diff --git a/CHANGELOG.md b/CHANGELOG.md
index 33294fa..9f7c4d1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,13 @@
+## V 5.13.0
+- FIX: rollup config updated to prevent lottie-web from running in Server-Side Rendering contexts
+- FIX: fixed renderGradient() cache invalidation issue so that both start and end points are checked for changes
+- IMPROVEMENT: avoid recalculating static transform matrices, results in a significant performance improvement
+- FIX: reloadShapes() no longer has the side effect of creating duplicate styles
+- FEATURE: Web Worker supports resetSegments
+- FIX: hidden styles were forcibly set as visible when using searchShapes()
+- IMPROVEMENT: expressions can access unidimensional values by index
+- IMPROVEMENT: expression support for thisProperty.name
+
 ## V 5.12.1
 - FIX: Transform Effect opacity reset
 - FEATURE: esm support
diff --git a/History.md b/History.md
index 872d086..0632699 100644
--- a/History.md
+++ b/History.md
@@ -1,3 +1,13 @@
+## V 5.13.0
+- FIX: rollup config updated to prevent lottie-web from running in Server-Side Rendering contexts
+- FIX: fixed renderGradient() cache invalidation issue so that both start and end points are checked for changes
+- IMPROVEMENT: avoid recalculating static transform matrices, results in a significant performance improvement
+- FIX: reloadShapes() no longer has the side effect of creating duplicate styles
+- FEATURE: Web Worker supports resetSegments
+- FIX: hidden styles were forcibly set as visible when using searchShapes()
+- IMPROVEMENT: expressions can access unidimensional values by index
+- IMPROVEMENT: expression support for thisProperty.name
+
 ## V 5.12.1
 - FIX: Transform Effect opacity reset
 - FEATURE: esm support
diff --git a/build/player/cjs/lottie.min.js b/build/player/cjs/lottie.min.js
new file mode 100644
index 0000000..7d095fc
--- /dev/null
+++ b/build/player/cjs/lottie.min.js
@@ -0,0 +1,18131 @@
+'use strict';
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+const svgNS = 'http://www.w3.org/2000/svg';
+
+let locationHref = '';
+let _useWebWorker = false;
+
+const initialDefaultFrame = -999999;
+
+const setWebWorker = (flag) => { _useWebWorker = !!flag; };
+const getWebWorker = () => _useWebWorker;
+
+const setLocationHref = (value) => { locationHref = value; };
+const getLocationHref = () => locationHref;
+
+function createTag(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElement(type);
+}
+
+function extendPrototype(sources, destination) {
+  var i;
+  var len = sources.length;
+  var sourcePrototype;
+  for (i = 0; i < len; i += 1) {
+    sourcePrototype = sources[i].prototype;
+    for (var attr in sourcePrototype) {
+      if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
+    }
+  }
+}
+
+function getDescriptor(object, prop) {
+  return Object.getOwnPropertyDescriptor(object, prop);
+}
+
+function createProxyFunction(prototype) {
+  function ProxyFunction() {}
+  ProxyFunction.prototype = prototype;
+  return ProxyFunction;
+}
+
+// import Howl from '../../3rd_party/howler';
+
+const audioControllerFactory = (function () {
+  function AudioController(audioFactory) {
+    this.audios = [];
+    this.audioFactory = audioFactory;
+    this._volume = 1;
+    this._isMuted = false;
+  }
+
+  AudioController.prototype = {
+    addAudio: function (audio) {
+      this.audios.push(audio);
+    },
+    pause: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].pause();
+      }
+    },
+    resume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].resume();
+      }
+    },
+    setRate: function (rateValue) {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].setRate(rateValue);
+      }
+    },
+    createAudio: function (assetPath) {
+      if (this.audioFactory) {
+        return this.audioFactory(assetPath);
+      } if (window.Howl) {
+        return new window.Howl({
+          src: [assetPath],
+        });
+      }
+      return {
+        isPlaying: false,
+        play: function () { this.isPlaying = true; },
+        seek: function () { this.isPlaying = false; },
+        playing: function () {},
+        rate: function () {},
+        setVolume: function () {},
+      };
+    },
+    setAudioFactory: function (audioFactory) {
+      this.audioFactory = audioFactory;
+    },
+    setVolume: function (value) {
+      this._volume = value;
+      this._updateVolume();
+    },
+    mute: function () {
+      this._isMuted = true;
+      this._updateVolume();
+    },
+    unmute: function () {
+      this._isMuted = false;
+      this._updateVolume();
+    },
+    getVolume: function () {
+      return this._volume;
+    },
+    _updateVolume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
+      }
+    },
+  };
+
+  return function () {
+    return new AudioController();
+  };
+}());
+
+const createTypedArray = (function () {
+  function createRegularArray(type, len) {
+    var i = 0;
+    var arr = [];
+    var value;
+    switch (type) {
+      case 'int16':
+      case 'uint8c':
+        value = 1;
+        break;
+      default:
+        value = 1.1;
+        break;
+    }
+    for (i = 0; i < len; i += 1) {
+      arr.push(value);
+    }
+    return arr;
+  }
+  function createTypedArrayFactory(type, len) {
+    if (type === 'float32') {
+      return new Float32Array(len);
+    } if (type === 'int16') {
+      return new Int16Array(len);
+    } if (type === 'uint8c') {
+      return new Uint8ClampedArray(len);
+    }
+    return createRegularArray(type, len);
+  }
+  if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
+    return createTypedArrayFactory;
+  }
+  return createRegularArray;
+}());
+
+function createSizedArray(len) {
+  return Array.apply(null, { length: len });
+}
+
+let subframeEnabled = true;
+let expressionsPlugin = null;
+let expressionsInterfaces = null;
+let idPrefix$1 = '';
+const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+let _shouldRoundValues = false;
+const bmPow = Math.pow;
+const bmSqrt = Math.sqrt;
+const bmFloor = Math.floor;
+const bmMax = Math.max;
+const bmMin = Math.min;
+
+const BMMath = {};
+(function () {
+  var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
+  var i;
+  var len = propertyNames.length;
+  for (i = 0; i < len; i += 1) {
+    BMMath[propertyNames[i]] = Math[propertyNames[i]];
+  }
+}());
+
+function ProjectInterface$1() { return {}; }
+BMMath.random = Math.random;
+BMMath.abs = function (val) {
+  var tOfVal = typeof val;
+  if (tOfVal === 'object' && val.length) {
+    var absArr = createSizedArray(val.length);
+    var i;
+    var len = val.length;
+    for (i = 0; i < len; i += 1) {
+      absArr[i] = Math.abs(val[i]);
+    }
+    return absArr;
+  }
+  return Math.abs(val);
+};
+let defaultCurveSegments = 150;
+const degToRads = Math.PI / 180;
+const roundCorner = 0.5519;
+
+function roundValues(flag) {
+  _shouldRoundValues = !!flag;
+}
+
+function bmRnd(value) {
+  if (_shouldRoundValues) {
+    return Math.round(value);
+  }
+  return value;
+}
+
+function styleDiv(element) {
+  element.style.position = 'absolute';
+  element.style.top = 0;
+  element.style.left = 0;
+  element.style.display = 'block';
+  element.style.transformOrigin = '0 0';
+  element.style.webkitTransformOrigin = '0 0';
+  element.style.backfaceVisibility = 'visible';
+  element.style.webkitBackfaceVisibility = 'visible';
+  element.style.transformStyle = 'preserve-3d';
+  element.style.webkitTransformStyle = 'preserve-3d';
+  element.style.mozTransformStyle = 'preserve-3d';
+}
+
+function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
+  this.type = type;
+  this.currentTime = currentTime;
+  this.totalTime = totalTime;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteEvent(type, frameMultiplier) {
+  this.type = type;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
+  this.type = type;
+  this.currentLoop = currentLoop;
+  this.totalLoops = totalLoops;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMSegmentStartEvent(type, firstFrame, totalFrames) {
+  this.type = type;
+  this.firstFrame = firstFrame;
+  this.totalFrames = totalFrames;
+}
+
+function BMDestroyEvent(type, target) {
+  this.type = type;
+  this.target = target;
+}
+
+function BMRenderFrameErrorEvent(nativeError, currentTime) {
+  this.type = 'renderFrameError';
+  this.nativeError = nativeError;
+  this.currentTime = currentTime;
+}
+
+function BMConfigErrorEvent(nativeError) {
+  this.type = 'configError';
+  this.nativeError = nativeError;
+}
+
+function BMAnimationConfigErrorEvent(type, nativeError) {
+  this.type = type;
+  this.nativeError = nativeError;
+}
+
+const createElementID = (function () {
+  var _count = 0;
+  return function createID() {
+    _count += 1;
+    return idPrefix$1 + '__lottie_element_' + _count;
+  };
+}());
+
+function HSVtoRGB(h, s, v) {
+  var r;
+  var g;
+  var b;
+  var i;
+  var f;
+  var p;
+  var q;
+  var t;
+  i = Math.floor(h * 6);
+  f = h * 6 - i;
+  p = v * (1 - s);
+  q = v * (1 - f * s);
+  t = v * (1 - (1 - f) * s);
+  switch (i % 6) {
+    case 0: r = v; g = t; b = p; break;
+    case 1: r = q; g = v; b = p; break;
+    case 2: r = p; g = v; b = t; break;
+    case 3: r = p; g = q; b = v; break;
+    case 4: r = t; g = p; b = v; break;
+    case 5: r = v; g = p; b = q; break;
+    default: break;
+  }
+  return [r,
+    g,
+    b];
+}
+
+function RGBtoHSV(r, g, b) {
+  var max = Math.max(r, g, b);
+  var min = Math.min(r, g, b);
+  var d = max - min;
+  var h;
+  var s = (max === 0 ? 0 : d / max);
+  var v = max / 255;
+
+  switch (max) {
+    case min: h = 0; break;
+    case r: h = (g - b) + d * (g < b ? 6 : 0); h /= 6 * d; break;
+    case g: h = (b - r) + d * 2; h /= 6 * d; break;
+    case b: h = (r - g) + d * 4; h /= 6 * d; break;
+    default: break;
+  }
+
+  return [
+    h,
+    s,
+    v,
+  ];
+}
+
+function addSaturationToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[1] += offset;
+  if (hsv[1] > 1) {
+    hsv[1] = 1;
+  } else if (hsv[1] <= 0) {
+    hsv[1] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addBrightnessToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[2] += offset;
+  if (hsv[2] > 1) {
+    hsv[2] = 1;
+  } else if (hsv[2] < 0) {
+    hsv[2] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addHueToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[0] += offset / 360;
+  if (hsv[0] > 1) {
+    hsv[0] -= 1;
+  } else if (hsv[0] < 0) {
+    hsv[0] += 1;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+const rgbToHex = (function () {
+  var colorMap = [];
+  var i;
+  var hex;
+  for (i = 0; i < 256; i += 1) {
+    hex = i.toString(16);
+    colorMap[i] = hex.length === 1 ? '0' + hex : hex;
+  }
+
+  return function (r, g, b) {
+    if (r < 0) {
+      r = 0;
+    }
+    if (g < 0) {
+      g = 0;
+    }
+    if (b < 0) {
+      b = 0;
+    }
+    return '#' + colorMap[r] + colorMap[g] + colorMap[b];
+  };
+}());
+
+const setSubframeEnabled = (flag) => { subframeEnabled = !!flag; };
+const getSubframeEnabled = () => subframeEnabled;
+const setExpressionsPlugin = (value) => { expressionsPlugin = value; };
+const getExpressionsPlugin = () => expressionsPlugin;
+const setExpressionInterfaces = (value) => { expressionsInterfaces = value; };
+const getExpressionInterfaces = () => expressionsInterfaces;
+const setDefaultCurveSegments = (value) => { defaultCurveSegments = value; };
+const getDefaultCurveSegments = () => defaultCurveSegments;
+const setIdPrefix = (value) => { idPrefix$1 = value; };
+const getIdPrefix = () => idPrefix$1;
+
+function createNS(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElementNS(svgNS, type);
+}
+
+const dataManager = (function () {
+  var _counterId = 1;
+  var processes = [];
+  var workerFn;
+  var workerInstance;
+  var workerProxy = {
+    onmessage: function () {
+
+    },
+    postMessage: function (path) {
+      workerFn({
+        data: path,
+      });
+    },
+  };
+  var _workerSelf = {
+    postMessage: function (data) {
+      workerProxy.onmessage({
+        data: data,
+      });
+    },
+  };
+  function createWorker(fn) {
+    if (window.Worker && window.Blob && getWebWorker()) {
+      var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      var url = URL.createObjectURL(blob);
+      return new Worker(url);
+    }
+    workerFn = fn;
+    return workerProxy;
+  }
+
+  function setupWorker() {
+    if (!workerInstance) {
+      workerInstance = createWorker(function workerStart(e) {
+        function dataFunctionManager() {
+          function completeLayers(layers, comps) {
+            var layerData;
+            var i;
+            var len = layers.length;
+            var j;
+            var jLen;
+            var k;
+            var kLen;
+            for (i = 0; i < len; i += 1) {
+              layerData = layers[i];
+              if (('ks' in layerData) && !layerData.completed) {
+                layerData.completed = true;
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      convertPathsToAbsoluteValues(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) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 0) {
+                  layerData.layers = findCompLayers(layerData.refId, comps);
+                  completeLayers(layerData.layers, comps);
+                } else if (layerData.ty === 4) {
+                  completeShapes(layerData.shapes);
+                } else if (layerData.ty === 5) {
+                  completeText(layerData);
+                }
+              }
+            }
+          }
+
+          function completeChars(chars, assets) {
+            if (chars) {
+              var i = 0;
+              var len = chars.length;
+              for (i = 0; i < len; i += 1) {
+                if (chars[i].t === 1) {
+                  // var compData = findComp(chars[i].data.refId, assets);
+                  chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                  // chars[i].data.ip = 0;
+                  // chars[i].data.op = 99999;
+                  // chars[i].data.st = 0;
+                  // chars[i].data.sr = 1;
+                  // chars[i].w = compData.w;
+                  // chars[i].data.ks = {
+                  //   a: { k: [0, 0, 0], a: 0 },
+                  //   p: { k: [0, -compData.h, 0], a: 0 },
+                  //   r: { k: 0, a: 0 },
+                  //   s: { k: [100, 100], a: 0 },
+                  //   o: { k: 100, a: 0 },
+                  // };
+                  completeLayers(chars[i].data.layers, assets);
+                }
+              }
+            }
+          }
+
+          function findComp(id, comps) {
+            var i = 0;
+            var len = comps.length;
+            while (i < len) {
+              if (comps[i].id === id) {
+                return comps[i];
+              }
+              i += 1;
+            }
+            return null;
+          }
+
+          function findCompLayers(id, comps) {
+            var comp = findComp(id, comps);
+            if (comp) {
+              if (!comp.layers.__used) {
+                comp.layers.__used = true;
+                return comp.layers;
+              }
+              return JSON.parse(JSON.stringify(comp.layers));
+            }
+            return null;
+          }
+
+          function completeShapes(arr) {
+            var i;
+            var len = arr.length;
+            var j;
+            var jLen;
+            for (i = len - 1; i >= 0; i -= 1) {
+              if (arr[i].ty === 'sh') {
+                if (arr[i].ks.k.i) {
+                  convertPathsToAbsoluteValues(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) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
+                    }
+                    if (arr[i].ks.k[j].e) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
+                    }
+                  }
+                }
+              } else if (arr[i].ty === 'gr') {
+                completeShapes(arr[i].it);
+              }
+            }
+          }
+
+          function convertPathsToAbsoluteValues(path) {
+            var i;
+            var len = path.i.length;
+            for (i = 0; i < len; i += 1) {
+              path.i[i][0] += path.v[i][0];
+              path.i[i][1] += path.v[i][1];
+              path.o[i][0] += path.v[i][0];
+              path.o[i][1] += path.v[i][1];
+            }
+          }
+
+          function checkVersion(minimum, animVersionString) {
+            var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
+            if (minimum[0] > animVersion[0]) {
+              return true;
+            } if (animVersion[0] > minimum[0]) {
+              return false;
+            }
+            if (minimum[1] > animVersion[1]) {
+              return true;
+            } if (animVersion[1] > minimum[1]) {
+              return false;
+            }
+            if (minimum[2] > animVersion[2]) {
+              return true;
+            } if (animVersion[2] > minimum[2]) {
+              return false;
+            }
+            return null;
+          }
+
+          var checkText = (function () {
+            var minimumVersion = [4, 4, 14];
+
+            function updateTextLayer(textLayer) {
+              var documentData = textLayer.t.d;
+              textLayer.t.d = {
+                k: [
+                  {
+                    s: documentData,
+                    t: 0,
+                  },
+                ],
+              };
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkChars = (function () {
+            var minimumVersion = [4, 7, 99];
+            return function (animationData) {
+              if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
+                var i;
+                var len = animationData.chars.length;
+                for (i = 0; i < len; i += 1) {
+                  var charData = animationData.chars[i];
+                  if (charData.data && charData.data.shapes) {
+                    completeShapes(charData.data.shapes);
+                    charData.data.ip = 0;
+                    charData.data.op = 99999;
+                    charData.data.st = 0;
+                    charData.data.sr = 1;
+                    charData.data.ks = {
+                      p: { k: [0, 0], a: 0 },
+                      s: { k: [100, 100], a: 0 },
+                      a: { k: [0, 0], a: 0 },
+                      r: { k: 0, a: 0 },
+                      o: { k: 100, a: 0 },
+                    };
+                    if (!animationData.chars[i].t) {
+                      charData.data.shapes.push(
+                        {
+                          ty: 'no',
+                        }
+                      );
+                      charData.data.shapes[0].it.push(
+                        {
+                          p: { k: [0, 0], a: 0 },
+                          s: { k: [100, 100], a: 0 },
+                          a: { k: [0, 0], a: 0 },
+                          r: { k: 0, a: 0 },
+                          o: { k: 100, a: 0 },
+                          sk: { k: 0, a: 0 },
+                          sa: { k: 0, a: 0 },
+                          ty: 'tr',
+                        }
+                      );
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkPathProperties = (function () {
+            var minimumVersion = [5, 7, 15];
+
+            function updateTextLayer(textLayer) {
+              var pathData = textLayer.t.p;
+              if (typeof pathData.a === 'number') {
+                pathData.a = {
+                  a: 0,
+                  k: pathData.a,
+                };
+              }
+              if (typeof pathData.p === 'number') {
+                pathData.p = {
+                  a: 0,
+                  k: pathData.p,
+                };
+              }
+              if (typeof pathData.r === 'number') {
+                pathData.r = {
+                  a: 0,
+                  k: pathData.r,
+                };
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkColors = (function () {
+            var minimumVersion = [4, 1, 9];
+
+            function iterateShapes(shapes) {
+              var i;
+              var len = shapes.length;
+              var j;
+              var jLen;
+              for (i = 0; i < len; i += 1) {
+                if (shapes[i].ty === 'gr') {
+                  iterateShapes(shapes[i].it);
+                } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
+                  if (shapes[i].c.k && shapes[i].c.k[0].i) {
+                    jLen = shapes[i].c.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (shapes[i].c.k[j].s) {
+                        shapes[i].c.k[j].s[0] /= 255;
+                        shapes[i].c.k[j].s[1] /= 255;
+                        shapes[i].c.k[j].s[2] /= 255;
+                        shapes[i].c.k[j].s[3] /= 255;
+                      }
+                      if (shapes[i].c.k[j].e) {
+                        shapes[i].c.k[j].e[0] /= 255;
+                        shapes[i].c.k[j].e[1] /= 255;
+                        shapes[i].c.k[j].e[2] /= 255;
+                        shapes[i].c.k[j].e[3] /= 255;
+                      }
+                    }
+                  } else {
+                    shapes[i].c.k[0] /= 255;
+                    shapes[i].c.k[1] /= 255;
+                    shapes[i].c.k[2] /= 255;
+                    shapes[i].c.k[3] /= 255;
+                  }
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 4) {
+                  iterateShapes(layers[i].shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkShapes = (function () {
+            var minimumVersion = [4, 4, 18];
+
+            function completeClosingShapes(arr) {
+              var i;
+              var len = arr.length;
+              var j;
+              var jLen;
+              for (i = len - 1; i >= 0; i -= 1) {
+                if (arr[i].ty === 'sh') {
+                  if (arr[i].ks.k.i) {
+                    arr[i].ks.k.c = arr[i].closed;
+                  } else {
+                    jLen = arr[i].ks.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (arr[i].ks.k[j].s) {
+                        arr[i].ks.k[j].s[0].c = arr[i].closed;
+                      }
+                      if (arr[i].ks.k[j].e) {
+                        arr[i].ks.k[j].e[0].c = arr[i].closed;
+                      }
+                    }
+                  }
+                } else if (arr[i].ty === 'gr') {
+                  completeClosingShapes(arr[i].it);
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var layerData;
+              var i;
+              var len = layers.length;
+              var j;
+              var jLen;
+              var k;
+              var kLen;
+              for (i = 0; i < len; i += 1) {
+                layerData = layers[i];
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      maskProps[j].pt.k.c = maskProps[j].cl;
+                    } else {
+                      kLen = maskProps[j].pt.k.length;
+                      for (k = 0; k < kLen; k += 1) {
+                        if (maskProps[j].pt.k[k].s) {
+                          maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 4) {
+                  completeClosingShapes(layerData.shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          function completeData(animationData) {
+            if (animationData.__complete) {
+              return;
+            }
+            checkColors(animationData);
+            checkText(animationData);
+            checkChars(animationData);
+            checkPathProperties(animationData);
+            checkShapes(animationData);
+            completeLayers(animationData.layers, animationData.assets);
+            completeChars(animationData.chars, animationData.assets);
+            animationData.__complete = true;
+          }
+
+          function completeText(data) {
+            if (data.t.a.length === 0 && !('m' in data.t.p)) {
+              // data.singleShape = true;
+            }
+          }
+
+          var moduleOb = {};
+          moduleOb.completeData = completeData;
+          moduleOb.checkColors = checkColors;
+          moduleOb.checkChars = checkChars;
+          moduleOb.checkPathProperties = checkPathProperties;
+          moduleOb.checkShapes = checkShapes;
+          moduleOb.completeLayers = completeLayers;
+
+          return moduleOb;
+        }
+        if (!_workerSelf.dataManager) {
+          _workerSelf.dataManager = dataFunctionManager();
+        }
+
+        if (!_workerSelf.assetLoader) {
+          _workerSelf.assetLoader = (function () {
+            function formatResponse(xhr) {
+              // using typeof doubles the time of execution of this method,
+              // so if available, it's better to use the header to validate the type
+              var contentTypeHeader = xhr.getResponseHeader('content-type');
+              if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
+                return xhr.response;
+              }
+              if (xhr.response && typeof xhr.response === 'object') {
+                return xhr.response;
+              } if (xhr.response && typeof xhr.response === 'string') {
+                return JSON.parse(xhr.response);
+              } if (xhr.responseText) {
+                return JSON.parse(xhr.responseText);
+              }
+              return null;
+            }
+
+            function loadAsset(path, fullPath, callback, errorCallback) {
+              var response;
+              var xhr = new XMLHttpRequest();
+              // set responseType after calling open or IE will break.
+              try {
+                // This crashes on Android WebView prior to KitKat
+                xhr.responseType = 'json';
+              } catch (err) {} // eslint-disable-line no-empty
+              xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4) {
+                  if (xhr.status === 200) {
+                    response = formatResponse(xhr);
+                    callback(response);
+                  } else {
+                    try {
+                      response = formatResponse(xhr);
+                      callback(response);
+                    } catch (err) {
+                      if (errorCallback) {
+                        errorCallback(err);
+                      }
+                    }
+                  }
+                }
+              };
+              try {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), path, true);
+              } catch (error) {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
+              }
+              xhr.send();
+            }
+            return {
+              load: loadAsset,
+            };
+          }());
+        }
+
+        if (e.data.type === 'loadAnimation') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.dataManager.completeData(data);
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        } else if (e.data.type === 'complete') {
+          var animation = e.data.animation;
+          _workerSelf.dataManager.completeData(animation);
+          _workerSelf.postMessage({
+            id: e.data.id,
+            payload: animation,
+            status: 'success',
+          });
+        } else if (e.data.type === 'loadData') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        }
+      });
+
+      workerInstance.onmessage = function (event) {
+        var data = event.data;
+        var id = data.id;
+        var process = processes[id];
+        processes[id] = null;
+        if (data.status === 'success') {
+          process.onComplete(data.payload);
+        } else if (process.onError) {
+          process.onError();
+        }
+      };
+    }
+  }
+
+  function createProcess(onComplete, onError) {
+    _counterId += 1;
+    var id = 'processId_' + _counterId;
+    processes[id] = {
+      onComplete: onComplete,
+      onError: onError,
+    };
+    return id;
+  }
+
+  function loadAnimation(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadAnimation',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function loadData(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadData',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function completeAnimation(anim, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'complete',
+      animation: anim,
+      id: processId,
+    });
+  }
+
+  return {
+    loadAnimation: loadAnimation,
+    loadData: loadData,
+    completeAnimation: completeAnimation,
+  };
+}());
+
+const ImagePreloader = (function () {
+  var proxyImage = (function () {
+    var canvas = createTag('canvas');
+    canvas.width = 1;
+    canvas.height = 1;
+    var ctx = canvas.getContext('2d');
+    ctx.fillStyle = 'rgba(0,0,0,0)';
+    ctx.fillRect(0, 0, 1, 1);
+    return canvas;
+  }());
+
+  function imageLoaded() {
+    this.loadedAssets += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+  function footageLoaded() {
+    this.loadedFootagesCount += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+
+  function getAssetsPath(assetData, assetsPath, originalPath) {
+    var path = '';
+    if (assetData.e) {
+      path = assetData.p;
+    } else if (assetsPath) {
+      var imagePath = assetData.p;
+      if (imagePath.indexOf('images/') !== -1) {
+        imagePath = imagePath.split('/')[1];
+      }
+      path = assetsPath + imagePath;
+    } else {
+      path = originalPath;
+      path += assetData.u ? assetData.u : '';
+      path += assetData.p;
+    }
+    return path;
+  }
+
+  function testImageLoaded(img) {
+    var _count = 0;
+    var intervalId = setInterval(function () {
+      var box = img.getBBox();
+      if (box.width || _count > 500) {
+        this._imageLoaded();
+        clearInterval(intervalId);
+      }
+      _count += 1;
+    }.bind(this), 50);
+  }
+
+  function createImageData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createNS('image');
+    if (isSafari) {
+      this.testImageLoaded(img);
+    } else {
+      img.addEventListener('load', this._imageLoaded, false);
+    }
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
+    if (this._elementHelper.append) {
+      this._elementHelper.append(img);
+    } else {
+      this._elementHelper.appendChild(img);
+    }
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createImgData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createTag('img');
+    img.crossOrigin = 'anonymous';
+    img.addEventListener('load', this._imageLoaded, false);
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.src = path;
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createFootageData(data) {
+    var ob = {
+      assetData: data,
+    };
+    var path = getAssetsPath(data, this.assetsPath, this.path);
+    dataManager.loadData(path, function (footageData) {
+      ob.img = footageData;
+      this._footageLoaded();
+    }.bind(this), function () {
+      ob.img = {};
+      this._footageLoaded();
+    }.bind(this));
+    return ob;
+  }
+
+  function loadAssets(assets, cb) {
+    this.imagesLoadedCb = cb;
+    var i;
+    var len = assets.length;
+    for (i = 0; i < len; i += 1) {
+      if (!assets[i].layers) {
+        if (!assets[i].t || assets[i].t === 'seq') {
+          this.totalImages += 1;
+          this.images.push(this._createImageData(assets[i]));
+        } else if (assets[i].t === 3) {
+          this.totalFootages += 1;
+          this.images.push(this.createFootageData(assets[i]));
+        }
+      }
+    }
+  }
+
+  function setPath(path) {
+    this.path = path || '';
+  }
+
+  function setAssetsPath(path) {
+    this.assetsPath = path || '';
+  }
+
+  function getAsset(assetData) {
+    var i = 0;
+    var len = this.images.length;
+    while (i < len) {
+      if (this.images[i].assetData === assetData) {
+        return this.images[i].img;
+      }
+      i += 1;
+    }
+    return null;
+  }
+
+  function destroy() {
+    this.imagesLoadedCb = null;
+    this.images.length = 0;
+  }
+
+  function loadedImages() {
+    return this.totalImages === this.loadedAssets;
+  }
+
+  function loadedFootages() {
+    return this.totalFootages === this.loadedFootagesCount;
+  }
+
+  function setCacheType(type, elementHelper) {
+    if (type === 'svg') {
+      this._elementHelper = elementHelper;
+      this._createImageData = this.createImageData.bind(this);
+    } else {
+      this._createImageData = this.createImgData.bind(this);
+    }
+  }
+
+  function ImagePreloaderFactory() {
+    this._imageLoaded = imageLoaded.bind(this);
+    this._footageLoaded = footageLoaded.bind(this);
+    this.testImageLoaded = testImageLoaded.bind(this);
+    this.createFootageData = createFootageData.bind(this);
+    this.assetsPath = '';
+    this.path = '';
+    this.totalImages = 0;
+    this.totalFootages = 0;
+    this.loadedAssets = 0;
+    this.loadedFootagesCount = 0;
+    this.imagesLoadedCb = null;
+    this.images = [];
+  }
+
+  ImagePreloaderFactory.prototype = {
+    loadAssets: loadAssets,
+    setAssetsPath: setAssetsPath,
+    setPath: setPath,
+    loadedImages: loadedImages,
+    loadedFootages: loadedFootages,
+    destroy: destroy,
+    getAsset: getAsset,
+    createImgData: createImgData,
+    createImageData: createImageData,
+    imageLoaded: imageLoaded,
+    footageLoaded: footageLoaded,
+    setCacheType: setCacheType,
+  };
+
+  return ImagePreloaderFactory;
+}());
+
+function BaseEvent() {}
+BaseEvent.prototype = {
+  triggerEvent: function (eventName, args) {
+    if (this._cbs[eventName]) {
+      var callbacks = this._cbs[eventName];
+      for (var i = 0; i < callbacks.length; i += 1) {
+        callbacks[i](args);
+      }
+    }
+  },
+  addEventListener: function (eventName, callback) {
+    if (!this._cbs[eventName]) {
+      this._cbs[eventName] = [];
+    }
+    this._cbs[eventName].push(callback);
+
+    return function () {
+      this.removeEventListener(eventName, callback);
+    }.bind(this);
+  },
+  removeEventListener: function (eventName, callback) {
+    if (!callback) {
+      this._cbs[eventName] = null;
+    } else if (this._cbs[eventName]) {
+      var i = 0;
+      var len = this._cbs[eventName].length;
+      while (i < len) {
+        if (this._cbs[eventName][i] === callback) {
+          this._cbs[eventName].splice(i, 1);
+          i -= 1;
+          len -= 1;
+        }
+        i += 1;
+      }
+      if (!this._cbs[eventName].length) {
+        this._cbs[eventName] = null;
+      }
+    }
+  },
+};
+
+const markerParser = (
+
+  function () {
+    function parsePayloadLines(payload) {
+      var lines = payload.split('\r\n');
+      var keys = {};
+      var line;
+      var keysCount = 0;
+      for (var i = 0; i < lines.length; i += 1) {
+        line = lines[i].split(':');
+        if (line.length === 2) {
+          keys[line[0]] = line[1].trim();
+          keysCount += 1;
+        }
+      }
+      if (keysCount === 0) {
+        throw new Error();
+      }
+      return keys;
+    }
+
+    return function (_markers) {
+      var markers = [];
+      for (var i = 0; i < _markers.length; i += 1) {
+        var _marker = _markers[i];
+        var markerData = {
+          time: _marker.tm,
+          duration: _marker.dr,
+        };
+        try {
+          markerData.payload = JSON.parse(_markers[i].cm);
+        } catch (_) {
+          try {
+            markerData.payload = parsePayloadLines(_markers[i].cm);
+          } catch (__) {
+            markerData.payload = {
+              name: _markers[i].cm,
+            };
+          }
+        }
+        markers.push(markerData);
+      }
+      return markers;
+    };
+  }());
+
+const ProjectInterface = (function () {
+  function registerComposition(comp) {
+    this.compositions.push(comp);
+  }
+
+  return function () {
+    function _thisProjectFunction(name) {
+      var i = 0;
+      var len = this.compositions.length;
+      while (i < len) {
+        if (this.compositions[i].data && this.compositions[i].data.nm === name) {
+          if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
+            this.compositions[i].prepareFrame(this.currentFrame);
+          }
+          return this.compositions[i].compInterface;
+        }
+        i += 1;
+      }
+      return null;
+    }
+
+    _thisProjectFunction.compositions = [];
+    _thisProjectFunction.currentFrame = 0;
+
+    _thisProjectFunction.registerComposition = registerComposition;
+
+    return _thisProjectFunction;
+  };
+}());
+
+const renderers = {};
+
+const registerRenderer = (key, value) => {
+  renderers[key] = value;
+};
+
+function getRenderer(key) {
+  return renderers[key];
+}
+
+function getRegisteredRenderer() {
+  // Returns canvas by default for compatibility
+  if (renderers.canvas) {
+    return 'canvas';
+  }
+  // Returns any renderer that is registered
+  for (const key in renderers) {
+    if (renderers[key]) {
+      return key;
+    }
+  }
+  return '';
+}
+
+const AnimationItem = function () {
+  this._cbs = [];
+  this.name = '';
+  this.path = '';
+  this.isLoaded = false;
+  this.currentFrame = 0;
+  this.currentRawFrame = 0;
+  this.firstFrame = 0;
+  this.totalFrames = 0;
+  this.frameRate = 0;
+  this.frameMult = 0;
+  this.playSpeed = 1;
+  this.playDirection = 1;
+  this.playCount = 0;
+  this.animationData = {};
+  this.assets = [];
+  this.isPaused = true;
+  this.autoplay = false;
+  this.loop = true;
+  this.renderer = null;
+  this.animationID = createElementID();
+  this.assetsPath = '';
+  this.timeCompleted = 0;
+  this.segmentPos = 0;
+  this.isSubframeEnabled = getSubframeEnabled();
+  this.segments = [];
+  this._idle = true;
+  this._completedLoop = false;
+  this.projectInterface = ProjectInterface();
+  this.imagePreloader = new ImagePreloader();
+  this.audioController = audioControllerFactory();
+  this.markers = [];
+  this.configAnimation = this.configAnimation.bind(this);
+  this.onSetupError = this.onSetupError.bind(this);
+  this.onSegmentComplete = this.onSegmentComplete.bind(this);
+  this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
+  this.expressionsPlugin = getExpressionsPlugin();
+};
+
+extendPrototype([BaseEvent], AnimationItem);
+
+AnimationItem.prototype.setParams = function (params) {
+  if (params.wrapper || params.container) {
+    this.wrapper = params.wrapper || params.container;
+  }
+  var animType = 'svg';
+  if (params.animType) {
+    animType = params.animType;
+  } else if (params.renderer) {
+    animType = params.renderer;
+  }
+  const RendererClass = getRenderer(animType);
+  this.renderer = new RendererClass(this, params.rendererSettings);
+  this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
+  this.renderer.setProjectInterface(this.projectInterface);
+  this.animType = animType;
+  if (params.loop === ''
+        || params.loop === null
+        || params.loop === undefined
+        || params.loop === true) {
+    this.loop = true;
+  } else if (params.loop === false) {
+    this.loop = false;
+  } else {
+    this.loop = parseInt(params.loop, 10);
+  }
+  this.autoplay = 'autoplay' in params ? params.autoplay : true;
+  this.name = params.name ? params.name : '';
+  this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
+  this.assetsPath = params.assetsPath;
+  this.initialSegment = params.initialSegment;
+  if (params.audioFactory) {
+    this.audioController.setAudioFactory(params.audioFactory);
+  }
+  if (params.animationData) {
+    this.setupAnimation(params.animationData);
+  } else if (params.path) {
+    if (params.path.lastIndexOf('\\') !== -1) {
+      this.path = params.path.substr(0, params.path.lastIndexOf('\\') + 1);
+    } else {
+      this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
+    }
+    this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
+    this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
+    dataManager.loadAnimation(
+      params.path,
+      this.configAnimation,
+      this.onSetupError
+    );
+  }
+};
+
+AnimationItem.prototype.onSetupError = function () {
+  this.trigger('data_failed');
+};
+
+AnimationItem.prototype.setupAnimation = function (data) {
+  dataManager.completeAnimation(
+    data,
+    this.configAnimation
+  );
+};
+
+AnimationItem.prototype.setData = function (wrapper, animationData) {
+  if (animationData) {
+    if (typeof animationData !== 'object') {
+      animationData = JSON.parse(animationData);
+    }
+  }
+  var params = {
+    wrapper: wrapper,
+    animationData: animationData,
+  };
+  var wrapperAttributes = wrapper.attributes;
+
+  params.path = wrapperAttributes.getNamedItem('data-animation-path') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-animation-path').value
+    : wrapperAttributes.getNamedItem('data-bm-path') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-path').value
+      : wrapperAttributes.getNamedItem('bm-path')
+        ? wrapperAttributes.getNamedItem('bm-path').value
+        : '';
+  params.animType = wrapperAttributes.getNamedItem('data-anim-type') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-type').value
+    : wrapperAttributes.getNamedItem('data-bm-type') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-type').value
+      : wrapperAttributes.getNamedItem('bm-type') // eslint-disable-line no-nested-ternary
+        ? wrapperAttributes.getNamedItem('bm-type').value
+        : wrapperAttributes.getNamedItem('data-bm-renderer') // eslint-disable-line no-nested-ternary
+          ? wrapperAttributes.getNamedItem('data-bm-renderer').value
+          : wrapperAttributes.getNamedItem('bm-renderer')
+            ? wrapperAttributes.getNamedItem('bm-renderer').value
+            : getRegisteredRenderer() || 'canvas';
+
+  var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-loop').value
+    : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-loop').value
+      : wrapperAttributes.getNamedItem('bm-loop')
+        ? wrapperAttributes.getNamedItem('bm-loop').value
+        : '';
+  if (loop === 'false') {
+    params.loop = false;
+  } else if (loop === 'true') {
+    params.loop = true;
+  } else if (loop !== '') {
+    params.loop = parseInt(loop, 10);
+  }
+  var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-autoplay').value
+    : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-autoplay').value
+      : wrapperAttributes.getNamedItem('bm-autoplay')
+        ? wrapperAttributes.getNamedItem('bm-autoplay').value
+        : true;
+  params.autoplay = autoplay !== 'false';
+
+  params.name = wrapperAttributes.getNamedItem('data-name') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-name').value
+    : wrapperAttributes.getNamedItem('data-bm-name') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-name').value
+      : wrapperAttributes.getNamedItem('bm-name')
+        ? wrapperAttributes.getNamedItem('bm-name').value
+        : '';
+  var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-prerender').value
+    : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-prerender').value
+      : wrapperAttributes.getNamedItem('bm-prerender')
+        ? wrapperAttributes.getNamedItem('bm-prerender').value
+        : '';
+
+  if (prerender === 'false') {
+    params.prerender = false;
+  }
+  if (!params.path) {
+    this.trigger('destroy');
+  } else {
+    this.setParams(params);
+  }
+};
+
+AnimationItem.prototype.includeLayers = function (data) {
+  if (data.op > this.animationData.op) {
+    this.animationData.op = data.op;
+    this.totalFrames = Math.floor(data.op - this.animationData.ip);
+  }
+  var layers = this.animationData.layers;
+  var i;
+  var len = layers.length;
+  var newLayers = data.layers;
+  var j;
+  var jLen = newLayers.length;
+  for (j = 0; j < jLen; j += 1) {
+    i = 0;
+    while (i < len) {
+      if (layers[i].id === newLayers[j].id) {
+        layers[i] = newLayers[j];
+        break;
+      }
+      i += 1;
+    }
+  }
+  if (data.chars || data.fonts) {
+    this.renderer.globalData.fontManager.addChars(data.chars);
+    this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
+  }
+  if (data.assets) {
+    len = data.assets.length;
+    for (i = 0; i < len; i += 1) {
+      this.animationData.assets.push(data.assets[i]);
+    }
+  }
+  this.animationData.__complete = false;
+  dataManager.completeAnimation(
+    this.animationData,
+    this.onSegmentComplete
+  );
+};
+
+AnimationItem.prototype.onSegmentComplete = function (data) {
+  this.animationData = data;
+  var expressionsPlugin = getExpressionsPlugin();
+  if (expressionsPlugin) {
+    expressionsPlugin.initExpressions(this);
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.loadNextSegment = function () {
+  var segments = this.animationData.segments;
+  if (!segments || segments.length === 0 || !this.autoloadSegments) {
+    this.trigger('data_ready');
+    this.timeCompleted = this.totalFrames;
+    return;
+  }
+  var segment = segments.shift();
+  this.timeCompleted = segment.time * this.frameRate;
+  var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
+  this.segmentPos += 1;
+  dataManager.loadData(segmentPath, this.includeLayers.bind(this), function () {
+    this.trigger('data_failed');
+  }.bind(this));
+};
+
+AnimationItem.prototype.loadSegments = function () {
+  var segments = this.animationData.segments;
+  if (!segments) {
+    this.timeCompleted = this.totalFrames;
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.imagesLoaded = function () {
+  this.trigger('loaded_images');
+  this.checkLoaded();
+};
+
+AnimationItem.prototype.preloadImages = function () {
+  this.imagePreloader.setAssetsPath(this.assetsPath);
+  this.imagePreloader.setPath(this.path);
+  this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
+};
+
+AnimationItem.prototype.configAnimation = function (animData) {
+  if (!this.renderer) {
+    return;
+  }
+  try {
+    this.animationData = animData;
+    if (this.initialSegment) {
+      this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
+      this.firstFrame = Math.round(this.initialSegment[0]);
+    } else {
+      this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
+      this.firstFrame = Math.round(this.animationData.ip);
+    }
+    this.renderer.configAnimation(animData);
+    if (!animData.assets) {
+      animData.assets = [];
+    }
+
+    this.assets = this.animationData.assets;
+    this.frameRate = this.animationData.fr;
+    this.frameMult = this.animationData.fr / 1000;
+    this.renderer.searchExtraCompositions(animData.assets);
+    this.markers = markerParser(animData.markers || []);
+    this.trigger('config_ready');
+    this.preloadImages();
+    this.loadSegments();
+    this.updaFrameModifier();
+    this.waitForFontsLoaded();
+    if (this.isPaused) {
+      this.audioController.pause();
+    }
+  } catch (error) {
+    this.triggerConfigError(error);
+  }
+};
+
+AnimationItem.prototype.waitForFontsLoaded = function () {
+  if (!this.renderer) {
+    return;
+  }
+  if (this.renderer.globalData.fontManager.isLoaded) {
+    this.checkLoaded();
+  } else {
+    setTimeout(this.waitForFontsLoaded.bind(this), 20);
+  }
+};
+
+AnimationItem.prototype.checkLoaded = function () {
+  if (!this.isLoaded
+        && this.renderer.globalData.fontManager.isLoaded
+        && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas')
+        && (this.imagePreloader.loadedFootages())
+  ) {
+    this.isLoaded = true;
+    var expressionsPlugin = getExpressionsPlugin();
+    if (expressionsPlugin) {
+      expressionsPlugin.initExpressions(this);
+    }
+    this.renderer.initItems();
+    setTimeout(function () {
+      this.trigger('DOMLoaded');
+    }.bind(this), 0);
+    this.gotoFrame();
+    if (this.autoplay) {
+      this.play();
+    }
+  }
+};
+
+AnimationItem.prototype.resize = function (width, height) {
+  // Adding this validation for backwards compatibility in case an event object was being passed down
+  var _width = typeof width === 'number' ? width : undefined;
+  var _height = typeof height === 'number' ? height : undefined;
+  this.renderer.updateContainerSize(_width, _height);
+};
+
+AnimationItem.prototype.setSubframe = function (flag) {
+  this.isSubframeEnabled = !!flag;
+};
+
+AnimationItem.prototype.gotoFrame = function () {
+  this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
+
+  if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
+    this.currentFrame = this.timeCompleted;
+  }
+  this.trigger('enterFrame');
+  this.renderFrame();
+  this.trigger('drawnFrame');
+};
+
+AnimationItem.prototype.renderFrame = function () {
+  if (this.isLoaded === false || !this.renderer) {
+    return;
+  }
+  try {
+    if (this.expressionsPlugin) {
+      this.expressionsPlugin.resetFrame();
+    }
+    this.renderer.renderFrame(this.currentFrame + this.firstFrame);
+  } catch (error) {
+    this.triggerRenderFrameError(error);
+  }
+};
+
+AnimationItem.prototype.play = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.isPaused = false;
+    this.trigger('_play');
+    this.audioController.resume();
+    if (this._idle) {
+      this._idle = false;
+      this.trigger('_active');
+    }
+  }
+};
+
+AnimationItem.prototype.pause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === false) {
+    this.isPaused = true;
+    this.trigger('_pause');
+    this._idle = true;
+    this.trigger('_idle');
+    this.audioController.pause();
+  }
+};
+
+AnimationItem.prototype.togglePause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.play();
+  } else {
+    this.pause();
+  }
+};
+
+AnimationItem.prototype.stop = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.pause();
+  this.playCount = 0;
+  this._completedLoop = false;
+  this.setCurrentRawFrameValue(0);
+};
+
+AnimationItem.prototype.getMarkerData = function (markerName) {
+  var marker;
+  for (var i = 0; i < this.markers.length; i += 1) {
+    marker = this.markers[i];
+    if (marker.payload && marker.payload.name === markerName) {
+      return marker;
+    }
+  }
+  return null;
+};
+
+AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      this.goToAndStop(marker.time, true);
+    }
+  } else if (isFrame) {
+    this.setCurrentRawFrameValue(value);
+  } else {
+    this.setCurrentRawFrameValue(value * this.frameModifier);
+  }
+  this.pause();
+};
+
+AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      if (!marker.duration) {
+        this.goToAndStop(marker.time, true);
+      } else {
+        this.playSegments([marker.time, marker.time + marker.duration], true);
+      }
+    }
+  } else {
+    this.goToAndStop(numValue, isFrame, name);
+  }
+  this.play();
+};
+
+AnimationItem.prototype.advanceTime = function (value) {
+  if (this.isPaused === true || this.isLoaded === false) {
+    return;
+  }
+  var nextValue = this.currentRawFrame + value * this.frameModifier;
+  var _isComplete = false;
+  // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+  // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
+  if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
+    if (!this.loop || this.playCount === this.loop) {
+      if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
+        _isComplete = true;
+        nextValue = this.totalFrames - 1;
+      }
+    } else if (nextValue >= this.totalFrames) {
+      this.playCount += 1;
+      if (!this.checkSegments(nextValue % this.totalFrames)) {
+        this.setCurrentRawFrameValue(nextValue % this.totalFrames);
+        this._completedLoop = true;
+        this.trigger('loopComplete');
+      }
+    } else {
+      this.setCurrentRawFrameValue(nextValue);
+    }
+  } else if (nextValue < 0) {
+    if (!this.checkSegments(nextValue % this.totalFrames)) {
+      if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) { // eslint-disable-line no-plusplus
+        this.setCurrentRawFrameValue(this.totalFrames + (nextValue % this.totalFrames));
+        if (!this._completedLoop) {
+          this._completedLoop = true;
+        } else {
+          this.trigger('loopComplete');
+        }
+      } else {
+        _isComplete = true;
+        nextValue = 0;
+      }
+    }
+  } else {
+    this.setCurrentRawFrameValue(nextValue);
+  }
+  if (_isComplete) {
+    this.setCurrentRawFrameValue(nextValue);
+    this.pause();
+    this.trigger('complete');
+  }
+};
+
+AnimationItem.prototype.adjustSegment = function (arr, offset) {
+  this.playCount = 0;
+  if (arr[1] < arr[0]) {
+    if (this.frameModifier > 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(-1);
+      }
+    }
+    this.totalFrames = arr[0] - arr[1];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[1];
+    this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset);
+  } else if (arr[1] > arr[0]) {
+    if (this.frameModifier < 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(1);
+      }
+    }
+    this.totalFrames = arr[1] - arr[0];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[0];
+    this.setCurrentRawFrameValue(0.001 + offset);
+  }
+  this.trigger('segmentStart');
+};
+AnimationItem.prototype.setSegment = function (init, end) {
+  var pendingFrame = -1;
+  if (this.isPaused) {
+    if (this.currentRawFrame + this.firstFrame < init) {
+      pendingFrame = init;
+    } else if (this.currentRawFrame + this.firstFrame > end) {
+      pendingFrame = end - init;
+    }
+  }
+
+  this.firstFrame = init;
+  this.totalFrames = end - init;
+  this.timeCompleted = this.totalFrames;
+  if (pendingFrame !== -1) {
+    this.goToAndStop(pendingFrame, true);
+  }
+};
+
+AnimationItem.prototype.playSegments = function (arr, forceFlag) {
+  if (forceFlag) {
+    this.segments.length = 0;
+  }
+  if (typeof arr[0] === 'object') {
+    var i;
+    var len = arr.length;
+    for (i = 0; i < len; i += 1) {
+      this.segments.push(arr[i]);
+    }
+  } else {
+    this.segments.push(arr);
+  }
+  if (this.segments.length && forceFlag) {
+    this.adjustSegment(this.segments.shift(), 0);
+  }
+  if (this.isPaused) {
+    this.play();
+  }
+};
+
+AnimationItem.prototype.resetSegments = function (forceFlag) {
+  this.segments.length = 0;
+  this.segments.push([this.animationData.ip, this.animationData.op]);
+  if (forceFlag) {
+    this.checkSegments(0);
+  }
+};
+AnimationItem.prototype.checkSegments = function (offset) {
+  if (this.segments.length) {
+    this.adjustSegment(this.segments.shift(), offset);
+    return true;
+  }
+  return false;
+};
+
+AnimationItem.prototype.destroy = function (name) {
+  if ((name && this.name !== name) || !this.renderer) {
+    return;
+  }
+  this.renderer.destroy();
+  this.imagePreloader.destroy();
+  this.trigger('destroy');
+  this._cbs = null;
+  this.onEnterFrame = null;
+  this.onLoopComplete = null;
+  this.onComplete = null;
+  this.onSegmentStart = null;
+  this.onDestroy = null;
+  this.renderer = null;
+  this.expressionsPlugin = null;
+  this.imagePreloader = null;
+  this.projectInterface = null;
+};
+
+AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
+  this.currentRawFrame = value;
+  this.gotoFrame();
+};
+
+AnimationItem.prototype.setSpeed = function (val) {
+  this.playSpeed = val;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setDirection = function (val) {
+  this.playDirection = val < 0 ? -1 : 1;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setLoop = function (isLooping) {
+  this.loop = isLooping;
+};
+
+AnimationItem.prototype.setVolume = function (val, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.setVolume(val);
+};
+
+AnimationItem.prototype.getVolume = function () {
+  return this.audioController.getVolume();
+};
+
+AnimationItem.prototype.mute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.mute();
+};
+
+AnimationItem.prototype.unmute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.unmute();
+};
+
+AnimationItem.prototype.updaFrameModifier = function () {
+  this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
+  this.audioController.setRate(this.playSpeed * this.playDirection);
+};
+
+AnimationItem.prototype.getPath = function () {
+  return this.path;
+};
+
+AnimationItem.prototype.getAssetsPath = function (assetData) {
+  var path = '';
+  if (assetData.e) {
+    path = assetData.p;
+  } else if (this.assetsPath) {
+    var imagePath = assetData.p;
+    if (imagePath.indexOf('images/') !== -1) {
+      imagePath = imagePath.split('/')[1];
+    }
+    path = this.assetsPath + imagePath;
+  } else {
+    path = this.path;
+    path += assetData.u ? assetData.u : '';
+    path += assetData.p;
+  }
+  return path;
+};
+
+AnimationItem.prototype.getAssetData = function (id) {
+  var i = 0;
+  var len = this.assets.length;
+  while (i < len) {
+    if (id === this.assets[i].id) {
+      return this.assets[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+AnimationItem.prototype.hide = function () {
+  this.renderer.hide();
+};
+
+AnimationItem.prototype.show = function () {
+  this.renderer.show();
+};
+
+AnimationItem.prototype.getDuration = function (isFrame) {
+  return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
+};
+
+AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
+  try {
+    var element = this.renderer.getElementByPath(path);
+    element.updateDocumentData(documentData, index);
+  } catch (error) {
+    // TODO: decide how to handle catch case
+  }
+};
+
+AnimationItem.prototype.trigger = function (name) {
+  if (this._cbs && this._cbs[name]) {
+    switch (name) {
+      case 'enterFrame':
+        this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
+        break;
+      case 'drawnFrame':
+        this.drawnFrameEvent.currentTime = this.currentFrame;
+        this.drawnFrameEvent.totalTime = this.totalFrames;
+        this.drawnFrameEvent.direction = this.frameModifier;
+        this.triggerEvent(name, this.drawnFrameEvent);
+        break;
+      case 'loopComplete':
+        this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+        break;
+      case 'complete':
+        this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
+        break;
+      case 'segmentStart':
+        this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+        break;
+      case 'destroy':
+        this.triggerEvent(name, new BMDestroyEvent(name, this));
+        break;
+      default:
+        this.triggerEvent(name);
+    }
+  }
+  if (name === 'enterFrame' && this.onEnterFrame) {
+    this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
+  }
+  if (name === 'loopComplete' && this.onLoopComplete) {
+    this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+  }
+  if (name === 'complete' && this.onComplete) {
+    this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
+  }
+  if (name === 'segmentStart' && this.onSegmentStart) {
+    this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+  }
+  if (name === 'destroy' && this.onDestroy) {
+    this.onDestroy.call(this, new BMDestroyEvent(name, this));
+  }
+};
+
+AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
+  var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+AnimationItem.prototype.triggerConfigError = function (nativeError) {
+  var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+const animationManager = (function () {
+  var moduleOb = {};
+  var registeredAnimations = [];
+  var initTime = 0;
+  var len = 0;
+  var playingAnimationsNum = 0;
+  var _stopped = true;
+  var _isFrozen = false;
+
+  function removeElement(ev) {
+    var i = 0;
+    var animItem = ev.target;
+    while (i < len) {
+      if (registeredAnimations[i].animation === animItem) {
+        registeredAnimations.splice(i, 1);
+        i -= 1;
+        len -= 1;
+        if (!animItem.isPaused) {
+          subtractPlayingCount();
+        }
+      }
+      i += 1;
+    }
+  }
+
+  function registerAnimation(element, animationData) {
+    if (!element) {
+      return null;
+    }
+    var i = 0;
+    while (i < len) {
+      if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
+        return registeredAnimations[i].animation;
+      }
+      i += 1;
+    }
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, element);
+    animItem.setData(element, animationData);
+    return animItem;
+  }
+
+  function getRegisteredAnimations() {
+    var i;
+    var lenAnims = registeredAnimations.length;
+    var animations = [];
+    for (i = 0; i < lenAnims; i += 1) {
+      animations.push(registeredAnimations[i].animation);
+    }
+    return animations;
+  }
+
+  function addPlayingCount() {
+    playingAnimationsNum += 1;
+    activate();
+  }
+
+  function subtractPlayingCount() {
+    playingAnimationsNum -= 1;
+  }
+
+  function setupAnimation(animItem, element) {
+    animItem.addEventListener('destroy', removeElement);
+    animItem.addEventListener('_active', addPlayingCount);
+    animItem.addEventListener('_idle', subtractPlayingCount);
+    registeredAnimations.push({ elem: element, animation: animItem });
+    len += 1;
+  }
+
+  function loadAnimation(params) {
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, null);
+    animItem.setParams(params);
+    return animItem;
+  }
+
+  function setSpeed(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setSpeed(val, animation);
+    }
+  }
+
+  function setDirection(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setDirection(val, animation);
+    }
+  }
+
+  function play(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.play(animation);
+    }
+  }
+  function resume(nowTime) {
+    var elapsedTime = nowTime - initTime;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.advanceTime(elapsedTime);
+    }
+    initTime = nowTime;
+    if (playingAnimationsNum && !_isFrozen) {
+      window.requestAnimationFrame(resume);
+    } else {
+      _stopped = true;
+    }
+  }
+
+  function first(nowTime) {
+    initTime = nowTime;
+    window.requestAnimationFrame(resume);
+  }
+
+  function pause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.pause(animation);
+    }
+  }
+
+  function goToAndStop(value, isFrame, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
+    }
+  }
+
+  function stop(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.stop(animation);
+    }
+  }
+
+  function togglePause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.togglePause(animation);
+    }
+  }
+
+  function destroy(animation) {
+    var i;
+    for (i = (len - 1); i >= 0; i -= 1) {
+      registeredAnimations[i].animation.destroy(animation);
+    }
+  }
+
+  function searchAnimations(animationData, standalone, renderer) {
+    var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')),
+      [].slice.call(document.getElementsByClassName('bodymovin')));
+    var i;
+    var lenAnims = animElements.length;
+    for (i = 0; i < lenAnims; i += 1) {
+      if (renderer) {
+        animElements[i].setAttribute('data-bm-type', renderer);
+      }
+      registerAnimation(animElements[i], animationData);
+    }
+    if (standalone && lenAnims === 0) {
+      if (!renderer) {
+        renderer = 'svg';
+      }
+      var body = document.getElementsByTagName('body')[0];
+      body.innerText = '';
+      var div = createTag('div');
+      div.style.width = '100%';
+      div.style.height = '100%';
+      div.setAttribute('data-bm-type', renderer);
+      body.appendChild(div);
+      registerAnimation(div, animationData);
+    }
+  }
+
+  function resize() {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.resize();
+    }
+  }
+
+  function activate() {
+    if (!_isFrozen && playingAnimationsNum) {
+      if (_stopped) {
+        window.requestAnimationFrame(first);
+        _stopped = false;
+      }
+    }
+  }
+
+  function freeze() {
+    _isFrozen = true;
+  }
+
+  function unfreeze() {
+    _isFrozen = false;
+    activate();
+  }
+
+  function setVolume(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setVolume(val, animation);
+    }
+  }
+
+  function mute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.mute(animation);
+    }
+  }
+
+  function unmute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.unmute(animation);
+    }
+  }
+
+  moduleOb.registerAnimation = registerAnimation;
+  moduleOb.loadAnimation = loadAnimation;
+  moduleOb.setSpeed = setSpeed;
+  moduleOb.setDirection = setDirection;
+  moduleOb.play = play;
+  moduleOb.pause = pause;
+  moduleOb.stop = stop;
+  moduleOb.togglePause = togglePause;
+  moduleOb.searchAnimations = searchAnimations;
+  moduleOb.resize = resize;
+  // moduleOb.start = start;
+  moduleOb.goToAndStop = goToAndStop;
+  moduleOb.destroy = destroy;
+  moduleOb.freeze = freeze;
+  moduleOb.unfreeze = unfreeze;
+  moduleOb.setVolume = setVolume;
+  moduleOb.mute = mute;
+  moduleOb.unmute = unmute;
+  moduleOb.getRegisteredAnimations = getRegisteredAnimations;
+  return moduleOb;
+}());
+
+/* eslint-disable */
+const BezierFactory = (function () {
+  /**
+     * BezierEasing - use bezier curve for transition easing function
+     * by Gaëtan Renaudeau 2014 - 2015 – MIT License
+     *
+     * Credits: is based on Firefox's nsSMILKeySpline.cpp
+     * Usage:
+     * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
+     * spline.get(x) => returns the easing value | x must be in [0, 1] range
+     *
+     */
+
+  var ob = {};
+  ob.getBezierEasing = getBezierEasing;
+  var beziers = {};
+
+  function getBezierEasing(a, b, c, d, nm) {
+    var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
+    if (beziers[str]) {
+      return beziers[str];
+    }
+    var bezEasing = new BezierEasing([a, b, c, d]);
+    beziers[str] = bezEasing;
+    return bezEasing;
+  }
+
+  // These values are established by empiricism with tests (tradeoff: performance VS precision)
+  var NEWTON_ITERATIONS = 4;
+  var NEWTON_MIN_SLOPE = 0.001;
+  var SUBDIVISION_PRECISION = 0.0000001;
+  var SUBDIVISION_MAX_ITERATIONS = 10;
+
+  var kSplineTableSize = 11;
+  var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
+
+  var float32ArraySupported = typeof Float32Array === 'function';
+
+  function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
+  function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
+  function C(aA1) { return 3.0 * aA1; }
+
+  // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+  function calcBezier(aT, aA1, aA2) {
+    return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
+  }
+
+  // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+  function getSlope(aT, aA1, aA2) {
+    return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
+  }
+
+  function binarySubdivide(aX, aA, aB, mX1, mX2) {
+    var currentX,
+      currentT,
+      i = 0;
+    do {
+      currentT = aA + (aB - aA) / 2.0;
+      currentX = calcBezier(currentT, mX1, mX2) - aX;
+      if (currentX > 0.0) {
+        aB = currentT;
+      } else {
+        aA = currentT;
+      }
+    } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
+    return currentT;
+  }
+
+  function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
+    for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
+      var currentSlope = getSlope(aGuessT, mX1, mX2);
+      if (currentSlope === 0.0) return aGuessT;
+      var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
+      aGuessT -= currentX / currentSlope;
+    }
+    return aGuessT;
+  }
+
+  /**
+     * points is an array of [ mX1, mY1, mX2, mY2 ]
+     */
+  function BezierEasing(points) {
+    this._p = points;
+    this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
+    this._precomputed = false;
+
+    this.get = this.get.bind(this);
+  }
+
+  BezierEasing.prototype = {
+
+    get: function (x) {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      if (!this._precomputed) this._precompute();
+      if (mX1 === mY1 && mX2 === mY2) return x; // linear
+      // Because JavaScript number are imprecise, we should guarantee the extremes are right.
+      if (x === 0) return 0;
+      if (x === 1) return 1;
+      return calcBezier(this._getTForX(x), mY1, mY2);
+    },
+
+    // Private part
+
+    _precompute: function () {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      this._precomputed = true;
+      if (mX1 !== mY1 || mX2 !== mY2) { this._calcSampleValues(); }
+    },
+
+    _calcSampleValues: function () {
+      var mX1 = this._p[0],
+        mX2 = this._p[2];
+      for (var i = 0; i < kSplineTableSize; ++i) {
+        this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
+      }
+    },
+
+    /**
+         * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
+         */
+    _getTForX: function (aX) {
+      var mX1 = this._p[0],
+        mX2 = this._p[2],
+        mSampleValues = this._mSampleValues;
+
+      var intervalStart = 0.0;
+      var currentSample = 1;
+      var lastSample = kSplineTableSize - 1;
+
+      for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
+        intervalStart += kSampleStepSize;
+      }
+      --currentSample;
+
+      // Interpolate to provide an initial guess for t
+      var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
+      var guessForT = intervalStart + dist * kSampleStepSize;
+
+      var initialSlope = getSlope(guessForT, mX1, mX2);
+      if (initialSlope >= NEWTON_MIN_SLOPE) {
+        return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
+      } if (initialSlope === 0.0) {
+        return guessForT;
+      }
+      return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
+    },
+  };
+
+  return ob;
+}());
+
+const pooling = (function () {
+  function double(arr) {
+    return arr.concat(createSizedArray(arr.length));
+  }
+
+  return {
+    double: double,
+  };
+}());
+
+const poolFactory = (function () {
+  return function (initialLength, _create, _release) {
+    var _length = 0;
+    var _maxLength = initialLength;
+    var pool = createSizedArray(_maxLength);
+
+    var ob = {
+      newElement: newElement,
+      release: release,
+    };
+
+    function newElement() {
+      var element;
+      if (_length) {
+        _length -= 1;
+        element = pool[_length];
+      } else {
+        element = _create();
+      }
+      return element;
+    }
+
+    function release(element) {
+      if (_length === _maxLength) {
+        pool = pooling.double(pool);
+        _maxLength *= 2;
+      }
+      if (_release) {
+        _release(element);
+      }
+      pool[_length] = element;
+      _length += 1;
+    }
+
+    return ob;
+  };
+}());
+
+const bezierLengthPool = (function () {
+  function create() {
+    return {
+      addedLength: 0,
+      percents: createTypedArray('float32', getDefaultCurveSegments()),
+      lengths: createTypedArray('float32', getDefaultCurveSegments()),
+    };
+  }
+  return poolFactory(8, create);
+}());
+
+const segmentsLengthPool = (function () {
+  function create() {
+    return {
+      lengths: [],
+      totalLength: 0,
+    };
+  }
+
+  function release(element) {
+    var i;
+    var len = element.lengths.length;
+    for (i = 0; i < len; i += 1) {
+      bezierLengthPool.release(element.lengths[i]);
+    }
+    element.lengths.length = 0;
+  }
+
+  return poolFactory(8, create, release);
+}());
+
+function bezFunction() {
+  var math = Math;
+
+  function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
+    var det1 = (x1 * y2) + (y1 * x3) + (x2 * y3) - (x3 * y2) - (y3 * x1) - (x2 * y1);
+    return det1 > -0.001 && det1 < 0.001;
+  }
+
+  function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
+    if (z1 === 0 && z2 === 0 && z3 === 0) {
+      return pointOnLine2D(x1, y1, x2, y2, x3, y3);
+    }
+    var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
+    var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
+    var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
+    var diffDist;
+    if (dist1 > dist2) {
+      if (dist1 > dist3) {
+        diffDist = dist1 - dist2 - dist3;
+      } else {
+        diffDist = dist3 - dist2 - dist1;
+      }
+    } else if (dist3 > dist2) {
+      diffDist = dist3 - dist2 - dist1;
+    } else {
+      diffDist = dist2 - dist1 - dist3;
+    }
+    return diffDist > -0.0001 && diffDist < 0.0001;
+  }
+
+  var getBezierLength = (function () {
+    return function (pt1, pt2, pt3, pt4) {
+      var curveSegments = getDefaultCurveSegments();
+      var k;
+      var i;
+      var len;
+      var ptCoord;
+      var perc;
+      var addedLength = 0;
+      var ptDistance;
+      var point = [];
+      var lastPoint = [];
+      var lengthData = bezierLengthPool.newElement();
+      len = pt3.length;
+      for (k = 0; k < curveSegments; k += 1) {
+        perc = k / (curveSegments - 1);
+        ptDistance = 0;
+        for (i = 0; i < len; i += 1) {
+          ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
+          point[i] = ptCoord;
+          if (lastPoint[i] !== null) {
+            ptDistance += bmPow(point[i] - lastPoint[i], 2);
+          }
+          lastPoint[i] = point[i];
+        }
+        if (ptDistance) {
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+        }
+        lengthData.percents[k] = perc;
+        lengthData.lengths[k] = addedLength;
+      }
+      lengthData.addedLength = addedLength;
+      return lengthData;
+    };
+  }());
+
+  function getSegmentsLength(shapeData) {
+    var segmentsLength = segmentsLengthPool.newElement();
+    var closed = shapeData.c;
+    var pathV = shapeData.v;
+    var pathO = shapeData.o;
+    var pathI = shapeData.i;
+    var i;
+    var len = shapeData._length;
+    var lengths = segmentsLength.lengths;
+    var totalLength = 0;
+    for (i = 0; i < len - 1; i += 1) {
+      lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
+      totalLength += lengths[i].addedLength;
+    }
+    if (closed && len) {
+      lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
+      totalLength += lengths[i].addedLength;
+    }
+    segmentsLength.totalLength = totalLength;
+    return segmentsLength;
+  }
+
+  function BezierData(length) {
+    this.segmentLength = 0;
+    this.points = new Array(length);
+  }
+
+  function PointData(partial, point) {
+    this.partialLength = partial;
+    this.point = point;
+  }
+
+  var buildBezierData = (function () {
+    var storedData = {};
+
+    return function (pt1, pt2, pt3, pt4) {
+      var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
+      if (!storedData[bezierName]) {
+        var curveSegments = getDefaultCurveSegments();
+        var k;
+        var i;
+        var len;
+        var ptCoord;
+        var perc;
+        var addedLength = 0;
+        var ptDistance;
+        var point;
+        var lastPoint = null;
+        if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
+          curveSegments = 2;
+        }
+        var bezierData = new BezierData(curveSegments);
+        len = pt3.length;
+        for (k = 0; k < curveSegments; k += 1) {
+          point = createSizedArray(len);
+          perc = k / (curveSegments - 1);
+          ptDistance = 0;
+          for (i = 0; i < len; i += 1) {
+            ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
+            point[i] = ptCoord;
+            if (lastPoint !== null) {
+              ptDistance += bmPow(point[i] - lastPoint[i], 2);
+            }
+          }
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+          bezierData.points[k] = new PointData(ptDistance, point);
+          lastPoint = point;
+        }
+        bezierData.segmentLength = addedLength;
+        storedData[bezierName] = bezierData;
+      }
+      return storedData[bezierName];
+    };
+  }());
+
+  function getDistancePerc(perc, bezierData) {
+    var percents = bezierData.percents;
+    var lengths = bezierData.lengths;
+    var len = percents.length;
+    var initPos = bmFloor((len - 1) * perc);
+    var lengthPos = perc * bezierData.addedLength;
+    var lPerc = 0;
+    if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
+      return percents[initPos];
+    }
+    var dir = lengths[initPos] > lengthPos ? -1 : 1;
+    var flag = true;
+    while (flag) {
+      if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
+        lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
+        flag = false;
+      } else {
+        initPos += dir;
+      }
+      if (initPos < 0 || initPos >= len - 1) {
+        // FIX for TypedArrays that don't store floating point values with enough accuracy
+        if (initPos === len - 1) {
+          return percents[initPos];
+        }
+        flag = false;
+      }
+    }
+    return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
+  }
+
+  function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
+    var t1 = getDistancePerc(percent, bezierData);
+    var u1 = 1 - t1;
+    var ptX = math.round((u1 * u1 * u1 * pt1[0] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[0] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[0] + t1 * t1 * t1 * pt2[0]) * 1000) / 1000;
+    var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
+    return [ptX, ptY];
+  }
+
+  var bezierSegmentPoints = createTypedArray('float32', 8);
+
+  function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
+    if (startPerc < 0) {
+      startPerc = 0;
+    } else if (startPerc > 1) {
+      startPerc = 1;
+    }
+    var t0 = getDistancePerc(startPerc, bezierData);
+    endPerc = endPerc > 1 ? 1 : endPerc;
+    var t1 = getDistancePerc(endPerc, bezierData);
+    var i;
+    var len = pt1.length;
+    var u0 = 1 - t0;
+    var u1 = 1 - t1;
+    var u0u0u0 = u0 * u0 * u0;
+    var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0t0 = t0 * t0 * t0;
+    //
+    var u0u0u1 = u0 * u0 * u1;
+    var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0t1 = t0 * t0 * t1;
+    //
+    var u0u1u1 = u0 * u1 * u1;
+    var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1t1 = t0 * t1 * t1;
+    //
+    var u1u1u1 = u1 * u1 * u1;
+    var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1t1 = t1 * t1 * t1;
+    for (i = 0; i < len; i += 1) {
+      bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+    }
+
+    return bezierSegmentPoints;
+  }
+
+  return {
+    getSegmentsLength: getSegmentsLength,
+    getNewSegment: getNewSegment,
+    getPointInSegment: getPointInSegment,
+    buildBezierData: buildBezierData,
+    pointOnLine2D: pointOnLine2D,
+    pointOnLine3D: pointOnLine3D,
+  };
+}
+
+const bez = bezFunction();
+
+var initFrame = initialDefaultFrame;
+var mathAbs = Math.abs;
+
+function interpolateValue(frameNum, caching) {
+  var offsetTime = this.offsetTime;
+  var newValue;
+  if (this.propType === 'multidimensional') {
+    newValue = createTypedArray('float32', this.pv.length);
+  }
+  var iterationIndex = caching.lastIndex;
+  var i = iterationIndex;
+  var len = this.keyframes.length - 1;
+  var flag = true;
+  var keyData;
+  var nextKeyData;
+  var keyframeMetadata;
+
+  while (flag) {
+    keyData = this.keyframes[i];
+    nextKeyData = this.keyframes[i + 1];
+    if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
+      if (keyData.h) {
+        keyData = nextKeyData;
+      }
+      iterationIndex = 0;
+      break;
+    }
+    if ((nextKeyData.t - offsetTime) > frameNum) {
+      iterationIndex = i;
+      break;
+    }
+    if (i < len - 1) {
+      i += 1;
+    } else {
+      iterationIndex = 0;
+      flag = false;
+    }
+  }
+  keyframeMetadata = this.keyframesMetadata[i] || {};
+
+  var k;
+  var kLen;
+  var perc;
+  var jLen;
+  var j;
+  var fnc;
+  var nextKeyTime = nextKeyData.t - offsetTime;
+  var keyTime = keyData.t - offsetTime;
+  var endValue;
+  if (keyData.to) {
+    if (!keyframeMetadata.bezierData) {
+      keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
+    }
+    var bezierData = keyframeMetadata.bezierData;
+    if (frameNum >= nextKeyTime || frameNum < keyTime) {
+      var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
+      kLen = bezierData.points[ind].point.length;
+      for (k = 0; k < kLen; k += 1) {
+        newValue[k] = bezierData.points[ind].point[k];
+      }
+      // caching._lastKeyframeIndex = -1;
+    } else {
+      if (keyframeMetadata.__fnct) {
+        fnc = keyframeMetadata.__fnct;
+      } else {
+        fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
+        keyframeMetadata.__fnct = fnc;
+      }
+      perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+      var distanceInLine = bezierData.segmentLength * perc;
+
+      var segmentPerc;
+      var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0;
+      j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0;
+      flag = true;
+      jLen = bezierData.points.length;
+      while (flag) {
+        addedLength += bezierData.points[j].partialLength;
+        if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k];
+          }
+          break;
+        } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
+          segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
+          }
+          break;
+        }
+        if (j < jLen - 1) {
+          j += 1;
+        } else {
+          flag = false;
+        }
+      }
+      caching._lastPoint = j;
+      caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
+      caching._lastKeyframeIndex = i;
+    }
+  } else {
+    var outX;
+    var outY;
+    var inX;
+    var inY;
+    var keyValue;
+    len = keyData.s.length;
+    endValue = nextKeyData.s || keyData.e;
+    if (this.sh && keyData.h !== 1) {
+      if (frameNum >= nextKeyTime) {
+        newValue[0] = endValue[0];
+        newValue[1] = endValue[1];
+        newValue[2] = endValue[2];
+      } else if (frameNum <= keyTime) {
+        newValue[0] = keyData.s[0];
+        newValue[1] = keyData.s[1];
+        newValue[2] = keyData.s[2];
+      } else {
+        var quatStart = createQuaternion(keyData.s);
+        var quatEnd = createQuaternion(endValue);
+        var time = (frameNum - keyTime) / (nextKeyTime - keyTime);
+        quaternionToEuler(newValue, slerp(quatStart, quatEnd, time));
+      }
+    } else {
+      for (i = 0; i < len; i += 1) {
+        if (keyData.h !== 1) {
+          if (frameNum >= nextKeyTime) {
+            perc = 1;
+          } else if (frameNum < keyTime) {
+            perc = 0;
+          } else {
+            if (keyData.o.x.constructor === Array) {
+              if (!keyframeMetadata.__fnct) {
+                keyframeMetadata.__fnct = [];
+              }
+              if (!keyframeMetadata.__fnct[i]) {
+                outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
+                outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
+                inX = keyData.i.x[i] === undefined ? keyData.i.x[0] : keyData.i.x[i];
+                inY = keyData.i.y[i] === undefined ? keyData.i.y[0] : keyData.i.y[i];
+                fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+                keyframeMetadata.__fnct[i] = fnc;
+              } else {
+                fnc = keyframeMetadata.__fnct[i];
+              }
+            } else if (!keyframeMetadata.__fnct) {
+              outX = keyData.o.x;
+              outY = keyData.o.y;
+              inX = keyData.i.x;
+              inY = keyData.i.y;
+              fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+              keyData.keyframeMetadata = fnc;
+            } else {
+              fnc = keyframeMetadata.__fnct;
+            }
+            perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+          }
+        }
+
+        endValue = nextKeyData.s || keyData.e;
+        keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
+
+        if (this.propType === 'multidimensional') {
+          newValue[i] = keyValue;
+        } else {
+          newValue = keyValue;
+        }
+      }
+    }
+  }
+  caching.lastIndex = iterationIndex;
+  return newValue;
+}
+
+// based on @Toji's https://github.com/toji/gl-matrix/
+function slerp(a, b, t) {
+  var out = [];
+  var ax = a[0];
+  var ay = a[1];
+  var az = a[2];
+  var aw = a[3];
+  var bx = b[0];
+  var by = b[1];
+  var bz = b[2];
+  var bw = b[3];
+
+  var omega;
+  var cosom;
+  var sinom;
+  var scale0;
+  var scale1;
+
+  cosom = ax * bx + ay * by + az * bz + aw * bw;
+  if (cosom < 0.0) {
+    cosom = -cosom;
+    bx = -bx;
+    by = -by;
+    bz = -bz;
+    bw = -bw;
+  }
+  if ((1.0 - cosom) > 0.000001) {
+    omega = Math.acos(cosom);
+    sinom = Math.sin(omega);
+    scale0 = Math.sin((1.0 - t) * omega) / sinom;
+    scale1 = Math.sin(t * omega) / sinom;
+  } else {
+    scale0 = 1.0 - t;
+    scale1 = t;
+  }
+  out[0] = scale0 * ax + scale1 * bx;
+  out[1] = scale0 * ay + scale1 * by;
+  out[2] = scale0 * az + scale1 * bz;
+  out[3] = scale0 * aw + scale1 * bw;
+
+  return out;
+}
+
+function quaternionToEuler(out, quat) {
+  var qx = quat[0];
+  var qy = quat[1];
+  var qz = quat[2];
+  var qw = quat[3];
+  var heading = Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy * qy - 2 * qz * qz);
+  var attitude = Math.asin(2 * qx * qy + 2 * qz * qw);
+  var bank = Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx * qx - 2 * qz * qz);
+  out[0] = heading / degToRads;
+  out[1] = attitude / degToRads;
+  out[2] = bank / degToRads;
+}
+
+function createQuaternion(values) {
+  var heading = values[0] * degToRads;
+  var attitude = values[1] * degToRads;
+  var bank = values[2] * degToRads;
+  var c1 = Math.cos(heading / 2);
+  var c2 = Math.cos(attitude / 2);
+  var c3 = Math.cos(bank / 2);
+  var s1 = Math.sin(heading / 2);
+  var s2 = Math.sin(attitude / 2);
+  var s3 = Math.sin(bank / 2);
+  var w = c1 * c2 * c3 - s1 * s2 * s3;
+  var x = s1 * s2 * c3 + c1 * c2 * s3;
+  var y = s1 * c2 * c3 + c1 * s2 * s3;
+  var z = c1 * s2 * c3 - s1 * c2 * s3;
+
+  return [x, y, z, w];
+}
+
+function getValueAtCurrentTime() {
+  var frameNum = this.comp.renderedFrame - this.offsetTime;
+  var initTime = this.keyframes[0].t - this.offsetTime;
+  var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+  if (!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))) {
+    if (this._caching.lastFrame >= frameNum) {
+      this._caching._lastKeyframeIndex = -1;
+      this._caching.lastIndex = 0;
+    }
+
+    var renderResult = this.interpolateValue(frameNum, this._caching);
+    this.pv = renderResult;
+  }
+  this._caching.lastFrame = frameNum;
+  return this.pv;
+}
+
+function setVValue(val) {
+  var multipliedValue;
+  if (this.propType === 'unidimensional') {
+    multipliedValue = val * this.mult;
+    if (mathAbs(this.v - multipliedValue) > 0.00001) {
+      this.v = multipliedValue;
+      this._mdf = true;
+    }
+  } else {
+    var i = 0;
+    var len = this.v.length;
+    while (i < len) {
+      multipliedValue = val[i] * this.mult;
+      if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
+        this.v[i] = multipliedValue;
+        this._mdf = true;
+      }
+      i += 1;
+    }
+  }
+}
+
+function processEffectsSequence() {
+  if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
+    return;
+  }
+  if (this.lock) {
+    this.setVValue(this.pv);
+    return;
+  }
+  this.lock = true;
+  this._mdf = this._isFirstFrame;
+  var i;
+  var len = this.effectsSequence.length;
+  var finalValue = this.kf ? this.pv : this.data.k;
+  for (i = 0; i < len; i += 1) {
+    finalValue = this.effectsSequence[i](finalValue);
+  }
+  this.setVValue(finalValue);
+  this._isFirstFrame = false;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+}
+
+function addEffect(effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.container.addDynamicProperty(this);
+}
+
+function ValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this.v = mult ? data.k * mult : data.k;
+  this.pv = data.k;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.vel = 0;
+  this.effectsSequence = [];
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function MultiDimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.frameId = -1;
+  var i;
+  var len = data.k.length;
+  this.v = createTypedArray('float32', len);
+  this.pv = createTypedArray('float32', len);
+  this.vel = createTypedArray('float32', len);
+  for (i = 0; i < len; i += 1) {
+    this.v[i] = data.k[i] * this.mult;
+    this.pv[i] = data.k[i];
+  }
+  this._isFirstFrame = true;
+  this.effectsSequence = [];
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function KeyframedValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.frameId = -1;
+  this._caching = {
+    lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1,
+  };
+  this.k = true;
+  this.kf = true;
+  this.data = data;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.v = initFrame;
+  this.pv = initFrame;
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.addEffect = addEffect;
+}
+
+function KeyframedMultidimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  var i;
+  var len = data.k.length;
+  var s;
+  var e;
+  var to;
+  var ti;
+  for (i = 0; i < len - 1; i += 1) {
+    if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
+      s = data.k[i].s;
+      e = data.k[i + 1].s;
+      to = data.k[i].to;
+      ti = data.k[i].ti;
+      if ((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2]))) {
+        data.k[i].to = null;
+        data.k[i].ti = null;
+      }
+      if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
+        if (s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) {
+          data.k[i].to = null;
+          data.k[i].ti = null;
+        }
+      }
+    }
+  }
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.data = data;
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.k = true;
+  this.kf = true;
+  this._isFirstFrame = true;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.frameId = -1;
+  var arrLen = data.k[0].s.length;
+  this.v = createTypedArray('float32', arrLen);
+  this.pv = createTypedArray('float32', arrLen);
+  for (i = 0; i < arrLen; i += 1) {
+    this.v[i] = initFrame;
+    this.pv[i] = initFrame;
+  }
+  this._caching = { lastFrame: initFrame, lastIndex: 0, value: createTypedArray('float32', arrLen) };
+  this.addEffect = addEffect;
+}
+
+const PropertyFactory = (function () {
+  function getProp(elem, data, type, mult, container) {
+    if (data.sid) {
+      data = elem.globalData.slotManager.getProp(data);
+    }
+    var p;
+    if (!data.k.length) {
+      p = new ValueProperty(elem, data, mult, container);
+    } else if (typeof (data.k[0]) === 'number') {
+      p = new MultiDimensionalProperty(elem, data, mult, container);
+    } else {
+      switch (type) {
+        case 0:
+          p = new KeyframedValueProperty(elem, data, mult, container);
+          break;
+        case 1:
+          p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
+          break;
+        default:
+          break;
+      }
+    }
+    if (p.effectsSequence.length) {
+      container.addDynamicProperty(p);
+    }
+    return p;
+  }
+
+  var ob = {
+    getProp: getProp,
+  };
+  return ob;
+}());
+
+function DynamicPropertyContainer() {}
+DynamicPropertyContainer.prototype = {
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+      this.container.addDynamicProperty(this);
+      this._isAnimated = true;
+    }
+  },
+  iterateDynamicProperties: function () {
+    this._mdf = false;
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      this.dynamicProperties[i].getValue();
+      if (this.dynamicProperties[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  },
+  initDynamicPropertyContainer: function (container) {
+    this.container = container;
+    this.dynamicProperties = [];
+    this._mdf = false;
+    this._isAnimated = false;
+  },
+};
+
+const pointPool = (function () {
+  function create() {
+    return createTypedArray('float32', 2);
+  }
+  return poolFactory(8, create);
+}());
+
+function ShapePath() {
+  this.c = false;
+  this._length = 0;
+  this._maxLength = 8;
+  this.v = createSizedArray(this._maxLength);
+  this.o = createSizedArray(this._maxLength);
+  this.i = createSizedArray(this._maxLength);
+}
+
+ShapePath.prototype.setPathData = function (closed, len) {
+  this.c = closed;
+  this.setLength(len);
+  var i = 0;
+  while (i < len) {
+    this.v[i] = pointPool.newElement();
+    this.o[i] = pointPool.newElement();
+    this.i[i] = pointPool.newElement();
+    i += 1;
+  }
+};
+
+ShapePath.prototype.setLength = function (len) {
+  while (this._maxLength < len) {
+    this.doubleArrayLength();
+  }
+  this._length = len;
+};
+
+ShapePath.prototype.doubleArrayLength = function () {
+  this.v = this.v.concat(createSizedArray(this._maxLength));
+  this.i = this.i.concat(createSizedArray(this._maxLength));
+  this.o = this.o.concat(createSizedArray(this._maxLength));
+  this._maxLength *= 2;
+};
+
+ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
+  var arr;
+  this._length = Math.max(this._length, pos + 1);
+  if (this._length >= this._maxLength) {
+    this.doubleArrayLength();
+  }
+  switch (type) {
+    case 'v':
+      arr = this.v;
+      break;
+    case 'i':
+      arr = this.i;
+      break;
+    case 'o':
+      arr = this.o;
+      break;
+    default:
+      arr = [];
+      break;
+  }
+  if (!arr[pos] || (arr[pos] && !replace)) {
+    arr[pos] = pointPool.newElement();
+  }
+  arr[pos][0] = x;
+  arr[pos][1] = y;
+};
+
+ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
+  this.setXYAt(vX, vY, 'v', pos, replace);
+  this.setXYAt(oX, oY, 'o', pos, replace);
+  this.setXYAt(iX, iY, 'i', pos, replace);
+};
+
+ShapePath.prototype.reverse = function () {
+  var newPath = new ShapePath();
+  newPath.setPathData(this.c, this._length);
+  var vertices = this.v;
+  var outPoints = this.o;
+  var inPoints = this.i;
+  var init = 0;
+  if (this.c) {
+    newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
+    init = 1;
+  }
+  var cnt = this._length - 1;
+  var len = this._length;
+
+  var i;
+  for (i = init; i < len; i += 1) {
+    newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
+    cnt -= 1;
+  }
+  return newPath;
+};
+
+ShapePath.prototype.length = function () {
+  return this._length;
+};
+
+const shapePool = (function () {
+  function create() {
+    return new ShapePath();
+  }
+
+  function release(shapePath) {
+    var len = shapePath._length;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      pointPool.release(shapePath.v[i]);
+      pointPool.release(shapePath.i[i]);
+      pointPool.release(shapePath.o[i]);
+      shapePath.v[i] = null;
+      shapePath.i[i] = null;
+      shapePath.o[i] = null;
+    }
+    shapePath._length = 0;
+    shapePath.c = false;
+  }
+
+  function clone(shape) {
+    var cloned = factory.newElement();
+    var i;
+    var len = shape._length === undefined ? shape.v.length : shape._length;
+    cloned.setLength(len);
+    cloned.c = shape.c;
+
+    for (i = 0; i < len; i += 1) {
+      cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
+    }
+    return cloned;
+  }
+
+  var factory = poolFactory(4, create, release);
+  factory.clone = clone;
+
+  return factory;
+}());
+
+function ShapeCollection() {
+  this._length = 0;
+  this._maxLength = 4;
+  this.shapes = createSizedArray(this._maxLength);
+}
+
+ShapeCollection.prototype.addShape = function (shapeData) {
+  if (this._length === this._maxLength) {
+    this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
+    this._maxLength *= 2;
+  }
+  this.shapes[this._length] = shapeData;
+  this._length += 1;
+};
+
+ShapeCollection.prototype.releaseShapes = function () {
+  var i;
+  for (i = 0; i < this._length; i += 1) {
+    shapePool.release(this.shapes[i]);
+  }
+  this._length = 0;
+};
+
+const shapeCollectionPool = (function () {
+  var ob = {
+    newShapeCollection: newShapeCollection,
+    release: release,
+  };
+
+  var _length = 0;
+  var _maxLength = 4;
+  var pool = createSizedArray(_maxLength);
+
+  function newShapeCollection() {
+    var shapeCollection;
+    if (_length) {
+      _length -= 1;
+      shapeCollection = pool[_length];
+    } else {
+      shapeCollection = new ShapeCollection();
+    }
+    return shapeCollection;
+  }
+
+  function release(shapeCollection) {
+    var i;
+    var len = shapeCollection._length;
+    for (i = 0; i < len; i += 1) {
+      shapePool.release(shapeCollection.shapes[i]);
+    }
+    shapeCollection._length = 0;
+
+    if (_length === _maxLength) {
+      pool = pooling.double(pool);
+      _maxLength *= 2;
+    }
+    pool[_length] = shapeCollection;
+    _length += 1;
+  }
+
+  return ob;
+}());
+
+const ShapePropertyFactory = (function () {
+  var initFrame = -999999;
+
+  function interpolateShape(frameNum, previousValue, caching) {
+    var iterationIndex = caching.lastIndex;
+    var keyPropS;
+    var keyPropE;
+    var isHold;
+    var j;
+    var k;
+    var jLen;
+    var kLen;
+    var perc;
+    var vertexValue;
+    var kf = this.keyframes;
+    if (frameNum < kf[0].t - this.offsetTime) {
+      keyPropS = kf[0].s[0];
+      isHold = true;
+      iterationIndex = 0;
+    } else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) {
+      keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
+      /* if(kf[kf.length - 1].s){
+                keyPropS = kf[kf.length - 1].s[0];
+            }else{
+                keyPropS = kf[kf.length - 2].e[0];
+            } */
+      isHold = true;
+    } else {
+      var i = iterationIndex;
+      var len = kf.length - 1;
+      var flag = true;
+      var keyData;
+      var nextKeyData;
+      var keyframeMetadata;
+      while (flag) {
+        keyData = kf[i];
+        nextKeyData = kf[i + 1];
+        if ((nextKeyData.t - this.offsetTime) > frameNum) {
+          break;
+        }
+        if (i < len - 1) {
+          i += 1;
+        } else {
+          flag = false;
+        }
+      }
+      keyframeMetadata = this.keyframesMetadata[i] || {};
+      isHold = keyData.h === 1;
+      iterationIndex = i;
+      if (!isHold) {
+        if (frameNum >= nextKeyData.t - this.offsetTime) {
+          perc = 1;
+        } else if (frameNum < keyData.t - this.offsetTime) {
+          perc = 0;
+        } else {
+          var fnc;
+          if (keyframeMetadata.__fnct) {
+            fnc = keyframeMetadata.__fnct;
+          } else {
+            fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
+            keyframeMetadata.__fnct = fnc;
+          }
+          perc = fnc((frameNum - (keyData.t - this.offsetTime)) / ((nextKeyData.t - this.offsetTime) - (keyData.t - this.offsetTime)));
+        }
+        keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
+      }
+      keyPropS = keyData.s[0];
+    }
+    jLen = previousValue._length;
+    kLen = keyPropS.i[0].length;
+    caching.lastIndex = iterationIndex;
+
+    for (j = 0; j < jLen; j += 1) {
+      for (k = 0; k < kLen; k += 1) {
+        vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
+        previousValue.i[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc;
+        previousValue.o[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc;
+        previousValue.v[j][k] = vertexValue;
+      }
+    }
+  }
+
+  function interpolateShapeCurrentTime() {
+    var frameNum = this.comp.renderedFrame - this.offsetTime;
+    var initTime = this.keyframes[0].t - this.offsetTime;
+    var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+    var lastFrame = this._caching.lastFrame;
+    if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) {
+      /// /
+      this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
+      this.interpolateShape(frameNum, this.pv, this._caching);
+      /// /
+    }
+    this._caching.lastFrame = frameNum;
+    return this.pv;
+  }
+
+  function resetShape() {
+    this.paths = this.localShapeCollection;
+  }
+
+  function shapesEqual(shape1, shape2) {
+    if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
+      return false;
+    }
+    var i;
+    var len = shape1._length;
+    for (i = 0; i < len; i += 1) {
+      if (shape1.v[i][0] !== shape2.v[i][0]
+            || shape1.v[i][1] !== shape2.v[i][1]
+            || shape1.o[i][0] !== shape2.o[i][0]
+            || shape1.o[i][1] !== shape2.o[i][1]
+            || shape1.i[i][0] !== shape2.i[i][0]
+            || shape1.i[i][1] !== shape2.i[i][1]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  function setVValue(newPath) {
+    if (!shapesEqual(this.v, newPath)) {
+      this.v = shapePool.clone(newPath);
+      this.localShapeCollection.releaseShapes();
+      this.localShapeCollection.addShape(this.v);
+      this._mdf = true;
+      this.paths = this.localShapeCollection;
+    }
+  }
+
+  function processEffectsSequence() {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    } if (!this.effectsSequence.length) {
+      this._mdf = false;
+      return;
+    }
+    if (this.lock) {
+      this.setVValue(this.pv);
+      return;
+    }
+    this.lock = true;
+    this._mdf = false;
+    var finalValue;
+    if (this.kf) {
+      finalValue = this.pv;
+    } else if (this.data.ks) {
+      finalValue = this.data.ks.k;
+    } else {
+      finalValue = this.data.pt.k;
+    }
+    var i;
+    var len = this.effectsSequence.length;
+    for (i = 0; i < len; i += 1) {
+      finalValue = this.effectsSequence[i](finalValue);
+    }
+    this.setVValue(finalValue);
+    this.lock = false;
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function ShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.container = elem;
+    this.elem = elem;
+    this.data = data;
+    this.k = false;
+    this.kf = false;
+    this._mdf = false;
+    var pathData = type === 3 ? data.pt.k : data.ks.k;
+    this.v = shapePool.clone(pathData);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.reset = resetShape;
+    this.effectsSequence = [];
+  }
+
+  function addEffect(effectFunction) {
+    this.effectsSequence.push(effectFunction);
+    this.container.addDynamicProperty(this);
+  }
+
+  ShapeProperty.prototype.interpolateShape = interpolateShape;
+  ShapeProperty.prototype.getValue = processEffectsSequence;
+  ShapeProperty.prototype.setVValue = setVValue;
+  ShapeProperty.prototype.addEffect = addEffect;
+
+  function KeyframedShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.elem = elem;
+    this.container = elem;
+    this.offsetTime = elem.data.st;
+    this.keyframes = type === 3 ? data.pt.k : data.ks.k;
+    this.keyframesMetadata = [];
+    this.k = true;
+    this.kf = true;
+    var len = this.keyframes[0].s[0].i.length;
+    this.v = shapePool.newElement();
+    this.v.setPathData(this.keyframes[0].s[0].c, len);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.lastFrame = initFrame;
+    this.reset = resetShape;
+    this._caching = { lastFrame: initFrame, lastIndex: 0 };
+    this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
+  }
+  KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
+  KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
+  KeyframedShapeProperty.prototype.setVValue = setVValue;
+  KeyframedShapeProperty.prototype.addEffect = addEffect;
+
+  var EllShapeProperty = (function () {
+    var cPoint = roundCorner;
+
+    function EllShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 4);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.paths = this.localShapeCollection;
+      this.localShapeCollection.addShape(this.v);
+      this.d = data.d;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertEllToPath();
+      }
+    }
+
+    EllShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+
+        if (this._mdf) {
+          this.convertEllToPath();
+        }
+      },
+      convertEllToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var s0 = this.s.v[0] / 2;
+        var s1 = this.s.v[1] / 2;
+        var _cw = this.d !== 3;
+        var _v = this.v;
+        _v.v[0][0] = p0;
+        _v.v[0][1] = p1 - s1;
+        _v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.v[1][1] = p1;
+        _v.v[2][0] = p0;
+        _v.v[2][1] = p1 + s1;
+        _v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.v[3][1] = p1;
+        _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.i[0][1] = p1 - s1;
+        _v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.i[1][1] = p1 - s1 * cPoint;
+        _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.i[2][1] = p1 + s1;
+        _v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.i[3][1] = p1 + s1 * cPoint;
+        _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.o[0][1] = p1 - s1;
+        _v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.o[1][1] = p1 + s1 * cPoint;
+        _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.o[2][1] = p1 + s1;
+        _v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.o[3][1] = p1 - s1 * cPoint;
+      },
+    };
+
+    extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
+
+    return EllShapePropertyFactory;
+  }());
+
+  var StarShapeProperty = (function () {
+    function StarShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 0);
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.data = data;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      if (data.sy === 1) {
+        this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
+        this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
+        this.convertToPath = this.convertStarToPath;
+      } else {
+        this.convertToPath = this.convertPolygonToPath;
+      }
+      this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
+      this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this);
+      this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertToPath();
+      }
+    }
+
+    StarShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertToPath();
+        }
+      },
+      convertStarToPath: function () {
+        var numPts = Math.floor(this.pt.v) * 2;
+        var angle = (Math.PI * 2) / numPts;
+        /* this.v.v.length = numPts;
+                this.v.i.length = numPts;
+                this.v.o.length = numPts; */
+        var longFlag = true;
+        var longRad = this.or.v;
+        var shortRad = this.ir.v;
+        var longRound = this.os.v;
+        var shortRound = this.is.v;
+        var longPerimSegment = (2 * Math.PI * longRad) / (numPts * 2);
+        var shortPerimSegment = (2 * Math.PI * shortRad) / (numPts * 2);
+        var i;
+        var rad;
+        var roundness;
+        var perimSegment;
+        var currentAng = -Math.PI / 2;
+        currentAng += this.r.v;
+        var dir = this.data.d === 3 ? -1 : 1;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          rad = longFlag ? longRad : shortRad;
+          roundness = longFlag ? longRound : shortRound;
+          perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
+          /* this.v.v[i] = [x,y];
+                    this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
+                    this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
+                    this.v._length = numPts; */
+          longFlag = !longFlag;
+          currentAng += angle * dir;
+        }
+      },
+      convertPolygonToPath: function () {
+        var numPts = Math.floor(this.pt.v);
+        var angle = (Math.PI * 2) / numPts;
+        var rad = this.or.v;
+        var roundness = this.os.v;
+        var perimSegment = (2 * Math.PI * rad) / (numPts * 4);
+        var i;
+        var currentAng = -Math.PI * 0.5;
+        var dir = this.data.d === 3 ? -1 : 1;
+        currentAng += this.r.v;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+          currentAng += angle * dir;
+        }
+        this.paths.length = 0;
+        this.paths[0] = this.v;
+      },
+
+    };
+    extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
+
+    return StarShapePropertyFactory;
+  }());
+
+  var RectShapeProperty = (function () {
+    function RectShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.c = true;
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertRectToPath();
+      }
+    }
+
+    RectShapePropertyFactory.prototype = {
+      convertRectToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var v0 = this.s.v[0] / 2;
+        var v1 = this.s.v[1] / 2;
+        var round = bmMin(v0, v1, this.r.v);
+        var cPoint = round * (1 - roundCorner);
+        this.v._length = 0;
+
+        if (this.d === 2 || this.d === 1) {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
+          this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2);
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3);
+          }
+        } else {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true);
+          }
+        }
+      },
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertRectToPath();
+        }
+      },
+      reset: resetShape,
+    };
+    extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
+
+    return RectShapePropertyFactory;
+  }());
+
+  function getShapeProp(elem, data, type) {
+    var prop;
+    if (type === 3 || type === 4) {
+      var dataProp = type === 3 ? data.pt : data.ks;
+      var keys = dataProp.k;
+      if (keys.length) {
+        prop = new KeyframedShapeProperty(elem, data, type);
+      } else {
+        prop = new ShapeProperty(elem, data, type);
+      }
+    } else if (type === 5) {
+      prop = new RectShapeProperty(elem, data);
+    } else if (type === 6) {
+      prop = new EllShapeProperty(elem, data);
+    } else if (type === 7) {
+      prop = new StarShapeProperty(elem, data);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  }
+
+  function getConstructorFunction() {
+    return ShapeProperty;
+  }
+
+  function getKeyframedConstructorFunction() {
+    return KeyframedShapeProperty;
+  }
+
+  var ob = {};
+  ob.getShapeProp = getShapeProp;
+  ob.getConstructorFunction = getConstructorFunction;
+  ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction;
+  return ob;
+}());
+
+/*!
+ Transformation Matrix v2.0
+ (c) Epistemex 2014-2015
+ www.epistemex.com
+ By Ken Fyrstenberg
+ Contributions by leeoniya.
+ License: MIT, header required.
+ */
+
+/**
+ * 2D transformation matrix object initialized with identity matrix.
+ *
+ * The matrix can synchronize a canvas context by supplying the context
+ * as an argument, or later apply current absolute transform to an
+ * existing context.
+ *
+ * All values are handled as floating point values.
+ *
+ * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix
+ * @prop {number} a - scale x
+ * @prop {number} b - shear y
+ * @prop {number} c - shear x
+ * @prop {number} d - scale y
+ * @prop {number} e - translate x
+ * @prop {number} f - translate y
+ * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context
+ * @constructor
+ */
+
+const Matrix = (function () {
+  var _cos = Math.cos;
+  var _sin = Math.sin;
+  var _tan = Math.tan;
+  var _rnd = Math.round;
+
+  function reset() {
+    this.props[0] = 1;
+    this.props[1] = 0;
+    this.props[2] = 0;
+    this.props[3] = 0;
+    this.props[4] = 0;
+    this.props[5] = 1;
+    this.props[6] = 0;
+    this.props[7] = 0;
+    this.props[8] = 0;
+    this.props[9] = 0;
+    this.props[10] = 1;
+    this.props[11] = 0;
+    this.props[12] = 0;
+    this.props[13] = 0;
+    this.props[14] = 0;
+    this.props[15] = 1;
+    return this;
+  }
+
+  function rotate(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function rotateX(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateY(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateZ(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function shear(sx, sy) {
+    return this._t(1, sy, sx, 1, 0, 0);
+  }
+
+  function skew(ax, ay) {
+    return this.shear(_tan(ax), _tan(ay));
+  }
+
+  function skewFromAxis(ax, angle) {
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+    // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+  }
+
+  function scale(sx, sy, sz) {
+    if (!sz && sz !== 0) {
+      sz = 1;
+    }
+    if (sx === 1 && sy === 1 && sz === 1) {
+      return this;
+    }
+    return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
+  }
+
+  function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
+    this.props[0] = a;
+    this.props[1] = b;
+    this.props[2] = c;
+    this.props[3] = d;
+    this.props[4] = e;
+    this.props[5] = f;
+    this.props[6] = g;
+    this.props[7] = h;
+    this.props[8] = i;
+    this.props[9] = j;
+    this.props[10] = k;
+    this.props[11] = l;
+    this.props[12] = m;
+    this.props[13] = n;
+    this.props[14] = o;
+    this.props[15] = p;
+    return this;
+  }
+
+  function translate(tx, ty, tz) {
+    tz = tz || 0;
+    if (tx !== 0 || ty !== 0 || tz !== 0) {
+      return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
+    }
+    return this;
+  }
+
+  function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
+    var _p = this.props;
+
+    if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
+      // NOTE: commenting this condition because TurboFan deoptimizes code when present
+      // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
+      _p[12] = _p[12] * a2 + _p[15] * m2;
+      _p[13] = _p[13] * f2 + _p[15] * n2;
+      _p[14] = _p[14] * k2 + _p[15] * o2;
+      _p[15] *= p2;
+      // }
+      this._identityCalculated = false;
+      return this;
+    }
+
+    var a1 = _p[0];
+    var b1 = _p[1];
+    var c1 = _p[2];
+    var d1 = _p[3];
+    var e1 = _p[4];
+    var f1 = _p[5];
+    var g1 = _p[6];
+    var h1 = _p[7];
+    var i1 = _p[8];
+    var j1 = _p[9];
+    var k1 = _p[10];
+    var l1 = _p[11];
+    var m1 = _p[12];
+    var n1 = _p[13];
+    var o1 = _p[14];
+    var p1 = _p[15];
+
+    /* matrix order (canvas compatible):
+         * ace
+         * bdf
+         * 001
+         */
+    _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
+    _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
+    _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
+    _p[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2;
+
+    _p[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2;
+    _p[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2;
+    _p[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2;
+    _p[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2;
+
+    _p[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2;
+    _p[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2;
+    _p[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2;
+    _p[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2;
+
+    _p[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2;
+    _p[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2;
+    _p[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2;
+    _p[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2;
+
+    this._identityCalculated = false;
+    return this;
+  }
+
+  function multiply(matrix) {
+    var matrixProps = matrix.props;
+    return this.transform(
+      matrixProps[0],
+      matrixProps[1],
+      matrixProps[2],
+      matrixProps[3],
+      matrixProps[4],
+      matrixProps[5],
+      matrixProps[6],
+      matrixProps[7],
+      matrixProps[8],
+      matrixProps[9],
+      matrixProps[10],
+      matrixProps[11],
+      matrixProps[12],
+      matrixProps[13],
+      matrixProps[14],
+      matrixProps[15]
+    );
+  }
+
+  function isIdentity() {
+    if (!this._identityCalculated) {
+      this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
+      this._identityCalculated = true;
+    }
+    return this._identity;
+  }
+
+  function equals(matr) {
+    var i = 0;
+    while (i < 16) {
+      if (matr.props[i] !== this.props[i]) {
+        return false;
+      }
+      i += 1;
+    }
+    return true;
+  }
+
+  function clone(matr) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      matr.props[i] = this.props[i];
+    }
+    return matr;
+  }
+
+  function cloneFromProps(props) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      this.props[i] = props[i];
+    }
+  }
+
+  function applyToPoint(x, y, z) {
+    return {
+      x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+      y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+      z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+    };
+    /* return {
+         x: x * me.a + y * me.c + me.e,
+         y: x * me.b + y * me.d + me.f
+         }; */
+  }
+  function applyToX(x, y, z) {
+    return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
+  }
+  function applyToY(x, y, z) {
+    return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
+  }
+  function applyToZ(x, y, z) {
+    return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
+  }
+
+  function getInverseMatrix() {
+    var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
+    var a = this.props[5] / determinant;
+    var b = -this.props[1] / determinant;
+    var c = -this.props[4] / determinant;
+    var d = this.props[0] / determinant;
+    var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12]) / determinant;
+    var f = -(this.props[0] * this.props[13] - this.props[1] * this.props[12]) / determinant;
+    var inverseMatrix = new Matrix();
+    inverseMatrix.props[0] = a;
+    inverseMatrix.props[1] = b;
+    inverseMatrix.props[4] = c;
+    inverseMatrix.props[5] = d;
+    inverseMatrix.props[12] = e;
+    inverseMatrix.props[13] = f;
+    return inverseMatrix;
+  }
+
+  function inversePoint(pt) {
+    var inverseMatrix = this.getInverseMatrix();
+    return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
+  }
+
+  function inversePoints(pts) {
+    var i;
+    var len = pts.length;
+    var retPts = [];
+    for (i = 0; i < len; i += 1) {
+      retPts[i] = inversePoint(pts[i]);
+    }
+    return retPts;
+  }
+
+  function applyToTriplePoints(pt1, pt2, pt3) {
+    var arr = createTypedArray('float32', 6);
+    if (this.isIdentity()) {
+      arr[0] = pt1[0];
+      arr[1] = pt1[1];
+      arr[2] = pt2[0];
+      arr[3] = pt2[1];
+      arr[4] = pt3[0];
+      arr[5] = pt3[1];
+    } else {
+      var p0 = this.props[0];
+      var p1 = this.props[1];
+      var p4 = this.props[4];
+      var p5 = this.props[5];
+      var p12 = this.props[12];
+      var p13 = this.props[13];
+      arr[0] = pt1[0] * p0 + pt1[1] * p4 + p12;
+      arr[1] = pt1[0] * p1 + pt1[1] * p5 + p13;
+      arr[2] = pt2[0] * p0 + pt2[1] * p4 + p12;
+      arr[3] = pt2[0] * p1 + pt2[1] * p5 + p13;
+      arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
+      arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
+    }
+    return arr;
+  }
+
+  function applyToPointArray(x, y, z) {
+    var arr;
+    if (this.isIdentity()) {
+      arr = [x, y, z];
+    } else {
+      arr = [
+        x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+        x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+        x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+      ];
+    }
+    return arr;
+  }
+
+  function applyToPointStringified(x, y) {
+    if (this.isIdentity()) {
+      return x + ',' + y;
+    }
+    var _p = this.props;
+    return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
+  }
+
+  function toCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var i = 0;
+    var props = this.props;
+    var cssValue = 'matrix3d(';
+    var v = 10000;
+    while (i < 16) {
+      cssValue += _rnd(props[i] * v) / v;
+      cssValue += i === 15 ? ')' : ',';
+      i += 1;
+    }
+    return cssValue;
+  }
+
+  function roundMatrixProperty(val) {
+    var v = 10000;
+    if ((val < 0.000001 && val > 0) || (val > -0.000001 && val < 0)) {
+      return _rnd(val * v) / v;
+    }
+    return val;
+  }
+
+  function to2dCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var props = this.props;
+    var _a = roundMatrixProperty(props[0]);
+    var _b = roundMatrixProperty(props[1]);
+    var _c = roundMatrixProperty(props[4]);
+    var _d = roundMatrixProperty(props[5]);
+    var _e = roundMatrixProperty(props[12]);
+    var _f = roundMatrixProperty(props[13]);
+    return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
+  }
+
+  return function () {
+    this.reset = reset;
+    this.rotate = rotate;
+    this.rotateX = rotateX;
+    this.rotateY = rotateY;
+    this.rotateZ = rotateZ;
+    this.skew = skew;
+    this.skewFromAxis = skewFromAxis;
+    this.shear = shear;
+    this.scale = scale;
+    this.setTransform = setTransform;
+    this.translate = translate;
+    this.transform = transform;
+    this.multiply = multiply;
+    this.applyToPoint = applyToPoint;
+    this.applyToX = applyToX;
+    this.applyToY = applyToY;
+    this.applyToZ = applyToZ;
+    this.applyToPointArray = applyToPointArray;
+    this.applyToTriplePoints = applyToTriplePoints;
+    this.applyToPointStringified = applyToPointStringified;
+    this.toCSS = toCSS;
+    this.to2dCSS = to2dCSS;
+    this.clone = clone;
+    this.cloneFromProps = cloneFromProps;
+    this.equals = equals;
+    this.inversePoints = inversePoints;
+    this.inversePoint = inversePoint;
+    this.getInverseMatrix = getInverseMatrix;
+    this._t = this.transform;
+    this.isIdentity = isIdentity;
+    this._identity = true;
+    this._identityCalculated = false;
+
+    this.props = createTypedArray('float32', 16);
+    this.reset();
+  };
+}());
+
+const lottie = {};
+var standalone = '__[STANDALONE]__';
+var animationData = '__[ANIMATIONDATA]__';
+var renderer = '';
+
+function setLocation(href) {
+  setLocationHref(href);
+}
+
+function searchAnimations() {
+  if (standalone === true) {
+    animationManager.searchAnimations(animationData, standalone, renderer);
+  } else {
+    animationManager.searchAnimations();
+  }
+}
+
+function setSubframeRendering(flag) {
+  setSubframeEnabled(flag);
+}
+
+function setPrefix(prefix) {
+  setIdPrefix(prefix);
+}
+
+function loadAnimation(params) {
+  if (standalone === true) {
+    params.animationData = JSON.parse(animationData);
+  }
+  return animationManager.loadAnimation(params);
+}
+
+function setQuality(value) {
+  if (typeof value === 'string') {
+    switch (value) {
+      case 'high':
+        setDefaultCurveSegments(200);
+        break;
+      default:
+      case 'medium':
+        setDefaultCurveSegments(50);
+        break;
+      case 'low':
+        setDefaultCurveSegments(10);
+        break;
+    }
+  } else if (!isNaN(value) && value > 1) {
+    setDefaultCurveSegments(value);
+  }
+  if (getDefaultCurveSegments() >= 50) {
+    roundValues(false);
+  } else {
+    roundValues(true);
+  }
+}
+
+function inBrowser() {
+  return typeof navigator !== 'undefined';
+}
+
+function installPlugin(type, plugin) {
+  if (type === 'expressions') {
+    setExpressionsPlugin(plugin);
+  }
+}
+
+function getFactory(name) {
+  switch (name) {
+    case 'propertyFactory':
+      return PropertyFactory;
+    case 'shapePropertyFactory':
+      return ShapePropertyFactory;
+    case 'matrix':
+      return Matrix;
+    default:
+      return null;
+  }
+}
+
+lottie.play = animationManager.play;
+lottie.pause = animationManager.pause;
+lottie.setLocationHref = setLocation;
+lottie.togglePause = animationManager.togglePause;
+lottie.setSpeed = animationManager.setSpeed;
+lottie.setDirection = animationManager.setDirection;
+lottie.stop = animationManager.stop;
+lottie.searchAnimations = searchAnimations;
+lottie.registerAnimation = animationManager.registerAnimation;
+lottie.loadAnimation = loadAnimation;
+lottie.setSubframeRendering = setSubframeRendering;
+lottie.resize = animationManager.resize;
+// lottie.start = start;
+lottie.goToAndStop = animationManager.goToAndStop;
+lottie.destroy = animationManager.destroy;
+lottie.setQuality = setQuality;
+lottie.inBrowser = inBrowser;
+lottie.installPlugin = installPlugin;
+lottie.freeze = animationManager.freeze;
+lottie.unfreeze = animationManager.unfreeze;
+lottie.setVolume = animationManager.setVolume;
+lottie.mute = animationManager.mute;
+lottie.unmute = animationManager.unmute;
+lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations;
+lottie.useWebWorker = setWebWorker;
+lottie.setIDPrefix = setPrefix;
+lottie.__getFactory = getFactory;
+lottie.version = '[[BM_VERSION]]';
+
+function checkReady() {
+  if (document.readyState === 'complete') {
+    clearInterval(readyStateCheckInterval);
+    searchAnimations();
+  }
+}
+
+function getQueryVariable(variable) {
+  var vars = queryString.split('&');
+  for (var i = 0; i < vars.length; i += 1) {
+    var pair = vars[i].split('=');
+    if (decodeURIComponent(pair[0]) == variable) { // eslint-disable-line eqeqeq
+      return decodeURIComponent(pair[1]);
+    }
+  }
+  return null;
+}
+var queryString = '';
+if (standalone) {
+  var scripts = document.getElementsByTagName('script');
+  var index = scripts.length - 1;
+  var myScript = scripts[index] || {
+    src: '',
+  };
+  queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
+  renderer = getQueryVariable('renderer');
+}
+var readyStateCheckInterval = setInterval(checkReady, 100);
+
+// this adds bodymovin to the window object for backwards compatibility
+try {
+  if (!(typeof exports === 'object' && typeof module !== 'undefined')
+    && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
+  ) {
+    window.bodymovin = lottie;
+  }
+} catch (err) {
+  //
+}
+
+const ShapeModifiers = (function () {
+  var ob = {};
+  var modifiers = {};
+  ob.registerModifier = registerModifier;
+  ob.getModifier = getModifier;
+
+  function registerModifier(nm, factory) {
+    if (!modifiers[nm]) {
+      modifiers[nm] = factory;
+    }
+  }
+
+  function getModifier(nm, elem, data) {
+    return new modifiers[nm](elem, data);
+  }
+
+  return ob;
+}());
+
+function ShapeModifier() {}
+ShapeModifier.prototype.initModifierProperties = function () {};
+ShapeModifier.prototype.addShapeToModifier = function () {};
+ShapeModifier.prototype.addShape = function (data) {
+  if (!this.closed) {
+    // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
+    data.sh.container.addDynamicProperty(data.sh);
+    var shapeData = { shape: data.sh, data: data, localShapeCollection: shapeCollectionPool.newShapeCollection() };
+    this.shapes.push(shapeData);
+    this.addShapeToModifier(shapeData);
+    if (this._isAnimated) {
+      data.setAsAnimated();
+    }
+  }
+};
+ShapeModifier.prototype.init = function (elem, data) {
+  this.shapes = [];
+  this.elem = elem;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, data);
+  this.frameId = initialDefaultFrame;
+  this.closed = false;
+  this.k = false;
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+ShapeModifier.prototype.processKeys = function () {
+  if (this.elem.globalData.frameId === this.frameId) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+extendPrototype([DynamicPropertyContainer], ShapeModifier);
+
+function TrimModifier() {
+}
+extendPrototype([ShapeModifier], TrimModifier);
+TrimModifier.prototype.initModifierProperties = function (elem, data) {
+  this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this);
+  this.sValue = 0;
+  this.eValue = 0;
+  this.getValue = this.processKeys;
+  this.m = data.m;
+  this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
+};
+
+TrimModifier.prototype.addShapeToModifier = function (shapeData) {
+  shapeData.pathsData = [];
+};
+
+TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
+  var segments = [];
+  if (e <= 1) {
+    segments.push({
+      s: s,
+      e: e,
+    });
+  } else if (s >= 1) {
+    segments.push({
+      s: s - 1,
+      e: e - 1,
+    });
+  } else {
+    segments.push({
+      s: s,
+      e: 1,
+    });
+    segments.push({
+      s: 0,
+      e: e - 1,
+    });
+  }
+  var shapeSegments = [];
+  var i;
+  var len = segments.length;
+  var segmentOb;
+  for (i = 0; i < len; i += 1) {
+    segmentOb = segments[i];
+    if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
+      var shapeS;
+      var shapeE;
+      if (segmentOb.s * totalModifierLength <= addedLength) {
+        shapeS = 0;
+      } else {
+        shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
+      }
+      if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
+        shapeE = 1;
+      } else {
+        shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength);
+      }
+      shapeSegments.push([shapeS, shapeE]);
+    }
+  }
+  if (!shapeSegments.length) {
+    shapeSegments.push([0, 0]);
+  }
+  return shapeSegments;
+};
+
+TrimModifier.prototype.releasePathsData = function (pathsData) {
+  var i;
+  var len = pathsData.length;
+  for (i = 0; i < len; i += 1) {
+    segmentsLengthPool.release(pathsData[i]);
+  }
+  pathsData.length = 0;
+  return pathsData;
+};
+
+TrimModifier.prototype.processShapes = function (_isFirstFrame) {
+  var s;
+  var e;
+  if (this._mdf || _isFirstFrame) {
+    var o = (this.o.v % 360) / 360;
+    if (o < 0) {
+      o += 1;
+    }
+    if (this.s.v > 1) {
+      s = 1 + o;
+    } else if (this.s.v < 0) {
+      s = 0 + o;
+    } else {
+      s = this.s.v + o;
+    }
+    if (this.e.v > 1) {
+      e = 1 + o;
+    } else if (this.e.v < 0) {
+      e = 0 + o;
+    } else {
+      e = this.e.v + o;
+    }
+
+    if (s > e) {
+      var _s = s;
+      s = e;
+      e = _s;
+    }
+    s = Math.round(s * 10000) * 0.0001;
+    e = Math.round(e * 10000) * 0.0001;
+    this.sValue = s;
+    this.eValue = e;
+  } else {
+    s = this.sValue;
+    e = this.eValue;
+  }
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var pathsData;
+  var pathData;
+  var totalShapeLength;
+  var totalModifierLength = 0;
+
+  if (e === s) {
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].localShapeCollection.releaseShapes();
+      this.shapes[i].shape._mdf = true;
+      this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
+      if (this._mdf) {
+        this.shapes[i].pathsData.length = 0;
+      }
+    }
+  } else if (!((e === 1 && s === 0) || (e === 0 && s === 1))) {
+    var segments = [];
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
+      if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
+        shapeData.shape.paths = shapeData.localShapeCollection;
+      } else {
+        shapePaths = shapeData.shape.paths;
+        jLen = shapePaths._length;
+        totalShapeLength = 0;
+        if (!shapeData.shape._mdf && shapeData.pathsData.length) {
+          totalShapeLength = shapeData.totalShapeLength;
+        } else {
+          pathsData = this.releasePathsData(shapeData.pathsData);
+          for (j = 0; j < jLen; j += 1) {
+            pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
+            pathsData.push(pathData);
+            totalShapeLength += pathData.totalLength;
+          }
+          shapeData.totalShapeLength = totalShapeLength;
+          shapeData.pathsData = pathsData;
+        }
+
+        totalModifierLength += totalShapeLength;
+        shapeData.shape._mdf = true;
+      }
+    }
+    var shapeS = s;
+    var shapeE = e;
+    var addedLength = 0;
+    var edges;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shapeData = this.shapes[i];
+      if (shapeData.shape._mdf) {
+        localShapeCollection = shapeData.localShapeCollection;
+        localShapeCollection.releaseShapes();
+        // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
+        if (this.m === 2 && len > 1) {
+          edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
+          addedLength += shapeData.totalShapeLength;
+        } else {
+          edges = [[shapeS, shapeE]];
+        }
+        jLen = edges.length;
+        for (j = 0; j < jLen; j += 1) {
+          shapeS = edges[j][0];
+          shapeE = edges[j][1];
+          segments.length = 0;
+          if (shapeE <= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength * shapeE,
+            });
+          } else if (shapeS >= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * (shapeS - 1),
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          } else {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength,
+            });
+            segments.push({
+              s: 0,
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          }
+          var newShapesData = this.addShapes(shapeData, segments[0]);
+          if (segments[0].s !== segments[0].e) {
+            if (segments.length > 1) {
+              var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
+              if (lastShapeInCollection.c) {
+                var lastShape = newShapesData.pop();
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1], lastShape);
+              } else {
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1]);
+              }
+            }
+            this.addPaths(newShapesData, localShapeCollection);
+          }
+        }
+        shapeData.shape.paths = localShapeCollection;
+      }
+    }
+  } else if (this._mdf) {
+    for (i = 0; i < len; i += 1) {
+      // Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween.
+      // Don't remove this even if it's losing cached info.
+      this.shapes[i].pathsData.length = 0;
+      this.shapes[i].shape._mdf = true;
+    }
+  }
+};
+
+TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
+  var i;
+  var len = newPaths.length;
+  for (i = 0; i < len; i += 1) {
+    localShapeCollection.addShape(newPaths[i]);
+  }
+};
+
+TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
+  shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
+  shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
+  }
+  shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
+  shapePath.setXYAt(points[1], points[5], 'o', pos);
+  shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(points[0], points[4], 'v', pos);
+  }
+  shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
+  var pathsData = shapeData.pathsData;
+  var shapePaths = shapeData.shape.paths.shapes;
+  var i;
+  var len = shapeData.shape.paths._length;
+  var j;
+  var jLen;
+  var addedLength = 0;
+  var currentLengthData;
+  var segmentCount;
+  var lengths;
+  var segment;
+  var shapes = [];
+  var initPos;
+  var newShape = true;
+  if (!shapePath) {
+    shapePath = shapePool.newElement();
+    segmentCount = 0;
+    initPos = 0;
+  } else {
+    segmentCount = shapePath._length;
+    initPos = shapePath._length;
+  }
+  shapes.push(shapePath);
+  for (i = 0; i < len; i += 1) {
+    lengths = pathsData[i].lengths;
+    shapePath.c = shapePaths[i].c;
+    jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
+    for (j = 1; j < jLen; j += 1) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
+        addedLength += currentLengthData.addedLength;
+        shapePath.c = false;
+      } else if (addedLength > shapeSegment.e) {
+        shapePath.c = false;
+        break;
+      } else {
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+        addedLength += currentLengthData.addedLength;
+        segmentCount += 1;
+      }
+    }
+    if (shapePaths[i].c && lengths.length) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength <= shapeSegment.e) {
+        var segmentLength = lengths[j - 1].addedLength;
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+      } else {
+        shapePath.c = false;
+      }
+      addedLength += currentLengthData.addedLength;
+      segmentCount += 1;
+    }
+    if (shapePath._length) {
+      shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
+      shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
+    }
+    if (addedLength > shapeSegment.e) {
+      break;
+    }
+    if (i < len - 1) {
+      shapePath = shapePool.newElement();
+      newShape = true;
+      shapes.push(shapePath);
+      segmentCount = 0;
+    }
+  }
+  return shapes;
+};
+
+function PuckerAndBloatModifier() {}
+extendPrototype([ShapeModifier], PuckerAndBloatModifier);
+PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this._isAnimated = !!this.amount.effectsSequence.length;
+};
+
+PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
+  var percent = amount / 100;
+  var centerPoint = [0, 0];
+  var pathLength = path._length;
+  var i = 0;
+  for (i = 0; i < pathLength; i += 1) {
+    centerPoint[0] += path.v[i][0];
+    centerPoint[1] += path.v[i][1];
+  }
+  centerPoint[0] /= pathLength;
+  centerPoint[1] /= pathLength;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < pathLength; i += 1) {
+    vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
+    vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
+    oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent;
+    oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent;
+    iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent;
+    iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
+    clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
+  }
+  return clonedPath;
+};
+
+PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+const TransformPropertyFactory = (function () {
+  var defaultVector = [0, 0];
+
+  function applyToMatrix(mat) {
+    var _mdf = this._mdf;
+    this.iterateDynamicProperties();
+    this._mdf = this._mdf || _mdf;
+    if (this.a) {
+      mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+    }
+    if (this.s) {
+      mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+    }
+    if (this.sk) {
+      mat.skewFromAxis(-this.sk.v, this.sa.v);
+    }
+    if (this.r) {
+      mat.rotate(-this.r.v);
+    } else {
+      mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+    }
+    if (this.data.p.s) {
+      if (this.data.p.z) {
+        mat.translate(this.px.v, this.py.v, -this.pz.v);
+      } else {
+        mat.translate(this.px.v, this.py.v, 0);
+      }
+    } else {
+      mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+    }
+  }
+  function processKeys(forceRender) {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    }
+    if (this._isDirty) {
+      this.precalculateMatrix();
+      this._isDirty = false;
+    }
+
+    this.iterateDynamicProperties();
+
+    if (this._mdf || forceRender) {
+      var frameRate;
+      this.v.cloneFromProps(this.pre.props);
+      if (this.appliedTransformations < 1) {
+        this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      }
+      if (this.appliedTransformations < 2) {
+        this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      }
+      if (this.sk && this.appliedTransformations < 3) {
+        this.v.skewFromAxis(-this.sk.v, this.sa.v);
+      }
+      if (this.r && this.appliedTransformations < 4) {
+        this.v.rotate(-this.r.v);
+      } else if (!this.r && this.appliedTransformations < 4) {
+        this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+          .rotateY(this.or.v[1])
+          .rotateX(this.or.v[0]);
+      }
+      if (this.autoOriented) {
+        var v1;
+        var v2;
+        frameRate = this.elem.globalData.frameRate;
+        if (this.p && this.p.keyframes && this.p.getValueAtTime) {
+          if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
+            v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0);
+          } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0);
+            v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0);
+          } else {
+            v1 = this.p.pv;
+            v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime);
+          }
+        } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) {
+          v1 = [];
+          v2 = [];
+          var px = this.px;
+          var py = this.py;
+          if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
+            v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
+            v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate, 0);
+          } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate), 0);
+            v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate), 0);
+            v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0);
+          } else {
+            v1 = [px.pv, py.pv];
+            v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime);
+            v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime);
+          }
+        } else {
+          v2 = defaultVector;
+          v1 = v2;
+        }
+        this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
+      }
+      if (this.data.p && this.data.p.s) {
+        if (this.data.p.z) {
+          this.v.translate(this.px.v, this.py.v, -this.pz.v);
+        } else {
+          this.v.translate(this.px.v, this.py.v, 0);
+        }
+      } else {
+        this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+      }
+    }
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function precalculateMatrix() {
+    this.appliedTransformations = 0;
+    this.pre.reset();
+
+    if (!this.a.effectsSequence.length) {
+      this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      this.appliedTransformations = 1;
+    } else {
+      return;
+    }
+    if (!this.s.effectsSequence.length) {
+      this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      this.appliedTransformations = 2;
+    } else {
+      return;
+    }
+    if (this.sk) {
+      if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
+        this.pre.skewFromAxis(-this.sk.v, this.sa.v);
+        this.appliedTransformations = 3;
+      } else {
+        return;
+      }
+    }
+    if (this.r) {
+      if (!this.r.effectsSequence.length) {
+        this.pre.rotate(-this.r.v);
+        this.appliedTransformations = 4;
+      }
+    } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) {
+      this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+      this.appliedTransformations = 4;
+    }
+  }
+
+  function autoOrient() {
+    //
+    // var prevP = this.getValueAtTime();
+  }
+
+  function addDynamicProperty(prop) {
+    this._addDynamicProperty(prop);
+    this.elem.addDynamicProperty(prop);
+    this._isDirty = true;
+  }
+
+  function TransformProperty(elem, data, container) {
+    this.elem = elem;
+    this.frameId = -1;
+    this.propType = 'transform';
+    this.data = data;
+    this.v = new Matrix();
+    // Precalculated matrix with non animated properties
+    this.pre = new Matrix();
+    this.appliedTransformations = 0;
+    this.initDynamicPropertyContainer(container || elem);
+    if (data.p && data.p.s) {
+      this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
+      this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
+      if (data.p.z) {
+        this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
+      }
+    } else {
+      this.p = PropertyFactory.getProp(elem, data.p || { k: [0, 0, 0] }, 1, 0, this);
+    }
+    if (data.rx) {
+      this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
+      this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
+      this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
+      if (data.or.k[0].ti) {
+        var i;
+        var len = data.or.k.length;
+        for (i = 0; i < len; i += 1) {
+          data.or.k[i].to = null;
+          data.or.k[i].ti = null;
+        }
+      }
+      this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+      // sh Indicates it needs to be capped between -180 and 180
+      this.or.sh = true;
+    } else {
+      this.r = PropertyFactory.getProp(elem, data.r || { k: 0 }, 0, degToRads, this);
+    }
+    if (data.sk) {
+      this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
+      this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
+    }
+    this.a = PropertyFactory.getProp(elem, data.a || { k: [0, 0, 0] }, 1, 0, this);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: [100, 100, 100] }, 1, 0.01, this);
+    // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
+    if (data.o) {
+      this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
+    } else {
+      this.o = { _mdf: false, v: 1 };
+    }
+    this._isDirty = true;
+    if (!this.dynamicProperties.length) {
+      this.getValue(true);
+    }
+  }
+
+  TransformProperty.prototype = {
+    applyToMatrix: applyToMatrix,
+    getValue: processKeys,
+    precalculateMatrix: precalculateMatrix,
+    autoOrient: autoOrient,
+  };
+
+  extendPrototype([DynamicPropertyContainer], TransformProperty);
+  TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
+  TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
+
+  function getTransformProperty(elem, data, container) {
+    return new TransformProperty(elem, data, container);
+  }
+
+  return {
+    getTransformProperty: getTransformProperty,
+  };
+}());
+
+function RepeaterModifier() {}
+extendPrototype([ShapeModifier], RepeaterModifier);
+
+RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, null, this);
+  this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this);
+  this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
+  this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
+  this.data = data;
+  if (!this.dynamicProperties.length) {
+    this.getValue(true);
+  }
+  this._isAnimated = !!this.dynamicProperties.length;
+  this.pMatrix = new Matrix();
+  this.rMatrix = new Matrix();
+  this.sMatrix = new Matrix();
+  this.tMatrix = new Matrix();
+  this.matrix = new Matrix();
+};
+
+RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
+  var dir = inv ? -1 : 1;
+  var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
+  var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
+  pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
+  rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  rMatrix.rotate(-transform.r.v * dir * perc);
+  rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+  sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
+  sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+};
+
+RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
+  this.elem = elem;
+  this.arr = arr;
+  this.pos = pos;
+  this.elemsData = elemsData;
+  this._currentCopies = 0;
+  this._elements = [];
+  this._groups = [];
+  this.frameId = -1;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, arr[pos]);
+  while (pos > 0) {
+    pos -= 1;
+    // this._elements.unshift(arr.splice(pos,1)[0]);
+    this._elements.unshift(arr[pos]);
+  }
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+
+RepeaterModifier.prototype.resetElements = function (elements) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._processed = false;
+    if (elements[i].ty === 'gr') {
+      this.resetElements(elements[i].it);
+    }
+  }
+};
+
+RepeaterModifier.prototype.cloneElements = function (elements) {
+  var newElements = JSON.parse(JSON.stringify(elements));
+  this.resetElements(newElements);
+  return newElements;
+};
+
+RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._render = renderFlag;
+    if (elements[i].ty === 'gr') {
+      this.changeGroupRender(elements[i].it, renderFlag);
+    }
+  }
+};
+
+RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
+  var items;
+  var itemsTransform;
+  var i;
+  var dir;
+  var cont;
+  var hasReloaded = false;
+  if (this._mdf || _isFirstFrame) {
+    var copies = Math.ceil(this.c.v);
+    if (this._groups.length < copies) {
+      while (this._groups.length < copies) {
+        var group = {
+          it: this.cloneElements(this._elements),
+          ty: 'gr',
+        };
+        group.it.push({
+          a: { a: 0, ix: 1, k: [0, 0] }, nm: 'Transform', o: { a: 0, ix: 7, k: 100 }, p: { a: 0, ix: 2, k: [0, 0] }, r: { a: 1, ix: 6, k: [{ s: 0, e: 0, t: 0 }, { s: 0, e: 0, t: 1 }] }, s: { a: 0, ix: 3, k: [100, 100] }, sa: { a: 0, ix: 5, k: 0 }, sk: { a: 0, ix: 4, k: 0 }, ty: 'tr',
+        });
+
+        this.arr.splice(0, 0, group);
+        this._groups.splice(0, 0, group);
+        this._currentCopies += 1;
+      }
+      this.elem.reloadShapes();
+      hasReloaded = true;
+    }
+    cont = 0;
+    var renderFlag;
+    for (i = 0; i <= this._groups.length - 1; i += 1) {
+      renderFlag = cont < copies;
+      this._groups[i]._render = renderFlag;
+      this.changeGroupRender(this._groups[i].it, renderFlag);
+      if (!renderFlag) {
+        var elems = this.elemsData[i].it;
+        var transformData = elems[elems.length - 1];
+        if (transformData.transform.op.v !== 0) {
+          transformData.transform.op._mdf = true;
+          transformData.transform.op.v = 0;
+        } else {
+          transformData.transform.op._mdf = false;
+        }
+      }
+      cont += 1;
+    }
+
+    this._currentCopies = copies;
+    /// /
+
+    var offset = this.o.v;
+    var offsetModulo = offset % 1;
+    var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
+    var pProps = this.pMatrix.props;
+    var rProps = this.rMatrix.props;
+    var sProps = this.sMatrix.props;
+    this.pMatrix.reset();
+    this.rMatrix.reset();
+    this.sMatrix.reset();
+    this.tMatrix.reset();
+    this.matrix.reset();
+    var iteration = 0;
+
+    if (offset > 0) {
+      while (iteration < roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        iteration += 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
+        iteration += offsetModulo;
+      }
+    } else if (offset < 0) {
+      while (iteration > roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
+        iteration -= 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
+        iteration -= offsetModulo;
+      }
+    }
+    i = this.data.m === 1 ? 0 : this._currentCopies - 1;
+    dir = this.data.m === 1 ? 1 : -1;
+    cont = this._currentCopies;
+    var j;
+    var jLen;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      jLen = itemsTransform.length;
+      items[items.length - 1].transform.mProps._mdf = true;
+      items[items.length - 1].transform.op._mdf = true;
+      items[items.length - 1].transform.op.v = this._currentCopies === 1
+        ? this.so.v
+        : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
+
+      if (iteration !== 0) {
+        if ((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)) {
+          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        }
+        this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
+        this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
+        this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
+
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+        this.matrix.reset();
+      } else {
+        this.matrix.reset();
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+      }
+      iteration += 1;
+      cont -= 1;
+      i += dir;
+    }
+  } else {
+    cont = this._currentCopies;
+    i = 0;
+    dir = 1;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      items[items.length - 1].transform.mProps._mdf = false;
+      items[items.length - 1].transform.op._mdf = false;
+      cont -= 1;
+      i += dir;
+    }
+  }
+  return hasReloaded;
+};
+
+RepeaterModifier.prototype.addShape = function () {};
+
+function RoundCornersModifier() {}
+extendPrototype([ShapeModifier], RoundCornersModifier);
+RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this._isAnimated = !!this.rd.effectsSequence.length;
+};
+
+RoundCornersModifier.prototype.processPath = function (path, round) {
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var i;
+  var len = path._length;
+  var currentV;
+  var currentI;
+  var currentO;
+  var closerV;
+  var distance;
+  var newPosPerc;
+  var index = 0;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < len; i += 1) {
+    currentV = path.v[i];
+    currentO = path.o[i];
+    currentI = path.i[i];
+    if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
+      if ((i === 0 || i === len - 1) && !path.c) {
+        clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
+        /* clonedPath.v[index] = currentV;
+                clonedPath.o[index] = currentO;
+                clonedPath.i[index] = currentI; */
+        index += 1;
+      } else {
+        if (i === 0) {
+          closerV = path.v[len - 1];
+        } else {
+          closerV = path.v[i - 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = iX;
+        iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
+        vY = iY;
+        oX = vX - (vX - currentV[0]) * roundCorner;
+        oY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+
+        if (i === len - 1) {
+          closerV = path.v[0];
+        } else {
+          closerV = path.v[i + 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = oX;
+        oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc;
+        vY = oY;
+        iX = vX - (vX - currentV[0]) * roundCorner;
+        iY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+      }
+    } else {
+      clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index);
+      index += 1;
+    }
+  }
+  return clonedPath;
+};
+
+RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var rd = this.rd.v;
+
+  if (rd !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function floatEqual(a, b) {
+  return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
+}
+
+function floatZero(f) {
+  return Math.abs(f) <= 0.00001;
+}
+
+function lerp(p0, p1, amount) {
+  return p0 * (1 - amount) + p1 * amount;
+}
+
+function lerpPoint(p0, p1, amount) {
+  return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
+}
+
+function quadRoots(a, b, c) {
+  // no root
+  if (a === 0) return [];
+  var s = b * b - 4 * a * c;
+  // Complex roots
+  if (s < 0) return [];
+  var singleRoot = -b / (2 * a);
+  // 1 root
+  if (s === 0) return [singleRoot];
+  var delta = Math.sqrt(s) / (2 * a);
+  // 2 roots
+  return [singleRoot - delta, singleRoot + delta];
+}
+
+function polynomialCoefficients(p0, p1, p2, p3) {
+  return [
+    -p0 + 3 * p1 - 3 * p2 + p3,
+    3 * p0 - 6 * p1 + 3 * p2,
+    -3 * p0 + 3 * p1,
+    p0,
+  ];
+}
+
+function singlePoint(p) {
+  return new PolynomialBezier(p, p, p, p, false);
+}
+
+function PolynomialBezier(p0, p1, p2, p3, linearize) {
+  if (linearize && pointEqual(p0, p1)) {
+    p1 = lerpPoint(p0, p3, 1 / 3);
+  }
+  if (linearize && pointEqual(p2, p3)) {
+    p2 = lerpPoint(p0, p3, 2 / 3);
+  }
+  var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
+  var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
+  this.a = [coeffx[0], coeffy[0]];
+  this.b = [coeffx[1], coeffy[1]];
+  this.c = [coeffx[2], coeffy[2]];
+  this.d = [coeffx[3], coeffy[3]];
+  this.points = [p0, p1, p2, p3];
+}
+PolynomialBezier.prototype.point = function (t) {
+  return [
+    (((this.a[0] * t) + this.b[0]) * t + this.c[0]) * t + this.d[0],
+    (((this.a[1] * t) + this.b[1]) * t + this.c[1]) * t + this.d[1],
+  ];
+};
+PolynomialBezier.prototype.derivative = function (t) {
+  return [
+    (3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0],
+    (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1],
+  ];
+};
+PolynomialBezier.prototype.tangentAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[1], p[0]);
+};
+PolynomialBezier.prototype.normalAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[0], p[1]);
+};
+
+PolynomialBezier.prototype.inflectionPoints = function () {
+  var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
+  if (floatZero(denom)) return [];
+  var tcusp = (-0.5 * (this.a[1] * this.c[0] - this.a[0] * this.c[1])) / denom;
+  var square = tcusp * tcusp - ((1 / 3) * (this.b[1] * this.c[0] - this.b[0] * this.c[1])) / denom;
+  if (square < 0) return [];
+  var root = Math.sqrt(square);
+  if (floatZero(root)) {
+    if (root > 0 && root < 1) return [tcusp];
+    return [];
+  }
+  return [tcusp - root, tcusp + root].filter(function (r) { return r > 0 && r < 1; });
+};
+PolynomialBezier.prototype.split = function (t) {
+  if (t <= 0) return [singlePoint(this.points[0]), this];
+  if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
+  var p10 = lerpPoint(this.points[0], this.points[1], t);
+  var p11 = lerpPoint(this.points[1], this.points[2], t);
+  var p12 = lerpPoint(this.points[2], this.points[3], t);
+  var p20 = lerpPoint(p10, p11, t);
+  var p21 = lerpPoint(p11, p12, t);
+  var p3 = lerpPoint(p20, p21, t);
+  return [
+    new PolynomialBezier(this.points[0], p10, p20, p3, true),
+    new PolynomialBezier(p3, p21, p12, this.points[3], true),
+  ];
+};
+function extrema(bez, comp) {
+  var min = bez.points[0][comp];
+  var max = bez.points[bez.points.length - 1][comp];
+  if (min > max) {
+    var e = max;
+    max = min;
+    min = e;
+  }
+  // Derivative roots to find min/max
+  var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
+  for (var i = 0; i < f.length; i += 1) {
+    if (f[i] > 0 && f[i] < 1) {
+      var val = bez.point(f[i])[comp];
+      if (val < min) min = val;
+      else if (val > max) max = val;
+    }
+  }
+  return {
+    min: min,
+    max: max,
+  };
+}
+PolynomialBezier.prototype.bounds = function () {
+  return {
+    x: extrema(this, 0),
+    y: extrema(this, 1),
+  };
+};
+PolynomialBezier.prototype.boundingBox = function () {
+  var bounds = this.bounds();
+  return {
+    left: bounds.x.min,
+    right: bounds.x.max,
+    top: bounds.y.min,
+    bottom: bounds.y.max,
+    width: bounds.x.max - bounds.x.min,
+    height: bounds.y.max - bounds.y.min,
+    cx: (bounds.x.max + bounds.x.min) / 2,
+    cy: (bounds.y.max + bounds.y.min) / 2,
+  };
+};
+
+function intersectData(bez, t1, t2) {
+  var box = bez.boundingBox();
+  return {
+    cx: box.cx,
+    cy: box.cy,
+    width: box.width,
+    height: box.height,
+    bez: bez,
+    t: (t1 + t2) / 2,
+    t1: t1,
+    t2: t2,
+  };
+}
+function splitData(data) {
+  var split = data.bez.split(0.5);
+  return [
+    intersectData(split[0], data.t1, data.t),
+    intersectData(split[1], data.t, data.t2),
+  ];
+}
+
+function boxIntersect(b1, b2) {
+  return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width
+    && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
+}
+
+function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
+  if (!boxIntersect(d1, d2)) return;
+  if (depth >= maxRecursion || (d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance)) {
+    intersections.push([d1.t, d2.t]);
+    return;
+  }
+  var d1s = splitData(d1);
+  var d2s = splitData(d2);
+  intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[0], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+}
+
+PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
+  if (tolerance === undefined) tolerance = 2;
+  if (maxRecursion === undefined) maxRecursion = 7;
+  var intersections = [];
+  intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
+  return intersections;
+};
+
+PolynomialBezier.shapeSegment = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
+};
+
+PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
+};
+
+function crossProduct(a, b) {
+  return [
+    a[1] * b[2] - a[2] * b[1],
+    a[2] * b[0] - a[0] * b[2],
+    a[0] * b[1] - a[1] * b[0],
+  ];
+}
+
+function lineIntersection(start1, end1, start2, end2) {
+  var v1 = [start1[0], start1[1], 1];
+  var v2 = [end1[0], end1[1], 1];
+  var v3 = [start2[0], start2[1], 1];
+  var v4 = [end2[0], end2[1], 1];
+
+  var r = crossProduct(
+    crossProduct(v1, v2),
+    crossProduct(v3, v4)
+  );
+
+  if (floatZero(r[2])) return null;
+
+  return [r[0] / r[2], r[1] / r[2]];
+}
+
+function polarOffset(p, angle, length) {
+  return [
+    p[0] + Math.cos(angle) * length,
+    p[1] - Math.sin(angle) * length,
+  ];
+}
+
+function pointDistance(p1, p2) {
+  return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
+}
+
+function pointEqual(p1, p2) {
+  return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
+}
+
+function ZigZagModifier() {}
+extendPrototype([ShapeModifier], ZigZagModifier);
+ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
+  this.frequency = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
+  this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
+};
+
+function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
+  var angO = angle - Math.PI / 2;
+  var angI = angle + Math.PI / 2;
+  var px = point[0] + Math.cos(angle) * direction * amplitude;
+  var py = point[1] - Math.sin(angle) * direction * amplitude;
+
+  outputBezier.setTripleAt(
+    px,
+    py,
+    px + Math.cos(angO) * outAmplitude,
+    py - Math.sin(angO) * outAmplitude,
+    px + Math.cos(angI) * inAmplitude,
+    py - Math.sin(angI) * inAmplitude,
+    outputBezier.length()
+  );
+}
+
+function getPerpendicularVector(pt1, pt2) {
+  var vector = [
+    pt2[0] - pt1[0],
+    pt2[1] - pt1[1],
+  ];
+  var rot = -Math.PI * 0.5;
+  var rotatedVector = [
+    Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1],
+    Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1],
+  ];
+  return rotatedVector;
+}
+
+function getProjectingAngle(path, cur) {
+  var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
+  var nextIndex = (cur + 1) % path.length();
+  var prevPoint = path.v[prevIndex];
+  var nextPoint = path.v[nextIndex];
+  var pVector = getPerpendicularVector(prevPoint, nextPoint);
+  return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
+}
+
+function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
+  var angle = getProjectingAngle(path, cur);
+  var point = path.v[cur % path._length];
+  var prevPoint = path.v[cur === 0 ? path._length - 1 : cur - 1];
+  var nextPoint = path.v[(cur + 1) % path._length];
+  var prevDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - prevPoint[0], 2) + Math.pow(point[1] - prevPoint[1], 2))
+    : 0;
+  var nextDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2))
+    : 0;
+
+  setPoint(
+    outputBezier,
+    path.v[cur % path._length],
+    angle,
+    direction,
+    amplitude,
+    nextDist / ((frequency + 1) * 2),
+    prevDist / ((frequency + 1) * 2),
+    pointType
+  );
+}
+
+function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
+  for (var i = 0; i < frequency; i += 1) {
+    var t = (i + 1) / (frequency + 1);
+
+    var dist = pointType === 2
+      ? Math.sqrt(Math.pow(segment.points[3][0] - segment.points[0][0], 2) + Math.pow(segment.points[3][1] - segment.points[0][1], 2))
+      : 0;
+
+    var angle = segment.normalAngle(t);
+    var point = segment.point(t);
+    setPoint(
+      outputBezier,
+      point,
+      angle,
+      direction,
+      amplitude,
+      dist / ((frequency + 1) * 2),
+      dist / ((frequency + 1) * 2),
+      pointType
+    );
+
+    direction = -direction;
+  }
+
+  return direction;
+}
+
+ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
+  var count = path._length;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+
+  if (!path.c) {
+    count -= 1;
+  }
+
+  if (count === 0) return clonedPath;
+
+  var direction = -1;
+  var segment = PolynomialBezier.shapeSegment(path, 0);
+  zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
+
+  for (var i = 0; i < count; i += 1) {
+    direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
+
+    if (i === count - 1 && !path.c) {
+      segment = null;
+    } else {
+      segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
+    }
+
+    zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
+  }
+
+  return clonedPath;
+};
+
+ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amplitude = this.amplitude.v;
+  var frequency = Math.max(0, Math.round(this.frequency.v));
+  var pointType = this.pointsType.v;
+
+  if (amplitude !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function linearOffset(p1, p2, amount) {
+  var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
+  return [
+    polarOffset(p1, angle, amount),
+    polarOffset(p2, angle, amount),
+  ];
+}
+
+function offsetSegment(segment, amount) {
+  var p0; var p1a; var p1b; var p2b; var p2a; var
+    p3;
+  var e;
+  e = linearOffset(segment.points[0], segment.points[1], amount);
+  p0 = e[0];
+  p1a = e[1];
+  e = linearOffset(segment.points[1], segment.points[2], amount);
+  p1b = e[0];
+  p2b = e[1];
+  e = linearOffset(segment.points[2], segment.points[3], amount);
+  p2a = e[0];
+  p3 = e[1];
+  var p1 = lineIntersection(p0, p1a, p1b, p2b);
+  if (p1 === null) p1 = p1a;
+  var p2 = lineIntersection(p2a, p3, p1b, p2b);
+  if (p2 === null) p2 = p2a;
+
+  return new PolynomialBezier(p0, p1, p2, p3);
+}
+
+function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
+  var p0 = seg1.points[3];
+  var p1 = seg2.points[0];
+
+  // Bevel
+  if (lineJoin === 3) return p0;
+
+  // Connected, they don't need a joint
+  if (pointEqual(p0, p1)) return p0;
+
+  // Round
+  if (lineJoin === 2) {
+    var angleOut = -seg1.tangentAngle(1);
+    var angleIn = -seg2.tangentAngle(0) + Math.PI;
+    var center = lineIntersection(
+      p0,
+      polarOffset(p0, angleOut + Math.PI / 2, 100),
+      p1,
+      polarOffset(p1, angleOut + Math.PI / 2, 100)
+    );
+    var radius = center ? pointDistance(center, p0) : pointDistance(p0, p1) / 2;
+
+    var tan = polarOffset(p0, angleOut, 2 * radius * roundCorner);
+    outputBezier.setXYAt(tan[0], tan[1], 'o', outputBezier.length() - 1);
+
+    tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
+    outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
+
+    return p1;
+  }
+
+  // Miter
+  var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
+  var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
+  var intersection = lineIntersection(t0, p0, p1, t1);
+  if (intersection && pointDistance(intersection, p0) < miterLimit) {
+    outputBezier.setTripleAt(
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      outputBezier.length()
+    );
+    return intersection;
+  }
+
+  return p0;
+}
+
+function getIntersection(a, b) {
+  const intersect = a.intersections(b);
+
+  if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
+
+  if (intersect.length) return intersect[0];
+
+  return null;
+}
+
+function pruneSegmentIntersection(a, b) {
+  var outa = a.slice();
+  var outb = b.slice();
+  var intersect = getIntersection(a[a.length - 1], b[0]);
+  if (intersect) {
+    outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
+    outb[0] = b[0].split(intersect[1])[1];
+  }
+  if (a.length > 1 && b.length > 1) {
+    intersect = getIntersection(a[0], b[b.length - 1]);
+    if (intersect) {
+      return [
+        [a[0].split(intersect[0])[0]],
+        [b[b.length - 1].split(intersect[1])[1]],
+      ];
+    }
+  }
+  return [outa, outb];
+}
+
+function pruneIntersections(segments) {
+  var e;
+  for (var i = 1; i < segments.length; i += 1) {
+    e = pruneSegmentIntersection(segments[i - 1], segments[i]);
+    segments[i - 1] = e[0];
+    segments[i] = e[1];
+  }
+
+  if (segments.length > 1) {
+    e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
+    segments[segments.length - 1] = e[0];
+    segments[0] = e[1];
+  }
+
+  return segments;
+}
+
+function offsetSegmentSplit(segment, amount) {
+  /*
+    We split each bezier segment into smaller pieces based
+    on inflection points, this ensures the control point
+    polygon is convex.
+
+    (A cubic bezier can have none, one, or two inflection points)
+  */
+  var flex = segment.inflectionPoints();
+  var left;
+  var right;
+  var split;
+  var mid;
+
+  if (flex.length === 0) {
+    return [offsetSegment(segment, amount)];
+  }
+
+  if (flex.length === 1 || floatEqual(flex[1], 1)) {
+    split = segment.split(flex[0]);
+    left = split[0];
+    right = split[1];
+
+    return [
+      offsetSegment(left, amount),
+      offsetSegment(right, amount),
+    ];
+  }
+
+  split = segment.split(flex[0]);
+  left = split[0];
+  var t = (flex[1] - flex[0]) / (1 - flex[0]);
+  split = split[1].split(t);
+  mid = split[0];
+  right = split[1];
+
+  return [
+    offsetSegment(left, amount),
+    offsetSegment(mid, amount),
+    offsetSegment(right, amount),
+  ];
+}
+
+function OffsetPathModifier() {}
+
+extendPrototype([ShapeModifier], OffsetPathModifier);
+OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this.miterLimit = PropertyFactory.getProp(elem, data.ml, 0, null, this);
+  this.lineJoin = data.lj;
+  this._isAnimated = this.amount.effectsSequence.length !== 0;
+};
+
+OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
+  var outputBezier = shapePool.newElement();
+  outputBezier.c = inputBezier.c;
+  var count = inputBezier.length();
+  if (!inputBezier.c) {
+    count -= 1;
+  }
+  var i; var j; var segment;
+  var multiSegments = [];
+
+  for (i = 0; i < count; i += 1) {
+    segment = PolynomialBezier.shapeSegment(inputBezier, i);
+    multiSegments.push(offsetSegmentSplit(segment, amount));
+  }
+
+  if (!inputBezier.c) {
+    for (i = count - 1; i >= 0; i -= 1) {
+      segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
+      multiSegments.push(offsetSegmentSplit(segment, amount));
+    }
+  }
+
+  multiSegments = pruneIntersections(multiSegments);
+
+  // Add bezier segments to the output and apply line joints
+  var lastPoint = null;
+  var lastSeg = null;
+
+  for (i = 0; i < multiSegments.length; i += 1) {
+    var multiSegment = multiSegments[i];
+
+    if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
+
+    lastSeg = multiSegment[multiSegment.length - 1];
+
+    for (j = 0; j < multiSegment.length; j += 1) {
+      segment = multiSegment[j];
+
+      if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
+        outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
+      } else {
+        outputBezier.setTripleAt(
+          segment.points[0][0],
+          segment.points[0][1],
+          segment.points[1][0],
+          segment.points[1][1],
+          segment.points[0][0],
+          segment.points[0][1],
+          outputBezier.length()
+        );
+      }
+
+      outputBezier.setTripleAt(
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[2][0],
+        segment.points[2][1],
+        outputBezier.length()
+      );
+
+      lastPoint = segment.points[3];
+    }
+  }
+
+  if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
+
+  return outputBezier;
+};
+
+OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+  var miterLimit = this.miterLimit.v;
+  var lineJoin = this.lineJoin;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function getFontProperties(fontData) {
+  var styles = fontData.fStyle ? fontData.fStyle.split(' ') : [];
+
+  var fWeight = 'normal'; var
+    fStyle = 'normal';
+  var len = styles.length;
+  var styleName;
+  for (var i = 0; i < len; i += 1) {
+    styleName = styles[i].toLowerCase();
+    switch (styleName) {
+      case 'italic':
+        fStyle = 'italic';
+        break;
+      case 'bold':
+        fWeight = '700';
+        break;
+      case 'black':
+        fWeight = '900';
+        break;
+      case 'medium':
+        fWeight = '500';
+        break;
+      case 'regular':
+      case 'normal':
+        fWeight = '400';
+        break;
+      case 'light':
+      case 'thin':
+        fWeight = '200';
+        break;
+      default:
+        break;
+    }
+  }
+
+  return {
+    style: fStyle,
+    weight: fontData.fWeight || fWeight,
+  };
+}
+
+const FontManager = (function () {
+  var maxWaitingTime = 5000;
+  var emptyChar = {
+    w: 0,
+    size: 0,
+    shapes: [],
+    data: {
+      shapes: [],
+    },
+  };
+  var combinedCharacters = [];
+  // Hindi characters
+  combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366,
+    2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379,
+    2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
+
+  var BLACK_FLAG_CODE_POINT = 127988;
+  var CANCEL_TAG_CODE_POINT = 917631;
+  var A_TAG_CODE_POINT = 917601;
+  var Z_TAG_CODE_POINT = 917626;
+  var VARIATION_SELECTOR_16_CODE_POINT = 65039;
+  var ZERO_WIDTH_JOINER_CODE_POINT = 8205;
+  var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
+  var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
+
+  var surrogateModifiers = [
+    'd83cdffb',
+    'd83cdffc',
+    'd83cdffd',
+    'd83cdffe',
+    'd83cdfff',
+  ];
+
+  function trimFontOptions(font) {
+    var familyArray = font.split(',');
+    var i;
+    var len = familyArray.length;
+    var enabledFamilies = [];
+    for (i = 0; i < len; i += 1) {
+      if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
+        enabledFamilies.push(familyArray[i]);
+      }
+    }
+    return enabledFamilies.join(',');
+  }
+
+  function setUpNode(font, family) {
+    var parentNode = createTag('span');
+    // Node is invisible to screen readers.
+    parentNode.setAttribute('aria-hidden', true);
+    parentNode.style.fontFamily = family;
+    var node = createTag('span');
+    // Characters that vary significantly among different fonts
+    node.innerText = 'giItT1WQy@!-/#';
+    // Visible - so we can measure it - but not on the screen
+    parentNode.style.position = 'absolute';
+    parentNode.style.left = '-10000px';
+    parentNode.style.top = '-10000px';
+    // Large font size makes even subtle changes obvious
+    parentNode.style.fontSize = '300px';
+    // Reset any font properties
+    parentNode.style.fontVariant = 'normal';
+    parentNode.style.fontStyle = 'normal';
+    parentNode.style.fontWeight = 'normal';
+    parentNode.style.letterSpacing = '0';
+    parentNode.appendChild(node);
+    document.body.appendChild(parentNode);
+
+    // Remember width with no applied web font
+    var width = node.offsetWidth;
+    node.style.fontFamily = trimFontOptions(font) + ', ' + family;
+    return { node: node, w: width, parent: parentNode };
+  }
+
+  function checkLoadedFonts() {
+    var i;
+    var len = this.fonts.length;
+    var node;
+    var w;
+    var loadedCount = len;
+    for (i = 0; i < len; i += 1) {
+      if (this.fonts[i].loaded) {
+        loadedCount -= 1;
+      } else if (this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0) {
+        this.fonts[i].loaded = true;
+      } else {
+        node = this.fonts[i].monoCase.node;
+        w = this.fonts[i].monoCase.w;
+        if (node.offsetWidth !== w) {
+          loadedCount -= 1;
+          this.fonts[i].loaded = true;
+        } else {
+          node = this.fonts[i].sansCase.node;
+          w = this.fonts[i].sansCase.w;
+          if (node.offsetWidth !== w) {
+            loadedCount -= 1;
+            this.fonts[i].loaded = true;
+          }
+        }
+        if (this.fonts[i].loaded) {
+          this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
+          this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
+        }
+      }
+    }
+
+    if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
+      setTimeout(this.checkLoadedFontsBinded, 20);
+    } else {
+      setTimeout(this.setIsLoadedBinded, 10);
+    }
+  }
+
+  function createHelper(fontData, def) {
+    var engine = (document.body && def) ? 'svg' : 'canvas';
+    var helper;
+    var fontProps = getFontProperties(fontData);
+    if (engine === 'svg') {
+      var tHelper = createNS('text');
+      tHelper.style.fontSize = '100px';
+      // tHelper.style.fontFamily = fontData.fFamily;
+      tHelper.setAttribute('font-family', fontData.fFamily);
+      tHelper.setAttribute('font-style', fontProps.style);
+      tHelper.setAttribute('font-weight', fontProps.weight);
+      tHelper.textContent = '1';
+      if (fontData.fClass) {
+        tHelper.style.fontFamily = 'inherit';
+        tHelper.setAttribute('class', fontData.fClass);
+      } else {
+        tHelper.style.fontFamily = fontData.fFamily;
+      }
+      def.appendChild(tHelper);
+      helper = tHelper;
+    } else {
+      var tCanvasHelper = new OffscreenCanvas(500, 500).getContext('2d');
+      tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
+      helper = tCanvasHelper;
+    }
+    function measure(text) {
+      if (engine === 'svg') {
+        helper.textContent = text;
+        return helper.getComputedTextLength();
+      }
+      return helper.measureText(text).width;
+    }
+    return {
+      measureText: measure,
+    };
+  }
+
+  function addFonts(fontData, defs) {
+    if (!fontData) {
+      this.isLoaded = true;
+      return;
+    }
+    if (this.chars) {
+      this.isLoaded = true;
+      this.fonts = fontData.list;
+      return;
+    }
+    if (!document.body) {
+      this.isLoaded = true;
+      fontData.list.forEach((data) => {
+        data.helper = createHelper(data);
+        data.cache = {};
+      });
+      this.fonts = fontData.list;
+      return;
+    }
+
+    var fontArr = fontData.list;
+    var i;
+    var len = fontArr.length;
+    var _pendingFonts = len;
+    for (i = 0; i < len; i += 1) {
+      var shouldLoadFont = true;
+      var loadedSelector;
+      var j;
+      fontArr[i].loaded = false;
+      fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
+      fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
+      if (!fontArr[i].fPath) {
+        fontArr[i].loaded = true;
+        _pendingFonts -= 1;
+      } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
+        loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
+
+        if (loadedSelector.length > 0) {
+          shouldLoadFont = false;
+        }
+
+        if (shouldLoadFont) {
+          var s = createTag('style');
+          s.setAttribute('f-forigin', fontArr[i].fOrigin);
+          s.setAttribute('f-origin', fontArr[i].origin);
+          s.setAttribute('f-family', fontArr[i].fFamily);
+          s.type = 'text/css';
+          s.innerText = '@font-face {font-family: ' + fontArr[i].fFamily + "; font-style: normal; src: url('" + fontArr[i].fPath + "');}";
+          defs.appendChild(s);
+        }
+      } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
+        loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var l = createTag('link');
+          l.setAttribute('f-forigin', fontArr[i].fOrigin);
+          l.setAttribute('f-origin', fontArr[i].origin);
+          l.type = 'text/css';
+          l.rel = 'stylesheet';
+          l.href = fontArr[i].fPath;
+          document.body.appendChild(l);
+        }
+      } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
+        loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (fontArr[i].fPath === loadedSelector[j].src) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var sc = createTag('link');
+          sc.setAttribute('f-forigin', fontArr[i].fOrigin);
+          sc.setAttribute('f-origin', fontArr[i].origin);
+          sc.setAttribute('rel', 'stylesheet');
+          sc.setAttribute('href', fontArr[i].fPath);
+          defs.appendChild(sc);
+        }
+      }
+      fontArr[i].helper = createHelper(fontArr[i], defs);
+      fontArr[i].cache = {};
+      this.fonts.push(fontArr[i]);
+    }
+    if (_pendingFonts === 0) {
+      this.isLoaded = true;
+    } else {
+      // On some cases even if the font is loaded, it won't load correctly when measuring text on canvas.
+      // Adding this timeout seems to fix it
+      setTimeout(this.checkLoadedFonts.bind(this), 100);
+    }
+  }
+
+  function addChars(chars) {
+    if (!chars) {
+      return;
+    }
+    if (!this.chars) {
+      this.chars = [];
+    }
+    var i;
+    var len = chars.length;
+    var j;
+    var jLen = this.chars.length;
+    var found;
+    for (i = 0; i < len; i += 1) {
+      j = 0;
+      found = false;
+      while (j < jLen) {
+        if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
+          found = true;
+        }
+        j += 1;
+      }
+      if (!found) {
+        this.chars.push(chars[i]);
+        jLen += 1;
+      }
+    }
+  }
+
+  function getCharData(char, style, font) {
+    var i = 0;
+    var len = this.chars.length;
+    while (i < len) {
+      if (this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font) {
+        return this.chars[i];
+      }
+      i += 1;
+    }
+    if (((typeof char === 'string' && char.charCodeAt(0) !== 13) || !char)
+            && console
+            && console.warn // eslint-disable-line no-console
+            && !this._warned
+    ) {
+      this._warned = true;
+      console.warn('Missing character from exported characters list: ', char, style, font); // eslint-disable-line no-console
+    }
+    return emptyChar;
+  }
+
+  function measureText(char, fontName, size) {
+    var fontData = this.getFontByName(fontName);
+    // Using the char instead of char.charCodeAt(0)
+    // to avoid collisions between equal chars
+    var index = char;
+    if (!fontData.cache[index]) {
+      var tHelper = fontData.helper;
+      if (char === ' ') {
+        var doubleSize = tHelper.measureText('|' + char + '|');
+        var singleSize = tHelper.measureText('||');
+        fontData.cache[index] = (doubleSize - singleSize) / 100;
+      } else {
+        fontData.cache[index] = tHelper.measureText(char) / 100;
+      }
+    }
+    return fontData.cache[index] * size;
+  }
+
+  function getFontByName(name) {
+    var i = 0;
+    var len = this.fonts.length;
+    while (i < len) {
+      if (this.fonts[i].fName === name) {
+        return this.fonts[i];
+      }
+      i += 1;
+    }
+    return this.fonts[0];
+  }
+
+  function getCodePoint(string) {
+    var codePoint = 0;
+    var first = string.charCodeAt(0);
+    if (first >= 0xD800 && first <= 0xDBFF) {
+      var second = string.charCodeAt(1);
+      if (second >= 0xDC00 && second <= 0xDFFF) {
+        codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+      }
+    }
+    return codePoint;
+  }
+
+  // Skin tone modifiers
+  function isModifier(firstCharCode, secondCharCode) {
+    var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
+    return surrogateModifiers.indexOf(sum) !== -1;
+  }
+
+  function isZeroWidthJoiner(charCode) {
+    return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
+  }
+
+  // This codepoint may change the appearance of the preceding character.
+  // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
+  // as a colorful image as compared to a monochrome text variant.
+  function isVariationSelector(charCode) {
+    return charCode === VARIATION_SELECTOR_16_CODE_POINT;
+  }
+
+  // The regional indicator symbols are a set of 26 alphabetic Unicode
+  /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
+  // two-letter country codes in a way that allows optional special treatment.
+  function isRegionalCode(string) {
+    var codePoint = getCodePoint(string);
+    if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
+      return true;
+    }
+    return false;
+  }
+
+  // Some Emoji implementations represent combinations of
+  // two “regional indicator” letters as a single flag symbol.
+  function isFlagEmoji(string) {
+    return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
+  }
+
+  function isCombinedCharacter(char) {
+    return combinedCharacters.indexOf(char) !== -1;
+  }
+
+  // Regional flags start with a BLACK_FLAG_CODE_POINT
+  // folowed by 5 chars in the TAG range
+  // and end with a CANCEL_TAG_CODE_POINT
+  function isRegionalFlag(text, index) {
+    var codePoint = getCodePoint(text.substr(index, 2));
+    if (codePoint !== BLACK_FLAG_CODE_POINT) {
+      return false;
+    }
+    var count = 0;
+    index += 2;
+    while (count < 5) {
+      codePoint = getCodePoint(text.substr(index, 2));
+      if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
+        return false;
+      }
+      count += 1;
+      index += 2;
+    }
+    return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
+  }
+
+  function setIsLoaded() {
+    this.isLoaded = true;
+  }
+
+  var Font = function () {
+    this.fonts = [];
+    this.chars = null;
+    this.typekitLoaded = 0;
+    this.isLoaded = false;
+    this._warned = false;
+    this.initTime = Date.now();
+    this.setIsLoadedBinded = this.setIsLoaded.bind(this);
+    this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
+  };
+  Font.isModifier = isModifier;
+  Font.isZeroWidthJoiner = isZeroWidthJoiner;
+  Font.isFlagEmoji = isFlagEmoji;
+  Font.isRegionalCode = isRegionalCode;
+  Font.isCombinedCharacter = isCombinedCharacter;
+  Font.isRegionalFlag = isRegionalFlag;
+  Font.isVariationSelector = isVariationSelector;
+  Font.BLACK_FLAG_CODE_POINT = BLACK_FLAG_CODE_POINT;
+
+  var fontPrototype = {
+    addChars: addChars,
+    addFonts: addFonts,
+    getCharData: getCharData,
+    getFontByName: getFontByName,
+    measureText: measureText,
+    checkLoadedFonts: checkLoadedFonts,
+    setIsLoaded: setIsLoaded,
+  };
+
+  Font.prototype = fontPrototype;
+
+  return Font;
+}());
+
+function SlotManager(animationData) {
+  this.animationData = animationData;
+}
+SlotManager.prototype.getProp = function (data) {
+  if (this.animationData.slots
+    && this.animationData.slots[data.sid]
+  ) {
+    return Object.assign(data, this.animationData.slots[data.sid].p);
+  }
+  return data;
+};
+
+function slotFactory(animationData) {
+  return new SlotManager(animationData);
+}
+
+function RenderableElement() {
+
+}
+
+RenderableElement.prototype = {
+  initRenderable: function () {
+    // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
+    this.isInRange = false;
+    // layer's display state
+    this.hidden = false;
+    // If layer's transparency equals 0, it can be hidden
+    this.isTransparent = false;
+    // list of animated components
+    this.renderableComponents = [];
+  },
+  addRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) === -1) {
+      this.renderableComponents.push(component);
+    }
+  },
+  removeRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) !== -1) {
+      this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1);
+    }
+  },
+  prepareRenderableFrame: function (num) {
+    this.checkLayerLimits(num);
+  },
+  checkTransparency: function () {
+    if (this.finalTransform.mProp.o.v <= 0) {
+      if (!this.isTransparent && this.globalData.renderConfig.hideOnTransparent) {
+        this.isTransparent = true;
+        this.hide();
+      }
+    } else if (this.isTransparent) {
+      this.isTransparent = false;
+      this.show();
+    }
+  },
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     *
+     */
+  checkLayerLimits: function (num) {
+    if (this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) {
+      if (this.isInRange !== true) {
+        this.globalData._mdf = true;
+        this._mdf = true;
+        this.isInRange = true;
+        this.show();
+      }
+    } else if (this.isInRange !== false) {
+      this.globalData._mdf = true;
+      this.isInRange = false;
+      this.hide();
+    }
+  },
+  renderRenderable: function () {
+    var i;
+    var len = this.renderableComponents.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderableComponents[i].renderFrame(this._isFirstFrame);
+    }
+    /* this.maskManager.renderFrame(this.finalTransform.mat);
+        this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
+  },
+  sourceRectAtTime: function () {
+    return {
+      top: 0,
+      left: 0,
+      width: 100,
+      height: 100,
+    };
+  },
+  getLayerSize: function () {
+    if (this.data.ty === 5) {
+      return { w: this.data.textData.width, h: this.data.textData.height };
+    }
+    return { w: this.data.width, h: this.data.height };
+  },
+};
+
+const getBlendMode = (function () {
+  var blendModeEnums = {
+    0: 'source-over',
+    1: 'multiply',
+    2: 'screen',
+    3: 'overlay',
+    4: 'darken',
+    5: 'lighten',
+    6: 'color-dodge',
+    7: 'color-burn',
+    8: 'hard-light',
+    9: 'soft-light',
+    10: 'difference',
+    11: 'exclusion',
+    12: 'hue',
+    13: 'saturation',
+    14: 'color',
+    15: 'luminosity',
+  };
+
+  return function (mode) {
+    return blendModeEnums[mode] || '';
+  };
+}());
+
+function SliderEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function AngleEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function ColorEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function PointEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function LayerIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function MaskIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function CheckboxEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function NoValueEffect() {
+  this.p = {};
+}
+
+function EffectsManager(data, element) {
+  var effects = data.ef || [];
+  this.effectElements = [];
+  var i;
+  var len = effects.length;
+  var effectItem;
+  for (i = 0; i < len; i += 1) {
+    effectItem = new GroupEffect(effects[i], element);
+    this.effectElements.push(effectItem);
+  }
+}
+
+function GroupEffect(data, element) {
+  this.init(data, element);
+}
+
+extendPrototype([DynamicPropertyContainer], GroupEffect);
+
+GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
+
+GroupEffect.prototype.init = function (data, element) {
+  this.data = data;
+  this.effectElements = [];
+  this.initDynamicPropertyContainer(element);
+  var i;
+  var len = this.data.ef.length;
+  var eff;
+  var effects = this.data.ef;
+  for (i = 0; i < len; i += 1) {
+    eff = null;
+    switch (effects[i].ty) {
+      case 0:
+        eff = new SliderEffect(effects[i], element, this);
+        break;
+      case 1:
+        eff = new AngleEffect(effects[i], element, this);
+        break;
+      case 2:
+        eff = new ColorEffect(effects[i], element, this);
+        break;
+      case 3:
+        eff = new PointEffect(effects[i], element, this);
+        break;
+      case 4:
+      case 7:
+        eff = new CheckboxEffect(effects[i], element, this);
+        break;
+      case 10:
+        eff = new LayerIndexEffect(effects[i], element, this);
+        break;
+      case 11:
+        eff = new MaskIndexEffect(effects[i], element, this);
+        break;
+      case 5:
+        eff = new EffectsManager(effects[i], element, this);
+        break;
+        // case 6:
+      default:
+        eff = new NoValueEffect(effects[i], element, this);
+        break;
+    }
+    if (eff) {
+      this.effectElements.push(eff);
+    }
+  }
+};
+
+function BaseElement() {
+}
+
+BaseElement.prototype = {
+  checkMasks: function () {
+    if (!this.data.hasMask) {
+      return false;
+    }
+    var i = 0;
+    var len = this.data.masksProperties.length;
+    while (i < len) {
+      if ((this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false)) {
+        return true;
+      }
+      i += 1;
+    }
+    return false;
+  },
+  initExpressions: function () {
+    const expressionsInterfaces = getExpressionInterfaces();
+    if (!expressionsInterfaces) {
+      return;
+    }
+    const LayerExpressionInterface = expressionsInterfaces('layer');
+    const EffectsExpressionInterface = expressionsInterfaces('effects');
+    const ShapeExpressionInterface = expressionsInterfaces('shape');
+    const TextExpressionInterface = expressionsInterfaces('text');
+    const CompExpressionInterface = expressionsInterfaces('comp');
+    this.layerInterface = LayerExpressionInterface(this);
+    if (this.data.hasMask && this.maskManager) {
+      this.layerInterface.registerMaskInterface(this.maskManager);
+    }
+    var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
+    this.layerInterface.registerEffectsInterface(effectsInterface);
+
+    if (this.data.ty === 0 || this.data.xt) {
+      this.compInterface = CompExpressionInterface(this);
+    } else if (this.data.ty === 4) {
+      this.layerInterface.shapeInterface = ShapeExpressionInterface(this.shapesData, this.itemsData, this.layerInterface);
+      this.layerInterface.content = this.layerInterface.shapeInterface;
+    } else if (this.data.ty === 5) {
+      this.layerInterface.textInterface = TextExpressionInterface(this);
+      this.layerInterface.text = this.layerInterface.textInterface;
+    }
+  },
+  setBlendMode: function () {
+    var blendModeValue = getBlendMode(this.data.bm);
+    var elem = this.baseElement || this.layerElement;
+
+    elem.style['mix-blend-mode'] = blendModeValue;
+  },
+  initBaseData: function (data, globalData, comp) {
+    this.globalData = globalData;
+    this.comp = comp;
+    this.data = data;
+    this.layerId = createElementID();
+
+    // Stretch factor for old animations missing this property.
+    if (!this.data.sr) {
+      this.data.sr = 1;
+    }
+    // effects manager
+    this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
+  },
+  getType: function () {
+    return this.type;
+  },
+  sourceRectAtTime: function () {},
+};
+
+/**
+ * @file
+ * Handles element's layer frame update.
+ * Checks layer in point and out point
+ *
+ */
+
+function FrameElement() {}
+
+FrameElement.prototype = {
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     */
+  initFrame: function () {
+    // set to true when inpoint is rendered
+    this._isFirstFrame = false;
+    // list of animated properties
+    this.dynamicProperties = [];
+    // If layer has been modified in current tick this will be true
+    this._mdf = false;
+  },
+  /**
+     * @function
+     * Calculates all dynamic values
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     * @param {boolean} isVisible
+     * if layers is currently in range
+     *
+     */
+  prepareProperties: function (num, isVisible) {
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      if (isVisible || (this._isParent && this.dynamicProperties[i].propType === 'transform')) {
+        this.dynamicProperties[i].getValue();
+        if (this.dynamicProperties[i]._mdf) {
+          this.globalData._mdf = true;
+          this._mdf = true;
+        }
+      }
+    }
+  },
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+    }
+  },
+};
+
+function FootageElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.footageData = globalData.imageLoader.getAsset(this.assetData);
+  this.initBaseData(data, globalData, comp);
+}
+
+FootageElement.prototype.prepareFrame = function () {
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
+
+FootageElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+FootageElement.prototype.renderFrame = function () {
+};
+
+FootageElement.prototype.destroy = function () {
+};
+
+FootageElement.prototype.initExpressions = function () {
+  const expressionsInterfaces = getExpressionInterfaces();
+  if (!expressionsInterfaces) {
+    return;
+  }
+  const FootageInterface = expressionsInterfaces('footage');
+  this.layerInterface = FootageInterface(this);
+};
+
+FootageElement.prototype.getFootageData = function () {
+  return this.footageData;
+};
+
+function AudioElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initBaseData(data, globalData, comp);
+  this._isPlaying = false;
+  this._canPlay = false;
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  this.audio = this.globalData.audioController.createAudio(assetPath);
+  this._currentTime = 0;
+  this.globalData.audioController.addAudio(this);
+  this._volumeMultiplier = 1;
+  this._volume = 1;
+  this._previousVolume = null;
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+  this.lv = PropertyFactory.getProp(this, data.au && data.au.lv ? data.au.lv : { k: [100] }, 1, 0.01, this);
+}
+
+AudioElement.prototype.prepareFrame = function (num) {
+  this.prepareRenderableFrame(num, true);
+  this.prepareProperties(num, true);
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    this._currentTime = timeRemapped;
+  } else {
+    this._currentTime = num / this.data.sr;
+  }
+  this._volume = this.lv.v[0];
+  var totalVolume = this._volume * this._volumeMultiplier;
+  if (this._previousVolume !== totalVolume) {
+    this._previousVolume = totalVolume;
+    this.audio.volume(totalVolume);
+  }
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
+
+AudioElement.prototype.renderFrame = function () {
+  if (this.isInRange && this._canPlay) {
+    if (!this._isPlaying) {
+      this.audio.play();
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+      this._isPlaying = true;
+    } else if (!this.audio.playing()
+      || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1
+    ) {
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+    }
+  }
+};
+
+AudioElement.prototype.show = function () {
+  // this.audio.play()
+};
+
+AudioElement.prototype.hide = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+};
+
+AudioElement.prototype.pause = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+  this._canPlay = false;
+};
+
+AudioElement.prototype.resume = function () {
+  this._canPlay = true;
+};
+
+AudioElement.prototype.setRate = function (rateValue) {
+  this.audio.rate(rateValue);
+};
+
+AudioElement.prototype.volume = function (volumeValue) {
+  this._volumeMultiplier = volumeValue;
+  this._previousVolume = volumeValue * this._volume;
+  this.audio.volume(this._previousVolume);
+};
+
+AudioElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+AudioElement.prototype.destroy = function () {
+};
+
+AudioElement.prototype.sourceRectAtTime = function () {
+};
+
+AudioElement.prototype.initExpressions = function () {
+};
+
+function BaseRenderer() {}
+BaseRenderer.prototype.checkLayers = function (num) {
+  var i;
+  var len = this.layers.length;
+  var data;
+  this.completeLayers = true;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (!this.elements[i]) {
+      data = this.layers[i];
+      if (data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) {
+        this.buildItem(i);
+      }
+    }
+    this.completeLayers = this.elements[i] ? this.completeLayers : false;
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.createItem = function (layer) {
+  switch (layer.ty) {
+    case 2:
+      return this.createImage(layer);
+    case 0:
+      return this.createComp(layer);
+    case 1:
+      return this.createSolid(layer);
+    case 3:
+      return this.createNull(layer);
+    case 4:
+      return this.createShape(layer);
+    case 5:
+      return this.createText(layer);
+    case 6:
+      return this.createAudio(layer);
+    case 13:
+      return this.createCamera(layer);
+    case 15:
+      return this.createFootage(layer);
+    default:
+      return this.createNull(layer);
+  }
+};
+
+BaseRenderer.prototype.createCamera = function () {
+  throw new Error('You\'re using a 3d camera. Try the html renderer.');
+};
+
+BaseRenderer.prototype.createAudio = function (data) {
+  return new AudioElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.createFootage = function (data) {
+  return new FootageElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.buildAllItems = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    this.buildItem(i);
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.includeLayers = function (newLayers) {
+  this.completeLayers = false;
+  var i;
+  var len = newLayers.length;
+  var j;
+  var jLen = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    j = 0;
+    while (j < jLen) {
+      if (this.layers[j].id === newLayers[i].id) {
+        this.layers[j] = newLayers[i];
+        break;
+      }
+      j += 1;
+    }
+  }
+};
+
+BaseRenderer.prototype.setProjectInterface = function (pInterface) {
+  this.globalData.projectInterface = pInterface;
+};
+
+BaseRenderer.prototype.initItems = function () {
+  if (!this.globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+};
+BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
+  var elements = this.elements;
+  var layers = this.layers;
+  var i = 0;
+  var len = layers.length;
+  while (i < len) {
+    if (layers[i].ind == parentName) { // eslint-disable-line eqeqeq
+      if (!elements[i] || elements[i] === true) {
+        this.buildItem(i);
+        this.addPendingElement(element);
+      } else {
+        hierarchy.push(elements[i]);
+        elements[i].setAsParent();
+        if (layers[i].parent !== undefined) {
+          this.buildElementParenting(element, layers[i].parent, hierarchy);
+        } else {
+          element.setHierarchy(hierarchy);
+        }
+      }
+    }
+    i += 1;
+  }
+};
+
+BaseRenderer.prototype.addPendingElement = function (element) {
+  this.pendingElements.push(element);
+};
+
+BaseRenderer.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var len = assets.length;
+  for (i = 0; i < len; i += 1) {
+    if (assets[i].xt) {
+      var comp = this.createComp(assets[i]);
+      comp.initExpressions();
+      this.globalData.projectInterface.registerComposition(comp);
+    }
+  }
+};
+
+BaseRenderer.prototype.getElementById = function (ind) {
+  var i;
+  var len = this.elements.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i].data.ind === ind) {
+      return this.elements[i];
+    }
+  }
+  return null;
+};
+
+BaseRenderer.prototype.getElementByPath = function (path) {
+  var pathValue = path.shift();
+  var element;
+  if (typeof pathValue === 'number') {
+    element = this.elements[pathValue];
+  } else {
+    var i;
+    var len = this.elements.length;
+    for (i = 0; i < len; i += 1) {
+      if (this.elements[i].data.nm === pathValue) {
+        element = this.elements[i];
+        break;
+      }
+    }
+  }
+  if (path.length === 0) {
+    return element;
+  }
+  return element.getElementByPath(path);
+};
+
+BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
+  this.globalData.fontManager = new FontManager();
+  this.globalData.slotManager = slotFactory(animData);
+  this.globalData.fontManager.addChars(animData.chars);
+  this.globalData.fontManager.addFonts(animData.fonts, fontsContainer);
+  this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+  this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+  this.globalData.imageLoader = this.animationItem.imagePreloader;
+  this.globalData.audioController = this.animationItem.audioController;
+  this.globalData.frameId = 0;
+  this.globalData.frameRate = animData.fr;
+  this.globalData.nm = animData.nm;
+  this.globalData.compSize = {
+    w: animData.w,
+    h: animData.h,
+  };
+};
+
+var effectTypes = {
+  TRANSFORM_EFFECT: 'transformEFfect',
+};
+
+function TransformElement() {}
+
+TransformElement.prototype = {
+  initTransform: function () {
+    var mat = new Matrix();
+    this.finalTransform = {
+      mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : { o: 0 },
+      _matMdf: false,
+      _localMatMdf: false,
+      _opMdf: false,
+      mat: mat,
+      localMat: mat,
+      localOpacity: 1,
+    };
+    if (this.data.ao) {
+      this.finalTransform.mProp.autoOriented = true;
+    }
+
+    // TODO: check TYPE 11: Guided elements
+    if (this.data.ty !== 11) {
+      // this.createElements();
+    }
+  },
+  renderTransform: function () {
+    this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
+    this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
+
+    if (this.hierarchy) {
+      var mat;
+      var finalMat = this.finalTransform.mat;
+      var i = 0;
+      var len = this.hierarchy.length;
+      // Checking if any of the transformation matrices in the hierarchy chain has changed.
+      if (!this.finalTransform._matMdf) {
+        while (i < len) {
+          if (this.hierarchy[i].finalTransform.mProp._mdf) {
+            this.finalTransform._matMdf = true;
+            break;
+          }
+          i += 1;
+        }
+      }
+
+      if (this.finalTransform._matMdf) {
+        mat = this.finalTransform.mProp.v.props;
+        finalMat.cloneFromProps(mat);
+        for (i = 0; i < len; i += 1) {
+          finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
+        }
+      }
+    }
+    if (!this.localTransforms || this.finalTransform._matMdf) {
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+    }
+    if (this.finalTransform._opMdf) {
+      this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderLocalTransform: function () {
+    if (this.localTransforms) {
+      var i = 0;
+      var len = this.localTransforms.length;
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+      if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
+        while (i < len) {
+          if (this.localTransforms[i]._mdf) {
+            this.finalTransform._localMatMdf = true;
+          }
+          if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
+            this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+            this.finalTransform._opMdf = true;
+          }
+          i += 1;
+        }
+      }
+      if (this.finalTransform._localMatMdf) {
+        var localMat = this.finalTransform.localMat;
+        this.localTransforms[0].matrix.clone(localMat);
+        for (i = 1; i < len; i += 1) {
+          var lmat = this.localTransforms[i].matrix;
+          localMat.multiply(lmat);
+        }
+        localMat.multiply(this.finalTransform.mat);
+      }
+      if (this.finalTransform._opMdf) {
+        var localOp = this.finalTransform.localOpacity;
+        for (i = 0; i < len; i += 1) {
+          localOp *= this.localTransforms[i].opacity * 0.01;
+        }
+        this.finalTransform.localOpacity = localOp;
+      }
+    }
+  },
+  searchEffectTransforms: function () {
+    if (this.renderableEffectsManager) {
+      var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+      if (transformEffects.length) {
+        this.localTransforms = [];
+        this.finalTransform.localMat = new Matrix();
+        var i = 0;
+        var len = transformEffects.length;
+        for (i = 0; i < len; i += 1) {
+          this.localTransforms.push(transformEffects[i]);
+        }
+      }
+    }
+  },
+  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;
+    var len = transforms.length;
+    var 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;
+  },
+  mHelper: new Matrix(),
+};
+
+function MaskElement(data, element, globalData) {
+  this.data = data;
+  this.element = element;
+  this.globalData = globalData;
+  this.storedData = [];
+  this.masksProperties = this.data.masksProperties || [];
+  this.maskElement = null;
+  var defs = this.globalData.defs;
+  var i;
+  var len = this.masksProperties ? this.masksProperties.length : 0;
+  this.viewData = createSizedArray(len);
+  this.solidPath = '';
+
+  var path;
+  var properties = this.masksProperties;
+  var count = 0;
+  var currentMasks = [];
+  var j;
+  var jLen;
+  var layerId = createElementID();
+  var rect;
+  var expansor;
+  var feMorph;
+  var x;
+  var maskType = 'clipPath';
+  var maskRef = 'clip-path';
+  for (i = 0; i < len; i += 1) {
+    if ((properties[i].mode !== 'a' && properties[i].mode !== 'n') || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
+      maskType = 'mask';
+      maskRef = 'mask';
+    }
+
+    if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
+      rect = createNS('rect');
+      rect.setAttribute('fill', '#ffffff');
+      rect.setAttribute('width', this.element.comp.data.w || 0);
+      rect.setAttribute('height', this.element.comp.data.h || 0);
+      currentMasks.push(rect);
+    } else {
+      rect = null;
+    }
+
+    path = createNS('path');
+    if (properties[i].mode === 'n') {
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        elem: path,
+        lastPath: '',
+      };
+      defs.appendChild(path);
+    } else {
+      count += 1;
+
+      path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      path.setAttribute('clip-rule', 'nonzero');
+      var filterID;
+
+      if (properties[i].x.k !== 0) {
+        maskType = 'mask';
+        maskRef = 'mask';
+        x = PropertyFactory.getProp(this.element, properties[i].x, 0, null, this.element);
+        filterID = createElementID();
+        expansor = createNS('filter');
+        expansor.setAttribute('id', filterID);
+        feMorph = createNS('feMorphology');
+        feMorph.setAttribute('operator', 'erode');
+        feMorph.setAttribute('in', 'SourceGraphic');
+        feMorph.setAttribute('radius', '0');
+        expansor.appendChild(feMorph);
+        defs.appendChild(expansor);
+        path.setAttribute('stroke', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      } else {
+        feMorph = null;
+        x = null;
+      }
+
+      // TODO move this to a factory or to a constructor
+      this.storedData[i] = {
+        elem: path,
+        x: x,
+        expan: feMorph,
+        lastPath: '',
+        lastOperator: '',
+        filterId: filterID,
+        lastRadius: 0,
+      };
+      if (properties[i].mode === 'i') {
+        jLen = currentMasks.length;
+        var g = createNS('g');
+        for (j = 0; j < jLen; j += 1) {
+          g.appendChild(currentMasks[j]);
+        }
+        var mask = createNS('mask');
+        mask.setAttribute('mask-type', 'alpha');
+        mask.setAttribute('id', layerId + '_' + count);
+        mask.appendChild(path);
+        defs.appendChild(mask);
+        g.setAttribute('mask', 'url(' + getLocationHref() + '#' + layerId + '_' + count + ')');
+
+        currentMasks.length = 0;
+        currentMasks.push(g);
+      } else {
+        currentMasks.push(path);
+      }
+      if (properties[i].inv && !this.solidPath) {
+        this.solidPath = this.createLayerSolidPath();
+      }
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        elem: path,
+        lastPath: '',
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        invRect: rect,
+      };
+      if (!this.viewData[i].prop.k) {
+        this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
+      }
+    }
+  }
+
+  this.maskElement = createNS(maskType);
+
+  len = currentMasks.length;
+  for (i = 0; i < len; i += 1) {
+    this.maskElement.appendChild(currentMasks[i]);
+  }
+
+  if (count > 0) {
+    this.maskElement.setAttribute('id', layerId);
+    this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
+    defs.appendChild(this.maskElement);
+  }
+  if (this.viewData.length) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+MaskElement.prototype.getMaskProperty = function (pos) {
+  return this.viewData[pos].prop;
+};
+
+MaskElement.prototype.renderFrame = function (isFirstFrame) {
+  var finalMat = this.element.finalTransform.mat;
+  var i;
+  var len = this.masksProperties.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.viewData[i].prop._mdf || isFirstFrame) {
+      this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
+    }
+    if (this.viewData[i].op._mdf || isFirstFrame) {
+      this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
+    }
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
+        this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
+      }
+      if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
+        var feMorph = this.storedData[i].expan;
+        if (this.storedData[i].x.v < 0) {
+          if (this.storedData[i].lastOperator !== 'erode') {
+            this.storedData[i].lastOperator = 'erode';
+            this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
+          }
+          feMorph.setAttribute('radius', -this.storedData[i].x.v);
+        } else {
+          if (this.storedData[i].lastOperator !== 'dilate') {
+            this.storedData[i].lastOperator = 'dilate';
+            this.storedData[i].elem.setAttribute('filter', null);
+          }
+          this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
+        }
+      }
+    }
+  }
+};
+
+MaskElement.prototype.getMaskelement = function () {
+  return this.maskElement;
+};
+
+MaskElement.prototype.createLayerSolidPath = function () {
+  var path = 'M0,0 ';
+  path += ' h' + this.globalData.compSize.w;
+  path += ' v' + this.globalData.compSize.h;
+  path += ' h-' + this.globalData.compSize.w;
+  path += ' v-' + this.globalData.compSize.h + ' ';
+  return path;
+};
+
+MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
+  var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  var i;
+  var len;
+  len = pathNodes._length;
+  for (i = 1; i < len; i += 1) {
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
+  }
+  // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+  if (pathNodes.c && len > 1) {
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  }
+  // pathNodes.__renderedString = pathString;
+
+  if (viewData.lastPath !== pathString) {
+    var pathShapeValue = '';
+    if (viewData.elem) {
+      if (pathNodes.c) {
+        pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
+      }
+      viewData.elem.setAttribute('d', pathShapeValue);
+    }
+    viewData.lastPath = pathString;
+  }
+};
+
+MaskElement.prototype.destroy = function () {
+  this.element = null;
+  this.globalData = null;
+  this.maskElement = null;
+  this.data = null;
+  this.masksProperties = null;
+};
+
+const filtersFactory = (function () {
+  var ob = {};
+  ob.createFilter = createFilter;
+  ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
+
+  function createFilter(filId, skipCoordinates) {
+    var fil = createNS('filter');
+    fil.setAttribute('id', filId);
+    if (skipCoordinates !== true) {
+      fil.setAttribute('filterUnits', 'objectBoundingBox');
+      fil.setAttribute('x', '0%');
+      fil.setAttribute('y', '0%');
+      fil.setAttribute('width', '100%');
+      fil.setAttribute('height', '100%');
+    }
+    return fil;
+  }
+
+  function createAlphaToLuminanceFilter() {
+    var feColorMatrix = createNS('feColorMatrix');
+    feColorMatrix.setAttribute('type', 'matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+    feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
+    return feColorMatrix;
+  }
+
+  return ob;
+}());
+
+const featureSupport = (function () {
+  var ob = {
+    maskType: true,
+    svgLumaHidden: true,
+    offscreenCanvas: typeof OffscreenCanvas !== 'undefined',
+  };
+  if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
+    ob.maskType = false;
+  }
+  if (/firefox/i.test(navigator.userAgent)) {
+    ob.svgLumaHidden = false;
+  }
+  return ob;
+}());
+
+var registeredEffects$1 = {};
+var idPrefix = 'filter_result_';
+
+function SVGEffects(elem) {
+  var i;
+  var source = 'SourceGraphic';
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  var filId = createElementID();
+  var fil = filtersFactory.createFilter(filId, true);
+  var count = 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects$1[type]) {
+      var Effect = registeredEffects$1[type].effect;
+      filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
+      source = idPrefix + count;
+      if (registeredEffects$1[type].countsAsEffect) {
+        count += 1;
+      }
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (count) {
+    elem.globalData.defs.appendChild(fil);
+    elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+SVGEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect$1(id, effect, countsAsEffect) {
+  registeredEffects$1[id] = {
+    effect,
+    countsAsEffect,
+  };
+}
+
+function SVGBaseElement() {
+}
+
+SVGBaseElement.prototype = {
+  initRendererElement: function () {
+    this.layerElement = createNS('g');
+  },
+  createContainerElements: function () {
+    this.matteElement = createNS('g');
+    this.transformedElement = this.layerElement;
+    this.maskedElement = this.layerElement;
+    this._sizeChanged = false;
+    var layerElementParent = null;
+    // If this layer acts as a mask for the following layer
+    if (this.data.td) {
+      this.matteMasks = {};
+      var gg = createNS('g');
+      gg.setAttribute('id', this.layerId);
+      gg.appendChild(this.layerElement);
+      layerElementParent = gg;
+      this.globalData.defs.appendChild(gg);
+    } else if (this.data.tt) {
+      this.matteElement.appendChild(this.layerElement);
+      layerElementParent = this.matteElement;
+      this.baseElement = this.matteElement;
+    } else {
+      this.baseElement = this.layerElement;
+    }
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
+    if (this.data.ty === 0 && !this.data.hd) {
+      var cp = createNS('clipPath');
+      var pt = createNS('path');
+      pt.setAttribute('d', 'M0,0 L' + this.data.w + ',0 L' + this.data.w + ',' + this.data.h + ' L0,' + this.data.h + 'z');
+      var clipId = createElementID();
+      cp.setAttribute('id', clipId);
+      cp.appendChild(pt);
+      this.globalData.defs.appendChild(cp);
+
+      if (this.checkMasks()) {
+        var cpGroup = createNS('g');
+        cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+        cpGroup.appendChild(this.layerElement);
+        this.transformedElement = cpGroup;
+        if (layerElementParent) {
+          layerElementParent.appendChild(this.transformedElement);
+        } else {
+          this.baseElement = this.transformedElement;
+        }
+      } else {
+        this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+      }
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    if (this.finalTransform._localMatMdf) {
+      this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
+    }
+    if (this.finalTransform._opMdf) {
+      this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
+    }
+  },
+  destroyBaseElement: function () {
+    this.layerElement = null;
+    this.matteElement = null;
+    this.maskManager.destroy();
+  },
+  getBaseElement: function () {
+    if (this.data.hd) {
+      return null;
+    }
+    return this.baseElement;
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+    this.renderableEffectsManager = new SVGEffects(this);
+    this.searchEffectTransforms();
+  },
+  getMatte: function (matteType) {
+    // This should not be a common case. But for backward compatibility, we'll create the matte object.
+    // It solves animations that have two consecutive layers marked as matte masks.
+    // Which is an undefined behavior in AE.
+    if (!this.matteMasks) {
+      this.matteMasks = {};
+    }
+    if (!this.matteMasks[matteType]) {
+      var id = this.layerId + '_' + matteType;
+      var filId;
+      var fil;
+      var useElement;
+      var gg;
+      if (matteType === 1 || matteType === 3) {
+        var masker = createNS('mask');
+        masker.setAttribute('id', id);
+        masker.setAttribute('mask-type', matteType === 3 ? 'luminance' : 'alpha');
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        masker.appendChild(useElement);
+        this.globalData.defs.appendChild(masker);
+        if (!featureSupport.maskType && matteType === 1) {
+          masker.setAttribute('mask-type', 'luminance');
+          filId = createElementID();
+          fil = filtersFactory.createFilter(filId);
+          this.globalData.defs.appendChild(fil);
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          gg.appendChild(useElement);
+          masker.appendChild(gg);
+          gg.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        }
+      } else if (matteType === 2) {
+        var maskGroup = createNS('mask');
+        maskGroup.setAttribute('id', id);
+        maskGroup.setAttribute('mask-type', 'alpha');
+        var maskGrouper = createNS('g');
+        maskGroup.appendChild(maskGrouper);
+        filId = createElementID();
+        fil = filtersFactory.createFilter(filId);
+        /// /
+        var feCTr = createNS('feComponentTransfer');
+        feCTr.setAttribute('in', 'SourceGraphic');
+        fil.appendChild(feCTr);
+        var feFunc = createNS('feFuncA');
+        feFunc.setAttribute('type', 'table');
+        feFunc.setAttribute('tableValues', '1.0 0.0');
+        feCTr.appendChild(feFunc);
+        /// /
+        this.globalData.defs.appendChild(fil);
+        var alphaRect = createNS('rect');
+        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');
+        alphaRect.setAttribute('opacity', '0');
+        maskGrouper.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        maskGrouper.appendChild(alphaRect);
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        maskGrouper.appendChild(useElement);
+        if (!featureSupport.maskType) {
+          maskGroup.setAttribute('mask-type', 'luminance');
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          maskGrouper.appendChild(alphaRect);
+          gg.appendChild(this.layerElement);
+          maskGrouper.appendChild(gg);
+        }
+        this.globalData.defs.appendChild(maskGroup);
+      }
+      this.matteMasks[matteType] = id;
+    }
+    return this.matteMasks[matteType];
+  },
+  setMatte: function (id) {
+    if (!this.matteElement) {
+      return;
+    }
+    this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+  },
+};
+
+/**
+ * @file
+ * Handles AE's layer parenting property.
+ *
+ */
+
+function HierarchyElement() {}
+
+HierarchyElement.prototype = {
+  /**
+     * @function
+     * Initializes hierarchy properties
+     *
+     */
+  initHierarchy: function () {
+    // element's parent list
+    this.hierarchy = [];
+    // if element is parent of another layer _isParent will be true
+    this._isParent = false;
+    this.checkParenting();
+  },
+  /**
+     * @function
+     * Sets layer's hierarchy.
+     * @param {array} hierarch
+     * layer's parent list
+     *
+     */
+  setHierarchy: function (hierarchy) {
+    this.hierarchy = hierarchy;
+  },
+  /**
+     * @function
+     * Sets layer as parent.
+     *
+     */
+  setAsParent: function () {
+    this._isParent = true;
+  },
+  /**
+     * @function
+     * Searches layer's parenting chain
+     *
+     */
+  checkParenting: function () {
+    if (this.data.parent !== undefined) {
+      this.comp.buildElementParenting(this, this.data.parent, []);
+    }
+  },
+};
+
+function RenderableDOMElement() {}
+
+(function () {
+  var _prototype = {
+    initElement: function (data, globalData, comp) {
+      this.initFrame();
+      this.initBaseData(data, globalData, comp);
+      this.initTransform(data, globalData, comp);
+      this.initHierarchy();
+      this.initRenderable();
+      this.initRendererElement();
+      this.createContainerElements();
+      this.createRenderableComponents();
+      this.createContent();
+      this.hide();
+    },
+    hide: function () {
+      // console.log('HIDE', this);
+      if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+        var elem = this.baseElement || this.layerElement;
+        elem.style.display = 'none';
+        this.hidden = true;
+      }
+    },
+    show: function () {
+      // console.log('SHOW', this);
+      if (this.isInRange && !this.isTransparent) {
+        if (!this.data.hd) {
+          var elem = this.baseElement || this.layerElement;
+          elem.style.display = 'block';
+        }
+        this.hidden = false;
+        this._isFirstFrame = true;
+      }
+    },
+    renderFrame: function () {
+      // If it is exported as hidden (data.hd === true) no need to render
+      // If it is not visible no need to render
+      if (this.data.hd || this.hidden) {
+        return;
+      }
+      this.renderTransform();
+      this.renderRenderable();
+      this.renderLocalTransform();
+      this.renderElement();
+      this.renderInnerContent();
+      if (this._isFirstFrame) {
+        this._isFirstFrame = false;
+      }
+    },
+    renderInnerContent: function () {},
+    prepareFrame: function (num) {
+      this._mdf = false;
+      this.prepareRenderableFrame(num);
+      this.prepareProperties(num, this.isInRange);
+      this.checkTransparency();
+    },
+    destroy: function () {
+      this.innerElem = null;
+      this.destroyBaseElement();
+    },
+  };
+  extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement);
+}());
+
+function IImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  if (this.assetData && this.assetData.sid) {
+    this.assetData = globalData.slotManager.getProp(this.assetData);
+  }
+  this.initElement(data, globalData, comp);
+  this.sourceRect = {
+    top: 0, left: 0, width: this.assetData.w, height: this.assetData.h,
+  };
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
+
+IImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+
+  this.innerElem = createNS('image');
+  this.innerElem.setAttribute('width', this.assetData.w + 'px');
+  this.innerElem.setAttribute('height', this.assetData.h + 'px');
+  this.innerElem.setAttribute('preserveAspectRatio', this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio);
+  this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+
+  this.layerElement.appendChild(this.innerElem);
+};
+
+IImageElement.prototype.sourceRectAtTime = function () {
+  return this.sourceRect;
+};
+
+function ProcessedElement(element, position) {
+  this.elem = element;
+  this.pos = position;
+}
+
+function IShapeElement() {
+}
+
+IShapeElement.prototype = {
+  addShapeToModifiers: function (data) {
+    var i;
+    var len = this.shapeModifiers.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapeModifiers[i].addShape(data);
+    }
+  },
+  isShapeInAnimatedModifiers: function (data) {
+    var i = 0;
+    var len = this.shapeModifiers.length;
+    while (i < len) {
+      if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
+        return true;
+      }
+    }
+    return false;
+  },
+  renderModifiers: function () {
+    if (!this.shapeModifiers.length) {
+      return;
+    }
+    var i;
+    var len = this.shapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].sh.reset();
+    }
+
+    len = this.shapeModifiers.length;
+    var shouldBreakProcess;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+      // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+      // TODO: find a better solution for this
+      if (shouldBreakProcess) {
+        break;
+      }
+    }
+  },
+
+  searchProcessedElement: function (elem) {
+    var elements = this.processedElements;
+    var i = 0;
+    var len = elements.length;
+    while (i < len) {
+      if (elements[i].elem === elem) {
+        return elements[i].pos;
+      }
+      i += 1;
+    }
+    return 0;
+  },
+  addProcessedElement: function (elem, pos) {
+    var elements = this.processedElements;
+    var i = elements.length;
+    while (i) {
+      i -= 1;
+      if (elements[i].elem === elem) {
+        elements[i].pos = pos;
+        return;
+      }
+    }
+    elements.push(new ProcessedElement(elem, pos));
+  },
+  prepareFrame: function (num) {
+    this.prepareRenderableFrame(num);
+    this.prepareProperties(num, this.isInRange);
+  },
+};
+
+const lineCapEnum = {
+  1: 'butt',
+  2: 'round',
+  3: 'square',
+};
+
+const lineJoinEnum = {
+  1: 'miter',
+  2: 'round',
+  3: 'bevel',
+};
+
+function SVGShapeData(transformers, level, shape) {
+  this.caches = [];
+  this.styles = [];
+  this.transformers = transformers;
+  this.lStr = '';
+  this.sh = shape;
+  this.lvl = level;
+  // TODO find if there are some cases where _isAnimated can be false.
+  // For now, since shapes add up with other shapes. They have to be calculated every time.
+  // One way of finding out is checking if all styles associated to this shape depend only of this shape
+  this._isAnimated = !!shape.k;
+  // TODO: commenting this for now since all shapes are animated
+  var i = 0;
+  var len = transformers.length;
+  while (i < len) {
+    if (transformers[i].mProps.dynamicProperties.length) {
+      this._isAnimated = true;
+      break;
+    }
+    i += 1;
+  }
+}
+
+SVGShapeData.prototype.setAsAnimated = function () {
+  this._isAnimated = true;
+};
+
+function SVGStyleData(data, level) {
+  this.data = data;
+  this.type = data.ty;
+  this.d = '';
+  this.lvl = level;
+  this._mdf = false;
+  this.closed = data.hd === true;
+  this.pElem = createNS('path');
+  this.msElem = null;
+}
+
+SVGStyleData.prototype.reset = function () {
+  this.d = '';
+  this._mdf = false;
+};
+
+function DashProperty(elem, data, renderer, container) {
+  this.elem = elem;
+  this.frameId = -1;
+  this.dataProps = createSizedArray(data.length);
+  this.renderer = renderer;
+  this.k = false;
+  this.dashStr = '';
+  this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0);
+  this.dashoffset = createTypedArray('float32', 1);
+  this.initDynamicPropertyContainer(container);
+  var i;
+  var len = data.length || 0;
+  var prop;
+  for (i = 0; i < len; i += 1) {
+    prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
+    this.k = prop.k || this.k;
+    this.dataProps[i] = { n: data[i].n, p: prop };
+  }
+  if (!this.k) {
+    this.getValue(true);
+  }
+  this._isAnimated = this.k;
+}
+
+DashProperty.prototype.getValue = function (forceRender) {
+  if (this.elem.globalData.frameId === this.frameId && !forceRender) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+  this._mdf = this._mdf || forceRender;
+  if (this._mdf) {
+    var i = 0;
+    var len = this.dataProps.length;
+    if (this.renderer === 'svg') {
+      this.dashStr = '';
+    }
+    for (i = 0; i < len; i += 1) {
+      if (this.dataProps[i].n !== 'o') {
+        if (this.renderer === 'svg') {
+          this.dashStr += ' ' + this.dataProps[i].p.v;
+        } else {
+          this.dashArray[i] = this.dataProps[i].p.v;
+        }
+      } else {
+        this.dashoffset[0] = this.dataProps[i].p.v;
+      }
+    }
+  }
+};
+extendPrototype([DynamicPropertyContainer], DashProperty);
+
+function SVGStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
+
+function SVGFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
+
+function SVGNoStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
+
+function GradientProperty(elem, data, container) {
+  this.data = data;
+  this.c = createTypedArray('uint8c', data.p * 4);
+  var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p * 4) : data.k.k.length - data.p * 4;
+  this.o = createTypedArray('float32', cLength);
+  this._cmdf = false;
+  this._omdf = false;
+  this._collapsable = this.checkCollapsable();
+  this._hasOpacity = cLength;
+  this.initDynamicPropertyContainer(container);
+  this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this);
+  this.k = this.prop.k;
+  this.getValue(true);
+}
+
+GradientProperty.prototype.comparePoints = function (values, points) {
+  var i = 0;
+  var len = this.o.length / 2;
+  var diff;
+  while (i < len) {
+    diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
+    if (diff > 0.01) {
+      return false;
+    }
+    i += 1;
+  }
+  return true;
+};
+
+GradientProperty.prototype.checkCollapsable = function () {
+  if (this.o.length / 2 !== this.c.length / 4) {
+    return false;
+  }
+  if (this.data.k.k[0].s) {
+    var i = 0;
+    var len = this.data.k.k.length;
+    while (i < len) {
+      if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
+        return false;
+      }
+      i += 1;
+    }
+  } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
+    return false;
+  }
+  return true;
+};
+
+GradientProperty.prototype.getValue = function (forceRender) {
+  this.prop.getValue();
+  this._mdf = false;
+  this._cmdf = false;
+  this._omdf = false;
+  if (this.prop._mdf || forceRender) {
+    var i;
+    var len = this.data.p * 4;
+    var mult;
+    var val;
+    for (i = 0; i < len; i += 1) {
+      mult = i % 4 === 0 ? 100 : 255;
+      val = Math.round(this.prop.v[i] * mult);
+      if (this.c[i] !== val) {
+        this.c[i] = val;
+        this._cmdf = !forceRender;
+      }
+    }
+    if (this.o.length) {
+      len = this.prop.v.length;
+      for (i = this.data.p * 4; i < len; i += 1) {
+        mult = i % 2 === 0 ? 100 : 1;
+        val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
+        if (this.o[i - this.data.p * 4] !== val) {
+          this.o[i - this.data.p * 4] = val;
+          this._omdf = !forceRender;
+        }
+      }
+    }
+    this._mdf = !forceRender;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], GradientProperty);
+
+function SVGGradientFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.initGradientData(elem, data, styleOb);
+}
+
+SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 1, null, this);
+  this.h = PropertyFactory.getProp(elem, data.h || { k: 0 }, 0, 0.01, this);
+  this.a = PropertyFactory.getProp(elem, data.a || { k: 0 }, 0, degToRads, this);
+  this.g = new GradientProperty(elem, data.g, this);
+  this.style = styleOb;
+  this.stops = [];
+  this.setGradientData(styleOb.pElem, data);
+  this.setGradientOpacity(data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+};
+
+SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
+  var gradientId = createElementID();
+  var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+  gfill.setAttribute('id', gradientId);
+  gfill.setAttribute('spreadMethod', 'pad');
+  gfill.setAttribute('gradientUnits', 'userSpaceOnUse');
+  var stops = [];
+  var stop;
+  var j;
+  var jLen;
+  jLen = data.g.p * 4;
+  for (j = 0; j < jLen; j += 4) {
+    stop = createNS('stop');
+    gfill.appendChild(stop);
+    stops.push(stop);
+  }
+  pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
+  this.gf = gfill;
+  this.cst = stops;
+};
+
+SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
+  if (this.g._hasOpacity && !this.g._collapsable) {
+    var stop;
+    var j;
+    var jLen;
+    var mask = createNS('mask');
+    var maskElement = createNS('path');
+    mask.appendChild(maskElement);
+    var opacityId = createElementID();
+    var maskId = createElementID();
+    mask.setAttribute('id', maskId);
+    var opFill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+    opFill.setAttribute('id', opacityId);
+    opFill.setAttribute('spreadMethod', 'pad');
+    opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
+    jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
+    var stops = this.stops;
+    for (j = data.g.p * 4; j < jLen; j += 2) {
+      stop = createNS('stop');
+      stop.setAttribute('stop-color', 'rgb(255,255,255)');
+      opFill.appendChild(stop);
+      stops.push(stop);
+    }
+    maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
+    this.maskId = maskId;
+    styleOb.msElem = maskElement;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
+
+function SVGGradientStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.initGradientData(elem, data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
+
+function ShapeGroupData() {
+  this.it = [];
+  this.prevViewData = [];
+  this.gr = createNS('g');
+}
+
+function SVGTransformData(mProps, op, container) {
+  this.transform = {
+    mProps: mProps,
+    op: op,
+    container: container,
+  };
+  this.elements = [];
+  this._isAnimated = this.transform.mProps.dynamicProperties.length || this.transform.op.effectsSequence.length;
+}
+
+const buildShapeString = function (pathNodes, length, closed, mat) {
+  if (length === 0) {
+    return '';
+  }
+  var _o = pathNodes.o;
+  var _i = pathNodes.i;
+  var _v = pathNodes.v;
+  var i;
+  var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+  for (i = 1; i < length; i += 1) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
+  }
+  if (closed && length) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+    shapeString += 'z';
+  }
+  return shapeString;
+};
+
+const SVGElementsRenderer = (function () {
+  var _identityMatrix = new Matrix();
+  var _matrixHelper = new Matrix();
+
+  var ob = {
+    createRenderFunction: createRenderFunction,
+  };
+
+  function createRenderFunction(data) {
+    switch (data.ty) {
+      case 'fl':
+        return renderFill;
+      case 'gf':
+        return renderGradient;
+      case 'gs':
+        return renderGradientStroke;
+      case 'st':
+        return renderStroke;
+      case 'sh':
+      case 'el':
+      case 'rc':
+      case 'sr':
+        return renderPath;
+      case 'tr':
+        return renderContentTransform;
+      case 'no':
+        return renderNoop;
+      default:
+        return null;
+    }
+  }
+
+  function renderContentTransform(styleData, itemData, isFirstFrame) {
+    if (isFirstFrame || itemData.transform.op._mdf) {
+      itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
+    }
+    if (isFirstFrame || itemData.transform.mProps._mdf) {
+      itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
+    }
+  }
+
+  function renderNoop() {
+
+  }
+
+  function renderPath(styleData, itemData, isFirstFrame) {
+    var j;
+    var jLen;
+    var pathStringTransformed;
+    var redraw;
+    var pathNodes;
+    var l;
+    var lLen = itemData.styles.length;
+    var lvl = itemData.lvl;
+    var paths;
+    var mat;
+    var iterations;
+    var k;
+    for (l = 0; l < lLen; l += 1) {
+      redraw = itemData.sh._mdf || isFirstFrame;
+      if (itemData.styles[l].lvl < lvl) {
+        mat = _matrixHelper.reset();
+        iterations = lvl - itemData.styles[l].lvl;
+        k = itemData.transformers.length - 1;
+        while (!redraw && iterations > 0) {
+          redraw = itemData.transformers[k].mProps._mdf || redraw;
+          iterations -= 1;
+          k -= 1;
+        }
+        if (redraw) {
+          iterations = lvl - itemData.styles[l].lvl;
+          k = itemData.transformers.length - 1;
+          while (iterations > 0) {
+            mat.multiply(itemData.transformers[k].mProps.v);
+            iterations -= 1;
+            k -= 1;
+          }
+        }
+      } else {
+        mat = _identityMatrix;
+      }
+      paths = itemData.sh.paths;
+      jLen = paths._length;
+      if (redraw) {
+        pathStringTransformed = '';
+        for (j = 0; j < jLen; j += 1) {
+          pathNodes = paths.shapes[j];
+          if (pathNodes && pathNodes._length) {
+            pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
+          }
+        }
+        itemData.caches[l] = pathStringTransformed;
+      } else {
+        pathStringTransformed = itemData.caches[l];
+      }
+      itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
+      itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
+    }
+  }
+
+  function renderFill(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+
+    if (itemData.c._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
+    }
+  }
+
+  function renderGradientStroke(styleData, itemData, isFirstFrame) {
+    renderGradient(styleData, itemData, isFirstFrame);
+    renderStroke(styleData, itemData, isFirstFrame);
+  }
+
+  function renderGradient(styleData, itemData, isFirstFrame) {
+    var gfill = itemData.gf;
+    var hasOpacity = itemData.g._hasOpacity;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+
+    if (itemData.o._mdf || isFirstFrame) {
+      var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
+      itemData.style.pElem.setAttribute(attr, itemData.o.v);
+    }
+    if (itemData.s._mdf || isFirstFrame) {
+      var attr1 = styleData.t === 1 ? 'x1' : 'cx';
+      var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
+      gfill.setAttribute(attr1, pt1[0]);
+      gfill.setAttribute(attr2, pt1[1]);
+      if (hasOpacity && !itemData.g._collapsable) {
+        itemData.of.setAttribute(attr1, pt1[0]);
+        itemData.of.setAttribute(attr2, pt1[1]);
+      }
+    }
+    var stops;
+    var i;
+    var len;
+    var stop;
+    if (itemData.g._cmdf || isFirstFrame) {
+      stops = itemData.cst;
+      var cValues = itemData.g.c;
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        stop.setAttribute('offset', cValues[i * 4] + '%');
+        stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
+      }
+    }
+    if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
+      var oValues = itemData.g.o;
+      if (itemData.g._collapsable) {
+        stops = itemData.cst;
+      } else {
+        stops = itemData.ost;
+      }
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        if (!itemData.g._collapsable) {
+          stop.setAttribute('offset', oValues[i * 2] + '%');
+        }
+        stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
+      }
+    }
+    if (styleData.t === 1) {
+      if (itemData.e._mdf || isFirstFrame) {
+        gfill.setAttribute('x2', pt2[0]);
+        gfill.setAttribute('y2', pt2[1]);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('x2', pt2[0]);
+          itemData.of.setAttribute('y2', pt2[1]);
+        }
+      }
+    } else {
+      var rad;
+      if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
+        rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        gfill.setAttribute('r', rad);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('r', rad);
+        }
+      }
+      if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (!rad) {
+          rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        }
+        var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+        var percent = itemData.h.v;
+        if (percent >= 1) {
+          percent = 0.99;
+        } else if (percent <= -1) {
+          percent = -0.99;
+        }
+        var dist = rad * percent;
+        var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+        var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+        gfill.setAttribute('fx', x);
+        gfill.setAttribute('fy', y);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('fx', x);
+          itemData.of.setAttribute('fy', y);
+        }
+      }
+      // gfill.setAttribute('fy','200');
+    }
+  }
+
+  function renderStroke(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+    var d = itemData.d;
+    if (d && (d._mdf || isFirstFrame) && d.dashStr) {
+      styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
+      styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
+    }
+    if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
+      styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
+    }
+    if (itemData.w._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
+      if (styleElem.msElem) {
+        styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
+      }
+    }
+  }
+
+  return ob;
+}());
+
+function SVGShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
+
+SVGShapeElement.prototype.initSecondaryElement = function () {
+};
+
+SVGShapeElement.prototype.identityMatrix = new Matrix();
+
+SVGShapeElement.prototype.buildExpressionInterface = function () {};
+
+SVGShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+};
+
+/*
+This method searches for multiple shapes that affect a single element and one of them is animated
+*/
+SVGShapeElement.prototype.filterUniqueShapes = function () {
+  var i;
+  var len = this.shapes.length;
+  var shape;
+  var j;
+  var jLen = this.stylesList.length;
+  var style;
+  var tempShapes = [];
+  var areAnimated = false;
+  for (j = 0; j < jLen; j += 1) {
+    style = this.stylesList[j];
+    areAnimated = false;
+    tempShapes.length = 0;
+    for (i = 0; i < len; i += 1) {
+      shape = this.shapes[i];
+      if (shape.styles.indexOf(style) !== -1) {
+        tempShapes.push(shape);
+        areAnimated = shape._isAnimated || areAnimated;
+      }
+    }
+    if (tempShapes.length > 1 && areAnimated) {
+      this.setShapesAsAnimated(tempShapes);
+    }
+  }
+};
+
+SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
+  var i;
+  var len = shapes.length;
+  for (i = 0; i < len; i += 1) {
+    shapes[i].setAsAnimated();
+  }
+};
+
+SVGShapeElement.prototype.createStyleElement = function (data, level) {
+  // TODO: prevent drawing of hidden styles
+  var elementData;
+  var styleOb = new SVGStyleData(data, level);
+
+  var pathElement = styleOb.pElem;
+  if (data.ty === 'st') {
+    elementData = new SVGStrokeStyleData(this, data, styleOb);
+  } else if (data.ty === 'fl') {
+    elementData = new SVGFillStyleData(this, data, styleOb);
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
+    elementData = new GradientConstructor(this, data, styleOb);
+    this.globalData.defs.appendChild(elementData.gf);
+    if (elementData.maskId) {
+      this.globalData.defs.appendChild(elementData.ms);
+      this.globalData.defs.appendChild(elementData.of);
+      pathElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + elementData.maskId + ')');
+    }
+  } else if (data.ty === 'no') {
+    elementData = new SVGNoStyleData(this, data, styleOb);
+  }
+
+  if (data.ty === 'st' || data.ty === 'gs') {
+    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);
+    }
+  }
+
+  if (data.r === 2) {
+    pathElement.setAttribute('fill-rule', 'evenodd');
+  }
+
+  if (data.ln) {
+    pathElement.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    pathElement.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  this.stylesList.push(styleOb);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createGroupElement = function (data) {
+  var elementData = new ShapeGroupData();
+  if (data.ln) {
+    elementData.gr.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    elementData.gr.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  return elementData;
+};
+
+SVGShapeElement.prototype.createTransformElement = function (data, container) {
+  var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
+  var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
+  var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
+  var i = 0;
+  var len = this.animatedContents.length;
+  while (i < len) {
+    if (this.animatedContents[i].element === element) {
+      return;
+    }
+    i += 1;
+  }
+  this.animatedContents.push({
+    fn: SVGElementsRenderer.createRenderFunction(data),
+    element: element,
+    data: data,
+  });
+};
+
+SVGShapeElement.prototype.setElementStyles = function (elementData) {
+  var arr = elementData.styles;
+  var j;
+  var jLen = this.stylesList.length;
+  for (j = 0; j < jLen; j += 1) {
+    if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
+      arr.push(this.stylesList[j]);
+    }
+  }
+};
+
+SVGShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+};
+
+SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
+  var ownTransformers = [].concat(transformers);
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var currentTransform;
+  var modifier;
+  var processedPos;
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._render = render;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], level);
+      } else {
+        itemsData[i].style.closed = arr[i].hd;
+      }
+      if (arr[i]._render) {
+        if (itemsData[i].style.pElem.parentNode !== container) {
+          container.appendChild(itemsData[i].style.pElem);
+        }
+      }
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
+      if (arr[i]._render) {
+        if (itemsData[i].gr.parentNode !== container) {
+          container.appendChild(itemsData[i].gr);
+        }
+      }
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        itemsData[i] = this.createTransformElement(arr[i], container);
+      }
+      currentTransform = itemsData[i].transform;
+      ownTransformers.push(currentTransform);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
+      }
+      this.setElementStyles(itemsData[i]);
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        render = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  len = ownStyles.length;
+  for (i = 0; i < len; i += 1) {
+    ownStyles[i].closed = true;
+  }
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+SVGShapeElement.prototype.renderInnerContent = function () {
+  this.renderModifiers();
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    this.stylesList[i].reset();
+  }
+  this.renderShape();
+  for (i = 0; i < len; i += 1) {
+    if (this.stylesList[i]._mdf || this._isFirstFrame) {
+      if (this.stylesList[i].msElem) {
+        this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+        // Adding M0 0 fixes same mask bug on all browsers
+        this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
+      }
+      this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
+    }
+  }
+};
+
+SVGShapeElement.prototype.renderShape = function () {
+  var i;
+  var len = this.animatedContents.length;
+  var animatedContent;
+  for (i = 0; i < len; i += 1) {
+    animatedContent = this.animatedContents[i];
+    if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
+      animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
+    }
+  }
+};
+
+SVGShapeElement.prototype.destroy = function () {
+  this.destroyBaseElement();
+  this.shapesData = null;
+  this.itemsData = null;
+};
+
+function LetterProps(o, sw, sc, fc, m, p) {
+  this.o = o;
+  this.sw = sw;
+  this.sc = sc;
+  this.fc = fc;
+  this.m = m;
+  this.p = p;
+  this._mdf = {
+    o: true,
+    sw: !!sw,
+    sc: !!sc,
+    fc: !!fc,
+    m: true,
+    p: true,
+  };
+}
+
+LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
+  this._mdf.o = false;
+  this._mdf.sw = false;
+  this._mdf.sc = false;
+  this._mdf.fc = false;
+  this._mdf.m = false;
+  this._mdf.p = false;
+  var updated = false;
+
+  if (this.o !== o) {
+    this.o = o;
+    this._mdf.o = true;
+    updated = true;
+  }
+  if (this.sw !== sw) {
+    this.sw = sw;
+    this._mdf.sw = true;
+    updated = true;
+  }
+  if (this.sc !== sc) {
+    this.sc = sc;
+    this._mdf.sc = true;
+    updated = true;
+  }
+  if (this.fc !== fc) {
+    this.fc = fc;
+    this._mdf.fc = true;
+    updated = true;
+  }
+  if (this.m !== m) {
+    this.m = m;
+    this._mdf.m = true;
+    updated = true;
+  }
+  if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
+    this.p = p;
+    this._mdf.p = true;
+    updated = true;
+  }
+  return updated;
+};
+
+function TextProperty(elem, data) {
+  this._frameId = initialDefaultFrame;
+  this.pv = '';
+  this.v = '';
+  this.kf = false;
+  this._isFirstFrame = true;
+  this._mdf = false;
+  if (data.d && data.d.sid) {
+    data.d = elem.globalData.slotManager.getProp(data.d);
+  }
+  this.data = data;
+  this.elem = elem;
+  this.comp = this.elem.comp;
+  this.keysIndex = 0;
+  this.canResize = false;
+  this.minimumFontSize = 1;
+  this.effectsSequence = [];
+  this.currentData = {
+    ascent: 0,
+    boxWidth: this.defaultBoxWidth,
+    f: '',
+    fStyle: '',
+    fWeight: '',
+    fc: '',
+    j: '',
+    justifyOffset: '',
+    l: [],
+    lh: 0,
+    lineWidths: [],
+    ls: '',
+    of: '',
+    s: '',
+    sc: '',
+    sw: 0,
+    t: 0,
+    tr: 0,
+    sz: 0,
+    ps: null,
+    fillColorAnim: false,
+    strokeColorAnim: false,
+    strokeWidthAnim: false,
+    yOffset: 0,
+    finalSize: 0,
+    finalText: [],
+    finalLineHeight: 0,
+    __complete: false,
+
+  };
+  this.copyData(this.currentData, this.data.d.k[0].s);
+
+  if (!this.searchProperty()) {
+    this.completeTextData(this.currentData);
+  }
+}
+
+TextProperty.prototype.defaultBoxWidth = [0, 0];
+
+TextProperty.prototype.copyData = function (obj, data) {
+  for (var s in data) {
+    if (Object.prototype.hasOwnProperty.call(data, s)) {
+      obj[s] = data[s];
+    }
+  }
+  return obj;
+};
+
+TextProperty.prototype.setCurrentData = function (data) {
+  if (!data.__complete) {
+    this.completeTextData(data);
+  }
+  this.currentData = data;
+  this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
+  this._mdf = true;
+};
+
+TextProperty.prototype.searchProperty = function () {
+  return this.searchKeyframes();
+};
+
+TextProperty.prototype.searchKeyframes = function () {
+  this.kf = this.data.d.k.length > 1;
+  if (this.kf) {
+    this.addEffect(this.getKeyframeValue.bind(this));
+  }
+  return this.kf;
+};
+
+TextProperty.prototype.addEffect = function (effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.getValue = function (_finalValue) {
+  if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
+    return;
+  }
+  this.currentData.t = this.data.d.k[this.keysIndex].s.t;
+  var currentValue = this.currentData;
+  var currentIndex = this.keysIndex;
+  if (this.lock) {
+    this.setCurrentData(this.currentData);
+    return;
+  }
+  this.lock = true;
+  this._mdf = false;
+  var i; var
+    len = this.effectsSequence.length;
+  var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
+  for (i = 0; i < len; i += 1) {
+    // Checking if index changed to prevent creating a new object every time the expression updates.
+    if (currentIndex !== this.keysIndex) {
+      finalValue = this.effectsSequence[i](finalValue, finalValue.t);
+    } else {
+      finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
+    }
+  }
+  if (currentValue !== finalValue) {
+    this.setCurrentData(finalValue);
+  }
+  this.v = this.currentData;
+  this.pv = this.v;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+};
+
+TextProperty.prototype.getKeyframeValue = function () {
+  var textKeys = this.data.d.k;
+  var frameNum = this.elem.comp.renderedFrame;
+  var i = 0; var
+    len = textKeys.length;
+  while (i <= len - 1) {
+    if (i === len - 1 || textKeys[i + 1].t > frameNum) {
+      break;
+    }
+    i += 1;
+  }
+  if (this.keysIndex !== i) {
+    this.keysIndex = i;
+  }
+  return this.data.d.k[this.keysIndex].s;
+};
+
+TextProperty.prototype.buildFinalText = function (text) {
+  var charactersArray = [];
+  var i = 0;
+  var len = text.length;
+  var charCode;
+  var secondCharCode;
+  var shouldCombine = false;
+  var shouldCombineNext = false;
+  var currentChars = '';
+  while (i < len) {
+    shouldCombine = shouldCombineNext;
+    shouldCombineNext = false;
+    charCode = text.charCodeAt(i);
+    currentChars = text.charAt(i);
+    if (FontManager.isCombinedCharacter(charCode)) {
+      shouldCombine = true;
+      // It's a potential surrogate pair (this is the High surrogate)
+    } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+      if (FontManager.isRegionalFlag(text, i)) {
+        currentChars = text.substr(i, 14);
+      } else {
+        secondCharCode = text.charCodeAt(i + 1);
+        // It's a surrogate pair (this is the Low surrogate)
+        if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
+          if (FontManager.isModifier(charCode, secondCharCode)) {
+            currentChars = text.substr(i, 2);
+            shouldCombine = true;
+          } else if (FontManager.isFlagEmoji(text.substr(i, 4))) {
+            currentChars = text.substr(i, 4);
+          } else {
+            currentChars = text.substr(i, 2);
+          }
+        }
+      }
+    } else if (charCode > 0xDBFF) {
+      secondCharCode = text.charCodeAt(i + 1);
+      if (FontManager.isVariationSelector(charCode)) {
+        shouldCombine = true;
+      }
+    } else if (FontManager.isZeroWidthJoiner(charCode)) {
+      shouldCombine = true;
+      shouldCombineNext = true;
+    }
+    if (shouldCombine) {
+      charactersArray[charactersArray.length - 1] += currentChars;
+      shouldCombine = false;
+    } else {
+      charactersArray.push(currentChars);
+    }
+    i += currentChars.length;
+  }
+  return charactersArray;
+};
+
+TextProperty.prototype.completeTextData = function (documentData) {
+  documentData.__complete = true;
+  var fontManager = this.elem.globalData.fontManager;
+  var data = this.data;
+  var letters = [];
+  var i; var
+    len;
+  var newLineFlag; var index = 0; var
+    val;
+  var anchorGrouping = data.m.g;
+  var currentSize = 0; var currentPos = 0; var currentLine = 0; var
+    lineWidths = [];
+  var lineWidth = 0;
+  var maxLineWidth = 0;
+  var j; var
+    jLen;
+  var fontData = fontManager.getFontByName(documentData.f);
+  var charData; var
+    cLength = 0;
+
+  var fontProps = getFontProperties(fontData);
+  documentData.fWeight = fontProps.weight;
+  documentData.fStyle = fontProps.style;
+  documentData.finalSize = documentData.s;
+  documentData.finalText = this.buildFinalText(documentData.t);
+  len = documentData.finalText.length;
+  documentData.finalLineHeight = documentData.lh;
+  var trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+  var charCode;
+  if (documentData.sz) {
+    var flag = true;
+    var boxWidth = documentData.sz[0];
+    var boxHeight = documentData.sz[1];
+    var currentHeight; var
+      finalText;
+    while (flag) {
+      finalText = this.buildFinalText(documentData.t);
+      currentHeight = 0;
+      lineWidth = 0;
+      len = finalText.length;
+      trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+      var lastSpaceIndex = -1;
+      for (i = 0; i < len; i += 1) {
+        charCode = finalText[i].charCodeAt(0);
+        newLineFlag = false;
+        if (finalText[i] === ' ') {
+          lastSpaceIndex = i;
+        } else if (charCode === 13 || charCode === 3) {
+          lineWidth = 0;
+          newLineFlag = true;
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+        }
+        if (fontManager.chars) {
+          charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
+          cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+        } else {
+          // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
+          cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
+        }
+        if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
+          if (lastSpaceIndex === -1) {
+            len += 1;
+          } else {
+            i = lastSpaceIndex;
+          }
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+          finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+          // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
+          lastSpaceIndex = -1;
+          lineWidth = 0;
+        } else {
+          lineWidth += cLength;
+          lineWidth += trackingOffset;
+        }
+      }
+      currentHeight += (fontData.ascent * documentData.finalSize) / 100;
+      if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
+        documentData.finalSize -= 1;
+        documentData.finalLineHeight = (documentData.finalSize * documentData.lh) / documentData.s;
+      } else {
+        documentData.finalText = finalText;
+        len = documentData.finalText.length;
+        flag = false;
+      }
+    }
+  }
+  lineWidth = -trackingOffset;
+  cLength = 0;
+  var uncollapsedSpaces = 0;
+  var currentChar;
+  for (i = 0; i < len; i += 1) {
+    newLineFlag = false;
+    currentChar = documentData.finalText[i];
+    charCode = currentChar.charCodeAt(0);
+    if (charCode === 13 || charCode === 3) {
+      uncollapsedSpaces = 0;
+      lineWidths.push(lineWidth);
+      maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+      lineWidth = -2 * trackingOffset;
+      val = '';
+      newLineFlag = true;
+      currentLine += 1;
+    } else {
+      val = currentChar;
+    }
+    if (fontManager.chars) {
+      charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
+      cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+    } else {
+      // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
+      // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
+      cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
+    }
+
+    //
+    if (currentChar === ' ') {
+      uncollapsedSpaces += cLength + trackingOffset;
+    } else {
+      lineWidth += cLength + trackingOffset + uncollapsedSpaces;
+      uncollapsedSpaces = 0;
+    }
+    letters.push({
+      l: cLength, an: cLength, add: currentSize, n: newLineFlag, anIndexes: [], val: val, line: currentLine, animatorJustifyOffset: 0,
+    });
+    if (anchorGrouping == 2) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || val === ' ' || i === len - 1) {
+        if (val === '' || val === ' ') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        index += 1;
+        currentSize = 0;
+      }
+    } else if (anchorGrouping == 3) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || i === len - 1) {
+        if (val === '') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        currentSize = 0;
+        index += 1;
+      }
+    } else {
+      letters[index].ind = index;
+      letters[index].extra = 0;
+      index += 1;
+    }
+  }
+  documentData.l = letters;
+  maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+  lineWidths.push(lineWidth);
+  if (documentData.sz) {
+    documentData.boxWidth = documentData.sz[0];
+    documentData.justifyOffset = 0;
+  } else {
+    documentData.boxWidth = maxLineWidth;
+    switch (documentData.j) {
+      case 1:
+        documentData.justifyOffset = -documentData.boxWidth;
+        break;
+      case 2:
+        documentData.justifyOffset = -documentData.boxWidth / 2;
+        break;
+      default:
+        documentData.justifyOffset = 0;
+    }
+  }
+  documentData.lineWidths = lineWidths;
+
+  var animators = data.a; var animatorData; var
+    letterData;
+  jLen = animators.length;
+  var based; var ind; var
+    indexes = [];
+  for (j = 0; j < jLen; j += 1) {
+    animatorData = animators[j];
+    if (animatorData.a.sc) {
+      documentData.strokeColorAnim = true;
+    }
+    if (animatorData.a.sw) {
+      documentData.strokeWidthAnim = true;
+    }
+    if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
+      documentData.fillColorAnim = true;
+    }
+    ind = 0;
+    based = animatorData.s.b;
+    for (i = 0; i < len; i += 1) {
+      letterData = letters[i];
+      letterData.anIndexes[j] = ind;
+      if ((based == 1 && letterData.val !== '') || (based == 2 && letterData.val !== '' && letterData.val !== ' ') || (based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1)) || (based == 4 && (letterData.n || i == len - 1))) { // eslint-disable-line eqeqeq
+        if (animatorData.s.rn === 1) {
+          indexes.push(ind);
+        }
+        ind += 1;
+      }
+    }
+    data.a[j].s.totalChars = ind;
+    var currentInd = -1; var
+      newInd;
+    if (animatorData.s.rn === 1) {
+      for (i = 0; i < len; i += 1) {
+        letterData = letters[i];
+        if (currentInd != letterData.anIndexes[j]) { // eslint-disable-line eqeqeq
+          currentInd = letterData.anIndexes[j];
+          newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
+        }
+        letterData.anIndexes[j] = newInd;
+      }
+    }
+  }
+  documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
+  documentData.ls = documentData.ls || 0;
+  documentData.ascent = (fontData.ascent * documentData.finalSize) / 100;
+};
+
+TextProperty.prototype.updateDocumentData = function (newData, index) {
+  index = index === undefined ? this.keysIndex : index;
+  var dData = this.copyData({}, this.data.d.k[index].s);
+  dData = this.copyData(dData, newData);
+  this.data.d.k[index].s = dData;
+  this.recalculate(index);
+  this.setCurrentData(dData);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.recalculate = function (index) {
+  var dData = this.data.d.k[index].s;
+  dData.__complete = false;
+  this.keysIndex = 0;
+  this._isFirstFrame = true;
+  this.getValue(dData);
+};
+
+TextProperty.prototype.canResizeFont = function (_canResize) {
+  this.canResize = _canResize;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
+  this.minimumFontSize = Math.floor(_fontValue) || 1;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+const TextSelectorProp = (function () {
+  var max = Math.max;
+  var min = Math.min;
+  var floor = Math.floor;
+
+  function TextSelectorPropFactory(elem, data) {
+    this._currentTextLength = -1;
+    this.k = false;
+    this.data = data;
+    this.elem = elem;
+    this.comp = elem.comp;
+    this.finalS = 0;
+    this.finalE = 0;
+    this.initDynamicPropertyContainer(elem);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: 0 }, 0, 0, this);
+    if ('e' in data) {
+      this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
+    } else {
+      this.e = { v: 100 };
+    }
+    this.o = PropertyFactory.getProp(elem, data.o || { k: 0 }, 0, 0, this);
+    this.xe = PropertyFactory.getProp(elem, data.xe || { k: 0 }, 0, 0, this);
+    this.ne = PropertyFactory.getProp(elem, data.ne || { k: 0 }, 0, 0, this);
+    this.sm = PropertyFactory.getProp(elem, data.sm || { k: 100 }, 0, 0, this);
+    this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
+    if (!this.dynamicProperties.length) {
+      this.getValue();
+    }
+  }
+
+  TextSelectorPropFactory.prototype = {
+    getMult: function (ind) {
+      if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
+        this.getValue();
+      }
+      var x1 = 0;
+      var y1 = 0;
+      var x2 = 1;
+      var y2 = 1;
+      if (this.ne.v > 0) {
+        x1 = this.ne.v / 100.0;
+      } else {
+        y1 = -this.ne.v / 100.0;
+      }
+      if (this.xe.v > 0) {
+        x2 = 1.0 - this.xe.v / 100.0;
+      } else {
+        y2 = 1.0 + this.xe.v / 100.0;
+      }
+      var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
+
+      var mult = 0;
+      var s = this.finalS;
+      var e = this.finalE;
+      var type = this.data.sh;
+      if (type === 2) {
+        if (e === s) {
+          mult = ind >= e ? 1 : 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+        mult = easer(mult);
+      } else if (type === 3) {
+        if (e === s) {
+          mult = ind >= e ? 0 : 1;
+        } else {
+          mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+
+        mult = easer(mult);
+      } else if (type === 4) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+          if (mult < 0.5) {
+            mult *= 2;
+          } else {
+            mult = 1 - 2 * (mult - 0.5);
+          }
+        }
+        mult = easer(mult);
+      } else if (type === 5) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          var tot = e - s;
+          /* ind += 0.5;
+                    mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          var x = -tot / 2 + ind;
+          var a = tot / 2;
+          mult = Math.sqrt(1 - (x * x) / (a * a));
+        }
+        mult = easer(mult);
+      } else if (type === 6) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; // eslint-disable-line
+        }
+        mult = easer(mult);
+      } else {
+        if (ind >= floor(s)) {
+          if (ind - s < 0) {
+            mult = max(0, min(min(e, 1) - (s - ind), 1));
+          } else {
+            mult = max(0, min(e - ind, 1));
+          }
+        }
+        mult = easer(mult);
+      }
+      // Smoothness implementation.
+      // The smoothness represents a reduced range of the original [0; 1] range.
+      // if smoothness is 25%, the new range will be [0.375; 0.625]
+      // Steps are:
+      // - find the lower value of the new range (threshold)
+      // - if multiplier is smaller than that value, floor it to 0
+      // - if it is larger,
+      //     - subtract the threshold
+      //     - divide it by the smoothness (this will return the range to [0; 1])
+      // Note: If it doesn't work on some scenarios, consider applying it before the easer.
+      if (this.sm.v !== 100) {
+        var smoothness = this.sm.v * 0.01;
+        if (smoothness === 0) {
+          smoothness = 0.00000001;
+        }
+        var threshold = 0.5 - smoothness * 0.5;
+        if (mult < threshold) {
+          mult = 0;
+        } else {
+          mult = (mult - threshold) / smoothness;
+          if (mult > 1) {
+            mult = 1;
+          }
+        }
+      }
+      return mult * this.a.v;
+    },
+    getValue: function (newCharsFlag) {
+      this.iterateDynamicProperties();
+      this._mdf = newCharsFlag || this._mdf;
+      this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
+      if (newCharsFlag && this.data.r === 2) {
+        this.e.v = this._currentTextLength;
+      }
+      var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
+      var o = this.o.v / divisor;
+      var s = this.s.v / divisor + o;
+      var e = (this.e.v / divisor) + o;
+      if (s > e) {
+        var _s = s;
+        s = e;
+        e = _s;
+      }
+      this.finalS = s;
+      this.finalE = e;
+    },
+  };
+  extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
+
+  function getTextSelectorProp(elem, data, arr) {
+    return new TextSelectorPropFactory(elem, data, arr);
+  }
+
+  return {
+    getTextSelectorProp: getTextSelectorProp,
+  };
+}());
+
+function TextAnimatorDataProperty(elem, animatorProps, container) {
+  var defaultData = { propType: false };
+  var getProp = PropertyFactory.getProp;
+  var textAnimatorAnimatables = animatorProps.a;
+  this.a = {
+    r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData,
+    rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData,
+    ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData,
+    sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData,
+    sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData,
+    s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData,
+    a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData,
+    o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData,
+    p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData,
+    sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData,
+    sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData,
+    fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData,
+    fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData,
+    fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData,
+    fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData,
+    t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData,
+  };
+
+  this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container);
+  this.s.t = animatorProps.s.t;
+}
+
+function TextAnimatorProperty(textData, renderType, elem) {
+  this._isFirstFrame = true;
+  this._hasMaskedPath = false;
+  this._frameId = -1;
+  this._textData = textData;
+  this._renderType = renderType;
+  this._elem = elem;
+  this._animatorsData = createSizedArray(this._textData.a.length);
+  this._pathData = {};
+  this._moreOptions = {
+    alignment: {},
+  };
+  this.renderedLetters = [];
+  this.lettersChangedFlag = false;
+  this.initDynamicPropertyContainer(elem);
+}
+
+TextAnimatorProperty.prototype.searchProperties = function () {
+  var i;
+  var len = this._textData.a.length;
+  var animatorProps;
+  var getProp = PropertyFactory.getProp;
+  for (i = 0; i < len; i += 1) {
+    animatorProps = this._textData.a[i];
+    this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
+  }
+  if (this._textData.p && 'm' in this._textData.p) {
+    this._pathData = {
+      a: getProp(this._elem, this._textData.p.a, 0, 0, this),
+      f: getProp(this._elem, this._textData.p.f, 0, 0, this),
+      l: getProp(this._elem, this._textData.p.l, 0, 0, this),
+      r: getProp(this._elem, this._textData.p.r, 0, 0, this),
+      p: getProp(this._elem, this._textData.p.p, 0, 0, this),
+      m: this._elem.maskManager.getMaskProperty(this._textData.p.m),
+    };
+    this._hasMaskedPath = true;
+  } else {
+    this._hasMaskedPath = false;
+  }
+  this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
+};
+
+TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
+  this.lettersChangedFlag = lettersChangedFlag;
+  if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
+    return;
+  }
+  this._isFirstFrame = false;
+  var alignment = this._moreOptions.alignment.v;
+  var animators = this._animatorsData;
+  var textData = this._textData;
+  var matrixHelper = this.mHelper;
+  var renderType = this._renderType;
+  var renderedLettersCount = this.renderedLetters.length;
+  var xPos;
+  var yPos;
+  var i;
+  var len;
+  var letters = documentData.l;
+  var pathInfo;
+  var currentLength;
+  var currentPoint;
+  var segmentLength;
+  var flag;
+  var pointInd;
+  var segmentInd;
+  var prevPoint;
+  var points;
+  var segments;
+  var partialLength;
+  var totalLength;
+  var perc;
+  var tanAngle;
+  var mask;
+  if (this._hasMaskedPath) {
+    mask = this._pathData.m;
+    if (!this._pathData.n || this._pathData._mdf) {
+      var paths = mask.v;
+      if (this._pathData.r.v) {
+        paths = paths.reverse();
+      }
+      // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
+      pathInfo = {
+        tLength: 0,
+        segments: [],
+      };
+      len = paths._length - 1;
+      var bezierData;
+      totalLength = 0;
+      for (i = 0; i < len; i += 1) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[i + 1],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      i = len;
+      if (mask.v.c) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[0],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      this._pathData.pi = pathInfo;
+    }
+    pathInfo = this._pathData.pi;
+
+    currentLength = this._pathData.f.v;
+    segmentInd = 0;
+    pointInd = 1;
+    segmentLength = 0;
+    flag = true;
+    segments = pathInfo.segments;
+    if (currentLength < 0 && mask.v.c) {
+      if (pathInfo.tLength < Math.abs(currentLength)) {
+        currentLength = -Math.abs(currentLength) % pathInfo.tLength;
+      }
+      segmentInd = segments.length - 1;
+      points = segments[segmentInd].points;
+      pointInd = points.length - 1;
+      while (currentLength < 0) {
+        currentLength += points[pointInd].partialLength;
+        pointInd -= 1;
+        if (pointInd < 0) {
+          segmentInd -= 1;
+          points = segments[segmentInd].points;
+          pointInd = points.length - 1;
+        }
+      }
+    }
+    points = segments[segmentInd].points;
+    prevPoint = points[pointInd - 1];
+    currentPoint = points[pointInd];
+    partialLength = currentPoint.partialLength;
+  }
+
+  len = letters.length;
+  xPos = 0;
+  yPos = 0;
+  var yOff = documentData.finalSize * 1.2 * 0.714;
+  var firstLine = true;
+  var animatorProps;
+  var animatorSelector;
+  var j;
+  var jLen;
+  var letterValue;
+
+  jLen = animators.length;
+
+  var mult;
+  var ind = -1;
+  var offf;
+  var xPathPos;
+  var yPathPos;
+  var initPathPos = currentLength;
+  var initSegmentInd = segmentInd;
+  var initPointInd = pointInd;
+  var currentLine = -1;
+  var elemOpacity;
+  var sc;
+  var sw;
+  var fc;
+  var k;
+  var letterSw;
+  var letterSc;
+  var letterFc;
+  var letterM = '';
+  var letterP = this.defaultPropsArray;
+  var letterO;
+
+  //
+  if (documentData.j === 2 || documentData.j === 1) {
+    var animatorJustifyOffset = 0;
+    var animatorFirstCharOffset = 0;
+    var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
+    var lastIndex = 0;
+    var isNewLine = true;
+
+    for (i = 0; i < len; i += 1) {
+      if (letters[i].n) {
+        if (animatorJustifyOffset) {
+          animatorJustifyOffset += animatorFirstCharOffset;
+        }
+        while (lastIndex < i) {
+          letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+          lastIndex += 1;
+        }
+        animatorJustifyOffset = 0;
+        isNewLine = true;
+      } else {
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.t.propType) {
+            if (isNewLine && documentData.j === 2) {
+              animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
+            }
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
+            } else {
+              animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult;
+            }
+          }
+        }
+        isNewLine = false;
+      }
+    }
+    if (animatorJustifyOffset) {
+      animatorJustifyOffset += animatorFirstCharOffset;
+    }
+    while (lastIndex < i) {
+      letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+      lastIndex += 1;
+    }
+  }
+  //
+
+  for (i = 0; i < len; i += 1) {
+    matrixHelper.reset();
+    elemOpacity = 1;
+    if (letters[i].n) {
+      xPos = 0;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      currentLength = initPathPos;
+      firstLine = false;
+      if (this._hasMaskedPath) {
+        segmentInd = initSegmentInd;
+        pointInd = initPointInd;
+        points = segments[segmentInd].points;
+        prevPoint = points[pointInd - 1];
+        currentPoint = points[pointInd];
+        partialLength = currentPoint.partialLength;
+        segmentLength = 0;
+      }
+      letterM = '';
+      letterFc = '';
+      letterSw = '';
+      letterO = '';
+      letterP = this.defaultPropsArray;
+    } else {
+      if (this._hasMaskedPath) {
+        if (currentLine !== letters[i].line) {
+          switch (documentData.j) {
+            case 1:
+              currentLength += totalLength - documentData.lineWidths[letters[i].line];
+              break;
+            case 2:
+              currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
+              break;
+            default:
+              break;
+          }
+          currentLine = letters[i].line;
+        }
+        if (ind !== letters[i].ind) {
+          if (letters[ind]) {
+            currentLength += letters[ind].extra;
+          }
+          currentLength += letters[i].an / 2;
+          ind = letters[i].ind;
+        }
+        currentLength += (alignment[0] * letters[i].an) * 0.005;
+        var animatorOffset = 0;
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.p.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.p.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.p.v[0] * mult;
+            }
+          }
+          if (animatorProps.a.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.a.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.a.v[0] * mult;
+            }
+          }
+        }
+        flag = true;
+        // Force alignment only works with a single line for now
+        if (this._pathData.a.v) {
+          currentLength = letters[0].an * 0.5 + ((totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind) / (len - 1);
+          currentLength += this._pathData.f.v;
+        }
+        while (flag) {
+          if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
+            perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
+            xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
+            yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
+            matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, -(alignment[1] * yOff) * 0.01);
+            flag = false;
+          } else if (points) {
+            segmentLength += currentPoint.partialLength;
+            pointInd += 1;
+            if (pointInd >= points.length) {
+              pointInd = 0;
+              segmentInd += 1;
+              if (!segments[segmentInd]) {
+                if (mask.v.c) {
+                  pointInd = 0;
+                  segmentInd = 0;
+                  points = segments[segmentInd].points;
+                } else {
+                  segmentLength -= currentPoint.partialLength;
+                  points = null;
+                }
+              } else {
+                points = segments[segmentInd].points;
+              }
+            }
+            if (points) {
+              prevPoint = currentPoint;
+              currentPoint = points[pointInd];
+              partialLength = currentPoint.partialLength;
+            }
+          }
+        }
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+      } else {
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+
+        // Grouping alignment
+        matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, (-alignment[1] * yOff) * 0.01, 0);
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.t.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
+          if (xPos !== 0 || documentData.j !== 0) {
+            if (this._hasMaskedPath) {
+              if (mult.length) {
+                currentLength += animatorProps.t.v * mult[0];
+              } else {
+                currentLength += animatorProps.t.v * mult;
+              }
+            } else if (mult.length) {
+              xPos += animatorProps.t.v * mult[0];
+            } else {
+              xPos += animatorProps.t.v * mult;
+            }
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        sw = documentData.sw || 0;
+      }
+      if (documentData.strokeColorAnim) {
+        if (documentData.sc) {
+          sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
+        } else {
+          sc = [0, 0, 0];
+        }
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.a.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+
+          if (mult.length) {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.s.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (mult.length) {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult[0]), 1 + ((animatorProps.s.v[1] - 1) * mult[1]), 1);
+          } else {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult), 1 + ((animatorProps.s.v[1] - 1) * mult), 1);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        animatorSelector = animators[j].s;
+        mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+        if (animatorProps.sk.propType) {
+          if (mult.length) {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
+          } else {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
+          }
+        }
+        if (animatorProps.r.propType) {
+          if (mult.length) {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
+          } else {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult);
+          }
+        }
+        if (animatorProps.ry.propType) {
+          if (mult.length) {
+            matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
+          } else {
+            matrixHelper.rotateY(animatorProps.ry.v * mult);
+          }
+        }
+        if (animatorProps.rx.propType) {
+          if (mult.length) {
+            matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
+          } else {
+            matrixHelper.rotateX(animatorProps.rx.v * mult);
+          }
+        }
+        if (animatorProps.o.propType) {
+          if (mult.length) {
+            elemOpacity += ((animatorProps.o.v) * mult[0] - elemOpacity) * mult[0];
+          } else {
+            elemOpacity += ((animatorProps.o.v) * mult - elemOpacity) * mult;
+          }
+        }
+        if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
+          if (mult.length) {
+            sw += animatorProps.sw.v * mult[0];
+          } else {
+            sw += animatorProps.sw.v * mult;
+          }
+        }
+        if (documentData.strokeColorAnim && animatorProps.sc.propType) {
+          for (k = 0; k < 3; k += 1) {
+            if (mult.length) {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0];
+            } else {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult;
+            }
+          }
+        }
+        if (documentData.fillColorAnim && documentData.fc) {
+          if (animatorProps.fc.propType) {
+            for (k = 0; k < 3; k += 1) {
+              if (mult.length) {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0];
+              } else {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult;
+              }
+            }
+          }
+          if (animatorProps.fh.propType) {
+            if (mult.length) {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
+            } else {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult);
+            }
+          }
+          if (animatorProps.fs.propType) {
+            if (mult.length) {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
+            } else {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
+            }
+          }
+          if (animatorProps.fb.propType) {
+            if (mult.length) {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
+            } else {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult);
+            }
+          }
+        }
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+
+        if (animatorProps.p.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (this._hasMaskedPath) {
+            if (mult.length) {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
+            } else {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+            }
+          } else if (mult.length) {
+            matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        letterSw = sw < 0 ? 0 : sw;
+      }
+      if (documentData.strokeColorAnim) {
+        letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
+      }
+
+      if (this._hasMaskedPath) {
+        matrixHelper.translate(0, -documentData.ls);
+
+        matrixHelper.translate(0, (alignment[1] * yOff) * 0.01 + yPos, 0);
+        if (this._pathData.p.v) {
+          tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
+          var rot = (Math.atan(tanAngle) * 180) / Math.PI;
+          if (currentPoint.point[0] < prevPoint.point[0]) {
+            rot += 180;
+          }
+          matrixHelper.rotate((-rot * Math.PI) / 180);
+        }
+        matrixHelper.translate(xPathPos, yPathPos, 0);
+        currentLength -= (alignment[0] * letters[i].an) * 0.005;
+        if (letters[i + 1] && ind !== letters[i + 1].ind) {
+          currentLength += letters[i].an / 2;
+          currentLength += (documentData.tr * 0.001) * documentData.finalSize;
+        }
+      } else {
+        matrixHelper.translate(xPos, yPos, 0);
+
+        if (documentData.ps) {
+          // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
+          matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+        }
+        switch (documentData.j) {
+          case 1:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
+            break;
+          case 2:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
+            break;
+          default:
+            break;
+        }
+        matrixHelper.translate(0, -documentData.ls);
+        matrixHelper.translate(offf, 0, 0);
+        matrixHelper.translate((alignment[0] * letters[i].an) * 0.005, (alignment[1] * yOff) * 0.01, 0);
+        xPos += letters[i].l + (documentData.tr * 0.001) * documentData.finalSize;
+      }
+      if (renderType === 'html') {
+        letterM = matrixHelper.toCSS();
+      } else if (renderType === 'svg') {
+        letterM = matrixHelper.to2dCSS();
+      } else {
+        letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
+      }
+      letterO = elemOpacity;
+    }
+
+    if (renderedLettersCount <= i) {
+      letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
+      this.renderedLetters.push(letterValue);
+      renderedLettersCount += 1;
+      this.lettersChangedFlag = true;
+    } else {
+      letterValue = this.renderedLetters[i];
+      this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag;
+    }
+  }
+};
+
+TextAnimatorProperty.prototype.getValue = function () {
+  if (this._elem.globalData.frameId === this._frameId) {
+    return;
+  }
+  this._frameId = this._elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+TextAnimatorProperty.prototype.mHelper = new Matrix();
+TextAnimatorProperty.prototype.defaultPropsArray = [];
+extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
+
+function ITextElement() {
+}
+
+ITextElement.prototype.initElement = function (data, globalData, comp) {
+  this.lettersChangedFlag = true;
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.textProperty = new TextProperty(this, data.t, this.dynamicProperties);
+  this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this);
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+  this.initRenderable();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  this.createContent();
+  this.hide();
+  this.textAnimator.searchProperties(this.dynamicProperties);
+};
+
+ITextElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+};
+
+ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
+  var j;
+  var jLen = shapes.length;
+  var pathNodes;
+  var shapeStr = '';
+  for (j = 0; j < jLen; j += 1) {
+    if (shapes[j].ty === 'sh') {
+      pathNodes = shapes[j].ks.k;
+      shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
+    }
+  }
+  return shapeStr;
+};
+
+ITextElement.prototype.updateDocumentData = function (newData, index) {
+  this.textProperty.updateDocumentData(newData, index);
+};
+
+ITextElement.prototype.canResizeFont = function (_canResize) {
+  this.textProperty.canResizeFont(_canResize);
+};
+
+ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
+  this.textProperty.setMinimumFontSize(_fontSize);
+};
+
+ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
+  if (documentData.ps) {
+    matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+  }
+  matrixHelper.translate(0, -documentData.ls, 0);
+  switch (documentData.j) {
+    case 1:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
+      break;
+    case 2:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
+      break;
+    default:
+      break;
+  }
+  matrixHelper.translate(xPos, yPos, 0);
+};
+
+ITextElement.prototype.buildColor = function (colorData) {
+  return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
+};
+
+ITextElement.prototype.emptyProp = new LetterProps();
+
+ITextElement.prototype.destroy = function () {
+
+};
+
+ITextElement.prototype.validateText = function () {
+  if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
+    this.buildNewText();
+    this.textProperty._isFirstFrame = false;
+    this.textProperty._mdf = false;
+  }
+};
+
+var emptyShapeData = {
+  shapes: [],
+};
+
+function SVGTextLottieElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.renderType = 'svg';
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
+
+SVGTextLottieElement.prototype.createContent = function () {
+  if (this.data.singleShape && !this.globalData.fontManager.chars) {
+    this.textContainer = createNS('text');
+  }
+};
+
+SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
+  var i = 0;
+  var len = textArray.length;
+  var textContents = [];
+  var currentTextContent = '';
+  while (i < len) {
+    if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
+      textContents.push(currentTextContent);
+      currentTextContent = '';
+    } else {
+      currentTextContent += textArray[i];
+    }
+    i += 1;
+  }
+  textContents.push(currentTextContent);
+  return textContents;
+};
+
+SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
+  // data should probably be cloned to apply scale separately to each instance of a text on different layers
+  // but since text internal content gets only rendered once and then it's never rerendered,
+  // it's probably safe not to clone data and reuse always the same instance even if the object is mutated.
+  // Avoiding cloning is preferred since cloning each character shape data is expensive
+  if (data.shapes && data.shapes.length) {
+    var shape = data.shapes[0];
+    if (shape.it) {
+      var shapeItem = shape.it[shape.it.length - 1];
+      if (shapeItem.s) {
+        shapeItem.s.k[0] = scale;
+        shapeItem.s.k[1] = scale;
+      }
+    }
+  }
+  return data;
+};
+
+SVGTextLottieElement.prototype.buildNewText = function () {
+  this.addDynamicProperty(this);
+  var i;
+  var len;
+
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
+  if (documentData.fc) {
+    this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
+  } else {
+    this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
+  }
+  if (documentData.sc) {
+    this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
+    this.layerElement.setAttribute('stroke-width', documentData.sw);
+  }
+  this.layerElement.setAttribute('font-size', documentData.finalSize);
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (fontData.fClass) {
+    this.layerElement.setAttribute('class', fontData.fClass);
+  } else {
+    this.layerElement.setAttribute('font-family', fontData.fFamily);
+    var fWeight = documentData.fWeight;
+    var fStyle = documentData.fStyle;
+    this.layerElement.setAttribute('font-style', fStyle);
+    this.layerElement.setAttribute('font-weight', fWeight);
+  }
+  this.layerElement.setAttribute('aria-label', documentData.t);
+
+  var letters = documentData.l || [];
+  var usesGlyphs = !!this.globalData.fontManager.chars;
+  len = letters.length;
+
+  var tSpan;
+  var matrixHelper = this.mHelper;
+  var shapeStr = '';
+  var singleShape = this.data.singleShape;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  if (singleShape && !usesGlyphs && !documentData.sz) {
+    var tElement = this.textContainer;
+    var justify = 'start';
+    switch (documentData.j) {
+      case 1:
+        justify = 'end';
+        break;
+      case 2:
+        justify = 'middle';
+        break;
+      default:
+        justify = 'start';
+        break;
+    }
+    tElement.setAttribute('text-anchor', justify);
+    tElement.setAttribute('letter-spacing', trackingOffset);
+    var textContent = this.buildTextContents(documentData.finalText);
+    len = textContent.length;
+    yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
+    for (i = 0; i < len; i += 1) {
+      tSpan = this.textSpans[i].span || createNS('tspan');
+      tSpan.textContent = textContent[i];
+      tSpan.setAttribute('x', 0);
+      tSpan.setAttribute('y', yPos);
+      tSpan.style.display = 'inherit';
+      tElement.appendChild(tSpan);
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          glyph: null,
+        };
+      }
+      this.textSpans[i].span = tSpan;
+      yPos += documentData.finalLineHeight;
+    }
+
+    this.layerElement.appendChild(tElement);
+  } else {
+    var cachedSpansLength = this.textSpans.length;
+    var charData;
+    for (i = 0; i < len; i += 1) {
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          childSpan: null,
+          glyph: null,
+        };
+      }
+      if (!usesGlyphs || !singleShape || i === 0) {
+        tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
+        if (cachedSpansLength <= i) {
+          tSpan.setAttribute('stroke-linecap', 'butt');
+          tSpan.setAttribute('stroke-linejoin', 'round');
+          tSpan.setAttribute('stroke-miterlimit', '4');
+          this.textSpans[i].span = tSpan;
+          if (usesGlyphs) {
+            var childSpan = createNS('g');
+            tSpan.appendChild(childSpan);
+            this.textSpans[i].childSpan = childSpan;
+          }
+          this.textSpans[i].span = tSpan;
+          this.layerElement.appendChild(tSpan);
+        }
+        tSpan.style.display = 'inherit';
+      }
+
+      matrixHelper.reset();
+      if (singleShape) {
+        if (letters[i].n) {
+          xPos = -trackingOffset;
+          yPos += documentData.yOffset;
+          yPos += firstLine ? 1 : 0;
+          firstLine = false;
+        }
+        this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+        xPos += letters[i].l || 0;
+        // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
+        xPos += trackingOffset;
+      }
+      if (usesGlyphs) {
+        charData = this.globalData.fontManager.getCharData(
+          documentData.finalText[i],
+          fontData.fStyle,
+          this.globalData.fontManager.getFontByName(documentData.f).fFamily
+        );
+        var glyphElement;
+        // t === 1 means the character has been replaced with an animated shaped
+        if (charData.t === 1) {
+          glyphElement = new SVGCompElement(charData.data, this.globalData, this);
+        } else {
+          var data = emptyShapeData;
+          if (charData.data && charData.data.shapes) {
+            data = this.buildShapeData(charData.data, documentData.finalSize);
+          }
+          glyphElement = new SVGShapeElement(data, this.globalData, this);
+        }
+        if (this.textSpans[i].glyph) {
+          var glyph = this.textSpans[i].glyph;
+          this.textSpans[i].childSpan.removeChild(glyph.layerElement);
+          glyph.destroy();
+        }
+        this.textSpans[i].glyph = glyphElement;
+        glyphElement._debug = true;
+        glyphElement.prepareFrame(0);
+        glyphElement.renderFrame();
+        this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+        // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+        // this might have issues with strokes and might need a different solution
+        if (charData.t === 1) {
+          this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
+        }
+      } else {
+        if (singleShape) {
+          tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
+        }
+        tSpan.textContent = letters[i].val;
+        tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      }
+      //
+    }
+    if (singleShape && tSpan) {
+      tSpan.setAttribute('d', shapeStr);
+    }
+  }
+  while (i < this.textSpans.length) {
+    this.textSpans[i].span.style.display = 'none';
+    i += 1;
+  }
+
+  this._sizeChanged = true;
+};
+
+SVGTextLottieElement.prototype.sourceRectAtTime = function () {
+  this.prepareFrame(this.comp.renderedFrame - this.data.st);
+  this.renderInnerContent();
+  if (this._sizeChanged) {
+    this._sizeChanged = false;
+    var textBox = this.layerElement.getBBox();
+    this.bbox = {
+      top: textBox.y,
+      left: textBox.x,
+      width: textBox.width,
+      height: textBox.height,
+    };
+  }
+  return this.bbox;
+};
+
+SVGTextLottieElement.prototype.getValue = function () {
+  var i;
+  var len = this.textSpans.length;
+  var glyphElement;
+  this.renderedFrame = this.comp.renderedFrame;
+  for (i = 0; i < len; i += 1) {
+    glyphElement = this.textSpans[i].glyph;
+    if (glyphElement) {
+      glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
+      if (glyphElement._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+SVGTextLottieElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  if (!this.data.singleShape || this._mdf) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+    if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
+      this._sizeChanged = true;
+      var i;
+      var len;
+      var renderedLetters = this.textAnimator.renderedLetters;
+
+      var letters = this.textProperty.currentData.l;
+
+      len = letters.length;
+      var renderedLetter;
+      var textSpan;
+      var glyphElement;
+      for (i = 0; i < len; i += 1) {
+        if (!letters[i].n) {
+          renderedLetter = renderedLetters[i];
+          textSpan = this.textSpans[i].span;
+          glyphElement = this.textSpans[i].glyph;
+          if (glyphElement) {
+            glyphElement.renderFrame();
+          }
+          if (renderedLetter._mdf.m) {
+            textSpan.setAttribute('transform', renderedLetter.m);
+          }
+          if (renderedLetter._mdf.o) {
+            textSpan.setAttribute('opacity', renderedLetter.o);
+          }
+          if (renderedLetter._mdf.sw) {
+            textSpan.setAttribute('stroke-width', renderedLetter.sw);
+          }
+          if (renderedLetter._mdf.sc) {
+            textSpan.setAttribute('stroke', renderedLetter.sc);
+          }
+          if (renderedLetter._mdf.fc) {
+            textSpan.setAttribute('fill', renderedLetter.fc);
+          }
+        }
+      }
+    }
+  }
+};
+
+function ISolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([IImageElement], ISolidElement);
+
+ISolidElement.prototype.createContent = function () {
+  var rect = createNS('rect');
+  /// /rect.style.width = this.data.sw;
+  /// /rect.style.height = this.data.sh;
+  /// /rect.style.fill = this.data.sc;
+  rect.setAttribute('width', this.data.sw);
+  rect.setAttribute('height', this.data.sh);
+  rect.setAttribute('fill', this.data.sc);
+  this.layerElement.appendChild(rect);
+};
+
+function NullElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initFrame();
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+}
+
+NullElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+NullElement.prototype.renderFrame = function () {
+};
+
+NullElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+NullElement.prototype.destroy = function () {
+};
+
+NullElement.prototype.sourceRectAtTime = function () {
+};
+
+NullElement.prototype.hide = function () {
+};
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
+
+function SVGRendererBase() {
+}
+
+extendPrototype([BaseRenderer], SVGRendererBase);
+
+SVGRendererBase.prototype.createNull = function (data) {
+  return new NullElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createShape = function (data) {
+  return new SVGShapeElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createText = function (data) {
+  return new SVGTextLottieElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createImage = function (data) {
+  return new IImageElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createSolid = function (data) {
+  return new ISolidElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.configAnimation = function (animData) {
+  this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+  this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+  if (this.renderConfig.viewBoxSize) {
+    this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
+  } else {
+    this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
+  }
+
+  if (!this.renderConfig.viewBoxOnly) {
+    this.svgElement.setAttribute('width', animData.w);
+    this.svgElement.setAttribute('height', animData.h);
+    this.svgElement.style.width = '100%';
+    this.svgElement.style.height = '100%';
+    this.svgElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
+  }
+  if (this.renderConfig.width) {
+    this.svgElement.setAttribute('width', this.renderConfig.width);
+  }
+  if (this.renderConfig.height) {
+    this.svgElement.setAttribute('height', this.renderConfig.height);
+  }
+  if (this.renderConfig.className) {
+    this.svgElement.setAttribute('class', this.renderConfig.className);
+  }
+  if (this.renderConfig.id) {
+    this.svgElement.setAttribute('id', this.renderConfig.id);
+  }
+  if (this.renderConfig.focusable !== undefined) {
+    this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
+  }
+  this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+  // this.layerElement.style.transform = 'translate3d(0,0,0)';
+  // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
+  this.animationItem.wrapper.appendChild(this.svgElement);
+  // Mask animation
+  var defs = this.globalData.defs;
+
+  this.setupGlobalData(animData, defs);
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.data = animData;
+
+  var maskElement = createNS('clipPath');
+  var rect = createNS('rect');
+  rect.setAttribute('width', animData.w);
+  rect.setAttribute('height', animData.h);
+  rect.setAttribute('x', 0);
+  rect.setAttribute('y', 0);
+  var maskId = createElementID();
+  maskElement.setAttribute('id', maskId);
+  maskElement.appendChild(rect);
+  this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')');
+
+  defs.appendChild(maskElement);
+  this.layers = animData.layers;
+  this.elements = createSizedArray(animData.layers.length);
+};
+
+SVGRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.layerElement = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+SVGRendererBase.prototype.updateContainerSize = function () {
+};
+
+SVGRendererBase.prototype.findIndexByInd = function (ind) {
+  var i = 0;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.layers[i].ind === ind) {
+      return i;
+    }
+  }
+  return -1;
+};
+
+SVGRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  elements[pos] = true;
+  var element = this.createItem(this.layers[pos]);
+
+  elements[pos] = element;
+  if (getExpressionsPlugin()) {
+    if (this.layers[pos].ty === 0) {
+      this.globalData.projectInterface.registerComposition(element);
+    }
+    element.initExpressions();
+  }
+  this.appendElementInPos(element, pos);
+  if (this.layers[pos].tt) {
+    var elementIndex = ('tp' in this.layers[pos])
+      ? this.findIndexByInd(this.layers[pos].tp)
+      : pos - 1;
+    if (elementIndex === -1) {
+      return;
+    }
+    if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
+      this.buildItem(elementIndex);
+      this.addPendingElement(element);
+    } else {
+      var matteElement = elements[elementIndex];
+      var matteMask = matteElement.getMatte(this.layers[pos].tt);
+      element.setMatte(matteMask);
+    }
+  }
+};
+
+SVGRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+    if (element.data.tt) {
+      var i = 0;
+      var len = this.elements.length;
+      while (i < len) {
+        if (this.elements[i] === element) {
+          var elementIndex = 'tp' in element.data
+            ? this.findIndexByInd(element.data.tp)
+            : i - 1;
+          var matteElement = this.elements[elementIndex];
+          var matteMask = matteElement.getMatte(this.layers[i].tt);
+          element.setMatte(matteMask);
+          break;
+        }
+        i += 1;
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.renderFrame = function (num) {
+  if (this.renderedFrame === num || this.destroyed) {
+    return;
+  }
+  if (num === null) {
+    num = this.renderedFrame;
+  } else {
+    this.renderedFrame = num;
+  }
+  // console.log('-------');
+  // console.log('FRAME ',num);
+  this.globalData.frameNum = num;
+  this.globalData.frameId += 1;
+  this.globalData.projectInterface.currentFrame = num;
+  this.globalData._mdf = false;
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    for (i = 0; i < len; i += 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
+  var newElement = element.getBaseElement();
+  if (!newElement) {
+    return;
+  }
+  var i = 0;
+  var nextElement;
+  while (i < pos) {
+    if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
+      nextElement = this.elements[i].getBaseElement();
+    }
+    i += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(newElement, nextElement);
+  } else {
+    this.layerElement.appendChild(newElement);
+  }
+};
+
+SVGRendererBase.prototype.hide = function () {
+  this.layerElement.style.display = 'none';
+};
+
+SVGRendererBase.prototype.show = function () {
+  this.layerElement.style.display = 'block';
+};
+
+function ICompElement() {}
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
+
+ICompElement.prototype.initElement = function (data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initTransform(data, globalData, comp);
+  this.initRenderable();
+  this.initHierarchy();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  if (this.data.xt || !globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+  this.hide();
+};
+
+/* ICompElement.prototype.hide = function(){
+    if(!this.hidden){
+        this.hideElement();
+        var i,len = this.elements.length;
+        for( i = 0; i < len; i+=1 ){
+            if(this.elements[i]){
+                this.elements[i].hide();
+            }
+        }
+    }
+}; */
+
+ICompElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+  if (!this.isInRange && !this.data.xt) {
+    return;
+  }
+
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    if (timeRemapped === this.data.op) {
+      timeRemapped = this.data.op - 1;
+    }
+    this.renderedFrame = timeRemapped;
+  } else {
+    this.renderedFrame = num / this.data.sr;
+  }
+  var i;
+  var len = this.elements.length;
+  if (!this.completeLayers) {
+    this.checkLayers(this.renderedFrame);
+  }
+  // This iteration needs to be backwards because of how expressions connect between each other
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
+      if (this.elements[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+ICompElement.prototype.renderInnerContent = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+ICompElement.prototype.setElements = function (elems) {
+  this.elements = elems;
+};
+
+ICompElement.prototype.getElements = function () {
+  return this.elements;
+};
+
+ICompElement.prototype.destroyElements = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+};
+
+ICompElement.prototype.destroy = function () {
+  this.destroyElements();
+  this.destroyBaseElement();
+};
+
+function SVGCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = true;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
+
+SVGCompElement.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function SVGRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.layers = null;
+  this.renderedFrame = -1;
+  this.svgElement = createNS('svg');
+  var ariaLabel = '';
+  if (config && config.title) {
+    var titleElement = createNS('title');
+    var titleId = createElementID();
+    titleElement.setAttribute('id', titleId);
+    titleElement.textContent = config.title;
+    this.svgElement.appendChild(titleElement);
+    ariaLabel += titleId;
+  }
+  if (config && config.description) {
+    var descElement = createNS('desc');
+    var descId = createElementID();
+    descElement.setAttribute('id', descId);
+    descElement.textContent = config.description;
+    this.svgElement.appendChild(descElement);
+    ariaLabel += ' ' + descId;
+  }
+  if (ariaLabel) {
+    this.svgElement.setAttribute('aria-labelledby', ariaLabel);
+  }
+  var defs = createNS('defs');
+  this.svgElement.appendChild(defs);
+  var maskElement = createNS('g');
+  this.svgElement.appendChild(maskElement);
+  this.layerElement = maskElement;
+  this.renderConfig = {
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    hideOnTransparent: !((config && config.hideOnTransparent === false)),
+    viewBoxOnly: (config && config.viewBoxOnly) || false,
+    viewBoxSize: (config && config.viewBoxSize) || false,
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    focusable: config && config.focusable,
+    filterSize: {
+      width: (config && config.filterSize && config.filterSize.width) || '100%',
+      height: (config && config.filterSize && config.filterSize.height) || '100%',
+      x: (config && config.filterSize && config.filterSize.x) || '0%',
+      y: (config && config.filterSize && config.filterSize.y) || '0%',
+    },
+    width: (config && config.width),
+    height: (config && config.height),
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+
+  this.globalData = {
+    _mdf: false,
+    frameNum: -1,
+    defs: defs,
+    renderConfig: this.renderConfig,
+  };
+  this.elements = [];
+  this.pendingElements = [];
+  this.destroyed = false;
+  this.rendererType = 'svg';
+}
+
+extendPrototype([SVGRendererBase], SVGRenderer);
+
+SVGRenderer.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function ShapeTransformManager() {
+  this.sequences = {};
+  this.sequenceList = [];
+  this.transform_key_count = 0;
+}
+
+ShapeTransformManager.prototype = {
+  addTransformSequence: function (transforms) {
+    var i;
+    var len = transforms.length;
+    var key = '_';
+    for (i = 0; i < len; i += 1) {
+      key += transforms[i].transform.key + '_';
+    }
+    var sequence = this.sequences[key];
+    if (!sequence) {
+      sequence = {
+        transforms: [].concat(transforms),
+        finalTransform: new Matrix(),
+        _mdf: false,
+      };
+      this.sequences[key] = sequence;
+      this.sequenceList.push(sequence);
+    }
+    return sequence;
+  },
+  processSequence: function (sequence, isFirstFrame) {
+    var i = 0;
+    var len = sequence.transforms.length;
+    var _mdf = isFirstFrame;
+    while (i < len && !isFirstFrame) {
+      if (sequence.transforms[i].transform.mProps._mdf) {
+        _mdf = true;
+        break;
+      }
+      i += 1;
+    }
+    if (_mdf) {
+      sequence.finalTransform.reset();
+      for (i = len - 1; i >= 0; i -= 1) {
+        sequence.finalTransform.multiply(sequence.transforms[i].transform.mProps.v);
+      }
+    }
+    sequence._mdf = _mdf;
+  },
+  processSequences: function (isFirstFrame) {
+    var i;
+    var len = this.sequenceList.length;
+    for (i = 0; i < len; i += 1) {
+      this.processSequence(this.sequenceList[i], isFirstFrame);
+    }
+  },
+  getNewKey: function () {
+    this.transform_key_count += 1;
+    return '_' + this.transform_key_count;
+  },
+};
+
+var lumaLoader = (function () {
+  var id = '__lottie_element_luma_buffer';
+  var lumaBuffer = null;
+  var lumaBufferCtx = null;
+  var svg = null;
+
+  // This alternate solution has a slight delay before the filter is applied, resulting in a flicker on the first frame.
+  // Keeping this here for reference, and in the future, if offscreen canvas supports url filters, this can be used.
+  // For now, neither of them work for offscreen canvas, so canvas workers can't support the luma track matte mask.
+  // Naming it solution 2 to mark the extra comment lines.
+  /*
+  var svgString = [
+    '<svg xmlns="http://www.w3.org/2000/svg">',
+    '<filter id="' + id + '">',
+    '<feColorMatrix type="matrix" color-interpolation-filters="sRGB" values="',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0',
+    '"/>',
+    '</filter>',
+    '</svg>',
+  ].join('');
+  var blob = new Blob([svgString], { type: 'image/svg+xml' });
+  var url = URL.createObjectURL(blob);
+  */
+
+  function createLumaSvgFilter() {
+    var _svg = createNS('svg');
+    var fil = createNS('filter');
+    var matrix = createNS('feColorMatrix');
+    fil.setAttribute('id', id);
+    matrix.setAttribute('type', 'matrix');
+    matrix.setAttribute('color-interpolation-filters', 'sRGB');
+    matrix.setAttribute('values', '0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0');
+    fil.appendChild(matrix);
+    _svg.appendChild(fil);
+    _svg.setAttribute('id', id + '_svg');
+    if (featureSupport.svgLumaHidden) {
+      _svg.style.display = 'none';
+    }
+    return _svg;
+  }
+
+  function loadLuma() {
+    if (!lumaBuffer) {
+      svg = createLumaSvgFilter();
+      document.body.appendChild(svg);
+      lumaBuffer = createTag('canvas');
+      lumaBufferCtx = lumaBuffer.getContext('2d');
+      // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
+      lumaBufferCtx.filter = 'url(#' + id + ')';
+      lumaBufferCtx.fillStyle = 'rgba(0,0,0,0)';
+      lumaBufferCtx.fillRect(0, 0, 1, 1);
+    }
+  }
+
+  function getLuma(canvas) {
+    if (!lumaBuffer) {
+      loadLuma();
+    }
+    lumaBuffer.width = canvas.width;
+    lumaBuffer.height = canvas.height;
+    // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
+    lumaBufferCtx.filter = 'url(#' + id + ')';
+    return lumaBuffer;
+  }
+  return {
+    load: loadLuma,
+    get: getLuma,
+  };
+});
+
+function createCanvas(width, height) {
+  if (featureSupport.offscreenCanvas) {
+    return new OffscreenCanvas(width, height);
+  }
+  var canvas = createTag('canvas');
+  canvas.width = width;
+  canvas.height = height;
+  return canvas;
+}
+
+const assetLoader = (function () {
+  return {
+    loadLumaCanvas: lumaLoader.load,
+    getLumaCanvas: lumaLoader.get,
+    createCanvas: createCanvas,
+  };
+}());
+
+var registeredEffects = {};
+
+function CVEffects(elem) {
+  var i;
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects[type]) {
+      var Effect = registeredEffects[type].effect;
+      filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+CVEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+CVEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect(id, effect) {
+  registeredEffects[id] = {
+    effect,
+  };
+}
+
+function CVMaskElement(data, element) {
+  this.data = data;
+  this.element = element;
+  this.masksProperties = this.data.masksProperties || [];
+  this.viewData = createSizedArray(this.masksProperties.length);
+  var i;
+  var len = this.masksProperties.length;
+  var hasMasks = false;
+  for (i = 0; i < len; i += 1) {
+    if (this.masksProperties[i].mode !== 'n') {
+      hasMasks = true;
+    }
+    this.viewData[i] = ShapePropertyFactory.getShapeProp(this.element, this.masksProperties[i], 3);
+  }
+  this.hasMasks = hasMasks;
+  if (hasMasks) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+CVMaskElement.prototype.renderFrame = function () {
+  if (!this.hasMasks) {
+    return;
+  }
+  var transform = this.element.finalTransform.mat;
+  var ctx = this.element.canvasContext;
+  var i;
+  var len = this.masksProperties.length;
+  var pt;
+  var pts;
+  var data;
+  ctx.beginPath();
+  for (i = 0; i < len; i += 1) {
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.masksProperties[i].inv) {
+        ctx.moveTo(0, 0);
+        ctx.lineTo(this.element.globalData.compSize.w, 0);
+        ctx.lineTo(this.element.globalData.compSize.w, this.element.globalData.compSize.h);
+        ctx.lineTo(0, this.element.globalData.compSize.h);
+        ctx.lineTo(0, 0);
+      }
+      data = this.viewData[i].v;
+      pt = transform.applyToPointArray(data.v[0][0], data.v[0][1], 0);
+      ctx.moveTo(pt[0], pt[1]);
+      var j;
+      var jLen = data._length;
+      for (j = 1; j < jLen; j += 1) {
+        pts = transform.applyToTriplePoints(data.o[j - 1], data.i[j], data.v[j]);
+        ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
+      }
+      pts = transform.applyToTriplePoints(data.o[j - 1], data.i[0], data.v[0]);
+      ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
+    }
+  }
+  this.element.globalData.renderer.save(true);
+  ctx.clip();
+};
+
+CVMaskElement.prototype.getMaskProperty = MaskElement.prototype.getMaskProperty;
+
+CVMaskElement.prototype.destroy = function () {
+  this.element = null;
+};
+
+function CVBaseElement() {
+}
+
+var operationsMap = {
+  1: 'source-in',
+  2: 'source-out',
+  3: 'source-in',
+  4: 'source-out',
+};
+
+CVBaseElement.prototype = {
+  createElements: function () {},
+  initRendererElement: function () {},
+  createContainerElements: function () {
+    // If the layer is masked we will use two buffers to store each different states of the drawing
+    // This solution is not ideal for several reason. But unfortunately, because of the recursive
+    // nature of the render tree, it's the only simple way to make sure one inner mask doesn't override an outer mask.
+    // TODO: try to reduce the size of these buffers to the size of the composition contaning the layer
+    // It might be challenging because the layer most likely is transformed in some way
+    if (this.data.tt >= 1) {
+      this.buffers = [];
+      var canvasContext = this.globalData.canvasContext;
+      var bufferCanvas = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
+      this.buffers.push(bufferCanvas);
+      var bufferCanvas2 = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
+      this.buffers.push(bufferCanvas2);
+      if (this.data.tt >= 3 && !document._isProxy) {
+        assetLoader.loadLumaCanvas();
+      }
+    }
+    this.canvasContext = this.globalData.canvasContext;
+    this.transformCanvas = this.globalData.transformCanvas;
+    this.renderableEffectsManager = new CVEffects(this);
+    this.searchEffectTransforms();
+  },
+  createContent: function () {},
+  setBlendMode: function () {
+    var globalData = this.globalData;
+    if (globalData.blendMode !== this.data.bm) {
+      globalData.blendMode = this.data.bm;
+      var blendModeValue = getBlendMode(this.data.bm);
+      globalData.canvasContext.globalCompositeOperation = blendModeValue;
+    }
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new CVMaskElement(this.data, this);
+    this.transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+  },
+  hideElement: function () {
+    if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+      this.hidden = true;
+    }
+  },
+  showElement: function () {
+    if (this.isInRange && !this.isTransparent) {
+      this.hidden = false;
+      this._isFirstFrame = true;
+      this.maskManager._isFirstFrame = true;
+    }
+  },
+  clearCanvas: function (canvasContext) {
+    canvasContext.clearRect(
+      this.transformCanvas.tx,
+      this.transformCanvas.ty,
+      this.transformCanvas.w * this.transformCanvas.sx,
+      this.transformCanvas.h * this.transformCanvas.sy
+    );
+  },
+  prepareLayer: function () {
+    if (this.data.tt >= 1) {
+      var buffer = this.buffers[0];
+      var bufferCtx = buffer.getContext('2d');
+      this.clearCanvas(bufferCtx);
+      // on the first buffer we store the current state of the global drawing
+      bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+      // The next four lines are to clear the canvas
+      // TODO: Check if there is a way to clear the canvas without resetting the transform
+      this.currentTransform = this.canvasContext.getTransform();
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+      this.clearCanvas(this.canvasContext);
+      this.canvasContext.setTransform(this.currentTransform);
+    }
+  },
+  exitLayer: function () {
+    if (this.data.tt >= 1) {
+      var buffer = this.buffers[1];
+      // On the second buffer we store the current state of the global drawing
+      // that only contains the content of this layer
+      // (if it is a composition, it also includes the nested layers)
+      var bufferCtx = buffer.getContext('2d');
+      this.clearCanvas(bufferCtx);
+      bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+      // We clear the canvas again
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+      this.clearCanvas(this.canvasContext);
+      this.canvasContext.setTransform(this.currentTransform);
+      // We draw the mask
+      const mask = this.comp.getElementById('tp' in this.data ? this.data.tp : this.data.ind - 1);
+      mask.renderFrame(true);
+      // We draw the second buffer (that contains the content of this layer)
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+
+      // If the mask is a Luma matte, we need to do two extra painting operations
+      // the _isProxy check is to avoid drawing a fake canvas in workers that will throw an error
+      if (this.data.tt >= 3 && !document._isProxy) {
+        // We copy the painted mask to a buffer that has a color matrix filter applied to it
+        // that applies the rgb values to the alpha channel
+        var lumaBuffer = assetLoader.getLumaCanvas(this.canvasContext.canvas);
+        var lumaBufferCtx = lumaBuffer.getContext('2d');
+        lumaBufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+        this.clearCanvas(this.canvasContext);
+        // we repaint the context with the mask applied to it
+        this.canvasContext.drawImage(lumaBuffer, 0, 0);
+      }
+      this.canvasContext.globalCompositeOperation = operationsMap[this.data.tt];
+      this.canvasContext.drawImage(buffer, 0, 0);
+      // We finally draw the first buffer (that contains the content of the global drawing)
+      // We use destination-over to draw the global drawing below the current layer
+      this.canvasContext.globalCompositeOperation = 'destination-over';
+      this.canvasContext.drawImage(this.buffers[0], 0, 0);
+      this.canvasContext.setTransform(this.currentTransform);
+      // We reset the globalCompositeOperation to source-over, the standard type of operation
+      this.canvasContext.globalCompositeOperation = 'source-over';
+    }
+  },
+  renderFrame: function (forceRender) {
+    if (this.hidden || this.data.hd) {
+      return;
+    }
+    if (this.data.td === 1 && !forceRender) {
+      return;
+    }
+    this.renderTransform();
+    this.renderRenderable();
+    this.renderLocalTransform();
+    this.setBlendMode();
+    var forceRealStack = this.data.ty === 0;
+    this.prepareLayer();
+    this.globalData.renderer.save(forceRealStack);
+    this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props);
+    this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity);
+    this.renderInnerContent();
+    this.globalData.renderer.restore(forceRealStack);
+    this.exitLayer();
+    if (this.maskManager.hasMasks) {
+      this.globalData.renderer.restore(true);
+    }
+    if (this._isFirstFrame) {
+      this._isFirstFrame = false;
+    }
+  },
+  destroy: function () {
+    this.canvasContext = null;
+    this.data = null;
+    this.globalData = null;
+    this.maskManager.destroy();
+  },
+  mHelper: new Matrix(),
+};
+CVBaseElement.prototype.hide = CVBaseElement.prototype.hideElement;
+CVBaseElement.prototype.show = CVBaseElement.prototype.showElement;
+
+function CVShapeData(element, data, styles, transformsManager) {
+  this.styledShapes = [];
+  this.tr = [0, 0, 0, 0, 0, 0];
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  this.sh = ShapePropertyFactory.getShapeProp(element, data, ty, element);
+  var i;
+  var len = styles.length;
+  var styledShape;
+  for (i = 0; i < len; i += 1) {
+    if (!styles[i].closed) {
+      styledShape = {
+        transforms: transformsManager.addTransformSequence(styles[i].transforms),
+        trNodes: [],
+      };
+      this.styledShapes.push(styledShape);
+      styles[i].elements.push(styledShape);
+    }
+  }
+}
+
+CVShapeData.prototype.setAsAnimated = SVGShapeData.prototype.setAsAnimated;
+
+function CVShapeElement(data, globalData, comp) {
+  this.shapes = [];
+  this.shapesData = data.shapes;
+  this.stylesList = [];
+  this.itemsData = [];
+  this.prevViewData = [];
+  this.shapeModifiers = [];
+  this.processedElements = [];
+  this.transformsManager = new ShapeTransformManager();
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, CVBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableElement], CVShapeElement);
+
+CVShapeElement.prototype.initElement = RenderableDOMElement.prototype.initElement;
+
+CVShapeElement.prototype.transformHelper = { opacity: 1, _opMdf: false };
+
+CVShapeElement.prototype.dashResetter = [];
+
+CVShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
+};
+
+CVShapeElement.prototype.createStyleElement = function (data, transforms) {
+  var styleElem = {
+    data: data,
+    type: data.ty,
+    preTransforms: this.transformsManager.addTransformSequence(transforms),
+    transforms: [],
+    elements: [],
+    closed: data.hd === true,
+  };
+  var elementData = {};
+  if (data.ty === 'fl' || data.ty === 'st') {
+    elementData.c = PropertyFactory.getProp(this, data.c, 1, 255, this);
+    if (!elementData.c.k) {
+      styleElem.co = 'rgb(' + bmFloor(elementData.c.v[0]) + ',' + bmFloor(elementData.c.v[1]) + ',' + bmFloor(elementData.c.v[2]) + ')';
+    }
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    elementData.s = PropertyFactory.getProp(this, data.s, 1, null, this);
+    elementData.e = PropertyFactory.getProp(this, data.e, 1, null, this);
+    elementData.h = PropertyFactory.getProp(this, data.h || { k: 0 }, 0, 0.01, this);
+    elementData.a = PropertyFactory.getProp(this, data.a || { k: 0 }, 0, degToRads, this);
+    elementData.g = new GradientProperty(this, data.g, this);
+  }
+  elementData.o = PropertyFactory.getProp(this, data.o, 0, 0.01, this);
+  if (data.ty === 'st' || data.ty === 'gs') {
+    styleElem.lc = lineCapEnum[data.lc || 2];
+    styleElem.lj = lineJoinEnum[data.lj || 2];
+    if (data.lj == 1) { // eslint-disable-line eqeqeq
+      styleElem.ml = data.ml;
+    }
+    elementData.w = PropertyFactory.getProp(this, data.w, 0, null, this);
+    if (!elementData.w.k) {
+      styleElem.wi = elementData.w.v;
+    }
+    if (data.d) {
+      var d = new DashProperty(this, data.d, 'canvas', this);
+      elementData.d = d;
+      if (!elementData.d.k) {
+        styleElem.da = elementData.d.dashArray;
+        styleElem.do = elementData.d.dashoffset[0];
+      }
+    }
+  } else {
+    styleElem.r = data.r === 2 ? 'evenodd' : 'nonzero';
+  }
+  this.stylesList.push(styleElem);
+  elementData.style = styleElem;
+  return elementData;
+};
+
+CVShapeElement.prototype.createGroupElement = function () {
+  var elementData = {
+    it: [],
+    prevViewData: [],
+  };
+  return elementData;
+};
+
+CVShapeElement.prototype.createTransformElement = function (data) {
+  var elementData = {
+    transform: {
+      opacity: 1,
+      _opMdf: false,
+      key: this.transformsManager.getNewKey(),
+      op: PropertyFactory.getProp(this, data.o, 0, 0.01, this),
+      mProps: TransformPropertyFactory.getTransformProperty(this, data, this),
+    },
+  };
+  return elementData;
+};
+
+CVShapeElement.prototype.createShapeElement = function (data) {
+  var elementData = new CVShapeData(this, data, this.stylesList, this.transformsManager);
+
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  return elementData;
+};
+
+CVShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+  this.transformsManager.processSequences(this._isFirstFrame);
+};
+
+CVShapeElement.prototype.addTransformToStyleList = function (transform) {
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    if (!this.stylesList[i].closed) {
+      this.stylesList[i].transforms.push(transform);
+    }
+  }
+};
+
+CVShapeElement.prototype.removeTransformFromStyleList = function () {
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    if (!this.stylesList[i].closed) {
+      this.stylesList[i].transforms.pop();
+    }
+  }
+};
+
+CVShapeElement.prototype.closeStyles = function (styles) {
+  var i;
+  var len = styles.length;
+  for (i = 0; i < len; i += 1) {
+    styles[i].closed = true;
+  }
+};
+
+CVShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, shouldRender, transforms) {
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var processedPos;
+  var modifier;
+  var currentTransform;
+  var ownTransforms = [].concat(transforms);
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._shouldRender = shouldRender;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], ownTransforms);
+      } else {
+        itemsData[i].style.closed = false;
+      }
+
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, shouldRender, ownTransforms);
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        currentTransform = this.createTransformElement(arr[i]);
+        itemsData[i] = currentTransform;
+      }
+      ownTransforms.push(itemsData[i]);
+      this.addTransformToStyleList(itemsData[i]);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i]);
+      }
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        shouldRender = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  this.removeTransformFromStyleList();
+  this.closeStyles(ownStyles);
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+CVShapeElement.prototype.renderInnerContent = function () {
+  this.transformHelper.opacity = 1;
+  this.transformHelper._opMdf = false;
+  this.renderModifiers();
+  this.transformsManager.processSequences(this._isFirstFrame);
+  this.renderShape(this.transformHelper, this.shapesData, this.itemsData, true);
+};
+
+CVShapeElement.prototype.renderShapeTransform = function (parentTransform, groupTransform) {
+  if (parentTransform._opMdf || groupTransform.op._mdf || this._isFirstFrame) {
+    groupTransform.opacity = parentTransform.opacity;
+    groupTransform.opacity *= groupTransform.op.v;
+    groupTransform._opMdf = true;
+  }
+};
+
+CVShapeElement.prototype.drawLayer = function () {
+  var i;
+  var len = this.stylesList.length;
+  var j;
+  var jLen;
+  var k;
+  var kLen;
+  var elems;
+  var nodes;
+  var renderer = this.globalData.renderer;
+  var ctx = this.globalData.canvasContext;
+  var type;
+  var currentStyle;
+  for (i = 0; i < len; i += 1) {
+    currentStyle = this.stylesList[i];
+    type = currentStyle.type;
+
+    // Skipping style when
+    // Stroke width equals 0
+    // style should not be rendered (extra unused repeaters)
+    // current opacity equals 0
+    // global opacity equals 0
+    if (!(((type === 'st' || type === 'gs') && currentStyle.wi === 0) || !currentStyle.data._shouldRender || currentStyle.coOp === 0 || this.globalData.currentGlobalAlpha === 0)) {
+      renderer.save();
+      elems = currentStyle.elements;
+      if (type === 'st' || type === 'gs') {
+        renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd);
+        // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
+        renderer.ctxLineWidth(currentStyle.wi);
+        // ctx.lineWidth = currentStyle.wi;
+        renderer.ctxLineCap(currentStyle.lc);
+        // ctx.lineCap = currentStyle.lc;
+        renderer.ctxLineJoin(currentStyle.lj);
+        // ctx.lineJoin = currentStyle.lj;
+        renderer.ctxMiterLimit(currentStyle.ml || 0);
+        // ctx.miterLimit = currentStyle.ml || 0;
+      } else {
+        renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd);
+        // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
+      }
+      renderer.ctxOpacity(currentStyle.coOp);
+      if (type !== 'st' && type !== 'gs') {
+        ctx.beginPath();
+      }
+      renderer.ctxTransform(currentStyle.preTransforms.finalTransform.props);
+      jLen = elems.length;
+      for (j = 0; j < jLen; j += 1) {
+        if (type === 'st' || type === 'gs') {
+          ctx.beginPath();
+          if (currentStyle.da) {
+            ctx.setLineDash(currentStyle.da);
+            ctx.lineDashOffset = currentStyle.do;
+          }
+        }
+        nodes = elems[j].trNodes;
+        kLen = nodes.length;
+
+        for (k = 0; k < kLen; k += 1) {
+          if (nodes[k].t === 'm') {
+            ctx.moveTo(nodes[k].p[0], nodes[k].p[1]);
+          } else if (nodes[k].t === 'c') {
+            ctx.bezierCurveTo(nodes[k].pts[0], nodes[k].pts[1], nodes[k].pts[2], nodes[k].pts[3], nodes[k].pts[4], nodes[k].pts[5]);
+          } else {
+            ctx.closePath();
+          }
+        }
+        if (type === 'st' || type === 'gs') {
+          // ctx.stroke();
+          renderer.ctxStroke();
+          if (currentStyle.da) {
+            ctx.setLineDash(this.dashResetter);
+          }
+        }
+      }
+      if (type !== 'st' && type !== 'gs') {
+        // ctx.fill(currentStyle.r);
+        this.globalData.renderer.ctxFill(currentStyle.r);
+      }
+      renderer.restore();
+    }
+  }
+};
+
+CVShapeElement.prototype.renderShape = function (parentTransform, items, data, isMain) {
+  var i;
+  var len = items.length - 1;
+  var groupTransform;
+  groupTransform = parentTransform;
+  for (i = len; i >= 0; i -= 1) {
+    if (items[i].ty === 'tr') {
+      groupTransform = data[i].transform;
+      this.renderShapeTransform(parentTransform, groupTransform);
+    } else if (items[i].ty === 'sh' || items[i].ty === 'el' || items[i].ty === 'rc' || items[i].ty === 'sr') {
+      this.renderPath(items[i], data[i]);
+    } else if (items[i].ty === 'fl') {
+      this.renderFill(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'st') {
+      this.renderStroke(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'gf' || items[i].ty === 'gs') {
+      this.renderGradientFill(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'gr') {
+      this.renderShape(groupTransform, items[i].it, data[i].it);
+    } else if (items[i].ty === 'tm') {
+      //
+    }
+  }
+  if (isMain) {
+    this.drawLayer();
+  }
+};
+
+CVShapeElement.prototype.renderStyledShape = function (styledShape, shape) {
+  if (this._isFirstFrame || shape._mdf || styledShape.transforms._mdf) {
+    var shapeNodes = styledShape.trNodes;
+    var paths = shape.paths;
+    var i;
+    var len;
+    var j;
+    var jLen = paths._length;
+    shapeNodes.length = 0;
+    var groupTransformMat = styledShape.transforms.finalTransform;
+    for (j = 0; j < jLen; j += 1) {
+      var pathNodes = paths.shapes[j];
+      if (pathNodes && pathNodes.v) {
+        len = pathNodes._length;
+        for (i = 1; i < len; i += 1) {
+          if (i === 1) {
+            shapeNodes.push({
+              t: 'm',
+              p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0),
+            });
+          }
+          shapeNodes.push({
+            t: 'c',
+            pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[i], pathNodes.v[i]),
+          });
+        }
+        if (len === 1) {
+          shapeNodes.push({
+            t: 'm',
+            p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0),
+          });
+        }
+        if (pathNodes.c && len) {
+          shapeNodes.push({
+            t: 'c',
+            pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[0], pathNodes.v[0]),
+          });
+          shapeNodes.push({
+            t: 'z',
+          });
+        }
+      }
+    }
+    styledShape.trNodes = shapeNodes;
+  }
+};
+
+CVShapeElement.prototype.renderPath = function (pathData, itemData) {
+  if (pathData.hd !== true && pathData._shouldRender) {
+    var i;
+    var len = itemData.styledShapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderStyledShape(itemData.styledShapes[i], itemData.sh);
+    }
+  }
+};
+
+CVShapeElement.prototype.renderFill = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+
+  if (itemData.c._mdf || this._isFirstFrame) {
+    styleElem.co = 'rgb('
+        + bmFloor(itemData.c.v[0]) + ','
+        + bmFloor(itemData.c.v[1]) + ','
+        + bmFloor(itemData.c.v[2]) + ')';
+  }
+  if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
+    styleElem.coOp = itemData.o.v * groupTransform.opacity;
+  }
+};
+
+CVShapeElement.prototype.renderGradientFill = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+  var grd;
+  if (!styleElem.grd || itemData.g._mdf || itemData.s._mdf || itemData.e._mdf || (styleData.t !== 1 && (itemData.h._mdf || itemData.a._mdf))) {
+    var ctx = this.globalData.canvasContext;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+    if (styleData.t === 1) {
+      grd = ctx.createLinearGradient(pt1[0], pt1[1], pt2[0], pt2[1]);
+    } else {
+      var rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+      var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+      var percent = itemData.h.v;
+      if (percent >= 1) {
+        percent = 0.99;
+      } else if (percent <= -1) {
+        percent = -0.99;
+      }
+      var dist = rad * percent;
+      var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+      var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+      grd = ctx.createRadialGradient(x, y, 0, pt1[0], pt1[1], rad);
+    }
+
+    var i;
+    var len = styleData.g.p;
+    var cValues = itemData.g.c;
+    var opacity = 1;
+
+    for (i = 0; i < len; i += 1) {
+      if (itemData.g._hasOpacity && itemData.g._collapsable) {
+        opacity = itemData.g.o[i * 2 + 1];
+      }
+      grd.addColorStop(cValues[i * 4] / 100, 'rgba(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ',' + opacity + ')');
+    }
+    styleElem.grd = grd;
+  }
+  styleElem.coOp = itemData.o.v * groupTransform.opacity;
+};
+
+CVShapeElement.prototype.renderStroke = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+  var d = itemData.d;
+  if (d && (d._mdf || this._isFirstFrame)) {
+    styleElem.da = d.dashArray;
+    styleElem.do = d.dashoffset[0];
+  }
+  if (itemData.c._mdf || this._isFirstFrame) {
+    styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
+  }
+  if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
+    styleElem.coOp = itemData.o.v * groupTransform.opacity;
+  }
+  if (itemData.w._mdf || this._isFirstFrame) {
+    styleElem.wi = itemData.w.v;
+  }
+};
+
+CVShapeElement.prototype.destroy = function () {
+  this.shapesData = null;
+  this.globalData = null;
+  this.canvasContext = null;
+  this.stylesList.length = 0;
+  this.itemsData.length = 0;
+};
+
+function CVTextElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.yOffset = 0;
+  this.fillColorAnim = false;
+  this.strokeColorAnim = false;
+  this.strokeWidthAnim = false;
+  this.stroke = false;
+  this.fill = false;
+  this.justifyOffset = 0;
+  this.currentRender = null;
+  this.renderType = 'canvas';
+  this.values = {
+    fill: 'rgba(0,0,0,0)',
+    stroke: 'rgba(0,0,0,0)',
+    sWidth: 0,
+    fValue: '',
+  };
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement, ITextElement], CVTextElement);
+
+CVTextElement.prototype.tHelper = createTag('canvas').getContext('2d');
+
+CVTextElement.prototype.buildNewText = function () {
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
+
+  var hasFill = false;
+  if (documentData.fc) {
+    hasFill = true;
+    this.values.fill = this.buildColor(documentData.fc);
+  } else {
+    this.values.fill = 'rgba(0,0,0,0)';
+  }
+  this.fill = hasFill;
+  var hasStroke = false;
+  if (documentData.sc) {
+    hasStroke = true;
+    this.values.stroke = this.buildColor(documentData.sc);
+    this.values.sWidth = documentData.sw;
+  }
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  var i;
+  var len;
+  var letters = documentData.l;
+  var matrixHelper = this.mHelper;
+  this.stroke = hasStroke;
+  this.values.fValue = documentData.finalSize + 'px ' + this.globalData.fontManager.getFontByName(documentData.f).fFamily;
+  len = documentData.finalText.length;
+  // this.tHelper.font = this.values.fValue;
+  var charData;
+  var shapeData;
+  var k;
+  var kLen;
+  var shapes;
+  var j;
+  var jLen;
+  var pathNodes;
+  var commands;
+  var pathArr;
+  var singleShape = this.data.singleShape;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var cnt = 0;
+  for (i = 0; i < len; i += 1) {
+    charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
+    shapeData = (charData && charData.data) || {};
+    matrixHelper.reset();
+    if (singleShape && letters[i].n) {
+      xPos = -trackingOffset;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      firstLine = false;
+    }
+    shapes = shapeData.shapes ? shapeData.shapes[0].it : [];
+    jLen = shapes.length;
+    matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
+    if (singleShape) {
+      this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+    }
+    commands = createSizedArray(jLen - 1);
+    var commandsCounter = 0;
+    for (j = 0; j < jLen; j += 1) {
+      if (shapes[j].ty === 'sh') {
+        kLen = shapes[j].ks.k.i.length;
+        pathNodes = shapes[j].ks.k;
+        pathArr = [];
+        for (k = 1; k < kLen; k += 1) {
+          if (k === 1) {
+            pathArr.push(matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
+          }
+          pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToY(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToX(pathNodes.v[k][0], pathNodes.v[k][1], 0), matrixHelper.applyToY(pathNodes.v[k][0], pathNodes.v[k][1], 0));
+        }
+        pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToY(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
+        commands[commandsCounter] = pathArr;
+        commandsCounter += 1;
+      }
+    }
+    if (singleShape) {
+      xPos += letters[i].l;
+      xPos += trackingOffset;
+    }
+    if (this.textSpans[cnt]) {
+      this.textSpans[cnt].elem = commands;
+    } else {
+      this.textSpans[cnt] = { elem: commands };
+    }
+    cnt += 1;
+  }
+};
+
+CVTextElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  var ctx = this.canvasContext;
+  ctx.font = this.values.fValue;
+  this.globalData.renderer.ctxLineCap('butt');
+  // ctx.lineCap = 'butt';
+  this.globalData.renderer.ctxLineJoin('miter');
+  // ctx.lineJoin = 'miter';
+  this.globalData.renderer.ctxMiterLimit(4);
+  // ctx.miterLimit = 4;
+
+  if (!this.data.singleShape) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+  }
+
+  var i;
+  var len;
+  var j;
+  var jLen;
+  var k;
+  var kLen;
+  var renderedLetters = this.textAnimator.renderedLetters;
+
+  var letters = this.textProperty.currentData.l;
+
+  len = letters.length;
+  var renderedLetter;
+  var lastFill = null;
+  var lastStroke = null;
+  var lastStrokeW = null;
+  var commands;
+  var pathArr;
+  var renderer = this.globalData.renderer;
+  for (i = 0; i < len; i += 1) {
+    if (!letters[i].n) {
+      renderedLetter = renderedLetters[i];
+      if (renderedLetter) {
+        renderer.save();
+        renderer.ctxTransform(renderedLetter.p);
+        renderer.ctxOpacity(renderedLetter.o);
+      }
+      if (this.fill) {
+        if (renderedLetter && renderedLetter.fc) {
+          if (lastFill !== renderedLetter.fc) {
+            renderer.ctxFillStyle(renderedLetter.fc);
+            lastFill = renderedLetter.fc;
+            // ctx.fillStyle = renderedLetter.fc;
+          }
+        } else if (lastFill !== this.values.fill) {
+          lastFill = this.values.fill;
+          renderer.ctxFillStyle(this.values.fill);
+          // ctx.fillStyle = this.values.fill;
+        }
+        commands = this.textSpans[i].elem;
+        jLen = commands.length;
+        this.globalData.canvasContext.beginPath();
+        for (j = 0; j < jLen; j += 1) {
+          pathArr = commands[j];
+          kLen = pathArr.length;
+          this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
+          for (k = 2; k < kLen; k += 6) {
+            this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
+          }
+        }
+        this.globalData.canvasContext.closePath();
+        renderer.ctxFill();
+        // this.globalData.canvasContext.fill();
+        /// ctx.fillText(this.textSpans[i].val,0,0);
+      }
+      if (this.stroke) {
+        if (renderedLetter && renderedLetter.sw) {
+          if (lastStrokeW !== renderedLetter.sw) {
+            lastStrokeW = renderedLetter.sw;
+            renderer.ctxLineWidth(renderedLetter.sw);
+            // ctx.lineWidth = renderedLetter.sw;
+          }
+        } else if (lastStrokeW !== this.values.sWidth) {
+          lastStrokeW = this.values.sWidth;
+          renderer.ctxLineWidth(this.values.sWidth);
+          // ctx.lineWidth = this.values.sWidth;
+        }
+        if (renderedLetter && renderedLetter.sc) {
+          if (lastStroke !== renderedLetter.sc) {
+            lastStroke = renderedLetter.sc;
+            renderer.ctxStrokeStyle(renderedLetter.sc);
+            // ctx.strokeStyle = renderedLetter.sc;
+          }
+        } else if (lastStroke !== this.values.stroke) {
+          lastStroke = this.values.stroke;
+          renderer.ctxStrokeStyle(this.values.stroke);
+          // ctx.strokeStyle = this.values.stroke;
+        }
+        commands = this.textSpans[i].elem;
+        jLen = commands.length;
+        this.globalData.canvasContext.beginPath();
+        for (j = 0; j < jLen; j += 1) {
+          pathArr = commands[j];
+          kLen = pathArr.length;
+          this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
+          for (k = 2; k < kLen; k += 6) {
+            this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
+          }
+        }
+        this.globalData.canvasContext.closePath();
+        renderer.ctxStroke();
+        // this.globalData.canvasContext.stroke();
+        /// ctx.strokeText(letters[i].val,0,0);
+      }
+      if (renderedLetter) {
+        this.globalData.renderer.restore();
+      }
+    }
+  }
+};
+
+function CVImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  this.img = globalData.imageLoader.getAsset(this.assetData);
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVImageElement);
+
+CVImageElement.prototype.initElement = SVGShapeElement.prototype.initElement;
+CVImageElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
+
+CVImageElement.prototype.createContent = function () {
+  if (this.img.width && (this.assetData.w !== this.img.width || this.assetData.h !== this.img.height)) {
+    var canvas = createTag('canvas');
+    canvas.width = this.assetData.w;
+    canvas.height = this.assetData.h;
+    var ctx = canvas.getContext('2d');
+
+    var imgW = this.img.width;
+    var imgH = this.img.height;
+    var imgRel = imgW / imgH;
+    var canvasRel = this.assetData.w / this.assetData.h;
+    var widthCrop;
+    var heightCrop;
+    var par = this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio;
+    if ((imgRel > canvasRel && par === 'xMidYMid slice') || (imgRel < canvasRel && par !== 'xMidYMid slice')) {
+      heightCrop = imgH;
+      widthCrop = heightCrop * canvasRel;
+    } else {
+      widthCrop = imgW;
+      heightCrop = widthCrop / canvasRel;
+    }
+    ctx.drawImage(this.img, (imgW - widthCrop) / 2, (imgH - heightCrop) / 2, widthCrop, heightCrop, 0, 0, this.assetData.w, this.assetData.h);
+    this.img = canvas;
+  }
+};
+
+CVImageElement.prototype.renderInnerContent = function () {
+  this.canvasContext.drawImage(this.img, 0, 0);
+};
+
+CVImageElement.prototype.destroy = function () {
+  this.img = null;
+};
+
+function CVSolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVSolidElement);
+
+CVSolidElement.prototype.initElement = SVGShapeElement.prototype.initElement;
+CVSolidElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
+
+CVSolidElement.prototype.renderInnerContent = function () {
+  // var ctx = this.canvasContext;
+  this.globalData.renderer.ctxFillStyle(this.data.sc);
+  // ctx.fillStyle = this.data.sc;
+  this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh);
+  // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
+  //
+};
+
+function CanvasRendererBase() {
+}
+extendPrototype([BaseRenderer], CanvasRendererBase);
+
+CanvasRendererBase.prototype.createShape = function (data) {
+  return new CVShapeElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createText = function (data) {
+  return new CVTextElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createImage = function (data) {
+  return new CVImageElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createSolid = function (data) {
+  return new CVSolidElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
+
+CanvasRendererBase.prototype.ctxTransform = function (props) {
+  if (props[0] === 1 && props[1] === 0 && props[4] === 0 && props[5] === 1 && props[12] === 0 && props[13] === 0) {
+    return;
+  }
+  this.canvasContext.transform(props[0], props[1], props[4], props[5], props[12], props[13]);
+};
+
+CanvasRendererBase.prototype.ctxOpacity = function (op) {
+  this.canvasContext.globalAlpha *= op < 0 ? 0 : op;
+};
+
+CanvasRendererBase.prototype.ctxFillStyle = function (value) {
+  this.canvasContext.fillStyle = value;
+};
+
+CanvasRendererBase.prototype.ctxStrokeStyle = function (value) {
+  this.canvasContext.strokeStyle = value;
+};
+
+CanvasRendererBase.prototype.ctxLineWidth = function (value) {
+  this.canvasContext.lineWidth = value;
+};
+
+CanvasRendererBase.prototype.ctxLineCap = function (value) {
+  this.canvasContext.lineCap = value;
+};
+
+CanvasRendererBase.prototype.ctxLineJoin = function (value) {
+  this.canvasContext.lineJoin = value;
+};
+
+CanvasRendererBase.prototype.ctxMiterLimit = function (value) {
+  this.canvasContext.miterLimit = value;
+};
+
+CanvasRendererBase.prototype.ctxFill = function (rule) {
+  this.canvasContext.fill(rule);
+};
+
+CanvasRendererBase.prototype.ctxFillRect = function (x, y, w, h) {
+  this.canvasContext.fillRect(x, y, w, h);
+};
+
+CanvasRendererBase.prototype.ctxStroke = function () {
+  this.canvasContext.stroke();
+};
+
+CanvasRendererBase.prototype.reset = function () {
+  if (!this.renderConfig.clearCanvas) {
+    this.canvasContext.restore();
+    return;
+  }
+  this.contextData.reset();
+};
+
+CanvasRendererBase.prototype.save = function () {
+  this.canvasContext.save();
+};
+
+CanvasRendererBase.prototype.restore = function (actionFlag) {
+  if (!this.renderConfig.clearCanvas) {
+    this.canvasContext.restore();
+    return;
+  }
+  if (actionFlag) {
+    this.globalData.blendMode = 'source-over';
+  }
+  this.contextData.restore(actionFlag);
+};
+
+CanvasRendererBase.prototype.configAnimation = function (animData) {
+  if (this.animationItem.wrapper) {
+    this.animationItem.container = createTag('canvas');
+    var containerStyle = this.animationItem.container.style;
+    containerStyle.width = '100%';
+    containerStyle.height = '100%';
+    var origin = '0px 0px 0px';
+    containerStyle.transformOrigin = origin;
+    containerStyle.mozTransformOrigin = origin;
+    containerStyle.webkitTransformOrigin = origin;
+    containerStyle['-webkit-transform'] = origin;
+    containerStyle.contentVisibility = this.renderConfig.contentVisibility;
+    this.animationItem.wrapper.appendChild(this.animationItem.container);
+    this.canvasContext = this.animationItem.container.getContext('2d');
+    if (this.renderConfig.className) {
+      this.animationItem.container.setAttribute('class', this.renderConfig.className);
+    }
+    if (this.renderConfig.id) {
+      this.animationItem.container.setAttribute('id', this.renderConfig.id);
+    }
+  } else {
+    this.canvasContext = this.renderConfig.context;
+  }
+  this.contextData.setContext(this.canvasContext);
+  this.data = animData;
+  this.layers = animData.layers;
+  this.transformCanvas = {
+    w: animData.w,
+    h: animData.h,
+    sx: 0,
+    sy: 0,
+    tx: 0,
+    ty: 0,
+  };
+  this.setupGlobalData(animData, document.body);
+  this.globalData.canvasContext = this.canvasContext;
+  this.globalData.renderer = this;
+  this.globalData.isDashed = false;
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.globalData.transformCanvas = this.transformCanvas;
+  this.elements = createSizedArray(animData.layers.length);
+
+  this.updateContainerSize();
+};
+
+CanvasRendererBase.prototype.updateContainerSize = function (width, height) {
+  this.reset();
+  var elementWidth;
+  var elementHeight;
+  if (width) {
+    elementWidth = width;
+    elementHeight = height;
+    this.canvasContext.canvas.width = elementWidth;
+    this.canvasContext.canvas.height = elementHeight;
+  } else {
+    if (this.animationItem.wrapper && this.animationItem.container) {
+      elementWidth = this.animationItem.wrapper.offsetWidth;
+      elementHeight = this.animationItem.wrapper.offsetHeight;
+    } else {
+      elementWidth = this.canvasContext.canvas.width;
+      elementHeight = this.canvasContext.canvas.height;
+    }
+    this.canvasContext.canvas.width = elementWidth * this.renderConfig.dpr;
+    this.canvasContext.canvas.height = elementHeight * this.renderConfig.dpr;
+  }
+
+  var elementRel;
+  var animationRel;
+  if (this.renderConfig.preserveAspectRatio.indexOf('meet') !== -1 || this.renderConfig.preserveAspectRatio.indexOf('slice') !== -1) {
+    var par = this.renderConfig.preserveAspectRatio.split(' ');
+    var fillType = par[1] || 'meet';
+    var pos = par[0] || 'xMidYMid';
+    var xPos = pos.substr(0, 4);
+    var yPos = pos.substr(4);
+    elementRel = elementWidth / elementHeight;
+    animationRel = this.transformCanvas.w / this.transformCanvas.h;
+    if ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice')) {
+      this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+      this.transformCanvas.sy = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+    } else {
+      this.transformCanvas.sx = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+      this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+    }
+
+    if (xPos === 'xMid' && ((animationRel < elementRel && fillType === 'meet') || (animationRel > elementRel && fillType === 'slice'))) {
+      this.transformCanvas.tx = ((elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) / 2) * this.renderConfig.dpr;
+    } else if (xPos === 'xMax' && ((animationRel < elementRel && fillType === 'meet') || (animationRel > elementRel && fillType === 'slice'))) {
+      this.transformCanvas.tx = (elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) * this.renderConfig.dpr;
+    } else {
+      this.transformCanvas.tx = 0;
+    }
+    if (yPos === 'YMid' && ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice'))) {
+      this.transformCanvas.ty = ((elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w)) / 2) * this.renderConfig.dpr;
+    } else if (yPos === 'YMax' && ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice'))) {
+      this.transformCanvas.ty = ((elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w))) * this.renderConfig.dpr;
+    } else {
+      this.transformCanvas.ty = 0;
+    }
+  } else if (this.renderConfig.preserveAspectRatio === 'none') {
+    this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+    this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+    this.transformCanvas.tx = 0;
+    this.transformCanvas.ty = 0;
+  } else {
+    this.transformCanvas.sx = this.renderConfig.dpr;
+    this.transformCanvas.sy = this.renderConfig.dpr;
+    this.transformCanvas.tx = 0;
+    this.transformCanvas.ty = 0;
+  }
+  this.transformCanvas.props = [this.transformCanvas.sx, 0, 0, 0, 0, this.transformCanvas.sy, 0, 0, 0, 0, 1, 0, this.transformCanvas.tx, this.transformCanvas.ty, 0, 1];
+  /* var i, len = this.elements.length;
+    for(i=0;i<len;i+=1){
+        if(this.elements[i] && this.elements[i].data.ty === 0){
+            this.elements[i].resize(this.globalData.transformCanvas);
+        }
+    } */
+  this.ctxTransform(this.transformCanvas.props);
+  this.canvasContext.beginPath();
+  this.canvasContext.rect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
+  this.canvasContext.closePath();
+  this.canvasContext.clip();
+
+  this.renderFrame(this.renderedFrame, true);
+};
+
+CanvasRendererBase.prototype.destroy = function () {
+  if (this.renderConfig.clearCanvas && this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.globalData.canvasContext = null;
+  this.animationItem.container = null;
+  this.destroyed = true;
+};
+
+CanvasRendererBase.prototype.renderFrame = function (num, forceRender) {
+  if ((this.renderedFrame === num && this.renderConfig.clearCanvas === true && !forceRender) || this.destroyed || num === -1) {
+    return;
+  }
+  this.renderedFrame = num;
+  this.globalData.frameNum = num - this.animationItem._isFirstFrame;
+  this.globalData.frameId += 1;
+  this.globalData._mdf = !this.renderConfig.clearCanvas || forceRender;
+  this.globalData.projectInterface.currentFrame = num;
+
+  // console.log('--------');
+  // console.log('NEW: ',num);
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    if (this.renderConfig.clearCanvas === true) {
+      this.canvasContext.clearRect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
+    } else {
+      this.save();
+    }
+    for (i = len - 1; i >= 0; i -= 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+    if (this.renderConfig.clearCanvas !== true) {
+      this.restore();
+    }
+  }
+};
+
+CanvasRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  var element = this.createItem(this.layers[pos], this, this.globalData);
+  elements[pos] = element;
+  element.initExpressions();
+  /* if(this.layers[pos].ty === 0){
+        element.resize(this.globalData.transformCanvas);
+    } */
+};
+
+CanvasRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+  }
+};
+
+CanvasRendererBase.prototype.hide = function () {
+  this.animationItem.container.style.display = 'none';
+};
+
+CanvasRendererBase.prototype.show = function () {
+  this.animationItem.container.style.display = 'block';
+};
+
+function CanvasContext() {
+  this.opacity = -1;
+  this.transform = createTypedArray('float32', 16);
+  this.fillStyle = '';
+  this.strokeStyle = '';
+  this.lineWidth = '';
+  this.lineCap = '';
+  this.lineJoin = '';
+  this.miterLimit = '';
+  this.id = Math.random();
+}
+
+function CVContextData() {
+  this.stack = [];
+  this.cArrPos = 0;
+  this.cTr = new Matrix();
+  var i;
+  var len = 15;
+  for (i = 0; i < len; i += 1) {
+    var canvasContext = new CanvasContext();
+    this.stack[i] = canvasContext;
+  }
+  this._length = len;
+  this.nativeContext = null;
+  this.transformMat = new Matrix();
+  this.currentOpacity = 1;
+  //
+  this.currentFillStyle = '';
+  this.appliedFillStyle = '';
+  //
+  this.currentStrokeStyle = '';
+  this.appliedStrokeStyle = '';
+  //
+  this.currentLineWidth = '';
+  this.appliedLineWidth = '';
+  //
+  this.currentLineCap = '';
+  this.appliedLineCap = '';
+  //
+  this.currentLineJoin = '';
+  this.appliedLineJoin = '';
+  //
+  this.appliedMiterLimit = '';
+  this.currentMiterLimit = '';
+}
+
+CVContextData.prototype.duplicate = function () {
+  var newLength = this._length * 2;
+  var i = 0;
+  for (i = this._length; i < newLength; i += 1) {
+    this.stack[i] = new CanvasContext();
+  }
+  this._length = newLength;
+};
+
+CVContextData.prototype.reset = function () {
+  this.cArrPos = 0;
+  this.cTr.reset();
+  this.stack[this.cArrPos].opacity = 1;
+};
+
+CVContextData.prototype.restore = function (forceRestore) {
+  this.cArrPos -= 1;
+  var currentContext = this.stack[this.cArrPos];
+  var transform = currentContext.transform;
+  var i;
+  var arr = this.cTr.props;
+  for (i = 0; i < 16; i += 1) {
+    arr[i] = transform[i];
+  }
+  if (forceRestore) {
+    this.nativeContext.restore();
+    var prevStack = this.stack[this.cArrPos + 1];
+    this.appliedFillStyle = prevStack.fillStyle;
+    this.appliedStrokeStyle = prevStack.strokeStyle;
+    this.appliedLineWidth = prevStack.lineWidth;
+    this.appliedLineCap = prevStack.lineCap;
+    this.appliedLineJoin = prevStack.lineJoin;
+    this.appliedMiterLimit = prevStack.miterLimit;
+  }
+  this.nativeContext.setTransform(transform[0], transform[1], transform[4], transform[5], transform[12], transform[13]);
+  if (forceRestore || (currentContext.opacity !== -1 && this.currentOpacity !== currentContext.opacity)) {
+    this.nativeContext.globalAlpha = currentContext.opacity;
+    this.currentOpacity = currentContext.opacity;
+  }
+  this.currentFillStyle = currentContext.fillStyle;
+  this.currentStrokeStyle = currentContext.strokeStyle;
+  this.currentLineWidth = currentContext.lineWidth;
+  this.currentLineCap = currentContext.lineCap;
+  this.currentLineJoin = currentContext.lineJoin;
+  this.currentMiterLimit = currentContext.miterLimit;
+};
+
+CVContextData.prototype.save = function (saveOnNativeFlag) {
+  if (saveOnNativeFlag) {
+    this.nativeContext.save();
+  }
+  var props = this.cTr.props;
+  if (this._length <= this.cArrPos) {
+    this.duplicate();
+  }
+
+  var currentStack = this.stack[this.cArrPos];
+  var i;
+  for (i = 0; i < 16; i += 1) {
+    currentStack.transform[i] = props[i];
+  }
+  this.cArrPos += 1;
+  var newStack = this.stack[this.cArrPos];
+  newStack.opacity = currentStack.opacity;
+  newStack.fillStyle = currentStack.fillStyle;
+  newStack.strokeStyle = currentStack.strokeStyle;
+  newStack.lineWidth = currentStack.lineWidth;
+  newStack.lineCap = currentStack.lineCap;
+  newStack.lineJoin = currentStack.lineJoin;
+  newStack.miterLimit = currentStack.miterLimit;
+};
+
+CVContextData.prototype.setOpacity = function (value) {
+  this.stack[this.cArrPos].opacity = value;
+};
+
+CVContextData.prototype.setContext = function (value) {
+  this.nativeContext = value;
+};
+
+CVContextData.prototype.fillStyle = function (value) {
+  if (this.stack[this.cArrPos].fillStyle !== value) {
+    this.currentFillStyle = value;
+    this.stack[this.cArrPos].fillStyle = value;
+  }
+};
+
+CVContextData.prototype.strokeStyle = function (value) {
+  if (this.stack[this.cArrPos].strokeStyle !== value) {
+    this.currentStrokeStyle = value;
+    this.stack[this.cArrPos].strokeStyle = value;
+  }
+};
+
+CVContextData.prototype.lineWidth = function (value) {
+  if (this.stack[this.cArrPos].lineWidth !== value) {
+    this.currentLineWidth = value;
+    this.stack[this.cArrPos].lineWidth = value;
+  }
+};
+
+CVContextData.prototype.lineCap = function (value) {
+  if (this.stack[this.cArrPos].lineCap !== value) {
+    this.currentLineCap = value;
+    this.stack[this.cArrPos].lineCap = value;
+  }
+};
+
+CVContextData.prototype.lineJoin = function (value) {
+  if (this.stack[this.cArrPos].lineJoin !== value) {
+    this.currentLineJoin = value;
+    this.stack[this.cArrPos].lineJoin = value;
+  }
+};
+
+CVContextData.prototype.miterLimit = function (value) {
+  if (this.stack[this.cArrPos].miterLimit !== value) {
+    this.currentMiterLimit = value;
+    this.stack[this.cArrPos].miterLimit = value;
+  }
+};
+
+CVContextData.prototype.transform = function (props) {
+  this.transformMat.cloneFromProps(props);
+  // Taking the last transform value from the stored stack of transforms
+  var currentTransform = this.cTr;
+  // Applying the last transform value after the new transform to respect the order of transformations
+  this.transformMat.multiply(currentTransform);
+  // Storing the new transformed value in the stored transform
+  currentTransform.cloneFromProps(this.transformMat.props);
+  var trProps = currentTransform.props;
+  // Applying the new transform to the canvas
+  this.nativeContext.setTransform(trProps[0], trProps[1], trProps[4], trProps[5], trProps[12], trProps[13]);
+};
+
+CVContextData.prototype.opacity = function (op) {
+  var currentOpacity = this.stack[this.cArrPos].opacity;
+  currentOpacity *= op < 0 ? 0 : op;
+  if (this.stack[this.cArrPos].opacity !== currentOpacity) {
+    if (this.currentOpacity !== op) {
+      this.nativeContext.globalAlpha = op;
+      this.currentOpacity = op;
+    }
+    this.stack[this.cArrPos].opacity = currentOpacity;
+  }
+};
+
+CVContextData.prototype.fill = function (rule) {
+  if (this.appliedFillStyle !== this.currentFillStyle) {
+    this.appliedFillStyle = this.currentFillStyle;
+    this.nativeContext.fillStyle = this.appliedFillStyle;
+  }
+  this.nativeContext.fill(rule);
+};
+
+CVContextData.prototype.fillRect = function (x, y, w, h) {
+  if (this.appliedFillStyle !== this.currentFillStyle) {
+    this.appliedFillStyle = this.currentFillStyle;
+    this.nativeContext.fillStyle = this.appliedFillStyle;
+  }
+  this.nativeContext.fillRect(x, y, w, h);
+};
+
+CVContextData.prototype.stroke = function () {
+  if (this.appliedStrokeStyle !== this.currentStrokeStyle) {
+    this.appliedStrokeStyle = this.currentStrokeStyle;
+    this.nativeContext.strokeStyle = this.appliedStrokeStyle;
+  }
+  if (this.appliedLineWidth !== this.currentLineWidth) {
+    this.appliedLineWidth = this.currentLineWidth;
+    this.nativeContext.lineWidth = this.appliedLineWidth;
+  }
+  if (this.appliedLineCap !== this.currentLineCap) {
+    this.appliedLineCap = this.currentLineCap;
+    this.nativeContext.lineCap = this.appliedLineCap;
+  }
+  if (this.appliedLineJoin !== this.currentLineJoin) {
+    this.appliedLineJoin = this.currentLineJoin;
+    this.nativeContext.lineJoin = this.appliedLineJoin;
+  }
+  if (this.appliedMiterLimit !== this.currentMiterLimit) {
+    this.appliedMiterLimit = this.currentMiterLimit;
+    this.nativeContext.miterLimit = this.appliedMiterLimit;
+  }
+  this.nativeContext.stroke();
+};
+
+function CVCompElement(data, globalData, comp) {
+  this.completeLayers = false;
+  this.layers = data.layers;
+  this.pendingElements = [];
+  this.elements = createSizedArray(this.layers.length);
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([CanvasRendererBase, ICompElement, CVBaseElement], CVCompElement);
+
+CVCompElement.prototype.renderInnerContent = function () {
+  var ctx = this.canvasContext;
+  ctx.beginPath();
+  ctx.moveTo(0, 0);
+  ctx.lineTo(this.data.w, 0);
+  ctx.lineTo(this.data.w, this.data.h);
+  ctx.lineTo(0, this.data.h);
+  ctx.lineTo(0, 0);
+  ctx.clip();
+  var i;
+  var len = this.layers.length;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+CVCompElement.prototype.destroy = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+  this.layers = null;
+  this.elements = null;
+};
+
+CVCompElement.prototype.createComp = function (data) {
+  return new CVCompElement(data, this.globalData, this);
+};
+
+function CanvasRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.renderConfig = {
+    clearCanvas: (config && config.clearCanvas !== undefined) ? config.clearCanvas : true,
+    context: (config && config.context) || null,
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+  this.renderConfig.dpr = (config && config.dpr) || 1;
+  if (this.animationItem.wrapper) {
+    this.renderConfig.dpr = (config && config.dpr) || window.devicePixelRatio || 1;
+  }
+  this.renderedFrame = -1;
+  this.globalData = {
+    frameNum: -1,
+    _mdf: false,
+    renderConfig: this.renderConfig,
+    currentGlobalAlpha: -1,
+  };
+  this.contextData = new CVContextData();
+  this.elements = [];
+  this.pendingElements = [];
+  this.transformMat = new Matrix();
+  this.completeLayers = false;
+  this.rendererType = 'canvas';
+  if (this.renderConfig.clearCanvas) {
+    this.ctxTransform = this.contextData.transform.bind(this.contextData);
+    this.ctxOpacity = this.contextData.opacity.bind(this.contextData);
+    this.ctxFillStyle = this.contextData.fillStyle.bind(this.contextData);
+    this.ctxStrokeStyle = this.contextData.strokeStyle.bind(this.contextData);
+    this.ctxLineWidth = this.contextData.lineWidth.bind(this.contextData);
+    this.ctxLineCap = this.contextData.lineCap.bind(this.contextData);
+    this.ctxLineJoin = this.contextData.lineJoin.bind(this.contextData);
+    this.ctxMiterLimit = this.contextData.miterLimit.bind(this.contextData);
+    this.ctxFill = this.contextData.fill.bind(this.contextData);
+    this.ctxFillRect = this.contextData.fillRect.bind(this.contextData);
+    this.ctxStroke = this.contextData.stroke.bind(this.contextData);
+    this.save = this.contextData.save.bind(this.contextData);
+  }
+}
+extendPrototype([CanvasRendererBase], CanvasRenderer);
+
+CanvasRenderer.prototype.createComp = function (data) {
+  return new CVCompElement(data, this.globalData, this);
+};
+
+function HBaseElement() {}
+HBaseElement.prototype = {
+  checkBlendMode: function () {},
+  initRendererElement: function () {
+    this.baseElement = createTag(this.data.tg || 'div');
+    if (this.data.hasMask) {
+      this.svgElement = createNS('svg');
+      this.layerElement = createNS('g');
+      this.maskedElement = this.layerElement;
+      this.svgElement.appendChild(this.layerElement);
+      this.baseElement.appendChild(this.svgElement);
+    } else {
+      this.layerElement = this.baseElement;
+    }
+    styleDiv(this.baseElement);
+  },
+  createContainerElements: function () {
+    this.renderableEffectsManager = new CVEffects(this);
+    this.transformedElement = this.baseElement;
+    this.maskedElement = this.layerElement;
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    var transformedElementStyle = this.transformedElement ? this.transformedElement.style : {};
+    if (this.finalTransform._matMdf) {
+      var matrixValue = this.finalTransform.mat.toCSS();
+      transformedElementStyle.transform = matrixValue;
+      transformedElementStyle.webkitTransform = matrixValue;
+    }
+    if (this.finalTransform._opMdf) {
+      transformedElementStyle.opacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderFrame: function () {
+    // If it is exported as hidden (data.hd === true) no need to render
+    // If it is not visible no need to render
+    if (this.data.hd || this.hidden) {
+      return;
+    }
+    this.renderTransform();
+    this.renderRenderable();
+    this.renderElement();
+    this.renderInnerContent();
+    if (this._isFirstFrame) {
+      this._isFirstFrame = false;
+    }
+  },
+  destroy: function () {
+    this.layerElement = null;
+    this.transformedElement = null;
+    if (this.matteElement) {
+      this.matteElement = null;
+    }
+    if (this.maskManager) {
+      this.maskManager.destroy();
+      this.maskManager = null;
+    }
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+  },
+  addEffects: function () {
+  },
+  setMatte: function () {},
+};
+HBaseElement.prototype.getBaseElement = SVGBaseElement.prototype.getBaseElement;
+HBaseElement.prototype.destroyBaseElement = HBaseElement.prototype.destroy;
+HBaseElement.prototype.buildElementParenting = BaseRenderer.prototype.buildElementParenting;
+
+function HSolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], HSolidElement);
+
+HSolidElement.prototype.createContent = function () {
+  var rect;
+  if (this.data.hasMask) {
+    rect = createNS('rect');
+    rect.setAttribute('width', this.data.sw);
+    rect.setAttribute('height', this.data.sh);
+    rect.setAttribute('fill', this.data.sc);
+    this.svgElement.setAttribute('width', this.data.sw);
+    this.svgElement.setAttribute('height', this.data.sh);
+  } else {
+    rect = createTag('div');
+    rect.style.width = this.data.sw + 'px';
+    rect.style.height = this.data.sh + 'px';
+    rect.style.backgroundColor = this.data.sc;
+  }
+  this.layerElement.appendChild(rect);
+};
+
+function HShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.shapesContainer = createNS('g');
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  this.currentBBox = {
+    x: 999999,
+    y: -999999,
+    h: 0,
+    w: 0,
+  };
+}
+extendPrototype([BaseElement, TransformElement, HSolidElement, SVGShapeElement, HBaseElement, HierarchyElement, FrameElement, RenderableElement], HShapeElement);
+HShapeElement.prototype._renderShapeFrame = HShapeElement.prototype.renderInnerContent;
+
+HShapeElement.prototype.createContent = function () {
+  var cont;
+  this.baseElement.style.fontSize = 0;
+  if (this.data.hasMask) {
+    this.layerElement.appendChild(this.shapesContainer);
+    cont = this.svgElement;
+  } else {
+    cont = createNS('svg');
+    var size = this.comp.data ? this.comp.data : this.globalData.compSize;
+    cont.setAttribute('width', size.w);
+    cont.setAttribute('height', size.h);
+    cont.appendChild(this.shapesContainer);
+    this.layerElement.appendChild(cont);
+  }
+
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.shapesContainer, 0, [], true);
+  this.filterUniqueShapes();
+  this.shapeCont = cont;
+};
+
+HShapeElement.prototype.getTransformedPoint = function (transformers, point) {
+  var i;
+  var len = transformers.length;
+  for (i = 0; i < len; i += 1) {
+    point = transformers[i].mProps.v.applyToPointArray(point[0], point[1], 0);
+  }
+  return point;
+};
+
+HShapeElement.prototype.calculateShapeBoundingBox = function (item, boundingBox) {
+  var shape = item.sh.v;
+  var transformers = item.transformers;
+  var i;
+  var len = shape._length;
+  var vPoint;
+  var oPoint;
+  var nextIPoint;
+  var nextVPoint;
+  if (len <= 1) {
+    return;
+  }
+  for (i = 0; i < len - 1; i += 1) {
+    vPoint = this.getTransformedPoint(transformers, shape.v[i]);
+    oPoint = this.getTransformedPoint(transformers, shape.o[i]);
+    nextIPoint = this.getTransformedPoint(transformers, shape.i[i + 1]);
+    nextVPoint = this.getTransformedPoint(transformers, shape.v[i + 1]);
+    this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
+  }
+  if (shape.c) {
+    vPoint = this.getTransformedPoint(transformers, shape.v[i]);
+    oPoint = this.getTransformedPoint(transformers, shape.o[i]);
+    nextIPoint = this.getTransformedPoint(transformers, shape.i[0]);
+    nextVPoint = this.getTransformedPoint(transformers, shape.v[0]);
+    this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
+  }
+};
+
+HShapeElement.prototype.checkBounds = function (vPoint, oPoint, nextIPoint, nextVPoint, boundingBox) {
+  this.getBoundsOfCurve(vPoint, oPoint, nextIPoint, nextVPoint);
+  var bounds = this.shapeBoundingBox;
+  boundingBox.x = bmMin(bounds.left, boundingBox.x);
+  boundingBox.xMax = bmMax(bounds.right, boundingBox.xMax);
+  boundingBox.y = bmMin(bounds.top, boundingBox.y);
+  boundingBox.yMax = bmMax(bounds.bottom, boundingBox.yMax);
+};
+
+HShapeElement.prototype.shapeBoundingBox = {
+  left: 0,
+  right: 0,
+  top: 0,
+  bottom: 0,
+};
+
+HShapeElement.prototype.tempBoundingBox = {
+  x: 0,
+  xMax: 0,
+  y: 0,
+  yMax: 0,
+  width: 0,
+  height: 0,
+};
+
+HShapeElement.prototype.getBoundsOfCurve = function (p0, p1, p2, p3) {
+  var bounds = [[p0[0], p3[0]], [p0[1], p3[1]]];
+
+  for (var a, b, c, t, b2ac, t1, t2, i = 0; i < 2; ++i) { // eslint-disable-line no-plusplus
+    b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];
+    a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];
+    c = 3 * p1[i] - 3 * p0[i];
+
+    b |= 0; // eslint-disable-line no-bitwise
+    a |= 0; // eslint-disable-line no-bitwise
+    c |= 0; // eslint-disable-line no-bitwise
+
+    if (a === 0 && b === 0) {
+      //
+    } else if (a === 0) {
+      t = -c / b;
+
+      if (t > 0 && t < 1) {
+        bounds[i].push(this.calculateF(t, p0, p1, p2, p3, i));
+      }
+    } else {
+      b2ac = b * b - 4 * c * a;
+
+      if (b2ac >= 0) {
+        t1 = (-b + bmSqrt(b2ac)) / (2 * a);
+        if (t1 > 0 && t1 < 1) bounds[i].push(this.calculateF(t1, p0, p1, p2, p3, i));
+        t2 = (-b - bmSqrt(b2ac)) / (2 * a);
+        if (t2 > 0 && t2 < 1) bounds[i].push(this.calculateF(t2, p0, p1, p2, p3, i));
+      }
+    }
+  }
+
+  this.shapeBoundingBox.left = bmMin.apply(null, bounds[0]);
+  this.shapeBoundingBox.top = bmMin.apply(null, bounds[1]);
+  this.shapeBoundingBox.right = bmMax.apply(null, bounds[0]);
+  this.shapeBoundingBox.bottom = bmMax.apply(null, bounds[1]);
+};
+
+HShapeElement.prototype.calculateF = function (t, p0, p1, p2, p3, i) {
+  return bmPow(1 - t, 3) * p0[i]
+        + 3 * bmPow(1 - t, 2) * t * p1[i]
+        + 3 * (1 - t) * bmPow(t, 2) * p2[i]
+        + bmPow(t, 3) * p3[i];
+};
+
+HShapeElement.prototype.calculateBoundingBox = function (itemsData, boundingBox) {
+  var i;
+  var len = itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    if (itemsData[i] && itemsData[i].sh) {
+      this.calculateShapeBoundingBox(itemsData[i], boundingBox);
+    } else if (itemsData[i] && itemsData[i].it) {
+      this.calculateBoundingBox(itemsData[i].it, boundingBox);
+    } else if (itemsData[i] && itemsData[i].style && itemsData[i].w) {
+      this.expandStrokeBoundingBox(itemsData[i].w, boundingBox);
+    }
+  }
+};
+
+HShapeElement.prototype.expandStrokeBoundingBox = function (widthProperty, boundingBox) {
+  var width = 0;
+  if (widthProperty.keyframes) {
+    for (var i = 0; i < widthProperty.keyframes.length; i += 1) {
+      var kfw = widthProperty.keyframes[i].s;
+      if (kfw > width) {
+        width = kfw;
+      }
+    }
+    width *= widthProperty.mult;
+  } else {
+    width = widthProperty.v * widthProperty.mult;
+  }
+
+  boundingBox.x -= width;
+  boundingBox.xMax += width;
+  boundingBox.y -= width;
+  boundingBox.yMax += width;
+};
+
+HShapeElement.prototype.currentBoxContains = function (box) {
+  return this.currentBBox.x <= box.x
+    && this.currentBBox.y <= box.y
+    && this.currentBBox.width + this.currentBBox.x >= box.x + box.width
+    && this.currentBBox.height + this.currentBBox.y >= box.y + box.height;
+};
+
+HShapeElement.prototype.renderInnerContent = function () {
+  this._renderShapeFrame();
+
+  if (!this.hidden && (this._isFirstFrame || this._mdf)) {
+    var tempBoundingBox = this.tempBoundingBox;
+    var max = 999999;
+    tempBoundingBox.x = max;
+    tempBoundingBox.xMax = -max;
+    tempBoundingBox.y = max;
+    tempBoundingBox.yMax = -max;
+    this.calculateBoundingBox(this.itemsData, tempBoundingBox);
+    tempBoundingBox.width = tempBoundingBox.xMax < tempBoundingBox.x ? 0 : tempBoundingBox.xMax - tempBoundingBox.x;
+    tempBoundingBox.height = tempBoundingBox.yMax < tempBoundingBox.y ? 0 : tempBoundingBox.yMax - tempBoundingBox.y;
+    // var tempBoundingBox = this.shapeCont.getBBox();
+    if (this.currentBoxContains(tempBoundingBox)) {
+      return;
+    }
+    var changed = false;
+    if (this.currentBBox.w !== tempBoundingBox.width) {
+      this.currentBBox.w = tempBoundingBox.width;
+      this.shapeCont.setAttribute('width', tempBoundingBox.width);
+      changed = true;
+    }
+    if (this.currentBBox.h !== tempBoundingBox.height) {
+      this.currentBBox.h = tempBoundingBox.height;
+      this.shapeCont.setAttribute('height', tempBoundingBox.height);
+      changed = true;
+    }
+    if (changed || this.currentBBox.x !== tempBoundingBox.x || this.currentBBox.y !== tempBoundingBox.y) {
+      this.currentBBox.w = tempBoundingBox.width;
+      this.currentBBox.h = tempBoundingBox.height;
+      this.currentBBox.x = tempBoundingBox.x;
+      this.currentBBox.y = tempBoundingBox.y;
+
+      this.shapeCont.setAttribute('viewBox', this.currentBBox.x + ' ' + this.currentBBox.y + ' ' + this.currentBBox.w + ' ' + this.currentBBox.h);
+      var shapeStyle = this.shapeCont.style;
+      var shapeTransform = 'translate(' + this.currentBBox.x + 'px,' + this.currentBBox.y + 'px)';
+      shapeStyle.transform = shapeTransform;
+      shapeStyle.webkitTransform = shapeTransform;
+    }
+  }
+};
+
+function HTextElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.textPaths = [];
+  this.currentBBox = {
+    x: 999999,
+    y: -999999,
+    h: 0,
+    w: 0,
+  };
+  this.renderType = 'svg';
+  this.isMasked = false;
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], HTextElement);
+
+HTextElement.prototype.createContent = function () {
+  this.isMasked = this.checkMasks();
+  if (this.isMasked) {
+    this.renderType = 'svg';
+    this.compW = this.comp.data.w;
+    this.compH = this.comp.data.h;
+    this.svgElement.setAttribute('width', this.compW);
+    this.svgElement.setAttribute('height', this.compH);
+    var g = createNS('g');
+    this.maskedElement.appendChild(g);
+    this.innerElem = g;
+  } else {
+    this.renderType = 'html';
+    this.innerElem = this.layerElement;
+  }
+
+  this.checkParenting();
+};
+
+HTextElement.prototype.buildNewText = function () {
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
+  var innerElemStyle = this.innerElem.style;
+  var textColor = documentData.fc ? this.buildColor(documentData.fc) : 'rgba(0,0,0,0)';
+  innerElemStyle.fill = textColor;
+  innerElemStyle.color = textColor;
+  if (documentData.sc) {
+    innerElemStyle.stroke = this.buildColor(documentData.sc);
+    innerElemStyle.strokeWidth = documentData.sw + 'px';
+  }
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (!this.globalData.fontManager.chars) {
+    innerElemStyle.fontSize = documentData.finalSize + 'px';
+    innerElemStyle.lineHeight = documentData.finalSize + 'px';
+    if (fontData.fClass) {
+      this.innerElem.className = fontData.fClass;
+    } else {
+      innerElemStyle.fontFamily = fontData.fFamily;
+      var fWeight = documentData.fWeight;
+      var fStyle = documentData.fStyle;
+      innerElemStyle.fontStyle = fStyle;
+      innerElemStyle.fontWeight = fWeight;
+    }
+  }
+  var i;
+  var len;
+
+  var letters = documentData.l;
+  len = letters.length;
+  var tSpan;
+  var tParent;
+  var tCont;
+  var matrixHelper = this.mHelper;
+  var shapes;
+  var shapeStr = '';
+  var cnt = 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.globalData.fontManager.chars) {
+      if (!this.textPaths[cnt]) {
+        tSpan = createNS('path');
+        tSpan.setAttribute('stroke-linecap', lineCapEnum[1]);
+        tSpan.setAttribute('stroke-linejoin', lineJoinEnum[2]);
+        tSpan.setAttribute('stroke-miterlimit', '4');
+      } else {
+        tSpan = this.textPaths[cnt];
+      }
+      if (!this.isMasked) {
+        if (this.textSpans[cnt]) {
+          tParent = this.textSpans[cnt];
+          tCont = tParent.children[0];
+        } else {
+          tParent = createTag('div');
+          tParent.style.lineHeight = 0;
+          tCont = createNS('svg');
+          tCont.appendChild(tSpan);
+          styleDiv(tParent);
+        }
+      }
+    } else if (!this.isMasked) {
+      if (this.textSpans[cnt]) {
+        tParent = this.textSpans[cnt];
+        tSpan = this.textPaths[cnt];
+      } else {
+        tParent = createTag('span');
+        styleDiv(tParent);
+        tSpan = createTag('span');
+        styleDiv(tSpan);
+        tParent.appendChild(tSpan);
+      }
+    } else {
+      tSpan = this.textPaths[cnt] ? this.textPaths[cnt] : createNS('text');
+    }
+    // tSpan.setAttribute('visibility', 'hidden');
+    if (this.globalData.fontManager.chars) {
+      var charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
+      var shapeData;
+      if (charData) {
+        shapeData = charData.data;
+      } else {
+        shapeData = null;
+      }
+      matrixHelper.reset();
+      if (shapeData && shapeData.shapes && shapeData.shapes.length) {
+        shapes = shapeData.shapes[0].it;
+        matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
+        shapeStr = this.createPathShape(matrixHelper, shapes);
+        tSpan.setAttribute('d', shapeStr);
+      }
+      if (!this.isMasked) {
+        this.innerElem.appendChild(tParent);
+        if (shapeData && shapeData.shapes) {
+          // document.body.appendChild is needed to get exact measure of shape
+          document.body.appendChild(tCont);
+          var boundingBox = tCont.getBBox();
+          tCont.setAttribute('width', boundingBox.width + 2);
+          tCont.setAttribute('height', boundingBox.height + 2);
+          tCont.setAttribute('viewBox', (boundingBox.x - 1) + ' ' + (boundingBox.y - 1) + ' ' + (boundingBox.width + 2) + ' ' + (boundingBox.height + 2));
+          var tContStyle = tCont.style;
+          var tContTranslation = 'translate(' + (boundingBox.x - 1) + 'px,' + (boundingBox.y - 1) + 'px)';
+          tContStyle.transform = tContTranslation;
+          tContStyle.webkitTransform = tContTranslation;
+
+          letters[i].yOffset = boundingBox.y - 1;
+        } else {
+          tCont.setAttribute('width', 1);
+          tCont.setAttribute('height', 1);
+        }
+        tParent.appendChild(tCont);
+      } else {
+        this.innerElem.appendChild(tSpan);
+      }
+    } else {
+      tSpan.textContent = letters[i].val;
+      tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      if (!this.isMasked) {
+        this.innerElem.appendChild(tParent);
+        //
+        var tStyle = tSpan.style;
+        var tSpanTranslation = 'translate3d(0,' + -documentData.finalSize / 1.2 + 'px,0)';
+        tStyle.transform = tSpanTranslation;
+        tStyle.webkitTransform = tSpanTranslation;
+      } else {
+        this.innerElem.appendChild(tSpan);
+      }
+    }
+    //
+    if (!this.isMasked) {
+      this.textSpans[cnt] = tParent;
+    } else {
+      this.textSpans[cnt] = tSpan;
+    }
+    this.textSpans[cnt].style.display = 'block';
+    this.textPaths[cnt] = tSpan;
+    cnt += 1;
+  }
+  while (cnt < this.textSpans.length) {
+    this.textSpans[cnt].style.display = 'none';
+    cnt += 1;
+  }
+};
+
+HTextElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  var svgStyle;
+  if (this.data.singleShape) {
+    if (!this._isFirstFrame && !this.lettersChangedFlag) {
+      return;
+    } if (this.isMasked && this.finalTransform._matMdf) {
+      // Todo Benchmark if using this is better than getBBox
+      this.svgElement.setAttribute('viewBox', -this.finalTransform.mProp.p.v[0] + ' ' + -this.finalTransform.mProp.p.v[1] + ' ' + this.compW + ' ' + this.compH);
+      svgStyle = this.svgElement.style;
+      var translation = 'translate(' + -this.finalTransform.mProp.p.v[0] + 'px,' + -this.finalTransform.mProp.p.v[1] + 'px)';
+      svgStyle.transform = translation;
+      svgStyle.webkitTransform = translation;
+    }
+  }
+
+  this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+  if (!this.lettersChangedFlag && !this.textAnimator.lettersChangedFlag) {
+    return;
+  }
+  var i;
+  var len;
+  var count = 0;
+  var renderedLetters = this.textAnimator.renderedLetters;
+
+  var letters = this.textProperty.currentData.l;
+
+  len = letters.length;
+  var renderedLetter;
+  var textSpan;
+  var textPath;
+  for (i = 0; i < len; i += 1) {
+    if (letters[i].n) {
+      count += 1;
+    } else {
+      textSpan = this.textSpans[i];
+      textPath = this.textPaths[i];
+      renderedLetter = renderedLetters[count];
+      count += 1;
+      if (renderedLetter._mdf.m) {
+        if (!this.isMasked) {
+          textSpan.style.webkitTransform = renderedLetter.m;
+          textSpan.style.transform = renderedLetter.m;
+        } else {
+          textSpan.setAttribute('transform', renderedLetter.m);
+        }
+      }
+      /// /textSpan.setAttribute('opacity',renderedLetter.o);
+      textSpan.style.opacity = renderedLetter.o;
+      if (renderedLetter.sw && renderedLetter._mdf.sw) {
+        textPath.setAttribute('stroke-width', renderedLetter.sw);
+      }
+      if (renderedLetter.sc && renderedLetter._mdf.sc) {
+        textPath.setAttribute('stroke', renderedLetter.sc);
+      }
+      if (renderedLetter.fc && renderedLetter._mdf.fc) {
+        textPath.setAttribute('fill', renderedLetter.fc);
+        textPath.style.color = renderedLetter.fc;
+      }
+    }
+  }
+
+  if (this.innerElem.getBBox && !this.hidden && (this._isFirstFrame || this._mdf)) {
+    var boundingBox = this.innerElem.getBBox();
+
+    if (this.currentBBox.w !== boundingBox.width) {
+      this.currentBBox.w = boundingBox.width;
+      this.svgElement.setAttribute('width', boundingBox.width);
+    }
+    if (this.currentBBox.h !== boundingBox.height) {
+      this.currentBBox.h = boundingBox.height;
+      this.svgElement.setAttribute('height', boundingBox.height);
+    }
+
+    var margin = 1;
+    if (this.currentBBox.w !== (boundingBox.width + margin * 2) || this.currentBBox.h !== (boundingBox.height + margin * 2) || this.currentBBox.x !== (boundingBox.x - margin) || this.currentBBox.y !== (boundingBox.y - margin)) {
+      this.currentBBox.w = boundingBox.width + margin * 2;
+      this.currentBBox.h = boundingBox.height + margin * 2;
+      this.currentBBox.x = boundingBox.x - margin;
+      this.currentBBox.y = boundingBox.y - margin;
+
+      this.svgElement.setAttribute('viewBox', this.currentBBox.x + ' ' + this.currentBBox.y + ' ' + this.currentBBox.w + ' ' + this.currentBBox.h);
+      svgStyle = this.svgElement.style;
+      var svgTransform = 'translate(' + this.currentBBox.x + 'px,' + this.currentBBox.y + 'px)';
+      svgStyle.transform = svgTransform;
+      svgStyle.webkitTransform = svgTransform;
+    }
+  }
+};
+
+function HCameraElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initHierarchy();
+  var getProp = PropertyFactory.getProp;
+  this.pe = getProp(this, data.pe, 0, 0, this);
+  if (data.ks.p.s) {
+    this.px = getProp(this, data.ks.p.x, 1, 0, this);
+    this.py = getProp(this, data.ks.p.y, 1, 0, this);
+    this.pz = getProp(this, data.ks.p.z, 1, 0, this);
+  } else {
+    this.p = getProp(this, data.ks.p, 1, 0, this);
+  }
+  if (data.ks.a) {
+    this.a = getProp(this, data.ks.a, 1, 0, this);
+  }
+  if (data.ks.or.k.length && data.ks.or.k[0].to) {
+    var i;
+    var len = data.ks.or.k.length;
+    for (i = 0; i < len; i += 1) {
+      data.ks.or.k[i].to = null;
+      data.ks.or.k[i].ti = null;
+    }
+  }
+  this.or = getProp(this, data.ks.or, 1, degToRads, this);
+  this.or.sh = true;
+  this.rx = getProp(this, data.ks.rx, 0, degToRads, this);
+  this.ry = getProp(this, data.ks.ry, 0, degToRads, this);
+  this.rz = getProp(this, data.ks.rz, 0, degToRads, this);
+  this.mat = new Matrix();
+  this._prevMat = new Matrix();
+  this._isFirstFrame = true;
+
+  // TODO: find a better way to make the HCamera element to be compatible with the LayerInterface and TransformInterface.
+  this.finalTransform = {
+    mProp: this,
+  };
+}
+extendPrototype([BaseElement, FrameElement, HierarchyElement], HCameraElement);
+
+HCameraElement.prototype.setup = function () {
+  var i;
+  var len = this.comp.threeDElements.length;
+  var comp;
+  var perspectiveStyle;
+  var containerStyle;
+  for (i = 0; i < len; i += 1) {
+    // [perspectiveElem,container]
+    comp = this.comp.threeDElements[i];
+    if (comp.type === '3d') {
+      perspectiveStyle = comp.perspectiveElem.style;
+      containerStyle = comp.container.style;
+      var perspective = this.pe.v + 'px';
+      var origin = '0px 0px 0px';
+      var matrix = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)';
+      perspectiveStyle.perspective = perspective;
+      perspectiveStyle.webkitPerspective = perspective;
+      containerStyle.transformOrigin = origin;
+      containerStyle.mozTransformOrigin = origin;
+      containerStyle.webkitTransformOrigin = origin;
+      perspectiveStyle.transform = matrix;
+      perspectiveStyle.webkitTransform = matrix;
+    }
+  }
+};
+
+HCameraElement.prototype.createElements = function () {
+};
+
+HCameraElement.prototype.hide = function () {
+};
+
+HCameraElement.prototype.renderFrame = function () {
+  var _mdf = this._isFirstFrame;
+  var i;
+  var len;
+  if (this.hierarchy) {
+    len = this.hierarchy.length;
+    for (i = 0; i < len; i += 1) {
+      _mdf = this.hierarchy[i].finalTransform.mProp._mdf || _mdf;
+    }
+  }
+  if (_mdf || this.pe._mdf || (this.p && this.p._mdf) || (this.px && (this.px._mdf || this.py._mdf || this.pz._mdf)) || this.rx._mdf || this.ry._mdf || this.rz._mdf || this.or._mdf || (this.a && this.a._mdf)) {
+    this.mat.reset();
+
+    if (this.hierarchy) {
+      len = this.hierarchy.length - 1;
+      for (i = len; i >= 0; i -= 1) {
+        var mTransf = this.hierarchy[i].finalTransform.mProp;
+        this.mat.translate(-mTransf.p.v[0], -mTransf.p.v[1], mTransf.p.v[2]);
+        this.mat.rotateX(-mTransf.or.v[0]).rotateY(-mTransf.or.v[1]).rotateZ(mTransf.or.v[2]);
+        this.mat.rotateX(-mTransf.rx.v).rotateY(-mTransf.ry.v).rotateZ(mTransf.rz.v);
+        this.mat.scale(1 / mTransf.s.v[0], 1 / mTransf.s.v[1], 1 / mTransf.s.v[2]);
+        this.mat.translate(mTransf.a.v[0], mTransf.a.v[1], mTransf.a.v[2]);
+      }
+    }
+    if (this.p) {
+      this.mat.translate(-this.p.v[0], -this.p.v[1], this.p.v[2]);
+    } else {
+      this.mat.translate(-this.px.v, -this.py.v, this.pz.v);
+    }
+    if (this.a) {
+      var diffVector;
+      if (this.p) {
+        diffVector = [this.p.v[0] - this.a.v[0], this.p.v[1] - this.a.v[1], this.p.v[2] - this.a.v[2]];
+      } else {
+        diffVector = [this.px.v - this.a.v[0], this.py.v - this.a.v[1], this.pz.v - this.a.v[2]];
+      }
+      var mag = Math.sqrt(Math.pow(diffVector[0], 2) + Math.pow(diffVector[1], 2) + Math.pow(diffVector[2], 2));
+      // var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
+      var lookDir = [diffVector[0] / mag, diffVector[1] / mag, diffVector[2] / mag];
+      var lookLengthOnXZ = Math.sqrt(lookDir[2] * lookDir[2] + lookDir[0] * lookDir[0]);
+      var mRotationX = (Math.atan2(lookDir[1], lookLengthOnXZ));
+      var mRotationY = (Math.atan2(lookDir[0], -lookDir[2]));
+      this.mat.rotateY(mRotationY).rotateX(-mRotationX);
+    }
+    this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v);
+    this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]);
+    this.mat.translate(this.globalData.compSize.w / 2, this.globalData.compSize.h / 2, 0);
+    this.mat.translate(0, 0, this.pe.v);
+
+    var hasMatrixChanged = !this._prevMat.equals(this.mat);
+    if ((hasMatrixChanged || this.pe._mdf) && this.comp.threeDElements) {
+      len = this.comp.threeDElements.length;
+      var comp;
+      var perspectiveStyle;
+      var containerStyle;
+      for (i = 0; i < len; i += 1) {
+        comp = this.comp.threeDElements[i];
+        if (comp.type === '3d') {
+          if (hasMatrixChanged) {
+            var matValue = this.mat.toCSS();
+            containerStyle = comp.container.style;
+            containerStyle.transform = matValue;
+            containerStyle.webkitTransform = matValue;
+          }
+          if (this.pe._mdf) {
+            perspectiveStyle = comp.perspectiveElem.style;
+            perspectiveStyle.perspective = this.pe.v + 'px';
+            perspectiveStyle.webkitPerspective = this.pe.v + 'px';
+          }
+        }
+      }
+      this.mat.clone(this._prevMat);
+    }
+  }
+  this._isFirstFrame = false;
+};
+
+HCameraElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+HCameraElement.prototype.destroy = function () {
+};
+HCameraElement.prototype.getBaseElement = function () { return null; };
+
+function HImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, HBaseElement, HSolidElement, HierarchyElement, FrameElement, RenderableElement], HImageElement);
+
+HImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  var img = new Image();
+
+  if (this.data.hasMask) {
+    this.imageElem = createNS('image');
+    this.imageElem.setAttribute('width', this.assetData.w + 'px');
+    this.imageElem.setAttribute('height', this.assetData.h + 'px');
+    this.imageElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+    this.layerElement.appendChild(this.imageElem);
+    this.baseElement.setAttribute('width', this.assetData.w);
+    this.baseElement.setAttribute('height', this.assetData.h);
+  } else {
+    this.layerElement.appendChild(img);
+  }
+  img.crossOrigin = 'anonymous';
+  img.src = assetPath;
+  if (this.data.ln) {
+    this.baseElement.setAttribute('id', this.data.ln);
+  }
+};
+
+function HybridRendererBase(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),
+    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], HybridRendererBase);
+
+HybridRendererBase.prototype.buildItem = SVGRenderer.prototype.buildItem;
+
+HybridRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+  }
+};
+
+HybridRendererBase.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;
+      var nextLayer;
+      var 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);
+  }
+};
+
+HybridRendererBase.prototype.createShape = function (data) {
+  if (!this.supports3d) {
+    return new SVGShapeElement(data, this.globalData, this);
+  }
+  return new HShapeElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createText = function (data) {
+  if (!this.supports3d) {
+    return new SVGTextLottieElement(data, this.globalData, this);
+  }
+  return new HTextElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createCamera = function (data) {
+  this.camera = new HCameraElement(data, this.globalData, this);
+  return this.camera;
+};
+
+HybridRendererBase.prototype.createImage = function (data) {
+  if (!this.supports3d) {
+    return new IImageElement(data, this.globalData, this);
+  }
+  return new HImageElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createSolid = function (data) {
+  if (!this.supports3d) {
+    return new ISolidElement(data, this.globalData, this);
+  }
+  return new HSolidElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
+
+HybridRendererBase.prototype.getThreeDContainerByPos = function (pos) {
+  var i = 0;
+  var 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;
+  }
+  return null;
+};
+
+HybridRendererBase.prototype.createThreeDContainer = function (pos, type) {
+  var perspectiveElem = createTag('div');
+  var style;
+  var containerStyle;
+  styleDiv(perspectiveElem);
+  var container = createTag('div');
+  styleDiv(container);
+  if (type === '3d') {
+    style = perspectiveElem.style;
+    style.width = this.globalData.compSize.w + 'px';
+    style.height = this.globalData.compSize.h + 'px';
+    var center = '50% 50%';
+    style.webkitTransformOrigin = center;
+    style.mozTransformOrigin = center;
+    style.transformOrigin = center;
+    containerStyle = container.style;
+    var matrix = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)';
+    containerStyle.transform = matrix;
+    containerStyle.webkitTransform = matrix;
+  }
+
+  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;
+};
+
+HybridRendererBase.prototype.build3dContainers = function () {
+  var i;
+  var 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 -= 1) {
+    this.resizerElem.appendChild(this.threeDElements[i].perspectiveElem);
+  }
+};
+
+HybridRendererBase.prototype.addTo3dContainer = function (elem, pos) {
+  var i = 0;
+  var 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;
+  }
+};
+
+HybridRendererBase.prototype.configAnimation = function (animData) {
+  var resizerElem = createTag('div');
+  var wrapper = this.animationItem.wrapper;
+  var style = resizerElem.style;
+  style.width = animData.w + 'px';
+  style.height = animData.h + 'px';
+  this.resizerElem = resizerElem;
+  styleDiv(resizerElem);
+  style.transformStyle = 'flat';
+  style.mozTransformStyle = 'flat';
+  style.webkitTransformStyle = 'flat';
+  if (this.renderConfig.className) {
+    resizerElem.setAttribute('class', this.renderConfig.className);
+  }
+  wrapper.appendChild(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();
+};
+
+HybridRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.animationItem.container = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+HybridRendererBase.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;
+  var sy;
+  var tx;
+  var 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;
+  }
+  var style = this.resizerElem.style;
+  style.webkitTransform = 'matrix3d(' + sx + ',0,0,0,0,' + sy + ',0,0,0,0,1,0,' + tx + ',' + ty + ',0,1)';
+  style.transform = style.webkitTransform;
+};
+
+HybridRendererBase.prototype.renderFrame = SVGRenderer.prototype.renderFrame;
+
+HybridRendererBase.prototype.hide = function () {
+  this.resizerElem.style.display = 'none';
+};
+
+HybridRendererBase.prototype.show = function () {
+  this.resizerElem.style.display = 'block';
+};
+
+HybridRendererBase.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;
+    var len = this.threeDElements.length;
+    for (i = 0; i < len; i += 1) {
+      var style = this.threeDElements[i].perspectiveElem.style;
+      style.webkitPerspective = Math.sqrt(Math.pow(cWidth, 2) + Math.pow(cHeight, 2)) + 'px';
+      style.perspective = style.webkitPerspective;
+    }
+  }
+};
+
+HybridRendererBase.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var 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);
+    }
+  }
+};
+
+function HCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = !data.hasMask;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([HybridRendererBase, ICompElement, HBaseElement], HCompElement);
+HCompElement.prototype._createBaseContainerElements = HCompElement.prototype.createContainerElements;
+
+HCompElement.prototype.createContainerElements = function () {
+  this._createBaseContainerElements();
+  // divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
+  if (this.data.hasMask) {
+    this.svgElement.setAttribute('width', this.data.w);
+    this.svgElement.setAttribute('height', this.data.h);
+    this.transformedElement = this.baseElement;
+  } else {
+    this.transformedElement = this.layerElement;
+  }
+};
+
+HCompElement.prototype.addTo3dContainer = function (elem, pos) {
+  var j = 0;
+  var nextElement;
+  while (j < pos) {
+    if (this.elements[j] && this.elements[j].getBaseElement) {
+      nextElement = this.elements[j].getBaseElement();
+    }
+    j += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(elem, nextElement);
+  } else {
+    this.layerElement.appendChild(elem);
+  }
+};
+
+HCompElement.prototype.createComp = function (data) {
+  if (!this.supports3d) {
+    return new SVGCompElement(data, this.globalData, this);
+  }
+  return new HCompElement(data, this.globalData, this);
+};
+
+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),
+    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%',
+    },
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+  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([HybridRendererBase], HybridRenderer);
+
+HybridRenderer.prototype.createComp = function (data) {
+  if (!this.supports3d) {
+    return new SVGCompElement(data, this.globalData, this);
+  }
+  return new HCompElement(data, this.globalData, this);
+};
+
+const CompExpressionInterface = (function () {
+  return function (comp) {
+    function _thisLayerFunction(name) {
+      var i = 0;
+      var len = comp.layers.length;
+      while (i < len) {
+        if (comp.layers[i].nm === name || comp.layers[i].ind === name) {
+          return comp.elements[i].layerInterface;
+        }
+        i += 1;
+      }
+      return null;
+      // return {active:false};
+    }
+    Object.defineProperty(_thisLayerFunction, '_name', { value: comp.data.nm });
+    _thisLayerFunction.layer = _thisLayerFunction;
+    _thisLayerFunction.pixelAspect = 1;
+    _thisLayerFunction.height = comp.data.h || comp.globalData.compSize.h;
+    _thisLayerFunction.width = comp.data.w || comp.globalData.compSize.w;
+    _thisLayerFunction.pixelAspect = 1;
+    _thisLayerFunction.frameDuration = 1 / comp.globalData.frameRate;
+    _thisLayerFunction.displayStartTime = 0;
+    _thisLayerFunction.numLayers = comp.layers.length;
+    return _thisLayerFunction;
+  };
+}());
+
+/* eslint-disable */
+/*
+ Copyright 2014 David Bau.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ */
+
+function seedRandom(pool, math) {
+//
+// The following constants are related to IEEE 754 limits.
+//
+    var global = this,
+        width = 256,        // each RC4 output is 0 <= x < 256
+        chunks = 6,         // at least six RC4 outputs for each double
+        digits = 52,        // there are 52 significant digits in a double
+        rngname = 'random', // rngname: name for Math.random and Math.seedrandom
+        startdenom = math.pow(width, chunks),
+        significance = math.pow(2, digits),
+        overflow = significance * 2,
+        mask = width - 1,
+        nodecrypto;         // node.js crypto module, initialized at the bottom.
+
+//
+// seedrandom()
+// This is the seedrandom function described above.
+//
+    function seedrandom(seed, options, callback) {
+        var key = [];
+        options = (options === true) ? { entropy: true } : (options || {});
+
+        // Flatten the seed string or build one from local entropy if needed.
+        var shortseed = mixkey(flatten(
+            options.entropy ? [seed, tostring(pool)] :
+                (seed === null) ? autoseed() : seed, 3), key);
+
+        // Use the seed to initialize an ARC4 generator.
+        var arc4 = new ARC4(key);
+
+        // This function returns a random double in [0, 1) that contains
+        // randomness in every bit of the mantissa of the IEEE 754 value.
+        var prng = function() {
+            var n = arc4.g(chunks),             // Start with a numerator n < 2 ^ 48
+                d = startdenom,                 //   and denominator d = 2 ^ 48.
+                x = 0;                          //   and no 'extra last byte'.
+            while (n < significance) {          // Fill up all significant digits by
+                n = (n + x) * width;              //   shifting numerator and
+                d *= width;                       //   denominator and generating a
+                x = arc4.g(1);                    //   new least-significant-byte.
+            }
+            while (n >= overflow) {             // To avoid rounding up, before adding
+                n /= 2;                           //   last byte, shift everything
+                d /= 2;                           //   right using integer math until
+                x >>>= 1;                         //   we have exactly the desired bits.
+            }
+            return (n + x) / d;                 // Form the number within [0, 1).
+        };
+
+        prng.int32 = function() { return arc4.g(4) | 0; };
+        prng.quick = function() { return arc4.g(4) / 0x100000000; };
+        prng.double = prng;
+
+        // Mix the randomness into accumulated entropy.
+        mixkey(tostring(arc4.S), pool);
+
+        // Calling convention: what to return as a function of prng, seed, is_math.
+        return (options.pass || callback ||
+        function(prng, seed, is_math_call, state) {
+            if (state) {
+                // Load the arc4 state from the given state if it has an S array.
+                if (state.S) { copy(state, arc4); }
+                // Only provide the .state method if requested via options.state.
+                prng.state = function() { return copy(arc4, {}); };
+            }
+
+            // If called as a method of Math (Math.seedrandom()), mutate
+            // Math.random because that is how seedrandom.js has worked since v1.0.
+            if (is_math_call) { math[rngname] = prng; return seed; }
+
+            // Otherwise, it is a newer calling convention, so return the
+            // prng directly.
+            else return prng;
+        })(
+            prng,
+            shortseed,
+            'global' in options ? options.global : (this == math),
+            options.state);
+    }
+    math['seed' + rngname] = seedrandom;
+
+//
+// ARC4
+//
+// An ARC4 implementation.  The constructor takes a key in the form of
+// an array of at most (width) integers that should be 0 <= x < (width).
+//
+// The g(count) method returns a pseudorandom integer that concatenates
+// the next (count) outputs from ARC4.  Its return value is a number x
+// that is in the range 0 <= x < (width ^ count).
+//
+    function ARC4(key) {
+        var t, keylen = key.length,
+            me = this, i = 0, j = me.i = me.j = 0, s = me.S = [];
+
+        // The empty key [] is treated as [0].
+        if (!keylen) { key = [keylen++]; }
+
+        // Set up S using the standard key scheduling algorithm.
+        while (i < width) {
+            s[i] = i++;
+        }
+        for (i = 0; i < width; i++) {
+            s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))];
+            s[j] = t;
+        }
+
+        // The "g" method returns the next (count) outputs as one number.
+        me.g = function(count) {
+            // Using instance members instead of closure state nearly doubles speed.
+            var t, r = 0,
+                i = me.i, j = me.j, s = me.S;
+            while (count--) {
+                t = s[i = mask & (i + 1)];
+                r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))];
+            }
+            me.i = i; me.j = j;
+            return r;
+            // For robust unpredictability, the function call below automatically
+            // discards an initial batch of values.  This is called RC4-drop[256].
+            // See http://google.com/search?q=rsa+fluhrer+response&btnI
+        };
+    }
+
+//
+// copy()
+// Copies internal state of ARC4 to or from a plain object.
+//
+    function copy(f, t) {
+        t.i = f.i;
+        t.j = f.j;
+        t.S = f.S.slice();
+        return t;
+    }
+
+//
+// flatten()
+// Converts an object tree to nested arrays of strings.
+//
+    function flatten(obj, depth) {
+        var result = [], typ = (typeof obj), prop;
+        if (depth && typ == 'object') {
+            for (prop in obj) {
+                try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}
+            }
+        }
+        return (result.length ? result : typ == 'string' ? obj : obj + '\0');
+    }
+
+//
+// mixkey()
+// Mixes a string seed into a key that is an array of integers, and
+// returns a shortened string seed that is equivalent to the result key.
+//
+    function mixkey(seed, key) {
+        var stringseed = seed + '', smear, j = 0;
+        while (j < stringseed.length) {
+            key[mask & j] =
+                mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++));
+        }
+        return tostring(key);
+    }
+
+//
+// autoseed()
+// Returns an object for autoseeding, using window.crypto and Node crypto
+// module if available.
+//
+    function autoseed() {
+        try {
+            if (nodecrypto) { return tostring(nodecrypto.randomBytes(width)); }
+            var out = new Uint8Array(width);
+            (global.crypto || global.msCrypto).getRandomValues(out);
+            return tostring(out);
+        } catch (e) {
+            var browser = global.navigator,
+                plugins = browser && browser.plugins;
+            return [+new Date(), global, plugins, global.screen, tostring(pool)];
+        }
+    }
+
+//
+// tostring()
+// Converts an array of charcodes to a string
+//
+    function tostring(a) {
+        return String.fromCharCode.apply(0, a);
+    }
+
+//
+// When seedrandom.js is loaded, we immediately mix a few bits
+// from the built-in RNG into the entropy pool.  Because we do
+// not want to interfere with deterministic PRNG state later,
+// seedrandom will not call math.random on its own again after
+// initialization.
+//
+    mixkey(math.random(), pool);
+
+//
+// Nodejs and AMD support: export the implementation as a module using
+// either convention.
+//
+
+// End anonymous scope, and pass initial values.
+};
+
+function initialize$2(BMMath) {
+    seedRandom([], BMMath);
+}
+
+var propTypes = {
+  SHAPE: 'shape',
+};
+
+/* eslint-disable camelcase */
+
+const ExpressionManager = (function () {
+  'use strict';
+
+  var ob = {};
+  var Math = BMMath;
+  var window = null;
+  var document = null;
+  var XMLHttpRequest = null;
+  var fetch = null;
+  var frames = null;
+  var _lottieGlobal = {};
+  initialize$2(BMMath);
+
+  function resetFrame() {
+    _lottieGlobal = {};
+  }
+
+  function $bm_isInstanceOfArray(arr) {
+    return arr.constructor === Array || arr.constructor === Float32Array;
+  }
+
+  function isNumerable(tOfV, v) {
+    return tOfV === 'number' || v instanceof Number || tOfV === 'boolean' || tOfV === 'string';
+  }
+
+  function $bm_neg(a) {
+    var tOfA = typeof a;
+    if (tOfA === 'number' || a instanceof Number || tOfA === 'boolean') {
+      return -a;
+    }
+    if ($bm_isInstanceOfArray(a)) {
+      var i;
+      var lenA = a.length;
+      var retArr = [];
+      for (i = 0; i < lenA; i += 1) {
+        retArr[i] = -a[i];
+      }
+      return retArr;
+    }
+    if (a.propType) {
+      return a.v;
+    }
+    return -a;
+  }
+
+  var easeInBez = BezierFactory.getBezierEasing(0.333, 0, 0.833, 0.833, 'easeIn').get;
+  var easeOutBez = BezierFactory.getBezierEasing(0.167, 0.167, 0.667, 1, 'easeOut').get;
+  var easeInOutBez = BezierFactory.getBezierEasing(0.33, 0, 0.667, 1, 'easeInOut').get;
+
+  function sum(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    if ((isNumerable(tOfA, a) && isNumerable(tOfB, b)) || tOfA === 'string' || tOfB === 'string') {
+      return a + b;
+    }
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      a = a.slice(0);
+      a[0] += b;
+      return a;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      b = b.slice(0);
+      b[0] = a + b[0];
+      return b;
+    }
+    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
+      var i = 0;
+      var lenA = a.length;
+      var lenB = b.length;
+      var retArr = [];
+      while (i < lenA || i < lenB) {
+        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
+          retArr[i] = a[i] + b[i];
+        } else {
+          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
+        }
+        i += 1;
+      }
+      return retArr;
+    }
+    return 0;
+  }
+  var add = sum;
+
+  function sub(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      if (tOfA === 'string') {
+        a = parseInt(a, 10);
+      }
+      if (tOfB === 'string') {
+        b = parseInt(b, 10);
+      }
+      return a - b;
+    }
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      a = a.slice(0);
+      a[0] -= b;
+      return a;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      b = b.slice(0);
+      b[0] = a - b[0];
+      return b;
+    }
+    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
+      var i = 0;
+      var lenA = a.length;
+      var lenB = b.length;
+      var retArr = [];
+      while (i < lenA || i < lenB) {
+        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
+          retArr[i] = a[i] - b[i];
+        } else {
+          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
+        }
+        i += 1;
+      }
+      return retArr;
+    }
+    return 0;
+  }
+
+  function mul(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    var arr;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      return a * b;
+    }
+
+    var i;
+    var len;
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      len = a.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a[i] * b;
+      }
+      return arr;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      len = b.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a * b[i];
+      }
+      return arr;
+    }
+    return 0;
+  }
+
+  function div(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    var arr;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      return a / b;
+    }
+    var i;
+    var len;
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      len = a.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a[i] / b;
+      }
+      return arr;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      len = b.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a / b[i];
+      }
+      return arr;
+    }
+    return 0;
+  }
+  function mod(a, b) {
+    if (typeof a === 'string') {
+      a = parseInt(a, 10);
+    }
+    if (typeof b === 'string') {
+      b = parseInt(b, 10);
+    }
+    return a % b;
+  }
+  var $bm_sum = sum;
+  var $bm_sub = sub;
+  var $bm_mul = mul;
+  var $bm_div = div;
+  var $bm_mod = mod;
+
+  function clamp(num, min, max) {
+    if (min > max) {
+      var mm = max;
+      max = min;
+      min = mm;
+    }
+    return Math.min(Math.max(num, min), max);
+  }
+
+  function radiansToDegrees(val) {
+    return val / degToRads;
+  }
+  var radians_to_degrees = radiansToDegrees;
+
+  function degreesToRadians(val) {
+    return val * degToRads;
+  }
+  var degrees_to_radians = radiansToDegrees;
+
+  var helperLengthArray = [0, 0, 0, 0, 0, 0];
+
+  function length(arr1, arr2) {
+    if (typeof arr1 === 'number' || arr1 instanceof Number) {
+      arr2 = arr2 || 0;
+      return Math.abs(arr1 - arr2);
+    }
+    if (!arr2) {
+      arr2 = helperLengthArray;
+    }
+    var i;
+    var len = Math.min(arr1.length, arr2.length);
+    var addedLength = 0;
+    for (i = 0; i < len; i += 1) {
+      addedLength += Math.pow(arr2[i] - arr1[i], 2);
+    }
+    return Math.sqrt(addedLength);
+  }
+
+  function normalize(vec) {
+    return div(vec, length(vec));
+  }
+
+  function rgbToHsl(val) {
+    var r = val[0]; var g = val[1]; var b = val[2];
+    var max = Math.max(r, g, b);
+    var min = Math.min(r, g, b);
+    var h;
+    var s;
+    var l = (max + min) / 2;
+
+    if (max === min) {
+      h = 0; // achromatic
+      s = 0; // achromatic
+    } else {
+      var d = max - min;
+      s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+      switch (max) {
+        case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+        case g: h = (b - r) / d + 2; break;
+        case b: h = (r - g) / d + 4; break;
+        default: break;
+      }
+      h /= 6;
+    }
+
+    return [h, s, l, val[3]];
+  }
+
+  function hue2rgb(p, q, t) {
+    if (t < 0) t += 1;
+    if (t > 1) t -= 1;
+    if (t < 1 / 6) return p + (q - p) * 6 * t;
+    if (t < 1 / 2) return q;
+    if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
+    return p;
+  }
+
+  function hslToRgb(val) {
+    var h = val[0];
+    var s = val[1];
+    var l = val[2];
+
+    var r;
+    var g;
+    var b;
+
+    if (s === 0) {
+      r = l; // achromatic
+      b = l; // achromatic
+      g = l; // achromatic
+    } else {
+      var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+      var p = 2 * l - q;
+      r = hue2rgb(p, q, h + 1 / 3);
+      g = hue2rgb(p, q, h);
+      b = hue2rgb(p, q, h - 1 / 3);
+    }
+
+    return [r, g, b, val[3]];
+  }
+
+  function linear(t, tMin, tMax, value1, value2) {
+    if (value1 === undefined || value2 === undefined) {
+      value1 = tMin;
+      value2 = tMax;
+      tMin = 0;
+      tMax = 1;
+    }
+    if (tMax < tMin) {
+      var _tMin = tMax;
+      tMax = tMin;
+      tMin = _tMin;
+    }
+    if (t <= tMin) {
+      return value1;
+    } if (t >= tMax) {
+      return value2;
+    }
+    var perc = tMax === tMin ? 0 : (t - tMin) / (tMax - tMin);
+    if (!value1.length) {
+      return value1 + (value2 - value1) * perc;
+    }
+    var i;
+    var len = value1.length;
+    var arr = createTypedArray('float32', len);
+    for (i = 0; i < len; i += 1) {
+      arr[i] = value1[i] + (value2[i] - value1[i]) * perc;
+    }
+    return arr;
+  }
+  function random(min, max) {
+    if (max === undefined) {
+      if (min === undefined) {
+        min = 0;
+        max = 1;
+      } else {
+        max = min;
+        min = undefined;
+      }
+    }
+    if (max.length) {
+      var i;
+      var len = max.length;
+      if (!min) {
+        min = createTypedArray('float32', len);
+      }
+      var arr = createTypedArray('float32', len);
+      var rnd = BMMath.random();
+      for (i = 0; i < len; i += 1) {
+        arr[i] = min[i] + rnd * (max[i] - min[i]);
+      }
+      return arr;
+    }
+    if (min === undefined) {
+      min = 0;
+    }
+    var rndm = BMMath.random();
+    return min + rndm * (max - min);
+  }
+
+  function createPath(points, inTangents, outTangents, closed) {
+    var i;
+    var len = points.length;
+    var path = shapePool.newElement();
+    path.setPathData(!!closed, len);
+    var arrPlaceholder = [0, 0];
+    var inVertexPoint;
+    var outVertexPoint;
+    for (i = 0; i < len; i += 1) {
+      inVertexPoint = (inTangents && inTangents[i]) ? inTangents[i] : arrPlaceholder;
+      outVertexPoint = (outTangents && outTangents[i]) ? outTangents[i] : arrPlaceholder;
+      path.setTripleAt(points[i][0], points[i][1], outVertexPoint[0] + points[i][0], outVertexPoint[1] + points[i][1], inVertexPoint[0] + points[i][0], inVertexPoint[1] + points[i][1], i, true);
+    }
+    return path;
+  }
+
+  function initiateExpression(elem, data, property) {
+    // Bail out if we don't want expressions
+    function noOp(_value) {
+      return _value;
+    }
+    if (!elem.globalData.renderConfig.runExpressions) {
+      return noOp;
+    }
+
+    var val = data.x;
+    var needsVelocity = /velocity(?![\w\d])/.test(val);
+    var _needsRandom = val.indexOf('random') !== -1;
+    var elemType = elem.data.ty;
+    var transform;
+    var $bm_transform;
+    var content;
+    var effect;
+    var thisProperty = property;
+    thisProperty._name = elem.data.nm;
+    thisProperty.valueAtTime = thisProperty.getValueAtTime;
+    Object.defineProperty(thisProperty, 'value', {
+      get: function () {
+        return thisProperty.v;
+      },
+    });
+    elem.comp.frameDuration = 1 / elem.comp.globalData.frameRate;
+    elem.comp.displayStartTime = 0;
+    var inPoint = elem.data.ip / elem.comp.globalData.frameRate;
+    var outPoint = elem.data.op / elem.comp.globalData.frameRate;
+    var width = elem.data.sw ? elem.data.sw : 0;
+    var height = elem.data.sh ? elem.data.sh : 0;
+    var name = elem.data.nm;
+    var loopIn;
+    var loop_in;
+    var loopOut;
+    var loop_out;
+    var smooth;
+    var toWorld;
+    var fromWorld;
+    var fromComp;
+    var toComp;
+    var fromCompToSurface;
+    var position;
+    var rotation;
+    var anchorPoint;
+    var scale;
+    var thisLayer;
+    var thisComp;
+    var mask;
+    var valueAtTime;
+    var velocityAtTime;
+
+    var scoped_bm_rt;
+    // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
+    var expression_function = eval('[function _expression_function(){' + val + ';scoped_bm_rt=$bm_rt}]')[0]; // eslint-disable-line no-eval
+    var numKeys = property.kf ? data.k.length : 0;
+
+    var active = !this.data || this.data.hd !== true;
+
+    var wiggle = function wiggle(freq, amp) {
+      var iWiggle;
+      var j;
+      var lenWiggle = this.pv.length ? this.pv.length : 1;
+      var addedAmps = createTypedArray('float32', lenWiggle);
+      freq = 5;
+      var iterations = Math.floor(time * freq);
+      iWiggle = 0;
+      j = 0;
+      while (iWiggle < iterations) {
+        // var rnd = BMMath.random();
+        for (j = 0; j < lenWiggle; j += 1) {
+          addedAmps[j] += -amp + amp * 2 * BMMath.random();
+          // addedAmps[j] += -amp + amp*2*rnd;
+        }
+        iWiggle += 1;
+      }
+      // var rnd2 = BMMath.random();
+      var periods = time * freq;
+      var perc = periods - Math.floor(periods);
+      var arr = createTypedArray('float32', lenWiggle);
+      if (lenWiggle > 1) {
+        for (j = 0; j < lenWiggle; j += 1) {
+          arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc;
+          // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
+          // arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc);
+        }
+        return arr;
+      }
+      return this.pv + addedAmps[0] + (-amp + amp * 2 * BMMath.random()) * perc;
+    }.bind(this);
+
+    if (thisProperty.loopIn) {
+      loopIn = thisProperty.loopIn.bind(thisProperty);
+      loop_in = loopIn;
+    }
+
+    if (thisProperty.loopOut) {
+      loopOut = thisProperty.loopOut.bind(thisProperty);
+      loop_out = loopOut;
+    }
+
+    if (thisProperty.smooth) {
+      smooth = thisProperty.smooth.bind(thisProperty);
+    }
+
+    function loopInDuration(type, duration) {
+      return loopIn(type, duration, true);
+    }
+
+    function loopOutDuration(type, duration) {
+      return loopOut(type, duration, true);
+    }
+
+    if (this.getValueAtTime) {
+      valueAtTime = this.getValueAtTime.bind(this);
+    }
+
+    if (this.getVelocityAtTime) {
+      velocityAtTime = this.getVelocityAtTime.bind(this);
+    }
+
+    var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface);
+
+    function lookAt(elem1, elem2) {
+      var fVec = [elem2[0] - elem1[0], elem2[1] - elem1[1], elem2[2] - elem1[2]];
+      var pitch = Math.atan2(fVec[0], Math.sqrt(fVec[1] * fVec[1] + fVec[2] * fVec[2])) / degToRads;
+      var yaw = -Math.atan2(fVec[1], fVec[2]) / degToRads;
+      return [yaw, pitch, 0];
+    }
+
+    function easeOut(t, tMin, tMax, val1, val2) {
+      return applyEase(easeOutBez, t, tMin, tMax, val1, val2);
+    }
+
+    function easeIn(t, tMin, tMax, val1, val2) {
+      return applyEase(easeInBez, t, tMin, tMax, val1, val2);
+    }
+
+    function ease(t, tMin, tMax, val1, val2) {
+      return applyEase(easeInOutBez, t, tMin, tMax, val1, val2);
+    }
+
+    function applyEase(fn, t, tMin, tMax, val1, val2) {
+      if (val1 === undefined) {
+        val1 = tMin;
+        val2 = tMax;
+      } else {
+        t = (t - tMin) / (tMax - tMin);
+      }
+      if (t > 1) {
+        t = 1;
+      } else if (t < 0) {
+        t = 0;
+      }
+      var mult = fn(t);
+      if ($bm_isInstanceOfArray(val1)) {
+        var iKey;
+        var lenKey = val1.length;
+        var arr = createTypedArray('float32', lenKey);
+        for (iKey = 0; iKey < lenKey; iKey += 1) {
+          arr[iKey] = (val2[iKey] - val1[iKey]) * mult + val1[iKey];
+        }
+        return arr;
+      }
+      return (val2 - val1) * mult + val1;
+    }
+
+    function nearestKey(time) {
+      var iKey;
+      var lenKey = data.k.length;
+      var index;
+      var keyTime;
+      if (!data.k.length || typeof (data.k[0]) === 'number') {
+        index = 0;
+        keyTime = 0;
+      } else {
+        index = -1;
+        time *= elem.comp.globalData.frameRate;
+        if (time < data.k[0].t) {
+          index = 1;
+          keyTime = data.k[0].t;
+        } else {
+          for (iKey = 0; iKey < lenKey - 1; iKey += 1) {
+            if (time === data.k[iKey].t) {
+              index = iKey + 1;
+              keyTime = data.k[iKey].t;
+              break;
+            } else if (time > data.k[iKey].t && time < data.k[iKey + 1].t) {
+              if (time - data.k[iKey].t > data.k[iKey + 1].t - time) {
+                index = iKey + 2;
+                keyTime = data.k[iKey + 1].t;
+              } else {
+                index = iKey + 1;
+                keyTime = data.k[iKey].t;
+              }
+              break;
+            }
+          }
+          if (index === -1) {
+            index = iKey + 1;
+            keyTime = data.k[iKey].t;
+          }
+        }
+      }
+      var obKey = {};
+      obKey.index = index;
+      obKey.time = keyTime / elem.comp.globalData.frameRate;
+      return obKey;
+    }
+
+    function key(ind) {
+      var obKey;
+      var iKey;
+      var lenKey;
+      if (!data.k.length || typeof (data.k[0]) === 'number') {
+        throw new Error('The property has no keyframe at index ' + ind);
+      }
+      ind -= 1;
+      obKey = {
+        time: data.k[ind].t / elem.comp.globalData.frameRate,
+        value: [],
+      };
+      var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e;
+
+      lenKey = arr.length;
+      for (iKey = 0; iKey < lenKey; iKey += 1) {
+        obKey[iKey] = arr[iKey];
+        obKey.value[iKey] = arr[iKey];
+      }
+      return obKey;
+    }
+
+    function framesToTime(fr, fps) {
+      if (!fps) {
+        fps = elem.comp.globalData.frameRate;
+      }
+      return fr / fps;
+    }
+
+    function timeToFrames(t, fps) {
+      if (!t && t !== 0) {
+        t = time;
+      }
+      if (!fps) {
+        fps = elem.comp.globalData.frameRate;
+      }
+      return t * fps;
+    }
+
+    function seedRandom(seed) {
+      BMMath.seedrandom(randSeed + seed);
+    }
+
+    function sourceRectAtTime() {
+      return elem.sourceRectAtTime();
+    }
+
+    function substring(init, end) {
+      if (typeof value === 'string') {
+        if (end === undefined) {
+          return value.substring(init);
+        }
+        return value.substring(init, end);
+      }
+      return '';
+    }
+
+    function substr(init, end) {
+      if (typeof value === 'string') {
+        if (end === undefined) {
+          return value.substr(init);
+        }
+        return value.substr(init, end);
+      }
+      return '';
+    }
+
+    function posterizeTime(framesPerSecond) {
+      time = framesPerSecond === 0 ? 0 : Math.floor(time * framesPerSecond) / framesPerSecond;
+      value = valueAtTime(time);
+    }
+
+    var time;
+    var velocity;
+    var value;
+    var text;
+    var textIndex;
+    var textTotal;
+    var selectorValue;
+    var index = elem.data.ind;
+    var hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+    var parent;
+    var randSeed = Math.floor(Math.random() * 1000000);
+    var globalData = elem.globalData;
+
+    function executeExpression(_value) {
+      // globalData.pushExpression();
+      value = _value;
+      if (this.frameExpressionId === elem.globalData.frameId && this.propType !== 'textSelector') {
+        return value;
+      }
+      if (this.propType === 'textSelector') {
+        textIndex = this.textIndex;
+        textTotal = this.textTotal;
+        selectorValue = this.selectorValue;
+      }
+      if (!thisLayer) {
+        text = elem.layerInterface.text;
+        thisLayer = elem.layerInterface;
+        thisComp = elem.comp.compInterface;
+        toWorld = thisLayer.toWorld.bind(thisLayer);
+        fromWorld = thisLayer.fromWorld.bind(thisLayer);
+        fromComp = thisLayer.fromComp.bind(thisLayer);
+        toComp = thisLayer.toComp.bind(thisLayer);
+        mask = thisLayer.mask ? thisLayer.mask.bind(thisLayer) : null;
+        fromCompToSurface = fromComp;
+      }
+      if (!transform) {
+        transform = elem.layerInterface('ADBE Transform Group');
+        $bm_transform = transform;
+        if (transform) {
+          anchorPoint = transform.anchorPoint;
+          /* position = transform.position;
+                    rotation = transform.rotation;
+                    scale = transform.scale; */
+        }
+      }
+
+      if (elemType === 4 && !content) {
+        content = thisLayer('ADBE Root Vectors Group');
+      }
+      if (!effect) {
+        effect = thisLayer(4);
+      }
+      hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+      if (hasParent && !parent) {
+        parent = elem.hierarchy[0].layerInterface;
+      }
+      time = this.comp.renderedFrame / this.comp.globalData.frameRate;
+      if (_needsRandom) {
+        seedRandom(randSeed + time);
+      }
+      if (needsVelocity) {
+        velocity = velocityAtTime(time);
+      }
+      expression_function();
+      this.frameExpressionId = elem.globalData.frameId;
+
+      // TODO: Check if it's possible to return on ShapeInterface the .v value
+      // Changed this to a ternary operation because Rollup failed compiling it correctly
+      scoped_bm_rt = scoped_bm_rt.propType === propTypes.SHAPE
+        ? scoped_bm_rt.v
+        : scoped_bm_rt;
+      return scoped_bm_rt;
+    }
+    // Bundlers will see these as dead code and unless we reference them
+    executeExpression.__preventDeadCodeRemoval = [$bm_transform, anchorPoint, time, velocity, inPoint, outPoint, width, height, name, loop_in, loop_out, smooth, toComp, fromCompToSurface, toWorld, fromWorld, mask, position, rotation, scale, thisComp, numKeys, active, wiggle, loopInDuration, loopOutDuration, comp, lookAt, easeOut, easeIn, ease, nearestKey, key, text, textIndex, textTotal, selectorValue, framesToTime, timeToFrames, sourceRectAtTime, substring, substr, posterizeTime, index, globalData];
+    return executeExpression;
+  }
+
+  ob.initiateExpression = initiateExpression;
+  ob.__preventDeadCodeRemoval = [window, document, XMLHttpRequest, fetch, frames, $bm_neg, add, $bm_sum, $bm_sub, $bm_mul, $bm_div, $bm_mod, clamp, radians_to_degrees, degreesToRadians, degrees_to_radians, normalize, rgbToHsl, hslToRgb, linear, random, createPath, _lottieGlobal];
+  ob.resetFrame = resetFrame;
+  return ob;
+}());
+
+const Expressions = (function () {
+  var ob = {};
+  ob.initExpressions = initExpressions;
+  ob.resetFrame = ExpressionManager.resetFrame;
+
+  function initExpressions(animation) {
+    var stackCount = 0;
+    var registers = [];
+
+    function pushExpression() {
+      stackCount += 1;
+    }
+
+    function popExpression() {
+      stackCount -= 1;
+      if (stackCount === 0) {
+        releaseInstances();
+      }
+    }
+
+    function registerExpressionProperty(expression) {
+      if (registers.indexOf(expression) === -1) {
+        registers.push(expression);
+      }
+    }
+
+    function releaseInstances() {
+      var i;
+      var len = registers.length;
+      for (i = 0; i < len; i += 1) {
+        registers[i].release();
+      }
+      registers.length = 0;
+    }
+
+    animation.renderer.compInterface = CompExpressionInterface(animation.renderer);
+    animation.renderer.globalData.projectInterface.registerComposition(animation.renderer);
+    animation.renderer.globalData.pushExpression = pushExpression;
+    animation.renderer.globalData.popExpression = popExpression;
+    animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty;
+  }
+  return ob;
+}());
+
+const MaskManagerInterface = (function () {
+  function MaskInterface(mask, data) {
+    this._mask = mask;
+    this._data = data;
+  }
+  Object.defineProperty(MaskInterface.prototype, 'maskPath', {
+    get: function () {
+      if (this._mask.prop.k) {
+        this._mask.prop.getValue();
+      }
+      return this._mask.prop;
+    },
+  });
+  Object.defineProperty(MaskInterface.prototype, 'maskOpacity', {
+    get: function () {
+      if (this._mask.op.k) {
+        this._mask.op.getValue();
+      }
+      return this._mask.op.v * 100;
+    },
+  });
+
+  var MaskManager = function (maskManager) {
+    var _masksInterfaces = createSizedArray(maskManager.viewData.length);
+    var i;
+    var len = maskManager.viewData.length;
+    for (i = 0; i < len; i += 1) {
+      _masksInterfaces[i] = new MaskInterface(maskManager.viewData[i], maskManager.masksProperties[i]);
+    }
+
+    var maskFunction = function (name) {
+      i = 0;
+      while (i < len) {
+        if (maskManager.masksProperties[i].nm === name) {
+          return _masksInterfaces[i];
+        }
+        i += 1;
+      }
+      return null;
+    };
+    return maskFunction;
+  };
+  return MaskManager;
+}());
+
+const ExpressionPropertyInterface = (function () {
+  var defaultUnidimensionalValue = { pv: 0, v: 0, mult: 1 };
+  var defaultMultidimensionalValue = { pv: [0, 0, 0], v: [0, 0, 0], mult: 1 };
+
+  function completeProperty(expressionValue, property, type) {
+    Object.defineProperty(expressionValue, 'velocity', {
+      get: function () {
+        return property.getVelocityAtTime(property.comp.currentFrame);
+      },
+    });
+    expressionValue.numKeys = property.keyframes ? property.keyframes.length : 0;
+    expressionValue.key = function (pos) {
+      if (!expressionValue.numKeys) {
+        return 0;
+      }
+      var value = '';
+      if ('s' in property.keyframes[pos - 1]) {
+        value = property.keyframes[pos - 1].s;
+      } else if ('e' in property.keyframes[pos - 2]) {
+        value = property.keyframes[pos - 2].e;
+      } else {
+        value = property.keyframes[pos - 2].s;
+      }
+      var valueProp = type === 'unidimensional' ? new Number(value) : Object.assign({}, value); // eslint-disable-line no-new-wrappers
+      valueProp.time = property.keyframes[pos - 1].t / property.elem.comp.globalData.frameRate;
+      valueProp.value = type === 'unidimensional' ? value[0] : value;
+      return valueProp;
+    };
+    expressionValue.valueAtTime = property.getValueAtTime;
+    expressionValue.speedAtTime = property.getSpeedAtTime;
+    expressionValue.velocityAtTime = property.getVelocityAtTime;
+    expressionValue.propertyGroup = property.propertyGroup;
+  }
+
+  function UnidimensionalPropertyInterface(property) {
+    if (!property || !('pv' in property)) {
+      property = defaultUnidimensionalValue;
+    }
+    var mult = 1 / property.mult;
+    var val = property.pv * mult;
+    var expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
+    expressionValue.value = val;
+    completeProperty(expressionValue, property, 'unidimensional');
+
+    return function () {
+      if (property.k) {
+        property.getValue();
+      }
+      val = property.v * mult;
+      if (expressionValue.value !== val) {
+        expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
+        expressionValue.value = val;
+        expressionValue[0] = val;
+        completeProperty(expressionValue, property, 'unidimensional');
+      }
+      return expressionValue;
+    };
+  }
+
+  function MultidimensionalPropertyInterface(property) {
+    if (!property || !('pv' in property)) {
+      property = defaultMultidimensionalValue;
+    }
+    var mult = 1 / property.mult;
+    var len = (property.data && property.data.l) || property.pv.length;
+    var expressionValue = createTypedArray('float32', len);
+    var arrValue = createTypedArray('float32', len);
+    expressionValue.value = arrValue;
+    completeProperty(expressionValue, property, 'multidimensional');
+
+    return function () {
+      if (property.k) {
+        property.getValue();
+      }
+      for (var i = 0; i < len; i += 1) {
+        arrValue[i] = property.v[i] * mult;
+        expressionValue[i] = arrValue[i];
+      }
+      return expressionValue;
+    };
+  }
+
+  // TODO: try to avoid using this getter
+  function defaultGetter() {
+    return defaultUnidimensionalValue;
+  }
+
+  return function (property) {
+    if (!property) {
+      return defaultGetter;
+    } if (property.propType === 'unidimensional') {
+      return UnidimensionalPropertyInterface(property);
+    }
+    return MultidimensionalPropertyInterface(property);
+  };
+}());
+
+const TransformExpressionInterface = (function () {
+  return function (transform) {
+    function _thisFunction(name) {
+      switch (name) {
+        case 'scale':
+        case 'Scale':
+        case 'ADBE Scale':
+        case 6:
+          return _thisFunction.scale;
+        case 'rotation':
+        case 'Rotation':
+        case 'ADBE Rotation':
+        case 'ADBE Rotate Z':
+        case 10:
+          return _thisFunction.rotation;
+        case 'ADBE Rotate X':
+          return _thisFunction.xRotation;
+        case 'ADBE Rotate Y':
+          return _thisFunction.yRotation;
+        case 'position':
+        case 'Position':
+        case 'ADBE Position':
+        case 2:
+          return _thisFunction.position;
+        case 'ADBE Position_0':
+          return _thisFunction.xPosition;
+        case 'ADBE Position_1':
+          return _thisFunction.yPosition;
+        case 'ADBE Position_2':
+          return _thisFunction.zPosition;
+        case 'anchorPoint':
+        case 'AnchorPoint':
+        case 'Anchor Point':
+        case 'ADBE AnchorPoint':
+        case 1:
+          return _thisFunction.anchorPoint;
+        case 'opacity':
+        case 'Opacity':
+        case 11:
+          return _thisFunction.opacity;
+        default:
+          return null;
+      }
+    }
+    Object.defineProperty(_thisFunction, 'rotation', {
+      get: ExpressionPropertyInterface(transform.r || transform.rz),
+    });
+
+    Object.defineProperty(_thisFunction, 'zRotation', {
+      get: ExpressionPropertyInterface(transform.rz || transform.r),
+    });
+
+    Object.defineProperty(_thisFunction, 'xRotation', {
+      get: ExpressionPropertyInterface(transform.rx),
+    });
+
+    Object.defineProperty(_thisFunction, 'yRotation', {
+      get: ExpressionPropertyInterface(transform.ry),
+    });
+    Object.defineProperty(_thisFunction, 'scale', {
+      get: ExpressionPropertyInterface(transform.s),
+    });
+    var _px;
+    var _py;
+    var _pz;
+    var _transformFactory;
+    if (transform.p) {
+      _transformFactory = ExpressionPropertyInterface(transform.p);
+    } else {
+      _px = ExpressionPropertyInterface(transform.px);
+      _py = ExpressionPropertyInterface(transform.py);
+      if (transform.pz) {
+        _pz = ExpressionPropertyInterface(transform.pz);
+      }
+    }
+    Object.defineProperty(_thisFunction, 'position', {
+      get: function () {
+        if (transform.p) {
+          return _transformFactory();
+        }
+        return [
+          _px(),
+          _py(),
+          _pz ? _pz() : 0];
+      },
+    });
+
+    Object.defineProperty(_thisFunction, 'xPosition', {
+      get: ExpressionPropertyInterface(transform.px),
+    });
+
+    Object.defineProperty(_thisFunction, 'yPosition', {
+      get: ExpressionPropertyInterface(transform.py),
+    });
+
+    Object.defineProperty(_thisFunction, 'zPosition', {
+      get: ExpressionPropertyInterface(transform.pz),
+    });
+
+    Object.defineProperty(_thisFunction, 'anchorPoint', {
+      get: ExpressionPropertyInterface(transform.a),
+    });
+
+    Object.defineProperty(_thisFunction, 'opacity', {
+      get: ExpressionPropertyInterface(transform.o),
+    });
+
+    Object.defineProperty(_thisFunction, 'skew', {
+      get: ExpressionPropertyInterface(transform.sk),
+    });
+
+    Object.defineProperty(_thisFunction, 'skewAxis', {
+      get: ExpressionPropertyInterface(transform.sa),
+    });
+
+    Object.defineProperty(_thisFunction, 'orientation', {
+      get: ExpressionPropertyInterface(transform.or),
+    });
+
+    return _thisFunction;
+  };
+}());
+
+const LayerExpressionInterface = (function () {
+  function getMatrix(time) {
+    var toWorldMat = new Matrix();
+    if (time !== undefined) {
+      var propMatrix = this._elem.finalTransform.mProp.getValueAtTime(time);
+      propMatrix.clone(toWorldMat);
+    } else {
+      var transformMat = this._elem.finalTransform.mProp;
+      transformMat.applyToMatrix(toWorldMat);
+    }
+    return toWorldMat;
+  }
+
+  function toWorldVec(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    toWorldMat.props[12] = 0;
+    toWorldMat.props[13] = 0;
+    toWorldMat.props[14] = 0;
+    return this.applyPoint(toWorldMat, arr);
+  }
+
+  function toWorld(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    return this.applyPoint(toWorldMat, arr);
+  }
+
+  function fromWorldVec(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    toWorldMat.props[12] = 0;
+    toWorldMat.props[13] = 0;
+    toWorldMat.props[14] = 0;
+    return this.invertPoint(toWorldMat, arr);
+  }
+
+  function fromWorld(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    return this.invertPoint(toWorldMat, arr);
+  }
+
+  function applyPoint(matrix, arr) {
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
+      }
+    }
+    return matrix.applyToPointArray(arr[0], arr[1], arr[2] || 0);
+  }
+
+  function invertPoint(matrix, arr) {
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
+      }
+    }
+    return matrix.inversePoint(arr);
+  }
+
+  function fromComp(arr) {
+    var toWorldMat = new Matrix();
+    toWorldMat.reset();
+    this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
+      }
+      return toWorldMat.inversePoint(arr);
+    }
+    return toWorldMat.inversePoint(arr);
+  }
+
+  function sampleImage() {
+    return [1, 1, 1, 1];
+  }
+
+  return function (elem) {
+    var transformInterface;
+
+    function _registerMaskInterface(maskManager) {
+      _thisLayerFunction.mask = new MaskManagerInterface(maskManager, elem);
+    }
+    function _registerEffectsInterface(effects) {
+      _thisLayerFunction.effect = effects;
+    }
+
+    function _thisLayerFunction(name) {
+      switch (name) {
+        case 'ADBE Root Vectors Group':
+        case 'Contents':
+        case 2:
+          return _thisLayerFunction.shapeInterface;
+        case 1:
+        case 6:
+        case 'Transform':
+        case 'transform':
+        case 'ADBE Transform Group':
+          return transformInterface;
+        case 4:
+        case 'ADBE Effect Parade':
+        case 'effects':
+        case 'Effects':
+          return _thisLayerFunction.effect;
+        case 'ADBE Text Properties':
+          return _thisLayerFunction.textInterface;
+        default:
+          return null;
+      }
+    }
+    _thisLayerFunction.getMatrix = getMatrix;
+    _thisLayerFunction.invertPoint = invertPoint;
+    _thisLayerFunction.applyPoint = applyPoint;
+    _thisLayerFunction.toWorld = toWorld;
+    _thisLayerFunction.toWorldVec = toWorldVec;
+    _thisLayerFunction.fromWorld = fromWorld;
+    _thisLayerFunction.fromWorldVec = fromWorldVec;
+    _thisLayerFunction.toComp = toWorld;
+    _thisLayerFunction.fromComp = fromComp;
+    _thisLayerFunction.sampleImage = sampleImage;
+    _thisLayerFunction.sourceRectAtTime = elem.sourceRectAtTime.bind(elem);
+    _thisLayerFunction._elem = elem;
+    transformInterface = TransformExpressionInterface(elem.finalTransform.mProp);
+    var anchorPointDescriptor = getDescriptor(transformInterface, 'anchorPoint');
+    Object.defineProperties(_thisLayerFunction, {
+      hasParent: {
+        get: function () {
+          return elem.hierarchy.length;
+        },
+      },
+      parent: {
+        get: function () {
+          return elem.hierarchy[0].layerInterface;
+        },
+      },
+      rotation: getDescriptor(transformInterface, 'rotation'),
+      scale: getDescriptor(transformInterface, 'scale'),
+      position: getDescriptor(transformInterface, 'position'),
+      opacity: getDescriptor(transformInterface, 'opacity'),
+      anchorPoint: anchorPointDescriptor,
+      anchor_point: anchorPointDescriptor,
+      transform: {
+        get: function () {
+          return transformInterface;
+        },
+      },
+      active: {
+        get: function () {
+          return elem.isInRange;
+        },
+      },
+    });
+
+    _thisLayerFunction.startTime = elem.data.st;
+    _thisLayerFunction.index = elem.data.ind;
+    _thisLayerFunction.source = elem.data.refId;
+    _thisLayerFunction.height = elem.data.ty === 0 ? elem.data.h : 100;
+    _thisLayerFunction.width = elem.data.ty === 0 ? elem.data.w : 100;
+    _thisLayerFunction.inPoint = elem.data.ip / elem.comp.globalData.frameRate;
+    _thisLayerFunction.outPoint = elem.data.op / elem.comp.globalData.frameRate;
+    _thisLayerFunction._name = elem.data.nm;
+
+    _thisLayerFunction.registerMaskInterface = _registerMaskInterface;
+    _thisLayerFunction.registerEffectsInterface = _registerEffectsInterface;
+    return _thisLayerFunction;
+  };
+}());
+
+const propertyGroupFactory = (function () {
+  return function (interfaceFunction, parentPropertyGroup) {
+    return function (val) {
+      val = val === undefined ? 1 : val;
+      if (val <= 0) {
+        return interfaceFunction;
+      }
+      return parentPropertyGroup(val - 1);
+    };
+  };
+}());
+
+const PropertyInterface = (function () {
+  return function (propertyName, propertyGroup) {
+    var interfaceFunction = {
+      _name: propertyName,
+    };
+
+    function _propertyGroup(val) {
+      val = val === undefined ? 1 : val;
+      if (val <= 0) {
+        return interfaceFunction;
+      }
+      return propertyGroup(val - 1);
+    }
+
+    return _propertyGroup;
+  };
+}());
+
+const EffectsExpressionInterface = (function () {
+  var ob = {
+    createEffectsInterface: createEffectsInterface,
+  };
+
+  function createEffectsInterface(elem, propertyGroup) {
+    if (elem.effectsManager) {
+      var effectElements = [];
+      var effectsData = elem.data.ef;
+      var i;
+      var len = elem.effectsManager.effectElements.length;
+      for (i = 0; i < len; i += 1) {
+        effectElements.push(createGroupInterface(effectsData[i], elem.effectsManager.effectElements[i], propertyGroup, elem));
+      }
+
+      var effects = elem.data.ef || [];
+      var groupInterface = function (name) {
+        i = 0;
+        len = effects.length;
+        while (i < len) {
+          if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
+            return effectElements[i];
+          }
+          i += 1;
+        }
+        return null;
+      };
+      Object.defineProperty(groupInterface, 'numProperties', {
+        get: function () {
+          return effects.length;
+        },
+      });
+      return groupInterface;
+    }
+    return null;
+  }
+
+  function createGroupInterface(data, elements, propertyGroup, elem) {
+    function groupInterface(name) {
+      var effects = data.ef;
+      var i = 0;
+      var len = effects.length;
+      while (i < len) {
+        if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
+          if (effects[i].ty === 5) {
+            return effectElements[i];
+          }
+          return effectElements[i]();
+        }
+        i += 1;
+      }
+      throw new Error();
+    }
+    var _propertyGroup = propertyGroupFactory(groupInterface, propertyGroup);
+
+    var effectElements = [];
+    var i;
+    var len = data.ef.length;
+    for (i = 0; i < len; i += 1) {
+      if (data.ef[i].ty === 5) {
+        effectElements.push(createGroupInterface(data.ef[i], elements.effectElements[i], elements.effectElements[i].propertyGroup, elem));
+      } else {
+        effectElements.push(createValueInterface(elements.effectElements[i], data.ef[i].ty, elem, _propertyGroup));
+      }
+    }
+
+    if (data.mn === 'ADBE Color Control') {
+      Object.defineProperty(groupInterface, 'color', {
+        get: function () {
+          return effectElements[0]();
+        },
+      });
+    }
+    Object.defineProperties(groupInterface, {
+      numProperties: {
+        get: function () {
+          return data.np;
+        },
+      },
+      _name: { value: data.nm },
+      propertyGroup: { value: _propertyGroup },
+    });
+    groupInterface.enabled = data.en !== 0;
+    groupInterface.active = groupInterface.enabled;
+    return groupInterface;
+  }
+
+  function createValueInterface(element, type, elem, propertyGroup) {
+    var expressionProperty = ExpressionPropertyInterface(element.p);
+    function interfaceFunction() {
+      if (type === 10) {
+        return elem.comp.compInterface(element.p.v);
+      }
+      return expressionProperty();
+    }
+
+    if (element.p.setGroupProperty) {
+      element.p.setGroupProperty(PropertyInterface('', propertyGroup));
+    }
+
+    return interfaceFunction;
+  }
+
+  return ob;
+}());
+
+const ShapePathInterface = (
+
+  function () {
+    return function pathInterfaceFactory(shape, view, propertyGroup) {
+      var prop = view.sh;
+
+      function interfaceFunction(val) {
+        if (val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2) {
+          return interfaceFunction.path;
+        }
+        return null;
+      }
+
+      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+      prop.setGroupProperty(PropertyInterface('Path', _propertyGroup));
+      Object.defineProperties(interfaceFunction, {
+        path: {
+          get: function () {
+            if (prop.k) {
+              prop.getValue();
+            }
+            return prop;
+          },
+        },
+        shape: {
+          get: function () {
+            if (prop.k) {
+              prop.getValue();
+            }
+            return prop;
+          },
+        },
+        _name: { value: shape.nm },
+        ix: { value: shape.ix },
+        propertyIndex: { value: shape.ix },
+        mn: { value: shape.mn },
+        propertyGroup: { value: propertyGroup },
+      });
+      return interfaceFunction;
+    };
+  }()
+);
+
+const ShapeExpressionInterface = (function () {
+  function iterateElements(shapes, view, propertyGroup) {
+    var arr = [];
+    var i;
+    var len = shapes ? shapes.length : 0;
+    for (i = 0; i < len; i += 1) {
+      if (shapes[i].ty === 'gr') {
+        arr.push(groupInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'fl') {
+        arr.push(fillInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'st') {
+        arr.push(strokeInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'tm') {
+        arr.push(trimInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'tr') {
+        // arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
+      } else if (shapes[i].ty === 'el') {
+        arr.push(ellipseInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'sr') {
+        arr.push(starInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'sh') {
+        arr.push(ShapePathInterface(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'rc') {
+        arr.push(rectInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'rd') {
+        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;
+  }
+
+  function contentsInterfaceFactory(shape, view, propertyGroup) {
+    var interfaces;
+    var interfaceFunction = function _interfaceFunction(value) {
+      var i = 0;
+      var len = interfaces.length;
+      while (i < len) {
+        if (interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value) {
+          return interfaces[i];
+        }
+        i += 1;
+      }
+      if (typeof value === 'number') {
+        return interfaces[value - 1];
+      }
+      return null;
+    };
+
+    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup);
+    interfaceFunction.numProperties = interfaces.length;
+    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
+    interfaceFunction.transform = transformInterface;
+    interfaceFunction.propertyIndex = shape.cix;
+    interfaceFunction._name = shape.nm;
+
+    return interfaceFunction;
+  }
+
+  function groupInterfaceFactory(shape, view, propertyGroup) {
+    var interfaceFunction = function _interfaceFunction(value) {
+      switch (value) {
+        case 'ADBE Vectors Group':
+        case 'Contents':
+        case 2:
+          return interfaceFunction.content;
+          // Not necessary for now. Keeping them here in case a new case appears
+          // case 'ADBE Vector Transform Group':
+          // case 3:
+        default:
+          return interfaceFunction.transform;
+      }
+    };
+    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var content = contentsInterfaceFactory(shape, view, interfaceFunction.propertyGroup);
+    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
+    interfaceFunction.content = content;
+    interfaceFunction.transform = transformInterface;
+    Object.defineProperty(interfaceFunction, '_name', {
+      get: function () {
+        return shape.nm;
+      },
+    });
+    // interfaceFunction.content = interfaceFunction;
+    interfaceFunction.numProperties = shape.np;
+    interfaceFunction.propertyIndex = shape.ix;
+    interfaceFunction.nm = shape.nm;
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function fillInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      if (val === 'Color' || val === 'color') {
+        return interfaceFunction.color;
+      } if (val === 'Opacity' || val === 'opacity') {
+        return interfaceFunction.opacity;
+      }
+      return null;
+    }
+    Object.defineProperties(interfaceFunction, {
+      color: {
+        get: ExpressionPropertyInterface(view.c),
+      },
+      opacity: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      _name: { value: shape.nm },
+      mn: { value: shape.mn },
+    });
+
+    view.c.setGroupProperty(PropertyInterface('Color', propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
+    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 () {
+          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() {
+    function interfaceFunction() {
+      return null;
+    }
+    return interfaceFunction;
+  }
+
+  function strokeInterfaceFactory(shape, view, propertyGroup) {
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup);
+    function addPropertyToDashOb(i) {
+      Object.defineProperty(dashOb, shape.d[i].nm, {
+        get: ExpressionPropertyInterface(view.d.dataProps[i].p),
+      });
+    }
+    var i;
+    var len = shape.d ? shape.d.length : 0;
+    var dashOb = {};
+    for (i = 0; i < len; i += 1) {
+      addPropertyToDashOb(i);
+      view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup);
+    }
+
+    function interfaceFunction(val) {
+      if (val === 'Color' || val === 'color') {
+        return interfaceFunction.color;
+      } if (val === 'Opacity' || val === 'opacity') {
+        return interfaceFunction.opacity;
+      } if (val === 'Stroke Width' || val === 'stroke width') {
+        return interfaceFunction.strokeWidth;
+      }
+      return null;
+    }
+    Object.defineProperties(interfaceFunction, {
+      color: {
+        get: ExpressionPropertyInterface(view.c),
+      },
+      opacity: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      strokeWidth: {
+        get: ExpressionPropertyInterface(view.w),
+      },
+      dash: {
+        get: function () {
+          return dashOb;
+        },
+      },
+      _name: { value: shape.nm },
+      mn: { value: shape.mn },
+    });
+
+    view.c.setGroupProperty(PropertyInterface('Color', _propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    view.w.setGroupProperty(PropertyInterface('Stroke Width', _propertyGroup));
+    return interfaceFunction;
+  }
+
+  function trimInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      if (val === shape.e.ix || val === 'End' || val === 'end') {
+        return interfaceFunction.end;
+      }
+      if (val === shape.s.ix) {
+        return interfaceFunction.start;
+      }
+      if (val === shape.o.ix) {
+        return interfaceFunction.offset;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaceFunction.propertyIndex = shape.ix;
+
+    view.s.setGroupProperty(PropertyInterface('Start', _propertyGroup));
+    view.e.setGroupProperty(PropertyInterface('End', _propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
+    interfaceFunction.propertyIndex = shape.ix;
+    interfaceFunction.propertyGroup = propertyGroup;
+
+    Object.defineProperties(interfaceFunction, {
+      start: {
+        get: ExpressionPropertyInterface(view.s),
+      },
+      end: {
+        get: ExpressionPropertyInterface(view.e),
+      },
+      offset: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function transformInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.a.ix === value || value === 'Anchor Point') {
+        return interfaceFunction.anchorPoint;
+      }
+      if (shape.o.ix === value || value === 'Opacity') {
+        return interfaceFunction.opacity;
+      }
+      if (shape.p.ix === value || value === 'Position') {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value || value === 'Rotation' || value === 'ADBE Vector Rotation') {
+        return interfaceFunction.rotation;
+      }
+      if (shape.s.ix === value || value === 'Scale') {
+        return interfaceFunction.scale;
+      }
+      if ((shape.sk && shape.sk.ix === value) || value === 'Skew') {
+        return interfaceFunction.skew;
+      }
+      if ((shape.sa && shape.sa.ix === value) || value === 'Skew Axis') {
+        return interfaceFunction.skewAxis;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    view.transform.mProps.a.setGroupProperty(PropertyInterface('Anchor Point', _propertyGroup));
+    view.transform.mProps.s.setGroupProperty(PropertyInterface('Scale', _propertyGroup));
+    view.transform.mProps.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+    if (view.transform.mProps.sk) {
+      view.transform.mProps.sk.setGroupProperty(PropertyInterface('Skew', _propertyGroup));
+      view.transform.mProps.sa.setGroupProperty(PropertyInterface('Skew Angle', _propertyGroup));
+    }
+    view.transform.op.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    Object.defineProperties(interfaceFunction, {
+      opacity: {
+        get: ExpressionPropertyInterface(view.transform.mProps.o),
+      },
+      position: {
+        get: ExpressionPropertyInterface(view.transform.mProps.p),
+      },
+      anchorPoint: {
+        get: ExpressionPropertyInterface(view.transform.mProps.a),
+      },
+      scale: {
+        get: ExpressionPropertyInterface(view.transform.mProps.s),
+      },
+      rotation: {
+        get: ExpressionPropertyInterface(view.transform.mProps.r),
+      },
+      skew: {
+        get: ExpressionPropertyInterface(view.transform.mProps.sk),
+      },
+      skewAxis: {
+        get: ExpressionPropertyInterface(view.transform.mProps.sa),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.ty = 'tr';
+    interfaceFunction.mn = shape.mn;
+    interfaceFunction.propertyGroup = propertyGroup;
+    return interfaceFunction;
+  }
+
+  function ellipseInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.s.ix === value) {
+        return interfaceFunction.size;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaceFunction.propertyIndex = shape.ix;
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      size: {
+        get: ExpressionPropertyInterface(prop.s),
+      },
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function starInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value) {
+        return interfaceFunction.rotation;
+      }
+      if (shape.pt.ix === value) {
+        return interfaceFunction.points;
+      }
+      if (shape.or.ix === value || value === 'ADBE Vector Star Outer Radius') {
+        return interfaceFunction.outerRadius;
+      }
+      if (shape.os.ix === value) {
+        return interfaceFunction.outerRoundness;
+      }
+      if (shape.ir && (shape.ir.ix === value || value === 'ADBE Vector Star Inner Radius')) {
+        return interfaceFunction.innerRadius;
+      }
+      if (shape.is && shape.is.ix === value) {
+        return interfaceFunction.innerRoundness;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.or.setGroupProperty(PropertyInterface('Outer Radius', _propertyGroup));
+    prop.os.setGroupProperty(PropertyInterface('Outer Roundness', _propertyGroup));
+    prop.pt.setGroupProperty(PropertyInterface('Points', _propertyGroup));
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+    if (shape.ir) {
+      prop.ir.setGroupProperty(PropertyInterface('Inner Radius', _propertyGroup));
+      prop.is.setGroupProperty(PropertyInterface('Inner Roundness', _propertyGroup));
+    }
+
+    Object.defineProperties(interfaceFunction, {
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      rotation: {
+        get: ExpressionPropertyInterface(prop.r),
+      },
+      points: {
+        get: ExpressionPropertyInterface(prop.pt),
+      },
+      outerRadius: {
+        get: ExpressionPropertyInterface(prop.or),
+      },
+      outerRoundness: {
+        get: ExpressionPropertyInterface(prop.os),
+      },
+      innerRadius: {
+        get: ExpressionPropertyInterface(prop.ir),
+      },
+      innerRoundness: {
+        get: ExpressionPropertyInterface(prop.is),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function rectInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value) {
+        return interfaceFunction.roundness;
+      }
+      if (shape.s.ix === value || value === 'Size' || value === 'ADBE Vector Rect Size') {
+        return interfaceFunction.size;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
+    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      roundness: {
+        get: ExpressionPropertyInterface(prop.r),
+      },
+      size: {
+        get: ExpressionPropertyInterface(prop.s),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function roundedInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.r.ix === value || value === 'Round Corners 1') {
+        return interfaceFunction.radius;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.rd.setGroupProperty(PropertyInterface('Radius', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      radius: {
+        get: ExpressionPropertyInterface(prop.rd),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function repeaterInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.c.ix === value || value === 'Copies') {
+        return interfaceFunction.copies;
+      } if (shape.o.ix === value || value === 'Offset') {
+        return interfaceFunction.offset;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.c.setGroupProperty(PropertyInterface('Copies', _propertyGroup));
+    prop.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
+    Object.defineProperties(interfaceFunction, {
+      copies: {
+        get: ExpressionPropertyInterface(prop.c),
+      },
+      offset: {
+        get: ExpressionPropertyInterface(prop.o),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  return function (shapes, view, propertyGroup) {
+    var interfaces;
+    function _interfaceFunction(value) {
+      if (typeof value === 'number') {
+        value = value === undefined ? 1 : value;
+        if (value === 0) {
+          return propertyGroup;
+        }
+        return interfaces[value - 1];
+      }
+      var i = 0;
+      var len = interfaces.length;
+      while (i < len) {
+        if (interfaces[i]._name === value) {
+          return interfaces[i];
+        }
+        i += 1;
+      }
+      return null;
+    }
+    function parentGroupWrapper() {
+      return propertyGroup;
+    }
+    _interfaceFunction.propertyGroup = propertyGroupFactory(_interfaceFunction, parentGroupWrapper);
+    interfaces = iterateElements(shapes, view, _interfaceFunction.propertyGroup);
+    _interfaceFunction.numProperties = interfaces.length;
+    _interfaceFunction._name = 'Contents';
+    return _interfaceFunction;
+  };
+}());
+
+const TextExpressionInterface = (function () {
+  return function (elem) {
+    var _sourceText;
+    function _thisLayerFunction(name) {
+      switch (name) {
+        case 'ADBE Text Document':
+          return _thisLayerFunction.sourceText;
+        default:
+          return null;
+      }
+    }
+    Object.defineProperty(_thisLayerFunction, 'sourceText', {
+      get: function () {
+        elem.textProperty.getValue();
+        var stringValue = elem.textProperty.currentData.t;
+        if (!_sourceText || stringValue !== _sourceText.value) {
+          _sourceText = new String(stringValue); // eslint-disable-line no-new-wrappers
+          // If stringValue is an empty string, eval returns undefined, so it has to be returned as a String primitive
+          _sourceText.value = stringValue || new String(stringValue); // eslint-disable-line no-new-wrappers
+          Object.defineProperty(_sourceText, 'style', {
+            get: function () {
+              return {
+                fillColor: elem.textProperty.currentData.fc,
+              };
+            },
+          });
+        }
+        return _sourceText;
+      },
+    });
+    return _thisLayerFunction;
+  };
+}());
+
+const FootageInterface = (function () {
+  var outlineInterfaceFactory = (function (elem) {
+    var currentPropertyName = '';
+    var currentProperty = elem.getFootageData();
+    function init() {
+      currentPropertyName = '';
+      currentProperty = elem.getFootageData();
+      return searchProperty;
+    }
+    function searchProperty(value) {
+      if (currentProperty[value]) {
+        currentPropertyName = value;
+        currentProperty = currentProperty[value];
+        if (typeof currentProperty === 'object') {
+          return searchProperty;
+        }
+        return currentProperty;
+      }
+      var propertyNameIndex = value.indexOf(currentPropertyName);
+      if (propertyNameIndex !== -1) {
+        var index = parseInt(value.substr(propertyNameIndex + currentPropertyName.length), 10);
+        currentProperty = currentProperty[index];
+        if (typeof currentProperty === 'object') {
+          return searchProperty;
+        }
+        return currentProperty;
+      }
+      return '';
+    }
+    return init;
+  });
+
+  var dataInterfaceFactory = function (elem) {
+    function interfaceFunction(value) {
+      if (value === 'Outline') {
+        return interfaceFunction.outlineInterface();
+      }
+      return null;
+    }
+
+    interfaceFunction._name = 'Outline';
+    interfaceFunction.outlineInterface = outlineInterfaceFactory(elem);
+    return interfaceFunction;
+  };
+
+  return function (elem) {
+    function _interfaceFunction(value) {
+      if (value === 'Data') {
+        return _interfaceFunction.dataInterface;
+      }
+      return null;
+    }
+
+    _interfaceFunction._name = 'Data';
+    _interfaceFunction.dataInterface = dataInterfaceFactory(elem);
+    return _interfaceFunction;
+  };
+}());
+
+var interfaces = {
+  layer: LayerExpressionInterface,
+  effects: EffectsExpressionInterface,
+  comp: CompExpressionInterface,
+  shape: ShapeExpressionInterface,
+  text: TextExpressionInterface,
+  footage: FootageInterface,
+};
+
+function getInterface(type) {
+  return interfaces[type] || null;
+}
+
+const expressionHelpers = (function () {
+  function searchExpressions(elem, data, prop) {
+    if (data.x) {
+      prop.k = true;
+      prop.x = true;
+      prop.initiateExpression = ExpressionManager.initiateExpression;
+      prop.effectsSequence.push(prop.initiateExpression(elem, data, prop).bind(prop));
+    }
+  }
+
+  function getValueAtTime(frameNum) {
+    frameNum *= this.elem.globalData.frameRate;
+    frameNum -= this.offsetTime;
+    if (frameNum !== this._cachingAtTime.lastFrame) {
+      this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0;
+      this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime);
+      this._cachingAtTime.lastFrame = frameNum;
+    }
+    return this._cachingAtTime.value;
+  }
+
+  function getSpeedAtTime(frameNum) {
+    var delta = -0.01;
+    var v1 = this.getValueAtTime(frameNum);
+    var v2 = this.getValueAtTime(frameNum + delta);
+    var speed = 0;
+    if (v1.length) {
+      var i;
+      for (i = 0; i < v1.length; i += 1) {
+        speed += Math.pow(v2[i] - v1[i], 2);
+      }
+      speed = Math.sqrt(speed) * 100;
+    } else {
+      speed = 0;
+    }
+    return speed;
+  }
+
+  function getVelocityAtTime(frameNum) {
+    if (this.vel !== undefined) {
+      return this.vel;
+    }
+    var delta = -0.001;
+    // frameNum += this.elem.data.st;
+    var v1 = this.getValueAtTime(frameNum);
+    var v2 = this.getValueAtTime(frameNum + delta);
+    var velocity;
+    if (v1.length) {
+      velocity = createTypedArray('float32', v1.length);
+      var i;
+      for (i = 0; i < v1.length; i += 1) {
+        // removing frameRate
+        // if needed, don't add it here
+        // velocity[i] = this.elem.globalData.frameRate*((v2[i] - v1[i])/delta);
+        velocity[i] = (v2[i] - v1[i]) / delta;
+      }
+    } else {
+      velocity = (v2 - v1) / delta;
+    }
+    return velocity;
+  }
+
+  function getStaticValueAtTime() {
+    return this.pv;
+  }
+
+  function setGroupProperty(propertyGroup) {
+    this.propertyGroup = propertyGroup;
+  }
+
+  return {
+    searchExpressions: searchExpressions,
+    getSpeedAtTime: getSpeedAtTime,
+    getVelocityAtTime: getVelocityAtTime,
+    getValueAtTime: getValueAtTime,
+    getStaticValueAtTime: getStaticValueAtTime,
+    setGroupProperty: setGroupProperty,
+  };
+}());
+
+function addPropertyDecorator() {
+  function loopOut(type, duration, durationFlag) {
+    if (!this.k || !this.keyframes) {
+      return this.pv;
+    }
+    type = type ? type.toLowerCase() : '';
+    var currentFrame = this.comp.renderedFrame;
+    var keyframes = this.keyframes;
+    var lastKeyFrame = keyframes[keyframes.length - 1].t;
+    if (currentFrame <= lastKeyFrame) {
+      return this.pv;
+    }
+    var cycleDuration;
+    var firstKeyFrame;
+    if (!durationFlag) {
+      if (!duration || duration > keyframes.length - 1) {
+        duration = keyframes.length - 1;
+      }
+      firstKeyFrame = keyframes[keyframes.length - 1 - duration].t;
+      cycleDuration = lastKeyFrame - firstKeyFrame;
+    } else {
+      if (!duration) {
+        cycleDuration = Math.max(0, lastKeyFrame - this.elem.data.ip);
+      } else {
+        cycleDuration = Math.abs(lastKeyFrame - this.elem.comp.globalData.frameRate * duration);
+      }
+      firstKeyFrame = lastKeyFrame - cycleDuration;
+    }
+    var i;
+    var len;
+    var ret;
+    if (type === 'pingpong') {
+      var iterations = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
+      if (iterations % 2 !== 0) {
+          return this.getValueAtTime(((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      }
+    } else if (type === 'offset') {
+      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+        var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      var repeats = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
+      if (this.pv.length) {
+        ret = new Array(initV.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = (endV[i] - initV[i]) * repeats + current[i];
+        }
+        return ret;
+      }
+      return (endV - initV) * repeats + current;
+    } else if (type === 'continue') {
+      var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+      var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0);
+      if (this.pv.length) {
+        ret = new Array(lastValue.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+            ret[i] = lastValue[i] + (lastValue[i] - nextLastValue[i]) * ((currentFrame - lastKeyFrame) / this.comp.globalData.frameRate) / 0.0005; // eslint-disable-line
+        }
+        return ret;
+      }
+      return lastValue + (lastValue - nextLastValue) * (((currentFrame - lastKeyFrame)) / 0.001);
+    }
+      return this.getValueAtTime((((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+
+  }
+
+  function loopIn(type, duration, durationFlag) {
+    if (!this.k) {
+      return this.pv;
+    }
+    type = type ? type.toLowerCase() : '';
+    var currentFrame = this.comp.renderedFrame;
+    var keyframes = this.keyframes;
+    var firstKeyFrame = keyframes[0].t;
+    if (currentFrame >= firstKeyFrame) {
+      return this.pv;
+    }
+    var cycleDuration;
+    var lastKeyFrame;
+    if (!durationFlag) {
+      if (!duration || duration > keyframes.length - 1) {
+        duration = keyframes.length - 1;
+      }
+      lastKeyFrame = keyframes[duration].t;
+      cycleDuration = lastKeyFrame - firstKeyFrame;
+    } else {
+      if (!duration) {
+        cycleDuration = Math.max(0, this.elem.data.op - firstKeyFrame);
+      } else {
+        cycleDuration = Math.abs(this.elem.comp.globalData.frameRate * duration);
+      }
+      lastKeyFrame = firstKeyFrame + cycleDuration;
+    }
+    var i;
+    var len;
+    var ret;
+    if (type === 'pingpong') {
+      var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration);
+      if (iterations % 2 === 0) {
+          return this.getValueAtTime((((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      }
+    } else if (type === 'offset') {
+      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+      var current = this.getValueAtTime((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration) + firstKeyFrame) / this.comp.globalData.frameRate, 0);
+      var repeats = Math.floor((firstKeyFrame - currentFrame) / cycleDuration) + 1;
+      if (this.pv.length) {
+        ret = new Array(initV.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = current[i] - (endV[i] - initV[i]) * repeats;
+        }
+        return ret;
+      }
+      return current - (endV - initV) * repeats;
+    } else if (type === 'continue') {
+      var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0);
+      if (this.pv.length) {
+        ret = new Array(firstValue.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = firstValue[i] + ((firstValue[i] - nextFirstValue[i]) * (firstKeyFrame - currentFrame)) / 0.001;
+        }
+        return ret;
+      }
+      return firstValue + ((firstValue - nextFirstValue) * (firstKeyFrame - currentFrame)) / 0.001;
+    }
+      return this.getValueAtTime(((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame))) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+
+  }
+
+  function smooth(width, samples) {
+    if (!this.k) {
+      return this.pv;
+    }
+    width = (width || 0.4) * 0.5;
+    samples = Math.floor(samples || 5);
+    if (samples <= 1) {
+      return this.pv;
+    }
+    var currentTime = this.comp.renderedFrame / this.comp.globalData.frameRate;
+    var initFrame = currentTime - width;
+    var endFrame = currentTime + width;
+    var sampleFrequency = samples > 1 ? (endFrame - initFrame) / (samples - 1) : 1;
+    var i = 0;
+    var j = 0;
+    var value;
+    if (this.pv.length) {
+      value = createTypedArray('float32', this.pv.length);
+    } else {
+      value = 0;
+    }
+    var sampleValue;
+    while (i < samples) {
+      sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency);
+      if (this.pv.length) {
+        for (j = 0; j < this.pv.length; j += 1) {
+          value[j] += sampleValue[j];
+        }
+      } else {
+        value += sampleValue;
+      }
+      i += 1;
+    }
+    if (this.pv.length) {
+      for (j = 0; j < this.pv.length; j += 1) {
+        value[j] /= samples;
+      }
+    } else {
+      value /= samples;
+    }
+    return value;
+  }
+
+  function getTransformValueAtTime(time) {
+    if (!this._transformCachingAtTime) {
+      this._transformCachingAtTime = {
+        v: new Matrix(),
+      };
+    }
+    /// /
+    var matrix = this._transformCachingAtTime.v;
+    matrix.cloneFromProps(this.pre.props);
+    if (this.appliedTransformations < 1) {
+      var anchor = this.a.getValueAtTime(time);
+      matrix.translate(
+        -anchor[0] * this.a.mult,
+        -anchor[1] * this.a.mult,
+        anchor[2] * this.a.mult
+      );
+    }
+    if (this.appliedTransformations < 2) {
+      var scale = this.s.getValueAtTime(time);
+      matrix.scale(
+        scale[0] * this.s.mult,
+        scale[1] * this.s.mult,
+        scale[2] * this.s.mult
+      );
+    }
+    if (this.sk && this.appliedTransformations < 3) {
+      var skew = this.sk.getValueAtTime(time);
+      var skewAxis = this.sa.getValueAtTime(time);
+      matrix.skewFromAxis(-skew * this.sk.mult, skewAxis * this.sa.mult);
+    }
+    if (this.r && this.appliedTransformations < 4) {
+      var rotation = this.r.getValueAtTime(time);
+      matrix.rotate(-rotation * this.r.mult);
+    } else if (!this.r && this.appliedTransformations < 4) {
+      var rotationZ = this.rz.getValueAtTime(time);
+      var rotationY = this.ry.getValueAtTime(time);
+      var rotationX = this.rx.getValueAtTime(time);
+      var orientation = this.or.getValueAtTime(time);
+      matrix.rotateZ(-rotationZ * this.rz.mult)
+        .rotateY(rotationY * this.ry.mult)
+        .rotateX(rotationX * this.rx.mult)
+        .rotateZ(-orientation[2] * this.or.mult)
+        .rotateY(orientation[1] * this.or.mult)
+        .rotateX(orientation[0] * this.or.mult);
+    }
+    if (this.data.p && this.data.p.s) {
+      var positionX = this.px.getValueAtTime(time);
+      var positionY = this.py.getValueAtTime(time);
+      if (this.data.p.z) {
+        var positionZ = this.pz.getValueAtTime(time);
+        matrix.translate(
+          positionX * this.px.mult,
+          positionY * this.py.mult,
+          -positionZ * this.pz.mult
+        );
+      } else {
+        matrix.translate(positionX * this.px.mult, positionY * this.py.mult, 0);
+      }
+    } else {
+      var position = this.p.getValueAtTime(time);
+      matrix.translate(
+        position[0] * this.p.mult,
+        position[1] * this.p.mult,
+        -position[2] * this.p.mult
+      );
+    }
+    return matrix;
+    /// /
+  }
+
+  function getTransformStaticValueAtTime() {
+    return this.v.clone(new Matrix());
+  }
+
+  var getTransformProperty = TransformPropertyFactory.getTransformProperty;
+  TransformPropertyFactory.getTransformProperty = function (elem, data, container) {
+    var prop = getTransformProperty(elem, data, container);
+    if (prop.dynamicProperties.length) {
+      prop.getValueAtTime = getTransformValueAtTime.bind(prop);
+    } else {
+      prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop);
+    }
+    prop.setGroupProperty = expressionHelpers.setGroupProperty;
+    return prop;
+  };
+
+  var propertyGetProp = PropertyFactory.getProp;
+  PropertyFactory.getProp = function (elem, data, type, mult, container) {
+    var prop = propertyGetProp(elem, data, type, mult, container);
+    // prop.getVelocityAtTime = getVelocityAtTime;
+    // prop.loopOut = loopOut;
+    // prop.loopIn = loopIn;
+    if (prop.kf) {
+      prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop);
+    } else {
+      prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop);
+    }
+    prop.setGroupProperty = expressionHelpers.setGroupProperty;
+    prop.loopOut = loopOut;
+    prop.loopIn = loopIn;
+    prop.smooth = smooth;
+    prop.getVelocityAtTime = expressionHelpers.getVelocityAtTime.bind(prop);
+    prop.getSpeedAtTime = expressionHelpers.getSpeedAtTime.bind(prop);
+    prop.numKeys = data.a === 1 ? data.k.length : 0;
+    prop.propertyIndex = data.ix;
+    var value = 0;
+    if (type !== 0) {
+      value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length);
+    }
+    prop._cachingAtTime = {
+      lastFrame: initialDefaultFrame,
+      lastIndex: 0,
+      value: value,
+    };
+    expressionHelpers.searchExpressions(elem, data, prop);
+    if (prop.k) {
+      container.addDynamicProperty(prop);
+    }
+
+    return prop;
+  };
+
+  function getShapeValueAtTime(frameNum) {
+    // For now this caching object is created only when needed instead of creating it when the shape is initialized.
+    if (!this._cachingAtTime) {
+      this._cachingAtTime = {
+        shapeValue: shapePool.clone(this.pv),
+        lastIndex: 0,
+        lastTime: initialDefaultFrame,
+      };
+    }
+
+    frameNum *= this.elem.globalData.frameRate;
+    frameNum -= this.offsetTime;
+    if (frameNum !== this._cachingAtTime.lastTime) {
+      this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0;
+      this._cachingAtTime.lastTime = frameNum;
+      this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime);
+    }
+    return this._cachingAtTime.shapeValue;
+  }
+
+  var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction();
+  var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction();
+
+  function ShapeExpressions() {}
+  ShapeExpressions.prototype = {
+    vertices: function (prop, time) {
+      if (this.k) {
+        this.getValue();
+      }
+      var shapePath = this.v;
+      if (time !== undefined) {
+        shapePath = this.getValueAtTime(time, 0);
+      }
+      var i;
+      var len = shapePath._length;
+      var vertices = shapePath[prop];
+      var points = shapePath.v;
+      var arr = createSizedArray(len);
+      for (i = 0; i < len; i += 1) {
+        if (prop === 'i' || prop === 'o') {
+          arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]];
+        } else {
+          arr[i] = [vertices[i][0], vertices[i][1]];
+        }
+      }
+      return arr;
+    },
+    points: function (time) {
+      return this.vertices('v', time);
+    },
+    inTangents: function (time) {
+      return this.vertices('i', time);
+    },
+    outTangents: function (time) {
+      return this.vertices('o', time);
+    },
+    isClosed: function () {
+      return this.v.c;
+    },
+    pointOnPath: function (perc, time) {
+      var shapePath = this.v;
+      if (time !== undefined) {
+        shapePath = this.getValueAtTime(time, 0);
+      }
+      if (!this._segmentsLength) {
+        this._segmentsLength = bez.getSegmentsLength(shapePath);
+      }
+
+      var segmentsLength = this._segmentsLength;
+      var lengths = segmentsLength.lengths;
+      var lengthPos = segmentsLength.totalLength * perc;
+      var i = 0;
+      var len = lengths.length;
+      var accumulatedLength = 0;
+      var pt;
+      while (i < len) {
+        if (accumulatedLength + lengths[i].addedLength > lengthPos) {
+          var initIndex = i;
+          var endIndex = (shapePath.c && i === len - 1) ? 0 : i + 1;
+          var segmentPerc = (lengthPos - accumulatedLength) / lengths[i].addedLength;
+          pt = bez.getPointInSegment(shapePath.v[initIndex], shapePath.v[endIndex], shapePath.o[initIndex], shapePath.i[endIndex], segmentPerc, lengths[i]);
+          break;
+        } else {
+          accumulatedLength += lengths[i].addedLength;
+        }
+        i += 1;
+      }
+      if (!pt) {
+        pt = shapePath.c ? [shapePath.v[0][0], shapePath.v[0][1]] : [shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1]];
+      }
+      return pt;
+    },
+    vectorOnPath: function (perc, time, vectorType) {
+      // perc doesn't use triple equality because it can be a Number object as well as a primitive.
+      if (perc == 1) { // eslint-disable-line eqeqeq
+        perc = this.v.c;
+      } else if (perc == 0) { // eslint-disable-line eqeqeq
+        perc = 0.999;
+      }
+      var pt1 = this.pointOnPath(perc, time);
+      var pt2 = this.pointOnPath(perc + 0.001, time);
+      var xLength = pt2[0] - pt1[0];
+      var yLength = pt2[1] - pt1[1];
+      var magnitude = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2));
+      if (magnitude === 0) {
+        return [0, 0];
+      }
+      var unitVector = vectorType === 'tangent' ? [xLength / magnitude, yLength / magnitude] : [-yLength / magnitude, xLength / magnitude];
+      return unitVector;
+    },
+    tangentOnPath: function (perc, time) {
+      return this.vectorOnPath(perc, time, 'tangent');
+    },
+    normalOnPath: function (perc, time) {
+      return this.vectorOnPath(perc, time, 'normal');
+    },
+    setGroupProperty: expressionHelpers.setGroupProperty,
+    getValueAtTime: expressionHelpers.getStaticValueAtTime,
+  };
+  extendPrototype([ShapeExpressions], ShapePropertyConstructorFunction);
+  extendPrototype([ShapeExpressions], KeyframedShapePropertyConstructorFunction);
+  KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime;
+  KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression;
+
+  var propertyGetShapeProp = ShapePropertyFactory.getShapeProp;
+  ShapePropertyFactory.getShapeProp = function (elem, data, type, arr, trims) {
+    var prop = propertyGetShapeProp(elem, data, type, arr, trims);
+    prop.propertyIndex = data.ix;
+    prop.lock = false;
+    if (type === 3) {
+      expressionHelpers.searchExpressions(elem, data.pt, prop);
+    } else if (type === 4) {
+      expressionHelpers.searchExpressions(elem, data.ks, prop);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  };
+}
+
+function initialize$1() {
+  addPropertyDecorator();
+}
+
+function addDecorator() {
+  function searchExpressions() {
+    if (this.data.d.x) {
+      this.calculateExpression = ExpressionManager.initiateExpression.bind(this)(this.elem, this.data.d, this);
+      this.addEffect(this.getExpressionValue.bind(this));
+      return true;
+    }
+    return null;
+  }
+
+  TextProperty.prototype.getExpressionValue = function (currentValue, text) {
+    var newValue = this.calculateExpression(text);
+    if (currentValue.t !== newValue) {
+      var newData = {};
+      this.copyData(newData, currentValue);
+      newData.t = newValue.toString();
+      newData.__complete = false;
+      return newData;
+    }
+    return currentValue;
+  };
+
+  TextProperty.prototype.searchProperty = function () {
+    var isKeyframed = this.searchKeyframes();
+    var hasExpressions = this.searchExpressions();
+    this.kf = isKeyframed || hasExpressions;
+    return this.kf;
+  };
+
+  TextProperty.prototype.searchExpressions = searchExpressions;
+}
+
+function initialize() {
+  addDecorator();
+}
+
+function SVGComposableEffect() {
+
+}
+SVGComposableEffect.prototype = {
+  createMergeNode: (resultId, ins) => {
+    var feMerge = createNS('feMerge');
+    feMerge.setAttribute('result', resultId);
+    var feMergeNode;
+    var i;
+    for (i = 0; i < ins.length; i += 1) {
+      feMergeNode = createNS('feMergeNode');
+      feMergeNode.setAttribute('in', ins[i]);
+      feMerge.appendChild(feMergeNode);
+      feMerge.appendChild(feMergeNode);
+    }
+    return feMerge;
+  },
+};
+
+var linearFilterValue = '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0';
+
+function SVGTintFilter(filter, filterManager, elem, id, source) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'linearRGB');
+  feColorMatrix.setAttribute('values', linearFilterValue + ' 1 0');
+  this.linearFilter = feColorMatrix;
+  feColorMatrix.setAttribute('result', id + '_tint_1');
+  filter.appendChild(feColorMatrix);
+  feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+  feColorMatrix.setAttribute('values', '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0');
+  feColorMatrix.setAttribute('result', id + '_tint_2');
+  filter.appendChild(feColorMatrix);
+  this.matrixFilter = feColorMatrix;
+  var feMerge = this.createMergeNode(
+    id,
+    [
+      source,
+      id + '_tint_1',
+      id + '_tint_2',
+    ]
+  );
+  filter.appendChild(feMerge);
+}
+extendPrototype([SVGComposableEffect], SVGTintFilter);
+
+SVGTintFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var colorBlack = this.filterManager.effectElements[0].p.v;
+    var colorWhite = this.filterManager.effectElements[1].p.v;
+    var opacity = this.filterManager.effectElements[2].p.v / 100;
+    this.linearFilter.setAttribute('values', linearFilterValue + ' ' + opacity + ' 0');
+    this.matrixFilter.setAttribute('values', (colorWhite[0] - colorBlack[0]) + ' 0 0 0 ' + colorBlack[0] + ' ' + (colorWhite[1] - colorBlack[1]) + ' 0 0 0 ' + colorBlack[1] + ' ' + (colorWhite[2] - colorBlack[2]) + ' 0 0 0 ' + colorBlack[2] + ' 0 0 0 1 0');
+  }
+};
+
+function SVGFillFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+  feColorMatrix.setAttribute('values', '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0');
+  feColorMatrix.setAttribute('result', id);
+  filter.appendChild(feColorMatrix);
+  this.matrixFilter = feColorMatrix;
+}
+
+SVGFillFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var color = this.filterManager.effectElements[2].p.v;
+    var opacity = this.filterManager.effectElements[6].p.v;
+    this.matrixFilter.setAttribute('values', '0 0 0 0 ' + color[0] + ' 0 0 0 0 ' + color[1] + ' 0 0 0 0 ' + color[2] + ' 0 0 0 ' + opacity + ' 0');
+  }
+};
+
+function SVGStrokeEffect(fil, filterManager, elem) {
+  this.initialized = false;
+  this.filterManager = filterManager;
+  this.elem = elem;
+  this.paths = [];
+}
+
+SVGStrokeEffect.prototype.initialize = function () {
+  var elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
+  var path;
+  var groupPath;
+  var i;
+  var len;
+  if (this.filterManager.effectElements[1].p.v === 1) {
+    len = this.elem.maskManager.masksProperties.length;
+    i = 0;
+  } else {
+    i = this.filterManager.effectElements[0].p.v - 1;
+    len = i + 1;
+  }
+  groupPath = createNS('g');
+  groupPath.setAttribute('fill', 'none');
+  groupPath.setAttribute('stroke-linecap', 'round');
+  groupPath.setAttribute('stroke-dashoffset', 1);
+  for (i; i < len; i += 1) {
+    path = createNS('path');
+    groupPath.appendChild(path);
+    this.paths.push({ p: path, m: i });
+  }
+  if (this.filterManager.effectElements[10].p.v === 3) {
+    var mask = createNS('mask');
+    var id = createElementID();
+    mask.setAttribute('id', id);
+    mask.setAttribute('mask-type', 'alpha');
+    mask.appendChild(groupPath);
+    this.elem.globalData.defs.appendChild(mask);
+    var g = createNS('g');
+    g.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+    while (elemChildren[0]) {
+      g.appendChild(elemChildren[0]);
+    }
+    this.elem.layerElement.appendChild(g);
+    this.masker = mask;
+    groupPath.setAttribute('stroke', '#fff');
+  } else if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
+    if (this.filterManager.effectElements[10].p.v === 2) {
+      elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
+      while (elemChildren.length) {
+        this.elem.layerElement.removeChild(elemChildren[0]);
+      }
+    }
+    this.elem.layerElement.appendChild(groupPath);
+    this.elem.layerElement.removeAttribute('mask');
+    groupPath.setAttribute('stroke', '#fff');
+  }
+  this.initialized = true;
+  this.pathMasker = groupPath;
+};
+
+SVGStrokeEffect.prototype.renderFrame = function (forceRender) {
+  if (!this.initialized) {
+    this.initialize();
+  }
+  var i;
+  var len = this.paths.length;
+  var mask;
+  var path;
+  for (i = 0; i < len; i += 1) {
+    if (this.paths[i].m !== -1) {
+      mask = this.elem.maskManager.viewData[this.paths[i].m];
+      path = this.paths[i].p;
+      if (forceRender || this.filterManager._mdf || mask.prop._mdf) {
+        path.setAttribute('d', mask.lastPath);
+      }
+      if (forceRender || this.filterManager.effectElements[9].p._mdf || this.filterManager.effectElements[4].p._mdf || this.filterManager.effectElements[7].p._mdf || this.filterManager.effectElements[8].p._mdf || mask.prop._mdf) {
+        var dasharrayValue;
+        if (this.filterManager.effectElements[7].p.v !== 0 || this.filterManager.effectElements[8].p.v !== 100) {
+          var s = Math.min(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
+          var e = Math.max(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
+          var l = path.getTotalLength();
+          dasharrayValue = '0 0 0 ' + l * s + ' ';
+          var lineLength = l * (e - s);
+          var segment = 1 + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
+          var units = Math.floor(lineLength / segment);
+          var j;
+          for (j = 0; j < units; j += 1) {
+            dasharrayValue += '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01 + ' ';
+          }
+          dasharrayValue += '0 ' + l * 10 + ' 0 0';
+        } else {
+          dasharrayValue = '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
+        }
+        path.setAttribute('stroke-dasharray', dasharrayValue);
+      }
+    }
+  }
+  if (forceRender || this.filterManager.effectElements[4].p._mdf) {
+    this.pathMasker.setAttribute('stroke-width', this.filterManager.effectElements[4].p.v * 2);
+  }
+
+  if (forceRender || this.filterManager.effectElements[6].p._mdf) {
+    this.pathMasker.setAttribute('opacity', this.filterManager.effectElements[6].p.v);
+  }
+  if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
+    if (forceRender || this.filterManager.effectElements[3].p._mdf) {
+      var color = this.filterManager.effectElements[3].p.v;
+      this.pathMasker.setAttribute('stroke', 'rgb(' + bmFloor(color[0] * 255) + ',' + bmFloor(color[1] * 255) + ',' + bmFloor(color[2] * 255) + ')');
+    }
+  }
+};
+
+function SVGTritoneFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'linearRGB');
+  feColorMatrix.setAttribute('values', '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0');
+  filter.appendChild(feColorMatrix);
+  var feComponentTransfer = createNS('feComponentTransfer');
+  feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+  feComponentTransfer.setAttribute('result', id);
+  this.matrixFilter = feComponentTransfer;
+  var feFuncR = createNS('feFuncR');
+  feFuncR.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncR);
+  this.feFuncR = feFuncR;
+  var feFuncG = createNS('feFuncG');
+  feFuncG.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncG);
+  this.feFuncG = feFuncG;
+  var feFuncB = createNS('feFuncB');
+  feFuncB.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncB);
+  this.feFuncB = feFuncB;
+  filter.appendChild(feComponentTransfer);
+}
+
+SVGTritoneFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var color1 = this.filterManager.effectElements[0].p.v;
+    var color2 = this.filterManager.effectElements[1].p.v;
+    var color3 = this.filterManager.effectElements[2].p.v;
+    var tableR = color3[0] + ' ' + color2[0] + ' ' + color1[0];
+    var tableG = color3[1] + ' ' + color2[1] + ' ' + color1[1];
+    var tableB = color3[2] + ' ' + color2[2] + ' ' + color1[2];
+    this.feFuncR.setAttribute('tableValues', tableR);
+    this.feFuncG.setAttribute('tableValues', tableG);
+    this.feFuncB.setAttribute('tableValues', tableB);
+  }
+};
+
+function SVGProLevelsFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var effectElements = this.filterManager.effectElements;
+  var feComponentTransfer = createNS('feComponentTransfer');
+
+  // Red
+  if (effectElements[10].p.k || effectElements[10].p.v !== 0 || effectElements[11].p.k || effectElements[11].p.v !== 1 || effectElements[12].p.k || effectElements[12].p.v !== 1 || effectElements[13].p.k || effectElements[13].p.v !== 0 || effectElements[14].p.k || effectElements[14].p.v !== 1) {
+    this.feFuncR = this.createFeFunc('feFuncR', feComponentTransfer);
+  }
+  // Green
+  if (effectElements[17].p.k || effectElements[17].p.v !== 0 || effectElements[18].p.k || effectElements[18].p.v !== 1 || effectElements[19].p.k || effectElements[19].p.v !== 1 || effectElements[20].p.k || effectElements[20].p.v !== 0 || effectElements[21].p.k || effectElements[21].p.v !== 1) {
+    this.feFuncG = this.createFeFunc('feFuncG', feComponentTransfer);
+  }
+  // Blue
+  if (effectElements[24].p.k || effectElements[24].p.v !== 0 || effectElements[25].p.k || effectElements[25].p.v !== 1 || effectElements[26].p.k || effectElements[26].p.v !== 1 || effectElements[27].p.k || effectElements[27].p.v !== 0 || effectElements[28].p.k || effectElements[28].p.v !== 1) {
+    this.feFuncB = this.createFeFunc('feFuncB', feComponentTransfer);
+  }
+  // Alpha
+  if (effectElements[31].p.k || effectElements[31].p.v !== 0 || effectElements[32].p.k || effectElements[32].p.v !== 1 || effectElements[33].p.k || effectElements[33].p.v !== 1 || effectElements[34].p.k || effectElements[34].p.v !== 0 || effectElements[35].p.k || effectElements[35].p.v !== 1) {
+    this.feFuncA = this.createFeFunc('feFuncA', feComponentTransfer);
+  }
+  // RGB
+  if (this.feFuncR || this.feFuncG || this.feFuncB || this.feFuncA) {
+    feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+    filter.appendChild(feComponentTransfer);
+  }
+
+  if (effectElements[3].p.k || effectElements[3].p.v !== 0 || effectElements[4].p.k || effectElements[4].p.v !== 1 || effectElements[5].p.k || effectElements[5].p.v !== 1 || effectElements[6].p.k || effectElements[6].p.v !== 0 || effectElements[7].p.k || effectElements[7].p.v !== 1) {
+    feComponentTransfer = createNS('feComponentTransfer');
+    feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+    feComponentTransfer.setAttribute('result', id);
+    filter.appendChild(feComponentTransfer);
+    this.feFuncRComposed = this.createFeFunc('feFuncR', feComponentTransfer);
+    this.feFuncGComposed = this.createFeFunc('feFuncG', feComponentTransfer);
+    this.feFuncBComposed = this.createFeFunc('feFuncB', feComponentTransfer);
+  }
+}
+
+SVGProLevelsFilter.prototype.createFeFunc = function (type, feComponentTransfer) {
+  var feFunc = createNS(type);
+  feFunc.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFunc);
+  return feFunc;
+};
+
+SVGProLevelsFilter.prototype.getTableValue = function (inputBlack, inputWhite, gamma, outputBlack, outputWhite) {
+  var cnt = 0;
+  var segments = 256;
+  var perc;
+  var min = Math.min(inputBlack, inputWhite);
+  var max = Math.max(inputBlack, inputWhite);
+  var table = Array.call(null, { length: segments });
+  var colorValue;
+  var pos = 0;
+  var outputDelta = outputWhite - outputBlack;
+  var inputDelta = inputWhite - inputBlack;
+  while (cnt <= 256) {
+    perc = cnt / 256;
+    if (perc <= min) {
+      colorValue = inputDelta < 0 ? outputWhite : outputBlack;
+    } else if (perc >= max) {
+      colorValue = inputDelta < 0 ? outputBlack : outputWhite;
+    } else {
+      colorValue = (outputBlack + outputDelta * Math.pow((perc - inputBlack) / inputDelta, 1 / gamma));
+    }
+    table[pos] = colorValue;
+    pos += 1;
+    cnt += 256 / (segments - 1);
+  }
+  return table.join(' ');
+};
+
+SVGProLevelsFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var val;
+    var effectElements = this.filterManager.effectElements;
+    if (this.feFuncRComposed && (forceRender || effectElements[3].p._mdf || effectElements[4].p._mdf || effectElements[5].p._mdf || effectElements[6].p._mdf || effectElements[7].p._mdf)) {
+      val = this.getTableValue(effectElements[3].p.v, effectElements[4].p.v, effectElements[5].p.v, effectElements[6].p.v, effectElements[7].p.v);
+      this.feFuncRComposed.setAttribute('tableValues', val);
+      this.feFuncGComposed.setAttribute('tableValues', val);
+      this.feFuncBComposed.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncR && (forceRender || effectElements[10].p._mdf || effectElements[11].p._mdf || effectElements[12].p._mdf || effectElements[13].p._mdf || effectElements[14].p._mdf)) {
+      val = this.getTableValue(effectElements[10].p.v, effectElements[11].p.v, effectElements[12].p.v, effectElements[13].p.v, effectElements[14].p.v);
+      this.feFuncR.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncG && (forceRender || effectElements[17].p._mdf || effectElements[18].p._mdf || effectElements[19].p._mdf || effectElements[20].p._mdf || effectElements[21].p._mdf)) {
+      val = this.getTableValue(effectElements[17].p.v, effectElements[18].p.v, effectElements[19].p.v, effectElements[20].p.v, effectElements[21].p.v);
+      this.feFuncG.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncB && (forceRender || effectElements[24].p._mdf || effectElements[25].p._mdf || effectElements[26].p._mdf || effectElements[27].p._mdf || effectElements[28].p._mdf)) {
+      val = this.getTableValue(effectElements[24].p.v, effectElements[25].p.v, effectElements[26].p.v, effectElements[27].p.v, effectElements[28].p.v);
+      this.feFuncB.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncA && (forceRender || effectElements[31].p._mdf || effectElements[32].p._mdf || effectElements[33].p._mdf || effectElements[34].p._mdf || effectElements[35].p._mdf)) {
+      val = this.getTableValue(effectElements[31].p.v, effectElements[32].p.v, effectElements[33].p.v, effectElements[34].p.v, effectElements[35].p.v);
+      this.feFuncA.setAttribute('tableValues', val);
+    }
+  }
+};
+
+function SVGDropShadowEffect(filter, filterManager, elem, id, source) {
+  var globalFilterSize = filterManager.container.globalData.renderConfig.filterSize;
+  var filterSize = filterManager.data.fs || globalFilterSize;
+  filter.setAttribute('x', filterSize.x || globalFilterSize.x);
+  filter.setAttribute('y', filterSize.y || globalFilterSize.y);
+  filter.setAttribute('width', filterSize.width || globalFilterSize.width);
+  filter.setAttribute('height', filterSize.height || globalFilterSize.height);
+  this.filterManager = filterManager;
+
+  var feGaussianBlur = createNS('feGaussianBlur');
+  feGaussianBlur.setAttribute('in', 'SourceAlpha');
+  feGaussianBlur.setAttribute('result', id + '_drop_shadow_1');
+  feGaussianBlur.setAttribute('stdDeviation', '0');
+  this.feGaussianBlur = feGaussianBlur;
+  filter.appendChild(feGaussianBlur);
+
+  var feOffset = createNS('feOffset');
+  feOffset.setAttribute('dx', '25');
+  feOffset.setAttribute('dy', '0');
+  feOffset.setAttribute('in', id + '_drop_shadow_1');
+  feOffset.setAttribute('result', id + '_drop_shadow_2');
+  this.feOffset = feOffset;
+  filter.appendChild(feOffset);
+  var feFlood = createNS('feFlood');
+  feFlood.setAttribute('flood-color', '#00ff00');
+  feFlood.setAttribute('flood-opacity', '1');
+  feFlood.setAttribute('result', id + '_drop_shadow_3');
+  this.feFlood = feFlood;
+  filter.appendChild(feFlood);
+
+  var feComposite = createNS('feComposite');
+  feComposite.setAttribute('in', id + '_drop_shadow_3');
+  feComposite.setAttribute('in2', id + '_drop_shadow_2');
+  feComposite.setAttribute('operator', 'in');
+  feComposite.setAttribute('result', id + '_drop_shadow_4');
+  filter.appendChild(feComposite);
+
+  var feMerge = this.createMergeNode(
+    id,
+    [
+      id + '_drop_shadow_4',
+      source,
+    ]
+  );
+  filter.appendChild(feMerge);
+  //
+}
+extendPrototype([SVGComposableEffect], SVGDropShadowEffect);
+
+SVGDropShadowEffect.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    if (forceRender || this.filterManager.effectElements[4].p._mdf) {
+      this.feGaussianBlur.setAttribute('stdDeviation', this.filterManager.effectElements[4].p.v / 4);
+    }
+    if (forceRender || this.filterManager.effectElements[0].p._mdf) {
+      var col = this.filterManager.effectElements[0].p.v;
+      this.feFlood.setAttribute('flood-color', rgbToHex(Math.round(col[0] * 255), Math.round(col[1] * 255), Math.round(col[2] * 255)));
+    }
+    if (forceRender || this.filterManager.effectElements[1].p._mdf) {
+      this.feFlood.setAttribute('flood-opacity', this.filterManager.effectElements[1].p.v / 255);
+    }
+    if (forceRender || this.filterManager.effectElements[2].p._mdf || this.filterManager.effectElements[3].p._mdf) {
+      var distance = this.filterManager.effectElements[3].p.v;
+      var angle = (this.filterManager.effectElements[2].p.v - 90) * degToRads;
+      var x = distance * Math.cos(angle);
+      var y = distance * Math.sin(angle);
+      this.feOffset.setAttribute('dx', x);
+      this.feOffset.setAttribute('dy', y);
+    }
+  }
+};
+
+var _svgMatteSymbols = [];
+
+function SVGMatte3Effect(filterElem, filterManager, elem) {
+  this.initialized = false;
+  this.filterManager = filterManager;
+  this.filterElem = filterElem;
+  this.elem = elem;
+  elem.matteElement = createNS('g');
+  elem.matteElement.appendChild(elem.layerElement);
+  elem.matteElement.appendChild(elem.transformedElement);
+  elem.baseElement = elem.matteElement;
+}
+
+SVGMatte3Effect.prototype.findSymbol = function (mask) {
+  var i = 0;
+  var len = _svgMatteSymbols.length;
+  while (i < len) {
+    if (_svgMatteSymbols[i] === mask) {
+      return _svgMatteSymbols[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+SVGMatte3Effect.prototype.replaceInParent = function (mask, symbolId) {
+  var parentNode = mask.layerElement.parentNode;
+  if (!parentNode) {
+    return;
+  }
+  var children = parentNode.children;
+  var i = 0;
+  var len = children.length;
+  while (i < len) {
+    if (children[i] === mask.layerElement) {
+      break;
+    }
+    i += 1;
+  }
+  var nextChild;
+  if (i <= len - 2) {
+    nextChild = children[i + 1];
+  }
+  var useElem = createNS('use');
+  useElem.setAttribute('href', '#' + symbolId);
+  if (nextChild) {
+    parentNode.insertBefore(useElem, nextChild);
+  } else {
+    parentNode.appendChild(useElem);
+  }
+};
+
+SVGMatte3Effect.prototype.setElementAsMask = function (elem, mask) {
+  if (!this.findSymbol(mask)) {
+    var symbolId = createElementID();
+    var masker = createNS('mask');
+    masker.setAttribute('id', mask.layerId);
+    masker.setAttribute('mask-type', 'alpha');
+    _svgMatteSymbols.push(mask);
+    var defs = elem.globalData.defs;
+    defs.appendChild(masker);
+    var symbol = createNS('symbol');
+    symbol.setAttribute('id', symbolId);
+    this.replaceInParent(mask, symbolId);
+    symbol.appendChild(mask.layerElement);
+    defs.appendChild(symbol);
+    var useElem = createNS('use');
+    useElem.setAttribute('href', '#' + symbolId);
+    masker.appendChild(useElem);
+    mask.data.hd = false;
+    mask.show();
+  }
+  elem.setMatte(mask.layerId);
+};
+
+SVGMatte3Effect.prototype.initialize = function () {
+  var ind = this.filterManager.effectElements[0].p.v;
+  var elements = this.elem.comp.elements;
+  var i = 0;
+  var len = elements.length;
+  while (i < len) {
+    if (elements[i] && elements[i].data.ind === ind) {
+      this.setElementAsMask(this.elem, elements[i]);
+    }
+    i += 1;
+  }
+  this.initialized = true;
+};
+
+SVGMatte3Effect.prototype.renderFrame = function () {
+  if (!this.initialized) {
+    this.initialize();
+  }
+};
+
+function SVGGaussianBlurEffect(filter, filterManager, elem, id) {
+  // Outset the filter region by 100% on all sides to accommodate blur expansion.
+  filter.setAttribute('x', '-100%');
+  filter.setAttribute('y', '-100%');
+  filter.setAttribute('width', '300%');
+  filter.setAttribute('height', '300%');
+
+  this.filterManager = filterManager;
+  var feGaussianBlur = createNS('feGaussianBlur');
+  feGaussianBlur.setAttribute('result', id);
+  filter.appendChild(feGaussianBlur);
+  this.feGaussianBlur = feGaussianBlur;
+}
+
+SVGGaussianBlurEffect.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    // Empirical value, matching AE's blur appearance.
+    var kBlurrinessToSigma = 0.3;
+    var sigma = this.filterManager.effectElements[0].p.v * kBlurrinessToSigma;
+
+    // Dimensions mapping:
+    //
+    //   1 -> horizontal & vertical
+    //   2 -> horizontal only
+    //   3 -> vertical only
+    //
+    var dimensions = this.filterManager.effectElements[1].p.v;
+    var sigmaX = (dimensions == 3) ? 0 : sigma; // eslint-disable-line eqeqeq
+    var sigmaY = (dimensions == 2) ? 0 : sigma; // eslint-disable-line eqeqeq
+
+    this.feGaussianBlur.setAttribute('stdDeviation', sigmaX + ' ' + sigmaY);
+
+    // Repeat edges mapping:
+    //
+    //   0 -> off -> duplicate
+    //   1 -> on  -> wrap
+    var edgeMode = (this.filterManager.effectElements[2].p.v == 1) ? 'wrap' : 'duplicate'; // eslint-disable-line eqeqeq
+    this.feGaussianBlur.setAttribute('edgeMode', edgeMode);
+  }
+};
+
+function TransformEffect() {
+}
+
+TransformEffect.prototype.init = function (effectsManager) {
+  this.effectsManager = effectsManager;
+  this.type = effectTypes.TRANSFORM_EFFECT;
+  this.matrix = new Matrix();
+  this.opacity = -1;
+  this._mdf = false;
+  this._opMdf = false;
+};
+
+TransformEffect.prototype.renderFrame = function (forceFrame) {
+  this._opMdf = false;
+  this._mdf = false;
+  if (forceFrame || this.effectsManager._mdf) {
+    var effectElements = this.effectsManager.effectElements;
+    var anchor = effectElements[0].p.v;
+    var position = effectElements[1].p.v;
+    var isUniformScale = effectElements[2].p.v === 1;
+    var scaleHeight = effectElements[3].p.v;
+    var scaleWidth = isUniformScale ? scaleHeight : effectElements[4].p.v;
+    var skew = effectElements[5].p.v;
+    var skewAxis = effectElements[6].p.v;
+    var rotation = effectElements[7].p.v;
+    this.matrix.reset();
+    this.matrix.translate(-anchor[0], -anchor[1], anchor[2]);
+    this.matrix.scale(scaleWidth * 0.01, scaleHeight * 0.01, 1);
+    this.matrix.rotate(-rotation * degToRads);
+    this.matrix.skewFromAxis(-skew * degToRads, (skewAxis + 90) * degToRads);
+    this.matrix.translate(position[0], position[1], 0);
+    this._mdf = true;
+    if (this.opacity !== effectElements[8].p.v) {
+      this.opacity = effectElements[8].p.v;
+      this._opMdf = true;
+    }
+  }
+};
+
+function SVGTransformEffect(_, filterManager) {
+  this.init(filterManager);
+}
+
+extendPrototype([TransformEffect], SVGTransformEffect);
+
+function CVTransformEffect(effectsManager) {
+  this.init(effectsManager);
+}
+extendPrototype([TransformEffect], CVTransformEffect);
+
+// Registering renderers
+registerRenderer('canvas', CanvasRenderer);
+registerRenderer('html', HybridRenderer);
+registerRenderer('svg', SVGRenderer);
+
+// Registering shape modifiers
+ShapeModifiers.registerModifier('tm', TrimModifier);
+ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
+ShapeModifiers.registerModifier('rp', RepeaterModifier);
+ShapeModifiers.registerModifier('rd', RoundCornersModifier);
+ShapeModifiers.registerModifier('zz', ZigZagModifier);
+ShapeModifiers.registerModifier('op', OffsetPathModifier);
+
+// Registering expression plugin
+setExpressionsPlugin(Expressions);
+setExpressionInterfaces(getInterface);
+initialize$1();
+initialize();
+
+// Registering svg effects
+registerEffect$1(20, SVGTintFilter, true);
+registerEffect$1(21, SVGFillFilter, true);
+registerEffect$1(22, SVGStrokeEffect, false);
+registerEffect$1(23, SVGTritoneFilter, true);
+registerEffect$1(24, SVGProLevelsFilter, true);
+registerEffect$1(25, SVGDropShadowEffect, true);
+registerEffect$1(28, SVGMatte3Effect, false);
+registerEffect$1(29, SVGGaussianBlurEffect, true);
+registerEffect$1(35, SVGTransformEffect, false);
+registerEffect(35, CVTransformEffect);
+
+exports["default"] = lottie;
diff --git a/build/player/cjs/lottie_canvas.min.js b/build/player/cjs/lottie_canvas.min.js
new file mode 100644
index 0000000..99bd38c
--- /dev/null
+++ b/build/player/cjs/lottie_canvas.min.js
@@ -0,0 +1,16367 @@
+'use strict';
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+const svgNS = 'http://www.w3.org/2000/svg';
+
+let locationHref = '';
+let _useWebWorker = false;
+
+const initialDefaultFrame = -999999;
+
+const setWebWorker = (flag) => { _useWebWorker = !!flag; };
+const getWebWorker = () => _useWebWorker;
+
+const setLocationHref = (value) => { locationHref = value; };
+const getLocationHref = () => locationHref;
+
+function createTag(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElement(type);
+}
+
+function extendPrototype(sources, destination) {
+  var i;
+  var len = sources.length;
+  var sourcePrototype;
+  for (i = 0; i < len; i += 1) {
+    sourcePrototype = sources[i].prototype;
+    for (var attr in sourcePrototype) {
+      if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
+    }
+  }
+}
+
+function getDescriptor(object, prop) {
+  return Object.getOwnPropertyDescriptor(object, prop);
+}
+
+function createProxyFunction(prototype) {
+  function ProxyFunction() {}
+  ProxyFunction.prototype = prototype;
+  return ProxyFunction;
+}
+
+// import Howl from '../../3rd_party/howler';
+
+const audioControllerFactory = (function () {
+  function AudioController(audioFactory) {
+    this.audios = [];
+    this.audioFactory = audioFactory;
+    this._volume = 1;
+    this._isMuted = false;
+  }
+
+  AudioController.prototype = {
+    addAudio: function (audio) {
+      this.audios.push(audio);
+    },
+    pause: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].pause();
+      }
+    },
+    resume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].resume();
+      }
+    },
+    setRate: function (rateValue) {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].setRate(rateValue);
+      }
+    },
+    createAudio: function (assetPath) {
+      if (this.audioFactory) {
+        return this.audioFactory(assetPath);
+      } if (window.Howl) {
+        return new window.Howl({
+          src: [assetPath],
+        });
+      }
+      return {
+        isPlaying: false,
+        play: function () { this.isPlaying = true; },
+        seek: function () { this.isPlaying = false; },
+        playing: function () {},
+        rate: function () {},
+        setVolume: function () {},
+      };
+    },
+    setAudioFactory: function (audioFactory) {
+      this.audioFactory = audioFactory;
+    },
+    setVolume: function (value) {
+      this._volume = value;
+      this._updateVolume();
+    },
+    mute: function () {
+      this._isMuted = true;
+      this._updateVolume();
+    },
+    unmute: function () {
+      this._isMuted = false;
+      this._updateVolume();
+    },
+    getVolume: function () {
+      return this._volume;
+    },
+    _updateVolume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
+      }
+    },
+  };
+
+  return function () {
+    return new AudioController();
+  };
+}());
+
+const createTypedArray = (function () {
+  function createRegularArray(type, len) {
+    var i = 0;
+    var arr = [];
+    var value;
+    switch (type) {
+      case 'int16':
+      case 'uint8c':
+        value = 1;
+        break;
+      default:
+        value = 1.1;
+        break;
+    }
+    for (i = 0; i < len; i += 1) {
+      arr.push(value);
+    }
+    return arr;
+  }
+  function createTypedArrayFactory(type, len) {
+    if (type === 'float32') {
+      return new Float32Array(len);
+    } if (type === 'int16') {
+      return new Int16Array(len);
+    } if (type === 'uint8c') {
+      return new Uint8ClampedArray(len);
+    }
+    return createRegularArray(type, len);
+  }
+  if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
+    return createTypedArrayFactory;
+  }
+  return createRegularArray;
+}());
+
+function createSizedArray(len) {
+  return Array.apply(null, { length: len });
+}
+
+let subframeEnabled = true;
+let expressionsPlugin = null;
+let expressionsInterfaces = null;
+let idPrefix$1 = '';
+const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+let _shouldRoundValues = false;
+const bmPow = Math.pow;
+const bmSqrt = Math.sqrt;
+const bmFloor = Math.floor;
+const bmMax = Math.max;
+const bmMin = Math.min;
+
+const BMMath = {};
+(function () {
+  var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
+  var i;
+  var len = propertyNames.length;
+  for (i = 0; i < len; i += 1) {
+    BMMath[propertyNames[i]] = Math[propertyNames[i]];
+  }
+}());
+
+function ProjectInterface$1() { return {}; }
+BMMath.random = Math.random;
+BMMath.abs = function (val) {
+  var tOfVal = typeof val;
+  if (tOfVal === 'object' && val.length) {
+    var absArr = createSizedArray(val.length);
+    var i;
+    var len = val.length;
+    for (i = 0; i < len; i += 1) {
+      absArr[i] = Math.abs(val[i]);
+    }
+    return absArr;
+  }
+  return Math.abs(val);
+};
+let defaultCurveSegments = 150;
+const degToRads = Math.PI / 180;
+const roundCorner = 0.5519;
+
+function roundValues(flag) {
+  _shouldRoundValues = !!flag;
+}
+
+function bmRnd(value) {
+  if (_shouldRoundValues) {
+    return Math.round(value);
+  }
+  return value;
+}
+
+function styleDiv(element) {
+  element.style.position = 'absolute';
+  element.style.top = 0;
+  element.style.left = 0;
+  element.style.display = 'block';
+  element.style.transformOrigin = '0 0';
+  element.style.webkitTransformOrigin = '0 0';
+  element.style.backfaceVisibility = 'visible';
+  element.style.webkitBackfaceVisibility = 'visible';
+  element.style.transformStyle = 'preserve-3d';
+  element.style.webkitTransformStyle = 'preserve-3d';
+  element.style.mozTransformStyle = 'preserve-3d';
+}
+
+function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
+  this.type = type;
+  this.currentTime = currentTime;
+  this.totalTime = totalTime;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteEvent(type, frameMultiplier) {
+  this.type = type;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
+  this.type = type;
+  this.currentLoop = currentLoop;
+  this.totalLoops = totalLoops;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMSegmentStartEvent(type, firstFrame, totalFrames) {
+  this.type = type;
+  this.firstFrame = firstFrame;
+  this.totalFrames = totalFrames;
+}
+
+function BMDestroyEvent(type, target) {
+  this.type = type;
+  this.target = target;
+}
+
+function BMRenderFrameErrorEvent(nativeError, currentTime) {
+  this.type = 'renderFrameError';
+  this.nativeError = nativeError;
+  this.currentTime = currentTime;
+}
+
+function BMConfigErrorEvent(nativeError) {
+  this.type = 'configError';
+  this.nativeError = nativeError;
+}
+
+function BMAnimationConfigErrorEvent(type, nativeError) {
+  this.type = type;
+  this.nativeError = nativeError;
+}
+
+const createElementID = (function () {
+  var _count = 0;
+  return function createID() {
+    _count += 1;
+    return idPrefix$1 + '__lottie_element_' + _count;
+  };
+}());
+
+function HSVtoRGB(h, s, v) {
+  var r;
+  var g;
+  var b;
+  var i;
+  var f;
+  var p;
+  var q;
+  var t;
+  i = Math.floor(h * 6);
+  f = h * 6 - i;
+  p = v * (1 - s);
+  q = v * (1 - f * s);
+  t = v * (1 - (1 - f) * s);
+  switch (i % 6) {
+    case 0: r = v; g = t; b = p; break;
+    case 1: r = q; g = v; b = p; break;
+    case 2: r = p; g = v; b = t; break;
+    case 3: r = p; g = q; b = v; break;
+    case 4: r = t; g = p; b = v; break;
+    case 5: r = v; g = p; b = q; break;
+    default: break;
+  }
+  return [r,
+    g,
+    b];
+}
+
+function RGBtoHSV(r, g, b) {
+  var max = Math.max(r, g, b);
+  var min = Math.min(r, g, b);
+  var d = max - min;
+  var h;
+  var s = (max === 0 ? 0 : d / max);
+  var v = max / 255;
+
+  switch (max) {
+    case min: h = 0; break;
+    case r: h = (g - b) + d * (g < b ? 6 : 0); h /= 6 * d; break;
+    case g: h = (b - r) + d * 2; h /= 6 * d; break;
+    case b: h = (r - g) + d * 4; h /= 6 * d; break;
+    default: break;
+  }
+
+  return [
+    h,
+    s,
+    v,
+  ];
+}
+
+function addSaturationToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[1] += offset;
+  if (hsv[1] > 1) {
+    hsv[1] = 1;
+  } else if (hsv[1] <= 0) {
+    hsv[1] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addBrightnessToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[2] += offset;
+  if (hsv[2] > 1) {
+    hsv[2] = 1;
+  } else if (hsv[2] < 0) {
+    hsv[2] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addHueToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[0] += offset / 360;
+  if (hsv[0] > 1) {
+    hsv[0] -= 1;
+  } else if (hsv[0] < 0) {
+    hsv[0] += 1;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+const rgbToHex = (function () {
+  var colorMap = [];
+  var i;
+  var hex;
+  for (i = 0; i < 256; i += 1) {
+    hex = i.toString(16);
+    colorMap[i] = hex.length === 1 ? '0' + hex : hex;
+  }
+
+  return function (r, g, b) {
+    if (r < 0) {
+      r = 0;
+    }
+    if (g < 0) {
+      g = 0;
+    }
+    if (b < 0) {
+      b = 0;
+    }
+    return '#' + colorMap[r] + colorMap[g] + colorMap[b];
+  };
+}());
+
+const setSubframeEnabled = (flag) => { subframeEnabled = !!flag; };
+const getSubframeEnabled = () => subframeEnabled;
+const setExpressionsPlugin = (value) => { expressionsPlugin = value; };
+const getExpressionsPlugin = () => expressionsPlugin;
+const setExpressionInterfaces = (value) => { expressionsInterfaces = value; };
+const getExpressionInterfaces = () => expressionsInterfaces;
+const setDefaultCurveSegments = (value) => { defaultCurveSegments = value; };
+const getDefaultCurveSegments = () => defaultCurveSegments;
+const setIdPrefix = (value) => { idPrefix$1 = value; };
+const getIdPrefix = () => idPrefix$1;
+
+function createNS(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElementNS(svgNS, type);
+}
+
+const dataManager = (function () {
+  var _counterId = 1;
+  var processes = [];
+  var workerFn;
+  var workerInstance;
+  var workerProxy = {
+    onmessage: function () {
+
+    },
+    postMessage: function (path) {
+      workerFn({
+        data: path,
+      });
+    },
+  };
+  var _workerSelf = {
+    postMessage: function (data) {
+      workerProxy.onmessage({
+        data: data,
+      });
+    },
+  };
+  function createWorker(fn) {
+    if (window.Worker && window.Blob && getWebWorker()) {
+      var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      var url = URL.createObjectURL(blob);
+      return new Worker(url);
+    }
+    workerFn = fn;
+    return workerProxy;
+  }
+
+  function setupWorker() {
+    if (!workerInstance) {
+      workerInstance = createWorker(function workerStart(e) {
+        function dataFunctionManager() {
+          function completeLayers(layers, comps) {
+            var layerData;
+            var i;
+            var len = layers.length;
+            var j;
+            var jLen;
+            var k;
+            var kLen;
+            for (i = 0; i < len; i += 1) {
+              layerData = layers[i];
+              if (('ks' in layerData) && !layerData.completed) {
+                layerData.completed = true;
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      convertPathsToAbsoluteValues(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) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 0) {
+                  layerData.layers = findCompLayers(layerData.refId, comps);
+                  completeLayers(layerData.layers, comps);
+                } else if (layerData.ty === 4) {
+                  completeShapes(layerData.shapes);
+                } else if (layerData.ty === 5) {
+                  completeText(layerData);
+                }
+              }
+            }
+          }
+
+          function completeChars(chars, assets) {
+            if (chars) {
+              var i = 0;
+              var len = chars.length;
+              for (i = 0; i < len; i += 1) {
+                if (chars[i].t === 1) {
+                  // var compData = findComp(chars[i].data.refId, assets);
+                  chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                  // chars[i].data.ip = 0;
+                  // chars[i].data.op = 99999;
+                  // chars[i].data.st = 0;
+                  // chars[i].data.sr = 1;
+                  // chars[i].w = compData.w;
+                  // chars[i].data.ks = {
+                  //   a: { k: [0, 0, 0], a: 0 },
+                  //   p: { k: [0, -compData.h, 0], a: 0 },
+                  //   r: { k: 0, a: 0 },
+                  //   s: { k: [100, 100], a: 0 },
+                  //   o: { k: 100, a: 0 },
+                  // };
+                  completeLayers(chars[i].data.layers, assets);
+                }
+              }
+            }
+          }
+
+          function findComp(id, comps) {
+            var i = 0;
+            var len = comps.length;
+            while (i < len) {
+              if (comps[i].id === id) {
+                return comps[i];
+              }
+              i += 1;
+            }
+            return null;
+          }
+
+          function findCompLayers(id, comps) {
+            var comp = findComp(id, comps);
+            if (comp) {
+              if (!comp.layers.__used) {
+                comp.layers.__used = true;
+                return comp.layers;
+              }
+              return JSON.parse(JSON.stringify(comp.layers));
+            }
+            return null;
+          }
+
+          function completeShapes(arr) {
+            var i;
+            var len = arr.length;
+            var j;
+            var jLen;
+            for (i = len - 1; i >= 0; i -= 1) {
+              if (arr[i].ty === 'sh') {
+                if (arr[i].ks.k.i) {
+                  convertPathsToAbsoluteValues(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) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
+                    }
+                    if (arr[i].ks.k[j].e) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
+                    }
+                  }
+                }
+              } else if (arr[i].ty === 'gr') {
+                completeShapes(arr[i].it);
+              }
+            }
+          }
+
+          function convertPathsToAbsoluteValues(path) {
+            var i;
+            var len = path.i.length;
+            for (i = 0; i < len; i += 1) {
+              path.i[i][0] += path.v[i][0];
+              path.i[i][1] += path.v[i][1];
+              path.o[i][0] += path.v[i][0];
+              path.o[i][1] += path.v[i][1];
+            }
+          }
+
+          function checkVersion(minimum, animVersionString) {
+            var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
+            if (minimum[0] > animVersion[0]) {
+              return true;
+            } if (animVersion[0] > minimum[0]) {
+              return false;
+            }
+            if (minimum[1] > animVersion[1]) {
+              return true;
+            } if (animVersion[1] > minimum[1]) {
+              return false;
+            }
+            if (minimum[2] > animVersion[2]) {
+              return true;
+            } if (animVersion[2] > minimum[2]) {
+              return false;
+            }
+            return null;
+          }
+
+          var checkText = (function () {
+            var minimumVersion = [4, 4, 14];
+
+            function updateTextLayer(textLayer) {
+              var documentData = textLayer.t.d;
+              textLayer.t.d = {
+                k: [
+                  {
+                    s: documentData,
+                    t: 0,
+                  },
+                ],
+              };
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkChars = (function () {
+            var minimumVersion = [4, 7, 99];
+            return function (animationData) {
+              if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
+                var i;
+                var len = animationData.chars.length;
+                for (i = 0; i < len; i += 1) {
+                  var charData = animationData.chars[i];
+                  if (charData.data && charData.data.shapes) {
+                    completeShapes(charData.data.shapes);
+                    charData.data.ip = 0;
+                    charData.data.op = 99999;
+                    charData.data.st = 0;
+                    charData.data.sr = 1;
+                    charData.data.ks = {
+                      p: { k: [0, 0], a: 0 },
+                      s: { k: [100, 100], a: 0 },
+                      a: { k: [0, 0], a: 0 },
+                      r: { k: 0, a: 0 },
+                      o: { k: 100, a: 0 },
+                    };
+                    if (!animationData.chars[i].t) {
+                      charData.data.shapes.push(
+                        {
+                          ty: 'no',
+                        }
+                      );
+                      charData.data.shapes[0].it.push(
+                        {
+                          p: { k: [0, 0], a: 0 },
+                          s: { k: [100, 100], a: 0 },
+                          a: { k: [0, 0], a: 0 },
+                          r: { k: 0, a: 0 },
+                          o: { k: 100, a: 0 },
+                          sk: { k: 0, a: 0 },
+                          sa: { k: 0, a: 0 },
+                          ty: 'tr',
+                        }
+                      );
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkPathProperties = (function () {
+            var minimumVersion = [5, 7, 15];
+
+            function updateTextLayer(textLayer) {
+              var pathData = textLayer.t.p;
+              if (typeof pathData.a === 'number') {
+                pathData.a = {
+                  a: 0,
+                  k: pathData.a,
+                };
+              }
+              if (typeof pathData.p === 'number') {
+                pathData.p = {
+                  a: 0,
+                  k: pathData.p,
+                };
+              }
+              if (typeof pathData.r === 'number') {
+                pathData.r = {
+                  a: 0,
+                  k: pathData.r,
+                };
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkColors = (function () {
+            var minimumVersion = [4, 1, 9];
+
+            function iterateShapes(shapes) {
+              var i;
+              var len = shapes.length;
+              var j;
+              var jLen;
+              for (i = 0; i < len; i += 1) {
+                if (shapes[i].ty === 'gr') {
+                  iterateShapes(shapes[i].it);
+                } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
+                  if (shapes[i].c.k && shapes[i].c.k[0].i) {
+                    jLen = shapes[i].c.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (shapes[i].c.k[j].s) {
+                        shapes[i].c.k[j].s[0] /= 255;
+                        shapes[i].c.k[j].s[1] /= 255;
+                        shapes[i].c.k[j].s[2] /= 255;
+                        shapes[i].c.k[j].s[3] /= 255;
+                      }
+                      if (shapes[i].c.k[j].e) {
+                        shapes[i].c.k[j].e[0] /= 255;
+                        shapes[i].c.k[j].e[1] /= 255;
+                        shapes[i].c.k[j].e[2] /= 255;
+                        shapes[i].c.k[j].e[3] /= 255;
+                      }
+                    }
+                  } else {
+                    shapes[i].c.k[0] /= 255;
+                    shapes[i].c.k[1] /= 255;
+                    shapes[i].c.k[2] /= 255;
+                    shapes[i].c.k[3] /= 255;
+                  }
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 4) {
+                  iterateShapes(layers[i].shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkShapes = (function () {
+            var minimumVersion = [4, 4, 18];
+
+            function completeClosingShapes(arr) {
+              var i;
+              var len = arr.length;
+              var j;
+              var jLen;
+              for (i = len - 1; i >= 0; i -= 1) {
+                if (arr[i].ty === 'sh') {
+                  if (arr[i].ks.k.i) {
+                    arr[i].ks.k.c = arr[i].closed;
+                  } else {
+                    jLen = arr[i].ks.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (arr[i].ks.k[j].s) {
+                        arr[i].ks.k[j].s[0].c = arr[i].closed;
+                      }
+                      if (arr[i].ks.k[j].e) {
+                        arr[i].ks.k[j].e[0].c = arr[i].closed;
+                      }
+                    }
+                  }
+                } else if (arr[i].ty === 'gr') {
+                  completeClosingShapes(arr[i].it);
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var layerData;
+              var i;
+              var len = layers.length;
+              var j;
+              var jLen;
+              var k;
+              var kLen;
+              for (i = 0; i < len; i += 1) {
+                layerData = layers[i];
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      maskProps[j].pt.k.c = maskProps[j].cl;
+                    } else {
+                      kLen = maskProps[j].pt.k.length;
+                      for (k = 0; k < kLen; k += 1) {
+                        if (maskProps[j].pt.k[k].s) {
+                          maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 4) {
+                  completeClosingShapes(layerData.shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          function completeData(animationData) {
+            if (animationData.__complete) {
+              return;
+            }
+            checkColors(animationData);
+            checkText(animationData);
+            checkChars(animationData);
+            checkPathProperties(animationData);
+            checkShapes(animationData);
+            completeLayers(animationData.layers, animationData.assets);
+            completeChars(animationData.chars, animationData.assets);
+            animationData.__complete = true;
+          }
+
+          function completeText(data) {
+            if (data.t.a.length === 0 && !('m' in data.t.p)) {
+              // data.singleShape = true;
+            }
+          }
+
+          var moduleOb = {};
+          moduleOb.completeData = completeData;
+          moduleOb.checkColors = checkColors;
+          moduleOb.checkChars = checkChars;
+          moduleOb.checkPathProperties = checkPathProperties;
+          moduleOb.checkShapes = checkShapes;
+          moduleOb.completeLayers = completeLayers;
+
+          return moduleOb;
+        }
+        if (!_workerSelf.dataManager) {
+          _workerSelf.dataManager = dataFunctionManager();
+        }
+
+        if (!_workerSelf.assetLoader) {
+          _workerSelf.assetLoader = (function () {
+            function formatResponse(xhr) {
+              // using typeof doubles the time of execution of this method,
+              // so if available, it's better to use the header to validate the type
+              var contentTypeHeader = xhr.getResponseHeader('content-type');
+              if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
+                return xhr.response;
+              }
+              if (xhr.response && typeof xhr.response === 'object') {
+                return xhr.response;
+              } if (xhr.response && typeof xhr.response === 'string') {
+                return JSON.parse(xhr.response);
+              } if (xhr.responseText) {
+                return JSON.parse(xhr.responseText);
+              }
+              return null;
+            }
+
+            function loadAsset(path, fullPath, callback, errorCallback) {
+              var response;
+              var xhr = new XMLHttpRequest();
+              // set responseType after calling open or IE will break.
+              try {
+                // This crashes on Android WebView prior to KitKat
+                xhr.responseType = 'json';
+              } catch (err) {} // eslint-disable-line no-empty
+              xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4) {
+                  if (xhr.status === 200) {
+                    response = formatResponse(xhr);
+                    callback(response);
+                  } else {
+                    try {
+                      response = formatResponse(xhr);
+                      callback(response);
+                    } catch (err) {
+                      if (errorCallback) {
+                        errorCallback(err);
+                      }
+                    }
+                  }
+                }
+              };
+              try {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), path, true);
+              } catch (error) {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
+              }
+              xhr.send();
+            }
+            return {
+              load: loadAsset,
+            };
+          }());
+        }
+
+        if (e.data.type === 'loadAnimation') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.dataManager.completeData(data);
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        } else if (e.data.type === 'complete') {
+          var animation = e.data.animation;
+          _workerSelf.dataManager.completeData(animation);
+          _workerSelf.postMessage({
+            id: e.data.id,
+            payload: animation,
+            status: 'success',
+          });
+        } else if (e.data.type === 'loadData') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        }
+      });
+
+      workerInstance.onmessage = function (event) {
+        var data = event.data;
+        var id = data.id;
+        var process = processes[id];
+        processes[id] = null;
+        if (data.status === 'success') {
+          process.onComplete(data.payload);
+        } else if (process.onError) {
+          process.onError();
+        }
+      };
+    }
+  }
+
+  function createProcess(onComplete, onError) {
+    _counterId += 1;
+    var id = 'processId_' + _counterId;
+    processes[id] = {
+      onComplete: onComplete,
+      onError: onError,
+    };
+    return id;
+  }
+
+  function loadAnimation(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadAnimation',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function loadData(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadData',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function completeAnimation(anim, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'complete',
+      animation: anim,
+      id: processId,
+    });
+  }
+
+  return {
+    loadAnimation: loadAnimation,
+    loadData: loadData,
+    completeAnimation: completeAnimation,
+  };
+}());
+
+const ImagePreloader = (function () {
+  var proxyImage = (function () {
+    var canvas = createTag('canvas');
+    canvas.width = 1;
+    canvas.height = 1;
+    var ctx = canvas.getContext('2d');
+    ctx.fillStyle = 'rgba(0,0,0,0)';
+    ctx.fillRect(0, 0, 1, 1);
+    return canvas;
+  }());
+
+  function imageLoaded() {
+    this.loadedAssets += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+  function footageLoaded() {
+    this.loadedFootagesCount += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+
+  function getAssetsPath(assetData, assetsPath, originalPath) {
+    var path = '';
+    if (assetData.e) {
+      path = assetData.p;
+    } else if (assetsPath) {
+      var imagePath = assetData.p;
+      if (imagePath.indexOf('images/') !== -1) {
+        imagePath = imagePath.split('/')[1];
+      }
+      path = assetsPath + imagePath;
+    } else {
+      path = originalPath;
+      path += assetData.u ? assetData.u : '';
+      path += assetData.p;
+    }
+    return path;
+  }
+
+  function testImageLoaded(img) {
+    var _count = 0;
+    var intervalId = setInterval(function () {
+      var box = img.getBBox();
+      if (box.width || _count > 500) {
+        this._imageLoaded();
+        clearInterval(intervalId);
+      }
+      _count += 1;
+    }.bind(this), 50);
+  }
+
+  function createImageData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createNS('image');
+    if (isSafari) {
+      this.testImageLoaded(img);
+    } else {
+      img.addEventListener('load', this._imageLoaded, false);
+    }
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
+    if (this._elementHelper.append) {
+      this._elementHelper.append(img);
+    } else {
+      this._elementHelper.appendChild(img);
+    }
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createImgData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createTag('img');
+    img.crossOrigin = 'anonymous';
+    img.addEventListener('load', this._imageLoaded, false);
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.src = path;
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createFootageData(data) {
+    var ob = {
+      assetData: data,
+    };
+    var path = getAssetsPath(data, this.assetsPath, this.path);
+    dataManager.loadData(path, function (footageData) {
+      ob.img = footageData;
+      this._footageLoaded();
+    }.bind(this), function () {
+      ob.img = {};
+      this._footageLoaded();
+    }.bind(this));
+    return ob;
+  }
+
+  function loadAssets(assets, cb) {
+    this.imagesLoadedCb = cb;
+    var i;
+    var len = assets.length;
+    for (i = 0; i < len; i += 1) {
+      if (!assets[i].layers) {
+        if (!assets[i].t || assets[i].t === 'seq') {
+          this.totalImages += 1;
+          this.images.push(this._createImageData(assets[i]));
+        } else if (assets[i].t === 3) {
+          this.totalFootages += 1;
+          this.images.push(this.createFootageData(assets[i]));
+        }
+      }
+    }
+  }
+
+  function setPath(path) {
+    this.path = path || '';
+  }
+
+  function setAssetsPath(path) {
+    this.assetsPath = path || '';
+  }
+
+  function getAsset(assetData) {
+    var i = 0;
+    var len = this.images.length;
+    while (i < len) {
+      if (this.images[i].assetData === assetData) {
+        return this.images[i].img;
+      }
+      i += 1;
+    }
+    return null;
+  }
+
+  function destroy() {
+    this.imagesLoadedCb = null;
+    this.images.length = 0;
+  }
+
+  function loadedImages() {
+    return this.totalImages === this.loadedAssets;
+  }
+
+  function loadedFootages() {
+    return this.totalFootages === this.loadedFootagesCount;
+  }
+
+  function setCacheType(type, elementHelper) {
+    if (type === 'svg') {
+      this._elementHelper = elementHelper;
+      this._createImageData = this.createImageData.bind(this);
+    } else {
+      this._createImageData = this.createImgData.bind(this);
+    }
+  }
+
+  function ImagePreloaderFactory() {
+    this._imageLoaded = imageLoaded.bind(this);
+    this._footageLoaded = footageLoaded.bind(this);
+    this.testImageLoaded = testImageLoaded.bind(this);
+    this.createFootageData = createFootageData.bind(this);
+    this.assetsPath = '';
+    this.path = '';
+    this.totalImages = 0;
+    this.totalFootages = 0;
+    this.loadedAssets = 0;
+    this.loadedFootagesCount = 0;
+    this.imagesLoadedCb = null;
+    this.images = [];
+  }
+
+  ImagePreloaderFactory.prototype = {
+    loadAssets: loadAssets,
+    setAssetsPath: setAssetsPath,
+    setPath: setPath,
+    loadedImages: loadedImages,
+    loadedFootages: loadedFootages,
+    destroy: destroy,
+    getAsset: getAsset,
+    createImgData: createImgData,
+    createImageData: createImageData,
+    imageLoaded: imageLoaded,
+    footageLoaded: footageLoaded,
+    setCacheType: setCacheType,
+  };
+
+  return ImagePreloaderFactory;
+}());
+
+function BaseEvent() {}
+BaseEvent.prototype = {
+  triggerEvent: function (eventName, args) {
+    if (this._cbs[eventName]) {
+      var callbacks = this._cbs[eventName];
+      for (var i = 0; i < callbacks.length; i += 1) {
+        callbacks[i](args);
+      }
+    }
+  },
+  addEventListener: function (eventName, callback) {
+    if (!this._cbs[eventName]) {
+      this._cbs[eventName] = [];
+    }
+    this._cbs[eventName].push(callback);
+
+    return function () {
+      this.removeEventListener(eventName, callback);
+    }.bind(this);
+  },
+  removeEventListener: function (eventName, callback) {
+    if (!callback) {
+      this._cbs[eventName] = null;
+    } else if (this._cbs[eventName]) {
+      var i = 0;
+      var len = this._cbs[eventName].length;
+      while (i < len) {
+        if (this._cbs[eventName][i] === callback) {
+          this._cbs[eventName].splice(i, 1);
+          i -= 1;
+          len -= 1;
+        }
+        i += 1;
+      }
+      if (!this._cbs[eventName].length) {
+        this._cbs[eventName] = null;
+      }
+    }
+  },
+};
+
+const markerParser = (
+
+  function () {
+    function parsePayloadLines(payload) {
+      var lines = payload.split('\r\n');
+      var keys = {};
+      var line;
+      var keysCount = 0;
+      for (var i = 0; i < lines.length; i += 1) {
+        line = lines[i].split(':');
+        if (line.length === 2) {
+          keys[line[0]] = line[1].trim();
+          keysCount += 1;
+        }
+      }
+      if (keysCount === 0) {
+        throw new Error();
+      }
+      return keys;
+    }
+
+    return function (_markers) {
+      var markers = [];
+      for (var i = 0; i < _markers.length; i += 1) {
+        var _marker = _markers[i];
+        var markerData = {
+          time: _marker.tm,
+          duration: _marker.dr,
+        };
+        try {
+          markerData.payload = JSON.parse(_markers[i].cm);
+        } catch (_) {
+          try {
+            markerData.payload = parsePayloadLines(_markers[i].cm);
+          } catch (__) {
+            markerData.payload = {
+              name: _markers[i].cm,
+            };
+          }
+        }
+        markers.push(markerData);
+      }
+      return markers;
+    };
+  }());
+
+const ProjectInterface = (function () {
+  function registerComposition(comp) {
+    this.compositions.push(comp);
+  }
+
+  return function () {
+    function _thisProjectFunction(name) {
+      var i = 0;
+      var len = this.compositions.length;
+      while (i < len) {
+        if (this.compositions[i].data && this.compositions[i].data.nm === name) {
+          if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
+            this.compositions[i].prepareFrame(this.currentFrame);
+          }
+          return this.compositions[i].compInterface;
+        }
+        i += 1;
+      }
+      return null;
+    }
+
+    _thisProjectFunction.compositions = [];
+    _thisProjectFunction.currentFrame = 0;
+
+    _thisProjectFunction.registerComposition = registerComposition;
+
+    return _thisProjectFunction;
+  };
+}());
+
+const renderers = {};
+
+const registerRenderer = (key, value) => {
+  renderers[key] = value;
+};
+
+function getRenderer(key) {
+  return renderers[key];
+}
+
+function getRegisteredRenderer() {
+  // Returns canvas by default for compatibility
+  if (renderers.canvas) {
+    return 'canvas';
+  }
+  // Returns any renderer that is registered
+  for (const key in renderers) {
+    if (renderers[key]) {
+      return key;
+    }
+  }
+  return '';
+}
+
+const AnimationItem = function () {
+  this._cbs = [];
+  this.name = '';
+  this.path = '';
+  this.isLoaded = false;
+  this.currentFrame = 0;
+  this.currentRawFrame = 0;
+  this.firstFrame = 0;
+  this.totalFrames = 0;
+  this.frameRate = 0;
+  this.frameMult = 0;
+  this.playSpeed = 1;
+  this.playDirection = 1;
+  this.playCount = 0;
+  this.animationData = {};
+  this.assets = [];
+  this.isPaused = true;
+  this.autoplay = false;
+  this.loop = true;
+  this.renderer = null;
+  this.animationID = createElementID();
+  this.assetsPath = '';
+  this.timeCompleted = 0;
+  this.segmentPos = 0;
+  this.isSubframeEnabled = getSubframeEnabled();
+  this.segments = [];
+  this._idle = true;
+  this._completedLoop = false;
+  this.projectInterface = ProjectInterface();
+  this.imagePreloader = new ImagePreloader();
+  this.audioController = audioControllerFactory();
+  this.markers = [];
+  this.configAnimation = this.configAnimation.bind(this);
+  this.onSetupError = this.onSetupError.bind(this);
+  this.onSegmentComplete = this.onSegmentComplete.bind(this);
+  this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
+  this.expressionsPlugin = getExpressionsPlugin();
+};
+
+extendPrototype([BaseEvent], AnimationItem);
+
+AnimationItem.prototype.setParams = function (params) {
+  if (params.wrapper || params.container) {
+    this.wrapper = params.wrapper || params.container;
+  }
+  var animType = 'svg';
+  if (params.animType) {
+    animType = params.animType;
+  } else if (params.renderer) {
+    animType = params.renderer;
+  }
+  const RendererClass = getRenderer(animType);
+  this.renderer = new RendererClass(this, params.rendererSettings);
+  this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
+  this.renderer.setProjectInterface(this.projectInterface);
+  this.animType = animType;
+  if (params.loop === ''
+        || params.loop === null
+        || params.loop === undefined
+        || params.loop === true) {
+    this.loop = true;
+  } else if (params.loop === false) {
+    this.loop = false;
+  } else {
+    this.loop = parseInt(params.loop, 10);
+  }
+  this.autoplay = 'autoplay' in params ? params.autoplay : true;
+  this.name = params.name ? params.name : '';
+  this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
+  this.assetsPath = params.assetsPath;
+  this.initialSegment = params.initialSegment;
+  if (params.audioFactory) {
+    this.audioController.setAudioFactory(params.audioFactory);
+  }
+  if (params.animationData) {
+    this.setupAnimation(params.animationData);
+  } else if (params.path) {
+    if (params.path.lastIndexOf('\\') !== -1) {
+      this.path = params.path.substr(0, params.path.lastIndexOf('\\') + 1);
+    } else {
+      this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
+    }
+    this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
+    this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
+    dataManager.loadAnimation(
+      params.path,
+      this.configAnimation,
+      this.onSetupError
+    );
+  }
+};
+
+AnimationItem.prototype.onSetupError = function () {
+  this.trigger('data_failed');
+};
+
+AnimationItem.prototype.setupAnimation = function (data) {
+  dataManager.completeAnimation(
+    data,
+    this.configAnimation
+  );
+};
+
+AnimationItem.prototype.setData = function (wrapper, animationData) {
+  if (animationData) {
+    if (typeof animationData !== 'object') {
+      animationData = JSON.parse(animationData);
+    }
+  }
+  var params = {
+    wrapper: wrapper,
+    animationData: animationData,
+  };
+  var wrapperAttributes = wrapper.attributes;
+
+  params.path = wrapperAttributes.getNamedItem('data-animation-path') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-animation-path').value
+    : wrapperAttributes.getNamedItem('data-bm-path') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-path').value
+      : wrapperAttributes.getNamedItem('bm-path')
+        ? wrapperAttributes.getNamedItem('bm-path').value
+        : '';
+  params.animType = wrapperAttributes.getNamedItem('data-anim-type') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-type').value
+    : wrapperAttributes.getNamedItem('data-bm-type') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-type').value
+      : wrapperAttributes.getNamedItem('bm-type') // eslint-disable-line no-nested-ternary
+        ? wrapperAttributes.getNamedItem('bm-type').value
+        : wrapperAttributes.getNamedItem('data-bm-renderer') // eslint-disable-line no-nested-ternary
+          ? wrapperAttributes.getNamedItem('data-bm-renderer').value
+          : wrapperAttributes.getNamedItem('bm-renderer')
+            ? wrapperAttributes.getNamedItem('bm-renderer').value
+            : getRegisteredRenderer() || 'canvas';
+
+  var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-loop').value
+    : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-loop').value
+      : wrapperAttributes.getNamedItem('bm-loop')
+        ? wrapperAttributes.getNamedItem('bm-loop').value
+        : '';
+  if (loop === 'false') {
+    params.loop = false;
+  } else if (loop === 'true') {
+    params.loop = true;
+  } else if (loop !== '') {
+    params.loop = parseInt(loop, 10);
+  }
+  var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-autoplay').value
+    : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-autoplay').value
+      : wrapperAttributes.getNamedItem('bm-autoplay')
+        ? wrapperAttributes.getNamedItem('bm-autoplay').value
+        : true;
+  params.autoplay = autoplay !== 'false';
+
+  params.name = wrapperAttributes.getNamedItem('data-name') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-name').value
+    : wrapperAttributes.getNamedItem('data-bm-name') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-name').value
+      : wrapperAttributes.getNamedItem('bm-name')
+        ? wrapperAttributes.getNamedItem('bm-name').value
+        : '';
+  var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-prerender').value
+    : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-prerender').value
+      : wrapperAttributes.getNamedItem('bm-prerender')
+        ? wrapperAttributes.getNamedItem('bm-prerender').value
+        : '';
+
+  if (prerender === 'false') {
+    params.prerender = false;
+  }
+  if (!params.path) {
+    this.trigger('destroy');
+  } else {
+    this.setParams(params);
+  }
+};
+
+AnimationItem.prototype.includeLayers = function (data) {
+  if (data.op > this.animationData.op) {
+    this.animationData.op = data.op;
+    this.totalFrames = Math.floor(data.op - this.animationData.ip);
+  }
+  var layers = this.animationData.layers;
+  var i;
+  var len = layers.length;
+  var newLayers = data.layers;
+  var j;
+  var jLen = newLayers.length;
+  for (j = 0; j < jLen; j += 1) {
+    i = 0;
+    while (i < len) {
+      if (layers[i].id === newLayers[j].id) {
+        layers[i] = newLayers[j];
+        break;
+      }
+      i += 1;
+    }
+  }
+  if (data.chars || data.fonts) {
+    this.renderer.globalData.fontManager.addChars(data.chars);
+    this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
+  }
+  if (data.assets) {
+    len = data.assets.length;
+    for (i = 0; i < len; i += 1) {
+      this.animationData.assets.push(data.assets[i]);
+    }
+  }
+  this.animationData.__complete = false;
+  dataManager.completeAnimation(
+    this.animationData,
+    this.onSegmentComplete
+  );
+};
+
+AnimationItem.prototype.onSegmentComplete = function (data) {
+  this.animationData = data;
+  var expressionsPlugin = getExpressionsPlugin();
+  if (expressionsPlugin) {
+    expressionsPlugin.initExpressions(this);
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.loadNextSegment = function () {
+  var segments = this.animationData.segments;
+  if (!segments || segments.length === 0 || !this.autoloadSegments) {
+    this.trigger('data_ready');
+    this.timeCompleted = this.totalFrames;
+    return;
+  }
+  var segment = segments.shift();
+  this.timeCompleted = segment.time * this.frameRate;
+  var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
+  this.segmentPos += 1;
+  dataManager.loadData(segmentPath, this.includeLayers.bind(this), function () {
+    this.trigger('data_failed');
+  }.bind(this));
+};
+
+AnimationItem.prototype.loadSegments = function () {
+  var segments = this.animationData.segments;
+  if (!segments) {
+    this.timeCompleted = this.totalFrames;
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.imagesLoaded = function () {
+  this.trigger('loaded_images');
+  this.checkLoaded();
+};
+
+AnimationItem.prototype.preloadImages = function () {
+  this.imagePreloader.setAssetsPath(this.assetsPath);
+  this.imagePreloader.setPath(this.path);
+  this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
+};
+
+AnimationItem.prototype.configAnimation = function (animData) {
+  if (!this.renderer) {
+    return;
+  }
+  try {
+    this.animationData = animData;
+    if (this.initialSegment) {
+      this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
+      this.firstFrame = Math.round(this.initialSegment[0]);
+    } else {
+      this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
+      this.firstFrame = Math.round(this.animationData.ip);
+    }
+    this.renderer.configAnimation(animData);
+    if (!animData.assets) {
+      animData.assets = [];
+    }
+
+    this.assets = this.animationData.assets;
+    this.frameRate = this.animationData.fr;
+    this.frameMult = this.animationData.fr / 1000;
+    this.renderer.searchExtraCompositions(animData.assets);
+    this.markers = markerParser(animData.markers || []);
+    this.trigger('config_ready');
+    this.preloadImages();
+    this.loadSegments();
+    this.updaFrameModifier();
+    this.waitForFontsLoaded();
+    if (this.isPaused) {
+      this.audioController.pause();
+    }
+  } catch (error) {
+    this.triggerConfigError(error);
+  }
+};
+
+AnimationItem.prototype.waitForFontsLoaded = function () {
+  if (!this.renderer) {
+    return;
+  }
+  if (this.renderer.globalData.fontManager.isLoaded) {
+    this.checkLoaded();
+  } else {
+    setTimeout(this.waitForFontsLoaded.bind(this), 20);
+  }
+};
+
+AnimationItem.prototype.checkLoaded = function () {
+  if (!this.isLoaded
+        && this.renderer.globalData.fontManager.isLoaded
+        && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas')
+        && (this.imagePreloader.loadedFootages())
+  ) {
+    this.isLoaded = true;
+    var expressionsPlugin = getExpressionsPlugin();
+    if (expressionsPlugin) {
+      expressionsPlugin.initExpressions(this);
+    }
+    this.renderer.initItems();
+    setTimeout(function () {
+      this.trigger('DOMLoaded');
+    }.bind(this), 0);
+    this.gotoFrame();
+    if (this.autoplay) {
+      this.play();
+    }
+  }
+};
+
+AnimationItem.prototype.resize = function (width, height) {
+  // Adding this validation for backwards compatibility in case an event object was being passed down
+  var _width = typeof width === 'number' ? width : undefined;
+  var _height = typeof height === 'number' ? height : undefined;
+  this.renderer.updateContainerSize(_width, _height);
+};
+
+AnimationItem.prototype.setSubframe = function (flag) {
+  this.isSubframeEnabled = !!flag;
+};
+
+AnimationItem.prototype.gotoFrame = function () {
+  this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
+
+  if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
+    this.currentFrame = this.timeCompleted;
+  }
+  this.trigger('enterFrame');
+  this.renderFrame();
+  this.trigger('drawnFrame');
+};
+
+AnimationItem.prototype.renderFrame = function () {
+  if (this.isLoaded === false || !this.renderer) {
+    return;
+  }
+  try {
+    if (this.expressionsPlugin) {
+      this.expressionsPlugin.resetFrame();
+    }
+    this.renderer.renderFrame(this.currentFrame + this.firstFrame);
+  } catch (error) {
+    this.triggerRenderFrameError(error);
+  }
+};
+
+AnimationItem.prototype.play = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.isPaused = false;
+    this.trigger('_play');
+    this.audioController.resume();
+    if (this._idle) {
+      this._idle = false;
+      this.trigger('_active');
+    }
+  }
+};
+
+AnimationItem.prototype.pause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === false) {
+    this.isPaused = true;
+    this.trigger('_pause');
+    this._idle = true;
+    this.trigger('_idle');
+    this.audioController.pause();
+  }
+};
+
+AnimationItem.prototype.togglePause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.play();
+  } else {
+    this.pause();
+  }
+};
+
+AnimationItem.prototype.stop = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.pause();
+  this.playCount = 0;
+  this._completedLoop = false;
+  this.setCurrentRawFrameValue(0);
+};
+
+AnimationItem.prototype.getMarkerData = function (markerName) {
+  var marker;
+  for (var i = 0; i < this.markers.length; i += 1) {
+    marker = this.markers[i];
+    if (marker.payload && marker.payload.name === markerName) {
+      return marker;
+    }
+  }
+  return null;
+};
+
+AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      this.goToAndStop(marker.time, true);
+    }
+  } else if (isFrame) {
+    this.setCurrentRawFrameValue(value);
+  } else {
+    this.setCurrentRawFrameValue(value * this.frameModifier);
+  }
+  this.pause();
+};
+
+AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      if (!marker.duration) {
+        this.goToAndStop(marker.time, true);
+      } else {
+        this.playSegments([marker.time, marker.time + marker.duration], true);
+      }
+    }
+  } else {
+    this.goToAndStop(numValue, isFrame, name);
+  }
+  this.play();
+};
+
+AnimationItem.prototype.advanceTime = function (value) {
+  if (this.isPaused === true || this.isLoaded === false) {
+    return;
+  }
+  var nextValue = this.currentRawFrame + value * this.frameModifier;
+  var _isComplete = false;
+  // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+  // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
+  if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
+    if (!this.loop || this.playCount === this.loop) {
+      if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
+        _isComplete = true;
+        nextValue = this.totalFrames - 1;
+      }
+    } else if (nextValue >= this.totalFrames) {
+      this.playCount += 1;
+      if (!this.checkSegments(nextValue % this.totalFrames)) {
+        this.setCurrentRawFrameValue(nextValue % this.totalFrames);
+        this._completedLoop = true;
+        this.trigger('loopComplete');
+      }
+    } else {
+      this.setCurrentRawFrameValue(nextValue);
+    }
+  } else if (nextValue < 0) {
+    if (!this.checkSegments(nextValue % this.totalFrames)) {
+      if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) { // eslint-disable-line no-plusplus
+        this.setCurrentRawFrameValue(this.totalFrames + (nextValue % this.totalFrames));
+        if (!this._completedLoop) {
+          this._completedLoop = true;
+        } else {
+          this.trigger('loopComplete');
+        }
+      } else {
+        _isComplete = true;
+        nextValue = 0;
+      }
+    }
+  } else {
+    this.setCurrentRawFrameValue(nextValue);
+  }
+  if (_isComplete) {
+    this.setCurrentRawFrameValue(nextValue);
+    this.pause();
+    this.trigger('complete');
+  }
+};
+
+AnimationItem.prototype.adjustSegment = function (arr, offset) {
+  this.playCount = 0;
+  if (arr[1] < arr[0]) {
+    if (this.frameModifier > 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(-1);
+      }
+    }
+    this.totalFrames = arr[0] - arr[1];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[1];
+    this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset);
+  } else if (arr[1] > arr[0]) {
+    if (this.frameModifier < 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(1);
+      }
+    }
+    this.totalFrames = arr[1] - arr[0];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[0];
+    this.setCurrentRawFrameValue(0.001 + offset);
+  }
+  this.trigger('segmentStart');
+};
+AnimationItem.prototype.setSegment = function (init, end) {
+  var pendingFrame = -1;
+  if (this.isPaused) {
+    if (this.currentRawFrame + this.firstFrame < init) {
+      pendingFrame = init;
+    } else if (this.currentRawFrame + this.firstFrame > end) {
+      pendingFrame = end - init;
+    }
+  }
+
+  this.firstFrame = init;
+  this.totalFrames = end - init;
+  this.timeCompleted = this.totalFrames;
+  if (pendingFrame !== -1) {
+    this.goToAndStop(pendingFrame, true);
+  }
+};
+
+AnimationItem.prototype.playSegments = function (arr, forceFlag) {
+  if (forceFlag) {
+    this.segments.length = 0;
+  }
+  if (typeof arr[0] === 'object') {
+    var i;
+    var len = arr.length;
+    for (i = 0; i < len; i += 1) {
+      this.segments.push(arr[i]);
+    }
+  } else {
+    this.segments.push(arr);
+  }
+  if (this.segments.length && forceFlag) {
+    this.adjustSegment(this.segments.shift(), 0);
+  }
+  if (this.isPaused) {
+    this.play();
+  }
+};
+
+AnimationItem.prototype.resetSegments = function (forceFlag) {
+  this.segments.length = 0;
+  this.segments.push([this.animationData.ip, this.animationData.op]);
+  if (forceFlag) {
+    this.checkSegments(0);
+  }
+};
+AnimationItem.prototype.checkSegments = function (offset) {
+  if (this.segments.length) {
+    this.adjustSegment(this.segments.shift(), offset);
+    return true;
+  }
+  return false;
+};
+
+AnimationItem.prototype.destroy = function (name) {
+  if ((name && this.name !== name) || !this.renderer) {
+    return;
+  }
+  this.renderer.destroy();
+  this.imagePreloader.destroy();
+  this.trigger('destroy');
+  this._cbs = null;
+  this.onEnterFrame = null;
+  this.onLoopComplete = null;
+  this.onComplete = null;
+  this.onSegmentStart = null;
+  this.onDestroy = null;
+  this.renderer = null;
+  this.expressionsPlugin = null;
+  this.imagePreloader = null;
+  this.projectInterface = null;
+};
+
+AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
+  this.currentRawFrame = value;
+  this.gotoFrame();
+};
+
+AnimationItem.prototype.setSpeed = function (val) {
+  this.playSpeed = val;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setDirection = function (val) {
+  this.playDirection = val < 0 ? -1 : 1;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setLoop = function (isLooping) {
+  this.loop = isLooping;
+};
+
+AnimationItem.prototype.setVolume = function (val, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.setVolume(val);
+};
+
+AnimationItem.prototype.getVolume = function () {
+  return this.audioController.getVolume();
+};
+
+AnimationItem.prototype.mute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.mute();
+};
+
+AnimationItem.prototype.unmute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.unmute();
+};
+
+AnimationItem.prototype.updaFrameModifier = function () {
+  this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
+  this.audioController.setRate(this.playSpeed * this.playDirection);
+};
+
+AnimationItem.prototype.getPath = function () {
+  return this.path;
+};
+
+AnimationItem.prototype.getAssetsPath = function (assetData) {
+  var path = '';
+  if (assetData.e) {
+    path = assetData.p;
+  } else if (this.assetsPath) {
+    var imagePath = assetData.p;
+    if (imagePath.indexOf('images/') !== -1) {
+      imagePath = imagePath.split('/')[1];
+    }
+    path = this.assetsPath + imagePath;
+  } else {
+    path = this.path;
+    path += assetData.u ? assetData.u : '';
+    path += assetData.p;
+  }
+  return path;
+};
+
+AnimationItem.prototype.getAssetData = function (id) {
+  var i = 0;
+  var len = this.assets.length;
+  while (i < len) {
+    if (id === this.assets[i].id) {
+      return this.assets[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+AnimationItem.prototype.hide = function () {
+  this.renderer.hide();
+};
+
+AnimationItem.prototype.show = function () {
+  this.renderer.show();
+};
+
+AnimationItem.prototype.getDuration = function (isFrame) {
+  return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
+};
+
+AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
+  try {
+    var element = this.renderer.getElementByPath(path);
+    element.updateDocumentData(documentData, index);
+  } catch (error) {
+    // TODO: decide how to handle catch case
+  }
+};
+
+AnimationItem.prototype.trigger = function (name) {
+  if (this._cbs && this._cbs[name]) {
+    switch (name) {
+      case 'enterFrame':
+        this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
+        break;
+      case 'drawnFrame':
+        this.drawnFrameEvent.currentTime = this.currentFrame;
+        this.drawnFrameEvent.totalTime = this.totalFrames;
+        this.drawnFrameEvent.direction = this.frameModifier;
+        this.triggerEvent(name, this.drawnFrameEvent);
+        break;
+      case 'loopComplete':
+        this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+        break;
+      case 'complete':
+        this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
+        break;
+      case 'segmentStart':
+        this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+        break;
+      case 'destroy':
+        this.triggerEvent(name, new BMDestroyEvent(name, this));
+        break;
+      default:
+        this.triggerEvent(name);
+    }
+  }
+  if (name === 'enterFrame' && this.onEnterFrame) {
+    this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
+  }
+  if (name === 'loopComplete' && this.onLoopComplete) {
+    this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+  }
+  if (name === 'complete' && this.onComplete) {
+    this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
+  }
+  if (name === 'segmentStart' && this.onSegmentStart) {
+    this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+  }
+  if (name === 'destroy' && this.onDestroy) {
+    this.onDestroy.call(this, new BMDestroyEvent(name, this));
+  }
+};
+
+AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
+  var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+AnimationItem.prototype.triggerConfigError = function (nativeError) {
+  var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+const animationManager = (function () {
+  var moduleOb = {};
+  var registeredAnimations = [];
+  var initTime = 0;
+  var len = 0;
+  var playingAnimationsNum = 0;
+  var _stopped = true;
+  var _isFrozen = false;
+
+  function removeElement(ev) {
+    var i = 0;
+    var animItem = ev.target;
+    while (i < len) {
+      if (registeredAnimations[i].animation === animItem) {
+        registeredAnimations.splice(i, 1);
+        i -= 1;
+        len -= 1;
+        if (!animItem.isPaused) {
+          subtractPlayingCount();
+        }
+      }
+      i += 1;
+    }
+  }
+
+  function registerAnimation(element, animationData) {
+    if (!element) {
+      return null;
+    }
+    var i = 0;
+    while (i < len) {
+      if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
+        return registeredAnimations[i].animation;
+      }
+      i += 1;
+    }
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, element);
+    animItem.setData(element, animationData);
+    return animItem;
+  }
+
+  function getRegisteredAnimations() {
+    var i;
+    var lenAnims = registeredAnimations.length;
+    var animations = [];
+    for (i = 0; i < lenAnims; i += 1) {
+      animations.push(registeredAnimations[i].animation);
+    }
+    return animations;
+  }
+
+  function addPlayingCount() {
+    playingAnimationsNum += 1;
+    activate();
+  }
+
+  function subtractPlayingCount() {
+    playingAnimationsNum -= 1;
+  }
+
+  function setupAnimation(animItem, element) {
+    animItem.addEventListener('destroy', removeElement);
+    animItem.addEventListener('_active', addPlayingCount);
+    animItem.addEventListener('_idle', subtractPlayingCount);
+    registeredAnimations.push({ elem: element, animation: animItem });
+    len += 1;
+  }
+
+  function loadAnimation(params) {
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, null);
+    animItem.setParams(params);
+    return animItem;
+  }
+
+  function setSpeed(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setSpeed(val, animation);
+    }
+  }
+
+  function setDirection(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setDirection(val, animation);
+    }
+  }
+
+  function play(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.play(animation);
+    }
+  }
+  function resume(nowTime) {
+    var elapsedTime = nowTime - initTime;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.advanceTime(elapsedTime);
+    }
+    initTime = nowTime;
+    if (playingAnimationsNum && !_isFrozen) {
+      window.requestAnimationFrame(resume);
+    } else {
+      _stopped = true;
+    }
+  }
+
+  function first(nowTime) {
+    initTime = nowTime;
+    window.requestAnimationFrame(resume);
+  }
+
+  function pause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.pause(animation);
+    }
+  }
+
+  function goToAndStop(value, isFrame, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
+    }
+  }
+
+  function stop(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.stop(animation);
+    }
+  }
+
+  function togglePause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.togglePause(animation);
+    }
+  }
+
+  function destroy(animation) {
+    var i;
+    for (i = (len - 1); i >= 0; i -= 1) {
+      registeredAnimations[i].animation.destroy(animation);
+    }
+  }
+
+  function searchAnimations(animationData, standalone, renderer) {
+    var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')),
+      [].slice.call(document.getElementsByClassName('bodymovin')));
+    var i;
+    var lenAnims = animElements.length;
+    for (i = 0; i < lenAnims; i += 1) {
+      if (renderer) {
+        animElements[i].setAttribute('data-bm-type', renderer);
+      }
+      registerAnimation(animElements[i], animationData);
+    }
+    if (standalone && lenAnims === 0) {
+      if (!renderer) {
+        renderer = 'svg';
+      }
+      var body = document.getElementsByTagName('body')[0];
+      body.innerText = '';
+      var div = createTag('div');
+      div.style.width = '100%';
+      div.style.height = '100%';
+      div.setAttribute('data-bm-type', renderer);
+      body.appendChild(div);
+      registerAnimation(div, animationData);
+    }
+  }
+
+  function resize() {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.resize();
+    }
+  }
+
+  function activate() {
+    if (!_isFrozen && playingAnimationsNum) {
+      if (_stopped) {
+        window.requestAnimationFrame(first);
+        _stopped = false;
+      }
+    }
+  }
+
+  function freeze() {
+    _isFrozen = true;
+  }
+
+  function unfreeze() {
+    _isFrozen = false;
+    activate();
+  }
+
+  function setVolume(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setVolume(val, animation);
+    }
+  }
+
+  function mute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.mute(animation);
+    }
+  }
+
+  function unmute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.unmute(animation);
+    }
+  }
+
+  moduleOb.registerAnimation = registerAnimation;
+  moduleOb.loadAnimation = loadAnimation;
+  moduleOb.setSpeed = setSpeed;
+  moduleOb.setDirection = setDirection;
+  moduleOb.play = play;
+  moduleOb.pause = pause;
+  moduleOb.stop = stop;
+  moduleOb.togglePause = togglePause;
+  moduleOb.searchAnimations = searchAnimations;
+  moduleOb.resize = resize;
+  // moduleOb.start = start;
+  moduleOb.goToAndStop = goToAndStop;
+  moduleOb.destroy = destroy;
+  moduleOb.freeze = freeze;
+  moduleOb.unfreeze = unfreeze;
+  moduleOb.setVolume = setVolume;
+  moduleOb.mute = mute;
+  moduleOb.unmute = unmute;
+  moduleOb.getRegisteredAnimations = getRegisteredAnimations;
+  return moduleOb;
+}());
+
+/* eslint-disable */
+const BezierFactory = (function () {
+  /**
+     * BezierEasing - use bezier curve for transition easing function
+     * by Gaëtan Renaudeau 2014 - 2015 – MIT License
+     *
+     * Credits: is based on Firefox's nsSMILKeySpline.cpp
+     * Usage:
+     * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
+     * spline.get(x) => returns the easing value | x must be in [0, 1] range
+     *
+     */
+
+  var ob = {};
+  ob.getBezierEasing = getBezierEasing;
+  var beziers = {};
+
+  function getBezierEasing(a, b, c, d, nm) {
+    var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
+    if (beziers[str]) {
+      return beziers[str];
+    }
+    var bezEasing = new BezierEasing([a, b, c, d]);
+    beziers[str] = bezEasing;
+    return bezEasing;
+  }
+
+  // These values are established by empiricism with tests (tradeoff: performance VS precision)
+  var NEWTON_ITERATIONS = 4;
+  var NEWTON_MIN_SLOPE = 0.001;
+  var SUBDIVISION_PRECISION = 0.0000001;
+  var SUBDIVISION_MAX_ITERATIONS = 10;
+
+  var kSplineTableSize = 11;
+  var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
+
+  var float32ArraySupported = typeof Float32Array === 'function';
+
+  function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
+  function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
+  function C(aA1) { return 3.0 * aA1; }
+
+  // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+  function calcBezier(aT, aA1, aA2) {
+    return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
+  }
+
+  // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+  function getSlope(aT, aA1, aA2) {
+    return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
+  }
+
+  function binarySubdivide(aX, aA, aB, mX1, mX2) {
+    var currentX,
+      currentT,
+      i = 0;
+    do {
+      currentT = aA + (aB - aA) / 2.0;
+      currentX = calcBezier(currentT, mX1, mX2) - aX;
+      if (currentX > 0.0) {
+        aB = currentT;
+      } else {
+        aA = currentT;
+      }
+    } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
+    return currentT;
+  }
+
+  function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
+    for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
+      var currentSlope = getSlope(aGuessT, mX1, mX2);
+      if (currentSlope === 0.0) return aGuessT;
+      var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
+      aGuessT -= currentX / currentSlope;
+    }
+    return aGuessT;
+  }
+
+  /**
+     * points is an array of [ mX1, mY1, mX2, mY2 ]
+     */
+  function BezierEasing(points) {
+    this._p = points;
+    this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
+    this._precomputed = false;
+
+    this.get = this.get.bind(this);
+  }
+
+  BezierEasing.prototype = {
+
+    get: function (x) {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      if (!this._precomputed) this._precompute();
+      if (mX1 === mY1 && mX2 === mY2) return x; // linear
+      // Because JavaScript number are imprecise, we should guarantee the extremes are right.
+      if (x === 0) return 0;
+      if (x === 1) return 1;
+      return calcBezier(this._getTForX(x), mY1, mY2);
+    },
+
+    // Private part
+
+    _precompute: function () {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      this._precomputed = true;
+      if (mX1 !== mY1 || mX2 !== mY2) { this._calcSampleValues(); }
+    },
+
+    _calcSampleValues: function () {
+      var mX1 = this._p[0],
+        mX2 = this._p[2];
+      for (var i = 0; i < kSplineTableSize; ++i) {
+        this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
+      }
+    },
+
+    /**
+         * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
+         */
+    _getTForX: function (aX) {
+      var mX1 = this._p[0],
+        mX2 = this._p[2],
+        mSampleValues = this._mSampleValues;
+
+      var intervalStart = 0.0;
+      var currentSample = 1;
+      var lastSample = kSplineTableSize - 1;
+
+      for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
+        intervalStart += kSampleStepSize;
+      }
+      --currentSample;
+
+      // Interpolate to provide an initial guess for t
+      var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
+      var guessForT = intervalStart + dist * kSampleStepSize;
+
+      var initialSlope = getSlope(guessForT, mX1, mX2);
+      if (initialSlope >= NEWTON_MIN_SLOPE) {
+        return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
+      } if (initialSlope === 0.0) {
+        return guessForT;
+      }
+      return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
+    },
+  };
+
+  return ob;
+}());
+
+const pooling = (function () {
+  function double(arr) {
+    return arr.concat(createSizedArray(arr.length));
+  }
+
+  return {
+    double: double,
+  };
+}());
+
+const poolFactory = (function () {
+  return function (initialLength, _create, _release) {
+    var _length = 0;
+    var _maxLength = initialLength;
+    var pool = createSizedArray(_maxLength);
+
+    var ob = {
+      newElement: newElement,
+      release: release,
+    };
+
+    function newElement() {
+      var element;
+      if (_length) {
+        _length -= 1;
+        element = pool[_length];
+      } else {
+        element = _create();
+      }
+      return element;
+    }
+
+    function release(element) {
+      if (_length === _maxLength) {
+        pool = pooling.double(pool);
+        _maxLength *= 2;
+      }
+      if (_release) {
+        _release(element);
+      }
+      pool[_length] = element;
+      _length += 1;
+    }
+
+    return ob;
+  };
+}());
+
+const bezierLengthPool = (function () {
+  function create() {
+    return {
+      addedLength: 0,
+      percents: createTypedArray('float32', getDefaultCurveSegments()),
+      lengths: createTypedArray('float32', getDefaultCurveSegments()),
+    };
+  }
+  return poolFactory(8, create);
+}());
+
+const segmentsLengthPool = (function () {
+  function create() {
+    return {
+      lengths: [],
+      totalLength: 0,
+    };
+  }
+
+  function release(element) {
+    var i;
+    var len = element.lengths.length;
+    for (i = 0; i < len; i += 1) {
+      bezierLengthPool.release(element.lengths[i]);
+    }
+    element.lengths.length = 0;
+  }
+
+  return poolFactory(8, create, release);
+}());
+
+function bezFunction() {
+  var math = Math;
+
+  function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
+    var det1 = (x1 * y2) + (y1 * x3) + (x2 * y3) - (x3 * y2) - (y3 * x1) - (x2 * y1);
+    return det1 > -0.001 && det1 < 0.001;
+  }
+
+  function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
+    if (z1 === 0 && z2 === 0 && z3 === 0) {
+      return pointOnLine2D(x1, y1, x2, y2, x3, y3);
+    }
+    var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
+    var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
+    var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
+    var diffDist;
+    if (dist1 > dist2) {
+      if (dist1 > dist3) {
+        diffDist = dist1 - dist2 - dist3;
+      } else {
+        diffDist = dist3 - dist2 - dist1;
+      }
+    } else if (dist3 > dist2) {
+      diffDist = dist3 - dist2 - dist1;
+    } else {
+      diffDist = dist2 - dist1 - dist3;
+    }
+    return diffDist > -0.0001 && diffDist < 0.0001;
+  }
+
+  var getBezierLength = (function () {
+    return function (pt1, pt2, pt3, pt4) {
+      var curveSegments = getDefaultCurveSegments();
+      var k;
+      var i;
+      var len;
+      var ptCoord;
+      var perc;
+      var addedLength = 0;
+      var ptDistance;
+      var point = [];
+      var lastPoint = [];
+      var lengthData = bezierLengthPool.newElement();
+      len = pt3.length;
+      for (k = 0; k < curveSegments; k += 1) {
+        perc = k / (curveSegments - 1);
+        ptDistance = 0;
+        for (i = 0; i < len; i += 1) {
+          ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
+          point[i] = ptCoord;
+          if (lastPoint[i] !== null) {
+            ptDistance += bmPow(point[i] - lastPoint[i], 2);
+          }
+          lastPoint[i] = point[i];
+        }
+        if (ptDistance) {
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+        }
+        lengthData.percents[k] = perc;
+        lengthData.lengths[k] = addedLength;
+      }
+      lengthData.addedLength = addedLength;
+      return lengthData;
+    };
+  }());
+
+  function getSegmentsLength(shapeData) {
+    var segmentsLength = segmentsLengthPool.newElement();
+    var closed = shapeData.c;
+    var pathV = shapeData.v;
+    var pathO = shapeData.o;
+    var pathI = shapeData.i;
+    var i;
+    var len = shapeData._length;
+    var lengths = segmentsLength.lengths;
+    var totalLength = 0;
+    for (i = 0; i < len - 1; i += 1) {
+      lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
+      totalLength += lengths[i].addedLength;
+    }
+    if (closed && len) {
+      lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
+      totalLength += lengths[i].addedLength;
+    }
+    segmentsLength.totalLength = totalLength;
+    return segmentsLength;
+  }
+
+  function BezierData(length) {
+    this.segmentLength = 0;
+    this.points = new Array(length);
+  }
+
+  function PointData(partial, point) {
+    this.partialLength = partial;
+    this.point = point;
+  }
+
+  var buildBezierData = (function () {
+    var storedData = {};
+
+    return function (pt1, pt2, pt3, pt4) {
+      var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
+      if (!storedData[bezierName]) {
+        var curveSegments = getDefaultCurveSegments();
+        var k;
+        var i;
+        var len;
+        var ptCoord;
+        var perc;
+        var addedLength = 0;
+        var ptDistance;
+        var point;
+        var lastPoint = null;
+        if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
+          curveSegments = 2;
+        }
+        var bezierData = new BezierData(curveSegments);
+        len = pt3.length;
+        for (k = 0; k < curveSegments; k += 1) {
+          point = createSizedArray(len);
+          perc = k / (curveSegments - 1);
+          ptDistance = 0;
+          for (i = 0; i < len; i += 1) {
+            ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
+            point[i] = ptCoord;
+            if (lastPoint !== null) {
+              ptDistance += bmPow(point[i] - lastPoint[i], 2);
+            }
+          }
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+          bezierData.points[k] = new PointData(ptDistance, point);
+          lastPoint = point;
+        }
+        bezierData.segmentLength = addedLength;
+        storedData[bezierName] = bezierData;
+      }
+      return storedData[bezierName];
+    };
+  }());
+
+  function getDistancePerc(perc, bezierData) {
+    var percents = bezierData.percents;
+    var lengths = bezierData.lengths;
+    var len = percents.length;
+    var initPos = bmFloor((len - 1) * perc);
+    var lengthPos = perc * bezierData.addedLength;
+    var lPerc = 0;
+    if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
+      return percents[initPos];
+    }
+    var dir = lengths[initPos] > lengthPos ? -1 : 1;
+    var flag = true;
+    while (flag) {
+      if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
+        lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
+        flag = false;
+      } else {
+        initPos += dir;
+      }
+      if (initPos < 0 || initPos >= len - 1) {
+        // FIX for TypedArrays that don't store floating point values with enough accuracy
+        if (initPos === len - 1) {
+          return percents[initPos];
+        }
+        flag = false;
+      }
+    }
+    return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
+  }
+
+  function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
+    var t1 = getDistancePerc(percent, bezierData);
+    var u1 = 1 - t1;
+    var ptX = math.round((u1 * u1 * u1 * pt1[0] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[0] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[0] + t1 * t1 * t1 * pt2[0]) * 1000) / 1000;
+    var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
+    return [ptX, ptY];
+  }
+
+  var bezierSegmentPoints = createTypedArray('float32', 8);
+
+  function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
+    if (startPerc < 0) {
+      startPerc = 0;
+    } else if (startPerc > 1) {
+      startPerc = 1;
+    }
+    var t0 = getDistancePerc(startPerc, bezierData);
+    endPerc = endPerc > 1 ? 1 : endPerc;
+    var t1 = getDistancePerc(endPerc, bezierData);
+    var i;
+    var len = pt1.length;
+    var u0 = 1 - t0;
+    var u1 = 1 - t1;
+    var u0u0u0 = u0 * u0 * u0;
+    var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0t0 = t0 * t0 * t0;
+    //
+    var u0u0u1 = u0 * u0 * u1;
+    var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0t1 = t0 * t0 * t1;
+    //
+    var u0u1u1 = u0 * u1 * u1;
+    var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1t1 = t0 * t1 * t1;
+    //
+    var u1u1u1 = u1 * u1 * u1;
+    var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1t1 = t1 * t1 * t1;
+    for (i = 0; i < len; i += 1) {
+      bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+    }
+
+    return bezierSegmentPoints;
+  }
+
+  return {
+    getSegmentsLength: getSegmentsLength,
+    getNewSegment: getNewSegment,
+    getPointInSegment: getPointInSegment,
+    buildBezierData: buildBezierData,
+    pointOnLine2D: pointOnLine2D,
+    pointOnLine3D: pointOnLine3D,
+  };
+}
+
+const bez = bezFunction();
+
+var initFrame = initialDefaultFrame;
+var mathAbs = Math.abs;
+
+function interpolateValue(frameNum, caching) {
+  var offsetTime = this.offsetTime;
+  var newValue;
+  if (this.propType === 'multidimensional') {
+    newValue = createTypedArray('float32', this.pv.length);
+  }
+  var iterationIndex = caching.lastIndex;
+  var i = iterationIndex;
+  var len = this.keyframes.length - 1;
+  var flag = true;
+  var keyData;
+  var nextKeyData;
+  var keyframeMetadata;
+
+  while (flag) {
+    keyData = this.keyframes[i];
+    nextKeyData = this.keyframes[i + 1];
+    if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
+      if (keyData.h) {
+        keyData = nextKeyData;
+      }
+      iterationIndex = 0;
+      break;
+    }
+    if ((nextKeyData.t - offsetTime) > frameNum) {
+      iterationIndex = i;
+      break;
+    }
+    if (i < len - 1) {
+      i += 1;
+    } else {
+      iterationIndex = 0;
+      flag = false;
+    }
+  }
+  keyframeMetadata = this.keyframesMetadata[i] || {};
+
+  var k;
+  var kLen;
+  var perc;
+  var jLen;
+  var j;
+  var fnc;
+  var nextKeyTime = nextKeyData.t - offsetTime;
+  var keyTime = keyData.t - offsetTime;
+  var endValue;
+  if (keyData.to) {
+    if (!keyframeMetadata.bezierData) {
+      keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
+    }
+    var bezierData = keyframeMetadata.bezierData;
+    if (frameNum >= nextKeyTime || frameNum < keyTime) {
+      var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
+      kLen = bezierData.points[ind].point.length;
+      for (k = 0; k < kLen; k += 1) {
+        newValue[k] = bezierData.points[ind].point[k];
+      }
+      // caching._lastKeyframeIndex = -1;
+    } else {
+      if (keyframeMetadata.__fnct) {
+        fnc = keyframeMetadata.__fnct;
+      } else {
+        fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
+        keyframeMetadata.__fnct = fnc;
+      }
+      perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+      var distanceInLine = bezierData.segmentLength * perc;
+
+      var segmentPerc;
+      var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0;
+      j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0;
+      flag = true;
+      jLen = bezierData.points.length;
+      while (flag) {
+        addedLength += bezierData.points[j].partialLength;
+        if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k];
+          }
+          break;
+        } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
+          segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
+          }
+          break;
+        }
+        if (j < jLen - 1) {
+          j += 1;
+        } else {
+          flag = false;
+        }
+      }
+      caching._lastPoint = j;
+      caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
+      caching._lastKeyframeIndex = i;
+    }
+  } else {
+    var outX;
+    var outY;
+    var inX;
+    var inY;
+    var keyValue;
+    len = keyData.s.length;
+    endValue = nextKeyData.s || keyData.e;
+    if (this.sh && keyData.h !== 1) {
+      if (frameNum >= nextKeyTime) {
+        newValue[0] = endValue[0];
+        newValue[1] = endValue[1];
+        newValue[2] = endValue[2];
+      } else if (frameNum <= keyTime) {
+        newValue[0] = keyData.s[0];
+        newValue[1] = keyData.s[1];
+        newValue[2] = keyData.s[2];
+      } else {
+        var quatStart = createQuaternion(keyData.s);
+        var quatEnd = createQuaternion(endValue);
+        var time = (frameNum - keyTime) / (nextKeyTime - keyTime);
+        quaternionToEuler(newValue, slerp(quatStart, quatEnd, time));
+      }
+    } else {
+      for (i = 0; i < len; i += 1) {
+        if (keyData.h !== 1) {
+          if (frameNum >= nextKeyTime) {
+            perc = 1;
+          } else if (frameNum < keyTime) {
+            perc = 0;
+          } else {
+            if (keyData.o.x.constructor === Array) {
+              if (!keyframeMetadata.__fnct) {
+                keyframeMetadata.__fnct = [];
+              }
+              if (!keyframeMetadata.__fnct[i]) {
+                outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
+                outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
+                inX = keyData.i.x[i] === undefined ? keyData.i.x[0] : keyData.i.x[i];
+                inY = keyData.i.y[i] === undefined ? keyData.i.y[0] : keyData.i.y[i];
+                fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+                keyframeMetadata.__fnct[i] = fnc;
+              } else {
+                fnc = keyframeMetadata.__fnct[i];
+              }
+            } else if (!keyframeMetadata.__fnct) {
+              outX = keyData.o.x;
+              outY = keyData.o.y;
+              inX = keyData.i.x;
+              inY = keyData.i.y;
+              fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+              keyData.keyframeMetadata = fnc;
+            } else {
+              fnc = keyframeMetadata.__fnct;
+            }
+            perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+          }
+        }
+
+        endValue = nextKeyData.s || keyData.e;
+        keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
+
+        if (this.propType === 'multidimensional') {
+          newValue[i] = keyValue;
+        } else {
+          newValue = keyValue;
+        }
+      }
+    }
+  }
+  caching.lastIndex = iterationIndex;
+  return newValue;
+}
+
+// based on @Toji's https://github.com/toji/gl-matrix/
+function slerp(a, b, t) {
+  var out = [];
+  var ax = a[0];
+  var ay = a[1];
+  var az = a[2];
+  var aw = a[3];
+  var bx = b[0];
+  var by = b[1];
+  var bz = b[2];
+  var bw = b[3];
+
+  var omega;
+  var cosom;
+  var sinom;
+  var scale0;
+  var scale1;
+
+  cosom = ax * bx + ay * by + az * bz + aw * bw;
+  if (cosom < 0.0) {
+    cosom = -cosom;
+    bx = -bx;
+    by = -by;
+    bz = -bz;
+    bw = -bw;
+  }
+  if ((1.0 - cosom) > 0.000001) {
+    omega = Math.acos(cosom);
+    sinom = Math.sin(omega);
+    scale0 = Math.sin((1.0 - t) * omega) / sinom;
+    scale1 = Math.sin(t * omega) / sinom;
+  } else {
+    scale0 = 1.0 - t;
+    scale1 = t;
+  }
+  out[0] = scale0 * ax + scale1 * bx;
+  out[1] = scale0 * ay + scale1 * by;
+  out[2] = scale0 * az + scale1 * bz;
+  out[3] = scale0 * aw + scale1 * bw;
+
+  return out;
+}
+
+function quaternionToEuler(out, quat) {
+  var qx = quat[0];
+  var qy = quat[1];
+  var qz = quat[2];
+  var qw = quat[3];
+  var heading = Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy * qy - 2 * qz * qz);
+  var attitude = Math.asin(2 * qx * qy + 2 * qz * qw);
+  var bank = Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx * qx - 2 * qz * qz);
+  out[0] = heading / degToRads;
+  out[1] = attitude / degToRads;
+  out[2] = bank / degToRads;
+}
+
+function createQuaternion(values) {
+  var heading = values[0] * degToRads;
+  var attitude = values[1] * degToRads;
+  var bank = values[2] * degToRads;
+  var c1 = Math.cos(heading / 2);
+  var c2 = Math.cos(attitude / 2);
+  var c3 = Math.cos(bank / 2);
+  var s1 = Math.sin(heading / 2);
+  var s2 = Math.sin(attitude / 2);
+  var s3 = Math.sin(bank / 2);
+  var w = c1 * c2 * c3 - s1 * s2 * s3;
+  var x = s1 * s2 * c3 + c1 * c2 * s3;
+  var y = s1 * c2 * c3 + c1 * s2 * s3;
+  var z = c1 * s2 * c3 - s1 * c2 * s3;
+
+  return [x, y, z, w];
+}
+
+function getValueAtCurrentTime() {
+  var frameNum = this.comp.renderedFrame - this.offsetTime;
+  var initTime = this.keyframes[0].t - this.offsetTime;
+  var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+  if (!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))) {
+    if (this._caching.lastFrame >= frameNum) {
+      this._caching._lastKeyframeIndex = -1;
+      this._caching.lastIndex = 0;
+    }
+
+    var renderResult = this.interpolateValue(frameNum, this._caching);
+    this.pv = renderResult;
+  }
+  this._caching.lastFrame = frameNum;
+  return this.pv;
+}
+
+function setVValue(val) {
+  var multipliedValue;
+  if (this.propType === 'unidimensional') {
+    multipliedValue = val * this.mult;
+    if (mathAbs(this.v - multipliedValue) > 0.00001) {
+      this.v = multipliedValue;
+      this._mdf = true;
+    }
+  } else {
+    var i = 0;
+    var len = this.v.length;
+    while (i < len) {
+      multipliedValue = val[i] * this.mult;
+      if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
+        this.v[i] = multipliedValue;
+        this._mdf = true;
+      }
+      i += 1;
+    }
+  }
+}
+
+function processEffectsSequence() {
+  if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
+    return;
+  }
+  if (this.lock) {
+    this.setVValue(this.pv);
+    return;
+  }
+  this.lock = true;
+  this._mdf = this._isFirstFrame;
+  var i;
+  var len = this.effectsSequence.length;
+  var finalValue = this.kf ? this.pv : this.data.k;
+  for (i = 0; i < len; i += 1) {
+    finalValue = this.effectsSequence[i](finalValue);
+  }
+  this.setVValue(finalValue);
+  this._isFirstFrame = false;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+}
+
+function addEffect(effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.container.addDynamicProperty(this);
+}
+
+function ValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this.v = mult ? data.k * mult : data.k;
+  this.pv = data.k;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.vel = 0;
+  this.effectsSequence = [];
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function MultiDimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.frameId = -1;
+  var i;
+  var len = data.k.length;
+  this.v = createTypedArray('float32', len);
+  this.pv = createTypedArray('float32', len);
+  this.vel = createTypedArray('float32', len);
+  for (i = 0; i < len; i += 1) {
+    this.v[i] = data.k[i] * this.mult;
+    this.pv[i] = data.k[i];
+  }
+  this._isFirstFrame = true;
+  this.effectsSequence = [];
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function KeyframedValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.frameId = -1;
+  this._caching = {
+    lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1,
+  };
+  this.k = true;
+  this.kf = true;
+  this.data = data;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.v = initFrame;
+  this.pv = initFrame;
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.addEffect = addEffect;
+}
+
+function KeyframedMultidimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  var i;
+  var len = data.k.length;
+  var s;
+  var e;
+  var to;
+  var ti;
+  for (i = 0; i < len - 1; i += 1) {
+    if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
+      s = data.k[i].s;
+      e = data.k[i + 1].s;
+      to = data.k[i].to;
+      ti = data.k[i].ti;
+      if ((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2]))) {
+        data.k[i].to = null;
+        data.k[i].ti = null;
+      }
+      if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
+        if (s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) {
+          data.k[i].to = null;
+          data.k[i].ti = null;
+        }
+      }
+    }
+  }
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.data = data;
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.k = true;
+  this.kf = true;
+  this._isFirstFrame = true;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.frameId = -1;
+  var arrLen = data.k[0].s.length;
+  this.v = createTypedArray('float32', arrLen);
+  this.pv = createTypedArray('float32', arrLen);
+  for (i = 0; i < arrLen; i += 1) {
+    this.v[i] = initFrame;
+    this.pv[i] = initFrame;
+  }
+  this._caching = { lastFrame: initFrame, lastIndex: 0, value: createTypedArray('float32', arrLen) };
+  this.addEffect = addEffect;
+}
+
+const PropertyFactory = (function () {
+  function getProp(elem, data, type, mult, container) {
+    if (data.sid) {
+      data = elem.globalData.slotManager.getProp(data);
+    }
+    var p;
+    if (!data.k.length) {
+      p = new ValueProperty(elem, data, mult, container);
+    } else if (typeof (data.k[0]) === 'number') {
+      p = new MultiDimensionalProperty(elem, data, mult, container);
+    } else {
+      switch (type) {
+        case 0:
+          p = new KeyframedValueProperty(elem, data, mult, container);
+          break;
+        case 1:
+          p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
+          break;
+        default:
+          break;
+      }
+    }
+    if (p.effectsSequence.length) {
+      container.addDynamicProperty(p);
+    }
+    return p;
+  }
+
+  var ob = {
+    getProp: getProp,
+  };
+  return ob;
+}());
+
+function DynamicPropertyContainer() {}
+DynamicPropertyContainer.prototype = {
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+      this.container.addDynamicProperty(this);
+      this._isAnimated = true;
+    }
+  },
+  iterateDynamicProperties: function () {
+    this._mdf = false;
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      this.dynamicProperties[i].getValue();
+      if (this.dynamicProperties[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  },
+  initDynamicPropertyContainer: function (container) {
+    this.container = container;
+    this.dynamicProperties = [];
+    this._mdf = false;
+    this._isAnimated = false;
+  },
+};
+
+const pointPool = (function () {
+  function create() {
+    return createTypedArray('float32', 2);
+  }
+  return poolFactory(8, create);
+}());
+
+function ShapePath() {
+  this.c = false;
+  this._length = 0;
+  this._maxLength = 8;
+  this.v = createSizedArray(this._maxLength);
+  this.o = createSizedArray(this._maxLength);
+  this.i = createSizedArray(this._maxLength);
+}
+
+ShapePath.prototype.setPathData = function (closed, len) {
+  this.c = closed;
+  this.setLength(len);
+  var i = 0;
+  while (i < len) {
+    this.v[i] = pointPool.newElement();
+    this.o[i] = pointPool.newElement();
+    this.i[i] = pointPool.newElement();
+    i += 1;
+  }
+};
+
+ShapePath.prototype.setLength = function (len) {
+  while (this._maxLength < len) {
+    this.doubleArrayLength();
+  }
+  this._length = len;
+};
+
+ShapePath.prototype.doubleArrayLength = function () {
+  this.v = this.v.concat(createSizedArray(this._maxLength));
+  this.i = this.i.concat(createSizedArray(this._maxLength));
+  this.o = this.o.concat(createSizedArray(this._maxLength));
+  this._maxLength *= 2;
+};
+
+ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
+  var arr;
+  this._length = Math.max(this._length, pos + 1);
+  if (this._length >= this._maxLength) {
+    this.doubleArrayLength();
+  }
+  switch (type) {
+    case 'v':
+      arr = this.v;
+      break;
+    case 'i':
+      arr = this.i;
+      break;
+    case 'o':
+      arr = this.o;
+      break;
+    default:
+      arr = [];
+      break;
+  }
+  if (!arr[pos] || (arr[pos] && !replace)) {
+    arr[pos] = pointPool.newElement();
+  }
+  arr[pos][0] = x;
+  arr[pos][1] = y;
+};
+
+ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
+  this.setXYAt(vX, vY, 'v', pos, replace);
+  this.setXYAt(oX, oY, 'o', pos, replace);
+  this.setXYAt(iX, iY, 'i', pos, replace);
+};
+
+ShapePath.prototype.reverse = function () {
+  var newPath = new ShapePath();
+  newPath.setPathData(this.c, this._length);
+  var vertices = this.v;
+  var outPoints = this.o;
+  var inPoints = this.i;
+  var init = 0;
+  if (this.c) {
+    newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
+    init = 1;
+  }
+  var cnt = this._length - 1;
+  var len = this._length;
+
+  var i;
+  for (i = init; i < len; i += 1) {
+    newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
+    cnt -= 1;
+  }
+  return newPath;
+};
+
+ShapePath.prototype.length = function () {
+  return this._length;
+};
+
+const shapePool = (function () {
+  function create() {
+    return new ShapePath();
+  }
+
+  function release(shapePath) {
+    var len = shapePath._length;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      pointPool.release(shapePath.v[i]);
+      pointPool.release(shapePath.i[i]);
+      pointPool.release(shapePath.o[i]);
+      shapePath.v[i] = null;
+      shapePath.i[i] = null;
+      shapePath.o[i] = null;
+    }
+    shapePath._length = 0;
+    shapePath.c = false;
+  }
+
+  function clone(shape) {
+    var cloned = factory.newElement();
+    var i;
+    var len = shape._length === undefined ? shape.v.length : shape._length;
+    cloned.setLength(len);
+    cloned.c = shape.c;
+
+    for (i = 0; i < len; i += 1) {
+      cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
+    }
+    return cloned;
+  }
+
+  var factory = poolFactory(4, create, release);
+  factory.clone = clone;
+
+  return factory;
+}());
+
+function ShapeCollection() {
+  this._length = 0;
+  this._maxLength = 4;
+  this.shapes = createSizedArray(this._maxLength);
+}
+
+ShapeCollection.prototype.addShape = function (shapeData) {
+  if (this._length === this._maxLength) {
+    this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
+    this._maxLength *= 2;
+  }
+  this.shapes[this._length] = shapeData;
+  this._length += 1;
+};
+
+ShapeCollection.prototype.releaseShapes = function () {
+  var i;
+  for (i = 0; i < this._length; i += 1) {
+    shapePool.release(this.shapes[i]);
+  }
+  this._length = 0;
+};
+
+const shapeCollectionPool = (function () {
+  var ob = {
+    newShapeCollection: newShapeCollection,
+    release: release,
+  };
+
+  var _length = 0;
+  var _maxLength = 4;
+  var pool = createSizedArray(_maxLength);
+
+  function newShapeCollection() {
+    var shapeCollection;
+    if (_length) {
+      _length -= 1;
+      shapeCollection = pool[_length];
+    } else {
+      shapeCollection = new ShapeCollection();
+    }
+    return shapeCollection;
+  }
+
+  function release(shapeCollection) {
+    var i;
+    var len = shapeCollection._length;
+    for (i = 0; i < len; i += 1) {
+      shapePool.release(shapeCollection.shapes[i]);
+    }
+    shapeCollection._length = 0;
+
+    if (_length === _maxLength) {
+      pool = pooling.double(pool);
+      _maxLength *= 2;
+    }
+    pool[_length] = shapeCollection;
+    _length += 1;
+  }
+
+  return ob;
+}());
+
+const ShapePropertyFactory = (function () {
+  var initFrame = -999999;
+
+  function interpolateShape(frameNum, previousValue, caching) {
+    var iterationIndex = caching.lastIndex;
+    var keyPropS;
+    var keyPropE;
+    var isHold;
+    var j;
+    var k;
+    var jLen;
+    var kLen;
+    var perc;
+    var vertexValue;
+    var kf = this.keyframes;
+    if (frameNum < kf[0].t - this.offsetTime) {
+      keyPropS = kf[0].s[0];
+      isHold = true;
+      iterationIndex = 0;
+    } else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) {
+      keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
+      /* if(kf[kf.length - 1].s){
+                keyPropS = kf[kf.length - 1].s[0];
+            }else{
+                keyPropS = kf[kf.length - 2].e[0];
+            } */
+      isHold = true;
+    } else {
+      var i = iterationIndex;
+      var len = kf.length - 1;
+      var flag = true;
+      var keyData;
+      var nextKeyData;
+      var keyframeMetadata;
+      while (flag) {
+        keyData = kf[i];
+        nextKeyData = kf[i + 1];
+        if ((nextKeyData.t - this.offsetTime) > frameNum) {
+          break;
+        }
+        if (i < len - 1) {
+          i += 1;
+        } else {
+          flag = false;
+        }
+      }
+      keyframeMetadata = this.keyframesMetadata[i] || {};
+      isHold = keyData.h === 1;
+      iterationIndex = i;
+      if (!isHold) {
+        if (frameNum >= nextKeyData.t - this.offsetTime) {
+          perc = 1;
+        } else if (frameNum < keyData.t - this.offsetTime) {
+          perc = 0;
+        } else {
+          var fnc;
+          if (keyframeMetadata.__fnct) {
+            fnc = keyframeMetadata.__fnct;
+          } else {
+            fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
+            keyframeMetadata.__fnct = fnc;
+          }
+          perc = fnc((frameNum - (keyData.t - this.offsetTime)) / ((nextKeyData.t - this.offsetTime) - (keyData.t - this.offsetTime)));
+        }
+        keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
+      }
+      keyPropS = keyData.s[0];
+    }
+    jLen = previousValue._length;
+    kLen = keyPropS.i[0].length;
+    caching.lastIndex = iterationIndex;
+
+    for (j = 0; j < jLen; j += 1) {
+      for (k = 0; k < kLen; k += 1) {
+        vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
+        previousValue.i[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc;
+        previousValue.o[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc;
+        previousValue.v[j][k] = vertexValue;
+      }
+    }
+  }
+
+  function interpolateShapeCurrentTime() {
+    var frameNum = this.comp.renderedFrame - this.offsetTime;
+    var initTime = this.keyframes[0].t - this.offsetTime;
+    var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+    var lastFrame = this._caching.lastFrame;
+    if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) {
+      /// /
+      this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
+      this.interpolateShape(frameNum, this.pv, this._caching);
+      /// /
+    }
+    this._caching.lastFrame = frameNum;
+    return this.pv;
+  }
+
+  function resetShape() {
+    this.paths = this.localShapeCollection;
+  }
+
+  function shapesEqual(shape1, shape2) {
+    if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
+      return false;
+    }
+    var i;
+    var len = shape1._length;
+    for (i = 0; i < len; i += 1) {
+      if (shape1.v[i][0] !== shape2.v[i][0]
+            || shape1.v[i][1] !== shape2.v[i][1]
+            || shape1.o[i][0] !== shape2.o[i][0]
+            || shape1.o[i][1] !== shape2.o[i][1]
+            || shape1.i[i][0] !== shape2.i[i][0]
+            || shape1.i[i][1] !== shape2.i[i][1]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  function setVValue(newPath) {
+    if (!shapesEqual(this.v, newPath)) {
+      this.v = shapePool.clone(newPath);
+      this.localShapeCollection.releaseShapes();
+      this.localShapeCollection.addShape(this.v);
+      this._mdf = true;
+      this.paths = this.localShapeCollection;
+    }
+  }
+
+  function processEffectsSequence() {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    } if (!this.effectsSequence.length) {
+      this._mdf = false;
+      return;
+    }
+    if (this.lock) {
+      this.setVValue(this.pv);
+      return;
+    }
+    this.lock = true;
+    this._mdf = false;
+    var finalValue;
+    if (this.kf) {
+      finalValue = this.pv;
+    } else if (this.data.ks) {
+      finalValue = this.data.ks.k;
+    } else {
+      finalValue = this.data.pt.k;
+    }
+    var i;
+    var len = this.effectsSequence.length;
+    for (i = 0; i < len; i += 1) {
+      finalValue = this.effectsSequence[i](finalValue);
+    }
+    this.setVValue(finalValue);
+    this.lock = false;
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function ShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.container = elem;
+    this.elem = elem;
+    this.data = data;
+    this.k = false;
+    this.kf = false;
+    this._mdf = false;
+    var pathData = type === 3 ? data.pt.k : data.ks.k;
+    this.v = shapePool.clone(pathData);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.reset = resetShape;
+    this.effectsSequence = [];
+  }
+
+  function addEffect(effectFunction) {
+    this.effectsSequence.push(effectFunction);
+    this.container.addDynamicProperty(this);
+  }
+
+  ShapeProperty.prototype.interpolateShape = interpolateShape;
+  ShapeProperty.prototype.getValue = processEffectsSequence;
+  ShapeProperty.prototype.setVValue = setVValue;
+  ShapeProperty.prototype.addEffect = addEffect;
+
+  function KeyframedShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.elem = elem;
+    this.container = elem;
+    this.offsetTime = elem.data.st;
+    this.keyframes = type === 3 ? data.pt.k : data.ks.k;
+    this.keyframesMetadata = [];
+    this.k = true;
+    this.kf = true;
+    var len = this.keyframes[0].s[0].i.length;
+    this.v = shapePool.newElement();
+    this.v.setPathData(this.keyframes[0].s[0].c, len);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.lastFrame = initFrame;
+    this.reset = resetShape;
+    this._caching = { lastFrame: initFrame, lastIndex: 0 };
+    this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
+  }
+  KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
+  KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
+  KeyframedShapeProperty.prototype.setVValue = setVValue;
+  KeyframedShapeProperty.prototype.addEffect = addEffect;
+
+  var EllShapeProperty = (function () {
+    var cPoint = roundCorner;
+
+    function EllShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 4);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.paths = this.localShapeCollection;
+      this.localShapeCollection.addShape(this.v);
+      this.d = data.d;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertEllToPath();
+      }
+    }
+
+    EllShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+
+        if (this._mdf) {
+          this.convertEllToPath();
+        }
+      },
+      convertEllToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var s0 = this.s.v[0] / 2;
+        var s1 = this.s.v[1] / 2;
+        var _cw = this.d !== 3;
+        var _v = this.v;
+        _v.v[0][0] = p0;
+        _v.v[0][1] = p1 - s1;
+        _v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.v[1][1] = p1;
+        _v.v[2][0] = p0;
+        _v.v[2][1] = p1 + s1;
+        _v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.v[3][1] = p1;
+        _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.i[0][1] = p1 - s1;
+        _v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.i[1][1] = p1 - s1 * cPoint;
+        _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.i[2][1] = p1 + s1;
+        _v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.i[3][1] = p1 + s1 * cPoint;
+        _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.o[0][1] = p1 - s1;
+        _v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.o[1][1] = p1 + s1 * cPoint;
+        _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.o[2][1] = p1 + s1;
+        _v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.o[3][1] = p1 - s1 * cPoint;
+      },
+    };
+
+    extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
+
+    return EllShapePropertyFactory;
+  }());
+
+  var StarShapeProperty = (function () {
+    function StarShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 0);
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.data = data;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      if (data.sy === 1) {
+        this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
+        this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
+        this.convertToPath = this.convertStarToPath;
+      } else {
+        this.convertToPath = this.convertPolygonToPath;
+      }
+      this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
+      this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this);
+      this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertToPath();
+      }
+    }
+
+    StarShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertToPath();
+        }
+      },
+      convertStarToPath: function () {
+        var numPts = Math.floor(this.pt.v) * 2;
+        var angle = (Math.PI * 2) / numPts;
+        /* this.v.v.length = numPts;
+                this.v.i.length = numPts;
+                this.v.o.length = numPts; */
+        var longFlag = true;
+        var longRad = this.or.v;
+        var shortRad = this.ir.v;
+        var longRound = this.os.v;
+        var shortRound = this.is.v;
+        var longPerimSegment = (2 * Math.PI * longRad) / (numPts * 2);
+        var shortPerimSegment = (2 * Math.PI * shortRad) / (numPts * 2);
+        var i;
+        var rad;
+        var roundness;
+        var perimSegment;
+        var currentAng = -Math.PI / 2;
+        currentAng += this.r.v;
+        var dir = this.data.d === 3 ? -1 : 1;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          rad = longFlag ? longRad : shortRad;
+          roundness = longFlag ? longRound : shortRound;
+          perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
+          /* this.v.v[i] = [x,y];
+                    this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
+                    this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
+                    this.v._length = numPts; */
+          longFlag = !longFlag;
+          currentAng += angle * dir;
+        }
+      },
+      convertPolygonToPath: function () {
+        var numPts = Math.floor(this.pt.v);
+        var angle = (Math.PI * 2) / numPts;
+        var rad = this.or.v;
+        var roundness = this.os.v;
+        var perimSegment = (2 * Math.PI * rad) / (numPts * 4);
+        var i;
+        var currentAng = -Math.PI * 0.5;
+        var dir = this.data.d === 3 ? -1 : 1;
+        currentAng += this.r.v;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+          currentAng += angle * dir;
+        }
+        this.paths.length = 0;
+        this.paths[0] = this.v;
+      },
+
+    };
+    extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
+
+    return StarShapePropertyFactory;
+  }());
+
+  var RectShapeProperty = (function () {
+    function RectShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.c = true;
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertRectToPath();
+      }
+    }
+
+    RectShapePropertyFactory.prototype = {
+      convertRectToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var v0 = this.s.v[0] / 2;
+        var v1 = this.s.v[1] / 2;
+        var round = bmMin(v0, v1, this.r.v);
+        var cPoint = round * (1 - roundCorner);
+        this.v._length = 0;
+
+        if (this.d === 2 || this.d === 1) {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
+          this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2);
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3);
+          }
+        } else {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true);
+          }
+        }
+      },
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertRectToPath();
+        }
+      },
+      reset: resetShape,
+    };
+    extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
+
+    return RectShapePropertyFactory;
+  }());
+
+  function getShapeProp(elem, data, type) {
+    var prop;
+    if (type === 3 || type === 4) {
+      var dataProp = type === 3 ? data.pt : data.ks;
+      var keys = dataProp.k;
+      if (keys.length) {
+        prop = new KeyframedShapeProperty(elem, data, type);
+      } else {
+        prop = new ShapeProperty(elem, data, type);
+      }
+    } else if (type === 5) {
+      prop = new RectShapeProperty(elem, data);
+    } else if (type === 6) {
+      prop = new EllShapeProperty(elem, data);
+    } else if (type === 7) {
+      prop = new StarShapeProperty(elem, data);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  }
+
+  function getConstructorFunction() {
+    return ShapeProperty;
+  }
+
+  function getKeyframedConstructorFunction() {
+    return KeyframedShapeProperty;
+  }
+
+  var ob = {};
+  ob.getShapeProp = getShapeProp;
+  ob.getConstructorFunction = getConstructorFunction;
+  ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction;
+  return ob;
+}());
+
+/*!
+ Transformation Matrix v2.0
+ (c) Epistemex 2014-2015
+ www.epistemex.com
+ By Ken Fyrstenberg
+ Contributions by leeoniya.
+ License: MIT, header required.
+ */
+
+/**
+ * 2D transformation matrix object initialized with identity matrix.
+ *
+ * The matrix can synchronize a canvas context by supplying the context
+ * as an argument, or later apply current absolute transform to an
+ * existing context.
+ *
+ * All values are handled as floating point values.
+ *
+ * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix
+ * @prop {number} a - scale x
+ * @prop {number} b - shear y
+ * @prop {number} c - shear x
+ * @prop {number} d - scale y
+ * @prop {number} e - translate x
+ * @prop {number} f - translate y
+ * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context
+ * @constructor
+ */
+
+const Matrix = (function () {
+  var _cos = Math.cos;
+  var _sin = Math.sin;
+  var _tan = Math.tan;
+  var _rnd = Math.round;
+
+  function reset() {
+    this.props[0] = 1;
+    this.props[1] = 0;
+    this.props[2] = 0;
+    this.props[3] = 0;
+    this.props[4] = 0;
+    this.props[5] = 1;
+    this.props[6] = 0;
+    this.props[7] = 0;
+    this.props[8] = 0;
+    this.props[9] = 0;
+    this.props[10] = 1;
+    this.props[11] = 0;
+    this.props[12] = 0;
+    this.props[13] = 0;
+    this.props[14] = 0;
+    this.props[15] = 1;
+    return this;
+  }
+
+  function rotate(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function rotateX(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateY(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateZ(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function shear(sx, sy) {
+    return this._t(1, sy, sx, 1, 0, 0);
+  }
+
+  function skew(ax, ay) {
+    return this.shear(_tan(ax), _tan(ay));
+  }
+
+  function skewFromAxis(ax, angle) {
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+    // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+  }
+
+  function scale(sx, sy, sz) {
+    if (!sz && sz !== 0) {
+      sz = 1;
+    }
+    if (sx === 1 && sy === 1 && sz === 1) {
+      return this;
+    }
+    return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
+  }
+
+  function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
+    this.props[0] = a;
+    this.props[1] = b;
+    this.props[2] = c;
+    this.props[3] = d;
+    this.props[4] = e;
+    this.props[5] = f;
+    this.props[6] = g;
+    this.props[7] = h;
+    this.props[8] = i;
+    this.props[9] = j;
+    this.props[10] = k;
+    this.props[11] = l;
+    this.props[12] = m;
+    this.props[13] = n;
+    this.props[14] = o;
+    this.props[15] = p;
+    return this;
+  }
+
+  function translate(tx, ty, tz) {
+    tz = tz || 0;
+    if (tx !== 0 || ty !== 0 || tz !== 0) {
+      return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
+    }
+    return this;
+  }
+
+  function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
+    var _p = this.props;
+
+    if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
+      // NOTE: commenting this condition because TurboFan deoptimizes code when present
+      // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
+      _p[12] = _p[12] * a2 + _p[15] * m2;
+      _p[13] = _p[13] * f2 + _p[15] * n2;
+      _p[14] = _p[14] * k2 + _p[15] * o2;
+      _p[15] *= p2;
+      // }
+      this._identityCalculated = false;
+      return this;
+    }
+
+    var a1 = _p[0];
+    var b1 = _p[1];
+    var c1 = _p[2];
+    var d1 = _p[3];
+    var e1 = _p[4];
+    var f1 = _p[5];
+    var g1 = _p[6];
+    var h1 = _p[7];
+    var i1 = _p[8];
+    var j1 = _p[9];
+    var k1 = _p[10];
+    var l1 = _p[11];
+    var m1 = _p[12];
+    var n1 = _p[13];
+    var o1 = _p[14];
+    var p1 = _p[15];
+
+    /* matrix order (canvas compatible):
+         * ace
+         * bdf
+         * 001
+         */
+    _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
+    _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
+    _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
+    _p[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2;
+
+    _p[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2;
+    _p[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2;
+    _p[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2;
+    _p[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2;
+
+    _p[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2;
+    _p[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2;
+    _p[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2;
+    _p[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2;
+
+    _p[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2;
+    _p[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2;
+    _p[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2;
+    _p[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2;
+
+    this._identityCalculated = false;
+    return this;
+  }
+
+  function multiply(matrix) {
+    var matrixProps = matrix.props;
+    return this.transform(
+      matrixProps[0],
+      matrixProps[1],
+      matrixProps[2],
+      matrixProps[3],
+      matrixProps[4],
+      matrixProps[5],
+      matrixProps[6],
+      matrixProps[7],
+      matrixProps[8],
+      matrixProps[9],
+      matrixProps[10],
+      matrixProps[11],
+      matrixProps[12],
+      matrixProps[13],
+      matrixProps[14],
+      matrixProps[15]
+    );
+  }
+
+  function isIdentity() {
+    if (!this._identityCalculated) {
+      this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
+      this._identityCalculated = true;
+    }
+    return this._identity;
+  }
+
+  function equals(matr) {
+    var i = 0;
+    while (i < 16) {
+      if (matr.props[i] !== this.props[i]) {
+        return false;
+      }
+      i += 1;
+    }
+    return true;
+  }
+
+  function clone(matr) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      matr.props[i] = this.props[i];
+    }
+    return matr;
+  }
+
+  function cloneFromProps(props) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      this.props[i] = props[i];
+    }
+  }
+
+  function applyToPoint(x, y, z) {
+    return {
+      x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+      y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+      z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+    };
+    /* return {
+         x: x * me.a + y * me.c + me.e,
+         y: x * me.b + y * me.d + me.f
+         }; */
+  }
+  function applyToX(x, y, z) {
+    return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
+  }
+  function applyToY(x, y, z) {
+    return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
+  }
+  function applyToZ(x, y, z) {
+    return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
+  }
+
+  function getInverseMatrix() {
+    var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
+    var a = this.props[5] / determinant;
+    var b = -this.props[1] / determinant;
+    var c = -this.props[4] / determinant;
+    var d = this.props[0] / determinant;
+    var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12]) / determinant;
+    var f = -(this.props[0] * this.props[13] - this.props[1] * this.props[12]) / determinant;
+    var inverseMatrix = new Matrix();
+    inverseMatrix.props[0] = a;
+    inverseMatrix.props[1] = b;
+    inverseMatrix.props[4] = c;
+    inverseMatrix.props[5] = d;
+    inverseMatrix.props[12] = e;
+    inverseMatrix.props[13] = f;
+    return inverseMatrix;
+  }
+
+  function inversePoint(pt) {
+    var inverseMatrix = this.getInverseMatrix();
+    return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
+  }
+
+  function inversePoints(pts) {
+    var i;
+    var len = pts.length;
+    var retPts = [];
+    for (i = 0; i < len; i += 1) {
+      retPts[i] = inversePoint(pts[i]);
+    }
+    return retPts;
+  }
+
+  function applyToTriplePoints(pt1, pt2, pt3) {
+    var arr = createTypedArray('float32', 6);
+    if (this.isIdentity()) {
+      arr[0] = pt1[0];
+      arr[1] = pt1[1];
+      arr[2] = pt2[0];
+      arr[3] = pt2[1];
+      arr[4] = pt3[0];
+      arr[5] = pt3[1];
+    } else {
+      var p0 = this.props[0];
+      var p1 = this.props[1];
+      var p4 = this.props[4];
+      var p5 = this.props[5];
+      var p12 = this.props[12];
+      var p13 = this.props[13];
+      arr[0] = pt1[0] * p0 + pt1[1] * p4 + p12;
+      arr[1] = pt1[0] * p1 + pt1[1] * p5 + p13;
+      arr[2] = pt2[0] * p0 + pt2[1] * p4 + p12;
+      arr[3] = pt2[0] * p1 + pt2[1] * p5 + p13;
+      arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
+      arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
+    }
+    return arr;
+  }
+
+  function applyToPointArray(x, y, z) {
+    var arr;
+    if (this.isIdentity()) {
+      arr = [x, y, z];
+    } else {
+      arr = [
+        x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+        x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+        x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+      ];
+    }
+    return arr;
+  }
+
+  function applyToPointStringified(x, y) {
+    if (this.isIdentity()) {
+      return x + ',' + y;
+    }
+    var _p = this.props;
+    return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
+  }
+
+  function toCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var i = 0;
+    var props = this.props;
+    var cssValue = 'matrix3d(';
+    var v = 10000;
+    while (i < 16) {
+      cssValue += _rnd(props[i] * v) / v;
+      cssValue += i === 15 ? ')' : ',';
+      i += 1;
+    }
+    return cssValue;
+  }
+
+  function roundMatrixProperty(val) {
+    var v = 10000;
+    if ((val < 0.000001 && val > 0) || (val > -0.000001 && val < 0)) {
+      return _rnd(val * v) / v;
+    }
+    return val;
+  }
+
+  function to2dCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var props = this.props;
+    var _a = roundMatrixProperty(props[0]);
+    var _b = roundMatrixProperty(props[1]);
+    var _c = roundMatrixProperty(props[4]);
+    var _d = roundMatrixProperty(props[5]);
+    var _e = roundMatrixProperty(props[12]);
+    var _f = roundMatrixProperty(props[13]);
+    return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
+  }
+
+  return function () {
+    this.reset = reset;
+    this.rotate = rotate;
+    this.rotateX = rotateX;
+    this.rotateY = rotateY;
+    this.rotateZ = rotateZ;
+    this.skew = skew;
+    this.skewFromAxis = skewFromAxis;
+    this.shear = shear;
+    this.scale = scale;
+    this.setTransform = setTransform;
+    this.translate = translate;
+    this.transform = transform;
+    this.multiply = multiply;
+    this.applyToPoint = applyToPoint;
+    this.applyToX = applyToX;
+    this.applyToY = applyToY;
+    this.applyToZ = applyToZ;
+    this.applyToPointArray = applyToPointArray;
+    this.applyToTriplePoints = applyToTriplePoints;
+    this.applyToPointStringified = applyToPointStringified;
+    this.toCSS = toCSS;
+    this.to2dCSS = to2dCSS;
+    this.clone = clone;
+    this.cloneFromProps = cloneFromProps;
+    this.equals = equals;
+    this.inversePoints = inversePoints;
+    this.inversePoint = inversePoint;
+    this.getInverseMatrix = getInverseMatrix;
+    this._t = this.transform;
+    this.isIdentity = isIdentity;
+    this._identity = true;
+    this._identityCalculated = false;
+
+    this.props = createTypedArray('float32', 16);
+    this.reset();
+  };
+}());
+
+const lottie = {};
+var standalone = '__[STANDALONE]__';
+var animationData = '__[ANIMATIONDATA]__';
+var renderer = '';
+
+function setLocation(href) {
+  setLocationHref(href);
+}
+
+function searchAnimations() {
+  if (standalone === true) {
+    animationManager.searchAnimations(animationData, standalone, renderer);
+  } else {
+    animationManager.searchAnimations();
+  }
+}
+
+function setSubframeRendering(flag) {
+  setSubframeEnabled(flag);
+}
+
+function setPrefix(prefix) {
+  setIdPrefix(prefix);
+}
+
+function loadAnimation(params) {
+  if (standalone === true) {
+    params.animationData = JSON.parse(animationData);
+  }
+  return animationManager.loadAnimation(params);
+}
+
+function setQuality(value) {
+  if (typeof value === 'string') {
+    switch (value) {
+      case 'high':
+        setDefaultCurveSegments(200);
+        break;
+      default:
+      case 'medium':
+        setDefaultCurveSegments(50);
+        break;
+      case 'low':
+        setDefaultCurveSegments(10);
+        break;
+    }
+  } else if (!isNaN(value) && value > 1) {
+    setDefaultCurveSegments(value);
+  }
+  if (getDefaultCurveSegments() >= 50) {
+    roundValues(false);
+  } else {
+    roundValues(true);
+  }
+}
+
+function inBrowser() {
+  return typeof navigator !== 'undefined';
+}
+
+function installPlugin(type, plugin) {
+  if (type === 'expressions') {
+    setExpressionsPlugin(plugin);
+  }
+}
+
+function getFactory(name) {
+  switch (name) {
+    case 'propertyFactory':
+      return PropertyFactory;
+    case 'shapePropertyFactory':
+      return ShapePropertyFactory;
+    case 'matrix':
+      return Matrix;
+    default:
+      return null;
+  }
+}
+
+lottie.play = animationManager.play;
+lottie.pause = animationManager.pause;
+lottie.setLocationHref = setLocation;
+lottie.togglePause = animationManager.togglePause;
+lottie.setSpeed = animationManager.setSpeed;
+lottie.setDirection = animationManager.setDirection;
+lottie.stop = animationManager.stop;
+lottie.searchAnimations = searchAnimations;
+lottie.registerAnimation = animationManager.registerAnimation;
+lottie.loadAnimation = loadAnimation;
+lottie.setSubframeRendering = setSubframeRendering;
+lottie.resize = animationManager.resize;
+// lottie.start = start;
+lottie.goToAndStop = animationManager.goToAndStop;
+lottie.destroy = animationManager.destroy;
+lottie.setQuality = setQuality;
+lottie.inBrowser = inBrowser;
+lottie.installPlugin = installPlugin;
+lottie.freeze = animationManager.freeze;
+lottie.unfreeze = animationManager.unfreeze;
+lottie.setVolume = animationManager.setVolume;
+lottie.mute = animationManager.mute;
+lottie.unmute = animationManager.unmute;
+lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations;
+lottie.useWebWorker = setWebWorker;
+lottie.setIDPrefix = setPrefix;
+lottie.__getFactory = getFactory;
+lottie.version = '[[BM_VERSION]]';
+
+function checkReady() {
+  if (document.readyState === 'complete') {
+    clearInterval(readyStateCheckInterval);
+    searchAnimations();
+  }
+}
+
+function getQueryVariable(variable) {
+  var vars = queryString.split('&');
+  for (var i = 0; i < vars.length; i += 1) {
+    var pair = vars[i].split('=');
+    if (decodeURIComponent(pair[0]) == variable) { // eslint-disable-line eqeqeq
+      return decodeURIComponent(pair[1]);
+    }
+  }
+  return null;
+}
+var queryString = '';
+if (standalone) {
+  var scripts = document.getElementsByTagName('script');
+  var index = scripts.length - 1;
+  var myScript = scripts[index] || {
+    src: '',
+  };
+  queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
+  renderer = getQueryVariable('renderer');
+}
+var readyStateCheckInterval = setInterval(checkReady, 100);
+
+// this adds bodymovin to the window object for backwards compatibility
+try {
+  if (!(typeof exports === 'object' && typeof module !== 'undefined')
+    && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
+  ) {
+    window.bodymovin = lottie;
+  }
+} catch (err) {
+  //
+}
+
+const ShapeModifiers = (function () {
+  var ob = {};
+  var modifiers = {};
+  ob.registerModifier = registerModifier;
+  ob.getModifier = getModifier;
+
+  function registerModifier(nm, factory) {
+    if (!modifiers[nm]) {
+      modifiers[nm] = factory;
+    }
+  }
+
+  function getModifier(nm, elem, data) {
+    return new modifiers[nm](elem, data);
+  }
+
+  return ob;
+}());
+
+function ShapeModifier() {}
+ShapeModifier.prototype.initModifierProperties = function () {};
+ShapeModifier.prototype.addShapeToModifier = function () {};
+ShapeModifier.prototype.addShape = function (data) {
+  if (!this.closed) {
+    // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
+    data.sh.container.addDynamicProperty(data.sh);
+    var shapeData = { shape: data.sh, data: data, localShapeCollection: shapeCollectionPool.newShapeCollection() };
+    this.shapes.push(shapeData);
+    this.addShapeToModifier(shapeData);
+    if (this._isAnimated) {
+      data.setAsAnimated();
+    }
+  }
+};
+ShapeModifier.prototype.init = function (elem, data) {
+  this.shapes = [];
+  this.elem = elem;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, data);
+  this.frameId = initialDefaultFrame;
+  this.closed = false;
+  this.k = false;
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+ShapeModifier.prototype.processKeys = function () {
+  if (this.elem.globalData.frameId === this.frameId) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+extendPrototype([DynamicPropertyContainer], ShapeModifier);
+
+function TrimModifier() {
+}
+extendPrototype([ShapeModifier], TrimModifier);
+TrimModifier.prototype.initModifierProperties = function (elem, data) {
+  this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this);
+  this.sValue = 0;
+  this.eValue = 0;
+  this.getValue = this.processKeys;
+  this.m = data.m;
+  this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
+};
+
+TrimModifier.prototype.addShapeToModifier = function (shapeData) {
+  shapeData.pathsData = [];
+};
+
+TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
+  var segments = [];
+  if (e <= 1) {
+    segments.push({
+      s: s,
+      e: e,
+    });
+  } else if (s >= 1) {
+    segments.push({
+      s: s - 1,
+      e: e - 1,
+    });
+  } else {
+    segments.push({
+      s: s,
+      e: 1,
+    });
+    segments.push({
+      s: 0,
+      e: e - 1,
+    });
+  }
+  var shapeSegments = [];
+  var i;
+  var len = segments.length;
+  var segmentOb;
+  for (i = 0; i < len; i += 1) {
+    segmentOb = segments[i];
+    if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
+      var shapeS;
+      var shapeE;
+      if (segmentOb.s * totalModifierLength <= addedLength) {
+        shapeS = 0;
+      } else {
+        shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
+      }
+      if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
+        shapeE = 1;
+      } else {
+        shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength);
+      }
+      shapeSegments.push([shapeS, shapeE]);
+    }
+  }
+  if (!shapeSegments.length) {
+    shapeSegments.push([0, 0]);
+  }
+  return shapeSegments;
+};
+
+TrimModifier.prototype.releasePathsData = function (pathsData) {
+  var i;
+  var len = pathsData.length;
+  for (i = 0; i < len; i += 1) {
+    segmentsLengthPool.release(pathsData[i]);
+  }
+  pathsData.length = 0;
+  return pathsData;
+};
+
+TrimModifier.prototype.processShapes = function (_isFirstFrame) {
+  var s;
+  var e;
+  if (this._mdf || _isFirstFrame) {
+    var o = (this.o.v % 360) / 360;
+    if (o < 0) {
+      o += 1;
+    }
+    if (this.s.v > 1) {
+      s = 1 + o;
+    } else if (this.s.v < 0) {
+      s = 0 + o;
+    } else {
+      s = this.s.v + o;
+    }
+    if (this.e.v > 1) {
+      e = 1 + o;
+    } else if (this.e.v < 0) {
+      e = 0 + o;
+    } else {
+      e = this.e.v + o;
+    }
+
+    if (s > e) {
+      var _s = s;
+      s = e;
+      e = _s;
+    }
+    s = Math.round(s * 10000) * 0.0001;
+    e = Math.round(e * 10000) * 0.0001;
+    this.sValue = s;
+    this.eValue = e;
+  } else {
+    s = this.sValue;
+    e = this.eValue;
+  }
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var pathsData;
+  var pathData;
+  var totalShapeLength;
+  var totalModifierLength = 0;
+
+  if (e === s) {
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].localShapeCollection.releaseShapes();
+      this.shapes[i].shape._mdf = true;
+      this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
+      if (this._mdf) {
+        this.shapes[i].pathsData.length = 0;
+      }
+    }
+  } else if (!((e === 1 && s === 0) || (e === 0 && s === 1))) {
+    var segments = [];
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
+      if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
+        shapeData.shape.paths = shapeData.localShapeCollection;
+      } else {
+        shapePaths = shapeData.shape.paths;
+        jLen = shapePaths._length;
+        totalShapeLength = 0;
+        if (!shapeData.shape._mdf && shapeData.pathsData.length) {
+          totalShapeLength = shapeData.totalShapeLength;
+        } else {
+          pathsData = this.releasePathsData(shapeData.pathsData);
+          for (j = 0; j < jLen; j += 1) {
+            pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
+            pathsData.push(pathData);
+            totalShapeLength += pathData.totalLength;
+          }
+          shapeData.totalShapeLength = totalShapeLength;
+          shapeData.pathsData = pathsData;
+        }
+
+        totalModifierLength += totalShapeLength;
+        shapeData.shape._mdf = true;
+      }
+    }
+    var shapeS = s;
+    var shapeE = e;
+    var addedLength = 0;
+    var edges;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shapeData = this.shapes[i];
+      if (shapeData.shape._mdf) {
+        localShapeCollection = shapeData.localShapeCollection;
+        localShapeCollection.releaseShapes();
+        // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
+        if (this.m === 2 && len > 1) {
+          edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
+          addedLength += shapeData.totalShapeLength;
+        } else {
+          edges = [[shapeS, shapeE]];
+        }
+        jLen = edges.length;
+        for (j = 0; j < jLen; j += 1) {
+          shapeS = edges[j][0];
+          shapeE = edges[j][1];
+          segments.length = 0;
+          if (shapeE <= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength * shapeE,
+            });
+          } else if (shapeS >= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * (shapeS - 1),
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          } else {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength,
+            });
+            segments.push({
+              s: 0,
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          }
+          var newShapesData = this.addShapes(shapeData, segments[0]);
+          if (segments[0].s !== segments[0].e) {
+            if (segments.length > 1) {
+              var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
+              if (lastShapeInCollection.c) {
+                var lastShape = newShapesData.pop();
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1], lastShape);
+              } else {
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1]);
+              }
+            }
+            this.addPaths(newShapesData, localShapeCollection);
+          }
+        }
+        shapeData.shape.paths = localShapeCollection;
+      }
+    }
+  } else if (this._mdf) {
+    for (i = 0; i < len; i += 1) {
+      // Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween.
+      // Don't remove this even if it's losing cached info.
+      this.shapes[i].pathsData.length = 0;
+      this.shapes[i].shape._mdf = true;
+    }
+  }
+};
+
+TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
+  var i;
+  var len = newPaths.length;
+  for (i = 0; i < len; i += 1) {
+    localShapeCollection.addShape(newPaths[i]);
+  }
+};
+
+TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
+  shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
+  shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
+  }
+  shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
+  shapePath.setXYAt(points[1], points[5], 'o', pos);
+  shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(points[0], points[4], 'v', pos);
+  }
+  shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
+  var pathsData = shapeData.pathsData;
+  var shapePaths = shapeData.shape.paths.shapes;
+  var i;
+  var len = shapeData.shape.paths._length;
+  var j;
+  var jLen;
+  var addedLength = 0;
+  var currentLengthData;
+  var segmentCount;
+  var lengths;
+  var segment;
+  var shapes = [];
+  var initPos;
+  var newShape = true;
+  if (!shapePath) {
+    shapePath = shapePool.newElement();
+    segmentCount = 0;
+    initPos = 0;
+  } else {
+    segmentCount = shapePath._length;
+    initPos = shapePath._length;
+  }
+  shapes.push(shapePath);
+  for (i = 0; i < len; i += 1) {
+    lengths = pathsData[i].lengths;
+    shapePath.c = shapePaths[i].c;
+    jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
+    for (j = 1; j < jLen; j += 1) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
+        addedLength += currentLengthData.addedLength;
+        shapePath.c = false;
+      } else if (addedLength > shapeSegment.e) {
+        shapePath.c = false;
+        break;
+      } else {
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+        addedLength += currentLengthData.addedLength;
+        segmentCount += 1;
+      }
+    }
+    if (shapePaths[i].c && lengths.length) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength <= shapeSegment.e) {
+        var segmentLength = lengths[j - 1].addedLength;
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+      } else {
+        shapePath.c = false;
+      }
+      addedLength += currentLengthData.addedLength;
+      segmentCount += 1;
+    }
+    if (shapePath._length) {
+      shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
+      shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
+    }
+    if (addedLength > shapeSegment.e) {
+      break;
+    }
+    if (i < len - 1) {
+      shapePath = shapePool.newElement();
+      newShape = true;
+      shapes.push(shapePath);
+      segmentCount = 0;
+    }
+  }
+  return shapes;
+};
+
+function PuckerAndBloatModifier() {}
+extendPrototype([ShapeModifier], PuckerAndBloatModifier);
+PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this._isAnimated = !!this.amount.effectsSequence.length;
+};
+
+PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
+  var percent = amount / 100;
+  var centerPoint = [0, 0];
+  var pathLength = path._length;
+  var i = 0;
+  for (i = 0; i < pathLength; i += 1) {
+    centerPoint[0] += path.v[i][0];
+    centerPoint[1] += path.v[i][1];
+  }
+  centerPoint[0] /= pathLength;
+  centerPoint[1] /= pathLength;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < pathLength; i += 1) {
+    vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
+    vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
+    oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent;
+    oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent;
+    iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent;
+    iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
+    clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
+  }
+  return clonedPath;
+};
+
+PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+const TransformPropertyFactory = (function () {
+  var defaultVector = [0, 0];
+
+  function applyToMatrix(mat) {
+    var _mdf = this._mdf;
+    this.iterateDynamicProperties();
+    this._mdf = this._mdf || _mdf;
+    if (this.a) {
+      mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+    }
+    if (this.s) {
+      mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+    }
+    if (this.sk) {
+      mat.skewFromAxis(-this.sk.v, this.sa.v);
+    }
+    if (this.r) {
+      mat.rotate(-this.r.v);
+    } else {
+      mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+    }
+    if (this.data.p.s) {
+      if (this.data.p.z) {
+        mat.translate(this.px.v, this.py.v, -this.pz.v);
+      } else {
+        mat.translate(this.px.v, this.py.v, 0);
+      }
+    } else {
+      mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+    }
+  }
+  function processKeys(forceRender) {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    }
+    if (this._isDirty) {
+      this.precalculateMatrix();
+      this._isDirty = false;
+    }
+
+    this.iterateDynamicProperties();
+
+    if (this._mdf || forceRender) {
+      var frameRate;
+      this.v.cloneFromProps(this.pre.props);
+      if (this.appliedTransformations < 1) {
+        this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      }
+      if (this.appliedTransformations < 2) {
+        this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      }
+      if (this.sk && this.appliedTransformations < 3) {
+        this.v.skewFromAxis(-this.sk.v, this.sa.v);
+      }
+      if (this.r && this.appliedTransformations < 4) {
+        this.v.rotate(-this.r.v);
+      } else if (!this.r && this.appliedTransformations < 4) {
+        this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+          .rotateY(this.or.v[1])
+          .rotateX(this.or.v[0]);
+      }
+      if (this.autoOriented) {
+        var v1;
+        var v2;
+        frameRate = this.elem.globalData.frameRate;
+        if (this.p && this.p.keyframes && this.p.getValueAtTime) {
+          if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
+            v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0);
+          } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0);
+            v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0);
+          } else {
+            v1 = this.p.pv;
+            v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime);
+          }
+        } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) {
+          v1 = [];
+          v2 = [];
+          var px = this.px;
+          var py = this.py;
+          if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
+            v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
+            v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate, 0);
+          } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate), 0);
+            v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate), 0);
+            v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0);
+          } else {
+            v1 = [px.pv, py.pv];
+            v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime);
+            v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime);
+          }
+        } else {
+          v2 = defaultVector;
+          v1 = v2;
+        }
+        this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
+      }
+      if (this.data.p && this.data.p.s) {
+        if (this.data.p.z) {
+          this.v.translate(this.px.v, this.py.v, -this.pz.v);
+        } else {
+          this.v.translate(this.px.v, this.py.v, 0);
+        }
+      } else {
+        this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+      }
+    }
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function precalculateMatrix() {
+    this.appliedTransformations = 0;
+    this.pre.reset();
+
+    if (!this.a.effectsSequence.length) {
+      this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      this.appliedTransformations = 1;
+    } else {
+      return;
+    }
+    if (!this.s.effectsSequence.length) {
+      this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      this.appliedTransformations = 2;
+    } else {
+      return;
+    }
+    if (this.sk) {
+      if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
+        this.pre.skewFromAxis(-this.sk.v, this.sa.v);
+        this.appliedTransformations = 3;
+      } else {
+        return;
+      }
+    }
+    if (this.r) {
+      if (!this.r.effectsSequence.length) {
+        this.pre.rotate(-this.r.v);
+        this.appliedTransformations = 4;
+      }
+    } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) {
+      this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+      this.appliedTransformations = 4;
+    }
+  }
+
+  function autoOrient() {
+    //
+    // var prevP = this.getValueAtTime();
+  }
+
+  function addDynamicProperty(prop) {
+    this._addDynamicProperty(prop);
+    this.elem.addDynamicProperty(prop);
+    this._isDirty = true;
+  }
+
+  function TransformProperty(elem, data, container) {
+    this.elem = elem;
+    this.frameId = -1;
+    this.propType = 'transform';
+    this.data = data;
+    this.v = new Matrix();
+    // Precalculated matrix with non animated properties
+    this.pre = new Matrix();
+    this.appliedTransformations = 0;
+    this.initDynamicPropertyContainer(container || elem);
+    if (data.p && data.p.s) {
+      this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
+      this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
+      if (data.p.z) {
+        this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
+      }
+    } else {
+      this.p = PropertyFactory.getProp(elem, data.p || { k: [0, 0, 0] }, 1, 0, this);
+    }
+    if (data.rx) {
+      this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
+      this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
+      this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
+      if (data.or.k[0].ti) {
+        var i;
+        var len = data.or.k.length;
+        for (i = 0; i < len; i += 1) {
+          data.or.k[i].to = null;
+          data.or.k[i].ti = null;
+        }
+      }
+      this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+      // sh Indicates it needs to be capped between -180 and 180
+      this.or.sh = true;
+    } else {
+      this.r = PropertyFactory.getProp(elem, data.r || { k: 0 }, 0, degToRads, this);
+    }
+    if (data.sk) {
+      this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
+      this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
+    }
+    this.a = PropertyFactory.getProp(elem, data.a || { k: [0, 0, 0] }, 1, 0, this);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: [100, 100, 100] }, 1, 0.01, this);
+    // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
+    if (data.o) {
+      this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
+    } else {
+      this.o = { _mdf: false, v: 1 };
+    }
+    this._isDirty = true;
+    if (!this.dynamicProperties.length) {
+      this.getValue(true);
+    }
+  }
+
+  TransformProperty.prototype = {
+    applyToMatrix: applyToMatrix,
+    getValue: processKeys,
+    precalculateMatrix: precalculateMatrix,
+    autoOrient: autoOrient,
+  };
+
+  extendPrototype([DynamicPropertyContainer], TransformProperty);
+  TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
+  TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
+
+  function getTransformProperty(elem, data, container) {
+    return new TransformProperty(elem, data, container);
+  }
+
+  return {
+    getTransformProperty: getTransformProperty,
+  };
+}());
+
+function RepeaterModifier() {}
+extendPrototype([ShapeModifier], RepeaterModifier);
+
+RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, null, this);
+  this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this);
+  this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
+  this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
+  this.data = data;
+  if (!this.dynamicProperties.length) {
+    this.getValue(true);
+  }
+  this._isAnimated = !!this.dynamicProperties.length;
+  this.pMatrix = new Matrix();
+  this.rMatrix = new Matrix();
+  this.sMatrix = new Matrix();
+  this.tMatrix = new Matrix();
+  this.matrix = new Matrix();
+};
+
+RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
+  var dir = inv ? -1 : 1;
+  var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
+  var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
+  pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
+  rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  rMatrix.rotate(-transform.r.v * dir * perc);
+  rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+  sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
+  sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+};
+
+RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
+  this.elem = elem;
+  this.arr = arr;
+  this.pos = pos;
+  this.elemsData = elemsData;
+  this._currentCopies = 0;
+  this._elements = [];
+  this._groups = [];
+  this.frameId = -1;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, arr[pos]);
+  while (pos > 0) {
+    pos -= 1;
+    // this._elements.unshift(arr.splice(pos,1)[0]);
+    this._elements.unshift(arr[pos]);
+  }
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+
+RepeaterModifier.prototype.resetElements = function (elements) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._processed = false;
+    if (elements[i].ty === 'gr') {
+      this.resetElements(elements[i].it);
+    }
+  }
+};
+
+RepeaterModifier.prototype.cloneElements = function (elements) {
+  var newElements = JSON.parse(JSON.stringify(elements));
+  this.resetElements(newElements);
+  return newElements;
+};
+
+RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._render = renderFlag;
+    if (elements[i].ty === 'gr') {
+      this.changeGroupRender(elements[i].it, renderFlag);
+    }
+  }
+};
+
+RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
+  var items;
+  var itemsTransform;
+  var i;
+  var dir;
+  var cont;
+  var hasReloaded = false;
+  if (this._mdf || _isFirstFrame) {
+    var copies = Math.ceil(this.c.v);
+    if (this._groups.length < copies) {
+      while (this._groups.length < copies) {
+        var group = {
+          it: this.cloneElements(this._elements),
+          ty: 'gr',
+        };
+        group.it.push({
+          a: { a: 0, ix: 1, k: [0, 0] }, nm: 'Transform', o: { a: 0, ix: 7, k: 100 }, p: { a: 0, ix: 2, k: [0, 0] }, r: { a: 1, ix: 6, k: [{ s: 0, e: 0, t: 0 }, { s: 0, e: 0, t: 1 }] }, s: { a: 0, ix: 3, k: [100, 100] }, sa: { a: 0, ix: 5, k: 0 }, sk: { a: 0, ix: 4, k: 0 }, ty: 'tr',
+        });
+
+        this.arr.splice(0, 0, group);
+        this._groups.splice(0, 0, group);
+        this._currentCopies += 1;
+      }
+      this.elem.reloadShapes();
+      hasReloaded = true;
+    }
+    cont = 0;
+    var renderFlag;
+    for (i = 0; i <= this._groups.length - 1; i += 1) {
+      renderFlag = cont < copies;
+      this._groups[i]._render = renderFlag;
+      this.changeGroupRender(this._groups[i].it, renderFlag);
+      if (!renderFlag) {
+        var elems = this.elemsData[i].it;
+        var transformData = elems[elems.length - 1];
+        if (transformData.transform.op.v !== 0) {
+          transformData.transform.op._mdf = true;
+          transformData.transform.op.v = 0;
+        } else {
+          transformData.transform.op._mdf = false;
+        }
+      }
+      cont += 1;
+    }
+
+    this._currentCopies = copies;
+    /// /
+
+    var offset = this.o.v;
+    var offsetModulo = offset % 1;
+    var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
+    var pProps = this.pMatrix.props;
+    var rProps = this.rMatrix.props;
+    var sProps = this.sMatrix.props;
+    this.pMatrix.reset();
+    this.rMatrix.reset();
+    this.sMatrix.reset();
+    this.tMatrix.reset();
+    this.matrix.reset();
+    var iteration = 0;
+
+    if (offset > 0) {
+      while (iteration < roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        iteration += 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
+        iteration += offsetModulo;
+      }
+    } else if (offset < 0) {
+      while (iteration > roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
+        iteration -= 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
+        iteration -= offsetModulo;
+      }
+    }
+    i = this.data.m === 1 ? 0 : this._currentCopies - 1;
+    dir = this.data.m === 1 ? 1 : -1;
+    cont = this._currentCopies;
+    var j;
+    var jLen;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      jLen = itemsTransform.length;
+      items[items.length - 1].transform.mProps._mdf = true;
+      items[items.length - 1].transform.op._mdf = true;
+      items[items.length - 1].transform.op.v = this._currentCopies === 1
+        ? this.so.v
+        : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
+
+      if (iteration !== 0) {
+        if ((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)) {
+          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        }
+        this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
+        this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
+        this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
+
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+        this.matrix.reset();
+      } else {
+        this.matrix.reset();
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+      }
+      iteration += 1;
+      cont -= 1;
+      i += dir;
+    }
+  } else {
+    cont = this._currentCopies;
+    i = 0;
+    dir = 1;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      items[items.length - 1].transform.mProps._mdf = false;
+      items[items.length - 1].transform.op._mdf = false;
+      cont -= 1;
+      i += dir;
+    }
+  }
+  return hasReloaded;
+};
+
+RepeaterModifier.prototype.addShape = function () {};
+
+function RoundCornersModifier() {}
+extendPrototype([ShapeModifier], RoundCornersModifier);
+RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this._isAnimated = !!this.rd.effectsSequence.length;
+};
+
+RoundCornersModifier.prototype.processPath = function (path, round) {
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var i;
+  var len = path._length;
+  var currentV;
+  var currentI;
+  var currentO;
+  var closerV;
+  var distance;
+  var newPosPerc;
+  var index = 0;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < len; i += 1) {
+    currentV = path.v[i];
+    currentO = path.o[i];
+    currentI = path.i[i];
+    if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
+      if ((i === 0 || i === len - 1) && !path.c) {
+        clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
+        /* clonedPath.v[index] = currentV;
+                clonedPath.o[index] = currentO;
+                clonedPath.i[index] = currentI; */
+        index += 1;
+      } else {
+        if (i === 0) {
+          closerV = path.v[len - 1];
+        } else {
+          closerV = path.v[i - 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = iX;
+        iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
+        vY = iY;
+        oX = vX - (vX - currentV[0]) * roundCorner;
+        oY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+
+        if (i === len - 1) {
+          closerV = path.v[0];
+        } else {
+          closerV = path.v[i + 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = oX;
+        oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc;
+        vY = oY;
+        iX = vX - (vX - currentV[0]) * roundCorner;
+        iY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+      }
+    } else {
+      clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index);
+      index += 1;
+    }
+  }
+  return clonedPath;
+};
+
+RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var rd = this.rd.v;
+
+  if (rd !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function floatEqual(a, b) {
+  return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
+}
+
+function floatZero(f) {
+  return Math.abs(f) <= 0.00001;
+}
+
+function lerp(p0, p1, amount) {
+  return p0 * (1 - amount) + p1 * amount;
+}
+
+function lerpPoint(p0, p1, amount) {
+  return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
+}
+
+function quadRoots(a, b, c) {
+  // no root
+  if (a === 0) return [];
+  var s = b * b - 4 * a * c;
+  // Complex roots
+  if (s < 0) return [];
+  var singleRoot = -b / (2 * a);
+  // 1 root
+  if (s === 0) return [singleRoot];
+  var delta = Math.sqrt(s) / (2 * a);
+  // 2 roots
+  return [singleRoot - delta, singleRoot + delta];
+}
+
+function polynomialCoefficients(p0, p1, p2, p3) {
+  return [
+    -p0 + 3 * p1 - 3 * p2 + p3,
+    3 * p0 - 6 * p1 + 3 * p2,
+    -3 * p0 + 3 * p1,
+    p0,
+  ];
+}
+
+function singlePoint(p) {
+  return new PolynomialBezier(p, p, p, p, false);
+}
+
+function PolynomialBezier(p0, p1, p2, p3, linearize) {
+  if (linearize && pointEqual(p0, p1)) {
+    p1 = lerpPoint(p0, p3, 1 / 3);
+  }
+  if (linearize && pointEqual(p2, p3)) {
+    p2 = lerpPoint(p0, p3, 2 / 3);
+  }
+  var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
+  var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
+  this.a = [coeffx[0], coeffy[0]];
+  this.b = [coeffx[1], coeffy[1]];
+  this.c = [coeffx[2], coeffy[2]];
+  this.d = [coeffx[3], coeffy[3]];
+  this.points = [p0, p1, p2, p3];
+}
+PolynomialBezier.prototype.point = function (t) {
+  return [
+    (((this.a[0] * t) + this.b[0]) * t + this.c[0]) * t + this.d[0],
+    (((this.a[1] * t) + this.b[1]) * t + this.c[1]) * t + this.d[1],
+  ];
+};
+PolynomialBezier.prototype.derivative = function (t) {
+  return [
+    (3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0],
+    (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1],
+  ];
+};
+PolynomialBezier.prototype.tangentAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[1], p[0]);
+};
+PolynomialBezier.prototype.normalAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[0], p[1]);
+};
+
+PolynomialBezier.prototype.inflectionPoints = function () {
+  var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
+  if (floatZero(denom)) return [];
+  var tcusp = (-0.5 * (this.a[1] * this.c[0] - this.a[0] * this.c[1])) / denom;
+  var square = tcusp * tcusp - ((1 / 3) * (this.b[1] * this.c[0] - this.b[0] * this.c[1])) / denom;
+  if (square < 0) return [];
+  var root = Math.sqrt(square);
+  if (floatZero(root)) {
+    if (root > 0 && root < 1) return [tcusp];
+    return [];
+  }
+  return [tcusp - root, tcusp + root].filter(function (r) { return r > 0 && r < 1; });
+};
+PolynomialBezier.prototype.split = function (t) {
+  if (t <= 0) return [singlePoint(this.points[0]), this];
+  if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
+  var p10 = lerpPoint(this.points[0], this.points[1], t);
+  var p11 = lerpPoint(this.points[1], this.points[2], t);
+  var p12 = lerpPoint(this.points[2], this.points[3], t);
+  var p20 = lerpPoint(p10, p11, t);
+  var p21 = lerpPoint(p11, p12, t);
+  var p3 = lerpPoint(p20, p21, t);
+  return [
+    new PolynomialBezier(this.points[0], p10, p20, p3, true),
+    new PolynomialBezier(p3, p21, p12, this.points[3], true),
+  ];
+};
+function extrema(bez, comp) {
+  var min = bez.points[0][comp];
+  var max = bez.points[bez.points.length - 1][comp];
+  if (min > max) {
+    var e = max;
+    max = min;
+    min = e;
+  }
+  // Derivative roots to find min/max
+  var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
+  for (var i = 0; i < f.length; i += 1) {
+    if (f[i] > 0 && f[i] < 1) {
+      var val = bez.point(f[i])[comp];
+      if (val < min) min = val;
+      else if (val > max) max = val;
+    }
+  }
+  return {
+    min: min,
+    max: max,
+  };
+}
+PolynomialBezier.prototype.bounds = function () {
+  return {
+    x: extrema(this, 0),
+    y: extrema(this, 1),
+  };
+};
+PolynomialBezier.prototype.boundingBox = function () {
+  var bounds = this.bounds();
+  return {
+    left: bounds.x.min,
+    right: bounds.x.max,
+    top: bounds.y.min,
+    bottom: bounds.y.max,
+    width: bounds.x.max - bounds.x.min,
+    height: bounds.y.max - bounds.y.min,
+    cx: (bounds.x.max + bounds.x.min) / 2,
+    cy: (bounds.y.max + bounds.y.min) / 2,
+  };
+};
+
+function intersectData(bez, t1, t2) {
+  var box = bez.boundingBox();
+  return {
+    cx: box.cx,
+    cy: box.cy,
+    width: box.width,
+    height: box.height,
+    bez: bez,
+    t: (t1 + t2) / 2,
+    t1: t1,
+    t2: t2,
+  };
+}
+function splitData(data) {
+  var split = data.bez.split(0.5);
+  return [
+    intersectData(split[0], data.t1, data.t),
+    intersectData(split[1], data.t, data.t2),
+  ];
+}
+
+function boxIntersect(b1, b2) {
+  return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width
+    && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
+}
+
+function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
+  if (!boxIntersect(d1, d2)) return;
+  if (depth >= maxRecursion || (d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance)) {
+    intersections.push([d1.t, d2.t]);
+    return;
+  }
+  var d1s = splitData(d1);
+  var d2s = splitData(d2);
+  intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[0], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+}
+
+PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
+  if (tolerance === undefined) tolerance = 2;
+  if (maxRecursion === undefined) maxRecursion = 7;
+  var intersections = [];
+  intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
+  return intersections;
+};
+
+PolynomialBezier.shapeSegment = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
+};
+
+PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
+};
+
+function crossProduct(a, b) {
+  return [
+    a[1] * b[2] - a[2] * b[1],
+    a[2] * b[0] - a[0] * b[2],
+    a[0] * b[1] - a[1] * b[0],
+  ];
+}
+
+function lineIntersection(start1, end1, start2, end2) {
+  var v1 = [start1[0], start1[1], 1];
+  var v2 = [end1[0], end1[1], 1];
+  var v3 = [start2[0], start2[1], 1];
+  var v4 = [end2[0], end2[1], 1];
+
+  var r = crossProduct(
+    crossProduct(v1, v2),
+    crossProduct(v3, v4)
+  );
+
+  if (floatZero(r[2])) return null;
+
+  return [r[0] / r[2], r[1] / r[2]];
+}
+
+function polarOffset(p, angle, length) {
+  return [
+    p[0] + Math.cos(angle) * length,
+    p[1] - Math.sin(angle) * length,
+  ];
+}
+
+function pointDistance(p1, p2) {
+  return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
+}
+
+function pointEqual(p1, p2) {
+  return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
+}
+
+function ZigZagModifier() {}
+extendPrototype([ShapeModifier], ZigZagModifier);
+ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
+  this.frequency = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
+  this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
+};
+
+function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
+  var angO = angle - Math.PI / 2;
+  var angI = angle + Math.PI / 2;
+  var px = point[0] + Math.cos(angle) * direction * amplitude;
+  var py = point[1] - Math.sin(angle) * direction * amplitude;
+
+  outputBezier.setTripleAt(
+    px,
+    py,
+    px + Math.cos(angO) * outAmplitude,
+    py - Math.sin(angO) * outAmplitude,
+    px + Math.cos(angI) * inAmplitude,
+    py - Math.sin(angI) * inAmplitude,
+    outputBezier.length()
+  );
+}
+
+function getPerpendicularVector(pt1, pt2) {
+  var vector = [
+    pt2[0] - pt1[0],
+    pt2[1] - pt1[1],
+  ];
+  var rot = -Math.PI * 0.5;
+  var rotatedVector = [
+    Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1],
+    Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1],
+  ];
+  return rotatedVector;
+}
+
+function getProjectingAngle(path, cur) {
+  var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
+  var nextIndex = (cur + 1) % path.length();
+  var prevPoint = path.v[prevIndex];
+  var nextPoint = path.v[nextIndex];
+  var pVector = getPerpendicularVector(prevPoint, nextPoint);
+  return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
+}
+
+function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
+  var angle = getProjectingAngle(path, cur);
+  var point = path.v[cur % path._length];
+  var prevPoint = path.v[cur === 0 ? path._length - 1 : cur - 1];
+  var nextPoint = path.v[(cur + 1) % path._length];
+  var prevDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - prevPoint[0], 2) + Math.pow(point[1] - prevPoint[1], 2))
+    : 0;
+  var nextDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2))
+    : 0;
+
+  setPoint(
+    outputBezier,
+    path.v[cur % path._length],
+    angle,
+    direction,
+    amplitude,
+    nextDist / ((frequency + 1) * 2),
+    prevDist / ((frequency + 1) * 2),
+    pointType
+  );
+}
+
+function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
+  for (var i = 0; i < frequency; i += 1) {
+    var t = (i + 1) / (frequency + 1);
+
+    var dist = pointType === 2
+      ? Math.sqrt(Math.pow(segment.points[3][0] - segment.points[0][0], 2) + Math.pow(segment.points[3][1] - segment.points[0][1], 2))
+      : 0;
+
+    var angle = segment.normalAngle(t);
+    var point = segment.point(t);
+    setPoint(
+      outputBezier,
+      point,
+      angle,
+      direction,
+      amplitude,
+      dist / ((frequency + 1) * 2),
+      dist / ((frequency + 1) * 2),
+      pointType
+    );
+
+    direction = -direction;
+  }
+
+  return direction;
+}
+
+ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
+  var count = path._length;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+
+  if (!path.c) {
+    count -= 1;
+  }
+
+  if (count === 0) return clonedPath;
+
+  var direction = -1;
+  var segment = PolynomialBezier.shapeSegment(path, 0);
+  zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
+
+  for (var i = 0; i < count; i += 1) {
+    direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
+
+    if (i === count - 1 && !path.c) {
+      segment = null;
+    } else {
+      segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
+    }
+
+    zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
+  }
+
+  return clonedPath;
+};
+
+ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amplitude = this.amplitude.v;
+  var frequency = Math.max(0, Math.round(this.frequency.v));
+  var pointType = this.pointsType.v;
+
+  if (amplitude !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function linearOffset(p1, p2, amount) {
+  var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
+  return [
+    polarOffset(p1, angle, amount),
+    polarOffset(p2, angle, amount),
+  ];
+}
+
+function offsetSegment(segment, amount) {
+  var p0; var p1a; var p1b; var p2b; var p2a; var
+    p3;
+  var e;
+  e = linearOffset(segment.points[0], segment.points[1], amount);
+  p0 = e[0];
+  p1a = e[1];
+  e = linearOffset(segment.points[1], segment.points[2], amount);
+  p1b = e[0];
+  p2b = e[1];
+  e = linearOffset(segment.points[2], segment.points[3], amount);
+  p2a = e[0];
+  p3 = e[1];
+  var p1 = lineIntersection(p0, p1a, p1b, p2b);
+  if (p1 === null) p1 = p1a;
+  var p2 = lineIntersection(p2a, p3, p1b, p2b);
+  if (p2 === null) p2 = p2a;
+
+  return new PolynomialBezier(p0, p1, p2, p3);
+}
+
+function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
+  var p0 = seg1.points[3];
+  var p1 = seg2.points[0];
+
+  // Bevel
+  if (lineJoin === 3) return p0;
+
+  // Connected, they don't need a joint
+  if (pointEqual(p0, p1)) return p0;
+
+  // Round
+  if (lineJoin === 2) {
+    var angleOut = -seg1.tangentAngle(1);
+    var angleIn = -seg2.tangentAngle(0) + Math.PI;
+    var center = lineIntersection(
+      p0,
+      polarOffset(p0, angleOut + Math.PI / 2, 100),
+      p1,
+      polarOffset(p1, angleOut + Math.PI / 2, 100)
+    );
+    var radius = center ? pointDistance(center, p0) : pointDistance(p0, p1) / 2;
+
+    var tan = polarOffset(p0, angleOut, 2 * radius * roundCorner);
+    outputBezier.setXYAt(tan[0], tan[1], 'o', outputBezier.length() - 1);
+
+    tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
+    outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
+
+    return p1;
+  }
+
+  // Miter
+  var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
+  var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
+  var intersection = lineIntersection(t0, p0, p1, t1);
+  if (intersection && pointDistance(intersection, p0) < miterLimit) {
+    outputBezier.setTripleAt(
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      outputBezier.length()
+    );
+    return intersection;
+  }
+
+  return p0;
+}
+
+function getIntersection(a, b) {
+  const intersect = a.intersections(b);
+
+  if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
+
+  if (intersect.length) return intersect[0];
+
+  return null;
+}
+
+function pruneSegmentIntersection(a, b) {
+  var outa = a.slice();
+  var outb = b.slice();
+  var intersect = getIntersection(a[a.length - 1], b[0]);
+  if (intersect) {
+    outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
+    outb[0] = b[0].split(intersect[1])[1];
+  }
+  if (a.length > 1 && b.length > 1) {
+    intersect = getIntersection(a[0], b[b.length - 1]);
+    if (intersect) {
+      return [
+        [a[0].split(intersect[0])[0]],
+        [b[b.length - 1].split(intersect[1])[1]],
+      ];
+    }
+  }
+  return [outa, outb];
+}
+
+function pruneIntersections(segments) {
+  var e;
+  for (var i = 1; i < segments.length; i += 1) {
+    e = pruneSegmentIntersection(segments[i - 1], segments[i]);
+    segments[i - 1] = e[0];
+    segments[i] = e[1];
+  }
+
+  if (segments.length > 1) {
+    e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
+    segments[segments.length - 1] = e[0];
+    segments[0] = e[1];
+  }
+
+  return segments;
+}
+
+function offsetSegmentSplit(segment, amount) {
+  /*
+    We split each bezier segment into smaller pieces based
+    on inflection points, this ensures the control point
+    polygon is convex.
+
+    (A cubic bezier can have none, one, or two inflection points)
+  */
+  var flex = segment.inflectionPoints();
+  var left;
+  var right;
+  var split;
+  var mid;
+
+  if (flex.length === 0) {
+    return [offsetSegment(segment, amount)];
+  }
+
+  if (flex.length === 1 || floatEqual(flex[1], 1)) {
+    split = segment.split(flex[0]);
+    left = split[0];
+    right = split[1];
+
+    return [
+      offsetSegment(left, amount),
+      offsetSegment(right, amount),
+    ];
+  }
+
+  split = segment.split(flex[0]);
+  left = split[0];
+  var t = (flex[1] - flex[0]) / (1 - flex[0]);
+  split = split[1].split(t);
+  mid = split[0];
+  right = split[1];
+
+  return [
+    offsetSegment(left, amount),
+    offsetSegment(mid, amount),
+    offsetSegment(right, amount),
+  ];
+}
+
+function OffsetPathModifier() {}
+
+extendPrototype([ShapeModifier], OffsetPathModifier);
+OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this.miterLimit = PropertyFactory.getProp(elem, data.ml, 0, null, this);
+  this.lineJoin = data.lj;
+  this._isAnimated = this.amount.effectsSequence.length !== 0;
+};
+
+OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
+  var outputBezier = shapePool.newElement();
+  outputBezier.c = inputBezier.c;
+  var count = inputBezier.length();
+  if (!inputBezier.c) {
+    count -= 1;
+  }
+  var i; var j; var segment;
+  var multiSegments = [];
+
+  for (i = 0; i < count; i += 1) {
+    segment = PolynomialBezier.shapeSegment(inputBezier, i);
+    multiSegments.push(offsetSegmentSplit(segment, amount));
+  }
+
+  if (!inputBezier.c) {
+    for (i = count - 1; i >= 0; i -= 1) {
+      segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
+      multiSegments.push(offsetSegmentSplit(segment, amount));
+    }
+  }
+
+  multiSegments = pruneIntersections(multiSegments);
+
+  // Add bezier segments to the output and apply line joints
+  var lastPoint = null;
+  var lastSeg = null;
+
+  for (i = 0; i < multiSegments.length; i += 1) {
+    var multiSegment = multiSegments[i];
+
+    if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
+
+    lastSeg = multiSegment[multiSegment.length - 1];
+
+    for (j = 0; j < multiSegment.length; j += 1) {
+      segment = multiSegment[j];
+
+      if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
+        outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
+      } else {
+        outputBezier.setTripleAt(
+          segment.points[0][0],
+          segment.points[0][1],
+          segment.points[1][0],
+          segment.points[1][1],
+          segment.points[0][0],
+          segment.points[0][1],
+          outputBezier.length()
+        );
+      }
+
+      outputBezier.setTripleAt(
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[2][0],
+        segment.points[2][1],
+        outputBezier.length()
+      );
+
+      lastPoint = segment.points[3];
+    }
+  }
+
+  if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
+
+  return outputBezier;
+};
+
+OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+  var miterLimit = this.miterLimit.v;
+  var lineJoin = this.lineJoin;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function getFontProperties(fontData) {
+  var styles = fontData.fStyle ? fontData.fStyle.split(' ') : [];
+
+  var fWeight = 'normal'; var
+    fStyle = 'normal';
+  var len = styles.length;
+  var styleName;
+  for (var i = 0; i < len; i += 1) {
+    styleName = styles[i].toLowerCase();
+    switch (styleName) {
+      case 'italic':
+        fStyle = 'italic';
+        break;
+      case 'bold':
+        fWeight = '700';
+        break;
+      case 'black':
+        fWeight = '900';
+        break;
+      case 'medium':
+        fWeight = '500';
+        break;
+      case 'regular':
+      case 'normal':
+        fWeight = '400';
+        break;
+      case 'light':
+      case 'thin':
+        fWeight = '200';
+        break;
+      default:
+        break;
+    }
+  }
+
+  return {
+    style: fStyle,
+    weight: fontData.fWeight || fWeight,
+  };
+}
+
+const FontManager = (function () {
+  var maxWaitingTime = 5000;
+  var emptyChar = {
+    w: 0,
+    size: 0,
+    shapes: [],
+    data: {
+      shapes: [],
+    },
+  };
+  var combinedCharacters = [];
+  // Hindi characters
+  combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366,
+    2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379,
+    2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
+
+  var BLACK_FLAG_CODE_POINT = 127988;
+  var CANCEL_TAG_CODE_POINT = 917631;
+  var A_TAG_CODE_POINT = 917601;
+  var Z_TAG_CODE_POINT = 917626;
+  var VARIATION_SELECTOR_16_CODE_POINT = 65039;
+  var ZERO_WIDTH_JOINER_CODE_POINT = 8205;
+  var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
+  var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
+
+  var surrogateModifiers = [
+    'd83cdffb',
+    'd83cdffc',
+    'd83cdffd',
+    'd83cdffe',
+    'd83cdfff',
+  ];
+
+  function trimFontOptions(font) {
+    var familyArray = font.split(',');
+    var i;
+    var len = familyArray.length;
+    var enabledFamilies = [];
+    for (i = 0; i < len; i += 1) {
+      if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
+        enabledFamilies.push(familyArray[i]);
+      }
+    }
+    return enabledFamilies.join(',');
+  }
+
+  function setUpNode(font, family) {
+    var parentNode = createTag('span');
+    // Node is invisible to screen readers.
+    parentNode.setAttribute('aria-hidden', true);
+    parentNode.style.fontFamily = family;
+    var node = createTag('span');
+    // Characters that vary significantly among different fonts
+    node.innerText = 'giItT1WQy@!-/#';
+    // Visible - so we can measure it - but not on the screen
+    parentNode.style.position = 'absolute';
+    parentNode.style.left = '-10000px';
+    parentNode.style.top = '-10000px';
+    // Large font size makes even subtle changes obvious
+    parentNode.style.fontSize = '300px';
+    // Reset any font properties
+    parentNode.style.fontVariant = 'normal';
+    parentNode.style.fontStyle = 'normal';
+    parentNode.style.fontWeight = 'normal';
+    parentNode.style.letterSpacing = '0';
+    parentNode.appendChild(node);
+    document.body.appendChild(parentNode);
+
+    // Remember width with no applied web font
+    var width = node.offsetWidth;
+    node.style.fontFamily = trimFontOptions(font) + ', ' + family;
+    return { node: node, w: width, parent: parentNode };
+  }
+
+  function checkLoadedFonts() {
+    var i;
+    var len = this.fonts.length;
+    var node;
+    var w;
+    var loadedCount = len;
+    for (i = 0; i < len; i += 1) {
+      if (this.fonts[i].loaded) {
+        loadedCount -= 1;
+      } else if (this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0) {
+        this.fonts[i].loaded = true;
+      } else {
+        node = this.fonts[i].monoCase.node;
+        w = this.fonts[i].monoCase.w;
+        if (node.offsetWidth !== w) {
+          loadedCount -= 1;
+          this.fonts[i].loaded = true;
+        } else {
+          node = this.fonts[i].sansCase.node;
+          w = this.fonts[i].sansCase.w;
+          if (node.offsetWidth !== w) {
+            loadedCount -= 1;
+            this.fonts[i].loaded = true;
+          }
+        }
+        if (this.fonts[i].loaded) {
+          this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
+          this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
+        }
+      }
+    }
+
+    if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
+      setTimeout(this.checkLoadedFontsBinded, 20);
+    } else {
+      setTimeout(this.setIsLoadedBinded, 10);
+    }
+  }
+
+  function createHelper(fontData, def) {
+    var engine = (document.body && def) ? 'svg' : 'canvas';
+    var helper;
+    var fontProps = getFontProperties(fontData);
+    if (engine === 'svg') {
+      var tHelper = createNS('text');
+      tHelper.style.fontSize = '100px';
+      // tHelper.style.fontFamily = fontData.fFamily;
+      tHelper.setAttribute('font-family', fontData.fFamily);
+      tHelper.setAttribute('font-style', fontProps.style);
+      tHelper.setAttribute('font-weight', fontProps.weight);
+      tHelper.textContent = '1';
+      if (fontData.fClass) {
+        tHelper.style.fontFamily = 'inherit';
+        tHelper.setAttribute('class', fontData.fClass);
+      } else {
+        tHelper.style.fontFamily = fontData.fFamily;
+      }
+      def.appendChild(tHelper);
+      helper = tHelper;
+    } else {
+      var tCanvasHelper = new OffscreenCanvas(500, 500).getContext('2d');
+      tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
+      helper = tCanvasHelper;
+    }
+    function measure(text) {
+      if (engine === 'svg') {
+        helper.textContent = text;
+        return helper.getComputedTextLength();
+      }
+      return helper.measureText(text).width;
+    }
+    return {
+      measureText: measure,
+    };
+  }
+
+  function addFonts(fontData, defs) {
+    if (!fontData) {
+      this.isLoaded = true;
+      return;
+    }
+    if (this.chars) {
+      this.isLoaded = true;
+      this.fonts = fontData.list;
+      return;
+    }
+    if (!document.body) {
+      this.isLoaded = true;
+      fontData.list.forEach((data) => {
+        data.helper = createHelper(data);
+        data.cache = {};
+      });
+      this.fonts = fontData.list;
+      return;
+    }
+
+    var fontArr = fontData.list;
+    var i;
+    var len = fontArr.length;
+    var _pendingFonts = len;
+    for (i = 0; i < len; i += 1) {
+      var shouldLoadFont = true;
+      var loadedSelector;
+      var j;
+      fontArr[i].loaded = false;
+      fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
+      fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
+      if (!fontArr[i].fPath) {
+        fontArr[i].loaded = true;
+        _pendingFonts -= 1;
+      } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
+        loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
+
+        if (loadedSelector.length > 0) {
+          shouldLoadFont = false;
+        }
+
+        if (shouldLoadFont) {
+          var s = createTag('style');
+          s.setAttribute('f-forigin', fontArr[i].fOrigin);
+          s.setAttribute('f-origin', fontArr[i].origin);
+          s.setAttribute('f-family', fontArr[i].fFamily);
+          s.type = 'text/css';
+          s.innerText = '@font-face {font-family: ' + fontArr[i].fFamily + "; font-style: normal; src: url('" + fontArr[i].fPath + "');}";
+          defs.appendChild(s);
+        }
+      } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
+        loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var l = createTag('link');
+          l.setAttribute('f-forigin', fontArr[i].fOrigin);
+          l.setAttribute('f-origin', fontArr[i].origin);
+          l.type = 'text/css';
+          l.rel = 'stylesheet';
+          l.href = fontArr[i].fPath;
+          document.body.appendChild(l);
+        }
+      } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
+        loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (fontArr[i].fPath === loadedSelector[j].src) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var sc = createTag('link');
+          sc.setAttribute('f-forigin', fontArr[i].fOrigin);
+          sc.setAttribute('f-origin', fontArr[i].origin);
+          sc.setAttribute('rel', 'stylesheet');
+          sc.setAttribute('href', fontArr[i].fPath);
+          defs.appendChild(sc);
+        }
+      }
+      fontArr[i].helper = createHelper(fontArr[i], defs);
+      fontArr[i].cache = {};
+      this.fonts.push(fontArr[i]);
+    }
+    if (_pendingFonts === 0) {
+      this.isLoaded = true;
+    } else {
+      // On some cases even if the font is loaded, it won't load correctly when measuring text on canvas.
+      // Adding this timeout seems to fix it
+      setTimeout(this.checkLoadedFonts.bind(this), 100);
+    }
+  }
+
+  function addChars(chars) {
+    if (!chars) {
+      return;
+    }
+    if (!this.chars) {
+      this.chars = [];
+    }
+    var i;
+    var len = chars.length;
+    var j;
+    var jLen = this.chars.length;
+    var found;
+    for (i = 0; i < len; i += 1) {
+      j = 0;
+      found = false;
+      while (j < jLen) {
+        if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
+          found = true;
+        }
+        j += 1;
+      }
+      if (!found) {
+        this.chars.push(chars[i]);
+        jLen += 1;
+      }
+    }
+  }
+
+  function getCharData(char, style, font) {
+    var i = 0;
+    var len = this.chars.length;
+    while (i < len) {
+      if (this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font) {
+        return this.chars[i];
+      }
+      i += 1;
+    }
+    if (((typeof char === 'string' && char.charCodeAt(0) !== 13) || !char)
+            && console
+            && console.warn // eslint-disable-line no-console
+            && !this._warned
+    ) {
+      this._warned = true;
+      console.warn('Missing character from exported characters list: ', char, style, font); // eslint-disable-line no-console
+    }
+    return emptyChar;
+  }
+
+  function measureText(char, fontName, size) {
+    var fontData = this.getFontByName(fontName);
+    // Using the char instead of char.charCodeAt(0)
+    // to avoid collisions between equal chars
+    var index = char;
+    if (!fontData.cache[index]) {
+      var tHelper = fontData.helper;
+      if (char === ' ') {
+        var doubleSize = tHelper.measureText('|' + char + '|');
+        var singleSize = tHelper.measureText('||');
+        fontData.cache[index] = (doubleSize - singleSize) / 100;
+      } else {
+        fontData.cache[index] = tHelper.measureText(char) / 100;
+      }
+    }
+    return fontData.cache[index] * size;
+  }
+
+  function getFontByName(name) {
+    var i = 0;
+    var len = this.fonts.length;
+    while (i < len) {
+      if (this.fonts[i].fName === name) {
+        return this.fonts[i];
+      }
+      i += 1;
+    }
+    return this.fonts[0];
+  }
+
+  function getCodePoint(string) {
+    var codePoint = 0;
+    var first = string.charCodeAt(0);
+    if (first >= 0xD800 && first <= 0xDBFF) {
+      var second = string.charCodeAt(1);
+      if (second >= 0xDC00 && second <= 0xDFFF) {
+        codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+      }
+    }
+    return codePoint;
+  }
+
+  // Skin tone modifiers
+  function isModifier(firstCharCode, secondCharCode) {
+    var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
+    return surrogateModifiers.indexOf(sum) !== -1;
+  }
+
+  function isZeroWidthJoiner(charCode) {
+    return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
+  }
+
+  // This codepoint may change the appearance of the preceding character.
+  // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
+  // as a colorful image as compared to a monochrome text variant.
+  function isVariationSelector(charCode) {
+    return charCode === VARIATION_SELECTOR_16_CODE_POINT;
+  }
+
+  // The regional indicator symbols are a set of 26 alphabetic Unicode
+  /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
+  // two-letter country codes in a way that allows optional special treatment.
+  function isRegionalCode(string) {
+    var codePoint = getCodePoint(string);
+    if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
+      return true;
+    }
+    return false;
+  }
+
+  // Some Emoji implementations represent combinations of
+  // two “regional indicator” letters as a single flag symbol.
+  function isFlagEmoji(string) {
+    return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
+  }
+
+  function isCombinedCharacter(char) {
+    return combinedCharacters.indexOf(char) !== -1;
+  }
+
+  // Regional flags start with a BLACK_FLAG_CODE_POINT
+  // folowed by 5 chars in the TAG range
+  // and end with a CANCEL_TAG_CODE_POINT
+  function isRegionalFlag(text, index) {
+    var codePoint = getCodePoint(text.substr(index, 2));
+    if (codePoint !== BLACK_FLAG_CODE_POINT) {
+      return false;
+    }
+    var count = 0;
+    index += 2;
+    while (count < 5) {
+      codePoint = getCodePoint(text.substr(index, 2));
+      if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
+        return false;
+      }
+      count += 1;
+      index += 2;
+    }
+    return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
+  }
+
+  function setIsLoaded() {
+    this.isLoaded = true;
+  }
+
+  var Font = function () {
+    this.fonts = [];
+    this.chars = null;
+    this.typekitLoaded = 0;
+    this.isLoaded = false;
+    this._warned = false;
+    this.initTime = Date.now();
+    this.setIsLoadedBinded = this.setIsLoaded.bind(this);
+    this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
+  };
+  Font.isModifier = isModifier;
+  Font.isZeroWidthJoiner = isZeroWidthJoiner;
+  Font.isFlagEmoji = isFlagEmoji;
+  Font.isRegionalCode = isRegionalCode;
+  Font.isCombinedCharacter = isCombinedCharacter;
+  Font.isRegionalFlag = isRegionalFlag;
+  Font.isVariationSelector = isVariationSelector;
+  Font.BLACK_FLAG_CODE_POINT = BLACK_FLAG_CODE_POINT;
+
+  var fontPrototype = {
+    addChars: addChars,
+    addFonts: addFonts,
+    getCharData: getCharData,
+    getFontByName: getFontByName,
+    measureText: measureText,
+    checkLoadedFonts: checkLoadedFonts,
+    setIsLoaded: setIsLoaded,
+  };
+
+  Font.prototype = fontPrototype;
+
+  return Font;
+}());
+
+function SlotManager(animationData) {
+  this.animationData = animationData;
+}
+SlotManager.prototype.getProp = function (data) {
+  if (this.animationData.slots
+    && this.animationData.slots[data.sid]
+  ) {
+    return Object.assign(data, this.animationData.slots[data.sid].p);
+  }
+  return data;
+};
+
+function slotFactory(animationData) {
+  return new SlotManager(animationData);
+}
+
+function RenderableElement() {
+
+}
+
+RenderableElement.prototype = {
+  initRenderable: function () {
+    // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
+    this.isInRange = false;
+    // layer's display state
+    this.hidden = false;
+    // If layer's transparency equals 0, it can be hidden
+    this.isTransparent = false;
+    // list of animated components
+    this.renderableComponents = [];
+  },
+  addRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) === -1) {
+      this.renderableComponents.push(component);
+    }
+  },
+  removeRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) !== -1) {
+      this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1);
+    }
+  },
+  prepareRenderableFrame: function (num) {
+    this.checkLayerLimits(num);
+  },
+  checkTransparency: function () {
+    if (this.finalTransform.mProp.o.v <= 0) {
+      if (!this.isTransparent && this.globalData.renderConfig.hideOnTransparent) {
+        this.isTransparent = true;
+        this.hide();
+      }
+    } else if (this.isTransparent) {
+      this.isTransparent = false;
+      this.show();
+    }
+  },
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     *
+     */
+  checkLayerLimits: function (num) {
+    if (this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) {
+      if (this.isInRange !== true) {
+        this.globalData._mdf = true;
+        this._mdf = true;
+        this.isInRange = true;
+        this.show();
+      }
+    } else if (this.isInRange !== false) {
+      this.globalData._mdf = true;
+      this.isInRange = false;
+      this.hide();
+    }
+  },
+  renderRenderable: function () {
+    var i;
+    var len = this.renderableComponents.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderableComponents[i].renderFrame(this._isFirstFrame);
+    }
+    /* this.maskManager.renderFrame(this.finalTransform.mat);
+        this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
+  },
+  sourceRectAtTime: function () {
+    return {
+      top: 0,
+      left: 0,
+      width: 100,
+      height: 100,
+    };
+  },
+  getLayerSize: function () {
+    if (this.data.ty === 5) {
+      return { w: this.data.textData.width, h: this.data.textData.height };
+    }
+    return { w: this.data.width, h: this.data.height };
+  },
+};
+
+const getBlendMode = (function () {
+  var blendModeEnums = {
+    0: 'source-over',
+    1: 'multiply',
+    2: 'screen',
+    3: 'overlay',
+    4: 'darken',
+    5: 'lighten',
+    6: 'color-dodge',
+    7: 'color-burn',
+    8: 'hard-light',
+    9: 'soft-light',
+    10: 'difference',
+    11: 'exclusion',
+    12: 'hue',
+    13: 'saturation',
+    14: 'color',
+    15: 'luminosity',
+  };
+
+  return function (mode) {
+    return blendModeEnums[mode] || '';
+  };
+}());
+
+function SliderEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function AngleEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function ColorEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function PointEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function LayerIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function MaskIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function CheckboxEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function NoValueEffect() {
+  this.p = {};
+}
+
+function EffectsManager(data, element) {
+  var effects = data.ef || [];
+  this.effectElements = [];
+  var i;
+  var len = effects.length;
+  var effectItem;
+  for (i = 0; i < len; i += 1) {
+    effectItem = new GroupEffect(effects[i], element);
+    this.effectElements.push(effectItem);
+  }
+}
+
+function GroupEffect(data, element) {
+  this.init(data, element);
+}
+
+extendPrototype([DynamicPropertyContainer], GroupEffect);
+
+GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
+
+GroupEffect.prototype.init = function (data, element) {
+  this.data = data;
+  this.effectElements = [];
+  this.initDynamicPropertyContainer(element);
+  var i;
+  var len = this.data.ef.length;
+  var eff;
+  var effects = this.data.ef;
+  for (i = 0; i < len; i += 1) {
+    eff = null;
+    switch (effects[i].ty) {
+      case 0:
+        eff = new SliderEffect(effects[i], element, this);
+        break;
+      case 1:
+        eff = new AngleEffect(effects[i], element, this);
+        break;
+      case 2:
+        eff = new ColorEffect(effects[i], element, this);
+        break;
+      case 3:
+        eff = new PointEffect(effects[i], element, this);
+        break;
+      case 4:
+      case 7:
+        eff = new CheckboxEffect(effects[i], element, this);
+        break;
+      case 10:
+        eff = new LayerIndexEffect(effects[i], element, this);
+        break;
+      case 11:
+        eff = new MaskIndexEffect(effects[i], element, this);
+        break;
+      case 5:
+        eff = new EffectsManager(effects[i], element, this);
+        break;
+        // case 6:
+      default:
+        eff = new NoValueEffect(effects[i], element, this);
+        break;
+    }
+    if (eff) {
+      this.effectElements.push(eff);
+    }
+  }
+};
+
+function BaseElement() {
+}
+
+BaseElement.prototype = {
+  checkMasks: function () {
+    if (!this.data.hasMask) {
+      return false;
+    }
+    var i = 0;
+    var len = this.data.masksProperties.length;
+    while (i < len) {
+      if ((this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false)) {
+        return true;
+      }
+      i += 1;
+    }
+    return false;
+  },
+  initExpressions: function () {
+    const expressionsInterfaces = getExpressionInterfaces();
+    if (!expressionsInterfaces) {
+      return;
+    }
+    const LayerExpressionInterface = expressionsInterfaces('layer');
+    const EffectsExpressionInterface = expressionsInterfaces('effects');
+    const ShapeExpressionInterface = expressionsInterfaces('shape');
+    const TextExpressionInterface = expressionsInterfaces('text');
+    const CompExpressionInterface = expressionsInterfaces('comp');
+    this.layerInterface = LayerExpressionInterface(this);
+    if (this.data.hasMask && this.maskManager) {
+      this.layerInterface.registerMaskInterface(this.maskManager);
+    }
+    var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
+    this.layerInterface.registerEffectsInterface(effectsInterface);
+
+    if (this.data.ty === 0 || this.data.xt) {
+      this.compInterface = CompExpressionInterface(this);
+    } else if (this.data.ty === 4) {
+      this.layerInterface.shapeInterface = ShapeExpressionInterface(this.shapesData, this.itemsData, this.layerInterface);
+      this.layerInterface.content = this.layerInterface.shapeInterface;
+    } else if (this.data.ty === 5) {
+      this.layerInterface.textInterface = TextExpressionInterface(this);
+      this.layerInterface.text = this.layerInterface.textInterface;
+    }
+  },
+  setBlendMode: function () {
+    var blendModeValue = getBlendMode(this.data.bm);
+    var elem = this.baseElement || this.layerElement;
+
+    elem.style['mix-blend-mode'] = blendModeValue;
+  },
+  initBaseData: function (data, globalData, comp) {
+    this.globalData = globalData;
+    this.comp = comp;
+    this.data = data;
+    this.layerId = createElementID();
+
+    // Stretch factor for old animations missing this property.
+    if (!this.data.sr) {
+      this.data.sr = 1;
+    }
+    // effects manager
+    this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
+  },
+  getType: function () {
+    return this.type;
+  },
+  sourceRectAtTime: function () {},
+};
+
+/**
+ * @file
+ * Handles element's layer frame update.
+ * Checks layer in point and out point
+ *
+ */
+
+function FrameElement() {}
+
+FrameElement.prototype = {
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     */
+  initFrame: function () {
+    // set to true when inpoint is rendered
+    this._isFirstFrame = false;
+    // list of animated properties
+    this.dynamicProperties = [];
+    // If layer has been modified in current tick this will be true
+    this._mdf = false;
+  },
+  /**
+     * @function
+     * Calculates all dynamic values
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     * @param {boolean} isVisible
+     * if layers is currently in range
+     *
+     */
+  prepareProperties: function (num, isVisible) {
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      if (isVisible || (this._isParent && this.dynamicProperties[i].propType === 'transform')) {
+        this.dynamicProperties[i].getValue();
+        if (this.dynamicProperties[i]._mdf) {
+          this.globalData._mdf = true;
+          this._mdf = true;
+        }
+      }
+    }
+  },
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+    }
+  },
+};
+
+function FootageElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.footageData = globalData.imageLoader.getAsset(this.assetData);
+  this.initBaseData(data, globalData, comp);
+}
+
+FootageElement.prototype.prepareFrame = function () {
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
+
+FootageElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+FootageElement.prototype.renderFrame = function () {
+};
+
+FootageElement.prototype.destroy = function () {
+};
+
+FootageElement.prototype.initExpressions = function () {
+  const expressionsInterfaces = getExpressionInterfaces();
+  if (!expressionsInterfaces) {
+    return;
+  }
+  const FootageInterface = expressionsInterfaces('footage');
+  this.layerInterface = FootageInterface(this);
+};
+
+FootageElement.prototype.getFootageData = function () {
+  return this.footageData;
+};
+
+function AudioElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initBaseData(data, globalData, comp);
+  this._isPlaying = false;
+  this._canPlay = false;
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  this.audio = this.globalData.audioController.createAudio(assetPath);
+  this._currentTime = 0;
+  this.globalData.audioController.addAudio(this);
+  this._volumeMultiplier = 1;
+  this._volume = 1;
+  this._previousVolume = null;
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+  this.lv = PropertyFactory.getProp(this, data.au && data.au.lv ? data.au.lv : { k: [100] }, 1, 0.01, this);
+}
+
+AudioElement.prototype.prepareFrame = function (num) {
+  this.prepareRenderableFrame(num, true);
+  this.prepareProperties(num, true);
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    this._currentTime = timeRemapped;
+  } else {
+    this._currentTime = num / this.data.sr;
+  }
+  this._volume = this.lv.v[0];
+  var totalVolume = this._volume * this._volumeMultiplier;
+  if (this._previousVolume !== totalVolume) {
+    this._previousVolume = totalVolume;
+    this.audio.volume(totalVolume);
+  }
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
+
+AudioElement.prototype.renderFrame = function () {
+  if (this.isInRange && this._canPlay) {
+    if (!this._isPlaying) {
+      this.audio.play();
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+      this._isPlaying = true;
+    } else if (!this.audio.playing()
+      || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1
+    ) {
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+    }
+  }
+};
+
+AudioElement.prototype.show = function () {
+  // this.audio.play()
+};
+
+AudioElement.prototype.hide = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+};
+
+AudioElement.prototype.pause = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+  this._canPlay = false;
+};
+
+AudioElement.prototype.resume = function () {
+  this._canPlay = true;
+};
+
+AudioElement.prototype.setRate = function (rateValue) {
+  this.audio.rate(rateValue);
+};
+
+AudioElement.prototype.volume = function (volumeValue) {
+  this._volumeMultiplier = volumeValue;
+  this._previousVolume = volumeValue * this._volume;
+  this.audio.volume(this._previousVolume);
+};
+
+AudioElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+AudioElement.prototype.destroy = function () {
+};
+
+AudioElement.prototype.sourceRectAtTime = function () {
+};
+
+AudioElement.prototype.initExpressions = function () {
+};
+
+function BaseRenderer() {}
+BaseRenderer.prototype.checkLayers = function (num) {
+  var i;
+  var len = this.layers.length;
+  var data;
+  this.completeLayers = true;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (!this.elements[i]) {
+      data = this.layers[i];
+      if (data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) {
+        this.buildItem(i);
+      }
+    }
+    this.completeLayers = this.elements[i] ? this.completeLayers : false;
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.createItem = function (layer) {
+  switch (layer.ty) {
+    case 2:
+      return this.createImage(layer);
+    case 0:
+      return this.createComp(layer);
+    case 1:
+      return this.createSolid(layer);
+    case 3:
+      return this.createNull(layer);
+    case 4:
+      return this.createShape(layer);
+    case 5:
+      return this.createText(layer);
+    case 6:
+      return this.createAudio(layer);
+    case 13:
+      return this.createCamera(layer);
+    case 15:
+      return this.createFootage(layer);
+    default:
+      return this.createNull(layer);
+  }
+};
+
+BaseRenderer.prototype.createCamera = function () {
+  throw new Error('You\'re using a 3d camera. Try the html renderer.');
+};
+
+BaseRenderer.prototype.createAudio = function (data) {
+  return new AudioElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.createFootage = function (data) {
+  return new FootageElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.buildAllItems = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    this.buildItem(i);
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.includeLayers = function (newLayers) {
+  this.completeLayers = false;
+  var i;
+  var len = newLayers.length;
+  var j;
+  var jLen = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    j = 0;
+    while (j < jLen) {
+      if (this.layers[j].id === newLayers[i].id) {
+        this.layers[j] = newLayers[i];
+        break;
+      }
+      j += 1;
+    }
+  }
+};
+
+BaseRenderer.prototype.setProjectInterface = function (pInterface) {
+  this.globalData.projectInterface = pInterface;
+};
+
+BaseRenderer.prototype.initItems = function () {
+  if (!this.globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+};
+BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
+  var elements = this.elements;
+  var layers = this.layers;
+  var i = 0;
+  var len = layers.length;
+  while (i < len) {
+    if (layers[i].ind == parentName) { // eslint-disable-line eqeqeq
+      if (!elements[i] || elements[i] === true) {
+        this.buildItem(i);
+        this.addPendingElement(element);
+      } else {
+        hierarchy.push(elements[i]);
+        elements[i].setAsParent();
+        if (layers[i].parent !== undefined) {
+          this.buildElementParenting(element, layers[i].parent, hierarchy);
+        } else {
+          element.setHierarchy(hierarchy);
+        }
+      }
+    }
+    i += 1;
+  }
+};
+
+BaseRenderer.prototype.addPendingElement = function (element) {
+  this.pendingElements.push(element);
+};
+
+BaseRenderer.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var len = assets.length;
+  for (i = 0; i < len; i += 1) {
+    if (assets[i].xt) {
+      var comp = this.createComp(assets[i]);
+      comp.initExpressions();
+      this.globalData.projectInterface.registerComposition(comp);
+    }
+  }
+};
+
+BaseRenderer.prototype.getElementById = function (ind) {
+  var i;
+  var len = this.elements.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i].data.ind === ind) {
+      return this.elements[i];
+    }
+  }
+  return null;
+};
+
+BaseRenderer.prototype.getElementByPath = function (path) {
+  var pathValue = path.shift();
+  var element;
+  if (typeof pathValue === 'number') {
+    element = this.elements[pathValue];
+  } else {
+    var i;
+    var len = this.elements.length;
+    for (i = 0; i < len; i += 1) {
+      if (this.elements[i].data.nm === pathValue) {
+        element = this.elements[i];
+        break;
+      }
+    }
+  }
+  if (path.length === 0) {
+    return element;
+  }
+  return element.getElementByPath(path);
+};
+
+BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
+  this.globalData.fontManager = new FontManager();
+  this.globalData.slotManager = slotFactory(animData);
+  this.globalData.fontManager.addChars(animData.chars);
+  this.globalData.fontManager.addFonts(animData.fonts, fontsContainer);
+  this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+  this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+  this.globalData.imageLoader = this.animationItem.imagePreloader;
+  this.globalData.audioController = this.animationItem.audioController;
+  this.globalData.frameId = 0;
+  this.globalData.frameRate = animData.fr;
+  this.globalData.nm = animData.nm;
+  this.globalData.compSize = {
+    w: animData.w,
+    h: animData.h,
+  };
+};
+
+var effectTypes = {
+  TRANSFORM_EFFECT: 'transformEFfect',
+};
+
+function TransformElement() {}
+
+TransformElement.prototype = {
+  initTransform: function () {
+    var mat = new Matrix();
+    this.finalTransform = {
+      mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : { o: 0 },
+      _matMdf: false,
+      _localMatMdf: false,
+      _opMdf: false,
+      mat: mat,
+      localMat: mat,
+      localOpacity: 1,
+    };
+    if (this.data.ao) {
+      this.finalTransform.mProp.autoOriented = true;
+    }
+
+    // TODO: check TYPE 11: Guided elements
+    if (this.data.ty !== 11) {
+      // this.createElements();
+    }
+  },
+  renderTransform: function () {
+    this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
+    this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
+
+    if (this.hierarchy) {
+      var mat;
+      var finalMat = this.finalTransform.mat;
+      var i = 0;
+      var len = this.hierarchy.length;
+      // Checking if any of the transformation matrices in the hierarchy chain has changed.
+      if (!this.finalTransform._matMdf) {
+        while (i < len) {
+          if (this.hierarchy[i].finalTransform.mProp._mdf) {
+            this.finalTransform._matMdf = true;
+            break;
+          }
+          i += 1;
+        }
+      }
+
+      if (this.finalTransform._matMdf) {
+        mat = this.finalTransform.mProp.v.props;
+        finalMat.cloneFromProps(mat);
+        for (i = 0; i < len; i += 1) {
+          finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
+        }
+      }
+    }
+    if (!this.localTransforms || this.finalTransform._matMdf) {
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+    }
+    if (this.finalTransform._opMdf) {
+      this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderLocalTransform: function () {
+    if (this.localTransforms) {
+      var i = 0;
+      var len = this.localTransforms.length;
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+      if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
+        while (i < len) {
+          if (this.localTransforms[i]._mdf) {
+            this.finalTransform._localMatMdf = true;
+          }
+          if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
+            this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+            this.finalTransform._opMdf = true;
+          }
+          i += 1;
+        }
+      }
+      if (this.finalTransform._localMatMdf) {
+        var localMat = this.finalTransform.localMat;
+        this.localTransforms[0].matrix.clone(localMat);
+        for (i = 1; i < len; i += 1) {
+          var lmat = this.localTransforms[i].matrix;
+          localMat.multiply(lmat);
+        }
+        localMat.multiply(this.finalTransform.mat);
+      }
+      if (this.finalTransform._opMdf) {
+        var localOp = this.finalTransform.localOpacity;
+        for (i = 0; i < len; i += 1) {
+          localOp *= this.localTransforms[i].opacity * 0.01;
+        }
+        this.finalTransform.localOpacity = localOp;
+      }
+    }
+  },
+  searchEffectTransforms: function () {
+    if (this.renderableEffectsManager) {
+      var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+      if (transformEffects.length) {
+        this.localTransforms = [];
+        this.finalTransform.localMat = new Matrix();
+        var i = 0;
+        var len = transformEffects.length;
+        for (i = 0; i < len; i += 1) {
+          this.localTransforms.push(transformEffects[i]);
+        }
+      }
+    }
+  },
+  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;
+    var len = transforms.length;
+    var 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;
+  },
+  mHelper: new Matrix(),
+};
+
+function MaskElement(data, element, globalData) {
+  this.data = data;
+  this.element = element;
+  this.globalData = globalData;
+  this.storedData = [];
+  this.masksProperties = this.data.masksProperties || [];
+  this.maskElement = null;
+  var defs = this.globalData.defs;
+  var i;
+  var len = this.masksProperties ? this.masksProperties.length : 0;
+  this.viewData = createSizedArray(len);
+  this.solidPath = '';
+
+  var path;
+  var properties = this.masksProperties;
+  var count = 0;
+  var currentMasks = [];
+  var j;
+  var jLen;
+  var layerId = createElementID();
+  var rect;
+  var expansor;
+  var feMorph;
+  var x;
+  var maskType = 'clipPath';
+  var maskRef = 'clip-path';
+  for (i = 0; i < len; i += 1) {
+    if ((properties[i].mode !== 'a' && properties[i].mode !== 'n') || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
+      maskType = 'mask';
+      maskRef = 'mask';
+    }
+
+    if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
+      rect = createNS('rect');
+      rect.setAttribute('fill', '#ffffff');
+      rect.setAttribute('width', this.element.comp.data.w || 0);
+      rect.setAttribute('height', this.element.comp.data.h || 0);
+      currentMasks.push(rect);
+    } else {
+      rect = null;
+    }
+
+    path = createNS('path');
+    if (properties[i].mode === 'n') {
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        elem: path,
+        lastPath: '',
+      };
+      defs.appendChild(path);
+    } else {
+      count += 1;
+
+      path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      path.setAttribute('clip-rule', 'nonzero');
+      var filterID;
+
+      if (properties[i].x.k !== 0) {
+        maskType = 'mask';
+        maskRef = 'mask';
+        x = PropertyFactory.getProp(this.element, properties[i].x, 0, null, this.element);
+        filterID = createElementID();
+        expansor = createNS('filter');
+        expansor.setAttribute('id', filterID);
+        feMorph = createNS('feMorphology');
+        feMorph.setAttribute('operator', 'erode');
+        feMorph.setAttribute('in', 'SourceGraphic');
+        feMorph.setAttribute('radius', '0');
+        expansor.appendChild(feMorph);
+        defs.appendChild(expansor);
+        path.setAttribute('stroke', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      } else {
+        feMorph = null;
+        x = null;
+      }
+
+      // TODO move this to a factory or to a constructor
+      this.storedData[i] = {
+        elem: path,
+        x: x,
+        expan: feMorph,
+        lastPath: '',
+        lastOperator: '',
+        filterId: filterID,
+        lastRadius: 0,
+      };
+      if (properties[i].mode === 'i') {
+        jLen = currentMasks.length;
+        var g = createNS('g');
+        for (j = 0; j < jLen; j += 1) {
+          g.appendChild(currentMasks[j]);
+        }
+        var mask = createNS('mask');
+        mask.setAttribute('mask-type', 'alpha');
+        mask.setAttribute('id', layerId + '_' + count);
+        mask.appendChild(path);
+        defs.appendChild(mask);
+        g.setAttribute('mask', 'url(' + getLocationHref() + '#' + layerId + '_' + count + ')');
+
+        currentMasks.length = 0;
+        currentMasks.push(g);
+      } else {
+        currentMasks.push(path);
+      }
+      if (properties[i].inv && !this.solidPath) {
+        this.solidPath = this.createLayerSolidPath();
+      }
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        elem: path,
+        lastPath: '',
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        invRect: rect,
+      };
+      if (!this.viewData[i].prop.k) {
+        this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
+      }
+    }
+  }
+
+  this.maskElement = createNS(maskType);
+
+  len = currentMasks.length;
+  for (i = 0; i < len; i += 1) {
+    this.maskElement.appendChild(currentMasks[i]);
+  }
+
+  if (count > 0) {
+    this.maskElement.setAttribute('id', layerId);
+    this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
+    defs.appendChild(this.maskElement);
+  }
+  if (this.viewData.length) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+MaskElement.prototype.getMaskProperty = function (pos) {
+  return this.viewData[pos].prop;
+};
+
+MaskElement.prototype.renderFrame = function (isFirstFrame) {
+  var finalMat = this.element.finalTransform.mat;
+  var i;
+  var len = this.masksProperties.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.viewData[i].prop._mdf || isFirstFrame) {
+      this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
+    }
+    if (this.viewData[i].op._mdf || isFirstFrame) {
+      this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
+    }
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
+        this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
+      }
+      if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
+        var feMorph = this.storedData[i].expan;
+        if (this.storedData[i].x.v < 0) {
+          if (this.storedData[i].lastOperator !== 'erode') {
+            this.storedData[i].lastOperator = 'erode';
+            this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
+          }
+          feMorph.setAttribute('radius', -this.storedData[i].x.v);
+        } else {
+          if (this.storedData[i].lastOperator !== 'dilate') {
+            this.storedData[i].lastOperator = 'dilate';
+            this.storedData[i].elem.setAttribute('filter', null);
+          }
+          this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
+        }
+      }
+    }
+  }
+};
+
+MaskElement.prototype.getMaskelement = function () {
+  return this.maskElement;
+};
+
+MaskElement.prototype.createLayerSolidPath = function () {
+  var path = 'M0,0 ';
+  path += ' h' + this.globalData.compSize.w;
+  path += ' v' + this.globalData.compSize.h;
+  path += ' h-' + this.globalData.compSize.w;
+  path += ' v-' + this.globalData.compSize.h + ' ';
+  return path;
+};
+
+MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
+  var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  var i;
+  var len;
+  len = pathNodes._length;
+  for (i = 1; i < len; i += 1) {
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
+  }
+  // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+  if (pathNodes.c && len > 1) {
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  }
+  // pathNodes.__renderedString = pathString;
+
+  if (viewData.lastPath !== pathString) {
+    var pathShapeValue = '';
+    if (viewData.elem) {
+      if (pathNodes.c) {
+        pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
+      }
+      viewData.elem.setAttribute('d', pathShapeValue);
+    }
+    viewData.lastPath = pathString;
+  }
+};
+
+MaskElement.prototype.destroy = function () {
+  this.element = null;
+  this.globalData = null;
+  this.maskElement = null;
+  this.data = null;
+  this.masksProperties = null;
+};
+
+const filtersFactory = (function () {
+  var ob = {};
+  ob.createFilter = createFilter;
+  ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
+
+  function createFilter(filId, skipCoordinates) {
+    var fil = createNS('filter');
+    fil.setAttribute('id', filId);
+    if (skipCoordinates !== true) {
+      fil.setAttribute('filterUnits', 'objectBoundingBox');
+      fil.setAttribute('x', '0%');
+      fil.setAttribute('y', '0%');
+      fil.setAttribute('width', '100%');
+      fil.setAttribute('height', '100%');
+    }
+    return fil;
+  }
+
+  function createAlphaToLuminanceFilter() {
+    var feColorMatrix = createNS('feColorMatrix');
+    feColorMatrix.setAttribute('type', 'matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+    feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
+    return feColorMatrix;
+  }
+
+  return ob;
+}());
+
+const featureSupport = (function () {
+  var ob = {
+    maskType: true,
+    svgLumaHidden: true,
+    offscreenCanvas: typeof OffscreenCanvas !== 'undefined',
+  };
+  if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
+    ob.maskType = false;
+  }
+  if (/firefox/i.test(navigator.userAgent)) {
+    ob.svgLumaHidden = false;
+  }
+  return ob;
+}());
+
+var registeredEffects$1 = {};
+var idPrefix = 'filter_result_';
+
+function SVGEffects(elem) {
+  var i;
+  var source = 'SourceGraphic';
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  var filId = createElementID();
+  var fil = filtersFactory.createFilter(filId, true);
+  var count = 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects$1[type]) {
+      var Effect = registeredEffects$1[type].effect;
+      filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
+      source = idPrefix + count;
+      if (registeredEffects$1[type].countsAsEffect) {
+        count += 1;
+      }
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (count) {
+    elem.globalData.defs.appendChild(fil);
+    elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+SVGEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect$1(id, effect, countsAsEffect) {
+  registeredEffects$1[id] = {
+    effect,
+    countsAsEffect,
+  };
+}
+
+function SVGBaseElement() {
+}
+
+SVGBaseElement.prototype = {
+  initRendererElement: function () {
+    this.layerElement = createNS('g');
+  },
+  createContainerElements: function () {
+    this.matteElement = createNS('g');
+    this.transformedElement = this.layerElement;
+    this.maskedElement = this.layerElement;
+    this._sizeChanged = false;
+    var layerElementParent = null;
+    // If this layer acts as a mask for the following layer
+    if (this.data.td) {
+      this.matteMasks = {};
+      var gg = createNS('g');
+      gg.setAttribute('id', this.layerId);
+      gg.appendChild(this.layerElement);
+      layerElementParent = gg;
+      this.globalData.defs.appendChild(gg);
+    } else if (this.data.tt) {
+      this.matteElement.appendChild(this.layerElement);
+      layerElementParent = this.matteElement;
+      this.baseElement = this.matteElement;
+    } else {
+      this.baseElement = this.layerElement;
+    }
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
+    if (this.data.ty === 0 && !this.data.hd) {
+      var cp = createNS('clipPath');
+      var pt = createNS('path');
+      pt.setAttribute('d', 'M0,0 L' + this.data.w + ',0 L' + this.data.w + ',' + this.data.h + ' L0,' + this.data.h + 'z');
+      var clipId = createElementID();
+      cp.setAttribute('id', clipId);
+      cp.appendChild(pt);
+      this.globalData.defs.appendChild(cp);
+
+      if (this.checkMasks()) {
+        var cpGroup = createNS('g');
+        cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+        cpGroup.appendChild(this.layerElement);
+        this.transformedElement = cpGroup;
+        if (layerElementParent) {
+          layerElementParent.appendChild(this.transformedElement);
+        } else {
+          this.baseElement = this.transformedElement;
+        }
+      } else {
+        this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+      }
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    if (this.finalTransform._localMatMdf) {
+      this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
+    }
+    if (this.finalTransform._opMdf) {
+      this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
+    }
+  },
+  destroyBaseElement: function () {
+    this.layerElement = null;
+    this.matteElement = null;
+    this.maskManager.destroy();
+  },
+  getBaseElement: function () {
+    if (this.data.hd) {
+      return null;
+    }
+    return this.baseElement;
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+    this.renderableEffectsManager = new SVGEffects(this);
+    this.searchEffectTransforms();
+  },
+  getMatte: function (matteType) {
+    // This should not be a common case. But for backward compatibility, we'll create the matte object.
+    // It solves animations that have two consecutive layers marked as matte masks.
+    // Which is an undefined behavior in AE.
+    if (!this.matteMasks) {
+      this.matteMasks = {};
+    }
+    if (!this.matteMasks[matteType]) {
+      var id = this.layerId + '_' + matteType;
+      var filId;
+      var fil;
+      var useElement;
+      var gg;
+      if (matteType === 1 || matteType === 3) {
+        var masker = createNS('mask');
+        masker.setAttribute('id', id);
+        masker.setAttribute('mask-type', matteType === 3 ? 'luminance' : 'alpha');
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        masker.appendChild(useElement);
+        this.globalData.defs.appendChild(masker);
+        if (!featureSupport.maskType && matteType === 1) {
+          masker.setAttribute('mask-type', 'luminance');
+          filId = createElementID();
+          fil = filtersFactory.createFilter(filId);
+          this.globalData.defs.appendChild(fil);
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          gg.appendChild(useElement);
+          masker.appendChild(gg);
+          gg.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        }
+      } else if (matteType === 2) {
+        var maskGroup = createNS('mask');
+        maskGroup.setAttribute('id', id);
+        maskGroup.setAttribute('mask-type', 'alpha');
+        var maskGrouper = createNS('g');
+        maskGroup.appendChild(maskGrouper);
+        filId = createElementID();
+        fil = filtersFactory.createFilter(filId);
+        /// /
+        var feCTr = createNS('feComponentTransfer');
+        feCTr.setAttribute('in', 'SourceGraphic');
+        fil.appendChild(feCTr);
+        var feFunc = createNS('feFuncA');
+        feFunc.setAttribute('type', 'table');
+        feFunc.setAttribute('tableValues', '1.0 0.0');
+        feCTr.appendChild(feFunc);
+        /// /
+        this.globalData.defs.appendChild(fil);
+        var alphaRect = createNS('rect');
+        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');
+        alphaRect.setAttribute('opacity', '0');
+        maskGrouper.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        maskGrouper.appendChild(alphaRect);
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        maskGrouper.appendChild(useElement);
+        if (!featureSupport.maskType) {
+          maskGroup.setAttribute('mask-type', 'luminance');
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          maskGrouper.appendChild(alphaRect);
+          gg.appendChild(this.layerElement);
+          maskGrouper.appendChild(gg);
+        }
+        this.globalData.defs.appendChild(maskGroup);
+      }
+      this.matteMasks[matteType] = id;
+    }
+    return this.matteMasks[matteType];
+  },
+  setMatte: function (id) {
+    if (!this.matteElement) {
+      return;
+    }
+    this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+  },
+};
+
+/**
+ * @file
+ * Handles AE's layer parenting property.
+ *
+ */
+
+function HierarchyElement() {}
+
+HierarchyElement.prototype = {
+  /**
+     * @function
+     * Initializes hierarchy properties
+     *
+     */
+  initHierarchy: function () {
+    // element's parent list
+    this.hierarchy = [];
+    // if element is parent of another layer _isParent will be true
+    this._isParent = false;
+    this.checkParenting();
+  },
+  /**
+     * @function
+     * Sets layer's hierarchy.
+     * @param {array} hierarch
+     * layer's parent list
+     *
+     */
+  setHierarchy: function (hierarchy) {
+    this.hierarchy = hierarchy;
+  },
+  /**
+     * @function
+     * Sets layer as parent.
+     *
+     */
+  setAsParent: function () {
+    this._isParent = true;
+  },
+  /**
+     * @function
+     * Searches layer's parenting chain
+     *
+     */
+  checkParenting: function () {
+    if (this.data.parent !== undefined) {
+      this.comp.buildElementParenting(this, this.data.parent, []);
+    }
+  },
+};
+
+function RenderableDOMElement() {}
+
+(function () {
+  var _prototype = {
+    initElement: function (data, globalData, comp) {
+      this.initFrame();
+      this.initBaseData(data, globalData, comp);
+      this.initTransform(data, globalData, comp);
+      this.initHierarchy();
+      this.initRenderable();
+      this.initRendererElement();
+      this.createContainerElements();
+      this.createRenderableComponents();
+      this.createContent();
+      this.hide();
+    },
+    hide: function () {
+      // console.log('HIDE', this);
+      if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+        var elem = this.baseElement || this.layerElement;
+        elem.style.display = 'none';
+        this.hidden = true;
+      }
+    },
+    show: function () {
+      // console.log('SHOW', this);
+      if (this.isInRange && !this.isTransparent) {
+        if (!this.data.hd) {
+          var elem = this.baseElement || this.layerElement;
+          elem.style.display = 'block';
+        }
+        this.hidden = false;
+        this._isFirstFrame = true;
+      }
+    },
+    renderFrame: function () {
+      // If it is exported as hidden (data.hd === true) no need to render
+      // If it is not visible no need to render
+      if (this.data.hd || this.hidden) {
+        return;
+      }
+      this.renderTransform();
+      this.renderRenderable();
+      this.renderLocalTransform();
+      this.renderElement();
+      this.renderInnerContent();
+      if (this._isFirstFrame) {
+        this._isFirstFrame = false;
+      }
+    },
+    renderInnerContent: function () {},
+    prepareFrame: function (num) {
+      this._mdf = false;
+      this.prepareRenderableFrame(num);
+      this.prepareProperties(num, this.isInRange);
+      this.checkTransparency();
+    },
+    destroy: function () {
+      this.innerElem = null;
+      this.destroyBaseElement();
+    },
+  };
+  extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement);
+}());
+
+function IImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  if (this.assetData && this.assetData.sid) {
+    this.assetData = globalData.slotManager.getProp(this.assetData);
+  }
+  this.initElement(data, globalData, comp);
+  this.sourceRect = {
+    top: 0, left: 0, width: this.assetData.w, height: this.assetData.h,
+  };
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
+
+IImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+
+  this.innerElem = createNS('image');
+  this.innerElem.setAttribute('width', this.assetData.w + 'px');
+  this.innerElem.setAttribute('height', this.assetData.h + 'px');
+  this.innerElem.setAttribute('preserveAspectRatio', this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio);
+  this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+
+  this.layerElement.appendChild(this.innerElem);
+};
+
+IImageElement.prototype.sourceRectAtTime = function () {
+  return this.sourceRect;
+};
+
+function ProcessedElement(element, position) {
+  this.elem = element;
+  this.pos = position;
+}
+
+function IShapeElement() {
+}
+
+IShapeElement.prototype = {
+  addShapeToModifiers: function (data) {
+    var i;
+    var len = this.shapeModifiers.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapeModifiers[i].addShape(data);
+    }
+  },
+  isShapeInAnimatedModifiers: function (data) {
+    var i = 0;
+    var len = this.shapeModifiers.length;
+    while (i < len) {
+      if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
+        return true;
+      }
+    }
+    return false;
+  },
+  renderModifiers: function () {
+    if (!this.shapeModifiers.length) {
+      return;
+    }
+    var i;
+    var len = this.shapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].sh.reset();
+    }
+
+    len = this.shapeModifiers.length;
+    var shouldBreakProcess;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+      // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+      // TODO: find a better solution for this
+      if (shouldBreakProcess) {
+        break;
+      }
+    }
+  },
+
+  searchProcessedElement: function (elem) {
+    var elements = this.processedElements;
+    var i = 0;
+    var len = elements.length;
+    while (i < len) {
+      if (elements[i].elem === elem) {
+        return elements[i].pos;
+      }
+      i += 1;
+    }
+    return 0;
+  },
+  addProcessedElement: function (elem, pos) {
+    var elements = this.processedElements;
+    var i = elements.length;
+    while (i) {
+      i -= 1;
+      if (elements[i].elem === elem) {
+        elements[i].pos = pos;
+        return;
+      }
+    }
+    elements.push(new ProcessedElement(elem, pos));
+  },
+  prepareFrame: function (num) {
+    this.prepareRenderableFrame(num);
+    this.prepareProperties(num, this.isInRange);
+  },
+};
+
+const lineCapEnum = {
+  1: 'butt',
+  2: 'round',
+  3: 'square',
+};
+
+const lineJoinEnum = {
+  1: 'miter',
+  2: 'round',
+  3: 'bevel',
+};
+
+function SVGShapeData(transformers, level, shape) {
+  this.caches = [];
+  this.styles = [];
+  this.transformers = transformers;
+  this.lStr = '';
+  this.sh = shape;
+  this.lvl = level;
+  // TODO find if there are some cases where _isAnimated can be false.
+  // For now, since shapes add up with other shapes. They have to be calculated every time.
+  // One way of finding out is checking if all styles associated to this shape depend only of this shape
+  this._isAnimated = !!shape.k;
+  // TODO: commenting this for now since all shapes are animated
+  var i = 0;
+  var len = transformers.length;
+  while (i < len) {
+    if (transformers[i].mProps.dynamicProperties.length) {
+      this._isAnimated = true;
+      break;
+    }
+    i += 1;
+  }
+}
+
+SVGShapeData.prototype.setAsAnimated = function () {
+  this._isAnimated = true;
+};
+
+function SVGStyleData(data, level) {
+  this.data = data;
+  this.type = data.ty;
+  this.d = '';
+  this.lvl = level;
+  this._mdf = false;
+  this.closed = data.hd === true;
+  this.pElem = createNS('path');
+  this.msElem = null;
+}
+
+SVGStyleData.prototype.reset = function () {
+  this.d = '';
+  this._mdf = false;
+};
+
+function DashProperty(elem, data, renderer, container) {
+  this.elem = elem;
+  this.frameId = -1;
+  this.dataProps = createSizedArray(data.length);
+  this.renderer = renderer;
+  this.k = false;
+  this.dashStr = '';
+  this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0);
+  this.dashoffset = createTypedArray('float32', 1);
+  this.initDynamicPropertyContainer(container);
+  var i;
+  var len = data.length || 0;
+  var prop;
+  for (i = 0; i < len; i += 1) {
+    prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
+    this.k = prop.k || this.k;
+    this.dataProps[i] = { n: data[i].n, p: prop };
+  }
+  if (!this.k) {
+    this.getValue(true);
+  }
+  this._isAnimated = this.k;
+}
+
+DashProperty.prototype.getValue = function (forceRender) {
+  if (this.elem.globalData.frameId === this.frameId && !forceRender) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+  this._mdf = this._mdf || forceRender;
+  if (this._mdf) {
+    var i = 0;
+    var len = this.dataProps.length;
+    if (this.renderer === 'svg') {
+      this.dashStr = '';
+    }
+    for (i = 0; i < len; i += 1) {
+      if (this.dataProps[i].n !== 'o') {
+        if (this.renderer === 'svg') {
+          this.dashStr += ' ' + this.dataProps[i].p.v;
+        } else {
+          this.dashArray[i] = this.dataProps[i].p.v;
+        }
+      } else {
+        this.dashoffset[0] = this.dataProps[i].p.v;
+      }
+    }
+  }
+};
+extendPrototype([DynamicPropertyContainer], DashProperty);
+
+function SVGStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
+
+function SVGFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
+
+function SVGNoStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
+
+function GradientProperty(elem, data, container) {
+  this.data = data;
+  this.c = createTypedArray('uint8c', data.p * 4);
+  var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p * 4) : data.k.k.length - data.p * 4;
+  this.o = createTypedArray('float32', cLength);
+  this._cmdf = false;
+  this._omdf = false;
+  this._collapsable = this.checkCollapsable();
+  this._hasOpacity = cLength;
+  this.initDynamicPropertyContainer(container);
+  this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this);
+  this.k = this.prop.k;
+  this.getValue(true);
+}
+
+GradientProperty.prototype.comparePoints = function (values, points) {
+  var i = 0;
+  var len = this.o.length / 2;
+  var diff;
+  while (i < len) {
+    diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
+    if (diff > 0.01) {
+      return false;
+    }
+    i += 1;
+  }
+  return true;
+};
+
+GradientProperty.prototype.checkCollapsable = function () {
+  if (this.o.length / 2 !== this.c.length / 4) {
+    return false;
+  }
+  if (this.data.k.k[0].s) {
+    var i = 0;
+    var len = this.data.k.k.length;
+    while (i < len) {
+      if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
+        return false;
+      }
+      i += 1;
+    }
+  } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
+    return false;
+  }
+  return true;
+};
+
+GradientProperty.prototype.getValue = function (forceRender) {
+  this.prop.getValue();
+  this._mdf = false;
+  this._cmdf = false;
+  this._omdf = false;
+  if (this.prop._mdf || forceRender) {
+    var i;
+    var len = this.data.p * 4;
+    var mult;
+    var val;
+    for (i = 0; i < len; i += 1) {
+      mult = i % 4 === 0 ? 100 : 255;
+      val = Math.round(this.prop.v[i] * mult);
+      if (this.c[i] !== val) {
+        this.c[i] = val;
+        this._cmdf = !forceRender;
+      }
+    }
+    if (this.o.length) {
+      len = this.prop.v.length;
+      for (i = this.data.p * 4; i < len; i += 1) {
+        mult = i % 2 === 0 ? 100 : 1;
+        val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
+        if (this.o[i - this.data.p * 4] !== val) {
+          this.o[i - this.data.p * 4] = val;
+          this._omdf = !forceRender;
+        }
+      }
+    }
+    this._mdf = !forceRender;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], GradientProperty);
+
+function SVGGradientFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.initGradientData(elem, data, styleOb);
+}
+
+SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 1, null, this);
+  this.h = PropertyFactory.getProp(elem, data.h || { k: 0 }, 0, 0.01, this);
+  this.a = PropertyFactory.getProp(elem, data.a || { k: 0 }, 0, degToRads, this);
+  this.g = new GradientProperty(elem, data.g, this);
+  this.style = styleOb;
+  this.stops = [];
+  this.setGradientData(styleOb.pElem, data);
+  this.setGradientOpacity(data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+};
+
+SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
+  var gradientId = createElementID();
+  var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+  gfill.setAttribute('id', gradientId);
+  gfill.setAttribute('spreadMethod', 'pad');
+  gfill.setAttribute('gradientUnits', 'userSpaceOnUse');
+  var stops = [];
+  var stop;
+  var j;
+  var jLen;
+  jLen = data.g.p * 4;
+  for (j = 0; j < jLen; j += 4) {
+    stop = createNS('stop');
+    gfill.appendChild(stop);
+    stops.push(stop);
+  }
+  pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
+  this.gf = gfill;
+  this.cst = stops;
+};
+
+SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
+  if (this.g._hasOpacity && !this.g._collapsable) {
+    var stop;
+    var j;
+    var jLen;
+    var mask = createNS('mask');
+    var maskElement = createNS('path');
+    mask.appendChild(maskElement);
+    var opacityId = createElementID();
+    var maskId = createElementID();
+    mask.setAttribute('id', maskId);
+    var opFill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+    opFill.setAttribute('id', opacityId);
+    opFill.setAttribute('spreadMethod', 'pad');
+    opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
+    jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
+    var stops = this.stops;
+    for (j = data.g.p * 4; j < jLen; j += 2) {
+      stop = createNS('stop');
+      stop.setAttribute('stop-color', 'rgb(255,255,255)');
+      opFill.appendChild(stop);
+      stops.push(stop);
+    }
+    maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
+    this.maskId = maskId;
+    styleOb.msElem = maskElement;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
+
+function SVGGradientStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.initGradientData(elem, data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
+
+function ShapeGroupData() {
+  this.it = [];
+  this.prevViewData = [];
+  this.gr = createNS('g');
+}
+
+function SVGTransformData(mProps, op, container) {
+  this.transform = {
+    mProps: mProps,
+    op: op,
+    container: container,
+  };
+  this.elements = [];
+  this._isAnimated = this.transform.mProps.dynamicProperties.length || this.transform.op.effectsSequence.length;
+}
+
+const buildShapeString = function (pathNodes, length, closed, mat) {
+  if (length === 0) {
+    return '';
+  }
+  var _o = pathNodes.o;
+  var _i = pathNodes.i;
+  var _v = pathNodes.v;
+  var i;
+  var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+  for (i = 1; i < length; i += 1) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
+  }
+  if (closed && length) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+    shapeString += 'z';
+  }
+  return shapeString;
+};
+
+const SVGElementsRenderer = (function () {
+  var _identityMatrix = new Matrix();
+  var _matrixHelper = new Matrix();
+
+  var ob = {
+    createRenderFunction: createRenderFunction,
+  };
+
+  function createRenderFunction(data) {
+    switch (data.ty) {
+      case 'fl':
+        return renderFill;
+      case 'gf':
+        return renderGradient;
+      case 'gs':
+        return renderGradientStroke;
+      case 'st':
+        return renderStroke;
+      case 'sh':
+      case 'el':
+      case 'rc':
+      case 'sr':
+        return renderPath;
+      case 'tr':
+        return renderContentTransform;
+      case 'no':
+        return renderNoop;
+      default:
+        return null;
+    }
+  }
+
+  function renderContentTransform(styleData, itemData, isFirstFrame) {
+    if (isFirstFrame || itemData.transform.op._mdf) {
+      itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
+    }
+    if (isFirstFrame || itemData.transform.mProps._mdf) {
+      itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
+    }
+  }
+
+  function renderNoop() {
+
+  }
+
+  function renderPath(styleData, itemData, isFirstFrame) {
+    var j;
+    var jLen;
+    var pathStringTransformed;
+    var redraw;
+    var pathNodes;
+    var l;
+    var lLen = itemData.styles.length;
+    var lvl = itemData.lvl;
+    var paths;
+    var mat;
+    var iterations;
+    var k;
+    for (l = 0; l < lLen; l += 1) {
+      redraw = itemData.sh._mdf || isFirstFrame;
+      if (itemData.styles[l].lvl < lvl) {
+        mat = _matrixHelper.reset();
+        iterations = lvl - itemData.styles[l].lvl;
+        k = itemData.transformers.length - 1;
+        while (!redraw && iterations > 0) {
+          redraw = itemData.transformers[k].mProps._mdf || redraw;
+          iterations -= 1;
+          k -= 1;
+        }
+        if (redraw) {
+          iterations = lvl - itemData.styles[l].lvl;
+          k = itemData.transformers.length - 1;
+          while (iterations > 0) {
+            mat.multiply(itemData.transformers[k].mProps.v);
+            iterations -= 1;
+            k -= 1;
+          }
+        }
+      } else {
+        mat = _identityMatrix;
+      }
+      paths = itemData.sh.paths;
+      jLen = paths._length;
+      if (redraw) {
+        pathStringTransformed = '';
+        for (j = 0; j < jLen; j += 1) {
+          pathNodes = paths.shapes[j];
+          if (pathNodes && pathNodes._length) {
+            pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
+          }
+        }
+        itemData.caches[l] = pathStringTransformed;
+      } else {
+        pathStringTransformed = itemData.caches[l];
+      }
+      itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
+      itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
+    }
+  }
+
+  function renderFill(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+
+    if (itemData.c._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
+    }
+  }
+
+  function renderGradientStroke(styleData, itemData, isFirstFrame) {
+    renderGradient(styleData, itemData, isFirstFrame);
+    renderStroke(styleData, itemData, isFirstFrame);
+  }
+
+  function renderGradient(styleData, itemData, isFirstFrame) {
+    var gfill = itemData.gf;
+    var hasOpacity = itemData.g._hasOpacity;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+
+    if (itemData.o._mdf || isFirstFrame) {
+      var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
+      itemData.style.pElem.setAttribute(attr, itemData.o.v);
+    }
+    if (itemData.s._mdf || isFirstFrame) {
+      var attr1 = styleData.t === 1 ? 'x1' : 'cx';
+      var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
+      gfill.setAttribute(attr1, pt1[0]);
+      gfill.setAttribute(attr2, pt1[1]);
+      if (hasOpacity && !itemData.g._collapsable) {
+        itemData.of.setAttribute(attr1, pt1[0]);
+        itemData.of.setAttribute(attr2, pt1[1]);
+      }
+    }
+    var stops;
+    var i;
+    var len;
+    var stop;
+    if (itemData.g._cmdf || isFirstFrame) {
+      stops = itemData.cst;
+      var cValues = itemData.g.c;
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        stop.setAttribute('offset', cValues[i * 4] + '%');
+        stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
+      }
+    }
+    if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
+      var oValues = itemData.g.o;
+      if (itemData.g._collapsable) {
+        stops = itemData.cst;
+      } else {
+        stops = itemData.ost;
+      }
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        if (!itemData.g._collapsable) {
+          stop.setAttribute('offset', oValues[i * 2] + '%');
+        }
+        stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
+      }
+    }
+    if (styleData.t === 1) {
+      if (itemData.e._mdf || isFirstFrame) {
+        gfill.setAttribute('x2', pt2[0]);
+        gfill.setAttribute('y2', pt2[1]);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('x2', pt2[0]);
+          itemData.of.setAttribute('y2', pt2[1]);
+        }
+      }
+    } else {
+      var rad;
+      if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
+        rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        gfill.setAttribute('r', rad);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('r', rad);
+        }
+      }
+      if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (!rad) {
+          rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        }
+        var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+        var percent = itemData.h.v;
+        if (percent >= 1) {
+          percent = 0.99;
+        } else if (percent <= -1) {
+          percent = -0.99;
+        }
+        var dist = rad * percent;
+        var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+        var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+        gfill.setAttribute('fx', x);
+        gfill.setAttribute('fy', y);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('fx', x);
+          itemData.of.setAttribute('fy', y);
+        }
+      }
+      // gfill.setAttribute('fy','200');
+    }
+  }
+
+  function renderStroke(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+    var d = itemData.d;
+    if (d && (d._mdf || isFirstFrame) && d.dashStr) {
+      styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
+      styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
+    }
+    if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
+      styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
+    }
+    if (itemData.w._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
+      if (styleElem.msElem) {
+        styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
+      }
+    }
+  }
+
+  return ob;
+}());
+
+function SVGShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
+
+SVGShapeElement.prototype.initSecondaryElement = function () {
+};
+
+SVGShapeElement.prototype.identityMatrix = new Matrix();
+
+SVGShapeElement.prototype.buildExpressionInterface = function () {};
+
+SVGShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+};
+
+/*
+This method searches for multiple shapes that affect a single element and one of them is animated
+*/
+SVGShapeElement.prototype.filterUniqueShapes = function () {
+  var i;
+  var len = this.shapes.length;
+  var shape;
+  var j;
+  var jLen = this.stylesList.length;
+  var style;
+  var tempShapes = [];
+  var areAnimated = false;
+  for (j = 0; j < jLen; j += 1) {
+    style = this.stylesList[j];
+    areAnimated = false;
+    tempShapes.length = 0;
+    for (i = 0; i < len; i += 1) {
+      shape = this.shapes[i];
+      if (shape.styles.indexOf(style) !== -1) {
+        tempShapes.push(shape);
+        areAnimated = shape._isAnimated || areAnimated;
+      }
+    }
+    if (tempShapes.length > 1 && areAnimated) {
+      this.setShapesAsAnimated(tempShapes);
+    }
+  }
+};
+
+SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
+  var i;
+  var len = shapes.length;
+  for (i = 0; i < len; i += 1) {
+    shapes[i].setAsAnimated();
+  }
+};
+
+SVGShapeElement.prototype.createStyleElement = function (data, level) {
+  // TODO: prevent drawing of hidden styles
+  var elementData;
+  var styleOb = new SVGStyleData(data, level);
+
+  var pathElement = styleOb.pElem;
+  if (data.ty === 'st') {
+    elementData = new SVGStrokeStyleData(this, data, styleOb);
+  } else if (data.ty === 'fl') {
+    elementData = new SVGFillStyleData(this, data, styleOb);
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
+    elementData = new GradientConstructor(this, data, styleOb);
+    this.globalData.defs.appendChild(elementData.gf);
+    if (elementData.maskId) {
+      this.globalData.defs.appendChild(elementData.ms);
+      this.globalData.defs.appendChild(elementData.of);
+      pathElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + elementData.maskId + ')');
+    }
+  } else if (data.ty === 'no') {
+    elementData = new SVGNoStyleData(this, data, styleOb);
+  }
+
+  if (data.ty === 'st' || data.ty === 'gs') {
+    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);
+    }
+  }
+
+  if (data.r === 2) {
+    pathElement.setAttribute('fill-rule', 'evenodd');
+  }
+
+  if (data.ln) {
+    pathElement.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    pathElement.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  this.stylesList.push(styleOb);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createGroupElement = function (data) {
+  var elementData = new ShapeGroupData();
+  if (data.ln) {
+    elementData.gr.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    elementData.gr.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  return elementData;
+};
+
+SVGShapeElement.prototype.createTransformElement = function (data, container) {
+  var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
+  var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
+  var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
+  var i = 0;
+  var len = this.animatedContents.length;
+  while (i < len) {
+    if (this.animatedContents[i].element === element) {
+      return;
+    }
+    i += 1;
+  }
+  this.animatedContents.push({
+    fn: SVGElementsRenderer.createRenderFunction(data),
+    element: element,
+    data: data,
+  });
+};
+
+SVGShapeElement.prototype.setElementStyles = function (elementData) {
+  var arr = elementData.styles;
+  var j;
+  var jLen = this.stylesList.length;
+  for (j = 0; j < jLen; j += 1) {
+    if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
+      arr.push(this.stylesList[j]);
+    }
+  }
+};
+
+SVGShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+};
+
+SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
+  var ownTransformers = [].concat(transformers);
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var currentTransform;
+  var modifier;
+  var processedPos;
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._render = render;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], level);
+      } else {
+        itemsData[i].style.closed = arr[i].hd;
+      }
+      if (arr[i]._render) {
+        if (itemsData[i].style.pElem.parentNode !== container) {
+          container.appendChild(itemsData[i].style.pElem);
+        }
+      }
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
+      if (arr[i]._render) {
+        if (itemsData[i].gr.parentNode !== container) {
+          container.appendChild(itemsData[i].gr);
+        }
+      }
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        itemsData[i] = this.createTransformElement(arr[i], container);
+      }
+      currentTransform = itemsData[i].transform;
+      ownTransformers.push(currentTransform);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
+      }
+      this.setElementStyles(itemsData[i]);
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        render = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  len = ownStyles.length;
+  for (i = 0; i < len; i += 1) {
+    ownStyles[i].closed = true;
+  }
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+SVGShapeElement.prototype.renderInnerContent = function () {
+  this.renderModifiers();
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    this.stylesList[i].reset();
+  }
+  this.renderShape();
+  for (i = 0; i < len; i += 1) {
+    if (this.stylesList[i]._mdf || this._isFirstFrame) {
+      if (this.stylesList[i].msElem) {
+        this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+        // Adding M0 0 fixes same mask bug on all browsers
+        this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
+      }
+      this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
+    }
+  }
+};
+
+SVGShapeElement.prototype.renderShape = function () {
+  var i;
+  var len = this.animatedContents.length;
+  var animatedContent;
+  for (i = 0; i < len; i += 1) {
+    animatedContent = this.animatedContents[i];
+    if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
+      animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
+    }
+  }
+};
+
+SVGShapeElement.prototype.destroy = function () {
+  this.destroyBaseElement();
+  this.shapesData = null;
+  this.itemsData = null;
+};
+
+function LetterProps(o, sw, sc, fc, m, p) {
+  this.o = o;
+  this.sw = sw;
+  this.sc = sc;
+  this.fc = fc;
+  this.m = m;
+  this.p = p;
+  this._mdf = {
+    o: true,
+    sw: !!sw,
+    sc: !!sc,
+    fc: !!fc,
+    m: true,
+    p: true,
+  };
+}
+
+LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
+  this._mdf.o = false;
+  this._mdf.sw = false;
+  this._mdf.sc = false;
+  this._mdf.fc = false;
+  this._mdf.m = false;
+  this._mdf.p = false;
+  var updated = false;
+
+  if (this.o !== o) {
+    this.o = o;
+    this._mdf.o = true;
+    updated = true;
+  }
+  if (this.sw !== sw) {
+    this.sw = sw;
+    this._mdf.sw = true;
+    updated = true;
+  }
+  if (this.sc !== sc) {
+    this.sc = sc;
+    this._mdf.sc = true;
+    updated = true;
+  }
+  if (this.fc !== fc) {
+    this.fc = fc;
+    this._mdf.fc = true;
+    updated = true;
+  }
+  if (this.m !== m) {
+    this.m = m;
+    this._mdf.m = true;
+    updated = true;
+  }
+  if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
+    this.p = p;
+    this._mdf.p = true;
+    updated = true;
+  }
+  return updated;
+};
+
+function TextProperty(elem, data) {
+  this._frameId = initialDefaultFrame;
+  this.pv = '';
+  this.v = '';
+  this.kf = false;
+  this._isFirstFrame = true;
+  this._mdf = false;
+  if (data.d && data.d.sid) {
+    data.d = elem.globalData.slotManager.getProp(data.d);
+  }
+  this.data = data;
+  this.elem = elem;
+  this.comp = this.elem.comp;
+  this.keysIndex = 0;
+  this.canResize = false;
+  this.minimumFontSize = 1;
+  this.effectsSequence = [];
+  this.currentData = {
+    ascent: 0,
+    boxWidth: this.defaultBoxWidth,
+    f: '',
+    fStyle: '',
+    fWeight: '',
+    fc: '',
+    j: '',
+    justifyOffset: '',
+    l: [],
+    lh: 0,
+    lineWidths: [],
+    ls: '',
+    of: '',
+    s: '',
+    sc: '',
+    sw: 0,
+    t: 0,
+    tr: 0,
+    sz: 0,
+    ps: null,
+    fillColorAnim: false,
+    strokeColorAnim: false,
+    strokeWidthAnim: false,
+    yOffset: 0,
+    finalSize: 0,
+    finalText: [],
+    finalLineHeight: 0,
+    __complete: false,
+
+  };
+  this.copyData(this.currentData, this.data.d.k[0].s);
+
+  if (!this.searchProperty()) {
+    this.completeTextData(this.currentData);
+  }
+}
+
+TextProperty.prototype.defaultBoxWidth = [0, 0];
+
+TextProperty.prototype.copyData = function (obj, data) {
+  for (var s in data) {
+    if (Object.prototype.hasOwnProperty.call(data, s)) {
+      obj[s] = data[s];
+    }
+  }
+  return obj;
+};
+
+TextProperty.prototype.setCurrentData = function (data) {
+  if (!data.__complete) {
+    this.completeTextData(data);
+  }
+  this.currentData = data;
+  this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
+  this._mdf = true;
+};
+
+TextProperty.prototype.searchProperty = function () {
+  return this.searchKeyframes();
+};
+
+TextProperty.prototype.searchKeyframes = function () {
+  this.kf = this.data.d.k.length > 1;
+  if (this.kf) {
+    this.addEffect(this.getKeyframeValue.bind(this));
+  }
+  return this.kf;
+};
+
+TextProperty.prototype.addEffect = function (effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.getValue = function (_finalValue) {
+  if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
+    return;
+  }
+  this.currentData.t = this.data.d.k[this.keysIndex].s.t;
+  var currentValue = this.currentData;
+  var currentIndex = this.keysIndex;
+  if (this.lock) {
+    this.setCurrentData(this.currentData);
+    return;
+  }
+  this.lock = true;
+  this._mdf = false;
+  var i; var
+    len = this.effectsSequence.length;
+  var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
+  for (i = 0; i < len; i += 1) {
+    // Checking if index changed to prevent creating a new object every time the expression updates.
+    if (currentIndex !== this.keysIndex) {
+      finalValue = this.effectsSequence[i](finalValue, finalValue.t);
+    } else {
+      finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
+    }
+  }
+  if (currentValue !== finalValue) {
+    this.setCurrentData(finalValue);
+  }
+  this.v = this.currentData;
+  this.pv = this.v;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+};
+
+TextProperty.prototype.getKeyframeValue = function () {
+  var textKeys = this.data.d.k;
+  var frameNum = this.elem.comp.renderedFrame;
+  var i = 0; var
+    len = textKeys.length;
+  while (i <= len - 1) {
+    if (i === len - 1 || textKeys[i + 1].t > frameNum) {
+      break;
+    }
+    i += 1;
+  }
+  if (this.keysIndex !== i) {
+    this.keysIndex = i;
+  }
+  return this.data.d.k[this.keysIndex].s;
+};
+
+TextProperty.prototype.buildFinalText = function (text) {
+  var charactersArray = [];
+  var i = 0;
+  var len = text.length;
+  var charCode;
+  var secondCharCode;
+  var shouldCombine = false;
+  var shouldCombineNext = false;
+  var currentChars = '';
+  while (i < len) {
+    shouldCombine = shouldCombineNext;
+    shouldCombineNext = false;
+    charCode = text.charCodeAt(i);
+    currentChars = text.charAt(i);
+    if (FontManager.isCombinedCharacter(charCode)) {
+      shouldCombine = true;
+      // It's a potential surrogate pair (this is the High surrogate)
+    } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+      if (FontManager.isRegionalFlag(text, i)) {
+        currentChars = text.substr(i, 14);
+      } else {
+        secondCharCode = text.charCodeAt(i + 1);
+        // It's a surrogate pair (this is the Low surrogate)
+        if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
+          if (FontManager.isModifier(charCode, secondCharCode)) {
+            currentChars = text.substr(i, 2);
+            shouldCombine = true;
+          } else if (FontManager.isFlagEmoji(text.substr(i, 4))) {
+            currentChars = text.substr(i, 4);
+          } else {
+            currentChars = text.substr(i, 2);
+          }
+        }
+      }
+    } else if (charCode > 0xDBFF) {
+      secondCharCode = text.charCodeAt(i + 1);
+      if (FontManager.isVariationSelector(charCode)) {
+        shouldCombine = true;
+      }
+    } else if (FontManager.isZeroWidthJoiner(charCode)) {
+      shouldCombine = true;
+      shouldCombineNext = true;
+    }
+    if (shouldCombine) {
+      charactersArray[charactersArray.length - 1] += currentChars;
+      shouldCombine = false;
+    } else {
+      charactersArray.push(currentChars);
+    }
+    i += currentChars.length;
+  }
+  return charactersArray;
+};
+
+TextProperty.prototype.completeTextData = function (documentData) {
+  documentData.__complete = true;
+  var fontManager = this.elem.globalData.fontManager;
+  var data = this.data;
+  var letters = [];
+  var i; var
+    len;
+  var newLineFlag; var index = 0; var
+    val;
+  var anchorGrouping = data.m.g;
+  var currentSize = 0; var currentPos = 0; var currentLine = 0; var
+    lineWidths = [];
+  var lineWidth = 0;
+  var maxLineWidth = 0;
+  var j; var
+    jLen;
+  var fontData = fontManager.getFontByName(documentData.f);
+  var charData; var
+    cLength = 0;
+
+  var fontProps = getFontProperties(fontData);
+  documentData.fWeight = fontProps.weight;
+  documentData.fStyle = fontProps.style;
+  documentData.finalSize = documentData.s;
+  documentData.finalText = this.buildFinalText(documentData.t);
+  len = documentData.finalText.length;
+  documentData.finalLineHeight = documentData.lh;
+  var trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+  var charCode;
+  if (documentData.sz) {
+    var flag = true;
+    var boxWidth = documentData.sz[0];
+    var boxHeight = documentData.sz[1];
+    var currentHeight; var
+      finalText;
+    while (flag) {
+      finalText = this.buildFinalText(documentData.t);
+      currentHeight = 0;
+      lineWidth = 0;
+      len = finalText.length;
+      trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+      var lastSpaceIndex = -1;
+      for (i = 0; i < len; i += 1) {
+        charCode = finalText[i].charCodeAt(0);
+        newLineFlag = false;
+        if (finalText[i] === ' ') {
+          lastSpaceIndex = i;
+        } else if (charCode === 13 || charCode === 3) {
+          lineWidth = 0;
+          newLineFlag = true;
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+        }
+        if (fontManager.chars) {
+          charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
+          cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+        } else {
+          // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
+          cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
+        }
+        if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
+          if (lastSpaceIndex === -1) {
+            len += 1;
+          } else {
+            i = lastSpaceIndex;
+          }
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+          finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+          // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
+          lastSpaceIndex = -1;
+          lineWidth = 0;
+        } else {
+          lineWidth += cLength;
+          lineWidth += trackingOffset;
+        }
+      }
+      currentHeight += (fontData.ascent * documentData.finalSize) / 100;
+      if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
+        documentData.finalSize -= 1;
+        documentData.finalLineHeight = (documentData.finalSize * documentData.lh) / documentData.s;
+      } else {
+        documentData.finalText = finalText;
+        len = documentData.finalText.length;
+        flag = false;
+      }
+    }
+  }
+  lineWidth = -trackingOffset;
+  cLength = 0;
+  var uncollapsedSpaces = 0;
+  var currentChar;
+  for (i = 0; i < len; i += 1) {
+    newLineFlag = false;
+    currentChar = documentData.finalText[i];
+    charCode = currentChar.charCodeAt(0);
+    if (charCode === 13 || charCode === 3) {
+      uncollapsedSpaces = 0;
+      lineWidths.push(lineWidth);
+      maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+      lineWidth = -2 * trackingOffset;
+      val = '';
+      newLineFlag = true;
+      currentLine += 1;
+    } else {
+      val = currentChar;
+    }
+    if (fontManager.chars) {
+      charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
+      cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+    } else {
+      // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
+      // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
+      cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
+    }
+
+    //
+    if (currentChar === ' ') {
+      uncollapsedSpaces += cLength + trackingOffset;
+    } else {
+      lineWidth += cLength + trackingOffset + uncollapsedSpaces;
+      uncollapsedSpaces = 0;
+    }
+    letters.push({
+      l: cLength, an: cLength, add: currentSize, n: newLineFlag, anIndexes: [], val: val, line: currentLine, animatorJustifyOffset: 0,
+    });
+    if (anchorGrouping == 2) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || val === ' ' || i === len - 1) {
+        if (val === '' || val === ' ') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        index += 1;
+        currentSize = 0;
+      }
+    } else if (anchorGrouping == 3) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || i === len - 1) {
+        if (val === '') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        currentSize = 0;
+        index += 1;
+      }
+    } else {
+      letters[index].ind = index;
+      letters[index].extra = 0;
+      index += 1;
+    }
+  }
+  documentData.l = letters;
+  maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+  lineWidths.push(lineWidth);
+  if (documentData.sz) {
+    documentData.boxWidth = documentData.sz[0];
+    documentData.justifyOffset = 0;
+  } else {
+    documentData.boxWidth = maxLineWidth;
+    switch (documentData.j) {
+      case 1:
+        documentData.justifyOffset = -documentData.boxWidth;
+        break;
+      case 2:
+        documentData.justifyOffset = -documentData.boxWidth / 2;
+        break;
+      default:
+        documentData.justifyOffset = 0;
+    }
+  }
+  documentData.lineWidths = lineWidths;
+
+  var animators = data.a; var animatorData; var
+    letterData;
+  jLen = animators.length;
+  var based; var ind; var
+    indexes = [];
+  for (j = 0; j < jLen; j += 1) {
+    animatorData = animators[j];
+    if (animatorData.a.sc) {
+      documentData.strokeColorAnim = true;
+    }
+    if (animatorData.a.sw) {
+      documentData.strokeWidthAnim = true;
+    }
+    if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
+      documentData.fillColorAnim = true;
+    }
+    ind = 0;
+    based = animatorData.s.b;
+    for (i = 0; i < len; i += 1) {
+      letterData = letters[i];
+      letterData.anIndexes[j] = ind;
+      if ((based == 1 && letterData.val !== '') || (based == 2 && letterData.val !== '' && letterData.val !== ' ') || (based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1)) || (based == 4 && (letterData.n || i == len - 1))) { // eslint-disable-line eqeqeq
+        if (animatorData.s.rn === 1) {
+          indexes.push(ind);
+        }
+        ind += 1;
+      }
+    }
+    data.a[j].s.totalChars = ind;
+    var currentInd = -1; var
+      newInd;
+    if (animatorData.s.rn === 1) {
+      for (i = 0; i < len; i += 1) {
+        letterData = letters[i];
+        if (currentInd != letterData.anIndexes[j]) { // eslint-disable-line eqeqeq
+          currentInd = letterData.anIndexes[j];
+          newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
+        }
+        letterData.anIndexes[j] = newInd;
+      }
+    }
+  }
+  documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
+  documentData.ls = documentData.ls || 0;
+  documentData.ascent = (fontData.ascent * documentData.finalSize) / 100;
+};
+
+TextProperty.prototype.updateDocumentData = function (newData, index) {
+  index = index === undefined ? this.keysIndex : index;
+  var dData = this.copyData({}, this.data.d.k[index].s);
+  dData = this.copyData(dData, newData);
+  this.data.d.k[index].s = dData;
+  this.recalculate(index);
+  this.setCurrentData(dData);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.recalculate = function (index) {
+  var dData = this.data.d.k[index].s;
+  dData.__complete = false;
+  this.keysIndex = 0;
+  this._isFirstFrame = true;
+  this.getValue(dData);
+};
+
+TextProperty.prototype.canResizeFont = function (_canResize) {
+  this.canResize = _canResize;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
+  this.minimumFontSize = Math.floor(_fontValue) || 1;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+const TextSelectorProp = (function () {
+  var max = Math.max;
+  var min = Math.min;
+  var floor = Math.floor;
+
+  function TextSelectorPropFactory(elem, data) {
+    this._currentTextLength = -1;
+    this.k = false;
+    this.data = data;
+    this.elem = elem;
+    this.comp = elem.comp;
+    this.finalS = 0;
+    this.finalE = 0;
+    this.initDynamicPropertyContainer(elem);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: 0 }, 0, 0, this);
+    if ('e' in data) {
+      this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
+    } else {
+      this.e = { v: 100 };
+    }
+    this.o = PropertyFactory.getProp(elem, data.o || { k: 0 }, 0, 0, this);
+    this.xe = PropertyFactory.getProp(elem, data.xe || { k: 0 }, 0, 0, this);
+    this.ne = PropertyFactory.getProp(elem, data.ne || { k: 0 }, 0, 0, this);
+    this.sm = PropertyFactory.getProp(elem, data.sm || { k: 100 }, 0, 0, this);
+    this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
+    if (!this.dynamicProperties.length) {
+      this.getValue();
+    }
+  }
+
+  TextSelectorPropFactory.prototype = {
+    getMult: function (ind) {
+      if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
+        this.getValue();
+      }
+      var x1 = 0;
+      var y1 = 0;
+      var x2 = 1;
+      var y2 = 1;
+      if (this.ne.v > 0) {
+        x1 = this.ne.v / 100.0;
+      } else {
+        y1 = -this.ne.v / 100.0;
+      }
+      if (this.xe.v > 0) {
+        x2 = 1.0 - this.xe.v / 100.0;
+      } else {
+        y2 = 1.0 + this.xe.v / 100.0;
+      }
+      var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
+
+      var mult = 0;
+      var s = this.finalS;
+      var e = this.finalE;
+      var type = this.data.sh;
+      if (type === 2) {
+        if (e === s) {
+          mult = ind >= e ? 1 : 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+        mult = easer(mult);
+      } else if (type === 3) {
+        if (e === s) {
+          mult = ind >= e ? 0 : 1;
+        } else {
+          mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+
+        mult = easer(mult);
+      } else if (type === 4) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+          if (mult < 0.5) {
+            mult *= 2;
+          } else {
+            mult = 1 - 2 * (mult - 0.5);
+          }
+        }
+        mult = easer(mult);
+      } else if (type === 5) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          var tot = e - s;
+          /* ind += 0.5;
+                    mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          var x = -tot / 2 + ind;
+          var a = tot / 2;
+          mult = Math.sqrt(1 - (x * x) / (a * a));
+        }
+        mult = easer(mult);
+      } else if (type === 6) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; // eslint-disable-line
+        }
+        mult = easer(mult);
+      } else {
+        if (ind >= floor(s)) {
+          if (ind - s < 0) {
+            mult = max(0, min(min(e, 1) - (s - ind), 1));
+          } else {
+            mult = max(0, min(e - ind, 1));
+          }
+        }
+        mult = easer(mult);
+      }
+      // Smoothness implementation.
+      // The smoothness represents a reduced range of the original [0; 1] range.
+      // if smoothness is 25%, the new range will be [0.375; 0.625]
+      // Steps are:
+      // - find the lower value of the new range (threshold)
+      // - if multiplier is smaller than that value, floor it to 0
+      // - if it is larger,
+      //     - subtract the threshold
+      //     - divide it by the smoothness (this will return the range to [0; 1])
+      // Note: If it doesn't work on some scenarios, consider applying it before the easer.
+      if (this.sm.v !== 100) {
+        var smoothness = this.sm.v * 0.01;
+        if (smoothness === 0) {
+          smoothness = 0.00000001;
+        }
+        var threshold = 0.5 - smoothness * 0.5;
+        if (mult < threshold) {
+          mult = 0;
+        } else {
+          mult = (mult - threshold) / smoothness;
+          if (mult > 1) {
+            mult = 1;
+          }
+        }
+      }
+      return mult * this.a.v;
+    },
+    getValue: function (newCharsFlag) {
+      this.iterateDynamicProperties();
+      this._mdf = newCharsFlag || this._mdf;
+      this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
+      if (newCharsFlag && this.data.r === 2) {
+        this.e.v = this._currentTextLength;
+      }
+      var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
+      var o = this.o.v / divisor;
+      var s = this.s.v / divisor + o;
+      var e = (this.e.v / divisor) + o;
+      if (s > e) {
+        var _s = s;
+        s = e;
+        e = _s;
+      }
+      this.finalS = s;
+      this.finalE = e;
+    },
+  };
+  extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
+
+  function getTextSelectorProp(elem, data, arr) {
+    return new TextSelectorPropFactory(elem, data, arr);
+  }
+
+  return {
+    getTextSelectorProp: getTextSelectorProp,
+  };
+}());
+
+function TextAnimatorDataProperty(elem, animatorProps, container) {
+  var defaultData = { propType: false };
+  var getProp = PropertyFactory.getProp;
+  var textAnimatorAnimatables = animatorProps.a;
+  this.a = {
+    r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData,
+    rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData,
+    ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData,
+    sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData,
+    sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData,
+    s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData,
+    a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData,
+    o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData,
+    p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData,
+    sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData,
+    sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData,
+    fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData,
+    fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData,
+    fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData,
+    fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData,
+    t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData,
+  };
+
+  this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container);
+  this.s.t = animatorProps.s.t;
+}
+
+function TextAnimatorProperty(textData, renderType, elem) {
+  this._isFirstFrame = true;
+  this._hasMaskedPath = false;
+  this._frameId = -1;
+  this._textData = textData;
+  this._renderType = renderType;
+  this._elem = elem;
+  this._animatorsData = createSizedArray(this._textData.a.length);
+  this._pathData = {};
+  this._moreOptions = {
+    alignment: {},
+  };
+  this.renderedLetters = [];
+  this.lettersChangedFlag = false;
+  this.initDynamicPropertyContainer(elem);
+}
+
+TextAnimatorProperty.prototype.searchProperties = function () {
+  var i;
+  var len = this._textData.a.length;
+  var animatorProps;
+  var getProp = PropertyFactory.getProp;
+  for (i = 0; i < len; i += 1) {
+    animatorProps = this._textData.a[i];
+    this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
+  }
+  if (this._textData.p && 'm' in this._textData.p) {
+    this._pathData = {
+      a: getProp(this._elem, this._textData.p.a, 0, 0, this),
+      f: getProp(this._elem, this._textData.p.f, 0, 0, this),
+      l: getProp(this._elem, this._textData.p.l, 0, 0, this),
+      r: getProp(this._elem, this._textData.p.r, 0, 0, this),
+      p: getProp(this._elem, this._textData.p.p, 0, 0, this),
+      m: this._elem.maskManager.getMaskProperty(this._textData.p.m),
+    };
+    this._hasMaskedPath = true;
+  } else {
+    this._hasMaskedPath = false;
+  }
+  this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
+};
+
+TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
+  this.lettersChangedFlag = lettersChangedFlag;
+  if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
+    return;
+  }
+  this._isFirstFrame = false;
+  var alignment = this._moreOptions.alignment.v;
+  var animators = this._animatorsData;
+  var textData = this._textData;
+  var matrixHelper = this.mHelper;
+  var renderType = this._renderType;
+  var renderedLettersCount = this.renderedLetters.length;
+  var xPos;
+  var yPos;
+  var i;
+  var len;
+  var letters = documentData.l;
+  var pathInfo;
+  var currentLength;
+  var currentPoint;
+  var segmentLength;
+  var flag;
+  var pointInd;
+  var segmentInd;
+  var prevPoint;
+  var points;
+  var segments;
+  var partialLength;
+  var totalLength;
+  var perc;
+  var tanAngle;
+  var mask;
+  if (this._hasMaskedPath) {
+    mask = this._pathData.m;
+    if (!this._pathData.n || this._pathData._mdf) {
+      var paths = mask.v;
+      if (this._pathData.r.v) {
+        paths = paths.reverse();
+      }
+      // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
+      pathInfo = {
+        tLength: 0,
+        segments: [],
+      };
+      len = paths._length - 1;
+      var bezierData;
+      totalLength = 0;
+      for (i = 0; i < len; i += 1) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[i + 1],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      i = len;
+      if (mask.v.c) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[0],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      this._pathData.pi = pathInfo;
+    }
+    pathInfo = this._pathData.pi;
+
+    currentLength = this._pathData.f.v;
+    segmentInd = 0;
+    pointInd = 1;
+    segmentLength = 0;
+    flag = true;
+    segments = pathInfo.segments;
+    if (currentLength < 0 && mask.v.c) {
+      if (pathInfo.tLength < Math.abs(currentLength)) {
+        currentLength = -Math.abs(currentLength) % pathInfo.tLength;
+      }
+      segmentInd = segments.length - 1;
+      points = segments[segmentInd].points;
+      pointInd = points.length - 1;
+      while (currentLength < 0) {
+        currentLength += points[pointInd].partialLength;
+        pointInd -= 1;
+        if (pointInd < 0) {
+          segmentInd -= 1;
+          points = segments[segmentInd].points;
+          pointInd = points.length - 1;
+        }
+      }
+    }
+    points = segments[segmentInd].points;
+    prevPoint = points[pointInd - 1];
+    currentPoint = points[pointInd];
+    partialLength = currentPoint.partialLength;
+  }
+
+  len = letters.length;
+  xPos = 0;
+  yPos = 0;
+  var yOff = documentData.finalSize * 1.2 * 0.714;
+  var firstLine = true;
+  var animatorProps;
+  var animatorSelector;
+  var j;
+  var jLen;
+  var letterValue;
+
+  jLen = animators.length;
+
+  var mult;
+  var ind = -1;
+  var offf;
+  var xPathPos;
+  var yPathPos;
+  var initPathPos = currentLength;
+  var initSegmentInd = segmentInd;
+  var initPointInd = pointInd;
+  var currentLine = -1;
+  var elemOpacity;
+  var sc;
+  var sw;
+  var fc;
+  var k;
+  var letterSw;
+  var letterSc;
+  var letterFc;
+  var letterM = '';
+  var letterP = this.defaultPropsArray;
+  var letterO;
+
+  //
+  if (documentData.j === 2 || documentData.j === 1) {
+    var animatorJustifyOffset = 0;
+    var animatorFirstCharOffset = 0;
+    var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
+    var lastIndex = 0;
+    var isNewLine = true;
+
+    for (i = 0; i < len; i += 1) {
+      if (letters[i].n) {
+        if (animatorJustifyOffset) {
+          animatorJustifyOffset += animatorFirstCharOffset;
+        }
+        while (lastIndex < i) {
+          letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+          lastIndex += 1;
+        }
+        animatorJustifyOffset = 0;
+        isNewLine = true;
+      } else {
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.t.propType) {
+            if (isNewLine && documentData.j === 2) {
+              animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
+            }
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
+            } else {
+              animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult;
+            }
+          }
+        }
+        isNewLine = false;
+      }
+    }
+    if (animatorJustifyOffset) {
+      animatorJustifyOffset += animatorFirstCharOffset;
+    }
+    while (lastIndex < i) {
+      letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+      lastIndex += 1;
+    }
+  }
+  //
+
+  for (i = 0; i < len; i += 1) {
+    matrixHelper.reset();
+    elemOpacity = 1;
+    if (letters[i].n) {
+      xPos = 0;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      currentLength = initPathPos;
+      firstLine = false;
+      if (this._hasMaskedPath) {
+        segmentInd = initSegmentInd;
+        pointInd = initPointInd;
+        points = segments[segmentInd].points;
+        prevPoint = points[pointInd - 1];
+        currentPoint = points[pointInd];
+        partialLength = currentPoint.partialLength;
+        segmentLength = 0;
+      }
+      letterM = '';
+      letterFc = '';
+      letterSw = '';
+      letterO = '';
+      letterP = this.defaultPropsArray;
+    } else {
+      if (this._hasMaskedPath) {
+        if (currentLine !== letters[i].line) {
+          switch (documentData.j) {
+            case 1:
+              currentLength += totalLength - documentData.lineWidths[letters[i].line];
+              break;
+            case 2:
+              currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
+              break;
+            default:
+              break;
+          }
+          currentLine = letters[i].line;
+        }
+        if (ind !== letters[i].ind) {
+          if (letters[ind]) {
+            currentLength += letters[ind].extra;
+          }
+          currentLength += letters[i].an / 2;
+          ind = letters[i].ind;
+        }
+        currentLength += (alignment[0] * letters[i].an) * 0.005;
+        var animatorOffset = 0;
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.p.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.p.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.p.v[0] * mult;
+            }
+          }
+          if (animatorProps.a.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.a.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.a.v[0] * mult;
+            }
+          }
+        }
+        flag = true;
+        // Force alignment only works with a single line for now
+        if (this._pathData.a.v) {
+          currentLength = letters[0].an * 0.5 + ((totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind) / (len - 1);
+          currentLength += this._pathData.f.v;
+        }
+        while (flag) {
+          if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
+            perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
+            xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
+            yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
+            matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, -(alignment[1] * yOff) * 0.01);
+            flag = false;
+          } else if (points) {
+            segmentLength += currentPoint.partialLength;
+            pointInd += 1;
+            if (pointInd >= points.length) {
+              pointInd = 0;
+              segmentInd += 1;
+              if (!segments[segmentInd]) {
+                if (mask.v.c) {
+                  pointInd = 0;
+                  segmentInd = 0;
+                  points = segments[segmentInd].points;
+                } else {
+                  segmentLength -= currentPoint.partialLength;
+                  points = null;
+                }
+              } else {
+                points = segments[segmentInd].points;
+              }
+            }
+            if (points) {
+              prevPoint = currentPoint;
+              currentPoint = points[pointInd];
+              partialLength = currentPoint.partialLength;
+            }
+          }
+        }
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+      } else {
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+
+        // Grouping alignment
+        matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, (-alignment[1] * yOff) * 0.01, 0);
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.t.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
+          if (xPos !== 0 || documentData.j !== 0) {
+            if (this._hasMaskedPath) {
+              if (mult.length) {
+                currentLength += animatorProps.t.v * mult[0];
+              } else {
+                currentLength += animatorProps.t.v * mult;
+              }
+            } else if (mult.length) {
+              xPos += animatorProps.t.v * mult[0];
+            } else {
+              xPos += animatorProps.t.v * mult;
+            }
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        sw = documentData.sw || 0;
+      }
+      if (documentData.strokeColorAnim) {
+        if (documentData.sc) {
+          sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
+        } else {
+          sc = [0, 0, 0];
+        }
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.a.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+
+          if (mult.length) {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.s.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (mult.length) {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult[0]), 1 + ((animatorProps.s.v[1] - 1) * mult[1]), 1);
+          } else {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult), 1 + ((animatorProps.s.v[1] - 1) * mult), 1);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        animatorSelector = animators[j].s;
+        mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+        if (animatorProps.sk.propType) {
+          if (mult.length) {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
+          } else {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
+          }
+        }
+        if (animatorProps.r.propType) {
+          if (mult.length) {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
+          } else {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult);
+          }
+        }
+        if (animatorProps.ry.propType) {
+          if (mult.length) {
+            matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
+          } else {
+            matrixHelper.rotateY(animatorProps.ry.v * mult);
+          }
+        }
+        if (animatorProps.rx.propType) {
+          if (mult.length) {
+            matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
+          } else {
+            matrixHelper.rotateX(animatorProps.rx.v * mult);
+          }
+        }
+        if (animatorProps.o.propType) {
+          if (mult.length) {
+            elemOpacity += ((animatorProps.o.v) * mult[0] - elemOpacity) * mult[0];
+          } else {
+            elemOpacity += ((animatorProps.o.v) * mult - elemOpacity) * mult;
+          }
+        }
+        if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
+          if (mult.length) {
+            sw += animatorProps.sw.v * mult[0];
+          } else {
+            sw += animatorProps.sw.v * mult;
+          }
+        }
+        if (documentData.strokeColorAnim && animatorProps.sc.propType) {
+          for (k = 0; k < 3; k += 1) {
+            if (mult.length) {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0];
+            } else {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult;
+            }
+          }
+        }
+        if (documentData.fillColorAnim && documentData.fc) {
+          if (animatorProps.fc.propType) {
+            for (k = 0; k < 3; k += 1) {
+              if (mult.length) {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0];
+              } else {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult;
+              }
+            }
+          }
+          if (animatorProps.fh.propType) {
+            if (mult.length) {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
+            } else {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult);
+            }
+          }
+          if (animatorProps.fs.propType) {
+            if (mult.length) {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
+            } else {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
+            }
+          }
+          if (animatorProps.fb.propType) {
+            if (mult.length) {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
+            } else {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult);
+            }
+          }
+        }
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+
+        if (animatorProps.p.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (this._hasMaskedPath) {
+            if (mult.length) {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
+            } else {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+            }
+          } else if (mult.length) {
+            matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        letterSw = sw < 0 ? 0 : sw;
+      }
+      if (documentData.strokeColorAnim) {
+        letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
+      }
+
+      if (this._hasMaskedPath) {
+        matrixHelper.translate(0, -documentData.ls);
+
+        matrixHelper.translate(0, (alignment[1] * yOff) * 0.01 + yPos, 0);
+        if (this._pathData.p.v) {
+          tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
+          var rot = (Math.atan(tanAngle) * 180) / Math.PI;
+          if (currentPoint.point[0] < prevPoint.point[0]) {
+            rot += 180;
+          }
+          matrixHelper.rotate((-rot * Math.PI) / 180);
+        }
+        matrixHelper.translate(xPathPos, yPathPos, 0);
+        currentLength -= (alignment[0] * letters[i].an) * 0.005;
+        if (letters[i + 1] && ind !== letters[i + 1].ind) {
+          currentLength += letters[i].an / 2;
+          currentLength += (documentData.tr * 0.001) * documentData.finalSize;
+        }
+      } else {
+        matrixHelper.translate(xPos, yPos, 0);
+
+        if (documentData.ps) {
+          // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
+          matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+        }
+        switch (documentData.j) {
+          case 1:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
+            break;
+          case 2:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
+            break;
+          default:
+            break;
+        }
+        matrixHelper.translate(0, -documentData.ls);
+        matrixHelper.translate(offf, 0, 0);
+        matrixHelper.translate((alignment[0] * letters[i].an) * 0.005, (alignment[1] * yOff) * 0.01, 0);
+        xPos += letters[i].l + (documentData.tr * 0.001) * documentData.finalSize;
+      }
+      if (renderType === 'html') {
+        letterM = matrixHelper.toCSS();
+      } else if (renderType === 'svg') {
+        letterM = matrixHelper.to2dCSS();
+      } else {
+        letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
+      }
+      letterO = elemOpacity;
+    }
+
+    if (renderedLettersCount <= i) {
+      letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
+      this.renderedLetters.push(letterValue);
+      renderedLettersCount += 1;
+      this.lettersChangedFlag = true;
+    } else {
+      letterValue = this.renderedLetters[i];
+      this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag;
+    }
+  }
+};
+
+TextAnimatorProperty.prototype.getValue = function () {
+  if (this._elem.globalData.frameId === this._frameId) {
+    return;
+  }
+  this._frameId = this._elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+TextAnimatorProperty.prototype.mHelper = new Matrix();
+TextAnimatorProperty.prototype.defaultPropsArray = [];
+extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
+
+function ITextElement() {
+}
+
+ITextElement.prototype.initElement = function (data, globalData, comp) {
+  this.lettersChangedFlag = true;
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.textProperty = new TextProperty(this, data.t, this.dynamicProperties);
+  this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this);
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+  this.initRenderable();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  this.createContent();
+  this.hide();
+  this.textAnimator.searchProperties(this.dynamicProperties);
+};
+
+ITextElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+};
+
+ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
+  var j;
+  var jLen = shapes.length;
+  var pathNodes;
+  var shapeStr = '';
+  for (j = 0; j < jLen; j += 1) {
+    if (shapes[j].ty === 'sh') {
+      pathNodes = shapes[j].ks.k;
+      shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
+    }
+  }
+  return shapeStr;
+};
+
+ITextElement.prototype.updateDocumentData = function (newData, index) {
+  this.textProperty.updateDocumentData(newData, index);
+};
+
+ITextElement.prototype.canResizeFont = function (_canResize) {
+  this.textProperty.canResizeFont(_canResize);
+};
+
+ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
+  this.textProperty.setMinimumFontSize(_fontSize);
+};
+
+ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
+  if (documentData.ps) {
+    matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+  }
+  matrixHelper.translate(0, -documentData.ls, 0);
+  switch (documentData.j) {
+    case 1:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
+      break;
+    case 2:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
+      break;
+    default:
+      break;
+  }
+  matrixHelper.translate(xPos, yPos, 0);
+};
+
+ITextElement.prototype.buildColor = function (colorData) {
+  return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
+};
+
+ITextElement.prototype.emptyProp = new LetterProps();
+
+ITextElement.prototype.destroy = function () {
+
+};
+
+ITextElement.prototype.validateText = function () {
+  if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
+    this.buildNewText();
+    this.textProperty._isFirstFrame = false;
+    this.textProperty._mdf = false;
+  }
+};
+
+var emptyShapeData = {
+  shapes: [],
+};
+
+function SVGTextLottieElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.renderType = 'svg';
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
+
+SVGTextLottieElement.prototype.createContent = function () {
+  if (this.data.singleShape && !this.globalData.fontManager.chars) {
+    this.textContainer = createNS('text');
+  }
+};
+
+SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
+  var i = 0;
+  var len = textArray.length;
+  var textContents = [];
+  var currentTextContent = '';
+  while (i < len) {
+    if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
+      textContents.push(currentTextContent);
+      currentTextContent = '';
+    } else {
+      currentTextContent += textArray[i];
+    }
+    i += 1;
+  }
+  textContents.push(currentTextContent);
+  return textContents;
+};
+
+SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
+  // data should probably be cloned to apply scale separately to each instance of a text on different layers
+  // but since text internal content gets only rendered once and then it's never rerendered,
+  // it's probably safe not to clone data and reuse always the same instance even if the object is mutated.
+  // Avoiding cloning is preferred since cloning each character shape data is expensive
+  if (data.shapes && data.shapes.length) {
+    var shape = data.shapes[0];
+    if (shape.it) {
+      var shapeItem = shape.it[shape.it.length - 1];
+      if (shapeItem.s) {
+        shapeItem.s.k[0] = scale;
+        shapeItem.s.k[1] = scale;
+      }
+    }
+  }
+  return data;
+};
+
+SVGTextLottieElement.prototype.buildNewText = function () {
+  this.addDynamicProperty(this);
+  var i;
+  var len;
+
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
+  if (documentData.fc) {
+    this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
+  } else {
+    this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
+  }
+  if (documentData.sc) {
+    this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
+    this.layerElement.setAttribute('stroke-width', documentData.sw);
+  }
+  this.layerElement.setAttribute('font-size', documentData.finalSize);
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (fontData.fClass) {
+    this.layerElement.setAttribute('class', fontData.fClass);
+  } else {
+    this.layerElement.setAttribute('font-family', fontData.fFamily);
+    var fWeight = documentData.fWeight;
+    var fStyle = documentData.fStyle;
+    this.layerElement.setAttribute('font-style', fStyle);
+    this.layerElement.setAttribute('font-weight', fWeight);
+  }
+  this.layerElement.setAttribute('aria-label', documentData.t);
+
+  var letters = documentData.l || [];
+  var usesGlyphs = !!this.globalData.fontManager.chars;
+  len = letters.length;
+
+  var tSpan;
+  var matrixHelper = this.mHelper;
+  var shapeStr = '';
+  var singleShape = this.data.singleShape;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  if (singleShape && !usesGlyphs && !documentData.sz) {
+    var tElement = this.textContainer;
+    var justify = 'start';
+    switch (documentData.j) {
+      case 1:
+        justify = 'end';
+        break;
+      case 2:
+        justify = 'middle';
+        break;
+      default:
+        justify = 'start';
+        break;
+    }
+    tElement.setAttribute('text-anchor', justify);
+    tElement.setAttribute('letter-spacing', trackingOffset);
+    var textContent = this.buildTextContents(documentData.finalText);
+    len = textContent.length;
+    yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
+    for (i = 0; i < len; i += 1) {
+      tSpan = this.textSpans[i].span || createNS('tspan');
+      tSpan.textContent = textContent[i];
+      tSpan.setAttribute('x', 0);
+      tSpan.setAttribute('y', yPos);
+      tSpan.style.display = 'inherit';
+      tElement.appendChild(tSpan);
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          glyph: null,
+        };
+      }
+      this.textSpans[i].span = tSpan;
+      yPos += documentData.finalLineHeight;
+    }
+
+    this.layerElement.appendChild(tElement);
+  } else {
+    var cachedSpansLength = this.textSpans.length;
+    var charData;
+    for (i = 0; i < len; i += 1) {
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          childSpan: null,
+          glyph: null,
+        };
+      }
+      if (!usesGlyphs || !singleShape || i === 0) {
+        tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
+        if (cachedSpansLength <= i) {
+          tSpan.setAttribute('stroke-linecap', 'butt');
+          tSpan.setAttribute('stroke-linejoin', 'round');
+          tSpan.setAttribute('stroke-miterlimit', '4');
+          this.textSpans[i].span = tSpan;
+          if (usesGlyphs) {
+            var childSpan = createNS('g');
+            tSpan.appendChild(childSpan);
+            this.textSpans[i].childSpan = childSpan;
+          }
+          this.textSpans[i].span = tSpan;
+          this.layerElement.appendChild(tSpan);
+        }
+        tSpan.style.display = 'inherit';
+      }
+
+      matrixHelper.reset();
+      if (singleShape) {
+        if (letters[i].n) {
+          xPos = -trackingOffset;
+          yPos += documentData.yOffset;
+          yPos += firstLine ? 1 : 0;
+          firstLine = false;
+        }
+        this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+        xPos += letters[i].l || 0;
+        // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
+        xPos += trackingOffset;
+      }
+      if (usesGlyphs) {
+        charData = this.globalData.fontManager.getCharData(
+          documentData.finalText[i],
+          fontData.fStyle,
+          this.globalData.fontManager.getFontByName(documentData.f).fFamily
+        );
+        var glyphElement;
+        // t === 1 means the character has been replaced with an animated shaped
+        if (charData.t === 1) {
+          glyphElement = new SVGCompElement(charData.data, this.globalData, this);
+        } else {
+          var data = emptyShapeData;
+          if (charData.data && charData.data.shapes) {
+            data = this.buildShapeData(charData.data, documentData.finalSize);
+          }
+          glyphElement = new SVGShapeElement(data, this.globalData, this);
+        }
+        if (this.textSpans[i].glyph) {
+          var glyph = this.textSpans[i].glyph;
+          this.textSpans[i].childSpan.removeChild(glyph.layerElement);
+          glyph.destroy();
+        }
+        this.textSpans[i].glyph = glyphElement;
+        glyphElement._debug = true;
+        glyphElement.prepareFrame(0);
+        glyphElement.renderFrame();
+        this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+        // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+        // this might have issues with strokes and might need a different solution
+        if (charData.t === 1) {
+          this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
+        }
+      } else {
+        if (singleShape) {
+          tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
+        }
+        tSpan.textContent = letters[i].val;
+        tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      }
+      //
+    }
+    if (singleShape && tSpan) {
+      tSpan.setAttribute('d', shapeStr);
+    }
+  }
+  while (i < this.textSpans.length) {
+    this.textSpans[i].span.style.display = 'none';
+    i += 1;
+  }
+
+  this._sizeChanged = true;
+};
+
+SVGTextLottieElement.prototype.sourceRectAtTime = function () {
+  this.prepareFrame(this.comp.renderedFrame - this.data.st);
+  this.renderInnerContent();
+  if (this._sizeChanged) {
+    this._sizeChanged = false;
+    var textBox = this.layerElement.getBBox();
+    this.bbox = {
+      top: textBox.y,
+      left: textBox.x,
+      width: textBox.width,
+      height: textBox.height,
+    };
+  }
+  return this.bbox;
+};
+
+SVGTextLottieElement.prototype.getValue = function () {
+  var i;
+  var len = this.textSpans.length;
+  var glyphElement;
+  this.renderedFrame = this.comp.renderedFrame;
+  for (i = 0; i < len; i += 1) {
+    glyphElement = this.textSpans[i].glyph;
+    if (glyphElement) {
+      glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
+      if (glyphElement._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+SVGTextLottieElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  if (!this.data.singleShape || this._mdf) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+    if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
+      this._sizeChanged = true;
+      var i;
+      var len;
+      var renderedLetters = this.textAnimator.renderedLetters;
+
+      var letters = this.textProperty.currentData.l;
+
+      len = letters.length;
+      var renderedLetter;
+      var textSpan;
+      var glyphElement;
+      for (i = 0; i < len; i += 1) {
+        if (!letters[i].n) {
+          renderedLetter = renderedLetters[i];
+          textSpan = this.textSpans[i].span;
+          glyphElement = this.textSpans[i].glyph;
+          if (glyphElement) {
+            glyphElement.renderFrame();
+          }
+          if (renderedLetter._mdf.m) {
+            textSpan.setAttribute('transform', renderedLetter.m);
+          }
+          if (renderedLetter._mdf.o) {
+            textSpan.setAttribute('opacity', renderedLetter.o);
+          }
+          if (renderedLetter._mdf.sw) {
+            textSpan.setAttribute('stroke-width', renderedLetter.sw);
+          }
+          if (renderedLetter._mdf.sc) {
+            textSpan.setAttribute('stroke', renderedLetter.sc);
+          }
+          if (renderedLetter._mdf.fc) {
+            textSpan.setAttribute('fill', renderedLetter.fc);
+          }
+        }
+      }
+    }
+  }
+};
+
+function ISolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([IImageElement], ISolidElement);
+
+ISolidElement.prototype.createContent = function () {
+  var rect = createNS('rect');
+  /// /rect.style.width = this.data.sw;
+  /// /rect.style.height = this.data.sh;
+  /// /rect.style.fill = this.data.sc;
+  rect.setAttribute('width', this.data.sw);
+  rect.setAttribute('height', this.data.sh);
+  rect.setAttribute('fill', this.data.sc);
+  this.layerElement.appendChild(rect);
+};
+
+function NullElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initFrame();
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+}
+
+NullElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+NullElement.prototype.renderFrame = function () {
+};
+
+NullElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+NullElement.prototype.destroy = function () {
+};
+
+NullElement.prototype.sourceRectAtTime = function () {
+};
+
+NullElement.prototype.hide = function () {
+};
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
+
+function SVGRendererBase() {
+}
+
+extendPrototype([BaseRenderer], SVGRendererBase);
+
+SVGRendererBase.prototype.createNull = function (data) {
+  return new NullElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createShape = function (data) {
+  return new SVGShapeElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createText = function (data) {
+  return new SVGTextLottieElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createImage = function (data) {
+  return new IImageElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createSolid = function (data) {
+  return new ISolidElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.configAnimation = function (animData) {
+  this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+  this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+  if (this.renderConfig.viewBoxSize) {
+    this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
+  } else {
+    this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
+  }
+
+  if (!this.renderConfig.viewBoxOnly) {
+    this.svgElement.setAttribute('width', animData.w);
+    this.svgElement.setAttribute('height', animData.h);
+    this.svgElement.style.width = '100%';
+    this.svgElement.style.height = '100%';
+    this.svgElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
+  }
+  if (this.renderConfig.width) {
+    this.svgElement.setAttribute('width', this.renderConfig.width);
+  }
+  if (this.renderConfig.height) {
+    this.svgElement.setAttribute('height', this.renderConfig.height);
+  }
+  if (this.renderConfig.className) {
+    this.svgElement.setAttribute('class', this.renderConfig.className);
+  }
+  if (this.renderConfig.id) {
+    this.svgElement.setAttribute('id', this.renderConfig.id);
+  }
+  if (this.renderConfig.focusable !== undefined) {
+    this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
+  }
+  this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+  // this.layerElement.style.transform = 'translate3d(0,0,0)';
+  // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
+  this.animationItem.wrapper.appendChild(this.svgElement);
+  // Mask animation
+  var defs = this.globalData.defs;
+
+  this.setupGlobalData(animData, defs);
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.data = animData;
+
+  var maskElement = createNS('clipPath');
+  var rect = createNS('rect');
+  rect.setAttribute('width', animData.w);
+  rect.setAttribute('height', animData.h);
+  rect.setAttribute('x', 0);
+  rect.setAttribute('y', 0);
+  var maskId = createElementID();
+  maskElement.setAttribute('id', maskId);
+  maskElement.appendChild(rect);
+  this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')');
+
+  defs.appendChild(maskElement);
+  this.layers = animData.layers;
+  this.elements = createSizedArray(animData.layers.length);
+};
+
+SVGRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.layerElement = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+SVGRendererBase.prototype.updateContainerSize = function () {
+};
+
+SVGRendererBase.prototype.findIndexByInd = function (ind) {
+  var i = 0;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.layers[i].ind === ind) {
+      return i;
+    }
+  }
+  return -1;
+};
+
+SVGRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  elements[pos] = true;
+  var element = this.createItem(this.layers[pos]);
+
+  elements[pos] = element;
+  if (getExpressionsPlugin()) {
+    if (this.layers[pos].ty === 0) {
+      this.globalData.projectInterface.registerComposition(element);
+    }
+    element.initExpressions();
+  }
+  this.appendElementInPos(element, pos);
+  if (this.layers[pos].tt) {
+    var elementIndex = ('tp' in this.layers[pos])
+      ? this.findIndexByInd(this.layers[pos].tp)
+      : pos - 1;
+    if (elementIndex === -1) {
+      return;
+    }
+    if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
+      this.buildItem(elementIndex);
+      this.addPendingElement(element);
+    } else {
+      var matteElement = elements[elementIndex];
+      var matteMask = matteElement.getMatte(this.layers[pos].tt);
+      element.setMatte(matteMask);
+    }
+  }
+};
+
+SVGRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+    if (element.data.tt) {
+      var i = 0;
+      var len = this.elements.length;
+      while (i < len) {
+        if (this.elements[i] === element) {
+          var elementIndex = 'tp' in element.data
+            ? this.findIndexByInd(element.data.tp)
+            : i - 1;
+          var matteElement = this.elements[elementIndex];
+          var matteMask = matteElement.getMatte(this.layers[i].tt);
+          element.setMatte(matteMask);
+          break;
+        }
+        i += 1;
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.renderFrame = function (num) {
+  if (this.renderedFrame === num || this.destroyed) {
+    return;
+  }
+  if (num === null) {
+    num = this.renderedFrame;
+  } else {
+    this.renderedFrame = num;
+  }
+  // console.log('-------');
+  // console.log('FRAME ',num);
+  this.globalData.frameNum = num;
+  this.globalData.frameId += 1;
+  this.globalData.projectInterface.currentFrame = num;
+  this.globalData._mdf = false;
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    for (i = 0; i < len; i += 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
+  var newElement = element.getBaseElement();
+  if (!newElement) {
+    return;
+  }
+  var i = 0;
+  var nextElement;
+  while (i < pos) {
+    if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
+      nextElement = this.elements[i].getBaseElement();
+    }
+    i += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(newElement, nextElement);
+  } else {
+    this.layerElement.appendChild(newElement);
+  }
+};
+
+SVGRendererBase.prototype.hide = function () {
+  this.layerElement.style.display = 'none';
+};
+
+SVGRendererBase.prototype.show = function () {
+  this.layerElement.style.display = 'block';
+};
+
+function ICompElement() {}
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
+
+ICompElement.prototype.initElement = function (data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initTransform(data, globalData, comp);
+  this.initRenderable();
+  this.initHierarchy();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  if (this.data.xt || !globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+  this.hide();
+};
+
+/* ICompElement.prototype.hide = function(){
+    if(!this.hidden){
+        this.hideElement();
+        var i,len = this.elements.length;
+        for( i = 0; i < len; i+=1 ){
+            if(this.elements[i]){
+                this.elements[i].hide();
+            }
+        }
+    }
+}; */
+
+ICompElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+  if (!this.isInRange && !this.data.xt) {
+    return;
+  }
+
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    if (timeRemapped === this.data.op) {
+      timeRemapped = this.data.op - 1;
+    }
+    this.renderedFrame = timeRemapped;
+  } else {
+    this.renderedFrame = num / this.data.sr;
+  }
+  var i;
+  var len = this.elements.length;
+  if (!this.completeLayers) {
+    this.checkLayers(this.renderedFrame);
+  }
+  // This iteration needs to be backwards because of how expressions connect between each other
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
+      if (this.elements[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+ICompElement.prototype.renderInnerContent = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+ICompElement.prototype.setElements = function (elems) {
+  this.elements = elems;
+};
+
+ICompElement.prototype.getElements = function () {
+  return this.elements;
+};
+
+ICompElement.prototype.destroyElements = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+};
+
+ICompElement.prototype.destroy = function () {
+  this.destroyElements();
+  this.destroyBaseElement();
+};
+
+function SVGCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = true;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
+
+SVGCompElement.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function SVGRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.layers = null;
+  this.renderedFrame = -1;
+  this.svgElement = createNS('svg');
+  var ariaLabel = '';
+  if (config && config.title) {
+    var titleElement = createNS('title');
+    var titleId = createElementID();
+    titleElement.setAttribute('id', titleId);
+    titleElement.textContent = config.title;
+    this.svgElement.appendChild(titleElement);
+    ariaLabel += titleId;
+  }
+  if (config && config.description) {
+    var descElement = createNS('desc');
+    var descId = createElementID();
+    descElement.setAttribute('id', descId);
+    descElement.textContent = config.description;
+    this.svgElement.appendChild(descElement);
+    ariaLabel += ' ' + descId;
+  }
+  if (ariaLabel) {
+    this.svgElement.setAttribute('aria-labelledby', ariaLabel);
+  }
+  var defs = createNS('defs');
+  this.svgElement.appendChild(defs);
+  var maskElement = createNS('g');
+  this.svgElement.appendChild(maskElement);
+  this.layerElement = maskElement;
+  this.renderConfig = {
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    hideOnTransparent: !((config && config.hideOnTransparent === false)),
+    viewBoxOnly: (config && config.viewBoxOnly) || false,
+    viewBoxSize: (config && config.viewBoxSize) || false,
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    focusable: config && config.focusable,
+    filterSize: {
+      width: (config && config.filterSize && config.filterSize.width) || '100%',
+      height: (config && config.filterSize && config.filterSize.height) || '100%',
+      x: (config && config.filterSize && config.filterSize.x) || '0%',
+      y: (config && config.filterSize && config.filterSize.y) || '0%',
+    },
+    width: (config && config.width),
+    height: (config && config.height),
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+
+  this.globalData = {
+    _mdf: false,
+    frameNum: -1,
+    defs: defs,
+    renderConfig: this.renderConfig,
+  };
+  this.elements = [];
+  this.pendingElements = [];
+  this.destroyed = false;
+  this.rendererType = 'svg';
+}
+
+extendPrototype([SVGRendererBase], SVGRenderer);
+
+SVGRenderer.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function ShapeTransformManager() {
+  this.sequences = {};
+  this.sequenceList = [];
+  this.transform_key_count = 0;
+}
+
+ShapeTransformManager.prototype = {
+  addTransformSequence: function (transforms) {
+    var i;
+    var len = transforms.length;
+    var key = '_';
+    for (i = 0; i < len; i += 1) {
+      key += transforms[i].transform.key + '_';
+    }
+    var sequence = this.sequences[key];
+    if (!sequence) {
+      sequence = {
+        transforms: [].concat(transforms),
+        finalTransform: new Matrix(),
+        _mdf: false,
+      };
+      this.sequences[key] = sequence;
+      this.sequenceList.push(sequence);
+    }
+    return sequence;
+  },
+  processSequence: function (sequence, isFirstFrame) {
+    var i = 0;
+    var len = sequence.transforms.length;
+    var _mdf = isFirstFrame;
+    while (i < len && !isFirstFrame) {
+      if (sequence.transforms[i].transform.mProps._mdf) {
+        _mdf = true;
+        break;
+      }
+      i += 1;
+    }
+    if (_mdf) {
+      sequence.finalTransform.reset();
+      for (i = len - 1; i >= 0; i -= 1) {
+        sequence.finalTransform.multiply(sequence.transforms[i].transform.mProps.v);
+      }
+    }
+    sequence._mdf = _mdf;
+  },
+  processSequences: function (isFirstFrame) {
+    var i;
+    var len = this.sequenceList.length;
+    for (i = 0; i < len; i += 1) {
+      this.processSequence(this.sequenceList[i], isFirstFrame);
+    }
+  },
+  getNewKey: function () {
+    this.transform_key_count += 1;
+    return '_' + this.transform_key_count;
+  },
+};
+
+var lumaLoader = (function () {
+  var id = '__lottie_element_luma_buffer';
+  var lumaBuffer = null;
+  var lumaBufferCtx = null;
+  var svg = null;
+
+  // This alternate solution has a slight delay before the filter is applied, resulting in a flicker on the first frame.
+  // Keeping this here for reference, and in the future, if offscreen canvas supports url filters, this can be used.
+  // For now, neither of them work for offscreen canvas, so canvas workers can't support the luma track matte mask.
+  // Naming it solution 2 to mark the extra comment lines.
+  /*
+  var svgString = [
+    '<svg xmlns="http://www.w3.org/2000/svg">',
+    '<filter id="' + id + '">',
+    '<feColorMatrix type="matrix" color-interpolation-filters="sRGB" values="',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0',
+    '"/>',
+    '</filter>',
+    '</svg>',
+  ].join('');
+  var blob = new Blob([svgString], { type: 'image/svg+xml' });
+  var url = URL.createObjectURL(blob);
+  */
+
+  function createLumaSvgFilter() {
+    var _svg = createNS('svg');
+    var fil = createNS('filter');
+    var matrix = createNS('feColorMatrix');
+    fil.setAttribute('id', id);
+    matrix.setAttribute('type', 'matrix');
+    matrix.setAttribute('color-interpolation-filters', 'sRGB');
+    matrix.setAttribute('values', '0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0');
+    fil.appendChild(matrix);
+    _svg.appendChild(fil);
+    _svg.setAttribute('id', id + '_svg');
+    if (featureSupport.svgLumaHidden) {
+      _svg.style.display = 'none';
+    }
+    return _svg;
+  }
+
+  function loadLuma() {
+    if (!lumaBuffer) {
+      svg = createLumaSvgFilter();
+      document.body.appendChild(svg);
+      lumaBuffer = createTag('canvas');
+      lumaBufferCtx = lumaBuffer.getContext('2d');
+      // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
+      lumaBufferCtx.filter = 'url(#' + id + ')';
+      lumaBufferCtx.fillStyle = 'rgba(0,0,0,0)';
+      lumaBufferCtx.fillRect(0, 0, 1, 1);
+    }
+  }
+
+  function getLuma(canvas) {
+    if (!lumaBuffer) {
+      loadLuma();
+    }
+    lumaBuffer.width = canvas.width;
+    lumaBuffer.height = canvas.height;
+    // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
+    lumaBufferCtx.filter = 'url(#' + id + ')';
+    return lumaBuffer;
+  }
+  return {
+    load: loadLuma,
+    get: getLuma,
+  };
+});
+
+function createCanvas(width, height) {
+  if (featureSupport.offscreenCanvas) {
+    return new OffscreenCanvas(width, height);
+  }
+  var canvas = createTag('canvas');
+  canvas.width = width;
+  canvas.height = height;
+  return canvas;
+}
+
+const assetLoader = (function () {
+  return {
+    loadLumaCanvas: lumaLoader.load,
+    getLumaCanvas: lumaLoader.get,
+    createCanvas: createCanvas,
+  };
+}());
+
+var registeredEffects = {};
+
+function CVEffects(elem) {
+  var i;
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects[type]) {
+      var Effect = registeredEffects[type].effect;
+      filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+CVEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+CVEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect(id, effect) {
+  registeredEffects[id] = {
+    effect,
+  };
+}
+
+function CVMaskElement(data, element) {
+  this.data = data;
+  this.element = element;
+  this.masksProperties = this.data.masksProperties || [];
+  this.viewData = createSizedArray(this.masksProperties.length);
+  var i;
+  var len = this.masksProperties.length;
+  var hasMasks = false;
+  for (i = 0; i < len; i += 1) {
+    if (this.masksProperties[i].mode !== 'n') {
+      hasMasks = true;
+    }
+    this.viewData[i] = ShapePropertyFactory.getShapeProp(this.element, this.masksProperties[i], 3);
+  }
+  this.hasMasks = hasMasks;
+  if (hasMasks) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+CVMaskElement.prototype.renderFrame = function () {
+  if (!this.hasMasks) {
+    return;
+  }
+  var transform = this.element.finalTransform.mat;
+  var ctx = this.element.canvasContext;
+  var i;
+  var len = this.masksProperties.length;
+  var pt;
+  var pts;
+  var data;
+  ctx.beginPath();
+  for (i = 0; i < len; i += 1) {
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.masksProperties[i].inv) {
+        ctx.moveTo(0, 0);
+        ctx.lineTo(this.element.globalData.compSize.w, 0);
+        ctx.lineTo(this.element.globalData.compSize.w, this.element.globalData.compSize.h);
+        ctx.lineTo(0, this.element.globalData.compSize.h);
+        ctx.lineTo(0, 0);
+      }
+      data = this.viewData[i].v;
+      pt = transform.applyToPointArray(data.v[0][0], data.v[0][1], 0);
+      ctx.moveTo(pt[0], pt[1]);
+      var j;
+      var jLen = data._length;
+      for (j = 1; j < jLen; j += 1) {
+        pts = transform.applyToTriplePoints(data.o[j - 1], data.i[j], data.v[j]);
+        ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
+      }
+      pts = transform.applyToTriplePoints(data.o[j - 1], data.i[0], data.v[0]);
+      ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
+    }
+  }
+  this.element.globalData.renderer.save(true);
+  ctx.clip();
+};
+
+CVMaskElement.prototype.getMaskProperty = MaskElement.prototype.getMaskProperty;
+
+CVMaskElement.prototype.destroy = function () {
+  this.element = null;
+};
+
+function CVBaseElement() {
+}
+
+var operationsMap = {
+  1: 'source-in',
+  2: 'source-out',
+  3: 'source-in',
+  4: 'source-out',
+};
+
+CVBaseElement.prototype = {
+  createElements: function () {},
+  initRendererElement: function () {},
+  createContainerElements: function () {
+    // If the layer is masked we will use two buffers to store each different states of the drawing
+    // This solution is not ideal for several reason. But unfortunately, because of the recursive
+    // nature of the render tree, it's the only simple way to make sure one inner mask doesn't override an outer mask.
+    // TODO: try to reduce the size of these buffers to the size of the composition contaning the layer
+    // It might be challenging because the layer most likely is transformed in some way
+    if (this.data.tt >= 1) {
+      this.buffers = [];
+      var canvasContext = this.globalData.canvasContext;
+      var bufferCanvas = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
+      this.buffers.push(bufferCanvas);
+      var bufferCanvas2 = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
+      this.buffers.push(bufferCanvas2);
+      if (this.data.tt >= 3 && !document._isProxy) {
+        assetLoader.loadLumaCanvas();
+      }
+    }
+    this.canvasContext = this.globalData.canvasContext;
+    this.transformCanvas = this.globalData.transformCanvas;
+    this.renderableEffectsManager = new CVEffects(this);
+    this.searchEffectTransforms();
+  },
+  createContent: function () {},
+  setBlendMode: function () {
+    var globalData = this.globalData;
+    if (globalData.blendMode !== this.data.bm) {
+      globalData.blendMode = this.data.bm;
+      var blendModeValue = getBlendMode(this.data.bm);
+      globalData.canvasContext.globalCompositeOperation = blendModeValue;
+    }
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new CVMaskElement(this.data, this);
+    this.transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+  },
+  hideElement: function () {
+    if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+      this.hidden = true;
+    }
+  },
+  showElement: function () {
+    if (this.isInRange && !this.isTransparent) {
+      this.hidden = false;
+      this._isFirstFrame = true;
+      this.maskManager._isFirstFrame = true;
+    }
+  },
+  clearCanvas: function (canvasContext) {
+    canvasContext.clearRect(
+      this.transformCanvas.tx,
+      this.transformCanvas.ty,
+      this.transformCanvas.w * this.transformCanvas.sx,
+      this.transformCanvas.h * this.transformCanvas.sy
+    );
+  },
+  prepareLayer: function () {
+    if (this.data.tt >= 1) {
+      var buffer = this.buffers[0];
+      var bufferCtx = buffer.getContext('2d');
+      this.clearCanvas(bufferCtx);
+      // on the first buffer we store the current state of the global drawing
+      bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+      // The next four lines are to clear the canvas
+      // TODO: Check if there is a way to clear the canvas without resetting the transform
+      this.currentTransform = this.canvasContext.getTransform();
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+      this.clearCanvas(this.canvasContext);
+      this.canvasContext.setTransform(this.currentTransform);
+    }
+  },
+  exitLayer: function () {
+    if (this.data.tt >= 1) {
+      var buffer = this.buffers[1];
+      // On the second buffer we store the current state of the global drawing
+      // that only contains the content of this layer
+      // (if it is a composition, it also includes the nested layers)
+      var bufferCtx = buffer.getContext('2d');
+      this.clearCanvas(bufferCtx);
+      bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+      // We clear the canvas again
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+      this.clearCanvas(this.canvasContext);
+      this.canvasContext.setTransform(this.currentTransform);
+      // We draw the mask
+      const mask = this.comp.getElementById('tp' in this.data ? this.data.tp : this.data.ind - 1);
+      mask.renderFrame(true);
+      // We draw the second buffer (that contains the content of this layer)
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+
+      // If the mask is a Luma matte, we need to do two extra painting operations
+      // the _isProxy check is to avoid drawing a fake canvas in workers that will throw an error
+      if (this.data.tt >= 3 && !document._isProxy) {
+        // We copy the painted mask to a buffer that has a color matrix filter applied to it
+        // that applies the rgb values to the alpha channel
+        var lumaBuffer = assetLoader.getLumaCanvas(this.canvasContext.canvas);
+        var lumaBufferCtx = lumaBuffer.getContext('2d');
+        lumaBufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+        this.clearCanvas(this.canvasContext);
+        // we repaint the context with the mask applied to it
+        this.canvasContext.drawImage(lumaBuffer, 0, 0);
+      }
+      this.canvasContext.globalCompositeOperation = operationsMap[this.data.tt];
+      this.canvasContext.drawImage(buffer, 0, 0);
+      // We finally draw the first buffer (that contains the content of the global drawing)
+      // We use destination-over to draw the global drawing below the current layer
+      this.canvasContext.globalCompositeOperation = 'destination-over';
+      this.canvasContext.drawImage(this.buffers[0], 0, 0);
+      this.canvasContext.setTransform(this.currentTransform);
+      // We reset the globalCompositeOperation to source-over, the standard type of operation
+      this.canvasContext.globalCompositeOperation = 'source-over';
+    }
+  },
+  renderFrame: function (forceRender) {
+    if (this.hidden || this.data.hd) {
+      return;
+    }
+    if (this.data.td === 1 && !forceRender) {
+      return;
+    }
+    this.renderTransform();
+    this.renderRenderable();
+    this.renderLocalTransform();
+    this.setBlendMode();
+    var forceRealStack = this.data.ty === 0;
+    this.prepareLayer();
+    this.globalData.renderer.save(forceRealStack);
+    this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props);
+    this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity);
+    this.renderInnerContent();
+    this.globalData.renderer.restore(forceRealStack);
+    this.exitLayer();
+    if (this.maskManager.hasMasks) {
+      this.globalData.renderer.restore(true);
+    }
+    if (this._isFirstFrame) {
+      this._isFirstFrame = false;
+    }
+  },
+  destroy: function () {
+    this.canvasContext = null;
+    this.data = null;
+    this.globalData = null;
+    this.maskManager.destroy();
+  },
+  mHelper: new Matrix(),
+};
+CVBaseElement.prototype.hide = CVBaseElement.prototype.hideElement;
+CVBaseElement.prototype.show = CVBaseElement.prototype.showElement;
+
+function CVShapeData(element, data, styles, transformsManager) {
+  this.styledShapes = [];
+  this.tr = [0, 0, 0, 0, 0, 0];
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  this.sh = ShapePropertyFactory.getShapeProp(element, data, ty, element);
+  var i;
+  var len = styles.length;
+  var styledShape;
+  for (i = 0; i < len; i += 1) {
+    if (!styles[i].closed) {
+      styledShape = {
+        transforms: transformsManager.addTransformSequence(styles[i].transforms),
+        trNodes: [],
+      };
+      this.styledShapes.push(styledShape);
+      styles[i].elements.push(styledShape);
+    }
+  }
+}
+
+CVShapeData.prototype.setAsAnimated = SVGShapeData.prototype.setAsAnimated;
+
+function CVShapeElement(data, globalData, comp) {
+  this.shapes = [];
+  this.shapesData = data.shapes;
+  this.stylesList = [];
+  this.itemsData = [];
+  this.prevViewData = [];
+  this.shapeModifiers = [];
+  this.processedElements = [];
+  this.transformsManager = new ShapeTransformManager();
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, CVBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableElement], CVShapeElement);
+
+CVShapeElement.prototype.initElement = RenderableDOMElement.prototype.initElement;
+
+CVShapeElement.prototype.transformHelper = { opacity: 1, _opMdf: false };
+
+CVShapeElement.prototype.dashResetter = [];
+
+CVShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
+};
+
+CVShapeElement.prototype.createStyleElement = function (data, transforms) {
+  var styleElem = {
+    data: data,
+    type: data.ty,
+    preTransforms: this.transformsManager.addTransformSequence(transforms),
+    transforms: [],
+    elements: [],
+    closed: data.hd === true,
+  };
+  var elementData = {};
+  if (data.ty === 'fl' || data.ty === 'st') {
+    elementData.c = PropertyFactory.getProp(this, data.c, 1, 255, this);
+    if (!elementData.c.k) {
+      styleElem.co = 'rgb(' + bmFloor(elementData.c.v[0]) + ',' + bmFloor(elementData.c.v[1]) + ',' + bmFloor(elementData.c.v[2]) + ')';
+    }
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    elementData.s = PropertyFactory.getProp(this, data.s, 1, null, this);
+    elementData.e = PropertyFactory.getProp(this, data.e, 1, null, this);
+    elementData.h = PropertyFactory.getProp(this, data.h || { k: 0 }, 0, 0.01, this);
+    elementData.a = PropertyFactory.getProp(this, data.a || { k: 0 }, 0, degToRads, this);
+    elementData.g = new GradientProperty(this, data.g, this);
+  }
+  elementData.o = PropertyFactory.getProp(this, data.o, 0, 0.01, this);
+  if (data.ty === 'st' || data.ty === 'gs') {
+    styleElem.lc = lineCapEnum[data.lc || 2];
+    styleElem.lj = lineJoinEnum[data.lj || 2];
+    if (data.lj == 1) { // eslint-disable-line eqeqeq
+      styleElem.ml = data.ml;
+    }
+    elementData.w = PropertyFactory.getProp(this, data.w, 0, null, this);
+    if (!elementData.w.k) {
+      styleElem.wi = elementData.w.v;
+    }
+    if (data.d) {
+      var d = new DashProperty(this, data.d, 'canvas', this);
+      elementData.d = d;
+      if (!elementData.d.k) {
+        styleElem.da = elementData.d.dashArray;
+        styleElem.do = elementData.d.dashoffset[0];
+      }
+    }
+  } else {
+    styleElem.r = data.r === 2 ? 'evenodd' : 'nonzero';
+  }
+  this.stylesList.push(styleElem);
+  elementData.style = styleElem;
+  return elementData;
+};
+
+CVShapeElement.prototype.createGroupElement = function () {
+  var elementData = {
+    it: [],
+    prevViewData: [],
+  };
+  return elementData;
+};
+
+CVShapeElement.prototype.createTransformElement = function (data) {
+  var elementData = {
+    transform: {
+      opacity: 1,
+      _opMdf: false,
+      key: this.transformsManager.getNewKey(),
+      op: PropertyFactory.getProp(this, data.o, 0, 0.01, this),
+      mProps: TransformPropertyFactory.getTransformProperty(this, data, this),
+    },
+  };
+  return elementData;
+};
+
+CVShapeElement.prototype.createShapeElement = function (data) {
+  var elementData = new CVShapeData(this, data, this.stylesList, this.transformsManager);
+
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  return elementData;
+};
+
+CVShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+  this.transformsManager.processSequences(this._isFirstFrame);
+};
+
+CVShapeElement.prototype.addTransformToStyleList = function (transform) {
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    if (!this.stylesList[i].closed) {
+      this.stylesList[i].transforms.push(transform);
+    }
+  }
+};
+
+CVShapeElement.prototype.removeTransformFromStyleList = function () {
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    if (!this.stylesList[i].closed) {
+      this.stylesList[i].transforms.pop();
+    }
+  }
+};
+
+CVShapeElement.prototype.closeStyles = function (styles) {
+  var i;
+  var len = styles.length;
+  for (i = 0; i < len; i += 1) {
+    styles[i].closed = true;
+  }
+};
+
+CVShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, shouldRender, transforms) {
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var processedPos;
+  var modifier;
+  var currentTransform;
+  var ownTransforms = [].concat(transforms);
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._shouldRender = shouldRender;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], ownTransforms);
+      } else {
+        itemsData[i].style.closed = false;
+      }
+
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, shouldRender, ownTransforms);
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        currentTransform = this.createTransformElement(arr[i]);
+        itemsData[i] = currentTransform;
+      }
+      ownTransforms.push(itemsData[i]);
+      this.addTransformToStyleList(itemsData[i]);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i]);
+      }
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        shouldRender = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  this.removeTransformFromStyleList();
+  this.closeStyles(ownStyles);
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+CVShapeElement.prototype.renderInnerContent = function () {
+  this.transformHelper.opacity = 1;
+  this.transformHelper._opMdf = false;
+  this.renderModifiers();
+  this.transformsManager.processSequences(this._isFirstFrame);
+  this.renderShape(this.transformHelper, this.shapesData, this.itemsData, true);
+};
+
+CVShapeElement.prototype.renderShapeTransform = function (parentTransform, groupTransform) {
+  if (parentTransform._opMdf || groupTransform.op._mdf || this._isFirstFrame) {
+    groupTransform.opacity = parentTransform.opacity;
+    groupTransform.opacity *= groupTransform.op.v;
+    groupTransform._opMdf = true;
+  }
+};
+
+CVShapeElement.prototype.drawLayer = function () {
+  var i;
+  var len = this.stylesList.length;
+  var j;
+  var jLen;
+  var k;
+  var kLen;
+  var elems;
+  var nodes;
+  var renderer = this.globalData.renderer;
+  var ctx = this.globalData.canvasContext;
+  var type;
+  var currentStyle;
+  for (i = 0; i < len; i += 1) {
+    currentStyle = this.stylesList[i];
+    type = currentStyle.type;
+
+    // Skipping style when
+    // Stroke width equals 0
+    // style should not be rendered (extra unused repeaters)
+    // current opacity equals 0
+    // global opacity equals 0
+    if (!(((type === 'st' || type === 'gs') && currentStyle.wi === 0) || !currentStyle.data._shouldRender || currentStyle.coOp === 0 || this.globalData.currentGlobalAlpha === 0)) {
+      renderer.save();
+      elems = currentStyle.elements;
+      if (type === 'st' || type === 'gs') {
+        renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd);
+        // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
+        renderer.ctxLineWidth(currentStyle.wi);
+        // ctx.lineWidth = currentStyle.wi;
+        renderer.ctxLineCap(currentStyle.lc);
+        // ctx.lineCap = currentStyle.lc;
+        renderer.ctxLineJoin(currentStyle.lj);
+        // ctx.lineJoin = currentStyle.lj;
+        renderer.ctxMiterLimit(currentStyle.ml || 0);
+        // ctx.miterLimit = currentStyle.ml || 0;
+      } else {
+        renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd);
+        // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
+      }
+      renderer.ctxOpacity(currentStyle.coOp);
+      if (type !== 'st' && type !== 'gs') {
+        ctx.beginPath();
+      }
+      renderer.ctxTransform(currentStyle.preTransforms.finalTransform.props);
+      jLen = elems.length;
+      for (j = 0; j < jLen; j += 1) {
+        if (type === 'st' || type === 'gs') {
+          ctx.beginPath();
+          if (currentStyle.da) {
+            ctx.setLineDash(currentStyle.da);
+            ctx.lineDashOffset = currentStyle.do;
+          }
+        }
+        nodes = elems[j].trNodes;
+        kLen = nodes.length;
+
+        for (k = 0; k < kLen; k += 1) {
+          if (nodes[k].t === 'm') {
+            ctx.moveTo(nodes[k].p[0], nodes[k].p[1]);
+          } else if (nodes[k].t === 'c') {
+            ctx.bezierCurveTo(nodes[k].pts[0], nodes[k].pts[1], nodes[k].pts[2], nodes[k].pts[3], nodes[k].pts[4], nodes[k].pts[5]);
+          } else {
+            ctx.closePath();
+          }
+        }
+        if (type === 'st' || type === 'gs') {
+          // ctx.stroke();
+          renderer.ctxStroke();
+          if (currentStyle.da) {
+            ctx.setLineDash(this.dashResetter);
+          }
+        }
+      }
+      if (type !== 'st' && type !== 'gs') {
+        // ctx.fill(currentStyle.r);
+        this.globalData.renderer.ctxFill(currentStyle.r);
+      }
+      renderer.restore();
+    }
+  }
+};
+
+CVShapeElement.prototype.renderShape = function (parentTransform, items, data, isMain) {
+  var i;
+  var len = items.length - 1;
+  var groupTransform;
+  groupTransform = parentTransform;
+  for (i = len; i >= 0; i -= 1) {
+    if (items[i].ty === 'tr') {
+      groupTransform = data[i].transform;
+      this.renderShapeTransform(parentTransform, groupTransform);
+    } else if (items[i].ty === 'sh' || items[i].ty === 'el' || items[i].ty === 'rc' || items[i].ty === 'sr') {
+      this.renderPath(items[i], data[i]);
+    } else if (items[i].ty === 'fl') {
+      this.renderFill(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'st') {
+      this.renderStroke(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'gf' || items[i].ty === 'gs') {
+      this.renderGradientFill(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'gr') {
+      this.renderShape(groupTransform, items[i].it, data[i].it);
+    } else if (items[i].ty === 'tm') {
+      //
+    }
+  }
+  if (isMain) {
+    this.drawLayer();
+  }
+};
+
+CVShapeElement.prototype.renderStyledShape = function (styledShape, shape) {
+  if (this._isFirstFrame || shape._mdf || styledShape.transforms._mdf) {
+    var shapeNodes = styledShape.trNodes;
+    var paths = shape.paths;
+    var i;
+    var len;
+    var j;
+    var jLen = paths._length;
+    shapeNodes.length = 0;
+    var groupTransformMat = styledShape.transforms.finalTransform;
+    for (j = 0; j < jLen; j += 1) {
+      var pathNodes = paths.shapes[j];
+      if (pathNodes && pathNodes.v) {
+        len = pathNodes._length;
+        for (i = 1; i < len; i += 1) {
+          if (i === 1) {
+            shapeNodes.push({
+              t: 'm',
+              p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0),
+            });
+          }
+          shapeNodes.push({
+            t: 'c',
+            pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[i], pathNodes.v[i]),
+          });
+        }
+        if (len === 1) {
+          shapeNodes.push({
+            t: 'm',
+            p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0),
+          });
+        }
+        if (pathNodes.c && len) {
+          shapeNodes.push({
+            t: 'c',
+            pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[0], pathNodes.v[0]),
+          });
+          shapeNodes.push({
+            t: 'z',
+          });
+        }
+      }
+    }
+    styledShape.trNodes = shapeNodes;
+  }
+};
+
+CVShapeElement.prototype.renderPath = function (pathData, itemData) {
+  if (pathData.hd !== true && pathData._shouldRender) {
+    var i;
+    var len = itemData.styledShapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderStyledShape(itemData.styledShapes[i], itemData.sh);
+    }
+  }
+};
+
+CVShapeElement.prototype.renderFill = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+
+  if (itemData.c._mdf || this._isFirstFrame) {
+    styleElem.co = 'rgb('
+        + bmFloor(itemData.c.v[0]) + ','
+        + bmFloor(itemData.c.v[1]) + ','
+        + bmFloor(itemData.c.v[2]) + ')';
+  }
+  if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
+    styleElem.coOp = itemData.o.v * groupTransform.opacity;
+  }
+};
+
+CVShapeElement.prototype.renderGradientFill = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+  var grd;
+  if (!styleElem.grd || itemData.g._mdf || itemData.s._mdf || itemData.e._mdf || (styleData.t !== 1 && (itemData.h._mdf || itemData.a._mdf))) {
+    var ctx = this.globalData.canvasContext;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+    if (styleData.t === 1) {
+      grd = ctx.createLinearGradient(pt1[0], pt1[1], pt2[0], pt2[1]);
+    } else {
+      var rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+      var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+      var percent = itemData.h.v;
+      if (percent >= 1) {
+        percent = 0.99;
+      } else if (percent <= -1) {
+        percent = -0.99;
+      }
+      var dist = rad * percent;
+      var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+      var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+      grd = ctx.createRadialGradient(x, y, 0, pt1[0], pt1[1], rad);
+    }
+
+    var i;
+    var len = styleData.g.p;
+    var cValues = itemData.g.c;
+    var opacity = 1;
+
+    for (i = 0; i < len; i += 1) {
+      if (itemData.g._hasOpacity && itemData.g._collapsable) {
+        opacity = itemData.g.o[i * 2 + 1];
+      }
+      grd.addColorStop(cValues[i * 4] / 100, 'rgba(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ',' + opacity + ')');
+    }
+    styleElem.grd = grd;
+  }
+  styleElem.coOp = itemData.o.v * groupTransform.opacity;
+};
+
+CVShapeElement.prototype.renderStroke = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+  var d = itemData.d;
+  if (d && (d._mdf || this._isFirstFrame)) {
+    styleElem.da = d.dashArray;
+    styleElem.do = d.dashoffset[0];
+  }
+  if (itemData.c._mdf || this._isFirstFrame) {
+    styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
+  }
+  if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
+    styleElem.coOp = itemData.o.v * groupTransform.opacity;
+  }
+  if (itemData.w._mdf || this._isFirstFrame) {
+    styleElem.wi = itemData.w.v;
+  }
+};
+
+CVShapeElement.prototype.destroy = function () {
+  this.shapesData = null;
+  this.globalData = null;
+  this.canvasContext = null;
+  this.stylesList.length = 0;
+  this.itemsData.length = 0;
+};
+
+function CVTextElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.yOffset = 0;
+  this.fillColorAnim = false;
+  this.strokeColorAnim = false;
+  this.strokeWidthAnim = false;
+  this.stroke = false;
+  this.fill = false;
+  this.justifyOffset = 0;
+  this.currentRender = null;
+  this.renderType = 'canvas';
+  this.values = {
+    fill: 'rgba(0,0,0,0)',
+    stroke: 'rgba(0,0,0,0)',
+    sWidth: 0,
+    fValue: '',
+  };
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement, ITextElement], CVTextElement);
+
+CVTextElement.prototype.tHelper = createTag('canvas').getContext('2d');
+
+CVTextElement.prototype.buildNewText = function () {
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
+
+  var hasFill = false;
+  if (documentData.fc) {
+    hasFill = true;
+    this.values.fill = this.buildColor(documentData.fc);
+  } else {
+    this.values.fill = 'rgba(0,0,0,0)';
+  }
+  this.fill = hasFill;
+  var hasStroke = false;
+  if (documentData.sc) {
+    hasStroke = true;
+    this.values.stroke = this.buildColor(documentData.sc);
+    this.values.sWidth = documentData.sw;
+  }
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  var i;
+  var len;
+  var letters = documentData.l;
+  var matrixHelper = this.mHelper;
+  this.stroke = hasStroke;
+  this.values.fValue = documentData.finalSize + 'px ' + this.globalData.fontManager.getFontByName(documentData.f).fFamily;
+  len = documentData.finalText.length;
+  // this.tHelper.font = this.values.fValue;
+  var charData;
+  var shapeData;
+  var k;
+  var kLen;
+  var shapes;
+  var j;
+  var jLen;
+  var pathNodes;
+  var commands;
+  var pathArr;
+  var singleShape = this.data.singleShape;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var cnt = 0;
+  for (i = 0; i < len; i += 1) {
+    charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
+    shapeData = (charData && charData.data) || {};
+    matrixHelper.reset();
+    if (singleShape && letters[i].n) {
+      xPos = -trackingOffset;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      firstLine = false;
+    }
+    shapes = shapeData.shapes ? shapeData.shapes[0].it : [];
+    jLen = shapes.length;
+    matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
+    if (singleShape) {
+      this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+    }
+    commands = createSizedArray(jLen - 1);
+    var commandsCounter = 0;
+    for (j = 0; j < jLen; j += 1) {
+      if (shapes[j].ty === 'sh') {
+        kLen = shapes[j].ks.k.i.length;
+        pathNodes = shapes[j].ks.k;
+        pathArr = [];
+        for (k = 1; k < kLen; k += 1) {
+          if (k === 1) {
+            pathArr.push(matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
+          }
+          pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToY(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToX(pathNodes.v[k][0], pathNodes.v[k][1], 0), matrixHelper.applyToY(pathNodes.v[k][0], pathNodes.v[k][1], 0));
+        }
+        pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToY(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
+        commands[commandsCounter] = pathArr;
+        commandsCounter += 1;
+      }
+    }
+    if (singleShape) {
+      xPos += letters[i].l;
+      xPos += trackingOffset;
+    }
+    if (this.textSpans[cnt]) {
+      this.textSpans[cnt].elem = commands;
+    } else {
+      this.textSpans[cnt] = { elem: commands };
+    }
+    cnt += 1;
+  }
+};
+
+CVTextElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  var ctx = this.canvasContext;
+  ctx.font = this.values.fValue;
+  this.globalData.renderer.ctxLineCap('butt');
+  // ctx.lineCap = 'butt';
+  this.globalData.renderer.ctxLineJoin('miter');
+  // ctx.lineJoin = 'miter';
+  this.globalData.renderer.ctxMiterLimit(4);
+  // ctx.miterLimit = 4;
+
+  if (!this.data.singleShape) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+  }
+
+  var i;
+  var len;
+  var j;
+  var jLen;
+  var k;
+  var kLen;
+  var renderedLetters = this.textAnimator.renderedLetters;
+
+  var letters = this.textProperty.currentData.l;
+
+  len = letters.length;
+  var renderedLetter;
+  var lastFill = null;
+  var lastStroke = null;
+  var lastStrokeW = null;
+  var commands;
+  var pathArr;
+  var renderer = this.globalData.renderer;
+  for (i = 0; i < len; i += 1) {
+    if (!letters[i].n) {
+      renderedLetter = renderedLetters[i];
+      if (renderedLetter) {
+        renderer.save();
+        renderer.ctxTransform(renderedLetter.p);
+        renderer.ctxOpacity(renderedLetter.o);
+      }
+      if (this.fill) {
+        if (renderedLetter && renderedLetter.fc) {
+          if (lastFill !== renderedLetter.fc) {
+            renderer.ctxFillStyle(renderedLetter.fc);
+            lastFill = renderedLetter.fc;
+            // ctx.fillStyle = renderedLetter.fc;
+          }
+        } else if (lastFill !== this.values.fill) {
+          lastFill = this.values.fill;
+          renderer.ctxFillStyle(this.values.fill);
+          // ctx.fillStyle = this.values.fill;
+        }
+        commands = this.textSpans[i].elem;
+        jLen = commands.length;
+        this.globalData.canvasContext.beginPath();
+        for (j = 0; j < jLen; j += 1) {
+          pathArr = commands[j];
+          kLen = pathArr.length;
+          this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
+          for (k = 2; k < kLen; k += 6) {
+            this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
+          }
+        }
+        this.globalData.canvasContext.closePath();
+        renderer.ctxFill();
+        // this.globalData.canvasContext.fill();
+        /// ctx.fillText(this.textSpans[i].val,0,0);
+      }
+      if (this.stroke) {
+        if (renderedLetter && renderedLetter.sw) {
+          if (lastStrokeW !== renderedLetter.sw) {
+            lastStrokeW = renderedLetter.sw;
+            renderer.ctxLineWidth(renderedLetter.sw);
+            // ctx.lineWidth = renderedLetter.sw;
+          }
+        } else if (lastStrokeW !== this.values.sWidth) {
+          lastStrokeW = this.values.sWidth;
+          renderer.ctxLineWidth(this.values.sWidth);
+          // ctx.lineWidth = this.values.sWidth;
+        }
+        if (renderedLetter && renderedLetter.sc) {
+          if (lastStroke !== renderedLetter.sc) {
+            lastStroke = renderedLetter.sc;
+            renderer.ctxStrokeStyle(renderedLetter.sc);
+            // ctx.strokeStyle = renderedLetter.sc;
+          }
+        } else if (lastStroke !== this.values.stroke) {
+          lastStroke = this.values.stroke;
+          renderer.ctxStrokeStyle(this.values.stroke);
+          // ctx.strokeStyle = this.values.stroke;
+        }
+        commands = this.textSpans[i].elem;
+        jLen = commands.length;
+        this.globalData.canvasContext.beginPath();
+        for (j = 0; j < jLen; j += 1) {
+          pathArr = commands[j];
+          kLen = pathArr.length;
+          this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
+          for (k = 2; k < kLen; k += 6) {
+            this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
+          }
+        }
+        this.globalData.canvasContext.closePath();
+        renderer.ctxStroke();
+        // this.globalData.canvasContext.stroke();
+        /// ctx.strokeText(letters[i].val,0,0);
+      }
+      if (renderedLetter) {
+        this.globalData.renderer.restore();
+      }
+    }
+  }
+};
+
+function CVImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  this.img = globalData.imageLoader.getAsset(this.assetData);
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVImageElement);
+
+CVImageElement.prototype.initElement = SVGShapeElement.prototype.initElement;
+CVImageElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
+
+CVImageElement.prototype.createContent = function () {
+  if (this.img.width && (this.assetData.w !== this.img.width || this.assetData.h !== this.img.height)) {
+    var canvas = createTag('canvas');
+    canvas.width = this.assetData.w;
+    canvas.height = this.assetData.h;
+    var ctx = canvas.getContext('2d');
+
+    var imgW = this.img.width;
+    var imgH = this.img.height;
+    var imgRel = imgW / imgH;
+    var canvasRel = this.assetData.w / this.assetData.h;
+    var widthCrop;
+    var heightCrop;
+    var par = this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio;
+    if ((imgRel > canvasRel && par === 'xMidYMid slice') || (imgRel < canvasRel && par !== 'xMidYMid slice')) {
+      heightCrop = imgH;
+      widthCrop = heightCrop * canvasRel;
+    } else {
+      widthCrop = imgW;
+      heightCrop = widthCrop / canvasRel;
+    }
+    ctx.drawImage(this.img, (imgW - widthCrop) / 2, (imgH - heightCrop) / 2, widthCrop, heightCrop, 0, 0, this.assetData.w, this.assetData.h);
+    this.img = canvas;
+  }
+};
+
+CVImageElement.prototype.renderInnerContent = function () {
+  this.canvasContext.drawImage(this.img, 0, 0);
+};
+
+CVImageElement.prototype.destroy = function () {
+  this.img = null;
+};
+
+function CVSolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVSolidElement);
+
+CVSolidElement.prototype.initElement = SVGShapeElement.prototype.initElement;
+CVSolidElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
+
+CVSolidElement.prototype.renderInnerContent = function () {
+  // var ctx = this.canvasContext;
+  this.globalData.renderer.ctxFillStyle(this.data.sc);
+  // ctx.fillStyle = this.data.sc;
+  this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh);
+  // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
+  //
+};
+
+function CanvasRendererBase() {
+}
+extendPrototype([BaseRenderer], CanvasRendererBase);
+
+CanvasRendererBase.prototype.createShape = function (data) {
+  return new CVShapeElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createText = function (data) {
+  return new CVTextElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createImage = function (data) {
+  return new CVImageElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createSolid = function (data) {
+  return new CVSolidElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
+
+CanvasRendererBase.prototype.ctxTransform = function (props) {
+  if (props[0] === 1 && props[1] === 0 && props[4] === 0 && props[5] === 1 && props[12] === 0 && props[13] === 0) {
+    return;
+  }
+  this.canvasContext.transform(props[0], props[1], props[4], props[5], props[12], props[13]);
+};
+
+CanvasRendererBase.prototype.ctxOpacity = function (op) {
+  this.canvasContext.globalAlpha *= op < 0 ? 0 : op;
+};
+
+CanvasRendererBase.prototype.ctxFillStyle = function (value) {
+  this.canvasContext.fillStyle = value;
+};
+
+CanvasRendererBase.prototype.ctxStrokeStyle = function (value) {
+  this.canvasContext.strokeStyle = value;
+};
+
+CanvasRendererBase.prototype.ctxLineWidth = function (value) {
+  this.canvasContext.lineWidth = value;
+};
+
+CanvasRendererBase.prototype.ctxLineCap = function (value) {
+  this.canvasContext.lineCap = value;
+};
+
+CanvasRendererBase.prototype.ctxLineJoin = function (value) {
+  this.canvasContext.lineJoin = value;
+};
+
+CanvasRendererBase.prototype.ctxMiterLimit = function (value) {
+  this.canvasContext.miterLimit = value;
+};
+
+CanvasRendererBase.prototype.ctxFill = function (rule) {
+  this.canvasContext.fill(rule);
+};
+
+CanvasRendererBase.prototype.ctxFillRect = function (x, y, w, h) {
+  this.canvasContext.fillRect(x, y, w, h);
+};
+
+CanvasRendererBase.prototype.ctxStroke = function () {
+  this.canvasContext.stroke();
+};
+
+CanvasRendererBase.prototype.reset = function () {
+  if (!this.renderConfig.clearCanvas) {
+    this.canvasContext.restore();
+    return;
+  }
+  this.contextData.reset();
+};
+
+CanvasRendererBase.prototype.save = function () {
+  this.canvasContext.save();
+};
+
+CanvasRendererBase.prototype.restore = function (actionFlag) {
+  if (!this.renderConfig.clearCanvas) {
+    this.canvasContext.restore();
+    return;
+  }
+  if (actionFlag) {
+    this.globalData.blendMode = 'source-over';
+  }
+  this.contextData.restore(actionFlag);
+};
+
+CanvasRendererBase.prototype.configAnimation = function (animData) {
+  if (this.animationItem.wrapper) {
+    this.animationItem.container = createTag('canvas');
+    var containerStyle = this.animationItem.container.style;
+    containerStyle.width = '100%';
+    containerStyle.height = '100%';
+    var origin = '0px 0px 0px';
+    containerStyle.transformOrigin = origin;
+    containerStyle.mozTransformOrigin = origin;
+    containerStyle.webkitTransformOrigin = origin;
+    containerStyle['-webkit-transform'] = origin;
+    containerStyle.contentVisibility = this.renderConfig.contentVisibility;
+    this.animationItem.wrapper.appendChild(this.animationItem.container);
+    this.canvasContext = this.animationItem.container.getContext('2d');
+    if (this.renderConfig.className) {
+      this.animationItem.container.setAttribute('class', this.renderConfig.className);
+    }
+    if (this.renderConfig.id) {
+      this.animationItem.container.setAttribute('id', this.renderConfig.id);
+    }
+  } else {
+    this.canvasContext = this.renderConfig.context;
+  }
+  this.contextData.setContext(this.canvasContext);
+  this.data = animData;
+  this.layers = animData.layers;
+  this.transformCanvas = {
+    w: animData.w,
+    h: animData.h,
+    sx: 0,
+    sy: 0,
+    tx: 0,
+    ty: 0,
+  };
+  this.setupGlobalData(animData, document.body);
+  this.globalData.canvasContext = this.canvasContext;
+  this.globalData.renderer = this;
+  this.globalData.isDashed = false;
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.globalData.transformCanvas = this.transformCanvas;
+  this.elements = createSizedArray(animData.layers.length);
+
+  this.updateContainerSize();
+};
+
+CanvasRendererBase.prototype.updateContainerSize = function (width, height) {
+  this.reset();
+  var elementWidth;
+  var elementHeight;
+  if (width) {
+    elementWidth = width;
+    elementHeight = height;
+    this.canvasContext.canvas.width = elementWidth;
+    this.canvasContext.canvas.height = elementHeight;
+  } else {
+    if (this.animationItem.wrapper && this.animationItem.container) {
+      elementWidth = this.animationItem.wrapper.offsetWidth;
+      elementHeight = this.animationItem.wrapper.offsetHeight;
+    } else {
+      elementWidth = this.canvasContext.canvas.width;
+      elementHeight = this.canvasContext.canvas.height;
+    }
+    this.canvasContext.canvas.width = elementWidth * this.renderConfig.dpr;
+    this.canvasContext.canvas.height = elementHeight * this.renderConfig.dpr;
+  }
+
+  var elementRel;
+  var animationRel;
+  if (this.renderConfig.preserveAspectRatio.indexOf('meet') !== -1 || this.renderConfig.preserveAspectRatio.indexOf('slice') !== -1) {
+    var par = this.renderConfig.preserveAspectRatio.split(' ');
+    var fillType = par[1] || 'meet';
+    var pos = par[0] || 'xMidYMid';
+    var xPos = pos.substr(0, 4);
+    var yPos = pos.substr(4);
+    elementRel = elementWidth / elementHeight;
+    animationRel = this.transformCanvas.w / this.transformCanvas.h;
+    if ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice')) {
+      this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+      this.transformCanvas.sy = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+    } else {
+      this.transformCanvas.sx = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+      this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+    }
+
+    if (xPos === 'xMid' && ((animationRel < elementRel && fillType === 'meet') || (animationRel > elementRel && fillType === 'slice'))) {
+      this.transformCanvas.tx = ((elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) / 2) * this.renderConfig.dpr;
+    } else if (xPos === 'xMax' && ((animationRel < elementRel && fillType === 'meet') || (animationRel > elementRel && fillType === 'slice'))) {
+      this.transformCanvas.tx = (elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) * this.renderConfig.dpr;
+    } else {
+      this.transformCanvas.tx = 0;
+    }
+    if (yPos === 'YMid' && ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice'))) {
+      this.transformCanvas.ty = ((elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w)) / 2) * this.renderConfig.dpr;
+    } else if (yPos === 'YMax' && ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice'))) {
+      this.transformCanvas.ty = ((elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w))) * this.renderConfig.dpr;
+    } else {
+      this.transformCanvas.ty = 0;
+    }
+  } else if (this.renderConfig.preserveAspectRatio === 'none') {
+    this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+    this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+    this.transformCanvas.tx = 0;
+    this.transformCanvas.ty = 0;
+  } else {
+    this.transformCanvas.sx = this.renderConfig.dpr;
+    this.transformCanvas.sy = this.renderConfig.dpr;
+    this.transformCanvas.tx = 0;
+    this.transformCanvas.ty = 0;
+  }
+  this.transformCanvas.props = [this.transformCanvas.sx, 0, 0, 0, 0, this.transformCanvas.sy, 0, 0, 0, 0, 1, 0, this.transformCanvas.tx, this.transformCanvas.ty, 0, 1];
+  /* var i, len = this.elements.length;
+    for(i=0;i<len;i+=1){
+        if(this.elements[i] && this.elements[i].data.ty === 0){
+            this.elements[i].resize(this.globalData.transformCanvas);
+        }
+    } */
+  this.ctxTransform(this.transformCanvas.props);
+  this.canvasContext.beginPath();
+  this.canvasContext.rect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
+  this.canvasContext.closePath();
+  this.canvasContext.clip();
+
+  this.renderFrame(this.renderedFrame, true);
+};
+
+CanvasRendererBase.prototype.destroy = function () {
+  if (this.renderConfig.clearCanvas && this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.globalData.canvasContext = null;
+  this.animationItem.container = null;
+  this.destroyed = true;
+};
+
+CanvasRendererBase.prototype.renderFrame = function (num, forceRender) {
+  if ((this.renderedFrame === num && this.renderConfig.clearCanvas === true && !forceRender) || this.destroyed || num === -1) {
+    return;
+  }
+  this.renderedFrame = num;
+  this.globalData.frameNum = num - this.animationItem._isFirstFrame;
+  this.globalData.frameId += 1;
+  this.globalData._mdf = !this.renderConfig.clearCanvas || forceRender;
+  this.globalData.projectInterface.currentFrame = num;
+
+  // console.log('--------');
+  // console.log('NEW: ',num);
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    if (this.renderConfig.clearCanvas === true) {
+      this.canvasContext.clearRect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
+    } else {
+      this.save();
+    }
+    for (i = len - 1; i >= 0; i -= 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+    if (this.renderConfig.clearCanvas !== true) {
+      this.restore();
+    }
+  }
+};
+
+CanvasRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  var element = this.createItem(this.layers[pos], this, this.globalData);
+  elements[pos] = element;
+  element.initExpressions();
+  /* if(this.layers[pos].ty === 0){
+        element.resize(this.globalData.transformCanvas);
+    } */
+};
+
+CanvasRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+  }
+};
+
+CanvasRendererBase.prototype.hide = function () {
+  this.animationItem.container.style.display = 'none';
+};
+
+CanvasRendererBase.prototype.show = function () {
+  this.animationItem.container.style.display = 'block';
+};
+
+function CanvasContext() {
+  this.opacity = -1;
+  this.transform = createTypedArray('float32', 16);
+  this.fillStyle = '';
+  this.strokeStyle = '';
+  this.lineWidth = '';
+  this.lineCap = '';
+  this.lineJoin = '';
+  this.miterLimit = '';
+  this.id = Math.random();
+}
+
+function CVContextData() {
+  this.stack = [];
+  this.cArrPos = 0;
+  this.cTr = new Matrix();
+  var i;
+  var len = 15;
+  for (i = 0; i < len; i += 1) {
+    var canvasContext = new CanvasContext();
+    this.stack[i] = canvasContext;
+  }
+  this._length = len;
+  this.nativeContext = null;
+  this.transformMat = new Matrix();
+  this.currentOpacity = 1;
+  //
+  this.currentFillStyle = '';
+  this.appliedFillStyle = '';
+  //
+  this.currentStrokeStyle = '';
+  this.appliedStrokeStyle = '';
+  //
+  this.currentLineWidth = '';
+  this.appliedLineWidth = '';
+  //
+  this.currentLineCap = '';
+  this.appliedLineCap = '';
+  //
+  this.currentLineJoin = '';
+  this.appliedLineJoin = '';
+  //
+  this.appliedMiterLimit = '';
+  this.currentMiterLimit = '';
+}
+
+CVContextData.prototype.duplicate = function () {
+  var newLength = this._length * 2;
+  var i = 0;
+  for (i = this._length; i < newLength; i += 1) {
+    this.stack[i] = new CanvasContext();
+  }
+  this._length = newLength;
+};
+
+CVContextData.prototype.reset = function () {
+  this.cArrPos = 0;
+  this.cTr.reset();
+  this.stack[this.cArrPos].opacity = 1;
+};
+
+CVContextData.prototype.restore = function (forceRestore) {
+  this.cArrPos -= 1;
+  var currentContext = this.stack[this.cArrPos];
+  var transform = currentContext.transform;
+  var i;
+  var arr = this.cTr.props;
+  for (i = 0; i < 16; i += 1) {
+    arr[i] = transform[i];
+  }
+  if (forceRestore) {
+    this.nativeContext.restore();
+    var prevStack = this.stack[this.cArrPos + 1];
+    this.appliedFillStyle = prevStack.fillStyle;
+    this.appliedStrokeStyle = prevStack.strokeStyle;
+    this.appliedLineWidth = prevStack.lineWidth;
+    this.appliedLineCap = prevStack.lineCap;
+    this.appliedLineJoin = prevStack.lineJoin;
+    this.appliedMiterLimit = prevStack.miterLimit;
+  }
+  this.nativeContext.setTransform(transform[0], transform[1], transform[4], transform[5], transform[12], transform[13]);
+  if (forceRestore || (currentContext.opacity !== -1 && this.currentOpacity !== currentContext.opacity)) {
+    this.nativeContext.globalAlpha = currentContext.opacity;
+    this.currentOpacity = currentContext.opacity;
+  }
+  this.currentFillStyle = currentContext.fillStyle;
+  this.currentStrokeStyle = currentContext.strokeStyle;
+  this.currentLineWidth = currentContext.lineWidth;
+  this.currentLineCap = currentContext.lineCap;
+  this.currentLineJoin = currentContext.lineJoin;
+  this.currentMiterLimit = currentContext.miterLimit;
+};
+
+CVContextData.prototype.save = function (saveOnNativeFlag) {
+  if (saveOnNativeFlag) {
+    this.nativeContext.save();
+  }
+  var props = this.cTr.props;
+  if (this._length <= this.cArrPos) {
+    this.duplicate();
+  }
+
+  var currentStack = this.stack[this.cArrPos];
+  var i;
+  for (i = 0; i < 16; i += 1) {
+    currentStack.transform[i] = props[i];
+  }
+  this.cArrPos += 1;
+  var newStack = this.stack[this.cArrPos];
+  newStack.opacity = currentStack.opacity;
+  newStack.fillStyle = currentStack.fillStyle;
+  newStack.strokeStyle = currentStack.strokeStyle;
+  newStack.lineWidth = currentStack.lineWidth;
+  newStack.lineCap = currentStack.lineCap;
+  newStack.lineJoin = currentStack.lineJoin;
+  newStack.miterLimit = currentStack.miterLimit;
+};
+
+CVContextData.prototype.setOpacity = function (value) {
+  this.stack[this.cArrPos].opacity = value;
+};
+
+CVContextData.prototype.setContext = function (value) {
+  this.nativeContext = value;
+};
+
+CVContextData.prototype.fillStyle = function (value) {
+  if (this.stack[this.cArrPos].fillStyle !== value) {
+    this.currentFillStyle = value;
+    this.stack[this.cArrPos].fillStyle = value;
+  }
+};
+
+CVContextData.prototype.strokeStyle = function (value) {
+  if (this.stack[this.cArrPos].strokeStyle !== value) {
+    this.currentStrokeStyle = value;
+    this.stack[this.cArrPos].strokeStyle = value;
+  }
+};
+
+CVContextData.prototype.lineWidth = function (value) {
+  if (this.stack[this.cArrPos].lineWidth !== value) {
+    this.currentLineWidth = value;
+    this.stack[this.cArrPos].lineWidth = value;
+  }
+};
+
+CVContextData.prototype.lineCap = function (value) {
+  if (this.stack[this.cArrPos].lineCap !== value) {
+    this.currentLineCap = value;
+    this.stack[this.cArrPos].lineCap = value;
+  }
+};
+
+CVContextData.prototype.lineJoin = function (value) {
+  if (this.stack[this.cArrPos].lineJoin !== value) {
+    this.currentLineJoin = value;
+    this.stack[this.cArrPos].lineJoin = value;
+  }
+};
+
+CVContextData.prototype.miterLimit = function (value) {
+  if (this.stack[this.cArrPos].miterLimit !== value) {
+    this.currentMiterLimit = value;
+    this.stack[this.cArrPos].miterLimit = value;
+  }
+};
+
+CVContextData.prototype.transform = function (props) {
+  this.transformMat.cloneFromProps(props);
+  // Taking the last transform value from the stored stack of transforms
+  var currentTransform = this.cTr;
+  // Applying the last transform value after the new transform to respect the order of transformations
+  this.transformMat.multiply(currentTransform);
+  // Storing the new transformed value in the stored transform
+  currentTransform.cloneFromProps(this.transformMat.props);
+  var trProps = currentTransform.props;
+  // Applying the new transform to the canvas
+  this.nativeContext.setTransform(trProps[0], trProps[1], trProps[4], trProps[5], trProps[12], trProps[13]);
+};
+
+CVContextData.prototype.opacity = function (op) {
+  var currentOpacity = this.stack[this.cArrPos].opacity;
+  currentOpacity *= op < 0 ? 0 : op;
+  if (this.stack[this.cArrPos].opacity !== currentOpacity) {
+    if (this.currentOpacity !== op) {
+      this.nativeContext.globalAlpha = op;
+      this.currentOpacity = op;
+    }
+    this.stack[this.cArrPos].opacity = currentOpacity;
+  }
+};
+
+CVContextData.prototype.fill = function (rule) {
+  if (this.appliedFillStyle !== this.currentFillStyle) {
+    this.appliedFillStyle = this.currentFillStyle;
+    this.nativeContext.fillStyle = this.appliedFillStyle;
+  }
+  this.nativeContext.fill(rule);
+};
+
+CVContextData.prototype.fillRect = function (x, y, w, h) {
+  if (this.appliedFillStyle !== this.currentFillStyle) {
+    this.appliedFillStyle = this.currentFillStyle;
+    this.nativeContext.fillStyle = this.appliedFillStyle;
+  }
+  this.nativeContext.fillRect(x, y, w, h);
+};
+
+CVContextData.prototype.stroke = function () {
+  if (this.appliedStrokeStyle !== this.currentStrokeStyle) {
+    this.appliedStrokeStyle = this.currentStrokeStyle;
+    this.nativeContext.strokeStyle = this.appliedStrokeStyle;
+  }
+  if (this.appliedLineWidth !== this.currentLineWidth) {
+    this.appliedLineWidth = this.currentLineWidth;
+    this.nativeContext.lineWidth = this.appliedLineWidth;
+  }
+  if (this.appliedLineCap !== this.currentLineCap) {
+    this.appliedLineCap = this.currentLineCap;
+    this.nativeContext.lineCap = this.appliedLineCap;
+  }
+  if (this.appliedLineJoin !== this.currentLineJoin) {
+    this.appliedLineJoin = this.currentLineJoin;
+    this.nativeContext.lineJoin = this.appliedLineJoin;
+  }
+  if (this.appliedMiterLimit !== this.currentMiterLimit) {
+    this.appliedMiterLimit = this.currentMiterLimit;
+    this.nativeContext.miterLimit = this.appliedMiterLimit;
+  }
+  this.nativeContext.stroke();
+};
+
+function CVCompElement(data, globalData, comp) {
+  this.completeLayers = false;
+  this.layers = data.layers;
+  this.pendingElements = [];
+  this.elements = createSizedArray(this.layers.length);
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([CanvasRendererBase, ICompElement, CVBaseElement], CVCompElement);
+
+CVCompElement.prototype.renderInnerContent = function () {
+  var ctx = this.canvasContext;
+  ctx.beginPath();
+  ctx.moveTo(0, 0);
+  ctx.lineTo(this.data.w, 0);
+  ctx.lineTo(this.data.w, this.data.h);
+  ctx.lineTo(0, this.data.h);
+  ctx.lineTo(0, 0);
+  ctx.clip();
+  var i;
+  var len = this.layers.length;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+CVCompElement.prototype.destroy = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+  this.layers = null;
+  this.elements = null;
+};
+
+CVCompElement.prototype.createComp = function (data) {
+  return new CVCompElement(data, this.globalData, this);
+};
+
+function CanvasRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.renderConfig = {
+    clearCanvas: (config && config.clearCanvas !== undefined) ? config.clearCanvas : true,
+    context: (config && config.context) || null,
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+  this.renderConfig.dpr = (config && config.dpr) || 1;
+  if (this.animationItem.wrapper) {
+    this.renderConfig.dpr = (config && config.dpr) || window.devicePixelRatio || 1;
+  }
+  this.renderedFrame = -1;
+  this.globalData = {
+    frameNum: -1,
+    _mdf: false,
+    renderConfig: this.renderConfig,
+    currentGlobalAlpha: -1,
+  };
+  this.contextData = new CVContextData();
+  this.elements = [];
+  this.pendingElements = [];
+  this.transformMat = new Matrix();
+  this.completeLayers = false;
+  this.rendererType = 'canvas';
+  if (this.renderConfig.clearCanvas) {
+    this.ctxTransform = this.contextData.transform.bind(this.contextData);
+    this.ctxOpacity = this.contextData.opacity.bind(this.contextData);
+    this.ctxFillStyle = this.contextData.fillStyle.bind(this.contextData);
+    this.ctxStrokeStyle = this.contextData.strokeStyle.bind(this.contextData);
+    this.ctxLineWidth = this.contextData.lineWidth.bind(this.contextData);
+    this.ctxLineCap = this.contextData.lineCap.bind(this.contextData);
+    this.ctxLineJoin = this.contextData.lineJoin.bind(this.contextData);
+    this.ctxMiterLimit = this.contextData.miterLimit.bind(this.contextData);
+    this.ctxFill = this.contextData.fill.bind(this.contextData);
+    this.ctxFillRect = this.contextData.fillRect.bind(this.contextData);
+    this.ctxStroke = this.contextData.stroke.bind(this.contextData);
+    this.save = this.contextData.save.bind(this.contextData);
+  }
+}
+extendPrototype([CanvasRendererBase], CanvasRenderer);
+
+CanvasRenderer.prototype.createComp = function (data) {
+  return new CVCompElement(data, this.globalData, this);
+};
+
+// Registering renderers
+registerRenderer('canvas', CanvasRenderer);
+
+// Registering shape modifiers
+ShapeModifiers.registerModifier('tm', TrimModifier);
+ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
+ShapeModifiers.registerModifier('rp', RepeaterModifier);
+ShapeModifiers.registerModifier('rd', RoundCornersModifier);
+ShapeModifiers.registerModifier('zz', ZigZagModifier);
+ShapeModifiers.registerModifier('op', OffsetPathModifier);
+
+const CompExpressionInterface = (function () {
+  return function (comp) {
+    function _thisLayerFunction(name) {
+      var i = 0;
+      var len = comp.layers.length;
+      while (i < len) {
+        if (comp.layers[i].nm === name || comp.layers[i].ind === name) {
+          return comp.elements[i].layerInterface;
+        }
+        i += 1;
+      }
+      return null;
+      // return {active:false};
+    }
+    Object.defineProperty(_thisLayerFunction, '_name', { value: comp.data.nm });
+    _thisLayerFunction.layer = _thisLayerFunction;
+    _thisLayerFunction.pixelAspect = 1;
+    _thisLayerFunction.height = comp.data.h || comp.globalData.compSize.h;
+    _thisLayerFunction.width = comp.data.w || comp.globalData.compSize.w;
+    _thisLayerFunction.pixelAspect = 1;
+    _thisLayerFunction.frameDuration = 1 / comp.globalData.frameRate;
+    _thisLayerFunction.displayStartTime = 0;
+    _thisLayerFunction.numLayers = comp.layers.length;
+    return _thisLayerFunction;
+  };
+}());
+
+/* eslint-disable */
+/*
+ Copyright 2014 David Bau.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ */
+
+function seedRandom(pool, math) {
+//
+// The following constants are related to IEEE 754 limits.
+//
+    var global = this,
+        width = 256,        // each RC4 output is 0 <= x < 256
+        chunks = 6,         // at least six RC4 outputs for each double
+        digits = 52,        // there are 52 significant digits in a double
+        rngname = 'random', // rngname: name for Math.random and Math.seedrandom
+        startdenom = math.pow(width, chunks),
+        significance = math.pow(2, digits),
+        overflow = significance * 2,
+        mask = width - 1,
+        nodecrypto;         // node.js crypto module, initialized at the bottom.
+
+//
+// seedrandom()
+// This is the seedrandom function described above.
+//
+    function seedrandom(seed, options, callback) {
+        var key = [];
+        options = (options === true) ? { entropy: true } : (options || {});
+
+        // Flatten the seed string or build one from local entropy if needed.
+        var shortseed = mixkey(flatten(
+            options.entropy ? [seed, tostring(pool)] :
+                (seed === null) ? autoseed() : seed, 3), key);
+
+        // Use the seed to initialize an ARC4 generator.
+        var arc4 = new ARC4(key);
+
+        // This function returns a random double in [0, 1) that contains
+        // randomness in every bit of the mantissa of the IEEE 754 value.
+        var prng = function() {
+            var n = arc4.g(chunks),             // Start with a numerator n < 2 ^ 48
+                d = startdenom,                 //   and denominator d = 2 ^ 48.
+                x = 0;                          //   and no 'extra last byte'.
+            while (n < significance) {          // Fill up all significant digits by
+                n = (n + x) * width;              //   shifting numerator and
+                d *= width;                       //   denominator and generating a
+                x = arc4.g(1);                    //   new least-significant-byte.
+            }
+            while (n >= overflow) {             // To avoid rounding up, before adding
+                n /= 2;                           //   last byte, shift everything
+                d /= 2;                           //   right using integer math until
+                x >>>= 1;                         //   we have exactly the desired bits.
+            }
+            return (n + x) / d;                 // Form the number within [0, 1).
+        };
+
+        prng.int32 = function() { return arc4.g(4) | 0; };
+        prng.quick = function() { return arc4.g(4) / 0x100000000; };
+        prng.double = prng;
+
+        // Mix the randomness into accumulated entropy.
+        mixkey(tostring(arc4.S), pool);
+
+        // Calling convention: what to return as a function of prng, seed, is_math.
+        return (options.pass || callback ||
+        function(prng, seed, is_math_call, state) {
+            if (state) {
+                // Load the arc4 state from the given state if it has an S array.
+                if (state.S) { copy(state, arc4); }
+                // Only provide the .state method if requested via options.state.
+                prng.state = function() { return copy(arc4, {}); };
+            }
+
+            // If called as a method of Math (Math.seedrandom()), mutate
+            // Math.random because that is how seedrandom.js has worked since v1.0.
+            if (is_math_call) { math[rngname] = prng; return seed; }
+
+            // Otherwise, it is a newer calling convention, so return the
+            // prng directly.
+            else return prng;
+        })(
+            prng,
+            shortseed,
+            'global' in options ? options.global : (this == math),
+            options.state);
+    }
+    math['seed' + rngname] = seedrandom;
+
+//
+// ARC4
+//
+// An ARC4 implementation.  The constructor takes a key in the form of
+// an array of at most (width) integers that should be 0 <= x < (width).
+//
+// The g(count) method returns a pseudorandom integer that concatenates
+// the next (count) outputs from ARC4.  Its return value is a number x
+// that is in the range 0 <= x < (width ^ count).
+//
+    function ARC4(key) {
+        var t, keylen = key.length,
+            me = this, i = 0, j = me.i = me.j = 0, s = me.S = [];
+
+        // The empty key [] is treated as [0].
+        if (!keylen) { key = [keylen++]; }
+
+        // Set up S using the standard key scheduling algorithm.
+        while (i < width) {
+            s[i] = i++;
+        }
+        for (i = 0; i < width; i++) {
+            s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))];
+            s[j] = t;
+        }
+
+        // The "g" method returns the next (count) outputs as one number.
+        me.g = function(count) {
+            // Using instance members instead of closure state nearly doubles speed.
+            var t, r = 0,
+                i = me.i, j = me.j, s = me.S;
+            while (count--) {
+                t = s[i = mask & (i + 1)];
+                r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))];
+            }
+            me.i = i; me.j = j;
+            return r;
+            // For robust unpredictability, the function call below automatically
+            // discards an initial batch of values.  This is called RC4-drop[256].
+            // See http://google.com/search?q=rsa+fluhrer+response&btnI
+        };
+    }
+
+//
+// copy()
+// Copies internal state of ARC4 to or from a plain object.
+//
+    function copy(f, t) {
+        t.i = f.i;
+        t.j = f.j;
+        t.S = f.S.slice();
+        return t;
+    }
+
+//
+// flatten()
+// Converts an object tree to nested arrays of strings.
+//
+    function flatten(obj, depth) {
+        var result = [], typ = (typeof obj), prop;
+        if (depth && typ == 'object') {
+            for (prop in obj) {
+                try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}
+            }
+        }
+        return (result.length ? result : typ == 'string' ? obj : obj + '\0');
+    }
+
+//
+// mixkey()
+// Mixes a string seed into a key that is an array of integers, and
+// returns a shortened string seed that is equivalent to the result key.
+//
+    function mixkey(seed, key) {
+        var stringseed = seed + '', smear, j = 0;
+        while (j < stringseed.length) {
+            key[mask & j] =
+                mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++));
+        }
+        return tostring(key);
+    }
+
+//
+// autoseed()
+// Returns an object for autoseeding, using window.crypto and Node crypto
+// module if available.
+//
+    function autoseed() {
+        try {
+            if (nodecrypto) { return tostring(nodecrypto.randomBytes(width)); }
+            var out = new Uint8Array(width);
+            (global.crypto || global.msCrypto).getRandomValues(out);
+            return tostring(out);
+        } catch (e) {
+            var browser = global.navigator,
+                plugins = browser && browser.plugins;
+            return [+new Date(), global, plugins, global.screen, tostring(pool)];
+        }
+    }
+
+//
+// tostring()
+// Converts an array of charcodes to a string
+//
+    function tostring(a) {
+        return String.fromCharCode.apply(0, a);
+    }
+
+//
+// When seedrandom.js is loaded, we immediately mix a few bits
+// from the built-in RNG into the entropy pool.  Because we do
+// not want to interfere with deterministic PRNG state later,
+// seedrandom will not call math.random on its own again after
+// initialization.
+//
+    mixkey(math.random(), pool);
+
+//
+// Nodejs and AMD support: export the implementation as a module using
+// either convention.
+//
+
+// End anonymous scope, and pass initial values.
+};
+
+function initialize$2(BMMath) {
+    seedRandom([], BMMath);
+}
+
+var propTypes = {
+  SHAPE: 'shape',
+};
+
+/* eslint-disable camelcase */
+
+const ExpressionManager = (function () {
+  'use strict';
+
+  var ob = {};
+  var Math = BMMath;
+  var window = null;
+  var document = null;
+  var XMLHttpRequest = null;
+  var fetch = null;
+  var frames = null;
+  var _lottieGlobal = {};
+  initialize$2(BMMath);
+
+  function resetFrame() {
+    _lottieGlobal = {};
+  }
+
+  function $bm_isInstanceOfArray(arr) {
+    return arr.constructor === Array || arr.constructor === Float32Array;
+  }
+
+  function isNumerable(tOfV, v) {
+    return tOfV === 'number' || v instanceof Number || tOfV === 'boolean' || tOfV === 'string';
+  }
+
+  function $bm_neg(a) {
+    var tOfA = typeof a;
+    if (tOfA === 'number' || a instanceof Number || tOfA === 'boolean') {
+      return -a;
+    }
+    if ($bm_isInstanceOfArray(a)) {
+      var i;
+      var lenA = a.length;
+      var retArr = [];
+      for (i = 0; i < lenA; i += 1) {
+        retArr[i] = -a[i];
+      }
+      return retArr;
+    }
+    if (a.propType) {
+      return a.v;
+    }
+    return -a;
+  }
+
+  var easeInBez = BezierFactory.getBezierEasing(0.333, 0, 0.833, 0.833, 'easeIn').get;
+  var easeOutBez = BezierFactory.getBezierEasing(0.167, 0.167, 0.667, 1, 'easeOut').get;
+  var easeInOutBez = BezierFactory.getBezierEasing(0.33, 0, 0.667, 1, 'easeInOut').get;
+
+  function sum(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    if ((isNumerable(tOfA, a) && isNumerable(tOfB, b)) || tOfA === 'string' || tOfB === 'string') {
+      return a + b;
+    }
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      a = a.slice(0);
+      a[0] += b;
+      return a;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      b = b.slice(0);
+      b[0] = a + b[0];
+      return b;
+    }
+    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
+      var i = 0;
+      var lenA = a.length;
+      var lenB = b.length;
+      var retArr = [];
+      while (i < lenA || i < lenB) {
+        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
+          retArr[i] = a[i] + b[i];
+        } else {
+          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
+        }
+        i += 1;
+      }
+      return retArr;
+    }
+    return 0;
+  }
+  var add = sum;
+
+  function sub(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      if (tOfA === 'string') {
+        a = parseInt(a, 10);
+      }
+      if (tOfB === 'string') {
+        b = parseInt(b, 10);
+      }
+      return a - b;
+    }
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      a = a.slice(0);
+      a[0] -= b;
+      return a;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      b = b.slice(0);
+      b[0] = a - b[0];
+      return b;
+    }
+    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
+      var i = 0;
+      var lenA = a.length;
+      var lenB = b.length;
+      var retArr = [];
+      while (i < lenA || i < lenB) {
+        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
+          retArr[i] = a[i] - b[i];
+        } else {
+          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
+        }
+        i += 1;
+      }
+      return retArr;
+    }
+    return 0;
+  }
+
+  function mul(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    var arr;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      return a * b;
+    }
+
+    var i;
+    var len;
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      len = a.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a[i] * b;
+      }
+      return arr;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      len = b.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a * b[i];
+      }
+      return arr;
+    }
+    return 0;
+  }
+
+  function div(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    var arr;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      return a / b;
+    }
+    var i;
+    var len;
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      len = a.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a[i] / b;
+      }
+      return arr;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      len = b.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a / b[i];
+      }
+      return arr;
+    }
+    return 0;
+  }
+  function mod(a, b) {
+    if (typeof a === 'string') {
+      a = parseInt(a, 10);
+    }
+    if (typeof b === 'string') {
+      b = parseInt(b, 10);
+    }
+    return a % b;
+  }
+  var $bm_sum = sum;
+  var $bm_sub = sub;
+  var $bm_mul = mul;
+  var $bm_div = div;
+  var $bm_mod = mod;
+
+  function clamp(num, min, max) {
+    if (min > max) {
+      var mm = max;
+      max = min;
+      min = mm;
+    }
+    return Math.min(Math.max(num, min), max);
+  }
+
+  function radiansToDegrees(val) {
+    return val / degToRads;
+  }
+  var radians_to_degrees = radiansToDegrees;
+
+  function degreesToRadians(val) {
+    return val * degToRads;
+  }
+  var degrees_to_radians = radiansToDegrees;
+
+  var helperLengthArray = [0, 0, 0, 0, 0, 0];
+
+  function length(arr1, arr2) {
+    if (typeof arr1 === 'number' || arr1 instanceof Number) {
+      arr2 = arr2 || 0;
+      return Math.abs(arr1 - arr2);
+    }
+    if (!arr2) {
+      arr2 = helperLengthArray;
+    }
+    var i;
+    var len = Math.min(arr1.length, arr2.length);
+    var addedLength = 0;
+    for (i = 0; i < len; i += 1) {
+      addedLength += Math.pow(arr2[i] - arr1[i], 2);
+    }
+    return Math.sqrt(addedLength);
+  }
+
+  function normalize(vec) {
+    return div(vec, length(vec));
+  }
+
+  function rgbToHsl(val) {
+    var r = val[0]; var g = val[1]; var b = val[2];
+    var max = Math.max(r, g, b);
+    var min = Math.min(r, g, b);
+    var h;
+    var s;
+    var l = (max + min) / 2;
+
+    if (max === min) {
+      h = 0; // achromatic
+      s = 0; // achromatic
+    } else {
+      var d = max - min;
+      s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+      switch (max) {
+        case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+        case g: h = (b - r) / d + 2; break;
+        case b: h = (r - g) / d + 4; break;
+        default: break;
+      }
+      h /= 6;
+    }
+
+    return [h, s, l, val[3]];
+  }
+
+  function hue2rgb(p, q, t) {
+    if (t < 0) t += 1;
+    if (t > 1) t -= 1;
+    if (t < 1 / 6) return p + (q - p) * 6 * t;
+    if (t < 1 / 2) return q;
+    if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
+    return p;
+  }
+
+  function hslToRgb(val) {
+    var h = val[0];
+    var s = val[1];
+    var l = val[2];
+
+    var r;
+    var g;
+    var b;
+
+    if (s === 0) {
+      r = l; // achromatic
+      b = l; // achromatic
+      g = l; // achromatic
+    } else {
+      var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+      var p = 2 * l - q;
+      r = hue2rgb(p, q, h + 1 / 3);
+      g = hue2rgb(p, q, h);
+      b = hue2rgb(p, q, h - 1 / 3);
+    }
+
+    return [r, g, b, val[3]];
+  }
+
+  function linear(t, tMin, tMax, value1, value2) {
+    if (value1 === undefined || value2 === undefined) {
+      value1 = tMin;
+      value2 = tMax;
+      tMin = 0;
+      tMax = 1;
+    }
+    if (tMax < tMin) {
+      var _tMin = tMax;
+      tMax = tMin;
+      tMin = _tMin;
+    }
+    if (t <= tMin) {
+      return value1;
+    } if (t >= tMax) {
+      return value2;
+    }
+    var perc = tMax === tMin ? 0 : (t - tMin) / (tMax - tMin);
+    if (!value1.length) {
+      return value1 + (value2 - value1) * perc;
+    }
+    var i;
+    var len = value1.length;
+    var arr = createTypedArray('float32', len);
+    for (i = 0; i < len; i += 1) {
+      arr[i] = value1[i] + (value2[i] - value1[i]) * perc;
+    }
+    return arr;
+  }
+  function random(min, max) {
+    if (max === undefined) {
+      if (min === undefined) {
+        min = 0;
+        max = 1;
+      } else {
+        max = min;
+        min = undefined;
+      }
+    }
+    if (max.length) {
+      var i;
+      var len = max.length;
+      if (!min) {
+        min = createTypedArray('float32', len);
+      }
+      var arr = createTypedArray('float32', len);
+      var rnd = BMMath.random();
+      for (i = 0; i < len; i += 1) {
+        arr[i] = min[i] + rnd * (max[i] - min[i]);
+      }
+      return arr;
+    }
+    if (min === undefined) {
+      min = 0;
+    }
+    var rndm = BMMath.random();
+    return min + rndm * (max - min);
+  }
+
+  function createPath(points, inTangents, outTangents, closed) {
+    var i;
+    var len = points.length;
+    var path = shapePool.newElement();
+    path.setPathData(!!closed, len);
+    var arrPlaceholder = [0, 0];
+    var inVertexPoint;
+    var outVertexPoint;
+    for (i = 0; i < len; i += 1) {
+      inVertexPoint = (inTangents && inTangents[i]) ? inTangents[i] : arrPlaceholder;
+      outVertexPoint = (outTangents && outTangents[i]) ? outTangents[i] : arrPlaceholder;
+      path.setTripleAt(points[i][0], points[i][1], outVertexPoint[0] + points[i][0], outVertexPoint[1] + points[i][1], inVertexPoint[0] + points[i][0], inVertexPoint[1] + points[i][1], i, true);
+    }
+    return path;
+  }
+
+  function initiateExpression(elem, data, property) {
+    // Bail out if we don't want expressions
+    function noOp(_value) {
+      return _value;
+    }
+    if (!elem.globalData.renderConfig.runExpressions) {
+      return noOp;
+    }
+
+    var val = data.x;
+    var needsVelocity = /velocity(?![\w\d])/.test(val);
+    var _needsRandom = val.indexOf('random') !== -1;
+    var elemType = elem.data.ty;
+    var transform;
+    var $bm_transform;
+    var content;
+    var effect;
+    var thisProperty = property;
+    thisProperty._name = elem.data.nm;
+    thisProperty.valueAtTime = thisProperty.getValueAtTime;
+    Object.defineProperty(thisProperty, 'value', {
+      get: function () {
+        return thisProperty.v;
+      },
+    });
+    elem.comp.frameDuration = 1 / elem.comp.globalData.frameRate;
+    elem.comp.displayStartTime = 0;
+    var inPoint = elem.data.ip / elem.comp.globalData.frameRate;
+    var outPoint = elem.data.op / elem.comp.globalData.frameRate;
+    var width = elem.data.sw ? elem.data.sw : 0;
+    var height = elem.data.sh ? elem.data.sh : 0;
+    var name = elem.data.nm;
+    var loopIn;
+    var loop_in;
+    var loopOut;
+    var loop_out;
+    var smooth;
+    var toWorld;
+    var fromWorld;
+    var fromComp;
+    var toComp;
+    var fromCompToSurface;
+    var position;
+    var rotation;
+    var anchorPoint;
+    var scale;
+    var thisLayer;
+    var thisComp;
+    var mask;
+    var valueAtTime;
+    var velocityAtTime;
+
+    var scoped_bm_rt;
+    // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
+    var expression_function = eval('[function _expression_function(){' + val + ';scoped_bm_rt=$bm_rt}]')[0]; // eslint-disable-line no-eval
+    var numKeys = property.kf ? data.k.length : 0;
+
+    var active = !this.data || this.data.hd !== true;
+
+    var wiggle = function wiggle(freq, amp) {
+      var iWiggle;
+      var j;
+      var lenWiggle = this.pv.length ? this.pv.length : 1;
+      var addedAmps = createTypedArray('float32', lenWiggle);
+      freq = 5;
+      var iterations = Math.floor(time * freq);
+      iWiggle = 0;
+      j = 0;
+      while (iWiggle < iterations) {
+        // var rnd = BMMath.random();
+        for (j = 0; j < lenWiggle; j += 1) {
+          addedAmps[j] += -amp + amp * 2 * BMMath.random();
+          // addedAmps[j] += -amp + amp*2*rnd;
+        }
+        iWiggle += 1;
+      }
+      // var rnd2 = BMMath.random();
+      var periods = time * freq;
+      var perc = periods - Math.floor(periods);
+      var arr = createTypedArray('float32', lenWiggle);
+      if (lenWiggle > 1) {
+        for (j = 0; j < lenWiggle; j += 1) {
+          arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc;
+          // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
+          // arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc);
+        }
+        return arr;
+      }
+      return this.pv + addedAmps[0] + (-amp + amp * 2 * BMMath.random()) * perc;
+    }.bind(this);
+
+    if (thisProperty.loopIn) {
+      loopIn = thisProperty.loopIn.bind(thisProperty);
+      loop_in = loopIn;
+    }
+
+    if (thisProperty.loopOut) {
+      loopOut = thisProperty.loopOut.bind(thisProperty);
+      loop_out = loopOut;
+    }
+
+    if (thisProperty.smooth) {
+      smooth = thisProperty.smooth.bind(thisProperty);
+    }
+
+    function loopInDuration(type, duration) {
+      return loopIn(type, duration, true);
+    }
+
+    function loopOutDuration(type, duration) {
+      return loopOut(type, duration, true);
+    }
+
+    if (this.getValueAtTime) {
+      valueAtTime = this.getValueAtTime.bind(this);
+    }
+
+    if (this.getVelocityAtTime) {
+      velocityAtTime = this.getVelocityAtTime.bind(this);
+    }
+
+    var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface);
+
+    function lookAt(elem1, elem2) {
+      var fVec = [elem2[0] - elem1[0], elem2[1] - elem1[1], elem2[2] - elem1[2]];
+      var pitch = Math.atan2(fVec[0], Math.sqrt(fVec[1] * fVec[1] + fVec[2] * fVec[2])) / degToRads;
+      var yaw = -Math.atan2(fVec[1], fVec[2]) / degToRads;
+      return [yaw, pitch, 0];
+    }
+
+    function easeOut(t, tMin, tMax, val1, val2) {
+      return applyEase(easeOutBez, t, tMin, tMax, val1, val2);
+    }
+
+    function easeIn(t, tMin, tMax, val1, val2) {
+      return applyEase(easeInBez, t, tMin, tMax, val1, val2);
+    }
+
+    function ease(t, tMin, tMax, val1, val2) {
+      return applyEase(easeInOutBez, t, tMin, tMax, val1, val2);
+    }
+
+    function applyEase(fn, t, tMin, tMax, val1, val2) {
+      if (val1 === undefined) {
+        val1 = tMin;
+        val2 = tMax;
+      } else {
+        t = (t - tMin) / (tMax - tMin);
+      }
+      if (t > 1) {
+        t = 1;
+      } else if (t < 0) {
+        t = 0;
+      }
+      var mult = fn(t);
+      if ($bm_isInstanceOfArray(val1)) {
+        var iKey;
+        var lenKey = val1.length;
+        var arr = createTypedArray('float32', lenKey);
+        for (iKey = 0; iKey < lenKey; iKey += 1) {
+          arr[iKey] = (val2[iKey] - val1[iKey]) * mult + val1[iKey];
+        }
+        return arr;
+      }
+      return (val2 - val1) * mult + val1;
+    }
+
+    function nearestKey(time) {
+      var iKey;
+      var lenKey = data.k.length;
+      var index;
+      var keyTime;
+      if (!data.k.length || typeof (data.k[0]) === 'number') {
+        index = 0;
+        keyTime = 0;
+      } else {
+        index = -1;
+        time *= elem.comp.globalData.frameRate;
+        if (time < data.k[0].t) {
+          index = 1;
+          keyTime = data.k[0].t;
+        } else {
+          for (iKey = 0; iKey < lenKey - 1; iKey += 1) {
+            if (time === data.k[iKey].t) {
+              index = iKey + 1;
+              keyTime = data.k[iKey].t;
+              break;
+            } else if (time > data.k[iKey].t && time < data.k[iKey + 1].t) {
+              if (time - data.k[iKey].t > data.k[iKey + 1].t - time) {
+                index = iKey + 2;
+                keyTime = data.k[iKey + 1].t;
+              } else {
+                index = iKey + 1;
+                keyTime = data.k[iKey].t;
+              }
+              break;
+            }
+          }
+          if (index === -1) {
+            index = iKey + 1;
+            keyTime = data.k[iKey].t;
+          }
+        }
+      }
+      var obKey = {};
+      obKey.index = index;
+      obKey.time = keyTime / elem.comp.globalData.frameRate;
+      return obKey;
+    }
+
+    function key(ind) {
+      var obKey;
+      var iKey;
+      var lenKey;
+      if (!data.k.length || typeof (data.k[0]) === 'number') {
+        throw new Error('The property has no keyframe at index ' + ind);
+      }
+      ind -= 1;
+      obKey = {
+        time: data.k[ind].t / elem.comp.globalData.frameRate,
+        value: [],
+      };
+      var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e;
+
+      lenKey = arr.length;
+      for (iKey = 0; iKey < lenKey; iKey += 1) {
+        obKey[iKey] = arr[iKey];
+        obKey.value[iKey] = arr[iKey];
+      }
+      return obKey;
+    }
+
+    function framesToTime(fr, fps) {
+      if (!fps) {
+        fps = elem.comp.globalData.frameRate;
+      }
+      return fr / fps;
+    }
+
+    function timeToFrames(t, fps) {
+      if (!t && t !== 0) {
+        t = time;
+      }
+      if (!fps) {
+        fps = elem.comp.globalData.frameRate;
+      }
+      return t * fps;
+    }
+
+    function seedRandom(seed) {
+      BMMath.seedrandom(randSeed + seed);
+    }
+
+    function sourceRectAtTime() {
+      return elem.sourceRectAtTime();
+    }
+
+    function substring(init, end) {
+      if (typeof value === 'string') {
+        if (end === undefined) {
+          return value.substring(init);
+        }
+        return value.substring(init, end);
+      }
+      return '';
+    }
+
+    function substr(init, end) {
+      if (typeof value === 'string') {
+        if (end === undefined) {
+          return value.substr(init);
+        }
+        return value.substr(init, end);
+      }
+      return '';
+    }
+
+    function posterizeTime(framesPerSecond) {
+      time = framesPerSecond === 0 ? 0 : Math.floor(time * framesPerSecond) / framesPerSecond;
+      value = valueAtTime(time);
+    }
+
+    var time;
+    var velocity;
+    var value;
+    var text;
+    var textIndex;
+    var textTotal;
+    var selectorValue;
+    var index = elem.data.ind;
+    var hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+    var parent;
+    var randSeed = Math.floor(Math.random() * 1000000);
+    var globalData = elem.globalData;
+
+    function executeExpression(_value) {
+      // globalData.pushExpression();
+      value = _value;
+      if (this.frameExpressionId === elem.globalData.frameId && this.propType !== 'textSelector') {
+        return value;
+      }
+      if (this.propType === 'textSelector') {
+        textIndex = this.textIndex;
+        textTotal = this.textTotal;
+        selectorValue = this.selectorValue;
+      }
+      if (!thisLayer) {
+        text = elem.layerInterface.text;
+        thisLayer = elem.layerInterface;
+        thisComp = elem.comp.compInterface;
+        toWorld = thisLayer.toWorld.bind(thisLayer);
+        fromWorld = thisLayer.fromWorld.bind(thisLayer);
+        fromComp = thisLayer.fromComp.bind(thisLayer);
+        toComp = thisLayer.toComp.bind(thisLayer);
+        mask = thisLayer.mask ? thisLayer.mask.bind(thisLayer) : null;
+        fromCompToSurface = fromComp;
+      }
+      if (!transform) {
+        transform = elem.layerInterface('ADBE Transform Group');
+        $bm_transform = transform;
+        if (transform) {
+          anchorPoint = transform.anchorPoint;
+          /* position = transform.position;
+                    rotation = transform.rotation;
+                    scale = transform.scale; */
+        }
+      }
+
+      if (elemType === 4 && !content) {
+        content = thisLayer('ADBE Root Vectors Group');
+      }
+      if (!effect) {
+        effect = thisLayer(4);
+      }
+      hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+      if (hasParent && !parent) {
+        parent = elem.hierarchy[0].layerInterface;
+      }
+      time = this.comp.renderedFrame / this.comp.globalData.frameRate;
+      if (_needsRandom) {
+        seedRandom(randSeed + time);
+      }
+      if (needsVelocity) {
+        velocity = velocityAtTime(time);
+      }
+      expression_function();
+      this.frameExpressionId = elem.globalData.frameId;
+
+      // TODO: Check if it's possible to return on ShapeInterface the .v value
+      // Changed this to a ternary operation because Rollup failed compiling it correctly
+      scoped_bm_rt = scoped_bm_rt.propType === propTypes.SHAPE
+        ? scoped_bm_rt.v
+        : scoped_bm_rt;
+      return scoped_bm_rt;
+    }
+    // Bundlers will see these as dead code and unless we reference them
+    executeExpression.__preventDeadCodeRemoval = [$bm_transform, anchorPoint, time, velocity, inPoint, outPoint, width, height, name, loop_in, loop_out, smooth, toComp, fromCompToSurface, toWorld, fromWorld, mask, position, rotation, scale, thisComp, numKeys, active, wiggle, loopInDuration, loopOutDuration, comp, lookAt, easeOut, easeIn, ease, nearestKey, key, text, textIndex, textTotal, selectorValue, framesToTime, timeToFrames, sourceRectAtTime, substring, substr, posterizeTime, index, globalData];
+    return executeExpression;
+  }
+
+  ob.initiateExpression = initiateExpression;
+  ob.__preventDeadCodeRemoval = [window, document, XMLHttpRequest, fetch, frames, $bm_neg, add, $bm_sum, $bm_sub, $bm_mul, $bm_div, $bm_mod, clamp, radians_to_degrees, degreesToRadians, degrees_to_radians, normalize, rgbToHsl, hslToRgb, linear, random, createPath, _lottieGlobal];
+  ob.resetFrame = resetFrame;
+  return ob;
+}());
+
+const Expressions = (function () {
+  var ob = {};
+  ob.initExpressions = initExpressions;
+  ob.resetFrame = ExpressionManager.resetFrame;
+
+  function initExpressions(animation) {
+    var stackCount = 0;
+    var registers = [];
+
+    function pushExpression() {
+      stackCount += 1;
+    }
+
+    function popExpression() {
+      stackCount -= 1;
+      if (stackCount === 0) {
+        releaseInstances();
+      }
+    }
+
+    function registerExpressionProperty(expression) {
+      if (registers.indexOf(expression) === -1) {
+        registers.push(expression);
+      }
+    }
+
+    function releaseInstances() {
+      var i;
+      var len = registers.length;
+      for (i = 0; i < len; i += 1) {
+        registers[i].release();
+      }
+      registers.length = 0;
+    }
+
+    animation.renderer.compInterface = CompExpressionInterface(animation.renderer);
+    animation.renderer.globalData.projectInterface.registerComposition(animation.renderer);
+    animation.renderer.globalData.pushExpression = pushExpression;
+    animation.renderer.globalData.popExpression = popExpression;
+    animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty;
+  }
+  return ob;
+}());
+
+const MaskManagerInterface = (function () {
+  function MaskInterface(mask, data) {
+    this._mask = mask;
+    this._data = data;
+  }
+  Object.defineProperty(MaskInterface.prototype, 'maskPath', {
+    get: function () {
+      if (this._mask.prop.k) {
+        this._mask.prop.getValue();
+      }
+      return this._mask.prop;
+    },
+  });
+  Object.defineProperty(MaskInterface.prototype, 'maskOpacity', {
+    get: function () {
+      if (this._mask.op.k) {
+        this._mask.op.getValue();
+      }
+      return this._mask.op.v * 100;
+    },
+  });
+
+  var MaskManager = function (maskManager) {
+    var _masksInterfaces = createSizedArray(maskManager.viewData.length);
+    var i;
+    var len = maskManager.viewData.length;
+    for (i = 0; i < len; i += 1) {
+      _masksInterfaces[i] = new MaskInterface(maskManager.viewData[i], maskManager.masksProperties[i]);
+    }
+
+    var maskFunction = function (name) {
+      i = 0;
+      while (i < len) {
+        if (maskManager.masksProperties[i].nm === name) {
+          return _masksInterfaces[i];
+        }
+        i += 1;
+      }
+      return null;
+    };
+    return maskFunction;
+  };
+  return MaskManager;
+}());
+
+const ExpressionPropertyInterface = (function () {
+  var defaultUnidimensionalValue = { pv: 0, v: 0, mult: 1 };
+  var defaultMultidimensionalValue = { pv: [0, 0, 0], v: [0, 0, 0], mult: 1 };
+
+  function completeProperty(expressionValue, property, type) {
+    Object.defineProperty(expressionValue, 'velocity', {
+      get: function () {
+        return property.getVelocityAtTime(property.comp.currentFrame);
+      },
+    });
+    expressionValue.numKeys = property.keyframes ? property.keyframes.length : 0;
+    expressionValue.key = function (pos) {
+      if (!expressionValue.numKeys) {
+        return 0;
+      }
+      var value = '';
+      if ('s' in property.keyframes[pos - 1]) {
+        value = property.keyframes[pos - 1].s;
+      } else if ('e' in property.keyframes[pos - 2]) {
+        value = property.keyframes[pos - 2].e;
+      } else {
+        value = property.keyframes[pos - 2].s;
+      }
+      var valueProp = type === 'unidimensional' ? new Number(value) : Object.assign({}, value); // eslint-disable-line no-new-wrappers
+      valueProp.time = property.keyframes[pos - 1].t / property.elem.comp.globalData.frameRate;
+      valueProp.value = type === 'unidimensional' ? value[0] : value;
+      return valueProp;
+    };
+    expressionValue.valueAtTime = property.getValueAtTime;
+    expressionValue.speedAtTime = property.getSpeedAtTime;
+    expressionValue.velocityAtTime = property.getVelocityAtTime;
+    expressionValue.propertyGroup = property.propertyGroup;
+  }
+
+  function UnidimensionalPropertyInterface(property) {
+    if (!property || !('pv' in property)) {
+      property = defaultUnidimensionalValue;
+    }
+    var mult = 1 / property.mult;
+    var val = property.pv * mult;
+    var expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
+    expressionValue.value = val;
+    completeProperty(expressionValue, property, 'unidimensional');
+
+    return function () {
+      if (property.k) {
+        property.getValue();
+      }
+      val = property.v * mult;
+      if (expressionValue.value !== val) {
+        expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
+        expressionValue.value = val;
+        expressionValue[0] = val;
+        completeProperty(expressionValue, property, 'unidimensional');
+      }
+      return expressionValue;
+    };
+  }
+
+  function MultidimensionalPropertyInterface(property) {
+    if (!property || !('pv' in property)) {
+      property = defaultMultidimensionalValue;
+    }
+    var mult = 1 / property.mult;
+    var len = (property.data && property.data.l) || property.pv.length;
+    var expressionValue = createTypedArray('float32', len);
+    var arrValue = createTypedArray('float32', len);
+    expressionValue.value = arrValue;
+    completeProperty(expressionValue, property, 'multidimensional');
+
+    return function () {
+      if (property.k) {
+        property.getValue();
+      }
+      for (var i = 0; i < len; i += 1) {
+        arrValue[i] = property.v[i] * mult;
+        expressionValue[i] = arrValue[i];
+      }
+      return expressionValue;
+    };
+  }
+
+  // TODO: try to avoid using this getter
+  function defaultGetter() {
+    return defaultUnidimensionalValue;
+  }
+
+  return function (property) {
+    if (!property) {
+      return defaultGetter;
+    } if (property.propType === 'unidimensional') {
+      return UnidimensionalPropertyInterface(property);
+    }
+    return MultidimensionalPropertyInterface(property);
+  };
+}());
+
+const TransformExpressionInterface = (function () {
+  return function (transform) {
+    function _thisFunction(name) {
+      switch (name) {
+        case 'scale':
+        case 'Scale':
+        case 'ADBE Scale':
+        case 6:
+          return _thisFunction.scale;
+        case 'rotation':
+        case 'Rotation':
+        case 'ADBE Rotation':
+        case 'ADBE Rotate Z':
+        case 10:
+          return _thisFunction.rotation;
+        case 'ADBE Rotate X':
+          return _thisFunction.xRotation;
+        case 'ADBE Rotate Y':
+          return _thisFunction.yRotation;
+        case 'position':
+        case 'Position':
+        case 'ADBE Position':
+        case 2:
+          return _thisFunction.position;
+        case 'ADBE Position_0':
+          return _thisFunction.xPosition;
+        case 'ADBE Position_1':
+          return _thisFunction.yPosition;
+        case 'ADBE Position_2':
+          return _thisFunction.zPosition;
+        case 'anchorPoint':
+        case 'AnchorPoint':
+        case 'Anchor Point':
+        case 'ADBE AnchorPoint':
+        case 1:
+          return _thisFunction.anchorPoint;
+        case 'opacity':
+        case 'Opacity':
+        case 11:
+          return _thisFunction.opacity;
+        default:
+          return null;
+      }
+    }
+    Object.defineProperty(_thisFunction, 'rotation', {
+      get: ExpressionPropertyInterface(transform.r || transform.rz),
+    });
+
+    Object.defineProperty(_thisFunction, 'zRotation', {
+      get: ExpressionPropertyInterface(transform.rz || transform.r),
+    });
+
+    Object.defineProperty(_thisFunction, 'xRotation', {
+      get: ExpressionPropertyInterface(transform.rx),
+    });
+
+    Object.defineProperty(_thisFunction, 'yRotation', {
+      get: ExpressionPropertyInterface(transform.ry),
+    });
+    Object.defineProperty(_thisFunction, 'scale', {
+      get: ExpressionPropertyInterface(transform.s),
+    });
+    var _px;
+    var _py;
+    var _pz;
+    var _transformFactory;
+    if (transform.p) {
+      _transformFactory = ExpressionPropertyInterface(transform.p);
+    } else {
+      _px = ExpressionPropertyInterface(transform.px);
+      _py = ExpressionPropertyInterface(transform.py);
+      if (transform.pz) {
+        _pz = ExpressionPropertyInterface(transform.pz);
+      }
+    }
+    Object.defineProperty(_thisFunction, 'position', {
+      get: function () {
+        if (transform.p) {
+          return _transformFactory();
+        }
+        return [
+          _px(),
+          _py(),
+          _pz ? _pz() : 0];
+      },
+    });
+
+    Object.defineProperty(_thisFunction, 'xPosition', {
+      get: ExpressionPropertyInterface(transform.px),
+    });
+
+    Object.defineProperty(_thisFunction, 'yPosition', {
+      get: ExpressionPropertyInterface(transform.py),
+    });
+
+    Object.defineProperty(_thisFunction, 'zPosition', {
+      get: ExpressionPropertyInterface(transform.pz),
+    });
+
+    Object.defineProperty(_thisFunction, 'anchorPoint', {
+      get: ExpressionPropertyInterface(transform.a),
+    });
+
+    Object.defineProperty(_thisFunction, 'opacity', {
+      get: ExpressionPropertyInterface(transform.o),
+    });
+
+    Object.defineProperty(_thisFunction, 'skew', {
+      get: ExpressionPropertyInterface(transform.sk),
+    });
+
+    Object.defineProperty(_thisFunction, 'skewAxis', {
+      get: ExpressionPropertyInterface(transform.sa),
+    });
+
+    Object.defineProperty(_thisFunction, 'orientation', {
+      get: ExpressionPropertyInterface(transform.or),
+    });
+
+    return _thisFunction;
+  };
+}());
+
+const LayerExpressionInterface = (function () {
+  function getMatrix(time) {
+    var toWorldMat = new Matrix();
+    if (time !== undefined) {
+      var propMatrix = this._elem.finalTransform.mProp.getValueAtTime(time);
+      propMatrix.clone(toWorldMat);
+    } else {
+      var transformMat = this._elem.finalTransform.mProp;
+      transformMat.applyToMatrix(toWorldMat);
+    }
+    return toWorldMat;
+  }
+
+  function toWorldVec(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    toWorldMat.props[12] = 0;
+    toWorldMat.props[13] = 0;
+    toWorldMat.props[14] = 0;
+    return this.applyPoint(toWorldMat, arr);
+  }
+
+  function toWorld(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    return this.applyPoint(toWorldMat, arr);
+  }
+
+  function fromWorldVec(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    toWorldMat.props[12] = 0;
+    toWorldMat.props[13] = 0;
+    toWorldMat.props[14] = 0;
+    return this.invertPoint(toWorldMat, arr);
+  }
+
+  function fromWorld(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    return this.invertPoint(toWorldMat, arr);
+  }
+
+  function applyPoint(matrix, arr) {
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
+      }
+    }
+    return matrix.applyToPointArray(arr[0], arr[1], arr[2] || 0);
+  }
+
+  function invertPoint(matrix, arr) {
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
+      }
+    }
+    return matrix.inversePoint(arr);
+  }
+
+  function fromComp(arr) {
+    var toWorldMat = new Matrix();
+    toWorldMat.reset();
+    this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
+      }
+      return toWorldMat.inversePoint(arr);
+    }
+    return toWorldMat.inversePoint(arr);
+  }
+
+  function sampleImage() {
+    return [1, 1, 1, 1];
+  }
+
+  return function (elem) {
+    var transformInterface;
+
+    function _registerMaskInterface(maskManager) {
+      _thisLayerFunction.mask = new MaskManagerInterface(maskManager, elem);
+    }
+    function _registerEffectsInterface(effects) {
+      _thisLayerFunction.effect = effects;
+    }
+
+    function _thisLayerFunction(name) {
+      switch (name) {
+        case 'ADBE Root Vectors Group':
+        case 'Contents':
+        case 2:
+          return _thisLayerFunction.shapeInterface;
+        case 1:
+        case 6:
+        case 'Transform':
+        case 'transform':
+        case 'ADBE Transform Group':
+          return transformInterface;
+        case 4:
+        case 'ADBE Effect Parade':
+        case 'effects':
+        case 'Effects':
+          return _thisLayerFunction.effect;
+        case 'ADBE Text Properties':
+          return _thisLayerFunction.textInterface;
+        default:
+          return null;
+      }
+    }
+    _thisLayerFunction.getMatrix = getMatrix;
+    _thisLayerFunction.invertPoint = invertPoint;
+    _thisLayerFunction.applyPoint = applyPoint;
+    _thisLayerFunction.toWorld = toWorld;
+    _thisLayerFunction.toWorldVec = toWorldVec;
+    _thisLayerFunction.fromWorld = fromWorld;
+    _thisLayerFunction.fromWorldVec = fromWorldVec;
+    _thisLayerFunction.toComp = toWorld;
+    _thisLayerFunction.fromComp = fromComp;
+    _thisLayerFunction.sampleImage = sampleImage;
+    _thisLayerFunction.sourceRectAtTime = elem.sourceRectAtTime.bind(elem);
+    _thisLayerFunction._elem = elem;
+    transformInterface = TransformExpressionInterface(elem.finalTransform.mProp);
+    var anchorPointDescriptor = getDescriptor(transformInterface, 'anchorPoint');
+    Object.defineProperties(_thisLayerFunction, {
+      hasParent: {
+        get: function () {
+          return elem.hierarchy.length;
+        },
+      },
+      parent: {
+        get: function () {
+          return elem.hierarchy[0].layerInterface;
+        },
+      },
+      rotation: getDescriptor(transformInterface, 'rotation'),
+      scale: getDescriptor(transformInterface, 'scale'),
+      position: getDescriptor(transformInterface, 'position'),
+      opacity: getDescriptor(transformInterface, 'opacity'),
+      anchorPoint: anchorPointDescriptor,
+      anchor_point: anchorPointDescriptor,
+      transform: {
+        get: function () {
+          return transformInterface;
+        },
+      },
+      active: {
+        get: function () {
+          return elem.isInRange;
+        },
+      },
+    });
+
+    _thisLayerFunction.startTime = elem.data.st;
+    _thisLayerFunction.index = elem.data.ind;
+    _thisLayerFunction.source = elem.data.refId;
+    _thisLayerFunction.height = elem.data.ty === 0 ? elem.data.h : 100;
+    _thisLayerFunction.width = elem.data.ty === 0 ? elem.data.w : 100;
+    _thisLayerFunction.inPoint = elem.data.ip / elem.comp.globalData.frameRate;
+    _thisLayerFunction.outPoint = elem.data.op / elem.comp.globalData.frameRate;
+    _thisLayerFunction._name = elem.data.nm;
+
+    _thisLayerFunction.registerMaskInterface = _registerMaskInterface;
+    _thisLayerFunction.registerEffectsInterface = _registerEffectsInterface;
+    return _thisLayerFunction;
+  };
+}());
+
+const propertyGroupFactory = (function () {
+  return function (interfaceFunction, parentPropertyGroup) {
+    return function (val) {
+      val = val === undefined ? 1 : val;
+      if (val <= 0) {
+        return interfaceFunction;
+      }
+      return parentPropertyGroup(val - 1);
+    };
+  };
+}());
+
+const PropertyInterface = (function () {
+  return function (propertyName, propertyGroup) {
+    var interfaceFunction = {
+      _name: propertyName,
+    };
+
+    function _propertyGroup(val) {
+      val = val === undefined ? 1 : val;
+      if (val <= 0) {
+        return interfaceFunction;
+      }
+      return propertyGroup(val - 1);
+    }
+
+    return _propertyGroup;
+  };
+}());
+
+const EffectsExpressionInterface = (function () {
+  var ob = {
+    createEffectsInterface: createEffectsInterface,
+  };
+
+  function createEffectsInterface(elem, propertyGroup) {
+    if (elem.effectsManager) {
+      var effectElements = [];
+      var effectsData = elem.data.ef;
+      var i;
+      var len = elem.effectsManager.effectElements.length;
+      for (i = 0; i < len; i += 1) {
+        effectElements.push(createGroupInterface(effectsData[i], elem.effectsManager.effectElements[i], propertyGroup, elem));
+      }
+
+      var effects = elem.data.ef || [];
+      var groupInterface = function (name) {
+        i = 0;
+        len = effects.length;
+        while (i < len) {
+          if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
+            return effectElements[i];
+          }
+          i += 1;
+        }
+        return null;
+      };
+      Object.defineProperty(groupInterface, 'numProperties', {
+        get: function () {
+          return effects.length;
+        },
+      });
+      return groupInterface;
+    }
+    return null;
+  }
+
+  function createGroupInterface(data, elements, propertyGroup, elem) {
+    function groupInterface(name) {
+      var effects = data.ef;
+      var i = 0;
+      var len = effects.length;
+      while (i < len) {
+        if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
+          if (effects[i].ty === 5) {
+            return effectElements[i];
+          }
+          return effectElements[i]();
+        }
+        i += 1;
+      }
+      throw new Error();
+    }
+    var _propertyGroup = propertyGroupFactory(groupInterface, propertyGroup);
+
+    var effectElements = [];
+    var i;
+    var len = data.ef.length;
+    for (i = 0; i < len; i += 1) {
+      if (data.ef[i].ty === 5) {
+        effectElements.push(createGroupInterface(data.ef[i], elements.effectElements[i], elements.effectElements[i].propertyGroup, elem));
+      } else {
+        effectElements.push(createValueInterface(elements.effectElements[i], data.ef[i].ty, elem, _propertyGroup));
+      }
+    }
+
+    if (data.mn === 'ADBE Color Control') {
+      Object.defineProperty(groupInterface, 'color', {
+        get: function () {
+          return effectElements[0]();
+        },
+      });
+    }
+    Object.defineProperties(groupInterface, {
+      numProperties: {
+        get: function () {
+          return data.np;
+        },
+      },
+      _name: { value: data.nm },
+      propertyGroup: { value: _propertyGroup },
+    });
+    groupInterface.enabled = data.en !== 0;
+    groupInterface.active = groupInterface.enabled;
+    return groupInterface;
+  }
+
+  function createValueInterface(element, type, elem, propertyGroup) {
+    var expressionProperty = ExpressionPropertyInterface(element.p);
+    function interfaceFunction() {
+      if (type === 10) {
+        return elem.comp.compInterface(element.p.v);
+      }
+      return expressionProperty();
+    }
+
+    if (element.p.setGroupProperty) {
+      element.p.setGroupProperty(PropertyInterface('', propertyGroup));
+    }
+
+    return interfaceFunction;
+  }
+
+  return ob;
+}());
+
+const ShapePathInterface = (
+
+  function () {
+    return function pathInterfaceFactory(shape, view, propertyGroup) {
+      var prop = view.sh;
+
+      function interfaceFunction(val) {
+        if (val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2) {
+          return interfaceFunction.path;
+        }
+        return null;
+      }
+
+      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+      prop.setGroupProperty(PropertyInterface('Path', _propertyGroup));
+      Object.defineProperties(interfaceFunction, {
+        path: {
+          get: function () {
+            if (prop.k) {
+              prop.getValue();
+            }
+            return prop;
+          },
+        },
+        shape: {
+          get: function () {
+            if (prop.k) {
+              prop.getValue();
+            }
+            return prop;
+          },
+        },
+        _name: { value: shape.nm },
+        ix: { value: shape.ix },
+        propertyIndex: { value: shape.ix },
+        mn: { value: shape.mn },
+        propertyGroup: { value: propertyGroup },
+      });
+      return interfaceFunction;
+    };
+  }()
+);
+
+const ShapeExpressionInterface = (function () {
+  function iterateElements(shapes, view, propertyGroup) {
+    var arr = [];
+    var i;
+    var len = shapes ? shapes.length : 0;
+    for (i = 0; i < len; i += 1) {
+      if (shapes[i].ty === 'gr') {
+        arr.push(groupInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'fl') {
+        arr.push(fillInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'st') {
+        arr.push(strokeInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'tm') {
+        arr.push(trimInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'tr') {
+        // arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
+      } else if (shapes[i].ty === 'el') {
+        arr.push(ellipseInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'sr') {
+        arr.push(starInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'sh') {
+        arr.push(ShapePathInterface(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'rc') {
+        arr.push(rectInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'rd') {
+        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;
+  }
+
+  function contentsInterfaceFactory(shape, view, propertyGroup) {
+    var interfaces;
+    var interfaceFunction = function _interfaceFunction(value) {
+      var i = 0;
+      var len = interfaces.length;
+      while (i < len) {
+        if (interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value) {
+          return interfaces[i];
+        }
+        i += 1;
+      }
+      if (typeof value === 'number') {
+        return interfaces[value - 1];
+      }
+      return null;
+    };
+
+    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup);
+    interfaceFunction.numProperties = interfaces.length;
+    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
+    interfaceFunction.transform = transformInterface;
+    interfaceFunction.propertyIndex = shape.cix;
+    interfaceFunction._name = shape.nm;
+
+    return interfaceFunction;
+  }
+
+  function groupInterfaceFactory(shape, view, propertyGroup) {
+    var interfaceFunction = function _interfaceFunction(value) {
+      switch (value) {
+        case 'ADBE Vectors Group':
+        case 'Contents':
+        case 2:
+          return interfaceFunction.content;
+          // Not necessary for now. Keeping them here in case a new case appears
+          // case 'ADBE Vector Transform Group':
+          // case 3:
+        default:
+          return interfaceFunction.transform;
+      }
+    };
+    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var content = contentsInterfaceFactory(shape, view, interfaceFunction.propertyGroup);
+    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
+    interfaceFunction.content = content;
+    interfaceFunction.transform = transformInterface;
+    Object.defineProperty(interfaceFunction, '_name', {
+      get: function () {
+        return shape.nm;
+      },
+    });
+    // interfaceFunction.content = interfaceFunction;
+    interfaceFunction.numProperties = shape.np;
+    interfaceFunction.propertyIndex = shape.ix;
+    interfaceFunction.nm = shape.nm;
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function fillInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      if (val === 'Color' || val === 'color') {
+        return interfaceFunction.color;
+      } if (val === 'Opacity' || val === 'opacity') {
+        return interfaceFunction.opacity;
+      }
+      return null;
+    }
+    Object.defineProperties(interfaceFunction, {
+      color: {
+        get: ExpressionPropertyInterface(view.c),
+      },
+      opacity: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      _name: { value: shape.nm },
+      mn: { value: shape.mn },
+    });
+
+    view.c.setGroupProperty(PropertyInterface('Color', propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
+    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 () {
+          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() {
+    function interfaceFunction() {
+      return null;
+    }
+    return interfaceFunction;
+  }
+
+  function strokeInterfaceFactory(shape, view, propertyGroup) {
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup);
+    function addPropertyToDashOb(i) {
+      Object.defineProperty(dashOb, shape.d[i].nm, {
+        get: ExpressionPropertyInterface(view.d.dataProps[i].p),
+      });
+    }
+    var i;
+    var len = shape.d ? shape.d.length : 0;
+    var dashOb = {};
+    for (i = 0; i < len; i += 1) {
+      addPropertyToDashOb(i);
+      view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup);
+    }
+
+    function interfaceFunction(val) {
+      if (val === 'Color' || val === 'color') {
+        return interfaceFunction.color;
+      } if (val === 'Opacity' || val === 'opacity') {
+        return interfaceFunction.opacity;
+      } if (val === 'Stroke Width' || val === 'stroke width') {
+        return interfaceFunction.strokeWidth;
+      }
+      return null;
+    }
+    Object.defineProperties(interfaceFunction, {
+      color: {
+        get: ExpressionPropertyInterface(view.c),
+      },
+      opacity: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      strokeWidth: {
+        get: ExpressionPropertyInterface(view.w),
+      },
+      dash: {
+        get: function () {
+          return dashOb;
+        },
+      },
+      _name: { value: shape.nm },
+      mn: { value: shape.mn },
+    });
+
+    view.c.setGroupProperty(PropertyInterface('Color', _propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    view.w.setGroupProperty(PropertyInterface('Stroke Width', _propertyGroup));
+    return interfaceFunction;
+  }
+
+  function trimInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      if (val === shape.e.ix || val === 'End' || val === 'end') {
+        return interfaceFunction.end;
+      }
+      if (val === shape.s.ix) {
+        return interfaceFunction.start;
+      }
+      if (val === shape.o.ix) {
+        return interfaceFunction.offset;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaceFunction.propertyIndex = shape.ix;
+
+    view.s.setGroupProperty(PropertyInterface('Start', _propertyGroup));
+    view.e.setGroupProperty(PropertyInterface('End', _propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
+    interfaceFunction.propertyIndex = shape.ix;
+    interfaceFunction.propertyGroup = propertyGroup;
+
+    Object.defineProperties(interfaceFunction, {
+      start: {
+        get: ExpressionPropertyInterface(view.s),
+      },
+      end: {
+        get: ExpressionPropertyInterface(view.e),
+      },
+      offset: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function transformInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.a.ix === value || value === 'Anchor Point') {
+        return interfaceFunction.anchorPoint;
+      }
+      if (shape.o.ix === value || value === 'Opacity') {
+        return interfaceFunction.opacity;
+      }
+      if (shape.p.ix === value || value === 'Position') {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value || value === 'Rotation' || value === 'ADBE Vector Rotation') {
+        return interfaceFunction.rotation;
+      }
+      if (shape.s.ix === value || value === 'Scale') {
+        return interfaceFunction.scale;
+      }
+      if ((shape.sk && shape.sk.ix === value) || value === 'Skew') {
+        return interfaceFunction.skew;
+      }
+      if ((shape.sa && shape.sa.ix === value) || value === 'Skew Axis') {
+        return interfaceFunction.skewAxis;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    view.transform.mProps.a.setGroupProperty(PropertyInterface('Anchor Point', _propertyGroup));
+    view.transform.mProps.s.setGroupProperty(PropertyInterface('Scale', _propertyGroup));
+    view.transform.mProps.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+    if (view.transform.mProps.sk) {
+      view.transform.mProps.sk.setGroupProperty(PropertyInterface('Skew', _propertyGroup));
+      view.transform.mProps.sa.setGroupProperty(PropertyInterface('Skew Angle', _propertyGroup));
+    }
+    view.transform.op.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    Object.defineProperties(interfaceFunction, {
+      opacity: {
+        get: ExpressionPropertyInterface(view.transform.mProps.o),
+      },
+      position: {
+        get: ExpressionPropertyInterface(view.transform.mProps.p),
+      },
+      anchorPoint: {
+        get: ExpressionPropertyInterface(view.transform.mProps.a),
+      },
+      scale: {
+        get: ExpressionPropertyInterface(view.transform.mProps.s),
+      },
+      rotation: {
+        get: ExpressionPropertyInterface(view.transform.mProps.r),
+      },
+      skew: {
+        get: ExpressionPropertyInterface(view.transform.mProps.sk),
+      },
+      skewAxis: {
+        get: ExpressionPropertyInterface(view.transform.mProps.sa),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.ty = 'tr';
+    interfaceFunction.mn = shape.mn;
+    interfaceFunction.propertyGroup = propertyGroup;
+    return interfaceFunction;
+  }
+
+  function ellipseInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.s.ix === value) {
+        return interfaceFunction.size;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaceFunction.propertyIndex = shape.ix;
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      size: {
+        get: ExpressionPropertyInterface(prop.s),
+      },
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function starInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value) {
+        return interfaceFunction.rotation;
+      }
+      if (shape.pt.ix === value) {
+        return interfaceFunction.points;
+      }
+      if (shape.or.ix === value || value === 'ADBE Vector Star Outer Radius') {
+        return interfaceFunction.outerRadius;
+      }
+      if (shape.os.ix === value) {
+        return interfaceFunction.outerRoundness;
+      }
+      if (shape.ir && (shape.ir.ix === value || value === 'ADBE Vector Star Inner Radius')) {
+        return interfaceFunction.innerRadius;
+      }
+      if (shape.is && shape.is.ix === value) {
+        return interfaceFunction.innerRoundness;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.or.setGroupProperty(PropertyInterface('Outer Radius', _propertyGroup));
+    prop.os.setGroupProperty(PropertyInterface('Outer Roundness', _propertyGroup));
+    prop.pt.setGroupProperty(PropertyInterface('Points', _propertyGroup));
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+    if (shape.ir) {
+      prop.ir.setGroupProperty(PropertyInterface('Inner Radius', _propertyGroup));
+      prop.is.setGroupProperty(PropertyInterface('Inner Roundness', _propertyGroup));
+    }
+
+    Object.defineProperties(interfaceFunction, {
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      rotation: {
+        get: ExpressionPropertyInterface(prop.r),
+      },
+      points: {
+        get: ExpressionPropertyInterface(prop.pt),
+      },
+      outerRadius: {
+        get: ExpressionPropertyInterface(prop.or),
+      },
+      outerRoundness: {
+        get: ExpressionPropertyInterface(prop.os),
+      },
+      innerRadius: {
+        get: ExpressionPropertyInterface(prop.ir),
+      },
+      innerRoundness: {
+        get: ExpressionPropertyInterface(prop.is),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function rectInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value) {
+        return interfaceFunction.roundness;
+      }
+      if (shape.s.ix === value || value === 'Size' || value === 'ADBE Vector Rect Size') {
+        return interfaceFunction.size;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
+    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      roundness: {
+        get: ExpressionPropertyInterface(prop.r),
+      },
+      size: {
+        get: ExpressionPropertyInterface(prop.s),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function roundedInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.r.ix === value || value === 'Round Corners 1') {
+        return interfaceFunction.radius;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.rd.setGroupProperty(PropertyInterface('Radius', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      radius: {
+        get: ExpressionPropertyInterface(prop.rd),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function repeaterInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.c.ix === value || value === 'Copies') {
+        return interfaceFunction.copies;
+      } if (shape.o.ix === value || value === 'Offset') {
+        return interfaceFunction.offset;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.c.setGroupProperty(PropertyInterface('Copies', _propertyGroup));
+    prop.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
+    Object.defineProperties(interfaceFunction, {
+      copies: {
+        get: ExpressionPropertyInterface(prop.c),
+      },
+      offset: {
+        get: ExpressionPropertyInterface(prop.o),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  return function (shapes, view, propertyGroup) {
+    var interfaces;
+    function _interfaceFunction(value) {
+      if (typeof value === 'number') {
+        value = value === undefined ? 1 : value;
+        if (value === 0) {
+          return propertyGroup;
+        }
+        return interfaces[value - 1];
+      }
+      var i = 0;
+      var len = interfaces.length;
+      while (i < len) {
+        if (interfaces[i]._name === value) {
+          return interfaces[i];
+        }
+        i += 1;
+      }
+      return null;
+    }
+    function parentGroupWrapper() {
+      return propertyGroup;
+    }
+    _interfaceFunction.propertyGroup = propertyGroupFactory(_interfaceFunction, parentGroupWrapper);
+    interfaces = iterateElements(shapes, view, _interfaceFunction.propertyGroup);
+    _interfaceFunction.numProperties = interfaces.length;
+    _interfaceFunction._name = 'Contents';
+    return _interfaceFunction;
+  };
+}());
+
+const TextExpressionInterface = (function () {
+  return function (elem) {
+    var _sourceText;
+    function _thisLayerFunction(name) {
+      switch (name) {
+        case 'ADBE Text Document':
+          return _thisLayerFunction.sourceText;
+        default:
+          return null;
+      }
+    }
+    Object.defineProperty(_thisLayerFunction, 'sourceText', {
+      get: function () {
+        elem.textProperty.getValue();
+        var stringValue = elem.textProperty.currentData.t;
+        if (!_sourceText || stringValue !== _sourceText.value) {
+          _sourceText = new String(stringValue); // eslint-disable-line no-new-wrappers
+          // If stringValue is an empty string, eval returns undefined, so it has to be returned as a String primitive
+          _sourceText.value = stringValue || new String(stringValue); // eslint-disable-line no-new-wrappers
+          Object.defineProperty(_sourceText, 'style', {
+            get: function () {
+              return {
+                fillColor: elem.textProperty.currentData.fc,
+              };
+            },
+          });
+        }
+        return _sourceText;
+      },
+    });
+    return _thisLayerFunction;
+  };
+}());
+
+const FootageInterface = (function () {
+  var outlineInterfaceFactory = (function (elem) {
+    var currentPropertyName = '';
+    var currentProperty = elem.getFootageData();
+    function init() {
+      currentPropertyName = '';
+      currentProperty = elem.getFootageData();
+      return searchProperty;
+    }
+    function searchProperty(value) {
+      if (currentProperty[value]) {
+        currentPropertyName = value;
+        currentProperty = currentProperty[value];
+        if (typeof currentProperty === 'object') {
+          return searchProperty;
+        }
+        return currentProperty;
+      }
+      var propertyNameIndex = value.indexOf(currentPropertyName);
+      if (propertyNameIndex !== -1) {
+        var index = parseInt(value.substr(propertyNameIndex + currentPropertyName.length), 10);
+        currentProperty = currentProperty[index];
+        if (typeof currentProperty === 'object') {
+          return searchProperty;
+        }
+        return currentProperty;
+      }
+      return '';
+    }
+    return init;
+  });
+
+  var dataInterfaceFactory = function (elem) {
+    function interfaceFunction(value) {
+      if (value === 'Outline') {
+        return interfaceFunction.outlineInterface();
+      }
+      return null;
+    }
+
+    interfaceFunction._name = 'Outline';
+    interfaceFunction.outlineInterface = outlineInterfaceFactory(elem);
+    return interfaceFunction;
+  };
+
+  return function (elem) {
+    function _interfaceFunction(value) {
+      if (value === 'Data') {
+        return _interfaceFunction.dataInterface;
+      }
+      return null;
+    }
+
+    _interfaceFunction._name = 'Data';
+    _interfaceFunction.dataInterface = dataInterfaceFactory(elem);
+    return _interfaceFunction;
+  };
+}());
+
+var interfaces = {
+  layer: LayerExpressionInterface,
+  effects: EffectsExpressionInterface,
+  comp: CompExpressionInterface,
+  shape: ShapeExpressionInterface,
+  text: TextExpressionInterface,
+  footage: FootageInterface,
+};
+
+function getInterface(type) {
+  return interfaces[type] || null;
+}
+
+const expressionHelpers = (function () {
+  function searchExpressions(elem, data, prop) {
+    if (data.x) {
+      prop.k = true;
+      prop.x = true;
+      prop.initiateExpression = ExpressionManager.initiateExpression;
+      prop.effectsSequence.push(prop.initiateExpression(elem, data, prop).bind(prop));
+    }
+  }
+
+  function getValueAtTime(frameNum) {
+    frameNum *= this.elem.globalData.frameRate;
+    frameNum -= this.offsetTime;
+    if (frameNum !== this._cachingAtTime.lastFrame) {
+      this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0;
+      this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime);
+      this._cachingAtTime.lastFrame = frameNum;
+    }
+    return this._cachingAtTime.value;
+  }
+
+  function getSpeedAtTime(frameNum) {
+    var delta = -0.01;
+    var v1 = this.getValueAtTime(frameNum);
+    var v2 = this.getValueAtTime(frameNum + delta);
+    var speed = 0;
+    if (v1.length) {
+      var i;
+      for (i = 0; i < v1.length; i += 1) {
+        speed += Math.pow(v2[i] - v1[i], 2);
+      }
+      speed = Math.sqrt(speed) * 100;
+    } else {
+      speed = 0;
+    }
+    return speed;
+  }
+
+  function getVelocityAtTime(frameNum) {
+    if (this.vel !== undefined) {
+      return this.vel;
+    }
+    var delta = -0.001;
+    // frameNum += this.elem.data.st;
+    var v1 = this.getValueAtTime(frameNum);
+    var v2 = this.getValueAtTime(frameNum + delta);
+    var velocity;
+    if (v1.length) {
+      velocity = createTypedArray('float32', v1.length);
+      var i;
+      for (i = 0; i < v1.length; i += 1) {
+        // removing frameRate
+        // if needed, don't add it here
+        // velocity[i] = this.elem.globalData.frameRate*((v2[i] - v1[i])/delta);
+        velocity[i] = (v2[i] - v1[i]) / delta;
+      }
+    } else {
+      velocity = (v2 - v1) / delta;
+    }
+    return velocity;
+  }
+
+  function getStaticValueAtTime() {
+    return this.pv;
+  }
+
+  function setGroupProperty(propertyGroup) {
+    this.propertyGroup = propertyGroup;
+  }
+
+  return {
+    searchExpressions: searchExpressions,
+    getSpeedAtTime: getSpeedAtTime,
+    getVelocityAtTime: getVelocityAtTime,
+    getValueAtTime: getValueAtTime,
+    getStaticValueAtTime: getStaticValueAtTime,
+    setGroupProperty: setGroupProperty,
+  };
+}());
+
+function addPropertyDecorator() {
+  function loopOut(type, duration, durationFlag) {
+    if (!this.k || !this.keyframes) {
+      return this.pv;
+    }
+    type = type ? type.toLowerCase() : '';
+    var currentFrame = this.comp.renderedFrame;
+    var keyframes = this.keyframes;
+    var lastKeyFrame = keyframes[keyframes.length - 1].t;
+    if (currentFrame <= lastKeyFrame) {
+      return this.pv;
+    }
+    var cycleDuration;
+    var firstKeyFrame;
+    if (!durationFlag) {
+      if (!duration || duration > keyframes.length - 1) {
+        duration = keyframes.length - 1;
+      }
+      firstKeyFrame = keyframes[keyframes.length - 1 - duration].t;
+      cycleDuration = lastKeyFrame - firstKeyFrame;
+    } else {
+      if (!duration) {
+        cycleDuration = Math.max(0, lastKeyFrame - this.elem.data.ip);
+      } else {
+        cycleDuration = Math.abs(lastKeyFrame - this.elem.comp.globalData.frameRate * duration);
+      }
+      firstKeyFrame = lastKeyFrame - cycleDuration;
+    }
+    var i;
+    var len;
+    var ret;
+    if (type === 'pingpong') {
+      var iterations = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
+      if (iterations % 2 !== 0) {
+          return this.getValueAtTime(((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      }
+    } else if (type === 'offset') {
+      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+        var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      var repeats = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
+      if (this.pv.length) {
+        ret = new Array(initV.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = (endV[i] - initV[i]) * repeats + current[i];
+        }
+        return ret;
+      }
+      return (endV - initV) * repeats + current;
+    } else if (type === 'continue') {
+      var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+      var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0);
+      if (this.pv.length) {
+        ret = new Array(lastValue.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+            ret[i] = lastValue[i] + (lastValue[i] - nextLastValue[i]) * ((currentFrame - lastKeyFrame) / this.comp.globalData.frameRate) / 0.0005; // eslint-disable-line
+        }
+        return ret;
+      }
+      return lastValue + (lastValue - nextLastValue) * (((currentFrame - lastKeyFrame)) / 0.001);
+    }
+      return this.getValueAtTime((((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+
+  }
+
+  function loopIn(type, duration, durationFlag) {
+    if (!this.k) {
+      return this.pv;
+    }
+    type = type ? type.toLowerCase() : '';
+    var currentFrame = this.comp.renderedFrame;
+    var keyframes = this.keyframes;
+    var firstKeyFrame = keyframes[0].t;
+    if (currentFrame >= firstKeyFrame) {
+      return this.pv;
+    }
+    var cycleDuration;
+    var lastKeyFrame;
+    if (!durationFlag) {
+      if (!duration || duration > keyframes.length - 1) {
+        duration = keyframes.length - 1;
+      }
+      lastKeyFrame = keyframes[duration].t;
+      cycleDuration = lastKeyFrame - firstKeyFrame;
+    } else {
+      if (!duration) {
+        cycleDuration = Math.max(0, this.elem.data.op - firstKeyFrame);
+      } else {
+        cycleDuration = Math.abs(this.elem.comp.globalData.frameRate * duration);
+      }
+      lastKeyFrame = firstKeyFrame + cycleDuration;
+    }
+    var i;
+    var len;
+    var ret;
+    if (type === 'pingpong') {
+      var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration);
+      if (iterations % 2 === 0) {
+          return this.getValueAtTime((((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      }
+    } else if (type === 'offset') {
+      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+      var current = this.getValueAtTime((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration) + firstKeyFrame) / this.comp.globalData.frameRate, 0);
+      var repeats = Math.floor((firstKeyFrame - currentFrame) / cycleDuration) + 1;
+      if (this.pv.length) {
+        ret = new Array(initV.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = current[i] - (endV[i] - initV[i]) * repeats;
+        }
+        return ret;
+      }
+      return current - (endV - initV) * repeats;
+    } else if (type === 'continue') {
+      var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0);
+      if (this.pv.length) {
+        ret = new Array(firstValue.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = firstValue[i] + ((firstValue[i] - nextFirstValue[i]) * (firstKeyFrame - currentFrame)) / 0.001;
+        }
+        return ret;
+      }
+      return firstValue + ((firstValue - nextFirstValue) * (firstKeyFrame - currentFrame)) / 0.001;
+    }
+      return this.getValueAtTime(((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame))) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+
+  }
+
+  function smooth(width, samples) {
+    if (!this.k) {
+      return this.pv;
+    }
+    width = (width || 0.4) * 0.5;
+    samples = Math.floor(samples || 5);
+    if (samples <= 1) {
+      return this.pv;
+    }
+    var currentTime = this.comp.renderedFrame / this.comp.globalData.frameRate;
+    var initFrame = currentTime - width;
+    var endFrame = currentTime + width;
+    var sampleFrequency = samples > 1 ? (endFrame - initFrame) / (samples - 1) : 1;
+    var i = 0;
+    var j = 0;
+    var value;
+    if (this.pv.length) {
+      value = createTypedArray('float32', this.pv.length);
+    } else {
+      value = 0;
+    }
+    var sampleValue;
+    while (i < samples) {
+      sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency);
+      if (this.pv.length) {
+        for (j = 0; j < this.pv.length; j += 1) {
+          value[j] += sampleValue[j];
+        }
+      } else {
+        value += sampleValue;
+      }
+      i += 1;
+    }
+    if (this.pv.length) {
+      for (j = 0; j < this.pv.length; j += 1) {
+        value[j] /= samples;
+      }
+    } else {
+      value /= samples;
+    }
+    return value;
+  }
+
+  function getTransformValueAtTime(time) {
+    if (!this._transformCachingAtTime) {
+      this._transformCachingAtTime = {
+        v: new Matrix(),
+      };
+    }
+    /// /
+    var matrix = this._transformCachingAtTime.v;
+    matrix.cloneFromProps(this.pre.props);
+    if (this.appliedTransformations < 1) {
+      var anchor = this.a.getValueAtTime(time);
+      matrix.translate(
+        -anchor[0] * this.a.mult,
+        -anchor[1] * this.a.mult,
+        anchor[2] * this.a.mult
+      );
+    }
+    if (this.appliedTransformations < 2) {
+      var scale = this.s.getValueAtTime(time);
+      matrix.scale(
+        scale[0] * this.s.mult,
+        scale[1] * this.s.mult,
+        scale[2] * this.s.mult
+      );
+    }
+    if (this.sk && this.appliedTransformations < 3) {
+      var skew = this.sk.getValueAtTime(time);
+      var skewAxis = this.sa.getValueAtTime(time);
+      matrix.skewFromAxis(-skew * this.sk.mult, skewAxis * this.sa.mult);
+    }
+    if (this.r && this.appliedTransformations < 4) {
+      var rotation = this.r.getValueAtTime(time);
+      matrix.rotate(-rotation * this.r.mult);
+    } else if (!this.r && this.appliedTransformations < 4) {
+      var rotationZ = this.rz.getValueAtTime(time);
+      var rotationY = this.ry.getValueAtTime(time);
+      var rotationX = this.rx.getValueAtTime(time);
+      var orientation = this.or.getValueAtTime(time);
+      matrix.rotateZ(-rotationZ * this.rz.mult)
+        .rotateY(rotationY * this.ry.mult)
+        .rotateX(rotationX * this.rx.mult)
+        .rotateZ(-orientation[2] * this.or.mult)
+        .rotateY(orientation[1] * this.or.mult)
+        .rotateX(orientation[0] * this.or.mult);
+    }
+    if (this.data.p && this.data.p.s) {
+      var positionX = this.px.getValueAtTime(time);
+      var positionY = this.py.getValueAtTime(time);
+      if (this.data.p.z) {
+        var positionZ = this.pz.getValueAtTime(time);
+        matrix.translate(
+          positionX * this.px.mult,
+          positionY * this.py.mult,
+          -positionZ * this.pz.mult
+        );
+      } else {
+        matrix.translate(positionX * this.px.mult, positionY * this.py.mult, 0);
+      }
+    } else {
+      var position = this.p.getValueAtTime(time);
+      matrix.translate(
+        position[0] * this.p.mult,
+        position[1] * this.p.mult,
+        -position[2] * this.p.mult
+      );
+    }
+    return matrix;
+    /// /
+  }
+
+  function getTransformStaticValueAtTime() {
+    return this.v.clone(new Matrix());
+  }
+
+  var getTransformProperty = TransformPropertyFactory.getTransformProperty;
+  TransformPropertyFactory.getTransformProperty = function (elem, data, container) {
+    var prop = getTransformProperty(elem, data, container);
+    if (prop.dynamicProperties.length) {
+      prop.getValueAtTime = getTransformValueAtTime.bind(prop);
+    } else {
+      prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop);
+    }
+    prop.setGroupProperty = expressionHelpers.setGroupProperty;
+    return prop;
+  };
+
+  var propertyGetProp = PropertyFactory.getProp;
+  PropertyFactory.getProp = function (elem, data, type, mult, container) {
+    var prop = propertyGetProp(elem, data, type, mult, container);
+    // prop.getVelocityAtTime = getVelocityAtTime;
+    // prop.loopOut = loopOut;
+    // prop.loopIn = loopIn;
+    if (prop.kf) {
+      prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop);
+    } else {
+      prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop);
+    }
+    prop.setGroupProperty = expressionHelpers.setGroupProperty;
+    prop.loopOut = loopOut;
+    prop.loopIn = loopIn;
+    prop.smooth = smooth;
+    prop.getVelocityAtTime = expressionHelpers.getVelocityAtTime.bind(prop);
+    prop.getSpeedAtTime = expressionHelpers.getSpeedAtTime.bind(prop);
+    prop.numKeys = data.a === 1 ? data.k.length : 0;
+    prop.propertyIndex = data.ix;
+    var value = 0;
+    if (type !== 0) {
+      value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length);
+    }
+    prop._cachingAtTime = {
+      lastFrame: initialDefaultFrame,
+      lastIndex: 0,
+      value: value,
+    };
+    expressionHelpers.searchExpressions(elem, data, prop);
+    if (prop.k) {
+      container.addDynamicProperty(prop);
+    }
+
+    return prop;
+  };
+
+  function getShapeValueAtTime(frameNum) {
+    // For now this caching object is created only when needed instead of creating it when the shape is initialized.
+    if (!this._cachingAtTime) {
+      this._cachingAtTime = {
+        shapeValue: shapePool.clone(this.pv),
+        lastIndex: 0,
+        lastTime: initialDefaultFrame,
+      };
+    }
+
+    frameNum *= this.elem.globalData.frameRate;
+    frameNum -= this.offsetTime;
+    if (frameNum !== this._cachingAtTime.lastTime) {
+      this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0;
+      this._cachingAtTime.lastTime = frameNum;
+      this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime);
+    }
+    return this._cachingAtTime.shapeValue;
+  }
+
+  var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction();
+  var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction();
+
+  function ShapeExpressions() {}
+  ShapeExpressions.prototype = {
+    vertices: function (prop, time) {
+      if (this.k) {
+        this.getValue();
+      }
+      var shapePath = this.v;
+      if (time !== undefined) {
+        shapePath = this.getValueAtTime(time, 0);
+      }
+      var i;
+      var len = shapePath._length;
+      var vertices = shapePath[prop];
+      var points = shapePath.v;
+      var arr = createSizedArray(len);
+      for (i = 0; i < len; i += 1) {
+        if (prop === 'i' || prop === 'o') {
+          arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]];
+        } else {
+          arr[i] = [vertices[i][0], vertices[i][1]];
+        }
+      }
+      return arr;
+    },
+    points: function (time) {
+      return this.vertices('v', time);
+    },
+    inTangents: function (time) {
+      return this.vertices('i', time);
+    },
+    outTangents: function (time) {
+      return this.vertices('o', time);
+    },
+    isClosed: function () {
+      return this.v.c;
+    },
+    pointOnPath: function (perc, time) {
+      var shapePath = this.v;
+      if (time !== undefined) {
+        shapePath = this.getValueAtTime(time, 0);
+      }
+      if (!this._segmentsLength) {
+        this._segmentsLength = bez.getSegmentsLength(shapePath);
+      }
+
+      var segmentsLength = this._segmentsLength;
+      var lengths = segmentsLength.lengths;
+      var lengthPos = segmentsLength.totalLength * perc;
+      var i = 0;
+      var len = lengths.length;
+      var accumulatedLength = 0;
+      var pt;
+      while (i < len) {
+        if (accumulatedLength + lengths[i].addedLength > lengthPos) {
+          var initIndex = i;
+          var endIndex = (shapePath.c && i === len - 1) ? 0 : i + 1;
+          var segmentPerc = (lengthPos - accumulatedLength) / lengths[i].addedLength;
+          pt = bez.getPointInSegment(shapePath.v[initIndex], shapePath.v[endIndex], shapePath.o[initIndex], shapePath.i[endIndex], segmentPerc, lengths[i]);
+          break;
+        } else {
+          accumulatedLength += lengths[i].addedLength;
+        }
+        i += 1;
+      }
+      if (!pt) {
+        pt = shapePath.c ? [shapePath.v[0][0], shapePath.v[0][1]] : [shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1]];
+      }
+      return pt;
+    },
+    vectorOnPath: function (perc, time, vectorType) {
+      // perc doesn't use triple equality because it can be a Number object as well as a primitive.
+      if (perc == 1) { // eslint-disable-line eqeqeq
+        perc = this.v.c;
+      } else if (perc == 0) { // eslint-disable-line eqeqeq
+        perc = 0.999;
+      }
+      var pt1 = this.pointOnPath(perc, time);
+      var pt2 = this.pointOnPath(perc + 0.001, time);
+      var xLength = pt2[0] - pt1[0];
+      var yLength = pt2[1] - pt1[1];
+      var magnitude = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2));
+      if (magnitude === 0) {
+        return [0, 0];
+      }
+      var unitVector = vectorType === 'tangent' ? [xLength / magnitude, yLength / magnitude] : [-yLength / magnitude, xLength / magnitude];
+      return unitVector;
+    },
+    tangentOnPath: function (perc, time) {
+      return this.vectorOnPath(perc, time, 'tangent');
+    },
+    normalOnPath: function (perc, time) {
+      return this.vectorOnPath(perc, time, 'normal');
+    },
+    setGroupProperty: expressionHelpers.setGroupProperty,
+    getValueAtTime: expressionHelpers.getStaticValueAtTime,
+  };
+  extendPrototype([ShapeExpressions], ShapePropertyConstructorFunction);
+  extendPrototype([ShapeExpressions], KeyframedShapePropertyConstructorFunction);
+  KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime;
+  KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression;
+
+  var propertyGetShapeProp = ShapePropertyFactory.getShapeProp;
+  ShapePropertyFactory.getShapeProp = function (elem, data, type, arr, trims) {
+    var prop = propertyGetShapeProp(elem, data, type, arr, trims);
+    prop.propertyIndex = data.ix;
+    prop.lock = false;
+    if (type === 3) {
+      expressionHelpers.searchExpressions(elem, data.pt, prop);
+    } else if (type === 4) {
+      expressionHelpers.searchExpressions(elem, data.ks, prop);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  };
+}
+
+function initialize$1() {
+  addPropertyDecorator();
+}
+
+function addDecorator() {
+  function searchExpressions() {
+    if (this.data.d.x) {
+      this.calculateExpression = ExpressionManager.initiateExpression.bind(this)(this.elem, this.data.d, this);
+      this.addEffect(this.getExpressionValue.bind(this));
+      return true;
+    }
+    return null;
+  }
+
+  TextProperty.prototype.getExpressionValue = function (currentValue, text) {
+    var newValue = this.calculateExpression(text);
+    if (currentValue.t !== newValue) {
+      var newData = {};
+      this.copyData(newData, currentValue);
+      newData.t = newValue.toString();
+      newData.__complete = false;
+      return newData;
+    }
+    return currentValue;
+  };
+
+  TextProperty.prototype.searchProperty = function () {
+    var isKeyframed = this.searchKeyframes();
+    var hasExpressions = this.searchExpressions();
+    this.kf = isKeyframed || hasExpressions;
+    return this.kf;
+  };
+
+  TextProperty.prototype.searchExpressions = searchExpressions;
+}
+
+function initialize() {
+  addDecorator();
+}
+
+function TransformEffect() {
+}
+
+TransformEffect.prototype.init = function (effectsManager) {
+  this.effectsManager = effectsManager;
+  this.type = effectTypes.TRANSFORM_EFFECT;
+  this.matrix = new Matrix();
+  this.opacity = -1;
+  this._mdf = false;
+  this._opMdf = false;
+};
+
+TransformEffect.prototype.renderFrame = function (forceFrame) {
+  this._opMdf = false;
+  this._mdf = false;
+  if (forceFrame || this.effectsManager._mdf) {
+    var effectElements = this.effectsManager.effectElements;
+    var anchor = effectElements[0].p.v;
+    var position = effectElements[1].p.v;
+    var isUniformScale = effectElements[2].p.v === 1;
+    var scaleHeight = effectElements[3].p.v;
+    var scaleWidth = isUniformScale ? scaleHeight : effectElements[4].p.v;
+    var skew = effectElements[5].p.v;
+    var skewAxis = effectElements[6].p.v;
+    var rotation = effectElements[7].p.v;
+    this.matrix.reset();
+    this.matrix.translate(-anchor[0], -anchor[1], anchor[2]);
+    this.matrix.scale(scaleWidth * 0.01, scaleHeight * 0.01, 1);
+    this.matrix.rotate(-rotation * degToRads);
+    this.matrix.skewFromAxis(-skew * degToRads, (skewAxis + 90) * degToRads);
+    this.matrix.translate(position[0], position[1], 0);
+    this._mdf = true;
+    if (this.opacity !== effectElements[8].p.v) {
+      this.opacity = effectElements[8].p.v;
+      this._opMdf = true;
+    }
+  }
+};
+
+function CVTransformEffect(effectsManager) {
+  this.init(effectsManager);
+}
+extendPrototype([TransformEffect], CVTransformEffect);
+
+// Registering expression plugin
+setExpressionsPlugin(Expressions);
+setExpressionInterfaces(getInterface);
+initialize$1();
+initialize();
+registerEffect(35, CVTransformEffect);
+
+exports["default"] = lottie;
diff --git a/build/player/cjs/lottie_html.min.js b/build/player/cjs/lottie_html.min.js
new file mode 100644
index 0000000..e7f003f
--- /dev/null
+++ b/build/player/cjs/lottie_html.min.js
@@ -0,0 +1,16305 @@
+'use strict';
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+const svgNS = 'http://www.w3.org/2000/svg';
+
+let locationHref = '';
+let _useWebWorker = false;
+
+const initialDefaultFrame = -999999;
+
+const setWebWorker = (flag) => { _useWebWorker = !!flag; };
+const getWebWorker = () => _useWebWorker;
+
+const setLocationHref = (value) => { locationHref = value; };
+const getLocationHref = () => locationHref;
+
+function createTag(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElement(type);
+}
+
+function extendPrototype(sources, destination) {
+  var i;
+  var len = sources.length;
+  var sourcePrototype;
+  for (i = 0; i < len; i += 1) {
+    sourcePrototype = sources[i].prototype;
+    for (var attr in sourcePrototype) {
+      if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
+    }
+  }
+}
+
+function getDescriptor(object, prop) {
+  return Object.getOwnPropertyDescriptor(object, prop);
+}
+
+function createProxyFunction(prototype) {
+  function ProxyFunction() {}
+  ProxyFunction.prototype = prototype;
+  return ProxyFunction;
+}
+
+// import Howl from '../../3rd_party/howler';
+
+const audioControllerFactory = (function () {
+  function AudioController(audioFactory) {
+    this.audios = [];
+    this.audioFactory = audioFactory;
+    this._volume = 1;
+    this._isMuted = false;
+  }
+
+  AudioController.prototype = {
+    addAudio: function (audio) {
+      this.audios.push(audio);
+    },
+    pause: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].pause();
+      }
+    },
+    resume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].resume();
+      }
+    },
+    setRate: function (rateValue) {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].setRate(rateValue);
+      }
+    },
+    createAudio: function (assetPath) {
+      if (this.audioFactory) {
+        return this.audioFactory(assetPath);
+      } if (window.Howl) {
+        return new window.Howl({
+          src: [assetPath],
+        });
+      }
+      return {
+        isPlaying: false,
+        play: function () { this.isPlaying = true; },
+        seek: function () { this.isPlaying = false; },
+        playing: function () {},
+        rate: function () {},
+        setVolume: function () {},
+      };
+    },
+    setAudioFactory: function (audioFactory) {
+      this.audioFactory = audioFactory;
+    },
+    setVolume: function (value) {
+      this._volume = value;
+      this._updateVolume();
+    },
+    mute: function () {
+      this._isMuted = true;
+      this._updateVolume();
+    },
+    unmute: function () {
+      this._isMuted = false;
+      this._updateVolume();
+    },
+    getVolume: function () {
+      return this._volume;
+    },
+    _updateVolume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
+      }
+    },
+  };
+
+  return function () {
+    return new AudioController();
+  };
+}());
+
+const createTypedArray = (function () {
+  function createRegularArray(type, len) {
+    var i = 0;
+    var arr = [];
+    var value;
+    switch (type) {
+      case 'int16':
+      case 'uint8c':
+        value = 1;
+        break;
+      default:
+        value = 1.1;
+        break;
+    }
+    for (i = 0; i < len; i += 1) {
+      arr.push(value);
+    }
+    return arr;
+  }
+  function createTypedArrayFactory(type, len) {
+    if (type === 'float32') {
+      return new Float32Array(len);
+    } if (type === 'int16') {
+      return new Int16Array(len);
+    } if (type === 'uint8c') {
+      return new Uint8ClampedArray(len);
+    }
+    return createRegularArray(type, len);
+  }
+  if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
+    return createTypedArrayFactory;
+  }
+  return createRegularArray;
+}());
+
+function createSizedArray(len) {
+  return Array.apply(null, { length: len });
+}
+
+let subframeEnabled = true;
+let expressionsPlugin = null;
+let expressionsInterfaces = null;
+let idPrefix$1 = '';
+const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+let _shouldRoundValues = false;
+const bmPow = Math.pow;
+const bmSqrt = Math.sqrt;
+const bmFloor = Math.floor;
+const bmMax = Math.max;
+const bmMin = Math.min;
+
+const BMMath = {};
+(function () {
+  var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
+  var i;
+  var len = propertyNames.length;
+  for (i = 0; i < len; i += 1) {
+    BMMath[propertyNames[i]] = Math[propertyNames[i]];
+  }
+}());
+
+function ProjectInterface$1() { return {}; }
+BMMath.random = Math.random;
+BMMath.abs = function (val) {
+  var tOfVal = typeof val;
+  if (tOfVal === 'object' && val.length) {
+    var absArr = createSizedArray(val.length);
+    var i;
+    var len = val.length;
+    for (i = 0; i < len; i += 1) {
+      absArr[i] = Math.abs(val[i]);
+    }
+    return absArr;
+  }
+  return Math.abs(val);
+};
+let defaultCurveSegments = 150;
+const degToRads = Math.PI / 180;
+const roundCorner = 0.5519;
+
+function roundValues(flag) {
+  _shouldRoundValues = !!flag;
+}
+
+function bmRnd(value) {
+  if (_shouldRoundValues) {
+    return Math.round(value);
+  }
+  return value;
+}
+
+function styleDiv(element) {
+  element.style.position = 'absolute';
+  element.style.top = 0;
+  element.style.left = 0;
+  element.style.display = 'block';
+  element.style.transformOrigin = '0 0';
+  element.style.webkitTransformOrigin = '0 0';
+  element.style.backfaceVisibility = 'visible';
+  element.style.webkitBackfaceVisibility = 'visible';
+  element.style.transformStyle = 'preserve-3d';
+  element.style.webkitTransformStyle = 'preserve-3d';
+  element.style.mozTransformStyle = 'preserve-3d';
+}
+
+function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
+  this.type = type;
+  this.currentTime = currentTime;
+  this.totalTime = totalTime;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteEvent(type, frameMultiplier) {
+  this.type = type;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
+  this.type = type;
+  this.currentLoop = currentLoop;
+  this.totalLoops = totalLoops;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMSegmentStartEvent(type, firstFrame, totalFrames) {
+  this.type = type;
+  this.firstFrame = firstFrame;
+  this.totalFrames = totalFrames;
+}
+
+function BMDestroyEvent(type, target) {
+  this.type = type;
+  this.target = target;
+}
+
+function BMRenderFrameErrorEvent(nativeError, currentTime) {
+  this.type = 'renderFrameError';
+  this.nativeError = nativeError;
+  this.currentTime = currentTime;
+}
+
+function BMConfigErrorEvent(nativeError) {
+  this.type = 'configError';
+  this.nativeError = nativeError;
+}
+
+function BMAnimationConfigErrorEvent(type, nativeError) {
+  this.type = type;
+  this.nativeError = nativeError;
+}
+
+const createElementID = (function () {
+  var _count = 0;
+  return function createID() {
+    _count += 1;
+    return idPrefix$1 + '__lottie_element_' + _count;
+  };
+}());
+
+function HSVtoRGB(h, s, v) {
+  var r;
+  var g;
+  var b;
+  var i;
+  var f;
+  var p;
+  var q;
+  var t;
+  i = Math.floor(h * 6);
+  f = h * 6 - i;
+  p = v * (1 - s);
+  q = v * (1 - f * s);
+  t = v * (1 - (1 - f) * s);
+  switch (i % 6) {
+    case 0: r = v; g = t; b = p; break;
+    case 1: r = q; g = v; b = p; break;
+    case 2: r = p; g = v; b = t; break;
+    case 3: r = p; g = q; b = v; break;
+    case 4: r = t; g = p; b = v; break;
+    case 5: r = v; g = p; b = q; break;
+    default: break;
+  }
+  return [r,
+    g,
+    b];
+}
+
+function RGBtoHSV(r, g, b) {
+  var max = Math.max(r, g, b);
+  var min = Math.min(r, g, b);
+  var d = max - min;
+  var h;
+  var s = (max === 0 ? 0 : d / max);
+  var v = max / 255;
+
+  switch (max) {
+    case min: h = 0; break;
+    case r: h = (g - b) + d * (g < b ? 6 : 0); h /= 6 * d; break;
+    case g: h = (b - r) + d * 2; h /= 6 * d; break;
+    case b: h = (r - g) + d * 4; h /= 6 * d; break;
+    default: break;
+  }
+
+  return [
+    h,
+    s,
+    v,
+  ];
+}
+
+function addSaturationToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[1] += offset;
+  if (hsv[1] > 1) {
+    hsv[1] = 1;
+  } else if (hsv[1] <= 0) {
+    hsv[1] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addBrightnessToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[2] += offset;
+  if (hsv[2] > 1) {
+    hsv[2] = 1;
+  } else if (hsv[2] < 0) {
+    hsv[2] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addHueToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[0] += offset / 360;
+  if (hsv[0] > 1) {
+    hsv[0] -= 1;
+  } else if (hsv[0] < 0) {
+    hsv[0] += 1;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+const rgbToHex = (function () {
+  var colorMap = [];
+  var i;
+  var hex;
+  for (i = 0; i < 256; i += 1) {
+    hex = i.toString(16);
+    colorMap[i] = hex.length === 1 ? '0' + hex : hex;
+  }
+
+  return function (r, g, b) {
+    if (r < 0) {
+      r = 0;
+    }
+    if (g < 0) {
+      g = 0;
+    }
+    if (b < 0) {
+      b = 0;
+    }
+    return '#' + colorMap[r] + colorMap[g] + colorMap[b];
+  };
+}());
+
+const setSubframeEnabled = (flag) => { subframeEnabled = !!flag; };
+const getSubframeEnabled = () => subframeEnabled;
+const setExpressionsPlugin = (value) => { expressionsPlugin = value; };
+const getExpressionsPlugin = () => expressionsPlugin;
+const setExpressionInterfaces = (value) => { expressionsInterfaces = value; };
+const getExpressionInterfaces = () => expressionsInterfaces;
+const setDefaultCurveSegments = (value) => { defaultCurveSegments = value; };
+const getDefaultCurveSegments = () => defaultCurveSegments;
+const setIdPrefix = (value) => { idPrefix$1 = value; };
+const getIdPrefix = () => idPrefix$1;
+
+function createNS(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElementNS(svgNS, type);
+}
+
+const dataManager = (function () {
+  var _counterId = 1;
+  var processes = [];
+  var workerFn;
+  var workerInstance;
+  var workerProxy = {
+    onmessage: function () {
+
+    },
+    postMessage: function (path) {
+      workerFn({
+        data: path,
+      });
+    },
+  };
+  var _workerSelf = {
+    postMessage: function (data) {
+      workerProxy.onmessage({
+        data: data,
+      });
+    },
+  };
+  function createWorker(fn) {
+    if (window.Worker && window.Blob && getWebWorker()) {
+      var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      var url = URL.createObjectURL(blob);
+      return new Worker(url);
+    }
+    workerFn = fn;
+    return workerProxy;
+  }
+
+  function setupWorker() {
+    if (!workerInstance) {
+      workerInstance = createWorker(function workerStart(e) {
+        function dataFunctionManager() {
+          function completeLayers(layers, comps) {
+            var layerData;
+            var i;
+            var len = layers.length;
+            var j;
+            var jLen;
+            var k;
+            var kLen;
+            for (i = 0; i < len; i += 1) {
+              layerData = layers[i];
+              if (('ks' in layerData) && !layerData.completed) {
+                layerData.completed = true;
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      convertPathsToAbsoluteValues(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) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 0) {
+                  layerData.layers = findCompLayers(layerData.refId, comps);
+                  completeLayers(layerData.layers, comps);
+                } else if (layerData.ty === 4) {
+                  completeShapes(layerData.shapes);
+                } else if (layerData.ty === 5) {
+                  completeText(layerData);
+                }
+              }
+            }
+          }
+
+          function completeChars(chars, assets) {
+            if (chars) {
+              var i = 0;
+              var len = chars.length;
+              for (i = 0; i < len; i += 1) {
+                if (chars[i].t === 1) {
+                  // var compData = findComp(chars[i].data.refId, assets);
+                  chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                  // chars[i].data.ip = 0;
+                  // chars[i].data.op = 99999;
+                  // chars[i].data.st = 0;
+                  // chars[i].data.sr = 1;
+                  // chars[i].w = compData.w;
+                  // chars[i].data.ks = {
+                  //   a: { k: [0, 0, 0], a: 0 },
+                  //   p: { k: [0, -compData.h, 0], a: 0 },
+                  //   r: { k: 0, a: 0 },
+                  //   s: { k: [100, 100], a: 0 },
+                  //   o: { k: 100, a: 0 },
+                  // };
+                  completeLayers(chars[i].data.layers, assets);
+                }
+              }
+            }
+          }
+
+          function findComp(id, comps) {
+            var i = 0;
+            var len = comps.length;
+            while (i < len) {
+              if (comps[i].id === id) {
+                return comps[i];
+              }
+              i += 1;
+            }
+            return null;
+          }
+
+          function findCompLayers(id, comps) {
+            var comp = findComp(id, comps);
+            if (comp) {
+              if (!comp.layers.__used) {
+                comp.layers.__used = true;
+                return comp.layers;
+              }
+              return JSON.parse(JSON.stringify(comp.layers));
+            }
+            return null;
+          }
+
+          function completeShapes(arr) {
+            var i;
+            var len = arr.length;
+            var j;
+            var jLen;
+            for (i = len - 1; i >= 0; i -= 1) {
+              if (arr[i].ty === 'sh') {
+                if (arr[i].ks.k.i) {
+                  convertPathsToAbsoluteValues(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) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
+                    }
+                    if (arr[i].ks.k[j].e) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
+                    }
+                  }
+                }
+              } else if (arr[i].ty === 'gr') {
+                completeShapes(arr[i].it);
+              }
+            }
+          }
+
+          function convertPathsToAbsoluteValues(path) {
+            var i;
+            var len = path.i.length;
+            for (i = 0; i < len; i += 1) {
+              path.i[i][0] += path.v[i][0];
+              path.i[i][1] += path.v[i][1];
+              path.o[i][0] += path.v[i][0];
+              path.o[i][1] += path.v[i][1];
+            }
+          }
+
+          function checkVersion(minimum, animVersionString) {
+            var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
+            if (minimum[0] > animVersion[0]) {
+              return true;
+            } if (animVersion[0] > minimum[0]) {
+              return false;
+            }
+            if (minimum[1] > animVersion[1]) {
+              return true;
+            } if (animVersion[1] > minimum[1]) {
+              return false;
+            }
+            if (minimum[2] > animVersion[2]) {
+              return true;
+            } if (animVersion[2] > minimum[2]) {
+              return false;
+            }
+            return null;
+          }
+
+          var checkText = (function () {
+            var minimumVersion = [4, 4, 14];
+
+            function updateTextLayer(textLayer) {
+              var documentData = textLayer.t.d;
+              textLayer.t.d = {
+                k: [
+                  {
+                    s: documentData,
+                    t: 0,
+                  },
+                ],
+              };
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkChars = (function () {
+            var minimumVersion = [4, 7, 99];
+            return function (animationData) {
+              if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
+                var i;
+                var len = animationData.chars.length;
+                for (i = 0; i < len; i += 1) {
+                  var charData = animationData.chars[i];
+                  if (charData.data && charData.data.shapes) {
+                    completeShapes(charData.data.shapes);
+                    charData.data.ip = 0;
+                    charData.data.op = 99999;
+                    charData.data.st = 0;
+                    charData.data.sr = 1;
+                    charData.data.ks = {
+                      p: { k: [0, 0], a: 0 },
+                      s: { k: [100, 100], a: 0 },
+                      a: { k: [0, 0], a: 0 },
+                      r: { k: 0, a: 0 },
+                      o: { k: 100, a: 0 },
+                    };
+                    if (!animationData.chars[i].t) {
+                      charData.data.shapes.push(
+                        {
+                          ty: 'no',
+                        }
+                      );
+                      charData.data.shapes[0].it.push(
+                        {
+                          p: { k: [0, 0], a: 0 },
+                          s: { k: [100, 100], a: 0 },
+                          a: { k: [0, 0], a: 0 },
+                          r: { k: 0, a: 0 },
+                          o: { k: 100, a: 0 },
+                          sk: { k: 0, a: 0 },
+                          sa: { k: 0, a: 0 },
+                          ty: 'tr',
+                        }
+                      );
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkPathProperties = (function () {
+            var minimumVersion = [5, 7, 15];
+
+            function updateTextLayer(textLayer) {
+              var pathData = textLayer.t.p;
+              if (typeof pathData.a === 'number') {
+                pathData.a = {
+                  a: 0,
+                  k: pathData.a,
+                };
+              }
+              if (typeof pathData.p === 'number') {
+                pathData.p = {
+                  a: 0,
+                  k: pathData.p,
+                };
+              }
+              if (typeof pathData.r === 'number') {
+                pathData.r = {
+                  a: 0,
+                  k: pathData.r,
+                };
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkColors = (function () {
+            var minimumVersion = [4, 1, 9];
+
+            function iterateShapes(shapes) {
+              var i;
+              var len = shapes.length;
+              var j;
+              var jLen;
+              for (i = 0; i < len; i += 1) {
+                if (shapes[i].ty === 'gr') {
+                  iterateShapes(shapes[i].it);
+                } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
+                  if (shapes[i].c.k && shapes[i].c.k[0].i) {
+                    jLen = shapes[i].c.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (shapes[i].c.k[j].s) {
+                        shapes[i].c.k[j].s[0] /= 255;
+                        shapes[i].c.k[j].s[1] /= 255;
+                        shapes[i].c.k[j].s[2] /= 255;
+                        shapes[i].c.k[j].s[3] /= 255;
+                      }
+                      if (shapes[i].c.k[j].e) {
+                        shapes[i].c.k[j].e[0] /= 255;
+                        shapes[i].c.k[j].e[1] /= 255;
+                        shapes[i].c.k[j].e[2] /= 255;
+                        shapes[i].c.k[j].e[3] /= 255;
+                      }
+                    }
+                  } else {
+                    shapes[i].c.k[0] /= 255;
+                    shapes[i].c.k[1] /= 255;
+                    shapes[i].c.k[2] /= 255;
+                    shapes[i].c.k[3] /= 255;
+                  }
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 4) {
+                  iterateShapes(layers[i].shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkShapes = (function () {
+            var minimumVersion = [4, 4, 18];
+
+            function completeClosingShapes(arr) {
+              var i;
+              var len = arr.length;
+              var j;
+              var jLen;
+              for (i = len - 1; i >= 0; i -= 1) {
+                if (arr[i].ty === 'sh') {
+                  if (arr[i].ks.k.i) {
+                    arr[i].ks.k.c = arr[i].closed;
+                  } else {
+                    jLen = arr[i].ks.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (arr[i].ks.k[j].s) {
+                        arr[i].ks.k[j].s[0].c = arr[i].closed;
+                      }
+                      if (arr[i].ks.k[j].e) {
+                        arr[i].ks.k[j].e[0].c = arr[i].closed;
+                      }
+                    }
+                  }
+                } else if (arr[i].ty === 'gr') {
+                  completeClosingShapes(arr[i].it);
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var layerData;
+              var i;
+              var len = layers.length;
+              var j;
+              var jLen;
+              var k;
+              var kLen;
+              for (i = 0; i < len; i += 1) {
+                layerData = layers[i];
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      maskProps[j].pt.k.c = maskProps[j].cl;
+                    } else {
+                      kLen = maskProps[j].pt.k.length;
+                      for (k = 0; k < kLen; k += 1) {
+                        if (maskProps[j].pt.k[k].s) {
+                          maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 4) {
+                  completeClosingShapes(layerData.shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          function completeData(animationData) {
+            if (animationData.__complete) {
+              return;
+            }
+            checkColors(animationData);
+            checkText(animationData);
+            checkChars(animationData);
+            checkPathProperties(animationData);
+            checkShapes(animationData);
+            completeLayers(animationData.layers, animationData.assets);
+            completeChars(animationData.chars, animationData.assets);
+            animationData.__complete = true;
+          }
+
+          function completeText(data) {
+            if (data.t.a.length === 0 && !('m' in data.t.p)) {
+              // data.singleShape = true;
+            }
+          }
+
+          var moduleOb = {};
+          moduleOb.completeData = completeData;
+          moduleOb.checkColors = checkColors;
+          moduleOb.checkChars = checkChars;
+          moduleOb.checkPathProperties = checkPathProperties;
+          moduleOb.checkShapes = checkShapes;
+          moduleOb.completeLayers = completeLayers;
+
+          return moduleOb;
+        }
+        if (!_workerSelf.dataManager) {
+          _workerSelf.dataManager = dataFunctionManager();
+        }
+
+        if (!_workerSelf.assetLoader) {
+          _workerSelf.assetLoader = (function () {
+            function formatResponse(xhr) {
+              // using typeof doubles the time of execution of this method,
+              // so if available, it's better to use the header to validate the type
+              var contentTypeHeader = xhr.getResponseHeader('content-type');
+              if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
+                return xhr.response;
+              }
+              if (xhr.response && typeof xhr.response === 'object') {
+                return xhr.response;
+              } if (xhr.response && typeof xhr.response === 'string') {
+                return JSON.parse(xhr.response);
+              } if (xhr.responseText) {
+                return JSON.parse(xhr.responseText);
+              }
+              return null;
+            }
+
+            function loadAsset(path, fullPath, callback, errorCallback) {
+              var response;
+              var xhr = new XMLHttpRequest();
+              // set responseType after calling open or IE will break.
+              try {
+                // This crashes on Android WebView prior to KitKat
+                xhr.responseType = 'json';
+              } catch (err) {} // eslint-disable-line no-empty
+              xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4) {
+                  if (xhr.status === 200) {
+                    response = formatResponse(xhr);
+                    callback(response);
+                  } else {
+                    try {
+                      response = formatResponse(xhr);
+                      callback(response);
+                    } catch (err) {
+                      if (errorCallback) {
+                        errorCallback(err);
+                      }
+                    }
+                  }
+                }
+              };
+              try {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), path, true);
+              } catch (error) {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
+              }
+              xhr.send();
+            }
+            return {
+              load: loadAsset,
+            };
+          }());
+        }
+
+        if (e.data.type === 'loadAnimation') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.dataManager.completeData(data);
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        } else if (e.data.type === 'complete') {
+          var animation = e.data.animation;
+          _workerSelf.dataManager.completeData(animation);
+          _workerSelf.postMessage({
+            id: e.data.id,
+            payload: animation,
+            status: 'success',
+          });
+        } else if (e.data.type === 'loadData') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        }
+      });
+
+      workerInstance.onmessage = function (event) {
+        var data = event.data;
+        var id = data.id;
+        var process = processes[id];
+        processes[id] = null;
+        if (data.status === 'success') {
+          process.onComplete(data.payload);
+        } else if (process.onError) {
+          process.onError();
+        }
+      };
+    }
+  }
+
+  function createProcess(onComplete, onError) {
+    _counterId += 1;
+    var id = 'processId_' + _counterId;
+    processes[id] = {
+      onComplete: onComplete,
+      onError: onError,
+    };
+    return id;
+  }
+
+  function loadAnimation(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadAnimation',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function loadData(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadData',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function completeAnimation(anim, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'complete',
+      animation: anim,
+      id: processId,
+    });
+  }
+
+  return {
+    loadAnimation: loadAnimation,
+    loadData: loadData,
+    completeAnimation: completeAnimation,
+  };
+}());
+
+const ImagePreloader = (function () {
+  var proxyImage = (function () {
+    var canvas = createTag('canvas');
+    canvas.width = 1;
+    canvas.height = 1;
+    var ctx = canvas.getContext('2d');
+    ctx.fillStyle = 'rgba(0,0,0,0)';
+    ctx.fillRect(0, 0, 1, 1);
+    return canvas;
+  }());
+
+  function imageLoaded() {
+    this.loadedAssets += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+  function footageLoaded() {
+    this.loadedFootagesCount += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+
+  function getAssetsPath(assetData, assetsPath, originalPath) {
+    var path = '';
+    if (assetData.e) {
+      path = assetData.p;
+    } else if (assetsPath) {
+      var imagePath = assetData.p;
+      if (imagePath.indexOf('images/') !== -1) {
+        imagePath = imagePath.split('/')[1];
+      }
+      path = assetsPath + imagePath;
+    } else {
+      path = originalPath;
+      path += assetData.u ? assetData.u : '';
+      path += assetData.p;
+    }
+    return path;
+  }
+
+  function testImageLoaded(img) {
+    var _count = 0;
+    var intervalId = setInterval(function () {
+      var box = img.getBBox();
+      if (box.width || _count > 500) {
+        this._imageLoaded();
+        clearInterval(intervalId);
+      }
+      _count += 1;
+    }.bind(this), 50);
+  }
+
+  function createImageData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createNS('image');
+    if (isSafari) {
+      this.testImageLoaded(img);
+    } else {
+      img.addEventListener('load', this._imageLoaded, false);
+    }
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
+    if (this._elementHelper.append) {
+      this._elementHelper.append(img);
+    } else {
+      this._elementHelper.appendChild(img);
+    }
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createImgData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createTag('img');
+    img.crossOrigin = 'anonymous';
+    img.addEventListener('load', this._imageLoaded, false);
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.src = path;
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createFootageData(data) {
+    var ob = {
+      assetData: data,
+    };
+    var path = getAssetsPath(data, this.assetsPath, this.path);
+    dataManager.loadData(path, function (footageData) {
+      ob.img = footageData;
+      this._footageLoaded();
+    }.bind(this), function () {
+      ob.img = {};
+      this._footageLoaded();
+    }.bind(this));
+    return ob;
+  }
+
+  function loadAssets(assets, cb) {
+    this.imagesLoadedCb = cb;
+    var i;
+    var len = assets.length;
+    for (i = 0; i < len; i += 1) {
+      if (!assets[i].layers) {
+        if (!assets[i].t || assets[i].t === 'seq') {
+          this.totalImages += 1;
+          this.images.push(this._createImageData(assets[i]));
+        } else if (assets[i].t === 3) {
+          this.totalFootages += 1;
+          this.images.push(this.createFootageData(assets[i]));
+        }
+      }
+    }
+  }
+
+  function setPath(path) {
+    this.path = path || '';
+  }
+
+  function setAssetsPath(path) {
+    this.assetsPath = path || '';
+  }
+
+  function getAsset(assetData) {
+    var i = 0;
+    var len = this.images.length;
+    while (i < len) {
+      if (this.images[i].assetData === assetData) {
+        return this.images[i].img;
+      }
+      i += 1;
+    }
+    return null;
+  }
+
+  function destroy() {
+    this.imagesLoadedCb = null;
+    this.images.length = 0;
+  }
+
+  function loadedImages() {
+    return this.totalImages === this.loadedAssets;
+  }
+
+  function loadedFootages() {
+    return this.totalFootages === this.loadedFootagesCount;
+  }
+
+  function setCacheType(type, elementHelper) {
+    if (type === 'svg') {
+      this._elementHelper = elementHelper;
+      this._createImageData = this.createImageData.bind(this);
+    } else {
+      this._createImageData = this.createImgData.bind(this);
+    }
+  }
+
+  function ImagePreloaderFactory() {
+    this._imageLoaded = imageLoaded.bind(this);
+    this._footageLoaded = footageLoaded.bind(this);
+    this.testImageLoaded = testImageLoaded.bind(this);
+    this.createFootageData = createFootageData.bind(this);
+    this.assetsPath = '';
+    this.path = '';
+    this.totalImages = 0;
+    this.totalFootages = 0;
+    this.loadedAssets = 0;
+    this.loadedFootagesCount = 0;
+    this.imagesLoadedCb = null;
+    this.images = [];
+  }
+
+  ImagePreloaderFactory.prototype = {
+    loadAssets: loadAssets,
+    setAssetsPath: setAssetsPath,
+    setPath: setPath,
+    loadedImages: loadedImages,
+    loadedFootages: loadedFootages,
+    destroy: destroy,
+    getAsset: getAsset,
+    createImgData: createImgData,
+    createImageData: createImageData,
+    imageLoaded: imageLoaded,
+    footageLoaded: footageLoaded,
+    setCacheType: setCacheType,
+  };
+
+  return ImagePreloaderFactory;
+}());
+
+function BaseEvent() {}
+BaseEvent.prototype = {
+  triggerEvent: function (eventName, args) {
+    if (this._cbs[eventName]) {
+      var callbacks = this._cbs[eventName];
+      for (var i = 0; i < callbacks.length; i += 1) {
+        callbacks[i](args);
+      }
+    }
+  },
+  addEventListener: function (eventName, callback) {
+    if (!this._cbs[eventName]) {
+      this._cbs[eventName] = [];
+    }
+    this._cbs[eventName].push(callback);
+
+    return function () {
+      this.removeEventListener(eventName, callback);
+    }.bind(this);
+  },
+  removeEventListener: function (eventName, callback) {
+    if (!callback) {
+      this._cbs[eventName] = null;
+    } else if (this._cbs[eventName]) {
+      var i = 0;
+      var len = this._cbs[eventName].length;
+      while (i < len) {
+        if (this._cbs[eventName][i] === callback) {
+          this._cbs[eventName].splice(i, 1);
+          i -= 1;
+          len -= 1;
+        }
+        i += 1;
+      }
+      if (!this._cbs[eventName].length) {
+        this._cbs[eventName] = null;
+      }
+    }
+  },
+};
+
+const markerParser = (
+
+  function () {
+    function parsePayloadLines(payload) {
+      var lines = payload.split('\r\n');
+      var keys = {};
+      var line;
+      var keysCount = 0;
+      for (var i = 0; i < lines.length; i += 1) {
+        line = lines[i].split(':');
+        if (line.length === 2) {
+          keys[line[0]] = line[1].trim();
+          keysCount += 1;
+        }
+      }
+      if (keysCount === 0) {
+        throw new Error();
+      }
+      return keys;
+    }
+
+    return function (_markers) {
+      var markers = [];
+      for (var i = 0; i < _markers.length; i += 1) {
+        var _marker = _markers[i];
+        var markerData = {
+          time: _marker.tm,
+          duration: _marker.dr,
+        };
+        try {
+          markerData.payload = JSON.parse(_markers[i].cm);
+        } catch (_) {
+          try {
+            markerData.payload = parsePayloadLines(_markers[i].cm);
+          } catch (__) {
+            markerData.payload = {
+              name: _markers[i].cm,
+            };
+          }
+        }
+        markers.push(markerData);
+      }
+      return markers;
+    };
+  }());
+
+const ProjectInterface = (function () {
+  function registerComposition(comp) {
+    this.compositions.push(comp);
+  }
+
+  return function () {
+    function _thisProjectFunction(name) {
+      var i = 0;
+      var len = this.compositions.length;
+      while (i < len) {
+        if (this.compositions[i].data && this.compositions[i].data.nm === name) {
+          if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
+            this.compositions[i].prepareFrame(this.currentFrame);
+          }
+          return this.compositions[i].compInterface;
+        }
+        i += 1;
+      }
+      return null;
+    }
+
+    _thisProjectFunction.compositions = [];
+    _thisProjectFunction.currentFrame = 0;
+
+    _thisProjectFunction.registerComposition = registerComposition;
+
+    return _thisProjectFunction;
+  };
+}());
+
+const renderers = {};
+
+const registerRenderer = (key, value) => {
+  renderers[key] = value;
+};
+
+function getRenderer(key) {
+  return renderers[key];
+}
+
+function getRegisteredRenderer() {
+  // Returns canvas by default for compatibility
+  if (renderers.canvas) {
+    return 'canvas';
+  }
+  // Returns any renderer that is registered
+  for (const key in renderers) {
+    if (renderers[key]) {
+      return key;
+    }
+  }
+  return '';
+}
+
+const AnimationItem = function () {
+  this._cbs = [];
+  this.name = '';
+  this.path = '';
+  this.isLoaded = false;
+  this.currentFrame = 0;
+  this.currentRawFrame = 0;
+  this.firstFrame = 0;
+  this.totalFrames = 0;
+  this.frameRate = 0;
+  this.frameMult = 0;
+  this.playSpeed = 1;
+  this.playDirection = 1;
+  this.playCount = 0;
+  this.animationData = {};
+  this.assets = [];
+  this.isPaused = true;
+  this.autoplay = false;
+  this.loop = true;
+  this.renderer = null;
+  this.animationID = createElementID();
+  this.assetsPath = '';
+  this.timeCompleted = 0;
+  this.segmentPos = 0;
+  this.isSubframeEnabled = getSubframeEnabled();
+  this.segments = [];
+  this._idle = true;
+  this._completedLoop = false;
+  this.projectInterface = ProjectInterface();
+  this.imagePreloader = new ImagePreloader();
+  this.audioController = audioControllerFactory();
+  this.markers = [];
+  this.configAnimation = this.configAnimation.bind(this);
+  this.onSetupError = this.onSetupError.bind(this);
+  this.onSegmentComplete = this.onSegmentComplete.bind(this);
+  this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
+  this.expressionsPlugin = getExpressionsPlugin();
+};
+
+extendPrototype([BaseEvent], AnimationItem);
+
+AnimationItem.prototype.setParams = function (params) {
+  if (params.wrapper || params.container) {
+    this.wrapper = params.wrapper || params.container;
+  }
+  var animType = 'svg';
+  if (params.animType) {
+    animType = params.animType;
+  } else if (params.renderer) {
+    animType = params.renderer;
+  }
+  const RendererClass = getRenderer(animType);
+  this.renderer = new RendererClass(this, params.rendererSettings);
+  this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
+  this.renderer.setProjectInterface(this.projectInterface);
+  this.animType = animType;
+  if (params.loop === ''
+        || params.loop === null
+        || params.loop === undefined
+        || params.loop === true) {
+    this.loop = true;
+  } else if (params.loop === false) {
+    this.loop = false;
+  } else {
+    this.loop = parseInt(params.loop, 10);
+  }
+  this.autoplay = 'autoplay' in params ? params.autoplay : true;
+  this.name = params.name ? params.name : '';
+  this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
+  this.assetsPath = params.assetsPath;
+  this.initialSegment = params.initialSegment;
+  if (params.audioFactory) {
+    this.audioController.setAudioFactory(params.audioFactory);
+  }
+  if (params.animationData) {
+    this.setupAnimation(params.animationData);
+  } else if (params.path) {
+    if (params.path.lastIndexOf('\\') !== -1) {
+      this.path = params.path.substr(0, params.path.lastIndexOf('\\') + 1);
+    } else {
+      this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
+    }
+    this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
+    this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
+    dataManager.loadAnimation(
+      params.path,
+      this.configAnimation,
+      this.onSetupError
+    );
+  }
+};
+
+AnimationItem.prototype.onSetupError = function () {
+  this.trigger('data_failed');
+};
+
+AnimationItem.prototype.setupAnimation = function (data) {
+  dataManager.completeAnimation(
+    data,
+    this.configAnimation
+  );
+};
+
+AnimationItem.prototype.setData = function (wrapper, animationData) {
+  if (animationData) {
+    if (typeof animationData !== 'object') {
+      animationData = JSON.parse(animationData);
+    }
+  }
+  var params = {
+    wrapper: wrapper,
+    animationData: animationData,
+  };
+  var wrapperAttributes = wrapper.attributes;
+
+  params.path = wrapperAttributes.getNamedItem('data-animation-path') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-animation-path').value
+    : wrapperAttributes.getNamedItem('data-bm-path') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-path').value
+      : wrapperAttributes.getNamedItem('bm-path')
+        ? wrapperAttributes.getNamedItem('bm-path').value
+        : '';
+  params.animType = wrapperAttributes.getNamedItem('data-anim-type') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-type').value
+    : wrapperAttributes.getNamedItem('data-bm-type') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-type').value
+      : wrapperAttributes.getNamedItem('bm-type') // eslint-disable-line no-nested-ternary
+        ? wrapperAttributes.getNamedItem('bm-type').value
+        : wrapperAttributes.getNamedItem('data-bm-renderer') // eslint-disable-line no-nested-ternary
+          ? wrapperAttributes.getNamedItem('data-bm-renderer').value
+          : wrapperAttributes.getNamedItem('bm-renderer')
+            ? wrapperAttributes.getNamedItem('bm-renderer').value
+            : getRegisteredRenderer() || 'canvas';
+
+  var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-loop').value
+    : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-loop').value
+      : wrapperAttributes.getNamedItem('bm-loop')
+        ? wrapperAttributes.getNamedItem('bm-loop').value
+        : '';
+  if (loop === 'false') {
+    params.loop = false;
+  } else if (loop === 'true') {
+    params.loop = true;
+  } else if (loop !== '') {
+    params.loop = parseInt(loop, 10);
+  }
+  var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-autoplay').value
+    : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-autoplay').value
+      : wrapperAttributes.getNamedItem('bm-autoplay')
+        ? wrapperAttributes.getNamedItem('bm-autoplay').value
+        : true;
+  params.autoplay = autoplay !== 'false';
+
+  params.name = wrapperAttributes.getNamedItem('data-name') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-name').value
+    : wrapperAttributes.getNamedItem('data-bm-name') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-name').value
+      : wrapperAttributes.getNamedItem('bm-name')
+        ? wrapperAttributes.getNamedItem('bm-name').value
+        : '';
+  var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-prerender').value
+    : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-prerender').value
+      : wrapperAttributes.getNamedItem('bm-prerender')
+        ? wrapperAttributes.getNamedItem('bm-prerender').value
+        : '';
+
+  if (prerender === 'false') {
+    params.prerender = false;
+  }
+  if (!params.path) {
+    this.trigger('destroy');
+  } else {
+    this.setParams(params);
+  }
+};
+
+AnimationItem.prototype.includeLayers = function (data) {
+  if (data.op > this.animationData.op) {
+    this.animationData.op = data.op;
+    this.totalFrames = Math.floor(data.op - this.animationData.ip);
+  }
+  var layers = this.animationData.layers;
+  var i;
+  var len = layers.length;
+  var newLayers = data.layers;
+  var j;
+  var jLen = newLayers.length;
+  for (j = 0; j < jLen; j += 1) {
+    i = 0;
+    while (i < len) {
+      if (layers[i].id === newLayers[j].id) {
+        layers[i] = newLayers[j];
+        break;
+      }
+      i += 1;
+    }
+  }
+  if (data.chars || data.fonts) {
+    this.renderer.globalData.fontManager.addChars(data.chars);
+    this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
+  }
+  if (data.assets) {
+    len = data.assets.length;
+    for (i = 0; i < len; i += 1) {
+      this.animationData.assets.push(data.assets[i]);
+    }
+  }
+  this.animationData.__complete = false;
+  dataManager.completeAnimation(
+    this.animationData,
+    this.onSegmentComplete
+  );
+};
+
+AnimationItem.prototype.onSegmentComplete = function (data) {
+  this.animationData = data;
+  var expressionsPlugin = getExpressionsPlugin();
+  if (expressionsPlugin) {
+    expressionsPlugin.initExpressions(this);
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.loadNextSegment = function () {
+  var segments = this.animationData.segments;
+  if (!segments || segments.length === 0 || !this.autoloadSegments) {
+    this.trigger('data_ready');
+    this.timeCompleted = this.totalFrames;
+    return;
+  }
+  var segment = segments.shift();
+  this.timeCompleted = segment.time * this.frameRate;
+  var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
+  this.segmentPos += 1;
+  dataManager.loadData(segmentPath, this.includeLayers.bind(this), function () {
+    this.trigger('data_failed');
+  }.bind(this));
+};
+
+AnimationItem.prototype.loadSegments = function () {
+  var segments = this.animationData.segments;
+  if (!segments) {
+    this.timeCompleted = this.totalFrames;
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.imagesLoaded = function () {
+  this.trigger('loaded_images');
+  this.checkLoaded();
+};
+
+AnimationItem.prototype.preloadImages = function () {
+  this.imagePreloader.setAssetsPath(this.assetsPath);
+  this.imagePreloader.setPath(this.path);
+  this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
+};
+
+AnimationItem.prototype.configAnimation = function (animData) {
+  if (!this.renderer) {
+    return;
+  }
+  try {
+    this.animationData = animData;
+    if (this.initialSegment) {
+      this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
+      this.firstFrame = Math.round(this.initialSegment[0]);
+    } else {
+      this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
+      this.firstFrame = Math.round(this.animationData.ip);
+    }
+    this.renderer.configAnimation(animData);
+    if (!animData.assets) {
+      animData.assets = [];
+    }
+
+    this.assets = this.animationData.assets;
+    this.frameRate = this.animationData.fr;
+    this.frameMult = this.animationData.fr / 1000;
+    this.renderer.searchExtraCompositions(animData.assets);
+    this.markers = markerParser(animData.markers || []);
+    this.trigger('config_ready');
+    this.preloadImages();
+    this.loadSegments();
+    this.updaFrameModifier();
+    this.waitForFontsLoaded();
+    if (this.isPaused) {
+      this.audioController.pause();
+    }
+  } catch (error) {
+    this.triggerConfigError(error);
+  }
+};
+
+AnimationItem.prototype.waitForFontsLoaded = function () {
+  if (!this.renderer) {
+    return;
+  }
+  if (this.renderer.globalData.fontManager.isLoaded) {
+    this.checkLoaded();
+  } else {
+    setTimeout(this.waitForFontsLoaded.bind(this), 20);
+  }
+};
+
+AnimationItem.prototype.checkLoaded = function () {
+  if (!this.isLoaded
+        && this.renderer.globalData.fontManager.isLoaded
+        && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas')
+        && (this.imagePreloader.loadedFootages())
+  ) {
+    this.isLoaded = true;
+    var expressionsPlugin = getExpressionsPlugin();
+    if (expressionsPlugin) {
+      expressionsPlugin.initExpressions(this);
+    }
+    this.renderer.initItems();
+    setTimeout(function () {
+      this.trigger('DOMLoaded');
+    }.bind(this), 0);
+    this.gotoFrame();
+    if (this.autoplay) {
+      this.play();
+    }
+  }
+};
+
+AnimationItem.prototype.resize = function (width, height) {
+  // Adding this validation for backwards compatibility in case an event object was being passed down
+  var _width = typeof width === 'number' ? width : undefined;
+  var _height = typeof height === 'number' ? height : undefined;
+  this.renderer.updateContainerSize(_width, _height);
+};
+
+AnimationItem.prototype.setSubframe = function (flag) {
+  this.isSubframeEnabled = !!flag;
+};
+
+AnimationItem.prototype.gotoFrame = function () {
+  this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
+
+  if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
+    this.currentFrame = this.timeCompleted;
+  }
+  this.trigger('enterFrame');
+  this.renderFrame();
+  this.trigger('drawnFrame');
+};
+
+AnimationItem.prototype.renderFrame = function () {
+  if (this.isLoaded === false || !this.renderer) {
+    return;
+  }
+  try {
+    if (this.expressionsPlugin) {
+      this.expressionsPlugin.resetFrame();
+    }
+    this.renderer.renderFrame(this.currentFrame + this.firstFrame);
+  } catch (error) {
+    this.triggerRenderFrameError(error);
+  }
+};
+
+AnimationItem.prototype.play = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.isPaused = false;
+    this.trigger('_play');
+    this.audioController.resume();
+    if (this._idle) {
+      this._idle = false;
+      this.trigger('_active');
+    }
+  }
+};
+
+AnimationItem.prototype.pause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === false) {
+    this.isPaused = true;
+    this.trigger('_pause');
+    this._idle = true;
+    this.trigger('_idle');
+    this.audioController.pause();
+  }
+};
+
+AnimationItem.prototype.togglePause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.play();
+  } else {
+    this.pause();
+  }
+};
+
+AnimationItem.prototype.stop = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.pause();
+  this.playCount = 0;
+  this._completedLoop = false;
+  this.setCurrentRawFrameValue(0);
+};
+
+AnimationItem.prototype.getMarkerData = function (markerName) {
+  var marker;
+  for (var i = 0; i < this.markers.length; i += 1) {
+    marker = this.markers[i];
+    if (marker.payload && marker.payload.name === markerName) {
+      return marker;
+    }
+  }
+  return null;
+};
+
+AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      this.goToAndStop(marker.time, true);
+    }
+  } else if (isFrame) {
+    this.setCurrentRawFrameValue(value);
+  } else {
+    this.setCurrentRawFrameValue(value * this.frameModifier);
+  }
+  this.pause();
+};
+
+AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      if (!marker.duration) {
+        this.goToAndStop(marker.time, true);
+      } else {
+        this.playSegments([marker.time, marker.time + marker.duration], true);
+      }
+    }
+  } else {
+    this.goToAndStop(numValue, isFrame, name);
+  }
+  this.play();
+};
+
+AnimationItem.prototype.advanceTime = function (value) {
+  if (this.isPaused === true || this.isLoaded === false) {
+    return;
+  }
+  var nextValue = this.currentRawFrame + value * this.frameModifier;
+  var _isComplete = false;
+  // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+  // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
+  if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
+    if (!this.loop || this.playCount === this.loop) {
+      if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
+        _isComplete = true;
+        nextValue = this.totalFrames - 1;
+      }
+    } else if (nextValue >= this.totalFrames) {
+      this.playCount += 1;
+      if (!this.checkSegments(nextValue % this.totalFrames)) {
+        this.setCurrentRawFrameValue(nextValue % this.totalFrames);
+        this._completedLoop = true;
+        this.trigger('loopComplete');
+      }
+    } else {
+      this.setCurrentRawFrameValue(nextValue);
+    }
+  } else if (nextValue < 0) {
+    if (!this.checkSegments(nextValue % this.totalFrames)) {
+      if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) { // eslint-disable-line no-plusplus
+        this.setCurrentRawFrameValue(this.totalFrames + (nextValue % this.totalFrames));
+        if (!this._completedLoop) {
+          this._completedLoop = true;
+        } else {
+          this.trigger('loopComplete');
+        }
+      } else {
+        _isComplete = true;
+        nextValue = 0;
+      }
+    }
+  } else {
+    this.setCurrentRawFrameValue(nextValue);
+  }
+  if (_isComplete) {
+    this.setCurrentRawFrameValue(nextValue);
+    this.pause();
+    this.trigger('complete');
+  }
+};
+
+AnimationItem.prototype.adjustSegment = function (arr, offset) {
+  this.playCount = 0;
+  if (arr[1] < arr[0]) {
+    if (this.frameModifier > 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(-1);
+      }
+    }
+    this.totalFrames = arr[0] - arr[1];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[1];
+    this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset);
+  } else if (arr[1] > arr[0]) {
+    if (this.frameModifier < 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(1);
+      }
+    }
+    this.totalFrames = arr[1] - arr[0];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[0];
+    this.setCurrentRawFrameValue(0.001 + offset);
+  }
+  this.trigger('segmentStart');
+};
+AnimationItem.prototype.setSegment = function (init, end) {
+  var pendingFrame = -1;
+  if (this.isPaused) {
+    if (this.currentRawFrame + this.firstFrame < init) {
+      pendingFrame = init;
+    } else if (this.currentRawFrame + this.firstFrame > end) {
+      pendingFrame = end - init;
+    }
+  }
+
+  this.firstFrame = init;
+  this.totalFrames = end - init;
+  this.timeCompleted = this.totalFrames;
+  if (pendingFrame !== -1) {
+    this.goToAndStop(pendingFrame, true);
+  }
+};
+
+AnimationItem.prototype.playSegments = function (arr, forceFlag) {
+  if (forceFlag) {
+    this.segments.length = 0;
+  }
+  if (typeof arr[0] === 'object') {
+    var i;
+    var len = arr.length;
+    for (i = 0; i < len; i += 1) {
+      this.segments.push(arr[i]);
+    }
+  } else {
+    this.segments.push(arr);
+  }
+  if (this.segments.length && forceFlag) {
+    this.adjustSegment(this.segments.shift(), 0);
+  }
+  if (this.isPaused) {
+    this.play();
+  }
+};
+
+AnimationItem.prototype.resetSegments = function (forceFlag) {
+  this.segments.length = 0;
+  this.segments.push([this.animationData.ip, this.animationData.op]);
+  if (forceFlag) {
+    this.checkSegments(0);
+  }
+};
+AnimationItem.prototype.checkSegments = function (offset) {
+  if (this.segments.length) {
+    this.adjustSegment(this.segments.shift(), offset);
+    return true;
+  }
+  return false;
+};
+
+AnimationItem.prototype.destroy = function (name) {
+  if ((name && this.name !== name) || !this.renderer) {
+    return;
+  }
+  this.renderer.destroy();
+  this.imagePreloader.destroy();
+  this.trigger('destroy');
+  this._cbs = null;
+  this.onEnterFrame = null;
+  this.onLoopComplete = null;
+  this.onComplete = null;
+  this.onSegmentStart = null;
+  this.onDestroy = null;
+  this.renderer = null;
+  this.expressionsPlugin = null;
+  this.imagePreloader = null;
+  this.projectInterface = null;
+};
+
+AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
+  this.currentRawFrame = value;
+  this.gotoFrame();
+};
+
+AnimationItem.prototype.setSpeed = function (val) {
+  this.playSpeed = val;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setDirection = function (val) {
+  this.playDirection = val < 0 ? -1 : 1;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setLoop = function (isLooping) {
+  this.loop = isLooping;
+};
+
+AnimationItem.prototype.setVolume = function (val, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.setVolume(val);
+};
+
+AnimationItem.prototype.getVolume = function () {
+  return this.audioController.getVolume();
+};
+
+AnimationItem.prototype.mute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.mute();
+};
+
+AnimationItem.prototype.unmute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.unmute();
+};
+
+AnimationItem.prototype.updaFrameModifier = function () {
+  this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
+  this.audioController.setRate(this.playSpeed * this.playDirection);
+};
+
+AnimationItem.prototype.getPath = function () {
+  return this.path;
+};
+
+AnimationItem.prototype.getAssetsPath = function (assetData) {
+  var path = '';
+  if (assetData.e) {
+    path = assetData.p;
+  } else if (this.assetsPath) {
+    var imagePath = assetData.p;
+    if (imagePath.indexOf('images/') !== -1) {
+      imagePath = imagePath.split('/')[1];
+    }
+    path = this.assetsPath + imagePath;
+  } else {
+    path = this.path;
+    path += assetData.u ? assetData.u : '';
+    path += assetData.p;
+  }
+  return path;
+};
+
+AnimationItem.prototype.getAssetData = function (id) {
+  var i = 0;
+  var len = this.assets.length;
+  while (i < len) {
+    if (id === this.assets[i].id) {
+      return this.assets[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+AnimationItem.prototype.hide = function () {
+  this.renderer.hide();
+};
+
+AnimationItem.prototype.show = function () {
+  this.renderer.show();
+};
+
+AnimationItem.prototype.getDuration = function (isFrame) {
+  return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
+};
+
+AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
+  try {
+    var element = this.renderer.getElementByPath(path);
+    element.updateDocumentData(documentData, index);
+  } catch (error) {
+    // TODO: decide how to handle catch case
+  }
+};
+
+AnimationItem.prototype.trigger = function (name) {
+  if (this._cbs && this._cbs[name]) {
+    switch (name) {
+      case 'enterFrame':
+        this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
+        break;
+      case 'drawnFrame':
+        this.drawnFrameEvent.currentTime = this.currentFrame;
+        this.drawnFrameEvent.totalTime = this.totalFrames;
+        this.drawnFrameEvent.direction = this.frameModifier;
+        this.triggerEvent(name, this.drawnFrameEvent);
+        break;
+      case 'loopComplete':
+        this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+        break;
+      case 'complete':
+        this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
+        break;
+      case 'segmentStart':
+        this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+        break;
+      case 'destroy':
+        this.triggerEvent(name, new BMDestroyEvent(name, this));
+        break;
+      default:
+        this.triggerEvent(name);
+    }
+  }
+  if (name === 'enterFrame' && this.onEnterFrame) {
+    this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
+  }
+  if (name === 'loopComplete' && this.onLoopComplete) {
+    this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+  }
+  if (name === 'complete' && this.onComplete) {
+    this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
+  }
+  if (name === 'segmentStart' && this.onSegmentStart) {
+    this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+  }
+  if (name === 'destroy' && this.onDestroy) {
+    this.onDestroy.call(this, new BMDestroyEvent(name, this));
+  }
+};
+
+AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
+  var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+AnimationItem.prototype.triggerConfigError = function (nativeError) {
+  var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+const animationManager = (function () {
+  var moduleOb = {};
+  var registeredAnimations = [];
+  var initTime = 0;
+  var len = 0;
+  var playingAnimationsNum = 0;
+  var _stopped = true;
+  var _isFrozen = false;
+
+  function removeElement(ev) {
+    var i = 0;
+    var animItem = ev.target;
+    while (i < len) {
+      if (registeredAnimations[i].animation === animItem) {
+        registeredAnimations.splice(i, 1);
+        i -= 1;
+        len -= 1;
+        if (!animItem.isPaused) {
+          subtractPlayingCount();
+        }
+      }
+      i += 1;
+    }
+  }
+
+  function registerAnimation(element, animationData) {
+    if (!element) {
+      return null;
+    }
+    var i = 0;
+    while (i < len) {
+      if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
+        return registeredAnimations[i].animation;
+      }
+      i += 1;
+    }
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, element);
+    animItem.setData(element, animationData);
+    return animItem;
+  }
+
+  function getRegisteredAnimations() {
+    var i;
+    var lenAnims = registeredAnimations.length;
+    var animations = [];
+    for (i = 0; i < lenAnims; i += 1) {
+      animations.push(registeredAnimations[i].animation);
+    }
+    return animations;
+  }
+
+  function addPlayingCount() {
+    playingAnimationsNum += 1;
+    activate();
+  }
+
+  function subtractPlayingCount() {
+    playingAnimationsNum -= 1;
+  }
+
+  function setupAnimation(animItem, element) {
+    animItem.addEventListener('destroy', removeElement);
+    animItem.addEventListener('_active', addPlayingCount);
+    animItem.addEventListener('_idle', subtractPlayingCount);
+    registeredAnimations.push({ elem: element, animation: animItem });
+    len += 1;
+  }
+
+  function loadAnimation(params) {
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, null);
+    animItem.setParams(params);
+    return animItem;
+  }
+
+  function setSpeed(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setSpeed(val, animation);
+    }
+  }
+
+  function setDirection(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setDirection(val, animation);
+    }
+  }
+
+  function play(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.play(animation);
+    }
+  }
+  function resume(nowTime) {
+    var elapsedTime = nowTime - initTime;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.advanceTime(elapsedTime);
+    }
+    initTime = nowTime;
+    if (playingAnimationsNum && !_isFrozen) {
+      window.requestAnimationFrame(resume);
+    } else {
+      _stopped = true;
+    }
+  }
+
+  function first(nowTime) {
+    initTime = nowTime;
+    window.requestAnimationFrame(resume);
+  }
+
+  function pause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.pause(animation);
+    }
+  }
+
+  function goToAndStop(value, isFrame, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
+    }
+  }
+
+  function stop(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.stop(animation);
+    }
+  }
+
+  function togglePause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.togglePause(animation);
+    }
+  }
+
+  function destroy(animation) {
+    var i;
+    for (i = (len - 1); i >= 0; i -= 1) {
+      registeredAnimations[i].animation.destroy(animation);
+    }
+  }
+
+  function searchAnimations(animationData, standalone, renderer) {
+    var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')),
+      [].slice.call(document.getElementsByClassName('bodymovin')));
+    var i;
+    var lenAnims = animElements.length;
+    for (i = 0; i < lenAnims; i += 1) {
+      if (renderer) {
+        animElements[i].setAttribute('data-bm-type', renderer);
+      }
+      registerAnimation(animElements[i], animationData);
+    }
+    if (standalone && lenAnims === 0) {
+      if (!renderer) {
+        renderer = 'svg';
+      }
+      var body = document.getElementsByTagName('body')[0];
+      body.innerText = '';
+      var div = createTag('div');
+      div.style.width = '100%';
+      div.style.height = '100%';
+      div.setAttribute('data-bm-type', renderer);
+      body.appendChild(div);
+      registerAnimation(div, animationData);
+    }
+  }
+
+  function resize() {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.resize();
+    }
+  }
+
+  function activate() {
+    if (!_isFrozen && playingAnimationsNum) {
+      if (_stopped) {
+        window.requestAnimationFrame(first);
+        _stopped = false;
+      }
+    }
+  }
+
+  function freeze() {
+    _isFrozen = true;
+  }
+
+  function unfreeze() {
+    _isFrozen = false;
+    activate();
+  }
+
+  function setVolume(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setVolume(val, animation);
+    }
+  }
+
+  function mute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.mute(animation);
+    }
+  }
+
+  function unmute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.unmute(animation);
+    }
+  }
+
+  moduleOb.registerAnimation = registerAnimation;
+  moduleOb.loadAnimation = loadAnimation;
+  moduleOb.setSpeed = setSpeed;
+  moduleOb.setDirection = setDirection;
+  moduleOb.play = play;
+  moduleOb.pause = pause;
+  moduleOb.stop = stop;
+  moduleOb.togglePause = togglePause;
+  moduleOb.searchAnimations = searchAnimations;
+  moduleOb.resize = resize;
+  // moduleOb.start = start;
+  moduleOb.goToAndStop = goToAndStop;
+  moduleOb.destroy = destroy;
+  moduleOb.freeze = freeze;
+  moduleOb.unfreeze = unfreeze;
+  moduleOb.setVolume = setVolume;
+  moduleOb.mute = mute;
+  moduleOb.unmute = unmute;
+  moduleOb.getRegisteredAnimations = getRegisteredAnimations;
+  return moduleOb;
+}());
+
+/* eslint-disable */
+const BezierFactory = (function () {
+  /**
+     * BezierEasing - use bezier curve for transition easing function
+     * by Gaëtan Renaudeau 2014 - 2015 – MIT License
+     *
+     * Credits: is based on Firefox's nsSMILKeySpline.cpp
+     * Usage:
+     * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
+     * spline.get(x) => returns the easing value | x must be in [0, 1] range
+     *
+     */
+
+  var ob = {};
+  ob.getBezierEasing = getBezierEasing;
+  var beziers = {};
+
+  function getBezierEasing(a, b, c, d, nm) {
+    var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
+    if (beziers[str]) {
+      return beziers[str];
+    }
+    var bezEasing = new BezierEasing([a, b, c, d]);
+    beziers[str] = bezEasing;
+    return bezEasing;
+  }
+
+  // These values are established by empiricism with tests (tradeoff: performance VS precision)
+  var NEWTON_ITERATIONS = 4;
+  var NEWTON_MIN_SLOPE = 0.001;
+  var SUBDIVISION_PRECISION = 0.0000001;
+  var SUBDIVISION_MAX_ITERATIONS = 10;
+
+  var kSplineTableSize = 11;
+  var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
+
+  var float32ArraySupported = typeof Float32Array === 'function';
+
+  function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
+  function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
+  function C(aA1) { return 3.0 * aA1; }
+
+  // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+  function calcBezier(aT, aA1, aA2) {
+    return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
+  }
+
+  // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+  function getSlope(aT, aA1, aA2) {
+    return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
+  }
+
+  function binarySubdivide(aX, aA, aB, mX1, mX2) {
+    var currentX,
+      currentT,
+      i = 0;
+    do {
+      currentT = aA + (aB - aA) / 2.0;
+      currentX = calcBezier(currentT, mX1, mX2) - aX;
+      if (currentX > 0.0) {
+        aB = currentT;
+      } else {
+        aA = currentT;
+      }
+    } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
+    return currentT;
+  }
+
+  function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
+    for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
+      var currentSlope = getSlope(aGuessT, mX1, mX2);
+      if (currentSlope === 0.0) return aGuessT;
+      var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
+      aGuessT -= currentX / currentSlope;
+    }
+    return aGuessT;
+  }
+
+  /**
+     * points is an array of [ mX1, mY1, mX2, mY2 ]
+     */
+  function BezierEasing(points) {
+    this._p = points;
+    this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
+    this._precomputed = false;
+
+    this.get = this.get.bind(this);
+  }
+
+  BezierEasing.prototype = {
+
+    get: function (x) {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      if (!this._precomputed) this._precompute();
+      if (mX1 === mY1 && mX2 === mY2) return x; // linear
+      // Because JavaScript number are imprecise, we should guarantee the extremes are right.
+      if (x === 0) return 0;
+      if (x === 1) return 1;
+      return calcBezier(this._getTForX(x), mY1, mY2);
+    },
+
+    // Private part
+
+    _precompute: function () {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      this._precomputed = true;
+      if (mX1 !== mY1 || mX2 !== mY2) { this._calcSampleValues(); }
+    },
+
+    _calcSampleValues: function () {
+      var mX1 = this._p[0],
+        mX2 = this._p[2];
+      for (var i = 0; i < kSplineTableSize; ++i) {
+        this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
+      }
+    },
+
+    /**
+         * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
+         */
+    _getTForX: function (aX) {
+      var mX1 = this._p[0],
+        mX2 = this._p[2],
+        mSampleValues = this._mSampleValues;
+
+      var intervalStart = 0.0;
+      var currentSample = 1;
+      var lastSample = kSplineTableSize - 1;
+
+      for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
+        intervalStart += kSampleStepSize;
+      }
+      --currentSample;
+
+      // Interpolate to provide an initial guess for t
+      var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
+      var guessForT = intervalStart + dist * kSampleStepSize;
+
+      var initialSlope = getSlope(guessForT, mX1, mX2);
+      if (initialSlope >= NEWTON_MIN_SLOPE) {
+        return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
+      } if (initialSlope === 0.0) {
+        return guessForT;
+      }
+      return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
+    },
+  };
+
+  return ob;
+}());
+
+const pooling = (function () {
+  function double(arr) {
+    return arr.concat(createSizedArray(arr.length));
+  }
+
+  return {
+    double: double,
+  };
+}());
+
+const poolFactory = (function () {
+  return function (initialLength, _create, _release) {
+    var _length = 0;
+    var _maxLength = initialLength;
+    var pool = createSizedArray(_maxLength);
+
+    var ob = {
+      newElement: newElement,
+      release: release,
+    };
+
+    function newElement() {
+      var element;
+      if (_length) {
+        _length -= 1;
+        element = pool[_length];
+      } else {
+        element = _create();
+      }
+      return element;
+    }
+
+    function release(element) {
+      if (_length === _maxLength) {
+        pool = pooling.double(pool);
+        _maxLength *= 2;
+      }
+      if (_release) {
+        _release(element);
+      }
+      pool[_length] = element;
+      _length += 1;
+    }
+
+    return ob;
+  };
+}());
+
+const bezierLengthPool = (function () {
+  function create() {
+    return {
+      addedLength: 0,
+      percents: createTypedArray('float32', getDefaultCurveSegments()),
+      lengths: createTypedArray('float32', getDefaultCurveSegments()),
+    };
+  }
+  return poolFactory(8, create);
+}());
+
+const segmentsLengthPool = (function () {
+  function create() {
+    return {
+      lengths: [],
+      totalLength: 0,
+    };
+  }
+
+  function release(element) {
+    var i;
+    var len = element.lengths.length;
+    for (i = 0; i < len; i += 1) {
+      bezierLengthPool.release(element.lengths[i]);
+    }
+    element.lengths.length = 0;
+  }
+
+  return poolFactory(8, create, release);
+}());
+
+function bezFunction() {
+  var math = Math;
+
+  function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
+    var det1 = (x1 * y2) + (y1 * x3) + (x2 * y3) - (x3 * y2) - (y3 * x1) - (x2 * y1);
+    return det1 > -0.001 && det1 < 0.001;
+  }
+
+  function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
+    if (z1 === 0 && z2 === 0 && z3 === 0) {
+      return pointOnLine2D(x1, y1, x2, y2, x3, y3);
+    }
+    var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
+    var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
+    var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
+    var diffDist;
+    if (dist1 > dist2) {
+      if (dist1 > dist3) {
+        diffDist = dist1 - dist2 - dist3;
+      } else {
+        diffDist = dist3 - dist2 - dist1;
+      }
+    } else if (dist3 > dist2) {
+      diffDist = dist3 - dist2 - dist1;
+    } else {
+      diffDist = dist2 - dist1 - dist3;
+    }
+    return diffDist > -0.0001 && diffDist < 0.0001;
+  }
+
+  var getBezierLength = (function () {
+    return function (pt1, pt2, pt3, pt4) {
+      var curveSegments = getDefaultCurveSegments();
+      var k;
+      var i;
+      var len;
+      var ptCoord;
+      var perc;
+      var addedLength = 0;
+      var ptDistance;
+      var point = [];
+      var lastPoint = [];
+      var lengthData = bezierLengthPool.newElement();
+      len = pt3.length;
+      for (k = 0; k < curveSegments; k += 1) {
+        perc = k / (curveSegments - 1);
+        ptDistance = 0;
+        for (i = 0; i < len; i += 1) {
+          ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
+          point[i] = ptCoord;
+          if (lastPoint[i] !== null) {
+            ptDistance += bmPow(point[i] - lastPoint[i], 2);
+          }
+          lastPoint[i] = point[i];
+        }
+        if (ptDistance) {
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+        }
+        lengthData.percents[k] = perc;
+        lengthData.lengths[k] = addedLength;
+      }
+      lengthData.addedLength = addedLength;
+      return lengthData;
+    };
+  }());
+
+  function getSegmentsLength(shapeData) {
+    var segmentsLength = segmentsLengthPool.newElement();
+    var closed = shapeData.c;
+    var pathV = shapeData.v;
+    var pathO = shapeData.o;
+    var pathI = shapeData.i;
+    var i;
+    var len = shapeData._length;
+    var lengths = segmentsLength.lengths;
+    var totalLength = 0;
+    for (i = 0; i < len - 1; i += 1) {
+      lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
+      totalLength += lengths[i].addedLength;
+    }
+    if (closed && len) {
+      lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
+      totalLength += lengths[i].addedLength;
+    }
+    segmentsLength.totalLength = totalLength;
+    return segmentsLength;
+  }
+
+  function BezierData(length) {
+    this.segmentLength = 0;
+    this.points = new Array(length);
+  }
+
+  function PointData(partial, point) {
+    this.partialLength = partial;
+    this.point = point;
+  }
+
+  var buildBezierData = (function () {
+    var storedData = {};
+
+    return function (pt1, pt2, pt3, pt4) {
+      var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
+      if (!storedData[bezierName]) {
+        var curveSegments = getDefaultCurveSegments();
+        var k;
+        var i;
+        var len;
+        var ptCoord;
+        var perc;
+        var addedLength = 0;
+        var ptDistance;
+        var point;
+        var lastPoint = null;
+        if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
+          curveSegments = 2;
+        }
+        var bezierData = new BezierData(curveSegments);
+        len = pt3.length;
+        for (k = 0; k < curveSegments; k += 1) {
+          point = createSizedArray(len);
+          perc = k / (curveSegments - 1);
+          ptDistance = 0;
+          for (i = 0; i < len; i += 1) {
+            ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
+            point[i] = ptCoord;
+            if (lastPoint !== null) {
+              ptDistance += bmPow(point[i] - lastPoint[i], 2);
+            }
+          }
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+          bezierData.points[k] = new PointData(ptDistance, point);
+          lastPoint = point;
+        }
+        bezierData.segmentLength = addedLength;
+        storedData[bezierName] = bezierData;
+      }
+      return storedData[bezierName];
+    };
+  }());
+
+  function getDistancePerc(perc, bezierData) {
+    var percents = bezierData.percents;
+    var lengths = bezierData.lengths;
+    var len = percents.length;
+    var initPos = bmFloor((len - 1) * perc);
+    var lengthPos = perc * bezierData.addedLength;
+    var lPerc = 0;
+    if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
+      return percents[initPos];
+    }
+    var dir = lengths[initPos] > lengthPos ? -1 : 1;
+    var flag = true;
+    while (flag) {
+      if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
+        lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
+        flag = false;
+      } else {
+        initPos += dir;
+      }
+      if (initPos < 0 || initPos >= len - 1) {
+        // FIX for TypedArrays that don't store floating point values with enough accuracy
+        if (initPos === len - 1) {
+          return percents[initPos];
+        }
+        flag = false;
+      }
+    }
+    return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
+  }
+
+  function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
+    var t1 = getDistancePerc(percent, bezierData);
+    var u1 = 1 - t1;
+    var ptX = math.round((u1 * u1 * u1 * pt1[0] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[0] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[0] + t1 * t1 * t1 * pt2[0]) * 1000) / 1000;
+    var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
+    return [ptX, ptY];
+  }
+
+  var bezierSegmentPoints = createTypedArray('float32', 8);
+
+  function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
+    if (startPerc < 0) {
+      startPerc = 0;
+    } else if (startPerc > 1) {
+      startPerc = 1;
+    }
+    var t0 = getDistancePerc(startPerc, bezierData);
+    endPerc = endPerc > 1 ? 1 : endPerc;
+    var t1 = getDistancePerc(endPerc, bezierData);
+    var i;
+    var len = pt1.length;
+    var u0 = 1 - t0;
+    var u1 = 1 - t1;
+    var u0u0u0 = u0 * u0 * u0;
+    var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0t0 = t0 * t0 * t0;
+    //
+    var u0u0u1 = u0 * u0 * u1;
+    var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0t1 = t0 * t0 * t1;
+    //
+    var u0u1u1 = u0 * u1 * u1;
+    var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1t1 = t0 * t1 * t1;
+    //
+    var u1u1u1 = u1 * u1 * u1;
+    var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1t1 = t1 * t1 * t1;
+    for (i = 0; i < len; i += 1) {
+      bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+    }
+
+    return bezierSegmentPoints;
+  }
+
+  return {
+    getSegmentsLength: getSegmentsLength,
+    getNewSegment: getNewSegment,
+    getPointInSegment: getPointInSegment,
+    buildBezierData: buildBezierData,
+    pointOnLine2D: pointOnLine2D,
+    pointOnLine3D: pointOnLine3D,
+  };
+}
+
+const bez = bezFunction();
+
+var initFrame = initialDefaultFrame;
+var mathAbs = Math.abs;
+
+function interpolateValue(frameNum, caching) {
+  var offsetTime = this.offsetTime;
+  var newValue;
+  if (this.propType === 'multidimensional') {
+    newValue = createTypedArray('float32', this.pv.length);
+  }
+  var iterationIndex = caching.lastIndex;
+  var i = iterationIndex;
+  var len = this.keyframes.length - 1;
+  var flag = true;
+  var keyData;
+  var nextKeyData;
+  var keyframeMetadata;
+
+  while (flag) {
+    keyData = this.keyframes[i];
+    nextKeyData = this.keyframes[i + 1];
+    if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
+      if (keyData.h) {
+        keyData = nextKeyData;
+      }
+      iterationIndex = 0;
+      break;
+    }
+    if ((nextKeyData.t - offsetTime) > frameNum) {
+      iterationIndex = i;
+      break;
+    }
+    if (i < len - 1) {
+      i += 1;
+    } else {
+      iterationIndex = 0;
+      flag = false;
+    }
+  }
+  keyframeMetadata = this.keyframesMetadata[i] || {};
+
+  var k;
+  var kLen;
+  var perc;
+  var jLen;
+  var j;
+  var fnc;
+  var nextKeyTime = nextKeyData.t - offsetTime;
+  var keyTime = keyData.t - offsetTime;
+  var endValue;
+  if (keyData.to) {
+    if (!keyframeMetadata.bezierData) {
+      keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
+    }
+    var bezierData = keyframeMetadata.bezierData;
+    if (frameNum >= nextKeyTime || frameNum < keyTime) {
+      var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
+      kLen = bezierData.points[ind].point.length;
+      for (k = 0; k < kLen; k += 1) {
+        newValue[k] = bezierData.points[ind].point[k];
+      }
+      // caching._lastKeyframeIndex = -1;
+    } else {
+      if (keyframeMetadata.__fnct) {
+        fnc = keyframeMetadata.__fnct;
+      } else {
+        fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
+        keyframeMetadata.__fnct = fnc;
+      }
+      perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+      var distanceInLine = bezierData.segmentLength * perc;
+
+      var segmentPerc;
+      var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0;
+      j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0;
+      flag = true;
+      jLen = bezierData.points.length;
+      while (flag) {
+        addedLength += bezierData.points[j].partialLength;
+        if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k];
+          }
+          break;
+        } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
+          segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
+          }
+          break;
+        }
+        if (j < jLen - 1) {
+          j += 1;
+        } else {
+          flag = false;
+        }
+      }
+      caching._lastPoint = j;
+      caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
+      caching._lastKeyframeIndex = i;
+    }
+  } else {
+    var outX;
+    var outY;
+    var inX;
+    var inY;
+    var keyValue;
+    len = keyData.s.length;
+    endValue = nextKeyData.s || keyData.e;
+    if (this.sh && keyData.h !== 1) {
+      if (frameNum >= nextKeyTime) {
+        newValue[0] = endValue[0];
+        newValue[1] = endValue[1];
+        newValue[2] = endValue[2];
+      } else if (frameNum <= keyTime) {
+        newValue[0] = keyData.s[0];
+        newValue[1] = keyData.s[1];
+        newValue[2] = keyData.s[2];
+      } else {
+        var quatStart = createQuaternion(keyData.s);
+        var quatEnd = createQuaternion(endValue);
+        var time = (frameNum - keyTime) / (nextKeyTime - keyTime);
+        quaternionToEuler(newValue, slerp(quatStart, quatEnd, time));
+      }
+    } else {
+      for (i = 0; i < len; i += 1) {
+        if (keyData.h !== 1) {
+          if (frameNum >= nextKeyTime) {
+            perc = 1;
+          } else if (frameNum < keyTime) {
+            perc = 0;
+          } else {
+            if (keyData.o.x.constructor === Array) {
+              if (!keyframeMetadata.__fnct) {
+                keyframeMetadata.__fnct = [];
+              }
+              if (!keyframeMetadata.__fnct[i]) {
+                outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
+                outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
+                inX = keyData.i.x[i] === undefined ? keyData.i.x[0] : keyData.i.x[i];
+                inY = keyData.i.y[i] === undefined ? keyData.i.y[0] : keyData.i.y[i];
+                fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+                keyframeMetadata.__fnct[i] = fnc;
+              } else {
+                fnc = keyframeMetadata.__fnct[i];
+              }
+            } else if (!keyframeMetadata.__fnct) {
+              outX = keyData.o.x;
+              outY = keyData.o.y;
+              inX = keyData.i.x;
+              inY = keyData.i.y;
+              fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+              keyData.keyframeMetadata = fnc;
+            } else {
+              fnc = keyframeMetadata.__fnct;
+            }
+            perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+          }
+        }
+
+        endValue = nextKeyData.s || keyData.e;
+        keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
+
+        if (this.propType === 'multidimensional') {
+          newValue[i] = keyValue;
+        } else {
+          newValue = keyValue;
+        }
+      }
+    }
+  }
+  caching.lastIndex = iterationIndex;
+  return newValue;
+}
+
+// based on @Toji's https://github.com/toji/gl-matrix/
+function slerp(a, b, t) {
+  var out = [];
+  var ax = a[0];
+  var ay = a[1];
+  var az = a[2];
+  var aw = a[3];
+  var bx = b[0];
+  var by = b[1];
+  var bz = b[2];
+  var bw = b[3];
+
+  var omega;
+  var cosom;
+  var sinom;
+  var scale0;
+  var scale1;
+
+  cosom = ax * bx + ay * by + az * bz + aw * bw;
+  if (cosom < 0.0) {
+    cosom = -cosom;
+    bx = -bx;
+    by = -by;
+    bz = -bz;
+    bw = -bw;
+  }
+  if ((1.0 - cosom) > 0.000001) {
+    omega = Math.acos(cosom);
+    sinom = Math.sin(omega);
+    scale0 = Math.sin((1.0 - t) * omega) / sinom;
+    scale1 = Math.sin(t * omega) / sinom;
+  } else {
+    scale0 = 1.0 - t;
+    scale1 = t;
+  }
+  out[0] = scale0 * ax + scale1 * bx;
+  out[1] = scale0 * ay + scale1 * by;
+  out[2] = scale0 * az + scale1 * bz;
+  out[3] = scale0 * aw + scale1 * bw;
+
+  return out;
+}
+
+function quaternionToEuler(out, quat) {
+  var qx = quat[0];
+  var qy = quat[1];
+  var qz = quat[2];
+  var qw = quat[3];
+  var heading = Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy * qy - 2 * qz * qz);
+  var attitude = Math.asin(2 * qx * qy + 2 * qz * qw);
+  var bank = Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx * qx - 2 * qz * qz);
+  out[0] = heading / degToRads;
+  out[1] = attitude / degToRads;
+  out[2] = bank / degToRads;
+}
+
+function createQuaternion(values) {
+  var heading = values[0] * degToRads;
+  var attitude = values[1] * degToRads;
+  var bank = values[2] * degToRads;
+  var c1 = Math.cos(heading / 2);
+  var c2 = Math.cos(attitude / 2);
+  var c3 = Math.cos(bank / 2);
+  var s1 = Math.sin(heading / 2);
+  var s2 = Math.sin(attitude / 2);
+  var s3 = Math.sin(bank / 2);
+  var w = c1 * c2 * c3 - s1 * s2 * s3;
+  var x = s1 * s2 * c3 + c1 * c2 * s3;
+  var y = s1 * c2 * c3 + c1 * s2 * s3;
+  var z = c1 * s2 * c3 - s1 * c2 * s3;
+
+  return [x, y, z, w];
+}
+
+function getValueAtCurrentTime() {
+  var frameNum = this.comp.renderedFrame - this.offsetTime;
+  var initTime = this.keyframes[0].t - this.offsetTime;
+  var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+  if (!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))) {
+    if (this._caching.lastFrame >= frameNum) {
+      this._caching._lastKeyframeIndex = -1;
+      this._caching.lastIndex = 0;
+    }
+
+    var renderResult = this.interpolateValue(frameNum, this._caching);
+    this.pv = renderResult;
+  }
+  this._caching.lastFrame = frameNum;
+  return this.pv;
+}
+
+function setVValue(val) {
+  var multipliedValue;
+  if (this.propType === 'unidimensional') {
+    multipliedValue = val * this.mult;
+    if (mathAbs(this.v - multipliedValue) > 0.00001) {
+      this.v = multipliedValue;
+      this._mdf = true;
+    }
+  } else {
+    var i = 0;
+    var len = this.v.length;
+    while (i < len) {
+      multipliedValue = val[i] * this.mult;
+      if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
+        this.v[i] = multipliedValue;
+        this._mdf = true;
+      }
+      i += 1;
+    }
+  }
+}
+
+function processEffectsSequence() {
+  if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
+    return;
+  }
+  if (this.lock) {
+    this.setVValue(this.pv);
+    return;
+  }
+  this.lock = true;
+  this._mdf = this._isFirstFrame;
+  var i;
+  var len = this.effectsSequence.length;
+  var finalValue = this.kf ? this.pv : this.data.k;
+  for (i = 0; i < len; i += 1) {
+    finalValue = this.effectsSequence[i](finalValue);
+  }
+  this.setVValue(finalValue);
+  this._isFirstFrame = false;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+}
+
+function addEffect(effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.container.addDynamicProperty(this);
+}
+
+function ValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this.v = mult ? data.k * mult : data.k;
+  this.pv = data.k;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.vel = 0;
+  this.effectsSequence = [];
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function MultiDimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.frameId = -1;
+  var i;
+  var len = data.k.length;
+  this.v = createTypedArray('float32', len);
+  this.pv = createTypedArray('float32', len);
+  this.vel = createTypedArray('float32', len);
+  for (i = 0; i < len; i += 1) {
+    this.v[i] = data.k[i] * this.mult;
+    this.pv[i] = data.k[i];
+  }
+  this._isFirstFrame = true;
+  this.effectsSequence = [];
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function KeyframedValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.frameId = -1;
+  this._caching = {
+    lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1,
+  };
+  this.k = true;
+  this.kf = true;
+  this.data = data;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.v = initFrame;
+  this.pv = initFrame;
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.addEffect = addEffect;
+}
+
+function KeyframedMultidimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  var i;
+  var len = data.k.length;
+  var s;
+  var e;
+  var to;
+  var ti;
+  for (i = 0; i < len - 1; i += 1) {
+    if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
+      s = data.k[i].s;
+      e = data.k[i + 1].s;
+      to = data.k[i].to;
+      ti = data.k[i].ti;
+      if ((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2]))) {
+        data.k[i].to = null;
+        data.k[i].ti = null;
+      }
+      if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
+        if (s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) {
+          data.k[i].to = null;
+          data.k[i].ti = null;
+        }
+      }
+    }
+  }
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.data = data;
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.k = true;
+  this.kf = true;
+  this._isFirstFrame = true;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.frameId = -1;
+  var arrLen = data.k[0].s.length;
+  this.v = createTypedArray('float32', arrLen);
+  this.pv = createTypedArray('float32', arrLen);
+  for (i = 0; i < arrLen; i += 1) {
+    this.v[i] = initFrame;
+    this.pv[i] = initFrame;
+  }
+  this._caching = { lastFrame: initFrame, lastIndex: 0, value: createTypedArray('float32', arrLen) };
+  this.addEffect = addEffect;
+}
+
+const PropertyFactory = (function () {
+  function getProp(elem, data, type, mult, container) {
+    if (data.sid) {
+      data = elem.globalData.slotManager.getProp(data);
+    }
+    var p;
+    if (!data.k.length) {
+      p = new ValueProperty(elem, data, mult, container);
+    } else if (typeof (data.k[0]) === 'number') {
+      p = new MultiDimensionalProperty(elem, data, mult, container);
+    } else {
+      switch (type) {
+        case 0:
+          p = new KeyframedValueProperty(elem, data, mult, container);
+          break;
+        case 1:
+          p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
+          break;
+        default:
+          break;
+      }
+    }
+    if (p.effectsSequence.length) {
+      container.addDynamicProperty(p);
+    }
+    return p;
+  }
+
+  var ob = {
+    getProp: getProp,
+  };
+  return ob;
+}());
+
+function DynamicPropertyContainer() {}
+DynamicPropertyContainer.prototype = {
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+      this.container.addDynamicProperty(this);
+      this._isAnimated = true;
+    }
+  },
+  iterateDynamicProperties: function () {
+    this._mdf = false;
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      this.dynamicProperties[i].getValue();
+      if (this.dynamicProperties[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  },
+  initDynamicPropertyContainer: function (container) {
+    this.container = container;
+    this.dynamicProperties = [];
+    this._mdf = false;
+    this._isAnimated = false;
+  },
+};
+
+const pointPool = (function () {
+  function create() {
+    return createTypedArray('float32', 2);
+  }
+  return poolFactory(8, create);
+}());
+
+function ShapePath() {
+  this.c = false;
+  this._length = 0;
+  this._maxLength = 8;
+  this.v = createSizedArray(this._maxLength);
+  this.o = createSizedArray(this._maxLength);
+  this.i = createSizedArray(this._maxLength);
+}
+
+ShapePath.prototype.setPathData = function (closed, len) {
+  this.c = closed;
+  this.setLength(len);
+  var i = 0;
+  while (i < len) {
+    this.v[i] = pointPool.newElement();
+    this.o[i] = pointPool.newElement();
+    this.i[i] = pointPool.newElement();
+    i += 1;
+  }
+};
+
+ShapePath.prototype.setLength = function (len) {
+  while (this._maxLength < len) {
+    this.doubleArrayLength();
+  }
+  this._length = len;
+};
+
+ShapePath.prototype.doubleArrayLength = function () {
+  this.v = this.v.concat(createSizedArray(this._maxLength));
+  this.i = this.i.concat(createSizedArray(this._maxLength));
+  this.o = this.o.concat(createSizedArray(this._maxLength));
+  this._maxLength *= 2;
+};
+
+ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
+  var arr;
+  this._length = Math.max(this._length, pos + 1);
+  if (this._length >= this._maxLength) {
+    this.doubleArrayLength();
+  }
+  switch (type) {
+    case 'v':
+      arr = this.v;
+      break;
+    case 'i':
+      arr = this.i;
+      break;
+    case 'o':
+      arr = this.o;
+      break;
+    default:
+      arr = [];
+      break;
+  }
+  if (!arr[pos] || (arr[pos] && !replace)) {
+    arr[pos] = pointPool.newElement();
+  }
+  arr[pos][0] = x;
+  arr[pos][1] = y;
+};
+
+ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
+  this.setXYAt(vX, vY, 'v', pos, replace);
+  this.setXYAt(oX, oY, 'o', pos, replace);
+  this.setXYAt(iX, iY, 'i', pos, replace);
+};
+
+ShapePath.prototype.reverse = function () {
+  var newPath = new ShapePath();
+  newPath.setPathData(this.c, this._length);
+  var vertices = this.v;
+  var outPoints = this.o;
+  var inPoints = this.i;
+  var init = 0;
+  if (this.c) {
+    newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
+    init = 1;
+  }
+  var cnt = this._length - 1;
+  var len = this._length;
+
+  var i;
+  for (i = init; i < len; i += 1) {
+    newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
+    cnt -= 1;
+  }
+  return newPath;
+};
+
+ShapePath.prototype.length = function () {
+  return this._length;
+};
+
+const shapePool = (function () {
+  function create() {
+    return new ShapePath();
+  }
+
+  function release(shapePath) {
+    var len = shapePath._length;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      pointPool.release(shapePath.v[i]);
+      pointPool.release(shapePath.i[i]);
+      pointPool.release(shapePath.o[i]);
+      shapePath.v[i] = null;
+      shapePath.i[i] = null;
+      shapePath.o[i] = null;
+    }
+    shapePath._length = 0;
+    shapePath.c = false;
+  }
+
+  function clone(shape) {
+    var cloned = factory.newElement();
+    var i;
+    var len = shape._length === undefined ? shape.v.length : shape._length;
+    cloned.setLength(len);
+    cloned.c = shape.c;
+
+    for (i = 0; i < len; i += 1) {
+      cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
+    }
+    return cloned;
+  }
+
+  var factory = poolFactory(4, create, release);
+  factory.clone = clone;
+
+  return factory;
+}());
+
+function ShapeCollection() {
+  this._length = 0;
+  this._maxLength = 4;
+  this.shapes = createSizedArray(this._maxLength);
+}
+
+ShapeCollection.prototype.addShape = function (shapeData) {
+  if (this._length === this._maxLength) {
+    this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
+    this._maxLength *= 2;
+  }
+  this.shapes[this._length] = shapeData;
+  this._length += 1;
+};
+
+ShapeCollection.prototype.releaseShapes = function () {
+  var i;
+  for (i = 0; i < this._length; i += 1) {
+    shapePool.release(this.shapes[i]);
+  }
+  this._length = 0;
+};
+
+const shapeCollectionPool = (function () {
+  var ob = {
+    newShapeCollection: newShapeCollection,
+    release: release,
+  };
+
+  var _length = 0;
+  var _maxLength = 4;
+  var pool = createSizedArray(_maxLength);
+
+  function newShapeCollection() {
+    var shapeCollection;
+    if (_length) {
+      _length -= 1;
+      shapeCollection = pool[_length];
+    } else {
+      shapeCollection = new ShapeCollection();
+    }
+    return shapeCollection;
+  }
+
+  function release(shapeCollection) {
+    var i;
+    var len = shapeCollection._length;
+    for (i = 0; i < len; i += 1) {
+      shapePool.release(shapeCollection.shapes[i]);
+    }
+    shapeCollection._length = 0;
+
+    if (_length === _maxLength) {
+      pool = pooling.double(pool);
+      _maxLength *= 2;
+    }
+    pool[_length] = shapeCollection;
+    _length += 1;
+  }
+
+  return ob;
+}());
+
+const ShapePropertyFactory = (function () {
+  var initFrame = -999999;
+
+  function interpolateShape(frameNum, previousValue, caching) {
+    var iterationIndex = caching.lastIndex;
+    var keyPropS;
+    var keyPropE;
+    var isHold;
+    var j;
+    var k;
+    var jLen;
+    var kLen;
+    var perc;
+    var vertexValue;
+    var kf = this.keyframes;
+    if (frameNum < kf[0].t - this.offsetTime) {
+      keyPropS = kf[0].s[0];
+      isHold = true;
+      iterationIndex = 0;
+    } else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) {
+      keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
+      /* if(kf[kf.length - 1].s){
+                keyPropS = kf[kf.length - 1].s[0];
+            }else{
+                keyPropS = kf[kf.length - 2].e[0];
+            } */
+      isHold = true;
+    } else {
+      var i = iterationIndex;
+      var len = kf.length - 1;
+      var flag = true;
+      var keyData;
+      var nextKeyData;
+      var keyframeMetadata;
+      while (flag) {
+        keyData = kf[i];
+        nextKeyData = kf[i + 1];
+        if ((nextKeyData.t - this.offsetTime) > frameNum) {
+          break;
+        }
+        if (i < len - 1) {
+          i += 1;
+        } else {
+          flag = false;
+        }
+      }
+      keyframeMetadata = this.keyframesMetadata[i] || {};
+      isHold = keyData.h === 1;
+      iterationIndex = i;
+      if (!isHold) {
+        if (frameNum >= nextKeyData.t - this.offsetTime) {
+          perc = 1;
+        } else if (frameNum < keyData.t - this.offsetTime) {
+          perc = 0;
+        } else {
+          var fnc;
+          if (keyframeMetadata.__fnct) {
+            fnc = keyframeMetadata.__fnct;
+          } else {
+            fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
+            keyframeMetadata.__fnct = fnc;
+          }
+          perc = fnc((frameNum - (keyData.t - this.offsetTime)) / ((nextKeyData.t - this.offsetTime) - (keyData.t - this.offsetTime)));
+        }
+        keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
+      }
+      keyPropS = keyData.s[0];
+    }
+    jLen = previousValue._length;
+    kLen = keyPropS.i[0].length;
+    caching.lastIndex = iterationIndex;
+
+    for (j = 0; j < jLen; j += 1) {
+      for (k = 0; k < kLen; k += 1) {
+        vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
+        previousValue.i[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc;
+        previousValue.o[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc;
+        previousValue.v[j][k] = vertexValue;
+      }
+    }
+  }
+
+  function interpolateShapeCurrentTime() {
+    var frameNum = this.comp.renderedFrame - this.offsetTime;
+    var initTime = this.keyframes[0].t - this.offsetTime;
+    var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+    var lastFrame = this._caching.lastFrame;
+    if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) {
+      /// /
+      this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
+      this.interpolateShape(frameNum, this.pv, this._caching);
+      /// /
+    }
+    this._caching.lastFrame = frameNum;
+    return this.pv;
+  }
+
+  function resetShape() {
+    this.paths = this.localShapeCollection;
+  }
+
+  function shapesEqual(shape1, shape2) {
+    if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
+      return false;
+    }
+    var i;
+    var len = shape1._length;
+    for (i = 0; i < len; i += 1) {
+      if (shape1.v[i][0] !== shape2.v[i][0]
+            || shape1.v[i][1] !== shape2.v[i][1]
+            || shape1.o[i][0] !== shape2.o[i][0]
+            || shape1.o[i][1] !== shape2.o[i][1]
+            || shape1.i[i][0] !== shape2.i[i][0]
+            || shape1.i[i][1] !== shape2.i[i][1]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  function setVValue(newPath) {
+    if (!shapesEqual(this.v, newPath)) {
+      this.v = shapePool.clone(newPath);
+      this.localShapeCollection.releaseShapes();
+      this.localShapeCollection.addShape(this.v);
+      this._mdf = true;
+      this.paths = this.localShapeCollection;
+    }
+  }
+
+  function processEffectsSequence() {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    } if (!this.effectsSequence.length) {
+      this._mdf = false;
+      return;
+    }
+    if (this.lock) {
+      this.setVValue(this.pv);
+      return;
+    }
+    this.lock = true;
+    this._mdf = false;
+    var finalValue;
+    if (this.kf) {
+      finalValue = this.pv;
+    } else if (this.data.ks) {
+      finalValue = this.data.ks.k;
+    } else {
+      finalValue = this.data.pt.k;
+    }
+    var i;
+    var len = this.effectsSequence.length;
+    for (i = 0; i < len; i += 1) {
+      finalValue = this.effectsSequence[i](finalValue);
+    }
+    this.setVValue(finalValue);
+    this.lock = false;
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function ShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.container = elem;
+    this.elem = elem;
+    this.data = data;
+    this.k = false;
+    this.kf = false;
+    this._mdf = false;
+    var pathData = type === 3 ? data.pt.k : data.ks.k;
+    this.v = shapePool.clone(pathData);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.reset = resetShape;
+    this.effectsSequence = [];
+  }
+
+  function addEffect(effectFunction) {
+    this.effectsSequence.push(effectFunction);
+    this.container.addDynamicProperty(this);
+  }
+
+  ShapeProperty.prototype.interpolateShape = interpolateShape;
+  ShapeProperty.prototype.getValue = processEffectsSequence;
+  ShapeProperty.prototype.setVValue = setVValue;
+  ShapeProperty.prototype.addEffect = addEffect;
+
+  function KeyframedShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.elem = elem;
+    this.container = elem;
+    this.offsetTime = elem.data.st;
+    this.keyframes = type === 3 ? data.pt.k : data.ks.k;
+    this.keyframesMetadata = [];
+    this.k = true;
+    this.kf = true;
+    var len = this.keyframes[0].s[0].i.length;
+    this.v = shapePool.newElement();
+    this.v.setPathData(this.keyframes[0].s[0].c, len);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.lastFrame = initFrame;
+    this.reset = resetShape;
+    this._caching = { lastFrame: initFrame, lastIndex: 0 };
+    this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
+  }
+  KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
+  KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
+  KeyframedShapeProperty.prototype.setVValue = setVValue;
+  KeyframedShapeProperty.prototype.addEffect = addEffect;
+
+  var EllShapeProperty = (function () {
+    var cPoint = roundCorner;
+
+    function EllShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 4);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.paths = this.localShapeCollection;
+      this.localShapeCollection.addShape(this.v);
+      this.d = data.d;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertEllToPath();
+      }
+    }
+
+    EllShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+
+        if (this._mdf) {
+          this.convertEllToPath();
+        }
+      },
+      convertEllToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var s0 = this.s.v[0] / 2;
+        var s1 = this.s.v[1] / 2;
+        var _cw = this.d !== 3;
+        var _v = this.v;
+        _v.v[0][0] = p0;
+        _v.v[0][1] = p1 - s1;
+        _v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.v[1][1] = p1;
+        _v.v[2][0] = p0;
+        _v.v[2][1] = p1 + s1;
+        _v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.v[3][1] = p1;
+        _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.i[0][1] = p1 - s1;
+        _v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.i[1][1] = p1 - s1 * cPoint;
+        _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.i[2][1] = p1 + s1;
+        _v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.i[3][1] = p1 + s1 * cPoint;
+        _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.o[0][1] = p1 - s1;
+        _v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.o[1][1] = p1 + s1 * cPoint;
+        _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.o[2][1] = p1 + s1;
+        _v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.o[3][1] = p1 - s1 * cPoint;
+      },
+    };
+
+    extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
+
+    return EllShapePropertyFactory;
+  }());
+
+  var StarShapeProperty = (function () {
+    function StarShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 0);
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.data = data;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      if (data.sy === 1) {
+        this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
+        this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
+        this.convertToPath = this.convertStarToPath;
+      } else {
+        this.convertToPath = this.convertPolygonToPath;
+      }
+      this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
+      this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this);
+      this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertToPath();
+      }
+    }
+
+    StarShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertToPath();
+        }
+      },
+      convertStarToPath: function () {
+        var numPts = Math.floor(this.pt.v) * 2;
+        var angle = (Math.PI * 2) / numPts;
+        /* this.v.v.length = numPts;
+                this.v.i.length = numPts;
+                this.v.o.length = numPts; */
+        var longFlag = true;
+        var longRad = this.or.v;
+        var shortRad = this.ir.v;
+        var longRound = this.os.v;
+        var shortRound = this.is.v;
+        var longPerimSegment = (2 * Math.PI * longRad) / (numPts * 2);
+        var shortPerimSegment = (2 * Math.PI * shortRad) / (numPts * 2);
+        var i;
+        var rad;
+        var roundness;
+        var perimSegment;
+        var currentAng = -Math.PI / 2;
+        currentAng += this.r.v;
+        var dir = this.data.d === 3 ? -1 : 1;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          rad = longFlag ? longRad : shortRad;
+          roundness = longFlag ? longRound : shortRound;
+          perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
+          /* this.v.v[i] = [x,y];
+                    this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
+                    this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
+                    this.v._length = numPts; */
+          longFlag = !longFlag;
+          currentAng += angle * dir;
+        }
+      },
+      convertPolygonToPath: function () {
+        var numPts = Math.floor(this.pt.v);
+        var angle = (Math.PI * 2) / numPts;
+        var rad = this.or.v;
+        var roundness = this.os.v;
+        var perimSegment = (2 * Math.PI * rad) / (numPts * 4);
+        var i;
+        var currentAng = -Math.PI * 0.5;
+        var dir = this.data.d === 3 ? -1 : 1;
+        currentAng += this.r.v;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+          currentAng += angle * dir;
+        }
+        this.paths.length = 0;
+        this.paths[0] = this.v;
+      },
+
+    };
+    extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
+
+    return StarShapePropertyFactory;
+  }());
+
+  var RectShapeProperty = (function () {
+    function RectShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.c = true;
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertRectToPath();
+      }
+    }
+
+    RectShapePropertyFactory.prototype = {
+      convertRectToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var v0 = this.s.v[0] / 2;
+        var v1 = this.s.v[1] / 2;
+        var round = bmMin(v0, v1, this.r.v);
+        var cPoint = round * (1 - roundCorner);
+        this.v._length = 0;
+
+        if (this.d === 2 || this.d === 1) {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
+          this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2);
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3);
+          }
+        } else {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true);
+          }
+        }
+      },
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertRectToPath();
+        }
+      },
+      reset: resetShape,
+    };
+    extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
+
+    return RectShapePropertyFactory;
+  }());
+
+  function getShapeProp(elem, data, type) {
+    var prop;
+    if (type === 3 || type === 4) {
+      var dataProp = type === 3 ? data.pt : data.ks;
+      var keys = dataProp.k;
+      if (keys.length) {
+        prop = new KeyframedShapeProperty(elem, data, type);
+      } else {
+        prop = new ShapeProperty(elem, data, type);
+      }
+    } else if (type === 5) {
+      prop = new RectShapeProperty(elem, data);
+    } else if (type === 6) {
+      prop = new EllShapeProperty(elem, data);
+    } else if (type === 7) {
+      prop = new StarShapeProperty(elem, data);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  }
+
+  function getConstructorFunction() {
+    return ShapeProperty;
+  }
+
+  function getKeyframedConstructorFunction() {
+    return KeyframedShapeProperty;
+  }
+
+  var ob = {};
+  ob.getShapeProp = getShapeProp;
+  ob.getConstructorFunction = getConstructorFunction;
+  ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction;
+  return ob;
+}());
+
+/*!
+ Transformation Matrix v2.0
+ (c) Epistemex 2014-2015
+ www.epistemex.com
+ By Ken Fyrstenberg
+ Contributions by leeoniya.
+ License: MIT, header required.
+ */
+
+/**
+ * 2D transformation matrix object initialized with identity matrix.
+ *
+ * The matrix can synchronize a canvas context by supplying the context
+ * as an argument, or later apply current absolute transform to an
+ * existing context.
+ *
+ * All values are handled as floating point values.
+ *
+ * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix
+ * @prop {number} a - scale x
+ * @prop {number} b - shear y
+ * @prop {number} c - shear x
+ * @prop {number} d - scale y
+ * @prop {number} e - translate x
+ * @prop {number} f - translate y
+ * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context
+ * @constructor
+ */
+
+const Matrix = (function () {
+  var _cos = Math.cos;
+  var _sin = Math.sin;
+  var _tan = Math.tan;
+  var _rnd = Math.round;
+
+  function reset() {
+    this.props[0] = 1;
+    this.props[1] = 0;
+    this.props[2] = 0;
+    this.props[3] = 0;
+    this.props[4] = 0;
+    this.props[5] = 1;
+    this.props[6] = 0;
+    this.props[7] = 0;
+    this.props[8] = 0;
+    this.props[9] = 0;
+    this.props[10] = 1;
+    this.props[11] = 0;
+    this.props[12] = 0;
+    this.props[13] = 0;
+    this.props[14] = 0;
+    this.props[15] = 1;
+    return this;
+  }
+
+  function rotate(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function rotateX(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateY(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateZ(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function shear(sx, sy) {
+    return this._t(1, sy, sx, 1, 0, 0);
+  }
+
+  function skew(ax, ay) {
+    return this.shear(_tan(ax), _tan(ay));
+  }
+
+  function skewFromAxis(ax, angle) {
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+    // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+  }
+
+  function scale(sx, sy, sz) {
+    if (!sz && sz !== 0) {
+      sz = 1;
+    }
+    if (sx === 1 && sy === 1 && sz === 1) {
+      return this;
+    }
+    return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
+  }
+
+  function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
+    this.props[0] = a;
+    this.props[1] = b;
+    this.props[2] = c;
+    this.props[3] = d;
+    this.props[4] = e;
+    this.props[5] = f;
+    this.props[6] = g;
+    this.props[7] = h;
+    this.props[8] = i;
+    this.props[9] = j;
+    this.props[10] = k;
+    this.props[11] = l;
+    this.props[12] = m;
+    this.props[13] = n;
+    this.props[14] = o;
+    this.props[15] = p;
+    return this;
+  }
+
+  function translate(tx, ty, tz) {
+    tz = tz || 0;
+    if (tx !== 0 || ty !== 0 || tz !== 0) {
+      return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
+    }
+    return this;
+  }
+
+  function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
+    var _p = this.props;
+
+    if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
+      // NOTE: commenting this condition because TurboFan deoptimizes code when present
+      // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
+      _p[12] = _p[12] * a2 + _p[15] * m2;
+      _p[13] = _p[13] * f2 + _p[15] * n2;
+      _p[14] = _p[14] * k2 + _p[15] * o2;
+      _p[15] *= p2;
+      // }
+      this._identityCalculated = false;
+      return this;
+    }
+
+    var a1 = _p[0];
+    var b1 = _p[1];
+    var c1 = _p[2];
+    var d1 = _p[3];
+    var e1 = _p[4];
+    var f1 = _p[5];
+    var g1 = _p[6];
+    var h1 = _p[7];
+    var i1 = _p[8];
+    var j1 = _p[9];
+    var k1 = _p[10];
+    var l1 = _p[11];
+    var m1 = _p[12];
+    var n1 = _p[13];
+    var o1 = _p[14];
+    var p1 = _p[15];
+
+    /* matrix order (canvas compatible):
+         * ace
+         * bdf
+         * 001
+         */
+    _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
+    _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
+    _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
+    _p[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2;
+
+    _p[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2;
+    _p[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2;
+    _p[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2;
+    _p[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2;
+
+    _p[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2;
+    _p[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2;
+    _p[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2;
+    _p[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2;
+
+    _p[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2;
+    _p[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2;
+    _p[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2;
+    _p[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2;
+
+    this._identityCalculated = false;
+    return this;
+  }
+
+  function multiply(matrix) {
+    var matrixProps = matrix.props;
+    return this.transform(
+      matrixProps[0],
+      matrixProps[1],
+      matrixProps[2],
+      matrixProps[3],
+      matrixProps[4],
+      matrixProps[5],
+      matrixProps[6],
+      matrixProps[7],
+      matrixProps[8],
+      matrixProps[9],
+      matrixProps[10],
+      matrixProps[11],
+      matrixProps[12],
+      matrixProps[13],
+      matrixProps[14],
+      matrixProps[15]
+    );
+  }
+
+  function isIdentity() {
+    if (!this._identityCalculated) {
+      this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
+      this._identityCalculated = true;
+    }
+    return this._identity;
+  }
+
+  function equals(matr) {
+    var i = 0;
+    while (i < 16) {
+      if (matr.props[i] !== this.props[i]) {
+        return false;
+      }
+      i += 1;
+    }
+    return true;
+  }
+
+  function clone(matr) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      matr.props[i] = this.props[i];
+    }
+    return matr;
+  }
+
+  function cloneFromProps(props) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      this.props[i] = props[i];
+    }
+  }
+
+  function applyToPoint(x, y, z) {
+    return {
+      x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+      y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+      z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+    };
+    /* return {
+         x: x * me.a + y * me.c + me.e,
+         y: x * me.b + y * me.d + me.f
+         }; */
+  }
+  function applyToX(x, y, z) {
+    return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
+  }
+  function applyToY(x, y, z) {
+    return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
+  }
+  function applyToZ(x, y, z) {
+    return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
+  }
+
+  function getInverseMatrix() {
+    var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
+    var a = this.props[5] / determinant;
+    var b = -this.props[1] / determinant;
+    var c = -this.props[4] / determinant;
+    var d = this.props[0] / determinant;
+    var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12]) / determinant;
+    var f = -(this.props[0] * this.props[13] - this.props[1] * this.props[12]) / determinant;
+    var inverseMatrix = new Matrix();
+    inverseMatrix.props[0] = a;
+    inverseMatrix.props[1] = b;
+    inverseMatrix.props[4] = c;
+    inverseMatrix.props[5] = d;
+    inverseMatrix.props[12] = e;
+    inverseMatrix.props[13] = f;
+    return inverseMatrix;
+  }
+
+  function inversePoint(pt) {
+    var inverseMatrix = this.getInverseMatrix();
+    return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
+  }
+
+  function inversePoints(pts) {
+    var i;
+    var len = pts.length;
+    var retPts = [];
+    for (i = 0; i < len; i += 1) {
+      retPts[i] = inversePoint(pts[i]);
+    }
+    return retPts;
+  }
+
+  function applyToTriplePoints(pt1, pt2, pt3) {
+    var arr = createTypedArray('float32', 6);
+    if (this.isIdentity()) {
+      arr[0] = pt1[0];
+      arr[1] = pt1[1];
+      arr[2] = pt2[0];
+      arr[3] = pt2[1];
+      arr[4] = pt3[0];
+      arr[5] = pt3[1];
+    } else {
+      var p0 = this.props[0];
+      var p1 = this.props[1];
+      var p4 = this.props[4];
+      var p5 = this.props[5];
+      var p12 = this.props[12];
+      var p13 = this.props[13];
+      arr[0] = pt1[0] * p0 + pt1[1] * p4 + p12;
+      arr[1] = pt1[0] * p1 + pt1[1] * p5 + p13;
+      arr[2] = pt2[0] * p0 + pt2[1] * p4 + p12;
+      arr[3] = pt2[0] * p1 + pt2[1] * p5 + p13;
+      arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
+      arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
+    }
+    return arr;
+  }
+
+  function applyToPointArray(x, y, z) {
+    var arr;
+    if (this.isIdentity()) {
+      arr = [x, y, z];
+    } else {
+      arr = [
+        x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+        x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+        x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+      ];
+    }
+    return arr;
+  }
+
+  function applyToPointStringified(x, y) {
+    if (this.isIdentity()) {
+      return x + ',' + y;
+    }
+    var _p = this.props;
+    return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
+  }
+
+  function toCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var i = 0;
+    var props = this.props;
+    var cssValue = 'matrix3d(';
+    var v = 10000;
+    while (i < 16) {
+      cssValue += _rnd(props[i] * v) / v;
+      cssValue += i === 15 ? ')' : ',';
+      i += 1;
+    }
+    return cssValue;
+  }
+
+  function roundMatrixProperty(val) {
+    var v = 10000;
+    if ((val < 0.000001 && val > 0) || (val > -0.000001 && val < 0)) {
+      return _rnd(val * v) / v;
+    }
+    return val;
+  }
+
+  function to2dCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var props = this.props;
+    var _a = roundMatrixProperty(props[0]);
+    var _b = roundMatrixProperty(props[1]);
+    var _c = roundMatrixProperty(props[4]);
+    var _d = roundMatrixProperty(props[5]);
+    var _e = roundMatrixProperty(props[12]);
+    var _f = roundMatrixProperty(props[13]);
+    return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
+  }
+
+  return function () {
+    this.reset = reset;
+    this.rotate = rotate;
+    this.rotateX = rotateX;
+    this.rotateY = rotateY;
+    this.rotateZ = rotateZ;
+    this.skew = skew;
+    this.skewFromAxis = skewFromAxis;
+    this.shear = shear;
+    this.scale = scale;
+    this.setTransform = setTransform;
+    this.translate = translate;
+    this.transform = transform;
+    this.multiply = multiply;
+    this.applyToPoint = applyToPoint;
+    this.applyToX = applyToX;
+    this.applyToY = applyToY;
+    this.applyToZ = applyToZ;
+    this.applyToPointArray = applyToPointArray;
+    this.applyToTriplePoints = applyToTriplePoints;
+    this.applyToPointStringified = applyToPointStringified;
+    this.toCSS = toCSS;
+    this.to2dCSS = to2dCSS;
+    this.clone = clone;
+    this.cloneFromProps = cloneFromProps;
+    this.equals = equals;
+    this.inversePoints = inversePoints;
+    this.inversePoint = inversePoint;
+    this.getInverseMatrix = getInverseMatrix;
+    this._t = this.transform;
+    this.isIdentity = isIdentity;
+    this._identity = true;
+    this._identityCalculated = false;
+
+    this.props = createTypedArray('float32', 16);
+    this.reset();
+  };
+}());
+
+const lottie = {};
+var standalone = '__[STANDALONE]__';
+var animationData = '__[ANIMATIONDATA]__';
+var renderer = '';
+
+function setLocation(href) {
+  setLocationHref(href);
+}
+
+function searchAnimations() {
+  if (standalone === true) {
+    animationManager.searchAnimations(animationData, standalone, renderer);
+  } else {
+    animationManager.searchAnimations();
+  }
+}
+
+function setSubframeRendering(flag) {
+  setSubframeEnabled(flag);
+}
+
+function setPrefix(prefix) {
+  setIdPrefix(prefix);
+}
+
+function loadAnimation(params) {
+  if (standalone === true) {
+    params.animationData = JSON.parse(animationData);
+  }
+  return animationManager.loadAnimation(params);
+}
+
+function setQuality(value) {
+  if (typeof value === 'string') {
+    switch (value) {
+      case 'high':
+        setDefaultCurveSegments(200);
+        break;
+      default:
+      case 'medium':
+        setDefaultCurveSegments(50);
+        break;
+      case 'low':
+        setDefaultCurveSegments(10);
+        break;
+    }
+  } else if (!isNaN(value) && value > 1) {
+    setDefaultCurveSegments(value);
+  }
+  if (getDefaultCurveSegments() >= 50) {
+    roundValues(false);
+  } else {
+    roundValues(true);
+  }
+}
+
+function inBrowser() {
+  return typeof navigator !== 'undefined';
+}
+
+function installPlugin(type, plugin) {
+  if (type === 'expressions') {
+    setExpressionsPlugin(plugin);
+  }
+}
+
+function getFactory(name) {
+  switch (name) {
+    case 'propertyFactory':
+      return PropertyFactory;
+    case 'shapePropertyFactory':
+      return ShapePropertyFactory;
+    case 'matrix':
+      return Matrix;
+    default:
+      return null;
+  }
+}
+
+lottie.play = animationManager.play;
+lottie.pause = animationManager.pause;
+lottie.setLocationHref = setLocation;
+lottie.togglePause = animationManager.togglePause;
+lottie.setSpeed = animationManager.setSpeed;
+lottie.setDirection = animationManager.setDirection;
+lottie.stop = animationManager.stop;
+lottie.searchAnimations = searchAnimations;
+lottie.registerAnimation = animationManager.registerAnimation;
+lottie.loadAnimation = loadAnimation;
+lottie.setSubframeRendering = setSubframeRendering;
+lottie.resize = animationManager.resize;
+// lottie.start = start;
+lottie.goToAndStop = animationManager.goToAndStop;
+lottie.destroy = animationManager.destroy;
+lottie.setQuality = setQuality;
+lottie.inBrowser = inBrowser;
+lottie.installPlugin = installPlugin;
+lottie.freeze = animationManager.freeze;
+lottie.unfreeze = animationManager.unfreeze;
+lottie.setVolume = animationManager.setVolume;
+lottie.mute = animationManager.mute;
+lottie.unmute = animationManager.unmute;
+lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations;
+lottie.useWebWorker = setWebWorker;
+lottie.setIDPrefix = setPrefix;
+lottie.__getFactory = getFactory;
+lottie.version = '[[BM_VERSION]]';
+
+function checkReady() {
+  if (document.readyState === 'complete') {
+    clearInterval(readyStateCheckInterval);
+    searchAnimations();
+  }
+}
+
+function getQueryVariable(variable) {
+  var vars = queryString.split('&');
+  for (var i = 0; i < vars.length; i += 1) {
+    var pair = vars[i].split('=');
+    if (decodeURIComponent(pair[0]) == variable) { // eslint-disable-line eqeqeq
+      return decodeURIComponent(pair[1]);
+    }
+  }
+  return null;
+}
+var queryString = '';
+if (standalone) {
+  var scripts = document.getElementsByTagName('script');
+  var index = scripts.length - 1;
+  var myScript = scripts[index] || {
+    src: '',
+  };
+  queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
+  renderer = getQueryVariable('renderer');
+}
+var readyStateCheckInterval = setInterval(checkReady, 100);
+
+// this adds bodymovin to the window object for backwards compatibility
+try {
+  if (!(typeof exports === 'object' && typeof module !== 'undefined')
+    && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
+  ) {
+    window.bodymovin = lottie;
+  }
+} catch (err) {
+  //
+}
+
+const ShapeModifiers = (function () {
+  var ob = {};
+  var modifiers = {};
+  ob.registerModifier = registerModifier;
+  ob.getModifier = getModifier;
+
+  function registerModifier(nm, factory) {
+    if (!modifiers[nm]) {
+      modifiers[nm] = factory;
+    }
+  }
+
+  function getModifier(nm, elem, data) {
+    return new modifiers[nm](elem, data);
+  }
+
+  return ob;
+}());
+
+function ShapeModifier() {}
+ShapeModifier.prototype.initModifierProperties = function () {};
+ShapeModifier.prototype.addShapeToModifier = function () {};
+ShapeModifier.prototype.addShape = function (data) {
+  if (!this.closed) {
+    // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
+    data.sh.container.addDynamicProperty(data.sh);
+    var shapeData = { shape: data.sh, data: data, localShapeCollection: shapeCollectionPool.newShapeCollection() };
+    this.shapes.push(shapeData);
+    this.addShapeToModifier(shapeData);
+    if (this._isAnimated) {
+      data.setAsAnimated();
+    }
+  }
+};
+ShapeModifier.prototype.init = function (elem, data) {
+  this.shapes = [];
+  this.elem = elem;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, data);
+  this.frameId = initialDefaultFrame;
+  this.closed = false;
+  this.k = false;
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+ShapeModifier.prototype.processKeys = function () {
+  if (this.elem.globalData.frameId === this.frameId) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+extendPrototype([DynamicPropertyContainer], ShapeModifier);
+
+function TrimModifier() {
+}
+extendPrototype([ShapeModifier], TrimModifier);
+TrimModifier.prototype.initModifierProperties = function (elem, data) {
+  this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this);
+  this.sValue = 0;
+  this.eValue = 0;
+  this.getValue = this.processKeys;
+  this.m = data.m;
+  this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
+};
+
+TrimModifier.prototype.addShapeToModifier = function (shapeData) {
+  shapeData.pathsData = [];
+};
+
+TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
+  var segments = [];
+  if (e <= 1) {
+    segments.push({
+      s: s,
+      e: e,
+    });
+  } else if (s >= 1) {
+    segments.push({
+      s: s - 1,
+      e: e - 1,
+    });
+  } else {
+    segments.push({
+      s: s,
+      e: 1,
+    });
+    segments.push({
+      s: 0,
+      e: e - 1,
+    });
+  }
+  var shapeSegments = [];
+  var i;
+  var len = segments.length;
+  var segmentOb;
+  for (i = 0; i < len; i += 1) {
+    segmentOb = segments[i];
+    if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
+      var shapeS;
+      var shapeE;
+      if (segmentOb.s * totalModifierLength <= addedLength) {
+        shapeS = 0;
+      } else {
+        shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
+      }
+      if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
+        shapeE = 1;
+      } else {
+        shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength);
+      }
+      shapeSegments.push([shapeS, shapeE]);
+    }
+  }
+  if (!shapeSegments.length) {
+    shapeSegments.push([0, 0]);
+  }
+  return shapeSegments;
+};
+
+TrimModifier.prototype.releasePathsData = function (pathsData) {
+  var i;
+  var len = pathsData.length;
+  for (i = 0; i < len; i += 1) {
+    segmentsLengthPool.release(pathsData[i]);
+  }
+  pathsData.length = 0;
+  return pathsData;
+};
+
+TrimModifier.prototype.processShapes = function (_isFirstFrame) {
+  var s;
+  var e;
+  if (this._mdf || _isFirstFrame) {
+    var o = (this.o.v % 360) / 360;
+    if (o < 0) {
+      o += 1;
+    }
+    if (this.s.v > 1) {
+      s = 1 + o;
+    } else if (this.s.v < 0) {
+      s = 0 + o;
+    } else {
+      s = this.s.v + o;
+    }
+    if (this.e.v > 1) {
+      e = 1 + o;
+    } else if (this.e.v < 0) {
+      e = 0 + o;
+    } else {
+      e = this.e.v + o;
+    }
+
+    if (s > e) {
+      var _s = s;
+      s = e;
+      e = _s;
+    }
+    s = Math.round(s * 10000) * 0.0001;
+    e = Math.round(e * 10000) * 0.0001;
+    this.sValue = s;
+    this.eValue = e;
+  } else {
+    s = this.sValue;
+    e = this.eValue;
+  }
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var pathsData;
+  var pathData;
+  var totalShapeLength;
+  var totalModifierLength = 0;
+
+  if (e === s) {
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].localShapeCollection.releaseShapes();
+      this.shapes[i].shape._mdf = true;
+      this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
+      if (this._mdf) {
+        this.shapes[i].pathsData.length = 0;
+      }
+    }
+  } else if (!((e === 1 && s === 0) || (e === 0 && s === 1))) {
+    var segments = [];
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
+      if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
+        shapeData.shape.paths = shapeData.localShapeCollection;
+      } else {
+        shapePaths = shapeData.shape.paths;
+        jLen = shapePaths._length;
+        totalShapeLength = 0;
+        if (!shapeData.shape._mdf && shapeData.pathsData.length) {
+          totalShapeLength = shapeData.totalShapeLength;
+        } else {
+          pathsData = this.releasePathsData(shapeData.pathsData);
+          for (j = 0; j < jLen; j += 1) {
+            pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
+            pathsData.push(pathData);
+            totalShapeLength += pathData.totalLength;
+          }
+          shapeData.totalShapeLength = totalShapeLength;
+          shapeData.pathsData = pathsData;
+        }
+
+        totalModifierLength += totalShapeLength;
+        shapeData.shape._mdf = true;
+      }
+    }
+    var shapeS = s;
+    var shapeE = e;
+    var addedLength = 0;
+    var edges;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shapeData = this.shapes[i];
+      if (shapeData.shape._mdf) {
+        localShapeCollection = shapeData.localShapeCollection;
+        localShapeCollection.releaseShapes();
+        // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
+        if (this.m === 2 && len > 1) {
+          edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
+          addedLength += shapeData.totalShapeLength;
+        } else {
+          edges = [[shapeS, shapeE]];
+        }
+        jLen = edges.length;
+        for (j = 0; j < jLen; j += 1) {
+          shapeS = edges[j][0];
+          shapeE = edges[j][1];
+          segments.length = 0;
+          if (shapeE <= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength * shapeE,
+            });
+          } else if (shapeS >= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * (shapeS - 1),
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          } else {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength,
+            });
+            segments.push({
+              s: 0,
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          }
+          var newShapesData = this.addShapes(shapeData, segments[0]);
+          if (segments[0].s !== segments[0].e) {
+            if (segments.length > 1) {
+              var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
+              if (lastShapeInCollection.c) {
+                var lastShape = newShapesData.pop();
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1], lastShape);
+              } else {
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1]);
+              }
+            }
+            this.addPaths(newShapesData, localShapeCollection);
+          }
+        }
+        shapeData.shape.paths = localShapeCollection;
+      }
+    }
+  } else if (this._mdf) {
+    for (i = 0; i < len; i += 1) {
+      // Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween.
+      // Don't remove this even if it's losing cached info.
+      this.shapes[i].pathsData.length = 0;
+      this.shapes[i].shape._mdf = true;
+    }
+  }
+};
+
+TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
+  var i;
+  var len = newPaths.length;
+  for (i = 0; i < len; i += 1) {
+    localShapeCollection.addShape(newPaths[i]);
+  }
+};
+
+TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
+  shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
+  shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
+  }
+  shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
+  shapePath.setXYAt(points[1], points[5], 'o', pos);
+  shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(points[0], points[4], 'v', pos);
+  }
+  shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
+  var pathsData = shapeData.pathsData;
+  var shapePaths = shapeData.shape.paths.shapes;
+  var i;
+  var len = shapeData.shape.paths._length;
+  var j;
+  var jLen;
+  var addedLength = 0;
+  var currentLengthData;
+  var segmentCount;
+  var lengths;
+  var segment;
+  var shapes = [];
+  var initPos;
+  var newShape = true;
+  if (!shapePath) {
+    shapePath = shapePool.newElement();
+    segmentCount = 0;
+    initPos = 0;
+  } else {
+    segmentCount = shapePath._length;
+    initPos = shapePath._length;
+  }
+  shapes.push(shapePath);
+  for (i = 0; i < len; i += 1) {
+    lengths = pathsData[i].lengths;
+    shapePath.c = shapePaths[i].c;
+    jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
+    for (j = 1; j < jLen; j += 1) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
+        addedLength += currentLengthData.addedLength;
+        shapePath.c = false;
+      } else if (addedLength > shapeSegment.e) {
+        shapePath.c = false;
+        break;
+      } else {
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+        addedLength += currentLengthData.addedLength;
+        segmentCount += 1;
+      }
+    }
+    if (shapePaths[i].c && lengths.length) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength <= shapeSegment.e) {
+        var segmentLength = lengths[j - 1].addedLength;
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+      } else {
+        shapePath.c = false;
+      }
+      addedLength += currentLengthData.addedLength;
+      segmentCount += 1;
+    }
+    if (shapePath._length) {
+      shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
+      shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
+    }
+    if (addedLength > shapeSegment.e) {
+      break;
+    }
+    if (i < len - 1) {
+      shapePath = shapePool.newElement();
+      newShape = true;
+      shapes.push(shapePath);
+      segmentCount = 0;
+    }
+  }
+  return shapes;
+};
+
+function PuckerAndBloatModifier() {}
+extendPrototype([ShapeModifier], PuckerAndBloatModifier);
+PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this._isAnimated = !!this.amount.effectsSequence.length;
+};
+
+PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
+  var percent = amount / 100;
+  var centerPoint = [0, 0];
+  var pathLength = path._length;
+  var i = 0;
+  for (i = 0; i < pathLength; i += 1) {
+    centerPoint[0] += path.v[i][0];
+    centerPoint[1] += path.v[i][1];
+  }
+  centerPoint[0] /= pathLength;
+  centerPoint[1] /= pathLength;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < pathLength; i += 1) {
+    vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
+    vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
+    oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent;
+    oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent;
+    iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent;
+    iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
+    clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
+  }
+  return clonedPath;
+};
+
+PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+const TransformPropertyFactory = (function () {
+  var defaultVector = [0, 0];
+
+  function applyToMatrix(mat) {
+    var _mdf = this._mdf;
+    this.iterateDynamicProperties();
+    this._mdf = this._mdf || _mdf;
+    if (this.a) {
+      mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+    }
+    if (this.s) {
+      mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+    }
+    if (this.sk) {
+      mat.skewFromAxis(-this.sk.v, this.sa.v);
+    }
+    if (this.r) {
+      mat.rotate(-this.r.v);
+    } else {
+      mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+    }
+    if (this.data.p.s) {
+      if (this.data.p.z) {
+        mat.translate(this.px.v, this.py.v, -this.pz.v);
+      } else {
+        mat.translate(this.px.v, this.py.v, 0);
+      }
+    } else {
+      mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+    }
+  }
+  function processKeys(forceRender) {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    }
+    if (this._isDirty) {
+      this.precalculateMatrix();
+      this._isDirty = false;
+    }
+
+    this.iterateDynamicProperties();
+
+    if (this._mdf || forceRender) {
+      var frameRate;
+      this.v.cloneFromProps(this.pre.props);
+      if (this.appliedTransformations < 1) {
+        this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      }
+      if (this.appliedTransformations < 2) {
+        this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      }
+      if (this.sk && this.appliedTransformations < 3) {
+        this.v.skewFromAxis(-this.sk.v, this.sa.v);
+      }
+      if (this.r && this.appliedTransformations < 4) {
+        this.v.rotate(-this.r.v);
+      } else if (!this.r && this.appliedTransformations < 4) {
+        this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+          .rotateY(this.or.v[1])
+          .rotateX(this.or.v[0]);
+      }
+      if (this.autoOriented) {
+        var v1;
+        var v2;
+        frameRate = this.elem.globalData.frameRate;
+        if (this.p && this.p.keyframes && this.p.getValueAtTime) {
+          if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
+            v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0);
+          } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0);
+            v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0);
+          } else {
+            v1 = this.p.pv;
+            v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime);
+          }
+        } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) {
+          v1 = [];
+          v2 = [];
+          var px = this.px;
+          var py = this.py;
+          if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
+            v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
+            v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate, 0);
+          } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate), 0);
+            v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate), 0);
+            v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0);
+          } else {
+            v1 = [px.pv, py.pv];
+            v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime);
+            v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime);
+          }
+        } else {
+          v2 = defaultVector;
+          v1 = v2;
+        }
+        this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
+      }
+      if (this.data.p && this.data.p.s) {
+        if (this.data.p.z) {
+          this.v.translate(this.px.v, this.py.v, -this.pz.v);
+        } else {
+          this.v.translate(this.px.v, this.py.v, 0);
+        }
+      } else {
+        this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+      }
+    }
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function precalculateMatrix() {
+    this.appliedTransformations = 0;
+    this.pre.reset();
+
+    if (!this.a.effectsSequence.length) {
+      this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      this.appliedTransformations = 1;
+    } else {
+      return;
+    }
+    if (!this.s.effectsSequence.length) {
+      this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      this.appliedTransformations = 2;
+    } else {
+      return;
+    }
+    if (this.sk) {
+      if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
+        this.pre.skewFromAxis(-this.sk.v, this.sa.v);
+        this.appliedTransformations = 3;
+      } else {
+        return;
+      }
+    }
+    if (this.r) {
+      if (!this.r.effectsSequence.length) {
+        this.pre.rotate(-this.r.v);
+        this.appliedTransformations = 4;
+      }
+    } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) {
+      this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+      this.appliedTransformations = 4;
+    }
+  }
+
+  function autoOrient() {
+    //
+    // var prevP = this.getValueAtTime();
+  }
+
+  function addDynamicProperty(prop) {
+    this._addDynamicProperty(prop);
+    this.elem.addDynamicProperty(prop);
+    this._isDirty = true;
+  }
+
+  function TransformProperty(elem, data, container) {
+    this.elem = elem;
+    this.frameId = -1;
+    this.propType = 'transform';
+    this.data = data;
+    this.v = new Matrix();
+    // Precalculated matrix with non animated properties
+    this.pre = new Matrix();
+    this.appliedTransformations = 0;
+    this.initDynamicPropertyContainer(container || elem);
+    if (data.p && data.p.s) {
+      this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
+      this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
+      if (data.p.z) {
+        this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
+      }
+    } else {
+      this.p = PropertyFactory.getProp(elem, data.p || { k: [0, 0, 0] }, 1, 0, this);
+    }
+    if (data.rx) {
+      this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
+      this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
+      this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
+      if (data.or.k[0].ti) {
+        var i;
+        var len = data.or.k.length;
+        for (i = 0; i < len; i += 1) {
+          data.or.k[i].to = null;
+          data.or.k[i].ti = null;
+        }
+      }
+      this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+      // sh Indicates it needs to be capped between -180 and 180
+      this.or.sh = true;
+    } else {
+      this.r = PropertyFactory.getProp(elem, data.r || { k: 0 }, 0, degToRads, this);
+    }
+    if (data.sk) {
+      this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
+      this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
+    }
+    this.a = PropertyFactory.getProp(elem, data.a || { k: [0, 0, 0] }, 1, 0, this);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: [100, 100, 100] }, 1, 0.01, this);
+    // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
+    if (data.o) {
+      this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
+    } else {
+      this.o = { _mdf: false, v: 1 };
+    }
+    this._isDirty = true;
+    if (!this.dynamicProperties.length) {
+      this.getValue(true);
+    }
+  }
+
+  TransformProperty.prototype = {
+    applyToMatrix: applyToMatrix,
+    getValue: processKeys,
+    precalculateMatrix: precalculateMatrix,
+    autoOrient: autoOrient,
+  };
+
+  extendPrototype([DynamicPropertyContainer], TransformProperty);
+  TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
+  TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
+
+  function getTransformProperty(elem, data, container) {
+    return new TransformProperty(elem, data, container);
+  }
+
+  return {
+    getTransformProperty: getTransformProperty,
+  };
+}());
+
+function RepeaterModifier() {}
+extendPrototype([ShapeModifier], RepeaterModifier);
+
+RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, null, this);
+  this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this);
+  this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
+  this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
+  this.data = data;
+  if (!this.dynamicProperties.length) {
+    this.getValue(true);
+  }
+  this._isAnimated = !!this.dynamicProperties.length;
+  this.pMatrix = new Matrix();
+  this.rMatrix = new Matrix();
+  this.sMatrix = new Matrix();
+  this.tMatrix = new Matrix();
+  this.matrix = new Matrix();
+};
+
+RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
+  var dir = inv ? -1 : 1;
+  var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
+  var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
+  pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
+  rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  rMatrix.rotate(-transform.r.v * dir * perc);
+  rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+  sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
+  sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+};
+
+RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
+  this.elem = elem;
+  this.arr = arr;
+  this.pos = pos;
+  this.elemsData = elemsData;
+  this._currentCopies = 0;
+  this._elements = [];
+  this._groups = [];
+  this.frameId = -1;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, arr[pos]);
+  while (pos > 0) {
+    pos -= 1;
+    // this._elements.unshift(arr.splice(pos,1)[0]);
+    this._elements.unshift(arr[pos]);
+  }
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+
+RepeaterModifier.prototype.resetElements = function (elements) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._processed = false;
+    if (elements[i].ty === 'gr') {
+      this.resetElements(elements[i].it);
+    }
+  }
+};
+
+RepeaterModifier.prototype.cloneElements = function (elements) {
+  var newElements = JSON.parse(JSON.stringify(elements));
+  this.resetElements(newElements);
+  return newElements;
+};
+
+RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._render = renderFlag;
+    if (elements[i].ty === 'gr') {
+      this.changeGroupRender(elements[i].it, renderFlag);
+    }
+  }
+};
+
+RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
+  var items;
+  var itemsTransform;
+  var i;
+  var dir;
+  var cont;
+  var hasReloaded = false;
+  if (this._mdf || _isFirstFrame) {
+    var copies = Math.ceil(this.c.v);
+    if (this._groups.length < copies) {
+      while (this._groups.length < copies) {
+        var group = {
+          it: this.cloneElements(this._elements),
+          ty: 'gr',
+        };
+        group.it.push({
+          a: { a: 0, ix: 1, k: [0, 0] }, nm: 'Transform', o: { a: 0, ix: 7, k: 100 }, p: { a: 0, ix: 2, k: [0, 0] }, r: { a: 1, ix: 6, k: [{ s: 0, e: 0, t: 0 }, { s: 0, e: 0, t: 1 }] }, s: { a: 0, ix: 3, k: [100, 100] }, sa: { a: 0, ix: 5, k: 0 }, sk: { a: 0, ix: 4, k: 0 }, ty: 'tr',
+        });
+
+        this.arr.splice(0, 0, group);
+        this._groups.splice(0, 0, group);
+        this._currentCopies += 1;
+      }
+      this.elem.reloadShapes();
+      hasReloaded = true;
+    }
+    cont = 0;
+    var renderFlag;
+    for (i = 0; i <= this._groups.length - 1; i += 1) {
+      renderFlag = cont < copies;
+      this._groups[i]._render = renderFlag;
+      this.changeGroupRender(this._groups[i].it, renderFlag);
+      if (!renderFlag) {
+        var elems = this.elemsData[i].it;
+        var transformData = elems[elems.length - 1];
+        if (transformData.transform.op.v !== 0) {
+          transformData.transform.op._mdf = true;
+          transformData.transform.op.v = 0;
+        } else {
+          transformData.transform.op._mdf = false;
+        }
+      }
+      cont += 1;
+    }
+
+    this._currentCopies = copies;
+    /// /
+
+    var offset = this.o.v;
+    var offsetModulo = offset % 1;
+    var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
+    var pProps = this.pMatrix.props;
+    var rProps = this.rMatrix.props;
+    var sProps = this.sMatrix.props;
+    this.pMatrix.reset();
+    this.rMatrix.reset();
+    this.sMatrix.reset();
+    this.tMatrix.reset();
+    this.matrix.reset();
+    var iteration = 0;
+
+    if (offset > 0) {
+      while (iteration < roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        iteration += 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
+        iteration += offsetModulo;
+      }
+    } else if (offset < 0) {
+      while (iteration > roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
+        iteration -= 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
+        iteration -= offsetModulo;
+      }
+    }
+    i = this.data.m === 1 ? 0 : this._currentCopies - 1;
+    dir = this.data.m === 1 ? 1 : -1;
+    cont = this._currentCopies;
+    var j;
+    var jLen;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      jLen = itemsTransform.length;
+      items[items.length - 1].transform.mProps._mdf = true;
+      items[items.length - 1].transform.op._mdf = true;
+      items[items.length - 1].transform.op.v = this._currentCopies === 1
+        ? this.so.v
+        : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
+
+      if (iteration !== 0) {
+        if ((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)) {
+          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        }
+        this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
+        this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
+        this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
+
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+        this.matrix.reset();
+      } else {
+        this.matrix.reset();
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+      }
+      iteration += 1;
+      cont -= 1;
+      i += dir;
+    }
+  } else {
+    cont = this._currentCopies;
+    i = 0;
+    dir = 1;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      items[items.length - 1].transform.mProps._mdf = false;
+      items[items.length - 1].transform.op._mdf = false;
+      cont -= 1;
+      i += dir;
+    }
+  }
+  return hasReloaded;
+};
+
+RepeaterModifier.prototype.addShape = function () {};
+
+function RoundCornersModifier() {}
+extendPrototype([ShapeModifier], RoundCornersModifier);
+RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this._isAnimated = !!this.rd.effectsSequence.length;
+};
+
+RoundCornersModifier.prototype.processPath = function (path, round) {
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var i;
+  var len = path._length;
+  var currentV;
+  var currentI;
+  var currentO;
+  var closerV;
+  var distance;
+  var newPosPerc;
+  var index = 0;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < len; i += 1) {
+    currentV = path.v[i];
+    currentO = path.o[i];
+    currentI = path.i[i];
+    if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
+      if ((i === 0 || i === len - 1) && !path.c) {
+        clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
+        /* clonedPath.v[index] = currentV;
+                clonedPath.o[index] = currentO;
+                clonedPath.i[index] = currentI; */
+        index += 1;
+      } else {
+        if (i === 0) {
+          closerV = path.v[len - 1];
+        } else {
+          closerV = path.v[i - 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = iX;
+        iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
+        vY = iY;
+        oX = vX - (vX - currentV[0]) * roundCorner;
+        oY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+
+        if (i === len - 1) {
+          closerV = path.v[0];
+        } else {
+          closerV = path.v[i + 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = oX;
+        oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc;
+        vY = oY;
+        iX = vX - (vX - currentV[0]) * roundCorner;
+        iY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+      }
+    } else {
+      clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index);
+      index += 1;
+    }
+  }
+  return clonedPath;
+};
+
+RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var rd = this.rd.v;
+
+  if (rd !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function floatEqual(a, b) {
+  return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
+}
+
+function floatZero(f) {
+  return Math.abs(f) <= 0.00001;
+}
+
+function lerp(p0, p1, amount) {
+  return p0 * (1 - amount) + p1 * amount;
+}
+
+function lerpPoint(p0, p1, amount) {
+  return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
+}
+
+function quadRoots(a, b, c) {
+  // no root
+  if (a === 0) return [];
+  var s = b * b - 4 * a * c;
+  // Complex roots
+  if (s < 0) return [];
+  var singleRoot = -b / (2 * a);
+  // 1 root
+  if (s === 0) return [singleRoot];
+  var delta = Math.sqrt(s) / (2 * a);
+  // 2 roots
+  return [singleRoot - delta, singleRoot + delta];
+}
+
+function polynomialCoefficients(p0, p1, p2, p3) {
+  return [
+    -p0 + 3 * p1 - 3 * p2 + p3,
+    3 * p0 - 6 * p1 + 3 * p2,
+    -3 * p0 + 3 * p1,
+    p0,
+  ];
+}
+
+function singlePoint(p) {
+  return new PolynomialBezier(p, p, p, p, false);
+}
+
+function PolynomialBezier(p0, p1, p2, p3, linearize) {
+  if (linearize && pointEqual(p0, p1)) {
+    p1 = lerpPoint(p0, p3, 1 / 3);
+  }
+  if (linearize && pointEqual(p2, p3)) {
+    p2 = lerpPoint(p0, p3, 2 / 3);
+  }
+  var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
+  var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
+  this.a = [coeffx[0], coeffy[0]];
+  this.b = [coeffx[1], coeffy[1]];
+  this.c = [coeffx[2], coeffy[2]];
+  this.d = [coeffx[3], coeffy[3]];
+  this.points = [p0, p1, p2, p3];
+}
+PolynomialBezier.prototype.point = function (t) {
+  return [
+    (((this.a[0] * t) + this.b[0]) * t + this.c[0]) * t + this.d[0],
+    (((this.a[1] * t) + this.b[1]) * t + this.c[1]) * t + this.d[1],
+  ];
+};
+PolynomialBezier.prototype.derivative = function (t) {
+  return [
+    (3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0],
+    (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1],
+  ];
+};
+PolynomialBezier.prototype.tangentAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[1], p[0]);
+};
+PolynomialBezier.prototype.normalAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[0], p[1]);
+};
+
+PolynomialBezier.prototype.inflectionPoints = function () {
+  var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
+  if (floatZero(denom)) return [];
+  var tcusp = (-0.5 * (this.a[1] * this.c[0] - this.a[0] * this.c[1])) / denom;
+  var square = tcusp * tcusp - ((1 / 3) * (this.b[1] * this.c[0] - this.b[0] * this.c[1])) / denom;
+  if (square < 0) return [];
+  var root = Math.sqrt(square);
+  if (floatZero(root)) {
+    if (root > 0 && root < 1) return [tcusp];
+    return [];
+  }
+  return [tcusp - root, tcusp + root].filter(function (r) { return r > 0 && r < 1; });
+};
+PolynomialBezier.prototype.split = function (t) {
+  if (t <= 0) return [singlePoint(this.points[0]), this];
+  if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
+  var p10 = lerpPoint(this.points[0], this.points[1], t);
+  var p11 = lerpPoint(this.points[1], this.points[2], t);
+  var p12 = lerpPoint(this.points[2], this.points[3], t);
+  var p20 = lerpPoint(p10, p11, t);
+  var p21 = lerpPoint(p11, p12, t);
+  var p3 = lerpPoint(p20, p21, t);
+  return [
+    new PolynomialBezier(this.points[0], p10, p20, p3, true),
+    new PolynomialBezier(p3, p21, p12, this.points[3], true),
+  ];
+};
+function extrema(bez, comp) {
+  var min = bez.points[0][comp];
+  var max = bez.points[bez.points.length - 1][comp];
+  if (min > max) {
+    var e = max;
+    max = min;
+    min = e;
+  }
+  // Derivative roots to find min/max
+  var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
+  for (var i = 0; i < f.length; i += 1) {
+    if (f[i] > 0 && f[i] < 1) {
+      var val = bez.point(f[i])[comp];
+      if (val < min) min = val;
+      else if (val > max) max = val;
+    }
+  }
+  return {
+    min: min,
+    max: max,
+  };
+}
+PolynomialBezier.prototype.bounds = function () {
+  return {
+    x: extrema(this, 0),
+    y: extrema(this, 1),
+  };
+};
+PolynomialBezier.prototype.boundingBox = function () {
+  var bounds = this.bounds();
+  return {
+    left: bounds.x.min,
+    right: bounds.x.max,
+    top: bounds.y.min,
+    bottom: bounds.y.max,
+    width: bounds.x.max - bounds.x.min,
+    height: bounds.y.max - bounds.y.min,
+    cx: (bounds.x.max + bounds.x.min) / 2,
+    cy: (bounds.y.max + bounds.y.min) / 2,
+  };
+};
+
+function intersectData(bez, t1, t2) {
+  var box = bez.boundingBox();
+  return {
+    cx: box.cx,
+    cy: box.cy,
+    width: box.width,
+    height: box.height,
+    bez: bez,
+    t: (t1 + t2) / 2,
+    t1: t1,
+    t2: t2,
+  };
+}
+function splitData(data) {
+  var split = data.bez.split(0.5);
+  return [
+    intersectData(split[0], data.t1, data.t),
+    intersectData(split[1], data.t, data.t2),
+  ];
+}
+
+function boxIntersect(b1, b2) {
+  return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width
+    && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
+}
+
+function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
+  if (!boxIntersect(d1, d2)) return;
+  if (depth >= maxRecursion || (d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance)) {
+    intersections.push([d1.t, d2.t]);
+    return;
+  }
+  var d1s = splitData(d1);
+  var d2s = splitData(d2);
+  intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[0], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+}
+
+PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
+  if (tolerance === undefined) tolerance = 2;
+  if (maxRecursion === undefined) maxRecursion = 7;
+  var intersections = [];
+  intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
+  return intersections;
+};
+
+PolynomialBezier.shapeSegment = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
+};
+
+PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
+};
+
+function crossProduct(a, b) {
+  return [
+    a[1] * b[2] - a[2] * b[1],
+    a[2] * b[0] - a[0] * b[2],
+    a[0] * b[1] - a[1] * b[0],
+  ];
+}
+
+function lineIntersection(start1, end1, start2, end2) {
+  var v1 = [start1[0], start1[1], 1];
+  var v2 = [end1[0], end1[1], 1];
+  var v3 = [start2[0], start2[1], 1];
+  var v4 = [end2[0], end2[1], 1];
+
+  var r = crossProduct(
+    crossProduct(v1, v2),
+    crossProduct(v3, v4)
+  );
+
+  if (floatZero(r[2])) return null;
+
+  return [r[0] / r[2], r[1] / r[2]];
+}
+
+function polarOffset(p, angle, length) {
+  return [
+    p[0] + Math.cos(angle) * length,
+    p[1] - Math.sin(angle) * length,
+  ];
+}
+
+function pointDistance(p1, p2) {
+  return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
+}
+
+function pointEqual(p1, p2) {
+  return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
+}
+
+function ZigZagModifier() {}
+extendPrototype([ShapeModifier], ZigZagModifier);
+ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
+  this.frequency = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
+  this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
+};
+
+function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
+  var angO = angle - Math.PI / 2;
+  var angI = angle + Math.PI / 2;
+  var px = point[0] + Math.cos(angle) * direction * amplitude;
+  var py = point[1] - Math.sin(angle) * direction * amplitude;
+
+  outputBezier.setTripleAt(
+    px,
+    py,
+    px + Math.cos(angO) * outAmplitude,
+    py - Math.sin(angO) * outAmplitude,
+    px + Math.cos(angI) * inAmplitude,
+    py - Math.sin(angI) * inAmplitude,
+    outputBezier.length()
+  );
+}
+
+function getPerpendicularVector(pt1, pt2) {
+  var vector = [
+    pt2[0] - pt1[0],
+    pt2[1] - pt1[1],
+  ];
+  var rot = -Math.PI * 0.5;
+  var rotatedVector = [
+    Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1],
+    Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1],
+  ];
+  return rotatedVector;
+}
+
+function getProjectingAngle(path, cur) {
+  var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
+  var nextIndex = (cur + 1) % path.length();
+  var prevPoint = path.v[prevIndex];
+  var nextPoint = path.v[nextIndex];
+  var pVector = getPerpendicularVector(prevPoint, nextPoint);
+  return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
+}
+
+function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
+  var angle = getProjectingAngle(path, cur);
+  var point = path.v[cur % path._length];
+  var prevPoint = path.v[cur === 0 ? path._length - 1 : cur - 1];
+  var nextPoint = path.v[(cur + 1) % path._length];
+  var prevDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - prevPoint[0], 2) + Math.pow(point[1] - prevPoint[1], 2))
+    : 0;
+  var nextDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2))
+    : 0;
+
+  setPoint(
+    outputBezier,
+    path.v[cur % path._length],
+    angle,
+    direction,
+    amplitude,
+    nextDist / ((frequency + 1) * 2),
+    prevDist / ((frequency + 1) * 2),
+    pointType
+  );
+}
+
+function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
+  for (var i = 0; i < frequency; i += 1) {
+    var t = (i + 1) / (frequency + 1);
+
+    var dist = pointType === 2
+      ? Math.sqrt(Math.pow(segment.points[3][0] - segment.points[0][0], 2) + Math.pow(segment.points[3][1] - segment.points[0][1], 2))
+      : 0;
+
+    var angle = segment.normalAngle(t);
+    var point = segment.point(t);
+    setPoint(
+      outputBezier,
+      point,
+      angle,
+      direction,
+      amplitude,
+      dist / ((frequency + 1) * 2),
+      dist / ((frequency + 1) * 2),
+      pointType
+    );
+
+    direction = -direction;
+  }
+
+  return direction;
+}
+
+ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
+  var count = path._length;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+
+  if (!path.c) {
+    count -= 1;
+  }
+
+  if (count === 0) return clonedPath;
+
+  var direction = -1;
+  var segment = PolynomialBezier.shapeSegment(path, 0);
+  zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
+
+  for (var i = 0; i < count; i += 1) {
+    direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
+
+    if (i === count - 1 && !path.c) {
+      segment = null;
+    } else {
+      segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
+    }
+
+    zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
+  }
+
+  return clonedPath;
+};
+
+ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amplitude = this.amplitude.v;
+  var frequency = Math.max(0, Math.round(this.frequency.v));
+  var pointType = this.pointsType.v;
+
+  if (amplitude !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function linearOffset(p1, p2, amount) {
+  var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
+  return [
+    polarOffset(p1, angle, amount),
+    polarOffset(p2, angle, amount),
+  ];
+}
+
+function offsetSegment(segment, amount) {
+  var p0; var p1a; var p1b; var p2b; var p2a; var
+    p3;
+  var e;
+  e = linearOffset(segment.points[0], segment.points[1], amount);
+  p0 = e[0];
+  p1a = e[1];
+  e = linearOffset(segment.points[1], segment.points[2], amount);
+  p1b = e[0];
+  p2b = e[1];
+  e = linearOffset(segment.points[2], segment.points[3], amount);
+  p2a = e[0];
+  p3 = e[1];
+  var p1 = lineIntersection(p0, p1a, p1b, p2b);
+  if (p1 === null) p1 = p1a;
+  var p2 = lineIntersection(p2a, p3, p1b, p2b);
+  if (p2 === null) p2 = p2a;
+
+  return new PolynomialBezier(p0, p1, p2, p3);
+}
+
+function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
+  var p0 = seg1.points[3];
+  var p1 = seg2.points[0];
+
+  // Bevel
+  if (lineJoin === 3) return p0;
+
+  // Connected, they don't need a joint
+  if (pointEqual(p0, p1)) return p0;
+
+  // Round
+  if (lineJoin === 2) {
+    var angleOut = -seg1.tangentAngle(1);
+    var angleIn = -seg2.tangentAngle(0) + Math.PI;
+    var center = lineIntersection(
+      p0,
+      polarOffset(p0, angleOut + Math.PI / 2, 100),
+      p1,
+      polarOffset(p1, angleOut + Math.PI / 2, 100)
+    );
+    var radius = center ? pointDistance(center, p0) : pointDistance(p0, p1) / 2;
+
+    var tan = polarOffset(p0, angleOut, 2 * radius * roundCorner);
+    outputBezier.setXYAt(tan[0], tan[1], 'o', outputBezier.length() - 1);
+
+    tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
+    outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
+
+    return p1;
+  }
+
+  // Miter
+  var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
+  var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
+  var intersection = lineIntersection(t0, p0, p1, t1);
+  if (intersection && pointDistance(intersection, p0) < miterLimit) {
+    outputBezier.setTripleAt(
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      outputBezier.length()
+    );
+    return intersection;
+  }
+
+  return p0;
+}
+
+function getIntersection(a, b) {
+  const intersect = a.intersections(b);
+
+  if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
+
+  if (intersect.length) return intersect[0];
+
+  return null;
+}
+
+function pruneSegmentIntersection(a, b) {
+  var outa = a.slice();
+  var outb = b.slice();
+  var intersect = getIntersection(a[a.length - 1], b[0]);
+  if (intersect) {
+    outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
+    outb[0] = b[0].split(intersect[1])[1];
+  }
+  if (a.length > 1 && b.length > 1) {
+    intersect = getIntersection(a[0], b[b.length - 1]);
+    if (intersect) {
+      return [
+        [a[0].split(intersect[0])[0]],
+        [b[b.length - 1].split(intersect[1])[1]],
+      ];
+    }
+  }
+  return [outa, outb];
+}
+
+function pruneIntersections(segments) {
+  var e;
+  for (var i = 1; i < segments.length; i += 1) {
+    e = pruneSegmentIntersection(segments[i - 1], segments[i]);
+    segments[i - 1] = e[0];
+    segments[i] = e[1];
+  }
+
+  if (segments.length > 1) {
+    e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
+    segments[segments.length - 1] = e[0];
+    segments[0] = e[1];
+  }
+
+  return segments;
+}
+
+function offsetSegmentSplit(segment, amount) {
+  /*
+    We split each bezier segment into smaller pieces based
+    on inflection points, this ensures the control point
+    polygon is convex.
+
+    (A cubic bezier can have none, one, or two inflection points)
+  */
+  var flex = segment.inflectionPoints();
+  var left;
+  var right;
+  var split;
+  var mid;
+
+  if (flex.length === 0) {
+    return [offsetSegment(segment, amount)];
+  }
+
+  if (flex.length === 1 || floatEqual(flex[1], 1)) {
+    split = segment.split(flex[0]);
+    left = split[0];
+    right = split[1];
+
+    return [
+      offsetSegment(left, amount),
+      offsetSegment(right, amount),
+    ];
+  }
+
+  split = segment.split(flex[0]);
+  left = split[0];
+  var t = (flex[1] - flex[0]) / (1 - flex[0]);
+  split = split[1].split(t);
+  mid = split[0];
+  right = split[1];
+
+  return [
+    offsetSegment(left, amount),
+    offsetSegment(mid, amount),
+    offsetSegment(right, amount),
+  ];
+}
+
+function OffsetPathModifier() {}
+
+extendPrototype([ShapeModifier], OffsetPathModifier);
+OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this.miterLimit = PropertyFactory.getProp(elem, data.ml, 0, null, this);
+  this.lineJoin = data.lj;
+  this._isAnimated = this.amount.effectsSequence.length !== 0;
+};
+
+OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
+  var outputBezier = shapePool.newElement();
+  outputBezier.c = inputBezier.c;
+  var count = inputBezier.length();
+  if (!inputBezier.c) {
+    count -= 1;
+  }
+  var i; var j; var segment;
+  var multiSegments = [];
+
+  for (i = 0; i < count; i += 1) {
+    segment = PolynomialBezier.shapeSegment(inputBezier, i);
+    multiSegments.push(offsetSegmentSplit(segment, amount));
+  }
+
+  if (!inputBezier.c) {
+    for (i = count - 1; i >= 0; i -= 1) {
+      segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
+      multiSegments.push(offsetSegmentSplit(segment, amount));
+    }
+  }
+
+  multiSegments = pruneIntersections(multiSegments);
+
+  // Add bezier segments to the output and apply line joints
+  var lastPoint = null;
+  var lastSeg = null;
+
+  for (i = 0; i < multiSegments.length; i += 1) {
+    var multiSegment = multiSegments[i];
+
+    if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
+
+    lastSeg = multiSegment[multiSegment.length - 1];
+
+    for (j = 0; j < multiSegment.length; j += 1) {
+      segment = multiSegment[j];
+
+      if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
+        outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
+      } else {
+        outputBezier.setTripleAt(
+          segment.points[0][0],
+          segment.points[0][1],
+          segment.points[1][0],
+          segment.points[1][1],
+          segment.points[0][0],
+          segment.points[0][1],
+          outputBezier.length()
+        );
+      }
+
+      outputBezier.setTripleAt(
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[2][0],
+        segment.points[2][1],
+        outputBezier.length()
+      );
+
+      lastPoint = segment.points[3];
+    }
+  }
+
+  if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
+
+  return outputBezier;
+};
+
+OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+  var miterLimit = this.miterLimit.v;
+  var lineJoin = this.lineJoin;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function getFontProperties(fontData) {
+  var styles = fontData.fStyle ? fontData.fStyle.split(' ') : [];
+
+  var fWeight = 'normal'; var
+    fStyle = 'normal';
+  var len = styles.length;
+  var styleName;
+  for (var i = 0; i < len; i += 1) {
+    styleName = styles[i].toLowerCase();
+    switch (styleName) {
+      case 'italic':
+        fStyle = 'italic';
+        break;
+      case 'bold':
+        fWeight = '700';
+        break;
+      case 'black':
+        fWeight = '900';
+        break;
+      case 'medium':
+        fWeight = '500';
+        break;
+      case 'regular':
+      case 'normal':
+        fWeight = '400';
+        break;
+      case 'light':
+      case 'thin':
+        fWeight = '200';
+        break;
+      default:
+        break;
+    }
+  }
+
+  return {
+    style: fStyle,
+    weight: fontData.fWeight || fWeight,
+  };
+}
+
+const FontManager = (function () {
+  var maxWaitingTime = 5000;
+  var emptyChar = {
+    w: 0,
+    size: 0,
+    shapes: [],
+    data: {
+      shapes: [],
+    },
+  };
+  var combinedCharacters = [];
+  // Hindi characters
+  combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366,
+    2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379,
+    2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
+
+  var BLACK_FLAG_CODE_POINT = 127988;
+  var CANCEL_TAG_CODE_POINT = 917631;
+  var A_TAG_CODE_POINT = 917601;
+  var Z_TAG_CODE_POINT = 917626;
+  var VARIATION_SELECTOR_16_CODE_POINT = 65039;
+  var ZERO_WIDTH_JOINER_CODE_POINT = 8205;
+  var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
+  var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
+
+  var surrogateModifiers = [
+    'd83cdffb',
+    'd83cdffc',
+    'd83cdffd',
+    'd83cdffe',
+    'd83cdfff',
+  ];
+
+  function trimFontOptions(font) {
+    var familyArray = font.split(',');
+    var i;
+    var len = familyArray.length;
+    var enabledFamilies = [];
+    for (i = 0; i < len; i += 1) {
+      if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
+        enabledFamilies.push(familyArray[i]);
+      }
+    }
+    return enabledFamilies.join(',');
+  }
+
+  function setUpNode(font, family) {
+    var parentNode = createTag('span');
+    // Node is invisible to screen readers.
+    parentNode.setAttribute('aria-hidden', true);
+    parentNode.style.fontFamily = family;
+    var node = createTag('span');
+    // Characters that vary significantly among different fonts
+    node.innerText = 'giItT1WQy@!-/#';
+    // Visible - so we can measure it - but not on the screen
+    parentNode.style.position = 'absolute';
+    parentNode.style.left = '-10000px';
+    parentNode.style.top = '-10000px';
+    // Large font size makes even subtle changes obvious
+    parentNode.style.fontSize = '300px';
+    // Reset any font properties
+    parentNode.style.fontVariant = 'normal';
+    parentNode.style.fontStyle = 'normal';
+    parentNode.style.fontWeight = 'normal';
+    parentNode.style.letterSpacing = '0';
+    parentNode.appendChild(node);
+    document.body.appendChild(parentNode);
+
+    // Remember width with no applied web font
+    var width = node.offsetWidth;
+    node.style.fontFamily = trimFontOptions(font) + ', ' + family;
+    return { node: node, w: width, parent: parentNode };
+  }
+
+  function checkLoadedFonts() {
+    var i;
+    var len = this.fonts.length;
+    var node;
+    var w;
+    var loadedCount = len;
+    for (i = 0; i < len; i += 1) {
+      if (this.fonts[i].loaded) {
+        loadedCount -= 1;
+      } else if (this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0) {
+        this.fonts[i].loaded = true;
+      } else {
+        node = this.fonts[i].monoCase.node;
+        w = this.fonts[i].monoCase.w;
+        if (node.offsetWidth !== w) {
+          loadedCount -= 1;
+          this.fonts[i].loaded = true;
+        } else {
+          node = this.fonts[i].sansCase.node;
+          w = this.fonts[i].sansCase.w;
+          if (node.offsetWidth !== w) {
+            loadedCount -= 1;
+            this.fonts[i].loaded = true;
+          }
+        }
+        if (this.fonts[i].loaded) {
+          this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
+          this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
+        }
+      }
+    }
+
+    if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
+      setTimeout(this.checkLoadedFontsBinded, 20);
+    } else {
+      setTimeout(this.setIsLoadedBinded, 10);
+    }
+  }
+
+  function createHelper(fontData, def) {
+    var engine = (document.body && def) ? 'svg' : 'canvas';
+    var helper;
+    var fontProps = getFontProperties(fontData);
+    if (engine === 'svg') {
+      var tHelper = createNS('text');
+      tHelper.style.fontSize = '100px';
+      // tHelper.style.fontFamily = fontData.fFamily;
+      tHelper.setAttribute('font-family', fontData.fFamily);
+      tHelper.setAttribute('font-style', fontProps.style);
+      tHelper.setAttribute('font-weight', fontProps.weight);
+      tHelper.textContent = '1';
+      if (fontData.fClass) {
+        tHelper.style.fontFamily = 'inherit';
+        tHelper.setAttribute('class', fontData.fClass);
+      } else {
+        tHelper.style.fontFamily = fontData.fFamily;
+      }
+      def.appendChild(tHelper);
+      helper = tHelper;
+    } else {
+      var tCanvasHelper = new OffscreenCanvas(500, 500).getContext('2d');
+      tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
+      helper = tCanvasHelper;
+    }
+    function measure(text) {
+      if (engine === 'svg') {
+        helper.textContent = text;
+        return helper.getComputedTextLength();
+      }
+      return helper.measureText(text).width;
+    }
+    return {
+      measureText: measure,
+    };
+  }
+
+  function addFonts(fontData, defs) {
+    if (!fontData) {
+      this.isLoaded = true;
+      return;
+    }
+    if (this.chars) {
+      this.isLoaded = true;
+      this.fonts = fontData.list;
+      return;
+    }
+    if (!document.body) {
+      this.isLoaded = true;
+      fontData.list.forEach((data) => {
+        data.helper = createHelper(data);
+        data.cache = {};
+      });
+      this.fonts = fontData.list;
+      return;
+    }
+
+    var fontArr = fontData.list;
+    var i;
+    var len = fontArr.length;
+    var _pendingFonts = len;
+    for (i = 0; i < len; i += 1) {
+      var shouldLoadFont = true;
+      var loadedSelector;
+      var j;
+      fontArr[i].loaded = false;
+      fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
+      fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
+      if (!fontArr[i].fPath) {
+        fontArr[i].loaded = true;
+        _pendingFonts -= 1;
+      } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
+        loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
+
+        if (loadedSelector.length > 0) {
+          shouldLoadFont = false;
+        }
+
+        if (shouldLoadFont) {
+          var s = createTag('style');
+          s.setAttribute('f-forigin', fontArr[i].fOrigin);
+          s.setAttribute('f-origin', fontArr[i].origin);
+          s.setAttribute('f-family', fontArr[i].fFamily);
+          s.type = 'text/css';
+          s.innerText = '@font-face {font-family: ' + fontArr[i].fFamily + "; font-style: normal; src: url('" + fontArr[i].fPath + "');}";
+          defs.appendChild(s);
+        }
+      } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
+        loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var l = createTag('link');
+          l.setAttribute('f-forigin', fontArr[i].fOrigin);
+          l.setAttribute('f-origin', fontArr[i].origin);
+          l.type = 'text/css';
+          l.rel = 'stylesheet';
+          l.href = fontArr[i].fPath;
+          document.body.appendChild(l);
+        }
+      } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
+        loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (fontArr[i].fPath === loadedSelector[j].src) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var sc = createTag('link');
+          sc.setAttribute('f-forigin', fontArr[i].fOrigin);
+          sc.setAttribute('f-origin', fontArr[i].origin);
+          sc.setAttribute('rel', 'stylesheet');
+          sc.setAttribute('href', fontArr[i].fPath);
+          defs.appendChild(sc);
+        }
+      }
+      fontArr[i].helper = createHelper(fontArr[i], defs);
+      fontArr[i].cache = {};
+      this.fonts.push(fontArr[i]);
+    }
+    if (_pendingFonts === 0) {
+      this.isLoaded = true;
+    } else {
+      // On some cases even if the font is loaded, it won't load correctly when measuring text on canvas.
+      // Adding this timeout seems to fix it
+      setTimeout(this.checkLoadedFonts.bind(this), 100);
+    }
+  }
+
+  function addChars(chars) {
+    if (!chars) {
+      return;
+    }
+    if (!this.chars) {
+      this.chars = [];
+    }
+    var i;
+    var len = chars.length;
+    var j;
+    var jLen = this.chars.length;
+    var found;
+    for (i = 0; i < len; i += 1) {
+      j = 0;
+      found = false;
+      while (j < jLen) {
+        if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
+          found = true;
+        }
+        j += 1;
+      }
+      if (!found) {
+        this.chars.push(chars[i]);
+        jLen += 1;
+      }
+    }
+  }
+
+  function getCharData(char, style, font) {
+    var i = 0;
+    var len = this.chars.length;
+    while (i < len) {
+      if (this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font) {
+        return this.chars[i];
+      }
+      i += 1;
+    }
+    if (((typeof char === 'string' && char.charCodeAt(0) !== 13) || !char)
+            && console
+            && console.warn // eslint-disable-line no-console
+            && !this._warned
+    ) {
+      this._warned = true;
+      console.warn('Missing character from exported characters list: ', char, style, font); // eslint-disable-line no-console
+    }
+    return emptyChar;
+  }
+
+  function measureText(char, fontName, size) {
+    var fontData = this.getFontByName(fontName);
+    // Using the char instead of char.charCodeAt(0)
+    // to avoid collisions between equal chars
+    var index = char;
+    if (!fontData.cache[index]) {
+      var tHelper = fontData.helper;
+      if (char === ' ') {
+        var doubleSize = tHelper.measureText('|' + char + '|');
+        var singleSize = tHelper.measureText('||');
+        fontData.cache[index] = (doubleSize - singleSize) / 100;
+      } else {
+        fontData.cache[index] = tHelper.measureText(char) / 100;
+      }
+    }
+    return fontData.cache[index] * size;
+  }
+
+  function getFontByName(name) {
+    var i = 0;
+    var len = this.fonts.length;
+    while (i < len) {
+      if (this.fonts[i].fName === name) {
+        return this.fonts[i];
+      }
+      i += 1;
+    }
+    return this.fonts[0];
+  }
+
+  function getCodePoint(string) {
+    var codePoint = 0;
+    var first = string.charCodeAt(0);
+    if (first >= 0xD800 && first <= 0xDBFF) {
+      var second = string.charCodeAt(1);
+      if (second >= 0xDC00 && second <= 0xDFFF) {
+        codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+      }
+    }
+    return codePoint;
+  }
+
+  // Skin tone modifiers
+  function isModifier(firstCharCode, secondCharCode) {
+    var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
+    return surrogateModifiers.indexOf(sum) !== -1;
+  }
+
+  function isZeroWidthJoiner(charCode) {
+    return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
+  }
+
+  // This codepoint may change the appearance of the preceding character.
+  // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
+  // as a colorful image as compared to a monochrome text variant.
+  function isVariationSelector(charCode) {
+    return charCode === VARIATION_SELECTOR_16_CODE_POINT;
+  }
+
+  // The regional indicator symbols are a set of 26 alphabetic Unicode
+  /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
+  // two-letter country codes in a way that allows optional special treatment.
+  function isRegionalCode(string) {
+    var codePoint = getCodePoint(string);
+    if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
+      return true;
+    }
+    return false;
+  }
+
+  // Some Emoji implementations represent combinations of
+  // two “regional indicator” letters as a single flag symbol.
+  function isFlagEmoji(string) {
+    return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
+  }
+
+  function isCombinedCharacter(char) {
+    return combinedCharacters.indexOf(char) !== -1;
+  }
+
+  // Regional flags start with a BLACK_FLAG_CODE_POINT
+  // folowed by 5 chars in the TAG range
+  // and end with a CANCEL_TAG_CODE_POINT
+  function isRegionalFlag(text, index) {
+    var codePoint = getCodePoint(text.substr(index, 2));
+    if (codePoint !== BLACK_FLAG_CODE_POINT) {
+      return false;
+    }
+    var count = 0;
+    index += 2;
+    while (count < 5) {
+      codePoint = getCodePoint(text.substr(index, 2));
+      if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
+        return false;
+      }
+      count += 1;
+      index += 2;
+    }
+    return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
+  }
+
+  function setIsLoaded() {
+    this.isLoaded = true;
+  }
+
+  var Font = function () {
+    this.fonts = [];
+    this.chars = null;
+    this.typekitLoaded = 0;
+    this.isLoaded = false;
+    this._warned = false;
+    this.initTime = Date.now();
+    this.setIsLoadedBinded = this.setIsLoaded.bind(this);
+    this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
+  };
+  Font.isModifier = isModifier;
+  Font.isZeroWidthJoiner = isZeroWidthJoiner;
+  Font.isFlagEmoji = isFlagEmoji;
+  Font.isRegionalCode = isRegionalCode;
+  Font.isCombinedCharacter = isCombinedCharacter;
+  Font.isRegionalFlag = isRegionalFlag;
+  Font.isVariationSelector = isVariationSelector;
+  Font.BLACK_FLAG_CODE_POINT = BLACK_FLAG_CODE_POINT;
+
+  var fontPrototype = {
+    addChars: addChars,
+    addFonts: addFonts,
+    getCharData: getCharData,
+    getFontByName: getFontByName,
+    measureText: measureText,
+    checkLoadedFonts: checkLoadedFonts,
+    setIsLoaded: setIsLoaded,
+  };
+
+  Font.prototype = fontPrototype;
+
+  return Font;
+}());
+
+function SlotManager(animationData) {
+  this.animationData = animationData;
+}
+SlotManager.prototype.getProp = function (data) {
+  if (this.animationData.slots
+    && this.animationData.slots[data.sid]
+  ) {
+    return Object.assign(data, this.animationData.slots[data.sid].p);
+  }
+  return data;
+};
+
+function slotFactory(animationData) {
+  return new SlotManager(animationData);
+}
+
+function RenderableElement() {
+
+}
+
+RenderableElement.prototype = {
+  initRenderable: function () {
+    // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
+    this.isInRange = false;
+    // layer's display state
+    this.hidden = false;
+    // If layer's transparency equals 0, it can be hidden
+    this.isTransparent = false;
+    // list of animated components
+    this.renderableComponents = [];
+  },
+  addRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) === -1) {
+      this.renderableComponents.push(component);
+    }
+  },
+  removeRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) !== -1) {
+      this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1);
+    }
+  },
+  prepareRenderableFrame: function (num) {
+    this.checkLayerLimits(num);
+  },
+  checkTransparency: function () {
+    if (this.finalTransform.mProp.o.v <= 0) {
+      if (!this.isTransparent && this.globalData.renderConfig.hideOnTransparent) {
+        this.isTransparent = true;
+        this.hide();
+      }
+    } else if (this.isTransparent) {
+      this.isTransparent = false;
+      this.show();
+    }
+  },
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     *
+     */
+  checkLayerLimits: function (num) {
+    if (this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) {
+      if (this.isInRange !== true) {
+        this.globalData._mdf = true;
+        this._mdf = true;
+        this.isInRange = true;
+        this.show();
+      }
+    } else if (this.isInRange !== false) {
+      this.globalData._mdf = true;
+      this.isInRange = false;
+      this.hide();
+    }
+  },
+  renderRenderable: function () {
+    var i;
+    var len = this.renderableComponents.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderableComponents[i].renderFrame(this._isFirstFrame);
+    }
+    /* this.maskManager.renderFrame(this.finalTransform.mat);
+        this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
+  },
+  sourceRectAtTime: function () {
+    return {
+      top: 0,
+      left: 0,
+      width: 100,
+      height: 100,
+    };
+  },
+  getLayerSize: function () {
+    if (this.data.ty === 5) {
+      return { w: this.data.textData.width, h: this.data.textData.height };
+    }
+    return { w: this.data.width, h: this.data.height };
+  },
+};
+
+const getBlendMode = (function () {
+  var blendModeEnums = {
+    0: 'source-over',
+    1: 'multiply',
+    2: 'screen',
+    3: 'overlay',
+    4: 'darken',
+    5: 'lighten',
+    6: 'color-dodge',
+    7: 'color-burn',
+    8: 'hard-light',
+    9: 'soft-light',
+    10: 'difference',
+    11: 'exclusion',
+    12: 'hue',
+    13: 'saturation',
+    14: 'color',
+    15: 'luminosity',
+  };
+
+  return function (mode) {
+    return blendModeEnums[mode] || '';
+  };
+}());
+
+function SliderEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function AngleEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function ColorEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function PointEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function LayerIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function MaskIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function CheckboxEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function NoValueEffect() {
+  this.p = {};
+}
+
+function EffectsManager(data, element) {
+  var effects = data.ef || [];
+  this.effectElements = [];
+  var i;
+  var len = effects.length;
+  var effectItem;
+  for (i = 0; i < len; i += 1) {
+    effectItem = new GroupEffect(effects[i], element);
+    this.effectElements.push(effectItem);
+  }
+}
+
+function GroupEffect(data, element) {
+  this.init(data, element);
+}
+
+extendPrototype([DynamicPropertyContainer], GroupEffect);
+
+GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
+
+GroupEffect.prototype.init = function (data, element) {
+  this.data = data;
+  this.effectElements = [];
+  this.initDynamicPropertyContainer(element);
+  var i;
+  var len = this.data.ef.length;
+  var eff;
+  var effects = this.data.ef;
+  for (i = 0; i < len; i += 1) {
+    eff = null;
+    switch (effects[i].ty) {
+      case 0:
+        eff = new SliderEffect(effects[i], element, this);
+        break;
+      case 1:
+        eff = new AngleEffect(effects[i], element, this);
+        break;
+      case 2:
+        eff = new ColorEffect(effects[i], element, this);
+        break;
+      case 3:
+        eff = new PointEffect(effects[i], element, this);
+        break;
+      case 4:
+      case 7:
+        eff = new CheckboxEffect(effects[i], element, this);
+        break;
+      case 10:
+        eff = new LayerIndexEffect(effects[i], element, this);
+        break;
+      case 11:
+        eff = new MaskIndexEffect(effects[i], element, this);
+        break;
+      case 5:
+        eff = new EffectsManager(effects[i], element, this);
+        break;
+        // case 6:
+      default:
+        eff = new NoValueEffect(effects[i], element, this);
+        break;
+    }
+    if (eff) {
+      this.effectElements.push(eff);
+    }
+  }
+};
+
+function BaseElement() {
+}
+
+BaseElement.prototype = {
+  checkMasks: function () {
+    if (!this.data.hasMask) {
+      return false;
+    }
+    var i = 0;
+    var len = this.data.masksProperties.length;
+    while (i < len) {
+      if ((this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false)) {
+        return true;
+      }
+      i += 1;
+    }
+    return false;
+  },
+  initExpressions: function () {
+    const expressionsInterfaces = getExpressionInterfaces();
+    if (!expressionsInterfaces) {
+      return;
+    }
+    const LayerExpressionInterface = expressionsInterfaces('layer');
+    const EffectsExpressionInterface = expressionsInterfaces('effects');
+    const ShapeExpressionInterface = expressionsInterfaces('shape');
+    const TextExpressionInterface = expressionsInterfaces('text');
+    const CompExpressionInterface = expressionsInterfaces('comp');
+    this.layerInterface = LayerExpressionInterface(this);
+    if (this.data.hasMask && this.maskManager) {
+      this.layerInterface.registerMaskInterface(this.maskManager);
+    }
+    var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
+    this.layerInterface.registerEffectsInterface(effectsInterface);
+
+    if (this.data.ty === 0 || this.data.xt) {
+      this.compInterface = CompExpressionInterface(this);
+    } else if (this.data.ty === 4) {
+      this.layerInterface.shapeInterface = ShapeExpressionInterface(this.shapesData, this.itemsData, this.layerInterface);
+      this.layerInterface.content = this.layerInterface.shapeInterface;
+    } else if (this.data.ty === 5) {
+      this.layerInterface.textInterface = TextExpressionInterface(this);
+      this.layerInterface.text = this.layerInterface.textInterface;
+    }
+  },
+  setBlendMode: function () {
+    var blendModeValue = getBlendMode(this.data.bm);
+    var elem = this.baseElement || this.layerElement;
+
+    elem.style['mix-blend-mode'] = blendModeValue;
+  },
+  initBaseData: function (data, globalData, comp) {
+    this.globalData = globalData;
+    this.comp = comp;
+    this.data = data;
+    this.layerId = createElementID();
+
+    // Stretch factor for old animations missing this property.
+    if (!this.data.sr) {
+      this.data.sr = 1;
+    }
+    // effects manager
+    this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
+  },
+  getType: function () {
+    return this.type;
+  },
+  sourceRectAtTime: function () {},
+};
+
+/**
+ * @file
+ * Handles element's layer frame update.
+ * Checks layer in point and out point
+ *
+ */
+
+function FrameElement() {}
+
+FrameElement.prototype = {
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     */
+  initFrame: function () {
+    // set to true when inpoint is rendered
+    this._isFirstFrame = false;
+    // list of animated properties
+    this.dynamicProperties = [];
+    // If layer has been modified in current tick this will be true
+    this._mdf = false;
+  },
+  /**
+     * @function
+     * Calculates all dynamic values
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     * @param {boolean} isVisible
+     * if layers is currently in range
+     *
+     */
+  prepareProperties: function (num, isVisible) {
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      if (isVisible || (this._isParent && this.dynamicProperties[i].propType === 'transform')) {
+        this.dynamicProperties[i].getValue();
+        if (this.dynamicProperties[i]._mdf) {
+          this.globalData._mdf = true;
+          this._mdf = true;
+        }
+      }
+    }
+  },
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+    }
+  },
+};
+
+function FootageElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.footageData = globalData.imageLoader.getAsset(this.assetData);
+  this.initBaseData(data, globalData, comp);
+}
+
+FootageElement.prototype.prepareFrame = function () {
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
+
+FootageElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+FootageElement.prototype.renderFrame = function () {
+};
+
+FootageElement.prototype.destroy = function () {
+};
+
+FootageElement.prototype.initExpressions = function () {
+  const expressionsInterfaces = getExpressionInterfaces();
+  if (!expressionsInterfaces) {
+    return;
+  }
+  const FootageInterface = expressionsInterfaces('footage');
+  this.layerInterface = FootageInterface(this);
+};
+
+FootageElement.prototype.getFootageData = function () {
+  return this.footageData;
+};
+
+function AudioElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initBaseData(data, globalData, comp);
+  this._isPlaying = false;
+  this._canPlay = false;
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  this.audio = this.globalData.audioController.createAudio(assetPath);
+  this._currentTime = 0;
+  this.globalData.audioController.addAudio(this);
+  this._volumeMultiplier = 1;
+  this._volume = 1;
+  this._previousVolume = null;
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+  this.lv = PropertyFactory.getProp(this, data.au && data.au.lv ? data.au.lv : { k: [100] }, 1, 0.01, this);
+}
+
+AudioElement.prototype.prepareFrame = function (num) {
+  this.prepareRenderableFrame(num, true);
+  this.prepareProperties(num, true);
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    this._currentTime = timeRemapped;
+  } else {
+    this._currentTime = num / this.data.sr;
+  }
+  this._volume = this.lv.v[0];
+  var totalVolume = this._volume * this._volumeMultiplier;
+  if (this._previousVolume !== totalVolume) {
+    this._previousVolume = totalVolume;
+    this.audio.volume(totalVolume);
+  }
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
+
+AudioElement.prototype.renderFrame = function () {
+  if (this.isInRange && this._canPlay) {
+    if (!this._isPlaying) {
+      this.audio.play();
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+      this._isPlaying = true;
+    } else if (!this.audio.playing()
+      || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1
+    ) {
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+    }
+  }
+};
+
+AudioElement.prototype.show = function () {
+  // this.audio.play()
+};
+
+AudioElement.prototype.hide = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+};
+
+AudioElement.prototype.pause = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+  this._canPlay = false;
+};
+
+AudioElement.prototype.resume = function () {
+  this._canPlay = true;
+};
+
+AudioElement.prototype.setRate = function (rateValue) {
+  this.audio.rate(rateValue);
+};
+
+AudioElement.prototype.volume = function (volumeValue) {
+  this._volumeMultiplier = volumeValue;
+  this._previousVolume = volumeValue * this._volume;
+  this.audio.volume(this._previousVolume);
+};
+
+AudioElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+AudioElement.prototype.destroy = function () {
+};
+
+AudioElement.prototype.sourceRectAtTime = function () {
+};
+
+AudioElement.prototype.initExpressions = function () {
+};
+
+function BaseRenderer() {}
+BaseRenderer.prototype.checkLayers = function (num) {
+  var i;
+  var len = this.layers.length;
+  var data;
+  this.completeLayers = true;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (!this.elements[i]) {
+      data = this.layers[i];
+      if (data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) {
+        this.buildItem(i);
+      }
+    }
+    this.completeLayers = this.elements[i] ? this.completeLayers : false;
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.createItem = function (layer) {
+  switch (layer.ty) {
+    case 2:
+      return this.createImage(layer);
+    case 0:
+      return this.createComp(layer);
+    case 1:
+      return this.createSolid(layer);
+    case 3:
+      return this.createNull(layer);
+    case 4:
+      return this.createShape(layer);
+    case 5:
+      return this.createText(layer);
+    case 6:
+      return this.createAudio(layer);
+    case 13:
+      return this.createCamera(layer);
+    case 15:
+      return this.createFootage(layer);
+    default:
+      return this.createNull(layer);
+  }
+};
+
+BaseRenderer.prototype.createCamera = function () {
+  throw new Error('You\'re using a 3d camera. Try the html renderer.');
+};
+
+BaseRenderer.prototype.createAudio = function (data) {
+  return new AudioElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.createFootage = function (data) {
+  return new FootageElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.buildAllItems = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    this.buildItem(i);
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.includeLayers = function (newLayers) {
+  this.completeLayers = false;
+  var i;
+  var len = newLayers.length;
+  var j;
+  var jLen = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    j = 0;
+    while (j < jLen) {
+      if (this.layers[j].id === newLayers[i].id) {
+        this.layers[j] = newLayers[i];
+        break;
+      }
+      j += 1;
+    }
+  }
+};
+
+BaseRenderer.prototype.setProjectInterface = function (pInterface) {
+  this.globalData.projectInterface = pInterface;
+};
+
+BaseRenderer.prototype.initItems = function () {
+  if (!this.globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+};
+BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
+  var elements = this.elements;
+  var layers = this.layers;
+  var i = 0;
+  var len = layers.length;
+  while (i < len) {
+    if (layers[i].ind == parentName) { // eslint-disable-line eqeqeq
+      if (!elements[i] || elements[i] === true) {
+        this.buildItem(i);
+        this.addPendingElement(element);
+      } else {
+        hierarchy.push(elements[i]);
+        elements[i].setAsParent();
+        if (layers[i].parent !== undefined) {
+          this.buildElementParenting(element, layers[i].parent, hierarchy);
+        } else {
+          element.setHierarchy(hierarchy);
+        }
+      }
+    }
+    i += 1;
+  }
+};
+
+BaseRenderer.prototype.addPendingElement = function (element) {
+  this.pendingElements.push(element);
+};
+
+BaseRenderer.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var len = assets.length;
+  for (i = 0; i < len; i += 1) {
+    if (assets[i].xt) {
+      var comp = this.createComp(assets[i]);
+      comp.initExpressions();
+      this.globalData.projectInterface.registerComposition(comp);
+    }
+  }
+};
+
+BaseRenderer.prototype.getElementById = function (ind) {
+  var i;
+  var len = this.elements.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i].data.ind === ind) {
+      return this.elements[i];
+    }
+  }
+  return null;
+};
+
+BaseRenderer.prototype.getElementByPath = function (path) {
+  var pathValue = path.shift();
+  var element;
+  if (typeof pathValue === 'number') {
+    element = this.elements[pathValue];
+  } else {
+    var i;
+    var len = this.elements.length;
+    for (i = 0; i < len; i += 1) {
+      if (this.elements[i].data.nm === pathValue) {
+        element = this.elements[i];
+        break;
+      }
+    }
+  }
+  if (path.length === 0) {
+    return element;
+  }
+  return element.getElementByPath(path);
+};
+
+BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
+  this.globalData.fontManager = new FontManager();
+  this.globalData.slotManager = slotFactory(animData);
+  this.globalData.fontManager.addChars(animData.chars);
+  this.globalData.fontManager.addFonts(animData.fonts, fontsContainer);
+  this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+  this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+  this.globalData.imageLoader = this.animationItem.imagePreloader;
+  this.globalData.audioController = this.animationItem.audioController;
+  this.globalData.frameId = 0;
+  this.globalData.frameRate = animData.fr;
+  this.globalData.nm = animData.nm;
+  this.globalData.compSize = {
+    w: animData.w,
+    h: animData.h,
+  };
+};
+
+var effectTypes = {
+  TRANSFORM_EFFECT: 'transformEFfect',
+};
+
+function TransformElement() {}
+
+TransformElement.prototype = {
+  initTransform: function () {
+    var mat = new Matrix();
+    this.finalTransform = {
+      mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : { o: 0 },
+      _matMdf: false,
+      _localMatMdf: false,
+      _opMdf: false,
+      mat: mat,
+      localMat: mat,
+      localOpacity: 1,
+    };
+    if (this.data.ao) {
+      this.finalTransform.mProp.autoOriented = true;
+    }
+
+    // TODO: check TYPE 11: Guided elements
+    if (this.data.ty !== 11) {
+      // this.createElements();
+    }
+  },
+  renderTransform: function () {
+    this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
+    this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
+
+    if (this.hierarchy) {
+      var mat;
+      var finalMat = this.finalTransform.mat;
+      var i = 0;
+      var len = this.hierarchy.length;
+      // Checking if any of the transformation matrices in the hierarchy chain has changed.
+      if (!this.finalTransform._matMdf) {
+        while (i < len) {
+          if (this.hierarchy[i].finalTransform.mProp._mdf) {
+            this.finalTransform._matMdf = true;
+            break;
+          }
+          i += 1;
+        }
+      }
+
+      if (this.finalTransform._matMdf) {
+        mat = this.finalTransform.mProp.v.props;
+        finalMat.cloneFromProps(mat);
+        for (i = 0; i < len; i += 1) {
+          finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
+        }
+      }
+    }
+    if (!this.localTransforms || this.finalTransform._matMdf) {
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+    }
+    if (this.finalTransform._opMdf) {
+      this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderLocalTransform: function () {
+    if (this.localTransforms) {
+      var i = 0;
+      var len = this.localTransforms.length;
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+      if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
+        while (i < len) {
+          if (this.localTransforms[i]._mdf) {
+            this.finalTransform._localMatMdf = true;
+          }
+          if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
+            this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+            this.finalTransform._opMdf = true;
+          }
+          i += 1;
+        }
+      }
+      if (this.finalTransform._localMatMdf) {
+        var localMat = this.finalTransform.localMat;
+        this.localTransforms[0].matrix.clone(localMat);
+        for (i = 1; i < len; i += 1) {
+          var lmat = this.localTransforms[i].matrix;
+          localMat.multiply(lmat);
+        }
+        localMat.multiply(this.finalTransform.mat);
+      }
+      if (this.finalTransform._opMdf) {
+        var localOp = this.finalTransform.localOpacity;
+        for (i = 0; i < len; i += 1) {
+          localOp *= this.localTransforms[i].opacity * 0.01;
+        }
+        this.finalTransform.localOpacity = localOp;
+      }
+    }
+  },
+  searchEffectTransforms: function () {
+    if (this.renderableEffectsManager) {
+      var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+      if (transformEffects.length) {
+        this.localTransforms = [];
+        this.finalTransform.localMat = new Matrix();
+        var i = 0;
+        var len = transformEffects.length;
+        for (i = 0; i < len; i += 1) {
+          this.localTransforms.push(transformEffects[i]);
+        }
+      }
+    }
+  },
+  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;
+    var len = transforms.length;
+    var 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;
+  },
+  mHelper: new Matrix(),
+};
+
+function MaskElement(data, element, globalData) {
+  this.data = data;
+  this.element = element;
+  this.globalData = globalData;
+  this.storedData = [];
+  this.masksProperties = this.data.masksProperties || [];
+  this.maskElement = null;
+  var defs = this.globalData.defs;
+  var i;
+  var len = this.masksProperties ? this.masksProperties.length : 0;
+  this.viewData = createSizedArray(len);
+  this.solidPath = '';
+
+  var path;
+  var properties = this.masksProperties;
+  var count = 0;
+  var currentMasks = [];
+  var j;
+  var jLen;
+  var layerId = createElementID();
+  var rect;
+  var expansor;
+  var feMorph;
+  var x;
+  var maskType = 'clipPath';
+  var maskRef = 'clip-path';
+  for (i = 0; i < len; i += 1) {
+    if ((properties[i].mode !== 'a' && properties[i].mode !== 'n') || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
+      maskType = 'mask';
+      maskRef = 'mask';
+    }
+
+    if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
+      rect = createNS('rect');
+      rect.setAttribute('fill', '#ffffff');
+      rect.setAttribute('width', this.element.comp.data.w || 0);
+      rect.setAttribute('height', this.element.comp.data.h || 0);
+      currentMasks.push(rect);
+    } else {
+      rect = null;
+    }
+
+    path = createNS('path');
+    if (properties[i].mode === 'n') {
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        elem: path,
+        lastPath: '',
+      };
+      defs.appendChild(path);
+    } else {
+      count += 1;
+
+      path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      path.setAttribute('clip-rule', 'nonzero');
+      var filterID;
+
+      if (properties[i].x.k !== 0) {
+        maskType = 'mask';
+        maskRef = 'mask';
+        x = PropertyFactory.getProp(this.element, properties[i].x, 0, null, this.element);
+        filterID = createElementID();
+        expansor = createNS('filter');
+        expansor.setAttribute('id', filterID);
+        feMorph = createNS('feMorphology');
+        feMorph.setAttribute('operator', 'erode');
+        feMorph.setAttribute('in', 'SourceGraphic');
+        feMorph.setAttribute('radius', '0');
+        expansor.appendChild(feMorph);
+        defs.appendChild(expansor);
+        path.setAttribute('stroke', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      } else {
+        feMorph = null;
+        x = null;
+      }
+
+      // TODO move this to a factory or to a constructor
+      this.storedData[i] = {
+        elem: path,
+        x: x,
+        expan: feMorph,
+        lastPath: '',
+        lastOperator: '',
+        filterId: filterID,
+        lastRadius: 0,
+      };
+      if (properties[i].mode === 'i') {
+        jLen = currentMasks.length;
+        var g = createNS('g');
+        for (j = 0; j < jLen; j += 1) {
+          g.appendChild(currentMasks[j]);
+        }
+        var mask = createNS('mask');
+        mask.setAttribute('mask-type', 'alpha');
+        mask.setAttribute('id', layerId + '_' + count);
+        mask.appendChild(path);
+        defs.appendChild(mask);
+        g.setAttribute('mask', 'url(' + getLocationHref() + '#' + layerId + '_' + count + ')');
+
+        currentMasks.length = 0;
+        currentMasks.push(g);
+      } else {
+        currentMasks.push(path);
+      }
+      if (properties[i].inv && !this.solidPath) {
+        this.solidPath = this.createLayerSolidPath();
+      }
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        elem: path,
+        lastPath: '',
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        invRect: rect,
+      };
+      if (!this.viewData[i].prop.k) {
+        this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
+      }
+    }
+  }
+
+  this.maskElement = createNS(maskType);
+
+  len = currentMasks.length;
+  for (i = 0; i < len; i += 1) {
+    this.maskElement.appendChild(currentMasks[i]);
+  }
+
+  if (count > 0) {
+    this.maskElement.setAttribute('id', layerId);
+    this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
+    defs.appendChild(this.maskElement);
+  }
+  if (this.viewData.length) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+MaskElement.prototype.getMaskProperty = function (pos) {
+  return this.viewData[pos].prop;
+};
+
+MaskElement.prototype.renderFrame = function (isFirstFrame) {
+  var finalMat = this.element.finalTransform.mat;
+  var i;
+  var len = this.masksProperties.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.viewData[i].prop._mdf || isFirstFrame) {
+      this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
+    }
+    if (this.viewData[i].op._mdf || isFirstFrame) {
+      this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
+    }
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
+        this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
+      }
+      if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
+        var feMorph = this.storedData[i].expan;
+        if (this.storedData[i].x.v < 0) {
+          if (this.storedData[i].lastOperator !== 'erode') {
+            this.storedData[i].lastOperator = 'erode';
+            this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
+          }
+          feMorph.setAttribute('radius', -this.storedData[i].x.v);
+        } else {
+          if (this.storedData[i].lastOperator !== 'dilate') {
+            this.storedData[i].lastOperator = 'dilate';
+            this.storedData[i].elem.setAttribute('filter', null);
+          }
+          this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
+        }
+      }
+    }
+  }
+};
+
+MaskElement.prototype.getMaskelement = function () {
+  return this.maskElement;
+};
+
+MaskElement.prototype.createLayerSolidPath = function () {
+  var path = 'M0,0 ';
+  path += ' h' + this.globalData.compSize.w;
+  path += ' v' + this.globalData.compSize.h;
+  path += ' h-' + this.globalData.compSize.w;
+  path += ' v-' + this.globalData.compSize.h + ' ';
+  return path;
+};
+
+MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
+  var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  var i;
+  var len;
+  len = pathNodes._length;
+  for (i = 1; i < len; i += 1) {
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
+  }
+  // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+  if (pathNodes.c && len > 1) {
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  }
+  // pathNodes.__renderedString = pathString;
+
+  if (viewData.lastPath !== pathString) {
+    var pathShapeValue = '';
+    if (viewData.elem) {
+      if (pathNodes.c) {
+        pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
+      }
+      viewData.elem.setAttribute('d', pathShapeValue);
+    }
+    viewData.lastPath = pathString;
+  }
+};
+
+MaskElement.prototype.destroy = function () {
+  this.element = null;
+  this.globalData = null;
+  this.maskElement = null;
+  this.data = null;
+  this.masksProperties = null;
+};
+
+const filtersFactory = (function () {
+  var ob = {};
+  ob.createFilter = createFilter;
+  ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
+
+  function createFilter(filId, skipCoordinates) {
+    var fil = createNS('filter');
+    fil.setAttribute('id', filId);
+    if (skipCoordinates !== true) {
+      fil.setAttribute('filterUnits', 'objectBoundingBox');
+      fil.setAttribute('x', '0%');
+      fil.setAttribute('y', '0%');
+      fil.setAttribute('width', '100%');
+      fil.setAttribute('height', '100%');
+    }
+    return fil;
+  }
+
+  function createAlphaToLuminanceFilter() {
+    var feColorMatrix = createNS('feColorMatrix');
+    feColorMatrix.setAttribute('type', 'matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+    feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
+    return feColorMatrix;
+  }
+
+  return ob;
+}());
+
+const featureSupport = (function () {
+  var ob = {
+    maskType: true,
+    svgLumaHidden: true,
+    offscreenCanvas: typeof OffscreenCanvas !== 'undefined',
+  };
+  if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
+    ob.maskType = false;
+  }
+  if (/firefox/i.test(navigator.userAgent)) {
+    ob.svgLumaHidden = false;
+  }
+  return ob;
+}());
+
+var registeredEffects$1 = {};
+var idPrefix = 'filter_result_';
+
+function SVGEffects(elem) {
+  var i;
+  var source = 'SourceGraphic';
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  var filId = createElementID();
+  var fil = filtersFactory.createFilter(filId, true);
+  var count = 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects$1[type]) {
+      var Effect = registeredEffects$1[type].effect;
+      filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
+      source = idPrefix + count;
+      if (registeredEffects$1[type].countsAsEffect) {
+        count += 1;
+      }
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (count) {
+    elem.globalData.defs.appendChild(fil);
+    elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+SVGEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect$1(id, effect, countsAsEffect) {
+  registeredEffects$1[id] = {
+    effect,
+    countsAsEffect,
+  };
+}
+
+function SVGBaseElement() {
+}
+
+SVGBaseElement.prototype = {
+  initRendererElement: function () {
+    this.layerElement = createNS('g');
+  },
+  createContainerElements: function () {
+    this.matteElement = createNS('g');
+    this.transformedElement = this.layerElement;
+    this.maskedElement = this.layerElement;
+    this._sizeChanged = false;
+    var layerElementParent = null;
+    // If this layer acts as a mask for the following layer
+    if (this.data.td) {
+      this.matteMasks = {};
+      var gg = createNS('g');
+      gg.setAttribute('id', this.layerId);
+      gg.appendChild(this.layerElement);
+      layerElementParent = gg;
+      this.globalData.defs.appendChild(gg);
+    } else if (this.data.tt) {
+      this.matteElement.appendChild(this.layerElement);
+      layerElementParent = this.matteElement;
+      this.baseElement = this.matteElement;
+    } else {
+      this.baseElement = this.layerElement;
+    }
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
+    if (this.data.ty === 0 && !this.data.hd) {
+      var cp = createNS('clipPath');
+      var pt = createNS('path');
+      pt.setAttribute('d', 'M0,0 L' + this.data.w + ',0 L' + this.data.w + ',' + this.data.h + ' L0,' + this.data.h + 'z');
+      var clipId = createElementID();
+      cp.setAttribute('id', clipId);
+      cp.appendChild(pt);
+      this.globalData.defs.appendChild(cp);
+
+      if (this.checkMasks()) {
+        var cpGroup = createNS('g');
+        cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+        cpGroup.appendChild(this.layerElement);
+        this.transformedElement = cpGroup;
+        if (layerElementParent) {
+          layerElementParent.appendChild(this.transformedElement);
+        } else {
+          this.baseElement = this.transformedElement;
+        }
+      } else {
+        this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+      }
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    if (this.finalTransform._localMatMdf) {
+      this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
+    }
+    if (this.finalTransform._opMdf) {
+      this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
+    }
+  },
+  destroyBaseElement: function () {
+    this.layerElement = null;
+    this.matteElement = null;
+    this.maskManager.destroy();
+  },
+  getBaseElement: function () {
+    if (this.data.hd) {
+      return null;
+    }
+    return this.baseElement;
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+    this.renderableEffectsManager = new SVGEffects(this);
+    this.searchEffectTransforms();
+  },
+  getMatte: function (matteType) {
+    // This should not be a common case. But for backward compatibility, we'll create the matte object.
+    // It solves animations that have two consecutive layers marked as matte masks.
+    // Which is an undefined behavior in AE.
+    if (!this.matteMasks) {
+      this.matteMasks = {};
+    }
+    if (!this.matteMasks[matteType]) {
+      var id = this.layerId + '_' + matteType;
+      var filId;
+      var fil;
+      var useElement;
+      var gg;
+      if (matteType === 1 || matteType === 3) {
+        var masker = createNS('mask');
+        masker.setAttribute('id', id);
+        masker.setAttribute('mask-type', matteType === 3 ? 'luminance' : 'alpha');
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        masker.appendChild(useElement);
+        this.globalData.defs.appendChild(masker);
+        if (!featureSupport.maskType && matteType === 1) {
+          masker.setAttribute('mask-type', 'luminance');
+          filId = createElementID();
+          fil = filtersFactory.createFilter(filId);
+          this.globalData.defs.appendChild(fil);
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          gg.appendChild(useElement);
+          masker.appendChild(gg);
+          gg.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        }
+      } else if (matteType === 2) {
+        var maskGroup = createNS('mask');
+        maskGroup.setAttribute('id', id);
+        maskGroup.setAttribute('mask-type', 'alpha');
+        var maskGrouper = createNS('g');
+        maskGroup.appendChild(maskGrouper);
+        filId = createElementID();
+        fil = filtersFactory.createFilter(filId);
+        /// /
+        var feCTr = createNS('feComponentTransfer');
+        feCTr.setAttribute('in', 'SourceGraphic');
+        fil.appendChild(feCTr);
+        var feFunc = createNS('feFuncA');
+        feFunc.setAttribute('type', 'table');
+        feFunc.setAttribute('tableValues', '1.0 0.0');
+        feCTr.appendChild(feFunc);
+        /// /
+        this.globalData.defs.appendChild(fil);
+        var alphaRect = createNS('rect');
+        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');
+        alphaRect.setAttribute('opacity', '0');
+        maskGrouper.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        maskGrouper.appendChild(alphaRect);
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        maskGrouper.appendChild(useElement);
+        if (!featureSupport.maskType) {
+          maskGroup.setAttribute('mask-type', 'luminance');
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          maskGrouper.appendChild(alphaRect);
+          gg.appendChild(this.layerElement);
+          maskGrouper.appendChild(gg);
+        }
+        this.globalData.defs.appendChild(maskGroup);
+      }
+      this.matteMasks[matteType] = id;
+    }
+    return this.matteMasks[matteType];
+  },
+  setMatte: function (id) {
+    if (!this.matteElement) {
+      return;
+    }
+    this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+  },
+};
+
+/**
+ * @file
+ * Handles AE's layer parenting property.
+ *
+ */
+
+function HierarchyElement() {}
+
+HierarchyElement.prototype = {
+  /**
+     * @function
+     * Initializes hierarchy properties
+     *
+     */
+  initHierarchy: function () {
+    // element's parent list
+    this.hierarchy = [];
+    // if element is parent of another layer _isParent will be true
+    this._isParent = false;
+    this.checkParenting();
+  },
+  /**
+     * @function
+     * Sets layer's hierarchy.
+     * @param {array} hierarch
+     * layer's parent list
+     *
+     */
+  setHierarchy: function (hierarchy) {
+    this.hierarchy = hierarchy;
+  },
+  /**
+     * @function
+     * Sets layer as parent.
+     *
+     */
+  setAsParent: function () {
+    this._isParent = true;
+  },
+  /**
+     * @function
+     * Searches layer's parenting chain
+     *
+     */
+  checkParenting: function () {
+    if (this.data.parent !== undefined) {
+      this.comp.buildElementParenting(this, this.data.parent, []);
+    }
+  },
+};
+
+function RenderableDOMElement() {}
+
+(function () {
+  var _prototype = {
+    initElement: function (data, globalData, comp) {
+      this.initFrame();
+      this.initBaseData(data, globalData, comp);
+      this.initTransform(data, globalData, comp);
+      this.initHierarchy();
+      this.initRenderable();
+      this.initRendererElement();
+      this.createContainerElements();
+      this.createRenderableComponents();
+      this.createContent();
+      this.hide();
+    },
+    hide: function () {
+      // console.log('HIDE', this);
+      if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+        var elem = this.baseElement || this.layerElement;
+        elem.style.display = 'none';
+        this.hidden = true;
+      }
+    },
+    show: function () {
+      // console.log('SHOW', this);
+      if (this.isInRange && !this.isTransparent) {
+        if (!this.data.hd) {
+          var elem = this.baseElement || this.layerElement;
+          elem.style.display = 'block';
+        }
+        this.hidden = false;
+        this._isFirstFrame = true;
+      }
+    },
+    renderFrame: function () {
+      // If it is exported as hidden (data.hd === true) no need to render
+      // If it is not visible no need to render
+      if (this.data.hd || this.hidden) {
+        return;
+      }
+      this.renderTransform();
+      this.renderRenderable();
+      this.renderLocalTransform();
+      this.renderElement();
+      this.renderInnerContent();
+      if (this._isFirstFrame) {
+        this._isFirstFrame = false;
+      }
+    },
+    renderInnerContent: function () {},
+    prepareFrame: function (num) {
+      this._mdf = false;
+      this.prepareRenderableFrame(num);
+      this.prepareProperties(num, this.isInRange);
+      this.checkTransparency();
+    },
+    destroy: function () {
+      this.innerElem = null;
+      this.destroyBaseElement();
+    },
+  };
+  extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement);
+}());
+
+function IImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  if (this.assetData && this.assetData.sid) {
+    this.assetData = globalData.slotManager.getProp(this.assetData);
+  }
+  this.initElement(data, globalData, comp);
+  this.sourceRect = {
+    top: 0, left: 0, width: this.assetData.w, height: this.assetData.h,
+  };
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
+
+IImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+
+  this.innerElem = createNS('image');
+  this.innerElem.setAttribute('width', this.assetData.w + 'px');
+  this.innerElem.setAttribute('height', this.assetData.h + 'px');
+  this.innerElem.setAttribute('preserveAspectRatio', this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio);
+  this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+
+  this.layerElement.appendChild(this.innerElem);
+};
+
+IImageElement.prototype.sourceRectAtTime = function () {
+  return this.sourceRect;
+};
+
+function ProcessedElement(element, position) {
+  this.elem = element;
+  this.pos = position;
+}
+
+function IShapeElement() {
+}
+
+IShapeElement.prototype = {
+  addShapeToModifiers: function (data) {
+    var i;
+    var len = this.shapeModifiers.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapeModifiers[i].addShape(data);
+    }
+  },
+  isShapeInAnimatedModifiers: function (data) {
+    var i = 0;
+    var len = this.shapeModifiers.length;
+    while (i < len) {
+      if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
+        return true;
+      }
+    }
+    return false;
+  },
+  renderModifiers: function () {
+    if (!this.shapeModifiers.length) {
+      return;
+    }
+    var i;
+    var len = this.shapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].sh.reset();
+    }
+
+    len = this.shapeModifiers.length;
+    var shouldBreakProcess;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+      // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+      // TODO: find a better solution for this
+      if (shouldBreakProcess) {
+        break;
+      }
+    }
+  },
+
+  searchProcessedElement: function (elem) {
+    var elements = this.processedElements;
+    var i = 0;
+    var len = elements.length;
+    while (i < len) {
+      if (elements[i].elem === elem) {
+        return elements[i].pos;
+      }
+      i += 1;
+    }
+    return 0;
+  },
+  addProcessedElement: function (elem, pos) {
+    var elements = this.processedElements;
+    var i = elements.length;
+    while (i) {
+      i -= 1;
+      if (elements[i].elem === elem) {
+        elements[i].pos = pos;
+        return;
+      }
+    }
+    elements.push(new ProcessedElement(elem, pos));
+  },
+  prepareFrame: function (num) {
+    this.prepareRenderableFrame(num);
+    this.prepareProperties(num, this.isInRange);
+  },
+};
+
+const lineCapEnum = {
+  1: 'butt',
+  2: 'round',
+  3: 'square',
+};
+
+const lineJoinEnum = {
+  1: 'miter',
+  2: 'round',
+  3: 'bevel',
+};
+
+function SVGShapeData(transformers, level, shape) {
+  this.caches = [];
+  this.styles = [];
+  this.transformers = transformers;
+  this.lStr = '';
+  this.sh = shape;
+  this.lvl = level;
+  // TODO find if there are some cases where _isAnimated can be false.
+  // For now, since shapes add up with other shapes. They have to be calculated every time.
+  // One way of finding out is checking if all styles associated to this shape depend only of this shape
+  this._isAnimated = !!shape.k;
+  // TODO: commenting this for now since all shapes are animated
+  var i = 0;
+  var len = transformers.length;
+  while (i < len) {
+    if (transformers[i].mProps.dynamicProperties.length) {
+      this._isAnimated = true;
+      break;
+    }
+    i += 1;
+  }
+}
+
+SVGShapeData.prototype.setAsAnimated = function () {
+  this._isAnimated = true;
+};
+
+function SVGStyleData(data, level) {
+  this.data = data;
+  this.type = data.ty;
+  this.d = '';
+  this.lvl = level;
+  this._mdf = false;
+  this.closed = data.hd === true;
+  this.pElem = createNS('path');
+  this.msElem = null;
+}
+
+SVGStyleData.prototype.reset = function () {
+  this.d = '';
+  this._mdf = false;
+};
+
+function DashProperty(elem, data, renderer, container) {
+  this.elem = elem;
+  this.frameId = -1;
+  this.dataProps = createSizedArray(data.length);
+  this.renderer = renderer;
+  this.k = false;
+  this.dashStr = '';
+  this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0);
+  this.dashoffset = createTypedArray('float32', 1);
+  this.initDynamicPropertyContainer(container);
+  var i;
+  var len = data.length || 0;
+  var prop;
+  for (i = 0; i < len; i += 1) {
+    prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
+    this.k = prop.k || this.k;
+    this.dataProps[i] = { n: data[i].n, p: prop };
+  }
+  if (!this.k) {
+    this.getValue(true);
+  }
+  this._isAnimated = this.k;
+}
+
+DashProperty.prototype.getValue = function (forceRender) {
+  if (this.elem.globalData.frameId === this.frameId && !forceRender) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+  this._mdf = this._mdf || forceRender;
+  if (this._mdf) {
+    var i = 0;
+    var len = this.dataProps.length;
+    if (this.renderer === 'svg') {
+      this.dashStr = '';
+    }
+    for (i = 0; i < len; i += 1) {
+      if (this.dataProps[i].n !== 'o') {
+        if (this.renderer === 'svg') {
+          this.dashStr += ' ' + this.dataProps[i].p.v;
+        } else {
+          this.dashArray[i] = this.dataProps[i].p.v;
+        }
+      } else {
+        this.dashoffset[0] = this.dataProps[i].p.v;
+      }
+    }
+  }
+};
+extendPrototype([DynamicPropertyContainer], DashProperty);
+
+function SVGStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
+
+function SVGFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
+
+function SVGNoStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
+
+function GradientProperty(elem, data, container) {
+  this.data = data;
+  this.c = createTypedArray('uint8c', data.p * 4);
+  var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p * 4) : data.k.k.length - data.p * 4;
+  this.o = createTypedArray('float32', cLength);
+  this._cmdf = false;
+  this._omdf = false;
+  this._collapsable = this.checkCollapsable();
+  this._hasOpacity = cLength;
+  this.initDynamicPropertyContainer(container);
+  this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this);
+  this.k = this.prop.k;
+  this.getValue(true);
+}
+
+GradientProperty.prototype.comparePoints = function (values, points) {
+  var i = 0;
+  var len = this.o.length / 2;
+  var diff;
+  while (i < len) {
+    diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
+    if (diff > 0.01) {
+      return false;
+    }
+    i += 1;
+  }
+  return true;
+};
+
+GradientProperty.prototype.checkCollapsable = function () {
+  if (this.o.length / 2 !== this.c.length / 4) {
+    return false;
+  }
+  if (this.data.k.k[0].s) {
+    var i = 0;
+    var len = this.data.k.k.length;
+    while (i < len) {
+      if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
+        return false;
+      }
+      i += 1;
+    }
+  } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
+    return false;
+  }
+  return true;
+};
+
+GradientProperty.prototype.getValue = function (forceRender) {
+  this.prop.getValue();
+  this._mdf = false;
+  this._cmdf = false;
+  this._omdf = false;
+  if (this.prop._mdf || forceRender) {
+    var i;
+    var len = this.data.p * 4;
+    var mult;
+    var val;
+    for (i = 0; i < len; i += 1) {
+      mult = i % 4 === 0 ? 100 : 255;
+      val = Math.round(this.prop.v[i] * mult);
+      if (this.c[i] !== val) {
+        this.c[i] = val;
+        this._cmdf = !forceRender;
+      }
+    }
+    if (this.o.length) {
+      len = this.prop.v.length;
+      for (i = this.data.p * 4; i < len; i += 1) {
+        mult = i % 2 === 0 ? 100 : 1;
+        val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
+        if (this.o[i - this.data.p * 4] !== val) {
+          this.o[i - this.data.p * 4] = val;
+          this._omdf = !forceRender;
+        }
+      }
+    }
+    this._mdf = !forceRender;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], GradientProperty);
+
+function SVGGradientFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.initGradientData(elem, data, styleOb);
+}
+
+SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 1, null, this);
+  this.h = PropertyFactory.getProp(elem, data.h || { k: 0 }, 0, 0.01, this);
+  this.a = PropertyFactory.getProp(elem, data.a || { k: 0 }, 0, degToRads, this);
+  this.g = new GradientProperty(elem, data.g, this);
+  this.style = styleOb;
+  this.stops = [];
+  this.setGradientData(styleOb.pElem, data);
+  this.setGradientOpacity(data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+};
+
+SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
+  var gradientId = createElementID();
+  var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+  gfill.setAttribute('id', gradientId);
+  gfill.setAttribute('spreadMethod', 'pad');
+  gfill.setAttribute('gradientUnits', 'userSpaceOnUse');
+  var stops = [];
+  var stop;
+  var j;
+  var jLen;
+  jLen = data.g.p * 4;
+  for (j = 0; j < jLen; j += 4) {
+    stop = createNS('stop');
+    gfill.appendChild(stop);
+    stops.push(stop);
+  }
+  pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
+  this.gf = gfill;
+  this.cst = stops;
+};
+
+SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
+  if (this.g._hasOpacity && !this.g._collapsable) {
+    var stop;
+    var j;
+    var jLen;
+    var mask = createNS('mask');
+    var maskElement = createNS('path');
+    mask.appendChild(maskElement);
+    var opacityId = createElementID();
+    var maskId = createElementID();
+    mask.setAttribute('id', maskId);
+    var opFill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+    opFill.setAttribute('id', opacityId);
+    opFill.setAttribute('spreadMethod', 'pad');
+    opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
+    jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
+    var stops = this.stops;
+    for (j = data.g.p * 4; j < jLen; j += 2) {
+      stop = createNS('stop');
+      stop.setAttribute('stop-color', 'rgb(255,255,255)');
+      opFill.appendChild(stop);
+      stops.push(stop);
+    }
+    maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
+    this.maskId = maskId;
+    styleOb.msElem = maskElement;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
+
+function SVGGradientStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.initGradientData(elem, data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
+
+function ShapeGroupData() {
+  this.it = [];
+  this.prevViewData = [];
+  this.gr = createNS('g');
+}
+
+function SVGTransformData(mProps, op, container) {
+  this.transform = {
+    mProps: mProps,
+    op: op,
+    container: container,
+  };
+  this.elements = [];
+  this._isAnimated = this.transform.mProps.dynamicProperties.length || this.transform.op.effectsSequence.length;
+}
+
+const buildShapeString = function (pathNodes, length, closed, mat) {
+  if (length === 0) {
+    return '';
+  }
+  var _o = pathNodes.o;
+  var _i = pathNodes.i;
+  var _v = pathNodes.v;
+  var i;
+  var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+  for (i = 1; i < length; i += 1) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
+  }
+  if (closed && length) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+    shapeString += 'z';
+  }
+  return shapeString;
+};
+
+const SVGElementsRenderer = (function () {
+  var _identityMatrix = new Matrix();
+  var _matrixHelper = new Matrix();
+
+  var ob = {
+    createRenderFunction: createRenderFunction,
+  };
+
+  function createRenderFunction(data) {
+    switch (data.ty) {
+      case 'fl':
+        return renderFill;
+      case 'gf':
+        return renderGradient;
+      case 'gs':
+        return renderGradientStroke;
+      case 'st':
+        return renderStroke;
+      case 'sh':
+      case 'el':
+      case 'rc':
+      case 'sr':
+        return renderPath;
+      case 'tr':
+        return renderContentTransform;
+      case 'no':
+        return renderNoop;
+      default:
+        return null;
+    }
+  }
+
+  function renderContentTransform(styleData, itemData, isFirstFrame) {
+    if (isFirstFrame || itemData.transform.op._mdf) {
+      itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
+    }
+    if (isFirstFrame || itemData.transform.mProps._mdf) {
+      itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
+    }
+  }
+
+  function renderNoop() {
+
+  }
+
+  function renderPath(styleData, itemData, isFirstFrame) {
+    var j;
+    var jLen;
+    var pathStringTransformed;
+    var redraw;
+    var pathNodes;
+    var l;
+    var lLen = itemData.styles.length;
+    var lvl = itemData.lvl;
+    var paths;
+    var mat;
+    var iterations;
+    var k;
+    for (l = 0; l < lLen; l += 1) {
+      redraw = itemData.sh._mdf || isFirstFrame;
+      if (itemData.styles[l].lvl < lvl) {
+        mat = _matrixHelper.reset();
+        iterations = lvl - itemData.styles[l].lvl;
+        k = itemData.transformers.length - 1;
+        while (!redraw && iterations > 0) {
+          redraw = itemData.transformers[k].mProps._mdf || redraw;
+          iterations -= 1;
+          k -= 1;
+        }
+        if (redraw) {
+          iterations = lvl - itemData.styles[l].lvl;
+          k = itemData.transformers.length - 1;
+          while (iterations > 0) {
+            mat.multiply(itemData.transformers[k].mProps.v);
+            iterations -= 1;
+            k -= 1;
+          }
+        }
+      } else {
+        mat = _identityMatrix;
+      }
+      paths = itemData.sh.paths;
+      jLen = paths._length;
+      if (redraw) {
+        pathStringTransformed = '';
+        for (j = 0; j < jLen; j += 1) {
+          pathNodes = paths.shapes[j];
+          if (pathNodes && pathNodes._length) {
+            pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
+          }
+        }
+        itemData.caches[l] = pathStringTransformed;
+      } else {
+        pathStringTransformed = itemData.caches[l];
+      }
+      itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
+      itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
+    }
+  }
+
+  function renderFill(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+
+    if (itemData.c._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
+    }
+  }
+
+  function renderGradientStroke(styleData, itemData, isFirstFrame) {
+    renderGradient(styleData, itemData, isFirstFrame);
+    renderStroke(styleData, itemData, isFirstFrame);
+  }
+
+  function renderGradient(styleData, itemData, isFirstFrame) {
+    var gfill = itemData.gf;
+    var hasOpacity = itemData.g._hasOpacity;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+
+    if (itemData.o._mdf || isFirstFrame) {
+      var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
+      itemData.style.pElem.setAttribute(attr, itemData.o.v);
+    }
+    if (itemData.s._mdf || isFirstFrame) {
+      var attr1 = styleData.t === 1 ? 'x1' : 'cx';
+      var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
+      gfill.setAttribute(attr1, pt1[0]);
+      gfill.setAttribute(attr2, pt1[1]);
+      if (hasOpacity && !itemData.g._collapsable) {
+        itemData.of.setAttribute(attr1, pt1[0]);
+        itemData.of.setAttribute(attr2, pt1[1]);
+      }
+    }
+    var stops;
+    var i;
+    var len;
+    var stop;
+    if (itemData.g._cmdf || isFirstFrame) {
+      stops = itemData.cst;
+      var cValues = itemData.g.c;
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        stop.setAttribute('offset', cValues[i * 4] + '%');
+        stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
+      }
+    }
+    if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
+      var oValues = itemData.g.o;
+      if (itemData.g._collapsable) {
+        stops = itemData.cst;
+      } else {
+        stops = itemData.ost;
+      }
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        if (!itemData.g._collapsable) {
+          stop.setAttribute('offset', oValues[i * 2] + '%');
+        }
+        stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
+      }
+    }
+    if (styleData.t === 1) {
+      if (itemData.e._mdf || isFirstFrame) {
+        gfill.setAttribute('x2', pt2[0]);
+        gfill.setAttribute('y2', pt2[1]);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('x2', pt2[0]);
+          itemData.of.setAttribute('y2', pt2[1]);
+        }
+      }
+    } else {
+      var rad;
+      if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
+        rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        gfill.setAttribute('r', rad);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('r', rad);
+        }
+      }
+      if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (!rad) {
+          rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        }
+        var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+        var percent = itemData.h.v;
+        if (percent >= 1) {
+          percent = 0.99;
+        } else if (percent <= -1) {
+          percent = -0.99;
+        }
+        var dist = rad * percent;
+        var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+        var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+        gfill.setAttribute('fx', x);
+        gfill.setAttribute('fy', y);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('fx', x);
+          itemData.of.setAttribute('fy', y);
+        }
+      }
+      // gfill.setAttribute('fy','200');
+    }
+  }
+
+  function renderStroke(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+    var d = itemData.d;
+    if (d && (d._mdf || isFirstFrame) && d.dashStr) {
+      styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
+      styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
+    }
+    if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
+      styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
+    }
+    if (itemData.w._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
+      if (styleElem.msElem) {
+        styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
+      }
+    }
+  }
+
+  return ob;
+}());
+
+function SVGShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
+
+SVGShapeElement.prototype.initSecondaryElement = function () {
+};
+
+SVGShapeElement.prototype.identityMatrix = new Matrix();
+
+SVGShapeElement.prototype.buildExpressionInterface = function () {};
+
+SVGShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+};
+
+/*
+This method searches for multiple shapes that affect a single element and one of them is animated
+*/
+SVGShapeElement.prototype.filterUniqueShapes = function () {
+  var i;
+  var len = this.shapes.length;
+  var shape;
+  var j;
+  var jLen = this.stylesList.length;
+  var style;
+  var tempShapes = [];
+  var areAnimated = false;
+  for (j = 0; j < jLen; j += 1) {
+    style = this.stylesList[j];
+    areAnimated = false;
+    tempShapes.length = 0;
+    for (i = 0; i < len; i += 1) {
+      shape = this.shapes[i];
+      if (shape.styles.indexOf(style) !== -1) {
+        tempShapes.push(shape);
+        areAnimated = shape._isAnimated || areAnimated;
+      }
+    }
+    if (tempShapes.length > 1 && areAnimated) {
+      this.setShapesAsAnimated(tempShapes);
+    }
+  }
+};
+
+SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
+  var i;
+  var len = shapes.length;
+  for (i = 0; i < len; i += 1) {
+    shapes[i].setAsAnimated();
+  }
+};
+
+SVGShapeElement.prototype.createStyleElement = function (data, level) {
+  // TODO: prevent drawing of hidden styles
+  var elementData;
+  var styleOb = new SVGStyleData(data, level);
+
+  var pathElement = styleOb.pElem;
+  if (data.ty === 'st') {
+    elementData = new SVGStrokeStyleData(this, data, styleOb);
+  } else if (data.ty === 'fl') {
+    elementData = new SVGFillStyleData(this, data, styleOb);
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
+    elementData = new GradientConstructor(this, data, styleOb);
+    this.globalData.defs.appendChild(elementData.gf);
+    if (elementData.maskId) {
+      this.globalData.defs.appendChild(elementData.ms);
+      this.globalData.defs.appendChild(elementData.of);
+      pathElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + elementData.maskId + ')');
+    }
+  } else if (data.ty === 'no') {
+    elementData = new SVGNoStyleData(this, data, styleOb);
+  }
+
+  if (data.ty === 'st' || data.ty === 'gs') {
+    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);
+    }
+  }
+
+  if (data.r === 2) {
+    pathElement.setAttribute('fill-rule', 'evenodd');
+  }
+
+  if (data.ln) {
+    pathElement.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    pathElement.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  this.stylesList.push(styleOb);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createGroupElement = function (data) {
+  var elementData = new ShapeGroupData();
+  if (data.ln) {
+    elementData.gr.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    elementData.gr.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  return elementData;
+};
+
+SVGShapeElement.prototype.createTransformElement = function (data, container) {
+  var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
+  var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
+  var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
+  var i = 0;
+  var len = this.animatedContents.length;
+  while (i < len) {
+    if (this.animatedContents[i].element === element) {
+      return;
+    }
+    i += 1;
+  }
+  this.animatedContents.push({
+    fn: SVGElementsRenderer.createRenderFunction(data),
+    element: element,
+    data: data,
+  });
+};
+
+SVGShapeElement.prototype.setElementStyles = function (elementData) {
+  var arr = elementData.styles;
+  var j;
+  var jLen = this.stylesList.length;
+  for (j = 0; j < jLen; j += 1) {
+    if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
+      arr.push(this.stylesList[j]);
+    }
+  }
+};
+
+SVGShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+};
+
+SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
+  var ownTransformers = [].concat(transformers);
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var currentTransform;
+  var modifier;
+  var processedPos;
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._render = render;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], level);
+      } else {
+        itemsData[i].style.closed = arr[i].hd;
+      }
+      if (arr[i]._render) {
+        if (itemsData[i].style.pElem.parentNode !== container) {
+          container.appendChild(itemsData[i].style.pElem);
+        }
+      }
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
+      if (arr[i]._render) {
+        if (itemsData[i].gr.parentNode !== container) {
+          container.appendChild(itemsData[i].gr);
+        }
+      }
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        itemsData[i] = this.createTransformElement(arr[i], container);
+      }
+      currentTransform = itemsData[i].transform;
+      ownTransformers.push(currentTransform);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
+      }
+      this.setElementStyles(itemsData[i]);
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        render = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  len = ownStyles.length;
+  for (i = 0; i < len; i += 1) {
+    ownStyles[i].closed = true;
+  }
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+SVGShapeElement.prototype.renderInnerContent = function () {
+  this.renderModifiers();
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    this.stylesList[i].reset();
+  }
+  this.renderShape();
+  for (i = 0; i < len; i += 1) {
+    if (this.stylesList[i]._mdf || this._isFirstFrame) {
+      if (this.stylesList[i].msElem) {
+        this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+        // Adding M0 0 fixes same mask bug on all browsers
+        this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
+      }
+      this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
+    }
+  }
+};
+
+SVGShapeElement.prototype.renderShape = function () {
+  var i;
+  var len = this.animatedContents.length;
+  var animatedContent;
+  for (i = 0; i < len; i += 1) {
+    animatedContent = this.animatedContents[i];
+    if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
+      animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
+    }
+  }
+};
+
+SVGShapeElement.prototype.destroy = function () {
+  this.destroyBaseElement();
+  this.shapesData = null;
+  this.itemsData = null;
+};
+
+function LetterProps(o, sw, sc, fc, m, p) {
+  this.o = o;
+  this.sw = sw;
+  this.sc = sc;
+  this.fc = fc;
+  this.m = m;
+  this.p = p;
+  this._mdf = {
+    o: true,
+    sw: !!sw,
+    sc: !!sc,
+    fc: !!fc,
+    m: true,
+    p: true,
+  };
+}
+
+LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
+  this._mdf.o = false;
+  this._mdf.sw = false;
+  this._mdf.sc = false;
+  this._mdf.fc = false;
+  this._mdf.m = false;
+  this._mdf.p = false;
+  var updated = false;
+
+  if (this.o !== o) {
+    this.o = o;
+    this._mdf.o = true;
+    updated = true;
+  }
+  if (this.sw !== sw) {
+    this.sw = sw;
+    this._mdf.sw = true;
+    updated = true;
+  }
+  if (this.sc !== sc) {
+    this.sc = sc;
+    this._mdf.sc = true;
+    updated = true;
+  }
+  if (this.fc !== fc) {
+    this.fc = fc;
+    this._mdf.fc = true;
+    updated = true;
+  }
+  if (this.m !== m) {
+    this.m = m;
+    this._mdf.m = true;
+    updated = true;
+  }
+  if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
+    this.p = p;
+    this._mdf.p = true;
+    updated = true;
+  }
+  return updated;
+};
+
+function TextProperty(elem, data) {
+  this._frameId = initialDefaultFrame;
+  this.pv = '';
+  this.v = '';
+  this.kf = false;
+  this._isFirstFrame = true;
+  this._mdf = false;
+  if (data.d && data.d.sid) {
+    data.d = elem.globalData.slotManager.getProp(data.d);
+  }
+  this.data = data;
+  this.elem = elem;
+  this.comp = this.elem.comp;
+  this.keysIndex = 0;
+  this.canResize = false;
+  this.minimumFontSize = 1;
+  this.effectsSequence = [];
+  this.currentData = {
+    ascent: 0,
+    boxWidth: this.defaultBoxWidth,
+    f: '',
+    fStyle: '',
+    fWeight: '',
+    fc: '',
+    j: '',
+    justifyOffset: '',
+    l: [],
+    lh: 0,
+    lineWidths: [],
+    ls: '',
+    of: '',
+    s: '',
+    sc: '',
+    sw: 0,
+    t: 0,
+    tr: 0,
+    sz: 0,
+    ps: null,
+    fillColorAnim: false,
+    strokeColorAnim: false,
+    strokeWidthAnim: false,
+    yOffset: 0,
+    finalSize: 0,
+    finalText: [],
+    finalLineHeight: 0,
+    __complete: false,
+
+  };
+  this.copyData(this.currentData, this.data.d.k[0].s);
+
+  if (!this.searchProperty()) {
+    this.completeTextData(this.currentData);
+  }
+}
+
+TextProperty.prototype.defaultBoxWidth = [0, 0];
+
+TextProperty.prototype.copyData = function (obj, data) {
+  for (var s in data) {
+    if (Object.prototype.hasOwnProperty.call(data, s)) {
+      obj[s] = data[s];
+    }
+  }
+  return obj;
+};
+
+TextProperty.prototype.setCurrentData = function (data) {
+  if (!data.__complete) {
+    this.completeTextData(data);
+  }
+  this.currentData = data;
+  this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
+  this._mdf = true;
+};
+
+TextProperty.prototype.searchProperty = function () {
+  return this.searchKeyframes();
+};
+
+TextProperty.prototype.searchKeyframes = function () {
+  this.kf = this.data.d.k.length > 1;
+  if (this.kf) {
+    this.addEffect(this.getKeyframeValue.bind(this));
+  }
+  return this.kf;
+};
+
+TextProperty.prototype.addEffect = function (effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.getValue = function (_finalValue) {
+  if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
+    return;
+  }
+  this.currentData.t = this.data.d.k[this.keysIndex].s.t;
+  var currentValue = this.currentData;
+  var currentIndex = this.keysIndex;
+  if (this.lock) {
+    this.setCurrentData(this.currentData);
+    return;
+  }
+  this.lock = true;
+  this._mdf = false;
+  var i; var
+    len = this.effectsSequence.length;
+  var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
+  for (i = 0; i < len; i += 1) {
+    // Checking if index changed to prevent creating a new object every time the expression updates.
+    if (currentIndex !== this.keysIndex) {
+      finalValue = this.effectsSequence[i](finalValue, finalValue.t);
+    } else {
+      finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
+    }
+  }
+  if (currentValue !== finalValue) {
+    this.setCurrentData(finalValue);
+  }
+  this.v = this.currentData;
+  this.pv = this.v;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+};
+
+TextProperty.prototype.getKeyframeValue = function () {
+  var textKeys = this.data.d.k;
+  var frameNum = this.elem.comp.renderedFrame;
+  var i = 0; var
+    len = textKeys.length;
+  while (i <= len - 1) {
+    if (i === len - 1 || textKeys[i + 1].t > frameNum) {
+      break;
+    }
+    i += 1;
+  }
+  if (this.keysIndex !== i) {
+    this.keysIndex = i;
+  }
+  return this.data.d.k[this.keysIndex].s;
+};
+
+TextProperty.prototype.buildFinalText = function (text) {
+  var charactersArray = [];
+  var i = 0;
+  var len = text.length;
+  var charCode;
+  var secondCharCode;
+  var shouldCombine = false;
+  var shouldCombineNext = false;
+  var currentChars = '';
+  while (i < len) {
+    shouldCombine = shouldCombineNext;
+    shouldCombineNext = false;
+    charCode = text.charCodeAt(i);
+    currentChars = text.charAt(i);
+    if (FontManager.isCombinedCharacter(charCode)) {
+      shouldCombine = true;
+      // It's a potential surrogate pair (this is the High surrogate)
+    } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+      if (FontManager.isRegionalFlag(text, i)) {
+        currentChars = text.substr(i, 14);
+      } else {
+        secondCharCode = text.charCodeAt(i + 1);
+        // It's a surrogate pair (this is the Low surrogate)
+        if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
+          if (FontManager.isModifier(charCode, secondCharCode)) {
+            currentChars = text.substr(i, 2);
+            shouldCombine = true;
+          } else if (FontManager.isFlagEmoji(text.substr(i, 4))) {
+            currentChars = text.substr(i, 4);
+          } else {
+            currentChars = text.substr(i, 2);
+          }
+        }
+      }
+    } else if (charCode > 0xDBFF) {
+      secondCharCode = text.charCodeAt(i + 1);
+      if (FontManager.isVariationSelector(charCode)) {
+        shouldCombine = true;
+      }
+    } else if (FontManager.isZeroWidthJoiner(charCode)) {
+      shouldCombine = true;
+      shouldCombineNext = true;
+    }
+    if (shouldCombine) {
+      charactersArray[charactersArray.length - 1] += currentChars;
+      shouldCombine = false;
+    } else {
+      charactersArray.push(currentChars);
+    }
+    i += currentChars.length;
+  }
+  return charactersArray;
+};
+
+TextProperty.prototype.completeTextData = function (documentData) {
+  documentData.__complete = true;
+  var fontManager = this.elem.globalData.fontManager;
+  var data = this.data;
+  var letters = [];
+  var i; var
+    len;
+  var newLineFlag; var index = 0; var
+    val;
+  var anchorGrouping = data.m.g;
+  var currentSize = 0; var currentPos = 0; var currentLine = 0; var
+    lineWidths = [];
+  var lineWidth = 0;
+  var maxLineWidth = 0;
+  var j; var
+    jLen;
+  var fontData = fontManager.getFontByName(documentData.f);
+  var charData; var
+    cLength = 0;
+
+  var fontProps = getFontProperties(fontData);
+  documentData.fWeight = fontProps.weight;
+  documentData.fStyle = fontProps.style;
+  documentData.finalSize = documentData.s;
+  documentData.finalText = this.buildFinalText(documentData.t);
+  len = documentData.finalText.length;
+  documentData.finalLineHeight = documentData.lh;
+  var trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+  var charCode;
+  if (documentData.sz) {
+    var flag = true;
+    var boxWidth = documentData.sz[0];
+    var boxHeight = documentData.sz[1];
+    var currentHeight; var
+      finalText;
+    while (flag) {
+      finalText = this.buildFinalText(documentData.t);
+      currentHeight = 0;
+      lineWidth = 0;
+      len = finalText.length;
+      trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+      var lastSpaceIndex = -1;
+      for (i = 0; i < len; i += 1) {
+        charCode = finalText[i].charCodeAt(0);
+        newLineFlag = false;
+        if (finalText[i] === ' ') {
+          lastSpaceIndex = i;
+        } else if (charCode === 13 || charCode === 3) {
+          lineWidth = 0;
+          newLineFlag = true;
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+        }
+        if (fontManager.chars) {
+          charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
+          cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+        } else {
+          // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
+          cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
+        }
+        if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
+          if (lastSpaceIndex === -1) {
+            len += 1;
+          } else {
+            i = lastSpaceIndex;
+          }
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+          finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+          // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
+          lastSpaceIndex = -1;
+          lineWidth = 0;
+        } else {
+          lineWidth += cLength;
+          lineWidth += trackingOffset;
+        }
+      }
+      currentHeight += (fontData.ascent * documentData.finalSize) / 100;
+      if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
+        documentData.finalSize -= 1;
+        documentData.finalLineHeight = (documentData.finalSize * documentData.lh) / documentData.s;
+      } else {
+        documentData.finalText = finalText;
+        len = documentData.finalText.length;
+        flag = false;
+      }
+    }
+  }
+  lineWidth = -trackingOffset;
+  cLength = 0;
+  var uncollapsedSpaces = 0;
+  var currentChar;
+  for (i = 0; i < len; i += 1) {
+    newLineFlag = false;
+    currentChar = documentData.finalText[i];
+    charCode = currentChar.charCodeAt(0);
+    if (charCode === 13 || charCode === 3) {
+      uncollapsedSpaces = 0;
+      lineWidths.push(lineWidth);
+      maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+      lineWidth = -2 * trackingOffset;
+      val = '';
+      newLineFlag = true;
+      currentLine += 1;
+    } else {
+      val = currentChar;
+    }
+    if (fontManager.chars) {
+      charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
+      cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+    } else {
+      // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
+      // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
+      cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
+    }
+
+    //
+    if (currentChar === ' ') {
+      uncollapsedSpaces += cLength + trackingOffset;
+    } else {
+      lineWidth += cLength + trackingOffset + uncollapsedSpaces;
+      uncollapsedSpaces = 0;
+    }
+    letters.push({
+      l: cLength, an: cLength, add: currentSize, n: newLineFlag, anIndexes: [], val: val, line: currentLine, animatorJustifyOffset: 0,
+    });
+    if (anchorGrouping == 2) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || val === ' ' || i === len - 1) {
+        if (val === '' || val === ' ') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        index += 1;
+        currentSize = 0;
+      }
+    } else if (anchorGrouping == 3) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || i === len - 1) {
+        if (val === '') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        currentSize = 0;
+        index += 1;
+      }
+    } else {
+      letters[index].ind = index;
+      letters[index].extra = 0;
+      index += 1;
+    }
+  }
+  documentData.l = letters;
+  maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+  lineWidths.push(lineWidth);
+  if (documentData.sz) {
+    documentData.boxWidth = documentData.sz[0];
+    documentData.justifyOffset = 0;
+  } else {
+    documentData.boxWidth = maxLineWidth;
+    switch (documentData.j) {
+      case 1:
+        documentData.justifyOffset = -documentData.boxWidth;
+        break;
+      case 2:
+        documentData.justifyOffset = -documentData.boxWidth / 2;
+        break;
+      default:
+        documentData.justifyOffset = 0;
+    }
+  }
+  documentData.lineWidths = lineWidths;
+
+  var animators = data.a; var animatorData; var
+    letterData;
+  jLen = animators.length;
+  var based; var ind; var
+    indexes = [];
+  for (j = 0; j < jLen; j += 1) {
+    animatorData = animators[j];
+    if (animatorData.a.sc) {
+      documentData.strokeColorAnim = true;
+    }
+    if (animatorData.a.sw) {
+      documentData.strokeWidthAnim = true;
+    }
+    if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
+      documentData.fillColorAnim = true;
+    }
+    ind = 0;
+    based = animatorData.s.b;
+    for (i = 0; i < len; i += 1) {
+      letterData = letters[i];
+      letterData.anIndexes[j] = ind;
+      if ((based == 1 && letterData.val !== '') || (based == 2 && letterData.val !== '' && letterData.val !== ' ') || (based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1)) || (based == 4 && (letterData.n || i == len - 1))) { // eslint-disable-line eqeqeq
+        if (animatorData.s.rn === 1) {
+          indexes.push(ind);
+        }
+        ind += 1;
+      }
+    }
+    data.a[j].s.totalChars = ind;
+    var currentInd = -1; var
+      newInd;
+    if (animatorData.s.rn === 1) {
+      for (i = 0; i < len; i += 1) {
+        letterData = letters[i];
+        if (currentInd != letterData.anIndexes[j]) { // eslint-disable-line eqeqeq
+          currentInd = letterData.anIndexes[j];
+          newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
+        }
+        letterData.anIndexes[j] = newInd;
+      }
+    }
+  }
+  documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
+  documentData.ls = documentData.ls || 0;
+  documentData.ascent = (fontData.ascent * documentData.finalSize) / 100;
+};
+
+TextProperty.prototype.updateDocumentData = function (newData, index) {
+  index = index === undefined ? this.keysIndex : index;
+  var dData = this.copyData({}, this.data.d.k[index].s);
+  dData = this.copyData(dData, newData);
+  this.data.d.k[index].s = dData;
+  this.recalculate(index);
+  this.setCurrentData(dData);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.recalculate = function (index) {
+  var dData = this.data.d.k[index].s;
+  dData.__complete = false;
+  this.keysIndex = 0;
+  this._isFirstFrame = true;
+  this.getValue(dData);
+};
+
+TextProperty.prototype.canResizeFont = function (_canResize) {
+  this.canResize = _canResize;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
+  this.minimumFontSize = Math.floor(_fontValue) || 1;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+const TextSelectorProp = (function () {
+  var max = Math.max;
+  var min = Math.min;
+  var floor = Math.floor;
+
+  function TextSelectorPropFactory(elem, data) {
+    this._currentTextLength = -1;
+    this.k = false;
+    this.data = data;
+    this.elem = elem;
+    this.comp = elem.comp;
+    this.finalS = 0;
+    this.finalE = 0;
+    this.initDynamicPropertyContainer(elem);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: 0 }, 0, 0, this);
+    if ('e' in data) {
+      this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
+    } else {
+      this.e = { v: 100 };
+    }
+    this.o = PropertyFactory.getProp(elem, data.o || { k: 0 }, 0, 0, this);
+    this.xe = PropertyFactory.getProp(elem, data.xe || { k: 0 }, 0, 0, this);
+    this.ne = PropertyFactory.getProp(elem, data.ne || { k: 0 }, 0, 0, this);
+    this.sm = PropertyFactory.getProp(elem, data.sm || { k: 100 }, 0, 0, this);
+    this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
+    if (!this.dynamicProperties.length) {
+      this.getValue();
+    }
+  }
+
+  TextSelectorPropFactory.prototype = {
+    getMult: function (ind) {
+      if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
+        this.getValue();
+      }
+      var x1 = 0;
+      var y1 = 0;
+      var x2 = 1;
+      var y2 = 1;
+      if (this.ne.v > 0) {
+        x1 = this.ne.v / 100.0;
+      } else {
+        y1 = -this.ne.v / 100.0;
+      }
+      if (this.xe.v > 0) {
+        x2 = 1.0 - this.xe.v / 100.0;
+      } else {
+        y2 = 1.0 + this.xe.v / 100.0;
+      }
+      var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
+
+      var mult = 0;
+      var s = this.finalS;
+      var e = this.finalE;
+      var type = this.data.sh;
+      if (type === 2) {
+        if (e === s) {
+          mult = ind >= e ? 1 : 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+        mult = easer(mult);
+      } else if (type === 3) {
+        if (e === s) {
+          mult = ind >= e ? 0 : 1;
+        } else {
+          mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+
+        mult = easer(mult);
+      } else if (type === 4) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+          if (mult < 0.5) {
+            mult *= 2;
+          } else {
+            mult = 1 - 2 * (mult - 0.5);
+          }
+        }
+        mult = easer(mult);
+      } else if (type === 5) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          var tot = e - s;
+          /* ind += 0.5;
+                    mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          var x = -tot / 2 + ind;
+          var a = tot / 2;
+          mult = Math.sqrt(1 - (x * x) / (a * a));
+        }
+        mult = easer(mult);
+      } else if (type === 6) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; // eslint-disable-line
+        }
+        mult = easer(mult);
+      } else {
+        if (ind >= floor(s)) {
+          if (ind - s < 0) {
+            mult = max(0, min(min(e, 1) - (s - ind), 1));
+          } else {
+            mult = max(0, min(e - ind, 1));
+          }
+        }
+        mult = easer(mult);
+      }
+      // Smoothness implementation.
+      // The smoothness represents a reduced range of the original [0; 1] range.
+      // if smoothness is 25%, the new range will be [0.375; 0.625]
+      // Steps are:
+      // - find the lower value of the new range (threshold)
+      // - if multiplier is smaller than that value, floor it to 0
+      // - if it is larger,
+      //     - subtract the threshold
+      //     - divide it by the smoothness (this will return the range to [0; 1])
+      // Note: If it doesn't work on some scenarios, consider applying it before the easer.
+      if (this.sm.v !== 100) {
+        var smoothness = this.sm.v * 0.01;
+        if (smoothness === 0) {
+          smoothness = 0.00000001;
+        }
+        var threshold = 0.5 - smoothness * 0.5;
+        if (mult < threshold) {
+          mult = 0;
+        } else {
+          mult = (mult - threshold) / smoothness;
+          if (mult > 1) {
+            mult = 1;
+          }
+        }
+      }
+      return mult * this.a.v;
+    },
+    getValue: function (newCharsFlag) {
+      this.iterateDynamicProperties();
+      this._mdf = newCharsFlag || this._mdf;
+      this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
+      if (newCharsFlag && this.data.r === 2) {
+        this.e.v = this._currentTextLength;
+      }
+      var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
+      var o = this.o.v / divisor;
+      var s = this.s.v / divisor + o;
+      var e = (this.e.v / divisor) + o;
+      if (s > e) {
+        var _s = s;
+        s = e;
+        e = _s;
+      }
+      this.finalS = s;
+      this.finalE = e;
+    },
+  };
+  extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
+
+  function getTextSelectorProp(elem, data, arr) {
+    return new TextSelectorPropFactory(elem, data, arr);
+  }
+
+  return {
+    getTextSelectorProp: getTextSelectorProp,
+  };
+}());
+
+function TextAnimatorDataProperty(elem, animatorProps, container) {
+  var defaultData = { propType: false };
+  var getProp = PropertyFactory.getProp;
+  var textAnimatorAnimatables = animatorProps.a;
+  this.a = {
+    r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData,
+    rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData,
+    ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData,
+    sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData,
+    sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData,
+    s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData,
+    a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData,
+    o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData,
+    p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData,
+    sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData,
+    sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData,
+    fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData,
+    fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData,
+    fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData,
+    fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData,
+    t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData,
+  };
+
+  this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container);
+  this.s.t = animatorProps.s.t;
+}
+
+function TextAnimatorProperty(textData, renderType, elem) {
+  this._isFirstFrame = true;
+  this._hasMaskedPath = false;
+  this._frameId = -1;
+  this._textData = textData;
+  this._renderType = renderType;
+  this._elem = elem;
+  this._animatorsData = createSizedArray(this._textData.a.length);
+  this._pathData = {};
+  this._moreOptions = {
+    alignment: {},
+  };
+  this.renderedLetters = [];
+  this.lettersChangedFlag = false;
+  this.initDynamicPropertyContainer(elem);
+}
+
+TextAnimatorProperty.prototype.searchProperties = function () {
+  var i;
+  var len = this._textData.a.length;
+  var animatorProps;
+  var getProp = PropertyFactory.getProp;
+  for (i = 0; i < len; i += 1) {
+    animatorProps = this._textData.a[i];
+    this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
+  }
+  if (this._textData.p && 'm' in this._textData.p) {
+    this._pathData = {
+      a: getProp(this._elem, this._textData.p.a, 0, 0, this),
+      f: getProp(this._elem, this._textData.p.f, 0, 0, this),
+      l: getProp(this._elem, this._textData.p.l, 0, 0, this),
+      r: getProp(this._elem, this._textData.p.r, 0, 0, this),
+      p: getProp(this._elem, this._textData.p.p, 0, 0, this),
+      m: this._elem.maskManager.getMaskProperty(this._textData.p.m),
+    };
+    this._hasMaskedPath = true;
+  } else {
+    this._hasMaskedPath = false;
+  }
+  this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
+};
+
+TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
+  this.lettersChangedFlag = lettersChangedFlag;
+  if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
+    return;
+  }
+  this._isFirstFrame = false;
+  var alignment = this._moreOptions.alignment.v;
+  var animators = this._animatorsData;
+  var textData = this._textData;
+  var matrixHelper = this.mHelper;
+  var renderType = this._renderType;
+  var renderedLettersCount = this.renderedLetters.length;
+  var xPos;
+  var yPos;
+  var i;
+  var len;
+  var letters = documentData.l;
+  var pathInfo;
+  var currentLength;
+  var currentPoint;
+  var segmentLength;
+  var flag;
+  var pointInd;
+  var segmentInd;
+  var prevPoint;
+  var points;
+  var segments;
+  var partialLength;
+  var totalLength;
+  var perc;
+  var tanAngle;
+  var mask;
+  if (this._hasMaskedPath) {
+    mask = this._pathData.m;
+    if (!this._pathData.n || this._pathData._mdf) {
+      var paths = mask.v;
+      if (this._pathData.r.v) {
+        paths = paths.reverse();
+      }
+      // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
+      pathInfo = {
+        tLength: 0,
+        segments: [],
+      };
+      len = paths._length - 1;
+      var bezierData;
+      totalLength = 0;
+      for (i = 0; i < len; i += 1) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[i + 1],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      i = len;
+      if (mask.v.c) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[0],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      this._pathData.pi = pathInfo;
+    }
+    pathInfo = this._pathData.pi;
+
+    currentLength = this._pathData.f.v;
+    segmentInd = 0;
+    pointInd = 1;
+    segmentLength = 0;
+    flag = true;
+    segments = pathInfo.segments;
+    if (currentLength < 0 && mask.v.c) {
+      if (pathInfo.tLength < Math.abs(currentLength)) {
+        currentLength = -Math.abs(currentLength) % pathInfo.tLength;
+      }
+      segmentInd = segments.length - 1;
+      points = segments[segmentInd].points;
+      pointInd = points.length - 1;
+      while (currentLength < 0) {
+        currentLength += points[pointInd].partialLength;
+        pointInd -= 1;
+        if (pointInd < 0) {
+          segmentInd -= 1;
+          points = segments[segmentInd].points;
+          pointInd = points.length - 1;
+        }
+      }
+    }
+    points = segments[segmentInd].points;
+    prevPoint = points[pointInd - 1];
+    currentPoint = points[pointInd];
+    partialLength = currentPoint.partialLength;
+  }
+
+  len = letters.length;
+  xPos = 0;
+  yPos = 0;
+  var yOff = documentData.finalSize * 1.2 * 0.714;
+  var firstLine = true;
+  var animatorProps;
+  var animatorSelector;
+  var j;
+  var jLen;
+  var letterValue;
+
+  jLen = animators.length;
+
+  var mult;
+  var ind = -1;
+  var offf;
+  var xPathPos;
+  var yPathPos;
+  var initPathPos = currentLength;
+  var initSegmentInd = segmentInd;
+  var initPointInd = pointInd;
+  var currentLine = -1;
+  var elemOpacity;
+  var sc;
+  var sw;
+  var fc;
+  var k;
+  var letterSw;
+  var letterSc;
+  var letterFc;
+  var letterM = '';
+  var letterP = this.defaultPropsArray;
+  var letterO;
+
+  //
+  if (documentData.j === 2 || documentData.j === 1) {
+    var animatorJustifyOffset = 0;
+    var animatorFirstCharOffset = 0;
+    var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
+    var lastIndex = 0;
+    var isNewLine = true;
+
+    for (i = 0; i < len; i += 1) {
+      if (letters[i].n) {
+        if (animatorJustifyOffset) {
+          animatorJustifyOffset += animatorFirstCharOffset;
+        }
+        while (lastIndex < i) {
+          letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+          lastIndex += 1;
+        }
+        animatorJustifyOffset = 0;
+        isNewLine = true;
+      } else {
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.t.propType) {
+            if (isNewLine && documentData.j === 2) {
+              animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
+            }
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
+            } else {
+              animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult;
+            }
+          }
+        }
+        isNewLine = false;
+      }
+    }
+    if (animatorJustifyOffset) {
+      animatorJustifyOffset += animatorFirstCharOffset;
+    }
+    while (lastIndex < i) {
+      letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+      lastIndex += 1;
+    }
+  }
+  //
+
+  for (i = 0; i < len; i += 1) {
+    matrixHelper.reset();
+    elemOpacity = 1;
+    if (letters[i].n) {
+      xPos = 0;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      currentLength = initPathPos;
+      firstLine = false;
+      if (this._hasMaskedPath) {
+        segmentInd = initSegmentInd;
+        pointInd = initPointInd;
+        points = segments[segmentInd].points;
+        prevPoint = points[pointInd - 1];
+        currentPoint = points[pointInd];
+        partialLength = currentPoint.partialLength;
+        segmentLength = 0;
+      }
+      letterM = '';
+      letterFc = '';
+      letterSw = '';
+      letterO = '';
+      letterP = this.defaultPropsArray;
+    } else {
+      if (this._hasMaskedPath) {
+        if (currentLine !== letters[i].line) {
+          switch (documentData.j) {
+            case 1:
+              currentLength += totalLength - documentData.lineWidths[letters[i].line];
+              break;
+            case 2:
+              currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
+              break;
+            default:
+              break;
+          }
+          currentLine = letters[i].line;
+        }
+        if (ind !== letters[i].ind) {
+          if (letters[ind]) {
+            currentLength += letters[ind].extra;
+          }
+          currentLength += letters[i].an / 2;
+          ind = letters[i].ind;
+        }
+        currentLength += (alignment[0] * letters[i].an) * 0.005;
+        var animatorOffset = 0;
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.p.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.p.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.p.v[0] * mult;
+            }
+          }
+          if (animatorProps.a.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.a.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.a.v[0] * mult;
+            }
+          }
+        }
+        flag = true;
+        // Force alignment only works with a single line for now
+        if (this._pathData.a.v) {
+          currentLength = letters[0].an * 0.5 + ((totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind) / (len - 1);
+          currentLength += this._pathData.f.v;
+        }
+        while (flag) {
+          if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
+            perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
+            xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
+            yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
+            matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, -(alignment[1] * yOff) * 0.01);
+            flag = false;
+          } else if (points) {
+            segmentLength += currentPoint.partialLength;
+            pointInd += 1;
+            if (pointInd >= points.length) {
+              pointInd = 0;
+              segmentInd += 1;
+              if (!segments[segmentInd]) {
+                if (mask.v.c) {
+                  pointInd = 0;
+                  segmentInd = 0;
+                  points = segments[segmentInd].points;
+                } else {
+                  segmentLength -= currentPoint.partialLength;
+                  points = null;
+                }
+              } else {
+                points = segments[segmentInd].points;
+              }
+            }
+            if (points) {
+              prevPoint = currentPoint;
+              currentPoint = points[pointInd];
+              partialLength = currentPoint.partialLength;
+            }
+          }
+        }
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+      } else {
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+
+        // Grouping alignment
+        matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, (-alignment[1] * yOff) * 0.01, 0);
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.t.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
+          if (xPos !== 0 || documentData.j !== 0) {
+            if (this._hasMaskedPath) {
+              if (mult.length) {
+                currentLength += animatorProps.t.v * mult[0];
+              } else {
+                currentLength += animatorProps.t.v * mult;
+              }
+            } else if (mult.length) {
+              xPos += animatorProps.t.v * mult[0];
+            } else {
+              xPos += animatorProps.t.v * mult;
+            }
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        sw = documentData.sw || 0;
+      }
+      if (documentData.strokeColorAnim) {
+        if (documentData.sc) {
+          sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
+        } else {
+          sc = [0, 0, 0];
+        }
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.a.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+
+          if (mult.length) {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.s.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (mult.length) {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult[0]), 1 + ((animatorProps.s.v[1] - 1) * mult[1]), 1);
+          } else {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult), 1 + ((animatorProps.s.v[1] - 1) * mult), 1);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        animatorSelector = animators[j].s;
+        mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+        if (animatorProps.sk.propType) {
+          if (mult.length) {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
+          } else {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
+          }
+        }
+        if (animatorProps.r.propType) {
+          if (mult.length) {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
+          } else {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult);
+          }
+        }
+        if (animatorProps.ry.propType) {
+          if (mult.length) {
+            matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
+          } else {
+            matrixHelper.rotateY(animatorProps.ry.v * mult);
+          }
+        }
+        if (animatorProps.rx.propType) {
+          if (mult.length) {
+            matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
+          } else {
+            matrixHelper.rotateX(animatorProps.rx.v * mult);
+          }
+        }
+        if (animatorProps.o.propType) {
+          if (mult.length) {
+            elemOpacity += ((animatorProps.o.v) * mult[0] - elemOpacity) * mult[0];
+          } else {
+            elemOpacity += ((animatorProps.o.v) * mult - elemOpacity) * mult;
+          }
+        }
+        if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
+          if (mult.length) {
+            sw += animatorProps.sw.v * mult[0];
+          } else {
+            sw += animatorProps.sw.v * mult;
+          }
+        }
+        if (documentData.strokeColorAnim && animatorProps.sc.propType) {
+          for (k = 0; k < 3; k += 1) {
+            if (mult.length) {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0];
+            } else {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult;
+            }
+          }
+        }
+        if (documentData.fillColorAnim && documentData.fc) {
+          if (animatorProps.fc.propType) {
+            for (k = 0; k < 3; k += 1) {
+              if (mult.length) {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0];
+              } else {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult;
+              }
+            }
+          }
+          if (animatorProps.fh.propType) {
+            if (mult.length) {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
+            } else {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult);
+            }
+          }
+          if (animatorProps.fs.propType) {
+            if (mult.length) {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
+            } else {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
+            }
+          }
+          if (animatorProps.fb.propType) {
+            if (mult.length) {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
+            } else {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult);
+            }
+          }
+        }
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+
+        if (animatorProps.p.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (this._hasMaskedPath) {
+            if (mult.length) {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
+            } else {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+            }
+          } else if (mult.length) {
+            matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        letterSw = sw < 0 ? 0 : sw;
+      }
+      if (documentData.strokeColorAnim) {
+        letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
+      }
+
+      if (this._hasMaskedPath) {
+        matrixHelper.translate(0, -documentData.ls);
+
+        matrixHelper.translate(0, (alignment[1] * yOff) * 0.01 + yPos, 0);
+        if (this._pathData.p.v) {
+          tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
+          var rot = (Math.atan(tanAngle) * 180) / Math.PI;
+          if (currentPoint.point[0] < prevPoint.point[0]) {
+            rot += 180;
+          }
+          matrixHelper.rotate((-rot * Math.PI) / 180);
+        }
+        matrixHelper.translate(xPathPos, yPathPos, 0);
+        currentLength -= (alignment[0] * letters[i].an) * 0.005;
+        if (letters[i + 1] && ind !== letters[i + 1].ind) {
+          currentLength += letters[i].an / 2;
+          currentLength += (documentData.tr * 0.001) * documentData.finalSize;
+        }
+      } else {
+        matrixHelper.translate(xPos, yPos, 0);
+
+        if (documentData.ps) {
+          // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
+          matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+        }
+        switch (documentData.j) {
+          case 1:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
+            break;
+          case 2:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
+            break;
+          default:
+            break;
+        }
+        matrixHelper.translate(0, -documentData.ls);
+        matrixHelper.translate(offf, 0, 0);
+        matrixHelper.translate((alignment[0] * letters[i].an) * 0.005, (alignment[1] * yOff) * 0.01, 0);
+        xPos += letters[i].l + (documentData.tr * 0.001) * documentData.finalSize;
+      }
+      if (renderType === 'html') {
+        letterM = matrixHelper.toCSS();
+      } else if (renderType === 'svg') {
+        letterM = matrixHelper.to2dCSS();
+      } else {
+        letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
+      }
+      letterO = elemOpacity;
+    }
+
+    if (renderedLettersCount <= i) {
+      letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
+      this.renderedLetters.push(letterValue);
+      renderedLettersCount += 1;
+      this.lettersChangedFlag = true;
+    } else {
+      letterValue = this.renderedLetters[i];
+      this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag;
+    }
+  }
+};
+
+TextAnimatorProperty.prototype.getValue = function () {
+  if (this._elem.globalData.frameId === this._frameId) {
+    return;
+  }
+  this._frameId = this._elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+TextAnimatorProperty.prototype.mHelper = new Matrix();
+TextAnimatorProperty.prototype.defaultPropsArray = [];
+extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
+
+function ITextElement() {
+}
+
+ITextElement.prototype.initElement = function (data, globalData, comp) {
+  this.lettersChangedFlag = true;
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.textProperty = new TextProperty(this, data.t, this.dynamicProperties);
+  this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this);
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+  this.initRenderable();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  this.createContent();
+  this.hide();
+  this.textAnimator.searchProperties(this.dynamicProperties);
+};
+
+ITextElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+};
+
+ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
+  var j;
+  var jLen = shapes.length;
+  var pathNodes;
+  var shapeStr = '';
+  for (j = 0; j < jLen; j += 1) {
+    if (shapes[j].ty === 'sh') {
+      pathNodes = shapes[j].ks.k;
+      shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
+    }
+  }
+  return shapeStr;
+};
+
+ITextElement.prototype.updateDocumentData = function (newData, index) {
+  this.textProperty.updateDocumentData(newData, index);
+};
+
+ITextElement.prototype.canResizeFont = function (_canResize) {
+  this.textProperty.canResizeFont(_canResize);
+};
+
+ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
+  this.textProperty.setMinimumFontSize(_fontSize);
+};
+
+ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
+  if (documentData.ps) {
+    matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+  }
+  matrixHelper.translate(0, -documentData.ls, 0);
+  switch (documentData.j) {
+    case 1:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
+      break;
+    case 2:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
+      break;
+    default:
+      break;
+  }
+  matrixHelper.translate(xPos, yPos, 0);
+};
+
+ITextElement.prototype.buildColor = function (colorData) {
+  return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
+};
+
+ITextElement.prototype.emptyProp = new LetterProps();
+
+ITextElement.prototype.destroy = function () {
+
+};
+
+ITextElement.prototype.validateText = function () {
+  if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
+    this.buildNewText();
+    this.textProperty._isFirstFrame = false;
+    this.textProperty._mdf = false;
+  }
+};
+
+var emptyShapeData = {
+  shapes: [],
+};
+
+function SVGTextLottieElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.renderType = 'svg';
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
+
+SVGTextLottieElement.prototype.createContent = function () {
+  if (this.data.singleShape && !this.globalData.fontManager.chars) {
+    this.textContainer = createNS('text');
+  }
+};
+
+SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
+  var i = 0;
+  var len = textArray.length;
+  var textContents = [];
+  var currentTextContent = '';
+  while (i < len) {
+    if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
+      textContents.push(currentTextContent);
+      currentTextContent = '';
+    } else {
+      currentTextContent += textArray[i];
+    }
+    i += 1;
+  }
+  textContents.push(currentTextContent);
+  return textContents;
+};
+
+SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
+  // data should probably be cloned to apply scale separately to each instance of a text on different layers
+  // but since text internal content gets only rendered once and then it's never rerendered,
+  // it's probably safe not to clone data and reuse always the same instance even if the object is mutated.
+  // Avoiding cloning is preferred since cloning each character shape data is expensive
+  if (data.shapes && data.shapes.length) {
+    var shape = data.shapes[0];
+    if (shape.it) {
+      var shapeItem = shape.it[shape.it.length - 1];
+      if (shapeItem.s) {
+        shapeItem.s.k[0] = scale;
+        shapeItem.s.k[1] = scale;
+      }
+    }
+  }
+  return data;
+};
+
+SVGTextLottieElement.prototype.buildNewText = function () {
+  this.addDynamicProperty(this);
+  var i;
+  var len;
+
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
+  if (documentData.fc) {
+    this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
+  } else {
+    this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
+  }
+  if (documentData.sc) {
+    this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
+    this.layerElement.setAttribute('stroke-width', documentData.sw);
+  }
+  this.layerElement.setAttribute('font-size', documentData.finalSize);
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (fontData.fClass) {
+    this.layerElement.setAttribute('class', fontData.fClass);
+  } else {
+    this.layerElement.setAttribute('font-family', fontData.fFamily);
+    var fWeight = documentData.fWeight;
+    var fStyle = documentData.fStyle;
+    this.layerElement.setAttribute('font-style', fStyle);
+    this.layerElement.setAttribute('font-weight', fWeight);
+  }
+  this.layerElement.setAttribute('aria-label', documentData.t);
+
+  var letters = documentData.l || [];
+  var usesGlyphs = !!this.globalData.fontManager.chars;
+  len = letters.length;
+
+  var tSpan;
+  var matrixHelper = this.mHelper;
+  var shapeStr = '';
+  var singleShape = this.data.singleShape;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  if (singleShape && !usesGlyphs && !documentData.sz) {
+    var tElement = this.textContainer;
+    var justify = 'start';
+    switch (documentData.j) {
+      case 1:
+        justify = 'end';
+        break;
+      case 2:
+        justify = 'middle';
+        break;
+      default:
+        justify = 'start';
+        break;
+    }
+    tElement.setAttribute('text-anchor', justify);
+    tElement.setAttribute('letter-spacing', trackingOffset);
+    var textContent = this.buildTextContents(documentData.finalText);
+    len = textContent.length;
+    yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
+    for (i = 0; i < len; i += 1) {
+      tSpan = this.textSpans[i].span || createNS('tspan');
+      tSpan.textContent = textContent[i];
+      tSpan.setAttribute('x', 0);
+      tSpan.setAttribute('y', yPos);
+      tSpan.style.display = 'inherit';
+      tElement.appendChild(tSpan);
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          glyph: null,
+        };
+      }
+      this.textSpans[i].span = tSpan;
+      yPos += documentData.finalLineHeight;
+    }
+
+    this.layerElement.appendChild(tElement);
+  } else {
+    var cachedSpansLength = this.textSpans.length;
+    var charData;
+    for (i = 0; i < len; i += 1) {
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          childSpan: null,
+          glyph: null,
+        };
+      }
+      if (!usesGlyphs || !singleShape || i === 0) {
+        tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
+        if (cachedSpansLength <= i) {
+          tSpan.setAttribute('stroke-linecap', 'butt');
+          tSpan.setAttribute('stroke-linejoin', 'round');
+          tSpan.setAttribute('stroke-miterlimit', '4');
+          this.textSpans[i].span = tSpan;
+          if (usesGlyphs) {
+            var childSpan = createNS('g');
+            tSpan.appendChild(childSpan);
+            this.textSpans[i].childSpan = childSpan;
+          }
+          this.textSpans[i].span = tSpan;
+          this.layerElement.appendChild(tSpan);
+        }
+        tSpan.style.display = 'inherit';
+      }
+
+      matrixHelper.reset();
+      if (singleShape) {
+        if (letters[i].n) {
+          xPos = -trackingOffset;
+          yPos += documentData.yOffset;
+          yPos += firstLine ? 1 : 0;
+          firstLine = false;
+        }
+        this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+        xPos += letters[i].l || 0;
+        // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
+        xPos += trackingOffset;
+      }
+      if (usesGlyphs) {
+        charData = this.globalData.fontManager.getCharData(
+          documentData.finalText[i],
+          fontData.fStyle,
+          this.globalData.fontManager.getFontByName(documentData.f).fFamily
+        );
+        var glyphElement;
+        // t === 1 means the character has been replaced with an animated shaped
+        if (charData.t === 1) {
+          glyphElement = new SVGCompElement(charData.data, this.globalData, this);
+        } else {
+          var data = emptyShapeData;
+          if (charData.data && charData.data.shapes) {
+            data = this.buildShapeData(charData.data, documentData.finalSize);
+          }
+          glyphElement = new SVGShapeElement(data, this.globalData, this);
+        }
+        if (this.textSpans[i].glyph) {
+          var glyph = this.textSpans[i].glyph;
+          this.textSpans[i].childSpan.removeChild(glyph.layerElement);
+          glyph.destroy();
+        }
+        this.textSpans[i].glyph = glyphElement;
+        glyphElement._debug = true;
+        glyphElement.prepareFrame(0);
+        glyphElement.renderFrame();
+        this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+        // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+        // this might have issues with strokes and might need a different solution
+        if (charData.t === 1) {
+          this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
+        }
+      } else {
+        if (singleShape) {
+          tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
+        }
+        tSpan.textContent = letters[i].val;
+        tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      }
+      //
+    }
+    if (singleShape && tSpan) {
+      tSpan.setAttribute('d', shapeStr);
+    }
+  }
+  while (i < this.textSpans.length) {
+    this.textSpans[i].span.style.display = 'none';
+    i += 1;
+  }
+
+  this._sizeChanged = true;
+};
+
+SVGTextLottieElement.prototype.sourceRectAtTime = function () {
+  this.prepareFrame(this.comp.renderedFrame - this.data.st);
+  this.renderInnerContent();
+  if (this._sizeChanged) {
+    this._sizeChanged = false;
+    var textBox = this.layerElement.getBBox();
+    this.bbox = {
+      top: textBox.y,
+      left: textBox.x,
+      width: textBox.width,
+      height: textBox.height,
+    };
+  }
+  return this.bbox;
+};
+
+SVGTextLottieElement.prototype.getValue = function () {
+  var i;
+  var len = this.textSpans.length;
+  var glyphElement;
+  this.renderedFrame = this.comp.renderedFrame;
+  for (i = 0; i < len; i += 1) {
+    glyphElement = this.textSpans[i].glyph;
+    if (glyphElement) {
+      glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
+      if (glyphElement._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+SVGTextLottieElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  if (!this.data.singleShape || this._mdf) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+    if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
+      this._sizeChanged = true;
+      var i;
+      var len;
+      var renderedLetters = this.textAnimator.renderedLetters;
+
+      var letters = this.textProperty.currentData.l;
+
+      len = letters.length;
+      var renderedLetter;
+      var textSpan;
+      var glyphElement;
+      for (i = 0; i < len; i += 1) {
+        if (!letters[i].n) {
+          renderedLetter = renderedLetters[i];
+          textSpan = this.textSpans[i].span;
+          glyphElement = this.textSpans[i].glyph;
+          if (glyphElement) {
+            glyphElement.renderFrame();
+          }
+          if (renderedLetter._mdf.m) {
+            textSpan.setAttribute('transform', renderedLetter.m);
+          }
+          if (renderedLetter._mdf.o) {
+            textSpan.setAttribute('opacity', renderedLetter.o);
+          }
+          if (renderedLetter._mdf.sw) {
+            textSpan.setAttribute('stroke-width', renderedLetter.sw);
+          }
+          if (renderedLetter._mdf.sc) {
+            textSpan.setAttribute('stroke', renderedLetter.sc);
+          }
+          if (renderedLetter._mdf.fc) {
+            textSpan.setAttribute('fill', renderedLetter.fc);
+          }
+        }
+      }
+    }
+  }
+};
+
+function ISolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([IImageElement], ISolidElement);
+
+ISolidElement.prototype.createContent = function () {
+  var rect = createNS('rect');
+  /// /rect.style.width = this.data.sw;
+  /// /rect.style.height = this.data.sh;
+  /// /rect.style.fill = this.data.sc;
+  rect.setAttribute('width', this.data.sw);
+  rect.setAttribute('height', this.data.sh);
+  rect.setAttribute('fill', this.data.sc);
+  this.layerElement.appendChild(rect);
+};
+
+function NullElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initFrame();
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+}
+
+NullElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+NullElement.prototype.renderFrame = function () {
+};
+
+NullElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+NullElement.prototype.destroy = function () {
+};
+
+NullElement.prototype.sourceRectAtTime = function () {
+};
+
+NullElement.prototype.hide = function () {
+};
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
+
+function SVGRendererBase() {
+}
+
+extendPrototype([BaseRenderer], SVGRendererBase);
+
+SVGRendererBase.prototype.createNull = function (data) {
+  return new NullElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createShape = function (data) {
+  return new SVGShapeElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createText = function (data) {
+  return new SVGTextLottieElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createImage = function (data) {
+  return new IImageElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createSolid = function (data) {
+  return new ISolidElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.configAnimation = function (animData) {
+  this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+  this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+  if (this.renderConfig.viewBoxSize) {
+    this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
+  } else {
+    this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
+  }
+
+  if (!this.renderConfig.viewBoxOnly) {
+    this.svgElement.setAttribute('width', animData.w);
+    this.svgElement.setAttribute('height', animData.h);
+    this.svgElement.style.width = '100%';
+    this.svgElement.style.height = '100%';
+    this.svgElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
+  }
+  if (this.renderConfig.width) {
+    this.svgElement.setAttribute('width', this.renderConfig.width);
+  }
+  if (this.renderConfig.height) {
+    this.svgElement.setAttribute('height', this.renderConfig.height);
+  }
+  if (this.renderConfig.className) {
+    this.svgElement.setAttribute('class', this.renderConfig.className);
+  }
+  if (this.renderConfig.id) {
+    this.svgElement.setAttribute('id', this.renderConfig.id);
+  }
+  if (this.renderConfig.focusable !== undefined) {
+    this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
+  }
+  this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+  // this.layerElement.style.transform = 'translate3d(0,0,0)';
+  // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
+  this.animationItem.wrapper.appendChild(this.svgElement);
+  // Mask animation
+  var defs = this.globalData.defs;
+
+  this.setupGlobalData(animData, defs);
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.data = animData;
+
+  var maskElement = createNS('clipPath');
+  var rect = createNS('rect');
+  rect.setAttribute('width', animData.w);
+  rect.setAttribute('height', animData.h);
+  rect.setAttribute('x', 0);
+  rect.setAttribute('y', 0);
+  var maskId = createElementID();
+  maskElement.setAttribute('id', maskId);
+  maskElement.appendChild(rect);
+  this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')');
+
+  defs.appendChild(maskElement);
+  this.layers = animData.layers;
+  this.elements = createSizedArray(animData.layers.length);
+};
+
+SVGRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.layerElement = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+SVGRendererBase.prototype.updateContainerSize = function () {
+};
+
+SVGRendererBase.prototype.findIndexByInd = function (ind) {
+  var i = 0;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.layers[i].ind === ind) {
+      return i;
+    }
+  }
+  return -1;
+};
+
+SVGRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  elements[pos] = true;
+  var element = this.createItem(this.layers[pos]);
+
+  elements[pos] = element;
+  if (getExpressionsPlugin()) {
+    if (this.layers[pos].ty === 0) {
+      this.globalData.projectInterface.registerComposition(element);
+    }
+    element.initExpressions();
+  }
+  this.appendElementInPos(element, pos);
+  if (this.layers[pos].tt) {
+    var elementIndex = ('tp' in this.layers[pos])
+      ? this.findIndexByInd(this.layers[pos].tp)
+      : pos - 1;
+    if (elementIndex === -1) {
+      return;
+    }
+    if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
+      this.buildItem(elementIndex);
+      this.addPendingElement(element);
+    } else {
+      var matteElement = elements[elementIndex];
+      var matteMask = matteElement.getMatte(this.layers[pos].tt);
+      element.setMatte(matteMask);
+    }
+  }
+};
+
+SVGRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+    if (element.data.tt) {
+      var i = 0;
+      var len = this.elements.length;
+      while (i < len) {
+        if (this.elements[i] === element) {
+          var elementIndex = 'tp' in element.data
+            ? this.findIndexByInd(element.data.tp)
+            : i - 1;
+          var matteElement = this.elements[elementIndex];
+          var matteMask = matteElement.getMatte(this.layers[i].tt);
+          element.setMatte(matteMask);
+          break;
+        }
+        i += 1;
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.renderFrame = function (num) {
+  if (this.renderedFrame === num || this.destroyed) {
+    return;
+  }
+  if (num === null) {
+    num = this.renderedFrame;
+  } else {
+    this.renderedFrame = num;
+  }
+  // console.log('-------');
+  // console.log('FRAME ',num);
+  this.globalData.frameNum = num;
+  this.globalData.frameId += 1;
+  this.globalData.projectInterface.currentFrame = num;
+  this.globalData._mdf = false;
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    for (i = 0; i < len; i += 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
+  var newElement = element.getBaseElement();
+  if (!newElement) {
+    return;
+  }
+  var i = 0;
+  var nextElement;
+  while (i < pos) {
+    if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
+      nextElement = this.elements[i].getBaseElement();
+    }
+    i += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(newElement, nextElement);
+  } else {
+    this.layerElement.appendChild(newElement);
+  }
+};
+
+SVGRendererBase.prototype.hide = function () {
+  this.layerElement.style.display = 'none';
+};
+
+SVGRendererBase.prototype.show = function () {
+  this.layerElement.style.display = 'block';
+};
+
+function ICompElement() {}
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
+
+ICompElement.prototype.initElement = function (data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initTransform(data, globalData, comp);
+  this.initRenderable();
+  this.initHierarchy();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  if (this.data.xt || !globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+  this.hide();
+};
+
+/* ICompElement.prototype.hide = function(){
+    if(!this.hidden){
+        this.hideElement();
+        var i,len = this.elements.length;
+        for( i = 0; i < len; i+=1 ){
+            if(this.elements[i]){
+                this.elements[i].hide();
+            }
+        }
+    }
+}; */
+
+ICompElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+  if (!this.isInRange && !this.data.xt) {
+    return;
+  }
+
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    if (timeRemapped === this.data.op) {
+      timeRemapped = this.data.op - 1;
+    }
+    this.renderedFrame = timeRemapped;
+  } else {
+    this.renderedFrame = num / this.data.sr;
+  }
+  var i;
+  var len = this.elements.length;
+  if (!this.completeLayers) {
+    this.checkLayers(this.renderedFrame);
+  }
+  // This iteration needs to be backwards because of how expressions connect between each other
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
+      if (this.elements[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+ICompElement.prototype.renderInnerContent = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+ICompElement.prototype.setElements = function (elems) {
+  this.elements = elems;
+};
+
+ICompElement.prototype.getElements = function () {
+  return this.elements;
+};
+
+ICompElement.prototype.destroyElements = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+};
+
+ICompElement.prototype.destroy = function () {
+  this.destroyElements();
+  this.destroyBaseElement();
+};
+
+function SVGCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = true;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
+
+SVGCompElement.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function SVGRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.layers = null;
+  this.renderedFrame = -1;
+  this.svgElement = createNS('svg');
+  var ariaLabel = '';
+  if (config && config.title) {
+    var titleElement = createNS('title');
+    var titleId = createElementID();
+    titleElement.setAttribute('id', titleId);
+    titleElement.textContent = config.title;
+    this.svgElement.appendChild(titleElement);
+    ariaLabel += titleId;
+  }
+  if (config && config.description) {
+    var descElement = createNS('desc');
+    var descId = createElementID();
+    descElement.setAttribute('id', descId);
+    descElement.textContent = config.description;
+    this.svgElement.appendChild(descElement);
+    ariaLabel += ' ' + descId;
+  }
+  if (ariaLabel) {
+    this.svgElement.setAttribute('aria-labelledby', ariaLabel);
+  }
+  var defs = createNS('defs');
+  this.svgElement.appendChild(defs);
+  var maskElement = createNS('g');
+  this.svgElement.appendChild(maskElement);
+  this.layerElement = maskElement;
+  this.renderConfig = {
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    hideOnTransparent: !((config && config.hideOnTransparent === false)),
+    viewBoxOnly: (config && config.viewBoxOnly) || false,
+    viewBoxSize: (config && config.viewBoxSize) || false,
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    focusable: config && config.focusable,
+    filterSize: {
+      width: (config && config.filterSize && config.filterSize.width) || '100%',
+      height: (config && config.filterSize && config.filterSize.height) || '100%',
+      x: (config && config.filterSize && config.filterSize.x) || '0%',
+      y: (config && config.filterSize && config.filterSize.y) || '0%',
+    },
+    width: (config && config.width),
+    height: (config && config.height),
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+
+  this.globalData = {
+    _mdf: false,
+    frameNum: -1,
+    defs: defs,
+    renderConfig: this.renderConfig,
+  };
+  this.elements = [];
+  this.pendingElements = [];
+  this.destroyed = false;
+  this.rendererType = 'svg';
+}
+
+extendPrototype([SVGRendererBase], SVGRenderer);
+
+SVGRenderer.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+var registeredEffects = {};
+
+function CVEffects(elem) {
+  var i;
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects[type]) {
+      var Effect = registeredEffects[type].effect;
+      filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+CVEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+CVEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect(id, effect) {
+  registeredEffects[id] = {
+    effect,
+  };
+}
+
+function HBaseElement() {}
+HBaseElement.prototype = {
+  checkBlendMode: function () {},
+  initRendererElement: function () {
+    this.baseElement = createTag(this.data.tg || 'div');
+    if (this.data.hasMask) {
+      this.svgElement = createNS('svg');
+      this.layerElement = createNS('g');
+      this.maskedElement = this.layerElement;
+      this.svgElement.appendChild(this.layerElement);
+      this.baseElement.appendChild(this.svgElement);
+    } else {
+      this.layerElement = this.baseElement;
+    }
+    styleDiv(this.baseElement);
+  },
+  createContainerElements: function () {
+    this.renderableEffectsManager = new CVEffects(this);
+    this.transformedElement = this.baseElement;
+    this.maskedElement = this.layerElement;
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    var transformedElementStyle = this.transformedElement ? this.transformedElement.style : {};
+    if (this.finalTransform._matMdf) {
+      var matrixValue = this.finalTransform.mat.toCSS();
+      transformedElementStyle.transform = matrixValue;
+      transformedElementStyle.webkitTransform = matrixValue;
+    }
+    if (this.finalTransform._opMdf) {
+      transformedElementStyle.opacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderFrame: function () {
+    // If it is exported as hidden (data.hd === true) no need to render
+    // If it is not visible no need to render
+    if (this.data.hd || this.hidden) {
+      return;
+    }
+    this.renderTransform();
+    this.renderRenderable();
+    this.renderElement();
+    this.renderInnerContent();
+    if (this._isFirstFrame) {
+      this._isFirstFrame = false;
+    }
+  },
+  destroy: function () {
+    this.layerElement = null;
+    this.transformedElement = null;
+    if (this.matteElement) {
+      this.matteElement = null;
+    }
+    if (this.maskManager) {
+      this.maskManager.destroy();
+      this.maskManager = null;
+    }
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+  },
+  addEffects: function () {
+  },
+  setMatte: function () {},
+};
+HBaseElement.prototype.getBaseElement = SVGBaseElement.prototype.getBaseElement;
+HBaseElement.prototype.destroyBaseElement = HBaseElement.prototype.destroy;
+HBaseElement.prototype.buildElementParenting = BaseRenderer.prototype.buildElementParenting;
+
+function HSolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], HSolidElement);
+
+HSolidElement.prototype.createContent = function () {
+  var rect;
+  if (this.data.hasMask) {
+    rect = createNS('rect');
+    rect.setAttribute('width', this.data.sw);
+    rect.setAttribute('height', this.data.sh);
+    rect.setAttribute('fill', this.data.sc);
+    this.svgElement.setAttribute('width', this.data.sw);
+    this.svgElement.setAttribute('height', this.data.sh);
+  } else {
+    rect = createTag('div');
+    rect.style.width = this.data.sw + 'px';
+    rect.style.height = this.data.sh + 'px';
+    rect.style.backgroundColor = this.data.sc;
+  }
+  this.layerElement.appendChild(rect);
+};
+
+function HShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.shapesContainer = createNS('g');
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  this.currentBBox = {
+    x: 999999,
+    y: -999999,
+    h: 0,
+    w: 0,
+  };
+}
+extendPrototype([BaseElement, TransformElement, HSolidElement, SVGShapeElement, HBaseElement, HierarchyElement, FrameElement, RenderableElement], HShapeElement);
+HShapeElement.prototype._renderShapeFrame = HShapeElement.prototype.renderInnerContent;
+
+HShapeElement.prototype.createContent = function () {
+  var cont;
+  this.baseElement.style.fontSize = 0;
+  if (this.data.hasMask) {
+    this.layerElement.appendChild(this.shapesContainer);
+    cont = this.svgElement;
+  } else {
+    cont = createNS('svg');
+    var size = this.comp.data ? this.comp.data : this.globalData.compSize;
+    cont.setAttribute('width', size.w);
+    cont.setAttribute('height', size.h);
+    cont.appendChild(this.shapesContainer);
+    this.layerElement.appendChild(cont);
+  }
+
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.shapesContainer, 0, [], true);
+  this.filterUniqueShapes();
+  this.shapeCont = cont;
+};
+
+HShapeElement.prototype.getTransformedPoint = function (transformers, point) {
+  var i;
+  var len = transformers.length;
+  for (i = 0; i < len; i += 1) {
+    point = transformers[i].mProps.v.applyToPointArray(point[0], point[1], 0);
+  }
+  return point;
+};
+
+HShapeElement.prototype.calculateShapeBoundingBox = function (item, boundingBox) {
+  var shape = item.sh.v;
+  var transformers = item.transformers;
+  var i;
+  var len = shape._length;
+  var vPoint;
+  var oPoint;
+  var nextIPoint;
+  var nextVPoint;
+  if (len <= 1) {
+    return;
+  }
+  for (i = 0; i < len - 1; i += 1) {
+    vPoint = this.getTransformedPoint(transformers, shape.v[i]);
+    oPoint = this.getTransformedPoint(transformers, shape.o[i]);
+    nextIPoint = this.getTransformedPoint(transformers, shape.i[i + 1]);
+    nextVPoint = this.getTransformedPoint(transformers, shape.v[i + 1]);
+    this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
+  }
+  if (shape.c) {
+    vPoint = this.getTransformedPoint(transformers, shape.v[i]);
+    oPoint = this.getTransformedPoint(transformers, shape.o[i]);
+    nextIPoint = this.getTransformedPoint(transformers, shape.i[0]);
+    nextVPoint = this.getTransformedPoint(transformers, shape.v[0]);
+    this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
+  }
+};
+
+HShapeElement.prototype.checkBounds = function (vPoint, oPoint, nextIPoint, nextVPoint, boundingBox) {
+  this.getBoundsOfCurve(vPoint, oPoint, nextIPoint, nextVPoint);
+  var bounds = this.shapeBoundingBox;
+  boundingBox.x = bmMin(bounds.left, boundingBox.x);
+  boundingBox.xMax = bmMax(bounds.right, boundingBox.xMax);
+  boundingBox.y = bmMin(bounds.top, boundingBox.y);
+  boundingBox.yMax = bmMax(bounds.bottom, boundingBox.yMax);
+};
+
+HShapeElement.prototype.shapeBoundingBox = {
+  left: 0,
+  right: 0,
+  top: 0,
+  bottom: 0,
+};
+
+HShapeElement.prototype.tempBoundingBox = {
+  x: 0,
+  xMax: 0,
+  y: 0,
+  yMax: 0,
+  width: 0,
+  height: 0,
+};
+
+HShapeElement.prototype.getBoundsOfCurve = function (p0, p1, p2, p3) {
+  var bounds = [[p0[0], p3[0]], [p0[1], p3[1]]];
+
+  for (var a, b, c, t, b2ac, t1, t2, i = 0; i < 2; ++i) { // eslint-disable-line no-plusplus
+    b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];
+    a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];
+    c = 3 * p1[i] - 3 * p0[i];
+
+    b |= 0; // eslint-disable-line no-bitwise
+    a |= 0; // eslint-disable-line no-bitwise
+    c |= 0; // eslint-disable-line no-bitwise
+
+    if (a === 0 && b === 0) {
+      //
+    } else if (a === 0) {
+      t = -c / b;
+
+      if (t > 0 && t < 1) {
+        bounds[i].push(this.calculateF(t, p0, p1, p2, p3, i));
+      }
+    } else {
+      b2ac = b * b - 4 * c * a;
+
+      if (b2ac >= 0) {
+        t1 = (-b + bmSqrt(b2ac)) / (2 * a);
+        if (t1 > 0 && t1 < 1) bounds[i].push(this.calculateF(t1, p0, p1, p2, p3, i));
+        t2 = (-b - bmSqrt(b2ac)) / (2 * a);
+        if (t2 > 0 && t2 < 1) bounds[i].push(this.calculateF(t2, p0, p1, p2, p3, i));
+      }
+    }
+  }
+
+  this.shapeBoundingBox.left = bmMin.apply(null, bounds[0]);
+  this.shapeBoundingBox.top = bmMin.apply(null, bounds[1]);
+  this.shapeBoundingBox.right = bmMax.apply(null, bounds[0]);
+  this.shapeBoundingBox.bottom = bmMax.apply(null, bounds[1]);
+};
+
+HShapeElement.prototype.calculateF = function (t, p0, p1, p2, p3, i) {
+  return bmPow(1 - t, 3) * p0[i]
+        + 3 * bmPow(1 - t, 2) * t * p1[i]
+        + 3 * (1 - t) * bmPow(t, 2) * p2[i]
+        + bmPow(t, 3) * p3[i];
+};
+
+HShapeElement.prototype.calculateBoundingBox = function (itemsData, boundingBox) {
+  var i;
+  var len = itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    if (itemsData[i] && itemsData[i].sh) {
+      this.calculateShapeBoundingBox(itemsData[i], boundingBox);
+    } else if (itemsData[i] && itemsData[i].it) {
+      this.calculateBoundingBox(itemsData[i].it, boundingBox);
+    } else if (itemsData[i] && itemsData[i].style && itemsData[i].w) {
+      this.expandStrokeBoundingBox(itemsData[i].w, boundingBox);
+    }
+  }
+};
+
+HShapeElement.prototype.expandStrokeBoundingBox = function (widthProperty, boundingBox) {
+  var width = 0;
+  if (widthProperty.keyframes) {
+    for (var i = 0; i < widthProperty.keyframes.length; i += 1) {
+      var kfw = widthProperty.keyframes[i].s;
+      if (kfw > width) {
+        width = kfw;
+      }
+    }
+    width *= widthProperty.mult;
+  } else {
+    width = widthProperty.v * widthProperty.mult;
+  }
+
+  boundingBox.x -= width;
+  boundingBox.xMax += width;
+  boundingBox.y -= width;
+  boundingBox.yMax += width;
+};
+
+HShapeElement.prototype.currentBoxContains = function (box) {
+  return this.currentBBox.x <= box.x
+    && this.currentBBox.y <= box.y
+    && this.currentBBox.width + this.currentBBox.x >= box.x + box.width
+    && this.currentBBox.height + this.currentBBox.y >= box.y + box.height;
+};
+
+HShapeElement.prototype.renderInnerContent = function () {
+  this._renderShapeFrame();
+
+  if (!this.hidden && (this._isFirstFrame || this._mdf)) {
+    var tempBoundingBox = this.tempBoundingBox;
+    var max = 999999;
+    tempBoundingBox.x = max;
+    tempBoundingBox.xMax = -max;
+    tempBoundingBox.y = max;
+    tempBoundingBox.yMax = -max;
+    this.calculateBoundingBox(this.itemsData, tempBoundingBox);
+    tempBoundingBox.width = tempBoundingBox.xMax < tempBoundingBox.x ? 0 : tempBoundingBox.xMax - tempBoundingBox.x;
+    tempBoundingBox.height = tempBoundingBox.yMax < tempBoundingBox.y ? 0 : tempBoundingBox.yMax - tempBoundingBox.y;
+    // var tempBoundingBox = this.shapeCont.getBBox();
+    if (this.currentBoxContains(tempBoundingBox)) {
+      return;
+    }
+    var changed = false;
+    if (this.currentBBox.w !== tempBoundingBox.width) {
+      this.currentBBox.w = tempBoundingBox.width;
+      this.shapeCont.setAttribute('width', tempBoundingBox.width);
+      changed = true;
+    }
+    if (this.currentBBox.h !== tempBoundingBox.height) {
+      this.currentBBox.h = tempBoundingBox.height;
+      this.shapeCont.setAttribute('height', tempBoundingBox.height);
+      changed = true;
+    }
+    if (changed || this.currentBBox.x !== tempBoundingBox.x || this.currentBBox.y !== tempBoundingBox.y) {
+      this.currentBBox.w = tempBoundingBox.width;
+      this.currentBBox.h = tempBoundingBox.height;
+      this.currentBBox.x = tempBoundingBox.x;
+      this.currentBBox.y = tempBoundingBox.y;
+
+      this.shapeCont.setAttribute('viewBox', this.currentBBox.x + ' ' + this.currentBBox.y + ' ' + this.currentBBox.w + ' ' + this.currentBBox.h);
+      var shapeStyle = this.shapeCont.style;
+      var shapeTransform = 'translate(' + this.currentBBox.x + 'px,' + this.currentBBox.y + 'px)';
+      shapeStyle.transform = shapeTransform;
+      shapeStyle.webkitTransform = shapeTransform;
+    }
+  }
+};
+
+function HTextElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.textPaths = [];
+  this.currentBBox = {
+    x: 999999,
+    y: -999999,
+    h: 0,
+    w: 0,
+  };
+  this.renderType = 'svg';
+  this.isMasked = false;
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], HTextElement);
+
+HTextElement.prototype.createContent = function () {
+  this.isMasked = this.checkMasks();
+  if (this.isMasked) {
+    this.renderType = 'svg';
+    this.compW = this.comp.data.w;
+    this.compH = this.comp.data.h;
+    this.svgElement.setAttribute('width', this.compW);
+    this.svgElement.setAttribute('height', this.compH);
+    var g = createNS('g');
+    this.maskedElement.appendChild(g);
+    this.innerElem = g;
+  } else {
+    this.renderType = 'html';
+    this.innerElem = this.layerElement;
+  }
+
+  this.checkParenting();
+};
+
+HTextElement.prototype.buildNewText = function () {
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
+  var innerElemStyle = this.innerElem.style;
+  var textColor = documentData.fc ? this.buildColor(documentData.fc) : 'rgba(0,0,0,0)';
+  innerElemStyle.fill = textColor;
+  innerElemStyle.color = textColor;
+  if (documentData.sc) {
+    innerElemStyle.stroke = this.buildColor(documentData.sc);
+    innerElemStyle.strokeWidth = documentData.sw + 'px';
+  }
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (!this.globalData.fontManager.chars) {
+    innerElemStyle.fontSize = documentData.finalSize + 'px';
+    innerElemStyle.lineHeight = documentData.finalSize + 'px';
+    if (fontData.fClass) {
+      this.innerElem.className = fontData.fClass;
+    } else {
+      innerElemStyle.fontFamily = fontData.fFamily;
+      var fWeight = documentData.fWeight;
+      var fStyle = documentData.fStyle;
+      innerElemStyle.fontStyle = fStyle;
+      innerElemStyle.fontWeight = fWeight;
+    }
+  }
+  var i;
+  var len;
+
+  var letters = documentData.l;
+  len = letters.length;
+  var tSpan;
+  var tParent;
+  var tCont;
+  var matrixHelper = this.mHelper;
+  var shapes;
+  var shapeStr = '';
+  var cnt = 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.globalData.fontManager.chars) {
+      if (!this.textPaths[cnt]) {
+        tSpan = createNS('path');
+        tSpan.setAttribute('stroke-linecap', lineCapEnum[1]);
+        tSpan.setAttribute('stroke-linejoin', lineJoinEnum[2]);
+        tSpan.setAttribute('stroke-miterlimit', '4');
+      } else {
+        tSpan = this.textPaths[cnt];
+      }
+      if (!this.isMasked) {
+        if (this.textSpans[cnt]) {
+          tParent = this.textSpans[cnt];
+          tCont = tParent.children[0];
+        } else {
+          tParent = createTag('div');
+          tParent.style.lineHeight = 0;
+          tCont = createNS('svg');
+          tCont.appendChild(tSpan);
+          styleDiv(tParent);
+        }
+      }
+    } else if (!this.isMasked) {
+      if (this.textSpans[cnt]) {
+        tParent = this.textSpans[cnt];
+        tSpan = this.textPaths[cnt];
+      } else {
+        tParent = createTag('span');
+        styleDiv(tParent);
+        tSpan = createTag('span');
+        styleDiv(tSpan);
+        tParent.appendChild(tSpan);
+      }
+    } else {
+      tSpan = this.textPaths[cnt] ? this.textPaths[cnt] : createNS('text');
+    }
+    // tSpan.setAttribute('visibility', 'hidden');
+    if (this.globalData.fontManager.chars) {
+      var charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
+      var shapeData;
+      if (charData) {
+        shapeData = charData.data;
+      } else {
+        shapeData = null;
+      }
+      matrixHelper.reset();
+      if (shapeData && shapeData.shapes && shapeData.shapes.length) {
+        shapes = shapeData.shapes[0].it;
+        matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
+        shapeStr = this.createPathShape(matrixHelper, shapes);
+        tSpan.setAttribute('d', shapeStr);
+      }
+      if (!this.isMasked) {
+        this.innerElem.appendChild(tParent);
+        if (shapeData && shapeData.shapes) {
+          // document.body.appendChild is needed to get exact measure of shape
+          document.body.appendChild(tCont);
+          var boundingBox = tCont.getBBox();
+          tCont.setAttribute('width', boundingBox.width + 2);
+          tCont.setAttribute('height', boundingBox.height + 2);
+          tCont.setAttribute('viewBox', (boundingBox.x - 1) + ' ' + (boundingBox.y - 1) + ' ' + (boundingBox.width + 2) + ' ' + (boundingBox.height + 2));
+          var tContStyle = tCont.style;
+          var tContTranslation = 'translate(' + (boundingBox.x - 1) + 'px,' + (boundingBox.y - 1) + 'px)';
+          tContStyle.transform = tContTranslation;
+          tContStyle.webkitTransform = tContTranslation;
+
+          letters[i].yOffset = boundingBox.y - 1;
+        } else {
+          tCont.setAttribute('width', 1);
+          tCont.setAttribute('height', 1);
+        }
+        tParent.appendChild(tCont);
+      } else {
+        this.innerElem.appendChild(tSpan);
+      }
+    } else {
+      tSpan.textContent = letters[i].val;
+      tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      if (!this.isMasked) {
+        this.innerElem.appendChild(tParent);
+        //
+        var tStyle = tSpan.style;
+        var tSpanTranslation = 'translate3d(0,' + -documentData.finalSize / 1.2 + 'px,0)';
+        tStyle.transform = tSpanTranslation;
+        tStyle.webkitTransform = tSpanTranslation;
+      } else {
+        this.innerElem.appendChild(tSpan);
+      }
+    }
+    //
+    if (!this.isMasked) {
+      this.textSpans[cnt] = tParent;
+    } else {
+      this.textSpans[cnt] = tSpan;
+    }
+    this.textSpans[cnt].style.display = 'block';
+    this.textPaths[cnt] = tSpan;
+    cnt += 1;
+  }
+  while (cnt < this.textSpans.length) {
+    this.textSpans[cnt].style.display = 'none';
+    cnt += 1;
+  }
+};
+
+HTextElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  var svgStyle;
+  if (this.data.singleShape) {
+    if (!this._isFirstFrame && !this.lettersChangedFlag) {
+      return;
+    } if (this.isMasked && this.finalTransform._matMdf) {
+      // Todo Benchmark if using this is better than getBBox
+      this.svgElement.setAttribute('viewBox', -this.finalTransform.mProp.p.v[0] + ' ' + -this.finalTransform.mProp.p.v[1] + ' ' + this.compW + ' ' + this.compH);
+      svgStyle = this.svgElement.style;
+      var translation = 'translate(' + -this.finalTransform.mProp.p.v[0] + 'px,' + -this.finalTransform.mProp.p.v[1] + 'px)';
+      svgStyle.transform = translation;
+      svgStyle.webkitTransform = translation;
+    }
+  }
+
+  this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+  if (!this.lettersChangedFlag && !this.textAnimator.lettersChangedFlag) {
+    return;
+  }
+  var i;
+  var len;
+  var count = 0;
+  var renderedLetters = this.textAnimator.renderedLetters;
+
+  var letters = this.textProperty.currentData.l;
+
+  len = letters.length;
+  var renderedLetter;
+  var textSpan;
+  var textPath;
+  for (i = 0; i < len; i += 1) {
+    if (letters[i].n) {
+      count += 1;
+    } else {
+      textSpan = this.textSpans[i];
+      textPath = this.textPaths[i];
+      renderedLetter = renderedLetters[count];
+      count += 1;
+      if (renderedLetter._mdf.m) {
+        if (!this.isMasked) {
+          textSpan.style.webkitTransform = renderedLetter.m;
+          textSpan.style.transform = renderedLetter.m;
+        } else {
+          textSpan.setAttribute('transform', renderedLetter.m);
+        }
+      }
+      /// /textSpan.setAttribute('opacity',renderedLetter.o);
+      textSpan.style.opacity = renderedLetter.o;
+      if (renderedLetter.sw && renderedLetter._mdf.sw) {
+        textPath.setAttribute('stroke-width', renderedLetter.sw);
+      }
+      if (renderedLetter.sc && renderedLetter._mdf.sc) {
+        textPath.setAttribute('stroke', renderedLetter.sc);
+      }
+      if (renderedLetter.fc && renderedLetter._mdf.fc) {
+        textPath.setAttribute('fill', renderedLetter.fc);
+        textPath.style.color = renderedLetter.fc;
+      }
+    }
+  }
+
+  if (this.innerElem.getBBox && !this.hidden && (this._isFirstFrame || this._mdf)) {
+    var boundingBox = this.innerElem.getBBox();
+
+    if (this.currentBBox.w !== boundingBox.width) {
+      this.currentBBox.w = boundingBox.width;
+      this.svgElement.setAttribute('width', boundingBox.width);
+    }
+    if (this.currentBBox.h !== boundingBox.height) {
+      this.currentBBox.h = boundingBox.height;
+      this.svgElement.setAttribute('height', boundingBox.height);
+    }
+
+    var margin = 1;
+    if (this.currentBBox.w !== (boundingBox.width + margin * 2) || this.currentBBox.h !== (boundingBox.height + margin * 2) || this.currentBBox.x !== (boundingBox.x - margin) || this.currentBBox.y !== (boundingBox.y - margin)) {
+      this.currentBBox.w = boundingBox.width + margin * 2;
+      this.currentBBox.h = boundingBox.height + margin * 2;
+      this.currentBBox.x = boundingBox.x - margin;
+      this.currentBBox.y = boundingBox.y - margin;
+
+      this.svgElement.setAttribute('viewBox', this.currentBBox.x + ' ' + this.currentBBox.y + ' ' + this.currentBBox.w + ' ' + this.currentBBox.h);
+      svgStyle = this.svgElement.style;
+      var svgTransform = 'translate(' + this.currentBBox.x + 'px,' + this.currentBBox.y + 'px)';
+      svgStyle.transform = svgTransform;
+      svgStyle.webkitTransform = svgTransform;
+    }
+  }
+};
+
+function HCameraElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initHierarchy();
+  var getProp = PropertyFactory.getProp;
+  this.pe = getProp(this, data.pe, 0, 0, this);
+  if (data.ks.p.s) {
+    this.px = getProp(this, data.ks.p.x, 1, 0, this);
+    this.py = getProp(this, data.ks.p.y, 1, 0, this);
+    this.pz = getProp(this, data.ks.p.z, 1, 0, this);
+  } else {
+    this.p = getProp(this, data.ks.p, 1, 0, this);
+  }
+  if (data.ks.a) {
+    this.a = getProp(this, data.ks.a, 1, 0, this);
+  }
+  if (data.ks.or.k.length && data.ks.or.k[0].to) {
+    var i;
+    var len = data.ks.or.k.length;
+    for (i = 0; i < len; i += 1) {
+      data.ks.or.k[i].to = null;
+      data.ks.or.k[i].ti = null;
+    }
+  }
+  this.or = getProp(this, data.ks.or, 1, degToRads, this);
+  this.or.sh = true;
+  this.rx = getProp(this, data.ks.rx, 0, degToRads, this);
+  this.ry = getProp(this, data.ks.ry, 0, degToRads, this);
+  this.rz = getProp(this, data.ks.rz, 0, degToRads, this);
+  this.mat = new Matrix();
+  this._prevMat = new Matrix();
+  this._isFirstFrame = true;
+
+  // TODO: find a better way to make the HCamera element to be compatible with the LayerInterface and TransformInterface.
+  this.finalTransform = {
+    mProp: this,
+  };
+}
+extendPrototype([BaseElement, FrameElement, HierarchyElement], HCameraElement);
+
+HCameraElement.prototype.setup = function () {
+  var i;
+  var len = this.comp.threeDElements.length;
+  var comp;
+  var perspectiveStyle;
+  var containerStyle;
+  for (i = 0; i < len; i += 1) {
+    // [perspectiveElem,container]
+    comp = this.comp.threeDElements[i];
+    if (comp.type === '3d') {
+      perspectiveStyle = comp.perspectiveElem.style;
+      containerStyle = comp.container.style;
+      var perspective = this.pe.v + 'px';
+      var origin = '0px 0px 0px';
+      var matrix = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)';
+      perspectiveStyle.perspective = perspective;
+      perspectiveStyle.webkitPerspective = perspective;
+      containerStyle.transformOrigin = origin;
+      containerStyle.mozTransformOrigin = origin;
+      containerStyle.webkitTransformOrigin = origin;
+      perspectiveStyle.transform = matrix;
+      perspectiveStyle.webkitTransform = matrix;
+    }
+  }
+};
+
+HCameraElement.prototype.createElements = function () {
+};
+
+HCameraElement.prototype.hide = function () {
+};
+
+HCameraElement.prototype.renderFrame = function () {
+  var _mdf = this._isFirstFrame;
+  var i;
+  var len;
+  if (this.hierarchy) {
+    len = this.hierarchy.length;
+    for (i = 0; i < len; i += 1) {
+      _mdf = this.hierarchy[i].finalTransform.mProp._mdf || _mdf;
+    }
+  }
+  if (_mdf || this.pe._mdf || (this.p && this.p._mdf) || (this.px && (this.px._mdf || this.py._mdf || this.pz._mdf)) || this.rx._mdf || this.ry._mdf || this.rz._mdf || this.or._mdf || (this.a && this.a._mdf)) {
+    this.mat.reset();
+
+    if (this.hierarchy) {
+      len = this.hierarchy.length - 1;
+      for (i = len; i >= 0; i -= 1) {
+        var mTransf = this.hierarchy[i].finalTransform.mProp;
+        this.mat.translate(-mTransf.p.v[0], -mTransf.p.v[1], mTransf.p.v[2]);
+        this.mat.rotateX(-mTransf.or.v[0]).rotateY(-mTransf.or.v[1]).rotateZ(mTransf.or.v[2]);
+        this.mat.rotateX(-mTransf.rx.v).rotateY(-mTransf.ry.v).rotateZ(mTransf.rz.v);
+        this.mat.scale(1 / mTransf.s.v[0], 1 / mTransf.s.v[1], 1 / mTransf.s.v[2]);
+        this.mat.translate(mTransf.a.v[0], mTransf.a.v[1], mTransf.a.v[2]);
+      }
+    }
+    if (this.p) {
+      this.mat.translate(-this.p.v[0], -this.p.v[1], this.p.v[2]);
+    } else {
+      this.mat.translate(-this.px.v, -this.py.v, this.pz.v);
+    }
+    if (this.a) {
+      var diffVector;
+      if (this.p) {
+        diffVector = [this.p.v[0] - this.a.v[0], this.p.v[1] - this.a.v[1], this.p.v[2] - this.a.v[2]];
+      } else {
+        diffVector = [this.px.v - this.a.v[0], this.py.v - this.a.v[1], this.pz.v - this.a.v[2]];
+      }
+      var mag = Math.sqrt(Math.pow(diffVector[0], 2) + Math.pow(diffVector[1], 2) + Math.pow(diffVector[2], 2));
+      // var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
+      var lookDir = [diffVector[0] / mag, diffVector[1] / mag, diffVector[2] / mag];
+      var lookLengthOnXZ = Math.sqrt(lookDir[2] * lookDir[2] + lookDir[0] * lookDir[0]);
+      var mRotationX = (Math.atan2(lookDir[1], lookLengthOnXZ));
+      var mRotationY = (Math.atan2(lookDir[0], -lookDir[2]));
+      this.mat.rotateY(mRotationY).rotateX(-mRotationX);
+    }
+    this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v);
+    this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]);
+    this.mat.translate(this.globalData.compSize.w / 2, this.globalData.compSize.h / 2, 0);
+    this.mat.translate(0, 0, this.pe.v);
+
+    var hasMatrixChanged = !this._prevMat.equals(this.mat);
+    if ((hasMatrixChanged || this.pe._mdf) && this.comp.threeDElements) {
+      len = this.comp.threeDElements.length;
+      var comp;
+      var perspectiveStyle;
+      var containerStyle;
+      for (i = 0; i < len; i += 1) {
+        comp = this.comp.threeDElements[i];
+        if (comp.type === '3d') {
+          if (hasMatrixChanged) {
+            var matValue = this.mat.toCSS();
+            containerStyle = comp.container.style;
+            containerStyle.transform = matValue;
+            containerStyle.webkitTransform = matValue;
+          }
+          if (this.pe._mdf) {
+            perspectiveStyle = comp.perspectiveElem.style;
+            perspectiveStyle.perspective = this.pe.v + 'px';
+            perspectiveStyle.webkitPerspective = this.pe.v + 'px';
+          }
+        }
+      }
+      this.mat.clone(this._prevMat);
+    }
+  }
+  this._isFirstFrame = false;
+};
+
+HCameraElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+HCameraElement.prototype.destroy = function () {
+};
+HCameraElement.prototype.getBaseElement = function () { return null; };
+
+function HImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, HBaseElement, HSolidElement, HierarchyElement, FrameElement, RenderableElement], HImageElement);
+
+HImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  var img = new Image();
+
+  if (this.data.hasMask) {
+    this.imageElem = createNS('image');
+    this.imageElem.setAttribute('width', this.assetData.w + 'px');
+    this.imageElem.setAttribute('height', this.assetData.h + 'px');
+    this.imageElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+    this.layerElement.appendChild(this.imageElem);
+    this.baseElement.setAttribute('width', this.assetData.w);
+    this.baseElement.setAttribute('height', this.assetData.h);
+  } else {
+    this.layerElement.appendChild(img);
+  }
+  img.crossOrigin = 'anonymous';
+  img.src = assetPath;
+  if (this.data.ln) {
+    this.baseElement.setAttribute('id', this.data.ln);
+  }
+};
+
+function HybridRendererBase(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),
+    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], HybridRendererBase);
+
+HybridRendererBase.prototype.buildItem = SVGRenderer.prototype.buildItem;
+
+HybridRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+  }
+};
+
+HybridRendererBase.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;
+      var nextLayer;
+      var 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);
+  }
+};
+
+HybridRendererBase.prototype.createShape = function (data) {
+  if (!this.supports3d) {
+    return new SVGShapeElement(data, this.globalData, this);
+  }
+  return new HShapeElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createText = function (data) {
+  if (!this.supports3d) {
+    return new SVGTextLottieElement(data, this.globalData, this);
+  }
+  return new HTextElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createCamera = function (data) {
+  this.camera = new HCameraElement(data, this.globalData, this);
+  return this.camera;
+};
+
+HybridRendererBase.prototype.createImage = function (data) {
+  if (!this.supports3d) {
+    return new IImageElement(data, this.globalData, this);
+  }
+  return new HImageElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createSolid = function (data) {
+  if (!this.supports3d) {
+    return new ISolidElement(data, this.globalData, this);
+  }
+  return new HSolidElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
+
+HybridRendererBase.prototype.getThreeDContainerByPos = function (pos) {
+  var i = 0;
+  var 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;
+  }
+  return null;
+};
+
+HybridRendererBase.prototype.createThreeDContainer = function (pos, type) {
+  var perspectiveElem = createTag('div');
+  var style;
+  var containerStyle;
+  styleDiv(perspectiveElem);
+  var container = createTag('div');
+  styleDiv(container);
+  if (type === '3d') {
+    style = perspectiveElem.style;
+    style.width = this.globalData.compSize.w + 'px';
+    style.height = this.globalData.compSize.h + 'px';
+    var center = '50% 50%';
+    style.webkitTransformOrigin = center;
+    style.mozTransformOrigin = center;
+    style.transformOrigin = center;
+    containerStyle = container.style;
+    var matrix = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)';
+    containerStyle.transform = matrix;
+    containerStyle.webkitTransform = matrix;
+  }
+
+  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;
+};
+
+HybridRendererBase.prototype.build3dContainers = function () {
+  var i;
+  var 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 -= 1) {
+    this.resizerElem.appendChild(this.threeDElements[i].perspectiveElem);
+  }
+};
+
+HybridRendererBase.prototype.addTo3dContainer = function (elem, pos) {
+  var i = 0;
+  var 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;
+  }
+};
+
+HybridRendererBase.prototype.configAnimation = function (animData) {
+  var resizerElem = createTag('div');
+  var wrapper = this.animationItem.wrapper;
+  var style = resizerElem.style;
+  style.width = animData.w + 'px';
+  style.height = animData.h + 'px';
+  this.resizerElem = resizerElem;
+  styleDiv(resizerElem);
+  style.transformStyle = 'flat';
+  style.mozTransformStyle = 'flat';
+  style.webkitTransformStyle = 'flat';
+  if (this.renderConfig.className) {
+    resizerElem.setAttribute('class', this.renderConfig.className);
+  }
+  wrapper.appendChild(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();
+};
+
+HybridRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.animationItem.container = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+HybridRendererBase.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;
+  var sy;
+  var tx;
+  var 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;
+  }
+  var style = this.resizerElem.style;
+  style.webkitTransform = 'matrix3d(' + sx + ',0,0,0,0,' + sy + ',0,0,0,0,1,0,' + tx + ',' + ty + ',0,1)';
+  style.transform = style.webkitTransform;
+};
+
+HybridRendererBase.prototype.renderFrame = SVGRenderer.prototype.renderFrame;
+
+HybridRendererBase.prototype.hide = function () {
+  this.resizerElem.style.display = 'none';
+};
+
+HybridRendererBase.prototype.show = function () {
+  this.resizerElem.style.display = 'block';
+};
+
+HybridRendererBase.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;
+    var len = this.threeDElements.length;
+    for (i = 0; i < len; i += 1) {
+      var style = this.threeDElements[i].perspectiveElem.style;
+      style.webkitPerspective = Math.sqrt(Math.pow(cWidth, 2) + Math.pow(cHeight, 2)) + 'px';
+      style.perspective = style.webkitPerspective;
+    }
+  }
+};
+
+HybridRendererBase.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var 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);
+    }
+  }
+};
+
+function HCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = !data.hasMask;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([HybridRendererBase, ICompElement, HBaseElement], HCompElement);
+HCompElement.prototype._createBaseContainerElements = HCompElement.prototype.createContainerElements;
+
+HCompElement.prototype.createContainerElements = function () {
+  this._createBaseContainerElements();
+  // divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
+  if (this.data.hasMask) {
+    this.svgElement.setAttribute('width', this.data.w);
+    this.svgElement.setAttribute('height', this.data.h);
+    this.transformedElement = this.baseElement;
+  } else {
+    this.transformedElement = this.layerElement;
+  }
+};
+
+HCompElement.prototype.addTo3dContainer = function (elem, pos) {
+  var j = 0;
+  var nextElement;
+  while (j < pos) {
+    if (this.elements[j] && this.elements[j].getBaseElement) {
+      nextElement = this.elements[j].getBaseElement();
+    }
+    j += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(elem, nextElement);
+  } else {
+    this.layerElement.appendChild(elem);
+  }
+};
+
+HCompElement.prototype.createComp = function (data) {
+  if (!this.supports3d) {
+    return new SVGCompElement(data, this.globalData, this);
+  }
+  return new HCompElement(data, this.globalData, this);
+};
+
+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),
+    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%',
+    },
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+  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([HybridRendererBase], HybridRenderer);
+
+HybridRenderer.prototype.createComp = function (data) {
+  if (!this.supports3d) {
+    return new SVGCompElement(data, this.globalData, this);
+  }
+  return new HCompElement(data, this.globalData, this);
+};
+
+// Registering renderers
+registerRenderer('html', HybridRenderer);
+
+// Registering shape modifiers
+ShapeModifiers.registerModifier('tm', TrimModifier);
+ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
+ShapeModifiers.registerModifier('rp', RepeaterModifier);
+ShapeModifiers.registerModifier('rd', RoundCornersModifier);
+ShapeModifiers.registerModifier('zz', ZigZagModifier);
+ShapeModifiers.registerModifier('op', OffsetPathModifier);
+
+const CompExpressionInterface = (function () {
+  return function (comp) {
+    function _thisLayerFunction(name) {
+      var i = 0;
+      var len = comp.layers.length;
+      while (i < len) {
+        if (comp.layers[i].nm === name || comp.layers[i].ind === name) {
+          return comp.elements[i].layerInterface;
+        }
+        i += 1;
+      }
+      return null;
+      // return {active:false};
+    }
+    Object.defineProperty(_thisLayerFunction, '_name', { value: comp.data.nm });
+    _thisLayerFunction.layer = _thisLayerFunction;
+    _thisLayerFunction.pixelAspect = 1;
+    _thisLayerFunction.height = comp.data.h || comp.globalData.compSize.h;
+    _thisLayerFunction.width = comp.data.w || comp.globalData.compSize.w;
+    _thisLayerFunction.pixelAspect = 1;
+    _thisLayerFunction.frameDuration = 1 / comp.globalData.frameRate;
+    _thisLayerFunction.displayStartTime = 0;
+    _thisLayerFunction.numLayers = comp.layers.length;
+    return _thisLayerFunction;
+  };
+}());
+
+/* eslint-disable */
+/*
+ Copyright 2014 David Bau.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ */
+
+function seedRandom(pool, math) {
+//
+// The following constants are related to IEEE 754 limits.
+//
+    var global = this,
+        width = 256,        // each RC4 output is 0 <= x < 256
+        chunks = 6,         // at least six RC4 outputs for each double
+        digits = 52,        // there are 52 significant digits in a double
+        rngname = 'random', // rngname: name for Math.random and Math.seedrandom
+        startdenom = math.pow(width, chunks),
+        significance = math.pow(2, digits),
+        overflow = significance * 2,
+        mask = width - 1,
+        nodecrypto;         // node.js crypto module, initialized at the bottom.
+
+//
+// seedrandom()
+// This is the seedrandom function described above.
+//
+    function seedrandom(seed, options, callback) {
+        var key = [];
+        options = (options === true) ? { entropy: true } : (options || {});
+
+        // Flatten the seed string or build one from local entropy if needed.
+        var shortseed = mixkey(flatten(
+            options.entropy ? [seed, tostring(pool)] :
+                (seed === null) ? autoseed() : seed, 3), key);
+
+        // Use the seed to initialize an ARC4 generator.
+        var arc4 = new ARC4(key);
+
+        // This function returns a random double in [0, 1) that contains
+        // randomness in every bit of the mantissa of the IEEE 754 value.
+        var prng = function() {
+            var n = arc4.g(chunks),             // Start with a numerator n < 2 ^ 48
+                d = startdenom,                 //   and denominator d = 2 ^ 48.
+                x = 0;                          //   and no 'extra last byte'.
+            while (n < significance) {          // Fill up all significant digits by
+                n = (n + x) * width;              //   shifting numerator and
+                d *= width;                       //   denominator and generating a
+                x = arc4.g(1);                    //   new least-significant-byte.
+            }
+            while (n >= overflow) {             // To avoid rounding up, before adding
+                n /= 2;                           //   last byte, shift everything
+                d /= 2;                           //   right using integer math until
+                x >>>= 1;                         //   we have exactly the desired bits.
+            }
+            return (n + x) / d;                 // Form the number within [0, 1).
+        };
+
+        prng.int32 = function() { return arc4.g(4) | 0; };
+        prng.quick = function() { return arc4.g(4) / 0x100000000; };
+        prng.double = prng;
+
+        // Mix the randomness into accumulated entropy.
+        mixkey(tostring(arc4.S), pool);
+
+        // Calling convention: what to return as a function of prng, seed, is_math.
+        return (options.pass || callback ||
+        function(prng, seed, is_math_call, state) {
+            if (state) {
+                // Load the arc4 state from the given state if it has an S array.
+                if (state.S) { copy(state, arc4); }
+                // Only provide the .state method if requested via options.state.
+                prng.state = function() { return copy(arc4, {}); };
+            }
+
+            // If called as a method of Math (Math.seedrandom()), mutate
+            // Math.random because that is how seedrandom.js has worked since v1.0.
+            if (is_math_call) { math[rngname] = prng; return seed; }
+
+            // Otherwise, it is a newer calling convention, so return the
+            // prng directly.
+            else return prng;
+        })(
+            prng,
+            shortseed,
+            'global' in options ? options.global : (this == math),
+            options.state);
+    }
+    math['seed' + rngname] = seedrandom;
+
+//
+// ARC4
+//
+// An ARC4 implementation.  The constructor takes a key in the form of
+// an array of at most (width) integers that should be 0 <= x < (width).
+//
+// The g(count) method returns a pseudorandom integer that concatenates
+// the next (count) outputs from ARC4.  Its return value is a number x
+// that is in the range 0 <= x < (width ^ count).
+//
+    function ARC4(key) {
+        var t, keylen = key.length,
+            me = this, i = 0, j = me.i = me.j = 0, s = me.S = [];
+
+        // The empty key [] is treated as [0].
+        if (!keylen) { key = [keylen++]; }
+
+        // Set up S using the standard key scheduling algorithm.
+        while (i < width) {
+            s[i] = i++;
+        }
+        for (i = 0; i < width; i++) {
+            s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))];
+            s[j] = t;
+        }
+
+        // The "g" method returns the next (count) outputs as one number.
+        me.g = function(count) {
+            // Using instance members instead of closure state nearly doubles speed.
+            var t, r = 0,
+                i = me.i, j = me.j, s = me.S;
+            while (count--) {
+                t = s[i = mask & (i + 1)];
+                r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))];
+            }
+            me.i = i; me.j = j;
+            return r;
+            // For robust unpredictability, the function call below automatically
+            // discards an initial batch of values.  This is called RC4-drop[256].
+            // See http://google.com/search?q=rsa+fluhrer+response&btnI
+        };
+    }
+
+//
+// copy()
+// Copies internal state of ARC4 to or from a plain object.
+//
+    function copy(f, t) {
+        t.i = f.i;
+        t.j = f.j;
+        t.S = f.S.slice();
+        return t;
+    }
+
+//
+// flatten()
+// Converts an object tree to nested arrays of strings.
+//
+    function flatten(obj, depth) {
+        var result = [], typ = (typeof obj), prop;
+        if (depth && typ == 'object') {
+            for (prop in obj) {
+                try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}
+            }
+        }
+        return (result.length ? result : typ == 'string' ? obj : obj + '\0');
+    }
+
+//
+// mixkey()
+// Mixes a string seed into a key that is an array of integers, and
+// returns a shortened string seed that is equivalent to the result key.
+//
+    function mixkey(seed, key) {
+        var stringseed = seed + '', smear, j = 0;
+        while (j < stringseed.length) {
+            key[mask & j] =
+                mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++));
+        }
+        return tostring(key);
+    }
+
+//
+// autoseed()
+// Returns an object for autoseeding, using window.crypto and Node crypto
+// module if available.
+//
+    function autoseed() {
+        try {
+            if (nodecrypto) { return tostring(nodecrypto.randomBytes(width)); }
+            var out = new Uint8Array(width);
+            (global.crypto || global.msCrypto).getRandomValues(out);
+            return tostring(out);
+        } catch (e) {
+            var browser = global.navigator,
+                plugins = browser && browser.plugins;
+            return [+new Date(), global, plugins, global.screen, tostring(pool)];
+        }
+    }
+
+//
+// tostring()
+// Converts an array of charcodes to a string
+//
+    function tostring(a) {
+        return String.fromCharCode.apply(0, a);
+    }
+
+//
+// When seedrandom.js is loaded, we immediately mix a few bits
+// from the built-in RNG into the entropy pool.  Because we do
+// not want to interfere with deterministic PRNG state later,
+// seedrandom will not call math.random on its own again after
+// initialization.
+//
+    mixkey(math.random(), pool);
+
+//
+// Nodejs and AMD support: export the implementation as a module using
+// either convention.
+//
+
+// End anonymous scope, and pass initial values.
+};
+
+function initialize$2(BMMath) {
+    seedRandom([], BMMath);
+}
+
+var propTypes = {
+  SHAPE: 'shape',
+};
+
+/* eslint-disable camelcase */
+
+const ExpressionManager = (function () {
+  'use strict';
+
+  var ob = {};
+  var Math = BMMath;
+  var window = null;
+  var document = null;
+  var XMLHttpRequest = null;
+  var fetch = null;
+  var frames = null;
+  var _lottieGlobal = {};
+  initialize$2(BMMath);
+
+  function resetFrame() {
+    _lottieGlobal = {};
+  }
+
+  function $bm_isInstanceOfArray(arr) {
+    return arr.constructor === Array || arr.constructor === Float32Array;
+  }
+
+  function isNumerable(tOfV, v) {
+    return tOfV === 'number' || v instanceof Number || tOfV === 'boolean' || tOfV === 'string';
+  }
+
+  function $bm_neg(a) {
+    var tOfA = typeof a;
+    if (tOfA === 'number' || a instanceof Number || tOfA === 'boolean') {
+      return -a;
+    }
+    if ($bm_isInstanceOfArray(a)) {
+      var i;
+      var lenA = a.length;
+      var retArr = [];
+      for (i = 0; i < lenA; i += 1) {
+        retArr[i] = -a[i];
+      }
+      return retArr;
+    }
+    if (a.propType) {
+      return a.v;
+    }
+    return -a;
+  }
+
+  var easeInBez = BezierFactory.getBezierEasing(0.333, 0, 0.833, 0.833, 'easeIn').get;
+  var easeOutBez = BezierFactory.getBezierEasing(0.167, 0.167, 0.667, 1, 'easeOut').get;
+  var easeInOutBez = BezierFactory.getBezierEasing(0.33, 0, 0.667, 1, 'easeInOut').get;
+
+  function sum(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    if ((isNumerable(tOfA, a) && isNumerable(tOfB, b)) || tOfA === 'string' || tOfB === 'string') {
+      return a + b;
+    }
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      a = a.slice(0);
+      a[0] += b;
+      return a;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      b = b.slice(0);
+      b[0] = a + b[0];
+      return b;
+    }
+    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
+      var i = 0;
+      var lenA = a.length;
+      var lenB = b.length;
+      var retArr = [];
+      while (i < lenA || i < lenB) {
+        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
+          retArr[i] = a[i] + b[i];
+        } else {
+          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
+        }
+        i += 1;
+      }
+      return retArr;
+    }
+    return 0;
+  }
+  var add = sum;
+
+  function sub(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      if (tOfA === 'string') {
+        a = parseInt(a, 10);
+      }
+      if (tOfB === 'string') {
+        b = parseInt(b, 10);
+      }
+      return a - b;
+    }
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      a = a.slice(0);
+      a[0] -= b;
+      return a;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      b = b.slice(0);
+      b[0] = a - b[0];
+      return b;
+    }
+    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
+      var i = 0;
+      var lenA = a.length;
+      var lenB = b.length;
+      var retArr = [];
+      while (i < lenA || i < lenB) {
+        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
+          retArr[i] = a[i] - b[i];
+        } else {
+          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
+        }
+        i += 1;
+      }
+      return retArr;
+    }
+    return 0;
+  }
+
+  function mul(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    var arr;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      return a * b;
+    }
+
+    var i;
+    var len;
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      len = a.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a[i] * b;
+      }
+      return arr;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      len = b.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a * b[i];
+      }
+      return arr;
+    }
+    return 0;
+  }
+
+  function div(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    var arr;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      return a / b;
+    }
+    var i;
+    var len;
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      len = a.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a[i] / b;
+      }
+      return arr;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      len = b.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a / b[i];
+      }
+      return arr;
+    }
+    return 0;
+  }
+  function mod(a, b) {
+    if (typeof a === 'string') {
+      a = parseInt(a, 10);
+    }
+    if (typeof b === 'string') {
+      b = parseInt(b, 10);
+    }
+    return a % b;
+  }
+  var $bm_sum = sum;
+  var $bm_sub = sub;
+  var $bm_mul = mul;
+  var $bm_div = div;
+  var $bm_mod = mod;
+
+  function clamp(num, min, max) {
+    if (min > max) {
+      var mm = max;
+      max = min;
+      min = mm;
+    }
+    return Math.min(Math.max(num, min), max);
+  }
+
+  function radiansToDegrees(val) {
+    return val / degToRads;
+  }
+  var radians_to_degrees = radiansToDegrees;
+
+  function degreesToRadians(val) {
+    return val * degToRads;
+  }
+  var degrees_to_radians = radiansToDegrees;
+
+  var helperLengthArray = [0, 0, 0, 0, 0, 0];
+
+  function length(arr1, arr2) {
+    if (typeof arr1 === 'number' || arr1 instanceof Number) {
+      arr2 = arr2 || 0;
+      return Math.abs(arr1 - arr2);
+    }
+    if (!arr2) {
+      arr2 = helperLengthArray;
+    }
+    var i;
+    var len = Math.min(arr1.length, arr2.length);
+    var addedLength = 0;
+    for (i = 0; i < len; i += 1) {
+      addedLength += Math.pow(arr2[i] - arr1[i], 2);
+    }
+    return Math.sqrt(addedLength);
+  }
+
+  function normalize(vec) {
+    return div(vec, length(vec));
+  }
+
+  function rgbToHsl(val) {
+    var r = val[0]; var g = val[1]; var b = val[2];
+    var max = Math.max(r, g, b);
+    var min = Math.min(r, g, b);
+    var h;
+    var s;
+    var l = (max + min) / 2;
+
+    if (max === min) {
+      h = 0; // achromatic
+      s = 0; // achromatic
+    } else {
+      var d = max - min;
+      s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+      switch (max) {
+        case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+        case g: h = (b - r) / d + 2; break;
+        case b: h = (r - g) / d + 4; break;
+        default: break;
+      }
+      h /= 6;
+    }
+
+    return [h, s, l, val[3]];
+  }
+
+  function hue2rgb(p, q, t) {
+    if (t < 0) t += 1;
+    if (t > 1) t -= 1;
+    if (t < 1 / 6) return p + (q - p) * 6 * t;
+    if (t < 1 / 2) return q;
+    if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
+    return p;
+  }
+
+  function hslToRgb(val) {
+    var h = val[0];
+    var s = val[1];
+    var l = val[2];
+
+    var r;
+    var g;
+    var b;
+
+    if (s === 0) {
+      r = l; // achromatic
+      b = l; // achromatic
+      g = l; // achromatic
+    } else {
+      var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+      var p = 2 * l - q;
+      r = hue2rgb(p, q, h + 1 / 3);
+      g = hue2rgb(p, q, h);
+      b = hue2rgb(p, q, h - 1 / 3);
+    }
+
+    return [r, g, b, val[3]];
+  }
+
+  function linear(t, tMin, tMax, value1, value2) {
+    if (value1 === undefined || value2 === undefined) {
+      value1 = tMin;
+      value2 = tMax;
+      tMin = 0;
+      tMax = 1;
+    }
+    if (tMax < tMin) {
+      var _tMin = tMax;
+      tMax = tMin;
+      tMin = _tMin;
+    }
+    if (t <= tMin) {
+      return value1;
+    } if (t >= tMax) {
+      return value2;
+    }
+    var perc = tMax === tMin ? 0 : (t - tMin) / (tMax - tMin);
+    if (!value1.length) {
+      return value1 + (value2 - value1) * perc;
+    }
+    var i;
+    var len = value1.length;
+    var arr = createTypedArray('float32', len);
+    for (i = 0; i < len; i += 1) {
+      arr[i] = value1[i] + (value2[i] - value1[i]) * perc;
+    }
+    return arr;
+  }
+  function random(min, max) {
+    if (max === undefined) {
+      if (min === undefined) {
+        min = 0;
+        max = 1;
+      } else {
+        max = min;
+        min = undefined;
+      }
+    }
+    if (max.length) {
+      var i;
+      var len = max.length;
+      if (!min) {
+        min = createTypedArray('float32', len);
+      }
+      var arr = createTypedArray('float32', len);
+      var rnd = BMMath.random();
+      for (i = 0; i < len; i += 1) {
+        arr[i] = min[i] + rnd * (max[i] - min[i]);
+      }
+      return arr;
+    }
+    if (min === undefined) {
+      min = 0;
+    }
+    var rndm = BMMath.random();
+    return min + rndm * (max - min);
+  }
+
+  function createPath(points, inTangents, outTangents, closed) {
+    var i;
+    var len = points.length;
+    var path = shapePool.newElement();
+    path.setPathData(!!closed, len);
+    var arrPlaceholder = [0, 0];
+    var inVertexPoint;
+    var outVertexPoint;
+    for (i = 0; i < len; i += 1) {
+      inVertexPoint = (inTangents && inTangents[i]) ? inTangents[i] : arrPlaceholder;
+      outVertexPoint = (outTangents && outTangents[i]) ? outTangents[i] : arrPlaceholder;
+      path.setTripleAt(points[i][0], points[i][1], outVertexPoint[0] + points[i][0], outVertexPoint[1] + points[i][1], inVertexPoint[0] + points[i][0], inVertexPoint[1] + points[i][1], i, true);
+    }
+    return path;
+  }
+
+  function initiateExpression(elem, data, property) {
+    // Bail out if we don't want expressions
+    function noOp(_value) {
+      return _value;
+    }
+    if (!elem.globalData.renderConfig.runExpressions) {
+      return noOp;
+    }
+
+    var val = data.x;
+    var needsVelocity = /velocity(?![\w\d])/.test(val);
+    var _needsRandom = val.indexOf('random') !== -1;
+    var elemType = elem.data.ty;
+    var transform;
+    var $bm_transform;
+    var content;
+    var effect;
+    var thisProperty = property;
+    thisProperty._name = elem.data.nm;
+    thisProperty.valueAtTime = thisProperty.getValueAtTime;
+    Object.defineProperty(thisProperty, 'value', {
+      get: function () {
+        return thisProperty.v;
+      },
+    });
+    elem.comp.frameDuration = 1 / elem.comp.globalData.frameRate;
+    elem.comp.displayStartTime = 0;
+    var inPoint = elem.data.ip / elem.comp.globalData.frameRate;
+    var outPoint = elem.data.op / elem.comp.globalData.frameRate;
+    var width = elem.data.sw ? elem.data.sw : 0;
+    var height = elem.data.sh ? elem.data.sh : 0;
+    var name = elem.data.nm;
+    var loopIn;
+    var loop_in;
+    var loopOut;
+    var loop_out;
+    var smooth;
+    var toWorld;
+    var fromWorld;
+    var fromComp;
+    var toComp;
+    var fromCompToSurface;
+    var position;
+    var rotation;
+    var anchorPoint;
+    var scale;
+    var thisLayer;
+    var thisComp;
+    var mask;
+    var valueAtTime;
+    var velocityAtTime;
+
+    var scoped_bm_rt;
+    // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
+    var expression_function = eval('[function _expression_function(){' + val + ';scoped_bm_rt=$bm_rt}]')[0]; // eslint-disable-line no-eval
+    var numKeys = property.kf ? data.k.length : 0;
+
+    var active = !this.data || this.data.hd !== true;
+
+    var wiggle = function wiggle(freq, amp) {
+      var iWiggle;
+      var j;
+      var lenWiggle = this.pv.length ? this.pv.length : 1;
+      var addedAmps = createTypedArray('float32', lenWiggle);
+      freq = 5;
+      var iterations = Math.floor(time * freq);
+      iWiggle = 0;
+      j = 0;
+      while (iWiggle < iterations) {
+        // var rnd = BMMath.random();
+        for (j = 0; j < lenWiggle; j += 1) {
+          addedAmps[j] += -amp + amp * 2 * BMMath.random();
+          // addedAmps[j] += -amp + amp*2*rnd;
+        }
+        iWiggle += 1;
+      }
+      // var rnd2 = BMMath.random();
+      var periods = time * freq;
+      var perc = periods - Math.floor(periods);
+      var arr = createTypedArray('float32', lenWiggle);
+      if (lenWiggle > 1) {
+        for (j = 0; j < lenWiggle; j += 1) {
+          arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc;
+          // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
+          // arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc);
+        }
+        return arr;
+      }
+      return this.pv + addedAmps[0] + (-amp + amp * 2 * BMMath.random()) * perc;
+    }.bind(this);
+
+    if (thisProperty.loopIn) {
+      loopIn = thisProperty.loopIn.bind(thisProperty);
+      loop_in = loopIn;
+    }
+
+    if (thisProperty.loopOut) {
+      loopOut = thisProperty.loopOut.bind(thisProperty);
+      loop_out = loopOut;
+    }
+
+    if (thisProperty.smooth) {
+      smooth = thisProperty.smooth.bind(thisProperty);
+    }
+
+    function loopInDuration(type, duration) {
+      return loopIn(type, duration, true);
+    }
+
+    function loopOutDuration(type, duration) {
+      return loopOut(type, duration, true);
+    }
+
+    if (this.getValueAtTime) {
+      valueAtTime = this.getValueAtTime.bind(this);
+    }
+
+    if (this.getVelocityAtTime) {
+      velocityAtTime = this.getVelocityAtTime.bind(this);
+    }
+
+    var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface);
+
+    function lookAt(elem1, elem2) {
+      var fVec = [elem2[0] - elem1[0], elem2[1] - elem1[1], elem2[2] - elem1[2]];
+      var pitch = Math.atan2(fVec[0], Math.sqrt(fVec[1] * fVec[1] + fVec[2] * fVec[2])) / degToRads;
+      var yaw = -Math.atan2(fVec[1], fVec[2]) / degToRads;
+      return [yaw, pitch, 0];
+    }
+
+    function easeOut(t, tMin, tMax, val1, val2) {
+      return applyEase(easeOutBez, t, tMin, tMax, val1, val2);
+    }
+
+    function easeIn(t, tMin, tMax, val1, val2) {
+      return applyEase(easeInBez, t, tMin, tMax, val1, val2);
+    }
+
+    function ease(t, tMin, tMax, val1, val2) {
+      return applyEase(easeInOutBez, t, tMin, tMax, val1, val2);
+    }
+
+    function applyEase(fn, t, tMin, tMax, val1, val2) {
+      if (val1 === undefined) {
+        val1 = tMin;
+        val2 = tMax;
+      } else {
+        t = (t - tMin) / (tMax - tMin);
+      }
+      if (t > 1) {
+        t = 1;
+      } else if (t < 0) {
+        t = 0;
+      }
+      var mult = fn(t);
+      if ($bm_isInstanceOfArray(val1)) {
+        var iKey;
+        var lenKey = val1.length;
+        var arr = createTypedArray('float32', lenKey);
+        for (iKey = 0; iKey < lenKey; iKey += 1) {
+          arr[iKey] = (val2[iKey] - val1[iKey]) * mult + val1[iKey];
+        }
+        return arr;
+      }
+      return (val2 - val1) * mult + val1;
+    }
+
+    function nearestKey(time) {
+      var iKey;
+      var lenKey = data.k.length;
+      var index;
+      var keyTime;
+      if (!data.k.length || typeof (data.k[0]) === 'number') {
+        index = 0;
+        keyTime = 0;
+      } else {
+        index = -1;
+        time *= elem.comp.globalData.frameRate;
+        if (time < data.k[0].t) {
+          index = 1;
+          keyTime = data.k[0].t;
+        } else {
+          for (iKey = 0; iKey < lenKey - 1; iKey += 1) {
+            if (time === data.k[iKey].t) {
+              index = iKey + 1;
+              keyTime = data.k[iKey].t;
+              break;
+            } else if (time > data.k[iKey].t && time < data.k[iKey + 1].t) {
+              if (time - data.k[iKey].t > data.k[iKey + 1].t - time) {
+                index = iKey + 2;
+                keyTime = data.k[iKey + 1].t;
+              } else {
+                index = iKey + 1;
+                keyTime = data.k[iKey].t;
+              }
+              break;
+            }
+          }
+          if (index === -1) {
+            index = iKey + 1;
+            keyTime = data.k[iKey].t;
+          }
+        }
+      }
+      var obKey = {};
+      obKey.index = index;
+      obKey.time = keyTime / elem.comp.globalData.frameRate;
+      return obKey;
+    }
+
+    function key(ind) {
+      var obKey;
+      var iKey;
+      var lenKey;
+      if (!data.k.length || typeof (data.k[0]) === 'number') {
+        throw new Error('The property has no keyframe at index ' + ind);
+      }
+      ind -= 1;
+      obKey = {
+        time: data.k[ind].t / elem.comp.globalData.frameRate,
+        value: [],
+      };
+      var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e;
+
+      lenKey = arr.length;
+      for (iKey = 0; iKey < lenKey; iKey += 1) {
+        obKey[iKey] = arr[iKey];
+        obKey.value[iKey] = arr[iKey];
+      }
+      return obKey;
+    }
+
+    function framesToTime(fr, fps) {
+      if (!fps) {
+        fps = elem.comp.globalData.frameRate;
+      }
+      return fr / fps;
+    }
+
+    function timeToFrames(t, fps) {
+      if (!t && t !== 0) {
+        t = time;
+      }
+      if (!fps) {
+        fps = elem.comp.globalData.frameRate;
+      }
+      return t * fps;
+    }
+
+    function seedRandom(seed) {
+      BMMath.seedrandom(randSeed + seed);
+    }
+
+    function sourceRectAtTime() {
+      return elem.sourceRectAtTime();
+    }
+
+    function substring(init, end) {
+      if (typeof value === 'string') {
+        if (end === undefined) {
+          return value.substring(init);
+        }
+        return value.substring(init, end);
+      }
+      return '';
+    }
+
+    function substr(init, end) {
+      if (typeof value === 'string') {
+        if (end === undefined) {
+          return value.substr(init);
+        }
+        return value.substr(init, end);
+      }
+      return '';
+    }
+
+    function posterizeTime(framesPerSecond) {
+      time = framesPerSecond === 0 ? 0 : Math.floor(time * framesPerSecond) / framesPerSecond;
+      value = valueAtTime(time);
+    }
+
+    var time;
+    var velocity;
+    var value;
+    var text;
+    var textIndex;
+    var textTotal;
+    var selectorValue;
+    var index = elem.data.ind;
+    var hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+    var parent;
+    var randSeed = Math.floor(Math.random() * 1000000);
+    var globalData = elem.globalData;
+
+    function executeExpression(_value) {
+      // globalData.pushExpression();
+      value = _value;
+      if (this.frameExpressionId === elem.globalData.frameId && this.propType !== 'textSelector') {
+        return value;
+      }
+      if (this.propType === 'textSelector') {
+        textIndex = this.textIndex;
+        textTotal = this.textTotal;
+        selectorValue = this.selectorValue;
+      }
+      if (!thisLayer) {
+        text = elem.layerInterface.text;
+        thisLayer = elem.layerInterface;
+        thisComp = elem.comp.compInterface;
+        toWorld = thisLayer.toWorld.bind(thisLayer);
+        fromWorld = thisLayer.fromWorld.bind(thisLayer);
+        fromComp = thisLayer.fromComp.bind(thisLayer);
+        toComp = thisLayer.toComp.bind(thisLayer);
+        mask = thisLayer.mask ? thisLayer.mask.bind(thisLayer) : null;
+        fromCompToSurface = fromComp;
+      }
+      if (!transform) {
+        transform = elem.layerInterface('ADBE Transform Group');
+        $bm_transform = transform;
+        if (transform) {
+          anchorPoint = transform.anchorPoint;
+          /* position = transform.position;
+                    rotation = transform.rotation;
+                    scale = transform.scale; */
+        }
+      }
+
+      if (elemType === 4 && !content) {
+        content = thisLayer('ADBE Root Vectors Group');
+      }
+      if (!effect) {
+        effect = thisLayer(4);
+      }
+      hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+      if (hasParent && !parent) {
+        parent = elem.hierarchy[0].layerInterface;
+      }
+      time = this.comp.renderedFrame / this.comp.globalData.frameRate;
+      if (_needsRandom) {
+        seedRandom(randSeed + time);
+      }
+      if (needsVelocity) {
+        velocity = velocityAtTime(time);
+      }
+      expression_function();
+      this.frameExpressionId = elem.globalData.frameId;
+
+      // TODO: Check if it's possible to return on ShapeInterface the .v value
+      // Changed this to a ternary operation because Rollup failed compiling it correctly
+      scoped_bm_rt = scoped_bm_rt.propType === propTypes.SHAPE
+        ? scoped_bm_rt.v
+        : scoped_bm_rt;
+      return scoped_bm_rt;
+    }
+    // Bundlers will see these as dead code and unless we reference them
+    executeExpression.__preventDeadCodeRemoval = [$bm_transform, anchorPoint, time, velocity, inPoint, outPoint, width, height, name, loop_in, loop_out, smooth, toComp, fromCompToSurface, toWorld, fromWorld, mask, position, rotation, scale, thisComp, numKeys, active, wiggle, loopInDuration, loopOutDuration, comp, lookAt, easeOut, easeIn, ease, nearestKey, key, text, textIndex, textTotal, selectorValue, framesToTime, timeToFrames, sourceRectAtTime, substring, substr, posterizeTime, index, globalData];
+    return executeExpression;
+  }
+
+  ob.initiateExpression = initiateExpression;
+  ob.__preventDeadCodeRemoval = [window, document, XMLHttpRequest, fetch, frames, $bm_neg, add, $bm_sum, $bm_sub, $bm_mul, $bm_div, $bm_mod, clamp, radians_to_degrees, degreesToRadians, degrees_to_radians, normalize, rgbToHsl, hslToRgb, linear, random, createPath, _lottieGlobal];
+  ob.resetFrame = resetFrame;
+  return ob;
+}());
+
+const Expressions = (function () {
+  var ob = {};
+  ob.initExpressions = initExpressions;
+  ob.resetFrame = ExpressionManager.resetFrame;
+
+  function initExpressions(animation) {
+    var stackCount = 0;
+    var registers = [];
+
+    function pushExpression() {
+      stackCount += 1;
+    }
+
+    function popExpression() {
+      stackCount -= 1;
+      if (stackCount === 0) {
+        releaseInstances();
+      }
+    }
+
+    function registerExpressionProperty(expression) {
+      if (registers.indexOf(expression) === -1) {
+        registers.push(expression);
+      }
+    }
+
+    function releaseInstances() {
+      var i;
+      var len = registers.length;
+      for (i = 0; i < len; i += 1) {
+        registers[i].release();
+      }
+      registers.length = 0;
+    }
+
+    animation.renderer.compInterface = CompExpressionInterface(animation.renderer);
+    animation.renderer.globalData.projectInterface.registerComposition(animation.renderer);
+    animation.renderer.globalData.pushExpression = pushExpression;
+    animation.renderer.globalData.popExpression = popExpression;
+    animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty;
+  }
+  return ob;
+}());
+
+const MaskManagerInterface = (function () {
+  function MaskInterface(mask, data) {
+    this._mask = mask;
+    this._data = data;
+  }
+  Object.defineProperty(MaskInterface.prototype, 'maskPath', {
+    get: function () {
+      if (this._mask.prop.k) {
+        this._mask.prop.getValue();
+      }
+      return this._mask.prop;
+    },
+  });
+  Object.defineProperty(MaskInterface.prototype, 'maskOpacity', {
+    get: function () {
+      if (this._mask.op.k) {
+        this._mask.op.getValue();
+      }
+      return this._mask.op.v * 100;
+    },
+  });
+
+  var MaskManager = function (maskManager) {
+    var _masksInterfaces = createSizedArray(maskManager.viewData.length);
+    var i;
+    var len = maskManager.viewData.length;
+    for (i = 0; i < len; i += 1) {
+      _masksInterfaces[i] = new MaskInterface(maskManager.viewData[i], maskManager.masksProperties[i]);
+    }
+
+    var maskFunction = function (name) {
+      i = 0;
+      while (i < len) {
+        if (maskManager.masksProperties[i].nm === name) {
+          return _masksInterfaces[i];
+        }
+        i += 1;
+      }
+      return null;
+    };
+    return maskFunction;
+  };
+  return MaskManager;
+}());
+
+const ExpressionPropertyInterface = (function () {
+  var defaultUnidimensionalValue = { pv: 0, v: 0, mult: 1 };
+  var defaultMultidimensionalValue = { pv: [0, 0, 0], v: [0, 0, 0], mult: 1 };
+
+  function completeProperty(expressionValue, property, type) {
+    Object.defineProperty(expressionValue, 'velocity', {
+      get: function () {
+        return property.getVelocityAtTime(property.comp.currentFrame);
+      },
+    });
+    expressionValue.numKeys = property.keyframes ? property.keyframes.length : 0;
+    expressionValue.key = function (pos) {
+      if (!expressionValue.numKeys) {
+        return 0;
+      }
+      var value = '';
+      if ('s' in property.keyframes[pos - 1]) {
+        value = property.keyframes[pos - 1].s;
+      } else if ('e' in property.keyframes[pos - 2]) {
+        value = property.keyframes[pos - 2].e;
+      } else {
+        value = property.keyframes[pos - 2].s;
+      }
+      var valueProp = type === 'unidimensional' ? new Number(value) : Object.assign({}, value); // eslint-disable-line no-new-wrappers
+      valueProp.time = property.keyframes[pos - 1].t / property.elem.comp.globalData.frameRate;
+      valueProp.value = type === 'unidimensional' ? value[0] : value;
+      return valueProp;
+    };
+    expressionValue.valueAtTime = property.getValueAtTime;
+    expressionValue.speedAtTime = property.getSpeedAtTime;
+    expressionValue.velocityAtTime = property.getVelocityAtTime;
+    expressionValue.propertyGroup = property.propertyGroup;
+  }
+
+  function UnidimensionalPropertyInterface(property) {
+    if (!property || !('pv' in property)) {
+      property = defaultUnidimensionalValue;
+    }
+    var mult = 1 / property.mult;
+    var val = property.pv * mult;
+    var expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
+    expressionValue.value = val;
+    completeProperty(expressionValue, property, 'unidimensional');
+
+    return function () {
+      if (property.k) {
+        property.getValue();
+      }
+      val = property.v * mult;
+      if (expressionValue.value !== val) {
+        expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
+        expressionValue.value = val;
+        expressionValue[0] = val;
+        completeProperty(expressionValue, property, 'unidimensional');
+      }
+      return expressionValue;
+    };
+  }
+
+  function MultidimensionalPropertyInterface(property) {
+    if (!property || !('pv' in property)) {
+      property = defaultMultidimensionalValue;
+    }
+    var mult = 1 / property.mult;
+    var len = (property.data && property.data.l) || property.pv.length;
+    var expressionValue = createTypedArray('float32', len);
+    var arrValue = createTypedArray('float32', len);
+    expressionValue.value = arrValue;
+    completeProperty(expressionValue, property, 'multidimensional');
+
+    return function () {
+      if (property.k) {
+        property.getValue();
+      }
+      for (var i = 0; i < len; i += 1) {
+        arrValue[i] = property.v[i] * mult;
+        expressionValue[i] = arrValue[i];
+      }
+      return expressionValue;
+    };
+  }
+
+  // TODO: try to avoid using this getter
+  function defaultGetter() {
+    return defaultUnidimensionalValue;
+  }
+
+  return function (property) {
+    if (!property) {
+      return defaultGetter;
+    } if (property.propType === 'unidimensional') {
+      return UnidimensionalPropertyInterface(property);
+    }
+    return MultidimensionalPropertyInterface(property);
+  };
+}());
+
+const TransformExpressionInterface = (function () {
+  return function (transform) {
+    function _thisFunction(name) {
+      switch (name) {
+        case 'scale':
+        case 'Scale':
+        case 'ADBE Scale':
+        case 6:
+          return _thisFunction.scale;
+        case 'rotation':
+        case 'Rotation':
+        case 'ADBE Rotation':
+        case 'ADBE Rotate Z':
+        case 10:
+          return _thisFunction.rotation;
+        case 'ADBE Rotate X':
+          return _thisFunction.xRotation;
+        case 'ADBE Rotate Y':
+          return _thisFunction.yRotation;
+        case 'position':
+        case 'Position':
+        case 'ADBE Position':
+        case 2:
+          return _thisFunction.position;
+        case 'ADBE Position_0':
+          return _thisFunction.xPosition;
+        case 'ADBE Position_1':
+          return _thisFunction.yPosition;
+        case 'ADBE Position_2':
+          return _thisFunction.zPosition;
+        case 'anchorPoint':
+        case 'AnchorPoint':
+        case 'Anchor Point':
+        case 'ADBE AnchorPoint':
+        case 1:
+          return _thisFunction.anchorPoint;
+        case 'opacity':
+        case 'Opacity':
+        case 11:
+          return _thisFunction.opacity;
+        default:
+          return null;
+      }
+    }
+    Object.defineProperty(_thisFunction, 'rotation', {
+      get: ExpressionPropertyInterface(transform.r || transform.rz),
+    });
+
+    Object.defineProperty(_thisFunction, 'zRotation', {
+      get: ExpressionPropertyInterface(transform.rz || transform.r),
+    });
+
+    Object.defineProperty(_thisFunction, 'xRotation', {
+      get: ExpressionPropertyInterface(transform.rx),
+    });
+
+    Object.defineProperty(_thisFunction, 'yRotation', {
+      get: ExpressionPropertyInterface(transform.ry),
+    });
+    Object.defineProperty(_thisFunction, 'scale', {
+      get: ExpressionPropertyInterface(transform.s),
+    });
+    var _px;
+    var _py;
+    var _pz;
+    var _transformFactory;
+    if (transform.p) {
+      _transformFactory = ExpressionPropertyInterface(transform.p);
+    } else {
+      _px = ExpressionPropertyInterface(transform.px);
+      _py = ExpressionPropertyInterface(transform.py);
+      if (transform.pz) {
+        _pz = ExpressionPropertyInterface(transform.pz);
+      }
+    }
+    Object.defineProperty(_thisFunction, 'position', {
+      get: function () {
+        if (transform.p) {
+          return _transformFactory();
+        }
+        return [
+          _px(),
+          _py(),
+          _pz ? _pz() : 0];
+      },
+    });
+
+    Object.defineProperty(_thisFunction, 'xPosition', {
+      get: ExpressionPropertyInterface(transform.px),
+    });
+
+    Object.defineProperty(_thisFunction, 'yPosition', {
+      get: ExpressionPropertyInterface(transform.py),
+    });
+
+    Object.defineProperty(_thisFunction, 'zPosition', {
+      get: ExpressionPropertyInterface(transform.pz),
+    });
+
+    Object.defineProperty(_thisFunction, 'anchorPoint', {
+      get: ExpressionPropertyInterface(transform.a),
+    });
+
+    Object.defineProperty(_thisFunction, 'opacity', {
+      get: ExpressionPropertyInterface(transform.o),
+    });
+
+    Object.defineProperty(_thisFunction, 'skew', {
+      get: ExpressionPropertyInterface(transform.sk),
+    });
+
+    Object.defineProperty(_thisFunction, 'skewAxis', {
+      get: ExpressionPropertyInterface(transform.sa),
+    });
+
+    Object.defineProperty(_thisFunction, 'orientation', {
+      get: ExpressionPropertyInterface(transform.or),
+    });
+
+    return _thisFunction;
+  };
+}());
+
+const LayerExpressionInterface = (function () {
+  function getMatrix(time) {
+    var toWorldMat = new Matrix();
+    if (time !== undefined) {
+      var propMatrix = this._elem.finalTransform.mProp.getValueAtTime(time);
+      propMatrix.clone(toWorldMat);
+    } else {
+      var transformMat = this._elem.finalTransform.mProp;
+      transformMat.applyToMatrix(toWorldMat);
+    }
+    return toWorldMat;
+  }
+
+  function toWorldVec(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    toWorldMat.props[12] = 0;
+    toWorldMat.props[13] = 0;
+    toWorldMat.props[14] = 0;
+    return this.applyPoint(toWorldMat, arr);
+  }
+
+  function toWorld(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    return this.applyPoint(toWorldMat, arr);
+  }
+
+  function fromWorldVec(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    toWorldMat.props[12] = 0;
+    toWorldMat.props[13] = 0;
+    toWorldMat.props[14] = 0;
+    return this.invertPoint(toWorldMat, arr);
+  }
+
+  function fromWorld(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    return this.invertPoint(toWorldMat, arr);
+  }
+
+  function applyPoint(matrix, arr) {
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
+      }
+    }
+    return matrix.applyToPointArray(arr[0], arr[1], arr[2] || 0);
+  }
+
+  function invertPoint(matrix, arr) {
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
+      }
+    }
+    return matrix.inversePoint(arr);
+  }
+
+  function fromComp(arr) {
+    var toWorldMat = new Matrix();
+    toWorldMat.reset();
+    this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
+      }
+      return toWorldMat.inversePoint(arr);
+    }
+    return toWorldMat.inversePoint(arr);
+  }
+
+  function sampleImage() {
+    return [1, 1, 1, 1];
+  }
+
+  return function (elem) {
+    var transformInterface;
+
+    function _registerMaskInterface(maskManager) {
+      _thisLayerFunction.mask = new MaskManagerInterface(maskManager, elem);
+    }
+    function _registerEffectsInterface(effects) {
+      _thisLayerFunction.effect = effects;
+    }
+
+    function _thisLayerFunction(name) {
+      switch (name) {
+        case 'ADBE Root Vectors Group':
+        case 'Contents':
+        case 2:
+          return _thisLayerFunction.shapeInterface;
+        case 1:
+        case 6:
+        case 'Transform':
+        case 'transform':
+        case 'ADBE Transform Group':
+          return transformInterface;
+        case 4:
+        case 'ADBE Effect Parade':
+        case 'effects':
+        case 'Effects':
+          return _thisLayerFunction.effect;
+        case 'ADBE Text Properties':
+          return _thisLayerFunction.textInterface;
+        default:
+          return null;
+      }
+    }
+    _thisLayerFunction.getMatrix = getMatrix;
+    _thisLayerFunction.invertPoint = invertPoint;
+    _thisLayerFunction.applyPoint = applyPoint;
+    _thisLayerFunction.toWorld = toWorld;
+    _thisLayerFunction.toWorldVec = toWorldVec;
+    _thisLayerFunction.fromWorld = fromWorld;
+    _thisLayerFunction.fromWorldVec = fromWorldVec;
+    _thisLayerFunction.toComp = toWorld;
+    _thisLayerFunction.fromComp = fromComp;
+    _thisLayerFunction.sampleImage = sampleImage;
+    _thisLayerFunction.sourceRectAtTime = elem.sourceRectAtTime.bind(elem);
+    _thisLayerFunction._elem = elem;
+    transformInterface = TransformExpressionInterface(elem.finalTransform.mProp);
+    var anchorPointDescriptor = getDescriptor(transformInterface, 'anchorPoint');
+    Object.defineProperties(_thisLayerFunction, {
+      hasParent: {
+        get: function () {
+          return elem.hierarchy.length;
+        },
+      },
+      parent: {
+        get: function () {
+          return elem.hierarchy[0].layerInterface;
+        },
+      },
+      rotation: getDescriptor(transformInterface, 'rotation'),
+      scale: getDescriptor(transformInterface, 'scale'),
+      position: getDescriptor(transformInterface, 'position'),
+      opacity: getDescriptor(transformInterface, 'opacity'),
+      anchorPoint: anchorPointDescriptor,
+      anchor_point: anchorPointDescriptor,
+      transform: {
+        get: function () {
+          return transformInterface;
+        },
+      },
+      active: {
+        get: function () {
+          return elem.isInRange;
+        },
+      },
+    });
+
+    _thisLayerFunction.startTime = elem.data.st;
+    _thisLayerFunction.index = elem.data.ind;
+    _thisLayerFunction.source = elem.data.refId;
+    _thisLayerFunction.height = elem.data.ty === 0 ? elem.data.h : 100;
+    _thisLayerFunction.width = elem.data.ty === 0 ? elem.data.w : 100;
+    _thisLayerFunction.inPoint = elem.data.ip / elem.comp.globalData.frameRate;
+    _thisLayerFunction.outPoint = elem.data.op / elem.comp.globalData.frameRate;
+    _thisLayerFunction._name = elem.data.nm;
+
+    _thisLayerFunction.registerMaskInterface = _registerMaskInterface;
+    _thisLayerFunction.registerEffectsInterface = _registerEffectsInterface;
+    return _thisLayerFunction;
+  };
+}());
+
+const propertyGroupFactory = (function () {
+  return function (interfaceFunction, parentPropertyGroup) {
+    return function (val) {
+      val = val === undefined ? 1 : val;
+      if (val <= 0) {
+        return interfaceFunction;
+      }
+      return parentPropertyGroup(val - 1);
+    };
+  };
+}());
+
+const PropertyInterface = (function () {
+  return function (propertyName, propertyGroup) {
+    var interfaceFunction = {
+      _name: propertyName,
+    };
+
+    function _propertyGroup(val) {
+      val = val === undefined ? 1 : val;
+      if (val <= 0) {
+        return interfaceFunction;
+      }
+      return propertyGroup(val - 1);
+    }
+
+    return _propertyGroup;
+  };
+}());
+
+const EffectsExpressionInterface = (function () {
+  var ob = {
+    createEffectsInterface: createEffectsInterface,
+  };
+
+  function createEffectsInterface(elem, propertyGroup) {
+    if (elem.effectsManager) {
+      var effectElements = [];
+      var effectsData = elem.data.ef;
+      var i;
+      var len = elem.effectsManager.effectElements.length;
+      for (i = 0; i < len; i += 1) {
+        effectElements.push(createGroupInterface(effectsData[i], elem.effectsManager.effectElements[i], propertyGroup, elem));
+      }
+
+      var effects = elem.data.ef || [];
+      var groupInterface = function (name) {
+        i = 0;
+        len = effects.length;
+        while (i < len) {
+          if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
+            return effectElements[i];
+          }
+          i += 1;
+        }
+        return null;
+      };
+      Object.defineProperty(groupInterface, 'numProperties', {
+        get: function () {
+          return effects.length;
+        },
+      });
+      return groupInterface;
+    }
+    return null;
+  }
+
+  function createGroupInterface(data, elements, propertyGroup, elem) {
+    function groupInterface(name) {
+      var effects = data.ef;
+      var i = 0;
+      var len = effects.length;
+      while (i < len) {
+        if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
+          if (effects[i].ty === 5) {
+            return effectElements[i];
+          }
+          return effectElements[i]();
+        }
+        i += 1;
+      }
+      throw new Error();
+    }
+    var _propertyGroup = propertyGroupFactory(groupInterface, propertyGroup);
+
+    var effectElements = [];
+    var i;
+    var len = data.ef.length;
+    for (i = 0; i < len; i += 1) {
+      if (data.ef[i].ty === 5) {
+        effectElements.push(createGroupInterface(data.ef[i], elements.effectElements[i], elements.effectElements[i].propertyGroup, elem));
+      } else {
+        effectElements.push(createValueInterface(elements.effectElements[i], data.ef[i].ty, elem, _propertyGroup));
+      }
+    }
+
+    if (data.mn === 'ADBE Color Control') {
+      Object.defineProperty(groupInterface, 'color', {
+        get: function () {
+          return effectElements[0]();
+        },
+      });
+    }
+    Object.defineProperties(groupInterface, {
+      numProperties: {
+        get: function () {
+          return data.np;
+        },
+      },
+      _name: { value: data.nm },
+      propertyGroup: { value: _propertyGroup },
+    });
+    groupInterface.enabled = data.en !== 0;
+    groupInterface.active = groupInterface.enabled;
+    return groupInterface;
+  }
+
+  function createValueInterface(element, type, elem, propertyGroup) {
+    var expressionProperty = ExpressionPropertyInterface(element.p);
+    function interfaceFunction() {
+      if (type === 10) {
+        return elem.comp.compInterface(element.p.v);
+      }
+      return expressionProperty();
+    }
+
+    if (element.p.setGroupProperty) {
+      element.p.setGroupProperty(PropertyInterface('', propertyGroup));
+    }
+
+    return interfaceFunction;
+  }
+
+  return ob;
+}());
+
+const ShapePathInterface = (
+
+  function () {
+    return function pathInterfaceFactory(shape, view, propertyGroup) {
+      var prop = view.sh;
+
+      function interfaceFunction(val) {
+        if (val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2) {
+          return interfaceFunction.path;
+        }
+        return null;
+      }
+
+      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+      prop.setGroupProperty(PropertyInterface('Path', _propertyGroup));
+      Object.defineProperties(interfaceFunction, {
+        path: {
+          get: function () {
+            if (prop.k) {
+              prop.getValue();
+            }
+            return prop;
+          },
+        },
+        shape: {
+          get: function () {
+            if (prop.k) {
+              prop.getValue();
+            }
+            return prop;
+          },
+        },
+        _name: { value: shape.nm },
+        ix: { value: shape.ix },
+        propertyIndex: { value: shape.ix },
+        mn: { value: shape.mn },
+        propertyGroup: { value: propertyGroup },
+      });
+      return interfaceFunction;
+    };
+  }()
+);
+
+const ShapeExpressionInterface = (function () {
+  function iterateElements(shapes, view, propertyGroup) {
+    var arr = [];
+    var i;
+    var len = shapes ? shapes.length : 0;
+    for (i = 0; i < len; i += 1) {
+      if (shapes[i].ty === 'gr') {
+        arr.push(groupInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'fl') {
+        arr.push(fillInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'st') {
+        arr.push(strokeInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'tm') {
+        arr.push(trimInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'tr') {
+        // arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
+      } else if (shapes[i].ty === 'el') {
+        arr.push(ellipseInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'sr') {
+        arr.push(starInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'sh') {
+        arr.push(ShapePathInterface(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'rc') {
+        arr.push(rectInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'rd') {
+        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;
+  }
+
+  function contentsInterfaceFactory(shape, view, propertyGroup) {
+    var interfaces;
+    var interfaceFunction = function _interfaceFunction(value) {
+      var i = 0;
+      var len = interfaces.length;
+      while (i < len) {
+        if (interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value) {
+          return interfaces[i];
+        }
+        i += 1;
+      }
+      if (typeof value === 'number') {
+        return interfaces[value - 1];
+      }
+      return null;
+    };
+
+    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup);
+    interfaceFunction.numProperties = interfaces.length;
+    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
+    interfaceFunction.transform = transformInterface;
+    interfaceFunction.propertyIndex = shape.cix;
+    interfaceFunction._name = shape.nm;
+
+    return interfaceFunction;
+  }
+
+  function groupInterfaceFactory(shape, view, propertyGroup) {
+    var interfaceFunction = function _interfaceFunction(value) {
+      switch (value) {
+        case 'ADBE Vectors Group':
+        case 'Contents':
+        case 2:
+          return interfaceFunction.content;
+          // Not necessary for now. Keeping them here in case a new case appears
+          // case 'ADBE Vector Transform Group':
+          // case 3:
+        default:
+          return interfaceFunction.transform;
+      }
+    };
+    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var content = contentsInterfaceFactory(shape, view, interfaceFunction.propertyGroup);
+    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
+    interfaceFunction.content = content;
+    interfaceFunction.transform = transformInterface;
+    Object.defineProperty(interfaceFunction, '_name', {
+      get: function () {
+        return shape.nm;
+      },
+    });
+    // interfaceFunction.content = interfaceFunction;
+    interfaceFunction.numProperties = shape.np;
+    interfaceFunction.propertyIndex = shape.ix;
+    interfaceFunction.nm = shape.nm;
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function fillInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      if (val === 'Color' || val === 'color') {
+        return interfaceFunction.color;
+      } if (val === 'Opacity' || val === 'opacity') {
+        return interfaceFunction.opacity;
+      }
+      return null;
+    }
+    Object.defineProperties(interfaceFunction, {
+      color: {
+        get: ExpressionPropertyInterface(view.c),
+      },
+      opacity: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      _name: { value: shape.nm },
+      mn: { value: shape.mn },
+    });
+
+    view.c.setGroupProperty(PropertyInterface('Color', propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
+    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 () {
+          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() {
+    function interfaceFunction() {
+      return null;
+    }
+    return interfaceFunction;
+  }
+
+  function strokeInterfaceFactory(shape, view, propertyGroup) {
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup);
+    function addPropertyToDashOb(i) {
+      Object.defineProperty(dashOb, shape.d[i].nm, {
+        get: ExpressionPropertyInterface(view.d.dataProps[i].p),
+      });
+    }
+    var i;
+    var len = shape.d ? shape.d.length : 0;
+    var dashOb = {};
+    for (i = 0; i < len; i += 1) {
+      addPropertyToDashOb(i);
+      view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup);
+    }
+
+    function interfaceFunction(val) {
+      if (val === 'Color' || val === 'color') {
+        return interfaceFunction.color;
+      } if (val === 'Opacity' || val === 'opacity') {
+        return interfaceFunction.opacity;
+      } if (val === 'Stroke Width' || val === 'stroke width') {
+        return interfaceFunction.strokeWidth;
+      }
+      return null;
+    }
+    Object.defineProperties(interfaceFunction, {
+      color: {
+        get: ExpressionPropertyInterface(view.c),
+      },
+      opacity: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      strokeWidth: {
+        get: ExpressionPropertyInterface(view.w),
+      },
+      dash: {
+        get: function () {
+          return dashOb;
+        },
+      },
+      _name: { value: shape.nm },
+      mn: { value: shape.mn },
+    });
+
+    view.c.setGroupProperty(PropertyInterface('Color', _propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    view.w.setGroupProperty(PropertyInterface('Stroke Width', _propertyGroup));
+    return interfaceFunction;
+  }
+
+  function trimInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      if (val === shape.e.ix || val === 'End' || val === 'end') {
+        return interfaceFunction.end;
+      }
+      if (val === shape.s.ix) {
+        return interfaceFunction.start;
+      }
+      if (val === shape.o.ix) {
+        return interfaceFunction.offset;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaceFunction.propertyIndex = shape.ix;
+
+    view.s.setGroupProperty(PropertyInterface('Start', _propertyGroup));
+    view.e.setGroupProperty(PropertyInterface('End', _propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
+    interfaceFunction.propertyIndex = shape.ix;
+    interfaceFunction.propertyGroup = propertyGroup;
+
+    Object.defineProperties(interfaceFunction, {
+      start: {
+        get: ExpressionPropertyInterface(view.s),
+      },
+      end: {
+        get: ExpressionPropertyInterface(view.e),
+      },
+      offset: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function transformInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.a.ix === value || value === 'Anchor Point') {
+        return interfaceFunction.anchorPoint;
+      }
+      if (shape.o.ix === value || value === 'Opacity') {
+        return interfaceFunction.opacity;
+      }
+      if (shape.p.ix === value || value === 'Position') {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value || value === 'Rotation' || value === 'ADBE Vector Rotation') {
+        return interfaceFunction.rotation;
+      }
+      if (shape.s.ix === value || value === 'Scale') {
+        return interfaceFunction.scale;
+      }
+      if ((shape.sk && shape.sk.ix === value) || value === 'Skew') {
+        return interfaceFunction.skew;
+      }
+      if ((shape.sa && shape.sa.ix === value) || value === 'Skew Axis') {
+        return interfaceFunction.skewAxis;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    view.transform.mProps.a.setGroupProperty(PropertyInterface('Anchor Point', _propertyGroup));
+    view.transform.mProps.s.setGroupProperty(PropertyInterface('Scale', _propertyGroup));
+    view.transform.mProps.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+    if (view.transform.mProps.sk) {
+      view.transform.mProps.sk.setGroupProperty(PropertyInterface('Skew', _propertyGroup));
+      view.transform.mProps.sa.setGroupProperty(PropertyInterface('Skew Angle', _propertyGroup));
+    }
+    view.transform.op.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    Object.defineProperties(interfaceFunction, {
+      opacity: {
+        get: ExpressionPropertyInterface(view.transform.mProps.o),
+      },
+      position: {
+        get: ExpressionPropertyInterface(view.transform.mProps.p),
+      },
+      anchorPoint: {
+        get: ExpressionPropertyInterface(view.transform.mProps.a),
+      },
+      scale: {
+        get: ExpressionPropertyInterface(view.transform.mProps.s),
+      },
+      rotation: {
+        get: ExpressionPropertyInterface(view.transform.mProps.r),
+      },
+      skew: {
+        get: ExpressionPropertyInterface(view.transform.mProps.sk),
+      },
+      skewAxis: {
+        get: ExpressionPropertyInterface(view.transform.mProps.sa),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.ty = 'tr';
+    interfaceFunction.mn = shape.mn;
+    interfaceFunction.propertyGroup = propertyGroup;
+    return interfaceFunction;
+  }
+
+  function ellipseInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.s.ix === value) {
+        return interfaceFunction.size;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaceFunction.propertyIndex = shape.ix;
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      size: {
+        get: ExpressionPropertyInterface(prop.s),
+      },
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function starInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value) {
+        return interfaceFunction.rotation;
+      }
+      if (shape.pt.ix === value) {
+        return interfaceFunction.points;
+      }
+      if (shape.or.ix === value || value === 'ADBE Vector Star Outer Radius') {
+        return interfaceFunction.outerRadius;
+      }
+      if (shape.os.ix === value) {
+        return interfaceFunction.outerRoundness;
+      }
+      if (shape.ir && (shape.ir.ix === value || value === 'ADBE Vector Star Inner Radius')) {
+        return interfaceFunction.innerRadius;
+      }
+      if (shape.is && shape.is.ix === value) {
+        return interfaceFunction.innerRoundness;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.or.setGroupProperty(PropertyInterface('Outer Radius', _propertyGroup));
+    prop.os.setGroupProperty(PropertyInterface('Outer Roundness', _propertyGroup));
+    prop.pt.setGroupProperty(PropertyInterface('Points', _propertyGroup));
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+    if (shape.ir) {
+      prop.ir.setGroupProperty(PropertyInterface('Inner Radius', _propertyGroup));
+      prop.is.setGroupProperty(PropertyInterface('Inner Roundness', _propertyGroup));
+    }
+
+    Object.defineProperties(interfaceFunction, {
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      rotation: {
+        get: ExpressionPropertyInterface(prop.r),
+      },
+      points: {
+        get: ExpressionPropertyInterface(prop.pt),
+      },
+      outerRadius: {
+        get: ExpressionPropertyInterface(prop.or),
+      },
+      outerRoundness: {
+        get: ExpressionPropertyInterface(prop.os),
+      },
+      innerRadius: {
+        get: ExpressionPropertyInterface(prop.ir),
+      },
+      innerRoundness: {
+        get: ExpressionPropertyInterface(prop.is),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function rectInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value) {
+        return interfaceFunction.roundness;
+      }
+      if (shape.s.ix === value || value === 'Size' || value === 'ADBE Vector Rect Size') {
+        return interfaceFunction.size;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
+    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      roundness: {
+        get: ExpressionPropertyInterface(prop.r),
+      },
+      size: {
+        get: ExpressionPropertyInterface(prop.s),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function roundedInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.r.ix === value || value === 'Round Corners 1') {
+        return interfaceFunction.radius;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.rd.setGroupProperty(PropertyInterface('Radius', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      radius: {
+        get: ExpressionPropertyInterface(prop.rd),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function repeaterInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.c.ix === value || value === 'Copies') {
+        return interfaceFunction.copies;
+      } if (shape.o.ix === value || value === 'Offset') {
+        return interfaceFunction.offset;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.c.setGroupProperty(PropertyInterface('Copies', _propertyGroup));
+    prop.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
+    Object.defineProperties(interfaceFunction, {
+      copies: {
+        get: ExpressionPropertyInterface(prop.c),
+      },
+      offset: {
+        get: ExpressionPropertyInterface(prop.o),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  return function (shapes, view, propertyGroup) {
+    var interfaces;
+    function _interfaceFunction(value) {
+      if (typeof value === 'number') {
+        value = value === undefined ? 1 : value;
+        if (value === 0) {
+          return propertyGroup;
+        }
+        return interfaces[value - 1];
+      }
+      var i = 0;
+      var len = interfaces.length;
+      while (i < len) {
+        if (interfaces[i]._name === value) {
+          return interfaces[i];
+        }
+        i += 1;
+      }
+      return null;
+    }
+    function parentGroupWrapper() {
+      return propertyGroup;
+    }
+    _interfaceFunction.propertyGroup = propertyGroupFactory(_interfaceFunction, parentGroupWrapper);
+    interfaces = iterateElements(shapes, view, _interfaceFunction.propertyGroup);
+    _interfaceFunction.numProperties = interfaces.length;
+    _interfaceFunction._name = 'Contents';
+    return _interfaceFunction;
+  };
+}());
+
+const TextExpressionInterface = (function () {
+  return function (elem) {
+    var _sourceText;
+    function _thisLayerFunction(name) {
+      switch (name) {
+        case 'ADBE Text Document':
+          return _thisLayerFunction.sourceText;
+        default:
+          return null;
+      }
+    }
+    Object.defineProperty(_thisLayerFunction, 'sourceText', {
+      get: function () {
+        elem.textProperty.getValue();
+        var stringValue = elem.textProperty.currentData.t;
+        if (!_sourceText || stringValue !== _sourceText.value) {
+          _sourceText = new String(stringValue); // eslint-disable-line no-new-wrappers
+          // If stringValue is an empty string, eval returns undefined, so it has to be returned as a String primitive
+          _sourceText.value = stringValue || new String(stringValue); // eslint-disable-line no-new-wrappers
+          Object.defineProperty(_sourceText, 'style', {
+            get: function () {
+              return {
+                fillColor: elem.textProperty.currentData.fc,
+              };
+            },
+          });
+        }
+        return _sourceText;
+      },
+    });
+    return _thisLayerFunction;
+  };
+}());
+
+const FootageInterface = (function () {
+  var outlineInterfaceFactory = (function (elem) {
+    var currentPropertyName = '';
+    var currentProperty = elem.getFootageData();
+    function init() {
+      currentPropertyName = '';
+      currentProperty = elem.getFootageData();
+      return searchProperty;
+    }
+    function searchProperty(value) {
+      if (currentProperty[value]) {
+        currentPropertyName = value;
+        currentProperty = currentProperty[value];
+        if (typeof currentProperty === 'object') {
+          return searchProperty;
+        }
+        return currentProperty;
+      }
+      var propertyNameIndex = value.indexOf(currentPropertyName);
+      if (propertyNameIndex !== -1) {
+        var index = parseInt(value.substr(propertyNameIndex + currentPropertyName.length), 10);
+        currentProperty = currentProperty[index];
+        if (typeof currentProperty === 'object') {
+          return searchProperty;
+        }
+        return currentProperty;
+      }
+      return '';
+    }
+    return init;
+  });
+
+  var dataInterfaceFactory = function (elem) {
+    function interfaceFunction(value) {
+      if (value === 'Outline') {
+        return interfaceFunction.outlineInterface();
+      }
+      return null;
+    }
+
+    interfaceFunction._name = 'Outline';
+    interfaceFunction.outlineInterface = outlineInterfaceFactory(elem);
+    return interfaceFunction;
+  };
+
+  return function (elem) {
+    function _interfaceFunction(value) {
+      if (value === 'Data') {
+        return _interfaceFunction.dataInterface;
+      }
+      return null;
+    }
+
+    _interfaceFunction._name = 'Data';
+    _interfaceFunction.dataInterface = dataInterfaceFactory(elem);
+    return _interfaceFunction;
+  };
+}());
+
+var interfaces = {
+  layer: LayerExpressionInterface,
+  effects: EffectsExpressionInterface,
+  comp: CompExpressionInterface,
+  shape: ShapeExpressionInterface,
+  text: TextExpressionInterface,
+  footage: FootageInterface,
+};
+
+function getInterface(type) {
+  return interfaces[type] || null;
+}
+
+const expressionHelpers = (function () {
+  function searchExpressions(elem, data, prop) {
+    if (data.x) {
+      prop.k = true;
+      prop.x = true;
+      prop.initiateExpression = ExpressionManager.initiateExpression;
+      prop.effectsSequence.push(prop.initiateExpression(elem, data, prop).bind(prop));
+    }
+  }
+
+  function getValueAtTime(frameNum) {
+    frameNum *= this.elem.globalData.frameRate;
+    frameNum -= this.offsetTime;
+    if (frameNum !== this._cachingAtTime.lastFrame) {
+      this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0;
+      this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime);
+      this._cachingAtTime.lastFrame = frameNum;
+    }
+    return this._cachingAtTime.value;
+  }
+
+  function getSpeedAtTime(frameNum) {
+    var delta = -0.01;
+    var v1 = this.getValueAtTime(frameNum);
+    var v2 = this.getValueAtTime(frameNum + delta);
+    var speed = 0;
+    if (v1.length) {
+      var i;
+      for (i = 0; i < v1.length; i += 1) {
+        speed += Math.pow(v2[i] - v1[i], 2);
+      }
+      speed = Math.sqrt(speed) * 100;
+    } else {
+      speed = 0;
+    }
+    return speed;
+  }
+
+  function getVelocityAtTime(frameNum) {
+    if (this.vel !== undefined) {
+      return this.vel;
+    }
+    var delta = -0.001;
+    // frameNum += this.elem.data.st;
+    var v1 = this.getValueAtTime(frameNum);
+    var v2 = this.getValueAtTime(frameNum + delta);
+    var velocity;
+    if (v1.length) {
+      velocity = createTypedArray('float32', v1.length);
+      var i;
+      for (i = 0; i < v1.length; i += 1) {
+        // removing frameRate
+        // if needed, don't add it here
+        // velocity[i] = this.elem.globalData.frameRate*((v2[i] - v1[i])/delta);
+        velocity[i] = (v2[i] - v1[i]) / delta;
+      }
+    } else {
+      velocity = (v2 - v1) / delta;
+    }
+    return velocity;
+  }
+
+  function getStaticValueAtTime() {
+    return this.pv;
+  }
+
+  function setGroupProperty(propertyGroup) {
+    this.propertyGroup = propertyGroup;
+  }
+
+  return {
+    searchExpressions: searchExpressions,
+    getSpeedAtTime: getSpeedAtTime,
+    getVelocityAtTime: getVelocityAtTime,
+    getValueAtTime: getValueAtTime,
+    getStaticValueAtTime: getStaticValueAtTime,
+    setGroupProperty: setGroupProperty,
+  };
+}());
+
+function addPropertyDecorator() {
+  function loopOut(type, duration, durationFlag) {
+    if (!this.k || !this.keyframes) {
+      return this.pv;
+    }
+    type = type ? type.toLowerCase() : '';
+    var currentFrame = this.comp.renderedFrame;
+    var keyframes = this.keyframes;
+    var lastKeyFrame = keyframes[keyframes.length - 1].t;
+    if (currentFrame <= lastKeyFrame) {
+      return this.pv;
+    }
+    var cycleDuration;
+    var firstKeyFrame;
+    if (!durationFlag) {
+      if (!duration || duration > keyframes.length - 1) {
+        duration = keyframes.length - 1;
+      }
+      firstKeyFrame = keyframes[keyframes.length - 1 - duration].t;
+      cycleDuration = lastKeyFrame - firstKeyFrame;
+    } else {
+      if (!duration) {
+        cycleDuration = Math.max(0, lastKeyFrame - this.elem.data.ip);
+      } else {
+        cycleDuration = Math.abs(lastKeyFrame - this.elem.comp.globalData.frameRate * duration);
+      }
+      firstKeyFrame = lastKeyFrame - cycleDuration;
+    }
+    var i;
+    var len;
+    var ret;
+    if (type === 'pingpong') {
+      var iterations = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
+      if (iterations % 2 !== 0) {
+          return this.getValueAtTime(((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      }
+    } else if (type === 'offset') {
+      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+        var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      var repeats = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
+      if (this.pv.length) {
+        ret = new Array(initV.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = (endV[i] - initV[i]) * repeats + current[i];
+        }
+        return ret;
+      }
+      return (endV - initV) * repeats + current;
+    } else if (type === 'continue') {
+      var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+      var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0);
+      if (this.pv.length) {
+        ret = new Array(lastValue.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+            ret[i] = lastValue[i] + (lastValue[i] - nextLastValue[i]) * ((currentFrame - lastKeyFrame) / this.comp.globalData.frameRate) / 0.0005; // eslint-disable-line
+        }
+        return ret;
+      }
+      return lastValue + (lastValue - nextLastValue) * (((currentFrame - lastKeyFrame)) / 0.001);
+    }
+      return this.getValueAtTime((((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+
+  }
+
+  function loopIn(type, duration, durationFlag) {
+    if (!this.k) {
+      return this.pv;
+    }
+    type = type ? type.toLowerCase() : '';
+    var currentFrame = this.comp.renderedFrame;
+    var keyframes = this.keyframes;
+    var firstKeyFrame = keyframes[0].t;
+    if (currentFrame >= firstKeyFrame) {
+      return this.pv;
+    }
+    var cycleDuration;
+    var lastKeyFrame;
+    if (!durationFlag) {
+      if (!duration || duration > keyframes.length - 1) {
+        duration = keyframes.length - 1;
+      }
+      lastKeyFrame = keyframes[duration].t;
+      cycleDuration = lastKeyFrame - firstKeyFrame;
+    } else {
+      if (!duration) {
+        cycleDuration = Math.max(0, this.elem.data.op - firstKeyFrame);
+      } else {
+        cycleDuration = Math.abs(this.elem.comp.globalData.frameRate * duration);
+      }
+      lastKeyFrame = firstKeyFrame + cycleDuration;
+    }
+    var i;
+    var len;
+    var ret;
+    if (type === 'pingpong') {
+      var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration);
+      if (iterations % 2 === 0) {
+          return this.getValueAtTime((((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      }
+    } else if (type === 'offset') {
+      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+      var current = this.getValueAtTime((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration) + firstKeyFrame) / this.comp.globalData.frameRate, 0);
+      var repeats = Math.floor((firstKeyFrame - currentFrame) / cycleDuration) + 1;
+      if (this.pv.length) {
+        ret = new Array(initV.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = current[i] - (endV[i] - initV[i]) * repeats;
+        }
+        return ret;
+      }
+      return current - (endV - initV) * repeats;
+    } else if (type === 'continue') {
+      var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0);
+      if (this.pv.length) {
+        ret = new Array(firstValue.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = firstValue[i] + ((firstValue[i] - nextFirstValue[i]) * (firstKeyFrame - currentFrame)) / 0.001;
+        }
+        return ret;
+      }
+      return firstValue + ((firstValue - nextFirstValue) * (firstKeyFrame - currentFrame)) / 0.001;
+    }
+      return this.getValueAtTime(((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame))) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+
+  }
+
+  function smooth(width, samples) {
+    if (!this.k) {
+      return this.pv;
+    }
+    width = (width || 0.4) * 0.5;
+    samples = Math.floor(samples || 5);
+    if (samples <= 1) {
+      return this.pv;
+    }
+    var currentTime = this.comp.renderedFrame / this.comp.globalData.frameRate;
+    var initFrame = currentTime - width;
+    var endFrame = currentTime + width;
+    var sampleFrequency = samples > 1 ? (endFrame - initFrame) / (samples - 1) : 1;
+    var i = 0;
+    var j = 0;
+    var value;
+    if (this.pv.length) {
+      value = createTypedArray('float32', this.pv.length);
+    } else {
+      value = 0;
+    }
+    var sampleValue;
+    while (i < samples) {
+      sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency);
+      if (this.pv.length) {
+        for (j = 0; j < this.pv.length; j += 1) {
+          value[j] += sampleValue[j];
+        }
+      } else {
+        value += sampleValue;
+      }
+      i += 1;
+    }
+    if (this.pv.length) {
+      for (j = 0; j < this.pv.length; j += 1) {
+        value[j] /= samples;
+      }
+    } else {
+      value /= samples;
+    }
+    return value;
+  }
+
+  function getTransformValueAtTime(time) {
+    if (!this._transformCachingAtTime) {
+      this._transformCachingAtTime = {
+        v: new Matrix(),
+      };
+    }
+    /// /
+    var matrix = this._transformCachingAtTime.v;
+    matrix.cloneFromProps(this.pre.props);
+    if (this.appliedTransformations < 1) {
+      var anchor = this.a.getValueAtTime(time);
+      matrix.translate(
+        -anchor[0] * this.a.mult,
+        -anchor[1] * this.a.mult,
+        anchor[2] * this.a.mult
+      );
+    }
+    if (this.appliedTransformations < 2) {
+      var scale = this.s.getValueAtTime(time);
+      matrix.scale(
+        scale[0] * this.s.mult,
+        scale[1] * this.s.mult,
+        scale[2] * this.s.mult
+      );
+    }
+    if (this.sk && this.appliedTransformations < 3) {
+      var skew = this.sk.getValueAtTime(time);
+      var skewAxis = this.sa.getValueAtTime(time);
+      matrix.skewFromAxis(-skew * this.sk.mult, skewAxis * this.sa.mult);
+    }
+    if (this.r && this.appliedTransformations < 4) {
+      var rotation = this.r.getValueAtTime(time);
+      matrix.rotate(-rotation * this.r.mult);
+    } else if (!this.r && this.appliedTransformations < 4) {
+      var rotationZ = this.rz.getValueAtTime(time);
+      var rotationY = this.ry.getValueAtTime(time);
+      var rotationX = this.rx.getValueAtTime(time);
+      var orientation = this.or.getValueAtTime(time);
+      matrix.rotateZ(-rotationZ * this.rz.mult)
+        .rotateY(rotationY * this.ry.mult)
+        .rotateX(rotationX * this.rx.mult)
+        .rotateZ(-orientation[2] * this.or.mult)
+        .rotateY(orientation[1] * this.or.mult)
+        .rotateX(orientation[0] * this.or.mult);
+    }
+    if (this.data.p && this.data.p.s) {
+      var positionX = this.px.getValueAtTime(time);
+      var positionY = this.py.getValueAtTime(time);
+      if (this.data.p.z) {
+        var positionZ = this.pz.getValueAtTime(time);
+        matrix.translate(
+          positionX * this.px.mult,
+          positionY * this.py.mult,
+          -positionZ * this.pz.mult
+        );
+      } else {
+        matrix.translate(positionX * this.px.mult, positionY * this.py.mult, 0);
+      }
+    } else {
+      var position = this.p.getValueAtTime(time);
+      matrix.translate(
+        position[0] * this.p.mult,
+        position[1] * this.p.mult,
+        -position[2] * this.p.mult
+      );
+    }
+    return matrix;
+    /// /
+  }
+
+  function getTransformStaticValueAtTime() {
+    return this.v.clone(new Matrix());
+  }
+
+  var getTransformProperty = TransformPropertyFactory.getTransformProperty;
+  TransformPropertyFactory.getTransformProperty = function (elem, data, container) {
+    var prop = getTransformProperty(elem, data, container);
+    if (prop.dynamicProperties.length) {
+      prop.getValueAtTime = getTransformValueAtTime.bind(prop);
+    } else {
+      prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop);
+    }
+    prop.setGroupProperty = expressionHelpers.setGroupProperty;
+    return prop;
+  };
+
+  var propertyGetProp = PropertyFactory.getProp;
+  PropertyFactory.getProp = function (elem, data, type, mult, container) {
+    var prop = propertyGetProp(elem, data, type, mult, container);
+    // prop.getVelocityAtTime = getVelocityAtTime;
+    // prop.loopOut = loopOut;
+    // prop.loopIn = loopIn;
+    if (prop.kf) {
+      prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop);
+    } else {
+      prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop);
+    }
+    prop.setGroupProperty = expressionHelpers.setGroupProperty;
+    prop.loopOut = loopOut;
+    prop.loopIn = loopIn;
+    prop.smooth = smooth;
+    prop.getVelocityAtTime = expressionHelpers.getVelocityAtTime.bind(prop);
+    prop.getSpeedAtTime = expressionHelpers.getSpeedAtTime.bind(prop);
+    prop.numKeys = data.a === 1 ? data.k.length : 0;
+    prop.propertyIndex = data.ix;
+    var value = 0;
+    if (type !== 0) {
+      value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length);
+    }
+    prop._cachingAtTime = {
+      lastFrame: initialDefaultFrame,
+      lastIndex: 0,
+      value: value,
+    };
+    expressionHelpers.searchExpressions(elem, data, prop);
+    if (prop.k) {
+      container.addDynamicProperty(prop);
+    }
+
+    return prop;
+  };
+
+  function getShapeValueAtTime(frameNum) {
+    // For now this caching object is created only when needed instead of creating it when the shape is initialized.
+    if (!this._cachingAtTime) {
+      this._cachingAtTime = {
+        shapeValue: shapePool.clone(this.pv),
+        lastIndex: 0,
+        lastTime: initialDefaultFrame,
+      };
+    }
+
+    frameNum *= this.elem.globalData.frameRate;
+    frameNum -= this.offsetTime;
+    if (frameNum !== this._cachingAtTime.lastTime) {
+      this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0;
+      this._cachingAtTime.lastTime = frameNum;
+      this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime);
+    }
+    return this._cachingAtTime.shapeValue;
+  }
+
+  var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction();
+  var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction();
+
+  function ShapeExpressions() {}
+  ShapeExpressions.prototype = {
+    vertices: function (prop, time) {
+      if (this.k) {
+        this.getValue();
+      }
+      var shapePath = this.v;
+      if (time !== undefined) {
+        shapePath = this.getValueAtTime(time, 0);
+      }
+      var i;
+      var len = shapePath._length;
+      var vertices = shapePath[prop];
+      var points = shapePath.v;
+      var arr = createSizedArray(len);
+      for (i = 0; i < len; i += 1) {
+        if (prop === 'i' || prop === 'o') {
+          arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]];
+        } else {
+          arr[i] = [vertices[i][0], vertices[i][1]];
+        }
+      }
+      return arr;
+    },
+    points: function (time) {
+      return this.vertices('v', time);
+    },
+    inTangents: function (time) {
+      return this.vertices('i', time);
+    },
+    outTangents: function (time) {
+      return this.vertices('o', time);
+    },
+    isClosed: function () {
+      return this.v.c;
+    },
+    pointOnPath: function (perc, time) {
+      var shapePath = this.v;
+      if (time !== undefined) {
+        shapePath = this.getValueAtTime(time, 0);
+      }
+      if (!this._segmentsLength) {
+        this._segmentsLength = bez.getSegmentsLength(shapePath);
+      }
+
+      var segmentsLength = this._segmentsLength;
+      var lengths = segmentsLength.lengths;
+      var lengthPos = segmentsLength.totalLength * perc;
+      var i = 0;
+      var len = lengths.length;
+      var accumulatedLength = 0;
+      var pt;
+      while (i < len) {
+        if (accumulatedLength + lengths[i].addedLength > lengthPos) {
+          var initIndex = i;
+          var endIndex = (shapePath.c && i === len - 1) ? 0 : i + 1;
+          var segmentPerc = (lengthPos - accumulatedLength) / lengths[i].addedLength;
+          pt = bez.getPointInSegment(shapePath.v[initIndex], shapePath.v[endIndex], shapePath.o[initIndex], shapePath.i[endIndex], segmentPerc, lengths[i]);
+          break;
+        } else {
+          accumulatedLength += lengths[i].addedLength;
+        }
+        i += 1;
+      }
+      if (!pt) {
+        pt = shapePath.c ? [shapePath.v[0][0], shapePath.v[0][1]] : [shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1]];
+      }
+      return pt;
+    },
+    vectorOnPath: function (perc, time, vectorType) {
+      // perc doesn't use triple equality because it can be a Number object as well as a primitive.
+      if (perc == 1) { // eslint-disable-line eqeqeq
+        perc = this.v.c;
+      } else if (perc == 0) { // eslint-disable-line eqeqeq
+        perc = 0.999;
+      }
+      var pt1 = this.pointOnPath(perc, time);
+      var pt2 = this.pointOnPath(perc + 0.001, time);
+      var xLength = pt2[0] - pt1[0];
+      var yLength = pt2[1] - pt1[1];
+      var magnitude = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2));
+      if (magnitude === 0) {
+        return [0, 0];
+      }
+      var unitVector = vectorType === 'tangent' ? [xLength / magnitude, yLength / magnitude] : [-yLength / magnitude, xLength / magnitude];
+      return unitVector;
+    },
+    tangentOnPath: function (perc, time) {
+      return this.vectorOnPath(perc, time, 'tangent');
+    },
+    normalOnPath: function (perc, time) {
+      return this.vectorOnPath(perc, time, 'normal');
+    },
+    setGroupProperty: expressionHelpers.setGroupProperty,
+    getValueAtTime: expressionHelpers.getStaticValueAtTime,
+  };
+  extendPrototype([ShapeExpressions], ShapePropertyConstructorFunction);
+  extendPrototype([ShapeExpressions], KeyframedShapePropertyConstructorFunction);
+  KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime;
+  KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression;
+
+  var propertyGetShapeProp = ShapePropertyFactory.getShapeProp;
+  ShapePropertyFactory.getShapeProp = function (elem, data, type, arr, trims) {
+    var prop = propertyGetShapeProp(elem, data, type, arr, trims);
+    prop.propertyIndex = data.ix;
+    prop.lock = false;
+    if (type === 3) {
+      expressionHelpers.searchExpressions(elem, data.pt, prop);
+    } else if (type === 4) {
+      expressionHelpers.searchExpressions(elem, data.ks, prop);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  };
+}
+
+function initialize$1() {
+  addPropertyDecorator();
+}
+
+function addDecorator() {
+  function searchExpressions() {
+    if (this.data.d.x) {
+      this.calculateExpression = ExpressionManager.initiateExpression.bind(this)(this.elem, this.data.d, this);
+      this.addEffect(this.getExpressionValue.bind(this));
+      return true;
+    }
+    return null;
+  }
+
+  TextProperty.prototype.getExpressionValue = function (currentValue, text) {
+    var newValue = this.calculateExpression(text);
+    if (currentValue.t !== newValue) {
+      var newData = {};
+      this.copyData(newData, currentValue);
+      newData.t = newValue.toString();
+      newData.__complete = false;
+      return newData;
+    }
+    return currentValue;
+  };
+
+  TextProperty.prototype.searchProperty = function () {
+    var isKeyframed = this.searchKeyframes();
+    var hasExpressions = this.searchExpressions();
+    this.kf = isKeyframed || hasExpressions;
+    return this.kf;
+  };
+
+  TextProperty.prototype.searchExpressions = searchExpressions;
+}
+
+function initialize() {
+  addDecorator();
+}
+
+function SVGComposableEffect() {
+
+}
+SVGComposableEffect.prototype = {
+  createMergeNode: (resultId, ins) => {
+    var feMerge = createNS('feMerge');
+    feMerge.setAttribute('result', resultId);
+    var feMergeNode;
+    var i;
+    for (i = 0; i < ins.length; i += 1) {
+      feMergeNode = createNS('feMergeNode');
+      feMergeNode.setAttribute('in', ins[i]);
+      feMerge.appendChild(feMergeNode);
+      feMerge.appendChild(feMergeNode);
+    }
+    return feMerge;
+  },
+};
+
+var linearFilterValue = '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0';
+
+function SVGTintFilter(filter, filterManager, elem, id, source) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'linearRGB');
+  feColorMatrix.setAttribute('values', linearFilterValue + ' 1 0');
+  this.linearFilter = feColorMatrix;
+  feColorMatrix.setAttribute('result', id + '_tint_1');
+  filter.appendChild(feColorMatrix);
+  feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+  feColorMatrix.setAttribute('values', '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0');
+  feColorMatrix.setAttribute('result', id + '_tint_2');
+  filter.appendChild(feColorMatrix);
+  this.matrixFilter = feColorMatrix;
+  var feMerge = this.createMergeNode(
+    id,
+    [
+      source,
+      id + '_tint_1',
+      id + '_tint_2',
+    ]
+  );
+  filter.appendChild(feMerge);
+}
+extendPrototype([SVGComposableEffect], SVGTintFilter);
+
+SVGTintFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var colorBlack = this.filterManager.effectElements[0].p.v;
+    var colorWhite = this.filterManager.effectElements[1].p.v;
+    var opacity = this.filterManager.effectElements[2].p.v / 100;
+    this.linearFilter.setAttribute('values', linearFilterValue + ' ' + opacity + ' 0');
+    this.matrixFilter.setAttribute('values', (colorWhite[0] - colorBlack[0]) + ' 0 0 0 ' + colorBlack[0] + ' ' + (colorWhite[1] - colorBlack[1]) + ' 0 0 0 ' + colorBlack[1] + ' ' + (colorWhite[2] - colorBlack[2]) + ' 0 0 0 ' + colorBlack[2] + ' 0 0 0 1 0');
+  }
+};
+
+function SVGFillFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+  feColorMatrix.setAttribute('values', '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0');
+  feColorMatrix.setAttribute('result', id);
+  filter.appendChild(feColorMatrix);
+  this.matrixFilter = feColorMatrix;
+}
+
+SVGFillFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var color = this.filterManager.effectElements[2].p.v;
+    var opacity = this.filterManager.effectElements[6].p.v;
+    this.matrixFilter.setAttribute('values', '0 0 0 0 ' + color[0] + ' 0 0 0 0 ' + color[1] + ' 0 0 0 0 ' + color[2] + ' 0 0 0 ' + opacity + ' 0');
+  }
+};
+
+function SVGStrokeEffect(fil, filterManager, elem) {
+  this.initialized = false;
+  this.filterManager = filterManager;
+  this.elem = elem;
+  this.paths = [];
+}
+
+SVGStrokeEffect.prototype.initialize = function () {
+  var elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
+  var path;
+  var groupPath;
+  var i;
+  var len;
+  if (this.filterManager.effectElements[1].p.v === 1) {
+    len = this.elem.maskManager.masksProperties.length;
+    i = 0;
+  } else {
+    i = this.filterManager.effectElements[0].p.v - 1;
+    len = i + 1;
+  }
+  groupPath = createNS('g');
+  groupPath.setAttribute('fill', 'none');
+  groupPath.setAttribute('stroke-linecap', 'round');
+  groupPath.setAttribute('stroke-dashoffset', 1);
+  for (i; i < len; i += 1) {
+    path = createNS('path');
+    groupPath.appendChild(path);
+    this.paths.push({ p: path, m: i });
+  }
+  if (this.filterManager.effectElements[10].p.v === 3) {
+    var mask = createNS('mask');
+    var id = createElementID();
+    mask.setAttribute('id', id);
+    mask.setAttribute('mask-type', 'alpha');
+    mask.appendChild(groupPath);
+    this.elem.globalData.defs.appendChild(mask);
+    var g = createNS('g');
+    g.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+    while (elemChildren[0]) {
+      g.appendChild(elemChildren[0]);
+    }
+    this.elem.layerElement.appendChild(g);
+    this.masker = mask;
+    groupPath.setAttribute('stroke', '#fff');
+  } else if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
+    if (this.filterManager.effectElements[10].p.v === 2) {
+      elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
+      while (elemChildren.length) {
+        this.elem.layerElement.removeChild(elemChildren[0]);
+      }
+    }
+    this.elem.layerElement.appendChild(groupPath);
+    this.elem.layerElement.removeAttribute('mask');
+    groupPath.setAttribute('stroke', '#fff');
+  }
+  this.initialized = true;
+  this.pathMasker = groupPath;
+};
+
+SVGStrokeEffect.prototype.renderFrame = function (forceRender) {
+  if (!this.initialized) {
+    this.initialize();
+  }
+  var i;
+  var len = this.paths.length;
+  var mask;
+  var path;
+  for (i = 0; i < len; i += 1) {
+    if (this.paths[i].m !== -1) {
+      mask = this.elem.maskManager.viewData[this.paths[i].m];
+      path = this.paths[i].p;
+      if (forceRender || this.filterManager._mdf || mask.prop._mdf) {
+        path.setAttribute('d', mask.lastPath);
+      }
+      if (forceRender || this.filterManager.effectElements[9].p._mdf || this.filterManager.effectElements[4].p._mdf || this.filterManager.effectElements[7].p._mdf || this.filterManager.effectElements[8].p._mdf || mask.prop._mdf) {
+        var dasharrayValue;
+        if (this.filterManager.effectElements[7].p.v !== 0 || this.filterManager.effectElements[8].p.v !== 100) {
+          var s = Math.min(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
+          var e = Math.max(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
+          var l = path.getTotalLength();
+          dasharrayValue = '0 0 0 ' + l * s + ' ';
+          var lineLength = l * (e - s);
+          var segment = 1 + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
+          var units = Math.floor(lineLength / segment);
+          var j;
+          for (j = 0; j < units; j += 1) {
+            dasharrayValue += '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01 + ' ';
+          }
+          dasharrayValue += '0 ' + l * 10 + ' 0 0';
+        } else {
+          dasharrayValue = '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
+        }
+        path.setAttribute('stroke-dasharray', dasharrayValue);
+      }
+    }
+  }
+  if (forceRender || this.filterManager.effectElements[4].p._mdf) {
+    this.pathMasker.setAttribute('stroke-width', this.filterManager.effectElements[4].p.v * 2);
+  }
+
+  if (forceRender || this.filterManager.effectElements[6].p._mdf) {
+    this.pathMasker.setAttribute('opacity', this.filterManager.effectElements[6].p.v);
+  }
+  if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
+    if (forceRender || this.filterManager.effectElements[3].p._mdf) {
+      var color = this.filterManager.effectElements[3].p.v;
+      this.pathMasker.setAttribute('stroke', 'rgb(' + bmFloor(color[0] * 255) + ',' + bmFloor(color[1] * 255) + ',' + bmFloor(color[2] * 255) + ')');
+    }
+  }
+};
+
+function SVGTritoneFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'linearRGB');
+  feColorMatrix.setAttribute('values', '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0');
+  filter.appendChild(feColorMatrix);
+  var feComponentTransfer = createNS('feComponentTransfer');
+  feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+  feComponentTransfer.setAttribute('result', id);
+  this.matrixFilter = feComponentTransfer;
+  var feFuncR = createNS('feFuncR');
+  feFuncR.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncR);
+  this.feFuncR = feFuncR;
+  var feFuncG = createNS('feFuncG');
+  feFuncG.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncG);
+  this.feFuncG = feFuncG;
+  var feFuncB = createNS('feFuncB');
+  feFuncB.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncB);
+  this.feFuncB = feFuncB;
+  filter.appendChild(feComponentTransfer);
+}
+
+SVGTritoneFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var color1 = this.filterManager.effectElements[0].p.v;
+    var color2 = this.filterManager.effectElements[1].p.v;
+    var color3 = this.filterManager.effectElements[2].p.v;
+    var tableR = color3[0] + ' ' + color2[0] + ' ' + color1[0];
+    var tableG = color3[1] + ' ' + color2[1] + ' ' + color1[1];
+    var tableB = color3[2] + ' ' + color2[2] + ' ' + color1[2];
+    this.feFuncR.setAttribute('tableValues', tableR);
+    this.feFuncG.setAttribute('tableValues', tableG);
+    this.feFuncB.setAttribute('tableValues', tableB);
+  }
+};
+
+function SVGProLevelsFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var effectElements = this.filterManager.effectElements;
+  var feComponentTransfer = createNS('feComponentTransfer');
+
+  // Red
+  if (effectElements[10].p.k || effectElements[10].p.v !== 0 || effectElements[11].p.k || effectElements[11].p.v !== 1 || effectElements[12].p.k || effectElements[12].p.v !== 1 || effectElements[13].p.k || effectElements[13].p.v !== 0 || effectElements[14].p.k || effectElements[14].p.v !== 1) {
+    this.feFuncR = this.createFeFunc('feFuncR', feComponentTransfer);
+  }
+  // Green
+  if (effectElements[17].p.k || effectElements[17].p.v !== 0 || effectElements[18].p.k || effectElements[18].p.v !== 1 || effectElements[19].p.k || effectElements[19].p.v !== 1 || effectElements[20].p.k || effectElements[20].p.v !== 0 || effectElements[21].p.k || effectElements[21].p.v !== 1) {
+    this.feFuncG = this.createFeFunc('feFuncG', feComponentTransfer);
+  }
+  // Blue
+  if (effectElements[24].p.k || effectElements[24].p.v !== 0 || effectElements[25].p.k || effectElements[25].p.v !== 1 || effectElements[26].p.k || effectElements[26].p.v !== 1 || effectElements[27].p.k || effectElements[27].p.v !== 0 || effectElements[28].p.k || effectElements[28].p.v !== 1) {
+    this.feFuncB = this.createFeFunc('feFuncB', feComponentTransfer);
+  }
+  // Alpha
+  if (effectElements[31].p.k || effectElements[31].p.v !== 0 || effectElements[32].p.k || effectElements[32].p.v !== 1 || effectElements[33].p.k || effectElements[33].p.v !== 1 || effectElements[34].p.k || effectElements[34].p.v !== 0 || effectElements[35].p.k || effectElements[35].p.v !== 1) {
+    this.feFuncA = this.createFeFunc('feFuncA', feComponentTransfer);
+  }
+  // RGB
+  if (this.feFuncR || this.feFuncG || this.feFuncB || this.feFuncA) {
+    feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+    filter.appendChild(feComponentTransfer);
+  }
+
+  if (effectElements[3].p.k || effectElements[3].p.v !== 0 || effectElements[4].p.k || effectElements[4].p.v !== 1 || effectElements[5].p.k || effectElements[5].p.v !== 1 || effectElements[6].p.k || effectElements[6].p.v !== 0 || effectElements[7].p.k || effectElements[7].p.v !== 1) {
+    feComponentTransfer = createNS('feComponentTransfer');
+    feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+    feComponentTransfer.setAttribute('result', id);
+    filter.appendChild(feComponentTransfer);
+    this.feFuncRComposed = this.createFeFunc('feFuncR', feComponentTransfer);
+    this.feFuncGComposed = this.createFeFunc('feFuncG', feComponentTransfer);
+    this.feFuncBComposed = this.createFeFunc('feFuncB', feComponentTransfer);
+  }
+}
+
+SVGProLevelsFilter.prototype.createFeFunc = function (type, feComponentTransfer) {
+  var feFunc = createNS(type);
+  feFunc.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFunc);
+  return feFunc;
+};
+
+SVGProLevelsFilter.prototype.getTableValue = function (inputBlack, inputWhite, gamma, outputBlack, outputWhite) {
+  var cnt = 0;
+  var segments = 256;
+  var perc;
+  var min = Math.min(inputBlack, inputWhite);
+  var max = Math.max(inputBlack, inputWhite);
+  var table = Array.call(null, { length: segments });
+  var colorValue;
+  var pos = 0;
+  var outputDelta = outputWhite - outputBlack;
+  var inputDelta = inputWhite - inputBlack;
+  while (cnt <= 256) {
+    perc = cnt / 256;
+    if (perc <= min) {
+      colorValue = inputDelta < 0 ? outputWhite : outputBlack;
+    } else if (perc >= max) {
+      colorValue = inputDelta < 0 ? outputBlack : outputWhite;
+    } else {
+      colorValue = (outputBlack + outputDelta * Math.pow((perc - inputBlack) / inputDelta, 1 / gamma));
+    }
+    table[pos] = colorValue;
+    pos += 1;
+    cnt += 256 / (segments - 1);
+  }
+  return table.join(' ');
+};
+
+SVGProLevelsFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var val;
+    var effectElements = this.filterManager.effectElements;
+    if (this.feFuncRComposed && (forceRender || effectElements[3].p._mdf || effectElements[4].p._mdf || effectElements[5].p._mdf || effectElements[6].p._mdf || effectElements[7].p._mdf)) {
+      val = this.getTableValue(effectElements[3].p.v, effectElements[4].p.v, effectElements[5].p.v, effectElements[6].p.v, effectElements[7].p.v);
+      this.feFuncRComposed.setAttribute('tableValues', val);
+      this.feFuncGComposed.setAttribute('tableValues', val);
+      this.feFuncBComposed.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncR && (forceRender || effectElements[10].p._mdf || effectElements[11].p._mdf || effectElements[12].p._mdf || effectElements[13].p._mdf || effectElements[14].p._mdf)) {
+      val = this.getTableValue(effectElements[10].p.v, effectElements[11].p.v, effectElements[12].p.v, effectElements[13].p.v, effectElements[14].p.v);
+      this.feFuncR.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncG && (forceRender || effectElements[17].p._mdf || effectElements[18].p._mdf || effectElements[19].p._mdf || effectElements[20].p._mdf || effectElements[21].p._mdf)) {
+      val = this.getTableValue(effectElements[17].p.v, effectElements[18].p.v, effectElements[19].p.v, effectElements[20].p.v, effectElements[21].p.v);
+      this.feFuncG.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncB && (forceRender || effectElements[24].p._mdf || effectElements[25].p._mdf || effectElements[26].p._mdf || effectElements[27].p._mdf || effectElements[28].p._mdf)) {
+      val = this.getTableValue(effectElements[24].p.v, effectElements[25].p.v, effectElements[26].p.v, effectElements[27].p.v, effectElements[28].p.v);
+      this.feFuncB.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncA && (forceRender || effectElements[31].p._mdf || effectElements[32].p._mdf || effectElements[33].p._mdf || effectElements[34].p._mdf || effectElements[35].p._mdf)) {
+      val = this.getTableValue(effectElements[31].p.v, effectElements[32].p.v, effectElements[33].p.v, effectElements[34].p.v, effectElements[35].p.v);
+      this.feFuncA.setAttribute('tableValues', val);
+    }
+  }
+};
+
+function SVGDropShadowEffect(filter, filterManager, elem, id, source) {
+  var globalFilterSize = filterManager.container.globalData.renderConfig.filterSize;
+  var filterSize = filterManager.data.fs || globalFilterSize;
+  filter.setAttribute('x', filterSize.x || globalFilterSize.x);
+  filter.setAttribute('y', filterSize.y || globalFilterSize.y);
+  filter.setAttribute('width', filterSize.width || globalFilterSize.width);
+  filter.setAttribute('height', filterSize.height || globalFilterSize.height);
+  this.filterManager = filterManager;
+
+  var feGaussianBlur = createNS('feGaussianBlur');
+  feGaussianBlur.setAttribute('in', 'SourceAlpha');
+  feGaussianBlur.setAttribute('result', id + '_drop_shadow_1');
+  feGaussianBlur.setAttribute('stdDeviation', '0');
+  this.feGaussianBlur = feGaussianBlur;
+  filter.appendChild(feGaussianBlur);
+
+  var feOffset = createNS('feOffset');
+  feOffset.setAttribute('dx', '25');
+  feOffset.setAttribute('dy', '0');
+  feOffset.setAttribute('in', id + '_drop_shadow_1');
+  feOffset.setAttribute('result', id + '_drop_shadow_2');
+  this.feOffset = feOffset;
+  filter.appendChild(feOffset);
+  var feFlood = createNS('feFlood');
+  feFlood.setAttribute('flood-color', '#00ff00');
+  feFlood.setAttribute('flood-opacity', '1');
+  feFlood.setAttribute('result', id + '_drop_shadow_3');
+  this.feFlood = feFlood;
+  filter.appendChild(feFlood);
+
+  var feComposite = createNS('feComposite');
+  feComposite.setAttribute('in', id + '_drop_shadow_3');
+  feComposite.setAttribute('in2', id + '_drop_shadow_2');
+  feComposite.setAttribute('operator', 'in');
+  feComposite.setAttribute('result', id + '_drop_shadow_4');
+  filter.appendChild(feComposite);
+
+  var feMerge = this.createMergeNode(
+    id,
+    [
+      id + '_drop_shadow_4',
+      source,
+    ]
+  );
+  filter.appendChild(feMerge);
+  //
+}
+extendPrototype([SVGComposableEffect], SVGDropShadowEffect);
+
+SVGDropShadowEffect.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    if (forceRender || this.filterManager.effectElements[4].p._mdf) {
+      this.feGaussianBlur.setAttribute('stdDeviation', this.filterManager.effectElements[4].p.v / 4);
+    }
+    if (forceRender || this.filterManager.effectElements[0].p._mdf) {
+      var col = this.filterManager.effectElements[0].p.v;
+      this.feFlood.setAttribute('flood-color', rgbToHex(Math.round(col[0] * 255), Math.round(col[1] * 255), Math.round(col[2] * 255)));
+    }
+    if (forceRender || this.filterManager.effectElements[1].p._mdf) {
+      this.feFlood.setAttribute('flood-opacity', this.filterManager.effectElements[1].p.v / 255);
+    }
+    if (forceRender || this.filterManager.effectElements[2].p._mdf || this.filterManager.effectElements[3].p._mdf) {
+      var distance = this.filterManager.effectElements[3].p.v;
+      var angle = (this.filterManager.effectElements[2].p.v - 90) * degToRads;
+      var x = distance * Math.cos(angle);
+      var y = distance * Math.sin(angle);
+      this.feOffset.setAttribute('dx', x);
+      this.feOffset.setAttribute('dy', y);
+    }
+  }
+};
+
+var _svgMatteSymbols = [];
+
+function SVGMatte3Effect(filterElem, filterManager, elem) {
+  this.initialized = false;
+  this.filterManager = filterManager;
+  this.filterElem = filterElem;
+  this.elem = elem;
+  elem.matteElement = createNS('g');
+  elem.matteElement.appendChild(elem.layerElement);
+  elem.matteElement.appendChild(elem.transformedElement);
+  elem.baseElement = elem.matteElement;
+}
+
+SVGMatte3Effect.prototype.findSymbol = function (mask) {
+  var i = 0;
+  var len = _svgMatteSymbols.length;
+  while (i < len) {
+    if (_svgMatteSymbols[i] === mask) {
+      return _svgMatteSymbols[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+SVGMatte3Effect.prototype.replaceInParent = function (mask, symbolId) {
+  var parentNode = mask.layerElement.parentNode;
+  if (!parentNode) {
+    return;
+  }
+  var children = parentNode.children;
+  var i = 0;
+  var len = children.length;
+  while (i < len) {
+    if (children[i] === mask.layerElement) {
+      break;
+    }
+    i += 1;
+  }
+  var nextChild;
+  if (i <= len - 2) {
+    nextChild = children[i + 1];
+  }
+  var useElem = createNS('use');
+  useElem.setAttribute('href', '#' + symbolId);
+  if (nextChild) {
+    parentNode.insertBefore(useElem, nextChild);
+  } else {
+    parentNode.appendChild(useElem);
+  }
+};
+
+SVGMatte3Effect.prototype.setElementAsMask = function (elem, mask) {
+  if (!this.findSymbol(mask)) {
+    var symbolId = createElementID();
+    var masker = createNS('mask');
+    masker.setAttribute('id', mask.layerId);
+    masker.setAttribute('mask-type', 'alpha');
+    _svgMatteSymbols.push(mask);
+    var defs = elem.globalData.defs;
+    defs.appendChild(masker);
+    var symbol = createNS('symbol');
+    symbol.setAttribute('id', symbolId);
+    this.replaceInParent(mask, symbolId);
+    symbol.appendChild(mask.layerElement);
+    defs.appendChild(symbol);
+    var useElem = createNS('use');
+    useElem.setAttribute('href', '#' + symbolId);
+    masker.appendChild(useElem);
+    mask.data.hd = false;
+    mask.show();
+  }
+  elem.setMatte(mask.layerId);
+};
+
+SVGMatte3Effect.prototype.initialize = function () {
+  var ind = this.filterManager.effectElements[0].p.v;
+  var elements = this.elem.comp.elements;
+  var i = 0;
+  var len = elements.length;
+  while (i < len) {
+    if (elements[i] && elements[i].data.ind === ind) {
+      this.setElementAsMask(this.elem, elements[i]);
+    }
+    i += 1;
+  }
+  this.initialized = true;
+};
+
+SVGMatte3Effect.prototype.renderFrame = function () {
+  if (!this.initialized) {
+    this.initialize();
+  }
+};
+
+function SVGGaussianBlurEffect(filter, filterManager, elem, id) {
+  // Outset the filter region by 100% on all sides to accommodate blur expansion.
+  filter.setAttribute('x', '-100%');
+  filter.setAttribute('y', '-100%');
+  filter.setAttribute('width', '300%');
+  filter.setAttribute('height', '300%');
+
+  this.filterManager = filterManager;
+  var feGaussianBlur = createNS('feGaussianBlur');
+  feGaussianBlur.setAttribute('result', id);
+  filter.appendChild(feGaussianBlur);
+  this.feGaussianBlur = feGaussianBlur;
+}
+
+SVGGaussianBlurEffect.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    // Empirical value, matching AE's blur appearance.
+    var kBlurrinessToSigma = 0.3;
+    var sigma = this.filterManager.effectElements[0].p.v * kBlurrinessToSigma;
+
+    // Dimensions mapping:
+    //
+    //   1 -> horizontal & vertical
+    //   2 -> horizontal only
+    //   3 -> vertical only
+    //
+    var dimensions = this.filterManager.effectElements[1].p.v;
+    var sigmaX = (dimensions == 3) ? 0 : sigma; // eslint-disable-line eqeqeq
+    var sigmaY = (dimensions == 2) ? 0 : sigma; // eslint-disable-line eqeqeq
+
+    this.feGaussianBlur.setAttribute('stdDeviation', sigmaX + ' ' + sigmaY);
+
+    // Repeat edges mapping:
+    //
+    //   0 -> off -> duplicate
+    //   1 -> on  -> wrap
+    var edgeMode = (this.filterManager.effectElements[2].p.v == 1) ? 'wrap' : 'duplicate'; // eslint-disable-line eqeqeq
+    this.feGaussianBlur.setAttribute('edgeMode', edgeMode);
+  }
+};
+
+function TransformEffect() {
+}
+
+TransformEffect.prototype.init = function (effectsManager) {
+  this.effectsManager = effectsManager;
+  this.type = effectTypes.TRANSFORM_EFFECT;
+  this.matrix = new Matrix();
+  this.opacity = -1;
+  this._mdf = false;
+  this._opMdf = false;
+};
+
+TransformEffect.prototype.renderFrame = function (forceFrame) {
+  this._opMdf = false;
+  this._mdf = false;
+  if (forceFrame || this.effectsManager._mdf) {
+    var effectElements = this.effectsManager.effectElements;
+    var anchor = effectElements[0].p.v;
+    var position = effectElements[1].p.v;
+    var isUniformScale = effectElements[2].p.v === 1;
+    var scaleHeight = effectElements[3].p.v;
+    var scaleWidth = isUniformScale ? scaleHeight : effectElements[4].p.v;
+    var skew = effectElements[5].p.v;
+    var skewAxis = effectElements[6].p.v;
+    var rotation = effectElements[7].p.v;
+    this.matrix.reset();
+    this.matrix.translate(-anchor[0], -anchor[1], anchor[2]);
+    this.matrix.scale(scaleWidth * 0.01, scaleHeight * 0.01, 1);
+    this.matrix.rotate(-rotation * degToRads);
+    this.matrix.skewFromAxis(-skew * degToRads, (skewAxis + 90) * degToRads);
+    this.matrix.translate(position[0], position[1], 0);
+    this._mdf = true;
+    if (this.opacity !== effectElements[8].p.v) {
+      this.opacity = effectElements[8].p.v;
+      this._opMdf = true;
+    }
+  }
+};
+
+function SVGTransformEffect(_, filterManager) {
+  this.init(filterManager);
+}
+
+extendPrototype([TransformEffect], SVGTransformEffect);
+
+// Registering expression plugin
+setExpressionsPlugin(Expressions);
+setExpressionInterfaces(getInterface);
+initialize$1();
+initialize();
+registerEffect$1(20, SVGTintFilter, true);
+registerEffect$1(21, SVGFillFilter, true);
+registerEffect$1(22, SVGStrokeEffect, false);
+registerEffect$1(23, SVGTritoneFilter, true);
+registerEffect$1(24, SVGProLevelsFilter, true);
+registerEffect$1(25, SVGDropShadowEffect, true);
+registerEffect$1(28, SVGMatte3Effect, false);
+registerEffect$1(29, SVGGaussianBlurEffect, true);
+registerEffect$1(35, SVGTransformEffect, false);
+
+exports["default"] = lottie;
diff --git a/build/player/cjs/lottie_light.min.js b/build/player/cjs/lottie_light.min.js
new file mode 100644
index 0000000..88eb70d
--- /dev/null
+++ b/build/player/cjs/lottie_light.min.js
@@ -0,0 +1,11584 @@
+'use strict';
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+const svgNS = 'http://www.w3.org/2000/svg';
+
+let locationHref = '';
+let _useWebWorker = false;
+
+const initialDefaultFrame = -999999;
+
+const setWebWorker = (flag) => { _useWebWorker = !!flag; };
+const getWebWorker = () => _useWebWorker;
+
+const setLocationHref = (value) => { locationHref = value; };
+const getLocationHref = () => locationHref;
+
+function createTag(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElement(type);
+}
+
+function extendPrototype(sources, destination) {
+  var i;
+  var len = sources.length;
+  var sourcePrototype;
+  for (i = 0; i < len; i += 1) {
+    sourcePrototype = sources[i].prototype;
+    for (var attr in sourcePrototype) {
+      if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
+    }
+  }
+}
+
+function getDescriptor(object, prop) {
+  return Object.getOwnPropertyDescriptor(object, prop);
+}
+
+function createProxyFunction(prototype) {
+  function ProxyFunction() {}
+  ProxyFunction.prototype = prototype;
+  return ProxyFunction;
+}
+
+// import Howl from '../../3rd_party/howler';
+
+const audioControllerFactory = (function () {
+  function AudioController(audioFactory) {
+    this.audios = [];
+    this.audioFactory = audioFactory;
+    this._volume = 1;
+    this._isMuted = false;
+  }
+
+  AudioController.prototype = {
+    addAudio: function (audio) {
+      this.audios.push(audio);
+    },
+    pause: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].pause();
+      }
+    },
+    resume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].resume();
+      }
+    },
+    setRate: function (rateValue) {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].setRate(rateValue);
+      }
+    },
+    createAudio: function (assetPath) {
+      if (this.audioFactory) {
+        return this.audioFactory(assetPath);
+      } if (window.Howl) {
+        return new window.Howl({
+          src: [assetPath],
+        });
+      }
+      return {
+        isPlaying: false,
+        play: function () { this.isPlaying = true; },
+        seek: function () { this.isPlaying = false; },
+        playing: function () {},
+        rate: function () {},
+        setVolume: function () {},
+      };
+    },
+    setAudioFactory: function (audioFactory) {
+      this.audioFactory = audioFactory;
+    },
+    setVolume: function (value) {
+      this._volume = value;
+      this._updateVolume();
+    },
+    mute: function () {
+      this._isMuted = true;
+      this._updateVolume();
+    },
+    unmute: function () {
+      this._isMuted = false;
+      this._updateVolume();
+    },
+    getVolume: function () {
+      return this._volume;
+    },
+    _updateVolume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
+      }
+    },
+  };
+
+  return function () {
+    return new AudioController();
+  };
+}());
+
+const createTypedArray = (function () {
+  function createRegularArray(type, len) {
+    var i = 0;
+    var arr = [];
+    var value;
+    switch (type) {
+      case 'int16':
+      case 'uint8c':
+        value = 1;
+        break;
+      default:
+        value = 1.1;
+        break;
+    }
+    for (i = 0; i < len; i += 1) {
+      arr.push(value);
+    }
+    return arr;
+  }
+  function createTypedArrayFactory(type, len) {
+    if (type === 'float32') {
+      return new Float32Array(len);
+    } if (type === 'int16') {
+      return new Int16Array(len);
+    } if (type === 'uint8c') {
+      return new Uint8ClampedArray(len);
+    }
+    return createRegularArray(type, len);
+  }
+  if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
+    return createTypedArrayFactory;
+  }
+  return createRegularArray;
+}());
+
+function createSizedArray(len) {
+  return Array.apply(null, { length: len });
+}
+
+let subframeEnabled = true;
+let expressionsPlugin = null;
+let expressionsInterfaces = null;
+let idPrefix$1 = '';
+const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+let _shouldRoundValues = false;
+const bmPow = Math.pow;
+const bmSqrt = Math.sqrt;
+const bmFloor = Math.floor;
+const bmMax = Math.max;
+const bmMin = Math.min;
+
+const BMMath = {};
+(function () {
+  var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
+  var i;
+  var len = propertyNames.length;
+  for (i = 0; i < len; i += 1) {
+    BMMath[propertyNames[i]] = Math[propertyNames[i]];
+  }
+}());
+
+function ProjectInterface$1() { return {}; }
+BMMath.random = Math.random;
+BMMath.abs = function (val) {
+  var tOfVal = typeof val;
+  if (tOfVal === 'object' && val.length) {
+    var absArr = createSizedArray(val.length);
+    var i;
+    var len = val.length;
+    for (i = 0; i < len; i += 1) {
+      absArr[i] = Math.abs(val[i]);
+    }
+    return absArr;
+  }
+  return Math.abs(val);
+};
+let defaultCurveSegments = 150;
+const degToRads = Math.PI / 180;
+const roundCorner = 0.5519;
+
+function roundValues(flag) {
+  _shouldRoundValues = !!flag;
+}
+
+function bmRnd(value) {
+  if (_shouldRoundValues) {
+    return Math.round(value);
+  }
+  return value;
+}
+
+function styleDiv(element) {
+  element.style.position = 'absolute';
+  element.style.top = 0;
+  element.style.left = 0;
+  element.style.display = 'block';
+  element.style.transformOrigin = '0 0';
+  element.style.webkitTransformOrigin = '0 0';
+  element.style.backfaceVisibility = 'visible';
+  element.style.webkitBackfaceVisibility = 'visible';
+  element.style.transformStyle = 'preserve-3d';
+  element.style.webkitTransformStyle = 'preserve-3d';
+  element.style.mozTransformStyle = 'preserve-3d';
+}
+
+function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
+  this.type = type;
+  this.currentTime = currentTime;
+  this.totalTime = totalTime;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteEvent(type, frameMultiplier) {
+  this.type = type;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
+  this.type = type;
+  this.currentLoop = currentLoop;
+  this.totalLoops = totalLoops;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMSegmentStartEvent(type, firstFrame, totalFrames) {
+  this.type = type;
+  this.firstFrame = firstFrame;
+  this.totalFrames = totalFrames;
+}
+
+function BMDestroyEvent(type, target) {
+  this.type = type;
+  this.target = target;
+}
+
+function BMRenderFrameErrorEvent(nativeError, currentTime) {
+  this.type = 'renderFrameError';
+  this.nativeError = nativeError;
+  this.currentTime = currentTime;
+}
+
+function BMConfigErrorEvent(nativeError) {
+  this.type = 'configError';
+  this.nativeError = nativeError;
+}
+
+function BMAnimationConfigErrorEvent(type, nativeError) {
+  this.type = type;
+  this.nativeError = nativeError;
+}
+
+const createElementID = (function () {
+  var _count = 0;
+  return function createID() {
+    _count += 1;
+    return idPrefix$1 + '__lottie_element_' + _count;
+  };
+}());
+
+function HSVtoRGB(h, s, v) {
+  var r;
+  var g;
+  var b;
+  var i;
+  var f;
+  var p;
+  var q;
+  var t;
+  i = Math.floor(h * 6);
+  f = h * 6 - i;
+  p = v * (1 - s);
+  q = v * (1 - f * s);
+  t = v * (1 - (1 - f) * s);
+  switch (i % 6) {
+    case 0: r = v; g = t; b = p; break;
+    case 1: r = q; g = v; b = p; break;
+    case 2: r = p; g = v; b = t; break;
+    case 3: r = p; g = q; b = v; break;
+    case 4: r = t; g = p; b = v; break;
+    case 5: r = v; g = p; b = q; break;
+    default: break;
+  }
+  return [r,
+    g,
+    b];
+}
+
+function RGBtoHSV(r, g, b) {
+  var max = Math.max(r, g, b);
+  var min = Math.min(r, g, b);
+  var d = max - min;
+  var h;
+  var s = (max === 0 ? 0 : d / max);
+  var v = max / 255;
+
+  switch (max) {
+    case min: h = 0; break;
+    case r: h = (g - b) + d * (g < b ? 6 : 0); h /= 6 * d; break;
+    case g: h = (b - r) + d * 2; h /= 6 * d; break;
+    case b: h = (r - g) + d * 4; h /= 6 * d; break;
+    default: break;
+  }
+
+  return [
+    h,
+    s,
+    v,
+  ];
+}
+
+function addSaturationToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[1] += offset;
+  if (hsv[1] > 1) {
+    hsv[1] = 1;
+  } else if (hsv[1] <= 0) {
+    hsv[1] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addBrightnessToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[2] += offset;
+  if (hsv[2] > 1) {
+    hsv[2] = 1;
+  } else if (hsv[2] < 0) {
+    hsv[2] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addHueToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[0] += offset / 360;
+  if (hsv[0] > 1) {
+    hsv[0] -= 1;
+  } else if (hsv[0] < 0) {
+    hsv[0] += 1;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+const rgbToHex = (function () {
+  var colorMap = [];
+  var i;
+  var hex;
+  for (i = 0; i < 256; i += 1) {
+    hex = i.toString(16);
+    colorMap[i] = hex.length === 1 ? '0' + hex : hex;
+  }
+
+  return function (r, g, b) {
+    if (r < 0) {
+      r = 0;
+    }
+    if (g < 0) {
+      g = 0;
+    }
+    if (b < 0) {
+      b = 0;
+    }
+    return '#' + colorMap[r] + colorMap[g] + colorMap[b];
+  };
+}());
+
+const setSubframeEnabled = (flag) => { subframeEnabled = !!flag; };
+const getSubframeEnabled = () => subframeEnabled;
+const setExpressionsPlugin = (value) => { expressionsPlugin = value; };
+const getExpressionsPlugin = () => expressionsPlugin;
+const setExpressionInterfaces = (value) => { expressionsInterfaces = value; };
+const getExpressionInterfaces = () => expressionsInterfaces;
+const setDefaultCurveSegments = (value) => { defaultCurveSegments = value; };
+const getDefaultCurveSegments = () => defaultCurveSegments;
+const setIdPrefix = (value) => { idPrefix$1 = value; };
+const getIdPrefix = () => idPrefix$1;
+
+function createNS(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElementNS(svgNS, type);
+}
+
+const dataManager = (function () {
+  var _counterId = 1;
+  var processes = [];
+  var workerFn;
+  var workerInstance;
+  var workerProxy = {
+    onmessage: function () {
+
+    },
+    postMessage: function (path) {
+      workerFn({
+        data: path,
+      });
+    },
+  };
+  var _workerSelf = {
+    postMessage: function (data) {
+      workerProxy.onmessage({
+        data: data,
+      });
+    },
+  };
+  function createWorker(fn) {
+    if (window.Worker && window.Blob && getWebWorker()) {
+      var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      var url = URL.createObjectURL(blob);
+      return new Worker(url);
+    }
+    workerFn = fn;
+    return workerProxy;
+  }
+
+  function setupWorker() {
+    if (!workerInstance) {
+      workerInstance = createWorker(function workerStart(e) {
+        function dataFunctionManager() {
+          function completeLayers(layers, comps) {
+            var layerData;
+            var i;
+            var len = layers.length;
+            var j;
+            var jLen;
+            var k;
+            var kLen;
+            for (i = 0; i < len; i += 1) {
+              layerData = layers[i];
+              if (('ks' in layerData) && !layerData.completed) {
+                layerData.completed = true;
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      convertPathsToAbsoluteValues(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) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 0) {
+                  layerData.layers = findCompLayers(layerData.refId, comps);
+                  completeLayers(layerData.layers, comps);
+                } else if (layerData.ty === 4) {
+                  completeShapes(layerData.shapes);
+                } else if (layerData.ty === 5) {
+                  completeText(layerData);
+                }
+              }
+            }
+          }
+
+          function completeChars(chars, assets) {
+            if (chars) {
+              var i = 0;
+              var len = chars.length;
+              for (i = 0; i < len; i += 1) {
+                if (chars[i].t === 1) {
+                  // var compData = findComp(chars[i].data.refId, assets);
+                  chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                  // chars[i].data.ip = 0;
+                  // chars[i].data.op = 99999;
+                  // chars[i].data.st = 0;
+                  // chars[i].data.sr = 1;
+                  // chars[i].w = compData.w;
+                  // chars[i].data.ks = {
+                  //   a: { k: [0, 0, 0], a: 0 },
+                  //   p: { k: [0, -compData.h, 0], a: 0 },
+                  //   r: { k: 0, a: 0 },
+                  //   s: { k: [100, 100], a: 0 },
+                  //   o: { k: 100, a: 0 },
+                  // };
+                  completeLayers(chars[i].data.layers, assets);
+                }
+              }
+            }
+          }
+
+          function findComp(id, comps) {
+            var i = 0;
+            var len = comps.length;
+            while (i < len) {
+              if (comps[i].id === id) {
+                return comps[i];
+              }
+              i += 1;
+            }
+            return null;
+          }
+
+          function findCompLayers(id, comps) {
+            var comp = findComp(id, comps);
+            if (comp) {
+              if (!comp.layers.__used) {
+                comp.layers.__used = true;
+                return comp.layers;
+              }
+              return JSON.parse(JSON.stringify(comp.layers));
+            }
+            return null;
+          }
+
+          function completeShapes(arr) {
+            var i;
+            var len = arr.length;
+            var j;
+            var jLen;
+            for (i = len - 1; i >= 0; i -= 1) {
+              if (arr[i].ty === 'sh') {
+                if (arr[i].ks.k.i) {
+                  convertPathsToAbsoluteValues(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) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
+                    }
+                    if (arr[i].ks.k[j].e) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
+                    }
+                  }
+                }
+              } else if (arr[i].ty === 'gr') {
+                completeShapes(arr[i].it);
+              }
+            }
+          }
+
+          function convertPathsToAbsoluteValues(path) {
+            var i;
+            var len = path.i.length;
+            for (i = 0; i < len; i += 1) {
+              path.i[i][0] += path.v[i][0];
+              path.i[i][1] += path.v[i][1];
+              path.o[i][0] += path.v[i][0];
+              path.o[i][1] += path.v[i][1];
+            }
+          }
+
+          function checkVersion(minimum, animVersionString) {
+            var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
+            if (minimum[0] > animVersion[0]) {
+              return true;
+            } if (animVersion[0] > minimum[0]) {
+              return false;
+            }
+            if (minimum[1] > animVersion[1]) {
+              return true;
+            } if (animVersion[1] > minimum[1]) {
+              return false;
+            }
+            if (minimum[2] > animVersion[2]) {
+              return true;
+            } if (animVersion[2] > minimum[2]) {
+              return false;
+            }
+            return null;
+          }
+
+          var checkText = (function () {
+            var minimumVersion = [4, 4, 14];
+
+            function updateTextLayer(textLayer) {
+              var documentData = textLayer.t.d;
+              textLayer.t.d = {
+                k: [
+                  {
+                    s: documentData,
+                    t: 0,
+                  },
+                ],
+              };
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkChars = (function () {
+            var minimumVersion = [4, 7, 99];
+            return function (animationData) {
+              if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
+                var i;
+                var len = animationData.chars.length;
+                for (i = 0; i < len; i += 1) {
+                  var charData = animationData.chars[i];
+                  if (charData.data && charData.data.shapes) {
+                    completeShapes(charData.data.shapes);
+                    charData.data.ip = 0;
+                    charData.data.op = 99999;
+                    charData.data.st = 0;
+                    charData.data.sr = 1;
+                    charData.data.ks = {
+                      p: { k: [0, 0], a: 0 },
+                      s: { k: [100, 100], a: 0 },
+                      a: { k: [0, 0], a: 0 },
+                      r: { k: 0, a: 0 },
+                      o: { k: 100, a: 0 },
+                    };
+                    if (!animationData.chars[i].t) {
+                      charData.data.shapes.push(
+                        {
+                          ty: 'no',
+                        }
+                      );
+                      charData.data.shapes[0].it.push(
+                        {
+                          p: { k: [0, 0], a: 0 },
+                          s: { k: [100, 100], a: 0 },
+                          a: { k: [0, 0], a: 0 },
+                          r: { k: 0, a: 0 },
+                          o: { k: 100, a: 0 },
+                          sk: { k: 0, a: 0 },
+                          sa: { k: 0, a: 0 },
+                          ty: 'tr',
+                        }
+                      );
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkPathProperties = (function () {
+            var minimumVersion = [5, 7, 15];
+
+            function updateTextLayer(textLayer) {
+              var pathData = textLayer.t.p;
+              if (typeof pathData.a === 'number') {
+                pathData.a = {
+                  a: 0,
+                  k: pathData.a,
+                };
+              }
+              if (typeof pathData.p === 'number') {
+                pathData.p = {
+                  a: 0,
+                  k: pathData.p,
+                };
+              }
+              if (typeof pathData.r === 'number') {
+                pathData.r = {
+                  a: 0,
+                  k: pathData.r,
+                };
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkColors = (function () {
+            var minimumVersion = [4, 1, 9];
+
+            function iterateShapes(shapes) {
+              var i;
+              var len = shapes.length;
+              var j;
+              var jLen;
+              for (i = 0; i < len; i += 1) {
+                if (shapes[i].ty === 'gr') {
+                  iterateShapes(shapes[i].it);
+                } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
+                  if (shapes[i].c.k && shapes[i].c.k[0].i) {
+                    jLen = shapes[i].c.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (shapes[i].c.k[j].s) {
+                        shapes[i].c.k[j].s[0] /= 255;
+                        shapes[i].c.k[j].s[1] /= 255;
+                        shapes[i].c.k[j].s[2] /= 255;
+                        shapes[i].c.k[j].s[3] /= 255;
+                      }
+                      if (shapes[i].c.k[j].e) {
+                        shapes[i].c.k[j].e[0] /= 255;
+                        shapes[i].c.k[j].e[1] /= 255;
+                        shapes[i].c.k[j].e[2] /= 255;
+                        shapes[i].c.k[j].e[3] /= 255;
+                      }
+                    }
+                  } else {
+                    shapes[i].c.k[0] /= 255;
+                    shapes[i].c.k[1] /= 255;
+                    shapes[i].c.k[2] /= 255;
+                    shapes[i].c.k[3] /= 255;
+                  }
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 4) {
+                  iterateShapes(layers[i].shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkShapes = (function () {
+            var minimumVersion = [4, 4, 18];
+
+            function completeClosingShapes(arr) {
+              var i;
+              var len = arr.length;
+              var j;
+              var jLen;
+              for (i = len - 1; i >= 0; i -= 1) {
+                if (arr[i].ty === 'sh') {
+                  if (arr[i].ks.k.i) {
+                    arr[i].ks.k.c = arr[i].closed;
+                  } else {
+                    jLen = arr[i].ks.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (arr[i].ks.k[j].s) {
+                        arr[i].ks.k[j].s[0].c = arr[i].closed;
+                      }
+                      if (arr[i].ks.k[j].e) {
+                        arr[i].ks.k[j].e[0].c = arr[i].closed;
+                      }
+                    }
+                  }
+                } else if (arr[i].ty === 'gr') {
+                  completeClosingShapes(arr[i].it);
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var layerData;
+              var i;
+              var len = layers.length;
+              var j;
+              var jLen;
+              var k;
+              var kLen;
+              for (i = 0; i < len; i += 1) {
+                layerData = layers[i];
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      maskProps[j].pt.k.c = maskProps[j].cl;
+                    } else {
+                      kLen = maskProps[j].pt.k.length;
+                      for (k = 0; k < kLen; k += 1) {
+                        if (maskProps[j].pt.k[k].s) {
+                          maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 4) {
+                  completeClosingShapes(layerData.shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          function completeData(animationData) {
+            if (animationData.__complete) {
+              return;
+            }
+            checkColors(animationData);
+            checkText(animationData);
+            checkChars(animationData);
+            checkPathProperties(animationData);
+            checkShapes(animationData);
+            completeLayers(animationData.layers, animationData.assets);
+            completeChars(animationData.chars, animationData.assets);
+            animationData.__complete = true;
+          }
+
+          function completeText(data) {
+            if (data.t.a.length === 0 && !('m' in data.t.p)) {
+              // data.singleShape = true;
+            }
+          }
+
+          var moduleOb = {};
+          moduleOb.completeData = completeData;
+          moduleOb.checkColors = checkColors;
+          moduleOb.checkChars = checkChars;
+          moduleOb.checkPathProperties = checkPathProperties;
+          moduleOb.checkShapes = checkShapes;
+          moduleOb.completeLayers = completeLayers;
+
+          return moduleOb;
+        }
+        if (!_workerSelf.dataManager) {
+          _workerSelf.dataManager = dataFunctionManager();
+        }
+
+        if (!_workerSelf.assetLoader) {
+          _workerSelf.assetLoader = (function () {
+            function formatResponse(xhr) {
+              // using typeof doubles the time of execution of this method,
+              // so if available, it's better to use the header to validate the type
+              var contentTypeHeader = xhr.getResponseHeader('content-type');
+              if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
+                return xhr.response;
+              }
+              if (xhr.response && typeof xhr.response === 'object') {
+                return xhr.response;
+              } if (xhr.response && typeof xhr.response === 'string') {
+                return JSON.parse(xhr.response);
+              } if (xhr.responseText) {
+                return JSON.parse(xhr.responseText);
+              }
+              return null;
+            }
+
+            function loadAsset(path, fullPath, callback, errorCallback) {
+              var response;
+              var xhr = new XMLHttpRequest();
+              // set responseType after calling open or IE will break.
+              try {
+                // This crashes on Android WebView prior to KitKat
+                xhr.responseType = 'json';
+              } catch (err) {} // eslint-disable-line no-empty
+              xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4) {
+                  if (xhr.status === 200) {
+                    response = formatResponse(xhr);
+                    callback(response);
+                  } else {
+                    try {
+                      response = formatResponse(xhr);
+                      callback(response);
+                    } catch (err) {
+                      if (errorCallback) {
+                        errorCallback(err);
+                      }
+                    }
+                  }
+                }
+              };
+              try {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), path, true);
+              } catch (error) {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
+              }
+              xhr.send();
+            }
+            return {
+              load: loadAsset,
+            };
+          }());
+        }
+
+        if (e.data.type === 'loadAnimation') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.dataManager.completeData(data);
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        } else if (e.data.type === 'complete') {
+          var animation = e.data.animation;
+          _workerSelf.dataManager.completeData(animation);
+          _workerSelf.postMessage({
+            id: e.data.id,
+            payload: animation,
+            status: 'success',
+          });
+        } else if (e.data.type === 'loadData') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        }
+      });
+
+      workerInstance.onmessage = function (event) {
+        var data = event.data;
+        var id = data.id;
+        var process = processes[id];
+        processes[id] = null;
+        if (data.status === 'success') {
+          process.onComplete(data.payload);
+        } else if (process.onError) {
+          process.onError();
+        }
+      };
+    }
+  }
+
+  function createProcess(onComplete, onError) {
+    _counterId += 1;
+    var id = 'processId_' + _counterId;
+    processes[id] = {
+      onComplete: onComplete,
+      onError: onError,
+    };
+    return id;
+  }
+
+  function loadAnimation(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadAnimation',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function loadData(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadData',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function completeAnimation(anim, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'complete',
+      animation: anim,
+      id: processId,
+    });
+  }
+
+  return {
+    loadAnimation: loadAnimation,
+    loadData: loadData,
+    completeAnimation: completeAnimation,
+  };
+}());
+
+const ImagePreloader = (function () {
+  var proxyImage = (function () {
+    var canvas = createTag('canvas');
+    canvas.width = 1;
+    canvas.height = 1;
+    var ctx = canvas.getContext('2d');
+    ctx.fillStyle = 'rgba(0,0,0,0)';
+    ctx.fillRect(0, 0, 1, 1);
+    return canvas;
+  }());
+
+  function imageLoaded() {
+    this.loadedAssets += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+  function footageLoaded() {
+    this.loadedFootagesCount += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+
+  function getAssetsPath(assetData, assetsPath, originalPath) {
+    var path = '';
+    if (assetData.e) {
+      path = assetData.p;
+    } else if (assetsPath) {
+      var imagePath = assetData.p;
+      if (imagePath.indexOf('images/') !== -1) {
+        imagePath = imagePath.split('/')[1];
+      }
+      path = assetsPath + imagePath;
+    } else {
+      path = originalPath;
+      path += assetData.u ? assetData.u : '';
+      path += assetData.p;
+    }
+    return path;
+  }
+
+  function testImageLoaded(img) {
+    var _count = 0;
+    var intervalId = setInterval(function () {
+      var box = img.getBBox();
+      if (box.width || _count > 500) {
+        this._imageLoaded();
+        clearInterval(intervalId);
+      }
+      _count += 1;
+    }.bind(this), 50);
+  }
+
+  function createImageData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createNS('image');
+    if (isSafari) {
+      this.testImageLoaded(img);
+    } else {
+      img.addEventListener('load', this._imageLoaded, false);
+    }
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
+    if (this._elementHelper.append) {
+      this._elementHelper.append(img);
+    } else {
+      this._elementHelper.appendChild(img);
+    }
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createImgData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createTag('img');
+    img.crossOrigin = 'anonymous';
+    img.addEventListener('load', this._imageLoaded, false);
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.src = path;
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createFootageData(data) {
+    var ob = {
+      assetData: data,
+    };
+    var path = getAssetsPath(data, this.assetsPath, this.path);
+    dataManager.loadData(path, function (footageData) {
+      ob.img = footageData;
+      this._footageLoaded();
+    }.bind(this), function () {
+      ob.img = {};
+      this._footageLoaded();
+    }.bind(this));
+    return ob;
+  }
+
+  function loadAssets(assets, cb) {
+    this.imagesLoadedCb = cb;
+    var i;
+    var len = assets.length;
+    for (i = 0; i < len; i += 1) {
+      if (!assets[i].layers) {
+        if (!assets[i].t || assets[i].t === 'seq') {
+          this.totalImages += 1;
+          this.images.push(this._createImageData(assets[i]));
+        } else if (assets[i].t === 3) {
+          this.totalFootages += 1;
+          this.images.push(this.createFootageData(assets[i]));
+        }
+      }
+    }
+  }
+
+  function setPath(path) {
+    this.path = path || '';
+  }
+
+  function setAssetsPath(path) {
+    this.assetsPath = path || '';
+  }
+
+  function getAsset(assetData) {
+    var i = 0;
+    var len = this.images.length;
+    while (i < len) {
+      if (this.images[i].assetData === assetData) {
+        return this.images[i].img;
+      }
+      i += 1;
+    }
+    return null;
+  }
+
+  function destroy() {
+    this.imagesLoadedCb = null;
+    this.images.length = 0;
+  }
+
+  function loadedImages() {
+    return this.totalImages === this.loadedAssets;
+  }
+
+  function loadedFootages() {
+    return this.totalFootages === this.loadedFootagesCount;
+  }
+
+  function setCacheType(type, elementHelper) {
+    if (type === 'svg') {
+      this._elementHelper = elementHelper;
+      this._createImageData = this.createImageData.bind(this);
+    } else {
+      this._createImageData = this.createImgData.bind(this);
+    }
+  }
+
+  function ImagePreloaderFactory() {
+    this._imageLoaded = imageLoaded.bind(this);
+    this._footageLoaded = footageLoaded.bind(this);
+    this.testImageLoaded = testImageLoaded.bind(this);
+    this.createFootageData = createFootageData.bind(this);
+    this.assetsPath = '';
+    this.path = '';
+    this.totalImages = 0;
+    this.totalFootages = 0;
+    this.loadedAssets = 0;
+    this.loadedFootagesCount = 0;
+    this.imagesLoadedCb = null;
+    this.images = [];
+  }
+
+  ImagePreloaderFactory.prototype = {
+    loadAssets: loadAssets,
+    setAssetsPath: setAssetsPath,
+    setPath: setPath,
+    loadedImages: loadedImages,
+    loadedFootages: loadedFootages,
+    destroy: destroy,
+    getAsset: getAsset,
+    createImgData: createImgData,
+    createImageData: createImageData,
+    imageLoaded: imageLoaded,
+    footageLoaded: footageLoaded,
+    setCacheType: setCacheType,
+  };
+
+  return ImagePreloaderFactory;
+}());
+
+function BaseEvent() {}
+BaseEvent.prototype = {
+  triggerEvent: function (eventName, args) {
+    if (this._cbs[eventName]) {
+      var callbacks = this._cbs[eventName];
+      for (var i = 0; i < callbacks.length; i += 1) {
+        callbacks[i](args);
+      }
+    }
+  },
+  addEventListener: function (eventName, callback) {
+    if (!this._cbs[eventName]) {
+      this._cbs[eventName] = [];
+    }
+    this._cbs[eventName].push(callback);
+
+    return function () {
+      this.removeEventListener(eventName, callback);
+    }.bind(this);
+  },
+  removeEventListener: function (eventName, callback) {
+    if (!callback) {
+      this._cbs[eventName] = null;
+    } else if (this._cbs[eventName]) {
+      var i = 0;
+      var len = this._cbs[eventName].length;
+      while (i < len) {
+        if (this._cbs[eventName][i] === callback) {
+          this._cbs[eventName].splice(i, 1);
+          i -= 1;
+          len -= 1;
+        }
+        i += 1;
+      }
+      if (!this._cbs[eventName].length) {
+        this._cbs[eventName] = null;
+      }
+    }
+  },
+};
+
+const markerParser = (
+
+  function () {
+    function parsePayloadLines(payload) {
+      var lines = payload.split('\r\n');
+      var keys = {};
+      var line;
+      var keysCount = 0;
+      for (var i = 0; i < lines.length; i += 1) {
+        line = lines[i].split(':');
+        if (line.length === 2) {
+          keys[line[0]] = line[1].trim();
+          keysCount += 1;
+        }
+      }
+      if (keysCount === 0) {
+        throw new Error();
+      }
+      return keys;
+    }
+
+    return function (_markers) {
+      var markers = [];
+      for (var i = 0; i < _markers.length; i += 1) {
+        var _marker = _markers[i];
+        var markerData = {
+          time: _marker.tm,
+          duration: _marker.dr,
+        };
+        try {
+          markerData.payload = JSON.parse(_markers[i].cm);
+        } catch (_) {
+          try {
+            markerData.payload = parsePayloadLines(_markers[i].cm);
+          } catch (__) {
+            markerData.payload = {
+              name: _markers[i].cm,
+            };
+          }
+        }
+        markers.push(markerData);
+      }
+      return markers;
+    };
+  }());
+
+const ProjectInterface = (function () {
+  function registerComposition(comp) {
+    this.compositions.push(comp);
+  }
+
+  return function () {
+    function _thisProjectFunction(name) {
+      var i = 0;
+      var len = this.compositions.length;
+      while (i < len) {
+        if (this.compositions[i].data && this.compositions[i].data.nm === name) {
+          if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
+            this.compositions[i].prepareFrame(this.currentFrame);
+          }
+          return this.compositions[i].compInterface;
+        }
+        i += 1;
+      }
+      return null;
+    }
+
+    _thisProjectFunction.compositions = [];
+    _thisProjectFunction.currentFrame = 0;
+
+    _thisProjectFunction.registerComposition = registerComposition;
+
+    return _thisProjectFunction;
+  };
+}());
+
+const renderers = {};
+
+const registerRenderer = (key, value) => {
+  renderers[key] = value;
+};
+
+function getRenderer(key) {
+  return renderers[key];
+}
+
+function getRegisteredRenderer() {
+  // Returns canvas by default for compatibility
+  if (renderers.canvas) {
+    return 'canvas';
+  }
+  // Returns any renderer that is registered
+  for (const key in renderers) {
+    if (renderers[key]) {
+      return key;
+    }
+  }
+  return '';
+}
+
+const AnimationItem = function () {
+  this._cbs = [];
+  this.name = '';
+  this.path = '';
+  this.isLoaded = false;
+  this.currentFrame = 0;
+  this.currentRawFrame = 0;
+  this.firstFrame = 0;
+  this.totalFrames = 0;
+  this.frameRate = 0;
+  this.frameMult = 0;
+  this.playSpeed = 1;
+  this.playDirection = 1;
+  this.playCount = 0;
+  this.animationData = {};
+  this.assets = [];
+  this.isPaused = true;
+  this.autoplay = false;
+  this.loop = true;
+  this.renderer = null;
+  this.animationID = createElementID();
+  this.assetsPath = '';
+  this.timeCompleted = 0;
+  this.segmentPos = 0;
+  this.isSubframeEnabled = getSubframeEnabled();
+  this.segments = [];
+  this._idle = true;
+  this._completedLoop = false;
+  this.projectInterface = ProjectInterface();
+  this.imagePreloader = new ImagePreloader();
+  this.audioController = audioControllerFactory();
+  this.markers = [];
+  this.configAnimation = this.configAnimation.bind(this);
+  this.onSetupError = this.onSetupError.bind(this);
+  this.onSegmentComplete = this.onSegmentComplete.bind(this);
+  this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
+  this.expressionsPlugin = getExpressionsPlugin();
+};
+
+extendPrototype([BaseEvent], AnimationItem);
+
+AnimationItem.prototype.setParams = function (params) {
+  if (params.wrapper || params.container) {
+    this.wrapper = params.wrapper || params.container;
+  }
+  var animType = 'svg';
+  if (params.animType) {
+    animType = params.animType;
+  } else if (params.renderer) {
+    animType = params.renderer;
+  }
+  const RendererClass = getRenderer(animType);
+  this.renderer = new RendererClass(this, params.rendererSettings);
+  this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
+  this.renderer.setProjectInterface(this.projectInterface);
+  this.animType = animType;
+  if (params.loop === ''
+        || params.loop === null
+        || params.loop === undefined
+        || params.loop === true) {
+    this.loop = true;
+  } else if (params.loop === false) {
+    this.loop = false;
+  } else {
+    this.loop = parseInt(params.loop, 10);
+  }
+  this.autoplay = 'autoplay' in params ? params.autoplay : true;
+  this.name = params.name ? params.name : '';
+  this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
+  this.assetsPath = params.assetsPath;
+  this.initialSegment = params.initialSegment;
+  if (params.audioFactory) {
+    this.audioController.setAudioFactory(params.audioFactory);
+  }
+  if (params.animationData) {
+    this.setupAnimation(params.animationData);
+  } else if (params.path) {
+    if (params.path.lastIndexOf('\\') !== -1) {
+      this.path = params.path.substr(0, params.path.lastIndexOf('\\') + 1);
+    } else {
+      this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
+    }
+    this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
+    this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
+    dataManager.loadAnimation(
+      params.path,
+      this.configAnimation,
+      this.onSetupError
+    );
+  }
+};
+
+AnimationItem.prototype.onSetupError = function () {
+  this.trigger('data_failed');
+};
+
+AnimationItem.prototype.setupAnimation = function (data) {
+  dataManager.completeAnimation(
+    data,
+    this.configAnimation
+  );
+};
+
+AnimationItem.prototype.setData = function (wrapper, animationData) {
+  if (animationData) {
+    if (typeof animationData !== 'object') {
+      animationData = JSON.parse(animationData);
+    }
+  }
+  var params = {
+    wrapper: wrapper,
+    animationData: animationData,
+  };
+  var wrapperAttributes = wrapper.attributes;
+
+  params.path = wrapperAttributes.getNamedItem('data-animation-path') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-animation-path').value
+    : wrapperAttributes.getNamedItem('data-bm-path') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-path').value
+      : wrapperAttributes.getNamedItem('bm-path')
+        ? wrapperAttributes.getNamedItem('bm-path').value
+        : '';
+  params.animType = wrapperAttributes.getNamedItem('data-anim-type') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-type').value
+    : wrapperAttributes.getNamedItem('data-bm-type') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-type').value
+      : wrapperAttributes.getNamedItem('bm-type') // eslint-disable-line no-nested-ternary
+        ? wrapperAttributes.getNamedItem('bm-type').value
+        : wrapperAttributes.getNamedItem('data-bm-renderer') // eslint-disable-line no-nested-ternary
+          ? wrapperAttributes.getNamedItem('data-bm-renderer').value
+          : wrapperAttributes.getNamedItem('bm-renderer')
+            ? wrapperAttributes.getNamedItem('bm-renderer').value
+            : getRegisteredRenderer() || 'canvas';
+
+  var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-loop').value
+    : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-loop').value
+      : wrapperAttributes.getNamedItem('bm-loop')
+        ? wrapperAttributes.getNamedItem('bm-loop').value
+        : '';
+  if (loop === 'false') {
+    params.loop = false;
+  } else if (loop === 'true') {
+    params.loop = true;
+  } else if (loop !== '') {
+    params.loop = parseInt(loop, 10);
+  }
+  var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-autoplay').value
+    : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-autoplay').value
+      : wrapperAttributes.getNamedItem('bm-autoplay')
+        ? wrapperAttributes.getNamedItem('bm-autoplay').value
+        : true;
+  params.autoplay = autoplay !== 'false';
+
+  params.name = wrapperAttributes.getNamedItem('data-name') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-name').value
+    : wrapperAttributes.getNamedItem('data-bm-name') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-name').value
+      : wrapperAttributes.getNamedItem('bm-name')
+        ? wrapperAttributes.getNamedItem('bm-name').value
+        : '';
+  var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-prerender').value
+    : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-prerender').value
+      : wrapperAttributes.getNamedItem('bm-prerender')
+        ? wrapperAttributes.getNamedItem('bm-prerender').value
+        : '';
+
+  if (prerender === 'false') {
+    params.prerender = false;
+  }
+  if (!params.path) {
+    this.trigger('destroy');
+  } else {
+    this.setParams(params);
+  }
+};
+
+AnimationItem.prototype.includeLayers = function (data) {
+  if (data.op > this.animationData.op) {
+    this.animationData.op = data.op;
+    this.totalFrames = Math.floor(data.op - this.animationData.ip);
+  }
+  var layers = this.animationData.layers;
+  var i;
+  var len = layers.length;
+  var newLayers = data.layers;
+  var j;
+  var jLen = newLayers.length;
+  for (j = 0; j < jLen; j += 1) {
+    i = 0;
+    while (i < len) {
+      if (layers[i].id === newLayers[j].id) {
+        layers[i] = newLayers[j];
+        break;
+      }
+      i += 1;
+    }
+  }
+  if (data.chars || data.fonts) {
+    this.renderer.globalData.fontManager.addChars(data.chars);
+    this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
+  }
+  if (data.assets) {
+    len = data.assets.length;
+    for (i = 0; i < len; i += 1) {
+      this.animationData.assets.push(data.assets[i]);
+    }
+  }
+  this.animationData.__complete = false;
+  dataManager.completeAnimation(
+    this.animationData,
+    this.onSegmentComplete
+  );
+};
+
+AnimationItem.prototype.onSegmentComplete = function (data) {
+  this.animationData = data;
+  var expressionsPlugin = getExpressionsPlugin();
+  if (expressionsPlugin) {
+    expressionsPlugin.initExpressions(this);
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.loadNextSegment = function () {
+  var segments = this.animationData.segments;
+  if (!segments || segments.length === 0 || !this.autoloadSegments) {
+    this.trigger('data_ready');
+    this.timeCompleted = this.totalFrames;
+    return;
+  }
+  var segment = segments.shift();
+  this.timeCompleted = segment.time * this.frameRate;
+  var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
+  this.segmentPos += 1;
+  dataManager.loadData(segmentPath, this.includeLayers.bind(this), function () {
+    this.trigger('data_failed');
+  }.bind(this));
+};
+
+AnimationItem.prototype.loadSegments = function () {
+  var segments = this.animationData.segments;
+  if (!segments) {
+    this.timeCompleted = this.totalFrames;
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.imagesLoaded = function () {
+  this.trigger('loaded_images');
+  this.checkLoaded();
+};
+
+AnimationItem.prototype.preloadImages = function () {
+  this.imagePreloader.setAssetsPath(this.assetsPath);
+  this.imagePreloader.setPath(this.path);
+  this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
+};
+
+AnimationItem.prototype.configAnimation = function (animData) {
+  if (!this.renderer) {
+    return;
+  }
+  try {
+    this.animationData = animData;
+    if (this.initialSegment) {
+      this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
+      this.firstFrame = Math.round(this.initialSegment[0]);
+    } else {
+      this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
+      this.firstFrame = Math.round(this.animationData.ip);
+    }
+    this.renderer.configAnimation(animData);
+    if (!animData.assets) {
+      animData.assets = [];
+    }
+
+    this.assets = this.animationData.assets;
+    this.frameRate = this.animationData.fr;
+    this.frameMult = this.animationData.fr / 1000;
+    this.renderer.searchExtraCompositions(animData.assets);
+    this.markers = markerParser(animData.markers || []);
+    this.trigger('config_ready');
+    this.preloadImages();
+    this.loadSegments();
+    this.updaFrameModifier();
+    this.waitForFontsLoaded();
+    if (this.isPaused) {
+      this.audioController.pause();
+    }
+  } catch (error) {
+    this.triggerConfigError(error);
+  }
+};
+
+AnimationItem.prototype.waitForFontsLoaded = function () {
+  if (!this.renderer) {
+    return;
+  }
+  if (this.renderer.globalData.fontManager.isLoaded) {
+    this.checkLoaded();
+  } else {
+    setTimeout(this.waitForFontsLoaded.bind(this), 20);
+  }
+};
+
+AnimationItem.prototype.checkLoaded = function () {
+  if (!this.isLoaded
+        && this.renderer.globalData.fontManager.isLoaded
+        && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas')
+        && (this.imagePreloader.loadedFootages())
+  ) {
+    this.isLoaded = true;
+    var expressionsPlugin = getExpressionsPlugin();
+    if (expressionsPlugin) {
+      expressionsPlugin.initExpressions(this);
+    }
+    this.renderer.initItems();
+    setTimeout(function () {
+      this.trigger('DOMLoaded');
+    }.bind(this), 0);
+    this.gotoFrame();
+    if (this.autoplay) {
+      this.play();
+    }
+  }
+};
+
+AnimationItem.prototype.resize = function (width, height) {
+  // Adding this validation for backwards compatibility in case an event object was being passed down
+  var _width = typeof width === 'number' ? width : undefined;
+  var _height = typeof height === 'number' ? height : undefined;
+  this.renderer.updateContainerSize(_width, _height);
+};
+
+AnimationItem.prototype.setSubframe = function (flag) {
+  this.isSubframeEnabled = !!flag;
+};
+
+AnimationItem.prototype.gotoFrame = function () {
+  this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
+
+  if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
+    this.currentFrame = this.timeCompleted;
+  }
+  this.trigger('enterFrame');
+  this.renderFrame();
+  this.trigger('drawnFrame');
+};
+
+AnimationItem.prototype.renderFrame = function () {
+  if (this.isLoaded === false || !this.renderer) {
+    return;
+  }
+  try {
+    if (this.expressionsPlugin) {
+      this.expressionsPlugin.resetFrame();
+    }
+    this.renderer.renderFrame(this.currentFrame + this.firstFrame);
+  } catch (error) {
+    this.triggerRenderFrameError(error);
+  }
+};
+
+AnimationItem.prototype.play = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.isPaused = false;
+    this.trigger('_play');
+    this.audioController.resume();
+    if (this._idle) {
+      this._idle = false;
+      this.trigger('_active');
+    }
+  }
+};
+
+AnimationItem.prototype.pause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === false) {
+    this.isPaused = true;
+    this.trigger('_pause');
+    this._idle = true;
+    this.trigger('_idle');
+    this.audioController.pause();
+  }
+};
+
+AnimationItem.prototype.togglePause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.play();
+  } else {
+    this.pause();
+  }
+};
+
+AnimationItem.prototype.stop = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.pause();
+  this.playCount = 0;
+  this._completedLoop = false;
+  this.setCurrentRawFrameValue(0);
+};
+
+AnimationItem.prototype.getMarkerData = function (markerName) {
+  var marker;
+  for (var i = 0; i < this.markers.length; i += 1) {
+    marker = this.markers[i];
+    if (marker.payload && marker.payload.name === markerName) {
+      return marker;
+    }
+  }
+  return null;
+};
+
+AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      this.goToAndStop(marker.time, true);
+    }
+  } else if (isFrame) {
+    this.setCurrentRawFrameValue(value);
+  } else {
+    this.setCurrentRawFrameValue(value * this.frameModifier);
+  }
+  this.pause();
+};
+
+AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      if (!marker.duration) {
+        this.goToAndStop(marker.time, true);
+      } else {
+        this.playSegments([marker.time, marker.time + marker.duration], true);
+      }
+    }
+  } else {
+    this.goToAndStop(numValue, isFrame, name);
+  }
+  this.play();
+};
+
+AnimationItem.prototype.advanceTime = function (value) {
+  if (this.isPaused === true || this.isLoaded === false) {
+    return;
+  }
+  var nextValue = this.currentRawFrame + value * this.frameModifier;
+  var _isComplete = false;
+  // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+  // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
+  if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
+    if (!this.loop || this.playCount === this.loop) {
+      if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
+        _isComplete = true;
+        nextValue = this.totalFrames - 1;
+      }
+    } else if (nextValue >= this.totalFrames) {
+      this.playCount += 1;
+      if (!this.checkSegments(nextValue % this.totalFrames)) {
+        this.setCurrentRawFrameValue(nextValue % this.totalFrames);
+        this._completedLoop = true;
+        this.trigger('loopComplete');
+      }
+    } else {
+      this.setCurrentRawFrameValue(nextValue);
+    }
+  } else if (nextValue < 0) {
+    if (!this.checkSegments(nextValue % this.totalFrames)) {
+      if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) { // eslint-disable-line no-plusplus
+        this.setCurrentRawFrameValue(this.totalFrames + (nextValue % this.totalFrames));
+        if (!this._completedLoop) {
+          this._completedLoop = true;
+        } else {
+          this.trigger('loopComplete');
+        }
+      } else {
+        _isComplete = true;
+        nextValue = 0;
+      }
+    }
+  } else {
+    this.setCurrentRawFrameValue(nextValue);
+  }
+  if (_isComplete) {
+    this.setCurrentRawFrameValue(nextValue);
+    this.pause();
+    this.trigger('complete');
+  }
+};
+
+AnimationItem.prototype.adjustSegment = function (arr, offset) {
+  this.playCount = 0;
+  if (arr[1] < arr[0]) {
+    if (this.frameModifier > 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(-1);
+      }
+    }
+    this.totalFrames = arr[0] - arr[1];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[1];
+    this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset);
+  } else if (arr[1] > arr[0]) {
+    if (this.frameModifier < 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(1);
+      }
+    }
+    this.totalFrames = arr[1] - arr[0];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[0];
+    this.setCurrentRawFrameValue(0.001 + offset);
+  }
+  this.trigger('segmentStart');
+};
+AnimationItem.prototype.setSegment = function (init, end) {
+  var pendingFrame = -1;
+  if (this.isPaused) {
+    if (this.currentRawFrame + this.firstFrame < init) {
+      pendingFrame = init;
+    } else if (this.currentRawFrame + this.firstFrame > end) {
+      pendingFrame = end - init;
+    }
+  }
+
+  this.firstFrame = init;
+  this.totalFrames = end - init;
+  this.timeCompleted = this.totalFrames;
+  if (pendingFrame !== -1) {
+    this.goToAndStop(pendingFrame, true);
+  }
+};
+
+AnimationItem.prototype.playSegments = function (arr, forceFlag) {
+  if (forceFlag) {
+    this.segments.length = 0;
+  }
+  if (typeof arr[0] === 'object') {
+    var i;
+    var len = arr.length;
+    for (i = 0; i < len; i += 1) {
+      this.segments.push(arr[i]);
+    }
+  } else {
+    this.segments.push(arr);
+  }
+  if (this.segments.length && forceFlag) {
+    this.adjustSegment(this.segments.shift(), 0);
+  }
+  if (this.isPaused) {
+    this.play();
+  }
+};
+
+AnimationItem.prototype.resetSegments = function (forceFlag) {
+  this.segments.length = 0;
+  this.segments.push([this.animationData.ip, this.animationData.op]);
+  if (forceFlag) {
+    this.checkSegments(0);
+  }
+};
+AnimationItem.prototype.checkSegments = function (offset) {
+  if (this.segments.length) {
+    this.adjustSegment(this.segments.shift(), offset);
+    return true;
+  }
+  return false;
+};
+
+AnimationItem.prototype.destroy = function (name) {
+  if ((name && this.name !== name) || !this.renderer) {
+    return;
+  }
+  this.renderer.destroy();
+  this.imagePreloader.destroy();
+  this.trigger('destroy');
+  this._cbs = null;
+  this.onEnterFrame = null;
+  this.onLoopComplete = null;
+  this.onComplete = null;
+  this.onSegmentStart = null;
+  this.onDestroy = null;
+  this.renderer = null;
+  this.expressionsPlugin = null;
+  this.imagePreloader = null;
+  this.projectInterface = null;
+};
+
+AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
+  this.currentRawFrame = value;
+  this.gotoFrame();
+};
+
+AnimationItem.prototype.setSpeed = function (val) {
+  this.playSpeed = val;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setDirection = function (val) {
+  this.playDirection = val < 0 ? -1 : 1;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setLoop = function (isLooping) {
+  this.loop = isLooping;
+};
+
+AnimationItem.prototype.setVolume = function (val, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.setVolume(val);
+};
+
+AnimationItem.prototype.getVolume = function () {
+  return this.audioController.getVolume();
+};
+
+AnimationItem.prototype.mute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.mute();
+};
+
+AnimationItem.prototype.unmute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.unmute();
+};
+
+AnimationItem.prototype.updaFrameModifier = function () {
+  this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
+  this.audioController.setRate(this.playSpeed * this.playDirection);
+};
+
+AnimationItem.prototype.getPath = function () {
+  return this.path;
+};
+
+AnimationItem.prototype.getAssetsPath = function (assetData) {
+  var path = '';
+  if (assetData.e) {
+    path = assetData.p;
+  } else if (this.assetsPath) {
+    var imagePath = assetData.p;
+    if (imagePath.indexOf('images/') !== -1) {
+      imagePath = imagePath.split('/')[1];
+    }
+    path = this.assetsPath + imagePath;
+  } else {
+    path = this.path;
+    path += assetData.u ? assetData.u : '';
+    path += assetData.p;
+  }
+  return path;
+};
+
+AnimationItem.prototype.getAssetData = function (id) {
+  var i = 0;
+  var len = this.assets.length;
+  while (i < len) {
+    if (id === this.assets[i].id) {
+      return this.assets[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+AnimationItem.prototype.hide = function () {
+  this.renderer.hide();
+};
+
+AnimationItem.prototype.show = function () {
+  this.renderer.show();
+};
+
+AnimationItem.prototype.getDuration = function (isFrame) {
+  return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
+};
+
+AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
+  try {
+    var element = this.renderer.getElementByPath(path);
+    element.updateDocumentData(documentData, index);
+  } catch (error) {
+    // TODO: decide how to handle catch case
+  }
+};
+
+AnimationItem.prototype.trigger = function (name) {
+  if (this._cbs && this._cbs[name]) {
+    switch (name) {
+      case 'enterFrame':
+        this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
+        break;
+      case 'drawnFrame':
+        this.drawnFrameEvent.currentTime = this.currentFrame;
+        this.drawnFrameEvent.totalTime = this.totalFrames;
+        this.drawnFrameEvent.direction = this.frameModifier;
+        this.triggerEvent(name, this.drawnFrameEvent);
+        break;
+      case 'loopComplete':
+        this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+        break;
+      case 'complete':
+        this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
+        break;
+      case 'segmentStart':
+        this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+        break;
+      case 'destroy':
+        this.triggerEvent(name, new BMDestroyEvent(name, this));
+        break;
+      default:
+        this.triggerEvent(name);
+    }
+  }
+  if (name === 'enterFrame' && this.onEnterFrame) {
+    this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
+  }
+  if (name === 'loopComplete' && this.onLoopComplete) {
+    this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+  }
+  if (name === 'complete' && this.onComplete) {
+    this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
+  }
+  if (name === 'segmentStart' && this.onSegmentStart) {
+    this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+  }
+  if (name === 'destroy' && this.onDestroy) {
+    this.onDestroy.call(this, new BMDestroyEvent(name, this));
+  }
+};
+
+AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
+  var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+AnimationItem.prototype.triggerConfigError = function (nativeError) {
+  var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+const animationManager = (function () {
+  var moduleOb = {};
+  var registeredAnimations = [];
+  var initTime = 0;
+  var len = 0;
+  var playingAnimationsNum = 0;
+  var _stopped = true;
+  var _isFrozen = false;
+
+  function removeElement(ev) {
+    var i = 0;
+    var animItem = ev.target;
+    while (i < len) {
+      if (registeredAnimations[i].animation === animItem) {
+        registeredAnimations.splice(i, 1);
+        i -= 1;
+        len -= 1;
+        if (!animItem.isPaused) {
+          subtractPlayingCount();
+        }
+      }
+      i += 1;
+    }
+  }
+
+  function registerAnimation(element, animationData) {
+    if (!element) {
+      return null;
+    }
+    var i = 0;
+    while (i < len) {
+      if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
+        return registeredAnimations[i].animation;
+      }
+      i += 1;
+    }
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, element);
+    animItem.setData(element, animationData);
+    return animItem;
+  }
+
+  function getRegisteredAnimations() {
+    var i;
+    var lenAnims = registeredAnimations.length;
+    var animations = [];
+    for (i = 0; i < lenAnims; i += 1) {
+      animations.push(registeredAnimations[i].animation);
+    }
+    return animations;
+  }
+
+  function addPlayingCount() {
+    playingAnimationsNum += 1;
+    activate();
+  }
+
+  function subtractPlayingCount() {
+    playingAnimationsNum -= 1;
+  }
+
+  function setupAnimation(animItem, element) {
+    animItem.addEventListener('destroy', removeElement);
+    animItem.addEventListener('_active', addPlayingCount);
+    animItem.addEventListener('_idle', subtractPlayingCount);
+    registeredAnimations.push({ elem: element, animation: animItem });
+    len += 1;
+  }
+
+  function loadAnimation(params) {
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, null);
+    animItem.setParams(params);
+    return animItem;
+  }
+
+  function setSpeed(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setSpeed(val, animation);
+    }
+  }
+
+  function setDirection(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setDirection(val, animation);
+    }
+  }
+
+  function play(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.play(animation);
+    }
+  }
+  function resume(nowTime) {
+    var elapsedTime = nowTime - initTime;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.advanceTime(elapsedTime);
+    }
+    initTime = nowTime;
+    if (playingAnimationsNum && !_isFrozen) {
+      window.requestAnimationFrame(resume);
+    } else {
+      _stopped = true;
+    }
+  }
+
+  function first(nowTime) {
+    initTime = nowTime;
+    window.requestAnimationFrame(resume);
+  }
+
+  function pause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.pause(animation);
+    }
+  }
+
+  function goToAndStop(value, isFrame, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
+    }
+  }
+
+  function stop(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.stop(animation);
+    }
+  }
+
+  function togglePause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.togglePause(animation);
+    }
+  }
+
+  function destroy(animation) {
+    var i;
+    for (i = (len - 1); i >= 0; i -= 1) {
+      registeredAnimations[i].animation.destroy(animation);
+    }
+  }
+
+  function searchAnimations(animationData, standalone, renderer) {
+    var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')),
+      [].slice.call(document.getElementsByClassName('bodymovin')));
+    var i;
+    var lenAnims = animElements.length;
+    for (i = 0; i < lenAnims; i += 1) {
+      if (renderer) {
+        animElements[i].setAttribute('data-bm-type', renderer);
+      }
+      registerAnimation(animElements[i], animationData);
+    }
+    if (standalone && lenAnims === 0) {
+      if (!renderer) {
+        renderer = 'svg';
+      }
+      var body = document.getElementsByTagName('body')[0];
+      body.innerText = '';
+      var div = createTag('div');
+      div.style.width = '100%';
+      div.style.height = '100%';
+      div.setAttribute('data-bm-type', renderer);
+      body.appendChild(div);
+      registerAnimation(div, animationData);
+    }
+  }
+
+  function resize() {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.resize();
+    }
+  }
+
+  function activate() {
+    if (!_isFrozen && playingAnimationsNum) {
+      if (_stopped) {
+        window.requestAnimationFrame(first);
+        _stopped = false;
+      }
+    }
+  }
+
+  function freeze() {
+    _isFrozen = true;
+  }
+
+  function unfreeze() {
+    _isFrozen = false;
+    activate();
+  }
+
+  function setVolume(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setVolume(val, animation);
+    }
+  }
+
+  function mute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.mute(animation);
+    }
+  }
+
+  function unmute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.unmute(animation);
+    }
+  }
+
+  moduleOb.registerAnimation = registerAnimation;
+  moduleOb.loadAnimation = loadAnimation;
+  moduleOb.setSpeed = setSpeed;
+  moduleOb.setDirection = setDirection;
+  moduleOb.play = play;
+  moduleOb.pause = pause;
+  moduleOb.stop = stop;
+  moduleOb.togglePause = togglePause;
+  moduleOb.searchAnimations = searchAnimations;
+  moduleOb.resize = resize;
+  // moduleOb.start = start;
+  moduleOb.goToAndStop = goToAndStop;
+  moduleOb.destroy = destroy;
+  moduleOb.freeze = freeze;
+  moduleOb.unfreeze = unfreeze;
+  moduleOb.setVolume = setVolume;
+  moduleOb.mute = mute;
+  moduleOb.unmute = unmute;
+  moduleOb.getRegisteredAnimations = getRegisteredAnimations;
+  return moduleOb;
+}());
+
+/* eslint-disable */
+const BezierFactory = (function () {
+  /**
+     * BezierEasing - use bezier curve for transition easing function
+     * by Gaëtan Renaudeau 2014 - 2015 – MIT License
+     *
+     * Credits: is based on Firefox's nsSMILKeySpline.cpp
+     * Usage:
+     * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
+     * spline.get(x) => returns the easing value | x must be in [0, 1] range
+     *
+     */
+
+  var ob = {};
+  ob.getBezierEasing = getBezierEasing;
+  var beziers = {};
+
+  function getBezierEasing(a, b, c, d, nm) {
+    var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
+    if (beziers[str]) {
+      return beziers[str];
+    }
+    var bezEasing = new BezierEasing([a, b, c, d]);
+    beziers[str] = bezEasing;
+    return bezEasing;
+  }
+
+  // These values are established by empiricism with tests (tradeoff: performance VS precision)
+  var NEWTON_ITERATIONS = 4;
+  var NEWTON_MIN_SLOPE = 0.001;
+  var SUBDIVISION_PRECISION = 0.0000001;
+  var SUBDIVISION_MAX_ITERATIONS = 10;
+
+  var kSplineTableSize = 11;
+  var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
+
+  var float32ArraySupported = typeof Float32Array === 'function';
+
+  function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
+  function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
+  function C(aA1) { return 3.0 * aA1; }
+
+  // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+  function calcBezier(aT, aA1, aA2) {
+    return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
+  }
+
+  // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+  function getSlope(aT, aA1, aA2) {
+    return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
+  }
+
+  function binarySubdivide(aX, aA, aB, mX1, mX2) {
+    var currentX,
+      currentT,
+      i = 0;
+    do {
+      currentT = aA + (aB - aA) / 2.0;
+      currentX = calcBezier(currentT, mX1, mX2) - aX;
+      if (currentX > 0.0) {
+        aB = currentT;
+      } else {
+        aA = currentT;
+      }
+    } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
+    return currentT;
+  }
+
+  function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
+    for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
+      var currentSlope = getSlope(aGuessT, mX1, mX2);
+      if (currentSlope === 0.0) return aGuessT;
+      var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
+      aGuessT -= currentX / currentSlope;
+    }
+    return aGuessT;
+  }
+
+  /**
+     * points is an array of [ mX1, mY1, mX2, mY2 ]
+     */
+  function BezierEasing(points) {
+    this._p = points;
+    this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
+    this._precomputed = false;
+
+    this.get = this.get.bind(this);
+  }
+
+  BezierEasing.prototype = {
+
+    get: function (x) {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      if (!this._precomputed) this._precompute();
+      if (mX1 === mY1 && mX2 === mY2) return x; // linear
+      // Because JavaScript number are imprecise, we should guarantee the extremes are right.
+      if (x === 0) return 0;
+      if (x === 1) return 1;
+      return calcBezier(this._getTForX(x), mY1, mY2);
+    },
+
+    // Private part
+
+    _precompute: function () {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      this._precomputed = true;
+      if (mX1 !== mY1 || mX2 !== mY2) { this._calcSampleValues(); }
+    },
+
+    _calcSampleValues: function () {
+      var mX1 = this._p[0],
+        mX2 = this._p[2];
+      for (var i = 0; i < kSplineTableSize; ++i) {
+        this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
+      }
+    },
+
+    /**
+         * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
+         */
+    _getTForX: function (aX) {
+      var mX1 = this._p[0],
+        mX2 = this._p[2],
+        mSampleValues = this._mSampleValues;
+
+      var intervalStart = 0.0;
+      var currentSample = 1;
+      var lastSample = kSplineTableSize - 1;
+
+      for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
+        intervalStart += kSampleStepSize;
+      }
+      --currentSample;
+
+      // Interpolate to provide an initial guess for t
+      var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
+      var guessForT = intervalStart + dist * kSampleStepSize;
+
+      var initialSlope = getSlope(guessForT, mX1, mX2);
+      if (initialSlope >= NEWTON_MIN_SLOPE) {
+        return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
+      } if (initialSlope === 0.0) {
+        return guessForT;
+      }
+      return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
+    },
+  };
+
+  return ob;
+}());
+
+const pooling = (function () {
+  function double(arr) {
+    return arr.concat(createSizedArray(arr.length));
+  }
+
+  return {
+    double: double,
+  };
+}());
+
+const poolFactory = (function () {
+  return function (initialLength, _create, _release) {
+    var _length = 0;
+    var _maxLength = initialLength;
+    var pool = createSizedArray(_maxLength);
+
+    var ob = {
+      newElement: newElement,
+      release: release,
+    };
+
+    function newElement() {
+      var element;
+      if (_length) {
+        _length -= 1;
+        element = pool[_length];
+      } else {
+        element = _create();
+      }
+      return element;
+    }
+
+    function release(element) {
+      if (_length === _maxLength) {
+        pool = pooling.double(pool);
+        _maxLength *= 2;
+      }
+      if (_release) {
+        _release(element);
+      }
+      pool[_length] = element;
+      _length += 1;
+    }
+
+    return ob;
+  };
+}());
+
+const bezierLengthPool = (function () {
+  function create() {
+    return {
+      addedLength: 0,
+      percents: createTypedArray('float32', getDefaultCurveSegments()),
+      lengths: createTypedArray('float32', getDefaultCurveSegments()),
+    };
+  }
+  return poolFactory(8, create);
+}());
+
+const segmentsLengthPool = (function () {
+  function create() {
+    return {
+      lengths: [],
+      totalLength: 0,
+    };
+  }
+
+  function release(element) {
+    var i;
+    var len = element.lengths.length;
+    for (i = 0; i < len; i += 1) {
+      bezierLengthPool.release(element.lengths[i]);
+    }
+    element.lengths.length = 0;
+  }
+
+  return poolFactory(8, create, release);
+}());
+
+function bezFunction() {
+  var math = Math;
+
+  function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
+    var det1 = (x1 * y2) + (y1 * x3) + (x2 * y3) - (x3 * y2) - (y3 * x1) - (x2 * y1);
+    return det1 > -0.001 && det1 < 0.001;
+  }
+
+  function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
+    if (z1 === 0 && z2 === 0 && z3 === 0) {
+      return pointOnLine2D(x1, y1, x2, y2, x3, y3);
+    }
+    var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
+    var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
+    var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
+    var diffDist;
+    if (dist1 > dist2) {
+      if (dist1 > dist3) {
+        diffDist = dist1 - dist2 - dist3;
+      } else {
+        diffDist = dist3 - dist2 - dist1;
+      }
+    } else if (dist3 > dist2) {
+      diffDist = dist3 - dist2 - dist1;
+    } else {
+      diffDist = dist2 - dist1 - dist3;
+    }
+    return diffDist > -0.0001 && diffDist < 0.0001;
+  }
+
+  var getBezierLength = (function () {
+    return function (pt1, pt2, pt3, pt4) {
+      var curveSegments = getDefaultCurveSegments();
+      var k;
+      var i;
+      var len;
+      var ptCoord;
+      var perc;
+      var addedLength = 0;
+      var ptDistance;
+      var point = [];
+      var lastPoint = [];
+      var lengthData = bezierLengthPool.newElement();
+      len = pt3.length;
+      for (k = 0; k < curveSegments; k += 1) {
+        perc = k / (curveSegments - 1);
+        ptDistance = 0;
+        for (i = 0; i < len; i += 1) {
+          ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
+          point[i] = ptCoord;
+          if (lastPoint[i] !== null) {
+            ptDistance += bmPow(point[i] - lastPoint[i], 2);
+          }
+          lastPoint[i] = point[i];
+        }
+        if (ptDistance) {
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+        }
+        lengthData.percents[k] = perc;
+        lengthData.lengths[k] = addedLength;
+      }
+      lengthData.addedLength = addedLength;
+      return lengthData;
+    };
+  }());
+
+  function getSegmentsLength(shapeData) {
+    var segmentsLength = segmentsLengthPool.newElement();
+    var closed = shapeData.c;
+    var pathV = shapeData.v;
+    var pathO = shapeData.o;
+    var pathI = shapeData.i;
+    var i;
+    var len = shapeData._length;
+    var lengths = segmentsLength.lengths;
+    var totalLength = 0;
+    for (i = 0; i < len - 1; i += 1) {
+      lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
+      totalLength += lengths[i].addedLength;
+    }
+    if (closed && len) {
+      lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
+      totalLength += lengths[i].addedLength;
+    }
+    segmentsLength.totalLength = totalLength;
+    return segmentsLength;
+  }
+
+  function BezierData(length) {
+    this.segmentLength = 0;
+    this.points = new Array(length);
+  }
+
+  function PointData(partial, point) {
+    this.partialLength = partial;
+    this.point = point;
+  }
+
+  var buildBezierData = (function () {
+    var storedData = {};
+
+    return function (pt1, pt2, pt3, pt4) {
+      var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
+      if (!storedData[bezierName]) {
+        var curveSegments = getDefaultCurveSegments();
+        var k;
+        var i;
+        var len;
+        var ptCoord;
+        var perc;
+        var addedLength = 0;
+        var ptDistance;
+        var point;
+        var lastPoint = null;
+        if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
+          curveSegments = 2;
+        }
+        var bezierData = new BezierData(curveSegments);
+        len = pt3.length;
+        for (k = 0; k < curveSegments; k += 1) {
+          point = createSizedArray(len);
+          perc = k / (curveSegments - 1);
+          ptDistance = 0;
+          for (i = 0; i < len; i += 1) {
+            ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
+            point[i] = ptCoord;
+            if (lastPoint !== null) {
+              ptDistance += bmPow(point[i] - lastPoint[i], 2);
+            }
+          }
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+          bezierData.points[k] = new PointData(ptDistance, point);
+          lastPoint = point;
+        }
+        bezierData.segmentLength = addedLength;
+        storedData[bezierName] = bezierData;
+      }
+      return storedData[bezierName];
+    };
+  }());
+
+  function getDistancePerc(perc, bezierData) {
+    var percents = bezierData.percents;
+    var lengths = bezierData.lengths;
+    var len = percents.length;
+    var initPos = bmFloor((len - 1) * perc);
+    var lengthPos = perc * bezierData.addedLength;
+    var lPerc = 0;
+    if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
+      return percents[initPos];
+    }
+    var dir = lengths[initPos] > lengthPos ? -1 : 1;
+    var flag = true;
+    while (flag) {
+      if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
+        lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
+        flag = false;
+      } else {
+        initPos += dir;
+      }
+      if (initPos < 0 || initPos >= len - 1) {
+        // FIX for TypedArrays that don't store floating point values with enough accuracy
+        if (initPos === len - 1) {
+          return percents[initPos];
+        }
+        flag = false;
+      }
+    }
+    return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
+  }
+
+  function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
+    var t1 = getDistancePerc(percent, bezierData);
+    var u1 = 1 - t1;
+    var ptX = math.round((u1 * u1 * u1 * pt1[0] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[0] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[0] + t1 * t1 * t1 * pt2[0]) * 1000) / 1000;
+    var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
+    return [ptX, ptY];
+  }
+
+  var bezierSegmentPoints = createTypedArray('float32', 8);
+
+  function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
+    if (startPerc < 0) {
+      startPerc = 0;
+    } else if (startPerc > 1) {
+      startPerc = 1;
+    }
+    var t0 = getDistancePerc(startPerc, bezierData);
+    endPerc = endPerc > 1 ? 1 : endPerc;
+    var t1 = getDistancePerc(endPerc, bezierData);
+    var i;
+    var len = pt1.length;
+    var u0 = 1 - t0;
+    var u1 = 1 - t1;
+    var u0u0u0 = u0 * u0 * u0;
+    var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0t0 = t0 * t0 * t0;
+    //
+    var u0u0u1 = u0 * u0 * u1;
+    var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0t1 = t0 * t0 * t1;
+    //
+    var u0u1u1 = u0 * u1 * u1;
+    var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1t1 = t0 * t1 * t1;
+    //
+    var u1u1u1 = u1 * u1 * u1;
+    var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1t1 = t1 * t1 * t1;
+    for (i = 0; i < len; i += 1) {
+      bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+    }
+
+    return bezierSegmentPoints;
+  }
+
+  return {
+    getSegmentsLength: getSegmentsLength,
+    getNewSegment: getNewSegment,
+    getPointInSegment: getPointInSegment,
+    buildBezierData: buildBezierData,
+    pointOnLine2D: pointOnLine2D,
+    pointOnLine3D: pointOnLine3D,
+  };
+}
+
+const bez = bezFunction();
+
+var initFrame = initialDefaultFrame;
+var mathAbs = Math.abs;
+
+function interpolateValue(frameNum, caching) {
+  var offsetTime = this.offsetTime;
+  var newValue;
+  if (this.propType === 'multidimensional') {
+    newValue = createTypedArray('float32', this.pv.length);
+  }
+  var iterationIndex = caching.lastIndex;
+  var i = iterationIndex;
+  var len = this.keyframes.length - 1;
+  var flag = true;
+  var keyData;
+  var nextKeyData;
+  var keyframeMetadata;
+
+  while (flag) {
+    keyData = this.keyframes[i];
+    nextKeyData = this.keyframes[i + 1];
+    if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
+      if (keyData.h) {
+        keyData = nextKeyData;
+      }
+      iterationIndex = 0;
+      break;
+    }
+    if ((nextKeyData.t - offsetTime) > frameNum) {
+      iterationIndex = i;
+      break;
+    }
+    if (i < len - 1) {
+      i += 1;
+    } else {
+      iterationIndex = 0;
+      flag = false;
+    }
+  }
+  keyframeMetadata = this.keyframesMetadata[i] || {};
+
+  var k;
+  var kLen;
+  var perc;
+  var jLen;
+  var j;
+  var fnc;
+  var nextKeyTime = nextKeyData.t - offsetTime;
+  var keyTime = keyData.t - offsetTime;
+  var endValue;
+  if (keyData.to) {
+    if (!keyframeMetadata.bezierData) {
+      keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
+    }
+    var bezierData = keyframeMetadata.bezierData;
+    if (frameNum >= nextKeyTime || frameNum < keyTime) {
+      var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
+      kLen = bezierData.points[ind].point.length;
+      for (k = 0; k < kLen; k += 1) {
+        newValue[k] = bezierData.points[ind].point[k];
+      }
+      // caching._lastKeyframeIndex = -1;
+    } else {
+      if (keyframeMetadata.__fnct) {
+        fnc = keyframeMetadata.__fnct;
+      } else {
+        fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
+        keyframeMetadata.__fnct = fnc;
+      }
+      perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+      var distanceInLine = bezierData.segmentLength * perc;
+
+      var segmentPerc;
+      var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0;
+      j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0;
+      flag = true;
+      jLen = bezierData.points.length;
+      while (flag) {
+        addedLength += bezierData.points[j].partialLength;
+        if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k];
+          }
+          break;
+        } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
+          segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
+          }
+          break;
+        }
+        if (j < jLen - 1) {
+          j += 1;
+        } else {
+          flag = false;
+        }
+      }
+      caching._lastPoint = j;
+      caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
+      caching._lastKeyframeIndex = i;
+    }
+  } else {
+    var outX;
+    var outY;
+    var inX;
+    var inY;
+    var keyValue;
+    len = keyData.s.length;
+    endValue = nextKeyData.s || keyData.e;
+    if (this.sh && keyData.h !== 1) {
+      if (frameNum >= nextKeyTime) {
+        newValue[0] = endValue[0];
+        newValue[1] = endValue[1];
+        newValue[2] = endValue[2];
+      } else if (frameNum <= keyTime) {
+        newValue[0] = keyData.s[0];
+        newValue[1] = keyData.s[1];
+        newValue[2] = keyData.s[2];
+      } else {
+        var quatStart = createQuaternion(keyData.s);
+        var quatEnd = createQuaternion(endValue);
+        var time = (frameNum - keyTime) / (nextKeyTime - keyTime);
+        quaternionToEuler(newValue, slerp(quatStart, quatEnd, time));
+      }
+    } else {
+      for (i = 0; i < len; i += 1) {
+        if (keyData.h !== 1) {
+          if (frameNum >= nextKeyTime) {
+            perc = 1;
+          } else if (frameNum < keyTime) {
+            perc = 0;
+          } else {
+            if (keyData.o.x.constructor === Array) {
+              if (!keyframeMetadata.__fnct) {
+                keyframeMetadata.__fnct = [];
+              }
+              if (!keyframeMetadata.__fnct[i]) {
+                outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
+                outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
+                inX = keyData.i.x[i] === undefined ? keyData.i.x[0] : keyData.i.x[i];
+                inY = keyData.i.y[i] === undefined ? keyData.i.y[0] : keyData.i.y[i];
+                fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+                keyframeMetadata.__fnct[i] = fnc;
+              } else {
+                fnc = keyframeMetadata.__fnct[i];
+              }
+            } else if (!keyframeMetadata.__fnct) {
+              outX = keyData.o.x;
+              outY = keyData.o.y;
+              inX = keyData.i.x;
+              inY = keyData.i.y;
+              fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+              keyData.keyframeMetadata = fnc;
+            } else {
+              fnc = keyframeMetadata.__fnct;
+            }
+            perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+          }
+        }
+
+        endValue = nextKeyData.s || keyData.e;
+        keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
+
+        if (this.propType === 'multidimensional') {
+          newValue[i] = keyValue;
+        } else {
+          newValue = keyValue;
+        }
+      }
+    }
+  }
+  caching.lastIndex = iterationIndex;
+  return newValue;
+}
+
+// based on @Toji's https://github.com/toji/gl-matrix/
+function slerp(a, b, t) {
+  var out = [];
+  var ax = a[0];
+  var ay = a[1];
+  var az = a[2];
+  var aw = a[3];
+  var bx = b[0];
+  var by = b[1];
+  var bz = b[2];
+  var bw = b[3];
+
+  var omega;
+  var cosom;
+  var sinom;
+  var scale0;
+  var scale1;
+
+  cosom = ax * bx + ay * by + az * bz + aw * bw;
+  if (cosom < 0.0) {
+    cosom = -cosom;
+    bx = -bx;
+    by = -by;
+    bz = -bz;
+    bw = -bw;
+  }
+  if ((1.0 - cosom) > 0.000001) {
+    omega = Math.acos(cosom);
+    sinom = Math.sin(omega);
+    scale0 = Math.sin((1.0 - t) * omega) / sinom;
+    scale1 = Math.sin(t * omega) / sinom;
+  } else {
+    scale0 = 1.0 - t;
+    scale1 = t;
+  }
+  out[0] = scale0 * ax + scale1 * bx;
+  out[1] = scale0 * ay + scale1 * by;
+  out[2] = scale0 * az + scale1 * bz;
+  out[3] = scale0 * aw + scale1 * bw;
+
+  return out;
+}
+
+function quaternionToEuler(out, quat) {
+  var qx = quat[0];
+  var qy = quat[1];
+  var qz = quat[2];
+  var qw = quat[3];
+  var heading = Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy * qy - 2 * qz * qz);
+  var attitude = Math.asin(2 * qx * qy + 2 * qz * qw);
+  var bank = Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx * qx - 2 * qz * qz);
+  out[0] = heading / degToRads;
+  out[1] = attitude / degToRads;
+  out[2] = bank / degToRads;
+}
+
+function createQuaternion(values) {
+  var heading = values[0] * degToRads;
+  var attitude = values[1] * degToRads;
+  var bank = values[2] * degToRads;
+  var c1 = Math.cos(heading / 2);
+  var c2 = Math.cos(attitude / 2);
+  var c3 = Math.cos(bank / 2);
+  var s1 = Math.sin(heading / 2);
+  var s2 = Math.sin(attitude / 2);
+  var s3 = Math.sin(bank / 2);
+  var w = c1 * c2 * c3 - s1 * s2 * s3;
+  var x = s1 * s2 * c3 + c1 * c2 * s3;
+  var y = s1 * c2 * c3 + c1 * s2 * s3;
+  var z = c1 * s2 * c3 - s1 * c2 * s3;
+
+  return [x, y, z, w];
+}
+
+function getValueAtCurrentTime() {
+  var frameNum = this.comp.renderedFrame - this.offsetTime;
+  var initTime = this.keyframes[0].t - this.offsetTime;
+  var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+  if (!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))) {
+    if (this._caching.lastFrame >= frameNum) {
+      this._caching._lastKeyframeIndex = -1;
+      this._caching.lastIndex = 0;
+    }
+
+    var renderResult = this.interpolateValue(frameNum, this._caching);
+    this.pv = renderResult;
+  }
+  this._caching.lastFrame = frameNum;
+  return this.pv;
+}
+
+function setVValue(val) {
+  var multipliedValue;
+  if (this.propType === 'unidimensional') {
+    multipliedValue = val * this.mult;
+    if (mathAbs(this.v - multipliedValue) > 0.00001) {
+      this.v = multipliedValue;
+      this._mdf = true;
+    }
+  } else {
+    var i = 0;
+    var len = this.v.length;
+    while (i < len) {
+      multipliedValue = val[i] * this.mult;
+      if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
+        this.v[i] = multipliedValue;
+        this._mdf = true;
+      }
+      i += 1;
+    }
+  }
+}
+
+function processEffectsSequence() {
+  if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
+    return;
+  }
+  if (this.lock) {
+    this.setVValue(this.pv);
+    return;
+  }
+  this.lock = true;
+  this._mdf = this._isFirstFrame;
+  var i;
+  var len = this.effectsSequence.length;
+  var finalValue = this.kf ? this.pv : this.data.k;
+  for (i = 0; i < len; i += 1) {
+    finalValue = this.effectsSequence[i](finalValue);
+  }
+  this.setVValue(finalValue);
+  this._isFirstFrame = false;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+}
+
+function addEffect(effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.container.addDynamicProperty(this);
+}
+
+function ValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this.v = mult ? data.k * mult : data.k;
+  this.pv = data.k;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.vel = 0;
+  this.effectsSequence = [];
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function MultiDimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.frameId = -1;
+  var i;
+  var len = data.k.length;
+  this.v = createTypedArray('float32', len);
+  this.pv = createTypedArray('float32', len);
+  this.vel = createTypedArray('float32', len);
+  for (i = 0; i < len; i += 1) {
+    this.v[i] = data.k[i] * this.mult;
+    this.pv[i] = data.k[i];
+  }
+  this._isFirstFrame = true;
+  this.effectsSequence = [];
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function KeyframedValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.frameId = -1;
+  this._caching = {
+    lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1,
+  };
+  this.k = true;
+  this.kf = true;
+  this.data = data;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.v = initFrame;
+  this.pv = initFrame;
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.addEffect = addEffect;
+}
+
+function KeyframedMultidimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  var i;
+  var len = data.k.length;
+  var s;
+  var e;
+  var to;
+  var ti;
+  for (i = 0; i < len - 1; i += 1) {
+    if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
+      s = data.k[i].s;
+      e = data.k[i + 1].s;
+      to = data.k[i].to;
+      ti = data.k[i].ti;
+      if ((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2]))) {
+        data.k[i].to = null;
+        data.k[i].ti = null;
+      }
+      if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
+        if (s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) {
+          data.k[i].to = null;
+          data.k[i].ti = null;
+        }
+      }
+    }
+  }
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.data = data;
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.k = true;
+  this.kf = true;
+  this._isFirstFrame = true;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.frameId = -1;
+  var arrLen = data.k[0].s.length;
+  this.v = createTypedArray('float32', arrLen);
+  this.pv = createTypedArray('float32', arrLen);
+  for (i = 0; i < arrLen; i += 1) {
+    this.v[i] = initFrame;
+    this.pv[i] = initFrame;
+  }
+  this._caching = { lastFrame: initFrame, lastIndex: 0, value: createTypedArray('float32', arrLen) };
+  this.addEffect = addEffect;
+}
+
+const PropertyFactory = (function () {
+  function getProp(elem, data, type, mult, container) {
+    if (data.sid) {
+      data = elem.globalData.slotManager.getProp(data);
+    }
+    var p;
+    if (!data.k.length) {
+      p = new ValueProperty(elem, data, mult, container);
+    } else if (typeof (data.k[0]) === 'number') {
+      p = new MultiDimensionalProperty(elem, data, mult, container);
+    } else {
+      switch (type) {
+        case 0:
+          p = new KeyframedValueProperty(elem, data, mult, container);
+          break;
+        case 1:
+          p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
+          break;
+        default:
+          break;
+      }
+    }
+    if (p.effectsSequence.length) {
+      container.addDynamicProperty(p);
+    }
+    return p;
+  }
+
+  var ob = {
+    getProp: getProp,
+  };
+  return ob;
+}());
+
+function DynamicPropertyContainer() {}
+DynamicPropertyContainer.prototype = {
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+      this.container.addDynamicProperty(this);
+      this._isAnimated = true;
+    }
+  },
+  iterateDynamicProperties: function () {
+    this._mdf = false;
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      this.dynamicProperties[i].getValue();
+      if (this.dynamicProperties[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  },
+  initDynamicPropertyContainer: function (container) {
+    this.container = container;
+    this.dynamicProperties = [];
+    this._mdf = false;
+    this._isAnimated = false;
+  },
+};
+
+const pointPool = (function () {
+  function create() {
+    return createTypedArray('float32', 2);
+  }
+  return poolFactory(8, create);
+}());
+
+function ShapePath() {
+  this.c = false;
+  this._length = 0;
+  this._maxLength = 8;
+  this.v = createSizedArray(this._maxLength);
+  this.o = createSizedArray(this._maxLength);
+  this.i = createSizedArray(this._maxLength);
+}
+
+ShapePath.prototype.setPathData = function (closed, len) {
+  this.c = closed;
+  this.setLength(len);
+  var i = 0;
+  while (i < len) {
+    this.v[i] = pointPool.newElement();
+    this.o[i] = pointPool.newElement();
+    this.i[i] = pointPool.newElement();
+    i += 1;
+  }
+};
+
+ShapePath.prototype.setLength = function (len) {
+  while (this._maxLength < len) {
+    this.doubleArrayLength();
+  }
+  this._length = len;
+};
+
+ShapePath.prototype.doubleArrayLength = function () {
+  this.v = this.v.concat(createSizedArray(this._maxLength));
+  this.i = this.i.concat(createSizedArray(this._maxLength));
+  this.o = this.o.concat(createSizedArray(this._maxLength));
+  this._maxLength *= 2;
+};
+
+ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
+  var arr;
+  this._length = Math.max(this._length, pos + 1);
+  if (this._length >= this._maxLength) {
+    this.doubleArrayLength();
+  }
+  switch (type) {
+    case 'v':
+      arr = this.v;
+      break;
+    case 'i':
+      arr = this.i;
+      break;
+    case 'o':
+      arr = this.o;
+      break;
+    default:
+      arr = [];
+      break;
+  }
+  if (!arr[pos] || (arr[pos] && !replace)) {
+    arr[pos] = pointPool.newElement();
+  }
+  arr[pos][0] = x;
+  arr[pos][1] = y;
+};
+
+ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
+  this.setXYAt(vX, vY, 'v', pos, replace);
+  this.setXYAt(oX, oY, 'o', pos, replace);
+  this.setXYAt(iX, iY, 'i', pos, replace);
+};
+
+ShapePath.prototype.reverse = function () {
+  var newPath = new ShapePath();
+  newPath.setPathData(this.c, this._length);
+  var vertices = this.v;
+  var outPoints = this.o;
+  var inPoints = this.i;
+  var init = 0;
+  if (this.c) {
+    newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
+    init = 1;
+  }
+  var cnt = this._length - 1;
+  var len = this._length;
+
+  var i;
+  for (i = init; i < len; i += 1) {
+    newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
+    cnt -= 1;
+  }
+  return newPath;
+};
+
+ShapePath.prototype.length = function () {
+  return this._length;
+};
+
+const shapePool = (function () {
+  function create() {
+    return new ShapePath();
+  }
+
+  function release(shapePath) {
+    var len = shapePath._length;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      pointPool.release(shapePath.v[i]);
+      pointPool.release(shapePath.i[i]);
+      pointPool.release(shapePath.o[i]);
+      shapePath.v[i] = null;
+      shapePath.i[i] = null;
+      shapePath.o[i] = null;
+    }
+    shapePath._length = 0;
+    shapePath.c = false;
+  }
+
+  function clone(shape) {
+    var cloned = factory.newElement();
+    var i;
+    var len = shape._length === undefined ? shape.v.length : shape._length;
+    cloned.setLength(len);
+    cloned.c = shape.c;
+
+    for (i = 0; i < len; i += 1) {
+      cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
+    }
+    return cloned;
+  }
+
+  var factory = poolFactory(4, create, release);
+  factory.clone = clone;
+
+  return factory;
+}());
+
+function ShapeCollection() {
+  this._length = 0;
+  this._maxLength = 4;
+  this.shapes = createSizedArray(this._maxLength);
+}
+
+ShapeCollection.prototype.addShape = function (shapeData) {
+  if (this._length === this._maxLength) {
+    this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
+    this._maxLength *= 2;
+  }
+  this.shapes[this._length] = shapeData;
+  this._length += 1;
+};
+
+ShapeCollection.prototype.releaseShapes = function () {
+  var i;
+  for (i = 0; i < this._length; i += 1) {
+    shapePool.release(this.shapes[i]);
+  }
+  this._length = 0;
+};
+
+const shapeCollectionPool = (function () {
+  var ob = {
+    newShapeCollection: newShapeCollection,
+    release: release,
+  };
+
+  var _length = 0;
+  var _maxLength = 4;
+  var pool = createSizedArray(_maxLength);
+
+  function newShapeCollection() {
+    var shapeCollection;
+    if (_length) {
+      _length -= 1;
+      shapeCollection = pool[_length];
+    } else {
+      shapeCollection = new ShapeCollection();
+    }
+    return shapeCollection;
+  }
+
+  function release(shapeCollection) {
+    var i;
+    var len = shapeCollection._length;
+    for (i = 0; i < len; i += 1) {
+      shapePool.release(shapeCollection.shapes[i]);
+    }
+    shapeCollection._length = 0;
+
+    if (_length === _maxLength) {
+      pool = pooling.double(pool);
+      _maxLength *= 2;
+    }
+    pool[_length] = shapeCollection;
+    _length += 1;
+  }
+
+  return ob;
+}());
+
+const ShapePropertyFactory = (function () {
+  var initFrame = -999999;
+
+  function interpolateShape(frameNum, previousValue, caching) {
+    var iterationIndex = caching.lastIndex;
+    var keyPropS;
+    var keyPropE;
+    var isHold;
+    var j;
+    var k;
+    var jLen;
+    var kLen;
+    var perc;
+    var vertexValue;
+    var kf = this.keyframes;
+    if (frameNum < kf[0].t - this.offsetTime) {
+      keyPropS = kf[0].s[0];
+      isHold = true;
+      iterationIndex = 0;
+    } else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) {
+      keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
+      /* if(kf[kf.length - 1].s){
+                keyPropS = kf[kf.length - 1].s[0];
+            }else{
+                keyPropS = kf[kf.length - 2].e[0];
+            } */
+      isHold = true;
+    } else {
+      var i = iterationIndex;
+      var len = kf.length - 1;
+      var flag = true;
+      var keyData;
+      var nextKeyData;
+      var keyframeMetadata;
+      while (flag) {
+        keyData = kf[i];
+        nextKeyData = kf[i + 1];
+        if ((nextKeyData.t - this.offsetTime) > frameNum) {
+          break;
+        }
+        if (i < len - 1) {
+          i += 1;
+        } else {
+          flag = false;
+        }
+      }
+      keyframeMetadata = this.keyframesMetadata[i] || {};
+      isHold = keyData.h === 1;
+      iterationIndex = i;
+      if (!isHold) {
+        if (frameNum >= nextKeyData.t - this.offsetTime) {
+          perc = 1;
+        } else if (frameNum < keyData.t - this.offsetTime) {
+          perc = 0;
+        } else {
+          var fnc;
+          if (keyframeMetadata.__fnct) {
+            fnc = keyframeMetadata.__fnct;
+          } else {
+            fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
+            keyframeMetadata.__fnct = fnc;
+          }
+          perc = fnc((frameNum - (keyData.t - this.offsetTime)) / ((nextKeyData.t - this.offsetTime) - (keyData.t - this.offsetTime)));
+        }
+        keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
+      }
+      keyPropS = keyData.s[0];
+    }
+    jLen = previousValue._length;
+    kLen = keyPropS.i[0].length;
+    caching.lastIndex = iterationIndex;
+
+    for (j = 0; j < jLen; j += 1) {
+      for (k = 0; k < kLen; k += 1) {
+        vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
+        previousValue.i[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc;
+        previousValue.o[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc;
+        previousValue.v[j][k] = vertexValue;
+      }
+    }
+  }
+
+  function interpolateShapeCurrentTime() {
+    var frameNum = this.comp.renderedFrame - this.offsetTime;
+    var initTime = this.keyframes[0].t - this.offsetTime;
+    var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+    var lastFrame = this._caching.lastFrame;
+    if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) {
+      /// /
+      this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
+      this.interpolateShape(frameNum, this.pv, this._caching);
+      /// /
+    }
+    this._caching.lastFrame = frameNum;
+    return this.pv;
+  }
+
+  function resetShape() {
+    this.paths = this.localShapeCollection;
+  }
+
+  function shapesEqual(shape1, shape2) {
+    if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
+      return false;
+    }
+    var i;
+    var len = shape1._length;
+    for (i = 0; i < len; i += 1) {
+      if (shape1.v[i][0] !== shape2.v[i][0]
+            || shape1.v[i][1] !== shape2.v[i][1]
+            || shape1.o[i][0] !== shape2.o[i][0]
+            || shape1.o[i][1] !== shape2.o[i][1]
+            || shape1.i[i][0] !== shape2.i[i][0]
+            || shape1.i[i][1] !== shape2.i[i][1]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  function setVValue(newPath) {
+    if (!shapesEqual(this.v, newPath)) {
+      this.v = shapePool.clone(newPath);
+      this.localShapeCollection.releaseShapes();
+      this.localShapeCollection.addShape(this.v);
+      this._mdf = true;
+      this.paths = this.localShapeCollection;
+    }
+  }
+
+  function processEffectsSequence() {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    } if (!this.effectsSequence.length) {
+      this._mdf = false;
+      return;
+    }
+    if (this.lock) {
+      this.setVValue(this.pv);
+      return;
+    }
+    this.lock = true;
+    this._mdf = false;
+    var finalValue;
+    if (this.kf) {
+      finalValue = this.pv;
+    } else if (this.data.ks) {
+      finalValue = this.data.ks.k;
+    } else {
+      finalValue = this.data.pt.k;
+    }
+    var i;
+    var len = this.effectsSequence.length;
+    for (i = 0; i < len; i += 1) {
+      finalValue = this.effectsSequence[i](finalValue);
+    }
+    this.setVValue(finalValue);
+    this.lock = false;
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function ShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.container = elem;
+    this.elem = elem;
+    this.data = data;
+    this.k = false;
+    this.kf = false;
+    this._mdf = false;
+    var pathData = type === 3 ? data.pt.k : data.ks.k;
+    this.v = shapePool.clone(pathData);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.reset = resetShape;
+    this.effectsSequence = [];
+  }
+
+  function addEffect(effectFunction) {
+    this.effectsSequence.push(effectFunction);
+    this.container.addDynamicProperty(this);
+  }
+
+  ShapeProperty.prototype.interpolateShape = interpolateShape;
+  ShapeProperty.prototype.getValue = processEffectsSequence;
+  ShapeProperty.prototype.setVValue = setVValue;
+  ShapeProperty.prototype.addEffect = addEffect;
+
+  function KeyframedShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.elem = elem;
+    this.container = elem;
+    this.offsetTime = elem.data.st;
+    this.keyframes = type === 3 ? data.pt.k : data.ks.k;
+    this.keyframesMetadata = [];
+    this.k = true;
+    this.kf = true;
+    var len = this.keyframes[0].s[0].i.length;
+    this.v = shapePool.newElement();
+    this.v.setPathData(this.keyframes[0].s[0].c, len);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.lastFrame = initFrame;
+    this.reset = resetShape;
+    this._caching = { lastFrame: initFrame, lastIndex: 0 };
+    this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
+  }
+  KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
+  KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
+  KeyframedShapeProperty.prototype.setVValue = setVValue;
+  KeyframedShapeProperty.prototype.addEffect = addEffect;
+
+  var EllShapeProperty = (function () {
+    var cPoint = roundCorner;
+
+    function EllShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 4);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.paths = this.localShapeCollection;
+      this.localShapeCollection.addShape(this.v);
+      this.d = data.d;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertEllToPath();
+      }
+    }
+
+    EllShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+
+        if (this._mdf) {
+          this.convertEllToPath();
+        }
+      },
+      convertEllToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var s0 = this.s.v[0] / 2;
+        var s1 = this.s.v[1] / 2;
+        var _cw = this.d !== 3;
+        var _v = this.v;
+        _v.v[0][0] = p0;
+        _v.v[0][1] = p1 - s1;
+        _v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.v[1][1] = p1;
+        _v.v[2][0] = p0;
+        _v.v[2][1] = p1 + s1;
+        _v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.v[3][1] = p1;
+        _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.i[0][1] = p1 - s1;
+        _v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.i[1][1] = p1 - s1 * cPoint;
+        _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.i[2][1] = p1 + s1;
+        _v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.i[3][1] = p1 + s1 * cPoint;
+        _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.o[0][1] = p1 - s1;
+        _v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.o[1][1] = p1 + s1 * cPoint;
+        _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.o[2][1] = p1 + s1;
+        _v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.o[3][1] = p1 - s1 * cPoint;
+      },
+    };
+
+    extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
+
+    return EllShapePropertyFactory;
+  }());
+
+  var StarShapeProperty = (function () {
+    function StarShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 0);
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.data = data;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      if (data.sy === 1) {
+        this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
+        this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
+        this.convertToPath = this.convertStarToPath;
+      } else {
+        this.convertToPath = this.convertPolygonToPath;
+      }
+      this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
+      this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this);
+      this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertToPath();
+      }
+    }
+
+    StarShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertToPath();
+        }
+      },
+      convertStarToPath: function () {
+        var numPts = Math.floor(this.pt.v) * 2;
+        var angle = (Math.PI * 2) / numPts;
+        /* this.v.v.length = numPts;
+                this.v.i.length = numPts;
+                this.v.o.length = numPts; */
+        var longFlag = true;
+        var longRad = this.or.v;
+        var shortRad = this.ir.v;
+        var longRound = this.os.v;
+        var shortRound = this.is.v;
+        var longPerimSegment = (2 * Math.PI * longRad) / (numPts * 2);
+        var shortPerimSegment = (2 * Math.PI * shortRad) / (numPts * 2);
+        var i;
+        var rad;
+        var roundness;
+        var perimSegment;
+        var currentAng = -Math.PI / 2;
+        currentAng += this.r.v;
+        var dir = this.data.d === 3 ? -1 : 1;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          rad = longFlag ? longRad : shortRad;
+          roundness = longFlag ? longRound : shortRound;
+          perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
+          /* this.v.v[i] = [x,y];
+                    this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
+                    this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
+                    this.v._length = numPts; */
+          longFlag = !longFlag;
+          currentAng += angle * dir;
+        }
+      },
+      convertPolygonToPath: function () {
+        var numPts = Math.floor(this.pt.v);
+        var angle = (Math.PI * 2) / numPts;
+        var rad = this.or.v;
+        var roundness = this.os.v;
+        var perimSegment = (2 * Math.PI * rad) / (numPts * 4);
+        var i;
+        var currentAng = -Math.PI * 0.5;
+        var dir = this.data.d === 3 ? -1 : 1;
+        currentAng += this.r.v;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+          currentAng += angle * dir;
+        }
+        this.paths.length = 0;
+        this.paths[0] = this.v;
+      },
+
+    };
+    extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
+
+    return StarShapePropertyFactory;
+  }());
+
+  var RectShapeProperty = (function () {
+    function RectShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.c = true;
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertRectToPath();
+      }
+    }
+
+    RectShapePropertyFactory.prototype = {
+      convertRectToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var v0 = this.s.v[0] / 2;
+        var v1 = this.s.v[1] / 2;
+        var round = bmMin(v0, v1, this.r.v);
+        var cPoint = round * (1 - roundCorner);
+        this.v._length = 0;
+
+        if (this.d === 2 || this.d === 1) {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
+          this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2);
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3);
+          }
+        } else {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true);
+          }
+        }
+      },
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertRectToPath();
+        }
+      },
+      reset: resetShape,
+    };
+    extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
+
+    return RectShapePropertyFactory;
+  }());
+
+  function getShapeProp(elem, data, type) {
+    var prop;
+    if (type === 3 || type === 4) {
+      var dataProp = type === 3 ? data.pt : data.ks;
+      var keys = dataProp.k;
+      if (keys.length) {
+        prop = new KeyframedShapeProperty(elem, data, type);
+      } else {
+        prop = new ShapeProperty(elem, data, type);
+      }
+    } else if (type === 5) {
+      prop = new RectShapeProperty(elem, data);
+    } else if (type === 6) {
+      prop = new EllShapeProperty(elem, data);
+    } else if (type === 7) {
+      prop = new StarShapeProperty(elem, data);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  }
+
+  function getConstructorFunction() {
+    return ShapeProperty;
+  }
+
+  function getKeyframedConstructorFunction() {
+    return KeyframedShapeProperty;
+  }
+
+  var ob = {};
+  ob.getShapeProp = getShapeProp;
+  ob.getConstructorFunction = getConstructorFunction;
+  ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction;
+  return ob;
+}());
+
+/*!
+ Transformation Matrix v2.0
+ (c) Epistemex 2014-2015
+ www.epistemex.com
+ By Ken Fyrstenberg
+ Contributions by leeoniya.
+ License: MIT, header required.
+ */
+
+/**
+ * 2D transformation matrix object initialized with identity matrix.
+ *
+ * The matrix can synchronize a canvas context by supplying the context
+ * as an argument, or later apply current absolute transform to an
+ * existing context.
+ *
+ * All values are handled as floating point values.
+ *
+ * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix
+ * @prop {number} a - scale x
+ * @prop {number} b - shear y
+ * @prop {number} c - shear x
+ * @prop {number} d - scale y
+ * @prop {number} e - translate x
+ * @prop {number} f - translate y
+ * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context
+ * @constructor
+ */
+
+const Matrix = (function () {
+  var _cos = Math.cos;
+  var _sin = Math.sin;
+  var _tan = Math.tan;
+  var _rnd = Math.round;
+
+  function reset() {
+    this.props[0] = 1;
+    this.props[1] = 0;
+    this.props[2] = 0;
+    this.props[3] = 0;
+    this.props[4] = 0;
+    this.props[5] = 1;
+    this.props[6] = 0;
+    this.props[7] = 0;
+    this.props[8] = 0;
+    this.props[9] = 0;
+    this.props[10] = 1;
+    this.props[11] = 0;
+    this.props[12] = 0;
+    this.props[13] = 0;
+    this.props[14] = 0;
+    this.props[15] = 1;
+    return this;
+  }
+
+  function rotate(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function rotateX(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateY(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateZ(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function shear(sx, sy) {
+    return this._t(1, sy, sx, 1, 0, 0);
+  }
+
+  function skew(ax, ay) {
+    return this.shear(_tan(ax), _tan(ay));
+  }
+
+  function skewFromAxis(ax, angle) {
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+    // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+  }
+
+  function scale(sx, sy, sz) {
+    if (!sz && sz !== 0) {
+      sz = 1;
+    }
+    if (sx === 1 && sy === 1 && sz === 1) {
+      return this;
+    }
+    return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
+  }
+
+  function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
+    this.props[0] = a;
+    this.props[1] = b;
+    this.props[2] = c;
+    this.props[3] = d;
+    this.props[4] = e;
+    this.props[5] = f;
+    this.props[6] = g;
+    this.props[7] = h;
+    this.props[8] = i;
+    this.props[9] = j;
+    this.props[10] = k;
+    this.props[11] = l;
+    this.props[12] = m;
+    this.props[13] = n;
+    this.props[14] = o;
+    this.props[15] = p;
+    return this;
+  }
+
+  function translate(tx, ty, tz) {
+    tz = tz || 0;
+    if (tx !== 0 || ty !== 0 || tz !== 0) {
+      return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
+    }
+    return this;
+  }
+
+  function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
+    var _p = this.props;
+
+    if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
+      // NOTE: commenting this condition because TurboFan deoptimizes code when present
+      // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
+      _p[12] = _p[12] * a2 + _p[15] * m2;
+      _p[13] = _p[13] * f2 + _p[15] * n2;
+      _p[14] = _p[14] * k2 + _p[15] * o2;
+      _p[15] *= p2;
+      // }
+      this._identityCalculated = false;
+      return this;
+    }
+
+    var a1 = _p[0];
+    var b1 = _p[1];
+    var c1 = _p[2];
+    var d1 = _p[3];
+    var e1 = _p[4];
+    var f1 = _p[5];
+    var g1 = _p[6];
+    var h1 = _p[7];
+    var i1 = _p[8];
+    var j1 = _p[9];
+    var k1 = _p[10];
+    var l1 = _p[11];
+    var m1 = _p[12];
+    var n1 = _p[13];
+    var o1 = _p[14];
+    var p1 = _p[15];
+
+    /* matrix order (canvas compatible):
+         * ace
+         * bdf
+         * 001
+         */
+    _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
+    _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
+    _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
+    _p[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2;
+
+    _p[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2;
+    _p[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2;
+    _p[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2;
+    _p[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2;
+
+    _p[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2;
+    _p[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2;
+    _p[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2;
+    _p[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2;
+
+    _p[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2;
+    _p[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2;
+    _p[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2;
+    _p[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2;
+
+    this._identityCalculated = false;
+    return this;
+  }
+
+  function multiply(matrix) {
+    var matrixProps = matrix.props;
+    return this.transform(
+      matrixProps[0],
+      matrixProps[1],
+      matrixProps[2],
+      matrixProps[3],
+      matrixProps[4],
+      matrixProps[5],
+      matrixProps[6],
+      matrixProps[7],
+      matrixProps[8],
+      matrixProps[9],
+      matrixProps[10],
+      matrixProps[11],
+      matrixProps[12],
+      matrixProps[13],
+      matrixProps[14],
+      matrixProps[15]
+    );
+  }
+
+  function isIdentity() {
+    if (!this._identityCalculated) {
+      this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
+      this._identityCalculated = true;
+    }
+    return this._identity;
+  }
+
+  function equals(matr) {
+    var i = 0;
+    while (i < 16) {
+      if (matr.props[i] !== this.props[i]) {
+        return false;
+      }
+      i += 1;
+    }
+    return true;
+  }
+
+  function clone(matr) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      matr.props[i] = this.props[i];
+    }
+    return matr;
+  }
+
+  function cloneFromProps(props) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      this.props[i] = props[i];
+    }
+  }
+
+  function applyToPoint(x, y, z) {
+    return {
+      x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+      y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+      z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+    };
+    /* return {
+         x: x * me.a + y * me.c + me.e,
+         y: x * me.b + y * me.d + me.f
+         }; */
+  }
+  function applyToX(x, y, z) {
+    return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
+  }
+  function applyToY(x, y, z) {
+    return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
+  }
+  function applyToZ(x, y, z) {
+    return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
+  }
+
+  function getInverseMatrix() {
+    var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
+    var a = this.props[5] / determinant;
+    var b = -this.props[1] / determinant;
+    var c = -this.props[4] / determinant;
+    var d = this.props[0] / determinant;
+    var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12]) / determinant;
+    var f = -(this.props[0] * this.props[13] - this.props[1] * this.props[12]) / determinant;
+    var inverseMatrix = new Matrix();
+    inverseMatrix.props[0] = a;
+    inverseMatrix.props[1] = b;
+    inverseMatrix.props[4] = c;
+    inverseMatrix.props[5] = d;
+    inverseMatrix.props[12] = e;
+    inverseMatrix.props[13] = f;
+    return inverseMatrix;
+  }
+
+  function inversePoint(pt) {
+    var inverseMatrix = this.getInverseMatrix();
+    return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
+  }
+
+  function inversePoints(pts) {
+    var i;
+    var len = pts.length;
+    var retPts = [];
+    for (i = 0; i < len; i += 1) {
+      retPts[i] = inversePoint(pts[i]);
+    }
+    return retPts;
+  }
+
+  function applyToTriplePoints(pt1, pt2, pt3) {
+    var arr = createTypedArray('float32', 6);
+    if (this.isIdentity()) {
+      arr[0] = pt1[0];
+      arr[1] = pt1[1];
+      arr[2] = pt2[0];
+      arr[3] = pt2[1];
+      arr[4] = pt3[0];
+      arr[5] = pt3[1];
+    } else {
+      var p0 = this.props[0];
+      var p1 = this.props[1];
+      var p4 = this.props[4];
+      var p5 = this.props[5];
+      var p12 = this.props[12];
+      var p13 = this.props[13];
+      arr[0] = pt1[0] * p0 + pt1[1] * p4 + p12;
+      arr[1] = pt1[0] * p1 + pt1[1] * p5 + p13;
+      arr[2] = pt2[0] * p0 + pt2[1] * p4 + p12;
+      arr[3] = pt2[0] * p1 + pt2[1] * p5 + p13;
+      arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
+      arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
+    }
+    return arr;
+  }
+
+  function applyToPointArray(x, y, z) {
+    var arr;
+    if (this.isIdentity()) {
+      arr = [x, y, z];
+    } else {
+      arr = [
+        x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+        x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+        x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+      ];
+    }
+    return arr;
+  }
+
+  function applyToPointStringified(x, y) {
+    if (this.isIdentity()) {
+      return x + ',' + y;
+    }
+    var _p = this.props;
+    return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
+  }
+
+  function toCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var i = 0;
+    var props = this.props;
+    var cssValue = 'matrix3d(';
+    var v = 10000;
+    while (i < 16) {
+      cssValue += _rnd(props[i] * v) / v;
+      cssValue += i === 15 ? ')' : ',';
+      i += 1;
+    }
+    return cssValue;
+  }
+
+  function roundMatrixProperty(val) {
+    var v = 10000;
+    if ((val < 0.000001 && val > 0) || (val > -0.000001 && val < 0)) {
+      return _rnd(val * v) / v;
+    }
+    return val;
+  }
+
+  function to2dCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var props = this.props;
+    var _a = roundMatrixProperty(props[0]);
+    var _b = roundMatrixProperty(props[1]);
+    var _c = roundMatrixProperty(props[4]);
+    var _d = roundMatrixProperty(props[5]);
+    var _e = roundMatrixProperty(props[12]);
+    var _f = roundMatrixProperty(props[13]);
+    return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
+  }
+
+  return function () {
+    this.reset = reset;
+    this.rotate = rotate;
+    this.rotateX = rotateX;
+    this.rotateY = rotateY;
+    this.rotateZ = rotateZ;
+    this.skew = skew;
+    this.skewFromAxis = skewFromAxis;
+    this.shear = shear;
+    this.scale = scale;
+    this.setTransform = setTransform;
+    this.translate = translate;
+    this.transform = transform;
+    this.multiply = multiply;
+    this.applyToPoint = applyToPoint;
+    this.applyToX = applyToX;
+    this.applyToY = applyToY;
+    this.applyToZ = applyToZ;
+    this.applyToPointArray = applyToPointArray;
+    this.applyToTriplePoints = applyToTriplePoints;
+    this.applyToPointStringified = applyToPointStringified;
+    this.toCSS = toCSS;
+    this.to2dCSS = to2dCSS;
+    this.clone = clone;
+    this.cloneFromProps = cloneFromProps;
+    this.equals = equals;
+    this.inversePoints = inversePoints;
+    this.inversePoint = inversePoint;
+    this.getInverseMatrix = getInverseMatrix;
+    this._t = this.transform;
+    this.isIdentity = isIdentity;
+    this._identity = true;
+    this._identityCalculated = false;
+
+    this.props = createTypedArray('float32', 16);
+    this.reset();
+  };
+}());
+
+const lottie = {};
+var standalone = '__[STANDALONE]__';
+var animationData = '__[ANIMATIONDATA]__';
+var renderer = '';
+
+function setLocation(href) {
+  setLocationHref(href);
+}
+
+function searchAnimations() {
+  if (standalone === true) {
+    animationManager.searchAnimations(animationData, standalone, renderer);
+  } else {
+    animationManager.searchAnimations();
+  }
+}
+
+function setSubframeRendering(flag) {
+  setSubframeEnabled(flag);
+}
+
+function setPrefix(prefix) {
+  setIdPrefix(prefix);
+}
+
+function loadAnimation(params) {
+  if (standalone === true) {
+    params.animationData = JSON.parse(animationData);
+  }
+  return animationManager.loadAnimation(params);
+}
+
+function setQuality(value) {
+  if (typeof value === 'string') {
+    switch (value) {
+      case 'high':
+        setDefaultCurveSegments(200);
+        break;
+      default:
+      case 'medium':
+        setDefaultCurveSegments(50);
+        break;
+      case 'low':
+        setDefaultCurveSegments(10);
+        break;
+    }
+  } else if (!isNaN(value) && value > 1) {
+    setDefaultCurveSegments(value);
+  }
+  if (getDefaultCurveSegments() >= 50) {
+    roundValues(false);
+  } else {
+    roundValues(true);
+  }
+}
+
+function inBrowser() {
+  return typeof navigator !== 'undefined';
+}
+
+function installPlugin(type, plugin) {
+  if (type === 'expressions') {
+    setExpressionsPlugin(plugin);
+  }
+}
+
+function getFactory(name) {
+  switch (name) {
+    case 'propertyFactory':
+      return PropertyFactory;
+    case 'shapePropertyFactory':
+      return ShapePropertyFactory;
+    case 'matrix':
+      return Matrix;
+    default:
+      return null;
+  }
+}
+
+lottie.play = animationManager.play;
+lottie.pause = animationManager.pause;
+lottie.setLocationHref = setLocation;
+lottie.togglePause = animationManager.togglePause;
+lottie.setSpeed = animationManager.setSpeed;
+lottie.setDirection = animationManager.setDirection;
+lottie.stop = animationManager.stop;
+lottie.searchAnimations = searchAnimations;
+lottie.registerAnimation = animationManager.registerAnimation;
+lottie.loadAnimation = loadAnimation;
+lottie.setSubframeRendering = setSubframeRendering;
+lottie.resize = animationManager.resize;
+// lottie.start = start;
+lottie.goToAndStop = animationManager.goToAndStop;
+lottie.destroy = animationManager.destroy;
+lottie.setQuality = setQuality;
+lottie.inBrowser = inBrowser;
+lottie.installPlugin = installPlugin;
+lottie.freeze = animationManager.freeze;
+lottie.unfreeze = animationManager.unfreeze;
+lottie.setVolume = animationManager.setVolume;
+lottie.mute = animationManager.mute;
+lottie.unmute = animationManager.unmute;
+lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations;
+lottie.useWebWorker = setWebWorker;
+lottie.setIDPrefix = setPrefix;
+lottie.__getFactory = getFactory;
+lottie.version = '[[BM_VERSION]]';
+
+function checkReady() {
+  if (document.readyState === 'complete') {
+    clearInterval(readyStateCheckInterval);
+    searchAnimations();
+  }
+}
+
+function getQueryVariable(variable) {
+  var vars = queryString.split('&');
+  for (var i = 0; i < vars.length; i += 1) {
+    var pair = vars[i].split('=');
+    if (decodeURIComponent(pair[0]) == variable) { // eslint-disable-line eqeqeq
+      return decodeURIComponent(pair[1]);
+    }
+  }
+  return null;
+}
+var queryString = '';
+if (standalone) {
+  var scripts = document.getElementsByTagName('script');
+  var index = scripts.length - 1;
+  var myScript = scripts[index] || {
+    src: '',
+  };
+  queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
+  renderer = getQueryVariable('renderer');
+}
+var readyStateCheckInterval = setInterval(checkReady, 100);
+
+// this adds bodymovin to the window object for backwards compatibility
+try {
+  if (!(typeof exports === 'object' && typeof module !== 'undefined')
+    && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
+  ) {
+    window.bodymovin = lottie;
+  }
+} catch (err) {
+  //
+}
+
+const ShapeModifiers = (function () {
+  var ob = {};
+  var modifiers = {};
+  ob.registerModifier = registerModifier;
+  ob.getModifier = getModifier;
+
+  function registerModifier(nm, factory) {
+    if (!modifiers[nm]) {
+      modifiers[nm] = factory;
+    }
+  }
+
+  function getModifier(nm, elem, data) {
+    return new modifiers[nm](elem, data);
+  }
+
+  return ob;
+}());
+
+function ShapeModifier() {}
+ShapeModifier.prototype.initModifierProperties = function () {};
+ShapeModifier.prototype.addShapeToModifier = function () {};
+ShapeModifier.prototype.addShape = function (data) {
+  if (!this.closed) {
+    // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
+    data.sh.container.addDynamicProperty(data.sh);
+    var shapeData = { shape: data.sh, data: data, localShapeCollection: shapeCollectionPool.newShapeCollection() };
+    this.shapes.push(shapeData);
+    this.addShapeToModifier(shapeData);
+    if (this._isAnimated) {
+      data.setAsAnimated();
+    }
+  }
+};
+ShapeModifier.prototype.init = function (elem, data) {
+  this.shapes = [];
+  this.elem = elem;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, data);
+  this.frameId = initialDefaultFrame;
+  this.closed = false;
+  this.k = false;
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+ShapeModifier.prototype.processKeys = function () {
+  if (this.elem.globalData.frameId === this.frameId) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+extendPrototype([DynamicPropertyContainer], ShapeModifier);
+
+function TrimModifier() {
+}
+extendPrototype([ShapeModifier], TrimModifier);
+TrimModifier.prototype.initModifierProperties = function (elem, data) {
+  this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this);
+  this.sValue = 0;
+  this.eValue = 0;
+  this.getValue = this.processKeys;
+  this.m = data.m;
+  this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
+};
+
+TrimModifier.prototype.addShapeToModifier = function (shapeData) {
+  shapeData.pathsData = [];
+};
+
+TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
+  var segments = [];
+  if (e <= 1) {
+    segments.push({
+      s: s,
+      e: e,
+    });
+  } else if (s >= 1) {
+    segments.push({
+      s: s - 1,
+      e: e - 1,
+    });
+  } else {
+    segments.push({
+      s: s,
+      e: 1,
+    });
+    segments.push({
+      s: 0,
+      e: e - 1,
+    });
+  }
+  var shapeSegments = [];
+  var i;
+  var len = segments.length;
+  var segmentOb;
+  for (i = 0; i < len; i += 1) {
+    segmentOb = segments[i];
+    if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
+      var shapeS;
+      var shapeE;
+      if (segmentOb.s * totalModifierLength <= addedLength) {
+        shapeS = 0;
+      } else {
+        shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
+      }
+      if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
+        shapeE = 1;
+      } else {
+        shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength);
+      }
+      shapeSegments.push([shapeS, shapeE]);
+    }
+  }
+  if (!shapeSegments.length) {
+    shapeSegments.push([0, 0]);
+  }
+  return shapeSegments;
+};
+
+TrimModifier.prototype.releasePathsData = function (pathsData) {
+  var i;
+  var len = pathsData.length;
+  for (i = 0; i < len; i += 1) {
+    segmentsLengthPool.release(pathsData[i]);
+  }
+  pathsData.length = 0;
+  return pathsData;
+};
+
+TrimModifier.prototype.processShapes = function (_isFirstFrame) {
+  var s;
+  var e;
+  if (this._mdf || _isFirstFrame) {
+    var o = (this.o.v % 360) / 360;
+    if (o < 0) {
+      o += 1;
+    }
+    if (this.s.v > 1) {
+      s = 1 + o;
+    } else if (this.s.v < 0) {
+      s = 0 + o;
+    } else {
+      s = this.s.v + o;
+    }
+    if (this.e.v > 1) {
+      e = 1 + o;
+    } else if (this.e.v < 0) {
+      e = 0 + o;
+    } else {
+      e = this.e.v + o;
+    }
+
+    if (s > e) {
+      var _s = s;
+      s = e;
+      e = _s;
+    }
+    s = Math.round(s * 10000) * 0.0001;
+    e = Math.round(e * 10000) * 0.0001;
+    this.sValue = s;
+    this.eValue = e;
+  } else {
+    s = this.sValue;
+    e = this.eValue;
+  }
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var pathsData;
+  var pathData;
+  var totalShapeLength;
+  var totalModifierLength = 0;
+
+  if (e === s) {
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].localShapeCollection.releaseShapes();
+      this.shapes[i].shape._mdf = true;
+      this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
+      if (this._mdf) {
+        this.shapes[i].pathsData.length = 0;
+      }
+    }
+  } else if (!((e === 1 && s === 0) || (e === 0 && s === 1))) {
+    var segments = [];
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
+      if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
+        shapeData.shape.paths = shapeData.localShapeCollection;
+      } else {
+        shapePaths = shapeData.shape.paths;
+        jLen = shapePaths._length;
+        totalShapeLength = 0;
+        if (!shapeData.shape._mdf && shapeData.pathsData.length) {
+          totalShapeLength = shapeData.totalShapeLength;
+        } else {
+          pathsData = this.releasePathsData(shapeData.pathsData);
+          for (j = 0; j < jLen; j += 1) {
+            pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
+            pathsData.push(pathData);
+            totalShapeLength += pathData.totalLength;
+          }
+          shapeData.totalShapeLength = totalShapeLength;
+          shapeData.pathsData = pathsData;
+        }
+
+        totalModifierLength += totalShapeLength;
+        shapeData.shape._mdf = true;
+      }
+    }
+    var shapeS = s;
+    var shapeE = e;
+    var addedLength = 0;
+    var edges;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shapeData = this.shapes[i];
+      if (shapeData.shape._mdf) {
+        localShapeCollection = shapeData.localShapeCollection;
+        localShapeCollection.releaseShapes();
+        // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
+        if (this.m === 2 && len > 1) {
+          edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
+          addedLength += shapeData.totalShapeLength;
+        } else {
+          edges = [[shapeS, shapeE]];
+        }
+        jLen = edges.length;
+        for (j = 0; j < jLen; j += 1) {
+          shapeS = edges[j][0];
+          shapeE = edges[j][1];
+          segments.length = 0;
+          if (shapeE <= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength * shapeE,
+            });
+          } else if (shapeS >= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * (shapeS - 1),
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          } else {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength,
+            });
+            segments.push({
+              s: 0,
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          }
+          var newShapesData = this.addShapes(shapeData, segments[0]);
+          if (segments[0].s !== segments[0].e) {
+            if (segments.length > 1) {
+              var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
+              if (lastShapeInCollection.c) {
+                var lastShape = newShapesData.pop();
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1], lastShape);
+              } else {
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1]);
+              }
+            }
+            this.addPaths(newShapesData, localShapeCollection);
+          }
+        }
+        shapeData.shape.paths = localShapeCollection;
+      }
+    }
+  } else if (this._mdf) {
+    for (i = 0; i < len; i += 1) {
+      // Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween.
+      // Don't remove this even if it's losing cached info.
+      this.shapes[i].pathsData.length = 0;
+      this.shapes[i].shape._mdf = true;
+    }
+  }
+};
+
+TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
+  var i;
+  var len = newPaths.length;
+  for (i = 0; i < len; i += 1) {
+    localShapeCollection.addShape(newPaths[i]);
+  }
+};
+
+TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
+  shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
+  shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
+  }
+  shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
+  shapePath.setXYAt(points[1], points[5], 'o', pos);
+  shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(points[0], points[4], 'v', pos);
+  }
+  shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
+  var pathsData = shapeData.pathsData;
+  var shapePaths = shapeData.shape.paths.shapes;
+  var i;
+  var len = shapeData.shape.paths._length;
+  var j;
+  var jLen;
+  var addedLength = 0;
+  var currentLengthData;
+  var segmentCount;
+  var lengths;
+  var segment;
+  var shapes = [];
+  var initPos;
+  var newShape = true;
+  if (!shapePath) {
+    shapePath = shapePool.newElement();
+    segmentCount = 0;
+    initPos = 0;
+  } else {
+    segmentCount = shapePath._length;
+    initPos = shapePath._length;
+  }
+  shapes.push(shapePath);
+  for (i = 0; i < len; i += 1) {
+    lengths = pathsData[i].lengths;
+    shapePath.c = shapePaths[i].c;
+    jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
+    for (j = 1; j < jLen; j += 1) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
+        addedLength += currentLengthData.addedLength;
+        shapePath.c = false;
+      } else if (addedLength > shapeSegment.e) {
+        shapePath.c = false;
+        break;
+      } else {
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+        addedLength += currentLengthData.addedLength;
+        segmentCount += 1;
+      }
+    }
+    if (shapePaths[i].c && lengths.length) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength <= shapeSegment.e) {
+        var segmentLength = lengths[j - 1].addedLength;
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+      } else {
+        shapePath.c = false;
+      }
+      addedLength += currentLengthData.addedLength;
+      segmentCount += 1;
+    }
+    if (shapePath._length) {
+      shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
+      shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
+    }
+    if (addedLength > shapeSegment.e) {
+      break;
+    }
+    if (i < len - 1) {
+      shapePath = shapePool.newElement();
+      newShape = true;
+      shapes.push(shapePath);
+      segmentCount = 0;
+    }
+  }
+  return shapes;
+};
+
+function PuckerAndBloatModifier() {}
+extendPrototype([ShapeModifier], PuckerAndBloatModifier);
+PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this._isAnimated = !!this.amount.effectsSequence.length;
+};
+
+PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
+  var percent = amount / 100;
+  var centerPoint = [0, 0];
+  var pathLength = path._length;
+  var i = 0;
+  for (i = 0; i < pathLength; i += 1) {
+    centerPoint[0] += path.v[i][0];
+    centerPoint[1] += path.v[i][1];
+  }
+  centerPoint[0] /= pathLength;
+  centerPoint[1] /= pathLength;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < pathLength; i += 1) {
+    vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
+    vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
+    oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent;
+    oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent;
+    iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent;
+    iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
+    clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
+  }
+  return clonedPath;
+};
+
+PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+const TransformPropertyFactory = (function () {
+  var defaultVector = [0, 0];
+
+  function applyToMatrix(mat) {
+    var _mdf = this._mdf;
+    this.iterateDynamicProperties();
+    this._mdf = this._mdf || _mdf;
+    if (this.a) {
+      mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+    }
+    if (this.s) {
+      mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+    }
+    if (this.sk) {
+      mat.skewFromAxis(-this.sk.v, this.sa.v);
+    }
+    if (this.r) {
+      mat.rotate(-this.r.v);
+    } else {
+      mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+    }
+    if (this.data.p.s) {
+      if (this.data.p.z) {
+        mat.translate(this.px.v, this.py.v, -this.pz.v);
+      } else {
+        mat.translate(this.px.v, this.py.v, 0);
+      }
+    } else {
+      mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+    }
+  }
+  function processKeys(forceRender) {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    }
+    if (this._isDirty) {
+      this.precalculateMatrix();
+      this._isDirty = false;
+    }
+
+    this.iterateDynamicProperties();
+
+    if (this._mdf || forceRender) {
+      var frameRate;
+      this.v.cloneFromProps(this.pre.props);
+      if (this.appliedTransformations < 1) {
+        this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      }
+      if (this.appliedTransformations < 2) {
+        this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      }
+      if (this.sk && this.appliedTransformations < 3) {
+        this.v.skewFromAxis(-this.sk.v, this.sa.v);
+      }
+      if (this.r && this.appliedTransformations < 4) {
+        this.v.rotate(-this.r.v);
+      } else if (!this.r && this.appliedTransformations < 4) {
+        this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+          .rotateY(this.or.v[1])
+          .rotateX(this.or.v[0]);
+      }
+      if (this.autoOriented) {
+        var v1;
+        var v2;
+        frameRate = this.elem.globalData.frameRate;
+        if (this.p && this.p.keyframes && this.p.getValueAtTime) {
+          if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
+            v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0);
+          } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0);
+            v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0);
+          } else {
+            v1 = this.p.pv;
+            v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime);
+          }
+        } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) {
+          v1 = [];
+          v2 = [];
+          var px = this.px;
+          var py = this.py;
+          if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
+            v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
+            v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate, 0);
+          } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate), 0);
+            v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate), 0);
+            v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0);
+          } else {
+            v1 = [px.pv, py.pv];
+            v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime);
+            v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime);
+          }
+        } else {
+          v2 = defaultVector;
+          v1 = v2;
+        }
+        this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
+      }
+      if (this.data.p && this.data.p.s) {
+        if (this.data.p.z) {
+          this.v.translate(this.px.v, this.py.v, -this.pz.v);
+        } else {
+          this.v.translate(this.px.v, this.py.v, 0);
+        }
+      } else {
+        this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+      }
+    }
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function precalculateMatrix() {
+    this.appliedTransformations = 0;
+    this.pre.reset();
+
+    if (!this.a.effectsSequence.length) {
+      this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      this.appliedTransformations = 1;
+    } else {
+      return;
+    }
+    if (!this.s.effectsSequence.length) {
+      this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      this.appliedTransformations = 2;
+    } else {
+      return;
+    }
+    if (this.sk) {
+      if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
+        this.pre.skewFromAxis(-this.sk.v, this.sa.v);
+        this.appliedTransformations = 3;
+      } else {
+        return;
+      }
+    }
+    if (this.r) {
+      if (!this.r.effectsSequence.length) {
+        this.pre.rotate(-this.r.v);
+        this.appliedTransformations = 4;
+      }
+    } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) {
+      this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+      this.appliedTransformations = 4;
+    }
+  }
+
+  function autoOrient() {
+    //
+    // var prevP = this.getValueAtTime();
+  }
+
+  function addDynamicProperty(prop) {
+    this._addDynamicProperty(prop);
+    this.elem.addDynamicProperty(prop);
+    this._isDirty = true;
+  }
+
+  function TransformProperty(elem, data, container) {
+    this.elem = elem;
+    this.frameId = -1;
+    this.propType = 'transform';
+    this.data = data;
+    this.v = new Matrix();
+    // Precalculated matrix with non animated properties
+    this.pre = new Matrix();
+    this.appliedTransformations = 0;
+    this.initDynamicPropertyContainer(container || elem);
+    if (data.p && data.p.s) {
+      this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
+      this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
+      if (data.p.z) {
+        this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
+      }
+    } else {
+      this.p = PropertyFactory.getProp(elem, data.p || { k: [0, 0, 0] }, 1, 0, this);
+    }
+    if (data.rx) {
+      this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
+      this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
+      this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
+      if (data.or.k[0].ti) {
+        var i;
+        var len = data.or.k.length;
+        for (i = 0; i < len; i += 1) {
+          data.or.k[i].to = null;
+          data.or.k[i].ti = null;
+        }
+      }
+      this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+      // sh Indicates it needs to be capped between -180 and 180
+      this.or.sh = true;
+    } else {
+      this.r = PropertyFactory.getProp(elem, data.r || { k: 0 }, 0, degToRads, this);
+    }
+    if (data.sk) {
+      this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
+      this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
+    }
+    this.a = PropertyFactory.getProp(elem, data.a || { k: [0, 0, 0] }, 1, 0, this);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: [100, 100, 100] }, 1, 0.01, this);
+    // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
+    if (data.o) {
+      this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
+    } else {
+      this.o = { _mdf: false, v: 1 };
+    }
+    this._isDirty = true;
+    if (!this.dynamicProperties.length) {
+      this.getValue(true);
+    }
+  }
+
+  TransformProperty.prototype = {
+    applyToMatrix: applyToMatrix,
+    getValue: processKeys,
+    precalculateMatrix: precalculateMatrix,
+    autoOrient: autoOrient,
+  };
+
+  extendPrototype([DynamicPropertyContainer], TransformProperty);
+  TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
+  TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
+
+  function getTransformProperty(elem, data, container) {
+    return new TransformProperty(elem, data, container);
+  }
+
+  return {
+    getTransformProperty: getTransformProperty,
+  };
+}());
+
+function RepeaterModifier() {}
+extendPrototype([ShapeModifier], RepeaterModifier);
+
+RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, null, this);
+  this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this);
+  this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
+  this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
+  this.data = data;
+  if (!this.dynamicProperties.length) {
+    this.getValue(true);
+  }
+  this._isAnimated = !!this.dynamicProperties.length;
+  this.pMatrix = new Matrix();
+  this.rMatrix = new Matrix();
+  this.sMatrix = new Matrix();
+  this.tMatrix = new Matrix();
+  this.matrix = new Matrix();
+};
+
+RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
+  var dir = inv ? -1 : 1;
+  var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
+  var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
+  pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
+  rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  rMatrix.rotate(-transform.r.v * dir * perc);
+  rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+  sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
+  sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+};
+
+RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
+  this.elem = elem;
+  this.arr = arr;
+  this.pos = pos;
+  this.elemsData = elemsData;
+  this._currentCopies = 0;
+  this._elements = [];
+  this._groups = [];
+  this.frameId = -1;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, arr[pos]);
+  while (pos > 0) {
+    pos -= 1;
+    // this._elements.unshift(arr.splice(pos,1)[0]);
+    this._elements.unshift(arr[pos]);
+  }
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+
+RepeaterModifier.prototype.resetElements = function (elements) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._processed = false;
+    if (elements[i].ty === 'gr') {
+      this.resetElements(elements[i].it);
+    }
+  }
+};
+
+RepeaterModifier.prototype.cloneElements = function (elements) {
+  var newElements = JSON.parse(JSON.stringify(elements));
+  this.resetElements(newElements);
+  return newElements;
+};
+
+RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._render = renderFlag;
+    if (elements[i].ty === 'gr') {
+      this.changeGroupRender(elements[i].it, renderFlag);
+    }
+  }
+};
+
+RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
+  var items;
+  var itemsTransform;
+  var i;
+  var dir;
+  var cont;
+  var hasReloaded = false;
+  if (this._mdf || _isFirstFrame) {
+    var copies = Math.ceil(this.c.v);
+    if (this._groups.length < copies) {
+      while (this._groups.length < copies) {
+        var group = {
+          it: this.cloneElements(this._elements),
+          ty: 'gr',
+        };
+        group.it.push({
+          a: { a: 0, ix: 1, k: [0, 0] }, nm: 'Transform', o: { a: 0, ix: 7, k: 100 }, p: { a: 0, ix: 2, k: [0, 0] }, r: { a: 1, ix: 6, k: [{ s: 0, e: 0, t: 0 }, { s: 0, e: 0, t: 1 }] }, s: { a: 0, ix: 3, k: [100, 100] }, sa: { a: 0, ix: 5, k: 0 }, sk: { a: 0, ix: 4, k: 0 }, ty: 'tr',
+        });
+
+        this.arr.splice(0, 0, group);
+        this._groups.splice(0, 0, group);
+        this._currentCopies += 1;
+      }
+      this.elem.reloadShapes();
+      hasReloaded = true;
+    }
+    cont = 0;
+    var renderFlag;
+    for (i = 0; i <= this._groups.length - 1; i += 1) {
+      renderFlag = cont < copies;
+      this._groups[i]._render = renderFlag;
+      this.changeGroupRender(this._groups[i].it, renderFlag);
+      if (!renderFlag) {
+        var elems = this.elemsData[i].it;
+        var transformData = elems[elems.length - 1];
+        if (transformData.transform.op.v !== 0) {
+          transformData.transform.op._mdf = true;
+          transformData.transform.op.v = 0;
+        } else {
+          transformData.transform.op._mdf = false;
+        }
+      }
+      cont += 1;
+    }
+
+    this._currentCopies = copies;
+    /// /
+
+    var offset = this.o.v;
+    var offsetModulo = offset % 1;
+    var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
+    var pProps = this.pMatrix.props;
+    var rProps = this.rMatrix.props;
+    var sProps = this.sMatrix.props;
+    this.pMatrix.reset();
+    this.rMatrix.reset();
+    this.sMatrix.reset();
+    this.tMatrix.reset();
+    this.matrix.reset();
+    var iteration = 0;
+
+    if (offset > 0) {
+      while (iteration < roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        iteration += 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
+        iteration += offsetModulo;
+      }
+    } else if (offset < 0) {
+      while (iteration > roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
+        iteration -= 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
+        iteration -= offsetModulo;
+      }
+    }
+    i = this.data.m === 1 ? 0 : this._currentCopies - 1;
+    dir = this.data.m === 1 ? 1 : -1;
+    cont = this._currentCopies;
+    var j;
+    var jLen;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      jLen = itemsTransform.length;
+      items[items.length - 1].transform.mProps._mdf = true;
+      items[items.length - 1].transform.op._mdf = true;
+      items[items.length - 1].transform.op.v = this._currentCopies === 1
+        ? this.so.v
+        : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
+
+      if (iteration !== 0) {
+        if ((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)) {
+          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        }
+        this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
+        this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
+        this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
+
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+        this.matrix.reset();
+      } else {
+        this.matrix.reset();
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+      }
+      iteration += 1;
+      cont -= 1;
+      i += dir;
+    }
+  } else {
+    cont = this._currentCopies;
+    i = 0;
+    dir = 1;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      items[items.length - 1].transform.mProps._mdf = false;
+      items[items.length - 1].transform.op._mdf = false;
+      cont -= 1;
+      i += dir;
+    }
+  }
+  return hasReloaded;
+};
+
+RepeaterModifier.prototype.addShape = function () {};
+
+function RoundCornersModifier() {}
+extendPrototype([ShapeModifier], RoundCornersModifier);
+RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this._isAnimated = !!this.rd.effectsSequence.length;
+};
+
+RoundCornersModifier.prototype.processPath = function (path, round) {
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var i;
+  var len = path._length;
+  var currentV;
+  var currentI;
+  var currentO;
+  var closerV;
+  var distance;
+  var newPosPerc;
+  var index = 0;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < len; i += 1) {
+    currentV = path.v[i];
+    currentO = path.o[i];
+    currentI = path.i[i];
+    if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
+      if ((i === 0 || i === len - 1) && !path.c) {
+        clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
+        /* clonedPath.v[index] = currentV;
+                clonedPath.o[index] = currentO;
+                clonedPath.i[index] = currentI; */
+        index += 1;
+      } else {
+        if (i === 0) {
+          closerV = path.v[len - 1];
+        } else {
+          closerV = path.v[i - 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = iX;
+        iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
+        vY = iY;
+        oX = vX - (vX - currentV[0]) * roundCorner;
+        oY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+
+        if (i === len - 1) {
+          closerV = path.v[0];
+        } else {
+          closerV = path.v[i + 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = oX;
+        oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc;
+        vY = oY;
+        iX = vX - (vX - currentV[0]) * roundCorner;
+        iY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+      }
+    } else {
+      clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index);
+      index += 1;
+    }
+  }
+  return clonedPath;
+};
+
+RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var rd = this.rd.v;
+
+  if (rd !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function floatEqual(a, b) {
+  return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
+}
+
+function floatZero(f) {
+  return Math.abs(f) <= 0.00001;
+}
+
+function lerp(p0, p1, amount) {
+  return p0 * (1 - amount) + p1 * amount;
+}
+
+function lerpPoint(p0, p1, amount) {
+  return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
+}
+
+function quadRoots(a, b, c) {
+  // no root
+  if (a === 0) return [];
+  var s = b * b - 4 * a * c;
+  // Complex roots
+  if (s < 0) return [];
+  var singleRoot = -b / (2 * a);
+  // 1 root
+  if (s === 0) return [singleRoot];
+  var delta = Math.sqrt(s) / (2 * a);
+  // 2 roots
+  return [singleRoot - delta, singleRoot + delta];
+}
+
+function polynomialCoefficients(p0, p1, p2, p3) {
+  return [
+    -p0 + 3 * p1 - 3 * p2 + p3,
+    3 * p0 - 6 * p1 + 3 * p2,
+    -3 * p0 + 3 * p1,
+    p0,
+  ];
+}
+
+function singlePoint(p) {
+  return new PolynomialBezier(p, p, p, p, false);
+}
+
+function PolynomialBezier(p0, p1, p2, p3, linearize) {
+  if (linearize && pointEqual(p0, p1)) {
+    p1 = lerpPoint(p0, p3, 1 / 3);
+  }
+  if (linearize && pointEqual(p2, p3)) {
+    p2 = lerpPoint(p0, p3, 2 / 3);
+  }
+  var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
+  var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
+  this.a = [coeffx[0], coeffy[0]];
+  this.b = [coeffx[1], coeffy[1]];
+  this.c = [coeffx[2], coeffy[2]];
+  this.d = [coeffx[3], coeffy[3]];
+  this.points = [p0, p1, p2, p3];
+}
+PolynomialBezier.prototype.point = function (t) {
+  return [
+    (((this.a[0] * t) + this.b[0]) * t + this.c[0]) * t + this.d[0],
+    (((this.a[1] * t) + this.b[1]) * t + this.c[1]) * t + this.d[1],
+  ];
+};
+PolynomialBezier.prototype.derivative = function (t) {
+  return [
+    (3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0],
+    (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1],
+  ];
+};
+PolynomialBezier.prototype.tangentAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[1], p[0]);
+};
+PolynomialBezier.prototype.normalAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[0], p[1]);
+};
+
+PolynomialBezier.prototype.inflectionPoints = function () {
+  var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
+  if (floatZero(denom)) return [];
+  var tcusp = (-0.5 * (this.a[1] * this.c[0] - this.a[0] * this.c[1])) / denom;
+  var square = tcusp * tcusp - ((1 / 3) * (this.b[1] * this.c[0] - this.b[0] * this.c[1])) / denom;
+  if (square < 0) return [];
+  var root = Math.sqrt(square);
+  if (floatZero(root)) {
+    if (root > 0 && root < 1) return [tcusp];
+    return [];
+  }
+  return [tcusp - root, tcusp + root].filter(function (r) { return r > 0 && r < 1; });
+};
+PolynomialBezier.prototype.split = function (t) {
+  if (t <= 0) return [singlePoint(this.points[0]), this];
+  if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
+  var p10 = lerpPoint(this.points[0], this.points[1], t);
+  var p11 = lerpPoint(this.points[1], this.points[2], t);
+  var p12 = lerpPoint(this.points[2], this.points[3], t);
+  var p20 = lerpPoint(p10, p11, t);
+  var p21 = lerpPoint(p11, p12, t);
+  var p3 = lerpPoint(p20, p21, t);
+  return [
+    new PolynomialBezier(this.points[0], p10, p20, p3, true),
+    new PolynomialBezier(p3, p21, p12, this.points[3], true),
+  ];
+};
+function extrema(bez, comp) {
+  var min = bez.points[0][comp];
+  var max = bez.points[bez.points.length - 1][comp];
+  if (min > max) {
+    var e = max;
+    max = min;
+    min = e;
+  }
+  // Derivative roots to find min/max
+  var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
+  for (var i = 0; i < f.length; i += 1) {
+    if (f[i] > 0 && f[i] < 1) {
+      var val = bez.point(f[i])[comp];
+      if (val < min) min = val;
+      else if (val > max) max = val;
+    }
+  }
+  return {
+    min: min,
+    max: max,
+  };
+}
+PolynomialBezier.prototype.bounds = function () {
+  return {
+    x: extrema(this, 0),
+    y: extrema(this, 1),
+  };
+};
+PolynomialBezier.prototype.boundingBox = function () {
+  var bounds = this.bounds();
+  return {
+    left: bounds.x.min,
+    right: bounds.x.max,
+    top: bounds.y.min,
+    bottom: bounds.y.max,
+    width: bounds.x.max - bounds.x.min,
+    height: bounds.y.max - bounds.y.min,
+    cx: (bounds.x.max + bounds.x.min) / 2,
+    cy: (bounds.y.max + bounds.y.min) / 2,
+  };
+};
+
+function intersectData(bez, t1, t2) {
+  var box = bez.boundingBox();
+  return {
+    cx: box.cx,
+    cy: box.cy,
+    width: box.width,
+    height: box.height,
+    bez: bez,
+    t: (t1 + t2) / 2,
+    t1: t1,
+    t2: t2,
+  };
+}
+function splitData(data) {
+  var split = data.bez.split(0.5);
+  return [
+    intersectData(split[0], data.t1, data.t),
+    intersectData(split[1], data.t, data.t2),
+  ];
+}
+
+function boxIntersect(b1, b2) {
+  return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width
+    && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
+}
+
+function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
+  if (!boxIntersect(d1, d2)) return;
+  if (depth >= maxRecursion || (d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance)) {
+    intersections.push([d1.t, d2.t]);
+    return;
+  }
+  var d1s = splitData(d1);
+  var d2s = splitData(d2);
+  intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[0], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+}
+
+PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
+  if (tolerance === undefined) tolerance = 2;
+  if (maxRecursion === undefined) maxRecursion = 7;
+  var intersections = [];
+  intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
+  return intersections;
+};
+
+PolynomialBezier.shapeSegment = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
+};
+
+PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
+};
+
+function crossProduct(a, b) {
+  return [
+    a[1] * b[2] - a[2] * b[1],
+    a[2] * b[0] - a[0] * b[2],
+    a[0] * b[1] - a[1] * b[0],
+  ];
+}
+
+function lineIntersection(start1, end1, start2, end2) {
+  var v1 = [start1[0], start1[1], 1];
+  var v2 = [end1[0], end1[1], 1];
+  var v3 = [start2[0], start2[1], 1];
+  var v4 = [end2[0], end2[1], 1];
+
+  var r = crossProduct(
+    crossProduct(v1, v2),
+    crossProduct(v3, v4)
+  );
+
+  if (floatZero(r[2])) return null;
+
+  return [r[0] / r[2], r[1] / r[2]];
+}
+
+function polarOffset(p, angle, length) {
+  return [
+    p[0] + Math.cos(angle) * length,
+    p[1] - Math.sin(angle) * length,
+  ];
+}
+
+function pointDistance(p1, p2) {
+  return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
+}
+
+function pointEqual(p1, p2) {
+  return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
+}
+
+function ZigZagModifier() {}
+extendPrototype([ShapeModifier], ZigZagModifier);
+ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
+  this.frequency = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
+  this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
+};
+
+function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
+  var angO = angle - Math.PI / 2;
+  var angI = angle + Math.PI / 2;
+  var px = point[0] + Math.cos(angle) * direction * amplitude;
+  var py = point[1] - Math.sin(angle) * direction * amplitude;
+
+  outputBezier.setTripleAt(
+    px,
+    py,
+    px + Math.cos(angO) * outAmplitude,
+    py - Math.sin(angO) * outAmplitude,
+    px + Math.cos(angI) * inAmplitude,
+    py - Math.sin(angI) * inAmplitude,
+    outputBezier.length()
+  );
+}
+
+function getPerpendicularVector(pt1, pt2) {
+  var vector = [
+    pt2[0] - pt1[0],
+    pt2[1] - pt1[1],
+  ];
+  var rot = -Math.PI * 0.5;
+  var rotatedVector = [
+    Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1],
+    Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1],
+  ];
+  return rotatedVector;
+}
+
+function getProjectingAngle(path, cur) {
+  var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
+  var nextIndex = (cur + 1) % path.length();
+  var prevPoint = path.v[prevIndex];
+  var nextPoint = path.v[nextIndex];
+  var pVector = getPerpendicularVector(prevPoint, nextPoint);
+  return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
+}
+
+function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
+  var angle = getProjectingAngle(path, cur);
+  var point = path.v[cur % path._length];
+  var prevPoint = path.v[cur === 0 ? path._length - 1 : cur - 1];
+  var nextPoint = path.v[(cur + 1) % path._length];
+  var prevDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - prevPoint[0], 2) + Math.pow(point[1] - prevPoint[1], 2))
+    : 0;
+  var nextDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2))
+    : 0;
+
+  setPoint(
+    outputBezier,
+    path.v[cur % path._length],
+    angle,
+    direction,
+    amplitude,
+    nextDist / ((frequency + 1) * 2),
+    prevDist / ((frequency + 1) * 2),
+    pointType
+  );
+}
+
+function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
+  for (var i = 0; i < frequency; i += 1) {
+    var t = (i + 1) / (frequency + 1);
+
+    var dist = pointType === 2
+      ? Math.sqrt(Math.pow(segment.points[3][0] - segment.points[0][0], 2) + Math.pow(segment.points[3][1] - segment.points[0][1], 2))
+      : 0;
+
+    var angle = segment.normalAngle(t);
+    var point = segment.point(t);
+    setPoint(
+      outputBezier,
+      point,
+      angle,
+      direction,
+      amplitude,
+      dist / ((frequency + 1) * 2),
+      dist / ((frequency + 1) * 2),
+      pointType
+    );
+
+    direction = -direction;
+  }
+
+  return direction;
+}
+
+ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
+  var count = path._length;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+
+  if (!path.c) {
+    count -= 1;
+  }
+
+  if (count === 0) return clonedPath;
+
+  var direction = -1;
+  var segment = PolynomialBezier.shapeSegment(path, 0);
+  zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
+
+  for (var i = 0; i < count; i += 1) {
+    direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
+
+    if (i === count - 1 && !path.c) {
+      segment = null;
+    } else {
+      segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
+    }
+
+    zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
+  }
+
+  return clonedPath;
+};
+
+ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amplitude = this.amplitude.v;
+  var frequency = Math.max(0, Math.round(this.frequency.v));
+  var pointType = this.pointsType.v;
+
+  if (amplitude !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function linearOffset(p1, p2, amount) {
+  var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
+  return [
+    polarOffset(p1, angle, amount),
+    polarOffset(p2, angle, amount),
+  ];
+}
+
+function offsetSegment(segment, amount) {
+  var p0; var p1a; var p1b; var p2b; var p2a; var
+    p3;
+  var e;
+  e = linearOffset(segment.points[0], segment.points[1], amount);
+  p0 = e[0];
+  p1a = e[1];
+  e = linearOffset(segment.points[1], segment.points[2], amount);
+  p1b = e[0];
+  p2b = e[1];
+  e = linearOffset(segment.points[2], segment.points[3], amount);
+  p2a = e[0];
+  p3 = e[1];
+  var p1 = lineIntersection(p0, p1a, p1b, p2b);
+  if (p1 === null) p1 = p1a;
+  var p2 = lineIntersection(p2a, p3, p1b, p2b);
+  if (p2 === null) p2 = p2a;
+
+  return new PolynomialBezier(p0, p1, p2, p3);
+}
+
+function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
+  var p0 = seg1.points[3];
+  var p1 = seg2.points[0];
+
+  // Bevel
+  if (lineJoin === 3) return p0;
+
+  // Connected, they don't need a joint
+  if (pointEqual(p0, p1)) return p0;
+
+  // Round
+  if (lineJoin === 2) {
+    var angleOut = -seg1.tangentAngle(1);
+    var angleIn = -seg2.tangentAngle(0) + Math.PI;
+    var center = lineIntersection(
+      p0,
+      polarOffset(p0, angleOut + Math.PI / 2, 100),
+      p1,
+      polarOffset(p1, angleOut + Math.PI / 2, 100)
+    );
+    var radius = center ? pointDistance(center, p0) : pointDistance(p0, p1) / 2;
+
+    var tan = polarOffset(p0, angleOut, 2 * radius * roundCorner);
+    outputBezier.setXYAt(tan[0], tan[1], 'o', outputBezier.length() - 1);
+
+    tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
+    outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
+
+    return p1;
+  }
+
+  // Miter
+  var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
+  var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
+  var intersection = lineIntersection(t0, p0, p1, t1);
+  if (intersection && pointDistance(intersection, p0) < miterLimit) {
+    outputBezier.setTripleAt(
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      outputBezier.length()
+    );
+    return intersection;
+  }
+
+  return p0;
+}
+
+function getIntersection(a, b) {
+  const intersect = a.intersections(b);
+
+  if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
+
+  if (intersect.length) return intersect[0];
+
+  return null;
+}
+
+function pruneSegmentIntersection(a, b) {
+  var outa = a.slice();
+  var outb = b.slice();
+  var intersect = getIntersection(a[a.length - 1], b[0]);
+  if (intersect) {
+    outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
+    outb[0] = b[0].split(intersect[1])[1];
+  }
+  if (a.length > 1 && b.length > 1) {
+    intersect = getIntersection(a[0], b[b.length - 1]);
+    if (intersect) {
+      return [
+        [a[0].split(intersect[0])[0]],
+        [b[b.length - 1].split(intersect[1])[1]],
+      ];
+    }
+  }
+  return [outa, outb];
+}
+
+function pruneIntersections(segments) {
+  var e;
+  for (var i = 1; i < segments.length; i += 1) {
+    e = pruneSegmentIntersection(segments[i - 1], segments[i]);
+    segments[i - 1] = e[0];
+    segments[i] = e[1];
+  }
+
+  if (segments.length > 1) {
+    e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
+    segments[segments.length - 1] = e[0];
+    segments[0] = e[1];
+  }
+
+  return segments;
+}
+
+function offsetSegmentSplit(segment, amount) {
+  /*
+    We split each bezier segment into smaller pieces based
+    on inflection points, this ensures the control point
+    polygon is convex.
+
+    (A cubic bezier can have none, one, or two inflection points)
+  */
+  var flex = segment.inflectionPoints();
+  var left;
+  var right;
+  var split;
+  var mid;
+
+  if (flex.length === 0) {
+    return [offsetSegment(segment, amount)];
+  }
+
+  if (flex.length === 1 || floatEqual(flex[1], 1)) {
+    split = segment.split(flex[0]);
+    left = split[0];
+    right = split[1];
+
+    return [
+      offsetSegment(left, amount),
+      offsetSegment(right, amount),
+    ];
+  }
+
+  split = segment.split(flex[0]);
+  left = split[0];
+  var t = (flex[1] - flex[0]) / (1 - flex[0]);
+  split = split[1].split(t);
+  mid = split[0];
+  right = split[1];
+
+  return [
+    offsetSegment(left, amount),
+    offsetSegment(mid, amount),
+    offsetSegment(right, amount),
+  ];
+}
+
+function OffsetPathModifier() {}
+
+extendPrototype([ShapeModifier], OffsetPathModifier);
+OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this.miterLimit = PropertyFactory.getProp(elem, data.ml, 0, null, this);
+  this.lineJoin = data.lj;
+  this._isAnimated = this.amount.effectsSequence.length !== 0;
+};
+
+OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
+  var outputBezier = shapePool.newElement();
+  outputBezier.c = inputBezier.c;
+  var count = inputBezier.length();
+  if (!inputBezier.c) {
+    count -= 1;
+  }
+  var i; var j; var segment;
+  var multiSegments = [];
+
+  for (i = 0; i < count; i += 1) {
+    segment = PolynomialBezier.shapeSegment(inputBezier, i);
+    multiSegments.push(offsetSegmentSplit(segment, amount));
+  }
+
+  if (!inputBezier.c) {
+    for (i = count - 1; i >= 0; i -= 1) {
+      segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
+      multiSegments.push(offsetSegmentSplit(segment, amount));
+    }
+  }
+
+  multiSegments = pruneIntersections(multiSegments);
+
+  // Add bezier segments to the output and apply line joints
+  var lastPoint = null;
+  var lastSeg = null;
+
+  for (i = 0; i < multiSegments.length; i += 1) {
+    var multiSegment = multiSegments[i];
+
+    if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
+
+    lastSeg = multiSegment[multiSegment.length - 1];
+
+    for (j = 0; j < multiSegment.length; j += 1) {
+      segment = multiSegment[j];
+
+      if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
+        outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
+      } else {
+        outputBezier.setTripleAt(
+          segment.points[0][0],
+          segment.points[0][1],
+          segment.points[1][0],
+          segment.points[1][1],
+          segment.points[0][0],
+          segment.points[0][1],
+          outputBezier.length()
+        );
+      }
+
+      outputBezier.setTripleAt(
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[2][0],
+        segment.points[2][1],
+        outputBezier.length()
+      );
+
+      lastPoint = segment.points[3];
+    }
+  }
+
+  if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
+
+  return outputBezier;
+};
+
+OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+  var miterLimit = this.miterLimit.v;
+  var lineJoin = this.lineJoin;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function getFontProperties(fontData) {
+  var styles = fontData.fStyle ? fontData.fStyle.split(' ') : [];
+
+  var fWeight = 'normal'; var
+    fStyle = 'normal';
+  var len = styles.length;
+  var styleName;
+  for (var i = 0; i < len; i += 1) {
+    styleName = styles[i].toLowerCase();
+    switch (styleName) {
+      case 'italic':
+        fStyle = 'italic';
+        break;
+      case 'bold':
+        fWeight = '700';
+        break;
+      case 'black':
+        fWeight = '900';
+        break;
+      case 'medium':
+        fWeight = '500';
+        break;
+      case 'regular':
+      case 'normal':
+        fWeight = '400';
+        break;
+      case 'light':
+      case 'thin':
+        fWeight = '200';
+        break;
+      default:
+        break;
+    }
+  }
+
+  return {
+    style: fStyle,
+    weight: fontData.fWeight || fWeight,
+  };
+}
+
+const FontManager = (function () {
+  var maxWaitingTime = 5000;
+  var emptyChar = {
+    w: 0,
+    size: 0,
+    shapes: [],
+    data: {
+      shapes: [],
+    },
+  };
+  var combinedCharacters = [];
+  // Hindi characters
+  combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366,
+    2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379,
+    2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
+
+  var BLACK_FLAG_CODE_POINT = 127988;
+  var CANCEL_TAG_CODE_POINT = 917631;
+  var A_TAG_CODE_POINT = 917601;
+  var Z_TAG_CODE_POINT = 917626;
+  var VARIATION_SELECTOR_16_CODE_POINT = 65039;
+  var ZERO_WIDTH_JOINER_CODE_POINT = 8205;
+  var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
+  var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
+
+  var surrogateModifiers = [
+    'd83cdffb',
+    'd83cdffc',
+    'd83cdffd',
+    'd83cdffe',
+    'd83cdfff',
+  ];
+
+  function trimFontOptions(font) {
+    var familyArray = font.split(',');
+    var i;
+    var len = familyArray.length;
+    var enabledFamilies = [];
+    for (i = 0; i < len; i += 1) {
+      if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
+        enabledFamilies.push(familyArray[i]);
+      }
+    }
+    return enabledFamilies.join(',');
+  }
+
+  function setUpNode(font, family) {
+    var parentNode = createTag('span');
+    // Node is invisible to screen readers.
+    parentNode.setAttribute('aria-hidden', true);
+    parentNode.style.fontFamily = family;
+    var node = createTag('span');
+    // Characters that vary significantly among different fonts
+    node.innerText = 'giItT1WQy@!-/#';
+    // Visible - so we can measure it - but not on the screen
+    parentNode.style.position = 'absolute';
+    parentNode.style.left = '-10000px';
+    parentNode.style.top = '-10000px';
+    // Large font size makes even subtle changes obvious
+    parentNode.style.fontSize = '300px';
+    // Reset any font properties
+    parentNode.style.fontVariant = 'normal';
+    parentNode.style.fontStyle = 'normal';
+    parentNode.style.fontWeight = 'normal';
+    parentNode.style.letterSpacing = '0';
+    parentNode.appendChild(node);
+    document.body.appendChild(parentNode);
+
+    // Remember width with no applied web font
+    var width = node.offsetWidth;
+    node.style.fontFamily = trimFontOptions(font) + ', ' + family;
+    return { node: node, w: width, parent: parentNode };
+  }
+
+  function checkLoadedFonts() {
+    var i;
+    var len = this.fonts.length;
+    var node;
+    var w;
+    var loadedCount = len;
+    for (i = 0; i < len; i += 1) {
+      if (this.fonts[i].loaded) {
+        loadedCount -= 1;
+      } else if (this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0) {
+        this.fonts[i].loaded = true;
+      } else {
+        node = this.fonts[i].monoCase.node;
+        w = this.fonts[i].monoCase.w;
+        if (node.offsetWidth !== w) {
+          loadedCount -= 1;
+          this.fonts[i].loaded = true;
+        } else {
+          node = this.fonts[i].sansCase.node;
+          w = this.fonts[i].sansCase.w;
+          if (node.offsetWidth !== w) {
+            loadedCount -= 1;
+            this.fonts[i].loaded = true;
+          }
+        }
+        if (this.fonts[i].loaded) {
+          this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
+          this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
+        }
+      }
+    }
+
+    if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
+      setTimeout(this.checkLoadedFontsBinded, 20);
+    } else {
+      setTimeout(this.setIsLoadedBinded, 10);
+    }
+  }
+
+  function createHelper(fontData, def) {
+    var engine = (document.body && def) ? 'svg' : 'canvas';
+    var helper;
+    var fontProps = getFontProperties(fontData);
+    if (engine === 'svg') {
+      var tHelper = createNS('text');
+      tHelper.style.fontSize = '100px';
+      // tHelper.style.fontFamily = fontData.fFamily;
+      tHelper.setAttribute('font-family', fontData.fFamily);
+      tHelper.setAttribute('font-style', fontProps.style);
+      tHelper.setAttribute('font-weight', fontProps.weight);
+      tHelper.textContent = '1';
+      if (fontData.fClass) {
+        tHelper.style.fontFamily = 'inherit';
+        tHelper.setAttribute('class', fontData.fClass);
+      } else {
+        tHelper.style.fontFamily = fontData.fFamily;
+      }
+      def.appendChild(tHelper);
+      helper = tHelper;
+    } else {
+      var tCanvasHelper = new OffscreenCanvas(500, 500).getContext('2d');
+      tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
+      helper = tCanvasHelper;
+    }
+    function measure(text) {
+      if (engine === 'svg') {
+        helper.textContent = text;
+        return helper.getComputedTextLength();
+      }
+      return helper.measureText(text).width;
+    }
+    return {
+      measureText: measure,
+    };
+  }
+
+  function addFonts(fontData, defs) {
+    if (!fontData) {
+      this.isLoaded = true;
+      return;
+    }
+    if (this.chars) {
+      this.isLoaded = true;
+      this.fonts = fontData.list;
+      return;
+    }
+    if (!document.body) {
+      this.isLoaded = true;
+      fontData.list.forEach((data) => {
+        data.helper = createHelper(data);
+        data.cache = {};
+      });
+      this.fonts = fontData.list;
+      return;
+    }
+
+    var fontArr = fontData.list;
+    var i;
+    var len = fontArr.length;
+    var _pendingFonts = len;
+    for (i = 0; i < len; i += 1) {
+      var shouldLoadFont = true;
+      var loadedSelector;
+      var j;
+      fontArr[i].loaded = false;
+      fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
+      fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
+      if (!fontArr[i].fPath) {
+        fontArr[i].loaded = true;
+        _pendingFonts -= 1;
+      } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
+        loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
+
+        if (loadedSelector.length > 0) {
+          shouldLoadFont = false;
+        }
+
+        if (shouldLoadFont) {
+          var s = createTag('style');
+          s.setAttribute('f-forigin', fontArr[i].fOrigin);
+          s.setAttribute('f-origin', fontArr[i].origin);
+          s.setAttribute('f-family', fontArr[i].fFamily);
+          s.type = 'text/css';
+          s.innerText = '@font-face {font-family: ' + fontArr[i].fFamily + "; font-style: normal; src: url('" + fontArr[i].fPath + "');}";
+          defs.appendChild(s);
+        }
+      } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
+        loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var l = createTag('link');
+          l.setAttribute('f-forigin', fontArr[i].fOrigin);
+          l.setAttribute('f-origin', fontArr[i].origin);
+          l.type = 'text/css';
+          l.rel = 'stylesheet';
+          l.href = fontArr[i].fPath;
+          document.body.appendChild(l);
+        }
+      } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
+        loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (fontArr[i].fPath === loadedSelector[j].src) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var sc = createTag('link');
+          sc.setAttribute('f-forigin', fontArr[i].fOrigin);
+          sc.setAttribute('f-origin', fontArr[i].origin);
+          sc.setAttribute('rel', 'stylesheet');
+          sc.setAttribute('href', fontArr[i].fPath);
+          defs.appendChild(sc);
+        }
+      }
+      fontArr[i].helper = createHelper(fontArr[i], defs);
+      fontArr[i].cache = {};
+      this.fonts.push(fontArr[i]);
+    }
+    if (_pendingFonts === 0) {
+      this.isLoaded = true;
+    } else {
+      // On some cases even if the font is loaded, it won't load correctly when measuring text on canvas.
+      // Adding this timeout seems to fix it
+      setTimeout(this.checkLoadedFonts.bind(this), 100);
+    }
+  }
+
+  function addChars(chars) {
+    if (!chars) {
+      return;
+    }
+    if (!this.chars) {
+      this.chars = [];
+    }
+    var i;
+    var len = chars.length;
+    var j;
+    var jLen = this.chars.length;
+    var found;
+    for (i = 0; i < len; i += 1) {
+      j = 0;
+      found = false;
+      while (j < jLen) {
+        if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
+          found = true;
+        }
+        j += 1;
+      }
+      if (!found) {
+        this.chars.push(chars[i]);
+        jLen += 1;
+      }
+    }
+  }
+
+  function getCharData(char, style, font) {
+    var i = 0;
+    var len = this.chars.length;
+    while (i < len) {
+      if (this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font) {
+        return this.chars[i];
+      }
+      i += 1;
+    }
+    if (((typeof char === 'string' && char.charCodeAt(0) !== 13) || !char)
+            && console
+            && console.warn // eslint-disable-line no-console
+            && !this._warned
+    ) {
+      this._warned = true;
+      console.warn('Missing character from exported characters list: ', char, style, font); // eslint-disable-line no-console
+    }
+    return emptyChar;
+  }
+
+  function measureText(char, fontName, size) {
+    var fontData = this.getFontByName(fontName);
+    // Using the char instead of char.charCodeAt(0)
+    // to avoid collisions between equal chars
+    var index = char;
+    if (!fontData.cache[index]) {
+      var tHelper = fontData.helper;
+      if (char === ' ') {
+        var doubleSize = tHelper.measureText('|' + char + '|');
+        var singleSize = tHelper.measureText('||');
+        fontData.cache[index] = (doubleSize - singleSize) / 100;
+      } else {
+        fontData.cache[index] = tHelper.measureText(char) / 100;
+      }
+    }
+    return fontData.cache[index] * size;
+  }
+
+  function getFontByName(name) {
+    var i = 0;
+    var len = this.fonts.length;
+    while (i < len) {
+      if (this.fonts[i].fName === name) {
+        return this.fonts[i];
+      }
+      i += 1;
+    }
+    return this.fonts[0];
+  }
+
+  function getCodePoint(string) {
+    var codePoint = 0;
+    var first = string.charCodeAt(0);
+    if (first >= 0xD800 && first <= 0xDBFF) {
+      var second = string.charCodeAt(1);
+      if (second >= 0xDC00 && second <= 0xDFFF) {
+        codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+      }
+    }
+    return codePoint;
+  }
+
+  // Skin tone modifiers
+  function isModifier(firstCharCode, secondCharCode) {
+    var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
+    return surrogateModifiers.indexOf(sum) !== -1;
+  }
+
+  function isZeroWidthJoiner(charCode) {
+    return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
+  }
+
+  // This codepoint may change the appearance of the preceding character.
+  // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
+  // as a colorful image as compared to a monochrome text variant.
+  function isVariationSelector(charCode) {
+    return charCode === VARIATION_SELECTOR_16_CODE_POINT;
+  }
+
+  // The regional indicator symbols are a set of 26 alphabetic Unicode
+  /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
+  // two-letter country codes in a way that allows optional special treatment.
+  function isRegionalCode(string) {
+    var codePoint = getCodePoint(string);
+    if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
+      return true;
+    }
+    return false;
+  }
+
+  // Some Emoji implementations represent combinations of
+  // two “regional indicator” letters as a single flag symbol.
+  function isFlagEmoji(string) {
+    return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
+  }
+
+  function isCombinedCharacter(char) {
+    return combinedCharacters.indexOf(char) !== -1;
+  }
+
+  // Regional flags start with a BLACK_FLAG_CODE_POINT
+  // folowed by 5 chars in the TAG range
+  // and end with a CANCEL_TAG_CODE_POINT
+  function isRegionalFlag(text, index) {
+    var codePoint = getCodePoint(text.substr(index, 2));
+    if (codePoint !== BLACK_FLAG_CODE_POINT) {
+      return false;
+    }
+    var count = 0;
+    index += 2;
+    while (count < 5) {
+      codePoint = getCodePoint(text.substr(index, 2));
+      if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
+        return false;
+      }
+      count += 1;
+      index += 2;
+    }
+    return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
+  }
+
+  function setIsLoaded() {
+    this.isLoaded = true;
+  }
+
+  var Font = function () {
+    this.fonts = [];
+    this.chars = null;
+    this.typekitLoaded = 0;
+    this.isLoaded = false;
+    this._warned = false;
+    this.initTime = Date.now();
+    this.setIsLoadedBinded = this.setIsLoaded.bind(this);
+    this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
+  };
+  Font.isModifier = isModifier;
+  Font.isZeroWidthJoiner = isZeroWidthJoiner;
+  Font.isFlagEmoji = isFlagEmoji;
+  Font.isRegionalCode = isRegionalCode;
+  Font.isCombinedCharacter = isCombinedCharacter;
+  Font.isRegionalFlag = isRegionalFlag;
+  Font.isVariationSelector = isVariationSelector;
+  Font.BLACK_FLAG_CODE_POINT = BLACK_FLAG_CODE_POINT;
+
+  var fontPrototype = {
+    addChars: addChars,
+    addFonts: addFonts,
+    getCharData: getCharData,
+    getFontByName: getFontByName,
+    measureText: measureText,
+    checkLoadedFonts: checkLoadedFonts,
+    setIsLoaded: setIsLoaded,
+  };
+
+  Font.prototype = fontPrototype;
+
+  return Font;
+}());
+
+function SlotManager(animationData) {
+  this.animationData = animationData;
+}
+SlotManager.prototype.getProp = function (data) {
+  if (this.animationData.slots
+    && this.animationData.slots[data.sid]
+  ) {
+    return Object.assign(data, this.animationData.slots[data.sid].p);
+  }
+  return data;
+};
+
+function slotFactory(animationData) {
+  return new SlotManager(animationData);
+}
+
+function RenderableElement() {
+
+}
+
+RenderableElement.prototype = {
+  initRenderable: function () {
+    // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
+    this.isInRange = false;
+    // layer's display state
+    this.hidden = false;
+    // If layer's transparency equals 0, it can be hidden
+    this.isTransparent = false;
+    // list of animated components
+    this.renderableComponents = [];
+  },
+  addRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) === -1) {
+      this.renderableComponents.push(component);
+    }
+  },
+  removeRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) !== -1) {
+      this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1);
+    }
+  },
+  prepareRenderableFrame: function (num) {
+    this.checkLayerLimits(num);
+  },
+  checkTransparency: function () {
+    if (this.finalTransform.mProp.o.v <= 0) {
+      if (!this.isTransparent && this.globalData.renderConfig.hideOnTransparent) {
+        this.isTransparent = true;
+        this.hide();
+      }
+    } else if (this.isTransparent) {
+      this.isTransparent = false;
+      this.show();
+    }
+  },
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     *
+     */
+  checkLayerLimits: function (num) {
+    if (this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) {
+      if (this.isInRange !== true) {
+        this.globalData._mdf = true;
+        this._mdf = true;
+        this.isInRange = true;
+        this.show();
+      }
+    } else if (this.isInRange !== false) {
+      this.globalData._mdf = true;
+      this.isInRange = false;
+      this.hide();
+    }
+  },
+  renderRenderable: function () {
+    var i;
+    var len = this.renderableComponents.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderableComponents[i].renderFrame(this._isFirstFrame);
+    }
+    /* this.maskManager.renderFrame(this.finalTransform.mat);
+        this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
+  },
+  sourceRectAtTime: function () {
+    return {
+      top: 0,
+      left: 0,
+      width: 100,
+      height: 100,
+    };
+  },
+  getLayerSize: function () {
+    if (this.data.ty === 5) {
+      return { w: this.data.textData.width, h: this.data.textData.height };
+    }
+    return { w: this.data.width, h: this.data.height };
+  },
+};
+
+const getBlendMode = (function () {
+  var blendModeEnums = {
+    0: 'source-over',
+    1: 'multiply',
+    2: 'screen',
+    3: 'overlay',
+    4: 'darken',
+    5: 'lighten',
+    6: 'color-dodge',
+    7: 'color-burn',
+    8: 'hard-light',
+    9: 'soft-light',
+    10: 'difference',
+    11: 'exclusion',
+    12: 'hue',
+    13: 'saturation',
+    14: 'color',
+    15: 'luminosity',
+  };
+
+  return function (mode) {
+    return blendModeEnums[mode] || '';
+  };
+}());
+
+function SliderEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function AngleEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function ColorEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function PointEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function LayerIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function MaskIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function CheckboxEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function NoValueEffect() {
+  this.p = {};
+}
+
+function EffectsManager(data, element) {
+  var effects = data.ef || [];
+  this.effectElements = [];
+  var i;
+  var len = effects.length;
+  var effectItem;
+  for (i = 0; i < len; i += 1) {
+    effectItem = new GroupEffect(effects[i], element);
+    this.effectElements.push(effectItem);
+  }
+}
+
+function GroupEffect(data, element) {
+  this.init(data, element);
+}
+
+extendPrototype([DynamicPropertyContainer], GroupEffect);
+
+GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
+
+GroupEffect.prototype.init = function (data, element) {
+  this.data = data;
+  this.effectElements = [];
+  this.initDynamicPropertyContainer(element);
+  var i;
+  var len = this.data.ef.length;
+  var eff;
+  var effects = this.data.ef;
+  for (i = 0; i < len; i += 1) {
+    eff = null;
+    switch (effects[i].ty) {
+      case 0:
+        eff = new SliderEffect(effects[i], element, this);
+        break;
+      case 1:
+        eff = new AngleEffect(effects[i], element, this);
+        break;
+      case 2:
+        eff = new ColorEffect(effects[i], element, this);
+        break;
+      case 3:
+        eff = new PointEffect(effects[i], element, this);
+        break;
+      case 4:
+      case 7:
+        eff = new CheckboxEffect(effects[i], element, this);
+        break;
+      case 10:
+        eff = new LayerIndexEffect(effects[i], element, this);
+        break;
+      case 11:
+        eff = new MaskIndexEffect(effects[i], element, this);
+        break;
+      case 5:
+        eff = new EffectsManager(effects[i], element, this);
+        break;
+        // case 6:
+      default:
+        eff = new NoValueEffect(effects[i], element, this);
+        break;
+    }
+    if (eff) {
+      this.effectElements.push(eff);
+    }
+  }
+};
+
+function BaseElement() {
+}
+
+BaseElement.prototype = {
+  checkMasks: function () {
+    if (!this.data.hasMask) {
+      return false;
+    }
+    var i = 0;
+    var len = this.data.masksProperties.length;
+    while (i < len) {
+      if ((this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false)) {
+        return true;
+      }
+      i += 1;
+    }
+    return false;
+  },
+  initExpressions: function () {
+    const expressionsInterfaces = getExpressionInterfaces();
+    if (!expressionsInterfaces) {
+      return;
+    }
+    const LayerExpressionInterface = expressionsInterfaces('layer');
+    const EffectsExpressionInterface = expressionsInterfaces('effects');
+    const ShapeExpressionInterface = expressionsInterfaces('shape');
+    const TextExpressionInterface = expressionsInterfaces('text');
+    const CompExpressionInterface = expressionsInterfaces('comp');
+    this.layerInterface = LayerExpressionInterface(this);
+    if (this.data.hasMask && this.maskManager) {
+      this.layerInterface.registerMaskInterface(this.maskManager);
+    }
+    var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
+    this.layerInterface.registerEffectsInterface(effectsInterface);
+
+    if (this.data.ty === 0 || this.data.xt) {
+      this.compInterface = CompExpressionInterface(this);
+    } else if (this.data.ty === 4) {
+      this.layerInterface.shapeInterface = ShapeExpressionInterface(this.shapesData, this.itemsData, this.layerInterface);
+      this.layerInterface.content = this.layerInterface.shapeInterface;
+    } else if (this.data.ty === 5) {
+      this.layerInterface.textInterface = TextExpressionInterface(this);
+      this.layerInterface.text = this.layerInterface.textInterface;
+    }
+  },
+  setBlendMode: function () {
+    var blendModeValue = getBlendMode(this.data.bm);
+    var elem = this.baseElement || this.layerElement;
+
+    elem.style['mix-blend-mode'] = blendModeValue;
+  },
+  initBaseData: function (data, globalData, comp) {
+    this.globalData = globalData;
+    this.comp = comp;
+    this.data = data;
+    this.layerId = createElementID();
+
+    // Stretch factor for old animations missing this property.
+    if (!this.data.sr) {
+      this.data.sr = 1;
+    }
+    // effects manager
+    this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
+  },
+  getType: function () {
+    return this.type;
+  },
+  sourceRectAtTime: function () {},
+};
+
+/**
+ * @file
+ * Handles element's layer frame update.
+ * Checks layer in point and out point
+ *
+ */
+
+function FrameElement() {}
+
+FrameElement.prototype = {
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     */
+  initFrame: function () {
+    // set to true when inpoint is rendered
+    this._isFirstFrame = false;
+    // list of animated properties
+    this.dynamicProperties = [];
+    // If layer has been modified in current tick this will be true
+    this._mdf = false;
+  },
+  /**
+     * @function
+     * Calculates all dynamic values
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     * @param {boolean} isVisible
+     * if layers is currently in range
+     *
+     */
+  prepareProperties: function (num, isVisible) {
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      if (isVisible || (this._isParent && this.dynamicProperties[i].propType === 'transform')) {
+        this.dynamicProperties[i].getValue();
+        if (this.dynamicProperties[i]._mdf) {
+          this.globalData._mdf = true;
+          this._mdf = true;
+        }
+      }
+    }
+  },
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+    }
+  },
+};
+
+function FootageElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.footageData = globalData.imageLoader.getAsset(this.assetData);
+  this.initBaseData(data, globalData, comp);
+}
+
+FootageElement.prototype.prepareFrame = function () {
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
+
+FootageElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+FootageElement.prototype.renderFrame = function () {
+};
+
+FootageElement.prototype.destroy = function () {
+};
+
+FootageElement.prototype.initExpressions = function () {
+  const expressionsInterfaces = getExpressionInterfaces();
+  if (!expressionsInterfaces) {
+    return;
+  }
+  const FootageInterface = expressionsInterfaces('footage');
+  this.layerInterface = FootageInterface(this);
+};
+
+FootageElement.prototype.getFootageData = function () {
+  return this.footageData;
+};
+
+function AudioElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initBaseData(data, globalData, comp);
+  this._isPlaying = false;
+  this._canPlay = false;
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  this.audio = this.globalData.audioController.createAudio(assetPath);
+  this._currentTime = 0;
+  this.globalData.audioController.addAudio(this);
+  this._volumeMultiplier = 1;
+  this._volume = 1;
+  this._previousVolume = null;
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+  this.lv = PropertyFactory.getProp(this, data.au && data.au.lv ? data.au.lv : { k: [100] }, 1, 0.01, this);
+}
+
+AudioElement.prototype.prepareFrame = function (num) {
+  this.prepareRenderableFrame(num, true);
+  this.prepareProperties(num, true);
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    this._currentTime = timeRemapped;
+  } else {
+    this._currentTime = num / this.data.sr;
+  }
+  this._volume = this.lv.v[0];
+  var totalVolume = this._volume * this._volumeMultiplier;
+  if (this._previousVolume !== totalVolume) {
+    this._previousVolume = totalVolume;
+    this.audio.volume(totalVolume);
+  }
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
+
+AudioElement.prototype.renderFrame = function () {
+  if (this.isInRange && this._canPlay) {
+    if (!this._isPlaying) {
+      this.audio.play();
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+      this._isPlaying = true;
+    } else if (!this.audio.playing()
+      || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1
+    ) {
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+    }
+  }
+};
+
+AudioElement.prototype.show = function () {
+  // this.audio.play()
+};
+
+AudioElement.prototype.hide = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+};
+
+AudioElement.prototype.pause = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+  this._canPlay = false;
+};
+
+AudioElement.prototype.resume = function () {
+  this._canPlay = true;
+};
+
+AudioElement.prototype.setRate = function (rateValue) {
+  this.audio.rate(rateValue);
+};
+
+AudioElement.prototype.volume = function (volumeValue) {
+  this._volumeMultiplier = volumeValue;
+  this._previousVolume = volumeValue * this._volume;
+  this.audio.volume(this._previousVolume);
+};
+
+AudioElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+AudioElement.prototype.destroy = function () {
+};
+
+AudioElement.prototype.sourceRectAtTime = function () {
+};
+
+AudioElement.prototype.initExpressions = function () {
+};
+
+function BaseRenderer() {}
+BaseRenderer.prototype.checkLayers = function (num) {
+  var i;
+  var len = this.layers.length;
+  var data;
+  this.completeLayers = true;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (!this.elements[i]) {
+      data = this.layers[i];
+      if (data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) {
+        this.buildItem(i);
+      }
+    }
+    this.completeLayers = this.elements[i] ? this.completeLayers : false;
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.createItem = function (layer) {
+  switch (layer.ty) {
+    case 2:
+      return this.createImage(layer);
+    case 0:
+      return this.createComp(layer);
+    case 1:
+      return this.createSolid(layer);
+    case 3:
+      return this.createNull(layer);
+    case 4:
+      return this.createShape(layer);
+    case 5:
+      return this.createText(layer);
+    case 6:
+      return this.createAudio(layer);
+    case 13:
+      return this.createCamera(layer);
+    case 15:
+      return this.createFootage(layer);
+    default:
+      return this.createNull(layer);
+  }
+};
+
+BaseRenderer.prototype.createCamera = function () {
+  throw new Error('You\'re using a 3d camera. Try the html renderer.');
+};
+
+BaseRenderer.prototype.createAudio = function (data) {
+  return new AudioElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.createFootage = function (data) {
+  return new FootageElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.buildAllItems = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    this.buildItem(i);
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.includeLayers = function (newLayers) {
+  this.completeLayers = false;
+  var i;
+  var len = newLayers.length;
+  var j;
+  var jLen = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    j = 0;
+    while (j < jLen) {
+      if (this.layers[j].id === newLayers[i].id) {
+        this.layers[j] = newLayers[i];
+        break;
+      }
+      j += 1;
+    }
+  }
+};
+
+BaseRenderer.prototype.setProjectInterface = function (pInterface) {
+  this.globalData.projectInterface = pInterface;
+};
+
+BaseRenderer.prototype.initItems = function () {
+  if (!this.globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+};
+BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
+  var elements = this.elements;
+  var layers = this.layers;
+  var i = 0;
+  var len = layers.length;
+  while (i < len) {
+    if (layers[i].ind == parentName) { // eslint-disable-line eqeqeq
+      if (!elements[i] || elements[i] === true) {
+        this.buildItem(i);
+        this.addPendingElement(element);
+      } else {
+        hierarchy.push(elements[i]);
+        elements[i].setAsParent();
+        if (layers[i].parent !== undefined) {
+          this.buildElementParenting(element, layers[i].parent, hierarchy);
+        } else {
+          element.setHierarchy(hierarchy);
+        }
+      }
+    }
+    i += 1;
+  }
+};
+
+BaseRenderer.prototype.addPendingElement = function (element) {
+  this.pendingElements.push(element);
+};
+
+BaseRenderer.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var len = assets.length;
+  for (i = 0; i < len; i += 1) {
+    if (assets[i].xt) {
+      var comp = this.createComp(assets[i]);
+      comp.initExpressions();
+      this.globalData.projectInterface.registerComposition(comp);
+    }
+  }
+};
+
+BaseRenderer.prototype.getElementById = function (ind) {
+  var i;
+  var len = this.elements.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i].data.ind === ind) {
+      return this.elements[i];
+    }
+  }
+  return null;
+};
+
+BaseRenderer.prototype.getElementByPath = function (path) {
+  var pathValue = path.shift();
+  var element;
+  if (typeof pathValue === 'number') {
+    element = this.elements[pathValue];
+  } else {
+    var i;
+    var len = this.elements.length;
+    for (i = 0; i < len; i += 1) {
+      if (this.elements[i].data.nm === pathValue) {
+        element = this.elements[i];
+        break;
+      }
+    }
+  }
+  if (path.length === 0) {
+    return element;
+  }
+  return element.getElementByPath(path);
+};
+
+BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
+  this.globalData.fontManager = new FontManager();
+  this.globalData.slotManager = slotFactory(animData);
+  this.globalData.fontManager.addChars(animData.chars);
+  this.globalData.fontManager.addFonts(animData.fonts, fontsContainer);
+  this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+  this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+  this.globalData.imageLoader = this.animationItem.imagePreloader;
+  this.globalData.audioController = this.animationItem.audioController;
+  this.globalData.frameId = 0;
+  this.globalData.frameRate = animData.fr;
+  this.globalData.nm = animData.nm;
+  this.globalData.compSize = {
+    w: animData.w,
+    h: animData.h,
+  };
+};
+
+var effectTypes = {
+  TRANSFORM_EFFECT: 'transformEFfect',
+};
+
+function TransformElement() {}
+
+TransformElement.prototype = {
+  initTransform: function () {
+    var mat = new Matrix();
+    this.finalTransform = {
+      mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : { o: 0 },
+      _matMdf: false,
+      _localMatMdf: false,
+      _opMdf: false,
+      mat: mat,
+      localMat: mat,
+      localOpacity: 1,
+    };
+    if (this.data.ao) {
+      this.finalTransform.mProp.autoOriented = true;
+    }
+
+    // TODO: check TYPE 11: Guided elements
+    if (this.data.ty !== 11) {
+      // this.createElements();
+    }
+  },
+  renderTransform: function () {
+    this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
+    this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
+
+    if (this.hierarchy) {
+      var mat;
+      var finalMat = this.finalTransform.mat;
+      var i = 0;
+      var len = this.hierarchy.length;
+      // Checking if any of the transformation matrices in the hierarchy chain has changed.
+      if (!this.finalTransform._matMdf) {
+        while (i < len) {
+          if (this.hierarchy[i].finalTransform.mProp._mdf) {
+            this.finalTransform._matMdf = true;
+            break;
+          }
+          i += 1;
+        }
+      }
+
+      if (this.finalTransform._matMdf) {
+        mat = this.finalTransform.mProp.v.props;
+        finalMat.cloneFromProps(mat);
+        for (i = 0; i < len; i += 1) {
+          finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
+        }
+      }
+    }
+    if (!this.localTransforms || this.finalTransform._matMdf) {
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+    }
+    if (this.finalTransform._opMdf) {
+      this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderLocalTransform: function () {
+    if (this.localTransforms) {
+      var i = 0;
+      var len = this.localTransforms.length;
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+      if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
+        while (i < len) {
+          if (this.localTransforms[i]._mdf) {
+            this.finalTransform._localMatMdf = true;
+          }
+          if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
+            this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+            this.finalTransform._opMdf = true;
+          }
+          i += 1;
+        }
+      }
+      if (this.finalTransform._localMatMdf) {
+        var localMat = this.finalTransform.localMat;
+        this.localTransforms[0].matrix.clone(localMat);
+        for (i = 1; i < len; i += 1) {
+          var lmat = this.localTransforms[i].matrix;
+          localMat.multiply(lmat);
+        }
+        localMat.multiply(this.finalTransform.mat);
+      }
+      if (this.finalTransform._opMdf) {
+        var localOp = this.finalTransform.localOpacity;
+        for (i = 0; i < len; i += 1) {
+          localOp *= this.localTransforms[i].opacity * 0.01;
+        }
+        this.finalTransform.localOpacity = localOp;
+      }
+    }
+  },
+  searchEffectTransforms: function () {
+    if (this.renderableEffectsManager) {
+      var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+      if (transformEffects.length) {
+        this.localTransforms = [];
+        this.finalTransform.localMat = new Matrix();
+        var i = 0;
+        var len = transformEffects.length;
+        for (i = 0; i < len; i += 1) {
+          this.localTransforms.push(transformEffects[i]);
+        }
+      }
+    }
+  },
+  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;
+    var len = transforms.length;
+    var 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;
+  },
+  mHelper: new Matrix(),
+};
+
+function MaskElement(data, element, globalData) {
+  this.data = data;
+  this.element = element;
+  this.globalData = globalData;
+  this.storedData = [];
+  this.masksProperties = this.data.masksProperties || [];
+  this.maskElement = null;
+  var defs = this.globalData.defs;
+  var i;
+  var len = this.masksProperties ? this.masksProperties.length : 0;
+  this.viewData = createSizedArray(len);
+  this.solidPath = '';
+
+  var path;
+  var properties = this.masksProperties;
+  var count = 0;
+  var currentMasks = [];
+  var j;
+  var jLen;
+  var layerId = createElementID();
+  var rect;
+  var expansor;
+  var feMorph;
+  var x;
+  var maskType = 'clipPath';
+  var maskRef = 'clip-path';
+  for (i = 0; i < len; i += 1) {
+    if ((properties[i].mode !== 'a' && properties[i].mode !== 'n') || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
+      maskType = 'mask';
+      maskRef = 'mask';
+    }
+
+    if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
+      rect = createNS('rect');
+      rect.setAttribute('fill', '#ffffff');
+      rect.setAttribute('width', this.element.comp.data.w || 0);
+      rect.setAttribute('height', this.element.comp.data.h || 0);
+      currentMasks.push(rect);
+    } else {
+      rect = null;
+    }
+
+    path = createNS('path');
+    if (properties[i].mode === 'n') {
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        elem: path,
+        lastPath: '',
+      };
+      defs.appendChild(path);
+    } else {
+      count += 1;
+
+      path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      path.setAttribute('clip-rule', 'nonzero');
+      var filterID;
+
+      if (properties[i].x.k !== 0) {
+        maskType = 'mask';
+        maskRef = 'mask';
+        x = PropertyFactory.getProp(this.element, properties[i].x, 0, null, this.element);
+        filterID = createElementID();
+        expansor = createNS('filter');
+        expansor.setAttribute('id', filterID);
+        feMorph = createNS('feMorphology');
+        feMorph.setAttribute('operator', 'erode');
+        feMorph.setAttribute('in', 'SourceGraphic');
+        feMorph.setAttribute('radius', '0');
+        expansor.appendChild(feMorph);
+        defs.appendChild(expansor);
+        path.setAttribute('stroke', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      } else {
+        feMorph = null;
+        x = null;
+      }
+
+      // TODO move this to a factory or to a constructor
+      this.storedData[i] = {
+        elem: path,
+        x: x,
+        expan: feMorph,
+        lastPath: '',
+        lastOperator: '',
+        filterId: filterID,
+        lastRadius: 0,
+      };
+      if (properties[i].mode === 'i') {
+        jLen = currentMasks.length;
+        var g = createNS('g');
+        for (j = 0; j < jLen; j += 1) {
+          g.appendChild(currentMasks[j]);
+        }
+        var mask = createNS('mask');
+        mask.setAttribute('mask-type', 'alpha');
+        mask.setAttribute('id', layerId + '_' + count);
+        mask.appendChild(path);
+        defs.appendChild(mask);
+        g.setAttribute('mask', 'url(' + getLocationHref() + '#' + layerId + '_' + count + ')');
+
+        currentMasks.length = 0;
+        currentMasks.push(g);
+      } else {
+        currentMasks.push(path);
+      }
+      if (properties[i].inv && !this.solidPath) {
+        this.solidPath = this.createLayerSolidPath();
+      }
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        elem: path,
+        lastPath: '',
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        invRect: rect,
+      };
+      if (!this.viewData[i].prop.k) {
+        this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
+      }
+    }
+  }
+
+  this.maskElement = createNS(maskType);
+
+  len = currentMasks.length;
+  for (i = 0; i < len; i += 1) {
+    this.maskElement.appendChild(currentMasks[i]);
+  }
+
+  if (count > 0) {
+    this.maskElement.setAttribute('id', layerId);
+    this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
+    defs.appendChild(this.maskElement);
+  }
+  if (this.viewData.length) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+MaskElement.prototype.getMaskProperty = function (pos) {
+  return this.viewData[pos].prop;
+};
+
+MaskElement.prototype.renderFrame = function (isFirstFrame) {
+  var finalMat = this.element.finalTransform.mat;
+  var i;
+  var len = this.masksProperties.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.viewData[i].prop._mdf || isFirstFrame) {
+      this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
+    }
+    if (this.viewData[i].op._mdf || isFirstFrame) {
+      this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
+    }
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
+        this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
+      }
+      if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
+        var feMorph = this.storedData[i].expan;
+        if (this.storedData[i].x.v < 0) {
+          if (this.storedData[i].lastOperator !== 'erode') {
+            this.storedData[i].lastOperator = 'erode';
+            this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
+          }
+          feMorph.setAttribute('radius', -this.storedData[i].x.v);
+        } else {
+          if (this.storedData[i].lastOperator !== 'dilate') {
+            this.storedData[i].lastOperator = 'dilate';
+            this.storedData[i].elem.setAttribute('filter', null);
+          }
+          this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
+        }
+      }
+    }
+  }
+};
+
+MaskElement.prototype.getMaskelement = function () {
+  return this.maskElement;
+};
+
+MaskElement.prototype.createLayerSolidPath = function () {
+  var path = 'M0,0 ';
+  path += ' h' + this.globalData.compSize.w;
+  path += ' v' + this.globalData.compSize.h;
+  path += ' h-' + this.globalData.compSize.w;
+  path += ' v-' + this.globalData.compSize.h + ' ';
+  return path;
+};
+
+MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
+  var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  var i;
+  var len;
+  len = pathNodes._length;
+  for (i = 1; i < len; i += 1) {
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
+  }
+  // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+  if (pathNodes.c && len > 1) {
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  }
+  // pathNodes.__renderedString = pathString;
+
+  if (viewData.lastPath !== pathString) {
+    var pathShapeValue = '';
+    if (viewData.elem) {
+      if (pathNodes.c) {
+        pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
+      }
+      viewData.elem.setAttribute('d', pathShapeValue);
+    }
+    viewData.lastPath = pathString;
+  }
+};
+
+MaskElement.prototype.destroy = function () {
+  this.element = null;
+  this.globalData = null;
+  this.maskElement = null;
+  this.data = null;
+  this.masksProperties = null;
+};
+
+const filtersFactory = (function () {
+  var ob = {};
+  ob.createFilter = createFilter;
+  ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
+
+  function createFilter(filId, skipCoordinates) {
+    var fil = createNS('filter');
+    fil.setAttribute('id', filId);
+    if (skipCoordinates !== true) {
+      fil.setAttribute('filterUnits', 'objectBoundingBox');
+      fil.setAttribute('x', '0%');
+      fil.setAttribute('y', '0%');
+      fil.setAttribute('width', '100%');
+      fil.setAttribute('height', '100%');
+    }
+    return fil;
+  }
+
+  function createAlphaToLuminanceFilter() {
+    var feColorMatrix = createNS('feColorMatrix');
+    feColorMatrix.setAttribute('type', 'matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+    feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
+    return feColorMatrix;
+  }
+
+  return ob;
+}());
+
+const featureSupport = (function () {
+  var ob = {
+    maskType: true,
+    svgLumaHidden: true,
+    offscreenCanvas: typeof OffscreenCanvas !== 'undefined',
+  };
+  if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
+    ob.maskType = false;
+  }
+  if (/firefox/i.test(navigator.userAgent)) {
+    ob.svgLumaHidden = false;
+  }
+  return ob;
+}());
+
+var registeredEffects = {};
+var idPrefix = 'filter_result_';
+
+function SVGEffects(elem) {
+  var i;
+  var source = 'SourceGraphic';
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  var filId = createElementID();
+  var fil = filtersFactory.createFilter(filId, true);
+  var count = 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects[type]) {
+      var Effect = registeredEffects[type].effect;
+      filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
+      source = idPrefix + count;
+      if (registeredEffects[type].countsAsEffect) {
+        count += 1;
+      }
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (count) {
+    elem.globalData.defs.appendChild(fil);
+    elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+SVGEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect(id, effect, countsAsEffect) {
+  registeredEffects[id] = {
+    effect,
+    countsAsEffect,
+  };
+}
+
+function SVGBaseElement() {
+}
+
+SVGBaseElement.prototype = {
+  initRendererElement: function () {
+    this.layerElement = createNS('g');
+  },
+  createContainerElements: function () {
+    this.matteElement = createNS('g');
+    this.transformedElement = this.layerElement;
+    this.maskedElement = this.layerElement;
+    this._sizeChanged = false;
+    var layerElementParent = null;
+    // If this layer acts as a mask for the following layer
+    if (this.data.td) {
+      this.matteMasks = {};
+      var gg = createNS('g');
+      gg.setAttribute('id', this.layerId);
+      gg.appendChild(this.layerElement);
+      layerElementParent = gg;
+      this.globalData.defs.appendChild(gg);
+    } else if (this.data.tt) {
+      this.matteElement.appendChild(this.layerElement);
+      layerElementParent = this.matteElement;
+      this.baseElement = this.matteElement;
+    } else {
+      this.baseElement = this.layerElement;
+    }
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
+    if (this.data.ty === 0 && !this.data.hd) {
+      var cp = createNS('clipPath');
+      var pt = createNS('path');
+      pt.setAttribute('d', 'M0,0 L' + this.data.w + ',0 L' + this.data.w + ',' + this.data.h + ' L0,' + this.data.h + 'z');
+      var clipId = createElementID();
+      cp.setAttribute('id', clipId);
+      cp.appendChild(pt);
+      this.globalData.defs.appendChild(cp);
+
+      if (this.checkMasks()) {
+        var cpGroup = createNS('g');
+        cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+        cpGroup.appendChild(this.layerElement);
+        this.transformedElement = cpGroup;
+        if (layerElementParent) {
+          layerElementParent.appendChild(this.transformedElement);
+        } else {
+          this.baseElement = this.transformedElement;
+        }
+      } else {
+        this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+      }
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    if (this.finalTransform._localMatMdf) {
+      this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
+    }
+    if (this.finalTransform._opMdf) {
+      this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
+    }
+  },
+  destroyBaseElement: function () {
+    this.layerElement = null;
+    this.matteElement = null;
+    this.maskManager.destroy();
+  },
+  getBaseElement: function () {
+    if (this.data.hd) {
+      return null;
+    }
+    return this.baseElement;
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+    this.renderableEffectsManager = new SVGEffects(this);
+    this.searchEffectTransforms();
+  },
+  getMatte: function (matteType) {
+    // This should not be a common case. But for backward compatibility, we'll create the matte object.
+    // It solves animations that have two consecutive layers marked as matte masks.
+    // Which is an undefined behavior in AE.
+    if (!this.matteMasks) {
+      this.matteMasks = {};
+    }
+    if (!this.matteMasks[matteType]) {
+      var id = this.layerId + '_' + matteType;
+      var filId;
+      var fil;
+      var useElement;
+      var gg;
+      if (matteType === 1 || matteType === 3) {
+        var masker = createNS('mask');
+        masker.setAttribute('id', id);
+        masker.setAttribute('mask-type', matteType === 3 ? 'luminance' : 'alpha');
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        masker.appendChild(useElement);
+        this.globalData.defs.appendChild(masker);
+        if (!featureSupport.maskType && matteType === 1) {
+          masker.setAttribute('mask-type', 'luminance');
+          filId = createElementID();
+          fil = filtersFactory.createFilter(filId);
+          this.globalData.defs.appendChild(fil);
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          gg.appendChild(useElement);
+          masker.appendChild(gg);
+          gg.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        }
+      } else if (matteType === 2) {
+        var maskGroup = createNS('mask');
+        maskGroup.setAttribute('id', id);
+        maskGroup.setAttribute('mask-type', 'alpha');
+        var maskGrouper = createNS('g');
+        maskGroup.appendChild(maskGrouper);
+        filId = createElementID();
+        fil = filtersFactory.createFilter(filId);
+        /// /
+        var feCTr = createNS('feComponentTransfer');
+        feCTr.setAttribute('in', 'SourceGraphic');
+        fil.appendChild(feCTr);
+        var feFunc = createNS('feFuncA');
+        feFunc.setAttribute('type', 'table');
+        feFunc.setAttribute('tableValues', '1.0 0.0');
+        feCTr.appendChild(feFunc);
+        /// /
+        this.globalData.defs.appendChild(fil);
+        var alphaRect = createNS('rect');
+        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');
+        alphaRect.setAttribute('opacity', '0');
+        maskGrouper.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        maskGrouper.appendChild(alphaRect);
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        maskGrouper.appendChild(useElement);
+        if (!featureSupport.maskType) {
+          maskGroup.setAttribute('mask-type', 'luminance');
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          maskGrouper.appendChild(alphaRect);
+          gg.appendChild(this.layerElement);
+          maskGrouper.appendChild(gg);
+        }
+        this.globalData.defs.appendChild(maskGroup);
+      }
+      this.matteMasks[matteType] = id;
+    }
+    return this.matteMasks[matteType];
+  },
+  setMatte: function (id) {
+    if (!this.matteElement) {
+      return;
+    }
+    this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+  },
+};
+
+/**
+ * @file
+ * Handles AE's layer parenting property.
+ *
+ */
+
+function HierarchyElement() {}
+
+HierarchyElement.prototype = {
+  /**
+     * @function
+     * Initializes hierarchy properties
+     *
+     */
+  initHierarchy: function () {
+    // element's parent list
+    this.hierarchy = [];
+    // if element is parent of another layer _isParent will be true
+    this._isParent = false;
+    this.checkParenting();
+  },
+  /**
+     * @function
+     * Sets layer's hierarchy.
+     * @param {array} hierarch
+     * layer's parent list
+     *
+     */
+  setHierarchy: function (hierarchy) {
+    this.hierarchy = hierarchy;
+  },
+  /**
+     * @function
+     * Sets layer as parent.
+     *
+     */
+  setAsParent: function () {
+    this._isParent = true;
+  },
+  /**
+     * @function
+     * Searches layer's parenting chain
+     *
+     */
+  checkParenting: function () {
+    if (this.data.parent !== undefined) {
+      this.comp.buildElementParenting(this, this.data.parent, []);
+    }
+  },
+};
+
+function RenderableDOMElement() {}
+
+(function () {
+  var _prototype = {
+    initElement: function (data, globalData, comp) {
+      this.initFrame();
+      this.initBaseData(data, globalData, comp);
+      this.initTransform(data, globalData, comp);
+      this.initHierarchy();
+      this.initRenderable();
+      this.initRendererElement();
+      this.createContainerElements();
+      this.createRenderableComponents();
+      this.createContent();
+      this.hide();
+    },
+    hide: function () {
+      // console.log('HIDE', this);
+      if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+        var elem = this.baseElement || this.layerElement;
+        elem.style.display = 'none';
+        this.hidden = true;
+      }
+    },
+    show: function () {
+      // console.log('SHOW', this);
+      if (this.isInRange && !this.isTransparent) {
+        if (!this.data.hd) {
+          var elem = this.baseElement || this.layerElement;
+          elem.style.display = 'block';
+        }
+        this.hidden = false;
+        this._isFirstFrame = true;
+      }
+    },
+    renderFrame: function () {
+      // If it is exported as hidden (data.hd === true) no need to render
+      // If it is not visible no need to render
+      if (this.data.hd || this.hidden) {
+        return;
+      }
+      this.renderTransform();
+      this.renderRenderable();
+      this.renderLocalTransform();
+      this.renderElement();
+      this.renderInnerContent();
+      if (this._isFirstFrame) {
+        this._isFirstFrame = false;
+      }
+    },
+    renderInnerContent: function () {},
+    prepareFrame: function (num) {
+      this._mdf = false;
+      this.prepareRenderableFrame(num);
+      this.prepareProperties(num, this.isInRange);
+      this.checkTransparency();
+    },
+    destroy: function () {
+      this.innerElem = null;
+      this.destroyBaseElement();
+    },
+  };
+  extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement);
+}());
+
+function IImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  if (this.assetData && this.assetData.sid) {
+    this.assetData = globalData.slotManager.getProp(this.assetData);
+  }
+  this.initElement(data, globalData, comp);
+  this.sourceRect = {
+    top: 0, left: 0, width: this.assetData.w, height: this.assetData.h,
+  };
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
+
+IImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+
+  this.innerElem = createNS('image');
+  this.innerElem.setAttribute('width', this.assetData.w + 'px');
+  this.innerElem.setAttribute('height', this.assetData.h + 'px');
+  this.innerElem.setAttribute('preserveAspectRatio', this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio);
+  this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+
+  this.layerElement.appendChild(this.innerElem);
+};
+
+IImageElement.prototype.sourceRectAtTime = function () {
+  return this.sourceRect;
+};
+
+function ProcessedElement(element, position) {
+  this.elem = element;
+  this.pos = position;
+}
+
+function IShapeElement() {
+}
+
+IShapeElement.prototype = {
+  addShapeToModifiers: function (data) {
+    var i;
+    var len = this.shapeModifiers.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapeModifiers[i].addShape(data);
+    }
+  },
+  isShapeInAnimatedModifiers: function (data) {
+    var i = 0;
+    var len = this.shapeModifiers.length;
+    while (i < len) {
+      if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
+        return true;
+      }
+    }
+    return false;
+  },
+  renderModifiers: function () {
+    if (!this.shapeModifiers.length) {
+      return;
+    }
+    var i;
+    var len = this.shapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].sh.reset();
+    }
+
+    len = this.shapeModifiers.length;
+    var shouldBreakProcess;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+      // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+      // TODO: find a better solution for this
+      if (shouldBreakProcess) {
+        break;
+      }
+    }
+  },
+
+  searchProcessedElement: function (elem) {
+    var elements = this.processedElements;
+    var i = 0;
+    var len = elements.length;
+    while (i < len) {
+      if (elements[i].elem === elem) {
+        return elements[i].pos;
+      }
+      i += 1;
+    }
+    return 0;
+  },
+  addProcessedElement: function (elem, pos) {
+    var elements = this.processedElements;
+    var i = elements.length;
+    while (i) {
+      i -= 1;
+      if (elements[i].elem === elem) {
+        elements[i].pos = pos;
+        return;
+      }
+    }
+    elements.push(new ProcessedElement(elem, pos));
+  },
+  prepareFrame: function (num) {
+    this.prepareRenderableFrame(num);
+    this.prepareProperties(num, this.isInRange);
+  },
+};
+
+const lineCapEnum = {
+  1: 'butt',
+  2: 'round',
+  3: 'square',
+};
+
+const lineJoinEnum = {
+  1: 'miter',
+  2: 'round',
+  3: 'bevel',
+};
+
+function SVGShapeData(transformers, level, shape) {
+  this.caches = [];
+  this.styles = [];
+  this.transformers = transformers;
+  this.lStr = '';
+  this.sh = shape;
+  this.lvl = level;
+  // TODO find if there are some cases where _isAnimated can be false.
+  // For now, since shapes add up with other shapes. They have to be calculated every time.
+  // One way of finding out is checking if all styles associated to this shape depend only of this shape
+  this._isAnimated = !!shape.k;
+  // TODO: commenting this for now since all shapes are animated
+  var i = 0;
+  var len = transformers.length;
+  while (i < len) {
+    if (transformers[i].mProps.dynamicProperties.length) {
+      this._isAnimated = true;
+      break;
+    }
+    i += 1;
+  }
+}
+
+SVGShapeData.prototype.setAsAnimated = function () {
+  this._isAnimated = true;
+};
+
+function SVGStyleData(data, level) {
+  this.data = data;
+  this.type = data.ty;
+  this.d = '';
+  this.lvl = level;
+  this._mdf = false;
+  this.closed = data.hd === true;
+  this.pElem = createNS('path');
+  this.msElem = null;
+}
+
+SVGStyleData.prototype.reset = function () {
+  this.d = '';
+  this._mdf = false;
+};
+
+function DashProperty(elem, data, renderer, container) {
+  this.elem = elem;
+  this.frameId = -1;
+  this.dataProps = createSizedArray(data.length);
+  this.renderer = renderer;
+  this.k = false;
+  this.dashStr = '';
+  this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0);
+  this.dashoffset = createTypedArray('float32', 1);
+  this.initDynamicPropertyContainer(container);
+  var i;
+  var len = data.length || 0;
+  var prop;
+  for (i = 0; i < len; i += 1) {
+    prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
+    this.k = prop.k || this.k;
+    this.dataProps[i] = { n: data[i].n, p: prop };
+  }
+  if (!this.k) {
+    this.getValue(true);
+  }
+  this._isAnimated = this.k;
+}
+
+DashProperty.prototype.getValue = function (forceRender) {
+  if (this.elem.globalData.frameId === this.frameId && !forceRender) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+  this._mdf = this._mdf || forceRender;
+  if (this._mdf) {
+    var i = 0;
+    var len = this.dataProps.length;
+    if (this.renderer === 'svg') {
+      this.dashStr = '';
+    }
+    for (i = 0; i < len; i += 1) {
+      if (this.dataProps[i].n !== 'o') {
+        if (this.renderer === 'svg') {
+          this.dashStr += ' ' + this.dataProps[i].p.v;
+        } else {
+          this.dashArray[i] = this.dataProps[i].p.v;
+        }
+      } else {
+        this.dashoffset[0] = this.dataProps[i].p.v;
+      }
+    }
+  }
+};
+extendPrototype([DynamicPropertyContainer], DashProperty);
+
+function SVGStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
+
+function SVGFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
+
+function SVGNoStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
+
+function GradientProperty(elem, data, container) {
+  this.data = data;
+  this.c = createTypedArray('uint8c', data.p * 4);
+  var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p * 4) : data.k.k.length - data.p * 4;
+  this.o = createTypedArray('float32', cLength);
+  this._cmdf = false;
+  this._omdf = false;
+  this._collapsable = this.checkCollapsable();
+  this._hasOpacity = cLength;
+  this.initDynamicPropertyContainer(container);
+  this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this);
+  this.k = this.prop.k;
+  this.getValue(true);
+}
+
+GradientProperty.prototype.comparePoints = function (values, points) {
+  var i = 0;
+  var len = this.o.length / 2;
+  var diff;
+  while (i < len) {
+    diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
+    if (diff > 0.01) {
+      return false;
+    }
+    i += 1;
+  }
+  return true;
+};
+
+GradientProperty.prototype.checkCollapsable = function () {
+  if (this.o.length / 2 !== this.c.length / 4) {
+    return false;
+  }
+  if (this.data.k.k[0].s) {
+    var i = 0;
+    var len = this.data.k.k.length;
+    while (i < len) {
+      if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
+        return false;
+      }
+      i += 1;
+    }
+  } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
+    return false;
+  }
+  return true;
+};
+
+GradientProperty.prototype.getValue = function (forceRender) {
+  this.prop.getValue();
+  this._mdf = false;
+  this._cmdf = false;
+  this._omdf = false;
+  if (this.prop._mdf || forceRender) {
+    var i;
+    var len = this.data.p * 4;
+    var mult;
+    var val;
+    for (i = 0; i < len; i += 1) {
+      mult = i % 4 === 0 ? 100 : 255;
+      val = Math.round(this.prop.v[i] * mult);
+      if (this.c[i] !== val) {
+        this.c[i] = val;
+        this._cmdf = !forceRender;
+      }
+    }
+    if (this.o.length) {
+      len = this.prop.v.length;
+      for (i = this.data.p * 4; i < len; i += 1) {
+        mult = i % 2 === 0 ? 100 : 1;
+        val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
+        if (this.o[i - this.data.p * 4] !== val) {
+          this.o[i - this.data.p * 4] = val;
+          this._omdf = !forceRender;
+        }
+      }
+    }
+    this._mdf = !forceRender;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], GradientProperty);
+
+function SVGGradientFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.initGradientData(elem, data, styleOb);
+}
+
+SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 1, null, this);
+  this.h = PropertyFactory.getProp(elem, data.h || { k: 0 }, 0, 0.01, this);
+  this.a = PropertyFactory.getProp(elem, data.a || { k: 0 }, 0, degToRads, this);
+  this.g = new GradientProperty(elem, data.g, this);
+  this.style = styleOb;
+  this.stops = [];
+  this.setGradientData(styleOb.pElem, data);
+  this.setGradientOpacity(data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+};
+
+SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
+  var gradientId = createElementID();
+  var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+  gfill.setAttribute('id', gradientId);
+  gfill.setAttribute('spreadMethod', 'pad');
+  gfill.setAttribute('gradientUnits', 'userSpaceOnUse');
+  var stops = [];
+  var stop;
+  var j;
+  var jLen;
+  jLen = data.g.p * 4;
+  for (j = 0; j < jLen; j += 4) {
+    stop = createNS('stop');
+    gfill.appendChild(stop);
+    stops.push(stop);
+  }
+  pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
+  this.gf = gfill;
+  this.cst = stops;
+};
+
+SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
+  if (this.g._hasOpacity && !this.g._collapsable) {
+    var stop;
+    var j;
+    var jLen;
+    var mask = createNS('mask');
+    var maskElement = createNS('path');
+    mask.appendChild(maskElement);
+    var opacityId = createElementID();
+    var maskId = createElementID();
+    mask.setAttribute('id', maskId);
+    var opFill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+    opFill.setAttribute('id', opacityId);
+    opFill.setAttribute('spreadMethod', 'pad');
+    opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
+    jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
+    var stops = this.stops;
+    for (j = data.g.p * 4; j < jLen; j += 2) {
+      stop = createNS('stop');
+      stop.setAttribute('stop-color', 'rgb(255,255,255)');
+      opFill.appendChild(stop);
+      stops.push(stop);
+    }
+    maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
+    this.maskId = maskId;
+    styleOb.msElem = maskElement;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
+
+function SVGGradientStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.initGradientData(elem, data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
+
+function ShapeGroupData() {
+  this.it = [];
+  this.prevViewData = [];
+  this.gr = createNS('g');
+}
+
+function SVGTransformData(mProps, op, container) {
+  this.transform = {
+    mProps: mProps,
+    op: op,
+    container: container,
+  };
+  this.elements = [];
+  this._isAnimated = this.transform.mProps.dynamicProperties.length || this.transform.op.effectsSequence.length;
+}
+
+const buildShapeString = function (pathNodes, length, closed, mat) {
+  if (length === 0) {
+    return '';
+  }
+  var _o = pathNodes.o;
+  var _i = pathNodes.i;
+  var _v = pathNodes.v;
+  var i;
+  var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+  for (i = 1; i < length; i += 1) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
+  }
+  if (closed && length) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+    shapeString += 'z';
+  }
+  return shapeString;
+};
+
+const SVGElementsRenderer = (function () {
+  var _identityMatrix = new Matrix();
+  var _matrixHelper = new Matrix();
+
+  var ob = {
+    createRenderFunction: createRenderFunction,
+  };
+
+  function createRenderFunction(data) {
+    switch (data.ty) {
+      case 'fl':
+        return renderFill;
+      case 'gf':
+        return renderGradient;
+      case 'gs':
+        return renderGradientStroke;
+      case 'st':
+        return renderStroke;
+      case 'sh':
+      case 'el':
+      case 'rc':
+      case 'sr':
+        return renderPath;
+      case 'tr':
+        return renderContentTransform;
+      case 'no':
+        return renderNoop;
+      default:
+        return null;
+    }
+  }
+
+  function renderContentTransform(styleData, itemData, isFirstFrame) {
+    if (isFirstFrame || itemData.transform.op._mdf) {
+      itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
+    }
+    if (isFirstFrame || itemData.transform.mProps._mdf) {
+      itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
+    }
+  }
+
+  function renderNoop() {
+
+  }
+
+  function renderPath(styleData, itemData, isFirstFrame) {
+    var j;
+    var jLen;
+    var pathStringTransformed;
+    var redraw;
+    var pathNodes;
+    var l;
+    var lLen = itemData.styles.length;
+    var lvl = itemData.lvl;
+    var paths;
+    var mat;
+    var iterations;
+    var k;
+    for (l = 0; l < lLen; l += 1) {
+      redraw = itemData.sh._mdf || isFirstFrame;
+      if (itemData.styles[l].lvl < lvl) {
+        mat = _matrixHelper.reset();
+        iterations = lvl - itemData.styles[l].lvl;
+        k = itemData.transformers.length - 1;
+        while (!redraw && iterations > 0) {
+          redraw = itemData.transformers[k].mProps._mdf || redraw;
+          iterations -= 1;
+          k -= 1;
+        }
+        if (redraw) {
+          iterations = lvl - itemData.styles[l].lvl;
+          k = itemData.transformers.length - 1;
+          while (iterations > 0) {
+            mat.multiply(itemData.transformers[k].mProps.v);
+            iterations -= 1;
+            k -= 1;
+          }
+        }
+      } else {
+        mat = _identityMatrix;
+      }
+      paths = itemData.sh.paths;
+      jLen = paths._length;
+      if (redraw) {
+        pathStringTransformed = '';
+        for (j = 0; j < jLen; j += 1) {
+          pathNodes = paths.shapes[j];
+          if (pathNodes && pathNodes._length) {
+            pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
+          }
+        }
+        itemData.caches[l] = pathStringTransformed;
+      } else {
+        pathStringTransformed = itemData.caches[l];
+      }
+      itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
+      itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
+    }
+  }
+
+  function renderFill(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+
+    if (itemData.c._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
+    }
+  }
+
+  function renderGradientStroke(styleData, itemData, isFirstFrame) {
+    renderGradient(styleData, itemData, isFirstFrame);
+    renderStroke(styleData, itemData, isFirstFrame);
+  }
+
+  function renderGradient(styleData, itemData, isFirstFrame) {
+    var gfill = itemData.gf;
+    var hasOpacity = itemData.g._hasOpacity;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+
+    if (itemData.o._mdf || isFirstFrame) {
+      var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
+      itemData.style.pElem.setAttribute(attr, itemData.o.v);
+    }
+    if (itemData.s._mdf || isFirstFrame) {
+      var attr1 = styleData.t === 1 ? 'x1' : 'cx';
+      var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
+      gfill.setAttribute(attr1, pt1[0]);
+      gfill.setAttribute(attr2, pt1[1]);
+      if (hasOpacity && !itemData.g._collapsable) {
+        itemData.of.setAttribute(attr1, pt1[0]);
+        itemData.of.setAttribute(attr2, pt1[1]);
+      }
+    }
+    var stops;
+    var i;
+    var len;
+    var stop;
+    if (itemData.g._cmdf || isFirstFrame) {
+      stops = itemData.cst;
+      var cValues = itemData.g.c;
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        stop.setAttribute('offset', cValues[i * 4] + '%');
+        stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
+      }
+    }
+    if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
+      var oValues = itemData.g.o;
+      if (itemData.g._collapsable) {
+        stops = itemData.cst;
+      } else {
+        stops = itemData.ost;
+      }
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        if (!itemData.g._collapsable) {
+          stop.setAttribute('offset', oValues[i * 2] + '%');
+        }
+        stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
+      }
+    }
+    if (styleData.t === 1) {
+      if (itemData.e._mdf || isFirstFrame) {
+        gfill.setAttribute('x2', pt2[0]);
+        gfill.setAttribute('y2', pt2[1]);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('x2', pt2[0]);
+          itemData.of.setAttribute('y2', pt2[1]);
+        }
+      }
+    } else {
+      var rad;
+      if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
+        rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        gfill.setAttribute('r', rad);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('r', rad);
+        }
+      }
+      if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (!rad) {
+          rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        }
+        var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+        var percent = itemData.h.v;
+        if (percent >= 1) {
+          percent = 0.99;
+        } else if (percent <= -1) {
+          percent = -0.99;
+        }
+        var dist = rad * percent;
+        var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+        var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+        gfill.setAttribute('fx', x);
+        gfill.setAttribute('fy', y);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('fx', x);
+          itemData.of.setAttribute('fy', y);
+        }
+      }
+      // gfill.setAttribute('fy','200');
+    }
+  }
+
+  function renderStroke(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+    var d = itemData.d;
+    if (d && (d._mdf || isFirstFrame) && d.dashStr) {
+      styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
+      styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
+    }
+    if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
+      styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
+    }
+    if (itemData.w._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
+      if (styleElem.msElem) {
+        styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
+      }
+    }
+  }
+
+  return ob;
+}());
+
+function SVGShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
+
+SVGShapeElement.prototype.initSecondaryElement = function () {
+};
+
+SVGShapeElement.prototype.identityMatrix = new Matrix();
+
+SVGShapeElement.prototype.buildExpressionInterface = function () {};
+
+SVGShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+};
+
+/*
+This method searches for multiple shapes that affect a single element and one of them is animated
+*/
+SVGShapeElement.prototype.filterUniqueShapes = function () {
+  var i;
+  var len = this.shapes.length;
+  var shape;
+  var j;
+  var jLen = this.stylesList.length;
+  var style;
+  var tempShapes = [];
+  var areAnimated = false;
+  for (j = 0; j < jLen; j += 1) {
+    style = this.stylesList[j];
+    areAnimated = false;
+    tempShapes.length = 0;
+    for (i = 0; i < len; i += 1) {
+      shape = this.shapes[i];
+      if (shape.styles.indexOf(style) !== -1) {
+        tempShapes.push(shape);
+        areAnimated = shape._isAnimated || areAnimated;
+      }
+    }
+    if (tempShapes.length > 1 && areAnimated) {
+      this.setShapesAsAnimated(tempShapes);
+    }
+  }
+};
+
+SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
+  var i;
+  var len = shapes.length;
+  for (i = 0; i < len; i += 1) {
+    shapes[i].setAsAnimated();
+  }
+};
+
+SVGShapeElement.prototype.createStyleElement = function (data, level) {
+  // TODO: prevent drawing of hidden styles
+  var elementData;
+  var styleOb = new SVGStyleData(data, level);
+
+  var pathElement = styleOb.pElem;
+  if (data.ty === 'st') {
+    elementData = new SVGStrokeStyleData(this, data, styleOb);
+  } else if (data.ty === 'fl') {
+    elementData = new SVGFillStyleData(this, data, styleOb);
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
+    elementData = new GradientConstructor(this, data, styleOb);
+    this.globalData.defs.appendChild(elementData.gf);
+    if (elementData.maskId) {
+      this.globalData.defs.appendChild(elementData.ms);
+      this.globalData.defs.appendChild(elementData.of);
+      pathElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + elementData.maskId + ')');
+    }
+  } else if (data.ty === 'no') {
+    elementData = new SVGNoStyleData(this, data, styleOb);
+  }
+
+  if (data.ty === 'st' || data.ty === 'gs') {
+    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);
+    }
+  }
+
+  if (data.r === 2) {
+    pathElement.setAttribute('fill-rule', 'evenodd');
+  }
+
+  if (data.ln) {
+    pathElement.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    pathElement.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  this.stylesList.push(styleOb);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createGroupElement = function (data) {
+  var elementData = new ShapeGroupData();
+  if (data.ln) {
+    elementData.gr.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    elementData.gr.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  return elementData;
+};
+
+SVGShapeElement.prototype.createTransformElement = function (data, container) {
+  var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
+  var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
+  var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
+  var i = 0;
+  var len = this.animatedContents.length;
+  while (i < len) {
+    if (this.animatedContents[i].element === element) {
+      return;
+    }
+    i += 1;
+  }
+  this.animatedContents.push({
+    fn: SVGElementsRenderer.createRenderFunction(data),
+    element: element,
+    data: data,
+  });
+};
+
+SVGShapeElement.prototype.setElementStyles = function (elementData) {
+  var arr = elementData.styles;
+  var j;
+  var jLen = this.stylesList.length;
+  for (j = 0; j < jLen; j += 1) {
+    if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
+      arr.push(this.stylesList[j]);
+    }
+  }
+};
+
+SVGShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+};
+
+SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
+  var ownTransformers = [].concat(transformers);
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var currentTransform;
+  var modifier;
+  var processedPos;
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._render = render;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], level);
+      } else {
+        itemsData[i].style.closed = arr[i].hd;
+      }
+      if (arr[i]._render) {
+        if (itemsData[i].style.pElem.parentNode !== container) {
+          container.appendChild(itemsData[i].style.pElem);
+        }
+      }
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
+      if (arr[i]._render) {
+        if (itemsData[i].gr.parentNode !== container) {
+          container.appendChild(itemsData[i].gr);
+        }
+      }
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        itemsData[i] = this.createTransformElement(arr[i], container);
+      }
+      currentTransform = itemsData[i].transform;
+      ownTransformers.push(currentTransform);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
+      }
+      this.setElementStyles(itemsData[i]);
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        render = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  len = ownStyles.length;
+  for (i = 0; i < len; i += 1) {
+    ownStyles[i].closed = true;
+  }
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+SVGShapeElement.prototype.renderInnerContent = function () {
+  this.renderModifiers();
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    this.stylesList[i].reset();
+  }
+  this.renderShape();
+  for (i = 0; i < len; i += 1) {
+    if (this.stylesList[i]._mdf || this._isFirstFrame) {
+      if (this.stylesList[i].msElem) {
+        this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+        // Adding M0 0 fixes same mask bug on all browsers
+        this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
+      }
+      this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
+    }
+  }
+};
+
+SVGShapeElement.prototype.renderShape = function () {
+  var i;
+  var len = this.animatedContents.length;
+  var animatedContent;
+  for (i = 0; i < len; i += 1) {
+    animatedContent = this.animatedContents[i];
+    if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
+      animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
+    }
+  }
+};
+
+SVGShapeElement.prototype.destroy = function () {
+  this.destroyBaseElement();
+  this.shapesData = null;
+  this.itemsData = null;
+};
+
+function LetterProps(o, sw, sc, fc, m, p) {
+  this.o = o;
+  this.sw = sw;
+  this.sc = sc;
+  this.fc = fc;
+  this.m = m;
+  this.p = p;
+  this._mdf = {
+    o: true,
+    sw: !!sw,
+    sc: !!sc,
+    fc: !!fc,
+    m: true,
+    p: true,
+  };
+}
+
+LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
+  this._mdf.o = false;
+  this._mdf.sw = false;
+  this._mdf.sc = false;
+  this._mdf.fc = false;
+  this._mdf.m = false;
+  this._mdf.p = false;
+  var updated = false;
+
+  if (this.o !== o) {
+    this.o = o;
+    this._mdf.o = true;
+    updated = true;
+  }
+  if (this.sw !== sw) {
+    this.sw = sw;
+    this._mdf.sw = true;
+    updated = true;
+  }
+  if (this.sc !== sc) {
+    this.sc = sc;
+    this._mdf.sc = true;
+    updated = true;
+  }
+  if (this.fc !== fc) {
+    this.fc = fc;
+    this._mdf.fc = true;
+    updated = true;
+  }
+  if (this.m !== m) {
+    this.m = m;
+    this._mdf.m = true;
+    updated = true;
+  }
+  if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
+    this.p = p;
+    this._mdf.p = true;
+    updated = true;
+  }
+  return updated;
+};
+
+function TextProperty(elem, data) {
+  this._frameId = initialDefaultFrame;
+  this.pv = '';
+  this.v = '';
+  this.kf = false;
+  this._isFirstFrame = true;
+  this._mdf = false;
+  if (data.d && data.d.sid) {
+    data.d = elem.globalData.slotManager.getProp(data.d);
+  }
+  this.data = data;
+  this.elem = elem;
+  this.comp = this.elem.comp;
+  this.keysIndex = 0;
+  this.canResize = false;
+  this.minimumFontSize = 1;
+  this.effectsSequence = [];
+  this.currentData = {
+    ascent: 0,
+    boxWidth: this.defaultBoxWidth,
+    f: '',
+    fStyle: '',
+    fWeight: '',
+    fc: '',
+    j: '',
+    justifyOffset: '',
+    l: [],
+    lh: 0,
+    lineWidths: [],
+    ls: '',
+    of: '',
+    s: '',
+    sc: '',
+    sw: 0,
+    t: 0,
+    tr: 0,
+    sz: 0,
+    ps: null,
+    fillColorAnim: false,
+    strokeColorAnim: false,
+    strokeWidthAnim: false,
+    yOffset: 0,
+    finalSize: 0,
+    finalText: [],
+    finalLineHeight: 0,
+    __complete: false,
+
+  };
+  this.copyData(this.currentData, this.data.d.k[0].s);
+
+  if (!this.searchProperty()) {
+    this.completeTextData(this.currentData);
+  }
+}
+
+TextProperty.prototype.defaultBoxWidth = [0, 0];
+
+TextProperty.prototype.copyData = function (obj, data) {
+  for (var s in data) {
+    if (Object.prototype.hasOwnProperty.call(data, s)) {
+      obj[s] = data[s];
+    }
+  }
+  return obj;
+};
+
+TextProperty.prototype.setCurrentData = function (data) {
+  if (!data.__complete) {
+    this.completeTextData(data);
+  }
+  this.currentData = data;
+  this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
+  this._mdf = true;
+};
+
+TextProperty.prototype.searchProperty = function () {
+  return this.searchKeyframes();
+};
+
+TextProperty.prototype.searchKeyframes = function () {
+  this.kf = this.data.d.k.length > 1;
+  if (this.kf) {
+    this.addEffect(this.getKeyframeValue.bind(this));
+  }
+  return this.kf;
+};
+
+TextProperty.prototype.addEffect = function (effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.getValue = function (_finalValue) {
+  if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
+    return;
+  }
+  this.currentData.t = this.data.d.k[this.keysIndex].s.t;
+  var currentValue = this.currentData;
+  var currentIndex = this.keysIndex;
+  if (this.lock) {
+    this.setCurrentData(this.currentData);
+    return;
+  }
+  this.lock = true;
+  this._mdf = false;
+  var i; var
+    len = this.effectsSequence.length;
+  var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
+  for (i = 0; i < len; i += 1) {
+    // Checking if index changed to prevent creating a new object every time the expression updates.
+    if (currentIndex !== this.keysIndex) {
+      finalValue = this.effectsSequence[i](finalValue, finalValue.t);
+    } else {
+      finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
+    }
+  }
+  if (currentValue !== finalValue) {
+    this.setCurrentData(finalValue);
+  }
+  this.v = this.currentData;
+  this.pv = this.v;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+};
+
+TextProperty.prototype.getKeyframeValue = function () {
+  var textKeys = this.data.d.k;
+  var frameNum = this.elem.comp.renderedFrame;
+  var i = 0; var
+    len = textKeys.length;
+  while (i <= len - 1) {
+    if (i === len - 1 || textKeys[i + 1].t > frameNum) {
+      break;
+    }
+    i += 1;
+  }
+  if (this.keysIndex !== i) {
+    this.keysIndex = i;
+  }
+  return this.data.d.k[this.keysIndex].s;
+};
+
+TextProperty.prototype.buildFinalText = function (text) {
+  var charactersArray = [];
+  var i = 0;
+  var len = text.length;
+  var charCode;
+  var secondCharCode;
+  var shouldCombine = false;
+  var shouldCombineNext = false;
+  var currentChars = '';
+  while (i < len) {
+    shouldCombine = shouldCombineNext;
+    shouldCombineNext = false;
+    charCode = text.charCodeAt(i);
+    currentChars = text.charAt(i);
+    if (FontManager.isCombinedCharacter(charCode)) {
+      shouldCombine = true;
+      // It's a potential surrogate pair (this is the High surrogate)
+    } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+      if (FontManager.isRegionalFlag(text, i)) {
+        currentChars = text.substr(i, 14);
+      } else {
+        secondCharCode = text.charCodeAt(i + 1);
+        // It's a surrogate pair (this is the Low surrogate)
+        if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
+          if (FontManager.isModifier(charCode, secondCharCode)) {
+            currentChars = text.substr(i, 2);
+            shouldCombine = true;
+          } else if (FontManager.isFlagEmoji(text.substr(i, 4))) {
+            currentChars = text.substr(i, 4);
+          } else {
+            currentChars = text.substr(i, 2);
+          }
+        }
+      }
+    } else if (charCode > 0xDBFF) {
+      secondCharCode = text.charCodeAt(i + 1);
+      if (FontManager.isVariationSelector(charCode)) {
+        shouldCombine = true;
+      }
+    } else if (FontManager.isZeroWidthJoiner(charCode)) {
+      shouldCombine = true;
+      shouldCombineNext = true;
+    }
+    if (shouldCombine) {
+      charactersArray[charactersArray.length - 1] += currentChars;
+      shouldCombine = false;
+    } else {
+      charactersArray.push(currentChars);
+    }
+    i += currentChars.length;
+  }
+  return charactersArray;
+};
+
+TextProperty.prototype.completeTextData = function (documentData) {
+  documentData.__complete = true;
+  var fontManager = this.elem.globalData.fontManager;
+  var data = this.data;
+  var letters = [];
+  var i; var
+    len;
+  var newLineFlag; var index = 0; var
+    val;
+  var anchorGrouping = data.m.g;
+  var currentSize = 0; var currentPos = 0; var currentLine = 0; var
+    lineWidths = [];
+  var lineWidth = 0;
+  var maxLineWidth = 0;
+  var j; var
+    jLen;
+  var fontData = fontManager.getFontByName(documentData.f);
+  var charData; var
+    cLength = 0;
+
+  var fontProps = getFontProperties(fontData);
+  documentData.fWeight = fontProps.weight;
+  documentData.fStyle = fontProps.style;
+  documentData.finalSize = documentData.s;
+  documentData.finalText = this.buildFinalText(documentData.t);
+  len = documentData.finalText.length;
+  documentData.finalLineHeight = documentData.lh;
+  var trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+  var charCode;
+  if (documentData.sz) {
+    var flag = true;
+    var boxWidth = documentData.sz[0];
+    var boxHeight = documentData.sz[1];
+    var currentHeight; var
+      finalText;
+    while (flag) {
+      finalText = this.buildFinalText(documentData.t);
+      currentHeight = 0;
+      lineWidth = 0;
+      len = finalText.length;
+      trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+      var lastSpaceIndex = -1;
+      for (i = 0; i < len; i += 1) {
+        charCode = finalText[i].charCodeAt(0);
+        newLineFlag = false;
+        if (finalText[i] === ' ') {
+          lastSpaceIndex = i;
+        } else if (charCode === 13 || charCode === 3) {
+          lineWidth = 0;
+          newLineFlag = true;
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+        }
+        if (fontManager.chars) {
+          charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
+          cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+        } else {
+          // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
+          cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
+        }
+        if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
+          if (lastSpaceIndex === -1) {
+            len += 1;
+          } else {
+            i = lastSpaceIndex;
+          }
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+          finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+          // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
+          lastSpaceIndex = -1;
+          lineWidth = 0;
+        } else {
+          lineWidth += cLength;
+          lineWidth += trackingOffset;
+        }
+      }
+      currentHeight += (fontData.ascent * documentData.finalSize) / 100;
+      if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
+        documentData.finalSize -= 1;
+        documentData.finalLineHeight = (documentData.finalSize * documentData.lh) / documentData.s;
+      } else {
+        documentData.finalText = finalText;
+        len = documentData.finalText.length;
+        flag = false;
+      }
+    }
+  }
+  lineWidth = -trackingOffset;
+  cLength = 0;
+  var uncollapsedSpaces = 0;
+  var currentChar;
+  for (i = 0; i < len; i += 1) {
+    newLineFlag = false;
+    currentChar = documentData.finalText[i];
+    charCode = currentChar.charCodeAt(0);
+    if (charCode === 13 || charCode === 3) {
+      uncollapsedSpaces = 0;
+      lineWidths.push(lineWidth);
+      maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+      lineWidth = -2 * trackingOffset;
+      val = '';
+      newLineFlag = true;
+      currentLine += 1;
+    } else {
+      val = currentChar;
+    }
+    if (fontManager.chars) {
+      charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
+      cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+    } else {
+      // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
+      // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
+      cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
+    }
+
+    //
+    if (currentChar === ' ') {
+      uncollapsedSpaces += cLength + trackingOffset;
+    } else {
+      lineWidth += cLength + trackingOffset + uncollapsedSpaces;
+      uncollapsedSpaces = 0;
+    }
+    letters.push({
+      l: cLength, an: cLength, add: currentSize, n: newLineFlag, anIndexes: [], val: val, line: currentLine, animatorJustifyOffset: 0,
+    });
+    if (anchorGrouping == 2) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || val === ' ' || i === len - 1) {
+        if (val === '' || val === ' ') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        index += 1;
+        currentSize = 0;
+      }
+    } else if (anchorGrouping == 3) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || i === len - 1) {
+        if (val === '') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        currentSize = 0;
+        index += 1;
+      }
+    } else {
+      letters[index].ind = index;
+      letters[index].extra = 0;
+      index += 1;
+    }
+  }
+  documentData.l = letters;
+  maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+  lineWidths.push(lineWidth);
+  if (documentData.sz) {
+    documentData.boxWidth = documentData.sz[0];
+    documentData.justifyOffset = 0;
+  } else {
+    documentData.boxWidth = maxLineWidth;
+    switch (documentData.j) {
+      case 1:
+        documentData.justifyOffset = -documentData.boxWidth;
+        break;
+      case 2:
+        documentData.justifyOffset = -documentData.boxWidth / 2;
+        break;
+      default:
+        documentData.justifyOffset = 0;
+    }
+  }
+  documentData.lineWidths = lineWidths;
+
+  var animators = data.a; var animatorData; var
+    letterData;
+  jLen = animators.length;
+  var based; var ind; var
+    indexes = [];
+  for (j = 0; j < jLen; j += 1) {
+    animatorData = animators[j];
+    if (animatorData.a.sc) {
+      documentData.strokeColorAnim = true;
+    }
+    if (animatorData.a.sw) {
+      documentData.strokeWidthAnim = true;
+    }
+    if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
+      documentData.fillColorAnim = true;
+    }
+    ind = 0;
+    based = animatorData.s.b;
+    for (i = 0; i < len; i += 1) {
+      letterData = letters[i];
+      letterData.anIndexes[j] = ind;
+      if ((based == 1 && letterData.val !== '') || (based == 2 && letterData.val !== '' && letterData.val !== ' ') || (based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1)) || (based == 4 && (letterData.n || i == len - 1))) { // eslint-disable-line eqeqeq
+        if (animatorData.s.rn === 1) {
+          indexes.push(ind);
+        }
+        ind += 1;
+      }
+    }
+    data.a[j].s.totalChars = ind;
+    var currentInd = -1; var
+      newInd;
+    if (animatorData.s.rn === 1) {
+      for (i = 0; i < len; i += 1) {
+        letterData = letters[i];
+        if (currentInd != letterData.anIndexes[j]) { // eslint-disable-line eqeqeq
+          currentInd = letterData.anIndexes[j];
+          newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
+        }
+        letterData.anIndexes[j] = newInd;
+      }
+    }
+  }
+  documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
+  documentData.ls = documentData.ls || 0;
+  documentData.ascent = (fontData.ascent * documentData.finalSize) / 100;
+};
+
+TextProperty.prototype.updateDocumentData = function (newData, index) {
+  index = index === undefined ? this.keysIndex : index;
+  var dData = this.copyData({}, this.data.d.k[index].s);
+  dData = this.copyData(dData, newData);
+  this.data.d.k[index].s = dData;
+  this.recalculate(index);
+  this.setCurrentData(dData);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.recalculate = function (index) {
+  var dData = this.data.d.k[index].s;
+  dData.__complete = false;
+  this.keysIndex = 0;
+  this._isFirstFrame = true;
+  this.getValue(dData);
+};
+
+TextProperty.prototype.canResizeFont = function (_canResize) {
+  this.canResize = _canResize;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
+  this.minimumFontSize = Math.floor(_fontValue) || 1;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+const TextSelectorProp = (function () {
+  var max = Math.max;
+  var min = Math.min;
+  var floor = Math.floor;
+
+  function TextSelectorPropFactory(elem, data) {
+    this._currentTextLength = -1;
+    this.k = false;
+    this.data = data;
+    this.elem = elem;
+    this.comp = elem.comp;
+    this.finalS = 0;
+    this.finalE = 0;
+    this.initDynamicPropertyContainer(elem);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: 0 }, 0, 0, this);
+    if ('e' in data) {
+      this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
+    } else {
+      this.e = { v: 100 };
+    }
+    this.o = PropertyFactory.getProp(elem, data.o || { k: 0 }, 0, 0, this);
+    this.xe = PropertyFactory.getProp(elem, data.xe || { k: 0 }, 0, 0, this);
+    this.ne = PropertyFactory.getProp(elem, data.ne || { k: 0 }, 0, 0, this);
+    this.sm = PropertyFactory.getProp(elem, data.sm || { k: 100 }, 0, 0, this);
+    this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
+    if (!this.dynamicProperties.length) {
+      this.getValue();
+    }
+  }
+
+  TextSelectorPropFactory.prototype = {
+    getMult: function (ind) {
+      if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
+        this.getValue();
+      }
+      var x1 = 0;
+      var y1 = 0;
+      var x2 = 1;
+      var y2 = 1;
+      if (this.ne.v > 0) {
+        x1 = this.ne.v / 100.0;
+      } else {
+        y1 = -this.ne.v / 100.0;
+      }
+      if (this.xe.v > 0) {
+        x2 = 1.0 - this.xe.v / 100.0;
+      } else {
+        y2 = 1.0 + this.xe.v / 100.0;
+      }
+      var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
+
+      var mult = 0;
+      var s = this.finalS;
+      var e = this.finalE;
+      var type = this.data.sh;
+      if (type === 2) {
+        if (e === s) {
+          mult = ind >= e ? 1 : 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+        mult = easer(mult);
+      } else if (type === 3) {
+        if (e === s) {
+          mult = ind >= e ? 0 : 1;
+        } else {
+          mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+
+        mult = easer(mult);
+      } else if (type === 4) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+          if (mult < 0.5) {
+            mult *= 2;
+          } else {
+            mult = 1 - 2 * (mult - 0.5);
+          }
+        }
+        mult = easer(mult);
+      } else if (type === 5) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          var tot = e - s;
+          /* ind += 0.5;
+                    mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          var x = -tot / 2 + ind;
+          var a = tot / 2;
+          mult = Math.sqrt(1 - (x * x) / (a * a));
+        }
+        mult = easer(mult);
+      } else if (type === 6) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; // eslint-disable-line
+        }
+        mult = easer(mult);
+      } else {
+        if (ind >= floor(s)) {
+          if (ind - s < 0) {
+            mult = max(0, min(min(e, 1) - (s - ind), 1));
+          } else {
+            mult = max(0, min(e - ind, 1));
+          }
+        }
+        mult = easer(mult);
+      }
+      // Smoothness implementation.
+      // The smoothness represents a reduced range of the original [0; 1] range.
+      // if smoothness is 25%, the new range will be [0.375; 0.625]
+      // Steps are:
+      // - find the lower value of the new range (threshold)
+      // - if multiplier is smaller than that value, floor it to 0
+      // - if it is larger,
+      //     - subtract the threshold
+      //     - divide it by the smoothness (this will return the range to [0; 1])
+      // Note: If it doesn't work on some scenarios, consider applying it before the easer.
+      if (this.sm.v !== 100) {
+        var smoothness = this.sm.v * 0.01;
+        if (smoothness === 0) {
+          smoothness = 0.00000001;
+        }
+        var threshold = 0.5 - smoothness * 0.5;
+        if (mult < threshold) {
+          mult = 0;
+        } else {
+          mult = (mult - threshold) / smoothness;
+          if (mult > 1) {
+            mult = 1;
+          }
+        }
+      }
+      return mult * this.a.v;
+    },
+    getValue: function (newCharsFlag) {
+      this.iterateDynamicProperties();
+      this._mdf = newCharsFlag || this._mdf;
+      this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
+      if (newCharsFlag && this.data.r === 2) {
+        this.e.v = this._currentTextLength;
+      }
+      var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
+      var o = this.o.v / divisor;
+      var s = this.s.v / divisor + o;
+      var e = (this.e.v / divisor) + o;
+      if (s > e) {
+        var _s = s;
+        s = e;
+        e = _s;
+      }
+      this.finalS = s;
+      this.finalE = e;
+    },
+  };
+  extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
+
+  function getTextSelectorProp(elem, data, arr) {
+    return new TextSelectorPropFactory(elem, data, arr);
+  }
+
+  return {
+    getTextSelectorProp: getTextSelectorProp,
+  };
+}());
+
+function TextAnimatorDataProperty(elem, animatorProps, container) {
+  var defaultData = { propType: false };
+  var getProp = PropertyFactory.getProp;
+  var textAnimatorAnimatables = animatorProps.a;
+  this.a = {
+    r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData,
+    rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData,
+    ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData,
+    sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData,
+    sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData,
+    s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData,
+    a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData,
+    o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData,
+    p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData,
+    sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData,
+    sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData,
+    fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData,
+    fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData,
+    fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData,
+    fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData,
+    t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData,
+  };
+
+  this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container);
+  this.s.t = animatorProps.s.t;
+}
+
+function TextAnimatorProperty(textData, renderType, elem) {
+  this._isFirstFrame = true;
+  this._hasMaskedPath = false;
+  this._frameId = -1;
+  this._textData = textData;
+  this._renderType = renderType;
+  this._elem = elem;
+  this._animatorsData = createSizedArray(this._textData.a.length);
+  this._pathData = {};
+  this._moreOptions = {
+    alignment: {},
+  };
+  this.renderedLetters = [];
+  this.lettersChangedFlag = false;
+  this.initDynamicPropertyContainer(elem);
+}
+
+TextAnimatorProperty.prototype.searchProperties = function () {
+  var i;
+  var len = this._textData.a.length;
+  var animatorProps;
+  var getProp = PropertyFactory.getProp;
+  for (i = 0; i < len; i += 1) {
+    animatorProps = this._textData.a[i];
+    this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
+  }
+  if (this._textData.p && 'm' in this._textData.p) {
+    this._pathData = {
+      a: getProp(this._elem, this._textData.p.a, 0, 0, this),
+      f: getProp(this._elem, this._textData.p.f, 0, 0, this),
+      l: getProp(this._elem, this._textData.p.l, 0, 0, this),
+      r: getProp(this._elem, this._textData.p.r, 0, 0, this),
+      p: getProp(this._elem, this._textData.p.p, 0, 0, this),
+      m: this._elem.maskManager.getMaskProperty(this._textData.p.m),
+    };
+    this._hasMaskedPath = true;
+  } else {
+    this._hasMaskedPath = false;
+  }
+  this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
+};
+
+TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
+  this.lettersChangedFlag = lettersChangedFlag;
+  if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
+    return;
+  }
+  this._isFirstFrame = false;
+  var alignment = this._moreOptions.alignment.v;
+  var animators = this._animatorsData;
+  var textData = this._textData;
+  var matrixHelper = this.mHelper;
+  var renderType = this._renderType;
+  var renderedLettersCount = this.renderedLetters.length;
+  var xPos;
+  var yPos;
+  var i;
+  var len;
+  var letters = documentData.l;
+  var pathInfo;
+  var currentLength;
+  var currentPoint;
+  var segmentLength;
+  var flag;
+  var pointInd;
+  var segmentInd;
+  var prevPoint;
+  var points;
+  var segments;
+  var partialLength;
+  var totalLength;
+  var perc;
+  var tanAngle;
+  var mask;
+  if (this._hasMaskedPath) {
+    mask = this._pathData.m;
+    if (!this._pathData.n || this._pathData._mdf) {
+      var paths = mask.v;
+      if (this._pathData.r.v) {
+        paths = paths.reverse();
+      }
+      // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
+      pathInfo = {
+        tLength: 0,
+        segments: [],
+      };
+      len = paths._length - 1;
+      var bezierData;
+      totalLength = 0;
+      for (i = 0; i < len; i += 1) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[i + 1],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      i = len;
+      if (mask.v.c) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[0],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      this._pathData.pi = pathInfo;
+    }
+    pathInfo = this._pathData.pi;
+
+    currentLength = this._pathData.f.v;
+    segmentInd = 0;
+    pointInd = 1;
+    segmentLength = 0;
+    flag = true;
+    segments = pathInfo.segments;
+    if (currentLength < 0 && mask.v.c) {
+      if (pathInfo.tLength < Math.abs(currentLength)) {
+        currentLength = -Math.abs(currentLength) % pathInfo.tLength;
+      }
+      segmentInd = segments.length - 1;
+      points = segments[segmentInd].points;
+      pointInd = points.length - 1;
+      while (currentLength < 0) {
+        currentLength += points[pointInd].partialLength;
+        pointInd -= 1;
+        if (pointInd < 0) {
+          segmentInd -= 1;
+          points = segments[segmentInd].points;
+          pointInd = points.length - 1;
+        }
+      }
+    }
+    points = segments[segmentInd].points;
+    prevPoint = points[pointInd - 1];
+    currentPoint = points[pointInd];
+    partialLength = currentPoint.partialLength;
+  }
+
+  len = letters.length;
+  xPos = 0;
+  yPos = 0;
+  var yOff = documentData.finalSize * 1.2 * 0.714;
+  var firstLine = true;
+  var animatorProps;
+  var animatorSelector;
+  var j;
+  var jLen;
+  var letterValue;
+
+  jLen = animators.length;
+
+  var mult;
+  var ind = -1;
+  var offf;
+  var xPathPos;
+  var yPathPos;
+  var initPathPos = currentLength;
+  var initSegmentInd = segmentInd;
+  var initPointInd = pointInd;
+  var currentLine = -1;
+  var elemOpacity;
+  var sc;
+  var sw;
+  var fc;
+  var k;
+  var letterSw;
+  var letterSc;
+  var letterFc;
+  var letterM = '';
+  var letterP = this.defaultPropsArray;
+  var letterO;
+
+  //
+  if (documentData.j === 2 || documentData.j === 1) {
+    var animatorJustifyOffset = 0;
+    var animatorFirstCharOffset = 0;
+    var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
+    var lastIndex = 0;
+    var isNewLine = true;
+
+    for (i = 0; i < len; i += 1) {
+      if (letters[i].n) {
+        if (animatorJustifyOffset) {
+          animatorJustifyOffset += animatorFirstCharOffset;
+        }
+        while (lastIndex < i) {
+          letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+          lastIndex += 1;
+        }
+        animatorJustifyOffset = 0;
+        isNewLine = true;
+      } else {
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.t.propType) {
+            if (isNewLine && documentData.j === 2) {
+              animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
+            }
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
+            } else {
+              animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult;
+            }
+          }
+        }
+        isNewLine = false;
+      }
+    }
+    if (animatorJustifyOffset) {
+      animatorJustifyOffset += animatorFirstCharOffset;
+    }
+    while (lastIndex < i) {
+      letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+      lastIndex += 1;
+    }
+  }
+  //
+
+  for (i = 0; i < len; i += 1) {
+    matrixHelper.reset();
+    elemOpacity = 1;
+    if (letters[i].n) {
+      xPos = 0;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      currentLength = initPathPos;
+      firstLine = false;
+      if (this._hasMaskedPath) {
+        segmentInd = initSegmentInd;
+        pointInd = initPointInd;
+        points = segments[segmentInd].points;
+        prevPoint = points[pointInd - 1];
+        currentPoint = points[pointInd];
+        partialLength = currentPoint.partialLength;
+        segmentLength = 0;
+      }
+      letterM = '';
+      letterFc = '';
+      letterSw = '';
+      letterO = '';
+      letterP = this.defaultPropsArray;
+    } else {
+      if (this._hasMaskedPath) {
+        if (currentLine !== letters[i].line) {
+          switch (documentData.j) {
+            case 1:
+              currentLength += totalLength - documentData.lineWidths[letters[i].line];
+              break;
+            case 2:
+              currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
+              break;
+            default:
+              break;
+          }
+          currentLine = letters[i].line;
+        }
+        if (ind !== letters[i].ind) {
+          if (letters[ind]) {
+            currentLength += letters[ind].extra;
+          }
+          currentLength += letters[i].an / 2;
+          ind = letters[i].ind;
+        }
+        currentLength += (alignment[0] * letters[i].an) * 0.005;
+        var animatorOffset = 0;
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.p.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.p.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.p.v[0] * mult;
+            }
+          }
+          if (animatorProps.a.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.a.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.a.v[0] * mult;
+            }
+          }
+        }
+        flag = true;
+        // Force alignment only works with a single line for now
+        if (this._pathData.a.v) {
+          currentLength = letters[0].an * 0.5 + ((totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind) / (len - 1);
+          currentLength += this._pathData.f.v;
+        }
+        while (flag) {
+          if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
+            perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
+            xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
+            yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
+            matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, -(alignment[1] * yOff) * 0.01);
+            flag = false;
+          } else if (points) {
+            segmentLength += currentPoint.partialLength;
+            pointInd += 1;
+            if (pointInd >= points.length) {
+              pointInd = 0;
+              segmentInd += 1;
+              if (!segments[segmentInd]) {
+                if (mask.v.c) {
+                  pointInd = 0;
+                  segmentInd = 0;
+                  points = segments[segmentInd].points;
+                } else {
+                  segmentLength -= currentPoint.partialLength;
+                  points = null;
+                }
+              } else {
+                points = segments[segmentInd].points;
+              }
+            }
+            if (points) {
+              prevPoint = currentPoint;
+              currentPoint = points[pointInd];
+              partialLength = currentPoint.partialLength;
+            }
+          }
+        }
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+      } else {
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+
+        // Grouping alignment
+        matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, (-alignment[1] * yOff) * 0.01, 0);
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.t.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
+          if (xPos !== 0 || documentData.j !== 0) {
+            if (this._hasMaskedPath) {
+              if (mult.length) {
+                currentLength += animatorProps.t.v * mult[0];
+              } else {
+                currentLength += animatorProps.t.v * mult;
+              }
+            } else if (mult.length) {
+              xPos += animatorProps.t.v * mult[0];
+            } else {
+              xPos += animatorProps.t.v * mult;
+            }
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        sw = documentData.sw || 0;
+      }
+      if (documentData.strokeColorAnim) {
+        if (documentData.sc) {
+          sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
+        } else {
+          sc = [0, 0, 0];
+        }
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.a.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+
+          if (mult.length) {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.s.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (mult.length) {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult[0]), 1 + ((animatorProps.s.v[1] - 1) * mult[1]), 1);
+          } else {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult), 1 + ((animatorProps.s.v[1] - 1) * mult), 1);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        animatorSelector = animators[j].s;
+        mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+        if (animatorProps.sk.propType) {
+          if (mult.length) {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
+          } else {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
+          }
+        }
+        if (animatorProps.r.propType) {
+          if (mult.length) {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
+          } else {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult);
+          }
+        }
+        if (animatorProps.ry.propType) {
+          if (mult.length) {
+            matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
+          } else {
+            matrixHelper.rotateY(animatorProps.ry.v * mult);
+          }
+        }
+        if (animatorProps.rx.propType) {
+          if (mult.length) {
+            matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
+          } else {
+            matrixHelper.rotateX(animatorProps.rx.v * mult);
+          }
+        }
+        if (animatorProps.o.propType) {
+          if (mult.length) {
+            elemOpacity += ((animatorProps.o.v) * mult[0] - elemOpacity) * mult[0];
+          } else {
+            elemOpacity += ((animatorProps.o.v) * mult - elemOpacity) * mult;
+          }
+        }
+        if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
+          if (mult.length) {
+            sw += animatorProps.sw.v * mult[0];
+          } else {
+            sw += animatorProps.sw.v * mult;
+          }
+        }
+        if (documentData.strokeColorAnim && animatorProps.sc.propType) {
+          for (k = 0; k < 3; k += 1) {
+            if (mult.length) {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0];
+            } else {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult;
+            }
+          }
+        }
+        if (documentData.fillColorAnim && documentData.fc) {
+          if (animatorProps.fc.propType) {
+            for (k = 0; k < 3; k += 1) {
+              if (mult.length) {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0];
+              } else {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult;
+              }
+            }
+          }
+          if (animatorProps.fh.propType) {
+            if (mult.length) {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
+            } else {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult);
+            }
+          }
+          if (animatorProps.fs.propType) {
+            if (mult.length) {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
+            } else {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
+            }
+          }
+          if (animatorProps.fb.propType) {
+            if (mult.length) {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
+            } else {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult);
+            }
+          }
+        }
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+
+        if (animatorProps.p.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (this._hasMaskedPath) {
+            if (mult.length) {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
+            } else {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+            }
+          } else if (mult.length) {
+            matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        letterSw = sw < 0 ? 0 : sw;
+      }
+      if (documentData.strokeColorAnim) {
+        letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
+      }
+
+      if (this._hasMaskedPath) {
+        matrixHelper.translate(0, -documentData.ls);
+
+        matrixHelper.translate(0, (alignment[1] * yOff) * 0.01 + yPos, 0);
+        if (this._pathData.p.v) {
+          tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
+          var rot = (Math.atan(tanAngle) * 180) / Math.PI;
+          if (currentPoint.point[0] < prevPoint.point[0]) {
+            rot += 180;
+          }
+          matrixHelper.rotate((-rot * Math.PI) / 180);
+        }
+        matrixHelper.translate(xPathPos, yPathPos, 0);
+        currentLength -= (alignment[0] * letters[i].an) * 0.005;
+        if (letters[i + 1] && ind !== letters[i + 1].ind) {
+          currentLength += letters[i].an / 2;
+          currentLength += (documentData.tr * 0.001) * documentData.finalSize;
+        }
+      } else {
+        matrixHelper.translate(xPos, yPos, 0);
+
+        if (documentData.ps) {
+          // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
+          matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+        }
+        switch (documentData.j) {
+          case 1:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
+            break;
+          case 2:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
+            break;
+          default:
+            break;
+        }
+        matrixHelper.translate(0, -documentData.ls);
+        matrixHelper.translate(offf, 0, 0);
+        matrixHelper.translate((alignment[0] * letters[i].an) * 0.005, (alignment[1] * yOff) * 0.01, 0);
+        xPos += letters[i].l + (documentData.tr * 0.001) * documentData.finalSize;
+      }
+      if (renderType === 'html') {
+        letterM = matrixHelper.toCSS();
+      } else if (renderType === 'svg') {
+        letterM = matrixHelper.to2dCSS();
+      } else {
+        letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
+      }
+      letterO = elemOpacity;
+    }
+
+    if (renderedLettersCount <= i) {
+      letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
+      this.renderedLetters.push(letterValue);
+      renderedLettersCount += 1;
+      this.lettersChangedFlag = true;
+    } else {
+      letterValue = this.renderedLetters[i];
+      this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag;
+    }
+  }
+};
+
+TextAnimatorProperty.prototype.getValue = function () {
+  if (this._elem.globalData.frameId === this._frameId) {
+    return;
+  }
+  this._frameId = this._elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+TextAnimatorProperty.prototype.mHelper = new Matrix();
+TextAnimatorProperty.prototype.defaultPropsArray = [];
+extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
+
+function ITextElement() {
+}
+
+ITextElement.prototype.initElement = function (data, globalData, comp) {
+  this.lettersChangedFlag = true;
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.textProperty = new TextProperty(this, data.t, this.dynamicProperties);
+  this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this);
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+  this.initRenderable();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  this.createContent();
+  this.hide();
+  this.textAnimator.searchProperties(this.dynamicProperties);
+};
+
+ITextElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+};
+
+ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
+  var j;
+  var jLen = shapes.length;
+  var pathNodes;
+  var shapeStr = '';
+  for (j = 0; j < jLen; j += 1) {
+    if (shapes[j].ty === 'sh') {
+      pathNodes = shapes[j].ks.k;
+      shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
+    }
+  }
+  return shapeStr;
+};
+
+ITextElement.prototype.updateDocumentData = function (newData, index) {
+  this.textProperty.updateDocumentData(newData, index);
+};
+
+ITextElement.prototype.canResizeFont = function (_canResize) {
+  this.textProperty.canResizeFont(_canResize);
+};
+
+ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
+  this.textProperty.setMinimumFontSize(_fontSize);
+};
+
+ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
+  if (documentData.ps) {
+    matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+  }
+  matrixHelper.translate(0, -documentData.ls, 0);
+  switch (documentData.j) {
+    case 1:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
+      break;
+    case 2:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
+      break;
+    default:
+      break;
+  }
+  matrixHelper.translate(xPos, yPos, 0);
+};
+
+ITextElement.prototype.buildColor = function (colorData) {
+  return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
+};
+
+ITextElement.prototype.emptyProp = new LetterProps();
+
+ITextElement.prototype.destroy = function () {
+
+};
+
+ITextElement.prototype.validateText = function () {
+  if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
+    this.buildNewText();
+    this.textProperty._isFirstFrame = false;
+    this.textProperty._mdf = false;
+  }
+};
+
+var emptyShapeData = {
+  shapes: [],
+};
+
+function SVGTextLottieElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.renderType = 'svg';
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
+
+SVGTextLottieElement.prototype.createContent = function () {
+  if (this.data.singleShape && !this.globalData.fontManager.chars) {
+    this.textContainer = createNS('text');
+  }
+};
+
+SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
+  var i = 0;
+  var len = textArray.length;
+  var textContents = [];
+  var currentTextContent = '';
+  while (i < len) {
+    if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
+      textContents.push(currentTextContent);
+      currentTextContent = '';
+    } else {
+      currentTextContent += textArray[i];
+    }
+    i += 1;
+  }
+  textContents.push(currentTextContent);
+  return textContents;
+};
+
+SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
+  // data should probably be cloned to apply scale separately to each instance of a text on different layers
+  // but since text internal content gets only rendered once and then it's never rerendered,
+  // it's probably safe not to clone data and reuse always the same instance even if the object is mutated.
+  // Avoiding cloning is preferred since cloning each character shape data is expensive
+  if (data.shapes && data.shapes.length) {
+    var shape = data.shapes[0];
+    if (shape.it) {
+      var shapeItem = shape.it[shape.it.length - 1];
+      if (shapeItem.s) {
+        shapeItem.s.k[0] = scale;
+        shapeItem.s.k[1] = scale;
+      }
+    }
+  }
+  return data;
+};
+
+SVGTextLottieElement.prototype.buildNewText = function () {
+  this.addDynamicProperty(this);
+  var i;
+  var len;
+
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
+  if (documentData.fc) {
+    this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
+  } else {
+    this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
+  }
+  if (documentData.sc) {
+    this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
+    this.layerElement.setAttribute('stroke-width', documentData.sw);
+  }
+  this.layerElement.setAttribute('font-size', documentData.finalSize);
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (fontData.fClass) {
+    this.layerElement.setAttribute('class', fontData.fClass);
+  } else {
+    this.layerElement.setAttribute('font-family', fontData.fFamily);
+    var fWeight = documentData.fWeight;
+    var fStyle = documentData.fStyle;
+    this.layerElement.setAttribute('font-style', fStyle);
+    this.layerElement.setAttribute('font-weight', fWeight);
+  }
+  this.layerElement.setAttribute('aria-label', documentData.t);
+
+  var letters = documentData.l || [];
+  var usesGlyphs = !!this.globalData.fontManager.chars;
+  len = letters.length;
+
+  var tSpan;
+  var matrixHelper = this.mHelper;
+  var shapeStr = '';
+  var singleShape = this.data.singleShape;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  if (singleShape && !usesGlyphs && !documentData.sz) {
+    var tElement = this.textContainer;
+    var justify = 'start';
+    switch (documentData.j) {
+      case 1:
+        justify = 'end';
+        break;
+      case 2:
+        justify = 'middle';
+        break;
+      default:
+        justify = 'start';
+        break;
+    }
+    tElement.setAttribute('text-anchor', justify);
+    tElement.setAttribute('letter-spacing', trackingOffset);
+    var textContent = this.buildTextContents(documentData.finalText);
+    len = textContent.length;
+    yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
+    for (i = 0; i < len; i += 1) {
+      tSpan = this.textSpans[i].span || createNS('tspan');
+      tSpan.textContent = textContent[i];
+      tSpan.setAttribute('x', 0);
+      tSpan.setAttribute('y', yPos);
+      tSpan.style.display = 'inherit';
+      tElement.appendChild(tSpan);
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          glyph: null,
+        };
+      }
+      this.textSpans[i].span = tSpan;
+      yPos += documentData.finalLineHeight;
+    }
+
+    this.layerElement.appendChild(tElement);
+  } else {
+    var cachedSpansLength = this.textSpans.length;
+    var charData;
+    for (i = 0; i < len; i += 1) {
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          childSpan: null,
+          glyph: null,
+        };
+      }
+      if (!usesGlyphs || !singleShape || i === 0) {
+        tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
+        if (cachedSpansLength <= i) {
+          tSpan.setAttribute('stroke-linecap', 'butt');
+          tSpan.setAttribute('stroke-linejoin', 'round');
+          tSpan.setAttribute('stroke-miterlimit', '4');
+          this.textSpans[i].span = tSpan;
+          if (usesGlyphs) {
+            var childSpan = createNS('g');
+            tSpan.appendChild(childSpan);
+            this.textSpans[i].childSpan = childSpan;
+          }
+          this.textSpans[i].span = tSpan;
+          this.layerElement.appendChild(tSpan);
+        }
+        tSpan.style.display = 'inherit';
+      }
+
+      matrixHelper.reset();
+      if (singleShape) {
+        if (letters[i].n) {
+          xPos = -trackingOffset;
+          yPos += documentData.yOffset;
+          yPos += firstLine ? 1 : 0;
+          firstLine = false;
+        }
+        this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+        xPos += letters[i].l || 0;
+        // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
+        xPos += trackingOffset;
+      }
+      if (usesGlyphs) {
+        charData = this.globalData.fontManager.getCharData(
+          documentData.finalText[i],
+          fontData.fStyle,
+          this.globalData.fontManager.getFontByName(documentData.f).fFamily
+        );
+        var glyphElement;
+        // t === 1 means the character has been replaced with an animated shaped
+        if (charData.t === 1) {
+          glyphElement = new SVGCompElement(charData.data, this.globalData, this);
+        } else {
+          var data = emptyShapeData;
+          if (charData.data && charData.data.shapes) {
+            data = this.buildShapeData(charData.data, documentData.finalSize);
+          }
+          glyphElement = new SVGShapeElement(data, this.globalData, this);
+        }
+        if (this.textSpans[i].glyph) {
+          var glyph = this.textSpans[i].glyph;
+          this.textSpans[i].childSpan.removeChild(glyph.layerElement);
+          glyph.destroy();
+        }
+        this.textSpans[i].glyph = glyphElement;
+        glyphElement._debug = true;
+        glyphElement.prepareFrame(0);
+        glyphElement.renderFrame();
+        this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+        // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+        // this might have issues with strokes and might need a different solution
+        if (charData.t === 1) {
+          this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
+        }
+      } else {
+        if (singleShape) {
+          tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
+        }
+        tSpan.textContent = letters[i].val;
+        tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      }
+      //
+    }
+    if (singleShape && tSpan) {
+      tSpan.setAttribute('d', shapeStr);
+    }
+  }
+  while (i < this.textSpans.length) {
+    this.textSpans[i].span.style.display = 'none';
+    i += 1;
+  }
+
+  this._sizeChanged = true;
+};
+
+SVGTextLottieElement.prototype.sourceRectAtTime = function () {
+  this.prepareFrame(this.comp.renderedFrame - this.data.st);
+  this.renderInnerContent();
+  if (this._sizeChanged) {
+    this._sizeChanged = false;
+    var textBox = this.layerElement.getBBox();
+    this.bbox = {
+      top: textBox.y,
+      left: textBox.x,
+      width: textBox.width,
+      height: textBox.height,
+    };
+  }
+  return this.bbox;
+};
+
+SVGTextLottieElement.prototype.getValue = function () {
+  var i;
+  var len = this.textSpans.length;
+  var glyphElement;
+  this.renderedFrame = this.comp.renderedFrame;
+  for (i = 0; i < len; i += 1) {
+    glyphElement = this.textSpans[i].glyph;
+    if (glyphElement) {
+      glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
+      if (glyphElement._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+SVGTextLottieElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  if (!this.data.singleShape || this._mdf) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+    if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
+      this._sizeChanged = true;
+      var i;
+      var len;
+      var renderedLetters = this.textAnimator.renderedLetters;
+
+      var letters = this.textProperty.currentData.l;
+
+      len = letters.length;
+      var renderedLetter;
+      var textSpan;
+      var glyphElement;
+      for (i = 0; i < len; i += 1) {
+        if (!letters[i].n) {
+          renderedLetter = renderedLetters[i];
+          textSpan = this.textSpans[i].span;
+          glyphElement = this.textSpans[i].glyph;
+          if (glyphElement) {
+            glyphElement.renderFrame();
+          }
+          if (renderedLetter._mdf.m) {
+            textSpan.setAttribute('transform', renderedLetter.m);
+          }
+          if (renderedLetter._mdf.o) {
+            textSpan.setAttribute('opacity', renderedLetter.o);
+          }
+          if (renderedLetter._mdf.sw) {
+            textSpan.setAttribute('stroke-width', renderedLetter.sw);
+          }
+          if (renderedLetter._mdf.sc) {
+            textSpan.setAttribute('stroke', renderedLetter.sc);
+          }
+          if (renderedLetter._mdf.fc) {
+            textSpan.setAttribute('fill', renderedLetter.fc);
+          }
+        }
+      }
+    }
+  }
+};
+
+function ISolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([IImageElement], ISolidElement);
+
+ISolidElement.prototype.createContent = function () {
+  var rect = createNS('rect');
+  /// /rect.style.width = this.data.sw;
+  /// /rect.style.height = this.data.sh;
+  /// /rect.style.fill = this.data.sc;
+  rect.setAttribute('width', this.data.sw);
+  rect.setAttribute('height', this.data.sh);
+  rect.setAttribute('fill', this.data.sc);
+  this.layerElement.appendChild(rect);
+};
+
+function NullElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initFrame();
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+}
+
+NullElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+NullElement.prototype.renderFrame = function () {
+};
+
+NullElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+NullElement.prototype.destroy = function () {
+};
+
+NullElement.prototype.sourceRectAtTime = function () {
+};
+
+NullElement.prototype.hide = function () {
+};
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
+
+function SVGRendererBase() {
+}
+
+extendPrototype([BaseRenderer], SVGRendererBase);
+
+SVGRendererBase.prototype.createNull = function (data) {
+  return new NullElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createShape = function (data) {
+  return new SVGShapeElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createText = function (data) {
+  return new SVGTextLottieElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createImage = function (data) {
+  return new IImageElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createSolid = function (data) {
+  return new ISolidElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.configAnimation = function (animData) {
+  this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+  this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+  if (this.renderConfig.viewBoxSize) {
+    this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
+  } else {
+    this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
+  }
+
+  if (!this.renderConfig.viewBoxOnly) {
+    this.svgElement.setAttribute('width', animData.w);
+    this.svgElement.setAttribute('height', animData.h);
+    this.svgElement.style.width = '100%';
+    this.svgElement.style.height = '100%';
+    this.svgElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
+  }
+  if (this.renderConfig.width) {
+    this.svgElement.setAttribute('width', this.renderConfig.width);
+  }
+  if (this.renderConfig.height) {
+    this.svgElement.setAttribute('height', this.renderConfig.height);
+  }
+  if (this.renderConfig.className) {
+    this.svgElement.setAttribute('class', this.renderConfig.className);
+  }
+  if (this.renderConfig.id) {
+    this.svgElement.setAttribute('id', this.renderConfig.id);
+  }
+  if (this.renderConfig.focusable !== undefined) {
+    this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
+  }
+  this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+  // this.layerElement.style.transform = 'translate3d(0,0,0)';
+  // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
+  this.animationItem.wrapper.appendChild(this.svgElement);
+  // Mask animation
+  var defs = this.globalData.defs;
+
+  this.setupGlobalData(animData, defs);
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.data = animData;
+
+  var maskElement = createNS('clipPath');
+  var rect = createNS('rect');
+  rect.setAttribute('width', animData.w);
+  rect.setAttribute('height', animData.h);
+  rect.setAttribute('x', 0);
+  rect.setAttribute('y', 0);
+  var maskId = createElementID();
+  maskElement.setAttribute('id', maskId);
+  maskElement.appendChild(rect);
+  this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')');
+
+  defs.appendChild(maskElement);
+  this.layers = animData.layers;
+  this.elements = createSizedArray(animData.layers.length);
+};
+
+SVGRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.layerElement = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+SVGRendererBase.prototype.updateContainerSize = function () {
+};
+
+SVGRendererBase.prototype.findIndexByInd = function (ind) {
+  var i = 0;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.layers[i].ind === ind) {
+      return i;
+    }
+  }
+  return -1;
+};
+
+SVGRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  elements[pos] = true;
+  var element = this.createItem(this.layers[pos]);
+
+  elements[pos] = element;
+  if (getExpressionsPlugin()) {
+    if (this.layers[pos].ty === 0) {
+      this.globalData.projectInterface.registerComposition(element);
+    }
+    element.initExpressions();
+  }
+  this.appendElementInPos(element, pos);
+  if (this.layers[pos].tt) {
+    var elementIndex = ('tp' in this.layers[pos])
+      ? this.findIndexByInd(this.layers[pos].tp)
+      : pos - 1;
+    if (elementIndex === -1) {
+      return;
+    }
+    if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
+      this.buildItem(elementIndex);
+      this.addPendingElement(element);
+    } else {
+      var matteElement = elements[elementIndex];
+      var matteMask = matteElement.getMatte(this.layers[pos].tt);
+      element.setMatte(matteMask);
+    }
+  }
+};
+
+SVGRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+    if (element.data.tt) {
+      var i = 0;
+      var len = this.elements.length;
+      while (i < len) {
+        if (this.elements[i] === element) {
+          var elementIndex = 'tp' in element.data
+            ? this.findIndexByInd(element.data.tp)
+            : i - 1;
+          var matteElement = this.elements[elementIndex];
+          var matteMask = matteElement.getMatte(this.layers[i].tt);
+          element.setMatte(matteMask);
+          break;
+        }
+        i += 1;
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.renderFrame = function (num) {
+  if (this.renderedFrame === num || this.destroyed) {
+    return;
+  }
+  if (num === null) {
+    num = this.renderedFrame;
+  } else {
+    this.renderedFrame = num;
+  }
+  // console.log('-------');
+  // console.log('FRAME ',num);
+  this.globalData.frameNum = num;
+  this.globalData.frameId += 1;
+  this.globalData.projectInterface.currentFrame = num;
+  this.globalData._mdf = false;
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    for (i = 0; i < len; i += 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
+  var newElement = element.getBaseElement();
+  if (!newElement) {
+    return;
+  }
+  var i = 0;
+  var nextElement;
+  while (i < pos) {
+    if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
+      nextElement = this.elements[i].getBaseElement();
+    }
+    i += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(newElement, nextElement);
+  } else {
+    this.layerElement.appendChild(newElement);
+  }
+};
+
+SVGRendererBase.prototype.hide = function () {
+  this.layerElement.style.display = 'none';
+};
+
+SVGRendererBase.prototype.show = function () {
+  this.layerElement.style.display = 'block';
+};
+
+function ICompElement() {}
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
+
+ICompElement.prototype.initElement = function (data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initTransform(data, globalData, comp);
+  this.initRenderable();
+  this.initHierarchy();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  if (this.data.xt || !globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+  this.hide();
+};
+
+/* ICompElement.prototype.hide = function(){
+    if(!this.hidden){
+        this.hideElement();
+        var i,len = this.elements.length;
+        for( i = 0; i < len; i+=1 ){
+            if(this.elements[i]){
+                this.elements[i].hide();
+            }
+        }
+    }
+}; */
+
+ICompElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+  if (!this.isInRange && !this.data.xt) {
+    return;
+  }
+
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    if (timeRemapped === this.data.op) {
+      timeRemapped = this.data.op - 1;
+    }
+    this.renderedFrame = timeRemapped;
+  } else {
+    this.renderedFrame = num / this.data.sr;
+  }
+  var i;
+  var len = this.elements.length;
+  if (!this.completeLayers) {
+    this.checkLayers(this.renderedFrame);
+  }
+  // This iteration needs to be backwards because of how expressions connect between each other
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
+      if (this.elements[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+ICompElement.prototype.renderInnerContent = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+ICompElement.prototype.setElements = function (elems) {
+  this.elements = elems;
+};
+
+ICompElement.prototype.getElements = function () {
+  return this.elements;
+};
+
+ICompElement.prototype.destroyElements = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+};
+
+ICompElement.prototype.destroy = function () {
+  this.destroyElements();
+  this.destroyBaseElement();
+};
+
+function SVGCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = true;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
+
+SVGCompElement.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function SVGRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.layers = null;
+  this.renderedFrame = -1;
+  this.svgElement = createNS('svg');
+  var ariaLabel = '';
+  if (config && config.title) {
+    var titleElement = createNS('title');
+    var titleId = createElementID();
+    titleElement.setAttribute('id', titleId);
+    titleElement.textContent = config.title;
+    this.svgElement.appendChild(titleElement);
+    ariaLabel += titleId;
+  }
+  if (config && config.description) {
+    var descElement = createNS('desc');
+    var descId = createElementID();
+    descElement.setAttribute('id', descId);
+    descElement.textContent = config.description;
+    this.svgElement.appendChild(descElement);
+    ariaLabel += ' ' + descId;
+  }
+  if (ariaLabel) {
+    this.svgElement.setAttribute('aria-labelledby', ariaLabel);
+  }
+  var defs = createNS('defs');
+  this.svgElement.appendChild(defs);
+  var maskElement = createNS('g');
+  this.svgElement.appendChild(maskElement);
+  this.layerElement = maskElement;
+  this.renderConfig = {
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    hideOnTransparent: !((config && config.hideOnTransparent === false)),
+    viewBoxOnly: (config && config.viewBoxOnly) || false,
+    viewBoxSize: (config && config.viewBoxSize) || false,
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    focusable: config && config.focusable,
+    filterSize: {
+      width: (config && config.filterSize && config.filterSize.width) || '100%',
+      height: (config && config.filterSize && config.filterSize.height) || '100%',
+      x: (config && config.filterSize && config.filterSize.x) || '0%',
+      y: (config && config.filterSize && config.filterSize.y) || '0%',
+    },
+    width: (config && config.width),
+    height: (config && config.height),
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+
+  this.globalData = {
+    _mdf: false,
+    frameNum: -1,
+    defs: defs,
+    renderConfig: this.renderConfig,
+  };
+  this.elements = [];
+  this.pendingElements = [];
+  this.destroyed = false;
+  this.rendererType = 'svg';
+}
+
+extendPrototype([SVGRendererBase], SVGRenderer);
+
+SVGRenderer.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+// Registering renderers
+registerRenderer('svg', SVGRenderer);
+
+// Registering shape modifiers
+ShapeModifiers.registerModifier('tm', TrimModifier);
+ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
+ShapeModifiers.registerModifier('rp', RepeaterModifier);
+ShapeModifiers.registerModifier('rd', RoundCornersModifier);
+ShapeModifiers.registerModifier('zz', ZigZagModifier);
+ShapeModifiers.registerModifier('op', OffsetPathModifier);
+
+exports["default"] = lottie;
diff --git a/build/player/cjs/lottie_light_canvas.min.js b/build/player/cjs/lottie_light_canvas.min.js
new file mode 100644
index 0000000..6cbdbd1
--- /dev/null
+++ b/build/player/cjs/lottie_light_canvas.min.js
@@ -0,0 +1,13449 @@
+'use strict';
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+const svgNS = 'http://www.w3.org/2000/svg';
+
+let locationHref = '';
+let _useWebWorker = false;
+
+const initialDefaultFrame = -999999;
+
+const setWebWorker = (flag) => { _useWebWorker = !!flag; };
+const getWebWorker = () => _useWebWorker;
+
+const setLocationHref = (value) => { locationHref = value; };
+const getLocationHref = () => locationHref;
+
+function createTag(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElement(type);
+}
+
+function extendPrototype(sources, destination) {
+  var i;
+  var len = sources.length;
+  var sourcePrototype;
+  for (i = 0; i < len; i += 1) {
+    sourcePrototype = sources[i].prototype;
+    for (var attr in sourcePrototype) {
+      if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
+    }
+  }
+}
+
+function getDescriptor(object, prop) {
+  return Object.getOwnPropertyDescriptor(object, prop);
+}
+
+function createProxyFunction(prototype) {
+  function ProxyFunction() {}
+  ProxyFunction.prototype = prototype;
+  return ProxyFunction;
+}
+
+// import Howl from '../../3rd_party/howler';
+
+const audioControllerFactory = (function () {
+  function AudioController(audioFactory) {
+    this.audios = [];
+    this.audioFactory = audioFactory;
+    this._volume = 1;
+    this._isMuted = false;
+  }
+
+  AudioController.prototype = {
+    addAudio: function (audio) {
+      this.audios.push(audio);
+    },
+    pause: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].pause();
+      }
+    },
+    resume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].resume();
+      }
+    },
+    setRate: function (rateValue) {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].setRate(rateValue);
+      }
+    },
+    createAudio: function (assetPath) {
+      if (this.audioFactory) {
+        return this.audioFactory(assetPath);
+      } if (window.Howl) {
+        return new window.Howl({
+          src: [assetPath],
+        });
+      }
+      return {
+        isPlaying: false,
+        play: function () { this.isPlaying = true; },
+        seek: function () { this.isPlaying = false; },
+        playing: function () {},
+        rate: function () {},
+        setVolume: function () {},
+      };
+    },
+    setAudioFactory: function (audioFactory) {
+      this.audioFactory = audioFactory;
+    },
+    setVolume: function (value) {
+      this._volume = value;
+      this._updateVolume();
+    },
+    mute: function () {
+      this._isMuted = true;
+      this._updateVolume();
+    },
+    unmute: function () {
+      this._isMuted = false;
+      this._updateVolume();
+    },
+    getVolume: function () {
+      return this._volume;
+    },
+    _updateVolume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
+      }
+    },
+  };
+
+  return function () {
+    return new AudioController();
+  };
+}());
+
+const createTypedArray = (function () {
+  function createRegularArray(type, len) {
+    var i = 0;
+    var arr = [];
+    var value;
+    switch (type) {
+      case 'int16':
+      case 'uint8c':
+        value = 1;
+        break;
+      default:
+        value = 1.1;
+        break;
+    }
+    for (i = 0; i < len; i += 1) {
+      arr.push(value);
+    }
+    return arr;
+  }
+  function createTypedArrayFactory(type, len) {
+    if (type === 'float32') {
+      return new Float32Array(len);
+    } if (type === 'int16') {
+      return new Int16Array(len);
+    } if (type === 'uint8c') {
+      return new Uint8ClampedArray(len);
+    }
+    return createRegularArray(type, len);
+  }
+  if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
+    return createTypedArrayFactory;
+  }
+  return createRegularArray;
+}());
+
+function createSizedArray(len) {
+  return Array.apply(null, { length: len });
+}
+
+let subframeEnabled = true;
+let expressionsPlugin = null;
+let expressionsInterfaces = null;
+let idPrefix$1 = '';
+const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+let _shouldRoundValues = false;
+const bmPow = Math.pow;
+const bmSqrt = Math.sqrt;
+const bmFloor = Math.floor;
+const bmMax = Math.max;
+const bmMin = Math.min;
+
+const BMMath = {};
+(function () {
+  var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
+  var i;
+  var len = propertyNames.length;
+  for (i = 0; i < len; i += 1) {
+    BMMath[propertyNames[i]] = Math[propertyNames[i]];
+  }
+}());
+
+function ProjectInterface$1() { return {}; }
+BMMath.random = Math.random;
+BMMath.abs = function (val) {
+  var tOfVal = typeof val;
+  if (tOfVal === 'object' && val.length) {
+    var absArr = createSizedArray(val.length);
+    var i;
+    var len = val.length;
+    for (i = 0; i < len; i += 1) {
+      absArr[i] = Math.abs(val[i]);
+    }
+    return absArr;
+  }
+  return Math.abs(val);
+};
+let defaultCurveSegments = 150;
+const degToRads = Math.PI / 180;
+const roundCorner = 0.5519;
+
+function roundValues(flag) {
+  _shouldRoundValues = !!flag;
+}
+
+function bmRnd(value) {
+  if (_shouldRoundValues) {
+    return Math.round(value);
+  }
+  return value;
+}
+
+function styleDiv(element) {
+  element.style.position = 'absolute';
+  element.style.top = 0;
+  element.style.left = 0;
+  element.style.display = 'block';
+  element.style.transformOrigin = '0 0';
+  element.style.webkitTransformOrigin = '0 0';
+  element.style.backfaceVisibility = 'visible';
+  element.style.webkitBackfaceVisibility = 'visible';
+  element.style.transformStyle = 'preserve-3d';
+  element.style.webkitTransformStyle = 'preserve-3d';
+  element.style.mozTransformStyle = 'preserve-3d';
+}
+
+function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
+  this.type = type;
+  this.currentTime = currentTime;
+  this.totalTime = totalTime;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteEvent(type, frameMultiplier) {
+  this.type = type;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
+  this.type = type;
+  this.currentLoop = currentLoop;
+  this.totalLoops = totalLoops;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMSegmentStartEvent(type, firstFrame, totalFrames) {
+  this.type = type;
+  this.firstFrame = firstFrame;
+  this.totalFrames = totalFrames;
+}
+
+function BMDestroyEvent(type, target) {
+  this.type = type;
+  this.target = target;
+}
+
+function BMRenderFrameErrorEvent(nativeError, currentTime) {
+  this.type = 'renderFrameError';
+  this.nativeError = nativeError;
+  this.currentTime = currentTime;
+}
+
+function BMConfigErrorEvent(nativeError) {
+  this.type = 'configError';
+  this.nativeError = nativeError;
+}
+
+function BMAnimationConfigErrorEvent(type, nativeError) {
+  this.type = type;
+  this.nativeError = nativeError;
+}
+
+const createElementID = (function () {
+  var _count = 0;
+  return function createID() {
+    _count += 1;
+    return idPrefix$1 + '__lottie_element_' + _count;
+  };
+}());
+
+function HSVtoRGB(h, s, v) {
+  var r;
+  var g;
+  var b;
+  var i;
+  var f;
+  var p;
+  var q;
+  var t;
+  i = Math.floor(h * 6);
+  f = h * 6 - i;
+  p = v * (1 - s);
+  q = v * (1 - f * s);
+  t = v * (1 - (1 - f) * s);
+  switch (i % 6) {
+    case 0: r = v; g = t; b = p; break;
+    case 1: r = q; g = v; b = p; break;
+    case 2: r = p; g = v; b = t; break;
+    case 3: r = p; g = q; b = v; break;
+    case 4: r = t; g = p; b = v; break;
+    case 5: r = v; g = p; b = q; break;
+    default: break;
+  }
+  return [r,
+    g,
+    b];
+}
+
+function RGBtoHSV(r, g, b) {
+  var max = Math.max(r, g, b);
+  var min = Math.min(r, g, b);
+  var d = max - min;
+  var h;
+  var s = (max === 0 ? 0 : d / max);
+  var v = max / 255;
+
+  switch (max) {
+    case min: h = 0; break;
+    case r: h = (g - b) + d * (g < b ? 6 : 0); h /= 6 * d; break;
+    case g: h = (b - r) + d * 2; h /= 6 * d; break;
+    case b: h = (r - g) + d * 4; h /= 6 * d; break;
+    default: break;
+  }
+
+  return [
+    h,
+    s,
+    v,
+  ];
+}
+
+function addSaturationToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[1] += offset;
+  if (hsv[1] > 1) {
+    hsv[1] = 1;
+  } else if (hsv[1] <= 0) {
+    hsv[1] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addBrightnessToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[2] += offset;
+  if (hsv[2] > 1) {
+    hsv[2] = 1;
+  } else if (hsv[2] < 0) {
+    hsv[2] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addHueToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[0] += offset / 360;
+  if (hsv[0] > 1) {
+    hsv[0] -= 1;
+  } else if (hsv[0] < 0) {
+    hsv[0] += 1;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+const rgbToHex = (function () {
+  var colorMap = [];
+  var i;
+  var hex;
+  for (i = 0; i < 256; i += 1) {
+    hex = i.toString(16);
+    colorMap[i] = hex.length === 1 ? '0' + hex : hex;
+  }
+
+  return function (r, g, b) {
+    if (r < 0) {
+      r = 0;
+    }
+    if (g < 0) {
+      g = 0;
+    }
+    if (b < 0) {
+      b = 0;
+    }
+    return '#' + colorMap[r] + colorMap[g] + colorMap[b];
+  };
+}());
+
+const setSubframeEnabled = (flag) => { subframeEnabled = !!flag; };
+const getSubframeEnabled = () => subframeEnabled;
+const setExpressionsPlugin = (value) => { expressionsPlugin = value; };
+const getExpressionsPlugin = () => expressionsPlugin;
+const setExpressionInterfaces = (value) => { expressionsInterfaces = value; };
+const getExpressionInterfaces = () => expressionsInterfaces;
+const setDefaultCurveSegments = (value) => { defaultCurveSegments = value; };
+const getDefaultCurveSegments = () => defaultCurveSegments;
+const setIdPrefix = (value) => { idPrefix$1 = value; };
+const getIdPrefix = () => idPrefix$1;
+
+function createNS(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElementNS(svgNS, type);
+}
+
+const dataManager = (function () {
+  var _counterId = 1;
+  var processes = [];
+  var workerFn;
+  var workerInstance;
+  var workerProxy = {
+    onmessage: function () {
+
+    },
+    postMessage: function (path) {
+      workerFn({
+        data: path,
+      });
+    },
+  };
+  var _workerSelf = {
+    postMessage: function (data) {
+      workerProxy.onmessage({
+        data: data,
+      });
+    },
+  };
+  function createWorker(fn) {
+    if (window.Worker && window.Blob && getWebWorker()) {
+      var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      var url = URL.createObjectURL(blob);
+      return new Worker(url);
+    }
+    workerFn = fn;
+    return workerProxy;
+  }
+
+  function setupWorker() {
+    if (!workerInstance) {
+      workerInstance = createWorker(function workerStart(e) {
+        function dataFunctionManager() {
+          function completeLayers(layers, comps) {
+            var layerData;
+            var i;
+            var len = layers.length;
+            var j;
+            var jLen;
+            var k;
+            var kLen;
+            for (i = 0; i < len; i += 1) {
+              layerData = layers[i];
+              if (('ks' in layerData) && !layerData.completed) {
+                layerData.completed = true;
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      convertPathsToAbsoluteValues(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) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 0) {
+                  layerData.layers = findCompLayers(layerData.refId, comps);
+                  completeLayers(layerData.layers, comps);
+                } else if (layerData.ty === 4) {
+                  completeShapes(layerData.shapes);
+                } else if (layerData.ty === 5) {
+                  completeText(layerData);
+                }
+              }
+            }
+          }
+
+          function completeChars(chars, assets) {
+            if (chars) {
+              var i = 0;
+              var len = chars.length;
+              for (i = 0; i < len; i += 1) {
+                if (chars[i].t === 1) {
+                  // var compData = findComp(chars[i].data.refId, assets);
+                  chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                  // chars[i].data.ip = 0;
+                  // chars[i].data.op = 99999;
+                  // chars[i].data.st = 0;
+                  // chars[i].data.sr = 1;
+                  // chars[i].w = compData.w;
+                  // chars[i].data.ks = {
+                  //   a: { k: [0, 0, 0], a: 0 },
+                  //   p: { k: [0, -compData.h, 0], a: 0 },
+                  //   r: { k: 0, a: 0 },
+                  //   s: { k: [100, 100], a: 0 },
+                  //   o: { k: 100, a: 0 },
+                  // };
+                  completeLayers(chars[i].data.layers, assets);
+                }
+              }
+            }
+          }
+
+          function findComp(id, comps) {
+            var i = 0;
+            var len = comps.length;
+            while (i < len) {
+              if (comps[i].id === id) {
+                return comps[i];
+              }
+              i += 1;
+            }
+            return null;
+          }
+
+          function findCompLayers(id, comps) {
+            var comp = findComp(id, comps);
+            if (comp) {
+              if (!comp.layers.__used) {
+                comp.layers.__used = true;
+                return comp.layers;
+              }
+              return JSON.parse(JSON.stringify(comp.layers));
+            }
+            return null;
+          }
+
+          function completeShapes(arr) {
+            var i;
+            var len = arr.length;
+            var j;
+            var jLen;
+            for (i = len - 1; i >= 0; i -= 1) {
+              if (arr[i].ty === 'sh') {
+                if (arr[i].ks.k.i) {
+                  convertPathsToAbsoluteValues(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) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
+                    }
+                    if (arr[i].ks.k[j].e) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
+                    }
+                  }
+                }
+              } else if (arr[i].ty === 'gr') {
+                completeShapes(arr[i].it);
+              }
+            }
+          }
+
+          function convertPathsToAbsoluteValues(path) {
+            var i;
+            var len = path.i.length;
+            for (i = 0; i < len; i += 1) {
+              path.i[i][0] += path.v[i][0];
+              path.i[i][1] += path.v[i][1];
+              path.o[i][0] += path.v[i][0];
+              path.o[i][1] += path.v[i][1];
+            }
+          }
+
+          function checkVersion(minimum, animVersionString) {
+            var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
+            if (minimum[0] > animVersion[0]) {
+              return true;
+            } if (animVersion[0] > minimum[0]) {
+              return false;
+            }
+            if (minimum[1] > animVersion[1]) {
+              return true;
+            } if (animVersion[1] > minimum[1]) {
+              return false;
+            }
+            if (minimum[2] > animVersion[2]) {
+              return true;
+            } if (animVersion[2] > minimum[2]) {
+              return false;
+            }
+            return null;
+          }
+
+          var checkText = (function () {
+            var minimumVersion = [4, 4, 14];
+
+            function updateTextLayer(textLayer) {
+              var documentData = textLayer.t.d;
+              textLayer.t.d = {
+                k: [
+                  {
+                    s: documentData,
+                    t: 0,
+                  },
+                ],
+              };
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkChars = (function () {
+            var minimumVersion = [4, 7, 99];
+            return function (animationData) {
+              if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
+                var i;
+                var len = animationData.chars.length;
+                for (i = 0; i < len; i += 1) {
+                  var charData = animationData.chars[i];
+                  if (charData.data && charData.data.shapes) {
+                    completeShapes(charData.data.shapes);
+                    charData.data.ip = 0;
+                    charData.data.op = 99999;
+                    charData.data.st = 0;
+                    charData.data.sr = 1;
+                    charData.data.ks = {
+                      p: { k: [0, 0], a: 0 },
+                      s: { k: [100, 100], a: 0 },
+                      a: { k: [0, 0], a: 0 },
+                      r: { k: 0, a: 0 },
+                      o: { k: 100, a: 0 },
+                    };
+                    if (!animationData.chars[i].t) {
+                      charData.data.shapes.push(
+                        {
+                          ty: 'no',
+                        }
+                      );
+                      charData.data.shapes[0].it.push(
+                        {
+                          p: { k: [0, 0], a: 0 },
+                          s: { k: [100, 100], a: 0 },
+                          a: { k: [0, 0], a: 0 },
+                          r: { k: 0, a: 0 },
+                          o: { k: 100, a: 0 },
+                          sk: { k: 0, a: 0 },
+                          sa: { k: 0, a: 0 },
+                          ty: 'tr',
+                        }
+                      );
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkPathProperties = (function () {
+            var minimumVersion = [5, 7, 15];
+
+            function updateTextLayer(textLayer) {
+              var pathData = textLayer.t.p;
+              if (typeof pathData.a === 'number') {
+                pathData.a = {
+                  a: 0,
+                  k: pathData.a,
+                };
+              }
+              if (typeof pathData.p === 'number') {
+                pathData.p = {
+                  a: 0,
+                  k: pathData.p,
+                };
+              }
+              if (typeof pathData.r === 'number') {
+                pathData.r = {
+                  a: 0,
+                  k: pathData.r,
+                };
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkColors = (function () {
+            var minimumVersion = [4, 1, 9];
+
+            function iterateShapes(shapes) {
+              var i;
+              var len = shapes.length;
+              var j;
+              var jLen;
+              for (i = 0; i < len; i += 1) {
+                if (shapes[i].ty === 'gr') {
+                  iterateShapes(shapes[i].it);
+                } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
+                  if (shapes[i].c.k && shapes[i].c.k[0].i) {
+                    jLen = shapes[i].c.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (shapes[i].c.k[j].s) {
+                        shapes[i].c.k[j].s[0] /= 255;
+                        shapes[i].c.k[j].s[1] /= 255;
+                        shapes[i].c.k[j].s[2] /= 255;
+                        shapes[i].c.k[j].s[3] /= 255;
+                      }
+                      if (shapes[i].c.k[j].e) {
+                        shapes[i].c.k[j].e[0] /= 255;
+                        shapes[i].c.k[j].e[1] /= 255;
+                        shapes[i].c.k[j].e[2] /= 255;
+                        shapes[i].c.k[j].e[3] /= 255;
+                      }
+                    }
+                  } else {
+                    shapes[i].c.k[0] /= 255;
+                    shapes[i].c.k[1] /= 255;
+                    shapes[i].c.k[2] /= 255;
+                    shapes[i].c.k[3] /= 255;
+                  }
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 4) {
+                  iterateShapes(layers[i].shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkShapes = (function () {
+            var minimumVersion = [4, 4, 18];
+
+            function completeClosingShapes(arr) {
+              var i;
+              var len = arr.length;
+              var j;
+              var jLen;
+              for (i = len - 1; i >= 0; i -= 1) {
+                if (arr[i].ty === 'sh') {
+                  if (arr[i].ks.k.i) {
+                    arr[i].ks.k.c = arr[i].closed;
+                  } else {
+                    jLen = arr[i].ks.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (arr[i].ks.k[j].s) {
+                        arr[i].ks.k[j].s[0].c = arr[i].closed;
+                      }
+                      if (arr[i].ks.k[j].e) {
+                        arr[i].ks.k[j].e[0].c = arr[i].closed;
+                      }
+                    }
+                  }
+                } else if (arr[i].ty === 'gr') {
+                  completeClosingShapes(arr[i].it);
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var layerData;
+              var i;
+              var len = layers.length;
+              var j;
+              var jLen;
+              var k;
+              var kLen;
+              for (i = 0; i < len; i += 1) {
+                layerData = layers[i];
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      maskProps[j].pt.k.c = maskProps[j].cl;
+                    } else {
+                      kLen = maskProps[j].pt.k.length;
+                      for (k = 0; k < kLen; k += 1) {
+                        if (maskProps[j].pt.k[k].s) {
+                          maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 4) {
+                  completeClosingShapes(layerData.shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          function completeData(animationData) {
+            if (animationData.__complete) {
+              return;
+            }
+            checkColors(animationData);
+            checkText(animationData);
+            checkChars(animationData);
+            checkPathProperties(animationData);
+            checkShapes(animationData);
+            completeLayers(animationData.layers, animationData.assets);
+            completeChars(animationData.chars, animationData.assets);
+            animationData.__complete = true;
+          }
+
+          function completeText(data) {
+            if (data.t.a.length === 0 && !('m' in data.t.p)) {
+              // data.singleShape = true;
+            }
+          }
+
+          var moduleOb = {};
+          moduleOb.completeData = completeData;
+          moduleOb.checkColors = checkColors;
+          moduleOb.checkChars = checkChars;
+          moduleOb.checkPathProperties = checkPathProperties;
+          moduleOb.checkShapes = checkShapes;
+          moduleOb.completeLayers = completeLayers;
+
+          return moduleOb;
+        }
+        if (!_workerSelf.dataManager) {
+          _workerSelf.dataManager = dataFunctionManager();
+        }
+
+        if (!_workerSelf.assetLoader) {
+          _workerSelf.assetLoader = (function () {
+            function formatResponse(xhr) {
+              // using typeof doubles the time of execution of this method,
+              // so if available, it's better to use the header to validate the type
+              var contentTypeHeader = xhr.getResponseHeader('content-type');
+              if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
+                return xhr.response;
+              }
+              if (xhr.response && typeof xhr.response === 'object') {
+                return xhr.response;
+              } if (xhr.response && typeof xhr.response === 'string') {
+                return JSON.parse(xhr.response);
+              } if (xhr.responseText) {
+                return JSON.parse(xhr.responseText);
+              }
+              return null;
+            }
+
+            function loadAsset(path, fullPath, callback, errorCallback) {
+              var response;
+              var xhr = new XMLHttpRequest();
+              // set responseType after calling open or IE will break.
+              try {
+                // This crashes on Android WebView prior to KitKat
+                xhr.responseType = 'json';
+              } catch (err) {} // eslint-disable-line no-empty
+              xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4) {
+                  if (xhr.status === 200) {
+                    response = formatResponse(xhr);
+                    callback(response);
+                  } else {
+                    try {
+                      response = formatResponse(xhr);
+                      callback(response);
+                    } catch (err) {
+                      if (errorCallback) {
+                        errorCallback(err);
+                      }
+                    }
+                  }
+                }
+              };
+              try {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), path, true);
+              } catch (error) {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
+              }
+              xhr.send();
+            }
+            return {
+              load: loadAsset,
+            };
+          }());
+        }
+
+        if (e.data.type === 'loadAnimation') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.dataManager.completeData(data);
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        } else if (e.data.type === 'complete') {
+          var animation = e.data.animation;
+          _workerSelf.dataManager.completeData(animation);
+          _workerSelf.postMessage({
+            id: e.data.id,
+            payload: animation,
+            status: 'success',
+          });
+        } else if (e.data.type === 'loadData') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        }
+      });
+
+      workerInstance.onmessage = function (event) {
+        var data = event.data;
+        var id = data.id;
+        var process = processes[id];
+        processes[id] = null;
+        if (data.status === 'success') {
+          process.onComplete(data.payload);
+        } else if (process.onError) {
+          process.onError();
+        }
+      };
+    }
+  }
+
+  function createProcess(onComplete, onError) {
+    _counterId += 1;
+    var id = 'processId_' + _counterId;
+    processes[id] = {
+      onComplete: onComplete,
+      onError: onError,
+    };
+    return id;
+  }
+
+  function loadAnimation(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadAnimation',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function loadData(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadData',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function completeAnimation(anim, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'complete',
+      animation: anim,
+      id: processId,
+    });
+  }
+
+  return {
+    loadAnimation: loadAnimation,
+    loadData: loadData,
+    completeAnimation: completeAnimation,
+  };
+}());
+
+const ImagePreloader = (function () {
+  var proxyImage = (function () {
+    var canvas = createTag('canvas');
+    canvas.width = 1;
+    canvas.height = 1;
+    var ctx = canvas.getContext('2d');
+    ctx.fillStyle = 'rgba(0,0,0,0)';
+    ctx.fillRect(0, 0, 1, 1);
+    return canvas;
+  }());
+
+  function imageLoaded() {
+    this.loadedAssets += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+  function footageLoaded() {
+    this.loadedFootagesCount += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+
+  function getAssetsPath(assetData, assetsPath, originalPath) {
+    var path = '';
+    if (assetData.e) {
+      path = assetData.p;
+    } else if (assetsPath) {
+      var imagePath = assetData.p;
+      if (imagePath.indexOf('images/') !== -1) {
+        imagePath = imagePath.split('/')[1];
+      }
+      path = assetsPath + imagePath;
+    } else {
+      path = originalPath;
+      path += assetData.u ? assetData.u : '';
+      path += assetData.p;
+    }
+    return path;
+  }
+
+  function testImageLoaded(img) {
+    var _count = 0;
+    var intervalId = setInterval(function () {
+      var box = img.getBBox();
+      if (box.width || _count > 500) {
+        this._imageLoaded();
+        clearInterval(intervalId);
+      }
+      _count += 1;
+    }.bind(this), 50);
+  }
+
+  function createImageData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createNS('image');
+    if (isSafari) {
+      this.testImageLoaded(img);
+    } else {
+      img.addEventListener('load', this._imageLoaded, false);
+    }
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
+    if (this._elementHelper.append) {
+      this._elementHelper.append(img);
+    } else {
+      this._elementHelper.appendChild(img);
+    }
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createImgData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createTag('img');
+    img.crossOrigin = 'anonymous';
+    img.addEventListener('load', this._imageLoaded, false);
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.src = path;
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createFootageData(data) {
+    var ob = {
+      assetData: data,
+    };
+    var path = getAssetsPath(data, this.assetsPath, this.path);
+    dataManager.loadData(path, function (footageData) {
+      ob.img = footageData;
+      this._footageLoaded();
+    }.bind(this), function () {
+      ob.img = {};
+      this._footageLoaded();
+    }.bind(this));
+    return ob;
+  }
+
+  function loadAssets(assets, cb) {
+    this.imagesLoadedCb = cb;
+    var i;
+    var len = assets.length;
+    for (i = 0; i < len; i += 1) {
+      if (!assets[i].layers) {
+        if (!assets[i].t || assets[i].t === 'seq') {
+          this.totalImages += 1;
+          this.images.push(this._createImageData(assets[i]));
+        } else if (assets[i].t === 3) {
+          this.totalFootages += 1;
+          this.images.push(this.createFootageData(assets[i]));
+        }
+      }
+    }
+  }
+
+  function setPath(path) {
+    this.path = path || '';
+  }
+
+  function setAssetsPath(path) {
+    this.assetsPath = path || '';
+  }
+
+  function getAsset(assetData) {
+    var i = 0;
+    var len = this.images.length;
+    while (i < len) {
+      if (this.images[i].assetData === assetData) {
+        return this.images[i].img;
+      }
+      i += 1;
+    }
+    return null;
+  }
+
+  function destroy() {
+    this.imagesLoadedCb = null;
+    this.images.length = 0;
+  }
+
+  function loadedImages() {
+    return this.totalImages === this.loadedAssets;
+  }
+
+  function loadedFootages() {
+    return this.totalFootages === this.loadedFootagesCount;
+  }
+
+  function setCacheType(type, elementHelper) {
+    if (type === 'svg') {
+      this._elementHelper = elementHelper;
+      this._createImageData = this.createImageData.bind(this);
+    } else {
+      this._createImageData = this.createImgData.bind(this);
+    }
+  }
+
+  function ImagePreloaderFactory() {
+    this._imageLoaded = imageLoaded.bind(this);
+    this._footageLoaded = footageLoaded.bind(this);
+    this.testImageLoaded = testImageLoaded.bind(this);
+    this.createFootageData = createFootageData.bind(this);
+    this.assetsPath = '';
+    this.path = '';
+    this.totalImages = 0;
+    this.totalFootages = 0;
+    this.loadedAssets = 0;
+    this.loadedFootagesCount = 0;
+    this.imagesLoadedCb = null;
+    this.images = [];
+  }
+
+  ImagePreloaderFactory.prototype = {
+    loadAssets: loadAssets,
+    setAssetsPath: setAssetsPath,
+    setPath: setPath,
+    loadedImages: loadedImages,
+    loadedFootages: loadedFootages,
+    destroy: destroy,
+    getAsset: getAsset,
+    createImgData: createImgData,
+    createImageData: createImageData,
+    imageLoaded: imageLoaded,
+    footageLoaded: footageLoaded,
+    setCacheType: setCacheType,
+  };
+
+  return ImagePreloaderFactory;
+}());
+
+function BaseEvent() {}
+BaseEvent.prototype = {
+  triggerEvent: function (eventName, args) {
+    if (this._cbs[eventName]) {
+      var callbacks = this._cbs[eventName];
+      for (var i = 0; i < callbacks.length; i += 1) {
+        callbacks[i](args);
+      }
+    }
+  },
+  addEventListener: function (eventName, callback) {
+    if (!this._cbs[eventName]) {
+      this._cbs[eventName] = [];
+    }
+    this._cbs[eventName].push(callback);
+
+    return function () {
+      this.removeEventListener(eventName, callback);
+    }.bind(this);
+  },
+  removeEventListener: function (eventName, callback) {
+    if (!callback) {
+      this._cbs[eventName] = null;
+    } else if (this._cbs[eventName]) {
+      var i = 0;
+      var len = this._cbs[eventName].length;
+      while (i < len) {
+        if (this._cbs[eventName][i] === callback) {
+          this._cbs[eventName].splice(i, 1);
+          i -= 1;
+          len -= 1;
+        }
+        i += 1;
+      }
+      if (!this._cbs[eventName].length) {
+        this._cbs[eventName] = null;
+      }
+    }
+  },
+};
+
+const markerParser = (
+
+  function () {
+    function parsePayloadLines(payload) {
+      var lines = payload.split('\r\n');
+      var keys = {};
+      var line;
+      var keysCount = 0;
+      for (var i = 0; i < lines.length; i += 1) {
+        line = lines[i].split(':');
+        if (line.length === 2) {
+          keys[line[0]] = line[1].trim();
+          keysCount += 1;
+        }
+      }
+      if (keysCount === 0) {
+        throw new Error();
+      }
+      return keys;
+    }
+
+    return function (_markers) {
+      var markers = [];
+      for (var i = 0; i < _markers.length; i += 1) {
+        var _marker = _markers[i];
+        var markerData = {
+          time: _marker.tm,
+          duration: _marker.dr,
+        };
+        try {
+          markerData.payload = JSON.parse(_markers[i].cm);
+        } catch (_) {
+          try {
+            markerData.payload = parsePayloadLines(_markers[i].cm);
+          } catch (__) {
+            markerData.payload = {
+              name: _markers[i].cm,
+            };
+          }
+        }
+        markers.push(markerData);
+      }
+      return markers;
+    };
+  }());
+
+const ProjectInterface = (function () {
+  function registerComposition(comp) {
+    this.compositions.push(comp);
+  }
+
+  return function () {
+    function _thisProjectFunction(name) {
+      var i = 0;
+      var len = this.compositions.length;
+      while (i < len) {
+        if (this.compositions[i].data && this.compositions[i].data.nm === name) {
+          if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
+            this.compositions[i].prepareFrame(this.currentFrame);
+          }
+          return this.compositions[i].compInterface;
+        }
+        i += 1;
+      }
+      return null;
+    }
+
+    _thisProjectFunction.compositions = [];
+    _thisProjectFunction.currentFrame = 0;
+
+    _thisProjectFunction.registerComposition = registerComposition;
+
+    return _thisProjectFunction;
+  };
+}());
+
+const renderers = {};
+
+const registerRenderer = (key, value) => {
+  renderers[key] = value;
+};
+
+function getRenderer(key) {
+  return renderers[key];
+}
+
+function getRegisteredRenderer() {
+  // Returns canvas by default for compatibility
+  if (renderers.canvas) {
+    return 'canvas';
+  }
+  // Returns any renderer that is registered
+  for (const key in renderers) {
+    if (renderers[key]) {
+      return key;
+    }
+  }
+  return '';
+}
+
+const AnimationItem = function () {
+  this._cbs = [];
+  this.name = '';
+  this.path = '';
+  this.isLoaded = false;
+  this.currentFrame = 0;
+  this.currentRawFrame = 0;
+  this.firstFrame = 0;
+  this.totalFrames = 0;
+  this.frameRate = 0;
+  this.frameMult = 0;
+  this.playSpeed = 1;
+  this.playDirection = 1;
+  this.playCount = 0;
+  this.animationData = {};
+  this.assets = [];
+  this.isPaused = true;
+  this.autoplay = false;
+  this.loop = true;
+  this.renderer = null;
+  this.animationID = createElementID();
+  this.assetsPath = '';
+  this.timeCompleted = 0;
+  this.segmentPos = 0;
+  this.isSubframeEnabled = getSubframeEnabled();
+  this.segments = [];
+  this._idle = true;
+  this._completedLoop = false;
+  this.projectInterface = ProjectInterface();
+  this.imagePreloader = new ImagePreloader();
+  this.audioController = audioControllerFactory();
+  this.markers = [];
+  this.configAnimation = this.configAnimation.bind(this);
+  this.onSetupError = this.onSetupError.bind(this);
+  this.onSegmentComplete = this.onSegmentComplete.bind(this);
+  this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
+  this.expressionsPlugin = getExpressionsPlugin();
+};
+
+extendPrototype([BaseEvent], AnimationItem);
+
+AnimationItem.prototype.setParams = function (params) {
+  if (params.wrapper || params.container) {
+    this.wrapper = params.wrapper || params.container;
+  }
+  var animType = 'svg';
+  if (params.animType) {
+    animType = params.animType;
+  } else if (params.renderer) {
+    animType = params.renderer;
+  }
+  const RendererClass = getRenderer(animType);
+  this.renderer = new RendererClass(this, params.rendererSettings);
+  this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
+  this.renderer.setProjectInterface(this.projectInterface);
+  this.animType = animType;
+  if (params.loop === ''
+        || params.loop === null
+        || params.loop === undefined
+        || params.loop === true) {
+    this.loop = true;
+  } else if (params.loop === false) {
+    this.loop = false;
+  } else {
+    this.loop = parseInt(params.loop, 10);
+  }
+  this.autoplay = 'autoplay' in params ? params.autoplay : true;
+  this.name = params.name ? params.name : '';
+  this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
+  this.assetsPath = params.assetsPath;
+  this.initialSegment = params.initialSegment;
+  if (params.audioFactory) {
+    this.audioController.setAudioFactory(params.audioFactory);
+  }
+  if (params.animationData) {
+    this.setupAnimation(params.animationData);
+  } else if (params.path) {
+    if (params.path.lastIndexOf('\\') !== -1) {
+      this.path = params.path.substr(0, params.path.lastIndexOf('\\') + 1);
+    } else {
+      this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
+    }
+    this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
+    this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
+    dataManager.loadAnimation(
+      params.path,
+      this.configAnimation,
+      this.onSetupError
+    );
+  }
+};
+
+AnimationItem.prototype.onSetupError = function () {
+  this.trigger('data_failed');
+};
+
+AnimationItem.prototype.setupAnimation = function (data) {
+  dataManager.completeAnimation(
+    data,
+    this.configAnimation
+  );
+};
+
+AnimationItem.prototype.setData = function (wrapper, animationData) {
+  if (animationData) {
+    if (typeof animationData !== 'object') {
+      animationData = JSON.parse(animationData);
+    }
+  }
+  var params = {
+    wrapper: wrapper,
+    animationData: animationData,
+  };
+  var wrapperAttributes = wrapper.attributes;
+
+  params.path = wrapperAttributes.getNamedItem('data-animation-path') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-animation-path').value
+    : wrapperAttributes.getNamedItem('data-bm-path') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-path').value
+      : wrapperAttributes.getNamedItem('bm-path')
+        ? wrapperAttributes.getNamedItem('bm-path').value
+        : '';
+  params.animType = wrapperAttributes.getNamedItem('data-anim-type') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-type').value
+    : wrapperAttributes.getNamedItem('data-bm-type') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-type').value
+      : wrapperAttributes.getNamedItem('bm-type') // eslint-disable-line no-nested-ternary
+        ? wrapperAttributes.getNamedItem('bm-type').value
+        : wrapperAttributes.getNamedItem('data-bm-renderer') // eslint-disable-line no-nested-ternary
+          ? wrapperAttributes.getNamedItem('data-bm-renderer').value
+          : wrapperAttributes.getNamedItem('bm-renderer')
+            ? wrapperAttributes.getNamedItem('bm-renderer').value
+            : getRegisteredRenderer() || 'canvas';
+
+  var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-loop').value
+    : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-loop').value
+      : wrapperAttributes.getNamedItem('bm-loop')
+        ? wrapperAttributes.getNamedItem('bm-loop').value
+        : '';
+  if (loop === 'false') {
+    params.loop = false;
+  } else if (loop === 'true') {
+    params.loop = true;
+  } else if (loop !== '') {
+    params.loop = parseInt(loop, 10);
+  }
+  var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-autoplay').value
+    : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-autoplay').value
+      : wrapperAttributes.getNamedItem('bm-autoplay')
+        ? wrapperAttributes.getNamedItem('bm-autoplay').value
+        : true;
+  params.autoplay = autoplay !== 'false';
+
+  params.name = wrapperAttributes.getNamedItem('data-name') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-name').value
+    : wrapperAttributes.getNamedItem('data-bm-name') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-name').value
+      : wrapperAttributes.getNamedItem('bm-name')
+        ? wrapperAttributes.getNamedItem('bm-name').value
+        : '';
+  var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-prerender').value
+    : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-prerender').value
+      : wrapperAttributes.getNamedItem('bm-prerender')
+        ? wrapperAttributes.getNamedItem('bm-prerender').value
+        : '';
+
+  if (prerender === 'false') {
+    params.prerender = false;
+  }
+  if (!params.path) {
+    this.trigger('destroy');
+  } else {
+    this.setParams(params);
+  }
+};
+
+AnimationItem.prototype.includeLayers = function (data) {
+  if (data.op > this.animationData.op) {
+    this.animationData.op = data.op;
+    this.totalFrames = Math.floor(data.op - this.animationData.ip);
+  }
+  var layers = this.animationData.layers;
+  var i;
+  var len = layers.length;
+  var newLayers = data.layers;
+  var j;
+  var jLen = newLayers.length;
+  for (j = 0; j < jLen; j += 1) {
+    i = 0;
+    while (i < len) {
+      if (layers[i].id === newLayers[j].id) {
+        layers[i] = newLayers[j];
+        break;
+      }
+      i += 1;
+    }
+  }
+  if (data.chars || data.fonts) {
+    this.renderer.globalData.fontManager.addChars(data.chars);
+    this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
+  }
+  if (data.assets) {
+    len = data.assets.length;
+    for (i = 0; i < len; i += 1) {
+      this.animationData.assets.push(data.assets[i]);
+    }
+  }
+  this.animationData.__complete = false;
+  dataManager.completeAnimation(
+    this.animationData,
+    this.onSegmentComplete
+  );
+};
+
+AnimationItem.prototype.onSegmentComplete = function (data) {
+  this.animationData = data;
+  var expressionsPlugin = getExpressionsPlugin();
+  if (expressionsPlugin) {
+    expressionsPlugin.initExpressions(this);
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.loadNextSegment = function () {
+  var segments = this.animationData.segments;
+  if (!segments || segments.length === 0 || !this.autoloadSegments) {
+    this.trigger('data_ready');
+    this.timeCompleted = this.totalFrames;
+    return;
+  }
+  var segment = segments.shift();
+  this.timeCompleted = segment.time * this.frameRate;
+  var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
+  this.segmentPos += 1;
+  dataManager.loadData(segmentPath, this.includeLayers.bind(this), function () {
+    this.trigger('data_failed');
+  }.bind(this));
+};
+
+AnimationItem.prototype.loadSegments = function () {
+  var segments = this.animationData.segments;
+  if (!segments) {
+    this.timeCompleted = this.totalFrames;
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.imagesLoaded = function () {
+  this.trigger('loaded_images');
+  this.checkLoaded();
+};
+
+AnimationItem.prototype.preloadImages = function () {
+  this.imagePreloader.setAssetsPath(this.assetsPath);
+  this.imagePreloader.setPath(this.path);
+  this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
+};
+
+AnimationItem.prototype.configAnimation = function (animData) {
+  if (!this.renderer) {
+    return;
+  }
+  try {
+    this.animationData = animData;
+    if (this.initialSegment) {
+      this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
+      this.firstFrame = Math.round(this.initialSegment[0]);
+    } else {
+      this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
+      this.firstFrame = Math.round(this.animationData.ip);
+    }
+    this.renderer.configAnimation(animData);
+    if (!animData.assets) {
+      animData.assets = [];
+    }
+
+    this.assets = this.animationData.assets;
+    this.frameRate = this.animationData.fr;
+    this.frameMult = this.animationData.fr / 1000;
+    this.renderer.searchExtraCompositions(animData.assets);
+    this.markers = markerParser(animData.markers || []);
+    this.trigger('config_ready');
+    this.preloadImages();
+    this.loadSegments();
+    this.updaFrameModifier();
+    this.waitForFontsLoaded();
+    if (this.isPaused) {
+      this.audioController.pause();
+    }
+  } catch (error) {
+    this.triggerConfigError(error);
+  }
+};
+
+AnimationItem.prototype.waitForFontsLoaded = function () {
+  if (!this.renderer) {
+    return;
+  }
+  if (this.renderer.globalData.fontManager.isLoaded) {
+    this.checkLoaded();
+  } else {
+    setTimeout(this.waitForFontsLoaded.bind(this), 20);
+  }
+};
+
+AnimationItem.prototype.checkLoaded = function () {
+  if (!this.isLoaded
+        && this.renderer.globalData.fontManager.isLoaded
+        && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas')
+        && (this.imagePreloader.loadedFootages())
+  ) {
+    this.isLoaded = true;
+    var expressionsPlugin = getExpressionsPlugin();
+    if (expressionsPlugin) {
+      expressionsPlugin.initExpressions(this);
+    }
+    this.renderer.initItems();
+    setTimeout(function () {
+      this.trigger('DOMLoaded');
+    }.bind(this), 0);
+    this.gotoFrame();
+    if (this.autoplay) {
+      this.play();
+    }
+  }
+};
+
+AnimationItem.prototype.resize = function (width, height) {
+  // Adding this validation for backwards compatibility in case an event object was being passed down
+  var _width = typeof width === 'number' ? width : undefined;
+  var _height = typeof height === 'number' ? height : undefined;
+  this.renderer.updateContainerSize(_width, _height);
+};
+
+AnimationItem.prototype.setSubframe = function (flag) {
+  this.isSubframeEnabled = !!flag;
+};
+
+AnimationItem.prototype.gotoFrame = function () {
+  this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
+
+  if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
+    this.currentFrame = this.timeCompleted;
+  }
+  this.trigger('enterFrame');
+  this.renderFrame();
+  this.trigger('drawnFrame');
+};
+
+AnimationItem.prototype.renderFrame = function () {
+  if (this.isLoaded === false || !this.renderer) {
+    return;
+  }
+  try {
+    if (this.expressionsPlugin) {
+      this.expressionsPlugin.resetFrame();
+    }
+    this.renderer.renderFrame(this.currentFrame + this.firstFrame);
+  } catch (error) {
+    this.triggerRenderFrameError(error);
+  }
+};
+
+AnimationItem.prototype.play = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.isPaused = false;
+    this.trigger('_play');
+    this.audioController.resume();
+    if (this._idle) {
+      this._idle = false;
+      this.trigger('_active');
+    }
+  }
+};
+
+AnimationItem.prototype.pause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === false) {
+    this.isPaused = true;
+    this.trigger('_pause');
+    this._idle = true;
+    this.trigger('_idle');
+    this.audioController.pause();
+  }
+};
+
+AnimationItem.prototype.togglePause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.play();
+  } else {
+    this.pause();
+  }
+};
+
+AnimationItem.prototype.stop = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.pause();
+  this.playCount = 0;
+  this._completedLoop = false;
+  this.setCurrentRawFrameValue(0);
+};
+
+AnimationItem.prototype.getMarkerData = function (markerName) {
+  var marker;
+  for (var i = 0; i < this.markers.length; i += 1) {
+    marker = this.markers[i];
+    if (marker.payload && marker.payload.name === markerName) {
+      return marker;
+    }
+  }
+  return null;
+};
+
+AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      this.goToAndStop(marker.time, true);
+    }
+  } else if (isFrame) {
+    this.setCurrentRawFrameValue(value);
+  } else {
+    this.setCurrentRawFrameValue(value * this.frameModifier);
+  }
+  this.pause();
+};
+
+AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      if (!marker.duration) {
+        this.goToAndStop(marker.time, true);
+      } else {
+        this.playSegments([marker.time, marker.time + marker.duration], true);
+      }
+    }
+  } else {
+    this.goToAndStop(numValue, isFrame, name);
+  }
+  this.play();
+};
+
+AnimationItem.prototype.advanceTime = function (value) {
+  if (this.isPaused === true || this.isLoaded === false) {
+    return;
+  }
+  var nextValue = this.currentRawFrame + value * this.frameModifier;
+  var _isComplete = false;
+  // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+  // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
+  if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
+    if (!this.loop || this.playCount === this.loop) {
+      if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
+        _isComplete = true;
+        nextValue = this.totalFrames - 1;
+      }
+    } else if (nextValue >= this.totalFrames) {
+      this.playCount += 1;
+      if (!this.checkSegments(nextValue % this.totalFrames)) {
+        this.setCurrentRawFrameValue(nextValue % this.totalFrames);
+        this._completedLoop = true;
+        this.trigger('loopComplete');
+      }
+    } else {
+      this.setCurrentRawFrameValue(nextValue);
+    }
+  } else if (nextValue < 0) {
+    if (!this.checkSegments(nextValue % this.totalFrames)) {
+      if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) { // eslint-disable-line no-plusplus
+        this.setCurrentRawFrameValue(this.totalFrames + (nextValue % this.totalFrames));
+        if (!this._completedLoop) {
+          this._completedLoop = true;
+        } else {
+          this.trigger('loopComplete');
+        }
+      } else {
+        _isComplete = true;
+        nextValue = 0;
+      }
+    }
+  } else {
+    this.setCurrentRawFrameValue(nextValue);
+  }
+  if (_isComplete) {
+    this.setCurrentRawFrameValue(nextValue);
+    this.pause();
+    this.trigger('complete');
+  }
+};
+
+AnimationItem.prototype.adjustSegment = function (arr, offset) {
+  this.playCount = 0;
+  if (arr[1] < arr[0]) {
+    if (this.frameModifier > 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(-1);
+      }
+    }
+    this.totalFrames = arr[0] - arr[1];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[1];
+    this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset);
+  } else if (arr[1] > arr[0]) {
+    if (this.frameModifier < 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(1);
+      }
+    }
+    this.totalFrames = arr[1] - arr[0];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[0];
+    this.setCurrentRawFrameValue(0.001 + offset);
+  }
+  this.trigger('segmentStart');
+};
+AnimationItem.prototype.setSegment = function (init, end) {
+  var pendingFrame = -1;
+  if (this.isPaused) {
+    if (this.currentRawFrame + this.firstFrame < init) {
+      pendingFrame = init;
+    } else if (this.currentRawFrame + this.firstFrame > end) {
+      pendingFrame = end - init;
+    }
+  }
+
+  this.firstFrame = init;
+  this.totalFrames = end - init;
+  this.timeCompleted = this.totalFrames;
+  if (pendingFrame !== -1) {
+    this.goToAndStop(pendingFrame, true);
+  }
+};
+
+AnimationItem.prototype.playSegments = function (arr, forceFlag) {
+  if (forceFlag) {
+    this.segments.length = 0;
+  }
+  if (typeof arr[0] === 'object') {
+    var i;
+    var len = arr.length;
+    for (i = 0; i < len; i += 1) {
+      this.segments.push(arr[i]);
+    }
+  } else {
+    this.segments.push(arr);
+  }
+  if (this.segments.length && forceFlag) {
+    this.adjustSegment(this.segments.shift(), 0);
+  }
+  if (this.isPaused) {
+    this.play();
+  }
+};
+
+AnimationItem.prototype.resetSegments = function (forceFlag) {
+  this.segments.length = 0;
+  this.segments.push([this.animationData.ip, this.animationData.op]);
+  if (forceFlag) {
+    this.checkSegments(0);
+  }
+};
+AnimationItem.prototype.checkSegments = function (offset) {
+  if (this.segments.length) {
+    this.adjustSegment(this.segments.shift(), offset);
+    return true;
+  }
+  return false;
+};
+
+AnimationItem.prototype.destroy = function (name) {
+  if ((name && this.name !== name) || !this.renderer) {
+    return;
+  }
+  this.renderer.destroy();
+  this.imagePreloader.destroy();
+  this.trigger('destroy');
+  this._cbs = null;
+  this.onEnterFrame = null;
+  this.onLoopComplete = null;
+  this.onComplete = null;
+  this.onSegmentStart = null;
+  this.onDestroy = null;
+  this.renderer = null;
+  this.expressionsPlugin = null;
+  this.imagePreloader = null;
+  this.projectInterface = null;
+};
+
+AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
+  this.currentRawFrame = value;
+  this.gotoFrame();
+};
+
+AnimationItem.prototype.setSpeed = function (val) {
+  this.playSpeed = val;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setDirection = function (val) {
+  this.playDirection = val < 0 ? -1 : 1;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setLoop = function (isLooping) {
+  this.loop = isLooping;
+};
+
+AnimationItem.prototype.setVolume = function (val, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.setVolume(val);
+};
+
+AnimationItem.prototype.getVolume = function () {
+  return this.audioController.getVolume();
+};
+
+AnimationItem.prototype.mute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.mute();
+};
+
+AnimationItem.prototype.unmute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.unmute();
+};
+
+AnimationItem.prototype.updaFrameModifier = function () {
+  this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
+  this.audioController.setRate(this.playSpeed * this.playDirection);
+};
+
+AnimationItem.prototype.getPath = function () {
+  return this.path;
+};
+
+AnimationItem.prototype.getAssetsPath = function (assetData) {
+  var path = '';
+  if (assetData.e) {
+    path = assetData.p;
+  } else if (this.assetsPath) {
+    var imagePath = assetData.p;
+    if (imagePath.indexOf('images/') !== -1) {
+      imagePath = imagePath.split('/')[1];
+    }
+    path = this.assetsPath + imagePath;
+  } else {
+    path = this.path;
+    path += assetData.u ? assetData.u : '';
+    path += assetData.p;
+  }
+  return path;
+};
+
+AnimationItem.prototype.getAssetData = function (id) {
+  var i = 0;
+  var len = this.assets.length;
+  while (i < len) {
+    if (id === this.assets[i].id) {
+      return this.assets[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+AnimationItem.prototype.hide = function () {
+  this.renderer.hide();
+};
+
+AnimationItem.prototype.show = function () {
+  this.renderer.show();
+};
+
+AnimationItem.prototype.getDuration = function (isFrame) {
+  return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
+};
+
+AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
+  try {
+    var element = this.renderer.getElementByPath(path);
+    element.updateDocumentData(documentData, index);
+  } catch (error) {
+    // TODO: decide how to handle catch case
+  }
+};
+
+AnimationItem.prototype.trigger = function (name) {
+  if (this._cbs && this._cbs[name]) {
+    switch (name) {
+      case 'enterFrame':
+        this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
+        break;
+      case 'drawnFrame':
+        this.drawnFrameEvent.currentTime = this.currentFrame;
+        this.drawnFrameEvent.totalTime = this.totalFrames;
+        this.drawnFrameEvent.direction = this.frameModifier;
+        this.triggerEvent(name, this.drawnFrameEvent);
+        break;
+      case 'loopComplete':
+        this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+        break;
+      case 'complete':
+        this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
+        break;
+      case 'segmentStart':
+        this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+        break;
+      case 'destroy':
+        this.triggerEvent(name, new BMDestroyEvent(name, this));
+        break;
+      default:
+        this.triggerEvent(name);
+    }
+  }
+  if (name === 'enterFrame' && this.onEnterFrame) {
+    this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
+  }
+  if (name === 'loopComplete' && this.onLoopComplete) {
+    this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+  }
+  if (name === 'complete' && this.onComplete) {
+    this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
+  }
+  if (name === 'segmentStart' && this.onSegmentStart) {
+    this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+  }
+  if (name === 'destroy' && this.onDestroy) {
+    this.onDestroy.call(this, new BMDestroyEvent(name, this));
+  }
+};
+
+AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
+  var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+AnimationItem.prototype.triggerConfigError = function (nativeError) {
+  var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+const animationManager = (function () {
+  var moduleOb = {};
+  var registeredAnimations = [];
+  var initTime = 0;
+  var len = 0;
+  var playingAnimationsNum = 0;
+  var _stopped = true;
+  var _isFrozen = false;
+
+  function removeElement(ev) {
+    var i = 0;
+    var animItem = ev.target;
+    while (i < len) {
+      if (registeredAnimations[i].animation === animItem) {
+        registeredAnimations.splice(i, 1);
+        i -= 1;
+        len -= 1;
+        if (!animItem.isPaused) {
+          subtractPlayingCount();
+        }
+      }
+      i += 1;
+    }
+  }
+
+  function registerAnimation(element, animationData) {
+    if (!element) {
+      return null;
+    }
+    var i = 0;
+    while (i < len) {
+      if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
+        return registeredAnimations[i].animation;
+      }
+      i += 1;
+    }
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, element);
+    animItem.setData(element, animationData);
+    return animItem;
+  }
+
+  function getRegisteredAnimations() {
+    var i;
+    var lenAnims = registeredAnimations.length;
+    var animations = [];
+    for (i = 0; i < lenAnims; i += 1) {
+      animations.push(registeredAnimations[i].animation);
+    }
+    return animations;
+  }
+
+  function addPlayingCount() {
+    playingAnimationsNum += 1;
+    activate();
+  }
+
+  function subtractPlayingCount() {
+    playingAnimationsNum -= 1;
+  }
+
+  function setupAnimation(animItem, element) {
+    animItem.addEventListener('destroy', removeElement);
+    animItem.addEventListener('_active', addPlayingCount);
+    animItem.addEventListener('_idle', subtractPlayingCount);
+    registeredAnimations.push({ elem: element, animation: animItem });
+    len += 1;
+  }
+
+  function loadAnimation(params) {
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, null);
+    animItem.setParams(params);
+    return animItem;
+  }
+
+  function setSpeed(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setSpeed(val, animation);
+    }
+  }
+
+  function setDirection(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setDirection(val, animation);
+    }
+  }
+
+  function play(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.play(animation);
+    }
+  }
+  function resume(nowTime) {
+    var elapsedTime = nowTime - initTime;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.advanceTime(elapsedTime);
+    }
+    initTime = nowTime;
+    if (playingAnimationsNum && !_isFrozen) {
+      window.requestAnimationFrame(resume);
+    } else {
+      _stopped = true;
+    }
+  }
+
+  function first(nowTime) {
+    initTime = nowTime;
+    window.requestAnimationFrame(resume);
+  }
+
+  function pause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.pause(animation);
+    }
+  }
+
+  function goToAndStop(value, isFrame, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
+    }
+  }
+
+  function stop(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.stop(animation);
+    }
+  }
+
+  function togglePause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.togglePause(animation);
+    }
+  }
+
+  function destroy(animation) {
+    var i;
+    for (i = (len - 1); i >= 0; i -= 1) {
+      registeredAnimations[i].animation.destroy(animation);
+    }
+  }
+
+  function searchAnimations(animationData, standalone, renderer) {
+    var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')),
+      [].slice.call(document.getElementsByClassName('bodymovin')));
+    var i;
+    var lenAnims = animElements.length;
+    for (i = 0; i < lenAnims; i += 1) {
+      if (renderer) {
+        animElements[i].setAttribute('data-bm-type', renderer);
+      }
+      registerAnimation(animElements[i], animationData);
+    }
+    if (standalone && lenAnims === 0) {
+      if (!renderer) {
+        renderer = 'svg';
+      }
+      var body = document.getElementsByTagName('body')[0];
+      body.innerText = '';
+      var div = createTag('div');
+      div.style.width = '100%';
+      div.style.height = '100%';
+      div.setAttribute('data-bm-type', renderer);
+      body.appendChild(div);
+      registerAnimation(div, animationData);
+    }
+  }
+
+  function resize() {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.resize();
+    }
+  }
+
+  function activate() {
+    if (!_isFrozen && playingAnimationsNum) {
+      if (_stopped) {
+        window.requestAnimationFrame(first);
+        _stopped = false;
+      }
+    }
+  }
+
+  function freeze() {
+    _isFrozen = true;
+  }
+
+  function unfreeze() {
+    _isFrozen = false;
+    activate();
+  }
+
+  function setVolume(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setVolume(val, animation);
+    }
+  }
+
+  function mute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.mute(animation);
+    }
+  }
+
+  function unmute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.unmute(animation);
+    }
+  }
+
+  moduleOb.registerAnimation = registerAnimation;
+  moduleOb.loadAnimation = loadAnimation;
+  moduleOb.setSpeed = setSpeed;
+  moduleOb.setDirection = setDirection;
+  moduleOb.play = play;
+  moduleOb.pause = pause;
+  moduleOb.stop = stop;
+  moduleOb.togglePause = togglePause;
+  moduleOb.searchAnimations = searchAnimations;
+  moduleOb.resize = resize;
+  // moduleOb.start = start;
+  moduleOb.goToAndStop = goToAndStop;
+  moduleOb.destroy = destroy;
+  moduleOb.freeze = freeze;
+  moduleOb.unfreeze = unfreeze;
+  moduleOb.setVolume = setVolume;
+  moduleOb.mute = mute;
+  moduleOb.unmute = unmute;
+  moduleOb.getRegisteredAnimations = getRegisteredAnimations;
+  return moduleOb;
+}());
+
+/* eslint-disable */
+const BezierFactory = (function () {
+  /**
+     * BezierEasing - use bezier curve for transition easing function
+     * by Gaëtan Renaudeau 2014 - 2015 – MIT License
+     *
+     * Credits: is based on Firefox's nsSMILKeySpline.cpp
+     * Usage:
+     * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
+     * spline.get(x) => returns the easing value | x must be in [0, 1] range
+     *
+     */
+
+  var ob = {};
+  ob.getBezierEasing = getBezierEasing;
+  var beziers = {};
+
+  function getBezierEasing(a, b, c, d, nm) {
+    var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
+    if (beziers[str]) {
+      return beziers[str];
+    }
+    var bezEasing = new BezierEasing([a, b, c, d]);
+    beziers[str] = bezEasing;
+    return bezEasing;
+  }
+
+  // These values are established by empiricism with tests (tradeoff: performance VS precision)
+  var NEWTON_ITERATIONS = 4;
+  var NEWTON_MIN_SLOPE = 0.001;
+  var SUBDIVISION_PRECISION = 0.0000001;
+  var SUBDIVISION_MAX_ITERATIONS = 10;
+
+  var kSplineTableSize = 11;
+  var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
+
+  var float32ArraySupported = typeof Float32Array === 'function';
+
+  function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
+  function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
+  function C(aA1) { return 3.0 * aA1; }
+
+  // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+  function calcBezier(aT, aA1, aA2) {
+    return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
+  }
+
+  // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+  function getSlope(aT, aA1, aA2) {
+    return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
+  }
+
+  function binarySubdivide(aX, aA, aB, mX1, mX2) {
+    var currentX,
+      currentT,
+      i = 0;
+    do {
+      currentT = aA + (aB - aA) / 2.0;
+      currentX = calcBezier(currentT, mX1, mX2) - aX;
+      if (currentX > 0.0) {
+        aB = currentT;
+      } else {
+        aA = currentT;
+      }
+    } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
+    return currentT;
+  }
+
+  function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
+    for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
+      var currentSlope = getSlope(aGuessT, mX1, mX2);
+      if (currentSlope === 0.0) return aGuessT;
+      var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
+      aGuessT -= currentX / currentSlope;
+    }
+    return aGuessT;
+  }
+
+  /**
+     * points is an array of [ mX1, mY1, mX2, mY2 ]
+     */
+  function BezierEasing(points) {
+    this._p = points;
+    this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
+    this._precomputed = false;
+
+    this.get = this.get.bind(this);
+  }
+
+  BezierEasing.prototype = {
+
+    get: function (x) {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      if (!this._precomputed) this._precompute();
+      if (mX1 === mY1 && mX2 === mY2) return x; // linear
+      // Because JavaScript number are imprecise, we should guarantee the extremes are right.
+      if (x === 0) return 0;
+      if (x === 1) return 1;
+      return calcBezier(this._getTForX(x), mY1, mY2);
+    },
+
+    // Private part
+
+    _precompute: function () {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      this._precomputed = true;
+      if (mX1 !== mY1 || mX2 !== mY2) { this._calcSampleValues(); }
+    },
+
+    _calcSampleValues: function () {
+      var mX1 = this._p[0],
+        mX2 = this._p[2];
+      for (var i = 0; i < kSplineTableSize; ++i) {
+        this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
+      }
+    },
+
+    /**
+         * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
+         */
+    _getTForX: function (aX) {
+      var mX1 = this._p[0],
+        mX2 = this._p[2],
+        mSampleValues = this._mSampleValues;
+
+      var intervalStart = 0.0;
+      var currentSample = 1;
+      var lastSample = kSplineTableSize - 1;
+
+      for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
+        intervalStart += kSampleStepSize;
+      }
+      --currentSample;
+
+      // Interpolate to provide an initial guess for t
+      var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
+      var guessForT = intervalStart + dist * kSampleStepSize;
+
+      var initialSlope = getSlope(guessForT, mX1, mX2);
+      if (initialSlope >= NEWTON_MIN_SLOPE) {
+        return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
+      } if (initialSlope === 0.0) {
+        return guessForT;
+      }
+      return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
+    },
+  };
+
+  return ob;
+}());
+
+const pooling = (function () {
+  function double(arr) {
+    return arr.concat(createSizedArray(arr.length));
+  }
+
+  return {
+    double: double,
+  };
+}());
+
+const poolFactory = (function () {
+  return function (initialLength, _create, _release) {
+    var _length = 0;
+    var _maxLength = initialLength;
+    var pool = createSizedArray(_maxLength);
+
+    var ob = {
+      newElement: newElement,
+      release: release,
+    };
+
+    function newElement() {
+      var element;
+      if (_length) {
+        _length -= 1;
+        element = pool[_length];
+      } else {
+        element = _create();
+      }
+      return element;
+    }
+
+    function release(element) {
+      if (_length === _maxLength) {
+        pool = pooling.double(pool);
+        _maxLength *= 2;
+      }
+      if (_release) {
+        _release(element);
+      }
+      pool[_length] = element;
+      _length += 1;
+    }
+
+    return ob;
+  };
+}());
+
+const bezierLengthPool = (function () {
+  function create() {
+    return {
+      addedLength: 0,
+      percents: createTypedArray('float32', getDefaultCurveSegments()),
+      lengths: createTypedArray('float32', getDefaultCurveSegments()),
+    };
+  }
+  return poolFactory(8, create);
+}());
+
+const segmentsLengthPool = (function () {
+  function create() {
+    return {
+      lengths: [],
+      totalLength: 0,
+    };
+  }
+
+  function release(element) {
+    var i;
+    var len = element.lengths.length;
+    for (i = 0; i < len; i += 1) {
+      bezierLengthPool.release(element.lengths[i]);
+    }
+    element.lengths.length = 0;
+  }
+
+  return poolFactory(8, create, release);
+}());
+
+function bezFunction() {
+  var math = Math;
+
+  function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
+    var det1 = (x1 * y2) + (y1 * x3) + (x2 * y3) - (x3 * y2) - (y3 * x1) - (x2 * y1);
+    return det1 > -0.001 && det1 < 0.001;
+  }
+
+  function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
+    if (z1 === 0 && z2 === 0 && z3 === 0) {
+      return pointOnLine2D(x1, y1, x2, y2, x3, y3);
+    }
+    var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
+    var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
+    var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
+    var diffDist;
+    if (dist1 > dist2) {
+      if (dist1 > dist3) {
+        diffDist = dist1 - dist2 - dist3;
+      } else {
+        diffDist = dist3 - dist2 - dist1;
+      }
+    } else if (dist3 > dist2) {
+      diffDist = dist3 - dist2 - dist1;
+    } else {
+      diffDist = dist2 - dist1 - dist3;
+    }
+    return diffDist > -0.0001 && diffDist < 0.0001;
+  }
+
+  var getBezierLength = (function () {
+    return function (pt1, pt2, pt3, pt4) {
+      var curveSegments = getDefaultCurveSegments();
+      var k;
+      var i;
+      var len;
+      var ptCoord;
+      var perc;
+      var addedLength = 0;
+      var ptDistance;
+      var point = [];
+      var lastPoint = [];
+      var lengthData = bezierLengthPool.newElement();
+      len = pt3.length;
+      for (k = 0; k < curveSegments; k += 1) {
+        perc = k / (curveSegments - 1);
+        ptDistance = 0;
+        for (i = 0; i < len; i += 1) {
+          ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
+          point[i] = ptCoord;
+          if (lastPoint[i] !== null) {
+            ptDistance += bmPow(point[i] - lastPoint[i], 2);
+          }
+          lastPoint[i] = point[i];
+        }
+        if (ptDistance) {
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+        }
+        lengthData.percents[k] = perc;
+        lengthData.lengths[k] = addedLength;
+      }
+      lengthData.addedLength = addedLength;
+      return lengthData;
+    };
+  }());
+
+  function getSegmentsLength(shapeData) {
+    var segmentsLength = segmentsLengthPool.newElement();
+    var closed = shapeData.c;
+    var pathV = shapeData.v;
+    var pathO = shapeData.o;
+    var pathI = shapeData.i;
+    var i;
+    var len = shapeData._length;
+    var lengths = segmentsLength.lengths;
+    var totalLength = 0;
+    for (i = 0; i < len - 1; i += 1) {
+      lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
+      totalLength += lengths[i].addedLength;
+    }
+    if (closed && len) {
+      lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
+      totalLength += lengths[i].addedLength;
+    }
+    segmentsLength.totalLength = totalLength;
+    return segmentsLength;
+  }
+
+  function BezierData(length) {
+    this.segmentLength = 0;
+    this.points = new Array(length);
+  }
+
+  function PointData(partial, point) {
+    this.partialLength = partial;
+    this.point = point;
+  }
+
+  var buildBezierData = (function () {
+    var storedData = {};
+
+    return function (pt1, pt2, pt3, pt4) {
+      var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
+      if (!storedData[bezierName]) {
+        var curveSegments = getDefaultCurveSegments();
+        var k;
+        var i;
+        var len;
+        var ptCoord;
+        var perc;
+        var addedLength = 0;
+        var ptDistance;
+        var point;
+        var lastPoint = null;
+        if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
+          curveSegments = 2;
+        }
+        var bezierData = new BezierData(curveSegments);
+        len = pt3.length;
+        for (k = 0; k < curveSegments; k += 1) {
+          point = createSizedArray(len);
+          perc = k / (curveSegments - 1);
+          ptDistance = 0;
+          for (i = 0; i < len; i += 1) {
+            ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
+            point[i] = ptCoord;
+            if (lastPoint !== null) {
+              ptDistance += bmPow(point[i] - lastPoint[i], 2);
+            }
+          }
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+          bezierData.points[k] = new PointData(ptDistance, point);
+          lastPoint = point;
+        }
+        bezierData.segmentLength = addedLength;
+        storedData[bezierName] = bezierData;
+      }
+      return storedData[bezierName];
+    };
+  }());
+
+  function getDistancePerc(perc, bezierData) {
+    var percents = bezierData.percents;
+    var lengths = bezierData.lengths;
+    var len = percents.length;
+    var initPos = bmFloor((len - 1) * perc);
+    var lengthPos = perc * bezierData.addedLength;
+    var lPerc = 0;
+    if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
+      return percents[initPos];
+    }
+    var dir = lengths[initPos] > lengthPos ? -1 : 1;
+    var flag = true;
+    while (flag) {
+      if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
+        lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
+        flag = false;
+      } else {
+        initPos += dir;
+      }
+      if (initPos < 0 || initPos >= len - 1) {
+        // FIX for TypedArrays that don't store floating point values with enough accuracy
+        if (initPos === len - 1) {
+          return percents[initPos];
+        }
+        flag = false;
+      }
+    }
+    return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
+  }
+
+  function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
+    var t1 = getDistancePerc(percent, bezierData);
+    var u1 = 1 - t1;
+    var ptX = math.round((u1 * u1 * u1 * pt1[0] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[0] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[0] + t1 * t1 * t1 * pt2[0]) * 1000) / 1000;
+    var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
+    return [ptX, ptY];
+  }
+
+  var bezierSegmentPoints = createTypedArray('float32', 8);
+
+  function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
+    if (startPerc < 0) {
+      startPerc = 0;
+    } else if (startPerc > 1) {
+      startPerc = 1;
+    }
+    var t0 = getDistancePerc(startPerc, bezierData);
+    endPerc = endPerc > 1 ? 1 : endPerc;
+    var t1 = getDistancePerc(endPerc, bezierData);
+    var i;
+    var len = pt1.length;
+    var u0 = 1 - t0;
+    var u1 = 1 - t1;
+    var u0u0u0 = u0 * u0 * u0;
+    var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0t0 = t0 * t0 * t0;
+    //
+    var u0u0u1 = u0 * u0 * u1;
+    var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0t1 = t0 * t0 * t1;
+    //
+    var u0u1u1 = u0 * u1 * u1;
+    var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1t1 = t0 * t1 * t1;
+    //
+    var u1u1u1 = u1 * u1 * u1;
+    var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1t1 = t1 * t1 * t1;
+    for (i = 0; i < len; i += 1) {
+      bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+    }
+
+    return bezierSegmentPoints;
+  }
+
+  return {
+    getSegmentsLength: getSegmentsLength,
+    getNewSegment: getNewSegment,
+    getPointInSegment: getPointInSegment,
+    buildBezierData: buildBezierData,
+    pointOnLine2D: pointOnLine2D,
+    pointOnLine3D: pointOnLine3D,
+  };
+}
+
+const bez = bezFunction();
+
+var initFrame = initialDefaultFrame;
+var mathAbs = Math.abs;
+
+function interpolateValue(frameNum, caching) {
+  var offsetTime = this.offsetTime;
+  var newValue;
+  if (this.propType === 'multidimensional') {
+    newValue = createTypedArray('float32', this.pv.length);
+  }
+  var iterationIndex = caching.lastIndex;
+  var i = iterationIndex;
+  var len = this.keyframes.length - 1;
+  var flag = true;
+  var keyData;
+  var nextKeyData;
+  var keyframeMetadata;
+
+  while (flag) {
+    keyData = this.keyframes[i];
+    nextKeyData = this.keyframes[i + 1];
+    if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
+      if (keyData.h) {
+        keyData = nextKeyData;
+      }
+      iterationIndex = 0;
+      break;
+    }
+    if ((nextKeyData.t - offsetTime) > frameNum) {
+      iterationIndex = i;
+      break;
+    }
+    if (i < len - 1) {
+      i += 1;
+    } else {
+      iterationIndex = 0;
+      flag = false;
+    }
+  }
+  keyframeMetadata = this.keyframesMetadata[i] || {};
+
+  var k;
+  var kLen;
+  var perc;
+  var jLen;
+  var j;
+  var fnc;
+  var nextKeyTime = nextKeyData.t - offsetTime;
+  var keyTime = keyData.t - offsetTime;
+  var endValue;
+  if (keyData.to) {
+    if (!keyframeMetadata.bezierData) {
+      keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
+    }
+    var bezierData = keyframeMetadata.bezierData;
+    if (frameNum >= nextKeyTime || frameNum < keyTime) {
+      var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
+      kLen = bezierData.points[ind].point.length;
+      for (k = 0; k < kLen; k += 1) {
+        newValue[k] = bezierData.points[ind].point[k];
+      }
+      // caching._lastKeyframeIndex = -1;
+    } else {
+      if (keyframeMetadata.__fnct) {
+        fnc = keyframeMetadata.__fnct;
+      } else {
+        fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
+        keyframeMetadata.__fnct = fnc;
+      }
+      perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+      var distanceInLine = bezierData.segmentLength * perc;
+
+      var segmentPerc;
+      var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0;
+      j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0;
+      flag = true;
+      jLen = bezierData.points.length;
+      while (flag) {
+        addedLength += bezierData.points[j].partialLength;
+        if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k];
+          }
+          break;
+        } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
+          segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
+          }
+          break;
+        }
+        if (j < jLen - 1) {
+          j += 1;
+        } else {
+          flag = false;
+        }
+      }
+      caching._lastPoint = j;
+      caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
+      caching._lastKeyframeIndex = i;
+    }
+  } else {
+    var outX;
+    var outY;
+    var inX;
+    var inY;
+    var keyValue;
+    len = keyData.s.length;
+    endValue = nextKeyData.s || keyData.e;
+    if (this.sh && keyData.h !== 1) {
+      if (frameNum >= nextKeyTime) {
+        newValue[0] = endValue[0];
+        newValue[1] = endValue[1];
+        newValue[2] = endValue[2];
+      } else if (frameNum <= keyTime) {
+        newValue[0] = keyData.s[0];
+        newValue[1] = keyData.s[1];
+        newValue[2] = keyData.s[2];
+      } else {
+        var quatStart = createQuaternion(keyData.s);
+        var quatEnd = createQuaternion(endValue);
+        var time = (frameNum - keyTime) / (nextKeyTime - keyTime);
+        quaternionToEuler(newValue, slerp(quatStart, quatEnd, time));
+      }
+    } else {
+      for (i = 0; i < len; i += 1) {
+        if (keyData.h !== 1) {
+          if (frameNum >= nextKeyTime) {
+            perc = 1;
+          } else if (frameNum < keyTime) {
+            perc = 0;
+          } else {
+            if (keyData.o.x.constructor === Array) {
+              if (!keyframeMetadata.__fnct) {
+                keyframeMetadata.__fnct = [];
+              }
+              if (!keyframeMetadata.__fnct[i]) {
+                outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
+                outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
+                inX = keyData.i.x[i] === undefined ? keyData.i.x[0] : keyData.i.x[i];
+                inY = keyData.i.y[i] === undefined ? keyData.i.y[0] : keyData.i.y[i];
+                fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+                keyframeMetadata.__fnct[i] = fnc;
+              } else {
+                fnc = keyframeMetadata.__fnct[i];
+              }
+            } else if (!keyframeMetadata.__fnct) {
+              outX = keyData.o.x;
+              outY = keyData.o.y;
+              inX = keyData.i.x;
+              inY = keyData.i.y;
+              fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+              keyData.keyframeMetadata = fnc;
+            } else {
+              fnc = keyframeMetadata.__fnct;
+            }
+            perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+          }
+        }
+
+        endValue = nextKeyData.s || keyData.e;
+        keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
+
+        if (this.propType === 'multidimensional') {
+          newValue[i] = keyValue;
+        } else {
+          newValue = keyValue;
+        }
+      }
+    }
+  }
+  caching.lastIndex = iterationIndex;
+  return newValue;
+}
+
+// based on @Toji's https://github.com/toji/gl-matrix/
+function slerp(a, b, t) {
+  var out = [];
+  var ax = a[0];
+  var ay = a[1];
+  var az = a[2];
+  var aw = a[3];
+  var bx = b[0];
+  var by = b[1];
+  var bz = b[2];
+  var bw = b[3];
+
+  var omega;
+  var cosom;
+  var sinom;
+  var scale0;
+  var scale1;
+
+  cosom = ax * bx + ay * by + az * bz + aw * bw;
+  if (cosom < 0.0) {
+    cosom = -cosom;
+    bx = -bx;
+    by = -by;
+    bz = -bz;
+    bw = -bw;
+  }
+  if ((1.0 - cosom) > 0.000001) {
+    omega = Math.acos(cosom);
+    sinom = Math.sin(omega);
+    scale0 = Math.sin((1.0 - t) * omega) / sinom;
+    scale1 = Math.sin(t * omega) / sinom;
+  } else {
+    scale0 = 1.0 - t;
+    scale1 = t;
+  }
+  out[0] = scale0 * ax + scale1 * bx;
+  out[1] = scale0 * ay + scale1 * by;
+  out[2] = scale0 * az + scale1 * bz;
+  out[3] = scale0 * aw + scale1 * bw;
+
+  return out;
+}
+
+function quaternionToEuler(out, quat) {
+  var qx = quat[0];
+  var qy = quat[1];
+  var qz = quat[2];
+  var qw = quat[3];
+  var heading = Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy * qy - 2 * qz * qz);
+  var attitude = Math.asin(2 * qx * qy + 2 * qz * qw);
+  var bank = Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx * qx - 2 * qz * qz);
+  out[0] = heading / degToRads;
+  out[1] = attitude / degToRads;
+  out[2] = bank / degToRads;
+}
+
+function createQuaternion(values) {
+  var heading = values[0] * degToRads;
+  var attitude = values[1] * degToRads;
+  var bank = values[2] * degToRads;
+  var c1 = Math.cos(heading / 2);
+  var c2 = Math.cos(attitude / 2);
+  var c3 = Math.cos(bank / 2);
+  var s1 = Math.sin(heading / 2);
+  var s2 = Math.sin(attitude / 2);
+  var s3 = Math.sin(bank / 2);
+  var w = c1 * c2 * c3 - s1 * s2 * s3;
+  var x = s1 * s2 * c3 + c1 * c2 * s3;
+  var y = s1 * c2 * c3 + c1 * s2 * s3;
+  var z = c1 * s2 * c3 - s1 * c2 * s3;
+
+  return [x, y, z, w];
+}
+
+function getValueAtCurrentTime() {
+  var frameNum = this.comp.renderedFrame - this.offsetTime;
+  var initTime = this.keyframes[0].t - this.offsetTime;
+  var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+  if (!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))) {
+    if (this._caching.lastFrame >= frameNum) {
+      this._caching._lastKeyframeIndex = -1;
+      this._caching.lastIndex = 0;
+    }
+
+    var renderResult = this.interpolateValue(frameNum, this._caching);
+    this.pv = renderResult;
+  }
+  this._caching.lastFrame = frameNum;
+  return this.pv;
+}
+
+function setVValue(val) {
+  var multipliedValue;
+  if (this.propType === 'unidimensional') {
+    multipliedValue = val * this.mult;
+    if (mathAbs(this.v - multipliedValue) > 0.00001) {
+      this.v = multipliedValue;
+      this._mdf = true;
+    }
+  } else {
+    var i = 0;
+    var len = this.v.length;
+    while (i < len) {
+      multipliedValue = val[i] * this.mult;
+      if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
+        this.v[i] = multipliedValue;
+        this._mdf = true;
+      }
+      i += 1;
+    }
+  }
+}
+
+function processEffectsSequence() {
+  if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
+    return;
+  }
+  if (this.lock) {
+    this.setVValue(this.pv);
+    return;
+  }
+  this.lock = true;
+  this._mdf = this._isFirstFrame;
+  var i;
+  var len = this.effectsSequence.length;
+  var finalValue = this.kf ? this.pv : this.data.k;
+  for (i = 0; i < len; i += 1) {
+    finalValue = this.effectsSequence[i](finalValue);
+  }
+  this.setVValue(finalValue);
+  this._isFirstFrame = false;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+}
+
+function addEffect(effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.container.addDynamicProperty(this);
+}
+
+function ValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this.v = mult ? data.k * mult : data.k;
+  this.pv = data.k;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.vel = 0;
+  this.effectsSequence = [];
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function MultiDimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.frameId = -1;
+  var i;
+  var len = data.k.length;
+  this.v = createTypedArray('float32', len);
+  this.pv = createTypedArray('float32', len);
+  this.vel = createTypedArray('float32', len);
+  for (i = 0; i < len; i += 1) {
+    this.v[i] = data.k[i] * this.mult;
+    this.pv[i] = data.k[i];
+  }
+  this._isFirstFrame = true;
+  this.effectsSequence = [];
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function KeyframedValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.frameId = -1;
+  this._caching = {
+    lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1,
+  };
+  this.k = true;
+  this.kf = true;
+  this.data = data;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.v = initFrame;
+  this.pv = initFrame;
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.addEffect = addEffect;
+}
+
+function KeyframedMultidimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  var i;
+  var len = data.k.length;
+  var s;
+  var e;
+  var to;
+  var ti;
+  for (i = 0; i < len - 1; i += 1) {
+    if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
+      s = data.k[i].s;
+      e = data.k[i + 1].s;
+      to = data.k[i].to;
+      ti = data.k[i].ti;
+      if ((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2]))) {
+        data.k[i].to = null;
+        data.k[i].ti = null;
+      }
+      if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
+        if (s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) {
+          data.k[i].to = null;
+          data.k[i].ti = null;
+        }
+      }
+    }
+  }
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.data = data;
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.k = true;
+  this.kf = true;
+  this._isFirstFrame = true;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.frameId = -1;
+  var arrLen = data.k[0].s.length;
+  this.v = createTypedArray('float32', arrLen);
+  this.pv = createTypedArray('float32', arrLen);
+  for (i = 0; i < arrLen; i += 1) {
+    this.v[i] = initFrame;
+    this.pv[i] = initFrame;
+  }
+  this._caching = { lastFrame: initFrame, lastIndex: 0, value: createTypedArray('float32', arrLen) };
+  this.addEffect = addEffect;
+}
+
+const PropertyFactory = (function () {
+  function getProp(elem, data, type, mult, container) {
+    if (data.sid) {
+      data = elem.globalData.slotManager.getProp(data);
+    }
+    var p;
+    if (!data.k.length) {
+      p = new ValueProperty(elem, data, mult, container);
+    } else if (typeof (data.k[0]) === 'number') {
+      p = new MultiDimensionalProperty(elem, data, mult, container);
+    } else {
+      switch (type) {
+        case 0:
+          p = new KeyframedValueProperty(elem, data, mult, container);
+          break;
+        case 1:
+          p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
+          break;
+        default:
+          break;
+      }
+    }
+    if (p.effectsSequence.length) {
+      container.addDynamicProperty(p);
+    }
+    return p;
+  }
+
+  var ob = {
+    getProp: getProp,
+  };
+  return ob;
+}());
+
+function DynamicPropertyContainer() {}
+DynamicPropertyContainer.prototype = {
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+      this.container.addDynamicProperty(this);
+      this._isAnimated = true;
+    }
+  },
+  iterateDynamicProperties: function () {
+    this._mdf = false;
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      this.dynamicProperties[i].getValue();
+      if (this.dynamicProperties[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  },
+  initDynamicPropertyContainer: function (container) {
+    this.container = container;
+    this.dynamicProperties = [];
+    this._mdf = false;
+    this._isAnimated = false;
+  },
+};
+
+const pointPool = (function () {
+  function create() {
+    return createTypedArray('float32', 2);
+  }
+  return poolFactory(8, create);
+}());
+
+function ShapePath() {
+  this.c = false;
+  this._length = 0;
+  this._maxLength = 8;
+  this.v = createSizedArray(this._maxLength);
+  this.o = createSizedArray(this._maxLength);
+  this.i = createSizedArray(this._maxLength);
+}
+
+ShapePath.prototype.setPathData = function (closed, len) {
+  this.c = closed;
+  this.setLength(len);
+  var i = 0;
+  while (i < len) {
+    this.v[i] = pointPool.newElement();
+    this.o[i] = pointPool.newElement();
+    this.i[i] = pointPool.newElement();
+    i += 1;
+  }
+};
+
+ShapePath.prototype.setLength = function (len) {
+  while (this._maxLength < len) {
+    this.doubleArrayLength();
+  }
+  this._length = len;
+};
+
+ShapePath.prototype.doubleArrayLength = function () {
+  this.v = this.v.concat(createSizedArray(this._maxLength));
+  this.i = this.i.concat(createSizedArray(this._maxLength));
+  this.o = this.o.concat(createSizedArray(this._maxLength));
+  this._maxLength *= 2;
+};
+
+ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
+  var arr;
+  this._length = Math.max(this._length, pos + 1);
+  if (this._length >= this._maxLength) {
+    this.doubleArrayLength();
+  }
+  switch (type) {
+    case 'v':
+      arr = this.v;
+      break;
+    case 'i':
+      arr = this.i;
+      break;
+    case 'o':
+      arr = this.o;
+      break;
+    default:
+      arr = [];
+      break;
+  }
+  if (!arr[pos] || (arr[pos] && !replace)) {
+    arr[pos] = pointPool.newElement();
+  }
+  arr[pos][0] = x;
+  arr[pos][1] = y;
+};
+
+ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
+  this.setXYAt(vX, vY, 'v', pos, replace);
+  this.setXYAt(oX, oY, 'o', pos, replace);
+  this.setXYAt(iX, iY, 'i', pos, replace);
+};
+
+ShapePath.prototype.reverse = function () {
+  var newPath = new ShapePath();
+  newPath.setPathData(this.c, this._length);
+  var vertices = this.v;
+  var outPoints = this.o;
+  var inPoints = this.i;
+  var init = 0;
+  if (this.c) {
+    newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
+    init = 1;
+  }
+  var cnt = this._length - 1;
+  var len = this._length;
+
+  var i;
+  for (i = init; i < len; i += 1) {
+    newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
+    cnt -= 1;
+  }
+  return newPath;
+};
+
+ShapePath.prototype.length = function () {
+  return this._length;
+};
+
+const shapePool = (function () {
+  function create() {
+    return new ShapePath();
+  }
+
+  function release(shapePath) {
+    var len = shapePath._length;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      pointPool.release(shapePath.v[i]);
+      pointPool.release(shapePath.i[i]);
+      pointPool.release(shapePath.o[i]);
+      shapePath.v[i] = null;
+      shapePath.i[i] = null;
+      shapePath.o[i] = null;
+    }
+    shapePath._length = 0;
+    shapePath.c = false;
+  }
+
+  function clone(shape) {
+    var cloned = factory.newElement();
+    var i;
+    var len = shape._length === undefined ? shape.v.length : shape._length;
+    cloned.setLength(len);
+    cloned.c = shape.c;
+
+    for (i = 0; i < len; i += 1) {
+      cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
+    }
+    return cloned;
+  }
+
+  var factory = poolFactory(4, create, release);
+  factory.clone = clone;
+
+  return factory;
+}());
+
+function ShapeCollection() {
+  this._length = 0;
+  this._maxLength = 4;
+  this.shapes = createSizedArray(this._maxLength);
+}
+
+ShapeCollection.prototype.addShape = function (shapeData) {
+  if (this._length === this._maxLength) {
+    this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
+    this._maxLength *= 2;
+  }
+  this.shapes[this._length] = shapeData;
+  this._length += 1;
+};
+
+ShapeCollection.prototype.releaseShapes = function () {
+  var i;
+  for (i = 0; i < this._length; i += 1) {
+    shapePool.release(this.shapes[i]);
+  }
+  this._length = 0;
+};
+
+const shapeCollectionPool = (function () {
+  var ob = {
+    newShapeCollection: newShapeCollection,
+    release: release,
+  };
+
+  var _length = 0;
+  var _maxLength = 4;
+  var pool = createSizedArray(_maxLength);
+
+  function newShapeCollection() {
+    var shapeCollection;
+    if (_length) {
+      _length -= 1;
+      shapeCollection = pool[_length];
+    } else {
+      shapeCollection = new ShapeCollection();
+    }
+    return shapeCollection;
+  }
+
+  function release(shapeCollection) {
+    var i;
+    var len = shapeCollection._length;
+    for (i = 0; i < len; i += 1) {
+      shapePool.release(shapeCollection.shapes[i]);
+    }
+    shapeCollection._length = 0;
+
+    if (_length === _maxLength) {
+      pool = pooling.double(pool);
+      _maxLength *= 2;
+    }
+    pool[_length] = shapeCollection;
+    _length += 1;
+  }
+
+  return ob;
+}());
+
+const ShapePropertyFactory = (function () {
+  var initFrame = -999999;
+
+  function interpolateShape(frameNum, previousValue, caching) {
+    var iterationIndex = caching.lastIndex;
+    var keyPropS;
+    var keyPropE;
+    var isHold;
+    var j;
+    var k;
+    var jLen;
+    var kLen;
+    var perc;
+    var vertexValue;
+    var kf = this.keyframes;
+    if (frameNum < kf[0].t - this.offsetTime) {
+      keyPropS = kf[0].s[0];
+      isHold = true;
+      iterationIndex = 0;
+    } else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) {
+      keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
+      /* if(kf[kf.length - 1].s){
+                keyPropS = kf[kf.length - 1].s[0];
+            }else{
+                keyPropS = kf[kf.length - 2].e[0];
+            } */
+      isHold = true;
+    } else {
+      var i = iterationIndex;
+      var len = kf.length - 1;
+      var flag = true;
+      var keyData;
+      var nextKeyData;
+      var keyframeMetadata;
+      while (flag) {
+        keyData = kf[i];
+        nextKeyData = kf[i + 1];
+        if ((nextKeyData.t - this.offsetTime) > frameNum) {
+          break;
+        }
+        if (i < len - 1) {
+          i += 1;
+        } else {
+          flag = false;
+        }
+      }
+      keyframeMetadata = this.keyframesMetadata[i] || {};
+      isHold = keyData.h === 1;
+      iterationIndex = i;
+      if (!isHold) {
+        if (frameNum >= nextKeyData.t - this.offsetTime) {
+          perc = 1;
+        } else if (frameNum < keyData.t - this.offsetTime) {
+          perc = 0;
+        } else {
+          var fnc;
+          if (keyframeMetadata.__fnct) {
+            fnc = keyframeMetadata.__fnct;
+          } else {
+            fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
+            keyframeMetadata.__fnct = fnc;
+          }
+          perc = fnc((frameNum - (keyData.t - this.offsetTime)) / ((nextKeyData.t - this.offsetTime) - (keyData.t - this.offsetTime)));
+        }
+        keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
+      }
+      keyPropS = keyData.s[0];
+    }
+    jLen = previousValue._length;
+    kLen = keyPropS.i[0].length;
+    caching.lastIndex = iterationIndex;
+
+    for (j = 0; j < jLen; j += 1) {
+      for (k = 0; k < kLen; k += 1) {
+        vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
+        previousValue.i[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc;
+        previousValue.o[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc;
+        previousValue.v[j][k] = vertexValue;
+      }
+    }
+  }
+
+  function interpolateShapeCurrentTime() {
+    var frameNum = this.comp.renderedFrame - this.offsetTime;
+    var initTime = this.keyframes[0].t - this.offsetTime;
+    var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+    var lastFrame = this._caching.lastFrame;
+    if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) {
+      /// /
+      this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
+      this.interpolateShape(frameNum, this.pv, this._caching);
+      /// /
+    }
+    this._caching.lastFrame = frameNum;
+    return this.pv;
+  }
+
+  function resetShape() {
+    this.paths = this.localShapeCollection;
+  }
+
+  function shapesEqual(shape1, shape2) {
+    if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
+      return false;
+    }
+    var i;
+    var len = shape1._length;
+    for (i = 0; i < len; i += 1) {
+      if (shape1.v[i][0] !== shape2.v[i][0]
+            || shape1.v[i][1] !== shape2.v[i][1]
+            || shape1.o[i][0] !== shape2.o[i][0]
+            || shape1.o[i][1] !== shape2.o[i][1]
+            || shape1.i[i][0] !== shape2.i[i][0]
+            || shape1.i[i][1] !== shape2.i[i][1]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  function setVValue(newPath) {
+    if (!shapesEqual(this.v, newPath)) {
+      this.v = shapePool.clone(newPath);
+      this.localShapeCollection.releaseShapes();
+      this.localShapeCollection.addShape(this.v);
+      this._mdf = true;
+      this.paths = this.localShapeCollection;
+    }
+  }
+
+  function processEffectsSequence() {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    } if (!this.effectsSequence.length) {
+      this._mdf = false;
+      return;
+    }
+    if (this.lock) {
+      this.setVValue(this.pv);
+      return;
+    }
+    this.lock = true;
+    this._mdf = false;
+    var finalValue;
+    if (this.kf) {
+      finalValue = this.pv;
+    } else if (this.data.ks) {
+      finalValue = this.data.ks.k;
+    } else {
+      finalValue = this.data.pt.k;
+    }
+    var i;
+    var len = this.effectsSequence.length;
+    for (i = 0; i < len; i += 1) {
+      finalValue = this.effectsSequence[i](finalValue);
+    }
+    this.setVValue(finalValue);
+    this.lock = false;
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function ShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.container = elem;
+    this.elem = elem;
+    this.data = data;
+    this.k = false;
+    this.kf = false;
+    this._mdf = false;
+    var pathData = type === 3 ? data.pt.k : data.ks.k;
+    this.v = shapePool.clone(pathData);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.reset = resetShape;
+    this.effectsSequence = [];
+  }
+
+  function addEffect(effectFunction) {
+    this.effectsSequence.push(effectFunction);
+    this.container.addDynamicProperty(this);
+  }
+
+  ShapeProperty.prototype.interpolateShape = interpolateShape;
+  ShapeProperty.prototype.getValue = processEffectsSequence;
+  ShapeProperty.prototype.setVValue = setVValue;
+  ShapeProperty.prototype.addEffect = addEffect;
+
+  function KeyframedShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.elem = elem;
+    this.container = elem;
+    this.offsetTime = elem.data.st;
+    this.keyframes = type === 3 ? data.pt.k : data.ks.k;
+    this.keyframesMetadata = [];
+    this.k = true;
+    this.kf = true;
+    var len = this.keyframes[0].s[0].i.length;
+    this.v = shapePool.newElement();
+    this.v.setPathData(this.keyframes[0].s[0].c, len);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.lastFrame = initFrame;
+    this.reset = resetShape;
+    this._caching = { lastFrame: initFrame, lastIndex: 0 };
+    this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
+  }
+  KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
+  KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
+  KeyframedShapeProperty.prototype.setVValue = setVValue;
+  KeyframedShapeProperty.prototype.addEffect = addEffect;
+
+  var EllShapeProperty = (function () {
+    var cPoint = roundCorner;
+
+    function EllShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 4);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.paths = this.localShapeCollection;
+      this.localShapeCollection.addShape(this.v);
+      this.d = data.d;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertEllToPath();
+      }
+    }
+
+    EllShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+
+        if (this._mdf) {
+          this.convertEllToPath();
+        }
+      },
+      convertEllToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var s0 = this.s.v[0] / 2;
+        var s1 = this.s.v[1] / 2;
+        var _cw = this.d !== 3;
+        var _v = this.v;
+        _v.v[0][0] = p0;
+        _v.v[0][1] = p1 - s1;
+        _v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.v[1][1] = p1;
+        _v.v[2][0] = p0;
+        _v.v[2][1] = p1 + s1;
+        _v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.v[3][1] = p1;
+        _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.i[0][1] = p1 - s1;
+        _v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.i[1][1] = p1 - s1 * cPoint;
+        _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.i[2][1] = p1 + s1;
+        _v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.i[3][1] = p1 + s1 * cPoint;
+        _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.o[0][1] = p1 - s1;
+        _v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.o[1][1] = p1 + s1 * cPoint;
+        _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.o[2][1] = p1 + s1;
+        _v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.o[3][1] = p1 - s1 * cPoint;
+      },
+    };
+
+    extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
+
+    return EllShapePropertyFactory;
+  }());
+
+  var StarShapeProperty = (function () {
+    function StarShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 0);
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.data = data;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      if (data.sy === 1) {
+        this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
+        this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
+        this.convertToPath = this.convertStarToPath;
+      } else {
+        this.convertToPath = this.convertPolygonToPath;
+      }
+      this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
+      this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this);
+      this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertToPath();
+      }
+    }
+
+    StarShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertToPath();
+        }
+      },
+      convertStarToPath: function () {
+        var numPts = Math.floor(this.pt.v) * 2;
+        var angle = (Math.PI * 2) / numPts;
+        /* this.v.v.length = numPts;
+                this.v.i.length = numPts;
+                this.v.o.length = numPts; */
+        var longFlag = true;
+        var longRad = this.or.v;
+        var shortRad = this.ir.v;
+        var longRound = this.os.v;
+        var shortRound = this.is.v;
+        var longPerimSegment = (2 * Math.PI * longRad) / (numPts * 2);
+        var shortPerimSegment = (2 * Math.PI * shortRad) / (numPts * 2);
+        var i;
+        var rad;
+        var roundness;
+        var perimSegment;
+        var currentAng = -Math.PI / 2;
+        currentAng += this.r.v;
+        var dir = this.data.d === 3 ? -1 : 1;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          rad = longFlag ? longRad : shortRad;
+          roundness = longFlag ? longRound : shortRound;
+          perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
+          /* this.v.v[i] = [x,y];
+                    this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
+                    this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
+                    this.v._length = numPts; */
+          longFlag = !longFlag;
+          currentAng += angle * dir;
+        }
+      },
+      convertPolygonToPath: function () {
+        var numPts = Math.floor(this.pt.v);
+        var angle = (Math.PI * 2) / numPts;
+        var rad = this.or.v;
+        var roundness = this.os.v;
+        var perimSegment = (2 * Math.PI * rad) / (numPts * 4);
+        var i;
+        var currentAng = -Math.PI * 0.5;
+        var dir = this.data.d === 3 ? -1 : 1;
+        currentAng += this.r.v;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+          currentAng += angle * dir;
+        }
+        this.paths.length = 0;
+        this.paths[0] = this.v;
+      },
+
+    };
+    extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
+
+    return StarShapePropertyFactory;
+  }());
+
+  var RectShapeProperty = (function () {
+    function RectShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.c = true;
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertRectToPath();
+      }
+    }
+
+    RectShapePropertyFactory.prototype = {
+      convertRectToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var v0 = this.s.v[0] / 2;
+        var v1 = this.s.v[1] / 2;
+        var round = bmMin(v0, v1, this.r.v);
+        var cPoint = round * (1 - roundCorner);
+        this.v._length = 0;
+
+        if (this.d === 2 || this.d === 1) {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
+          this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2);
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3);
+          }
+        } else {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true);
+          }
+        }
+      },
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertRectToPath();
+        }
+      },
+      reset: resetShape,
+    };
+    extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
+
+    return RectShapePropertyFactory;
+  }());
+
+  function getShapeProp(elem, data, type) {
+    var prop;
+    if (type === 3 || type === 4) {
+      var dataProp = type === 3 ? data.pt : data.ks;
+      var keys = dataProp.k;
+      if (keys.length) {
+        prop = new KeyframedShapeProperty(elem, data, type);
+      } else {
+        prop = new ShapeProperty(elem, data, type);
+      }
+    } else if (type === 5) {
+      prop = new RectShapeProperty(elem, data);
+    } else if (type === 6) {
+      prop = new EllShapeProperty(elem, data);
+    } else if (type === 7) {
+      prop = new StarShapeProperty(elem, data);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  }
+
+  function getConstructorFunction() {
+    return ShapeProperty;
+  }
+
+  function getKeyframedConstructorFunction() {
+    return KeyframedShapeProperty;
+  }
+
+  var ob = {};
+  ob.getShapeProp = getShapeProp;
+  ob.getConstructorFunction = getConstructorFunction;
+  ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction;
+  return ob;
+}());
+
+/*!
+ Transformation Matrix v2.0
+ (c) Epistemex 2014-2015
+ www.epistemex.com
+ By Ken Fyrstenberg
+ Contributions by leeoniya.
+ License: MIT, header required.
+ */
+
+/**
+ * 2D transformation matrix object initialized with identity matrix.
+ *
+ * The matrix can synchronize a canvas context by supplying the context
+ * as an argument, or later apply current absolute transform to an
+ * existing context.
+ *
+ * All values are handled as floating point values.
+ *
+ * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix
+ * @prop {number} a - scale x
+ * @prop {number} b - shear y
+ * @prop {number} c - shear x
+ * @prop {number} d - scale y
+ * @prop {number} e - translate x
+ * @prop {number} f - translate y
+ * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context
+ * @constructor
+ */
+
+const Matrix = (function () {
+  var _cos = Math.cos;
+  var _sin = Math.sin;
+  var _tan = Math.tan;
+  var _rnd = Math.round;
+
+  function reset() {
+    this.props[0] = 1;
+    this.props[1] = 0;
+    this.props[2] = 0;
+    this.props[3] = 0;
+    this.props[4] = 0;
+    this.props[5] = 1;
+    this.props[6] = 0;
+    this.props[7] = 0;
+    this.props[8] = 0;
+    this.props[9] = 0;
+    this.props[10] = 1;
+    this.props[11] = 0;
+    this.props[12] = 0;
+    this.props[13] = 0;
+    this.props[14] = 0;
+    this.props[15] = 1;
+    return this;
+  }
+
+  function rotate(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function rotateX(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateY(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateZ(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function shear(sx, sy) {
+    return this._t(1, sy, sx, 1, 0, 0);
+  }
+
+  function skew(ax, ay) {
+    return this.shear(_tan(ax), _tan(ay));
+  }
+
+  function skewFromAxis(ax, angle) {
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+    // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+  }
+
+  function scale(sx, sy, sz) {
+    if (!sz && sz !== 0) {
+      sz = 1;
+    }
+    if (sx === 1 && sy === 1 && sz === 1) {
+      return this;
+    }
+    return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
+  }
+
+  function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
+    this.props[0] = a;
+    this.props[1] = b;
+    this.props[2] = c;
+    this.props[3] = d;
+    this.props[4] = e;
+    this.props[5] = f;
+    this.props[6] = g;
+    this.props[7] = h;
+    this.props[8] = i;
+    this.props[9] = j;
+    this.props[10] = k;
+    this.props[11] = l;
+    this.props[12] = m;
+    this.props[13] = n;
+    this.props[14] = o;
+    this.props[15] = p;
+    return this;
+  }
+
+  function translate(tx, ty, tz) {
+    tz = tz || 0;
+    if (tx !== 0 || ty !== 0 || tz !== 0) {
+      return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
+    }
+    return this;
+  }
+
+  function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
+    var _p = this.props;
+
+    if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
+      // NOTE: commenting this condition because TurboFan deoptimizes code when present
+      // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
+      _p[12] = _p[12] * a2 + _p[15] * m2;
+      _p[13] = _p[13] * f2 + _p[15] * n2;
+      _p[14] = _p[14] * k2 + _p[15] * o2;
+      _p[15] *= p2;
+      // }
+      this._identityCalculated = false;
+      return this;
+    }
+
+    var a1 = _p[0];
+    var b1 = _p[1];
+    var c1 = _p[2];
+    var d1 = _p[3];
+    var e1 = _p[4];
+    var f1 = _p[5];
+    var g1 = _p[6];
+    var h1 = _p[7];
+    var i1 = _p[8];
+    var j1 = _p[9];
+    var k1 = _p[10];
+    var l1 = _p[11];
+    var m1 = _p[12];
+    var n1 = _p[13];
+    var o1 = _p[14];
+    var p1 = _p[15];
+
+    /* matrix order (canvas compatible):
+         * ace
+         * bdf
+         * 001
+         */
+    _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
+    _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
+    _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
+    _p[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2;
+
+    _p[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2;
+    _p[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2;
+    _p[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2;
+    _p[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2;
+
+    _p[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2;
+    _p[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2;
+    _p[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2;
+    _p[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2;
+
+    _p[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2;
+    _p[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2;
+    _p[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2;
+    _p[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2;
+
+    this._identityCalculated = false;
+    return this;
+  }
+
+  function multiply(matrix) {
+    var matrixProps = matrix.props;
+    return this.transform(
+      matrixProps[0],
+      matrixProps[1],
+      matrixProps[2],
+      matrixProps[3],
+      matrixProps[4],
+      matrixProps[5],
+      matrixProps[6],
+      matrixProps[7],
+      matrixProps[8],
+      matrixProps[9],
+      matrixProps[10],
+      matrixProps[11],
+      matrixProps[12],
+      matrixProps[13],
+      matrixProps[14],
+      matrixProps[15]
+    );
+  }
+
+  function isIdentity() {
+    if (!this._identityCalculated) {
+      this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
+      this._identityCalculated = true;
+    }
+    return this._identity;
+  }
+
+  function equals(matr) {
+    var i = 0;
+    while (i < 16) {
+      if (matr.props[i] !== this.props[i]) {
+        return false;
+      }
+      i += 1;
+    }
+    return true;
+  }
+
+  function clone(matr) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      matr.props[i] = this.props[i];
+    }
+    return matr;
+  }
+
+  function cloneFromProps(props) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      this.props[i] = props[i];
+    }
+  }
+
+  function applyToPoint(x, y, z) {
+    return {
+      x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+      y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+      z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+    };
+    /* return {
+         x: x * me.a + y * me.c + me.e,
+         y: x * me.b + y * me.d + me.f
+         }; */
+  }
+  function applyToX(x, y, z) {
+    return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
+  }
+  function applyToY(x, y, z) {
+    return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
+  }
+  function applyToZ(x, y, z) {
+    return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
+  }
+
+  function getInverseMatrix() {
+    var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
+    var a = this.props[5] / determinant;
+    var b = -this.props[1] / determinant;
+    var c = -this.props[4] / determinant;
+    var d = this.props[0] / determinant;
+    var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12]) / determinant;
+    var f = -(this.props[0] * this.props[13] - this.props[1] * this.props[12]) / determinant;
+    var inverseMatrix = new Matrix();
+    inverseMatrix.props[0] = a;
+    inverseMatrix.props[1] = b;
+    inverseMatrix.props[4] = c;
+    inverseMatrix.props[5] = d;
+    inverseMatrix.props[12] = e;
+    inverseMatrix.props[13] = f;
+    return inverseMatrix;
+  }
+
+  function inversePoint(pt) {
+    var inverseMatrix = this.getInverseMatrix();
+    return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
+  }
+
+  function inversePoints(pts) {
+    var i;
+    var len = pts.length;
+    var retPts = [];
+    for (i = 0; i < len; i += 1) {
+      retPts[i] = inversePoint(pts[i]);
+    }
+    return retPts;
+  }
+
+  function applyToTriplePoints(pt1, pt2, pt3) {
+    var arr = createTypedArray('float32', 6);
+    if (this.isIdentity()) {
+      arr[0] = pt1[0];
+      arr[1] = pt1[1];
+      arr[2] = pt2[0];
+      arr[3] = pt2[1];
+      arr[4] = pt3[0];
+      arr[5] = pt3[1];
+    } else {
+      var p0 = this.props[0];
+      var p1 = this.props[1];
+      var p4 = this.props[4];
+      var p5 = this.props[5];
+      var p12 = this.props[12];
+      var p13 = this.props[13];
+      arr[0] = pt1[0] * p0 + pt1[1] * p4 + p12;
+      arr[1] = pt1[0] * p1 + pt1[1] * p5 + p13;
+      arr[2] = pt2[0] * p0 + pt2[1] * p4 + p12;
+      arr[3] = pt2[0] * p1 + pt2[1] * p5 + p13;
+      arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
+      arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
+    }
+    return arr;
+  }
+
+  function applyToPointArray(x, y, z) {
+    var arr;
+    if (this.isIdentity()) {
+      arr = [x, y, z];
+    } else {
+      arr = [
+        x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+        x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+        x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+      ];
+    }
+    return arr;
+  }
+
+  function applyToPointStringified(x, y) {
+    if (this.isIdentity()) {
+      return x + ',' + y;
+    }
+    var _p = this.props;
+    return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
+  }
+
+  function toCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var i = 0;
+    var props = this.props;
+    var cssValue = 'matrix3d(';
+    var v = 10000;
+    while (i < 16) {
+      cssValue += _rnd(props[i] * v) / v;
+      cssValue += i === 15 ? ')' : ',';
+      i += 1;
+    }
+    return cssValue;
+  }
+
+  function roundMatrixProperty(val) {
+    var v = 10000;
+    if ((val < 0.000001 && val > 0) || (val > -0.000001 && val < 0)) {
+      return _rnd(val * v) / v;
+    }
+    return val;
+  }
+
+  function to2dCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var props = this.props;
+    var _a = roundMatrixProperty(props[0]);
+    var _b = roundMatrixProperty(props[1]);
+    var _c = roundMatrixProperty(props[4]);
+    var _d = roundMatrixProperty(props[5]);
+    var _e = roundMatrixProperty(props[12]);
+    var _f = roundMatrixProperty(props[13]);
+    return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
+  }
+
+  return function () {
+    this.reset = reset;
+    this.rotate = rotate;
+    this.rotateX = rotateX;
+    this.rotateY = rotateY;
+    this.rotateZ = rotateZ;
+    this.skew = skew;
+    this.skewFromAxis = skewFromAxis;
+    this.shear = shear;
+    this.scale = scale;
+    this.setTransform = setTransform;
+    this.translate = translate;
+    this.transform = transform;
+    this.multiply = multiply;
+    this.applyToPoint = applyToPoint;
+    this.applyToX = applyToX;
+    this.applyToY = applyToY;
+    this.applyToZ = applyToZ;
+    this.applyToPointArray = applyToPointArray;
+    this.applyToTriplePoints = applyToTriplePoints;
+    this.applyToPointStringified = applyToPointStringified;
+    this.toCSS = toCSS;
+    this.to2dCSS = to2dCSS;
+    this.clone = clone;
+    this.cloneFromProps = cloneFromProps;
+    this.equals = equals;
+    this.inversePoints = inversePoints;
+    this.inversePoint = inversePoint;
+    this.getInverseMatrix = getInverseMatrix;
+    this._t = this.transform;
+    this.isIdentity = isIdentity;
+    this._identity = true;
+    this._identityCalculated = false;
+
+    this.props = createTypedArray('float32', 16);
+    this.reset();
+  };
+}());
+
+const lottie = {};
+var standalone = '__[STANDALONE]__';
+var animationData = '__[ANIMATIONDATA]__';
+var renderer = '';
+
+function setLocation(href) {
+  setLocationHref(href);
+}
+
+function searchAnimations() {
+  if (standalone === true) {
+    animationManager.searchAnimations(animationData, standalone, renderer);
+  } else {
+    animationManager.searchAnimations();
+  }
+}
+
+function setSubframeRendering(flag) {
+  setSubframeEnabled(flag);
+}
+
+function setPrefix(prefix) {
+  setIdPrefix(prefix);
+}
+
+function loadAnimation(params) {
+  if (standalone === true) {
+    params.animationData = JSON.parse(animationData);
+  }
+  return animationManager.loadAnimation(params);
+}
+
+function setQuality(value) {
+  if (typeof value === 'string') {
+    switch (value) {
+      case 'high':
+        setDefaultCurveSegments(200);
+        break;
+      default:
+      case 'medium':
+        setDefaultCurveSegments(50);
+        break;
+      case 'low':
+        setDefaultCurveSegments(10);
+        break;
+    }
+  } else if (!isNaN(value) && value > 1) {
+    setDefaultCurveSegments(value);
+  }
+  if (getDefaultCurveSegments() >= 50) {
+    roundValues(false);
+  } else {
+    roundValues(true);
+  }
+}
+
+function inBrowser() {
+  return typeof navigator !== 'undefined';
+}
+
+function installPlugin(type, plugin) {
+  if (type === 'expressions') {
+    setExpressionsPlugin(plugin);
+  }
+}
+
+function getFactory(name) {
+  switch (name) {
+    case 'propertyFactory':
+      return PropertyFactory;
+    case 'shapePropertyFactory':
+      return ShapePropertyFactory;
+    case 'matrix':
+      return Matrix;
+    default:
+      return null;
+  }
+}
+
+lottie.play = animationManager.play;
+lottie.pause = animationManager.pause;
+lottie.setLocationHref = setLocation;
+lottie.togglePause = animationManager.togglePause;
+lottie.setSpeed = animationManager.setSpeed;
+lottie.setDirection = animationManager.setDirection;
+lottie.stop = animationManager.stop;
+lottie.searchAnimations = searchAnimations;
+lottie.registerAnimation = animationManager.registerAnimation;
+lottie.loadAnimation = loadAnimation;
+lottie.setSubframeRendering = setSubframeRendering;
+lottie.resize = animationManager.resize;
+// lottie.start = start;
+lottie.goToAndStop = animationManager.goToAndStop;
+lottie.destroy = animationManager.destroy;
+lottie.setQuality = setQuality;
+lottie.inBrowser = inBrowser;
+lottie.installPlugin = installPlugin;
+lottie.freeze = animationManager.freeze;
+lottie.unfreeze = animationManager.unfreeze;
+lottie.setVolume = animationManager.setVolume;
+lottie.mute = animationManager.mute;
+lottie.unmute = animationManager.unmute;
+lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations;
+lottie.useWebWorker = setWebWorker;
+lottie.setIDPrefix = setPrefix;
+lottie.__getFactory = getFactory;
+lottie.version = '[[BM_VERSION]]';
+
+function checkReady() {
+  if (document.readyState === 'complete') {
+    clearInterval(readyStateCheckInterval);
+    searchAnimations();
+  }
+}
+
+function getQueryVariable(variable) {
+  var vars = queryString.split('&');
+  for (var i = 0; i < vars.length; i += 1) {
+    var pair = vars[i].split('=');
+    if (decodeURIComponent(pair[0]) == variable) { // eslint-disable-line eqeqeq
+      return decodeURIComponent(pair[1]);
+    }
+  }
+  return null;
+}
+var queryString = '';
+if (standalone) {
+  var scripts = document.getElementsByTagName('script');
+  var index = scripts.length - 1;
+  var myScript = scripts[index] || {
+    src: '',
+  };
+  queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
+  renderer = getQueryVariable('renderer');
+}
+var readyStateCheckInterval = setInterval(checkReady, 100);
+
+// this adds bodymovin to the window object for backwards compatibility
+try {
+  if (!(typeof exports === 'object' && typeof module !== 'undefined')
+    && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
+  ) {
+    window.bodymovin = lottie;
+  }
+} catch (err) {
+  //
+}
+
+const ShapeModifiers = (function () {
+  var ob = {};
+  var modifiers = {};
+  ob.registerModifier = registerModifier;
+  ob.getModifier = getModifier;
+
+  function registerModifier(nm, factory) {
+    if (!modifiers[nm]) {
+      modifiers[nm] = factory;
+    }
+  }
+
+  function getModifier(nm, elem, data) {
+    return new modifiers[nm](elem, data);
+  }
+
+  return ob;
+}());
+
+function ShapeModifier() {}
+ShapeModifier.prototype.initModifierProperties = function () {};
+ShapeModifier.prototype.addShapeToModifier = function () {};
+ShapeModifier.prototype.addShape = function (data) {
+  if (!this.closed) {
+    // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
+    data.sh.container.addDynamicProperty(data.sh);
+    var shapeData = { shape: data.sh, data: data, localShapeCollection: shapeCollectionPool.newShapeCollection() };
+    this.shapes.push(shapeData);
+    this.addShapeToModifier(shapeData);
+    if (this._isAnimated) {
+      data.setAsAnimated();
+    }
+  }
+};
+ShapeModifier.prototype.init = function (elem, data) {
+  this.shapes = [];
+  this.elem = elem;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, data);
+  this.frameId = initialDefaultFrame;
+  this.closed = false;
+  this.k = false;
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+ShapeModifier.prototype.processKeys = function () {
+  if (this.elem.globalData.frameId === this.frameId) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+extendPrototype([DynamicPropertyContainer], ShapeModifier);
+
+function TrimModifier() {
+}
+extendPrototype([ShapeModifier], TrimModifier);
+TrimModifier.prototype.initModifierProperties = function (elem, data) {
+  this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this);
+  this.sValue = 0;
+  this.eValue = 0;
+  this.getValue = this.processKeys;
+  this.m = data.m;
+  this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
+};
+
+TrimModifier.prototype.addShapeToModifier = function (shapeData) {
+  shapeData.pathsData = [];
+};
+
+TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
+  var segments = [];
+  if (e <= 1) {
+    segments.push({
+      s: s,
+      e: e,
+    });
+  } else if (s >= 1) {
+    segments.push({
+      s: s - 1,
+      e: e - 1,
+    });
+  } else {
+    segments.push({
+      s: s,
+      e: 1,
+    });
+    segments.push({
+      s: 0,
+      e: e - 1,
+    });
+  }
+  var shapeSegments = [];
+  var i;
+  var len = segments.length;
+  var segmentOb;
+  for (i = 0; i < len; i += 1) {
+    segmentOb = segments[i];
+    if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
+      var shapeS;
+      var shapeE;
+      if (segmentOb.s * totalModifierLength <= addedLength) {
+        shapeS = 0;
+      } else {
+        shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
+      }
+      if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
+        shapeE = 1;
+      } else {
+        shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength);
+      }
+      shapeSegments.push([shapeS, shapeE]);
+    }
+  }
+  if (!shapeSegments.length) {
+    shapeSegments.push([0, 0]);
+  }
+  return shapeSegments;
+};
+
+TrimModifier.prototype.releasePathsData = function (pathsData) {
+  var i;
+  var len = pathsData.length;
+  for (i = 0; i < len; i += 1) {
+    segmentsLengthPool.release(pathsData[i]);
+  }
+  pathsData.length = 0;
+  return pathsData;
+};
+
+TrimModifier.prototype.processShapes = function (_isFirstFrame) {
+  var s;
+  var e;
+  if (this._mdf || _isFirstFrame) {
+    var o = (this.o.v % 360) / 360;
+    if (o < 0) {
+      o += 1;
+    }
+    if (this.s.v > 1) {
+      s = 1 + o;
+    } else if (this.s.v < 0) {
+      s = 0 + o;
+    } else {
+      s = this.s.v + o;
+    }
+    if (this.e.v > 1) {
+      e = 1 + o;
+    } else if (this.e.v < 0) {
+      e = 0 + o;
+    } else {
+      e = this.e.v + o;
+    }
+
+    if (s > e) {
+      var _s = s;
+      s = e;
+      e = _s;
+    }
+    s = Math.round(s * 10000) * 0.0001;
+    e = Math.round(e * 10000) * 0.0001;
+    this.sValue = s;
+    this.eValue = e;
+  } else {
+    s = this.sValue;
+    e = this.eValue;
+  }
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var pathsData;
+  var pathData;
+  var totalShapeLength;
+  var totalModifierLength = 0;
+
+  if (e === s) {
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].localShapeCollection.releaseShapes();
+      this.shapes[i].shape._mdf = true;
+      this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
+      if (this._mdf) {
+        this.shapes[i].pathsData.length = 0;
+      }
+    }
+  } else if (!((e === 1 && s === 0) || (e === 0 && s === 1))) {
+    var segments = [];
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
+      if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
+        shapeData.shape.paths = shapeData.localShapeCollection;
+      } else {
+        shapePaths = shapeData.shape.paths;
+        jLen = shapePaths._length;
+        totalShapeLength = 0;
+        if (!shapeData.shape._mdf && shapeData.pathsData.length) {
+          totalShapeLength = shapeData.totalShapeLength;
+        } else {
+          pathsData = this.releasePathsData(shapeData.pathsData);
+          for (j = 0; j < jLen; j += 1) {
+            pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
+            pathsData.push(pathData);
+            totalShapeLength += pathData.totalLength;
+          }
+          shapeData.totalShapeLength = totalShapeLength;
+          shapeData.pathsData = pathsData;
+        }
+
+        totalModifierLength += totalShapeLength;
+        shapeData.shape._mdf = true;
+      }
+    }
+    var shapeS = s;
+    var shapeE = e;
+    var addedLength = 0;
+    var edges;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shapeData = this.shapes[i];
+      if (shapeData.shape._mdf) {
+        localShapeCollection = shapeData.localShapeCollection;
+        localShapeCollection.releaseShapes();
+        // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
+        if (this.m === 2 && len > 1) {
+          edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
+          addedLength += shapeData.totalShapeLength;
+        } else {
+          edges = [[shapeS, shapeE]];
+        }
+        jLen = edges.length;
+        for (j = 0; j < jLen; j += 1) {
+          shapeS = edges[j][0];
+          shapeE = edges[j][1];
+          segments.length = 0;
+          if (shapeE <= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength * shapeE,
+            });
+          } else if (shapeS >= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * (shapeS - 1),
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          } else {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength,
+            });
+            segments.push({
+              s: 0,
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          }
+          var newShapesData = this.addShapes(shapeData, segments[0]);
+          if (segments[0].s !== segments[0].e) {
+            if (segments.length > 1) {
+              var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
+              if (lastShapeInCollection.c) {
+                var lastShape = newShapesData.pop();
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1], lastShape);
+              } else {
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1]);
+              }
+            }
+            this.addPaths(newShapesData, localShapeCollection);
+          }
+        }
+        shapeData.shape.paths = localShapeCollection;
+      }
+    }
+  } else if (this._mdf) {
+    for (i = 0; i < len; i += 1) {
+      // Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween.
+      // Don't remove this even if it's losing cached info.
+      this.shapes[i].pathsData.length = 0;
+      this.shapes[i].shape._mdf = true;
+    }
+  }
+};
+
+TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
+  var i;
+  var len = newPaths.length;
+  for (i = 0; i < len; i += 1) {
+    localShapeCollection.addShape(newPaths[i]);
+  }
+};
+
+TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
+  shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
+  shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
+  }
+  shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
+  shapePath.setXYAt(points[1], points[5], 'o', pos);
+  shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(points[0], points[4], 'v', pos);
+  }
+  shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
+  var pathsData = shapeData.pathsData;
+  var shapePaths = shapeData.shape.paths.shapes;
+  var i;
+  var len = shapeData.shape.paths._length;
+  var j;
+  var jLen;
+  var addedLength = 0;
+  var currentLengthData;
+  var segmentCount;
+  var lengths;
+  var segment;
+  var shapes = [];
+  var initPos;
+  var newShape = true;
+  if (!shapePath) {
+    shapePath = shapePool.newElement();
+    segmentCount = 0;
+    initPos = 0;
+  } else {
+    segmentCount = shapePath._length;
+    initPos = shapePath._length;
+  }
+  shapes.push(shapePath);
+  for (i = 0; i < len; i += 1) {
+    lengths = pathsData[i].lengths;
+    shapePath.c = shapePaths[i].c;
+    jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
+    for (j = 1; j < jLen; j += 1) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
+        addedLength += currentLengthData.addedLength;
+        shapePath.c = false;
+      } else if (addedLength > shapeSegment.e) {
+        shapePath.c = false;
+        break;
+      } else {
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+        addedLength += currentLengthData.addedLength;
+        segmentCount += 1;
+      }
+    }
+    if (shapePaths[i].c && lengths.length) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength <= shapeSegment.e) {
+        var segmentLength = lengths[j - 1].addedLength;
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+      } else {
+        shapePath.c = false;
+      }
+      addedLength += currentLengthData.addedLength;
+      segmentCount += 1;
+    }
+    if (shapePath._length) {
+      shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
+      shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
+    }
+    if (addedLength > shapeSegment.e) {
+      break;
+    }
+    if (i < len - 1) {
+      shapePath = shapePool.newElement();
+      newShape = true;
+      shapes.push(shapePath);
+      segmentCount = 0;
+    }
+  }
+  return shapes;
+};
+
+function PuckerAndBloatModifier() {}
+extendPrototype([ShapeModifier], PuckerAndBloatModifier);
+PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this._isAnimated = !!this.amount.effectsSequence.length;
+};
+
+PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
+  var percent = amount / 100;
+  var centerPoint = [0, 0];
+  var pathLength = path._length;
+  var i = 0;
+  for (i = 0; i < pathLength; i += 1) {
+    centerPoint[0] += path.v[i][0];
+    centerPoint[1] += path.v[i][1];
+  }
+  centerPoint[0] /= pathLength;
+  centerPoint[1] /= pathLength;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < pathLength; i += 1) {
+    vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
+    vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
+    oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent;
+    oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent;
+    iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent;
+    iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
+    clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
+  }
+  return clonedPath;
+};
+
+PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+const TransformPropertyFactory = (function () {
+  var defaultVector = [0, 0];
+
+  function applyToMatrix(mat) {
+    var _mdf = this._mdf;
+    this.iterateDynamicProperties();
+    this._mdf = this._mdf || _mdf;
+    if (this.a) {
+      mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+    }
+    if (this.s) {
+      mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+    }
+    if (this.sk) {
+      mat.skewFromAxis(-this.sk.v, this.sa.v);
+    }
+    if (this.r) {
+      mat.rotate(-this.r.v);
+    } else {
+      mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+    }
+    if (this.data.p.s) {
+      if (this.data.p.z) {
+        mat.translate(this.px.v, this.py.v, -this.pz.v);
+      } else {
+        mat.translate(this.px.v, this.py.v, 0);
+      }
+    } else {
+      mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+    }
+  }
+  function processKeys(forceRender) {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    }
+    if (this._isDirty) {
+      this.precalculateMatrix();
+      this._isDirty = false;
+    }
+
+    this.iterateDynamicProperties();
+
+    if (this._mdf || forceRender) {
+      var frameRate;
+      this.v.cloneFromProps(this.pre.props);
+      if (this.appliedTransformations < 1) {
+        this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      }
+      if (this.appliedTransformations < 2) {
+        this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      }
+      if (this.sk && this.appliedTransformations < 3) {
+        this.v.skewFromAxis(-this.sk.v, this.sa.v);
+      }
+      if (this.r && this.appliedTransformations < 4) {
+        this.v.rotate(-this.r.v);
+      } else if (!this.r && this.appliedTransformations < 4) {
+        this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+          .rotateY(this.or.v[1])
+          .rotateX(this.or.v[0]);
+      }
+      if (this.autoOriented) {
+        var v1;
+        var v2;
+        frameRate = this.elem.globalData.frameRate;
+        if (this.p && this.p.keyframes && this.p.getValueAtTime) {
+          if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
+            v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0);
+          } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0);
+            v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0);
+          } else {
+            v1 = this.p.pv;
+            v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime);
+          }
+        } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) {
+          v1 = [];
+          v2 = [];
+          var px = this.px;
+          var py = this.py;
+          if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
+            v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
+            v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate, 0);
+          } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate), 0);
+            v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate), 0);
+            v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0);
+          } else {
+            v1 = [px.pv, py.pv];
+            v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime);
+            v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime);
+          }
+        } else {
+          v2 = defaultVector;
+          v1 = v2;
+        }
+        this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
+      }
+      if (this.data.p && this.data.p.s) {
+        if (this.data.p.z) {
+          this.v.translate(this.px.v, this.py.v, -this.pz.v);
+        } else {
+          this.v.translate(this.px.v, this.py.v, 0);
+        }
+      } else {
+        this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+      }
+    }
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function precalculateMatrix() {
+    this.appliedTransformations = 0;
+    this.pre.reset();
+
+    if (!this.a.effectsSequence.length) {
+      this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      this.appliedTransformations = 1;
+    } else {
+      return;
+    }
+    if (!this.s.effectsSequence.length) {
+      this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      this.appliedTransformations = 2;
+    } else {
+      return;
+    }
+    if (this.sk) {
+      if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
+        this.pre.skewFromAxis(-this.sk.v, this.sa.v);
+        this.appliedTransformations = 3;
+      } else {
+        return;
+      }
+    }
+    if (this.r) {
+      if (!this.r.effectsSequence.length) {
+        this.pre.rotate(-this.r.v);
+        this.appliedTransformations = 4;
+      }
+    } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) {
+      this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+      this.appliedTransformations = 4;
+    }
+  }
+
+  function autoOrient() {
+    //
+    // var prevP = this.getValueAtTime();
+  }
+
+  function addDynamicProperty(prop) {
+    this._addDynamicProperty(prop);
+    this.elem.addDynamicProperty(prop);
+    this._isDirty = true;
+  }
+
+  function TransformProperty(elem, data, container) {
+    this.elem = elem;
+    this.frameId = -1;
+    this.propType = 'transform';
+    this.data = data;
+    this.v = new Matrix();
+    // Precalculated matrix with non animated properties
+    this.pre = new Matrix();
+    this.appliedTransformations = 0;
+    this.initDynamicPropertyContainer(container || elem);
+    if (data.p && data.p.s) {
+      this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
+      this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
+      if (data.p.z) {
+        this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
+      }
+    } else {
+      this.p = PropertyFactory.getProp(elem, data.p || { k: [0, 0, 0] }, 1, 0, this);
+    }
+    if (data.rx) {
+      this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
+      this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
+      this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
+      if (data.or.k[0].ti) {
+        var i;
+        var len = data.or.k.length;
+        for (i = 0; i < len; i += 1) {
+          data.or.k[i].to = null;
+          data.or.k[i].ti = null;
+        }
+      }
+      this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+      // sh Indicates it needs to be capped between -180 and 180
+      this.or.sh = true;
+    } else {
+      this.r = PropertyFactory.getProp(elem, data.r || { k: 0 }, 0, degToRads, this);
+    }
+    if (data.sk) {
+      this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
+      this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
+    }
+    this.a = PropertyFactory.getProp(elem, data.a || { k: [0, 0, 0] }, 1, 0, this);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: [100, 100, 100] }, 1, 0.01, this);
+    // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
+    if (data.o) {
+      this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
+    } else {
+      this.o = { _mdf: false, v: 1 };
+    }
+    this._isDirty = true;
+    if (!this.dynamicProperties.length) {
+      this.getValue(true);
+    }
+  }
+
+  TransformProperty.prototype = {
+    applyToMatrix: applyToMatrix,
+    getValue: processKeys,
+    precalculateMatrix: precalculateMatrix,
+    autoOrient: autoOrient,
+  };
+
+  extendPrototype([DynamicPropertyContainer], TransformProperty);
+  TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
+  TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
+
+  function getTransformProperty(elem, data, container) {
+    return new TransformProperty(elem, data, container);
+  }
+
+  return {
+    getTransformProperty: getTransformProperty,
+  };
+}());
+
+function RepeaterModifier() {}
+extendPrototype([ShapeModifier], RepeaterModifier);
+
+RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, null, this);
+  this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this);
+  this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
+  this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
+  this.data = data;
+  if (!this.dynamicProperties.length) {
+    this.getValue(true);
+  }
+  this._isAnimated = !!this.dynamicProperties.length;
+  this.pMatrix = new Matrix();
+  this.rMatrix = new Matrix();
+  this.sMatrix = new Matrix();
+  this.tMatrix = new Matrix();
+  this.matrix = new Matrix();
+};
+
+RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
+  var dir = inv ? -1 : 1;
+  var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
+  var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
+  pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
+  rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  rMatrix.rotate(-transform.r.v * dir * perc);
+  rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+  sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
+  sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+};
+
+RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
+  this.elem = elem;
+  this.arr = arr;
+  this.pos = pos;
+  this.elemsData = elemsData;
+  this._currentCopies = 0;
+  this._elements = [];
+  this._groups = [];
+  this.frameId = -1;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, arr[pos]);
+  while (pos > 0) {
+    pos -= 1;
+    // this._elements.unshift(arr.splice(pos,1)[0]);
+    this._elements.unshift(arr[pos]);
+  }
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+
+RepeaterModifier.prototype.resetElements = function (elements) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._processed = false;
+    if (elements[i].ty === 'gr') {
+      this.resetElements(elements[i].it);
+    }
+  }
+};
+
+RepeaterModifier.prototype.cloneElements = function (elements) {
+  var newElements = JSON.parse(JSON.stringify(elements));
+  this.resetElements(newElements);
+  return newElements;
+};
+
+RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._render = renderFlag;
+    if (elements[i].ty === 'gr') {
+      this.changeGroupRender(elements[i].it, renderFlag);
+    }
+  }
+};
+
+RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
+  var items;
+  var itemsTransform;
+  var i;
+  var dir;
+  var cont;
+  var hasReloaded = false;
+  if (this._mdf || _isFirstFrame) {
+    var copies = Math.ceil(this.c.v);
+    if (this._groups.length < copies) {
+      while (this._groups.length < copies) {
+        var group = {
+          it: this.cloneElements(this._elements),
+          ty: 'gr',
+        };
+        group.it.push({
+          a: { a: 0, ix: 1, k: [0, 0] }, nm: 'Transform', o: { a: 0, ix: 7, k: 100 }, p: { a: 0, ix: 2, k: [0, 0] }, r: { a: 1, ix: 6, k: [{ s: 0, e: 0, t: 0 }, { s: 0, e: 0, t: 1 }] }, s: { a: 0, ix: 3, k: [100, 100] }, sa: { a: 0, ix: 5, k: 0 }, sk: { a: 0, ix: 4, k: 0 }, ty: 'tr',
+        });
+
+        this.arr.splice(0, 0, group);
+        this._groups.splice(0, 0, group);
+        this._currentCopies += 1;
+      }
+      this.elem.reloadShapes();
+      hasReloaded = true;
+    }
+    cont = 0;
+    var renderFlag;
+    for (i = 0; i <= this._groups.length - 1; i += 1) {
+      renderFlag = cont < copies;
+      this._groups[i]._render = renderFlag;
+      this.changeGroupRender(this._groups[i].it, renderFlag);
+      if (!renderFlag) {
+        var elems = this.elemsData[i].it;
+        var transformData = elems[elems.length - 1];
+        if (transformData.transform.op.v !== 0) {
+          transformData.transform.op._mdf = true;
+          transformData.transform.op.v = 0;
+        } else {
+          transformData.transform.op._mdf = false;
+        }
+      }
+      cont += 1;
+    }
+
+    this._currentCopies = copies;
+    /// /
+
+    var offset = this.o.v;
+    var offsetModulo = offset % 1;
+    var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
+    var pProps = this.pMatrix.props;
+    var rProps = this.rMatrix.props;
+    var sProps = this.sMatrix.props;
+    this.pMatrix.reset();
+    this.rMatrix.reset();
+    this.sMatrix.reset();
+    this.tMatrix.reset();
+    this.matrix.reset();
+    var iteration = 0;
+
+    if (offset > 0) {
+      while (iteration < roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        iteration += 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
+        iteration += offsetModulo;
+      }
+    } else if (offset < 0) {
+      while (iteration > roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
+        iteration -= 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
+        iteration -= offsetModulo;
+      }
+    }
+    i = this.data.m === 1 ? 0 : this._currentCopies - 1;
+    dir = this.data.m === 1 ? 1 : -1;
+    cont = this._currentCopies;
+    var j;
+    var jLen;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      jLen = itemsTransform.length;
+      items[items.length - 1].transform.mProps._mdf = true;
+      items[items.length - 1].transform.op._mdf = true;
+      items[items.length - 1].transform.op.v = this._currentCopies === 1
+        ? this.so.v
+        : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
+
+      if (iteration !== 0) {
+        if ((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)) {
+          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        }
+        this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
+        this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
+        this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
+
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+        this.matrix.reset();
+      } else {
+        this.matrix.reset();
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+      }
+      iteration += 1;
+      cont -= 1;
+      i += dir;
+    }
+  } else {
+    cont = this._currentCopies;
+    i = 0;
+    dir = 1;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      items[items.length - 1].transform.mProps._mdf = false;
+      items[items.length - 1].transform.op._mdf = false;
+      cont -= 1;
+      i += dir;
+    }
+  }
+  return hasReloaded;
+};
+
+RepeaterModifier.prototype.addShape = function () {};
+
+function RoundCornersModifier() {}
+extendPrototype([ShapeModifier], RoundCornersModifier);
+RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this._isAnimated = !!this.rd.effectsSequence.length;
+};
+
+RoundCornersModifier.prototype.processPath = function (path, round) {
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var i;
+  var len = path._length;
+  var currentV;
+  var currentI;
+  var currentO;
+  var closerV;
+  var distance;
+  var newPosPerc;
+  var index = 0;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < len; i += 1) {
+    currentV = path.v[i];
+    currentO = path.o[i];
+    currentI = path.i[i];
+    if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
+      if ((i === 0 || i === len - 1) && !path.c) {
+        clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
+        /* clonedPath.v[index] = currentV;
+                clonedPath.o[index] = currentO;
+                clonedPath.i[index] = currentI; */
+        index += 1;
+      } else {
+        if (i === 0) {
+          closerV = path.v[len - 1];
+        } else {
+          closerV = path.v[i - 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = iX;
+        iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
+        vY = iY;
+        oX = vX - (vX - currentV[0]) * roundCorner;
+        oY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+
+        if (i === len - 1) {
+          closerV = path.v[0];
+        } else {
+          closerV = path.v[i + 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = oX;
+        oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc;
+        vY = oY;
+        iX = vX - (vX - currentV[0]) * roundCorner;
+        iY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+      }
+    } else {
+      clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index);
+      index += 1;
+    }
+  }
+  return clonedPath;
+};
+
+RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var rd = this.rd.v;
+
+  if (rd !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function floatEqual(a, b) {
+  return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
+}
+
+function floatZero(f) {
+  return Math.abs(f) <= 0.00001;
+}
+
+function lerp(p0, p1, amount) {
+  return p0 * (1 - amount) + p1 * amount;
+}
+
+function lerpPoint(p0, p1, amount) {
+  return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
+}
+
+function quadRoots(a, b, c) {
+  // no root
+  if (a === 0) return [];
+  var s = b * b - 4 * a * c;
+  // Complex roots
+  if (s < 0) return [];
+  var singleRoot = -b / (2 * a);
+  // 1 root
+  if (s === 0) return [singleRoot];
+  var delta = Math.sqrt(s) / (2 * a);
+  // 2 roots
+  return [singleRoot - delta, singleRoot + delta];
+}
+
+function polynomialCoefficients(p0, p1, p2, p3) {
+  return [
+    -p0 + 3 * p1 - 3 * p2 + p3,
+    3 * p0 - 6 * p1 + 3 * p2,
+    -3 * p0 + 3 * p1,
+    p0,
+  ];
+}
+
+function singlePoint(p) {
+  return new PolynomialBezier(p, p, p, p, false);
+}
+
+function PolynomialBezier(p0, p1, p2, p3, linearize) {
+  if (linearize && pointEqual(p0, p1)) {
+    p1 = lerpPoint(p0, p3, 1 / 3);
+  }
+  if (linearize && pointEqual(p2, p3)) {
+    p2 = lerpPoint(p0, p3, 2 / 3);
+  }
+  var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
+  var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
+  this.a = [coeffx[0], coeffy[0]];
+  this.b = [coeffx[1], coeffy[1]];
+  this.c = [coeffx[2], coeffy[2]];
+  this.d = [coeffx[3], coeffy[3]];
+  this.points = [p0, p1, p2, p3];
+}
+PolynomialBezier.prototype.point = function (t) {
+  return [
+    (((this.a[0] * t) + this.b[0]) * t + this.c[0]) * t + this.d[0],
+    (((this.a[1] * t) + this.b[1]) * t + this.c[1]) * t + this.d[1],
+  ];
+};
+PolynomialBezier.prototype.derivative = function (t) {
+  return [
+    (3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0],
+    (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1],
+  ];
+};
+PolynomialBezier.prototype.tangentAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[1], p[0]);
+};
+PolynomialBezier.prototype.normalAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[0], p[1]);
+};
+
+PolynomialBezier.prototype.inflectionPoints = function () {
+  var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
+  if (floatZero(denom)) return [];
+  var tcusp = (-0.5 * (this.a[1] * this.c[0] - this.a[0] * this.c[1])) / denom;
+  var square = tcusp * tcusp - ((1 / 3) * (this.b[1] * this.c[0] - this.b[0] * this.c[1])) / denom;
+  if (square < 0) return [];
+  var root = Math.sqrt(square);
+  if (floatZero(root)) {
+    if (root > 0 && root < 1) return [tcusp];
+    return [];
+  }
+  return [tcusp - root, tcusp + root].filter(function (r) { return r > 0 && r < 1; });
+};
+PolynomialBezier.prototype.split = function (t) {
+  if (t <= 0) return [singlePoint(this.points[0]), this];
+  if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
+  var p10 = lerpPoint(this.points[0], this.points[1], t);
+  var p11 = lerpPoint(this.points[1], this.points[2], t);
+  var p12 = lerpPoint(this.points[2], this.points[3], t);
+  var p20 = lerpPoint(p10, p11, t);
+  var p21 = lerpPoint(p11, p12, t);
+  var p3 = lerpPoint(p20, p21, t);
+  return [
+    new PolynomialBezier(this.points[0], p10, p20, p3, true),
+    new PolynomialBezier(p3, p21, p12, this.points[3], true),
+  ];
+};
+function extrema(bez, comp) {
+  var min = bez.points[0][comp];
+  var max = bez.points[bez.points.length - 1][comp];
+  if (min > max) {
+    var e = max;
+    max = min;
+    min = e;
+  }
+  // Derivative roots to find min/max
+  var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
+  for (var i = 0; i < f.length; i += 1) {
+    if (f[i] > 0 && f[i] < 1) {
+      var val = bez.point(f[i])[comp];
+      if (val < min) min = val;
+      else if (val > max) max = val;
+    }
+  }
+  return {
+    min: min,
+    max: max,
+  };
+}
+PolynomialBezier.prototype.bounds = function () {
+  return {
+    x: extrema(this, 0),
+    y: extrema(this, 1),
+  };
+};
+PolynomialBezier.prototype.boundingBox = function () {
+  var bounds = this.bounds();
+  return {
+    left: bounds.x.min,
+    right: bounds.x.max,
+    top: bounds.y.min,
+    bottom: bounds.y.max,
+    width: bounds.x.max - bounds.x.min,
+    height: bounds.y.max - bounds.y.min,
+    cx: (bounds.x.max + bounds.x.min) / 2,
+    cy: (bounds.y.max + bounds.y.min) / 2,
+  };
+};
+
+function intersectData(bez, t1, t2) {
+  var box = bez.boundingBox();
+  return {
+    cx: box.cx,
+    cy: box.cy,
+    width: box.width,
+    height: box.height,
+    bez: bez,
+    t: (t1 + t2) / 2,
+    t1: t1,
+    t2: t2,
+  };
+}
+function splitData(data) {
+  var split = data.bez.split(0.5);
+  return [
+    intersectData(split[0], data.t1, data.t),
+    intersectData(split[1], data.t, data.t2),
+  ];
+}
+
+function boxIntersect(b1, b2) {
+  return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width
+    && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
+}
+
+function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
+  if (!boxIntersect(d1, d2)) return;
+  if (depth >= maxRecursion || (d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance)) {
+    intersections.push([d1.t, d2.t]);
+    return;
+  }
+  var d1s = splitData(d1);
+  var d2s = splitData(d2);
+  intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[0], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+}
+
+PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
+  if (tolerance === undefined) tolerance = 2;
+  if (maxRecursion === undefined) maxRecursion = 7;
+  var intersections = [];
+  intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
+  return intersections;
+};
+
+PolynomialBezier.shapeSegment = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
+};
+
+PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
+};
+
+function crossProduct(a, b) {
+  return [
+    a[1] * b[2] - a[2] * b[1],
+    a[2] * b[0] - a[0] * b[2],
+    a[0] * b[1] - a[1] * b[0],
+  ];
+}
+
+function lineIntersection(start1, end1, start2, end2) {
+  var v1 = [start1[0], start1[1], 1];
+  var v2 = [end1[0], end1[1], 1];
+  var v3 = [start2[0], start2[1], 1];
+  var v4 = [end2[0], end2[1], 1];
+
+  var r = crossProduct(
+    crossProduct(v1, v2),
+    crossProduct(v3, v4)
+  );
+
+  if (floatZero(r[2])) return null;
+
+  return [r[0] / r[2], r[1] / r[2]];
+}
+
+function polarOffset(p, angle, length) {
+  return [
+    p[0] + Math.cos(angle) * length,
+    p[1] - Math.sin(angle) * length,
+  ];
+}
+
+function pointDistance(p1, p2) {
+  return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
+}
+
+function pointEqual(p1, p2) {
+  return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
+}
+
+function ZigZagModifier() {}
+extendPrototype([ShapeModifier], ZigZagModifier);
+ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
+  this.frequency = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
+  this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
+};
+
+function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
+  var angO = angle - Math.PI / 2;
+  var angI = angle + Math.PI / 2;
+  var px = point[0] + Math.cos(angle) * direction * amplitude;
+  var py = point[1] - Math.sin(angle) * direction * amplitude;
+
+  outputBezier.setTripleAt(
+    px,
+    py,
+    px + Math.cos(angO) * outAmplitude,
+    py - Math.sin(angO) * outAmplitude,
+    px + Math.cos(angI) * inAmplitude,
+    py - Math.sin(angI) * inAmplitude,
+    outputBezier.length()
+  );
+}
+
+function getPerpendicularVector(pt1, pt2) {
+  var vector = [
+    pt2[0] - pt1[0],
+    pt2[1] - pt1[1],
+  ];
+  var rot = -Math.PI * 0.5;
+  var rotatedVector = [
+    Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1],
+    Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1],
+  ];
+  return rotatedVector;
+}
+
+function getProjectingAngle(path, cur) {
+  var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
+  var nextIndex = (cur + 1) % path.length();
+  var prevPoint = path.v[prevIndex];
+  var nextPoint = path.v[nextIndex];
+  var pVector = getPerpendicularVector(prevPoint, nextPoint);
+  return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
+}
+
+function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
+  var angle = getProjectingAngle(path, cur);
+  var point = path.v[cur % path._length];
+  var prevPoint = path.v[cur === 0 ? path._length - 1 : cur - 1];
+  var nextPoint = path.v[(cur + 1) % path._length];
+  var prevDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - prevPoint[0], 2) + Math.pow(point[1] - prevPoint[1], 2))
+    : 0;
+  var nextDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2))
+    : 0;
+
+  setPoint(
+    outputBezier,
+    path.v[cur % path._length],
+    angle,
+    direction,
+    amplitude,
+    nextDist / ((frequency + 1) * 2),
+    prevDist / ((frequency + 1) * 2),
+    pointType
+  );
+}
+
+function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
+  for (var i = 0; i < frequency; i += 1) {
+    var t = (i + 1) / (frequency + 1);
+
+    var dist = pointType === 2
+      ? Math.sqrt(Math.pow(segment.points[3][0] - segment.points[0][0], 2) + Math.pow(segment.points[3][1] - segment.points[0][1], 2))
+      : 0;
+
+    var angle = segment.normalAngle(t);
+    var point = segment.point(t);
+    setPoint(
+      outputBezier,
+      point,
+      angle,
+      direction,
+      amplitude,
+      dist / ((frequency + 1) * 2),
+      dist / ((frequency + 1) * 2),
+      pointType
+    );
+
+    direction = -direction;
+  }
+
+  return direction;
+}
+
+ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
+  var count = path._length;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+
+  if (!path.c) {
+    count -= 1;
+  }
+
+  if (count === 0) return clonedPath;
+
+  var direction = -1;
+  var segment = PolynomialBezier.shapeSegment(path, 0);
+  zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
+
+  for (var i = 0; i < count; i += 1) {
+    direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
+
+    if (i === count - 1 && !path.c) {
+      segment = null;
+    } else {
+      segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
+    }
+
+    zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
+  }
+
+  return clonedPath;
+};
+
+ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amplitude = this.amplitude.v;
+  var frequency = Math.max(0, Math.round(this.frequency.v));
+  var pointType = this.pointsType.v;
+
+  if (amplitude !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function linearOffset(p1, p2, amount) {
+  var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
+  return [
+    polarOffset(p1, angle, amount),
+    polarOffset(p2, angle, amount),
+  ];
+}
+
+function offsetSegment(segment, amount) {
+  var p0; var p1a; var p1b; var p2b; var p2a; var
+    p3;
+  var e;
+  e = linearOffset(segment.points[0], segment.points[1], amount);
+  p0 = e[0];
+  p1a = e[1];
+  e = linearOffset(segment.points[1], segment.points[2], amount);
+  p1b = e[0];
+  p2b = e[1];
+  e = linearOffset(segment.points[2], segment.points[3], amount);
+  p2a = e[0];
+  p3 = e[1];
+  var p1 = lineIntersection(p0, p1a, p1b, p2b);
+  if (p1 === null) p1 = p1a;
+  var p2 = lineIntersection(p2a, p3, p1b, p2b);
+  if (p2 === null) p2 = p2a;
+
+  return new PolynomialBezier(p0, p1, p2, p3);
+}
+
+function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
+  var p0 = seg1.points[3];
+  var p1 = seg2.points[0];
+
+  // Bevel
+  if (lineJoin === 3) return p0;
+
+  // Connected, they don't need a joint
+  if (pointEqual(p0, p1)) return p0;
+
+  // Round
+  if (lineJoin === 2) {
+    var angleOut = -seg1.tangentAngle(1);
+    var angleIn = -seg2.tangentAngle(0) + Math.PI;
+    var center = lineIntersection(
+      p0,
+      polarOffset(p0, angleOut + Math.PI / 2, 100),
+      p1,
+      polarOffset(p1, angleOut + Math.PI / 2, 100)
+    );
+    var radius = center ? pointDistance(center, p0) : pointDistance(p0, p1) / 2;
+
+    var tan = polarOffset(p0, angleOut, 2 * radius * roundCorner);
+    outputBezier.setXYAt(tan[0], tan[1], 'o', outputBezier.length() - 1);
+
+    tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
+    outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
+
+    return p1;
+  }
+
+  // Miter
+  var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
+  var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
+  var intersection = lineIntersection(t0, p0, p1, t1);
+  if (intersection && pointDistance(intersection, p0) < miterLimit) {
+    outputBezier.setTripleAt(
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      outputBezier.length()
+    );
+    return intersection;
+  }
+
+  return p0;
+}
+
+function getIntersection(a, b) {
+  const intersect = a.intersections(b);
+
+  if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
+
+  if (intersect.length) return intersect[0];
+
+  return null;
+}
+
+function pruneSegmentIntersection(a, b) {
+  var outa = a.slice();
+  var outb = b.slice();
+  var intersect = getIntersection(a[a.length - 1], b[0]);
+  if (intersect) {
+    outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
+    outb[0] = b[0].split(intersect[1])[1];
+  }
+  if (a.length > 1 && b.length > 1) {
+    intersect = getIntersection(a[0], b[b.length - 1]);
+    if (intersect) {
+      return [
+        [a[0].split(intersect[0])[0]],
+        [b[b.length - 1].split(intersect[1])[1]],
+      ];
+    }
+  }
+  return [outa, outb];
+}
+
+function pruneIntersections(segments) {
+  var e;
+  for (var i = 1; i < segments.length; i += 1) {
+    e = pruneSegmentIntersection(segments[i - 1], segments[i]);
+    segments[i - 1] = e[0];
+    segments[i] = e[1];
+  }
+
+  if (segments.length > 1) {
+    e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
+    segments[segments.length - 1] = e[0];
+    segments[0] = e[1];
+  }
+
+  return segments;
+}
+
+function offsetSegmentSplit(segment, amount) {
+  /*
+    We split each bezier segment into smaller pieces based
+    on inflection points, this ensures the control point
+    polygon is convex.
+
+    (A cubic bezier can have none, one, or two inflection points)
+  */
+  var flex = segment.inflectionPoints();
+  var left;
+  var right;
+  var split;
+  var mid;
+
+  if (flex.length === 0) {
+    return [offsetSegment(segment, amount)];
+  }
+
+  if (flex.length === 1 || floatEqual(flex[1], 1)) {
+    split = segment.split(flex[0]);
+    left = split[0];
+    right = split[1];
+
+    return [
+      offsetSegment(left, amount),
+      offsetSegment(right, amount),
+    ];
+  }
+
+  split = segment.split(flex[0]);
+  left = split[0];
+  var t = (flex[1] - flex[0]) / (1 - flex[0]);
+  split = split[1].split(t);
+  mid = split[0];
+  right = split[1];
+
+  return [
+    offsetSegment(left, amount),
+    offsetSegment(mid, amount),
+    offsetSegment(right, amount),
+  ];
+}
+
+function OffsetPathModifier() {}
+
+extendPrototype([ShapeModifier], OffsetPathModifier);
+OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this.miterLimit = PropertyFactory.getProp(elem, data.ml, 0, null, this);
+  this.lineJoin = data.lj;
+  this._isAnimated = this.amount.effectsSequence.length !== 0;
+};
+
+OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
+  var outputBezier = shapePool.newElement();
+  outputBezier.c = inputBezier.c;
+  var count = inputBezier.length();
+  if (!inputBezier.c) {
+    count -= 1;
+  }
+  var i; var j; var segment;
+  var multiSegments = [];
+
+  for (i = 0; i < count; i += 1) {
+    segment = PolynomialBezier.shapeSegment(inputBezier, i);
+    multiSegments.push(offsetSegmentSplit(segment, amount));
+  }
+
+  if (!inputBezier.c) {
+    for (i = count - 1; i >= 0; i -= 1) {
+      segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
+      multiSegments.push(offsetSegmentSplit(segment, amount));
+    }
+  }
+
+  multiSegments = pruneIntersections(multiSegments);
+
+  // Add bezier segments to the output and apply line joints
+  var lastPoint = null;
+  var lastSeg = null;
+
+  for (i = 0; i < multiSegments.length; i += 1) {
+    var multiSegment = multiSegments[i];
+
+    if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
+
+    lastSeg = multiSegment[multiSegment.length - 1];
+
+    for (j = 0; j < multiSegment.length; j += 1) {
+      segment = multiSegment[j];
+
+      if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
+        outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
+      } else {
+        outputBezier.setTripleAt(
+          segment.points[0][0],
+          segment.points[0][1],
+          segment.points[1][0],
+          segment.points[1][1],
+          segment.points[0][0],
+          segment.points[0][1],
+          outputBezier.length()
+        );
+      }
+
+      outputBezier.setTripleAt(
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[2][0],
+        segment.points[2][1],
+        outputBezier.length()
+      );
+
+      lastPoint = segment.points[3];
+    }
+  }
+
+  if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
+
+  return outputBezier;
+};
+
+OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+  var miterLimit = this.miterLimit.v;
+  var lineJoin = this.lineJoin;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function getFontProperties(fontData) {
+  var styles = fontData.fStyle ? fontData.fStyle.split(' ') : [];
+
+  var fWeight = 'normal'; var
+    fStyle = 'normal';
+  var len = styles.length;
+  var styleName;
+  for (var i = 0; i < len; i += 1) {
+    styleName = styles[i].toLowerCase();
+    switch (styleName) {
+      case 'italic':
+        fStyle = 'italic';
+        break;
+      case 'bold':
+        fWeight = '700';
+        break;
+      case 'black':
+        fWeight = '900';
+        break;
+      case 'medium':
+        fWeight = '500';
+        break;
+      case 'regular':
+      case 'normal':
+        fWeight = '400';
+        break;
+      case 'light':
+      case 'thin':
+        fWeight = '200';
+        break;
+      default:
+        break;
+    }
+  }
+
+  return {
+    style: fStyle,
+    weight: fontData.fWeight || fWeight,
+  };
+}
+
+const FontManager = (function () {
+  var maxWaitingTime = 5000;
+  var emptyChar = {
+    w: 0,
+    size: 0,
+    shapes: [],
+    data: {
+      shapes: [],
+    },
+  };
+  var combinedCharacters = [];
+  // Hindi characters
+  combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366,
+    2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379,
+    2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
+
+  var BLACK_FLAG_CODE_POINT = 127988;
+  var CANCEL_TAG_CODE_POINT = 917631;
+  var A_TAG_CODE_POINT = 917601;
+  var Z_TAG_CODE_POINT = 917626;
+  var VARIATION_SELECTOR_16_CODE_POINT = 65039;
+  var ZERO_WIDTH_JOINER_CODE_POINT = 8205;
+  var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
+  var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
+
+  var surrogateModifiers = [
+    'd83cdffb',
+    'd83cdffc',
+    'd83cdffd',
+    'd83cdffe',
+    'd83cdfff',
+  ];
+
+  function trimFontOptions(font) {
+    var familyArray = font.split(',');
+    var i;
+    var len = familyArray.length;
+    var enabledFamilies = [];
+    for (i = 0; i < len; i += 1) {
+      if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
+        enabledFamilies.push(familyArray[i]);
+      }
+    }
+    return enabledFamilies.join(',');
+  }
+
+  function setUpNode(font, family) {
+    var parentNode = createTag('span');
+    // Node is invisible to screen readers.
+    parentNode.setAttribute('aria-hidden', true);
+    parentNode.style.fontFamily = family;
+    var node = createTag('span');
+    // Characters that vary significantly among different fonts
+    node.innerText = 'giItT1WQy@!-/#';
+    // Visible - so we can measure it - but not on the screen
+    parentNode.style.position = 'absolute';
+    parentNode.style.left = '-10000px';
+    parentNode.style.top = '-10000px';
+    // Large font size makes even subtle changes obvious
+    parentNode.style.fontSize = '300px';
+    // Reset any font properties
+    parentNode.style.fontVariant = 'normal';
+    parentNode.style.fontStyle = 'normal';
+    parentNode.style.fontWeight = 'normal';
+    parentNode.style.letterSpacing = '0';
+    parentNode.appendChild(node);
+    document.body.appendChild(parentNode);
+
+    // Remember width with no applied web font
+    var width = node.offsetWidth;
+    node.style.fontFamily = trimFontOptions(font) + ', ' + family;
+    return { node: node, w: width, parent: parentNode };
+  }
+
+  function checkLoadedFonts() {
+    var i;
+    var len = this.fonts.length;
+    var node;
+    var w;
+    var loadedCount = len;
+    for (i = 0; i < len; i += 1) {
+      if (this.fonts[i].loaded) {
+        loadedCount -= 1;
+      } else if (this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0) {
+        this.fonts[i].loaded = true;
+      } else {
+        node = this.fonts[i].monoCase.node;
+        w = this.fonts[i].monoCase.w;
+        if (node.offsetWidth !== w) {
+          loadedCount -= 1;
+          this.fonts[i].loaded = true;
+        } else {
+          node = this.fonts[i].sansCase.node;
+          w = this.fonts[i].sansCase.w;
+          if (node.offsetWidth !== w) {
+            loadedCount -= 1;
+            this.fonts[i].loaded = true;
+          }
+        }
+        if (this.fonts[i].loaded) {
+          this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
+          this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
+        }
+      }
+    }
+
+    if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
+      setTimeout(this.checkLoadedFontsBinded, 20);
+    } else {
+      setTimeout(this.setIsLoadedBinded, 10);
+    }
+  }
+
+  function createHelper(fontData, def) {
+    var engine = (document.body && def) ? 'svg' : 'canvas';
+    var helper;
+    var fontProps = getFontProperties(fontData);
+    if (engine === 'svg') {
+      var tHelper = createNS('text');
+      tHelper.style.fontSize = '100px';
+      // tHelper.style.fontFamily = fontData.fFamily;
+      tHelper.setAttribute('font-family', fontData.fFamily);
+      tHelper.setAttribute('font-style', fontProps.style);
+      tHelper.setAttribute('font-weight', fontProps.weight);
+      tHelper.textContent = '1';
+      if (fontData.fClass) {
+        tHelper.style.fontFamily = 'inherit';
+        tHelper.setAttribute('class', fontData.fClass);
+      } else {
+        tHelper.style.fontFamily = fontData.fFamily;
+      }
+      def.appendChild(tHelper);
+      helper = tHelper;
+    } else {
+      var tCanvasHelper = new OffscreenCanvas(500, 500).getContext('2d');
+      tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
+      helper = tCanvasHelper;
+    }
+    function measure(text) {
+      if (engine === 'svg') {
+        helper.textContent = text;
+        return helper.getComputedTextLength();
+      }
+      return helper.measureText(text).width;
+    }
+    return {
+      measureText: measure,
+    };
+  }
+
+  function addFonts(fontData, defs) {
+    if (!fontData) {
+      this.isLoaded = true;
+      return;
+    }
+    if (this.chars) {
+      this.isLoaded = true;
+      this.fonts = fontData.list;
+      return;
+    }
+    if (!document.body) {
+      this.isLoaded = true;
+      fontData.list.forEach((data) => {
+        data.helper = createHelper(data);
+        data.cache = {};
+      });
+      this.fonts = fontData.list;
+      return;
+    }
+
+    var fontArr = fontData.list;
+    var i;
+    var len = fontArr.length;
+    var _pendingFonts = len;
+    for (i = 0; i < len; i += 1) {
+      var shouldLoadFont = true;
+      var loadedSelector;
+      var j;
+      fontArr[i].loaded = false;
+      fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
+      fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
+      if (!fontArr[i].fPath) {
+        fontArr[i].loaded = true;
+        _pendingFonts -= 1;
+      } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
+        loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
+
+        if (loadedSelector.length > 0) {
+          shouldLoadFont = false;
+        }
+
+        if (shouldLoadFont) {
+          var s = createTag('style');
+          s.setAttribute('f-forigin', fontArr[i].fOrigin);
+          s.setAttribute('f-origin', fontArr[i].origin);
+          s.setAttribute('f-family', fontArr[i].fFamily);
+          s.type = 'text/css';
+          s.innerText = '@font-face {font-family: ' + fontArr[i].fFamily + "; font-style: normal; src: url('" + fontArr[i].fPath + "');}";
+          defs.appendChild(s);
+        }
+      } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
+        loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var l = createTag('link');
+          l.setAttribute('f-forigin', fontArr[i].fOrigin);
+          l.setAttribute('f-origin', fontArr[i].origin);
+          l.type = 'text/css';
+          l.rel = 'stylesheet';
+          l.href = fontArr[i].fPath;
+          document.body.appendChild(l);
+        }
+      } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
+        loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (fontArr[i].fPath === loadedSelector[j].src) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var sc = createTag('link');
+          sc.setAttribute('f-forigin', fontArr[i].fOrigin);
+          sc.setAttribute('f-origin', fontArr[i].origin);
+          sc.setAttribute('rel', 'stylesheet');
+          sc.setAttribute('href', fontArr[i].fPath);
+          defs.appendChild(sc);
+        }
+      }
+      fontArr[i].helper = createHelper(fontArr[i], defs);
+      fontArr[i].cache = {};
+      this.fonts.push(fontArr[i]);
+    }
+    if (_pendingFonts === 0) {
+      this.isLoaded = true;
+    } else {
+      // On some cases even if the font is loaded, it won't load correctly when measuring text on canvas.
+      // Adding this timeout seems to fix it
+      setTimeout(this.checkLoadedFonts.bind(this), 100);
+    }
+  }
+
+  function addChars(chars) {
+    if (!chars) {
+      return;
+    }
+    if (!this.chars) {
+      this.chars = [];
+    }
+    var i;
+    var len = chars.length;
+    var j;
+    var jLen = this.chars.length;
+    var found;
+    for (i = 0; i < len; i += 1) {
+      j = 0;
+      found = false;
+      while (j < jLen) {
+        if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
+          found = true;
+        }
+        j += 1;
+      }
+      if (!found) {
+        this.chars.push(chars[i]);
+        jLen += 1;
+      }
+    }
+  }
+
+  function getCharData(char, style, font) {
+    var i = 0;
+    var len = this.chars.length;
+    while (i < len) {
+      if (this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font) {
+        return this.chars[i];
+      }
+      i += 1;
+    }
+    if (((typeof char === 'string' && char.charCodeAt(0) !== 13) || !char)
+            && console
+            && console.warn // eslint-disable-line no-console
+            && !this._warned
+    ) {
+      this._warned = true;
+      console.warn('Missing character from exported characters list: ', char, style, font); // eslint-disable-line no-console
+    }
+    return emptyChar;
+  }
+
+  function measureText(char, fontName, size) {
+    var fontData = this.getFontByName(fontName);
+    // Using the char instead of char.charCodeAt(0)
+    // to avoid collisions between equal chars
+    var index = char;
+    if (!fontData.cache[index]) {
+      var tHelper = fontData.helper;
+      if (char === ' ') {
+        var doubleSize = tHelper.measureText('|' + char + '|');
+        var singleSize = tHelper.measureText('||');
+        fontData.cache[index] = (doubleSize - singleSize) / 100;
+      } else {
+        fontData.cache[index] = tHelper.measureText(char) / 100;
+      }
+    }
+    return fontData.cache[index] * size;
+  }
+
+  function getFontByName(name) {
+    var i = 0;
+    var len = this.fonts.length;
+    while (i < len) {
+      if (this.fonts[i].fName === name) {
+        return this.fonts[i];
+      }
+      i += 1;
+    }
+    return this.fonts[0];
+  }
+
+  function getCodePoint(string) {
+    var codePoint = 0;
+    var first = string.charCodeAt(0);
+    if (first >= 0xD800 && first <= 0xDBFF) {
+      var second = string.charCodeAt(1);
+      if (second >= 0xDC00 && second <= 0xDFFF) {
+        codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+      }
+    }
+    return codePoint;
+  }
+
+  // Skin tone modifiers
+  function isModifier(firstCharCode, secondCharCode) {
+    var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
+    return surrogateModifiers.indexOf(sum) !== -1;
+  }
+
+  function isZeroWidthJoiner(charCode) {
+    return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
+  }
+
+  // This codepoint may change the appearance of the preceding character.
+  // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
+  // as a colorful image as compared to a monochrome text variant.
+  function isVariationSelector(charCode) {
+    return charCode === VARIATION_SELECTOR_16_CODE_POINT;
+  }
+
+  // The regional indicator symbols are a set of 26 alphabetic Unicode
+  /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
+  // two-letter country codes in a way that allows optional special treatment.
+  function isRegionalCode(string) {
+    var codePoint = getCodePoint(string);
+    if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
+      return true;
+    }
+    return false;
+  }
+
+  // Some Emoji implementations represent combinations of
+  // two “regional indicator” letters as a single flag symbol.
+  function isFlagEmoji(string) {
+    return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
+  }
+
+  function isCombinedCharacter(char) {
+    return combinedCharacters.indexOf(char) !== -1;
+  }
+
+  // Regional flags start with a BLACK_FLAG_CODE_POINT
+  // folowed by 5 chars in the TAG range
+  // and end with a CANCEL_TAG_CODE_POINT
+  function isRegionalFlag(text, index) {
+    var codePoint = getCodePoint(text.substr(index, 2));
+    if (codePoint !== BLACK_FLAG_CODE_POINT) {
+      return false;
+    }
+    var count = 0;
+    index += 2;
+    while (count < 5) {
+      codePoint = getCodePoint(text.substr(index, 2));
+      if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
+        return false;
+      }
+      count += 1;
+      index += 2;
+    }
+    return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
+  }
+
+  function setIsLoaded() {
+    this.isLoaded = true;
+  }
+
+  var Font = function () {
+    this.fonts = [];
+    this.chars = null;
+    this.typekitLoaded = 0;
+    this.isLoaded = false;
+    this._warned = false;
+    this.initTime = Date.now();
+    this.setIsLoadedBinded = this.setIsLoaded.bind(this);
+    this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
+  };
+  Font.isModifier = isModifier;
+  Font.isZeroWidthJoiner = isZeroWidthJoiner;
+  Font.isFlagEmoji = isFlagEmoji;
+  Font.isRegionalCode = isRegionalCode;
+  Font.isCombinedCharacter = isCombinedCharacter;
+  Font.isRegionalFlag = isRegionalFlag;
+  Font.isVariationSelector = isVariationSelector;
+  Font.BLACK_FLAG_CODE_POINT = BLACK_FLAG_CODE_POINT;
+
+  var fontPrototype = {
+    addChars: addChars,
+    addFonts: addFonts,
+    getCharData: getCharData,
+    getFontByName: getFontByName,
+    measureText: measureText,
+    checkLoadedFonts: checkLoadedFonts,
+    setIsLoaded: setIsLoaded,
+  };
+
+  Font.prototype = fontPrototype;
+
+  return Font;
+}());
+
+function SlotManager(animationData) {
+  this.animationData = animationData;
+}
+SlotManager.prototype.getProp = function (data) {
+  if (this.animationData.slots
+    && this.animationData.slots[data.sid]
+  ) {
+    return Object.assign(data, this.animationData.slots[data.sid].p);
+  }
+  return data;
+};
+
+function slotFactory(animationData) {
+  return new SlotManager(animationData);
+}
+
+function RenderableElement() {
+
+}
+
+RenderableElement.prototype = {
+  initRenderable: function () {
+    // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
+    this.isInRange = false;
+    // layer's display state
+    this.hidden = false;
+    // If layer's transparency equals 0, it can be hidden
+    this.isTransparent = false;
+    // list of animated components
+    this.renderableComponents = [];
+  },
+  addRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) === -1) {
+      this.renderableComponents.push(component);
+    }
+  },
+  removeRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) !== -1) {
+      this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1);
+    }
+  },
+  prepareRenderableFrame: function (num) {
+    this.checkLayerLimits(num);
+  },
+  checkTransparency: function () {
+    if (this.finalTransform.mProp.o.v <= 0) {
+      if (!this.isTransparent && this.globalData.renderConfig.hideOnTransparent) {
+        this.isTransparent = true;
+        this.hide();
+      }
+    } else if (this.isTransparent) {
+      this.isTransparent = false;
+      this.show();
+    }
+  },
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     *
+     */
+  checkLayerLimits: function (num) {
+    if (this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) {
+      if (this.isInRange !== true) {
+        this.globalData._mdf = true;
+        this._mdf = true;
+        this.isInRange = true;
+        this.show();
+      }
+    } else if (this.isInRange !== false) {
+      this.globalData._mdf = true;
+      this.isInRange = false;
+      this.hide();
+    }
+  },
+  renderRenderable: function () {
+    var i;
+    var len = this.renderableComponents.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderableComponents[i].renderFrame(this._isFirstFrame);
+    }
+    /* this.maskManager.renderFrame(this.finalTransform.mat);
+        this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
+  },
+  sourceRectAtTime: function () {
+    return {
+      top: 0,
+      left: 0,
+      width: 100,
+      height: 100,
+    };
+  },
+  getLayerSize: function () {
+    if (this.data.ty === 5) {
+      return { w: this.data.textData.width, h: this.data.textData.height };
+    }
+    return { w: this.data.width, h: this.data.height };
+  },
+};
+
+const getBlendMode = (function () {
+  var blendModeEnums = {
+    0: 'source-over',
+    1: 'multiply',
+    2: 'screen',
+    3: 'overlay',
+    4: 'darken',
+    5: 'lighten',
+    6: 'color-dodge',
+    7: 'color-burn',
+    8: 'hard-light',
+    9: 'soft-light',
+    10: 'difference',
+    11: 'exclusion',
+    12: 'hue',
+    13: 'saturation',
+    14: 'color',
+    15: 'luminosity',
+  };
+
+  return function (mode) {
+    return blendModeEnums[mode] || '';
+  };
+}());
+
+function SliderEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function AngleEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function ColorEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function PointEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function LayerIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function MaskIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function CheckboxEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function NoValueEffect() {
+  this.p = {};
+}
+
+function EffectsManager(data, element) {
+  var effects = data.ef || [];
+  this.effectElements = [];
+  var i;
+  var len = effects.length;
+  var effectItem;
+  for (i = 0; i < len; i += 1) {
+    effectItem = new GroupEffect(effects[i], element);
+    this.effectElements.push(effectItem);
+  }
+}
+
+function GroupEffect(data, element) {
+  this.init(data, element);
+}
+
+extendPrototype([DynamicPropertyContainer], GroupEffect);
+
+GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
+
+GroupEffect.prototype.init = function (data, element) {
+  this.data = data;
+  this.effectElements = [];
+  this.initDynamicPropertyContainer(element);
+  var i;
+  var len = this.data.ef.length;
+  var eff;
+  var effects = this.data.ef;
+  for (i = 0; i < len; i += 1) {
+    eff = null;
+    switch (effects[i].ty) {
+      case 0:
+        eff = new SliderEffect(effects[i], element, this);
+        break;
+      case 1:
+        eff = new AngleEffect(effects[i], element, this);
+        break;
+      case 2:
+        eff = new ColorEffect(effects[i], element, this);
+        break;
+      case 3:
+        eff = new PointEffect(effects[i], element, this);
+        break;
+      case 4:
+      case 7:
+        eff = new CheckboxEffect(effects[i], element, this);
+        break;
+      case 10:
+        eff = new LayerIndexEffect(effects[i], element, this);
+        break;
+      case 11:
+        eff = new MaskIndexEffect(effects[i], element, this);
+        break;
+      case 5:
+        eff = new EffectsManager(effects[i], element, this);
+        break;
+        // case 6:
+      default:
+        eff = new NoValueEffect(effects[i], element, this);
+        break;
+    }
+    if (eff) {
+      this.effectElements.push(eff);
+    }
+  }
+};
+
+function BaseElement() {
+}
+
+BaseElement.prototype = {
+  checkMasks: function () {
+    if (!this.data.hasMask) {
+      return false;
+    }
+    var i = 0;
+    var len = this.data.masksProperties.length;
+    while (i < len) {
+      if ((this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false)) {
+        return true;
+      }
+      i += 1;
+    }
+    return false;
+  },
+  initExpressions: function () {
+    const expressionsInterfaces = getExpressionInterfaces();
+    if (!expressionsInterfaces) {
+      return;
+    }
+    const LayerExpressionInterface = expressionsInterfaces('layer');
+    const EffectsExpressionInterface = expressionsInterfaces('effects');
+    const ShapeExpressionInterface = expressionsInterfaces('shape');
+    const TextExpressionInterface = expressionsInterfaces('text');
+    const CompExpressionInterface = expressionsInterfaces('comp');
+    this.layerInterface = LayerExpressionInterface(this);
+    if (this.data.hasMask && this.maskManager) {
+      this.layerInterface.registerMaskInterface(this.maskManager);
+    }
+    var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
+    this.layerInterface.registerEffectsInterface(effectsInterface);
+
+    if (this.data.ty === 0 || this.data.xt) {
+      this.compInterface = CompExpressionInterface(this);
+    } else if (this.data.ty === 4) {
+      this.layerInterface.shapeInterface = ShapeExpressionInterface(this.shapesData, this.itemsData, this.layerInterface);
+      this.layerInterface.content = this.layerInterface.shapeInterface;
+    } else if (this.data.ty === 5) {
+      this.layerInterface.textInterface = TextExpressionInterface(this);
+      this.layerInterface.text = this.layerInterface.textInterface;
+    }
+  },
+  setBlendMode: function () {
+    var blendModeValue = getBlendMode(this.data.bm);
+    var elem = this.baseElement || this.layerElement;
+
+    elem.style['mix-blend-mode'] = blendModeValue;
+  },
+  initBaseData: function (data, globalData, comp) {
+    this.globalData = globalData;
+    this.comp = comp;
+    this.data = data;
+    this.layerId = createElementID();
+
+    // Stretch factor for old animations missing this property.
+    if (!this.data.sr) {
+      this.data.sr = 1;
+    }
+    // effects manager
+    this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
+  },
+  getType: function () {
+    return this.type;
+  },
+  sourceRectAtTime: function () {},
+};
+
+/**
+ * @file
+ * Handles element's layer frame update.
+ * Checks layer in point and out point
+ *
+ */
+
+function FrameElement() {}
+
+FrameElement.prototype = {
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     */
+  initFrame: function () {
+    // set to true when inpoint is rendered
+    this._isFirstFrame = false;
+    // list of animated properties
+    this.dynamicProperties = [];
+    // If layer has been modified in current tick this will be true
+    this._mdf = false;
+  },
+  /**
+     * @function
+     * Calculates all dynamic values
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     * @param {boolean} isVisible
+     * if layers is currently in range
+     *
+     */
+  prepareProperties: function (num, isVisible) {
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      if (isVisible || (this._isParent && this.dynamicProperties[i].propType === 'transform')) {
+        this.dynamicProperties[i].getValue();
+        if (this.dynamicProperties[i]._mdf) {
+          this.globalData._mdf = true;
+          this._mdf = true;
+        }
+      }
+    }
+  },
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+    }
+  },
+};
+
+function FootageElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.footageData = globalData.imageLoader.getAsset(this.assetData);
+  this.initBaseData(data, globalData, comp);
+}
+
+FootageElement.prototype.prepareFrame = function () {
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
+
+FootageElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+FootageElement.prototype.renderFrame = function () {
+};
+
+FootageElement.prototype.destroy = function () {
+};
+
+FootageElement.prototype.initExpressions = function () {
+  const expressionsInterfaces = getExpressionInterfaces();
+  if (!expressionsInterfaces) {
+    return;
+  }
+  const FootageInterface = expressionsInterfaces('footage');
+  this.layerInterface = FootageInterface(this);
+};
+
+FootageElement.prototype.getFootageData = function () {
+  return this.footageData;
+};
+
+function AudioElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initBaseData(data, globalData, comp);
+  this._isPlaying = false;
+  this._canPlay = false;
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  this.audio = this.globalData.audioController.createAudio(assetPath);
+  this._currentTime = 0;
+  this.globalData.audioController.addAudio(this);
+  this._volumeMultiplier = 1;
+  this._volume = 1;
+  this._previousVolume = null;
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+  this.lv = PropertyFactory.getProp(this, data.au && data.au.lv ? data.au.lv : { k: [100] }, 1, 0.01, this);
+}
+
+AudioElement.prototype.prepareFrame = function (num) {
+  this.prepareRenderableFrame(num, true);
+  this.prepareProperties(num, true);
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    this._currentTime = timeRemapped;
+  } else {
+    this._currentTime = num / this.data.sr;
+  }
+  this._volume = this.lv.v[0];
+  var totalVolume = this._volume * this._volumeMultiplier;
+  if (this._previousVolume !== totalVolume) {
+    this._previousVolume = totalVolume;
+    this.audio.volume(totalVolume);
+  }
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
+
+AudioElement.prototype.renderFrame = function () {
+  if (this.isInRange && this._canPlay) {
+    if (!this._isPlaying) {
+      this.audio.play();
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+      this._isPlaying = true;
+    } else if (!this.audio.playing()
+      || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1
+    ) {
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+    }
+  }
+};
+
+AudioElement.prototype.show = function () {
+  // this.audio.play()
+};
+
+AudioElement.prototype.hide = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+};
+
+AudioElement.prototype.pause = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+  this._canPlay = false;
+};
+
+AudioElement.prototype.resume = function () {
+  this._canPlay = true;
+};
+
+AudioElement.prototype.setRate = function (rateValue) {
+  this.audio.rate(rateValue);
+};
+
+AudioElement.prototype.volume = function (volumeValue) {
+  this._volumeMultiplier = volumeValue;
+  this._previousVolume = volumeValue * this._volume;
+  this.audio.volume(this._previousVolume);
+};
+
+AudioElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+AudioElement.prototype.destroy = function () {
+};
+
+AudioElement.prototype.sourceRectAtTime = function () {
+};
+
+AudioElement.prototype.initExpressions = function () {
+};
+
+function BaseRenderer() {}
+BaseRenderer.prototype.checkLayers = function (num) {
+  var i;
+  var len = this.layers.length;
+  var data;
+  this.completeLayers = true;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (!this.elements[i]) {
+      data = this.layers[i];
+      if (data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) {
+        this.buildItem(i);
+      }
+    }
+    this.completeLayers = this.elements[i] ? this.completeLayers : false;
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.createItem = function (layer) {
+  switch (layer.ty) {
+    case 2:
+      return this.createImage(layer);
+    case 0:
+      return this.createComp(layer);
+    case 1:
+      return this.createSolid(layer);
+    case 3:
+      return this.createNull(layer);
+    case 4:
+      return this.createShape(layer);
+    case 5:
+      return this.createText(layer);
+    case 6:
+      return this.createAudio(layer);
+    case 13:
+      return this.createCamera(layer);
+    case 15:
+      return this.createFootage(layer);
+    default:
+      return this.createNull(layer);
+  }
+};
+
+BaseRenderer.prototype.createCamera = function () {
+  throw new Error('You\'re using a 3d camera. Try the html renderer.');
+};
+
+BaseRenderer.prototype.createAudio = function (data) {
+  return new AudioElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.createFootage = function (data) {
+  return new FootageElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.buildAllItems = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    this.buildItem(i);
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.includeLayers = function (newLayers) {
+  this.completeLayers = false;
+  var i;
+  var len = newLayers.length;
+  var j;
+  var jLen = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    j = 0;
+    while (j < jLen) {
+      if (this.layers[j].id === newLayers[i].id) {
+        this.layers[j] = newLayers[i];
+        break;
+      }
+      j += 1;
+    }
+  }
+};
+
+BaseRenderer.prototype.setProjectInterface = function (pInterface) {
+  this.globalData.projectInterface = pInterface;
+};
+
+BaseRenderer.prototype.initItems = function () {
+  if (!this.globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+};
+BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
+  var elements = this.elements;
+  var layers = this.layers;
+  var i = 0;
+  var len = layers.length;
+  while (i < len) {
+    if (layers[i].ind == parentName) { // eslint-disable-line eqeqeq
+      if (!elements[i] || elements[i] === true) {
+        this.buildItem(i);
+        this.addPendingElement(element);
+      } else {
+        hierarchy.push(elements[i]);
+        elements[i].setAsParent();
+        if (layers[i].parent !== undefined) {
+          this.buildElementParenting(element, layers[i].parent, hierarchy);
+        } else {
+          element.setHierarchy(hierarchy);
+        }
+      }
+    }
+    i += 1;
+  }
+};
+
+BaseRenderer.prototype.addPendingElement = function (element) {
+  this.pendingElements.push(element);
+};
+
+BaseRenderer.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var len = assets.length;
+  for (i = 0; i < len; i += 1) {
+    if (assets[i].xt) {
+      var comp = this.createComp(assets[i]);
+      comp.initExpressions();
+      this.globalData.projectInterface.registerComposition(comp);
+    }
+  }
+};
+
+BaseRenderer.prototype.getElementById = function (ind) {
+  var i;
+  var len = this.elements.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i].data.ind === ind) {
+      return this.elements[i];
+    }
+  }
+  return null;
+};
+
+BaseRenderer.prototype.getElementByPath = function (path) {
+  var pathValue = path.shift();
+  var element;
+  if (typeof pathValue === 'number') {
+    element = this.elements[pathValue];
+  } else {
+    var i;
+    var len = this.elements.length;
+    for (i = 0; i < len; i += 1) {
+      if (this.elements[i].data.nm === pathValue) {
+        element = this.elements[i];
+        break;
+      }
+    }
+  }
+  if (path.length === 0) {
+    return element;
+  }
+  return element.getElementByPath(path);
+};
+
+BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
+  this.globalData.fontManager = new FontManager();
+  this.globalData.slotManager = slotFactory(animData);
+  this.globalData.fontManager.addChars(animData.chars);
+  this.globalData.fontManager.addFonts(animData.fonts, fontsContainer);
+  this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+  this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+  this.globalData.imageLoader = this.animationItem.imagePreloader;
+  this.globalData.audioController = this.animationItem.audioController;
+  this.globalData.frameId = 0;
+  this.globalData.frameRate = animData.fr;
+  this.globalData.nm = animData.nm;
+  this.globalData.compSize = {
+    w: animData.w,
+    h: animData.h,
+  };
+};
+
+var effectTypes = {
+  TRANSFORM_EFFECT: 'transformEFfect',
+};
+
+function TransformElement() {}
+
+TransformElement.prototype = {
+  initTransform: function () {
+    var mat = new Matrix();
+    this.finalTransform = {
+      mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : { o: 0 },
+      _matMdf: false,
+      _localMatMdf: false,
+      _opMdf: false,
+      mat: mat,
+      localMat: mat,
+      localOpacity: 1,
+    };
+    if (this.data.ao) {
+      this.finalTransform.mProp.autoOriented = true;
+    }
+
+    // TODO: check TYPE 11: Guided elements
+    if (this.data.ty !== 11) {
+      // this.createElements();
+    }
+  },
+  renderTransform: function () {
+    this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
+    this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
+
+    if (this.hierarchy) {
+      var mat;
+      var finalMat = this.finalTransform.mat;
+      var i = 0;
+      var len = this.hierarchy.length;
+      // Checking if any of the transformation matrices in the hierarchy chain has changed.
+      if (!this.finalTransform._matMdf) {
+        while (i < len) {
+          if (this.hierarchy[i].finalTransform.mProp._mdf) {
+            this.finalTransform._matMdf = true;
+            break;
+          }
+          i += 1;
+        }
+      }
+
+      if (this.finalTransform._matMdf) {
+        mat = this.finalTransform.mProp.v.props;
+        finalMat.cloneFromProps(mat);
+        for (i = 0; i < len; i += 1) {
+          finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
+        }
+      }
+    }
+    if (!this.localTransforms || this.finalTransform._matMdf) {
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+    }
+    if (this.finalTransform._opMdf) {
+      this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderLocalTransform: function () {
+    if (this.localTransforms) {
+      var i = 0;
+      var len = this.localTransforms.length;
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+      if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
+        while (i < len) {
+          if (this.localTransforms[i]._mdf) {
+            this.finalTransform._localMatMdf = true;
+          }
+          if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
+            this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+            this.finalTransform._opMdf = true;
+          }
+          i += 1;
+        }
+      }
+      if (this.finalTransform._localMatMdf) {
+        var localMat = this.finalTransform.localMat;
+        this.localTransforms[0].matrix.clone(localMat);
+        for (i = 1; i < len; i += 1) {
+          var lmat = this.localTransforms[i].matrix;
+          localMat.multiply(lmat);
+        }
+        localMat.multiply(this.finalTransform.mat);
+      }
+      if (this.finalTransform._opMdf) {
+        var localOp = this.finalTransform.localOpacity;
+        for (i = 0; i < len; i += 1) {
+          localOp *= this.localTransforms[i].opacity * 0.01;
+        }
+        this.finalTransform.localOpacity = localOp;
+      }
+    }
+  },
+  searchEffectTransforms: function () {
+    if (this.renderableEffectsManager) {
+      var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+      if (transformEffects.length) {
+        this.localTransforms = [];
+        this.finalTransform.localMat = new Matrix();
+        var i = 0;
+        var len = transformEffects.length;
+        for (i = 0; i < len; i += 1) {
+          this.localTransforms.push(transformEffects[i]);
+        }
+      }
+    }
+  },
+  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;
+    var len = transforms.length;
+    var 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;
+  },
+  mHelper: new Matrix(),
+};
+
+function MaskElement(data, element, globalData) {
+  this.data = data;
+  this.element = element;
+  this.globalData = globalData;
+  this.storedData = [];
+  this.masksProperties = this.data.masksProperties || [];
+  this.maskElement = null;
+  var defs = this.globalData.defs;
+  var i;
+  var len = this.masksProperties ? this.masksProperties.length : 0;
+  this.viewData = createSizedArray(len);
+  this.solidPath = '';
+
+  var path;
+  var properties = this.masksProperties;
+  var count = 0;
+  var currentMasks = [];
+  var j;
+  var jLen;
+  var layerId = createElementID();
+  var rect;
+  var expansor;
+  var feMorph;
+  var x;
+  var maskType = 'clipPath';
+  var maskRef = 'clip-path';
+  for (i = 0; i < len; i += 1) {
+    if ((properties[i].mode !== 'a' && properties[i].mode !== 'n') || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
+      maskType = 'mask';
+      maskRef = 'mask';
+    }
+
+    if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
+      rect = createNS('rect');
+      rect.setAttribute('fill', '#ffffff');
+      rect.setAttribute('width', this.element.comp.data.w || 0);
+      rect.setAttribute('height', this.element.comp.data.h || 0);
+      currentMasks.push(rect);
+    } else {
+      rect = null;
+    }
+
+    path = createNS('path');
+    if (properties[i].mode === 'n') {
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        elem: path,
+        lastPath: '',
+      };
+      defs.appendChild(path);
+    } else {
+      count += 1;
+
+      path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      path.setAttribute('clip-rule', 'nonzero');
+      var filterID;
+
+      if (properties[i].x.k !== 0) {
+        maskType = 'mask';
+        maskRef = 'mask';
+        x = PropertyFactory.getProp(this.element, properties[i].x, 0, null, this.element);
+        filterID = createElementID();
+        expansor = createNS('filter');
+        expansor.setAttribute('id', filterID);
+        feMorph = createNS('feMorphology');
+        feMorph.setAttribute('operator', 'erode');
+        feMorph.setAttribute('in', 'SourceGraphic');
+        feMorph.setAttribute('radius', '0');
+        expansor.appendChild(feMorph);
+        defs.appendChild(expansor);
+        path.setAttribute('stroke', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      } else {
+        feMorph = null;
+        x = null;
+      }
+
+      // TODO move this to a factory or to a constructor
+      this.storedData[i] = {
+        elem: path,
+        x: x,
+        expan: feMorph,
+        lastPath: '',
+        lastOperator: '',
+        filterId: filterID,
+        lastRadius: 0,
+      };
+      if (properties[i].mode === 'i') {
+        jLen = currentMasks.length;
+        var g = createNS('g');
+        for (j = 0; j < jLen; j += 1) {
+          g.appendChild(currentMasks[j]);
+        }
+        var mask = createNS('mask');
+        mask.setAttribute('mask-type', 'alpha');
+        mask.setAttribute('id', layerId + '_' + count);
+        mask.appendChild(path);
+        defs.appendChild(mask);
+        g.setAttribute('mask', 'url(' + getLocationHref() + '#' + layerId + '_' + count + ')');
+
+        currentMasks.length = 0;
+        currentMasks.push(g);
+      } else {
+        currentMasks.push(path);
+      }
+      if (properties[i].inv && !this.solidPath) {
+        this.solidPath = this.createLayerSolidPath();
+      }
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        elem: path,
+        lastPath: '',
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        invRect: rect,
+      };
+      if (!this.viewData[i].prop.k) {
+        this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
+      }
+    }
+  }
+
+  this.maskElement = createNS(maskType);
+
+  len = currentMasks.length;
+  for (i = 0; i < len; i += 1) {
+    this.maskElement.appendChild(currentMasks[i]);
+  }
+
+  if (count > 0) {
+    this.maskElement.setAttribute('id', layerId);
+    this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
+    defs.appendChild(this.maskElement);
+  }
+  if (this.viewData.length) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+MaskElement.prototype.getMaskProperty = function (pos) {
+  return this.viewData[pos].prop;
+};
+
+MaskElement.prototype.renderFrame = function (isFirstFrame) {
+  var finalMat = this.element.finalTransform.mat;
+  var i;
+  var len = this.masksProperties.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.viewData[i].prop._mdf || isFirstFrame) {
+      this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
+    }
+    if (this.viewData[i].op._mdf || isFirstFrame) {
+      this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
+    }
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
+        this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
+      }
+      if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
+        var feMorph = this.storedData[i].expan;
+        if (this.storedData[i].x.v < 0) {
+          if (this.storedData[i].lastOperator !== 'erode') {
+            this.storedData[i].lastOperator = 'erode';
+            this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
+          }
+          feMorph.setAttribute('radius', -this.storedData[i].x.v);
+        } else {
+          if (this.storedData[i].lastOperator !== 'dilate') {
+            this.storedData[i].lastOperator = 'dilate';
+            this.storedData[i].elem.setAttribute('filter', null);
+          }
+          this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
+        }
+      }
+    }
+  }
+};
+
+MaskElement.prototype.getMaskelement = function () {
+  return this.maskElement;
+};
+
+MaskElement.prototype.createLayerSolidPath = function () {
+  var path = 'M0,0 ';
+  path += ' h' + this.globalData.compSize.w;
+  path += ' v' + this.globalData.compSize.h;
+  path += ' h-' + this.globalData.compSize.w;
+  path += ' v-' + this.globalData.compSize.h + ' ';
+  return path;
+};
+
+MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
+  var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  var i;
+  var len;
+  len = pathNodes._length;
+  for (i = 1; i < len; i += 1) {
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
+  }
+  // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+  if (pathNodes.c && len > 1) {
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  }
+  // pathNodes.__renderedString = pathString;
+
+  if (viewData.lastPath !== pathString) {
+    var pathShapeValue = '';
+    if (viewData.elem) {
+      if (pathNodes.c) {
+        pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
+      }
+      viewData.elem.setAttribute('d', pathShapeValue);
+    }
+    viewData.lastPath = pathString;
+  }
+};
+
+MaskElement.prototype.destroy = function () {
+  this.element = null;
+  this.globalData = null;
+  this.maskElement = null;
+  this.data = null;
+  this.masksProperties = null;
+};
+
+const filtersFactory = (function () {
+  var ob = {};
+  ob.createFilter = createFilter;
+  ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
+
+  function createFilter(filId, skipCoordinates) {
+    var fil = createNS('filter');
+    fil.setAttribute('id', filId);
+    if (skipCoordinates !== true) {
+      fil.setAttribute('filterUnits', 'objectBoundingBox');
+      fil.setAttribute('x', '0%');
+      fil.setAttribute('y', '0%');
+      fil.setAttribute('width', '100%');
+      fil.setAttribute('height', '100%');
+    }
+    return fil;
+  }
+
+  function createAlphaToLuminanceFilter() {
+    var feColorMatrix = createNS('feColorMatrix');
+    feColorMatrix.setAttribute('type', 'matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+    feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
+    return feColorMatrix;
+  }
+
+  return ob;
+}());
+
+const featureSupport = (function () {
+  var ob = {
+    maskType: true,
+    svgLumaHidden: true,
+    offscreenCanvas: typeof OffscreenCanvas !== 'undefined',
+  };
+  if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
+    ob.maskType = false;
+  }
+  if (/firefox/i.test(navigator.userAgent)) {
+    ob.svgLumaHidden = false;
+  }
+  return ob;
+}());
+
+var registeredEffects$1 = {};
+var idPrefix = 'filter_result_';
+
+function SVGEffects(elem) {
+  var i;
+  var source = 'SourceGraphic';
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  var filId = createElementID();
+  var fil = filtersFactory.createFilter(filId, true);
+  var count = 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects$1[type]) {
+      var Effect = registeredEffects$1[type].effect;
+      filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
+      source = idPrefix + count;
+      if (registeredEffects$1[type].countsAsEffect) {
+        count += 1;
+      }
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (count) {
+    elem.globalData.defs.appendChild(fil);
+    elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+SVGEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect$1(id, effect, countsAsEffect) {
+  registeredEffects$1[id] = {
+    effect,
+    countsAsEffect,
+  };
+}
+
+function SVGBaseElement() {
+}
+
+SVGBaseElement.prototype = {
+  initRendererElement: function () {
+    this.layerElement = createNS('g');
+  },
+  createContainerElements: function () {
+    this.matteElement = createNS('g');
+    this.transformedElement = this.layerElement;
+    this.maskedElement = this.layerElement;
+    this._sizeChanged = false;
+    var layerElementParent = null;
+    // If this layer acts as a mask for the following layer
+    if (this.data.td) {
+      this.matteMasks = {};
+      var gg = createNS('g');
+      gg.setAttribute('id', this.layerId);
+      gg.appendChild(this.layerElement);
+      layerElementParent = gg;
+      this.globalData.defs.appendChild(gg);
+    } else if (this.data.tt) {
+      this.matteElement.appendChild(this.layerElement);
+      layerElementParent = this.matteElement;
+      this.baseElement = this.matteElement;
+    } else {
+      this.baseElement = this.layerElement;
+    }
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
+    if (this.data.ty === 0 && !this.data.hd) {
+      var cp = createNS('clipPath');
+      var pt = createNS('path');
+      pt.setAttribute('d', 'M0,0 L' + this.data.w + ',0 L' + this.data.w + ',' + this.data.h + ' L0,' + this.data.h + 'z');
+      var clipId = createElementID();
+      cp.setAttribute('id', clipId);
+      cp.appendChild(pt);
+      this.globalData.defs.appendChild(cp);
+
+      if (this.checkMasks()) {
+        var cpGroup = createNS('g');
+        cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+        cpGroup.appendChild(this.layerElement);
+        this.transformedElement = cpGroup;
+        if (layerElementParent) {
+          layerElementParent.appendChild(this.transformedElement);
+        } else {
+          this.baseElement = this.transformedElement;
+        }
+      } else {
+        this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+      }
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    if (this.finalTransform._localMatMdf) {
+      this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
+    }
+    if (this.finalTransform._opMdf) {
+      this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
+    }
+  },
+  destroyBaseElement: function () {
+    this.layerElement = null;
+    this.matteElement = null;
+    this.maskManager.destroy();
+  },
+  getBaseElement: function () {
+    if (this.data.hd) {
+      return null;
+    }
+    return this.baseElement;
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+    this.renderableEffectsManager = new SVGEffects(this);
+    this.searchEffectTransforms();
+  },
+  getMatte: function (matteType) {
+    // This should not be a common case. But for backward compatibility, we'll create the matte object.
+    // It solves animations that have two consecutive layers marked as matte masks.
+    // Which is an undefined behavior in AE.
+    if (!this.matteMasks) {
+      this.matteMasks = {};
+    }
+    if (!this.matteMasks[matteType]) {
+      var id = this.layerId + '_' + matteType;
+      var filId;
+      var fil;
+      var useElement;
+      var gg;
+      if (matteType === 1 || matteType === 3) {
+        var masker = createNS('mask');
+        masker.setAttribute('id', id);
+        masker.setAttribute('mask-type', matteType === 3 ? 'luminance' : 'alpha');
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        masker.appendChild(useElement);
+        this.globalData.defs.appendChild(masker);
+        if (!featureSupport.maskType && matteType === 1) {
+          masker.setAttribute('mask-type', 'luminance');
+          filId = createElementID();
+          fil = filtersFactory.createFilter(filId);
+          this.globalData.defs.appendChild(fil);
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          gg.appendChild(useElement);
+          masker.appendChild(gg);
+          gg.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        }
+      } else if (matteType === 2) {
+        var maskGroup = createNS('mask');
+        maskGroup.setAttribute('id', id);
+        maskGroup.setAttribute('mask-type', 'alpha');
+        var maskGrouper = createNS('g');
+        maskGroup.appendChild(maskGrouper);
+        filId = createElementID();
+        fil = filtersFactory.createFilter(filId);
+        /// /
+        var feCTr = createNS('feComponentTransfer');
+        feCTr.setAttribute('in', 'SourceGraphic');
+        fil.appendChild(feCTr);
+        var feFunc = createNS('feFuncA');
+        feFunc.setAttribute('type', 'table');
+        feFunc.setAttribute('tableValues', '1.0 0.0');
+        feCTr.appendChild(feFunc);
+        /// /
+        this.globalData.defs.appendChild(fil);
+        var alphaRect = createNS('rect');
+        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');
+        alphaRect.setAttribute('opacity', '0');
+        maskGrouper.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        maskGrouper.appendChild(alphaRect);
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        maskGrouper.appendChild(useElement);
+        if (!featureSupport.maskType) {
+          maskGroup.setAttribute('mask-type', 'luminance');
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          maskGrouper.appendChild(alphaRect);
+          gg.appendChild(this.layerElement);
+          maskGrouper.appendChild(gg);
+        }
+        this.globalData.defs.appendChild(maskGroup);
+      }
+      this.matteMasks[matteType] = id;
+    }
+    return this.matteMasks[matteType];
+  },
+  setMatte: function (id) {
+    if (!this.matteElement) {
+      return;
+    }
+    this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+  },
+};
+
+/**
+ * @file
+ * Handles AE's layer parenting property.
+ *
+ */
+
+function HierarchyElement() {}
+
+HierarchyElement.prototype = {
+  /**
+     * @function
+     * Initializes hierarchy properties
+     *
+     */
+  initHierarchy: function () {
+    // element's parent list
+    this.hierarchy = [];
+    // if element is parent of another layer _isParent will be true
+    this._isParent = false;
+    this.checkParenting();
+  },
+  /**
+     * @function
+     * Sets layer's hierarchy.
+     * @param {array} hierarch
+     * layer's parent list
+     *
+     */
+  setHierarchy: function (hierarchy) {
+    this.hierarchy = hierarchy;
+  },
+  /**
+     * @function
+     * Sets layer as parent.
+     *
+     */
+  setAsParent: function () {
+    this._isParent = true;
+  },
+  /**
+     * @function
+     * Searches layer's parenting chain
+     *
+     */
+  checkParenting: function () {
+    if (this.data.parent !== undefined) {
+      this.comp.buildElementParenting(this, this.data.parent, []);
+    }
+  },
+};
+
+function RenderableDOMElement() {}
+
+(function () {
+  var _prototype = {
+    initElement: function (data, globalData, comp) {
+      this.initFrame();
+      this.initBaseData(data, globalData, comp);
+      this.initTransform(data, globalData, comp);
+      this.initHierarchy();
+      this.initRenderable();
+      this.initRendererElement();
+      this.createContainerElements();
+      this.createRenderableComponents();
+      this.createContent();
+      this.hide();
+    },
+    hide: function () {
+      // console.log('HIDE', this);
+      if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+        var elem = this.baseElement || this.layerElement;
+        elem.style.display = 'none';
+        this.hidden = true;
+      }
+    },
+    show: function () {
+      // console.log('SHOW', this);
+      if (this.isInRange && !this.isTransparent) {
+        if (!this.data.hd) {
+          var elem = this.baseElement || this.layerElement;
+          elem.style.display = 'block';
+        }
+        this.hidden = false;
+        this._isFirstFrame = true;
+      }
+    },
+    renderFrame: function () {
+      // If it is exported as hidden (data.hd === true) no need to render
+      // If it is not visible no need to render
+      if (this.data.hd || this.hidden) {
+        return;
+      }
+      this.renderTransform();
+      this.renderRenderable();
+      this.renderLocalTransform();
+      this.renderElement();
+      this.renderInnerContent();
+      if (this._isFirstFrame) {
+        this._isFirstFrame = false;
+      }
+    },
+    renderInnerContent: function () {},
+    prepareFrame: function (num) {
+      this._mdf = false;
+      this.prepareRenderableFrame(num);
+      this.prepareProperties(num, this.isInRange);
+      this.checkTransparency();
+    },
+    destroy: function () {
+      this.innerElem = null;
+      this.destroyBaseElement();
+    },
+  };
+  extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement);
+}());
+
+function IImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  if (this.assetData && this.assetData.sid) {
+    this.assetData = globalData.slotManager.getProp(this.assetData);
+  }
+  this.initElement(data, globalData, comp);
+  this.sourceRect = {
+    top: 0, left: 0, width: this.assetData.w, height: this.assetData.h,
+  };
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
+
+IImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+
+  this.innerElem = createNS('image');
+  this.innerElem.setAttribute('width', this.assetData.w + 'px');
+  this.innerElem.setAttribute('height', this.assetData.h + 'px');
+  this.innerElem.setAttribute('preserveAspectRatio', this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio);
+  this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+
+  this.layerElement.appendChild(this.innerElem);
+};
+
+IImageElement.prototype.sourceRectAtTime = function () {
+  return this.sourceRect;
+};
+
+function ProcessedElement(element, position) {
+  this.elem = element;
+  this.pos = position;
+}
+
+function IShapeElement() {
+}
+
+IShapeElement.prototype = {
+  addShapeToModifiers: function (data) {
+    var i;
+    var len = this.shapeModifiers.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapeModifiers[i].addShape(data);
+    }
+  },
+  isShapeInAnimatedModifiers: function (data) {
+    var i = 0;
+    var len = this.shapeModifiers.length;
+    while (i < len) {
+      if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
+        return true;
+      }
+    }
+    return false;
+  },
+  renderModifiers: function () {
+    if (!this.shapeModifiers.length) {
+      return;
+    }
+    var i;
+    var len = this.shapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].sh.reset();
+    }
+
+    len = this.shapeModifiers.length;
+    var shouldBreakProcess;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+      // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+      // TODO: find a better solution for this
+      if (shouldBreakProcess) {
+        break;
+      }
+    }
+  },
+
+  searchProcessedElement: function (elem) {
+    var elements = this.processedElements;
+    var i = 0;
+    var len = elements.length;
+    while (i < len) {
+      if (elements[i].elem === elem) {
+        return elements[i].pos;
+      }
+      i += 1;
+    }
+    return 0;
+  },
+  addProcessedElement: function (elem, pos) {
+    var elements = this.processedElements;
+    var i = elements.length;
+    while (i) {
+      i -= 1;
+      if (elements[i].elem === elem) {
+        elements[i].pos = pos;
+        return;
+      }
+    }
+    elements.push(new ProcessedElement(elem, pos));
+  },
+  prepareFrame: function (num) {
+    this.prepareRenderableFrame(num);
+    this.prepareProperties(num, this.isInRange);
+  },
+};
+
+const lineCapEnum = {
+  1: 'butt',
+  2: 'round',
+  3: 'square',
+};
+
+const lineJoinEnum = {
+  1: 'miter',
+  2: 'round',
+  3: 'bevel',
+};
+
+function SVGShapeData(transformers, level, shape) {
+  this.caches = [];
+  this.styles = [];
+  this.transformers = transformers;
+  this.lStr = '';
+  this.sh = shape;
+  this.lvl = level;
+  // TODO find if there are some cases where _isAnimated can be false.
+  // For now, since shapes add up with other shapes. They have to be calculated every time.
+  // One way of finding out is checking if all styles associated to this shape depend only of this shape
+  this._isAnimated = !!shape.k;
+  // TODO: commenting this for now since all shapes are animated
+  var i = 0;
+  var len = transformers.length;
+  while (i < len) {
+    if (transformers[i].mProps.dynamicProperties.length) {
+      this._isAnimated = true;
+      break;
+    }
+    i += 1;
+  }
+}
+
+SVGShapeData.prototype.setAsAnimated = function () {
+  this._isAnimated = true;
+};
+
+function SVGStyleData(data, level) {
+  this.data = data;
+  this.type = data.ty;
+  this.d = '';
+  this.lvl = level;
+  this._mdf = false;
+  this.closed = data.hd === true;
+  this.pElem = createNS('path');
+  this.msElem = null;
+}
+
+SVGStyleData.prototype.reset = function () {
+  this.d = '';
+  this._mdf = false;
+};
+
+function DashProperty(elem, data, renderer, container) {
+  this.elem = elem;
+  this.frameId = -1;
+  this.dataProps = createSizedArray(data.length);
+  this.renderer = renderer;
+  this.k = false;
+  this.dashStr = '';
+  this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0);
+  this.dashoffset = createTypedArray('float32', 1);
+  this.initDynamicPropertyContainer(container);
+  var i;
+  var len = data.length || 0;
+  var prop;
+  for (i = 0; i < len; i += 1) {
+    prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
+    this.k = prop.k || this.k;
+    this.dataProps[i] = { n: data[i].n, p: prop };
+  }
+  if (!this.k) {
+    this.getValue(true);
+  }
+  this._isAnimated = this.k;
+}
+
+DashProperty.prototype.getValue = function (forceRender) {
+  if (this.elem.globalData.frameId === this.frameId && !forceRender) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+  this._mdf = this._mdf || forceRender;
+  if (this._mdf) {
+    var i = 0;
+    var len = this.dataProps.length;
+    if (this.renderer === 'svg') {
+      this.dashStr = '';
+    }
+    for (i = 0; i < len; i += 1) {
+      if (this.dataProps[i].n !== 'o') {
+        if (this.renderer === 'svg') {
+          this.dashStr += ' ' + this.dataProps[i].p.v;
+        } else {
+          this.dashArray[i] = this.dataProps[i].p.v;
+        }
+      } else {
+        this.dashoffset[0] = this.dataProps[i].p.v;
+      }
+    }
+  }
+};
+extendPrototype([DynamicPropertyContainer], DashProperty);
+
+function SVGStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
+
+function SVGFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
+
+function SVGNoStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
+
+function GradientProperty(elem, data, container) {
+  this.data = data;
+  this.c = createTypedArray('uint8c', data.p * 4);
+  var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p * 4) : data.k.k.length - data.p * 4;
+  this.o = createTypedArray('float32', cLength);
+  this._cmdf = false;
+  this._omdf = false;
+  this._collapsable = this.checkCollapsable();
+  this._hasOpacity = cLength;
+  this.initDynamicPropertyContainer(container);
+  this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this);
+  this.k = this.prop.k;
+  this.getValue(true);
+}
+
+GradientProperty.prototype.comparePoints = function (values, points) {
+  var i = 0;
+  var len = this.o.length / 2;
+  var diff;
+  while (i < len) {
+    diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
+    if (diff > 0.01) {
+      return false;
+    }
+    i += 1;
+  }
+  return true;
+};
+
+GradientProperty.prototype.checkCollapsable = function () {
+  if (this.o.length / 2 !== this.c.length / 4) {
+    return false;
+  }
+  if (this.data.k.k[0].s) {
+    var i = 0;
+    var len = this.data.k.k.length;
+    while (i < len) {
+      if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
+        return false;
+      }
+      i += 1;
+    }
+  } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
+    return false;
+  }
+  return true;
+};
+
+GradientProperty.prototype.getValue = function (forceRender) {
+  this.prop.getValue();
+  this._mdf = false;
+  this._cmdf = false;
+  this._omdf = false;
+  if (this.prop._mdf || forceRender) {
+    var i;
+    var len = this.data.p * 4;
+    var mult;
+    var val;
+    for (i = 0; i < len; i += 1) {
+      mult = i % 4 === 0 ? 100 : 255;
+      val = Math.round(this.prop.v[i] * mult);
+      if (this.c[i] !== val) {
+        this.c[i] = val;
+        this._cmdf = !forceRender;
+      }
+    }
+    if (this.o.length) {
+      len = this.prop.v.length;
+      for (i = this.data.p * 4; i < len; i += 1) {
+        mult = i % 2 === 0 ? 100 : 1;
+        val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
+        if (this.o[i - this.data.p * 4] !== val) {
+          this.o[i - this.data.p * 4] = val;
+          this._omdf = !forceRender;
+        }
+      }
+    }
+    this._mdf = !forceRender;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], GradientProperty);
+
+function SVGGradientFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.initGradientData(elem, data, styleOb);
+}
+
+SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 1, null, this);
+  this.h = PropertyFactory.getProp(elem, data.h || { k: 0 }, 0, 0.01, this);
+  this.a = PropertyFactory.getProp(elem, data.a || { k: 0 }, 0, degToRads, this);
+  this.g = new GradientProperty(elem, data.g, this);
+  this.style = styleOb;
+  this.stops = [];
+  this.setGradientData(styleOb.pElem, data);
+  this.setGradientOpacity(data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+};
+
+SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
+  var gradientId = createElementID();
+  var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+  gfill.setAttribute('id', gradientId);
+  gfill.setAttribute('spreadMethod', 'pad');
+  gfill.setAttribute('gradientUnits', 'userSpaceOnUse');
+  var stops = [];
+  var stop;
+  var j;
+  var jLen;
+  jLen = data.g.p * 4;
+  for (j = 0; j < jLen; j += 4) {
+    stop = createNS('stop');
+    gfill.appendChild(stop);
+    stops.push(stop);
+  }
+  pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
+  this.gf = gfill;
+  this.cst = stops;
+};
+
+SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
+  if (this.g._hasOpacity && !this.g._collapsable) {
+    var stop;
+    var j;
+    var jLen;
+    var mask = createNS('mask');
+    var maskElement = createNS('path');
+    mask.appendChild(maskElement);
+    var opacityId = createElementID();
+    var maskId = createElementID();
+    mask.setAttribute('id', maskId);
+    var opFill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+    opFill.setAttribute('id', opacityId);
+    opFill.setAttribute('spreadMethod', 'pad');
+    opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
+    jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
+    var stops = this.stops;
+    for (j = data.g.p * 4; j < jLen; j += 2) {
+      stop = createNS('stop');
+      stop.setAttribute('stop-color', 'rgb(255,255,255)');
+      opFill.appendChild(stop);
+      stops.push(stop);
+    }
+    maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
+    this.maskId = maskId;
+    styleOb.msElem = maskElement;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
+
+function SVGGradientStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.initGradientData(elem, data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
+
+function ShapeGroupData() {
+  this.it = [];
+  this.prevViewData = [];
+  this.gr = createNS('g');
+}
+
+function SVGTransformData(mProps, op, container) {
+  this.transform = {
+    mProps: mProps,
+    op: op,
+    container: container,
+  };
+  this.elements = [];
+  this._isAnimated = this.transform.mProps.dynamicProperties.length || this.transform.op.effectsSequence.length;
+}
+
+const buildShapeString = function (pathNodes, length, closed, mat) {
+  if (length === 0) {
+    return '';
+  }
+  var _o = pathNodes.o;
+  var _i = pathNodes.i;
+  var _v = pathNodes.v;
+  var i;
+  var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+  for (i = 1; i < length; i += 1) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
+  }
+  if (closed && length) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+    shapeString += 'z';
+  }
+  return shapeString;
+};
+
+const SVGElementsRenderer = (function () {
+  var _identityMatrix = new Matrix();
+  var _matrixHelper = new Matrix();
+
+  var ob = {
+    createRenderFunction: createRenderFunction,
+  };
+
+  function createRenderFunction(data) {
+    switch (data.ty) {
+      case 'fl':
+        return renderFill;
+      case 'gf':
+        return renderGradient;
+      case 'gs':
+        return renderGradientStroke;
+      case 'st':
+        return renderStroke;
+      case 'sh':
+      case 'el':
+      case 'rc':
+      case 'sr':
+        return renderPath;
+      case 'tr':
+        return renderContentTransform;
+      case 'no':
+        return renderNoop;
+      default:
+        return null;
+    }
+  }
+
+  function renderContentTransform(styleData, itemData, isFirstFrame) {
+    if (isFirstFrame || itemData.transform.op._mdf) {
+      itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
+    }
+    if (isFirstFrame || itemData.transform.mProps._mdf) {
+      itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
+    }
+  }
+
+  function renderNoop() {
+
+  }
+
+  function renderPath(styleData, itemData, isFirstFrame) {
+    var j;
+    var jLen;
+    var pathStringTransformed;
+    var redraw;
+    var pathNodes;
+    var l;
+    var lLen = itemData.styles.length;
+    var lvl = itemData.lvl;
+    var paths;
+    var mat;
+    var iterations;
+    var k;
+    for (l = 0; l < lLen; l += 1) {
+      redraw = itemData.sh._mdf || isFirstFrame;
+      if (itemData.styles[l].lvl < lvl) {
+        mat = _matrixHelper.reset();
+        iterations = lvl - itemData.styles[l].lvl;
+        k = itemData.transformers.length - 1;
+        while (!redraw && iterations > 0) {
+          redraw = itemData.transformers[k].mProps._mdf || redraw;
+          iterations -= 1;
+          k -= 1;
+        }
+        if (redraw) {
+          iterations = lvl - itemData.styles[l].lvl;
+          k = itemData.transformers.length - 1;
+          while (iterations > 0) {
+            mat.multiply(itemData.transformers[k].mProps.v);
+            iterations -= 1;
+            k -= 1;
+          }
+        }
+      } else {
+        mat = _identityMatrix;
+      }
+      paths = itemData.sh.paths;
+      jLen = paths._length;
+      if (redraw) {
+        pathStringTransformed = '';
+        for (j = 0; j < jLen; j += 1) {
+          pathNodes = paths.shapes[j];
+          if (pathNodes && pathNodes._length) {
+            pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
+          }
+        }
+        itemData.caches[l] = pathStringTransformed;
+      } else {
+        pathStringTransformed = itemData.caches[l];
+      }
+      itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
+      itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
+    }
+  }
+
+  function renderFill(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+
+    if (itemData.c._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
+    }
+  }
+
+  function renderGradientStroke(styleData, itemData, isFirstFrame) {
+    renderGradient(styleData, itemData, isFirstFrame);
+    renderStroke(styleData, itemData, isFirstFrame);
+  }
+
+  function renderGradient(styleData, itemData, isFirstFrame) {
+    var gfill = itemData.gf;
+    var hasOpacity = itemData.g._hasOpacity;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+
+    if (itemData.o._mdf || isFirstFrame) {
+      var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
+      itemData.style.pElem.setAttribute(attr, itemData.o.v);
+    }
+    if (itemData.s._mdf || isFirstFrame) {
+      var attr1 = styleData.t === 1 ? 'x1' : 'cx';
+      var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
+      gfill.setAttribute(attr1, pt1[0]);
+      gfill.setAttribute(attr2, pt1[1]);
+      if (hasOpacity && !itemData.g._collapsable) {
+        itemData.of.setAttribute(attr1, pt1[0]);
+        itemData.of.setAttribute(attr2, pt1[1]);
+      }
+    }
+    var stops;
+    var i;
+    var len;
+    var stop;
+    if (itemData.g._cmdf || isFirstFrame) {
+      stops = itemData.cst;
+      var cValues = itemData.g.c;
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        stop.setAttribute('offset', cValues[i * 4] + '%');
+        stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
+      }
+    }
+    if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
+      var oValues = itemData.g.o;
+      if (itemData.g._collapsable) {
+        stops = itemData.cst;
+      } else {
+        stops = itemData.ost;
+      }
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        if (!itemData.g._collapsable) {
+          stop.setAttribute('offset', oValues[i * 2] + '%');
+        }
+        stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
+      }
+    }
+    if (styleData.t === 1) {
+      if (itemData.e._mdf || isFirstFrame) {
+        gfill.setAttribute('x2', pt2[0]);
+        gfill.setAttribute('y2', pt2[1]);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('x2', pt2[0]);
+          itemData.of.setAttribute('y2', pt2[1]);
+        }
+      }
+    } else {
+      var rad;
+      if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
+        rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        gfill.setAttribute('r', rad);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('r', rad);
+        }
+      }
+      if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (!rad) {
+          rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        }
+        var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+        var percent = itemData.h.v;
+        if (percent >= 1) {
+          percent = 0.99;
+        } else if (percent <= -1) {
+          percent = -0.99;
+        }
+        var dist = rad * percent;
+        var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+        var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+        gfill.setAttribute('fx', x);
+        gfill.setAttribute('fy', y);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('fx', x);
+          itemData.of.setAttribute('fy', y);
+        }
+      }
+      // gfill.setAttribute('fy','200');
+    }
+  }
+
+  function renderStroke(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+    var d = itemData.d;
+    if (d && (d._mdf || isFirstFrame) && d.dashStr) {
+      styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
+      styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
+    }
+    if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
+      styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
+    }
+    if (itemData.w._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
+      if (styleElem.msElem) {
+        styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
+      }
+    }
+  }
+
+  return ob;
+}());
+
+function SVGShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
+
+SVGShapeElement.prototype.initSecondaryElement = function () {
+};
+
+SVGShapeElement.prototype.identityMatrix = new Matrix();
+
+SVGShapeElement.prototype.buildExpressionInterface = function () {};
+
+SVGShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+};
+
+/*
+This method searches for multiple shapes that affect a single element and one of them is animated
+*/
+SVGShapeElement.prototype.filterUniqueShapes = function () {
+  var i;
+  var len = this.shapes.length;
+  var shape;
+  var j;
+  var jLen = this.stylesList.length;
+  var style;
+  var tempShapes = [];
+  var areAnimated = false;
+  for (j = 0; j < jLen; j += 1) {
+    style = this.stylesList[j];
+    areAnimated = false;
+    tempShapes.length = 0;
+    for (i = 0; i < len; i += 1) {
+      shape = this.shapes[i];
+      if (shape.styles.indexOf(style) !== -1) {
+        tempShapes.push(shape);
+        areAnimated = shape._isAnimated || areAnimated;
+      }
+    }
+    if (tempShapes.length > 1 && areAnimated) {
+      this.setShapesAsAnimated(tempShapes);
+    }
+  }
+};
+
+SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
+  var i;
+  var len = shapes.length;
+  for (i = 0; i < len; i += 1) {
+    shapes[i].setAsAnimated();
+  }
+};
+
+SVGShapeElement.prototype.createStyleElement = function (data, level) {
+  // TODO: prevent drawing of hidden styles
+  var elementData;
+  var styleOb = new SVGStyleData(data, level);
+
+  var pathElement = styleOb.pElem;
+  if (data.ty === 'st') {
+    elementData = new SVGStrokeStyleData(this, data, styleOb);
+  } else if (data.ty === 'fl') {
+    elementData = new SVGFillStyleData(this, data, styleOb);
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
+    elementData = new GradientConstructor(this, data, styleOb);
+    this.globalData.defs.appendChild(elementData.gf);
+    if (elementData.maskId) {
+      this.globalData.defs.appendChild(elementData.ms);
+      this.globalData.defs.appendChild(elementData.of);
+      pathElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + elementData.maskId + ')');
+    }
+  } else if (data.ty === 'no') {
+    elementData = new SVGNoStyleData(this, data, styleOb);
+  }
+
+  if (data.ty === 'st' || data.ty === 'gs') {
+    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);
+    }
+  }
+
+  if (data.r === 2) {
+    pathElement.setAttribute('fill-rule', 'evenodd');
+  }
+
+  if (data.ln) {
+    pathElement.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    pathElement.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  this.stylesList.push(styleOb);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createGroupElement = function (data) {
+  var elementData = new ShapeGroupData();
+  if (data.ln) {
+    elementData.gr.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    elementData.gr.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  return elementData;
+};
+
+SVGShapeElement.prototype.createTransformElement = function (data, container) {
+  var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
+  var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
+  var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
+  var i = 0;
+  var len = this.animatedContents.length;
+  while (i < len) {
+    if (this.animatedContents[i].element === element) {
+      return;
+    }
+    i += 1;
+  }
+  this.animatedContents.push({
+    fn: SVGElementsRenderer.createRenderFunction(data),
+    element: element,
+    data: data,
+  });
+};
+
+SVGShapeElement.prototype.setElementStyles = function (elementData) {
+  var arr = elementData.styles;
+  var j;
+  var jLen = this.stylesList.length;
+  for (j = 0; j < jLen; j += 1) {
+    if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
+      arr.push(this.stylesList[j]);
+    }
+  }
+};
+
+SVGShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+};
+
+SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
+  var ownTransformers = [].concat(transformers);
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var currentTransform;
+  var modifier;
+  var processedPos;
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._render = render;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], level);
+      } else {
+        itemsData[i].style.closed = arr[i].hd;
+      }
+      if (arr[i]._render) {
+        if (itemsData[i].style.pElem.parentNode !== container) {
+          container.appendChild(itemsData[i].style.pElem);
+        }
+      }
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
+      if (arr[i]._render) {
+        if (itemsData[i].gr.parentNode !== container) {
+          container.appendChild(itemsData[i].gr);
+        }
+      }
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        itemsData[i] = this.createTransformElement(arr[i], container);
+      }
+      currentTransform = itemsData[i].transform;
+      ownTransformers.push(currentTransform);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
+      }
+      this.setElementStyles(itemsData[i]);
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        render = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  len = ownStyles.length;
+  for (i = 0; i < len; i += 1) {
+    ownStyles[i].closed = true;
+  }
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+SVGShapeElement.prototype.renderInnerContent = function () {
+  this.renderModifiers();
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    this.stylesList[i].reset();
+  }
+  this.renderShape();
+  for (i = 0; i < len; i += 1) {
+    if (this.stylesList[i]._mdf || this._isFirstFrame) {
+      if (this.stylesList[i].msElem) {
+        this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+        // Adding M0 0 fixes same mask bug on all browsers
+        this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
+      }
+      this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
+    }
+  }
+};
+
+SVGShapeElement.prototype.renderShape = function () {
+  var i;
+  var len = this.animatedContents.length;
+  var animatedContent;
+  for (i = 0; i < len; i += 1) {
+    animatedContent = this.animatedContents[i];
+    if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
+      animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
+    }
+  }
+};
+
+SVGShapeElement.prototype.destroy = function () {
+  this.destroyBaseElement();
+  this.shapesData = null;
+  this.itemsData = null;
+};
+
+function LetterProps(o, sw, sc, fc, m, p) {
+  this.o = o;
+  this.sw = sw;
+  this.sc = sc;
+  this.fc = fc;
+  this.m = m;
+  this.p = p;
+  this._mdf = {
+    o: true,
+    sw: !!sw,
+    sc: !!sc,
+    fc: !!fc,
+    m: true,
+    p: true,
+  };
+}
+
+LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
+  this._mdf.o = false;
+  this._mdf.sw = false;
+  this._mdf.sc = false;
+  this._mdf.fc = false;
+  this._mdf.m = false;
+  this._mdf.p = false;
+  var updated = false;
+
+  if (this.o !== o) {
+    this.o = o;
+    this._mdf.o = true;
+    updated = true;
+  }
+  if (this.sw !== sw) {
+    this.sw = sw;
+    this._mdf.sw = true;
+    updated = true;
+  }
+  if (this.sc !== sc) {
+    this.sc = sc;
+    this._mdf.sc = true;
+    updated = true;
+  }
+  if (this.fc !== fc) {
+    this.fc = fc;
+    this._mdf.fc = true;
+    updated = true;
+  }
+  if (this.m !== m) {
+    this.m = m;
+    this._mdf.m = true;
+    updated = true;
+  }
+  if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
+    this.p = p;
+    this._mdf.p = true;
+    updated = true;
+  }
+  return updated;
+};
+
+function TextProperty(elem, data) {
+  this._frameId = initialDefaultFrame;
+  this.pv = '';
+  this.v = '';
+  this.kf = false;
+  this._isFirstFrame = true;
+  this._mdf = false;
+  if (data.d && data.d.sid) {
+    data.d = elem.globalData.slotManager.getProp(data.d);
+  }
+  this.data = data;
+  this.elem = elem;
+  this.comp = this.elem.comp;
+  this.keysIndex = 0;
+  this.canResize = false;
+  this.minimumFontSize = 1;
+  this.effectsSequence = [];
+  this.currentData = {
+    ascent: 0,
+    boxWidth: this.defaultBoxWidth,
+    f: '',
+    fStyle: '',
+    fWeight: '',
+    fc: '',
+    j: '',
+    justifyOffset: '',
+    l: [],
+    lh: 0,
+    lineWidths: [],
+    ls: '',
+    of: '',
+    s: '',
+    sc: '',
+    sw: 0,
+    t: 0,
+    tr: 0,
+    sz: 0,
+    ps: null,
+    fillColorAnim: false,
+    strokeColorAnim: false,
+    strokeWidthAnim: false,
+    yOffset: 0,
+    finalSize: 0,
+    finalText: [],
+    finalLineHeight: 0,
+    __complete: false,
+
+  };
+  this.copyData(this.currentData, this.data.d.k[0].s);
+
+  if (!this.searchProperty()) {
+    this.completeTextData(this.currentData);
+  }
+}
+
+TextProperty.prototype.defaultBoxWidth = [0, 0];
+
+TextProperty.prototype.copyData = function (obj, data) {
+  for (var s in data) {
+    if (Object.prototype.hasOwnProperty.call(data, s)) {
+      obj[s] = data[s];
+    }
+  }
+  return obj;
+};
+
+TextProperty.prototype.setCurrentData = function (data) {
+  if (!data.__complete) {
+    this.completeTextData(data);
+  }
+  this.currentData = data;
+  this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
+  this._mdf = true;
+};
+
+TextProperty.prototype.searchProperty = function () {
+  return this.searchKeyframes();
+};
+
+TextProperty.prototype.searchKeyframes = function () {
+  this.kf = this.data.d.k.length > 1;
+  if (this.kf) {
+    this.addEffect(this.getKeyframeValue.bind(this));
+  }
+  return this.kf;
+};
+
+TextProperty.prototype.addEffect = function (effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.getValue = function (_finalValue) {
+  if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
+    return;
+  }
+  this.currentData.t = this.data.d.k[this.keysIndex].s.t;
+  var currentValue = this.currentData;
+  var currentIndex = this.keysIndex;
+  if (this.lock) {
+    this.setCurrentData(this.currentData);
+    return;
+  }
+  this.lock = true;
+  this._mdf = false;
+  var i; var
+    len = this.effectsSequence.length;
+  var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
+  for (i = 0; i < len; i += 1) {
+    // Checking if index changed to prevent creating a new object every time the expression updates.
+    if (currentIndex !== this.keysIndex) {
+      finalValue = this.effectsSequence[i](finalValue, finalValue.t);
+    } else {
+      finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
+    }
+  }
+  if (currentValue !== finalValue) {
+    this.setCurrentData(finalValue);
+  }
+  this.v = this.currentData;
+  this.pv = this.v;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+};
+
+TextProperty.prototype.getKeyframeValue = function () {
+  var textKeys = this.data.d.k;
+  var frameNum = this.elem.comp.renderedFrame;
+  var i = 0; var
+    len = textKeys.length;
+  while (i <= len - 1) {
+    if (i === len - 1 || textKeys[i + 1].t > frameNum) {
+      break;
+    }
+    i += 1;
+  }
+  if (this.keysIndex !== i) {
+    this.keysIndex = i;
+  }
+  return this.data.d.k[this.keysIndex].s;
+};
+
+TextProperty.prototype.buildFinalText = function (text) {
+  var charactersArray = [];
+  var i = 0;
+  var len = text.length;
+  var charCode;
+  var secondCharCode;
+  var shouldCombine = false;
+  var shouldCombineNext = false;
+  var currentChars = '';
+  while (i < len) {
+    shouldCombine = shouldCombineNext;
+    shouldCombineNext = false;
+    charCode = text.charCodeAt(i);
+    currentChars = text.charAt(i);
+    if (FontManager.isCombinedCharacter(charCode)) {
+      shouldCombine = true;
+      // It's a potential surrogate pair (this is the High surrogate)
+    } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+      if (FontManager.isRegionalFlag(text, i)) {
+        currentChars = text.substr(i, 14);
+      } else {
+        secondCharCode = text.charCodeAt(i + 1);
+        // It's a surrogate pair (this is the Low surrogate)
+        if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
+          if (FontManager.isModifier(charCode, secondCharCode)) {
+            currentChars = text.substr(i, 2);
+            shouldCombine = true;
+          } else if (FontManager.isFlagEmoji(text.substr(i, 4))) {
+            currentChars = text.substr(i, 4);
+          } else {
+            currentChars = text.substr(i, 2);
+          }
+        }
+      }
+    } else if (charCode > 0xDBFF) {
+      secondCharCode = text.charCodeAt(i + 1);
+      if (FontManager.isVariationSelector(charCode)) {
+        shouldCombine = true;
+      }
+    } else if (FontManager.isZeroWidthJoiner(charCode)) {
+      shouldCombine = true;
+      shouldCombineNext = true;
+    }
+    if (shouldCombine) {
+      charactersArray[charactersArray.length - 1] += currentChars;
+      shouldCombine = false;
+    } else {
+      charactersArray.push(currentChars);
+    }
+    i += currentChars.length;
+  }
+  return charactersArray;
+};
+
+TextProperty.prototype.completeTextData = function (documentData) {
+  documentData.__complete = true;
+  var fontManager = this.elem.globalData.fontManager;
+  var data = this.data;
+  var letters = [];
+  var i; var
+    len;
+  var newLineFlag; var index = 0; var
+    val;
+  var anchorGrouping = data.m.g;
+  var currentSize = 0; var currentPos = 0; var currentLine = 0; var
+    lineWidths = [];
+  var lineWidth = 0;
+  var maxLineWidth = 0;
+  var j; var
+    jLen;
+  var fontData = fontManager.getFontByName(documentData.f);
+  var charData; var
+    cLength = 0;
+
+  var fontProps = getFontProperties(fontData);
+  documentData.fWeight = fontProps.weight;
+  documentData.fStyle = fontProps.style;
+  documentData.finalSize = documentData.s;
+  documentData.finalText = this.buildFinalText(documentData.t);
+  len = documentData.finalText.length;
+  documentData.finalLineHeight = documentData.lh;
+  var trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+  var charCode;
+  if (documentData.sz) {
+    var flag = true;
+    var boxWidth = documentData.sz[0];
+    var boxHeight = documentData.sz[1];
+    var currentHeight; var
+      finalText;
+    while (flag) {
+      finalText = this.buildFinalText(documentData.t);
+      currentHeight = 0;
+      lineWidth = 0;
+      len = finalText.length;
+      trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+      var lastSpaceIndex = -1;
+      for (i = 0; i < len; i += 1) {
+        charCode = finalText[i].charCodeAt(0);
+        newLineFlag = false;
+        if (finalText[i] === ' ') {
+          lastSpaceIndex = i;
+        } else if (charCode === 13 || charCode === 3) {
+          lineWidth = 0;
+          newLineFlag = true;
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+        }
+        if (fontManager.chars) {
+          charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
+          cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+        } else {
+          // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
+          cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
+        }
+        if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
+          if (lastSpaceIndex === -1) {
+            len += 1;
+          } else {
+            i = lastSpaceIndex;
+          }
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+          finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+          // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
+          lastSpaceIndex = -1;
+          lineWidth = 0;
+        } else {
+          lineWidth += cLength;
+          lineWidth += trackingOffset;
+        }
+      }
+      currentHeight += (fontData.ascent * documentData.finalSize) / 100;
+      if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
+        documentData.finalSize -= 1;
+        documentData.finalLineHeight = (documentData.finalSize * documentData.lh) / documentData.s;
+      } else {
+        documentData.finalText = finalText;
+        len = documentData.finalText.length;
+        flag = false;
+      }
+    }
+  }
+  lineWidth = -trackingOffset;
+  cLength = 0;
+  var uncollapsedSpaces = 0;
+  var currentChar;
+  for (i = 0; i < len; i += 1) {
+    newLineFlag = false;
+    currentChar = documentData.finalText[i];
+    charCode = currentChar.charCodeAt(0);
+    if (charCode === 13 || charCode === 3) {
+      uncollapsedSpaces = 0;
+      lineWidths.push(lineWidth);
+      maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+      lineWidth = -2 * trackingOffset;
+      val = '';
+      newLineFlag = true;
+      currentLine += 1;
+    } else {
+      val = currentChar;
+    }
+    if (fontManager.chars) {
+      charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
+      cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+    } else {
+      // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
+      // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
+      cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
+    }
+
+    //
+    if (currentChar === ' ') {
+      uncollapsedSpaces += cLength + trackingOffset;
+    } else {
+      lineWidth += cLength + trackingOffset + uncollapsedSpaces;
+      uncollapsedSpaces = 0;
+    }
+    letters.push({
+      l: cLength, an: cLength, add: currentSize, n: newLineFlag, anIndexes: [], val: val, line: currentLine, animatorJustifyOffset: 0,
+    });
+    if (anchorGrouping == 2) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || val === ' ' || i === len - 1) {
+        if (val === '' || val === ' ') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        index += 1;
+        currentSize = 0;
+      }
+    } else if (anchorGrouping == 3) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || i === len - 1) {
+        if (val === '') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        currentSize = 0;
+        index += 1;
+      }
+    } else {
+      letters[index].ind = index;
+      letters[index].extra = 0;
+      index += 1;
+    }
+  }
+  documentData.l = letters;
+  maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+  lineWidths.push(lineWidth);
+  if (documentData.sz) {
+    documentData.boxWidth = documentData.sz[0];
+    documentData.justifyOffset = 0;
+  } else {
+    documentData.boxWidth = maxLineWidth;
+    switch (documentData.j) {
+      case 1:
+        documentData.justifyOffset = -documentData.boxWidth;
+        break;
+      case 2:
+        documentData.justifyOffset = -documentData.boxWidth / 2;
+        break;
+      default:
+        documentData.justifyOffset = 0;
+    }
+  }
+  documentData.lineWidths = lineWidths;
+
+  var animators = data.a; var animatorData; var
+    letterData;
+  jLen = animators.length;
+  var based; var ind; var
+    indexes = [];
+  for (j = 0; j < jLen; j += 1) {
+    animatorData = animators[j];
+    if (animatorData.a.sc) {
+      documentData.strokeColorAnim = true;
+    }
+    if (animatorData.a.sw) {
+      documentData.strokeWidthAnim = true;
+    }
+    if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
+      documentData.fillColorAnim = true;
+    }
+    ind = 0;
+    based = animatorData.s.b;
+    for (i = 0; i < len; i += 1) {
+      letterData = letters[i];
+      letterData.anIndexes[j] = ind;
+      if ((based == 1 && letterData.val !== '') || (based == 2 && letterData.val !== '' && letterData.val !== ' ') || (based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1)) || (based == 4 && (letterData.n || i == len - 1))) { // eslint-disable-line eqeqeq
+        if (animatorData.s.rn === 1) {
+          indexes.push(ind);
+        }
+        ind += 1;
+      }
+    }
+    data.a[j].s.totalChars = ind;
+    var currentInd = -1; var
+      newInd;
+    if (animatorData.s.rn === 1) {
+      for (i = 0; i < len; i += 1) {
+        letterData = letters[i];
+        if (currentInd != letterData.anIndexes[j]) { // eslint-disable-line eqeqeq
+          currentInd = letterData.anIndexes[j];
+          newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
+        }
+        letterData.anIndexes[j] = newInd;
+      }
+    }
+  }
+  documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
+  documentData.ls = documentData.ls || 0;
+  documentData.ascent = (fontData.ascent * documentData.finalSize) / 100;
+};
+
+TextProperty.prototype.updateDocumentData = function (newData, index) {
+  index = index === undefined ? this.keysIndex : index;
+  var dData = this.copyData({}, this.data.d.k[index].s);
+  dData = this.copyData(dData, newData);
+  this.data.d.k[index].s = dData;
+  this.recalculate(index);
+  this.setCurrentData(dData);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.recalculate = function (index) {
+  var dData = this.data.d.k[index].s;
+  dData.__complete = false;
+  this.keysIndex = 0;
+  this._isFirstFrame = true;
+  this.getValue(dData);
+};
+
+TextProperty.prototype.canResizeFont = function (_canResize) {
+  this.canResize = _canResize;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
+  this.minimumFontSize = Math.floor(_fontValue) || 1;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+const TextSelectorProp = (function () {
+  var max = Math.max;
+  var min = Math.min;
+  var floor = Math.floor;
+
+  function TextSelectorPropFactory(elem, data) {
+    this._currentTextLength = -1;
+    this.k = false;
+    this.data = data;
+    this.elem = elem;
+    this.comp = elem.comp;
+    this.finalS = 0;
+    this.finalE = 0;
+    this.initDynamicPropertyContainer(elem);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: 0 }, 0, 0, this);
+    if ('e' in data) {
+      this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
+    } else {
+      this.e = { v: 100 };
+    }
+    this.o = PropertyFactory.getProp(elem, data.o || { k: 0 }, 0, 0, this);
+    this.xe = PropertyFactory.getProp(elem, data.xe || { k: 0 }, 0, 0, this);
+    this.ne = PropertyFactory.getProp(elem, data.ne || { k: 0 }, 0, 0, this);
+    this.sm = PropertyFactory.getProp(elem, data.sm || { k: 100 }, 0, 0, this);
+    this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
+    if (!this.dynamicProperties.length) {
+      this.getValue();
+    }
+  }
+
+  TextSelectorPropFactory.prototype = {
+    getMult: function (ind) {
+      if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
+        this.getValue();
+      }
+      var x1 = 0;
+      var y1 = 0;
+      var x2 = 1;
+      var y2 = 1;
+      if (this.ne.v > 0) {
+        x1 = this.ne.v / 100.0;
+      } else {
+        y1 = -this.ne.v / 100.0;
+      }
+      if (this.xe.v > 0) {
+        x2 = 1.0 - this.xe.v / 100.0;
+      } else {
+        y2 = 1.0 + this.xe.v / 100.0;
+      }
+      var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
+
+      var mult = 0;
+      var s = this.finalS;
+      var e = this.finalE;
+      var type = this.data.sh;
+      if (type === 2) {
+        if (e === s) {
+          mult = ind >= e ? 1 : 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+        mult = easer(mult);
+      } else if (type === 3) {
+        if (e === s) {
+          mult = ind >= e ? 0 : 1;
+        } else {
+          mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+
+        mult = easer(mult);
+      } else if (type === 4) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+          if (mult < 0.5) {
+            mult *= 2;
+          } else {
+            mult = 1 - 2 * (mult - 0.5);
+          }
+        }
+        mult = easer(mult);
+      } else if (type === 5) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          var tot = e - s;
+          /* ind += 0.5;
+                    mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          var x = -tot / 2 + ind;
+          var a = tot / 2;
+          mult = Math.sqrt(1 - (x * x) / (a * a));
+        }
+        mult = easer(mult);
+      } else if (type === 6) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; // eslint-disable-line
+        }
+        mult = easer(mult);
+      } else {
+        if (ind >= floor(s)) {
+          if (ind - s < 0) {
+            mult = max(0, min(min(e, 1) - (s - ind), 1));
+          } else {
+            mult = max(0, min(e - ind, 1));
+          }
+        }
+        mult = easer(mult);
+      }
+      // Smoothness implementation.
+      // The smoothness represents a reduced range of the original [0; 1] range.
+      // if smoothness is 25%, the new range will be [0.375; 0.625]
+      // Steps are:
+      // - find the lower value of the new range (threshold)
+      // - if multiplier is smaller than that value, floor it to 0
+      // - if it is larger,
+      //     - subtract the threshold
+      //     - divide it by the smoothness (this will return the range to [0; 1])
+      // Note: If it doesn't work on some scenarios, consider applying it before the easer.
+      if (this.sm.v !== 100) {
+        var smoothness = this.sm.v * 0.01;
+        if (smoothness === 0) {
+          smoothness = 0.00000001;
+        }
+        var threshold = 0.5 - smoothness * 0.5;
+        if (mult < threshold) {
+          mult = 0;
+        } else {
+          mult = (mult - threshold) / smoothness;
+          if (mult > 1) {
+            mult = 1;
+          }
+        }
+      }
+      return mult * this.a.v;
+    },
+    getValue: function (newCharsFlag) {
+      this.iterateDynamicProperties();
+      this._mdf = newCharsFlag || this._mdf;
+      this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
+      if (newCharsFlag && this.data.r === 2) {
+        this.e.v = this._currentTextLength;
+      }
+      var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
+      var o = this.o.v / divisor;
+      var s = this.s.v / divisor + o;
+      var e = (this.e.v / divisor) + o;
+      if (s > e) {
+        var _s = s;
+        s = e;
+        e = _s;
+      }
+      this.finalS = s;
+      this.finalE = e;
+    },
+  };
+  extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
+
+  function getTextSelectorProp(elem, data, arr) {
+    return new TextSelectorPropFactory(elem, data, arr);
+  }
+
+  return {
+    getTextSelectorProp: getTextSelectorProp,
+  };
+}());
+
+function TextAnimatorDataProperty(elem, animatorProps, container) {
+  var defaultData = { propType: false };
+  var getProp = PropertyFactory.getProp;
+  var textAnimatorAnimatables = animatorProps.a;
+  this.a = {
+    r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData,
+    rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData,
+    ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData,
+    sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData,
+    sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData,
+    s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData,
+    a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData,
+    o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData,
+    p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData,
+    sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData,
+    sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData,
+    fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData,
+    fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData,
+    fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData,
+    fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData,
+    t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData,
+  };
+
+  this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container);
+  this.s.t = animatorProps.s.t;
+}
+
+function TextAnimatorProperty(textData, renderType, elem) {
+  this._isFirstFrame = true;
+  this._hasMaskedPath = false;
+  this._frameId = -1;
+  this._textData = textData;
+  this._renderType = renderType;
+  this._elem = elem;
+  this._animatorsData = createSizedArray(this._textData.a.length);
+  this._pathData = {};
+  this._moreOptions = {
+    alignment: {},
+  };
+  this.renderedLetters = [];
+  this.lettersChangedFlag = false;
+  this.initDynamicPropertyContainer(elem);
+}
+
+TextAnimatorProperty.prototype.searchProperties = function () {
+  var i;
+  var len = this._textData.a.length;
+  var animatorProps;
+  var getProp = PropertyFactory.getProp;
+  for (i = 0; i < len; i += 1) {
+    animatorProps = this._textData.a[i];
+    this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
+  }
+  if (this._textData.p && 'm' in this._textData.p) {
+    this._pathData = {
+      a: getProp(this._elem, this._textData.p.a, 0, 0, this),
+      f: getProp(this._elem, this._textData.p.f, 0, 0, this),
+      l: getProp(this._elem, this._textData.p.l, 0, 0, this),
+      r: getProp(this._elem, this._textData.p.r, 0, 0, this),
+      p: getProp(this._elem, this._textData.p.p, 0, 0, this),
+      m: this._elem.maskManager.getMaskProperty(this._textData.p.m),
+    };
+    this._hasMaskedPath = true;
+  } else {
+    this._hasMaskedPath = false;
+  }
+  this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
+};
+
+TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
+  this.lettersChangedFlag = lettersChangedFlag;
+  if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
+    return;
+  }
+  this._isFirstFrame = false;
+  var alignment = this._moreOptions.alignment.v;
+  var animators = this._animatorsData;
+  var textData = this._textData;
+  var matrixHelper = this.mHelper;
+  var renderType = this._renderType;
+  var renderedLettersCount = this.renderedLetters.length;
+  var xPos;
+  var yPos;
+  var i;
+  var len;
+  var letters = documentData.l;
+  var pathInfo;
+  var currentLength;
+  var currentPoint;
+  var segmentLength;
+  var flag;
+  var pointInd;
+  var segmentInd;
+  var prevPoint;
+  var points;
+  var segments;
+  var partialLength;
+  var totalLength;
+  var perc;
+  var tanAngle;
+  var mask;
+  if (this._hasMaskedPath) {
+    mask = this._pathData.m;
+    if (!this._pathData.n || this._pathData._mdf) {
+      var paths = mask.v;
+      if (this._pathData.r.v) {
+        paths = paths.reverse();
+      }
+      // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
+      pathInfo = {
+        tLength: 0,
+        segments: [],
+      };
+      len = paths._length - 1;
+      var bezierData;
+      totalLength = 0;
+      for (i = 0; i < len; i += 1) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[i + 1],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      i = len;
+      if (mask.v.c) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[0],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      this._pathData.pi = pathInfo;
+    }
+    pathInfo = this._pathData.pi;
+
+    currentLength = this._pathData.f.v;
+    segmentInd = 0;
+    pointInd = 1;
+    segmentLength = 0;
+    flag = true;
+    segments = pathInfo.segments;
+    if (currentLength < 0 && mask.v.c) {
+      if (pathInfo.tLength < Math.abs(currentLength)) {
+        currentLength = -Math.abs(currentLength) % pathInfo.tLength;
+      }
+      segmentInd = segments.length - 1;
+      points = segments[segmentInd].points;
+      pointInd = points.length - 1;
+      while (currentLength < 0) {
+        currentLength += points[pointInd].partialLength;
+        pointInd -= 1;
+        if (pointInd < 0) {
+          segmentInd -= 1;
+          points = segments[segmentInd].points;
+          pointInd = points.length - 1;
+        }
+      }
+    }
+    points = segments[segmentInd].points;
+    prevPoint = points[pointInd - 1];
+    currentPoint = points[pointInd];
+    partialLength = currentPoint.partialLength;
+  }
+
+  len = letters.length;
+  xPos = 0;
+  yPos = 0;
+  var yOff = documentData.finalSize * 1.2 * 0.714;
+  var firstLine = true;
+  var animatorProps;
+  var animatorSelector;
+  var j;
+  var jLen;
+  var letterValue;
+
+  jLen = animators.length;
+
+  var mult;
+  var ind = -1;
+  var offf;
+  var xPathPos;
+  var yPathPos;
+  var initPathPos = currentLength;
+  var initSegmentInd = segmentInd;
+  var initPointInd = pointInd;
+  var currentLine = -1;
+  var elemOpacity;
+  var sc;
+  var sw;
+  var fc;
+  var k;
+  var letterSw;
+  var letterSc;
+  var letterFc;
+  var letterM = '';
+  var letterP = this.defaultPropsArray;
+  var letterO;
+
+  //
+  if (documentData.j === 2 || documentData.j === 1) {
+    var animatorJustifyOffset = 0;
+    var animatorFirstCharOffset = 0;
+    var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
+    var lastIndex = 0;
+    var isNewLine = true;
+
+    for (i = 0; i < len; i += 1) {
+      if (letters[i].n) {
+        if (animatorJustifyOffset) {
+          animatorJustifyOffset += animatorFirstCharOffset;
+        }
+        while (lastIndex < i) {
+          letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+          lastIndex += 1;
+        }
+        animatorJustifyOffset = 0;
+        isNewLine = true;
+      } else {
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.t.propType) {
+            if (isNewLine && documentData.j === 2) {
+              animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
+            }
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
+            } else {
+              animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult;
+            }
+          }
+        }
+        isNewLine = false;
+      }
+    }
+    if (animatorJustifyOffset) {
+      animatorJustifyOffset += animatorFirstCharOffset;
+    }
+    while (lastIndex < i) {
+      letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+      lastIndex += 1;
+    }
+  }
+  //
+
+  for (i = 0; i < len; i += 1) {
+    matrixHelper.reset();
+    elemOpacity = 1;
+    if (letters[i].n) {
+      xPos = 0;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      currentLength = initPathPos;
+      firstLine = false;
+      if (this._hasMaskedPath) {
+        segmentInd = initSegmentInd;
+        pointInd = initPointInd;
+        points = segments[segmentInd].points;
+        prevPoint = points[pointInd - 1];
+        currentPoint = points[pointInd];
+        partialLength = currentPoint.partialLength;
+        segmentLength = 0;
+      }
+      letterM = '';
+      letterFc = '';
+      letterSw = '';
+      letterO = '';
+      letterP = this.defaultPropsArray;
+    } else {
+      if (this._hasMaskedPath) {
+        if (currentLine !== letters[i].line) {
+          switch (documentData.j) {
+            case 1:
+              currentLength += totalLength - documentData.lineWidths[letters[i].line];
+              break;
+            case 2:
+              currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
+              break;
+            default:
+              break;
+          }
+          currentLine = letters[i].line;
+        }
+        if (ind !== letters[i].ind) {
+          if (letters[ind]) {
+            currentLength += letters[ind].extra;
+          }
+          currentLength += letters[i].an / 2;
+          ind = letters[i].ind;
+        }
+        currentLength += (alignment[0] * letters[i].an) * 0.005;
+        var animatorOffset = 0;
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.p.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.p.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.p.v[0] * mult;
+            }
+          }
+          if (animatorProps.a.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.a.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.a.v[0] * mult;
+            }
+          }
+        }
+        flag = true;
+        // Force alignment only works with a single line for now
+        if (this._pathData.a.v) {
+          currentLength = letters[0].an * 0.5 + ((totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind) / (len - 1);
+          currentLength += this._pathData.f.v;
+        }
+        while (flag) {
+          if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
+            perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
+            xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
+            yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
+            matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, -(alignment[1] * yOff) * 0.01);
+            flag = false;
+          } else if (points) {
+            segmentLength += currentPoint.partialLength;
+            pointInd += 1;
+            if (pointInd >= points.length) {
+              pointInd = 0;
+              segmentInd += 1;
+              if (!segments[segmentInd]) {
+                if (mask.v.c) {
+                  pointInd = 0;
+                  segmentInd = 0;
+                  points = segments[segmentInd].points;
+                } else {
+                  segmentLength -= currentPoint.partialLength;
+                  points = null;
+                }
+              } else {
+                points = segments[segmentInd].points;
+              }
+            }
+            if (points) {
+              prevPoint = currentPoint;
+              currentPoint = points[pointInd];
+              partialLength = currentPoint.partialLength;
+            }
+          }
+        }
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+      } else {
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+
+        // Grouping alignment
+        matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, (-alignment[1] * yOff) * 0.01, 0);
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.t.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
+          if (xPos !== 0 || documentData.j !== 0) {
+            if (this._hasMaskedPath) {
+              if (mult.length) {
+                currentLength += animatorProps.t.v * mult[0];
+              } else {
+                currentLength += animatorProps.t.v * mult;
+              }
+            } else if (mult.length) {
+              xPos += animatorProps.t.v * mult[0];
+            } else {
+              xPos += animatorProps.t.v * mult;
+            }
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        sw = documentData.sw || 0;
+      }
+      if (documentData.strokeColorAnim) {
+        if (documentData.sc) {
+          sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
+        } else {
+          sc = [0, 0, 0];
+        }
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.a.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+
+          if (mult.length) {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.s.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (mult.length) {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult[0]), 1 + ((animatorProps.s.v[1] - 1) * mult[1]), 1);
+          } else {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult), 1 + ((animatorProps.s.v[1] - 1) * mult), 1);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        animatorSelector = animators[j].s;
+        mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+        if (animatorProps.sk.propType) {
+          if (mult.length) {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
+          } else {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
+          }
+        }
+        if (animatorProps.r.propType) {
+          if (mult.length) {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
+          } else {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult);
+          }
+        }
+        if (animatorProps.ry.propType) {
+          if (mult.length) {
+            matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
+          } else {
+            matrixHelper.rotateY(animatorProps.ry.v * mult);
+          }
+        }
+        if (animatorProps.rx.propType) {
+          if (mult.length) {
+            matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
+          } else {
+            matrixHelper.rotateX(animatorProps.rx.v * mult);
+          }
+        }
+        if (animatorProps.o.propType) {
+          if (mult.length) {
+            elemOpacity += ((animatorProps.o.v) * mult[0] - elemOpacity) * mult[0];
+          } else {
+            elemOpacity += ((animatorProps.o.v) * mult - elemOpacity) * mult;
+          }
+        }
+        if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
+          if (mult.length) {
+            sw += animatorProps.sw.v * mult[0];
+          } else {
+            sw += animatorProps.sw.v * mult;
+          }
+        }
+        if (documentData.strokeColorAnim && animatorProps.sc.propType) {
+          for (k = 0; k < 3; k += 1) {
+            if (mult.length) {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0];
+            } else {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult;
+            }
+          }
+        }
+        if (documentData.fillColorAnim && documentData.fc) {
+          if (animatorProps.fc.propType) {
+            for (k = 0; k < 3; k += 1) {
+              if (mult.length) {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0];
+              } else {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult;
+              }
+            }
+          }
+          if (animatorProps.fh.propType) {
+            if (mult.length) {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
+            } else {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult);
+            }
+          }
+          if (animatorProps.fs.propType) {
+            if (mult.length) {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
+            } else {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
+            }
+          }
+          if (animatorProps.fb.propType) {
+            if (mult.length) {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
+            } else {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult);
+            }
+          }
+        }
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+
+        if (animatorProps.p.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (this._hasMaskedPath) {
+            if (mult.length) {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
+            } else {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+            }
+          } else if (mult.length) {
+            matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        letterSw = sw < 0 ? 0 : sw;
+      }
+      if (documentData.strokeColorAnim) {
+        letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
+      }
+
+      if (this._hasMaskedPath) {
+        matrixHelper.translate(0, -documentData.ls);
+
+        matrixHelper.translate(0, (alignment[1] * yOff) * 0.01 + yPos, 0);
+        if (this._pathData.p.v) {
+          tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
+          var rot = (Math.atan(tanAngle) * 180) / Math.PI;
+          if (currentPoint.point[0] < prevPoint.point[0]) {
+            rot += 180;
+          }
+          matrixHelper.rotate((-rot * Math.PI) / 180);
+        }
+        matrixHelper.translate(xPathPos, yPathPos, 0);
+        currentLength -= (alignment[0] * letters[i].an) * 0.005;
+        if (letters[i + 1] && ind !== letters[i + 1].ind) {
+          currentLength += letters[i].an / 2;
+          currentLength += (documentData.tr * 0.001) * documentData.finalSize;
+        }
+      } else {
+        matrixHelper.translate(xPos, yPos, 0);
+
+        if (documentData.ps) {
+          // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
+          matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+        }
+        switch (documentData.j) {
+          case 1:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
+            break;
+          case 2:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
+            break;
+          default:
+            break;
+        }
+        matrixHelper.translate(0, -documentData.ls);
+        matrixHelper.translate(offf, 0, 0);
+        matrixHelper.translate((alignment[0] * letters[i].an) * 0.005, (alignment[1] * yOff) * 0.01, 0);
+        xPos += letters[i].l + (documentData.tr * 0.001) * documentData.finalSize;
+      }
+      if (renderType === 'html') {
+        letterM = matrixHelper.toCSS();
+      } else if (renderType === 'svg') {
+        letterM = matrixHelper.to2dCSS();
+      } else {
+        letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
+      }
+      letterO = elemOpacity;
+    }
+
+    if (renderedLettersCount <= i) {
+      letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
+      this.renderedLetters.push(letterValue);
+      renderedLettersCount += 1;
+      this.lettersChangedFlag = true;
+    } else {
+      letterValue = this.renderedLetters[i];
+      this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag;
+    }
+  }
+};
+
+TextAnimatorProperty.prototype.getValue = function () {
+  if (this._elem.globalData.frameId === this._frameId) {
+    return;
+  }
+  this._frameId = this._elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+TextAnimatorProperty.prototype.mHelper = new Matrix();
+TextAnimatorProperty.prototype.defaultPropsArray = [];
+extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
+
+function ITextElement() {
+}
+
+ITextElement.prototype.initElement = function (data, globalData, comp) {
+  this.lettersChangedFlag = true;
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.textProperty = new TextProperty(this, data.t, this.dynamicProperties);
+  this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this);
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+  this.initRenderable();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  this.createContent();
+  this.hide();
+  this.textAnimator.searchProperties(this.dynamicProperties);
+};
+
+ITextElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+};
+
+ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
+  var j;
+  var jLen = shapes.length;
+  var pathNodes;
+  var shapeStr = '';
+  for (j = 0; j < jLen; j += 1) {
+    if (shapes[j].ty === 'sh') {
+      pathNodes = shapes[j].ks.k;
+      shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
+    }
+  }
+  return shapeStr;
+};
+
+ITextElement.prototype.updateDocumentData = function (newData, index) {
+  this.textProperty.updateDocumentData(newData, index);
+};
+
+ITextElement.prototype.canResizeFont = function (_canResize) {
+  this.textProperty.canResizeFont(_canResize);
+};
+
+ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
+  this.textProperty.setMinimumFontSize(_fontSize);
+};
+
+ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
+  if (documentData.ps) {
+    matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+  }
+  matrixHelper.translate(0, -documentData.ls, 0);
+  switch (documentData.j) {
+    case 1:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
+      break;
+    case 2:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
+      break;
+    default:
+      break;
+  }
+  matrixHelper.translate(xPos, yPos, 0);
+};
+
+ITextElement.prototype.buildColor = function (colorData) {
+  return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
+};
+
+ITextElement.prototype.emptyProp = new LetterProps();
+
+ITextElement.prototype.destroy = function () {
+
+};
+
+ITextElement.prototype.validateText = function () {
+  if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
+    this.buildNewText();
+    this.textProperty._isFirstFrame = false;
+    this.textProperty._mdf = false;
+  }
+};
+
+var emptyShapeData = {
+  shapes: [],
+};
+
+function SVGTextLottieElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.renderType = 'svg';
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
+
+SVGTextLottieElement.prototype.createContent = function () {
+  if (this.data.singleShape && !this.globalData.fontManager.chars) {
+    this.textContainer = createNS('text');
+  }
+};
+
+SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
+  var i = 0;
+  var len = textArray.length;
+  var textContents = [];
+  var currentTextContent = '';
+  while (i < len) {
+    if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
+      textContents.push(currentTextContent);
+      currentTextContent = '';
+    } else {
+      currentTextContent += textArray[i];
+    }
+    i += 1;
+  }
+  textContents.push(currentTextContent);
+  return textContents;
+};
+
+SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
+  // data should probably be cloned to apply scale separately to each instance of a text on different layers
+  // but since text internal content gets only rendered once and then it's never rerendered,
+  // it's probably safe not to clone data and reuse always the same instance even if the object is mutated.
+  // Avoiding cloning is preferred since cloning each character shape data is expensive
+  if (data.shapes && data.shapes.length) {
+    var shape = data.shapes[0];
+    if (shape.it) {
+      var shapeItem = shape.it[shape.it.length - 1];
+      if (shapeItem.s) {
+        shapeItem.s.k[0] = scale;
+        shapeItem.s.k[1] = scale;
+      }
+    }
+  }
+  return data;
+};
+
+SVGTextLottieElement.prototype.buildNewText = function () {
+  this.addDynamicProperty(this);
+  var i;
+  var len;
+
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
+  if (documentData.fc) {
+    this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
+  } else {
+    this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
+  }
+  if (documentData.sc) {
+    this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
+    this.layerElement.setAttribute('stroke-width', documentData.sw);
+  }
+  this.layerElement.setAttribute('font-size', documentData.finalSize);
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (fontData.fClass) {
+    this.layerElement.setAttribute('class', fontData.fClass);
+  } else {
+    this.layerElement.setAttribute('font-family', fontData.fFamily);
+    var fWeight = documentData.fWeight;
+    var fStyle = documentData.fStyle;
+    this.layerElement.setAttribute('font-style', fStyle);
+    this.layerElement.setAttribute('font-weight', fWeight);
+  }
+  this.layerElement.setAttribute('aria-label', documentData.t);
+
+  var letters = documentData.l || [];
+  var usesGlyphs = !!this.globalData.fontManager.chars;
+  len = letters.length;
+
+  var tSpan;
+  var matrixHelper = this.mHelper;
+  var shapeStr = '';
+  var singleShape = this.data.singleShape;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  if (singleShape && !usesGlyphs && !documentData.sz) {
+    var tElement = this.textContainer;
+    var justify = 'start';
+    switch (documentData.j) {
+      case 1:
+        justify = 'end';
+        break;
+      case 2:
+        justify = 'middle';
+        break;
+      default:
+        justify = 'start';
+        break;
+    }
+    tElement.setAttribute('text-anchor', justify);
+    tElement.setAttribute('letter-spacing', trackingOffset);
+    var textContent = this.buildTextContents(documentData.finalText);
+    len = textContent.length;
+    yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
+    for (i = 0; i < len; i += 1) {
+      tSpan = this.textSpans[i].span || createNS('tspan');
+      tSpan.textContent = textContent[i];
+      tSpan.setAttribute('x', 0);
+      tSpan.setAttribute('y', yPos);
+      tSpan.style.display = 'inherit';
+      tElement.appendChild(tSpan);
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          glyph: null,
+        };
+      }
+      this.textSpans[i].span = tSpan;
+      yPos += documentData.finalLineHeight;
+    }
+
+    this.layerElement.appendChild(tElement);
+  } else {
+    var cachedSpansLength = this.textSpans.length;
+    var charData;
+    for (i = 0; i < len; i += 1) {
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          childSpan: null,
+          glyph: null,
+        };
+      }
+      if (!usesGlyphs || !singleShape || i === 0) {
+        tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
+        if (cachedSpansLength <= i) {
+          tSpan.setAttribute('stroke-linecap', 'butt');
+          tSpan.setAttribute('stroke-linejoin', 'round');
+          tSpan.setAttribute('stroke-miterlimit', '4');
+          this.textSpans[i].span = tSpan;
+          if (usesGlyphs) {
+            var childSpan = createNS('g');
+            tSpan.appendChild(childSpan);
+            this.textSpans[i].childSpan = childSpan;
+          }
+          this.textSpans[i].span = tSpan;
+          this.layerElement.appendChild(tSpan);
+        }
+        tSpan.style.display = 'inherit';
+      }
+
+      matrixHelper.reset();
+      if (singleShape) {
+        if (letters[i].n) {
+          xPos = -trackingOffset;
+          yPos += documentData.yOffset;
+          yPos += firstLine ? 1 : 0;
+          firstLine = false;
+        }
+        this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+        xPos += letters[i].l || 0;
+        // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
+        xPos += trackingOffset;
+      }
+      if (usesGlyphs) {
+        charData = this.globalData.fontManager.getCharData(
+          documentData.finalText[i],
+          fontData.fStyle,
+          this.globalData.fontManager.getFontByName(documentData.f).fFamily
+        );
+        var glyphElement;
+        // t === 1 means the character has been replaced with an animated shaped
+        if (charData.t === 1) {
+          glyphElement = new SVGCompElement(charData.data, this.globalData, this);
+        } else {
+          var data = emptyShapeData;
+          if (charData.data && charData.data.shapes) {
+            data = this.buildShapeData(charData.data, documentData.finalSize);
+          }
+          glyphElement = new SVGShapeElement(data, this.globalData, this);
+        }
+        if (this.textSpans[i].glyph) {
+          var glyph = this.textSpans[i].glyph;
+          this.textSpans[i].childSpan.removeChild(glyph.layerElement);
+          glyph.destroy();
+        }
+        this.textSpans[i].glyph = glyphElement;
+        glyphElement._debug = true;
+        glyphElement.prepareFrame(0);
+        glyphElement.renderFrame();
+        this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+        // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+        // this might have issues with strokes and might need a different solution
+        if (charData.t === 1) {
+          this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
+        }
+      } else {
+        if (singleShape) {
+          tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
+        }
+        tSpan.textContent = letters[i].val;
+        tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      }
+      //
+    }
+    if (singleShape && tSpan) {
+      tSpan.setAttribute('d', shapeStr);
+    }
+  }
+  while (i < this.textSpans.length) {
+    this.textSpans[i].span.style.display = 'none';
+    i += 1;
+  }
+
+  this._sizeChanged = true;
+};
+
+SVGTextLottieElement.prototype.sourceRectAtTime = function () {
+  this.prepareFrame(this.comp.renderedFrame - this.data.st);
+  this.renderInnerContent();
+  if (this._sizeChanged) {
+    this._sizeChanged = false;
+    var textBox = this.layerElement.getBBox();
+    this.bbox = {
+      top: textBox.y,
+      left: textBox.x,
+      width: textBox.width,
+      height: textBox.height,
+    };
+  }
+  return this.bbox;
+};
+
+SVGTextLottieElement.prototype.getValue = function () {
+  var i;
+  var len = this.textSpans.length;
+  var glyphElement;
+  this.renderedFrame = this.comp.renderedFrame;
+  for (i = 0; i < len; i += 1) {
+    glyphElement = this.textSpans[i].glyph;
+    if (glyphElement) {
+      glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
+      if (glyphElement._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+SVGTextLottieElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  if (!this.data.singleShape || this._mdf) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+    if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
+      this._sizeChanged = true;
+      var i;
+      var len;
+      var renderedLetters = this.textAnimator.renderedLetters;
+
+      var letters = this.textProperty.currentData.l;
+
+      len = letters.length;
+      var renderedLetter;
+      var textSpan;
+      var glyphElement;
+      for (i = 0; i < len; i += 1) {
+        if (!letters[i].n) {
+          renderedLetter = renderedLetters[i];
+          textSpan = this.textSpans[i].span;
+          glyphElement = this.textSpans[i].glyph;
+          if (glyphElement) {
+            glyphElement.renderFrame();
+          }
+          if (renderedLetter._mdf.m) {
+            textSpan.setAttribute('transform', renderedLetter.m);
+          }
+          if (renderedLetter._mdf.o) {
+            textSpan.setAttribute('opacity', renderedLetter.o);
+          }
+          if (renderedLetter._mdf.sw) {
+            textSpan.setAttribute('stroke-width', renderedLetter.sw);
+          }
+          if (renderedLetter._mdf.sc) {
+            textSpan.setAttribute('stroke', renderedLetter.sc);
+          }
+          if (renderedLetter._mdf.fc) {
+            textSpan.setAttribute('fill', renderedLetter.fc);
+          }
+        }
+      }
+    }
+  }
+};
+
+function ISolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([IImageElement], ISolidElement);
+
+ISolidElement.prototype.createContent = function () {
+  var rect = createNS('rect');
+  /// /rect.style.width = this.data.sw;
+  /// /rect.style.height = this.data.sh;
+  /// /rect.style.fill = this.data.sc;
+  rect.setAttribute('width', this.data.sw);
+  rect.setAttribute('height', this.data.sh);
+  rect.setAttribute('fill', this.data.sc);
+  this.layerElement.appendChild(rect);
+};
+
+function NullElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initFrame();
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+}
+
+NullElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+NullElement.prototype.renderFrame = function () {
+};
+
+NullElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+NullElement.prototype.destroy = function () {
+};
+
+NullElement.prototype.sourceRectAtTime = function () {
+};
+
+NullElement.prototype.hide = function () {
+};
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
+
+function SVGRendererBase() {
+}
+
+extendPrototype([BaseRenderer], SVGRendererBase);
+
+SVGRendererBase.prototype.createNull = function (data) {
+  return new NullElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createShape = function (data) {
+  return new SVGShapeElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createText = function (data) {
+  return new SVGTextLottieElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createImage = function (data) {
+  return new IImageElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createSolid = function (data) {
+  return new ISolidElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.configAnimation = function (animData) {
+  this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+  this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+  if (this.renderConfig.viewBoxSize) {
+    this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
+  } else {
+    this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
+  }
+
+  if (!this.renderConfig.viewBoxOnly) {
+    this.svgElement.setAttribute('width', animData.w);
+    this.svgElement.setAttribute('height', animData.h);
+    this.svgElement.style.width = '100%';
+    this.svgElement.style.height = '100%';
+    this.svgElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
+  }
+  if (this.renderConfig.width) {
+    this.svgElement.setAttribute('width', this.renderConfig.width);
+  }
+  if (this.renderConfig.height) {
+    this.svgElement.setAttribute('height', this.renderConfig.height);
+  }
+  if (this.renderConfig.className) {
+    this.svgElement.setAttribute('class', this.renderConfig.className);
+  }
+  if (this.renderConfig.id) {
+    this.svgElement.setAttribute('id', this.renderConfig.id);
+  }
+  if (this.renderConfig.focusable !== undefined) {
+    this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
+  }
+  this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+  // this.layerElement.style.transform = 'translate3d(0,0,0)';
+  // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
+  this.animationItem.wrapper.appendChild(this.svgElement);
+  // Mask animation
+  var defs = this.globalData.defs;
+
+  this.setupGlobalData(animData, defs);
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.data = animData;
+
+  var maskElement = createNS('clipPath');
+  var rect = createNS('rect');
+  rect.setAttribute('width', animData.w);
+  rect.setAttribute('height', animData.h);
+  rect.setAttribute('x', 0);
+  rect.setAttribute('y', 0);
+  var maskId = createElementID();
+  maskElement.setAttribute('id', maskId);
+  maskElement.appendChild(rect);
+  this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')');
+
+  defs.appendChild(maskElement);
+  this.layers = animData.layers;
+  this.elements = createSizedArray(animData.layers.length);
+};
+
+SVGRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.layerElement = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+SVGRendererBase.prototype.updateContainerSize = function () {
+};
+
+SVGRendererBase.prototype.findIndexByInd = function (ind) {
+  var i = 0;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.layers[i].ind === ind) {
+      return i;
+    }
+  }
+  return -1;
+};
+
+SVGRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  elements[pos] = true;
+  var element = this.createItem(this.layers[pos]);
+
+  elements[pos] = element;
+  if (getExpressionsPlugin()) {
+    if (this.layers[pos].ty === 0) {
+      this.globalData.projectInterface.registerComposition(element);
+    }
+    element.initExpressions();
+  }
+  this.appendElementInPos(element, pos);
+  if (this.layers[pos].tt) {
+    var elementIndex = ('tp' in this.layers[pos])
+      ? this.findIndexByInd(this.layers[pos].tp)
+      : pos - 1;
+    if (elementIndex === -1) {
+      return;
+    }
+    if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
+      this.buildItem(elementIndex);
+      this.addPendingElement(element);
+    } else {
+      var matteElement = elements[elementIndex];
+      var matteMask = matteElement.getMatte(this.layers[pos].tt);
+      element.setMatte(matteMask);
+    }
+  }
+};
+
+SVGRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+    if (element.data.tt) {
+      var i = 0;
+      var len = this.elements.length;
+      while (i < len) {
+        if (this.elements[i] === element) {
+          var elementIndex = 'tp' in element.data
+            ? this.findIndexByInd(element.data.tp)
+            : i - 1;
+          var matteElement = this.elements[elementIndex];
+          var matteMask = matteElement.getMatte(this.layers[i].tt);
+          element.setMatte(matteMask);
+          break;
+        }
+        i += 1;
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.renderFrame = function (num) {
+  if (this.renderedFrame === num || this.destroyed) {
+    return;
+  }
+  if (num === null) {
+    num = this.renderedFrame;
+  } else {
+    this.renderedFrame = num;
+  }
+  // console.log('-------');
+  // console.log('FRAME ',num);
+  this.globalData.frameNum = num;
+  this.globalData.frameId += 1;
+  this.globalData.projectInterface.currentFrame = num;
+  this.globalData._mdf = false;
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    for (i = 0; i < len; i += 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
+  var newElement = element.getBaseElement();
+  if (!newElement) {
+    return;
+  }
+  var i = 0;
+  var nextElement;
+  while (i < pos) {
+    if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
+      nextElement = this.elements[i].getBaseElement();
+    }
+    i += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(newElement, nextElement);
+  } else {
+    this.layerElement.appendChild(newElement);
+  }
+};
+
+SVGRendererBase.prototype.hide = function () {
+  this.layerElement.style.display = 'none';
+};
+
+SVGRendererBase.prototype.show = function () {
+  this.layerElement.style.display = 'block';
+};
+
+function ICompElement() {}
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
+
+ICompElement.prototype.initElement = function (data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initTransform(data, globalData, comp);
+  this.initRenderable();
+  this.initHierarchy();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  if (this.data.xt || !globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+  this.hide();
+};
+
+/* ICompElement.prototype.hide = function(){
+    if(!this.hidden){
+        this.hideElement();
+        var i,len = this.elements.length;
+        for( i = 0; i < len; i+=1 ){
+            if(this.elements[i]){
+                this.elements[i].hide();
+            }
+        }
+    }
+}; */
+
+ICompElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+  if (!this.isInRange && !this.data.xt) {
+    return;
+  }
+
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    if (timeRemapped === this.data.op) {
+      timeRemapped = this.data.op - 1;
+    }
+    this.renderedFrame = timeRemapped;
+  } else {
+    this.renderedFrame = num / this.data.sr;
+  }
+  var i;
+  var len = this.elements.length;
+  if (!this.completeLayers) {
+    this.checkLayers(this.renderedFrame);
+  }
+  // This iteration needs to be backwards because of how expressions connect between each other
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
+      if (this.elements[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+ICompElement.prototype.renderInnerContent = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+ICompElement.prototype.setElements = function (elems) {
+  this.elements = elems;
+};
+
+ICompElement.prototype.getElements = function () {
+  return this.elements;
+};
+
+ICompElement.prototype.destroyElements = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+};
+
+ICompElement.prototype.destroy = function () {
+  this.destroyElements();
+  this.destroyBaseElement();
+};
+
+function SVGCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = true;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
+
+SVGCompElement.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function SVGRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.layers = null;
+  this.renderedFrame = -1;
+  this.svgElement = createNS('svg');
+  var ariaLabel = '';
+  if (config && config.title) {
+    var titleElement = createNS('title');
+    var titleId = createElementID();
+    titleElement.setAttribute('id', titleId);
+    titleElement.textContent = config.title;
+    this.svgElement.appendChild(titleElement);
+    ariaLabel += titleId;
+  }
+  if (config && config.description) {
+    var descElement = createNS('desc');
+    var descId = createElementID();
+    descElement.setAttribute('id', descId);
+    descElement.textContent = config.description;
+    this.svgElement.appendChild(descElement);
+    ariaLabel += ' ' + descId;
+  }
+  if (ariaLabel) {
+    this.svgElement.setAttribute('aria-labelledby', ariaLabel);
+  }
+  var defs = createNS('defs');
+  this.svgElement.appendChild(defs);
+  var maskElement = createNS('g');
+  this.svgElement.appendChild(maskElement);
+  this.layerElement = maskElement;
+  this.renderConfig = {
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    hideOnTransparent: !((config && config.hideOnTransparent === false)),
+    viewBoxOnly: (config && config.viewBoxOnly) || false,
+    viewBoxSize: (config && config.viewBoxSize) || false,
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    focusable: config && config.focusable,
+    filterSize: {
+      width: (config && config.filterSize && config.filterSize.width) || '100%',
+      height: (config && config.filterSize && config.filterSize.height) || '100%',
+      x: (config && config.filterSize && config.filterSize.x) || '0%',
+      y: (config && config.filterSize && config.filterSize.y) || '0%',
+    },
+    width: (config && config.width),
+    height: (config && config.height),
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+
+  this.globalData = {
+    _mdf: false,
+    frameNum: -1,
+    defs: defs,
+    renderConfig: this.renderConfig,
+  };
+  this.elements = [];
+  this.pendingElements = [];
+  this.destroyed = false;
+  this.rendererType = 'svg';
+}
+
+extendPrototype([SVGRendererBase], SVGRenderer);
+
+SVGRenderer.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function ShapeTransformManager() {
+  this.sequences = {};
+  this.sequenceList = [];
+  this.transform_key_count = 0;
+}
+
+ShapeTransformManager.prototype = {
+  addTransformSequence: function (transforms) {
+    var i;
+    var len = transforms.length;
+    var key = '_';
+    for (i = 0; i < len; i += 1) {
+      key += transforms[i].transform.key + '_';
+    }
+    var sequence = this.sequences[key];
+    if (!sequence) {
+      sequence = {
+        transforms: [].concat(transforms),
+        finalTransform: new Matrix(),
+        _mdf: false,
+      };
+      this.sequences[key] = sequence;
+      this.sequenceList.push(sequence);
+    }
+    return sequence;
+  },
+  processSequence: function (sequence, isFirstFrame) {
+    var i = 0;
+    var len = sequence.transforms.length;
+    var _mdf = isFirstFrame;
+    while (i < len && !isFirstFrame) {
+      if (sequence.transforms[i].transform.mProps._mdf) {
+        _mdf = true;
+        break;
+      }
+      i += 1;
+    }
+    if (_mdf) {
+      sequence.finalTransform.reset();
+      for (i = len - 1; i >= 0; i -= 1) {
+        sequence.finalTransform.multiply(sequence.transforms[i].transform.mProps.v);
+      }
+    }
+    sequence._mdf = _mdf;
+  },
+  processSequences: function (isFirstFrame) {
+    var i;
+    var len = this.sequenceList.length;
+    for (i = 0; i < len; i += 1) {
+      this.processSequence(this.sequenceList[i], isFirstFrame);
+    }
+  },
+  getNewKey: function () {
+    this.transform_key_count += 1;
+    return '_' + this.transform_key_count;
+  },
+};
+
+var lumaLoader = (function () {
+  var id = '__lottie_element_luma_buffer';
+  var lumaBuffer = null;
+  var lumaBufferCtx = null;
+  var svg = null;
+
+  // This alternate solution has a slight delay before the filter is applied, resulting in a flicker on the first frame.
+  // Keeping this here for reference, and in the future, if offscreen canvas supports url filters, this can be used.
+  // For now, neither of them work for offscreen canvas, so canvas workers can't support the luma track matte mask.
+  // Naming it solution 2 to mark the extra comment lines.
+  /*
+  var svgString = [
+    '<svg xmlns="http://www.w3.org/2000/svg">',
+    '<filter id="' + id + '">',
+    '<feColorMatrix type="matrix" color-interpolation-filters="sRGB" values="',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0',
+    '"/>',
+    '</filter>',
+    '</svg>',
+  ].join('');
+  var blob = new Blob([svgString], { type: 'image/svg+xml' });
+  var url = URL.createObjectURL(blob);
+  */
+
+  function createLumaSvgFilter() {
+    var _svg = createNS('svg');
+    var fil = createNS('filter');
+    var matrix = createNS('feColorMatrix');
+    fil.setAttribute('id', id);
+    matrix.setAttribute('type', 'matrix');
+    matrix.setAttribute('color-interpolation-filters', 'sRGB');
+    matrix.setAttribute('values', '0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0');
+    fil.appendChild(matrix);
+    _svg.appendChild(fil);
+    _svg.setAttribute('id', id + '_svg');
+    if (featureSupport.svgLumaHidden) {
+      _svg.style.display = 'none';
+    }
+    return _svg;
+  }
+
+  function loadLuma() {
+    if (!lumaBuffer) {
+      svg = createLumaSvgFilter();
+      document.body.appendChild(svg);
+      lumaBuffer = createTag('canvas');
+      lumaBufferCtx = lumaBuffer.getContext('2d');
+      // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
+      lumaBufferCtx.filter = 'url(#' + id + ')';
+      lumaBufferCtx.fillStyle = 'rgba(0,0,0,0)';
+      lumaBufferCtx.fillRect(0, 0, 1, 1);
+    }
+  }
+
+  function getLuma(canvas) {
+    if (!lumaBuffer) {
+      loadLuma();
+    }
+    lumaBuffer.width = canvas.width;
+    lumaBuffer.height = canvas.height;
+    // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
+    lumaBufferCtx.filter = 'url(#' + id + ')';
+    return lumaBuffer;
+  }
+  return {
+    load: loadLuma,
+    get: getLuma,
+  };
+});
+
+function createCanvas(width, height) {
+  if (featureSupport.offscreenCanvas) {
+    return new OffscreenCanvas(width, height);
+  }
+  var canvas = createTag('canvas');
+  canvas.width = width;
+  canvas.height = height;
+  return canvas;
+}
+
+const assetLoader = (function () {
+  return {
+    loadLumaCanvas: lumaLoader.load,
+    getLumaCanvas: lumaLoader.get,
+    createCanvas: createCanvas,
+  };
+}());
+
+var registeredEffects = {};
+
+function CVEffects(elem) {
+  var i;
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects[type]) {
+      var Effect = registeredEffects[type].effect;
+      filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+CVEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+CVEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect(id, effect) {
+  registeredEffects[id] = {
+    effect,
+  };
+}
+
+function CVMaskElement(data, element) {
+  this.data = data;
+  this.element = element;
+  this.masksProperties = this.data.masksProperties || [];
+  this.viewData = createSizedArray(this.masksProperties.length);
+  var i;
+  var len = this.masksProperties.length;
+  var hasMasks = false;
+  for (i = 0; i < len; i += 1) {
+    if (this.masksProperties[i].mode !== 'n') {
+      hasMasks = true;
+    }
+    this.viewData[i] = ShapePropertyFactory.getShapeProp(this.element, this.masksProperties[i], 3);
+  }
+  this.hasMasks = hasMasks;
+  if (hasMasks) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+CVMaskElement.prototype.renderFrame = function () {
+  if (!this.hasMasks) {
+    return;
+  }
+  var transform = this.element.finalTransform.mat;
+  var ctx = this.element.canvasContext;
+  var i;
+  var len = this.masksProperties.length;
+  var pt;
+  var pts;
+  var data;
+  ctx.beginPath();
+  for (i = 0; i < len; i += 1) {
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.masksProperties[i].inv) {
+        ctx.moveTo(0, 0);
+        ctx.lineTo(this.element.globalData.compSize.w, 0);
+        ctx.lineTo(this.element.globalData.compSize.w, this.element.globalData.compSize.h);
+        ctx.lineTo(0, this.element.globalData.compSize.h);
+        ctx.lineTo(0, 0);
+      }
+      data = this.viewData[i].v;
+      pt = transform.applyToPointArray(data.v[0][0], data.v[0][1], 0);
+      ctx.moveTo(pt[0], pt[1]);
+      var j;
+      var jLen = data._length;
+      for (j = 1; j < jLen; j += 1) {
+        pts = transform.applyToTriplePoints(data.o[j - 1], data.i[j], data.v[j]);
+        ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
+      }
+      pts = transform.applyToTriplePoints(data.o[j - 1], data.i[0], data.v[0]);
+      ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
+    }
+  }
+  this.element.globalData.renderer.save(true);
+  ctx.clip();
+};
+
+CVMaskElement.prototype.getMaskProperty = MaskElement.prototype.getMaskProperty;
+
+CVMaskElement.prototype.destroy = function () {
+  this.element = null;
+};
+
+function CVBaseElement() {
+}
+
+var operationsMap = {
+  1: 'source-in',
+  2: 'source-out',
+  3: 'source-in',
+  4: 'source-out',
+};
+
+CVBaseElement.prototype = {
+  createElements: function () {},
+  initRendererElement: function () {},
+  createContainerElements: function () {
+    // If the layer is masked we will use two buffers to store each different states of the drawing
+    // This solution is not ideal for several reason. But unfortunately, because of the recursive
+    // nature of the render tree, it's the only simple way to make sure one inner mask doesn't override an outer mask.
+    // TODO: try to reduce the size of these buffers to the size of the composition contaning the layer
+    // It might be challenging because the layer most likely is transformed in some way
+    if (this.data.tt >= 1) {
+      this.buffers = [];
+      var canvasContext = this.globalData.canvasContext;
+      var bufferCanvas = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
+      this.buffers.push(bufferCanvas);
+      var bufferCanvas2 = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
+      this.buffers.push(bufferCanvas2);
+      if (this.data.tt >= 3 && !document._isProxy) {
+        assetLoader.loadLumaCanvas();
+      }
+    }
+    this.canvasContext = this.globalData.canvasContext;
+    this.transformCanvas = this.globalData.transformCanvas;
+    this.renderableEffectsManager = new CVEffects(this);
+    this.searchEffectTransforms();
+  },
+  createContent: function () {},
+  setBlendMode: function () {
+    var globalData = this.globalData;
+    if (globalData.blendMode !== this.data.bm) {
+      globalData.blendMode = this.data.bm;
+      var blendModeValue = getBlendMode(this.data.bm);
+      globalData.canvasContext.globalCompositeOperation = blendModeValue;
+    }
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new CVMaskElement(this.data, this);
+    this.transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+  },
+  hideElement: function () {
+    if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+      this.hidden = true;
+    }
+  },
+  showElement: function () {
+    if (this.isInRange && !this.isTransparent) {
+      this.hidden = false;
+      this._isFirstFrame = true;
+      this.maskManager._isFirstFrame = true;
+    }
+  },
+  clearCanvas: function (canvasContext) {
+    canvasContext.clearRect(
+      this.transformCanvas.tx,
+      this.transformCanvas.ty,
+      this.transformCanvas.w * this.transformCanvas.sx,
+      this.transformCanvas.h * this.transformCanvas.sy
+    );
+  },
+  prepareLayer: function () {
+    if (this.data.tt >= 1) {
+      var buffer = this.buffers[0];
+      var bufferCtx = buffer.getContext('2d');
+      this.clearCanvas(bufferCtx);
+      // on the first buffer we store the current state of the global drawing
+      bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+      // The next four lines are to clear the canvas
+      // TODO: Check if there is a way to clear the canvas without resetting the transform
+      this.currentTransform = this.canvasContext.getTransform();
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+      this.clearCanvas(this.canvasContext);
+      this.canvasContext.setTransform(this.currentTransform);
+    }
+  },
+  exitLayer: function () {
+    if (this.data.tt >= 1) {
+      var buffer = this.buffers[1];
+      // On the second buffer we store the current state of the global drawing
+      // that only contains the content of this layer
+      // (if it is a composition, it also includes the nested layers)
+      var bufferCtx = buffer.getContext('2d');
+      this.clearCanvas(bufferCtx);
+      bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+      // We clear the canvas again
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+      this.clearCanvas(this.canvasContext);
+      this.canvasContext.setTransform(this.currentTransform);
+      // We draw the mask
+      const mask = this.comp.getElementById('tp' in this.data ? this.data.tp : this.data.ind - 1);
+      mask.renderFrame(true);
+      // We draw the second buffer (that contains the content of this layer)
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+
+      // If the mask is a Luma matte, we need to do two extra painting operations
+      // the _isProxy check is to avoid drawing a fake canvas in workers that will throw an error
+      if (this.data.tt >= 3 && !document._isProxy) {
+        // We copy the painted mask to a buffer that has a color matrix filter applied to it
+        // that applies the rgb values to the alpha channel
+        var lumaBuffer = assetLoader.getLumaCanvas(this.canvasContext.canvas);
+        var lumaBufferCtx = lumaBuffer.getContext('2d');
+        lumaBufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+        this.clearCanvas(this.canvasContext);
+        // we repaint the context with the mask applied to it
+        this.canvasContext.drawImage(lumaBuffer, 0, 0);
+      }
+      this.canvasContext.globalCompositeOperation = operationsMap[this.data.tt];
+      this.canvasContext.drawImage(buffer, 0, 0);
+      // We finally draw the first buffer (that contains the content of the global drawing)
+      // We use destination-over to draw the global drawing below the current layer
+      this.canvasContext.globalCompositeOperation = 'destination-over';
+      this.canvasContext.drawImage(this.buffers[0], 0, 0);
+      this.canvasContext.setTransform(this.currentTransform);
+      // We reset the globalCompositeOperation to source-over, the standard type of operation
+      this.canvasContext.globalCompositeOperation = 'source-over';
+    }
+  },
+  renderFrame: function (forceRender) {
+    if (this.hidden || this.data.hd) {
+      return;
+    }
+    if (this.data.td === 1 && !forceRender) {
+      return;
+    }
+    this.renderTransform();
+    this.renderRenderable();
+    this.renderLocalTransform();
+    this.setBlendMode();
+    var forceRealStack = this.data.ty === 0;
+    this.prepareLayer();
+    this.globalData.renderer.save(forceRealStack);
+    this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props);
+    this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity);
+    this.renderInnerContent();
+    this.globalData.renderer.restore(forceRealStack);
+    this.exitLayer();
+    if (this.maskManager.hasMasks) {
+      this.globalData.renderer.restore(true);
+    }
+    if (this._isFirstFrame) {
+      this._isFirstFrame = false;
+    }
+  },
+  destroy: function () {
+    this.canvasContext = null;
+    this.data = null;
+    this.globalData = null;
+    this.maskManager.destroy();
+  },
+  mHelper: new Matrix(),
+};
+CVBaseElement.prototype.hide = CVBaseElement.prototype.hideElement;
+CVBaseElement.prototype.show = CVBaseElement.prototype.showElement;
+
+function CVShapeData(element, data, styles, transformsManager) {
+  this.styledShapes = [];
+  this.tr = [0, 0, 0, 0, 0, 0];
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  this.sh = ShapePropertyFactory.getShapeProp(element, data, ty, element);
+  var i;
+  var len = styles.length;
+  var styledShape;
+  for (i = 0; i < len; i += 1) {
+    if (!styles[i].closed) {
+      styledShape = {
+        transforms: transformsManager.addTransformSequence(styles[i].transforms),
+        trNodes: [],
+      };
+      this.styledShapes.push(styledShape);
+      styles[i].elements.push(styledShape);
+    }
+  }
+}
+
+CVShapeData.prototype.setAsAnimated = SVGShapeData.prototype.setAsAnimated;
+
+function CVShapeElement(data, globalData, comp) {
+  this.shapes = [];
+  this.shapesData = data.shapes;
+  this.stylesList = [];
+  this.itemsData = [];
+  this.prevViewData = [];
+  this.shapeModifiers = [];
+  this.processedElements = [];
+  this.transformsManager = new ShapeTransformManager();
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, CVBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableElement], CVShapeElement);
+
+CVShapeElement.prototype.initElement = RenderableDOMElement.prototype.initElement;
+
+CVShapeElement.prototype.transformHelper = { opacity: 1, _opMdf: false };
+
+CVShapeElement.prototype.dashResetter = [];
+
+CVShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
+};
+
+CVShapeElement.prototype.createStyleElement = function (data, transforms) {
+  var styleElem = {
+    data: data,
+    type: data.ty,
+    preTransforms: this.transformsManager.addTransformSequence(transforms),
+    transforms: [],
+    elements: [],
+    closed: data.hd === true,
+  };
+  var elementData = {};
+  if (data.ty === 'fl' || data.ty === 'st') {
+    elementData.c = PropertyFactory.getProp(this, data.c, 1, 255, this);
+    if (!elementData.c.k) {
+      styleElem.co = 'rgb(' + bmFloor(elementData.c.v[0]) + ',' + bmFloor(elementData.c.v[1]) + ',' + bmFloor(elementData.c.v[2]) + ')';
+    }
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    elementData.s = PropertyFactory.getProp(this, data.s, 1, null, this);
+    elementData.e = PropertyFactory.getProp(this, data.e, 1, null, this);
+    elementData.h = PropertyFactory.getProp(this, data.h || { k: 0 }, 0, 0.01, this);
+    elementData.a = PropertyFactory.getProp(this, data.a || { k: 0 }, 0, degToRads, this);
+    elementData.g = new GradientProperty(this, data.g, this);
+  }
+  elementData.o = PropertyFactory.getProp(this, data.o, 0, 0.01, this);
+  if (data.ty === 'st' || data.ty === 'gs') {
+    styleElem.lc = lineCapEnum[data.lc || 2];
+    styleElem.lj = lineJoinEnum[data.lj || 2];
+    if (data.lj == 1) { // eslint-disable-line eqeqeq
+      styleElem.ml = data.ml;
+    }
+    elementData.w = PropertyFactory.getProp(this, data.w, 0, null, this);
+    if (!elementData.w.k) {
+      styleElem.wi = elementData.w.v;
+    }
+    if (data.d) {
+      var d = new DashProperty(this, data.d, 'canvas', this);
+      elementData.d = d;
+      if (!elementData.d.k) {
+        styleElem.da = elementData.d.dashArray;
+        styleElem.do = elementData.d.dashoffset[0];
+      }
+    }
+  } else {
+    styleElem.r = data.r === 2 ? 'evenodd' : 'nonzero';
+  }
+  this.stylesList.push(styleElem);
+  elementData.style = styleElem;
+  return elementData;
+};
+
+CVShapeElement.prototype.createGroupElement = function () {
+  var elementData = {
+    it: [],
+    prevViewData: [],
+  };
+  return elementData;
+};
+
+CVShapeElement.prototype.createTransformElement = function (data) {
+  var elementData = {
+    transform: {
+      opacity: 1,
+      _opMdf: false,
+      key: this.transformsManager.getNewKey(),
+      op: PropertyFactory.getProp(this, data.o, 0, 0.01, this),
+      mProps: TransformPropertyFactory.getTransformProperty(this, data, this),
+    },
+  };
+  return elementData;
+};
+
+CVShapeElement.prototype.createShapeElement = function (data) {
+  var elementData = new CVShapeData(this, data, this.stylesList, this.transformsManager);
+
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  return elementData;
+};
+
+CVShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+  this.transformsManager.processSequences(this._isFirstFrame);
+};
+
+CVShapeElement.prototype.addTransformToStyleList = function (transform) {
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    if (!this.stylesList[i].closed) {
+      this.stylesList[i].transforms.push(transform);
+    }
+  }
+};
+
+CVShapeElement.prototype.removeTransformFromStyleList = function () {
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    if (!this.stylesList[i].closed) {
+      this.stylesList[i].transforms.pop();
+    }
+  }
+};
+
+CVShapeElement.prototype.closeStyles = function (styles) {
+  var i;
+  var len = styles.length;
+  for (i = 0; i < len; i += 1) {
+    styles[i].closed = true;
+  }
+};
+
+CVShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, shouldRender, transforms) {
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var processedPos;
+  var modifier;
+  var currentTransform;
+  var ownTransforms = [].concat(transforms);
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._shouldRender = shouldRender;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], ownTransforms);
+      } else {
+        itemsData[i].style.closed = false;
+      }
+
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, shouldRender, ownTransforms);
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        currentTransform = this.createTransformElement(arr[i]);
+        itemsData[i] = currentTransform;
+      }
+      ownTransforms.push(itemsData[i]);
+      this.addTransformToStyleList(itemsData[i]);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i]);
+      }
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        shouldRender = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  this.removeTransformFromStyleList();
+  this.closeStyles(ownStyles);
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+CVShapeElement.prototype.renderInnerContent = function () {
+  this.transformHelper.opacity = 1;
+  this.transformHelper._opMdf = false;
+  this.renderModifiers();
+  this.transformsManager.processSequences(this._isFirstFrame);
+  this.renderShape(this.transformHelper, this.shapesData, this.itemsData, true);
+};
+
+CVShapeElement.prototype.renderShapeTransform = function (parentTransform, groupTransform) {
+  if (parentTransform._opMdf || groupTransform.op._mdf || this._isFirstFrame) {
+    groupTransform.opacity = parentTransform.opacity;
+    groupTransform.opacity *= groupTransform.op.v;
+    groupTransform._opMdf = true;
+  }
+};
+
+CVShapeElement.prototype.drawLayer = function () {
+  var i;
+  var len = this.stylesList.length;
+  var j;
+  var jLen;
+  var k;
+  var kLen;
+  var elems;
+  var nodes;
+  var renderer = this.globalData.renderer;
+  var ctx = this.globalData.canvasContext;
+  var type;
+  var currentStyle;
+  for (i = 0; i < len; i += 1) {
+    currentStyle = this.stylesList[i];
+    type = currentStyle.type;
+
+    // Skipping style when
+    // Stroke width equals 0
+    // style should not be rendered (extra unused repeaters)
+    // current opacity equals 0
+    // global opacity equals 0
+    if (!(((type === 'st' || type === 'gs') && currentStyle.wi === 0) || !currentStyle.data._shouldRender || currentStyle.coOp === 0 || this.globalData.currentGlobalAlpha === 0)) {
+      renderer.save();
+      elems = currentStyle.elements;
+      if (type === 'st' || type === 'gs') {
+        renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd);
+        // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
+        renderer.ctxLineWidth(currentStyle.wi);
+        // ctx.lineWidth = currentStyle.wi;
+        renderer.ctxLineCap(currentStyle.lc);
+        // ctx.lineCap = currentStyle.lc;
+        renderer.ctxLineJoin(currentStyle.lj);
+        // ctx.lineJoin = currentStyle.lj;
+        renderer.ctxMiterLimit(currentStyle.ml || 0);
+        // ctx.miterLimit = currentStyle.ml || 0;
+      } else {
+        renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd);
+        // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
+      }
+      renderer.ctxOpacity(currentStyle.coOp);
+      if (type !== 'st' && type !== 'gs') {
+        ctx.beginPath();
+      }
+      renderer.ctxTransform(currentStyle.preTransforms.finalTransform.props);
+      jLen = elems.length;
+      for (j = 0; j < jLen; j += 1) {
+        if (type === 'st' || type === 'gs') {
+          ctx.beginPath();
+          if (currentStyle.da) {
+            ctx.setLineDash(currentStyle.da);
+            ctx.lineDashOffset = currentStyle.do;
+          }
+        }
+        nodes = elems[j].trNodes;
+        kLen = nodes.length;
+
+        for (k = 0; k < kLen; k += 1) {
+          if (nodes[k].t === 'm') {
+            ctx.moveTo(nodes[k].p[0], nodes[k].p[1]);
+          } else if (nodes[k].t === 'c') {
+            ctx.bezierCurveTo(nodes[k].pts[0], nodes[k].pts[1], nodes[k].pts[2], nodes[k].pts[3], nodes[k].pts[4], nodes[k].pts[5]);
+          } else {
+            ctx.closePath();
+          }
+        }
+        if (type === 'st' || type === 'gs') {
+          // ctx.stroke();
+          renderer.ctxStroke();
+          if (currentStyle.da) {
+            ctx.setLineDash(this.dashResetter);
+          }
+        }
+      }
+      if (type !== 'st' && type !== 'gs') {
+        // ctx.fill(currentStyle.r);
+        this.globalData.renderer.ctxFill(currentStyle.r);
+      }
+      renderer.restore();
+    }
+  }
+};
+
+CVShapeElement.prototype.renderShape = function (parentTransform, items, data, isMain) {
+  var i;
+  var len = items.length - 1;
+  var groupTransform;
+  groupTransform = parentTransform;
+  for (i = len; i >= 0; i -= 1) {
+    if (items[i].ty === 'tr') {
+      groupTransform = data[i].transform;
+      this.renderShapeTransform(parentTransform, groupTransform);
+    } else if (items[i].ty === 'sh' || items[i].ty === 'el' || items[i].ty === 'rc' || items[i].ty === 'sr') {
+      this.renderPath(items[i], data[i]);
+    } else if (items[i].ty === 'fl') {
+      this.renderFill(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'st') {
+      this.renderStroke(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'gf' || items[i].ty === 'gs') {
+      this.renderGradientFill(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'gr') {
+      this.renderShape(groupTransform, items[i].it, data[i].it);
+    } else if (items[i].ty === 'tm') {
+      //
+    }
+  }
+  if (isMain) {
+    this.drawLayer();
+  }
+};
+
+CVShapeElement.prototype.renderStyledShape = function (styledShape, shape) {
+  if (this._isFirstFrame || shape._mdf || styledShape.transforms._mdf) {
+    var shapeNodes = styledShape.trNodes;
+    var paths = shape.paths;
+    var i;
+    var len;
+    var j;
+    var jLen = paths._length;
+    shapeNodes.length = 0;
+    var groupTransformMat = styledShape.transforms.finalTransform;
+    for (j = 0; j < jLen; j += 1) {
+      var pathNodes = paths.shapes[j];
+      if (pathNodes && pathNodes.v) {
+        len = pathNodes._length;
+        for (i = 1; i < len; i += 1) {
+          if (i === 1) {
+            shapeNodes.push({
+              t: 'm',
+              p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0),
+            });
+          }
+          shapeNodes.push({
+            t: 'c',
+            pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[i], pathNodes.v[i]),
+          });
+        }
+        if (len === 1) {
+          shapeNodes.push({
+            t: 'm',
+            p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0),
+          });
+        }
+        if (pathNodes.c && len) {
+          shapeNodes.push({
+            t: 'c',
+            pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[0], pathNodes.v[0]),
+          });
+          shapeNodes.push({
+            t: 'z',
+          });
+        }
+      }
+    }
+    styledShape.trNodes = shapeNodes;
+  }
+};
+
+CVShapeElement.prototype.renderPath = function (pathData, itemData) {
+  if (pathData.hd !== true && pathData._shouldRender) {
+    var i;
+    var len = itemData.styledShapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderStyledShape(itemData.styledShapes[i], itemData.sh);
+    }
+  }
+};
+
+CVShapeElement.prototype.renderFill = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+
+  if (itemData.c._mdf || this._isFirstFrame) {
+    styleElem.co = 'rgb('
+        + bmFloor(itemData.c.v[0]) + ','
+        + bmFloor(itemData.c.v[1]) + ','
+        + bmFloor(itemData.c.v[2]) + ')';
+  }
+  if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
+    styleElem.coOp = itemData.o.v * groupTransform.opacity;
+  }
+};
+
+CVShapeElement.prototype.renderGradientFill = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+  var grd;
+  if (!styleElem.grd || itemData.g._mdf || itemData.s._mdf || itemData.e._mdf || (styleData.t !== 1 && (itemData.h._mdf || itemData.a._mdf))) {
+    var ctx = this.globalData.canvasContext;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+    if (styleData.t === 1) {
+      grd = ctx.createLinearGradient(pt1[0], pt1[1], pt2[0], pt2[1]);
+    } else {
+      var rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+      var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+      var percent = itemData.h.v;
+      if (percent >= 1) {
+        percent = 0.99;
+      } else if (percent <= -1) {
+        percent = -0.99;
+      }
+      var dist = rad * percent;
+      var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+      var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+      grd = ctx.createRadialGradient(x, y, 0, pt1[0], pt1[1], rad);
+    }
+
+    var i;
+    var len = styleData.g.p;
+    var cValues = itemData.g.c;
+    var opacity = 1;
+
+    for (i = 0; i < len; i += 1) {
+      if (itemData.g._hasOpacity && itemData.g._collapsable) {
+        opacity = itemData.g.o[i * 2 + 1];
+      }
+      grd.addColorStop(cValues[i * 4] / 100, 'rgba(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ',' + opacity + ')');
+    }
+    styleElem.grd = grd;
+  }
+  styleElem.coOp = itemData.o.v * groupTransform.opacity;
+};
+
+CVShapeElement.prototype.renderStroke = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+  var d = itemData.d;
+  if (d && (d._mdf || this._isFirstFrame)) {
+    styleElem.da = d.dashArray;
+    styleElem.do = d.dashoffset[0];
+  }
+  if (itemData.c._mdf || this._isFirstFrame) {
+    styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
+  }
+  if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
+    styleElem.coOp = itemData.o.v * groupTransform.opacity;
+  }
+  if (itemData.w._mdf || this._isFirstFrame) {
+    styleElem.wi = itemData.w.v;
+  }
+};
+
+CVShapeElement.prototype.destroy = function () {
+  this.shapesData = null;
+  this.globalData = null;
+  this.canvasContext = null;
+  this.stylesList.length = 0;
+  this.itemsData.length = 0;
+};
+
+function CVTextElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.yOffset = 0;
+  this.fillColorAnim = false;
+  this.strokeColorAnim = false;
+  this.strokeWidthAnim = false;
+  this.stroke = false;
+  this.fill = false;
+  this.justifyOffset = 0;
+  this.currentRender = null;
+  this.renderType = 'canvas';
+  this.values = {
+    fill: 'rgba(0,0,0,0)',
+    stroke: 'rgba(0,0,0,0)',
+    sWidth: 0,
+    fValue: '',
+  };
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement, ITextElement], CVTextElement);
+
+CVTextElement.prototype.tHelper = createTag('canvas').getContext('2d');
+
+CVTextElement.prototype.buildNewText = function () {
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
+
+  var hasFill = false;
+  if (documentData.fc) {
+    hasFill = true;
+    this.values.fill = this.buildColor(documentData.fc);
+  } else {
+    this.values.fill = 'rgba(0,0,0,0)';
+  }
+  this.fill = hasFill;
+  var hasStroke = false;
+  if (documentData.sc) {
+    hasStroke = true;
+    this.values.stroke = this.buildColor(documentData.sc);
+    this.values.sWidth = documentData.sw;
+  }
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  var i;
+  var len;
+  var letters = documentData.l;
+  var matrixHelper = this.mHelper;
+  this.stroke = hasStroke;
+  this.values.fValue = documentData.finalSize + 'px ' + this.globalData.fontManager.getFontByName(documentData.f).fFamily;
+  len = documentData.finalText.length;
+  // this.tHelper.font = this.values.fValue;
+  var charData;
+  var shapeData;
+  var k;
+  var kLen;
+  var shapes;
+  var j;
+  var jLen;
+  var pathNodes;
+  var commands;
+  var pathArr;
+  var singleShape = this.data.singleShape;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var cnt = 0;
+  for (i = 0; i < len; i += 1) {
+    charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
+    shapeData = (charData && charData.data) || {};
+    matrixHelper.reset();
+    if (singleShape && letters[i].n) {
+      xPos = -trackingOffset;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      firstLine = false;
+    }
+    shapes = shapeData.shapes ? shapeData.shapes[0].it : [];
+    jLen = shapes.length;
+    matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
+    if (singleShape) {
+      this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+    }
+    commands = createSizedArray(jLen - 1);
+    var commandsCounter = 0;
+    for (j = 0; j < jLen; j += 1) {
+      if (shapes[j].ty === 'sh') {
+        kLen = shapes[j].ks.k.i.length;
+        pathNodes = shapes[j].ks.k;
+        pathArr = [];
+        for (k = 1; k < kLen; k += 1) {
+          if (k === 1) {
+            pathArr.push(matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
+          }
+          pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToY(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToX(pathNodes.v[k][0], pathNodes.v[k][1], 0), matrixHelper.applyToY(pathNodes.v[k][0], pathNodes.v[k][1], 0));
+        }
+        pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToY(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
+        commands[commandsCounter] = pathArr;
+        commandsCounter += 1;
+      }
+    }
+    if (singleShape) {
+      xPos += letters[i].l;
+      xPos += trackingOffset;
+    }
+    if (this.textSpans[cnt]) {
+      this.textSpans[cnt].elem = commands;
+    } else {
+      this.textSpans[cnt] = { elem: commands };
+    }
+    cnt += 1;
+  }
+};
+
+CVTextElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  var ctx = this.canvasContext;
+  ctx.font = this.values.fValue;
+  this.globalData.renderer.ctxLineCap('butt');
+  // ctx.lineCap = 'butt';
+  this.globalData.renderer.ctxLineJoin('miter');
+  // ctx.lineJoin = 'miter';
+  this.globalData.renderer.ctxMiterLimit(4);
+  // ctx.miterLimit = 4;
+
+  if (!this.data.singleShape) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+  }
+
+  var i;
+  var len;
+  var j;
+  var jLen;
+  var k;
+  var kLen;
+  var renderedLetters = this.textAnimator.renderedLetters;
+
+  var letters = this.textProperty.currentData.l;
+
+  len = letters.length;
+  var renderedLetter;
+  var lastFill = null;
+  var lastStroke = null;
+  var lastStrokeW = null;
+  var commands;
+  var pathArr;
+  var renderer = this.globalData.renderer;
+  for (i = 0; i < len; i += 1) {
+    if (!letters[i].n) {
+      renderedLetter = renderedLetters[i];
+      if (renderedLetter) {
+        renderer.save();
+        renderer.ctxTransform(renderedLetter.p);
+        renderer.ctxOpacity(renderedLetter.o);
+      }
+      if (this.fill) {
+        if (renderedLetter && renderedLetter.fc) {
+          if (lastFill !== renderedLetter.fc) {
+            renderer.ctxFillStyle(renderedLetter.fc);
+            lastFill = renderedLetter.fc;
+            // ctx.fillStyle = renderedLetter.fc;
+          }
+        } else if (lastFill !== this.values.fill) {
+          lastFill = this.values.fill;
+          renderer.ctxFillStyle(this.values.fill);
+          // ctx.fillStyle = this.values.fill;
+        }
+        commands = this.textSpans[i].elem;
+        jLen = commands.length;
+        this.globalData.canvasContext.beginPath();
+        for (j = 0; j < jLen; j += 1) {
+          pathArr = commands[j];
+          kLen = pathArr.length;
+          this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
+          for (k = 2; k < kLen; k += 6) {
+            this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
+          }
+        }
+        this.globalData.canvasContext.closePath();
+        renderer.ctxFill();
+        // this.globalData.canvasContext.fill();
+        /// ctx.fillText(this.textSpans[i].val,0,0);
+      }
+      if (this.stroke) {
+        if (renderedLetter && renderedLetter.sw) {
+          if (lastStrokeW !== renderedLetter.sw) {
+            lastStrokeW = renderedLetter.sw;
+            renderer.ctxLineWidth(renderedLetter.sw);
+            // ctx.lineWidth = renderedLetter.sw;
+          }
+        } else if (lastStrokeW !== this.values.sWidth) {
+          lastStrokeW = this.values.sWidth;
+          renderer.ctxLineWidth(this.values.sWidth);
+          // ctx.lineWidth = this.values.sWidth;
+        }
+        if (renderedLetter && renderedLetter.sc) {
+          if (lastStroke !== renderedLetter.sc) {
+            lastStroke = renderedLetter.sc;
+            renderer.ctxStrokeStyle(renderedLetter.sc);
+            // ctx.strokeStyle = renderedLetter.sc;
+          }
+        } else if (lastStroke !== this.values.stroke) {
+          lastStroke = this.values.stroke;
+          renderer.ctxStrokeStyle(this.values.stroke);
+          // ctx.strokeStyle = this.values.stroke;
+        }
+        commands = this.textSpans[i].elem;
+        jLen = commands.length;
+        this.globalData.canvasContext.beginPath();
+        for (j = 0; j < jLen; j += 1) {
+          pathArr = commands[j];
+          kLen = pathArr.length;
+          this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
+          for (k = 2; k < kLen; k += 6) {
+            this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
+          }
+        }
+        this.globalData.canvasContext.closePath();
+        renderer.ctxStroke();
+        // this.globalData.canvasContext.stroke();
+        /// ctx.strokeText(letters[i].val,0,0);
+      }
+      if (renderedLetter) {
+        this.globalData.renderer.restore();
+      }
+    }
+  }
+};
+
+function CVImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  this.img = globalData.imageLoader.getAsset(this.assetData);
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVImageElement);
+
+CVImageElement.prototype.initElement = SVGShapeElement.prototype.initElement;
+CVImageElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
+
+CVImageElement.prototype.createContent = function () {
+  if (this.img.width && (this.assetData.w !== this.img.width || this.assetData.h !== this.img.height)) {
+    var canvas = createTag('canvas');
+    canvas.width = this.assetData.w;
+    canvas.height = this.assetData.h;
+    var ctx = canvas.getContext('2d');
+
+    var imgW = this.img.width;
+    var imgH = this.img.height;
+    var imgRel = imgW / imgH;
+    var canvasRel = this.assetData.w / this.assetData.h;
+    var widthCrop;
+    var heightCrop;
+    var par = this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio;
+    if ((imgRel > canvasRel && par === 'xMidYMid slice') || (imgRel < canvasRel && par !== 'xMidYMid slice')) {
+      heightCrop = imgH;
+      widthCrop = heightCrop * canvasRel;
+    } else {
+      widthCrop = imgW;
+      heightCrop = widthCrop / canvasRel;
+    }
+    ctx.drawImage(this.img, (imgW - widthCrop) / 2, (imgH - heightCrop) / 2, widthCrop, heightCrop, 0, 0, this.assetData.w, this.assetData.h);
+    this.img = canvas;
+  }
+};
+
+CVImageElement.prototype.renderInnerContent = function () {
+  this.canvasContext.drawImage(this.img, 0, 0);
+};
+
+CVImageElement.prototype.destroy = function () {
+  this.img = null;
+};
+
+function CVSolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVSolidElement);
+
+CVSolidElement.prototype.initElement = SVGShapeElement.prototype.initElement;
+CVSolidElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
+
+CVSolidElement.prototype.renderInnerContent = function () {
+  // var ctx = this.canvasContext;
+  this.globalData.renderer.ctxFillStyle(this.data.sc);
+  // ctx.fillStyle = this.data.sc;
+  this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh);
+  // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
+  //
+};
+
+function CanvasRendererBase() {
+}
+extendPrototype([BaseRenderer], CanvasRendererBase);
+
+CanvasRendererBase.prototype.createShape = function (data) {
+  return new CVShapeElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createText = function (data) {
+  return new CVTextElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createImage = function (data) {
+  return new CVImageElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createSolid = function (data) {
+  return new CVSolidElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
+
+CanvasRendererBase.prototype.ctxTransform = function (props) {
+  if (props[0] === 1 && props[1] === 0 && props[4] === 0 && props[5] === 1 && props[12] === 0 && props[13] === 0) {
+    return;
+  }
+  this.canvasContext.transform(props[0], props[1], props[4], props[5], props[12], props[13]);
+};
+
+CanvasRendererBase.prototype.ctxOpacity = function (op) {
+  this.canvasContext.globalAlpha *= op < 0 ? 0 : op;
+};
+
+CanvasRendererBase.prototype.ctxFillStyle = function (value) {
+  this.canvasContext.fillStyle = value;
+};
+
+CanvasRendererBase.prototype.ctxStrokeStyle = function (value) {
+  this.canvasContext.strokeStyle = value;
+};
+
+CanvasRendererBase.prototype.ctxLineWidth = function (value) {
+  this.canvasContext.lineWidth = value;
+};
+
+CanvasRendererBase.prototype.ctxLineCap = function (value) {
+  this.canvasContext.lineCap = value;
+};
+
+CanvasRendererBase.prototype.ctxLineJoin = function (value) {
+  this.canvasContext.lineJoin = value;
+};
+
+CanvasRendererBase.prototype.ctxMiterLimit = function (value) {
+  this.canvasContext.miterLimit = value;
+};
+
+CanvasRendererBase.prototype.ctxFill = function (rule) {
+  this.canvasContext.fill(rule);
+};
+
+CanvasRendererBase.prototype.ctxFillRect = function (x, y, w, h) {
+  this.canvasContext.fillRect(x, y, w, h);
+};
+
+CanvasRendererBase.prototype.ctxStroke = function () {
+  this.canvasContext.stroke();
+};
+
+CanvasRendererBase.prototype.reset = function () {
+  if (!this.renderConfig.clearCanvas) {
+    this.canvasContext.restore();
+    return;
+  }
+  this.contextData.reset();
+};
+
+CanvasRendererBase.prototype.save = function () {
+  this.canvasContext.save();
+};
+
+CanvasRendererBase.prototype.restore = function (actionFlag) {
+  if (!this.renderConfig.clearCanvas) {
+    this.canvasContext.restore();
+    return;
+  }
+  if (actionFlag) {
+    this.globalData.blendMode = 'source-over';
+  }
+  this.contextData.restore(actionFlag);
+};
+
+CanvasRendererBase.prototype.configAnimation = function (animData) {
+  if (this.animationItem.wrapper) {
+    this.animationItem.container = createTag('canvas');
+    var containerStyle = this.animationItem.container.style;
+    containerStyle.width = '100%';
+    containerStyle.height = '100%';
+    var origin = '0px 0px 0px';
+    containerStyle.transformOrigin = origin;
+    containerStyle.mozTransformOrigin = origin;
+    containerStyle.webkitTransformOrigin = origin;
+    containerStyle['-webkit-transform'] = origin;
+    containerStyle.contentVisibility = this.renderConfig.contentVisibility;
+    this.animationItem.wrapper.appendChild(this.animationItem.container);
+    this.canvasContext = this.animationItem.container.getContext('2d');
+    if (this.renderConfig.className) {
+      this.animationItem.container.setAttribute('class', this.renderConfig.className);
+    }
+    if (this.renderConfig.id) {
+      this.animationItem.container.setAttribute('id', this.renderConfig.id);
+    }
+  } else {
+    this.canvasContext = this.renderConfig.context;
+  }
+  this.contextData.setContext(this.canvasContext);
+  this.data = animData;
+  this.layers = animData.layers;
+  this.transformCanvas = {
+    w: animData.w,
+    h: animData.h,
+    sx: 0,
+    sy: 0,
+    tx: 0,
+    ty: 0,
+  };
+  this.setupGlobalData(animData, document.body);
+  this.globalData.canvasContext = this.canvasContext;
+  this.globalData.renderer = this;
+  this.globalData.isDashed = false;
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.globalData.transformCanvas = this.transformCanvas;
+  this.elements = createSizedArray(animData.layers.length);
+
+  this.updateContainerSize();
+};
+
+CanvasRendererBase.prototype.updateContainerSize = function (width, height) {
+  this.reset();
+  var elementWidth;
+  var elementHeight;
+  if (width) {
+    elementWidth = width;
+    elementHeight = height;
+    this.canvasContext.canvas.width = elementWidth;
+    this.canvasContext.canvas.height = elementHeight;
+  } else {
+    if (this.animationItem.wrapper && this.animationItem.container) {
+      elementWidth = this.animationItem.wrapper.offsetWidth;
+      elementHeight = this.animationItem.wrapper.offsetHeight;
+    } else {
+      elementWidth = this.canvasContext.canvas.width;
+      elementHeight = this.canvasContext.canvas.height;
+    }
+    this.canvasContext.canvas.width = elementWidth * this.renderConfig.dpr;
+    this.canvasContext.canvas.height = elementHeight * this.renderConfig.dpr;
+  }
+
+  var elementRel;
+  var animationRel;
+  if (this.renderConfig.preserveAspectRatio.indexOf('meet') !== -1 || this.renderConfig.preserveAspectRatio.indexOf('slice') !== -1) {
+    var par = this.renderConfig.preserveAspectRatio.split(' ');
+    var fillType = par[1] || 'meet';
+    var pos = par[0] || 'xMidYMid';
+    var xPos = pos.substr(0, 4);
+    var yPos = pos.substr(4);
+    elementRel = elementWidth / elementHeight;
+    animationRel = this.transformCanvas.w / this.transformCanvas.h;
+    if ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice')) {
+      this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+      this.transformCanvas.sy = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+    } else {
+      this.transformCanvas.sx = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+      this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+    }
+
+    if (xPos === 'xMid' && ((animationRel < elementRel && fillType === 'meet') || (animationRel > elementRel && fillType === 'slice'))) {
+      this.transformCanvas.tx = ((elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) / 2) * this.renderConfig.dpr;
+    } else if (xPos === 'xMax' && ((animationRel < elementRel && fillType === 'meet') || (animationRel > elementRel && fillType === 'slice'))) {
+      this.transformCanvas.tx = (elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) * this.renderConfig.dpr;
+    } else {
+      this.transformCanvas.tx = 0;
+    }
+    if (yPos === 'YMid' && ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice'))) {
+      this.transformCanvas.ty = ((elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w)) / 2) * this.renderConfig.dpr;
+    } else if (yPos === 'YMax' && ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice'))) {
+      this.transformCanvas.ty = ((elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w))) * this.renderConfig.dpr;
+    } else {
+      this.transformCanvas.ty = 0;
+    }
+  } else if (this.renderConfig.preserveAspectRatio === 'none') {
+    this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+    this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+    this.transformCanvas.tx = 0;
+    this.transformCanvas.ty = 0;
+  } else {
+    this.transformCanvas.sx = this.renderConfig.dpr;
+    this.transformCanvas.sy = this.renderConfig.dpr;
+    this.transformCanvas.tx = 0;
+    this.transformCanvas.ty = 0;
+  }
+  this.transformCanvas.props = [this.transformCanvas.sx, 0, 0, 0, 0, this.transformCanvas.sy, 0, 0, 0, 0, 1, 0, this.transformCanvas.tx, this.transformCanvas.ty, 0, 1];
+  /* var i, len = this.elements.length;
+    for(i=0;i<len;i+=1){
+        if(this.elements[i] && this.elements[i].data.ty === 0){
+            this.elements[i].resize(this.globalData.transformCanvas);
+        }
+    } */
+  this.ctxTransform(this.transformCanvas.props);
+  this.canvasContext.beginPath();
+  this.canvasContext.rect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
+  this.canvasContext.closePath();
+  this.canvasContext.clip();
+
+  this.renderFrame(this.renderedFrame, true);
+};
+
+CanvasRendererBase.prototype.destroy = function () {
+  if (this.renderConfig.clearCanvas && this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.globalData.canvasContext = null;
+  this.animationItem.container = null;
+  this.destroyed = true;
+};
+
+CanvasRendererBase.prototype.renderFrame = function (num, forceRender) {
+  if ((this.renderedFrame === num && this.renderConfig.clearCanvas === true && !forceRender) || this.destroyed || num === -1) {
+    return;
+  }
+  this.renderedFrame = num;
+  this.globalData.frameNum = num - this.animationItem._isFirstFrame;
+  this.globalData.frameId += 1;
+  this.globalData._mdf = !this.renderConfig.clearCanvas || forceRender;
+  this.globalData.projectInterface.currentFrame = num;
+
+  // console.log('--------');
+  // console.log('NEW: ',num);
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    if (this.renderConfig.clearCanvas === true) {
+      this.canvasContext.clearRect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
+    } else {
+      this.save();
+    }
+    for (i = len - 1; i >= 0; i -= 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+    if (this.renderConfig.clearCanvas !== true) {
+      this.restore();
+    }
+  }
+};
+
+CanvasRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  var element = this.createItem(this.layers[pos], this, this.globalData);
+  elements[pos] = element;
+  element.initExpressions();
+  /* if(this.layers[pos].ty === 0){
+        element.resize(this.globalData.transformCanvas);
+    } */
+};
+
+CanvasRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+  }
+};
+
+CanvasRendererBase.prototype.hide = function () {
+  this.animationItem.container.style.display = 'none';
+};
+
+CanvasRendererBase.prototype.show = function () {
+  this.animationItem.container.style.display = 'block';
+};
+
+function CanvasContext() {
+  this.opacity = -1;
+  this.transform = createTypedArray('float32', 16);
+  this.fillStyle = '';
+  this.strokeStyle = '';
+  this.lineWidth = '';
+  this.lineCap = '';
+  this.lineJoin = '';
+  this.miterLimit = '';
+  this.id = Math.random();
+}
+
+function CVContextData() {
+  this.stack = [];
+  this.cArrPos = 0;
+  this.cTr = new Matrix();
+  var i;
+  var len = 15;
+  for (i = 0; i < len; i += 1) {
+    var canvasContext = new CanvasContext();
+    this.stack[i] = canvasContext;
+  }
+  this._length = len;
+  this.nativeContext = null;
+  this.transformMat = new Matrix();
+  this.currentOpacity = 1;
+  //
+  this.currentFillStyle = '';
+  this.appliedFillStyle = '';
+  //
+  this.currentStrokeStyle = '';
+  this.appliedStrokeStyle = '';
+  //
+  this.currentLineWidth = '';
+  this.appliedLineWidth = '';
+  //
+  this.currentLineCap = '';
+  this.appliedLineCap = '';
+  //
+  this.currentLineJoin = '';
+  this.appliedLineJoin = '';
+  //
+  this.appliedMiterLimit = '';
+  this.currentMiterLimit = '';
+}
+
+CVContextData.prototype.duplicate = function () {
+  var newLength = this._length * 2;
+  var i = 0;
+  for (i = this._length; i < newLength; i += 1) {
+    this.stack[i] = new CanvasContext();
+  }
+  this._length = newLength;
+};
+
+CVContextData.prototype.reset = function () {
+  this.cArrPos = 0;
+  this.cTr.reset();
+  this.stack[this.cArrPos].opacity = 1;
+};
+
+CVContextData.prototype.restore = function (forceRestore) {
+  this.cArrPos -= 1;
+  var currentContext = this.stack[this.cArrPos];
+  var transform = currentContext.transform;
+  var i;
+  var arr = this.cTr.props;
+  for (i = 0; i < 16; i += 1) {
+    arr[i] = transform[i];
+  }
+  if (forceRestore) {
+    this.nativeContext.restore();
+    var prevStack = this.stack[this.cArrPos + 1];
+    this.appliedFillStyle = prevStack.fillStyle;
+    this.appliedStrokeStyle = prevStack.strokeStyle;
+    this.appliedLineWidth = prevStack.lineWidth;
+    this.appliedLineCap = prevStack.lineCap;
+    this.appliedLineJoin = prevStack.lineJoin;
+    this.appliedMiterLimit = prevStack.miterLimit;
+  }
+  this.nativeContext.setTransform(transform[0], transform[1], transform[4], transform[5], transform[12], transform[13]);
+  if (forceRestore || (currentContext.opacity !== -1 && this.currentOpacity !== currentContext.opacity)) {
+    this.nativeContext.globalAlpha = currentContext.opacity;
+    this.currentOpacity = currentContext.opacity;
+  }
+  this.currentFillStyle = currentContext.fillStyle;
+  this.currentStrokeStyle = currentContext.strokeStyle;
+  this.currentLineWidth = currentContext.lineWidth;
+  this.currentLineCap = currentContext.lineCap;
+  this.currentLineJoin = currentContext.lineJoin;
+  this.currentMiterLimit = currentContext.miterLimit;
+};
+
+CVContextData.prototype.save = function (saveOnNativeFlag) {
+  if (saveOnNativeFlag) {
+    this.nativeContext.save();
+  }
+  var props = this.cTr.props;
+  if (this._length <= this.cArrPos) {
+    this.duplicate();
+  }
+
+  var currentStack = this.stack[this.cArrPos];
+  var i;
+  for (i = 0; i < 16; i += 1) {
+    currentStack.transform[i] = props[i];
+  }
+  this.cArrPos += 1;
+  var newStack = this.stack[this.cArrPos];
+  newStack.opacity = currentStack.opacity;
+  newStack.fillStyle = currentStack.fillStyle;
+  newStack.strokeStyle = currentStack.strokeStyle;
+  newStack.lineWidth = currentStack.lineWidth;
+  newStack.lineCap = currentStack.lineCap;
+  newStack.lineJoin = currentStack.lineJoin;
+  newStack.miterLimit = currentStack.miterLimit;
+};
+
+CVContextData.prototype.setOpacity = function (value) {
+  this.stack[this.cArrPos].opacity = value;
+};
+
+CVContextData.prototype.setContext = function (value) {
+  this.nativeContext = value;
+};
+
+CVContextData.prototype.fillStyle = function (value) {
+  if (this.stack[this.cArrPos].fillStyle !== value) {
+    this.currentFillStyle = value;
+    this.stack[this.cArrPos].fillStyle = value;
+  }
+};
+
+CVContextData.prototype.strokeStyle = function (value) {
+  if (this.stack[this.cArrPos].strokeStyle !== value) {
+    this.currentStrokeStyle = value;
+    this.stack[this.cArrPos].strokeStyle = value;
+  }
+};
+
+CVContextData.prototype.lineWidth = function (value) {
+  if (this.stack[this.cArrPos].lineWidth !== value) {
+    this.currentLineWidth = value;
+    this.stack[this.cArrPos].lineWidth = value;
+  }
+};
+
+CVContextData.prototype.lineCap = function (value) {
+  if (this.stack[this.cArrPos].lineCap !== value) {
+    this.currentLineCap = value;
+    this.stack[this.cArrPos].lineCap = value;
+  }
+};
+
+CVContextData.prototype.lineJoin = function (value) {
+  if (this.stack[this.cArrPos].lineJoin !== value) {
+    this.currentLineJoin = value;
+    this.stack[this.cArrPos].lineJoin = value;
+  }
+};
+
+CVContextData.prototype.miterLimit = function (value) {
+  if (this.stack[this.cArrPos].miterLimit !== value) {
+    this.currentMiterLimit = value;
+    this.stack[this.cArrPos].miterLimit = value;
+  }
+};
+
+CVContextData.prototype.transform = function (props) {
+  this.transformMat.cloneFromProps(props);
+  // Taking the last transform value from the stored stack of transforms
+  var currentTransform = this.cTr;
+  // Applying the last transform value after the new transform to respect the order of transformations
+  this.transformMat.multiply(currentTransform);
+  // Storing the new transformed value in the stored transform
+  currentTransform.cloneFromProps(this.transformMat.props);
+  var trProps = currentTransform.props;
+  // Applying the new transform to the canvas
+  this.nativeContext.setTransform(trProps[0], trProps[1], trProps[4], trProps[5], trProps[12], trProps[13]);
+};
+
+CVContextData.prototype.opacity = function (op) {
+  var currentOpacity = this.stack[this.cArrPos].opacity;
+  currentOpacity *= op < 0 ? 0 : op;
+  if (this.stack[this.cArrPos].opacity !== currentOpacity) {
+    if (this.currentOpacity !== op) {
+      this.nativeContext.globalAlpha = op;
+      this.currentOpacity = op;
+    }
+    this.stack[this.cArrPos].opacity = currentOpacity;
+  }
+};
+
+CVContextData.prototype.fill = function (rule) {
+  if (this.appliedFillStyle !== this.currentFillStyle) {
+    this.appliedFillStyle = this.currentFillStyle;
+    this.nativeContext.fillStyle = this.appliedFillStyle;
+  }
+  this.nativeContext.fill(rule);
+};
+
+CVContextData.prototype.fillRect = function (x, y, w, h) {
+  if (this.appliedFillStyle !== this.currentFillStyle) {
+    this.appliedFillStyle = this.currentFillStyle;
+    this.nativeContext.fillStyle = this.appliedFillStyle;
+  }
+  this.nativeContext.fillRect(x, y, w, h);
+};
+
+CVContextData.prototype.stroke = function () {
+  if (this.appliedStrokeStyle !== this.currentStrokeStyle) {
+    this.appliedStrokeStyle = this.currentStrokeStyle;
+    this.nativeContext.strokeStyle = this.appliedStrokeStyle;
+  }
+  if (this.appliedLineWidth !== this.currentLineWidth) {
+    this.appliedLineWidth = this.currentLineWidth;
+    this.nativeContext.lineWidth = this.appliedLineWidth;
+  }
+  if (this.appliedLineCap !== this.currentLineCap) {
+    this.appliedLineCap = this.currentLineCap;
+    this.nativeContext.lineCap = this.appliedLineCap;
+  }
+  if (this.appliedLineJoin !== this.currentLineJoin) {
+    this.appliedLineJoin = this.currentLineJoin;
+    this.nativeContext.lineJoin = this.appliedLineJoin;
+  }
+  if (this.appliedMiterLimit !== this.currentMiterLimit) {
+    this.appliedMiterLimit = this.currentMiterLimit;
+    this.nativeContext.miterLimit = this.appliedMiterLimit;
+  }
+  this.nativeContext.stroke();
+};
+
+function CVCompElement(data, globalData, comp) {
+  this.completeLayers = false;
+  this.layers = data.layers;
+  this.pendingElements = [];
+  this.elements = createSizedArray(this.layers.length);
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([CanvasRendererBase, ICompElement, CVBaseElement], CVCompElement);
+
+CVCompElement.prototype.renderInnerContent = function () {
+  var ctx = this.canvasContext;
+  ctx.beginPath();
+  ctx.moveTo(0, 0);
+  ctx.lineTo(this.data.w, 0);
+  ctx.lineTo(this.data.w, this.data.h);
+  ctx.lineTo(0, this.data.h);
+  ctx.lineTo(0, 0);
+  ctx.clip();
+  var i;
+  var len = this.layers.length;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+CVCompElement.prototype.destroy = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+  this.layers = null;
+  this.elements = null;
+};
+
+CVCompElement.prototype.createComp = function (data) {
+  return new CVCompElement(data, this.globalData, this);
+};
+
+function CanvasRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.renderConfig = {
+    clearCanvas: (config && config.clearCanvas !== undefined) ? config.clearCanvas : true,
+    context: (config && config.context) || null,
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+  this.renderConfig.dpr = (config && config.dpr) || 1;
+  if (this.animationItem.wrapper) {
+    this.renderConfig.dpr = (config && config.dpr) || window.devicePixelRatio || 1;
+  }
+  this.renderedFrame = -1;
+  this.globalData = {
+    frameNum: -1,
+    _mdf: false,
+    renderConfig: this.renderConfig,
+    currentGlobalAlpha: -1,
+  };
+  this.contextData = new CVContextData();
+  this.elements = [];
+  this.pendingElements = [];
+  this.transformMat = new Matrix();
+  this.completeLayers = false;
+  this.rendererType = 'canvas';
+  if (this.renderConfig.clearCanvas) {
+    this.ctxTransform = this.contextData.transform.bind(this.contextData);
+    this.ctxOpacity = this.contextData.opacity.bind(this.contextData);
+    this.ctxFillStyle = this.contextData.fillStyle.bind(this.contextData);
+    this.ctxStrokeStyle = this.contextData.strokeStyle.bind(this.contextData);
+    this.ctxLineWidth = this.contextData.lineWidth.bind(this.contextData);
+    this.ctxLineCap = this.contextData.lineCap.bind(this.contextData);
+    this.ctxLineJoin = this.contextData.lineJoin.bind(this.contextData);
+    this.ctxMiterLimit = this.contextData.miterLimit.bind(this.contextData);
+    this.ctxFill = this.contextData.fill.bind(this.contextData);
+    this.ctxFillRect = this.contextData.fillRect.bind(this.contextData);
+    this.ctxStroke = this.contextData.stroke.bind(this.contextData);
+    this.save = this.contextData.save.bind(this.contextData);
+  }
+}
+extendPrototype([CanvasRendererBase], CanvasRenderer);
+
+CanvasRenderer.prototype.createComp = function (data) {
+  return new CVCompElement(data, this.globalData, this);
+};
+
+// Registering renderers
+registerRenderer('canvas', CanvasRenderer);
+
+// Registering shape modifiers
+ShapeModifiers.registerModifier('tm', TrimModifier);
+ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
+ShapeModifiers.registerModifier('rp', RepeaterModifier);
+ShapeModifiers.registerModifier('rd', RoundCornersModifier);
+ShapeModifiers.registerModifier('zz', ZigZagModifier);
+ShapeModifiers.registerModifier('op', OffsetPathModifier);
+
+exports["default"] = lottie;
diff --git a/build/player/cjs/lottie_light_html.min.js b/build/player/cjs/lottie_light_html.min.js
new file mode 100644
index 0000000..db05820
--- /dev/null
+++ b/build/player/cjs/lottie_light_html.min.js
@@ -0,0 +1,12836 @@
+'use strict';
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+const svgNS = 'http://www.w3.org/2000/svg';
+
+let locationHref = '';
+let _useWebWorker = false;
+
+const initialDefaultFrame = -999999;
+
+const setWebWorker = (flag) => { _useWebWorker = !!flag; };
+const getWebWorker = () => _useWebWorker;
+
+const setLocationHref = (value) => { locationHref = value; };
+const getLocationHref = () => locationHref;
+
+function createTag(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElement(type);
+}
+
+function extendPrototype(sources, destination) {
+  var i;
+  var len = sources.length;
+  var sourcePrototype;
+  for (i = 0; i < len; i += 1) {
+    sourcePrototype = sources[i].prototype;
+    for (var attr in sourcePrototype) {
+      if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
+    }
+  }
+}
+
+function getDescriptor(object, prop) {
+  return Object.getOwnPropertyDescriptor(object, prop);
+}
+
+function createProxyFunction(prototype) {
+  function ProxyFunction() {}
+  ProxyFunction.prototype = prototype;
+  return ProxyFunction;
+}
+
+// import Howl from '../../3rd_party/howler';
+
+const audioControllerFactory = (function () {
+  function AudioController(audioFactory) {
+    this.audios = [];
+    this.audioFactory = audioFactory;
+    this._volume = 1;
+    this._isMuted = false;
+  }
+
+  AudioController.prototype = {
+    addAudio: function (audio) {
+      this.audios.push(audio);
+    },
+    pause: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].pause();
+      }
+    },
+    resume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].resume();
+      }
+    },
+    setRate: function (rateValue) {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].setRate(rateValue);
+      }
+    },
+    createAudio: function (assetPath) {
+      if (this.audioFactory) {
+        return this.audioFactory(assetPath);
+      } if (window.Howl) {
+        return new window.Howl({
+          src: [assetPath],
+        });
+      }
+      return {
+        isPlaying: false,
+        play: function () { this.isPlaying = true; },
+        seek: function () { this.isPlaying = false; },
+        playing: function () {},
+        rate: function () {},
+        setVolume: function () {},
+      };
+    },
+    setAudioFactory: function (audioFactory) {
+      this.audioFactory = audioFactory;
+    },
+    setVolume: function (value) {
+      this._volume = value;
+      this._updateVolume();
+    },
+    mute: function () {
+      this._isMuted = true;
+      this._updateVolume();
+    },
+    unmute: function () {
+      this._isMuted = false;
+      this._updateVolume();
+    },
+    getVolume: function () {
+      return this._volume;
+    },
+    _updateVolume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
+      }
+    },
+  };
+
+  return function () {
+    return new AudioController();
+  };
+}());
+
+const createTypedArray = (function () {
+  function createRegularArray(type, len) {
+    var i = 0;
+    var arr = [];
+    var value;
+    switch (type) {
+      case 'int16':
+      case 'uint8c':
+        value = 1;
+        break;
+      default:
+        value = 1.1;
+        break;
+    }
+    for (i = 0; i < len; i += 1) {
+      arr.push(value);
+    }
+    return arr;
+  }
+  function createTypedArrayFactory(type, len) {
+    if (type === 'float32') {
+      return new Float32Array(len);
+    } if (type === 'int16') {
+      return new Int16Array(len);
+    } if (type === 'uint8c') {
+      return new Uint8ClampedArray(len);
+    }
+    return createRegularArray(type, len);
+  }
+  if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
+    return createTypedArrayFactory;
+  }
+  return createRegularArray;
+}());
+
+function createSizedArray(len) {
+  return Array.apply(null, { length: len });
+}
+
+let subframeEnabled = true;
+let expressionsPlugin = null;
+let expressionsInterfaces = null;
+let idPrefix$1 = '';
+const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+let _shouldRoundValues = false;
+const bmPow = Math.pow;
+const bmSqrt = Math.sqrt;
+const bmFloor = Math.floor;
+const bmMax = Math.max;
+const bmMin = Math.min;
+
+const BMMath = {};
+(function () {
+  var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
+  var i;
+  var len = propertyNames.length;
+  for (i = 0; i < len; i += 1) {
+    BMMath[propertyNames[i]] = Math[propertyNames[i]];
+  }
+}());
+
+function ProjectInterface$1() { return {}; }
+BMMath.random = Math.random;
+BMMath.abs = function (val) {
+  var tOfVal = typeof val;
+  if (tOfVal === 'object' && val.length) {
+    var absArr = createSizedArray(val.length);
+    var i;
+    var len = val.length;
+    for (i = 0; i < len; i += 1) {
+      absArr[i] = Math.abs(val[i]);
+    }
+    return absArr;
+  }
+  return Math.abs(val);
+};
+let defaultCurveSegments = 150;
+const degToRads = Math.PI / 180;
+const roundCorner = 0.5519;
+
+function roundValues(flag) {
+  _shouldRoundValues = !!flag;
+}
+
+function bmRnd(value) {
+  if (_shouldRoundValues) {
+    return Math.round(value);
+  }
+  return value;
+}
+
+function styleDiv(element) {
+  element.style.position = 'absolute';
+  element.style.top = 0;
+  element.style.left = 0;
+  element.style.display = 'block';
+  element.style.transformOrigin = '0 0';
+  element.style.webkitTransformOrigin = '0 0';
+  element.style.backfaceVisibility = 'visible';
+  element.style.webkitBackfaceVisibility = 'visible';
+  element.style.transformStyle = 'preserve-3d';
+  element.style.webkitTransformStyle = 'preserve-3d';
+  element.style.mozTransformStyle = 'preserve-3d';
+}
+
+function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
+  this.type = type;
+  this.currentTime = currentTime;
+  this.totalTime = totalTime;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteEvent(type, frameMultiplier) {
+  this.type = type;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
+  this.type = type;
+  this.currentLoop = currentLoop;
+  this.totalLoops = totalLoops;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMSegmentStartEvent(type, firstFrame, totalFrames) {
+  this.type = type;
+  this.firstFrame = firstFrame;
+  this.totalFrames = totalFrames;
+}
+
+function BMDestroyEvent(type, target) {
+  this.type = type;
+  this.target = target;
+}
+
+function BMRenderFrameErrorEvent(nativeError, currentTime) {
+  this.type = 'renderFrameError';
+  this.nativeError = nativeError;
+  this.currentTime = currentTime;
+}
+
+function BMConfigErrorEvent(nativeError) {
+  this.type = 'configError';
+  this.nativeError = nativeError;
+}
+
+function BMAnimationConfigErrorEvent(type, nativeError) {
+  this.type = type;
+  this.nativeError = nativeError;
+}
+
+const createElementID = (function () {
+  var _count = 0;
+  return function createID() {
+    _count += 1;
+    return idPrefix$1 + '__lottie_element_' + _count;
+  };
+}());
+
+function HSVtoRGB(h, s, v) {
+  var r;
+  var g;
+  var b;
+  var i;
+  var f;
+  var p;
+  var q;
+  var t;
+  i = Math.floor(h * 6);
+  f = h * 6 - i;
+  p = v * (1 - s);
+  q = v * (1 - f * s);
+  t = v * (1 - (1 - f) * s);
+  switch (i % 6) {
+    case 0: r = v; g = t; b = p; break;
+    case 1: r = q; g = v; b = p; break;
+    case 2: r = p; g = v; b = t; break;
+    case 3: r = p; g = q; b = v; break;
+    case 4: r = t; g = p; b = v; break;
+    case 5: r = v; g = p; b = q; break;
+    default: break;
+  }
+  return [r,
+    g,
+    b];
+}
+
+function RGBtoHSV(r, g, b) {
+  var max = Math.max(r, g, b);
+  var min = Math.min(r, g, b);
+  var d = max - min;
+  var h;
+  var s = (max === 0 ? 0 : d / max);
+  var v = max / 255;
+
+  switch (max) {
+    case min: h = 0; break;
+    case r: h = (g - b) + d * (g < b ? 6 : 0); h /= 6 * d; break;
+    case g: h = (b - r) + d * 2; h /= 6 * d; break;
+    case b: h = (r - g) + d * 4; h /= 6 * d; break;
+    default: break;
+  }
+
+  return [
+    h,
+    s,
+    v,
+  ];
+}
+
+function addSaturationToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[1] += offset;
+  if (hsv[1] > 1) {
+    hsv[1] = 1;
+  } else if (hsv[1] <= 0) {
+    hsv[1] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addBrightnessToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[2] += offset;
+  if (hsv[2] > 1) {
+    hsv[2] = 1;
+  } else if (hsv[2] < 0) {
+    hsv[2] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addHueToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[0] += offset / 360;
+  if (hsv[0] > 1) {
+    hsv[0] -= 1;
+  } else if (hsv[0] < 0) {
+    hsv[0] += 1;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+const rgbToHex = (function () {
+  var colorMap = [];
+  var i;
+  var hex;
+  for (i = 0; i < 256; i += 1) {
+    hex = i.toString(16);
+    colorMap[i] = hex.length === 1 ? '0' + hex : hex;
+  }
+
+  return function (r, g, b) {
+    if (r < 0) {
+      r = 0;
+    }
+    if (g < 0) {
+      g = 0;
+    }
+    if (b < 0) {
+      b = 0;
+    }
+    return '#' + colorMap[r] + colorMap[g] + colorMap[b];
+  };
+}());
+
+const setSubframeEnabled = (flag) => { subframeEnabled = !!flag; };
+const getSubframeEnabled = () => subframeEnabled;
+const setExpressionsPlugin = (value) => { expressionsPlugin = value; };
+const getExpressionsPlugin = () => expressionsPlugin;
+const setExpressionInterfaces = (value) => { expressionsInterfaces = value; };
+const getExpressionInterfaces = () => expressionsInterfaces;
+const setDefaultCurveSegments = (value) => { defaultCurveSegments = value; };
+const getDefaultCurveSegments = () => defaultCurveSegments;
+const setIdPrefix = (value) => { idPrefix$1 = value; };
+const getIdPrefix = () => idPrefix$1;
+
+function createNS(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElementNS(svgNS, type);
+}
+
+const dataManager = (function () {
+  var _counterId = 1;
+  var processes = [];
+  var workerFn;
+  var workerInstance;
+  var workerProxy = {
+    onmessage: function () {
+
+    },
+    postMessage: function (path) {
+      workerFn({
+        data: path,
+      });
+    },
+  };
+  var _workerSelf = {
+    postMessage: function (data) {
+      workerProxy.onmessage({
+        data: data,
+      });
+    },
+  };
+  function createWorker(fn) {
+    if (window.Worker && window.Blob && getWebWorker()) {
+      var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      var url = URL.createObjectURL(blob);
+      return new Worker(url);
+    }
+    workerFn = fn;
+    return workerProxy;
+  }
+
+  function setupWorker() {
+    if (!workerInstance) {
+      workerInstance = createWorker(function workerStart(e) {
+        function dataFunctionManager() {
+          function completeLayers(layers, comps) {
+            var layerData;
+            var i;
+            var len = layers.length;
+            var j;
+            var jLen;
+            var k;
+            var kLen;
+            for (i = 0; i < len; i += 1) {
+              layerData = layers[i];
+              if (('ks' in layerData) && !layerData.completed) {
+                layerData.completed = true;
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      convertPathsToAbsoluteValues(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) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 0) {
+                  layerData.layers = findCompLayers(layerData.refId, comps);
+                  completeLayers(layerData.layers, comps);
+                } else if (layerData.ty === 4) {
+                  completeShapes(layerData.shapes);
+                } else if (layerData.ty === 5) {
+                  completeText(layerData);
+                }
+              }
+            }
+          }
+
+          function completeChars(chars, assets) {
+            if (chars) {
+              var i = 0;
+              var len = chars.length;
+              for (i = 0; i < len; i += 1) {
+                if (chars[i].t === 1) {
+                  // var compData = findComp(chars[i].data.refId, assets);
+                  chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                  // chars[i].data.ip = 0;
+                  // chars[i].data.op = 99999;
+                  // chars[i].data.st = 0;
+                  // chars[i].data.sr = 1;
+                  // chars[i].w = compData.w;
+                  // chars[i].data.ks = {
+                  //   a: { k: [0, 0, 0], a: 0 },
+                  //   p: { k: [0, -compData.h, 0], a: 0 },
+                  //   r: { k: 0, a: 0 },
+                  //   s: { k: [100, 100], a: 0 },
+                  //   o: { k: 100, a: 0 },
+                  // };
+                  completeLayers(chars[i].data.layers, assets);
+                }
+              }
+            }
+          }
+
+          function findComp(id, comps) {
+            var i = 0;
+            var len = comps.length;
+            while (i < len) {
+              if (comps[i].id === id) {
+                return comps[i];
+              }
+              i += 1;
+            }
+            return null;
+          }
+
+          function findCompLayers(id, comps) {
+            var comp = findComp(id, comps);
+            if (comp) {
+              if (!comp.layers.__used) {
+                comp.layers.__used = true;
+                return comp.layers;
+              }
+              return JSON.parse(JSON.stringify(comp.layers));
+            }
+            return null;
+          }
+
+          function completeShapes(arr) {
+            var i;
+            var len = arr.length;
+            var j;
+            var jLen;
+            for (i = len - 1; i >= 0; i -= 1) {
+              if (arr[i].ty === 'sh') {
+                if (arr[i].ks.k.i) {
+                  convertPathsToAbsoluteValues(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) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
+                    }
+                    if (arr[i].ks.k[j].e) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
+                    }
+                  }
+                }
+              } else if (arr[i].ty === 'gr') {
+                completeShapes(arr[i].it);
+              }
+            }
+          }
+
+          function convertPathsToAbsoluteValues(path) {
+            var i;
+            var len = path.i.length;
+            for (i = 0; i < len; i += 1) {
+              path.i[i][0] += path.v[i][0];
+              path.i[i][1] += path.v[i][1];
+              path.o[i][0] += path.v[i][0];
+              path.o[i][1] += path.v[i][1];
+            }
+          }
+
+          function checkVersion(minimum, animVersionString) {
+            var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
+            if (minimum[0] > animVersion[0]) {
+              return true;
+            } if (animVersion[0] > minimum[0]) {
+              return false;
+            }
+            if (minimum[1] > animVersion[1]) {
+              return true;
+            } if (animVersion[1] > minimum[1]) {
+              return false;
+            }
+            if (minimum[2] > animVersion[2]) {
+              return true;
+            } if (animVersion[2] > minimum[2]) {
+              return false;
+            }
+            return null;
+          }
+
+          var checkText = (function () {
+            var minimumVersion = [4, 4, 14];
+
+            function updateTextLayer(textLayer) {
+              var documentData = textLayer.t.d;
+              textLayer.t.d = {
+                k: [
+                  {
+                    s: documentData,
+                    t: 0,
+                  },
+                ],
+              };
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkChars = (function () {
+            var minimumVersion = [4, 7, 99];
+            return function (animationData) {
+              if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
+                var i;
+                var len = animationData.chars.length;
+                for (i = 0; i < len; i += 1) {
+                  var charData = animationData.chars[i];
+                  if (charData.data && charData.data.shapes) {
+                    completeShapes(charData.data.shapes);
+                    charData.data.ip = 0;
+                    charData.data.op = 99999;
+                    charData.data.st = 0;
+                    charData.data.sr = 1;
+                    charData.data.ks = {
+                      p: { k: [0, 0], a: 0 },
+                      s: { k: [100, 100], a: 0 },
+                      a: { k: [0, 0], a: 0 },
+                      r: { k: 0, a: 0 },
+                      o: { k: 100, a: 0 },
+                    };
+                    if (!animationData.chars[i].t) {
+                      charData.data.shapes.push(
+                        {
+                          ty: 'no',
+                        }
+                      );
+                      charData.data.shapes[0].it.push(
+                        {
+                          p: { k: [0, 0], a: 0 },
+                          s: { k: [100, 100], a: 0 },
+                          a: { k: [0, 0], a: 0 },
+                          r: { k: 0, a: 0 },
+                          o: { k: 100, a: 0 },
+                          sk: { k: 0, a: 0 },
+                          sa: { k: 0, a: 0 },
+                          ty: 'tr',
+                        }
+                      );
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkPathProperties = (function () {
+            var minimumVersion = [5, 7, 15];
+
+            function updateTextLayer(textLayer) {
+              var pathData = textLayer.t.p;
+              if (typeof pathData.a === 'number') {
+                pathData.a = {
+                  a: 0,
+                  k: pathData.a,
+                };
+              }
+              if (typeof pathData.p === 'number') {
+                pathData.p = {
+                  a: 0,
+                  k: pathData.p,
+                };
+              }
+              if (typeof pathData.r === 'number') {
+                pathData.r = {
+                  a: 0,
+                  k: pathData.r,
+                };
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkColors = (function () {
+            var minimumVersion = [4, 1, 9];
+
+            function iterateShapes(shapes) {
+              var i;
+              var len = shapes.length;
+              var j;
+              var jLen;
+              for (i = 0; i < len; i += 1) {
+                if (shapes[i].ty === 'gr') {
+                  iterateShapes(shapes[i].it);
+                } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
+                  if (shapes[i].c.k && shapes[i].c.k[0].i) {
+                    jLen = shapes[i].c.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (shapes[i].c.k[j].s) {
+                        shapes[i].c.k[j].s[0] /= 255;
+                        shapes[i].c.k[j].s[1] /= 255;
+                        shapes[i].c.k[j].s[2] /= 255;
+                        shapes[i].c.k[j].s[3] /= 255;
+                      }
+                      if (shapes[i].c.k[j].e) {
+                        shapes[i].c.k[j].e[0] /= 255;
+                        shapes[i].c.k[j].e[1] /= 255;
+                        shapes[i].c.k[j].e[2] /= 255;
+                        shapes[i].c.k[j].e[3] /= 255;
+                      }
+                    }
+                  } else {
+                    shapes[i].c.k[0] /= 255;
+                    shapes[i].c.k[1] /= 255;
+                    shapes[i].c.k[2] /= 255;
+                    shapes[i].c.k[3] /= 255;
+                  }
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 4) {
+                  iterateShapes(layers[i].shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkShapes = (function () {
+            var minimumVersion = [4, 4, 18];
+
+            function completeClosingShapes(arr) {
+              var i;
+              var len = arr.length;
+              var j;
+              var jLen;
+              for (i = len - 1; i >= 0; i -= 1) {
+                if (arr[i].ty === 'sh') {
+                  if (arr[i].ks.k.i) {
+                    arr[i].ks.k.c = arr[i].closed;
+                  } else {
+                    jLen = arr[i].ks.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (arr[i].ks.k[j].s) {
+                        arr[i].ks.k[j].s[0].c = arr[i].closed;
+                      }
+                      if (arr[i].ks.k[j].e) {
+                        arr[i].ks.k[j].e[0].c = arr[i].closed;
+                      }
+                    }
+                  }
+                } else if (arr[i].ty === 'gr') {
+                  completeClosingShapes(arr[i].it);
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var layerData;
+              var i;
+              var len = layers.length;
+              var j;
+              var jLen;
+              var k;
+              var kLen;
+              for (i = 0; i < len; i += 1) {
+                layerData = layers[i];
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      maskProps[j].pt.k.c = maskProps[j].cl;
+                    } else {
+                      kLen = maskProps[j].pt.k.length;
+                      for (k = 0; k < kLen; k += 1) {
+                        if (maskProps[j].pt.k[k].s) {
+                          maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 4) {
+                  completeClosingShapes(layerData.shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          function completeData(animationData) {
+            if (animationData.__complete) {
+              return;
+            }
+            checkColors(animationData);
+            checkText(animationData);
+            checkChars(animationData);
+            checkPathProperties(animationData);
+            checkShapes(animationData);
+            completeLayers(animationData.layers, animationData.assets);
+            completeChars(animationData.chars, animationData.assets);
+            animationData.__complete = true;
+          }
+
+          function completeText(data) {
+            if (data.t.a.length === 0 && !('m' in data.t.p)) {
+              // data.singleShape = true;
+            }
+          }
+
+          var moduleOb = {};
+          moduleOb.completeData = completeData;
+          moduleOb.checkColors = checkColors;
+          moduleOb.checkChars = checkChars;
+          moduleOb.checkPathProperties = checkPathProperties;
+          moduleOb.checkShapes = checkShapes;
+          moduleOb.completeLayers = completeLayers;
+
+          return moduleOb;
+        }
+        if (!_workerSelf.dataManager) {
+          _workerSelf.dataManager = dataFunctionManager();
+        }
+
+        if (!_workerSelf.assetLoader) {
+          _workerSelf.assetLoader = (function () {
+            function formatResponse(xhr) {
+              // using typeof doubles the time of execution of this method,
+              // so if available, it's better to use the header to validate the type
+              var contentTypeHeader = xhr.getResponseHeader('content-type');
+              if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
+                return xhr.response;
+              }
+              if (xhr.response && typeof xhr.response === 'object') {
+                return xhr.response;
+              } if (xhr.response && typeof xhr.response === 'string') {
+                return JSON.parse(xhr.response);
+              } if (xhr.responseText) {
+                return JSON.parse(xhr.responseText);
+              }
+              return null;
+            }
+
+            function loadAsset(path, fullPath, callback, errorCallback) {
+              var response;
+              var xhr = new XMLHttpRequest();
+              // set responseType after calling open or IE will break.
+              try {
+                // This crashes on Android WebView prior to KitKat
+                xhr.responseType = 'json';
+              } catch (err) {} // eslint-disable-line no-empty
+              xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4) {
+                  if (xhr.status === 200) {
+                    response = formatResponse(xhr);
+                    callback(response);
+                  } else {
+                    try {
+                      response = formatResponse(xhr);
+                      callback(response);
+                    } catch (err) {
+                      if (errorCallback) {
+                        errorCallback(err);
+                      }
+                    }
+                  }
+                }
+              };
+              try {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), path, true);
+              } catch (error) {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
+              }
+              xhr.send();
+            }
+            return {
+              load: loadAsset,
+            };
+          }());
+        }
+
+        if (e.data.type === 'loadAnimation') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.dataManager.completeData(data);
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        } else if (e.data.type === 'complete') {
+          var animation = e.data.animation;
+          _workerSelf.dataManager.completeData(animation);
+          _workerSelf.postMessage({
+            id: e.data.id,
+            payload: animation,
+            status: 'success',
+          });
+        } else if (e.data.type === 'loadData') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        }
+      });
+
+      workerInstance.onmessage = function (event) {
+        var data = event.data;
+        var id = data.id;
+        var process = processes[id];
+        processes[id] = null;
+        if (data.status === 'success') {
+          process.onComplete(data.payload);
+        } else if (process.onError) {
+          process.onError();
+        }
+      };
+    }
+  }
+
+  function createProcess(onComplete, onError) {
+    _counterId += 1;
+    var id = 'processId_' + _counterId;
+    processes[id] = {
+      onComplete: onComplete,
+      onError: onError,
+    };
+    return id;
+  }
+
+  function loadAnimation(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadAnimation',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function loadData(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadData',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function completeAnimation(anim, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'complete',
+      animation: anim,
+      id: processId,
+    });
+  }
+
+  return {
+    loadAnimation: loadAnimation,
+    loadData: loadData,
+    completeAnimation: completeAnimation,
+  };
+}());
+
+const ImagePreloader = (function () {
+  var proxyImage = (function () {
+    var canvas = createTag('canvas');
+    canvas.width = 1;
+    canvas.height = 1;
+    var ctx = canvas.getContext('2d');
+    ctx.fillStyle = 'rgba(0,0,0,0)';
+    ctx.fillRect(0, 0, 1, 1);
+    return canvas;
+  }());
+
+  function imageLoaded() {
+    this.loadedAssets += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+  function footageLoaded() {
+    this.loadedFootagesCount += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+
+  function getAssetsPath(assetData, assetsPath, originalPath) {
+    var path = '';
+    if (assetData.e) {
+      path = assetData.p;
+    } else if (assetsPath) {
+      var imagePath = assetData.p;
+      if (imagePath.indexOf('images/') !== -1) {
+        imagePath = imagePath.split('/')[1];
+      }
+      path = assetsPath + imagePath;
+    } else {
+      path = originalPath;
+      path += assetData.u ? assetData.u : '';
+      path += assetData.p;
+    }
+    return path;
+  }
+
+  function testImageLoaded(img) {
+    var _count = 0;
+    var intervalId = setInterval(function () {
+      var box = img.getBBox();
+      if (box.width || _count > 500) {
+        this._imageLoaded();
+        clearInterval(intervalId);
+      }
+      _count += 1;
+    }.bind(this), 50);
+  }
+
+  function createImageData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createNS('image');
+    if (isSafari) {
+      this.testImageLoaded(img);
+    } else {
+      img.addEventListener('load', this._imageLoaded, false);
+    }
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
+    if (this._elementHelper.append) {
+      this._elementHelper.append(img);
+    } else {
+      this._elementHelper.appendChild(img);
+    }
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createImgData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createTag('img');
+    img.crossOrigin = 'anonymous';
+    img.addEventListener('load', this._imageLoaded, false);
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.src = path;
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createFootageData(data) {
+    var ob = {
+      assetData: data,
+    };
+    var path = getAssetsPath(data, this.assetsPath, this.path);
+    dataManager.loadData(path, function (footageData) {
+      ob.img = footageData;
+      this._footageLoaded();
+    }.bind(this), function () {
+      ob.img = {};
+      this._footageLoaded();
+    }.bind(this));
+    return ob;
+  }
+
+  function loadAssets(assets, cb) {
+    this.imagesLoadedCb = cb;
+    var i;
+    var len = assets.length;
+    for (i = 0; i < len; i += 1) {
+      if (!assets[i].layers) {
+        if (!assets[i].t || assets[i].t === 'seq') {
+          this.totalImages += 1;
+          this.images.push(this._createImageData(assets[i]));
+        } else if (assets[i].t === 3) {
+          this.totalFootages += 1;
+          this.images.push(this.createFootageData(assets[i]));
+        }
+      }
+    }
+  }
+
+  function setPath(path) {
+    this.path = path || '';
+  }
+
+  function setAssetsPath(path) {
+    this.assetsPath = path || '';
+  }
+
+  function getAsset(assetData) {
+    var i = 0;
+    var len = this.images.length;
+    while (i < len) {
+      if (this.images[i].assetData === assetData) {
+        return this.images[i].img;
+      }
+      i += 1;
+    }
+    return null;
+  }
+
+  function destroy() {
+    this.imagesLoadedCb = null;
+    this.images.length = 0;
+  }
+
+  function loadedImages() {
+    return this.totalImages === this.loadedAssets;
+  }
+
+  function loadedFootages() {
+    return this.totalFootages === this.loadedFootagesCount;
+  }
+
+  function setCacheType(type, elementHelper) {
+    if (type === 'svg') {
+      this._elementHelper = elementHelper;
+      this._createImageData = this.createImageData.bind(this);
+    } else {
+      this._createImageData = this.createImgData.bind(this);
+    }
+  }
+
+  function ImagePreloaderFactory() {
+    this._imageLoaded = imageLoaded.bind(this);
+    this._footageLoaded = footageLoaded.bind(this);
+    this.testImageLoaded = testImageLoaded.bind(this);
+    this.createFootageData = createFootageData.bind(this);
+    this.assetsPath = '';
+    this.path = '';
+    this.totalImages = 0;
+    this.totalFootages = 0;
+    this.loadedAssets = 0;
+    this.loadedFootagesCount = 0;
+    this.imagesLoadedCb = null;
+    this.images = [];
+  }
+
+  ImagePreloaderFactory.prototype = {
+    loadAssets: loadAssets,
+    setAssetsPath: setAssetsPath,
+    setPath: setPath,
+    loadedImages: loadedImages,
+    loadedFootages: loadedFootages,
+    destroy: destroy,
+    getAsset: getAsset,
+    createImgData: createImgData,
+    createImageData: createImageData,
+    imageLoaded: imageLoaded,
+    footageLoaded: footageLoaded,
+    setCacheType: setCacheType,
+  };
+
+  return ImagePreloaderFactory;
+}());
+
+function BaseEvent() {}
+BaseEvent.prototype = {
+  triggerEvent: function (eventName, args) {
+    if (this._cbs[eventName]) {
+      var callbacks = this._cbs[eventName];
+      for (var i = 0; i < callbacks.length; i += 1) {
+        callbacks[i](args);
+      }
+    }
+  },
+  addEventListener: function (eventName, callback) {
+    if (!this._cbs[eventName]) {
+      this._cbs[eventName] = [];
+    }
+    this._cbs[eventName].push(callback);
+
+    return function () {
+      this.removeEventListener(eventName, callback);
+    }.bind(this);
+  },
+  removeEventListener: function (eventName, callback) {
+    if (!callback) {
+      this._cbs[eventName] = null;
+    } else if (this._cbs[eventName]) {
+      var i = 0;
+      var len = this._cbs[eventName].length;
+      while (i < len) {
+        if (this._cbs[eventName][i] === callback) {
+          this._cbs[eventName].splice(i, 1);
+          i -= 1;
+          len -= 1;
+        }
+        i += 1;
+      }
+      if (!this._cbs[eventName].length) {
+        this._cbs[eventName] = null;
+      }
+    }
+  },
+};
+
+const markerParser = (
+
+  function () {
+    function parsePayloadLines(payload) {
+      var lines = payload.split('\r\n');
+      var keys = {};
+      var line;
+      var keysCount = 0;
+      for (var i = 0; i < lines.length; i += 1) {
+        line = lines[i].split(':');
+        if (line.length === 2) {
+          keys[line[0]] = line[1].trim();
+          keysCount += 1;
+        }
+      }
+      if (keysCount === 0) {
+        throw new Error();
+      }
+      return keys;
+    }
+
+    return function (_markers) {
+      var markers = [];
+      for (var i = 0; i < _markers.length; i += 1) {
+        var _marker = _markers[i];
+        var markerData = {
+          time: _marker.tm,
+          duration: _marker.dr,
+        };
+        try {
+          markerData.payload = JSON.parse(_markers[i].cm);
+        } catch (_) {
+          try {
+            markerData.payload = parsePayloadLines(_markers[i].cm);
+          } catch (__) {
+            markerData.payload = {
+              name: _markers[i].cm,
+            };
+          }
+        }
+        markers.push(markerData);
+      }
+      return markers;
+    };
+  }());
+
+const ProjectInterface = (function () {
+  function registerComposition(comp) {
+    this.compositions.push(comp);
+  }
+
+  return function () {
+    function _thisProjectFunction(name) {
+      var i = 0;
+      var len = this.compositions.length;
+      while (i < len) {
+        if (this.compositions[i].data && this.compositions[i].data.nm === name) {
+          if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
+            this.compositions[i].prepareFrame(this.currentFrame);
+          }
+          return this.compositions[i].compInterface;
+        }
+        i += 1;
+      }
+      return null;
+    }
+
+    _thisProjectFunction.compositions = [];
+    _thisProjectFunction.currentFrame = 0;
+
+    _thisProjectFunction.registerComposition = registerComposition;
+
+    return _thisProjectFunction;
+  };
+}());
+
+const renderers = {};
+
+const registerRenderer = (key, value) => {
+  renderers[key] = value;
+};
+
+function getRenderer(key) {
+  return renderers[key];
+}
+
+function getRegisteredRenderer() {
+  // Returns canvas by default for compatibility
+  if (renderers.canvas) {
+    return 'canvas';
+  }
+  // Returns any renderer that is registered
+  for (const key in renderers) {
+    if (renderers[key]) {
+      return key;
+    }
+  }
+  return '';
+}
+
+const AnimationItem = function () {
+  this._cbs = [];
+  this.name = '';
+  this.path = '';
+  this.isLoaded = false;
+  this.currentFrame = 0;
+  this.currentRawFrame = 0;
+  this.firstFrame = 0;
+  this.totalFrames = 0;
+  this.frameRate = 0;
+  this.frameMult = 0;
+  this.playSpeed = 1;
+  this.playDirection = 1;
+  this.playCount = 0;
+  this.animationData = {};
+  this.assets = [];
+  this.isPaused = true;
+  this.autoplay = false;
+  this.loop = true;
+  this.renderer = null;
+  this.animationID = createElementID();
+  this.assetsPath = '';
+  this.timeCompleted = 0;
+  this.segmentPos = 0;
+  this.isSubframeEnabled = getSubframeEnabled();
+  this.segments = [];
+  this._idle = true;
+  this._completedLoop = false;
+  this.projectInterface = ProjectInterface();
+  this.imagePreloader = new ImagePreloader();
+  this.audioController = audioControllerFactory();
+  this.markers = [];
+  this.configAnimation = this.configAnimation.bind(this);
+  this.onSetupError = this.onSetupError.bind(this);
+  this.onSegmentComplete = this.onSegmentComplete.bind(this);
+  this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
+  this.expressionsPlugin = getExpressionsPlugin();
+};
+
+extendPrototype([BaseEvent], AnimationItem);
+
+AnimationItem.prototype.setParams = function (params) {
+  if (params.wrapper || params.container) {
+    this.wrapper = params.wrapper || params.container;
+  }
+  var animType = 'svg';
+  if (params.animType) {
+    animType = params.animType;
+  } else if (params.renderer) {
+    animType = params.renderer;
+  }
+  const RendererClass = getRenderer(animType);
+  this.renderer = new RendererClass(this, params.rendererSettings);
+  this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
+  this.renderer.setProjectInterface(this.projectInterface);
+  this.animType = animType;
+  if (params.loop === ''
+        || params.loop === null
+        || params.loop === undefined
+        || params.loop === true) {
+    this.loop = true;
+  } else if (params.loop === false) {
+    this.loop = false;
+  } else {
+    this.loop = parseInt(params.loop, 10);
+  }
+  this.autoplay = 'autoplay' in params ? params.autoplay : true;
+  this.name = params.name ? params.name : '';
+  this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
+  this.assetsPath = params.assetsPath;
+  this.initialSegment = params.initialSegment;
+  if (params.audioFactory) {
+    this.audioController.setAudioFactory(params.audioFactory);
+  }
+  if (params.animationData) {
+    this.setupAnimation(params.animationData);
+  } else if (params.path) {
+    if (params.path.lastIndexOf('\\') !== -1) {
+      this.path = params.path.substr(0, params.path.lastIndexOf('\\') + 1);
+    } else {
+      this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
+    }
+    this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
+    this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
+    dataManager.loadAnimation(
+      params.path,
+      this.configAnimation,
+      this.onSetupError
+    );
+  }
+};
+
+AnimationItem.prototype.onSetupError = function () {
+  this.trigger('data_failed');
+};
+
+AnimationItem.prototype.setupAnimation = function (data) {
+  dataManager.completeAnimation(
+    data,
+    this.configAnimation
+  );
+};
+
+AnimationItem.prototype.setData = function (wrapper, animationData) {
+  if (animationData) {
+    if (typeof animationData !== 'object') {
+      animationData = JSON.parse(animationData);
+    }
+  }
+  var params = {
+    wrapper: wrapper,
+    animationData: animationData,
+  };
+  var wrapperAttributes = wrapper.attributes;
+
+  params.path = wrapperAttributes.getNamedItem('data-animation-path') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-animation-path').value
+    : wrapperAttributes.getNamedItem('data-bm-path') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-path').value
+      : wrapperAttributes.getNamedItem('bm-path')
+        ? wrapperAttributes.getNamedItem('bm-path').value
+        : '';
+  params.animType = wrapperAttributes.getNamedItem('data-anim-type') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-type').value
+    : wrapperAttributes.getNamedItem('data-bm-type') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-type').value
+      : wrapperAttributes.getNamedItem('bm-type') // eslint-disable-line no-nested-ternary
+        ? wrapperAttributes.getNamedItem('bm-type').value
+        : wrapperAttributes.getNamedItem('data-bm-renderer') // eslint-disable-line no-nested-ternary
+          ? wrapperAttributes.getNamedItem('data-bm-renderer').value
+          : wrapperAttributes.getNamedItem('bm-renderer')
+            ? wrapperAttributes.getNamedItem('bm-renderer').value
+            : getRegisteredRenderer() || 'canvas';
+
+  var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-loop').value
+    : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-loop').value
+      : wrapperAttributes.getNamedItem('bm-loop')
+        ? wrapperAttributes.getNamedItem('bm-loop').value
+        : '';
+  if (loop === 'false') {
+    params.loop = false;
+  } else if (loop === 'true') {
+    params.loop = true;
+  } else if (loop !== '') {
+    params.loop = parseInt(loop, 10);
+  }
+  var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-autoplay').value
+    : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-autoplay').value
+      : wrapperAttributes.getNamedItem('bm-autoplay')
+        ? wrapperAttributes.getNamedItem('bm-autoplay').value
+        : true;
+  params.autoplay = autoplay !== 'false';
+
+  params.name = wrapperAttributes.getNamedItem('data-name') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-name').value
+    : wrapperAttributes.getNamedItem('data-bm-name') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-name').value
+      : wrapperAttributes.getNamedItem('bm-name')
+        ? wrapperAttributes.getNamedItem('bm-name').value
+        : '';
+  var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-prerender').value
+    : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-prerender').value
+      : wrapperAttributes.getNamedItem('bm-prerender')
+        ? wrapperAttributes.getNamedItem('bm-prerender').value
+        : '';
+
+  if (prerender === 'false') {
+    params.prerender = false;
+  }
+  if (!params.path) {
+    this.trigger('destroy');
+  } else {
+    this.setParams(params);
+  }
+};
+
+AnimationItem.prototype.includeLayers = function (data) {
+  if (data.op > this.animationData.op) {
+    this.animationData.op = data.op;
+    this.totalFrames = Math.floor(data.op - this.animationData.ip);
+  }
+  var layers = this.animationData.layers;
+  var i;
+  var len = layers.length;
+  var newLayers = data.layers;
+  var j;
+  var jLen = newLayers.length;
+  for (j = 0; j < jLen; j += 1) {
+    i = 0;
+    while (i < len) {
+      if (layers[i].id === newLayers[j].id) {
+        layers[i] = newLayers[j];
+        break;
+      }
+      i += 1;
+    }
+  }
+  if (data.chars || data.fonts) {
+    this.renderer.globalData.fontManager.addChars(data.chars);
+    this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
+  }
+  if (data.assets) {
+    len = data.assets.length;
+    for (i = 0; i < len; i += 1) {
+      this.animationData.assets.push(data.assets[i]);
+    }
+  }
+  this.animationData.__complete = false;
+  dataManager.completeAnimation(
+    this.animationData,
+    this.onSegmentComplete
+  );
+};
+
+AnimationItem.prototype.onSegmentComplete = function (data) {
+  this.animationData = data;
+  var expressionsPlugin = getExpressionsPlugin();
+  if (expressionsPlugin) {
+    expressionsPlugin.initExpressions(this);
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.loadNextSegment = function () {
+  var segments = this.animationData.segments;
+  if (!segments || segments.length === 0 || !this.autoloadSegments) {
+    this.trigger('data_ready');
+    this.timeCompleted = this.totalFrames;
+    return;
+  }
+  var segment = segments.shift();
+  this.timeCompleted = segment.time * this.frameRate;
+  var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
+  this.segmentPos += 1;
+  dataManager.loadData(segmentPath, this.includeLayers.bind(this), function () {
+    this.trigger('data_failed');
+  }.bind(this));
+};
+
+AnimationItem.prototype.loadSegments = function () {
+  var segments = this.animationData.segments;
+  if (!segments) {
+    this.timeCompleted = this.totalFrames;
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.imagesLoaded = function () {
+  this.trigger('loaded_images');
+  this.checkLoaded();
+};
+
+AnimationItem.prototype.preloadImages = function () {
+  this.imagePreloader.setAssetsPath(this.assetsPath);
+  this.imagePreloader.setPath(this.path);
+  this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
+};
+
+AnimationItem.prototype.configAnimation = function (animData) {
+  if (!this.renderer) {
+    return;
+  }
+  try {
+    this.animationData = animData;
+    if (this.initialSegment) {
+      this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
+      this.firstFrame = Math.round(this.initialSegment[0]);
+    } else {
+      this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
+      this.firstFrame = Math.round(this.animationData.ip);
+    }
+    this.renderer.configAnimation(animData);
+    if (!animData.assets) {
+      animData.assets = [];
+    }
+
+    this.assets = this.animationData.assets;
+    this.frameRate = this.animationData.fr;
+    this.frameMult = this.animationData.fr / 1000;
+    this.renderer.searchExtraCompositions(animData.assets);
+    this.markers = markerParser(animData.markers || []);
+    this.trigger('config_ready');
+    this.preloadImages();
+    this.loadSegments();
+    this.updaFrameModifier();
+    this.waitForFontsLoaded();
+    if (this.isPaused) {
+      this.audioController.pause();
+    }
+  } catch (error) {
+    this.triggerConfigError(error);
+  }
+};
+
+AnimationItem.prototype.waitForFontsLoaded = function () {
+  if (!this.renderer) {
+    return;
+  }
+  if (this.renderer.globalData.fontManager.isLoaded) {
+    this.checkLoaded();
+  } else {
+    setTimeout(this.waitForFontsLoaded.bind(this), 20);
+  }
+};
+
+AnimationItem.prototype.checkLoaded = function () {
+  if (!this.isLoaded
+        && this.renderer.globalData.fontManager.isLoaded
+        && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas')
+        && (this.imagePreloader.loadedFootages())
+  ) {
+    this.isLoaded = true;
+    var expressionsPlugin = getExpressionsPlugin();
+    if (expressionsPlugin) {
+      expressionsPlugin.initExpressions(this);
+    }
+    this.renderer.initItems();
+    setTimeout(function () {
+      this.trigger('DOMLoaded');
+    }.bind(this), 0);
+    this.gotoFrame();
+    if (this.autoplay) {
+      this.play();
+    }
+  }
+};
+
+AnimationItem.prototype.resize = function (width, height) {
+  // Adding this validation for backwards compatibility in case an event object was being passed down
+  var _width = typeof width === 'number' ? width : undefined;
+  var _height = typeof height === 'number' ? height : undefined;
+  this.renderer.updateContainerSize(_width, _height);
+};
+
+AnimationItem.prototype.setSubframe = function (flag) {
+  this.isSubframeEnabled = !!flag;
+};
+
+AnimationItem.prototype.gotoFrame = function () {
+  this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
+
+  if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
+    this.currentFrame = this.timeCompleted;
+  }
+  this.trigger('enterFrame');
+  this.renderFrame();
+  this.trigger('drawnFrame');
+};
+
+AnimationItem.prototype.renderFrame = function () {
+  if (this.isLoaded === false || !this.renderer) {
+    return;
+  }
+  try {
+    if (this.expressionsPlugin) {
+      this.expressionsPlugin.resetFrame();
+    }
+    this.renderer.renderFrame(this.currentFrame + this.firstFrame);
+  } catch (error) {
+    this.triggerRenderFrameError(error);
+  }
+};
+
+AnimationItem.prototype.play = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.isPaused = false;
+    this.trigger('_play');
+    this.audioController.resume();
+    if (this._idle) {
+      this._idle = false;
+      this.trigger('_active');
+    }
+  }
+};
+
+AnimationItem.prototype.pause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === false) {
+    this.isPaused = true;
+    this.trigger('_pause');
+    this._idle = true;
+    this.trigger('_idle');
+    this.audioController.pause();
+  }
+};
+
+AnimationItem.prototype.togglePause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.play();
+  } else {
+    this.pause();
+  }
+};
+
+AnimationItem.prototype.stop = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.pause();
+  this.playCount = 0;
+  this._completedLoop = false;
+  this.setCurrentRawFrameValue(0);
+};
+
+AnimationItem.prototype.getMarkerData = function (markerName) {
+  var marker;
+  for (var i = 0; i < this.markers.length; i += 1) {
+    marker = this.markers[i];
+    if (marker.payload && marker.payload.name === markerName) {
+      return marker;
+    }
+  }
+  return null;
+};
+
+AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      this.goToAndStop(marker.time, true);
+    }
+  } else if (isFrame) {
+    this.setCurrentRawFrameValue(value);
+  } else {
+    this.setCurrentRawFrameValue(value * this.frameModifier);
+  }
+  this.pause();
+};
+
+AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      if (!marker.duration) {
+        this.goToAndStop(marker.time, true);
+      } else {
+        this.playSegments([marker.time, marker.time + marker.duration], true);
+      }
+    }
+  } else {
+    this.goToAndStop(numValue, isFrame, name);
+  }
+  this.play();
+};
+
+AnimationItem.prototype.advanceTime = function (value) {
+  if (this.isPaused === true || this.isLoaded === false) {
+    return;
+  }
+  var nextValue = this.currentRawFrame + value * this.frameModifier;
+  var _isComplete = false;
+  // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+  // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
+  if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
+    if (!this.loop || this.playCount === this.loop) {
+      if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
+        _isComplete = true;
+        nextValue = this.totalFrames - 1;
+      }
+    } else if (nextValue >= this.totalFrames) {
+      this.playCount += 1;
+      if (!this.checkSegments(nextValue % this.totalFrames)) {
+        this.setCurrentRawFrameValue(nextValue % this.totalFrames);
+        this._completedLoop = true;
+        this.trigger('loopComplete');
+      }
+    } else {
+      this.setCurrentRawFrameValue(nextValue);
+    }
+  } else if (nextValue < 0) {
+    if (!this.checkSegments(nextValue % this.totalFrames)) {
+      if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) { // eslint-disable-line no-plusplus
+        this.setCurrentRawFrameValue(this.totalFrames + (nextValue % this.totalFrames));
+        if (!this._completedLoop) {
+          this._completedLoop = true;
+        } else {
+          this.trigger('loopComplete');
+        }
+      } else {
+        _isComplete = true;
+        nextValue = 0;
+      }
+    }
+  } else {
+    this.setCurrentRawFrameValue(nextValue);
+  }
+  if (_isComplete) {
+    this.setCurrentRawFrameValue(nextValue);
+    this.pause();
+    this.trigger('complete');
+  }
+};
+
+AnimationItem.prototype.adjustSegment = function (arr, offset) {
+  this.playCount = 0;
+  if (arr[1] < arr[0]) {
+    if (this.frameModifier > 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(-1);
+      }
+    }
+    this.totalFrames = arr[0] - arr[1];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[1];
+    this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset);
+  } else if (arr[1] > arr[0]) {
+    if (this.frameModifier < 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(1);
+      }
+    }
+    this.totalFrames = arr[1] - arr[0];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[0];
+    this.setCurrentRawFrameValue(0.001 + offset);
+  }
+  this.trigger('segmentStart');
+};
+AnimationItem.prototype.setSegment = function (init, end) {
+  var pendingFrame = -1;
+  if (this.isPaused) {
+    if (this.currentRawFrame + this.firstFrame < init) {
+      pendingFrame = init;
+    } else if (this.currentRawFrame + this.firstFrame > end) {
+      pendingFrame = end - init;
+    }
+  }
+
+  this.firstFrame = init;
+  this.totalFrames = end - init;
+  this.timeCompleted = this.totalFrames;
+  if (pendingFrame !== -1) {
+    this.goToAndStop(pendingFrame, true);
+  }
+};
+
+AnimationItem.prototype.playSegments = function (arr, forceFlag) {
+  if (forceFlag) {
+    this.segments.length = 0;
+  }
+  if (typeof arr[0] === 'object') {
+    var i;
+    var len = arr.length;
+    for (i = 0; i < len; i += 1) {
+      this.segments.push(arr[i]);
+    }
+  } else {
+    this.segments.push(arr);
+  }
+  if (this.segments.length && forceFlag) {
+    this.adjustSegment(this.segments.shift(), 0);
+  }
+  if (this.isPaused) {
+    this.play();
+  }
+};
+
+AnimationItem.prototype.resetSegments = function (forceFlag) {
+  this.segments.length = 0;
+  this.segments.push([this.animationData.ip, this.animationData.op]);
+  if (forceFlag) {
+    this.checkSegments(0);
+  }
+};
+AnimationItem.prototype.checkSegments = function (offset) {
+  if (this.segments.length) {
+    this.adjustSegment(this.segments.shift(), offset);
+    return true;
+  }
+  return false;
+};
+
+AnimationItem.prototype.destroy = function (name) {
+  if ((name && this.name !== name) || !this.renderer) {
+    return;
+  }
+  this.renderer.destroy();
+  this.imagePreloader.destroy();
+  this.trigger('destroy');
+  this._cbs = null;
+  this.onEnterFrame = null;
+  this.onLoopComplete = null;
+  this.onComplete = null;
+  this.onSegmentStart = null;
+  this.onDestroy = null;
+  this.renderer = null;
+  this.expressionsPlugin = null;
+  this.imagePreloader = null;
+  this.projectInterface = null;
+};
+
+AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
+  this.currentRawFrame = value;
+  this.gotoFrame();
+};
+
+AnimationItem.prototype.setSpeed = function (val) {
+  this.playSpeed = val;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setDirection = function (val) {
+  this.playDirection = val < 0 ? -1 : 1;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setLoop = function (isLooping) {
+  this.loop = isLooping;
+};
+
+AnimationItem.prototype.setVolume = function (val, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.setVolume(val);
+};
+
+AnimationItem.prototype.getVolume = function () {
+  return this.audioController.getVolume();
+};
+
+AnimationItem.prototype.mute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.mute();
+};
+
+AnimationItem.prototype.unmute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.unmute();
+};
+
+AnimationItem.prototype.updaFrameModifier = function () {
+  this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
+  this.audioController.setRate(this.playSpeed * this.playDirection);
+};
+
+AnimationItem.prototype.getPath = function () {
+  return this.path;
+};
+
+AnimationItem.prototype.getAssetsPath = function (assetData) {
+  var path = '';
+  if (assetData.e) {
+    path = assetData.p;
+  } else if (this.assetsPath) {
+    var imagePath = assetData.p;
+    if (imagePath.indexOf('images/') !== -1) {
+      imagePath = imagePath.split('/')[1];
+    }
+    path = this.assetsPath + imagePath;
+  } else {
+    path = this.path;
+    path += assetData.u ? assetData.u : '';
+    path += assetData.p;
+  }
+  return path;
+};
+
+AnimationItem.prototype.getAssetData = function (id) {
+  var i = 0;
+  var len = this.assets.length;
+  while (i < len) {
+    if (id === this.assets[i].id) {
+      return this.assets[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+AnimationItem.prototype.hide = function () {
+  this.renderer.hide();
+};
+
+AnimationItem.prototype.show = function () {
+  this.renderer.show();
+};
+
+AnimationItem.prototype.getDuration = function (isFrame) {
+  return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
+};
+
+AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
+  try {
+    var element = this.renderer.getElementByPath(path);
+    element.updateDocumentData(documentData, index);
+  } catch (error) {
+    // TODO: decide how to handle catch case
+  }
+};
+
+AnimationItem.prototype.trigger = function (name) {
+  if (this._cbs && this._cbs[name]) {
+    switch (name) {
+      case 'enterFrame':
+        this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
+        break;
+      case 'drawnFrame':
+        this.drawnFrameEvent.currentTime = this.currentFrame;
+        this.drawnFrameEvent.totalTime = this.totalFrames;
+        this.drawnFrameEvent.direction = this.frameModifier;
+        this.triggerEvent(name, this.drawnFrameEvent);
+        break;
+      case 'loopComplete':
+        this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+        break;
+      case 'complete':
+        this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
+        break;
+      case 'segmentStart':
+        this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+        break;
+      case 'destroy':
+        this.triggerEvent(name, new BMDestroyEvent(name, this));
+        break;
+      default:
+        this.triggerEvent(name);
+    }
+  }
+  if (name === 'enterFrame' && this.onEnterFrame) {
+    this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
+  }
+  if (name === 'loopComplete' && this.onLoopComplete) {
+    this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+  }
+  if (name === 'complete' && this.onComplete) {
+    this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
+  }
+  if (name === 'segmentStart' && this.onSegmentStart) {
+    this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+  }
+  if (name === 'destroy' && this.onDestroy) {
+    this.onDestroy.call(this, new BMDestroyEvent(name, this));
+  }
+};
+
+AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
+  var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+AnimationItem.prototype.triggerConfigError = function (nativeError) {
+  var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+const animationManager = (function () {
+  var moduleOb = {};
+  var registeredAnimations = [];
+  var initTime = 0;
+  var len = 0;
+  var playingAnimationsNum = 0;
+  var _stopped = true;
+  var _isFrozen = false;
+
+  function removeElement(ev) {
+    var i = 0;
+    var animItem = ev.target;
+    while (i < len) {
+      if (registeredAnimations[i].animation === animItem) {
+        registeredAnimations.splice(i, 1);
+        i -= 1;
+        len -= 1;
+        if (!animItem.isPaused) {
+          subtractPlayingCount();
+        }
+      }
+      i += 1;
+    }
+  }
+
+  function registerAnimation(element, animationData) {
+    if (!element) {
+      return null;
+    }
+    var i = 0;
+    while (i < len) {
+      if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
+        return registeredAnimations[i].animation;
+      }
+      i += 1;
+    }
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, element);
+    animItem.setData(element, animationData);
+    return animItem;
+  }
+
+  function getRegisteredAnimations() {
+    var i;
+    var lenAnims = registeredAnimations.length;
+    var animations = [];
+    for (i = 0; i < lenAnims; i += 1) {
+      animations.push(registeredAnimations[i].animation);
+    }
+    return animations;
+  }
+
+  function addPlayingCount() {
+    playingAnimationsNum += 1;
+    activate();
+  }
+
+  function subtractPlayingCount() {
+    playingAnimationsNum -= 1;
+  }
+
+  function setupAnimation(animItem, element) {
+    animItem.addEventListener('destroy', removeElement);
+    animItem.addEventListener('_active', addPlayingCount);
+    animItem.addEventListener('_idle', subtractPlayingCount);
+    registeredAnimations.push({ elem: element, animation: animItem });
+    len += 1;
+  }
+
+  function loadAnimation(params) {
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, null);
+    animItem.setParams(params);
+    return animItem;
+  }
+
+  function setSpeed(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setSpeed(val, animation);
+    }
+  }
+
+  function setDirection(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setDirection(val, animation);
+    }
+  }
+
+  function play(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.play(animation);
+    }
+  }
+  function resume(nowTime) {
+    var elapsedTime = nowTime - initTime;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.advanceTime(elapsedTime);
+    }
+    initTime = nowTime;
+    if (playingAnimationsNum && !_isFrozen) {
+      window.requestAnimationFrame(resume);
+    } else {
+      _stopped = true;
+    }
+  }
+
+  function first(nowTime) {
+    initTime = nowTime;
+    window.requestAnimationFrame(resume);
+  }
+
+  function pause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.pause(animation);
+    }
+  }
+
+  function goToAndStop(value, isFrame, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
+    }
+  }
+
+  function stop(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.stop(animation);
+    }
+  }
+
+  function togglePause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.togglePause(animation);
+    }
+  }
+
+  function destroy(animation) {
+    var i;
+    for (i = (len - 1); i >= 0; i -= 1) {
+      registeredAnimations[i].animation.destroy(animation);
+    }
+  }
+
+  function searchAnimations(animationData, standalone, renderer) {
+    var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')),
+      [].slice.call(document.getElementsByClassName('bodymovin')));
+    var i;
+    var lenAnims = animElements.length;
+    for (i = 0; i < lenAnims; i += 1) {
+      if (renderer) {
+        animElements[i].setAttribute('data-bm-type', renderer);
+      }
+      registerAnimation(animElements[i], animationData);
+    }
+    if (standalone && lenAnims === 0) {
+      if (!renderer) {
+        renderer = 'svg';
+      }
+      var body = document.getElementsByTagName('body')[0];
+      body.innerText = '';
+      var div = createTag('div');
+      div.style.width = '100%';
+      div.style.height = '100%';
+      div.setAttribute('data-bm-type', renderer);
+      body.appendChild(div);
+      registerAnimation(div, animationData);
+    }
+  }
+
+  function resize() {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.resize();
+    }
+  }
+
+  function activate() {
+    if (!_isFrozen && playingAnimationsNum) {
+      if (_stopped) {
+        window.requestAnimationFrame(first);
+        _stopped = false;
+      }
+    }
+  }
+
+  function freeze() {
+    _isFrozen = true;
+  }
+
+  function unfreeze() {
+    _isFrozen = false;
+    activate();
+  }
+
+  function setVolume(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setVolume(val, animation);
+    }
+  }
+
+  function mute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.mute(animation);
+    }
+  }
+
+  function unmute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.unmute(animation);
+    }
+  }
+
+  moduleOb.registerAnimation = registerAnimation;
+  moduleOb.loadAnimation = loadAnimation;
+  moduleOb.setSpeed = setSpeed;
+  moduleOb.setDirection = setDirection;
+  moduleOb.play = play;
+  moduleOb.pause = pause;
+  moduleOb.stop = stop;
+  moduleOb.togglePause = togglePause;
+  moduleOb.searchAnimations = searchAnimations;
+  moduleOb.resize = resize;
+  // moduleOb.start = start;
+  moduleOb.goToAndStop = goToAndStop;
+  moduleOb.destroy = destroy;
+  moduleOb.freeze = freeze;
+  moduleOb.unfreeze = unfreeze;
+  moduleOb.setVolume = setVolume;
+  moduleOb.mute = mute;
+  moduleOb.unmute = unmute;
+  moduleOb.getRegisteredAnimations = getRegisteredAnimations;
+  return moduleOb;
+}());
+
+/* eslint-disable */
+const BezierFactory = (function () {
+  /**
+     * BezierEasing - use bezier curve for transition easing function
+     * by Gaëtan Renaudeau 2014 - 2015 – MIT License
+     *
+     * Credits: is based on Firefox's nsSMILKeySpline.cpp
+     * Usage:
+     * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
+     * spline.get(x) => returns the easing value | x must be in [0, 1] range
+     *
+     */
+
+  var ob = {};
+  ob.getBezierEasing = getBezierEasing;
+  var beziers = {};
+
+  function getBezierEasing(a, b, c, d, nm) {
+    var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
+    if (beziers[str]) {
+      return beziers[str];
+    }
+    var bezEasing = new BezierEasing([a, b, c, d]);
+    beziers[str] = bezEasing;
+    return bezEasing;
+  }
+
+  // These values are established by empiricism with tests (tradeoff: performance VS precision)
+  var NEWTON_ITERATIONS = 4;
+  var NEWTON_MIN_SLOPE = 0.001;
+  var SUBDIVISION_PRECISION = 0.0000001;
+  var SUBDIVISION_MAX_ITERATIONS = 10;
+
+  var kSplineTableSize = 11;
+  var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
+
+  var float32ArraySupported = typeof Float32Array === 'function';
+
+  function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
+  function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
+  function C(aA1) { return 3.0 * aA1; }
+
+  // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+  function calcBezier(aT, aA1, aA2) {
+    return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
+  }
+
+  // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+  function getSlope(aT, aA1, aA2) {
+    return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
+  }
+
+  function binarySubdivide(aX, aA, aB, mX1, mX2) {
+    var currentX,
+      currentT,
+      i = 0;
+    do {
+      currentT = aA + (aB - aA) / 2.0;
+      currentX = calcBezier(currentT, mX1, mX2) - aX;
+      if (currentX > 0.0) {
+        aB = currentT;
+      } else {
+        aA = currentT;
+      }
+    } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
+    return currentT;
+  }
+
+  function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
+    for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
+      var currentSlope = getSlope(aGuessT, mX1, mX2);
+      if (currentSlope === 0.0) return aGuessT;
+      var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
+      aGuessT -= currentX / currentSlope;
+    }
+    return aGuessT;
+  }
+
+  /**
+     * points is an array of [ mX1, mY1, mX2, mY2 ]
+     */
+  function BezierEasing(points) {
+    this._p = points;
+    this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
+    this._precomputed = false;
+
+    this.get = this.get.bind(this);
+  }
+
+  BezierEasing.prototype = {
+
+    get: function (x) {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      if (!this._precomputed) this._precompute();
+      if (mX1 === mY1 && mX2 === mY2) return x; // linear
+      // Because JavaScript number are imprecise, we should guarantee the extremes are right.
+      if (x === 0) return 0;
+      if (x === 1) return 1;
+      return calcBezier(this._getTForX(x), mY1, mY2);
+    },
+
+    // Private part
+
+    _precompute: function () {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      this._precomputed = true;
+      if (mX1 !== mY1 || mX2 !== mY2) { this._calcSampleValues(); }
+    },
+
+    _calcSampleValues: function () {
+      var mX1 = this._p[0],
+        mX2 = this._p[2];
+      for (var i = 0; i < kSplineTableSize; ++i) {
+        this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
+      }
+    },
+
+    /**
+         * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
+         */
+    _getTForX: function (aX) {
+      var mX1 = this._p[0],
+        mX2 = this._p[2],
+        mSampleValues = this._mSampleValues;
+
+      var intervalStart = 0.0;
+      var currentSample = 1;
+      var lastSample = kSplineTableSize - 1;
+
+      for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
+        intervalStart += kSampleStepSize;
+      }
+      --currentSample;
+
+      // Interpolate to provide an initial guess for t
+      var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
+      var guessForT = intervalStart + dist * kSampleStepSize;
+
+      var initialSlope = getSlope(guessForT, mX1, mX2);
+      if (initialSlope >= NEWTON_MIN_SLOPE) {
+        return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
+      } if (initialSlope === 0.0) {
+        return guessForT;
+      }
+      return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
+    },
+  };
+
+  return ob;
+}());
+
+const pooling = (function () {
+  function double(arr) {
+    return arr.concat(createSizedArray(arr.length));
+  }
+
+  return {
+    double: double,
+  };
+}());
+
+const poolFactory = (function () {
+  return function (initialLength, _create, _release) {
+    var _length = 0;
+    var _maxLength = initialLength;
+    var pool = createSizedArray(_maxLength);
+
+    var ob = {
+      newElement: newElement,
+      release: release,
+    };
+
+    function newElement() {
+      var element;
+      if (_length) {
+        _length -= 1;
+        element = pool[_length];
+      } else {
+        element = _create();
+      }
+      return element;
+    }
+
+    function release(element) {
+      if (_length === _maxLength) {
+        pool = pooling.double(pool);
+        _maxLength *= 2;
+      }
+      if (_release) {
+        _release(element);
+      }
+      pool[_length] = element;
+      _length += 1;
+    }
+
+    return ob;
+  };
+}());
+
+const bezierLengthPool = (function () {
+  function create() {
+    return {
+      addedLength: 0,
+      percents: createTypedArray('float32', getDefaultCurveSegments()),
+      lengths: createTypedArray('float32', getDefaultCurveSegments()),
+    };
+  }
+  return poolFactory(8, create);
+}());
+
+const segmentsLengthPool = (function () {
+  function create() {
+    return {
+      lengths: [],
+      totalLength: 0,
+    };
+  }
+
+  function release(element) {
+    var i;
+    var len = element.lengths.length;
+    for (i = 0; i < len; i += 1) {
+      bezierLengthPool.release(element.lengths[i]);
+    }
+    element.lengths.length = 0;
+  }
+
+  return poolFactory(8, create, release);
+}());
+
+function bezFunction() {
+  var math = Math;
+
+  function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
+    var det1 = (x1 * y2) + (y1 * x3) + (x2 * y3) - (x3 * y2) - (y3 * x1) - (x2 * y1);
+    return det1 > -0.001 && det1 < 0.001;
+  }
+
+  function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
+    if (z1 === 0 && z2 === 0 && z3 === 0) {
+      return pointOnLine2D(x1, y1, x2, y2, x3, y3);
+    }
+    var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
+    var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
+    var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
+    var diffDist;
+    if (dist1 > dist2) {
+      if (dist1 > dist3) {
+        diffDist = dist1 - dist2 - dist3;
+      } else {
+        diffDist = dist3 - dist2 - dist1;
+      }
+    } else if (dist3 > dist2) {
+      diffDist = dist3 - dist2 - dist1;
+    } else {
+      diffDist = dist2 - dist1 - dist3;
+    }
+    return diffDist > -0.0001 && diffDist < 0.0001;
+  }
+
+  var getBezierLength = (function () {
+    return function (pt1, pt2, pt3, pt4) {
+      var curveSegments = getDefaultCurveSegments();
+      var k;
+      var i;
+      var len;
+      var ptCoord;
+      var perc;
+      var addedLength = 0;
+      var ptDistance;
+      var point = [];
+      var lastPoint = [];
+      var lengthData = bezierLengthPool.newElement();
+      len = pt3.length;
+      for (k = 0; k < curveSegments; k += 1) {
+        perc = k / (curveSegments - 1);
+        ptDistance = 0;
+        for (i = 0; i < len; i += 1) {
+          ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
+          point[i] = ptCoord;
+          if (lastPoint[i] !== null) {
+            ptDistance += bmPow(point[i] - lastPoint[i], 2);
+          }
+          lastPoint[i] = point[i];
+        }
+        if (ptDistance) {
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+        }
+        lengthData.percents[k] = perc;
+        lengthData.lengths[k] = addedLength;
+      }
+      lengthData.addedLength = addedLength;
+      return lengthData;
+    };
+  }());
+
+  function getSegmentsLength(shapeData) {
+    var segmentsLength = segmentsLengthPool.newElement();
+    var closed = shapeData.c;
+    var pathV = shapeData.v;
+    var pathO = shapeData.o;
+    var pathI = shapeData.i;
+    var i;
+    var len = shapeData._length;
+    var lengths = segmentsLength.lengths;
+    var totalLength = 0;
+    for (i = 0; i < len - 1; i += 1) {
+      lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
+      totalLength += lengths[i].addedLength;
+    }
+    if (closed && len) {
+      lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
+      totalLength += lengths[i].addedLength;
+    }
+    segmentsLength.totalLength = totalLength;
+    return segmentsLength;
+  }
+
+  function BezierData(length) {
+    this.segmentLength = 0;
+    this.points = new Array(length);
+  }
+
+  function PointData(partial, point) {
+    this.partialLength = partial;
+    this.point = point;
+  }
+
+  var buildBezierData = (function () {
+    var storedData = {};
+
+    return function (pt1, pt2, pt3, pt4) {
+      var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
+      if (!storedData[bezierName]) {
+        var curveSegments = getDefaultCurveSegments();
+        var k;
+        var i;
+        var len;
+        var ptCoord;
+        var perc;
+        var addedLength = 0;
+        var ptDistance;
+        var point;
+        var lastPoint = null;
+        if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
+          curveSegments = 2;
+        }
+        var bezierData = new BezierData(curveSegments);
+        len = pt3.length;
+        for (k = 0; k < curveSegments; k += 1) {
+          point = createSizedArray(len);
+          perc = k / (curveSegments - 1);
+          ptDistance = 0;
+          for (i = 0; i < len; i += 1) {
+            ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
+            point[i] = ptCoord;
+            if (lastPoint !== null) {
+              ptDistance += bmPow(point[i] - lastPoint[i], 2);
+            }
+          }
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+          bezierData.points[k] = new PointData(ptDistance, point);
+          lastPoint = point;
+        }
+        bezierData.segmentLength = addedLength;
+        storedData[bezierName] = bezierData;
+      }
+      return storedData[bezierName];
+    };
+  }());
+
+  function getDistancePerc(perc, bezierData) {
+    var percents = bezierData.percents;
+    var lengths = bezierData.lengths;
+    var len = percents.length;
+    var initPos = bmFloor((len - 1) * perc);
+    var lengthPos = perc * bezierData.addedLength;
+    var lPerc = 0;
+    if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
+      return percents[initPos];
+    }
+    var dir = lengths[initPos] > lengthPos ? -1 : 1;
+    var flag = true;
+    while (flag) {
+      if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
+        lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
+        flag = false;
+      } else {
+        initPos += dir;
+      }
+      if (initPos < 0 || initPos >= len - 1) {
+        // FIX for TypedArrays that don't store floating point values with enough accuracy
+        if (initPos === len - 1) {
+          return percents[initPos];
+        }
+        flag = false;
+      }
+    }
+    return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
+  }
+
+  function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
+    var t1 = getDistancePerc(percent, bezierData);
+    var u1 = 1 - t1;
+    var ptX = math.round((u1 * u1 * u1 * pt1[0] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[0] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[0] + t1 * t1 * t1 * pt2[0]) * 1000) / 1000;
+    var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
+    return [ptX, ptY];
+  }
+
+  var bezierSegmentPoints = createTypedArray('float32', 8);
+
+  function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
+    if (startPerc < 0) {
+      startPerc = 0;
+    } else if (startPerc > 1) {
+      startPerc = 1;
+    }
+    var t0 = getDistancePerc(startPerc, bezierData);
+    endPerc = endPerc > 1 ? 1 : endPerc;
+    var t1 = getDistancePerc(endPerc, bezierData);
+    var i;
+    var len = pt1.length;
+    var u0 = 1 - t0;
+    var u1 = 1 - t1;
+    var u0u0u0 = u0 * u0 * u0;
+    var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0t0 = t0 * t0 * t0;
+    //
+    var u0u0u1 = u0 * u0 * u1;
+    var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0t1 = t0 * t0 * t1;
+    //
+    var u0u1u1 = u0 * u1 * u1;
+    var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1t1 = t0 * t1 * t1;
+    //
+    var u1u1u1 = u1 * u1 * u1;
+    var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1t1 = t1 * t1 * t1;
+    for (i = 0; i < len; i += 1) {
+      bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+    }
+
+    return bezierSegmentPoints;
+  }
+
+  return {
+    getSegmentsLength: getSegmentsLength,
+    getNewSegment: getNewSegment,
+    getPointInSegment: getPointInSegment,
+    buildBezierData: buildBezierData,
+    pointOnLine2D: pointOnLine2D,
+    pointOnLine3D: pointOnLine3D,
+  };
+}
+
+const bez = bezFunction();
+
+var initFrame = initialDefaultFrame;
+var mathAbs = Math.abs;
+
+function interpolateValue(frameNum, caching) {
+  var offsetTime = this.offsetTime;
+  var newValue;
+  if (this.propType === 'multidimensional') {
+    newValue = createTypedArray('float32', this.pv.length);
+  }
+  var iterationIndex = caching.lastIndex;
+  var i = iterationIndex;
+  var len = this.keyframes.length - 1;
+  var flag = true;
+  var keyData;
+  var nextKeyData;
+  var keyframeMetadata;
+
+  while (flag) {
+    keyData = this.keyframes[i];
+    nextKeyData = this.keyframes[i + 1];
+    if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
+      if (keyData.h) {
+        keyData = nextKeyData;
+      }
+      iterationIndex = 0;
+      break;
+    }
+    if ((nextKeyData.t - offsetTime) > frameNum) {
+      iterationIndex = i;
+      break;
+    }
+    if (i < len - 1) {
+      i += 1;
+    } else {
+      iterationIndex = 0;
+      flag = false;
+    }
+  }
+  keyframeMetadata = this.keyframesMetadata[i] || {};
+
+  var k;
+  var kLen;
+  var perc;
+  var jLen;
+  var j;
+  var fnc;
+  var nextKeyTime = nextKeyData.t - offsetTime;
+  var keyTime = keyData.t - offsetTime;
+  var endValue;
+  if (keyData.to) {
+    if (!keyframeMetadata.bezierData) {
+      keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
+    }
+    var bezierData = keyframeMetadata.bezierData;
+    if (frameNum >= nextKeyTime || frameNum < keyTime) {
+      var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
+      kLen = bezierData.points[ind].point.length;
+      for (k = 0; k < kLen; k += 1) {
+        newValue[k] = bezierData.points[ind].point[k];
+      }
+      // caching._lastKeyframeIndex = -1;
+    } else {
+      if (keyframeMetadata.__fnct) {
+        fnc = keyframeMetadata.__fnct;
+      } else {
+        fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
+        keyframeMetadata.__fnct = fnc;
+      }
+      perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+      var distanceInLine = bezierData.segmentLength * perc;
+
+      var segmentPerc;
+      var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0;
+      j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0;
+      flag = true;
+      jLen = bezierData.points.length;
+      while (flag) {
+        addedLength += bezierData.points[j].partialLength;
+        if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k];
+          }
+          break;
+        } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
+          segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
+          }
+          break;
+        }
+        if (j < jLen - 1) {
+          j += 1;
+        } else {
+          flag = false;
+        }
+      }
+      caching._lastPoint = j;
+      caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
+      caching._lastKeyframeIndex = i;
+    }
+  } else {
+    var outX;
+    var outY;
+    var inX;
+    var inY;
+    var keyValue;
+    len = keyData.s.length;
+    endValue = nextKeyData.s || keyData.e;
+    if (this.sh && keyData.h !== 1) {
+      if (frameNum >= nextKeyTime) {
+        newValue[0] = endValue[0];
+        newValue[1] = endValue[1];
+        newValue[2] = endValue[2];
+      } else if (frameNum <= keyTime) {
+        newValue[0] = keyData.s[0];
+        newValue[1] = keyData.s[1];
+        newValue[2] = keyData.s[2];
+      } else {
+        var quatStart = createQuaternion(keyData.s);
+        var quatEnd = createQuaternion(endValue);
+        var time = (frameNum - keyTime) / (nextKeyTime - keyTime);
+        quaternionToEuler(newValue, slerp(quatStart, quatEnd, time));
+      }
+    } else {
+      for (i = 0; i < len; i += 1) {
+        if (keyData.h !== 1) {
+          if (frameNum >= nextKeyTime) {
+            perc = 1;
+          } else if (frameNum < keyTime) {
+            perc = 0;
+          } else {
+            if (keyData.o.x.constructor === Array) {
+              if (!keyframeMetadata.__fnct) {
+                keyframeMetadata.__fnct = [];
+              }
+              if (!keyframeMetadata.__fnct[i]) {
+                outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
+                outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
+                inX = keyData.i.x[i] === undefined ? keyData.i.x[0] : keyData.i.x[i];
+                inY = keyData.i.y[i] === undefined ? keyData.i.y[0] : keyData.i.y[i];
+                fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+                keyframeMetadata.__fnct[i] = fnc;
+              } else {
+                fnc = keyframeMetadata.__fnct[i];
+              }
+            } else if (!keyframeMetadata.__fnct) {
+              outX = keyData.o.x;
+              outY = keyData.o.y;
+              inX = keyData.i.x;
+              inY = keyData.i.y;
+              fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+              keyData.keyframeMetadata = fnc;
+            } else {
+              fnc = keyframeMetadata.__fnct;
+            }
+            perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+          }
+        }
+
+        endValue = nextKeyData.s || keyData.e;
+        keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
+
+        if (this.propType === 'multidimensional') {
+          newValue[i] = keyValue;
+        } else {
+          newValue = keyValue;
+        }
+      }
+    }
+  }
+  caching.lastIndex = iterationIndex;
+  return newValue;
+}
+
+// based on @Toji's https://github.com/toji/gl-matrix/
+function slerp(a, b, t) {
+  var out = [];
+  var ax = a[0];
+  var ay = a[1];
+  var az = a[2];
+  var aw = a[3];
+  var bx = b[0];
+  var by = b[1];
+  var bz = b[2];
+  var bw = b[3];
+
+  var omega;
+  var cosom;
+  var sinom;
+  var scale0;
+  var scale1;
+
+  cosom = ax * bx + ay * by + az * bz + aw * bw;
+  if (cosom < 0.0) {
+    cosom = -cosom;
+    bx = -bx;
+    by = -by;
+    bz = -bz;
+    bw = -bw;
+  }
+  if ((1.0 - cosom) > 0.000001) {
+    omega = Math.acos(cosom);
+    sinom = Math.sin(omega);
+    scale0 = Math.sin((1.0 - t) * omega) / sinom;
+    scale1 = Math.sin(t * omega) / sinom;
+  } else {
+    scale0 = 1.0 - t;
+    scale1 = t;
+  }
+  out[0] = scale0 * ax + scale1 * bx;
+  out[1] = scale0 * ay + scale1 * by;
+  out[2] = scale0 * az + scale1 * bz;
+  out[3] = scale0 * aw + scale1 * bw;
+
+  return out;
+}
+
+function quaternionToEuler(out, quat) {
+  var qx = quat[0];
+  var qy = quat[1];
+  var qz = quat[2];
+  var qw = quat[3];
+  var heading = Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy * qy - 2 * qz * qz);
+  var attitude = Math.asin(2 * qx * qy + 2 * qz * qw);
+  var bank = Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx * qx - 2 * qz * qz);
+  out[0] = heading / degToRads;
+  out[1] = attitude / degToRads;
+  out[2] = bank / degToRads;
+}
+
+function createQuaternion(values) {
+  var heading = values[0] * degToRads;
+  var attitude = values[1] * degToRads;
+  var bank = values[2] * degToRads;
+  var c1 = Math.cos(heading / 2);
+  var c2 = Math.cos(attitude / 2);
+  var c3 = Math.cos(bank / 2);
+  var s1 = Math.sin(heading / 2);
+  var s2 = Math.sin(attitude / 2);
+  var s3 = Math.sin(bank / 2);
+  var w = c1 * c2 * c3 - s1 * s2 * s3;
+  var x = s1 * s2 * c3 + c1 * c2 * s3;
+  var y = s1 * c2 * c3 + c1 * s2 * s3;
+  var z = c1 * s2 * c3 - s1 * c2 * s3;
+
+  return [x, y, z, w];
+}
+
+function getValueAtCurrentTime() {
+  var frameNum = this.comp.renderedFrame - this.offsetTime;
+  var initTime = this.keyframes[0].t - this.offsetTime;
+  var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+  if (!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))) {
+    if (this._caching.lastFrame >= frameNum) {
+      this._caching._lastKeyframeIndex = -1;
+      this._caching.lastIndex = 0;
+    }
+
+    var renderResult = this.interpolateValue(frameNum, this._caching);
+    this.pv = renderResult;
+  }
+  this._caching.lastFrame = frameNum;
+  return this.pv;
+}
+
+function setVValue(val) {
+  var multipliedValue;
+  if (this.propType === 'unidimensional') {
+    multipliedValue = val * this.mult;
+    if (mathAbs(this.v - multipliedValue) > 0.00001) {
+      this.v = multipliedValue;
+      this._mdf = true;
+    }
+  } else {
+    var i = 0;
+    var len = this.v.length;
+    while (i < len) {
+      multipliedValue = val[i] * this.mult;
+      if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
+        this.v[i] = multipliedValue;
+        this._mdf = true;
+      }
+      i += 1;
+    }
+  }
+}
+
+function processEffectsSequence() {
+  if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
+    return;
+  }
+  if (this.lock) {
+    this.setVValue(this.pv);
+    return;
+  }
+  this.lock = true;
+  this._mdf = this._isFirstFrame;
+  var i;
+  var len = this.effectsSequence.length;
+  var finalValue = this.kf ? this.pv : this.data.k;
+  for (i = 0; i < len; i += 1) {
+    finalValue = this.effectsSequence[i](finalValue);
+  }
+  this.setVValue(finalValue);
+  this._isFirstFrame = false;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+}
+
+function addEffect(effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.container.addDynamicProperty(this);
+}
+
+function ValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this.v = mult ? data.k * mult : data.k;
+  this.pv = data.k;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.vel = 0;
+  this.effectsSequence = [];
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function MultiDimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.frameId = -1;
+  var i;
+  var len = data.k.length;
+  this.v = createTypedArray('float32', len);
+  this.pv = createTypedArray('float32', len);
+  this.vel = createTypedArray('float32', len);
+  for (i = 0; i < len; i += 1) {
+    this.v[i] = data.k[i] * this.mult;
+    this.pv[i] = data.k[i];
+  }
+  this._isFirstFrame = true;
+  this.effectsSequence = [];
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function KeyframedValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.frameId = -1;
+  this._caching = {
+    lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1,
+  };
+  this.k = true;
+  this.kf = true;
+  this.data = data;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.v = initFrame;
+  this.pv = initFrame;
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.addEffect = addEffect;
+}
+
+function KeyframedMultidimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  var i;
+  var len = data.k.length;
+  var s;
+  var e;
+  var to;
+  var ti;
+  for (i = 0; i < len - 1; i += 1) {
+    if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
+      s = data.k[i].s;
+      e = data.k[i + 1].s;
+      to = data.k[i].to;
+      ti = data.k[i].ti;
+      if ((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2]))) {
+        data.k[i].to = null;
+        data.k[i].ti = null;
+      }
+      if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
+        if (s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) {
+          data.k[i].to = null;
+          data.k[i].ti = null;
+        }
+      }
+    }
+  }
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.data = data;
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.k = true;
+  this.kf = true;
+  this._isFirstFrame = true;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.frameId = -1;
+  var arrLen = data.k[0].s.length;
+  this.v = createTypedArray('float32', arrLen);
+  this.pv = createTypedArray('float32', arrLen);
+  for (i = 0; i < arrLen; i += 1) {
+    this.v[i] = initFrame;
+    this.pv[i] = initFrame;
+  }
+  this._caching = { lastFrame: initFrame, lastIndex: 0, value: createTypedArray('float32', arrLen) };
+  this.addEffect = addEffect;
+}
+
+const PropertyFactory = (function () {
+  function getProp(elem, data, type, mult, container) {
+    if (data.sid) {
+      data = elem.globalData.slotManager.getProp(data);
+    }
+    var p;
+    if (!data.k.length) {
+      p = new ValueProperty(elem, data, mult, container);
+    } else if (typeof (data.k[0]) === 'number') {
+      p = new MultiDimensionalProperty(elem, data, mult, container);
+    } else {
+      switch (type) {
+        case 0:
+          p = new KeyframedValueProperty(elem, data, mult, container);
+          break;
+        case 1:
+          p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
+          break;
+        default:
+          break;
+      }
+    }
+    if (p.effectsSequence.length) {
+      container.addDynamicProperty(p);
+    }
+    return p;
+  }
+
+  var ob = {
+    getProp: getProp,
+  };
+  return ob;
+}());
+
+function DynamicPropertyContainer() {}
+DynamicPropertyContainer.prototype = {
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+      this.container.addDynamicProperty(this);
+      this._isAnimated = true;
+    }
+  },
+  iterateDynamicProperties: function () {
+    this._mdf = false;
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      this.dynamicProperties[i].getValue();
+      if (this.dynamicProperties[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  },
+  initDynamicPropertyContainer: function (container) {
+    this.container = container;
+    this.dynamicProperties = [];
+    this._mdf = false;
+    this._isAnimated = false;
+  },
+};
+
+const pointPool = (function () {
+  function create() {
+    return createTypedArray('float32', 2);
+  }
+  return poolFactory(8, create);
+}());
+
+function ShapePath() {
+  this.c = false;
+  this._length = 0;
+  this._maxLength = 8;
+  this.v = createSizedArray(this._maxLength);
+  this.o = createSizedArray(this._maxLength);
+  this.i = createSizedArray(this._maxLength);
+}
+
+ShapePath.prototype.setPathData = function (closed, len) {
+  this.c = closed;
+  this.setLength(len);
+  var i = 0;
+  while (i < len) {
+    this.v[i] = pointPool.newElement();
+    this.o[i] = pointPool.newElement();
+    this.i[i] = pointPool.newElement();
+    i += 1;
+  }
+};
+
+ShapePath.prototype.setLength = function (len) {
+  while (this._maxLength < len) {
+    this.doubleArrayLength();
+  }
+  this._length = len;
+};
+
+ShapePath.prototype.doubleArrayLength = function () {
+  this.v = this.v.concat(createSizedArray(this._maxLength));
+  this.i = this.i.concat(createSizedArray(this._maxLength));
+  this.o = this.o.concat(createSizedArray(this._maxLength));
+  this._maxLength *= 2;
+};
+
+ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
+  var arr;
+  this._length = Math.max(this._length, pos + 1);
+  if (this._length >= this._maxLength) {
+    this.doubleArrayLength();
+  }
+  switch (type) {
+    case 'v':
+      arr = this.v;
+      break;
+    case 'i':
+      arr = this.i;
+      break;
+    case 'o':
+      arr = this.o;
+      break;
+    default:
+      arr = [];
+      break;
+  }
+  if (!arr[pos] || (arr[pos] && !replace)) {
+    arr[pos] = pointPool.newElement();
+  }
+  arr[pos][0] = x;
+  arr[pos][1] = y;
+};
+
+ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
+  this.setXYAt(vX, vY, 'v', pos, replace);
+  this.setXYAt(oX, oY, 'o', pos, replace);
+  this.setXYAt(iX, iY, 'i', pos, replace);
+};
+
+ShapePath.prototype.reverse = function () {
+  var newPath = new ShapePath();
+  newPath.setPathData(this.c, this._length);
+  var vertices = this.v;
+  var outPoints = this.o;
+  var inPoints = this.i;
+  var init = 0;
+  if (this.c) {
+    newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
+    init = 1;
+  }
+  var cnt = this._length - 1;
+  var len = this._length;
+
+  var i;
+  for (i = init; i < len; i += 1) {
+    newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
+    cnt -= 1;
+  }
+  return newPath;
+};
+
+ShapePath.prototype.length = function () {
+  return this._length;
+};
+
+const shapePool = (function () {
+  function create() {
+    return new ShapePath();
+  }
+
+  function release(shapePath) {
+    var len = shapePath._length;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      pointPool.release(shapePath.v[i]);
+      pointPool.release(shapePath.i[i]);
+      pointPool.release(shapePath.o[i]);
+      shapePath.v[i] = null;
+      shapePath.i[i] = null;
+      shapePath.o[i] = null;
+    }
+    shapePath._length = 0;
+    shapePath.c = false;
+  }
+
+  function clone(shape) {
+    var cloned = factory.newElement();
+    var i;
+    var len = shape._length === undefined ? shape.v.length : shape._length;
+    cloned.setLength(len);
+    cloned.c = shape.c;
+
+    for (i = 0; i < len; i += 1) {
+      cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
+    }
+    return cloned;
+  }
+
+  var factory = poolFactory(4, create, release);
+  factory.clone = clone;
+
+  return factory;
+}());
+
+function ShapeCollection() {
+  this._length = 0;
+  this._maxLength = 4;
+  this.shapes = createSizedArray(this._maxLength);
+}
+
+ShapeCollection.prototype.addShape = function (shapeData) {
+  if (this._length === this._maxLength) {
+    this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
+    this._maxLength *= 2;
+  }
+  this.shapes[this._length] = shapeData;
+  this._length += 1;
+};
+
+ShapeCollection.prototype.releaseShapes = function () {
+  var i;
+  for (i = 0; i < this._length; i += 1) {
+    shapePool.release(this.shapes[i]);
+  }
+  this._length = 0;
+};
+
+const shapeCollectionPool = (function () {
+  var ob = {
+    newShapeCollection: newShapeCollection,
+    release: release,
+  };
+
+  var _length = 0;
+  var _maxLength = 4;
+  var pool = createSizedArray(_maxLength);
+
+  function newShapeCollection() {
+    var shapeCollection;
+    if (_length) {
+      _length -= 1;
+      shapeCollection = pool[_length];
+    } else {
+      shapeCollection = new ShapeCollection();
+    }
+    return shapeCollection;
+  }
+
+  function release(shapeCollection) {
+    var i;
+    var len = shapeCollection._length;
+    for (i = 0; i < len; i += 1) {
+      shapePool.release(shapeCollection.shapes[i]);
+    }
+    shapeCollection._length = 0;
+
+    if (_length === _maxLength) {
+      pool = pooling.double(pool);
+      _maxLength *= 2;
+    }
+    pool[_length] = shapeCollection;
+    _length += 1;
+  }
+
+  return ob;
+}());
+
+const ShapePropertyFactory = (function () {
+  var initFrame = -999999;
+
+  function interpolateShape(frameNum, previousValue, caching) {
+    var iterationIndex = caching.lastIndex;
+    var keyPropS;
+    var keyPropE;
+    var isHold;
+    var j;
+    var k;
+    var jLen;
+    var kLen;
+    var perc;
+    var vertexValue;
+    var kf = this.keyframes;
+    if (frameNum < kf[0].t - this.offsetTime) {
+      keyPropS = kf[0].s[0];
+      isHold = true;
+      iterationIndex = 0;
+    } else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) {
+      keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
+      /* if(kf[kf.length - 1].s){
+                keyPropS = kf[kf.length - 1].s[0];
+            }else{
+                keyPropS = kf[kf.length - 2].e[0];
+            } */
+      isHold = true;
+    } else {
+      var i = iterationIndex;
+      var len = kf.length - 1;
+      var flag = true;
+      var keyData;
+      var nextKeyData;
+      var keyframeMetadata;
+      while (flag) {
+        keyData = kf[i];
+        nextKeyData = kf[i + 1];
+        if ((nextKeyData.t - this.offsetTime) > frameNum) {
+          break;
+        }
+        if (i < len - 1) {
+          i += 1;
+        } else {
+          flag = false;
+        }
+      }
+      keyframeMetadata = this.keyframesMetadata[i] || {};
+      isHold = keyData.h === 1;
+      iterationIndex = i;
+      if (!isHold) {
+        if (frameNum >= nextKeyData.t - this.offsetTime) {
+          perc = 1;
+        } else if (frameNum < keyData.t - this.offsetTime) {
+          perc = 0;
+        } else {
+          var fnc;
+          if (keyframeMetadata.__fnct) {
+            fnc = keyframeMetadata.__fnct;
+          } else {
+            fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
+            keyframeMetadata.__fnct = fnc;
+          }
+          perc = fnc((frameNum - (keyData.t - this.offsetTime)) / ((nextKeyData.t - this.offsetTime) - (keyData.t - this.offsetTime)));
+        }
+        keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
+      }
+      keyPropS = keyData.s[0];
+    }
+    jLen = previousValue._length;
+    kLen = keyPropS.i[0].length;
+    caching.lastIndex = iterationIndex;
+
+    for (j = 0; j < jLen; j += 1) {
+      for (k = 0; k < kLen; k += 1) {
+        vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
+        previousValue.i[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc;
+        previousValue.o[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc;
+        previousValue.v[j][k] = vertexValue;
+      }
+    }
+  }
+
+  function interpolateShapeCurrentTime() {
+    var frameNum = this.comp.renderedFrame - this.offsetTime;
+    var initTime = this.keyframes[0].t - this.offsetTime;
+    var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+    var lastFrame = this._caching.lastFrame;
+    if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) {
+      /// /
+      this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
+      this.interpolateShape(frameNum, this.pv, this._caching);
+      /// /
+    }
+    this._caching.lastFrame = frameNum;
+    return this.pv;
+  }
+
+  function resetShape() {
+    this.paths = this.localShapeCollection;
+  }
+
+  function shapesEqual(shape1, shape2) {
+    if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
+      return false;
+    }
+    var i;
+    var len = shape1._length;
+    for (i = 0; i < len; i += 1) {
+      if (shape1.v[i][0] !== shape2.v[i][0]
+            || shape1.v[i][1] !== shape2.v[i][1]
+            || shape1.o[i][0] !== shape2.o[i][0]
+            || shape1.o[i][1] !== shape2.o[i][1]
+            || shape1.i[i][0] !== shape2.i[i][0]
+            || shape1.i[i][1] !== shape2.i[i][1]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  function setVValue(newPath) {
+    if (!shapesEqual(this.v, newPath)) {
+      this.v = shapePool.clone(newPath);
+      this.localShapeCollection.releaseShapes();
+      this.localShapeCollection.addShape(this.v);
+      this._mdf = true;
+      this.paths = this.localShapeCollection;
+    }
+  }
+
+  function processEffectsSequence() {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    } if (!this.effectsSequence.length) {
+      this._mdf = false;
+      return;
+    }
+    if (this.lock) {
+      this.setVValue(this.pv);
+      return;
+    }
+    this.lock = true;
+    this._mdf = false;
+    var finalValue;
+    if (this.kf) {
+      finalValue = this.pv;
+    } else if (this.data.ks) {
+      finalValue = this.data.ks.k;
+    } else {
+      finalValue = this.data.pt.k;
+    }
+    var i;
+    var len = this.effectsSequence.length;
+    for (i = 0; i < len; i += 1) {
+      finalValue = this.effectsSequence[i](finalValue);
+    }
+    this.setVValue(finalValue);
+    this.lock = false;
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function ShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.container = elem;
+    this.elem = elem;
+    this.data = data;
+    this.k = false;
+    this.kf = false;
+    this._mdf = false;
+    var pathData = type === 3 ? data.pt.k : data.ks.k;
+    this.v = shapePool.clone(pathData);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.reset = resetShape;
+    this.effectsSequence = [];
+  }
+
+  function addEffect(effectFunction) {
+    this.effectsSequence.push(effectFunction);
+    this.container.addDynamicProperty(this);
+  }
+
+  ShapeProperty.prototype.interpolateShape = interpolateShape;
+  ShapeProperty.prototype.getValue = processEffectsSequence;
+  ShapeProperty.prototype.setVValue = setVValue;
+  ShapeProperty.prototype.addEffect = addEffect;
+
+  function KeyframedShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.elem = elem;
+    this.container = elem;
+    this.offsetTime = elem.data.st;
+    this.keyframes = type === 3 ? data.pt.k : data.ks.k;
+    this.keyframesMetadata = [];
+    this.k = true;
+    this.kf = true;
+    var len = this.keyframes[0].s[0].i.length;
+    this.v = shapePool.newElement();
+    this.v.setPathData(this.keyframes[0].s[0].c, len);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.lastFrame = initFrame;
+    this.reset = resetShape;
+    this._caching = { lastFrame: initFrame, lastIndex: 0 };
+    this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
+  }
+  KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
+  KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
+  KeyframedShapeProperty.prototype.setVValue = setVValue;
+  KeyframedShapeProperty.prototype.addEffect = addEffect;
+
+  var EllShapeProperty = (function () {
+    var cPoint = roundCorner;
+
+    function EllShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 4);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.paths = this.localShapeCollection;
+      this.localShapeCollection.addShape(this.v);
+      this.d = data.d;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertEllToPath();
+      }
+    }
+
+    EllShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+
+        if (this._mdf) {
+          this.convertEllToPath();
+        }
+      },
+      convertEllToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var s0 = this.s.v[0] / 2;
+        var s1 = this.s.v[1] / 2;
+        var _cw = this.d !== 3;
+        var _v = this.v;
+        _v.v[0][0] = p0;
+        _v.v[0][1] = p1 - s1;
+        _v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.v[1][1] = p1;
+        _v.v[2][0] = p0;
+        _v.v[2][1] = p1 + s1;
+        _v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.v[3][1] = p1;
+        _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.i[0][1] = p1 - s1;
+        _v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.i[1][1] = p1 - s1 * cPoint;
+        _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.i[2][1] = p1 + s1;
+        _v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.i[3][1] = p1 + s1 * cPoint;
+        _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.o[0][1] = p1 - s1;
+        _v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.o[1][1] = p1 + s1 * cPoint;
+        _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.o[2][1] = p1 + s1;
+        _v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.o[3][1] = p1 - s1 * cPoint;
+      },
+    };
+
+    extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
+
+    return EllShapePropertyFactory;
+  }());
+
+  var StarShapeProperty = (function () {
+    function StarShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 0);
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.data = data;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      if (data.sy === 1) {
+        this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
+        this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
+        this.convertToPath = this.convertStarToPath;
+      } else {
+        this.convertToPath = this.convertPolygonToPath;
+      }
+      this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
+      this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this);
+      this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertToPath();
+      }
+    }
+
+    StarShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertToPath();
+        }
+      },
+      convertStarToPath: function () {
+        var numPts = Math.floor(this.pt.v) * 2;
+        var angle = (Math.PI * 2) / numPts;
+        /* this.v.v.length = numPts;
+                this.v.i.length = numPts;
+                this.v.o.length = numPts; */
+        var longFlag = true;
+        var longRad = this.or.v;
+        var shortRad = this.ir.v;
+        var longRound = this.os.v;
+        var shortRound = this.is.v;
+        var longPerimSegment = (2 * Math.PI * longRad) / (numPts * 2);
+        var shortPerimSegment = (2 * Math.PI * shortRad) / (numPts * 2);
+        var i;
+        var rad;
+        var roundness;
+        var perimSegment;
+        var currentAng = -Math.PI / 2;
+        currentAng += this.r.v;
+        var dir = this.data.d === 3 ? -1 : 1;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          rad = longFlag ? longRad : shortRad;
+          roundness = longFlag ? longRound : shortRound;
+          perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
+          /* this.v.v[i] = [x,y];
+                    this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
+                    this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
+                    this.v._length = numPts; */
+          longFlag = !longFlag;
+          currentAng += angle * dir;
+        }
+      },
+      convertPolygonToPath: function () {
+        var numPts = Math.floor(this.pt.v);
+        var angle = (Math.PI * 2) / numPts;
+        var rad = this.or.v;
+        var roundness = this.os.v;
+        var perimSegment = (2 * Math.PI * rad) / (numPts * 4);
+        var i;
+        var currentAng = -Math.PI * 0.5;
+        var dir = this.data.d === 3 ? -1 : 1;
+        currentAng += this.r.v;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+          currentAng += angle * dir;
+        }
+        this.paths.length = 0;
+        this.paths[0] = this.v;
+      },
+
+    };
+    extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
+
+    return StarShapePropertyFactory;
+  }());
+
+  var RectShapeProperty = (function () {
+    function RectShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.c = true;
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertRectToPath();
+      }
+    }
+
+    RectShapePropertyFactory.prototype = {
+      convertRectToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var v0 = this.s.v[0] / 2;
+        var v1 = this.s.v[1] / 2;
+        var round = bmMin(v0, v1, this.r.v);
+        var cPoint = round * (1 - roundCorner);
+        this.v._length = 0;
+
+        if (this.d === 2 || this.d === 1) {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
+          this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2);
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3);
+          }
+        } else {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true);
+          }
+        }
+      },
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertRectToPath();
+        }
+      },
+      reset: resetShape,
+    };
+    extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
+
+    return RectShapePropertyFactory;
+  }());
+
+  function getShapeProp(elem, data, type) {
+    var prop;
+    if (type === 3 || type === 4) {
+      var dataProp = type === 3 ? data.pt : data.ks;
+      var keys = dataProp.k;
+      if (keys.length) {
+        prop = new KeyframedShapeProperty(elem, data, type);
+      } else {
+        prop = new ShapeProperty(elem, data, type);
+      }
+    } else if (type === 5) {
+      prop = new RectShapeProperty(elem, data);
+    } else if (type === 6) {
+      prop = new EllShapeProperty(elem, data);
+    } else if (type === 7) {
+      prop = new StarShapeProperty(elem, data);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  }
+
+  function getConstructorFunction() {
+    return ShapeProperty;
+  }
+
+  function getKeyframedConstructorFunction() {
+    return KeyframedShapeProperty;
+  }
+
+  var ob = {};
+  ob.getShapeProp = getShapeProp;
+  ob.getConstructorFunction = getConstructorFunction;
+  ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction;
+  return ob;
+}());
+
+/*!
+ Transformation Matrix v2.0
+ (c) Epistemex 2014-2015
+ www.epistemex.com
+ By Ken Fyrstenberg
+ Contributions by leeoniya.
+ License: MIT, header required.
+ */
+
+/**
+ * 2D transformation matrix object initialized with identity matrix.
+ *
+ * The matrix can synchronize a canvas context by supplying the context
+ * as an argument, or later apply current absolute transform to an
+ * existing context.
+ *
+ * All values are handled as floating point values.
+ *
+ * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix
+ * @prop {number} a - scale x
+ * @prop {number} b - shear y
+ * @prop {number} c - shear x
+ * @prop {number} d - scale y
+ * @prop {number} e - translate x
+ * @prop {number} f - translate y
+ * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context
+ * @constructor
+ */
+
+const Matrix = (function () {
+  var _cos = Math.cos;
+  var _sin = Math.sin;
+  var _tan = Math.tan;
+  var _rnd = Math.round;
+
+  function reset() {
+    this.props[0] = 1;
+    this.props[1] = 0;
+    this.props[2] = 0;
+    this.props[3] = 0;
+    this.props[4] = 0;
+    this.props[5] = 1;
+    this.props[6] = 0;
+    this.props[7] = 0;
+    this.props[8] = 0;
+    this.props[9] = 0;
+    this.props[10] = 1;
+    this.props[11] = 0;
+    this.props[12] = 0;
+    this.props[13] = 0;
+    this.props[14] = 0;
+    this.props[15] = 1;
+    return this;
+  }
+
+  function rotate(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function rotateX(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateY(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateZ(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function shear(sx, sy) {
+    return this._t(1, sy, sx, 1, 0, 0);
+  }
+
+  function skew(ax, ay) {
+    return this.shear(_tan(ax), _tan(ay));
+  }
+
+  function skewFromAxis(ax, angle) {
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+    // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+  }
+
+  function scale(sx, sy, sz) {
+    if (!sz && sz !== 0) {
+      sz = 1;
+    }
+    if (sx === 1 && sy === 1 && sz === 1) {
+      return this;
+    }
+    return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
+  }
+
+  function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
+    this.props[0] = a;
+    this.props[1] = b;
+    this.props[2] = c;
+    this.props[3] = d;
+    this.props[4] = e;
+    this.props[5] = f;
+    this.props[6] = g;
+    this.props[7] = h;
+    this.props[8] = i;
+    this.props[9] = j;
+    this.props[10] = k;
+    this.props[11] = l;
+    this.props[12] = m;
+    this.props[13] = n;
+    this.props[14] = o;
+    this.props[15] = p;
+    return this;
+  }
+
+  function translate(tx, ty, tz) {
+    tz = tz || 0;
+    if (tx !== 0 || ty !== 0 || tz !== 0) {
+      return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
+    }
+    return this;
+  }
+
+  function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
+    var _p = this.props;
+
+    if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
+      // NOTE: commenting this condition because TurboFan deoptimizes code when present
+      // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
+      _p[12] = _p[12] * a2 + _p[15] * m2;
+      _p[13] = _p[13] * f2 + _p[15] * n2;
+      _p[14] = _p[14] * k2 + _p[15] * o2;
+      _p[15] *= p2;
+      // }
+      this._identityCalculated = false;
+      return this;
+    }
+
+    var a1 = _p[0];
+    var b1 = _p[1];
+    var c1 = _p[2];
+    var d1 = _p[3];
+    var e1 = _p[4];
+    var f1 = _p[5];
+    var g1 = _p[6];
+    var h1 = _p[7];
+    var i1 = _p[8];
+    var j1 = _p[9];
+    var k1 = _p[10];
+    var l1 = _p[11];
+    var m1 = _p[12];
+    var n1 = _p[13];
+    var o1 = _p[14];
+    var p1 = _p[15];
+
+    /* matrix order (canvas compatible):
+         * ace
+         * bdf
+         * 001
+         */
+    _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
+    _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
+    _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
+    _p[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2;
+
+    _p[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2;
+    _p[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2;
+    _p[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2;
+    _p[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2;
+
+    _p[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2;
+    _p[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2;
+    _p[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2;
+    _p[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2;
+
+    _p[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2;
+    _p[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2;
+    _p[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2;
+    _p[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2;
+
+    this._identityCalculated = false;
+    return this;
+  }
+
+  function multiply(matrix) {
+    var matrixProps = matrix.props;
+    return this.transform(
+      matrixProps[0],
+      matrixProps[1],
+      matrixProps[2],
+      matrixProps[3],
+      matrixProps[4],
+      matrixProps[5],
+      matrixProps[6],
+      matrixProps[7],
+      matrixProps[8],
+      matrixProps[9],
+      matrixProps[10],
+      matrixProps[11],
+      matrixProps[12],
+      matrixProps[13],
+      matrixProps[14],
+      matrixProps[15]
+    );
+  }
+
+  function isIdentity() {
+    if (!this._identityCalculated) {
+      this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
+      this._identityCalculated = true;
+    }
+    return this._identity;
+  }
+
+  function equals(matr) {
+    var i = 0;
+    while (i < 16) {
+      if (matr.props[i] !== this.props[i]) {
+        return false;
+      }
+      i += 1;
+    }
+    return true;
+  }
+
+  function clone(matr) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      matr.props[i] = this.props[i];
+    }
+    return matr;
+  }
+
+  function cloneFromProps(props) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      this.props[i] = props[i];
+    }
+  }
+
+  function applyToPoint(x, y, z) {
+    return {
+      x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+      y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+      z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+    };
+    /* return {
+         x: x * me.a + y * me.c + me.e,
+         y: x * me.b + y * me.d + me.f
+         }; */
+  }
+  function applyToX(x, y, z) {
+    return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
+  }
+  function applyToY(x, y, z) {
+    return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
+  }
+  function applyToZ(x, y, z) {
+    return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
+  }
+
+  function getInverseMatrix() {
+    var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
+    var a = this.props[5] / determinant;
+    var b = -this.props[1] / determinant;
+    var c = -this.props[4] / determinant;
+    var d = this.props[0] / determinant;
+    var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12]) / determinant;
+    var f = -(this.props[0] * this.props[13] - this.props[1] * this.props[12]) / determinant;
+    var inverseMatrix = new Matrix();
+    inverseMatrix.props[0] = a;
+    inverseMatrix.props[1] = b;
+    inverseMatrix.props[4] = c;
+    inverseMatrix.props[5] = d;
+    inverseMatrix.props[12] = e;
+    inverseMatrix.props[13] = f;
+    return inverseMatrix;
+  }
+
+  function inversePoint(pt) {
+    var inverseMatrix = this.getInverseMatrix();
+    return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
+  }
+
+  function inversePoints(pts) {
+    var i;
+    var len = pts.length;
+    var retPts = [];
+    for (i = 0; i < len; i += 1) {
+      retPts[i] = inversePoint(pts[i]);
+    }
+    return retPts;
+  }
+
+  function applyToTriplePoints(pt1, pt2, pt3) {
+    var arr = createTypedArray('float32', 6);
+    if (this.isIdentity()) {
+      arr[0] = pt1[0];
+      arr[1] = pt1[1];
+      arr[2] = pt2[0];
+      arr[3] = pt2[1];
+      arr[4] = pt3[0];
+      arr[5] = pt3[1];
+    } else {
+      var p0 = this.props[0];
+      var p1 = this.props[1];
+      var p4 = this.props[4];
+      var p5 = this.props[5];
+      var p12 = this.props[12];
+      var p13 = this.props[13];
+      arr[0] = pt1[0] * p0 + pt1[1] * p4 + p12;
+      arr[1] = pt1[0] * p1 + pt1[1] * p5 + p13;
+      arr[2] = pt2[0] * p0 + pt2[1] * p4 + p12;
+      arr[3] = pt2[0] * p1 + pt2[1] * p5 + p13;
+      arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
+      arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
+    }
+    return arr;
+  }
+
+  function applyToPointArray(x, y, z) {
+    var arr;
+    if (this.isIdentity()) {
+      arr = [x, y, z];
+    } else {
+      arr = [
+        x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+        x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+        x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+      ];
+    }
+    return arr;
+  }
+
+  function applyToPointStringified(x, y) {
+    if (this.isIdentity()) {
+      return x + ',' + y;
+    }
+    var _p = this.props;
+    return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
+  }
+
+  function toCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var i = 0;
+    var props = this.props;
+    var cssValue = 'matrix3d(';
+    var v = 10000;
+    while (i < 16) {
+      cssValue += _rnd(props[i] * v) / v;
+      cssValue += i === 15 ? ')' : ',';
+      i += 1;
+    }
+    return cssValue;
+  }
+
+  function roundMatrixProperty(val) {
+    var v = 10000;
+    if ((val < 0.000001 && val > 0) || (val > -0.000001 && val < 0)) {
+      return _rnd(val * v) / v;
+    }
+    return val;
+  }
+
+  function to2dCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var props = this.props;
+    var _a = roundMatrixProperty(props[0]);
+    var _b = roundMatrixProperty(props[1]);
+    var _c = roundMatrixProperty(props[4]);
+    var _d = roundMatrixProperty(props[5]);
+    var _e = roundMatrixProperty(props[12]);
+    var _f = roundMatrixProperty(props[13]);
+    return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
+  }
+
+  return function () {
+    this.reset = reset;
+    this.rotate = rotate;
+    this.rotateX = rotateX;
+    this.rotateY = rotateY;
+    this.rotateZ = rotateZ;
+    this.skew = skew;
+    this.skewFromAxis = skewFromAxis;
+    this.shear = shear;
+    this.scale = scale;
+    this.setTransform = setTransform;
+    this.translate = translate;
+    this.transform = transform;
+    this.multiply = multiply;
+    this.applyToPoint = applyToPoint;
+    this.applyToX = applyToX;
+    this.applyToY = applyToY;
+    this.applyToZ = applyToZ;
+    this.applyToPointArray = applyToPointArray;
+    this.applyToTriplePoints = applyToTriplePoints;
+    this.applyToPointStringified = applyToPointStringified;
+    this.toCSS = toCSS;
+    this.to2dCSS = to2dCSS;
+    this.clone = clone;
+    this.cloneFromProps = cloneFromProps;
+    this.equals = equals;
+    this.inversePoints = inversePoints;
+    this.inversePoint = inversePoint;
+    this.getInverseMatrix = getInverseMatrix;
+    this._t = this.transform;
+    this.isIdentity = isIdentity;
+    this._identity = true;
+    this._identityCalculated = false;
+
+    this.props = createTypedArray('float32', 16);
+    this.reset();
+  };
+}());
+
+const lottie = {};
+var standalone = '__[STANDALONE]__';
+var animationData = '__[ANIMATIONDATA]__';
+var renderer = '';
+
+function setLocation(href) {
+  setLocationHref(href);
+}
+
+function searchAnimations() {
+  if (standalone === true) {
+    animationManager.searchAnimations(animationData, standalone, renderer);
+  } else {
+    animationManager.searchAnimations();
+  }
+}
+
+function setSubframeRendering(flag) {
+  setSubframeEnabled(flag);
+}
+
+function setPrefix(prefix) {
+  setIdPrefix(prefix);
+}
+
+function loadAnimation(params) {
+  if (standalone === true) {
+    params.animationData = JSON.parse(animationData);
+  }
+  return animationManager.loadAnimation(params);
+}
+
+function setQuality(value) {
+  if (typeof value === 'string') {
+    switch (value) {
+      case 'high':
+        setDefaultCurveSegments(200);
+        break;
+      default:
+      case 'medium':
+        setDefaultCurveSegments(50);
+        break;
+      case 'low':
+        setDefaultCurveSegments(10);
+        break;
+    }
+  } else if (!isNaN(value) && value > 1) {
+    setDefaultCurveSegments(value);
+  }
+  if (getDefaultCurveSegments() >= 50) {
+    roundValues(false);
+  } else {
+    roundValues(true);
+  }
+}
+
+function inBrowser() {
+  return typeof navigator !== 'undefined';
+}
+
+function installPlugin(type, plugin) {
+  if (type === 'expressions') {
+    setExpressionsPlugin(plugin);
+  }
+}
+
+function getFactory(name) {
+  switch (name) {
+    case 'propertyFactory':
+      return PropertyFactory;
+    case 'shapePropertyFactory':
+      return ShapePropertyFactory;
+    case 'matrix':
+      return Matrix;
+    default:
+      return null;
+  }
+}
+
+lottie.play = animationManager.play;
+lottie.pause = animationManager.pause;
+lottie.setLocationHref = setLocation;
+lottie.togglePause = animationManager.togglePause;
+lottie.setSpeed = animationManager.setSpeed;
+lottie.setDirection = animationManager.setDirection;
+lottie.stop = animationManager.stop;
+lottie.searchAnimations = searchAnimations;
+lottie.registerAnimation = animationManager.registerAnimation;
+lottie.loadAnimation = loadAnimation;
+lottie.setSubframeRendering = setSubframeRendering;
+lottie.resize = animationManager.resize;
+// lottie.start = start;
+lottie.goToAndStop = animationManager.goToAndStop;
+lottie.destroy = animationManager.destroy;
+lottie.setQuality = setQuality;
+lottie.inBrowser = inBrowser;
+lottie.installPlugin = installPlugin;
+lottie.freeze = animationManager.freeze;
+lottie.unfreeze = animationManager.unfreeze;
+lottie.setVolume = animationManager.setVolume;
+lottie.mute = animationManager.mute;
+lottie.unmute = animationManager.unmute;
+lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations;
+lottie.useWebWorker = setWebWorker;
+lottie.setIDPrefix = setPrefix;
+lottie.__getFactory = getFactory;
+lottie.version = '[[BM_VERSION]]';
+
+function checkReady() {
+  if (document.readyState === 'complete') {
+    clearInterval(readyStateCheckInterval);
+    searchAnimations();
+  }
+}
+
+function getQueryVariable(variable) {
+  var vars = queryString.split('&');
+  for (var i = 0; i < vars.length; i += 1) {
+    var pair = vars[i].split('=');
+    if (decodeURIComponent(pair[0]) == variable) { // eslint-disable-line eqeqeq
+      return decodeURIComponent(pair[1]);
+    }
+  }
+  return null;
+}
+var queryString = '';
+if (standalone) {
+  var scripts = document.getElementsByTagName('script');
+  var index = scripts.length - 1;
+  var myScript = scripts[index] || {
+    src: '',
+  };
+  queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
+  renderer = getQueryVariable('renderer');
+}
+var readyStateCheckInterval = setInterval(checkReady, 100);
+
+// this adds bodymovin to the window object for backwards compatibility
+try {
+  if (!(typeof exports === 'object' && typeof module !== 'undefined')
+    && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
+  ) {
+    window.bodymovin = lottie;
+  }
+} catch (err) {
+  //
+}
+
+const ShapeModifiers = (function () {
+  var ob = {};
+  var modifiers = {};
+  ob.registerModifier = registerModifier;
+  ob.getModifier = getModifier;
+
+  function registerModifier(nm, factory) {
+    if (!modifiers[nm]) {
+      modifiers[nm] = factory;
+    }
+  }
+
+  function getModifier(nm, elem, data) {
+    return new modifiers[nm](elem, data);
+  }
+
+  return ob;
+}());
+
+function ShapeModifier() {}
+ShapeModifier.prototype.initModifierProperties = function () {};
+ShapeModifier.prototype.addShapeToModifier = function () {};
+ShapeModifier.prototype.addShape = function (data) {
+  if (!this.closed) {
+    // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
+    data.sh.container.addDynamicProperty(data.sh);
+    var shapeData = { shape: data.sh, data: data, localShapeCollection: shapeCollectionPool.newShapeCollection() };
+    this.shapes.push(shapeData);
+    this.addShapeToModifier(shapeData);
+    if (this._isAnimated) {
+      data.setAsAnimated();
+    }
+  }
+};
+ShapeModifier.prototype.init = function (elem, data) {
+  this.shapes = [];
+  this.elem = elem;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, data);
+  this.frameId = initialDefaultFrame;
+  this.closed = false;
+  this.k = false;
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+ShapeModifier.prototype.processKeys = function () {
+  if (this.elem.globalData.frameId === this.frameId) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+extendPrototype([DynamicPropertyContainer], ShapeModifier);
+
+function TrimModifier() {
+}
+extendPrototype([ShapeModifier], TrimModifier);
+TrimModifier.prototype.initModifierProperties = function (elem, data) {
+  this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this);
+  this.sValue = 0;
+  this.eValue = 0;
+  this.getValue = this.processKeys;
+  this.m = data.m;
+  this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
+};
+
+TrimModifier.prototype.addShapeToModifier = function (shapeData) {
+  shapeData.pathsData = [];
+};
+
+TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
+  var segments = [];
+  if (e <= 1) {
+    segments.push({
+      s: s,
+      e: e,
+    });
+  } else if (s >= 1) {
+    segments.push({
+      s: s - 1,
+      e: e - 1,
+    });
+  } else {
+    segments.push({
+      s: s,
+      e: 1,
+    });
+    segments.push({
+      s: 0,
+      e: e - 1,
+    });
+  }
+  var shapeSegments = [];
+  var i;
+  var len = segments.length;
+  var segmentOb;
+  for (i = 0; i < len; i += 1) {
+    segmentOb = segments[i];
+    if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
+      var shapeS;
+      var shapeE;
+      if (segmentOb.s * totalModifierLength <= addedLength) {
+        shapeS = 0;
+      } else {
+        shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
+      }
+      if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
+        shapeE = 1;
+      } else {
+        shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength);
+      }
+      shapeSegments.push([shapeS, shapeE]);
+    }
+  }
+  if (!shapeSegments.length) {
+    shapeSegments.push([0, 0]);
+  }
+  return shapeSegments;
+};
+
+TrimModifier.prototype.releasePathsData = function (pathsData) {
+  var i;
+  var len = pathsData.length;
+  for (i = 0; i < len; i += 1) {
+    segmentsLengthPool.release(pathsData[i]);
+  }
+  pathsData.length = 0;
+  return pathsData;
+};
+
+TrimModifier.prototype.processShapes = function (_isFirstFrame) {
+  var s;
+  var e;
+  if (this._mdf || _isFirstFrame) {
+    var o = (this.o.v % 360) / 360;
+    if (o < 0) {
+      o += 1;
+    }
+    if (this.s.v > 1) {
+      s = 1 + o;
+    } else if (this.s.v < 0) {
+      s = 0 + o;
+    } else {
+      s = this.s.v + o;
+    }
+    if (this.e.v > 1) {
+      e = 1 + o;
+    } else if (this.e.v < 0) {
+      e = 0 + o;
+    } else {
+      e = this.e.v + o;
+    }
+
+    if (s > e) {
+      var _s = s;
+      s = e;
+      e = _s;
+    }
+    s = Math.round(s * 10000) * 0.0001;
+    e = Math.round(e * 10000) * 0.0001;
+    this.sValue = s;
+    this.eValue = e;
+  } else {
+    s = this.sValue;
+    e = this.eValue;
+  }
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var pathsData;
+  var pathData;
+  var totalShapeLength;
+  var totalModifierLength = 0;
+
+  if (e === s) {
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].localShapeCollection.releaseShapes();
+      this.shapes[i].shape._mdf = true;
+      this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
+      if (this._mdf) {
+        this.shapes[i].pathsData.length = 0;
+      }
+    }
+  } else if (!((e === 1 && s === 0) || (e === 0 && s === 1))) {
+    var segments = [];
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
+      if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
+        shapeData.shape.paths = shapeData.localShapeCollection;
+      } else {
+        shapePaths = shapeData.shape.paths;
+        jLen = shapePaths._length;
+        totalShapeLength = 0;
+        if (!shapeData.shape._mdf && shapeData.pathsData.length) {
+          totalShapeLength = shapeData.totalShapeLength;
+        } else {
+          pathsData = this.releasePathsData(shapeData.pathsData);
+          for (j = 0; j < jLen; j += 1) {
+            pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
+            pathsData.push(pathData);
+            totalShapeLength += pathData.totalLength;
+          }
+          shapeData.totalShapeLength = totalShapeLength;
+          shapeData.pathsData = pathsData;
+        }
+
+        totalModifierLength += totalShapeLength;
+        shapeData.shape._mdf = true;
+      }
+    }
+    var shapeS = s;
+    var shapeE = e;
+    var addedLength = 0;
+    var edges;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shapeData = this.shapes[i];
+      if (shapeData.shape._mdf) {
+        localShapeCollection = shapeData.localShapeCollection;
+        localShapeCollection.releaseShapes();
+        // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
+        if (this.m === 2 && len > 1) {
+          edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
+          addedLength += shapeData.totalShapeLength;
+        } else {
+          edges = [[shapeS, shapeE]];
+        }
+        jLen = edges.length;
+        for (j = 0; j < jLen; j += 1) {
+          shapeS = edges[j][0];
+          shapeE = edges[j][1];
+          segments.length = 0;
+          if (shapeE <= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength * shapeE,
+            });
+          } else if (shapeS >= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * (shapeS - 1),
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          } else {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength,
+            });
+            segments.push({
+              s: 0,
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          }
+          var newShapesData = this.addShapes(shapeData, segments[0]);
+          if (segments[0].s !== segments[0].e) {
+            if (segments.length > 1) {
+              var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
+              if (lastShapeInCollection.c) {
+                var lastShape = newShapesData.pop();
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1], lastShape);
+              } else {
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1]);
+              }
+            }
+            this.addPaths(newShapesData, localShapeCollection);
+          }
+        }
+        shapeData.shape.paths = localShapeCollection;
+      }
+    }
+  } else if (this._mdf) {
+    for (i = 0; i < len; i += 1) {
+      // Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween.
+      // Don't remove this even if it's losing cached info.
+      this.shapes[i].pathsData.length = 0;
+      this.shapes[i].shape._mdf = true;
+    }
+  }
+};
+
+TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
+  var i;
+  var len = newPaths.length;
+  for (i = 0; i < len; i += 1) {
+    localShapeCollection.addShape(newPaths[i]);
+  }
+};
+
+TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
+  shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
+  shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
+  }
+  shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
+  shapePath.setXYAt(points[1], points[5], 'o', pos);
+  shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(points[0], points[4], 'v', pos);
+  }
+  shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
+  var pathsData = shapeData.pathsData;
+  var shapePaths = shapeData.shape.paths.shapes;
+  var i;
+  var len = shapeData.shape.paths._length;
+  var j;
+  var jLen;
+  var addedLength = 0;
+  var currentLengthData;
+  var segmentCount;
+  var lengths;
+  var segment;
+  var shapes = [];
+  var initPos;
+  var newShape = true;
+  if (!shapePath) {
+    shapePath = shapePool.newElement();
+    segmentCount = 0;
+    initPos = 0;
+  } else {
+    segmentCount = shapePath._length;
+    initPos = shapePath._length;
+  }
+  shapes.push(shapePath);
+  for (i = 0; i < len; i += 1) {
+    lengths = pathsData[i].lengths;
+    shapePath.c = shapePaths[i].c;
+    jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
+    for (j = 1; j < jLen; j += 1) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
+        addedLength += currentLengthData.addedLength;
+        shapePath.c = false;
+      } else if (addedLength > shapeSegment.e) {
+        shapePath.c = false;
+        break;
+      } else {
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+        addedLength += currentLengthData.addedLength;
+        segmentCount += 1;
+      }
+    }
+    if (shapePaths[i].c && lengths.length) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength <= shapeSegment.e) {
+        var segmentLength = lengths[j - 1].addedLength;
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+      } else {
+        shapePath.c = false;
+      }
+      addedLength += currentLengthData.addedLength;
+      segmentCount += 1;
+    }
+    if (shapePath._length) {
+      shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
+      shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
+    }
+    if (addedLength > shapeSegment.e) {
+      break;
+    }
+    if (i < len - 1) {
+      shapePath = shapePool.newElement();
+      newShape = true;
+      shapes.push(shapePath);
+      segmentCount = 0;
+    }
+  }
+  return shapes;
+};
+
+function PuckerAndBloatModifier() {}
+extendPrototype([ShapeModifier], PuckerAndBloatModifier);
+PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this._isAnimated = !!this.amount.effectsSequence.length;
+};
+
+PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
+  var percent = amount / 100;
+  var centerPoint = [0, 0];
+  var pathLength = path._length;
+  var i = 0;
+  for (i = 0; i < pathLength; i += 1) {
+    centerPoint[0] += path.v[i][0];
+    centerPoint[1] += path.v[i][1];
+  }
+  centerPoint[0] /= pathLength;
+  centerPoint[1] /= pathLength;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < pathLength; i += 1) {
+    vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
+    vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
+    oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent;
+    oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent;
+    iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent;
+    iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
+    clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
+  }
+  return clonedPath;
+};
+
+PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+const TransformPropertyFactory = (function () {
+  var defaultVector = [0, 0];
+
+  function applyToMatrix(mat) {
+    var _mdf = this._mdf;
+    this.iterateDynamicProperties();
+    this._mdf = this._mdf || _mdf;
+    if (this.a) {
+      mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+    }
+    if (this.s) {
+      mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+    }
+    if (this.sk) {
+      mat.skewFromAxis(-this.sk.v, this.sa.v);
+    }
+    if (this.r) {
+      mat.rotate(-this.r.v);
+    } else {
+      mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+    }
+    if (this.data.p.s) {
+      if (this.data.p.z) {
+        mat.translate(this.px.v, this.py.v, -this.pz.v);
+      } else {
+        mat.translate(this.px.v, this.py.v, 0);
+      }
+    } else {
+      mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+    }
+  }
+  function processKeys(forceRender) {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    }
+    if (this._isDirty) {
+      this.precalculateMatrix();
+      this._isDirty = false;
+    }
+
+    this.iterateDynamicProperties();
+
+    if (this._mdf || forceRender) {
+      var frameRate;
+      this.v.cloneFromProps(this.pre.props);
+      if (this.appliedTransformations < 1) {
+        this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      }
+      if (this.appliedTransformations < 2) {
+        this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      }
+      if (this.sk && this.appliedTransformations < 3) {
+        this.v.skewFromAxis(-this.sk.v, this.sa.v);
+      }
+      if (this.r && this.appliedTransformations < 4) {
+        this.v.rotate(-this.r.v);
+      } else if (!this.r && this.appliedTransformations < 4) {
+        this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+          .rotateY(this.or.v[1])
+          .rotateX(this.or.v[0]);
+      }
+      if (this.autoOriented) {
+        var v1;
+        var v2;
+        frameRate = this.elem.globalData.frameRate;
+        if (this.p && this.p.keyframes && this.p.getValueAtTime) {
+          if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
+            v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0);
+          } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0);
+            v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0);
+          } else {
+            v1 = this.p.pv;
+            v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime);
+          }
+        } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) {
+          v1 = [];
+          v2 = [];
+          var px = this.px;
+          var py = this.py;
+          if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
+            v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
+            v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate, 0);
+          } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate), 0);
+            v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate), 0);
+            v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0);
+          } else {
+            v1 = [px.pv, py.pv];
+            v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime);
+            v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime);
+          }
+        } else {
+          v2 = defaultVector;
+          v1 = v2;
+        }
+        this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
+      }
+      if (this.data.p && this.data.p.s) {
+        if (this.data.p.z) {
+          this.v.translate(this.px.v, this.py.v, -this.pz.v);
+        } else {
+          this.v.translate(this.px.v, this.py.v, 0);
+        }
+      } else {
+        this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+      }
+    }
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function precalculateMatrix() {
+    this.appliedTransformations = 0;
+    this.pre.reset();
+
+    if (!this.a.effectsSequence.length) {
+      this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      this.appliedTransformations = 1;
+    } else {
+      return;
+    }
+    if (!this.s.effectsSequence.length) {
+      this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      this.appliedTransformations = 2;
+    } else {
+      return;
+    }
+    if (this.sk) {
+      if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
+        this.pre.skewFromAxis(-this.sk.v, this.sa.v);
+        this.appliedTransformations = 3;
+      } else {
+        return;
+      }
+    }
+    if (this.r) {
+      if (!this.r.effectsSequence.length) {
+        this.pre.rotate(-this.r.v);
+        this.appliedTransformations = 4;
+      }
+    } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) {
+      this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+      this.appliedTransformations = 4;
+    }
+  }
+
+  function autoOrient() {
+    //
+    // var prevP = this.getValueAtTime();
+  }
+
+  function addDynamicProperty(prop) {
+    this._addDynamicProperty(prop);
+    this.elem.addDynamicProperty(prop);
+    this._isDirty = true;
+  }
+
+  function TransformProperty(elem, data, container) {
+    this.elem = elem;
+    this.frameId = -1;
+    this.propType = 'transform';
+    this.data = data;
+    this.v = new Matrix();
+    // Precalculated matrix with non animated properties
+    this.pre = new Matrix();
+    this.appliedTransformations = 0;
+    this.initDynamicPropertyContainer(container || elem);
+    if (data.p && data.p.s) {
+      this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
+      this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
+      if (data.p.z) {
+        this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
+      }
+    } else {
+      this.p = PropertyFactory.getProp(elem, data.p || { k: [0, 0, 0] }, 1, 0, this);
+    }
+    if (data.rx) {
+      this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
+      this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
+      this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
+      if (data.or.k[0].ti) {
+        var i;
+        var len = data.or.k.length;
+        for (i = 0; i < len; i += 1) {
+          data.or.k[i].to = null;
+          data.or.k[i].ti = null;
+        }
+      }
+      this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+      // sh Indicates it needs to be capped between -180 and 180
+      this.or.sh = true;
+    } else {
+      this.r = PropertyFactory.getProp(elem, data.r || { k: 0 }, 0, degToRads, this);
+    }
+    if (data.sk) {
+      this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
+      this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
+    }
+    this.a = PropertyFactory.getProp(elem, data.a || { k: [0, 0, 0] }, 1, 0, this);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: [100, 100, 100] }, 1, 0.01, this);
+    // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
+    if (data.o) {
+      this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
+    } else {
+      this.o = { _mdf: false, v: 1 };
+    }
+    this._isDirty = true;
+    if (!this.dynamicProperties.length) {
+      this.getValue(true);
+    }
+  }
+
+  TransformProperty.prototype = {
+    applyToMatrix: applyToMatrix,
+    getValue: processKeys,
+    precalculateMatrix: precalculateMatrix,
+    autoOrient: autoOrient,
+  };
+
+  extendPrototype([DynamicPropertyContainer], TransformProperty);
+  TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
+  TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
+
+  function getTransformProperty(elem, data, container) {
+    return new TransformProperty(elem, data, container);
+  }
+
+  return {
+    getTransformProperty: getTransformProperty,
+  };
+}());
+
+function RepeaterModifier() {}
+extendPrototype([ShapeModifier], RepeaterModifier);
+
+RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, null, this);
+  this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this);
+  this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
+  this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
+  this.data = data;
+  if (!this.dynamicProperties.length) {
+    this.getValue(true);
+  }
+  this._isAnimated = !!this.dynamicProperties.length;
+  this.pMatrix = new Matrix();
+  this.rMatrix = new Matrix();
+  this.sMatrix = new Matrix();
+  this.tMatrix = new Matrix();
+  this.matrix = new Matrix();
+};
+
+RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
+  var dir = inv ? -1 : 1;
+  var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
+  var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
+  pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
+  rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  rMatrix.rotate(-transform.r.v * dir * perc);
+  rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+  sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
+  sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+};
+
+RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
+  this.elem = elem;
+  this.arr = arr;
+  this.pos = pos;
+  this.elemsData = elemsData;
+  this._currentCopies = 0;
+  this._elements = [];
+  this._groups = [];
+  this.frameId = -1;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, arr[pos]);
+  while (pos > 0) {
+    pos -= 1;
+    // this._elements.unshift(arr.splice(pos,1)[0]);
+    this._elements.unshift(arr[pos]);
+  }
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+
+RepeaterModifier.prototype.resetElements = function (elements) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._processed = false;
+    if (elements[i].ty === 'gr') {
+      this.resetElements(elements[i].it);
+    }
+  }
+};
+
+RepeaterModifier.prototype.cloneElements = function (elements) {
+  var newElements = JSON.parse(JSON.stringify(elements));
+  this.resetElements(newElements);
+  return newElements;
+};
+
+RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._render = renderFlag;
+    if (elements[i].ty === 'gr') {
+      this.changeGroupRender(elements[i].it, renderFlag);
+    }
+  }
+};
+
+RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
+  var items;
+  var itemsTransform;
+  var i;
+  var dir;
+  var cont;
+  var hasReloaded = false;
+  if (this._mdf || _isFirstFrame) {
+    var copies = Math.ceil(this.c.v);
+    if (this._groups.length < copies) {
+      while (this._groups.length < copies) {
+        var group = {
+          it: this.cloneElements(this._elements),
+          ty: 'gr',
+        };
+        group.it.push({
+          a: { a: 0, ix: 1, k: [0, 0] }, nm: 'Transform', o: { a: 0, ix: 7, k: 100 }, p: { a: 0, ix: 2, k: [0, 0] }, r: { a: 1, ix: 6, k: [{ s: 0, e: 0, t: 0 }, { s: 0, e: 0, t: 1 }] }, s: { a: 0, ix: 3, k: [100, 100] }, sa: { a: 0, ix: 5, k: 0 }, sk: { a: 0, ix: 4, k: 0 }, ty: 'tr',
+        });
+
+        this.arr.splice(0, 0, group);
+        this._groups.splice(0, 0, group);
+        this._currentCopies += 1;
+      }
+      this.elem.reloadShapes();
+      hasReloaded = true;
+    }
+    cont = 0;
+    var renderFlag;
+    for (i = 0; i <= this._groups.length - 1; i += 1) {
+      renderFlag = cont < copies;
+      this._groups[i]._render = renderFlag;
+      this.changeGroupRender(this._groups[i].it, renderFlag);
+      if (!renderFlag) {
+        var elems = this.elemsData[i].it;
+        var transformData = elems[elems.length - 1];
+        if (transformData.transform.op.v !== 0) {
+          transformData.transform.op._mdf = true;
+          transformData.transform.op.v = 0;
+        } else {
+          transformData.transform.op._mdf = false;
+        }
+      }
+      cont += 1;
+    }
+
+    this._currentCopies = copies;
+    /// /
+
+    var offset = this.o.v;
+    var offsetModulo = offset % 1;
+    var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
+    var pProps = this.pMatrix.props;
+    var rProps = this.rMatrix.props;
+    var sProps = this.sMatrix.props;
+    this.pMatrix.reset();
+    this.rMatrix.reset();
+    this.sMatrix.reset();
+    this.tMatrix.reset();
+    this.matrix.reset();
+    var iteration = 0;
+
+    if (offset > 0) {
+      while (iteration < roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        iteration += 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
+        iteration += offsetModulo;
+      }
+    } else if (offset < 0) {
+      while (iteration > roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
+        iteration -= 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
+        iteration -= offsetModulo;
+      }
+    }
+    i = this.data.m === 1 ? 0 : this._currentCopies - 1;
+    dir = this.data.m === 1 ? 1 : -1;
+    cont = this._currentCopies;
+    var j;
+    var jLen;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      jLen = itemsTransform.length;
+      items[items.length - 1].transform.mProps._mdf = true;
+      items[items.length - 1].transform.op._mdf = true;
+      items[items.length - 1].transform.op.v = this._currentCopies === 1
+        ? this.so.v
+        : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
+
+      if (iteration !== 0) {
+        if ((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)) {
+          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        }
+        this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
+        this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
+        this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
+
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+        this.matrix.reset();
+      } else {
+        this.matrix.reset();
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+      }
+      iteration += 1;
+      cont -= 1;
+      i += dir;
+    }
+  } else {
+    cont = this._currentCopies;
+    i = 0;
+    dir = 1;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      items[items.length - 1].transform.mProps._mdf = false;
+      items[items.length - 1].transform.op._mdf = false;
+      cont -= 1;
+      i += dir;
+    }
+  }
+  return hasReloaded;
+};
+
+RepeaterModifier.prototype.addShape = function () {};
+
+function RoundCornersModifier() {}
+extendPrototype([ShapeModifier], RoundCornersModifier);
+RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this._isAnimated = !!this.rd.effectsSequence.length;
+};
+
+RoundCornersModifier.prototype.processPath = function (path, round) {
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var i;
+  var len = path._length;
+  var currentV;
+  var currentI;
+  var currentO;
+  var closerV;
+  var distance;
+  var newPosPerc;
+  var index = 0;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < len; i += 1) {
+    currentV = path.v[i];
+    currentO = path.o[i];
+    currentI = path.i[i];
+    if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
+      if ((i === 0 || i === len - 1) && !path.c) {
+        clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
+        /* clonedPath.v[index] = currentV;
+                clonedPath.o[index] = currentO;
+                clonedPath.i[index] = currentI; */
+        index += 1;
+      } else {
+        if (i === 0) {
+          closerV = path.v[len - 1];
+        } else {
+          closerV = path.v[i - 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = iX;
+        iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
+        vY = iY;
+        oX = vX - (vX - currentV[0]) * roundCorner;
+        oY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+
+        if (i === len - 1) {
+          closerV = path.v[0];
+        } else {
+          closerV = path.v[i + 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = oX;
+        oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc;
+        vY = oY;
+        iX = vX - (vX - currentV[0]) * roundCorner;
+        iY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+      }
+    } else {
+      clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index);
+      index += 1;
+    }
+  }
+  return clonedPath;
+};
+
+RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var rd = this.rd.v;
+
+  if (rd !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function floatEqual(a, b) {
+  return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
+}
+
+function floatZero(f) {
+  return Math.abs(f) <= 0.00001;
+}
+
+function lerp(p0, p1, amount) {
+  return p0 * (1 - amount) + p1 * amount;
+}
+
+function lerpPoint(p0, p1, amount) {
+  return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
+}
+
+function quadRoots(a, b, c) {
+  // no root
+  if (a === 0) return [];
+  var s = b * b - 4 * a * c;
+  // Complex roots
+  if (s < 0) return [];
+  var singleRoot = -b / (2 * a);
+  // 1 root
+  if (s === 0) return [singleRoot];
+  var delta = Math.sqrt(s) / (2 * a);
+  // 2 roots
+  return [singleRoot - delta, singleRoot + delta];
+}
+
+function polynomialCoefficients(p0, p1, p2, p3) {
+  return [
+    -p0 + 3 * p1 - 3 * p2 + p3,
+    3 * p0 - 6 * p1 + 3 * p2,
+    -3 * p0 + 3 * p1,
+    p0,
+  ];
+}
+
+function singlePoint(p) {
+  return new PolynomialBezier(p, p, p, p, false);
+}
+
+function PolynomialBezier(p0, p1, p2, p3, linearize) {
+  if (linearize && pointEqual(p0, p1)) {
+    p1 = lerpPoint(p0, p3, 1 / 3);
+  }
+  if (linearize && pointEqual(p2, p3)) {
+    p2 = lerpPoint(p0, p3, 2 / 3);
+  }
+  var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
+  var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
+  this.a = [coeffx[0], coeffy[0]];
+  this.b = [coeffx[1], coeffy[1]];
+  this.c = [coeffx[2], coeffy[2]];
+  this.d = [coeffx[3], coeffy[3]];
+  this.points = [p0, p1, p2, p3];
+}
+PolynomialBezier.prototype.point = function (t) {
+  return [
+    (((this.a[0] * t) + this.b[0]) * t + this.c[0]) * t + this.d[0],
+    (((this.a[1] * t) + this.b[1]) * t + this.c[1]) * t + this.d[1],
+  ];
+};
+PolynomialBezier.prototype.derivative = function (t) {
+  return [
+    (3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0],
+    (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1],
+  ];
+};
+PolynomialBezier.prototype.tangentAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[1], p[0]);
+};
+PolynomialBezier.prototype.normalAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[0], p[1]);
+};
+
+PolynomialBezier.prototype.inflectionPoints = function () {
+  var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
+  if (floatZero(denom)) return [];
+  var tcusp = (-0.5 * (this.a[1] * this.c[0] - this.a[0] * this.c[1])) / denom;
+  var square = tcusp * tcusp - ((1 / 3) * (this.b[1] * this.c[0] - this.b[0] * this.c[1])) / denom;
+  if (square < 0) return [];
+  var root = Math.sqrt(square);
+  if (floatZero(root)) {
+    if (root > 0 && root < 1) return [tcusp];
+    return [];
+  }
+  return [tcusp - root, tcusp + root].filter(function (r) { return r > 0 && r < 1; });
+};
+PolynomialBezier.prototype.split = function (t) {
+  if (t <= 0) return [singlePoint(this.points[0]), this];
+  if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
+  var p10 = lerpPoint(this.points[0], this.points[1], t);
+  var p11 = lerpPoint(this.points[1], this.points[2], t);
+  var p12 = lerpPoint(this.points[2], this.points[3], t);
+  var p20 = lerpPoint(p10, p11, t);
+  var p21 = lerpPoint(p11, p12, t);
+  var p3 = lerpPoint(p20, p21, t);
+  return [
+    new PolynomialBezier(this.points[0], p10, p20, p3, true),
+    new PolynomialBezier(p3, p21, p12, this.points[3], true),
+  ];
+};
+function extrema(bez, comp) {
+  var min = bez.points[0][comp];
+  var max = bez.points[bez.points.length - 1][comp];
+  if (min > max) {
+    var e = max;
+    max = min;
+    min = e;
+  }
+  // Derivative roots to find min/max
+  var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
+  for (var i = 0; i < f.length; i += 1) {
+    if (f[i] > 0 && f[i] < 1) {
+      var val = bez.point(f[i])[comp];
+      if (val < min) min = val;
+      else if (val > max) max = val;
+    }
+  }
+  return {
+    min: min,
+    max: max,
+  };
+}
+PolynomialBezier.prototype.bounds = function () {
+  return {
+    x: extrema(this, 0),
+    y: extrema(this, 1),
+  };
+};
+PolynomialBezier.prototype.boundingBox = function () {
+  var bounds = this.bounds();
+  return {
+    left: bounds.x.min,
+    right: bounds.x.max,
+    top: bounds.y.min,
+    bottom: bounds.y.max,
+    width: bounds.x.max - bounds.x.min,
+    height: bounds.y.max - bounds.y.min,
+    cx: (bounds.x.max + bounds.x.min) / 2,
+    cy: (bounds.y.max + bounds.y.min) / 2,
+  };
+};
+
+function intersectData(bez, t1, t2) {
+  var box = bez.boundingBox();
+  return {
+    cx: box.cx,
+    cy: box.cy,
+    width: box.width,
+    height: box.height,
+    bez: bez,
+    t: (t1 + t2) / 2,
+    t1: t1,
+    t2: t2,
+  };
+}
+function splitData(data) {
+  var split = data.bez.split(0.5);
+  return [
+    intersectData(split[0], data.t1, data.t),
+    intersectData(split[1], data.t, data.t2),
+  ];
+}
+
+function boxIntersect(b1, b2) {
+  return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width
+    && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
+}
+
+function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
+  if (!boxIntersect(d1, d2)) return;
+  if (depth >= maxRecursion || (d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance)) {
+    intersections.push([d1.t, d2.t]);
+    return;
+  }
+  var d1s = splitData(d1);
+  var d2s = splitData(d2);
+  intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[0], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+}
+
+PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
+  if (tolerance === undefined) tolerance = 2;
+  if (maxRecursion === undefined) maxRecursion = 7;
+  var intersections = [];
+  intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
+  return intersections;
+};
+
+PolynomialBezier.shapeSegment = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
+};
+
+PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
+};
+
+function crossProduct(a, b) {
+  return [
+    a[1] * b[2] - a[2] * b[1],
+    a[2] * b[0] - a[0] * b[2],
+    a[0] * b[1] - a[1] * b[0],
+  ];
+}
+
+function lineIntersection(start1, end1, start2, end2) {
+  var v1 = [start1[0], start1[1], 1];
+  var v2 = [end1[0], end1[1], 1];
+  var v3 = [start2[0], start2[1], 1];
+  var v4 = [end2[0], end2[1], 1];
+
+  var r = crossProduct(
+    crossProduct(v1, v2),
+    crossProduct(v3, v4)
+  );
+
+  if (floatZero(r[2])) return null;
+
+  return [r[0] / r[2], r[1] / r[2]];
+}
+
+function polarOffset(p, angle, length) {
+  return [
+    p[0] + Math.cos(angle) * length,
+    p[1] - Math.sin(angle) * length,
+  ];
+}
+
+function pointDistance(p1, p2) {
+  return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
+}
+
+function pointEqual(p1, p2) {
+  return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
+}
+
+function ZigZagModifier() {}
+extendPrototype([ShapeModifier], ZigZagModifier);
+ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
+  this.frequency = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
+  this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
+};
+
+function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
+  var angO = angle - Math.PI / 2;
+  var angI = angle + Math.PI / 2;
+  var px = point[0] + Math.cos(angle) * direction * amplitude;
+  var py = point[1] - Math.sin(angle) * direction * amplitude;
+
+  outputBezier.setTripleAt(
+    px,
+    py,
+    px + Math.cos(angO) * outAmplitude,
+    py - Math.sin(angO) * outAmplitude,
+    px + Math.cos(angI) * inAmplitude,
+    py - Math.sin(angI) * inAmplitude,
+    outputBezier.length()
+  );
+}
+
+function getPerpendicularVector(pt1, pt2) {
+  var vector = [
+    pt2[0] - pt1[0],
+    pt2[1] - pt1[1],
+  ];
+  var rot = -Math.PI * 0.5;
+  var rotatedVector = [
+    Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1],
+    Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1],
+  ];
+  return rotatedVector;
+}
+
+function getProjectingAngle(path, cur) {
+  var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
+  var nextIndex = (cur + 1) % path.length();
+  var prevPoint = path.v[prevIndex];
+  var nextPoint = path.v[nextIndex];
+  var pVector = getPerpendicularVector(prevPoint, nextPoint);
+  return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
+}
+
+function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
+  var angle = getProjectingAngle(path, cur);
+  var point = path.v[cur % path._length];
+  var prevPoint = path.v[cur === 0 ? path._length - 1 : cur - 1];
+  var nextPoint = path.v[(cur + 1) % path._length];
+  var prevDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - prevPoint[0], 2) + Math.pow(point[1] - prevPoint[1], 2))
+    : 0;
+  var nextDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2))
+    : 0;
+
+  setPoint(
+    outputBezier,
+    path.v[cur % path._length],
+    angle,
+    direction,
+    amplitude,
+    nextDist / ((frequency + 1) * 2),
+    prevDist / ((frequency + 1) * 2),
+    pointType
+  );
+}
+
+function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
+  for (var i = 0; i < frequency; i += 1) {
+    var t = (i + 1) / (frequency + 1);
+
+    var dist = pointType === 2
+      ? Math.sqrt(Math.pow(segment.points[3][0] - segment.points[0][0], 2) + Math.pow(segment.points[3][1] - segment.points[0][1], 2))
+      : 0;
+
+    var angle = segment.normalAngle(t);
+    var point = segment.point(t);
+    setPoint(
+      outputBezier,
+      point,
+      angle,
+      direction,
+      amplitude,
+      dist / ((frequency + 1) * 2),
+      dist / ((frequency + 1) * 2),
+      pointType
+    );
+
+    direction = -direction;
+  }
+
+  return direction;
+}
+
+ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
+  var count = path._length;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+
+  if (!path.c) {
+    count -= 1;
+  }
+
+  if (count === 0) return clonedPath;
+
+  var direction = -1;
+  var segment = PolynomialBezier.shapeSegment(path, 0);
+  zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
+
+  for (var i = 0; i < count; i += 1) {
+    direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
+
+    if (i === count - 1 && !path.c) {
+      segment = null;
+    } else {
+      segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
+    }
+
+    zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
+  }
+
+  return clonedPath;
+};
+
+ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amplitude = this.amplitude.v;
+  var frequency = Math.max(0, Math.round(this.frequency.v));
+  var pointType = this.pointsType.v;
+
+  if (amplitude !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function linearOffset(p1, p2, amount) {
+  var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
+  return [
+    polarOffset(p1, angle, amount),
+    polarOffset(p2, angle, amount),
+  ];
+}
+
+function offsetSegment(segment, amount) {
+  var p0; var p1a; var p1b; var p2b; var p2a; var
+    p3;
+  var e;
+  e = linearOffset(segment.points[0], segment.points[1], amount);
+  p0 = e[0];
+  p1a = e[1];
+  e = linearOffset(segment.points[1], segment.points[2], amount);
+  p1b = e[0];
+  p2b = e[1];
+  e = linearOffset(segment.points[2], segment.points[3], amount);
+  p2a = e[0];
+  p3 = e[1];
+  var p1 = lineIntersection(p0, p1a, p1b, p2b);
+  if (p1 === null) p1 = p1a;
+  var p2 = lineIntersection(p2a, p3, p1b, p2b);
+  if (p2 === null) p2 = p2a;
+
+  return new PolynomialBezier(p0, p1, p2, p3);
+}
+
+function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
+  var p0 = seg1.points[3];
+  var p1 = seg2.points[0];
+
+  // Bevel
+  if (lineJoin === 3) return p0;
+
+  // Connected, they don't need a joint
+  if (pointEqual(p0, p1)) return p0;
+
+  // Round
+  if (lineJoin === 2) {
+    var angleOut = -seg1.tangentAngle(1);
+    var angleIn = -seg2.tangentAngle(0) + Math.PI;
+    var center = lineIntersection(
+      p0,
+      polarOffset(p0, angleOut + Math.PI / 2, 100),
+      p1,
+      polarOffset(p1, angleOut + Math.PI / 2, 100)
+    );
+    var radius = center ? pointDistance(center, p0) : pointDistance(p0, p1) / 2;
+
+    var tan = polarOffset(p0, angleOut, 2 * radius * roundCorner);
+    outputBezier.setXYAt(tan[0], tan[1], 'o', outputBezier.length() - 1);
+
+    tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
+    outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
+
+    return p1;
+  }
+
+  // Miter
+  var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
+  var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
+  var intersection = lineIntersection(t0, p0, p1, t1);
+  if (intersection && pointDistance(intersection, p0) < miterLimit) {
+    outputBezier.setTripleAt(
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      outputBezier.length()
+    );
+    return intersection;
+  }
+
+  return p0;
+}
+
+function getIntersection(a, b) {
+  const intersect = a.intersections(b);
+
+  if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
+
+  if (intersect.length) return intersect[0];
+
+  return null;
+}
+
+function pruneSegmentIntersection(a, b) {
+  var outa = a.slice();
+  var outb = b.slice();
+  var intersect = getIntersection(a[a.length - 1], b[0]);
+  if (intersect) {
+    outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
+    outb[0] = b[0].split(intersect[1])[1];
+  }
+  if (a.length > 1 && b.length > 1) {
+    intersect = getIntersection(a[0], b[b.length - 1]);
+    if (intersect) {
+      return [
+        [a[0].split(intersect[0])[0]],
+        [b[b.length - 1].split(intersect[1])[1]],
+      ];
+    }
+  }
+  return [outa, outb];
+}
+
+function pruneIntersections(segments) {
+  var e;
+  for (var i = 1; i < segments.length; i += 1) {
+    e = pruneSegmentIntersection(segments[i - 1], segments[i]);
+    segments[i - 1] = e[0];
+    segments[i] = e[1];
+  }
+
+  if (segments.length > 1) {
+    e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
+    segments[segments.length - 1] = e[0];
+    segments[0] = e[1];
+  }
+
+  return segments;
+}
+
+function offsetSegmentSplit(segment, amount) {
+  /*
+    We split each bezier segment into smaller pieces based
+    on inflection points, this ensures the control point
+    polygon is convex.
+
+    (A cubic bezier can have none, one, or two inflection points)
+  */
+  var flex = segment.inflectionPoints();
+  var left;
+  var right;
+  var split;
+  var mid;
+
+  if (flex.length === 0) {
+    return [offsetSegment(segment, amount)];
+  }
+
+  if (flex.length === 1 || floatEqual(flex[1], 1)) {
+    split = segment.split(flex[0]);
+    left = split[0];
+    right = split[1];
+
+    return [
+      offsetSegment(left, amount),
+      offsetSegment(right, amount),
+    ];
+  }
+
+  split = segment.split(flex[0]);
+  left = split[0];
+  var t = (flex[1] - flex[0]) / (1 - flex[0]);
+  split = split[1].split(t);
+  mid = split[0];
+  right = split[1];
+
+  return [
+    offsetSegment(left, amount),
+    offsetSegment(mid, amount),
+    offsetSegment(right, amount),
+  ];
+}
+
+function OffsetPathModifier() {}
+
+extendPrototype([ShapeModifier], OffsetPathModifier);
+OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this.miterLimit = PropertyFactory.getProp(elem, data.ml, 0, null, this);
+  this.lineJoin = data.lj;
+  this._isAnimated = this.amount.effectsSequence.length !== 0;
+};
+
+OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
+  var outputBezier = shapePool.newElement();
+  outputBezier.c = inputBezier.c;
+  var count = inputBezier.length();
+  if (!inputBezier.c) {
+    count -= 1;
+  }
+  var i; var j; var segment;
+  var multiSegments = [];
+
+  for (i = 0; i < count; i += 1) {
+    segment = PolynomialBezier.shapeSegment(inputBezier, i);
+    multiSegments.push(offsetSegmentSplit(segment, amount));
+  }
+
+  if (!inputBezier.c) {
+    for (i = count - 1; i >= 0; i -= 1) {
+      segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
+      multiSegments.push(offsetSegmentSplit(segment, amount));
+    }
+  }
+
+  multiSegments = pruneIntersections(multiSegments);
+
+  // Add bezier segments to the output and apply line joints
+  var lastPoint = null;
+  var lastSeg = null;
+
+  for (i = 0; i < multiSegments.length; i += 1) {
+    var multiSegment = multiSegments[i];
+
+    if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
+
+    lastSeg = multiSegment[multiSegment.length - 1];
+
+    for (j = 0; j < multiSegment.length; j += 1) {
+      segment = multiSegment[j];
+
+      if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
+        outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
+      } else {
+        outputBezier.setTripleAt(
+          segment.points[0][0],
+          segment.points[0][1],
+          segment.points[1][0],
+          segment.points[1][1],
+          segment.points[0][0],
+          segment.points[0][1],
+          outputBezier.length()
+        );
+      }
+
+      outputBezier.setTripleAt(
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[2][0],
+        segment.points[2][1],
+        outputBezier.length()
+      );
+
+      lastPoint = segment.points[3];
+    }
+  }
+
+  if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
+
+  return outputBezier;
+};
+
+OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+  var miterLimit = this.miterLimit.v;
+  var lineJoin = this.lineJoin;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function getFontProperties(fontData) {
+  var styles = fontData.fStyle ? fontData.fStyle.split(' ') : [];
+
+  var fWeight = 'normal'; var
+    fStyle = 'normal';
+  var len = styles.length;
+  var styleName;
+  for (var i = 0; i < len; i += 1) {
+    styleName = styles[i].toLowerCase();
+    switch (styleName) {
+      case 'italic':
+        fStyle = 'italic';
+        break;
+      case 'bold':
+        fWeight = '700';
+        break;
+      case 'black':
+        fWeight = '900';
+        break;
+      case 'medium':
+        fWeight = '500';
+        break;
+      case 'regular':
+      case 'normal':
+        fWeight = '400';
+        break;
+      case 'light':
+      case 'thin':
+        fWeight = '200';
+        break;
+      default:
+        break;
+    }
+  }
+
+  return {
+    style: fStyle,
+    weight: fontData.fWeight || fWeight,
+  };
+}
+
+const FontManager = (function () {
+  var maxWaitingTime = 5000;
+  var emptyChar = {
+    w: 0,
+    size: 0,
+    shapes: [],
+    data: {
+      shapes: [],
+    },
+  };
+  var combinedCharacters = [];
+  // Hindi characters
+  combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366,
+    2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379,
+    2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
+
+  var BLACK_FLAG_CODE_POINT = 127988;
+  var CANCEL_TAG_CODE_POINT = 917631;
+  var A_TAG_CODE_POINT = 917601;
+  var Z_TAG_CODE_POINT = 917626;
+  var VARIATION_SELECTOR_16_CODE_POINT = 65039;
+  var ZERO_WIDTH_JOINER_CODE_POINT = 8205;
+  var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
+  var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
+
+  var surrogateModifiers = [
+    'd83cdffb',
+    'd83cdffc',
+    'd83cdffd',
+    'd83cdffe',
+    'd83cdfff',
+  ];
+
+  function trimFontOptions(font) {
+    var familyArray = font.split(',');
+    var i;
+    var len = familyArray.length;
+    var enabledFamilies = [];
+    for (i = 0; i < len; i += 1) {
+      if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
+        enabledFamilies.push(familyArray[i]);
+      }
+    }
+    return enabledFamilies.join(',');
+  }
+
+  function setUpNode(font, family) {
+    var parentNode = createTag('span');
+    // Node is invisible to screen readers.
+    parentNode.setAttribute('aria-hidden', true);
+    parentNode.style.fontFamily = family;
+    var node = createTag('span');
+    // Characters that vary significantly among different fonts
+    node.innerText = 'giItT1WQy@!-/#';
+    // Visible - so we can measure it - but not on the screen
+    parentNode.style.position = 'absolute';
+    parentNode.style.left = '-10000px';
+    parentNode.style.top = '-10000px';
+    // Large font size makes even subtle changes obvious
+    parentNode.style.fontSize = '300px';
+    // Reset any font properties
+    parentNode.style.fontVariant = 'normal';
+    parentNode.style.fontStyle = 'normal';
+    parentNode.style.fontWeight = 'normal';
+    parentNode.style.letterSpacing = '0';
+    parentNode.appendChild(node);
+    document.body.appendChild(parentNode);
+
+    // Remember width with no applied web font
+    var width = node.offsetWidth;
+    node.style.fontFamily = trimFontOptions(font) + ', ' + family;
+    return { node: node, w: width, parent: parentNode };
+  }
+
+  function checkLoadedFonts() {
+    var i;
+    var len = this.fonts.length;
+    var node;
+    var w;
+    var loadedCount = len;
+    for (i = 0; i < len; i += 1) {
+      if (this.fonts[i].loaded) {
+        loadedCount -= 1;
+      } else if (this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0) {
+        this.fonts[i].loaded = true;
+      } else {
+        node = this.fonts[i].monoCase.node;
+        w = this.fonts[i].monoCase.w;
+        if (node.offsetWidth !== w) {
+          loadedCount -= 1;
+          this.fonts[i].loaded = true;
+        } else {
+          node = this.fonts[i].sansCase.node;
+          w = this.fonts[i].sansCase.w;
+          if (node.offsetWidth !== w) {
+            loadedCount -= 1;
+            this.fonts[i].loaded = true;
+          }
+        }
+        if (this.fonts[i].loaded) {
+          this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
+          this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
+        }
+      }
+    }
+
+    if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
+      setTimeout(this.checkLoadedFontsBinded, 20);
+    } else {
+      setTimeout(this.setIsLoadedBinded, 10);
+    }
+  }
+
+  function createHelper(fontData, def) {
+    var engine = (document.body && def) ? 'svg' : 'canvas';
+    var helper;
+    var fontProps = getFontProperties(fontData);
+    if (engine === 'svg') {
+      var tHelper = createNS('text');
+      tHelper.style.fontSize = '100px';
+      // tHelper.style.fontFamily = fontData.fFamily;
+      tHelper.setAttribute('font-family', fontData.fFamily);
+      tHelper.setAttribute('font-style', fontProps.style);
+      tHelper.setAttribute('font-weight', fontProps.weight);
+      tHelper.textContent = '1';
+      if (fontData.fClass) {
+        tHelper.style.fontFamily = 'inherit';
+        tHelper.setAttribute('class', fontData.fClass);
+      } else {
+        tHelper.style.fontFamily = fontData.fFamily;
+      }
+      def.appendChild(tHelper);
+      helper = tHelper;
+    } else {
+      var tCanvasHelper = new OffscreenCanvas(500, 500).getContext('2d');
+      tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
+      helper = tCanvasHelper;
+    }
+    function measure(text) {
+      if (engine === 'svg') {
+        helper.textContent = text;
+        return helper.getComputedTextLength();
+      }
+      return helper.measureText(text).width;
+    }
+    return {
+      measureText: measure,
+    };
+  }
+
+  function addFonts(fontData, defs) {
+    if (!fontData) {
+      this.isLoaded = true;
+      return;
+    }
+    if (this.chars) {
+      this.isLoaded = true;
+      this.fonts = fontData.list;
+      return;
+    }
+    if (!document.body) {
+      this.isLoaded = true;
+      fontData.list.forEach((data) => {
+        data.helper = createHelper(data);
+        data.cache = {};
+      });
+      this.fonts = fontData.list;
+      return;
+    }
+
+    var fontArr = fontData.list;
+    var i;
+    var len = fontArr.length;
+    var _pendingFonts = len;
+    for (i = 0; i < len; i += 1) {
+      var shouldLoadFont = true;
+      var loadedSelector;
+      var j;
+      fontArr[i].loaded = false;
+      fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
+      fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
+      if (!fontArr[i].fPath) {
+        fontArr[i].loaded = true;
+        _pendingFonts -= 1;
+      } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
+        loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
+
+        if (loadedSelector.length > 0) {
+          shouldLoadFont = false;
+        }
+
+        if (shouldLoadFont) {
+          var s = createTag('style');
+          s.setAttribute('f-forigin', fontArr[i].fOrigin);
+          s.setAttribute('f-origin', fontArr[i].origin);
+          s.setAttribute('f-family', fontArr[i].fFamily);
+          s.type = 'text/css';
+          s.innerText = '@font-face {font-family: ' + fontArr[i].fFamily + "; font-style: normal; src: url('" + fontArr[i].fPath + "');}";
+          defs.appendChild(s);
+        }
+      } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
+        loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var l = createTag('link');
+          l.setAttribute('f-forigin', fontArr[i].fOrigin);
+          l.setAttribute('f-origin', fontArr[i].origin);
+          l.type = 'text/css';
+          l.rel = 'stylesheet';
+          l.href = fontArr[i].fPath;
+          document.body.appendChild(l);
+        }
+      } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
+        loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (fontArr[i].fPath === loadedSelector[j].src) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var sc = createTag('link');
+          sc.setAttribute('f-forigin', fontArr[i].fOrigin);
+          sc.setAttribute('f-origin', fontArr[i].origin);
+          sc.setAttribute('rel', 'stylesheet');
+          sc.setAttribute('href', fontArr[i].fPath);
+          defs.appendChild(sc);
+        }
+      }
+      fontArr[i].helper = createHelper(fontArr[i], defs);
+      fontArr[i].cache = {};
+      this.fonts.push(fontArr[i]);
+    }
+    if (_pendingFonts === 0) {
+      this.isLoaded = true;
+    } else {
+      // On some cases even if the font is loaded, it won't load correctly when measuring text on canvas.
+      // Adding this timeout seems to fix it
+      setTimeout(this.checkLoadedFonts.bind(this), 100);
+    }
+  }
+
+  function addChars(chars) {
+    if (!chars) {
+      return;
+    }
+    if (!this.chars) {
+      this.chars = [];
+    }
+    var i;
+    var len = chars.length;
+    var j;
+    var jLen = this.chars.length;
+    var found;
+    for (i = 0; i < len; i += 1) {
+      j = 0;
+      found = false;
+      while (j < jLen) {
+        if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
+          found = true;
+        }
+        j += 1;
+      }
+      if (!found) {
+        this.chars.push(chars[i]);
+        jLen += 1;
+      }
+    }
+  }
+
+  function getCharData(char, style, font) {
+    var i = 0;
+    var len = this.chars.length;
+    while (i < len) {
+      if (this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font) {
+        return this.chars[i];
+      }
+      i += 1;
+    }
+    if (((typeof char === 'string' && char.charCodeAt(0) !== 13) || !char)
+            && console
+            && console.warn // eslint-disable-line no-console
+            && !this._warned
+    ) {
+      this._warned = true;
+      console.warn('Missing character from exported characters list: ', char, style, font); // eslint-disable-line no-console
+    }
+    return emptyChar;
+  }
+
+  function measureText(char, fontName, size) {
+    var fontData = this.getFontByName(fontName);
+    // Using the char instead of char.charCodeAt(0)
+    // to avoid collisions between equal chars
+    var index = char;
+    if (!fontData.cache[index]) {
+      var tHelper = fontData.helper;
+      if (char === ' ') {
+        var doubleSize = tHelper.measureText('|' + char + '|');
+        var singleSize = tHelper.measureText('||');
+        fontData.cache[index] = (doubleSize - singleSize) / 100;
+      } else {
+        fontData.cache[index] = tHelper.measureText(char) / 100;
+      }
+    }
+    return fontData.cache[index] * size;
+  }
+
+  function getFontByName(name) {
+    var i = 0;
+    var len = this.fonts.length;
+    while (i < len) {
+      if (this.fonts[i].fName === name) {
+        return this.fonts[i];
+      }
+      i += 1;
+    }
+    return this.fonts[0];
+  }
+
+  function getCodePoint(string) {
+    var codePoint = 0;
+    var first = string.charCodeAt(0);
+    if (first >= 0xD800 && first <= 0xDBFF) {
+      var second = string.charCodeAt(1);
+      if (second >= 0xDC00 && second <= 0xDFFF) {
+        codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+      }
+    }
+    return codePoint;
+  }
+
+  // Skin tone modifiers
+  function isModifier(firstCharCode, secondCharCode) {
+    var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
+    return surrogateModifiers.indexOf(sum) !== -1;
+  }
+
+  function isZeroWidthJoiner(charCode) {
+    return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
+  }
+
+  // This codepoint may change the appearance of the preceding character.
+  // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
+  // as a colorful image as compared to a monochrome text variant.
+  function isVariationSelector(charCode) {
+    return charCode === VARIATION_SELECTOR_16_CODE_POINT;
+  }
+
+  // The regional indicator symbols are a set of 26 alphabetic Unicode
+  /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
+  // two-letter country codes in a way that allows optional special treatment.
+  function isRegionalCode(string) {
+    var codePoint = getCodePoint(string);
+    if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
+      return true;
+    }
+    return false;
+  }
+
+  // Some Emoji implementations represent combinations of
+  // two “regional indicator” letters as a single flag symbol.
+  function isFlagEmoji(string) {
+    return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
+  }
+
+  function isCombinedCharacter(char) {
+    return combinedCharacters.indexOf(char) !== -1;
+  }
+
+  // Regional flags start with a BLACK_FLAG_CODE_POINT
+  // folowed by 5 chars in the TAG range
+  // and end with a CANCEL_TAG_CODE_POINT
+  function isRegionalFlag(text, index) {
+    var codePoint = getCodePoint(text.substr(index, 2));
+    if (codePoint !== BLACK_FLAG_CODE_POINT) {
+      return false;
+    }
+    var count = 0;
+    index += 2;
+    while (count < 5) {
+      codePoint = getCodePoint(text.substr(index, 2));
+      if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
+        return false;
+      }
+      count += 1;
+      index += 2;
+    }
+    return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
+  }
+
+  function setIsLoaded() {
+    this.isLoaded = true;
+  }
+
+  var Font = function () {
+    this.fonts = [];
+    this.chars = null;
+    this.typekitLoaded = 0;
+    this.isLoaded = false;
+    this._warned = false;
+    this.initTime = Date.now();
+    this.setIsLoadedBinded = this.setIsLoaded.bind(this);
+    this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
+  };
+  Font.isModifier = isModifier;
+  Font.isZeroWidthJoiner = isZeroWidthJoiner;
+  Font.isFlagEmoji = isFlagEmoji;
+  Font.isRegionalCode = isRegionalCode;
+  Font.isCombinedCharacter = isCombinedCharacter;
+  Font.isRegionalFlag = isRegionalFlag;
+  Font.isVariationSelector = isVariationSelector;
+  Font.BLACK_FLAG_CODE_POINT = BLACK_FLAG_CODE_POINT;
+
+  var fontPrototype = {
+    addChars: addChars,
+    addFonts: addFonts,
+    getCharData: getCharData,
+    getFontByName: getFontByName,
+    measureText: measureText,
+    checkLoadedFonts: checkLoadedFonts,
+    setIsLoaded: setIsLoaded,
+  };
+
+  Font.prototype = fontPrototype;
+
+  return Font;
+}());
+
+function SlotManager(animationData) {
+  this.animationData = animationData;
+}
+SlotManager.prototype.getProp = function (data) {
+  if (this.animationData.slots
+    && this.animationData.slots[data.sid]
+  ) {
+    return Object.assign(data, this.animationData.slots[data.sid].p);
+  }
+  return data;
+};
+
+function slotFactory(animationData) {
+  return new SlotManager(animationData);
+}
+
+function RenderableElement() {
+
+}
+
+RenderableElement.prototype = {
+  initRenderable: function () {
+    // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
+    this.isInRange = false;
+    // layer's display state
+    this.hidden = false;
+    // If layer's transparency equals 0, it can be hidden
+    this.isTransparent = false;
+    // list of animated components
+    this.renderableComponents = [];
+  },
+  addRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) === -1) {
+      this.renderableComponents.push(component);
+    }
+  },
+  removeRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) !== -1) {
+      this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1);
+    }
+  },
+  prepareRenderableFrame: function (num) {
+    this.checkLayerLimits(num);
+  },
+  checkTransparency: function () {
+    if (this.finalTransform.mProp.o.v <= 0) {
+      if (!this.isTransparent && this.globalData.renderConfig.hideOnTransparent) {
+        this.isTransparent = true;
+        this.hide();
+      }
+    } else if (this.isTransparent) {
+      this.isTransparent = false;
+      this.show();
+    }
+  },
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     *
+     */
+  checkLayerLimits: function (num) {
+    if (this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) {
+      if (this.isInRange !== true) {
+        this.globalData._mdf = true;
+        this._mdf = true;
+        this.isInRange = true;
+        this.show();
+      }
+    } else if (this.isInRange !== false) {
+      this.globalData._mdf = true;
+      this.isInRange = false;
+      this.hide();
+    }
+  },
+  renderRenderable: function () {
+    var i;
+    var len = this.renderableComponents.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderableComponents[i].renderFrame(this._isFirstFrame);
+    }
+    /* this.maskManager.renderFrame(this.finalTransform.mat);
+        this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
+  },
+  sourceRectAtTime: function () {
+    return {
+      top: 0,
+      left: 0,
+      width: 100,
+      height: 100,
+    };
+  },
+  getLayerSize: function () {
+    if (this.data.ty === 5) {
+      return { w: this.data.textData.width, h: this.data.textData.height };
+    }
+    return { w: this.data.width, h: this.data.height };
+  },
+};
+
+const getBlendMode = (function () {
+  var blendModeEnums = {
+    0: 'source-over',
+    1: 'multiply',
+    2: 'screen',
+    3: 'overlay',
+    4: 'darken',
+    5: 'lighten',
+    6: 'color-dodge',
+    7: 'color-burn',
+    8: 'hard-light',
+    9: 'soft-light',
+    10: 'difference',
+    11: 'exclusion',
+    12: 'hue',
+    13: 'saturation',
+    14: 'color',
+    15: 'luminosity',
+  };
+
+  return function (mode) {
+    return blendModeEnums[mode] || '';
+  };
+}());
+
+function SliderEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function AngleEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function ColorEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function PointEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function LayerIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function MaskIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function CheckboxEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function NoValueEffect() {
+  this.p = {};
+}
+
+function EffectsManager(data, element) {
+  var effects = data.ef || [];
+  this.effectElements = [];
+  var i;
+  var len = effects.length;
+  var effectItem;
+  for (i = 0; i < len; i += 1) {
+    effectItem = new GroupEffect(effects[i], element);
+    this.effectElements.push(effectItem);
+  }
+}
+
+function GroupEffect(data, element) {
+  this.init(data, element);
+}
+
+extendPrototype([DynamicPropertyContainer], GroupEffect);
+
+GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
+
+GroupEffect.prototype.init = function (data, element) {
+  this.data = data;
+  this.effectElements = [];
+  this.initDynamicPropertyContainer(element);
+  var i;
+  var len = this.data.ef.length;
+  var eff;
+  var effects = this.data.ef;
+  for (i = 0; i < len; i += 1) {
+    eff = null;
+    switch (effects[i].ty) {
+      case 0:
+        eff = new SliderEffect(effects[i], element, this);
+        break;
+      case 1:
+        eff = new AngleEffect(effects[i], element, this);
+        break;
+      case 2:
+        eff = new ColorEffect(effects[i], element, this);
+        break;
+      case 3:
+        eff = new PointEffect(effects[i], element, this);
+        break;
+      case 4:
+      case 7:
+        eff = new CheckboxEffect(effects[i], element, this);
+        break;
+      case 10:
+        eff = new LayerIndexEffect(effects[i], element, this);
+        break;
+      case 11:
+        eff = new MaskIndexEffect(effects[i], element, this);
+        break;
+      case 5:
+        eff = new EffectsManager(effects[i], element, this);
+        break;
+        // case 6:
+      default:
+        eff = new NoValueEffect(effects[i], element, this);
+        break;
+    }
+    if (eff) {
+      this.effectElements.push(eff);
+    }
+  }
+};
+
+function BaseElement() {
+}
+
+BaseElement.prototype = {
+  checkMasks: function () {
+    if (!this.data.hasMask) {
+      return false;
+    }
+    var i = 0;
+    var len = this.data.masksProperties.length;
+    while (i < len) {
+      if ((this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false)) {
+        return true;
+      }
+      i += 1;
+    }
+    return false;
+  },
+  initExpressions: function () {
+    const expressionsInterfaces = getExpressionInterfaces();
+    if (!expressionsInterfaces) {
+      return;
+    }
+    const LayerExpressionInterface = expressionsInterfaces('layer');
+    const EffectsExpressionInterface = expressionsInterfaces('effects');
+    const ShapeExpressionInterface = expressionsInterfaces('shape');
+    const TextExpressionInterface = expressionsInterfaces('text');
+    const CompExpressionInterface = expressionsInterfaces('comp');
+    this.layerInterface = LayerExpressionInterface(this);
+    if (this.data.hasMask && this.maskManager) {
+      this.layerInterface.registerMaskInterface(this.maskManager);
+    }
+    var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
+    this.layerInterface.registerEffectsInterface(effectsInterface);
+
+    if (this.data.ty === 0 || this.data.xt) {
+      this.compInterface = CompExpressionInterface(this);
+    } else if (this.data.ty === 4) {
+      this.layerInterface.shapeInterface = ShapeExpressionInterface(this.shapesData, this.itemsData, this.layerInterface);
+      this.layerInterface.content = this.layerInterface.shapeInterface;
+    } else if (this.data.ty === 5) {
+      this.layerInterface.textInterface = TextExpressionInterface(this);
+      this.layerInterface.text = this.layerInterface.textInterface;
+    }
+  },
+  setBlendMode: function () {
+    var blendModeValue = getBlendMode(this.data.bm);
+    var elem = this.baseElement || this.layerElement;
+
+    elem.style['mix-blend-mode'] = blendModeValue;
+  },
+  initBaseData: function (data, globalData, comp) {
+    this.globalData = globalData;
+    this.comp = comp;
+    this.data = data;
+    this.layerId = createElementID();
+
+    // Stretch factor for old animations missing this property.
+    if (!this.data.sr) {
+      this.data.sr = 1;
+    }
+    // effects manager
+    this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
+  },
+  getType: function () {
+    return this.type;
+  },
+  sourceRectAtTime: function () {},
+};
+
+/**
+ * @file
+ * Handles element's layer frame update.
+ * Checks layer in point and out point
+ *
+ */
+
+function FrameElement() {}
+
+FrameElement.prototype = {
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     */
+  initFrame: function () {
+    // set to true when inpoint is rendered
+    this._isFirstFrame = false;
+    // list of animated properties
+    this.dynamicProperties = [];
+    // If layer has been modified in current tick this will be true
+    this._mdf = false;
+  },
+  /**
+     * @function
+     * Calculates all dynamic values
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     * @param {boolean} isVisible
+     * if layers is currently in range
+     *
+     */
+  prepareProperties: function (num, isVisible) {
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      if (isVisible || (this._isParent && this.dynamicProperties[i].propType === 'transform')) {
+        this.dynamicProperties[i].getValue();
+        if (this.dynamicProperties[i]._mdf) {
+          this.globalData._mdf = true;
+          this._mdf = true;
+        }
+      }
+    }
+  },
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+    }
+  },
+};
+
+function FootageElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.footageData = globalData.imageLoader.getAsset(this.assetData);
+  this.initBaseData(data, globalData, comp);
+}
+
+FootageElement.prototype.prepareFrame = function () {
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
+
+FootageElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+FootageElement.prototype.renderFrame = function () {
+};
+
+FootageElement.prototype.destroy = function () {
+};
+
+FootageElement.prototype.initExpressions = function () {
+  const expressionsInterfaces = getExpressionInterfaces();
+  if (!expressionsInterfaces) {
+    return;
+  }
+  const FootageInterface = expressionsInterfaces('footage');
+  this.layerInterface = FootageInterface(this);
+};
+
+FootageElement.prototype.getFootageData = function () {
+  return this.footageData;
+};
+
+function AudioElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initBaseData(data, globalData, comp);
+  this._isPlaying = false;
+  this._canPlay = false;
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  this.audio = this.globalData.audioController.createAudio(assetPath);
+  this._currentTime = 0;
+  this.globalData.audioController.addAudio(this);
+  this._volumeMultiplier = 1;
+  this._volume = 1;
+  this._previousVolume = null;
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+  this.lv = PropertyFactory.getProp(this, data.au && data.au.lv ? data.au.lv : { k: [100] }, 1, 0.01, this);
+}
+
+AudioElement.prototype.prepareFrame = function (num) {
+  this.prepareRenderableFrame(num, true);
+  this.prepareProperties(num, true);
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    this._currentTime = timeRemapped;
+  } else {
+    this._currentTime = num / this.data.sr;
+  }
+  this._volume = this.lv.v[0];
+  var totalVolume = this._volume * this._volumeMultiplier;
+  if (this._previousVolume !== totalVolume) {
+    this._previousVolume = totalVolume;
+    this.audio.volume(totalVolume);
+  }
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
+
+AudioElement.prototype.renderFrame = function () {
+  if (this.isInRange && this._canPlay) {
+    if (!this._isPlaying) {
+      this.audio.play();
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+      this._isPlaying = true;
+    } else if (!this.audio.playing()
+      || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1
+    ) {
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+    }
+  }
+};
+
+AudioElement.prototype.show = function () {
+  // this.audio.play()
+};
+
+AudioElement.prototype.hide = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+};
+
+AudioElement.prototype.pause = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+  this._canPlay = false;
+};
+
+AudioElement.prototype.resume = function () {
+  this._canPlay = true;
+};
+
+AudioElement.prototype.setRate = function (rateValue) {
+  this.audio.rate(rateValue);
+};
+
+AudioElement.prototype.volume = function (volumeValue) {
+  this._volumeMultiplier = volumeValue;
+  this._previousVolume = volumeValue * this._volume;
+  this.audio.volume(this._previousVolume);
+};
+
+AudioElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+AudioElement.prototype.destroy = function () {
+};
+
+AudioElement.prototype.sourceRectAtTime = function () {
+};
+
+AudioElement.prototype.initExpressions = function () {
+};
+
+function BaseRenderer() {}
+BaseRenderer.prototype.checkLayers = function (num) {
+  var i;
+  var len = this.layers.length;
+  var data;
+  this.completeLayers = true;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (!this.elements[i]) {
+      data = this.layers[i];
+      if (data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) {
+        this.buildItem(i);
+      }
+    }
+    this.completeLayers = this.elements[i] ? this.completeLayers : false;
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.createItem = function (layer) {
+  switch (layer.ty) {
+    case 2:
+      return this.createImage(layer);
+    case 0:
+      return this.createComp(layer);
+    case 1:
+      return this.createSolid(layer);
+    case 3:
+      return this.createNull(layer);
+    case 4:
+      return this.createShape(layer);
+    case 5:
+      return this.createText(layer);
+    case 6:
+      return this.createAudio(layer);
+    case 13:
+      return this.createCamera(layer);
+    case 15:
+      return this.createFootage(layer);
+    default:
+      return this.createNull(layer);
+  }
+};
+
+BaseRenderer.prototype.createCamera = function () {
+  throw new Error('You\'re using a 3d camera. Try the html renderer.');
+};
+
+BaseRenderer.prototype.createAudio = function (data) {
+  return new AudioElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.createFootage = function (data) {
+  return new FootageElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.buildAllItems = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    this.buildItem(i);
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.includeLayers = function (newLayers) {
+  this.completeLayers = false;
+  var i;
+  var len = newLayers.length;
+  var j;
+  var jLen = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    j = 0;
+    while (j < jLen) {
+      if (this.layers[j].id === newLayers[i].id) {
+        this.layers[j] = newLayers[i];
+        break;
+      }
+      j += 1;
+    }
+  }
+};
+
+BaseRenderer.prototype.setProjectInterface = function (pInterface) {
+  this.globalData.projectInterface = pInterface;
+};
+
+BaseRenderer.prototype.initItems = function () {
+  if (!this.globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+};
+BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
+  var elements = this.elements;
+  var layers = this.layers;
+  var i = 0;
+  var len = layers.length;
+  while (i < len) {
+    if (layers[i].ind == parentName) { // eslint-disable-line eqeqeq
+      if (!elements[i] || elements[i] === true) {
+        this.buildItem(i);
+        this.addPendingElement(element);
+      } else {
+        hierarchy.push(elements[i]);
+        elements[i].setAsParent();
+        if (layers[i].parent !== undefined) {
+          this.buildElementParenting(element, layers[i].parent, hierarchy);
+        } else {
+          element.setHierarchy(hierarchy);
+        }
+      }
+    }
+    i += 1;
+  }
+};
+
+BaseRenderer.prototype.addPendingElement = function (element) {
+  this.pendingElements.push(element);
+};
+
+BaseRenderer.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var len = assets.length;
+  for (i = 0; i < len; i += 1) {
+    if (assets[i].xt) {
+      var comp = this.createComp(assets[i]);
+      comp.initExpressions();
+      this.globalData.projectInterface.registerComposition(comp);
+    }
+  }
+};
+
+BaseRenderer.prototype.getElementById = function (ind) {
+  var i;
+  var len = this.elements.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i].data.ind === ind) {
+      return this.elements[i];
+    }
+  }
+  return null;
+};
+
+BaseRenderer.prototype.getElementByPath = function (path) {
+  var pathValue = path.shift();
+  var element;
+  if (typeof pathValue === 'number') {
+    element = this.elements[pathValue];
+  } else {
+    var i;
+    var len = this.elements.length;
+    for (i = 0; i < len; i += 1) {
+      if (this.elements[i].data.nm === pathValue) {
+        element = this.elements[i];
+        break;
+      }
+    }
+  }
+  if (path.length === 0) {
+    return element;
+  }
+  return element.getElementByPath(path);
+};
+
+BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
+  this.globalData.fontManager = new FontManager();
+  this.globalData.slotManager = slotFactory(animData);
+  this.globalData.fontManager.addChars(animData.chars);
+  this.globalData.fontManager.addFonts(animData.fonts, fontsContainer);
+  this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+  this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+  this.globalData.imageLoader = this.animationItem.imagePreloader;
+  this.globalData.audioController = this.animationItem.audioController;
+  this.globalData.frameId = 0;
+  this.globalData.frameRate = animData.fr;
+  this.globalData.nm = animData.nm;
+  this.globalData.compSize = {
+    w: animData.w,
+    h: animData.h,
+  };
+};
+
+var effectTypes = {
+  TRANSFORM_EFFECT: 'transformEFfect',
+};
+
+function TransformElement() {}
+
+TransformElement.prototype = {
+  initTransform: function () {
+    var mat = new Matrix();
+    this.finalTransform = {
+      mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : { o: 0 },
+      _matMdf: false,
+      _localMatMdf: false,
+      _opMdf: false,
+      mat: mat,
+      localMat: mat,
+      localOpacity: 1,
+    };
+    if (this.data.ao) {
+      this.finalTransform.mProp.autoOriented = true;
+    }
+
+    // TODO: check TYPE 11: Guided elements
+    if (this.data.ty !== 11) {
+      // this.createElements();
+    }
+  },
+  renderTransform: function () {
+    this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
+    this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
+
+    if (this.hierarchy) {
+      var mat;
+      var finalMat = this.finalTransform.mat;
+      var i = 0;
+      var len = this.hierarchy.length;
+      // Checking if any of the transformation matrices in the hierarchy chain has changed.
+      if (!this.finalTransform._matMdf) {
+        while (i < len) {
+          if (this.hierarchy[i].finalTransform.mProp._mdf) {
+            this.finalTransform._matMdf = true;
+            break;
+          }
+          i += 1;
+        }
+      }
+
+      if (this.finalTransform._matMdf) {
+        mat = this.finalTransform.mProp.v.props;
+        finalMat.cloneFromProps(mat);
+        for (i = 0; i < len; i += 1) {
+          finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
+        }
+      }
+    }
+    if (!this.localTransforms || this.finalTransform._matMdf) {
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+    }
+    if (this.finalTransform._opMdf) {
+      this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderLocalTransform: function () {
+    if (this.localTransforms) {
+      var i = 0;
+      var len = this.localTransforms.length;
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+      if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
+        while (i < len) {
+          if (this.localTransforms[i]._mdf) {
+            this.finalTransform._localMatMdf = true;
+          }
+          if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
+            this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+            this.finalTransform._opMdf = true;
+          }
+          i += 1;
+        }
+      }
+      if (this.finalTransform._localMatMdf) {
+        var localMat = this.finalTransform.localMat;
+        this.localTransforms[0].matrix.clone(localMat);
+        for (i = 1; i < len; i += 1) {
+          var lmat = this.localTransforms[i].matrix;
+          localMat.multiply(lmat);
+        }
+        localMat.multiply(this.finalTransform.mat);
+      }
+      if (this.finalTransform._opMdf) {
+        var localOp = this.finalTransform.localOpacity;
+        for (i = 0; i < len; i += 1) {
+          localOp *= this.localTransforms[i].opacity * 0.01;
+        }
+        this.finalTransform.localOpacity = localOp;
+      }
+    }
+  },
+  searchEffectTransforms: function () {
+    if (this.renderableEffectsManager) {
+      var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+      if (transformEffects.length) {
+        this.localTransforms = [];
+        this.finalTransform.localMat = new Matrix();
+        var i = 0;
+        var len = transformEffects.length;
+        for (i = 0; i < len; i += 1) {
+          this.localTransforms.push(transformEffects[i]);
+        }
+      }
+    }
+  },
+  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;
+    var len = transforms.length;
+    var 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;
+  },
+  mHelper: new Matrix(),
+};
+
+function MaskElement(data, element, globalData) {
+  this.data = data;
+  this.element = element;
+  this.globalData = globalData;
+  this.storedData = [];
+  this.masksProperties = this.data.masksProperties || [];
+  this.maskElement = null;
+  var defs = this.globalData.defs;
+  var i;
+  var len = this.masksProperties ? this.masksProperties.length : 0;
+  this.viewData = createSizedArray(len);
+  this.solidPath = '';
+
+  var path;
+  var properties = this.masksProperties;
+  var count = 0;
+  var currentMasks = [];
+  var j;
+  var jLen;
+  var layerId = createElementID();
+  var rect;
+  var expansor;
+  var feMorph;
+  var x;
+  var maskType = 'clipPath';
+  var maskRef = 'clip-path';
+  for (i = 0; i < len; i += 1) {
+    if ((properties[i].mode !== 'a' && properties[i].mode !== 'n') || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
+      maskType = 'mask';
+      maskRef = 'mask';
+    }
+
+    if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
+      rect = createNS('rect');
+      rect.setAttribute('fill', '#ffffff');
+      rect.setAttribute('width', this.element.comp.data.w || 0);
+      rect.setAttribute('height', this.element.comp.data.h || 0);
+      currentMasks.push(rect);
+    } else {
+      rect = null;
+    }
+
+    path = createNS('path');
+    if (properties[i].mode === 'n') {
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        elem: path,
+        lastPath: '',
+      };
+      defs.appendChild(path);
+    } else {
+      count += 1;
+
+      path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      path.setAttribute('clip-rule', 'nonzero');
+      var filterID;
+
+      if (properties[i].x.k !== 0) {
+        maskType = 'mask';
+        maskRef = 'mask';
+        x = PropertyFactory.getProp(this.element, properties[i].x, 0, null, this.element);
+        filterID = createElementID();
+        expansor = createNS('filter');
+        expansor.setAttribute('id', filterID);
+        feMorph = createNS('feMorphology');
+        feMorph.setAttribute('operator', 'erode');
+        feMorph.setAttribute('in', 'SourceGraphic');
+        feMorph.setAttribute('radius', '0');
+        expansor.appendChild(feMorph);
+        defs.appendChild(expansor);
+        path.setAttribute('stroke', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      } else {
+        feMorph = null;
+        x = null;
+      }
+
+      // TODO move this to a factory or to a constructor
+      this.storedData[i] = {
+        elem: path,
+        x: x,
+        expan: feMorph,
+        lastPath: '',
+        lastOperator: '',
+        filterId: filterID,
+        lastRadius: 0,
+      };
+      if (properties[i].mode === 'i') {
+        jLen = currentMasks.length;
+        var g = createNS('g');
+        for (j = 0; j < jLen; j += 1) {
+          g.appendChild(currentMasks[j]);
+        }
+        var mask = createNS('mask');
+        mask.setAttribute('mask-type', 'alpha');
+        mask.setAttribute('id', layerId + '_' + count);
+        mask.appendChild(path);
+        defs.appendChild(mask);
+        g.setAttribute('mask', 'url(' + getLocationHref() + '#' + layerId + '_' + count + ')');
+
+        currentMasks.length = 0;
+        currentMasks.push(g);
+      } else {
+        currentMasks.push(path);
+      }
+      if (properties[i].inv && !this.solidPath) {
+        this.solidPath = this.createLayerSolidPath();
+      }
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        elem: path,
+        lastPath: '',
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        invRect: rect,
+      };
+      if (!this.viewData[i].prop.k) {
+        this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
+      }
+    }
+  }
+
+  this.maskElement = createNS(maskType);
+
+  len = currentMasks.length;
+  for (i = 0; i < len; i += 1) {
+    this.maskElement.appendChild(currentMasks[i]);
+  }
+
+  if (count > 0) {
+    this.maskElement.setAttribute('id', layerId);
+    this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
+    defs.appendChild(this.maskElement);
+  }
+  if (this.viewData.length) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+MaskElement.prototype.getMaskProperty = function (pos) {
+  return this.viewData[pos].prop;
+};
+
+MaskElement.prototype.renderFrame = function (isFirstFrame) {
+  var finalMat = this.element.finalTransform.mat;
+  var i;
+  var len = this.masksProperties.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.viewData[i].prop._mdf || isFirstFrame) {
+      this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
+    }
+    if (this.viewData[i].op._mdf || isFirstFrame) {
+      this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
+    }
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
+        this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
+      }
+      if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
+        var feMorph = this.storedData[i].expan;
+        if (this.storedData[i].x.v < 0) {
+          if (this.storedData[i].lastOperator !== 'erode') {
+            this.storedData[i].lastOperator = 'erode';
+            this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
+          }
+          feMorph.setAttribute('radius', -this.storedData[i].x.v);
+        } else {
+          if (this.storedData[i].lastOperator !== 'dilate') {
+            this.storedData[i].lastOperator = 'dilate';
+            this.storedData[i].elem.setAttribute('filter', null);
+          }
+          this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
+        }
+      }
+    }
+  }
+};
+
+MaskElement.prototype.getMaskelement = function () {
+  return this.maskElement;
+};
+
+MaskElement.prototype.createLayerSolidPath = function () {
+  var path = 'M0,0 ';
+  path += ' h' + this.globalData.compSize.w;
+  path += ' v' + this.globalData.compSize.h;
+  path += ' h-' + this.globalData.compSize.w;
+  path += ' v-' + this.globalData.compSize.h + ' ';
+  return path;
+};
+
+MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
+  var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  var i;
+  var len;
+  len = pathNodes._length;
+  for (i = 1; i < len; i += 1) {
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
+  }
+  // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+  if (pathNodes.c && len > 1) {
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  }
+  // pathNodes.__renderedString = pathString;
+
+  if (viewData.lastPath !== pathString) {
+    var pathShapeValue = '';
+    if (viewData.elem) {
+      if (pathNodes.c) {
+        pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
+      }
+      viewData.elem.setAttribute('d', pathShapeValue);
+    }
+    viewData.lastPath = pathString;
+  }
+};
+
+MaskElement.prototype.destroy = function () {
+  this.element = null;
+  this.globalData = null;
+  this.maskElement = null;
+  this.data = null;
+  this.masksProperties = null;
+};
+
+const filtersFactory = (function () {
+  var ob = {};
+  ob.createFilter = createFilter;
+  ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
+
+  function createFilter(filId, skipCoordinates) {
+    var fil = createNS('filter');
+    fil.setAttribute('id', filId);
+    if (skipCoordinates !== true) {
+      fil.setAttribute('filterUnits', 'objectBoundingBox');
+      fil.setAttribute('x', '0%');
+      fil.setAttribute('y', '0%');
+      fil.setAttribute('width', '100%');
+      fil.setAttribute('height', '100%');
+    }
+    return fil;
+  }
+
+  function createAlphaToLuminanceFilter() {
+    var feColorMatrix = createNS('feColorMatrix');
+    feColorMatrix.setAttribute('type', 'matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+    feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
+    return feColorMatrix;
+  }
+
+  return ob;
+}());
+
+const featureSupport = (function () {
+  var ob = {
+    maskType: true,
+    svgLumaHidden: true,
+    offscreenCanvas: typeof OffscreenCanvas !== 'undefined',
+  };
+  if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
+    ob.maskType = false;
+  }
+  if (/firefox/i.test(navigator.userAgent)) {
+    ob.svgLumaHidden = false;
+  }
+  return ob;
+}());
+
+var registeredEffects$1 = {};
+var idPrefix = 'filter_result_';
+
+function SVGEffects(elem) {
+  var i;
+  var source = 'SourceGraphic';
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  var filId = createElementID();
+  var fil = filtersFactory.createFilter(filId, true);
+  var count = 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects$1[type]) {
+      var Effect = registeredEffects$1[type].effect;
+      filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
+      source = idPrefix + count;
+      if (registeredEffects$1[type].countsAsEffect) {
+        count += 1;
+      }
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (count) {
+    elem.globalData.defs.appendChild(fil);
+    elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+SVGEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect$1(id, effect, countsAsEffect) {
+  registeredEffects$1[id] = {
+    effect,
+    countsAsEffect,
+  };
+}
+
+function SVGBaseElement() {
+}
+
+SVGBaseElement.prototype = {
+  initRendererElement: function () {
+    this.layerElement = createNS('g');
+  },
+  createContainerElements: function () {
+    this.matteElement = createNS('g');
+    this.transformedElement = this.layerElement;
+    this.maskedElement = this.layerElement;
+    this._sizeChanged = false;
+    var layerElementParent = null;
+    // If this layer acts as a mask for the following layer
+    if (this.data.td) {
+      this.matteMasks = {};
+      var gg = createNS('g');
+      gg.setAttribute('id', this.layerId);
+      gg.appendChild(this.layerElement);
+      layerElementParent = gg;
+      this.globalData.defs.appendChild(gg);
+    } else if (this.data.tt) {
+      this.matteElement.appendChild(this.layerElement);
+      layerElementParent = this.matteElement;
+      this.baseElement = this.matteElement;
+    } else {
+      this.baseElement = this.layerElement;
+    }
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
+    if (this.data.ty === 0 && !this.data.hd) {
+      var cp = createNS('clipPath');
+      var pt = createNS('path');
+      pt.setAttribute('d', 'M0,0 L' + this.data.w + ',0 L' + this.data.w + ',' + this.data.h + ' L0,' + this.data.h + 'z');
+      var clipId = createElementID();
+      cp.setAttribute('id', clipId);
+      cp.appendChild(pt);
+      this.globalData.defs.appendChild(cp);
+
+      if (this.checkMasks()) {
+        var cpGroup = createNS('g');
+        cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+        cpGroup.appendChild(this.layerElement);
+        this.transformedElement = cpGroup;
+        if (layerElementParent) {
+          layerElementParent.appendChild(this.transformedElement);
+        } else {
+          this.baseElement = this.transformedElement;
+        }
+      } else {
+        this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+      }
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    if (this.finalTransform._localMatMdf) {
+      this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
+    }
+    if (this.finalTransform._opMdf) {
+      this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
+    }
+  },
+  destroyBaseElement: function () {
+    this.layerElement = null;
+    this.matteElement = null;
+    this.maskManager.destroy();
+  },
+  getBaseElement: function () {
+    if (this.data.hd) {
+      return null;
+    }
+    return this.baseElement;
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+    this.renderableEffectsManager = new SVGEffects(this);
+    this.searchEffectTransforms();
+  },
+  getMatte: function (matteType) {
+    // This should not be a common case. But for backward compatibility, we'll create the matte object.
+    // It solves animations that have two consecutive layers marked as matte masks.
+    // Which is an undefined behavior in AE.
+    if (!this.matteMasks) {
+      this.matteMasks = {};
+    }
+    if (!this.matteMasks[matteType]) {
+      var id = this.layerId + '_' + matteType;
+      var filId;
+      var fil;
+      var useElement;
+      var gg;
+      if (matteType === 1 || matteType === 3) {
+        var masker = createNS('mask');
+        masker.setAttribute('id', id);
+        masker.setAttribute('mask-type', matteType === 3 ? 'luminance' : 'alpha');
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        masker.appendChild(useElement);
+        this.globalData.defs.appendChild(masker);
+        if (!featureSupport.maskType && matteType === 1) {
+          masker.setAttribute('mask-type', 'luminance');
+          filId = createElementID();
+          fil = filtersFactory.createFilter(filId);
+          this.globalData.defs.appendChild(fil);
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          gg.appendChild(useElement);
+          masker.appendChild(gg);
+          gg.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        }
+      } else if (matteType === 2) {
+        var maskGroup = createNS('mask');
+        maskGroup.setAttribute('id', id);
+        maskGroup.setAttribute('mask-type', 'alpha');
+        var maskGrouper = createNS('g');
+        maskGroup.appendChild(maskGrouper);
+        filId = createElementID();
+        fil = filtersFactory.createFilter(filId);
+        /// /
+        var feCTr = createNS('feComponentTransfer');
+        feCTr.setAttribute('in', 'SourceGraphic');
+        fil.appendChild(feCTr);
+        var feFunc = createNS('feFuncA');
+        feFunc.setAttribute('type', 'table');
+        feFunc.setAttribute('tableValues', '1.0 0.0');
+        feCTr.appendChild(feFunc);
+        /// /
+        this.globalData.defs.appendChild(fil);
+        var alphaRect = createNS('rect');
+        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');
+        alphaRect.setAttribute('opacity', '0');
+        maskGrouper.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        maskGrouper.appendChild(alphaRect);
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        maskGrouper.appendChild(useElement);
+        if (!featureSupport.maskType) {
+          maskGroup.setAttribute('mask-type', 'luminance');
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          maskGrouper.appendChild(alphaRect);
+          gg.appendChild(this.layerElement);
+          maskGrouper.appendChild(gg);
+        }
+        this.globalData.defs.appendChild(maskGroup);
+      }
+      this.matteMasks[matteType] = id;
+    }
+    return this.matteMasks[matteType];
+  },
+  setMatte: function (id) {
+    if (!this.matteElement) {
+      return;
+    }
+    this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+  },
+};
+
+/**
+ * @file
+ * Handles AE's layer parenting property.
+ *
+ */
+
+function HierarchyElement() {}
+
+HierarchyElement.prototype = {
+  /**
+     * @function
+     * Initializes hierarchy properties
+     *
+     */
+  initHierarchy: function () {
+    // element's parent list
+    this.hierarchy = [];
+    // if element is parent of another layer _isParent will be true
+    this._isParent = false;
+    this.checkParenting();
+  },
+  /**
+     * @function
+     * Sets layer's hierarchy.
+     * @param {array} hierarch
+     * layer's parent list
+     *
+     */
+  setHierarchy: function (hierarchy) {
+    this.hierarchy = hierarchy;
+  },
+  /**
+     * @function
+     * Sets layer as parent.
+     *
+     */
+  setAsParent: function () {
+    this._isParent = true;
+  },
+  /**
+     * @function
+     * Searches layer's parenting chain
+     *
+     */
+  checkParenting: function () {
+    if (this.data.parent !== undefined) {
+      this.comp.buildElementParenting(this, this.data.parent, []);
+    }
+  },
+};
+
+function RenderableDOMElement() {}
+
+(function () {
+  var _prototype = {
+    initElement: function (data, globalData, comp) {
+      this.initFrame();
+      this.initBaseData(data, globalData, comp);
+      this.initTransform(data, globalData, comp);
+      this.initHierarchy();
+      this.initRenderable();
+      this.initRendererElement();
+      this.createContainerElements();
+      this.createRenderableComponents();
+      this.createContent();
+      this.hide();
+    },
+    hide: function () {
+      // console.log('HIDE', this);
+      if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+        var elem = this.baseElement || this.layerElement;
+        elem.style.display = 'none';
+        this.hidden = true;
+      }
+    },
+    show: function () {
+      // console.log('SHOW', this);
+      if (this.isInRange && !this.isTransparent) {
+        if (!this.data.hd) {
+          var elem = this.baseElement || this.layerElement;
+          elem.style.display = 'block';
+        }
+        this.hidden = false;
+        this._isFirstFrame = true;
+      }
+    },
+    renderFrame: function () {
+      // If it is exported as hidden (data.hd === true) no need to render
+      // If it is not visible no need to render
+      if (this.data.hd || this.hidden) {
+        return;
+      }
+      this.renderTransform();
+      this.renderRenderable();
+      this.renderLocalTransform();
+      this.renderElement();
+      this.renderInnerContent();
+      if (this._isFirstFrame) {
+        this._isFirstFrame = false;
+      }
+    },
+    renderInnerContent: function () {},
+    prepareFrame: function (num) {
+      this._mdf = false;
+      this.prepareRenderableFrame(num);
+      this.prepareProperties(num, this.isInRange);
+      this.checkTransparency();
+    },
+    destroy: function () {
+      this.innerElem = null;
+      this.destroyBaseElement();
+    },
+  };
+  extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement);
+}());
+
+function IImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  if (this.assetData && this.assetData.sid) {
+    this.assetData = globalData.slotManager.getProp(this.assetData);
+  }
+  this.initElement(data, globalData, comp);
+  this.sourceRect = {
+    top: 0, left: 0, width: this.assetData.w, height: this.assetData.h,
+  };
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
+
+IImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+
+  this.innerElem = createNS('image');
+  this.innerElem.setAttribute('width', this.assetData.w + 'px');
+  this.innerElem.setAttribute('height', this.assetData.h + 'px');
+  this.innerElem.setAttribute('preserveAspectRatio', this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio);
+  this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+
+  this.layerElement.appendChild(this.innerElem);
+};
+
+IImageElement.prototype.sourceRectAtTime = function () {
+  return this.sourceRect;
+};
+
+function ProcessedElement(element, position) {
+  this.elem = element;
+  this.pos = position;
+}
+
+function IShapeElement() {
+}
+
+IShapeElement.prototype = {
+  addShapeToModifiers: function (data) {
+    var i;
+    var len = this.shapeModifiers.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapeModifiers[i].addShape(data);
+    }
+  },
+  isShapeInAnimatedModifiers: function (data) {
+    var i = 0;
+    var len = this.shapeModifiers.length;
+    while (i < len) {
+      if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
+        return true;
+      }
+    }
+    return false;
+  },
+  renderModifiers: function () {
+    if (!this.shapeModifiers.length) {
+      return;
+    }
+    var i;
+    var len = this.shapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].sh.reset();
+    }
+
+    len = this.shapeModifiers.length;
+    var shouldBreakProcess;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+      // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+      // TODO: find a better solution for this
+      if (shouldBreakProcess) {
+        break;
+      }
+    }
+  },
+
+  searchProcessedElement: function (elem) {
+    var elements = this.processedElements;
+    var i = 0;
+    var len = elements.length;
+    while (i < len) {
+      if (elements[i].elem === elem) {
+        return elements[i].pos;
+      }
+      i += 1;
+    }
+    return 0;
+  },
+  addProcessedElement: function (elem, pos) {
+    var elements = this.processedElements;
+    var i = elements.length;
+    while (i) {
+      i -= 1;
+      if (elements[i].elem === elem) {
+        elements[i].pos = pos;
+        return;
+      }
+    }
+    elements.push(new ProcessedElement(elem, pos));
+  },
+  prepareFrame: function (num) {
+    this.prepareRenderableFrame(num);
+    this.prepareProperties(num, this.isInRange);
+  },
+};
+
+const lineCapEnum = {
+  1: 'butt',
+  2: 'round',
+  3: 'square',
+};
+
+const lineJoinEnum = {
+  1: 'miter',
+  2: 'round',
+  3: 'bevel',
+};
+
+function SVGShapeData(transformers, level, shape) {
+  this.caches = [];
+  this.styles = [];
+  this.transformers = transformers;
+  this.lStr = '';
+  this.sh = shape;
+  this.lvl = level;
+  // TODO find if there are some cases where _isAnimated can be false.
+  // For now, since shapes add up with other shapes. They have to be calculated every time.
+  // One way of finding out is checking if all styles associated to this shape depend only of this shape
+  this._isAnimated = !!shape.k;
+  // TODO: commenting this for now since all shapes are animated
+  var i = 0;
+  var len = transformers.length;
+  while (i < len) {
+    if (transformers[i].mProps.dynamicProperties.length) {
+      this._isAnimated = true;
+      break;
+    }
+    i += 1;
+  }
+}
+
+SVGShapeData.prototype.setAsAnimated = function () {
+  this._isAnimated = true;
+};
+
+function SVGStyleData(data, level) {
+  this.data = data;
+  this.type = data.ty;
+  this.d = '';
+  this.lvl = level;
+  this._mdf = false;
+  this.closed = data.hd === true;
+  this.pElem = createNS('path');
+  this.msElem = null;
+}
+
+SVGStyleData.prototype.reset = function () {
+  this.d = '';
+  this._mdf = false;
+};
+
+function DashProperty(elem, data, renderer, container) {
+  this.elem = elem;
+  this.frameId = -1;
+  this.dataProps = createSizedArray(data.length);
+  this.renderer = renderer;
+  this.k = false;
+  this.dashStr = '';
+  this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0);
+  this.dashoffset = createTypedArray('float32', 1);
+  this.initDynamicPropertyContainer(container);
+  var i;
+  var len = data.length || 0;
+  var prop;
+  for (i = 0; i < len; i += 1) {
+    prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
+    this.k = prop.k || this.k;
+    this.dataProps[i] = { n: data[i].n, p: prop };
+  }
+  if (!this.k) {
+    this.getValue(true);
+  }
+  this._isAnimated = this.k;
+}
+
+DashProperty.prototype.getValue = function (forceRender) {
+  if (this.elem.globalData.frameId === this.frameId && !forceRender) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+  this._mdf = this._mdf || forceRender;
+  if (this._mdf) {
+    var i = 0;
+    var len = this.dataProps.length;
+    if (this.renderer === 'svg') {
+      this.dashStr = '';
+    }
+    for (i = 0; i < len; i += 1) {
+      if (this.dataProps[i].n !== 'o') {
+        if (this.renderer === 'svg') {
+          this.dashStr += ' ' + this.dataProps[i].p.v;
+        } else {
+          this.dashArray[i] = this.dataProps[i].p.v;
+        }
+      } else {
+        this.dashoffset[0] = this.dataProps[i].p.v;
+      }
+    }
+  }
+};
+extendPrototype([DynamicPropertyContainer], DashProperty);
+
+function SVGStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
+
+function SVGFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
+
+function SVGNoStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
+
+function GradientProperty(elem, data, container) {
+  this.data = data;
+  this.c = createTypedArray('uint8c', data.p * 4);
+  var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p * 4) : data.k.k.length - data.p * 4;
+  this.o = createTypedArray('float32', cLength);
+  this._cmdf = false;
+  this._omdf = false;
+  this._collapsable = this.checkCollapsable();
+  this._hasOpacity = cLength;
+  this.initDynamicPropertyContainer(container);
+  this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this);
+  this.k = this.prop.k;
+  this.getValue(true);
+}
+
+GradientProperty.prototype.comparePoints = function (values, points) {
+  var i = 0;
+  var len = this.o.length / 2;
+  var diff;
+  while (i < len) {
+    diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
+    if (diff > 0.01) {
+      return false;
+    }
+    i += 1;
+  }
+  return true;
+};
+
+GradientProperty.prototype.checkCollapsable = function () {
+  if (this.o.length / 2 !== this.c.length / 4) {
+    return false;
+  }
+  if (this.data.k.k[0].s) {
+    var i = 0;
+    var len = this.data.k.k.length;
+    while (i < len) {
+      if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
+        return false;
+      }
+      i += 1;
+    }
+  } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
+    return false;
+  }
+  return true;
+};
+
+GradientProperty.prototype.getValue = function (forceRender) {
+  this.prop.getValue();
+  this._mdf = false;
+  this._cmdf = false;
+  this._omdf = false;
+  if (this.prop._mdf || forceRender) {
+    var i;
+    var len = this.data.p * 4;
+    var mult;
+    var val;
+    for (i = 0; i < len; i += 1) {
+      mult = i % 4 === 0 ? 100 : 255;
+      val = Math.round(this.prop.v[i] * mult);
+      if (this.c[i] !== val) {
+        this.c[i] = val;
+        this._cmdf = !forceRender;
+      }
+    }
+    if (this.o.length) {
+      len = this.prop.v.length;
+      for (i = this.data.p * 4; i < len; i += 1) {
+        mult = i % 2 === 0 ? 100 : 1;
+        val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
+        if (this.o[i - this.data.p * 4] !== val) {
+          this.o[i - this.data.p * 4] = val;
+          this._omdf = !forceRender;
+        }
+      }
+    }
+    this._mdf = !forceRender;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], GradientProperty);
+
+function SVGGradientFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.initGradientData(elem, data, styleOb);
+}
+
+SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 1, null, this);
+  this.h = PropertyFactory.getProp(elem, data.h || { k: 0 }, 0, 0.01, this);
+  this.a = PropertyFactory.getProp(elem, data.a || { k: 0 }, 0, degToRads, this);
+  this.g = new GradientProperty(elem, data.g, this);
+  this.style = styleOb;
+  this.stops = [];
+  this.setGradientData(styleOb.pElem, data);
+  this.setGradientOpacity(data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+};
+
+SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
+  var gradientId = createElementID();
+  var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+  gfill.setAttribute('id', gradientId);
+  gfill.setAttribute('spreadMethod', 'pad');
+  gfill.setAttribute('gradientUnits', 'userSpaceOnUse');
+  var stops = [];
+  var stop;
+  var j;
+  var jLen;
+  jLen = data.g.p * 4;
+  for (j = 0; j < jLen; j += 4) {
+    stop = createNS('stop');
+    gfill.appendChild(stop);
+    stops.push(stop);
+  }
+  pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
+  this.gf = gfill;
+  this.cst = stops;
+};
+
+SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
+  if (this.g._hasOpacity && !this.g._collapsable) {
+    var stop;
+    var j;
+    var jLen;
+    var mask = createNS('mask');
+    var maskElement = createNS('path');
+    mask.appendChild(maskElement);
+    var opacityId = createElementID();
+    var maskId = createElementID();
+    mask.setAttribute('id', maskId);
+    var opFill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+    opFill.setAttribute('id', opacityId);
+    opFill.setAttribute('spreadMethod', 'pad');
+    opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
+    jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
+    var stops = this.stops;
+    for (j = data.g.p * 4; j < jLen; j += 2) {
+      stop = createNS('stop');
+      stop.setAttribute('stop-color', 'rgb(255,255,255)');
+      opFill.appendChild(stop);
+      stops.push(stop);
+    }
+    maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
+    this.maskId = maskId;
+    styleOb.msElem = maskElement;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
+
+function SVGGradientStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.initGradientData(elem, data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
+
+function ShapeGroupData() {
+  this.it = [];
+  this.prevViewData = [];
+  this.gr = createNS('g');
+}
+
+function SVGTransformData(mProps, op, container) {
+  this.transform = {
+    mProps: mProps,
+    op: op,
+    container: container,
+  };
+  this.elements = [];
+  this._isAnimated = this.transform.mProps.dynamicProperties.length || this.transform.op.effectsSequence.length;
+}
+
+const buildShapeString = function (pathNodes, length, closed, mat) {
+  if (length === 0) {
+    return '';
+  }
+  var _o = pathNodes.o;
+  var _i = pathNodes.i;
+  var _v = pathNodes.v;
+  var i;
+  var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+  for (i = 1; i < length; i += 1) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
+  }
+  if (closed && length) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+    shapeString += 'z';
+  }
+  return shapeString;
+};
+
+const SVGElementsRenderer = (function () {
+  var _identityMatrix = new Matrix();
+  var _matrixHelper = new Matrix();
+
+  var ob = {
+    createRenderFunction: createRenderFunction,
+  };
+
+  function createRenderFunction(data) {
+    switch (data.ty) {
+      case 'fl':
+        return renderFill;
+      case 'gf':
+        return renderGradient;
+      case 'gs':
+        return renderGradientStroke;
+      case 'st':
+        return renderStroke;
+      case 'sh':
+      case 'el':
+      case 'rc':
+      case 'sr':
+        return renderPath;
+      case 'tr':
+        return renderContentTransform;
+      case 'no':
+        return renderNoop;
+      default:
+        return null;
+    }
+  }
+
+  function renderContentTransform(styleData, itemData, isFirstFrame) {
+    if (isFirstFrame || itemData.transform.op._mdf) {
+      itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
+    }
+    if (isFirstFrame || itemData.transform.mProps._mdf) {
+      itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
+    }
+  }
+
+  function renderNoop() {
+
+  }
+
+  function renderPath(styleData, itemData, isFirstFrame) {
+    var j;
+    var jLen;
+    var pathStringTransformed;
+    var redraw;
+    var pathNodes;
+    var l;
+    var lLen = itemData.styles.length;
+    var lvl = itemData.lvl;
+    var paths;
+    var mat;
+    var iterations;
+    var k;
+    for (l = 0; l < lLen; l += 1) {
+      redraw = itemData.sh._mdf || isFirstFrame;
+      if (itemData.styles[l].lvl < lvl) {
+        mat = _matrixHelper.reset();
+        iterations = lvl - itemData.styles[l].lvl;
+        k = itemData.transformers.length - 1;
+        while (!redraw && iterations > 0) {
+          redraw = itemData.transformers[k].mProps._mdf || redraw;
+          iterations -= 1;
+          k -= 1;
+        }
+        if (redraw) {
+          iterations = lvl - itemData.styles[l].lvl;
+          k = itemData.transformers.length - 1;
+          while (iterations > 0) {
+            mat.multiply(itemData.transformers[k].mProps.v);
+            iterations -= 1;
+            k -= 1;
+          }
+        }
+      } else {
+        mat = _identityMatrix;
+      }
+      paths = itemData.sh.paths;
+      jLen = paths._length;
+      if (redraw) {
+        pathStringTransformed = '';
+        for (j = 0; j < jLen; j += 1) {
+          pathNodes = paths.shapes[j];
+          if (pathNodes && pathNodes._length) {
+            pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
+          }
+        }
+        itemData.caches[l] = pathStringTransformed;
+      } else {
+        pathStringTransformed = itemData.caches[l];
+      }
+      itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
+      itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
+    }
+  }
+
+  function renderFill(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+
+    if (itemData.c._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
+    }
+  }
+
+  function renderGradientStroke(styleData, itemData, isFirstFrame) {
+    renderGradient(styleData, itemData, isFirstFrame);
+    renderStroke(styleData, itemData, isFirstFrame);
+  }
+
+  function renderGradient(styleData, itemData, isFirstFrame) {
+    var gfill = itemData.gf;
+    var hasOpacity = itemData.g._hasOpacity;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+
+    if (itemData.o._mdf || isFirstFrame) {
+      var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
+      itemData.style.pElem.setAttribute(attr, itemData.o.v);
+    }
+    if (itemData.s._mdf || isFirstFrame) {
+      var attr1 = styleData.t === 1 ? 'x1' : 'cx';
+      var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
+      gfill.setAttribute(attr1, pt1[0]);
+      gfill.setAttribute(attr2, pt1[1]);
+      if (hasOpacity && !itemData.g._collapsable) {
+        itemData.of.setAttribute(attr1, pt1[0]);
+        itemData.of.setAttribute(attr2, pt1[1]);
+      }
+    }
+    var stops;
+    var i;
+    var len;
+    var stop;
+    if (itemData.g._cmdf || isFirstFrame) {
+      stops = itemData.cst;
+      var cValues = itemData.g.c;
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        stop.setAttribute('offset', cValues[i * 4] + '%');
+        stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
+      }
+    }
+    if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
+      var oValues = itemData.g.o;
+      if (itemData.g._collapsable) {
+        stops = itemData.cst;
+      } else {
+        stops = itemData.ost;
+      }
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        if (!itemData.g._collapsable) {
+          stop.setAttribute('offset', oValues[i * 2] + '%');
+        }
+        stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
+      }
+    }
+    if (styleData.t === 1) {
+      if (itemData.e._mdf || isFirstFrame) {
+        gfill.setAttribute('x2', pt2[0]);
+        gfill.setAttribute('y2', pt2[1]);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('x2', pt2[0]);
+          itemData.of.setAttribute('y2', pt2[1]);
+        }
+      }
+    } else {
+      var rad;
+      if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
+        rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        gfill.setAttribute('r', rad);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('r', rad);
+        }
+      }
+      if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (!rad) {
+          rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        }
+        var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+        var percent = itemData.h.v;
+        if (percent >= 1) {
+          percent = 0.99;
+        } else if (percent <= -1) {
+          percent = -0.99;
+        }
+        var dist = rad * percent;
+        var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+        var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+        gfill.setAttribute('fx', x);
+        gfill.setAttribute('fy', y);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('fx', x);
+          itemData.of.setAttribute('fy', y);
+        }
+      }
+      // gfill.setAttribute('fy','200');
+    }
+  }
+
+  function renderStroke(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+    var d = itemData.d;
+    if (d && (d._mdf || isFirstFrame) && d.dashStr) {
+      styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
+      styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
+    }
+    if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
+      styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
+    }
+    if (itemData.w._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
+      if (styleElem.msElem) {
+        styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
+      }
+    }
+  }
+
+  return ob;
+}());
+
+function SVGShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
+
+SVGShapeElement.prototype.initSecondaryElement = function () {
+};
+
+SVGShapeElement.prototype.identityMatrix = new Matrix();
+
+SVGShapeElement.prototype.buildExpressionInterface = function () {};
+
+SVGShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+};
+
+/*
+This method searches for multiple shapes that affect a single element and one of them is animated
+*/
+SVGShapeElement.prototype.filterUniqueShapes = function () {
+  var i;
+  var len = this.shapes.length;
+  var shape;
+  var j;
+  var jLen = this.stylesList.length;
+  var style;
+  var tempShapes = [];
+  var areAnimated = false;
+  for (j = 0; j < jLen; j += 1) {
+    style = this.stylesList[j];
+    areAnimated = false;
+    tempShapes.length = 0;
+    for (i = 0; i < len; i += 1) {
+      shape = this.shapes[i];
+      if (shape.styles.indexOf(style) !== -1) {
+        tempShapes.push(shape);
+        areAnimated = shape._isAnimated || areAnimated;
+      }
+    }
+    if (tempShapes.length > 1 && areAnimated) {
+      this.setShapesAsAnimated(tempShapes);
+    }
+  }
+};
+
+SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
+  var i;
+  var len = shapes.length;
+  for (i = 0; i < len; i += 1) {
+    shapes[i].setAsAnimated();
+  }
+};
+
+SVGShapeElement.prototype.createStyleElement = function (data, level) {
+  // TODO: prevent drawing of hidden styles
+  var elementData;
+  var styleOb = new SVGStyleData(data, level);
+
+  var pathElement = styleOb.pElem;
+  if (data.ty === 'st') {
+    elementData = new SVGStrokeStyleData(this, data, styleOb);
+  } else if (data.ty === 'fl') {
+    elementData = new SVGFillStyleData(this, data, styleOb);
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
+    elementData = new GradientConstructor(this, data, styleOb);
+    this.globalData.defs.appendChild(elementData.gf);
+    if (elementData.maskId) {
+      this.globalData.defs.appendChild(elementData.ms);
+      this.globalData.defs.appendChild(elementData.of);
+      pathElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + elementData.maskId + ')');
+    }
+  } else if (data.ty === 'no') {
+    elementData = new SVGNoStyleData(this, data, styleOb);
+  }
+
+  if (data.ty === 'st' || data.ty === 'gs') {
+    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);
+    }
+  }
+
+  if (data.r === 2) {
+    pathElement.setAttribute('fill-rule', 'evenodd');
+  }
+
+  if (data.ln) {
+    pathElement.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    pathElement.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  this.stylesList.push(styleOb);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createGroupElement = function (data) {
+  var elementData = new ShapeGroupData();
+  if (data.ln) {
+    elementData.gr.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    elementData.gr.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  return elementData;
+};
+
+SVGShapeElement.prototype.createTransformElement = function (data, container) {
+  var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
+  var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
+  var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
+  var i = 0;
+  var len = this.animatedContents.length;
+  while (i < len) {
+    if (this.animatedContents[i].element === element) {
+      return;
+    }
+    i += 1;
+  }
+  this.animatedContents.push({
+    fn: SVGElementsRenderer.createRenderFunction(data),
+    element: element,
+    data: data,
+  });
+};
+
+SVGShapeElement.prototype.setElementStyles = function (elementData) {
+  var arr = elementData.styles;
+  var j;
+  var jLen = this.stylesList.length;
+  for (j = 0; j < jLen; j += 1) {
+    if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
+      arr.push(this.stylesList[j]);
+    }
+  }
+};
+
+SVGShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+};
+
+SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
+  var ownTransformers = [].concat(transformers);
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var currentTransform;
+  var modifier;
+  var processedPos;
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._render = render;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], level);
+      } else {
+        itemsData[i].style.closed = arr[i].hd;
+      }
+      if (arr[i]._render) {
+        if (itemsData[i].style.pElem.parentNode !== container) {
+          container.appendChild(itemsData[i].style.pElem);
+        }
+      }
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
+      if (arr[i]._render) {
+        if (itemsData[i].gr.parentNode !== container) {
+          container.appendChild(itemsData[i].gr);
+        }
+      }
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        itemsData[i] = this.createTransformElement(arr[i], container);
+      }
+      currentTransform = itemsData[i].transform;
+      ownTransformers.push(currentTransform);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
+      }
+      this.setElementStyles(itemsData[i]);
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        render = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  len = ownStyles.length;
+  for (i = 0; i < len; i += 1) {
+    ownStyles[i].closed = true;
+  }
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+SVGShapeElement.prototype.renderInnerContent = function () {
+  this.renderModifiers();
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    this.stylesList[i].reset();
+  }
+  this.renderShape();
+  for (i = 0; i < len; i += 1) {
+    if (this.stylesList[i]._mdf || this._isFirstFrame) {
+      if (this.stylesList[i].msElem) {
+        this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+        // Adding M0 0 fixes same mask bug on all browsers
+        this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
+      }
+      this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
+    }
+  }
+};
+
+SVGShapeElement.prototype.renderShape = function () {
+  var i;
+  var len = this.animatedContents.length;
+  var animatedContent;
+  for (i = 0; i < len; i += 1) {
+    animatedContent = this.animatedContents[i];
+    if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
+      animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
+    }
+  }
+};
+
+SVGShapeElement.prototype.destroy = function () {
+  this.destroyBaseElement();
+  this.shapesData = null;
+  this.itemsData = null;
+};
+
+function LetterProps(o, sw, sc, fc, m, p) {
+  this.o = o;
+  this.sw = sw;
+  this.sc = sc;
+  this.fc = fc;
+  this.m = m;
+  this.p = p;
+  this._mdf = {
+    o: true,
+    sw: !!sw,
+    sc: !!sc,
+    fc: !!fc,
+    m: true,
+    p: true,
+  };
+}
+
+LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
+  this._mdf.o = false;
+  this._mdf.sw = false;
+  this._mdf.sc = false;
+  this._mdf.fc = false;
+  this._mdf.m = false;
+  this._mdf.p = false;
+  var updated = false;
+
+  if (this.o !== o) {
+    this.o = o;
+    this._mdf.o = true;
+    updated = true;
+  }
+  if (this.sw !== sw) {
+    this.sw = sw;
+    this._mdf.sw = true;
+    updated = true;
+  }
+  if (this.sc !== sc) {
+    this.sc = sc;
+    this._mdf.sc = true;
+    updated = true;
+  }
+  if (this.fc !== fc) {
+    this.fc = fc;
+    this._mdf.fc = true;
+    updated = true;
+  }
+  if (this.m !== m) {
+    this.m = m;
+    this._mdf.m = true;
+    updated = true;
+  }
+  if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
+    this.p = p;
+    this._mdf.p = true;
+    updated = true;
+  }
+  return updated;
+};
+
+function TextProperty(elem, data) {
+  this._frameId = initialDefaultFrame;
+  this.pv = '';
+  this.v = '';
+  this.kf = false;
+  this._isFirstFrame = true;
+  this._mdf = false;
+  if (data.d && data.d.sid) {
+    data.d = elem.globalData.slotManager.getProp(data.d);
+  }
+  this.data = data;
+  this.elem = elem;
+  this.comp = this.elem.comp;
+  this.keysIndex = 0;
+  this.canResize = false;
+  this.minimumFontSize = 1;
+  this.effectsSequence = [];
+  this.currentData = {
+    ascent: 0,
+    boxWidth: this.defaultBoxWidth,
+    f: '',
+    fStyle: '',
+    fWeight: '',
+    fc: '',
+    j: '',
+    justifyOffset: '',
+    l: [],
+    lh: 0,
+    lineWidths: [],
+    ls: '',
+    of: '',
+    s: '',
+    sc: '',
+    sw: 0,
+    t: 0,
+    tr: 0,
+    sz: 0,
+    ps: null,
+    fillColorAnim: false,
+    strokeColorAnim: false,
+    strokeWidthAnim: false,
+    yOffset: 0,
+    finalSize: 0,
+    finalText: [],
+    finalLineHeight: 0,
+    __complete: false,
+
+  };
+  this.copyData(this.currentData, this.data.d.k[0].s);
+
+  if (!this.searchProperty()) {
+    this.completeTextData(this.currentData);
+  }
+}
+
+TextProperty.prototype.defaultBoxWidth = [0, 0];
+
+TextProperty.prototype.copyData = function (obj, data) {
+  for (var s in data) {
+    if (Object.prototype.hasOwnProperty.call(data, s)) {
+      obj[s] = data[s];
+    }
+  }
+  return obj;
+};
+
+TextProperty.prototype.setCurrentData = function (data) {
+  if (!data.__complete) {
+    this.completeTextData(data);
+  }
+  this.currentData = data;
+  this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
+  this._mdf = true;
+};
+
+TextProperty.prototype.searchProperty = function () {
+  return this.searchKeyframes();
+};
+
+TextProperty.prototype.searchKeyframes = function () {
+  this.kf = this.data.d.k.length > 1;
+  if (this.kf) {
+    this.addEffect(this.getKeyframeValue.bind(this));
+  }
+  return this.kf;
+};
+
+TextProperty.prototype.addEffect = function (effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.getValue = function (_finalValue) {
+  if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
+    return;
+  }
+  this.currentData.t = this.data.d.k[this.keysIndex].s.t;
+  var currentValue = this.currentData;
+  var currentIndex = this.keysIndex;
+  if (this.lock) {
+    this.setCurrentData(this.currentData);
+    return;
+  }
+  this.lock = true;
+  this._mdf = false;
+  var i; var
+    len = this.effectsSequence.length;
+  var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
+  for (i = 0; i < len; i += 1) {
+    // Checking if index changed to prevent creating a new object every time the expression updates.
+    if (currentIndex !== this.keysIndex) {
+      finalValue = this.effectsSequence[i](finalValue, finalValue.t);
+    } else {
+      finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
+    }
+  }
+  if (currentValue !== finalValue) {
+    this.setCurrentData(finalValue);
+  }
+  this.v = this.currentData;
+  this.pv = this.v;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+};
+
+TextProperty.prototype.getKeyframeValue = function () {
+  var textKeys = this.data.d.k;
+  var frameNum = this.elem.comp.renderedFrame;
+  var i = 0; var
+    len = textKeys.length;
+  while (i <= len - 1) {
+    if (i === len - 1 || textKeys[i + 1].t > frameNum) {
+      break;
+    }
+    i += 1;
+  }
+  if (this.keysIndex !== i) {
+    this.keysIndex = i;
+  }
+  return this.data.d.k[this.keysIndex].s;
+};
+
+TextProperty.prototype.buildFinalText = function (text) {
+  var charactersArray = [];
+  var i = 0;
+  var len = text.length;
+  var charCode;
+  var secondCharCode;
+  var shouldCombine = false;
+  var shouldCombineNext = false;
+  var currentChars = '';
+  while (i < len) {
+    shouldCombine = shouldCombineNext;
+    shouldCombineNext = false;
+    charCode = text.charCodeAt(i);
+    currentChars = text.charAt(i);
+    if (FontManager.isCombinedCharacter(charCode)) {
+      shouldCombine = true;
+      // It's a potential surrogate pair (this is the High surrogate)
+    } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+      if (FontManager.isRegionalFlag(text, i)) {
+        currentChars = text.substr(i, 14);
+      } else {
+        secondCharCode = text.charCodeAt(i + 1);
+        // It's a surrogate pair (this is the Low surrogate)
+        if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
+          if (FontManager.isModifier(charCode, secondCharCode)) {
+            currentChars = text.substr(i, 2);
+            shouldCombine = true;
+          } else if (FontManager.isFlagEmoji(text.substr(i, 4))) {
+            currentChars = text.substr(i, 4);
+          } else {
+            currentChars = text.substr(i, 2);
+          }
+        }
+      }
+    } else if (charCode > 0xDBFF) {
+      secondCharCode = text.charCodeAt(i + 1);
+      if (FontManager.isVariationSelector(charCode)) {
+        shouldCombine = true;
+      }
+    } else if (FontManager.isZeroWidthJoiner(charCode)) {
+      shouldCombine = true;
+      shouldCombineNext = true;
+    }
+    if (shouldCombine) {
+      charactersArray[charactersArray.length - 1] += currentChars;
+      shouldCombine = false;
+    } else {
+      charactersArray.push(currentChars);
+    }
+    i += currentChars.length;
+  }
+  return charactersArray;
+};
+
+TextProperty.prototype.completeTextData = function (documentData) {
+  documentData.__complete = true;
+  var fontManager = this.elem.globalData.fontManager;
+  var data = this.data;
+  var letters = [];
+  var i; var
+    len;
+  var newLineFlag; var index = 0; var
+    val;
+  var anchorGrouping = data.m.g;
+  var currentSize = 0; var currentPos = 0; var currentLine = 0; var
+    lineWidths = [];
+  var lineWidth = 0;
+  var maxLineWidth = 0;
+  var j; var
+    jLen;
+  var fontData = fontManager.getFontByName(documentData.f);
+  var charData; var
+    cLength = 0;
+
+  var fontProps = getFontProperties(fontData);
+  documentData.fWeight = fontProps.weight;
+  documentData.fStyle = fontProps.style;
+  documentData.finalSize = documentData.s;
+  documentData.finalText = this.buildFinalText(documentData.t);
+  len = documentData.finalText.length;
+  documentData.finalLineHeight = documentData.lh;
+  var trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+  var charCode;
+  if (documentData.sz) {
+    var flag = true;
+    var boxWidth = documentData.sz[0];
+    var boxHeight = documentData.sz[1];
+    var currentHeight; var
+      finalText;
+    while (flag) {
+      finalText = this.buildFinalText(documentData.t);
+      currentHeight = 0;
+      lineWidth = 0;
+      len = finalText.length;
+      trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+      var lastSpaceIndex = -1;
+      for (i = 0; i < len; i += 1) {
+        charCode = finalText[i].charCodeAt(0);
+        newLineFlag = false;
+        if (finalText[i] === ' ') {
+          lastSpaceIndex = i;
+        } else if (charCode === 13 || charCode === 3) {
+          lineWidth = 0;
+          newLineFlag = true;
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+        }
+        if (fontManager.chars) {
+          charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
+          cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+        } else {
+          // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
+          cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
+        }
+        if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
+          if (lastSpaceIndex === -1) {
+            len += 1;
+          } else {
+            i = lastSpaceIndex;
+          }
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+          finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+          // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
+          lastSpaceIndex = -1;
+          lineWidth = 0;
+        } else {
+          lineWidth += cLength;
+          lineWidth += trackingOffset;
+        }
+      }
+      currentHeight += (fontData.ascent * documentData.finalSize) / 100;
+      if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
+        documentData.finalSize -= 1;
+        documentData.finalLineHeight = (documentData.finalSize * documentData.lh) / documentData.s;
+      } else {
+        documentData.finalText = finalText;
+        len = documentData.finalText.length;
+        flag = false;
+      }
+    }
+  }
+  lineWidth = -trackingOffset;
+  cLength = 0;
+  var uncollapsedSpaces = 0;
+  var currentChar;
+  for (i = 0; i < len; i += 1) {
+    newLineFlag = false;
+    currentChar = documentData.finalText[i];
+    charCode = currentChar.charCodeAt(0);
+    if (charCode === 13 || charCode === 3) {
+      uncollapsedSpaces = 0;
+      lineWidths.push(lineWidth);
+      maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+      lineWidth = -2 * trackingOffset;
+      val = '';
+      newLineFlag = true;
+      currentLine += 1;
+    } else {
+      val = currentChar;
+    }
+    if (fontManager.chars) {
+      charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
+      cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+    } else {
+      // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
+      // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
+      cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
+    }
+
+    //
+    if (currentChar === ' ') {
+      uncollapsedSpaces += cLength + trackingOffset;
+    } else {
+      lineWidth += cLength + trackingOffset + uncollapsedSpaces;
+      uncollapsedSpaces = 0;
+    }
+    letters.push({
+      l: cLength, an: cLength, add: currentSize, n: newLineFlag, anIndexes: [], val: val, line: currentLine, animatorJustifyOffset: 0,
+    });
+    if (anchorGrouping == 2) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || val === ' ' || i === len - 1) {
+        if (val === '' || val === ' ') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        index += 1;
+        currentSize = 0;
+      }
+    } else if (anchorGrouping == 3) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || i === len - 1) {
+        if (val === '') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        currentSize = 0;
+        index += 1;
+      }
+    } else {
+      letters[index].ind = index;
+      letters[index].extra = 0;
+      index += 1;
+    }
+  }
+  documentData.l = letters;
+  maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+  lineWidths.push(lineWidth);
+  if (documentData.sz) {
+    documentData.boxWidth = documentData.sz[0];
+    documentData.justifyOffset = 0;
+  } else {
+    documentData.boxWidth = maxLineWidth;
+    switch (documentData.j) {
+      case 1:
+        documentData.justifyOffset = -documentData.boxWidth;
+        break;
+      case 2:
+        documentData.justifyOffset = -documentData.boxWidth / 2;
+        break;
+      default:
+        documentData.justifyOffset = 0;
+    }
+  }
+  documentData.lineWidths = lineWidths;
+
+  var animators = data.a; var animatorData; var
+    letterData;
+  jLen = animators.length;
+  var based; var ind; var
+    indexes = [];
+  for (j = 0; j < jLen; j += 1) {
+    animatorData = animators[j];
+    if (animatorData.a.sc) {
+      documentData.strokeColorAnim = true;
+    }
+    if (animatorData.a.sw) {
+      documentData.strokeWidthAnim = true;
+    }
+    if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
+      documentData.fillColorAnim = true;
+    }
+    ind = 0;
+    based = animatorData.s.b;
+    for (i = 0; i < len; i += 1) {
+      letterData = letters[i];
+      letterData.anIndexes[j] = ind;
+      if ((based == 1 && letterData.val !== '') || (based == 2 && letterData.val !== '' && letterData.val !== ' ') || (based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1)) || (based == 4 && (letterData.n || i == len - 1))) { // eslint-disable-line eqeqeq
+        if (animatorData.s.rn === 1) {
+          indexes.push(ind);
+        }
+        ind += 1;
+      }
+    }
+    data.a[j].s.totalChars = ind;
+    var currentInd = -1; var
+      newInd;
+    if (animatorData.s.rn === 1) {
+      for (i = 0; i < len; i += 1) {
+        letterData = letters[i];
+        if (currentInd != letterData.anIndexes[j]) { // eslint-disable-line eqeqeq
+          currentInd = letterData.anIndexes[j];
+          newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
+        }
+        letterData.anIndexes[j] = newInd;
+      }
+    }
+  }
+  documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
+  documentData.ls = documentData.ls || 0;
+  documentData.ascent = (fontData.ascent * documentData.finalSize) / 100;
+};
+
+TextProperty.prototype.updateDocumentData = function (newData, index) {
+  index = index === undefined ? this.keysIndex : index;
+  var dData = this.copyData({}, this.data.d.k[index].s);
+  dData = this.copyData(dData, newData);
+  this.data.d.k[index].s = dData;
+  this.recalculate(index);
+  this.setCurrentData(dData);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.recalculate = function (index) {
+  var dData = this.data.d.k[index].s;
+  dData.__complete = false;
+  this.keysIndex = 0;
+  this._isFirstFrame = true;
+  this.getValue(dData);
+};
+
+TextProperty.prototype.canResizeFont = function (_canResize) {
+  this.canResize = _canResize;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
+  this.minimumFontSize = Math.floor(_fontValue) || 1;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+const TextSelectorProp = (function () {
+  var max = Math.max;
+  var min = Math.min;
+  var floor = Math.floor;
+
+  function TextSelectorPropFactory(elem, data) {
+    this._currentTextLength = -1;
+    this.k = false;
+    this.data = data;
+    this.elem = elem;
+    this.comp = elem.comp;
+    this.finalS = 0;
+    this.finalE = 0;
+    this.initDynamicPropertyContainer(elem);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: 0 }, 0, 0, this);
+    if ('e' in data) {
+      this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
+    } else {
+      this.e = { v: 100 };
+    }
+    this.o = PropertyFactory.getProp(elem, data.o || { k: 0 }, 0, 0, this);
+    this.xe = PropertyFactory.getProp(elem, data.xe || { k: 0 }, 0, 0, this);
+    this.ne = PropertyFactory.getProp(elem, data.ne || { k: 0 }, 0, 0, this);
+    this.sm = PropertyFactory.getProp(elem, data.sm || { k: 100 }, 0, 0, this);
+    this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
+    if (!this.dynamicProperties.length) {
+      this.getValue();
+    }
+  }
+
+  TextSelectorPropFactory.prototype = {
+    getMult: function (ind) {
+      if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
+        this.getValue();
+      }
+      var x1 = 0;
+      var y1 = 0;
+      var x2 = 1;
+      var y2 = 1;
+      if (this.ne.v > 0) {
+        x1 = this.ne.v / 100.0;
+      } else {
+        y1 = -this.ne.v / 100.0;
+      }
+      if (this.xe.v > 0) {
+        x2 = 1.0 - this.xe.v / 100.0;
+      } else {
+        y2 = 1.0 + this.xe.v / 100.0;
+      }
+      var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
+
+      var mult = 0;
+      var s = this.finalS;
+      var e = this.finalE;
+      var type = this.data.sh;
+      if (type === 2) {
+        if (e === s) {
+          mult = ind >= e ? 1 : 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+        mult = easer(mult);
+      } else if (type === 3) {
+        if (e === s) {
+          mult = ind >= e ? 0 : 1;
+        } else {
+          mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+
+        mult = easer(mult);
+      } else if (type === 4) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+          if (mult < 0.5) {
+            mult *= 2;
+          } else {
+            mult = 1 - 2 * (mult - 0.5);
+          }
+        }
+        mult = easer(mult);
+      } else if (type === 5) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          var tot = e - s;
+          /* ind += 0.5;
+                    mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          var x = -tot / 2 + ind;
+          var a = tot / 2;
+          mult = Math.sqrt(1 - (x * x) / (a * a));
+        }
+        mult = easer(mult);
+      } else if (type === 6) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; // eslint-disable-line
+        }
+        mult = easer(mult);
+      } else {
+        if (ind >= floor(s)) {
+          if (ind - s < 0) {
+            mult = max(0, min(min(e, 1) - (s - ind), 1));
+          } else {
+            mult = max(0, min(e - ind, 1));
+          }
+        }
+        mult = easer(mult);
+      }
+      // Smoothness implementation.
+      // The smoothness represents a reduced range of the original [0; 1] range.
+      // if smoothness is 25%, the new range will be [0.375; 0.625]
+      // Steps are:
+      // - find the lower value of the new range (threshold)
+      // - if multiplier is smaller than that value, floor it to 0
+      // - if it is larger,
+      //     - subtract the threshold
+      //     - divide it by the smoothness (this will return the range to [0; 1])
+      // Note: If it doesn't work on some scenarios, consider applying it before the easer.
+      if (this.sm.v !== 100) {
+        var smoothness = this.sm.v * 0.01;
+        if (smoothness === 0) {
+          smoothness = 0.00000001;
+        }
+        var threshold = 0.5 - smoothness * 0.5;
+        if (mult < threshold) {
+          mult = 0;
+        } else {
+          mult = (mult - threshold) / smoothness;
+          if (mult > 1) {
+            mult = 1;
+          }
+        }
+      }
+      return mult * this.a.v;
+    },
+    getValue: function (newCharsFlag) {
+      this.iterateDynamicProperties();
+      this._mdf = newCharsFlag || this._mdf;
+      this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
+      if (newCharsFlag && this.data.r === 2) {
+        this.e.v = this._currentTextLength;
+      }
+      var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
+      var o = this.o.v / divisor;
+      var s = this.s.v / divisor + o;
+      var e = (this.e.v / divisor) + o;
+      if (s > e) {
+        var _s = s;
+        s = e;
+        e = _s;
+      }
+      this.finalS = s;
+      this.finalE = e;
+    },
+  };
+  extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
+
+  function getTextSelectorProp(elem, data, arr) {
+    return new TextSelectorPropFactory(elem, data, arr);
+  }
+
+  return {
+    getTextSelectorProp: getTextSelectorProp,
+  };
+}());
+
+function TextAnimatorDataProperty(elem, animatorProps, container) {
+  var defaultData = { propType: false };
+  var getProp = PropertyFactory.getProp;
+  var textAnimatorAnimatables = animatorProps.a;
+  this.a = {
+    r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData,
+    rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData,
+    ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData,
+    sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData,
+    sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData,
+    s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData,
+    a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData,
+    o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData,
+    p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData,
+    sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData,
+    sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData,
+    fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData,
+    fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData,
+    fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData,
+    fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData,
+    t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData,
+  };
+
+  this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container);
+  this.s.t = animatorProps.s.t;
+}
+
+function TextAnimatorProperty(textData, renderType, elem) {
+  this._isFirstFrame = true;
+  this._hasMaskedPath = false;
+  this._frameId = -1;
+  this._textData = textData;
+  this._renderType = renderType;
+  this._elem = elem;
+  this._animatorsData = createSizedArray(this._textData.a.length);
+  this._pathData = {};
+  this._moreOptions = {
+    alignment: {},
+  };
+  this.renderedLetters = [];
+  this.lettersChangedFlag = false;
+  this.initDynamicPropertyContainer(elem);
+}
+
+TextAnimatorProperty.prototype.searchProperties = function () {
+  var i;
+  var len = this._textData.a.length;
+  var animatorProps;
+  var getProp = PropertyFactory.getProp;
+  for (i = 0; i < len; i += 1) {
+    animatorProps = this._textData.a[i];
+    this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
+  }
+  if (this._textData.p && 'm' in this._textData.p) {
+    this._pathData = {
+      a: getProp(this._elem, this._textData.p.a, 0, 0, this),
+      f: getProp(this._elem, this._textData.p.f, 0, 0, this),
+      l: getProp(this._elem, this._textData.p.l, 0, 0, this),
+      r: getProp(this._elem, this._textData.p.r, 0, 0, this),
+      p: getProp(this._elem, this._textData.p.p, 0, 0, this),
+      m: this._elem.maskManager.getMaskProperty(this._textData.p.m),
+    };
+    this._hasMaskedPath = true;
+  } else {
+    this._hasMaskedPath = false;
+  }
+  this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
+};
+
+TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
+  this.lettersChangedFlag = lettersChangedFlag;
+  if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
+    return;
+  }
+  this._isFirstFrame = false;
+  var alignment = this._moreOptions.alignment.v;
+  var animators = this._animatorsData;
+  var textData = this._textData;
+  var matrixHelper = this.mHelper;
+  var renderType = this._renderType;
+  var renderedLettersCount = this.renderedLetters.length;
+  var xPos;
+  var yPos;
+  var i;
+  var len;
+  var letters = documentData.l;
+  var pathInfo;
+  var currentLength;
+  var currentPoint;
+  var segmentLength;
+  var flag;
+  var pointInd;
+  var segmentInd;
+  var prevPoint;
+  var points;
+  var segments;
+  var partialLength;
+  var totalLength;
+  var perc;
+  var tanAngle;
+  var mask;
+  if (this._hasMaskedPath) {
+    mask = this._pathData.m;
+    if (!this._pathData.n || this._pathData._mdf) {
+      var paths = mask.v;
+      if (this._pathData.r.v) {
+        paths = paths.reverse();
+      }
+      // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
+      pathInfo = {
+        tLength: 0,
+        segments: [],
+      };
+      len = paths._length - 1;
+      var bezierData;
+      totalLength = 0;
+      for (i = 0; i < len; i += 1) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[i + 1],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      i = len;
+      if (mask.v.c) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[0],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      this._pathData.pi = pathInfo;
+    }
+    pathInfo = this._pathData.pi;
+
+    currentLength = this._pathData.f.v;
+    segmentInd = 0;
+    pointInd = 1;
+    segmentLength = 0;
+    flag = true;
+    segments = pathInfo.segments;
+    if (currentLength < 0 && mask.v.c) {
+      if (pathInfo.tLength < Math.abs(currentLength)) {
+        currentLength = -Math.abs(currentLength) % pathInfo.tLength;
+      }
+      segmentInd = segments.length - 1;
+      points = segments[segmentInd].points;
+      pointInd = points.length - 1;
+      while (currentLength < 0) {
+        currentLength += points[pointInd].partialLength;
+        pointInd -= 1;
+        if (pointInd < 0) {
+          segmentInd -= 1;
+          points = segments[segmentInd].points;
+          pointInd = points.length - 1;
+        }
+      }
+    }
+    points = segments[segmentInd].points;
+    prevPoint = points[pointInd - 1];
+    currentPoint = points[pointInd];
+    partialLength = currentPoint.partialLength;
+  }
+
+  len = letters.length;
+  xPos = 0;
+  yPos = 0;
+  var yOff = documentData.finalSize * 1.2 * 0.714;
+  var firstLine = true;
+  var animatorProps;
+  var animatorSelector;
+  var j;
+  var jLen;
+  var letterValue;
+
+  jLen = animators.length;
+
+  var mult;
+  var ind = -1;
+  var offf;
+  var xPathPos;
+  var yPathPos;
+  var initPathPos = currentLength;
+  var initSegmentInd = segmentInd;
+  var initPointInd = pointInd;
+  var currentLine = -1;
+  var elemOpacity;
+  var sc;
+  var sw;
+  var fc;
+  var k;
+  var letterSw;
+  var letterSc;
+  var letterFc;
+  var letterM = '';
+  var letterP = this.defaultPropsArray;
+  var letterO;
+
+  //
+  if (documentData.j === 2 || documentData.j === 1) {
+    var animatorJustifyOffset = 0;
+    var animatorFirstCharOffset = 0;
+    var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
+    var lastIndex = 0;
+    var isNewLine = true;
+
+    for (i = 0; i < len; i += 1) {
+      if (letters[i].n) {
+        if (animatorJustifyOffset) {
+          animatorJustifyOffset += animatorFirstCharOffset;
+        }
+        while (lastIndex < i) {
+          letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+          lastIndex += 1;
+        }
+        animatorJustifyOffset = 0;
+        isNewLine = true;
+      } else {
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.t.propType) {
+            if (isNewLine && documentData.j === 2) {
+              animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
+            }
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
+            } else {
+              animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult;
+            }
+          }
+        }
+        isNewLine = false;
+      }
+    }
+    if (animatorJustifyOffset) {
+      animatorJustifyOffset += animatorFirstCharOffset;
+    }
+    while (lastIndex < i) {
+      letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+      lastIndex += 1;
+    }
+  }
+  //
+
+  for (i = 0; i < len; i += 1) {
+    matrixHelper.reset();
+    elemOpacity = 1;
+    if (letters[i].n) {
+      xPos = 0;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      currentLength = initPathPos;
+      firstLine = false;
+      if (this._hasMaskedPath) {
+        segmentInd = initSegmentInd;
+        pointInd = initPointInd;
+        points = segments[segmentInd].points;
+        prevPoint = points[pointInd - 1];
+        currentPoint = points[pointInd];
+        partialLength = currentPoint.partialLength;
+        segmentLength = 0;
+      }
+      letterM = '';
+      letterFc = '';
+      letterSw = '';
+      letterO = '';
+      letterP = this.defaultPropsArray;
+    } else {
+      if (this._hasMaskedPath) {
+        if (currentLine !== letters[i].line) {
+          switch (documentData.j) {
+            case 1:
+              currentLength += totalLength - documentData.lineWidths[letters[i].line];
+              break;
+            case 2:
+              currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
+              break;
+            default:
+              break;
+          }
+          currentLine = letters[i].line;
+        }
+        if (ind !== letters[i].ind) {
+          if (letters[ind]) {
+            currentLength += letters[ind].extra;
+          }
+          currentLength += letters[i].an / 2;
+          ind = letters[i].ind;
+        }
+        currentLength += (alignment[0] * letters[i].an) * 0.005;
+        var animatorOffset = 0;
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.p.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.p.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.p.v[0] * mult;
+            }
+          }
+          if (animatorProps.a.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.a.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.a.v[0] * mult;
+            }
+          }
+        }
+        flag = true;
+        // Force alignment only works with a single line for now
+        if (this._pathData.a.v) {
+          currentLength = letters[0].an * 0.5 + ((totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind) / (len - 1);
+          currentLength += this._pathData.f.v;
+        }
+        while (flag) {
+          if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
+            perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
+            xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
+            yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
+            matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, -(alignment[1] * yOff) * 0.01);
+            flag = false;
+          } else if (points) {
+            segmentLength += currentPoint.partialLength;
+            pointInd += 1;
+            if (pointInd >= points.length) {
+              pointInd = 0;
+              segmentInd += 1;
+              if (!segments[segmentInd]) {
+                if (mask.v.c) {
+                  pointInd = 0;
+                  segmentInd = 0;
+                  points = segments[segmentInd].points;
+                } else {
+                  segmentLength -= currentPoint.partialLength;
+                  points = null;
+                }
+              } else {
+                points = segments[segmentInd].points;
+              }
+            }
+            if (points) {
+              prevPoint = currentPoint;
+              currentPoint = points[pointInd];
+              partialLength = currentPoint.partialLength;
+            }
+          }
+        }
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+      } else {
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+
+        // Grouping alignment
+        matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, (-alignment[1] * yOff) * 0.01, 0);
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.t.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
+          if (xPos !== 0 || documentData.j !== 0) {
+            if (this._hasMaskedPath) {
+              if (mult.length) {
+                currentLength += animatorProps.t.v * mult[0];
+              } else {
+                currentLength += animatorProps.t.v * mult;
+              }
+            } else if (mult.length) {
+              xPos += animatorProps.t.v * mult[0];
+            } else {
+              xPos += animatorProps.t.v * mult;
+            }
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        sw = documentData.sw || 0;
+      }
+      if (documentData.strokeColorAnim) {
+        if (documentData.sc) {
+          sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
+        } else {
+          sc = [0, 0, 0];
+        }
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.a.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+
+          if (mult.length) {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.s.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (mult.length) {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult[0]), 1 + ((animatorProps.s.v[1] - 1) * mult[1]), 1);
+          } else {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult), 1 + ((animatorProps.s.v[1] - 1) * mult), 1);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        animatorSelector = animators[j].s;
+        mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+        if (animatorProps.sk.propType) {
+          if (mult.length) {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
+          } else {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
+          }
+        }
+        if (animatorProps.r.propType) {
+          if (mult.length) {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
+          } else {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult);
+          }
+        }
+        if (animatorProps.ry.propType) {
+          if (mult.length) {
+            matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
+          } else {
+            matrixHelper.rotateY(animatorProps.ry.v * mult);
+          }
+        }
+        if (animatorProps.rx.propType) {
+          if (mult.length) {
+            matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
+          } else {
+            matrixHelper.rotateX(animatorProps.rx.v * mult);
+          }
+        }
+        if (animatorProps.o.propType) {
+          if (mult.length) {
+            elemOpacity += ((animatorProps.o.v) * mult[0] - elemOpacity) * mult[0];
+          } else {
+            elemOpacity += ((animatorProps.o.v) * mult - elemOpacity) * mult;
+          }
+        }
+        if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
+          if (mult.length) {
+            sw += animatorProps.sw.v * mult[0];
+          } else {
+            sw += animatorProps.sw.v * mult;
+          }
+        }
+        if (documentData.strokeColorAnim && animatorProps.sc.propType) {
+          for (k = 0; k < 3; k += 1) {
+            if (mult.length) {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0];
+            } else {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult;
+            }
+          }
+        }
+        if (documentData.fillColorAnim && documentData.fc) {
+          if (animatorProps.fc.propType) {
+            for (k = 0; k < 3; k += 1) {
+              if (mult.length) {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0];
+              } else {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult;
+              }
+            }
+          }
+          if (animatorProps.fh.propType) {
+            if (mult.length) {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
+            } else {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult);
+            }
+          }
+          if (animatorProps.fs.propType) {
+            if (mult.length) {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
+            } else {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
+            }
+          }
+          if (animatorProps.fb.propType) {
+            if (mult.length) {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
+            } else {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult);
+            }
+          }
+        }
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+
+        if (animatorProps.p.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (this._hasMaskedPath) {
+            if (mult.length) {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
+            } else {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+            }
+          } else if (mult.length) {
+            matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        letterSw = sw < 0 ? 0 : sw;
+      }
+      if (documentData.strokeColorAnim) {
+        letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
+      }
+
+      if (this._hasMaskedPath) {
+        matrixHelper.translate(0, -documentData.ls);
+
+        matrixHelper.translate(0, (alignment[1] * yOff) * 0.01 + yPos, 0);
+        if (this._pathData.p.v) {
+          tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
+          var rot = (Math.atan(tanAngle) * 180) / Math.PI;
+          if (currentPoint.point[0] < prevPoint.point[0]) {
+            rot += 180;
+          }
+          matrixHelper.rotate((-rot * Math.PI) / 180);
+        }
+        matrixHelper.translate(xPathPos, yPathPos, 0);
+        currentLength -= (alignment[0] * letters[i].an) * 0.005;
+        if (letters[i + 1] && ind !== letters[i + 1].ind) {
+          currentLength += letters[i].an / 2;
+          currentLength += (documentData.tr * 0.001) * documentData.finalSize;
+        }
+      } else {
+        matrixHelper.translate(xPos, yPos, 0);
+
+        if (documentData.ps) {
+          // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
+          matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+        }
+        switch (documentData.j) {
+          case 1:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
+            break;
+          case 2:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
+            break;
+          default:
+            break;
+        }
+        matrixHelper.translate(0, -documentData.ls);
+        matrixHelper.translate(offf, 0, 0);
+        matrixHelper.translate((alignment[0] * letters[i].an) * 0.005, (alignment[1] * yOff) * 0.01, 0);
+        xPos += letters[i].l + (documentData.tr * 0.001) * documentData.finalSize;
+      }
+      if (renderType === 'html') {
+        letterM = matrixHelper.toCSS();
+      } else if (renderType === 'svg') {
+        letterM = matrixHelper.to2dCSS();
+      } else {
+        letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
+      }
+      letterO = elemOpacity;
+    }
+
+    if (renderedLettersCount <= i) {
+      letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
+      this.renderedLetters.push(letterValue);
+      renderedLettersCount += 1;
+      this.lettersChangedFlag = true;
+    } else {
+      letterValue = this.renderedLetters[i];
+      this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag;
+    }
+  }
+};
+
+TextAnimatorProperty.prototype.getValue = function () {
+  if (this._elem.globalData.frameId === this._frameId) {
+    return;
+  }
+  this._frameId = this._elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+TextAnimatorProperty.prototype.mHelper = new Matrix();
+TextAnimatorProperty.prototype.defaultPropsArray = [];
+extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
+
+function ITextElement() {
+}
+
+ITextElement.prototype.initElement = function (data, globalData, comp) {
+  this.lettersChangedFlag = true;
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.textProperty = new TextProperty(this, data.t, this.dynamicProperties);
+  this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this);
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+  this.initRenderable();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  this.createContent();
+  this.hide();
+  this.textAnimator.searchProperties(this.dynamicProperties);
+};
+
+ITextElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+};
+
+ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
+  var j;
+  var jLen = shapes.length;
+  var pathNodes;
+  var shapeStr = '';
+  for (j = 0; j < jLen; j += 1) {
+    if (shapes[j].ty === 'sh') {
+      pathNodes = shapes[j].ks.k;
+      shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
+    }
+  }
+  return shapeStr;
+};
+
+ITextElement.prototype.updateDocumentData = function (newData, index) {
+  this.textProperty.updateDocumentData(newData, index);
+};
+
+ITextElement.prototype.canResizeFont = function (_canResize) {
+  this.textProperty.canResizeFont(_canResize);
+};
+
+ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
+  this.textProperty.setMinimumFontSize(_fontSize);
+};
+
+ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
+  if (documentData.ps) {
+    matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+  }
+  matrixHelper.translate(0, -documentData.ls, 0);
+  switch (documentData.j) {
+    case 1:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
+      break;
+    case 2:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
+      break;
+    default:
+      break;
+  }
+  matrixHelper.translate(xPos, yPos, 0);
+};
+
+ITextElement.prototype.buildColor = function (colorData) {
+  return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
+};
+
+ITextElement.prototype.emptyProp = new LetterProps();
+
+ITextElement.prototype.destroy = function () {
+
+};
+
+ITextElement.prototype.validateText = function () {
+  if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
+    this.buildNewText();
+    this.textProperty._isFirstFrame = false;
+    this.textProperty._mdf = false;
+  }
+};
+
+var emptyShapeData = {
+  shapes: [],
+};
+
+function SVGTextLottieElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.renderType = 'svg';
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
+
+SVGTextLottieElement.prototype.createContent = function () {
+  if (this.data.singleShape && !this.globalData.fontManager.chars) {
+    this.textContainer = createNS('text');
+  }
+};
+
+SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
+  var i = 0;
+  var len = textArray.length;
+  var textContents = [];
+  var currentTextContent = '';
+  while (i < len) {
+    if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
+      textContents.push(currentTextContent);
+      currentTextContent = '';
+    } else {
+      currentTextContent += textArray[i];
+    }
+    i += 1;
+  }
+  textContents.push(currentTextContent);
+  return textContents;
+};
+
+SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
+  // data should probably be cloned to apply scale separately to each instance of a text on different layers
+  // but since text internal content gets only rendered once and then it's never rerendered,
+  // it's probably safe not to clone data and reuse always the same instance even if the object is mutated.
+  // Avoiding cloning is preferred since cloning each character shape data is expensive
+  if (data.shapes && data.shapes.length) {
+    var shape = data.shapes[0];
+    if (shape.it) {
+      var shapeItem = shape.it[shape.it.length - 1];
+      if (shapeItem.s) {
+        shapeItem.s.k[0] = scale;
+        shapeItem.s.k[1] = scale;
+      }
+    }
+  }
+  return data;
+};
+
+SVGTextLottieElement.prototype.buildNewText = function () {
+  this.addDynamicProperty(this);
+  var i;
+  var len;
+
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
+  if (documentData.fc) {
+    this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
+  } else {
+    this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
+  }
+  if (documentData.sc) {
+    this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
+    this.layerElement.setAttribute('stroke-width', documentData.sw);
+  }
+  this.layerElement.setAttribute('font-size', documentData.finalSize);
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (fontData.fClass) {
+    this.layerElement.setAttribute('class', fontData.fClass);
+  } else {
+    this.layerElement.setAttribute('font-family', fontData.fFamily);
+    var fWeight = documentData.fWeight;
+    var fStyle = documentData.fStyle;
+    this.layerElement.setAttribute('font-style', fStyle);
+    this.layerElement.setAttribute('font-weight', fWeight);
+  }
+  this.layerElement.setAttribute('aria-label', documentData.t);
+
+  var letters = documentData.l || [];
+  var usesGlyphs = !!this.globalData.fontManager.chars;
+  len = letters.length;
+
+  var tSpan;
+  var matrixHelper = this.mHelper;
+  var shapeStr = '';
+  var singleShape = this.data.singleShape;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  if (singleShape && !usesGlyphs && !documentData.sz) {
+    var tElement = this.textContainer;
+    var justify = 'start';
+    switch (documentData.j) {
+      case 1:
+        justify = 'end';
+        break;
+      case 2:
+        justify = 'middle';
+        break;
+      default:
+        justify = 'start';
+        break;
+    }
+    tElement.setAttribute('text-anchor', justify);
+    tElement.setAttribute('letter-spacing', trackingOffset);
+    var textContent = this.buildTextContents(documentData.finalText);
+    len = textContent.length;
+    yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
+    for (i = 0; i < len; i += 1) {
+      tSpan = this.textSpans[i].span || createNS('tspan');
+      tSpan.textContent = textContent[i];
+      tSpan.setAttribute('x', 0);
+      tSpan.setAttribute('y', yPos);
+      tSpan.style.display = 'inherit';
+      tElement.appendChild(tSpan);
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          glyph: null,
+        };
+      }
+      this.textSpans[i].span = tSpan;
+      yPos += documentData.finalLineHeight;
+    }
+
+    this.layerElement.appendChild(tElement);
+  } else {
+    var cachedSpansLength = this.textSpans.length;
+    var charData;
+    for (i = 0; i < len; i += 1) {
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          childSpan: null,
+          glyph: null,
+        };
+      }
+      if (!usesGlyphs || !singleShape || i === 0) {
+        tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
+        if (cachedSpansLength <= i) {
+          tSpan.setAttribute('stroke-linecap', 'butt');
+          tSpan.setAttribute('stroke-linejoin', 'round');
+          tSpan.setAttribute('stroke-miterlimit', '4');
+          this.textSpans[i].span = tSpan;
+          if (usesGlyphs) {
+            var childSpan = createNS('g');
+            tSpan.appendChild(childSpan);
+            this.textSpans[i].childSpan = childSpan;
+          }
+          this.textSpans[i].span = tSpan;
+          this.layerElement.appendChild(tSpan);
+        }
+        tSpan.style.display = 'inherit';
+      }
+
+      matrixHelper.reset();
+      if (singleShape) {
+        if (letters[i].n) {
+          xPos = -trackingOffset;
+          yPos += documentData.yOffset;
+          yPos += firstLine ? 1 : 0;
+          firstLine = false;
+        }
+        this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+        xPos += letters[i].l || 0;
+        // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
+        xPos += trackingOffset;
+      }
+      if (usesGlyphs) {
+        charData = this.globalData.fontManager.getCharData(
+          documentData.finalText[i],
+          fontData.fStyle,
+          this.globalData.fontManager.getFontByName(documentData.f).fFamily
+        );
+        var glyphElement;
+        // t === 1 means the character has been replaced with an animated shaped
+        if (charData.t === 1) {
+          glyphElement = new SVGCompElement(charData.data, this.globalData, this);
+        } else {
+          var data = emptyShapeData;
+          if (charData.data && charData.data.shapes) {
+            data = this.buildShapeData(charData.data, documentData.finalSize);
+          }
+          glyphElement = new SVGShapeElement(data, this.globalData, this);
+        }
+        if (this.textSpans[i].glyph) {
+          var glyph = this.textSpans[i].glyph;
+          this.textSpans[i].childSpan.removeChild(glyph.layerElement);
+          glyph.destroy();
+        }
+        this.textSpans[i].glyph = glyphElement;
+        glyphElement._debug = true;
+        glyphElement.prepareFrame(0);
+        glyphElement.renderFrame();
+        this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+        // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+        // this might have issues with strokes and might need a different solution
+        if (charData.t === 1) {
+          this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
+        }
+      } else {
+        if (singleShape) {
+          tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
+        }
+        tSpan.textContent = letters[i].val;
+        tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      }
+      //
+    }
+    if (singleShape && tSpan) {
+      tSpan.setAttribute('d', shapeStr);
+    }
+  }
+  while (i < this.textSpans.length) {
+    this.textSpans[i].span.style.display = 'none';
+    i += 1;
+  }
+
+  this._sizeChanged = true;
+};
+
+SVGTextLottieElement.prototype.sourceRectAtTime = function () {
+  this.prepareFrame(this.comp.renderedFrame - this.data.st);
+  this.renderInnerContent();
+  if (this._sizeChanged) {
+    this._sizeChanged = false;
+    var textBox = this.layerElement.getBBox();
+    this.bbox = {
+      top: textBox.y,
+      left: textBox.x,
+      width: textBox.width,
+      height: textBox.height,
+    };
+  }
+  return this.bbox;
+};
+
+SVGTextLottieElement.prototype.getValue = function () {
+  var i;
+  var len = this.textSpans.length;
+  var glyphElement;
+  this.renderedFrame = this.comp.renderedFrame;
+  for (i = 0; i < len; i += 1) {
+    glyphElement = this.textSpans[i].glyph;
+    if (glyphElement) {
+      glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
+      if (glyphElement._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+SVGTextLottieElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  if (!this.data.singleShape || this._mdf) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+    if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
+      this._sizeChanged = true;
+      var i;
+      var len;
+      var renderedLetters = this.textAnimator.renderedLetters;
+
+      var letters = this.textProperty.currentData.l;
+
+      len = letters.length;
+      var renderedLetter;
+      var textSpan;
+      var glyphElement;
+      for (i = 0; i < len; i += 1) {
+        if (!letters[i].n) {
+          renderedLetter = renderedLetters[i];
+          textSpan = this.textSpans[i].span;
+          glyphElement = this.textSpans[i].glyph;
+          if (glyphElement) {
+            glyphElement.renderFrame();
+          }
+          if (renderedLetter._mdf.m) {
+            textSpan.setAttribute('transform', renderedLetter.m);
+          }
+          if (renderedLetter._mdf.o) {
+            textSpan.setAttribute('opacity', renderedLetter.o);
+          }
+          if (renderedLetter._mdf.sw) {
+            textSpan.setAttribute('stroke-width', renderedLetter.sw);
+          }
+          if (renderedLetter._mdf.sc) {
+            textSpan.setAttribute('stroke', renderedLetter.sc);
+          }
+          if (renderedLetter._mdf.fc) {
+            textSpan.setAttribute('fill', renderedLetter.fc);
+          }
+        }
+      }
+    }
+  }
+};
+
+function ISolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([IImageElement], ISolidElement);
+
+ISolidElement.prototype.createContent = function () {
+  var rect = createNS('rect');
+  /// /rect.style.width = this.data.sw;
+  /// /rect.style.height = this.data.sh;
+  /// /rect.style.fill = this.data.sc;
+  rect.setAttribute('width', this.data.sw);
+  rect.setAttribute('height', this.data.sh);
+  rect.setAttribute('fill', this.data.sc);
+  this.layerElement.appendChild(rect);
+};
+
+function NullElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initFrame();
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+}
+
+NullElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+NullElement.prototype.renderFrame = function () {
+};
+
+NullElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+NullElement.prototype.destroy = function () {
+};
+
+NullElement.prototype.sourceRectAtTime = function () {
+};
+
+NullElement.prototype.hide = function () {
+};
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
+
+function SVGRendererBase() {
+}
+
+extendPrototype([BaseRenderer], SVGRendererBase);
+
+SVGRendererBase.prototype.createNull = function (data) {
+  return new NullElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createShape = function (data) {
+  return new SVGShapeElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createText = function (data) {
+  return new SVGTextLottieElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createImage = function (data) {
+  return new IImageElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createSolid = function (data) {
+  return new ISolidElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.configAnimation = function (animData) {
+  this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+  this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+  if (this.renderConfig.viewBoxSize) {
+    this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
+  } else {
+    this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
+  }
+
+  if (!this.renderConfig.viewBoxOnly) {
+    this.svgElement.setAttribute('width', animData.w);
+    this.svgElement.setAttribute('height', animData.h);
+    this.svgElement.style.width = '100%';
+    this.svgElement.style.height = '100%';
+    this.svgElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
+  }
+  if (this.renderConfig.width) {
+    this.svgElement.setAttribute('width', this.renderConfig.width);
+  }
+  if (this.renderConfig.height) {
+    this.svgElement.setAttribute('height', this.renderConfig.height);
+  }
+  if (this.renderConfig.className) {
+    this.svgElement.setAttribute('class', this.renderConfig.className);
+  }
+  if (this.renderConfig.id) {
+    this.svgElement.setAttribute('id', this.renderConfig.id);
+  }
+  if (this.renderConfig.focusable !== undefined) {
+    this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
+  }
+  this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+  // this.layerElement.style.transform = 'translate3d(0,0,0)';
+  // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
+  this.animationItem.wrapper.appendChild(this.svgElement);
+  // Mask animation
+  var defs = this.globalData.defs;
+
+  this.setupGlobalData(animData, defs);
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.data = animData;
+
+  var maskElement = createNS('clipPath');
+  var rect = createNS('rect');
+  rect.setAttribute('width', animData.w);
+  rect.setAttribute('height', animData.h);
+  rect.setAttribute('x', 0);
+  rect.setAttribute('y', 0);
+  var maskId = createElementID();
+  maskElement.setAttribute('id', maskId);
+  maskElement.appendChild(rect);
+  this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')');
+
+  defs.appendChild(maskElement);
+  this.layers = animData.layers;
+  this.elements = createSizedArray(animData.layers.length);
+};
+
+SVGRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.layerElement = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+SVGRendererBase.prototype.updateContainerSize = function () {
+};
+
+SVGRendererBase.prototype.findIndexByInd = function (ind) {
+  var i = 0;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.layers[i].ind === ind) {
+      return i;
+    }
+  }
+  return -1;
+};
+
+SVGRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  elements[pos] = true;
+  var element = this.createItem(this.layers[pos]);
+
+  elements[pos] = element;
+  if (getExpressionsPlugin()) {
+    if (this.layers[pos].ty === 0) {
+      this.globalData.projectInterface.registerComposition(element);
+    }
+    element.initExpressions();
+  }
+  this.appendElementInPos(element, pos);
+  if (this.layers[pos].tt) {
+    var elementIndex = ('tp' in this.layers[pos])
+      ? this.findIndexByInd(this.layers[pos].tp)
+      : pos - 1;
+    if (elementIndex === -1) {
+      return;
+    }
+    if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
+      this.buildItem(elementIndex);
+      this.addPendingElement(element);
+    } else {
+      var matteElement = elements[elementIndex];
+      var matteMask = matteElement.getMatte(this.layers[pos].tt);
+      element.setMatte(matteMask);
+    }
+  }
+};
+
+SVGRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+    if (element.data.tt) {
+      var i = 0;
+      var len = this.elements.length;
+      while (i < len) {
+        if (this.elements[i] === element) {
+          var elementIndex = 'tp' in element.data
+            ? this.findIndexByInd(element.data.tp)
+            : i - 1;
+          var matteElement = this.elements[elementIndex];
+          var matteMask = matteElement.getMatte(this.layers[i].tt);
+          element.setMatte(matteMask);
+          break;
+        }
+        i += 1;
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.renderFrame = function (num) {
+  if (this.renderedFrame === num || this.destroyed) {
+    return;
+  }
+  if (num === null) {
+    num = this.renderedFrame;
+  } else {
+    this.renderedFrame = num;
+  }
+  // console.log('-------');
+  // console.log('FRAME ',num);
+  this.globalData.frameNum = num;
+  this.globalData.frameId += 1;
+  this.globalData.projectInterface.currentFrame = num;
+  this.globalData._mdf = false;
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    for (i = 0; i < len; i += 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
+  var newElement = element.getBaseElement();
+  if (!newElement) {
+    return;
+  }
+  var i = 0;
+  var nextElement;
+  while (i < pos) {
+    if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
+      nextElement = this.elements[i].getBaseElement();
+    }
+    i += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(newElement, nextElement);
+  } else {
+    this.layerElement.appendChild(newElement);
+  }
+};
+
+SVGRendererBase.prototype.hide = function () {
+  this.layerElement.style.display = 'none';
+};
+
+SVGRendererBase.prototype.show = function () {
+  this.layerElement.style.display = 'block';
+};
+
+function ICompElement() {}
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
+
+ICompElement.prototype.initElement = function (data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initTransform(data, globalData, comp);
+  this.initRenderable();
+  this.initHierarchy();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  if (this.data.xt || !globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+  this.hide();
+};
+
+/* ICompElement.prototype.hide = function(){
+    if(!this.hidden){
+        this.hideElement();
+        var i,len = this.elements.length;
+        for( i = 0; i < len; i+=1 ){
+            if(this.elements[i]){
+                this.elements[i].hide();
+            }
+        }
+    }
+}; */
+
+ICompElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+  if (!this.isInRange && !this.data.xt) {
+    return;
+  }
+
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    if (timeRemapped === this.data.op) {
+      timeRemapped = this.data.op - 1;
+    }
+    this.renderedFrame = timeRemapped;
+  } else {
+    this.renderedFrame = num / this.data.sr;
+  }
+  var i;
+  var len = this.elements.length;
+  if (!this.completeLayers) {
+    this.checkLayers(this.renderedFrame);
+  }
+  // This iteration needs to be backwards because of how expressions connect between each other
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
+      if (this.elements[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+ICompElement.prototype.renderInnerContent = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+ICompElement.prototype.setElements = function (elems) {
+  this.elements = elems;
+};
+
+ICompElement.prototype.getElements = function () {
+  return this.elements;
+};
+
+ICompElement.prototype.destroyElements = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+};
+
+ICompElement.prototype.destroy = function () {
+  this.destroyElements();
+  this.destroyBaseElement();
+};
+
+function SVGCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = true;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
+
+SVGCompElement.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function SVGRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.layers = null;
+  this.renderedFrame = -1;
+  this.svgElement = createNS('svg');
+  var ariaLabel = '';
+  if (config && config.title) {
+    var titleElement = createNS('title');
+    var titleId = createElementID();
+    titleElement.setAttribute('id', titleId);
+    titleElement.textContent = config.title;
+    this.svgElement.appendChild(titleElement);
+    ariaLabel += titleId;
+  }
+  if (config && config.description) {
+    var descElement = createNS('desc');
+    var descId = createElementID();
+    descElement.setAttribute('id', descId);
+    descElement.textContent = config.description;
+    this.svgElement.appendChild(descElement);
+    ariaLabel += ' ' + descId;
+  }
+  if (ariaLabel) {
+    this.svgElement.setAttribute('aria-labelledby', ariaLabel);
+  }
+  var defs = createNS('defs');
+  this.svgElement.appendChild(defs);
+  var maskElement = createNS('g');
+  this.svgElement.appendChild(maskElement);
+  this.layerElement = maskElement;
+  this.renderConfig = {
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    hideOnTransparent: !((config && config.hideOnTransparent === false)),
+    viewBoxOnly: (config && config.viewBoxOnly) || false,
+    viewBoxSize: (config && config.viewBoxSize) || false,
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    focusable: config && config.focusable,
+    filterSize: {
+      width: (config && config.filterSize && config.filterSize.width) || '100%',
+      height: (config && config.filterSize && config.filterSize.height) || '100%',
+      x: (config && config.filterSize && config.filterSize.x) || '0%',
+      y: (config && config.filterSize && config.filterSize.y) || '0%',
+    },
+    width: (config && config.width),
+    height: (config && config.height),
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+
+  this.globalData = {
+    _mdf: false,
+    frameNum: -1,
+    defs: defs,
+    renderConfig: this.renderConfig,
+  };
+  this.elements = [];
+  this.pendingElements = [];
+  this.destroyed = false;
+  this.rendererType = 'svg';
+}
+
+extendPrototype([SVGRendererBase], SVGRenderer);
+
+SVGRenderer.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+var registeredEffects = {};
+
+function CVEffects(elem) {
+  var i;
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects[type]) {
+      var Effect = registeredEffects[type].effect;
+      filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+CVEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+CVEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect(id, effect) {
+  registeredEffects[id] = {
+    effect,
+  };
+}
+
+function HBaseElement() {}
+HBaseElement.prototype = {
+  checkBlendMode: function () {},
+  initRendererElement: function () {
+    this.baseElement = createTag(this.data.tg || 'div');
+    if (this.data.hasMask) {
+      this.svgElement = createNS('svg');
+      this.layerElement = createNS('g');
+      this.maskedElement = this.layerElement;
+      this.svgElement.appendChild(this.layerElement);
+      this.baseElement.appendChild(this.svgElement);
+    } else {
+      this.layerElement = this.baseElement;
+    }
+    styleDiv(this.baseElement);
+  },
+  createContainerElements: function () {
+    this.renderableEffectsManager = new CVEffects(this);
+    this.transformedElement = this.baseElement;
+    this.maskedElement = this.layerElement;
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    var transformedElementStyle = this.transformedElement ? this.transformedElement.style : {};
+    if (this.finalTransform._matMdf) {
+      var matrixValue = this.finalTransform.mat.toCSS();
+      transformedElementStyle.transform = matrixValue;
+      transformedElementStyle.webkitTransform = matrixValue;
+    }
+    if (this.finalTransform._opMdf) {
+      transformedElementStyle.opacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderFrame: function () {
+    // If it is exported as hidden (data.hd === true) no need to render
+    // If it is not visible no need to render
+    if (this.data.hd || this.hidden) {
+      return;
+    }
+    this.renderTransform();
+    this.renderRenderable();
+    this.renderElement();
+    this.renderInnerContent();
+    if (this._isFirstFrame) {
+      this._isFirstFrame = false;
+    }
+  },
+  destroy: function () {
+    this.layerElement = null;
+    this.transformedElement = null;
+    if (this.matteElement) {
+      this.matteElement = null;
+    }
+    if (this.maskManager) {
+      this.maskManager.destroy();
+      this.maskManager = null;
+    }
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+  },
+  addEffects: function () {
+  },
+  setMatte: function () {},
+};
+HBaseElement.prototype.getBaseElement = SVGBaseElement.prototype.getBaseElement;
+HBaseElement.prototype.destroyBaseElement = HBaseElement.prototype.destroy;
+HBaseElement.prototype.buildElementParenting = BaseRenderer.prototype.buildElementParenting;
+
+function HSolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], HSolidElement);
+
+HSolidElement.prototype.createContent = function () {
+  var rect;
+  if (this.data.hasMask) {
+    rect = createNS('rect');
+    rect.setAttribute('width', this.data.sw);
+    rect.setAttribute('height', this.data.sh);
+    rect.setAttribute('fill', this.data.sc);
+    this.svgElement.setAttribute('width', this.data.sw);
+    this.svgElement.setAttribute('height', this.data.sh);
+  } else {
+    rect = createTag('div');
+    rect.style.width = this.data.sw + 'px';
+    rect.style.height = this.data.sh + 'px';
+    rect.style.backgroundColor = this.data.sc;
+  }
+  this.layerElement.appendChild(rect);
+};
+
+function HShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.shapesContainer = createNS('g');
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  this.currentBBox = {
+    x: 999999,
+    y: -999999,
+    h: 0,
+    w: 0,
+  };
+}
+extendPrototype([BaseElement, TransformElement, HSolidElement, SVGShapeElement, HBaseElement, HierarchyElement, FrameElement, RenderableElement], HShapeElement);
+HShapeElement.prototype._renderShapeFrame = HShapeElement.prototype.renderInnerContent;
+
+HShapeElement.prototype.createContent = function () {
+  var cont;
+  this.baseElement.style.fontSize = 0;
+  if (this.data.hasMask) {
+    this.layerElement.appendChild(this.shapesContainer);
+    cont = this.svgElement;
+  } else {
+    cont = createNS('svg');
+    var size = this.comp.data ? this.comp.data : this.globalData.compSize;
+    cont.setAttribute('width', size.w);
+    cont.setAttribute('height', size.h);
+    cont.appendChild(this.shapesContainer);
+    this.layerElement.appendChild(cont);
+  }
+
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.shapesContainer, 0, [], true);
+  this.filterUniqueShapes();
+  this.shapeCont = cont;
+};
+
+HShapeElement.prototype.getTransformedPoint = function (transformers, point) {
+  var i;
+  var len = transformers.length;
+  for (i = 0; i < len; i += 1) {
+    point = transformers[i].mProps.v.applyToPointArray(point[0], point[1], 0);
+  }
+  return point;
+};
+
+HShapeElement.prototype.calculateShapeBoundingBox = function (item, boundingBox) {
+  var shape = item.sh.v;
+  var transformers = item.transformers;
+  var i;
+  var len = shape._length;
+  var vPoint;
+  var oPoint;
+  var nextIPoint;
+  var nextVPoint;
+  if (len <= 1) {
+    return;
+  }
+  for (i = 0; i < len - 1; i += 1) {
+    vPoint = this.getTransformedPoint(transformers, shape.v[i]);
+    oPoint = this.getTransformedPoint(transformers, shape.o[i]);
+    nextIPoint = this.getTransformedPoint(transformers, shape.i[i + 1]);
+    nextVPoint = this.getTransformedPoint(transformers, shape.v[i + 1]);
+    this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
+  }
+  if (shape.c) {
+    vPoint = this.getTransformedPoint(transformers, shape.v[i]);
+    oPoint = this.getTransformedPoint(transformers, shape.o[i]);
+    nextIPoint = this.getTransformedPoint(transformers, shape.i[0]);
+    nextVPoint = this.getTransformedPoint(transformers, shape.v[0]);
+    this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
+  }
+};
+
+HShapeElement.prototype.checkBounds = function (vPoint, oPoint, nextIPoint, nextVPoint, boundingBox) {
+  this.getBoundsOfCurve(vPoint, oPoint, nextIPoint, nextVPoint);
+  var bounds = this.shapeBoundingBox;
+  boundingBox.x = bmMin(bounds.left, boundingBox.x);
+  boundingBox.xMax = bmMax(bounds.right, boundingBox.xMax);
+  boundingBox.y = bmMin(bounds.top, boundingBox.y);
+  boundingBox.yMax = bmMax(bounds.bottom, boundingBox.yMax);
+};
+
+HShapeElement.prototype.shapeBoundingBox = {
+  left: 0,
+  right: 0,
+  top: 0,
+  bottom: 0,
+};
+
+HShapeElement.prototype.tempBoundingBox = {
+  x: 0,
+  xMax: 0,
+  y: 0,
+  yMax: 0,
+  width: 0,
+  height: 0,
+};
+
+HShapeElement.prototype.getBoundsOfCurve = function (p0, p1, p2, p3) {
+  var bounds = [[p0[0], p3[0]], [p0[1], p3[1]]];
+
+  for (var a, b, c, t, b2ac, t1, t2, i = 0; i < 2; ++i) { // eslint-disable-line no-plusplus
+    b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];
+    a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];
+    c = 3 * p1[i] - 3 * p0[i];
+
+    b |= 0; // eslint-disable-line no-bitwise
+    a |= 0; // eslint-disable-line no-bitwise
+    c |= 0; // eslint-disable-line no-bitwise
+
+    if (a === 0 && b === 0) {
+      //
+    } else if (a === 0) {
+      t = -c / b;
+
+      if (t > 0 && t < 1) {
+        bounds[i].push(this.calculateF(t, p0, p1, p2, p3, i));
+      }
+    } else {
+      b2ac = b * b - 4 * c * a;
+
+      if (b2ac >= 0) {
+        t1 = (-b + bmSqrt(b2ac)) / (2 * a);
+        if (t1 > 0 && t1 < 1) bounds[i].push(this.calculateF(t1, p0, p1, p2, p3, i));
+        t2 = (-b - bmSqrt(b2ac)) / (2 * a);
+        if (t2 > 0 && t2 < 1) bounds[i].push(this.calculateF(t2, p0, p1, p2, p3, i));
+      }
+    }
+  }
+
+  this.shapeBoundingBox.left = bmMin.apply(null, bounds[0]);
+  this.shapeBoundingBox.top = bmMin.apply(null, bounds[1]);
+  this.shapeBoundingBox.right = bmMax.apply(null, bounds[0]);
+  this.shapeBoundingBox.bottom = bmMax.apply(null, bounds[1]);
+};
+
+HShapeElement.prototype.calculateF = function (t, p0, p1, p2, p3, i) {
+  return bmPow(1 - t, 3) * p0[i]
+        + 3 * bmPow(1 - t, 2) * t * p1[i]
+        + 3 * (1 - t) * bmPow(t, 2) * p2[i]
+        + bmPow(t, 3) * p3[i];
+};
+
+HShapeElement.prototype.calculateBoundingBox = function (itemsData, boundingBox) {
+  var i;
+  var len = itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    if (itemsData[i] && itemsData[i].sh) {
+      this.calculateShapeBoundingBox(itemsData[i], boundingBox);
+    } else if (itemsData[i] && itemsData[i].it) {
+      this.calculateBoundingBox(itemsData[i].it, boundingBox);
+    } else if (itemsData[i] && itemsData[i].style && itemsData[i].w) {
+      this.expandStrokeBoundingBox(itemsData[i].w, boundingBox);
+    }
+  }
+};
+
+HShapeElement.prototype.expandStrokeBoundingBox = function (widthProperty, boundingBox) {
+  var width = 0;
+  if (widthProperty.keyframes) {
+    for (var i = 0; i < widthProperty.keyframes.length; i += 1) {
+      var kfw = widthProperty.keyframes[i].s;
+      if (kfw > width) {
+        width = kfw;
+      }
+    }
+    width *= widthProperty.mult;
+  } else {
+    width = widthProperty.v * widthProperty.mult;
+  }
+
+  boundingBox.x -= width;
+  boundingBox.xMax += width;
+  boundingBox.y -= width;
+  boundingBox.yMax += width;
+};
+
+HShapeElement.prototype.currentBoxContains = function (box) {
+  return this.currentBBox.x <= box.x
+    && this.currentBBox.y <= box.y
+    && this.currentBBox.width + this.currentBBox.x >= box.x + box.width
+    && this.currentBBox.height + this.currentBBox.y >= box.y + box.height;
+};
+
+HShapeElement.prototype.renderInnerContent = function () {
+  this._renderShapeFrame();
+
+  if (!this.hidden && (this._isFirstFrame || this._mdf)) {
+    var tempBoundingBox = this.tempBoundingBox;
+    var max = 999999;
+    tempBoundingBox.x = max;
+    tempBoundingBox.xMax = -max;
+    tempBoundingBox.y = max;
+    tempBoundingBox.yMax = -max;
+    this.calculateBoundingBox(this.itemsData, tempBoundingBox);
+    tempBoundingBox.width = tempBoundingBox.xMax < tempBoundingBox.x ? 0 : tempBoundingBox.xMax - tempBoundingBox.x;
+    tempBoundingBox.height = tempBoundingBox.yMax < tempBoundingBox.y ? 0 : tempBoundingBox.yMax - tempBoundingBox.y;
+    // var tempBoundingBox = this.shapeCont.getBBox();
+    if (this.currentBoxContains(tempBoundingBox)) {
+      return;
+    }
+    var changed = false;
+    if (this.currentBBox.w !== tempBoundingBox.width) {
+      this.currentBBox.w = tempBoundingBox.width;
+      this.shapeCont.setAttribute('width', tempBoundingBox.width);
+      changed = true;
+    }
+    if (this.currentBBox.h !== tempBoundingBox.height) {
+      this.currentBBox.h = tempBoundingBox.height;
+      this.shapeCont.setAttribute('height', tempBoundingBox.height);
+      changed = true;
+    }
+    if (changed || this.currentBBox.x !== tempBoundingBox.x || this.currentBBox.y !== tempBoundingBox.y) {
+      this.currentBBox.w = tempBoundingBox.width;
+      this.currentBBox.h = tempBoundingBox.height;
+      this.currentBBox.x = tempBoundingBox.x;
+      this.currentBBox.y = tempBoundingBox.y;
+
+      this.shapeCont.setAttribute('viewBox', this.currentBBox.x + ' ' + this.currentBBox.y + ' ' + this.currentBBox.w + ' ' + this.currentBBox.h);
+      var shapeStyle = this.shapeCont.style;
+      var shapeTransform = 'translate(' + this.currentBBox.x + 'px,' + this.currentBBox.y + 'px)';
+      shapeStyle.transform = shapeTransform;
+      shapeStyle.webkitTransform = shapeTransform;
+    }
+  }
+};
+
+function HTextElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.textPaths = [];
+  this.currentBBox = {
+    x: 999999,
+    y: -999999,
+    h: 0,
+    w: 0,
+  };
+  this.renderType = 'svg';
+  this.isMasked = false;
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], HTextElement);
+
+HTextElement.prototype.createContent = function () {
+  this.isMasked = this.checkMasks();
+  if (this.isMasked) {
+    this.renderType = 'svg';
+    this.compW = this.comp.data.w;
+    this.compH = this.comp.data.h;
+    this.svgElement.setAttribute('width', this.compW);
+    this.svgElement.setAttribute('height', this.compH);
+    var g = createNS('g');
+    this.maskedElement.appendChild(g);
+    this.innerElem = g;
+  } else {
+    this.renderType = 'html';
+    this.innerElem = this.layerElement;
+  }
+
+  this.checkParenting();
+};
+
+HTextElement.prototype.buildNewText = function () {
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
+  var innerElemStyle = this.innerElem.style;
+  var textColor = documentData.fc ? this.buildColor(documentData.fc) : 'rgba(0,0,0,0)';
+  innerElemStyle.fill = textColor;
+  innerElemStyle.color = textColor;
+  if (documentData.sc) {
+    innerElemStyle.stroke = this.buildColor(documentData.sc);
+    innerElemStyle.strokeWidth = documentData.sw + 'px';
+  }
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (!this.globalData.fontManager.chars) {
+    innerElemStyle.fontSize = documentData.finalSize + 'px';
+    innerElemStyle.lineHeight = documentData.finalSize + 'px';
+    if (fontData.fClass) {
+      this.innerElem.className = fontData.fClass;
+    } else {
+      innerElemStyle.fontFamily = fontData.fFamily;
+      var fWeight = documentData.fWeight;
+      var fStyle = documentData.fStyle;
+      innerElemStyle.fontStyle = fStyle;
+      innerElemStyle.fontWeight = fWeight;
+    }
+  }
+  var i;
+  var len;
+
+  var letters = documentData.l;
+  len = letters.length;
+  var tSpan;
+  var tParent;
+  var tCont;
+  var matrixHelper = this.mHelper;
+  var shapes;
+  var shapeStr = '';
+  var cnt = 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.globalData.fontManager.chars) {
+      if (!this.textPaths[cnt]) {
+        tSpan = createNS('path');
+        tSpan.setAttribute('stroke-linecap', lineCapEnum[1]);
+        tSpan.setAttribute('stroke-linejoin', lineJoinEnum[2]);
+        tSpan.setAttribute('stroke-miterlimit', '4');
+      } else {
+        tSpan = this.textPaths[cnt];
+      }
+      if (!this.isMasked) {
+        if (this.textSpans[cnt]) {
+          tParent = this.textSpans[cnt];
+          tCont = tParent.children[0];
+        } else {
+          tParent = createTag('div');
+          tParent.style.lineHeight = 0;
+          tCont = createNS('svg');
+          tCont.appendChild(tSpan);
+          styleDiv(tParent);
+        }
+      }
+    } else if (!this.isMasked) {
+      if (this.textSpans[cnt]) {
+        tParent = this.textSpans[cnt];
+        tSpan = this.textPaths[cnt];
+      } else {
+        tParent = createTag('span');
+        styleDiv(tParent);
+        tSpan = createTag('span');
+        styleDiv(tSpan);
+        tParent.appendChild(tSpan);
+      }
+    } else {
+      tSpan = this.textPaths[cnt] ? this.textPaths[cnt] : createNS('text');
+    }
+    // tSpan.setAttribute('visibility', 'hidden');
+    if (this.globalData.fontManager.chars) {
+      var charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
+      var shapeData;
+      if (charData) {
+        shapeData = charData.data;
+      } else {
+        shapeData = null;
+      }
+      matrixHelper.reset();
+      if (shapeData && shapeData.shapes && shapeData.shapes.length) {
+        shapes = shapeData.shapes[0].it;
+        matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
+        shapeStr = this.createPathShape(matrixHelper, shapes);
+        tSpan.setAttribute('d', shapeStr);
+      }
+      if (!this.isMasked) {
+        this.innerElem.appendChild(tParent);
+        if (shapeData && shapeData.shapes) {
+          // document.body.appendChild is needed to get exact measure of shape
+          document.body.appendChild(tCont);
+          var boundingBox = tCont.getBBox();
+          tCont.setAttribute('width', boundingBox.width + 2);
+          tCont.setAttribute('height', boundingBox.height + 2);
+          tCont.setAttribute('viewBox', (boundingBox.x - 1) + ' ' + (boundingBox.y - 1) + ' ' + (boundingBox.width + 2) + ' ' + (boundingBox.height + 2));
+          var tContStyle = tCont.style;
+          var tContTranslation = 'translate(' + (boundingBox.x - 1) + 'px,' + (boundingBox.y - 1) + 'px)';
+          tContStyle.transform = tContTranslation;
+          tContStyle.webkitTransform = tContTranslation;
+
+          letters[i].yOffset = boundingBox.y - 1;
+        } else {
+          tCont.setAttribute('width', 1);
+          tCont.setAttribute('height', 1);
+        }
+        tParent.appendChild(tCont);
+      } else {
+        this.innerElem.appendChild(tSpan);
+      }
+    } else {
+      tSpan.textContent = letters[i].val;
+      tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      if (!this.isMasked) {
+        this.innerElem.appendChild(tParent);
+        //
+        var tStyle = tSpan.style;
+        var tSpanTranslation = 'translate3d(0,' + -documentData.finalSize / 1.2 + 'px,0)';
+        tStyle.transform = tSpanTranslation;
+        tStyle.webkitTransform = tSpanTranslation;
+      } else {
+        this.innerElem.appendChild(tSpan);
+      }
+    }
+    //
+    if (!this.isMasked) {
+      this.textSpans[cnt] = tParent;
+    } else {
+      this.textSpans[cnt] = tSpan;
+    }
+    this.textSpans[cnt].style.display = 'block';
+    this.textPaths[cnt] = tSpan;
+    cnt += 1;
+  }
+  while (cnt < this.textSpans.length) {
+    this.textSpans[cnt].style.display = 'none';
+    cnt += 1;
+  }
+};
+
+HTextElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  var svgStyle;
+  if (this.data.singleShape) {
+    if (!this._isFirstFrame && !this.lettersChangedFlag) {
+      return;
+    } if (this.isMasked && this.finalTransform._matMdf) {
+      // Todo Benchmark if using this is better than getBBox
+      this.svgElement.setAttribute('viewBox', -this.finalTransform.mProp.p.v[0] + ' ' + -this.finalTransform.mProp.p.v[1] + ' ' + this.compW + ' ' + this.compH);
+      svgStyle = this.svgElement.style;
+      var translation = 'translate(' + -this.finalTransform.mProp.p.v[0] + 'px,' + -this.finalTransform.mProp.p.v[1] + 'px)';
+      svgStyle.transform = translation;
+      svgStyle.webkitTransform = translation;
+    }
+  }
+
+  this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+  if (!this.lettersChangedFlag && !this.textAnimator.lettersChangedFlag) {
+    return;
+  }
+  var i;
+  var len;
+  var count = 0;
+  var renderedLetters = this.textAnimator.renderedLetters;
+
+  var letters = this.textProperty.currentData.l;
+
+  len = letters.length;
+  var renderedLetter;
+  var textSpan;
+  var textPath;
+  for (i = 0; i < len; i += 1) {
+    if (letters[i].n) {
+      count += 1;
+    } else {
+      textSpan = this.textSpans[i];
+      textPath = this.textPaths[i];
+      renderedLetter = renderedLetters[count];
+      count += 1;
+      if (renderedLetter._mdf.m) {
+        if (!this.isMasked) {
+          textSpan.style.webkitTransform = renderedLetter.m;
+          textSpan.style.transform = renderedLetter.m;
+        } else {
+          textSpan.setAttribute('transform', renderedLetter.m);
+        }
+      }
+      /// /textSpan.setAttribute('opacity',renderedLetter.o);
+      textSpan.style.opacity = renderedLetter.o;
+      if (renderedLetter.sw && renderedLetter._mdf.sw) {
+        textPath.setAttribute('stroke-width', renderedLetter.sw);
+      }
+      if (renderedLetter.sc && renderedLetter._mdf.sc) {
+        textPath.setAttribute('stroke', renderedLetter.sc);
+      }
+      if (renderedLetter.fc && renderedLetter._mdf.fc) {
+        textPath.setAttribute('fill', renderedLetter.fc);
+        textPath.style.color = renderedLetter.fc;
+      }
+    }
+  }
+
+  if (this.innerElem.getBBox && !this.hidden && (this._isFirstFrame || this._mdf)) {
+    var boundingBox = this.innerElem.getBBox();
+
+    if (this.currentBBox.w !== boundingBox.width) {
+      this.currentBBox.w = boundingBox.width;
+      this.svgElement.setAttribute('width', boundingBox.width);
+    }
+    if (this.currentBBox.h !== boundingBox.height) {
+      this.currentBBox.h = boundingBox.height;
+      this.svgElement.setAttribute('height', boundingBox.height);
+    }
+
+    var margin = 1;
+    if (this.currentBBox.w !== (boundingBox.width + margin * 2) || this.currentBBox.h !== (boundingBox.height + margin * 2) || this.currentBBox.x !== (boundingBox.x - margin) || this.currentBBox.y !== (boundingBox.y - margin)) {
+      this.currentBBox.w = boundingBox.width + margin * 2;
+      this.currentBBox.h = boundingBox.height + margin * 2;
+      this.currentBBox.x = boundingBox.x - margin;
+      this.currentBBox.y = boundingBox.y - margin;
+
+      this.svgElement.setAttribute('viewBox', this.currentBBox.x + ' ' + this.currentBBox.y + ' ' + this.currentBBox.w + ' ' + this.currentBBox.h);
+      svgStyle = this.svgElement.style;
+      var svgTransform = 'translate(' + this.currentBBox.x + 'px,' + this.currentBBox.y + 'px)';
+      svgStyle.transform = svgTransform;
+      svgStyle.webkitTransform = svgTransform;
+    }
+  }
+};
+
+function HCameraElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initHierarchy();
+  var getProp = PropertyFactory.getProp;
+  this.pe = getProp(this, data.pe, 0, 0, this);
+  if (data.ks.p.s) {
+    this.px = getProp(this, data.ks.p.x, 1, 0, this);
+    this.py = getProp(this, data.ks.p.y, 1, 0, this);
+    this.pz = getProp(this, data.ks.p.z, 1, 0, this);
+  } else {
+    this.p = getProp(this, data.ks.p, 1, 0, this);
+  }
+  if (data.ks.a) {
+    this.a = getProp(this, data.ks.a, 1, 0, this);
+  }
+  if (data.ks.or.k.length && data.ks.or.k[0].to) {
+    var i;
+    var len = data.ks.or.k.length;
+    for (i = 0; i < len; i += 1) {
+      data.ks.or.k[i].to = null;
+      data.ks.or.k[i].ti = null;
+    }
+  }
+  this.or = getProp(this, data.ks.or, 1, degToRads, this);
+  this.or.sh = true;
+  this.rx = getProp(this, data.ks.rx, 0, degToRads, this);
+  this.ry = getProp(this, data.ks.ry, 0, degToRads, this);
+  this.rz = getProp(this, data.ks.rz, 0, degToRads, this);
+  this.mat = new Matrix();
+  this._prevMat = new Matrix();
+  this._isFirstFrame = true;
+
+  // TODO: find a better way to make the HCamera element to be compatible with the LayerInterface and TransformInterface.
+  this.finalTransform = {
+    mProp: this,
+  };
+}
+extendPrototype([BaseElement, FrameElement, HierarchyElement], HCameraElement);
+
+HCameraElement.prototype.setup = function () {
+  var i;
+  var len = this.comp.threeDElements.length;
+  var comp;
+  var perspectiveStyle;
+  var containerStyle;
+  for (i = 0; i < len; i += 1) {
+    // [perspectiveElem,container]
+    comp = this.comp.threeDElements[i];
+    if (comp.type === '3d') {
+      perspectiveStyle = comp.perspectiveElem.style;
+      containerStyle = comp.container.style;
+      var perspective = this.pe.v + 'px';
+      var origin = '0px 0px 0px';
+      var matrix = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)';
+      perspectiveStyle.perspective = perspective;
+      perspectiveStyle.webkitPerspective = perspective;
+      containerStyle.transformOrigin = origin;
+      containerStyle.mozTransformOrigin = origin;
+      containerStyle.webkitTransformOrigin = origin;
+      perspectiveStyle.transform = matrix;
+      perspectiveStyle.webkitTransform = matrix;
+    }
+  }
+};
+
+HCameraElement.prototype.createElements = function () {
+};
+
+HCameraElement.prototype.hide = function () {
+};
+
+HCameraElement.prototype.renderFrame = function () {
+  var _mdf = this._isFirstFrame;
+  var i;
+  var len;
+  if (this.hierarchy) {
+    len = this.hierarchy.length;
+    for (i = 0; i < len; i += 1) {
+      _mdf = this.hierarchy[i].finalTransform.mProp._mdf || _mdf;
+    }
+  }
+  if (_mdf || this.pe._mdf || (this.p && this.p._mdf) || (this.px && (this.px._mdf || this.py._mdf || this.pz._mdf)) || this.rx._mdf || this.ry._mdf || this.rz._mdf || this.or._mdf || (this.a && this.a._mdf)) {
+    this.mat.reset();
+
+    if (this.hierarchy) {
+      len = this.hierarchy.length - 1;
+      for (i = len; i >= 0; i -= 1) {
+        var mTransf = this.hierarchy[i].finalTransform.mProp;
+        this.mat.translate(-mTransf.p.v[0], -mTransf.p.v[1], mTransf.p.v[2]);
+        this.mat.rotateX(-mTransf.or.v[0]).rotateY(-mTransf.or.v[1]).rotateZ(mTransf.or.v[2]);
+        this.mat.rotateX(-mTransf.rx.v).rotateY(-mTransf.ry.v).rotateZ(mTransf.rz.v);
+        this.mat.scale(1 / mTransf.s.v[0], 1 / mTransf.s.v[1], 1 / mTransf.s.v[2]);
+        this.mat.translate(mTransf.a.v[0], mTransf.a.v[1], mTransf.a.v[2]);
+      }
+    }
+    if (this.p) {
+      this.mat.translate(-this.p.v[0], -this.p.v[1], this.p.v[2]);
+    } else {
+      this.mat.translate(-this.px.v, -this.py.v, this.pz.v);
+    }
+    if (this.a) {
+      var diffVector;
+      if (this.p) {
+        diffVector = [this.p.v[0] - this.a.v[0], this.p.v[1] - this.a.v[1], this.p.v[2] - this.a.v[2]];
+      } else {
+        diffVector = [this.px.v - this.a.v[0], this.py.v - this.a.v[1], this.pz.v - this.a.v[2]];
+      }
+      var mag = Math.sqrt(Math.pow(diffVector[0], 2) + Math.pow(diffVector[1], 2) + Math.pow(diffVector[2], 2));
+      // var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
+      var lookDir = [diffVector[0] / mag, diffVector[1] / mag, diffVector[2] / mag];
+      var lookLengthOnXZ = Math.sqrt(lookDir[2] * lookDir[2] + lookDir[0] * lookDir[0]);
+      var mRotationX = (Math.atan2(lookDir[1], lookLengthOnXZ));
+      var mRotationY = (Math.atan2(lookDir[0], -lookDir[2]));
+      this.mat.rotateY(mRotationY).rotateX(-mRotationX);
+    }
+    this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v);
+    this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]);
+    this.mat.translate(this.globalData.compSize.w / 2, this.globalData.compSize.h / 2, 0);
+    this.mat.translate(0, 0, this.pe.v);
+
+    var hasMatrixChanged = !this._prevMat.equals(this.mat);
+    if ((hasMatrixChanged || this.pe._mdf) && this.comp.threeDElements) {
+      len = this.comp.threeDElements.length;
+      var comp;
+      var perspectiveStyle;
+      var containerStyle;
+      for (i = 0; i < len; i += 1) {
+        comp = this.comp.threeDElements[i];
+        if (comp.type === '3d') {
+          if (hasMatrixChanged) {
+            var matValue = this.mat.toCSS();
+            containerStyle = comp.container.style;
+            containerStyle.transform = matValue;
+            containerStyle.webkitTransform = matValue;
+          }
+          if (this.pe._mdf) {
+            perspectiveStyle = comp.perspectiveElem.style;
+            perspectiveStyle.perspective = this.pe.v + 'px';
+            perspectiveStyle.webkitPerspective = this.pe.v + 'px';
+          }
+        }
+      }
+      this.mat.clone(this._prevMat);
+    }
+  }
+  this._isFirstFrame = false;
+};
+
+HCameraElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+HCameraElement.prototype.destroy = function () {
+};
+HCameraElement.prototype.getBaseElement = function () { return null; };
+
+function HImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, HBaseElement, HSolidElement, HierarchyElement, FrameElement, RenderableElement], HImageElement);
+
+HImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  var img = new Image();
+
+  if (this.data.hasMask) {
+    this.imageElem = createNS('image');
+    this.imageElem.setAttribute('width', this.assetData.w + 'px');
+    this.imageElem.setAttribute('height', this.assetData.h + 'px');
+    this.imageElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+    this.layerElement.appendChild(this.imageElem);
+    this.baseElement.setAttribute('width', this.assetData.w);
+    this.baseElement.setAttribute('height', this.assetData.h);
+  } else {
+    this.layerElement.appendChild(img);
+  }
+  img.crossOrigin = 'anonymous';
+  img.src = assetPath;
+  if (this.data.ln) {
+    this.baseElement.setAttribute('id', this.data.ln);
+  }
+};
+
+function HybridRendererBase(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),
+    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], HybridRendererBase);
+
+HybridRendererBase.prototype.buildItem = SVGRenderer.prototype.buildItem;
+
+HybridRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+  }
+};
+
+HybridRendererBase.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;
+      var nextLayer;
+      var 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);
+  }
+};
+
+HybridRendererBase.prototype.createShape = function (data) {
+  if (!this.supports3d) {
+    return new SVGShapeElement(data, this.globalData, this);
+  }
+  return new HShapeElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createText = function (data) {
+  if (!this.supports3d) {
+    return new SVGTextLottieElement(data, this.globalData, this);
+  }
+  return new HTextElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createCamera = function (data) {
+  this.camera = new HCameraElement(data, this.globalData, this);
+  return this.camera;
+};
+
+HybridRendererBase.prototype.createImage = function (data) {
+  if (!this.supports3d) {
+    return new IImageElement(data, this.globalData, this);
+  }
+  return new HImageElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createSolid = function (data) {
+  if (!this.supports3d) {
+    return new ISolidElement(data, this.globalData, this);
+  }
+  return new HSolidElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
+
+HybridRendererBase.prototype.getThreeDContainerByPos = function (pos) {
+  var i = 0;
+  var 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;
+  }
+  return null;
+};
+
+HybridRendererBase.prototype.createThreeDContainer = function (pos, type) {
+  var perspectiveElem = createTag('div');
+  var style;
+  var containerStyle;
+  styleDiv(perspectiveElem);
+  var container = createTag('div');
+  styleDiv(container);
+  if (type === '3d') {
+    style = perspectiveElem.style;
+    style.width = this.globalData.compSize.w + 'px';
+    style.height = this.globalData.compSize.h + 'px';
+    var center = '50% 50%';
+    style.webkitTransformOrigin = center;
+    style.mozTransformOrigin = center;
+    style.transformOrigin = center;
+    containerStyle = container.style;
+    var matrix = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)';
+    containerStyle.transform = matrix;
+    containerStyle.webkitTransform = matrix;
+  }
+
+  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;
+};
+
+HybridRendererBase.prototype.build3dContainers = function () {
+  var i;
+  var 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 -= 1) {
+    this.resizerElem.appendChild(this.threeDElements[i].perspectiveElem);
+  }
+};
+
+HybridRendererBase.prototype.addTo3dContainer = function (elem, pos) {
+  var i = 0;
+  var 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;
+  }
+};
+
+HybridRendererBase.prototype.configAnimation = function (animData) {
+  var resizerElem = createTag('div');
+  var wrapper = this.animationItem.wrapper;
+  var style = resizerElem.style;
+  style.width = animData.w + 'px';
+  style.height = animData.h + 'px';
+  this.resizerElem = resizerElem;
+  styleDiv(resizerElem);
+  style.transformStyle = 'flat';
+  style.mozTransformStyle = 'flat';
+  style.webkitTransformStyle = 'flat';
+  if (this.renderConfig.className) {
+    resizerElem.setAttribute('class', this.renderConfig.className);
+  }
+  wrapper.appendChild(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();
+};
+
+HybridRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.animationItem.container = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+HybridRendererBase.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;
+  var sy;
+  var tx;
+  var 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;
+  }
+  var style = this.resizerElem.style;
+  style.webkitTransform = 'matrix3d(' + sx + ',0,0,0,0,' + sy + ',0,0,0,0,1,0,' + tx + ',' + ty + ',0,1)';
+  style.transform = style.webkitTransform;
+};
+
+HybridRendererBase.prototype.renderFrame = SVGRenderer.prototype.renderFrame;
+
+HybridRendererBase.prototype.hide = function () {
+  this.resizerElem.style.display = 'none';
+};
+
+HybridRendererBase.prototype.show = function () {
+  this.resizerElem.style.display = 'block';
+};
+
+HybridRendererBase.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;
+    var len = this.threeDElements.length;
+    for (i = 0; i < len; i += 1) {
+      var style = this.threeDElements[i].perspectiveElem.style;
+      style.webkitPerspective = Math.sqrt(Math.pow(cWidth, 2) + Math.pow(cHeight, 2)) + 'px';
+      style.perspective = style.webkitPerspective;
+    }
+  }
+};
+
+HybridRendererBase.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var 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);
+    }
+  }
+};
+
+function HCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = !data.hasMask;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([HybridRendererBase, ICompElement, HBaseElement], HCompElement);
+HCompElement.prototype._createBaseContainerElements = HCompElement.prototype.createContainerElements;
+
+HCompElement.prototype.createContainerElements = function () {
+  this._createBaseContainerElements();
+  // divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
+  if (this.data.hasMask) {
+    this.svgElement.setAttribute('width', this.data.w);
+    this.svgElement.setAttribute('height', this.data.h);
+    this.transformedElement = this.baseElement;
+  } else {
+    this.transformedElement = this.layerElement;
+  }
+};
+
+HCompElement.prototype.addTo3dContainer = function (elem, pos) {
+  var j = 0;
+  var nextElement;
+  while (j < pos) {
+    if (this.elements[j] && this.elements[j].getBaseElement) {
+      nextElement = this.elements[j].getBaseElement();
+    }
+    j += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(elem, nextElement);
+  } else {
+    this.layerElement.appendChild(elem);
+  }
+};
+
+HCompElement.prototype.createComp = function (data) {
+  if (!this.supports3d) {
+    return new SVGCompElement(data, this.globalData, this);
+  }
+  return new HCompElement(data, this.globalData, this);
+};
+
+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),
+    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%',
+    },
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+  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([HybridRendererBase], HybridRenderer);
+
+HybridRenderer.prototype.createComp = function (data) {
+  if (!this.supports3d) {
+    return new SVGCompElement(data, this.globalData, this);
+  }
+  return new HCompElement(data, this.globalData, this);
+};
+
+// Registering renderers
+registerRenderer('html', HybridRenderer);
+
+// Registering shape modifiers
+ShapeModifiers.registerModifier('tm', TrimModifier);
+ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
+ShapeModifiers.registerModifier('rp', RepeaterModifier);
+ShapeModifiers.registerModifier('rd', RoundCornersModifier);
+ShapeModifiers.registerModifier('zz', ZigZagModifier);
+ShapeModifiers.registerModifier('op', OffsetPathModifier);
+
+exports["default"] = lottie;
diff --git a/build/player/cjs/lottie_svg.min.js b/build/player/cjs/lottie_svg.min.js
new file mode 100644
index 0000000..993047f
--- /dev/null
+++ b/build/player/cjs/lottie_svg.min.js
@@ -0,0 +1,15053 @@
+'use strict';
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+const svgNS = 'http://www.w3.org/2000/svg';
+
+let locationHref = '';
+let _useWebWorker = false;
+
+const initialDefaultFrame = -999999;
+
+const setWebWorker = (flag) => { _useWebWorker = !!flag; };
+const getWebWorker = () => _useWebWorker;
+
+const setLocationHref = (value) => { locationHref = value; };
+const getLocationHref = () => locationHref;
+
+function createTag(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElement(type);
+}
+
+function extendPrototype(sources, destination) {
+  var i;
+  var len = sources.length;
+  var sourcePrototype;
+  for (i = 0; i < len; i += 1) {
+    sourcePrototype = sources[i].prototype;
+    for (var attr in sourcePrototype) {
+      if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
+    }
+  }
+}
+
+function getDescriptor(object, prop) {
+  return Object.getOwnPropertyDescriptor(object, prop);
+}
+
+function createProxyFunction(prototype) {
+  function ProxyFunction() {}
+  ProxyFunction.prototype = prototype;
+  return ProxyFunction;
+}
+
+// import Howl from '../../3rd_party/howler';
+
+const audioControllerFactory = (function () {
+  function AudioController(audioFactory) {
+    this.audios = [];
+    this.audioFactory = audioFactory;
+    this._volume = 1;
+    this._isMuted = false;
+  }
+
+  AudioController.prototype = {
+    addAudio: function (audio) {
+      this.audios.push(audio);
+    },
+    pause: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].pause();
+      }
+    },
+    resume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].resume();
+      }
+    },
+    setRate: function (rateValue) {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].setRate(rateValue);
+      }
+    },
+    createAudio: function (assetPath) {
+      if (this.audioFactory) {
+        return this.audioFactory(assetPath);
+      } if (window.Howl) {
+        return new window.Howl({
+          src: [assetPath],
+        });
+      }
+      return {
+        isPlaying: false,
+        play: function () { this.isPlaying = true; },
+        seek: function () { this.isPlaying = false; },
+        playing: function () {},
+        rate: function () {},
+        setVolume: function () {},
+      };
+    },
+    setAudioFactory: function (audioFactory) {
+      this.audioFactory = audioFactory;
+    },
+    setVolume: function (value) {
+      this._volume = value;
+      this._updateVolume();
+    },
+    mute: function () {
+      this._isMuted = true;
+      this._updateVolume();
+    },
+    unmute: function () {
+      this._isMuted = false;
+      this._updateVolume();
+    },
+    getVolume: function () {
+      return this._volume;
+    },
+    _updateVolume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
+      }
+    },
+  };
+
+  return function () {
+    return new AudioController();
+  };
+}());
+
+const createTypedArray = (function () {
+  function createRegularArray(type, len) {
+    var i = 0;
+    var arr = [];
+    var value;
+    switch (type) {
+      case 'int16':
+      case 'uint8c':
+        value = 1;
+        break;
+      default:
+        value = 1.1;
+        break;
+    }
+    for (i = 0; i < len; i += 1) {
+      arr.push(value);
+    }
+    return arr;
+  }
+  function createTypedArrayFactory(type, len) {
+    if (type === 'float32') {
+      return new Float32Array(len);
+    } if (type === 'int16') {
+      return new Int16Array(len);
+    } if (type === 'uint8c') {
+      return new Uint8ClampedArray(len);
+    }
+    return createRegularArray(type, len);
+  }
+  if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
+    return createTypedArrayFactory;
+  }
+  return createRegularArray;
+}());
+
+function createSizedArray(len) {
+  return Array.apply(null, { length: len });
+}
+
+let subframeEnabled = true;
+let expressionsPlugin = null;
+let expressionsInterfaces = null;
+let idPrefix$1 = '';
+const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+let _shouldRoundValues = false;
+const bmPow = Math.pow;
+const bmSqrt = Math.sqrt;
+const bmFloor = Math.floor;
+const bmMax = Math.max;
+const bmMin = Math.min;
+
+const BMMath = {};
+(function () {
+  var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
+  var i;
+  var len = propertyNames.length;
+  for (i = 0; i < len; i += 1) {
+    BMMath[propertyNames[i]] = Math[propertyNames[i]];
+  }
+}());
+
+function ProjectInterface$1() { return {}; }
+BMMath.random = Math.random;
+BMMath.abs = function (val) {
+  var tOfVal = typeof val;
+  if (tOfVal === 'object' && val.length) {
+    var absArr = createSizedArray(val.length);
+    var i;
+    var len = val.length;
+    for (i = 0; i < len; i += 1) {
+      absArr[i] = Math.abs(val[i]);
+    }
+    return absArr;
+  }
+  return Math.abs(val);
+};
+let defaultCurveSegments = 150;
+const degToRads = Math.PI / 180;
+const roundCorner = 0.5519;
+
+function roundValues(flag) {
+  _shouldRoundValues = !!flag;
+}
+
+function bmRnd(value) {
+  if (_shouldRoundValues) {
+    return Math.round(value);
+  }
+  return value;
+}
+
+function styleDiv(element) {
+  element.style.position = 'absolute';
+  element.style.top = 0;
+  element.style.left = 0;
+  element.style.display = 'block';
+  element.style.transformOrigin = '0 0';
+  element.style.webkitTransformOrigin = '0 0';
+  element.style.backfaceVisibility = 'visible';
+  element.style.webkitBackfaceVisibility = 'visible';
+  element.style.transformStyle = 'preserve-3d';
+  element.style.webkitTransformStyle = 'preserve-3d';
+  element.style.mozTransformStyle = 'preserve-3d';
+}
+
+function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
+  this.type = type;
+  this.currentTime = currentTime;
+  this.totalTime = totalTime;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteEvent(type, frameMultiplier) {
+  this.type = type;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
+  this.type = type;
+  this.currentLoop = currentLoop;
+  this.totalLoops = totalLoops;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMSegmentStartEvent(type, firstFrame, totalFrames) {
+  this.type = type;
+  this.firstFrame = firstFrame;
+  this.totalFrames = totalFrames;
+}
+
+function BMDestroyEvent(type, target) {
+  this.type = type;
+  this.target = target;
+}
+
+function BMRenderFrameErrorEvent(nativeError, currentTime) {
+  this.type = 'renderFrameError';
+  this.nativeError = nativeError;
+  this.currentTime = currentTime;
+}
+
+function BMConfigErrorEvent(nativeError) {
+  this.type = 'configError';
+  this.nativeError = nativeError;
+}
+
+function BMAnimationConfigErrorEvent(type, nativeError) {
+  this.type = type;
+  this.nativeError = nativeError;
+}
+
+const createElementID = (function () {
+  var _count = 0;
+  return function createID() {
+    _count += 1;
+    return idPrefix$1 + '__lottie_element_' + _count;
+  };
+}());
+
+function HSVtoRGB(h, s, v) {
+  var r;
+  var g;
+  var b;
+  var i;
+  var f;
+  var p;
+  var q;
+  var t;
+  i = Math.floor(h * 6);
+  f = h * 6 - i;
+  p = v * (1 - s);
+  q = v * (1 - f * s);
+  t = v * (1 - (1 - f) * s);
+  switch (i % 6) {
+    case 0: r = v; g = t; b = p; break;
+    case 1: r = q; g = v; b = p; break;
+    case 2: r = p; g = v; b = t; break;
+    case 3: r = p; g = q; b = v; break;
+    case 4: r = t; g = p; b = v; break;
+    case 5: r = v; g = p; b = q; break;
+    default: break;
+  }
+  return [r,
+    g,
+    b];
+}
+
+function RGBtoHSV(r, g, b) {
+  var max = Math.max(r, g, b);
+  var min = Math.min(r, g, b);
+  var d = max - min;
+  var h;
+  var s = (max === 0 ? 0 : d / max);
+  var v = max / 255;
+
+  switch (max) {
+    case min: h = 0; break;
+    case r: h = (g - b) + d * (g < b ? 6 : 0); h /= 6 * d; break;
+    case g: h = (b - r) + d * 2; h /= 6 * d; break;
+    case b: h = (r - g) + d * 4; h /= 6 * d; break;
+    default: break;
+  }
+
+  return [
+    h,
+    s,
+    v,
+  ];
+}
+
+function addSaturationToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[1] += offset;
+  if (hsv[1] > 1) {
+    hsv[1] = 1;
+  } else if (hsv[1] <= 0) {
+    hsv[1] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addBrightnessToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[2] += offset;
+  if (hsv[2] > 1) {
+    hsv[2] = 1;
+  } else if (hsv[2] < 0) {
+    hsv[2] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addHueToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[0] += offset / 360;
+  if (hsv[0] > 1) {
+    hsv[0] -= 1;
+  } else if (hsv[0] < 0) {
+    hsv[0] += 1;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+const rgbToHex = (function () {
+  var colorMap = [];
+  var i;
+  var hex;
+  for (i = 0; i < 256; i += 1) {
+    hex = i.toString(16);
+    colorMap[i] = hex.length === 1 ? '0' + hex : hex;
+  }
+
+  return function (r, g, b) {
+    if (r < 0) {
+      r = 0;
+    }
+    if (g < 0) {
+      g = 0;
+    }
+    if (b < 0) {
+      b = 0;
+    }
+    return '#' + colorMap[r] + colorMap[g] + colorMap[b];
+  };
+}());
+
+const setSubframeEnabled = (flag) => { subframeEnabled = !!flag; };
+const getSubframeEnabled = () => subframeEnabled;
+const setExpressionsPlugin = (value) => { expressionsPlugin = value; };
+const getExpressionsPlugin = () => expressionsPlugin;
+const setExpressionInterfaces = (value) => { expressionsInterfaces = value; };
+const getExpressionInterfaces = () => expressionsInterfaces;
+const setDefaultCurveSegments = (value) => { defaultCurveSegments = value; };
+const getDefaultCurveSegments = () => defaultCurveSegments;
+const setIdPrefix = (value) => { idPrefix$1 = value; };
+const getIdPrefix = () => idPrefix$1;
+
+function createNS(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElementNS(svgNS, type);
+}
+
+const dataManager = (function () {
+  var _counterId = 1;
+  var processes = [];
+  var workerFn;
+  var workerInstance;
+  var workerProxy = {
+    onmessage: function () {
+
+    },
+    postMessage: function (path) {
+      workerFn({
+        data: path,
+      });
+    },
+  };
+  var _workerSelf = {
+    postMessage: function (data) {
+      workerProxy.onmessage({
+        data: data,
+      });
+    },
+  };
+  function createWorker(fn) {
+    if (window.Worker && window.Blob && getWebWorker()) {
+      var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      var url = URL.createObjectURL(blob);
+      return new Worker(url);
+    }
+    workerFn = fn;
+    return workerProxy;
+  }
+
+  function setupWorker() {
+    if (!workerInstance) {
+      workerInstance = createWorker(function workerStart(e) {
+        function dataFunctionManager() {
+          function completeLayers(layers, comps) {
+            var layerData;
+            var i;
+            var len = layers.length;
+            var j;
+            var jLen;
+            var k;
+            var kLen;
+            for (i = 0; i < len; i += 1) {
+              layerData = layers[i];
+              if (('ks' in layerData) && !layerData.completed) {
+                layerData.completed = true;
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      convertPathsToAbsoluteValues(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) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 0) {
+                  layerData.layers = findCompLayers(layerData.refId, comps);
+                  completeLayers(layerData.layers, comps);
+                } else if (layerData.ty === 4) {
+                  completeShapes(layerData.shapes);
+                } else if (layerData.ty === 5) {
+                  completeText(layerData);
+                }
+              }
+            }
+          }
+
+          function completeChars(chars, assets) {
+            if (chars) {
+              var i = 0;
+              var len = chars.length;
+              for (i = 0; i < len; i += 1) {
+                if (chars[i].t === 1) {
+                  // var compData = findComp(chars[i].data.refId, assets);
+                  chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                  // chars[i].data.ip = 0;
+                  // chars[i].data.op = 99999;
+                  // chars[i].data.st = 0;
+                  // chars[i].data.sr = 1;
+                  // chars[i].w = compData.w;
+                  // chars[i].data.ks = {
+                  //   a: { k: [0, 0, 0], a: 0 },
+                  //   p: { k: [0, -compData.h, 0], a: 0 },
+                  //   r: { k: 0, a: 0 },
+                  //   s: { k: [100, 100], a: 0 },
+                  //   o: { k: 100, a: 0 },
+                  // };
+                  completeLayers(chars[i].data.layers, assets);
+                }
+              }
+            }
+          }
+
+          function findComp(id, comps) {
+            var i = 0;
+            var len = comps.length;
+            while (i < len) {
+              if (comps[i].id === id) {
+                return comps[i];
+              }
+              i += 1;
+            }
+            return null;
+          }
+
+          function findCompLayers(id, comps) {
+            var comp = findComp(id, comps);
+            if (comp) {
+              if (!comp.layers.__used) {
+                comp.layers.__used = true;
+                return comp.layers;
+              }
+              return JSON.parse(JSON.stringify(comp.layers));
+            }
+            return null;
+          }
+
+          function completeShapes(arr) {
+            var i;
+            var len = arr.length;
+            var j;
+            var jLen;
+            for (i = len - 1; i >= 0; i -= 1) {
+              if (arr[i].ty === 'sh') {
+                if (arr[i].ks.k.i) {
+                  convertPathsToAbsoluteValues(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) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
+                    }
+                    if (arr[i].ks.k[j].e) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
+                    }
+                  }
+                }
+              } else if (arr[i].ty === 'gr') {
+                completeShapes(arr[i].it);
+              }
+            }
+          }
+
+          function convertPathsToAbsoluteValues(path) {
+            var i;
+            var len = path.i.length;
+            for (i = 0; i < len; i += 1) {
+              path.i[i][0] += path.v[i][0];
+              path.i[i][1] += path.v[i][1];
+              path.o[i][0] += path.v[i][0];
+              path.o[i][1] += path.v[i][1];
+            }
+          }
+
+          function checkVersion(minimum, animVersionString) {
+            var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
+            if (minimum[0] > animVersion[0]) {
+              return true;
+            } if (animVersion[0] > minimum[0]) {
+              return false;
+            }
+            if (minimum[1] > animVersion[1]) {
+              return true;
+            } if (animVersion[1] > minimum[1]) {
+              return false;
+            }
+            if (minimum[2] > animVersion[2]) {
+              return true;
+            } if (animVersion[2] > minimum[2]) {
+              return false;
+            }
+            return null;
+          }
+
+          var checkText = (function () {
+            var minimumVersion = [4, 4, 14];
+
+            function updateTextLayer(textLayer) {
+              var documentData = textLayer.t.d;
+              textLayer.t.d = {
+                k: [
+                  {
+                    s: documentData,
+                    t: 0,
+                  },
+                ],
+              };
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkChars = (function () {
+            var minimumVersion = [4, 7, 99];
+            return function (animationData) {
+              if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
+                var i;
+                var len = animationData.chars.length;
+                for (i = 0; i < len; i += 1) {
+                  var charData = animationData.chars[i];
+                  if (charData.data && charData.data.shapes) {
+                    completeShapes(charData.data.shapes);
+                    charData.data.ip = 0;
+                    charData.data.op = 99999;
+                    charData.data.st = 0;
+                    charData.data.sr = 1;
+                    charData.data.ks = {
+                      p: { k: [0, 0], a: 0 },
+                      s: { k: [100, 100], a: 0 },
+                      a: { k: [0, 0], a: 0 },
+                      r: { k: 0, a: 0 },
+                      o: { k: 100, a: 0 },
+                    };
+                    if (!animationData.chars[i].t) {
+                      charData.data.shapes.push(
+                        {
+                          ty: 'no',
+                        }
+                      );
+                      charData.data.shapes[0].it.push(
+                        {
+                          p: { k: [0, 0], a: 0 },
+                          s: { k: [100, 100], a: 0 },
+                          a: { k: [0, 0], a: 0 },
+                          r: { k: 0, a: 0 },
+                          o: { k: 100, a: 0 },
+                          sk: { k: 0, a: 0 },
+                          sa: { k: 0, a: 0 },
+                          ty: 'tr',
+                        }
+                      );
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkPathProperties = (function () {
+            var minimumVersion = [5, 7, 15];
+
+            function updateTextLayer(textLayer) {
+              var pathData = textLayer.t.p;
+              if (typeof pathData.a === 'number') {
+                pathData.a = {
+                  a: 0,
+                  k: pathData.a,
+                };
+              }
+              if (typeof pathData.p === 'number') {
+                pathData.p = {
+                  a: 0,
+                  k: pathData.p,
+                };
+              }
+              if (typeof pathData.r === 'number') {
+                pathData.r = {
+                  a: 0,
+                  k: pathData.r,
+                };
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkColors = (function () {
+            var minimumVersion = [4, 1, 9];
+
+            function iterateShapes(shapes) {
+              var i;
+              var len = shapes.length;
+              var j;
+              var jLen;
+              for (i = 0; i < len; i += 1) {
+                if (shapes[i].ty === 'gr') {
+                  iterateShapes(shapes[i].it);
+                } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
+                  if (shapes[i].c.k && shapes[i].c.k[0].i) {
+                    jLen = shapes[i].c.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (shapes[i].c.k[j].s) {
+                        shapes[i].c.k[j].s[0] /= 255;
+                        shapes[i].c.k[j].s[1] /= 255;
+                        shapes[i].c.k[j].s[2] /= 255;
+                        shapes[i].c.k[j].s[3] /= 255;
+                      }
+                      if (shapes[i].c.k[j].e) {
+                        shapes[i].c.k[j].e[0] /= 255;
+                        shapes[i].c.k[j].e[1] /= 255;
+                        shapes[i].c.k[j].e[2] /= 255;
+                        shapes[i].c.k[j].e[3] /= 255;
+                      }
+                    }
+                  } else {
+                    shapes[i].c.k[0] /= 255;
+                    shapes[i].c.k[1] /= 255;
+                    shapes[i].c.k[2] /= 255;
+                    shapes[i].c.k[3] /= 255;
+                  }
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 4) {
+                  iterateShapes(layers[i].shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkShapes = (function () {
+            var minimumVersion = [4, 4, 18];
+
+            function completeClosingShapes(arr) {
+              var i;
+              var len = arr.length;
+              var j;
+              var jLen;
+              for (i = len - 1; i >= 0; i -= 1) {
+                if (arr[i].ty === 'sh') {
+                  if (arr[i].ks.k.i) {
+                    arr[i].ks.k.c = arr[i].closed;
+                  } else {
+                    jLen = arr[i].ks.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (arr[i].ks.k[j].s) {
+                        arr[i].ks.k[j].s[0].c = arr[i].closed;
+                      }
+                      if (arr[i].ks.k[j].e) {
+                        arr[i].ks.k[j].e[0].c = arr[i].closed;
+                      }
+                    }
+                  }
+                } else if (arr[i].ty === 'gr') {
+                  completeClosingShapes(arr[i].it);
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var layerData;
+              var i;
+              var len = layers.length;
+              var j;
+              var jLen;
+              var k;
+              var kLen;
+              for (i = 0; i < len; i += 1) {
+                layerData = layers[i];
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      maskProps[j].pt.k.c = maskProps[j].cl;
+                    } else {
+                      kLen = maskProps[j].pt.k.length;
+                      for (k = 0; k < kLen; k += 1) {
+                        if (maskProps[j].pt.k[k].s) {
+                          maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 4) {
+                  completeClosingShapes(layerData.shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          function completeData(animationData) {
+            if (animationData.__complete) {
+              return;
+            }
+            checkColors(animationData);
+            checkText(animationData);
+            checkChars(animationData);
+            checkPathProperties(animationData);
+            checkShapes(animationData);
+            completeLayers(animationData.layers, animationData.assets);
+            completeChars(animationData.chars, animationData.assets);
+            animationData.__complete = true;
+          }
+
+          function completeText(data) {
+            if (data.t.a.length === 0 && !('m' in data.t.p)) {
+              // data.singleShape = true;
+            }
+          }
+
+          var moduleOb = {};
+          moduleOb.completeData = completeData;
+          moduleOb.checkColors = checkColors;
+          moduleOb.checkChars = checkChars;
+          moduleOb.checkPathProperties = checkPathProperties;
+          moduleOb.checkShapes = checkShapes;
+          moduleOb.completeLayers = completeLayers;
+
+          return moduleOb;
+        }
+        if (!_workerSelf.dataManager) {
+          _workerSelf.dataManager = dataFunctionManager();
+        }
+
+        if (!_workerSelf.assetLoader) {
+          _workerSelf.assetLoader = (function () {
+            function formatResponse(xhr) {
+              // using typeof doubles the time of execution of this method,
+              // so if available, it's better to use the header to validate the type
+              var contentTypeHeader = xhr.getResponseHeader('content-type');
+              if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
+                return xhr.response;
+              }
+              if (xhr.response && typeof xhr.response === 'object') {
+                return xhr.response;
+              } if (xhr.response && typeof xhr.response === 'string') {
+                return JSON.parse(xhr.response);
+              } if (xhr.responseText) {
+                return JSON.parse(xhr.responseText);
+              }
+              return null;
+            }
+
+            function loadAsset(path, fullPath, callback, errorCallback) {
+              var response;
+              var xhr = new XMLHttpRequest();
+              // set responseType after calling open or IE will break.
+              try {
+                // This crashes on Android WebView prior to KitKat
+                xhr.responseType = 'json';
+              } catch (err) {} // eslint-disable-line no-empty
+              xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4) {
+                  if (xhr.status === 200) {
+                    response = formatResponse(xhr);
+                    callback(response);
+                  } else {
+                    try {
+                      response = formatResponse(xhr);
+                      callback(response);
+                    } catch (err) {
+                      if (errorCallback) {
+                        errorCallback(err);
+                      }
+                    }
+                  }
+                }
+              };
+              try {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), path, true);
+              } catch (error) {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
+              }
+              xhr.send();
+            }
+            return {
+              load: loadAsset,
+            };
+          }());
+        }
+
+        if (e.data.type === 'loadAnimation') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.dataManager.completeData(data);
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        } else if (e.data.type === 'complete') {
+          var animation = e.data.animation;
+          _workerSelf.dataManager.completeData(animation);
+          _workerSelf.postMessage({
+            id: e.data.id,
+            payload: animation,
+            status: 'success',
+          });
+        } else if (e.data.type === 'loadData') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        }
+      });
+
+      workerInstance.onmessage = function (event) {
+        var data = event.data;
+        var id = data.id;
+        var process = processes[id];
+        processes[id] = null;
+        if (data.status === 'success') {
+          process.onComplete(data.payload);
+        } else if (process.onError) {
+          process.onError();
+        }
+      };
+    }
+  }
+
+  function createProcess(onComplete, onError) {
+    _counterId += 1;
+    var id = 'processId_' + _counterId;
+    processes[id] = {
+      onComplete: onComplete,
+      onError: onError,
+    };
+    return id;
+  }
+
+  function loadAnimation(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadAnimation',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function loadData(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadData',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function completeAnimation(anim, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'complete',
+      animation: anim,
+      id: processId,
+    });
+  }
+
+  return {
+    loadAnimation: loadAnimation,
+    loadData: loadData,
+    completeAnimation: completeAnimation,
+  };
+}());
+
+const ImagePreloader = (function () {
+  var proxyImage = (function () {
+    var canvas = createTag('canvas');
+    canvas.width = 1;
+    canvas.height = 1;
+    var ctx = canvas.getContext('2d');
+    ctx.fillStyle = 'rgba(0,0,0,0)';
+    ctx.fillRect(0, 0, 1, 1);
+    return canvas;
+  }());
+
+  function imageLoaded() {
+    this.loadedAssets += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+  function footageLoaded() {
+    this.loadedFootagesCount += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+
+  function getAssetsPath(assetData, assetsPath, originalPath) {
+    var path = '';
+    if (assetData.e) {
+      path = assetData.p;
+    } else if (assetsPath) {
+      var imagePath = assetData.p;
+      if (imagePath.indexOf('images/') !== -1) {
+        imagePath = imagePath.split('/')[1];
+      }
+      path = assetsPath + imagePath;
+    } else {
+      path = originalPath;
+      path += assetData.u ? assetData.u : '';
+      path += assetData.p;
+    }
+    return path;
+  }
+
+  function testImageLoaded(img) {
+    var _count = 0;
+    var intervalId = setInterval(function () {
+      var box = img.getBBox();
+      if (box.width || _count > 500) {
+        this._imageLoaded();
+        clearInterval(intervalId);
+      }
+      _count += 1;
+    }.bind(this), 50);
+  }
+
+  function createImageData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createNS('image');
+    if (isSafari) {
+      this.testImageLoaded(img);
+    } else {
+      img.addEventListener('load', this._imageLoaded, false);
+    }
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
+    if (this._elementHelper.append) {
+      this._elementHelper.append(img);
+    } else {
+      this._elementHelper.appendChild(img);
+    }
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createImgData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createTag('img');
+    img.crossOrigin = 'anonymous';
+    img.addEventListener('load', this._imageLoaded, false);
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.src = path;
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createFootageData(data) {
+    var ob = {
+      assetData: data,
+    };
+    var path = getAssetsPath(data, this.assetsPath, this.path);
+    dataManager.loadData(path, function (footageData) {
+      ob.img = footageData;
+      this._footageLoaded();
+    }.bind(this), function () {
+      ob.img = {};
+      this._footageLoaded();
+    }.bind(this));
+    return ob;
+  }
+
+  function loadAssets(assets, cb) {
+    this.imagesLoadedCb = cb;
+    var i;
+    var len = assets.length;
+    for (i = 0; i < len; i += 1) {
+      if (!assets[i].layers) {
+        if (!assets[i].t || assets[i].t === 'seq') {
+          this.totalImages += 1;
+          this.images.push(this._createImageData(assets[i]));
+        } else if (assets[i].t === 3) {
+          this.totalFootages += 1;
+          this.images.push(this.createFootageData(assets[i]));
+        }
+      }
+    }
+  }
+
+  function setPath(path) {
+    this.path = path || '';
+  }
+
+  function setAssetsPath(path) {
+    this.assetsPath = path || '';
+  }
+
+  function getAsset(assetData) {
+    var i = 0;
+    var len = this.images.length;
+    while (i < len) {
+      if (this.images[i].assetData === assetData) {
+        return this.images[i].img;
+      }
+      i += 1;
+    }
+    return null;
+  }
+
+  function destroy() {
+    this.imagesLoadedCb = null;
+    this.images.length = 0;
+  }
+
+  function loadedImages() {
+    return this.totalImages === this.loadedAssets;
+  }
+
+  function loadedFootages() {
+    return this.totalFootages === this.loadedFootagesCount;
+  }
+
+  function setCacheType(type, elementHelper) {
+    if (type === 'svg') {
+      this._elementHelper = elementHelper;
+      this._createImageData = this.createImageData.bind(this);
+    } else {
+      this._createImageData = this.createImgData.bind(this);
+    }
+  }
+
+  function ImagePreloaderFactory() {
+    this._imageLoaded = imageLoaded.bind(this);
+    this._footageLoaded = footageLoaded.bind(this);
+    this.testImageLoaded = testImageLoaded.bind(this);
+    this.createFootageData = createFootageData.bind(this);
+    this.assetsPath = '';
+    this.path = '';
+    this.totalImages = 0;
+    this.totalFootages = 0;
+    this.loadedAssets = 0;
+    this.loadedFootagesCount = 0;
+    this.imagesLoadedCb = null;
+    this.images = [];
+  }
+
+  ImagePreloaderFactory.prototype = {
+    loadAssets: loadAssets,
+    setAssetsPath: setAssetsPath,
+    setPath: setPath,
+    loadedImages: loadedImages,
+    loadedFootages: loadedFootages,
+    destroy: destroy,
+    getAsset: getAsset,
+    createImgData: createImgData,
+    createImageData: createImageData,
+    imageLoaded: imageLoaded,
+    footageLoaded: footageLoaded,
+    setCacheType: setCacheType,
+  };
+
+  return ImagePreloaderFactory;
+}());
+
+function BaseEvent() {}
+BaseEvent.prototype = {
+  triggerEvent: function (eventName, args) {
+    if (this._cbs[eventName]) {
+      var callbacks = this._cbs[eventName];
+      for (var i = 0; i < callbacks.length; i += 1) {
+        callbacks[i](args);
+      }
+    }
+  },
+  addEventListener: function (eventName, callback) {
+    if (!this._cbs[eventName]) {
+      this._cbs[eventName] = [];
+    }
+    this._cbs[eventName].push(callback);
+
+    return function () {
+      this.removeEventListener(eventName, callback);
+    }.bind(this);
+  },
+  removeEventListener: function (eventName, callback) {
+    if (!callback) {
+      this._cbs[eventName] = null;
+    } else if (this._cbs[eventName]) {
+      var i = 0;
+      var len = this._cbs[eventName].length;
+      while (i < len) {
+        if (this._cbs[eventName][i] === callback) {
+          this._cbs[eventName].splice(i, 1);
+          i -= 1;
+          len -= 1;
+        }
+        i += 1;
+      }
+      if (!this._cbs[eventName].length) {
+        this._cbs[eventName] = null;
+      }
+    }
+  },
+};
+
+const markerParser = (
+
+  function () {
+    function parsePayloadLines(payload) {
+      var lines = payload.split('\r\n');
+      var keys = {};
+      var line;
+      var keysCount = 0;
+      for (var i = 0; i < lines.length; i += 1) {
+        line = lines[i].split(':');
+        if (line.length === 2) {
+          keys[line[0]] = line[1].trim();
+          keysCount += 1;
+        }
+      }
+      if (keysCount === 0) {
+        throw new Error();
+      }
+      return keys;
+    }
+
+    return function (_markers) {
+      var markers = [];
+      for (var i = 0; i < _markers.length; i += 1) {
+        var _marker = _markers[i];
+        var markerData = {
+          time: _marker.tm,
+          duration: _marker.dr,
+        };
+        try {
+          markerData.payload = JSON.parse(_markers[i].cm);
+        } catch (_) {
+          try {
+            markerData.payload = parsePayloadLines(_markers[i].cm);
+          } catch (__) {
+            markerData.payload = {
+              name: _markers[i].cm,
+            };
+          }
+        }
+        markers.push(markerData);
+      }
+      return markers;
+    };
+  }());
+
+const ProjectInterface = (function () {
+  function registerComposition(comp) {
+    this.compositions.push(comp);
+  }
+
+  return function () {
+    function _thisProjectFunction(name) {
+      var i = 0;
+      var len = this.compositions.length;
+      while (i < len) {
+        if (this.compositions[i].data && this.compositions[i].data.nm === name) {
+          if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
+            this.compositions[i].prepareFrame(this.currentFrame);
+          }
+          return this.compositions[i].compInterface;
+        }
+        i += 1;
+      }
+      return null;
+    }
+
+    _thisProjectFunction.compositions = [];
+    _thisProjectFunction.currentFrame = 0;
+
+    _thisProjectFunction.registerComposition = registerComposition;
+
+    return _thisProjectFunction;
+  };
+}());
+
+const renderers = {};
+
+const registerRenderer = (key, value) => {
+  renderers[key] = value;
+};
+
+function getRenderer(key) {
+  return renderers[key];
+}
+
+function getRegisteredRenderer() {
+  // Returns canvas by default for compatibility
+  if (renderers.canvas) {
+    return 'canvas';
+  }
+  // Returns any renderer that is registered
+  for (const key in renderers) {
+    if (renderers[key]) {
+      return key;
+    }
+  }
+  return '';
+}
+
+const AnimationItem = function () {
+  this._cbs = [];
+  this.name = '';
+  this.path = '';
+  this.isLoaded = false;
+  this.currentFrame = 0;
+  this.currentRawFrame = 0;
+  this.firstFrame = 0;
+  this.totalFrames = 0;
+  this.frameRate = 0;
+  this.frameMult = 0;
+  this.playSpeed = 1;
+  this.playDirection = 1;
+  this.playCount = 0;
+  this.animationData = {};
+  this.assets = [];
+  this.isPaused = true;
+  this.autoplay = false;
+  this.loop = true;
+  this.renderer = null;
+  this.animationID = createElementID();
+  this.assetsPath = '';
+  this.timeCompleted = 0;
+  this.segmentPos = 0;
+  this.isSubframeEnabled = getSubframeEnabled();
+  this.segments = [];
+  this._idle = true;
+  this._completedLoop = false;
+  this.projectInterface = ProjectInterface();
+  this.imagePreloader = new ImagePreloader();
+  this.audioController = audioControllerFactory();
+  this.markers = [];
+  this.configAnimation = this.configAnimation.bind(this);
+  this.onSetupError = this.onSetupError.bind(this);
+  this.onSegmentComplete = this.onSegmentComplete.bind(this);
+  this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
+  this.expressionsPlugin = getExpressionsPlugin();
+};
+
+extendPrototype([BaseEvent], AnimationItem);
+
+AnimationItem.prototype.setParams = function (params) {
+  if (params.wrapper || params.container) {
+    this.wrapper = params.wrapper || params.container;
+  }
+  var animType = 'svg';
+  if (params.animType) {
+    animType = params.animType;
+  } else if (params.renderer) {
+    animType = params.renderer;
+  }
+  const RendererClass = getRenderer(animType);
+  this.renderer = new RendererClass(this, params.rendererSettings);
+  this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
+  this.renderer.setProjectInterface(this.projectInterface);
+  this.animType = animType;
+  if (params.loop === ''
+        || params.loop === null
+        || params.loop === undefined
+        || params.loop === true) {
+    this.loop = true;
+  } else if (params.loop === false) {
+    this.loop = false;
+  } else {
+    this.loop = parseInt(params.loop, 10);
+  }
+  this.autoplay = 'autoplay' in params ? params.autoplay : true;
+  this.name = params.name ? params.name : '';
+  this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
+  this.assetsPath = params.assetsPath;
+  this.initialSegment = params.initialSegment;
+  if (params.audioFactory) {
+    this.audioController.setAudioFactory(params.audioFactory);
+  }
+  if (params.animationData) {
+    this.setupAnimation(params.animationData);
+  } else if (params.path) {
+    if (params.path.lastIndexOf('\\') !== -1) {
+      this.path = params.path.substr(0, params.path.lastIndexOf('\\') + 1);
+    } else {
+      this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
+    }
+    this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
+    this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
+    dataManager.loadAnimation(
+      params.path,
+      this.configAnimation,
+      this.onSetupError
+    );
+  }
+};
+
+AnimationItem.prototype.onSetupError = function () {
+  this.trigger('data_failed');
+};
+
+AnimationItem.prototype.setupAnimation = function (data) {
+  dataManager.completeAnimation(
+    data,
+    this.configAnimation
+  );
+};
+
+AnimationItem.prototype.setData = function (wrapper, animationData) {
+  if (animationData) {
+    if (typeof animationData !== 'object') {
+      animationData = JSON.parse(animationData);
+    }
+  }
+  var params = {
+    wrapper: wrapper,
+    animationData: animationData,
+  };
+  var wrapperAttributes = wrapper.attributes;
+
+  params.path = wrapperAttributes.getNamedItem('data-animation-path') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-animation-path').value
+    : wrapperAttributes.getNamedItem('data-bm-path') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-path').value
+      : wrapperAttributes.getNamedItem('bm-path')
+        ? wrapperAttributes.getNamedItem('bm-path').value
+        : '';
+  params.animType = wrapperAttributes.getNamedItem('data-anim-type') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-type').value
+    : wrapperAttributes.getNamedItem('data-bm-type') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-type').value
+      : wrapperAttributes.getNamedItem('bm-type') // eslint-disable-line no-nested-ternary
+        ? wrapperAttributes.getNamedItem('bm-type').value
+        : wrapperAttributes.getNamedItem('data-bm-renderer') // eslint-disable-line no-nested-ternary
+          ? wrapperAttributes.getNamedItem('data-bm-renderer').value
+          : wrapperAttributes.getNamedItem('bm-renderer')
+            ? wrapperAttributes.getNamedItem('bm-renderer').value
+            : getRegisteredRenderer() || 'canvas';
+
+  var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-loop').value
+    : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-loop').value
+      : wrapperAttributes.getNamedItem('bm-loop')
+        ? wrapperAttributes.getNamedItem('bm-loop').value
+        : '';
+  if (loop === 'false') {
+    params.loop = false;
+  } else if (loop === 'true') {
+    params.loop = true;
+  } else if (loop !== '') {
+    params.loop = parseInt(loop, 10);
+  }
+  var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-autoplay').value
+    : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-autoplay').value
+      : wrapperAttributes.getNamedItem('bm-autoplay')
+        ? wrapperAttributes.getNamedItem('bm-autoplay').value
+        : true;
+  params.autoplay = autoplay !== 'false';
+
+  params.name = wrapperAttributes.getNamedItem('data-name') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-name').value
+    : wrapperAttributes.getNamedItem('data-bm-name') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-name').value
+      : wrapperAttributes.getNamedItem('bm-name')
+        ? wrapperAttributes.getNamedItem('bm-name').value
+        : '';
+  var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-prerender').value
+    : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-prerender').value
+      : wrapperAttributes.getNamedItem('bm-prerender')
+        ? wrapperAttributes.getNamedItem('bm-prerender').value
+        : '';
+
+  if (prerender === 'false') {
+    params.prerender = false;
+  }
+  if (!params.path) {
+    this.trigger('destroy');
+  } else {
+    this.setParams(params);
+  }
+};
+
+AnimationItem.prototype.includeLayers = function (data) {
+  if (data.op > this.animationData.op) {
+    this.animationData.op = data.op;
+    this.totalFrames = Math.floor(data.op - this.animationData.ip);
+  }
+  var layers = this.animationData.layers;
+  var i;
+  var len = layers.length;
+  var newLayers = data.layers;
+  var j;
+  var jLen = newLayers.length;
+  for (j = 0; j < jLen; j += 1) {
+    i = 0;
+    while (i < len) {
+      if (layers[i].id === newLayers[j].id) {
+        layers[i] = newLayers[j];
+        break;
+      }
+      i += 1;
+    }
+  }
+  if (data.chars || data.fonts) {
+    this.renderer.globalData.fontManager.addChars(data.chars);
+    this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
+  }
+  if (data.assets) {
+    len = data.assets.length;
+    for (i = 0; i < len; i += 1) {
+      this.animationData.assets.push(data.assets[i]);
+    }
+  }
+  this.animationData.__complete = false;
+  dataManager.completeAnimation(
+    this.animationData,
+    this.onSegmentComplete
+  );
+};
+
+AnimationItem.prototype.onSegmentComplete = function (data) {
+  this.animationData = data;
+  var expressionsPlugin = getExpressionsPlugin();
+  if (expressionsPlugin) {
+    expressionsPlugin.initExpressions(this);
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.loadNextSegment = function () {
+  var segments = this.animationData.segments;
+  if (!segments || segments.length === 0 || !this.autoloadSegments) {
+    this.trigger('data_ready');
+    this.timeCompleted = this.totalFrames;
+    return;
+  }
+  var segment = segments.shift();
+  this.timeCompleted = segment.time * this.frameRate;
+  var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
+  this.segmentPos += 1;
+  dataManager.loadData(segmentPath, this.includeLayers.bind(this), function () {
+    this.trigger('data_failed');
+  }.bind(this));
+};
+
+AnimationItem.prototype.loadSegments = function () {
+  var segments = this.animationData.segments;
+  if (!segments) {
+    this.timeCompleted = this.totalFrames;
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.imagesLoaded = function () {
+  this.trigger('loaded_images');
+  this.checkLoaded();
+};
+
+AnimationItem.prototype.preloadImages = function () {
+  this.imagePreloader.setAssetsPath(this.assetsPath);
+  this.imagePreloader.setPath(this.path);
+  this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
+};
+
+AnimationItem.prototype.configAnimation = function (animData) {
+  if (!this.renderer) {
+    return;
+  }
+  try {
+    this.animationData = animData;
+    if (this.initialSegment) {
+      this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
+      this.firstFrame = Math.round(this.initialSegment[0]);
+    } else {
+      this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
+      this.firstFrame = Math.round(this.animationData.ip);
+    }
+    this.renderer.configAnimation(animData);
+    if (!animData.assets) {
+      animData.assets = [];
+    }
+
+    this.assets = this.animationData.assets;
+    this.frameRate = this.animationData.fr;
+    this.frameMult = this.animationData.fr / 1000;
+    this.renderer.searchExtraCompositions(animData.assets);
+    this.markers = markerParser(animData.markers || []);
+    this.trigger('config_ready');
+    this.preloadImages();
+    this.loadSegments();
+    this.updaFrameModifier();
+    this.waitForFontsLoaded();
+    if (this.isPaused) {
+      this.audioController.pause();
+    }
+  } catch (error) {
+    this.triggerConfigError(error);
+  }
+};
+
+AnimationItem.prototype.waitForFontsLoaded = function () {
+  if (!this.renderer) {
+    return;
+  }
+  if (this.renderer.globalData.fontManager.isLoaded) {
+    this.checkLoaded();
+  } else {
+    setTimeout(this.waitForFontsLoaded.bind(this), 20);
+  }
+};
+
+AnimationItem.prototype.checkLoaded = function () {
+  if (!this.isLoaded
+        && this.renderer.globalData.fontManager.isLoaded
+        && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas')
+        && (this.imagePreloader.loadedFootages())
+  ) {
+    this.isLoaded = true;
+    var expressionsPlugin = getExpressionsPlugin();
+    if (expressionsPlugin) {
+      expressionsPlugin.initExpressions(this);
+    }
+    this.renderer.initItems();
+    setTimeout(function () {
+      this.trigger('DOMLoaded');
+    }.bind(this), 0);
+    this.gotoFrame();
+    if (this.autoplay) {
+      this.play();
+    }
+  }
+};
+
+AnimationItem.prototype.resize = function (width, height) {
+  // Adding this validation for backwards compatibility in case an event object was being passed down
+  var _width = typeof width === 'number' ? width : undefined;
+  var _height = typeof height === 'number' ? height : undefined;
+  this.renderer.updateContainerSize(_width, _height);
+};
+
+AnimationItem.prototype.setSubframe = function (flag) {
+  this.isSubframeEnabled = !!flag;
+};
+
+AnimationItem.prototype.gotoFrame = function () {
+  this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
+
+  if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
+    this.currentFrame = this.timeCompleted;
+  }
+  this.trigger('enterFrame');
+  this.renderFrame();
+  this.trigger('drawnFrame');
+};
+
+AnimationItem.prototype.renderFrame = function () {
+  if (this.isLoaded === false || !this.renderer) {
+    return;
+  }
+  try {
+    if (this.expressionsPlugin) {
+      this.expressionsPlugin.resetFrame();
+    }
+    this.renderer.renderFrame(this.currentFrame + this.firstFrame);
+  } catch (error) {
+    this.triggerRenderFrameError(error);
+  }
+};
+
+AnimationItem.prototype.play = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.isPaused = false;
+    this.trigger('_play');
+    this.audioController.resume();
+    if (this._idle) {
+      this._idle = false;
+      this.trigger('_active');
+    }
+  }
+};
+
+AnimationItem.prototype.pause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === false) {
+    this.isPaused = true;
+    this.trigger('_pause');
+    this._idle = true;
+    this.trigger('_idle');
+    this.audioController.pause();
+  }
+};
+
+AnimationItem.prototype.togglePause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.play();
+  } else {
+    this.pause();
+  }
+};
+
+AnimationItem.prototype.stop = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.pause();
+  this.playCount = 0;
+  this._completedLoop = false;
+  this.setCurrentRawFrameValue(0);
+};
+
+AnimationItem.prototype.getMarkerData = function (markerName) {
+  var marker;
+  for (var i = 0; i < this.markers.length; i += 1) {
+    marker = this.markers[i];
+    if (marker.payload && marker.payload.name === markerName) {
+      return marker;
+    }
+  }
+  return null;
+};
+
+AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      this.goToAndStop(marker.time, true);
+    }
+  } else if (isFrame) {
+    this.setCurrentRawFrameValue(value);
+  } else {
+    this.setCurrentRawFrameValue(value * this.frameModifier);
+  }
+  this.pause();
+};
+
+AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      if (!marker.duration) {
+        this.goToAndStop(marker.time, true);
+      } else {
+        this.playSegments([marker.time, marker.time + marker.duration], true);
+      }
+    }
+  } else {
+    this.goToAndStop(numValue, isFrame, name);
+  }
+  this.play();
+};
+
+AnimationItem.prototype.advanceTime = function (value) {
+  if (this.isPaused === true || this.isLoaded === false) {
+    return;
+  }
+  var nextValue = this.currentRawFrame + value * this.frameModifier;
+  var _isComplete = false;
+  // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+  // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
+  if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
+    if (!this.loop || this.playCount === this.loop) {
+      if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
+        _isComplete = true;
+        nextValue = this.totalFrames - 1;
+      }
+    } else if (nextValue >= this.totalFrames) {
+      this.playCount += 1;
+      if (!this.checkSegments(nextValue % this.totalFrames)) {
+        this.setCurrentRawFrameValue(nextValue % this.totalFrames);
+        this._completedLoop = true;
+        this.trigger('loopComplete');
+      }
+    } else {
+      this.setCurrentRawFrameValue(nextValue);
+    }
+  } else if (nextValue < 0) {
+    if (!this.checkSegments(nextValue % this.totalFrames)) {
+      if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) { // eslint-disable-line no-plusplus
+        this.setCurrentRawFrameValue(this.totalFrames + (nextValue % this.totalFrames));
+        if (!this._completedLoop) {
+          this._completedLoop = true;
+        } else {
+          this.trigger('loopComplete');
+        }
+      } else {
+        _isComplete = true;
+        nextValue = 0;
+      }
+    }
+  } else {
+    this.setCurrentRawFrameValue(nextValue);
+  }
+  if (_isComplete) {
+    this.setCurrentRawFrameValue(nextValue);
+    this.pause();
+    this.trigger('complete');
+  }
+};
+
+AnimationItem.prototype.adjustSegment = function (arr, offset) {
+  this.playCount = 0;
+  if (arr[1] < arr[0]) {
+    if (this.frameModifier > 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(-1);
+      }
+    }
+    this.totalFrames = arr[0] - arr[1];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[1];
+    this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset);
+  } else if (arr[1] > arr[0]) {
+    if (this.frameModifier < 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(1);
+      }
+    }
+    this.totalFrames = arr[1] - arr[0];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[0];
+    this.setCurrentRawFrameValue(0.001 + offset);
+  }
+  this.trigger('segmentStart');
+};
+AnimationItem.prototype.setSegment = function (init, end) {
+  var pendingFrame = -1;
+  if (this.isPaused) {
+    if (this.currentRawFrame + this.firstFrame < init) {
+      pendingFrame = init;
+    } else if (this.currentRawFrame + this.firstFrame > end) {
+      pendingFrame = end - init;
+    }
+  }
+
+  this.firstFrame = init;
+  this.totalFrames = end - init;
+  this.timeCompleted = this.totalFrames;
+  if (pendingFrame !== -1) {
+    this.goToAndStop(pendingFrame, true);
+  }
+};
+
+AnimationItem.prototype.playSegments = function (arr, forceFlag) {
+  if (forceFlag) {
+    this.segments.length = 0;
+  }
+  if (typeof arr[0] === 'object') {
+    var i;
+    var len = arr.length;
+    for (i = 0; i < len; i += 1) {
+      this.segments.push(arr[i]);
+    }
+  } else {
+    this.segments.push(arr);
+  }
+  if (this.segments.length && forceFlag) {
+    this.adjustSegment(this.segments.shift(), 0);
+  }
+  if (this.isPaused) {
+    this.play();
+  }
+};
+
+AnimationItem.prototype.resetSegments = function (forceFlag) {
+  this.segments.length = 0;
+  this.segments.push([this.animationData.ip, this.animationData.op]);
+  if (forceFlag) {
+    this.checkSegments(0);
+  }
+};
+AnimationItem.prototype.checkSegments = function (offset) {
+  if (this.segments.length) {
+    this.adjustSegment(this.segments.shift(), offset);
+    return true;
+  }
+  return false;
+};
+
+AnimationItem.prototype.destroy = function (name) {
+  if ((name && this.name !== name) || !this.renderer) {
+    return;
+  }
+  this.renderer.destroy();
+  this.imagePreloader.destroy();
+  this.trigger('destroy');
+  this._cbs = null;
+  this.onEnterFrame = null;
+  this.onLoopComplete = null;
+  this.onComplete = null;
+  this.onSegmentStart = null;
+  this.onDestroy = null;
+  this.renderer = null;
+  this.expressionsPlugin = null;
+  this.imagePreloader = null;
+  this.projectInterface = null;
+};
+
+AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
+  this.currentRawFrame = value;
+  this.gotoFrame();
+};
+
+AnimationItem.prototype.setSpeed = function (val) {
+  this.playSpeed = val;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setDirection = function (val) {
+  this.playDirection = val < 0 ? -1 : 1;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setLoop = function (isLooping) {
+  this.loop = isLooping;
+};
+
+AnimationItem.prototype.setVolume = function (val, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.setVolume(val);
+};
+
+AnimationItem.prototype.getVolume = function () {
+  return this.audioController.getVolume();
+};
+
+AnimationItem.prototype.mute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.mute();
+};
+
+AnimationItem.prototype.unmute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.unmute();
+};
+
+AnimationItem.prototype.updaFrameModifier = function () {
+  this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
+  this.audioController.setRate(this.playSpeed * this.playDirection);
+};
+
+AnimationItem.prototype.getPath = function () {
+  return this.path;
+};
+
+AnimationItem.prototype.getAssetsPath = function (assetData) {
+  var path = '';
+  if (assetData.e) {
+    path = assetData.p;
+  } else if (this.assetsPath) {
+    var imagePath = assetData.p;
+    if (imagePath.indexOf('images/') !== -1) {
+      imagePath = imagePath.split('/')[1];
+    }
+    path = this.assetsPath + imagePath;
+  } else {
+    path = this.path;
+    path += assetData.u ? assetData.u : '';
+    path += assetData.p;
+  }
+  return path;
+};
+
+AnimationItem.prototype.getAssetData = function (id) {
+  var i = 0;
+  var len = this.assets.length;
+  while (i < len) {
+    if (id === this.assets[i].id) {
+      return this.assets[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+AnimationItem.prototype.hide = function () {
+  this.renderer.hide();
+};
+
+AnimationItem.prototype.show = function () {
+  this.renderer.show();
+};
+
+AnimationItem.prototype.getDuration = function (isFrame) {
+  return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
+};
+
+AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
+  try {
+    var element = this.renderer.getElementByPath(path);
+    element.updateDocumentData(documentData, index);
+  } catch (error) {
+    // TODO: decide how to handle catch case
+  }
+};
+
+AnimationItem.prototype.trigger = function (name) {
+  if (this._cbs && this._cbs[name]) {
+    switch (name) {
+      case 'enterFrame':
+        this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
+        break;
+      case 'drawnFrame':
+        this.drawnFrameEvent.currentTime = this.currentFrame;
+        this.drawnFrameEvent.totalTime = this.totalFrames;
+        this.drawnFrameEvent.direction = this.frameModifier;
+        this.triggerEvent(name, this.drawnFrameEvent);
+        break;
+      case 'loopComplete':
+        this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+        break;
+      case 'complete':
+        this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
+        break;
+      case 'segmentStart':
+        this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+        break;
+      case 'destroy':
+        this.triggerEvent(name, new BMDestroyEvent(name, this));
+        break;
+      default:
+        this.triggerEvent(name);
+    }
+  }
+  if (name === 'enterFrame' && this.onEnterFrame) {
+    this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
+  }
+  if (name === 'loopComplete' && this.onLoopComplete) {
+    this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+  }
+  if (name === 'complete' && this.onComplete) {
+    this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
+  }
+  if (name === 'segmentStart' && this.onSegmentStart) {
+    this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+  }
+  if (name === 'destroy' && this.onDestroy) {
+    this.onDestroy.call(this, new BMDestroyEvent(name, this));
+  }
+};
+
+AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
+  var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+AnimationItem.prototype.triggerConfigError = function (nativeError) {
+  var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+const animationManager = (function () {
+  var moduleOb = {};
+  var registeredAnimations = [];
+  var initTime = 0;
+  var len = 0;
+  var playingAnimationsNum = 0;
+  var _stopped = true;
+  var _isFrozen = false;
+
+  function removeElement(ev) {
+    var i = 0;
+    var animItem = ev.target;
+    while (i < len) {
+      if (registeredAnimations[i].animation === animItem) {
+        registeredAnimations.splice(i, 1);
+        i -= 1;
+        len -= 1;
+        if (!animItem.isPaused) {
+          subtractPlayingCount();
+        }
+      }
+      i += 1;
+    }
+  }
+
+  function registerAnimation(element, animationData) {
+    if (!element) {
+      return null;
+    }
+    var i = 0;
+    while (i < len) {
+      if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
+        return registeredAnimations[i].animation;
+      }
+      i += 1;
+    }
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, element);
+    animItem.setData(element, animationData);
+    return animItem;
+  }
+
+  function getRegisteredAnimations() {
+    var i;
+    var lenAnims = registeredAnimations.length;
+    var animations = [];
+    for (i = 0; i < lenAnims; i += 1) {
+      animations.push(registeredAnimations[i].animation);
+    }
+    return animations;
+  }
+
+  function addPlayingCount() {
+    playingAnimationsNum += 1;
+    activate();
+  }
+
+  function subtractPlayingCount() {
+    playingAnimationsNum -= 1;
+  }
+
+  function setupAnimation(animItem, element) {
+    animItem.addEventListener('destroy', removeElement);
+    animItem.addEventListener('_active', addPlayingCount);
+    animItem.addEventListener('_idle', subtractPlayingCount);
+    registeredAnimations.push({ elem: element, animation: animItem });
+    len += 1;
+  }
+
+  function loadAnimation(params) {
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, null);
+    animItem.setParams(params);
+    return animItem;
+  }
+
+  function setSpeed(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setSpeed(val, animation);
+    }
+  }
+
+  function setDirection(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setDirection(val, animation);
+    }
+  }
+
+  function play(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.play(animation);
+    }
+  }
+  function resume(nowTime) {
+    var elapsedTime = nowTime - initTime;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.advanceTime(elapsedTime);
+    }
+    initTime = nowTime;
+    if (playingAnimationsNum && !_isFrozen) {
+      window.requestAnimationFrame(resume);
+    } else {
+      _stopped = true;
+    }
+  }
+
+  function first(nowTime) {
+    initTime = nowTime;
+    window.requestAnimationFrame(resume);
+  }
+
+  function pause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.pause(animation);
+    }
+  }
+
+  function goToAndStop(value, isFrame, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
+    }
+  }
+
+  function stop(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.stop(animation);
+    }
+  }
+
+  function togglePause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.togglePause(animation);
+    }
+  }
+
+  function destroy(animation) {
+    var i;
+    for (i = (len - 1); i >= 0; i -= 1) {
+      registeredAnimations[i].animation.destroy(animation);
+    }
+  }
+
+  function searchAnimations(animationData, standalone, renderer) {
+    var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')),
+      [].slice.call(document.getElementsByClassName('bodymovin')));
+    var i;
+    var lenAnims = animElements.length;
+    for (i = 0; i < lenAnims; i += 1) {
+      if (renderer) {
+        animElements[i].setAttribute('data-bm-type', renderer);
+      }
+      registerAnimation(animElements[i], animationData);
+    }
+    if (standalone && lenAnims === 0) {
+      if (!renderer) {
+        renderer = 'svg';
+      }
+      var body = document.getElementsByTagName('body')[0];
+      body.innerText = '';
+      var div = createTag('div');
+      div.style.width = '100%';
+      div.style.height = '100%';
+      div.setAttribute('data-bm-type', renderer);
+      body.appendChild(div);
+      registerAnimation(div, animationData);
+    }
+  }
+
+  function resize() {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.resize();
+    }
+  }
+
+  function activate() {
+    if (!_isFrozen && playingAnimationsNum) {
+      if (_stopped) {
+        window.requestAnimationFrame(first);
+        _stopped = false;
+      }
+    }
+  }
+
+  function freeze() {
+    _isFrozen = true;
+  }
+
+  function unfreeze() {
+    _isFrozen = false;
+    activate();
+  }
+
+  function setVolume(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setVolume(val, animation);
+    }
+  }
+
+  function mute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.mute(animation);
+    }
+  }
+
+  function unmute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.unmute(animation);
+    }
+  }
+
+  moduleOb.registerAnimation = registerAnimation;
+  moduleOb.loadAnimation = loadAnimation;
+  moduleOb.setSpeed = setSpeed;
+  moduleOb.setDirection = setDirection;
+  moduleOb.play = play;
+  moduleOb.pause = pause;
+  moduleOb.stop = stop;
+  moduleOb.togglePause = togglePause;
+  moduleOb.searchAnimations = searchAnimations;
+  moduleOb.resize = resize;
+  // moduleOb.start = start;
+  moduleOb.goToAndStop = goToAndStop;
+  moduleOb.destroy = destroy;
+  moduleOb.freeze = freeze;
+  moduleOb.unfreeze = unfreeze;
+  moduleOb.setVolume = setVolume;
+  moduleOb.mute = mute;
+  moduleOb.unmute = unmute;
+  moduleOb.getRegisteredAnimations = getRegisteredAnimations;
+  return moduleOb;
+}());
+
+/* eslint-disable */
+const BezierFactory = (function () {
+  /**
+     * BezierEasing - use bezier curve for transition easing function
+     * by Gaëtan Renaudeau 2014 - 2015 – MIT License
+     *
+     * Credits: is based on Firefox's nsSMILKeySpline.cpp
+     * Usage:
+     * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
+     * spline.get(x) => returns the easing value | x must be in [0, 1] range
+     *
+     */
+
+  var ob = {};
+  ob.getBezierEasing = getBezierEasing;
+  var beziers = {};
+
+  function getBezierEasing(a, b, c, d, nm) {
+    var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
+    if (beziers[str]) {
+      return beziers[str];
+    }
+    var bezEasing = new BezierEasing([a, b, c, d]);
+    beziers[str] = bezEasing;
+    return bezEasing;
+  }
+
+  // These values are established by empiricism with tests (tradeoff: performance VS precision)
+  var NEWTON_ITERATIONS = 4;
+  var NEWTON_MIN_SLOPE = 0.001;
+  var SUBDIVISION_PRECISION = 0.0000001;
+  var SUBDIVISION_MAX_ITERATIONS = 10;
+
+  var kSplineTableSize = 11;
+  var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
+
+  var float32ArraySupported = typeof Float32Array === 'function';
+
+  function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
+  function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
+  function C(aA1) { return 3.0 * aA1; }
+
+  // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+  function calcBezier(aT, aA1, aA2) {
+    return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
+  }
+
+  // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+  function getSlope(aT, aA1, aA2) {
+    return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
+  }
+
+  function binarySubdivide(aX, aA, aB, mX1, mX2) {
+    var currentX,
+      currentT,
+      i = 0;
+    do {
+      currentT = aA + (aB - aA) / 2.0;
+      currentX = calcBezier(currentT, mX1, mX2) - aX;
+      if (currentX > 0.0) {
+        aB = currentT;
+      } else {
+        aA = currentT;
+      }
+    } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
+    return currentT;
+  }
+
+  function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
+    for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
+      var currentSlope = getSlope(aGuessT, mX1, mX2);
+      if (currentSlope === 0.0) return aGuessT;
+      var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
+      aGuessT -= currentX / currentSlope;
+    }
+    return aGuessT;
+  }
+
+  /**
+     * points is an array of [ mX1, mY1, mX2, mY2 ]
+     */
+  function BezierEasing(points) {
+    this._p = points;
+    this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
+    this._precomputed = false;
+
+    this.get = this.get.bind(this);
+  }
+
+  BezierEasing.prototype = {
+
+    get: function (x) {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      if (!this._precomputed) this._precompute();
+      if (mX1 === mY1 && mX2 === mY2) return x; // linear
+      // Because JavaScript number are imprecise, we should guarantee the extremes are right.
+      if (x === 0) return 0;
+      if (x === 1) return 1;
+      return calcBezier(this._getTForX(x), mY1, mY2);
+    },
+
+    // Private part
+
+    _precompute: function () {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      this._precomputed = true;
+      if (mX1 !== mY1 || mX2 !== mY2) { this._calcSampleValues(); }
+    },
+
+    _calcSampleValues: function () {
+      var mX1 = this._p[0],
+        mX2 = this._p[2];
+      for (var i = 0; i < kSplineTableSize; ++i) {
+        this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
+      }
+    },
+
+    /**
+         * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
+         */
+    _getTForX: function (aX) {
+      var mX1 = this._p[0],
+        mX2 = this._p[2],
+        mSampleValues = this._mSampleValues;
+
+      var intervalStart = 0.0;
+      var currentSample = 1;
+      var lastSample = kSplineTableSize - 1;
+
+      for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
+        intervalStart += kSampleStepSize;
+      }
+      --currentSample;
+
+      // Interpolate to provide an initial guess for t
+      var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
+      var guessForT = intervalStart + dist * kSampleStepSize;
+
+      var initialSlope = getSlope(guessForT, mX1, mX2);
+      if (initialSlope >= NEWTON_MIN_SLOPE) {
+        return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
+      } if (initialSlope === 0.0) {
+        return guessForT;
+      }
+      return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
+    },
+  };
+
+  return ob;
+}());
+
+const pooling = (function () {
+  function double(arr) {
+    return arr.concat(createSizedArray(arr.length));
+  }
+
+  return {
+    double: double,
+  };
+}());
+
+const poolFactory = (function () {
+  return function (initialLength, _create, _release) {
+    var _length = 0;
+    var _maxLength = initialLength;
+    var pool = createSizedArray(_maxLength);
+
+    var ob = {
+      newElement: newElement,
+      release: release,
+    };
+
+    function newElement() {
+      var element;
+      if (_length) {
+        _length -= 1;
+        element = pool[_length];
+      } else {
+        element = _create();
+      }
+      return element;
+    }
+
+    function release(element) {
+      if (_length === _maxLength) {
+        pool = pooling.double(pool);
+        _maxLength *= 2;
+      }
+      if (_release) {
+        _release(element);
+      }
+      pool[_length] = element;
+      _length += 1;
+    }
+
+    return ob;
+  };
+}());
+
+const bezierLengthPool = (function () {
+  function create() {
+    return {
+      addedLength: 0,
+      percents: createTypedArray('float32', getDefaultCurveSegments()),
+      lengths: createTypedArray('float32', getDefaultCurveSegments()),
+    };
+  }
+  return poolFactory(8, create);
+}());
+
+const segmentsLengthPool = (function () {
+  function create() {
+    return {
+      lengths: [],
+      totalLength: 0,
+    };
+  }
+
+  function release(element) {
+    var i;
+    var len = element.lengths.length;
+    for (i = 0; i < len; i += 1) {
+      bezierLengthPool.release(element.lengths[i]);
+    }
+    element.lengths.length = 0;
+  }
+
+  return poolFactory(8, create, release);
+}());
+
+function bezFunction() {
+  var math = Math;
+
+  function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
+    var det1 = (x1 * y2) + (y1 * x3) + (x2 * y3) - (x3 * y2) - (y3 * x1) - (x2 * y1);
+    return det1 > -0.001 && det1 < 0.001;
+  }
+
+  function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
+    if (z1 === 0 && z2 === 0 && z3 === 0) {
+      return pointOnLine2D(x1, y1, x2, y2, x3, y3);
+    }
+    var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
+    var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
+    var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
+    var diffDist;
+    if (dist1 > dist2) {
+      if (dist1 > dist3) {
+        diffDist = dist1 - dist2 - dist3;
+      } else {
+        diffDist = dist3 - dist2 - dist1;
+      }
+    } else if (dist3 > dist2) {
+      diffDist = dist3 - dist2 - dist1;
+    } else {
+      diffDist = dist2 - dist1 - dist3;
+    }
+    return diffDist > -0.0001 && diffDist < 0.0001;
+  }
+
+  var getBezierLength = (function () {
+    return function (pt1, pt2, pt3, pt4) {
+      var curveSegments = getDefaultCurveSegments();
+      var k;
+      var i;
+      var len;
+      var ptCoord;
+      var perc;
+      var addedLength = 0;
+      var ptDistance;
+      var point = [];
+      var lastPoint = [];
+      var lengthData = bezierLengthPool.newElement();
+      len = pt3.length;
+      for (k = 0; k < curveSegments; k += 1) {
+        perc = k / (curveSegments - 1);
+        ptDistance = 0;
+        for (i = 0; i < len; i += 1) {
+          ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
+          point[i] = ptCoord;
+          if (lastPoint[i] !== null) {
+            ptDistance += bmPow(point[i] - lastPoint[i], 2);
+          }
+          lastPoint[i] = point[i];
+        }
+        if (ptDistance) {
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+        }
+        lengthData.percents[k] = perc;
+        lengthData.lengths[k] = addedLength;
+      }
+      lengthData.addedLength = addedLength;
+      return lengthData;
+    };
+  }());
+
+  function getSegmentsLength(shapeData) {
+    var segmentsLength = segmentsLengthPool.newElement();
+    var closed = shapeData.c;
+    var pathV = shapeData.v;
+    var pathO = shapeData.o;
+    var pathI = shapeData.i;
+    var i;
+    var len = shapeData._length;
+    var lengths = segmentsLength.lengths;
+    var totalLength = 0;
+    for (i = 0; i < len - 1; i += 1) {
+      lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
+      totalLength += lengths[i].addedLength;
+    }
+    if (closed && len) {
+      lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
+      totalLength += lengths[i].addedLength;
+    }
+    segmentsLength.totalLength = totalLength;
+    return segmentsLength;
+  }
+
+  function BezierData(length) {
+    this.segmentLength = 0;
+    this.points = new Array(length);
+  }
+
+  function PointData(partial, point) {
+    this.partialLength = partial;
+    this.point = point;
+  }
+
+  var buildBezierData = (function () {
+    var storedData = {};
+
+    return function (pt1, pt2, pt3, pt4) {
+      var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
+      if (!storedData[bezierName]) {
+        var curveSegments = getDefaultCurveSegments();
+        var k;
+        var i;
+        var len;
+        var ptCoord;
+        var perc;
+        var addedLength = 0;
+        var ptDistance;
+        var point;
+        var lastPoint = null;
+        if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
+          curveSegments = 2;
+        }
+        var bezierData = new BezierData(curveSegments);
+        len = pt3.length;
+        for (k = 0; k < curveSegments; k += 1) {
+          point = createSizedArray(len);
+          perc = k / (curveSegments - 1);
+          ptDistance = 0;
+          for (i = 0; i < len; i += 1) {
+            ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
+            point[i] = ptCoord;
+            if (lastPoint !== null) {
+              ptDistance += bmPow(point[i] - lastPoint[i], 2);
+            }
+          }
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+          bezierData.points[k] = new PointData(ptDistance, point);
+          lastPoint = point;
+        }
+        bezierData.segmentLength = addedLength;
+        storedData[bezierName] = bezierData;
+      }
+      return storedData[bezierName];
+    };
+  }());
+
+  function getDistancePerc(perc, bezierData) {
+    var percents = bezierData.percents;
+    var lengths = bezierData.lengths;
+    var len = percents.length;
+    var initPos = bmFloor((len - 1) * perc);
+    var lengthPos = perc * bezierData.addedLength;
+    var lPerc = 0;
+    if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
+      return percents[initPos];
+    }
+    var dir = lengths[initPos] > lengthPos ? -1 : 1;
+    var flag = true;
+    while (flag) {
+      if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
+        lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
+        flag = false;
+      } else {
+        initPos += dir;
+      }
+      if (initPos < 0 || initPos >= len - 1) {
+        // FIX for TypedArrays that don't store floating point values with enough accuracy
+        if (initPos === len - 1) {
+          return percents[initPos];
+        }
+        flag = false;
+      }
+    }
+    return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
+  }
+
+  function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
+    var t1 = getDistancePerc(percent, bezierData);
+    var u1 = 1 - t1;
+    var ptX = math.round((u1 * u1 * u1 * pt1[0] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[0] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[0] + t1 * t1 * t1 * pt2[0]) * 1000) / 1000;
+    var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
+    return [ptX, ptY];
+  }
+
+  var bezierSegmentPoints = createTypedArray('float32', 8);
+
+  function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
+    if (startPerc < 0) {
+      startPerc = 0;
+    } else if (startPerc > 1) {
+      startPerc = 1;
+    }
+    var t0 = getDistancePerc(startPerc, bezierData);
+    endPerc = endPerc > 1 ? 1 : endPerc;
+    var t1 = getDistancePerc(endPerc, bezierData);
+    var i;
+    var len = pt1.length;
+    var u0 = 1 - t0;
+    var u1 = 1 - t1;
+    var u0u0u0 = u0 * u0 * u0;
+    var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0t0 = t0 * t0 * t0;
+    //
+    var u0u0u1 = u0 * u0 * u1;
+    var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0t1 = t0 * t0 * t1;
+    //
+    var u0u1u1 = u0 * u1 * u1;
+    var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1t1 = t0 * t1 * t1;
+    //
+    var u1u1u1 = u1 * u1 * u1;
+    var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1t1 = t1 * t1 * t1;
+    for (i = 0; i < len; i += 1) {
+      bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+    }
+
+    return bezierSegmentPoints;
+  }
+
+  return {
+    getSegmentsLength: getSegmentsLength,
+    getNewSegment: getNewSegment,
+    getPointInSegment: getPointInSegment,
+    buildBezierData: buildBezierData,
+    pointOnLine2D: pointOnLine2D,
+    pointOnLine3D: pointOnLine3D,
+  };
+}
+
+const bez = bezFunction();
+
+var initFrame = initialDefaultFrame;
+var mathAbs = Math.abs;
+
+function interpolateValue(frameNum, caching) {
+  var offsetTime = this.offsetTime;
+  var newValue;
+  if (this.propType === 'multidimensional') {
+    newValue = createTypedArray('float32', this.pv.length);
+  }
+  var iterationIndex = caching.lastIndex;
+  var i = iterationIndex;
+  var len = this.keyframes.length - 1;
+  var flag = true;
+  var keyData;
+  var nextKeyData;
+  var keyframeMetadata;
+
+  while (flag) {
+    keyData = this.keyframes[i];
+    nextKeyData = this.keyframes[i + 1];
+    if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
+      if (keyData.h) {
+        keyData = nextKeyData;
+      }
+      iterationIndex = 0;
+      break;
+    }
+    if ((nextKeyData.t - offsetTime) > frameNum) {
+      iterationIndex = i;
+      break;
+    }
+    if (i < len - 1) {
+      i += 1;
+    } else {
+      iterationIndex = 0;
+      flag = false;
+    }
+  }
+  keyframeMetadata = this.keyframesMetadata[i] || {};
+
+  var k;
+  var kLen;
+  var perc;
+  var jLen;
+  var j;
+  var fnc;
+  var nextKeyTime = nextKeyData.t - offsetTime;
+  var keyTime = keyData.t - offsetTime;
+  var endValue;
+  if (keyData.to) {
+    if (!keyframeMetadata.bezierData) {
+      keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
+    }
+    var bezierData = keyframeMetadata.bezierData;
+    if (frameNum >= nextKeyTime || frameNum < keyTime) {
+      var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
+      kLen = bezierData.points[ind].point.length;
+      for (k = 0; k < kLen; k += 1) {
+        newValue[k] = bezierData.points[ind].point[k];
+      }
+      // caching._lastKeyframeIndex = -1;
+    } else {
+      if (keyframeMetadata.__fnct) {
+        fnc = keyframeMetadata.__fnct;
+      } else {
+        fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
+        keyframeMetadata.__fnct = fnc;
+      }
+      perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+      var distanceInLine = bezierData.segmentLength * perc;
+
+      var segmentPerc;
+      var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0;
+      j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0;
+      flag = true;
+      jLen = bezierData.points.length;
+      while (flag) {
+        addedLength += bezierData.points[j].partialLength;
+        if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k];
+          }
+          break;
+        } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
+          segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
+          }
+          break;
+        }
+        if (j < jLen - 1) {
+          j += 1;
+        } else {
+          flag = false;
+        }
+      }
+      caching._lastPoint = j;
+      caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
+      caching._lastKeyframeIndex = i;
+    }
+  } else {
+    var outX;
+    var outY;
+    var inX;
+    var inY;
+    var keyValue;
+    len = keyData.s.length;
+    endValue = nextKeyData.s || keyData.e;
+    if (this.sh && keyData.h !== 1) {
+      if (frameNum >= nextKeyTime) {
+        newValue[0] = endValue[0];
+        newValue[1] = endValue[1];
+        newValue[2] = endValue[2];
+      } else if (frameNum <= keyTime) {
+        newValue[0] = keyData.s[0];
+        newValue[1] = keyData.s[1];
+        newValue[2] = keyData.s[2];
+      } else {
+        var quatStart = createQuaternion(keyData.s);
+        var quatEnd = createQuaternion(endValue);
+        var time = (frameNum - keyTime) / (nextKeyTime - keyTime);
+        quaternionToEuler(newValue, slerp(quatStart, quatEnd, time));
+      }
+    } else {
+      for (i = 0; i < len; i += 1) {
+        if (keyData.h !== 1) {
+          if (frameNum >= nextKeyTime) {
+            perc = 1;
+          } else if (frameNum < keyTime) {
+            perc = 0;
+          } else {
+            if (keyData.o.x.constructor === Array) {
+              if (!keyframeMetadata.__fnct) {
+                keyframeMetadata.__fnct = [];
+              }
+              if (!keyframeMetadata.__fnct[i]) {
+                outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
+                outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
+                inX = keyData.i.x[i] === undefined ? keyData.i.x[0] : keyData.i.x[i];
+                inY = keyData.i.y[i] === undefined ? keyData.i.y[0] : keyData.i.y[i];
+                fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+                keyframeMetadata.__fnct[i] = fnc;
+              } else {
+                fnc = keyframeMetadata.__fnct[i];
+              }
+            } else if (!keyframeMetadata.__fnct) {
+              outX = keyData.o.x;
+              outY = keyData.o.y;
+              inX = keyData.i.x;
+              inY = keyData.i.y;
+              fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+              keyData.keyframeMetadata = fnc;
+            } else {
+              fnc = keyframeMetadata.__fnct;
+            }
+            perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+          }
+        }
+
+        endValue = nextKeyData.s || keyData.e;
+        keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
+
+        if (this.propType === 'multidimensional') {
+          newValue[i] = keyValue;
+        } else {
+          newValue = keyValue;
+        }
+      }
+    }
+  }
+  caching.lastIndex = iterationIndex;
+  return newValue;
+}
+
+// based on @Toji's https://github.com/toji/gl-matrix/
+function slerp(a, b, t) {
+  var out = [];
+  var ax = a[0];
+  var ay = a[1];
+  var az = a[2];
+  var aw = a[3];
+  var bx = b[0];
+  var by = b[1];
+  var bz = b[2];
+  var bw = b[3];
+
+  var omega;
+  var cosom;
+  var sinom;
+  var scale0;
+  var scale1;
+
+  cosom = ax * bx + ay * by + az * bz + aw * bw;
+  if (cosom < 0.0) {
+    cosom = -cosom;
+    bx = -bx;
+    by = -by;
+    bz = -bz;
+    bw = -bw;
+  }
+  if ((1.0 - cosom) > 0.000001) {
+    omega = Math.acos(cosom);
+    sinom = Math.sin(omega);
+    scale0 = Math.sin((1.0 - t) * omega) / sinom;
+    scale1 = Math.sin(t * omega) / sinom;
+  } else {
+    scale0 = 1.0 - t;
+    scale1 = t;
+  }
+  out[0] = scale0 * ax + scale1 * bx;
+  out[1] = scale0 * ay + scale1 * by;
+  out[2] = scale0 * az + scale1 * bz;
+  out[3] = scale0 * aw + scale1 * bw;
+
+  return out;
+}
+
+function quaternionToEuler(out, quat) {
+  var qx = quat[0];
+  var qy = quat[1];
+  var qz = quat[2];
+  var qw = quat[3];
+  var heading = Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy * qy - 2 * qz * qz);
+  var attitude = Math.asin(2 * qx * qy + 2 * qz * qw);
+  var bank = Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx * qx - 2 * qz * qz);
+  out[0] = heading / degToRads;
+  out[1] = attitude / degToRads;
+  out[2] = bank / degToRads;
+}
+
+function createQuaternion(values) {
+  var heading = values[0] * degToRads;
+  var attitude = values[1] * degToRads;
+  var bank = values[2] * degToRads;
+  var c1 = Math.cos(heading / 2);
+  var c2 = Math.cos(attitude / 2);
+  var c3 = Math.cos(bank / 2);
+  var s1 = Math.sin(heading / 2);
+  var s2 = Math.sin(attitude / 2);
+  var s3 = Math.sin(bank / 2);
+  var w = c1 * c2 * c3 - s1 * s2 * s3;
+  var x = s1 * s2 * c3 + c1 * c2 * s3;
+  var y = s1 * c2 * c3 + c1 * s2 * s3;
+  var z = c1 * s2 * c3 - s1 * c2 * s3;
+
+  return [x, y, z, w];
+}
+
+function getValueAtCurrentTime() {
+  var frameNum = this.comp.renderedFrame - this.offsetTime;
+  var initTime = this.keyframes[0].t - this.offsetTime;
+  var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+  if (!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))) {
+    if (this._caching.lastFrame >= frameNum) {
+      this._caching._lastKeyframeIndex = -1;
+      this._caching.lastIndex = 0;
+    }
+
+    var renderResult = this.interpolateValue(frameNum, this._caching);
+    this.pv = renderResult;
+  }
+  this._caching.lastFrame = frameNum;
+  return this.pv;
+}
+
+function setVValue(val) {
+  var multipliedValue;
+  if (this.propType === 'unidimensional') {
+    multipliedValue = val * this.mult;
+    if (mathAbs(this.v - multipliedValue) > 0.00001) {
+      this.v = multipliedValue;
+      this._mdf = true;
+    }
+  } else {
+    var i = 0;
+    var len = this.v.length;
+    while (i < len) {
+      multipliedValue = val[i] * this.mult;
+      if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
+        this.v[i] = multipliedValue;
+        this._mdf = true;
+      }
+      i += 1;
+    }
+  }
+}
+
+function processEffectsSequence() {
+  if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
+    return;
+  }
+  if (this.lock) {
+    this.setVValue(this.pv);
+    return;
+  }
+  this.lock = true;
+  this._mdf = this._isFirstFrame;
+  var i;
+  var len = this.effectsSequence.length;
+  var finalValue = this.kf ? this.pv : this.data.k;
+  for (i = 0; i < len; i += 1) {
+    finalValue = this.effectsSequence[i](finalValue);
+  }
+  this.setVValue(finalValue);
+  this._isFirstFrame = false;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+}
+
+function addEffect(effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.container.addDynamicProperty(this);
+}
+
+function ValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this.v = mult ? data.k * mult : data.k;
+  this.pv = data.k;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.vel = 0;
+  this.effectsSequence = [];
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function MultiDimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.frameId = -1;
+  var i;
+  var len = data.k.length;
+  this.v = createTypedArray('float32', len);
+  this.pv = createTypedArray('float32', len);
+  this.vel = createTypedArray('float32', len);
+  for (i = 0; i < len; i += 1) {
+    this.v[i] = data.k[i] * this.mult;
+    this.pv[i] = data.k[i];
+  }
+  this._isFirstFrame = true;
+  this.effectsSequence = [];
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function KeyframedValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.frameId = -1;
+  this._caching = {
+    lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1,
+  };
+  this.k = true;
+  this.kf = true;
+  this.data = data;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.v = initFrame;
+  this.pv = initFrame;
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.addEffect = addEffect;
+}
+
+function KeyframedMultidimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  var i;
+  var len = data.k.length;
+  var s;
+  var e;
+  var to;
+  var ti;
+  for (i = 0; i < len - 1; i += 1) {
+    if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
+      s = data.k[i].s;
+      e = data.k[i + 1].s;
+      to = data.k[i].to;
+      ti = data.k[i].ti;
+      if ((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2]))) {
+        data.k[i].to = null;
+        data.k[i].ti = null;
+      }
+      if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
+        if (s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) {
+          data.k[i].to = null;
+          data.k[i].ti = null;
+        }
+      }
+    }
+  }
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.data = data;
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.k = true;
+  this.kf = true;
+  this._isFirstFrame = true;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.frameId = -1;
+  var arrLen = data.k[0].s.length;
+  this.v = createTypedArray('float32', arrLen);
+  this.pv = createTypedArray('float32', arrLen);
+  for (i = 0; i < arrLen; i += 1) {
+    this.v[i] = initFrame;
+    this.pv[i] = initFrame;
+  }
+  this._caching = { lastFrame: initFrame, lastIndex: 0, value: createTypedArray('float32', arrLen) };
+  this.addEffect = addEffect;
+}
+
+const PropertyFactory = (function () {
+  function getProp(elem, data, type, mult, container) {
+    if (data.sid) {
+      data = elem.globalData.slotManager.getProp(data);
+    }
+    var p;
+    if (!data.k.length) {
+      p = new ValueProperty(elem, data, mult, container);
+    } else if (typeof (data.k[0]) === 'number') {
+      p = new MultiDimensionalProperty(elem, data, mult, container);
+    } else {
+      switch (type) {
+        case 0:
+          p = new KeyframedValueProperty(elem, data, mult, container);
+          break;
+        case 1:
+          p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
+          break;
+        default:
+          break;
+      }
+    }
+    if (p.effectsSequence.length) {
+      container.addDynamicProperty(p);
+    }
+    return p;
+  }
+
+  var ob = {
+    getProp: getProp,
+  };
+  return ob;
+}());
+
+function DynamicPropertyContainer() {}
+DynamicPropertyContainer.prototype = {
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+      this.container.addDynamicProperty(this);
+      this._isAnimated = true;
+    }
+  },
+  iterateDynamicProperties: function () {
+    this._mdf = false;
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      this.dynamicProperties[i].getValue();
+      if (this.dynamicProperties[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  },
+  initDynamicPropertyContainer: function (container) {
+    this.container = container;
+    this.dynamicProperties = [];
+    this._mdf = false;
+    this._isAnimated = false;
+  },
+};
+
+const pointPool = (function () {
+  function create() {
+    return createTypedArray('float32', 2);
+  }
+  return poolFactory(8, create);
+}());
+
+function ShapePath() {
+  this.c = false;
+  this._length = 0;
+  this._maxLength = 8;
+  this.v = createSizedArray(this._maxLength);
+  this.o = createSizedArray(this._maxLength);
+  this.i = createSizedArray(this._maxLength);
+}
+
+ShapePath.prototype.setPathData = function (closed, len) {
+  this.c = closed;
+  this.setLength(len);
+  var i = 0;
+  while (i < len) {
+    this.v[i] = pointPool.newElement();
+    this.o[i] = pointPool.newElement();
+    this.i[i] = pointPool.newElement();
+    i += 1;
+  }
+};
+
+ShapePath.prototype.setLength = function (len) {
+  while (this._maxLength < len) {
+    this.doubleArrayLength();
+  }
+  this._length = len;
+};
+
+ShapePath.prototype.doubleArrayLength = function () {
+  this.v = this.v.concat(createSizedArray(this._maxLength));
+  this.i = this.i.concat(createSizedArray(this._maxLength));
+  this.o = this.o.concat(createSizedArray(this._maxLength));
+  this._maxLength *= 2;
+};
+
+ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
+  var arr;
+  this._length = Math.max(this._length, pos + 1);
+  if (this._length >= this._maxLength) {
+    this.doubleArrayLength();
+  }
+  switch (type) {
+    case 'v':
+      arr = this.v;
+      break;
+    case 'i':
+      arr = this.i;
+      break;
+    case 'o':
+      arr = this.o;
+      break;
+    default:
+      arr = [];
+      break;
+  }
+  if (!arr[pos] || (arr[pos] && !replace)) {
+    arr[pos] = pointPool.newElement();
+  }
+  arr[pos][0] = x;
+  arr[pos][1] = y;
+};
+
+ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
+  this.setXYAt(vX, vY, 'v', pos, replace);
+  this.setXYAt(oX, oY, 'o', pos, replace);
+  this.setXYAt(iX, iY, 'i', pos, replace);
+};
+
+ShapePath.prototype.reverse = function () {
+  var newPath = new ShapePath();
+  newPath.setPathData(this.c, this._length);
+  var vertices = this.v;
+  var outPoints = this.o;
+  var inPoints = this.i;
+  var init = 0;
+  if (this.c) {
+    newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
+    init = 1;
+  }
+  var cnt = this._length - 1;
+  var len = this._length;
+
+  var i;
+  for (i = init; i < len; i += 1) {
+    newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
+    cnt -= 1;
+  }
+  return newPath;
+};
+
+ShapePath.prototype.length = function () {
+  return this._length;
+};
+
+const shapePool = (function () {
+  function create() {
+    return new ShapePath();
+  }
+
+  function release(shapePath) {
+    var len = shapePath._length;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      pointPool.release(shapePath.v[i]);
+      pointPool.release(shapePath.i[i]);
+      pointPool.release(shapePath.o[i]);
+      shapePath.v[i] = null;
+      shapePath.i[i] = null;
+      shapePath.o[i] = null;
+    }
+    shapePath._length = 0;
+    shapePath.c = false;
+  }
+
+  function clone(shape) {
+    var cloned = factory.newElement();
+    var i;
+    var len = shape._length === undefined ? shape.v.length : shape._length;
+    cloned.setLength(len);
+    cloned.c = shape.c;
+
+    for (i = 0; i < len; i += 1) {
+      cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
+    }
+    return cloned;
+  }
+
+  var factory = poolFactory(4, create, release);
+  factory.clone = clone;
+
+  return factory;
+}());
+
+function ShapeCollection() {
+  this._length = 0;
+  this._maxLength = 4;
+  this.shapes = createSizedArray(this._maxLength);
+}
+
+ShapeCollection.prototype.addShape = function (shapeData) {
+  if (this._length === this._maxLength) {
+    this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
+    this._maxLength *= 2;
+  }
+  this.shapes[this._length] = shapeData;
+  this._length += 1;
+};
+
+ShapeCollection.prototype.releaseShapes = function () {
+  var i;
+  for (i = 0; i < this._length; i += 1) {
+    shapePool.release(this.shapes[i]);
+  }
+  this._length = 0;
+};
+
+const shapeCollectionPool = (function () {
+  var ob = {
+    newShapeCollection: newShapeCollection,
+    release: release,
+  };
+
+  var _length = 0;
+  var _maxLength = 4;
+  var pool = createSizedArray(_maxLength);
+
+  function newShapeCollection() {
+    var shapeCollection;
+    if (_length) {
+      _length -= 1;
+      shapeCollection = pool[_length];
+    } else {
+      shapeCollection = new ShapeCollection();
+    }
+    return shapeCollection;
+  }
+
+  function release(shapeCollection) {
+    var i;
+    var len = shapeCollection._length;
+    for (i = 0; i < len; i += 1) {
+      shapePool.release(shapeCollection.shapes[i]);
+    }
+    shapeCollection._length = 0;
+
+    if (_length === _maxLength) {
+      pool = pooling.double(pool);
+      _maxLength *= 2;
+    }
+    pool[_length] = shapeCollection;
+    _length += 1;
+  }
+
+  return ob;
+}());
+
+const ShapePropertyFactory = (function () {
+  var initFrame = -999999;
+
+  function interpolateShape(frameNum, previousValue, caching) {
+    var iterationIndex = caching.lastIndex;
+    var keyPropS;
+    var keyPropE;
+    var isHold;
+    var j;
+    var k;
+    var jLen;
+    var kLen;
+    var perc;
+    var vertexValue;
+    var kf = this.keyframes;
+    if (frameNum < kf[0].t - this.offsetTime) {
+      keyPropS = kf[0].s[0];
+      isHold = true;
+      iterationIndex = 0;
+    } else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) {
+      keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
+      /* if(kf[kf.length - 1].s){
+                keyPropS = kf[kf.length - 1].s[0];
+            }else{
+                keyPropS = kf[kf.length - 2].e[0];
+            } */
+      isHold = true;
+    } else {
+      var i = iterationIndex;
+      var len = kf.length - 1;
+      var flag = true;
+      var keyData;
+      var nextKeyData;
+      var keyframeMetadata;
+      while (flag) {
+        keyData = kf[i];
+        nextKeyData = kf[i + 1];
+        if ((nextKeyData.t - this.offsetTime) > frameNum) {
+          break;
+        }
+        if (i < len - 1) {
+          i += 1;
+        } else {
+          flag = false;
+        }
+      }
+      keyframeMetadata = this.keyframesMetadata[i] || {};
+      isHold = keyData.h === 1;
+      iterationIndex = i;
+      if (!isHold) {
+        if (frameNum >= nextKeyData.t - this.offsetTime) {
+          perc = 1;
+        } else if (frameNum < keyData.t - this.offsetTime) {
+          perc = 0;
+        } else {
+          var fnc;
+          if (keyframeMetadata.__fnct) {
+            fnc = keyframeMetadata.__fnct;
+          } else {
+            fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
+            keyframeMetadata.__fnct = fnc;
+          }
+          perc = fnc((frameNum - (keyData.t - this.offsetTime)) / ((nextKeyData.t - this.offsetTime) - (keyData.t - this.offsetTime)));
+        }
+        keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
+      }
+      keyPropS = keyData.s[0];
+    }
+    jLen = previousValue._length;
+    kLen = keyPropS.i[0].length;
+    caching.lastIndex = iterationIndex;
+
+    for (j = 0; j < jLen; j += 1) {
+      for (k = 0; k < kLen; k += 1) {
+        vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
+        previousValue.i[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc;
+        previousValue.o[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc;
+        previousValue.v[j][k] = vertexValue;
+      }
+    }
+  }
+
+  function interpolateShapeCurrentTime() {
+    var frameNum = this.comp.renderedFrame - this.offsetTime;
+    var initTime = this.keyframes[0].t - this.offsetTime;
+    var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+    var lastFrame = this._caching.lastFrame;
+    if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) {
+      /// /
+      this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
+      this.interpolateShape(frameNum, this.pv, this._caching);
+      /// /
+    }
+    this._caching.lastFrame = frameNum;
+    return this.pv;
+  }
+
+  function resetShape() {
+    this.paths = this.localShapeCollection;
+  }
+
+  function shapesEqual(shape1, shape2) {
+    if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
+      return false;
+    }
+    var i;
+    var len = shape1._length;
+    for (i = 0; i < len; i += 1) {
+      if (shape1.v[i][0] !== shape2.v[i][0]
+            || shape1.v[i][1] !== shape2.v[i][1]
+            || shape1.o[i][0] !== shape2.o[i][0]
+            || shape1.o[i][1] !== shape2.o[i][1]
+            || shape1.i[i][0] !== shape2.i[i][0]
+            || shape1.i[i][1] !== shape2.i[i][1]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  function setVValue(newPath) {
+    if (!shapesEqual(this.v, newPath)) {
+      this.v = shapePool.clone(newPath);
+      this.localShapeCollection.releaseShapes();
+      this.localShapeCollection.addShape(this.v);
+      this._mdf = true;
+      this.paths = this.localShapeCollection;
+    }
+  }
+
+  function processEffectsSequence() {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    } if (!this.effectsSequence.length) {
+      this._mdf = false;
+      return;
+    }
+    if (this.lock) {
+      this.setVValue(this.pv);
+      return;
+    }
+    this.lock = true;
+    this._mdf = false;
+    var finalValue;
+    if (this.kf) {
+      finalValue = this.pv;
+    } else if (this.data.ks) {
+      finalValue = this.data.ks.k;
+    } else {
+      finalValue = this.data.pt.k;
+    }
+    var i;
+    var len = this.effectsSequence.length;
+    for (i = 0; i < len; i += 1) {
+      finalValue = this.effectsSequence[i](finalValue);
+    }
+    this.setVValue(finalValue);
+    this.lock = false;
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function ShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.container = elem;
+    this.elem = elem;
+    this.data = data;
+    this.k = false;
+    this.kf = false;
+    this._mdf = false;
+    var pathData = type === 3 ? data.pt.k : data.ks.k;
+    this.v = shapePool.clone(pathData);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.reset = resetShape;
+    this.effectsSequence = [];
+  }
+
+  function addEffect(effectFunction) {
+    this.effectsSequence.push(effectFunction);
+    this.container.addDynamicProperty(this);
+  }
+
+  ShapeProperty.prototype.interpolateShape = interpolateShape;
+  ShapeProperty.prototype.getValue = processEffectsSequence;
+  ShapeProperty.prototype.setVValue = setVValue;
+  ShapeProperty.prototype.addEffect = addEffect;
+
+  function KeyframedShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.elem = elem;
+    this.container = elem;
+    this.offsetTime = elem.data.st;
+    this.keyframes = type === 3 ? data.pt.k : data.ks.k;
+    this.keyframesMetadata = [];
+    this.k = true;
+    this.kf = true;
+    var len = this.keyframes[0].s[0].i.length;
+    this.v = shapePool.newElement();
+    this.v.setPathData(this.keyframes[0].s[0].c, len);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.lastFrame = initFrame;
+    this.reset = resetShape;
+    this._caching = { lastFrame: initFrame, lastIndex: 0 };
+    this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
+  }
+  KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
+  KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
+  KeyframedShapeProperty.prototype.setVValue = setVValue;
+  KeyframedShapeProperty.prototype.addEffect = addEffect;
+
+  var EllShapeProperty = (function () {
+    var cPoint = roundCorner;
+
+    function EllShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 4);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.paths = this.localShapeCollection;
+      this.localShapeCollection.addShape(this.v);
+      this.d = data.d;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertEllToPath();
+      }
+    }
+
+    EllShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+
+        if (this._mdf) {
+          this.convertEllToPath();
+        }
+      },
+      convertEllToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var s0 = this.s.v[0] / 2;
+        var s1 = this.s.v[1] / 2;
+        var _cw = this.d !== 3;
+        var _v = this.v;
+        _v.v[0][0] = p0;
+        _v.v[0][1] = p1 - s1;
+        _v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.v[1][1] = p1;
+        _v.v[2][0] = p0;
+        _v.v[2][1] = p1 + s1;
+        _v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.v[3][1] = p1;
+        _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.i[0][1] = p1 - s1;
+        _v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.i[1][1] = p1 - s1 * cPoint;
+        _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.i[2][1] = p1 + s1;
+        _v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.i[3][1] = p1 + s1 * cPoint;
+        _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.o[0][1] = p1 - s1;
+        _v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.o[1][1] = p1 + s1 * cPoint;
+        _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.o[2][1] = p1 + s1;
+        _v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.o[3][1] = p1 - s1 * cPoint;
+      },
+    };
+
+    extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
+
+    return EllShapePropertyFactory;
+  }());
+
+  var StarShapeProperty = (function () {
+    function StarShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 0);
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.data = data;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      if (data.sy === 1) {
+        this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
+        this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
+        this.convertToPath = this.convertStarToPath;
+      } else {
+        this.convertToPath = this.convertPolygonToPath;
+      }
+      this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
+      this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this);
+      this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertToPath();
+      }
+    }
+
+    StarShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertToPath();
+        }
+      },
+      convertStarToPath: function () {
+        var numPts = Math.floor(this.pt.v) * 2;
+        var angle = (Math.PI * 2) / numPts;
+        /* this.v.v.length = numPts;
+                this.v.i.length = numPts;
+                this.v.o.length = numPts; */
+        var longFlag = true;
+        var longRad = this.or.v;
+        var shortRad = this.ir.v;
+        var longRound = this.os.v;
+        var shortRound = this.is.v;
+        var longPerimSegment = (2 * Math.PI * longRad) / (numPts * 2);
+        var shortPerimSegment = (2 * Math.PI * shortRad) / (numPts * 2);
+        var i;
+        var rad;
+        var roundness;
+        var perimSegment;
+        var currentAng = -Math.PI / 2;
+        currentAng += this.r.v;
+        var dir = this.data.d === 3 ? -1 : 1;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          rad = longFlag ? longRad : shortRad;
+          roundness = longFlag ? longRound : shortRound;
+          perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
+          /* this.v.v[i] = [x,y];
+                    this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
+                    this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
+                    this.v._length = numPts; */
+          longFlag = !longFlag;
+          currentAng += angle * dir;
+        }
+      },
+      convertPolygonToPath: function () {
+        var numPts = Math.floor(this.pt.v);
+        var angle = (Math.PI * 2) / numPts;
+        var rad = this.or.v;
+        var roundness = this.os.v;
+        var perimSegment = (2 * Math.PI * rad) / (numPts * 4);
+        var i;
+        var currentAng = -Math.PI * 0.5;
+        var dir = this.data.d === 3 ? -1 : 1;
+        currentAng += this.r.v;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+          currentAng += angle * dir;
+        }
+        this.paths.length = 0;
+        this.paths[0] = this.v;
+      },
+
+    };
+    extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
+
+    return StarShapePropertyFactory;
+  }());
+
+  var RectShapeProperty = (function () {
+    function RectShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.c = true;
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertRectToPath();
+      }
+    }
+
+    RectShapePropertyFactory.prototype = {
+      convertRectToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var v0 = this.s.v[0] / 2;
+        var v1 = this.s.v[1] / 2;
+        var round = bmMin(v0, v1, this.r.v);
+        var cPoint = round * (1 - roundCorner);
+        this.v._length = 0;
+
+        if (this.d === 2 || this.d === 1) {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
+          this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2);
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3);
+          }
+        } else {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true);
+          }
+        }
+      },
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertRectToPath();
+        }
+      },
+      reset: resetShape,
+    };
+    extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
+
+    return RectShapePropertyFactory;
+  }());
+
+  function getShapeProp(elem, data, type) {
+    var prop;
+    if (type === 3 || type === 4) {
+      var dataProp = type === 3 ? data.pt : data.ks;
+      var keys = dataProp.k;
+      if (keys.length) {
+        prop = new KeyframedShapeProperty(elem, data, type);
+      } else {
+        prop = new ShapeProperty(elem, data, type);
+      }
+    } else if (type === 5) {
+      prop = new RectShapeProperty(elem, data);
+    } else if (type === 6) {
+      prop = new EllShapeProperty(elem, data);
+    } else if (type === 7) {
+      prop = new StarShapeProperty(elem, data);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  }
+
+  function getConstructorFunction() {
+    return ShapeProperty;
+  }
+
+  function getKeyframedConstructorFunction() {
+    return KeyframedShapeProperty;
+  }
+
+  var ob = {};
+  ob.getShapeProp = getShapeProp;
+  ob.getConstructorFunction = getConstructorFunction;
+  ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction;
+  return ob;
+}());
+
+/*!
+ Transformation Matrix v2.0
+ (c) Epistemex 2014-2015
+ www.epistemex.com
+ By Ken Fyrstenberg
+ Contributions by leeoniya.
+ License: MIT, header required.
+ */
+
+/**
+ * 2D transformation matrix object initialized with identity matrix.
+ *
+ * The matrix can synchronize a canvas context by supplying the context
+ * as an argument, or later apply current absolute transform to an
+ * existing context.
+ *
+ * All values are handled as floating point values.
+ *
+ * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix
+ * @prop {number} a - scale x
+ * @prop {number} b - shear y
+ * @prop {number} c - shear x
+ * @prop {number} d - scale y
+ * @prop {number} e - translate x
+ * @prop {number} f - translate y
+ * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context
+ * @constructor
+ */
+
+const Matrix = (function () {
+  var _cos = Math.cos;
+  var _sin = Math.sin;
+  var _tan = Math.tan;
+  var _rnd = Math.round;
+
+  function reset() {
+    this.props[0] = 1;
+    this.props[1] = 0;
+    this.props[2] = 0;
+    this.props[3] = 0;
+    this.props[4] = 0;
+    this.props[5] = 1;
+    this.props[6] = 0;
+    this.props[7] = 0;
+    this.props[8] = 0;
+    this.props[9] = 0;
+    this.props[10] = 1;
+    this.props[11] = 0;
+    this.props[12] = 0;
+    this.props[13] = 0;
+    this.props[14] = 0;
+    this.props[15] = 1;
+    return this;
+  }
+
+  function rotate(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function rotateX(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateY(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateZ(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function shear(sx, sy) {
+    return this._t(1, sy, sx, 1, 0, 0);
+  }
+
+  function skew(ax, ay) {
+    return this.shear(_tan(ax), _tan(ay));
+  }
+
+  function skewFromAxis(ax, angle) {
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+    // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+  }
+
+  function scale(sx, sy, sz) {
+    if (!sz && sz !== 0) {
+      sz = 1;
+    }
+    if (sx === 1 && sy === 1 && sz === 1) {
+      return this;
+    }
+    return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
+  }
+
+  function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
+    this.props[0] = a;
+    this.props[1] = b;
+    this.props[2] = c;
+    this.props[3] = d;
+    this.props[4] = e;
+    this.props[5] = f;
+    this.props[6] = g;
+    this.props[7] = h;
+    this.props[8] = i;
+    this.props[9] = j;
+    this.props[10] = k;
+    this.props[11] = l;
+    this.props[12] = m;
+    this.props[13] = n;
+    this.props[14] = o;
+    this.props[15] = p;
+    return this;
+  }
+
+  function translate(tx, ty, tz) {
+    tz = tz || 0;
+    if (tx !== 0 || ty !== 0 || tz !== 0) {
+      return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
+    }
+    return this;
+  }
+
+  function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
+    var _p = this.props;
+
+    if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
+      // NOTE: commenting this condition because TurboFan deoptimizes code when present
+      // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
+      _p[12] = _p[12] * a2 + _p[15] * m2;
+      _p[13] = _p[13] * f2 + _p[15] * n2;
+      _p[14] = _p[14] * k2 + _p[15] * o2;
+      _p[15] *= p2;
+      // }
+      this._identityCalculated = false;
+      return this;
+    }
+
+    var a1 = _p[0];
+    var b1 = _p[1];
+    var c1 = _p[2];
+    var d1 = _p[3];
+    var e1 = _p[4];
+    var f1 = _p[5];
+    var g1 = _p[6];
+    var h1 = _p[7];
+    var i1 = _p[8];
+    var j1 = _p[9];
+    var k1 = _p[10];
+    var l1 = _p[11];
+    var m1 = _p[12];
+    var n1 = _p[13];
+    var o1 = _p[14];
+    var p1 = _p[15];
+
+    /* matrix order (canvas compatible):
+         * ace
+         * bdf
+         * 001
+         */
+    _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
+    _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
+    _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
+    _p[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2;
+
+    _p[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2;
+    _p[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2;
+    _p[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2;
+    _p[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2;
+
+    _p[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2;
+    _p[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2;
+    _p[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2;
+    _p[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2;
+
+    _p[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2;
+    _p[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2;
+    _p[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2;
+    _p[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2;
+
+    this._identityCalculated = false;
+    return this;
+  }
+
+  function multiply(matrix) {
+    var matrixProps = matrix.props;
+    return this.transform(
+      matrixProps[0],
+      matrixProps[1],
+      matrixProps[2],
+      matrixProps[3],
+      matrixProps[4],
+      matrixProps[5],
+      matrixProps[6],
+      matrixProps[7],
+      matrixProps[8],
+      matrixProps[9],
+      matrixProps[10],
+      matrixProps[11],
+      matrixProps[12],
+      matrixProps[13],
+      matrixProps[14],
+      matrixProps[15]
+    );
+  }
+
+  function isIdentity() {
+    if (!this._identityCalculated) {
+      this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
+      this._identityCalculated = true;
+    }
+    return this._identity;
+  }
+
+  function equals(matr) {
+    var i = 0;
+    while (i < 16) {
+      if (matr.props[i] !== this.props[i]) {
+        return false;
+      }
+      i += 1;
+    }
+    return true;
+  }
+
+  function clone(matr) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      matr.props[i] = this.props[i];
+    }
+    return matr;
+  }
+
+  function cloneFromProps(props) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      this.props[i] = props[i];
+    }
+  }
+
+  function applyToPoint(x, y, z) {
+    return {
+      x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+      y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+      z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+    };
+    /* return {
+         x: x * me.a + y * me.c + me.e,
+         y: x * me.b + y * me.d + me.f
+         }; */
+  }
+  function applyToX(x, y, z) {
+    return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
+  }
+  function applyToY(x, y, z) {
+    return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
+  }
+  function applyToZ(x, y, z) {
+    return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
+  }
+
+  function getInverseMatrix() {
+    var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
+    var a = this.props[5] / determinant;
+    var b = -this.props[1] / determinant;
+    var c = -this.props[4] / determinant;
+    var d = this.props[0] / determinant;
+    var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12]) / determinant;
+    var f = -(this.props[0] * this.props[13] - this.props[1] * this.props[12]) / determinant;
+    var inverseMatrix = new Matrix();
+    inverseMatrix.props[0] = a;
+    inverseMatrix.props[1] = b;
+    inverseMatrix.props[4] = c;
+    inverseMatrix.props[5] = d;
+    inverseMatrix.props[12] = e;
+    inverseMatrix.props[13] = f;
+    return inverseMatrix;
+  }
+
+  function inversePoint(pt) {
+    var inverseMatrix = this.getInverseMatrix();
+    return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
+  }
+
+  function inversePoints(pts) {
+    var i;
+    var len = pts.length;
+    var retPts = [];
+    for (i = 0; i < len; i += 1) {
+      retPts[i] = inversePoint(pts[i]);
+    }
+    return retPts;
+  }
+
+  function applyToTriplePoints(pt1, pt2, pt3) {
+    var arr = createTypedArray('float32', 6);
+    if (this.isIdentity()) {
+      arr[0] = pt1[0];
+      arr[1] = pt1[1];
+      arr[2] = pt2[0];
+      arr[3] = pt2[1];
+      arr[4] = pt3[0];
+      arr[5] = pt3[1];
+    } else {
+      var p0 = this.props[0];
+      var p1 = this.props[1];
+      var p4 = this.props[4];
+      var p5 = this.props[5];
+      var p12 = this.props[12];
+      var p13 = this.props[13];
+      arr[0] = pt1[0] * p0 + pt1[1] * p4 + p12;
+      arr[1] = pt1[0] * p1 + pt1[1] * p5 + p13;
+      arr[2] = pt2[0] * p0 + pt2[1] * p4 + p12;
+      arr[3] = pt2[0] * p1 + pt2[1] * p5 + p13;
+      arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
+      arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
+    }
+    return arr;
+  }
+
+  function applyToPointArray(x, y, z) {
+    var arr;
+    if (this.isIdentity()) {
+      arr = [x, y, z];
+    } else {
+      arr = [
+        x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+        x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+        x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+      ];
+    }
+    return arr;
+  }
+
+  function applyToPointStringified(x, y) {
+    if (this.isIdentity()) {
+      return x + ',' + y;
+    }
+    var _p = this.props;
+    return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
+  }
+
+  function toCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var i = 0;
+    var props = this.props;
+    var cssValue = 'matrix3d(';
+    var v = 10000;
+    while (i < 16) {
+      cssValue += _rnd(props[i] * v) / v;
+      cssValue += i === 15 ? ')' : ',';
+      i += 1;
+    }
+    return cssValue;
+  }
+
+  function roundMatrixProperty(val) {
+    var v = 10000;
+    if ((val < 0.000001 && val > 0) || (val > -0.000001 && val < 0)) {
+      return _rnd(val * v) / v;
+    }
+    return val;
+  }
+
+  function to2dCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var props = this.props;
+    var _a = roundMatrixProperty(props[0]);
+    var _b = roundMatrixProperty(props[1]);
+    var _c = roundMatrixProperty(props[4]);
+    var _d = roundMatrixProperty(props[5]);
+    var _e = roundMatrixProperty(props[12]);
+    var _f = roundMatrixProperty(props[13]);
+    return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
+  }
+
+  return function () {
+    this.reset = reset;
+    this.rotate = rotate;
+    this.rotateX = rotateX;
+    this.rotateY = rotateY;
+    this.rotateZ = rotateZ;
+    this.skew = skew;
+    this.skewFromAxis = skewFromAxis;
+    this.shear = shear;
+    this.scale = scale;
+    this.setTransform = setTransform;
+    this.translate = translate;
+    this.transform = transform;
+    this.multiply = multiply;
+    this.applyToPoint = applyToPoint;
+    this.applyToX = applyToX;
+    this.applyToY = applyToY;
+    this.applyToZ = applyToZ;
+    this.applyToPointArray = applyToPointArray;
+    this.applyToTriplePoints = applyToTriplePoints;
+    this.applyToPointStringified = applyToPointStringified;
+    this.toCSS = toCSS;
+    this.to2dCSS = to2dCSS;
+    this.clone = clone;
+    this.cloneFromProps = cloneFromProps;
+    this.equals = equals;
+    this.inversePoints = inversePoints;
+    this.inversePoint = inversePoint;
+    this.getInverseMatrix = getInverseMatrix;
+    this._t = this.transform;
+    this.isIdentity = isIdentity;
+    this._identity = true;
+    this._identityCalculated = false;
+
+    this.props = createTypedArray('float32', 16);
+    this.reset();
+  };
+}());
+
+const lottie = {};
+var standalone = '__[STANDALONE]__';
+var animationData = '__[ANIMATIONDATA]__';
+var renderer = '';
+
+function setLocation(href) {
+  setLocationHref(href);
+}
+
+function searchAnimations() {
+  if (standalone === true) {
+    animationManager.searchAnimations(animationData, standalone, renderer);
+  } else {
+    animationManager.searchAnimations();
+  }
+}
+
+function setSubframeRendering(flag) {
+  setSubframeEnabled(flag);
+}
+
+function setPrefix(prefix) {
+  setIdPrefix(prefix);
+}
+
+function loadAnimation(params) {
+  if (standalone === true) {
+    params.animationData = JSON.parse(animationData);
+  }
+  return animationManager.loadAnimation(params);
+}
+
+function setQuality(value) {
+  if (typeof value === 'string') {
+    switch (value) {
+      case 'high':
+        setDefaultCurveSegments(200);
+        break;
+      default:
+      case 'medium':
+        setDefaultCurveSegments(50);
+        break;
+      case 'low':
+        setDefaultCurveSegments(10);
+        break;
+    }
+  } else if (!isNaN(value) && value > 1) {
+    setDefaultCurveSegments(value);
+  }
+  if (getDefaultCurveSegments() >= 50) {
+    roundValues(false);
+  } else {
+    roundValues(true);
+  }
+}
+
+function inBrowser() {
+  return typeof navigator !== 'undefined';
+}
+
+function installPlugin(type, plugin) {
+  if (type === 'expressions') {
+    setExpressionsPlugin(plugin);
+  }
+}
+
+function getFactory(name) {
+  switch (name) {
+    case 'propertyFactory':
+      return PropertyFactory;
+    case 'shapePropertyFactory':
+      return ShapePropertyFactory;
+    case 'matrix':
+      return Matrix;
+    default:
+      return null;
+  }
+}
+
+lottie.play = animationManager.play;
+lottie.pause = animationManager.pause;
+lottie.setLocationHref = setLocation;
+lottie.togglePause = animationManager.togglePause;
+lottie.setSpeed = animationManager.setSpeed;
+lottie.setDirection = animationManager.setDirection;
+lottie.stop = animationManager.stop;
+lottie.searchAnimations = searchAnimations;
+lottie.registerAnimation = animationManager.registerAnimation;
+lottie.loadAnimation = loadAnimation;
+lottie.setSubframeRendering = setSubframeRendering;
+lottie.resize = animationManager.resize;
+// lottie.start = start;
+lottie.goToAndStop = animationManager.goToAndStop;
+lottie.destroy = animationManager.destroy;
+lottie.setQuality = setQuality;
+lottie.inBrowser = inBrowser;
+lottie.installPlugin = installPlugin;
+lottie.freeze = animationManager.freeze;
+lottie.unfreeze = animationManager.unfreeze;
+lottie.setVolume = animationManager.setVolume;
+lottie.mute = animationManager.mute;
+lottie.unmute = animationManager.unmute;
+lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations;
+lottie.useWebWorker = setWebWorker;
+lottie.setIDPrefix = setPrefix;
+lottie.__getFactory = getFactory;
+lottie.version = '[[BM_VERSION]]';
+
+function checkReady() {
+  if (document.readyState === 'complete') {
+    clearInterval(readyStateCheckInterval);
+    searchAnimations();
+  }
+}
+
+function getQueryVariable(variable) {
+  var vars = queryString.split('&');
+  for (var i = 0; i < vars.length; i += 1) {
+    var pair = vars[i].split('=');
+    if (decodeURIComponent(pair[0]) == variable) { // eslint-disable-line eqeqeq
+      return decodeURIComponent(pair[1]);
+    }
+  }
+  return null;
+}
+var queryString = '';
+if (standalone) {
+  var scripts = document.getElementsByTagName('script');
+  var index = scripts.length - 1;
+  var myScript = scripts[index] || {
+    src: '',
+  };
+  queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
+  renderer = getQueryVariable('renderer');
+}
+var readyStateCheckInterval = setInterval(checkReady, 100);
+
+// this adds bodymovin to the window object for backwards compatibility
+try {
+  if (!(typeof exports === 'object' && typeof module !== 'undefined')
+    && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
+  ) {
+    window.bodymovin = lottie;
+  }
+} catch (err) {
+  //
+}
+
+const ShapeModifiers = (function () {
+  var ob = {};
+  var modifiers = {};
+  ob.registerModifier = registerModifier;
+  ob.getModifier = getModifier;
+
+  function registerModifier(nm, factory) {
+    if (!modifiers[nm]) {
+      modifiers[nm] = factory;
+    }
+  }
+
+  function getModifier(nm, elem, data) {
+    return new modifiers[nm](elem, data);
+  }
+
+  return ob;
+}());
+
+function ShapeModifier() {}
+ShapeModifier.prototype.initModifierProperties = function () {};
+ShapeModifier.prototype.addShapeToModifier = function () {};
+ShapeModifier.prototype.addShape = function (data) {
+  if (!this.closed) {
+    // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
+    data.sh.container.addDynamicProperty(data.sh);
+    var shapeData = { shape: data.sh, data: data, localShapeCollection: shapeCollectionPool.newShapeCollection() };
+    this.shapes.push(shapeData);
+    this.addShapeToModifier(shapeData);
+    if (this._isAnimated) {
+      data.setAsAnimated();
+    }
+  }
+};
+ShapeModifier.prototype.init = function (elem, data) {
+  this.shapes = [];
+  this.elem = elem;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, data);
+  this.frameId = initialDefaultFrame;
+  this.closed = false;
+  this.k = false;
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+ShapeModifier.prototype.processKeys = function () {
+  if (this.elem.globalData.frameId === this.frameId) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+extendPrototype([DynamicPropertyContainer], ShapeModifier);
+
+function TrimModifier() {
+}
+extendPrototype([ShapeModifier], TrimModifier);
+TrimModifier.prototype.initModifierProperties = function (elem, data) {
+  this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this);
+  this.sValue = 0;
+  this.eValue = 0;
+  this.getValue = this.processKeys;
+  this.m = data.m;
+  this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
+};
+
+TrimModifier.prototype.addShapeToModifier = function (shapeData) {
+  shapeData.pathsData = [];
+};
+
+TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
+  var segments = [];
+  if (e <= 1) {
+    segments.push({
+      s: s,
+      e: e,
+    });
+  } else if (s >= 1) {
+    segments.push({
+      s: s - 1,
+      e: e - 1,
+    });
+  } else {
+    segments.push({
+      s: s,
+      e: 1,
+    });
+    segments.push({
+      s: 0,
+      e: e - 1,
+    });
+  }
+  var shapeSegments = [];
+  var i;
+  var len = segments.length;
+  var segmentOb;
+  for (i = 0; i < len; i += 1) {
+    segmentOb = segments[i];
+    if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
+      var shapeS;
+      var shapeE;
+      if (segmentOb.s * totalModifierLength <= addedLength) {
+        shapeS = 0;
+      } else {
+        shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
+      }
+      if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
+        shapeE = 1;
+      } else {
+        shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength);
+      }
+      shapeSegments.push([shapeS, shapeE]);
+    }
+  }
+  if (!shapeSegments.length) {
+    shapeSegments.push([0, 0]);
+  }
+  return shapeSegments;
+};
+
+TrimModifier.prototype.releasePathsData = function (pathsData) {
+  var i;
+  var len = pathsData.length;
+  for (i = 0; i < len; i += 1) {
+    segmentsLengthPool.release(pathsData[i]);
+  }
+  pathsData.length = 0;
+  return pathsData;
+};
+
+TrimModifier.prototype.processShapes = function (_isFirstFrame) {
+  var s;
+  var e;
+  if (this._mdf || _isFirstFrame) {
+    var o = (this.o.v % 360) / 360;
+    if (o < 0) {
+      o += 1;
+    }
+    if (this.s.v > 1) {
+      s = 1 + o;
+    } else if (this.s.v < 0) {
+      s = 0 + o;
+    } else {
+      s = this.s.v + o;
+    }
+    if (this.e.v > 1) {
+      e = 1 + o;
+    } else if (this.e.v < 0) {
+      e = 0 + o;
+    } else {
+      e = this.e.v + o;
+    }
+
+    if (s > e) {
+      var _s = s;
+      s = e;
+      e = _s;
+    }
+    s = Math.round(s * 10000) * 0.0001;
+    e = Math.round(e * 10000) * 0.0001;
+    this.sValue = s;
+    this.eValue = e;
+  } else {
+    s = this.sValue;
+    e = this.eValue;
+  }
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var pathsData;
+  var pathData;
+  var totalShapeLength;
+  var totalModifierLength = 0;
+
+  if (e === s) {
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].localShapeCollection.releaseShapes();
+      this.shapes[i].shape._mdf = true;
+      this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
+      if (this._mdf) {
+        this.shapes[i].pathsData.length = 0;
+      }
+    }
+  } else if (!((e === 1 && s === 0) || (e === 0 && s === 1))) {
+    var segments = [];
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
+      if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
+        shapeData.shape.paths = shapeData.localShapeCollection;
+      } else {
+        shapePaths = shapeData.shape.paths;
+        jLen = shapePaths._length;
+        totalShapeLength = 0;
+        if (!shapeData.shape._mdf && shapeData.pathsData.length) {
+          totalShapeLength = shapeData.totalShapeLength;
+        } else {
+          pathsData = this.releasePathsData(shapeData.pathsData);
+          for (j = 0; j < jLen; j += 1) {
+            pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
+            pathsData.push(pathData);
+            totalShapeLength += pathData.totalLength;
+          }
+          shapeData.totalShapeLength = totalShapeLength;
+          shapeData.pathsData = pathsData;
+        }
+
+        totalModifierLength += totalShapeLength;
+        shapeData.shape._mdf = true;
+      }
+    }
+    var shapeS = s;
+    var shapeE = e;
+    var addedLength = 0;
+    var edges;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shapeData = this.shapes[i];
+      if (shapeData.shape._mdf) {
+        localShapeCollection = shapeData.localShapeCollection;
+        localShapeCollection.releaseShapes();
+        // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
+        if (this.m === 2 && len > 1) {
+          edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
+          addedLength += shapeData.totalShapeLength;
+        } else {
+          edges = [[shapeS, shapeE]];
+        }
+        jLen = edges.length;
+        for (j = 0; j < jLen; j += 1) {
+          shapeS = edges[j][0];
+          shapeE = edges[j][1];
+          segments.length = 0;
+          if (shapeE <= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength * shapeE,
+            });
+          } else if (shapeS >= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * (shapeS - 1),
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          } else {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength,
+            });
+            segments.push({
+              s: 0,
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          }
+          var newShapesData = this.addShapes(shapeData, segments[0]);
+          if (segments[0].s !== segments[0].e) {
+            if (segments.length > 1) {
+              var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
+              if (lastShapeInCollection.c) {
+                var lastShape = newShapesData.pop();
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1], lastShape);
+              } else {
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1]);
+              }
+            }
+            this.addPaths(newShapesData, localShapeCollection);
+          }
+        }
+        shapeData.shape.paths = localShapeCollection;
+      }
+    }
+  } else if (this._mdf) {
+    for (i = 0; i < len; i += 1) {
+      // Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween.
+      // Don't remove this even if it's losing cached info.
+      this.shapes[i].pathsData.length = 0;
+      this.shapes[i].shape._mdf = true;
+    }
+  }
+};
+
+TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
+  var i;
+  var len = newPaths.length;
+  for (i = 0; i < len; i += 1) {
+    localShapeCollection.addShape(newPaths[i]);
+  }
+};
+
+TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
+  shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
+  shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
+  }
+  shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
+  shapePath.setXYAt(points[1], points[5], 'o', pos);
+  shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(points[0], points[4], 'v', pos);
+  }
+  shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
+  var pathsData = shapeData.pathsData;
+  var shapePaths = shapeData.shape.paths.shapes;
+  var i;
+  var len = shapeData.shape.paths._length;
+  var j;
+  var jLen;
+  var addedLength = 0;
+  var currentLengthData;
+  var segmentCount;
+  var lengths;
+  var segment;
+  var shapes = [];
+  var initPos;
+  var newShape = true;
+  if (!shapePath) {
+    shapePath = shapePool.newElement();
+    segmentCount = 0;
+    initPos = 0;
+  } else {
+    segmentCount = shapePath._length;
+    initPos = shapePath._length;
+  }
+  shapes.push(shapePath);
+  for (i = 0; i < len; i += 1) {
+    lengths = pathsData[i].lengths;
+    shapePath.c = shapePaths[i].c;
+    jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
+    for (j = 1; j < jLen; j += 1) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
+        addedLength += currentLengthData.addedLength;
+        shapePath.c = false;
+      } else if (addedLength > shapeSegment.e) {
+        shapePath.c = false;
+        break;
+      } else {
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+        addedLength += currentLengthData.addedLength;
+        segmentCount += 1;
+      }
+    }
+    if (shapePaths[i].c && lengths.length) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength <= shapeSegment.e) {
+        var segmentLength = lengths[j - 1].addedLength;
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+      } else {
+        shapePath.c = false;
+      }
+      addedLength += currentLengthData.addedLength;
+      segmentCount += 1;
+    }
+    if (shapePath._length) {
+      shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
+      shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
+    }
+    if (addedLength > shapeSegment.e) {
+      break;
+    }
+    if (i < len - 1) {
+      shapePath = shapePool.newElement();
+      newShape = true;
+      shapes.push(shapePath);
+      segmentCount = 0;
+    }
+  }
+  return shapes;
+};
+
+function PuckerAndBloatModifier() {}
+extendPrototype([ShapeModifier], PuckerAndBloatModifier);
+PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this._isAnimated = !!this.amount.effectsSequence.length;
+};
+
+PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
+  var percent = amount / 100;
+  var centerPoint = [0, 0];
+  var pathLength = path._length;
+  var i = 0;
+  for (i = 0; i < pathLength; i += 1) {
+    centerPoint[0] += path.v[i][0];
+    centerPoint[1] += path.v[i][1];
+  }
+  centerPoint[0] /= pathLength;
+  centerPoint[1] /= pathLength;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < pathLength; i += 1) {
+    vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
+    vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
+    oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent;
+    oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent;
+    iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent;
+    iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
+    clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
+  }
+  return clonedPath;
+};
+
+PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+const TransformPropertyFactory = (function () {
+  var defaultVector = [0, 0];
+
+  function applyToMatrix(mat) {
+    var _mdf = this._mdf;
+    this.iterateDynamicProperties();
+    this._mdf = this._mdf || _mdf;
+    if (this.a) {
+      mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+    }
+    if (this.s) {
+      mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+    }
+    if (this.sk) {
+      mat.skewFromAxis(-this.sk.v, this.sa.v);
+    }
+    if (this.r) {
+      mat.rotate(-this.r.v);
+    } else {
+      mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+    }
+    if (this.data.p.s) {
+      if (this.data.p.z) {
+        mat.translate(this.px.v, this.py.v, -this.pz.v);
+      } else {
+        mat.translate(this.px.v, this.py.v, 0);
+      }
+    } else {
+      mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+    }
+  }
+  function processKeys(forceRender) {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    }
+    if (this._isDirty) {
+      this.precalculateMatrix();
+      this._isDirty = false;
+    }
+
+    this.iterateDynamicProperties();
+
+    if (this._mdf || forceRender) {
+      var frameRate;
+      this.v.cloneFromProps(this.pre.props);
+      if (this.appliedTransformations < 1) {
+        this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      }
+      if (this.appliedTransformations < 2) {
+        this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      }
+      if (this.sk && this.appliedTransformations < 3) {
+        this.v.skewFromAxis(-this.sk.v, this.sa.v);
+      }
+      if (this.r && this.appliedTransformations < 4) {
+        this.v.rotate(-this.r.v);
+      } else if (!this.r && this.appliedTransformations < 4) {
+        this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+          .rotateY(this.or.v[1])
+          .rotateX(this.or.v[0]);
+      }
+      if (this.autoOriented) {
+        var v1;
+        var v2;
+        frameRate = this.elem.globalData.frameRate;
+        if (this.p && this.p.keyframes && this.p.getValueAtTime) {
+          if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
+            v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0);
+          } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0);
+            v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0);
+          } else {
+            v1 = this.p.pv;
+            v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime);
+          }
+        } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) {
+          v1 = [];
+          v2 = [];
+          var px = this.px;
+          var py = this.py;
+          if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
+            v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
+            v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate, 0);
+          } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate), 0);
+            v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate), 0);
+            v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0);
+          } else {
+            v1 = [px.pv, py.pv];
+            v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime);
+            v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime);
+          }
+        } else {
+          v2 = defaultVector;
+          v1 = v2;
+        }
+        this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
+      }
+      if (this.data.p && this.data.p.s) {
+        if (this.data.p.z) {
+          this.v.translate(this.px.v, this.py.v, -this.pz.v);
+        } else {
+          this.v.translate(this.px.v, this.py.v, 0);
+        }
+      } else {
+        this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+      }
+    }
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function precalculateMatrix() {
+    this.appliedTransformations = 0;
+    this.pre.reset();
+
+    if (!this.a.effectsSequence.length) {
+      this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      this.appliedTransformations = 1;
+    } else {
+      return;
+    }
+    if (!this.s.effectsSequence.length) {
+      this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      this.appliedTransformations = 2;
+    } else {
+      return;
+    }
+    if (this.sk) {
+      if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
+        this.pre.skewFromAxis(-this.sk.v, this.sa.v);
+        this.appliedTransformations = 3;
+      } else {
+        return;
+      }
+    }
+    if (this.r) {
+      if (!this.r.effectsSequence.length) {
+        this.pre.rotate(-this.r.v);
+        this.appliedTransformations = 4;
+      }
+    } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) {
+      this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+      this.appliedTransformations = 4;
+    }
+  }
+
+  function autoOrient() {
+    //
+    // var prevP = this.getValueAtTime();
+  }
+
+  function addDynamicProperty(prop) {
+    this._addDynamicProperty(prop);
+    this.elem.addDynamicProperty(prop);
+    this._isDirty = true;
+  }
+
+  function TransformProperty(elem, data, container) {
+    this.elem = elem;
+    this.frameId = -1;
+    this.propType = 'transform';
+    this.data = data;
+    this.v = new Matrix();
+    // Precalculated matrix with non animated properties
+    this.pre = new Matrix();
+    this.appliedTransformations = 0;
+    this.initDynamicPropertyContainer(container || elem);
+    if (data.p && data.p.s) {
+      this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
+      this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
+      if (data.p.z) {
+        this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
+      }
+    } else {
+      this.p = PropertyFactory.getProp(elem, data.p || { k: [0, 0, 0] }, 1, 0, this);
+    }
+    if (data.rx) {
+      this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
+      this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
+      this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
+      if (data.or.k[0].ti) {
+        var i;
+        var len = data.or.k.length;
+        for (i = 0; i < len; i += 1) {
+          data.or.k[i].to = null;
+          data.or.k[i].ti = null;
+        }
+      }
+      this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+      // sh Indicates it needs to be capped between -180 and 180
+      this.or.sh = true;
+    } else {
+      this.r = PropertyFactory.getProp(elem, data.r || { k: 0 }, 0, degToRads, this);
+    }
+    if (data.sk) {
+      this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
+      this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
+    }
+    this.a = PropertyFactory.getProp(elem, data.a || { k: [0, 0, 0] }, 1, 0, this);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: [100, 100, 100] }, 1, 0.01, this);
+    // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
+    if (data.o) {
+      this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
+    } else {
+      this.o = { _mdf: false, v: 1 };
+    }
+    this._isDirty = true;
+    if (!this.dynamicProperties.length) {
+      this.getValue(true);
+    }
+  }
+
+  TransformProperty.prototype = {
+    applyToMatrix: applyToMatrix,
+    getValue: processKeys,
+    precalculateMatrix: precalculateMatrix,
+    autoOrient: autoOrient,
+  };
+
+  extendPrototype([DynamicPropertyContainer], TransformProperty);
+  TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
+  TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
+
+  function getTransformProperty(elem, data, container) {
+    return new TransformProperty(elem, data, container);
+  }
+
+  return {
+    getTransformProperty: getTransformProperty,
+  };
+}());
+
+function RepeaterModifier() {}
+extendPrototype([ShapeModifier], RepeaterModifier);
+
+RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, null, this);
+  this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this);
+  this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
+  this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
+  this.data = data;
+  if (!this.dynamicProperties.length) {
+    this.getValue(true);
+  }
+  this._isAnimated = !!this.dynamicProperties.length;
+  this.pMatrix = new Matrix();
+  this.rMatrix = new Matrix();
+  this.sMatrix = new Matrix();
+  this.tMatrix = new Matrix();
+  this.matrix = new Matrix();
+};
+
+RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
+  var dir = inv ? -1 : 1;
+  var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
+  var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
+  pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
+  rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  rMatrix.rotate(-transform.r.v * dir * perc);
+  rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+  sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
+  sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+};
+
+RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
+  this.elem = elem;
+  this.arr = arr;
+  this.pos = pos;
+  this.elemsData = elemsData;
+  this._currentCopies = 0;
+  this._elements = [];
+  this._groups = [];
+  this.frameId = -1;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, arr[pos]);
+  while (pos > 0) {
+    pos -= 1;
+    // this._elements.unshift(arr.splice(pos,1)[0]);
+    this._elements.unshift(arr[pos]);
+  }
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+
+RepeaterModifier.prototype.resetElements = function (elements) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._processed = false;
+    if (elements[i].ty === 'gr') {
+      this.resetElements(elements[i].it);
+    }
+  }
+};
+
+RepeaterModifier.prototype.cloneElements = function (elements) {
+  var newElements = JSON.parse(JSON.stringify(elements));
+  this.resetElements(newElements);
+  return newElements;
+};
+
+RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._render = renderFlag;
+    if (elements[i].ty === 'gr') {
+      this.changeGroupRender(elements[i].it, renderFlag);
+    }
+  }
+};
+
+RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
+  var items;
+  var itemsTransform;
+  var i;
+  var dir;
+  var cont;
+  var hasReloaded = false;
+  if (this._mdf || _isFirstFrame) {
+    var copies = Math.ceil(this.c.v);
+    if (this._groups.length < copies) {
+      while (this._groups.length < copies) {
+        var group = {
+          it: this.cloneElements(this._elements),
+          ty: 'gr',
+        };
+        group.it.push({
+          a: { a: 0, ix: 1, k: [0, 0] }, nm: 'Transform', o: { a: 0, ix: 7, k: 100 }, p: { a: 0, ix: 2, k: [0, 0] }, r: { a: 1, ix: 6, k: [{ s: 0, e: 0, t: 0 }, { s: 0, e: 0, t: 1 }] }, s: { a: 0, ix: 3, k: [100, 100] }, sa: { a: 0, ix: 5, k: 0 }, sk: { a: 0, ix: 4, k: 0 }, ty: 'tr',
+        });
+
+        this.arr.splice(0, 0, group);
+        this._groups.splice(0, 0, group);
+        this._currentCopies += 1;
+      }
+      this.elem.reloadShapes();
+      hasReloaded = true;
+    }
+    cont = 0;
+    var renderFlag;
+    for (i = 0; i <= this._groups.length - 1; i += 1) {
+      renderFlag = cont < copies;
+      this._groups[i]._render = renderFlag;
+      this.changeGroupRender(this._groups[i].it, renderFlag);
+      if (!renderFlag) {
+        var elems = this.elemsData[i].it;
+        var transformData = elems[elems.length - 1];
+        if (transformData.transform.op.v !== 0) {
+          transformData.transform.op._mdf = true;
+          transformData.transform.op.v = 0;
+        } else {
+          transformData.transform.op._mdf = false;
+        }
+      }
+      cont += 1;
+    }
+
+    this._currentCopies = copies;
+    /// /
+
+    var offset = this.o.v;
+    var offsetModulo = offset % 1;
+    var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
+    var pProps = this.pMatrix.props;
+    var rProps = this.rMatrix.props;
+    var sProps = this.sMatrix.props;
+    this.pMatrix.reset();
+    this.rMatrix.reset();
+    this.sMatrix.reset();
+    this.tMatrix.reset();
+    this.matrix.reset();
+    var iteration = 0;
+
+    if (offset > 0) {
+      while (iteration < roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        iteration += 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
+        iteration += offsetModulo;
+      }
+    } else if (offset < 0) {
+      while (iteration > roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
+        iteration -= 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
+        iteration -= offsetModulo;
+      }
+    }
+    i = this.data.m === 1 ? 0 : this._currentCopies - 1;
+    dir = this.data.m === 1 ? 1 : -1;
+    cont = this._currentCopies;
+    var j;
+    var jLen;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      jLen = itemsTransform.length;
+      items[items.length - 1].transform.mProps._mdf = true;
+      items[items.length - 1].transform.op._mdf = true;
+      items[items.length - 1].transform.op.v = this._currentCopies === 1
+        ? this.so.v
+        : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
+
+      if (iteration !== 0) {
+        if ((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)) {
+          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        }
+        this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
+        this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
+        this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
+
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+        this.matrix.reset();
+      } else {
+        this.matrix.reset();
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+      }
+      iteration += 1;
+      cont -= 1;
+      i += dir;
+    }
+  } else {
+    cont = this._currentCopies;
+    i = 0;
+    dir = 1;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      items[items.length - 1].transform.mProps._mdf = false;
+      items[items.length - 1].transform.op._mdf = false;
+      cont -= 1;
+      i += dir;
+    }
+  }
+  return hasReloaded;
+};
+
+RepeaterModifier.prototype.addShape = function () {};
+
+function RoundCornersModifier() {}
+extendPrototype([ShapeModifier], RoundCornersModifier);
+RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this._isAnimated = !!this.rd.effectsSequence.length;
+};
+
+RoundCornersModifier.prototype.processPath = function (path, round) {
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var i;
+  var len = path._length;
+  var currentV;
+  var currentI;
+  var currentO;
+  var closerV;
+  var distance;
+  var newPosPerc;
+  var index = 0;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < len; i += 1) {
+    currentV = path.v[i];
+    currentO = path.o[i];
+    currentI = path.i[i];
+    if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
+      if ((i === 0 || i === len - 1) && !path.c) {
+        clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
+        /* clonedPath.v[index] = currentV;
+                clonedPath.o[index] = currentO;
+                clonedPath.i[index] = currentI; */
+        index += 1;
+      } else {
+        if (i === 0) {
+          closerV = path.v[len - 1];
+        } else {
+          closerV = path.v[i - 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = iX;
+        iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
+        vY = iY;
+        oX = vX - (vX - currentV[0]) * roundCorner;
+        oY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+
+        if (i === len - 1) {
+          closerV = path.v[0];
+        } else {
+          closerV = path.v[i + 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = oX;
+        oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc;
+        vY = oY;
+        iX = vX - (vX - currentV[0]) * roundCorner;
+        iY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+      }
+    } else {
+      clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index);
+      index += 1;
+    }
+  }
+  return clonedPath;
+};
+
+RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var rd = this.rd.v;
+
+  if (rd !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function floatEqual(a, b) {
+  return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
+}
+
+function floatZero(f) {
+  return Math.abs(f) <= 0.00001;
+}
+
+function lerp(p0, p1, amount) {
+  return p0 * (1 - amount) + p1 * amount;
+}
+
+function lerpPoint(p0, p1, amount) {
+  return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
+}
+
+function quadRoots(a, b, c) {
+  // no root
+  if (a === 0) return [];
+  var s = b * b - 4 * a * c;
+  // Complex roots
+  if (s < 0) return [];
+  var singleRoot = -b / (2 * a);
+  // 1 root
+  if (s === 0) return [singleRoot];
+  var delta = Math.sqrt(s) / (2 * a);
+  // 2 roots
+  return [singleRoot - delta, singleRoot + delta];
+}
+
+function polynomialCoefficients(p0, p1, p2, p3) {
+  return [
+    -p0 + 3 * p1 - 3 * p2 + p3,
+    3 * p0 - 6 * p1 + 3 * p2,
+    -3 * p0 + 3 * p1,
+    p0,
+  ];
+}
+
+function singlePoint(p) {
+  return new PolynomialBezier(p, p, p, p, false);
+}
+
+function PolynomialBezier(p0, p1, p2, p3, linearize) {
+  if (linearize && pointEqual(p0, p1)) {
+    p1 = lerpPoint(p0, p3, 1 / 3);
+  }
+  if (linearize && pointEqual(p2, p3)) {
+    p2 = lerpPoint(p0, p3, 2 / 3);
+  }
+  var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
+  var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
+  this.a = [coeffx[0], coeffy[0]];
+  this.b = [coeffx[1], coeffy[1]];
+  this.c = [coeffx[2], coeffy[2]];
+  this.d = [coeffx[3], coeffy[3]];
+  this.points = [p0, p1, p2, p3];
+}
+PolynomialBezier.prototype.point = function (t) {
+  return [
+    (((this.a[0] * t) + this.b[0]) * t + this.c[0]) * t + this.d[0],
+    (((this.a[1] * t) + this.b[1]) * t + this.c[1]) * t + this.d[1],
+  ];
+};
+PolynomialBezier.prototype.derivative = function (t) {
+  return [
+    (3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0],
+    (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1],
+  ];
+};
+PolynomialBezier.prototype.tangentAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[1], p[0]);
+};
+PolynomialBezier.prototype.normalAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[0], p[1]);
+};
+
+PolynomialBezier.prototype.inflectionPoints = function () {
+  var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
+  if (floatZero(denom)) return [];
+  var tcusp = (-0.5 * (this.a[1] * this.c[0] - this.a[0] * this.c[1])) / denom;
+  var square = tcusp * tcusp - ((1 / 3) * (this.b[1] * this.c[0] - this.b[0] * this.c[1])) / denom;
+  if (square < 0) return [];
+  var root = Math.sqrt(square);
+  if (floatZero(root)) {
+    if (root > 0 && root < 1) return [tcusp];
+    return [];
+  }
+  return [tcusp - root, tcusp + root].filter(function (r) { return r > 0 && r < 1; });
+};
+PolynomialBezier.prototype.split = function (t) {
+  if (t <= 0) return [singlePoint(this.points[0]), this];
+  if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
+  var p10 = lerpPoint(this.points[0], this.points[1], t);
+  var p11 = lerpPoint(this.points[1], this.points[2], t);
+  var p12 = lerpPoint(this.points[2], this.points[3], t);
+  var p20 = lerpPoint(p10, p11, t);
+  var p21 = lerpPoint(p11, p12, t);
+  var p3 = lerpPoint(p20, p21, t);
+  return [
+    new PolynomialBezier(this.points[0], p10, p20, p3, true),
+    new PolynomialBezier(p3, p21, p12, this.points[3], true),
+  ];
+};
+function extrema(bez, comp) {
+  var min = bez.points[0][comp];
+  var max = bez.points[bez.points.length - 1][comp];
+  if (min > max) {
+    var e = max;
+    max = min;
+    min = e;
+  }
+  // Derivative roots to find min/max
+  var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
+  for (var i = 0; i < f.length; i += 1) {
+    if (f[i] > 0 && f[i] < 1) {
+      var val = bez.point(f[i])[comp];
+      if (val < min) min = val;
+      else if (val > max) max = val;
+    }
+  }
+  return {
+    min: min,
+    max: max,
+  };
+}
+PolynomialBezier.prototype.bounds = function () {
+  return {
+    x: extrema(this, 0),
+    y: extrema(this, 1),
+  };
+};
+PolynomialBezier.prototype.boundingBox = function () {
+  var bounds = this.bounds();
+  return {
+    left: bounds.x.min,
+    right: bounds.x.max,
+    top: bounds.y.min,
+    bottom: bounds.y.max,
+    width: bounds.x.max - bounds.x.min,
+    height: bounds.y.max - bounds.y.min,
+    cx: (bounds.x.max + bounds.x.min) / 2,
+    cy: (bounds.y.max + bounds.y.min) / 2,
+  };
+};
+
+function intersectData(bez, t1, t2) {
+  var box = bez.boundingBox();
+  return {
+    cx: box.cx,
+    cy: box.cy,
+    width: box.width,
+    height: box.height,
+    bez: bez,
+    t: (t1 + t2) / 2,
+    t1: t1,
+    t2: t2,
+  };
+}
+function splitData(data) {
+  var split = data.bez.split(0.5);
+  return [
+    intersectData(split[0], data.t1, data.t),
+    intersectData(split[1], data.t, data.t2),
+  ];
+}
+
+function boxIntersect(b1, b2) {
+  return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width
+    && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
+}
+
+function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
+  if (!boxIntersect(d1, d2)) return;
+  if (depth >= maxRecursion || (d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance)) {
+    intersections.push([d1.t, d2.t]);
+    return;
+  }
+  var d1s = splitData(d1);
+  var d2s = splitData(d2);
+  intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[0], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+}
+
+PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
+  if (tolerance === undefined) tolerance = 2;
+  if (maxRecursion === undefined) maxRecursion = 7;
+  var intersections = [];
+  intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
+  return intersections;
+};
+
+PolynomialBezier.shapeSegment = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
+};
+
+PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
+};
+
+function crossProduct(a, b) {
+  return [
+    a[1] * b[2] - a[2] * b[1],
+    a[2] * b[0] - a[0] * b[2],
+    a[0] * b[1] - a[1] * b[0],
+  ];
+}
+
+function lineIntersection(start1, end1, start2, end2) {
+  var v1 = [start1[0], start1[1], 1];
+  var v2 = [end1[0], end1[1], 1];
+  var v3 = [start2[0], start2[1], 1];
+  var v4 = [end2[0], end2[1], 1];
+
+  var r = crossProduct(
+    crossProduct(v1, v2),
+    crossProduct(v3, v4)
+  );
+
+  if (floatZero(r[2])) return null;
+
+  return [r[0] / r[2], r[1] / r[2]];
+}
+
+function polarOffset(p, angle, length) {
+  return [
+    p[0] + Math.cos(angle) * length,
+    p[1] - Math.sin(angle) * length,
+  ];
+}
+
+function pointDistance(p1, p2) {
+  return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
+}
+
+function pointEqual(p1, p2) {
+  return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
+}
+
+function ZigZagModifier() {}
+extendPrototype([ShapeModifier], ZigZagModifier);
+ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
+  this.frequency = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
+  this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
+};
+
+function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
+  var angO = angle - Math.PI / 2;
+  var angI = angle + Math.PI / 2;
+  var px = point[0] + Math.cos(angle) * direction * amplitude;
+  var py = point[1] - Math.sin(angle) * direction * amplitude;
+
+  outputBezier.setTripleAt(
+    px,
+    py,
+    px + Math.cos(angO) * outAmplitude,
+    py - Math.sin(angO) * outAmplitude,
+    px + Math.cos(angI) * inAmplitude,
+    py - Math.sin(angI) * inAmplitude,
+    outputBezier.length()
+  );
+}
+
+function getPerpendicularVector(pt1, pt2) {
+  var vector = [
+    pt2[0] - pt1[0],
+    pt2[1] - pt1[1],
+  ];
+  var rot = -Math.PI * 0.5;
+  var rotatedVector = [
+    Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1],
+    Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1],
+  ];
+  return rotatedVector;
+}
+
+function getProjectingAngle(path, cur) {
+  var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
+  var nextIndex = (cur + 1) % path.length();
+  var prevPoint = path.v[prevIndex];
+  var nextPoint = path.v[nextIndex];
+  var pVector = getPerpendicularVector(prevPoint, nextPoint);
+  return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
+}
+
+function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
+  var angle = getProjectingAngle(path, cur);
+  var point = path.v[cur % path._length];
+  var prevPoint = path.v[cur === 0 ? path._length - 1 : cur - 1];
+  var nextPoint = path.v[(cur + 1) % path._length];
+  var prevDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - prevPoint[0], 2) + Math.pow(point[1] - prevPoint[1], 2))
+    : 0;
+  var nextDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2))
+    : 0;
+
+  setPoint(
+    outputBezier,
+    path.v[cur % path._length],
+    angle,
+    direction,
+    amplitude,
+    nextDist / ((frequency + 1) * 2),
+    prevDist / ((frequency + 1) * 2),
+    pointType
+  );
+}
+
+function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
+  for (var i = 0; i < frequency; i += 1) {
+    var t = (i + 1) / (frequency + 1);
+
+    var dist = pointType === 2
+      ? Math.sqrt(Math.pow(segment.points[3][0] - segment.points[0][0], 2) + Math.pow(segment.points[3][1] - segment.points[0][1], 2))
+      : 0;
+
+    var angle = segment.normalAngle(t);
+    var point = segment.point(t);
+    setPoint(
+      outputBezier,
+      point,
+      angle,
+      direction,
+      amplitude,
+      dist / ((frequency + 1) * 2),
+      dist / ((frequency + 1) * 2),
+      pointType
+    );
+
+    direction = -direction;
+  }
+
+  return direction;
+}
+
+ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
+  var count = path._length;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+
+  if (!path.c) {
+    count -= 1;
+  }
+
+  if (count === 0) return clonedPath;
+
+  var direction = -1;
+  var segment = PolynomialBezier.shapeSegment(path, 0);
+  zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
+
+  for (var i = 0; i < count; i += 1) {
+    direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
+
+    if (i === count - 1 && !path.c) {
+      segment = null;
+    } else {
+      segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
+    }
+
+    zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
+  }
+
+  return clonedPath;
+};
+
+ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amplitude = this.amplitude.v;
+  var frequency = Math.max(0, Math.round(this.frequency.v));
+  var pointType = this.pointsType.v;
+
+  if (amplitude !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function linearOffset(p1, p2, amount) {
+  var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
+  return [
+    polarOffset(p1, angle, amount),
+    polarOffset(p2, angle, amount),
+  ];
+}
+
+function offsetSegment(segment, amount) {
+  var p0; var p1a; var p1b; var p2b; var p2a; var
+    p3;
+  var e;
+  e = linearOffset(segment.points[0], segment.points[1], amount);
+  p0 = e[0];
+  p1a = e[1];
+  e = linearOffset(segment.points[1], segment.points[2], amount);
+  p1b = e[0];
+  p2b = e[1];
+  e = linearOffset(segment.points[2], segment.points[3], amount);
+  p2a = e[0];
+  p3 = e[1];
+  var p1 = lineIntersection(p0, p1a, p1b, p2b);
+  if (p1 === null) p1 = p1a;
+  var p2 = lineIntersection(p2a, p3, p1b, p2b);
+  if (p2 === null) p2 = p2a;
+
+  return new PolynomialBezier(p0, p1, p2, p3);
+}
+
+function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
+  var p0 = seg1.points[3];
+  var p1 = seg2.points[0];
+
+  // Bevel
+  if (lineJoin === 3) return p0;
+
+  // Connected, they don't need a joint
+  if (pointEqual(p0, p1)) return p0;
+
+  // Round
+  if (lineJoin === 2) {
+    var angleOut = -seg1.tangentAngle(1);
+    var angleIn = -seg2.tangentAngle(0) + Math.PI;
+    var center = lineIntersection(
+      p0,
+      polarOffset(p0, angleOut + Math.PI / 2, 100),
+      p1,
+      polarOffset(p1, angleOut + Math.PI / 2, 100)
+    );
+    var radius = center ? pointDistance(center, p0) : pointDistance(p0, p1) / 2;
+
+    var tan = polarOffset(p0, angleOut, 2 * radius * roundCorner);
+    outputBezier.setXYAt(tan[0], tan[1], 'o', outputBezier.length() - 1);
+
+    tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
+    outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
+
+    return p1;
+  }
+
+  // Miter
+  var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
+  var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
+  var intersection = lineIntersection(t0, p0, p1, t1);
+  if (intersection && pointDistance(intersection, p0) < miterLimit) {
+    outputBezier.setTripleAt(
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      outputBezier.length()
+    );
+    return intersection;
+  }
+
+  return p0;
+}
+
+function getIntersection(a, b) {
+  const intersect = a.intersections(b);
+
+  if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
+
+  if (intersect.length) return intersect[0];
+
+  return null;
+}
+
+function pruneSegmentIntersection(a, b) {
+  var outa = a.slice();
+  var outb = b.slice();
+  var intersect = getIntersection(a[a.length - 1], b[0]);
+  if (intersect) {
+    outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
+    outb[0] = b[0].split(intersect[1])[1];
+  }
+  if (a.length > 1 && b.length > 1) {
+    intersect = getIntersection(a[0], b[b.length - 1]);
+    if (intersect) {
+      return [
+        [a[0].split(intersect[0])[0]],
+        [b[b.length - 1].split(intersect[1])[1]],
+      ];
+    }
+  }
+  return [outa, outb];
+}
+
+function pruneIntersections(segments) {
+  var e;
+  for (var i = 1; i < segments.length; i += 1) {
+    e = pruneSegmentIntersection(segments[i - 1], segments[i]);
+    segments[i - 1] = e[0];
+    segments[i] = e[1];
+  }
+
+  if (segments.length > 1) {
+    e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
+    segments[segments.length - 1] = e[0];
+    segments[0] = e[1];
+  }
+
+  return segments;
+}
+
+function offsetSegmentSplit(segment, amount) {
+  /*
+    We split each bezier segment into smaller pieces based
+    on inflection points, this ensures the control point
+    polygon is convex.
+
+    (A cubic bezier can have none, one, or two inflection points)
+  */
+  var flex = segment.inflectionPoints();
+  var left;
+  var right;
+  var split;
+  var mid;
+
+  if (flex.length === 0) {
+    return [offsetSegment(segment, amount)];
+  }
+
+  if (flex.length === 1 || floatEqual(flex[1], 1)) {
+    split = segment.split(flex[0]);
+    left = split[0];
+    right = split[1];
+
+    return [
+      offsetSegment(left, amount),
+      offsetSegment(right, amount),
+    ];
+  }
+
+  split = segment.split(flex[0]);
+  left = split[0];
+  var t = (flex[1] - flex[0]) / (1 - flex[0]);
+  split = split[1].split(t);
+  mid = split[0];
+  right = split[1];
+
+  return [
+    offsetSegment(left, amount),
+    offsetSegment(mid, amount),
+    offsetSegment(right, amount),
+  ];
+}
+
+function OffsetPathModifier() {}
+
+extendPrototype([ShapeModifier], OffsetPathModifier);
+OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this.miterLimit = PropertyFactory.getProp(elem, data.ml, 0, null, this);
+  this.lineJoin = data.lj;
+  this._isAnimated = this.amount.effectsSequence.length !== 0;
+};
+
+OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
+  var outputBezier = shapePool.newElement();
+  outputBezier.c = inputBezier.c;
+  var count = inputBezier.length();
+  if (!inputBezier.c) {
+    count -= 1;
+  }
+  var i; var j; var segment;
+  var multiSegments = [];
+
+  for (i = 0; i < count; i += 1) {
+    segment = PolynomialBezier.shapeSegment(inputBezier, i);
+    multiSegments.push(offsetSegmentSplit(segment, amount));
+  }
+
+  if (!inputBezier.c) {
+    for (i = count - 1; i >= 0; i -= 1) {
+      segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
+      multiSegments.push(offsetSegmentSplit(segment, amount));
+    }
+  }
+
+  multiSegments = pruneIntersections(multiSegments);
+
+  // Add bezier segments to the output and apply line joints
+  var lastPoint = null;
+  var lastSeg = null;
+
+  for (i = 0; i < multiSegments.length; i += 1) {
+    var multiSegment = multiSegments[i];
+
+    if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
+
+    lastSeg = multiSegment[multiSegment.length - 1];
+
+    for (j = 0; j < multiSegment.length; j += 1) {
+      segment = multiSegment[j];
+
+      if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
+        outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
+      } else {
+        outputBezier.setTripleAt(
+          segment.points[0][0],
+          segment.points[0][1],
+          segment.points[1][0],
+          segment.points[1][1],
+          segment.points[0][0],
+          segment.points[0][1],
+          outputBezier.length()
+        );
+      }
+
+      outputBezier.setTripleAt(
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[2][0],
+        segment.points[2][1],
+        outputBezier.length()
+      );
+
+      lastPoint = segment.points[3];
+    }
+  }
+
+  if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
+
+  return outputBezier;
+};
+
+OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+  var miterLimit = this.miterLimit.v;
+  var lineJoin = this.lineJoin;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function getFontProperties(fontData) {
+  var styles = fontData.fStyle ? fontData.fStyle.split(' ') : [];
+
+  var fWeight = 'normal'; var
+    fStyle = 'normal';
+  var len = styles.length;
+  var styleName;
+  for (var i = 0; i < len; i += 1) {
+    styleName = styles[i].toLowerCase();
+    switch (styleName) {
+      case 'italic':
+        fStyle = 'italic';
+        break;
+      case 'bold':
+        fWeight = '700';
+        break;
+      case 'black':
+        fWeight = '900';
+        break;
+      case 'medium':
+        fWeight = '500';
+        break;
+      case 'regular':
+      case 'normal':
+        fWeight = '400';
+        break;
+      case 'light':
+      case 'thin':
+        fWeight = '200';
+        break;
+      default:
+        break;
+    }
+  }
+
+  return {
+    style: fStyle,
+    weight: fontData.fWeight || fWeight,
+  };
+}
+
+const FontManager = (function () {
+  var maxWaitingTime = 5000;
+  var emptyChar = {
+    w: 0,
+    size: 0,
+    shapes: [],
+    data: {
+      shapes: [],
+    },
+  };
+  var combinedCharacters = [];
+  // Hindi characters
+  combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366,
+    2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379,
+    2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
+
+  var BLACK_FLAG_CODE_POINT = 127988;
+  var CANCEL_TAG_CODE_POINT = 917631;
+  var A_TAG_CODE_POINT = 917601;
+  var Z_TAG_CODE_POINT = 917626;
+  var VARIATION_SELECTOR_16_CODE_POINT = 65039;
+  var ZERO_WIDTH_JOINER_CODE_POINT = 8205;
+  var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
+  var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
+
+  var surrogateModifiers = [
+    'd83cdffb',
+    'd83cdffc',
+    'd83cdffd',
+    'd83cdffe',
+    'd83cdfff',
+  ];
+
+  function trimFontOptions(font) {
+    var familyArray = font.split(',');
+    var i;
+    var len = familyArray.length;
+    var enabledFamilies = [];
+    for (i = 0; i < len; i += 1) {
+      if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
+        enabledFamilies.push(familyArray[i]);
+      }
+    }
+    return enabledFamilies.join(',');
+  }
+
+  function setUpNode(font, family) {
+    var parentNode = createTag('span');
+    // Node is invisible to screen readers.
+    parentNode.setAttribute('aria-hidden', true);
+    parentNode.style.fontFamily = family;
+    var node = createTag('span');
+    // Characters that vary significantly among different fonts
+    node.innerText = 'giItT1WQy@!-/#';
+    // Visible - so we can measure it - but not on the screen
+    parentNode.style.position = 'absolute';
+    parentNode.style.left = '-10000px';
+    parentNode.style.top = '-10000px';
+    // Large font size makes even subtle changes obvious
+    parentNode.style.fontSize = '300px';
+    // Reset any font properties
+    parentNode.style.fontVariant = 'normal';
+    parentNode.style.fontStyle = 'normal';
+    parentNode.style.fontWeight = 'normal';
+    parentNode.style.letterSpacing = '0';
+    parentNode.appendChild(node);
+    document.body.appendChild(parentNode);
+
+    // Remember width with no applied web font
+    var width = node.offsetWidth;
+    node.style.fontFamily = trimFontOptions(font) + ', ' + family;
+    return { node: node, w: width, parent: parentNode };
+  }
+
+  function checkLoadedFonts() {
+    var i;
+    var len = this.fonts.length;
+    var node;
+    var w;
+    var loadedCount = len;
+    for (i = 0; i < len; i += 1) {
+      if (this.fonts[i].loaded) {
+        loadedCount -= 1;
+      } else if (this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0) {
+        this.fonts[i].loaded = true;
+      } else {
+        node = this.fonts[i].monoCase.node;
+        w = this.fonts[i].monoCase.w;
+        if (node.offsetWidth !== w) {
+          loadedCount -= 1;
+          this.fonts[i].loaded = true;
+        } else {
+          node = this.fonts[i].sansCase.node;
+          w = this.fonts[i].sansCase.w;
+          if (node.offsetWidth !== w) {
+            loadedCount -= 1;
+            this.fonts[i].loaded = true;
+          }
+        }
+        if (this.fonts[i].loaded) {
+          this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
+          this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
+        }
+      }
+    }
+
+    if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
+      setTimeout(this.checkLoadedFontsBinded, 20);
+    } else {
+      setTimeout(this.setIsLoadedBinded, 10);
+    }
+  }
+
+  function createHelper(fontData, def) {
+    var engine = (document.body && def) ? 'svg' : 'canvas';
+    var helper;
+    var fontProps = getFontProperties(fontData);
+    if (engine === 'svg') {
+      var tHelper = createNS('text');
+      tHelper.style.fontSize = '100px';
+      // tHelper.style.fontFamily = fontData.fFamily;
+      tHelper.setAttribute('font-family', fontData.fFamily);
+      tHelper.setAttribute('font-style', fontProps.style);
+      tHelper.setAttribute('font-weight', fontProps.weight);
+      tHelper.textContent = '1';
+      if (fontData.fClass) {
+        tHelper.style.fontFamily = 'inherit';
+        tHelper.setAttribute('class', fontData.fClass);
+      } else {
+        tHelper.style.fontFamily = fontData.fFamily;
+      }
+      def.appendChild(tHelper);
+      helper = tHelper;
+    } else {
+      var tCanvasHelper = new OffscreenCanvas(500, 500).getContext('2d');
+      tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
+      helper = tCanvasHelper;
+    }
+    function measure(text) {
+      if (engine === 'svg') {
+        helper.textContent = text;
+        return helper.getComputedTextLength();
+      }
+      return helper.measureText(text).width;
+    }
+    return {
+      measureText: measure,
+    };
+  }
+
+  function addFonts(fontData, defs) {
+    if (!fontData) {
+      this.isLoaded = true;
+      return;
+    }
+    if (this.chars) {
+      this.isLoaded = true;
+      this.fonts = fontData.list;
+      return;
+    }
+    if (!document.body) {
+      this.isLoaded = true;
+      fontData.list.forEach((data) => {
+        data.helper = createHelper(data);
+        data.cache = {};
+      });
+      this.fonts = fontData.list;
+      return;
+    }
+
+    var fontArr = fontData.list;
+    var i;
+    var len = fontArr.length;
+    var _pendingFonts = len;
+    for (i = 0; i < len; i += 1) {
+      var shouldLoadFont = true;
+      var loadedSelector;
+      var j;
+      fontArr[i].loaded = false;
+      fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
+      fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
+      if (!fontArr[i].fPath) {
+        fontArr[i].loaded = true;
+        _pendingFonts -= 1;
+      } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
+        loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
+
+        if (loadedSelector.length > 0) {
+          shouldLoadFont = false;
+        }
+
+        if (shouldLoadFont) {
+          var s = createTag('style');
+          s.setAttribute('f-forigin', fontArr[i].fOrigin);
+          s.setAttribute('f-origin', fontArr[i].origin);
+          s.setAttribute('f-family', fontArr[i].fFamily);
+          s.type = 'text/css';
+          s.innerText = '@font-face {font-family: ' + fontArr[i].fFamily + "; font-style: normal; src: url('" + fontArr[i].fPath + "');}";
+          defs.appendChild(s);
+        }
+      } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
+        loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var l = createTag('link');
+          l.setAttribute('f-forigin', fontArr[i].fOrigin);
+          l.setAttribute('f-origin', fontArr[i].origin);
+          l.type = 'text/css';
+          l.rel = 'stylesheet';
+          l.href = fontArr[i].fPath;
+          document.body.appendChild(l);
+        }
+      } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
+        loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (fontArr[i].fPath === loadedSelector[j].src) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var sc = createTag('link');
+          sc.setAttribute('f-forigin', fontArr[i].fOrigin);
+          sc.setAttribute('f-origin', fontArr[i].origin);
+          sc.setAttribute('rel', 'stylesheet');
+          sc.setAttribute('href', fontArr[i].fPath);
+          defs.appendChild(sc);
+        }
+      }
+      fontArr[i].helper = createHelper(fontArr[i], defs);
+      fontArr[i].cache = {};
+      this.fonts.push(fontArr[i]);
+    }
+    if (_pendingFonts === 0) {
+      this.isLoaded = true;
+    } else {
+      // On some cases even if the font is loaded, it won't load correctly when measuring text on canvas.
+      // Adding this timeout seems to fix it
+      setTimeout(this.checkLoadedFonts.bind(this), 100);
+    }
+  }
+
+  function addChars(chars) {
+    if (!chars) {
+      return;
+    }
+    if (!this.chars) {
+      this.chars = [];
+    }
+    var i;
+    var len = chars.length;
+    var j;
+    var jLen = this.chars.length;
+    var found;
+    for (i = 0; i < len; i += 1) {
+      j = 0;
+      found = false;
+      while (j < jLen) {
+        if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
+          found = true;
+        }
+        j += 1;
+      }
+      if (!found) {
+        this.chars.push(chars[i]);
+        jLen += 1;
+      }
+    }
+  }
+
+  function getCharData(char, style, font) {
+    var i = 0;
+    var len = this.chars.length;
+    while (i < len) {
+      if (this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font) {
+        return this.chars[i];
+      }
+      i += 1;
+    }
+    if (((typeof char === 'string' && char.charCodeAt(0) !== 13) || !char)
+            && console
+            && console.warn // eslint-disable-line no-console
+            && !this._warned
+    ) {
+      this._warned = true;
+      console.warn('Missing character from exported characters list: ', char, style, font); // eslint-disable-line no-console
+    }
+    return emptyChar;
+  }
+
+  function measureText(char, fontName, size) {
+    var fontData = this.getFontByName(fontName);
+    // Using the char instead of char.charCodeAt(0)
+    // to avoid collisions between equal chars
+    var index = char;
+    if (!fontData.cache[index]) {
+      var tHelper = fontData.helper;
+      if (char === ' ') {
+        var doubleSize = tHelper.measureText('|' + char + '|');
+        var singleSize = tHelper.measureText('||');
+        fontData.cache[index] = (doubleSize - singleSize) / 100;
+      } else {
+        fontData.cache[index] = tHelper.measureText(char) / 100;
+      }
+    }
+    return fontData.cache[index] * size;
+  }
+
+  function getFontByName(name) {
+    var i = 0;
+    var len = this.fonts.length;
+    while (i < len) {
+      if (this.fonts[i].fName === name) {
+        return this.fonts[i];
+      }
+      i += 1;
+    }
+    return this.fonts[0];
+  }
+
+  function getCodePoint(string) {
+    var codePoint = 0;
+    var first = string.charCodeAt(0);
+    if (first >= 0xD800 && first <= 0xDBFF) {
+      var second = string.charCodeAt(1);
+      if (second >= 0xDC00 && second <= 0xDFFF) {
+        codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+      }
+    }
+    return codePoint;
+  }
+
+  // Skin tone modifiers
+  function isModifier(firstCharCode, secondCharCode) {
+    var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
+    return surrogateModifiers.indexOf(sum) !== -1;
+  }
+
+  function isZeroWidthJoiner(charCode) {
+    return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
+  }
+
+  // This codepoint may change the appearance of the preceding character.
+  // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
+  // as a colorful image as compared to a monochrome text variant.
+  function isVariationSelector(charCode) {
+    return charCode === VARIATION_SELECTOR_16_CODE_POINT;
+  }
+
+  // The regional indicator symbols are a set of 26 alphabetic Unicode
+  /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
+  // two-letter country codes in a way that allows optional special treatment.
+  function isRegionalCode(string) {
+    var codePoint = getCodePoint(string);
+    if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
+      return true;
+    }
+    return false;
+  }
+
+  // Some Emoji implementations represent combinations of
+  // two “regional indicator” letters as a single flag symbol.
+  function isFlagEmoji(string) {
+    return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
+  }
+
+  function isCombinedCharacter(char) {
+    return combinedCharacters.indexOf(char) !== -1;
+  }
+
+  // Regional flags start with a BLACK_FLAG_CODE_POINT
+  // folowed by 5 chars in the TAG range
+  // and end with a CANCEL_TAG_CODE_POINT
+  function isRegionalFlag(text, index) {
+    var codePoint = getCodePoint(text.substr(index, 2));
+    if (codePoint !== BLACK_FLAG_CODE_POINT) {
+      return false;
+    }
+    var count = 0;
+    index += 2;
+    while (count < 5) {
+      codePoint = getCodePoint(text.substr(index, 2));
+      if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
+        return false;
+      }
+      count += 1;
+      index += 2;
+    }
+    return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
+  }
+
+  function setIsLoaded() {
+    this.isLoaded = true;
+  }
+
+  var Font = function () {
+    this.fonts = [];
+    this.chars = null;
+    this.typekitLoaded = 0;
+    this.isLoaded = false;
+    this._warned = false;
+    this.initTime = Date.now();
+    this.setIsLoadedBinded = this.setIsLoaded.bind(this);
+    this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
+  };
+  Font.isModifier = isModifier;
+  Font.isZeroWidthJoiner = isZeroWidthJoiner;
+  Font.isFlagEmoji = isFlagEmoji;
+  Font.isRegionalCode = isRegionalCode;
+  Font.isCombinedCharacter = isCombinedCharacter;
+  Font.isRegionalFlag = isRegionalFlag;
+  Font.isVariationSelector = isVariationSelector;
+  Font.BLACK_FLAG_CODE_POINT = BLACK_FLAG_CODE_POINT;
+
+  var fontPrototype = {
+    addChars: addChars,
+    addFonts: addFonts,
+    getCharData: getCharData,
+    getFontByName: getFontByName,
+    measureText: measureText,
+    checkLoadedFonts: checkLoadedFonts,
+    setIsLoaded: setIsLoaded,
+  };
+
+  Font.prototype = fontPrototype;
+
+  return Font;
+}());
+
+function SlotManager(animationData) {
+  this.animationData = animationData;
+}
+SlotManager.prototype.getProp = function (data) {
+  if (this.animationData.slots
+    && this.animationData.slots[data.sid]
+  ) {
+    return Object.assign(data, this.animationData.slots[data.sid].p);
+  }
+  return data;
+};
+
+function slotFactory(animationData) {
+  return new SlotManager(animationData);
+}
+
+function RenderableElement() {
+
+}
+
+RenderableElement.prototype = {
+  initRenderable: function () {
+    // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
+    this.isInRange = false;
+    // layer's display state
+    this.hidden = false;
+    // If layer's transparency equals 0, it can be hidden
+    this.isTransparent = false;
+    // list of animated components
+    this.renderableComponents = [];
+  },
+  addRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) === -1) {
+      this.renderableComponents.push(component);
+    }
+  },
+  removeRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) !== -1) {
+      this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1);
+    }
+  },
+  prepareRenderableFrame: function (num) {
+    this.checkLayerLimits(num);
+  },
+  checkTransparency: function () {
+    if (this.finalTransform.mProp.o.v <= 0) {
+      if (!this.isTransparent && this.globalData.renderConfig.hideOnTransparent) {
+        this.isTransparent = true;
+        this.hide();
+      }
+    } else if (this.isTransparent) {
+      this.isTransparent = false;
+      this.show();
+    }
+  },
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     *
+     */
+  checkLayerLimits: function (num) {
+    if (this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) {
+      if (this.isInRange !== true) {
+        this.globalData._mdf = true;
+        this._mdf = true;
+        this.isInRange = true;
+        this.show();
+      }
+    } else if (this.isInRange !== false) {
+      this.globalData._mdf = true;
+      this.isInRange = false;
+      this.hide();
+    }
+  },
+  renderRenderable: function () {
+    var i;
+    var len = this.renderableComponents.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderableComponents[i].renderFrame(this._isFirstFrame);
+    }
+    /* this.maskManager.renderFrame(this.finalTransform.mat);
+        this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
+  },
+  sourceRectAtTime: function () {
+    return {
+      top: 0,
+      left: 0,
+      width: 100,
+      height: 100,
+    };
+  },
+  getLayerSize: function () {
+    if (this.data.ty === 5) {
+      return { w: this.data.textData.width, h: this.data.textData.height };
+    }
+    return { w: this.data.width, h: this.data.height };
+  },
+};
+
+const getBlendMode = (function () {
+  var blendModeEnums = {
+    0: 'source-over',
+    1: 'multiply',
+    2: 'screen',
+    3: 'overlay',
+    4: 'darken',
+    5: 'lighten',
+    6: 'color-dodge',
+    7: 'color-burn',
+    8: 'hard-light',
+    9: 'soft-light',
+    10: 'difference',
+    11: 'exclusion',
+    12: 'hue',
+    13: 'saturation',
+    14: 'color',
+    15: 'luminosity',
+  };
+
+  return function (mode) {
+    return blendModeEnums[mode] || '';
+  };
+}());
+
+function SliderEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function AngleEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function ColorEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function PointEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function LayerIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function MaskIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function CheckboxEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function NoValueEffect() {
+  this.p = {};
+}
+
+function EffectsManager(data, element) {
+  var effects = data.ef || [];
+  this.effectElements = [];
+  var i;
+  var len = effects.length;
+  var effectItem;
+  for (i = 0; i < len; i += 1) {
+    effectItem = new GroupEffect(effects[i], element);
+    this.effectElements.push(effectItem);
+  }
+}
+
+function GroupEffect(data, element) {
+  this.init(data, element);
+}
+
+extendPrototype([DynamicPropertyContainer], GroupEffect);
+
+GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
+
+GroupEffect.prototype.init = function (data, element) {
+  this.data = data;
+  this.effectElements = [];
+  this.initDynamicPropertyContainer(element);
+  var i;
+  var len = this.data.ef.length;
+  var eff;
+  var effects = this.data.ef;
+  for (i = 0; i < len; i += 1) {
+    eff = null;
+    switch (effects[i].ty) {
+      case 0:
+        eff = new SliderEffect(effects[i], element, this);
+        break;
+      case 1:
+        eff = new AngleEffect(effects[i], element, this);
+        break;
+      case 2:
+        eff = new ColorEffect(effects[i], element, this);
+        break;
+      case 3:
+        eff = new PointEffect(effects[i], element, this);
+        break;
+      case 4:
+      case 7:
+        eff = new CheckboxEffect(effects[i], element, this);
+        break;
+      case 10:
+        eff = new LayerIndexEffect(effects[i], element, this);
+        break;
+      case 11:
+        eff = new MaskIndexEffect(effects[i], element, this);
+        break;
+      case 5:
+        eff = new EffectsManager(effects[i], element, this);
+        break;
+        // case 6:
+      default:
+        eff = new NoValueEffect(effects[i], element, this);
+        break;
+    }
+    if (eff) {
+      this.effectElements.push(eff);
+    }
+  }
+};
+
+function BaseElement() {
+}
+
+BaseElement.prototype = {
+  checkMasks: function () {
+    if (!this.data.hasMask) {
+      return false;
+    }
+    var i = 0;
+    var len = this.data.masksProperties.length;
+    while (i < len) {
+      if ((this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false)) {
+        return true;
+      }
+      i += 1;
+    }
+    return false;
+  },
+  initExpressions: function () {
+    const expressionsInterfaces = getExpressionInterfaces();
+    if (!expressionsInterfaces) {
+      return;
+    }
+    const LayerExpressionInterface = expressionsInterfaces('layer');
+    const EffectsExpressionInterface = expressionsInterfaces('effects');
+    const ShapeExpressionInterface = expressionsInterfaces('shape');
+    const TextExpressionInterface = expressionsInterfaces('text');
+    const CompExpressionInterface = expressionsInterfaces('comp');
+    this.layerInterface = LayerExpressionInterface(this);
+    if (this.data.hasMask && this.maskManager) {
+      this.layerInterface.registerMaskInterface(this.maskManager);
+    }
+    var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
+    this.layerInterface.registerEffectsInterface(effectsInterface);
+
+    if (this.data.ty === 0 || this.data.xt) {
+      this.compInterface = CompExpressionInterface(this);
+    } else if (this.data.ty === 4) {
+      this.layerInterface.shapeInterface = ShapeExpressionInterface(this.shapesData, this.itemsData, this.layerInterface);
+      this.layerInterface.content = this.layerInterface.shapeInterface;
+    } else if (this.data.ty === 5) {
+      this.layerInterface.textInterface = TextExpressionInterface(this);
+      this.layerInterface.text = this.layerInterface.textInterface;
+    }
+  },
+  setBlendMode: function () {
+    var blendModeValue = getBlendMode(this.data.bm);
+    var elem = this.baseElement || this.layerElement;
+
+    elem.style['mix-blend-mode'] = blendModeValue;
+  },
+  initBaseData: function (data, globalData, comp) {
+    this.globalData = globalData;
+    this.comp = comp;
+    this.data = data;
+    this.layerId = createElementID();
+
+    // Stretch factor for old animations missing this property.
+    if (!this.data.sr) {
+      this.data.sr = 1;
+    }
+    // effects manager
+    this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
+  },
+  getType: function () {
+    return this.type;
+  },
+  sourceRectAtTime: function () {},
+};
+
+/**
+ * @file
+ * Handles element's layer frame update.
+ * Checks layer in point and out point
+ *
+ */
+
+function FrameElement() {}
+
+FrameElement.prototype = {
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     */
+  initFrame: function () {
+    // set to true when inpoint is rendered
+    this._isFirstFrame = false;
+    // list of animated properties
+    this.dynamicProperties = [];
+    // If layer has been modified in current tick this will be true
+    this._mdf = false;
+  },
+  /**
+     * @function
+     * Calculates all dynamic values
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     * @param {boolean} isVisible
+     * if layers is currently in range
+     *
+     */
+  prepareProperties: function (num, isVisible) {
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      if (isVisible || (this._isParent && this.dynamicProperties[i].propType === 'transform')) {
+        this.dynamicProperties[i].getValue();
+        if (this.dynamicProperties[i]._mdf) {
+          this.globalData._mdf = true;
+          this._mdf = true;
+        }
+      }
+    }
+  },
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+    }
+  },
+};
+
+function FootageElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.footageData = globalData.imageLoader.getAsset(this.assetData);
+  this.initBaseData(data, globalData, comp);
+}
+
+FootageElement.prototype.prepareFrame = function () {
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
+
+FootageElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+FootageElement.prototype.renderFrame = function () {
+};
+
+FootageElement.prototype.destroy = function () {
+};
+
+FootageElement.prototype.initExpressions = function () {
+  const expressionsInterfaces = getExpressionInterfaces();
+  if (!expressionsInterfaces) {
+    return;
+  }
+  const FootageInterface = expressionsInterfaces('footage');
+  this.layerInterface = FootageInterface(this);
+};
+
+FootageElement.prototype.getFootageData = function () {
+  return this.footageData;
+};
+
+function AudioElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initBaseData(data, globalData, comp);
+  this._isPlaying = false;
+  this._canPlay = false;
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  this.audio = this.globalData.audioController.createAudio(assetPath);
+  this._currentTime = 0;
+  this.globalData.audioController.addAudio(this);
+  this._volumeMultiplier = 1;
+  this._volume = 1;
+  this._previousVolume = null;
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+  this.lv = PropertyFactory.getProp(this, data.au && data.au.lv ? data.au.lv : { k: [100] }, 1, 0.01, this);
+}
+
+AudioElement.prototype.prepareFrame = function (num) {
+  this.prepareRenderableFrame(num, true);
+  this.prepareProperties(num, true);
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    this._currentTime = timeRemapped;
+  } else {
+    this._currentTime = num / this.data.sr;
+  }
+  this._volume = this.lv.v[0];
+  var totalVolume = this._volume * this._volumeMultiplier;
+  if (this._previousVolume !== totalVolume) {
+    this._previousVolume = totalVolume;
+    this.audio.volume(totalVolume);
+  }
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
+
+AudioElement.prototype.renderFrame = function () {
+  if (this.isInRange && this._canPlay) {
+    if (!this._isPlaying) {
+      this.audio.play();
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+      this._isPlaying = true;
+    } else if (!this.audio.playing()
+      || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1
+    ) {
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+    }
+  }
+};
+
+AudioElement.prototype.show = function () {
+  // this.audio.play()
+};
+
+AudioElement.prototype.hide = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+};
+
+AudioElement.prototype.pause = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+  this._canPlay = false;
+};
+
+AudioElement.prototype.resume = function () {
+  this._canPlay = true;
+};
+
+AudioElement.prototype.setRate = function (rateValue) {
+  this.audio.rate(rateValue);
+};
+
+AudioElement.prototype.volume = function (volumeValue) {
+  this._volumeMultiplier = volumeValue;
+  this._previousVolume = volumeValue * this._volume;
+  this.audio.volume(this._previousVolume);
+};
+
+AudioElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+AudioElement.prototype.destroy = function () {
+};
+
+AudioElement.prototype.sourceRectAtTime = function () {
+};
+
+AudioElement.prototype.initExpressions = function () {
+};
+
+function BaseRenderer() {}
+BaseRenderer.prototype.checkLayers = function (num) {
+  var i;
+  var len = this.layers.length;
+  var data;
+  this.completeLayers = true;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (!this.elements[i]) {
+      data = this.layers[i];
+      if (data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) {
+        this.buildItem(i);
+      }
+    }
+    this.completeLayers = this.elements[i] ? this.completeLayers : false;
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.createItem = function (layer) {
+  switch (layer.ty) {
+    case 2:
+      return this.createImage(layer);
+    case 0:
+      return this.createComp(layer);
+    case 1:
+      return this.createSolid(layer);
+    case 3:
+      return this.createNull(layer);
+    case 4:
+      return this.createShape(layer);
+    case 5:
+      return this.createText(layer);
+    case 6:
+      return this.createAudio(layer);
+    case 13:
+      return this.createCamera(layer);
+    case 15:
+      return this.createFootage(layer);
+    default:
+      return this.createNull(layer);
+  }
+};
+
+BaseRenderer.prototype.createCamera = function () {
+  throw new Error('You\'re using a 3d camera. Try the html renderer.');
+};
+
+BaseRenderer.prototype.createAudio = function (data) {
+  return new AudioElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.createFootage = function (data) {
+  return new FootageElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.buildAllItems = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    this.buildItem(i);
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.includeLayers = function (newLayers) {
+  this.completeLayers = false;
+  var i;
+  var len = newLayers.length;
+  var j;
+  var jLen = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    j = 0;
+    while (j < jLen) {
+      if (this.layers[j].id === newLayers[i].id) {
+        this.layers[j] = newLayers[i];
+        break;
+      }
+      j += 1;
+    }
+  }
+};
+
+BaseRenderer.prototype.setProjectInterface = function (pInterface) {
+  this.globalData.projectInterface = pInterface;
+};
+
+BaseRenderer.prototype.initItems = function () {
+  if (!this.globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+};
+BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
+  var elements = this.elements;
+  var layers = this.layers;
+  var i = 0;
+  var len = layers.length;
+  while (i < len) {
+    if (layers[i].ind == parentName) { // eslint-disable-line eqeqeq
+      if (!elements[i] || elements[i] === true) {
+        this.buildItem(i);
+        this.addPendingElement(element);
+      } else {
+        hierarchy.push(elements[i]);
+        elements[i].setAsParent();
+        if (layers[i].parent !== undefined) {
+          this.buildElementParenting(element, layers[i].parent, hierarchy);
+        } else {
+          element.setHierarchy(hierarchy);
+        }
+      }
+    }
+    i += 1;
+  }
+};
+
+BaseRenderer.prototype.addPendingElement = function (element) {
+  this.pendingElements.push(element);
+};
+
+BaseRenderer.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var len = assets.length;
+  for (i = 0; i < len; i += 1) {
+    if (assets[i].xt) {
+      var comp = this.createComp(assets[i]);
+      comp.initExpressions();
+      this.globalData.projectInterface.registerComposition(comp);
+    }
+  }
+};
+
+BaseRenderer.prototype.getElementById = function (ind) {
+  var i;
+  var len = this.elements.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i].data.ind === ind) {
+      return this.elements[i];
+    }
+  }
+  return null;
+};
+
+BaseRenderer.prototype.getElementByPath = function (path) {
+  var pathValue = path.shift();
+  var element;
+  if (typeof pathValue === 'number') {
+    element = this.elements[pathValue];
+  } else {
+    var i;
+    var len = this.elements.length;
+    for (i = 0; i < len; i += 1) {
+      if (this.elements[i].data.nm === pathValue) {
+        element = this.elements[i];
+        break;
+      }
+    }
+  }
+  if (path.length === 0) {
+    return element;
+  }
+  return element.getElementByPath(path);
+};
+
+BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
+  this.globalData.fontManager = new FontManager();
+  this.globalData.slotManager = slotFactory(animData);
+  this.globalData.fontManager.addChars(animData.chars);
+  this.globalData.fontManager.addFonts(animData.fonts, fontsContainer);
+  this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+  this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+  this.globalData.imageLoader = this.animationItem.imagePreloader;
+  this.globalData.audioController = this.animationItem.audioController;
+  this.globalData.frameId = 0;
+  this.globalData.frameRate = animData.fr;
+  this.globalData.nm = animData.nm;
+  this.globalData.compSize = {
+    w: animData.w,
+    h: animData.h,
+  };
+};
+
+var effectTypes = {
+  TRANSFORM_EFFECT: 'transformEFfect',
+};
+
+function TransformElement() {}
+
+TransformElement.prototype = {
+  initTransform: function () {
+    var mat = new Matrix();
+    this.finalTransform = {
+      mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : { o: 0 },
+      _matMdf: false,
+      _localMatMdf: false,
+      _opMdf: false,
+      mat: mat,
+      localMat: mat,
+      localOpacity: 1,
+    };
+    if (this.data.ao) {
+      this.finalTransform.mProp.autoOriented = true;
+    }
+
+    // TODO: check TYPE 11: Guided elements
+    if (this.data.ty !== 11) {
+      // this.createElements();
+    }
+  },
+  renderTransform: function () {
+    this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
+    this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
+
+    if (this.hierarchy) {
+      var mat;
+      var finalMat = this.finalTransform.mat;
+      var i = 0;
+      var len = this.hierarchy.length;
+      // Checking if any of the transformation matrices in the hierarchy chain has changed.
+      if (!this.finalTransform._matMdf) {
+        while (i < len) {
+          if (this.hierarchy[i].finalTransform.mProp._mdf) {
+            this.finalTransform._matMdf = true;
+            break;
+          }
+          i += 1;
+        }
+      }
+
+      if (this.finalTransform._matMdf) {
+        mat = this.finalTransform.mProp.v.props;
+        finalMat.cloneFromProps(mat);
+        for (i = 0; i < len; i += 1) {
+          finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
+        }
+      }
+    }
+    if (!this.localTransforms || this.finalTransform._matMdf) {
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+    }
+    if (this.finalTransform._opMdf) {
+      this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderLocalTransform: function () {
+    if (this.localTransforms) {
+      var i = 0;
+      var len = this.localTransforms.length;
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+      if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
+        while (i < len) {
+          if (this.localTransforms[i]._mdf) {
+            this.finalTransform._localMatMdf = true;
+          }
+          if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
+            this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+            this.finalTransform._opMdf = true;
+          }
+          i += 1;
+        }
+      }
+      if (this.finalTransform._localMatMdf) {
+        var localMat = this.finalTransform.localMat;
+        this.localTransforms[0].matrix.clone(localMat);
+        for (i = 1; i < len; i += 1) {
+          var lmat = this.localTransforms[i].matrix;
+          localMat.multiply(lmat);
+        }
+        localMat.multiply(this.finalTransform.mat);
+      }
+      if (this.finalTransform._opMdf) {
+        var localOp = this.finalTransform.localOpacity;
+        for (i = 0; i < len; i += 1) {
+          localOp *= this.localTransforms[i].opacity * 0.01;
+        }
+        this.finalTransform.localOpacity = localOp;
+      }
+    }
+  },
+  searchEffectTransforms: function () {
+    if (this.renderableEffectsManager) {
+      var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+      if (transformEffects.length) {
+        this.localTransforms = [];
+        this.finalTransform.localMat = new Matrix();
+        var i = 0;
+        var len = transformEffects.length;
+        for (i = 0; i < len; i += 1) {
+          this.localTransforms.push(transformEffects[i]);
+        }
+      }
+    }
+  },
+  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;
+    var len = transforms.length;
+    var 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;
+  },
+  mHelper: new Matrix(),
+};
+
+function MaskElement(data, element, globalData) {
+  this.data = data;
+  this.element = element;
+  this.globalData = globalData;
+  this.storedData = [];
+  this.masksProperties = this.data.masksProperties || [];
+  this.maskElement = null;
+  var defs = this.globalData.defs;
+  var i;
+  var len = this.masksProperties ? this.masksProperties.length : 0;
+  this.viewData = createSizedArray(len);
+  this.solidPath = '';
+
+  var path;
+  var properties = this.masksProperties;
+  var count = 0;
+  var currentMasks = [];
+  var j;
+  var jLen;
+  var layerId = createElementID();
+  var rect;
+  var expansor;
+  var feMorph;
+  var x;
+  var maskType = 'clipPath';
+  var maskRef = 'clip-path';
+  for (i = 0; i < len; i += 1) {
+    if ((properties[i].mode !== 'a' && properties[i].mode !== 'n') || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
+      maskType = 'mask';
+      maskRef = 'mask';
+    }
+
+    if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
+      rect = createNS('rect');
+      rect.setAttribute('fill', '#ffffff');
+      rect.setAttribute('width', this.element.comp.data.w || 0);
+      rect.setAttribute('height', this.element.comp.data.h || 0);
+      currentMasks.push(rect);
+    } else {
+      rect = null;
+    }
+
+    path = createNS('path');
+    if (properties[i].mode === 'n') {
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        elem: path,
+        lastPath: '',
+      };
+      defs.appendChild(path);
+    } else {
+      count += 1;
+
+      path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      path.setAttribute('clip-rule', 'nonzero');
+      var filterID;
+
+      if (properties[i].x.k !== 0) {
+        maskType = 'mask';
+        maskRef = 'mask';
+        x = PropertyFactory.getProp(this.element, properties[i].x, 0, null, this.element);
+        filterID = createElementID();
+        expansor = createNS('filter');
+        expansor.setAttribute('id', filterID);
+        feMorph = createNS('feMorphology');
+        feMorph.setAttribute('operator', 'erode');
+        feMorph.setAttribute('in', 'SourceGraphic');
+        feMorph.setAttribute('radius', '0');
+        expansor.appendChild(feMorph);
+        defs.appendChild(expansor);
+        path.setAttribute('stroke', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      } else {
+        feMorph = null;
+        x = null;
+      }
+
+      // TODO move this to a factory or to a constructor
+      this.storedData[i] = {
+        elem: path,
+        x: x,
+        expan: feMorph,
+        lastPath: '',
+        lastOperator: '',
+        filterId: filterID,
+        lastRadius: 0,
+      };
+      if (properties[i].mode === 'i') {
+        jLen = currentMasks.length;
+        var g = createNS('g');
+        for (j = 0; j < jLen; j += 1) {
+          g.appendChild(currentMasks[j]);
+        }
+        var mask = createNS('mask');
+        mask.setAttribute('mask-type', 'alpha');
+        mask.setAttribute('id', layerId + '_' + count);
+        mask.appendChild(path);
+        defs.appendChild(mask);
+        g.setAttribute('mask', 'url(' + getLocationHref() + '#' + layerId + '_' + count + ')');
+
+        currentMasks.length = 0;
+        currentMasks.push(g);
+      } else {
+        currentMasks.push(path);
+      }
+      if (properties[i].inv && !this.solidPath) {
+        this.solidPath = this.createLayerSolidPath();
+      }
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        elem: path,
+        lastPath: '',
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        invRect: rect,
+      };
+      if (!this.viewData[i].prop.k) {
+        this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
+      }
+    }
+  }
+
+  this.maskElement = createNS(maskType);
+
+  len = currentMasks.length;
+  for (i = 0; i < len; i += 1) {
+    this.maskElement.appendChild(currentMasks[i]);
+  }
+
+  if (count > 0) {
+    this.maskElement.setAttribute('id', layerId);
+    this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
+    defs.appendChild(this.maskElement);
+  }
+  if (this.viewData.length) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+MaskElement.prototype.getMaskProperty = function (pos) {
+  return this.viewData[pos].prop;
+};
+
+MaskElement.prototype.renderFrame = function (isFirstFrame) {
+  var finalMat = this.element.finalTransform.mat;
+  var i;
+  var len = this.masksProperties.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.viewData[i].prop._mdf || isFirstFrame) {
+      this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
+    }
+    if (this.viewData[i].op._mdf || isFirstFrame) {
+      this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
+    }
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
+        this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
+      }
+      if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
+        var feMorph = this.storedData[i].expan;
+        if (this.storedData[i].x.v < 0) {
+          if (this.storedData[i].lastOperator !== 'erode') {
+            this.storedData[i].lastOperator = 'erode';
+            this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
+          }
+          feMorph.setAttribute('radius', -this.storedData[i].x.v);
+        } else {
+          if (this.storedData[i].lastOperator !== 'dilate') {
+            this.storedData[i].lastOperator = 'dilate';
+            this.storedData[i].elem.setAttribute('filter', null);
+          }
+          this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
+        }
+      }
+    }
+  }
+};
+
+MaskElement.prototype.getMaskelement = function () {
+  return this.maskElement;
+};
+
+MaskElement.prototype.createLayerSolidPath = function () {
+  var path = 'M0,0 ';
+  path += ' h' + this.globalData.compSize.w;
+  path += ' v' + this.globalData.compSize.h;
+  path += ' h-' + this.globalData.compSize.w;
+  path += ' v-' + this.globalData.compSize.h + ' ';
+  return path;
+};
+
+MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
+  var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  var i;
+  var len;
+  len = pathNodes._length;
+  for (i = 1; i < len; i += 1) {
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
+  }
+  // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+  if (pathNodes.c && len > 1) {
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  }
+  // pathNodes.__renderedString = pathString;
+
+  if (viewData.lastPath !== pathString) {
+    var pathShapeValue = '';
+    if (viewData.elem) {
+      if (pathNodes.c) {
+        pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
+      }
+      viewData.elem.setAttribute('d', pathShapeValue);
+    }
+    viewData.lastPath = pathString;
+  }
+};
+
+MaskElement.prototype.destroy = function () {
+  this.element = null;
+  this.globalData = null;
+  this.maskElement = null;
+  this.data = null;
+  this.masksProperties = null;
+};
+
+const filtersFactory = (function () {
+  var ob = {};
+  ob.createFilter = createFilter;
+  ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
+
+  function createFilter(filId, skipCoordinates) {
+    var fil = createNS('filter');
+    fil.setAttribute('id', filId);
+    if (skipCoordinates !== true) {
+      fil.setAttribute('filterUnits', 'objectBoundingBox');
+      fil.setAttribute('x', '0%');
+      fil.setAttribute('y', '0%');
+      fil.setAttribute('width', '100%');
+      fil.setAttribute('height', '100%');
+    }
+    return fil;
+  }
+
+  function createAlphaToLuminanceFilter() {
+    var feColorMatrix = createNS('feColorMatrix');
+    feColorMatrix.setAttribute('type', 'matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+    feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
+    return feColorMatrix;
+  }
+
+  return ob;
+}());
+
+const featureSupport = (function () {
+  var ob = {
+    maskType: true,
+    svgLumaHidden: true,
+    offscreenCanvas: typeof OffscreenCanvas !== 'undefined',
+  };
+  if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
+    ob.maskType = false;
+  }
+  if (/firefox/i.test(navigator.userAgent)) {
+    ob.svgLumaHidden = false;
+  }
+  return ob;
+}());
+
+var registeredEffects = {};
+var idPrefix = 'filter_result_';
+
+function SVGEffects(elem) {
+  var i;
+  var source = 'SourceGraphic';
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  var filId = createElementID();
+  var fil = filtersFactory.createFilter(filId, true);
+  var count = 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects[type]) {
+      var Effect = registeredEffects[type].effect;
+      filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
+      source = idPrefix + count;
+      if (registeredEffects[type].countsAsEffect) {
+        count += 1;
+      }
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (count) {
+    elem.globalData.defs.appendChild(fil);
+    elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+SVGEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect(id, effect, countsAsEffect) {
+  registeredEffects[id] = {
+    effect,
+    countsAsEffect,
+  };
+}
+
+function SVGBaseElement() {
+}
+
+SVGBaseElement.prototype = {
+  initRendererElement: function () {
+    this.layerElement = createNS('g');
+  },
+  createContainerElements: function () {
+    this.matteElement = createNS('g');
+    this.transformedElement = this.layerElement;
+    this.maskedElement = this.layerElement;
+    this._sizeChanged = false;
+    var layerElementParent = null;
+    // If this layer acts as a mask for the following layer
+    if (this.data.td) {
+      this.matteMasks = {};
+      var gg = createNS('g');
+      gg.setAttribute('id', this.layerId);
+      gg.appendChild(this.layerElement);
+      layerElementParent = gg;
+      this.globalData.defs.appendChild(gg);
+    } else if (this.data.tt) {
+      this.matteElement.appendChild(this.layerElement);
+      layerElementParent = this.matteElement;
+      this.baseElement = this.matteElement;
+    } else {
+      this.baseElement = this.layerElement;
+    }
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
+    if (this.data.ty === 0 && !this.data.hd) {
+      var cp = createNS('clipPath');
+      var pt = createNS('path');
+      pt.setAttribute('d', 'M0,0 L' + this.data.w + ',0 L' + this.data.w + ',' + this.data.h + ' L0,' + this.data.h + 'z');
+      var clipId = createElementID();
+      cp.setAttribute('id', clipId);
+      cp.appendChild(pt);
+      this.globalData.defs.appendChild(cp);
+
+      if (this.checkMasks()) {
+        var cpGroup = createNS('g');
+        cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+        cpGroup.appendChild(this.layerElement);
+        this.transformedElement = cpGroup;
+        if (layerElementParent) {
+          layerElementParent.appendChild(this.transformedElement);
+        } else {
+          this.baseElement = this.transformedElement;
+        }
+      } else {
+        this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+      }
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    if (this.finalTransform._localMatMdf) {
+      this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
+    }
+    if (this.finalTransform._opMdf) {
+      this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
+    }
+  },
+  destroyBaseElement: function () {
+    this.layerElement = null;
+    this.matteElement = null;
+    this.maskManager.destroy();
+  },
+  getBaseElement: function () {
+    if (this.data.hd) {
+      return null;
+    }
+    return this.baseElement;
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+    this.renderableEffectsManager = new SVGEffects(this);
+    this.searchEffectTransforms();
+  },
+  getMatte: function (matteType) {
+    // This should not be a common case. But for backward compatibility, we'll create the matte object.
+    // It solves animations that have two consecutive layers marked as matte masks.
+    // Which is an undefined behavior in AE.
+    if (!this.matteMasks) {
+      this.matteMasks = {};
+    }
+    if (!this.matteMasks[matteType]) {
+      var id = this.layerId + '_' + matteType;
+      var filId;
+      var fil;
+      var useElement;
+      var gg;
+      if (matteType === 1 || matteType === 3) {
+        var masker = createNS('mask');
+        masker.setAttribute('id', id);
+        masker.setAttribute('mask-type', matteType === 3 ? 'luminance' : 'alpha');
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        masker.appendChild(useElement);
+        this.globalData.defs.appendChild(masker);
+        if (!featureSupport.maskType && matteType === 1) {
+          masker.setAttribute('mask-type', 'luminance');
+          filId = createElementID();
+          fil = filtersFactory.createFilter(filId);
+          this.globalData.defs.appendChild(fil);
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          gg.appendChild(useElement);
+          masker.appendChild(gg);
+          gg.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        }
+      } else if (matteType === 2) {
+        var maskGroup = createNS('mask');
+        maskGroup.setAttribute('id', id);
+        maskGroup.setAttribute('mask-type', 'alpha');
+        var maskGrouper = createNS('g');
+        maskGroup.appendChild(maskGrouper);
+        filId = createElementID();
+        fil = filtersFactory.createFilter(filId);
+        /// /
+        var feCTr = createNS('feComponentTransfer');
+        feCTr.setAttribute('in', 'SourceGraphic');
+        fil.appendChild(feCTr);
+        var feFunc = createNS('feFuncA');
+        feFunc.setAttribute('type', 'table');
+        feFunc.setAttribute('tableValues', '1.0 0.0');
+        feCTr.appendChild(feFunc);
+        /// /
+        this.globalData.defs.appendChild(fil);
+        var alphaRect = createNS('rect');
+        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');
+        alphaRect.setAttribute('opacity', '0');
+        maskGrouper.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        maskGrouper.appendChild(alphaRect);
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        maskGrouper.appendChild(useElement);
+        if (!featureSupport.maskType) {
+          maskGroup.setAttribute('mask-type', 'luminance');
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          maskGrouper.appendChild(alphaRect);
+          gg.appendChild(this.layerElement);
+          maskGrouper.appendChild(gg);
+        }
+        this.globalData.defs.appendChild(maskGroup);
+      }
+      this.matteMasks[matteType] = id;
+    }
+    return this.matteMasks[matteType];
+  },
+  setMatte: function (id) {
+    if (!this.matteElement) {
+      return;
+    }
+    this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+  },
+};
+
+/**
+ * @file
+ * Handles AE's layer parenting property.
+ *
+ */
+
+function HierarchyElement() {}
+
+HierarchyElement.prototype = {
+  /**
+     * @function
+     * Initializes hierarchy properties
+     *
+     */
+  initHierarchy: function () {
+    // element's parent list
+    this.hierarchy = [];
+    // if element is parent of another layer _isParent will be true
+    this._isParent = false;
+    this.checkParenting();
+  },
+  /**
+     * @function
+     * Sets layer's hierarchy.
+     * @param {array} hierarch
+     * layer's parent list
+     *
+     */
+  setHierarchy: function (hierarchy) {
+    this.hierarchy = hierarchy;
+  },
+  /**
+     * @function
+     * Sets layer as parent.
+     *
+     */
+  setAsParent: function () {
+    this._isParent = true;
+  },
+  /**
+     * @function
+     * Searches layer's parenting chain
+     *
+     */
+  checkParenting: function () {
+    if (this.data.parent !== undefined) {
+      this.comp.buildElementParenting(this, this.data.parent, []);
+    }
+  },
+};
+
+function RenderableDOMElement() {}
+
+(function () {
+  var _prototype = {
+    initElement: function (data, globalData, comp) {
+      this.initFrame();
+      this.initBaseData(data, globalData, comp);
+      this.initTransform(data, globalData, comp);
+      this.initHierarchy();
+      this.initRenderable();
+      this.initRendererElement();
+      this.createContainerElements();
+      this.createRenderableComponents();
+      this.createContent();
+      this.hide();
+    },
+    hide: function () {
+      // console.log('HIDE', this);
+      if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+        var elem = this.baseElement || this.layerElement;
+        elem.style.display = 'none';
+        this.hidden = true;
+      }
+    },
+    show: function () {
+      // console.log('SHOW', this);
+      if (this.isInRange && !this.isTransparent) {
+        if (!this.data.hd) {
+          var elem = this.baseElement || this.layerElement;
+          elem.style.display = 'block';
+        }
+        this.hidden = false;
+        this._isFirstFrame = true;
+      }
+    },
+    renderFrame: function () {
+      // If it is exported as hidden (data.hd === true) no need to render
+      // If it is not visible no need to render
+      if (this.data.hd || this.hidden) {
+        return;
+      }
+      this.renderTransform();
+      this.renderRenderable();
+      this.renderLocalTransform();
+      this.renderElement();
+      this.renderInnerContent();
+      if (this._isFirstFrame) {
+        this._isFirstFrame = false;
+      }
+    },
+    renderInnerContent: function () {},
+    prepareFrame: function (num) {
+      this._mdf = false;
+      this.prepareRenderableFrame(num);
+      this.prepareProperties(num, this.isInRange);
+      this.checkTransparency();
+    },
+    destroy: function () {
+      this.innerElem = null;
+      this.destroyBaseElement();
+    },
+  };
+  extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement);
+}());
+
+function IImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  if (this.assetData && this.assetData.sid) {
+    this.assetData = globalData.slotManager.getProp(this.assetData);
+  }
+  this.initElement(data, globalData, comp);
+  this.sourceRect = {
+    top: 0, left: 0, width: this.assetData.w, height: this.assetData.h,
+  };
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
+
+IImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+
+  this.innerElem = createNS('image');
+  this.innerElem.setAttribute('width', this.assetData.w + 'px');
+  this.innerElem.setAttribute('height', this.assetData.h + 'px');
+  this.innerElem.setAttribute('preserveAspectRatio', this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio);
+  this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+
+  this.layerElement.appendChild(this.innerElem);
+};
+
+IImageElement.prototype.sourceRectAtTime = function () {
+  return this.sourceRect;
+};
+
+function ProcessedElement(element, position) {
+  this.elem = element;
+  this.pos = position;
+}
+
+function IShapeElement() {
+}
+
+IShapeElement.prototype = {
+  addShapeToModifiers: function (data) {
+    var i;
+    var len = this.shapeModifiers.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapeModifiers[i].addShape(data);
+    }
+  },
+  isShapeInAnimatedModifiers: function (data) {
+    var i = 0;
+    var len = this.shapeModifiers.length;
+    while (i < len) {
+      if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
+        return true;
+      }
+    }
+    return false;
+  },
+  renderModifiers: function () {
+    if (!this.shapeModifiers.length) {
+      return;
+    }
+    var i;
+    var len = this.shapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].sh.reset();
+    }
+
+    len = this.shapeModifiers.length;
+    var shouldBreakProcess;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+      // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+      // TODO: find a better solution for this
+      if (shouldBreakProcess) {
+        break;
+      }
+    }
+  },
+
+  searchProcessedElement: function (elem) {
+    var elements = this.processedElements;
+    var i = 0;
+    var len = elements.length;
+    while (i < len) {
+      if (elements[i].elem === elem) {
+        return elements[i].pos;
+      }
+      i += 1;
+    }
+    return 0;
+  },
+  addProcessedElement: function (elem, pos) {
+    var elements = this.processedElements;
+    var i = elements.length;
+    while (i) {
+      i -= 1;
+      if (elements[i].elem === elem) {
+        elements[i].pos = pos;
+        return;
+      }
+    }
+    elements.push(new ProcessedElement(elem, pos));
+  },
+  prepareFrame: function (num) {
+    this.prepareRenderableFrame(num);
+    this.prepareProperties(num, this.isInRange);
+  },
+};
+
+const lineCapEnum = {
+  1: 'butt',
+  2: 'round',
+  3: 'square',
+};
+
+const lineJoinEnum = {
+  1: 'miter',
+  2: 'round',
+  3: 'bevel',
+};
+
+function SVGShapeData(transformers, level, shape) {
+  this.caches = [];
+  this.styles = [];
+  this.transformers = transformers;
+  this.lStr = '';
+  this.sh = shape;
+  this.lvl = level;
+  // TODO find if there are some cases where _isAnimated can be false.
+  // For now, since shapes add up with other shapes. They have to be calculated every time.
+  // One way of finding out is checking if all styles associated to this shape depend only of this shape
+  this._isAnimated = !!shape.k;
+  // TODO: commenting this for now since all shapes are animated
+  var i = 0;
+  var len = transformers.length;
+  while (i < len) {
+    if (transformers[i].mProps.dynamicProperties.length) {
+      this._isAnimated = true;
+      break;
+    }
+    i += 1;
+  }
+}
+
+SVGShapeData.prototype.setAsAnimated = function () {
+  this._isAnimated = true;
+};
+
+function SVGStyleData(data, level) {
+  this.data = data;
+  this.type = data.ty;
+  this.d = '';
+  this.lvl = level;
+  this._mdf = false;
+  this.closed = data.hd === true;
+  this.pElem = createNS('path');
+  this.msElem = null;
+}
+
+SVGStyleData.prototype.reset = function () {
+  this.d = '';
+  this._mdf = false;
+};
+
+function DashProperty(elem, data, renderer, container) {
+  this.elem = elem;
+  this.frameId = -1;
+  this.dataProps = createSizedArray(data.length);
+  this.renderer = renderer;
+  this.k = false;
+  this.dashStr = '';
+  this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0);
+  this.dashoffset = createTypedArray('float32', 1);
+  this.initDynamicPropertyContainer(container);
+  var i;
+  var len = data.length || 0;
+  var prop;
+  for (i = 0; i < len; i += 1) {
+    prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
+    this.k = prop.k || this.k;
+    this.dataProps[i] = { n: data[i].n, p: prop };
+  }
+  if (!this.k) {
+    this.getValue(true);
+  }
+  this._isAnimated = this.k;
+}
+
+DashProperty.prototype.getValue = function (forceRender) {
+  if (this.elem.globalData.frameId === this.frameId && !forceRender) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+  this._mdf = this._mdf || forceRender;
+  if (this._mdf) {
+    var i = 0;
+    var len = this.dataProps.length;
+    if (this.renderer === 'svg') {
+      this.dashStr = '';
+    }
+    for (i = 0; i < len; i += 1) {
+      if (this.dataProps[i].n !== 'o') {
+        if (this.renderer === 'svg') {
+          this.dashStr += ' ' + this.dataProps[i].p.v;
+        } else {
+          this.dashArray[i] = this.dataProps[i].p.v;
+        }
+      } else {
+        this.dashoffset[0] = this.dataProps[i].p.v;
+      }
+    }
+  }
+};
+extendPrototype([DynamicPropertyContainer], DashProperty);
+
+function SVGStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
+
+function SVGFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
+
+function SVGNoStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
+
+function GradientProperty(elem, data, container) {
+  this.data = data;
+  this.c = createTypedArray('uint8c', data.p * 4);
+  var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p * 4) : data.k.k.length - data.p * 4;
+  this.o = createTypedArray('float32', cLength);
+  this._cmdf = false;
+  this._omdf = false;
+  this._collapsable = this.checkCollapsable();
+  this._hasOpacity = cLength;
+  this.initDynamicPropertyContainer(container);
+  this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this);
+  this.k = this.prop.k;
+  this.getValue(true);
+}
+
+GradientProperty.prototype.comparePoints = function (values, points) {
+  var i = 0;
+  var len = this.o.length / 2;
+  var diff;
+  while (i < len) {
+    diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
+    if (diff > 0.01) {
+      return false;
+    }
+    i += 1;
+  }
+  return true;
+};
+
+GradientProperty.prototype.checkCollapsable = function () {
+  if (this.o.length / 2 !== this.c.length / 4) {
+    return false;
+  }
+  if (this.data.k.k[0].s) {
+    var i = 0;
+    var len = this.data.k.k.length;
+    while (i < len) {
+      if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
+        return false;
+      }
+      i += 1;
+    }
+  } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
+    return false;
+  }
+  return true;
+};
+
+GradientProperty.prototype.getValue = function (forceRender) {
+  this.prop.getValue();
+  this._mdf = false;
+  this._cmdf = false;
+  this._omdf = false;
+  if (this.prop._mdf || forceRender) {
+    var i;
+    var len = this.data.p * 4;
+    var mult;
+    var val;
+    for (i = 0; i < len; i += 1) {
+      mult = i % 4 === 0 ? 100 : 255;
+      val = Math.round(this.prop.v[i] * mult);
+      if (this.c[i] !== val) {
+        this.c[i] = val;
+        this._cmdf = !forceRender;
+      }
+    }
+    if (this.o.length) {
+      len = this.prop.v.length;
+      for (i = this.data.p * 4; i < len; i += 1) {
+        mult = i % 2 === 0 ? 100 : 1;
+        val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
+        if (this.o[i - this.data.p * 4] !== val) {
+          this.o[i - this.data.p * 4] = val;
+          this._omdf = !forceRender;
+        }
+      }
+    }
+    this._mdf = !forceRender;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], GradientProperty);
+
+function SVGGradientFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.initGradientData(elem, data, styleOb);
+}
+
+SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 1, null, this);
+  this.h = PropertyFactory.getProp(elem, data.h || { k: 0 }, 0, 0.01, this);
+  this.a = PropertyFactory.getProp(elem, data.a || { k: 0 }, 0, degToRads, this);
+  this.g = new GradientProperty(elem, data.g, this);
+  this.style = styleOb;
+  this.stops = [];
+  this.setGradientData(styleOb.pElem, data);
+  this.setGradientOpacity(data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+};
+
+SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
+  var gradientId = createElementID();
+  var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+  gfill.setAttribute('id', gradientId);
+  gfill.setAttribute('spreadMethod', 'pad');
+  gfill.setAttribute('gradientUnits', 'userSpaceOnUse');
+  var stops = [];
+  var stop;
+  var j;
+  var jLen;
+  jLen = data.g.p * 4;
+  for (j = 0; j < jLen; j += 4) {
+    stop = createNS('stop');
+    gfill.appendChild(stop);
+    stops.push(stop);
+  }
+  pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
+  this.gf = gfill;
+  this.cst = stops;
+};
+
+SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
+  if (this.g._hasOpacity && !this.g._collapsable) {
+    var stop;
+    var j;
+    var jLen;
+    var mask = createNS('mask');
+    var maskElement = createNS('path');
+    mask.appendChild(maskElement);
+    var opacityId = createElementID();
+    var maskId = createElementID();
+    mask.setAttribute('id', maskId);
+    var opFill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+    opFill.setAttribute('id', opacityId);
+    opFill.setAttribute('spreadMethod', 'pad');
+    opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
+    jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
+    var stops = this.stops;
+    for (j = data.g.p * 4; j < jLen; j += 2) {
+      stop = createNS('stop');
+      stop.setAttribute('stop-color', 'rgb(255,255,255)');
+      opFill.appendChild(stop);
+      stops.push(stop);
+    }
+    maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
+    this.maskId = maskId;
+    styleOb.msElem = maskElement;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
+
+function SVGGradientStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.initGradientData(elem, data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
+
+function ShapeGroupData() {
+  this.it = [];
+  this.prevViewData = [];
+  this.gr = createNS('g');
+}
+
+function SVGTransformData(mProps, op, container) {
+  this.transform = {
+    mProps: mProps,
+    op: op,
+    container: container,
+  };
+  this.elements = [];
+  this._isAnimated = this.transform.mProps.dynamicProperties.length || this.transform.op.effectsSequence.length;
+}
+
+const buildShapeString = function (pathNodes, length, closed, mat) {
+  if (length === 0) {
+    return '';
+  }
+  var _o = pathNodes.o;
+  var _i = pathNodes.i;
+  var _v = pathNodes.v;
+  var i;
+  var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+  for (i = 1; i < length; i += 1) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
+  }
+  if (closed && length) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+    shapeString += 'z';
+  }
+  return shapeString;
+};
+
+const SVGElementsRenderer = (function () {
+  var _identityMatrix = new Matrix();
+  var _matrixHelper = new Matrix();
+
+  var ob = {
+    createRenderFunction: createRenderFunction,
+  };
+
+  function createRenderFunction(data) {
+    switch (data.ty) {
+      case 'fl':
+        return renderFill;
+      case 'gf':
+        return renderGradient;
+      case 'gs':
+        return renderGradientStroke;
+      case 'st':
+        return renderStroke;
+      case 'sh':
+      case 'el':
+      case 'rc':
+      case 'sr':
+        return renderPath;
+      case 'tr':
+        return renderContentTransform;
+      case 'no':
+        return renderNoop;
+      default:
+        return null;
+    }
+  }
+
+  function renderContentTransform(styleData, itemData, isFirstFrame) {
+    if (isFirstFrame || itemData.transform.op._mdf) {
+      itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
+    }
+    if (isFirstFrame || itemData.transform.mProps._mdf) {
+      itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
+    }
+  }
+
+  function renderNoop() {
+
+  }
+
+  function renderPath(styleData, itemData, isFirstFrame) {
+    var j;
+    var jLen;
+    var pathStringTransformed;
+    var redraw;
+    var pathNodes;
+    var l;
+    var lLen = itemData.styles.length;
+    var lvl = itemData.lvl;
+    var paths;
+    var mat;
+    var iterations;
+    var k;
+    for (l = 0; l < lLen; l += 1) {
+      redraw = itemData.sh._mdf || isFirstFrame;
+      if (itemData.styles[l].lvl < lvl) {
+        mat = _matrixHelper.reset();
+        iterations = lvl - itemData.styles[l].lvl;
+        k = itemData.transformers.length - 1;
+        while (!redraw && iterations > 0) {
+          redraw = itemData.transformers[k].mProps._mdf || redraw;
+          iterations -= 1;
+          k -= 1;
+        }
+        if (redraw) {
+          iterations = lvl - itemData.styles[l].lvl;
+          k = itemData.transformers.length - 1;
+          while (iterations > 0) {
+            mat.multiply(itemData.transformers[k].mProps.v);
+            iterations -= 1;
+            k -= 1;
+          }
+        }
+      } else {
+        mat = _identityMatrix;
+      }
+      paths = itemData.sh.paths;
+      jLen = paths._length;
+      if (redraw) {
+        pathStringTransformed = '';
+        for (j = 0; j < jLen; j += 1) {
+          pathNodes = paths.shapes[j];
+          if (pathNodes && pathNodes._length) {
+            pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
+          }
+        }
+        itemData.caches[l] = pathStringTransformed;
+      } else {
+        pathStringTransformed = itemData.caches[l];
+      }
+      itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
+      itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
+    }
+  }
+
+  function renderFill(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+
+    if (itemData.c._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
+    }
+  }
+
+  function renderGradientStroke(styleData, itemData, isFirstFrame) {
+    renderGradient(styleData, itemData, isFirstFrame);
+    renderStroke(styleData, itemData, isFirstFrame);
+  }
+
+  function renderGradient(styleData, itemData, isFirstFrame) {
+    var gfill = itemData.gf;
+    var hasOpacity = itemData.g._hasOpacity;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+
+    if (itemData.o._mdf || isFirstFrame) {
+      var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
+      itemData.style.pElem.setAttribute(attr, itemData.o.v);
+    }
+    if (itemData.s._mdf || isFirstFrame) {
+      var attr1 = styleData.t === 1 ? 'x1' : 'cx';
+      var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
+      gfill.setAttribute(attr1, pt1[0]);
+      gfill.setAttribute(attr2, pt1[1]);
+      if (hasOpacity && !itemData.g._collapsable) {
+        itemData.of.setAttribute(attr1, pt1[0]);
+        itemData.of.setAttribute(attr2, pt1[1]);
+      }
+    }
+    var stops;
+    var i;
+    var len;
+    var stop;
+    if (itemData.g._cmdf || isFirstFrame) {
+      stops = itemData.cst;
+      var cValues = itemData.g.c;
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        stop.setAttribute('offset', cValues[i * 4] + '%');
+        stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
+      }
+    }
+    if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
+      var oValues = itemData.g.o;
+      if (itemData.g._collapsable) {
+        stops = itemData.cst;
+      } else {
+        stops = itemData.ost;
+      }
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        if (!itemData.g._collapsable) {
+          stop.setAttribute('offset', oValues[i * 2] + '%');
+        }
+        stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
+      }
+    }
+    if (styleData.t === 1) {
+      if (itemData.e._mdf || isFirstFrame) {
+        gfill.setAttribute('x2', pt2[0]);
+        gfill.setAttribute('y2', pt2[1]);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('x2', pt2[0]);
+          itemData.of.setAttribute('y2', pt2[1]);
+        }
+      }
+    } else {
+      var rad;
+      if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
+        rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        gfill.setAttribute('r', rad);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('r', rad);
+        }
+      }
+      if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (!rad) {
+          rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        }
+        var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+        var percent = itemData.h.v;
+        if (percent >= 1) {
+          percent = 0.99;
+        } else if (percent <= -1) {
+          percent = -0.99;
+        }
+        var dist = rad * percent;
+        var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+        var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+        gfill.setAttribute('fx', x);
+        gfill.setAttribute('fy', y);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('fx', x);
+          itemData.of.setAttribute('fy', y);
+        }
+      }
+      // gfill.setAttribute('fy','200');
+    }
+  }
+
+  function renderStroke(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+    var d = itemData.d;
+    if (d && (d._mdf || isFirstFrame) && d.dashStr) {
+      styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
+      styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
+    }
+    if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
+      styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
+    }
+    if (itemData.w._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
+      if (styleElem.msElem) {
+        styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
+      }
+    }
+  }
+
+  return ob;
+}());
+
+function SVGShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
+
+SVGShapeElement.prototype.initSecondaryElement = function () {
+};
+
+SVGShapeElement.prototype.identityMatrix = new Matrix();
+
+SVGShapeElement.prototype.buildExpressionInterface = function () {};
+
+SVGShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+};
+
+/*
+This method searches for multiple shapes that affect a single element and one of them is animated
+*/
+SVGShapeElement.prototype.filterUniqueShapes = function () {
+  var i;
+  var len = this.shapes.length;
+  var shape;
+  var j;
+  var jLen = this.stylesList.length;
+  var style;
+  var tempShapes = [];
+  var areAnimated = false;
+  for (j = 0; j < jLen; j += 1) {
+    style = this.stylesList[j];
+    areAnimated = false;
+    tempShapes.length = 0;
+    for (i = 0; i < len; i += 1) {
+      shape = this.shapes[i];
+      if (shape.styles.indexOf(style) !== -1) {
+        tempShapes.push(shape);
+        areAnimated = shape._isAnimated || areAnimated;
+      }
+    }
+    if (tempShapes.length > 1 && areAnimated) {
+      this.setShapesAsAnimated(tempShapes);
+    }
+  }
+};
+
+SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
+  var i;
+  var len = shapes.length;
+  for (i = 0; i < len; i += 1) {
+    shapes[i].setAsAnimated();
+  }
+};
+
+SVGShapeElement.prototype.createStyleElement = function (data, level) {
+  // TODO: prevent drawing of hidden styles
+  var elementData;
+  var styleOb = new SVGStyleData(data, level);
+
+  var pathElement = styleOb.pElem;
+  if (data.ty === 'st') {
+    elementData = new SVGStrokeStyleData(this, data, styleOb);
+  } else if (data.ty === 'fl') {
+    elementData = new SVGFillStyleData(this, data, styleOb);
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
+    elementData = new GradientConstructor(this, data, styleOb);
+    this.globalData.defs.appendChild(elementData.gf);
+    if (elementData.maskId) {
+      this.globalData.defs.appendChild(elementData.ms);
+      this.globalData.defs.appendChild(elementData.of);
+      pathElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + elementData.maskId + ')');
+    }
+  } else if (data.ty === 'no') {
+    elementData = new SVGNoStyleData(this, data, styleOb);
+  }
+
+  if (data.ty === 'st' || data.ty === 'gs') {
+    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);
+    }
+  }
+
+  if (data.r === 2) {
+    pathElement.setAttribute('fill-rule', 'evenodd');
+  }
+
+  if (data.ln) {
+    pathElement.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    pathElement.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  this.stylesList.push(styleOb);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createGroupElement = function (data) {
+  var elementData = new ShapeGroupData();
+  if (data.ln) {
+    elementData.gr.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    elementData.gr.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  return elementData;
+};
+
+SVGShapeElement.prototype.createTransformElement = function (data, container) {
+  var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
+  var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
+  var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
+  var i = 0;
+  var len = this.animatedContents.length;
+  while (i < len) {
+    if (this.animatedContents[i].element === element) {
+      return;
+    }
+    i += 1;
+  }
+  this.animatedContents.push({
+    fn: SVGElementsRenderer.createRenderFunction(data),
+    element: element,
+    data: data,
+  });
+};
+
+SVGShapeElement.prototype.setElementStyles = function (elementData) {
+  var arr = elementData.styles;
+  var j;
+  var jLen = this.stylesList.length;
+  for (j = 0; j < jLen; j += 1) {
+    if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
+      arr.push(this.stylesList[j]);
+    }
+  }
+};
+
+SVGShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+};
+
+SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
+  var ownTransformers = [].concat(transformers);
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var currentTransform;
+  var modifier;
+  var processedPos;
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._render = render;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], level);
+      } else {
+        itemsData[i].style.closed = arr[i].hd;
+      }
+      if (arr[i]._render) {
+        if (itemsData[i].style.pElem.parentNode !== container) {
+          container.appendChild(itemsData[i].style.pElem);
+        }
+      }
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
+      if (arr[i]._render) {
+        if (itemsData[i].gr.parentNode !== container) {
+          container.appendChild(itemsData[i].gr);
+        }
+      }
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        itemsData[i] = this.createTransformElement(arr[i], container);
+      }
+      currentTransform = itemsData[i].transform;
+      ownTransformers.push(currentTransform);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
+      }
+      this.setElementStyles(itemsData[i]);
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        render = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  len = ownStyles.length;
+  for (i = 0; i < len; i += 1) {
+    ownStyles[i].closed = true;
+  }
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+SVGShapeElement.prototype.renderInnerContent = function () {
+  this.renderModifiers();
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    this.stylesList[i].reset();
+  }
+  this.renderShape();
+  for (i = 0; i < len; i += 1) {
+    if (this.stylesList[i]._mdf || this._isFirstFrame) {
+      if (this.stylesList[i].msElem) {
+        this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+        // Adding M0 0 fixes same mask bug on all browsers
+        this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
+      }
+      this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
+    }
+  }
+};
+
+SVGShapeElement.prototype.renderShape = function () {
+  var i;
+  var len = this.animatedContents.length;
+  var animatedContent;
+  for (i = 0; i < len; i += 1) {
+    animatedContent = this.animatedContents[i];
+    if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
+      animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
+    }
+  }
+};
+
+SVGShapeElement.prototype.destroy = function () {
+  this.destroyBaseElement();
+  this.shapesData = null;
+  this.itemsData = null;
+};
+
+function LetterProps(o, sw, sc, fc, m, p) {
+  this.o = o;
+  this.sw = sw;
+  this.sc = sc;
+  this.fc = fc;
+  this.m = m;
+  this.p = p;
+  this._mdf = {
+    o: true,
+    sw: !!sw,
+    sc: !!sc,
+    fc: !!fc,
+    m: true,
+    p: true,
+  };
+}
+
+LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
+  this._mdf.o = false;
+  this._mdf.sw = false;
+  this._mdf.sc = false;
+  this._mdf.fc = false;
+  this._mdf.m = false;
+  this._mdf.p = false;
+  var updated = false;
+
+  if (this.o !== o) {
+    this.o = o;
+    this._mdf.o = true;
+    updated = true;
+  }
+  if (this.sw !== sw) {
+    this.sw = sw;
+    this._mdf.sw = true;
+    updated = true;
+  }
+  if (this.sc !== sc) {
+    this.sc = sc;
+    this._mdf.sc = true;
+    updated = true;
+  }
+  if (this.fc !== fc) {
+    this.fc = fc;
+    this._mdf.fc = true;
+    updated = true;
+  }
+  if (this.m !== m) {
+    this.m = m;
+    this._mdf.m = true;
+    updated = true;
+  }
+  if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
+    this.p = p;
+    this._mdf.p = true;
+    updated = true;
+  }
+  return updated;
+};
+
+function TextProperty(elem, data) {
+  this._frameId = initialDefaultFrame;
+  this.pv = '';
+  this.v = '';
+  this.kf = false;
+  this._isFirstFrame = true;
+  this._mdf = false;
+  if (data.d && data.d.sid) {
+    data.d = elem.globalData.slotManager.getProp(data.d);
+  }
+  this.data = data;
+  this.elem = elem;
+  this.comp = this.elem.comp;
+  this.keysIndex = 0;
+  this.canResize = false;
+  this.minimumFontSize = 1;
+  this.effectsSequence = [];
+  this.currentData = {
+    ascent: 0,
+    boxWidth: this.defaultBoxWidth,
+    f: '',
+    fStyle: '',
+    fWeight: '',
+    fc: '',
+    j: '',
+    justifyOffset: '',
+    l: [],
+    lh: 0,
+    lineWidths: [],
+    ls: '',
+    of: '',
+    s: '',
+    sc: '',
+    sw: 0,
+    t: 0,
+    tr: 0,
+    sz: 0,
+    ps: null,
+    fillColorAnim: false,
+    strokeColorAnim: false,
+    strokeWidthAnim: false,
+    yOffset: 0,
+    finalSize: 0,
+    finalText: [],
+    finalLineHeight: 0,
+    __complete: false,
+
+  };
+  this.copyData(this.currentData, this.data.d.k[0].s);
+
+  if (!this.searchProperty()) {
+    this.completeTextData(this.currentData);
+  }
+}
+
+TextProperty.prototype.defaultBoxWidth = [0, 0];
+
+TextProperty.prototype.copyData = function (obj, data) {
+  for (var s in data) {
+    if (Object.prototype.hasOwnProperty.call(data, s)) {
+      obj[s] = data[s];
+    }
+  }
+  return obj;
+};
+
+TextProperty.prototype.setCurrentData = function (data) {
+  if (!data.__complete) {
+    this.completeTextData(data);
+  }
+  this.currentData = data;
+  this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
+  this._mdf = true;
+};
+
+TextProperty.prototype.searchProperty = function () {
+  return this.searchKeyframes();
+};
+
+TextProperty.prototype.searchKeyframes = function () {
+  this.kf = this.data.d.k.length > 1;
+  if (this.kf) {
+    this.addEffect(this.getKeyframeValue.bind(this));
+  }
+  return this.kf;
+};
+
+TextProperty.prototype.addEffect = function (effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.getValue = function (_finalValue) {
+  if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
+    return;
+  }
+  this.currentData.t = this.data.d.k[this.keysIndex].s.t;
+  var currentValue = this.currentData;
+  var currentIndex = this.keysIndex;
+  if (this.lock) {
+    this.setCurrentData(this.currentData);
+    return;
+  }
+  this.lock = true;
+  this._mdf = false;
+  var i; var
+    len = this.effectsSequence.length;
+  var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
+  for (i = 0; i < len; i += 1) {
+    // Checking if index changed to prevent creating a new object every time the expression updates.
+    if (currentIndex !== this.keysIndex) {
+      finalValue = this.effectsSequence[i](finalValue, finalValue.t);
+    } else {
+      finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
+    }
+  }
+  if (currentValue !== finalValue) {
+    this.setCurrentData(finalValue);
+  }
+  this.v = this.currentData;
+  this.pv = this.v;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+};
+
+TextProperty.prototype.getKeyframeValue = function () {
+  var textKeys = this.data.d.k;
+  var frameNum = this.elem.comp.renderedFrame;
+  var i = 0; var
+    len = textKeys.length;
+  while (i <= len - 1) {
+    if (i === len - 1 || textKeys[i + 1].t > frameNum) {
+      break;
+    }
+    i += 1;
+  }
+  if (this.keysIndex !== i) {
+    this.keysIndex = i;
+  }
+  return this.data.d.k[this.keysIndex].s;
+};
+
+TextProperty.prototype.buildFinalText = function (text) {
+  var charactersArray = [];
+  var i = 0;
+  var len = text.length;
+  var charCode;
+  var secondCharCode;
+  var shouldCombine = false;
+  var shouldCombineNext = false;
+  var currentChars = '';
+  while (i < len) {
+    shouldCombine = shouldCombineNext;
+    shouldCombineNext = false;
+    charCode = text.charCodeAt(i);
+    currentChars = text.charAt(i);
+    if (FontManager.isCombinedCharacter(charCode)) {
+      shouldCombine = true;
+      // It's a potential surrogate pair (this is the High surrogate)
+    } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+      if (FontManager.isRegionalFlag(text, i)) {
+        currentChars = text.substr(i, 14);
+      } else {
+        secondCharCode = text.charCodeAt(i + 1);
+        // It's a surrogate pair (this is the Low surrogate)
+        if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
+          if (FontManager.isModifier(charCode, secondCharCode)) {
+            currentChars = text.substr(i, 2);
+            shouldCombine = true;
+          } else if (FontManager.isFlagEmoji(text.substr(i, 4))) {
+            currentChars = text.substr(i, 4);
+          } else {
+            currentChars = text.substr(i, 2);
+          }
+        }
+      }
+    } else if (charCode > 0xDBFF) {
+      secondCharCode = text.charCodeAt(i + 1);
+      if (FontManager.isVariationSelector(charCode)) {
+        shouldCombine = true;
+      }
+    } else if (FontManager.isZeroWidthJoiner(charCode)) {
+      shouldCombine = true;
+      shouldCombineNext = true;
+    }
+    if (shouldCombine) {
+      charactersArray[charactersArray.length - 1] += currentChars;
+      shouldCombine = false;
+    } else {
+      charactersArray.push(currentChars);
+    }
+    i += currentChars.length;
+  }
+  return charactersArray;
+};
+
+TextProperty.prototype.completeTextData = function (documentData) {
+  documentData.__complete = true;
+  var fontManager = this.elem.globalData.fontManager;
+  var data = this.data;
+  var letters = [];
+  var i; var
+    len;
+  var newLineFlag; var index = 0; var
+    val;
+  var anchorGrouping = data.m.g;
+  var currentSize = 0; var currentPos = 0; var currentLine = 0; var
+    lineWidths = [];
+  var lineWidth = 0;
+  var maxLineWidth = 0;
+  var j; var
+    jLen;
+  var fontData = fontManager.getFontByName(documentData.f);
+  var charData; var
+    cLength = 0;
+
+  var fontProps = getFontProperties(fontData);
+  documentData.fWeight = fontProps.weight;
+  documentData.fStyle = fontProps.style;
+  documentData.finalSize = documentData.s;
+  documentData.finalText = this.buildFinalText(documentData.t);
+  len = documentData.finalText.length;
+  documentData.finalLineHeight = documentData.lh;
+  var trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+  var charCode;
+  if (documentData.sz) {
+    var flag = true;
+    var boxWidth = documentData.sz[0];
+    var boxHeight = documentData.sz[1];
+    var currentHeight; var
+      finalText;
+    while (flag) {
+      finalText = this.buildFinalText(documentData.t);
+      currentHeight = 0;
+      lineWidth = 0;
+      len = finalText.length;
+      trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+      var lastSpaceIndex = -1;
+      for (i = 0; i < len; i += 1) {
+        charCode = finalText[i].charCodeAt(0);
+        newLineFlag = false;
+        if (finalText[i] === ' ') {
+          lastSpaceIndex = i;
+        } else if (charCode === 13 || charCode === 3) {
+          lineWidth = 0;
+          newLineFlag = true;
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+        }
+        if (fontManager.chars) {
+          charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
+          cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+        } else {
+          // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
+          cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
+        }
+        if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
+          if (lastSpaceIndex === -1) {
+            len += 1;
+          } else {
+            i = lastSpaceIndex;
+          }
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+          finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+          // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
+          lastSpaceIndex = -1;
+          lineWidth = 0;
+        } else {
+          lineWidth += cLength;
+          lineWidth += trackingOffset;
+        }
+      }
+      currentHeight += (fontData.ascent * documentData.finalSize) / 100;
+      if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
+        documentData.finalSize -= 1;
+        documentData.finalLineHeight = (documentData.finalSize * documentData.lh) / documentData.s;
+      } else {
+        documentData.finalText = finalText;
+        len = documentData.finalText.length;
+        flag = false;
+      }
+    }
+  }
+  lineWidth = -trackingOffset;
+  cLength = 0;
+  var uncollapsedSpaces = 0;
+  var currentChar;
+  for (i = 0; i < len; i += 1) {
+    newLineFlag = false;
+    currentChar = documentData.finalText[i];
+    charCode = currentChar.charCodeAt(0);
+    if (charCode === 13 || charCode === 3) {
+      uncollapsedSpaces = 0;
+      lineWidths.push(lineWidth);
+      maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+      lineWidth = -2 * trackingOffset;
+      val = '';
+      newLineFlag = true;
+      currentLine += 1;
+    } else {
+      val = currentChar;
+    }
+    if (fontManager.chars) {
+      charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
+      cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+    } else {
+      // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
+      // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
+      cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
+    }
+
+    //
+    if (currentChar === ' ') {
+      uncollapsedSpaces += cLength + trackingOffset;
+    } else {
+      lineWidth += cLength + trackingOffset + uncollapsedSpaces;
+      uncollapsedSpaces = 0;
+    }
+    letters.push({
+      l: cLength, an: cLength, add: currentSize, n: newLineFlag, anIndexes: [], val: val, line: currentLine, animatorJustifyOffset: 0,
+    });
+    if (anchorGrouping == 2) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || val === ' ' || i === len - 1) {
+        if (val === '' || val === ' ') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        index += 1;
+        currentSize = 0;
+      }
+    } else if (anchorGrouping == 3) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || i === len - 1) {
+        if (val === '') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        currentSize = 0;
+        index += 1;
+      }
+    } else {
+      letters[index].ind = index;
+      letters[index].extra = 0;
+      index += 1;
+    }
+  }
+  documentData.l = letters;
+  maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+  lineWidths.push(lineWidth);
+  if (documentData.sz) {
+    documentData.boxWidth = documentData.sz[0];
+    documentData.justifyOffset = 0;
+  } else {
+    documentData.boxWidth = maxLineWidth;
+    switch (documentData.j) {
+      case 1:
+        documentData.justifyOffset = -documentData.boxWidth;
+        break;
+      case 2:
+        documentData.justifyOffset = -documentData.boxWidth / 2;
+        break;
+      default:
+        documentData.justifyOffset = 0;
+    }
+  }
+  documentData.lineWidths = lineWidths;
+
+  var animators = data.a; var animatorData; var
+    letterData;
+  jLen = animators.length;
+  var based; var ind; var
+    indexes = [];
+  for (j = 0; j < jLen; j += 1) {
+    animatorData = animators[j];
+    if (animatorData.a.sc) {
+      documentData.strokeColorAnim = true;
+    }
+    if (animatorData.a.sw) {
+      documentData.strokeWidthAnim = true;
+    }
+    if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
+      documentData.fillColorAnim = true;
+    }
+    ind = 0;
+    based = animatorData.s.b;
+    for (i = 0; i < len; i += 1) {
+      letterData = letters[i];
+      letterData.anIndexes[j] = ind;
+      if ((based == 1 && letterData.val !== '') || (based == 2 && letterData.val !== '' && letterData.val !== ' ') || (based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1)) || (based == 4 && (letterData.n || i == len - 1))) { // eslint-disable-line eqeqeq
+        if (animatorData.s.rn === 1) {
+          indexes.push(ind);
+        }
+        ind += 1;
+      }
+    }
+    data.a[j].s.totalChars = ind;
+    var currentInd = -1; var
+      newInd;
+    if (animatorData.s.rn === 1) {
+      for (i = 0; i < len; i += 1) {
+        letterData = letters[i];
+        if (currentInd != letterData.anIndexes[j]) { // eslint-disable-line eqeqeq
+          currentInd = letterData.anIndexes[j];
+          newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
+        }
+        letterData.anIndexes[j] = newInd;
+      }
+    }
+  }
+  documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
+  documentData.ls = documentData.ls || 0;
+  documentData.ascent = (fontData.ascent * documentData.finalSize) / 100;
+};
+
+TextProperty.prototype.updateDocumentData = function (newData, index) {
+  index = index === undefined ? this.keysIndex : index;
+  var dData = this.copyData({}, this.data.d.k[index].s);
+  dData = this.copyData(dData, newData);
+  this.data.d.k[index].s = dData;
+  this.recalculate(index);
+  this.setCurrentData(dData);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.recalculate = function (index) {
+  var dData = this.data.d.k[index].s;
+  dData.__complete = false;
+  this.keysIndex = 0;
+  this._isFirstFrame = true;
+  this.getValue(dData);
+};
+
+TextProperty.prototype.canResizeFont = function (_canResize) {
+  this.canResize = _canResize;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
+  this.minimumFontSize = Math.floor(_fontValue) || 1;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+const TextSelectorProp = (function () {
+  var max = Math.max;
+  var min = Math.min;
+  var floor = Math.floor;
+
+  function TextSelectorPropFactory(elem, data) {
+    this._currentTextLength = -1;
+    this.k = false;
+    this.data = data;
+    this.elem = elem;
+    this.comp = elem.comp;
+    this.finalS = 0;
+    this.finalE = 0;
+    this.initDynamicPropertyContainer(elem);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: 0 }, 0, 0, this);
+    if ('e' in data) {
+      this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
+    } else {
+      this.e = { v: 100 };
+    }
+    this.o = PropertyFactory.getProp(elem, data.o || { k: 0 }, 0, 0, this);
+    this.xe = PropertyFactory.getProp(elem, data.xe || { k: 0 }, 0, 0, this);
+    this.ne = PropertyFactory.getProp(elem, data.ne || { k: 0 }, 0, 0, this);
+    this.sm = PropertyFactory.getProp(elem, data.sm || { k: 100 }, 0, 0, this);
+    this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
+    if (!this.dynamicProperties.length) {
+      this.getValue();
+    }
+  }
+
+  TextSelectorPropFactory.prototype = {
+    getMult: function (ind) {
+      if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
+        this.getValue();
+      }
+      var x1 = 0;
+      var y1 = 0;
+      var x2 = 1;
+      var y2 = 1;
+      if (this.ne.v > 0) {
+        x1 = this.ne.v / 100.0;
+      } else {
+        y1 = -this.ne.v / 100.0;
+      }
+      if (this.xe.v > 0) {
+        x2 = 1.0 - this.xe.v / 100.0;
+      } else {
+        y2 = 1.0 + this.xe.v / 100.0;
+      }
+      var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
+
+      var mult = 0;
+      var s = this.finalS;
+      var e = this.finalE;
+      var type = this.data.sh;
+      if (type === 2) {
+        if (e === s) {
+          mult = ind >= e ? 1 : 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+        mult = easer(mult);
+      } else if (type === 3) {
+        if (e === s) {
+          mult = ind >= e ? 0 : 1;
+        } else {
+          mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+
+        mult = easer(mult);
+      } else if (type === 4) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+          if (mult < 0.5) {
+            mult *= 2;
+          } else {
+            mult = 1 - 2 * (mult - 0.5);
+          }
+        }
+        mult = easer(mult);
+      } else if (type === 5) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          var tot = e - s;
+          /* ind += 0.5;
+                    mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          var x = -tot / 2 + ind;
+          var a = tot / 2;
+          mult = Math.sqrt(1 - (x * x) / (a * a));
+        }
+        mult = easer(mult);
+      } else if (type === 6) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; // eslint-disable-line
+        }
+        mult = easer(mult);
+      } else {
+        if (ind >= floor(s)) {
+          if (ind - s < 0) {
+            mult = max(0, min(min(e, 1) - (s - ind), 1));
+          } else {
+            mult = max(0, min(e - ind, 1));
+          }
+        }
+        mult = easer(mult);
+      }
+      // Smoothness implementation.
+      // The smoothness represents a reduced range of the original [0; 1] range.
+      // if smoothness is 25%, the new range will be [0.375; 0.625]
+      // Steps are:
+      // - find the lower value of the new range (threshold)
+      // - if multiplier is smaller than that value, floor it to 0
+      // - if it is larger,
+      //     - subtract the threshold
+      //     - divide it by the smoothness (this will return the range to [0; 1])
+      // Note: If it doesn't work on some scenarios, consider applying it before the easer.
+      if (this.sm.v !== 100) {
+        var smoothness = this.sm.v * 0.01;
+        if (smoothness === 0) {
+          smoothness = 0.00000001;
+        }
+        var threshold = 0.5 - smoothness * 0.5;
+        if (mult < threshold) {
+          mult = 0;
+        } else {
+          mult = (mult - threshold) / smoothness;
+          if (mult > 1) {
+            mult = 1;
+          }
+        }
+      }
+      return mult * this.a.v;
+    },
+    getValue: function (newCharsFlag) {
+      this.iterateDynamicProperties();
+      this._mdf = newCharsFlag || this._mdf;
+      this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
+      if (newCharsFlag && this.data.r === 2) {
+        this.e.v = this._currentTextLength;
+      }
+      var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
+      var o = this.o.v / divisor;
+      var s = this.s.v / divisor + o;
+      var e = (this.e.v / divisor) + o;
+      if (s > e) {
+        var _s = s;
+        s = e;
+        e = _s;
+      }
+      this.finalS = s;
+      this.finalE = e;
+    },
+  };
+  extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
+
+  function getTextSelectorProp(elem, data, arr) {
+    return new TextSelectorPropFactory(elem, data, arr);
+  }
+
+  return {
+    getTextSelectorProp: getTextSelectorProp,
+  };
+}());
+
+function TextAnimatorDataProperty(elem, animatorProps, container) {
+  var defaultData = { propType: false };
+  var getProp = PropertyFactory.getProp;
+  var textAnimatorAnimatables = animatorProps.a;
+  this.a = {
+    r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData,
+    rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData,
+    ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData,
+    sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData,
+    sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData,
+    s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData,
+    a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData,
+    o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData,
+    p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData,
+    sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData,
+    sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData,
+    fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData,
+    fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData,
+    fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData,
+    fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData,
+    t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData,
+  };
+
+  this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container);
+  this.s.t = animatorProps.s.t;
+}
+
+function TextAnimatorProperty(textData, renderType, elem) {
+  this._isFirstFrame = true;
+  this._hasMaskedPath = false;
+  this._frameId = -1;
+  this._textData = textData;
+  this._renderType = renderType;
+  this._elem = elem;
+  this._animatorsData = createSizedArray(this._textData.a.length);
+  this._pathData = {};
+  this._moreOptions = {
+    alignment: {},
+  };
+  this.renderedLetters = [];
+  this.lettersChangedFlag = false;
+  this.initDynamicPropertyContainer(elem);
+}
+
+TextAnimatorProperty.prototype.searchProperties = function () {
+  var i;
+  var len = this._textData.a.length;
+  var animatorProps;
+  var getProp = PropertyFactory.getProp;
+  for (i = 0; i < len; i += 1) {
+    animatorProps = this._textData.a[i];
+    this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
+  }
+  if (this._textData.p && 'm' in this._textData.p) {
+    this._pathData = {
+      a: getProp(this._elem, this._textData.p.a, 0, 0, this),
+      f: getProp(this._elem, this._textData.p.f, 0, 0, this),
+      l: getProp(this._elem, this._textData.p.l, 0, 0, this),
+      r: getProp(this._elem, this._textData.p.r, 0, 0, this),
+      p: getProp(this._elem, this._textData.p.p, 0, 0, this),
+      m: this._elem.maskManager.getMaskProperty(this._textData.p.m),
+    };
+    this._hasMaskedPath = true;
+  } else {
+    this._hasMaskedPath = false;
+  }
+  this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
+};
+
+TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
+  this.lettersChangedFlag = lettersChangedFlag;
+  if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
+    return;
+  }
+  this._isFirstFrame = false;
+  var alignment = this._moreOptions.alignment.v;
+  var animators = this._animatorsData;
+  var textData = this._textData;
+  var matrixHelper = this.mHelper;
+  var renderType = this._renderType;
+  var renderedLettersCount = this.renderedLetters.length;
+  var xPos;
+  var yPos;
+  var i;
+  var len;
+  var letters = documentData.l;
+  var pathInfo;
+  var currentLength;
+  var currentPoint;
+  var segmentLength;
+  var flag;
+  var pointInd;
+  var segmentInd;
+  var prevPoint;
+  var points;
+  var segments;
+  var partialLength;
+  var totalLength;
+  var perc;
+  var tanAngle;
+  var mask;
+  if (this._hasMaskedPath) {
+    mask = this._pathData.m;
+    if (!this._pathData.n || this._pathData._mdf) {
+      var paths = mask.v;
+      if (this._pathData.r.v) {
+        paths = paths.reverse();
+      }
+      // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
+      pathInfo = {
+        tLength: 0,
+        segments: [],
+      };
+      len = paths._length - 1;
+      var bezierData;
+      totalLength = 0;
+      for (i = 0; i < len; i += 1) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[i + 1],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      i = len;
+      if (mask.v.c) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[0],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      this._pathData.pi = pathInfo;
+    }
+    pathInfo = this._pathData.pi;
+
+    currentLength = this._pathData.f.v;
+    segmentInd = 0;
+    pointInd = 1;
+    segmentLength = 0;
+    flag = true;
+    segments = pathInfo.segments;
+    if (currentLength < 0 && mask.v.c) {
+      if (pathInfo.tLength < Math.abs(currentLength)) {
+        currentLength = -Math.abs(currentLength) % pathInfo.tLength;
+      }
+      segmentInd = segments.length - 1;
+      points = segments[segmentInd].points;
+      pointInd = points.length - 1;
+      while (currentLength < 0) {
+        currentLength += points[pointInd].partialLength;
+        pointInd -= 1;
+        if (pointInd < 0) {
+          segmentInd -= 1;
+          points = segments[segmentInd].points;
+          pointInd = points.length - 1;
+        }
+      }
+    }
+    points = segments[segmentInd].points;
+    prevPoint = points[pointInd - 1];
+    currentPoint = points[pointInd];
+    partialLength = currentPoint.partialLength;
+  }
+
+  len = letters.length;
+  xPos = 0;
+  yPos = 0;
+  var yOff = documentData.finalSize * 1.2 * 0.714;
+  var firstLine = true;
+  var animatorProps;
+  var animatorSelector;
+  var j;
+  var jLen;
+  var letterValue;
+
+  jLen = animators.length;
+
+  var mult;
+  var ind = -1;
+  var offf;
+  var xPathPos;
+  var yPathPos;
+  var initPathPos = currentLength;
+  var initSegmentInd = segmentInd;
+  var initPointInd = pointInd;
+  var currentLine = -1;
+  var elemOpacity;
+  var sc;
+  var sw;
+  var fc;
+  var k;
+  var letterSw;
+  var letterSc;
+  var letterFc;
+  var letterM = '';
+  var letterP = this.defaultPropsArray;
+  var letterO;
+
+  //
+  if (documentData.j === 2 || documentData.j === 1) {
+    var animatorJustifyOffset = 0;
+    var animatorFirstCharOffset = 0;
+    var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
+    var lastIndex = 0;
+    var isNewLine = true;
+
+    for (i = 0; i < len; i += 1) {
+      if (letters[i].n) {
+        if (animatorJustifyOffset) {
+          animatorJustifyOffset += animatorFirstCharOffset;
+        }
+        while (lastIndex < i) {
+          letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+          lastIndex += 1;
+        }
+        animatorJustifyOffset = 0;
+        isNewLine = true;
+      } else {
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.t.propType) {
+            if (isNewLine && documentData.j === 2) {
+              animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
+            }
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
+            } else {
+              animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult;
+            }
+          }
+        }
+        isNewLine = false;
+      }
+    }
+    if (animatorJustifyOffset) {
+      animatorJustifyOffset += animatorFirstCharOffset;
+    }
+    while (lastIndex < i) {
+      letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+      lastIndex += 1;
+    }
+  }
+  //
+
+  for (i = 0; i < len; i += 1) {
+    matrixHelper.reset();
+    elemOpacity = 1;
+    if (letters[i].n) {
+      xPos = 0;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      currentLength = initPathPos;
+      firstLine = false;
+      if (this._hasMaskedPath) {
+        segmentInd = initSegmentInd;
+        pointInd = initPointInd;
+        points = segments[segmentInd].points;
+        prevPoint = points[pointInd - 1];
+        currentPoint = points[pointInd];
+        partialLength = currentPoint.partialLength;
+        segmentLength = 0;
+      }
+      letterM = '';
+      letterFc = '';
+      letterSw = '';
+      letterO = '';
+      letterP = this.defaultPropsArray;
+    } else {
+      if (this._hasMaskedPath) {
+        if (currentLine !== letters[i].line) {
+          switch (documentData.j) {
+            case 1:
+              currentLength += totalLength - documentData.lineWidths[letters[i].line];
+              break;
+            case 2:
+              currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
+              break;
+            default:
+              break;
+          }
+          currentLine = letters[i].line;
+        }
+        if (ind !== letters[i].ind) {
+          if (letters[ind]) {
+            currentLength += letters[ind].extra;
+          }
+          currentLength += letters[i].an / 2;
+          ind = letters[i].ind;
+        }
+        currentLength += (alignment[0] * letters[i].an) * 0.005;
+        var animatorOffset = 0;
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.p.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.p.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.p.v[0] * mult;
+            }
+          }
+          if (animatorProps.a.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.a.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.a.v[0] * mult;
+            }
+          }
+        }
+        flag = true;
+        // Force alignment only works with a single line for now
+        if (this._pathData.a.v) {
+          currentLength = letters[0].an * 0.5 + ((totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind) / (len - 1);
+          currentLength += this._pathData.f.v;
+        }
+        while (flag) {
+          if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
+            perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
+            xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
+            yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
+            matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, -(alignment[1] * yOff) * 0.01);
+            flag = false;
+          } else if (points) {
+            segmentLength += currentPoint.partialLength;
+            pointInd += 1;
+            if (pointInd >= points.length) {
+              pointInd = 0;
+              segmentInd += 1;
+              if (!segments[segmentInd]) {
+                if (mask.v.c) {
+                  pointInd = 0;
+                  segmentInd = 0;
+                  points = segments[segmentInd].points;
+                } else {
+                  segmentLength -= currentPoint.partialLength;
+                  points = null;
+                }
+              } else {
+                points = segments[segmentInd].points;
+              }
+            }
+            if (points) {
+              prevPoint = currentPoint;
+              currentPoint = points[pointInd];
+              partialLength = currentPoint.partialLength;
+            }
+          }
+        }
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+      } else {
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+
+        // Grouping alignment
+        matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, (-alignment[1] * yOff) * 0.01, 0);
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.t.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
+          if (xPos !== 0 || documentData.j !== 0) {
+            if (this._hasMaskedPath) {
+              if (mult.length) {
+                currentLength += animatorProps.t.v * mult[0];
+              } else {
+                currentLength += animatorProps.t.v * mult;
+              }
+            } else if (mult.length) {
+              xPos += animatorProps.t.v * mult[0];
+            } else {
+              xPos += animatorProps.t.v * mult;
+            }
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        sw = documentData.sw || 0;
+      }
+      if (documentData.strokeColorAnim) {
+        if (documentData.sc) {
+          sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
+        } else {
+          sc = [0, 0, 0];
+        }
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.a.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+
+          if (mult.length) {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.s.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (mult.length) {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult[0]), 1 + ((animatorProps.s.v[1] - 1) * mult[1]), 1);
+          } else {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult), 1 + ((animatorProps.s.v[1] - 1) * mult), 1);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        animatorSelector = animators[j].s;
+        mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+        if (animatorProps.sk.propType) {
+          if (mult.length) {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
+          } else {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
+          }
+        }
+        if (animatorProps.r.propType) {
+          if (mult.length) {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
+          } else {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult);
+          }
+        }
+        if (animatorProps.ry.propType) {
+          if (mult.length) {
+            matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
+          } else {
+            matrixHelper.rotateY(animatorProps.ry.v * mult);
+          }
+        }
+        if (animatorProps.rx.propType) {
+          if (mult.length) {
+            matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
+          } else {
+            matrixHelper.rotateX(animatorProps.rx.v * mult);
+          }
+        }
+        if (animatorProps.o.propType) {
+          if (mult.length) {
+            elemOpacity += ((animatorProps.o.v) * mult[0] - elemOpacity) * mult[0];
+          } else {
+            elemOpacity += ((animatorProps.o.v) * mult - elemOpacity) * mult;
+          }
+        }
+        if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
+          if (mult.length) {
+            sw += animatorProps.sw.v * mult[0];
+          } else {
+            sw += animatorProps.sw.v * mult;
+          }
+        }
+        if (documentData.strokeColorAnim && animatorProps.sc.propType) {
+          for (k = 0; k < 3; k += 1) {
+            if (mult.length) {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0];
+            } else {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult;
+            }
+          }
+        }
+        if (documentData.fillColorAnim && documentData.fc) {
+          if (animatorProps.fc.propType) {
+            for (k = 0; k < 3; k += 1) {
+              if (mult.length) {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0];
+              } else {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult;
+              }
+            }
+          }
+          if (animatorProps.fh.propType) {
+            if (mult.length) {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
+            } else {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult);
+            }
+          }
+          if (animatorProps.fs.propType) {
+            if (mult.length) {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
+            } else {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
+            }
+          }
+          if (animatorProps.fb.propType) {
+            if (mult.length) {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
+            } else {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult);
+            }
+          }
+        }
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+
+        if (animatorProps.p.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (this._hasMaskedPath) {
+            if (mult.length) {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
+            } else {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+            }
+          } else if (mult.length) {
+            matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        letterSw = sw < 0 ? 0 : sw;
+      }
+      if (documentData.strokeColorAnim) {
+        letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
+      }
+
+      if (this._hasMaskedPath) {
+        matrixHelper.translate(0, -documentData.ls);
+
+        matrixHelper.translate(0, (alignment[1] * yOff) * 0.01 + yPos, 0);
+        if (this._pathData.p.v) {
+          tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
+          var rot = (Math.atan(tanAngle) * 180) / Math.PI;
+          if (currentPoint.point[0] < prevPoint.point[0]) {
+            rot += 180;
+          }
+          matrixHelper.rotate((-rot * Math.PI) / 180);
+        }
+        matrixHelper.translate(xPathPos, yPathPos, 0);
+        currentLength -= (alignment[0] * letters[i].an) * 0.005;
+        if (letters[i + 1] && ind !== letters[i + 1].ind) {
+          currentLength += letters[i].an / 2;
+          currentLength += (documentData.tr * 0.001) * documentData.finalSize;
+        }
+      } else {
+        matrixHelper.translate(xPos, yPos, 0);
+
+        if (documentData.ps) {
+          // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
+          matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+        }
+        switch (documentData.j) {
+          case 1:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
+            break;
+          case 2:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
+            break;
+          default:
+            break;
+        }
+        matrixHelper.translate(0, -documentData.ls);
+        matrixHelper.translate(offf, 0, 0);
+        matrixHelper.translate((alignment[0] * letters[i].an) * 0.005, (alignment[1] * yOff) * 0.01, 0);
+        xPos += letters[i].l + (documentData.tr * 0.001) * documentData.finalSize;
+      }
+      if (renderType === 'html') {
+        letterM = matrixHelper.toCSS();
+      } else if (renderType === 'svg') {
+        letterM = matrixHelper.to2dCSS();
+      } else {
+        letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
+      }
+      letterO = elemOpacity;
+    }
+
+    if (renderedLettersCount <= i) {
+      letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
+      this.renderedLetters.push(letterValue);
+      renderedLettersCount += 1;
+      this.lettersChangedFlag = true;
+    } else {
+      letterValue = this.renderedLetters[i];
+      this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag;
+    }
+  }
+};
+
+TextAnimatorProperty.prototype.getValue = function () {
+  if (this._elem.globalData.frameId === this._frameId) {
+    return;
+  }
+  this._frameId = this._elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+TextAnimatorProperty.prototype.mHelper = new Matrix();
+TextAnimatorProperty.prototype.defaultPropsArray = [];
+extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
+
+function ITextElement() {
+}
+
+ITextElement.prototype.initElement = function (data, globalData, comp) {
+  this.lettersChangedFlag = true;
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.textProperty = new TextProperty(this, data.t, this.dynamicProperties);
+  this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this);
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+  this.initRenderable();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  this.createContent();
+  this.hide();
+  this.textAnimator.searchProperties(this.dynamicProperties);
+};
+
+ITextElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+};
+
+ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
+  var j;
+  var jLen = shapes.length;
+  var pathNodes;
+  var shapeStr = '';
+  for (j = 0; j < jLen; j += 1) {
+    if (shapes[j].ty === 'sh') {
+      pathNodes = shapes[j].ks.k;
+      shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
+    }
+  }
+  return shapeStr;
+};
+
+ITextElement.prototype.updateDocumentData = function (newData, index) {
+  this.textProperty.updateDocumentData(newData, index);
+};
+
+ITextElement.prototype.canResizeFont = function (_canResize) {
+  this.textProperty.canResizeFont(_canResize);
+};
+
+ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
+  this.textProperty.setMinimumFontSize(_fontSize);
+};
+
+ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
+  if (documentData.ps) {
+    matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+  }
+  matrixHelper.translate(0, -documentData.ls, 0);
+  switch (documentData.j) {
+    case 1:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
+      break;
+    case 2:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
+      break;
+    default:
+      break;
+  }
+  matrixHelper.translate(xPos, yPos, 0);
+};
+
+ITextElement.prototype.buildColor = function (colorData) {
+  return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
+};
+
+ITextElement.prototype.emptyProp = new LetterProps();
+
+ITextElement.prototype.destroy = function () {
+
+};
+
+ITextElement.prototype.validateText = function () {
+  if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
+    this.buildNewText();
+    this.textProperty._isFirstFrame = false;
+    this.textProperty._mdf = false;
+  }
+};
+
+var emptyShapeData = {
+  shapes: [],
+};
+
+function SVGTextLottieElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.renderType = 'svg';
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
+
+SVGTextLottieElement.prototype.createContent = function () {
+  if (this.data.singleShape && !this.globalData.fontManager.chars) {
+    this.textContainer = createNS('text');
+  }
+};
+
+SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
+  var i = 0;
+  var len = textArray.length;
+  var textContents = [];
+  var currentTextContent = '';
+  while (i < len) {
+    if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
+      textContents.push(currentTextContent);
+      currentTextContent = '';
+    } else {
+      currentTextContent += textArray[i];
+    }
+    i += 1;
+  }
+  textContents.push(currentTextContent);
+  return textContents;
+};
+
+SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
+  // data should probably be cloned to apply scale separately to each instance of a text on different layers
+  // but since text internal content gets only rendered once and then it's never rerendered,
+  // it's probably safe not to clone data and reuse always the same instance even if the object is mutated.
+  // Avoiding cloning is preferred since cloning each character shape data is expensive
+  if (data.shapes && data.shapes.length) {
+    var shape = data.shapes[0];
+    if (shape.it) {
+      var shapeItem = shape.it[shape.it.length - 1];
+      if (shapeItem.s) {
+        shapeItem.s.k[0] = scale;
+        shapeItem.s.k[1] = scale;
+      }
+    }
+  }
+  return data;
+};
+
+SVGTextLottieElement.prototype.buildNewText = function () {
+  this.addDynamicProperty(this);
+  var i;
+  var len;
+
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
+  if (documentData.fc) {
+    this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
+  } else {
+    this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
+  }
+  if (documentData.sc) {
+    this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
+    this.layerElement.setAttribute('stroke-width', documentData.sw);
+  }
+  this.layerElement.setAttribute('font-size', documentData.finalSize);
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (fontData.fClass) {
+    this.layerElement.setAttribute('class', fontData.fClass);
+  } else {
+    this.layerElement.setAttribute('font-family', fontData.fFamily);
+    var fWeight = documentData.fWeight;
+    var fStyle = documentData.fStyle;
+    this.layerElement.setAttribute('font-style', fStyle);
+    this.layerElement.setAttribute('font-weight', fWeight);
+  }
+  this.layerElement.setAttribute('aria-label', documentData.t);
+
+  var letters = documentData.l || [];
+  var usesGlyphs = !!this.globalData.fontManager.chars;
+  len = letters.length;
+
+  var tSpan;
+  var matrixHelper = this.mHelper;
+  var shapeStr = '';
+  var singleShape = this.data.singleShape;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  if (singleShape && !usesGlyphs && !documentData.sz) {
+    var tElement = this.textContainer;
+    var justify = 'start';
+    switch (documentData.j) {
+      case 1:
+        justify = 'end';
+        break;
+      case 2:
+        justify = 'middle';
+        break;
+      default:
+        justify = 'start';
+        break;
+    }
+    tElement.setAttribute('text-anchor', justify);
+    tElement.setAttribute('letter-spacing', trackingOffset);
+    var textContent = this.buildTextContents(documentData.finalText);
+    len = textContent.length;
+    yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
+    for (i = 0; i < len; i += 1) {
+      tSpan = this.textSpans[i].span || createNS('tspan');
+      tSpan.textContent = textContent[i];
+      tSpan.setAttribute('x', 0);
+      tSpan.setAttribute('y', yPos);
+      tSpan.style.display = 'inherit';
+      tElement.appendChild(tSpan);
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          glyph: null,
+        };
+      }
+      this.textSpans[i].span = tSpan;
+      yPos += documentData.finalLineHeight;
+    }
+
+    this.layerElement.appendChild(tElement);
+  } else {
+    var cachedSpansLength = this.textSpans.length;
+    var charData;
+    for (i = 0; i < len; i += 1) {
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          childSpan: null,
+          glyph: null,
+        };
+      }
+      if (!usesGlyphs || !singleShape || i === 0) {
+        tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
+        if (cachedSpansLength <= i) {
+          tSpan.setAttribute('stroke-linecap', 'butt');
+          tSpan.setAttribute('stroke-linejoin', 'round');
+          tSpan.setAttribute('stroke-miterlimit', '4');
+          this.textSpans[i].span = tSpan;
+          if (usesGlyphs) {
+            var childSpan = createNS('g');
+            tSpan.appendChild(childSpan);
+            this.textSpans[i].childSpan = childSpan;
+          }
+          this.textSpans[i].span = tSpan;
+          this.layerElement.appendChild(tSpan);
+        }
+        tSpan.style.display = 'inherit';
+      }
+
+      matrixHelper.reset();
+      if (singleShape) {
+        if (letters[i].n) {
+          xPos = -trackingOffset;
+          yPos += documentData.yOffset;
+          yPos += firstLine ? 1 : 0;
+          firstLine = false;
+        }
+        this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+        xPos += letters[i].l || 0;
+        // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
+        xPos += trackingOffset;
+      }
+      if (usesGlyphs) {
+        charData = this.globalData.fontManager.getCharData(
+          documentData.finalText[i],
+          fontData.fStyle,
+          this.globalData.fontManager.getFontByName(documentData.f).fFamily
+        );
+        var glyphElement;
+        // t === 1 means the character has been replaced with an animated shaped
+        if (charData.t === 1) {
+          glyphElement = new SVGCompElement(charData.data, this.globalData, this);
+        } else {
+          var data = emptyShapeData;
+          if (charData.data && charData.data.shapes) {
+            data = this.buildShapeData(charData.data, documentData.finalSize);
+          }
+          glyphElement = new SVGShapeElement(data, this.globalData, this);
+        }
+        if (this.textSpans[i].glyph) {
+          var glyph = this.textSpans[i].glyph;
+          this.textSpans[i].childSpan.removeChild(glyph.layerElement);
+          glyph.destroy();
+        }
+        this.textSpans[i].glyph = glyphElement;
+        glyphElement._debug = true;
+        glyphElement.prepareFrame(0);
+        glyphElement.renderFrame();
+        this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+        // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+        // this might have issues with strokes and might need a different solution
+        if (charData.t === 1) {
+          this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
+        }
+      } else {
+        if (singleShape) {
+          tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
+        }
+        tSpan.textContent = letters[i].val;
+        tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      }
+      //
+    }
+    if (singleShape && tSpan) {
+      tSpan.setAttribute('d', shapeStr);
+    }
+  }
+  while (i < this.textSpans.length) {
+    this.textSpans[i].span.style.display = 'none';
+    i += 1;
+  }
+
+  this._sizeChanged = true;
+};
+
+SVGTextLottieElement.prototype.sourceRectAtTime = function () {
+  this.prepareFrame(this.comp.renderedFrame - this.data.st);
+  this.renderInnerContent();
+  if (this._sizeChanged) {
+    this._sizeChanged = false;
+    var textBox = this.layerElement.getBBox();
+    this.bbox = {
+      top: textBox.y,
+      left: textBox.x,
+      width: textBox.width,
+      height: textBox.height,
+    };
+  }
+  return this.bbox;
+};
+
+SVGTextLottieElement.prototype.getValue = function () {
+  var i;
+  var len = this.textSpans.length;
+  var glyphElement;
+  this.renderedFrame = this.comp.renderedFrame;
+  for (i = 0; i < len; i += 1) {
+    glyphElement = this.textSpans[i].glyph;
+    if (glyphElement) {
+      glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
+      if (glyphElement._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+SVGTextLottieElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  if (!this.data.singleShape || this._mdf) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+    if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
+      this._sizeChanged = true;
+      var i;
+      var len;
+      var renderedLetters = this.textAnimator.renderedLetters;
+
+      var letters = this.textProperty.currentData.l;
+
+      len = letters.length;
+      var renderedLetter;
+      var textSpan;
+      var glyphElement;
+      for (i = 0; i < len; i += 1) {
+        if (!letters[i].n) {
+          renderedLetter = renderedLetters[i];
+          textSpan = this.textSpans[i].span;
+          glyphElement = this.textSpans[i].glyph;
+          if (glyphElement) {
+            glyphElement.renderFrame();
+          }
+          if (renderedLetter._mdf.m) {
+            textSpan.setAttribute('transform', renderedLetter.m);
+          }
+          if (renderedLetter._mdf.o) {
+            textSpan.setAttribute('opacity', renderedLetter.o);
+          }
+          if (renderedLetter._mdf.sw) {
+            textSpan.setAttribute('stroke-width', renderedLetter.sw);
+          }
+          if (renderedLetter._mdf.sc) {
+            textSpan.setAttribute('stroke', renderedLetter.sc);
+          }
+          if (renderedLetter._mdf.fc) {
+            textSpan.setAttribute('fill', renderedLetter.fc);
+          }
+        }
+      }
+    }
+  }
+};
+
+function ISolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([IImageElement], ISolidElement);
+
+ISolidElement.prototype.createContent = function () {
+  var rect = createNS('rect');
+  /// /rect.style.width = this.data.sw;
+  /// /rect.style.height = this.data.sh;
+  /// /rect.style.fill = this.data.sc;
+  rect.setAttribute('width', this.data.sw);
+  rect.setAttribute('height', this.data.sh);
+  rect.setAttribute('fill', this.data.sc);
+  this.layerElement.appendChild(rect);
+};
+
+function NullElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initFrame();
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+}
+
+NullElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+NullElement.prototype.renderFrame = function () {
+};
+
+NullElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+NullElement.prototype.destroy = function () {
+};
+
+NullElement.prototype.sourceRectAtTime = function () {
+};
+
+NullElement.prototype.hide = function () {
+};
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
+
+function SVGRendererBase() {
+}
+
+extendPrototype([BaseRenderer], SVGRendererBase);
+
+SVGRendererBase.prototype.createNull = function (data) {
+  return new NullElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createShape = function (data) {
+  return new SVGShapeElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createText = function (data) {
+  return new SVGTextLottieElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createImage = function (data) {
+  return new IImageElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createSolid = function (data) {
+  return new ISolidElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.configAnimation = function (animData) {
+  this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+  this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+  if (this.renderConfig.viewBoxSize) {
+    this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
+  } else {
+    this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
+  }
+
+  if (!this.renderConfig.viewBoxOnly) {
+    this.svgElement.setAttribute('width', animData.w);
+    this.svgElement.setAttribute('height', animData.h);
+    this.svgElement.style.width = '100%';
+    this.svgElement.style.height = '100%';
+    this.svgElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
+  }
+  if (this.renderConfig.width) {
+    this.svgElement.setAttribute('width', this.renderConfig.width);
+  }
+  if (this.renderConfig.height) {
+    this.svgElement.setAttribute('height', this.renderConfig.height);
+  }
+  if (this.renderConfig.className) {
+    this.svgElement.setAttribute('class', this.renderConfig.className);
+  }
+  if (this.renderConfig.id) {
+    this.svgElement.setAttribute('id', this.renderConfig.id);
+  }
+  if (this.renderConfig.focusable !== undefined) {
+    this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
+  }
+  this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+  // this.layerElement.style.transform = 'translate3d(0,0,0)';
+  // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
+  this.animationItem.wrapper.appendChild(this.svgElement);
+  // Mask animation
+  var defs = this.globalData.defs;
+
+  this.setupGlobalData(animData, defs);
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.data = animData;
+
+  var maskElement = createNS('clipPath');
+  var rect = createNS('rect');
+  rect.setAttribute('width', animData.w);
+  rect.setAttribute('height', animData.h);
+  rect.setAttribute('x', 0);
+  rect.setAttribute('y', 0);
+  var maskId = createElementID();
+  maskElement.setAttribute('id', maskId);
+  maskElement.appendChild(rect);
+  this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')');
+
+  defs.appendChild(maskElement);
+  this.layers = animData.layers;
+  this.elements = createSizedArray(animData.layers.length);
+};
+
+SVGRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.layerElement = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+SVGRendererBase.prototype.updateContainerSize = function () {
+};
+
+SVGRendererBase.prototype.findIndexByInd = function (ind) {
+  var i = 0;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.layers[i].ind === ind) {
+      return i;
+    }
+  }
+  return -1;
+};
+
+SVGRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  elements[pos] = true;
+  var element = this.createItem(this.layers[pos]);
+
+  elements[pos] = element;
+  if (getExpressionsPlugin()) {
+    if (this.layers[pos].ty === 0) {
+      this.globalData.projectInterface.registerComposition(element);
+    }
+    element.initExpressions();
+  }
+  this.appendElementInPos(element, pos);
+  if (this.layers[pos].tt) {
+    var elementIndex = ('tp' in this.layers[pos])
+      ? this.findIndexByInd(this.layers[pos].tp)
+      : pos - 1;
+    if (elementIndex === -1) {
+      return;
+    }
+    if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
+      this.buildItem(elementIndex);
+      this.addPendingElement(element);
+    } else {
+      var matteElement = elements[elementIndex];
+      var matteMask = matteElement.getMatte(this.layers[pos].tt);
+      element.setMatte(matteMask);
+    }
+  }
+};
+
+SVGRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+    if (element.data.tt) {
+      var i = 0;
+      var len = this.elements.length;
+      while (i < len) {
+        if (this.elements[i] === element) {
+          var elementIndex = 'tp' in element.data
+            ? this.findIndexByInd(element.data.tp)
+            : i - 1;
+          var matteElement = this.elements[elementIndex];
+          var matteMask = matteElement.getMatte(this.layers[i].tt);
+          element.setMatte(matteMask);
+          break;
+        }
+        i += 1;
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.renderFrame = function (num) {
+  if (this.renderedFrame === num || this.destroyed) {
+    return;
+  }
+  if (num === null) {
+    num = this.renderedFrame;
+  } else {
+    this.renderedFrame = num;
+  }
+  // console.log('-------');
+  // console.log('FRAME ',num);
+  this.globalData.frameNum = num;
+  this.globalData.frameId += 1;
+  this.globalData.projectInterface.currentFrame = num;
+  this.globalData._mdf = false;
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    for (i = 0; i < len; i += 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
+  var newElement = element.getBaseElement();
+  if (!newElement) {
+    return;
+  }
+  var i = 0;
+  var nextElement;
+  while (i < pos) {
+    if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
+      nextElement = this.elements[i].getBaseElement();
+    }
+    i += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(newElement, nextElement);
+  } else {
+    this.layerElement.appendChild(newElement);
+  }
+};
+
+SVGRendererBase.prototype.hide = function () {
+  this.layerElement.style.display = 'none';
+};
+
+SVGRendererBase.prototype.show = function () {
+  this.layerElement.style.display = 'block';
+};
+
+function ICompElement() {}
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
+
+ICompElement.prototype.initElement = function (data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initTransform(data, globalData, comp);
+  this.initRenderable();
+  this.initHierarchy();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  if (this.data.xt || !globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+  this.hide();
+};
+
+/* ICompElement.prototype.hide = function(){
+    if(!this.hidden){
+        this.hideElement();
+        var i,len = this.elements.length;
+        for( i = 0; i < len; i+=1 ){
+            if(this.elements[i]){
+                this.elements[i].hide();
+            }
+        }
+    }
+}; */
+
+ICompElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+  if (!this.isInRange && !this.data.xt) {
+    return;
+  }
+
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    if (timeRemapped === this.data.op) {
+      timeRemapped = this.data.op - 1;
+    }
+    this.renderedFrame = timeRemapped;
+  } else {
+    this.renderedFrame = num / this.data.sr;
+  }
+  var i;
+  var len = this.elements.length;
+  if (!this.completeLayers) {
+    this.checkLayers(this.renderedFrame);
+  }
+  // This iteration needs to be backwards because of how expressions connect between each other
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
+      if (this.elements[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+ICompElement.prototype.renderInnerContent = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+ICompElement.prototype.setElements = function (elems) {
+  this.elements = elems;
+};
+
+ICompElement.prototype.getElements = function () {
+  return this.elements;
+};
+
+ICompElement.prototype.destroyElements = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+};
+
+ICompElement.prototype.destroy = function () {
+  this.destroyElements();
+  this.destroyBaseElement();
+};
+
+function SVGCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = true;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
+
+SVGCompElement.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function SVGRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.layers = null;
+  this.renderedFrame = -1;
+  this.svgElement = createNS('svg');
+  var ariaLabel = '';
+  if (config && config.title) {
+    var titleElement = createNS('title');
+    var titleId = createElementID();
+    titleElement.setAttribute('id', titleId);
+    titleElement.textContent = config.title;
+    this.svgElement.appendChild(titleElement);
+    ariaLabel += titleId;
+  }
+  if (config && config.description) {
+    var descElement = createNS('desc');
+    var descId = createElementID();
+    descElement.setAttribute('id', descId);
+    descElement.textContent = config.description;
+    this.svgElement.appendChild(descElement);
+    ariaLabel += ' ' + descId;
+  }
+  if (ariaLabel) {
+    this.svgElement.setAttribute('aria-labelledby', ariaLabel);
+  }
+  var defs = createNS('defs');
+  this.svgElement.appendChild(defs);
+  var maskElement = createNS('g');
+  this.svgElement.appendChild(maskElement);
+  this.layerElement = maskElement;
+  this.renderConfig = {
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    hideOnTransparent: !((config && config.hideOnTransparent === false)),
+    viewBoxOnly: (config && config.viewBoxOnly) || false,
+    viewBoxSize: (config && config.viewBoxSize) || false,
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    focusable: config && config.focusable,
+    filterSize: {
+      width: (config && config.filterSize && config.filterSize.width) || '100%',
+      height: (config && config.filterSize && config.filterSize.height) || '100%',
+      x: (config && config.filterSize && config.filterSize.x) || '0%',
+      y: (config && config.filterSize && config.filterSize.y) || '0%',
+    },
+    width: (config && config.width),
+    height: (config && config.height),
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+
+  this.globalData = {
+    _mdf: false,
+    frameNum: -1,
+    defs: defs,
+    renderConfig: this.renderConfig,
+  };
+  this.elements = [];
+  this.pendingElements = [];
+  this.destroyed = false;
+  this.rendererType = 'svg';
+}
+
+extendPrototype([SVGRendererBase], SVGRenderer);
+
+SVGRenderer.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+// Registering renderers
+registerRenderer('svg', SVGRenderer);
+
+// Registering shape modifiers
+ShapeModifiers.registerModifier('tm', TrimModifier);
+ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
+ShapeModifiers.registerModifier('rp', RepeaterModifier);
+ShapeModifiers.registerModifier('rd', RoundCornersModifier);
+ShapeModifiers.registerModifier('zz', ZigZagModifier);
+ShapeModifiers.registerModifier('op', OffsetPathModifier);
+
+const CompExpressionInterface = (function () {
+  return function (comp) {
+    function _thisLayerFunction(name) {
+      var i = 0;
+      var len = comp.layers.length;
+      while (i < len) {
+        if (comp.layers[i].nm === name || comp.layers[i].ind === name) {
+          return comp.elements[i].layerInterface;
+        }
+        i += 1;
+      }
+      return null;
+      // return {active:false};
+    }
+    Object.defineProperty(_thisLayerFunction, '_name', { value: comp.data.nm });
+    _thisLayerFunction.layer = _thisLayerFunction;
+    _thisLayerFunction.pixelAspect = 1;
+    _thisLayerFunction.height = comp.data.h || comp.globalData.compSize.h;
+    _thisLayerFunction.width = comp.data.w || comp.globalData.compSize.w;
+    _thisLayerFunction.pixelAspect = 1;
+    _thisLayerFunction.frameDuration = 1 / comp.globalData.frameRate;
+    _thisLayerFunction.displayStartTime = 0;
+    _thisLayerFunction.numLayers = comp.layers.length;
+    return _thisLayerFunction;
+  };
+}());
+
+/* eslint-disable */
+/*
+ Copyright 2014 David Bau.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ */
+
+function seedRandom(pool, math) {
+//
+// The following constants are related to IEEE 754 limits.
+//
+    var global = this,
+        width = 256,        // each RC4 output is 0 <= x < 256
+        chunks = 6,         // at least six RC4 outputs for each double
+        digits = 52,        // there are 52 significant digits in a double
+        rngname = 'random', // rngname: name for Math.random and Math.seedrandom
+        startdenom = math.pow(width, chunks),
+        significance = math.pow(2, digits),
+        overflow = significance * 2,
+        mask = width - 1,
+        nodecrypto;         // node.js crypto module, initialized at the bottom.
+
+//
+// seedrandom()
+// This is the seedrandom function described above.
+//
+    function seedrandom(seed, options, callback) {
+        var key = [];
+        options = (options === true) ? { entropy: true } : (options || {});
+
+        // Flatten the seed string or build one from local entropy if needed.
+        var shortseed = mixkey(flatten(
+            options.entropy ? [seed, tostring(pool)] :
+                (seed === null) ? autoseed() : seed, 3), key);
+
+        // Use the seed to initialize an ARC4 generator.
+        var arc4 = new ARC4(key);
+
+        // This function returns a random double in [0, 1) that contains
+        // randomness in every bit of the mantissa of the IEEE 754 value.
+        var prng = function() {
+            var n = arc4.g(chunks),             // Start with a numerator n < 2 ^ 48
+                d = startdenom,                 //   and denominator d = 2 ^ 48.
+                x = 0;                          //   and no 'extra last byte'.
+            while (n < significance) {          // Fill up all significant digits by
+                n = (n + x) * width;              //   shifting numerator and
+                d *= width;                       //   denominator and generating a
+                x = arc4.g(1);                    //   new least-significant-byte.
+            }
+            while (n >= overflow) {             // To avoid rounding up, before adding
+                n /= 2;                           //   last byte, shift everything
+                d /= 2;                           //   right using integer math until
+                x >>>= 1;                         //   we have exactly the desired bits.
+            }
+            return (n + x) / d;                 // Form the number within [0, 1).
+        };
+
+        prng.int32 = function() { return arc4.g(4) | 0; };
+        prng.quick = function() { return arc4.g(4) / 0x100000000; };
+        prng.double = prng;
+
+        // Mix the randomness into accumulated entropy.
+        mixkey(tostring(arc4.S), pool);
+
+        // Calling convention: what to return as a function of prng, seed, is_math.
+        return (options.pass || callback ||
+        function(prng, seed, is_math_call, state) {
+            if (state) {
+                // Load the arc4 state from the given state if it has an S array.
+                if (state.S) { copy(state, arc4); }
+                // Only provide the .state method if requested via options.state.
+                prng.state = function() { return copy(arc4, {}); };
+            }
+
+            // If called as a method of Math (Math.seedrandom()), mutate
+            // Math.random because that is how seedrandom.js has worked since v1.0.
+            if (is_math_call) { math[rngname] = prng; return seed; }
+
+            // Otherwise, it is a newer calling convention, so return the
+            // prng directly.
+            else return prng;
+        })(
+            prng,
+            shortseed,
+            'global' in options ? options.global : (this == math),
+            options.state);
+    }
+    math['seed' + rngname] = seedrandom;
+
+//
+// ARC4
+//
+// An ARC4 implementation.  The constructor takes a key in the form of
+// an array of at most (width) integers that should be 0 <= x < (width).
+//
+// The g(count) method returns a pseudorandom integer that concatenates
+// the next (count) outputs from ARC4.  Its return value is a number x
+// that is in the range 0 <= x < (width ^ count).
+//
+    function ARC4(key) {
+        var t, keylen = key.length,
+            me = this, i = 0, j = me.i = me.j = 0, s = me.S = [];
+
+        // The empty key [] is treated as [0].
+        if (!keylen) { key = [keylen++]; }
+
+        // Set up S using the standard key scheduling algorithm.
+        while (i < width) {
+            s[i] = i++;
+        }
+        for (i = 0; i < width; i++) {
+            s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))];
+            s[j] = t;
+        }
+
+        // The "g" method returns the next (count) outputs as one number.
+        me.g = function(count) {
+            // Using instance members instead of closure state nearly doubles speed.
+            var t, r = 0,
+                i = me.i, j = me.j, s = me.S;
+            while (count--) {
+                t = s[i = mask & (i + 1)];
+                r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))];
+            }
+            me.i = i; me.j = j;
+            return r;
+            // For robust unpredictability, the function call below automatically
+            // discards an initial batch of values.  This is called RC4-drop[256].
+            // See http://google.com/search?q=rsa+fluhrer+response&btnI
+        };
+    }
+
+//
+// copy()
+// Copies internal state of ARC4 to or from a plain object.
+//
+    function copy(f, t) {
+        t.i = f.i;
+        t.j = f.j;
+        t.S = f.S.slice();
+        return t;
+    }
+
+//
+// flatten()
+// Converts an object tree to nested arrays of strings.
+//
+    function flatten(obj, depth) {
+        var result = [], typ = (typeof obj), prop;
+        if (depth && typ == 'object') {
+            for (prop in obj) {
+                try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}
+            }
+        }
+        return (result.length ? result : typ == 'string' ? obj : obj + '\0');
+    }
+
+//
+// mixkey()
+// Mixes a string seed into a key that is an array of integers, and
+// returns a shortened string seed that is equivalent to the result key.
+//
+    function mixkey(seed, key) {
+        var stringseed = seed + '', smear, j = 0;
+        while (j < stringseed.length) {
+            key[mask & j] =
+                mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++));
+        }
+        return tostring(key);
+    }
+
+//
+// autoseed()
+// Returns an object for autoseeding, using window.crypto and Node crypto
+// module if available.
+//
+    function autoseed() {
+        try {
+            if (nodecrypto) { return tostring(nodecrypto.randomBytes(width)); }
+            var out = new Uint8Array(width);
+            (global.crypto || global.msCrypto).getRandomValues(out);
+            return tostring(out);
+        } catch (e) {
+            var browser = global.navigator,
+                plugins = browser && browser.plugins;
+            return [+new Date(), global, plugins, global.screen, tostring(pool)];
+        }
+    }
+
+//
+// tostring()
+// Converts an array of charcodes to a string
+//
+    function tostring(a) {
+        return String.fromCharCode.apply(0, a);
+    }
+
+//
+// When seedrandom.js is loaded, we immediately mix a few bits
+// from the built-in RNG into the entropy pool.  Because we do
+// not want to interfere with deterministic PRNG state later,
+// seedrandom will not call math.random on its own again after
+// initialization.
+//
+    mixkey(math.random(), pool);
+
+//
+// Nodejs and AMD support: export the implementation as a module using
+// either convention.
+//
+
+// End anonymous scope, and pass initial values.
+};
+
+function initialize$2(BMMath) {
+    seedRandom([], BMMath);
+}
+
+var propTypes = {
+  SHAPE: 'shape',
+};
+
+/* eslint-disable camelcase */
+
+const ExpressionManager = (function () {
+  'use strict';
+
+  var ob = {};
+  var Math = BMMath;
+  var window = null;
+  var document = null;
+  var XMLHttpRequest = null;
+  var fetch = null;
+  var frames = null;
+  var _lottieGlobal = {};
+  initialize$2(BMMath);
+
+  function resetFrame() {
+    _lottieGlobal = {};
+  }
+
+  function $bm_isInstanceOfArray(arr) {
+    return arr.constructor === Array || arr.constructor === Float32Array;
+  }
+
+  function isNumerable(tOfV, v) {
+    return tOfV === 'number' || v instanceof Number || tOfV === 'boolean' || tOfV === 'string';
+  }
+
+  function $bm_neg(a) {
+    var tOfA = typeof a;
+    if (tOfA === 'number' || a instanceof Number || tOfA === 'boolean') {
+      return -a;
+    }
+    if ($bm_isInstanceOfArray(a)) {
+      var i;
+      var lenA = a.length;
+      var retArr = [];
+      for (i = 0; i < lenA; i += 1) {
+        retArr[i] = -a[i];
+      }
+      return retArr;
+    }
+    if (a.propType) {
+      return a.v;
+    }
+    return -a;
+  }
+
+  var easeInBez = BezierFactory.getBezierEasing(0.333, 0, 0.833, 0.833, 'easeIn').get;
+  var easeOutBez = BezierFactory.getBezierEasing(0.167, 0.167, 0.667, 1, 'easeOut').get;
+  var easeInOutBez = BezierFactory.getBezierEasing(0.33, 0, 0.667, 1, 'easeInOut').get;
+
+  function sum(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    if ((isNumerable(tOfA, a) && isNumerable(tOfB, b)) || tOfA === 'string' || tOfB === 'string') {
+      return a + b;
+    }
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      a = a.slice(0);
+      a[0] += b;
+      return a;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      b = b.slice(0);
+      b[0] = a + b[0];
+      return b;
+    }
+    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
+      var i = 0;
+      var lenA = a.length;
+      var lenB = b.length;
+      var retArr = [];
+      while (i < lenA || i < lenB) {
+        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
+          retArr[i] = a[i] + b[i];
+        } else {
+          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
+        }
+        i += 1;
+      }
+      return retArr;
+    }
+    return 0;
+  }
+  var add = sum;
+
+  function sub(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      if (tOfA === 'string') {
+        a = parseInt(a, 10);
+      }
+      if (tOfB === 'string') {
+        b = parseInt(b, 10);
+      }
+      return a - b;
+    }
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      a = a.slice(0);
+      a[0] -= b;
+      return a;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      b = b.slice(0);
+      b[0] = a - b[0];
+      return b;
+    }
+    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
+      var i = 0;
+      var lenA = a.length;
+      var lenB = b.length;
+      var retArr = [];
+      while (i < lenA || i < lenB) {
+        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
+          retArr[i] = a[i] - b[i];
+        } else {
+          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
+        }
+        i += 1;
+      }
+      return retArr;
+    }
+    return 0;
+  }
+
+  function mul(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    var arr;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      return a * b;
+    }
+
+    var i;
+    var len;
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      len = a.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a[i] * b;
+      }
+      return arr;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      len = b.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a * b[i];
+      }
+      return arr;
+    }
+    return 0;
+  }
+
+  function div(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    var arr;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      return a / b;
+    }
+    var i;
+    var len;
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      len = a.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a[i] / b;
+      }
+      return arr;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      len = b.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a / b[i];
+      }
+      return arr;
+    }
+    return 0;
+  }
+  function mod(a, b) {
+    if (typeof a === 'string') {
+      a = parseInt(a, 10);
+    }
+    if (typeof b === 'string') {
+      b = parseInt(b, 10);
+    }
+    return a % b;
+  }
+  var $bm_sum = sum;
+  var $bm_sub = sub;
+  var $bm_mul = mul;
+  var $bm_div = div;
+  var $bm_mod = mod;
+
+  function clamp(num, min, max) {
+    if (min > max) {
+      var mm = max;
+      max = min;
+      min = mm;
+    }
+    return Math.min(Math.max(num, min), max);
+  }
+
+  function radiansToDegrees(val) {
+    return val / degToRads;
+  }
+  var radians_to_degrees = radiansToDegrees;
+
+  function degreesToRadians(val) {
+    return val * degToRads;
+  }
+  var degrees_to_radians = radiansToDegrees;
+
+  var helperLengthArray = [0, 0, 0, 0, 0, 0];
+
+  function length(arr1, arr2) {
+    if (typeof arr1 === 'number' || arr1 instanceof Number) {
+      arr2 = arr2 || 0;
+      return Math.abs(arr1 - arr2);
+    }
+    if (!arr2) {
+      arr2 = helperLengthArray;
+    }
+    var i;
+    var len = Math.min(arr1.length, arr2.length);
+    var addedLength = 0;
+    for (i = 0; i < len; i += 1) {
+      addedLength += Math.pow(arr2[i] - arr1[i], 2);
+    }
+    return Math.sqrt(addedLength);
+  }
+
+  function normalize(vec) {
+    return div(vec, length(vec));
+  }
+
+  function rgbToHsl(val) {
+    var r = val[0]; var g = val[1]; var b = val[2];
+    var max = Math.max(r, g, b);
+    var min = Math.min(r, g, b);
+    var h;
+    var s;
+    var l = (max + min) / 2;
+
+    if (max === min) {
+      h = 0; // achromatic
+      s = 0; // achromatic
+    } else {
+      var d = max - min;
+      s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+      switch (max) {
+        case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+        case g: h = (b - r) / d + 2; break;
+        case b: h = (r - g) / d + 4; break;
+        default: break;
+      }
+      h /= 6;
+    }
+
+    return [h, s, l, val[3]];
+  }
+
+  function hue2rgb(p, q, t) {
+    if (t < 0) t += 1;
+    if (t > 1) t -= 1;
+    if (t < 1 / 6) return p + (q - p) * 6 * t;
+    if (t < 1 / 2) return q;
+    if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
+    return p;
+  }
+
+  function hslToRgb(val) {
+    var h = val[0];
+    var s = val[1];
+    var l = val[2];
+
+    var r;
+    var g;
+    var b;
+
+    if (s === 0) {
+      r = l; // achromatic
+      b = l; // achromatic
+      g = l; // achromatic
+    } else {
+      var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+      var p = 2 * l - q;
+      r = hue2rgb(p, q, h + 1 / 3);
+      g = hue2rgb(p, q, h);
+      b = hue2rgb(p, q, h - 1 / 3);
+    }
+
+    return [r, g, b, val[3]];
+  }
+
+  function linear(t, tMin, tMax, value1, value2) {
+    if (value1 === undefined || value2 === undefined) {
+      value1 = tMin;
+      value2 = tMax;
+      tMin = 0;
+      tMax = 1;
+    }
+    if (tMax < tMin) {
+      var _tMin = tMax;
+      tMax = tMin;
+      tMin = _tMin;
+    }
+    if (t <= tMin) {
+      return value1;
+    } if (t >= tMax) {
+      return value2;
+    }
+    var perc = tMax === tMin ? 0 : (t - tMin) / (tMax - tMin);
+    if (!value1.length) {
+      return value1 + (value2 - value1) * perc;
+    }
+    var i;
+    var len = value1.length;
+    var arr = createTypedArray('float32', len);
+    for (i = 0; i < len; i += 1) {
+      arr[i] = value1[i] + (value2[i] - value1[i]) * perc;
+    }
+    return arr;
+  }
+  function random(min, max) {
+    if (max === undefined) {
+      if (min === undefined) {
+        min = 0;
+        max = 1;
+      } else {
+        max = min;
+        min = undefined;
+      }
+    }
+    if (max.length) {
+      var i;
+      var len = max.length;
+      if (!min) {
+        min = createTypedArray('float32', len);
+      }
+      var arr = createTypedArray('float32', len);
+      var rnd = BMMath.random();
+      for (i = 0; i < len; i += 1) {
+        arr[i] = min[i] + rnd * (max[i] - min[i]);
+      }
+      return arr;
+    }
+    if (min === undefined) {
+      min = 0;
+    }
+    var rndm = BMMath.random();
+    return min + rndm * (max - min);
+  }
+
+  function createPath(points, inTangents, outTangents, closed) {
+    var i;
+    var len = points.length;
+    var path = shapePool.newElement();
+    path.setPathData(!!closed, len);
+    var arrPlaceholder = [0, 0];
+    var inVertexPoint;
+    var outVertexPoint;
+    for (i = 0; i < len; i += 1) {
+      inVertexPoint = (inTangents && inTangents[i]) ? inTangents[i] : arrPlaceholder;
+      outVertexPoint = (outTangents && outTangents[i]) ? outTangents[i] : arrPlaceholder;
+      path.setTripleAt(points[i][0], points[i][1], outVertexPoint[0] + points[i][0], outVertexPoint[1] + points[i][1], inVertexPoint[0] + points[i][0], inVertexPoint[1] + points[i][1], i, true);
+    }
+    return path;
+  }
+
+  function initiateExpression(elem, data, property) {
+    // Bail out if we don't want expressions
+    function noOp(_value) {
+      return _value;
+    }
+    if (!elem.globalData.renderConfig.runExpressions) {
+      return noOp;
+    }
+
+    var val = data.x;
+    var needsVelocity = /velocity(?![\w\d])/.test(val);
+    var _needsRandom = val.indexOf('random') !== -1;
+    var elemType = elem.data.ty;
+    var transform;
+    var $bm_transform;
+    var content;
+    var effect;
+    var thisProperty = property;
+    thisProperty._name = elem.data.nm;
+    thisProperty.valueAtTime = thisProperty.getValueAtTime;
+    Object.defineProperty(thisProperty, 'value', {
+      get: function () {
+        return thisProperty.v;
+      },
+    });
+    elem.comp.frameDuration = 1 / elem.comp.globalData.frameRate;
+    elem.comp.displayStartTime = 0;
+    var inPoint = elem.data.ip / elem.comp.globalData.frameRate;
+    var outPoint = elem.data.op / elem.comp.globalData.frameRate;
+    var width = elem.data.sw ? elem.data.sw : 0;
+    var height = elem.data.sh ? elem.data.sh : 0;
+    var name = elem.data.nm;
+    var loopIn;
+    var loop_in;
+    var loopOut;
+    var loop_out;
+    var smooth;
+    var toWorld;
+    var fromWorld;
+    var fromComp;
+    var toComp;
+    var fromCompToSurface;
+    var position;
+    var rotation;
+    var anchorPoint;
+    var scale;
+    var thisLayer;
+    var thisComp;
+    var mask;
+    var valueAtTime;
+    var velocityAtTime;
+
+    var scoped_bm_rt;
+    // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
+    var expression_function = eval('[function _expression_function(){' + val + ';scoped_bm_rt=$bm_rt}]')[0]; // eslint-disable-line no-eval
+    var numKeys = property.kf ? data.k.length : 0;
+
+    var active = !this.data || this.data.hd !== true;
+
+    var wiggle = function wiggle(freq, amp) {
+      var iWiggle;
+      var j;
+      var lenWiggle = this.pv.length ? this.pv.length : 1;
+      var addedAmps = createTypedArray('float32', lenWiggle);
+      freq = 5;
+      var iterations = Math.floor(time * freq);
+      iWiggle = 0;
+      j = 0;
+      while (iWiggle < iterations) {
+        // var rnd = BMMath.random();
+        for (j = 0; j < lenWiggle; j += 1) {
+          addedAmps[j] += -amp + amp * 2 * BMMath.random();
+          // addedAmps[j] += -amp + amp*2*rnd;
+        }
+        iWiggle += 1;
+      }
+      // var rnd2 = BMMath.random();
+      var periods = time * freq;
+      var perc = periods - Math.floor(periods);
+      var arr = createTypedArray('float32', lenWiggle);
+      if (lenWiggle > 1) {
+        for (j = 0; j < lenWiggle; j += 1) {
+          arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc;
+          // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
+          // arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc);
+        }
+        return arr;
+      }
+      return this.pv + addedAmps[0] + (-amp + amp * 2 * BMMath.random()) * perc;
+    }.bind(this);
+
+    if (thisProperty.loopIn) {
+      loopIn = thisProperty.loopIn.bind(thisProperty);
+      loop_in = loopIn;
+    }
+
+    if (thisProperty.loopOut) {
+      loopOut = thisProperty.loopOut.bind(thisProperty);
+      loop_out = loopOut;
+    }
+
+    if (thisProperty.smooth) {
+      smooth = thisProperty.smooth.bind(thisProperty);
+    }
+
+    function loopInDuration(type, duration) {
+      return loopIn(type, duration, true);
+    }
+
+    function loopOutDuration(type, duration) {
+      return loopOut(type, duration, true);
+    }
+
+    if (this.getValueAtTime) {
+      valueAtTime = this.getValueAtTime.bind(this);
+    }
+
+    if (this.getVelocityAtTime) {
+      velocityAtTime = this.getVelocityAtTime.bind(this);
+    }
+
+    var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface);
+
+    function lookAt(elem1, elem2) {
+      var fVec = [elem2[0] - elem1[0], elem2[1] - elem1[1], elem2[2] - elem1[2]];
+      var pitch = Math.atan2(fVec[0], Math.sqrt(fVec[1] * fVec[1] + fVec[2] * fVec[2])) / degToRads;
+      var yaw = -Math.atan2(fVec[1], fVec[2]) / degToRads;
+      return [yaw, pitch, 0];
+    }
+
+    function easeOut(t, tMin, tMax, val1, val2) {
+      return applyEase(easeOutBez, t, tMin, tMax, val1, val2);
+    }
+
+    function easeIn(t, tMin, tMax, val1, val2) {
+      return applyEase(easeInBez, t, tMin, tMax, val1, val2);
+    }
+
+    function ease(t, tMin, tMax, val1, val2) {
+      return applyEase(easeInOutBez, t, tMin, tMax, val1, val2);
+    }
+
+    function applyEase(fn, t, tMin, tMax, val1, val2) {
+      if (val1 === undefined) {
+        val1 = tMin;
+        val2 = tMax;
+      } else {
+        t = (t - tMin) / (tMax - tMin);
+      }
+      if (t > 1) {
+        t = 1;
+      } else if (t < 0) {
+        t = 0;
+      }
+      var mult = fn(t);
+      if ($bm_isInstanceOfArray(val1)) {
+        var iKey;
+        var lenKey = val1.length;
+        var arr = createTypedArray('float32', lenKey);
+        for (iKey = 0; iKey < lenKey; iKey += 1) {
+          arr[iKey] = (val2[iKey] - val1[iKey]) * mult + val1[iKey];
+        }
+        return arr;
+      }
+      return (val2 - val1) * mult + val1;
+    }
+
+    function nearestKey(time) {
+      var iKey;
+      var lenKey = data.k.length;
+      var index;
+      var keyTime;
+      if (!data.k.length || typeof (data.k[0]) === 'number') {
+        index = 0;
+        keyTime = 0;
+      } else {
+        index = -1;
+        time *= elem.comp.globalData.frameRate;
+        if (time < data.k[0].t) {
+          index = 1;
+          keyTime = data.k[0].t;
+        } else {
+          for (iKey = 0; iKey < lenKey - 1; iKey += 1) {
+            if (time === data.k[iKey].t) {
+              index = iKey + 1;
+              keyTime = data.k[iKey].t;
+              break;
+            } else if (time > data.k[iKey].t && time < data.k[iKey + 1].t) {
+              if (time - data.k[iKey].t > data.k[iKey + 1].t - time) {
+                index = iKey + 2;
+                keyTime = data.k[iKey + 1].t;
+              } else {
+                index = iKey + 1;
+                keyTime = data.k[iKey].t;
+              }
+              break;
+            }
+          }
+          if (index === -1) {
+            index = iKey + 1;
+            keyTime = data.k[iKey].t;
+          }
+        }
+      }
+      var obKey = {};
+      obKey.index = index;
+      obKey.time = keyTime / elem.comp.globalData.frameRate;
+      return obKey;
+    }
+
+    function key(ind) {
+      var obKey;
+      var iKey;
+      var lenKey;
+      if (!data.k.length || typeof (data.k[0]) === 'number') {
+        throw new Error('The property has no keyframe at index ' + ind);
+      }
+      ind -= 1;
+      obKey = {
+        time: data.k[ind].t / elem.comp.globalData.frameRate,
+        value: [],
+      };
+      var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e;
+
+      lenKey = arr.length;
+      for (iKey = 0; iKey < lenKey; iKey += 1) {
+        obKey[iKey] = arr[iKey];
+        obKey.value[iKey] = arr[iKey];
+      }
+      return obKey;
+    }
+
+    function framesToTime(fr, fps) {
+      if (!fps) {
+        fps = elem.comp.globalData.frameRate;
+      }
+      return fr / fps;
+    }
+
+    function timeToFrames(t, fps) {
+      if (!t && t !== 0) {
+        t = time;
+      }
+      if (!fps) {
+        fps = elem.comp.globalData.frameRate;
+      }
+      return t * fps;
+    }
+
+    function seedRandom(seed) {
+      BMMath.seedrandom(randSeed + seed);
+    }
+
+    function sourceRectAtTime() {
+      return elem.sourceRectAtTime();
+    }
+
+    function substring(init, end) {
+      if (typeof value === 'string') {
+        if (end === undefined) {
+          return value.substring(init);
+        }
+        return value.substring(init, end);
+      }
+      return '';
+    }
+
+    function substr(init, end) {
+      if (typeof value === 'string') {
+        if (end === undefined) {
+          return value.substr(init);
+        }
+        return value.substr(init, end);
+      }
+      return '';
+    }
+
+    function posterizeTime(framesPerSecond) {
+      time = framesPerSecond === 0 ? 0 : Math.floor(time * framesPerSecond) / framesPerSecond;
+      value = valueAtTime(time);
+    }
+
+    var time;
+    var velocity;
+    var value;
+    var text;
+    var textIndex;
+    var textTotal;
+    var selectorValue;
+    var index = elem.data.ind;
+    var hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+    var parent;
+    var randSeed = Math.floor(Math.random() * 1000000);
+    var globalData = elem.globalData;
+
+    function executeExpression(_value) {
+      // globalData.pushExpression();
+      value = _value;
+      if (this.frameExpressionId === elem.globalData.frameId && this.propType !== 'textSelector') {
+        return value;
+      }
+      if (this.propType === 'textSelector') {
+        textIndex = this.textIndex;
+        textTotal = this.textTotal;
+        selectorValue = this.selectorValue;
+      }
+      if (!thisLayer) {
+        text = elem.layerInterface.text;
+        thisLayer = elem.layerInterface;
+        thisComp = elem.comp.compInterface;
+        toWorld = thisLayer.toWorld.bind(thisLayer);
+        fromWorld = thisLayer.fromWorld.bind(thisLayer);
+        fromComp = thisLayer.fromComp.bind(thisLayer);
+        toComp = thisLayer.toComp.bind(thisLayer);
+        mask = thisLayer.mask ? thisLayer.mask.bind(thisLayer) : null;
+        fromCompToSurface = fromComp;
+      }
+      if (!transform) {
+        transform = elem.layerInterface('ADBE Transform Group');
+        $bm_transform = transform;
+        if (transform) {
+          anchorPoint = transform.anchorPoint;
+          /* position = transform.position;
+                    rotation = transform.rotation;
+                    scale = transform.scale; */
+        }
+      }
+
+      if (elemType === 4 && !content) {
+        content = thisLayer('ADBE Root Vectors Group');
+      }
+      if (!effect) {
+        effect = thisLayer(4);
+      }
+      hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+      if (hasParent && !parent) {
+        parent = elem.hierarchy[0].layerInterface;
+      }
+      time = this.comp.renderedFrame / this.comp.globalData.frameRate;
+      if (_needsRandom) {
+        seedRandom(randSeed + time);
+      }
+      if (needsVelocity) {
+        velocity = velocityAtTime(time);
+      }
+      expression_function();
+      this.frameExpressionId = elem.globalData.frameId;
+
+      // TODO: Check if it's possible to return on ShapeInterface the .v value
+      // Changed this to a ternary operation because Rollup failed compiling it correctly
+      scoped_bm_rt = scoped_bm_rt.propType === propTypes.SHAPE
+        ? scoped_bm_rt.v
+        : scoped_bm_rt;
+      return scoped_bm_rt;
+    }
+    // Bundlers will see these as dead code and unless we reference them
+    executeExpression.__preventDeadCodeRemoval = [$bm_transform, anchorPoint, time, velocity, inPoint, outPoint, width, height, name, loop_in, loop_out, smooth, toComp, fromCompToSurface, toWorld, fromWorld, mask, position, rotation, scale, thisComp, numKeys, active, wiggle, loopInDuration, loopOutDuration, comp, lookAt, easeOut, easeIn, ease, nearestKey, key, text, textIndex, textTotal, selectorValue, framesToTime, timeToFrames, sourceRectAtTime, substring, substr, posterizeTime, index, globalData];
+    return executeExpression;
+  }
+
+  ob.initiateExpression = initiateExpression;
+  ob.__preventDeadCodeRemoval = [window, document, XMLHttpRequest, fetch, frames, $bm_neg, add, $bm_sum, $bm_sub, $bm_mul, $bm_div, $bm_mod, clamp, radians_to_degrees, degreesToRadians, degrees_to_radians, normalize, rgbToHsl, hslToRgb, linear, random, createPath, _lottieGlobal];
+  ob.resetFrame = resetFrame;
+  return ob;
+}());
+
+const Expressions = (function () {
+  var ob = {};
+  ob.initExpressions = initExpressions;
+  ob.resetFrame = ExpressionManager.resetFrame;
+
+  function initExpressions(animation) {
+    var stackCount = 0;
+    var registers = [];
+
+    function pushExpression() {
+      stackCount += 1;
+    }
+
+    function popExpression() {
+      stackCount -= 1;
+      if (stackCount === 0) {
+        releaseInstances();
+      }
+    }
+
+    function registerExpressionProperty(expression) {
+      if (registers.indexOf(expression) === -1) {
+        registers.push(expression);
+      }
+    }
+
+    function releaseInstances() {
+      var i;
+      var len = registers.length;
+      for (i = 0; i < len; i += 1) {
+        registers[i].release();
+      }
+      registers.length = 0;
+    }
+
+    animation.renderer.compInterface = CompExpressionInterface(animation.renderer);
+    animation.renderer.globalData.projectInterface.registerComposition(animation.renderer);
+    animation.renderer.globalData.pushExpression = pushExpression;
+    animation.renderer.globalData.popExpression = popExpression;
+    animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty;
+  }
+  return ob;
+}());
+
+const MaskManagerInterface = (function () {
+  function MaskInterface(mask, data) {
+    this._mask = mask;
+    this._data = data;
+  }
+  Object.defineProperty(MaskInterface.prototype, 'maskPath', {
+    get: function () {
+      if (this._mask.prop.k) {
+        this._mask.prop.getValue();
+      }
+      return this._mask.prop;
+    },
+  });
+  Object.defineProperty(MaskInterface.prototype, 'maskOpacity', {
+    get: function () {
+      if (this._mask.op.k) {
+        this._mask.op.getValue();
+      }
+      return this._mask.op.v * 100;
+    },
+  });
+
+  var MaskManager = function (maskManager) {
+    var _masksInterfaces = createSizedArray(maskManager.viewData.length);
+    var i;
+    var len = maskManager.viewData.length;
+    for (i = 0; i < len; i += 1) {
+      _masksInterfaces[i] = new MaskInterface(maskManager.viewData[i], maskManager.masksProperties[i]);
+    }
+
+    var maskFunction = function (name) {
+      i = 0;
+      while (i < len) {
+        if (maskManager.masksProperties[i].nm === name) {
+          return _masksInterfaces[i];
+        }
+        i += 1;
+      }
+      return null;
+    };
+    return maskFunction;
+  };
+  return MaskManager;
+}());
+
+const ExpressionPropertyInterface = (function () {
+  var defaultUnidimensionalValue = { pv: 0, v: 0, mult: 1 };
+  var defaultMultidimensionalValue = { pv: [0, 0, 0], v: [0, 0, 0], mult: 1 };
+
+  function completeProperty(expressionValue, property, type) {
+    Object.defineProperty(expressionValue, 'velocity', {
+      get: function () {
+        return property.getVelocityAtTime(property.comp.currentFrame);
+      },
+    });
+    expressionValue.numKeys = property.keyframes ? property.keyframes.length : 0;
+    expressionValue.key = function (pos) {
+      if (!expressionValue.numKeys) {
+        return 0;
+      }
+      var value = '';
+      if ('s' in property.keyframes[pos - 1]) {
+        value = property.keyframes[pos - 1].s;
+      } else if ('e' in property.keyframes[pos - 2]) {
+        value = property.keyframes[pos - 2].e;
+      } else {
+        value = property.keyframes[pos - 2].s;
+      }
+      var valueProp = type === 'unidimensional' ? new Number(value) : Object.assign({}, value); // eslint-disable-line no-new-wrappers
+      valueProp.time = property.keyframes[pos - 1].t / property.elem.comp.globalData.frameRate;
+      valueProp.value = type === 'unidimensional' ? value[0] : value;
+      return valueProp;
+    };
+    expressionValue.valueAtTime = property.getValueAtTime;
+    expressionValue.speedAtTime = property.getSpeedAtTime;
+    expressionValue.velocityAtTime = property.getVelocityAtTime;
+    expressionValue.propertyGroup = property.propertyGroup;
+  }
+
+  function UnidimensionalPropertyInterface(property) {
+    if (!property || !('pv' in property)) {
+      property = defaultUnidimensionalValue;
+    }
+    var mult = 1 / property.mult;
+    var val = property.pv * mult;
+    var expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
+    expressionValue.value = val;
+    completeProperty(expressionValue, property, 'unidimensional');
+
+    return function () {
+      if (property.k) {
+        property.getValue();
+      }
+      val = property.v * mult;
+      if (expressionValue.value !== val) {
+        expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
+        expressionValue.value = val;
+        expressionValue[0] = val;
+        completeProperty(expressionValue, property, 'unidimensional');
+      }
+      return expressionValue;
+    };
+  }
+
+  function MultidimensionalPropertyInterface(property) {
+    if (!property || !('pv' in property)) {
+      property = defaultMultidimensionalValue;
+    }
+    var mult = 1 / property.mult;
+    var len = (property.data && property.data.l) || property.pv.length;
+    var expressionValue = createTypedArray('float32', len);
+    var arrValue = createTypedArray('float32', len);
+    expressionValue.value = arrValue;
+    completeProperty(expressionValue, property, 'multidimensional');
+
+    return function () {
+      if (property.k) {
+        property.getValue();
+      }
+      for (var i = 0; i < len; i += 1) {
+        arrValue[i] = property.v[i] * mult;
+        expressionValue[i] = arrValue[i];
+      }
+      return expressionValue;
+    };
+  }
+
+  // TODO: try to avoid using this getter
+  function defaultGetter() {
+    return defaultUnidimensionalValue;
+  }
+
+  return function (property) {
+    if (!property) {
+      return defaultGetter;
+    } if (property.propType === 'unidimensional') {
+      return UnidimensionalPropertyInterface(property);
+    }
+    return MultidimensionalPropertyInterface(property);
+  };
+}());
+
+const TransformExpressionInterface = (function () {
+  return function (transform) {
+    function _thisFunction(name) {
+      switch (name) {
+        case 'scale':
+        case 'Scale':
+        case 'ADBE Scale':
+        case 6:
+          return _thisFunction.scale;
+        case 'rotation':
+        case 'Rotation':
+        case 'ADBE Rotation':
+        case 'ADBE Rotate Z':
+        case 10:
+          return _thisFunction.rotation;
+        case 'ADBE Rotate X':
+          return _thisFunction.xRotation;
+        case 'ADBE Rotate Y':
+          return _thisFunction.yRotation;
+        case 'position':
+        case 'Position':
+        case 'ADBE Position':
+        case 2:
+          return _thisFunction.position;
+        case 'ADBE Position_0':
+          return _thisFunction.xPosition;
+        case 'ADBE Position_1':
+          return _thisFunction.yPosition;
+        case 'ADBE Position_2':
+          return _thisFunction.zPosition;
+        case 'anchorPoint':
+        case 'AnchorPoint':
+        case 'Anchor Point':
+        case 'ADBE AnchorPoint':
+        case 1:
+          return _thisFunction.anchorPoint;
+        case 'opacity':
+        case 'Opacity':
+        case 11:
+          return _thisFunction.opacity;
+        default:
+          return null;
+      }
+    }
+    Object.defineProperty(_thisFunction, 'rotation', {
+      get: ExpressionPropertyInterface(transform.r || transform.rz),
+    });
+
+    Object.defineProperty(_thisFunction, 'zRotation', {
+      get: ExpressionPropertyInterface(transform.rz || transform.r),
+    });
+
+    Object.defineProperty(_thisFunction, 'xRotation', {
+      get: ExpressionPropertyInterface(transform.rx),
+    });
+
+    Object.defineProperty(_thisFunction, 'yRotation', {
+      get: ExpressionPropertyInterface(transform.ry),
+    });
+    Object.defineProperty(_thisFunction, 'scale', {
+      get: ExpressionPropertyInterface(transform.s),
+    });
+    var _px;
+    var _py;
+    var _pz;
+    var _transformFactory;
+    if (transform.p) {
+      _transformFactory = ExpressionPropertyInterface(transform.p);
+    } else {
+      _px = ExpressionPropertyInterface(transform.px);
+      _py = ExpressionPropertyInterface(transform.py);
+      if (transform.pz) {
+        _pz = ExpressionPropertyInterface(transform.pz);
+      }
+    }
+    Object.defineProperty(_thisFunction, 'position', {
+      get: function () {
+        if (transform.p) {
+          return _transformFactory();
+        }
+        return [
+          _px(),
+          _py(),
+          _pz ? _pz() : 0];
+      },
+    });
+
+    Object.defineProperty(_thisFunction, 'xPosition', {
+      get: ExpressionPropertyInterface(transform.px),
+    });
+
+    Object.defineProperty(_thisFunction, 'yPosition', {
+      get: ExpressionPropertyInterface(transform.py),
+    });
+
+    Object.defineProperty(_thisFunction, 'zPosition', {
+      get: ExpressionPropertyInterface(transform.pz),
+    });
+
+    Object.defineProperty(_thisFunction, 'anchorPoint', {
+      get: ExpressionPropertyInterface(transform.a),
+    });
+
+    Object.defineProperty(_thisFunction, 'opacity', {
+      get: ExpressionPropertyInterface(transform.o),
+    });
+
+    Object.defineProperty(_thisFunction, 'skew', {
+      get: ExpressionPropertyInterface(transform.sk),
+    });
+
+    Object.defineProperty(_thisFunction, 'skewAxis', {
+      get: ExpressionPropertyInterface(transform.sa),
+    });
+
+    Object.defineProperty(_thisFunction, 'orientation', {
+      get: ExpressionPropertyInterface(transform.or),
+    });
+
+    return _thisFunction;
+  };
+}());
+
+const LayerExpressionInterface = (function () {
+  function getMatrix(time) {
+    var toWorldMat = new Matrix();
+    if (time !== undefined) {
+      var propMatrix = this._elem.finalTransform.mProp.getValueAtTime(time);
+      propMatrix.clone(toWorldMat);
+    } else {
+      var transformMat = this._elem.finalTransform.mProp;
+      transformMat.applyToMatrix(toWorldMat);
+    }
+    return toWorldMat;
+  }
+
+  function toWorldVec(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    toWorldMat.props[12] = 0;
+    toWorldMat.props[13] = 0;
+    toWorldMat.props[14] = 0;
+    return this.applyPoint(toWorldMat, arr);
+  }
+
+  function toWorld(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    return this.applyPoint(toWorldMat, arr);
+  }
+
+  function fromWorldVec(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    toWorldMat.props[12] = 0;
+    toWorldMat.props[13] = 0;
+    toWorldMat.props[14] = 0;
+    return this.invertPoint(toWorldMat, arr);
+  }
+
+  function fromWorld(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    return this.invertPoint(toWorldMat, arr);
+  }
+
+  function applyPoint(matrix, arr) {
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
+      }
+    }
+    return matrix.applyToPointArray(arr[0], arr[1], arr[2] || 0);
+  }
+
+  function invertPoint(matrix, arr) {
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
+      }
+    }
+    return matrix.inversePoint(arr);
+  }
+
+  function fromComp(arr) {
+    var toWorldMat = new Matrix();
+    toWorldMat.reset();
+    this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
+      }
+      return toWorldMat.inversePoint(arr);
+    }
+    return toWorldMat.inversePoint(arr);
+  }
+
+  function sampleImage() {
+    return [1, 1, 1, 1];
+  }
+
+  return function (elem) {
+    var transformInterface;
+
+    function _registerMaskInterface(maskManager) {
+      _thisLayerFunction.mask = new MaskManagerInterface(maskManager, elem);
+    }
+    function _registerEffectsInterface(effects) {
+      _thisLayerFunction.effect = effects;
+    }
+
+    function _thisLayerFunction(name) {
+      switch (name) {
+        case 'ADBE Root Vectors Group':
+        case 'Contents':
+        case 2:
+          return _thisLayerFunction.shapeInterface;
+        case 1:
+        case 6:
+        case 'Transform':
+        case 'transform':
+        case 'ADBE Transform Group':
+          return transformInterface;
+        case 4:
+        case 'ADBE Effect Parade':
+        case 'effects':
+        case 'Effects':
+          return _thisLayerFunction.effect;
+        case 'ADBE Text Properties':
+          return _thisLayerFunction.textInterface;
+        default:
+          return null;
+      }
+    }
+    _thisLayerFunction.getMatrix = getMatrix;
+    _thisLayerFunction.invertPoint = invertPoint;
+    _thisLayerFunction.applyPoint = applyPoint;
+    _thisLayerFunction.toWorld = toWorld;
+    _thisLayerFunction.toWorldVec = toWorldVec;
+    _thisLayerFunction.fromWorld = fromWorld;
+    _thisLayerFunction.fromWorldVec = fromWorldVec;
+    _thisLayerFunction.toComp = toWorld;
+    _thisLayerFunction.fromComp = fromComp;
+    _thisLayerFunction.sampleImage = sampleImage;
+    _thisLayerFunction.sourceRectAtTime = elem.sourceRectAtTime.bind(elem);
+    _thisLayerFunction._elem = elem;
+    transformInterface = TransformExpressionInterface(elem.finalTransform.mProp);
+    var anchorPointDescriptor = getDescriptor(transformInterface, 'anchorPoint');
+    Object.defineProperties(_thisLayerFunction, {
+      hasParent: {
+        get: function () {
+          return elem.hierarchy.length;
+        },
+      },
+      parent: {
+        get: function () {
+          return elem.hierarchy[0].layerInterface;
+        },
+      },
+      rotation: getDescriptor(transformInterface, 'rotation'),
+      scale: getDescriptor(transformInterface, 'scale'),
+      position: getDescriptor(transformInterface, 'position'),
+      opacity: getDescriptor(transformInterface, 'opacity'),
+      anchorPoint: anchorPointDescriptor,
+      anchor_point: anchorPointDescriptor,
+      transform: {
+        get: function () {
+          return transformInterface;
+        },
+      },
+      active: {
+        get: function () {
+          return elem.isInRange;
+        },
+      },
+    });
+
+    _thisLayerFunction.startTime = elem.data.st;
+    _thisLayerFunction.index = elem.data.ind;
+    _thisLayerFunction.source = elem.data.refId;
+    _thisLayerFunction.height = elem.data.ty === 0 ? elem.data.h : 100;
+    _thisLayerFunction.width = elem.data.ty === 0 ? elem.data.w : 100;
+    _thisLayerFunction.inPoint = elem.data.ip / elem.comp.globalData.frameRate;
+    _thisLayerFunction.outPoint = elem.data.op / elem.comp.globalData.frameRate;
+    _thisLayerFunction._name = elem.data.nm;
+
+    _thisLayerFunction.registerMaskInterface = _registerMaskInterface;
+    _thisLayerFunction.registerEffectsInterface = _registerEffectsInterface;
+    return _thisLayerFunction;
+  };
+}());
+
+const propertyGroupFactory = (function () {
+  return function (interfaceFunction, parentPropertyGroup) {
+    return function (val) {
+      val = val === undefined ? 1 : val;
+      if (val <= 0) {
+        return interfaceFunction;
+      }
+      return parentPropertyGroup(val - 1);
+    };
+  };
+}());
+
+const PropertyInterface = (function () {
+  return function (propertyName, propertyGroup) {
+    var interfaceFunction = {
+      _name: propertyName,
+    };
+
+    function _propertyGroup(val) {
+      val = val === undefined ? 1 : val;
+      if (val <= 0) {
+        return interfaceFunction;
+      }
+      return propertyGroup(val - 1);
+    }
+
+    return _propertyGroup;
+  };
+}());
+
+const EffectsExpressionInterface = (function () {
+  var ob = {
+    createEffectsInterface: createEffectsInterface,
+  };
+
+  function createEffectsInterface(elem, propertyGroup) {
+    if (elem.effectsManager) {
+      var effectElements = [];
+      var effectsData = elem.data.ef;
+      var i;
+      var len = elem.effectsManager.effectElements.length;
+      for (i = 0; i < len; i += 1) {
+        effectElements.push(createGroupInterface(effectsData[i], elem.effectsManager.effectElements[i], propertyGroup, elem));
+      }
+
+      var effects = elem.data.ef || [];
+      var groupInterface = function (name) {
+        i = 0;
+        len = effects.length;
+        while (i < len) {
+          if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
+            return effectElements[i];
+          }
+          i += 1;
+        }
+        return null;
+      };
+      Object.defineProperty(groupInterface, 'numProperties', {
+        get: function () {
+          return effects.length;
+        },
+      });
+      return groupInterface;
+    }
+    return null;
+  }
+
+  function createGroupInterface(data, elements, propertyGroup, elem) {
+    function groupInterface(name) {
+      var effects = data.ef;
+      var i = 0;
+      var len = effects.length;
+      while (i < len) {
+        if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
+          if (effects[i].ty === 5) {
+            return effectElements[i];
+          }
+          return effectElements[i]();
+        }
+        i += 1;
+      }
+      throw new Error();
+    }
+    var _propertyGroup = propertyGroupFactory(groupInterface, propertyGroup);
+
+    var effectElements = [];
+    var i;
+    var len = data.ef.length;
+    for (i = 0; i < len; i += 1) {
+      if (data.ef[i].ty === 5) {
+        effectElements.push(createGroupInterface(data.ef[i], elements.effectElements[i], elements.effectElements[i].propertyGroup, elem));
+      } else {
+        effectElements.push(createValueInterface(elements.effectElements[i], data.ef[i].ty, elem, _propertyGroup));
+      }
+    }
+
+    if (data.mn === 'ADBE Color Control') {
+      Object.defineProperty(groupInterface, 'color', {
+        get: function () {
+          return effectElements[0]();
+        },
+      });
+    }
+    Object.defineProperties(groupInterface, {
+      numProperties: {
+        get: function () {
+          return data.np;
+        },
+      },
+      _name: { value: data.nm },
+      propertyGroup: { value: _propertyGroup },
+    });
+    groupInterface.enabled = data.en !== 0;
+    groupInterface.active = groupInterface.enabled;
+    return groupInterface;
+  }
+
+  function createValueInterface(element, type, elem, propertyGroup) {
+    var expressionProperty = ExpressionPropertyInterface(element.p);
+    function interfaceFunction() {
+      if (type === 10) {
+        return elem.comp.compInterface(element.p.v);
+      }
+      return expressionProperty();
+    }
+
+    if (element.p.setGroupProperty) {
+      element.p.setGroupProperty(PropertyInterface('', propertyGroup));
+    }
+
+    return interfaceFunction;
+  }
+
+  return ob;
+}());
+
+const ShapePathInterface = (
+
+  function () {
+    return function pathInterfaceFactory(shape, view, propertyGroup) {
+      var prop = view.sh;
+
+      function interfaceFunction(val) {
+        if (val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2) {
+          return interfaceFunction.path;
+        }
+        return null;
+      }
+
+      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+      prop.setGroupProperty(PropertyInterface('Path', _propertyGroup));
+      Object.defineProperties(interfaceFunction, {
+        path: {
+          get: function () {
+            if (prop.k) {
+              prop.getValue();
+            }
+            return prop;
+          },
+        },
+        shape: {
+          get: function () {
+            if (prop.k) {
+              prop.getValue();
+            }
+            return prop;
+          },
+        },
+        _name: { value: shape.nm },
+        ix: { value: shape.ix },
+        propertyIndex: { value: shape.ix },
+        mn: { value: shape.mn },
+        propertyGroup: { value: propertyGroup },
+      });
+      return interfaceFunction;
+    };
+  }()
+);
+
+const ShapeExpressionInterface = (function () {
+  function iterateElements(shapes, view, propertyGroup) {
+    var arr = [];
+    var i;
+    var len = shapes ? shapes.length : 0;
+    for (i = 0; i < len; i += 1) {
+      if (shapes[i].ty === 'gr') {
+        arr.push(groupInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'fl') {
+        arr.push(fillInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'st') {
+        arr.push(strokeInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'tm') {
+        arr.push(trimInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'tr') {
+        // arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
+      } else if (shapes[i].ty === 'el') {
+        arr.push(ellipseInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'sr') {
+        arr.push(starInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'sh') {
+        arr.push(ShapePathInterface(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'rc') {
+        arr.push(rectInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'rd') {
+        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;
+  }
+
+  function contentsInterfaceFactory(shape, view, propertyGroup) {
+    var interfaces;
+    var interfaceFunction = function _interfaceFunction(value) {
+      var i = 0;
+      var len = interfaces.length;
+      while (i < len) {
+        if (interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value) {
+          return interfaces[i];
+        }
+        i += 1;
+      }
+      if (typeof value === 'number') {
+        return interfaces[value - 1];
+      }
+      return null;
+    };
+
+    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup);
+    interfaceFunction.numProperties = interfaces.length;
+    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
+    interfaceFunction.transform = transformInterface;
+    interfaceFunction.propertyIndex = shape.cix;
+    interfaceFunction._name = shape.nm;
+
+    return interfaceFunction;
+  }
+
+  function groupInterfaceFactory(shape, view, propertyGroup) {
+    var interfaceFunction = function _interfaceFunction(value) {
+      switch (value) {
+        case 'ADBE Vectors Group':
+        case 'Contents':
+        case 2:
+          return interfaceFunction.content;
+          // Not necessary for now. Keeping them here in case a new case appears
+          // case 'ADBE Vector Transform Group':
+          // case 3:
+        default:
+          return interfaceFunction.transform;
+      }
+    };
+    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var content = contentsInterfaceFactory(shape, view, interfaceFunction.propertyGroup);
+    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
+    interfaceFunction.content = content;
+    interfaceFunction.transform = transformInterface;
+    Object.defineProperty(interfaceFunction, '_name', {
+      get: function () {
+        return shape.nm;
+      },
+    });
+    // interfaceFunction.content = interfaceFunction;
+    interfaceFunction.numProperties = shape.np;
+    interfaceFunction.propertyIndex = shape.ix;
+    interfaceFunction.nm = shape.nm;
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function fillInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      if (val === 'Color' || val === 'color') {
+        return interfaceFunction.color;
+      } if (val === 'Opacity' || val === 'opacity') {
+        return interfaceFunction.opacity;
+      }
+      return null;
+    }
+    Object.defineProperties(interfaceFunction, {
+      color: {
+        get: ExpressionPropertyInterface(view.c),
+      },
+      opacity: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      _name: { value: shape.nm },
+      mn: { value: shape.mn },
+    });
+
+    view.c.setGroupProperty(PropertyInterface('Color', propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
+    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 () {
+          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() {
+    function interfaceFunction() {
+      return null;
+    }
+    return interfaceFunction;
+  }
+
+  function strokeInterfaceFactory(shape, view, propertyGroup) {
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup);
+    function addPropertyToDashOb(i) {
+      Object.defineProperty(dashOb, shape.d[i].nm, {
+        get: ExpressionPropertyInterface(view.d.dataProps[i].p),
+      });
+    }
+    var i;
+    var len = shape.d ? shape.d.length : 0;
+    var dashOb = {};
+    for (i = 0; i < len; i += 1) {
+      addPropertyToDashOb(i);
+      view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup);
+    }
+
+    function interfaceFunction(val) {
+      if (val === 'Color' || val === 'color') {
+        return interfaceFunction.color;
+      } if (val === 'Opacity' || val === 'opacity') {
+        return interfaceFunction.opacity;
+      } if (val === 'Stroke Width' || val === 'stroke width') {
+        return interfaceFunction.strokeWidth;
+      }
+      return null;
+    }
+    Object.defineProperties(interfaceFunction, {
+      color: {
+        get: ExpressionPropertyInterface(view.c),
+      },
+      opacity: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      strokeWidth: {
+        get: ExpressionPropertyInterface(view.w),
+      },
+      dash: {
+        get: function () {
+          return dashOb;
+        },
+      },
+      _name: { value: shape.nm },
+      mn: { value: shape.mn },
+    });
+
+    view.c.setGroupProperty(PropertyInterface('Color', _propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    view.w.setGroupProperty(PropertyInterface('Stroke Width', _propertyGroup));
+    return interfaceFunction;
+  }
+
+  function trimInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      if (val === shape.e.ix || val === 'End' || val === 'end') {
+        return interfaceFunction.end;
+      }
+      if (val === shape.s.ix) {
+        return interfaceFunction.start;
+      }
+      if (val === shape.o.ix) {
+        return interfaceFunction.offset;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaceFunction.propertyIndex = shape.ix;
+
+    view.s.setGroupProperty(PropertyInterface('Start', _propertyGroup));
+    view.e.setGroupProperty(PropertyInterface('End', _propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
+    interfaceFunction.propertyIndex = shape.ix;
+    interfaceFunction.propertyGroup = propertyGroup;
+
+    Object.defineProperties(interfaceFunction, {
+      start: {
+        get: ExpressionPropertyInterface(view.s),
+      },
+      end: {
+        get: ExpressionPropertyInterface(view.e),
+      },
+      offset: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function transformInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.a.ix === value || value === 'Anchor Point') {
+        return interfaceFunction.anchorPoint;
+      }
+      if (shape.o.ix === value || value === 'Opacity') {
+        return interfaceFunction.opacity;
+      }
+      if (shape.p.ix === value || value === 'Position') {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value || value === 'Rotation' || value === 'ADBE Vector Rotation') {
+        return interfaceFunction.rotation;
+      }
+      if (shape.s.ix === value || value === 'Scale') {
+        return interfaceFunction.scale;
+      }
+      if ((shape.sk && shape.sk.ix === value) || value === 'Skew') {
+        return interfaceFunction.skew;
+      }
+      if ((shape.sa && shape.sa.ix === value) || value === 'Skew Axis') {
+        return interfaceFunction.skewAxis;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    view.transform.mProps.a.setGroupProperty(PropertyInterface('Anchor Point', _propertyGroup));
+    view.transform.mProps.s.setGroupProperty(PropertyInterface('Scale', _propertyGroup));
+    view.transform.mProps.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+    if (view.transform.mProps.sk) {
+      view.transform.mProps.sk.setGroupProperty(PropertyInterface('Skew', _propertyGroup));
+      view.transform.mProps.sa.setGroupProperty(PropertyInterface('Skew Angle', _propertyGroup));
+    }
+    view.transform.op.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    Object.defineProperties(interfaceFunction, {
+      opacity: {
+        get: ExpressionPropertyInterface(view.transform.mProps.o),
+      },
+      position: {
+        get: ExpressionPropertyInterface(view.transform.mProps.p),
+      },
+      anchorPoint: {
+        get: ExpressionPropertyInterface(view.transform.mProps.a),
+      },
+      scale: {
+        get: ExpressionPropertyInterface(view.transform.mProps.s),
+      },
+      rotation: {
+        get: ExpressionPropertyInterface(view.transform.mProps.r),
+      },
+      skew: {
+        get: ExpressionPropertyInterface(view.transform.mProps.sk),
+      },
+      skewAxis: {
+        get: ExpressionPropertyInterface(view.transform.mProps.sa),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.ty = 'tr';
+    interfaceFunction.mn = shape.mn;
+    interfaceFunction.propertyGroup = propertyGroup;
+    return interfaceFunction;
+  }
+
+  function ellipseInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.s.ix === value) {
+        return interfaceFunction.size;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaceFunction.propertyIndex = shape.ix;
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      size: {
+        get: ExpressionPropertyInterface(prop.s),
+      },
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function starInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value) {
+        return interfaceFunction.rotation;
+      }
+      if (shape.pt.ix === value) {
+        return interfaceFunction.points;
+      }
+      if (shape.or.ix === value || value === 'ADBE Vector Star Outer Radius') {
+        return interfaceFunction.outerRadius;
+      }
+      if (shape.os.ix === value) {
+        return interfaceFunction.outerRoundness;
+      }
+      if (shape.ir && (shape.ir.ix === value || value === 'ADBE Vector Star Inner Radius')) {
+        return interfaceFunction.innerRadius;
+      }
+      if (shape.is && shape.is.ix === value) {
+        return interfaceFunction.innerRoundness;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.or.setGroupProperty(PropertyInterface('Outer Radius', _propertyGroup));
+    prop.os.setGroupProperty(PropertyInterface('Outer Roundness', _propertyGroup));
+    prop.pt.setGroupProperty(PropertyInterface('Points', _propertyGroup));
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+    if (shape.ir) {
+      prop.ir.setGroupProperty(PropertyInterface('Inner Radius', _propertyGroup));
+      prop.is.setGroupProperty(PropertyInterface('Inner Roundness', _propertyGroup));
+    }
+
+    Object.defineProperties(interfaceFunction, {
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      rotation: {
+        get: ExpressionPropertyInterface(prop.r),
+      },
+      points: {
+        get: ExpressionPropertyInterface(prop.pt),
+      },
+      outerRadius: {
+        get: ExpressionPropertyInterface(prop.or),
+      },
+      outerRoundness: {
+        get: ExpressionPropertyInterface(prop.os),
+      },
+      innerRadius: {
+        get: ExpressionPropertyInterface(prop.ir),
+      },
+      innerRoundness: {
+        get: ExpressionPropertyInterface(prop.is),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function rectInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value) {
+        return interfaceFunction.roundness;
+      }
+      if (shape.s.ix === value || value === 'Size' || value === 'ADBE Vector Rect Size') {
+        return interfaceFunction.size;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
+    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      roundness: {
+        get: ExpressionPropertyInterface(prop.r),
+      },
+      size: {
+        get: ExpressionPropertyInterface(prop.s),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function roundedInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.r.ix === value || value === 'Round Corners 1') {
+        return interfaceFunction.radius;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.rd.setGroupProperty(PropertyInterface('Radius', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      radius: {
+        get: ExpressionPropertyInterface(prop.rd),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function repeaterInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.c.ix === value || value === 'Copies') {
+        return interfaceFunction.copies;
+      } if (shape.o.ix === value || value === 'Offset') {
+        return interfaceFunction.offset;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.c.setGroupProperty(PropertyInterface('Copies', _propertyGroup));
+    prop.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
+    Object.defineProperties(interfaceFunction, {
+      copies: {
+        get: ExpressionPropertyInterface(prop.c),
+      },
+      offset: {
+        get: ExpressionPropertyInterface(prop.o),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  return function (shapes, view, propertyGroup) {
+    var interfaces;
+    function _interfaceFunction(value) {
+      if (typeof value === 'number') {
+        value = value === undefined ? 1 : value;
+        if (value === 0) {
+          return propertyGroup;
+        }
+        return interfaces[value - 1];
+      }
+      var i = 0;
+      var len = interfaces.length;
+      while (i < len) {
+        if (interfaces[i]._name === value) {
+          return interfaces[i];
+        }
+        i += 1;
+      }
+      return null;
+    }
+    function parentGroupWrapper() {
+      return propertyGroup;
+    }
+    _interfaceFunction.propertyGroup = propertyGroupFactory(_interfaceFunction, parentGroupWrapper);
+    interfaces = iterateElements(shapes, view, _interfaceFunction.propertyGroup);
+    _interfaceFunction.numProperties = interfaces.length;
+    _interfaceFunction._name = 'Contents';
+    return _interfaceFunction;
+  };
+}());
+
+const TextExpressionInterface = (function () {
+  return function (elem) {
+    var _sourceText;
+    function _thisLayerFunction(name) {
+      switch (name) {
+        case 'ADBE Text Document':
+          return _thisLayerFunction.sourceText;
+        default:
+          return null;
+      }
+    }
+    Object.defineProperty(_thisLayerFunction, 'sourceText', {
+      get: function () {
+        elem.textProperty.getValue();
+        var stringValue = elem.textProperty.currentData.t;
+        if (!_sourceText || stringValue !== _sourceText.value) {
+          _sourceText = new String(stringValue); // eslint-disable-line no-new-wrappers
+          // If stringValue is an empty string, eval returns undefined, so it has to be returned as a String primitive
+          _sourceText.value = stringValue || new String(stringValue); // eslint-disable-line no-new-wrappers
+          Object.defineProperty(_sourceText, 'style', {
+            get: function () {
+              return {
+                fillColor: elem.textProperty.currentData.fc,
+              };
+            },
+          });
+        }
+        return _sourceText;
+      },
+    });
+    return _thisLayerFunction;
+  };
+}());
+
+const FootageInterface = (function () {
+  var outlineInterfaceFactory = (function (elem) {
+    var currentPropertyName = '';
+    var currentProperty = elem.getFootageData();
+    function init() {
+      currentPropertyName = '';
+      currentProperty = elem.getFootageData();
+      return searchProperty;
+    }
+    function searchProperty(value) {
+      if (currentProperty[value]) {
+        currentPropertyName = value;
+        currentProperty = currentProperty[value];
+        if (typeof currentProperty === 'object') {
+          return searchProperty;
+        }
+        return currentProperty;
+      }
+      var propertyNameIndex = value.indexOf(currentPropertyName);
+      if (propertyNameIndex !== -1) {
+        var index = parseInt(value.substr(propertyNameIndex + currentPropertyName.length), 10);
+        currentProperty = currentProperty[index];
+        if (typeof currentProperty === 'object') {
+          return searchProperty;
+        }
+        return currentProperty;
+      }
+      return '';
+    }
+    return init;
+  });
+
+  var dataInterfaceFactory = function (elem) {
+    function interfaceFunction(value) {
+      if (value === 'Outline') {
+        return interfaceFunction.outlineInterface();
+      }
+      return null;
+    }
+
+    interfaceFunction._name = 'Outline';
+    interfaceFunction.outlineInterface = outlineInterfaceFactory(elem);
+    return interfaceFunction;
+  };
+
+  return function (elem) {
+    function _interfaceFunction(value) {
+      if (value === 'Data') {
+        return _interfaceFunction.dataInterface;
+      }
+      return null;
+    }
+
+    _interfaceFunction._name = 'Data';
+    _interfaceFunction.dataInterface = dataInterfaceFactory(elem);
+    return _interfaceFunction;
+  };
+}());
+
+var interfaces = {
+  layer: LayerExpressionInterface,
+  effects: EffectsExpressionInterface,
+  comp: CompExpressionInterface,
+  shape: ShapeExpressionInterface,
+  text: TextExpressionInterface,
+  footage: FootageInterface,
+};
+
+function getInterface(type) {
+  return interfaces[type] || null;
+}
+
+const expressionHelpers = (function () {
+  function searchExpressions(elem, data, prop) {
+    if (data.x) {
+      prop.k = true;
+      prop.x = true;
+      prop.initiateExpression = ExpressionManager.initiateExpression;
+      prop.effectsSequence.push(prop.initiateExpression(elem, data, prop).bind(prop));
+    }
+  }
+
+  function getValueAtTime(frameNum) {
+    frameNum *= this.elem.globalData.frameRate;
+    frameNum -= this.offsetTime;
+    if (frameNum !== this._cachingAtTime.lastFrame) {
+      this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0;
+      this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime);
+      this._cachingAtTime.lastFrame = frameNum;
+    }
+    return this._cachingAtTime.value;
+  }
+
+  function getSpeedAtTime(frameNum) {
+    var delta = -0.01;
+    var v1 = this.getValueAtTime(frameNum);
+    var v2 = this.getValueAtTime(frameNum + delta);
+    var speed = 0;
+    if (v1.length) {
+      var i;
+      for (i = 0; i < v1.length; i += 1) {
+        speed += Math.pow(v2[i] - v1[i], 2);
+      }
+      speed = Math.sqrt(speed) * 100;
+    } else {
+      speed = 0;
+    }
+    return speed;
+  }
+
+  function getVelocityAtTime(frameNum) {
+    if (this.vel !== undefined) {
+      return this.vel;
+    }
+    var delta = -0.001;
+    // frameNum += this.elem.data.st;
+    var v1 = this.getValueAtTime(frameNum);
+    var v2 = this.getValueAtTime(frameNum + delta);
+    var velocity;
+    if (v1.length) {
+      velocity = createTypedArray('float32', v1.length);
+      var i;
+      for (i = 0; i < v1.length; i += 1) {
+        // removing frameRate
+        // if needed, don't add it here
+        // velocity[i] = this.elem.globalData.frameRate*((v2[i] - v1[i])/delta);
+        velocity[i] = (v2[i] - v1[i]) / delta;
+      }
+    } else {
+      velocity = (v2 - v1) / delta;
+    }
+    return velocity;
+  }
+
+  function getStaticValueAtTime() {
+    return this.pv;
+  }
+
+  function setGroupProperty(propertyGroup) {
+    this.propertyGroup = propertyGroup;
+  }
+
+  return {
+    searchExpressions: searchExpressions,
+    getSpeedAtTime: getSpeedAtTime,
+    getVelocityAtTime: getVelocityAtTime,
+    getValueAtTime: getValueAtTime,
+    getStaticValueAtTime: getStaticValueAtTime,
+    setGroupProperty: setGroupProperty,
+  };
+}());
+
+function addPropertyDecorator() {
+  function loopOut(type, duration, durationFlag) {
+    if (!this.k || !this.keyframes) {
+      return this.pv;
+    }
+    type = type ? type.toLowerCase() : '';
+    var currentFrame = this.comp.renderedFrame;
+    var keyframes = this.keyframes;
+    var lastKeyFrame = keyframes[keyframes.length - 1].t;
+    if (currentFrame <= lastKeyFrame) {
+      return this.pv;
+    }
+    var cycleDuration;
+    var firstKeyFrame;
+    if (!durationFlag) {
+      if (!duration || duration > keyframes.length - 1) {
+        duration = keyframes.length - 1;
+      }
+      firstKeyFrame = keyframes[keyframes.length - 1 - duration].t;
+      cycleDuration = lastKeyFrame - firstKeyFrame;
+    } else {
+      if (!duration) {
+        cycleDuration = Math.max(0, lastKeyFrame - this.elem.data.ip);
+      } else {
+        cycleDuration = Math.abs(lastKeyFrame - this.elem.comp.globalData.frameRate * duration);
+      }
+      firstKeyFrame = lastKeyFrame - cycleDuration;
+    }
+    var i;
+    var len;
+    var ret;
+    if (type === 'pingpong') {
+      var iterations = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
+      if (iterations % 2 !== 0) {
+          return this.getValueAtTime(((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      }
+    } else if (type === 'offset') {
+      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+        var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      var repeats = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
+      if (this.pv.length) {
+        ret = new Array(initV.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = (endV[i] - initV[i]) * repeats + current[i];
+        }
+        return ret;
+      }
+      return (endV - initV) * repeats + current;
+    } else if (type === 'continue') {
+      var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+      var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0);
+      if (this.pv.length) {
+        ret = new Array(lastValue.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+            ret[i] = lastValue[i] + (lastValue[i] - nextLastValue[i]) * ((currentFrame - lastKeyFrame) / this.comp.globalData.frameRate) / 0.0005; // eslint-disable-line
+        }
+        return ret;
+      }
+      return lastValue + (lastValue - nextLastValue) * (((currentFrame - lastKeyFrame)) / 0.001);
+    }
+      return this.getValueAtTime((((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+
+  }
+
+  function loopIn(type, duration, durationFlag) {
+    if (!this.k) {
+      return this.pv;
+    }
+    type = type ? type.toLowerCase() : '';
+    var currentFrame = this.comp.renderedFrame;
+    var keyframes = this.keyframes;
+    var firstKeyFrame = keyframes[0].t;
+    if (currentFrame >= firstKeyFrame) {
+      return this.pv;
+    }
+    var cycleDuration;
+    var lastKeyFrame;
+    if (!durationFlag) {
+      if (!duration || duration > keyframes.length - 1) {
+        duration = keyframes.length - 1;
+      }
+      lastKeyFrame = keyframes[duration].t;
+      cycleDuration = lastKeyFrame - firstKeyFrame;
+    } else {
+      if (!duration) {
+        cycleDuration = Math.max(0, this.elem.data.op - firstKeyFrame);
+      } else {
+        cycleDuration = Math.abs(this.elem.comp.globalData.frameRate * duration);
+      }
+      lastKeyFrame = firstKeyFrame + cycleDuration;
+    }
+    var i;
+    var len;
+    var ret;
+    if (type === 'pingpong') {
+      var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration);
+      if (iterations % 2 === 0) {
+          return this.getValueAtTime((((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      }
+    } else if (type === 'offset') {
+      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+      var current = this.getValueAtTime((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration) + firstKeyFrame) / this.comp.globalData.frameRate, 0);
+      var repeats = Math.floor((firstKeyFrame - currentFrame) / cycleDuration) + 1;
+      if (this.pv.length) {
+        ret = new Array(initV.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = current[i] - (endV[i] - initV[i]) * repeats;
+        }
+        return ret;
+      }
+      return current - (endV - initV) * repeats;
+    } else if (type === 'continue') {
+      var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0);
+      if (this.pv.length) {
+        ret = new Array(firstValue.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = firstValue[i] + ((firstValue[i] - nextFirstValue[i]) * (firstKeyFrame - currentFrame)) / 0.001;
+        }
+        return ret;
+      }
+      return firstValue + ((firstValue - nextFirstValue) * (firstKeyFrame - currentFrame)) / 0.001;
+    }
+      return this.getValueAtTime(((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame))) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+
+  }
+
+  function smooth(width, samples) {
+    if (!this.k) {
+      return this.pv;
+    }
+    width = (width || 0.4) * 0.5;
+    samples = Math.floor(samples || 5);
+    if (samples <= 1) {
+      return this.pv;
+    }
+    var currentTime = this.comp.renderedFrame / this.comp.globalData.frameRate;
+    var initFrame = currentTime - width;
+    var endFrame = currentTime + width;
+    var sampleFrequency = samples > 1 ? (endFrame - initFrame) / (samples - 1) : 1;
+    var i = 0;
+    var j = 0;
+    var value;
+    if (this.pv.length) {
+      value = createTypedArray('float32', this.pv.length);
+    } else {
+      value = 0;
+    }
+    var sampleValue;
+    while (i < samples) {
+      sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency);
+      if (this.pv.length) {
+        for (j = 0; j < this.pv.length; j += 1) {
+          value[j] += sampleValue[j];
+        }
+      } else {
+        value += sampleValue;
+      }
+      i += 1;
+    }
+    if (this.pv.length) {
+      for (j = 0; j < this.pv.length; j += 1) {
+        value[j] /= samples;
+      }
+    } else {
+      value /= samples;
+    }
+    return value;
+  }
+
+  function getTransformValueAtTime(time) {
+    if (!this._transformCachingAtTime) {
+      this._transformCachingAtTime = {
+        v: new Matrix(),
+      };
+    }
+    /// /
+    var matrix = this._transformCachingAtTime.v;
+    matrix.cloneFromProps(this.pre.props);
+    if (this.appliedTransformations < 1) {
+      var anchor = this.a.getValueAtTime(time);
+      matrix.translate(
+        -anchor[0] * this.a.mult,
+        -anchor[1] * this.a.mult,
+        anchor[2] * this.a.mult
+      );
+    }
+    if (this.appliedTransformations < 2) {
+      var scale = this.s.getValueAtTime(time);
+      matrix.scale(
+        scale[0] * this.s.mult,
+        scale[1] * this.s.mult,
+        scale[2] * this.s.mult
+      );
+    }
+    if (this.sk && this.appliedTransformations < 3) {
+      var skew = this.sk.getValueAtTime(time);
+      var skewAxis = this.sa.getValueAtTime(time);
+      matrix.skewFromAxis(-skew * this.sk.mult, skewAxis * this.sa.mult);
+    }
+    if (this.r && this.appliedTransformations < 4) {
+      var rotation = this.r.getValueAtTime(time);
+      matrix.rotate(-rotation * this.r.mult);
+    } else if (!this.r && this.appliedTransformations < 4) {
+      var rotationZ = this.rz.getValueAtTime(time);
+      var rotationY = this.ry.getValueAtTime(time);
+      var rotationX = this.rx.getValueAtTime(time);
+      var orientation = this.or.getValueAtTime(time);
+      matrix.rotateZ(-rotationZ * this.rz.mult)
+        .rotateY(rotationY * this.ry.mult)
+        .rotateX(rotationX * this.rx.mult)
+        .rotateZ(-orientation[2] * this.or.mult)
+        .rotateY(orientation[1] * this.or.mult)
+        .rotateX(orientation[0] * this.or.mult);
+    }
+    if (this.data.p && this.data.p.s) {
+      var positionX = this.px.getValueAtTime(time);
+      var positionY = this.py.getValueAtTime(time);
+      if (this.data.p.z) {
+        var positionZ = this.pz.getValueAtTime(time);
+        matrix.translate(
+          positionX * this.px.mult,
+          positionY * this.py.mult,
+          -positionZ * this.pz.mult
+        );
+      } else {
+        matrix.translate(positionX * this.px.mult, positionY * this.py.mult, 0);
+      }
+    } else {
+      var position = this.p.getValueAtTime(time);
+      matrix.translate(
+        position[0] * this.p.mult,
+        position[1] * this.p.mult,
+        -position[2] * this.p.mult
+      );
+    }
+    return matrix;
+    /// /
+  }
+
+  function getTransformStaticValueAtTime() {
+    return this.v.clone(new Matrix());
+  }
+
+  var getTransformProperty = TransformPropertyFactory.getTransformProperty;
+  TransformPropertyFactory.getTransformProperty = function (elem, data, container) {
+    var prop = getTransformProperty(elem, data, container);
+    if (prop.dynamicProperties.length) {
+      prop.getValueAtTime = getTransformValueAtTime.bind(prop);
+    } else {
+      prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop);
+    }
+    prop.setGroupProperty = expressionHelpers.setGroupProperty;
+    return prop;
+  };
+
+  var propertyGetProp = PropertyFactory.getProp;
+  PropertyFactory.getProp = function (elem, data, type, mult, container) {
+    var prop = propertyGetProp(elem, data, type, mult, container);
+    // prop.getVelocityAtTime = getVelocityAtTime;
+    // prop.loopOut = loopOut;
+    // prop.loopIn = loopIn;
+    if (prop.kf) {
+      prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop);
+    } else {
+      prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop);
+    }
+    prop.setGroupProperty = expressionHelpers.setGroupProperty;
+    prop.loopOut = loopOut;
+    prop.loopIn = loopIn;
+    prop.smooth = smooth;
+    prop.getVelocityAtTime = expressionHelpers.getVelocityAtTime.bind(prop);
+    prop.getSpeedAtTime = expressionHelpers.getSpeedAtTime.bind(prop);
+    prop.numKeys = data.a === 1 ? data.k.length : 0;
+    prop.propertyIndex = data.ix;
+    var value = 0;
+    if (type !== 0) {
+      value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length);
+    }
+    prop._cachingAtTime = {
+      lastFrame: initialDefaultFrame,
+      lastIndex: 0,
+      value: value,
+    };
+    expressionHelpers.searchExpressions(elem, data, prop);
+    if (prop.k) {
+      container.addDynamicProperty(prop);
+    }
+
+    return prop;
+  };
+
+  function getShapeValueAtTime(frameNum) {
+    // For now this caching object is created only when needed instead of creating it when the shape is initialized.
+    if (!this._cachingAtTime) {
+      this._cachingAtTime = {
+        shapeValue: shapePool.clone(this.pv),
+        lastIndex: 0,
+        lastTime: initialDefaultFrame,
+      };
+    }
+
+    frameNum *= this.elem.globalData.frameRate;
+    frameNum -= this.offsetTime;
+    if (frameNum !== this._cachingAtTime.lastTime) {
+      this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0;
+      this._cachingAtTime.lastTime = frameNum;
+      this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime);
+    }
+    return this._cachingAtTime.shapeValue;
+  }
+
+  var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction();
+  var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction();
+
+  function ShapeExpressions() {}
+  ShapeExpressions.prototype = {
+    vertices: function (prop, time) {
+      if (this.k) {
+        this.getValue();
+      }
+      var shapePath = this.v;
+      if (time !== undefined) {
+        shapePath = this.getValueAtTime(time, 0);
+      }
+      var i;
+      var len = shapePath._length;
+      var vertices = shapePath[prop];
+      var points = shapePath.v;
+      var arr = createSizedArray(len);
+      for (i = 0; i < len; i += 1) {
+        if (prop === 'i' || prop === 'o') {
+          arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]];
+        } else {
+          arr[i] = [vertices[i][0], vertices[i][1]];
+        }
+      }
+      return arr;
+    },
+    points: function (time) {
+      return this.vertices('v', time);
+    },
+    inTangents: function (time) {
+      return this.vertices('i', time);
+    },
+    outTangents: function (time) {
+      return this.vertices('o', time);
+    },
+    isClosed: function () {
+      return this.v.c;
+    },
+    pointOnPath: function (perc, time) {
+      var shapePath = this.v;
+      if (time !== undefined) {
+        shapePath = this.getValueAtTime(time, 0);
+      }
+      if (!this._segmentsLength) {
+        this._segmentsLength = bez.getSegmentsLength(shapePath);
+      }
+
+      var segmentsLength = this._segmentsLength;
+      var lengths = segmentsLength.lengths;
+      var lengthPos = segmentsLength.totalLength * perc;
+      var i = 0;
+      var len = lengths.length;
+      var accumulatedLength = 0;
+      var pt;
+      while (i < len) {
+        if (accumulatedLength + lengths[i].addedLength > lengthPos) {
+          var initIndex = i;
+          var endIndex = (shapePath.c && i === len - 1) ? 0 : i + 1;
+          var segmentPerc = (lengthPos - accumulatedLength) / lengths[i].addedLength;
+          pt = bez.getPointInSegment(shapePath.v[initIndex], shapePath.v[endIndex], shapePath.o[initIndex], shapePath.i[endIndex], segmentPerc, lengths[i]);
+          break;
+        } else {
+          accumulatedLength += lengths[i].addedLength;
+        }
+        i += 1;
+      }
+      if (!pt) {
+        pt = shapePath.c ? [shapePath.v[0][0], shapePath.v[0][1]] : [shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1]];
+      }
+      return pt;
+    },
+    vectorOnPath: function (perc, time, vectorType) {
+      // perc doesn't use triple equality because it can be a Number object as well as a primitive.
+      if (perc == 1) { // eslint-disable-line eqeqeq
+        perc = this.v.c;
+      } else if (perc == 0) { // eslint-disable-line eqeqeq
+        perc = 0.999;
+      }
+      var pt1 = this.pointOnPath(perc, time);
+      var pt2 = this.pointOnPath(perc + 0.001, time);
+      var xLength = pt2[0] - pt1[0];
+      var yLength = pt2[1] - pt1[1];
+      var magnitude = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2));
+      if (magnitude === 0) {
+        return [0, 0];
+      }
+      var unitVector = vectorType === 'tangent' ? [xLength / magnitude, yLength / magnitude] : [-yLength / magnitude, xLength / magnitude];
+      return unitVector;
+    },
+    tangentOnPath: function (perc, time) {
+      return this.vectorOnPath(perc, time, 'tangent');
+    },
+    normalOnPath: function (perc, time) {
+      return this.vectorOnPath(perc, time, 'normal');
+    },
+    setGroupProperty: expressionHelpers.setGroupProperty,
+    getValueAtTime: expressionHelpers.getStaticValueAtTime,
+  };
+  extendPrototype([ShapeExpressions], ShapePropertyConstructorFunction);
+  extendPrototype([ShapeExpressions], KeyframedShapePropertyConstructorFunction);
+  KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime;
+  KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression;
+
+  var propertyGetShapeProp = ShapePropertyFactory.getShapeProp;
+  ShapePropertyFactory.getShapeProp = function (elem, data, type, arr, trims) {
+    var prop = propertyGetShapeProp(elem, data, type, arr, trims);
+    prop.propertyIndex = data.ix;
+    prop.lock = false;
+    if (type === 3) {
+      expressionHelpers.searchExpressions(elem, data.pt, prop);
+    } else if (type === 4) {
+      expressionHelpers.searchExpressions(elem, data.ks, prop);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  };
+}
+
+function initialize$1() {
+  addPropertyDecorator();
+}
+
+function addDecorator() {
+  function searchExpressions() {
+    if (this.data.d.x) {
+      this.calculateExpression = ExpressionManager.initiateExpression.bind(this)(this.elem, this.data.d, this);
+      this.addEffect(this.getExpressionValue.bind(this));
+      return true;
+    }
+    return null;
+  }
+
+  TextProperty.prototype.getExpressionValue = function (currentValue, text) {
+    var newValue = this.calculateExpression(text);
+    if (currentValue.t !== newValue) {
+      var newData = {};
+      this.copyData(newData, currentValue);
+      newData.t = newValue.toString();
+      newData.__complete = false;
+      return newData;
+    }
+    return currentValue;
+  };
+
+  TextProperty.prototype.searchProperty = function () {
+    var isKeyframed = this.searchKeyframes();
+    var hasExpressions = this.searchExpressions();
+    this.kf = isKeyframed || hasExpressions;
+    return this.kf;
+  };
+
+  TextProperty.prototype.searchExpressions = searchExpressions;
+}
+
+function initialize() {
+  addDecorator();
+}
+
+function SVGComposableEffect() {
+
+}
+SVGComposableEffect.prototype = {
+  createMergeNode: (resultId, ins) => {
+    var feMerge = createNS('feMerge');
+    feMerge.setAttribute('result', resultId);
+    var feMergeNode;
+    var i;
+    for (i = 0; i < ins.length; i += 1) {
+      feMergeNode = createNS('feMergeNode');
+      feMergeNode.setAttribute('in', ins[i]);
+      feMerge.appendChild(feMergeNode);
+      feMerge.appendChild(feMergeNode);
+    }
+    return feMerge;
+  },
+};
+
+var linearFilterValue = '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0';
+
+function SVGTintFilter(filter, filterManager, elem, id, source) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'linearRGB');
+  feColorMatrix.setAttribute('values', linearFilterValue + ' 1 0');
+  this.linearFilter = feColorMatrix;
+  feColorMatrix.setAttribute('result', id + '_tint_1');
+  filter.appendChild(feColorMatrix);
+  feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+  feColorMatrix.setAttribute('values', '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0');
+  feColorMatrix.setAttribute('result', id + '_tint_2');
+  filter.appendChild(feColorMatrix);
+  this.matrixFilter = feColorMatrix;
+  var feMerge = this.createMergeNode(
+    id,
+    [
+      source,
+      id + '_tint_1',
+      id + '_tint_2',
+    ]
+  );
+  filter.appendChild(feMerge);
+}
+extendPrototype([SVGComposableEffect], SVGTintFilter);
+
+SVGTintFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var colorBlack = this.filterManager.effectElements[0].p.v;
+    var colorWhite = this.filterManager.effectElements[1].p.v;
+    var opacity = this.filterManager.effectElements[2].p.v / 100;
+    this.linearFilter.setAttribute('values', linearFilterValue + ' ' + opacity + ' 0');
+    this.matrixFilter.setAttribute('values', (colorWhite[0] - colorBlack[0]) + ' 0 0 0 ' + colorBlack[0] + ' ' + (colorWhite[1] - colorBlack[1]) + ' 0 0 0 ' + colorBlack[1] + ' ' + (colorWhite[2] - colorBlack[2]) + ' 0 0 0 ' + colorBlack[2] + ' 0 0 0 1 0');
+  }
+};
+
+function SVGFillFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+  feColorMatrix.setAttribute('values', '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0');
+  feColorMatrix.setAttribute('result', id);
+  filter.appendChild(feColorMatrix);
+  this.matrixFilter = feColorMatrix;
+}
+
+SVGFillFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var color = this.filterManager.effectElements[2].p.v;
+    var opacity = this.filterManager.effectElements[6].p.v;
+    this.matrixFilter.setAttribute('values', '0 0 0 0 ' + color[0] + ' 0 0 0 0 ' + color[1] + ' 0 0 0 0 ' + color[2] + ' 0 0 0 ' + opacity + ' 0');
+  }
+};
+
+function SVGStrokeEffect(fil, filterManager, elem) {
+  this.initialized = false;
+  this.filterManager = filterManager;
+  this.elem = elem;
+  this.paths = [];
+}
+
+SVGStrokeEffect.prototype.initialize = function () {
+  var elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
+  var path;
+  var groupPath;
+  var i;
+  var len;
+  if (this.filterManager.effectElements[1].p.v === 1) {
+    len = this.elem.maskManager.masksProperties.length;
+    i = 0;
+  } else {
+    i = this.filterManager.effectElements[0].p.v - 1;
+    len = i + 1;
+  }
+  groupPath = createNS('g');
+  groupPath.setAttribute('fill', 'none');
+  groupPath.setAttribute('stroke-linecap', 'round');
+  groupPath.setAttribute('stroke-dashoffset', 1);
+  for (i; i < len; i += 1) {
+    path = createNS('path');
+    groupPath.appendChild(path);
+    this.paths.push({ p: path, m: i });
+  }
+  if (this.filterManager.effectElements[10].p.v === 3) {
+    var mask = createNS('mask');
+    var id = createElementID();
+    mask.setAttribute('id', id);
+    mask.setAttribute('mask-type', 'alpha');
+    mask.appendChild(groupPath);
+    this.elem.globalData.defs.appendChild(mask);
+    var g = createNS('g');
+    g.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+    while (elemChildren[0]) {
+      g.appendChild(elemChildren[0]);
+    }
+    this.elem.layerElement.appendChild(g);
+    this.masker = mask;
+    groupPath.setAttribute('stroke', '#fff');
+  } else if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
+    if (this.filterManager.effectElements[10].p.v === 2) {
+      elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
+      while (elemChildren.length) {
+        this.elem.layerElement.removeChild(elemChildren[0]);
+      }
+    }
+    this.elem.layerElement.appendChild(groupPath);
+    this.elem.layerElement.removeAttribute('mask');
+    groupPath.setAttribute('stroke', '#fff');
+  }
+  this.initialized = true;
+  this.pathMasker = groupPath;
+};
+
+SVGStrokeEffect.prototype.renderFrame = function (forceRender) {
+  if (!this.initialized) {
+    this.initialize();
+  }
+  var i;
+  var len = this.paths.length;
+  var mask;
+  var path;
+  for (i = 0; i < len; i += 1) {
+    if (this.paths[i].m !== -1) {
+      mask = this.elem.maskManager.viewData[this.paths[i].m];
+      path = this.paths[i].p;
+      if (forceRender || this.filterManager._mdf || mask.prop._mdf) {
+        path.setAttribute('d', mask.lastPath);
+      }
+      if (forceRender || this.filterManager.effectElements[9].p._mdf || this.filterManager.effectElements[4].p._mdf || this.filterManager.effectElements[7].p._mdf || this.filterManager.effectElements[8].p._mdf || mask.prop._mdf) {
+        var dasharrayValue;
+        if (this.filterManager.effectElements[7].p.v !== 0 || this.filterManager.effectElements[8].p.v !== 100) {
+          var s = Math.min(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
+          var e = Math.max(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
+          var l = path.getTotalLength();
+          dasharrayValue = '0 0 0 ' + l * s + ' ';
+          var lineLength = l * (e - s);
+          var segment = 1 + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
+          var units = Math.floor(lineLength / segment);
+          var j;
+          for (j = 0; j < units; j += 1) {
+            dasharrayValue += '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01 + ' ';
+          }
+          dasharrayValue += '0 ' + l * 10 + ' 0 0';
+        } else {
+          dasharrayValue = '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
+        }
+        path.setAttribute('stroke-dasharray', dasharrayValue);
+      }
+    }
+  }
+  if (forceRender || this.filterManager.effectElements[4].p._mdf) {
+    this.pathMasker.setAttribute('stroke-width', this.filterManager.effectElements[4].p.v * 2);
+  }
+
+  if (forceRender || this.filterManager.effectElements[6].p._mdf) {
+    this.pathMasker.setAttribute('opacity', this.filterManager.effectElements[6].p.v);
+  }
+  if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
+    if (forceRender || this.filterManager.effectElements[3].p._mdf) {
+      var color = this.filterManager.effectElements[3].p.v;
+      this.pathMasker.setAttribute('stroke', 'rgb(' + bmFloor(color[0] * 255) + ',' + bmFloor(color[1] * 255) + ',' + bmFloor(color[2] * 255) + ')');
+    }
+  }
+};
+
+function SVGTritoneFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'linearRGB');
+  feColorMatrix.setAttribute('values', '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0');
+  filter.appendChild(feColorMatrix);
+  var feComponentTransfer = createNS('feComponentTransfer');
+  feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+  feComponentTransfer.setAttribute('result', id);
+  this.matrixFilter = feComponentTransfer;
+  var feFuncR = createNS('feFuncR');
+  feFuncR.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncR);
+  this.feFuncR = feFuncR;
+  var feFuncG = createNS('feFuncG');
+  feFuncG.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncG);
+  this.feFuncG = feFuncG;
+  var feFuncB = createNS('feFuncB');
+  feFuncB.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncB);
+  this.feFuncB = feFuncB;
+  filter.appendChild(feComponentTransfer);
+}
+
+SVGTritoneFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var color1 = this.filterManager.effectElements[0].p.v;
+    var color2 = this.filterManager.effectElements[1].p.v;
+    var color3 = this.filterManager.effectElements[2].p.v;
+    var tableR = color3[0] + ' ' + color2[0] + ' ' + color1[0];
+    var tableG = color3[1] + ' ' + color2[1] + ' ' + color1[1];
+    var tableB = color3[2] + ' ' + color2[2] + ' ' + color1[2];
+    this.feFuncR.setAttribute('tableValues', tableR);
+    this.feFuncG.setAttribute('tableValues', tableG);
+    this.feFuncB.setAttribute('tableValues', tableB);
+  }
+};
+
+function SVGProLevelsFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var effectElements = this.filterManager.effectElements;
+  var feComponentTransfer = createNS('feComponentTransfer');
+
+  // Red
+  if (effectElements[10].p.k || effectElements[10].p.v !== 0 || effectElements[11].p.k || effectElements[11].p.v !== 1 || effectElements[12].p.k || effectElements[12].p.v !== 1 || effectElements[13].p.k || effectElements[13].p.v !== 0 || effectElements[14].p.k || effectElements[14].p.v !== 1) {
+    this.feFuncR = this.createFeFunc('feFuncR', feComponentTransfer);
+  }
+  // Green
+  if (effectElements[17].p.k || effectElements[17].p.v !== 0 || effectElements[18].p.k || effectElements[18].p.v !== 1 || effectElements[19].p.k || effectElements[19].p.v !== 1 || effectElements[20].p.k || effectElements[20].p.v !== 0 || effectElements[21].p.k || effectElements[21].p.v !== 1) {
+    this.feFuncG = this.createFeFunc('feFuncG', feComponentTransfer);
+  }
+  // Blue
+  if (effectElements[24].p.k || effectElements[24].p.v !== 0 || effectElements[25].p.k || effectElements[25].p.v !== 1 || effectElements[26].p.k || effectElements[26].p.v !== 1 || effectElements[27].p.k || effectElements[27].p.v !== 0 || effectElements[28].p.k || effectElements[28].p.v !== 1) {
+    this.feFuncB = this.createFeFunc('feFuncB', feComponentTransfer);
+  }
+  // Alpha
+  if (effectElements[31].p.k || effectElements[31].p.v !== 0 || effectElements[32].p.k || effectElements[32].p.v !== 1 || effectElements[33].p.k || effectElements[33].p.v !== 1 || effectElements[34].p.k || effectElements[34].p.v !== 0 || effectElements[35].p.k || effectElements[35].p.v !== 1) {
+    this.feFuncA = this.createFeFunc('feFuncA', feComponentTransfer);
+  }
+  // RGB
+  if (this.feFuncR || this.feFuncG || this.feFuncB || this.feFuncA) {
+    feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+    filter.appendChild(feComponentTransfer);
+  }
+
+  if (effectElements[3].p.k || effectElements[3].p.v !== 0 || effectElements[4].p.k || effectElements[4].p.v !== 1 || effectElements[5].p.k || effectElements[5].p.v !== 1 || effectElements[6].p.k || effectElements[6].p.v !== 0 || effectElements[7].p.k || effectElements[7].p.v !== 1) {
+    feComponentTransfer = createNS('feComponentTransfer');
+    feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+    feComponentTransfer.setAttribute('result', id);
+    filter.appendChild(feComponentTransfer);
+    this.feFuncRComposed = this.createFeFunc('feFuncR', feComponentTransfer);
+    this.feFuncGComposed = this.createFeFunc('feFuncG', feComponentTransfer);
+    this.feFuncBComposed = this.createFeFunc('feFuncB', feComponentTransfer);
+  }
+}
+
+SVGProLevelsFilter.prototype.createFeFunc = function (type, feComponentTransfer) {
+  var feFunc = createNS(type);
+  feFunc.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFunc);
+  return feFunc;
+};
+
+SVGProLevelsFilter.prototype.getTableValue = function (inputBlack, inputWhite, gamma, outputBlack, outputWhite) {
+  var cnt = 0;
+  var segments = 256;
+  var perc;
+  var min = Math.min(inputBlack, inputWhite);
+  var max = Math.max(inputBlack, inputWhite);
+  var table = Array.call(null, { length: segments });
+  var colorValue;
+  var pos = 0;
+  var outputDelta = outputWhite - outputBlack;
+  var inputDelta = inputWhite - inputBlack;
+  while (cnt <= 256) {
+    perc = cnt / 256;
+    if (perc <= min) {
+      colorValue = inputDelta < 0 ? outputWhite : outputBlack;
+    } else if (perc >= max) {
+      colorValue = inputDelta < 0 ? outputBlack : outputWhite;
+    } else {
+      colorValue = (outputBlack + outputDelta * Math.pow((perc - inputBlack) / inputDelta, 1 / gamma));
+    }
+    table[pos] = colorValue;
+    pos += 1;
+    cnt += 256 / (segments - 1);
+  }
+  return table.join(' ');
+};
+
+SVGProLevelsFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var val;
+    var effectElements = this.filterManager.effectElements;
+    if (this.feFuncRComposed && (forceRender || effectElements[3].p._mdf || effectElements[4].p._mdf || effectElements[5].p._mdf || effectElements[6].p._mdf || effectElements[7].p._mdf)) {
+      val = this.getTableValue(effectElements[3].p.v, effectElements[4].p.v, effectElements[5].p.v, effectElements[6].p.v, effectElements[7].p.v);
+      this.feFuncRComposed.setAttribute('tableValues', val);
+      this.feFuncGComposed.setAttribute('tableValues', val);
+      this.feFuncBComposed.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncR && (forceRender || effectElements[10].p._mdf || effectElements[11].p._mdf || effectElements[12].p._mdf || effectElements[13].p._mdf || effectElements[14].p._mdf)) {
+      val = this.getTableValue(effectElements[10].p.v, effectElements[11].p.v, effectElements[12].p.v, effectElements[13].p.v, effectElements[14].p.v);
+      this.feFuncR.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncG && (forceRender || effectElements[17].p._mdf || effectElements[18].p._mdf || effectElements[19].p._mdf || effectElements[20].p._mdf || effectElements[21].p._mdf)) {
+      val = this.getTableValue(effectElements[17].p.v, effectElements[18].p.v, effectElements[19].p.v, effectElements[20].p.v, effectElements[21].p.v);
+      this.feFuncG.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncB && (forceRender || effectElements[24].p._mdf || effectElements[25].p._mdf || effectElements[26].p._mdf || effectElements[27].p._mdf || effectElements[28].p._mdf)) {
+      val = this.getTableValue(effectElements[24].p.v, effectElements[25].p.v, effectElements[26].p.v, effectElements[27].p.v, effectElements[28].p.v);
+      this.feFuncB.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncA && (forceRender || effectElements[31].p._mdf || effectElements[32].p._mdf || effectElements[33].p._mdf || effectElements[34].p._mdf || effectElements[35].p._mdf)) {
+      val = this.getTableValue(effectElements[31].p.v, effectElements[32].p.v, effectElements[33].p.v, effectElements[34].p.v, effectElements[35].p.v);
+      this.feFuncA.setAttribute('tableValues', val);
+    }
+  }
+};
+
+function SVGDropShadowEffect(filter, filterManager, elem, id, source) {
+  var globalFilterSize = filterManager.container.globalData.renderConfig.filterSize;
+  var filterSize = filterManager.data.fs || globalFilterSize;
+  filter.setAttribute('x', filterSize.x || globalFilterSize.x);
+  filter.setAttribute('y', filterSize.y || globalFilterSize.y);
+  filter.setAttribute('width', filterSize.width || globalFilterSize.width);
+  filter.setAttribute('height', filterSize.height || globalFilterSize.height);
+  this.filterManager = filterManager;
+
+  var feGaussianBlur = createNS('feGaussianBlur');
+  feGaussianBlur.setAttribute('in', 'SourceAlpha');
+  feGaussianBlur.setAttribute('result', id + '_drop_shadow_1');
+  feGaussianBlur.setAttribute('stdDeviation', '0');
+  this.feGaussianBlur = feGaussianBlur;
+  filter.appendChild(feGaussianBlur);
+
+  var feOffset = createNS('feOffset');
+  feOffset.setAttribute('dx', '25');
+  feOffset.setAttribute('dy', '0');
+  feOffset.setAttribute('in', id + '_drop_shadow_1');
+  feOffset.setAttribute('result', id + '_drop_shadow_2');
+  this.feOffset = feOffset;
+  filter.appendChild(feOffset);
+  var feFlood = createNS('feFlood');
+  feFlood.setAttribute('flood-color', '#00ff00');
+  feFlood.setAttribute('flood-opacity', '1');
+  feFlood.setAttribute('result', id + '_drop_shadow_3');
+  this.feFlood = feFlood;
+  filter.appendChild(feFlood);
+
+  var feComposite = createNS('feComposite');
+  feComposite.setAttribute('in', id + '_drop_shadow_3');
+  feComposite.setAttribute('in2', id + '_drop_shadow_2');
+  feComposite.setAttribute('operator', 'in');
+  feComposite.setAttribute('result', id + '_drop_shadow_4');
+  filter.appendChild(feComposite);
+
+  var feMerge = this.createMergeNode(
+    id,
+    [
+      id + '_drop_shadow_4',
+      source,
+    ]
+  );
+  filter.appendChild(feMerge);
+  //
+}
+extendPrototype([SVGComposableEffect], SVGDropShadowEffect);
+
+SVGDropShadowEffect.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    if (forceRender || this.filterManager.effectElements[4].p._mdf) {
+      this.feGaussianBlur.setAttribute('stdDeviation', this.filterManager.effectElements[4].p.v / 4);
+    }
+    if (forceRender || this.filterManager.effectElements[0].p._mdf) {
+      var col = this.filterManager.effectElements[0].p.v;
+      this.feFlood.setAttribute('flood-color', rgbToHex(Math.round(col[0] * 255), Math.round(col[1] * 255), Math.round(col[2] * 255)));
+    }
+    if (forceRender || this.filterManager.effectElements[1].p._mdf) {
+      this.feFlood.setAttribute('flood-opacity', this.filterManager.effectElements[1].p.v / 255);
+    }
+    if (forceRender || this.filterManager.effectElements[2].p._mdf || this.filterManager.effectElements[3].p._mdf) {
+      var distance = this.filterManager.effectElements[3].p.v;
+      var angle = (this.filterManager.effectElements[2].p.v - 90) * degToRads;
+      var x = distance * Math.cos(angle);
+      var y = distance * Math.sin(angle);
+      this.feOffset.setAttribute('dx', x);
+      this.feOffset.setAttribute('dy', y);
+    }
+  }
+};
+
+var _svgMatteSymbols = [];
+
+function SVGMatte3Effect(filterElem, filterManager, elem) {
+  this.initialized = false;
+  this.filterManager = filterManager;
+  this.filterElem = filterElem;
+  this.elem = elem;
+  elem.matteElement = createNS('g');
+  elem.matteElement.appendChild(elem.layerElement);
+  elem.matteElement.appendChild(elem.transformedElement);
+  elem.baseElement = elem.matteElement;
+}
+
+SVGMatte3Effect.prototype.findSymbol = function (mask) {
+  var i = 0;
+  var len = _svgMatteSymbols.length;
+  while (i < len) {
+    if (_svgMatteSymbols[i] === mask) {
+      return _svgMatteSymbols[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+SVGMatte3Effect.prototype.replaceInParent = function (mask, symbolId) {
+  var parentNode = mask.layerElement.parentNode;
+  if (!parentNode) {
+    return;
+  }
+  var children = parentNode.children;
+  var i = 0;
+  var len = children.length;
+  while (i < len) {
+    if (children[i] === mask.layerElement) {
+      break;
+    }
+    i += 1;
+  }
+  var nextChild;
+  if (i <= len - 2) {
+    nextChild = children[i + 1];
+  }
+  var useElem = createNS('use');
+  useElem.setAttribute('href', '#' + symbolId);
+  if (nextChild) {
+    parentNode.insertBefore(useElem, nextChild);
+  } else {
+    parentNode.appendChild(useElem);
+  }
+};
+
+SVGMatte3Effect.prototype.setElementAsMask = function (elem, mask) {
+  if (!this.findSymbol(mask)) {
+    var symbolId = createElementID();
+    var masker = createNS('mask');
+    masker.setAttribute('id', mask.layerId);
+    masker.setAttribute('mask-type', 'alpha');
+    _svgMatteSymbols.push(mask);
+    var defs = elem.globalData.defs;
+    defs.appendChild(masker);
+    var symbol = createNS('symbol');
+    symbol.setAttribute('id', symbolId);
+    this.replaceInParent(mask, symbolId);
+    symbol.appendChild(mask.layerElement);
+    defs.appendChild(symbol);
+    var useElem = createNS('use');
+    useElem.setAttribute('href', '#' + symbolId);
+    masker.appendChild(useElem);
+    mask.data.hd = false;
+    mask.show();
+  }
+  elem.setMatte(mask.layerId);
+};
+
+SVGMatte3Effect.prototype.initialize = function () {
+  var ind = this.filterManager.effectElements[0].p.v;
+  var elements = this.elem.comp.elements;
+  var i = 0;
+  var len = elements.length;
+  while (i < len) {
+    if (elements[i] && elements[i].data.ind === ind) {
+      this.setElementAsMask(this.elem, elements[i]);
+    }
+    i += 1;
+  }
+  this.initialized = true;
+};
+
+SVGMatte3Effect.prototype.renderFrame = function () {
+  if (!this.initialized) {
+    this.initialize();
+  }
+};
+
+function SVGGaussianBlurEffect(filter, filterManager, elem, id) {
+  // Outset the filter region by 100% on all sides to accommodate blur expansion.
+  filter.setAttribute('x', '-100%');
+  filter.setAttribute('y', '-100%');
+  filter.setAttribute('width', '300%');
+  filter.setAttribute('height', '300%');
+
+  this.filterManager = filterManager;
+  var feGaussianBlur = createNS('feGaussianBlur');
+  feGaussianBlur.setAttribute('result', id);
+  filter.appendChild(feGaussianBlur);
+  this.feGaussianBlur = feGaussianBlur;
+}
+
+SVGGaussianBlurEffect.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    // Empirical value, matching AE's blur appearance.
+    var kBlurrinessToSigma = 0.3;
+    var sigma = this.filterManager.effectElements[0].p.v * kBlurrinessToSigma;
+
+    // Dimensions mapping:
+    //
+    //   1 -> horizontal & vertical
+    //   2 -> horizontal only
+    //   3 -> vertical only
+    //
+    var dimensions = this.filterManager.effectElements[1].p.v;
+    var sigmaX = (dimensions == 3) ? 0 : sigma; // eslint-disable-line eqeqeq
+    var sigmaY = (dimensions == 2) ? 0 : sigma; // eslint-disable-line eqeqeq
+
+    this.feGaussianBlur.setAttribute('stdDeviation', sigmaX + ' ' + sigmaY);
+
+    // Repeat edges mapping:
+    //
+    //   0 -> off -> duplicate
+    //   1 -> on  -> wrap
+    var edgeMode = (this.filterManager.effectElements[2].p.v == 1) ? 'wrap' : 'duplicate'; // eslint-disable-line eqeqeq
+    this.feGaussianBlur.setAttribute('edgeMode', edgeMode);
+  }
+};
+
+function TransformEffect() {
+}
+
+TransformEffect.prototype.init = function (effectsManager) {
+  this.effectsManager = effectsManager;
+  this.type = effectTypes.TRANSFORM_EFFECT;
+  this.matrix = new Matrix();
+  this.opacity = -1;
+  this._mdf = false;
+  this._opMdf = false;
+};
+
+TransformEffect.prototype.renderFrame = function (forceFrame) {
+  this._opMdf = false;
+  this._mdf = false;
+  if (forceFrame || this.effectsManager._mdf) {
+    var effectElements = this.effectsManager.effectElements;
+    var anchor = effectElements[0].p.v;
+    var position = effectElements[1].p.v;
+    var isUniformScale = effectElements[2].p.v === 1;
+    var scaleHeight = effectElements[3].p.v;
+    var scaleWidth = isUniformScale ? scaleHeight : effectElements[4].p.v;
+    var skew = effectElements[5].p.v;
+    var skewAxis = effectElements[6].p.v;
+    var rotation = effectElements[7].p.v;
+    this.matrix.reset();
+    this.matrix.translate(-anchor[0], -anchor[1], anchor[2]);
+    this.matrix.scale(scaleWidth * 0.01, scaleHeight * 0.01, 1);
+    this.matrix.rotate(-rotation * degToRads);
+    this.matrix.skewFromAxis(-skew * degToRads, (skewAxis + 90) * degToRads);
+    this.matrix.translate(position[0], position[1], 0);
+    this._mdf = true;
+    if (this.opacity !== effectElements[8].p.v) {
+      this.opacity = effectElements[8].p.v;
+      this._opMdf = true;
+    }
+  }
+};
+
+function SVGTransformEffect(_, filterManager) {
+  this.init(filterManager);
+}
+
+extendPrototype([TransformEffect], SVGTransformEffect);
+
+// Registering expression plugin
+setExpressionsPlugin(Expressions);
+setExpressionInterfaces(getInterface);
+initialize$1();
+initialize();
+registerEffect(20, SVGTintFilter, true);
+registerEffect(21, SVGFillFilter, true);
+registerEffect(22, SVGStrokeEffect, false);
+registerEffect(23, SVGTritoneFilter, true);
+registerEffect(24, SVGProLevelsFilter, true);
+registerEffect(25, SVGDropShadowEffect, true);
+registerEffect(28, SVGMatte3Effect, false);
+registerEffect(29, SVGGaussianBlurEffect, true);
+registerEffect(35, SVGTransformEffect, false);
+
+exports["default"] = lottie;
diff --git a/build/player/esm/lottie.min.js b/build/player/esm/lottie.min.js
new file mode 100644
index 0000000..7a2460c
--- /dev/null
+++ b/build/player/esm/lottie.min.js
@@ -0,0 +1,18127 @@
+const svgNS = 'http://www.w3.org/2000/svg';
+
+let locationHref = '';
+let _useWebWorker = false;
+
+const initialDefaultFrame = -999999;
+
+const setWebWorker = (flag) => { _useWebWorker = !!flag; };
+const getWebWorker = () => _useWebWorker;
+
+const setLocationHref = (value) => { locationHref = value; };
+const getLocationHref = () => locationHref;
+
+function createTag(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElement(type);
+}
+
+function extendPrototype(sources, destination) {
+  var i;
+  var len = sources.length;
+  var sourcePrototype;
+  for (i = 0; i < len; i += 1) {
+    sourcePrototype = sources[i].prototype;
+    for (var attr in sourcePrototype) {
+      if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
+    }
+  }
+}
+
+function getDescriptor(object, prop) {
+  return Object.getOwnPropertyDescriptor(object, prop);
+}
+
+function createProxyFunction(prototype) {
+  function ProxyFunction() {}
+  ProxyFunction.prototype = prototype;
+  return ProxyFunction;
+}
+
+// import Howl from '../../3rd_party/howler';
+
+const audioControllerFactory = (function () {
+  function AudioController(audioFactory) {
+    this.audios = [];
+    this.audioFactory = audioFactory;
+    this._volume = 1;
+    this._isMuted = false;
+  }
+
+  AudioController.prototype = {
+    addAudio: function (audio) {
+      this.audios.push(audio);
+    },
+    pause: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].pause();
+      }
+    },
+    resume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].resume();
+      }
+    },
+    setRate: function (rateValue) {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].setRate(rateValue);
+      }
+    },
+    createAudio: function (assetPath) {
+      if (this.audioFactory) {
+        return this.audioFactory(assetPath);
+      } if (window.Howl) {
+        return new window.Howl({
+          src: [assetPath],
+        });
+      }
+      return {
+        isPlaying: false,
+        play: function () { this.isPlaying = true; },
+        seek: function () { this.isPlaying = false; },
+        playing: function () {},
+        rate: function () {},
+        setVolume: function () {},
+      };
+    },
+    setAudioFactory: function (audioFactory) {
+      this.audioFactory = audioFactory;
+    },
+    setVolume: function (value) {
+      this._volume = value;
+      this._updateVolume();
+    },
+    mute: function () {
+      this._isMuted = true;
+      this._updateVolume();
+    },
+    unmute: function () {
+      this._isMuted = false;
+      this._updateVolume();
+    },
+    getVolume: function () {
+      return this._volume;
+    },
+    _updateVolume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
+      }
+    },
+  };
+
+  return function () {
+    return new AudioController();
+  };
+}());
+
+const createTypedArray = (function () {
+  function createRegularArray(type, len) {
+    var i = 0;
+    var arr = [];
+    var value;
+    switch (type) {
+      case 'int16':
+      case 'uint8c':
+        value = 1;
+        break;
+      default:
+        value = 1.1;
+        break;
+    }
+    for (i = 0; i < len; i += 1) {
+      arr.push(value);
+    }
+    return arr;
+  }
+  function createTypedArrayFactory(type, len) {
+    if (type === 'float32') {
+      return new Float32Array(len);
+    } if (type === 'int16') {
+      return new Int16Array(len);
+    } if (type === 'uint8c') {
+      return new Uint8ClampedArray(len);
+    }
+    return createRegularArray(type, len);
+  }
+  if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
+    return createTypedArrayFactory;
+  }
+  return createRegularArray;
+}());
+
+function createSizedArray(len) {
+  return Array.apply(null, { length: len });
+}
+
+let subframeEnabled = true;
+let expressionsPlugin = null;
+let expressionsInterfaces = null;
+let idPrefix$1 = '';
+const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+let _shouldRoundValues = false;
+const bmPow = Math.pow;
+const bmSqrt = Math.sqrt;
+const bmFloor = Math.floor;
+const bmMax = Math.max;
+const bmMin = Math.min;
+
+const BMMath = {};
+(function () {
+  var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
+  var i;
+  var len = propertyNames.length;
+  for (i = 0; i < len; i += 1) {
+    BMMath[propertyNames[i]] = Math[propertyNames[i]];
+  }
+}());
+
+function ProjectInterface$1() { return {}; }
+BMMath.random = Math.random;
+BMMath.abs = function (val) {
+  var tOfVal = typeof val;
+  if (tOfVal === 'object' && val.length) {
+    var absArr = createSizedArray(val.length);
+    var i;
+    var len = val.length;
+    for (i = 0; i < len; i += 1) {
+      absArr[i] = Math.abs(val[i]);
+    }
+    return absArr;
+  }
+  return Math.abs(val);
+};
+let defaultCurveSegments = 150;
+const degToRads = Math.PI / 180;
+const roundCorner = 0.5519;
+
+function roundValues(flag) {
+  _shouldRoundValues = !!flag;
+}
+
+function bmRnd(value) {
+  if (_shouldRoundValues) {
+    return Math.round(value);
+  }
+  return value;
+}
+
+function styleDiv(element) {
+  element.style.position = 'absolute';
+  element.style.top = 0;
+  element.style.left = 0;
+  element.style.display = 'block';
+  element.style.transformOrigin = '0 0';
+  element.style.webkitTransformOrigin = '0 0';
+  element.style.backfaceVisibility = 'visible';
+  element.style.webkitBackfaceVisibility = 'visible';
+  element.style.transformStyle = 'preserve-3d';
+  element.style.webkitTransformStyle = 'preserve-3d';
+  element.style.mozTransformStyle = 'preserve-3d';
+}
+
+function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
+  this.type = type;
+  this.currentTime = currentTime;
+  this.totalTime = totalTime;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteEvent(type, frameMultiplier) {
+  this.type = type;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
+  this.type = type;
+  this.currentLoop = currentLoop;
+  this.totalLoops = totalLoops;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMSegmentStartEvent(type, firstFrame, totalFrames) {
+  this.type = type;
+  this.firstFrame = firstFrame;
+  this.totalFrames = totalFrames;
+}
+
+function BMDestroyEvent(type, target) {
+  this.type = type;
+  this.target = target;
+}
+
+function BMRenderFrameErrorEvent(nativeError, currentTime) {
+  this.type = 'renderFrameError';
+  this.nativeError = nativeError;
+  this.currentTime = currentTime;
+}
+
+function BMConfigErrorEvent(nativeError) {
+  this.type = 'configError';
+  this.nativeError = nativeError;
+}
+
+function BMAnimationConfigErrorEvent(type, nativeError) {
+  this.type = type;
+  this.nativeError = nativeError;
+}
+
+const createElementID = (function () {
+  var _count = 0;
+  return function createID() {
+    _count += 1;
+    return idPrefix$1 + '__lottie_element_' + _count;
+  };
+}());
+
+function HSVtoRGB(h, s, v) {
+  var r;
+  var g;
+  var b;
+  var i;
+  var f;
+  var p;
+  var q;
+  var t;
+  i = Math.floor(h * 6);
+  f = h * 6 - i;
+  p = v * (1 - s);
+  q = v * (1 - f * s);
+  t = v * (1 - (1 - f) * s);
+  switch (i % 6) {
+    case 0: r = v; g = t; b = p; break;
+    case 1: r = q; g = v; b = p; break;
+    case 2: r = p; g = v; b = t; break;
+    case 3: r = p; g = q; b = v; break;
+    case 4: r = t; g = p; b = v; break;
+    case 5: r = v; g = p; b = q; break;
+    default: break;
+  }
+  return [r,
+    g,
+    b];
+}
+
+function RGBtoHSV(r, g, b) {
+  var max = Math.max(r, g, b);
+  var min = Math.min(r, g, b);
+  var d = max - min;
+  var h;
+  var s = (max === 0 ? 0 : d / max);
+  var v = max / 255;
+
+  switch (max) {
+    case min: h = 0; break;
+    case r: h = (g - b) + d * (g < b ? 6 : 0); h /= 6 * d; break;
+    case g: h = (b - r) + d * 2; h /= 6 * d; break;
+    case b: h = (r - g) + d * 4; h /= 6 * d; break;
+    default: break;
+  }
+
+  return [
+    h,
+    s,
+    v,
+  ];
+}
+
+function addSaturationToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[1] += offset;
+  if (hsv[1] > 1) {
+    hsv[1] = 1;
+  } else if (hsv[1] <= 0) {
+    hsv[1] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addBrightnessToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[2] += offset;
+  if (hsv[2] > 1) {
+    hsv[2] = 1;
+  } else if (hsv[2] < 0) {
+    hsv[2] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addHueToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[0] += offset / 360;
+  if (hsv[0] > 1) {
+    hsv[0] -= 1;
+  } else if (hsv[0] < 0) {
+    hsv[0] += 1;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+const rgbToHex = (function () {
+  var colorMap = [];
+  var i;
+  var hex;
+  for (i = 0; i < 256; i += 1) {
+    hex = i.toString(16);
+    colorMap[i] = hex.length === 1 ? '0' + hex : hex;
+  }
+
+  return function (r, g, b) {
+    if (r < 0) {
+      r = 0;
+    }
+    if (g < 0) {
+      g = 0;
+    }
+    if (b < 0) {
+      b = 0;
+    }
+    return '#' + colorMap[r] + colorMap[g] + colorMap[b];
+  };
+}());
+
+const setSubframeEnabled = (flag) => { subframeEnabled = !!flag; };
+const getSubframeEnabled = () => subframeEnabled;
+const setExpressionsPlugin = (value) => { expressionsPlugin = value; };
+const getExpressionsPlugin = () => expressionsPlugin;
+const setExpressionInterfaces = (value) => { expressionsInterfaces = value; };
+const getExpressionInterfaces = () => expressionsInterfaces;
+const setDefaultCurveSegments = (value) => { defaultCurveSegments = value; };
+const getDefaultCurveSegments = () => defaultCurveSegments;
+const setIdPrefix = (value) => { idPrefix$1 = value; };
+const getIdPrefix = () => idPrefix$1;
+
+function createNS(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElementNS(svgNS, type);
+}
+
+const dataManager = (function () {
+  var _counterId = 1;
+  var processes = [];
+  var workerFn;
+  var workerInstance;
+  var workerProxy = {
+    onmessage: function () {
+
+    },
+    postMessage: function (path) {
+      workerFn({
+        data: path,
+      });
+    },
+  };
+  var _workerSelf = {
+    postMessage: function (data) {
+      workerProxy.onmessage({
+        data: data,
+      });
+    },
+  };
+  function createWorker(fn) {
+    if (window.Worker && window.Blob && getWebWorker()) {
+      var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      var url = URL.createObjectURL(blob);
+      return new Worker(url);
+    }
+    workerFn = fn;
+    return workerProxy;
+  }
+
+  function setupWorker() {
+    if (!workerInstance) {
+      workerInstance = createWorker(function workerStart(e) {
+        function dataFunctionManager() {
+          function completeLayers(layers, comps) {
+            var layerData;
+            var i;
+            var len = layers.length;
+            var j;
+            var jLen;
+            var k;
+            var kLen;
+            for (i = 0; i < len; i += 1) {
+              layerData = layers[i];
+              if (('ks' in layerData) && !layerData.completed) {
+                layerData.completed = true;
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      convertPathsToAbsoluteValues(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) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 0) {
+                  layerData.layers = findCompLayers(layerData.refId, comps);
+                  completeLayers(layerData.layers, comps);
+                } else if (layerData.ty === 4) {
+                  completeShapes(layerData.shapes);
+                } else if (layerData.ty === 5) {
+                  completeText(layerData);
+                }
+              }
+            }
+          }
+
+          function completeChars(chars, assets) {
+            if (chars) {
+              var i = 0;
+              var len = chars.length;
+              for (i = 0; i < len; i += 1) {
+                if (chars[i].t === 1) {
+                  // var compData = findComp(chars[i].data.refId, assets);
+                  chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                  // chars[i].data.ip = 0;
+                  // chars[i].data.op = 99999;
+                  // chars[i].data.st = 0;
+                  // chars[i].data.sr = 1;
+                  // chars[i].w = compData.w;
+                  // chars[i].data.ks = {
+                  //   a: { k: [0, 0, 0], a: 0 },
+                  //   p: { k: [0, -compData.h, 0], a: 0 },
+                  //   r: { k: 0, a: 0 },
+                  //   s: { k: [100, 100], a: 0 },
+                  //   o: { k: 100, a: 0 },
+                  // };
+                  completeLayers(chars[i].data.layers, assets);
+                }
+              }
+            }
+          }
+
+          function findComp(id, comps) {
+            var i = 0;
+            var len = comps.length;
+            while (i < len) {
+              if (comps[i].id === id) {
+                return comps[i];
+              }
+              i += 1;
+            }
+            return null;
+          }
+
+          function findCompLayers(id, comps) {
+            var comp = findComp(id, comps);
+            if (comp) {
+              if (!comp.layers.__used) {
+                comp.layers.__used = true;
+                return comp.layers;
+              }
+              return JSON.parse(JSON.stringify(comp.layers));
+            }
+            return null;
+          }
+
+          function completeShapes(arr) {
+            var i;
+            var len = arr.length;
+            var j;
+            var jLen;
+            for (i = len - 1; i >= 0; i -= 1) {
+              if (arr[i].ty === 'sh') {
+                if (arr[i].ks.k.i) {
+                  convertPathsToAbsoluteValues(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) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
+                    }
+                    if (arr[i].ks.k[j].e) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
+                    }
+                  }
+                }
+              } else if (arr[i].ty === 'gr') {
+                completeShapes(arr[i].it);
+              }
+            }
+          }
+
+          function convertPathsToAbsoluteValues(path) {
+            var i;
+            var len = path.i.length;
+            for (i = 0; i < len; i += 1) {
+              path.i[i][0] += path.v[i][0];
+              path.i[i][1] += path.v[i][1];
+              path.o[i][0] += path.v[i][0];
+              path.o[i][1] += path.v[i][1];
+            }
+          }
+
+          function checkVersion(minimum, animVersionString) {
+            var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
+            if (minimum[0] > animVersion[0]) {
+              return true;
+            } if (animVersion[0] > minimum[0]) {
+              return false;
+            }
+            if (minimum[1] > animVersion[1]) {
+              return true;
+            } if (animVersion[1] > minimum[1]) {
+              return false;
+            }
+            if (minimum[2] > animVersion[2]) {
+              return true;
+            } if (animVersion[2] > minimum[2]) {
+              return false;
+            }
+            return null;
+          }
+
+          var checkText = (function () {
+            var minimumVersion = [4, 4, 14];
+
+            function updateTextLayer(textLayer) {
+              var documentData = textLayer.t.d;
+              textLayer.t.d = {
+                k: [
+                  {
+                    s: documentData,
+                    t: 0,
+                  },
+                ],
+              };
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkChars = (function () {
+            var minimumVersion = [4, 7, 99];
+            return function (animationData) {
+              if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
+                var i;
+                var len = animationData.chars.length;
+                for (i = 0; i < len; i += 1) {
+                  var charData = animationData.chars[i];
+                  if (charData.data && charData.data.shapes) {
+                    completeShapes(charData.data.shapes);
+                    charData.data.ip = 0;
+                    charData.data.op = 99999;
+                    charData.data.st = 0;
+                    charData.data.sr = 1;
+                    charData.data.ks = {
+                      p: { k: [0, 0], a: 0 },
+                      s: { k: [100, 100], a: 0 },
+                      a: { k: [0, 0], a: 0 },
+                      r: { k: 0, a: 0 },
+                      o: { k: 100, a: 0 },
+                    };
+                    if (!animationData.chars[i].t) {
+                      charData.data.shapes.push(
+                        {
+                          ty: 'no',
+                        }
+                      );
+                      charData.data.shapes[0].it.push(
+                        {
+                          p: { k: [0, 0], a: 0 },
+                          s: { k: [100, 100], a: 0 },
+                          a: { k: [0, 0], a: 0 },
+                          r: { k: 0, a: 0 },
+                          o: { k: 100, a: 0 },
+                          sk: { k: 0, a: 0 },
+                          sa: { k: 0, a: 0 },
+                          ty: 'tr',
+                        }
+                      );
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkPathProperties = (function () {
+            var minimumVersion = [5, 7, 15];
+
+            function updateTextLayer(textLayer) {
+              var pathData = textLayer.t.p;
+              if (typeof pathData.a === 'number') {
+                pathData.a = {
+                  a: 0,
+                  k: pathData.a,
+                };
+              }
+              if (typeof pathData.p === 'number') {
+                pathData.p = {
+                  a: 0,
+                  k: pathData.p,
+                };
+              }
+              if (typeof pathData.r === 'number') {
+                pathData.r = {
+                  a: 0,
+                  k: pathData.r,
+                };
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkColors = (function () {
+            var minimumVersion = [4, 1, 9];
+
+            function iterateShapes(shapes) {
+              var i;
+              var len = shapes.length;
+              var j;
+              var jLen;
+              for (i = 0; i < len; i += 1) {
+                if (shapes[i].ty === 'gr') {
+                  iterateShapes(shapes[i].it);
+                } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
+                  if (shapes[i].c.k && shapes[i].c.k[0].i) {
+                    jLen = shapes[i].c.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (shapes[i].c.k[j].s) {
+                        shapes[i].c.k[j].s[0] /= 255;
+                        shapes[i].c.k[j].s[1] /= 255;
+                        shapes[i].c.k[j].s[2] /= 255;
+                        shapes[i].c.k[j].s[3] /= 255;
+                      }
+                      if (shapes[i].c.k[j].e) {
+                        shapes[i].c.k[j].e[0] /= 255;
+                        shapes[i].c.k[j].e[1] /= 255;
+                        shapes[i].c.k[j].e[2] /= 255;
+                        shapes[i].c.k[j].e[3] /= 255;
+                      }
+                    }
+                  } else {
+                    shapes[i].c.k[0] /= 255;
+                    shapes[i].c.k[1] /= 255;
+                    shapes[i].c.k[2] /= 255;
+                    shapes[i].c.k[3] /= 255;
+                  }
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 4) {
+                  iterateShapes(layers[i].shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkShapes = (function () {
+            var minimumVersion = [4, 4, 18];
+
+            function completeClosingShapes(arr) {
+              var i;
+              var len = arr.length;
+              var j;
+              var jLen;
+              for (i = len - 1; i >= 0; i -= 1) {
+                if (arr[i].ty === 'sh') {
+                  if (arr[i].ks.k.i) {
+                    arr[i].ks.k.c = arr[i].closed;
+                  } else {
+                    jLen = arr[i].ks.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (arr[i].ks.k[j].s) {
+                        arr[i].ks.k[j].s[0].c = arr[i].closed;
+                      }
+                      if (arr[i].ks.k[j].e) {
+                        arr[i].ks.k[j].e[0].c = arr[i].closed;
+                      }
+                    }
+                  }
+                } else if (arr[i].ty === 'gr') {
+                  completeClosingShapes(arr[i].it);
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var layerData;
+              var i;
+              var len = layers.length;
+              var j;
+              var jLen;
+              var k;
+              var kLen;
+              for (i = 0; i < len; i += 1) {
+                layerData = layers[i];
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      maskProps[j].pt.k.c = maskProps[j].cl;
+                    } else {
+                      kLen = maskProps[j].pt.k.length;
+                      for (k = 0; k < kLen; k += 1) {
+                        if (maskProps[j].pt.k[k].s) {
+                          maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 4) {
+                  completeClosingShapes(layerData.shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          function completeData(animationData) {
+            if (animationData.__complete) {
+              return;
+            }
+            checkColors(animationData);
+            checkText(animationData);
+            checkChars(animationData);
+            checkPathProperties(animationData);
+            checkShapes(animationData);
+            completeLayers(animationData.layers, animationData.assets);
+            completeChars(animationData.chars, animationData.assets);
+            animationData.__complete = true;
+          }
+
+          function completeText(data) {
+            if (data.t.a.length === 0 && !('m' in data.t.p)) {
+              // data.singleShape = true;
+            }
+          }
+
+          var moduleOb = {};
+          moduleOb.completeData = completeData;
+          moduleOb.checkColors = checkColors;
+          moduleOb.checkChars = checkChars;
+          moduleOb.checkPathProperties = checkPathProperties;
+          moduleOb.checkShapes = checkShapes;
+          moduleOb.completeLayers = completeLayers;
+
+          return moduleOb;
+        }
+        if (!_workerSelf.dataManager) {
+          _workerSelf.dataManager = dataFunctionManager();
+        }
+
+        if (!_workerSelf.assetLoader) {
+          _workerSelf.assetLoader = (function () {
+            function formatResponse(xhr) {
+              // using typeof doubles the time of execution of this method,
+              // so if available, it's better to use the header to validate the type
+              var contentTypeHeader = xhr.getResponseHeader('content-type');
+              if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
+                return xhr.response;
+              }
+              if (xhr.response && typeof xhr.response === 'object') {
+                return xhr.response;
+              } if (xhr.response && typeof xhr.response === 'string') {
+                return JSON.parse(xhr.response);
+              } if (xhr.responseText) {
+                return JSON.parse(xhr.responseText);
+              }
+              return null;
+            }
+
+            function loadAsset(path, fullPath, callback, errorCallback) {
+              var response;
+              var xhr = new XMLHttpRequest();
+              // set responseType after calling open or IE will break.
+              try {
+                // This crashes on Android WebView prior to KitKat
+                xhr.responseType = 'json';
+              } catch (err) {} // eslint-disable-line no-empty
+              xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4) {
+                  if (xhr.status === 200) {
+                    response = formatResponse(xhr);
+                    callback(response);
+                  } else {
+                    try {
+                      response = formatResponse(xhr);
+                      callback(response);
+                    } catch (err) {
+                      if (errorCallback) {
+                        errorCallback(err);
+                      }
+                    }
+                  }
+                }
+              };
+              try {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), path, true);
+              } catch (error) {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
+              }
+              xhr.send();
+            }
+            return {
+              load: loadAsset,
+            };
+          }());
+        }
+
+        if (e.data.type === 'loadAnimation') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.dataManager.completeData(data);
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        } else if (e.data.type === 'complete') {
+          var animation = e.data.animation;
+          _workerSelf.dataManager.completeData(animation);
+          _workerSelf.postMessage({
+            id: e.data.id,
+            payload: animation,
+            status: 'success',
+          });
+        } else if (e.data.type === 'loadData') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        }
+      });
+
+      workerInstance.onmessage = function (event) {
+        var data = event.data;
+        var id = data.id;
+        var process = processes[id];
+        processes[id] = null;
+        if (data.status === 'success') {
+          process.onComplete(data.payload);
+        } else if (process.onError) {
+          process.onError();
+        }
+      };
+    }
+  }
+
+  function createProcess(onComplete, onError) {
+    _counterId += 1;
+    var id = 'processId_' + _counterId;
+    processes[id] = {
+      onComplete: onComplete,
+      onError: onError,
+    };
+    return id;
+  }
+
+  function loadAnimation(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadAnimation',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function loadData(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadData',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function completeAnimation(anim, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'complete',
+      animation: anim,
+      id: processId,
+    });
+  }
+
+  return {
+    loadAnimation: loadAnimation,
+    loadData: loadData,
+    completeAnimation: completeAnimation,
+  };
+}());
+
+const ImagePreloader = (function () {
+  var proxyImage = (function () {
+    var canvas = createTag('canvas');
+    canvas.width = 1;
+    canvas.height = 1;
+    var ctx = canvas.getContext('2d');
+    ctx.fillStyle = 'rgba(0,0,0,0)';
+    ctx.fillRect(0, 0, 1, 1);
+    return canvas;
+  }());
+
+  function imageLoaded() {
+    this.loadedAssets += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+  function footageLoaded() {
+    this.loadedFootagesCount += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+
+  function getAssetsPath(assetData, assetsPath, originalPath) {
+    var path = '';
+    if (assetData.e) {
+      path = assetData.p;
+    } else if (assetsPath) {
+      var imagePath = assetData.p;
+      if (imagePath.indexOf('images/') !== -1) {
+        imagePath = imagePath.split('/')[1];
+      }
+      path = assetsPath + imagePath;
+    } else {
+      path = originalPath;
+      path += assetData.u ? assetData.u : '';
+      path += assetData.p;
+    }
+    return path;
+  }
+
+  function testImageLoaded(img) {
+    var _count = 0;
+    var intervalId = setInterval(function () {
+      var box = img.getBBox();
+      if (box.width || _count > 500) {
+        this._imageLoaded();
+        clearInterval(intervalId);
+      }
+      _count += 1;
+    }.bind(this), 50);
+  }
+
+  function createImageData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createNS('image');
+    if (isSafari) {
+      this.testImageLoaded(img);
+    } else {
+      img.addEventListener('load', this._imageLoaded, false);
+    }
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
+    if (this._elementHelper.append) {
+      this._elementHelper.append(img);
+    } else {
+      this._elementHelper.appendChild(img);
+    }
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createImgData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createTag('img');
+    img.crossOrigin = 'anonymous';
+    img.addEventListener('load', this._imageLoaded, false);
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.src = path;
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createFootageData(data) {
+    var ob = {
+      assetData: data,
+    };
+    var path = getAssetsPath(data, this.assetsPath, this.path);
+    dataManager.loadData(path, function (footageData) {
+      ob.img = footageData;
+      this._footageLoaded();
+    }.bind(this), function () {
+      ob.img = {};
+      this._footageLoaded();
+    }.bind(this));
+    return ob;
+  }
+
+  function loadAssets(assets, cb) {
+    this.imagesLoadedCb = cb;
+    var i;
+    var len = assets.length;
+    for (i = 0; i < len; i += 1) {
+      if (!assets[i].layers) {
+        if (!assets[i].t || assets[i].t === 'seq') {
+          this.totalImages += 1;
+          this.images.push(this._createImageData(assets[i]));
+        } else if (assets[i].t === 3) {
+          this.totalFootages += 1;
+          this.images.push(this.createFootageData(assets[i]));
+        }
+      }
+    }
+  }
+
+  function setPath(path) {
+    this.path = path || '';
+  }
+
+  function setAssetsPath(path) {
+    this.assetsPath = path || '';
+  }
+
+  function getAsset(assetData) {
+    var i = 0;
+    var len = this.images.length;
+    while (i < len) {
+      if (this.images[i].assetData === assetData) {
+        return this.images[i].img;
+      }
+      i += 1;
+    }
+    return null;
+  }
+
+  function destroy() {
+    this.imagesLoadedCb = null;
+    this.images.length = 0;
+  }
+
+  function loadedImages() {
+    return this.totalImages === this.loadedAssets;
+  }
+
+  function loadedFootages() {
+    return this.totalFootages === this.loadedFootagesCount;
+  }
+
+  function setCacheType(type, elementHelper) {
+    if (type === 'svg') {
+      this._elementHelper = elementHelper;
+      this._createImageData = this.createImageData.bind(this);
+    } else {
+      this._createImageData = this.createImgData.bind(this);
+    }
+  }
+
+  function ImagePreloaderFactory() {
+    this._imageLoaded = imageLoaded.bind(this);
+    this._footageLoaded = footageLoaded.bind(this);
+    this.testImageLoaded = testImageLoaded.bind(this);
+    this.createFootageData = createFootageData.bind(this);
+    this.assetsPath = '';
+    this.path = '';
+    this.totalImages = 0;
+    this.totalFootages = 0;
+    this.loadedAssets = 0;
+    this.loadedFootagesCount = 0;
+    this.imagesLoadedCb = null;
+    this.images = [];
+  }
+
+  ImagePreloaderFactory.prototype = {
+    loadAssets: loadAssets,
+    setAssetsPath: setAssetsPath,
+    setPath: setPath,
+    loadedImages: loadedImages,
+    loadedFootages: loadedFootages,
+    destroy: destroy,
+    getAsset: getAsset,
+    createImgData: createImgData,
+    createImageData: createImageData,
+    imageLoaded: imageLoaded,
+    footageLoaded: footageLoaded,
+    setCacheType: setCacheType,
+  };
+
+  return ImagePreloaderFactory;
+}());
+
+function BaseEvent() {}
+BaseEvent.prototype = {
+  triggerEvent: function (eventName, args) {
+    if (this._cbs[eventName]) {
+      var callbacks = this._cbs[eventName];
+      for (var i = 0; i < callbacks.length; i += 1) {
+        callbacks[i](args);
+      }
+    }
+  },
+  addEventListener: function (eventName, callback) {
+    if (!this._cbs[eventName]) {
+      this._cbs[eventName] = [];
+    }
+    this._cbs[eventName].push(callback);
+
+    return function () {
+      this.removeEventListener(eventName, callback);
+    }.bind(this);
+  },
+  removeEventListener: function (eventName, callback) {
+    if (!callback) {
+      this._cbs[eventName] = null;
+    } else if (this._cbs[eventName]) {
+      var i = 0;
+      var len = this._cbs[eventName].length;
+      while (i < len) {
+        if (this._cbs[eventName][i] === callback) {
+          this._cbs[eventName].splice(i, 1);
+          i -= 1;
+          len -= 1;
+        }
+        i += 1;
+      }
+      if (!this._cbs[eventName].length) {
+        this._cbs[eventName] = null;
+      }
+    }
+  },
+};
+
+const markerParser = (
+
+  function () {
+    function parsePayloadLines(payload) {
+      var lines = payload.split('\r\n');
+      var keys = {};
+      var line;
+      var keysCount = 0;
+      for (var i = 0; i < lines.length; i += 1) {
+        line = lines[i].split(':');
+        if (line.length === 2) {
+          keys[line[0]] = line[1].trim();
+          keysCount += 1;
+        }
+      }
+      if (keysCount === 0) {
+        throw new Error();
+      }
+      return keys;
+    }
+
+    return function (_markers) {
+      var markers = [];
+      for (var i = 0; i < _markers.length; i += 1) {
+        var _marker = _markers[i];
+        var markerData = {
+          time: _marker.tm,
+          duration: _marker.dr,
+        };
+        try {
+          markerData.payload = JSON.parse(_markers[i].cm);
+        } catch (_) {
+          try {
+            markerData.payload = parsePayloadLines(_markers[i].cm);
+          } catch (__) {
+            markerData.payload = {
+              name: _markers[i].cm,
+            };
+          }
+        }
+        markers.push(markerData);
+      }
+      return markers;
+    };
+  }());
+
+const ProjectInterface = (function () {
+  function registerComposition(comp) {
+    this.compositions.push(comp);
+  }
+
+  return function () {
+    function _thisProjectFunction(name) {
+      var i = 0;
+      var len = this.compositions.length;
+      while (i < len) {
+        if (this.compositions[i].data && this.compositions[i].data.nm === name) {
+          if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
+            this.compositions[i].prepareFrame(this.currentFrame);
+          }
+          return this.compositions[i].compInterface;
+        }
+        i += 1;
+      }
+      return null;
+    }
+
+    _thisProjectFunction.compositions = [];
+    _thisProjectFunction.currentFrame = 0;
+
+    _thisProjectFunction.registerComposition = registerComposition;
+
+    return _thisProjectFunction;
+  };
+}());
+
+const renderers = {};
+
+const registerRenderer = (key, value) => {
+  renderers[key] = value;
+};
+
+function getRenderer(key) {
+  return renderers[key];
+}
+
+function getRegisteredRenderer() {
+  // Returns canvas by default for compatibility
+  if (renderers.canvas) {
+    return 'canvas';
+  }
+  // Returns any renderer that is registered
+  for (const key in renderers) {
+    if (renderers[key]) {
+      return key;
+    }
+  }
+  return '';
+}
+
+const AnimationItem = function () {
+  this._cbs = [];
+  this.name = '';
+  this.path = '';
+  this.isLoaded = false;
+  this.currentFrame = 0;
+  this.currentRawFrame = 0;
+  this.firstFrame = 0;
+  this.totalFrames = 0;
+  this.frameRate = 0;
+  this.frameMult = 0;
+  this.playSpeed = 1;
+  this.playDirection = 1;
+  this.playCount = 0;
+  this.animationData = {};
+  this.assets = [];
+  this.isPaused = true;
+  this.autoplay = false;
+  this.loop = true;
+  this.renderer = null;
+  this.animationID = createElementID();
+  this.assetsPath = '';
+  this.timeCompleted = 0;
+  this.segmentPos = 0;
+  this.isSubframeEnabled = getSubframeEnabled();
+  this.segments = [];
+  this._idle = true;
+  this._completedLoop = false;
+  this.projectInterface = ProjectInterface();
+  this.imagePreloader = new ImagePreloader();
+  this.audioController = audioControllerFactory();
+  this.markers = [];
+  this.configAnimation = this.configAnimation.bind(this);
+  this.onSetupError = this.onSetupError.bind(this);
+  this.onSegmentComplete = this.onSegmentComplete.bind(this);
+  this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
+  this.expressionsPlugin = getExpressionsPlugin();
+};
+
+extendPrototype([BaseEvent], AnimationItem);
+
+AnimationItem.prototype.setParams = function (params) {
+  if (params.wrapper || params.container) {
+    this.wrapper = params.wrapper || params.container;
+  }
+  var animType = 'svg';
+  if (params.animType) {
+    animType = params.animType;
+  } else if (params.renderer) {
+    animType = params.renderer;
+  }
+  const RendererClass = getRenderer(animType);
+  this.renderer = new RendererClass(this, params.rendererSettings);
+  this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
+  this.renderer.setProjectInterface(this.projectInterface);
+  this.animType = animType;
+  if (params.loop === ''
+        || params.loop === null
+        || params.loop === undefined
+        || params.loop === true) {
+    this.loop = true;
+  } else if (params.loop === false) {
+    this.loop = false;
+  } else {
+    this.loop = parseInt(params.loop, 10);
+  }
+  this.autoplay = 'autoplay' in params ? params.autoplay : true;
+  this.name = params.name ? params.name : '';
+  this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
+  this.assetsPath = params.assetsPath;
+  this.initialSegment = params.initialSegment;
+  if (params.audioFactory) {
+    this.audioController.setAudioFactory(params.audioFactory);
+  }
+  if (params.animationData) {
+    this.setupAnimation(params.animationData);
+  } else if (params.path) {
+    if (params.path.lastIndexOf('\\') !== -1) {
+      this.path = params.path.substr(0, params.path.lastIndexOf('\\') + 1);
+    } else {
+      this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
+    }
+    this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
+    this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
+    dataManager.loadAnimation(
+      params.path,
+      this.configAnimation,
+      this.onSetupError
+    );
+  }
+};
+
+AnimationItem.prototype.onSetupError = function () {
+  this.trigger('data_failed');
+};
+
+AnimationItem.prototype.setupAnimation = function (data) {
+  dataManager.completeAnimation(
+    data,
+    this.configAnimation
+  );
+};
+
+AnimationItem.prototype.setData = function (wrapper, animationData) {
+  if (animationData) {
+    if (typeof animationData !== 'object') {
+      animationData = JSON.parse(animationData);
+    }
+  }
+  var params = {
+    wrapper: wrapper,
+    animationData: animationData,
+  };
+  var wrapperAttributes = wrapper.attributes;
+
+  params.path = wrapperAttributes.getNamedItem('data-animation-path') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-animation-path').value
+    : wrapperAttributes.getNamedItem('data-bm-path') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-path').value
+      : wrapperAttributes.getNamedItem('bm-path')
+        ? wrapperAttributes.getNamedItem('bm-path').value
+        : '';
+  params.animType = wrapperAttributes.getNamedItem('data-anim-type') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-type').value
+    : wrapperAttributes.getNamedItem('data-bm-type') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-type').value
+      : wrapperAttributes.getNamedItem('bm-type') // eslint-disable-line no-nested-ternary
+        ? wrapperAttributes.getNamedItem('bm-type').value
+        : wrapperAttributes.getNamedItem('data-bm-renderer') // eslint-disable-line no-nested-ternary
+          ? wrapperAttributes.getNamedItem('data-bm-renderer').value
+          : wrapperAttributes.getNamedItem('bm-renderer')
+            ? wrapperAttributes.getNamedItem('bm-renderer').value
+            : getRegisteredRenderer() || 'canvas';
+
+  var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-loop').value
+    : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-loop').value
+      : wrapperAttributes.getNamedItem('bm-loop')
+        ? wrapperAttributes.getNamedItem('bm-loop').value
+        : '';
+  if (loop === 'false') {
+    params.loop = false;
+  } else if (loop === 'true') {
+    params.loop = true;
+  } else if (loop !== '') {
+    params.loop = parseInt(loop, 10);
+  }
+  var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-autoplay').value
+    : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-autoplay').value
+      : wrapperAttributes.getNamedItem('bm-autoplay')
+        ? wrapperAttributes.getNamedItem('bm-autoplay').value
+        : true;
+  params.autoplay = autoplay !== 'false';
+
+  params.name = wrapperAttributes.getNamedItem('data-name') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-name').value
+    : wrapperAttributes.getNamedItem('data-bm-name') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-name').value
+      : wrapperAttributes.getNamedItem('bm-name')
+        ? wrapperAttributes.getNamedItem('bm-name').value
+        : '';
+  var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-prerender').value
+    : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-prerender').value
+      : wrapperAttributes.getNamedItem('bm-prerender')
+        ? wrapperAttributes.getNamedItem('bm-prerender').value
+        : '';
+
+  if (prerender === 'false') {
+    params.prerender = false;
+  }
+  if (!params.path) {
+    this.trigger('destroy');
+  } else {
+    this.setParams(params);
+  }
+};
+
+AnimationItem.prototype.includeLayers = function (data) {
+  if (data.op > this.animationData.op) {
+    this.animationData.op = data.op;
+    this.totalFrames = Math.floor(data.op - this.animationData.ip);
+  }
+  var layers = this.animationData.layers;
+  var i;
+  var len = layers.length;
+  var newLayers = data.layers;
+  var j;
+  var jLen = newLayers.length;
+  for (j = 0; j < jLen; j += 1) {
+    i = 0;
+    while (i < len) {
+      if (layers[i].id === newLayers[j].id) {
+        layers[i] = newLayers[j];
+        break;
+      }
+      i += 1;
+    }
+  }
+  if (data.chars || data.fonts) {
+    this.renderer.globalData.fontManager.addChars(data.chars);
+    this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
+  }
+  if (data.assets) {
+    len = data.assets.length;
+    for (i = 0; i < len; i += 1) {
+      this.animationData.assets.push(data.assets[i]);
+    }
+  }
+  this.animationData.__complete = false;
+  dataManager.completeAnimation(
+    this.animationData,
+    this.onSegmentComplete
+  );
+};
+
+AnimationItem.prototype.onSegmentComplete = function (data) {
+  this.animationData = data;
+  var expressionsPlugin = getExpressionsPlugin();
+  if (expressionsPlugin) {
+    expressionsPlugin.initExpressions(this);
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.loadNextSegment = function () {
+  var segments = this.animationData.segments;
+  if (!segments || segments.length === 0 || !this.autoloadSegments) {
+    this.trigger('data_ready');
+    this.timeCompleted = this.totalFrames;
+    return;
+  }
+  var segment = segments.shift();
+  this.timeCompleted = segment.time * this.frameRate;
+  var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
+  this.segmentPos += 1;
+  dataManager.loadData(segmentPath, this.includeLayers.bind(this), function () {
+    this.trigger('data_failed');
+  }.bind(this));
+};
+
+AnimationItem.prototype.loadSegments = function () {
+  var segments = this.animationData.segments;
+  if (!segments) {
+    this.timeCompleted = this.totalFrames;
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.imagesLoaded = function () {
+  this.trigger('loaded_images');
+  this.checkLoaded();
+};
+
+AnimationItem.prototype.preloadImages = function () {
+  this.imagePreloader.setAssetsPath(this.assetsPath);
+  this.imagePreloader.setPath(this.path);
+  this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
+};
+
+AnimationItem.prototype.configAnimation = function (animData) {
+  if (!this.renderer) {
+    return;
+  }
+  try {
+    this.animationData = animData;
+    if (this.initialSegment) {
+      this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
+      this.firstFrame = Math.round(this.initialSegment[0]);
+    } else {
+      this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
+      this.firstFrame = Math.round(this.animationData.ip);
+    }
+    this.renderer.configAnimation(animData);
+    if (!animData.assets) {
+      animData.assets = [];
+    }
+
+    this.assets = this.animationData.assets;
+    this.frameRate = this.animationData.fr;
+    this.frameMult = this.animationData.fr / 1000;
+    this.renderer.searchExtraCompositions(animData.assets);
+    this.markers = markerParser(animData.markers || []);
+    this.trigger('config_ready');
+    this.preloadImages();
+    this.loadSegments();
+    this.updaFrameModifier();
+    this.waitForFontsLoaded();
+    if (this.isPaused) {
+      this.audioController.pause();
+    }
+  } catch (error) {
+    this.triggerConfigError(error);
+  }
+};
+
+AnimationItem.prototype.waitForFontsLoaded = function () {
+  if (!this.renderer) {
+    return;
+  }
+  if (this.renderer.globalData.fontManager.isLoaded) {
+    this.checkLoaded();
+  } else {
+    setTimeout(this.waitForFontsLoaded.bind(this), 20);
+  }
+};
+
+AnimationItem.prototype.checkLoaded = function () {
+  if (!this.isLoaded
+        && this.renderer.globalData.fontManager.isLoaded
+        && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas')
+        && (this.imagePreloader.loadedFootages())
+  ) {
+    this.isLoaded = true;
+    var expressionsPlugin = getExpressionsPlugin();
+    if (expressionsPlugin) {
+      expressionsPlugin.initExpressions(this);
+    }
+    this.renderer.initItems();
+    setTimeout(function () {
+      this.trigger('DOMLoaded');
+    }.bind(this), 0);
+    this.gotoFrame();
+    if (this.autoplay) {
+      this.play();
+    }
+  }
+};
+
+AnimationItem.prototype.resize = function (width, height) {
+  // Adding this validation for backwards compatibility in case an event object was being passed down
+  var _width = typeof width === 'number' ? width : undefined;
+  var _height = typeof height === 'number' ? height : undefined;
+  this.renderer.updateContainerSize(_width, _height);
+};
+
+AnimationItem.prototype.setSubframe = function (flag) {
+  this.isSubframeEnabled = !!flag;
+};
+
+AnimationItem.prototype.gotoFrame = function () {
+  this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
+
+  if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
+    this.currentFrame = this.timeCompleted;
+  }
+  this.trigger('enterFrame');
+  this.renderFrame();
+  this.trigger('drawnFrame');
+};
+
+AnimationItem.prototype.renderFrame = function () {
+  if (this.isLoaded === false || !this.renderer) {
+    return;
+  }
+  try {
+    if (this.expressionsPlugin) {
+      this.expressionsPlugin.resetFrame();
+    }
+    this.renderer.renderFrame(this.currentFrame + this.firstFrame);
+  } catch (error) {
+    this.triggerRenderFrameError(error);
+  }
+};
+
+AnimationItem.prototype.play = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.isPaused = false;
+    this.trigger('_play');
+    this.audioController.resume();
+    if (this._idle) {
+      this._idle = false;
+      this.trigger('_active');
+    }
+  }
+};
+
+AnimationItem.prototype.pause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === false) {
+    this.isPaused = true;
+    this.trigger('_pause');
+    this._idle = true;
+    this.trigger('_idle');
+    this.audioController.pause();
+  }
+};
+
+AnimationItem.prototype.togglePause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.play();
+  } else {
+    this.pause();
+  }
+};
+
+AnimationItem.prototype.stop = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.pause();
+  this.playCount = 0;
+  this._completedLoop = false;
+  this.setCurrentRawFrameValue(0);
+};
+
+AnimationItem.prototype.getMarkerData = function (markerName) {
+  var marker;
+  for (var i = 0; i < this.markers.length; i += 1) {
+    marker = this.markers[i];
+    if (marker.payload && marker.payload.name === markerName) {
+      return marker;
+    }
+  }
+  return null;
+};
+
+AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      this.goToAndStop(marker.time, true);
+    }
+  } else if (isFrame) {
+    this.setCurrentRawFrameValue(value);
+  } else {
+    this.setCurrentRawFrameValue(value * this.frameModifier);
+  }
+  this.pause();
+};
+
+AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      if (!marker.duration) {
+        this.goToAndStop(marker.time, true);
+      } else {
+        this.playSegments([marker.time, marker.time + marker.duration], true);
+      }
+    }
+  } else {
+    this.goToAndStop(numValue, isFrame, name);
+  }
+  this.play();
+};
+
+AnimationItem.prototype.advanceTime = function (value) {
+  if (this.isPaused === true || this.isLoaded === false) {
+    return;
+  }
+  var nextValue = this.currentRawFrame + value * this.frameModifier;
+  var _isComplete = false;
+  // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+  // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
+  if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
+    if (!this.loop || this.playCount === this.loop) {
+      if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
+        _isComplete = true;
+        nextValue = this.totalFrames - 1;
+      }
+    } else if (nextValue >= this.totalFrames) {
+      this.playCount += 1;
+      if (!this.checkSegments(nextValue % this.totalFrames)) {
+        this.setCurrentRawFrameValue(nextValue % this.totalFrames);
+        this._completedLoop = true;
+        this.trigger('loopComplete');
+      }
+    } else {
+      this.setCurrentRawFrameValue(nextValue);
+    }
+  } else if (nextValue < 0) {
+    if (!this.checkSegments(nextValue % this.totalFrames)) {
+      if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) { // eslint-disable-line no-plusplus
+        this.setCurrentRawFrameValue(this.totalFrames + (nextValue % this.totalFrames));
+        if (!this._completedLoop) {
+          this._completedLoop = true;
+        } else {
+          this.trigger('loopComplete');
+        }
+      } else {
+        _isComplete = true;
+        nextValue = 0;
+      }
+    }
+  } else {
+    this.setCurrentRawFrameValue(nextValue);
+  }
+  if (_isComplete) {
+    this.setCurrentRawFrameValue(nextValue);
+    this.pause();
+    this.trigger('complete');
+  }
+};
+
+AnimationItem.prototype.adjustSegment = function (arr, offset) {
+  this.playCount = 0;
+  if (arr[1] < arr[0]) {
+    if (this.frameModifier > 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(-1);
+      }
+    }
+    this.totalFrames = arr[0] - arr[1];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[1];
+    this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset);
+  } else if (arr[1] > arr[0]) {
+    if (this.frameModifier < 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(1);
+      }
+    }
+    this.totalFrames = arr[1] - arr[0];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[0];
+    this.setCurrentRawFrameValue(0.001 + offset);
+  }
+  this.trigger('segmentStart');
+};
+AnimationItem.prototype.setSegment = function (init, end) {
+  var pendingFrame = -1;
+  if (this.isPaused) {
+    if (this.currentRawFrame + this.firstFrame < init) {
+      pendingFrame = init;
+    } else if (this.currentRawFrame + this.firstFrame > end) {
+      pendingFrame = end - init;
+    }
+  }
+
+  this.firstFrame = init;
+  this.totalFrames = end - init;
+  this.timeCompleted = this.totalFrames;
+  if (pendingFrame !== -1) {
+    this.goToAndStop(pendingFrame, true);
+  }
+};
+
+AnimationItem.prototype.playSegments = function (arr, forceFlag) {
+  if (forceFlag) {
+    this.segments.length = 0;
+  }
+  if (typeof arr[0] === 'object') {
+    var i;
+    var len = arr.length;
+    for (i = 0; i < len; i += 1) {
+      this.segments.push(arr[i]);
+    }
+  } else {
+    this.segments.push(arr);
+  }
+  if (this.segments.length && forceFlag) {
+    this.adjustSegment(this.segments.shift(), 0);
+  }
+  if (this.isPaused) {
+    this.play();
+  }
+};
+
+AnimationItem.prototype.resetSegments = function (forceFlag) {
+  this.segments.length = 0;
+  this.segments.push([this.animationData.ip, this.animationData.op]);
+  if (forceFlag) {
+    this.checkSegments(0);
+  }
+};
+AnimationItem.prototype.checkSegments = function (offset) {
+  if (this.segments.length) {
+    this.adjustSegment(this.segments.shift(), offset);
+    return true;
+  }
+  return false;
+};
+
+AnimationItem.prototype.destroy = function (name) {
+  if ((name && this.name !== name) || !this.renderer) {
+    return;
+  }
+  this.renderer.destroy();
+  this.imagePreloader.destroy();
+  this.trigger('destroy');
+  this._cbs = null;
+  this.onEnterFrame = null;
+  this.onLoopComplete = null;
+  this.onComplete = null;
+  this.onSegmentStart = null;
+  this.onDestroy = null;
+  this.renderer = null;
+  this.expressionsPlugin = null;
+  this.imagePreloader = null;
+  this.projectInterface = null;
+};
+
+AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
+  this.currentRawFrame = value;
+  this.gotoFrame();
+};
+
+AnimationItem.prototype.setSpeed = function (val) {
+  this.playSpeed = val;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setDirection = function (val) {
+  this.playDirection = val < 0 ? -1 : 1;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setLoop = function (isLooping) {
+  this.loop = isLooping;
+};
+
+AnimationItem.prototype.setVolume = function (val, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.setVolume(val);
+};
+
+AnimationItem.prototype.getVolume = function () {
+  return this.audioController.getVolume();
+};
+
+AnimationItem.prototype.mute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.mute();
+};
+
+AnimationItem.prototype.unmute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.unmute();
+};
+
+AnimationItem.prototype.updaFrameModifier = function () {
+  this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
+  this.audioController.setRate(this.playSpeed * this.playDirection);
+};
+
+AnimationItem.prototype.getPath = function () {
+  return this.path;
+};
+
+AnimationItem.prototype.getAssetsPath = function (assetData) {
+  var path = '';
+  if (assetData.e) {
+    path = assetData.p;
+  } else if (this.assetsPath) {
+    var imagePath = assetData.p;
+    if (imagePath.indexOf('images/') !== -1) {
+      imagePath = imagePath.split('/')[1];
+    }
+    path = this.assetsPath + imagePath;
+  } else {
+    path = this.path;
+    path += assetData.u ? assetData.u : '';
+    path += assetData.p;
+  }
+  return path;
+};
+
+AnimationItem.prototype.getAssetData = function (id) {
+  var i = 0;
+  var len = this.assets.length;
+  while (i < len) {
+    if (id === this.assets[i].id) {
+      return this.assets[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+AnimationItem.prototype.hide = function () {
+  this.renderer.hide();
+};
+
+AnimationItem.prototype.show = function () {
+  this.renderer.show();
+};
+
+AnimationItem.prototype.getDuration = function (isFrame) {
+  return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
+};
+
+AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
+  try {
+    var element = this.renderer.getElementByPath(path);
+    element.updateDocumentData(documentData, index);
+  } catch (error) {
+    // TODO: decide how to handle catch case
+  }
+};
+
+AnimationItem.prototype.trigger = function (name) {
+  if (this._cbs && this._cbs[name]) {
+    switch (name) {
+      case 'enterFrame':
+        this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
+        break;
+      case 'drawnFrame':
+        this.drawnFrameEvent.currentTime = this.currentFrame;
+        this.drawnFrameEvent.totalTime = this.totalFrames;
+        this.drawnFrameEvent.direction = this.frameModifier;
+        this.triggerEvent(name, this.drawnFrameEvent);
+        break;
+      case 'loopComplete':
+        this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+        break;
+      case 'complete':
+        this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
+        break;
+      case 'segmentStart':
+        this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+        break;
+      case 'destroy':
+        this.triggerEvent(name, new BMDestroyEvent(name, this));
+        break;
+      default:
+        this.triggerEvent(name);
+    }
+  }
+  if (name === 'enterFrame' && this.onEnterFrame) {
+    this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
+  }
+  if (name === 'loopComplete' && this.onLoopComplete) {
+    this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+  }
+  if (name === 'complete' && this.onComplete) {
+    this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
+  }
+  if (name === 'segmentStart' && this.onSegmentStart) {
+    this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+  }
+  if (name === 'destroy' && this.onDestroy) {
+    this.onDestroy.call(this, new BMDestroyEvent(name, this));
+  }
+};
+
+AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
+  var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+AnimationItem.prototype.triggerConfigError = function (nativeError) {
+  var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+const animationManager = (function () {
+  var moduleOb = {};
+  var registeredAnimations = [];
+  var initTime = 0;
+  var len = 0;
+  var playingAnimationsNum = 0;
+  var _stopped = true;
+  var _isFrozen = false;
+
+  function removeElement(ev) {
+    var i = 0;
+    var animItem = ev.target;
+    while (i < len) {
+      if (registeredAnimations[i].animation === animItem) {
+        registeredAnimations.splice(i, 1);
+        i -= 1;
+        len -= 1;
+        if (!animItem.isPaused) {
+          subtractPlayingCount();
+        }
+      }
+      i += 1;
+    }
+  }
+
+  function registerAnimation(element, animationData) {
+    if (!element) {
+      return null;
+    }
+    var i = 0;
+    while (i < len) {
+      if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
+        return registeredAnimations[i].animation;
+      }
+      i += 1;
+    }
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, element);
+    animItem.setData(element, animationData);
+    return animItem;
+  }
+
+  function getRegisteredAnimations() {
+    var i;
+    var lenAnims = registeredAnimations.length;
+    var animations = [];
+    for (i = 0; i < lenAnims; i += 1) {
+      animations.push(registeredAnimations[i].animation);
+    }
+    return animations;
+  }
+
+  function addPlayingCount() {
+    playingAnimationsNum += 1;
+    activate();
+  }
+
+  function subtractPlayingCount() {
+    playingAnimationsNum -= 1;
+  }
+
+  function setupAnimation(animItem, element) {
+    animItem.addEventListener('destroy', removeElement);
+    animItem.addEventListener('_active', addPlayingCount);
+    animItem.addEventListener('_idle', subtractPlayingCount);
+    registeredAnimations.push({ elem: element, animation: animItem });
+    len += 1;
+  }
+
+  function loadAnimation(params) {
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, null);
+    animItem.setParams(params);
+    return animItem;
+  }
+
+  function setSpeed(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setSpeed(val, animation);
+    }
+  }
+
+  function setDirection(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setDirection(val, animation);
+    }
+  }
+
+  function play(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.play(animation);
+    }
+  }
+  function resume(nowTime) {
+    var elapsedTime = nowTime - initTime;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.advanceTime(elapsedTime);
+    }
+    initTime = nowTime;
+    if (playingAnimationsNum && !_isFrozen) {
+      window.requestAnimationFrame(resume);
+    } else {
+      _stopped = true;
+    }
+  }
+
+  function first(nowTime) {
+    initTime = nowTime;
+    window.requestAnimationFrame(resume);
+  }
+
+  function pause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.pause(animation);
+    }
+  }
+
+  function goToAndStop(value, isFrame, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
+    }
+  }
+
+  function stop(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.stop(animation);
+    }
+  }
+
+  function togglePause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.togglePause(animation);
+    }
+  }
+
+  function destroy(animation) {
+    var i;
+    for (i = (len - 1); i >= 0; i -= 1) {
+      registeredAnimations[i].animation.destroy(animation);
+    }
+  }
+
+  function searchAnimations(animationData, standalone, renderer) {
+    var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')),
+      [].slice.call(document.getElementsByClassName('bodymovin')));
+    var i;
+    var lenAnims = animElements.length;
+    for (i = 0; i < lenAnims; i += 1) {
+      if (renderer) {
+        animElements[i].setAttribute('data-bm-type', renderer);
+      }
+      registerAnimation(animElements[i], animationData);
+    }
+    if (standalone && lenAnims === 0) {
+      if (!renderer) {
+        renderer = 'svg';
+      }
+      var body = document.getElementsByTagName('body')[0];
+      body.innerText = '';
+      var div = createTag('div');
+      div.style.width = '100%';
+      div.style.height = '100%';
+      div.setAttribute('data-bm-type', renderer);
+      body.appendChild(div);
+      registerAnimation(div, animationData);
+    }
+  }
+
+  function resize() {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.resize();
+    }
+  }
+
+  function activate() {
+    if (!_isFrozen && playingAnimationsNum) {
+      if (_stopped) {
+        window.requestAnimationFrame(first);
+        _stopped = false;
+      }
+    }
+  }
+
+  function freeze() {
+    _isFrozen = true;
+  }
+
+  function unfreeze() {
+    _isFrozen = false;
+    activate();
+  }
+
+  function setVolume(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setVolume(val, animation);
+    }
+  }
+
+  function mute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.mute(animation);
+    }
+  }
+
+  function unmute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.unmute(animation);
+    }
+  }
+
+  moduleOb.registerAnimation = registerAnimation;
+  moduleOb.loadAnimation = loadAnimation;
+  moduleOb.setSpeed = setSpeed;
+  moduleOb.setDirection = setDirection;
+  moduleOb.play = play;
+  moduleOb.pause = pause;
+  moduleOb.stop = stop;
+  moduleOb.togglePause = togglePause;
+  moduleOb.searchAnimations = searchAnimations;
+  moduleOb.resize = resize;
+  // moduleOb.start = start;
+  moduleOb.goToAndStop = goToAndStop;
+  moduleOb.destroy = destroy;
+  moduleOb.freeze = freeze;
+  moduleOb.unfreeze = unfreeze;
+  moduleOb.setVolume = setVolume;
+  moduleOb.mute = mute;
+  moduleOb.unmute = unmute;
+  moduleOb.getRegisteredAnimations = getRegisteredAnimations;
+  return moduleOb;
+}());
+
+/* eslint-disable */
+const BezierFactory = (function () {
+  /**
+     * BezierEasing - use bezier curve for transition easing function
+     * by Gaëtan Renaudeau 2014 - 2015 – MIT License
+     *
+     * Credits: is based on Firefox's nsSMILKeySpline.cpp
+     * Usage:
+     * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
+     * spline.get(x) => returns the easing value | x must be in [0, 1] range
+     *
+     */
+
+  var ob = {};
+  ob.getBezierEasing = getBezierEasing;
+  var beziers = {};
+
+  function getBezierEasing(a, b, c, d, nm) {
+    var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
+    if (beziers[str]) {
+      return beziers[str];
+    }
+    var bezEasing = new BezierEasing([a, b, c, d]);
+    beziers[str] = bezEasing;
+    return bezEasing;
+  }
+
+  // These values are established by empiricism with tests (tradeoff: performance VS precision)
+  var NEWTON_ITERATIONS = 4;
+  var NEWTON_MIN_SLOPE = 0.001;
+  var SUBDIVISION_PRECISION = 0.0000001;
+  var SUBDIVISION_MAX_ITERATIONS = 10;
+
+  var kSplineTableSize = 11;
+  var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
+
+  var float32ArraySupported = typeof Float32Array === 'function';
+
+  function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
+  function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
+  function C(aA1) { return 3.0 * aA1; }
+
+  // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+  function calcBezier(aT, aA1, aA2) {
+    return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
+  }
+
+  // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+  function getSlope(aT, aA1, aA2) {
+    return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
+  }
+
+  function binarySubdivide(aX, aA, aB, mX1, mX2) {
+    var currentX,
+      currentT,
+      i = 0;
+    do {
+      currentT = aA + (aB - aA) / 2.0;
+      currentX = calcBezier(currentT, mX1, mX2) - aX;
+      if (currentX > 0.0) {
+        aB = currentT;
+      } else {
+        aA = currentT;
+      }
+    } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
+    return currentT;
+  }
+
+  function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
+    for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
+      var currentSlope = getSlope(aGuessT, mX1, mX2);
+      if (currentSlope === 0.0) return aGuessT;
+      var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
+      aGuessT -= currentX / currentSlope;
+    }
+    return aGuessT;
+  }
+
+  /**
+     * points is an array of [ mX1, mY1, mX2, mY2 ]
+     */
+  function BezierEasing(points) {
+    this._p = points;
+    this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
+    this._precomputed = false;
+
+    this.get = this.get.bind(this);
+  }
+
+  BezierEasing.prototype = {
+
+    get: function (x) {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      if (!this._precomputed) this._precompute();
+      if (mX1 === mY1 && mX2 === mY2) return x; // linear
+      // Because JavaScript number are imprecise, we should guarantee the extremes are right.
+      if (x === 0) return 0;
+      if (x === 1) return 1;
+      return calcBezier(this._getTForX(x), mY1, mY2);
+    },
+
+    // Private part
+
+    _precompute: function () {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      this._precomputed = true;
+      if (mX1 !== mY1 || mX2 !== mY2) { this._calcSampleValues(); }
+    },
+
+    _calcSampleValues: function () {
+      var mX1 = this._p[0],
+        mX2 = this._p[2];
+      for (var i = 0; i < kSplineTableSize; ++i) {
+        this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
+      }
+    },
+
+    /**
+         * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
+         */
+    _getTForX: function (aX) {
+      var mX1 = this._p[0],
+        mX2 = this._p[2],
+        mSampleValues = this._mSampleValues;
+
+      var intervalStart = 0.0;
+      var currentSample = 1;
+      var lastSample = kSplineTableSize - 1;
+
+      for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
+        intervalStart += kSampleStepSize;
+      }
+      --currentSample;
+
+      // Interpolate to provide an initial guess for t
+      var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
+      var guessForT = intervalStart + dist * kSampleStepSize;
+
+      var initialSlope = getSlope(guessForT, mX1, mX2);
+      if (initialSlope >= NEWTON_MIN_SLOPE) {
+        return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
+      } if (initialSlope === 0.0) {
+        return guessForT;
+      }
+      return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
+    },
+  };
+
+  return ob;
+}());
+
+const pooling = (function () {
+  function double(arr) {
+    return arr.concat(createSizedArray(arr.length));
+  }
+
+  return {
+    double: double,
+  };
+}());
+
+const poolFactory = (function () {
+  return function (initialLength, _create, _release) {
+    var _length = 0;
+    var _maxLength = initialLength;
+    var pool = createSizedArray(_maxLength);
+
+    var ob = {
+      newElement: newElement,
+      release: release,
+    };
+
+    function newElement() {
+      var element;
+      if (_length) {
+        _length -= 1;
+        element = pool[_length];
+      } else {
+        element = _create();
+      }
+      return element;
+    }
+
+    function release(element) {
+      if (_length === _maxLength) {
+        pool = pooling.double(pool);
+        _maxLength *= 2;
+      }
+      if (_release) {
+        _release(element);
+      }
+      pool[_length] = element;
+      _length += 1;
+    }
+
+    return ob;
+  };
+}());
+
+const bezierLengthPool = (function () {
+  function create() {
+    return {
+      addedLength: 0,
+      percents: createTypedArray('float32', getDefaultCurveSegments()),
+      lengths: createTypedArray('float32', getDefaultCurveSegments()),
+    };
+  }
+  return poolFactory(8, create);
+}());
+
+const segmentsLengthPool = (function () {
+  function create() {
+    return {
+      lengths: [],
+      totalLength: 0,
+    };
+  }
+
+  function release(element) {
+    var i;
+    var len = element.lengths.length;
+    for (i = 0; i < len; i += 1) {
+      bezierLengthPool.release(element.lengths[i]);
+    }
+    element.lengths.length = 0;
+  }
+
+  return poolFactory(8, create, release);
+}());
+
+function bezFunction() {
+  var math = Math;
+
+  function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
+    var det1 = (x1 * y2) + (y1 * x3) + (x2 * y3) - (x3 * y2) - (y3 * x1) - (x2 * y1);
+    return det1 > -0.001 && det1 < 0.001;
+  }
+
+  function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
+    if (z1 === 0 && z2 === 0 && z3 === 0) {
+      return pointOnLine2D(x1, y1, x2, y2, x3, y3);
+    }
+    var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
+    var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
+    var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
+    var diffDist;
+    if (dist1 > dist2) {
+      if (dist1 > dist3) {
+        diffDist = dist1 - dist2 - dist3;
+      } else {
+        diffDist = dist3 - dist2 - dist1;
+      }
+    } else if (dist3 > dist2) {
+      diffDist = dist3 - dist2 - dist1;
+    } else {
+      diffDist = dist2 - dist1 - dist3;
+    }
+    return diffDist > -0.0001 && diffDist < 0.0001;
+  }
+
+  var getBezierLength = (function () {
+    return function (pt1, pt2, pt3, pt4) {
+      var curveSegments = getDefaultCurveSegments();
+      var k;
+      var i;
+      var len;
+      var ptCoord;
+      var perc;
+      var addedLength = 0;
+      var ptDistance;
+      var point = [];
+      var lastPoint = [];
+      var lengthData = bezierLengthPool.newElement();
+      len = pt3.length;
+      for (k = 0; k < curveSegments; k += 1) {
+        perc = k / (curveSegments - 1);
+        ptDistance = 0;
+        for (i = 0; i < len; i += 1) {
+          ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
+          point[i] = ptCoord;
+          if (lastPoint[i] !== null) {
+            ptDistance += bmPow(point[i] - lastPoint[i], 2);
+          }
+          lastPoint[i] = point[i];
+        }
+        if (ptDistance) {
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+        }
+        lengthData.percents[k] = perc;
+        lengthData.lengths[k] = addedLength;
+      }
+      lengthData.addedLength = addedLength;
+      return lengthData;
+    };
+  }());
+
+  function getSegmentsLength(shapeData) {
+    var segmentsLength = segmentsLengthPool.newElement();
+    var closed = shapeData.c;
+    var pathV = shapeData.v;
+    var pathO = shapeData.o;
+    var pathI = shapeData.i;
+    var i;
+    var len = shapeData._length;
+    var lengths = segmentsLength.lengths;
+    var totalLength = 0;
+    for (i = 0; i < len - 1; i += 1) {
+      lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
+      totalLength += lengths[i].addedLength;
+    }
+    if (closed && len) {
+      lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
+      totalLength += lengths[i].addedLength;
+    }
+    segmentsLength.totalLength = totalLength;
+    return segmentsLength;
+  }
+
+  function BezierData(length) {
+    this.segmentLength = 0;
+    this.points = new Array(length);
+  }
+
+  function PointData(partial, point) {
+    this.partialLength = partial;
+    this.point = point;
+  }
+
+  var buildBezierData = (function () {
+    var storedData = {};
+
+    return function (pt1, pt2, pt3, pt4) {
+      var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
+      if (!storedData[bezierName]) {
+        var curveSegments = getDefaultCurveSegments();
+        var k;
+        var i;
+        var len;
+        var ptCoord;
+        var perc;
+        var addedLength = 0;
+        var ptDistance;
+        var point;
+        var lastPoint = null;
+        if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
+          curveSegments = 2;
+        }
+        var bezierData = new BezierData(curveSegments);
+        len = pt3.length;
+        for (k = 0; k < curveSegments; k += 1) {
+          point = createSizedArray(len);
+          perc = k / (curveSegments - 1);
+          ptDistance = 0;
+          for (i = 0; i < len; i += 1) {
+            ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
+            point[i] = ptCoord;
+            if (lastPoint !== null) {
+              ptDistance += bmPow(point[i] - lastPoint[i], 2);
+            }
+          }
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+          bezierData.points[k] = new PointData(ptDistance, point);
+          lastPoint = point;
+        }
+        bezierData.segmentLength = addedLength;
+        storedData[bezierName] = bezierData;
+      }
+      return storedData[bezierName];
+    };
+  }());
+
+  function getDistancePerc(perc, bezierData) {
+    var percents = bezierData.percents;
+    var lengths = bezierData.lengths;
+    var len = percents.length;
+    var initPos = bmFloor((len - 1) * perc);
+    var lengthPos = perc * bezierData.addedLength;
+    var lPerc = 0;
+    if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
+      return percents[initPos];
+    }
+    var dir = lengths[initPos] > lengthPos ? -1 : 1;
+    var flag = true;
+    while (flag) {
+      if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
+        lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
+        flag = false;
+      } else {
+        initPos += dir;
+      }
+      if (initPos < 0 || initPos >= len - 1) {
+        // FIX for TypedArrays that don't store floating point values with enough accuracy
+        if (initPos === len - 1) {
+          return percents[initPos];
+        }
+        flag = false;
+      }
+    }
+    return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
+  }
+
+  function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
+    var t1 = getDistancePerc(percent, bezierData);
+    var u1 = 1 - t1;
+    var ptX = math.round((u1 * u1 * u1 * pt1[0] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[0] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[0] + t1 * t1 * t1 * pt2[0]) * 1000) / 1000;
+    var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
+    return [ptX, ptY];
+  }
+
+  var bezierSegmentPoints = createTypedArray('float32', 8);
+
+  function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
+    if (startPerc < 0) {
+      startPerc = 0;
+    } else if (startPerc > 1) {
+      startPerc = 1;
+    }
+    var t0 = getDistancePerc(startPerc, bezierData);
+    endPerc = endPerc > 1 ? 1 : endPerc;
+    var t1 = getDistancePerc(endPerc, bezierData);
+    var i;
+    var len = pt1.length;
+    var u0 = 1 - t0;
+    var u1 = 1 - t1;
+    var u0u0u0 = u0 * u0 * u0;
+    var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0t0 = t0 * t0 * t0;
+    //
+    var u0u0u1 = u0 * u0 * u1;
+    var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0t1 = t0 * t0 * t1;
+    //
+    var u0u1u1 = u0 * u1 * u1;
+    var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1t1 = t0 * t1 * t1;
+    //
+    var u1u1u1 = u1 * u1 * u1;
+    var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1t1 = t1 * t1 * t1;
+    for (i = 0; i < len; i += 1) {
+      bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+    }
+
+    return bezierSegmentPoints;
+  }
+
+  return {
+    getSegmentsLength: getSegmentsLength,
+    getNewSegment: getNewSegment,
+    getPointInSegment: getPointInSegment,
+    buildBezierData: buildBezierData,
+    pointOnLine2D: pointOnLine2D,
+    pointOnLine3D: pointOnLine3D,
+  };
+}
+
+const bez = bezFunction();
+
+var initFrame = initialDefaultFrame;
+var mathAbs = Math.abs;
+
+function interpolateValue(frameNum, caching) {
+  var offsetTime = this.offsetTime;
+  var newValue;
+  if (this.propType === 'multidimensional') {
+    newValue = createTypedArray('float32', this.pv.length);
+  }
+  var iterationIndex = caching.lastIndex;
+  var i = iterationIndex;
+  var len = this.keyframes.length - 1;
+  var flag = true;
+  var keyData;
+  var nextKeyData;
+  var keyframeMetadata;
+
+  while (flag) {
+    keyData = this.keyframes[i];
+    nextKeyData = this.keyframes[i + 1];
+    if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
+      if (keyData.h) {
+        keyData = nextKeyData;
+      }
+      iterationIndex = 0;
+      break;
+    }
+    if ((nextKeyData.t - offsetTime) > frameNum) {
+      iterationIndex = i;
+      break;
+    }
+    if (i < len - 1) {
+      i += 1;
+    } else {
+      iterationIndex = 0;
+      flag = false;
+    }
+  }
+  keyframeMetadata = this.keyframesMetadata[i] || {};
+
+  var k;
+  var kLen;
+  var perc;
+  var jLen;
+  var j;
+  var fnc;
+  var nextKeyTime = nextKeyData.t - offsetTime;
+  var keyTime = keyData.t - offsetTime;
+  var endValue;
+  if (keyData.to) {
+    if (!keyframeMetadata.bezierData) {
+      keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
+    }
+    var bezierData = keyframeMetadata.bezierData;
+    if (frameNum >= nextKeyTime || frameNum < keyTime) {
+      var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
+      kLen = bezierData.points[ind].point.length;
+      for (k = 0; k < kLen; k += 1) {
+        newValue[k] = bezierData.points[ind].point[k];
+      }
+      // caching._lastKeyframeIndex = -1;
+    } else {
+      if (keyframeMetadata.__fnct) {
+        fnc = keyframeMetadata.__fnct;
+      } else {
+        fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
+        keyframeMetadata.__fnct = fnc;
+      }
+      perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+      var distanceInLine = bezierData.segmentLength * perc;
+
+      var segmentPerc;
+      var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0;
+      j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0;
+      flag = true;
+      jLen = bezierData.points.length;
+      while (flag) {
+        addedLength += bezierData.points[j].partialLength;
+        if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k];
+          }
+          break;
+        } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
+          segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
+          }
+          break;
+        }
+        if (j < jLen - 1) {
+          j += 1;
+        } else {
+          flag = false;
+        }
+      }
+      caching._lastPoint = j;
+      caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
+      caching._lastKeyframeIndex = i;
+    }
+  } else {
+    var outX;
+    var outY;
+    var inX;
+    var inY;
+    var keyValue;
+    len = keyData.s.length;
+    endValue = nextKeyData.s || keyData.e;
+    if (this.sh && keyData.h !== 1) {
+      if (frameNum >= nextKeyTime) {
+        newValue[0] = endValue[0];
+        newValue[1] = endValue[1];
+        newValue[2] = endValue[2];
+      } else if (frameNum <= keyTime) {
+        newValue[0] = keyData.s[0];
+        newValue[1] = keyData.s[1];
+        newValue[2] = keyData.s[2];
+      } else {
+        var quatStart = createQuaternion(keyData.s);
+        var quatEnd = createQuaternion(endValue);
+        var time = (frameNum - keyTime) / (nextKeyTime - keyTime);
+        quaternionToEuler(newValue, slerp(quatStart, quatEnd, time));
+      }
+    } else {
+      for (i = 0; i < len; i += 1) {
+        if (keyData.h !== 1) {
+          if (frameNum >= nextKeyTime) {
+            perc = 1;
+          } else if (frameNum < keyTime) {
+            perc = 0;
+          } else {
+            if (keyData.o.x.constructor === Array) {
+              if (!keyframeMetadata.__fnct) {
+                keyframeMetadata.__fnct = [];
+              }
+              if (!keyframeMetadata.__fnct[i]) {
+                outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
+                outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
+                inX = keyData.i.x[i] === undefined ? keyData.i.x[0] : keyData.i.x[i];
+                inY = keyData.i.y[i] === undefined ? keyData.i.y[0] : keyData.i.y[i];
+                fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+                keyframeMetadata.__fnct[i] = fnc;
+              } else {
+                fnc = keyframeMetadata.__fnct[i];
+              }
+            } else if (!keyframeMetadata.__fnct) {
+              outX = keyData.o.x;
+              outY = keyData.o.y;
+              inX = keyData.i.x;
+              inY = keyData.i.y;
+              fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+              keyData.keyframeMetadata = fnc;
+            } else {
+              fnc = keyframeMetadata.__fnct;
+            }
+            perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+          }
+        }
+
+        endValue = nextKeyData.s || keyData.e;
+        keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
+
+        if (this.propType === 'multidimensional') {
+          newValue[i] = keyValue;
+        } else {
+          newValue = keyValue;
+        }
+      }
+    }
+  }
+  caching.lastIndex = iterationIndex;
+  return newValue;
+}
+
+// based on @Toji's https://github.com/toji/gl-matrix/
+function slerp(a, b, t) {
+  var out = [];
+  var ax = a[0];
+  var ay = a[1];
+  var az = a[2];
+  var aw = a[3];
+  var bx = b[0];
+  var by = b[1];
+  var bz = b[2];
+  var bw = b[3];
+
+  var omega;
+  var cosom;
+  var sinom;
+  var scale0;
+  var scale1;
+
+  cosom = ax * bx + ay * by + az * bz + aw * bw;
+  if (cosom < 0.0) {
+    cosom = -cosom;
+    bx = -bx;
+    by = -by;
+    bz = -bz;
+    bw = -bw;
+  }
+  if ((1.0 - cosom) > 0.000001) {
+    omega = Math.acos(cosom);
+    sinom = Math.sin(omega);
+    scale0 = Math.sin((1.0 - t) * omega) / sinom;
+    scale1 = Math.sin(t * omega) / sinom;
+  } else {
+    scale0 = 1.0 - t;
+    scale1 = t;
+  }
+  out[0] = scale0 * ax + scale1 * bx;
+  out[1] = scale0 * ay + scale1 * by;
+  out[2] = scale0 * az + scale1 * bz;
+  out[3] = scale0 * aw + scale1 * bw;
+
+  return out;
+}
+
+function quaternionToEuler(out, quat) {
+  var qx = quat[0];
+  var qy = quat[1];
+  var qz = quat[2];
+  var qw = quat[3];
+  var heading = Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy * qy - 2 * qz * qz);
+  var attitude = Math.asin(2 * qx * qy + 2 * qz * qw);
+  var bank = Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx * qx - 2 * qz * qz);
+  out[0] = heading / degToRads;
+  out[1] = attitude / degToRads;
+  out[2] = bank / degToRads;
+}
+
+function createQuaternion(values) {
+  var heading = values[0] * degToRads;
+  var attitude = values[1] * degToRads;
+  var bank = values[2] * degToRads;
+  var c1 = Math.cos(heading / 2);
+  var c2 = Math.cos(attitude / 2);
+  var c3 = Math.cos(bank / 2);
+  var s1 = Math.sin(heading / 2);
+  var s2 = Math.sin(attitude / 2);
+  var s3 = Math.sin(bank / 2);
+  var w = c1 * c2 * c3 - s1 * s2 * s3;
+  var x = s1 * s2 * c3 + c1 * c2 * s3;
+  var y = s1 * c2 * c3 + c1 * s2 * s3;
+  var z = c1 * s2 * c3 - s1 * c2 * s3;
+
+  return [x, y, z, w];
+}
+
+function getValueAtCurrentTime() {
+  var frameNum = this.comp.renderedFrame - this.offsetTime;
+  var initTime = this.keyframes[0].t - this.offsetTime;
+  var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+  if (!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))) {
+    if (this._caching.lastFrame >= frameNum) {
+      this._caching._lastKeyframeIndex = -1;
+      this._caching.lastIndex = 0;
+    }
+
+    var renderResult = this.interpolateValue(frameNum, this._caching);
+    this.pv = renderResult;
+  }
+  this._caching.lastFrame = frameNum;
+  return this.pv;
+}
+
+function setVValue(val) {
+  var multipliedValue;
+  if (this.propType === 'unidimensional') {
+    multipliedValue = val * this.mult;
+    if (mathAbs(this.v - multipliedValue) > 0.00001) {
+      this.v = multipliedValue;
+      this._mdf = true;
+    }
+  } else {
+    var i = 0;
+    var len = this.v.length;
+    while (i < len) {
+      multipliedValue = val[i] * this.mult;
+      if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
+        this.v[i] = multipliedValue;
+        this._mdf = true;
+      }
+      i += 1;
+    }
+  }
+}
+
+function processEffectsSequence() {
+  if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
+    return;
+  }
+  if (this.lock) {
+    this.setVValue(this.pv);
+    return;
+  }
+  this.lock = true;
+  this._mdf = this._isFirstFrame;
+  var i;
+  var len = this.effectsSequence.length;
+  var finalValue = this.kf ? this.pv : this.data.k;
+  for (i = 0; i < len; i += 1) {
+    finalValue = this.effectsSequence[i](finalValue);
+  }
+  this.setVValue(finalValue);
+  this._isFirstFrame = false;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+}
+
+function addEffect(effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.container.addDynamicProperty(this);
+}
+
+function ValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this.v = mult ? data.k * mult : data.k;
+  this.pv = data.k;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.vel = 0;
+  this.effectsSequence = [];
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function MultiDimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.frameId = -1;
+  var i;
+  var len = data.k.length;
+  this.v = createTypedArray('float32', len);
+  this.pv = createTypedArray('float32', len);
+  this.vel = createTypedArray('float32', len);
+  for (i = 0; i < len; i += 1) {
+    this.v[i] = data.k[i] * this.mult;
+    this.pv[i] = data.k[i];
+  }
+  this._isFirstFrame = true;
+  this.effectsSequence = [];
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function KeyframedValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.frameId = -1;
+  this._caching = {
+    lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1,
+  };
+  this.k = true;
+  this.kf = true;
+  this.data = data;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.v = initFrame;
+  this.pv = initFrame;
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.addEffect = addEffect;
+}
+
+function KeyframedMultidimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  var i;
+  var len = data.k.length;
+  var s;
+  var e;
+  var to;
+  var ti;
+  for (i = 0; i < len - 1; i += 1) {
+    if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
+      s = data.k[i].s;
+      e = data.k[i + 1].s;
+      to = data.k[i].to;
+      ti = data.k[i].ti;
+      if ((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2]))) {
+        data.k[i].to = null;
+        data.k[i].ti = null;
+      }
+      if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
+        if (s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) {
+          data.k[i].to = null;
+          data.k[i].ti = null;
+        }
+      }
+    }
+  }
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.data = data;
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.k = true;
+  this.kf = true;
+  this._isFirstFrame = true;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.frameId = -1;
+  var arrLen = data.k[0].s.length;
+  this.v = createTypedArray('float32', arrLen);
+  this.pv = createTypedArray('float32', arrLen);
+  for (i = 0; i < arrLen; i += 1) {
+    this.v[i] = initFrame;
+    this.pv[i] = initFrame;
+  }
+  this._caching = { lastFrame: initFrame, lastIndex: 0, value: createTypedArray('float32', arrLen) };
+  this.addEffect = addEffect;
+}
+
+const PropertyFactory = (function () {
+  function getProp(elem, data, type, mult, container) {
+    if (data.sid) {
+      data = elem.globalData.slotManager.getProp(data);
+    }
+    var p;
+    if (!data.k.length) {
+      p = new ValueProperty(elem, data, mult, container);
+    } else if (typeof (data.k[0]) === 'number') {
+      p = new MultiDimensionalProperty(elem, data, mult, container);
+    } else {
+      switch (type) {
+        case 0:
+          p = new KeyframedValueProperty(elem, data, mult, container);
+          break;
+        case 1:
+          p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
+          break;
+        default:
+          break;
+      }
+    }
+    if (p.effectsSequence.length) {
+      container.addDynamicProperty(p);
+    }
+    return p;
+  }
+
+  var ob = {
+    getProp: getProp,
+  };
+  return ob;
+}());
+
+function DynamicPropertyContainer() {}
+DynamicPropertyContainer.prototype = {
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+      this.container.addDynamicProperty(this);
+      this._isAnimated = true;
+    }
+  },
+  iterateDynamicProperties: function () {
+    this._mdf = false;
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      this.dynamicProperties[i].getValue();
+      if (this.dynamicProperties[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  },
+  initDynamicPropertyContainer: function (container) {
+    this.container = container;
+    this.dynamicProperties = [];
+    this._mdf = false;
+    this._isAnimated = false;
+  },
+};
+
+const pointPool = (function () {
+  function create() {
+    return createTypedArray('float32', 2);
+  }
+  return poolFactory(8, create);
+}());
+
+function ShapePath() {
+  this.c = false;
+  this._length = 0;
+  this._maxLength = 8;
+  this.v = createSizedArray(this._maxLength);
+  this.o = createSizedArray(this._maxLength);
+  this.i = createSizedArray(this._maxLength);
+}
+
+ShapePath.prototype.setPathData = function (closed, len) {
+  this.c = closed;
+  this.setLength(len);
+  var i = 0;
+  while (i < len) {
+    this.v[i] = pointPool.newElement();
+    this.o[i] = pointPool.newElement();
+    this.i[i] = pointPool.newElement();
+    i += 1;
+  }
+};
+
+ShapePath.prototype.setLength = function (len) {
+  while (this._maxLength < len) {
+    this.doubleArrayLength();
+  }
+  this._length = len;
+};
+
+ShapePath.prototype.doubleArrayLength = function () {
+  this.v = this.v.concat(createSizedArray(this._maxLength));
+  this.i = this.i.concat(createSizedArray(this._maxLength));
+  this.o = this.o.concat(createSizedArray(this._maxLength));
+  this._maxLength *= 2;
+};
+
+ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
+  var arr;
+  this._length = Math.max(this._length, pos + 1);
+  if (this._length >= this._maxLength) {
+    this.doubleArrayLength();
+  }
+  switch (type) {
+    case 'v':
+      arr = this.v;
+      break;
+    case 'i':
+      arr = this.i;
+      break;
+    case 'o':
+      arr = this.o;
+      break;
+    default:
+      arr = [];
+      break;
+  }
+  if (!arr[pos] || (arr[pos] && !replace)) {
+    arr[pos] = pointPool.newElement();
+  }
+  arr[pos][0] = x;
+  arr[pos][1] = y;
+};
+
+ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
+  this.setXYAt(vX, vY, 'v', pos, replace);
+  this.setXYAt(oX, oY, 'o', pos, replace);
+  this.setXYAt(iX, iY, 'i', pos, replace);
+};
+
+ShapePath.prototype.reverse = function () {
+  var newPath = new ShapePath();
+  newPath.setPathData(this.c, this._length);
+  var vertices = this.v;
+  var outPoints = this.o;
+  var inPoints = this.i;
+  var init = 0;
+  if (this.c) {
+    newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
+    init = 1;
+  }
+  var cnt = this._length - 1;
+  var len = this._length;
+
+  var i;
+  for (i = init; i < len; i += 1) {
+    newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
+    cnt -= 1;
+  }
+  return newPath;
+};
+
+ShapePath.prototype.length = function () {
+  return this._length;
+};
+
+const shapePool = (function () {
+  function create() {
+    return new ShapePath();
+  }
+
+  function release(shapePath) {
+    var len = shapePath._length;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      pointPool.release(shapePath.v[i]);
+      pointPool.release(shapePath.i[i]);
+      pointPool.release(shapePath.o[i]);
+      shapePath.v[i] = null;
+      shapePath.i[i] = null;
+      shapePath.o[i] = null;
+    }
+    shapePath._length = 0;
+    shapePath.c = false;
+  }
+
+  function clone(shape) {
+    var cloned = factory.newElement();
+    var i;
+    var len = shape._length === undefined ? shape.v.length : shape._length;
+    cloned.setLength(len);
+    cloned.c = shape.c;
+
+    for (i = 0; i < len; i += 1) {
+      cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
+    }
+    return cloned;
+  }
+
+  var factory = poolFactory(4, create, release);
+  factory.clone = clone;
+
+  return factory;
+}());
+
+function ShapeCollection() {
+  this._length = 0;
+  this._maxLength = 4;
+  this.shapes = createSizedArray(this._maxLength);
+}
+
+ShapeCollection.prototype.addShape = function (shapeData) {
+  if (this._length === this._maxLength) {
+    this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
+    this._maxLength *= 2;
+  }
+  this.shapes[this._length] = shapeData;
+  this._length += 1;
+};
+
+ShapeCollection.prototype.releaseShapes = function () {
+  var i;
+  for (i = 0; i < this._length; i += 1) {
+    shapePool.release(this.shapes[i]);
+  }
+  this._length = 0;
+};
+
+const shapeCollectionPool = (function () {
+  var ob = {
+    newShapeCollection: newShapeCollection,
+    release: release,
+  };
+
+  var _length = 0;
+  var _maxLength = 4;
+  var pool = createSizedArray(_maxLength);
+
+  function newShapeCollection() {
+    var shapeCollection;
+    if (_length) {
+      _length -= 1;
+      shapeCollection = pool[_length];
+    } else {
+      shapeCollection = new ShapeCollection();
+    }
+    return shapeCollection;
+  }
+
+  function release(shapeCollection) {
+    var i;
+    var len = shapeCollection._length;
+    for (i = 0; i < len; i += 1) {
+      shapePool.release(shapeCollection.shapes[i]);
+    }
+    shapeCollection._length = 0;
+
+    if (_length === _maxLength) {
+      pool = pooling.double(pool);
+      _maxLength *= 2;
+    }
+    pool[_length] = shapeCollection;
+    _length += 1;
+  }
+
+  return ob;
+}());
+
+const ShapePropertyFactory = (function () {
+  var initFrame = -999999;
+
+  function interpolateShape(frameNum, previousValue, caching) {
+    var iterationIndex = caching.lastIndex;
+    var keyPropS;
+    var keyPropE;
+    var isHold;
+    var j;
+    var k;
+    var jLen;
+    var kLen;
+    var perc;
+    var vertexValue;
+    var kf = this.keyframes;
+    if (frameNum < kf[0].t - this.offsetTime) {
+      keyPropS = kf[0].s[0];
+      isHold = true;
+      iterationIndex = 0;
+    } else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) {
+      keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
+      /* if(kf[kf.length - 1].s){
+                keyPropS = kf[kf.length - 1].s[0];
+            }else{
+                keyPropS = kf[kf.length - 2].e[0];
+            } */
+      isHold = true;
+    } else {
+      var i = iterationIndex;
+      var len = kf.length - 1;
+      var flag = true;
+      var keyData;
+      var nextKeyData;
+      var keyframeMetadata;
+      while (flag) {
+        keyData = kf[i];
+        nextKeyData = kf[i + 1];
+        if ((nextKeyData.t - this.offsetTime) > frameNum) {
+          break;
+        }
+        if (i < len - 1) {
+          i += 1;
+        } else {
+          flag = false;
+        }
+      }
+      keyframeMetadata = this.keyframesMetadata[i] || {};
+      isHold = keyData.h === 1;
+      iterationIndex = i;
+      if (!isHold) {
+        if (frameNum >= nextKeyData.t - this.offsetTime) {
+          perc = 1;
+        } else if (frameNum < keyData.t - this.offsetTime) {
+          perc = 0;
+        } else {
+          var fnc;
+          if (keyframeMetadata.__fnct) {
+            fnc = keyframeMetadata.__fnct;
+          } else {
+            fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
+            keyframeMetadata.__fnct = fnc;
+          }
+          perc = fnc((frameNum - (keyData.t - this.offsetTime)) / ((nextKeyData.t - this.offsetTime) - (keyData.t - this.offsetTime)));
+        }
+        keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
+      }
+      keyPropS = keyData.s[0];
+    }
+    jLen = previousValue._length;
+    kLen = keyPropS.i[0].length;
+    caching.lastIndex = iterationIndex;
+
+    for (j = 0; j < jLen; j += 1) {
+      for (k = 0; k < kLen; k += 1) {
+        vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
+        previousValue.i[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc;
+        previousValue.o[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc;
+        previousValue.v[j][k] = vertexValue;
+      }
+    }
+  }
+
+  function interpolateShapeCurrentTime() {
+    var frameNum = this.comp.renderedFrame - this.offsetTime;
+    var initTime = this.keyframes[0].t - this.offsetTime;
+    var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+    var lastFrame = this._caching.lastFrame;
+    if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) {
+      /// /
+      this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
+      this.interpolateShape(frameNum, this.pv, this._caching);
+      /// /
+    }
+    this._caching.lastFrame = frameNum;
+    return this.pv;
+  }
+
+  function resetShape() {
+    this.paths = this.localShapeCollection;
+  }
+
+  function shapesEqual(shape1, shape2) {
+    if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
+      return false;
+    }
+    var i;
+    var len = shape1._length;
+    for (i = 0; i < len; i += 1) {
+      if (shape1.v[i][0] !== shape2.v[i][0]
+            || shape1.v[i][1] !== shape2.v[i][1]
+            || shape1.o[i][0] !== shape2.o[i][0]
+            || shape1.o[i][1] !== shape2.o[i][1]
+            || shape1.i[i][0] !== shape2.i[i][0]
+            || shape1.i[i][1] !== shape2.i[i][1]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  function setVValue(newPath) {
+    if (!shapesEqual(this.v, newPath)) {
+      this.v = shapePool.clone(newPath);
+      this.localShapeCollection.releaseShapes();
+      this.localShapeCollection.addShape(this.v);
+      this._mdf = true;
+      this.paths = this.localShapeCollection;
+    }
+  }
+
+  function processEffectsSequence() {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    } if (!this.effectsSequence.length) {
+      this._mdf = false;
+      return;
+    }
+    if (this.lock) {
+      this.setVValue(this.pv);
+      return;
+    }
+    this.lock = true;
+    this._mdf = false;
+    var finalValue;
+    if (this.kf) {
+      finalValue = this.pv;
+    } else if (this.data.ks) {
+      finalValue = this.data.ks.k;
+    } else {
+      finalValue = this.data.pt.k;
+    }
+    var i;
+    var len = this.effectsSequence.length;
+    for (i = 0; i < len; i += 1) {
+      finalValue = this.effectsSequence[i](finalValue);
+    }
+    this.setVValue(finalValue);
+    this.lock = false;
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function ShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.container = elem;
+    this.elem = elem;
+    this.data = data;
+    this.k = false;
+    this.kf = false;
+    this._mdf = false;
+    var pathData = type === 3 ? data.pt.k : data.ks.k;
+    this.v = shapePool.clone(pathData);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.reset = resetShape;
+    this.effectsSequence = [];
+  }
+
+  function addEffect(effectFunction) {
+    this.effectsSequence.push(effectFunction);
+    this.container.addDynamicProperty(this);
+  }
+
+  ShapeProperty.prototype.interpolateShape = interpolateShape;
+  ShapeProperty.prototype.getValue = processEffectsSequence;
+  ShapeProperty.prototype.setVValue = setVValue;
+  ShapeProperty.prototype.addEffect = addEffect;
+
+  function KeyframedShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.elem = elem;
+    this.container = elem;
+    this.offsetTime = elem.data.st;
+    this.keyframes = type === 3 ? data.pt.k : data.ks.k;
+    this.keyframesMetadata = [];
+    this.k = true;
+    this.kf = true;
+    var len = this.keyframes[0].s[0].i.length;
+    this.v = shapePool.newElement();
+    this.v.setPathData(this.keyframes[0].s[0].c, len);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.lastFrame = initFrame;
+    this.reset = resetShape;
+    this._caching = { lastFrame: initFrame, lastIndex: 0 };
+    this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
+  }
+  KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
+  KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
+  KeyframedShapeProperty.prototype.setVValue = setVValue;
+  KeyframedShapeProperty.prototype.addEffect = addEffect;
+
+  var EllShapeProperty = (function () {
+    var cPoint = roundCorner;
+
+    function EllShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 4);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.paths = this.localShapeCollection;
+      this.localShapeCollection.addShape(this.v);
+      this.d = data.d;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertEllToPath();
+      }
+    }
+
+    EllShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+
+        if (this._mdf) {
+          this.convertEllToPath();
+        }
+      },
+      convertEllToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var s0 = this.s.v[0] / 2;
+        var s1 = this.s.v[1] / 2;
+        var _cw = this.d !== 3;
+        var _v = this.v;
+        _v.v[0][0] = p0;
+        _v.v[0][1] = p1 - s1;
+        _v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.v[1][1] = p1;
+        _v.v[2][0] = p0;
+        _v.v[2][1] = p1 + s1;
+        _v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.v[3][1] = p1;
+        _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.i[0][1] = p1 - s1;
+        _v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.i[1][1] = p1 - s1 * cPoint;
+        _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.i[2][1] = p1 + s1;
+        _v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.i[3][1] = p1 + s1 * cPoint;
+        _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.o[0][1] = p1 - s1;
+        _v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.o[1][1] = p1 + s1 * cPoint;
+        _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.o[2][1] = p1 + s1;
+        _v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.o[3][1] = p1 - s1 * cPoint;
+      },
+    };
+
+    extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
+
+    return EllShapePropertyFactory;
+  }());
+
+  var StarShapeProperty = (function () {
+    function StarShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 0);
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.data = data;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      if (data.sy === 1) {
+        this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
+        this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
+        this.convertToPath = this.convertStarToPath;
+      } else {
+        this.convertToPath = this.convertPolygonToPath;
+      }
+      this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
+      this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this);
+      this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertToPath();
+      }
+    }
+
+    StarShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertToPath();
+        }
+      },
+      convertStarToPath: function () {
+        var numPts = Math.floor(this.pt.v) * 2;
+        var angle = (Math.PI * 2) / numPts;
+        /* this.v.v.length = numPts;
+                this.v.i.length = numPts;
+                this.v.o.length = numPts; */
+        var longFlag = true;
+        var longRad = this.or.v;
+        var shortRad = this.ir.v;
+        var longRound = this.os.v;
+        var shortRound = this.is.v;
+        var longPerimSegment = (2 * Math.PI * longRad) / (numPts * 2);
+        var shortPerimSegment = (2 * Math.PI * shortRad) / (numPts * 2);
+        var i;
+        var rad;
+        var roundness;
+        var perimSegment;
+        var currentAng = -Math.PI / 2;
+        currentAng += this.r.v;
+        var dir = this.data.d === 3 ? -1 : 1;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          rad = longFlag ? longRad : shortRad;
+          roundness = longFlag ? longRound : shortRound;
+          perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
+          /* this.v.v[i] = [x,y];
+                    this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
+                    this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
+                    this.v._length = numPts; */
+          longFlag = !longFlag;
+          currentAng += angle * dir;
+        }
+      },
+      convertPolygonToPath: function () {
+        var numPts = Math.floor(this.pt.v);
+        var angle = (Math.PI * 2) / numPts;
+        var rad = this.or.v;
+        var roundness = this.os.v;
+        var perimSegment = (2 * Math.PI * rad) / (numPts * 4);
+        var i;
+        var currentAng = -Math.PI * 0.5;
+        var dir = this.data.d === 3 ? -1 : 1;
+        currentAng += this.r.v;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+          currentAng += angle * dir;
+        }
+        this.paths.length = 0;
+        this.paths[0] = this.v;
+      },
+
+    };
+    extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
+
+    return StarShapePropertyFactory;
+  }());
+
+  var RectShapeProperty = (function () {
+    function RectShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.c = true;
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertRectToPath();
+      }
+    }
+
+    RectShapePropertyFactory.prototype = {
+      convertRectToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var v0 = this.s.v[0] / 2;
+        var v1 = this.s.v[1] / 2;
+        var round = bmMin(v0, v1, this.r.v);
+        var cPoint = round * (1 - roundCorner);
+        this.v._length = 0;
+
+        if (this.d === 2 || this.d === 1) {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
+          this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2);
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3);
+          }
+        } else {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true);
+          }
+        }
+      },
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertRectToPath();
+        }
+      },
+      reset: resetShape,
+    };
+    extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
+
+    return RectShapePropertyFactory;
+  }());
+
+  function getShapeProp(elem, data, type) {
+    var prop;
+    if (type === 3 || type === 4) {
+      var dataProp = type === 3 ? data.pt : data.ks;
+      var keys = dataProp.k;
+      if (keys.length) {
+        prop = new KeyframedShapeProperty(elem, data, type);
+      } else {
+        prop = new ShapeProperty(elem, data, type);
+      }
+    } else if (type === 5) {
+      prop = new RectShapeProperty(elem, data);
+    } else if (type === 6) {
+      prop = new EllShapeProperty(elem, data);
+    } else if (type === 7) {
+      prop = new StarShapeProperty(elem, data);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  }
+
+  function getConstructorFunction() {
+    return ShapeProperty;
+  }
+
+  function getKeyframedConstructorFunction() {
+    return KeyframedShapeProperty;
+  }
+
+  var ob = {};
+  ob.getShapeProp = getShapeProp;
+  ob.getConstructorFunction = getConstructorFunction;
+  ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction;
+  return ob;
+}());
+
+/*!
+ Transformation Matrix v2.0
+ (c) Epistemex 2014-2015
+ www.epistemex.com
+ By Ken Fyrstenberg
+ Contributions by leeoniya.
+ License: MIT, header required.
+ */
+
+/**
+ * 2D transformation matrix object initialized with identity matrix.
+ *
+ * The matrix can synchronize a canvas context by supplying the context
+ * as an argument, or later apply current absolute transform to an
+ * existing context.
+ *
+ * All values are handled as floating point values.
+ *
+ * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix
+ * @prop {number} a - scale x
+ * @prop {number} b - shear y
+ * @prop {number} c - shear x
+ * @prop {number} d - scale y
+ * @prop {number} e - translate x
+ * @prop {number} f - translate y
+ * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context
+ * @constructor
+ */
+
+const Matrix = (function () {
+  var _cos = Math.cos;
+  var _sin = Math.sin;
+  var _tan = Math.tan;
+  var _rnd = Math.round;
+
+  function reset() {
+    this.props[0] = 1;
+    this.props[1] = 0;
+    this.props[2] = 0;
+    this.props[3] = 0;
+    this.props[4] = 0;
+    this.props[5] = 1;
+    this.props[6] = 0;
+    this.props[7] = 0;
+    this.props[8] = 0;
+    this.props[9] = 0;
+    this.props[10] = 1;
+    this.props[11] = 0;
+    this.props[12] = 0;
+    this.props[13] = 0;
+    this.props[14] = 0;
+    this.props[15] = 1;
+    return this;
+  }
+
+  function rotate(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function rotateX(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateY(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateZ(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function shear(sx, sy) {
+    return this._t(1, sy, sx, 1, 0, 0);
+  }
+
+  function skew(ax, ay) {
+    return this.shear(_tan(ax), _tan(ay));
+  }
+
+  function skewFromAxis(ax, angle) {
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+    // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+  }
+
+  function scale(sx, sy, sz) {
+    if (!sz && sz !== 0) {
+      sz = 1;
+    }
+    if (sx === 1 && sy === 1 && sz === 1) {
+      return this;
+    }
+    return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
+  }
+
+  function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
+    this.props[0] = a;
+    this.props[1] = b;
+    this.props[2] = c;
+    this.props[3] = d;
+    this.props[4] = e;
+    this.props[5] = f;
+    this.props[6] = g;
+    this.props[7] = h;
+    this.props[8] = i;
+    this.props[9] = j;
+    this.props[10] = k;
+    this.props[11] = l;
+    this.props[12] = m;
+    this.props[13] = n;
+    this.props[14] = o;
+    this.props[15] = p;
+    return this;
+  }
+
+  function translate(tx, ty, tz) {
+    tz = tz || 0;
+    if (tx !== 0 || ty !== 0 || tz !== 0) {
+      return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
+    }
+    return this;
+  }
+
+  function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
+    var _p = this.props;
+
+    if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
+      // NOTE: commenting this condition because TurboFan deoptimizes code when present
+      // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
+      _p[12] = _p[12] * a2 + _p[15] * m2;
+      _p[13] = _p[13] * f2 + _p[15] * n2;
+      _p[14] = _p[14] * k2 + _p[15] * o2;
+      _p[15] *= p2;
+      // }
+      this._identityCalculated = false;
+      return this;
+    }
+
+    var a1 = _p[0];
+    var b1 = _p[1];
+    var c1 = _p[2];
+    var d1 = _p[3];
+    var e1 = _p[4];
+    var f1 = _p[5];
+    var g1 = _p[6];
+    var h1 = _p[7];
+    var i1 = _p[8];
+    var j1 = _p[9];
+    var k1 = _p[10];
+    var l1 = _p[11];
+    var m1 = _p[12];
+    var n1 = _p[13];
+    var o1 = _p[14];
+    var p1 = _p[15];
+
+    /* matrix order (canvas compatible):
+         * ace
+         * bdf
+         * 001
+         */
+    _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
+    _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
+    _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
+    _p[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2;
+
+    _p[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2;
+    _p[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2;
+    _p[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2;
+    _p[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2;
+
+    _p[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2;
+    _p[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2;
+    _p[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2;
+    _p[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2;
+
+    _p[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2;
+    _p[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2;
+    _p[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2;
+    _p[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2;
+
+    this._identityCalculated = false;
+    return this;
+  }
+
+  function multiply(matrix) {
+    var matrixProps = matrix.props;
+    return this.transform(
+      matrixProps[0],
+      matrixProps[1],
+      matrixProps[2],
+      matrixProps[3],
+      matrixProps[4],
+      matrixProps[5],
+      matrixProps[6],
+      matrixProps[7],
+      matrixProps[8],
+      matrixProps[9],
+      matrixProps[10],
+      matrixProps[11],
+      matrixProps[12],
+      matrixProps[13],
+      matrixProps[14],
+      matrixProps[15]
+    );
+  }
+
+  function isIdentity() {
+    if (!this._identityCalculated) {
+      this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
+      this._identityCalculated = true;
+    }
+    return this._identity;
+  }
+
+  function equals(matr) {
+    var i = 0;
+    while (i < 16) {
+      if (matr.props[i] !== this.props[i]) {
+        return false;
+      }
+      i += 1;
+    }
+    return true;
+  }
+
+  function clone(matr) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      matr.props[i] = this.props[i];
+    }
+    return matr;
+  }
+
+  function cloneFromProps(props) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      this.props[i] = props[i];
+    }
+  }
+
+  function applyToPoint(x, y, z) {
+    return {
+      x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+      y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+      z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+    };
+    /* return {
+         x: x * me.a + y * me.c + me.e,
+         y: x * me.b + y * me.d + me.f
+         }; */
+  }
+  function applyToX(x, y, z) {
+    return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
+  }
+  function applyToY(x, y, z) {
+    return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
+  }
+  function applyToZ(x, y, z) {
+    return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
+  }
+
+  function getInverseMatrix() {
+    var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
+    var a = this.props[5] / determinant;
+    var b = -this.props[1] / determinant;
+    var c = -this.props[4] / determinant;
+    var d = this.props[0] / determinant;
+    var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12]) / determinant;
+    var f = -(this.props[0] * this.props[13] - this.props[1] * this.props[12]) / determinant;
+    var inverseMatrix = new Matrix();
+    inverseMatrix.props[0] = a;
+    inverseMatrix.props[1] = b;
+    inverseMatrix.props[4] = c;
+    inverseMatrix.props[5] = d;
+    inverseMatrix.props[12] = e;
+    inverseMatrix.props[13] = f;
+    return inverseMatrix;
+  }
+
+  function inversePoint(pt) {
+    var inverseMatrix = this.getInverseMatrix();
+    return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
+  }
+
+  function inversePoints(pts) {
+    var i;
+    var len = pts.length;
+    var retPts = [];
+    for (i = 0; i < len; i += 1) {
+      retPts[i] = inversePoint(pts[i]);
+    }
+    return retPts;
+  }
+
+  function applyToTriplePoints(pt1, pt2, pt3) {
+    var arr = createTypedArray('float32', 6);
+    if (this.isIdentity()) {
+      arr[0] = pt1[0];
+      arr[1] = pt1[1];
+      arr[2] = pt2[0];
+      arr[3] = pt2[1];
+      arr[4] = pt3[0];
+      arr[5] = pt3[1];
+    } else {
+      var p0 = this.props[0];
+      var p1 = this.props[1];
+      var p4 = this.props[4];
+      var p5 = this.props[5];
+      var p12 = this.props[12];
+      var p13 = this.props[13];
+      arr[0] = pt1[0] * p0 + pt1[1] * p4 + p12;
+      arr[1] = pt1[0] * p1 + pt1[1] * p5 + p13;
+      arr[2] = pt2[0] * p0 + pt2[1] * p4 + p12;
+      arr[3] = pt2[0] * p1 + pt2[1] * p5 + p13;
+      arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
+      arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
+    }
+    return arr;
+  }
+
+  function applyToPointArray(x, y, z) {
+    var arr;
+    if (this.isIdentity()) {
+      arr = [x, y, z];
+    } else {
+      arr = [
+        x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+        x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+        x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+      ];
+    }
+    return arr;
+  }
+
+  function applyToPointStringified(x, y) {
+    if (this.isIdentity()) {
+      return x + ',' + y;
+    }
+    var _p = this.props;
+    return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
+  }
+
+  function toCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var i = 0;
+    var props = this.props;
+    var cssValue = 'matrix3d(';
+    var v = 10000;
+    while (i < 16) {
+      cssValue += _rnd(props[i] * v) / v;
+      cssValue += i === 15 ? ')' : ',';
+      i += 1;
+    }
+    return cssValue;
+  }
+
+  function roundMatrixProperty(val) {
+    var v = 10000;
+    if ((val < 0.000001 && val > 0) || (val > -0.000001 && val < 0)) {
+      return _rnd(val * v) / v;
+    }
+    return val;
+  }
+
+  function to2dCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var props = this.props;
+    var _a = roundMatrixProperty(props[0]);
+    var _b = roundMatrixProperty(props[1]);
+    var _c = roundMatrixProperty(props[4]);
+    var _d = roundMatrixProperty(props[5]);
+    var _e = roundMatrixProperty(props[12]);
+    var _f = roundMatrixProperty(props[13]);
+    return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
+  }
+
+  return function () {
+    this.reset = reset;
+    this.rotate = rotate;
+    this.rotateX = rotateX;
+    this.rotateY = rotateY;
+    this.rotateZ = rotateZ;
+    this.skew = skew;
+    this.skewFromAxis = skewFromAxis;
+    this.shear = shear;
+    this.scale = scale;
+    this.setTransform = setTransform;
+    this.translate = translate;
+    this.transform = transform;
+    this.multiply = multiply;
+    this.applyToPoint = applyToPoint;
+    this.applyToX = applyToX;
+    this.applyToY = applyToY;
+    this.applyToZ = applyToZ;
+    this.applyToPointArray = applyToPointArray;
+    this.applyToTriplePoints = applyToTriplePoints;
+    this.applyToPointStringified = applyToPointStringified;
+    this.toCSS = toCSS;
+    this.to2dCSS = to2dCSS;
+    this.clone = clone;
+    this.cloneFromProps = cloneFromProps;
+    this.equals = equals;
+    this.inversePoints = inversePoints;
+    this.inversePoint = inversePoint;
+    this.getInverseMatrix = getInverseMatrix;
+    this._t = this.transform;
+    this.isIdentity = isIdentity;
+    this._identity = true;
+    this._identityCalculated = false;
+
+    this.props = createTypedArray('float32', 16);
+    this.reset();
+  };
+}());
+
+const lottie = {};
+var standalone = '__[STANDALONE]__';
+var animationData = '__[ANIMATIONDATA]__';
+var renderer = '';
+
+function setLocation(href) {
+  setLocationHref(href);
+}
+
+function searchAnimations() {
+  if (standalone === true) {
+    animationManager.searchAnimations(animationData, standalone, renderer);
+  } else {
+    animationManager.searchAnimations();
+  }
+}
+
+function setSubframeRendering(flag) {
+  setSubframeEnabled(flag);
+}
+
+function setPrefix(prefix) {
+  setIdPrefix(prefix);
+}
+
+function loadAnimation(params) {
+  if (standalone === true) {
+    params.animationData = JSON.parse(animationData);
+  }
+  return animationManager.loadAnimation(params);
+}
+
+function setQuality(value) {
+  if (typeof value === 'string') {
+    switch (value) {
+      case 'high':
+        setDefaultCurveSegments(200);
+        break;
+      default:
+      case 'medium':
+        setDefaultCurveSegments(50);
+        break;
+      case 'low':
+        setDefaultCurveSegments(10);
+        break;
+    }
+  } else if (!isNaN(value) && value > 1) {
+    setDefaultCurveSegments(value);
+  }
+  if (getDefaultCurveSegments() >= 50) {
+    roundValues(false);
+  } else {
+    roundValues(true);
+  }
+}
+
+function inBrowser() {
+  return typeof navigator !== 'undefined';
+}
+
+function installPlugin(type, plugin) {
+  if (type === 'expressions') {
+    setExpressionsPlugin(plugin);
+  }
+}
+
+function getFactory(name) {
+  switch (name) {
+    case 'propertyFactory':
+      return PropertyFactory;
+    case 'shapePropertyFactory':
+      return ShapePropertyFactory;
+    case 'matrix':
+      return Matrix;
+    default:
+      return null;
+  }
+}
+
+lottie.play = animationManager.play;
+lottie.pause = animationManager.pause;
+lottie.setLocationHref = setLocation;
+lottie.togglePause = animationManager.togglePause;
+lottie.setSpeed = animationManager.setSpeed;
+lottie.setDirection = animationManager.setDirection;
+lottie.stop = animationManager.stop;
+lottie.searchAnimations = searchAnimations;
+lottie.registerAnimation = animationManager.registerAnimation;
+lottie.loadAnimation = loadAnimation;
+lottie.setSubframeRendering = setSubframeRendering;
+lottie.resize = animationManager.resize;
+// lottie.start = start;
+lottie.goToAndStop = animationManager.goToAndStop;
+lottie.destroy = animationManager.destroy;
+lottie.setQuality = setQuality;
+lottie.inBrowser = inBrowser;
+lottie.installPlugin = installPlugin;
+lottie.freeze = animationManager.freeze;
+lottie.unfreeze = animationManager.unfreeze;
+lottie.setVolume = animationManager.setVolume;
+lottie.mute = animationManager.mute;
+lottie.unmute = animationManager.unmute;
+lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations;
+lottie.useWebWorker = setWebWorker;
+lottie.setIDPrefix = setPrefix;
+lottie.__getFactory = getFactory;
+lottie.version = '[[BM_VERSION]]';
+
+function checkReady() {
+  if (document.readyState === 'complete') {
+    clearInterval(readyStateCheckInterval);
+    searchAnimations();
+  }
+}
+
+function getQueryVariable(variable) {
+  var vars = queryString.split('&');
+  for (var i = 0; i < vars.length; i += 1) {
+    var pair = vars[i].split('=');
+    if (decodeURIComponent(pair[0]) == variable) { // eslint-disable-line eqeqeq
+      return decodeURIComponent(pair[1]);
+    }
+  }
+  return null;
+}
+var queryString = '';
+if (standalone) {
+  var scripts = document.getElementsByTagName('script');
+  var index = scripts.length - 1;
+  var myScript = scripts[index] || {
+    src: '',
+  };
+  queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
+  renderer = getQueryVariable('renderer');
+}
+var readyStateCheckInterval = setInterval(checkReady, 100);
+
+// this adds bodymovin to the window object for backwards compatibility
+try {
+  if (!(typeof exports === 'object' && typeof module !== 'undefined')
+    && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
+  ) {
+    window.bodymovin = lottie;
+  }
+} catch (err) {
+  //
+}
+
+const ShapeModifiers = (function () {
+  var ob = {};
+  var modifiers = {};
+  ob.registerModifier = registerModifier;
+  ob.getModifier = getModifier;
+
+  function registerModifier(nm, factory) {
+    if (!modifiers[nm]) {
+      modifiers[nm] = factory;
+    }
+  }
+
+  function getModifier(nm, elem, data) {
+    return new modifiers[nm](elem, data);
+  }
+
+  return ob;
+}());
+
+function ShapeModifier() {}
+ShapeModifier.prototype.initModifierProperties = function () {};
+ShapeModifier.prototype.addShapeToModifier = function () {};
+ShapeModifier.prototype.addShape = function (data) {
+  if (!this.closed) {
+    // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
+    data.sh.container.addDynamicProperty(data.sh);
+    var shapeData = { shape: data.sh, data: data, localShapeCollection: shapeCollectionPool.newShapeCollection() };
+    this.shapes.push(shapeData);
+    this.addShapeToModifier(shapeData);
+    if (this._isAnimated) {
+      data.setAsAnimated();
+    }
+  }
+};
+ShapeModifier.prototype.init = function (elem, data) {
+  this.shapes = [];
+  this.elem = elem;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, data);
+  this.frameId = initialDefaultFrame;
+  this.closed = false;
+  this.k = false;
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+ShapeModifier.prototype.processKeys = function () {
+  if (this.elem.globalData.frameId === this.frameId) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+extendPrototype([DynamicPropertyContainer], ShapeModifier);
+
+function TrimModifier() {
+}
+extendPrototype([ShapeModifier], TrimModifier);
+TrimModifier.prototype.initModifierProperties = function (elem, data) {
+  this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this);
+  this.sValue = 0;
+  this.eValue = 0;
+  this.getValue = this.processKeys;
+  this.m = data.m;
+  this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
+};
+
+TrimModifier.prototype.addShapeToModifier = function (shapeData) {
+  shapeData.pathsData = [];
+};
+
+TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
+  var segments = [];
+  if (e <= 1) {
+    segments.push({
+      s: s,
+      e: e,
+    });
+  } else if (s >= 1) {
+    segments.push({
+      s: s - 1,
+      e: e - 1,
+    });
+  } else {
+    segments.push({
+      s: s,
+      e: 1,
+    });
+    segments.push({
+      s: 0,
+      e: e - 1,
+    });
+  }
+  var shapeSegments = [];
+  var i;
+  var len = segments.length;
+  var segmentOb;
+  for (i = 0; i < len; i += 1) {
+    segmentOb = segments[i];
+    if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
+      var shapeS;
+      var shapeE;
+      if (segmentOb.s * totalModifierLength <= addedLength) {
+        shapeS = 0;
+      } else {
+        shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
+      }
+      if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
+        shapeE = 1;
+      } else {
+        shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength);
+      }
+      shapeSegments.push([shapeS, shapeE]);
+    }
+  }
+  if (!shapeSegments.length) {
+    shapeSegments.push([0, 0]);
+  }
+  return shapeSegments;
+};
+
+TrimModifier.prototype.releasePathsData = function (pathsData) {
+  var i;
+  var len = pathsData.length;
+  for (i = 0; i < len; i += 1) {
+    segmentsLengthPool.release(pathsData[i]);
+  }
+  pathsData.length = 0;
+  return pathsData;
+};
+
+TrimModifier.prototype.processShapes = function (_isFirstFrame) {
+  var s;
+  var e;
+  if (this._mdf || _isFirstFrame) {
+    var o = (this.o.v % 360) / 360;
+    if (o < 0) {
+      o += 1;
+    }
+    if (this.s.v > 1) {
+      s = 1 + o;
+    } else if (this.s.v < 0) {
+      s = 0 + o;
+    } else {
+      s = this.s.v + o;
+    }
+    if (this.e.v > 1) {
+      e = 1 + o;
+    } else if (this.e.v < 0) {
+      e = 0 + o;
+    } else {
+      e = this.e.v + o;
+    }
+
+    if (s > e) {
+      var _s = s;
+      s = e;
+      e = _s;
+    }
+    s = Math.round(s * 10000) * 0.0001;
+    e = Math.round(e * 10000) * 0.0001;
+    this.sValue = s;
+    this.eValue = e;
+  } else {
+    s = this.sValue;
+    e = this.eValue;
+  }
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var pathsData;
+  var pathData;
+  var totalShapeLength;
+  var totalModifierLength = 0;
+
+  if (e === s) {
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].localShapeCollection.releaseShapes();
+      this.shapes[i].shape._mdf = true;
+      this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
+      if (this._mdf) {
+        this.shapes[i].pathsData.length = 0;
+      }
+    }
+  } else if (!((e === 1 && s === 0) || (e === 0 && s === 1))) {
+    var segments = [];
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
+      if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
+        shapeData.shape.paths = shapeData.localShapeCollection;
+      } else {
+        shapePaths = shapeData.shape.paths;
+        jLen = shapePaths._length;
+        totalShapeLength = 0;
+        if (!shapeData.shape._mdf && shapeData.pathsData.length) {
+          totalShapeLength = shapeData.totalShapeLength;
+        } else {
+          pathsData = this.releasePathsData(shapeData.pathsData);
+          for (j = 0; j < jLen; j += 1) {
+            pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
+            pathsData.push(pathData);
+            totalShapeLength += pathData.totalLength;
+          }
+          shapeData.totalShapeLength = totalShapeLength;
+          shapeData.pathsData = pathsData;
+        }
+
+        totalModifierLength += totalShapeLength;
+        shapeData.shape._mdf = true;
+      }
+    }
+    var shapeS = s;
+    var shapeE = e;
+    var addedLength = 0;
+    var edges;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shapeData = this.shapes[i];
+      if (shapeData.shape._mdf) {
+        localShapeCollection = shapeData.localShapeCollection;
+        localShapeCollection.releaseShapes();
+        // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
+        if (this.m === 2 && len > 1) {
+          edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
+          addedLength += shapeData.totalShapeLength;
+        } else {
+          edges = [[shapeS, shapeE]];
+        }
+        jLen = edges.length;
+        for (j = 0; j < jLen; j += 1) {
+          shapeS = edges[j][0];
+          shapeE = edges[j][1];
+          segments.length = 0;
+          if (shapeE <= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength * shapeE,
+            });
+          } else if (shapeS >= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * (shapeS - 1),
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          } else {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength,
+            });
+            segments.push({
+              s: 0,
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          }
+          var newShapesData = this.addShapes(shapeData, segments[0]);
+          if (segments[0].s !== segments[0].e) {
+            if (segments.length > 1) {
+              var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
+              if (lastShapeInCollection.c) {
+                var lastShape = newShapesData.pop();
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1], lastShape);
+              } else {
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1]);
+              }
+            }
+            this.addPaths(newShapesData, localShapeCollection);
+          }
+        }
+        shapeData.shape.paths = localShapeCollection;
+      }
+    }
+  } else if (this._mdf) {
+    for (i = 0; i < len; i += 1) {
+      // Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween.
+      // Don't remove this even if it's losing cached info.
+      this.shapes[i].pathsData.length = 0;
+      this.shapes[i].shape._mdf = true;
+    }
+  }
+};
+
+TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
+  var i;
+  var len = newPaths.length;
+  for (i = 0; i < len; i += 1) {
+    localShapeCollection.addShape(newPaths[i]);
+  }
+};
+
+TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
+  shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
+  shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
+  }
+  shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
+  shapePath.setXYAt(points[1], points[5], 'o', pos);
+  shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(points[0], points[4], 'v', pos);
+  }
+  shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
+  var pathsData = shapeData.pathsData;
+  var shapePaths = shapeData.shape.paths.shapes;
+  var i;
+  var len = shapeData.shape.paths._length;
+  var j;
+  var jLen;
+  var addedLength = 0;
+  var currentLengthData;
+  var segmentCount;
+  var lengths;
+  var segment;
+  var shapes = [];
+  var initPos;
+  var newShape = true;
+  if (!shapePath) {
+    shapePath = shapePool.newElement();
+    segmentCount = 0;
+    initPos = 0;
+  } else {
+    segmentCount = shapePath._length;
+    initPos = shapePath._length;
+  }
+  shapes.push(shapePath);
+  for (i = 0; i < len; i += 1) {
+    lengths = pathsData[i].lengths;
+    shapePath.c = shapePaths[i].c;
+    jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
+    for (j = 1; j < jLen; j += 1) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
+        addedLength += currentLengthData.addedLength;
+        shapePath.c = false;
+      } else if (addedLength > shapeSegment.e) {
+        shapePath.c = false;
+        break;
+      } else {
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+        addedLength += currentLengthData.addedLength;
+        segmentCount += 1;
+      }
+    }
+    if (shapePaths[i].c && lengths.length) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength <= shapeSegment.e) {
+        var segmentLength = lengths[j - 1].addedLength;
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+      } else {
+        shapePath.c = false;
+      }
+      addedLength += currentLengthData.addedLength;
+      segmentCount += 1;
+    }
+    if (shapePath._length) {
+      shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
+      shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
+    }
+    if (addedLength > shapeSegment.e) {
+      break;
+    }
+    if (i < len - 1) {
+      shapePath = shapePool.newElement();
+      newShape = true;
+      shapes.push(shapePath);
+      segmentCount = 0;
+    }
+  }
+  return shapes;
+};
+
+function PuckerAndBloatModifier() {}
+extendPrototype([ShapeModifier], PuckerAndBloatModifier);
+PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this._isAnimated = !!this.amount.effectsSequence.length;
+};
+
+PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
+  var percent = amount / 100;
+  var centerPoint = [0, 0];
+  var pathLength = path._length;
+  var i = 0;
+  for (i = 0; i < pathLength; i += 1) {
+    centerPoint[0] += path.v[i][0];
+    centerPoint[1] += path.v[i][1];
+  }
+  centerPoint[0] /= pathLength;
+  centerPoint[1] /= pathLength;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < pathLength; i += 1) {
+    vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
+    vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
+    oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent;
+    oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent;
+    iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent;
+    iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
+    clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
+  }
+  return clonedPath;
+};
+
+PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+const TransformPropertyFactory = (function () {
+  var defaultVector = [0, 0];
+
+  function applyToMatrix(mat) {
+    var _mdf = this._mdf;
+    this.iterateDynamicProperties();
+    this._mdf = this._mdf || _mdf;
+    if (this.a) {
+      mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+    }
+    if (this.s) {
+      mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+    }
+    if (this.sk) {
+      mat.skewFromAxis(-this.sk.v, this.sa.v);
+    }
+    if (this.r) {
+      mat.rotate(-this.r.v);
+    } else {
+      mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+    }
+    if (this.data.p.s) {
+      if (this.data.p.z) {
+        mat.translate(this.px.v, this.py.v, -this.pz.v);
+      } else {
+        mat.translate(this.px.v, this.py.v, 0);
+      }
+    } else {
+      mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+    }
+  }
+  function processKeys(forceRender) {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    }
+    if (this._isDirty) {
+      this.precalculateMatrix();
+      this._isDirty = false;
+    }
+
+    this.iterateDynamicProperties();
+
+    if (this._mdf || forceRender) {
+      var frameRate;
+      this.v.cloneFromProps(this.pre.props);
+      if (this.appliedTransformations < 1) {
+        this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      }
+      if (this.appliedTransformations < 2) {
+        this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      }
+      if (this.sk && this.appliedTransformations < 3) {
+        this.v.skewFromAxis(-this.sk.v, this.sa.v);
+      }
+      if (this.r && this.appliedTransformations < 4) {
+        this.v.rotate(-this.r.v);
+      } else if (!this.r && this.appliedTransformations < 4) {
+        this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+          .rotateY(this.or.v[1])
+          .rotateX(this.or.v[0]);
+      }
+      if (this.autoOriented) {
+        var v1;
+        var v2;
+        frameRate = this.elem.globalData.frameRate;
+        if (this.p && this.p.keyframes && this.p.getValueAtTime) {
+          if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
+            v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0);
+          } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0);
+            v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0);
+          } else {
+            v1 = this.p.pv;
+            v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime);
+          }
+        } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) {
+          v1 = [];
+          v2 = [];
+          var px = this.px;
+          var py = this.py;
+          if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
+            v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
+            v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate, 0);
+          } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate), 0);
+            v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate), 0);
+            v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0);
+          } else {
+            v1 = [px.pv, py.pv];
+            v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime);
+            v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime);
+          }
+        } else {
+          v2 = defaultVector;
+          v1 = v2;
+        }
+        this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
+      }
+      if (this.data.p && this.data.p.s) {
+        if (this.data.p.z) {
+          this.v.translate(this.px.v, this.py.v, -this.pz.v);
+        } else {
+          this.v.translate(this.px.v, this.py.v, 0);
+        }
+      } else {
+        this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+      }
+    }
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function precalculateMatrix() {
+    this.appliedTransformations = 0;
+    this.pre.reset();
+
+    if (!this.a.effectsSequence.length) {
+      this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      this.appliedTransformations = 1;
+    } else {
+      return;
+    }
+    if (!this.s.effectsSequence.length) {
+      this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      this.appliedTransformations = 2;
+    } else {
+      return;
+    }
+    if (this.sk) {
+      if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
+        this.pre.skewFromAxis(-this.sk.v, this.sa.v);
+        this.appliedTransformations = 3;
+      } else {
+        return;
+      }
+    }
+    if (this.r) {
+      if (!this.r.effectsSequence.length) {
+        this.pre.rotate(-this.r.v);
+        this.appliedTransformations = 4;
+      }
+    } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) {
+      this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+      this.appliedTransformations = 4;
+    }
+  }
+
+  function autoOrient() {
+    //
+    // var prevP = this.getValueAtTime();
+  }
+
+  function addDynamicProperty(prop) {
+    this._addDynamicProperty(prop);
+    this.elem.addDynamicProperty(prop);
+    this._isDirty = true;
+  }
+
+  function TransformProperty(elem, data, container) {
+    this.elem = elem;
+    this.frameId = -1;
+    this.propType = 'transform';
+    this.data = data;
+    this.v = new Matrix();
+    // Precalculated matrix with non animated properties
+    this.pre = new Matrix();
+    this.appliedTransformations = 0;
+    this.initDynamicPropertyContainer(container || elem);
+    if (data.p && data.p.s) {
+      this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
+      this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
+      if (data.p.z) {
+        this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
+      }
+    } else {
+      this.p = PropertyFactory.getProp(elem, data.p || { k: [0, 0, 0] }, 1, 0, this);
+    }
+    if (data.rx) {
+      this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
+      this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
+      this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
+      if (data.or.k[0].ti) {
+        var i;
+        var len = data.or.k.length;
+        for (i = 0; i < len; i += 1) {
+          data.or.k[i].to = null;
+          data.or.k[i].ti = null;
+        }
+      }
+      this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+      // sh Indicates it needs to be capped between -180 and 180
+      this.or.sh = true;
+    } else {
+      this.r = PropertyFactory.getProp(elem, data.r || { k: 0 }, 0, degToRads, this);
+    }
+    if (data.sk) {
+      this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
+      this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
+    }
+    this.a = PropertyFactory.getProp(elem, data.a || { k: [0, 0, 0] }, 1, 0, this);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: [100, 100, 100] }, 1, 0.01, this);
+    // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
+    if (data.o) {
+      this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
+    } else {
+      this.o = { _mdf: false, v: 1 };
+    }
+    this._isDirty = true;
+    if (!this.dynamicProperties.length) {
+      this.getValue(true);
+    }
+  }
+
+  TransformProperty.prototype = {
+    applyToMatrix: applyToMatrix,
+    getValue: processKeys,
+    precalculateMatrix: precalculateMatrix,
+    autoOrient: autoOrient,
+  };
+
+  extendPrototype([DynamicPropertyContainer], TransformProperty);
+  TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
+  TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
+
+  function getTransformProperty(elem, data, container) {
+    return new TransformProperty(elem, data, container);
+  }
+
+  return {
+    getTransformProperty: getTransformProperty,
+  };
+}());
+
+function RepeaterModifier() {}
+extendPrototype([ShapeModifier], RepeaterModifier);
+
+RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, null, this);
+  this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this);
+  this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
+  this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
+  this.data = data;
+  if (!this.dynamicProperties.length) {
+    this.getValue(true);
+  }
+  this._isAnimated = !!this.dynamicProperties.length;
+  this.pMatrix = new Matrix();
+  this.rMatrix = new Matrix();
+  this.sMatrix = new Matrix();
+  this.tMatrix = new Matrix();
+  this.matrix = new Matrix();
+};
+
+RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
+  var dir = inv ? -1 : 1;
+  var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
+  var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
+  pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
+  rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  rMatrix.rotate(-transform.r.v * dir * perc);
+  rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+  sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
+  sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+};
+
+RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
+  this.elem = elem;
+  this.arr = arr;
+  this.pos = pos;
+  this.elemsData = elemsData;
+  this._currentCopies = 0;
+  this._elements = [];
+  this._groups = [];
+  this.frameId = -1;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, arr[pos]);
+  while (pos > 0) {
+    pos -= 1;
+    // this._elements.unshift(arr.splice(pos,1)[0]);
+    this._elements.unshift(arr[pos]);
+  }
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+
+RepeaterModifier.prototype.resetElements = function (elements) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._processed = false;
+    if (elements[i].ty === 'gr') {
+      this.resetElements(elements[i].it);
+    }
+  }
+};
+
+RepeaterModifier.prototype.cloneElements = function (elements) {
+  var newElements = JSON.parse(JSON.stringify(elements));
+  this.resetElements(newElements);
+  return newElements;
+};
+
+RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._render = renderFlag;
+    if (elements[i].ty === 'gr') {
+      this.changeGroupRender(elements[i].it, renderFlag);
+    }
+  }
+};
+
+RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
+  var items;
+  var itemsTransform;
+  var i;
+  var dir;
+  var cont;
+  var hasReloaded = false;
+  if (this._mdf || _isFirstFrame) {
+    var copies = Math.ceil(this.c.v);
+    if (this._groups.length < copies) {
+      while (this._groups.length < copies) {
+        var group = {
+          it: this.cloneElements(this._elements),
+          ty: 'gr',
+        };
+        group.it.push({
+          a: { a: 0, ix: 1, k: [0, 0] }, nm: 'Transform', o: { a: 0, ix: 7, k: 100 }, p: { a: 0, ix: 2, k: [0, 0] }, r: { a: 1, ix: 6, k: [{ s: 0, e: 0, t: 0 }, { s: 0, e: 0, t: 1 }] }, s: { a: 0, ix: 3, k: [100, 100] }, sa: { a: 0, ix: 5, k: 0 }, sk: { a: 0, ix: 4, k: 0 }, ty: 'tr',
+        });
+
+        this.arr.splice(0, 0, group);
+        this._groups.splice(0, 0, group);
+        this._currentCopies += 1;
+      }
+      this.elem.reloadShapes();
+      hasReloaded = true;
+    }
+    cont = 0;
+    var renderFlag;
+    for (i = 0; i <= this._groups.length - 1; i += 1) {
+      renderFlag = cont < copies;
+      this._groups[i]._render = renderFlag;
+      this.changeGroupRender(this._groups[i].it, renderFlag);
+      if (!renderFlag) {
+        var elems = this.elemsData[i].it;
+        var transformData = elems[elems.length - 1];
+        if (transformData.transform.op.v !== 0) {
+          transformData.transform.op._mdf = true;
+          transformData.transform.op.v = 0;
+        } else {
+          transformData.transform.op._mdf = false;
+        }
+      }
+      cont += 1;
+    }
+
+    this._currentCopies = copies;
+    /// /
+
+    var offset = this.o.v;
+    var offsetModulo = offset % 1;
+    var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
+    var pProps = this.pMatrix.props;
+    var rProps = this.rMatrix.props;
+    var sProps = this.sMatrix.props;
+    this.pMatrix.reset();
+    this.rMatrix.reset();
+    this.sMatrix.reset();
+    this.tMatrix.reset();
+    this.matrix.reset();
+    var iteration = 0;
+
+    if (offset > 0) {
+      while (iteration < roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        iteration += 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
+        iteration += offsetModulo;
+      }
+    } else if (offset < 0) {
+      while (iteration > roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
+        iteration -= 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
+        iteration -= offsetModulo;
+      }
+    }
+    i = this.data.m === 1 ? 0 : this._currentCopies - 1;
+    dir = this.data.m === 1 ? 1 : -1;
+    cont = this._currentCopies;
+    var j;
+    var jLen;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      jLen = itemsTransform.length;
+      items[items.length - 1].transform.mProps._mdf = true;
+      items[items.length - 1].transform.op._mdf = true;
+      items[items.length - 1].transform.op.v = this._currentCopies === 1
+        ? this.so.v
+        : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
+
+      if (iteration !== 0) {
+        if ((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)) {
+          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        }
+        this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
+        this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
+        this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
+
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+        this.matrix.reset();
+      } else {
+        this.matrix.reset();
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+      }
+      iteration += 1;
+      cont -= 1;
+      i += dir;
+    }
+  } else {
+    cont = this._currentCopies;
+    i = 0;
+    dir = 1;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      items[items.length - 1].transform.mProps._mdf = false;
+      items[items.length - 1].transform.op._mdf = false;
+      cont -= 1;
+      i += dir;
+    }
+  }
+  return hasReloaded;
+};
+
+RepeaterModifier.prototype.addShape = function () {};
+
+function RoundCornersModifier() {}
+extendPrototype([ShapeModifier], RoundCornersModifier);
+RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this._isAnimated = !!this.rd.effectsSequence.length;
+};
+
+RoundCornersModifier.prototype.processPath = function (path, round) {
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var i;
+  var len = path._length;
+  var currentV;
+  var currentI;
+  var currentO;
+  var closerV;
+  var distance;
+  var newPosPerc;
+  var index = 0;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < len; i += 1) {
+    currentV = path.v[i];
+    currentO = path.o[i];
+    currentI = path.i[i];
+    if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
+      if ((i === 0 || i === len - 1) && !path.c) {
+        clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
+        /* clonedPath.v[index] = currentV;
+                clonedPath.o[index] = currentO;
+                clonedPath.i[index] = currentI; */
+        index += 1;
+      } else {
+        if (i === 0) {
+          closerV = path.v[len - 1];
+        } else {
+          closerV = path.v[i - 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = iX;
+        iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
+        vY = iY;
+        oX = vX - (vX - currentV[0]) * roundCorner;
+        oY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+
+        if (i === len - 1) {
+          closerV = path.v[0];
+        } else {
+          closerV = path.v[i + 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = oX;
+        oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc;
+        vY = oY;
+        iX = vX - (vX - currentV[0]) * roundCorner;
+        iY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+      }
+    } else {
+      clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index);
+      index += 1;
+    }
+  }
+  return clonedPath;
+};
+
+RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var rd = this.rd.v;
+
+  if (rd !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function floatEqual(a, b) {
+  return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
+}
+
+function floatZero(f) {
+  return Math.abs(f) <= 0.00001;
+}
+
+function lerp(p0, p1, amount) {
+  return p0 * (1 - amount) + p1 * amount;
+}
+
+function lerpPoint(p0, p1, amount) {
+  return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
+}
+
+function quadRoots(a, b, c) {
+  // no root
+  if (a === 0) return [];
+  var s = b * b - 4 * a * c;
+  // Complex roots
+  if (s < 0) return [];
+  var singleRoot = -b / (2 * a);
+  // 1 root
+  if (s === 0) return [singleRoot];
+  var delta = Math.sqrt(s) / (2 * a);
+  // 2 roots
+  return [singleRoot - delta, singleRoot + delta];
+}
+
+function polynomialCoefficients(p0, p1, p2, p3) {
+  return [
+    -p0 + 3 * p1 - 3 * p2 + p3,
+    3 * p0 - 6 * p1 + 3 * p2,
+    -3 * p0 + 3 * p1,
+    p0,
+  ];
+}
+
+function singlePoint(p) {
+  return new PolynomialBezier(p, p, p, p, false);
+}
+
+function PolynomialBezier(p0, p1, p2, p3, linearize) {
+  if (linearize && pointEqual(p0, p1)) {
+    p1 = lerpPoint(p0, p3, 1 / 3);
+  }
+  if (linearize && pointEqual(p2, p3)) {
+    p2 = lerpPoint(p0, p3, 2 / 3);
+  }
+  var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
+  var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
+  this.a = [coeffx[0], coeffy[0]];
+  this.b = [coeffx[1], coeffy[1]];
+  this.c = [coeffx[2], coeffy[2]];
+  this.d = [coeffx[3], coeffy[3]];
+  this.points = [p0, p1, p2, p3];
+}
+PolynomialBezier.prototype.point = function (t) {
+  return [
+    (((this.a[0] * t) + this.b[0]) * t + this.c[0]) * t + this.d[0],
+    (((this.a[1] * t) + this.b[1]) * t + this.c[1]) * t + this.d[1],
+  ];
+};
+PolynomialBezier.prototype.derivative = function (t) {
+  return [
+    (3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0],
+    (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1],
+  ];
+};
+PolynomialBezier.prototype.tangentAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[1], p[0]);
+};
+PolynomialBezier.prototype.normalAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[0], p[1]);
+};
+
+PolynomialBezier.prototype.inflectionPoints = function () {
+  var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
+  if (floatZero(denom)) return [];
+  var tcusp = (-0.5 * (this.a[1] * this.c[0] - this.a[0] * this.c[1])) / denom;
+  var square = tcusp * tcusp - ((1 / 3) * (this.b[1] * this.c[0] - this.b[0] * this.c[1])) / denom;
+  if (square < 0) return [];
+  var root = Math.sqrt(square);
+  if (floatZero(root)) {
+    if (root > 0 && root < 1) return [tcusp];
+    return [];
+  }
+  return [tcusp - root, tcusp + root].filter(function (r) { return r > 0 && r < 1; });
+};
+PolynomialBezier.prototype.split = function (t) {
+  if (t <= 0) return [singlePoint(this.points[0]), this];
+  if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
+  var p10 = lerpPoint(this.points[0], this.points[1], t);
+  var p11 = lerpPoint(this.points[1], this.points[2], t);
+  var p12 = lerpPoint(this.points[2], this.points[3], t);
+  var p20 = lerpPoint(p10, p11, t);
+  var p21 = lerpPoint(p11, p12, t);
+  var p3 = lerpPoint(p20, p21, t);
+  return [
+    new PolynomialBezier(this.points[0], p10, p20, p3, true),
+    new PolynomialBezier(p3, p21, p12, this.points[3], true),
+  ];
+};
+function extrema(bez, comp) {
+  var min = bez.points[0][comp];
+  var max = bez.points[bez.points.length - 1][comp];
+  if (min > max) {
+    var e = max;
+    max = min;
+    min = e;
+  }
+  // Derivative roots to find min/max
+  var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
+  for (var i = 0; i < f.length; i += 1) {
+    if (f[i] > 0 && f[i] < 1) {
+      var val = bez.point(f[i])[comp];
+      if (val < min) min = val;
+      else if (val > max) max = val;
+    }
+  }
+  return {
+    min: min,
+    max: max,
+  };
+}
+PolynomialBezier.prototype.bounds = function () {
+  return {
+    x: extrema(this, 0),
+    y: extrema(this, 1),
+  };
+};
+PolynomialBezier.prototype.boundingBox = function () {
+  var bounds = this.bounds();
+  return {
+    left: bounds.x.min,
+    right: bounds.x.max,
+    top: bounds.y.min,
+    bottom: bounds.y.max,
+    width: bounds.x.max - bounds.x.min,
+    height: bounds.y.max - bounds.y.min,
+    cx: (bounds.x.max + bounds.x.min) / 2,
+    cy: (bounds.y.max + bounds.y.min) / 2,
+  };
+};
+
+function intersectData(bez, t1, t2) {
+  var box = bez.boundingBox();
+  return {
+    cx: box.cx,
+    cy: box.cy,
+    width: box.width,
+    height: box.height,
+    bez: bez,
+    t: (t1 + t2) / 2,
+    t1: t1,
+    t2: t2,
+  };
+}
+function splitData(data) {
+  var split = data.bez.split(0.5);
+  return [
+    intersectData(split[0], data.t1, data.t),
+    intersectData(split[1], data.t, data.t2),
+  ];
+}
+
+function boxIntersect(b1, b2) {
+  return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width
+    && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
+}
+
+function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
+  if (!boxIntersect(d1, d2)) return;
+  if (depth >= maxRecursion || (d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance)) {
+    intersections.push([d1.t, d2.t]);
+    return;
+  }
+  var d1s = splitData(d1);
+  var d2s = splitData(d2);
+  intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[0], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+}
+
+PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
+  if (tolerance === undefined) tolerance = 2;
+  if (maxRecursion === undefined) maxRecursion = 7;
+  var intersections = [];
+  intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
+  return intersections;
+};
+
+PolynomialBezier.shapeSegment = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
+};
+
+PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
+};
+
+function crossProduct(a, b) {
+  return [
+    a[1] * b[2] - a[2] * b[1],
+    a[2] * b[0] - a[0] * b[2],
+    a[0] * b[1] - a[1] * b[0],
+  ];
+}
+
+function lineIntersection(start1, end1, start2, end2) {
+  var v1 = [start1[0], start1[1], 1];
+  var v2 = [end1[0], end1[1], 1];
+  var v3 = [start2[0], start2[1], 1];
+  var v4 = [end2[0], end2[1], 1];
+
+  var r = crossProduct(
+    crossProduct(v1, v2),
+    crossProduct(v3, v4)
+  );
+
+  if (floatZero(r[2])) return null;
+
+  return [r[0] / r[2], r[1] / r[2]];
+}
+
+function polarOffset(p, angle, length) {
+  return [
+    p[0] + Math.cos(angle) * length,
+    p[1] - Math.sin(angle) * length,
+  ];
+}
+
+function pointDistance(p1, p2) {
+  return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
+}
+
+function pointEqual(p1, p2) {
+  return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
+}
+
+function ZigZagModifier() {}
+extendPrototype([ShapeModifier], ZigZagModifier);
+ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
+  this.frequency = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
+  this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
+};
+
+function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
+  var angO = angle - Math.PI / 2;
+  var angI = angle + Math.PI / 2;
+  var px = point[0] + Math.cos(angle) * direction * amplitude;
+  var py = point[1] - Math.sin(angle) * direction * amplitude;
+
+  outputBezier.setTripleAt(
+    px,
+    py,
+    px + Math.cos(angO) * outAmplitude,
+    py - Math.sin(angO) * outAmplitude,
+    px + Math.cos(angI) * inAmplitude,
+    py - Math.sin(angI) * inAmplitude,
+    outputBezier.length()
+  );
+}
+
+function getPerpendicularVector(pt1, pt2) {
+  var vector = [
+    pt2[0] - pt1[0],
+    pt2[1] - pt1[1],
+  ];
+  var rot = -Math.PI * 0.5;
+  var rotatedVector = [
+    Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1],
+    Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1],
+  ];
+  return rotatedVector;
+}
+
+function getProjectingAngle(path, cur) {
+  var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
+  var nextIndex = (cur + 1) % path.length();
+  var prevPoint = path.v[prevIndex];
+  var nextPoint = path.v[nextIndex];
+  var pVector = getPerpendicularVector(prevPoint, nextPoint);
+  return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
+}
+
+function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
+  var angle = getProjectingAngle(path, cur);
+  var point = path.v[cur % path._length];
+  var prevPoint = path.v[cur === 0 ? path._length - 1 : cur - 1];
+  var nextPoint = path.v[(cur + 1) % path._length];
+  var prevDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - prevPoint[0], 2) + Math.pow(point[1] - prevPoint[1], 2))
+    : 0;
+  var nextDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2))
+    : 0;
+
+  setPoint(
+    outputBezier,
+    path.v[cur % path._length],
+    angle,
+    direction,
+    amplitude,
+    nextDist / ((frequency + 1) * 2),
+    prevDist / ((frequency + 1) * 2),
+    pointType
+  );
+}
+
+function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
+  for (var i = 0; i < frequency; i += 1) {
+    var t = (i + 1) / (frequency + 1);
+
+    var dist = pointType === 2
+      ? Math.sqrt(Math.pow(segment.points[3][0] - segment.points[0][0], 2) + Math.pow(segment.points[3][1] - segment.points[0][1], 2))
+      : 0;
+
+    var angle = segment.normalAngle(t);
+    var point = segment.point(t);
+    setPoint(
+      outputBezier,
+      point,
+      angle,
+      direction,
+      amplitude,
+      dist / ((frequency + 1) * 2),
+      dist / ((frequency + 1) * 2),
+      pointType
+    );
+
+    direction = -direction;
+  }
+
+  return direction;
+}
+
+ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
+  var count = path._length;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+
+  if (!path.c) {
+    count -= 1;
+  }
+
+  if (count === 0) return clonedPath;
+
+  var direction = -1;
+  var segment = PolynomialBezier.shapeSegment(path, 0);
+  zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
+
+  for (var i = 0; i < count; i += 1) {
+    direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
+
+    if (i === count - 1 && !path.c) {
+      segment = null;
+    } else {
+      segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
+    }
+
+    zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
+  }
+
+  return clonedPath;
+};
+
+ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amplitude = this.amplitude.v;
+  var frequency = Math.max(0, Math.round(this.frequency.v));
+  var pointType = this.pointsType.v;
+
+  if (amplitude !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function linearOffset(p1, p2, amount) {
+  var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
+  return [
+    polarOffset(p1, angle, amount),
+    polarOffset(p2, angle, amount),
+  ];
+}
+
+function offsetSegment(segment, amount) {
+  var p0; var p1a; var p1b; var p2b; var p2a; var
+    p3;
+  var e;
+  e = linearOffset(segment.points[0], segment.points[1], amount);
+  p0 = e[0];
+  p1a = e[1];
+  e = linearOffset(segment.points[1], segment.points[2], amount);
+  p1b = e[0];
+  p2b = e[1];
+  e = linearOffset(segment.points[2], segment.points[3], amount);
+  p2a = e[0];
+  p3 = e[1];
+  var p1 = lineIntersection(p0, p1a, p1b, p2b);
+  if (p1 === null) p1 = p1a;
+  var p2 = lineIntersection(p2a, p3, p1b, p2b);
+  if (p2 === null) p2 = p2a;
+
+  return new PolynomialBezier(p0, p1, p2, p3);
+}
+
+function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
+  var p0 = seg1.points[3];
+  var p1 = seg2.points[0];
+
+  // Bevel
+  if (lineJoin === 3) return p0;
+
+  // Connected, they don't need a joint
+  if (pointEqual(p0, p1)) return p0;
+
+  // Round
+  if (lineJoin === 2) {
+    var angleOut = -seg1.tangentAngle(1);
+    var angleIn = -seg2.tangentAngle(0) + Math.PI;
+    var center = lineIntersection(
+      p0,
+      polarOffset(p0, angleOut + Math.PI / 2, 100),
+      p1,
+      polarOffset(p1, angleOut + Math.PI / 2, 100)
+    );
+    var radius = center ? pointDistance(center, p0) : pointDistance(p0, p1) / 2;
+
+    var tan = polarOffset(p0, angleOut, 2 * radius * roundCorner);
+    outputBezier.setXYAt(tan[0], tan[1], 'o', outputBezier.length() - 1);
+
+    tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
+    outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
+
+    return p1;
+  }
+
+  // Miter
+  var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
+  var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
+  var intersection = lineIntersection(t0, p0, p1, t1);
+  if (intersection && pointDistance(intersection, p0) < miterLimit) {
+    outputBezier.setTripleAt(
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      outputBezier.length()
+    );
+    return intersection;
+  }
+
+  return p0;
+}
+
+function getIntersection(a, b) {
+  const intersect = a.intersections(b);
+
+  if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
+
+  if (intersect.length) return intersect[0];
+
+  return null;
+}
+
+function pruneSegmentIntersection(a, b) {
+  var outa = a.slice();
+  var outb = b.slice();
+  var intersect = getIntersection(a[a.length - 1], b[0]);
+  if (intersect) {
+    outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
+    outb[0] = b[0].split(intersect[1])[1];
+  }
+  if (a.length > 1 && b.length > 1) {
+    intersect = getIntersection(a[0], b[b.length - 1]);
+    if (intersect) {
+      return [
+        [a[0].split(intersect[0])[0]],
+        [b[b.length - 1].split(intersect[1])[1]],
+      ];
+    }
+  }
+  return [outa, outb];
+}
+
+function pruneIntersections(segments) {
+  var e;
+  for (var i = 1; i < segments.length; i += 1) {
+    e = pruneSegmentIntersection(segments[i - 1], segments[i]);
+    segments[i - 1] = e[0];
+    segments[i] = e[1];
+  }
+
+  if (segments.length > 1) {
+    e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
+    segments[segments.length - 1] = e[0];
+    segments[0] = e[1];
+  }
+
+  return segments;
+}
+
+function offsetSegmentSplit(segment, amount) {
+  /*
+    We split each bezier segment into smaller pieces based
+    on inflection points, this ensures the control point
+    polygon is convex.
+
+    (A cubic bezier can have none, one, or two inflection points)
+  */
+  var flex = segment.inflectionPoints();
+  var left;
+  var right;
+  var split;
+  var mid;
+
+  if (flex.length === 0) {
+    return [offsetSegment(segment, amount)];
+  }
+
+  if (flex.length === 1 || floatEqual(flex[1], 1)) {
+    split = segment.split(flex[0]);
+    left = split[0];
+    right = split[1];
+
+    return [
+      offsetSegment(left, amount),
+      offsetSegment(right, amount),
+    ];
+  }
+
+  split = segment.split(flex[0]);
+  left = split[0];
+  var t = (flex[1] - flex[0]) / (1 - flex[0]);
+  split = split[1].split(t);
+  mid = split[0];
+  right = split[1];
+
+  return [
+    offsetSegment(left, amount),
+    offsetSegment(mid, amount),
+    offsetSegment(right, amount),
+  ];
+}
+
+function OffsetPathModifier() {}
+
+extendPrototype([ShapeModifier], OffsetPathModifier);
+OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this.miterLimit = PropertyFactory.getProp(elem, data.ml, 0, null, this);
+  this.lineJoin = data.lj;
+  this._isAnimated = this.amount.effectsSequence.length !== 0;
+};
+
+OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
+  var outputBezier = shapePool.newElement();
+  outputBezier.c = inputBezier.c;
+  var count = inputBezier.length();
+  if (!inputBezier.c) {
+    count -= 1;
+  }
+  var i; var j; var segment;
+  var multiSegments = [];
+
+  for (i = 0; i < count; i += 1) {
+    segment = PolynomialBezier.shapeSegment(inputBezier, i);
+    multiSegments.push(offsetSegmentSplit(segment, amount));
+  }
+
+  if (!inputBezier.c) {
+    for (i = count - 1; i >= 0; i -= 1) {
+      segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
+      multiSegments.push(offsetSegmentSplit(segment, amount));
+    }
+  }
+
+  multiSegments = pruneIntersections(multiSegments);
+
+  // Add bezier segments to the output and apply line joints
+  var lastPoint = null;
+  var lastSeg = null;
+
+  for (i = 0; i < multiSegments.length; i += 1) {
+    var multiSegment = multiSegments[i];
+
+    if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
+
+    lastSeg = multiSegment[multiSegment.length - 1];
+
+    for (j = 0; j < multiSegment.length; j += 1) {
+      segment = multiSegment[j];
+
+      if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
+        outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
+      } else {
+        outputBezier.setTripleAt(
+          segment.points[0][0],
+          segment.points[0][1],
+          segment.points[1][0],
+          segment.points[1][1],
+          segment.points[0][0],
+          segment.points[0][1],
+          outputBezier.length()
+        );
+      }
+
+      outputBezier.setTripleAt(
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[2][0],
+        segment.points[2][1],
+        outputBezier.length()
+      );
+
+      lastPoint = segment.points[3];
+    }
+  }
+
+  if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
+
+  return outputBezier;
+};
+
+OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+  var miterLimit = this.miterLimit.v;
+  var lineJoin = this.lineJoin;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function getFontProperties(fontData) {
+  var styles = fontData.fStyle ? fontData.fStyle.split(' ') : [];
+
+  var fWeight = 'normal'; var
+    fStyle = 'normal';
+  var len = styles.length;
+  var styleName;
+  for (var i = 0; i < len; i += 1) {
+    styleName = styles[i].toLowerCase();
+    switch (styleName) {
+      case 'italic':
+        fStyle = 'italic';
+        break;
+      case 'bold':
+        fWeight = '700';
+        break;
+      case 'black':
+        fWeight = '900';
+        break;
+      case 'medium':
+        fWeight = '500';
+        break;
+      case 'regular':
+      case 'normal':
+        fWeight = '400';
+        break;
+      case 'light':
+      case 'thin':
+        fWeight = '200';
+        break;
+      default:
+        break;
+    }
+  }
+
+  return {
+    style: fStyle,
+    weight: fontData.fWeight || fWeight,
+  };
+}
+
+const FontManager = (function () {
+  var maxWaitingTime = 5000;
+  var emptyChar = {
+    w: 0,
+    size: 0,
+    shapes: [],
+    data: {
+      shapes: [],
+    },
+  };
+  var combinedCharacters = [];
+  // Hindi characters
+  combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366,
+    2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379,
+    2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
+
+  var BLACK_FLAG_CODE_POINT = 127988;
+  var CANCEL_TAG_CODE_POINT = 917631;
+  var A_TAG_CODE_POINT = 917601;
+  var Z_TAG_CODE_POINT = 917626;
+  var VARIATION_SELECTOR_16_CODE_POINT = 65039;
+  var ZERO_WIDTH_JOINER_CODE_POINT = 8205;
+  var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
+  var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
+
+  var surrogateModifiers = [
+    'd83cdffb',
+    'd83cdffc',
+    'd83cdffd',
+    'd83cdffe',
+    'd83cdfff',
+  ];
+
+  function trimFontOptions(font) {
+    var familyArray = font.split(',');
+    var i;
+    var len = familyArray.length;
+    var enabledFamilies = [];
+    for (i = 0; i < len; i += 1) {
+      if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
+        enabledFamilies.push(familyArray[i]);
+      }
+    }
+    return enabledFamilies.join(',');
+  }
+
+  function setUpNode(font, family) {
+    var parentNode = createTag('span');
+    // Node is invisible to screen readers.
+    parentNode.setAttribute('aria-hidden', true);
+    parentNode.style.fontFamily = family;
+    var node = createTag('span');
+    // Characters that vary significantly among different fonts
+    node.innerText = 'giItT1WQy@!-/#';
+    // Visible - so we can measure it - but not on the screen
+    parentNode.style.position = 'absolute';
+    parentNode.style.left = '-10000px';
+    parentNode.style.top = '-10000px';
+    // Large font size makes even subtle changes obvious
+    parentNode.style.fontSize = '300px';
+    // Reset any font properties
+    parentNode.style.fontVariant = 'normal';
+    parentNode.style.fontStyle = 'normal';
+    parentNode.style.fontWeight = 'normal';
+    parentNode.style.letterSpacing = '0';
+    parentNode.appendChild(node);
+    document.body.appendChild(parentNode);
+
+    // Remember width with no applied web font
+    var width = node.offsetWidth;
+    node.style.fontFamily = trimFontOptions(font) + ', ' + family;
+    return { node: node, w: width, parent: parentNode };
+  }
+
+  function checkLoadedFonts() {
+    var i;
+    var len = this.fonts.length;
+    var node;
+    var w;
+    var loadedCount = len;
+    for (i = 0; i < len; i += 1) {
+      if (this.fonts[i].loaded) {
+        loadedCount -= 1;
+      } else if (this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0) {
+        this.fonts[i].loaded = true;
+      } else {
+        node = this.fonts[i].monoCase.node;
+        w = this.fonts[i].monoCase.w;
+        if (node.offsetWidth !== w) {
+          loadedCount -= 1;
+          this.fonts[i].loaded = true;
+        } else {
+          node = this.fonts[i].sansCase.node;
+          w = this.fonts[i].sansCase.w;
+          if (node.offsetWidth !== w) {
+            loadedCount -= 1;
+            this.fonts[i].loaded = true;
+          }
+        }
+        if (this.fonts[i].loaded) {
+          this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
+          this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
+        }
+      }
+    }
+
+    if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
+      setTimeout(this.checkLoadedFontsBinded, 20);
+    } else {
+      setTimeout(this.setIsLoadedBinded, 10);
+    }
+  }
+
+  function createHelper(fontData, def) {
+    var engine = (document.body && def) ? 'svg' : 'canvas';
+    var helper;
+    var fontProps = getFontProperties(fontData);
+    if (engine === 'svg') {
+      var tHelper = createNS('text');
+      tHelper.style.fontSize = '100px';
+      // tHelper.style.fontFamily = fontData.fFamily;
+      tHelper.setAttribute('font-family', fontData.fFamily);
+      tHelper.setAttribute('font-style', fontProps.style);
+      tHelper.setAttribute('font-weight', fontProps.weight);
+      tHelper.textContent = '1';
+      if (fontData.fClass) {
+        tHelper.style.fontFamily = 'inherit';
+        tHelper.setAttribute('class', fontData.fClass);
+      } else {
+        tHelper.style.fontFamily = fontData.fFamily;
+      }
+      def.appendChild(tHelper);
+      helper = tHelper;
+    } else {
+      var tCanvasHelper = new OffscreenCanvas(500, 500).getContext('2d');
+      tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
+      helper = tCanvasHelper;
+    }
+    function measure(text) {
+      if (engine === 'svg') {
+        helper.textContent = text;
+        return helper.getComputedTextLength();
+      }
+      return helper.measureText(text).width;
+    }
+    return {
+      measureText: measure,
+    };
+  }
+
+  function addFonts(fontData, defs) {
+    if (!fontData) {
+      this.isLoaded = true;
+      return;
+    }
+    if (this.chars) {
+      this.isLoaded = true;
+      this.fonts = fontData.list;
+      return;
+    }
+    if (!document.body) {
+      this.isLoaded = true;
+      fontData.list.forEach((data) => {
+        data.helper = createHelper(data);
+        data.cache = {};
+      });
+      this.fonts = fontData.list;
+      return;
+    }
+
+    var fontArr = fontData.list;
+    var i;
+    var len = fontArr.length;
+    var _pendingFonts = len;
+    for (i = 0; i < len; i += 1) {
+      var shouldLoadFont = true;
+      var loadedSelector;
+      var j;
+      fontArr[i].loaded = false;
+      fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
+      fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
+      if (!fontArr[i].fPath) {
+        fontArr[i].loaded = true;
+        _pendingFonts -= 1;
+      } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
+        loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
+
+        if (loadedSelector.length > 0) {
+          shouldLoadFont = false;
+        }
+
+        if (shouldLoadFont) {
+          var s = createTag('style');
+          s.setAttribute('f-forigin', fontArr[i].fOrigin);
+          s.setAttribute('f-origin', fontArr[i].origin);
+          s.setAttribute('f-family', fontArr[i].fFamily);
+          s.type = 'text/css';
+          s.innerText = '@font-face {font-family: ' + fontArr[i].fFamily + "; font-style: normal; src: url('" + fontArr[i].fPath + "');}";
+          defs.appendChild(s);
+        }
+      } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
+        loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var l = createTag('link');
+          l.setAttribute('f-forigin', fontArr[i].fOrigin);
+          l.setAttribute('f-origin', fontArr[i].origin);
+          l.type = 'text/css';
+          l.rel = 'stylesheet';
+          l.href = fontArr[i].fPath;
+          document.body.appendChild(l);
+        }
+      } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
+        loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (fontArr[i].fPath === loadedSelector[j].src) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var sc = createTag('link');
+          sc.setAttribute('f-forigin', fontArr[i].fOrigin);
+          sc.setAttribute('f-origin', fontArr[i].origin);
+          sc.setAttribute('rel', 'stylesheet');
+          sc.setAttribute('href', fontArr[i].fPath);
+          defs.appendChild(sc);
+        }
+      }
+      fontArr[i].helper = createHelper(fontArr[i], defs);
+      fontArr[i].cache = {};
+      this.fonts.push(fontArr[i]);
+    }
+    if (_pendingFonts === 0) {
+      this.isLoaded = true;
+    } else {
+      // On some cases even if the font is loaded, it won't load correctly when measuring text on canvas.
+      // Adding this timeout seems to fix it
+      setTimeout(this.checkLoadedFonts.bind(this), 100);
+    }
+  }
+
+  function addChars(chars) {
+    if (!chars) {
+      return;
+    }
+    if (!this.chars) {
+      this.chars = [];
+    }
+    var i;
+    var len = chars.length;
+    var j;
+    var jLen = this.chars.length;
+    var found;
+    for (i = 0; i < len; i += 1) {
+      j = 0;
+      found = false;
+      while (j < jLen) {
+        if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
+          found = true;
+        }
+        j += 1;
+      }
+      if (!found) {
+        this.chars.push(chars[i]);
+        jLen += 1;
+      }
+    }
+  }
+
+  function getCharData(char, style, font) {
+    var i = 0;
+    var len = this.chars.length;
+    while (i < len) {
+      if (this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font) {
+        return this.chars[i];
+      }
+      i += 1;
+    }
+    if (((typeof char === 'string' && char.charCodeAt(0) !== 13) || !char)
+            && console
+            && console.warn // eslint-disable-line no-console
+            && !this._warned
+    ) {
+      this._warned = true;
+      console.warn('Missing character from exported characters list: ', char, style, font); // eslint-disable-line no-console
+    }
+    return emptyChar;
+  }
+
+  function measureText(char, fontName, size) {
+    var fontData = this.getFontByName(fontName);
+    // Using the char instead of char.charCodeAt(0)
+    // to avoid collisions between equal chars
+    var index = char;
+    if (!fontData.cache[index]) {
+      var tHelper = fontData.helper;
+      if (char === ' ') {
+        var doubleSize = tHelper.measureText('|' + char + '|');
+        var singleSize = tHelper.measureText('||');
+        fontData.cache[index] = (doubleSize - singleSize) / 100;
+      } else {
+        fontData.cache[index] = tHelper.measureText(char) / 100;
+      }
+    }
+    return fontData.cache[index] * size;
+  }
+
+  function getFontByName(name) {
+    var i = 0;
+    var len = this.fonts.length;
+    while (i < len) {
+      if (this.fonts[i].fName === name) {
+        return this.fonts[i];
+      }
+      i += 1;
+    }
+    return this.fonts[0];
+  }
+
+  function getCodePoint(string) {
+    var codePoint = 0;
+    var first = string.charCodeAt(0);
+    if (first >= 0xD800 && first <= 0xDBFF) {
+      var second = string.charCodeAt(1);
+      if (second >= 0xDC00 && second <= 0xDFFF) {
+        codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+      }
+    }
+    return codePoint;
+  }
+
+  // Skin tone modifiers
+  function isModifier(firstCharCode, secondCharCode) {
+    var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
+    return surrogateModifiers.indexOf(sum) !== -1;
+  }
+
+  function isZeroWidthJoiner(charCode) {
+    return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
+  }
+
+  // This codepoint may change the appearance of the preceding character.
+  // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
+  // as a colorful image as compared to a monochrome text variant.
+  function isVariationSelector(charCode) {
+    return charCode === VARIATION_SELECTOR_16_CODE_POINT;
+  }
+
+  // The regional indicator symbols are a set of 26 alphabetic Unicode
+  /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
+  // two-letter country codes in a way that allows optional special treatment.
+  function isRegionalCode(string) {
+    var codePoint = getCodePoint(string);
+    if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
+      return true;
+    }
+    return false;
+  }
+
+  // Some Emoji implementations represent combinations of
+  // two “regional indicator” letters as a single flag symbol.
+  function isFlagEmoji(string) {
+    return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
+  }
+
+  function isCombinedCharacter(char) {
+    return combinedCharacters.indexOf(char) !== -1;
+  }
+
+  // Regional flags start with a BLACK_FLAG_CODE_POINT
+  // folowed by 5 chars in the TAG range
+  // and end with a CANCEL_TAG_CODE_POINT
+  function isRegionalFlag(text, index) {
+    var codePoint = getCodePoint(text.substr(index, 2));
+    if (codePoint !== BLACK_FLAG_CODE_POINT) {
+      return false;
+    }
+    var count = 0;
+    index += 2;
+    while (count < 5) {
+      codePoint = getCodePoint(text.substr(index, 2));
+      if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
+        return false;
+      }
+      count += 1;
+      index += 2;
+    }
+    return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
+  }
+
+  function setIsLoaded() {
+    this.isLoaded = true;
+  }
+
+  var Font = function () {
+    this.fonts = [];
+    this.chars = null;
+    this.typekitLoaded = 0;
+    this.isLoaded = false;
+    this._warned = false;
+    this.initTime = Date.now();
+    this.setIsLoadedBinded = this.setIsLoaded.bind(this);
+    this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
+  };
+  Font.isModifier = isModifier;
+  Font.isZeroWidthJoiner = isZeroWidthJoiner;
+  Font.isFlagEmoji = isFlagEmoji;
+  Font.isRegionalCode = isRegionalCode;
+  Font.isCombinedCharacter = isCombinedCharacter;
+  Font.isRegionalFlag = isRegionalFlag;
+  Font.isVariationSelector = isVariationSelector;
+  Font.BLACK_FLAG_CODE_POINT = BLACK_FLAG_CODE_POINT;
+
+  var fontPrototype = {
+    addChars: addChars,
+    addFonts: addFonts,
+    getCharData: getCharData,
+    getFontByName: getFontByName,
+    measureText: measureText,
+    checkLoadedFonts: checkLoadedFonts,
+    setIsLoaded: setIsLoaded,
+  };
+
+  Font.prototype = fontPrototype;
+
+  return Font;
+}());
+
+function SlotManager(animationData) {
+  this.animationData = animationData;
+}
+SlotManager.prototype.getProp = function (data) {
+  if (this.animationData.slots
+    && this.animationData.slots[data.sid]
+  ) {
+    return Object.assign(data, this.animationData.slots[data.sid].p);
+  }
+  return data;
+};
+
+function slotFactory(animationData) {
+  return new SlotManager(animationData);
+}
+
+function RenderableElement() {
+
+}
+
+RenderableElement.prototype = {
+  initRenderable: function () {
+    // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
+    this.isInRange = false;
+    // layer's display state
+    this.hidden = false;
+    // If layer's transparency equals 0, it can be hidden
+    this.isTransparent = false;
+    // list of animated components
+    this.renderableComponents = [];
+  },
+  addRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) === -1) {
+      this.renderableComponents.push(component);
+    }
+  },
+  removeRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) !== -1) {
+      this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1);
+    }
+  },
+  prepareRenderableFrame: function (num) {
+    this.checkLayerLimits(num);
+  },
+  checkTransparency: function () {
+    if (this.finalTransform.mProp.o.v <= 0) {
+      if (!this.isTransparent && this.globalData.renderConfig.hideOnTransparent) {
+        this.isTransparent = true;
+        this.hide();
+      }
+    } else if (this.isTransparent) {
+      this.isTransparent = false;
+      this.show();
+    }
+  },
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     *
+     */
+  checkLayerLimits: function (num) {
+    if (this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) {
+      if (this.isInRange !== true) {
+        this.globalData._mdf = true;
+        this._mdf = true;
+        this.isInRange = true;
+        this.show();
+      }
+    } else if (this.isInRange !== false) {
+      this.globalData._mdf = true;
+      this.isInRange = false;
+      this.hide();
+    }
+  },
+  renderRenderable: function () {
+    var i;
+    var len = this.renderableComponents.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderableComponents[i].renderFrame(this._isFirstFrame);
+    }
+    /* this.maskManager.renderFrame(this.finalTransform.mat);
+        this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
+  },
+  sourceRectAtTime: function () {
+    return {
+      top: 0,
+      left: 0,
+      width: 100,
+      height: 100,
+    };
+  },
+  getLayerSize: function () {
+    if (this.data.ty === 5) {
+      return { w: this.data.textData.width, h: this.data.textData.height };
+    }
+    return { w: this.data.width, h: this.data.height };
+  },
+};
+
+const getBlendMode = (function () {
+  var blendModeEnums = {
+    0: 'source-over',
+    1: 'multiply',
+    2: 'screen',
+    3: 'overlay',
+    4: 'darken',
+    5: 'lighten',
+    6: 'color-dodge',
+    7: 'color-burn',
+    8: 'hard-light',
+    9: 'soft-light',
+    10: 'difference',
+    11: 'exclusion',
+    12: 'hue',
+    13: 'saturation',
+    14: 'color',
+    15: 'luminosity',
+  };
+
+  return function (mode) {
+    return blendModeEnums[mode] || '';
+  };
+}());
+
+function SliderEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function AngleEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function ColorEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function PointEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function LayerIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function MaskIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function CheckboxEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function NoValueEffect() {
+  this.p = {};
+}
+
+function EffectsManager(data, element) {
+  var effects = data.ef || [];
+  this.effectElements = [];
+  var i;
+  var len = effects.length;
+  var effectItem;
+  for (i = 0; i < len; i += 1) {
+    effectItem = new GroupEffect(effects[i], element);
+    this.effectElements.push(effectItem);
+  }
+}
+
+function GroupEffect(data, element) {
+  this.init(data, element);
+}
+
+extendPrototype([DynamicPropertyContainer], GroupEffect);
+
+GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
+
+GroupEffect.prototype.init = function (data, element) {
+  this.data = data;
+  this.effectElements = [];
+  this.initDynamicPropertyContainer(element);
+  var i;
+  var len = this.data.ef.length;
+  var eff;
+  var effects = this.data.ef;
+  for (i = 0; i < len; i += 1) {
+    eff = null;
+    switch (effects[i].ty) {
+      case 0:
+        eff = new SliderEffect(effects[i], element, this);
+        break;
+      case 1:
+        eff = new AngleEffect(effects[i], element, this);
+        break;
+      case 2:
+        eff = new ColorEffect(effects[i], element, this);
+        break;
+      case 3:
+        eff = new PointEffect(effects[i], element, this);
+        break;
+      case 4:
+      case 7:
+        eff = new CheckboxEffect(effects[i], element, this);
+        break;
+      case 10:
+        eff = new LayerIndexEffect(effects[i], element, this);
+        break;
+      case 11:
+        eff = new MaskIndexEffect(effects[i], element, this);
+        break;
+      case 5:
+        eff = new EffectsManager(effects[i], element, this);
+        break;
+        // case 6:
+      default:
+        eff = new NoValueEffect(effects[i], element, this);
+        break;
+    }
+    if (eff) {
+      this.effectElements.push(eff);
+    }
+  }
+};
+
+function BaseElement() {
+}
+
+BaseElement.prototype = {
+  checkMasks: function () {
+    if (!this.data.hasMask) {
+      return false;
+    }
+    var i = 0;
+    var len = this.data.masksProperties.length;
+    while (i < len) {
+      if ((this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false)) {
+        return true;
+      }
+      i += 1;
+    }
+    return false;
+  },
+  initExpressions: function () {
+    const expressionsInterfaces = getExpressionInterfaces();
+    if (!expressionsInterfaces) {
+      return;
+    }
+    const LayerExpressionInterface = expressionsInterfaces('layer');
+    const EffectsExpressionInterface = expressionsInterfaces('effects');
+    const ShapeExpressionInterface = expressionsInterfaces('shape');
+    const TextExpressionInterface = expressionsInterfaces('text');
+    const CompExpressionInterface = expressionsInterfaces('comp');
+    this.layerInterface = LayerExpressionInterface(this);
+    if (this.data.hasMask && this.maskManager) {
+      this.layerInterface.registerMaskInterface(this.maskManager);
+    }
+    var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
+    this.layerInterface.registerEffectsInterface(effectsInterface);
+
+    if (this.data.ty === 0 || this.data.xt) {
+      this.compInterface = CompExpressionInterface(this);
+    } else if (this.data.ty === 4) {
+      this.layerInterface.shapeInterface = ShapeExpressionInterface(this.shapesData, this.itemsData, this.layerInterface);
+      this.layerInterface.content = this.layerInterface.shapeInterface;
+    } else if (this.data.ty === 5) {
+      this.layerInterface.textInterface = TextExpressionInterface(this);
+      this.layerInterface.text = this.layerInterface.textInterface;
+    }
+  },
+  setBlendMode: function () {
+    var blendModeValue = getBlendMode(this.data.bm);
+    var elem = this.baseElement || this.layerElement;
+
+    elem.style['mix-blend-mode'] = blendModeValue;
+  },
+  initBaseData: function (data, globalData, comp) {
+    this.globalData = globalData;
+    this.comp = comp;
+    this.data = data;
+    this.layerId = createElementID();
+
+    // Stretch factor for old animations missing this property.
+    if (!this.data.sr) {
+      this.data.sr = 1;
+    }
+    // effects manager
+    this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
+  },
+  getType: function () {
+    return this.type;
+  },
+  sourceRectAtTime: function () {},
+};
+
+/**
+ * @file
+ * Handles element's layer frame update.
+ * Checks layer in point and out point
+ *
+ */
+
+function FrameElement() {}
+
+FrameElement.prototype = {
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     */
+  initFrame: function () {
+    // set to true when inpoint is rendered
+    this._isFirstFrame = false;
+    // list of animated properties
+    this.dynamicProperties = [];
+    // If layer has been modified in current tick this will be true
+    this._mdf = false;
+  },
+  /**
+     * @function
+     * Calculates all dynamic values
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     * @param {boolean} isVisible
+     * if layers is currently in range
+     *
+     */
+  prepareProperties: function (num, isVisible) {
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      if (isVisible || (this._isParent && this.dynamicProperties[i].propType === 'transform')) {
+        this.dynamicProperties[i].getValue();
+        if (this.dynamicProperties[i]._mdf) {
+          this.globalData._mdf = true;
+          this._mdf = true;
+        }
+      }
+    }
+  },
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+    }
+  },
+};
+
+function FootageElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.footageData = globalData.imageLoader.getAsset(this.assetData);
+  this.initBaseData(data, globalData, comp);
+}
+
+FootageElement.prototype.prepareFrame = function () {
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
+
+FootageElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+FootageElement.prototype.renderFrame = function () {
+};
+
+FootageElement.prototype.destroy = function () {
+};
+
+FootageElement.prototype.initExpressions = function () {
+  const expressionsInterfaces = getExpressionInterfaces();
+  if (!expressionsInterfaces) {
+    return;
+  }
+  const FootageInterface = expressionsInterfaces('footage');
+  this.layerInterface = FootageInterface(this);
+};
+
+FootageElement.prototype.getFootageData = function () {
+  return this.footageData;
+};
+
+function AudioElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initBaseData(data, globalData, comp);
+  this._isPlaying = false;
+  this._canPlay = false;
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  this.audio = this.globalData.audioController.createAudio(assetPath);
+  this._currentTime = 0;
+  this.globalData.audioController.addAudio(this);
+  this._volumeMultiplier = 1;
+  this._volume = 1;
+  this._previousVolume = null;
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+  this.lv = PropertyFactory.getProp(this, data.au && data.au.lv ? data.au.lv : { k: [100] }, 1, 0.01, this);
+}
+
+AudioElement.prototype.prepareFrame = function (num) {
+  this.prepareRenderableFrame(num, true);
+  this.prepareProperties(num, true);
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    this._currentTime = timeRemapped;
+  } else {
+    this._currentTime = num / this.data.sr;
+  }
+  this._volume = this.lv.v[0];
+  var totalVolume = this._volume * this._volumeMultiplier;
+  if (this._previousVolume !== totalVolume) {
+    this._previousVolume = totalVolume;
+    this.audio.volume(totalVolume);
+  }
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
+
+AudioElement.prototype.renderFrame = function () {
+  if (this.isInRange && this._canPlay) {
+    if (!this._isPlaying) {
+      this.audio.play();
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+      this._isPlaying = true;
+    } else if (!this.audio.playing()
+      || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1
+    ) {
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+    }
+  }
+};
+
+AudioElement.prototype.show = function () {
+  // this.audio.play()
+};
+
+AudioElement.prototype.hide = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+};
+
+AudioElement.prototype.pause = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+  this._canPlay = false;
+};
+
+AudioElement.prototype.resume = function () {
+  this._canPlay = true;
+};
+
+AudioElement.prototype.setRate = function (rateValue) {
+  this.audio.rate(rateValue);
+};
+
+AudioElement.prototype.volume = function (volumeValue) {
+  this._volumeMultiplier = volumeValue;
+  this._previousVolume = volumeValue * this._volume;
+  this.audio.volume(this._previousVolume);
+};
+
+AudioElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+AudioElement.prototype.destroy = function () {
+};
+
+AudioElement.prototype.sourceRectAtTime = function () {
+};
+
+AudioElement.prototype.initExpressions = function () {
+};
+
+function BaseRenderer() {}
+BaseRenderer.prototype.checkLayers = function (num) {
+  var i;
+  var len = this.layers.length;
+  var data;
+  this.completeLayers = true;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (!this.elements[i]) {
+      data = this.layers[i];
+      if (data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) {
+        this.buildItem(i);
+      }
+    }
+    this.completeLayers = this.elements[i] ? this.completeLayers : false;
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.createItem = function (layer) {
+  switch (layer.ty) {
+    case 2:
+      return this.createImage(layer);
+    case 0:
+      return this.createComp(layer);
+    case 1:
+      return this.createSolid(layer);
+    case 3:
+      return this.createNull(layer);
+    case 4:
+      return this.createShape(layer);
+    case 5:
+      return this.createText(layer);
+    case 6:
+      return this.createAudio(layer);
+    case 13:
+      return this.createCamera(layer);
+    case 15:
+      return this.createFootage(layer);
+    default:
+      return this.createNull(layer);
+  }
+};
+
+BaseRenderer.prototype.createCamera = function () {
+  throw new Error('You\'re using a 3d camera. Try the html renderer.');
+};
+
+BaseRenderer.prototype.createAudio = function (data) {
+  return new AudioElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.createFootage = function (data) {
+  return new FootageElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.buildAllItems = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    this.buildItem(i);
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.includeLayers = function (newLayers) {
+  this.completeLayers = false;
+  var i;
+  var len = newLayers.length;
+  var j;
+  var jLen = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    j = 0;
+    while (j < jLen) {
+      if (this.layers[j].id === newLayers[i].id) {
+        this.layers[j] = newLayers[i];
+        break;
+      }
+      j += 1;
+    }
+  }
+};
+
+BaseRenderer.prototype.setProjectInterface = function (pInterface) {
+  this.globalData.projectInterface = pInterface;
+};
+
+BaseRenderer.prototype.initItems = function () {
+  if (!this.globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+};
+BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
+  var elements = this.elements;
+  var layers = this.layers;
+  var i = 0;
+  var len = layers.length;
+  while (i < len) {
+    if (layers[i].ind == parentName) { // eslint-disable-line eqeqeq
+      if (!elements[i] || elements[i] === true) {
+        this.buildItem(i);
+        this.addPendingElement(element);
+      } else {
+        hierarchy.push(elements[i]);
+        elements[i].setAsParent();
+        if (layers[i].parent !== undefined) {
+          this.buildElementParenting(element, layers[i].parent, hierarchy);
+        } else {
+          element.setHierarchy(hierarchy);
+        }
+      }
+    }
+    i += 1;
+  }
+};
+
+BaseRenderer.prototype.addPendingElement = function (element) {
+  this.pendingElements.push(element);
+};
+
+BaseRenderer.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var len = assets.length;
+  for (i = 0; i < len; i += 1) {
+    if (assets[i].xt) {
+      var comp = this.createComp(assets[i]);
+      comp.initExpressions();
+      this.globalData.projectInterface.registerComposition(comp);
+    }
+  }
+};
+
+BaseRenderer.prototype.getElementById = function (ind) {
+  var i;
+  var len = this.elements.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i].data.ind === ind) {
+      return this.elements[i];
+    }
+  }
+  return null;
+};
+
+BaseRenderer.prototype.getElementByPath = function (path) {
+  var pathValue = path.shift();
+  var element;
+  if (typeof pathValue === 'number') {
+    element = this.elements[pathValue];
+  } else {
+    var i;
+    var len = this.elements.length;
+    for (i = 0; i < len; i += 1) {
+      if (this.elements[i].data.nm === pathValue) {
+        element = this.elements[i];
+        break;
+      }
+    }
+  }
+  if (path.length === 0) {
+    return element;
+  }
+  return element.getElementByPath(path);
+};
+
+BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
+  this.globalData.fontManager = new FontManager();
+  this.globalData.slotManager = slotFactory(animData);
+  this.globalData.fontManager.addChars(animData.chars);
+  this.globalData.fontManager.addFonts(animData.fonts, fontsContainer);
+  this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+  this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+  this.globalData.imageLoader = this.animationItem.imagePreloader;
+  this.globalData.audioController = this.animationItem.audioController;
+  this.globalData.frameId = 0;
+  this.globalData.frameRate = animData.fr;
+  this.globalData.nm = animData.nm;
+  this.globalData.compSize = {
+    w: animData.w,
+    h: animData.h,
+  };
+};
+
+var effectTypes = {
+  TRANSFORM_EFFECT: 'transformEFfect',
+};
+
+function TransformElement() {}
+
+TransformElement.prototype = {
+  initTransform: function () {
+    var mat = new Matrix();
+    this.finalTransform = {
+      mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : { o: 0 },
+      _matMdf: false,
+      _localMatMdf: false,
+      _opMdf: false,
+      mat: mat,
+      localMat: mat,
+      localOpacity: 1,
+    };
+    if (this.data.ao) {
+      this.finalTransform.mProp.autoOriented = true;
+    }
+
+    // TODO: check TYPE 11: Guided elements
+    if (this.data.ty !== 11) {
+      // this.createElements();
+    }
+  },
+  renderTransform: function () {
+    this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
+    this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
+
+    if (this.hierarchy) {
+      var mat;
+      var finalMat = this.finalTransform.mat;
+      var i = 0;
+      var len = this.hierarchy.length;
+      // Checking if any of the transformation matrices in the hierarchy chain has changed.
+      if (!this.finalTransform._matMdf) {
+        while (i < len) {
+          if (this.hierarchy[i].finalTransform.mProp._mdf) {
+            this.finalTransform._matMdf = true;
+            break;
+          }
+          i += 1;
+        }
+      }
+
+      if (this.finalTransform._matMdf) {
+        mat = this.finalTransform.mProp.v.props;
+        finalMat.cloneFromProps(mat);
+        for (i = 0; i < len; i += 1) {
+          finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
+        }
+      }
+    }
+    if (!this.localTransforms || this.finalTransform._matMdf) {
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+    }
+    if (this.finalTransform._opMdf) {
+      this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderLocalTransform: function () {
+    if (this.localTransforms) {
+      var i = 0;
+      var len = this.localTransforms.length;
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+      if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
+        while (i < len) {
+          if (this.localTransforms[i]._mdf) {
+            this.finalTransform._localMatMdf = true;
+          }
+          if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
+            this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+            this.finalTransform._opMdf = true;
+          }
+          i += 1;
+        }
+      }
+      if (this.finalTransform._localMatMdf) {
+        var localMat = this.finalTransform.localMat;
+        this.localTransforms[0].matrix.clone(localMat);
+        for (i = 1; i < len; i += 1) {
+          var lmat = this.localTransforms[i].matrix;
+          localMat.multiply(lmat);
+        }
+        localMat.multiply(this.finalTransform.mat);
+      }
+      if (this.finalTransform._opMdf) {
+        var localOp = this.finalTransform.localOpacity;
+        for (i = 0; i < len; i += 1) {
+          localOp *= this.localTransforms[i].opacity * 0.01;
+        }
+        this.finalTransform.localOpacity = localOp;
+      }
+    }
+  },
+  searchEffectTransforms: function () {
+    if (this.renderableEffectsManager) {
+      var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+      if (transformEffects.length) {
+        this.localTransforms = [];
+        this.finalTransform.localMat = new Matrix();
+        var i = 0;
+        var len = transformEffects.length;
+        for (i = 0; i < len; i += 1) {
+          this.localTransforms.push(transformEffects[i]);
+        }
+      }
+    }
+  },
+  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;
+    var len = transforms.length;
+    var 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;
+  },
+  mHelper: new Matrix(),
+};
+
+function MaskElement(data, element, globalData) {
+  this.data = data;
+  this.element = element;
+  this.globalData = globalData;
+  this.storedData = [];
+  this.masksProperties = this.data.masksProperties || [];
+  this.maskElement = null;
+  var defs = this.globalData.defs;
+  var i;
+  var len = this.masksProperties ? this.masksProperties.length : 0;
+  this.viewData = createSizedArray(len);
+  this.solidPath = '';
+
+  var path;
+  var properties = this.masksProperties;
+  var count = 0;
+  var currentMasks = [];
+  var j;
+  var jLen;
+  var layerId = createElementID();
+  var rect;
+  var expansor;
+  var feMorph;
+  var x;
+  var maskType = 'clipPath';
+  var maskRef = 'clip-path';
+  for (i = 0; i < len; i += 1) {
+    if ((properties[i].mode !== 'a' && properties[i].mode !== 'n') || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
+      maskType = 'mask';
+      maskRef = 'mask';
+    }
+
+    if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
+      rect = createNS('rect');
+      rect.setAttribute('fill', '#ffffff');
+      rect.setAttribute('width', this.element.comp.data.w || 0);
+      rect.setAttribute('height', this.element.comp.data.h || 0);
+      currentMasks.push(rect);
+    } else {
+      rect = null;
+    }
+
+    path = createNS('path');
+    if (properties[i].mode === 'n') {
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        elem: path,
+        lastPath: '',
+      };
+      defs.appendChild(path);
+    } else {
+      count += 1;
+
+      path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      path.setAttribute('clip-rule', 'nonzero');
+      var filterID;
+
+      if (properties[i].x.k !== 0) {
+        maskType = 'mask';
+        maskRef = 'mask';
+        x = PropertyFactory.getProp(this.element, properties[i].x, 0, null, this.element);
+        filterID = createElementID();
+        expansor = createNS('filter');
+        expansor.setAttribute('id', filterID);
+        feMorph = createNS('feMorphology');
+        feMorph.setAttribute('operator', 'erode');
+        feMorph.setAttribute('in', 'SourceGraphic');
+        feMorph.setAttribute('radius', '0');
+        expansor.appendChild(feMorph);
+        defs.appendChild(expansor);
+        path.setAttribute('stroke', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      } else {
+        feMorph = null;
+        x = null;
+      }
+
+      // TODO move this to a factory or to a constructor
+      this.storedData[i] = {
+        elem: path,
+        x: x,
+        expan: feMorph,
+        lastPath: '',
+        lastOperator: '',
+        filterId: filterID,
+        lastRadius: 0,
+      };
+      if (properties[i].mode === 'i') {
+        jLen = currentMasks.length;
+        var g = createNS('g');
+        for (j = 0; j < jLen; j += 1) {
+          g.appendChild(currentMasks[j]);
+        }
+        var mask = createNS('mask');
+        mask.setAttribute('mask-type', 'alpha');
+        mask.setAttribute('id', layerId + '_' + count);
+        mask.appendChild(path);
+        defs.appendChild(mask);
+        g.setAttribute('mask', 'url(' + getLocationHref() + '#' + layerId + '_' + count + ')');
+
+        currentMasks.length = 0;
+        currentMasks.push(g);
+      } else {
+        currentMasks.push(path);
+      }
+      if (properties[i].inv && !this.solidPath) {
+        this.solidPath = this.createLayerSolidPath();
+      }
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        elem: path,
+        lastPath: '',
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        invRect: rect,
+      };
+      if (!this.viewData[i].prop.k) {
+        this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
+      }
+    }
+  }
+
+  this.maskElement = createNS(maskType);
+
+  len = currentMasks.length;
+  for (i = 0; i < len; i += 1) {
+    this.maskElement.appendChild(currentMasks[i]);
+  }
+
+  if (count > 0) {
+    this.maskElement.setAttribute('id', layerId);
+    this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
+    defs.appendChild(this.maskElement);
+  }
+  if (this.viewData.length) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+MaskElement.prototype.getMaskProperty = function (pos) {
+  return this.viewData[pos].prop;
+};
+
+MaskElement.prototype.renderFrame = function (isFirstFrame) {
+  var finalMat = this.element.finalTransform.mat;
+  var i;
+  var len = this.masksProperties.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.viewData[i].prop._mdf || isFirstFrame) {
+      this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
+    }
+    if (this.viewData[i].op._mdf || isFirstFrame) {
+      this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
+    }
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
+        this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
+      }
+      if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
+        var feMorph = this.storedData[i].expan;
+        if (this.storedData[i].x.v < 0) {
+          if (this.storedData[i].lastOperator !== 'erode') {
+            this.storedData[i].lastOperator = 'erode';
+            this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
+          }
+          feMorph.setAttribute('radius', -this.storedData[i].x.v);
+        } else {
+          if (this.storedData[i].lastOperator !== 'dilate') {
+            this.storedData[i].lastOperator = 'dilate';
+            this.storedData[i].elem.setAttribute('filter', null);
+          }
+          this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
+        }
+      }
+    }
+  }
+};
+
+MaskElement.prototype.getMaskelement = function () {
+  return this.maskElement;
+};
+
+MaskElement.prototype.createLayerSolidPath = function () {
+  var path = 'M0,0 ';
+  path += ' h' + this.globalData.compSize.w;
+  path += ' v' + this.globalData.compSize.h;
+  path += ' h-' + this.globalData.compSize.w;
+  path += ' v-' + this.globalData.compSize.h + ' ';
+  return path;
+};
+
+MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
+  var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  var i;
+  var len;
+  len = pathNodes._length;
+  for (i = 1; i < len; i += 1) {
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
+  }
+  // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+  if (pathNodes.c && len > 1) {
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  }
+  // pathNodes.__renderedString = pathString;
+
+  if (viewData.lastPath !== pathString) {
+    var pathShapeValue = '';
+    if (viewData.elem) {
+      if (pathNodes.c) {
+        pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
+      }
+      viewData.elem.setAttribute('d', pathShapeValue);
+    }
+    viewData.lastPath = pathString;
+  }
+};
+
+MaskElement.prototype.destroy = function () {
+  this.element = null;
+  this.globalData = null;
+  this.maskElement = null;
+  this.data = null;
+  this.masksProperties = null;
+};
+
+const filtersFactory = (function () {
+  var ob = {};
+  ob.createFilter = createFilter;
+  ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
+
+  function createFilter(filId, skipCoordinates) {
+    var fil = createNS('filter');
+    fil.setAttribute('id', filId);
+    if (skipCoordinates !== true) {
+      fil.setAttribute('filterUnits', 'objectBoundingBox');
+      fil.setAttribute('x', '0%');
+      fil.setAttribute('y', '0%');
+      fil.setAttribute('width', '100%');
+      fil.setAttribute('height', '100%');
+    }
+    return fil;
+  }
+
+  function createAlphaToLuminanceFilter() {
+    var feColorMatrix = createNS('feColorMatrix');
+    feColorMatrix.setAttribute('type', 'matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+    feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
+    return feColorMatrix;
+  }
+
+  return ob;
+}());
+
+const featureSupport = (function () {
+  var ob = {
+    maskType: true,
+    svgLumaHidden: true,
+    offscreenCanvas: typeof OffscreenCanvas !== 'undefined',
+  };
+  if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
+    ob.maskType = false;
+  }
+  if (/firefox/i.test(navigator.userAgent)) {
+    ob.svgLumaHidden = false;
+  }
+  return ob;
+}());
+
+var registeredEffects$1 = {};
+var idPrefix = 'filter_result_';
+
+function SVGEffects(elem) {
+  var i;
+  var source = 'SourceGraphic';
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  var filId = createElementID();
+  var fil = filtersFactory.createFilter(filId, true);
+  var count = 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects$1[type]) {
+      var Effect = registeredEffects$1[type].effect;
+      filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
+      source = idPrefix + count;
+      if (registeredEffects$1[type].countsAsEffect) {
+        count += 1;
+      }
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (count) {
+    elem.globalData.defs.appendChild(fil);
+    elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+SVGEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect$1(id, effect, countsAsEffect) {
+  registeredEffects$1[id] = {
+    effect,
+    countsAsEffect,
+  };
+}
+
+function SVGBaseElement() {
+}
+
+SVGBaseElement.prototype = {
+  initRendererElement: function () {
+    this.layerElement = createNS('g');
+  },
+  createContainerElements: function () {
+    this.matteElement = createNS('g');
+    this.transformedElement = this.layerElement;
+    this.maskedElement = this.layerElement;
+    this._sizeChanged = false;
+    var layerElementParent = null;
+    // If this layer acts as a mask for the following layer
+    if (this.data.td) {
+      this.matteMasks = {};
+      var gg = createNS('g');
+      gg.setAttribute('id', this.layerId);
+      gg.appendChild(this.layerElement);
+      layerElementParent = gg;
+      this.globalData.defs.appendChild(gg);
+    } else if (this.data.tt) {
+      this.matteElement.appendChild(this.layerElement);
+      layerElementParent = this.matteElement;
+      this.baseElement = this.matteElement;
+    } else {
+      this.baseElement = this.layerElement;
+    }
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
+    if (this.data.ty === 0 && !this.data.hd) {
+      var cp = createNS('clipPath');
+      var pt = createNS('path');
+      pt.setAttribute('d', 'M0,0 L' + this.data.w + ',0 L' + this.data.w + ',' + this.data.h + ' L0,' + this.data.h + 'z');
+      var clipId = createElementID();
+      cp.setAttribute('id', clipId);
+      cp.appendChild(pt);
+      this.globalData.defs.appendChild(cp);
+
+      if (this.checkMasks()) {
+        var cpGroup = createNS('g');
+        cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+        cpGroup.appendChild(this.layerElement);
+        this.transformedElement = cpGroup;
+        if (layerElementParent) {
+          layerElementParent.appendChild(this.transformedElement);
+        } else {
+          this.baseElement = this.transformedElement;
+        }
+      } else {
+        this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+      }
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    if (this.finalTransform._localMatMdf) {
+      this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
+    }
+    if (this.finalTransform._opMdf) {
+      this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
+    }
+  },
+  destroyBaseElement: function () {
+    this.layerElement = null;
+    this.matteElement = null;
+    this.maskManager.destroy();
+  },
+  getBaseElement: function () {
+    if (this.data.hd) {
+      return null;
+    }
+    return this.baseElement;
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+    this.renderableEffectsManager = new SVGEffects(this);
+    this.searchEffectTransforms();
+  },
+  getMatte: function (matteType) {
+    // This should not be a common case. But for backward compatibility, we'll create the matte object.
+    // It solves animations that have two consecutive layers marked as matte masks.
+    // Which is an undefined behavior in AE.
+    if (!this.matteMasks) {
+      this.matteMasks = {};
+    }
+    if (!this.matteMasks[matteType]) {
+      var id = this.layerId + '_' + matteType;
+      var filId;
+      var fil;
+      var useElement;
+      var gg;
+      if (matteType === 1 || matteType === 3) {
+        var masker = createNS('mask');
+        masker.setAttribute('id', id);
+        masker.setAttribute('mask-type', matteType === 3 ? 'luminance' : 'alpha');
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        masker.appendChild(useElement);
+        this.globalData.defs.appendChild(masker);
+        if (!featureSupport.maskType && matteType === 1) {
+          masker.setAttribute('mask-type', 'luminance');
+          filId = createElementID();
+          fil = filtersFactory.createFilter(filId);
+          this.globalData.defs.appendChild(fil);
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          gg.appendChild(useElement);
+          masker.appendChild(gg);
+          gg.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        }
+      } else if (matteType === 2) {
+        var maskGroup = createNS('mask');
+        maskGroup.setAttribute('id', id);
+        maskGroup.setAttribute('mask-type', 'alpha');
+        var maskGrouper = createNS('g');
+        maskGroup.appendChild(maskGrouper);
+        filId = createElementID();
+        fil = filtersFactory.createFilter(filId);
+        /// /
+        var feCTr = createNS('feComponentTransfer');
+        feCTr.setAttribute('in', 'SourceGraphic');
+        fil.appendChild(feCTr);
+        var feFunc = createNS('feFuncA');
+        feFunc.setAttribute('type', 'table');
+        feFunc.setAttribute('tableValues', '1.0 0.0');
+        feCTr.appendChild(feFunc);
+        /// /
+        this.globalData.defs.appendChild(fil);
+        var alphaRect = createNS('rect');
+        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');
+        alphaRect.setAttribute('opacity', '0');
+        maskGrouper.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        maskGrouper.appendChild(alphaRect);
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        maskGrouper.appendChild(useElement);
+        if (!featureSupport.maskType) {
+          maskGroup.setAttribute('mask-type', 'luminance');
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          maskGrouper.appendChild(alphaRect);
+          gg.appendChild(this.layerElement);
+          maskGrouper.appendChild(gg);
+        }
+        this.globalData.defs.appendChild(maskGroup);
+      }
+      this.matteMasks[matteType] = id;
+    }
+    return this.matteMasks[matteType];
+  },
+  setMatte: function (id) {
+    if (!this.matteElement) {
+      return;
+    }
+    this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+  },
+};
+
+/**
+ * @file
+ * Handles AE's layer parenting property.
+ *
+ */
+
+function HierarchyElement() {}
+
+HierarchyElement.prototype = {
+  /**
+     * @function
+     * Initializes hierarchy properties
+     *
+     */
+  initHierarchy: function () {
+    // element's parent list
+    this.hierarchy = [];
+    // if element is parent of another layer _isParent will be true
+    this._isParent = false;
+    this.checkParenting();
+  },
+  /**
+     * @function
+     * Sets layer's hierarchy.
+     * @param {array} hierarch
+     * layer's parent list
+     *
+     */
+  setHierarchy: function (hierarchy) {
+    this.hierarchy = hierarchy;
+  },
+  /**
+     * @function
+     * Sets layer as parent.
+     *
+     */
+  setAsParent: function () {
+    this._isParent = true;
+  },
+  /**
+     * @function
+     * Searches layer's parenting chain
+     *
+     */
+  checkParenting: function () {
+    if (this.data.parent !== undefined) {
+      this.comp.buildElementParenting(this, this.data.parent, []);
+    }
+  },
+};
+
+function RenderableDOMElement() {}
+
+(function () {
+  var _prototype = {
+    initElement: function (data, globalData, comp) {
+      this.initFrame();
+      this.initBaseData(data, globalData, comp);
+      this.initTransform(data, globalData, comp);
+      this.initHierarchy();
+      this.initRenderable();
+      this.initRendererElement();
+      this.createContainerElements();
+      this.createRenderableComponents();
+      this.createContent();
+      this.hide();
+    },
+    hide: function () {
+      // console.log('HIDE', this);
+      if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+        var elem = this.baseElement || this.layerElement;
+        elem.style.display = 'none';
+        this.hidden = true;
+      }
+    },
+    show: function () {
+      // console.log('SHOW', this);
+      if (this.isInRange && !this.isTransparent) {
+        if (!this.data.hd) {
+          var elem = this.baseElement || this.layerElement;
+          elem.style.display = 'block';
+        }
+        this.hidden = false;
+        this._isFirstFrame = true;
+      }
+    },
+    renderFrame: function () {
+      // If it is exported as hidden (data.hd === true) no need to render
+      // If it is not visible no need to render
+      if (this.data.hd || this.hidden) {
+        return;
+      }
+      this.renderTransform();
+      this.renderRenderable();
+      this.renderLocalTransform();
+      this.renderElement();
+      this.renderInnerContent();
+      if (this._isFirstFrame) {
+        this._isFirstFrame = false;
+      }
+    },
+    renderInnerContent: function () {},
+    prepareFrame: function (num) {
+      this._mdf = false;
+      this.prepareRenderableFrame(num);
+      this.prepareProperties(num, this.isInRange);
+      this.checkTransparency();
+    },
+    destroy: function () {
+      this.innerElem = null;
+      this.destroyBaseElement();
+    },
+  };
+  extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement);
+}());
+
+function IImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  if (this.assetData && this.assetData.sid) {
+    this.assetData = globalData.slotManager.getProp(this.assetData);
+  }
+  this.initElement(data, globalData, comp);
+  this.sourceRect = {
+    top: 0, left: 0, width: this.assetData.w, height: this.assetData.h,
+  };
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
+
+IImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+
+  this.innerElem = createNS('image');
+  this.innerElem.setAttribute('width', this.assetData.w + 'px');
+  this.innerElem.setAttribute('height', this.assetData.h + 'px');
+  this.innerElem.setAttribute('preserveAspectRatio', this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio);
+  this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+
+  this.layerElement.appendChild(this.innerElem);
+};
+
+IImageElement.prototype.sourceRectAtTime = function () {
+  return this.sourceRect;
+};
+
+function ProcessedElement(element, position) {
+  this.elem = element;
+  this.pos = position;
+}
+
+function IShapeElement() {
+}
+
+IShapeElement.prototype = {
+  addShapeToModifiers: function (data) {
+    var i;
+    var len = this.shapeModifiers.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapeModifiers[i].addShape(data);
+    }
+  },
+  isShapeInAnimatedModifiers: function (data) {
+    var i = 0;
+    var len = this.shapeModifiers.length;
+    while (i < len) {
+      if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
+        return true;
+      }
+    }
+    return false;
+  },
+  renderModifiers: function () {
+    if (!this.shapeModifiers.length) {
+      return;
+    }
+    var i;
+    var len = this.shapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].sh.reset();
+    }
+
+    len = this.shapeModifiers.length;
+    var shouldBreakProcess;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+      // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+      // TODO: find a better solution for this
+      if (shouldBreakProcess) {
+        break;
+      }
+    }
+  },
+
+  searchProcessedElement: function (elem) {
+    var elements = this.processedElements;
+    var i = 0;
+    var len = elements.length;
+    while (i < len) {
+      if (elements[i].elem === elem) {
+        return elements[i].pos;
+      }
+      i += 1;
+    }
+    return 0;
+  },
+  addProcessedElement: function (elem, pos) {
+    var elements = this.processedElements;
+    var i = elements.length;
+    while (i) {
+      i -= 1;
+      if (elements[i].elem === elem) {
+        elements[i].pos = pos;
+        return;
+      }
+    }
+    elements.push(new ProcessedElement(elem, pos));
+  },
+  prepareFrame: function (num) {
+    this.prepareRenderableFrame(num);
+    this.prepareProperties(num, this.isInRange);
+  },
+};
+
+const lineCapEnum = {
+  1: 'butt',
+  2: 'round',
+  3: 'square',
+};
+
+const lineJoinEnum = {
+  1: 'miter',
+  2: 'round',
+  3: 'bevel',
+};
+
+function SVGShapeData(transformers, level, shape) {
+  this.caches = [];
+  this.styles = [];
+  this.transformers = transformers;
+  this.lStr = '';
+  this.sh = shape;
+  this.lvl = level;
+  // TODO find if there are some cases where _isAnimated can be false.
+  // For now, since shapes add up with other shapes. They have to be calculated every time.
+  // One way of finding out is checking if all styles associated to this shape depend only of this shape
+  this._isAnimated = !!shape.k;
+  // TODO: commenting this for now since all shapes are animated
+  var i = 0;
+  var len = transformers.length;
+  while (i < len) {
+    if (transformers[i].mProps.dynamicProperties.length) {
+      this._isAnimated = true;
+      break;
+    }
+    i += 1;
+  }
+}
+
+SVGShapeData.prototype.setAsAnimated = function () {
+  this._isAnimated = true;
+};
+
+function SVGStyleData(data, level) {
+  this.data = data;
+  this.type = data.ty;
+  this.d = '';
+  this.lvl = level;
+  this._mdf = false;
+  this.closed = data.hd === true;
+  this.pElem = createNS('path');
+  this.msElem = null;
+}
+
+SVGStyleData.prototype.reset = function () {
+  this.d = '';
+  this._mdf = false;
+};
+
+function DashProperty(elem, data, renderer, container) {
+  this.elem = elem;
+  this.frameId = -1;
+  this.dataProps = createSizedArray(data.length);
+  this.renderer = renderer;
+  this.k = false;
+  this.dashStr = '';
+  this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0);
+  this.dashoffset = createTypedArray('float32', 1);
+  this.initDynamicPropertyContainer(container);
+  var i;
+  var len = data.length || 0;
+  var prop;
+  for (i = 0; i < len; i += 1) {
+    prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
+    this.k = prop.k || this.k;
+    this.dataProps[i] = { n: data[i].n, p: prop };
+  }
+  if (!this.k) {
+    this.getValue(true);
+  }
+  this._isAnimated = this.k;
+}
+
+DashProperty.prototype.getValue = function (forceRender) {
+  if (this.elem.globalData.frameId === this.frameId && !forceRender) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+  this._mdf = this._mdf || forceRender;
+  if (this._mdf) {
+    var i = 0;
+    var len = this.dataProps.length;
+    if (this.renderer === 'svg') {
+      this.dashStr = '';
+    }
+    for (i = 0; i < len; i += 1) {
+      if (this.dataProps[i].n !== 'o') {
+        if (this.renderer === 'svg') {
+          this.dashStr += ' ' + this.dataProps[i].p.v;
+        } else {
+          this.dashArray[i] = this.dataProps[i].p.v;
+        }
+      } else {
+        this.dashoffset[0] = this.dataProps[i].p.v;
+      }
+    }
+  }
+};
+extendPrototype([DynamicPropertyContainer], DashProperty);
+
+function SVGStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
+
+function SVGFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
+
+function SVGNoStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
+
+function GradientProperty(elem, data, container) {
+  this.data = data;
+  this.c = createTypedArray('uint8c', data.p * 4);
+  var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p * 4) : data.k.k.length - data.p * 4;
+  this.o = createTypedArray('float32', cLength);
+  this._cmdf = false;
+  this._omdf = false;
+  this._collapsable = this.checkCollapsable();
+  this._hasOpacity = cLength;
+  this.initDynamicPropertyContainer(container);
+  this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this);
+  this.k = this.prop.k;
+  this.getValue(true);
+}
+
+GradientProperty.prototype.comparePoints = function (values, points) {
+  var i = 0;
+  var len = this.o.length / 2;
+  var diff;
+  while (i < len) {
+    diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
+    if (diff > 0.01) {
+      return false;
+    }
+    i += 1;
+  }
+  return true;
+};
+
+GradientProperty.prototype.checkCollapsable = function () {
+  if (this.o.length / 2 !== this.c.length / 4) {
+    return false;
+  }
+  if (this.data.k.k[0].s) {
+    var i = 0;
+    var len = this.data.k.k.length;
+    while (i < len) {
+      if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
+        return false;
+      }
+      i += 1;
+    }
+  } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
+    return false;
+  }
+  return true;
+};
+
+GradientProperty.prototype.getValue = function (forceRender) {
+  this.prop.getValue();
+  this._mdf = false;
+  this._cmdf = false;
+  this._omdf = false;
+  if (this.prop._mdf || forceRender) {
+    var i;
+    var len = this.data.p * 4;
+    var mult;
+    var val;
+    for (i = 0; i < len; i += 1) {
+      mult = i % 4 === 0 ? 100 : 255;
+      val = Math.round(this.prop.v[i] * mult);
+      if (this.c[i] !== val) {
+        this.c[i] = val;
+        this._cmdf = !forceRender;
+      }
+    }
+    if (this.o.length) {
+      len = this.prop.v.length;
+      for (i = this.data.p * 4; i < len; i += 1) {
+        mult = i % 2 === 0 ? 100 : 1;
+        val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
+        if (this.o[i - this.data.p * 4] !== val) {
+          this.o[i - this.data.p * 4] = val;
+          this._omdf = !forceRender;
+        }
+      }
+    }
+    this._mdf = !forceRender;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], GradientProperty);
+
+function SVGGradientFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.initGradientData(elem, data, styleOb);
+}
+
+SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 1, null, this);
+  this.h = PropertyFactory.getProp(elem, data.h || { k: 0 }, 0, 0.01, this);
+  this.a = PropertyFactory.getProp(elem, data.a || { k: 0 }, 0, degToRads, this);
+  this.g = new GradientProperty(elem, data.g, this);
+  this.style = styleOb;
+  this.stops = [];
+  this.setGradientData(styleOb.pElem, data);
+  this.setGradientOpacity(data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+};
+
+SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
+  var gradientId = createElementID();
+  var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+  gfill.setAttribute('id', gradientId);
+  gfill.setAttribute('spreadMethod', 'pad');
+  gfill.setAttribute('gradientUnits', 'userSpaceOnUse');
+  var stops = [];
+  var stop;
+  var j;
+  var jLen;
+  jLen = data.g.p * 4;
+  for (j = 0; j < jLen; j += 4) {
+    stop = createNS('stop');
+    gfill.appendChild(stop);
+    stops.push(stop);
+  }
+  pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
+  this.gf = gfill;
+  this.cst = stops;
+};
+
+SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
+  if (this.g._hasOpacity && !this.g._collapsable) {
+    var stop;
+    var j;
+    var jLen;
+    var mask = createNS('mask');
+    var maskElement = createNS('path');
+    mask.appendChild(maskElement);
+    var opacityId = createElementID();
+    var maskId = createElementID();
+    mask.setAttribute('id', maskId);
+    var opFill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+    opFill.setAttribute('id', opacityId);
+    opFill.setAttribute('spreadMethod', 'pad');
+    opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
+    jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
+    var stops = this.stops;
+    for (j = data.g.p * 4; j < jLen; j += 2) {
+      stop = createNS('stop');
+      stop.setAttribute('stop-color', 'rgb(255,255,255)');
+      opFill.appendChild(stop);
+      stops.push(stop);
+    }
+    maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
+    this.maskId = maskId;
+    styleOb.msElem = maskElement;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
+
+function SVGGradientStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.initGradientData(elem, data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
+
+function ShapeGroupData() {
+  this.it = [];
+  this.prevViewData = [];
+  this.gr = createNS('g');
+}
+
+function SVGTransformData(mProps, op, container) {
+  this.transform = {
+    mProps: mProps,
+    op: op,
+    container: container,
+  };
+  this.elements = [];
+  this._isAnimated = this.transform.mProps.dynamicProperties.length || this.transform.op.effectsSequence.length;
+}
+
+const buildShapeString = function (pathNodes, length, closed, mat) {
+  if (length === 0) {
+    return '';
+  }
+  var _o = pathNodes.o;
+  var _i = pathNodes.i;
+  var _v = pathNodes.v;
+  var i;
+  var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+  for (i = 1; i < length; i += 1) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
+  }
+  if (closed && length) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+    shapeString += 'z';
+  }
+  return shapeString;
+};
+
+const SVGElementsRenderer = (function () {
+  var _identityMatrix = new Matrix();
+  var _matrixHelper = new Matrix();
+
+  var ob = {
+    createRenderFunction: createRenderFunction,
+  };
+
+  function createRenderFunction(data) {
+    switch (data.ty) {
+      case 'fl':
+        return renderFill;
+      case 'gf':
+        return renderGradient;
+      case 'gs':
+        return renderGradientStroke;
+      case 'st':
+        return renderStroke;
+      case 'sh':
+      case 'el':
+      case 'rc':
+      case 'sr':
+        return renderPath;
+      case 'tr':
+        return renderContentTransform;
+      case 'no':
+        return renderNoop;
+      default:
+        return null;
+    }
+  }
+
+  function renderContentTransform(styleData, itemData, isFirstFrame) {
+    if (isFirstFrame || itemData.transform.op._mdf) {
+      itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
+    }
+    if (isFirstFrame || itemData.transform.mProps._mdf) {
+      itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
+    }
+  }
+
+  function renderNoop() {
+
+  }
+
+  function renderPath(styleData, itemData, isFirstFrame) {
+    var j;
+    var jLen;
+    var pathStringTransformed;
+    var redraw;
+    var pathNodes;
+    var l;
+    var lLen = itemData.styles.length;
+    var lvl = itemData.lvl;
+    var paths;
+    var mat;
+    var iterations;
+    var k;
+    for (l = 0; l < lLen; l += 1) {
+      redraw = itemData.sh._mdf || isFirstFrame;
+      if (itemData.styles[l].lvl < lvl) {
+        mat = _matrixHelper.reset();
+        iterations = lvl - itemData.styles[l].lvl;
+        k = itemData.transformers.length - 1;
+        while (!redraw && iterations > 0) {
+          redraw = itemData.transformers[k].mProps._mdf || redraw;
+          iterations -= 1;
+          k -= 1;
+        }
+        if (redraw) {
+          iterations = lvl - itemData.styles[l].lvl;
+          k = itemData.transformers.length - 1;
+          while (iterations > 0) {
+            mat.multiply(itemData.transformers[k].mProps.v);
+            iterations -= 1;
+            k -= 1;
+          }
+        }
+      } else {
+        mat = _identityMatrix;
+      }
+      paths = itemData.sh.paths;
+      jLen = paths._length;
+      if (redraw) {
+        pathStringTransformed = '';
+        for (j = 0; j < jLen; j += 1) {
+          pathNodes = paths.shapes[j];
+          if (pathNodes && pathNodes._length) {
+            pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
+          }
+        }
+        itemData.caches[l] = pathStringTransformed;
+      } else {
+        pathStringTransformed = itemData.caches[l];
+      }
+      itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
+      itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
+    }
+  }
+
+  function renderFill(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+
+    if (itemData.c._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
+    }
+  }
+
+  function renderGradientStroke(styleData, itemData, isFirstFrame) {
+    renderGradient(styleData, itemData, isFirstFrame);
+    renderStroke(styleData, itemData, isFirstFrame);
+  }
+
+  function renderGradient(styleData, itemData, isFirstFrame) {
+    var gfill = itemData.gf;
+    var hasOpacity = itemData.g._hasOpacity;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+
+    if (itemData.o._mdf || isFirstFrame) {
+      var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
+      itemData.style.pElem.setAttribute(attr, itemData.o.v);
+    }
+    if (itemData.s._mdf || isFirstFrame) {
+      var attr1 = styleData.t === 1 ? 'x1' : 'cx';
+      var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
+      gfill.setAttribute(attr1, pt1[0]);
+      gfill.setAttribute(attr2, pt1[1]);
+      if (hasOpacity && !itemData.g._collapsable) {
+        itemData.of.setAttribute(attr1, pt1[0]);
+        itemData.of.setAttribute(attr2, pt1[1]);
+      }
+    }
+    var stops;
+    var i;
+    var len;
+    var stop;
+    if (itemData.g._cmdf || isFirstFrame) {
+      stops = itemData.cst;
+      var cValues = itemData.g.c;
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        stop.setAttribute('offset', cValues[i * 4] + '%');
+        stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
+      }
+    }
+    if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
+      var oValues = itemData.g.o;
+      if (itemData.g._collapsable) {
+        stops = itemData.cst;
+      } else {
+        stops = itemData.ost;
+      }
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        if (!itemData.g._collapsable) {
+          stop.setAttribute('offset', oValues[i * 2] + '%');
+        }
+        stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
+      }
+    }
+    if (styleData.t === 1) {
+      if (itemData.e._mdf || isFirstFrame) {
+        gfill.setAttribute('x2', pt2[0]);
+        gfill.setAttribute('y2', pt2[1]);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('x2', pt2[0]);
+          itemData.of.setAttribute('y2', pt2[1]);
+        }
+      }
+    } else {
+      var rad;
+      if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
+        rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        gfill.setAttribute('r', rad);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('r', rad);
+        }
+      }
+      if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (!rad) {
+          rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        }
+        var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+        var percent = itemData.h.v;
+        if (percent >= 1) {
+          percent = 0.99;
+        } else if (percent <= -1) {
+          percent = -0.99;
+        }
+        var dist = rad * percent;
+        var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+        var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+        gfill.setAttribute('fx', x);
+        gfill.setAttribute('fy', y);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('fx', x);
+          itemData.of.setAttribute('fy', y);
+        }
+      }
+      // gfill.setAttribute('fy','200');
+    }
+  }
+
+  function renderStroke(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+    var d = itemData.d;
+    if (d && (d._mdf || isFirstFrame) && d.dashStr) {
+      styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
+      styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
+    }
+    if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
+      styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
+    }
+    if (itemData.w._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
+      if (styleElem.msElem) {
+        styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
+      }
+    }
+  }
+
+  return ob;
+}());
+
+function SVGShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
+
+SVGShapeElement.prototype.initSecondaryElement = function () {
+};
+
+SVGShapeElement.prototype.identityMatrix = new Matrix();
+
+SVGShapeElement.prototype.buildExpressionInterface = function () {};
+
+SVGShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+};
+
+/*
+This method searches for multiple shapes that affect a single element and one of them is animated
+*/
+SVGShapeElement.prototype.filterUniqueShapes = function () {
+  var i;
+  var len = this.shapes.length;
+  var shape;
+  var j;
+  var jLen = this.stylesList.length;
+  var style;
+  var tempShapes = [];
+  var areAnimated = false;
+  for (j = 0; j < jLen; j += 1) {
+    style = this.stylesList[j];
+    areAnimated = false;
+    tempShapes.length = 0;
+    for (i = 0; i < len; i += 1) {
+      shape = this.shapes[i];
+      if (shape.styles.indexOf(style) !== -1) {
+        tempShapes.push(shape);
+        areAnimated = shape._isAnimated || areAnimated;
+      }
+    }
+    if (tempShapes.length > 1 && areAnimated) {
+      this.setShapesAsAnimated(tempShapes);
+    }
+  }
+};
+
+SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
+  var i;
+  var len = shapes.length;
+  for (i = 0; i < len; i += 1) {
+    shapes[i].setAsAnimated();
+  }
+};
+
+SVGShapeElement.prototype.createStyleElement = function (data, level) {
+  // TODO: prevent drawing of hidden styles
+  var elementData;
+  var styleOb = new SVGStyleData(data, level);
+
+  var pathElement = styleOb.pElem;
+  if (data.ty === 'st') {
+    elementData = new SVGStrokeStyleData(this, data, styleOb);
+  } else if (data.ty === 'fl') {
+    elementData = new SVGFillStyleData(this, data, styleOb);
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
+    elementData = new GradientConstructor(this, data, styleOb);
+    this.globalData.defs.appendChild(elementData.gf);
+    if (elementData.maskId) {
+      this.globalData.defs.appendChild(elementData.ms);
+      this.globalData.defs.appendChild(elementData.of);
+      pathElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + elementData.maskId + ')');
+    }
+  } else if (data.ty === 'no') {
+    elementData = new SVGNoStyleData(this, data, styleOb);
+  }
+
+  if (data.ty === 'st' || data.ty === 'gs') {
+    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);
+    }
+  }
+
+  if (data.r === 2) {
+    pathElement.setAttribute('fill-rule', 'evenodd');
+  }
+
+  if (data.ln) {
+    pathElement.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    pathElement.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  this.stylesList.push(styleOb);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createGroupElement = function (data) {
+  var elementData = new ShapeGroupData();
+  if (data.ln) {
+    elementData.gr.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    elementData.gr.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  return elementData;
+};
+
+SVGShapeElement.prototype.createTransformElement = function (data, container) {
+  var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
+  var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
+  var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
+  var i = 0;
+  var len = this.animatedContents.length;
+  while (i < len) {
+    if (this.animatedContents[i].element === element) {
+      return;
+    }
+    i += 1;
+  }
+  this.animatedContents.push({
+    fn: SVGElementsRenderer.createRenderFunction(data),
+    element: element,
+    data: data,
+  });
+};
+
+SVGShapeElement.prototype.setElementStyles = function (elementData) {
+  var arr = elementData.styles;
+  var j;
+  var jLen = this.stylesList.length;
+  for (j = 0; j < jLen; j += 1) {
+    if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
+      arr.push(this.stylesList[j]);
+    }
+  }
+};
+
+SVGShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+};
+
+SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
+  var ownTransformers = [].concat(transformers);
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var currentTransform;
+  var modifier;
+  var processedPos;
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._render = render;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], level);
+      } else {
+        itemsData[i].style.closed = arr[i].hd;
+      }
+      if (arr[i]._render) {
+        if (itemsData[i].style.pElem.parentNode !== container) {
+          container.appendChild(itemsData[i].style.pElem);
+        }
+      }
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
+      if (arr[i]._render) {
+        if (itemsData[i].gr.parentNode !== container) {
+          container.appendChild(itemsData[i].gr);
+        }
+      }
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        itemsData[i] = this.createTransformElement(arr[i], container);
+      }
+      currentTransform = itemsData[i].transform;
+      ownTransformers.push(currentTransform);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
+      }
+      this.setElementStyles(itemsData[i]);
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        render = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  len = ownStyles.length;
+  for (i = 0; i < len; i += 1) {
+    ownStyles[i].closed = true;
+  }
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+SVGShapeElement.prototype.renderInnerContent = function () {
+  this.renderModifiers();
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    this.stylesList[i].reset();
+  }
+  this.renderShape();
+  for (i = 0; i < len; i += 1) {
+    if (this.stylesList[i]._mdf || this._isFirstFrame) {
+      if (this.stylesList[i].msElem) {
+        this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+        // Adding M0 0 fixes same mask bug on all browsers
+        this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
+      }
+      this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
+    }
+  }
+};
+
+SVGShapeElement.prototype.renderShape = function () {
+  var i;
+  var len = this.animatedContents.length;
+  var animatedContent;
+  for (i = 0; i < len; i += 1) {
+    animatedContent = this.animatedContents[i];
+    if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
+      animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
+    }
+  }
+};
+
+SVGShapeElement.prototype.destroy = function () {
+  this.destroyBaseElement();
+  this.shapesData = null;
+  this.itemsData = null;
+};
+
+function LetterProps(o, sw, sc, fc, m, p) {
+  this.o = o;
+  this.sw = sw;
+  this.sc = sc;
+  this.fc = fc;
+  this.m = m;
+  this.p = p;
+  this._mdf = {
+    o: true,
+    sw: !!sw,
+    sc: !!sc,
+    fc: !!fc,
+    m: true,
+    p: true,
+  };
+}
+
+LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
+  this._mdf.o = false;
+  this._mdf.sw = false;
+  this._mdf.sc = false;
+  this._mdf.fc = false;
+  this._mdf.m = false;
+  this._mdf.p = false;
+  var updated = false;
+
+  if (this.o !== o) {
+    this.o = o;
+    this._mdf.o = true;
+    updated = true;
+  }
+  if (this.sw !== sw) {
+    this.sw = sw;
+    this._mdf.sw = true;
+    updated = true;
+  }
+  if (this.sc !== sc) {
+    this.sc = sc;
+    this._mdf.sc = true;
+    updated = true;
+  }
+  if (this.fc !== fc) {
+    this.fc = fc;
+    this._mdf.fc = true;
+    updated = true;
+  }
+  if (this.m !== m) {
+    this.m = m;
+    this._mdf.m = true;
+    updated = true;
+  }
+  if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
+    this.p = p;
+    this._mdf.p = true;
+    updated = true;
+  }
+  return updated;
+};
+
+function TextProperty(elem, data) {
+  this._frameId = initialDefaultFrame;
+  this.pv = '';
+  this.v = '';
+  this.kf = false;
+  this._isFirstFrame = true;
+  this._mdf = false;
+  if (data.d && data.d.sid) {
+    data.d = elem.globalData.slotManager.getProp(data.d);
+  }
+  this.data = data;
+  this.elem = elem;
+  this.comp = this.elem.comp;
+  this.keysIndex = 0;
+  this.canResize = false;
+  this.minimumFontSize = 1;
+  this.effectsSequence = [];
+  this.currentData = {
+    ascent: 0,
+    boxWidth: this.defaultBoxWidth,
+    f: '',
+    fStyle: '',
+    fWeight: '',
+    fc: '',
+    j: '',
+    justifyOffset: '',
+    l: [],
+    lh: 0,
+    lineWidths: [],
+    ls: '',
+    of: '',
+    s: '',
+    sc: '',
+    sw: 0,
+    t: 0,
+    tr: 0,
+    sz: 0,
+    ps: null,
+    fillColorAnim: false,
+    strokeColorAnim: false,
+    strokeWidthAnim: false,
+    yOffset: 0,
+    finalSize: 0,
+    finalText: [],
+    finalLineHeight: 0,
+    __complete: false,
+
+  };
+  this.copyData(this.currentData, this.data.d.k[0].s);
+
+  if (!this.searchProperty()) {
+    this.completeTextData(this.currentData);
+  }
+}
+
+TextProperty.prototype.defaultBoxWidth = [0, 0];
+
+TextProperty.prototype.copyData = function (obj, data) {
+  for (var s in data) {
+    if (Object.prototype.hasOwnProperty.call(data, s)) {
+      obj[s] = data[s];
+    }
+  }
+  return obj;
+};
+
+TextProperty.prototype.setCurrentData = function (data) {
+  if (!data.__complete) {
+    this.completeTextData(data);
+  }
+  this.currentData = data;
+  this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
+  this._mdf = true;
+};
+
+TextProperty.prototype.searchProperty = function () {
+  return this.searchKeyframes();
+};
+
+TextProperty.prototype.searchKeyframes = function () {
+  this.kf = this.data.d.k.length > 1;
+  if (this.kf) {
+    this.addEffect(this.getKeyframeValue.bind(this));
+  }
+  return this.kf;
+};
+
+TextProperty.prototype.addEffect = function (effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.getValue = function (_finalValue) {
+  if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
+    return;
+  }
+  this.currentData.t = this.data.d.k[this.keysIndex].s.t;
+  var currentValue = this.currentData;
+  var currentIndex = this.keysIndex;
+  if (this.lock) {
+    this.setCurrentData(this.currentData);
+    return;
+  }
+  this.lock = true;
+  this._mdf = false;
+  var i; var
+    len = this.effectsSequence.length;
+  var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
+  for (i = 0; i < len; i += 1) {
+    // Checking if index changed to prevent creating a new object every time the expression updates.
+    if (currentIndex !== this.keysIndex) {
+      finalValue = this.effectsSequence[i](finalValue, finalValue.t);
+    } else {
+      finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
+    }
+  }
+  if (currentValue !== finalValue) {
+    this.setCurrentData(finalValue);
+  }
+  this.v = this.currentData;
+  this.pv = this.v;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+};
+
+TextProperty.prototype.getKeyframeValue = function () {
+  var textKeys = this.data.d.k;
+  var frameNum = this.elem.comp.renderedFrame;
+  var i = 0; var
+    len = textKeys.length;
+  while (i <= len - 1) {
+    if (i === len - 1 || textKeys[i + 1].t > frameNum) {
+      break;
+    }
+    i += 1;
+  }
+  if (this.keysIndex !== i) {
+    this.keysIndex = i;
+  }
+  return this.data.d.k[this.keysIndex].s;
+};
+
+TextProperty.prototype.buildFinalText = function (text) {
+  var charactersArray = [];
+  var i = 0;
+  var len = text.length;
+  var charCode;
+  var secondCharCode;
+  var shouldCombine = false;
+  var shouldCombineNext = false;
+  var currentChars = '';
+  while (i < len) {
+    shouldCombine = shouldCombineNext;
+    shouldCombineNext = false;
+    charCode = text.charCodeAt(i);
+    currentChars = text.charAt(i);
+    if (FontManager.isCombinedCharacter(charCode)) {
+      shouldCombine = true;
+      // It's a potential surrogate pair (this is the High surrogate)
+    } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+      if (FontManager.isRegionalFlag(text, i)) {
+        currentChars = text.substr(i, 14);
+      } else {
+        secondCharCode = text.charCodeAt(i + 1);
+        // It's a surrogate pair (this is the Low surrogate)
+        if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
+          if (FontManager.isModifier(charCode, secondCharCode)) {
+            currentChars = text.substr(i, 2);
+            shouldCombine = true;
+          } else if (FontManager.isFlagEmoji(text.substr(i, 4))) {
+            currentChars = text.substr(i, 4);
+          } else {
+            currentChars = text.substr(i, 2);
+          }
+        }
+      }
+    } else if (charCode > 0xDBFF) {
+      secondCharCode = text.charCodeAt(i + 1);
+      if (FontManager.isVariationSelector(charCode)) {
+        shouldCombine = true;
+      }
+    } else if (FontManager.isZeroWidthJoiner(charCode)) {
+      shouldCombine = true;
+      shouldCombineNext = true;
+    }
+    if (shouldCombine) {
+      charactersArray[charactersArray.length - 1] += currentChars;
+      shouldCombine = false;
+    } else {
+      charactersArray.push(currentChars);
+    }
+    i += currentChars.length;
+  }
+  return charactersArray;
+};
+
+TextProperty.prototype.completeTextData = function (documentData) {
+  documentData.__complete = true;
+  var fontManager = this.elem.globalData.fontManager;
+  var data = this.data;
+  var letters = [];
+  var i; var
+    len;
+  var newLineFlag; var index = 0; var
+    val;
+  var anchorGrouping = data.m.g;
+  var currentSize = 0; var currentPos = 0; var currentLine = 0; var
+    lineWidths = [];
+  var lineWidth = 0;
+  var maxLineWidth = 0;
+  var j; var
+    jLen;
+  var fontData = fontManager.getFontByName(documentData.f);
+  var charData; var
+    cLength = 0;
+
+  var fontProps = getFontProperties(fontData);
+  documentData.fWeight = fontProps.weight;
+  documentData.fStyle = fontProps.style;
+  documentData.finalSize = documentData.s;
+  documentData.finalText = this.buildFinalText(documentData.t);
+  len = documentData.finalText.length;
+  documentData.finalLineHeight = documentData.lh;
+  var trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+  var charCode;
+  if (documentData.sz) {
+    var flag = true;
+    var boxWidth = documentData.sz[0];
+    var boxHeight = documentData.sz[1];
+    var currentHeight; var
+      finalText;
+    while (flag) {
+      finalText = this.buildFinalText(documentData.t);
+      currentHeight = 0;
+      lineWidth = 0;
+      len = finalText.length;
+      trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+      var lastSpaceIndex = -1;
+      for (i = 0; i < len; i += 1) {
+        charCode = finalText[i].charCodeAt(0);
+        newLineFlag = false;
+        if (finalText[i] === ' ') {
+          lastSpaceIndex = i;
+        } else if (charCode === 13 || charCode === 3) {
+          lineWidth = 0;
+          newLineFlag = true;
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+        }
+        if (fontManager.chars) {
+          charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
+          cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+        } else {
+          // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
+          cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
+        }
+        if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
+          if (lastSpaceIndex === -1) {
+            len += 1;
+          } else {
+            i = lastSpaceIndex;
+          }
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+          finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+          // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
+          lastSpaceIndex = -1;
+          lineWidth = 0;
+        } else {
+          lineWidth += cLength;
+          lineWidth += trackingOffset;
+        }
+      }
+      currentHeight += (fontData.ascent * documentData.finalSize) / 100;
+      if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
+        documentData.finalSize -= 1;
+        documentData.finalLineHeight = (documentData.finalSize * documentData.lh) / documentData.s;
+      } else {
+        documentData.finalText = finalText;
+        len = documentData.finalText.length;
+        flag = false;
+      }
+    }
+  }
+  lineWidth = -trackingOffset;
+  cLength = 0;
+  var uncollapsedSpaces = 0;
+  var currentChar;
+  for (i = 0; i < len; i += 1) {
+    newLineFlag = false;
+    currentChar = documentData.finalText[i];
+    charCode = currentChar.charCodeAt(0);
+    if (charCode === 13 || charCode === 3) {
+      uncollapsedSpaces = 0;
+      lineWidths.push(lineWidth);
+      maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+      lineWidth = -2 * trackingOffset;
+      val = '';
+      newLineFlag = true;
+      currentLine += 1;
+    } else {
+      val = currentChar;
+    }
+    if (fontManager.chars) {
+      charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
+      cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+    } else {
+      // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
+      // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
+      cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
+    }
+
+    //
+    if (currentChar === ' ') {
+      uncollapsedSpaces += cLength + trackingOffset;
+    } else {
+      lineWidth += cLength + trackingOffset + uncollapsedSpaces;
+      uncollapsedSpaces = 0;
+    }
+    letters.push({
+      l: cLength, an: cLength, add: currentSize, n: newLineFlag, anIndexes: [], val: val, line: currentLine, animatorJustifyOffset: 0,
+    });
+    if (anchorGrouping == 2) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || val === ' ' || i === len - 1) {
+        if (val === '' || val === ' ') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        index += 1;
+        currentSize = 0;
+      }
+    } else if (anchorGrouping == 3) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || i === len - 1) {
+        if (val === '') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        currentSize = 0;
+        index += 1;
+      }
+    } else {
+      letters[index].ind = index;
+      letters[index].extra = 0;
+      index += 1;
+    }
+  }
+  documentData.l = letters;
+  maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+  lineWidths.push(lineWidth);
+  if (documentData.sz) {
+    documentData.boxWidth = documentData.sz[0];
+    documentData.justifyOffset = 0;
+  } else {
+    documentData.boxWidth = maxLineWidth;
+    switch (documentData.j) {
+      case 1:
+        documentData.justifyOffset = -documentData.boxWidth;
+        break;
+      case 2:
+        documentData.justifyOffset = -documentData.boxWidth / 2;
+        break;
+      default:
+        documentData.justifyOffset = 0;
+    }
+  }
+  documentData.lineWidths = lineWidths;
+
+  var animators = data.a; var animatorData; var
+    letterData;
+  jLen = animators.length;
+  var based; var ind; var
+    indexes = [];
+  for (j = 0; j < jLen; j += 1) {
+    animatorData = animators[j];
+    if (animatorData.a.sc) {
+      documentData.strokeColorAnim = true;
+    }
+    if (animatorData.a.sw) {
+      documentData.strokeWidthAnim = true;
+    }
+    if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
+      documentData.fillColorAnim = true;
+    }
+    ind = 0;
+    based = animatorData.s.b;
+    for (i = 0; i < len; i += 1) {
+      letterData = letters[i];
+      letterData.anIndexes[j] = ind;
+      if ((based == 1 && letterData.val !== '') || (based == 2 && letterData.val !== '' && letterData.val !== ' ') || (based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1)) || (based == 4 && (letterData.n || i == len - 1))) { // eslint-disable-line eqeqeq
+        if (animatorData.s.rn === 1) {
+          indexes.push(ind);
+        }
+        ind += 1;
+      }
+    }
+    data.a[j].s.totalChars = ind;
+    var currentInd = -1; var
+      newInd;
+    if (animatorData.s.rn === 1) {
+      for (i = 0; i < len; i += 1) {
+        letterData = letters[i];
+        if (currentInd != letterData.anIndexes[j]) { // eslint-disable-line eqeqeq
+          currentInd = letterData.anIndexes[j];
+          newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
+        }
+        letterData.anIndexes[j] = newInd;
+      }
+    }
+  }
+  documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
+  documentData.ls = documentData.ls || 0;
+  documentData.ascent = (fontData.ascent * documentData.finalSize) / 100;
+};
+
+TextProperty.prototype.updateDocumentData = function (newData, index) {
+  index = index === undefined ? this.keysIndex : index;
+  var dData = this.copyData({}, this.data.d.k[index].s);
+  dData = this.copyData(dData, newData);
+  this.data.d.k[index].s = dData;
+  this.recalculate(index);
+  this.setCurrentData(dData);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.recalculate = function (index) {
+  var dData = this.data.d.k[index].s;
+  dData.__complete = false;
+  this.keysIndex = 0;
+  this._isFirstFrame = true;
+  this.getValue(dData);
+};
+
+TextProperty.prototype.canResizeFont = function (_canResize) {
+  this.canResize = _canResize;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
+  this.minimumFontSize = Math.floor(_fontValue) || 1;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+const TextSelectorProp = (function () {
+  var max = Math.max;
+  var min = Math.min;
+  var floor = Math.floor;
+
+  function TextSelectorPropFactory(elem, data) {
+    this._currentTextLength = -1;
+    this.k = false;
+    this.data = data;
+    this.elem = elem;
+    this.comp = elem.comp;
+    this.finalS = 0;
+    this.finalE = 0;
+    this.initDynamicPropertyContainer(elem);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: 0 }, 0, 0, this);
+    if ('e' in data) {
+      this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
+    } else {
+      this.e = { v: 100 };
+    }
+    this.o = PropertyFactory.getProp(elem, data.o || { k: 0 }, 0, 0, this);
+    this.xe = PropertyFactory.getProp(elem, data.xe || { k: 0 }, 0, 0, this);
+    this.ne = PropertyFactory.getProp(elem, data.ne || { k: 0 }, 0, 0, this);
+    this.sm = PropertyFactory.getProp(elem, data.sm || { k: 100 }, 0, 0, this);
+    this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
+    if (!this.dynamicProperties.length) {
+      this.getValue();
+    }
+  }
+
+  TextSelectorPropFactory.prototype = {
+    getMult: function (ind) {
+      if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
+        this.getValue();
+      }
+      var x1 = 0;
+      var y1 = 0;
+      var x2 = 1;
+      var y2 = 1;
+      if (this.ne.v > 0) {
+        x1 = this.ne.v / 100.0;
+      } else {
+        y1 = -this.ne.v / 100.0;
+      }
+      if (this.xe.v > 0) {
+        x2 = 1.0 - this.xe.v / 100.0;
+      } else {
+        y2 = 1.0 + this.xe.v / 100.0;
+      }
+      var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
+
+      var mult = 0;
+      var s = this.finalS;
+      var e = this.finalE;
+      var type = this.data.sh;
+      if (type === 2) {
+        if (e === s) {
+          mult = ind >= e ? 1 : 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+        mult = easer(mult);
+      } else if (type === 3) {
+        if (e === s) {
+          mult = ind >= e ? 0 : 1;
+        } else {
+          mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+
+        mult = easer(mult);
+      } else if (type === 4) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+          if (mult < 0.5) {
+            mult *= 2;
+          } else {
+            mult = 1 - 2 * (mult - 0.5);
+          }
+        }
+        mult = easer(mult);
+      } else if (type === 5) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          var tot = e - s;
+          /* ind += 0.5;
+                    mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          var x = -tot / 2 + ind;
+          var a = tot / 2;
+          mult = Math.sqrt(1 - (x * x) / (a * a));
+        }
+        mult = easer(mult);
+      } else if (type === 6) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; // eslint-disable-line
+        }
+        mult = easer(mult);
+      } else {
+        if (ind >= floor(s)) {
+          if (ind - s < 0) {
+            mult = max(0, min(min(e, 1) - (s - ind), 1));
+          } else {
+            mult = max(0, min(e - ind, 1));
+          }
+        }
+        mult = easer(mult);
+      }
+      // Smoothness implementation.
+      // The smoothness represents a reduced range of the original [0; 1] range.
+      // if smoothness is 25%, the new range will be [0.375; 0.625]
+      // Steps are:
+      // - find the lower value of the new range (threshold)
+      // - if multiplier is smaller than that value, floor it to 0
+      // - if it is larger,
+      //     - subtract the threshold
+      //     - divide it by the smoothness (this will return the range to [0; 1])
+      // Note: If it doesn't work on some scenarios, consider applying it before the easer.
+      if (this.sm.v !== 100) {
+        var smoothness = this.sm.v * 0.01;
+        if (smoothness === 0) {
+          smoothness = 0.00000001;
+        }
+        var threshold = 0.5 - smoothness * 0.5;
+        if (mult < threshold) {
+          mult = 0;
+        } else {
+          mult = (mult - threshold) / smoothness;
+          if (mult > 1) {
+            mult = 1;
+          }
+        }
+      }
+      return mult * this.a.v;
+    },
+    getValue: function (newCharsFlag) {
+      this.iterateDynamicProperties();
+      this._mdf = newCharsFlag || this._mdf;
+      this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
+      if (newCharsFlag && this.data.r === 2) {
+        this.e.v = this._currentTextLength;
+      }
+      var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
+      var o = this.o.v / divisor;
+      var s = this.s.v / divisor + o;
+      var e = (this.e.v / divisor) + o;
+      if (s > e) {
+        var _s = s;
+        s = e;
+        e = _s;
+      }
+      this.finalS = s;
+      this.finalE = e;
+    },
+  };
+  extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
+
+  function getTextSelectorProp(elem, data, arr) {
+    return new TextSelectorPropFactory(elem, data, arr);
+  }
+
+  return {
+    getTextSelectorProp: getTextSelectorProp,
+  };
+}());
+
+function TextAnimatorDataProperty(elem, animatorProps, container) {
+  var defaultData = { propType: false };
+  var getProp = PropertyFactory.getProp;
+  var textAnimatorAnimatables = animatorProps.a;
+  this.a = {
+    r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData,
+    rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData,
+    ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData,
+    sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData,
+    sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData,
+    s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData,
+    a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData,
+    o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData,
+    p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData,
+    sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData,
+    sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData,
+    fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData,
+    fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData,
+    fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData,
+    fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData,
+    t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData,
+  };
+
+  this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container);
+  this.s.t = animatorProps.s.t;
+}
+
+function TextAnimatorProperty(textData, renderType, elem) {
+  this._isFirstFrame = true;
+  this._hasMaskedPath = false;
+  this._frameId = -1;
+  this._textData = textData;
+  this._renderType = renderType;
+  this._elem = elem;
+  this._animatorsData = createSizedArray(this._textData.a.length);
+  this._pathData = {};
+  this._moreOptions = {
+    alignment: {},
+  };
+  this.renderedLetters = [];
+  this.lettersChangedFlag = false;
+  this.initDynamicPropertyContainer(elem);
+}
+
+TextAnimatorProperty.prototype.searchProperties = function () {
+  var i;
+  var len = this._textData.a.length;
+  var animatorProps;
+  var getProp = PropertyFactory.getProp;
+  for (i = 0; i < len; i += 1) {
+    animatorProps = this._textData.a[i];
+    this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
+  }
+  if (this._textData.p && 'm' in this._textData.p) {
+    this._pathData = {
+      a: getProp(this._elem, this._textData.p.a, 0, 0, this),
+      f: getProp(this._elem, this._textData.p.f, 0, 0, this),
+      l: getProp(this._elem, this._textData.p.l, 0, 0, this),
+      r: getProp(this._elem, this._textData.p.r, 0, 0, this),
+      p: getProp(this._elem, this._textData.p.p, 0, 0, this),
+      m: this._elem.maskManager.getMaskProperty(this._textData.p.m),
+    };
+    this._hasMaskedPath = true;
+  } else {
+    this._hasMaskedPath = false;
+  }
+  this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
+};
+
+TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
+  this.lettersChangedFlag = lettersChangedFlag;
+  if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
+    return;
+  }
+  this._isFirstFrame = false;
+  var alignment = this._moreOptions.alignment.v;
+  var animators = this._animatorsData;
+  var textData = this._textData;
+  var matrixHelper = this.mHelper;
+  var renderType = this._renderType;
+  var renderedLettersCount = this.renderedLetters.length;
+  var xPos;
+  var yPos;
+  var i;
+  var len;
+  var letters = documentData.l;
+  var pathInfo;
+  var currentLength;
+  var currentPoint;
+  var segmentLength;
+  var flag;
+  var pointInd;
+  var segmentInd;
+  var prevPoint;
+  var points;
+  var segments;
+  var partialLength;
+  var totalLength;
+  var perc;
+  var tanAngle;
+  var mask;
+  if (this._hasMaskedPath) {
+    mask = this._pathData.m;
+    if (!this._pathData.n || this._pathData._mdf) {
+      var paths = mask.v;
+      if (this._pathData.r.v) {
+        paths = paths.reverse();
+      }
+      // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
+      pathInfo = {
+        tLength: 0,
+        segments: [],
+      };
+      len = paths._length - 1;
+      var bezierData;
+      totalLength = 0;
+      for (i = 0; i < len; i += 1) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[i + 1],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      i = len;
+      if (mask.v.c) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[0],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      this._pathData.pi = pathInfo;
+    }
+    pathInfo = this._pathData.pi;
+
+    currentLength = this._pathData.f.v;
+    segmentInd = 0;
+    pointInd = 1;
+    segmentLength = 0;
+    flag = true;
+    segments = pathInfo.segments;
+    if (currentLength < 0 && mask.v.c) {
+      if (pathInfo.tLength < Math.abs(currentLength)) {
+        currentLength = -Math.abs(currentLength) % pathInfo.tLength;
+      }
+      segmentInd = segments.length - 1;
+      points = segments[segmentInd].points;
+      pointInd = points.length - 1;
+      while (currentLength < 0) {
+        currentLength += points[pointInd].partialLength;
+        pointInd -= 1;
+        if (pointInd < 0) {
+          segmentInd -= 1;
+          points = segments[segmentInd].points;
+          pointInd = points.length - 1;
+        }
+      }
+    }
+    points = segments[segmentInd].points;
+    prevPoint = points[pointInd - 1];
+    currentPoint = points[pointInd];
+    partialLength = currentPoint.partialLength;
+  }
+
+  len = letters.length;
+  xPos = 0;
+  yPos = 0;
+  var yOff = documentData.finalSize * 1.2 * 0.714;
+  var firstLine = true;
+  var animatorProps;
+  var animatorSelector;
+  var j;
+  var jLen;
+  var letterValue;
+
+  jLen = animators.length;
+
+  var mult;
+  var ind = -1;
+  var offf;
+  var xPathPos;
+  var yPathPos;
+  var initPathPos = currentLength;
+  var initSegmentInd = segmentInd;
+  var initPointInd = pointInd;
+  var currentLine = -1;
+  var elemOpacity;
+  var sc;
+  var sw;
+  var fc;
+  var k;
+  var letterSw;
+  var letterSc;
+  var letterFc;
+  var letterM = '';
+  var letterP = this.defaultPropsArray;
+  var letterO;
+
+  //
+  if (documentData.j === 2 || documentData.j === 1) {
+    var animatorJustifyOffset = 0;
+    var animatorFirstCharOffset = 0;
+    var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
+    var lastIndex = 0;
+    var isNewLine = true;
+
+    for (i = 0; i < len; i += 1) {
+      if (letters[i].n) {
+        if (animatorJustifyOffset) {
+          animatorJustifyOffset += animatorFirstCharOffset;
+        }
+        while (lastIndex < i) {
+          letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+          lastIndex += 1;
+        }
+        animatorJustifyOffset = 0;
+        isNewLine = true;
+      } else {
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.t.propType) {
+            if (isNewLine && documentData.j === 2) {
+              animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
+            }
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
+            } else {
+              animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult;
+            }
+          }
+        }
+        isNewLine = false;
+      }
+    }
+    if (animatorJustifyOffset) {
+      animatorJustifyOffset += animatorFirstCharOffset;
+    }
+    while (lastIndex < i) {
+      letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+      lastIndex += 1;
+    }
+  }
+  //
+
+  for (i = 0; i < len; i += 1) {
+    matrixHelper.reset();
+    elemOpacity = 1;
+    if (letters[i].n) {
+      xPos = 0;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      currentLength = initPathPos;
+      firstLine = false;
+      if (this._hasMaskedPath) {
+        segmentInd = initSegmentInd;
+        pointInd = initPointInd;
+        points = segments[segmentInd].points;
+        prevPoint = points[pointInd - 1];
+        currentPoint = points[pointInd];
+        partialLength = currentPoint.partialLength;
+        segmentLength = 0;
+      }
+      letterM = '';
+      letterFc = '';
+      letterSw = '';
+      letterO = '';
+      letterP = this.defaultPropsArray;
+    } else {
+      if (this._hasMaskedPath) {
+        if (currentLine !== letters[i].line) {
+          switch (documentData.j) {
+            case 1:
+              currentLength += totalLength - documentData.lineWidths[letters[i].line];
+              break;
+            case 2:
+              currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
+              break;
+            default:
+              break;
+          }
+          currentLine = letters[i].line;
+        }
+        if (ind !== letters[i].ind) {
+          if (letters[ind]) {
+            currentLength += letters[ind].extra;
+          }
+          currentLength += letters[i].an / 2;
+          ind = letters[i].ind;
+        }
+        currentLength += (alignment[0] * letters[i].an) * 0.005;
+        var animatorOffset = 0;
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.p.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.p.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.p.v[0] * mult;
+            }
+          }
+          if (animatorProps.a.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.a.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.a.v[0] * mult;
+            }
+          }
+        }
+        flag = true;
+        // Force alignment only works with a single line for now
+        if (this._pathData.a.v) {
+          currentLength = letters[0].an * 0.5 + ((totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind) / (len - 1);
+          currentLength += this._pathData.f.v;
+        }
+        while (flag) {
+          if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
+            perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
+            xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
+            yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
+            matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, -(alignment[1] * yOff) * 0.01);
+            flag = false;
+          } else if (points) {
+            segmentLength += currentPoint.partialLength;
+            pointInd += 1;
+            if (pointInd >= points.length) {
+              pointInd = 0;
+              segmentInd += 1;
+              if (!segments[segmentInd]) {
+                if (mask.v.c) {
+                  pointInd = 0;
+                  segmentInd = 0;
+                  points = segments[segmentInd].points;
+                } else {
+                  segmentLength -= currentPoint.partialLength;
+                  points = null;
+                }
+              } else {
+                points = segments[segmentInd].points;
+              }
+            }
+            if (points) {
+              prevPoint = currentPoint;
+              currentPoint = points[pointInd];
+              partialLength = currentPoint.partialLength;
+            }
+          }
+        }
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+      } else {
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+
+        // Grouping alignment
+        matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, (-alignment[1] * yOff) * 0.01, 0);
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.t.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
+          if (xPos !== 0 || documentData.j !== 0) {
+            if (this._hasMaskedPath) {
+              if (mult.length) {
+                currentLength += animatorProps.t.v * mult[0];
+              } else {
+                currentLength += animatorProps.t.v * mult;
+              }
+            } else if (mult.length) {
+              xPos += animatorProps.t.v * mult[0];
+            } else {
+              xPos += animatorProps.t.v * mult;
+            }
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        sw = documentData.sw || 0;
+      }
+      if (documentData.strokeColorAnim) {
+        if (documentData.sc) {
+          sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
+        } else {
+          sc = [0, 0, 0];
+        }
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.a.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+
+          if (mult.length) {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.s.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (mult.length) {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult[0]), 1 + ((animatorProps.s.v[1] - 1) * mult[1]), 1);
+          } else {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult), 1 + ((animatorProps.s.v[1] - 1) * mult), 1);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        animatorSelector = animators[j].s;
+        mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+        if (animatorProps.sk.propType) {
+          if (mult.length) {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
+          } else {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
+          }
+        }
+        if (animatorProps.r.propType) {
+          if (mult.length) {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
+          } else {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult);
+          }
+        }
+        if (animatorProps.ry.propType) {
+          if (mult.length) {
+            matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
+          } else {
+            matrixHelper.rotateY(animatorProps.ry.v * mult);
+          }
+        }
+        if (animatorProps.rx.propType) {
+          if (mult.length) {
+            matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
+          } else {
+            matrixHelper.rotateX(animatorProps.rx.v * mult);
+          }
+        }
+        if (animatorProps.o.propType) {
+          if (mult.length) {
+            elemOpacity += ((animatorProps.o.v) * mult[0] - elemOpacity) * mult[0];
+          } else {
+            elemOpacity += ((animatorProps.o.v) * mult - elemOpacity) * mult;
+          }
+        }
+        if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
+          if (mult.length) {
+            sw += animatorProps.sw.v * mult[0];
+          } else {
+            sw += animatorProps.sw.v * mult;
+          }
+        }
+        if (documentData.strokeColorAnim && animatorProps.sc.propType) {
+          for (k = 0; k < 3; k += 1) {
+            if (mult.length) {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0];
+            } else {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult;
+            }
+          }
+        }
+        if (documentData.fillColorAnim && documentData.fc) {
+          if (animatorProps.fc.propType) {
+            for (k = 0; k < 3; k += 1) {
+              if (mult.length) {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0];
+              } else {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult;
+              }
+            }
+          }
+          if (animatorProps.fh.propType) {
+            if (mult.length) {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
+            } else {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult);
+            }
+          }
+          if (animatorProps.fs.propType) {
+            if (mult.length) {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
+            } else {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
+            }
+          }
+          if (animatorProps.fb.propType) {
+            if (mult.length) {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
+            } else {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult);
+            }
+          }
+        }
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+
+        if (animatorProps.p.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (this._hasMaskedPath) {
+            if (mult.length) {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
+            } else {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+            }
+          } else if (mult.length) {
+            matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        letterSw = sw < 0 ? 0 : sw;
+      }
+      if (documentData.strokeColorAnim) {
+        letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
+      }
+
+      if (this._hasMaskedPath) {
+        matrixHelper.translate(0, -documentData.ls);
+
+        matrixHelper.translate(0, (alignment[1] * yOff) * 0.01 + yPos, 0);
+        if (this._pathData.p.v) {
+          tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
+          var rot = (Math.atan(tanAngle) * 180) / Math.PI;
+          if (currentPoint.point[0] < prevPoint.point[0]) {
+            rot += 180;
+          }
+          matrixHelper.rotate((-rot * Math.PI) / 180);
+        }
+        matrixHelper.translate(xPathPos, yPathPos, 0);
+        currentLength -= (alignment[0] * letters[i].an) * 0.005;
+        if (letters[i + 1] && ind !== letters[i + 1].ind) {
+          currentLength += letters[i].an / 2;
+          currentLength += (documentData.tr * 0.001) * documentData.finalSize;
+        }
+      } else {
+        matrixHelper.translate(xPos, yPos, 0);
+
+        if (documentData.ps) {
+          // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
+          matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+        }
+        switch (documentData.j) {
+          case 1:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
+            break;
+          case 2:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
+            break;
+          default:
+            break;
+        }
+        matrixHelper.translate(0, -documentData.ls);
+        matrixHelper.translate(offf, 0, 0);
+        matrixHelper.translate((alignment[0] * letters[i].an) * 0.005, (alignment[1] * yOff) * 0.01, 0);
+        xPos += letters[i].l + (documentData.tr * 0.001) * documentData.finalSize;
+      }
+      if (renderType === 'html') {
+        letterM = matrixHelper.toCSS();
+      } else if (renderType === 'svg') {
+        letterM = matrixHelper.to2dCSS();
+      } else {
+        letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
+      }
+      letterO = elemOpacity;
+    }
+
+    if (renderedLettersCount <= i) {
+      letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
+      this.renderedLetters.push(letterValue);
+      renderedLettersCount += 1;
+      this.lettersChangedFlag = true;
+    } else {
+      letterValue = this.renderedLetters[i];
+      this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag;
+    }
+  }
+};
+
+TextAnimatorProperty.prototype.getValue = function () {
+  if (this._elem.globalData.frameId === this._frameId) {
+    return;
+  }
+  this._frameId = this._elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+TextAnimatorProperty.prototype.mHelper = new Matrix();
+TextAnimatorProperty.prototype.defaultPropsArray = [];
+extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
+
+function ITextElement() {
+}
+
+ITextElement.prototype.initElement = function (data, globalData, comp) {
+  this.lettersChangedFlag = true;
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.textProperty = new TextProperty(this, data.t, this.dynamicProperties);
+  this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this);
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+  this.initRenderable();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  this.createContent();
+  this.hide();
+  this.textAnimator.searchProperties(this.dynamicProperties);
+};
+
+ITextElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+};
+
+ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
+  var j;
+  var jLen = shapes.length;
+  var pathNodes;
+  var shapeStr = '';
+  for (j = 0; j < jLen; j += 1) {
+    if (shapes[j].ty === 'sh') {
+      pathNodes = shapes[j].ks.k;
+      shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
+    }
+  }
+  return shapeStr;
+};
+
+ITextElement.prototype.updateDocumentData = function (newData, index) {
+  this.textProperty.updateDocumentData(newData, index);
+};
+
+ITextElement.prototype.canResizeFont = function (_canResize) {
+  this.textProperty.canResizeFont(_canResize);
+};
+
+ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
+  this.textProperty.setMinimumFontSize(_fontSize);
+};
+
+ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
+  if (documentData.ps) {
+    matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+  }
+  matrixHelper.translate(0, -documentData.ls, 0);
+  switch (documentData.j) {
+    case 1:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
+      break;
+    case 2:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
+      break;
+    default:
+      break;
+  }
+  matrixHelper.translate(xPos, yPos, 0);
+};
+
+ITextElement.prototype.buildColor = function (colorData) {
+  return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
+};
+
+ITextElement.prototype.emptyProp = new LetterProps();
+
+ITextElement.prototype.destroy = function () {
+
+};
+
+ITextElement.prototype.validateText = function () {
+  if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
+    this.buildNewText();
+    this.textProperty._isFirstFrame = false;
+    this.textProperty._mdf = false;
+  }
+};
+
+var emptyShapeData = {
+  shapes: [],
+};
+
+function SVGTextLottieElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.renderType = 'svg';
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
+
+SVGTextLottieElement.prototype.createContent = function () {
+  if (this.data.singleShape && !this.globalData.fontManager.chars) {
+    this.textContainer = createNS('text');
+  }
+};
+
+SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
+  var i = 0;
+  var len = textArray.length;
+  var textContents = [];
+  var currentTextContent = '';
+  while (i < len) {
+    if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
+      textContents.push(currentTextContent);
+      currentTextContent = '';
+    } else {
+      currentTextContent += textArray[i];
+    }
+    i += 1;
+  }
+  textContents.push(currentTextContent);
+  return textContents;
+};
+
+SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
+  // data should probably be cloned to apply scale separately to each instance of a text on different layers
+  // but since text internal content gets only rendered once and then it's never rerendered,
+  // it's probably safe not to clone data and reuse always the same instance even if the object is mutated.
+  // Avoiding cloning is preferred since cloning each character shape data is expensive
+  if (data.shapes && data.shapes.length) {
+    var shape = data.shapes[0];
+    if (shape.it) {
+      var shapeItem = shape.it[shape.it.length - 1];
+      if (shapeItem.s) {
+        shapeItem.s.k[0] = scale;
+        shapeItem.s.k[1] = scale;
+      }
+    }
+  }
+  return data;
+};
+
+SVGTextLottieElement.prototype.buildNewText = function () {
+  this.addDynamicProperty(this);
+  var i;
+  var len;
+
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
+  if (documentData.fc) {
+    this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
+  } else {
+    this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
+  }
+  if (documentData.sc) {
+    this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
+    this.layerElement.setAttribute('stroke-width', documentData.sw);
+  }
+  this.layerElement.setAttribute('font-size', documentData.finalSize);
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (fontData.fClass) {
+    this.layerElement.setAttribute('class', fontData.fClass);
+  } else {
+    this.layerElement.setAttribute('font-family', fontData.fFamily);
+    var fWeight = documentData.fWeight;
+    var fStyle = documentData.fStyle;
+    this.layerElement.setAttribute('font-style', fStyle);
+    this.layerElement.setAttribute('font-weight', fWeight);
+  }
+  this.layerElement.setAttribute('aria-label', documentData.t);
+
+  var letters = documentData.l || [];
+  var usesGlyphs = !!this.globalData.fontManager.chars;
+  len = letters.length;
+
+  var tSpan;
+  var matrixHelper = this.mHelper;
+  var shapeStr = '';
+  var singleShape = this.data.singleShape;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  if (singleShape && !usesGlyphs && !documentData.sz) {
+    var tElement = this.textContainer;
+    var justify = 'start';
+    switch (documentData.j) {
+      case 1:
+        justify = 'end';
+        break;
+      case 2:
+        justify = 'middle';
+        break;
+      default:
+        justify = 'start';
+        break;
+    }
+    tElement.setAttribute('text-anchor', justify);
+    tElement.setAttribute('letter-spacing', trackingOffset);
+    var textContent = this.buildTextContents(documentData.finalText);
+    len = textContent.length;
+    yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
+    for (i = 0; i < len; i += 1) {
+      tSpan = this.textSpans[i].span || createNS('tspan');
+      tSpan.textContent = textContent[i];
+      tSpan.setAttribute('x', 0);
+      tSpan.setAttribute('y', yPos);
+      tSpan.style.display = 'inherit';
+      tElement.appendChild(tSpan);
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          glyph: null,
+        };
+      }
+      this.textSpans[i].span = tSpan;
+      yPos += documentData.finalLineHeight;
+    }
+
+    this.layerElement.appendChild(tElement);
+  } else {
+    var cachedSpansLength = this.textSpans.length;
+    var charData;
+    for (i = 0; i < len; i += 1) {
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          childSpan: null,
+          glyph: null,
+        };
+      }
+      if (!usesGlyphs || !singleShape || i === 0) {
+        tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
+        if (cachedSpansLength <= i) {
+          tSpan.setAttribute('stroke-linecap', 'butt');
+          tSpan.setAttribute('stroke-linejoin', 'round');
+          tSpan.setAttribute('stroke-miterlimit', '4');
+          this.textSpans[i].span = tSpan;
+          if (usesGlyphs) {
+            var childSpan = createNS('g');
+            tSpan.appendChild(childSpan);
+            this.textSpans[i].childSpan = childSpan;
+          }
+          this.textSpans[i].span = tSpan;
+          this.layerElement.appendChild(tSpan);
+        }
+        tSpan.style.display = 'inherit';
+      }
+
+      matrixHelper.reset();
+      if (singleShape) {
+        if (letters[i].n) {
+          xPos = -trackingOffset;
+          yPos += documentData.yOffset;
+          yPos += firstLine ? 1 : 0;
+          firstLine = false;
+        }
+        this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+        xPos += letters[i].l || 0;
+        // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
+        xPos += trackingOffset;
+      }
+      if (usesGlyphs) {
+        charData = this.globalData.fontManager.getCharData(
+          documentData.finalText[i],
+          fontData.fStyle,
+          this.globalData.fontManager.getFontByName(documentData.f).fFamily
+        );
+        var glyphElement;
+        // t === 1 means the character has been replaced with an animated shaped
+        if (charData.t === 1) {
+          glyphElement = new SVGCompElement(charData.data, this.globalData, this);
+        } else {
+          var data = emptyShapeData;
+          if (charData.data && charData.data.shapes) {
+            data = this.buildShapeData(charData.data, documentData.finalSize);
+          }
+          glyphElement = new SVGShapeElement(data, this.globalData, this);
+        }
+        if (this.textSpans[i].glyph) {
+          var glyph = this.textSpans[i].glyph;
+          this.textSpans[i].childSpan.removeChild(glyph.layerElement);
+          glyph.destroy();
+        }
+        this.textSpans[i].glyph = glyphElement;
+        glyphElement._debug = true;
+        glyphElement.prepareFrame(0);
+        glyphElement.renderFrame();
+        this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+        // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+        // this might have issues with strokes and might need a different solution
+        if (charData.t === 1) {
+          this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
+        }
+      } else {
+        if (singleShape) {
+          tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
+        }
+        tSpan.textContent = letters[i].val;
+        tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      }
+      //
+    }
+    if (singleShape && tSpan) {
+      tSpan.setAttribute('d', shapeStr);
+    }
+  }
+  while (i < this.textSpans.length) {
+    this.textSpans[i].span.style.display = 'none';
+    i += 1;
+  }
+
+  this._sizeChanged = true;
+};
+
+SVGTextLottieElement.prototype.sourceRectAtTime = function () {
+  this.prepareFrame(this.comp.renderedFrame - this.data.st);
+  this.renderInnerContent();
+  if (this._sizeChanged) {
+    this._sizeChanged = false;
+    var textBox = this.layerElement.getBBox();
+    this.bbox = {
+      top: textBox.y,
+      left: textBox.x,
+      width: textBox.width,
+      height: textBox.height,
+    };
+  }
+  return this.bbox;
+};
+
+SVGTextLottieElement.prototype.getValue = function () {
+  var i;
+  var len = this.textSpans.length;
+  var glyphElement;
+  this.renderedFrame = this.comp.renderedFrame;
+  for (i = 0; i < len; i += 1) {
+    glyphElement = this.textSpans[i].glyph;
+    if (glyphElement) {
+      glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
+      if (glyphElement._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+SVGTextLottieElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  if (!this.data.singleShape || this._mdf) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+    if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
+      this._sizeChanged = true;
+      var i;
+      var len;
+      var renderedLetters = this.textAnimator.renderedLetters;
+
+      var letters = this.textProperty.currentData.l;
+
+      len = letters.length;
+      var renderedLetter;
+      var textSpan;
+      var glyphElement;
+      for (i = 0; i < len; i += 1) {
+        if (!letters[i].n) {
+          renderedLetter = renderedLetters[i];
+          textSpan = this.textSpans[i].span;
+          glyphElement = this.textSpans[i].glyph;
+          if (glyphElement) {
+            glyphElement.renderFrame();
+          }
+          if (renderedLetter._mdf.m) {
+            textSpan.setAttribute('transform', renderedLetter.m);
+          }
+          if (renderedLetter._mdf.o) {
+            textSpan.setAttribute('opacity', renderedLetter.o);
+          }
+          if (renderedLetter._mdf.sw) {
+            textSpan.setAttribute('stroke-width', renderedLetter.sw);
+          }
+          if (renderedLetter._mdf.sc) {
+            textSpan.setAttribute('stroke', renderedLetter.sc);
+          }
+          if (renderedLetter._mdf.fc) {
+            textSpan.setAttribute('fill', renderedLetter.fc);
+          }
+        }
+      }
+    }
+  }
+};
+
+function ISolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([IImageElement], ISolidElement);
+
+ISolidElement.prototype.createContent = function () {
+  var rect = createNS('rect');
+  /// /rect.style.width = this.data.sw;
+  /// /rect.style.height = this.data.sh;
+  /// /rect.style.fill = this.data.sc;
+  rect.setAttribute('width', this.data.sw);
+  rect.setAttribute('height', this.data.sh);
+  rect.setAttribute('fill', this.data.sc);
+  this.layerElement.appendChild(rect);
+};
+
+function NullElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initFrame();
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+}
+
+NullElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+NullElement.prototype.renderFrame = function () {
+};
+
+NullElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+NullElement.prototype.destroy = function () {
+};
+
+NullElement.prototype.sourceRectAtTime = function () {
+};
+
+NullElement.prototype.hide = function () {
+};
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
+
+function SVGRendererBase() {
+}
+
+extendPrototype([BaseRenderer], SVGRendererBase);
+
+SVGRendererBase.prototype.createNull = function (data) {
+  return new NullElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createShape = function (data) {
+  return new SVGShapeElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createText = function (data) {
+  return new SVGTextLottieElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createImage = function (data) {
+  return new IImageElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createSolid = function (data) {
+  return new ISolidElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.configAnimation = function (animData) {
+  this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+  this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+  if (this.renderConfig.viewBoxSize) {
+    this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
+  } else {
+    this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
+  }
+
+  if (!this.renderConfig.viewBoxOnly) {
+    this.svgElement.setAttribute('width', animData.w);
+    this.svgElement.setAttribute('height', animData.h);
+    this.svgElement.style.width = '100%';
+    this.svgElement.style.height = '100%';
+    this.svgElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
+  }
+  if (this.renderConfig.width) {
+    this.svgElement.setAttribute('width', this.renderConfig.width);
+  }
+  if (this.renderConfig.height) {
+    this.svgElement.setAttribute('height', this.renderConfig.height);
+  }
+  if (this.renderConfig.className) {
+    this.svgElement.setAttribute('class', this.renderConfig.className);
+  }
+  if (this.renderConfig.id) {
+    this.svgElement.setAttribute('id', this.renderConfig.id);
+  }
+  if (this.renderConfig.focusable !== undefined) {
+    this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
+  }
+  this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+  // this.layerElement.style.transform = 'translate3d(0,0,0)';
+  // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
+  this.animationItem.wrapper.appendChild(this.svgElement);
+  // Mask animation
+  var defs = this.globalData.defs;
+
+  this.setupGlobalData(animData, defs);
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.data = animData;
+
+  var maskElement = createNS('clipPath');
+  var rect = createNS('rect');
+  rect.setAttribute('width', animData.w);
+  rect.setAttribute('height', animData.h);
+  rect.setAttribute('x', 0);
+  rect.setAttribute('y', 0);
+  var maskId = createElementID();
+  maskElement.setAttribute('id', maskId);
+  maskElement.appendChild(rect);
+  this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')');
+
+  defs.appendChild(maskElement);
+  this.layers = animData.layers;
+  this.elements = createSizedArray(animData.layers.length);
+};
+
+SVGRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.layerElement = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+SVGRendererBase.prototype.updateContainerSize = function () {
+};
+
+SVGRendererBase.prototype.findIndexByInd = function (ind) {
+  var i = 0;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.layers[i].ind === ind) {
+      return i;
+    }
+  }
+  return -1;
+};
+
+SVGRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  elements[pos] = true;
+  var element = this.createItem(this.layers[pos]);
+
+  elements[pos] = element;
+  if (getExpressionsPlugin()) {
+    if (this.layers[pos].ty === 0) {
+      this.globalData.projectInterface.registerComposition(element);
+    }
+    element.initExpressions();
+  }
+  this.appendElementInPos(element, pos);
+  if (this.layers[pos].tt) {
+    var elementIndex = ('tp' in this.layers[pos])
+      ? this.findIndexByInd(this.layers[pos].tp)
+      : pos - 1;
+    if (elementIndex === -1) {
+      return;
+    }
+    if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
+      this.buildItem(elementIndex);
+      this.addPendingElement(element);
+    } else {
+      var matteElement = elements[elementIndex];
+      var matteMask = matteElement.getMatte(this.layers[pos].tt);
+      element.setMatte(matteMask);
+    }
+  }
+};
+
+SVGRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+    if (element.data.tt) {
+      var i = 0;
+      var len = this.elements.length;
+      while (i < len) {
+        if (this.elements[i] === element) {
+          var elementIndex = 'tp' in element.data
+            ? this.findIndexByInd(element.data.tp)
+            : i - 1;
+          var matteElement = this.elements[elementIndex];
+          var matteMask = matteElement.getMatte(this.layers[i].tt);
+          element.setMatte(matteMask);
+          break;
+        }
+        i += 1;
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.renderFrame = function (num) {
+  if (this.renderedFrame === num || this.destroyed) {
+    return;
+  }
+  if (num === null) {
+    num = this.renderedFrame;
+  } else {
+    this.renderedFrame = num;
+  }
+  // console.log('-------');
+  // console.log('FRAME ',num);
+  this.globalData.frameNum = num;
+  this.globalData.frameId += 1;
+  this.globalData.projectInterface.currentFrame = num;
+  this.globalData._mdf = false;
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    for (i = 0; i < len; i += 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
+  var newElement = element.getBaseElement();
+  if (!newElement) {
+    return;
+  }
+  var i = 0;
+  var nextElement;
+  while (i < pos) {
+    if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
+      nextElement = this.elements[i].getBaseElement();
+    }
+    i += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(newElement, nextElement);
+  } else {
+    this.layerElement.appendChild(newElement);
+  }
+};
+
+SVGRendererBase.prototype.hide = function () {
+  this.layerElement.style.display = 'none';
+};
+
+SVGRendererBase.prototype.show = function () {
+  this.layerElement.style.display = 'block';
+};
+
+function ICompElement() {}
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
+
+ICompElement.prototype.initElement = function (data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initTransform(data, globalData, comp);
+  this.initRenderable();
+  this.initHierarchy();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  if (this.data.xt || !globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+  this.hide();
+};
+
+/* ICompElement.prototype.hide = function(){
+    if(!this.hidden){
+        this.hideElement();
+        var i,len = this.elements.length;
+        for( i = 0; i < len; i+=1 ){
+            if(this.elements[i]){
+                this.elements[i].hide();
+            }
+        }
+    }
+}; */
+
+ICompElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+  if (!this.isInRange && !this.data.xt) {
+    return;
+  }
+
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    if (timeRemapped === this.data.op) {
+      timeRemapped = this.data.op - 1;
+    }
+    this.renderedFrame = timeRemapped;
+  } else {
+    this.renderedFrame = num / this.data.sr;
+  }
+  var i;
+  var len = this.elements.length;
+  if (!this.completeLayers) {
+    this.checkLayers(this.renderedFrame);
+  }
+  // This iteration needs to be backwards because of how expressions connect between each other
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
+      if (this.elements[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+ICompElement.prototype.renderInnerContent = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+ICompElement.prototype.setElements = function (elems) {
+  this.elements = elems;
+};
+
+ICompElement.prototype.getElements = function () {
+  return this.elements;
+};
+
+ICompElement.prototype.destroyElements = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+};
+
+ICompElement.prototype.destroy = function () {
+  this.destroyElements();
+  this.destroyBaseElement();
+};
+
+function SVGCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = true;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
+
+SVGCompElement.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function SVGRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.layers = null;
+  this.renderedFrame = -1;
+  this.svgElement = createNS('svg');
+  var ariaLabel = '';
+  if (config && config.title) {
+    var titleElement = createNS('title');
+    var titleId = createElementID();
+    titleElement.setAttribute('id', titleId);
+    titleElement.textContent = config.title;
+    this.svgElement.appendChild(titleElement);
+    ariaLabel += titleId;
+  }
+  if (config && config.description) {
+    var descElement = createNS('desc');
+    var descId = createElementID();
+    descElement.setAttribute('id', descId);
+    descElement.textContent = config.description;
+    this.svgElement.appendChild(descElement);
+    ariaLabel += ' ' + descId;
+  }
+  if (ariaLabel) {
+    this.svgElement.setAttribute('aria-labelledby', ariaLabel);
+  }
+  var defs = createNS('defs');
+  this.svgElement.appendChild(defs);
+  var maskElement = createNS('g');
+  this.svgElement.appendChild(maskElement);
+  this.layerElement = maskElement;
+  this.renderConfig = {
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    hideOnTransparent: !((config && config.hideOnTransparent === false)),
+    viewBoxOnly: (config && config.viewBoxOnly) || false,
+    viewBoxSize: (config && config.viewBoxSize) || false,
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    focusable: config && config.focusable,
+    filterSize: {
+      width: (config && config.filterSize && config.filterSize.width) || '100%',
+      height: (config && config.filterSize && config.filterSize.height) || '100%',
+      x: (config && config.filterSize && config.filterSize.x) || '0%',
+      y: (config && config.filterSize && config.filterSize.y) || '0%',
+    },
+    width: (config && config.width),
+    height: (config && config.height),
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+
+  this.globalData = {
+    _mdf: false,
+    frameNum: -1,
+    defs: defs,
+    renderConfig: this.renderConfig,
+  };
+  this.elements = [];
+  this.pendingElements = [];
+  this.destroyed = false;
+  this.rendererType = 'svg';
+}
+
+extendPrototype([SVGRendererBase], SVGRenderer);
+
+SVGRenderer.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function ShapeTransformManager() {
+  this.sequences = {};
+  this.sequenceList = [];
+  this.transform_key_count = 0;
+}
+
+ShapeTransformManager.prototype = {
+  addTransformSequence: function (transforms) {
+    var i;
+    var len = transforms.length;
+    var key = '_';
+    for (i = 0; i < len; i += 1) {
+      key += transforms[i].transform.key + '_';
+    }
+    var sequence = this.sequences[key];
+    if (!sequence) {
+      sequence = {
+        transforms: [].concat(transforms),
+        finalTransform: new Matrix(),
+        _mdf: false,
+      };
+      this.sequences[key] = sequence;
+      this.sequenceList.push(sequence);
+    }
+    return sequence;
+  },
+  processSequence: function (sequence, isFirstFrame) {
+    var i = 0;
+    var len = sequence.transforms.length;
+    var _mdf = isFirstFrame;
+    while (i < len && !isFirstFrame) {
+      if (sequence.transforms[i].transform.mProps._mdf) {
+        _mdf = true;
+        break;
+      }
+      i += 1;
+    }
+    if (_mdf) {
+      sequence.finalTransform.reset();
+      for (i = len - 1; i >= 0; i -= 1) {
+        sequence.finalTransform.multiply(sequence.transforms[i].transform.mProps.v);
+      }
+    }
+    sequence._mdf = _mdf;
+  },
+  processSequences: function (isFirstFrame) {
+    var i;
+    var len = this.sequenceList.length;
+    for (i = 0; i < len; i += 1) {
+      this.processSequence(this.sequenceList[i], isFirstFrame);
+    }
+  },
+  getNewKey: function () {
+    this.transform_key_count += 1;
+    return '_' + this.transform_key_count;
+  },
+};
+
+var lumaLoader = (function () {
+  var id = '__lottie_element_luma_buffer';
+  var lumaBuffer = null;
+  var lumaBufferCtx = null;
+  var svg = null;
+
+  // This alternate solution has a slight delay before the filter is applied, resulting in a flicker on the first frame.
+  // Keeping this here for reference, and in the future, if offscreen canvas supports url filters, this can be used.
+  // For now, neither of them work for offscreen canvas, so canvas workers can't support the luma track matte mask.
+  // Naming it solution 2 to mark the extra comment lines.
+  /*
+  var svgString = [
+    '<svg xmlns="http://www.w3.org/2000/svg">',
+    '<filter id="' + id + '">',
+    '<feColorMatrix type="matrix" color-interpolation-filters="sRGB" values="',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0',
+    '"/>',
+    '</filter>',
+    '</svg>',
+  ].join('');
+  var blob = new Blob([svgString], { type: 'image/svg+xml' });
+  var url = URL.createObjectURL(blob);
+  */
+
+  function createLumaSvgFilter() {
+    var _svg = createNS('svg');
+    var fil = createNS('filter');
+    var matrix = createNS('feColorMatrix');
+    fil.setAttribute('id', id);
+    matrix.setAttribute('type', 'matrix');
+    matrix.setAttribute('color-interpolation-filters', 'sRGB');
+    matrix.setAttribute('values', '0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0');
+    fil.appendChild(matrix);
+    _svg.appendChild(fil);
+    _svg.setAttribute('id', id + '_svg');
+    if (featureSupport.svgLumaHidden) {
+      _svg.style.display = 'none';
+    }
+    return _svg;
+  }
+
+  function loadLuma() {
+    if (!lumaBuffer) {
+      svg = createLumaSvgFilter();
+      document.body.appendChild(svg);
+      lumaBuffer = createTag('canvas');
+      lumaBufferCtx = lumaBuffer.getContext('2d');
+      // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
+      lumaBufferCtx.filter = 'url(#' + id + ')';
+      lumaBufferCtx.fillStyle = 'rgba(0,0,0,0)';
+      lumaBufferCtx.fillRect(0, 0, 1, 1);
+    }
+  }
+
+  function getLuma(canvas) {
+    if (!lumaBuffer) {
+      loadLuma();
+    }
+    lumaBuffer.width = canvas.width;
+    lumaBuffer.height = canvas.height;
+    // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
+    lumaBufferCtx.filter = 'url(#' + id + ')';
+    return lumaBuffer;
+  }
+  return {
+    load: loadLuma,
+    get: getLuma,
+  };
+});
+
+function createCanvas(width, height) {
+  if (featureSupport.offscreenCanvas) {
+    return new OffscreenCanvas(width, height);
+  }
+  var canvas = createTag('canvas');
+  canvas.width = width;
+  canvas.height = height;
+  return canvas;
+}
+
+const assetLoader = (function () {
+  return {
+    loadLumaCanvas: lumaLoader.load,
+    getLumaCanvas: lumaLoader.get,
+    createCanvas: createCanvas,
+  };
+}());
+
+var registeredEffects = {};
+
+function CVEffects(elem) {
+  var i;
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects[type]) {
+      var Effect = registeredEffects[type].effect;
+      filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+CVEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+CVEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect(id, effect) {
+  registeredEffects[id] = {
+    effect,
+  };
+}
+
+function CVMaskElement(data, element) {
+  this.data = data;
+  this.element = element;
+  this.masksProperties = this.data.masksProperties || [];
+  this.viewData = createSizedArray(this.masksProperties.length);
+  var i;
+  var len = this.masksProperties.length;
+  var hasMasks = false;
+  for (i = 0; i < len; i += 1) {
+    if (this.masksProperties[i].mode !== 'n') {
+      hasMasks = true;
+    }
+    this.viewData[i] = ShapePropertyFactory.getShapeProp(this.element, this.masksProperties[i], 3);
+  }
+  this.hasMasks = hasMasks;
+  if (hasMasks) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+CVMaskElement.prototype.renderFrame = function () {
+  if (!this.hasMasks) {
+    return;
+  }
+  var transform = this.element.finalTransform.mat;
+  var ctx = this.element.canvasContext;
+  var i;
+  var len = this.masksProperties.length;
+  var pt;
+  var pts;
+  var data;
+  ctx.beginPath();
+  for (i = 0; i < len; i += 1) {
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.masksProperties[i].inv) {
+        ctx.moveTo(0, 0);
+        ctx.lineTo(this.element.globalData.compSize.w, 0);
+        ctx.lineTo(this.element.globalData.compSize.w, this.element.globalData.compSize.h);
+        ctx.lineTo(0, this.element.globalData.compSize.h);
+        ctx.lineTo(0, 0);
+      }
+      data = this.viewData[i].v;
+      pt = transform.applyToPointArray(data.v[0][0], data.v[0][1], 0);
+      ctx.moveTo(pt[0], pt[1]);
+      var j;
+      var jLen = data._length;
+      for (j = 1; j < jLen; j += 1) {
+        pts = transform.applyToTriplePoints(data.o[j - 1], data.i[j], data.v[j]);
+        ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
+      }
+      pts = transform.applyToTriplePoints(data.o[j - 1], data.i[0], data.v[0]);
+      ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
+    }
+  }
+  this.element.globalData.renderer.save(true);
+  ctx.clip();
+};
+
+CVMaskElement.prototype.getMaskProperty = MaskElement.prototype.getMaskProperty;
+
+CVMaskElement.prototype.destroy = function () {
+  this.element = null;
+};
+
+function CVBaseElement() {
+}
+
+var operationsMap = {
+  1: 'source-in',
+  2: 'source-out',
+  3: 'source-in',
+  4: 'source-out',
+};
+
+CVBaseElement.prototype = {
+  createElements: function () {},
+  initRendererElement: function () {},
+  createContainerElements: function () {
+    // If the layer is masked we will use two buffers to store each different states of the drawing
+    // This solution is not ideal for several reason. But unfortunately, because of the recursive
+    // nature of the render tree, it's the only simple way to make sure one inner mask doesn't override an outer mask.
+    // TODO: try to reduce the size of these buffers to the size of the composition contaning the layer
+    // It might be challenging because the layer most likely is transformed in some way
+    if (this.data.tt >= 1) {
+      this.buffers = [];
+      var canvasContext = this.globalData.canvasContext;
+      var bufferCanvas = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
+      this.buffers.push(bufferCanvas);
+      var bufferCanvas2 = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
+      this.buffers.push(bufferCanvas2);
+      if (this.data.tt >= 3 && !document._isProxy) {
+        assetLoader.loadLumaCanvas();
+      }
+    }
+    this.canvasContext = this.globalData.canvasContext;
+    this.transformCanvas = this.globalData.transformCanvas;
+    this.renderableEffectsManager = new CVEffects(this);
+    this.searchEffectTransforms();
+  },
+  createContent: function () {},
+  setBlendMode: function () {
+    var globalData = this.globalData;
+    if (globalData.blendMode !== this.data.bm) {
+      globalData.blendMode = this.data.bm;
+      var blendModeValue = getBlendMode(this.data.bm);
+      globalData.canvasContext.globalCompositeOperation = blendModeValue;
+    }
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new CVMaskElement(this.data, this);
+    this.transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+  },
+  hideElement: function () {
+    if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+      this.hidden = true;
+    }
+  },
+  showElement: function () {
+    if (this.isInRange && !this.isTransparent) {
+      this.hidden = false;
+      this._isFirstFrame = true;
+      this.maskManager._isFirstFrame = true;
+    }
+  },
+  clearCanvas: function (canvasContext) {
+    canvasContext.clearRect(
+      this.transformCanvas.tx,
+      this.transformCanvas.ty,
+      this.transformCanvas.w * this.transformCanvas.sx,
+      this.transformCanvas.h * this.transformCanvas.sy
+    );
+  },
+  prepareLayer: function () {
+    if (this.data.tt >= 1) {
+      var buffer = this.buffers[0];
+      var bufferCtx = buffer.getContext('2d');
+      this.clearCanvas(bufferCtx);
+      // on the first buffer we store the current state of the global drawing
+      bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+      // The next four lines are to clear the canvas
+      // TODO: Check if there is a way to clear the canvas without resetting the transform
+      this.currentTransform = this.canvasContext.getTransform();
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+      this.clearCanvas(this.canvasContext);
+      this.canvasContext.setTransform(this.currentTransform);
+    }
+  },
+  exitLayer: function () {
+    if (this.data.tt >= 1) {
+      var buffer = this.buffers[1];
+      // On the second buffer we store the current state of the global drawing
+      // that only contains the content of this layer
+      // (if it is a composition, it also includes the nested layers)
+      var bufferCtx = buffer.getContext('2d');
+      this.clearCanvas(bufferCtx);
+      bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+      // We clear the canvas again
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+      this.clearCanvas(this.canvasContext);
+      this.canvasContext.setTransform(this.currentTransform);
+      // We draw the mask
+      const mask = this.comp.getElementById('tp' in this.data ? this.data.tp : this.data.ind - 1);
+      mask.renderFrame(true);
+      // We draw the second buffer (that contains the content of this layer)
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+
+      // If the mask is a Luma matte, we need to do two extra painting operations
+      // the _isProxy check is to avoid drawing a fake canvas in workers that will throw an error
+      if (this.data.tt >= 3 && !document._isProxy) {
+        // We copy the painted mask to a buffer that has a color matrix filter applied to it
+        // that applies the rgb values to the alpha channel
+        var lumaBuffer = assetLoader.getLumaCanvas(this.canvasContext.canvas);
+        var lumaBufferCtx = lumaBuffer.getContext('2d');
+        lumaBufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+        this.clearCanvas(this.canvasContext);
+        // we repaint the context with the mask applied to it
+        this.canvasContext.drawImage(lumaBuffer, 0, 0);
+      }
+      this.canvasContext.globalCompositeOperation = operationsMap[this.data.tt];
+      this.canvasContext.drawImage(buffer, 0, 0);
+      // We finally draw the first buffer (that contains the content of the global drawing)
+      // We use destination-over to draw the global drawing below the current layer
+      this.canvasContext.globalCompositeOperation = 'destination-over';
+      this.canvasContext.drawImage(this.buffers[0], 0, 0);
+      this.canvasContext.setTransform(this.currentTransform);
+      // We reset the globalCompositeOperation to source-over, the standard type of operation
+      this.canvasContext.globalCompositeOperation = 'source-over';
+    }
+  },
+  renderFrame: function (forceRender) {
+    if (this.hidden || this.data.hd) {
+      return;
+    }
+    if (this.data.td === 1 && !forceRender) {
+      return;
+    }
+    this.renderTransform();
+    this.renderRenderable();
+    this.renderLocalTransform();
+    this.setBlendMode();
+    var forceRealStack = this.data.ty === 0;
+    this.prepareLayer();
+    this.globalData.renderer.save(forceRealStack);
+    this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props);
+    this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity);
+    this.renderInnerContent();
+    this.globalData.renderer.restore(forceRealStack);
+    this.exitLayer();
+    if (this.maskManager.hasMasks) {
+      this.globalData.renderer.restore(true);
+    }
+    if (this._isFirstFrame) {
+      this._isFirstFrame = false;
+    }
+  },
+  destroy: function () {
+    this.canvasContext = null;
+    this.data = null;
+    this.globalData = null;
+    this.maskManager.destroy();
+  },
+  mHelper: new Matrix(),
+};
+CVBaseElement.prototype.hide = CVBaseElement.prototype.hideElement;
+CVBaseElement.prototype.show = CVBaseElement.prototype.showElement;
+
+function CVShapeData(element, data, styles, transformsManager) {
+  this.styledShapes = [];
+  this.tr = [0, 0, 0, 0, 0, 0];
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  this.sh = ShapePropertyFactory.getShapeProp(element, data, ty, element);
+  var i;
+  var len = styles.length;
+  var styledShape;
+  for (i = 0; i < len; i += 1) {
+    if (!styles[i].closed) {
+      styledShape = {
+        transforms: transformsManager.addTransformSequence(styles[i].transforms),
+        trNodes: [],
+      };
+      this.styledShapes.push(styledShape);
+      styles[i].elements.push(styledShape);
+    }
+  }
+}
+
+CVShapeData.prototype.setAsAnimated = SVGShapeData.prototype.setAsAnimated;
+
+function CVShapeElement(data, globalData, comp) {
+  this.shapes = [];
+  this.shapesData = data.shapes;
+  this.stylesList = [];
+  this.itemsData = [];
+  this.prevViewData = [];
+  this.shapeModifiers = [];
+  this.processedElements = [];
+  this.transformsManager = new ShapeTransformManager();
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, CVBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableElement], CVShapeElement);
+
+CVShapeElement.prototype.initElement = RenderableDOMElement.prototype.initElement;
+
+CVShapeElement.prototype.transformHelper = { opacity: 1, _opMdf: false };
+
+CVShapeElement.prototype.dashResetter = [];
+
+CVShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
+};
+
+CVShapeElement.prototype.createStyleElement = function (data, transforms) {
+  var styleElem = {
+    data: data,
+    type: data.ty,
+    preTransforms: this.transformsManager.addTransformSequence(transforms),
+    transforms: [],
+    elements: [],
+    closed: data.hd === true,
+  };
+  var elementData = {};
+  if (data.ty === 'fl' || data.ty === 'st') {
+    elementData.c = PropertyFactory.getProp(this, data.c, 1, 255, this);
+    if (!elementData.c.k) {
+      styleElem.co = 'rgb(' + bmFloor(elementData.c.v[0]) + ',' + bmFloor(elementData.c.v[1]) + ',' + bmFloor(elementData.c.v[2]) + ')';
+    }
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    elementData.s = PropertyFactory.getProp(this, data.s, 1, null, this);
+    elementData.e = PropertyFactory.getProp(this, data.e, 1, null, this);
+    elementData.h = PropertyFactory.getProp(this, data.h || { k: 0 }, 0, 0.01, this);
+    elementData.a = PropertyFactory.getProp(this, data.a || { k: 0 }, 0, degToRads, this);
+    elementData.g = new GradientProperty(this, data.g, this);
+  }
+  elementData.o = PropertyFactory.getProp(this, data.o, 0, 0.01, this);
+  if (data.ty === 'st' || data.ty === 'gs') {
+    styleElem.lc = lineCapEnum[data.lc || 2];
+    styleElem.lj = lineJoinEnum[data.lj || 2];
+    if (data.lj == 1) { // eslint-disable-line eqeqeq
+      styleElem.ml = data.ml;
+    }
+    elementData.w = PropertyFactory.getProp(this, data.w, 0, null, this);
+    if (!elementData.w.k) {
+      styleElem.wi = elementData.w.v;
+    }
+    if (data.d) {
+      var d = new DashProperty(this, data.d, 'canvas', this);
+      elementData.d = d;
+      if (!elementData.d.k) {
+        styleElem.da = elementData.d.dashArray;
+        styleElem.do = elementData.d.dashoffset[0];
+      }
+    }
+  } else {
+    styleElem.r = data.r === 2 ? 'evenodd' : 'nonzero';
+  }
+  this.stylesList.push(styleElem);
+  elementData.style = styleElem;
+  return elementData;
+};
+
+CVShapeElement.prototype.createGroupElement = function () {
+  var elementData = {
+    it: [],
+    prevViewData: [],
+  };
+  return elementData;
+};
+
+CVShapeElement.prototype.createTransformElement = function (data) {
+  var elementData = {
+    transform: {
+      opacity: 1,
+      _opMdf: false,
+      key: this.transformsManager.getNewKey(),
+      op: PropertyFactory.getProp(this, data.o, 0, 0.01, this),
+      mProps: TransformPropertyFactory.getTransformProperty(this, data, this),
+    },
+  };
+  return elementData;
+};
+
+CVShapeElement.prototype.createShapeElement = function (data) {
+  var elementData = new CVShapeData(this, data, this.stylesList, this.transformsManager);
+
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  return elementData;
+};
+
+CVShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+  this.transformsManager.processSequences(this._isFirstFrame);
+};
+
+CVShapeElement.prototype.addTransformToStyleList = function (transform) {
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    if (!this.stylesList[i].closed) {
+      this.stylesList[i].transforms.push(transform);
+    }
+  }
+};
+
+CVShapeElement.prototype.removeTransformFromStyleList = function () {
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    if (!this.stylesList[i].closed) {
+      this.stylesList[i].transforms.pop();
+    }
+  }
+};
+
+CVShapeElement.prototype.closeStyles = function (styles) {
+  var i;
+  var len = styles.length;
+  for (i = 0; i < len; i += 1) {
+    styles[i].closed = true;
+  }
+};
+
+CVShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, shouldRender, transforms) {
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var processedPos;
+  var modifier;
+  var currentTransform;
+  var ownTransforms = [].concat(transforms);
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._shouldRender = shouldRender;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], ownTransforms);
+      } else {
+        itemsData[i].style.closed = false;
+      }
+
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, shouldRender, ownTransforms);
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        currentTransform = this.createTransformElement(arr[i]);
+        itemsData[i] = currentTransform;
+      }
+      ownTransforms.push(itemsData[i]);
+      this.addTransformToStyleList(itemsData[i]);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i]);
+      }
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        shouldRender = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  this.removeTransformFromStyleList();
+  this.closeStyles(ownStyles);
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+CVShapeElement.prototype.renderInnerContent = function () {
+  this.transformHelper.opacity = 1;
+  this.transformHelper._opMdf = false;
+  this.renderModifiers();
+  this.transformsManager.processSequences(this._isFirstFrame);
+  this.renderShape(this.transformHelper, this.shapesData, this.itemsData, true);
+};
+
+CVShapeElement.prototype.renderShapeTransform = function (parentTransform, groupTransform) {
+  if (parentTransform._opMdf || groupTransform.op._mdf || this._isFirstFrame) {
+    groupTransform.opacity = parentTransform.opacity;
+    groupTransform.opacity *= groupTransform.op.v;
+    groupTransform._opMdf = true;
+  }
+};
+
+CVShapeElement.prototype.drawLayer = function () {
+  var i;
+  var len = this.stylesList.length;
+  var j;
+  var jLen;
+  var k;
+  var kLen;
+  var elems;
+  var nodes;
+  var renderer = this.globalData.renderer;
+  var ctx = this.globalData.canvasContext;
+  var type;
+  var currentStyle;
+  for (i = 0; i < len; i += 1) {
+    currentStyle = this.stylesList[i];
+    type = currentStyle.type;
+
+    // Skipping style when
+    // Stroke width equals 0
+    // style should not be rendered (extra unused repeaters)
+    // current opacity equals 0
+    // global opacity equals 0
+    if (!(((type === 'st' || type === 'gs') && currentStyle.wi === 0) || !currentStyle.data._shouldRender || currentStyle.coOp === 0 || this.globalData.currentGlobalAlpha === 0)) {
+      renderer.save();
+      elems = currentStyle.elements;
+      if (type === 'st' || type === 'gs') {
+        renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd);
+        // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
+        renderer.ctxLineWidth(currentStyle.wi);
+        // ctx.lineWidth = currentStyle.wi;
+        renderer.ctxLineCap(currentStyle.lc);
+        // ctx.lineCap = currentStyle.lc;
+        renderer.ctxLineJoin(currentStyle.lj);
+        // ctx.lineJoin = currentStyle.lj;
+        renderer.ctxMiterLimit(currentStyle.ml || 0);
+        // ctx.miterLimit = currentStyle.ml || 0;
+      } else {
+        renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd);
+        // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
+      }
+      renderer.ctxOpacity(currentStyle.coOp);
+      if (type !== 'st' && type !== 'gs') {
+        ctx.beginPath();
+      }
+      renderer.ctxTransform(currentStyle.preTransforms.finalTransform.props);
+      jLen = elems.length;
+      for (j = 0; j < jLen; j += 1) {
+        if (type === 'st' || type === 'gs') {
+          ctx.beginPath();
+          if (currentStyle.da) {
+            ctx.setLineDash(currentStyle.da);
+            ctx.lineDashOffset = currentStyle.do;
+          }
+        }
+        nodes = elems[j].trNodes;
+        kLen = nodes.length;
+
+        for (k = 0; k < kLen; k += 1) {
+          if (nodes[k].t === 'm') {
+            ctx.moveTo(nodes[k].p[0], nodes[k].p[1]);
+          } else if (nodes[k].t === 'c') {
+            ctx.bezierCurveTo(nodes[k].pts[0], nodes[k].pts[1], nodes[k].pts[2], nodes[k].pts[3], nodes[k].pts[4], nodes[k].pts[5]);
+          } else {
+            ctx.closePath();
+          }
+        }
+        if (type === 'st' || type === 'gs') {
+          // ctx.stroke();
+          renderer.ctxStroke();
+          if (currentStyle.da) {
+            ctx.setLineDash(this.dashResetter);
+          }
+        }
+      }
+      if (type !== 'st' && type !== 'gs') {
+        // ctx.fill(currentStyle.r);
+        this.globalData.renderer.ctxFill(currentStyle.r);
+      }
+      renderer.restore();
+    }
+  }
+};
+
+CVShapeElement.prototype.renderShape = function (parentTransform, items, data, isMain) {
+  var i;
+  var len = items.length - 1;
+  var groupTransform;
+  groupTransform = parentTransform;
+  for (i = len; i >= 0; i -= 1) {
+    if (items[i].ty === 'tr') {
+      groupTransform = data[i].transform;
+      this.renderShapeTransform(parentTransform, groupTransform);
+    } else if (items[i].ty === 'sh' || items[i].ty === 'el' || items[i].ty === 'rc' || items[i].ty === 'sr') {
+      this.renderPath(items[i], data[i]);
+    } else if (items[i].ty === 'fl') {
+      this.renderFill(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'st') {
+      this.renderStroke(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'gf' || items[i].ty === 'gs') {
+      this.renderGradientFill(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'gr') {
+      this.renderShape(groupTransform, items[i].it, data[i].it);
+    } else if (items[i].ty === 'tm') {
+      //
+    }
+  }
+  if (isMain) {
+    this.drawLayer();
+  }
+};
+
+CVShapeElement.prototype.renderStyledShape = function (styledShape, shape) {
+  if (this._isFirstFrame || shape._mdf || styledShape.transforms._mdf) {
+    var shapeNodes = styledShape.trNodes;
+    var paths = shape.paths;
+    var i;
+    var len;
+    var j;
+    var jLen = paths._length;
+    shapeNodes.length = 0;
+    var groupTransformMat = styledShape.transforms.finalTransform;
+    for (j = 0; j < jLen; j += 1) {
+      var pathNodes = paths.shapes[j];
+      if (pathNodes && pathNodes.v) {
+        len = pathNodes._length;
+        for (i = 1; i < len; i += 1) {
+          if (i === 1) {
+            shapeNodes.push({
+              t: 'm',
+              p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0),
+            });
+          }
+          shapeNodes.push({
+            t: 'c',
+            pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[i], pathNodes.v[i]),
+          });
+        }
+        if (len === 1) {
+          shapeNodes.push({
+            t: 'm',
+            p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0),
+          });
+        }
+        if (pathNodes.c && len) {
+          shapeNodes.push({
+            t: 'c',
+            pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[0], pathNodes.v[0]),
+          });
+          shapeNodes.push({
+            t: 'z',
+          });
+        }
+      }
+    }
+    styledShape.trNodes = shapeNodes;
+  }
+};
+
+CVShapeElement.prototype.renderPath = function (pathData, itemData) {
+  if (pathData.hd !== true && pathData._shouldRender) {
+    var i;
+    var len = itemData.styledShapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderStyledShape(itemData.styledShapes[i], itemData.sh);
+    }
+  }
+};
+
+CVShapeElement.prototype.renderFill = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+
+  if (itemData.c._mdf || this._isFirstFrame) {
+    styleElem.co = 'rgb('
+        + bmFloor(itemData.c.v[0]) + ','
+        + bmFloor(itemData.c.v[1]) + ','
+        + bmFloor(itemData.c.v[2]) + ')';
+  }
+  if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
+    styleElem.coOp = itemData.o.v * groupTransform.opacity;
+  }
+};
+
+CVShapeElement.prototype.renderGradientFill = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+  var grd;
+  if (!styleElem.grd || itemData.g._mdf || itemData.s._mdf || itemData.e._mdf || (styleData.t !== 1 && (itemData.h._mdf || itemData.a._mdf))) {
+    var ctx = this.globalData.canvasContext;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+    if (styleData.t === 1) {
+      grd = ctx.createLinearGradient(pt1[0], pt1[1], pt2[0], pt2[1]);
+    } else {
+      var rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+      var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+      var percent = itemData.h.v;
+      if (percent >= 1) {
+        percent = 0.99;
+      } else if (percent <= -1) {
+        percent = -0.99;
+      }
+      var dist = rad * percent;
+      var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+      var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+      grd = ctx.createRadialGradient(x, y, 0, pt1[0], pt1[1], rad);
+    }
+
+    var i;
+    var len = styleData.g.p;
+    var cValues = itemData.g.c;
+    var opacity = 1;
+
+    for (i = 0; i < len; i += 1) {
+      if (itemData.g._hasOpacity && itemData.g._collapsable) {
+        opacity = itemData.g.o[i * 2 + 1];
+      }
+      grd.addColorStop(cValues[i * 4] / 100, 'rgba(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ',' + opacity + ')');
+    }
+    styleElem.grd = grd;
+  }
+  styleElem.coOp = itemData.o.v * groupTransform.opacity;
+};
+
+CVShapeElement.prototype.renderStroke = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+  var d = itemData.d;
+  if (d && (d._mdf || this._isFirstFrame)) {
+    styleElem.da = d.dashArray;
+    styleElem.do = d.dashoffset[0];
+  }
+  if (itemData.c._mdf || this._isFirstFrame) {
+    styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
+  }
+  if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
+    styleElem.coOp = itemData.o.v * groupTransform.opacity;
+  }
+  if (itemData.w._mdf || this._isFirstFrame) {
+    styleElem.wi = itemData.w.v;
+  }
+};
+
+CVShapeElement.prototype.destroy = function () {
+  this.shapesData = null;
+  this.globalData = null;
+  this.canvasContext = null;
+  this.stylesList.length = 0;
+  this.itemsData.length = 0;
+};
+
+function CVTextElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.yOffset = 0;
+  this.fillColorAnim = false;
+  this.strokeColorAnim = false;
+  this.strokeWidthAnim = false;
+  this.stroke = false;
+  this.fill = false;
+  this.justifyOffset = 0;
+  this.currentRender = null;
+  this.renderType = 'canvas';
+  this.values = {
+    fill: 'rgba(0,0,0,0)',
+    stroke: 'rgba(0,0,0,0)',
+    sWidth: 0,
+    fValue: '',
+  };
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement, ITextElement], CVTextElement);
+
+CVTextElement.prototype.tHelper = createTag('canvas').getContext('2d');
+
+CVTextElement.prototype.buildNewText = function () {
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
+
+  var hasFill = false;
+  if (documentData.fc) {
+    hasFill = true;
+    this.values.fill = this.buildColor(documentData.fc);
+  } else {
+    this.values.fill = 'rgba(0,0,0,0)';
+  }
+  this.fill = hasFill;
+  var hasStroke = false;
+  if (documentData.sc) {
+    hasStroke = true;
+    this.values.stroke = this.buildColor(documentData.sc);
+    this.values.sWidth = documentData.sw;
+  }
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  var i;
+  var len;
+  var letters = documentData.l;
+  var matrixHelper = this.mHelper;
+  this.stroke = hasStroke;
+  this.values.fValue = documentData.finalSize + 'px ' + this.globalData.fontManager.getFontByName(documentData.f).fFamily;
+  len = documentData.finalText.length;
+  // this.tHelper.font = this.values.fValue;
+  var charData;
+  var shapeData;
+  var k;
+  var kLen;
+  var shapes;
+  var j;
+  var jLen;
+  var pathNodes;
+  var commands;
+  var pathArr;
+  var singleShape = this.data.singleShape;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var cnt = 0;
+  for (i = 0; i < len; i += 1) {
+    charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
+    shapeData = (charData && charData.data) || {};
+    matrixHelper.reset();
+    if (singleShape && letters[i].n) {
+      xPos = -trackingOffset;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      firstLine = false;
+    }
+    shapes = shapeData.shapes ? shapeData.shapes[0].it : [];
+    jLen = shapes.length;
+    matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
+    if (singleShape) {
+      this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+    }
+    commands = createSizedArray(jLen - 1);
+    var commandsCounter = 0;
+    for (j = 0; j < jLen; j += 1) {
+      if (shapes[j].ty === 'sh') {
+        kLen = shapes[j].ks.k.i.length;
+        pathNodes = shapes[j].ks.k;
+        pathArr = [];
+        for (k = 1; k < kLen; k += 1) {
+          if (k === 1) {
+            pathArr.push(matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
+          }
+          pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToY(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToX(pathNodes.v[k][0], pathNodes.v[k][1], 0), matrixHelper.applyToY(pathNodes.v[k][0], pathNodes.v[k][1], 0));
+        }
+        pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToY(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
+        commands[commandsCounter] = pathArr;
+        commandsCounter += 1;
+      }
+    }
+    if (singleShape) {
+      xPos += letters[i].l;
+      xPos += trackingOffset;
+    }
+    if (this.textSpans[cnt]) {
+      this.textSpans[cnt].elem = commands;
+    } else {
+      this.textSpans[cnt] = { elem: commands };
+    }
+    cnt += 1;
+  }
+};
+
+CVTextElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  var ctx = this.canvasContext;
+  ctx.font = this.values.fValue;
+  this.globalData.renderer.ctxLineCap('butt');
+  // ctx.lineCap = 'butt';
+  this.globalData.renderer.ctxLineJoin('miter');
+  // ctx.lineJoin = 'miter';
+  this.globalData.renderer.ctxMiterLimit(4);
+  // ctx.miterLimit = 4;
+
+  if (!this.data.singleShape) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+  }
+
+  var i;
+  var len;
+  var j;
+  var jLen;
+  var k;
+  var kLen;
+  var renderedLetters = this.textAnimator.renderedLetters;
+
+  var letters = this.textProperty.currentData.l;
+
+  len = letters.length;
+  var renderedLetter;
+  var lastFill = null;
+  var lastStroke = null;
+  var lastStrokeW = null;
+  var commands;
+  var pathArr;
+  var renderer = this.globalData.renderer;
+  for (i = 0; i < len; i += 1) {
+    if (!letters[i].n) {
+      renderedLetter = renderedLetters[i];
+      if (renderedLetter) {
+        renderer.save();
+        renderer.ctxTransform(renderedLetter.p);
+        renderer.ctxOpacity(renderedLetter.o);
+      }
+      if (this.fill) {
+        if (renderedLetter && renderedLetter.fc) {
+          if (lastFill !== renderedLetter.fc) {
+            renderer.ctxFillStyle(renderedLetter.fc);
+            lastFill = renderedLetter.fc;
+            // ctx.fillStyle = renderedLetter.fc;
+          }
+        } else if (lastFill !== this.values.fill) {
+          lastFill = this.values.fill;
+          renderer.ctxFillStyle(this.values.fill);
+          // ctx.fillStyle = this.values.fill;
+        }
+        commands = this.textSpans[i].elem;
+        jLen = commands.length;
+        this.globalData.canvasContext.beginPath();
+        for (j = 0; j < jLen; j += 1) {
+          pathArr = commands[j];
+          kLen = pathArr.length;
+          this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
+          for (k = 2; k < kLen; k += 6) {
+            this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
+          }
+        }
+        this.globalData.canvasContext.closePath();
+        renderer.ctxFill();
+        // this.globalData.canvasContext.fill();
+        /// ctx.fillText(this.textSpans[i].val,0,0);
+      }
+      if (this.stroke) {
+        if (renderedLetter && renderedLetter.sw) {
+          if (lastStrokeW !== renderedLetter.sw) {
+            lastStrokeW = renderedLetter.sw;
+            renderer.ctxLineWidth(renderedLetter.sw);
+            // ctx.lineWidth = renderedLetter.sw;
+          }
+        } else if (lastStrokeW !== this.values.sWidth) {
+          lastStrokeW = this.values.sWidth;
+          renderer.ctxLineWidth(this.values.sWidth);
+          // ctx.lineWidth = this.values.sWidth;
+        }
+        if (renderedLetter && renderedLetter.sc) {
+          if (lastStroke !== renderedLetter.sc) {
+            lastStroke = renderedLetter.sc;
+            renderer.ctxStrokeStyle(renderedLetter.sc);
+            // ctx.strokeStyle = renderedLetter.sc;
+          }
+        } else if (lastStroke !== this.values.stroke) {
+          lastStroke = this.values.stroke;
+          renderer.ctxStrokeStyle(this.values.stroke);
+          // ctx.strokeStyle = this.values.stroke;
+        }
+        commands = this.textSpans[i].elem;
+        jLen = commands.length;
+        this.globalData.canvasContext.beginPath();
+        for (j = 0; j < jLen; j += 1) {
+          pathArr = commands[j];
+          kLen = pathArr.length;
+          this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
+          for (k = 2; k < kLen; k += 6) {
+            this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
+          }
+        }
+        this.globalData.canvasContext.closePath();
+        renderer.ctxStroke();
+        // this.globalData.canvasContext.stroke();
+        /// ctx.strokeText(letters[i].val,0,0);
+      }
+      if (renderedLetter) {
+        this.globalData.renderer.restore();
+      }
+    }
+  }
+};
+
+function CVImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  this.img = globalData.imageLoader.getAsset(this.assetData);
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVImageElement);
+
+CVImageElement.prototype.initElement = SVGShapeElement.prototype.initElement;
+CVImageElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
+
+CVImageElement.prototype.createContent = function () {
+  if (this.img.width && (this.assetData.w !== this.img.width || this.assetData.h !== this.img.height)) {
+    var canvas = createTag('canvas');
+    canvas.width = this.assetData.w;
+    canvas.height = this.assetData.h;
+    var ctx = canvas.getContext('2d');
+
+    var imgW = this.img.width;
+    var imgH = this.img.height;
+    var imgRel = imgW / imgH;
+    var canvasRel = this.assetData.w / this.assetData.h;
+    var widthCrop;
+    var heightCrop;
+    var par = this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio;
+    if ((imgRel > canvasRel && par === 'xMidYMid slice') || (imgRel < canvasRel && par !== 'xMidYMid slice')) {
+      heightCrop = imgH;
+      widthCrop = heightCrop * canvasRel;
+    } else {
+      widthCrop = imgW;
+      heightCrop = widthCrop / canvasRel;
+    }
+    ctx.drawImage(this.img, (imgW - widthCrop) / 2, (imgH - heightCrop) / 2, widthCrop, heightCrop, 0, 0, this.assetData.w, this.assetData.h);
+    this.img = canvas;
+  }
+};
+
+CVImageElement.prototype.renderInnerContent = function () {
+  this.canvasContext.drawImage(this.img, 0, 0);
+};
+
+CVImageElement.prototype.destroy = function () {
+  this.img = null;
+};
+
+function CVSolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVSolidElement);
+
+CVSolidElement.prototype.initElement = SVGShapeElement.prototype.initElement;
+CVSolidElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
+
+CVSolidElement.prototype.renderInnerContent = function () {
+  // var ctx = this.canvasContext;
+  this.globalData.renderer.ctxFillStyle(this.data.sc);
+  // ctx.fillStyle = this.data.sc;
+  this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh);
+  // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
+  //
+};
+
+function CanvasRendererBase() {
+}
+extendPrototype([BaseRenderer], CanvasRendererBase);
+
+CanvasRendererBase.prototype.createShape = function (data) {
+  return new CVShapeElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createText = function (data) {
+  return new CVTextElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createImage = function (data) {
+  return new CVImageElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createSolid = function (data) {
+  return new CVSolidElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
+
+CanvasRendererBase.prototype.ctxTransform = function (props) {
+  if (props[0] === 1 && props[1] === 0 && props[4] === 0 && props[5] === 1 && props[12] === 0 && props[13] === 0) {
+    return;
+  }
+  this.canvasContext.transform(props[0], props[1], props[4], props[5], props[12], props[13]);
+};
+
+CanvasRendererBase.prototype.ctxOpacity = function (op) {
+  this.canvasContext.globalAlpha *= op < 0 ? 0 : op;
+};
+
+CanvasRendererBase.prototype.ctxFillStyle = function (value) {
+  this.canvasContext.fillStyle = value;
+};
+
+CanvasRendererBase.prototype.ctxStrokeStyle = function (value) {
+  this.canvasContext.strokeStyle = value;
+};
+
+CanvasRendererBase.prototype.ctxLineWidth = function (value) {
+  this.canvasContext.lineWidth = value;
+};
+
+CanvasRendererBase.prototype.ctxLineCap = function (value) {
+  this.canvasContext.lineCap = value;
+};
+
+CanvasRendererBase.prototype.ctxLineJoin = function (value) {
+  this.canvasContext.lineJoin = value;
+};
+
+CanvasRendererBase.prototype.ctxMiterLimit = function (value) {
+  this.canvasContext.miterLimit = value;
+};
+
+CanvasRendererBase.prototype.ctxFill = function (rule) {
+  this.canvasContext.fill(rule);
+};
+
+CanvasRendererBase.prototype.ctxFillRect = function (x, y, w, h) {
+  this.canvasContext.fillRect(x, y, w, h);
+};
+
+CanvasRendererBase.prototype.ctxStroke = function () {
+  this.canvasContext.stroke();
+};
+
+CanvasRendererBase.prototype.reset = function () {
+  if (!this.renderConfig.clearCanvas) {
+    this.canvasContext.restore();
+    return;
+  }
+  this.contextData.reset();
+};
+
+CanvasRendererBase.prototype.save = function () {
+  this.canvasContext.save();
+};
+
+CanvasRendererBase.prototype.restore = function (actionFlag) {
+  if (!this.renderConfig.clearCanvas) {
+    this.canvasContext.restore();
+    return;
+  }
+  if (actionFlag) {
+    this.globalData.blendMode = 'source-over';
+  }
+  this.contextData.restore(actionFlag);
+};
+
+CanvasRendererBase.prototype.configAnimation = function (animData) {
+  if (this.animationItem.wrapper) {
+    this.animationItem.container = createTag('canvas');
+    var containerStyle = this.animationItem.container.style;
+    containerStyle.width = '100%';
+    containerStyle.height = '100%';
+    var origin = '0px 0px 0px';
+    containerStyle.transformOrigin = origin;
+    containerStyle.mozTransformOrigin = origin;
+    containerStyle.webkitTransformOrigin = origin;
+    containerStyle['-webkit-transform'] = origin;
+    containerStyle.contentVisibility = this.renderConfig.contentVisibility;
+    this.animationItem.wrapper.appendChild(this.animationItem.container);
+    this.canvasContext = this.animationItem.container.getContext('2d');
+    if (this.renderConfig.className) {
+      this.animationItem.container.setAttribute('class', this.renderConfig.className);
+    }
+    if (this.renderConfig.id) {
+      this.animationItem.container.setAttribute('id', this.renderConfig.id);
+    }
+  } else {
+    this.canvasContext = this.renderConfig.context;
+  }
+  this.contextData.setContext(this.canvasContext);
+  this.data = animData;
+  this.layers = animData.layers;
+  this.transformCanvas = {
+    w: animData.w,
+    h: animData.h,
+    sx: 0,
+    sy: 0,
+    tx: 0,
+    ty: 0,
+  };
+  this.setupGlobalData(animData, document.body);
+  this.globalData.canvasContext = this.canvasContext;
+  this.globalData.renderer = this;
+  this.globalData.isDashed = false;
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.globalData.transformCanvas = this.transformCanvas;
+  this.elements = createSizedArray(animData.layers.length);
+
+  this.updateContainerSize();
+};
+
+CanvasRendererBase.prototype.updateContainerSize = function (width, height) {
+  this.reset();
+  var elementWidth;
+  var elementHeight;
+  if (width) {
+    elementWidth = width;
+    elementHeight = height;
+    this.canvasContext.canvas.width = elementWidth;
+    this.canvasContext.canvas.height = elementHeight;
+  } else {
+    if (this.animationItem.wrapper && this.animationItem.container) {
+      elementWidth = this.animationItem.wrapper.offsetWidth;
+      elementHeight = this.animationItem.wrapper.offsetHeight;
+    } else {
+      elementWidth = this.canvasContext.canvas.width;
+      elementHeight = this.canvasContext.canvas.height;
+    }
+    this.canvasContext.canvas.width = elementWidth * this.renderConfig.dpr;
+    this.canvasContext.canvas.height = elementHeight * this.renderConfig.dpr;
+  }
+
+  var elementRel;
+  var animationRel;
+  if (this.renderConfig.preserveAspectRatio.indexOf('meet') !== -1 || this.renderConfig.preserveAspectRatio.indexOf('slice') !== -1) {
+    var par = this.renderConfig.preserveAspectRatio.split(' ');
+    var fillType = par[1] || 'meet';
+    var pos = par[0] || 'xMidYMid';
+    var xPos = pos.substr(0, 4);
+    var yPos = pos.substr(4);
+    elementRel = elementWidth / elementHeight;
+    animationRel = this.transformCanvas.w / this.transformCanvas.h;
+    if ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice')) {
+      this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+      this.transformCanvas.sy = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+    } else {
+      this.transformCanvas.sx = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+      this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+    }
+
+    if (xPos === 'xMid' && ((animationRel < elementRel && fillType === 'meet') || (animationRel > elementRel && fillType === 'slice'))) {
+      this.transformCanvas.tx = ((elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) / 2) * this.renderConfig.dpr;
+    } else if (xPos === 'xMax' && ((animationRel < elementRel && fillType === 'meet') || (animationRel > elementRel && fillType === 'slice'))) {
+      this.transformCanvas.tx = (elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) * this.renderConfig.dpr;
+    } else {
+      this.transformCanvas.tx = 0;
+    }
+    if (yPos === 'YMid' && ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice'))) {
+      this.transformCanvas.ty = ((elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w)) / 2) * this.renderConfig.dpr;
+    } else if (yPos === 'YMax' && ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice'))) {
+      this.transformCanvas.ty = ((elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w))) * this.renderConfig.dpr;
+    } else {
+      this.transformCanvas.ty = 0;
+    }
+  } else if (this.renderConfig.preserveAspectRatio === 'none') {
+    this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+    this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+    this.transformCanvas.tx = 0;
+    this.transformCanvas.ty = 0;
+  } else {
+    this.transformCanvas.sx = this.renderConfig.dpr;
+    this.transformCanvas.sy = this.renderConfig.dpr;
+    this.transformCanvas.tx = 0;
+    this.transformCanvas.ty = 0;
+  }
+  this.transformCanvas.props = [this.transformCanvas.sx, 0, 0, 0, 0, this.transformCanvas.sy, 0, 0, 0, 0, 1, 0, this.transformCanvas.tx, this.transformCanvas.ty, 0, 1];
+  /* var i, len = this.elements.length;
+    for(i=0;i<len;i+=1){
+        if(this.elements[i] && this.elements[i].data.ty === 0){
+            this.elements[i].resize(this.globalData.transformCanvas);
+        }
+    } */
+  this.ctxTransform(this.transformCanvas.props);
+  this.canvasContext.beginPath();
+  this.canvasContext.rect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
+  this.canvasContext.closePath();
+  this.canvasContext.clip();
+
+  this.renderFrame(this.renderedFrame, true);
+};
+
+CanvasRendererBase.prototype.destroy = function () {
+  if (this.renderConfig.clearCanvas && this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.globalData.canvasContext = null;
+  this.animationItem.container = null;
+  this.destroyed = true;
+};
+
+CanvasRendererBase.prototype.renderFrame = function (num, forceRender) {
+  if ((this.renderedFrame === num && this.renderConfig.clearCanvas === true && !forceRender) || this.destroyed || num === -1) {
+    return;
+  }
+  this.renderedFrame = num;
+  this.globalData.frameNum = num - this.animationItem._isFirstFrame;
+  this.globalData.frameId += 1;
+  this.globalData._mdf = !this.renderConfig.clearCanvas || forceRender;
+  this.globalData.projectInterface.currentFrame = num;
+
+  // console.log('--------');
+  // console.log('NEW: ',num);
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    if (this.renderConfig.clearCanvas === true) {
+      this.canvasContext.clearRect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
+    } else {
+      this.save();
+    }
+    for (i = len - 1; i >= 0; i -= 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+    if (this.renderConfig.clearCanvas !== true) {
+      this.restore();
+    }
+  }
+};
+
+CanvasRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  var element = this.createItem(this.layers[pos], this, this.globalData);
+  elements[pos] = element;
+  element.initExpressions();
+  /* if(this.layers[pos].ty === 0){
+        element.resize(this.globalData.transformCanvas);
+    } */
+};
+
+CanvasRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+  }
+};
+
+CanvasRendererBase.prototype.hide = function () {
+  this.animationItem.container.style.display = 'none';
+};
+
+CanvasRendererBase.prototype.show = function () {
+  this.animationItem.container.style.display = 'block';
+};
+
+function CanvasContext() {
+  this.opacity = -1;
+  this.transform = createTypedArray('float32', 16);
+  this.fillStyle = '';
+  this.strokeStyle = '';
+  this.lineWidth = '';
+  this.lineCap = '';
+  this.lineJoin = '';
+  this.miterLimit = '';
+  this.id = Math.random();
+}
+
+function CVContextData() {
+  this.stack = [];
+  this.cArrPos = 0;
+  this.cTr = new Matrix();
+  var i;
+  var len = 15;
+  for (i = 0; i < len; i += 1) {
+    var canvasContext = new CanvasContext();
+    this.stack[i] = canvasContext;
+  }
+  this._length = len;
+  this.nativeContext = null;
+  this.transformMat = new Matrix();
+  this.currentOpacity = 1;
+  //
+  this.currentFillStyle = '';
+  this.appliedFillStyle = '';
+  //
+  this.currentStrokeStyle = '';
+  this.appliedStrokeStyle = '';
+  //
+  this.currentLineWidth = '';
+  this.appliedLineWidth = '';
+  //
+  this.currentLineCap = '';
+  this.appliedLineCap = '';
+  //
+  this.currentLineJoin = '';
+  this.appliedLineJoin = '';
+  //
+  this.appliedMiterLimit = '';
+  this.currentMiterLimit = '';
+}
+
+CVContextData.prototype.duplicate = function () {
+  var newLength = this._length * 2;
+  var i = 0;
+  for (i = this._length; i < newLength; i += 1) {
+    this.stack[i] = new CanvasContext();
+  }
+  this._length = newLength;
+};
+
+CVContextData.prototype.reset = function () {
+  this.cArrPos = 0;
+  this.cTr.reset();
+  this.stack[this.cArrPos].opacity = 1;
+};
+
+CVContextData.prototype.restore = function (forceRestore) {
+  this.cArrPos -= 1;
+  var currentContext = this.stack[this.cArrPos];
+  var transform = currentContext.transform;
+  var i;
+  var arr = this.cTr.props;
+  for (i = 0; i < 16; i += 1) {
+    arr[i] = transform[i];
+  }
+  if (forceRestore) {
+    this.nativeContext.restore();
+    var prevStack = this.stack[this.cArrPos + 1];
+    this.appliedFillStyle = prevStack.fillStyle;
+    this.appliedStrokeStyle = prevStack.strokeStyle;
+    this.appliedLineWidth = prevStack.lineWidth;
+    this.appliedLineCap = prevStack.lineCap;
+    this.appliedLineJoin = prevStack.lineJoin;
+    this.appliedMiterLimit = prevStack.miterLimit;
+  }
+  this.nativeContext.setTransform(transform[0], transform[1], transform[4], transform[5], transform[12], transform[13]);
+  if (forceRestore || (currentContext.opacity !== -1 && this.currentOpacity !== currentContext.opacity)) {
+    this.nativeContext.globalAlpha = currentContext.opacity;
+    this.currentOpacity = currentContext.opacity;
+  }
+  this.currentFillStyle = currentContext.fillStyle;
+  this.currentStrokeStyle = currentContext.strokeStyle;
+  this.currentLineWidth = currentContext.lineWidth;
+  this.currentLineCap = currentContext.lineCap;
+  this.currentLineJoin = currentContext.lineJoin;
+  this.currentMiterLimit = currentContext.miterLimit;
+};
+
+CVContextData.prototype.save = function (saveOnNativeFlag) {
+  if (saveOnNativeFlag) {
+    this.nativeContext.save();
+  }
+  var props = this.cTr.props;
+  if (this._length <= this.cArrPos) {
+    this.duplicate();
+  }
+
+  var currentStack = this.stack[this.cArrPos];
+  var i;
+  for (i = 0; i < 16; i += 1) {
+    currentStack.transform[i] = props[i];
+  }
+  this.cArrPos += 1;
+  var newStack = this.stack[this.cArrPos];
+  newStack.opacity = currentStack.opacity;
+  newStack.fillStyle = currentStack.fillStyle;
+  newStack.strokeStyle = currentStack.strokeStyle;
+  newStack.lineWidth = currentStack.lineWidth;
+  newStack.lineCap = currentStack.lineCap;
+  newStack.lineJoin = currentStack.lineJoin;
+  newStack.miterLimit = currentStack.miterLimit;
+};
+
+CVContextData.prototype.setOpacity = function (value) {
+  this.stack[this.cArrPos].opacity = value;
+};
+
+CVContextData.prototype.setContext = function (value) {
+  this.nativeContext = value;
+};
+
+CVContextData.prototype.fillStyle = function (value) {
+  if (this.stack[this.cArrPos].fillStyle !== value) {
+    this.currentFillStyle = value;
+    this.stack[this.cArrPos].fillStyle = value;
+  }
+};
+
+CVContextData.prototype.strokeStyle = function (value) {
+  if (this.stack[this.cArrPos].strokeStyle !== value) {
+    this.currentStrokeStyle = value;
+    this.stack[this.cArrPos].strokeStyle = value;
+  }
+};
+
+CVContextData.prototype.lineWidth = function (value) {
+  if (this.stack[this.cArrPos].lineWidth !== value) {
+    this.currentLineWidth = value;
+    this.stack[this.cArrPos].lineWidth = value;
+  }
+};
+
+CVContextData.prototype.lineCap = function (value) {
+  if (this.stack[this.cArrPos].lineCap !== value) {
+    this.currentLineCap = value;
+    this.stack[this.cArrPos].lineCap = value;
+  }
+};
+
+CVContextData.prototype.lineJoin = function (value) {
+  if (this.stack[this.cArrPos].lineJoin !== value) {
+    this.currentLineJoin = value;
+    this.stack[this.cArrPos].lineJoin = value;
+  }
+};
+
+CVContextData.prototype.miterLimit = function (value) {
+  if (this.stack[this.cArrPos].miterLimit !== value) {
+    this.currentMiterLimit = value;
+    this.stack[this.cArrPos].miterLimit = value;
+  }
+};
+
+CVContextData.prototype.transform = function (props) {
+  this.transformMat.cloneFromProps(props);
+  // Taking the last transform value from the stored stack of transforms
+  var currentTransform = this.cTr;
+  // Applying the last transform value after the new transform to respect the order of transformations
+  this.transformMat.multiply(currentTransform);
+  // Storing the new transformed value in the stored transform
+  currentTransform.cloneFromProps(this.transformMat.props);
+  var trProps = currentTransform.props;
+  // Applying the new transform to the canvas
+  this.nativeContext.setTransform(trProps[0], trProps[1], trProps[4], trProps[5], trProps[12], trProps[13]);
+};
+
+CVContextData.prototype.opacity = function (op) {
+  var currentOpacity = this.stack[this.cArrPos].opacity;
+  currentOpacity *= op < 0 ? 0 : op;
+  if (this.stack[this.cArrPos].opacity !== currentOpacity) {
+    if (this.currentOpacity !== op) {
+      this.nativeContext.globalAlpha = op;
+      this.currentOpacity = op;
+    }
+    this.stack[this.cArrPos].opacity = currentOpacity;
+  }
+};
+
+CVContextData.prototype.fill = function (rule) {
+  if (this.appliedFillStyle !== this.currentFillStyle) {
+    this.appliedFillStyle = this.currentFillStyle;
+    this.nativeContext.fillStyle = this.appliedFillStyle;
+  }
+  this.nativeContext.fill(rule);
+};
+
+CVContextData.prototype.fillRect = function (x, y, w, h) {
+  if (this.appliedFillStyle !== this.currentFillStyle) {
+    this.appliedFillStyle = this.currentFillStyle;
+    this.nativeContext.fillStyle = this.appliedFillStyle;
+  }
+  this.nativeContext.fillRect(x, y, w, h);
+};
+
+CVContextData.prototype.stroke = function () {
+  if (this.appliedStrokeStyle !== this.currentStrokeStyle) {
+    this.appliedStrokeStyle = this.currentStrokeStyle;
+    this.nativeContext.strokeStyle = this.appliedStrokeStyle;
+  }
+  if (this.appliedLineWidth !== this.currentLineWidth) {
+    this.appliedLineWidth = this.currentLineWidth;
+    this.nativeContext.lineWidth = this.appliedLineWidth;
+  }
+  if (this.appliedLineCap !== this.currentLineCap) {
+    this.appliedLineCap = this.currentLineCap;
+    this.nativeContext.lineCap = this.appliedLineCap;
+  }
+  if (this.appliedLineJoin !== this.currentLineJoin) {
+    this.appliedLineJoin = this.currentLineJoin;
+    this.nativeContext.lineJoin = this.appliedLineJoin;
+  }
+  if (this.appliedMiterLimit !== this.currentMiterLimit) {
+    this.appliedMiterLimit = this.currentMiterLimit;
+    this.nativeContext.miterLimit = this.appliedMiterLimit;
+  }
+  this.nativeContext.stroke();
+};
+
+function CVCompElement(data, globalData, comp) {
+  this.completeLayers = false;
+  this.layers = data.layers;
+  this.pendingElements = [];
+  this.elements = createSizedArray(this.layers.length);
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([CanvasRendererBase, ICompElement, CVBaseElement], CVCompElement);
+
+CVCompElement.prototype.renderInnerContent = function () {
+  var ctx = this.canvasContext;
+  ctx.beginPath();
+  ctx.moveTo(0, 0);
+  ctx.lineTo(this.data.w, 0);
+  ctx.lineTo(this.data.w, this.data.h);
+  ctx.lineTo(0, this.data.h);
+  ctx.lineTo(0, 0);
+  ctx.clip();
+  var i;
+  var len = this.layers.length;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+CVCompElement.prototype.destroy = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+  this.layers = null;
+  this.elements = null;
+};
+
+CVCompElement.prototype.createComp = function (data) {
+  return new CVCompElement(data, this.globalData, this);
+};
+
+function CanvasRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.renderConfig = {
+    clearCanvas: (config && config.clearCanvas !== undefined) ? config.clearCanvas : true,
+    context: (config && config.context) || null,
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+  this.renderConfig.dpr = (config && config.dpr) || 1;
+  if (this.animationItem.wrapper) {
+    this.renderConfig.dpr = (config && config.dpr) || window.devicePixelRatio || 1;
+  }
+  this.renderedFrame = -1;
+  this.globalData = {
+    frameNum: -1,
+    _mdf: false,
+    renderConfig: this.renderConfig,
+    currentGlobalAlpha: -1,
+  };
+  this.contextData = new CVContextData();
+  this.elements = [];
+  this.pendingElements = [];
+  this.transformMat = new Matrix();
+  this.completeLayers = false;
+  this.rendererType = 'canvas';
+  if (this.renderConfig.clearCanvas) {
+    this.ctxTransform = this.contextData.transform.bind(this.contextData);
+    this.ctxOpacity = this.contextData.opacity.bind(this.contextData);
+    this.ctxFillStyle = this.contextData.fillStyle.bind(this.contextData);
+    this.ctxStrokeStyle = this.contextData.strokeStyle.bind(this.contextData);
+    this.ctxLineWidth = this.contextData.lineWidth.bind(this.contextData);
+    this.ctxLineCap = this.contextData.lineCap.bind(this.contextData);
+    this.ctxLineJoin = this.contextData.lineJoin.bind(this.contextData);
+    this.ctxMiterLimit = this.contextData.miterLimit.bind(this.contextData);
+    this.ctxFill = this.contextData.fill.bind(this.contextData);
+    this.ctxFillRect = this.contextData.fillRect.bind(this.contextData);
+    this.ctxStroke = this.contextData.stroke.bind(this.contextData);
+    this.save = this.contextData.save.bind(this.contextData);
+  }
+}
+extendPrototype([CanvasRendererBase], CanvasRenderer);
+
+CanvasRenderer.prototype.createComp = function (data) {
+  return new CVCompElement(data, this.globalData, this);
+};
+
+function HBaseElement() {}
+HBaseElement.prototype = {
+  checkBlendMode: function () {},
+  initRendererElement: function () {
+    this.baseElement = createTag(this.data.tg || 'div');
+    if (this.data.hasMask) {
+      this.svgElement = createNS('svg');
+      this.layerElement = createNS('g');
+      this.maskedElement = this.layerElement;
+      this.svgElement.appendChild(this.layerElement);
+      this.baseElement.appendChild(this.svgElement);
+    } else {
+      this.layerElement = this.baseElement;
+    }
+    styleDiv(this.baseElement);
+  },
+  createContainerElements: function () {
+    this.renderableEffectsManager = new CVEffects(this);
+    this.transformedElement = this.baseElement;
+    this.maskedElement = this.layerElement;
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    var transformedElementStyle = this.transformedElement ? this.transformedElement.style : {};
+    if (this.finalTransform._matMdf) {
+      var matrixValue = this.finalTransform.mat.toCSS();
+      transformedElementStyle.transform = matrixValue;
+      transformedElementStyle.webkitTransform = matrixValue;
+    }
+    if (this.finalTransform._opMdf) {
+      transformedElementStyle.opacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderFrame: function () {
+    // If it is exported as hidden (data.hd === true) no need to render
+    // If it is not visible no need to render
+    if (this.data.hd || this.hidden) {
+      return;
+    }
+    this.renderTransform();
+    this.renderRenderable();
+    this.renderElement();
+    this.renderInnerContent();
+    if (this._isFirstFrame) {
+      this._isFirstFrame = false;
+    }
+  },
+  destroy: function () {
+    this.layerElement = null;
+    this.transformedElement = null;
+    if (this.matteElement) {
+      this.matteElement = null;
+    }
+    if (this.maskManager) {
+      this.maskManager.destroy();
+      this.maskManager = null;
+    }
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+  },
+  addEffects: function () {
+  },
+  setMatte: function () {},
+};
+HBaseElement.prototype.getBaseElement = SVGBaseElement.prototype.getBaseElement;
+HBaseElement.prototype.destroyBaseElement = HBaseElement.prototype.destroy;
+HBaseElement.prototype.buildElementParenting = BaseRenderer.prototype.buildElementParenting;
+
+function HSolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], HSolidElement);
+
+HSolidElement.prototype.createContent = function () {
+  var rect;
+  if (this.data.hasMask) {
+    rect = createNS('rect');
+    rect.setAttribute('width', this.data.sw);
+    rect.setAttribute('height', this.data.sh);
+    rect.setAttribute('fill', this.data.sc);
+    this.svgElement.setAttribute('width', this.data.sw);
+    this.svgElement.setAttribute('height', this.data.sh);
+  } else {
+    rect = createTag('div');
+    rect.style.width = this.data.sw + 'px';
+    rect.style.height = this.data.sh + 'px';
+    rect.style.backgroundColor = this.data.sc;
+  }
+  this.layerElement.appendChild(rect);
+};
+
+function HShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.shapesContainer = createNS('g');
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  this.currentBBox = {
+    x: 999999,
+    y: -999999,
+    h: 0,
+    w: 0,
+  };
+}
+extendPrototype([BaseElement, TransformElement, HSolidElement, SVGShapeElement, HBaseElement, HierarchyElement, FrameElement, RenderableElement], HShapeElement);
+HShapeElement.prototype._renderShapeFrame = HShapeElement.prototype.renderInnerContent;
+
+HShapeElement.prototype.createContent = function () {
+  var cont;
+  this.baseElement.style.fontSize = 0;
+  if (this.data.hasMask) {
+    this.layerElement.appendChild(this.shapesContainer);
+    cont = this.svgElement;
+  } else {
+    cont = createNS('svg');
+    var size = this.comp.data ? this.comp.data : this.globalData.compSize;
+    cont.setAttribute('width', size.w);
+    cont.setAttribute('height', size.h);
+    cont.appendChild(this.shapesContainer);
+    this.layerElement.appendChild(cont);
+  }
+
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.shapesContainer, 0, [], true);
+  this.filterUniqueShapes();
+  this.shapeCont = cont;
+};
+
+HShapeElement.prototype.getTransformedPoint = function (transformers, point) {
+  var i;
+  var len = transformers.length;
+  for (i = 0; i < len; i += 1) {
+    point = transformers[i].mProps.v.applyToPointArray(point[0], point[1], 0);
+  }
+  return point;
+};
+
+HShapeElement.prototype.calculateShapeBoundingBox = function (item, boundingBox) {
+  var shape = item.sh.v;
+  var transformers = item.transformers;
+  var i;
+  var len = shape._length;
+  var vPoint;
+  var oPoint;
+  var nextIPoint;
+  var nextVPoint;
+  if (len <= 1) {
+    return;
+  }
+  for (i = 0; i < len - 1; i += 1) {
+    vPoint = this.getTransformedPoint(transformers, shape.v[i]);
+    oPoint = this.getTransformedPoint(transformers, shape.o[i]);
+    nextIPoint = this.getTransformedPoint(transformers, shape.i[i + 1]);
+    nextVPoint = this.getTransformedPoint(transformers, shape.v[i + 1]);
+    this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
+  }
+  if (shape.c) {
+    vPoint = this.getTransformedPoint(transformers, shape.v[i]);
+    oPoint = this.getTransformedPoint(transformers, shape.o[i]);
+    nextIPoint = this.getTransformedPoint(transformers, shape.i[0]);
+    nextVPoint = this.getTransformedPoint(transformers, shape.v[0]);
+    this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
+  }
+};
+
+HShapeElement.prototype.checkBounds = function (vPoint, oPoint, nextIPoint, nextVPoint, boundingBox) {
+  this.getBoundsOfCurve(vPoint, oPoint, nextIPoint, nextVPoint);
+  var bounds = this.shapeBoundingBox;
+  boundingBox.x = bmMin(bounds.left, boundingBox.x);
+  boundingBox.xMax = bmMax(bounds.right, boundingBox.xMax);
+  boundingBox.y = bmMin(bounds.top, boundingBox.y);
+  boundingBox.yMax = bmMax(bounds.bottom, boundingBox.yMax);
+};
+
+HShapeElement.prototype.shapeBoundingBox = {
+  left: 0,
+  right: 0,
+  top: 0,
+  bottom: 0,
+};
+
+HShapeElement.prototype.tempBoundingBox = {
+  x: 0,
+  xMax: 0,
+  y: 0,
+  yMax: 0,
+  width: 0,
+  height: 0,
+};
+
+HShapeElement.prototype.getBoundsOfCurve = function (p0, p1, p2, p3) {
+  var bounds = [[p0[0], p3[0]], [p0[1], p3[1]]];
+
+  for (var a, b, c, t, b2ac, t1, t2, i = 0; i < 2; ++i) { // eslint-disable-line no-plusplus
+    b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];
+    a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];
+    c = 3 * p1[i] - 3 * p0[i];
+
+    b |= 0; // eslint-disable-line no-bitwise
+    a |= 0; // eslint-disable-line no-bitwise
+    c |= 0; // eslint-disable-line no-bitwise
+
+    if (a === 0 && b === 0) {
+      //
+    } else if (a === 0) {
+      t = -c / b;
+
+      if (t > 0 && t < 1) {
+        bounds[i].push(this.calculateF(t, p0, p1, p2, p3, i));
+      }
+    } else {
+      b2ac = b * b - 4 * c * a;
+
+      if (b2ac >= 0) {
+        t1 = (-b + bmSqrt(b2ac)) / (2 * a);
+        if (t1 > 0 && t1 < 1) bounds[i].push(this.calculateF(t1, p0, p1, p2, p3, i));
+        t2 = (-b - bmSqrt(b2ac)) / (2 * a);
+        if (t2 > 0 && t2 < 1) bounds[i].push(this.calculateF(t2, p0, p1, p2, p3, i));
+      }
+    }
+  }
+
+  this.shapeBoundingBox.left = bmMin.apply(null, bounds[0]);
+  this.shapeBoundingBox.top = bmMin.apply(null, bounds[1]);
+  this.shapeBoundingBox.right = bmMax.apply(null, bounds[0]);
+  this.shapeBoundingBox.bottom = bmMax.apply(null, bounds[1]);
+};
+
+HShapeElement.prototype.calculateF = function (t, p0, p1, p2, p3, i) {
+  return bmPow(1 - t, 3) * p0[i]
+        + 3 * bmPow(1 - t, 2) * t * p1[i]
+        + 3 * (1 - t) * bmPow(t, 2) * p2[i]
+        + bmPow(t, 3) * p3[i];
+};
+
+HShapeElement.prototype.calculateBoundingBox = function (itemsData, boundingBox) {
+  var i;
+  var len = itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    if (itemsData[i] && itemsData[i].sh) {
+      this.calculateShapeBoundingBox(itemsData[i], boundingBox);
+    } else if (itemsData[i] && itemsData[i].it) {
+      this.calculateBoundingBox(itemsData[i].it, boundingBox);
+    } else if (itemsData[i] && itemsData[i].style && itemsData[i].w) {
+      this.expandStrokeBoundingBox(itemsData[i].w, boundingBox);
+    }
+  }
+};
+
+HShapeElement.prototype.expandStrokeBoundingBox = function (widthProperty, boundingBox) {
+  var width = 0;
+  if (widthProperty.keyframes) {
+    for (var i = 0; i < widthProperty.keyframes.length; i += 1) {
+      var kfw = widthProperty.keyframes[i].s;
+      if (kfw > width) {
+        width = kfw;
+      }
+    }
+    width *= widthProperty.mult;
+  } else {
+    width = widthProperty.v * widthProperty.mult;
+  }
+
+  boundingBox.x -= width;
+  boundingBox.xMax += width;
+  boundingBox.y -= width;
+  boundingBox.yMax += width;
+};
+
+HShapeElement.prototype.currentBoxContains = function (box) {
+  return this.currentBBox.x <= box.x
+    && this.currentBBox.y <= box.y
+    && this.currentBBox.width + this.currentBBox.x >= box.x + box.width
+    && this.currentBBox.height + this.currentBBox.y >= box.y + box.height;
+};
+
+HShapeElement.prototype.renderInnerContent = function () {
+  this._renderShapeFrame();
+
+  if (!this.hidden && (this._isFirstFrame || this._mdf)) {
+    var tempBoundingBox = this.tempBoundingBox;
+    var max = 999999;
+    tempBoundingBox.x = max;
+    tempBoundingBox.xMax = -max;
+    tempBoundingBox.y = max;
+    tempBoundingBox.yMax = -max;
+    this.calculateBoundingBox(this.itemsData, tempBoundingBox);
+    tempBoundingBox.width = tempBoundingBox.xMax < tempBoundingBox.x ? 0 : tempBoundingBox.xMax - tempBoundingBox.x;
+    tempBoundingBox.height = tempBoundingBox.yMax < tempBoundingBox.y ? 0 : tempBoundingBox.yMax - tempBoundingBox.y;
+    // var tempBoundingBox = this.shapeCont.getBBox();
+    if (this.currentBoxContains(tempBoundingBox)) {
+      return;
+    }
+    var changed = false;
+    if (this.currentBBox.w !== tempBoundingBox.width) {
+      this.currentBBox.w = tempBoundingBox.width;
+      this.shapeCont.setAttribute('width', tempBoundingBox.width);
+      changed = true;
+    }
+    if (this.currentBBox.h !== tempBoundingBox.height) {
+      this.currentBBox.h = tempBoundingBox.height;
+      this.shapeCont.setAttribute('height', tempBoundingBox.height);
+      changed = true;
+    }
+    if (changed || this.currentBBox.x !== tempBoundingBox.x || this.currentBBox.y !== tempBoundingBox.y) {
+      this.currentBBox.w = tempBoundingBox.width;
+      this.currentBBox.h = tempBoundingBox.height;
+      this.currentBBox.x = tempBoundingBox.x;
+      this.currentBBox.y = tempBoundingBox.y;
+
+      this.shapeCont.setAttribute('viewBox', this.currentBBox.x + ' ' + this.currentBBox.y + ' ' + this.currentBBox.w + ' ' + this.currentBBox.h);
+      var shapeStyle = this.shapeCont.style;
+      var shapeTransform = 'translate(' + this.currentBBox.x + 'px,' + this.currentBBox.y + 'px)';
+      shapeStyle.transform = shapeTransform;
+      shapeStyle.webkitTransform = shapeTransform;
+    }
+  }
+};
+
+function HTextElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.textPaths = [];
+  this.currentBBox = {
+    x: 999999,
+    y: -999999,
+    h: 0,
+    w: 0,
+  };
+  this.renderType = 'svg';
+  this.isMasked = false;
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], HTextElement);
+
+HTextElement.prototype.createContent = function () {
+  this.isMasked = this.checkMasks();
+  if (this.isMasked) {
+    this.renderType = 'svg';
+    this.compW = this.comp.data.w;
+    this.compH = this.comp.data.h;
+    this.svgElement.setAttribute('width', this.compW);
+    this.svgElement.setAttribute('height', this.compH);
+    var g = createNS('g');
+    this.maskedElement.appendChild(g);
+    this.innerElem = g;
+  } else {
+    this.renderType = 'html';
+    this.innerElem = this.layerElement;
+  }
+
+  this.checkParenting();
+};
+
+HTextElement.prototype.buildNewText = function () {
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
+  var innerElemStyle = this.innerElem.style;
+  var textColor = documentData.fc ? this.buildColor(documentData.fc) : 'rgba(0,0,0,0)';
+  innerElemStyle.fill = textColor;
+  innerElemStyle.color = textColor;
+  if (documentData.sc) {
+    innerElemStyle.stroke = this.buildColor(documentData.sc);
+    innerElemStyle.strokeWidth = documentData.sw + 'px';
+  }
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (!this.globalData.fontManager.chars) {
+    innerElemStyle.fontSize = documentData.finalSize + 'px';
+    innerElemStyle.lineHeight = documentData.finalSize + 'px';
+    if (fontData.fClass) {
+      this.innerElem.className = fontData.fClass;
+    } else {
+      innerElemStyle.fontFamily = fontData.fFamily;
+      var fWeight = documentData.fWeight;
+      var fStyle = documentData.fStyle;
+      innerElemStyle.fontStyle = fStyle;
+      innerElemStyle.fontWeight = fWeight;
+    }
+  }
+  var i;
+  var len;
+
+  var letters = documentData.l;
+  len = letters.length;
+  var tSpan;
+  var tParent;
+  var tCont;
+  var matrixHelper = this.mHelper;
+  var shapes;
+  var shapeStr = '';
+  var cnt = 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.globalData.fontManager.chars) {
+      if (!this.textPaths[cnt]) {
+        tSpan = createNS('path');
+        tSpan.setAttribute('stroke-linecap', lineCapEnum[1]);
+        tSpan.setAttribute('stroke-linejoin', lineJoinEnum[2]);
+        tSpan.setAttribute('stroke-miterlimit', '4');
+      } else {
+        tSpan = this.textPaths[cnt];
+      }
+      if (!this.isMasked) {
+        if (this.textSpans[cnt]) {
+          tParent = this.textSpans[cnt];
+          tCont = tParent.children[0];
+        } else {
+          tParent = createTag('div');
+          tParent.style.lineHeight = 0;
+          tCont = createNS('svg');
+          tCont.appendChild(tSpan);
+          styleDiv(tParent);
+        }
+      }
+    } else if (!this.isMasked) {
+      if (this.textSpans[cnt]) {
+        tParent = this.textSpans[cnt];
+        tSpan = this.textPaths[cnt];
+      } else {
+        tParent = createTag('span');
+        styleDiv(tParent);
+        tSpan = createTag('span');
+        styleDiv(tSpan);
+        tParent.appendChild(tSpan);
+      }
+    } else {
+      tSpan = this.textPaths[cnt] ? this.textPaths[cnt] : createNS('text');
+    }
+    // tSpan.setAttribute('visibility', 'hidden');
+    if (this.globalData.fontManager.chars) {
+      var charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
+      var shapeData;
+      if (charData) {
+        shapeData = charData.data;
+      } else {
+        shapeData = null;
+      }
+      matrixHelper.reset();
+      if (shapeData && shapeData.shapes && shapeData.shapes.length) {
+        shapes = shapeData.shapes[0].it;
+        matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
+        shapeStr = this.createPathShape(matrixHelper, shapes);
+        tSpan.setAttribute('d', shapeStr);
+      }
+      if (!this.isMasked) {
+        this.innerElem.appendChild(tParent);
+        if (shapeData && shapeData.shapes) {
+          // document.body.appendChild is needed to get exact measure of shape
+          document.body.appendChild(tCont);
+          var boundingBox = tCont.getBBox();
+          tCont.setAttribute('width', boundingBox.width + 2);
+          tCont.setAttribute('height', boundingBox.height + 2);
+          tCont.setAttribute('viewBox', (boundingBox.x - 1) + ' ' + (boundingBox.y - 1) + ' ' + (boundingBox.width + 2) + ' ' + (boundingBox.height + 2));
+          var tContStyle = tCont.style;
+          var tContTranslation = 'translate(' + (boundingBox.x - 1) + 'px,' + (boundingBox.y - 1) + 'px)';
+          tContStyle.transform = tContTranslation;
+          tContStyle.webkitTransform = tContTranslation;
+
+          letters[i].yOffset = boundingBox.y - 1;
+        } else {
+          tCont.setAttribute('width', 1);
+          tCont.setAttribute('height', 1);
+        }
+        tParent.appendChild(tCont);
+      } else {
+        this.innerElem.appendChild(tSpan);
+      }
+    } else {
+      tSpan.textContent = letters[i].val;
+      tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      if (!this.isMasked) {
+        this.innerElem.appendChild(tParent);
+        //
+        var tStyle = tSpan.style;
+        var tSpanTranslation = 'translate3d(0,' + -documentData.finalSize / 1.2 + 'px,0)';
+        tStyle.transform = tSpanTranslation;
+        tStyle.webkitTransform = tSpanTranslation;
+      } else {
+        this.innerElem.appendChild(tSpan);
+      }
+    }
+    //
+    if (!this.isMasked) {
+      this.textSpans[cnt] = tParent;
+    } else {
+      this.textSpans[cnt] = tSpan;
+    }
+    this.textSpans[cnt].style.display = 'block';
+    this.textPaths[cnt] = tSpan;
+    cnt += 1;
+  }
+  while (cnt < this.textSpans.length) {
+    this.textSpans[cnt].style.display = 'none';
+    cnt += 1;
+  }
+};
+
+HTextElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  var svgStyle;
+  if (this.data.singleShape) {
+    if (!this._isFirstFrame && !this.lettersChangedFlag) {
+      return;
+    } if (this.isMasked && this.finalTransform._matMdf) {
+      // Todo Benchmark if using this is better than getBBox
+      this.svgElement.setAttribute('viewBox', -this.finalTransform.mProp.p.v[0] + ' ' + -this.finalTransform.mProp.p.v[1] + ' ' + this.compW + ' ' + this.compH);
+      svgStyle = this.svgElement.style;
+      var translation = 'translate(' + -this.finalTransform.mProp.p.v[0] + 'px,' + -this.finalTransform.mProp.p.v[1] + 'px)';
+      svgStyle.transform = translation;
+      svgStyle.webkitTransform = translation;
+    }
+  }
+
+  this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+  if (!this.lettersChangedFlag && !this.textAnimator.lettersChangedFlag) {
+    return;
+  }
+  var i;
+  var len;
+  var count = 0;
+  var renderedLetters = this.textAnimator.renderedLetters;
+
+  var letters = this.textProperty.currentData.l;
+
+  len = letters.length;
+  var renderedLetter;
+  var textSpan;
+  var textPath;
+  for (i = 0; i < len; i += 1) {
+    if (letters[i].n) {
+      count += 1;
+    } else {
+      textSpan = this.textSpans[i];
+      textPath = this.textPaths[i];
+      renderedLetter = renderedLetters[count];
+      count += 1;
+      if (renderedLetter._mdf.m) {
+        if (!this.isMasked) {
+          textSpan.style.webkitTransform = renderedLetter.m;
+          textSpan.style.transform = renderedLetter.m;
+        } else {
+          textSpan.setAttribute('transform', renderedLetter.m);
+        }
+      }
+      /// /textSpan.setAttribute('opacity',renderedLetter.o);
+      textSpan.style.opacity = renderedLetter.o;
+      if (renderedLetter.sw && renderedLetter._mdf.sw) {
+        textPath.setAttribute('stroke-width', renderedLetter.sw);
+      }
+      if (renderedLetter.sc && renderedLetter._mdf.sc) {
+        textPath.setAttribute('stroke', renderedLetter.sc);
+      }
+      if (renderedLetter.fc && renderedLetter._mdf.fc) {
+        textPath.setAttribute('fill', renderedLetter.fc);
+        textPath.style.color = renderedLetter.fc;
+      }
+    }
+  }
+
+  if (this.innerElem.getBBox && !this.hidden && (this._isFirstFrame || this._mdf)) {
+    var boundingBox = this.innerElem.getBBox();
+
+    if (this.currentBBox.w !== boundingBox.width) {
+      this.currentBBox.w = boundingBox.width;
+      this.svgElement.setAttribute('width', boundingBox.width);
+    }
+    if (this.currentBBox.h !== boundingBox.height) {
+      this.currentBBox.h = boundingBox.height;
+      this.svgElement.setAttribute('height', boundingBox.height);
+    }
+
+    var margin = 1;
+    if (this.currentBBox.w !== (boundingBox.width + margin * 2) || this.currentBBox.h !== (boundingBox.height + margin * 2) || this.currentBBox.x !== (boundingBox.x - margin) || this.currentBBox.y !== (boundingBox.y - margin)) {
+      this.currentBBox.w = boundingBox.width + margin * 2;
+      this.currentBBox.h = boundingBox.height + margin * 2;
+      this.currentBBox.x = boundingBox.x - margin;
+      this.currentBBox.y = boundingBox.y - margin;
+
+      this.svgElement.setAttribute('viewBox', this.currentBBox.x + ' ' + this.currentBBox.y + ' ' + this.currentBBox.w + ' ' + this.currentBBox.h);
+      svgStyle = this.svgElement.style;
+      var svgTransform = 'translate(' + this.currentBBox.x + 'px,' + this.currentBBox.y + 'px)';
+      svgStyle.transform = svgTransform;
+      svgStyle.webkitTransform = svgTransform;
+    }
+  }
+};
+
+function HCameraElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initHierarchy();
+  var getProp = PropertyFactory.getProp;
+  this.pe = getProp(this, data.pe, 0, 0, this);
+  if (data.ks.p.s) {
+    this.px = getProp(this, data.ks.p.x, 1, 0, this);
+    this.py = getProp(this, data.ks.p.y, 1, 0, this);
+    this.pz = getProp(this, data.ks.p.z, 1, 0, this);
+  } else {
+    this.p = getProp(this, data.ks.p, 1, 0, this);
+  }
+  if (data.ks.a) {
+    this.a = getProp(this, data.ks.a, 1, 0, this);
+  }
+  if (data.ks.or.k.length && data.ks.or.k[0].to) {
+    var i;
+    var len = data.ks.or.k.length;
+    for (i = 0; i < len; i += 1) {
+      data.ks.or.k[i].to = null;
+      data.ks.or.k[i].ti = null;
+    }
+  }
+  this.or = getProp(this, data.ks.or, 1, degToRads, this);
+  this.or.sh = true;
+  this.rx = getProp(this, data.ks.rx, 0, degToRads, this);
+  this.ry = getProp(this, data.ks.ry, 0, degToRads, this);
+  this.rz = getProp(this, data.ks.rz, 0, degToRads, this);
+  this.mat = new Matrix();
+  this._prevMat = new Matrix();
+  this._isFirstFrame = true;
+
+  // TODO: find a better way to make the HCamera element to be compatible with the LayerInterface and TransformInterface.
+  this.finalTransform = {
+    mProp: this,
+  };
+}
+extendPrototype([BaseElement, FrameElement, HierarchyElement], HCameraElement);
+
+HCameraElement.prototype.setup = function () {
+  var i;
+  var len = this.comp.threeDElements.length;
+  var comp;
+  var perspectiveStyle;
+  var containerStyle;
+  for (i = 0; i < len; i += 1) {
+    // [perspectiveElem,container]
+    comp = this.comp.threeDElements[i];
+    if (comp.type === '3d') {
+      perspectiveStyle = comp.perspectiveElem.style;
+      containerStyle = comp.container.style;
+      var perspective = this.pe.v + 'px';
+      var origin = '0px 0px 0px';
+      var matrix = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)';
+      perspectiveStyle.perspective = perspective;
+      perspectiveStyle.webkitPerspective = perspective;
+      containerStyle.transformOrigin = origin;
+      containerStyle.mozTransformOrigin = origin;
+      containerStyle.webkitTransformOrigin = origin;
+      perspectiveStyle.transform = matrix;
+      perspectiveStyle.webkitTransform = matrix;
+    }
+  }
+};
+
+HCameraElement.prototype.createElements = function () {
+};
+
+HCameraElement.prototype.hide = function () {
+};
+
+HCameraElement.prototype.renderFrame = function () {
+  var _mdf = this._isFirstFrame;
+  var i;
+  var len;
+  if (this.hierarchy) {
+    len = this.hierarchy.length;
+    for (i = 0; i < len; i += 1) {
+      _mdf = this.hierarchy[i].finalTransform.mProp._mdf || _mdf;
+    }
+  }
+  if (_mdf || this.pe._mdf || (this.p && this.p._mdf) || (this.px && (this.px._mdf || this.py._mdf || this.pz._mdf)) || this.rx._mdf || this.ry._mdf || this.rz._mdf || this.or._mdf || (this.a && this.a._mdf)) {
+    this.mat.reset();
+
+    if (this.hierarchy) {
+      len = this.hierarchy.length - 1;
+      for (i = len; i >= 0; i -= 1) {
+        var mTransf = this.hierarchy[i].finalTransform.mProp;
+        this.mat.translate(-mTransf.p.v[0], -mTransf.p.v[1], mTransf.p.v[2]);
+        this.mat.rotateX(-mTransf.or.v[0]).rotateY(-mTransf.or.v[1]).rotateZ(mTransf.or.v[2]);
+        this.mat.rotateX(-mTransf.rx.v).rotateY(-mTransf.ry.v).rotateZ(mTransf.rz.v);
+        this.mat.scale(1 / mTransf.s.v[0], 1 / mTransf.s.v[1], 1 / mTransf.s.v[2]);
+        this.mat.translate(mTransf.a.v[0], mTransf.a.v[1], mTransf.a.v[2]);
+      }
+    }
+    if (this.p) {
+      this.mat.translate(-this.p.v[0], -this.p.v[1], this.p.v[2]);
+    } else {
+      this.mat.translate(-this.px.v, -this.py.v, this.pz.v);
+    }
+    if (this.a) {
+      var diffVector;
+      if (this.p) {
+        diffVector = [this.p.v[0] - this.a.v[0], this.p.v[1] - this.a.v[1], this.p.v[2] - this.a.v[2]];
+      } else {
+        diffVector = [this.px.v - this.a.v[0], this.py.v - this.a.v[1], this.pz.v - this.a.v[2]];
+      }
+      var mag = Math.sqrt(Math.pow(diffVector[0], 2) + Math.pow(diffVector[1], 2) + Math.pow(diffVector[2], 2));
+      // var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
+      var lookDir = [diffVector[0] / mag, diffVector[1] / mag, diffVector[2] / mag];
+      var lookLengthOnXZ = Math.sqrt(lookDir[2] * lookDir[2] + lookDir[0] * lookDir[0]);
+      var mRotationX = (Math.atan2(lookDir[1], lookLengthOnXZ));
+      var mRotationY = (Math.atan2(lookDir[0], -lookDir[2]));
+      this.mat.rotateY(mRotationY).rotateX(-mRotationX);
+    }
+    this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v);
+    this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]);
+    this.mat.translate(this.globalData.compSize.w / 2, this.globalData.compSize.h / 2, 0);
+    this.mat.translate(0, 0, this.pe.v);
+
+    var hasMatrixChanged = !this._prevMat.equals(this.mat);
+    if ((hasMatrixChanged || this.pe._mdf) && this.comp.threeDElements) {
+      len = this.comp.threeDElements.length;
+      var comp;
+      var perspectiveStyle;
+      var containerStyle;
+      for (i = 0; i < len; i += 1) {
+        comp = this.comp.threeDElements[i];
+        if (comp.type === '3d') {
+          if (hasMatrixChanged) {
+            var matValue = this.mat.toCSS();
+            containerStyle = comp.container.style;
+            containerStyle.transform = matValue;
+            containerStyle.webkitTransform = matValue;
+          }
+          if (this.pe._mdf) {
+            perspectiveStyle = comp.perspectiveElem.style;
+            perspectiveStyle.perspective = this.pe.v + 'px';
+            perspectiveStyle.webkitPerspective = this.pe.v + 'px';
+          }
+        }
+      }
+      this.mat.clone(this._prevMat);
+    }
+  }
+  this._isFirstFrame = false;
+};
+
+HCameraElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+HCameraElement.prototype.destroy = function () {
+};
+HCameraElement.prototype.getBaseElement = function () { return null; };
+
+function HImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, HBaseElement, HSolidElement, HierarchyElement, FrameElement, RenderableElement], HImageElement);
+
+HImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  var img = new Image();
+
+  if (this.data.hasMask) {
+    this.imageElem = createNS('image');
+    this.imageElem.setAttribute('width', this.assetData.w + 'px');
+    this.imageElem.setAttribute('height', this.assetData.h + 'px');
+    this.imageElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+    this.layerElement.appendChild(this.imageElem);
+    this.baseElement.setAttribute('width', this.assetData.w);
+    this.baseElement.setAttribute('height', this.assetData.h);
+  } else {
+    this.layerElement.appendChild(img);
+  }
+  img.crossOrigin = 'anonymous';
+  img.src = assetPath;
+  if (this.data.ln) {
+    this.baseElement.setAttribute('id', this.data.ln);
+  }
+};
+
+function HybridRendererBase(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),
+    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], HybridRendererBase);
+
+HybridRendererBase.prototype.buildItem = SVGRenderer.prototype.buildItem;
+
+HybridRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+  }
+};
+
+HybridRendererBase.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;
+      var nextLayer;
+      var 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);
+  }
+};
+
+HybridRendererBase.prototype.createShape = function (data) {
+  if (!this.supports3d) {
+    return new SVGShapeElement(data, this.globalData, this);
+  }
+  return new HShapeElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createText = function (data) {
+  if (!this.supports3d) {
+    return new SVGTextLottieElement(data, this.globalData, this);
+  }
+  return new HTextElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createCamera = function (data) {
+  this.camera = new HCameraElement(data, this.globalData, this);
+  return this.camera;
+};
+
+HybridRendererBase.prototype.createImage = function (data) {
+  if (!this.supports3d) {
+    return new IImageElement(data, this.globalData, this);
+  }
+  return new HImageElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createSolid = function (data) {
+  if (!this.supports3d) {
+    return new ISolidElement(data, this.globalData, this);
+  }
+  return new HSolidElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
+
+HybridRendererBase.prototype.getThreeDContainerByPos = function (pos) {
+  var i = 0;
+  var 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;
+  }
+  return null;
+};
+
+HybridRendererBase.prototype.createThreeDContainer = function (pos, type) {
+  var perspectiveElem = createTag('div');
+  var style;
+  var containerStyle;
+  styleDiv(perspectiveElem);
+  var container = createTag('div');
+  styleDiv(container);
+  if (type === '3d') {
+    style = perspectiveElem.style;
+    style.width = this.globalData.compSize.w + 'px';
+    style.height = this.globalData.compSize.h + 'px';
+    var center = '50% 50%';
+    style.webkitTransformOrigin = center;
+    style.mozTransformOrigin = center;
+    style.transformOrigin = center;
+    containerStyle = container.style;
+    var matrix = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)';
+    containerStyle.transform = matrix;
+    containerStyle.webkitTransform = matrix;
+  }
+
+  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;
+};
+
+HybridRendererBase.prototype.build3dContainers = function () {
+  var i;
+  var 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 -= 1) {
+    this.resizerElem.appendChild(this.threeDElements[i].perspectiveElem);
+  }
+};
+
+HybridRendererBase.prototype.addTo3dContainer = function (elem, pos) {
+  var i = 0;
+  var 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;
+  }
+};
+
+HybridRendererBase.prototype.configAnimation = function (animData) {
+  var resizerElem = createTag('div');
+  var wrapper = this.animationItem.wrapper;
+  var style = resizerElem.style;
+  style.width = animData.w + 'px';
+  style.height = animData.h + 'px';
+  this.resizerElem = resizerElem;
+  styleDiv(resizerElem);
+  style.transformStyle = 'flat';
+  style.mozTransformStyle = 'flat';
+  style.webkitTransformStyle = 'flat';
+  if (this.renderConfig.className) {
+    resizerElem.setAttribute('class', this.renderConfig.className);
+  }
+  wrapper.appendChild(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();
+};
+
+HybridRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.animationItem.container = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+HybridRendererBase.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;
+  var sy;
+  var tx;
+  var 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;
+  }
+  var style = this.resizerElem.style;
+  style.webkitTransform = 'matrix3d(' + sx + ',0,0,0,0,' + sy + ',0,0,0,0,1,0,' + tx + ',' + ty + ',0,1)';
+  style.transform = style.webkitTransform;
+};
+
+HybridRendererBase.prototype.renderFrame = SVGRenderer.prototype.renderFrame;
+
+HybridRendererBase.prototype.hide = function () {
+  this.resizerElem.style.display = 'none';
+};
+
+HybridRendererBase.prototype.show = function () {
+  this.resizerElem.style.display = 'block';
+};
+
+HybridRendererBase.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;
+    var len = this.threeDElements.length;
+    for (i = 0; i < len; i += 1) {
+      var style = this.threeDElements[i].perspectiveElem.style;
+      style.webkitPerspective = Math.sqrt(Math.pow(cWidth, 2) + Math.pow(cHeight, 2)) + 'px';
+      style.perspective = style.webkitPerspective;
+    }
+  }
+};
+
+HybridRendererBase.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var 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);
+    }
+  }
+};
+
+function HCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = !data.hasMask;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([HybridRendererBase, ICompElement, HBaseElement], HCompElement);
+HCompElement.prototype._createBaseContainerElements = HCompElement.prototype.createContainerElements;
+
+HCompElement.prototype.createContainerElements = function () {
+  this._createBaseContainerElements();
+  // divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
+  if (this.data.hasMask) {
+    this.svgElement.setAttribute('width', this.data.w);
+    this.svgElement.setAttribute('height', this.data.h);
+    this.transformedElement = this.baseElement;
+  } else {
+    this.transformedElement = this.layerElement;
+  }
+};
+
+HCompElement.prototype.addTo3dContainer = function (elem, pos) {
+  var j = 0;
+  var nextElement;
+  while (j < pos) {
+    if (this.elements[j] && this.elements[j].getBaseElement) {
+      nextElement = this.elements[j].getBaseElement();
+    }
+    j += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(elem, nextElement);
+  } else {
+    this.layerElement.appendChild(elem);
+  }
+};
+
+HCompElement.prototype.createComp = function (data) {
+  if (!this.supports3d) {
+    return new SVGCompElement(data, this.globalData, this);
+  }
+  return new HCompElement(data, this.globalData, this);
+};
+
+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),
+    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%',
+    },
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+  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([HybridRendererBase], HybridRenderer);
+
+HybridRenderer.prototype.createComp = function (data) {
+  if (!this.supports3d) {
+    return new SVGCompElement(data, this.globalData, this);
+  }
+  return new HCompElement(data, this.globalData, this);
+};
+
+const CompExpressionInterface = (function () {
+  return function (comp) {
+    function _thisLayerFunction(name) {
+      var i = 0;
+      var len = comp.layers.length;
+      while (i < len) {
+        if (comp.layers[i].nm === name || comp.layers[i].ind === name) {
+          return comp.elements[i].layerInterface;
+        }
+        i += 1;
+      }
+      return null;
+      // return {active:false};
+    }
+    Object.defineProperty(_thisLayerFunction, '_name', { value: comp.data.nm });
+    _thisLayerFunction.layer = _thisLayerFunction;
+    _thisLayerFunction.pixelAspect = 1;
+    _thisLayerFunction.height = comp.data.h || comp.globalData.compSize.h;
+    _thisLayerFunction.width = comp.data.w || comp.globalData.compSize.w;
+    _thisLayerFunction.pixelAspect = 1;
+    _thisLayerFunction.frameDuration = 1 / comp.globalData.frameRate;
+    _thisLayerFunction.displayStartTime = 0;
+    _thisLayerFunction.numLayers = comp.layers.length;
+    return _thisLayerFunction;
+  };
+}());
+
+/* eslint-disable */
+/*
+ Copyright 2014 David Bau.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ */
+
+function seedRandom(pool, math) {
+//
+// The following constants are related to IEEE 754 limits.
+//
+    var global = this,
+        width = 256,        // each RC4 output is 0 <= x < 256
+        chunks = 6,         // at least six RC4 outputs for each double
+        digits = 52,        // there are 52 significant digits in a double
+        rngname = 'random', // rngname: name for Math.random and Math.seedrandom
+        startdenom = math.pow(width, chunks),
+        significance = math.pow(2, digits),
+        overflow = significance * 2,
+        mask = width - 1,
+        nodecrypto;         // node.js crypto module, initialized at the bottom.
+
+//
+// seedrandom()
+// This is the seedrandom function described above.
+//
+    function seedrandom(seed, options, callback) {
+        var key = [];
+        options = (options === true) ? { entropy: true } : (options || {});
+
+        // Flatten the seed string or build one from local entropy if needed.
+        var shortseed = mixkey(flatten(
+            options.entropy ? [seed, tostring(pool)] :
+                (seed === null) ? autoseed() : seed, 3), key);
+
+        // Use the seed to initialize an ARC4 generator.
+        var arc4 = new ARC4(key);
+
+        // This function returns a random double in [0, 1) that contains
+        // randomness in every bit of the mantissa of the IEEE 754 value.
+        var prng = function() {
+            var n = arc4.g(chunks),             // Start with a numerator n < 2 ^ 48
+                d = startdenom,                 //   and denominator d = 2 ^ 48.
+                x = 0;                          //   and no 'extra last byte'.
+            while (n < significance) {          // Fill up all significant digits by
+                n = (n + x) * width;              //   shifting numerator and
+                d *= width;                       //   denominator and generating a
+                x = arc4.g(1);                    //   new least-significant-byte.
+            }
+            while (n >= overflow) {             // To avoid rounding up, before adding
+                n /= 2;                           //   last byte, shift everything
+                d /= 2;                           //   right using integer math until
+                x >>>= 1;                         //   we have exactly the desired bits.
+            }
+            return (n + x) / d;                 // Form the number within [0, 1).
+        };
+
+        prng.int32 = function() { return arc4.g(4) | 0; };
+        prng.quick = function() { return arc4.g(4) / 0x100000000; };
+        prng.double = prng;
+
+        // Mix the randomness into accumulated entropy.
+        mixkey(tostring(arc4.S), pool);
+
+        // Calling convention: what to return as a function of prng, seed, is_math.
+        return (options.pass || callback ||
+        function(prng, seed, is_math_call, state) {
+            if (state) {
+                // Load the arc4 state from the given state if it has an S array.
+                if (state.S) { copy(state, arc4); }
+                // Only provide the .state method if requested via options.state.
+                prng.state = function() { return copy(arc4, {}); };
+            }
+
+            // If called as a method of Math (Math.seedrandom()), mutate
+            // Math.random because that is how seedrandom.js has worked since v1.0.
+            if (is_math_call) { math[rngname] = prng; return seed; }
+
+            // Otherwise, it is a newer calling convention, so return the
+            // prng directly.
+            else return prng;
+        })(
+            prng,
+            shortseed,
+            'global' in options ? options.global : (this == math),
+            options.state);
+    }
+    math['seed' + rngname] = seedrandom;
+
+//
+// ARC4
+//
+// An ARC4 implementation.  The constructor takes a key in the form of
+// an array of at most (width) integers that should be 0 <= x < (width).
+//
+// The g(count) method returns a pseudorandom integer that concatenates
+// the next (count) outputs from ARC4.  Its return value is a number x
+// that is in the range 0 <= x < (width ^ count).
+//
+    function ARC4(key) {
+        var t, keylen = key.length,
+            me = this, i = 0, j = me.i = me.j = 0, s = me.S = [];
+
+        // The empty key [] is treated as [0].
+        if (!keylen) { key = [keylen++]; }
+
+        // Set up S using the standard key scheduling algorithm.
+        while (i < width) {
+            s[i] = i++;
+        }
+        for (i = 0; i < width; i++) {
+            s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))];
+            s[j] = t;
+        }
+
+        // The "g" method returns the next (count) outputs as one number.
+        me.g = function(count) {
+            // Using instance members instead of closure state nearly doubles speed.
+            var t, r = 0,
+                i = me.i, j = me.j, s = me.S;
+            while (count--) {
+                t = s[i = mask & (i + 1)];
+                r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))];
+            }
+            me.i = i; me.j = j;
+            return r;
+            // For robust unpredictability, the function call below automatically
+            // discards an initial batch of values.  This is called RC4-drop[256].
+            // See http://google.com/search?q=rsa+fluhrer+response&btnI
+        };
+    }
+
+//
+// copy()
+// Copies internal state of ARC4 to or from a plain object.
+//
+    function copy(f, t) {
+        t.i = f.i;
+        t.j = f.j;
+        t.S = f.S.slice();
+        return t;
+    }
+
+//
+// flatten()
+// Converts an object tree to nested arrays of strings.
+//
+    function flatten(obj, depth) {
+        var result = [], typ = (typeof obj), prop;
+        if (depth && typ == 'object') {
+            for (prop in obj) {
+                try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}
+            }
+        }
+        return (result.length ? result : typ == 'string' ? obj : obj + '\0');
+    }
+
+//
+// mixkey()
+// Mixes a string seed into a key that is an array of integers, and
+// returns a shortened string seed that is equivalent to the result key.
+//
+    function mixkey(seed, key) {
+        var stringseed = seed + '', smear, j = 0;
+        while (j < stringseed.length) {
+            key[mask & j] =
+                mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++));
+        }
+        return tostring(key);
+    }
+
+//
+// autoseed()
+// Returns an object for autoseeding, using window.crypto and Node crypto
+// module if available.
+//
+    function autoseed() {
+        try {
+            if (nodecrypto) { return tostring(nodecrypto.randomBytes(width)); }
+            var out = new Uint8Array(width);
+            (global.crypto || global.msCrypto).getRandomValues(out);
+            return tostring(out);
+        } catch (e) {
+            var browser = global.navigator,
+                plugins = browser && browser.plugins;
+            return [+new Date(), global, plugins, global.screen, tostring(pool)];
+        }
+    }
+
+//
+// tostring()
+// Converts an array of charcodes to a string
+//
+    function tostring(a) {
+        return String.fromCharCode.apply(0, a);
+    }
+
+//
+// When seedrandom.js is loaded, we immediately mix a few bits
+// from the built-in RNG into the entropy pool.  Because we do
+// not want to interfere with deterministic PRNG state later,
+// seedrandom will not call math.random on its own again after
+// initialization.
+//
+    mixkey(math.random(), pool);
+
+//
+// Nodejs and AMD support: export the implementation as a module using
+// either convention.
+//
+
+// End anonymous scope, and pass initial values.
+};
+
+function initialize$2(BMMath) {
+    seedRandom([], BMMath);
+}
+
+var propTypes = {
+  SHAPE: 'shape',
+};
+
+/* eslint-disable camelcase */
+
+const ExpressionManager = (function () {
+  'use strict';
+
+  var ob = {};
+  var Math = BMMath;
+  var window = null;
+  var document = null;
+  var XMLHttpRequest = null;
+  var fetch = null;
+  var frames = null;
+  var _lottieGlobal = {};
+  initialize$2(BMMath);
+
+  function resetFrame() {
+    _lottieGlobal = {};
+  }
+
+  function $bm_isInstanceOfArray(arr) {
+    return arr.constructor === Array || arr.constructor === Float32Array;
+  }
+
+  function isNumerable(tOfV, v) {
+    return tOfV === 'number' || v instanceof Number || tOfV === 'boolean' || tOfV === 'string';
+  }
+
+  function $bm_neg(a) {
+    var tOfA = typeof a;
+    if (tOfA === 'number' || a instanceof Number || tOfA === 'boolean') {
+      return -a;
+    }
+    if ($bm_isInstanceOfArray(a)) {
+      var i;
+      var lenA = a.length;
+      var retArr = [];
+      for (i = 0; i < lenA; i += 1) {
+        retArr[i] = -a[i];
+      }
+      return retArr;
+    }
+    if (a.propType) {
+      return a.v;
+    }
+    return -a;
+  }
+
+  var easeInBez = BezierFactory.getBezierEasing(0.333, 0, 0.833, 0.833, 'easeIn').get;
+  var easeOutBez = BezierFactory.getBezierEasing(0.167, 0.167, 0.667, 1, 'easeOut').get;
+  var easeInOutBez = BezierFactory.getBezierEasing(0.33, 0, 0.667, 1, 'easeInOut').get;
+
+  function sum(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    if ((isNumerable(tOfA, a) && isNumerable(tOfB, b)) || tOfA === 'string' || tOfB === 'string') {
+      return a + b;
+    }
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      a = a.slice(0);
+      a[0] += b;
+      return a;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      b = b.slice(0);
+      b[0] = a + b[0];
+      return b;
+    }
+    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
+      var i = 0;
+      var lenA = a.length;
+      var lenB = b.length;
+      var retArr = [];
+      while (i < lenA || i < lenB) {
+        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
+          retArr[i] = a[i] + b[i];
+        } else {
+          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
+        }
+        i += 1;
+      }
+      return retArr;
+    }
+    return 0;
+  }
+  var add = sum;
+
+  function sub(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      if (tOfA === 'string') {
+        a = parseInt(a, 10);
+      }
+      if (tOfB === 'string') {
+        b = parseInt(b, 10);
+      }
+      return a - b;
+    }
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      a = a.slice(0);
+      a[0] -= b;
+      return a;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      b = b.slice(0);
+      b[0] = a - b[0];
+      return b;
+    }
+    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
+      var i = 0;
+      var lenA = a.length;
+      var lenB = b.length;
+      var retArr = [];
+      while (i < lenA || i < lenB) {
+        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
+          retArr[i] = a[i] - b[i];
+        } else {
+          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
+        }
+        i += 1;
+      }
+      return retArr;
+    }
+    return 0;
+  }
+
+  function mul(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    var arr;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      return a * b;
+    }
+
+    var i;
+    var len;
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      len = a.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a[i] * b;
+      }
+      return arr;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      len = b.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a * b[i];
+      }
+      return arr;
+    }
+    return 0;
+  }
+
+  function div(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    var arr;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      return a / b;
+    }
+    var i;
+    var len;
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      len = a.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a[i] / b;
+      }
+      return arr;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      len = b.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a / b[i];
+      }
+      return arr;
+    }
+    return 0;
+  }
+  function mod(a, b) {
+    if (typeof a === 'string') {
+      a = parseInt(a, 10);
+    }
+    if (typeof b === 'string') {
+      b = parseInt(b, 10);
+    }
+    return a % b;
+  }
+  var $bm_sum = sum;
+  var $bm_sub = sub;
+  var $bm_mul = mul;
+  var $bm_div = div;
+  var $bm_mod = mod;
+
+  function clamp(num, min, max) {
+    if (min > max) {
+      var mm = max;
+      max = min;
+      min = mm;
+    }
+    return Math.min(Math.max(num, min), max);
+  }
+
+  function radiansToDegrees(val) {
+    return val / degToRads;
+  }
+  var radians_to_degrees = radiansToDegrees;
+
+  function degreesToRadians(val) {
+    return val * degToRads;
+  }
+  var degrees_to_radians = radiansToDegrees;
+
+  var helperLengthArray = [0, 0, 0, 0, 0, 0];
+
+  function length(arr1, arr2) {
+    if (typeof arr1 === 'number' || arr1 instanceof Number) {
+      arr2 = arr2 || 0;
+      return Math.abs(arr1 - arr2);
+    }
+    if (!arr2) {
+      arr2 = helperLengthArray;
+    }
+    var i;
+    var len = Math.min(arr1.length, arr2.length);
+    var addedLength = 0;
+    for (i = 0; i < len; i += 1) {
+      addedLength += Math.pow(arr2[i] - arr1[i], 2);
+    }
+    return Math.sqrt(addedLength);
+  }
+
+  function normalize(vec) {
+    return div(vec, length(vec));
+  }
+
+  function rgbToHsl(val) {
+    var r = val[0]; var g = val[1]; var b = val[2];
+    var max = Math.max(r, g, b);
+    var min = Math.min(r, g, b);
+    var h;
+    var s;
+    var l = (max + min) / 2;
+
+    if (max === min) {
+      h = 0; // achromatic
+      s = 0; // achromatic
+    } else {
+      var d = max - min;
+      s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+      switch (max) {
+        case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+        case g: h = (b - r) / d + 2; break;
+        case b: h = (r - g) / d + 4; break;
+        default: break;
+      }
+      h /= 6;
+    }
+
+    return [h, s, l, val[3]];
+  }
+
+  function hue2rgb(p, q, t) {
+    if (t < 0) t += 1;
+    if (t > 1) t -= 1;
+    if (t < 1 / 6) return p + (q - p) * 6 * t;
+    if (t < 1 / 2) return q;
+    if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
+    return p;
+  }
+
+  function hslToRgb(val) {
+    var h = val[0];
+    var s = val[1];
+    var l = val[2];
+
+    var r;
+    var g;
+    var b;
+
+    if (s === 0) {
+      r = l; // achromatic
+      b = l; // achromatic
+      g = l; // achromatic
+    } else {
+      var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+      var p = 2 * l - q;
+      r = hue2rgb(p, q, h + 1 / 3);
+      g = hue2rgb(p, q, h);
+      b = hue2rgb(p, q, h - 1 / 3);
+    }
+
+    return [r, g, b, val[3]];
+  }
+
+  function linear(t, tMin, tMax, value1, value2) {
+    if (value1 === undefined || value2 === undefined) {
+      value1 = tMin;
+      value2 = tMax;
+      tMin = 0;
+      tMax = 1;
+    }
+    if (tMax < tMin) {
+      var _tMin = tMax;
+      tMax = tMin;
+      tMin = _tMin;
+    }
+    if (t <= tMin) {
+      return value1;
+    } if (t >= tMax) {
+      return value2;
+    }
+    var perc = tMax === tMin ? 0 : (t - tMin) / (tMax - tMin);
+    if (!value1.length) {
+      return value1 + (value2 - value1) * perc;
+    }
+    var i;
+    var len = value1.length;
+    var arr = createTypedArray('float32', len);
+    for (i = 0; i < len; i += 1) {
+      arr[i] = value1[i] + (value2[i] - value1[i]) * perc;
+    }
+    return arr;
+  }
+  function random(min, max) {
+    if (max === undefined) {
+      if (min === undefined) {
+        min = 0;
+        max = 1;
+      } else {
+        max = min;
+        min = undefined;
+      }
+    }
+    if (max.length) {
+      var i;
+      var len = max.length;
+      if (!min) {
+        min = createTypedArray('float32', len);
+      }
+      var arr = createTypedArray('float32', len);
+      var rnd = BMMath.random();
+      for (i = 0; i < len; i += 1) {
+        arr[i] = min[i] + rnd * (max[i] - min[i]);
+      }
+      return arr;
+    }
+    if (min === undefined) {
+      min = 0;
+    }
+    var rndm = BMMath.random();
+    return min + rndm * (max - min);
+  }
+
+  function createPath(points, inTangents, outTangents, closed) {
+    var i;
+    var len = points.length;
+    var path = shapePool.newElement();
+    path.setPathData(!!closed, len);
+    var arrPlaceholder = [0, 0];
+    var inVertexPoint;
+    var outVertexPoint;
+    for (i = 0; i < len; i += 1) {
+      inVertexPoint = (inTangents && inTangents[i]) ? inTangents[i] : arrPlaceholder;
+      outVertexPoint = (outTangents && outTangents[i]) ? outTangents[i] : arrPlaceholder;
+      path.setTripleAt(points[i][0], points[i][1], outVertexPoint[0] + points[i][0], outVertexPoint[1] + points[i][1], inVertexPoint[0] + points[i][0], inVertexPoint[1] + points[i][1], i, true);
+    }
+    return path;
+  }
+
+  function initiateExpression(elem, data, property) {
+    // Bail out if we don't want expressions
+    function noOp(_value) {
+      return _value;
+    }
+    if (!elem.globalData.renderConfig.runExpressions) {
+      return noOp;
+    }
+
+    var val = data.x;
+    var needsVelocity = /velocity(?![\w\d])/.test(val);
+    var _needsRandom = val.indexOf('random') !== -1;
+    var elemType = elem.data.ty;
+    var transform;
+    var $bm_transform;
+    var content;
+    var effect;
+    var thisProperty = property;
+    thisProperty._name = elem.data.nm;
+    thisProperty.valueAtTime = thisProperty.getValueAtTime;
+    Object.defineProperty(thisProperty, 'value', {
+      get: function () {
+        return thisProperty.v;
+      },
+    });
+    elem.comp.frameDuration = 1 / elem.comp.globalData.frameRate;
+    elem.comp.displayStartTime = 0;
+    var inPoint = elem.data.ip / elem.comp.globalData.frameRate;
+    var outPoint = elem.data.op / elem.comp.globalData.frameRate;
+    var width = elem.data.sw ? elem.data.sw : 0;
+    var height = elem.data.sh ? elem.data.sh : 0;
+    var name = elem.data.nm;
+    var loopIn;
+    var loop_in;
+    var loopOut;
+    var loop_out;
+    var smooth;
+    var toWorld;
+    var fromWorld;
+    var fromComp;
+    var toComp;
+    var fromCompToSurface;
+    var position;
+    var rotation;
+    var anchorPoint;
+    var scale;
+    var thisLayer;
+    var thisComp;
+    var mask;
+    var valueAtTime;
+    var velocityAtTime;
+
+    var scoped_bm_rt;
+    // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
+    var expression_function = eval('[function _expression_function(){' + val + ';scoped_bm_rt=$bm_rt}]')[0]; // eslint-disable-line no-eval
+    var numKeys = property.kf ? data.k.length : 0;
+
+    var active = !this.data || this.data.hd !== true;
+
+    var wiggle = function wiggle(freq, amp) {
+      var iWiggle;
+      var j;
+      var lenWiggle = this.pv.length ? this.pv.length : 1;
+      var addedAmps = createTypedArray('float32', lenWiggle);
+      freq = 5;
+      var iterations = Math.floor(time * freq);
+      iWiggle = 0;
+      j = 0;
+      while (iWiggle < iterations) {
+        // var rnd = BMMath.random();
+        for (j = 0; j < lenWiggle; j += 1) {
+          addedAmps[j] += -amp + amp * 2 * BMMath.random();
+          // addedAmps[j] += -amp + amp*2*rnd;
+        }
+        iWiggle += 1;
+      }
+      // var rnd2 = BMMath.random();
+      var periods = time * freq;
+      var perc = periods - Math.floor(periods);
+      var arr = createTypedArray('float32', lenWiggle);
+      if (lenWiggle > 1) {
+        for (j = 0; j < lenWiggle; j += 1) {
+          arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc;
+          // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
+          // arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc);
+        }
+        return arr;
+      }
+      return this.pv + addedAmps[0] + (-amp + amp * 2 * BMMath.random()) * perc;
+    }.bind(this);
+
+    if (thisProperty.loopIn) {
+      loopIn = thisProperty.loopIn.bind(thisProperty);
+      loop_in = loopIn;
+    }
+
+    if (thisProperty.loopOut) {
+      loopOut = thisProperty.loopOut.bind(thisProperty);
+      loop_out = loopOut;
+    }
+
+    if (thisProperty.smooth) {
+      smooth = thisProperty.smooth.bind(thisProperty);
+    }
+
+    function loopInDuration(type, duration) {
+      return loopIn(type, duration, true);
+    }
+
+    function loopOutDuration(type, duration) {
+      return loopOut(type, duration, true);
+    }
+
+    if (this.getValueAtTime) {
+      valueAtTime = this.getValueAtTime.bind(this);
+    }
+
+    if (this.getVelocityAtTime) {
+      velocityAtTime = this.getVelocityAtTime.bind(this);
+    }
+
+    var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface);
+
+    function lookAt(elem1, elem2) {
+      var fVec = [elem2[0] - elem1[0], elem2[1] - elem1[1], elem2[2] - elem1[2]];
+      var pitch = Math.atan2(fVec[0], Math.sqrt(fVec[1] * fVec[1] + fVec[2] * fVec[2])) / degToRads;
+      var yaw = -Math.atan2(fVec[1], fVec[2]) / degToRads;
+      return [yaw, pitch, 0];
+    }
+
+    function easeOut(t, tMin, tMax, val1, val2) {
+      return applyEase(easeOutBez, t, tMin, tMax, val1, val2);
+    }
+
+    function easeIn(t, tMin, tMax, val1, val2) {
+      return applyEase(easeInBez, t, tMin, tMax, val1, val2);
+    }
+
+    function ease(t, tMin, tMax, val1, val2) {
+      return applyEase(easeInOutBez, t, tMin, tMax, val1, val2);
+    }
+
+    function applyEase(fn, t, tMin, tMax, val1, val2) {
+      if (val1 === undefined) {
+        val1 = tMin;
+        val2 = tMax;
+      } else {
+        t = (t - tMin) / (tMax - tMin);
+      }
+      if (t > 1) {
+        t = 1;
+      } else if (t < 0) {
+        t = 0;
+      }
+      var mult = fn(t);
+      if ($bm_isInstanceOfArray(val1)) {
+        var iKey;
+        var lenKey = val1.length;
+        var arr = createTypedArray('float32', lenKey);
+        for (iKey = 0; iKey < lenKey; iKey += 1) {
+          arr[iKey] = (val2[iKey] - val1[iKey]) * mult + val1[iKey];
+        }
+        return arr;
+      }
+      return (val2 - val1) * mult + val1;
+    }
+
+    function nearestKey(time) {
+      var iKey;
+      var lenKey = data.k.length;
+      var index;
+      var keyTime;
+      if (!data.k.length || typeof (data.k[0]) === 'number') {
+        index = 0;
+        keyTime = 0;
+      } else {
+        index = -1;
+        time *= elem.comp.globalData.frameRate;
+        if (time < data.k[0].t) {
+          index = 1;
+          keyTime = data.k[0].t;
+        } else {
+          for (iKey = 0; iKey < lenKey - 1; iKey += 1) {
+            if (time === data.k[iKey].t) {
+              index = iKey + 1;
+              keyTime = data.k[iKey].t;
+              break;
+            } else if (time > data.k[iKey].t && time < data.k[iKey + 1].t) {
+              if (time - data.k[iKey].t > data.k[iKey + 1].t - time) {
+                index = iKey + 2;
+                keyTime = data.k[iKey + 1].t;
+              } else {
+                index = iKey + 1;
+                keyTime = data.k[iKey].t;
+              }
+              break;
+            }
+          }
+          if (index === -1) {
+            index = iKey + 1;
+            keyTime = data.k[iKey].t;
+          }
+        }
+      }
+      var obKey = {};
+      obKey.index = index;
+      obKey.time = keyTime / elem.comp.globalData.frameRate;
+      return obKey;
+    }
+
+    function key(ind) {
+      var obKey;
+      var iKey;
+      var lenKey;
+      if (!data.k.length || typeof (data.k[0]) === 'number') {
+        throw new Error('The property has no keyframe at index ' + ind);
+      }
+      ind -= 1;
+      obKey = {
+        time: data.k[ind].t / elem.comp.globalData.frameRate,
+        value: [],
+      };
+      var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e;
+
+      lenKey = arr.length;
+      for (iKey = 0; iKey < lenKey; iKey += 1) {
+        obKey[iKey] = arr[iKey];
+        obKey.value[iKey] = arr[iKey];
+      }
+      return obKey;
+    }
+
+    function framesToTime(fr, fps) {
+      if (!fps) {
+        fps = elem.comp.globalData.frameRate;
+      }
+      return fr / fps;
+    }
+
+    function timeToFrames(t, fps) {
+      if (!t && t !== 0) {
+        t = time;
+      }
+      if (!fps) {
+        fps = elem.comp.globalData.frameRate;
+      }
+      return t * fps;
+    }
+
+    function seedRandom(seed) {
+      BMMath.seedrandom(randSeed + seed);
+    }
+
+    function sourceRectAtTime() {
+      return elem.sourceRectAtTime();
+    }
+
+    function substring(init, end) {
+      if (typeof value === 'string') {
+        if (end === undefined) {
+          return value.substring(init);
+        }
+        return value.substring(init, end);
+      }
+      return '';
+    }
+
+    function substr(init, end) {
+      if (typeof value === 'string') {
+        if (end === undefined) {
+          return value.substr(init);
+        }
+        return value.substr(init, end);
+      }
+      return '';
+    }
+
+    function posterizeTime(framesPerSecond) {
+      time = framesPerSecond === 0 ? 0 : Math.floor(time * framesPerSecond) / framesPerSecond;
+      value = valueAtTime(time);
+    }
+
+    var time;
+    var velocity;
+    var value;
+    var text;
+    var textIndex;
+    var textTotal;
+    var selectorValue;
+    var index = elem.data.ind;
+    var hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+    var parent;
+    var randSeed = Math.floor(Math.random() * 1000000);
+    var globalData = elem.globalData;
+
+    function executeExpression(_value) {
+      // globalData.pushExpression();
+      value = _value;
+      if (this.frameExpressionId === elem.globalData.frameId && this.propType !== 'textSelector') {
+        return value;
+      }
+      if (this.propType === 'textSelector') {
+        textIndex = this.textIndex;
+        textTotal = this.textTotal;
+        selectorValue = this.selectorValue;
+      }
+      if (!thisLayer) {
+        text = elem.layerInterface.text;
+        thisLayer = elem.layerInterface;
+        thisComp = elem.comp.compInterface;
+        toWorld = thisLayer.toWorld.bind(thisLayer);
+        fromWorld = thisLayer.fromWorld.bind(thisLayer);
+        fromComp = thisLayer.fromComp.bind(thisLayer);
+        toComp = thisLayer.toComp.bind(thisLayer);
+        mask = thisLayer.mask ? thisLayer.mask.bind(thisLayer) : null;
+        fromCompToSurface = fromComp;
+      }
+      if (!transform) {
+        transform = elem.layerInterface('ADBE Transform Group');
+        $bm_transform = transform;
+        if (transform) {
+          anchorPoint = transform.anchorPoint;
+          /* position = transform.position;
+                    rotation = transform.rotation;
+                    scale = transform.scale; */
+        }
+      }
+
+      if (elemType === 4 && !content) {
+        content = thisLayer('ADBE Root Vectors Group');
+      }
+      if (!effect) {
+        effect = thisLayer(4);
+      }
+      hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+      if (hasParent && !parent) {
+        parent = elem.hierarchy[0].layerInterface;
+      }
+      time = this.comp.renderedFrame / this.comp.globalData.frameRate;
+      if (_needsRandom) {
+        seedRandom(randSeed + time);
+      }
+      if (needsVelocity) {
+        velocity = velocityAtTime(time);
+      }
+      expression_function();
+      this.frameExpressionId = elem.globalData.frameId;
+
+      // TODO: Check if it's possible to return on ShapeInterface the .v value
+      // Changed this to a ternary operation because Rollup failed compiling it correctly
+      scoped_bm_rt = scoped_bm_rt.propType === propTypes.SHAPE
+        ? scoped_bm_rt.v
+        : scoped_bm_rt;
+      return scoped_bm_rt;
+    }
+    // Bundlers will see these as dead code and unless we reference them
+    executeExpression.__preventDeadCodeRemoval = [$bm_transform, anchorPoint, time, velocity, inPoint, outPoint, width, height, name, loop_in, loop_out, smooth, toComp, fromCompToSurface, toWorld, fromWorld, mask, position, rotation, scale, thisComp, numKeys, active, wiggle, loopInDuration, loopOutDuration, comp, lookAt, easeOut, easeIn, ease, nearestKey, key, text, textIndex, textTotal, selectorValue, framesToTime, timeToFrames, sourceRectAtTime, substring, substr, posterizeTime, index, globalData];
+    return executeExpression;
+  }
+
+  ob.initiateExpression = initiateExpression;
+  ob.__preventDeadCodeRemoval = [window, document, XMLHttpRequest, fetch, frames, $bm_neg, add, $bm_sum, $bm_sub, $bm_mul, $bm_div, $bm_mod, clamp, radians_to_degrees, degreesToRadians, degrees_to_radians, normalize, rgbToHsl, hslToRgb, linear, random, createPath, _lottieGlobal];
+  ob.resetFrame = resetFrame;
+  return ob;
+}());
+
+const Expressions = (function () {
+  var ob = {};
+  ob.initExpressions = initExpressions;
+  ob.resetFrame = ExpressionManager.resetFrame;
+
+  function initExpressions(animation) {
+    var stackCount = 0;
+    var registers = [];
+
+    function pushExpression() {
+      stackCount += 1;
+    }
+
+    function popExpression() {
+      stackCount -= 1;
+      if (stackCount === 0) {
+        releaseInstances();
+      }
+    }
+
+    function registerExpressionProperty(expression) {
+      if (registers.indexOf(expression) === -1) {
+        registers.push(expression);
+      }
+    }
+
+    function releaseInstances() {
+      var i;
+      var len = registers.length;
+      for (i = 0; i < len; i += 1) {
+        registers[i].release();
+      }
+      registers.length = 0;
+    }
+
+    animation.renderer.compInterface = CompExpressionInterface(animation.renderer);
+    animation.renderer.globalData.projectInterface.registerComposition(animation.renderer);
+    animation.renderer.globalData.pushExpression = pushExpression;
+    animation.renderer.globalData.popExpression = popExpression;
+    animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty;
+  }
+  return ob;
+}());
+
+const MaskManagerInterface = (function () {
+  function MaskInterface(mask, data) {
+    this._mask = mask;
+    this._data = data;
+  }
+  Object.defineProperty(MaskInterface.prototype, 'maskPath', {
+    get: function () {
+      if (this._mask.prop.k) {
+        this._mask.prop.getValue();
+      }
+      return this._mask.prop;
+    },
+  });
+  Object.defineProperty(MaskInterface.prototype, 'maskOpacity', {
+    get: function () {
+      if (this._mask.op.k) {
+        this._mask.op.getValue();
+      }
+      return this._mask.op.v * 100;
+    },
+  });
+
+  var MaskManager = function (maskManager) {
+    var _masksInterfaces = createSizedArray(maskManager.viewData.length);
+    var i;
+    var len = maskManager.viewData.length;
+    for (i = 0; i < len; i += 1) {
+      _masksInterfaces[i] = new MaskInterface(maskManager.viewData[i], maskManager.masksProperties[i]);
+    }
+
+    var maskFunction = function (name) {
+      i = 0;
+      while (i < len) {
+        if (maskManager.masksProperties[i].nm === name) {
+          return _masksInterfaces[i];
+        }
+        i += 1;
+      }
+      return null;
+    };
+    return maskFunction;
+  };
+  return MaskManager;
+}());
+
+const ExpressionPropertyInterface = (function () {
+  var defaultUnidimensionalValue = { pv: 0, v: 0, mult: 1 };
+  var defaultMultidimensionalValue = { pv: [0, 0, 0], v: [0, 0, 0], mult: 1 };
+
+  function completeProperty(expressionValue, property, type) {
+    Object.defineProperty(expressionValue, 'velocity', {
+      get: function () {
+        return property.getVelocityAtTime(property.comp.currentFrame);
+      },
+    });
+    expressionValue.numKeys = property.keyframes ? property.keyframes.length : 0;
+    expressionValue.key = function (pos) {
+      if (!expressionValue.numKeys) {
+        return 0;
+      }
+      var value = '';
+      if ('s' in property.keyframes[pos - 1]) {
+        value = property.keyframes[pos - 1].s;
+      } else if ('e' in property.keyframes[pos - 2]) {
+        value = property.keyframes[pos - 2].e;
+      } else {
+        value = property.keyframes[pos - 2].s;
+      }
+      var valueProp = type === 'unidimensional' ? new Number(value) : Object.assign({}, value); // eslint-disable-line no-new-wrappers
+      valueProp.time = property.keyframes[pos - 1].t / property.elem.comp.globalData.frameRate;
+      valueProp.value = type === 'unidimensional' ? value[0] : value;
+      return valueProp;
+    };
+    expressionValue.valueAtTime = property.getValueAtTime;
+    expressionValue.speedAtTime = property.getSpeedAtTime;
+    expressionValue.velocityAtTime = property.getVelocityAtTime;
+    expressionValue.propertyGroup = property.propertyGroup;
+  }
+
+  function UnidimensionalPropertyInterface(property) {
+    if (!property || !('pv' in property)) {
+      property = defaultUnidimensionalValue;
+    }
+    var mult = 1 / property.mult;
+    var val = property.pv * mult;
+    var expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
+    expressionValue.value = val;
+    completeProperty(expressionValue, property, 'unidimensional');
+
+    return function () {
+      if (property.k) {
+        property.getValue();
+      }
+      val = property.v * mult;
+      if (expressionValue.value !== val) {
+        expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
+        expressionValue.value = val;
+        expressionValue[0] = val;
+        completeProperty(expressionValue, property, 'unidimensional');
+      }
+      return expressionValue;
+    };
+  }
+
+  function MultidimensionalPropertyInterface(property) {
+    if (!property || !('pv' in property)) {
+      property = defaultMultidimensionalValue;
+    }
+    var mult = 1 / property.mult;
+    var len = (property.data && property.data.l) || property.pv.length;
+    var expressionValue = createTypedArray('float32', len);
+    var arrValue = createTypedArray('float32', len);
+    expressionValue.value = arrValue;
+    completeProperty(expressionValue, property, 'multidimensional');
+
+    return function () {
+      if (property.k) {
+        property.getValue();
+      }
+      for (var i = 0; i < len; i += 1) {
+        arrValue[i] = property.v[i] * mult;
+        expressionValue[i] = arrValue[i];
+      }
+      return expressionValue;
+    };
+  }
+
+  // TODO: try to avoid using this getter
+  function defaultGetter() {
+    return defaultUnidimensionalValue;
+  }
+
+  return function (property) {
+    if (!property) {
+      return defaultGetter;
+    } if (property.propType === 'unidimensional') {
+      return UnidimensionalPropertyInterface(property);
+    }
+    return MultidimensionalPropertyInterface(property);
+  };
+}());
+
+const TransformExpressionInterface = (function () {
+  return function (transform) {
+    function _thisFunction(name) {
+      switch (name) {
+        case 'scale':
+        case 'Scale':
+        case 'ADBE Scale':
+        case 6:
+          return _thisFunction.scale;
+        case 'rotation':
+        case 'Rotation':
+        case 'ADBE Rotation':
+        case 'ADBE Rotate Z':
+        case 10:
+          return _thisFunction.rotation;
+        case 'ADBE Rotate X':
+          return _thisFunction.xRotation;
+        case 'ADBE Rotate Y':
+          return _thisFunction.yRotation;
+        case 'position':
+        case 'Position':
+        case 'ADBE Position':
+        case 2:
+          return _thisFunction.position;
+        case 'ADBE Position_0':
+          return _thisFunction.xPosition;
+        case 'ADBE Position_1':
+          return _thisFunction.yPosition;
+        case 'ADBE Position_2':
+          return _thisFunction.zPosition;
+        case 'anchorPoint':
+        case 'AnchorPoint':
+        case 'Anchor Point':
+        case 'ADBE AnchorPoint':
+        case 1:
+          return _thisFunction.anchorPoint;
+        case 'opacity':
+        case 'Opacity':
+        case 11:
+          return _thisFunction.opacity;
+        default:
+          return null;
+      }
+    }
+    Object.defineProperty(_thisFunction, 'rotation', {
+      get: ExpressionPropertyInterface(transform.r || transform.rz),
+    });
+
+    Object.defineProperty(_thisFunction, 'zRotation', {
+      get: ExpressionPropertyInterface(transform.rz || transform.r),
+    });
+
+    Object.defineProperty(_thisFunction, 'xRotation', {
+      get: ExpressionPropertyInterface(transform.rx),
+    });
+
+    Object.defineProperty(_thisFunction, 'yRotation', {
+      get: ExpressionPropertyInterface(transform.ry),
+    });
+    Object.defineProperty(_thisFunction, 'scale', {
+      get: ExpressionPropertyInterface(transform.s),
+    });
+    var _px;
+    var _py;
+    var _pz;
+    var _transformFactory;
+    if (transform.p) {
+      _transformFactory = ExpressionPropertyInterface(transform.p);
+    } else {
+      _px = ExpressionPropertyInterface(transform.px);
+      _py = ExpressionPropertyInterface(transform.py);
+      if (transform.pz) {
+        _pz = ExpressionPropertyInterface(transform.pz);
+      }
+    }
+    Object.defineProperty(_thisFunction, 'position', {
+      get: function () {
+        if (transform.p) {
+          return _transformFactory();
+        }
+        return [
+          _px(),
+          _py(),
+          _pz ? _pz() : 0];
+      },
+    });
+
+    Object.defineProperty(_thisFunction, 'xPosition', {
+      get: ExpressionPropertyInterface(transform.px),
+    });
+
+    Object.defineProperty(_thisFunction, 'yPosition', {
+      get: ExpressionPropertyInterface(transform.py),
+    });
+
+    Object.defineProperty(_thisFunction, 'zPosition', {
+      get: ExpressionPropertyInterface(transform.pz),
+    });
+
+    Object.defineProperty(_thisFunction, 'anchorPoint', {
+      get: ExpressionPropertyInterface(transform.a),
+    });
+
+    Object.defineProperty(_thisFunction, 'opacity', {
+      get: ExpressionPropertyInterface(transform.o),
+    });
+
+    Object.defineProperty(_thisFunction, 'skew', {
+      get: ExpressionPropertyInterface(transform.sk),
+    });
+
+    Object.defineProperty(_thisFunction, 'skewAxis', {
+      get: ExpressionPropertyInterface(transform.sa),
+    });
+
+    Object.defineProperty(_thisFunction, 'orientation', {
+      get: ExpressionPropertyInterface(transform.or),
+    });
+
+    return _thisFunction;
+  };
+}());
+
+const LayerExpressionInterface = (function () {
+  function getMatrix(time) {
+    var toWorldMat = new Matrix();
+    if (time !== undefined) {
+      var propMatrix = this._elem.finalTransform.mProp.getValueAtTime(time);
+      propMatrix.clone(toWorldMat);
+    } else {
+      var transformMat = this._elem.finalTransform.mProp;
+      transformMat.applyToMatrix(toWorldMat);
+    }
+    return toWorldMat;
+  }
+
+  function toWorldVec(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    toWorldMat.props[12] = 0;
+    toWorldMat.props[13] = 0;
+    toWorldMat.props[14] = 0;
+    return this.applyPoint(toWorldMat, arr);
+  }
+
+  function toWorld(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    return this.applyPoint(toWorldMat, arr);
+  }
+
+  function fromWorldVec(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    toWorldMat.props[12] = 0;
+    toWorldMat.props[13] = 0;
+    toWorldMat.props[14] = 0;
+    return this.invertPoint(toWorldMat, arr);
+  }
+
+  function fromWorld(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    return this.invertPoint(toWorldMat, arr);
+  }
+
+  function applyPoint(matrix, arr) {
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
+      }
+    }
+    return matrix.applyToPointArray(arr[0], arr[1], arr[2] || 0);
+  }
+
+  function invertPoint(matrix, arr) {
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
+      }
+    }
+    return matrix.inversePoint(arr);
+  }
+
+  function fromComp(arr) {
+    var toWorldMat = new Matrix();
+    toWorldMat.reset();
+    this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
+      }
+      return toWorldMat.inversePoint(arr);
+    }
+    return toWorldMat.inversePoint(arr);
+  }
+
+  function sampleImage() {
+    return [1, 1, 1, 1];
+  }
+
+  return function (elem) {
+    var transformInterface;
+
+    function _registerMaskInterface(maskManager) {
+      _thisLayerFunction.mask = new MaskManagerInterface(maskManager, elem);
+    }
+    function _registerEffectsInterface(effects) {
+      _thisLayerFunction.effect = effects;
+    }
+
+    function _thisLayerFunction(name) {
+      switch (name) {
+        case 'ADBE Root Vectors Group':
+        case 'Contents':
+        case 2:
+          return _thisLayerFunction.shapeInterface;
+        case 1:
+        case 6:
+        case 'Transform':
+        case 'transform':
+        case 'ADBE Transform Group':
+          return transformInterface;
+        case 4:
+        case 'ADBE Effect Parade':
+        case 'effects':
+        case 'Effects':
+          return _thisLayerFunction.effect;
+        case 'ADBE Text Properties':
+          return _thisLayerFunction.textInterface;
+        default:
+          return null;
+      }
+    }
+    _thisLayerFunction.getMatrix = getMatrix;
+    _thisLayerFunction.invertPoint = invertPoint;
+    _thisLayerFunction.applyPoint = applyPoint;
+    _thisLayerFunction.toWorld = toWorld;
+    _thisLayerFunction.toWorldVec = toWorldVec;
+    _thisLayerFunction.fromWorld = fromWorld;
+    _thisLayerFunction.fromWorldVec = fromWorldVec;
+    _thisLayerFunction.toComp = toWorld;
+    _thisLayerFunction.fromComp = fromComp;
+    _thisLayerFunction.sampleImage = sampleImage;
+    _thisLayerFunction.sourceRectAtTime = elem.sourceRectAtTime.bind(elem);
+    _thisLayerFunction._elem = elem;
+    transformInterface = TransformExpressionInterface(elem.finalTransform.mProp);
+    var anchorPointDescriptor = getDescriptor(transformInterface, 'anchorPoint');
+    Object.defineProperties(_thisLayerFunction, {
+      hasParent: {
+        get: function () {
+          return elem.hierarchy.length;
+        },
+      },
+      parent: {
+        get: function () {
+          return elem.hierarchy[0].layerInterface;
+        },
+      },
+      rotation: getDescriptor(transformInterface, 'rotation'),
+      scale: getDescriptor(transformInterface, 'scale'),
+      position: getDescriptor(transformInterface, 'position'),
+      opacity: getDescriptor(transformInterface, 'opacity'),
+      anchorPoint: anchorPointDescriptor,
+      anchor_point: anchorPointDescriptor,
+      transform: {
+        get: function () {
+          return transformInterface;
+        },
+      },
+      active: {
+        get: function () {
+          return elem.isInRange;
+        },
+      },
+    });
+
+    _thisLayerFunction.startTime = elem.data.st;
+    _thisLayerFunction.index = elem.data.ind;
+    _thisLayerFunction.source = elem.data.refId;
+    _thisLayerFunction.height = elem.data.ty === 0 ? elem.data.h : 100;
+    _thisLayerFunction.width = elem.data.ty === 0 ? elem.data.w : 100;
+    _thisLayerFunction.inPoint = elem.data.ip / elem.comp.globalData.frameRate;
+    _thisLayerFunction.outPoint = elem.data.op / elem.comp.globalData.frameRate;
+    _thisLayerFunction._name = elem.data.nm;
+
+    _thisLayerFunction.registerMaskInterface = _registerMaskInterface;
+    _thisLayerFunction.registerEffectsInterface = _registerEffectsInterface;
+    return _thisLayerFunction;
+  };
+}());
+
+const propertyGroupFactory = (function () {
+  return function (interfaceFunction, parentPropertyGroup) {
+    return function (val) {
+      val = val === undefined ? 1 : val;
+      if (val <= 0) {
+        return interfaceFunction;
+      }
+      return parentPropertyGroup(val - 1);
+    };
+  };
+}());
+
+const PropertyInterface = (function () {
+  return function (propertyName, propertyGroup) {
+    var interfaceFunction = {
+      _name: propertyName,
+    };
+
+    function _propertyGroup(val) {
+      val = val === undefined ? 1 : val;
+      if (val <= 0) {
+        return interfaceFunction;
+      }
+      return propertyGroup(val - 1);
+    }
+
+    return _propertyGroup;
+  };
+}());
+
+const EffectsExpressionInterface = (function () {
+  var ob = {
+    createEffectsInterface: createEffectsInterface,
+  };
+
+  function createEffectsInterface(elem, propertyGroup) {
+    if (elem.effectsManager) {
+      var effectElements = [];
+      var effectsData = elem.data.ef;
+      var i;
+      var len = elem.effectsManager.effectElements.length;
+      for (i = 0; i < len; i += 1) {
+        effectElements.push(createGroupInterface(effectsData[i], elem.effectsManager.effectElements[i], propertyGroup, elem));
+      }
+
+      var effects = elem.data.ef || [];
+      var groupInterface = function (name) {
+        i = 0;
+        len = effects.length;
+        while (i < len) {
+          if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
+            return effectElements[i];
+          }
+          i += 1;
+        }
+        return null;
+      };
+      Object.defineProperty(groupInterface, 'numProperties', {
+        get: function () {
+          return effects.length;
+        },
+      });
+      return groupInterface;
+    }
+    return null;
+  }
+
+  function createGroupInterface(data, elements, propertyGroup, elem) {
+    function groupInterface(name) {
+      var effects = data.ef;
+      var i = 0;
+      var len = effects.length;
+      while (i < len) {
+        if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
+          if (effects[i].ty === 5) {
+            return effectElements[i];
+          }
+          return effectElements[i]();
+        }
+        i += 1;
+      }
+      throw new Error();
+    }
+    var _propertyGroup = propertyGroupFactory(groupInterface, propertyGroup);
+
+    var effectElements = [];
+    var i;
+    var len = data.ef.length;
+    for (i = 0; i < len; i += 1) {
+      if (data.ef[i].ty === 5) {
+        effectElements.push(createGroupInterface(data.ef[i], elements.effectElements[i], elements.effectElements[i].propertyGroup, elem));
+      } else {
+        effectElements.push(createValueInterface(elements.effectElements[i], data.ef[i].ty, elem, _propertyGroup));
+      }
+    }
+
+    if (data.mn === 'ADBE Color Control') {
+      Object.defineProperty(groupInterface, 'color', {
+        get: function () {
+          return effectElements[0]();
+        },
+      });
+    }
+    Object.defineProperties(groupInterface, {
+      numProperties: {
+        get: function () {
+          return data.np;
+        },
+      },
+      _name: { value: data.nm },
+      propertyGroup: { value: _propertyGroup },
+    });
+    groupInterface.enabled = data.en !== 0;
+    groupInterface.active = groupInterface.enabled;
+    return groupInterface;
+  }
+
+  function createValueInterface(element, type, elem, propertyGroup) {
+    var expressionProperty = ExpressionPropertyInterface(element.p);
+    function interfaceFunction() {
+      if (type === 10) {
+        return elem.comp.compInterface(element.p.v);
+      }
+      return expressionProperty();
+    }
+
+    if (element.p.setGroupProperty) {
+      element.p.setGroupProperty(PropertyInterface('', propertyGroup));
+    }
+
+    return interfaceFunction;
+  }
+
+  return ob;
+}());
+
+const ShapePathInterface = (
+
+  function () {
+    return function pathInterfaceFactory(shape, view, propertyGroup) {
+      var prop = view.sh;
+
+      function interfaceFunction(val) {
+        if (val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2) {
+          return interfaceFunction.path;
+        }
+        return null;
+      }
+
+      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+      prop.setGroupProperty(PropertyInterface('Path', _propertyGroup));
+      Object.defineProperties(interfaceFunction, {
+        path: {
+          get: function () {
+            if (prop.k) {
+              prop.getValue();
+            }
+            return prop;
+          },
+        },
+        shape: {
+          get: function () {
+            if (prop.k) {
+              prop.getValue();
+            }
+            return prop;
+          },
+        },
+        _name: { value: shape.nm },
+        ix: { value: shape.ix },
+        propertyIndex: { value: shape.ix },
+        mn: { value: shape.mn },
+        propertyGroup: { value: propertyGroup },
+      });
+      return interfaceFunction;
+    };
+  }()
+);
+
+const ShapeExpressionInterface = (function () {
+  function iterateElements(shapes, view, propertyGroup) {
+    var arr = [];
+    var i;
+    var len = shapes ? shapes.length : 0;
+    for (i = 0; i < len; i += 1) {
+      if (shapes[i].ty === 'gr') {
+        arr.push(groupInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'fl') {
+        arr.push(fillInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'st') {
+        arr.push(strokeInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'tm') {
+        arr.push(trimInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'tr') {
+        // arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
+      } else if (shapes[i].ty === 'el') {
+        arr.push(ellipseInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'sr') {
+        arr.push(starInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'sh') {
+        arr.push(ShapePathInterface(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'rc') {
+        arr.push(rectInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'rd') {
+        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;
+  }
+
+  function contentsInterfaceFactory(shape, view, propertyGroup) {
+    var interfaces;
+    var interfaceFunction = function _interfaceFunction(value) {
+      var i = 0;
+      var len = interfaces.length;
+      while (i < len) {
+        if (interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value) {
+          return interfaces[i];
+        }
+        i += 1;
+      }
+      if (typeof value === 'number') {
+        return interfaces[value - 1];
+      }
+      return null;
+    };
+
+    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup);
+    interfaceFunction.numProperties = interfaces.length;
+    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
+    interfaceFunction.transform = transformInterface;
+    interfaceFunction.propertyIndex = shape.cix;
+    interfaceFunction._name = shape.nm;
+
+    return interfaceFunction;
+  }
+
+  function groupInterfaceFactory(shape, view, propertyGroup) {
+    var interfaceFunction = function _interfaceFunction(value) {
+      switch (value) {
+        case 'ADBE Vectors Group':
+        case 'Contents':
+        case 2:
+          return interfaceFunction.content;
+          // Not necessary for now. Keeping them here in case a new case appears
+          // case 'ADBE Vector Transform Group':
+          // case 3:
+        default:
+          return interfaceFunction.transform;
+      }
+    };
+    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var content = contentsInterfaceFactory(shape, view, interfaceFunction.propertyGroup);
+    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
+    interfaceFunction.content = content;
+    interfaceFunction.transform = transformInterface;
+    Object.defineProperty(interfaceFunction, '_name', {
+      get: function () {
+        return shape.nm;
+      },
+    });
+    // interfaceFunction.content = interfaceFunction;
+    interfaceFunction.numProperties = shape.np;
+    interfaceFunction.propertyIndex = shape.ix;
+    interfaceFunction.nm = shape.nm;
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function fillInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      if (val === 'Color' || val === 'color') {
+        return interfaceFunction.color;
+      } if (val === 'Opacity' || val === 'opacity') {
+        return interfaceFunction.opacity;
+      }
+      return null;
+    }
+    Object.defineProperties(interfaceFunction, {
+      color: {
+        get: ExpressionPropertyInterface(view.c),
+      },
+      opacity: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      _name: { value: shape.nm },
+      mn: { value: shape.mn },
+    });
+
+    view.c.setGroupProperty(PropertyInterface('Color', propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
+    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 () {
+          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() {
+    function interfaceFunction() {
+      return null;
+    }
+    return interfaceFunction;
+  }
+
+  function strokeInterfaceFactory(shape, view, propertyGroup) {
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup);
+    function addPropertyToDashOb(i) {
+      Object.defineProperty(dashOb, shape.d[i].nm, {
+        get: ExpressionPropertyInterface(view.d.dataProps[i].p),
+      });
+    }
+    var i;
+    var len = shape.d ? shape.d.length : 0;
+    var dashOb = {};
+    for (i = 0; i < len; i += 1) {
+      addPropertyToDashOb(i);
+      view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup);
+    }
+
+    function interfaceFunction(val) {
+      if (val === 'Color' || val === 'color') {
+        return interfaceFunction.color;
+      } if (val === 'Opacity' || val === 'opacity') {
+        return interfaceFunction.opacity;
+      } if (val === 'Stroke Width' || val === 'stroke width') {
+        return interfaceFunction.strokeWidth;
+      }
+      return null;
+    }
+    Object.defineProperties(interfaceFunction, {
+      color: {
+        get: ExpressionPropertyInterface(view.c),
+      },
+      opacity: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      strokeWidth: {
+        get: ExpressionPropertyInterface(view.w),
+      },
+      dash: {
+        get: function () {
+          return dashOb;
+        },
+      },
+      _name: { value: shape.nm },
+      mn: { value: shape.mn },
+    });
+
+    view.c.setGroupProperty(PropertyInterface('Color', _propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    view.w.setGroupProperty(PropertyInterface('Stroke Width', _propertyGroup));
+    return interfaceFunction;
+  }
+
+  function trimInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      if (val === shape.e.ix || val === 'End' || val === 'end') {
+        return interfaceFunction.end;
+      }
+      if (val === shape.s.ix) {
+        return interfaceFunction.start;
+      }
+      if (val === shape.o.ix) {
+        return interfaceFunction.offset;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaceFunction.propertyIndex = shape.ix;
+
+    view.s.setGroupProperty(PropertyInterface('Start', _propertyGroup));
+    view.e.setGroupProperty(PropertyInterface('End', _propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
+    interfaceFunction.propertyIndex = shape.ix;
+    interfaceFunction.propertyGroup = propertyGroup;
+
+    Object.defineProperties(interfaceFunction, {
+      start: {
+        get: ExpressionPropertyInterface(view.s),
+      },
+      end: {
+        get: ExpressionPropertyInterface(view.e),
+      },
+      offset: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function transformInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.a.ix === value || value === 'Anchor Point') {
+        return interfaceFunction.anchorPoint;
+      }
+      if (shape.o.ix === value || value === 'Opacity') {
+        return interfaceFunction.opacity;
+      }
+      if (shape.p.ix === value || value === 'Position') {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value || value === 'Rotation' || value === 'ADBE Vector Rotation') {
+        return interfaceFunction.rotation;
+      }
+      if (shape.s.ix === value || value === 'Scale') {
+        return interfaceFunction.scale;
+      }
+      if ((shape.sk && shape.sk.ix === value) || value === 'Skew') {
+        return interfaceFunction.skew;
+      }
+      if ((shape.sa && shape.sa.ix === value) || value === 'Skew Axis') {
+        return interfaceFunction.skewAxis;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    view.transform.mProps.a.setGroupProperty(PropertyInterface('Anchor Point', _propertyGroup));
+    view.transform.mProps.s.setGroupProperty(PropertyInterface('Scale', _propertyGroup));
+    view.transform.mProps.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+    if (view.transform.mProps.sk) {
+      view.transform.mProps.sk.setGroupProperty(PropertyInterface('Skew', _propertyGroup));
+      view.transform.mProps.sa.setGroupProperty(PropertyInterface('Skew Angle', _propertyGroup));
+    }
+    view.transform.op.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    Object.defineProperties(interfaceFunction, {
+      opacity: {
+        get: ExpressionPropertyInterface(view.transform.mProps.o),
+      },
+      position: {
+        get: ExpressionPropertyInterface(view.transform.mProps.p),
+      },
+      anchorPoint: {
+        get: ExpressionPropertyInterface(view.transform.mProps.a),
+      },
+      scale: {
+        get: ExpressionPropertyInterface(view.transform.mProps.s),
+      },
+      rotation: {
+        get: ExpressionPropertyInterface(view.transform.mProps.r),
+      },
+      skew: {
+        get: ExpressionPropertyInterface(view.transform.mProps.sk),
+      },
+      skewAxis: {
+        get: ExpressionPropertyInterface(view.transform.mProps.sa),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.ty = 'tr';
+    interfaceFunction.mn = shape.mn;
+    interfaceFunction.propertyGroup = propertyGroup;
+    return interfaceFunction;
+  }
+
+  function ellipseInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.s.ix === value) {
+        return interfaceFunction.size;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaceFunction.propertyIndex = shape.ix;
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      size: {
+        get: ExpressionPropertyInterface(prop.s),
+      },
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function starInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value) {
+        return interfaceFunction.rotation;
+      }
+      if (shape.pt.ix === value) {
+        return interfaceFunction.points;
+      }
+      if (shape.or.ix === value || value === 'ADBE Vector Star Outer Radius') {
+        return interfaceFunction.outerRadius;
+      }
+      if (shape.os.ix === value) {
+        return interfaceFunction.outerRoundness;
+      }
+      if (shape.ir && (shape.ir.ix === value || value === 'ADBE Vector Star Inner Radius')) {
+        return interfaceFunction.innerRadius;
+      }
+      if (shape.is && shape.is.ix === value) {
+        return interfaceFunction.innerRoundness;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.or.setGroupProperty(PropertyInterface('Outer Radius', _propertyGroup));
+    prop.os.setGroupProperty(PropertyInterface('Outer Roundness', _propertyGroup));
+    prop.pt.setGroupProperty(PropertyInterface('Points', _propertyGroup));
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+    if (shape.ir) {
+      prop.ir.setGroupProperty(PropertyInterface('Inner Radius', _propertyGroup));
+      prop.is.setGroupProperty(PropertyInterface('Inner Roundness', _propertyGroup));
+    }
+
+    Object.defineProperties(interfaceFunction, {
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      rotation: {
+        get: ExpressionPropertyInterface(prop.r),
+      },
+      points: {
+        get: ExpressionPropertyInterface(prop.pt),
+      },
+      outerRadius: {
+        get: ExpressionPropertyInterface(prop.or),
+      },
+      outerRoundness: {
+        get: ExpressionPropertyInterface(prop.os),
+      },
+      innerRadius: {
+        get: ExpressionPropertyInterface(prop.ir),
+      },
+      innerRoundness: {
+        get: ExpressionPropertyInterface(prop.is),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function rectInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value) {
+        return interfaceFunction.roundness;
+      }
+      if (shape.s.ix === value || value === 'Size' || value === 'ADBE Vector Rect Size') {
+        return interfaceFunction.size;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
+    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      roundness: {
+        get: ExpressionPropertyInterface(prop.r),
+      },
+      size: {
+        get: ExpressionPropertyInterface(prop.s),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function roundedInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.r.ix === value || value === 'Round Corners 1') {
+        return interfaceFunction.radius;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.rd.setGroupProperty(PropertyInterface('Radius', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      radius: {
+        get: ExpressionPropertyInterface(prop.rd),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function repeaterInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.c.ix === value || value === 'Copies') {
+        return interfaceFunction.copies;
+      } if (shape.o.ix === value || value === 'Offset') {
+        return interfaceFunction.offset;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.c.setGroupProperty(PropertyInterface('Copies', _propertyGroup));
+    prop.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
+    Object.defineProperties(interfaceFunction, {
+      copies: {
+        get: ExpressionPropertyInterface(prop.c),
+      },
+      offset: {
+        get: ExpressionPropertyInterface(prop.o),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  return function (shapes, view, propertyGroup) {
+    var interfaces;
+    function _interfaceFunction(value) {
+      if (typeof value === 'number') {
+        value = value === undefined ? 1 : value;
+        if (value === 0) {
+          return propertyGroup;
+        }
+        return interfaces[value - 1];
+      }
+      var i = 0;
+      var len = interfaces.length;
+      while (i < len) {
+        if (interfaces[i]._name === value) {
+          return interfaces[i];
+        }
+        i += 1;
+      }
+      return null;
+    }
+    function parentGroupWrapper() {
+      return propertyGroup;
+    }
+    _interfaceFunction.propertyGroup = propertyGroupFactory(_interfaceFunction, parentGroupWrapper);
+    interfaces = iterateElements(shapes, view, _interfaceFunction.propertyGroup);
+    _interfaceFunction.numProperties = interfaces.length;
+    _interfaceFunction._name = 'Contents';
+    return _interfaceFunction;
+  };
+}());
+
+const TextExpressionInterface = (function () {
+  return function (elem) {
+    var _sourceText;
+    function _thisLayerFunction(name) {
+      switch (name) {
+        case 'ADBE Text Document':
+          return _thisLayerFunction.sourceText;
+        default:
+          return null;
+      }
+    }
+    Object.defineProperty(_thisLayerFunction, 'sourceText', {
+      get: function () {
+        elem.textProperty.getValue();
+        var stringValue = elem.textProperty.currentData.t;
+        if (!_sourceText || stringValue !== _sourceText.value) {
+          _sourceText = new String(stringValue); // eslint-disable-line no-new-wrappers
+          // If stringValue is an empty string, eval returns undefined, so it has to be returned as a String primitive
+          _sourceText.value = stringValue || new String(stringValue); // eslint-disable-line no-new-wrappers
+          Object.defineProperty(_sourceText, 'style', {
+            get: function () {
+              return {
+                fillColor: elem.textProperty.currentData.fc,
+              };
+            },
+          });
+        }
+        return _sourceText;
+      },
+    });
+    return _thisLayerFunction;
+  };
+}());
+
+const FootageInterface = (function () {
+  var outlineInterfaceFactory = (function (elem) {
+    var currentPropertyName = '';
+    var currentProperty = elem.getFootageData();
+    function init() {
+      currentPropertyName = '';
+      currentProperty = elem.getFootageData();
+      return searchProperty;
+    }
+    function searchProperty(value) {
+      if (currentProperty[value]) {
+        currentPropertyName = value;
+        currentProperty = currentProperty[value];
+        if (typeof currentProperty === 'object') {
+          return searchProperty;
+        }
+        return currentProperty;
+      }
+      var propertyNameIndex = value.indexOf(currentPropertyName);
+      if (propertyNameIndex !== -1) {
+        var index = parseInt(value.substr(propertyNameIndex + currentPropertyName.length), 10);
+        currentProperty = currentProperty[index];
+        if (typeof currentProperty === 'object') {
+          return searchProperty;
+        }
+        return currentProperty;
+      }
+      return '';
+    }
+    return init;
+  });
+
+  var dataInterfaceFactory = function (elem) {
+    function interfaceFunction(value) {
+      if (value === 'Outline') {
+        return interfaceFunction.outlineInterface();
+      }
+      return null;
+    }
+
+    interfaceFunction._name = 'Outline';
+    interfaceFunction.outlineInterface = outlineInterfaceFactory(elem);
+    return interfaceFunction;
+  };
+
+  return function (elem) {
+    function _interfaceFunction(value) {
+      if (value === 'Data') {
+        return _interfaceFunction.dataInterface;
+      }
+      return null;
+    }
+
+    _interfaceFunction._name = 'Data';
+    _interfaceFunction.dataInterface = dataInterfaceFactory(elem);
+    return _interfaceFunction;
+  };
+}());
+
+var interfaces = {
+  layer: LayerExpressionInterface,
+  effects: EffectsExpressionInterface,
+  comp: CompExpressionInterface,
+  shape: ShapeExpressionInterface,
+  text: TextExpressionInterface,
+  footage: FootageInterface,
+};
+
+function getInterface(type) {
+  return interfaces[type] || null;
+}
+
+const expressionHelpers = (function () {
+  function searchExpressions(elem, data, prop) {
+    if (data.x) {
+      prop.k = true;
+      prop.x = true;
+      prop.initiateExpression = ExpressionManager.initiateExpression;
+      prop.effectsSequence.push(prop.initiateExpression(elem, data, prop).bind(prop));
+    }
+  }
+
+  function getValueAtTime(frameNum) {
+    frameNum *= this.elem.globalData.frameRate;
+    frameNum -= this.offsetTime;
+    if (frameNum !== this._cachingAtTime.lastFrame) {
+      this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0;
+      this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime);
+      this._cachingAtTime.lastFrame = frameNum;
+    }
+    return this._cachingAtTime.value;
+  }
+
+  function getSpeedAtTime(frameNum) {
+    var delta = -0.01;
+    var v1 = this.getValueAtTime(frameNum);
+    var v2 = this.getValueAtTime(frameNum + delta);
+    var speed = 0;
+    if (v1.length) {
+      var i;
+      for (i = 0; i < v1.length; i += 1) {
+        speed += Math.pow(v2[i] - v1[i], 2);
+      }
+      speed = Math.sqrt(speed) * 100;
+    } else {
+      speed = 0;
+    }
+    return speed;
+  }
+
+  function getVelocityAtTime(frameNum) {
+    if (this.vel !== undefined) {
+      return this.vel;
+    }
+    var delta = -0.001;
+    // frameNum += this.elem.data.st;
+    var v1 = this.getValueAtTime(frameNum);
+    var v2 = this.getValueAtTime(frameNum + delta);
+    var velocity;
+    if (v1.length) {
+      velocity = createTypedArray('float32', v1.length);
+      var i;
+      for (i = 0; i < v1.length; i += 1) {
+        // removing frameRate
+        // if needed, don't add it here
+        // velocity[i] = this.elem.globalData.frameRate*((v2[i] - v1[i])/delta);
+        velocity[i] = (v2[i] - v1[i]) / delta;
+      }
+    } else {
+      velocity = (v2 - v1) / delta;
+    }
+    return velocity;
+  }
+
+  function getStaticValueAtTime() {
+    return this.pv;
+  }
+
+  function setGroupProperty(propertyGroup) {
+    this.propertyGroup = propertyGroup;
+  }
+
+  return {
+    searchExpressions: searchExpressions,
+    getSpeedAtTime: getSpeedAtTime,
+    getVelocityAtTime: getVelocityAtTime,
+    getValueAtTime: getValueAtTime,
+    getStaticValueAtTime: getStaticValueAtTime,
+    setGroupProperty: setGroupProperty,
+  };
+}());
+
+function addPropertyDecorator() {
+  function loopOut(type, duration, durationFlag) {
+    if (!this.k || !this.keyframes) {
+      return this.pv;
+    }
+    type = type ? type.toLowerCase() : '';
+    var currentFrame = this.comp.renderedFrame;
+    var keyframes = this.keyframes;
+    var lastKeyFrame = keyframes[keyframes.length - 1].t;
+    if (currentFrame <= lastKeyFrame) {
+      return this.pv;
+    }
+    var cycleDuration;
+    var firstKeyFrame;
+    if (!durationFlag) {
+      if (!duration || duration > keyframes.length - 1) {
+        duration = keyframes.length - 1;
+      }
+      firstKeyFrame = keyframes[keyframes.length - 1 - duration].t;
+      cycleDuration = lastKeyFrame - firstKeyFrame;
+    } else {
+      if (!duration) {
+        cycleDuration = Math.max(0, lastKeyFrame - this.elem.data.ip);
+      } else {
+        cycleDuration = Math.abs(lastKeyFrame - this.elem.comp.globalData.frameRate * duration);
+      }
+      firstKeyFrame = lastKeyFrame - cycleDuration;
+    }
+    var i;
+    var len;
+    var ret;
+    if (type === 'pingpong') {
+      var iterations = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
+      if (iterations % 2 !== 0) {
+          return this.getValueAtTime(((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      }
+    } else if (type === 'offset') {
+      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+        var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      var repeats = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
+      if (this.pv.length) {
+        ret = new Array(initV.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = (endV[i] - initV[i]) * repeats + current[i];
+        }
+        return ret;
+      }
+      return (endV - initV) * repeats + current;
+    } else if (type === 'continue') {
+      var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+      var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0);
+      if (this.pv.length) {
+        ret = new Array(lastValue.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+            ret[i] = lastValue[i] + (lastValue[i] - nextLastValue[i]) * ((currentFrame - lastKeyFrame) / this.comp.globalData.frameRate) / 0.0005; // eslint-disable-line
+        }
+        return ret;
+      }
+      return lastValue + (lastValue - nextLastValue) * (((currentFrame - lastKeyFrame)) / 0.001);
+    }
+      return this.getValueAtTime((((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+
+  }
+
+  function loopIn(type, duration, durationFlag) {
+    if (!this.k) {
+      return this.pv;
+    }
+    type = type ? type.toLowerCase() : '';
+    var currentFrame = this.comp.renderedFrame;
+    var keyframes = this.keyframes;
+    var firstKeyFrame = keyframes[0].t;
+    if (currentFrame >= firstKeyFrame) {
+      return this.pv;
+    }
+    var cycleDuration;
+    var lastKeyFrame;
+    if (!durationFlag) {
+      if (!duration || duration > keyframes.length - 1) {
+        duration = keyframes.length - 1;
+      }
+      lastKeyFrame = keyframes[duration].t;
+      cycleDuration = lastKeyFrame - firstKeyFrame;
+    } else {
+      if (!duration) {
+        cycleDuration = Math.max(0, this.elem.data.op - firstKeyFrame);
+      } else {
+        cycleDuration = Math.abs(this.elem.comp.globalData.frameRate * duration);
+      }
+      lastKeyFrame = firstKeyFrame + cycleDuration;
+    }
+    var i;
+    var len;
+    var ret;
+    if (type === 'pingpong') {
+      var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration);
+      if (iterations % 2 === 0) {
+          return this.getValueAtTime((((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      }
+    } else if (type === 'offset') {
+      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+      var current = this.getValueAtTime((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration) + firstKeyFrame) / this.comp.globalData.frameRate, 0);
+      var repeats = Math.floor((firstKeyFrame - currentFrame) / cycleDuration) + 1;
+      if (this.pv.length) {
+        ret = new Array(initV.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = current[i] - (endV[i] - initV[i]) * repeats;
+        }
+        return ret;
+      }
+      return current - (endV - initV) * repeats;
+    } else if (type === 'continue') {
+      var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0);
+      if (this.pv.length) {
+        ret = new Array(firstValue.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = firstValue[i] + ((firstValue[i] - nextFirstValue[i]) * (firstKeyFrame - currentFrame)) / 0.001;
+        }
+        return ret;
+      }
+      return firstValue + ((firstValue - nextFirstValue) * (firstKeyFrame - currentFrame)) / 0.001;
+    }
+      return this.getValueAtTime(((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame))) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+
+  }
+
+  function smooth(width, samples) {
+    if (!this.k) {
+      return this.pv;
+    }
+    width = (width || 0.4) * 0.5;
+    samples = Math.floor(samples || 5);
+    if (samples <= 1) {
+      return this.pv;
+    }
+    var currentTime = this.comp.renderedFrame / this.comp.globalData.frameRate;
+    var initFrame = currentTime - width;
+    var endFrame = currentTime + width;
+    var sampleFrequency = samples > 1 ? (endFrame - initFrame) / (samples - 1) : 1;
+    var i = 0;
+    var j = 0;
+    var value;
+    if (this.pv.length) {
+      value = createTypedArray('float32', this.pv.length);
+    } else {
+      value = 0;
+    }
+    var sampleValue;
+    while (i < samples) {
+      sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency);
+      if (this.pv.length) {
+        for (j = 0; j < this.pv.length; j += 1) {
+          value[j] += sampleValue[j];
+        }
+      } else {
+        value += sampleValue;
+      }
+      i += 1;
+    }
+    if (this.pv.length) {
+      for (j = 0; j < this.pv.length; j += 1) {
+        value[j] /= samples;
+      }
+    } else {
+      value /= samples;
+    }
+    return value;
+  }
+
+  function getTransformValueAtTime(time) {
+    if (!this._transformCachingAtTime) {
+      this._transformCachingAtTime = {
+        v: new Matrix(),
+      };
+    }
+    /// /
+    var matrix = this._transformCachingAtTime.v;
+    matrix.cloneFromProps(this.pre.props);
+    if (this.appliedTransformations < 1) {
+      var anchor = this.a.getValueAtTime(time);
+      matrix.translate(
+        -anchor[0] * this.a.mult,
+        -anchor[1] * this.a.mult,
+        anchor[2] * this.a.mult
+      );
+    }
+    if (this.appliedTransformations < 2) {
+      var scale = this.s.getValueAtTime(time);
+      matrix.scale(
+        scale[0] * this.s.mult,
+        scale[1] * this.s.mult,
+        scale[2] * this.s.mult
+      );
+    }
+    if (this.sk && this.appliedTransformations < 3) {
+      var skew = this.sk.getValueAtTime(time);
+      var skewAxis = this.sa.getValueAtTime(time);
+      matrix.skewFromAxis(-skew * this.sk.mult, skewAxis * this.sa.mult);
+    }
+    if (this.r && this.appliedTransformations < 4) {
+      var rotation = this.r.getValueAtTime(time);
+      matrix.rotate(-rotation * this.r.mult);
+    } else if (!this.r && this.appliedTransformations < 4) {
+      var rotationZ = this.rz.getValueAtTime(time);
+      var rotationY = this.ry.getValueAtTime(time);
+      var rotationX = this.rx.getValueAtTime(time);
+      var orientation = this.or.getValueAtTime(time);
+      matrix.rotateZ(-rotationZ * this.rz.mult)
+        .rotateY(rotationY * this.ry.mult)
+        .rotateX(rotationX * this.rx.mult)
+        .rotateZ(-orientation[2] * this.or.mult)
+        .rotateY(orientation[1] * this.or.mult)
+        .rotateX(orientation[0] * this.or.mult);
+    }
+    if (this.data.p && this.data.p.s) {
+      var positionX = this.px.getValueAtTime(time);
+      var positionY = this.py.getValueAtTime(time);
+      if (this.data.p.z) {
+        var positionZ = this.pz.getValueAtTime(time);
+        matrix.translate(
+          positionX * this.px.mult,
+          positionY * this.py.mult,
+          -positionZ * this.pz.mult
+        );
+      } else {
+        matrix.translate(positionX * this.px.mult, positionY * this.py.mult, 0);
+      }
+    } else {
+      var position = this.p.getValueAtTime(time);
+      matrix.translate(
+        position[0] * this.p.mult,
+        position[1] * this.p.mult,
+        -position[2] * this.p.mult
+      );
+    }
+    return matrix;
+    /// /
+  }
+
+  function getTransformStaticValueAtTime() {
+    return this.v.clone(new Matrix());
+  }
+
+  var getTransformProperty = TransformPropertyFactory.getTransformProperty;
+  TransformPropertyFactory.getTransformProperty = function (elem, data, container) {
+    var prop = getTransformProperty(elem, data, container);
+    if (prop.dynamicProperties.length) {
+      prop.getValueAtTime = getTransformValueAtTime.bind(prop);
+    } else {
+      prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop);
+    }
+    prop.setGroupProperty = expressionHelpers.setGroupProperty;
+    return prop;
+  };
+
+  var propertyGetProp = PropertyFactory.getProp;
+  PropertyFactory.getProp = function (elem, data, type, mult, container) {
+    var prop = propertyGetProp(elem, data, type, mult, container);
+    // prop.getVelocityAtTime = getVelocityAtTime;
+    // prop.loopOut = loopOut;
+    // prop.loopIn = loopIn;
+    if (prop.kf) {
+      prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop);
+    } else {
+      prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop);
+    }
+    prop.setGroupProperty = expressionHelpers.setGroupProperty;
+    prop.loopOut = loopOut;
+    prop.loopIn = loopIn;
+    prop.smooth = smooth;
+    prop.getVelocityAtTime = expressionHelpers.getVelocityAtTime.bind(prop);
+    prop.getSpeedAtTime = expressionHelpers.getSpeedAtTime.bind(prop);
+    prop.numKeys = data.a === 1 ? data.k.length : 0;
+    prop.propertyIndex = data.ix;
+    var value = 0;
+    if (type !== 0) {
+      value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length);
+    }
+    prop._cachingAtTime = {
+      lastFrame: initialDefaultFrame,
+      lastIndex: 0,
+      value: value,
+    };
+    expressionHelpers.searchExpressions(elem, data, prop);
+    if (prop.k) {
+      container.addDynamicProperty(prop);
+    }
+
+    return prop;
+  };
+
+  function getShapeValueAtTime(frameNum) {
+    // For now this caching object is created only when needed instead of creating it when the shape is initialized.
+    if (!this._cachingAtTime) {
+      this._cachingAtTime = {
+        shapeValue: shapePool.clone(this.pv),
+        lastIndex: 0,
+        lastTime: initialDefaultFrame,
+      };
+    }
+
+    frameNum *= this.elem.globalData.frameRate;
+    frameNum -= this.offsetTime;
+    if (frameNum !== this._cachingAtTime.lastTime) {
+      this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0;
+      this._cachingAtTime.lastTime = frameNum;
+      this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime);
+    }
+    return this._cachingAtTime.shapeValue;
+  }
+
+  var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction();
+  var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction();
+
+  function ShapeExpressions() {}
+  ShapeExpressions.prototype = {
+    vertices: function (prop, time) {
+      if (this.k) {
+        this.getValue();
+      }
+      var shapePath = this.v;
+      if (time !== undefined) {
+        shapePath = this.getValueAtTime(time, 0);
+      }
+      var i;
+      var len = shapePath._length;
+      var vertices = shapePath[prop];
+      var points = shapePath.v;
+      var arr = createSizedArray(len);
+      for (i = 0; i < len; i += 1) {
+        if (prop === 'i' || prop === 'o') {
+          arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]];
+        } else {
+          arr[i] = [vertices[i][0], vertices[i][1]];
+        }
+      }
+      return arr;
+    },
+    points: function (time) {
+      return this.vertices('v', time);
+    },
+    inTangents: function (time) {
+      return this.vertices('i', time);
+    },
+    outTangents: function (time) {
+      return this.vertices('o', time);
+    },
+    isClosed: function () {
+      return this.v.c;
+    },
+    pointOnPath: function (perc, time) {
+      var shapePath = this.v;
+      if (time !== undefined) {
+        shapePath = this.getValueAtTime(time, 0);
+      }
+      if (!this._segmentsLength) {
+        this._segmentsLength = bez.getSegmentsLength(shapePath);
+      }
+
+      var segmentsLength = this._segmentsLength;
+      var lengths = segmentsLength.lengths;
+      var lengthPos = segmentsLength.totalLength * perc;
+      var i = 0;
+      var len = lengths.length;
+      var accumulatedLength = 0;
+      var pt;
+      while (i < len) {
+        if (accumulatedLength + lengths[i].addedLength > lengthPos) {
+          var initIndex = i;
+          var endIndex = (shapePath.c && i === len - 1) ? 0 : i + 1;
+          var segmentPerc = (lengthPos - accumulatedLength) / lengths[i].addedLength;
+          pt = bez.getPointInSegment(shapePath.v[initIndex], shapePath.v[endIndex], shapePath.o[initIndex], shapePath.i[endIndex], segmentPerc, lengths[i]);
+          break;
+        } else {
+          accumulatedLength += lengths[i].addedLength;
+        }
+        i += 1;
+      }
+      if (!pt) {
+        pt = shapePath.c ? [shapePath.v[0][0], shapePath.v[0][1]] : [shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1]];
+      }
+      return pt;
+    },
+    vectorOnPath: function (perc, time, vectorType) {
+      // perc doesn't use triple equality because it can be a Number object as well as a primitive.
+      if (perc == 1) { // eslint-disable-line eqeqeq
+        perc = this.v.c;
+      } else if (perc == 0) { // eslint-disable-line eqeqeq
+        perc = 0.999;
+      }
+      var pt1 = this.pointOnPath(perc, time);
+      var pt2 = this.pointOnPath(perc + 0.001, time);
+      var xLength = pt2[0] - pt1[0];
+      var yLength = pt2[1] - pt1[1];
+      var magnitude = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2));
+      if (magnitude === 0) {
+        return [0, 0];
+      }
+      var unitVector = vectorType === 'tangent' ? [xLength / magnitude, yLength / magnitude] : [-yLength / magnitude, xLength / magnitude];
+      return unitVector;
+    },
+    tangentOnPath: function (perc, time) {
+      return this.vectorOnPath(perc, time, 'tangent');
+    },
+    normalOnPath: function (perc, time) {
+      return this.vectorOnPath(perc, time, 'normal');
+    },
+    setGroupProperty: expressionHelpers.setGroupProperty,
+    getValueAtTime: expressionHelpers.getStaticValueAtTime,
+  };
+  extendPrototype([ShapeExpressions], ShapePropertyConstructorFunction);
+  extendPrototype([ShapeExpressions], KeyframedShapePropertyConstructorFunction);
+  KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime;
+  KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression;
+
+  var propertyGetShapeProp = ShapePropertyFactory.getShapeProp;
+  ShapePropertyFactory.getShapeProp = function (elem, data, type, arr, trims) {
+    var prop = propertyGetShapeProp(elem, data, type, arr, trims);
+    prop.propertyIndex = data.ix;
+    prop.lock = false;
+    if (type === 3) {
+      expressionHelpers.searchExpressions(elem, data.pt, prop);
+    } else if (type === 4) {
+      expressionHelpers.searchExpressions(elem, data.ks, prop);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  };
+}
+
+function initialize$1() {
+  addPropertyDecorator();
+}
+
+function addDecorator() {
+  function searchExpressions() {
+    if (this.data.d.x) {
+      this.calculateExpression = ExpressionManager.initiateExpression.bind(this)(this.elem, this.data.d, this);
+      this.addEffect(this.getExpressionValue.bind(this));
+      return true;
+    }
+    return null;
+  }
+
+  TextProperty.prototype.getExpressionValue = function (currentValue, text) {
+    var newValue = this.calculateExpression(text);
+    if (currentValue.t !== newValue) {
+      var newData = {};
+      this.copyData(newData, currentValue);
+      newData.t = newValue.toString();
+      newData.__complete = false;
+      return newData;
+    }
+    return currentValue;
+  };
+
+  TextProperty.prototype.searchProperty = function () {
+    var isKeyframed = this.searchKeyframes();
+    var hasExpressions = this.searchExpressions();
+    this.kf = isKeyframed || hasExpressions;
+    return this.kf;
+  };
+
+  TextProperty.prototype.searchExpressions = searchExpressions;
+}
+
+function initialize() {
+  addDecorator();
+}
+
+function SVGComposableEffect() {
+
+}
+SVGComposableEffect.prototype = {
+  createMergeNode: (resultId, ins) => {
+    var feMerge = createNS('feMerge');
+    feMerge.setAttribute('result', resultId);
+    var feMergeNode;
+    var i;
+    for (i = 0; i < ins.length; i += 1) {
+      feMergeNode = createNS('feMergeNode');
+      feMergeNode.setAttribute('in', ins[i]);
+      feMerge.appendChild(feMergeNode);
+      feMerge.appendChild(feMergeNode);
+    }
+    return feMerge;
+  },
+};
+
+var linearFilterValue = '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0';
+
+function SVGTintFilter(filter, filterManager, elem, id, source) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'linearRGB');
+  feColorMatrix.setAttribute('values', linearFilterValue + ' 1 0');
+  this.linearFilter = feColorMatrix;
+  feColorMatrix.setAttribute('result', id + '_tint_1');
+  filter.appendChild(feColorMatrix);
+  feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+  feColorMatrix.setAttribute('values', '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0');
+  feColorMatrix.setAttribute('result', id + '_tint_2');
+  filter.appendChild(feColorMatrix);
+  this.matrixFilter = feColorMatrix;
+  var feMerge = this.createMergeNode(
+    id,
+    [
+      source,
+      id + '_tint_1',
+      id + '_tint_2',
+    ]
+  );
+  filter.appendChild(feMerge);
+}
+extendPrototype([SVGComposableEffect], SVGTintFilter);
+
+SVGTintFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var colorBlack = this.filterManager.effectElements[0].p.v;
+    var colorWhite = this.filterManager.effectElements[1].p.v;
+    var opacity = this.filterManager.effectElements[2].p.v / 100;
+    this.linearFilter.setAttribute('values', linearFilterValue + ' ' + opacity + ' 0');
+    this.matrixFilter.setAttribute('values', (colorWhite[0] - colorBlack[0]) + ' 0 0 0 ' + colorBlack[0] + ' ' + (colorWhite[1] - colorBlack[1]) + ' 0 0 0 ' + colorBlack[1] + ' ' + (colorWhite[2] - colorBlack[2]) + ' 0 0 0 ' + colorBlack[2] + ' 0 0 0 1 0');
+  }
+};
+
+function SVGFillFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+  feColorMatrix.setAttribute('values', '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0');
+  feColorMatrix.setAttribute('result', id);
+  filter.appendChild(feColorMatrix);
+  this.matrixFilter = feColorMatrix;
+}
+
+SVGFillFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var color = this.filterManager.effectElements[2].p.v;
+    var opacity = this.filterManager.effectElements[6].p.v;
+    this.matrixFilter.setAttribute('values', '0 0 0 0 ' + color[0] + ' 0 0 0 0 ' + color[1] + ' 0 0 0 0 ' + color[2] + ' 0 0 0 ' + opacity + ' 0');
+  }
+};
+
+function SVGStrokeEffect(fil, filterManager, elem) {
+  this.initialized = false;
+  this.filterManager = filterManager;
+  this.elem = elem;
+  this.paths = [];
+}
+
+SVGStrokeEffect.prototype.initialize = function () {
+  var elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
+  var path;
+  var groupPath;
+  var i;
+  var len;
+  if (this.filterManager.effectElements[1].p.v === 1) {
+    len = this.elem.maskManager.masksProperties.length;
+    i = 0;
+  } else {
+    i = this.filterManager.effectElements[0].p.v - 1;
+    len = i + 1;
+  }
+  groupPath = createNS('g');
+  groupPath.setAttribute('fill', 'none');
+  groupPath.setAttribute('stroke-linecap', 'round');
+  groupPath.setAttribute('stroke-dashoffset', 1);
+  for (i; i < len; i += 1) {
+    path = createNS('path');
+    groupPath.appendChild(path);
+    this.paths.push({ p: path, m: i });
+  }
+  if (this.filterManager.effectElements[10].p.v === 3) {
+    var mask = createNS('mask');
+    var id = createElementID();
+    mask.setAttribute('id', id);
+    mask.setAttribute('mask-type', 'alpha');
+    mask.appendChild(groupPath);
+    this.elem.globalData.defs.appendChild(mask);
+    var g = createNS('g');
+    g.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+    while (elemChildren[0]) {
+      g.appendChild(elemChildren[0]);
+    }
+    this.elem.layerElement.appendChild(g);
+    this.masker = mask;
+    groupPath.setAttribute('stroke', '#fff');
+  } else if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
+    if (this.filterManager.effectElements[10].p.v === 2) {
+      elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
+      while (elemChildren.length) {
+        this.elem.layerElement.removeChild(elemChildren[0]);
+      }
+    }
+    this.elem.layerElement.appendChild(groupPath);
+    this.elem.layerElement.removeAttribute('mask');
+    groupPath.setAttribute('stroke', '#fff');
+  }
+  this.initialized = true;
+  this.pathMasker = groupPath;
+};
+
+SVGStrokeEffect.prototype.renderFrame = function (forceRender) {
+  if (!this.initialized) {
+    this.initialize();
+  }
+  var i;
+  var len = this.paths.length;
+  var mask;
+  var path;
+  for (i = 0; i < len; i += 1) {
+    if (this.paths[i].m !== -1) {
+      mask = this.elem.maskManager.viewData[this.paths[i].m];
+      path = this.paths[i].p;
+      if (forceRender || this.filterManager._mdf || mask.prop._mdf) {
+        path.setAttribute('d', mask.lastPath);
+      }
+      if (forceRender || this.filterManager.effectElements[9].p._mdf || this.filterManager.effectElements[4].p._mdf || this.filterManager.effectElements[7].p._mdf || this.filterManager.effectElements[8].p._mdf || mask.prop._mdf) {
+        var dasharrayValue;
+        if (this.filterManager.effectElements[7].p.v !== 0 || this.filterManager.effectElements[8].p.v !== 100) {
+          var s = Math.min(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
+          var e = Math.max(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
+          var l = path.getTotalLength();
+          dasharrayValue = '0 0 0 ' + l * s + ' ';
+          var lineLength = l * (e - s);
+          var segment = 1 + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
+          var units = Math.floor(lineLength / segment);
+          var j;
+          for (j = 0; j < units; j += 1) {
+            dasharrayValue += '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01 + ' ';
+          }
+          dasharrayValue += '0 ' + l * 10 + ' 0 0';
+        } else {
+          dasharrayValue = '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
+        }
+        path.setAttribute('stroke-dasharray', dasharrayValue);
+      }
+    }
+  }
+  if (forceRender || this.filterManager.effectElements[4].p._mdf) {
+    this.pathMasker.setAttribute('stroke-width', this.filterManager.effectElements[4].p.v * 2);
+  }
+
+  if (forceRender || this.filterManager.effectElements[6].p._mdf) {
+    this.pathMasker.setAttribute('opacity', this.filterManager.effectElements[6].p.v);
+  }
+  if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
+    if (forceRender || this.filterManager.effectElements[3].p._mdf) {
+      var color = this.filterManager.effectElements[3].p.v;
+      this.pathMasker.setAttribute('stroke', 'rgb(' + bmFloor(color[0] * 255) + ',' + bmFloor(color[1] * 255) + ',' + bmFloor(color[2] * 255) + ')');
+    }
+  }
+};
+
+function SVGTritoneFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'linearRGB');
+  feColorMatrix.setAttribute('values', '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0');
+  filter.appendChild(feColorMatrix);
+  var feComponentTransfer = createNS('feComponentTransfer');
+  feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+  feComponentTransfer.setAttribute('result', id);
+  this.matrixFilter = feComponentTransfer;
+  var feFuncR = createNS('feFuncR');
+  feFuncR.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncR);
+  this.feFuncR = feFuncR;
+  var feFuncG = createNS('feFuncG');
+  feFuncG.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncG);
+  this.feFuncG = feFuncG;
+  var feFuncB = createNS('feFuncB');
+  feFuncB.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncB);
+  this.feFuncB = feFuncB;
+  filter.appendChild(feComponentTransfer);
+}
+
+SVGTritoneFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var color1 = this.filterManager.effectElements[0].p.v;
+    var color2 = this.filterManager.effectElements[1].p.v;
+    var color3 = this.filterManager.effectElements[2].p.v;
+    var tableR = color3[0] + ' ' + color2[0] + ' ' + color1[0];
+    var tableG = color3[1] + ' ' + color2[1] + ' ' + color1[1];
+    var tableB = color3[2] + ' ' + color2[2] + ' ' + color1[2];
+    this.feFuncR.setAttribute('tableValues', tableR);
+    this.feFuncG.setAttribute('tableValues', tableG);
+    this.feFuncB.setAttribute('tableValues', tableB);
+  }
+};
+
+function SVGProLevelsFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var effectElements = this.filterManager.effectElements;
+  var feComponentTransfer = createNS('feComponentTransfer');
+
+  // Red
+  if (effectElements[10].p.k || effectElements[10].p.v !== 0 || effectElements[11].p.k || effectElements[11].p.v !== 1 || effectElements[12].p.k || effectElements[12].p.v !== 1 || effectElements[13].p.k || effectElements[13].p.v !== 0 || effectElements[14].p.k || effectElements[14].p.v !== 1) {
+    this.feFuncR = this.createFeFunc('feFuncR', feComponentTransfer);
+  }
+  // Green
+  if (effectElements[17].p.k || effectElements[17].p.v !== 0 || effectElements[18].p.k || effectElements[18].p.v !== 1 || effectElements[19].p.k || effectElements[19].p.v !== 1 || effectElements[20].p.k || effectElements[20].p.v !== 0 || effectElements[21].p.k || effectElements[21].p.v !== 1) {
+    this.feFuncG = this.createFeFunc('feFuncG', feComponentTransfer);
+  }
+  // Blue
+  if (effectElements[24].p.k || effectElements[24].p.v !== 0 || effectElements[25].p.k || effectElements[25].p.v !== 1 || effectElements[26].p.k || effectElements[26].p.v !== 1 || effectElements[27].p.k || effectElements[27].p.v !== 0 || effectElements[28].p.k || effectElements[28].p.v !== 1) {
+    this.feFuncB = this.createFeFunc('feFuncB', feComponentTransfer);
+  }
+  // Alpha
+  if (effectElements[31].p.k || effectElements[31].p.v !== 0 || effectElements[32].p.k || effectElements[32].p.v !== 1 || effectElements[33].p.k || effectElements[33].p.v !== 1 || effectElements[34].p.k || effectElements[34].p.v !== 0 || effectElements[35].p.k || effectElements[35].p.v !== 1) {
+    this.feFuncA = this.createFeFunc('feFuncA', feComponentTransfer);
+  }
+  // RGB
+  if (this.feFuncR || this.feFuncG || this.feFuncB || this.feFuncA) {
+    feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+    filter.appendChild(feComponentTransfer);
+  }
+
+  if (effectElements[3].p.k || effectElements[3].p.v !== 0 || effectElements[4].p.k || effectElements[4].p.v !== 1 || effectElements[5].p.k || effectElements[5].p.v !== 1 || effectElements[6].p.k || effectElements[6].p.v !== 0 || effectElements[7].p.k || effectElements[7].p.v !== 1) {
+    feComponentTransfer = createNS('feComponentTransfer');
+    feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+    feComponentTransfer.setAttribute('result', id);
+    filter.appendChild(feComponentTransfer);
+    this.feFuncRComposed = this.createFeFunc('feFuncR', feComponentTransfer);
+    this.feFuncGComposed = this.createFeFunc('feFuncG', feComponentTransfer);
+    this.feFuncBComposed = this.createFeFunc('feFuncB', feComponentTransfer);
+  }
+}
+
+SVGProLevelsFilter.prototype.createFeFunc = function (type, feComponentTransfer) {
+  var feFunc = createNS(type);
+  feFunc.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFunc);
+  return feFunc;
+};
+
+SVGProLevelsFilter.prototype.getTableValue = function (inputBlack, inputWhite, gamma, outputBlack, outputWhite) {
+  var cnt = 0;
+  var segments = 256;
+  var perc;
+  var min = Math.min(inputBlack, inputWhite);
+  var max = Math.max(inputBlack, inputWhite);
+  var table = Array.call(null, { length: segments });
+  var colorValue;
+  var pos = 0;
+  var outputDelta = outputWhite - outputBlack;
+  var inputDelta = inputWhite - inputBlack;
+  while (cnt <= 256) {
+    perc = cnt / 256;
+    if (perc <= min) {
+      colorValue = inputDelta < 0 ? outputWhite : outputBlack;
+    } else if (perc >= max) {
+      colorValue = inputDelta < 0 ? outputBlack : outputWhite;
+    } else {
+      colorValue = (outputBlack + outputDelta * Math.pow((perc - inputBlack) / inputDelta, 1 / gamma));
+    }
+    table[pos] = colorValue;
+    pos += 1;
+    cnt += 256 / (segments - 1);
+  }
+  return table.join(' ');
+};
+
+SVGProLevelsFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var val;
+    var effectElements = this.filterManager.effectElements;
+    if (this.feFuncRComposed && (forceRender || effectElements[3].p._mdf || effectElements[4].p._mdf || effectElements[5].p._mdf || effectElements[6].p._mdf || effectElements[7].p._mdf)) {
+      val = this.getTableValue(effectElements[3].p.v, effectElements[4].p.v, effectElements[5].p.v, effectElements[6].p.v, effectElements[7].p.v);
+      this.feFuncRComposed.setAttribute('tableValues', val);
+      this.feFuncGComposed.setAttribute('tableValues', val);
+      this.feFuncBComposed.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncR && (forceRender || effectElements[10].p._mdf || effectElements[11].p._mdf || effectElements[12].p._mdf || effectElements[13].p._mdf || effectElements[14].p._mdf)) {
+      val = this.getTableValue(effectElements[10].p.v, effectElements[11].p.v, effectElements[12].p.v, effectElements[13].p.v, effectElements[14].p.v);
+      this.feFuncR.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncG && (forceRender || effectElements[17].p._mdf || effectElements[18].p._mdf || effectElements[19].p._mdf || effectElements[20].p._mdf || effectElements[21].p._mdf)) {
+      val = this.getTableValue(effectElements[17].p.v, effectElements[18].p.v, effectElements[19].p.v, effectElements[20].p.v, effectElements[21].p.v);
+      this.feFuncG.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncB && (forceRender || effectElements[24].p._mdf || effectElements[25].p._mdf || effectElements[26].p._mdf || effectElements[27].p._mdf || effectElements[28].p._mdf)) {
+      val = this.getTableValue(effectElements[24].p.v, effectElements[25].p.v, effectElements[26].p.v, effectElements[27].p.v, effectElements[28].p.v);
+      this.feFuncB.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncA && (forceRender || effectElements[31].p._mdf || effectElements[32].p._mdf || effectElements[33].p._mdf || effectElements[34].p._mdf || effectElements[35].p._mdf)) {
+      val = this.getTableValue(effectElements[31].p.v, effectElements[32].p.v, effectElements[33].p.v, effectElements[34].p.v, effectElements[35].p.v);
+      this.feFuncA.setAttribute('tableValues', val);
+    }
+  }
+};
+
+function SVGDropShadowEffect(filter, filterManager, elem, id, source) {
+  var globalFilterSize = filterManager.container.globalData.renderConfig.filterSize;
+  var filterSize = filterManager.data.fs || globalFilterSize;
+  filter.setAttribute('x', filterSize.x || globalFilterSize.x);
+  filter.setAttribute('y', filterSize.y || globalFilterSize.y);
+  filter.setAttribute('width', filterSize.width || globalFilterSize.width);
+  filter.setAttribute('height', filterSize.height || globalFilterSize.height);
+  this.filterManager = filterManager;
+
+  var feGaussianBlur = createNS('feGaussianBlur');
+  feGaussianBlur.setAttribute('in', 'SourceAlpha');
+  feGaussianBlur.setAttribute('result', id + '_drop_shadow_1');
+  feGaussianBlur.setAttribute('stdDeviation', '0');
+  this.feGaussianBlur = feGaussianBlur;
+  filter.appendChild(feGaussianBlur);
+
+  var feOffset = createNS('feOffset');
+  feOffset.setAttribute('dx', '25');
+  feOffset.setAttribute('dy', '0');
+  feOffset.setAttribute('in', id + '_drop_shadow_1');
+  feOffset.setAttribute('result', id + '_drop_shadow_2');
+  this.feOffset = feOffset;
+  filter.appendChild(feOffset);
+  var feFlood = createNS('feFlood');
+  feFlood.setAttribute('flood-color', '#00ff00');
+  feFlood.setAttribute('flood-opacity', '1');
+  feFlood.setAttribute('result', id + '_drop_shadow_3');
+  this.feFlood = feFlood;
+  filter.appendChild(feFlood);
+
+  var feComposite = createNS('feComposite');
+  feComposite.setAttribute('in', id + '_drop_shadow_3');
+  feComposite.setAttribute('in2', id + '_drop_shadow_2');
+  feComposite.setAttribute('operator', 'in');
+  feComposite.setAttribute('result', id + '_drop_shadow_4');
+  filter.appendChild(feComposite);
+
+  var feMerge = this.createMergeNode(
+    id,
+    [
+      id + '_drop_shadow_4',
+      source,
+    ]
+  );
+  filter.appendChild(feMerge);
+  //
+}
+extendPrototype([SVGComposableEffect], SVGDropShadowEffect);
+
+SVGDropShadowEffect.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    if (forceRender || this.filterManager.effectElements[4].p._mdf) {
+      this.feGaussianBlur.setAttribute('stdDeviation', this.filterManager.effectElements[4].p.v / 4);
+    }
+    if (forceRender || this.filterManager.effectElements[0].p._mdf) {
+      var col = this.filterManager.effectElements[0].p.v;
+      this.feFlood.setAttribute('flood-color', rgbToHex(Math.round(col[0] * 255), Math.round(col[1] * 255), Math.round(col[2] * 255)));
+    }
+    if (forceRender || this.filterManager.effectElements[1].p._mdf) {
+      this.feFlood.setAttribute('flood-opacity', this.filterManager.effectElements[1].p.v / 255);
+    }
+    if (forceRender || this.filterManager.effectElements[2].p._mdf || this.filterManager.effectElements[3].p._mdf) {
+      var distance = this.filterManager.effectElements[3].p.v;
+      var angle = (this.filterManager.effectElements[2].p.v - 90) * degToRads;
+      var x = distance * Math.cos(angle);
+      var y = distance * Math.sin(angle);
+      this.feOffset.setAttribute('dx', x);
+      this.feOffset.setAttribute('dy', y);
+    }
+  }
+};
+
+var _svgMatteSymbols = [];
+
+function SVGMatte3Effect(filterElem, filterManager, elem) {
+  this.initialized = false;
+  this.filterManager = filterManager;
+  this.filterElem = filterElem;
+  this.elem = elem;
+  elem.matteElement = createNS('g');
+  elem.matteElement.appendChild(elem.layerElement);
+  elem.matteElement.appendChild(elem.transformedElement);
+  elem.baseElement = elem.matteElement;
+}
+
+SVGMatte3Effect.prototype.findSymbol = function (mask) {
+  var i = 0;
+  var len = _svgMatteSymbols.length;
+  while (i < len) {
+    if (_svgMatteSymbols[i] === mask) {
+      return _svgMatteSymbols[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+SVGMatte3Effect.prototype.replaceInParent = function (mask, symbolId) {
+  var parentNode = mask.layerElement.parentNode;
+  if (!parentNode) {
+    return;
+  }
+  var children = parentNode.children;
+  var i = 0;
+  var len = children.length;
+  while (i < len) {
+    if (children[i] === mask.layerElement) {
+      break;
+    }
+    i += 1;
+  }
+  var nextChild;
+  if (i <= len - 2) {
+    nextChild = children[i + 1];
+  }
+  var useElem = createNS('use');
+  useElem.setAttribute('href', '#' + symbolId);
+  if (nextChild) {
+    parentNode.insertBefore(useElem, nextChild);
+  } else {
+    parentNode.appendChild(useElem);
+  }
+};
+
+SVGMatte3Effect.prototype.setElementAsMask = function (elem, mask) {
+  if (!this.findSymbol(mask)) {
+    var symbolId = createElementID();
+    var masker = createNS('mask');
+    masker.setAttribute('id', mask.layerId);
+    masker.setAttribute('mask-type', 'alpha');
+    _svgMatteSymbols.push(mask);
+    var defs = elem.globalData.defs;
+    defs.appendChild(masker);
+    var symbol = createNS('symbol');
+    symbol.setAttribute('id', symbolId);
+    this.replaceInParent(mask, symbolId);
+    symbol.appendChild(mask.layerElement);
+    defs.appendChild(symbol);
+    var useElem = createNS('use');
+    useElem.setAttribute('href', '#' + symbolId);
+    masker.appendChild(useElem);
+    mask.data.hd = false;
+    mask.show();
+  }
+  elem.setMatte(mask.layerId);
+};
+
+SVGMatte3Effect.prototype.initialize = function () {
+  var ind = this.filterManager.effectElements[0].p.v;
+  var elements = this.elem.comp.elements;
+  var i = 0;
+  var len = elements.length;
+  while (i < len) {
+    if (elements[i] && elements[i].data.ind === ind) {
+      this.setElementAsMask(this.elem, elements[i]);
+    }
+    i += 1;
+  }
+  this.initialized = true;
+};
+
+SVGMatte3Effect.prototype.renderFrame = function () {
+  if (!this.initialized) {
+    this.initialize();
+  }
+};
+
+function SVGGaussianBlurEffect(filter, filterManager, elem, id) {
+  // Outset the filter region by 100% on all sides to accommodate blur expansion.
+  filter.setAttribute('x', '-100%');
+  filter.setAttribute('y', '-100%');
+  filter.setAttribute('width', '300%');
+  filter.setAttribute('height', '300%');
+
+  this.filterManager = filterManager;
+  var feGaussianBlur = createNS('feGaussianBlur');
+  feGaussianBlur.setAttribute('result', id);
+  filter.appendChild(feGaussianBlur);
+  this.feGaussianBlur = feGaussianBlur;
+}
+
+SVGGaussianBlurEffect.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    // Empirical value, matching AE's blur appearance.
+    var kBlurrinessToSigma = 0.3;
+    var sigma = this.filterManager.effectElements[0].p.v * kBlurrinessToSigma;
+
+    // Dimensions mapping:
+    //
+    //   1 -> horizontal & vertical
+    //   2 -> horizontal only
+    //   3 -> vertical only
+    //
+    var dimensions = this.filterManager.effectElements[1].p.v;
+    var sigmaX = (dimensions == 3) ? 0 : sigma; // eslint-disable-line eqeqeq
+    var sigmaY = (dimensions == 2) ? 0 : sigma; // eslint-disable-line eqeqeq
+
+    this.feGaussianBlur.setAttribute('stdDeviation', sigmaX + ' ' + sigmaY);
+
+    // Repeat edges mapping:
+    //
+    //   0 -> off -> duplicate
+    //   1 -> on  -> wrap
+    var edgeMode = (this.filterManager.effectElements[2].p.v == 1) ? 'wrap' : 'duplicate'; // eslint-disable-line eqeqeq
+    this.feGaussianBlur.setAttribute('edgeMode', edgeMode);
+  }
+};
+
+function TransformEffect() {
+}
+
+TransformEffect.prototype.init = function (effectsManager) {
+  this.effectsManager = effectsManager;
+  this.type = effectTypes.TRANSFORM_EFFECT;
+  this.matrix = new Matrix();
+  this.opacity = -1;
+  this._mdf = false;
+  this._opMdf = false;
+};
+
+TransformEffect.prototype.renderFrame = function (forceFrame) {
+  this._opMdf = false;
+  this._mdf = false;
+  if (forceFrame || this.effectsManager._mdf) {
+    var effectElements = this.effectsManager.effectElements;
+    var anchor = effectElements[0].p.v;
+    var position = effectElements[1].p.v;
+    var isUniformScale = effectElements[2].p.v === 1;
+    var scaleHeight = effectElements[3].p.v;
+    var scaleWidth = isUniformScale ? scaleHeight : effectElements[4].p.v;
+    var skew = effectElements[5].p.v;
+    var skewAxis = effectElements[6].p.v;
+    var rotation = effectElements[7].p.v;
+    this.matrix.reset();
+    this.matrix.translate(-anchor[0], -anchor[1], anchor[2]);
+    this.matrix.scale(scaleWidth * 0.01, scaleHeight * 0.01, 1);
+    this.matrix.rotate(-rotation * degToRads);
+    this.matrix.skewFromAxis(-skew * degToRads, (skewAxis + 90) * degToRads);
+    this.matrix.translate(position[0], position[1], 0);
+    this._mdf = true;
+    if (this.opacity !== effectElements[8].p.v) {
+      this.opacity = effectElements[8].p.v;
+      this._opMdf = true;
+    }
+  }
+};
+
+function SVGTransformEffect(_, filterManager) {
+  this.init(filterManager);
+}
+
+extendPrototype([TransformEffect], SVGTransformEffect);
+
+function CVTransformEffect(effectsManager) {
+  this.init(effectsManager);
+}
+extendPrototype([TransformEffect], CVTransformEffect);
+
+// Registering renderers
+registerRenderer('canvas', CanvasRenderer);
+registerRenderer('html', HybridRenderer);
+registerRenderer('svg', SVGRenderer);
+
+// Registering shape modifiers
+ShapeModifiers.registerModifier('tm', TrimModifier);
+ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
+ShapeModifiers.registerModifier('rp', RepeaterModifier);
+ShapeModifiers.registerModifier('rd', RoundCornersModifier);
+ShapeModifiers.registerModifier('zz', ZigZagModifier);
+ShapeModifiers.registerModifier('op', OffsetPathModifier);
+
+// Registering expression plugin
+setExpressionsPlugin(Expressions);
+setExpressionInterfaces(getInterface);
+initialize$1();
+initialize();
+
+// Registering svg effects
+registerEffect$1(20, SVGTintFilter, true);
+registerEffect$1(21, SVGFillFilter, true);
+registerEffect$1(22, SVGStrokeEffect, false);
+registerEffect$1(23, SVGTritoneFilter, true);
+registerEffect$1(24, SVGProLevelsFilter, true);
+registerEffect$1(25, SVGDropShadowEffect, true);
+registerEffect$1(28, SVGMatte3Effect, false);
+registerEffect$1(29, SVGGaussianBlurEffect, true);
+registerEffect$1(35, SVGTransformEffect, false);
+registerEffect(35, CVTransformEffect);
+
+export { lottie as default };
diff --git a/build/player/esm/lottie_canvas.min.js b/build/player/esm/lottie_canvas.min.js
new file mode 100644
index 0000000..8a0d406
--- /dev/null
+++ b/build/player/esm/lottie_canvas.min.js
@@ -0,0 +1,16363 @@
+const svgNS = 'http://www.w3.org/2000/svg';
+
+let locationHref = '';
+let _useWebWorker = false;
+
+const initialDefaultFrame = -999999;
+
+const setWebWorker = (flag) => { _useWebWorker = !!flag; };
+const getWebWorker = () => _useWebWorker;
+
+const setLocationHref = (value) => { locationHref = value; };
+const getLocationHref = () => locationHref;
+
+function createTag(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElement(type);
+}
+
+function extendPrototype(sources, destination) {
+  var i;
+  var len = sources.length;
+  var sourcePrototype;
+  for (i = 0; i < len; i += 1) {
+    sourcePrototype = sources[i].prototype;
+    for (var attr in sourcePrototype) {
+      if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
+    }
+  }
+}
+
+function getDescriptor(object, prop) {
+  return Object.getOwnPropertyDescriptor(object, prop);
+}
+
+function createProxyFunction(prototype) {
+  function ProxyFunction() {}
+  ProxyFunction.prototype = prototype;
+  return ProxyFunction;
+}
+
+// import Howl from '../../3rd_party/howler';
+
+const audioControllerFactory = (function () {
+  function AudioController(audioFactory) {
+    this.audios = [];
+    this.audioFactory = audioFactory;
+    this._volume = 1;
+    this._isMuted = false;
+  }
+
+  AudioController.prototype = {
+    addAudio: function (audio) {
+      this.audios.push(audio);
+    },
+    pause: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].pause();
+      }
+    },
+    resume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].resume();
+      }
+    },
+    setRate: function (rateValue) {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].setRate(rateValue);
+      }
+    },
+    createAudio: function (assetPath) {
+      if (this.audioFactory) {
+        return this.audioFactory(assetPath);
+      } if (window.Howl) {
+        return new window.Howl({
+          src: [assetPath],
+        });
+      }
+      return {
+        isPlaying: false,
+        play: function () { this.isPlaying = true; },
+        seek: function () { this.isPlaying = false; },
+        playing: function () {},
+        rate: function () {},
+        setVolume: function () {},
+      };
+    },
+    setAudioFactory: function (audioFactory) {
+      this.audioFactory = audioFactory;
+    },
+    setVolume: function (value) {
+      this._volume = value;
+      this._updateVolume();
+    },
+    mute: function () {
+      this._isMuted = true;
+      this._updateVolume();
+    },
+    unmute: function () {
+      this._isMuted = false;
+      this._updateVolume();
+    },
+    getVolume: function () {
+      return this._volume;
+    },
+    _updateVolume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
+      }
+    },
+  };
+
+  return function () {
+    return new AudioController();
+  };
+}());
+
+const createTypedArray = (function () {
+  function createRegularArray(type, len) {
+    var i = 0;
+    var arr = [];
+    var value;
+    switch (type) {
+      case 'int16':
+      case 'uint8c':
+        value = 1;
+        break;
+      default:
+        value = 1.1;
+        break;
+    }
+    for (i = 0; i < len; i += 1) {
+      arr.push(value);
+    }
+    return arr;
+  }
+  function createTypedArrayFactory(type, len) {
+    if (type === 'float32') {
+      return new Float32Array(len);
+    } if (type === 'int16') {
+      return new Int16Array(len);
+    } if (type === 'uint8c') {
+      return new Uint8ClampedArray(len);
+    }
+    return createRegularArray(type, len);
+  }
+  if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
+    return createTypedArrayFactory;
+  }
+  return createRegularArray;
+}());
+
+function createSizedArray(len) {
+  return Array.apply(null, { length: len });
+}
+
+let subframeEnabled = true;
+let expressionsPlugin = null;
+let expressionsInterfaces = null;
+let idPrefix$1 = '';
+const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+let _shouldRoundValues = false;
+const bmPow = Math.pow;
+const bmSqrt = Math.sqrt;
+const bmFloor = Math.floor;
+const bmMax = Math.max;
+const bmMin = Math.min;
+
+const BMMath = {};
+(function () {
+  var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
+  var i;
+  var len = propertyNames.length;
+  for (i = 0; i < len; i += 1) {
+    BMMath[propertyNames[i]] = Math[propertyNames[i]];
+  }
+}());
+
+function ProjectInterface$1() { return {}; }
+BMMath.random = Math.random;
+BMMath.abs = function (val) {
+  var tOfVal = typeof val;
+  if (tOfVal === 'object' && val.length) {
+    var absArr = createSizedArray(val.length);
+    var i;
+    var len = val.length;
+    for (i = 0; i < len; i += 1) {
+      absArr[i] = Math.abs(val[i]);
+    }
+    return absArr;
+  }
+  return Math.abs(val);
+};
+let defaultCurveSegments = 150;
+const degToRads = Math.PI / 180;
+const roundCorner = 0.5519;
+
+function roundValues(flag) {
+  _shouldRoundValues = !!flag;
+}
+
+function bmRnd(value) {
+  if (_shouldRoundValues) {
+    return Math.round(value);
+  }
+  return value;
+}
+
+function styleDiv(element) {
+  element.style.position = 'absolute';
+  element.style.top = 0;
+  element.style.left = 0;
+  element.style.display = 'block';
+  element.style.transformOrigin = '0 0';
+  element.style.webkitTransformOrigin = '0 0';
+  element.style.backfaceVisibility = 'visible';
+  element.style.webkitBackfaceVisibility = 'visible';
+  element.style.transformStyle = 'preserve-3d';
+  element.style.webkitTransformStyle = 'preserve-3d';
+  element.style.mozTransformStyle = 'preserve-3d';
+}
+
+function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
+  this.type = type;
+  this.currentTime = currentTime;
+  this.totalTime = totalTime;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteEvent(type, frameMultiplier) {
+  this.type = type;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
+  this.type = type;
+  this.currentLoop = currentLoop;
+  this.totalLoops = totalLoops;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMSegmentStartEvent(type, firstFrame, totalFrames) {
+  this.type = type;
+  this.firstFrame = firstFrame;
+  this.totalFrames = totalFrames;
+}
+
+function BMDestroyEvent(type, target) {
+  this.type = type;
+  this.target = target;
+}
+
+function BMRenderFrameErrorEvent(nativeError, currentTime) {
+  this.type = 'renderFrameError';
+  this.nativeError = nativeError;
+  this.currentTime = currentTime;
+}
+
+function BMConfigErrorEvent(nativeError) {
+  this.type = 'configError';
+  this.nativeError = nativeError;
+}
+
+function BMAnimationConfigErrorEvent(type, nativeError) {
+  this.type = type;
+  this.nativeError = nativeError;
+}
+
+const createElementID = (function () {
+  var _count = 0;
+  return function createID() {
+    _count += 1;
+    return idPrefix$1 + '__lottie_element_' + _count;
+  };
+}());
+
+function HSVtoRGB(h, s, v) {
+  var r;
+  var g;
+  var b;
+  var i;
+  var f;
+  var p;
+  var q;
+  var t;
+  i = Math.floor(h * 6);
+  f = h * 6 - i;
+  p = v * (1 - s);
+  q = v * (1 - f * s);
+  t = v * (1 - (1 - f) * s);
+  switch (i % 6) {
+    case 0: r = v; g = t; b = p; break;
+    case 1: r = q; g = v; b = p; break;
+    case 2: r = p; g = v; b = t; break;
+    case 3: r = p; g = q; b = v; break;
+    case 4: r = t; g = p; b = v; break;
+    case 5: r = v; g = p; b = q; break;
+    default: break;
+  }
+  return [r,
+    g,
+    b];
+}
+
+function RGBtoHSV(r, g, b) {
+  var max = Math.max(r, g, b);
+  var min = Math.min(r, g, b);
+  var d = max - min;
+  var h;
+  var s = (max === 0 ? 0 : d / max);
+  var v = max / 255;
+
+  switch (max) {
+    case min: h = 0; break;
+    case r: h = (g - b) + d * (g < b ? 6 : 0); h /= 6 * d; break;
+    case g: h = (b - r) + d * 2; h /= 6 * d; break;
+    case b: h = (r - g) + d * 4; h /= 6 * d; break;
+    default: break;
+  }
+
+  return [
+    h,
+    s,
+    v,
+  ];
+}
+
+function addSaturationToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[1] += offset;
+  if (hsv[1] > 1) {
+    hsv[1] = 1;
+  } else if (hsv[1] <= 0) {
+    hsv[1] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addBrightnessToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[2] += offset;
+  if (hsv[2] > 1) {
+    hsv[2] = 1;
+  } else if (hsv[2] < 0) {
+    hsv[2] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addHueToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[0] += offset / 360;
+  if (hsv[0] > 1) {
+    hsv[0] -= 1;
+  } else if (hsv[0] < 0) {
+    hsv[0] += 1;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+const rgbToHex = (function () {
+  var colorMap = [];
+  var i;
+  var hex;
+  for (i = 0; i < 256; i += 1) {
+    hex = i.toString(16);
+    colorMap[i] = hex.length === 1 ? '0' + hex : hex;
+  }
+
+  return function (r, g, b) {
+    if (r < 0) {
+      r = 0;
+    }
+    if (g < 0) {
+      g = 0;
+    }
+    if (b < 0) {
+      b = 0;
+    }
+    return '#' + colorMap[r] + colorMap[g] + colorMap[b];
+  };
+}());
+
+const setSubframeEnabled = (flag) => { subframeEnabled = !!flag; };
+const getSubframeEnabled = () => subframeEnabled;
+const setExpressionsPlugin = (value) => { expressionsPlugin = value; };
+const getExpressionsPlugin = () => expressionsPlugin;
+const setExpressionInterfaces = (value) => { expressionsInterfaces = value; };
+const getExpressionInterfaces = () => expressionsInterfaces;
+const setDefaultCurveSegments = (value) => { defaultCurveSegments = value; };
+const getDefaultCurveSegments = () => defaultCurveSegments;
+const setIdPrefix = (value) => { idPrefix$1 = value; };
+const getIdPrefix = () => idPrefix$1;
+
+function createNS(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElementNS(svgNS, type);
+}
+
+const dataManager = (function () {
+  var _counterId = 1;
+  var processes = [];
+  var workerFn;
+  var workerInstance;
+  var workerProxy = {
+    onmessage: function () {
+
+    },
+    postMessage: function (path) {
+      workerFn({
+        data: path,
+      });
+    },
+  };
+  var _workerSelf = {
+    postMessage: function (data) {
+      workerProxy.onmessage({
+        data: data,
+      });
+    },
+  };
+  function createWorker(fn) {
+    if (window.Worker && window.Blob && getWebWorker()) {
+      var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      var url = URL.createObjectURL(blob);
+      return new Worker(url);
+    }
+    workerFn = fn;
+    return workerProxy;
+  }
+
+  function setupWorker() {
+    if (!workerInstance) {
+      workerInstance = createWorker(function workerStart(e) {
+        function dataFunctionManager() {
+          function completeLayers(layers, comps) {
+            var layerData;
+            var i;
+            var len = layers.length;
+            var j;
+            var jLen;
+            var k;
+            var kLen;
+            for (i = 0; i < len; i += 1) {
+              layerData = layers[i];
+              if (('ks' in layerData) && !layerData.completed) {
+                layerData.completed = true;
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      convertPathsToAbsoluteValues(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) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 0) {
+                  layerData.layers = findCompLayers(layerData.refId, comps);
+                  completeLayers(layerData.layers, comps);
+                } else if (layerData.ty === 4) {
+                  completeShapes(layerData.shapes);
+                } else if (layerData.ty === 5) {
+                  completeText(layerData);
+                }
+              }
+            }
+          }
+
+          function completeChars(chars, assets) {
+            if (chars) {
+              var i = 0;
+              var len = chars.length;
+              for (i = 0; i < len; i += 1) {
+                if (chars[i].t === 1) {
+                  // var compData = findComp(chars[i].data.refId, assets);
+                  chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                  // chars[i].data.ip = 0;
+                  // chars[i].data.op = 99999;
+                  // chars[i].data.st = 0;
+                  // chars[i].data.sr = 1;
+                  // chars[i].w = compData.w;
+                  // chars[i].data.ks = {
+                  //   a: { k: [0, 0, 0], a: 0 },
+                  //   p: { k: [0, -compData.h, 0], a: 0 },
+                  //   r: { k: 0, a: 0 },
+                  //   s: { k: [100, 100], a: 0 },
+                  //   o: { k: 100, a: 0 },
+                  // };
+                  completeLayers(chars[i].data.layers, assets);
+                }
+              }
+            }
+          }
+
+          function findComp(id, comps) {
+            var i = 0;
+            var len = comps.length;
+            while (i < len) {
+              if (comps[i].id === id) {
+                return comps[i];
+              }
+              i += 1;
+            }
+            return null;
+          }
+
+          function findCompLayers(id, comps) {
+            var comp = findComp(id, comps);
+            if (comp) {
+              if (!comp.layers.__used) {
+                comp.layers.__used = true;
+                return comp.layers;
+              }
+              return JSON.parse(JSON.stringify(comp.layers));
+            }
+            return null;
+          }
+
+          function completeShapes(arr) {
+            var i;
+            var len = arr.length;
+            var j;
+            var jLen;
+            for (i = len - 1; i >= 0; i -= 1) {
+              if (arr[i].ty === 'sh') {
+                if (arr[i].ks.k.i) {
+                  convertPathsToAbsoluteValues(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) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
+                    }
+                    if (arr[i].ks.k[j].e) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
+                    }
+                  }
+                }
+              } else if (arr[i].ty === 'gr') {
+                completeShapes(arr[i].it);
+              }
+            }
+          }
+
+          function convertPathsToAbsoluteValues(path) {
+            var i;
+            var len = path.i.length;
+            for (i = 0; i < len; i += 1) {
+              path.i[i][0] += path.v[i][0];
+              path.i[i][1] += path.v[i][1];
+              path.o[i][0] += path.v[i][0];
+              path.o[i][1] += path.v[i][1];
+            }
+          }
+
+          function checkVersion(minimum, animVersionString) {
+            var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
+            if (minimum[0] > animVersion[0]) {
+              return true;
+            } if (animVersion[0] > minimum[0]) {
+              return false;
+            }
+            if (minimum[1] > animVersion[1]) {
+              return true;
+            } if (animVersion[1] > minimum[1]) {
+              return false;
+            }
+            if (minimum[2] > animVersion[2]) {
+              return true;
+            } if (animVersion[2] > minimum[2]) {
+              return false;
+            }
+            return null;
+          }
+
+          var checkText = (function () {
+            var minimumVersion = [4, 4, 14];
+
+            function updateTextLayer(textLayer) {
+              var documentData = textLayer.t.d;
+              textLayer.t.d = {
+                k: [
+                  {
+                    s: documentData,
+                    t: 0,
+                  },
+                ],
+              };
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkChars = (function () {
+            var minimumVersion = [4, 7, 99];
+            return function (animationData) {
+              if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
+                var i;
+                var len = animationData.chars.length;
+                for (i = 0; i < len; i += 1) {
+                  var charData = animationData.chars[i];
+                  if (charData.data && charData.data.shapes) {
+                    completeShapes(charData.data.shapes);
+                    charData.data.ip = 0;
+                    charData.data.op = 99999;
+                    charData.data.st = 0;
+                    charData.data.sr = 1;
+                    charData.data.ks = {
+                      p: { k: [0, 0], a: 0 },
+                      s: { k: [100, 100], a: 0 },
+                      a: { k: [0, 0], a: 0 },
+                      r: { k: 0, a: 0 },
+                      o: { k: 100, a: 0 },
+                    };
+                    if (!animationData.chars[i].t) {
+                      charData.data.shapes.push(
+                        {
+                          ty: 'no',
+                        }
+                      );
+                      charData.data.shapes[0].it.push(
+                        {
+                          p: { k: [0, 0], a: 0 },
+                          s: { k: [100, 100], a: 0 },
+                          a: { k: [0, 0], a: 0 },
+                          r: { k: 0, a: 0 },
+                          o: { k: 100, a: 0 },
+                          sk: { k: 0, a: 0 },
+                          sa: { k: 0, a: 0 },
+                          ty: 'tr',
+                        }
+                      );
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkPathProperties = (function () {
+            var minimumVersion = [5, 7, 15];
+
+            function updateTextLayer(textLayer) {
+              var pathData = textLayer.t.p;
+              if (typeof pathData.a === 'number') {
+                pathData.a = {
+                  a: 0,
+                  k: pathData.a,
+                };
+              }
+              if (typeof pathData.p === 'number') {
+                pathData.p = {
+                  a: 0,
+                  k: pathData.p,
+                };
+              }
+              if (typeof pathData.r === 'number') {
+                pathData.r = {
+                  a: 0,
+                  k: pathData.r,
+                };
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkColors = (function () {
+            var minimumVersion = [4, 1, 9];
+
+            function iterateShapes(shapes) {
+              var i;
+              var len = shapes.length;
+              var j;
+              var jLen;
+              for (i = 0; i < len; i += 1) {
+                if (shapes[i].ty === 'gr') {
+                  iterateShapes(shapes[i].it);
+                } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
+                  if (shapes[i].c.k && shapes[i].c.k[0].i) {
+                    jLen = shapes[i].c.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (shapes[i].c.k[j].s) {
+                        shapes[i].c.k[j].s[0] /= 255;
+                        shapes[i].c.k[j].s[1] /= 255;
+                        shapes[i].c.k[j].s[2] /= 255;
+                        shapes[i].c.k[j].s[3] /= 255;
+                      }
+                      if (shapes[i].c.k[j].e) {
+                        shapes[i].c.k[j].e[0] /= 255;
+                        shapes[i].c.k[j].e[1] /= 255;
+                        shapes[i].c.k[j].e[2] /= 255;
+                        shapes[i].c.k[j].e[3] /= 255;
+                      }
+                    }
+                  } else {
+                    shapes[i].c.k[0] /= 255;
+                    shapes[i].c.k[1] /= 255;
+                    shapes[i].c.k[2] /= 255;
+                    shapes[i].c.k[3] /= 255;
+                  }
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 4) {
+                  iterateShapes(layers[i].shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkShapes = (function () {
+            var minimumVersion = [4, 4, 18];
+
+            function completeClosingShapes(arr) {
+              var i;
+              var len = arr.length;
+              var j;
+              var jLen;
+              for (i = len - 1; i >= 0; i -= 1) {
+                if (arr[i].ty === 'sh') {
+                  if (arr[i].ks.k.i) {
+                    arr[i].ks.k.c = arr[i].closed;
+                  } else {
+                    jLen = arr[i].ks.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (arr[i].ks.k[j].s) {
+                        arr[i].ks.k[j].s[0].c = arr[i].closed;
+                      }
+                      if (arr[i].ks.k[j].e) {
+                        arr[i].ks.k[j].e[0].c = arr[i].closed;
+                      }
+                    }
+                  }
+                } else if (arr[i].ty === 'gr') {
+                  completeClosingShapes(arr[i].it);
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var layerData;
+              var i;
+              var len = layers.length;
+              var j;
+              var jLen;
+              var k;
+              var kLen;
+              for (i = 0; i < len; i += 1) {
+                layerData = layers[i];
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      maskProps[j].pt.k.c = maskProps[j].cl;
+                    } else {
+                      kLen = maskProps[j].pt.k.length;
+                      for (k = 0; k < kLen; k += 1) {
+                        if (maskProps[j].pt.k[k].s) {
+                          maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 4) {
+                  completeClosingShapes(layerData.shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          function completeData(animationData) {
+            if (animationData.__complete) {
+              return;
+            }
+            checkColors(animationData);
+            checkText(animationData);
+            checkChars(animationData);
+            checkPathProperties(animationData);
+            checkShapes(animationData);
+            completeLayers(animationData.layers, animationData.assets);
+            completeChars(animationData.chars, animationData.assets);
+            animationData.__complete = true;
+          }
+
+          function completeText(data) {
+            if (data.t.a.length === 0 && !('m' in data.t.p)) {
+              // data.singleShape = true;
+            }
+          }
+
+          var moduleOb = {};
+          moduleOb.completeData = completeData;
+          moduleOb.checkColors = checkColors;
+          moduleOb.checkChars = checkChars;
+          moduleOb.checkPathProperties = checkPathProperties;
+          moduleOb.checkShapes = checkShapes;
+          moduleOb.completeLayers = completeLayers;
+
+          return moduleOb;
+        }
+        if (!_workerSelf.dataManager) {
+          _workerSelf.dataManager = dataFunctionManager();
+        }
+
+        if (!_workerSelf.assetLoader) {
+          _workerSelf.assetLoader = (function () {
+            function formatResponse(xhr) {
+              // using typeof doubles the time of execution of this method,
+              // so if available, it's better to use the header to validate the type
+              var contentTypeHeader = xhr.getResponseHeader('content-type');
+              if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
+                return xhr.response;
+              }
+              if (xhr.response && typeof xhr.response === 'object') {
+                return xhr.response;
+              } if (xhr.response && typeof xhr.response === 'string') {
+                return JSON.parse(xhr.response);
+              } if (xhr.responseText) {
+                return JSON.parse(xhr.responseText);
+              }
+              return null;
+            }
+
+            function loadAsset(path, fullPath, callback, errorCallback) {
+              var response;
+              var xhr = new XMLHttpRequest();
+              // set responseType after calling open or IE will break.
+              try {
+                // This crashes on Android WebView prior to KitKat
+                xhr.responseType = 'json';
+              } catch (err) {} // eslint-disable-line no-empty
+              xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4) {
+                  if (xhr.status === 200) {
+                    response = formatResponse(xhr);
+                    callback(response);
+                  } else {
+                    try {
+                      response = formatResponse(xhr);
+                      callback(response);
+                    } catch (err) {
+                      if (errorCallback) {
+                        errorCallback(err);
+                      }
+                    }
+                  }
+                }
+              };
+              try {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), path, true);
+              } catch (error) {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
+              }
+              xhr.send();
+            }
+            return {
+              load: loadAsset,
+            };
+          }());
+        }
+
+        if (e.data.type === 'loadAnimation') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.dataManager.completeData(data);
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        } else if (e.data.type === 'complete') {
+          var animation = e.data.animation;
+          _workerSelf.dataManager.completeData(animation);
+          _workerSelf.postMessage({
+            id: e.data.id,
+            payload: animation,
+            status: 'success',
+          });
+        } else if (e.data.type === 'loadData') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        }
+      });
+
+      workerInstance.onmessage = function (event) {
+        var data = event.data;
+        var id = data.id;
+        var process = processes[id];
+        processes[id] = null;
+        if (data.status === 'success') {
+          process.onComplete(data.payload);
+        } else if (process.onError) {
+          process.onError();
+        }
+      };
+    }
+  }
+
+  function createProcess(onComplete, onError) {
+    _counterId += 1;
+    var id = 'processId_' + _counterId;
+    processes[id] = {
+      onComplete: onComplete,
+      onError: onError,
+    };
+    return id;
+  }
+
+  function loadAnimation(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadAnimation',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function loadData(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadData',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function completeAnimation(anim, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'complete',
+      animation: anim,
+      id: processId,
+    });
+  }
+
+  return {
+    loadAnimation: loadAnimation,
+    loadData: loadData,
+    completeAnimation: completeAnimation,
+  };
+}());
+
+const ImagePreloader = (function () {
+  var proxyImage = (function () {
+    var canvas = createTag('canvas');
+    canvas.width = 1;
+    canvas.height = 1;
+    var ctx = canvas.getContext('2d');
+    ctx.fillStyle = 'rgba(0,0,0,0)';
+    ctx.fillRect(0, 0, 1, 1);
+    return canvas;
+  }());
+
+  function imageLoaded() {
+    this.loadedAssets += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+  function footageLoaded() {
+    this.loadedFootagesCount += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+
+  function getAssetsPath(assetData, assetsPath, originalPath) {
+    var path = '';
+    if (assetData.e) {
+      path = assetData.p;
+    } else if (assetsPath) {
+      var imagePath = assetData.p;
+      if (imagePath.indexOf('images/') !== -1) {
+        imagePath = imagePath.split('/')[1];
+      }
+      path = assetsPath + imagePath;
+    } else {
+      path = originalPath;
+      path += assetData.u ? assetData.u : '';
+      path += assetData.p;
+    }
+    return path;
+  }
+
+  function testImageLoaded(img) {
+    var _count = 0;
+    var intervalId = setInterval(function () {
+      var box = img.getBBox();
+      if (box.width || _count > 500) {
+        this._imageLoaded();
+        clearInterval(intervalId);
+      }
+      _count += 1;
+    }.bind(this), 50);
+  }
+
+  function createImageData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createNS('image');
+    if (isSafari) {
+      this.testImageLoaded(img);
+    } else {
+      img.addEventListener('load', this._imageLoaded, false);
+    }
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
+    if (this._elementHelper.append) {
+      this._elementHelper.append(img);
+    } else {
+      this._elementHelper.appendChild(img);
+    }
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createImgData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createTag('img');
+    img.crossOrigin = 'anonymous';
+    img.addEventListener('load', this._imageLoaded, false);
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.src = path;
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createFootageData(data) {
+    var ob = {
+      assetData: data,
+    };
+    var path = getAssetsPath(data, this.assetsPath, this.path);
+    dataManager.loadData(path, function (footageData) {
+      ob.img = footageData;
+      this._footageLoaded();
+    }.bind(this), function () {
+      ob.img = {};
+      this._footageLoaded();
+    }.bind(this));
+    return ob;
+  }
+
+  function loadAssets(assets, cb) {
+    this.imagesLoadedCb = cb;
+    var i;
+    var len = assets.length;
+    for (i = 0; i < len; i += 1) {
+      if (!assets[i].layers) {
+        if (!assets[i].t || assets[i].t === 'seq') {
+          this.totalImages += 1;
+          this.images.push(this._createImageData(assets[i]));
+        } else if (assets[i].t === 3) {
+          this.totalFootages += 1;
+          this.images.push(this.createFootageData(assets[i]));
+        }
+      }
+    }
+  }
+
+  function setPath(path) {
+    this.path = path || '';
+  }
+
+  function setAssetsPath(path) {
+    this.assetsPath = path || '';
+  }
+
+  function getAsset(assetData) {
+    var i = 0;
+    var len = this.images.length;
+    while (i < len) {
+      if (this.images[i].assetData === assetData) {
+        return this.images[i].img;
+      }
+      i += 1;
+    }
+    return null;
+  }
+
+  function destroy() {
+    this.imagesLoadedCb = null;
+    this.images.length = 0;
+  }
+
+  function loadedImages() {
+    return this.totalImages === this.loadedAssets;
+  }
+
+  function loadedFootages() {
+    return this.totalFootages === this.loadedFootagesCount;
+  }
+
+  function setCacheType(type, elementHelper) {
+    if (type === 'svg') {
+      this._elementHelper = elementHelper;
+      this._createImageData = this.createImageData.bind(this);
+    } else {
+      this._createImageData = this.createImgData.bind(this);
+    }
+  }
+
+  function ImagePreloaderFactory() {
+    this._imageLoaded = imageLoaded.bind(this);
+    this._footageLoaded = footageLoaded.bind(this);
+    this.testImageLoaded = testImageLoaded.bind(this);
+    this.createFootageData = createFootageData.bind(this);
+    this.assetsPath = '';
+    this.path = '';
+    this.totalImages = 0;
+    this.totalFootages = 0;
+    this.loadedAssets = 0;
+    this.loadedFootagesCount = 0;
+    this.imagesLoadedCb = null;
+    this.images = [];
+  }
+
+  ImagePreloaderFactory.prototype = {
+    loadAssets: loadAssets,
+    setAssetsPath: setAssetsPath,
+    setPath: setPath,
+    loadedImages: loadedImages,
+    loadedFootages: loadedFootages,
+    destroy: destroy,
+    getAsset: getAsset,
+    createImgData: createImgData,
+    createImageData: createImageData,
+    imageLoaded: imageLoaded,
+    footageLoaded: footageLoaded,
+    setCacheType: setCacheType,
+  };
+
+  return ImagePreloaderFactory;
+}());
+
+function BaseEvent() {}
+BaseEvent.prototype = {
+  triggerEvent: function (eventName, args) {
+    if (this._cbs[eventName]) {
+      var callbacks = this._cbs[eventName];
+      for (var i = 0; i < callbacks.length; i += 1) {
+        callbacks[i](args);
+      }
+    }
+  },
+  addEventListener: function (eventName, callback) {
+    if (!this._cbs[eventName]) {
+      this._cbs[eventName] = [];
+    }
+    this._cbs[eventName].push(callback);
+
+    return function () {
+      this.removeEventListener(eventName, callback);
+    }.bind(this);
+  },
+  removeEventListener: function (eventName, callback) {
+    if (!callback) {
+      this._cbs[eventName] = null;
+    } else if (this._cbs[eventName]) {
+      var i = 0;
+      var len = this._cbs[eventName].length;
+      while (i < len) {
+        if (this._cbs[eventName][i] === callback) {
+          this._cbs[eventName].splice(i, 1);
+          i -= 1;
+          len -= 1;
+        }
+        i += 1;
+      }
+      if (!this._cbs[eventName].length) {
+        this._cbs[eventName] = null;
+      }
+    }
+  },
+};
+
+const markerParser = (
+
+  function () {
+    function parsePayloadLines(payload) {
+      var lines = payload.split('\r\n');
+      var keys = {};
+      var line;
+      var keysCount = 0;
+      for (var i = 0; i < lines.length; i += 1) {
+        line = lines[i].split(':');
+        if (line.length === 2) {
+          keys[line[0]] = line[1].trim();
+          keysCount += 1;
+        }
+      }
+      if (keysCount === 0) {
+        throw new Error();
+      }
+      return keys;
+    }
+
+    return function (_markers) {
+      var markers = [];
+      for (var i = 0; i < _markers.length; i += 1) {
+        var _marker = _markers[i];
+        var markerData = {
+          time: _marker.tm,
+          duration: _marker.dr,
+        };
+        try {
+          markerData.payload = JSON.parse(_markers[i].cm);
+        } catch (_) {
+          try {
+            markerData.payload = parsePayloadLines(_markers[i].cm);
+          } catch (__) {
+            markerData.payload = {
+              name: _markers[i].cm,
+            };
+          }
+        }
+        markers.push(markerData);
+      }
+      return markers;
+    };
+  }());
+
+const ProjectInterface = (function () {
+  function registerComposition(comp) {
+    this.compositions.push(comp);
+  }
+
+  return function () {
+    function _thisProjectFunction(name) {
+      var i = 0;
+      var len = this.compositions.length;
+      while (i < len) {
+        if (this.compositions[i].data && this.compositions[i].data.nm === name) {
+          if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
+            this.compositions[i].prepareFrame(this.currentFrame);
+          }
+          return this.compositions[i].compInterface;
+        }
+        i += 1;
+      }
+      return null;
+    }
+
+    _thisProjectFunction.compositions = [];
+    _thisProjectFunction.currentFrame = 0;
+
+    _thisProjectFunction.registerComposition = registerComposition;
+
+    return _thisProjectFunction;
+  };
+}());
+
+const renderers = {};
+
+const registerRenderer = (key, value) => {
+  renderers[key] = value;
+};
+
+function getRenderer(key) {
+  return renderers[key];
+}
+
+function getRegisteredRenderer() {
+  // Returns canvas by default for compatibility
+  if (renderers.canvas) {
+    return 'canvas';
+  }
+  // Returns any renderer that is registered
+  for (const key in renderers) {
+    if (renderers[key]) {
+      return key;
+    }
+  }
+  return '';
+}
+
+const AnimationItem = function () {
+  this._cbs = [];
+  this.name = '';
+  this.path = '';
+  this.isLoaded = false;
+  this.currentFrame = 0;
+  this.currentRawFrame = 0;
+  this.firstFrame = 0;
+  this.totalFrames = 0;
+  this.frameRate = 0;
+  this.frameMult = 0;
+  this.playSpeed = 1;
+  this.playDirection = 1;
+  this.playCount = 0;
+  this.animationData = {};
+  this.assets = [];
+  this.isPaused = true;
+  this.autoplay = false;
+  this.loop = true;
+  this.renderer = null;
+  this.animationID = createElementID();
+  this.assetsPath = '';
+  this.timeCompleted = 0;
+  this.segmentPos = 0;
+  this.isSubframeEnabled = getSubframeEnabled();
+  this.segments = [];
+  this._idle = true;
+  this._completedLoop = false;
+  this.projectInterface = ProjectInterface();
+  this.imagePreloader = new ImagePreloader();
+  this.audioController = audioControllerFactory();
+  this.markers = [];
+  this.configAnimation = this.configAnimation.bind(this);
+  this.onSetupError = this.onSetupError.bind(this);
+  this.onSegmentComplete = this.onSegmentComplete.bind(this);
+  this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
+  this.expressionsPlugin = getExpressionsPlugin();
+};
+
+extendPrototype([BaseEvent], AnimationItem);
+
+AnimationItem.prototype.setParams = function (params) {
+  if (params.wrapper || params.container) {
+    this.wrapper = params.wrapper || params.container;
+  }
+  var animType = 'svg';
+  if (params.animType) {
+    animType = params.animType;
+  } else if (params.renderer) {
+    animType = params.renderer;
+  }
+  const RendererClass = getRenderer(animType);
+  this.renderer = new RendererClass(this, params.rendererSettings);
+  this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
+  this.renderer.setProjectInterface(this.projectInterface);
+  this.animType = animType;
+  if (params.loop === ''
+        || params.loop === null
+        || params.loop === undefined
+        || params.loop === true) {
+    this.loop = true;
+  } else if (params.loop === false) {
+    this.loop = false;
+  } else {
+    this.loop = parseInt(params.loop, 10);
+  }
+  this.autoplay = 'autoplay' in params ? params.autoplay : true;
+  this.name = params.name ? params.name : '';
+  this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
+  this.assetsPath = params.assetsPath;
+  this.initialSegment = params.initialSegment;
+  if (params.audioFactory) {
+    this.audioController.setAudioFactory(params.audioFactory);
+  }
+  if (params.animationData) {
+    this.setupAnimation(params.animationData);
+  } else if (params.path) {
+    if (params.path.lastIndexOf('\\') !== -1) {
+      this.path = params.path.substr(0, params.path.lastIndexOf('\\') + 1);
+    } else {
+      this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
+    }
+    this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
+    this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
+    dataManager.loadAnimation(
+      params.path,
+      this.configAnimation,
+      this.onSetupError
+    );
+  }
+};
+
+AnimationItem.prototype.onSetupError = function () {
+  this.trigger('data_failed');
+};
+
+AnimationItem.prototype.setupAnimation = function (data) {
+  dataManager.completeAnimation(
+    data,
+    this.configAnimation
+  );
+};
+
+AnimationItem.prototype.setData = function (wrapper, animationData) {
+  if (animationData) {
+    if (typeof animationData !== 'object') {
+      animationData = JSON.parse(animationData);
+    }
+  }
+  var params = {
+    wrapper: wrapper,
+    animationData: animationData,
+  };
+  var wrapperAttributes = wrapper.attributes;
+
+  params.path = wrapperAttributes.getNamedItem('data-animation-path') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-animation-path').value
+    : wrapperAttributes.getNamedItem('data-bm-path') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-path').value
+      : wrapperAttributes.getNamedItem('bm-path')
+        ? wrapperAttributes.getNamedItem('bm-path').value
+        : '';
+  params.animType = wrapperAttributes.getNamedItem('data-anim-type') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-type').value
+    : wrapperAttributes.getNamedItem('data-bm-type') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-type').value
+      : wrapperAttributes.getNamedItem('bm-type') // eslint-disable-line no-nested-ternary
+        ? wrapperAttributes.getNamedItem('bm-type').value
+        : wrapperAttributes.getNamedItem('data-bm-renderer') // eslint-disable-line no-nested-ternary
+          ? wrapperAttributes.getNamedItem('data-bm-renderer').value
+          : wrapperAttributes.getNamedItem('bm-renderer')
+            ? wrapperAttributes.getNamedItem('bm-renderer').value
+            : getRegisteredRenderer() || 'canvas';
+
+  var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-loop').value
+    : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-loop').value
+      : wrapperAttributes.getNamedItem('bm-loop')
+        ? wrapperAttributes.getNamedItem('bm-loop').value
+        : '';
+  if (loop === 'false') {
+    params.loop = false;
+  } else if (loop === 'true') {
+    params.loop = true;
+  } else if (loop !== '') {
+    params.loop = parseInt(loop, 10);
+  }
+  var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-autoplay').value
+    : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-autoplay').value
+      : wrapperAttributes.getNamedItem('bm-autoplay')
+        ? wrapperAttributes.getNamedItem('bm-autoplay').value
+        : true;
+  params.autoplay = autoplay !== 'false';
+
+  params.name = wrapperAttributes.getNamedItem('data-name') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-name').value
+    : wrapperAttributes.getNamedItem('data-bm-name') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-name').value
+      : wrapperAttributes.getNamedItem('bm-name')
+        ? wrapperAttributes.getNamedItem('bm-name').value
+        : '';
+  var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-prerender').value
+    : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-prerender').value
+      : wrapperAttributes.getNamedItem('bm-prerender')
+        ? wrapperAttributes.getNamedItem('bm-prerender').value
+        : '';
+
+  if (prerender === 'false') {
+    params.prerender = false;
+  }
+  if (!params.path) {
+    this.trigger('destroy');
+  } else {
+    this.setParams(params);
+  }
+};
+
+AnimationItem.prototype.includeLayers = function (data) {
+  if (data.op > this.animationData.op) {
+    this.animationData.op = data.op;
+    this.totalFrames = Math.floor(data.op - this.animationData.ip);
+  }
+  var layers = this.animationData.layers;
+  var i;
+  var len = layers.length;
+  var newLayers = data.layers;
+  var j;
+  var jLen = newLayers.length;
+  for (j = 0; j < jLen; j += 1) {
+    i = 0;
+    while (i < len) {
+      if (layers[i].id === newLayers[j].id) {
+        layers[i] = newLayers[j];
+        break;
+      }
+      i += 1;
+    }
+  }
+  if (data.chars || data.fonts) {
+    this.renderer.globalData.fontManager.addChars(data.chars);
+    this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
+  }
+  if (data.assets) {
+    len = data.assets.length;
+    for (i = 0; i < len; i += 1) {
+      this.animationData.assets.push(data.assets[i]);
+    }
+  }
+  this.animationData.__complete = false;
+  dataManager.completeAnimation(
+    this.animationData,
+    this.onSegmentComplete
+  );
+};
+
+AnimationItem.prototype.onSegmentComplete = function (data) {
+  this.animationData = data;
+  var expressionsPlugin = getExpressionsPlugin();
+  if (expressionsPlugin) {
+    expressionsPlugin.initExpressions(this);
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.loadNextSegment = function () {
+  var segments = this.animationData.segments;
+  if (!segments || segments.length === 0 || !this.autoloadSegments) {
+    this.trigger('data_ready');
+    this.timeCompleted = this.totalFrames;
+    return;
+  }
+  var segment = segments.shift();
+  this.timeCompleted = segment.time * this.frameRate;
+  var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
+  this.segmentPos += 1;
+  dataManager.loadData(segmentPath, this.includeLayers.bind(this), function () {
+    this.trigger('data_failed');
+  }.bind(this));
+};
+
+AnimationItem.prototype.loadSegments = function () {
+  var segments = this.animationData.segments;
+  if (!segments) {
+    this.timeCompleted = this.totalFrames;
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.imagesLoaded = function () {
+  this.trigger('loaded_images');
+  this.checkLoaded();
+};
+
+AnimationItem.prototype.preloadImages = function () {
+  this.imagePreloader.setAssetsPath(this.assetsPath);
+  this.imagePreloader.setPath(this.path);
+  this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
+};
+
+AnimationItem.prototype.configAnimation = function (animData) {
+  if (!this.renderer) {
+    return;
+  }
+  try {
+    this.animationData = animData;
+    if (this.initialSegment) {
+      this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
+      this.firstFrame = Math.round(this.initialSegment[0]);
+    } else {
+      this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
+      this.firstFrame = Math.round(this.animationData.ip);
+    }
+    this.renderer.configAnimation(animData);
+    if (!animData.assets) {
+      animData.assets = [];
+    }
+
+    this.assets = this.animationData.assets;
+    this.frameRate = this.animationData.fr;
+    this.frameMult = this.animationData.fr / 1000;
+    this.renderer.searchExtraCompositions(animData.assets);
+    this.markers = markerParser(animData.markers || []);
+    this.trigger('config_ready');
+    this.preloadImages();
+    this.loadSegments();
+    this.updaFrameModifier();
+    this.waitForFontsLoaded();
+    if (this.isPaused) {
+      this.audioController.pause();
+    }
+  } catch (error) {
+    this.triggerConfigError(error);
+  }
+};
+
+AnimationItem.prototype.waitForFontsLoaded = function () {
+  if (!this.renderer) {
+    return;
+  }
+  if (this.renderer.globalData.fontManager.isLoaded) {
+    this.checkLoaded();
+  } else {
+    setTimeout(this.waitForFontsLoaded.bind(this), 20);
+  }
+};
+
+AnimationItem.prototype.checkLoaded = function () {
+  if (!this.isLoaded
+        && this.renderer.globalData.fontManager.isLoaded
+        && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas')
+        && (this.imagePreloader.loadedFootages())
+  ) {
+    this.isLoaded = true;
+    var expressionsPlugin = getExpressionsPlugin();
+    if (expressionsPlugin) {
+      expressionsPlugin.initExpressions(this);
+    }
+    this.renderer.initItems();
+    setTimeout(function () {
+      this.trigger('DOMLoaded');
+    }.bind(this), 0);
+    this.gotoFrame();
+    if (this.autoplay) {
+      this.play();
+    }
+  }
+};
+
+AnimationItem.prototype.resize = function (width, height) {
+  // Adding this validation for backwards compatibility in case an event object was being passed down
+  var _width = typeof width === 'number' ? width : undefined;
+  var _height = typeof height === 'number' ? height : undefined;
+  this.renderer.updateContainerSize(_width, _height);
+};
+
+AnimationItem.prototype.setSubframe = function (flag) {
+  this.isSubframeEnabled = !!flag;
+};
+
+AnimationItem.prototype.gotoFrame = function () {
+  this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
+
+  if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
+    this.currentFrame = this.timeCompleted;
+  }
+  this.trigger('enterFrame');
+  this.renderFrame();
+  this.trigger('drawnFrame');
+};
+
+AnimationItem.prototype.renderFrame = function () {
+  if (this.isLoaded === false || !this.renderer) {
+    return;
+  }
+  try {
+    if (this.expressionsPlugin) {
+      this.expressionsPlugin.resetFrame();
+    }
+    this.renderer.renderFrame(this.currentFrame + this.firstFrame);
+  } catch (error) {
+    this.triggerRenderFrameError(error);
+  }
+};
+
+AnimationItem.prototype.play = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.isPaused = false;
+    this.trigger('_play');
+    this.audioController.resume();
+    if (this._idle) {
+      this._idle = false;
+      this.trigger('_active');
+    }
+  }
+};
+
+AnimationItem.prototype.pause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === false) {
+    this.isPaused = true;
+    this.trigger('_pause');
+    this._idle = true;
+    this.trigger('_idle');
+    this.audioController.pause();
+  }
+};
+
+AnimationItem.prototype.togglePause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.play();
+  } else {
+    this.pause();
+  }
+};
+
+AnimationItem.prototype.stop = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.pause();
+  this.playCount = 0;
+  this._completedLoop = false;
+  this.setCurrentRawFrameValue(0);
+};
+
+AnimationItem.prototype.getMarkerData = function (markerName) {
+  var marker;
+  for (var i = 0; i < this.markers.length; i += 1) {
+    marker = this.markers[i];
+    if (marker.payload && marker.payload.name === markerName) {
+      return marker;
+    }
+  }
+  return null;
+};
+
+AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      this.goToAndStop(marker.time, true);
+    }
+  } else if (isFrame) {
+    this.setCurrentRawFrameValue(value);
+  } else {
+    this.setCurrentRawFrameValue(value * this.frameModifier);
+  }
+  this.pause();
+};
+
+AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      if (!marker.duration) {
+        this.goToAndStop(marker.time, true);
+      } else {
+        this.playSegments([marker.time, marker.time + marker.duration], true);
+      }
+    }
+  } else {
+    this.goToAndStop(numValue, isFrame, name);
+  }
+  this.play();
+};
+
+AnimationItem.prototype.advanceTime = function (value) {
+  if (this.isPaused === true || this.isLoaded === false) {
+    return;
+  }
+  var nextValue = this.currentRawFrame + value * this.frameModifier;
+  var _isComplete = false;
+  // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+  // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
+  if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
+    if (!this.loop || this.playCount === this.loop) {
+      if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
+        _isComplete = true;
+        nextValue = this.totalFrames - 1;
+      }
+    } else if (nextValue >= this.totalFrames) {
+      this.playCount += 1;
+      if (!this.checkSegments(nextValue % this.totalFrames)) {
+        this.setCurrentRawFrameValue(nextValue % this.totalFrames);
+        this._completedLoop = true;
+        this.trigger('loopComplete');
+      }
+    } else {
+      this.setCurrentRawFrameValue(nextValue);
+    }
+  } else if (nextValue < 0) {
+    if (!this.checkSegments(nextValue % this.totalFrames)) {
+      if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) { // eslint-disable-line no-plusplus
+        this.setCurrentRawFrameValue(this.totalFrames + (nextValue % this.totalFrames));
+        if (!this._completedLoop) {
+          this._completedLoop = true;
+        } else {
+          this.trigger('loopComplete');
+        }
+      } else {
+        _isComplete = true;
+        nextValue = 0;
+      }
+    }
+  } else {
+    this.setCurrentRawFrameValue(nextValue);
+  }
+  if (_isComplete) {
+    this.setCurrentRawFrameValue(nextValue);
+    this.pause();
+    this.trigger('complete');
+  }
+};
+
+AnimationItem.prototype.adjustSegment = function (arr, offset) {
+  this.playCount = 0;
+  if (arr[1] < arr[0]) {
+    if (this.frameModifier > 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(-1);
+      }
+    }
+    this.totalFrames = arr[0] - arr[1];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[1];
+    this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset);
+  } else if (arr[1] > arr[0]) {
+    if (this.frameModifier < 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(1);
+      }
+    }
+    this.totalFrames = arr[1] - arr[0];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[0];
+    this.setCurrentRawFrameValue(0.001 + offset);
+  }
+  this.trigger('segmentStart');
+};
+AnimationItem.prototype.setSegment = function (init, end) {
+  var pendingFrame = -1;
+  if (this.isPaused) {
+    if (this.currentRawFrame + this.firstFrame < init) {
+      pendingFrame = init;
+    } else if (this.currentRawFrame + this.firstFrame > end) {
+      pendingFrame = end - init;
+    }
+  }
+
+  this.firstFrame = init;
+  this.totalFrames = end - init;
+  this.timeCompleted = this.totalFrames;
+  if (pendingFrame !== -1) {
+    this.goToAndStop(pendingFrame, true);
+  }
+};
+
+AnimationItem.prototype.playSegments = function (arr, forceFlag) {
+  if (forceFlag) {
+    this.segments.length = 0;
+  }
+  if (typeof arr[0] === 'object') {
+    var i;
+    var len = arr.length;
+    for (i = 0; i < len; i += 1) {
+      this.segments.push(arr[i]);
+    }
+  } else {
+    this.segments.push(arr);
+  }
+  if (this.segments.length && forceFlag) {
+    this.adjustSegment(this.segments.shift(), 0);
+  }
+  if (this.isPaused) {
+    this.play();
+  }
+};
+
+AnimationItem.prototype.resetSegments = function (forceFlag) {
+  this.segments.length = 0;
+  this.segments.push([this.animationData.ip, this.animationData.op]);
+  if (forceFlag) {
+    this.checkSegments(0);
+  }
+};
+AnimationItem.prototype.checkSegments = function (offset) {
+  if (this.segments.length) {
+    this.adjustSegment(this.segments.shift(), offset);
+    return true;
+  }
+  return false;
+};
+
+AnimationItem.prototype.destroy = function (name) {
+  if ((name && this.name !== name) || !this.renderer) {
+    return;
+  }
+  this.renderer.destroy();
+  this.imagePreloader.destroy();
+  this.trigger('destroy');
+  this._cbs = null;
+  this.onEnterFrame = null;
+  this.onLoopComplete = null;
+  this.onComplete = null;
+  this.onSegmentStart = null;
+  this.onDestroy = null;
+  this.renderer = null;
+  this.expressionsPlugin = null;
+  this.imagePreloader = null;
+  this.projectInterface = null;
+};
+
+AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
+  this.currentRawFrame = value;
+  this.gotoFrame();
+};
+
+AnimationItem.prototype.setSpeed = function (val) {
+  this.playSpeed = val;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setDirection = function (val) {
+  this.playDirection = val < 0 ? -1 : 1;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setLoop = function (isLooping) {
+  this.loop = isLooping;
+};
+
+AnimationItem.prototype.setVolume = function (val, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.setVolume(val);
+};
+
+AnimationItem.prototype.getVolume = function () {
+  return this.audioController.getVolume();
+};
+
+AnimationItem.prototype.mute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.mute();
+};
+
+AnimationItem.prototype.unmute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.unmute();
+};
+
+AnimationItem.prototype.updaFrameModifier = function () {
+  this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
+  this.audioController.setRate(this.playSpeed * this.playDirection);
+};
+
+AnimationItem.prototype.getPath = function () {
+  return this.path;
+};
+
+AnimationItem.prototype.getAssetsPath = function (assetData) {
+  var path = '';
+  if (assetData.e) {
+    path = assetData.p;
+  } else if (this.assetsPath) {
+    var imagePath = assetData.p;
+    if (imagePath.indexOf('images/') !== -1) {
+      imagePath = imagePath.split('/')[1];
+    }
+    path = this.assetsPath + imagePath;
+  } else {
+    path = this.path;
+    path += assetData.u ? assetData.u : '';
+    path += assetData.p;
+  }
+  return path;
+};
+
+AnimationItem.prototype.getAssetData = function (id) {
+  var i = 0;
+  var len = this.assets.length;
+  while (i < len) {
+    if (id === this.assets[i].id) {
+      return this.assets[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+AnimationItem.prototype.hide = function () {
+  this.renderer.hide();
+};
+
+AnimationItem.prototype.show = function () {
+  this.renderer.show();
+};
+
+AnimationItem.prototype.getDuration = function (isFrame) {
+  return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
+};
+
+AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
+  try {
+    var element = this.renderer.getElementByPath(path);
+    element.updateDocumentData(documentData, index);
+  } catch (error) {
+    // TODO: decide how to handle catch case
+  }
+};
+
+AnimationItem.prototype.trigger = function (name) {
+  if (this._cbs && this._cbs[name]) {
+    switch (name) {
+      case 'enterFrame':
+        this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
+        break;
+      case 'drawnFrame':
+        this.drawnFrameEvent.currentTime = this.currentFrame;
+        this.drawnFrameEvent.totalTime = this.totalFrames;
+        this.drawnFrameEvent.direction = this.frameModifier;
+        this.triggerEvent(name, this.drawnFrameEvent);
+        break;
+      case 'loopComplete':
+        this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+        break;
+      case 'complete':
+        this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
+        break;
+      case 'segmentStart':
+        this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+        break;
+      case 'destroy':
+        this.triggerEvent(name, new BMDestroyEvent(name, this));
+        break;
+      default:
+        this.triggerEvent(name);
+    }
+  }
+  if (name === 'enterFrame' && this.onEnterFrame) {
+    this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
+  }
+  if (name === 'loopComplete' && this.onLoopComplete) {
+    this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+  }
+  if (name === 'complete' && this.onComplete) {
+    this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
+  }
+  if (name === 'segmentStart' && this.onSegmentStart) {
+    this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+  }
+  if (name === 'destroy' && this.onDestroy) {
+    this.onDestroy.call(this, new BMDestroyEvent(name, this));
+  }
+};
+
+AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
+  var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+AnimationItem.prototype.triggerConfigError = function (nativeError) {
+  var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+const animationManager = (function () {
+  var moduleOb = {};
+  var registeredAnimations = [];
+  var initTime = 0;
+  var len = 0;
+  var playingAnimationsNum = 0;
+  var _stopped = true;
+  var _isFrozen = false;
+
+  function removeElement(ev) {
+    var i = 0;
+    var animItem = ev.target;
+    while (i < len) {
+      if (registeredAnimations[i].animation === animItem) {
+        registeredAnimations.splice(i, 1);
+        i -= 1;
+        len -= 1;
+        if (!animItem.isPaused) {
+          subtractPlayingCount();
+        }
+      }
+      i += 1;
+    }
+  }
+
+  function registerAnimation(element, animationData) {
+    if (!element) {
+      return null;
+    }
+    var i = 0;
+    while (i < len) {
+      if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
+        return registeredAnimations[i].animation;
+      }
+      i += 1;
+    }
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, element);
+    animItem.setData(element, animationData);
+    return animItem;
+  }
+
+  function getRegisteredAnimations() {
+    var i;
+    var lenAnims = registeredAnimations.length;
+    var animations = [];
+    for (i = 0; i < lenAnims; i += 1) {
+      animations.push(registeredAnimations[i].animation);
+    }
+    return animations;
+  }
+
+  function addPlayingCount() {
+    playingAnimationsNum += 1;
+    activate();
+  }
+
+  function subtractPlayingCount() {
+    playingAnimationsNum -= 1;
+  }
+
+  function setupAnimation(animItem, element) {
+    animItem.addEventListener('destroy', removeElement);
+    animItem.addEventListener('_active', addPlayingCount);
+    animItem.addEventListener('_idle', subtractPlayingCount);
+    registeredAnimations.push({ elem: element, animation: animItem });
+    len += 1;
+  }
+
+  function loadAnimation(params) {
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, null);
+    animItem.setParams(params);
+    return animItem;
+  }
+
+  function setSpeed(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setSpeed(val, animation);
+    }
+  }
+
+  function setDirection(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setDirection(val, animation);
+    }
+  }
+
+  function play(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.play(animation);
+    }
+  }
+  function resume(nowTime) {
+    var elapsedTime = nowTime - initTime;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.advanceTime(elapsedTime);
+    }
+    initTime = nowTime;
+    if (playingAnimationsNum && !_isFrozen) {
+      window.requestAnimationFrame(resume);
+    } else {
+      _stopped = true;
+    }
+  }
+
+  function first(nowTime) {
+    initTime = nowTime;
+    window.requestAnimationFrame(resume);
+  }
+
+  function pause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.pause(animation);
+    }
+  }
+
+  function goToAndStop(value, isFrame, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
+    }
+  }
+
+  function stop(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.stop(animation);
+    }
+  }
+
+  function togglePause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.togglePause(animation);
+    }
+  }
+
+  function destroy(animation) {
+    var i;
+    for (i = (len - 1); i >= 0; i -= 1) {
+      registeredAnimations[i].animation.destroy(animation);
+    }
+  }
+
+  function searchAnimations(animationData, standalone, renderer) {
+    var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')),
+      [].slice.call(document.getElementsByClassName('bodymovin')));
+    var i;
+    var lenAnims = animElements.length;
+    for (i = 0; i < lenAnims; i += 1) {
+      if (renderer) {
+        animElements[i].setAttribute('data-bm-type', renderer);
+      }
+      registerAnimation(animElements[i], animationData);
+    }
+    if (standalone && lenAnims === 0) {
+      if (!renderer) {
+        renderer = 'svg';
+      }
+      var body = document.getElementsByTagName('body')[0];
+      body.innerText = '';
+      var div = createTag('div');
+      div.style.width = '100%';
+      div.style.height = '100%';
+      div.setAttribute('data-bm-type', renderer);
+      body.appendChild(div);
+      registerAnimation(div, animationData);
+    }
+  }
+
+  function resize() {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.resize();
+    }
+  }
+
+  function activate() {
+    if (!_isFrozen && playingAnimationsNum) {
+      if (_stopped) {
+        window.requestAnimationFrame(first);
+        _stopped = false;
+      }
+    }
+  }
+
+  function freeze() {
+    _isFrozen = true;
+  }
+
+  function unfreeze() {
+    _isFrozen = false;
+    activate();
+  }
+
+  function setVolume(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setVolume(val, animation);
+    }
+  }
+
+  function mute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.mute(animation);
+    }
+  }
+
+  function unmute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.unmute(animation);
+    }
+  }
+
+  moduleOb.registerAnimation = registerAnimation;
+  moduleOb.loadAnimation = loadAnimation;
+  moduleOb.setSpeed = setSpeed;
+  moduleOb.setDirection = setDirection;
+  moduleOb.play = play;
+  moduleOb.pause = pause;
+  moduleOb.stop = stop;
+  moduleOb.togglePause = togglePause;
+  moduleOb.searchAnimations = searchAnimations;
+  moduleOb.resize = resize;
+  // moduleOb.start = start;
+  moduleOb.goToAndStop = goToAndStop;
+  moduleOb.destroy = destroy;
+  moduleOb.freeze = freeze;
+  moduleOb.unfreeze = unfreeze;
+  moduleOb.setVolume = setVolume;
+  moduleOb.mute = mute;
+  moduleOb.unmute = unmute;
+  moduleOb.getRegisteredAnimations = getRegisteredAnimations;
+  return moduleOb;
+}());
+
+/* eslint-disable */
+const BezierFactory = (function () {
+  /**
+     * BezierEasing - use bezier curve for transition easing function
+     * by Gaëtan Renaudeau 2014 - 2015 – MIT License
+     *
+     * Credits: is based on Firefox's nsSMILKeySpline.cpp
+     * Usage:
+     * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
+     * spline.get(x) => returns the easing value | x must be in [0, 1] range
+     *
+     */
+
+  var ob = {};
+  ob.getBezierEasing = getBezierEasing;
+  var beziers = {};
+
+  function getBezierEasing(a, b, c, d, nm) {
+    var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
+    if (beziers[str]) {
+      return beziers[str];
+    }
+    var bezEasing = new BezierEasing([a, b, c, d]);
+    beziers[str] = bezEasing;
+    return bezEasing;
+  }
+
+  // These values are established by empiricism with tests (tradeoff: performance VS precision)
+  var NEWTON_ITERATIONS = 4;
+  var NEWTON_MIN_SLOPE = 0.001;
+  var SUBDIVISION_PRECISION = 0.0000001;
+  var SUBDIVISION_MAX_ITERATIONS = 10;
+
+  var kSplineTableSize = 11;
+  var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
+
+  var float32ArraySupported = typeof Float32Array === 'function';
+
+  function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
+  function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
+  function C(aA1) { return 3.0 * aA1; }
+
+  // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+  function calcBezier(aT, aA1, aA2) {
+    return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
+  }
+
+  // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+  function getSlope(aT, aA1, aA2) {
+    return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
+  }
+
+  function binarySubdivide(aX, aA, aB, mX1, mX2) {
+    var currentX,
+      currentT,
+      i = 0;
+    do {
+      currentT = aA + (aB - aA) / 2.0;
+      currentX = calcBezier(currentT, mX1, mX2) - aX;
+      if (currentX > 0.0) {
+        aB = currentT;
+      } else {
+        aA = currentT;
+      }
+    } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
+    return currentT;
+  }
+
+  function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
+    for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
+      var currentSlope = getSlope(aGuessT, mX1, mX2);
+      if (currentSlope === 0.0) return aGuessT;
+      var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
+      aGuessT -= currentX / currentSlope;
+    }
+    return aGuessT;
+  }
+
+  /**
+     * points is an array of [ mX1, mY1, mX2, mY2 ]
+     */
+  function BezierEasing(points) {
+    this._p = points;
+    this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
+    this._precomputed = false;
+
+    this.get = this.get.bind(this);
+  }
+
+  BezierEasing.prototype = {
+
+    get: function (x) {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      if (!this._precomputed) this._precompute();
+      if (mX1 === mY1 && mX2 === mY2) return x; // linear
+      // Because JavaScript number are imprecise, we should guarantee the extremes are right.
+      if (x === 0) return 0;
+      if (x === 1) return 1;
+      return calcBezier(this._getTForX(x), mY1, mY2);
+    },
+
+    // Private part
+
+    _precompute: function () {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      this._precomputed = true;
+      if (mX1 !== mY1 || mX2 !== mY2) { this._calcSampleValues(); }
+    },
+
+    _calcSampleValues: function () {
+      var mX1 = this._p[0],
+        mX2 = this._p[2];
+      for (var i = 0; i < kSplineTableSize; ++i) {
+        this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
+      }
+    },
+
+    /**
+         * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
+         */
+    _getTForX: function (aX) {
+      var mX1 = this._p[0],
+        mX2 = this._p[2],
+        mSampleValues = this._mSampleValues;
+
+      var intervalStart = 0.0;
+      var currentSample = 1;
+      var lastSample = kSplineTableSize - 1;
+
+      for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
+        intervalStart += kSampleStepSize;
+      }
+      --currentSample;
+
+      // Interpolate to provide an initial guess for t
+      var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
+      var guessForT = intervalStart + dist * kSampleStepSize;
+
+      var initialSlope = getSlope(guessForT, mX1, mX2);
+      if (initialSlope >= NEWTON_MIN_SLOPE) {
+        return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
+      } if (initialSlope === 0.0) {
+        return guessForT;
+      }
+      return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
+    },
+  };
+
+  return ob;
+}());
+
+const pooling = (function () {
+  function double(arr) {
+    return arr.concat(createSizedArray(arr.length));
+  }
+
+  return {
+    double: double,
+  };
+}());
+
+const poolFactory = (function () {
+  return function (initialLength, _create, _release) {
+    var _length = 0;
+    var _maxLength = initialLength;
+    var pool = createSizedArray(_maxLength);
+
+    var ob = {
+      newElement: newElement,
+      release: release,
+    };
+
+    function newElement() {
+      var element;
+      if (_length) {
+        _length -= 1;
+        element = pool[_length];
+      } else {
+        element = _create();
+      }
+      return element;
+    }
+
+    function release(element) {
+      if (_length === _maxLength) {
+        pool = pooling.double(pool);
+        _maxLength *= 2;
+      }
+      if (_release) {
+        _release(element);
+      }
+      pool[_length] = element;
+      _length += 1;
+    }
+
+    return ob;
+  };
+}());
+
+const bezierLengthPool = (function () {
+  function create() {
+    return {
+      addedLength: 0,
+      percents: createTypedArray('float32', getDefaultCurveSegments()),
+      lengths: createTypedArray('float32', getDefaultCurveSegments()),
+    };
+  }
+  return poolFactory(8, create);
+}());
+
+const segmentsLengthPool = (function () {
+  function create() {
+    return {
+      lengths: [],
+      totalLength: 0,
+    };
+  }
+
+  function release(element) {
+    var i;
+    var len = element.lengths.length;
+    for (i = 0; i < len; i += 1) {
+      bezierLengthPool.release(element.lengths[i]);
+    }
+    element.lengths.length = 0;
+  }
+
+  return poolFactory(8, create, release);
+}());
+
+function bezFunction() {
+  var math = Math;
+
+  function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
+    var det1 = (x1 * y2) + (y1 * x3) + (x2 * y3) - (x3 * y2) - (y3 * x1) - (x2 * y1);
+    return det1 > -0.001 && det1 < 0.001;
+  }
+
+  function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
+    if (z1 === 0 && z2 === 0 && z3 === 0) {
+      return pointOnLine2D(x1, y1, x2, y2, x3, y3);
+    }
+    var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
+    var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
+    var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
+    var diffDist;
+    if (dist1 > dist2) {
+      if (dist1 > dist3) {
+        diffDist = dist1 - dist2 - dist3;
+      } else {
+        diffDist = dist3 - dist2 - dist1;
+      }
+    } else if (dist3 > dist2) {
+      diffDist = dist3 - dist2 - dist1;
+    } else {
+      diffDist = dist2 - dist1 - dist3;
+    }
+    return diffDist > -0.0001 && diffDist < 0.0001;
+  }
+
+  var getBezierLength = (function () {
+    return function (pt1, pt2, pt3, pt4) {
+      var curveSegments = getDefaultCurveSegments();
+      var k;
+      var i;
+      var len;
+      var ptCoord;
+      var perc;
+      var addedLength = 0;
+      var ptDistance;
+      var point = [];
+      var lastPoint = [];
+      var lengthData = bezierLengthPool.newElement();
+      len = pt3.length;
+      for (k = 0; k < curveSegments; k += 1) {
+        perc = k / (curveSegments - 1);
+        ptDistance = 0;
+        for (i = 0; i < len; i += 1) {
+          ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
+          point[i] = ptCoord;
+          if (lastPoint[i] !== null) {
+            ptDistance += bmPow(point[i] - lastPoint[i], 2);
+          }
+          lastPoint[i] = point[i];
+        }
+        if (ptDistance) {
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+        }
+        lengthData.percents[k] = perc;
+        lengthData.lengths[k] = addedLength;
+      }
+      lengthData.addedLength = addedLength;
+      return lengthData;
+    };
+  }());
+
+  function getSegmentsLength(shapeData) {
+    var segmentsLength = segmentsLengthPool.newElement();
+    var closed = shapeData.c;
+    var pathV = shapeData.v;
+    var pathO = shapeData.o;
+    var pathI = shapeData.i;
+    var i;
+    var len = shapeData._length;
+    var lengths = segmentsLength.lengths;
+    var totalLength = 0;
+    for (i = 0; i < len - 1; i += 1) {
+      lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
+      totalLength += lengths[i].addedLength;
+    }
+    if (closed && len) {
+      lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
+      totalLength += lengths[i].addedLength;
+    }
+    segmentsLength.totalLength = totalLength;
+    return segmentsLength;
+  }
+
+  function BezierData(length) {
+    this.segmentLength = 0;
+    this.points = new Array(length);
+  }
+
+  function PointData(partial, point) {
+    this.partialLength = partial;
+    this.point = point;
+  }
+
+  var buildBezierData = (function () {
+    var storedData = {};
+
+    return function (pt1, pt2, pt3, pt4) {
+      var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
+      if (!storedData[bezierName]) {
+        var curveSegments = getDefaultCurveSegments();
+        var k;
+        var i;
+        var len;
+        var ptCoord;
+        var perc;
+        var addedLength = 0;
+        var ptDistance;
+        var point;
+        var lastPoint = null;
+        if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
+          curveSegments = 2;
+        }
+        var bezierData = new BezierData(curveSegments);
+        len = pt3.length;
+        for (k = 0; k < curveSegments; k += 1) {
+          point = createSizedArray(len);
+          perc = k / (curveSegments - 1);
+          ptDistance = 0;
+          for (i = 0; i < len; i += 1) {
+            ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
+            point[i] = ptCoord;
+            if (lastPoint !== null) {
+              ptDistance += bmPow(point[i] - lastPoint[i], 2);
+            }
+          }
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+          bezierData.points[k] = new PointData(ptDistance, point);
+          lastPoint = point;
+        }
+        bezierData.segmentLength = addedLength;
+        storedData[bezierName] = bezierData;
+      }
+      return storedData[bezierName];
+    };
+  }());
+
+  function getDistancePerc(perc, bezierData) {
+    var percents = bezierData.percents;
+    var lengths = bezierData.lengths;
+    var len = percents.length;
+    var initPos = bmFloor((len - 1) * perc);
+    var lengthPos = perc * bezierData.addedLength;
+    var lPerc = 0;
+    if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
+      return percents[initPos];
+    }
+    var dir = lengths[initPos] > lengthPos ? -1 : 1;
+    var flag = true;
+    while (flag) {
+      if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
+        lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
+        flag = false;
+      } else {
+        initPos += dir;
+      }
+      if (initPos < 0 || initPos >= len - 1) {
+        // FIX for TypedArrays that don't store floating point values with enough accuracy
+        if (initPos === len - 1) {
+          return percents[initPos];
+        }
+        flag = false;
+      }
+    }
+    return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
+  }
+
+  function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
+    var t1 = getDistancePerc(percent, bezierData);
+    var u1 = 1 - t1;
+    var ptX = math.round((u1 * u1 * u1 * pt1[0] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[0] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[0] + t1 * t1 * t1 * pt2[0]) * 1000) / 1000;
+    var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
+    return [ptX, ptY];
+  }
+
+  var bezierSegmentPoints = createTypedArray('float32', 8);
+
+  function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
+    if (startPerc < 0) {
+      startPerc = 0;
+    } else if (startPerc > 1) {
+      startPerc = 1;
+    }
+    var t0 = getDistancePerc(startPerc, bezierData);
+    endPerc = endPerc > 1 ? 1 : endPerc;
+    var t1 = getDistancePerc(endPerc, bezierData);
+    var i;
+    var len = pt1.length;
+    var u0 = 1 - t0;
+    var u1 = 1 - t1;
+    var u0u0u0 = u0 * u0 * u0;
+    var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0t0 = t0 * t0 * t0;
+    //
+    var u0u0u1 = u0 * u0 * u1;
+    var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0t1 = t0 * t0 * t1;
+    //
+    var u0u1u1 = u0 * u1 * u1;
+    var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1t1 = t0 * t1 * t1;
+    //
+    var u1u1u1 = u1 * u1 * u1;
+    var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1t1 = t1 * t1 * t1;
+    for (i = 0; i < len; i += 1) {
+      bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+    }
+
+    return bezierSegmentPoints;
+  }
+
+  return {
+    getSegmentsLength: getSegmentsLength,
+    getNewSegment: getNewSegment,
+    getPointInSegment: getPointInSegment,
+    buildBezierData: buildBezierData,
+    pointOnLine2D: pointOnLine2D,
+    pointOnLine3D: pointOnLine3D,
+  };
+}
+
+const bez = bezFunction();
+
+var initFrame = initialDefaultFrame;
+var mathAbs = Math.abs;
+
+function interpolateValue(frameNum, caching) {
+  var offsetTime = this.offsetTime;
+  var newValue;
+  if (this.propType === 'multidimensional') {
+    newValue = createTypedArray('float32', this.pv.length);
+  }
+  var iterationIndex = caching.lastIndex;
+  var i = iterationIndex;
+  var len = this.keyframes.length - 1;
+  var flag = true;
+  var keyData;
+  var nextKeyData;
+  var keyframeMetadata;
+
+  while (flag) {
+    keyData = this.keyframes[i];
+    nextKeyData = this.keyframes[i + 1];
+    if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
+      if (keyData.h) {
+        keyData = nextKeyData;
+      }
+      iterationIndex = 0;
+      break;
+    }
+    if ((nextKeyData.t - offsetTime) > frameNum) {
+      iterationIndex = i;
+      break;
+    }
+    if (i < len - 1) {
+      i += 1;
+    } else {
+      iterationIndex = 0;
+      flag = false;
+    }
+  }
+  keyframeMetadata = this.keyframesMetadata[i] || {};
+
+  var k;
+  var kLen;
+  var perc;
+  var jLen;
+  var j;
+  var fnc;
+  var nextKeyTime = nextKeyData.t - offsetTime;
+  var keyTime = keyData.t - offsetTime;
+  var endValue;
+  if (keyData.to) {
+    if (!keyframeMetadata.bezierData) {
+      keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
+    }
+    var bezierData = keyframeMetadata.bezierData;
+    if (frameNum >= nextKeyTime || frameNum < keyTime) {
+      var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
+      kLen = bezierData.points[ind].point.length;
+      for (k = 0; k < kLen; k += 1) {
+        newValue[k] = bezierData.points[ind].point[k];
+      }
+      // caching._lastKeyframeIndex = -1;
+    } else {
+      if (keyframeMetadata.__fnct) {
+        fnc = keyframeMetadata.__fnct;
+      } else {
+        fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
+        keyframeMetadata.__fnct = fnc;
+      }
+      perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+      var distanceInLine = bezierData.segmentLength * perc;
+
+      var segmentPerc;
+      var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0;
+      j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0;
+      flag = true;
+      jLen = bezierData.points.length;
+      while (flag) {
+        addedLength += bezierData.points[j].partialLength;
+        if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k];
+          }
+          break;
+        } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
+          segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
+          }
+          break;
+        }
+        if (j < jLen - 1) {
+          j += 1;
+        } else {
+          flag = false;
+        }
+      }
+      caching._lastPoint = j;
+      caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
+      caching._lastKeyframeIndex = i;
+    }
+  } else {
+    var outX;
+    var outY;
+    var inX;
+    var inY;
+    var keyValue;
+    len = keyData.s.length;
+    endValue = nextKeyData.s || keyData.e;
+    if (this.sh && keyData.h !== 1) {
+      if (frameNum >= nextKeyTime) {
+        newValue[0] = endValue[0];
+        newValue[1] = endValue[1];
+        newValue[2] = endValue[2];
+      } else if (frameNum <= keyTime) {
+        newValue[0] = keyData.s[0];
+        newValue[1] = keyData.s[1];
+        newValue[2] = keyData.s[2];
+      } else {
+        var quatStart = createQuaternion(keyData.s);
+        var quatEnd = createQuaternion(endValue);
+        var time = (frameNum - keyTime) / (nextKeyTime - keyTime);
+        quaternionToEuler(newValue, slerp(quatStart, quatEnd, time));
+      }
+    } else {
+      for (i = 0; i < len; i += 1) {
+        if (keyData.h !== 1) {
+          if (frameNum >= nextKeyTime) {
+            perc = 1;
+          } else if (frameNum < keyTime) {
+            perc = 0;
+          } else {
+            if (keyData.o.x.constructor === Array) {
+              if (!keyframeMetadata.__fnct) {
+                keyframeMetadata.__fnct = [];
+              }
+              if (!keyframeMetadata.__fnct[i]) {
+                outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
+                outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
+                inX = keyData.i.x[i] === undefined ? keyData.i.x[0] : keyData.i.x[i];
+                inY = keyData.i.y[i] === undefined ? keyData.i.y[0] : keyData.i.y[i];
+                fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+                keyframeMetadata.__fnct[i] = fnc;
+              } else {
+                fnc = keyframeMetadata.__fnct[i];
+              }
+            } else if (!keyframeMetadata.__fnct) {
+              outX = keyData.o.x;
+              outY = keyData.o.y;
+              inX = keyData.i.x;
+              inY = keyData.i.y;
+              fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+              keyData.keyframeMetadata = fnc;
+            } else {
+              fnc = keyframeMetadata.__fnct;
+            }
+            perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+          }
+        }
+
+        endValue = nextKeyData.s || keyData.e;
+        keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
+
+        if (this.propType === 'multidimensional') {
+          newValue[i] = keyValue;
+        } else {
+          newValue = keyValue;
+        }
+      }
+    }
+  }
+  caching.lastIndex = iterationIndex;
+  return newValue;
+}
+
+// based on @Toji's https://github.com/toji/gl-matrix/
+function slerp(a, b, t) {
+  var out = [];
+  var ax = a[0];
+  var ay = a[1];
+  var az = a[2];
+  var aw = a[3];
+  var bx = b[0];
+  var by = b[1];
+  var bz = b[2];
+  var bw = b[3];
+
+  var omega;
+  var cosom;
+  var sinom;
+  var scale0;
+  var scale1;
+
+  cosom = ax * bx + ay * by + az * bz + aw * bw;
+  if (cosom < 0.0) {
+    cosom = -cosom;
+    bx = -bx;
+    by = -by;
+    bz = -bz;
+    bw = -bw;
+  }
+  if ((1.0 - cosom) > 0.000001) {
+    omega = Math.acos(cosom);
+    sinom = Math.sin(omega);
+    scale0 = Math.sin((1.0 - t) * omega) / sinom;
+    scale1 = Math.sin(t * omega) / sinom;
+  } else {
+    scale0 = 1.0 - t;
+    scale1 = t;
+  }
+  out[0] = scale0 * ax + scale1 * bx;
+  out[1] = scale0 * ay + scale1 * by;
+  out[2] = scale0 * az + scale1 * bz;
+  out[3] = scale0 * aw + scale1 * bw;
+
+  return out;
+}
+
+function quaternionToEuler(out, quat) {
+  var qx = quat[0];
+  var qy = quat[1];
+  var qz = quat[2];
+  var qw = quat[3];
+  var heading = Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy * qy - 2 * qz * qz);
+  var attitude = Math.asin(2 * qx * qy + 2 * qz * qw);
+  var bank = Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx * qx - 2 * qz * qz);
+  out[0] = heading / degToRads;
+  out[1] = attitude / degToRads;
+  out[2] = bank / degToRads;
+}
+
+function createQuaternion(values) {
+  var heading = values[0] * degToRads;
+  var attitude = values[1] * degToRads;
+  var bank = values[2] * degToRads;
+  var c1 = Math.cos(heading / 2);
+  var c2 = Math.cos(attitude / 2);
+  var c3 = Math.cos(bank / 2);
+  var s1 = Math.sin(heading / 2);
+  var s2 = Math.sin(attitude / 2);
+  var s3 = Math.sin(bank / 2);
+  var w = c1 * c2 * c3 - s1 * s2 * s3;
+  var x = s1 * s2 * c3 + c1 * c2 * s3;
+  var y = s1 * c2 * c3 + c1 * s2 * s3;
+  var z = c1 * s2 * c3 - s1 * c2 * s3;
+
+  return [x, y, z, w];
+}
+
+function getValueAtCurrentTime() {
+  var frameNum = this.comp.renderedFrame - this.offsetTime;
+  var initTime = this.keyframes[0].t - this.offsetTime;
+  var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+  if (!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))) {
+    if (this._caching.lastFrame >= frameNum) {
+      this._caching._lastKeyframeIndex = -1;
+      this._caching.lastIndex = 0;
+    }
+
+    var renderResult = this.interpolateValue(frameNum, this._caching);
+    this.pv = renderResult;
+  }
+  this._caching.lastFrame = frameNum;
+  return this.pv;
+}
+
+function setVValue(val) {
+  var multipliedValue;
+  if (this.propType === 'unidimensional') {
+    multipliedValue = val * this.mult;
+    if (mathAbs(this.v - multipliedValue) > 0.00001) {
+      this.v = multipliedValue;
+      this._mdf = true;
+    }
+  } else {
+    var i = 0;
+    var len = this.v.length;
+    while (i < len) {
+      multipliedValue = val[i] * this.mult;
+      if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
+        this.v[i] = multipliedValue;
+        this._mdf = true;
+      }
+      i += 1;
+    }
+  }
+}
+
+function processEffectsSequence() {
+  if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
+    return;
+  }
+  if (this.lock) {
+    this.setVValue(this.pv);
+    return;
+  }
+  this.lock = true;
+  this._mdf = this._isFirstFrame;
+  var i;
+  var len = this.effectsSequence.length;
+  var finalValue = this.kf ? this.pv : this.data.k;
+  for (i = 0; i < len; i += 1) {
+    finalValue = this.effectsSequence[i](finalValue);
+  }
+  this.setVValue(finalValue);
+  this._isFirstFrame = false;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+}
+
+function addEffect(effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.container.addDynamicProperty(this);
+}
+
+function ValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this.v = mult ? data.k * mult : data.k;
+  this.pv = data.k;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.vel = 0;
+  this.effectsSequence = [];
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function MultiDimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.frameId = -1;
+  var i;
+  var len = data.k.length;
+  this.v = createTypedArray('float32', len);
+  this.pv = createTypedArray('float32', len);
+  this.vel = createTypedArray('float32', len);
+  for (i = 0; i < len; i += 1) {
+    this.v[i] = data.k[i] * this.mult;
+    this.pv[i] = data.k[i];
+  }
+  this._isFirstFrame = true;
+  this.effectsSequence = [];
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function KeyframedValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.frameId = -1;
+  this._caching = {
+    lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1,
+  };
+  this.k = true;
+  this.kf = true;
+  this.data = data;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.v = initFrame;
+  this.pv = initFrame;
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.addEffect = addEffect;
+}
+
+function KeyframedMultidimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  var i;
+  var len = data.k.length;
+  var s;
+  var e;
+  var to;
+  var ti;
+  for (i = 0; i < len - 1; i += 1) {
+    if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
+      s = data.k[i].s;
+      e = data.k[i + 1].s;
+      to = data.k[i].to;
+      ti = data.k[i].ti;
+      if ((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2]))) {
+        data.k[i].to = null;
+        data.k[i].ti = null;
+      }
+      if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
+        if (s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) {
+          data.k[i].to = null;
+          data.k[i].ti = null;
+        }
+      }
+    }
+  }
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.data = data;
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.k = true;
+  this.kf = true;
+  this._isFirstFrame = true;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.frameId = -1;
+  var arrLen = data.k[0].s.length;
+  this.v = createTypedArray('float32', arrLen);
+  this.pv = createTypedArray('float32', arrLen);
+  for (i = 0; i < arrLen; i += 1) {
+    this.v[i] = initFrame;
+    this.pv[i] = initFrame;
+  }
+  this._caching = { lastFrame: initFrame, lastIndex: 0, value: createTypedArray('float32', arrLen) };
+  this.addEffect = addEffect;
+}
+
+const PropertyFactory = (function () {
+  function getProp(elem, data, type, mult, container) {
+    if (data.sid) {
+      data = elem.globalData.slotManager.getProp(data);
+    }
+    var p;
+    if (!data.k.length) {
+      p = new ValueProperty(elem, data, mult, container);
+    } else if (typeof (data.k[0]) === 'number') {
+      p = new MultiDimensionalProperty(elem, data, mult, container);
+    } else {
+      switch (type) {
+        case 0:
+          p = new KeyframedValueProperty(elem, data, mult, container);
+          break;
+        case 1:
+          p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
+          break;
+        default:
+          break;
+      }
+    }
+    if (p.effectsSequence.length) {
+      container.addDynamicProperty(p);
+    }
+    return p;
+  }
+
+  var ob = {
+    getProp: getProp,
+  };
+  return ob;
+}());
+
+function DynamicPropertyContainer() {}
+DynamicPropertyContainer.prototype = {
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+      this.container.addDynamicProperty(this);
+      this._isAnimated = true;
+    }
+  },
+  iterateDynamicProperties: function () {
+    this._mdf = false;
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      this.dynamicProperties[i].getValue();
+      if (this.dynamicProperties[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  },
+  initDynamicPropertyContainer: function (container) {
+    this.container = container;
+    this.dynamicProperties = [];
+    this._mdf = false;
+    this._isAnimated = false;
+  },
+};
+
+const pointPool = (function () {
+  function create() {
+    return createTypedArray('float32', 2);
+  }
+  return poolFactory(8, create);
+}());
+
+function ShapePath() {
+  this.c = false;
+  this._length = 0;
+  this._maxLength = 8;
+  this.v = createSizedArray(this._maxLength);
+  this.o = createSizedArray(this._maxLength);
+  this.i = createSizedArray(this._maxLength);
+}
+
+ShapePath.prototype.setPathData = function (closed, len) {
+  this.c = closed;
+  this.setLength(len);
+  var i = 0;
+  while (i < len) {
+    this.v[i] = pointPool.newElement();
+    this.o[i] = pointPool.newElement();
+    this.i[i] = pointPool.newElement();
+    i += 1;
+  }
+};
+
+ShapePath.prototype.setLength = function (len) {
+  while (this._maxLength < len) {
+    this.doubleArrayLength();
+  }
+  this._length = len;
+};
+
+ShapePath.prototype.doubleArrayLength = function () {
+  this.v = this.v.concat(createSizedArray(this._maxLength));
+  this.i = this.i.concat(createSizedArray(this._maxLength));
+  this.o = this.o.concat(createSizedArray(this._maxLength));
+  this._maxLength *= 2;
+};
+
+ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
+  var arr;
+  this._length = Math.max(this._length, pos + 1);
+  if (this._length >= this._maxLength) {
+    this.doubleArrayLength();
+  }
+  switch (type) {
+    case 'v':
+      arr = this.v;
+      break;
+    case 'i':
+      arr = this.i;
+      break;
+    case 'o':
+      arr = this.o;
+      break;
+    default:
+      arr = [];
+      break;
+  }
+  if (!arr[pos] || (arr[pos] && !replace)) {
+    arr[pos] = pointPool.newElement();
+  }
+  arr[pos][0] = x;
+  arr[pos][1] = y;
+};
+
+ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
+  this.setXYAt(vX, vY, 'v', pos, replace);
+  this.setXYAt(oX, oY, 'o', pos, replace);
+  this.setXYAt(iX, iY, 'i', pos, replace);
+};
+
+ShapePath.prototype.reverse = function () {
+  var newPath = new ShapePath();
+  newPath.setPathData(this.c, this._length);
+  var vertices = this.v;
+  var outPoints = this.o;
+  var inPoints = this.i;
+  var init = 0;
+  if (this.c) {
+    newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
+    init = 1;
+  }
+  var cnt = this._length - 1;
+  var len = this._length;
+
+  var i;
+  for (i = init; i < len; i += 1) {
+    newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
+    cnt -= 1;
+  }
+  return newPath;
+};
+
+ShapePath.prototype.length = function () {
+  return this._length;
+};
+
+const shapePool = (function () {
+  function create() {
+    return new ShapePath();
+  }
+
+  function release(shapePath) {
+    var len = shapePath._length;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      pointPool.release(shapePath.v[i]);
+      pointPool.release(shapePath.i[i]);
+      pointPool.release(shapePath.o[i]);
+      shapePath.v[i] = null;
+      shapePath.i[i] = null;
+      shapePath.o[i] = null;
+    }
+    shapePath._length = 0;
+    shapePath.c = false;
+  }
+
+  function clone(shape) {
+    var cloned = factory.newElement();
+    var i;
+    var len = shape._length === undefined ? shape.v.length : shape._length;
+    cloned.setLength(len);
+    cloned.c = shape.c;
+
+    for (i = 0; i < len; i += 1) {
+      cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
+    }
+    return cloned;
+  }
+
+  var factory = poolFactory(4, create, release);
+  factory.clone = clone;
+
+  return factory;
+}());
+
+function ShapeCollection() {
+  this._length = 0;
+  this._maxLength = 4;
+  this.shapes = createSizedArray(this._maxLength);
+}
+
+ShapeCollection.prototype.addShape = function (shapeData) {
+  if (this._length === this._maxLength) {
+    this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
+    this._maxLength *= 2;
+  }
+  this.shapes[this._length] = shapeData;
+  this._length += 1;
+};
+
+ShapeCollection.prototype.releaseShapes = function () {
+  var i;
+  for (i = 0; i < this._length; i += 1) {
+    shapePool.release(this.shapes[i]);
+  }
+  this._length = 0;
+};
+
+const shapeCollectionPool = (function () {
+  var ob = {
+    newShapeCollection: newShapeCollection,
+    release: release,
+  };
+
+  var _length = 0;
+  var _maxLength = 4;
+  var pool = createSizedArray(_maxLength);
+
+  function newShapeCollection() {
+    var shapeCollection;
+    if (_length) {
+      _length -= 1;
+      shapeCollection = pool[_length];
+    } else {
+      shapeCollection = new ShapeCollection();
+    }
+    return shapeCollection;
+  }
+
+  function release(shapeCollection) {
+    var i;
+    var len = shapeCollection._length;
+    for (i = 0; i < len; i += 1) {
+      shapePool.release(shapeCollection.shapes[i]);
+    }
+    shapeCollection._length = 0;
+
+    if (_length === _maxLength) {
+      pool = pooling.double(pool);
+      _maxLength *= 2;
+    }
+    pool[_length] = shapeCollection;
+    _length += 1;
+  }
+
+  return ob;
+}());
+
+const ShapePropertyFactory = (function () {
+  var initFrame = -999999;
+
+  function interpolateShape(frameNum, previousValue, caching) {
+    var iterationIndex = caching.lastIndex;
+    var keyPropS;
+    var keyPropE;
+    var isHold;
+    var j;
+    var k;
+    var jLen;
+    var kLen;
+    var perc;
+    var vertexValue;
+    var kf = this.keyframes;
+    if (frameNum < kf[0].t - this.offsetTime) {
+      keyPropS = kf[0].s[0];
+      isHold = true;
+      iterationIndex = 0;
+    } else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) {
+      keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
+      /* if(kf[kf.length - 1].s){
+                keyPropS = kf[kf.length - 1].s[0];
+            }else{
+                keyPropS = kf[kf.length - 2].e[0];
+            } */
+      isHold = true;
+    } else {
+      var i = iterationIndex;
+      var len = kf.length - 1;
+      var flag = true;
+      var keyData;
+      var nextKeyData;
+      var keyframeMetadata;
+      while (flag) {
+        keyData = kf[i];
+        nextKeyData = kf[i + 1];
+        if ((nextKeyData.t - this.offsetTime) > frameNum) {
+          break;
+        }
+        if (i < len - 1) {
+          i += 1;
+        } else {
+          flag = false;
+        }
+      }
+      keyframeMetadata = this.keyframesMetadata[i] || {};
+      isHold = keyData.h === 1;
+      iterationIndex = i;
+      if (!isHold) {
+        if (frameNum >= nextKeyData.t - this.offsetTime) {
+          perc = 1;
+        } else if (frameNum < keyData.t - this.offsetTime) {
+          perc = 0;
+        } else {
+          var fnc;
+          if (keyframeMetadata.__fnct) {
+            fnc = keyframeMetadata.__fnct;
+          } else {
+            fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
+            keyframeMetadata.__fnct = fnc;
+          }
+          perc = fnc((frameNum - (keyData.t - this.offsetTime)) / ((nextKeyData.t - this.offsetTime) - (keyData.t - this.offsetTime)));
+        }
+        keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
+      }
+      keyPropS = keyData.s[0];
+    }
+    jLen = previousValue._length;
+    kLen = keyPropS.i[0].length;
+    caching.lastIndex = iterationIndex;
+
+    for (j = 0; j < jLen; j += 1) {
+      for (k = 0; k < kLen; k += 1) {
+        vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
+        previousValue.i[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc;
+        previousValue.o[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc;
+        previousValue.v[j][k] = vertexValue;
+      }
+    }
+  }
+
+  function interpolateShapeCurrentTime() {
+    var frameNum = this.comp.renderedFrame - this.offsetTime;
+    var initTime = this.keyframes[0].t - this.offsetTime;
+    var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+    var lastFrame = this._caching.lastFrame;
+    if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) {
+      /// /
+      this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
+      this.interpolateShape(frameNum, this.pv, this._caching);
+      /// /
+    }
+    this._caching.lastFrame = frameNum;
+    return this.pv;
+  }
+
+  function resetShape() {
+    this.paths = this.localShapeCollection;
+  }
+
+  function shapesEqual(shape1, shape2) {
+    if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
+      return false;
+    }
+    var i;
+    var len = shape1._length;
+    for (i = 0; i < len; i += 1) {
+      if (shape1.v[i][0] !== shape2.v[i][0]
+            || shape1.v[i][1] !== shape2.v[i][1]
+            || shape1.o[i][0] !== shape2.o[i][0]
+            || shape1.o[i][1] !== shape2.o[i][1]
+            || shape1.i[i][0] !== shape2.i[i][0]
+            || shape1.i[i][1] !== shape2.i[i][1]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  function setVValue(newPath) {
+    if (!shapesEqual(this.v, newPath)) {
+      this.v = shapePool.clone(newPath);
+      this.localShapeCollection.releaseShapes();
+      this.localShapeCollection.addShape(this.v);
+      this._mdf = true;
+      this.paths = this.localShapeCollection;
+    }
+  }
+
+  function processEffectsSequence() {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    } if (!this.effectsSequence.length) {
+      this._mdf = false;
+      return;
+    }
+    if (this.lock) {
+      this.setVValue(this.pv);
+      return;
+    }
+    this.lock = true;
+    this._mdf = false;
+    var finalValue;
+    if (this.kf) {
+      finalValue = this.pv;
+    } else if (this.data.ks) {
+      finalValue = this.data.ks.k;
+    } else {
+      finalValue = this.data.pt.k;
+    }
+    var i;
+    var len = this.effectsSequence.length;
+    for (i = 0; i < len; i += 1) {
+      finalValue = this.effectsSequence[i](finalValue);
+    }
+    this.setVValue(finalValue);
+    this.lock = false;
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function ShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.container = elem;
+    this.elem = elem;
+    this.data = data;
+    this.k = false;
+    this.kf = false;
+    this._mdf = false;
+    var pathData = type === 3 ? data.pt.k : data.ks.k;
+    this.v = shapePool.clone(pathData);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.reset = resetShape;
+    this.effectsSequence = [];
+  }
+
+  function addEffect(effectFunction) {
+    this.effectsSequence.push(effectFunction);
+    this.container.addDynamicProperty(this);
+  }
+
+  ShapeProperty.prototype.interpolateShape = interpolateShape;
+  ShapeProperty.prototype.getValue = processEffectsSequence;
+  ShapeProperty.prototype.setVValue = setVValue;
+  ShapeProperty.prototype.addEffect = addEffect;
+
+  function KeyframedShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.elem = elem;
+    this.container = elem;
+    this.offsetTime = elem.data.st;
+    this.keyframes = type === 3 ? data.pt.k : data.ks.k;
+    this.keyframesMetadata = [];
+    this.k = true;
+    this.kf = true;
+    var len = this.keyframes[0].s[0].i.length;
+    this.v = shapePool.newElement();
+    this.v.setPathData(this.keyframes[0].s[0].c, len);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.lastFrame = initFrame;
+    this.reset = resetShape;
+    this._caching = { lastFrame: initFrame, lastIndex: 0 };
+    this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
+  }
+  KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
+  KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
+  KeyframedShapeProperty.prototype.setVValue = setVValue;
+  KeyframedShapeProperty.prototype.addEffect = addEffect;
+
+  var EllShapeProperty = (function () {
+    var cPoint = roundCorner;
+
+    function EllShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 4);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.paths = this.localShapeCollection;
+      this.localShapeCollection.addShape(this.v);
+      this.d = data.d;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertEllToPath();
+      }
+    }
+
+    EllShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+
+        if (this._mdf) {
+          this.convertEllToPath();
+        }
+      },
+      convertEllToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var s0 = this.s.v[0] / 2;
+        var s1 = this.s.v[1] / 2;
+        var _cw = this.d !== 3;
+        var _v = this.v;
+        _v.v[0][0] = p0;
+        _v.v[0][1] = p1 - s1;
+        _v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.v[1][1] = p1;
+        _v.v[2][0] = p0;
+        _v.v[2][1] = p1 + s1;
+        _v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.v[3][1] = p1;
+        _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.i[0][1] = p1 - s1;
+        _v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.i[1][1] = p1 - s1 * cPoint;
+        _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.i[2][1] = p1 + s1;
+        _v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.i[3][1] = p1 + s1 * cPoint;
+        _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.o[0][1] = p1 - s1;
+        _v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.o[1][1] = p1 + s1 * cPoint;
+        _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.o[2][1] = p1 + s1;
+        _v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.o[3][1] = p1 - s1 * cPoint;
+      },
+    };
+
+    extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
+
+    return EllShapePropertyFactory;
+  }());
+
+  var StarShapeProperty = (function () {
+    function StarShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 0);
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.data = data;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      if (data.sy === 1) {
+        this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
+        this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
+        this.convertToPath = this.convertStarToPath;
+      } else {
+        this.convertToPath = this.convertPolygonToPath;
+      }
+      this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
+      this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this);
+      this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertToPath();
+      }
+    }
+
+    StarShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertToPath();
+        }
+      },
+      convertStarToPath: function () {
+        var numPts = Math.floor(this.pt.v) * 2;
+        var angle = (Math.PI * 2) / numPts;
+        /* this.v.v.length = numPts;
+                this.v.i.length = numPts;
+                this.v.o.length = numPts; */
+        var longFlag = true;
+        var longRad = this.or.v;
+        var shortRad = this.ir.v;
+        var longRound = this.os.v;
+        var shortRound = this.is.v;
+        var longPerimSegment = (2 * Math.PI * longRad) / (numPts * 2);
+        var shortPerimSegment = (2 * Math.PI * shortRad) / (numPts * 2);
+        var i;
+        var rad;
+        var roundness;
+        var perimSegment;
+        var currentAng = -Math.PI / 2;
+        currentAng += this.r.v;
+        var dir = this.data.d === 3 ? -1 : 1;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          rad = longFlag ? longRad : shortRad;
+          roundness = longFlag ? longRound : shortRound;
+          perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
+          /* this.v.v[i] = [x,y];
+                    this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
+                    this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
+                    this.v._length = numPts; */
+          longFlag = !longFlag;
+          currentAng += angle * dir;
+        }
+      },
+      convertPolygonToPath: function () {
+        var numPts = Math.floor(this.pt.v);
+        var angle = (Math.PI * 2) / numPts;
+        var rad = this.or.v;
+        var roundness = this.os.v;
+        var perimSegment = (2 * Math.PI * rad) / (numPts * 4);
+        var i;
+        var currentAng = -Math.PI * 0.5;
+        var dir = this.data.d === 3 ? -1 : 1;
+        currentAng += this.r.v;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+          currentAng += angle * dir;
+        }
+        this.paths.length = 0;
+        this.paths[0] = this.v;
+      },
+
+    };
+    extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
+
+    return StarShapePropertyFactory;
+  }());
+
+  var RectShapeProperty = (function () {
+    function RectShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.c = true;
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertRectToPath();
+      }
+    }
+
+    RectShapePropertyFactory.prototype = {
+      convertRectToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var v0 = this.s.v[0] / 2;
+        var v1 = this.s.v[1] / 2;
+        var round = bmMin(v0, v1, this.r.v);
+        var cPoint = round * (1 - roundCorner);
+        this.v._length = 0;
+
+        if (this.d === 2 || this.d === 1) {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
+          this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2);
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3);
+          }
+        } else {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true);
+          }
+        }
+      },
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertRectToPath();
+        }
+      },
+      reset: resetShape,
+    };
+    extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
+
+    return RectShapePropertyFactory;
+  }());
+
+  function getShapeProp(elem, data, type) {
+    var prop;
+    if (type === 3 || type === 4) {
+      var dataProp = type === 3 ? data.pt : data.ks;
+      var keys = dataProp.k;
+      if (keys.length) {
+        prop = new KeyframedShapeProperty(elem, data, type);
+      } else {
+        prop = new ShapeProperty(elem, data, type);
+      }
+    } else if (type === 5) {
+      prop = new RectShapeProperty(elem, data);
+    } else if (type === 6) {
+      prop = new EllShapeProperty(elem, data);
+    } else if (type === 7) {
+      prop = new StarShapeProperty(elem, data);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  }
+
+  function getConstructorFunction() {
+    return ShapeProperty;
+  }
+
+  function getKeyframedConstructorFunction() {
+    return KeyframedShapeProperty;
+  }
+
+  var ob = {};
+  ob.getShapeProp = getShapeProp;
+  ob.getConstructorFunction = getConstructorFunction;
+  ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction;
+  return ob;
+}());
+
+/*!
+ Transformation Matrix v2.0
+ (c) Epistemex 2014-2015
+ www.epistemex.com
+ By Ken Fyrstenberg
+ Contributions by leeoniya.
+ License: MIT, header required.
+ */
+
+/**
+ * 2D transformation matrix object initialized with identity matrix.
+ *
+ * The matrix can synchronize a canvas context by supplying the context
+ * as an argument, or later apply current absolute transform to an
+ * existing context.
+ *
+ * All values are handled as floating point values.
+ *
+ * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix
+ * @prop {number} a - scale x
+ * @prop {number} b - shear y
+ * @prop {number} c - shear x
+ * @prop {number} d - scale y
+ * @prop {number} e - translate x
+ * @prop {number} f - translate y
+ * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context
+ * @constructor
+ */
+
+const Matrix = (function () {
+  var _cos = Math.cos;
+  var _sin = Math.sin;
+  var _tan = Math.tan;
+  var _rnd = Math.round;
+
+  function reset() {
+    this.props[0] = 1;
+    this.props[1] = 0;
+    this.props[2] = 0;
+    this.props[3] = 0;
+    this.props[4] = 0;
+    this.props[5] = 1;
+    this.props[6] = 0;
+    this.props[7] = 0;
+    this.props[8] = 0;
+    this.props[9] = 0;
+    this.props[10] = 1;
+    this.props[11] = 0;
+    this.props[12] = 0;
+    this.props[13] = 0;
+    this.props[14] = 0;
+    this.props[15] = 1;
+    return this;
+  }
+
+  function rotate(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function rotateX(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateY(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateZ(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function shear(sx, sy) {
+    return this._t(1, sy, sx, 1, 0, 0);
+  }
+
+  function skew(ax, ay) {
+    return this.shear(_tan(ax), _tan(ay));
+  }
+
+  function skewFromAxis(ax, angle) {
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+    // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+  }
+
+  function scale(sx, sy, sz) {
+    if (!sz && sz !== 0) {
+      sz = 1;
+    }
+    if (sx === 1 && sy === 1 && sz === 1) {
+      return this;
+    }
+    return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
+  }
+
+  function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
+    this.props[0] = a;
+    this.props[1] = b;
+    this.props[2] = c;
+    this.props[3] = d;
+    this.props[4] = e;
+    this.props[5] = f;
+    this.props[6] = g;
+    this.props[7] = h;
+    this.props[8] = i;
+    this.props[9] = j;
+    this.props[10] = k;
+    this.props[11] = l;
+    this.props[12] = m;
+    this.props[13] = n;
+    this.props[14] = o;
+    this.props[15] = p;
+    return this;
+  }
+
+  function translate(tx, ty, tz) {
+    tz = tz || 0;
+    if (tx !== 0 || ty !== 0 || tz !== 0) {
+      return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
+    }
+    return this;
+  }
+
+  function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
+    var _p = this.props;
+
+    if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
+      // NOTE: commenting this condition because TurboFan deoptimizes code when present
+      // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
+      _p[12] = _p[12] * a2 + _p[15] * m2;
+      _p[13] = _p[13] * f2 + _p[15] * n2;
+      _p[14] = _p[14] * k2 + _p[15] * o2;
+      _p[15] *= p2;
+      // }
+      this._identityCalculated = false;
+      return this;
+    }
+
+    var a1 = _p[0];
+    var b1 = _p[1];
+    var c1 = _p[2];
+    var d1 = _p[3];
+    var e1 = _p[4];
+    var f1 = _p[5];
+    var g1 = _p[6];
+    var h1 = _p[7];
+    var i1 = _p[8];
+    var j1 = _p[9];
+    var k1 = _p[10];
+    var l1 = _p[11];
+    var m1 = _p[12];
+    var n1 = _p[13];
+    var o1 = _p[14];
+    var p1 = _p[15];
+
+    /* matrix order (canvas compatible):
+         * ace
+         * bdf
+         * 001
+         */
+    _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
+    _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
+    _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
+    _p[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2;
+
+    _p[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2;
+    _p[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2;
+    _p[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2;
+    _p[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2;
+
+    _p[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2;
+    _p[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2;
+    _p[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2;
+    _p[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2;
+
+    _p[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2;
+    _p[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2;
+    _p[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2;
+    _p[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2;
+
+    this._identityCalculated = false;
+    return this;
+  }
+
+  function multiply(matrix) {
+    var matrixProps = matrix.props;
+    return this.transform(
+      matrixProps[0],
+      matrixProps[1],
+      matrixProps[2],
+      matrixProps[3],
+      matrixProps[4],
+      matrixProps[5],
+      matrixProps[6],
+      matrixProps[7],
+      matrixProps[8],
+      matrixProps[9],
+      matrixProps[10],
+      matrixProps[11],
+      matrixProps[12],
+      matrixProps[13],
+      matrixProps[14],
+      matrixProps[15]
+    );
+  }
+
+  function isIdentity() {
+    if (!this._identityCalculated) {
+      this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
+      this._identityCalculated = true;
+    }
+    return this._identity;
+  }
+
+  function equals(matr) {
+    var i = 0;
+    while (i < 16) {
+      if (matr.props[i] !== this.props[i]) {
+        return false;
+      }
+      i += 1;
+    }
+    return true;
+  }
+
+  function clone(matr) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      matr.props[i] = this.props[i];
+    }
+    return matr;
+  }
+
+  function cloneFromProps(props) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      this.props[i] = props[i];
+    }
+  }
+
+  function applyToPoint(x, y, z) {
+    return {
+      x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+      y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+      z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+    };
+    /* return {
+         x: x * me.a + y * me.c + me.e,
+         y: x * me.b + y * me.d + me.f
+         }; */
+  }
+  function applyToX(x, y, z) {
+    return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
+  }
+  function applyToY(x, y, z) {
+    return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
+  }
+  function applyToZ(x, y, z) {
+    return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
+  }
+
+  function getInverseMatrix() {
+    var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
+    var a = this.props[5] / determinant;
+    var b = -this.props[1] / determinant;
+    var c = -this.props[4] / determinant;
+    var d = this.props[0] / determinant;
+    var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12]) / determinant;
+    var f = -(this.props[0] * this.props[13] - this.props[1] * this.props[12]) / determinant;
+    var inverseMatrix = new Matrix();
+    inverseMatrix.props[0] = a;
+    inverseMatrix.props[1] = b;
+    inverseMatrix.props[4] = c;
+    inverseMatrix.props[5] = d;
+    inverseMatrix.props[12] = e;
+    inverseMatrix.props[13] = f;
+    return inverseMatrix;
+  }
+
+  function inversePoint(pt) {
+    var inverseMatrix = this.getInverseMatrix();
+    return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
+  }
+
+  function inversePoints(pts) {
+    var i;
+    var len = pts.length;
+    var retPts = [];
+    for (i = 0; i < len; i += 1) {
+      retPts[i] = inversePoint(pts[i]);
+    }
+    return retPts;
+  }
+
+  function applyToTriplePoints(pt1, pt2, pt3) {
+    var arr = createTypedArray('float32', 6);
+    if (this.isIdentity()) {
+      arr[0] = pt1[0];
+      arr[1] = pt1[1];
+      arr[2] = pt2[0];
+      arr[3] = pt2[1];
+      arr[4] = pt3[0];
+      arr[5] = pt3[1];
+    } else {
+      var p0 = this.props[0];
+      var p1 = this.props[1];
+      var p4 = this.props[4];
+      var p5 = this.props[5];
+      var p12 = this.props[12];
+      var p13 = this.props[13];
+      arr[0] = pt1[0] * p0 + pt1[1] * p4 + p12;
+      arr[1] = pt1[0] * p1 + pt1[1] * p5 + p13;
+      arr[2] = pt2[0] * p0 + pt2[1] * p4 + p12;
+      arr[3] = pt2[0] * p1 + pt2[1] * p5 + p13;
+      arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
+      arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
+    }
+    return arr;
+  }
+
+  function applyToPointArray(x, y, z) {
+    var arr;
+    if (this.isIdentity()) {
+      arr = [x, y, z];
+    } else {
+      arr = [
+        x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+        x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+        x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+      ];
+    }
+    return arr;
+  }
+
+  function applyToPointStringified(x, y) {
+    if (this.isIdentity()) {
+      return x + ',' + y;
+    }
+    var _p = this.props;
+    return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
+  }
+
+  function toCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var i = 0;
+    var props = this.props;
+    var cssValue = 'matrix3d(';
+    var v = 10000;
+    while (i < 16) {
+      cssValue += _rnd(props[i] * v) / v;
+      cssValue += i === 15 ? ')' : ',';
+      i += 1;
+    }
+    return cssValue;
+  }
+
+  function roundMatrixProperty(val) {
+    var v = 10000;
+    if ((val < 0.000001 && val > 0) || (val > -0.000001 && val < 0)) {
+      return _rnd(val * v) / v;
+    }
+    return val;
+  }
+
+  function to2dCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var props = this.props;
+    var _a = roundMatrixProperty(props[0]);
+    var _b = roundMatrixProperty(props[1]);
+    var _c = roundMatrixProperty(props[4]);
+    var _d = roundMatrixProperty(props[5]);
+    var _e = roundMatrixProperty(props[12]);
+    var _f = roundMatrixProperty(props[13]);
+    return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
+  }
+
+  return function () {
+    this.reset = reset;
+    this.rotate = rotate;
+    this.rotateX = rotateX;
+    this.rotateY = rotateY;
+    this.rotateZ = rotateZ;
+    this.skew = skew;
+    this.skewFromAxis = skewFromAxis;
+    this.shear = shear;
+    this.scale = scale;
+    this.setTransform = setTransform;
+    this.translate = translate;
+    this.transform = transform;
+    this.multiply = multiply;
+    this.applyToPoint = applyToPoint;
+    this.applyToX = applyToX;
+    this.applyToY = applyToY;
+    this.applyToZ = applyToZ;
+    this.applyToPointArray = applyToPointArray;
+    this.applyToTriplePoints = applyToTriplePoints;
+    this.applyToPointStringified = applyToPointStringified;
+    this.toCSS = toCSS;
+    this.to2dCSS = to2dCSS;
+    this.clone = clone;
+    this.cloneFromProps = cloneFromProps;
+    this.equals = equals;
+    this.inversePoints = inversePoints;
+    this.inversePoint = inversePoint;
+    this.getInverseMatrix = getInverseMatrix;
+    this._t = this.transform;
+    this.isIdentity = isIdentity;
+    this._identity = true;
+    this._identityCalculated = false;
+
+    this.props = createTypedArray('float32', 16);
+    this.reset();
+  };
+}());
+
+const lottie = {};
+var standalone = '__[STANDALONE]__';
+var animationData = '__[ANIMATIONDATA]__';
+var renderer = '';
+
+function setLocation(href) {
+  setLocationHref(href);
+}
+
+function searchAnimations() {
+  if (standalone === true) {
+    animationManager.searchAnimations(animationData, standalone, renderer);
+  } else {
+    animationManager.searchAnimations();
+  }
+}
+
+function setSubframeRendering(flag) {
+  setSubframeEnabled(flag);
+}
+
+function setPrefix(prefix) {
+  setIdPrefix(prefix);
+}
+
+function loadAnimation(params) {
+  if (standalone === true) {
+    params.animationData = JSON.parse(animationData);
+  }
+  return animationManager.loadAnimation(params);
+}
+
+function setQuality(value) {
+  if (typeof value === 'string') {
+    switch (value) {
+      case 'high':
+        setDefaultCurveSegments(200);
+        break;
+      default:
+      case 'medium':
+        setDefaultCurveSegments(50);
+        break;
+      case 'low':
+        setDefaultCurveSegments(10);
+        break;
+    }
+  } else if (!isNaN(value) && value > 1) {
+    setDefaultCurveSegments(value);
+  }
+  if (getDefaultCurveSegments() >= 50) {
+    roundValues(false);
+  } else {
+    roundValues(true);
+  }
+}
+
+function inBrowser() {
+  return typeof navigator !== 'undefined';
+}
+
+function installPlugin(type, plugin) {
+  if (type === 'expressions') {
+    setExpressionsPlugin(plugin);
+  }
+}
+
+function getFactory(name) {
+  switch (name) {
+    case 'propertyFactory':
+      return PropertyFactory;
+    case 'shapePropertyFactory':
+      return ShapePropertyFactory;
+    case 'matrix':
+      return Matrix;
+    default:
+      return null;
+  }
+}
+
+lottie.play = animationManager.play;
+lottie.pause = animationManager.pause;
+lottie.setLocationHref = setLocation;
+lottie.togglePause = animationManager.togglePause;
+lottie.setSpeed = animationManager.setSpeed;
+lottie.setDirection = animationManager.setDirection;
+lottie.stop = animationManager.stop;
+lottie.searchAnimations = searchAnimations;
+lottie.registerAnimation = animationManager.registerAnimation;
+lottie.loadAnimation = loadAnimation;
+lottie.setSubframeRendering = setSubframeRendering;
+lottie.resize = animationManager.resize;
+// lottie.start = start;
+lottie.goToAndStop = animationManager.goToAndStop;
+lottie.destroy = animationManager.destroy;
+lottie.setQuality = setQuality;
+lottie.inBrowser = inBrowser;
+lottie.installPlugin = installPlugin;
+lottie.freeze = animationManager.freeze;
+lottie.unfreeze = animationManager.unfreeze;
+lottie.setVolume = animationManager.setVolume;
+lottie.mute = animationManager.mute;
+lottie.unmute = animationManager.unmute;
+lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations;
+lottie.useWebWorker = setWebWorker;
+lottie.setIDPrefix = setPrefix;
+lottie.__getFactory = getFactory;
+lottie.version = '[[BM_VERSION]]';
+
+function checkReady() {
+  if (document.readyState === 'complete') {
+    clearInterval(readyStateCheckInterval);
+    searchAnimations();
+  }
+}
+
+function getQueryVariable(variable) {
+  var vars = queryString.split('&');
+  for (var i = 0; i < vars.length; i += 1) {
+    var pair = vars[i].split('=');
+    if (decodeURIComponent(pair[0]) == variable) { // eslint-disable-line eqeqeq
+      return decodeURIComponent(pair[1]);
+    }
+  }
+  return null;
+}
+var queryString = '';
+if (standalone) {
+  var scripts = document.getElementsByTagName('script');
+  var index = scripts.length - 1;
+  var myScript = scripts[index] || {
+    src: '',
+  };
+  queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
+  renderer = getQueryVariable('renderer');
+}
+var readyStateCheckInterval = setInterval(checkReady, 100);
+
+// this adds bodymovin to the window object for backwards compatibility
+try {
+  if (!(typeof exports === 'object' && typeof module !== 'undefined')
+    && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
+  ) {
+    window.bodymovin = lottie;
+  }
+} catch (err) {
+  //
+}
+
+const ShapeModifiers = (function () {
+  var ob = {};
+  var modifiers = {};
+  ob.registerModifier = registerModifier;
+  ob.getModifier = getModifier;
+
+  function registerModifier(nm, factory) {
+    if (!modifiers[nm]) {
+      modifiers[nm] = factory;
+    }
+  }
+
+  function getModifier(nm, elem, data) {
+    return new modifiers[nm](elem, data);
+  }
+
+  return ob;
+}());
+
+function ShapeModifier() {}
+ShapeModifier.prototype.initModifierProperties = function () {};
+ShapeModifier.prototype.addShapeToModifier = function () {};
+ShapeModifier.prototype.addShape = function (data) {
+  if (!this.closed) {
+    // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
+    data.sh.container.addDynamicProperty(data.sh);
+    var shapeData = { shape: data.sh, data: data, localShapeCollection: shapeCollectionPool.newShapeCollection() };
+    this.shapes.push(shapeData);
+    this.addShapeToModifier(shapeData);
+    if (this._isAnimated) {
+      data.setAsAnimated();
+    }
+  }
+};
+ShapeModifier.prototype.init = function (elem, data) {
+  this.shapes = [];
+  this.elem = elem;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, data);
+  this.frameId = initialDefaultFrame;
+  this.closed = false;
+  this.k = false;
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+ShapeModifier.prototype.processKeys = function () {
+  if (this.elem.globalData.frameId === this.frameId) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+extendPrototype([DynamicPropertyContainer], ShapeModifier);
+
+function TrimModifier() {
+}
+extendPrototype([ShapeModifier], TrimModifier);
+TrimModifier.prototype.initModifierProperties = function (elem, data) {
+  this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this);
+  this.sValue = 0;
+  this.eValue = 0;
+  this.getValue = this.processKeys;
+  this.m = data.m;
+  this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
+};
+
+TrimModifier.prototype.addShapeToModifier = function (shapeData) {
+  shapeData.pathsData = [];
+};
+
+TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
+  var segments = [];
+  if (e <= 1) {
+    segments.push({
+      s: s,
+      e: e,
+    });
+  } else if (s >= 1) {
+    segments.push({
+      s: s - 1,
+      e: e - 1,
+    });
+  } else {
+    segments.push({
+      s: s,
+      e: 1,
+    });
+    segments.push({
+      s: 0,
+      e: e - 1,
+    });
+  }
+  var shapeSegments = [];
+  var i;
+  var len = segments.length;
+  var segmentOb;
+  for (i = 0; i < len; i += 1) {
+    segmentOb = segments[i];
+    if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
+      var shapeS;
+      var shapeE;
+      if (segmentOb.s * totalModifierLength <= addedLength) {
+        shapeS = 0;
+      } else {
+        shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
+      }
+      if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
+        shapeE = 1;
+      } else {
+        shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength);
+      }
+      shapeSegments.push([shapeS, shapeE]);
+    }
+  }
+  if (!shapeSegments.length) {
+    shapeSegments.push([0, 0]);
+  }
+  return shapeSegments;
+};
+
+TrimModifier.prototype.releasePathsData = function (pathsData) {
+  var i;
+  var len = pathsData.length;
+  for (i = 0; i < len; i += 1) {
+    segmentsLengthPool.release(pathsData[i]);
+  }
+  pathsData.length = 0;
+  return pathsData;
+};
+
+TrimModifier.prototype.processShapes = function (_isFirstFrame) {
+  var s;
+  var e;
+  if (this._mdf || _isFirstFrame) {
+    var o = (this.o.v % 360) / 360;
+    if (o < 0) {
+      o += 1;
+    }
+    if (this.s.v > 1) {
+      s = 1 + o;
+    } else if (this.s.v < 0) {
+      s = 0 + o;
+    } else {
+      s = this.s.v + o;
+    }
+    if (this.e.v > 1) {
+      e = 1 + o;
+    } else if (this.e.v < 0) {
+      e = 0 + o;
+    } else {
+      e = this.e.v + o;
+    }
+
+    if (s > e) {
+      var _s = s;
+      s = e;
+      e = _s;
+    }
+    s = Math.round(s * 10000) * 0.0001;
+    e = Math.round(e * 10000) * 0.0001;
+    this.sValue = s;
+    this.eValue = e;
+  } else {
+    s = this.sValue;
+    e = this.eValue;
+  }
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var pathsData;
+  var pathData;
+  var totalShapeLength;
+  var totalModifierLength = 0;
+
+  if (e === s) {
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].localShapeCollection.releaseShapes();
+      this.shapes[i].shape._mdf = true;
+      this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
+      if (this._mdf) {
+        this.shapes[i].pathsData.length = 0;
+      }
+    }
+  } else if (!((e === 1 && s === 0) || (e === 0 && s === 1))) {
+    var segments = [];
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
+      if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
+        shapeData.shape.paths = shapeData.localShapeCollection;
+      } else {
+        shapePaths = shapeData.shape.paths;
+        jLen = shapePaths._length;
+        totalShapeLength = 0;
+        if (!shapeData.shape._mdf && shapeData.pathsData.length) {
+          totalShapeLength = shapeData.totalShapeLength;
+        } else {
+          pathsData = this.releasePathsData(shapeData.pathsData);
+          for (j = 0; j < jLen; j += 1) {
+            pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
+            pathsData.push(pathData);
+            totalShapeLength += pathData.totalLength;
+          }
+          shapeData.totalShapeLength = totalShapeLength;
+          shapeData.pathsData = pathsData;
+        }
+
+        totalModifierLength += totalShapeLength;
+        shapeData.shape._mdf = true;
+      }
+    }
+    var shapeS = s;
+    var shapeE = e;
+    var addedLength = 0;
+    var edges;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shapeData = this.shapes[i];
+      if (shapeData.shape._mdf) {
+        localShapeCollection = shapeData.localShapeCollection;
+        localShapeCollection.releaseShapes();
+        // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
+        if (this.m === 2 && len > 1) {
+          edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
+          addedLength += shapeData.totalShapeLength;
+        } else {
+          edges = [[shapeS, shapeE]];
+        }
+        jLen = edges.length;
+        for (j = 0; j < jLen; j += 1) {
+          shapeS = edges[j][0];
+          shapeE = edges[j][1];
+          segments.length = 0;
+          if (shapeE <= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength * shapeE,
+            });
+          } else if (shapeS >= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * (shapeS - 1),
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          } else {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength,
+            });
+            segments.push({
+              s: 0,
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          }
+          var newShapesData = this.addShapes(shapeData, segments[0]);
+          if (segments[0].s !== segments[0].e) {
+            if (segments.length > 1) {
+              var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
+              if (lastShapeInCollection.c) {
+                var lastShape = newShapesData.pop();
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1], lastShape);
+              } else {
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1]);
+              }
+            }
+            this.addPaths(newShapesData, localShapeCollection);
+          }
+        }
+        shapeData.shape.paths = localShapeCollection;
+      }
+    }
+  } else if (this._mdf) {
+    for (i = 0; i < len; i += 1) {
+      // Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween.
+      // Don't remove this even if it's losing cached info.
+      this.shapes[i].pathsData.length = 0;
+      this.shapes[i].shape._mdf = true;
+    }
+  }
+};
+
+TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
+  var i;
+  var len = newPaths.length;
+  for (i = 0; i < len; i += 1) {
+    localShapeCollection.addShape(newPaths[i]);
+  }
+};
+
+TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
+  shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
+  shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
+  }
+  shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
+  shapePath.setXYAt(points[1], points[5], 'o', pos);
+  shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(points[0], points[4], 'v', pos);
+  }
+  shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
+  var pathsData = shapeData.pathsData;
+  var shapePaths = shapeData.shape.paths.shapes;
+  var i;
+  var len = shapeData.shape.paths._length;
+  var j;
+  var jLen;
+  var addedLength = 0;
+  var currentLengthData;
+  var segmentCount;
+  var lengths;
+  var segment;
+  var shapes = [];
+  var initPos;
+  var newShape = true;
+  if (!shapePath) {
+    shapePath = shapePool.newElement();
+    segmentCount = 0;
+    initPos = 0;
+  } else {
+    segmentCount = shapePath._length;
+    initPos = shapePath._length;
+  }
+  shapes.push(shapePath);
+  for (i = 0; i < len; i += 1) {
+    lengths = pathsData[i].lengths;
+    shapePath.c = shapePaths[i].c;
+    jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
+    for (j = 1; j < jLen; j += 1) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
+        addedLength += currentLengthData.addedLength;
+        shapePath.c = false;
+      } else if (addedLength > shapeSegment.e) {
+        shapePath.c = false;
+        break;
+      } else {
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+        addedLength += currentLengthData.addedLength;
+        segmentCount += 1;
+      }
+    }
+    if (shapePaths[i].c && lengths.length) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength <= shapeSegment.e) {
+        var segmentLength = lengths[j - 1].addedLength;
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+      } else {
+        shapePath.c = false;
+      }
+      addedLength += currentLengthData.addedLength;
+      segmentCount += 1;
+    }
+    if (shapePath._length) {
+      shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
+      shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
+    }
+    if (addedLength > shapeSegment.e) {
+      break;
+    }
+    if (i < len - 1) {
+      shapePath = shapePool.newElement();
+      newShape = true;
+      shapes.push(shapePath);
+      segmentCount = 0;
+    }
+  }
+  return shapes;
+};
+
+function PuckerAndBloatModifier() {}
+extendPrototype([ShapeModifier], PuckerAndBloatModifier);
+PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this._isAnimated = !!this.amount.effectsSequence.length;
+};
+
+PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
+  var percent = amount / 100;
+  var centerPoint = [0, 0];
+  var pathLength = path._length;
+  var i = 0;
+  for (i = 0; i < pathLength; i += 1) {
+    centerPoint[0] += path.v[i][0];
+    centerPoint[1] += path.v[i][1];
+  }
+  centerPoint[0] /= pathLength;
+  centerPoint[1] /= pathLength;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < pathLength; i += 1) {
+    vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
+    vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
+    oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent;
+    oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent;
+    iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent;
+    iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
+    clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
+  }
+  return clonedPath;
+};
+
+PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+const TransformPropertyFactory = (function () {
+  var defaultVector = [0, 0];
+
+  function applyToMatrix(mat) {
+    var _mdf = this._mdf;
+    this.iterateDynamicProperties();
+    this._mdf = this._mdf || _mdf;
+    if (this.a) {
+      mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+    }
+    if (this.s) {
+      mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+    }
+    if (this.sk) {
+      mat.skewFromAxis(-this.sk.v, this.sa.v);
+    }
+    if (this.r) {
+      mat.rotate(-this.r.v);
+    } else {
+      mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+    }
+    if (this.data.p.s) {
+      if (this.data.p.z) {
+        mat.translate(this.px.v, this.py.v, -this.pz.v);
+      } else {
+        mat.translate(this.px.v, this.py.v, 0);
+      }
+    } else {
+      mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+    }
+  }
+  function processKeys(forceRender) {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    }
+    if (this._isDirty) {
+      this.precalculateMatrix();
+      this._isDirty = false;
+    }
+
+    this.iterateDynamicProperties();
+
+    if (this._mdf || forceRender) {
+      var frameRate;
+      this.v.cloneFromProps(this.pre.props);
+      if (this.appliedTransformations < 1) {
+        this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      }
+      if (this.appliedTransformations < 2) {
+        this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      }
+      if (this.sk && this.appliedTransformations < 3) {
+        this.v.skewFromAxis(-this.sk.v, this.sa.v);
+      }
+      if (this.r && this.appliedTransformations < 4) {
+        this.v.rotate(-this.r.v);
+      } else if (!this.r && this.appliedTransformations < 4) {
+        this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+          .rotateY(this.or.v[1])
+          .rotateX(this.or.v[0]);
+      }
+      if (this.autoOriented) {
+        var v1;
+        var v2;
+        frameRate = this.elem.globalData.frameRate;
+        if (this.p && this.p.keyframes && this.p.getValueAtTime) {
+          if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
+            v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0);
+          } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0);
+            v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0);
+          } else {
+            v1 = this.p.pv;
+            v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime);
+          }
+        } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) {
+          v1 = [];
+          v2 = [];
+          var px = this.px;
+          var py = this.py;
+          if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
+            v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
+            v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate, 0);
+          } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate), 0);
+            v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate), 0);
+            v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0);
+          } else {
+            v1 = [px.pv, py.pv];
+            v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime);
+            v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime);
+          }
+        } else {
+          v2 = defaultVector;
+          v1 = v2;
+        }
+        this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
+      }
+      if (this.data.p && this.data.p.s) {
+        if (this.data.p.z) {
+          this.v.translate(this.px.v, this.py.v, -this.pz.v);
+        } else {
+          this.v.translate(this.px.v, this.py.v, 0);
+        }
+      } else {
+        this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+      }
+    }
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function precalculateMatrix() {
+    this.appliedTransformations = 0;
+    this.pre.reset();
+
+    if (!this.a.effectsSequence.length) {
+      this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      this.appliedTransformations = 1;
+    } else {
+      return;
+    }
+    if (!this.s.effectsSequence.length) {
+      this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      this.appliedTransformations = 2;
+    } else {
+      return;
+    }
+    if (this.sk) {
+      if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
+        this.pre.skewFromAxis(-this.sk.v, this.sa.v);
+        this.appliedTransformations = 3;
+      } else {
+        return;
+      }
+    }
+    if (this.r) {
+      if (!this.r.effectsSequence.length) {
+        this.pre.rotate(-this.r.v);
+        this.appliedTransformations = 4;
+      }
+    } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) {
+      this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+      this.appliedTransformations = 4;
+    }
+  }
+
+  function autoOrient() {
+    //
+    // var prevP = this.getValueAtTime();
+  }
+
+  function addDynamicProperty(prop) {
+    this._addDynamicProperty(prop);
+    this.elem.addDynamicProperty(prop);
+    this._isDirty = true;
+  }
+
+  function TransformProperty(elem, data, container) {
+    this.elem = elem;
+    this.frameId = -1;
+    this.propType = 'transform';
+    this.data = data;
+    this.v = new Matrix();
+    // Precalculated matrix with non animated properties
+    this.pre = new Matrix();
+    this.appliedTransformations = 0;
+    this.initDynamicPropertyContainer(container || elem);
+    if (data.p && data.p.s) {
+      this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
+      this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
+      if (data.p.z) {
+        this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
+      }
+    } else {
+      this.p = PropertyFactory.getProp(elem, data.p || { k: [0, 0, 0] }, 1, 0, this);
+    }
+    if (data.rx) {
+      this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
+      this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
+      this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
+      if (data.or.k[0].ti) {
+        var i;
+        var len = data.or.k.length;
+        for (i = 0; i < len; i += 1) {
+          data.or.k[i].to = null;
+          data.or.k[i].ti = null;
+        }
+      }
+      this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+      // sh Indicates it needs to be capped between -180 and 180
+      this.or.sh = true;
+    } else {
+      this.r = PropertyFactory.getProp(elem, data.r || { k: 0 }, 0, degToRads, this);
+    }
+    if (data.sk) {
+      this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
+      this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
+    }
+    this.a = PropertyFactory.getProp(elem, data.a || { k: [0, 0, 0] }, 1, 0, this);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: [100, 100, 100] }, 1, 0.01, this);
+    // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
+    if (data.o) {
+      this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
+    } else {
+      this.o = { _mdf: false, v: 1 };
+    }
+    this._isDirty = true;
+    if (!this.dynamicProperties.length) {
+      this.getValue(true);
+    }
+  }
+
+  TransformProperty.prototype = {
+    applyToMatrix: applyToMatrix,
+    getValue: processKeys,
+    precalculateMatrix: precalculateMatrix,
+    autoOrient: autoOrient,
+  };
+
+  extendPrototype([DynamicPropertyContainer], TransformProperty);
+  TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
+  TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
+
+  function getTransformProperty(elem, data, container) {
+    return new TransformProperty(elem, data, container);
+  }
+
+  return {
+    getTransformProperty: getTransformProperty,
+  };
+}());
+
+function RepeaterModifier() {}
+extendPrototype([ShapeModifier], RepeaterModifier);
+
+RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, null, this);
+  this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this);
+  this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
+  this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
+  this.data = data;
+  if (!this.dynamicProperties.length) {
+    this.getValue(true);
+  }
+  this._isAnimated = !!this.dynamicProperties.length;
+  this.pMatrix = new Matrix();
+  this.rMatrix = new Matrix();
+  this.sMatrix = new Matrix();
+  this.tMatrix = new Matrix();
+  this.matrix = new Matrix();
+};
+
+RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
+  var dir = inv ? -1 : 1;
+  var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
+  var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
+  pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
+  rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  rMatrix.rotate(-transform.r.v * dir * perc);
+  rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+  sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
+  sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+};
+
+RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
+  this.elem = elem;
+  this.arr = arr;
+  this.pos = pos;
+  this.elemsData = elemsData;
+  this._currentCopies = 0;
+  this._elements = [];
+  this._groups = [];
+  this.frameId = -1;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, arr[pos]);
+  while (pos > 0) {
+    pos -= 1;
+    // this._elements.unshift(arr.splice(pos,1)[0]);
+    this._elements.unshift(arr[pos]);
+  }
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+
+RepeaterModifier.prototype.resetElements = function (elements) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._processed = false;
+    if (elements[i].ty === 'gr') {
+      this.resetElements(elements[i].it);
+    }
+  }
+};
+
+RepeaterModifier.prototype.cloneElements = function (elements) {
+  var newElements = JSON.parse(JSON.stringify(elements));
+  this.resetElements(newElements);
+  return newElements;
+};
+
+RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._render = renderFlag;
+    if (elements[i].ty === 'gr') {
+      this.changeGroupRender(elements[i].it, renderFlag);
+    }
+  }
+};
+
+RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
+  var items;
+  var itemsTransform;
+  var i;
+  var dir;
+  var cont;
+  var hasReloaded = false;
+  if (this._mdf || _isFirstFrame) {
+    var copies = Math.ceil(this.c.v);
+    if (this._groups.length < copies) {
+      while (this._groups.length < copies) {
+        var group = {
+          it: this.cloneElements(this._elements),
+          ty: 'gr',
+        };
+        group.it.push({
+          a: { a: 0, ix: 1, k: [0, 0] }, nm: 'Transform', o: { a: 0, ix: 7, k: 100 }, p: { a: 0, ix: 2, k: [0, 0] }, r: { a: 1, ix: 6, k: [{ s: 0, e: 0, t: 0 }, { s: 0, e: 0, t: 1 }] }, s: { a: 0, ix: 3, k: [100, 100] }, sa: { a: 0, ix: 5, k: 0 }, sk: { a: 0, ix: 4, k: 0 }, ty: 'tr',
+        });
+
+        this.arr.splice(0, 0, group);
+        this._groups.splice(0, 0, group);
+        this._currentCopies += 1;
+      }
+      this.elem.reloadShapes();
+      hasReloaded = true;
+    }
+    cont = 0;
+    var renderFlag;
+    for (i = 0; i <= this._groups.length - 1; i += 1) {
+      renderFlag = cont < copies;
+      this._groups[i]._render = renderFlag;
+      this.changeGroupRender(this._groups[i].it, renderFlag);
+      if (!renderFlag) {
+        var elems = this.elemsData[i].it;
+        var transformData = elems[elems.length - 1];
+        if (transformData.transform.op.v !== 0) {
+          transformData.transform.op._mdf = true;
+          transformData.transform.op.v = 0;
+        } else {
+          transformData.transform.op._mdf = false;
+        }
+      }
+      cont += 1;
+    }
+
+    this._currentCopies = copies;
+    /// /
+
+    var offset = this.o.v;
+    var offsetModulo = offset % 1;
+    var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
+    var pProps = this.pMatrix.props;
+    var rProps = this.rMatrix.props;
+    var sProps = this.sMatrix.props;
+    this.pMatrix.reset();
+    this.rMatrix.reset();
+    this.sMatrix.reset();
+    this.tMatrix.reset();
+    this.matrix.reset();
+    var iteration = 0;
+
+    if (offset > 0) {
+      while (iteration < roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        iteration += 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
+        iteration += offsetModulo;
+      }
+    } else if (offset < 0) {
+      while (iteration > roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
+        iteration -= 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
+        iteration -= offsetModulo;
+      }
+    }
+    i = this.data.m === 1 ? 0 : this._currentCopies - 1;
+    dir = this.data.m === 1 ? 1 : -1;
+    cont = this._currentCopies;
+    var j;
+    var jLen;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      jLen = itemsTransform.length;
+      items[items.length - 1].transform.mProps._mdf = true;
+      items[items.length - 1].transform.op._mdf = true;
+      items[items.length - 1].transform.op.v = this._currentCopies === 1
+        ? this.so.v
+        : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
+
+      if (iteration !== 0) {
+        if ((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)) {
+          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        }
+        this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
+        this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
+        this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
+
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+        this.matrix.reset();
+      } else {
+        this.matrix.reset();
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+      }
+      iteration += 1;
+      cont -= 1;
+      i += dir;
+    }
+  } else {
+    cont = this._currentCopies;
+    i = 0;
+    dir = 1;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      items[items.length - 1].transform.mProps._mdf = false;
+      items[items.length - 1].transform.op._mdf = false;
+      cont -= 1;
+      i += dir;
+    }
+  }
+  return hasReloaded;
+};
+
+RepeaterModifier.prototype.addShape = function () {};
+
+function RoundCornersModifier() {}
+extendPrototype([ShapeModifier], RoundCornersModifier);
+RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this._isAnimated = !!this.rd.effectsSequence.length;
+};
+
+RoundCornersModifier.prototype.processPath = function (path, round) {
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var i;
+  var len = path._length;
+  var currentV;
+  var currentI;
+  var currentO;
+  var closerV;
+  var distance;
+  var newPosPerc;
+  var index = 0;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < len; i += 1) {
+    currentV = path.v[i];
+    currentO = path.o[i];
+    currentI = path.i[i];
+    if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
+      if ((i === 0 || i === len - 1) && !path.c) {
+        clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
+        /* clonedPath.v[index] = currentV;
+                clonedPath.o[index] = currentO;
+                clonedPath.i[index] = currentI; */
+        index += 1;
+      } else {
+        if (i === 0) {
+          closerV = path.v[len - 1];
+        } else {
+          closerV = path.v[i - 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = iX;
+        iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
+        vY = iY;
+        oX = vX - (vX - currentV[0]) * roundCorner;
+        oY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+
+        if (i === len - 1) {
+          closerV = path.v[0];
+        } else {
+          closerV = path.v[i + 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = oX;
+        oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc;
+        vY = oY;
+        iX = vX - (vX - currentV[0]) * roundCorner;
+        iY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+      }
+    } else {
+      clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index);
+      index += 1;
+    }
+  }
+  return clonedPath;
+};
+
+RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var rd = this.rd.v;
+
+  if (rd !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function floatEqual(a, b) {
+  return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
+}
+
+function floatZero(f) {
+  return Math.abs(f) <= 0.00001;
+}
+
+function lerp(p0, p1, amount) {
+  return p0 * (1 - amount) + p1 * amount;
+}
+
+function lerpPoint(p0, p1, amount) {
+  return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
+}
+
+function quadRoots(a, b, c) {
+  // no root
+  if (a === 0) return [];
+  var s = b * b - 4 * a * c;
+  // Complex roots
+  if (s < 0) return [];
+  var singleRoot = -b / (2 * a);
+  // 1 root
+  if (s === 0) return [singleRoot];
+  var delta = Math.sqrt(s) / (2 * a);
+  // 2 roots
+  return [singleRoot - delta, singleRoot + delta];
+}
+
+function polynomialCoefficients(p0, p1, p2, p3) {
+  return [
+    -p0 + 3 * p1 - 3 * p2 + p3,
+    3 * p0 - 6 * p1 + 3 * p2,
+    -3 * p0 + 3 * p1,
+    p0,
+  ];
+}
+
+function singlePoint(p) {
+  return new PolynomialBezier(p, p, p, p, false);
+}
+
+function PolynomialBezier(p0, p1, p2, p3, linearize) {
+  if (linearize && pointEqual(p0, p1)) {
+    p1 = lerpPoint(p0, p3, 1 / 3);
+  }
+  if (linearize && pointEqual(p2, p3)) {
+    p2 = lerpPoint(p0, p3, 2 / 3);
+  }
+  var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
+  var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
+  this.a = [coeffx[0], coeffy[0]];
+  this.b = [coeffx[1], coeffy[1]];
+  this.c = [coeffx[2], coeffy[2]];
+  this.d = [coeffx[3], coeffy[3]];
+  this.points = [p0, p1, p2, p3];
+}
+PolynomialBezier.prototype.point = function (t) {
+  return [
+    (((this.a[0] * t) + this.b[0]) * t + this.c[0]) * t + this.d[0],
+    (((this.a[1] * t) + this.b[1]) * t + this.c[1]) * t + this.d[1],
+  ];
+};
+PolynomialBezier.prototype.derivative = function (t) {
+  return [
+    (3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0],
+    (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1],
+  ];
+};
+PolynomialBezier.prototype.tangentAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[1], p[0]);
+};
+PolynomialBezier.prototype.normalAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[0], p[1]);
+};
+
+PolynomialBezier.prototype.inflectionPoints = function () {
+  var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
+  if (floatZero(denom)) return [];
+  var tcusp = (-0.5 * (this.a[1] * this.c[0] - this.a[0] * this.c[1])) / denom;
+  var square = tcusp * tcusp - ((1 / 3) * (this.b[1] * this.c[0] - this.b[0] * this.c[1])) / denom;
+  if (square < 0) return [];
+  var root = Math.sqrt(square);
+  if (floatZero(root)) {
+    if (root > 0 && root < 1) return [tcusp];
+    return [];
+  }
+  return [tcusp - root, tcusp + root].filter(function (r) { return r > 0 && r < 1; });
+};
+PolynomialBezier.prototype.split = function (t) {
+  if (t <= 0) return [singlePoint(this.points[0]), this];
+  if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
+  var p10 = lerpPoint(this.points[0], this.points[1], t);
+  var p11 = lerpPoint(this.points[1], this.points[2], t);
+  var p12 = lerpPoint(this.points[2], this.points[3], t);
+  var p20 = lerpPoint(p10, p11, t);
+  var p21 = lerpPoint(p11, p12, t);
+  var p3 = lerpPoint(p20, p21, t);
+  return [
+    new PolynomialBezier(this.points[0], p10, p20, p3, true),
+    new PolynomialBezier(p3, p21, p12, this.points[3], true),
+  ];
+};
+function extrema(bez, comp) {
+  var min = bez.points[0][comp];
+  var max = bez.points[bez.points.length - 1][comp];
+  if (min > max) {
+    var e = max;
+    max = min;
+    min = e;
+  }
+  // Derivative roots to find min/max
+  var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
+  for (var i = 0; i < f.length; i += 1) {
+    if (f[i] > 0 && f[i] < 1) {
+      var val = bez.point(f[i])[comp];
+      if (val < min) min = val;
+      else if (val > max) max = val;
+    }
+  }
+  return {
+    min: min,
+    max: max,
+  };
+}
+PolynomialBezier.prototype.bounds = function () {
+  return {
+    x: extrema(this, 0),
+    y: extrema(this, 1),
+  };
+};
+PolynomialBezier.prototype.boundingBox = function () {
+  var bounds = this.bounds();
+  return {
+    left: bounds.x.min,
+    right: bounds.x.max,
+    top: bounds.y.min,
+    bottom: bounds.y.max,
+    width: bounds.x.max - bounds.x.min,
+    height: bounds.y.max - bounds.y.min,
+    cx: (bounds.x.max + bounds.x.min) / 2,
+    cy: (bounds.y.max + bounds.y.min) / 2,
+  };
+};
+
+function intersectData(bez, t1, t2) {
+  var box = bez.boundingBox();
+  return {
+    cx: box.cx,
+    cy: box.cy,
+    width: box.width,
+    height: box.height,
+    bez: bez,
+    t: (t1 + t2) / 2,
+    t1: t1,
+    t2: t2,
+  };
+}
+function splitData(data) {
+  var split = data.bez.split(0.5);
+  return [
+    intersectData(split[0], data.t1, data.t),
+    intersectData(split[1], data.t, data.t2),
+  ];
+}
+
+function boxIntersect(b1, b2) {
+  return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width
+    && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
+}
+
+function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
+  if (!boxIntersect(d1, d2)) return;
+  if (depth >= maxRecursion || (d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance)) {
+    intersections.push([d1.t, d2.t]);
+    return;
+  }
+  var d1s = splitData(d1);
+  var d2s = splitData(d2);
+  intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[0], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+}
+
+PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
+  if (tolerance === undefined) tolerance = 2;
+  if (maxRecursion === undefined) maxRecursion = 7;
+  var intersections = [];
+  intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
+  return intersections;
+};
+
+PolynomialBezier.shapeSegment = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
+};
+
+PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
+};
+
+function crossProduct(a, b) {
+  return [
+    a[1] * b[2] - a[2] * b[1],
+    a[2] * b[0] - a[0] * b[2],
+    a[0] * b[1] - a[1] * b[0],
+  ];
+}
+
+function lineIntersection(start1, end1, start2, end2) {
+  var v1 = [start1[0], start1[1], 1];
+  var v2 = [end1[0], end1[1], 1];
+  var v3 = [start2[0], start2[1], 1];
+  var v4 = [end2[0], end2[1], 1];
+
+  var r = crossProduct(
+    crossProduct(v1, v2),
+    crossProduct(v3, v4)
+  );
+
+  if (floatZero(r[2])) return null;
+
+  return [r[0] / r[2], r[1] / r[2]];
+}
+
+function polarOffset(p, angle, length) {
+  return [
+    p[0] + Math.cos(angle) * length,
+    p[1] - Math.sin(angle) * length,
+  ];
+}
+
+function pointDistance(p1, p2) {
+  return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
+}
+
+function pointEqual(p1, p2) {
+  return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
+}
+
+function ZigZagModifier() {}
+extendPrototype([ShapeModifier], ZigZagModifier);
+ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
+  this.frequency = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
+  this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
+};
+
+function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
+  var angO = angle - Math.PI / 2;
+  var angI = angle + Math.PI / 2;
+  var px = point[0] + Math.cos(angle) * direction * amplitude;
+  var py = point[1] - Math.sin(angle) * direction * amplitude;
+
+  outputBezier.setTripleAt(
+    px,
+    py,
+    px + Math.cos(angO) * outAmplitude,
+    py - Math.sin(angO) * outAmplitude,
+    px + Math.cos(angI) * inAmplitude,
+    py - Math.sin(angI) * inAmplitude,
+    outputBezier.length()
+  );
+}
+
+function getPerpendicularVector(pt1, pt2) {
+  var vector = [
+    pt2[0] - pt1[0],
+    pt2[1] - pt1[1],
+  ];
+  var rot = -Math.PI * 0.5;
+  var rotatedVector = [
+    Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1],
+    Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1],
+  ];
+  return rotatedVector;
+}
+
+function getProjectingAngle(path, cur) {
+  var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
+  var nextIndex = (cur + 1) % path.length();
+  var prevPoint = path.v[prevIndex];
+  var nextPoint = path.v[nextIndex];
+  var pVector = getPerpendicularVector(prevPoint, nextPoint);
+  return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
+}
+
+function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
+  var angle = getProjectingAngle(path, cur);
+  var point = path.v[cur % path._length];
+  var prevPoint = path.v[cur === 0 ? path._length - 1 : cur - 1];
+  var nextPoint = path.v[(cur + 1) % path._length];
+  var prevDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - prevPoint[0], 2) + Math.pow(point[1] - prevPoint[1], 2))
+    : 0;
+  var nextDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2))
+    : 0;
+
+  setPoint(
+    outputBezier,
+    path.v[cur % path._length],
+    angle,
+    direction,
+    amplitude,
+    nextDist / ((frequency + 1) * 2),
+    prevDist / ((frequency + 1) * 2),
+    pointType
+  );
+}
+
+function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
+  for (var i = 0; i < frequency; i += 1) {
+    var t = (i + 1) / (frequency + 1);
+
+    var dist = pointType === 2
+      ? Math.sqrt(Math.pow(segment.points[3][0] - segment.points[0][0], 2) + Math.pow(segment.points[3][1] - segment.points[0][1], 2))
+      : 0;
+
+    var angle = segment.normalAngle(t);
+    var point = segment.point(t);
+    setPoint(
+      outputBezier,
+      point,
+      angle,
+      direction,
+      amplitude,
+      dist / ((frequency + 1) * 2),
+      dist / ((frequency + 1) * 2),
+      pointType
+    );
+
+    direction = -direction;
+  }
+
+  return direction;
+}
+
+ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
+  var count = path._length;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+
+  if (!path.c) {
+    count -= 1;
+  }
+
+  if (count === 0) return clonedPath;
+
+  var direction = -1;
+  var segment = PolynomialBezier.shapeSegment(path, 0);
+  zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
+
+  for (var i = 0; i < count; i += 1) {
+    direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
+
+    if (i === count - 1 && !path.c) {
+      segment = null;
+    } else {
+      segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
+    }
+
+    zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
+  }
+
+  return clonedPath;
+};
+
+ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amplitude = this.amplitude.v;
+  var frequency = Math.max(0, Math.round(this.frequency.v));
+  var pointType = this.pointsType.v;
+
+  if (amplitude !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function linearOffset(p1, p2, amount) {
+  var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
+  return [
+    polarOffset(p1, angle, amount),
+    polarOffset(p2, angle, amount),
+  ];
+}
+
+function offsetSegment(segment, amount) {
+  var p0; var p1a; var p1b; var p2b; var p2a; var
+    p3;
+  var e;
+  e = linearOffset(segment.points[0], segment.points[1], amount);
+  p0 = e[0];
+  p1a = e[1];
+  e = linearOffset(segment.points[1], segment.points[2], amount);
+  p1b = e[0];
+  p2b = e[1];
+  e = linearOffset(segment.points[2], segment.points[3], amount);
+  p2a = e[0];
+  p3 = e[1];
+  var p1 = lineIntersection(p0, p1a, p1b, p2b);
+  if (p1 === null) p1 = p1a;
+  var p2 = lineIntersection(p2a, p3, p1b, p2b);
+  if (p2 === null) p2 = p2a;
+
+  return new PolynomialBezier(p0, p1, p2, p3);
+}
+
+function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
+  var p0 = seg1.points[3];
+  var p1 = seg2.points[0];
+
+  // Bevel
+  if (lineJoin === 3) return p0;
+
+  // Connected, they don't need a joint
+  if (pointEqual(p0, p1)) return p0;
+
+  // Round
+  if (lineJoin === 2) {
+    var angleOut = -seg1.tangentAngle(1);
+    var angleIn = -seg2.tangentAngle(0) + Math.PI;
+    var center = lineIntersection(
+      p0,
+      polarOffset(p0, angleOut + Math.PI / 2, 100),
+      p1,
+      polarOffset(p1, angleOut + Math.PI / 2, 100)
+    );
+    var radius = center ? pointDistance(center, p0) : pointDistance(p0, p1) / 2;
+
+    var tan = polarOffset(p0, angleOut, 2 * radius * roundCorner);
+    outputBezier.setXYAt(tan[0], tan[1], 'o', outputBezier.length() - 1);
+
+    tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
+    outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
+
+    return p1;
+  }
+
+  // Miter
+  var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
+  var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
+  var intersection = lineIntersection(t0, p0, p1, t1);
+  if (intersection && pointDistance(intersection, p0) < miterLimit) {
+    outputBezier.setTripleAt(
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      outputBezier.length()
+    );
+    return intersection;
+  }
+
+  return p0;
+}
+
+function getIntersection(a, b) {
+  const intersect = a.intersections(b);
+
+  if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
+
+  if (intersect.length) return intersect[0];
+
+  return null;
+}
+
+function pruneSegmentIntersection(a, b) {
+  var outa = a.slice();
+  var outb = b.slice();
+  var intersect = getIntersection(a[a.length - 1], b[0]);
+  if (intersect) {
+    outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
+    outb[0] = b[0].split(intersect[1])[1];
+  }
+  if (a.length > 1 && b.length > 1) {
+    intersect = getIntersection(a[0], b[b.length - 1]);
+    if (intersect) {
+      return [
+        [a[0].split(intersect[0])[0]],
+        [b[b.length - 1].split(intersect[1])[1]],
+      ];
+    }
+  }
+  return [outa, outb];
+}
+
+function pruneIntersections(segments) {
+  var e;
+  for (var i = 1; i < segments.length; i += 1) {
+    e = pruneSegmentIntersection(segments[i - 1], segments[i]);
+    segments[i - 1] = e[0];
+    segments[i] = e[1];
+  }
+
+  if (segments.length > 1) {
+    e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
+    segments[segments.length - 1] = e[0];
+    segments[0] = e[1];
+  }
+
+  return segments;
+}
+
+function offsetSegmentSplit(segment, amount) {
+  /*
+    We split each bezier segment into smaller pieces based
+    on inflection points, this ensures the control point
+    polygon is convex.
+
+    (A cubic bezier can have none, one, or two inflection points)
+  */
+  var flex = segment.inflectionPoints();
+  var left;
+  var right;
+  var split;
+  var mid;
+
+  if (flex.length === 0) {
+    return [offsetSegment(segment, amount)];
+  }
+
+  if (flex.length === 1 || floatEqual(flex[1], 1)) {
+    split = segment.split(flex[0]);
+    left = split[0];
+    right = split[1];
+
+    return [
+      offsetSegment(left, amount),
+      offsetSegment(right, amount),
+    ];
+  }
+
+  split = segment.split(flex[0]);
+  left = split[0];
+  var t = (flex[1] - flex[0]) / (1 - flex[0]);
+  split = split[1].split(t);
+  mid = split[0];
+  right = split[1];
+
+  return [
+    offsetSegment(left, amount),
+    offsetSegment(mid, amount),
+    offsetSegment(right, amount),
+  ];
+}
+
+function OffsetPathModifier() {}
+
+extendPrototype([ShapeModifier], OffsetPathModifier);
+OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this.miterLimit = PropertyFactory.getProp(elem, data.ml, 0, null, this);
+  this.lineJoin = data.lj;
+  this._isAnimated = this.amount.effectsSequence.length !== 0;
+};
+
+OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
+  var outputBezier = shapePool.newElement();
+  outputBezier.c = inputBezier.c;
+  var count = inputBezier.length();
+  if (!inputBezier.c) {
+    count -= 1;
+  }
+  var i; var j; var segment;
+  var multiSegments = [];
+
+  for (i = 0; i < count; i += 1) {
+    segment = PolynomialBezier.shapeSegment(inputBezier, i);
+    multiSegments.push(offsetSegmentSplit(segment, amount));
+  }
+
+  if (!inputBezier.c) {
+    for (i = count - 1; i >= 0; i -= 1) {
+      segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
+      multiSegments.push(offsetSegmentSplit(segment, amount));
+    }
+  }
+
+  multiSegments = pruneIntersections(multiSegments);
+
+  // Add bezier segments to the output and apply line joints
+  var lastPoint = null;
+  var lastSeg = null;
+
+  for (i = 0; i < multiSegments.length; i += 1) {
+    var multiSegment = multiSegments[i];
+
+    if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
+
+    lastSeg = multiSegment[multiSegment.length - 1];
+
+    for (j = 0; j < multiSegment.length; j += 1) {
+      segment = multiSegment[j];
+
+      if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
+        outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
+      } else {
+        outputBezier.setTripleAt(
+          segment.points[0][0],
+          segment.points[0][1],
+          segment.points[1][0],
+          segment.points[1][1],
+          segment.points[0][0],
+          segment.points[0][1],
+          outputBezier.length()
+        );
+      }
+
+      outputBezier.setTripleAt(
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[2][0],
+        segment.points[2][1],
+        outputBezier.length()
+      );
+
+      lastPoint = segment.points[3];
+    }
+  }
+
+  if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
+
+  return outputBezier;
+};
+
+OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+  var miterLimit = this.miterLimit.v;
+  var lineJoin = this.lineJoin;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function getFontProperties(fontData) {
+  var styles = fontData.fStyle ? fontData.fStyle.split(' ') : [];
+
+  var fWeight = 'normal'; var
+    fStyle = 'normal';
+  var len = styles.length;
+  var styleName;
+  for (var i = 0; i < len; i += 1) {
+    styleName = styles[i].toLowerCase();
+    switch (styleName) {
+      case 'italic':
+        fStyle = 'italic';
+        break;
+      case 'bold':
+        fWeight = '700';
+        break;
+      case 'black':
+        fWeight = '900';
+        break;
+      case 'medium':
+        fWeight = '500';
+        break;
+      case 'regular':
+      case 'normal':
+        fWeight = '400';
+        break;
+      case 'light':
+      case 'thin':
+        fWeight = '200';
+        break;
+      default:
+        break;
+    }
+  }
+
+  return {
+    style: fStyle,
+    weight: fontData.fWeight || fWeight,
+  };
+}
+
+const FontManager = (function () {
+  var maxWaitingTime = 5000;
+  var emptyChar = {
+    w: 0,
+    size: 0,
+    shapes: [],
+    data: {
+      shapes: [],
+    },
+  };
+  var combinedCharacters = [];
+  // Hindi characters
+  combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366,
+    2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379,
+    2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
+
+  var BLACK_FLAG_CODE_POINT = 127988;
+  var CANCEL_TAG_CODE_POINT = 917631;
+  var A_TAG_CODE_POINT = 917601;
+  var Z_TAG_CODE_POINT = 917626;
+  var VARIATION_SELECTOR_16_CODE_POINT = 65039;
+  var ZERO_WIDTH_JOINER_CODE_POINT = 8205;
+  var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
+  var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
+
+  var surrogateModifiers = [
+    'd83cdffb',
+    'd83cdffc',
+    'd83cdffd',
+    'd83cdffe',
+    'd83cdfff',
+  ];
+
+  function trimFontOptions(font) {
+    var familyArray = font.split(',');
+    var i;
+    var len = familyArray.length;
+    var enabledFamilies = [];
+    for (i = 0; i < len; i += 1) {
+      if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
+        enabledFamilies.push(familyArray[i]);
+      }
+    }
+    return enabledFamilies.join(',');
+  }
+
+  function setUpNode(font, family) {
+    var parentNode = createTag('span');
+    // Node is invisible to screen readers.
+    parentNode.setAttribute('aria-hidden', true);
+    parentNode.style.fontFamily = family;
+    var node = createTag('span');
+    // Characters that vary significantly among different fonts
+    node.innerText = 'giItT1WQy@!-/#';
+    // Visible - so we can measure it - but not on the screen
+    parentNode.style.position = 'absolute';
+    parentNode.style.left = '-10000px';
+    parentNode.style.top = '-10000px';
+    // Large font size makes even subtle changes obvious
+    parentNode.style.fontSize = '300px';
+    // Reset any font properties
+    parentNode.style.fontVariant = 'normal';
+    parentNode.style.fontStyle = 'normal';
+    parentNode.style.fontWeight = 'normal';
+    parentNode.style.letterSpacing = '0';
+    parentNode.appendChild(node);
+    document.body.appendChild(parentNode);
+
+    // Remember width with no applied web font
+    var width = node.offsetWidth;
+    node.style.fontFamily = trimFontOptions(font) + ', ' + family;
+    return { node: node, w: width, parent: parentNode };
+  }
+
+  function checkLoadedFonts() {
+    var i;
+    var len = this.fonts.length;
+    var node;
+    var w;
+    var loadedCount = len;
+    for (i = 0; i < len; i += 1) {
+      if (this.fonts[i].loaded) {
+        loadedCount -= 1;
+      } else if (this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0) {
+        this.fonts[i].loaded = true;
+      } else {
+        node = this.fonts[i].monoCase.node;
+        w = this.fonts[i].monoCase.w;
+        if (node.offsetWidth !== w) {
+          loadedCount -= 1;
+          this.fonts[i].loaded = true;
+        } else {
+          node = this.fonts[i].sansCase.node;
+          w = this.fonts[i].sansCase.w;
+          if (node.offsetWidth !== w) {
+            loadedCount -= 1;
+            this.fonts[i].loaded = true;
+          }
+        }
+        if (this.fonts[i].loaded) {
+          this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
+          this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
+        }
+      }
+    }
+
+    if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
+      setTimeout(this.checkLoadedFontsBinded, 20);
+    } else {
+      setTimeout(this.setIsLoadedBinded, 10);
+    }
+  }
+
+  function createHelper(fontData, def) {
+    var engine = (document.body && def) ? 'svg' : 'canvas';
+    var helper;
+    var fontProps = getFontProperties(fontData);
+    if (engine === 'svg') {
+      var tHelper = createNS('text');
+      tHelper.style.fontSize = '100px';
+      // tHelper.style.fontFamily = fontData.fFamily;
+      tHelper.setAttribute('font-family', fontData.fFamily);
+      tHelper.setAttribute('font-style', fontProps.style);
+      tHelper.setAttribute('font-weight', fontProps.weight);
+      tHelper.textContent = '1';
+      if (fontData.fClass) {
+        tHelper.style.fontFamily = 'inherit';
+        tHelper.setAttribute('class', fontData.fClass);
+      } else {
+        tHelper.style.fontFamily = fontData.fFamily;
+      }
+      def.appendChild(tHelper);
+      helper = tHelper;
+    } else {
+      var tCanvasHelper = new OffscreenCanvas(500, 500).getContext('2d');
+      tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
+      helper = tCanvasHelper;
+    }
+    function measure(text) {
+      if (engine === 'svg') {
+        helper.textContent = text;
+        return helper.getComputedTextLength();
+      }
+      return helper.measureText(text).width;
+    }
+    return {
+      measureText: measure,
+    };
+  }
+
+  function addFonts(fontData, defs) {
+    if (!fontData) {
+      this.isLoaded = true;
+      return;
+    }
+    if (this.chars) {
+      this.isLoaded = true;
+      this.fonts = fontData.list;
+      return;
+    }
+    if (!document.body) {
+      this.isLoaded = true;
+      fontData.list.forEach((data) => {
+        data.helper = createHelper(data);
+        data.cache = {};
+      });
+      this.fonts = fontData.list;
+      return;
+    }
+
+    var fontArr = fontData.list;
+    var i;
+    var len = fontArr.length;
+    var _pendingFonts = len;
+    for (i = 0; i < len; i += 1) {
+      var shouldLoadFont = true;
+      var loadedSelector;
+      var j;
+      fontArr[i].loaded = false;
+      fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
+      fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
+      if (!fontArr[i].fPath) {
+        fontArr[i].loaded = true;
+        _pendingFonts -= 1;
+      } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
+        loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
+
+        if (loadedSelector.length > 0) {
+          shouldLoadFont = false;
+        }
+
+        if (shouldLoadFont) {
+          var s = createTag('style');
+          s.setAttribute('f-forigin', fontArr[i].fOrigin);
+          s.setAttribute('f-origin', fontArr[i].origin);
+          s.setAttribute('f-family', fontArr[i].fFamily);
+          s.type = 'text/css';
+          s.innerText = '@font-face {font-family: ' + fontArr[i].fFamily + "; font-style: normal; src: url('" + fontArr[i].fPath + "');}";
+          defs.appendChild(s);
+        }
+      } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
+        loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var l = createTag('link');
+          l.setAttribute('f-forigin', fontArr[i].fOrigin);
+          l.setAttribute('f-origin', fontArr[i].origin);
+          l.type = 'text/css';
+          l.rel = 'stylesheet';
+          l.href = fontArr[i].fPath;
+          document.body.appendChild(l);
+        }
+      } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
+        loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (fontArr[i].fPath === loadedSelector[j].src) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var sc = createTag('link');
+          sc.setAttribute('f-forigin', fontArr[i].fOrigin);
+          sc.setAttribute('f-origin', fontArr[i].origin);
+          sc.setAttribute('rel', 'stylesheet');
+          sc.setAttribute('href', fontArr[i].fPath);
+          defs.appendChild(sc);
+        }
+      }
+      fontArr[i].helper = createHelper(fontArr[i], defs);
+      fontArr[i].cache = {};
+      this.fonts.push(fontArr[i]);
+    }
+    if (_pendingFonts === 0) {
+      this.isLoaded = true;
+    } else {
+      // On some cases even if the font is loaded, it won't load correctly when measuring text on canvas.
+      // Adding this timeout seems to fix it
+      setTimeout(this.checkLoadedFonts.bind(this), 100);
+    }
+  }
+
+  function addChars(chars) {
+    if (!chars) {
+      return;
+    }
+    if (!this.chars) {
+      this.chars = [];
+    }
+    var i;
+    var len = chars.length;
+    var j;
+    var jLen = this.chars.length;
+    var found;
+    for (i = 0; i < len; i += 1) {
+      j = 0;
+      found = false;
+      while (j < jLen) {
+        if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
+          found = true;
+        }
+        j += 1;
+      }
+      if (!found) {
+        this.chars.push(chars[i]);
+        jLen += 1;
+      }
+    }
+  }
+
+  function getCharData(char, style, font) {
+    var i = 0;
+    var len = this.chars.length;
+    while (i < len) {
+      if (this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font) {
+        return this.chars[i];
+      }
+      i += 1;
+    }
+    if (((typeof char === 'string' && char.charCodeAt(0) !== 13) || !char)
+            && console
+            && console.warn // eslint-disable-line no-console
+            && !this._warned
+    ) {
+      this._warned = true;
+      console.warn('Missing character from exported characters list: ', char, style, font); // eslint-disable-line no-console
+    }
+    return emptyChar;
+  }
+
+  function measureText(char, fontName, size) {
+    var fontData = this.getFontByName(fontName);
+    // Using the char instead of char.charCodeAt(0)
+    // to avoid collisions between equal chars
+    var index = char;
+    if (!fontData.cache[index]) {
+      var tHelper = fontData.helper;
+      if (char === ' ') {
+        var doubleSize = tHelper.measureText('|' + char + '|');
+        var singleSize = tHelper.measureText('||');
+        fontData.cache[index] = (doubleSize - singleSize) / 100;
+      } else {
+        fontData.cache[index] = tHelper.measureText(char) / 100;
+      }
+    }
+    return fontData.cache[index] * size;
+  }
+
+  function getFontByName(name) {
+    var i = 0;
+    var len = this.fonts.length;
+    while (i < len) {
+      if (this.fonts[i].fName === name) {
+        return this.fonts[i];
+      }
+      i += 1;
+    }
+    return this.fonts[0];
+  }
+
+  function getCodePoint(string) {
+    var codePoint = 0;
+    var first = string.charCodeAt(0);
+    if (first >= 0xD800 && first <= 0xDBFF) {
+      var second = string.charCodeAt(1);
+      if (second >= 0xDC00 && second <= 0xDFFF) {
+        codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+      }
+    }
+    return codePoint;
+  }
+
+  // Skin tone modifiers
+  function isModifier(firstCharCode, secondCharCode) {
+    var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
+    return surrogateModifiers.indexOf(sum) !== -1;
+  }
+
+  function isZeroWidthJoiner(charCode) {
+    return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
+  }
+
+  // This codepoint may change the appearance of the preceding character.
+  // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
+  // as a colorful image as compared to a monochrome text variant.
+  function isVariationSelector(charCode) {
+    return charCode === VARIATION_SELECTOR_16_CODE_POINT;
+  }
+
+  // The regional indicator symbols are a set of 26 alphabetic Unicode
+  /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
+  // two-letter country codes in a way that allows optional special treatment.
+  function isRegionalCode(string) {
+    var codePoint = getCodePoint(string);
+    if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
+      return true;
+    }
+    return false;
+  }
+
+  // Some Emoji implementations represent combinations of
+  // two “regional indicator” letters as a single flag symbol.
+  function isFlagEmoji(string) {
+    return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
+  }
+
+  function isCombinedCharacter(char) {
+    return combinedCharacters.indexOf(char) !== -1;
+  }
+
+  // Regional flags start with a BLACK_FLAG_CODE_POINT
+  // folowed by 5 chars in the TAG range
+  // and end with a CANCEL_TAG_CODE_POINT
+  function isRegionalFlag(text, index) {
+    var codePoint = getCodePoint(text.substr(index, 2));
+    if (codePoint !== BLACK_FLAG_CODE_POINT) {
+      return false;
+    }
+    var count = 0;
+    index += 2;
+    while (count < 5) {
+      codePoint = getCodePoint(text.substr(index, 2));
+      if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
+        return false;
+      }
+      count += 1;
+      index += 2;
+    }
+    return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
+  }
+
+  function setIsLoaded() {
+    this.isLoaded = true;
+  }
+
+  var Font = function () {
+    this.fonts = [];
+    this.chars = null;
+    this.typekitLoaded = 0;
+    this.isLoaded = false;
+    this._warned = false;
+    this.initTime = Date.now();
+    this.setIsLoadedBinded = this.setIsLoaded.bind(this);
+    this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
+  };
+  Font.isModifier = isModifier;
+  Font.isZeroWidthJoiner = isZeroWidthJoiner;
+  Font.isFlagEmoji = isFlagEmoji;
+  Font.isRegionalCode = isRegionalCode;
+  Font.isCombinedCharacter = isCombinedCharacter;
+  Font.isRegionalFlag = isRegionalFlag;
+  Font.isVariationSelector = isVariationSelector;
+  Font.BLACK_FLAG_CODE_POINT = BLACK_FLAG_CODE_POINT;
+
+  var fontPrototype = {
+    addChars: addChars,
+    addFonts: addFonts,
+    getCharData: getCharData,
+    getFontByName: getFontByName,
+    measureText: measureText,
+    checkLoadedFonts: checkLoadedFonts,
+    setIsLoaded: setIsLoaded,
+  };
+
+  Font.prototype = fontPrototype;
+
+  return Font;
+}());
+
+function SlotManager(animationData) {
+  this.animationData = animationData;
+}
+SlotManager.prototype.getProp = function (data) {
+  if (this.animationData.slots
+    && this.animationData.slots[data.sid]
+  ) {
+    return Object.assign(data, this.animationData.slots[data.sid].p);
+  }
+  return data;
+};
+
+function slotFactory(animationData) {
+  return new SlotManager(animationData);
+}
+
+function RenderableElement() {
+
+}
+
+RenderableElement.prototype = {
+  initRenderable: function () {
+    // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
+    this.isInRange = false;
+    // layer's display state
+    this.hidden = false;
+    // If layer's transparency equals 0, it can be hidden
+    this.isTransparent = false;
+    // list of animated components
+    this.renderableComponents = [];
+  },
+  addRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) === -1) {
+      this.renderableComponents.push(component);
+    }
+  },
+  removeRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) !== -1) {
+      this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1);
+    }
+  },
+  prepareRenderableFrame: function (num) {
+    this.checkLayerLimits(num);
+  },
+  checkTransparency: function () {
+    if (this.finalTransform.mProp.o.v <= 0) {
+      if (!this.isTransparent && this.globalData.renderConfig.hideOnTransparent) {
+        this.isTransparent = true;
+        this.hide();
+      }
+    } else if (this.isTransparent) {
+      this.isTransparent = false;
+      this.show();
+    }
+  },
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     *
+     */
+  checkLayerLimits: function (num) {
+    if (this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) {
+      if (this.isInRange !== true) {
+        this.globalData._mdf = true;
+        this._mdf = true;
+        this.isInRange = true;
+        this.show();
+      }
+    } else if (this.isInRange !== false) {
+      this.globalData._mdf = true;
+      this.isInRange = false;
+      this.hide();
+    }
+  },
+  renderRenderable: function () {
+    var i;
+    var len = this.renderableComponents.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderableComponents[i].renderFrame(this._isFirstFrame);
+    }
+    /* this.maskManager.renderFrame(this.finalTransform.mat);
+        this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
+  },
+  sourceRectAtTime: function () {
+    return {
+      top: 0,
+      left: 0,
+      width: 100,
+      height: 100,
+    };
+  },
+  getLayerSize: function () {
+    if (this.data.ty === 5) {
+      return { w: this.data.textData.width, h: this.data.textData.height };
+    }
+    return { w: this.data.width, h: this.data.height };
+  },
+};
+
+const getBlendMode = (function () {
+  var blendModeEnums = {
+    0: 'source-over',
+    1: 'multiply',
+    2: 'screen',
+    3: 'overlay',
+    4: 'darken',
+    5: 'lighten',
+    6: 'color-dodge',
+    7: 'color-burn',
+    8: 'hard-light',
+    9: 'soft-light',
+    10: 'difference',
+    11: 'exclusion',
+    12: 'hue',
+    13: 'saturation',
+    14: 'color',
+    15: 'luminosity',
+  };
+
+  return function (mode) {
+    return blendModeEnums[mode] || '';
+  };
+}());
+
+function SliderEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function AngleEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function ColorEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function PointEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function LayerIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function MaskIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function CheckboxEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function NoValueEffect() {
+  this.p = {};
+}
+
+function EffectsManager(data, element) {
+  var effects = data.ef || [];
+  this.effectElements = [];
+  var i;
+  var len = effects.length;
+  var effectItem;
+  for (i = 0; i < len; i += 1) {
+    effectItem = new GroupEffect(effects[i], element);
+    this.effectElements.push(effectItem);
+  }
+}
+
+function GroupEffect(data, element) {
+  this.init(data, element);
+}
+
+extendPrototype([DynamicPropertyContainer], GroupEffect);
+
+GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
+
+GroupEffect.prototype.init = function (data, element) {
+  this.data = data;
+  this.effectElements = [];
+  this.initDynamicPropertyContainer(element);
+  var i;
+  var len = this.data.ef.length;
+  var eff;
+  var effects = this.data.ef;
+  for (i = 0; i < len; i += 1) {
+    eff = null;
+    switch (effects[i].ty) {
+      case 0:
+        eff = new SliderEffect(effects[i], element, this);
+        break;
+      case 1:
+        eff = new AngleEffect(effects[i], element, this);
+        break;
+      case 2:
+        eff = new ColorEffect(effects[i], element, this);
+        break;
+      case 3:
+        eff = new PointEffect(effects[i], element, this);
+        break;
+      case 4:
+      case 7:
+        eff = new CheckboxEffect(effects[i], element, this);
+        break;
+      case 10:
+        eff = new LayerIndexEffect(effects[i], element, this);
+        break;
+      case 11:
+        eff = new MaskIndexEffect(effects[i], element, this);
+        break;
+      case 5:
+        eff = new EffectsManager(effects[i], element, this);
+        break;
+        // case 6:
+      default:
+        eff = new NoValueEffect(effects[i], element, this);
+        break;
+    }
+    if (eff) {
+      this.effectElements.push(eff);
+    }
+  }
+};
+
+function BaseElement() {
+}
+
+BaseElement.prototype = {
+  checkMasks: function () {
+    if (!this.data.hasMask) {
+      return false;
+    }
+    var i = 0;
+    var len = this.data.masksProperties.length;
+    while (i < len) {
+      if ((this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false)) {
+        return true;
+      }
+      i += 1;
+    }
+    return false;
+  },
+  initExpressions: function () {
+    const expressionsInterfaces = getExpressionInterfaces();
+    if (!expressionsInterfaces) {
+      return;
+    }
+    const LayerExpressionInterface = expressionsInterfaces('layer');
+    const EffectsExpressionInterface = expressionsInterfaces('effects');
+    const ShapeExpressionInterface = expressionsInterfaces('shape');
+    const TextExpressionInterface = expressionsInterfaces('text');
+    const CompExpressionInterface = expressionsInterfaces('comp');
+    this.layerInterface = LayerExpressionInterface(this);
+    if (this.data.hasMask && this.maskManager) {
+      this.layerInterface.registerMaskInterface(this.maskManager);
+    }
+    var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
+    this.layerInterface.registerEffectsInterface(effectsInterface);
+
+    if (this.data.ty === 0 || this.data.xt) {
+      this.compInterface = CompExpressionInterface(this);
+    } else if (this.data.ty === 4) {
+      this.layerInterface.shapeInterface = ShapeExpressionInterface(this.shapesData, this.itemsData, this.layerInterface);
+      this.layerInterface.content = this.layerInterface.shapeInterface;
+    } else if (this.data.ty === 5) {
+      this.layerInterface.textInterface = TextExpressionInterface(this);
+      this.layerInterface.text = this.layerInterface.textInterface;
+    }
+  },
+  setBlendMode: function () {
+    var blendModeValue = getBlendMode(this.data.bm);
+    var elem = this.baseElement || this.layerElement;
+
+    elem.style['mix-blend-mode'] = blendModeValue;
+  },
+  initBaseData: function (data, globalData, comp) {
+    this.globalData = globalData;
+    this.comp = comp;
+    this.data = data;
+    this.layerId = createElementID();
+
+    // Stretch factor for old animations missing this property.
+    if (!this.data.sr) {
+      this.data.sr = 1;
+    }
+    // effects manager
+    this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
+  },
+  getType: function () {
+    return this.type;
+  },
+  sourceRectAtTime: function () {},
+};
+
+/**
+ * @file
+ * Handles element's layer frame update.
+ * Checks layer in point and out point
+ *
+ */
+
+function FrameElement() {}
+
+FrameElement.prototype = {
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     */
+  initFrame: function () {
+    // set to true when inpoint is rendered
+    this._isFirstFrame = false;
+    // list of animated properties
+    this.dynamicProperties = [];
+    // If layer has been modified in current tick this will be true
+    this._mdf = false;
+  },
+  /**
+     * @function
+     * Calculates all dynamic values
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     * @param {boolean} isVisible
+     * if layers is currently in range
+     *
+     */
+  prepareProperties: function (num, isVisible) {
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      if (isVisible || (this._isParent && this.dynamicProperties[i].propType === 'transform')) {
+        this.dynamicProperties[i].getValue();
+        if (this.dynamicProperties[i]._mdf) {
+          this.globalData._mdf = true;
+          this._mdf = true;
+        }
+      }
+    }
+  },
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+    }
+  },
+};
+
+function FootageElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.footageData = globalData.imageLoader.getAsset(this.assetData);
+  this.initBaseData(data, globalData, comp);
+}
+
+FootageElement.prototype.prepareFrame = function () {
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
+
+FootageElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+FootageElement.prototype.renderFrame = function () {
+};
+
+FootageElement.prototype.destroy = function () {
+};
+
+FootageElement.prototype.initExpressions = function () {
+  const expressionsInterfaces = getExpressionInterfaces();
+  if (!expressionsInterfaces) {
+    return;
+  }
+  const FootageInterface = expressionsInterfaces('footage');
+  this.layerInterface = FootageInterface(this);
+};
+
+FootageElement.prototype.getFootageData = function () {
+  return this.footageData;
+};
+
+function AudioElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initBaseData(data, globalData, comp);
+  this._isPlaying = false;
+  this._canPlay = false;
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  this.audio = this.globalData.audioController.createAudio(assetPath);
+  this._currentTime = 0;
+  this.globalData.audioController.addAudio(this);
+  this._volumeMultiplier = 1;
+  this._volume = 1;
+  this._previousVolume = null;
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+  this.lv = PropertyFactory.getProp(this, data.au && data.au.lv ? data.au.lv : { k: [100] }, 1, 0.01, this);
+}
+
+AudioElement.prototype.prepareFrame = function (num) {
+  this.prepareRenderableFrame(num, true);
+  this.prepareProperties(num, true);
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    this._currentTime = timeRemapped;
+  } else {
+    this._currentTime = num / this.data.sr;
+  }
+  this._volume = this.lv.v[0];
+  var totalVolume = this._volume * this._volumeMultiplier;
+  if (this._previousVolume !== totalVolume) {
+    this._previousVolume = totalVolume;
+    this.audio.volume(totalVolume);
+  }
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
+
+AudioElement.prototype.renderFrame = function () {
+  if (this.isInRange && this._canPlay) {
+    if (!this._isPlaying) {
+      this.audio.play();
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+      this._isPlaying = true;
+    } else if (!this.audio.playing()
+      || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1
+    ) {
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+    }
+  }
+};
+
+AudioElement.prototype.show = function () {
+  // this.audio.play()
+};
+
+AudioElement.prototype.hide = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+};
+
+AudioElement.prototype.pause = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+  this._canPlay = false;
+};
+
+AudioElement.prototype.resume = function () {
+  this._canPlay = true;
+};
+
+AudioElement.prototype.setRate = function (rateValue) {
+  this.audio.rate(rateValue);
+};
+
+AudioElement.prototype.volume = function (volumeValue) {
+  this._volumeMultiplier = volumeValue;
+  this._previousVolume = volumeValue * this._volume;
+  this.audio.volume(this._previousVolume);
+};
+
+AudioElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+AudioElement.prototype.destroy = function () {
+};
+
+AudioElement.prototype.sourceRectAtTime = function () {
+};
+
+AudioElement.prototype.initExpressions = function () {
+};
+
+function BaseRenderer() {}
+BaseRenderer.prototype.checkLayers = function (num) {
+  var i;
+  var len = this.layers.length;
+  var data;
+  this.completeLayers = true;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (!this.elements[i]) {
+      data = this.layers[i];
+      if (data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) {
+        this.buildItem(i);
+      }
+    }
+    this.completeLayers = this.elements[i] ? this.completeLayers : false;
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.createItem = function (layer) {
+  switch (layer.ty) {
+    case 2:
+      return this.createImage(layer);
+    case 0:
+      return this.createComp(layer);
+    case 1:
+      return this.createSolid(layer);
+    case 3:
+      return this.createNull(layer);
+    case 4:
+      return this.createShape(layer);
+    case 5:
+      return this.createText(layer);
+    case 6:
+      return this.createAudio(layer);
+    case 13:
+      return this.createCamera(layer);
+    case 15:
+      return this.createFootage(layer);
+    default:
+      return this.createNull(layer);
+  }
+};
+
+BaseRenderer.prototype.createCamera = function () {
+  throw new Error('You\'re using a 3d camera. Try the html renderer.');
+};
+
+BaseRenderer.prototype.createAudio = function (data) {
+  return new AudioElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.createFootage = function (data) {
+  return new FootageElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.buildAllItems = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    this.buildItem(i);
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.includeLayers = function (newLayers) {
+  this.completeLayers = false;
+  var i;
+  var len = newLayers.length;
+  var j;
+  var jLen = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    j = 0;
+    while (j < jLen) {
+      if (this.layers[j].id === newLayers[i].id) {
+        this.layers[j] = newLayers[i];
+        break;
+      }
+      j += 1;
+    }
+  }
+};
+
+BaseRenderer.prototype.setProjectInterface = function (pInterface) {
+  this.globalData.projectInterface = pInterface;
+};
+
+BaseRenderer.prototype.initItems = function () {
+  if (!this.globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+};
+BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
+  var elements = this.elements;
+  var layers = this.layers;
+  var i = 0;
+  var len = layers.length;
+  while (i < len) {
+    if (layers[i].ind == parentName) { // eslint-disable-line eqeqeq
+      if (!elements[i] || elements[i] === true) {
+        this.buildItem(i);
+        this.addPendingElement(element);
+      } else {
+        hierarchy.push(elements[i]);
+        elements[i].setAsParent();
+        if (layers[i].parent !== undefined) {
+          this.buildElementParenting(element, layers[i].parent, hierarchy);
+        } else {
+          element.setHierarchy(hierarchy);
+        }
+      }
+    }
+    i += 1;
+  }
+};
+
+BaseRenderer.prototype.addPendingElement = function (element) {
+  this.pendingElements.push(element);
+};
+
+BaseRenderer.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var len = assets.length;
+  for (i = 0; i < len; i += 1) {
+    if (assets[i].xt) {
+      var comp = this.createComp(assets[i]);
+      comp.initExpressions();
+      this.globalData.projectInterface.registerComposition(comp);
+    }
+  }
+};
+
+BaseRenderer.prototype.getElementById = function (ind) {
+  var i;
+  var len = this.elements.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i].data.ind === ind) {
+      return this.elements[i];
+    }
+  }
+  return null;
+};
+
+BaseRenderer.prototype.getElementByPath = function (path) {
+  var pathValue = path.shift();
+  var element;
+  if (typeof pathValue === 'number') {
+    element = this.elements[pathValue];
+  } else {
+    var i;
+    var len = this.elements.length;
+    for (i = 0; i < len; i += 1) {
+      if (this.elements[i].data.nm === pathValue) {
+        element = this.elements[i];
+        break;
+      }
+    }
+  }
+  if (path.length === 0) {
+    return element;
+  }
+  return element.getElementByPath(path);
+};
+
+BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
+  this.globalData.fontManager = new FontManager();
+  this.globalData.slotManager = slotFactory(animData);
+  this.globalData.fontManager.addChars(animData.chars);
+  this.globalData.fontManager.addFonts(animData.fonts, fontsContainer);
+  this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+  this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+  this.globalData.imageLoader = this.animationItem.imagePreloader;
+  this.globalData.audioController = this.animationItem.audioController;
+  this.globalData.frameId = 0;
+  this.globalData.frameRate = animData.fr;
+  this.globalData.nm = animData.nm;
+  this.globalData.compSize = {
+    w: animData.w,
+    h: animData.h,
+  };
+};
+
+var effectTypes = {
+  TRANSFORM_EFFECT: 'transformEFfect',
+};
+
+function TransformElement() {}
+
+TransformElement.prototype = {
+  initTransform: function () {
+    var mat = new Matrix();
+    this.finalTransform = {
+      mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : { o: 0 },
+      _matMdf: false,
+      _localMatMdf: false,
+      _opMdf: false,
+      mat: mat,
+      localMat: mat,
+      localOpacity: 1,
+    };
+    if (this.data.ao) {
+      this.finalTransform.mProp.autoOriented = true;
+    }
+
+    // TODO: check TYPE 11: Guided elements
+    if (this.data.ty !== 11) {
+      // this.createElements();
+    }
+  },
+  renderTransform: function () {
+    this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
+    this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
+
+    if (this.hierarchy) {
+      var mat;
+      var finalMat = this.finalTransform.mat;
+      var i = 0;
+      var len = this.hierarchy.length;
+      // Checking if any of the transformation matrices in the hierarchy chain has changed.
+      if (!this.finalTransform._matMdf) {
+        while (i < len) {
+          if (this.hierarchy[i].finalTransform.mProp._mdf) {
+            this.finalTransform._matMdf = true;
+            break;
+          }
+          i += 1;
+        }
+      }
+
+      if (this.finalTransform._matMdf) {
+        mat = this.finalTransform.mProp.v.props;
+        finalMat.cloneFromProps(mat);
+        for (i = 0; i < len; i += 1) {
+          finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
+        }
+      }
+    }
+    if (!this.localTransforms || this.finalTransform._matMdf) {
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+    }
+    if (this.finalTransform._opMdf) {
+      this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderLocalTransform: function () {
+    if (this.localTransforms) {
+      var i = 0;
+      var len = this.localTransforms.length;
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+      if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
+        while (i < len) {
+          if (this.localTransforms[i]._mdf) {
+            this.finalTransform._localMatMdf = true;
+          }
+          if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
+            this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+            this.finalTransform._opMdf = true;
+          }
+          i += 1;
+        }
+      }
+      if (this.finalTransform._localMatMdf) {
+        var localMat = this.finalTransform.localMat;
+        this.localTransforms[0].matrix.clone(localMat);
+        for (i = 1; i < len; i += 1) {
+          var lmat = this.localTransforms[i].matrix;
+          localMat.multiply(lmat);
+        }
+        localMat.multiply(this.finalTransform.mat);
+      }
+      if (this.finalTransform._opMdf) {
+        var localOp = this.finalTransform.localOpacity;
+        for (i = 0; i < len; i += 1) {
+          localOp *= this.localTransforms[i].opacity * 0.01;
+        }
+        this.finalTransform.localOpacity = localOp;
+      }
+    }
+  },
+  searchEffectTransforms: function () {
+    if (this.renderableEffectsManager) {
+      var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+      if (transformEffects.length) {
+        this.localTransforms = [];
+        this.finalTransform.localMat = new Matrix();
+        var i = 0;
+        var len = transformEffects.length;
+        for (i = 0; i < len; i += 1) {
+          this.localTransforms.push(transformEffects[i]);
+        }
+      }
+    }
+  },
+  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;
+    var len = transforms.length;
+    var 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;
+  },
+  mHelper: new Matrix(),
+};
+
+function MaskElement(data, element, globalData) {
+  this.data = data;
+  this.element = element;
+  this.globalData = globalData;
+  this.storedData = [];
+  this.masksProperties = this.data.masksProperties || [];
+  this.maskElement = null;
+  var defs = this.globalData.defs;
+  var i;
+  var len = this.masksProperties ? this.masksProperties.length : 0;
+  this.viewData = createSizedArray(len);
+  this.solidPath = '';
+
+  var path;
+  var properties = this.masksProperties;
+  var count = 0;
+  var currentMasks = [];
+  var j;
+  var jLen;
+  var layerId = createElementID();
+  var rect;
+  var expansor;
+  var feMorph;
+  var x;
+  var maskType = 'clipPath';
+  var maskRef = 'clip-path';
+  for (i = 0; i < len; i += 1) {
+    if ((properties[i].mode !== 'a' && properties[i].mode !== 'n') || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
+      maskType = 'mask';
+      maskRef = 'mask';
+    }
+
+    if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
+      rect = createNS('rect');
+      rect.setAttribute('fill', '#ffffff');
+      rect.setAttribute('width', this.element.comp.data.w || 0);
+      rect.setAttribute('height', this.element.comp.data.h || 0);
+      currentMasks.push(rect);
+    } else {
+      rect = null;
+    }
+
+    path = createNS('path');
+    if (properties[i].mode === 'n') {
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        elem: path,
+        lastPath: '',
+      };
+      defs.appendChild(path);
+    } else {
+      count += 1;
+
+      path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      path.setAttribute('clip-rule', 'nonzero');
+      var filterID;
+
+      if (properties[i].x.k !== 0) {
+        maskType = 'mask';
+        maskRef = 'mask';
+        x = PropertyFactory.getProp(this.element, properties[i].x, 0, null, this.element);
+        filterID = createElementID();
+        expansor = createNS('filter');
+        expansor.setAttribute('id', filterID);
+        feMorph = createNS('feMorphology');
+        feMorph.setAttribute('operator', 'erode');
+        feMorph.setAttribute('in', 'SourceGraphic');
+        feMorph.setAttribute('radius', '0');
+        expansor.appendChild(feMorph);
+        defs.appendChild(expansor);
+        path.setAttribute('stroke', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      } else {
+        feMorph = null;
+        x = null;
+      }
+
+      // TODO move this to a factory or to a constructor
+      this.storedData[i] = {
+        elem: path,
+        x: x,
+        expan: feMorph,
+        lastPath: '',
+        lastOperator: '',
+        filterId: filterID,
+        lastRadius: 0,
+      };
+      if (properties[i].mode === 'i') {
+        jLen = currentMasks.length;
+        var g = createNS('g');
+        for (j = 0; j < jLen; j += 1) {
+          g.appendChild(currentMasks[j]);
+        }
+        var mask = createNS('mask');
+        mask.setAttribute('mask-type', 'alpha');
+        mask.setAttribute('id', layerId + '_' + count);
+        mask.appendChild(path);
+        defs.appendChild(mask);
+        g.setAttribute('mask', 'url(' + getLocationHref() + '#' + layerId + '_' + count + ')');
+
+        currentMasks.length = 0;
+        currentMasks.push(g);
+      } else {
+        currentMasks.push(path);
+      }
+      if (properties[i].inv && !this.solidPath) {
+        this.solidPath = this.createLayerSolidPath();
+      }
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        elem: path,
+        lastPath: '',
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        invRect: rect,
+      };
+      if (!this.viewData[i].prop.k) {
+        this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
+      }
+    }
+  }
+
+  this.maskElement = createNS(maskType);
+
+  len = currentMasks.length;
+  for (i = 0; i < len; i += 1) {
+    this.maskElement.appendChild(currentMasks[i]);
+  }
+
+  if (count > 0) {
+    this.maskElement.setAttribute('id', layerId);
+    this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
+    defs.appendChild(this.maskElement);
+  }
+  if (this.viewData.length) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+MaskElement.prototype.getMaskProperty = function (pos) {
+  return this.viewData[pos].prop;
+};
+
+MaskElement.prototype.renderFrame = function (isFirstFrame) {
+  var finalMat = this.element.finalTransform.mat;
+  var i;
+  var len = this.masksProperties.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.viewData[i].prop._mdf || isFirstFrame) {
+      this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
+    }
+    if (this.viewData[i].op._mdf || isFirstFrame) {
+      this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
+    }
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
+        this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
+      }
+      if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
+        var feMorph = this.storedData[i].expan;
+        if (this.storedData[i].x.v < 0) {
+          if (this.storedData[i].lastOperator !== 'erode') {
+            this.storedData[i].lastOperator = 'erode';
+            this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
+          }
+          feMorph.setAttribute('radius', -this.storedData[i].x.v);
+        } else {
+          if (this.storedData[i].lastOperator !== 'dilate') {
+            this.storedData[i].lastOperator = 'dilate';
+            this.storedData[i].elem.setAttribute('filter', null);
+          }
+          this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
+        }
+      }
+    }
+  }
+};
+
+MaskElement.prototype.getMaskelement = function () {
+  return this.maskElement;
+};
+
+MaskElement.prototype.createLayerSolidPath = function () {
+  var path = 'M0,0 ';
+  path += ' h' + this.globalData.compSize.w;
+  path += ' v' + this.globalData.compSize.h;
+  path += ' h-' + this.globalData.compSize.w;
+  path += ' v-' + this.globalData.compSize.h + ' ';
+  return path;
+};
+
+MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
+  var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  var i;
+  var len;
+  len = pathNodes._length;
+  for (i = 1; i < len; i += 1) {
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
+  }
+  // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+  if (pathNodes.c && len > 1) {
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  }
+  // pathNodes.__renderedString = pathString;
+
+  if (viewData.lastPath !== pathString) {
+    var pathShapeValue = '';
+    if (viewData.elem) {
+      if (pathNodes.c) {
+        pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
+      }
+      viewData.elem.setAttribute('d', pathShapeValue);
+    }
+    viewData.lastPath = pathString;
+  }
+};
+
+MaskElement.prototype.destroy = function () {
+  this.element = null;
+  this.globalData = null;
+  this.maskElement = null;
+  this.data = null;
+  this.masksProperties = null;
+};
+
+const filtersFactory = (function () {
+  var ob = {};
+  ob.createFilter = createFilter;
+  ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
+
+  function createFilter(filId, skipCoordinates) {
+    var fil = createNS('filter');
+    fil.setAttribute('id', filId);
+    if (skipCoordinates !== true) {
+      fil.setAttribute('filterUnits', 'objectBoundingBox');
+      fil.setAttribute('x', '0%');
+      fil.setAttribute('y', '0%');
+      fil.setAttribute('width', '100%');
+      fil.setAttribute('height', '100%');
+    }
+    return fil;
+  }
+
+  function createAlphaToLuminanceFilter() {
+    var feColorMatrix = createNS('feColorMatrix');
+    feColorMatrix.setAttribute('type', 'matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+    feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
+    return feColorMatrix;
+  }
+
+  return ob;
+}());
+
+const featureSupport = (function () {
+  var ob = {
+    maskType: true,
+    svgLumaHidden: true,
+    offscreenCanvas: typeof OffscreenCanvas !== 'undefined',
+  };
+  if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
+    ob.maskType = false;
+  }
+  if (/firefox/i.test(navigator.userAgent)) {
+    ob.svgLumaHidden = false;
+  }
+  return ob;
+}());
+
+var registeredEffects$1 = {};
+var idPrefix = 'filter_result_';
+
+function SVGEffects(elem) {
+  var i;
+  var source = 'SourceGraphic';
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  var filId = createElementID();
+  var fil = filtersFactory.createFilter(filId, true);
+  var count = 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects$1[type]) {
+      var Effect = registeredEffects$1[type].effect;
+      filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
+      source = idPrefix + count;
+      if (registeredEffects$1[type].countsAsEffect) {
+        count += 1;
+      }
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (count) {
+    elem.globalData.defs.appendChild(fil);
+    elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+SVGEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect$1(id, effect, countsAsEffect) {
+  registeredEffects$1[id] = {
+    effect,
+    countsAsEffect,
+  };
+}
+
+function SVGBaseElement() {
+}
+
+SVGBaseElement.prototype = {
+  initRendererElement: function () {
+    this.layerElement = createNS('g');
+  },
+  createContainerElements: function () {
+    this.matteElement = createNS('g');
+    this.transformedElement = this.layerElement;
+    this.maskedElement = this.layerElement;
+    this._sizeChanged = false;
+    var layerElementParent = null;
+    // If this layer acts as a mask for the following layer
+    if (this.data.td) {
+      this.matteMasks = {};
+      var gg = createNS('g');
+      gg.setAttribute('id', this.layerId);
+      gg.appendChild(this.layerElement);
+      layerElementParent = gg;
+      this.globalData.defs.appendChild(gg);
+    } else if (this.data.tt) {
+      this.matteElement.appendChild(this.layerElement);
+      layerElementParent = this.matteElement;
+      this.baseElement = this.matteElement;
+    } else {
+      this.baseElement = this.layerElement;
+    }
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
+    if (this.data.ty === 0 && !this.data.hd) {
+      var cp = createNS('clipPath');
+      var pt = createNS('path');
+      pt.setAttribute('d', 'M0,0 L' + this.data.w + ',0 L' + this.data.w + ',' + this.data.h + ' L0,' + this.data.h + 'z');
+      var clipId = createElementID();
+      cp.setAttribute('id', clipId);
+      cp.appendChild(pt);
+      this.globalData.defs.appendChild(cp);
+
+      if (this.checkMasks()) {
+        var cpGroup = createNS('g');
+        cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+        cpGroup.appendChild(this.layerElement);
+        this.transformedElement = cpGroup;
+        if (layerElementParent) {
+          layerElementParent.appendChild(this.transformedElement);
+        } else {
+          this.baseElement = this.transformedElement;
+        }
+      } else {
+        this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+      }
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    if (this.finalTransform._localMatMdf) {
+      this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
+    }
+    if (this.finalTransform._opMdf) {
+      this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
+    }
+  },
+  destroyBaseElement: function () {
+    this.layerElement = null;
+    this.matteElement = null;
+    this.maskManager.destroy();
+  },
+  getBaseElement: function () {
+    if (this.data.hd) {
+      return null;
+    }
+    return this.baseElement;
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+    this.renderableEffectsManager = new SVGEffects(this);
+    this.searchEffectTransforms();
+  },
+  getMatte: function (matteType) {
+    // This should not be a common case. But for backward compatibility, we'll create the matte object.
+    // It solves animations that have two consecutive layers marked as matte masks.
+    // Which is an undefined behavior in AE.
+    if (!this.matteMasks) {
+      this.matteMasks = {};
+    }
+    if (!this.matteMasks[matteType]) {
+      var id = this.layerId + '_' + matteType;
+      var filId;
+      var fil;
+      var useElement;
+      var gg;
+      if (matteType === 1 || matteType === 3) {
+        var masker = createNS('mask');
+        masker.setAttribute('id', id);
+        masker.setAttribute('mask-type', matteType === 3 ? 'luminance' : 'alpha');
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        masker.appendChild(useElement);
+        this.globalData.defs.appendChild(masker);
+        if (!featureSupport.maskType && matteType === 1) {
+          masker.setAttribute('mask-type', 'luminance');
+          filId = createElementID();
+          fil = filtersFactory.createFilter(filId);
+          this.globalData.defs.appendChild(fil);
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          gg.appendChild(useElement);
+          masker.appendChild(gg);
+          gg.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        }
+      } else if (matteType === 2) {
+        var maskGroup = createNS('mask');
+        maskGroup.setAttribute('id', id);
+        maskGroup.setAttribute('mask-type', 'alpha');
+        var maskGrouper = createNS('g');
+        maskGroup.appendChild(maskGrouper);
+        filId = createElementID();
+        fil = filtersFactory.createFilter(filId);
+        /// /
+        var feCTr = createNS('feComponentTransfer');
+        feCTr.setAttribute('in', 'SourceGraphic');
+        fil.appendChild(feCTr);
+        var feFunc = createNS('feFuncA');
+        feFunc.setAttribute('type', 'table');
+        feFunc.setAttribute('tableValues', '1.0 0.0');
+        feCTr.appendChild(feFunc);
+        /// /
+        this.globalData.defs.appendChild(fil);
+        var alphaRect = createNS('rect');
+        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');
+        alphaRect.setAttribute('opacity', '0');
+        maskGrouper.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        maskGrouper.appendChild(alphaRect);
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        maskGrouper.appendChild(useElement);
+        if (!featureSupport.maskType) {
+          maskGroup.setAttribute('mask-type', 'luminance');
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          maskGrouper.appendChild(alphaRect);
+          gg.appendChild(this.layerElement);
+          maskGrouper.appendChild(gg);
+        }
+        this.globalData.defs.appendChild(maskGroup);
+      }
+      this.matteMasks[matteType] = id;
+    }
+    return this.matteMasks[matteType];
+  },
+  setMatte: function (id) {
+    if (!this.matteElement) {
+      return;
+    }
+    this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+  },
+};
+
+/**
+ * @file
+ * Handles AE's layer parenting property.
+ *
+ */
+
+function HierarchyElement() {}
+
+HierarchyElement.prototype = {
+  /**
+     * @function
+     * Initializes hierarchy properties
+     *
+     */
+  initHierarchy: function () {
+    // element's parent list
+    this.hierarchy = [];
+    // if element is parent of another layer _isParent will be true
+    this._isParent = false;
+    this.checkParenting();
+  },
+  /**
+     * @function
+     * Sets layer's hierarchy.
+     * @param {array} hierarch
+     * layer's parent list
+     *
+     */
+  setHierarchy: function (hierarchy) {
+    this.hierarchy = hierarchy;
+  },
+  /**
+     * @function
+     * Sets layer as parent.
+     *
+     */
+  setAsParent: function () {
+    this._isParent = true;
+  },
+  /**
+     * @function
+     * Searches layer's parenting chain
+     *
+     */
+  checkParenting: function () {
+    if (this.data.parent !== undefined) {
+      this.comp.buildElementParenting(this, this.data.parent, []);
+    }
+  },
+};
+
+function RenderableDOMElement() {}
+
+(function () {
+  var _prototype = {
+    initElement: function (data, globalData, comp) {
+      this.initFrame();
+      this.initBaseData(data, globalData, comp);
+      this.initTransform(data, globalData, comp);
+      this.initHierarchy();
+      this.initRenderable();
+      this.initRendererElement();
+      this.createContainerElements();
+      this.createRenderableComponents();
+      this.createContent();
+      this.hide();
+    },
+    hide: function () {
+      // console.log('HIDE', this);
+      if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+        var elem = this.baseElement || this.layerElement;
+        elem.style.display = 'none';
+        this.hidden = true;
+      }
+    },
+    show: function () {
+      // console.log('SHOW', this);
+      if (this.isInRange && !this.isTransparent) {
+        if (!this.data.hd) {
+          var elem = this.baseElement || this.layerElement;
+          elem.style.display = 'block';
+        }
+        this.hidden = false;
+        this._isFirstFrame = true;
+      }
+    },
+    renderFrame: function () {
+      // If it is exported as hidden (data.hd === true) no need to render
+      // If it is not visible no need to render
+      if (this.data.hd || this.hidden) {
+        return;
+      }
+      this.renderTransform();
+      this.renderRenderable();
+      this.renderLocalTransform();
+      this.renderElement();
+      this.renderInnerContent();
+      if (this._isFirstFrame) {
+        this._isFirstFrame = false;
+      }
+    },
+    renderInnerContent: function () {},
+    prepareFrame: function (num) {
+      this._mdf = false;
+      this.prepareRenderableFrame(num);
+      this.prepareProperties(num, this.isInRange);
+      this.checkTransparency();
+    },
+    destroy: function () {
+      this.innerElem = null;
+      this.destroyBaseElement();
+    },
+  };
+  extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement);
+}());
+
+function IImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  if (this.assetData && this.assetData.sid) {
+    this.assetData = globalData.slotManager.getProp(this.assetData);
+  }
+  this.initElement(data, globalData, comp);
+  this.sourceRect = {
+    top: 0, left: 0, width: this.assetData.w, height: this.assetData.h,
+  };
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
+
+IImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+
+  this.innerElem = createNS('image');
+  this.innerElem.setAttribute('width', this.assetData.w + 'px');
+  this.innerElem.setAttribute('height', this.assetData.h + 'px');
+  this.innerElem.setAttribute('preserveAspectRatio', this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio);
+  this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+
+  this.layerElement.appendChild(this.innerElem);
+};
+
+IImageElement.prototype.sourceRectAtTime = function () {
+  return this.sourceRect;
+};
+
+function ProcessedElement(element, position) {
+  this.elem = element;
+  this.pos = position;
+}
+
+function IShapeElement() {
+}
+
+IShapeElement.prototype = {
+  addShapeToModifiers: function (data) {
+    var i;
+    var len = this.shapeModifiers.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapeModifiers[i].addShape(data);
+    }
+  },
+  isShapeInAnimatedModifiers: function (data) {
+    var i = 0;
+    var len = this.shapeModifiers.length;
+    while (i < len) {
+      if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
+        return true;
+      }
+    }
+    return false;
+  },
+  renderModifiers: function () {
+    if (!this.shapeModifiers.length) {
+      return;
+    }
+    var i;
+    var len = this.shapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].sh.reset();
+    }
+
+    len = this.shapeModifiers.length;
+    var shouldBreakProcess;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+      // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+      // TODO: find a better solution for this
+      if (shouldBreakProcess) {
+        break;
+      }
+    }
+  },
+
+  searchProcessedElement: function (elem) {
+    var elements = this.processedElements;
+    var i = 0;
+    var len = elements.length;
+    while (i < len) {
+      if (elements[i].elem === elem) {
+        return elements[i].pos;
+      }
+      i += 1;
+    }
+    return 0;
+  },
+  addProcessedElement: function (elem, pos) {
+    var elements = this.processedElements;
+    var i = elements.length;
+    while (i) {
+      i -= 1;
+      if (elements[i].elem === elem) {
+        elements[i].pos = pos;
+        return;
+      }
+    }
+    elements.push(new ProcessedElement(elem, pos));
+  },
+  prepareFrame: function (num) {
+    this.prepareRenderableFrame(num);
+    this.prepareProperties(num, this.isInRange);
+  },
+};
+
+const lineCapEnum = {
+  1: 'butt',
+  2: 'round',
+  3: 'square',
+};
+
+const lineJoinEnum = {
+  1: 'miter',
+  2: 'round',
+  3: 'bevel',
+};
+
+function SVGShapeData(transformers, level, shape) {
+  this.caches = [];
+  this.styles = [];
+  this.transformers = transformers;
+  this.lStr = '';
+  this.sh = shape;
+  this.lvl = level;
+  // TODO find if there are some cases where _isAnimated can be false.
+  // For now, since shapes add up with other shapes. They have to be calculated every time.
+  // One way of finding out is checking if all styles associated to this shape depend only of this shape
+  this._isAnimated = !!shape.k;
+  // TODO: commenting this for now since all shapes are animated
+  var i = 0;
+  var len = transformers.length;
+  while (i < len) {
+    if (transformers[i].mProps.dynamicProperties.length) {
+      this._isAnimated = true;
+      break;
+    }
+    i += 1;
+  }
+}
+
+SVGShapeData.prototype.setAsAnimated = function () {
+  this._isAnimated = true;
+};
+
+function SVGStyleData(data, level) {
+  this.data = data;
+  this.type = data.ty;
+  this.d = '';
+  this.lvl = level;
+  this._mdf = false;
+  this.closed = data.hd === true;
+  this.pElem = createNS('path');
+  this.msElem = null;
+}
+
+SVGStyleData.prototype.reset = function () {
+  this.d = '';
+  this._mdf = false;
+};
+
+function DashProperty(elem, data, renderer, container) {
+  this.elem = elem;
+  this.frameId = -1;
+  this.dataProps = createSizedArray(data.length);
+  this.renderer = renderer;
+  this.k = false;
+  this.dashStr = '';
+  this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0);
+  this.dashoffset = createTypedArray('float32', 1);
+  this.initDynamicPropertyContainer(container);
+  var i;
+  var len = data.length || 0;
+  var prop;
+  for (i = 0; i < len; i += 1) {
+    prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
+    this.k = prop.k || this.k;
+    this.dataProps[i] = { n: data[i].n, p: prop };
+  }
+  if (!this.k) {
+    this.getValue(true);
+  }
+  this._isAnimated = this.k;
+}
+
+DashProperty.prototype.getValue = function (forceRender) {
+  if (this.elem.globalData.frameId === this.frameId && !forceRender) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+  this._mdf = this._mdf || forceRender;
+  if (this._mdf) {
+    var i = 0;
+    var len = this.dataProps.length;
+    if (this.renderer === 'svg') {
+      this.dashStr = '';
+    }
+    for (i = 0; i < len; i += 1) {
+      if (this.dataProps[i].n !== 'o') {
+        if (this.renderer === 'svg') {
+          this.dashStr += ' ' + this.dataProps[i].p.v;
+        } else {
+          this.dashArray[i] = this.dataProps[i].p.v;
+        }
+      } else {
+        this.dashoffset[0] = this.dataProps[i].p.v;
+      }
+    }
+  }
+};
+extendPrototype([DynamicPropertyContainer], DashProperty);
+
+function SVGStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
+
+function SVGFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
+
+function SVGNoStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
+
+function GradientProperty(elem, data, container) {
+  this.data = data;
+  this.c = createTypedArray('uint8c', data.p * 4);
+  var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p * 4) : data.k.k.length - data.p * 4;
+  this.o = createTypedArray('float32', cLength);
+  this._cmdf = false;
+  this._omdf = false;
+  this._collapsable = this.checkCollapsable();
+  this._hasOpacity = cLength;
+  this.initDynamicPropertyContainer(container);
+  this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this);
+  this.k = this.prop.k;
+  this.getValue(true);
+}
+
+GradientProperty.prototype.comparePoints = function (values, points) {
+  var i = 0;
+  var len = this.o.length / 2;
+  var diff;
+  while (i < len) {
+    diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
+    if (diff > 0.01) {
+      return false;
+    }
+    i += 1;
+  }
+  return true;
+};
+
+GradientProperty.prototype.checkCollapsable = function () {
+  if (this.o.length / 2 !== this.c.length / 4) {
+    return false;
+  }
+  if (this.data.k.k[0].s) {
+    var i = 0;
+    var len = this.data.k.k.length;
+    while (i < len) {
+      if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
+        return false;
+      }
+      i += 1;
+    }
+  } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
+    return false;
+  }
+  return true;
+};
+
+GradientProperty.prototype.getValue = function (forceRender) {
+  this.prop.getValue();
+  this._mdf = false;
+  this._cmdf = false;
+  this._omdf = false;
+  if (this.prop._mdf || forceRender) {
+    var i;
+    var len = this.data.p * 4;
+    var mult;
+    var val;
+    for (i = 0; i < len; i += 1) {
+      mult = i % 4 === 0 ? 100 : 255;
+      val = Math.round(this.prop.v[i] * mult);
+      if (this.c[i] !== val) {
+        this.c[i] = val;
+        this._cmdf = !forceRender;
+      }
+    }
+    if (this.o.length) {
+      len = this.prop.v.length;
+      for (i = this.data.p * 4; i < len; i += 1) {
+        mult = i % 2 === 0 ? 100 : 1;
+        val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
+        if (this.o[i - this.data.p * 4] !== val) {
+          this.o[i - this.data.p * 4] = val;
+          this._omdf = !forceRender;
+        }
+      }
+    }
+    this._mdf = !forceRender;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], GradientProperty);
+
+function SVGGradientFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.initGradientData(elem, data, styleOb);
+}
+
+SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 1, null, this);
+  this.h = PropertyFactory.getProp(elem, data.h || { k: 0 }, 0, 0.01, this);
+  this.a = PropertyFactory.getProp(elem, data.a || { k: 0 }, 0, degToRads, this);
+  this.g = new GradientProperty(elem, data.g, this);
+  this.style = styleOb;
+  this.stops = [];
+  this.setGradientData(styleOb.pElem, data);
+  this.setGradientOpacity(data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+};
+
+SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
+  var gradientId = createElementID();
+  var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+  gfill.setAttribute('id', gradientId);
+  gfill.setAttribute('spreadMethod', 'pad');
+  gfill.setAttribute('gradientUnits', 'userSpaceOnUse');
+  var stops = [];
+  var stop;
+  var j;
+  var jLen;
+  jLen = data.g.p * 4;
+  for (j = 0; j < jLen; j += 4) {
+    stop = createNS('stop');
+    gfill.appendChild(stop);
+    stops.push(stop);
+  }
+  pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
+  this.gf = gfill;
+  this.cst = stops;
+};
+
+SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
+  if (this.g._hasOpacity && !this.g._collapsable) {
+    var stop;
+    var j;
+    var jLen;
+    var mask = createNS('mask');
+    var maskElement = createNS('path');
+    mask.appendChild(maskElement);
+    var opacityId = createElementID();
+    var maskId = createElementID();
+    mask.setAttribute('id', maskId);
+    var opFill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+    opFill.setAttribute('id', opacityId);
+    opFill.setAttribute('spreadMethod', 'pad');
+    opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
+    jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
+    var stops = this.stops;
+    for (j = data.g.p * 4; j < jLen; j += 2) {
+      stop = createNS('stop');
+      stop.setAttribute('stop-color', 'rgb(255,255,255)');
+      opFill.appendChild(stop);
+      stops.push(stop);
+    }
+    maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
+    this.maskId = maskId;
+    styleOb.msElem = maskElement;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
+
+function SVGGradientStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.initGradientData(elem, data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
+
+function ShapeGroupData() {
+  this.it = [];
+  this.prevViewData = [];
+  this.gr = createNS('g');
+}
+
+function SVGTransformData(mProps, op, container) {
+  this.transform = {
+    mProps: mProps,
+    op: op,
+    container: container,
+  };
+  this.elements = [];
+  this._isAnimated = this.transform.mProps.dynamicProperties.length || this.transform.op.effectsSequence.length;
+}
+
+const buildShapeString = function (pathNodes, length, closed, mat) {
+  if (length === 0) {
+    return '';
+  }
+  var _o = pathNodes.o;
+  var _i = pathNodes.i;
+  var _v = pathNodes.v;
+  var i;
+  var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+  for (i = 1; i < length; i += 1) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
+  }
+  if (closed && length) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+    shapeString += 'z';
+  }
+  return shapeString;
+};
+
+const SVGElementsRenderer = (function () {
+  var _identityMatrix = new Matrix();
+  var _matrixHelper = new Matrix();
+
+  var ob = {
+    createRenderFunction: createRenderFunction,
+  };
+
+  function createRenderFunction(data) {
+    switch (data.ty) {
+      case 'fl':
+        return renderFill;
+      case 'gf':
+        return renderGradient;
+      case 'gs':
+        return renderGradientStroke;
+      case 'st':
+        return renderStroke;
+      case 'sh':
+      case 'el':
+      case 'rc':
+      case 'sr':
+        return renderPath;
+      case 'tr':
+        return renderContentTransform;
+      case 'no':
+        return renderNoop;
+      default:
+        return null;
+    }
+  }
+
+  function renderContentTransform(styleData, itemData, isFirstFrame) {
+    if (isFirstFrame || itemData.transform.op._mdf) {
+      itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
+    }
+    if (isFirstFrame || itemData.transform.mProps._mdf) {
+      itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
+    }
+  }
+
+  function renderNoop() {
+
+  }
+
+  function renderPath(styleData, itemData, isFirstFrame) {
+    var j;
+    var jLen;
+    var pathStringTransformed;
+    var redraw;
+    var pathNodes;
+    var l;
+    var lLen = itemData.styles.length;
+    var lvl = itemData.lvl;
+    var paths;
+    var mat;
+    var iterations;
+    var k;
+    for (l = 0; l < lLen; l += 1) {
+      redraw = itemData.sh._mdf || isFirstFrame;
+      if (itemData.styles[l].lvl < lvl) {
+        mat = _matrixHelper.reset();
+        iterations = lvl - itemData.styles[l].lvl;
+        k = itemData.transformers.length - 1;
+        while (!redraw && iterations > 0) {
+          redraw = itemData.transformers[k].mProps._mdf || redraw;
+          iterations -= 1;
+          k -= 1;
+        }
+        if (redraw) {
+          iterations = lvl - itemData.styles[l].lvl;
+          k = itemData.transformers.length - 1;
+          while (iterations > 0) {
+            mat.multiply(itemData.transformers[k].mProps.v);
+            iterations -= 1;
+            k -= 1;
+          }
+        }
+      } else {
+        mat = _identityMatrix;
+      }
+      paths = itemData.sh.paths;
+      jLen = paths._length;
+      if (redraw) {
+        pathStringTransformed = '';
+        for (j = 0; j < jLen; j += 1) {
+          pathNodes = paths.shapes[j];
+          if (pathNodes && pathNodes._length) {
+            pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
+          }
+        }
+        itemData.caches[l] = pathStringTransformed;
+      } else {
+        pathStringTransformed = itemData.caches[l];
+      }
+      itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
+      itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
+    }
+  }
+
+  function renderFill(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+
+    if (itemData.c._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
+    }
+  }
+
+  function renderGradientStroke(styleData, itemData, isFirstFrame) {
+    renderGradient(styleData, itemData, isFirstFrame);
+    renderStroke(styleData, itemData, isFirstFrame);
+  }
+
+  function renderGradient(styleData, itemData, isFirstFrame) {
+    var gfill = itemData.gf;
+    var hasOpacity = itemData.g._hasOpacity;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+
+    if (itemData.o._mdf || isFirstFrame) {
+      var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
+      itemData.style.pElem.setAttribute(attr, itemData.o.v);
+    }
+    if (itemData.s._mdf || isFirstFrame) {
+      var attr1 = styleData.t === 1 ? 'x1' : 'cx';
+      var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
+      gfill.setAttribute(attr1, pt1[0]);
+      gfill.setAttribute(attr2, pt1[1]);
+      if (hasOpacity && !itemData.g._collapsable) {
+        itemData.of.setAttribute(attr1, pt1[0]);
+        itemData.of.setAttribute(attr2, pt1[1]);
+      }
+    }
+    var stops;
+    var i;
+    var len;
+    var stop;
+    if (itemData.g._cmdf || isFirstFrame) {
+      stops = itemData.cst;
+      var cValues = itemData.g.c;
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        stop.setAttribute('offset', cValues[i * 4] + '%');
+        stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
+      }
+    }
+    if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
+      var oValues = itemData.g.o;
+      if (itemData.g._collapsable) {
+        stops = itemData.cst;
+      } else {
+        stops = itemData.ost;
+      }
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        if (!itemData.g._collapsable) {
+          stop.setAttribute('offset', oValues[i * 2] + '%');
+        }
+        stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
+      }
+    }
+    if (styleData.t === 1) {
+      if (itemData.e._mdf || isFirstFrame) {
+        gfill.setAttribute('x2', pt2[0]);
+        gfill.setAttribute('y2', pt2[1]);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('x2', pt2[0]);
+          itemData.of.setAttribute('y2', pt2[1]);
+        }
+      }
+    } else {
+      var rad;
+      if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
+        rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        gfill.setAttribute('r', rad);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('r', rad);
+        }
+      }
+      if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (!rad) {
+          rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        }
+        var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+        var percent = itemData.h.v;
+        if (percent >= 1) {
+          percent = 0.99;
+        } else if (percent <= -1) {
+          percent = -0.99;
+        }
+        var dist = rad * percent;
+        var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+        var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+        gfill.setAttribute('fx', x);
+        gfill.setAttribute('fy', y);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('fx', x);
+          itemData.of.setAttribute('fy', y);
+        }
+      }
+      // gfill.setAttribute('fy','200');
+    }
+  }
+
+  function renderStroke(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+    var d = itemData.d;
+    if (d && (d._mdf || isFirstFrame) && d.dashStr) {
+      styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
+      styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
+    }
+    if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
+      styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
+    }
+    if (itemData.w._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
+      if (styleElem.msElem) {
+        styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
+      }
+    }
+  }
+
+  return ob;
+}());
+
+function SVGShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
+
+SVGShapeElement.prototype.initSecondaryElement = function () {
+};
+
+SVGShapeElement.prototype.identityMatrix = new Matrix();
+
+SVGShapeElement.prototype.buildExpressionInterface = function () {};
+
+SVGShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+};
+
+/*
+This method searches for multiple shapes that affect a single element and one of them is animated
+*/
+SVGShapeElement.prototype.filterUniqueShapes = function () {
+  var i;
+  var len = this.shapes.length;
+  var shape;
+  var j;
+  var jLen = this.stylesList.length;
+  var style;
+  var tempShapes = [];
+  var areAnimated = false;
+  for (j = 0; j < jLen; j += 1) {
+    style = this.stylesList[j];
+    areAnimated = false;
+    tempShapes.length = 0;
+    for (i = 0; i < len; i += 1) {
+      shape = this.shapes[i];
+      if (shape.styles.indexOf(style) !== -1) {
+        tempShapes.push(shape);
+        areAnimated = shape._isAnimated || areAnimated;
+      }
+    }
+    if (tempShapes.length > 1 && areAnimated) {
+      this.setShapesAsAnimated(tempShapes);
+    }
+  }
+};
+
+SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
+  var i;
+  var len = shapes.length;
+  for (i = 0; i < len; i += 1) {
+    shapes[i].setAsAnimated();
+  }
+};
+
+SVGShapeElement.prototype.createStyleElement = function (data, level) {
+  // TODO: prevent drawing of hidden styles
+  var elementData;
+  var styleOb = new SVGStyleData(data, level);
+
+  var pathElement = styleOb.pElem;
+  if (data.ty === 'st') {
+    elementData = new SVGStrokeStyleData(this, data, styleOb);
+  } else if (data.ty === 'fl') {
+    elementData = new SVGFillStyleData(this, data, styleOb);
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
+    elementData = new GradientConstructor(this, data, styleOb);
+    this.globalData.defs.appendChild(elementData.gf);
+    if (elementData.maskId) {
+      this.globalData.defs.appendChild(elementData.ms);
+      this.globalData.defs.appendChild(elementData.of);
+      pathElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + elementData.maskId + ')');
+    }
+  } else if (data.ty === 'no') {
+    elementData = new SVGNoStyleData(this, data, styleOb);
+  }
+
+  if (data.ty === 'st' || data.ty === 'gs') {
+    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);
+    }
+  }
+
+  if (data.r === 2) {
+    pathElement.setAttribute('fill-rule', 'evenodd');
+  }
+
+  if (data.ln) {
+    pathElement.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    pathElement.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  this.stylesList.push(styleOb);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createGroupElement = function (data) {
+  var elementData = new ShapeGroupData();
+  if (data.ln) {
+    elementData.gr.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    elementData.gr.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  return elementData;
+};
+
+SVGShapeElement.prototype.createTransformElement = function (data, container) {
+  var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
+  var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
+  var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
+  var i = 0;
+  var len = this.animatedContents.length;
+  while (i < len) {
+    if (this.animatedContents[i].element === element) {
+      return;
+    }
+    i += 1;
+  }
+  this.animatedContents.push({
+    fn: SVGElementsRenderer.createRenderFunction(data),
+    element: element,
+    data: data,
+  });
+};
+
+SVGShapeElement.prototype.setElementStyles = function (elementData) {
+  var arr = elementData.styles;
+  var j;
+  var jLen = this.stylesList.length;
+  for (j = 0; j < jLen; j += 1) {
+    if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
+      arr.push(this.stylesList[j]);
+    }
+  }
+};
+
+SVGShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+};
+
+SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
+  var ownTransformers = [].concat(transformers);
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var currentTransform;
+  var modifier;
+  var processedPos;
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._render = render;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], level);
+      } else {
+        itemsData[i].style.closed = arr[i].hd;
+      }
+      if (arr[i]._render) {
+        if (itemsData[i].style.pElem.parentNode !== container) {
+          container.appendChild(itemsData[i].style.pElem);
+        }
+      }
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
+      if (arr[i]._render) {
+        if (itemsData[i].gr.parentNode !== container) {
+          container.appendChild(itemsData[i].gr);
+        }
+      }
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        itemsData[i] = this.createTransformElement(arr[i], container);
+      }
+      currentTransform = itemsData[i].transform;
+      ownTransformers.push(currentTransform);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
+      }
+      this.setElementStyles(itemsData[i]);
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        render = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  len = ownStyles.length;
+  for (i = 0; i < len; i += 1) {
+    ownStyles[i].closed = true;
+  }
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+SVGShapeElement.prototype.renderInnerContent = function () {
+  this.renderModifiers();
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    this.stylesList[i].reset();
+  }
+  this.renderShape();
+  for (i = 0; i < len; i += 1) {
+    if (this.stylesList[i]._mdf || this._isFirstFrame) {
+      if (this.stylesList[i].msElem) {
+        this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+        // Adding M0 0 fixes same mask bug on all browsers
+        this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
+      }
+      this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
+    }
+  }
+};
+
+SVGShapeElement.prototype.renderShape = function () {
+  var i;
+  var len = this.animatedContents.length;
+  var animatedContent;
+  for (i = 0; i < len; i += 1) {
+    animatedContent = this.animatedContents[i];
+    if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
+      animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
+    }
+  }
+};
+
+SVGShapeElement.prototype.destroy = function () {
+  this.destroyBaseElement();
+  this.shapesData = null;
+  this.itemsData = null;
+};
+
+function LetterProps(o, sw, sc, fc, m, p) {
+  this.o = o;
+  this.sw = sw;
+  this.sc = sc;
+  this.fc = fc;
+  this.m = m;
+  this.p = p;
+  this._mdf = {
+    o: true,
+    sw: !!sw,
+    sc: !!sc,
+    fc: !!fc,
+    m: true,
+    p: true,
+  };
+}
+
+LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
+  this._mdf.o = false;
+  this._mdf.sw = false;
+  this._mdf.sc = false;
+  this._mdf.fc = false;
+  this._mdf.m = false;
+  this._mdf.p = false;
+  var updated = false;
+
+  if (this.o !== o) {
+    this.o = o;
+    this._mdf.o = true;
+    updated = true;
+  }
+  if (this.sw !== sw) {
+    this.sw = sw;
+    this._mdf.sw = true;
+    updated = true;
+  }
+  if (this.sc !== sc) {
+    this.sc = sc;
+    this._mdf.sc = true;
+    updated = true;
+  }
+  if (this.fc !== fc) {
+    this.fc = fc;
+    this._mdf.fc = true;
+    updated = true;
+  }
+  if (this.m !== m) {
+    this.m = m;
+    this._mdf.m = true;
+    updated = true;
+  }
+  if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
+    this.p = p;
+    this._mdf.p = true;
+    updated = true;
+  }
+  return updated;
+};
+
+function TextProperty(elem, data) {
+  this._frameId = initialDefaultFrame;
+  this.pv = '';
+  this.v = '';
+  this.kf = false;
+  this._isFirstFrame = true;
+  this._mdf = false;
+  if (data.d && data.d.sid) {
+    data.d = elem.globalData.slotManager.getProp(data.d);
+  }
+  this.data = data;
+  this.elem = elem;
+  this.comp = this.elem.comp;
+  this.keysIndex = 0;
+  this.canResize = false;
+  this.minimumFontSize = 1;
+  this.effectsSequence = [];
+  this.currentData = {
+    ascent: 0,
+    boxWidth: this.defaultBoxWidth,
+    f: '',
+    fStyle: '',
+    fWeight: '',
+    fc: '',
+    j: '',
+    justifyOffset: '',
+    l: [],
+    lh: 0,
+    lineWidths: [],
+    ls: '',
+    of: '',
+    s: '',
+    sc: '',
+    sw: 0,
+    t: 0,
+    tr: 0,
+    sz: 0,
+    ps: null,
+    fillColorAnim: false,
+    strokeColorAnim: false,
+    strokeWidthAnim: false,
+    yOffset: 0,
+    finalSize: 0,
+    finalText: [],
+    finalLineHeight: 0,
+    __complete: false,
+
+  };
+  this.copyData(this.currentData, this.data.d.k[0].s);
+
+  if (!this.searchProperty()) {
+    this.completeTextData(this.currentData);
+  }
+}
+
+TextProperty.prototype.defaultBoxWidth = [0, 0];
+
+TextProperty.prototype.copyData = function (obj, data) {
+  for (var s in data) {
+    if (Object.prototype.hasOwnProperty.call(data, s)) {
+      obj[s] = data[s];
+    }
+  }
+  return obj;
+};
+
+TextProperty.prototype.setCurrentData = function (data) {
+  if (!data.__complete) {
+    this.completeTextData(data);
+  }
+  this.currentData = data;
+  this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
+  this._mdf = true;
+};
+
+TextProperty.prototype.searchProperty = function () {
+  return this.searchKeyframes();
+};
+
+TextProperty.prototype.searchKeyframes = function () {
+  this.kf = this.data.d.k.length > 1;
+  if (this.kf) {
+    this.addEffect(this.getKeyframeValue.bind(this));
+  }
+  return this.kf;
+};
+
+TextProperty.prototype.addEffect = function (effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.getValue = function (_finalValue) {
+  if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
+    return;
+  }
+  this.currentData.t = this.data.d.k[this.keysIndex].s.t;
+  var currentValue = this.currentData;
+  var currentIndex = this.keysIndex;
+  if (this.lock) {
+    this.setCurrentData(this.currentData);
+    return;
+  }
+  this.lock = true;
+  this._mdf = false;
+  var i; var
+    len = this.effectsSequence.length;
+  var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
+  for (i = 0; i < len; i += 1) {
+    // Checking if index changed to prevent creating a new object every time the expression updates.
+    if (currentIndex !== this.keysIndex) {
+      finalValue = this.effectsSequence[i](finalValue, finalValue.t);
+    } else {
+      finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
+    }
+  }
+  if (currentValue !== finalValue) {
+    this.setCurrentData(finalValue);
+  }
+  this.v = this.currentData;
+  this.pv = this.v;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+};
+
+TextProperty.prototype.getKeyframeValue = function () {
+  var textKeys = this.data.d.k;
+  var frameNum = this.elem.comp.renderedFrame;
+  var i = 0; var
+    len = textKeys.length;
+  while (i <= len - 1) {
+    if (i === len - 1 || textKeys[i + 1].t > frameNum) {
+      break;
+    }
+    i += 1;
+  }
+  if (this.keysIndex !== i) {
+    this.keysIndex = i;
+  }
+  return this.data.d.k[this.keysIndex].s;
+};
+
+TextProperty.prototype.buildFinalText = function (text) {
+  var charactersArray = [];
+  var i = 0;
+  var len = text.length;
+  var charCode;
+  var secondCharCode;
+  var shouldCombine = false;
+  var shouldCombineNext = false;
+  var currentChars = '';
+  while (i < len) {
+    shouldCombine = shouldCombineNext;
+    shouldCombineNext = false;
+    charCode = text.charCodeAt(i);
+    currentChars = text.charAt(i);
+    if (FontManager.isCombinedCharacter(charCode)) {
+      shouldCombine = true;
+      // It's a potential surrogate pair (this is the High surrogate)
+    } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+      if (FontManager.isRegionalFlag(text, i)) {
+        currentChars = text.substr(i, 14);
+      } else {
+        secondCharCode = text.charCodeAt(i + 1);
+        // It's a surrogate pair (this is the Low surrogate)
+        if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
+          if (FontManager.isModifier(charCode, secondCharCode)) {
+            currentChars = text.substr(i, 2);
+            shouldCombine = true;
+          } else if (FontManager.isFlagEmoji(text.substr(i, 4))) {
+            currentChars = text.substr(i, 4);
+          } else {
+            currentChars = text.substr(i, 2);
+          }
+        }
+      }
+    } else if (charCode > 0xDBFF) {
+      secondCharCode = text.charCodeAt(i + 1);
+      if (FontManager.isVariationSelector(charCode)) {
+        shouldCombine = true;
+      }
+    } else if (FontManager.isZeroWidthJoiner(charCode)) {
+      shouldCombine = true;
+      shouldCombineNext = true;
+    }
+    if (shouldCombine) {
+      charactersArray[charactersArray.length - 1] += currentChars;
+      shouldCombine = false;
+    } else {
+      charactersArray.push(currentChars);
+    }
+    i += currentChars.length;
+  }
+  return charactersArray;
+};
+
+TextProperty.prototype.completeTextData = function (documentData) {
+  documentData.__complete = true;
+  var fontManager = this.elem.globalData.fontManager;
+  var data = this.data;
+  var letters = [];
+  var i; var
+    len;
+  var newLineFlag; var index = 0; var
+    val;
+  var anchorGrouping = data.m.g;
+  var currentSize = 0; var currentPos = 0; var currentLine = 0; var
+    lineWidths = [];
+  var lineWidth = 0;
+  var maxLineWidth = 0;
+  var j; var
+    jLen;
+  var fontData = fontManager.getFontByName(documentData.f);
+  var charData; var
+    cLength = 0;
+
+  var fontProps = getFontProperties(fontData);
+  documentData.fWeight = fontProps.weight;
+  documentData.fStyle = fontProps.style;
+  documentData.finalSize = documentData.s;
+  documentData.finalText = this.buildFinalText(documentData.t);
+  len = documentData.finalText.length;
+  documentData.finalLineHeight = documentData.lh;
+  var trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+  var charCode;
+  if (documentData.sz) {
+    var flag = true;
+    var boxWidth = documentData.sz[0];
+    var boxHeight = documentData.sz[1];
+    var currentHeight; var
+      finalText;
+    while (flag) {
+      finalText = this.buildFinalText(documentData.t);
+      currentHeight = 0;
+      lineWidth = 0;
+      len = finalText.length;
+      trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+      var lastSpaceIndex = -1;
+      for (i = 0; i < len; i += 1) {
+        charCode = finalText[i].charCodeAt(0);
+        newLineFlag = false;
+        if (finalText[i] === ' ') {
+          lastSpaceIndex = i;
+        } else if (charCode === 13 || charCode === 3) {
+          lineWidth = 0;
+          newLineFlag = true;
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+        }
+        if (fontManager.chars) {
+          charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
+          cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+        } else {
+          // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
+          cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
+        }
+        if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
+          if (lastSpaceIndex === -1) {
+            len += 1;
+          } else {
+            i = lastSpaceIndex;
+          }
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+          finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+          // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
+          lastSpaceIndex = -1;
+          lineWidth = 0;
+        } else {
+          lineWidth += cLength;
+          lineWidth += trackingOffset;
+        }
+      }
+      currentHeight += (fontData.ascent * documentData.finalSize) / 100;
+      if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
+        documentData.finalSize -= 1;
+        documentData.finalLineHeight = (documentData.finalSize * documentData.lh) / documentData.s;
+      } else {
+        documentData.finalText = finalText;
+        len = documentData.finalText.length;
+        flag = false;
+      }
+    }
+  }
+  lineWidth = -trackingOffset;
+  cLength = 0;
+  var uncollapsedSpaces = 0;
+  var currentChar;
+  for (i = 0; i < len; i += 1) {
+    newLineFlag = false;
+    currentChar = documentData.finalText[i];
+    charCode = currentChar.charCodeAt(0);
+    if (charCode === 13 || charCode === 3) {
+      uncollapsedSpaces = 0;
+      lineWidths.push(lineWidth);
+      maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+      lineWidth = -2 * trackingOffset;
+      val = '';
+      newLineFlag = true;
+      currentLine += 1;
+    } else {
+      val = currentChar;
+    }
+    if (fontManager.chars) {
+      charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
+      cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+    } else {
+      // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
+      // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
+      cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
+    }
+
+    //
+    if (currentChar === ' ') {
+      uncollapsedSpaces += cLength + trackingOffset;
+    } else {
+      lineWidth += cLength + trackingOffset + uncollapsedSpaces;
+      uncollapsedSpaces = 0;
+    }
+    letters.push({
+      l: cLength, an: cLength, add: currentSize, n: newLineFlag, anIndexes: [], val: val, line: currentLine, animatorJustifyOffset: 0,
+    });
+    if (anchorGrouping == 2) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || val === ' ' || i === len - 1) {
+        if (val === '' || val === ' ') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        index += 1;
+        currentSize = 0;
+      }
+    } else if (anchorGrouping == 3) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || i === len - 1) {
+        if (val === '') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        currentSize = 0;
+        index += 1;
+      }
+    } else {
+      letters[index].ind = index;
+      letters[index].extra = 0;
+      index += 1;
+    }
+  }
+  documentData.l = letters;
+  maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+  lineWidths.push(lineWidth);
+  if (documentData.sz) {
+    documentData.boxWidth = documentData.sz[0];
+    documentData.justifyOffset = 0;
+  } else {
+    documentData.boxWidth = maxLineWidth;
+    switch (documentData.j) {
+      case 1:
+        documentData.justifyOffset = -documentData.boxWidth;
+        break;
+      case 2:
+        documentData.justifyOffset = -documentData.boxWidth / 2;
+        break;
+      default:
+        documentData.justifyOffset = 0;
+    }
+  }
+  documentData.lineWidths = lineWidths;
+
+  var animators = data.a; var animatorData; var
+    letterData;
+  jLen = animators.length;
+  var based; var ind; var
+    indexes = [];
+  for (j = 0; j < jLen; j += 1) {
+    animatorData = animators[j];
+    if (animatorData.a.sc) {
+      documentData.strokeColorAnim = true;
+    }
+    if (animatorData.a.sw) {
+      documentData.strokeWidthAnim = true;
+    }
+    if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
+      documentData.fillColorAnim = true;
+    }
+    ind = 0;
+    based = animatorData.s.b;
+    for (i = 0; i < len; i += 1) {
+      letterData = letters[i];
+      letterData.anIndexes[j] = ind;
+      if ((based == 1 && letterData.val !== '') || (based == 2 && letterData.val !== '' && letterData.val !== ' ') || (based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1)) || (based == 4 && (letterData.n || i == len - 1))) { // eslint-disable-line eqeqeq
+        if (animatorData.s.rn === 1) {
+          indexes.push(ind);
+        }
+        ind += 1;
+      }
+    }
+    data.a[j].s.totalChars = ind;
+    var currentInd = -1; var
+      newInd;
+    if (animatorData.s.rn === 1) {
+      for (i = 0; i < len; i += 1) {
+        letterData = letters[i];
+        if (currentInd != letterData.anIndexes[j]) { // eslint-disable-line eqeqeq
+          currentInd = letterData.anIndexes[j];
+          newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
+        }
+        letterData.anIndexes[j] = newInd;
+      }
+    }
+  }
+  documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
+  documentData.ls = documentData.ls || 0;
+  documentData.ascent = (fontData.ascent * documentData.finalSize) / 100;
+};
+
+TextProperty.prototype.updateDocumentData = function (newData, index) {
+  index = index === undefined ? this.keysIndex : index;
+  var dData = this.copyData({}, this.data.d.k[index].s);
+  dData = this.copyData(dData, newData);
+  this.data.d.k[index].s = dData;
+  this.recalculate(index);
+  this.setCurrentData(dData);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.recalculate = function (index) {
+  var dData = this.data.d.k[index].s;
+  dData.__complete = false;
+  this.keysIndex = 0;
+  this._isFirstFrame = true;
+  this.getValue(dData);
+};
+
+TextProperty.prototype.canResizeFont = function (_canResize) {
+  this.canResize = _canResize;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
+  this.minimumFontSize = Math.floor(_fontValue) || 1;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+const TextSelectorProp = (function () {
+  var max = Math.max;
+  var min = Math.min;
+  var floor = Math.floor;
+
+  function TextSelectorPropFactory(elem, data) {
+    this._currentTextLength = -1;
+    this.k = false;
+    this.data = data;
+    this.elem = elem;
+    this.comp = elem.comp;
+    this.finalS = 0;
+    this.finalE = 0;
+    this.initDynamicPropertyContainer(elem);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: 0 }, 0, 0, this);
+    if ('e' in data) {
+      this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
+    } else {
+      this.e = { v: 100 };
+    }
+    this.o = PropertyFactory.getProp(elem, data.o || { k: 0 }, 0, 0, this);
+    this.xe = PropertyFactory.getProp(elem, data.xe || { k: 0 }, 0, 0, this);
+    this.ne = PropertyFactory.getProp(elem, data.ne || { k: 0 }, 0, 0, this);
+    this.sm = PropertyFactory.getProp(elem, data.sm || { k: 100 }, 0, 0, this);
+    this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
+    if (!this.dynamicProperties.length) {
+      this.getValue();
+    }
+  }
+
+  TextSelectorPropFactory.prototype = {
+    getMult: function (ind) {
+      if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
+        this.getValue();
+      }
+      var x1 = 0;
+      var y1 = 0;
+      var x2 = 1;
+      var y2 = 1;
+      if (this.ne.v > 0) {
+        x1 = this.ne.v / 100.0;
+      } else {
+        y1 = -this.ne.v / 100.0;
+      }
+      if (this.xe.v > 0) {
+        x2 = 1.0 - this.xe.v / 100.0;
+      } else {
+        y2 = 1.0 + this.xe.v / 100.0;
+      }
+      var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
+
+      var mult = 0;
+      var s = this.finalS;
+      var e = this.finalE;
+      var type = this.data.sh;
+      if (type === 2) {
+        if (e === s) {
+          mult = ind >= e ? 1 : 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+        mult = easer(mult);
+      } else if (type === 3) {
+        if (e === s) {
+          mult = ind >= e ? 0 : 1;
+        } else {
+          mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+
+        mult = easer(mult);
+      } else if (type === 4) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+          if (mult < 0.5) {
+            mult *= 2;
+          } else {
+            mult = 1 - 2 * (mult - 0.5);
+          }
+        }
+        mult = easer(mult);
+      } else if (type === 5) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          var tot = e - s;
+          /* ind += 0.5;
+                    mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          var x = -tot / 2 + ind;
+          var a = tot / 2;
+          mult = Math.sqrt(1 - (x * x) / (a * a));
+        }
+        mult = easer(mult);
+      } else if (type === 6) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; // eslint-disable-line
+        }
+        mult = easer(mult);
+      } else {
+        if (ind >= floor(s)) {
+          if (ind - s < 0) {
+            mult = max(0, min(min(e, 1) - (s - ind), 1));
+          } else {
+            mult = max(0, min(e - ind, 1));
+          }
+        }
+        mult = easer(mult);
+      }
+      // Smoothness implementation.
+      // The smoothness represents a reduced range of the original [0; 1] range.
+      // if smoothness is 25%, the new range will be [0.375; 0.625]
+      // Steps are:
+      // - find the lower value of the new range (threshold)
+      // - if multiplier is smaller than that value, floor it to 0
+      // - if it is larger,
+      //     - subtract the threshold
+      //     - divide it by the smoothness (this will return the range to [0; 1])
+      // Note: If it doesn't work on some scenarios, consider applying it before the easer.
+      if (this.sm.v !== 100) {
+        var smoothness = this.sm.v * 0.01;
+        if (smoothness === 0) {
+          smoothness = 0.00000001;
+        }
+        var threshold = 0.5 - smoothness * 0.5;
+        if (mult < threshold) {
+          mult = 0;
+        } else {
+          mult = (mult - threshold) / smoothness;
+          if (mult > 1) {
+            mult = 1;
+          }
+        }
+      }
+      return mult * this.a.v;
+    },
+    getValue: function (newCharsFlag) {
+      this.iterateDynamicProperties();
+      this._mdf = newCharsFlag || this._mdf;
+      this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
+      if (newCharsFlag && this.data.r === 2) {
+        this.e.v = this._currentTextLength;
+      }
+      var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
+      var o = this.o.v / divisor;
+      var s = this.s.v / divisor + o;
+      var e = (this.e.v / divisor) + o;
+      if (s > e) {
+        var _s = s;
+        s = e;
+        e = _s;
+      }
+      this.finalS = s;
+      this.finalE = e;
+    },
+  };
+  extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
+
+  function getTextSelectorProp(elem, data, arr) {
+    return new TextSelectorPropFactory(elem, data, arr);
+  }
+
+  return {
+    getTextSelectorProp: getTextSelectorProp,
+  };
+}());
+
+function TextAnimatorDataProperty(elem, animatorProps, container) {
+  var defaultData = { propType: false };
+  var getProp = PropertyFactory.getProp;
+  var textAnimatorAnimatables = animatorProps.a;
+  this.a = {
+    r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData,
+    rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData,
+    ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData,
+    sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData,
+    sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData,
+    s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData,
+    a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData,
+    o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData,
+    p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData,
+    sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData,
+    sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData,
+    fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData,
+    fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData,
+    fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData,
+    fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData,
+    t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData,
+  };
+
+  this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container);
+  this.s.t = animatorProps.s.t;
+}
+
+function TextAnimatorProperty(textData, renderType, elem) {
+  this._isFirstFrame = true;
+  this._hasMaskedPath = false;
+  this._frameId = -1;
+  this._textData = textData;
+  this._renderType = renderType;
+  this._elem = elem;
+  this._animatorsData = createSizedArray(this._textData.a.length);
+  this._pathData = {};
+  this._moreOptions = {
+    alignment: {},
+  };
+  this.renderedLetters = [];
+  this.lettersChangedFlag = false;
+  this.initDynamicPropertyContainer(elem);
+}
+
+TextAnimatorProperty.prototype.searchProperties = function () {
+  var i;
+  var len = this._textData.a.length;
+  var animatorProps;
+  var getProp = PropertyFactory.getProp;
+  for (i = 0; i < len; i += 1) {
+    animatorProps = this._textData.a[i];
+    this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
+  }
+  if (this._textData.p && 'm' in this._textData.p) {
+    this._pathData = {
+      a: getProp(this._elem, this._textData.p.a, 0, 0, this),
+      f: getProp(this._elem, this._textData.p.f, 0, 0, this),
+      l: getProp(this._elem, this._textData.p.l, 0, 0, this),
+      r: getProp(this._elem, this._textData.p.r, 0, 0, this),
+      p: getProp(this._elem, this._textData.p.p, 0, 0, this),
+      m: this._elem.maskManager.getMaskProperty(this._textData.p.m),
+    };
+    this._hasMaskedPath = true;
+  } else {
+    this._hasMaskedPath = false;
+  }
+  this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
+};
+
+TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
+  this.lettersChangedFlag = lettersChangedFlag;
+  if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
+    return;
+  }
+  this._isFirstFrame = false;
+  var alignment = this._moreOptions.alignment.v;
+  var animators = this._animatorsData;
+  var textData = this._textData;
+  var matrixHelper = this.mHelper;
+  var renderType = this._renderType;
+  var renderedLettersCount = this.renderedLetters.length;
+  var xPos;
+  var yPos;
+  var i;
+  var len;
+  var letters = documentData.l;
+  var pathInfo;
+  var currentLength;
+  var currentPoint;
+  var segmentLength;
+  var flag;
+  var pointInd;
+  var segmentInd;
+  var prevPoint;
+  var points;
+  var segments;
+  var partialLength;
+  var totalLength;
+  var perc;
+  var tanAngle;
+  var mask;
+  if (this._hasMaskedPath) {
+    mask = this._pathData.m;
+    if (!this._pathData.n || this._pathData._mdf) {
+      var paths = mask.v;
+      if (this._pathData.r.v) {
+        paths = paths.reverse();
+      }
+      // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
+      pathInfo = {
+        tLength: 0,
+        segments: [],
+      };
+      len = paths._length - 1;
+      var bezierData;
+      totalLength = 0;
+      for (i = 0; i < len; i += 1) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[i + 1],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      i = len;
+      if (mask.v.c) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[0],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      this._pathData.pi = pathInfo;
+    }
+    pathInfo = this._pathData.pi;
+
+    currentLength = this._pathData.f.v;
+    segmentInd = 0;
+    pointInd = 1;
+    segmentLength = 0;
+    flag = true;
+    segments = pathInfo.segments;
+    if (currentLength < 0 && mask.v.c) {
+      if (pathInfo.tLength < Math.abs(currentLength)) {
+        currentLength = -Math.abs(currentLength) % pathInfo.tLength;
+      }
+      segmentInd = segments.length - 1;
+      points = segments[segmentInd].points;
+      pointInd = points.length - 1;
+      while (currentLength < 0) {
+        currentLength += points[pointInd].partialLength;
+        pointInd -= 1;
+        if (pointInd < 0) {
+          segmentInd -= 1;
+          points = segments[segmentInd].points;
+          pointInd = points.length - 1;
+        }
+      }
+    }
+    points = segments[segmentInd].points;
+    prevPoint = points[pointInd - 1];
+    currentPoint = points[pointInd];
+    partialLength = currentPoint.partialLength;
+  }
+
+  len = letters.length;
+  xPos = 0;
+  yPos = 0;
+  var yOff = documentData.finalSize * 1.2 * 0.714;
+  var firstLine = true;
+  var animatorProps;
+  var animatorSelector;
+  var j;
+  var jLen;
+  var letterValue;
+
+  jLen = animators.length;
+
+  var mult;
+  var ind = -1;
+  var offf;
+  var xPathPos;
+  var yPathPos;
+  var initPathPos = currentLength;
+  var initSegmentInd = segmentInd;
+  var initPointInd = pointInd;
+  var currentLine = -1;
+  var elemOpacity;
+  var sc;
+  var sw;
+  var fc;
+  var k;
+  var letterSw;
+  var letterSc;
+  var letterFc;
+  var letterM = '';
+  var letterP = this.defaultPropsArray;
+  var letterO;
+
+  //
+  if (documentData.j === 2 || documentData.j === 1) {
+    var animatorJustifyOffset = 0;
+    var animatorFirstCharOffset = 0;
+    var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
+    var lastIndex = 0;
+    var isNewLine = true;
+
+    for (i = 0; i < len; i += 1) {
+      if (letters[i].n) {
+        if (animatorJustifyOffset) {
+          animatorJustifyOffset += animatorFirstCharOffset;
+        }
+        while (lastIndex < i) {
+          letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+          lastIndex += 1;
+        }
+        animatorJustifyOffset = 0;
+        isNewLine = true;
+      } else {
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.t.propType) {
+            if (isNewLine && documentData.j === 2) {
+              animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
+            }
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
+            } else {
+              animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult;
+            }
+          }
+        }
+        isNewLine = false;
+      }
+    }
+    if (animatorJustifyOffset) {
+      animatorJustifyOffset += animatorFirstCharOffset;
+    }
+    while (lastIndex < i) {
+      letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+      lastIndex += 1;
+    }
+  }
+  //
+
+  for (i = 0; i < len; i += 1) {
+    matrixHelper.reset();
+    elemOpacity = 1;
+    if (letters[i].n) {
+      xPos = 0;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      currentLength = initPathPos;
+      firstLine = false;
+      if (this._hasMaskedPath) {
+        segmentInd = initSegmentInd;
+        pointInd = initPointInd;
+        points = segments[segmentInd].points;
+        prevPoint = points[pointInd - 1];
+        currentPoint = points[pointInd];
+        partialLength = currentPoint.partialLength;
+        segmentLength = 0;
+      }
+      letterM = '';
+      letterFc = '';
+      letterSw = '';
+      letterO = '';
+      letterP = this.defaultPropsArray;
+    } else {
+      if (this._hasMaskedPath) {
+        if (currentLine !== letters[i].line) {
+          switch (documentData.j) {
+            case 1:
+              currentLength += totalLength - documentData.lineWidths[letters[i].line];
+              break;
+            case 2:
+              currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
+              break;
+            default:
+              break;
+          }
+          currentLine = letters[i].line;
+        }
+        if (ind !== letters[i].ind) {
+          if (letters[ind]) {
+            currentLength += letters[ind].extra;
+          }
+          currentLength += letters[i].an / 2;
+          ind = letters[i].ind;
+        }
+        currentLength += (alignment[0] * letters[i].an) * 0.005;
+        var animatorOffset = 0;
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.p.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.p.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.p.v[0] * mult;
+            }
+          }
+          if (animatorProps.a.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.a.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.a.v[0] * mult;
+            }
+          }
+        }
+        flag = true;
+        // Force alignment only works with a single line for now
+        if (this._pathData.a.v) {
+          currentLength = letters[0].an * 0.5 + ((totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind) / (len - 1);
+          currentLength += this._pathData.f.v;
+        }
+        while (flag) {
+          if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
+            perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
+            xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
+            yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
+            matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, -(alignment[1] * yOff) * 0.01);
+            flag = false;
+          } else if (points) {
+            segmentLength += currentPoint.partialLength;
+            pointInd += 1;
+            if (pointInd >= points.length) {
+              pointInd = 0;
+              segmentInd += 1;
+              if (!segments[segmentInd]) {
+                if (mask.v.c) {
+                  pointInd = 0;
+                  segmentInd = 0;
+                  points = segments[segmentInd].points;
+                } else {
+                  segmentLength -= currentPoint.partialLength;
+                  points = null;
+                }
+              } else {
+                points = segments[segmentInd].points;
+              }
+            }
+            if (points) {
+              prevPoint = currentPoint;
+              currentPoint = points[pointInd];
+              partialLength = currentPoint.partialLength;
+            }
+          }
+        }
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+      } else {
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+
+        // Grouping alignment
+        matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, (-alignment[1] * yOff) * 0.01, 0);
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.t.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
+          if (xPos !== 0 || documentData.j !== 0) {
+            if (this._hasMaskedPath) {
+              if (mult.length) {
+                currentLength += animatorProps.t.v * mult[0];
+              } else {
+                currentLength += animatorProps.t.v * mult;
+              }
+            } else if (mult.length) {
+              xPos += animatorProps.t.v * mult[0];
+            } else {
+              xPos += animatorProps.t.v * mult;
+            }
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        sw = documentData.sw || 0;
+      }
+      if (documentData.strokeColorAnim) {
+        if (documentData.sc) {
+          sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
+        } else {
+          sc = [0, 0, 0];
+        }
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.a.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+
+          if (mult.length) {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.s.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (mult.length) {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult[0]), 1 + ((animatorProps.s.v[1] - 1) * mult[1]), 1);
+          } else {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult), 1 + ((animatorProps.s.v[1] - 1) * mult), 1);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        animatorSelector = animators[j].s;
+        mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+        if (animatorProps.sk.propType) {
+          if (mult.length) {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
+          } else {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
+          }
+        }
+        if (animatorProps.r.propType) {
+          if (mult.length) {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
+          } else {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult);
+          }
+        }
+        if (animatorProps.ry.propType) {
+          if (mult.length) {
+            matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
+          } else {
+            matrixHelper.rotateY(animatorProps.ry.v * mult);
+          }
+        }
+        if (animatorProps.rx.propType) {
+          if (mult.length) {
+            matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
+          } else {
+            matrixHelper.rotateX(animatorProps.rx.v * mult);
+          }
+        }
+        if (animatorProps.o.propType) {
+          if (mult.length) {
+            elemOpacity += ((animatorProps.o.v) * mult[0] - elemOpacity) * mult[0];
+          } else {
+            elemOpacity += ((animatorProps.o.v) * mult - elemOpacity) * mult;
+          }
+        }
+        if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
+          if (mult.length) {
+            sw += animatorProps.sw.v * mult[0];
+          } else {
+            sw += animatorProps.sw.v * mult;
+          }
+        }
+        if (documentData.strokeColorAnim && animatorProps.sc.propType) {
+          for (k = 0; k < 3; k += 1) {
+            if (mult.length) {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0];
+            } else {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult;
+            }
+          }
+        }
+        if (documentData.fillColorAnim && documentData.fc) {
+          if (animatorProps.fc.propType) {
+            for (k = 0; k < 3; k += 1) {
+              if (mult.length) {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0];
+              } else {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult;
+              }
+            }
+          }
+          if (animatorProps.fh.propType) {
+            if (mult.length) {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
+            } else {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult);
+            }
+          }
+          if (animatorProps.fs.propType) {
+            if (mult.length) {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
+            } else {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
+            }
+          }
+          if (animatorProps.fb.propType) {
+            if (mult.length) {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
+            } else {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult);
+            }
+          }
+        }
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+
+        if (animatorProps.p.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (this._hasMaskedPath) {
+            if (mult.length) {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
+            } else {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+            }
+          } else if (mult.length) {
+            matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        letterSw = sw < 0 ? 0 : sw;
+      }
+      if (documentData.strokeColorAnim) {
+        letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
+      }
+
+      if (this._hasMaskedPath) {
+        matrixHelper.translate(0, -documentData.ls);
+
+        matrixHelper.translate(0, (alignment[1] * yOff) * 0.01 + yPos, 0);
+        if (this._pathData.p.v) {
+          tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
+          var rot = (Math.atan(tanAngle) * 180) / Math.PI;
+          if (currentPoint.point[0] < prevPoint.point[0]) {
+            rot += 180;
+          }
+          matrixHelper.rotate((-rot * Math.PI) / 180);
+        }
+        matrixHelper.translate(xPathPos, yPathPos, 0);
+        currentLength -= (alignment[0] * letters[i].an) * 0.005;
+        if (letters[i + 1] && ind !== letters[i + 1].ind) {
+          currentLength += letters[i].an / 2;
+          currentLength += (documentData.tr * 0.001) * documentData.finalSize;
+        }
+      } else {
+        matrixHelper.translate(xPos, yPos, 0);
+
+        if (documentData.ps) {
+          // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
+          matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+        }
+        switch (documentData.j) {
+          case 1:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
+            break;
+          case 2:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
+            break;
+          default:
+            break;
+        }
+        matrixHelper.translate(0, -documentData.ls);
+        matrixHelper.translate(offf, 0, 0);
+        matrixHelper.translate((alignment[0] * letters[i].an) * 0.005, (alignment[1] * yOff) * 0.01, 0);
+        xPos += letters[i].l + (documentData.tr * 0.001) * documentData.finalSize;
+      }
+      if (renderType === 'html') {
+        letterM = matrixHelper.toCSS();
+      } else if (renderType === 'svg') {
+        letterM = matrixHelper.to2dCSS();
+      } else {
+        letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
+      }
+      letterO = elemOpacity;
+    }
+
+    if (renderedLettersCount <= i) {
+      letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
+      this.renderedLetters.push(letterValue);
+      renderedLettersCount += 1;
+      this.lettersChangedFlag = true;
+    } else {
+      letterValue = this.renderedLetters[i];
+      this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag;
+    }
+  }
+};
+
+TextAnimatorProperty.prototype.getValue = function () {
+  if (this._elem.globalData.frameId === this._frameId) {
+    return;
+  }
+  this._frameId = this._elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+TextAnimatorProperty.prototype.mHelper = new Matrix();
+TextAnimatorProperty.prototype.defaultPropsArray = [];
+extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
+
+function ITextElement() {
+}
+
+ITextElement.prototype.initElement = function (data, globalData, comp) {
+  this.lettersChangedFlag = true;
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.textProperty = new TextProperty(this, data.t, this.dynamicProperties);
+  this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this);
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+  this.initRenderable();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  this.createContent();
+  this.hide();
+  this.textAnimator.searchProperties(this.dynamicProperties);
+};
+
+ITextElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+};
+
+ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
+  var j;
+  var jLen = shapes.length;
+  var pathNodes;
+  var shapeStr = '';
+  for (j = 0; j < jLen; j += 1) {
+    if (shapes[j].ty === 'sh') {
+      pathNodes = shapes[j].ks.k;
+      shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
+    }
+  }
+  return shapeStr;
+};
+
+ITextElement.prototype.updateDocumentData = function (newData, index) {
+  this.textProperty.updateDocumentData(newData, index);
+};
+
+ITextElement.prototype.canResizeFont = function (_canResize) {
+  this.textProperty.canResizeFont(_canResize);
+};
+
+ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
+  this.textProperty.setMinimumFontSize(_fontSize);
+};
+
+ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
+  if (documentData.ps) {
+    matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+  }
+  matrixHelper.translate(0, -documentData.ls, 0);
+  switch (documentData.j) {
+    case 1:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
+      break;
+    case 2:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
+      break;
+    default:
+      break;
+  }
+  matrixHelper.translate(xPos, yPos, 0);
+};
+
+ITextElement.prototype.buildColor = function (colorData) {
+  return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
+};
+
+ITextElement.prototype.emptyProp = new LetterProps();
+
+ITextElement.prototype.destroy = function () {
+
+};
+
+ITextElement.prototype.validateText = function () {
+  if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
+    this.buildNewText();
+    this.textProperty._isFirstFrame = false;
+    this.textProperty._mdf = false;
+  }
+};
+
+var emptyShapeData = {
+  shapes: [],
+};
+
+function SVGTextLottieElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.renderType = 'svg';
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
+
+SVGTextLottieElement.prototype.createContent = function () {
+  if (this.data.singleShape && !this.globalData.fontManager.chars) {
+    this.textContainer = createNS('text');
+  }
+};
+
+SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
+  var i = 0;
+  var len = textArray.length;
+  var textContents = [];
+  var currentTextContent = '';
+  while (i < len) {
+    if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
+      textContents.push(currentTextContent);
+      currentTextContent = '';
+    } else {
+      currentTextContent += textArray[i];
+    }
+    i += 1;
+  }
+  textContents.push(currentTextContent);
+  return textContents;
+};
+
+SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
+  // data should probably be cloned to apply scale separately to each instance of a text on different layers
+  // but since text internal content gets only rendered once and then it's never rerendered,
+  // it's probably safe not to clone data and reuse always the same instance even if the object is mutated.
+  // Avoiding cloning is preferred since cloning each character shape data is expensive
+  if (data.shapes && data.shapes.length) {
+    var shape = data.shapes[0];
+    if (shape.it) {
+      var shapeItem = shape.it[shape.it.length - 1];
+      if (shapeItem.s) {
+        shapeItem.s.k[0] = scale;
+        shapeItem.s.k[1] = scale;
+      }
+    }
+  }
+  return data;
+};
+
+SVGTextLottieElement.prototype.buildNewText = function () {
+  this.addDynamicProperty(this);
+  var i;
+  var len;
+
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
+  if (documentData.fc) {
+    this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
+  } else {
+    this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
+  }
+  if (documentData.sc) {
+    this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
+    this.layerElement.setAttribute('stroke-width', documentData.sw);
+  }
+  this.layerElement.setAttribute('font-size', documentData.finalSize);
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (fontData.fClass) {
+    this.layerElement.setAttribute('class', fontData.fClass);
+  } else {
+    this.layerElement.setAttribute('font-family', fontData.fFamily);
+    var fWeight = documentData.fWeight;
+    var fStyle = documentData.fStyle;
+    this.layerElement.setAttribute('font-style', fStyle);
+    this.layerElement.setAttribute('font-weight', fWeight);
+  }
+  this.layerElement.setAttribute('aria-label', documentData.t);
+
+  var letters = documentData.l || [];
+  var usesGlyphs = !!this.globalData.fontManager.chars;
+  len = letters.length;
+
+  var tSpan;
+  var matrixHelper = this.mHelper;
+  var shapeStr = '';
+  var singleShape = this.data.singleShape;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  if (singleShape && !usesGlyphs && !documentData.sz) {
+    var tElement = this.textContainer;
+    var justify = 'start';
+    switch (documentData.j) {
+      case 1:
+        justify = 'end';
+        break;
+      case 2:
+        justify = 'middle';
+        break;
+      default:
+        justify = 'start';
+        break;
+    }
+    tElement.setAttribute('text-anchor', justify);
+    tElement.setAttribute('letter-spacing', trackingOffset);
+    var textContent = this.buildTextContents(documentData.finalText);
+    len = textContent.length;
+    yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
+    for (i = 0; i < len; i += 1) {
+      tSpan = this.textSpans[i].span || createNS('tspan');
+      tSpan.textContent = textContent[i];
+      tSpan.setAttribute('x', 0);
+      tSpan.setAttribute('y', yPos);
+      tSpan.style.display = 'inherit';
+      tElement.appendChild(tSpan);
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          glyph: null,
+        };
+      }
+      this.textSpans[i].span = tSpan;
+      yPos += documentData.finalLineHeight;
+    }
+
+    this.layerElement.appendChild(tElement);
+  } else {
+    var cachedSpansLength = this.textSpans.length;
+    var charData;
+    for (i = 0; i < len; i += 1) {
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          childSpan: null,
+          glyph: null,
+        };
+      }
+      if (!usesGlyphs || !singleShape || i === 0) {
+        tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
+        if (cachedSpansLength <= i) {
+          tSpan.setAttribute('stroke-linecap', 'butt');
+          tSpan.setAttribute('stroke-linejoin', 'round');
+          tSpan.setAttribute('stroke-miterlimit', '4');
+          this.textSpans[i].span = tSpan;
+          if (usesGlyphs) {
+            var childSpan = createNS('g');
+            tSpan.appendChild(childSpan);
+            this.textSpans[i].childSpan = childSpan;
+          }
+          this.textSpans[i].span = tSpan;
+          this.layerElement.appendChild(tSpan);
+        }
+        tSpan.style.display = 'inherit';
+      }
+
+      matrixHelper.reset();
+      if (singleShape) {
+        if (letters[i].n) {
+          xPos = -trackingOffset;
+          yPos += documentData.yOffset;
+          yPos += firstLine ? 1 : 0;
+          firstLine = false;
+        }
+        this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+        xPos += letters[i].l || 0;
+        // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
+        xPos += trackingOffset;
+      }
+      if (usesGlyphs) {
+        charData = this.globalData.fontManager.getCharData(
+          documentData.finalText[i],
+          fontData.fStyle,
+          this.globalData.fontManager.getFontByName(documentData.f).fFamily
+        );
+        var glyphElement;
+        // t === 1 means the character has been replaced with an animated shaped
+        if (charData.t === 1) {
+          glyphElement = new SVGCompElement(charData.data, this.globalData, this);
+        } else {
+          var data = emptyShapeData;
+          if (charData.data && charData.data.shapes) {
+            data = this.buildShapeData(charData.data, documentData.finalSize);
+          }
+          glyphElement = new SVGShapeElement(data, this.globalData, this);
+        }
+        if (this.textSpans[i].glyph) {
+          var glyph = this.textSpans[i].glyph;
+          this.textSpans[i].childSpan.removeChild(glyph.layerElement);
+          glyph.destroy();
+        }
+        this.textSpans[i].glyph = glyphElement;
+        glyphElement._debug = true;
+        glyphElement.prepareFrame(0);
+        glyphElement.renderFrame();
+        this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+        // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+        // this might have issues with strokes and might need a different solution
+        if (charData.t === 1) {
+          this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
+        }
+      } else {
+        if (singleShape) {
+          tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
+        }
+        tSpan.textContent = letters[i].val;
+        tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      }
+      //
+    }
+    if (singleShape && tSpan) {
+      tSpan.setAttribute('d', shapeStr);
+    }
+  }
+  while (i < this.textSpans.length) {
+    this.textSpans[i].span.style.display = 'none';
+    i += 1;
+  }
+
+  this._sizeChanged = true;
+};
+
+SVGTextLottieElement.prototype.sourceRectAtTime = function () {
+  this.prepareFrame(this.comp.renderedFrame - this.data.st);
+  this.renderInnerContent();
+  if (this._sizeChanged) {
+    this._sizeChanged = false;
+    var textBox = this.layerElement.getBBox();
+    this.bbox = {
+      top: textBox.y,
+      left: textBox.x,
+      width: textBox.width,
+      height: textBox.height,
+    };
+  }
+  return this.bbox;
+};
+
+SVGTextLottieElement.prototype.getValue = function () {
+  var i;
+  var len = this.textSpans.length;
+  var glyphElement;
+  this.renderedFrame = this.comp.renderedFrame;
+  for (i = 0; i < len; i += 1) {
+    glyphElement = this.textSpans[i].glyph;
+    if (glyphElement) {
+      glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
+      if (glyphElement._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+SVGTextLottieElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  if (!this.data.singleShape || this._mdf) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+    if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
+      this._sizeChanged = true;
+      var i;
+      var len;
+      var renderedLetters = this.textAnimator.renderedLetters;
+
+      var letters = this.textProperty.currentData.l;
+
+      len = letters.length;
+      var renderedLetter;
+      var textSpan;
+      var glyphElement;
+      for (i = 0; i < len; i += 1) {
+        if (!letters[i].n) {
+          renderedLetter = renderedLetters[i];
+          textSpan = this.textSpans[i].span;
+          glyphElement = this.textSpans[i].glyph;
+          if (glyphElement) {
+            glyphElement.renderFrame();
+          }
+          if (renderedLetter._mdf.m) {
+            textSpan.setAttribute('transform', renderedLetter.m);
+          }
+          if (renderedLetter._mdf.o) {
+            textSpan.setAttribute('opacity', renderedLetter.o);
+          }
+          if (renderedLetter._mdf.sw) {
+            textSpan.setAttribute('stroke-width', renderedLetter.sw);
+          }
+          if (renderedLetter._mdf.sc) {
+            textSpan.setAttribute('stroke', renderedLetter.sc);
+          }
+          if (renderedLetter._mdf.fc) {
+            textSpan.setAttribute('fill', renderedLetter.fc);
+          }
+        }
+      }
+    }
+  }
+};
+
+function ISolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([IImageElement], ISolidElement);
+
+ISolidElement.prototype.createContent = function () {
+  var rect = createNS('rect');
+  /// /rect.style.width = this.data.sw;
+  /// /rect.style.height = this.data.sh;
+  /// /rect.style.fill = this.data.sc;
+  rect.setAttribute('width', this.data.sw);
+  rect.setAttribute('height', this.data.sh);
+  rect.setAttribute('fill', this.data.sc);
+  this.layerElement.appendChild(rect);
+};
+
+function NullElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initFrame();
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+}
+
+NullElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+NullElement.prototype.renderFrame = function () {
+};
+
+NullElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+NullElement.prototype.destroy = function () {
+};
+
+NullElement.prototype.sourceRectAtTime = function () {
+};
+
+NullElement.prototype.hide = function () {
+};
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
+
+function SVGRendererBase() {
+}
+
+extendPrototype([BaseRenderer], SVGRendererBase);
+
+SVGRendererBase.prototype.createNull = function (data) {
+  return new NullElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createShape = function (data) {
+  return new SVGShapeElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createText = function (data) {
+  return new SVGTextLottieElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createImage = function (data) {
+  return new IImageElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createSolid = function (data) {
+  return new ISolidElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.configAnimation = function (animData) {
+  this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+  this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+  if (this.renderConfig.viewBoxSize) {
+    this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
+  } else {
+    this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
+  }
+
+  if (!this.renderConfig.viewBoxOnly) {
+    this.svgElement.setAttribute('width', animData.w);
+    this.svgElement.setAttribute('height', animData.h);
+    this.svgElement.style.width = '100%';
+    this.svgElement.style.height = '100%';
+    this.svgElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
+  }
+  if (this.renderConfig.width) {
+    this.svgElement.setAttribute('width', this.renderConfig.width);
+  }
+  if (this.renderConfig.height) {
+    this.svgElement.setAttribute('height', this.renderConfig.height);
+  }
+  if (this.renderConfig.className) {
+    this.svgElement.setAttribute('class', this.renderConfig.className);
+  }
+  if (this.renderConfig.id) {
+    this.svgElement.setAttribute('id', this.renderConfig.id);
+  }
+  if (this.renderConfig.focusable !== undefined) {
+    this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
+  }
+  this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+  // this.layerElement.style.transform = 'translate3d(0,0,0)';
+  // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
+  this.animationItem.wrapper.appendChild(this.svgElement);
+  // Mask animation
+  var defs = this.globalData.defs;
+
+  this.setupGlobalData(animData, defs);
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.data = animData;
+
+  var maskElement = createNS('clipPath');
+  var rect = createNS('rect');
+  rect.setAttribute('width', animData.w);
+  rect.setAttribute('height', animData.h);
+  rect.setAttribute('x', 0);
+  rect.setAttribute('y', 0);
+  var maskId = createElementID();
+  maskElement.setAttribute('id', maskId);
+  maskElement.appendChild(rect);
+  this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')');
+
+  defs.appendChild(maskElement);
+  this.layers = animData.layers;
+  this.elements = createSizedArray(animData.layers.length);
+};
+
+SVGRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.layerElement = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+SVGRendererBase.prototype.updateContainerSize = function () {
+};
+
+SVGRendererBase.prototype.findIndexByInd = function (ind) {
+  var i = 0;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.layers[i].ind === ind) {
+      return i;
+    }
+  }
+  return -1;
+};
+
+SVGRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  elements[pos] = true;
+  var element = this.createItem(this.layers[pos]);
+
+  elements[pos] = element;
+  if (getExpressionsPlugin()) {
+    if (this.layers[pos].ty === 0) {
+      this.globalData.projectInterface.registerComposition(element);
+    }
+    element.initExpressions();
+  }
+  this.appendElementInPos(element, pos);
+  if (this.layers[pos].tt) {
+    var elementIndex = ('tp' in this.layers[pos])
+      ? this.findIndexByInd(this.layers[pos].tp)
+      : pos - 1;
+    if (elementIndex === -1) {
+      return;
+    }
+    if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
+      this.buildItem(elementIndex);
+      this.addPendingElement(element);
+    } else {
+      var matteElement = elements[elementIndex];
+      var matteMask = matteElement.getMatte(this.layers[pos].tt);
+      element.setMatte(matteMask);
+    }
+  }
+};
+
+SVGRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+    if (element.data.tt) {
+      var i = 0;
+      var len = this.elements.length;
+      while (i < len) {
+        if (this.elements[i] === element) {
+          var elementIndex = 'tp' in element.data
+            ? this.findIndexByInd(element.data.tp)
+            : i - 1;
+          var matteElement = this.elements[elementIndex];
+          var matteMask = matteElement.getMatte(this.layers[i].tt);
+          element.setMatte(matteMask);
+          break;
+        }
+        i += 1;
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.renderFrame = function (num) {
+  if (this.renderedFrame === num || this.destroyed) {
+    return;
+  }
+  if (num === null) {
+    num = this.renderedFrame;
+  } else {
+    this.renderedFrame = num;
+  }
+  // console.log('-------');
+  // console.log('FRAME ',num);
+  this.globalData.frameNum = num;
+  this.globalData.frameId += 1;
+  this.globalData.projectInterface.currentFrame = num;
+  this.globalData._mdf = false;
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    for (i = 0; i < len; i += 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
+  var newElement = element.getBaseElement();
+  if (!newElement) {
+    return;
+  }
+  var i = 0;
+  var nextElement;
+  while (i < pos) {
+    if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
+      nextElement = this.elements[i].getBaseElement();
+    }
+    i += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(newElement, nextElement);
+  } else {
+    this.layerElement.appendChild(newElement);
+  }
+};
+
+SVGRendererBase.prototype.hide = function () {
+  this.layerElement.style.display = 'none';
+};
+
+SVGRendererBase.prototype.show = function () {
+  this.layerElement.style.display = 'block';
+};
+
+function ICompElement() {}
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
+
+ICompElement.prototype.initElement = function (data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initTransform(data, globalData, comp);
+  this.initRenderable();
+  this.initHierarchy();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  if (this.data.xt || !globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+  this.hide();
+};
+
+/* ICompElement.prototype.hide = function(){
+    if(!this.hidden){
+        this.hideElement();
+        var i,len = this.elements.length;
+        for( i = 0; i < len; i+=1 ){
+            if(this.elements[i]){
+                this.elements[i].hide();
+            }
+        }
+    }
+}; */
+
+ICompElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+  if (!this.isInRange && !this.data.xt) {
+    return;
+  }
+
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    if (timeRemapped === this.data.op) {
+      timeRemapped = this.data.op - 1;
+    }
+    this.renderedFrame = timeRemapped;
+  } else {
+    this.renderedFrame = num / this.data.sr;
+  }
+  var i;
+  var len = this.elements.length;
+  if (!this.completeLayers) {
+    this.checkLayers(this.renderedFrame);
+  }
+  // This iteration needs to be backwards because of how expressions connect between each other
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
+      if (this.elements[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+ICompElement.prototype.renderInnerContent = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+ICompElement.prototype.setElements = function (elems) {
+  this.elements = elems;
+};
+
+ICompElement.prototype.getElements = function () {
+  return this.elements;
+};
+
+ICompElement.prototype.destroyElements = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+};
+
+ICompElement.prototype.destroy = function () {
+  this.destroyElements();
+  this.destroyBaseElement();
+};
+
+function SVGCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = true;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
+
+SVGCompElement.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function SVGRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.layers = null;
+  this.renderedFrame = -1;
+  this.svgElement = createNS('svg');
+  var ariaLabel = '';
+  if (config && config.title) {
+    var titleElement = createNS('title');
+    var titleId = createElementID();
+    titleElement.setAttribute('id', titleId);
+    titleElement.textContent = config.title;
+    this.svgElement.appendChild(titleElement);
+    ariaLabel += titleId;
+  }
+  if (config && config.description) {
+    var descElement = createNS('desc');
+    var descId = createElementID();
+    descElement.setAttribute('id', descId);
+    descElement.textContent = config.description;
+    this.svgElement.appendChild(descElement);
+    ariaLabel += ' ' + descId;
+  }
+  if (ariaLabel) {
+    this.svgElement.setAttribute('aria-labelledby', ariaLabel);
+  }
+  var defs = createNS('defs');
+  this.svgElement.appendChild(defs);
+  var maskElement = createNS('g');
+  this.svgElement.appendChild(maskElement);
+  this.layerElement = maskElement;
+  this.renderConfig = {
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    hideOnTransparent: !((config && config.hideOnTransparent === false)),
+    viewBoxOnly: (config && config.viewBoxOnly) || false,
+    viewBoxSize: (config && config.viewBoxSize) || false,
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    focusable: config && config.focusable,
+    filterSize: {
+      width: (config && config.filterSize && config.filterSize.width) || '100%',
+      height: (config && config.filterSize && config.filterSize.height) || '100%',
+      x: (config && config.filterSize && config.filterSize.x) || '0%',
+      y: (config && config.filterSize && config.filterSize.y) || '0%',
+    },
+    width: (config && config.width),
+    height: (config && config.height),
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+
+  this.globalData = {
+    _mdf: false,
+    frameNum: -1,
+    defs: defs,
+    renderConfig: this.renderConfig,
+  };
+  this.elements = [];
+  this.pendingElements = [];
+  this.destroyed = false;
+  this.rendererType = 'svg';
+}
+
+extendPrototype([SVGRendererBase], SVGRenderer);
+
+SVGRenderer.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function ShapeTransformManager() {
+  this.sequences = {};
+  this.sequenceList = [];
+  this.transform_key_count = 0;
+}
+
+ShapeTransformManager.prototype = {
+  addTransformSequence: function (transforms) {
+    var i;
+    var len = transforms.length;
+    var key = '_';
+    for (i = 0; i < len; i += 1) {
+      key += transforms[i].transform.key + '_';
+    }
+    var sequence = this.sequences[key];
+    if (!sequence) {
+      sequence = {
+        transforms: [].concat(transforms),
+        finalTransform: new Matrix(),
+        _mdf: false,
+      };
+      this.sequences[key] = sequence;
+      this.sequenceList.push(sequence);
+    }
+    return sequence;
+  },
+  processSequence: function (sequence, isFirstFrame) {
+    var i = 0;
+    var len = sequence.transforms.length;
+    var _mdf = isFirstFrame;
+    while (i < len && !isFirstFrame) {
+      if (sequence.transforms[i].transform.mProps._mdf) {
+        _mdf = true;
+        break;
+      }
+      i += 1;
+    }
+    if (_mdf) {
+      sequence.finalTransform.reset();
+      for (i = len - 1; i >= 0; i -= 1) {
+        sequence.finalTransform.multiply(sequence.transforms[i].transform.mProps.v);
+      }
+    }
+    sequence._mdf = _mdf;
+  },
+  processSequences: function (isFirstFrame) {
+    var i;
+    var len = this.sequenceList.length;
+    for (i = 0; i < len; i += 1) {
+      this.processSequence(this.sequenceList[i], isFirstFrame);
+    }
+  },
+  getNewKey: function () {
+    this.transform_key_count += 1;
+    return '_' + this.transform_key_count;
+  },
+};
+
+var lumaLoader = (function () {
+  var id = '__lottie_element_luma_buffer';
+  var lumaBuffer = null;
+  var lumaBufferCtx = null;
+  var svg = null;
+
+  // This alternate solution has a slight delay before the filter is applied, resulting in a flicker on the first frame.
+  // Keeping this here for reference, and in the future, if offscreen canvas supports url filters, this can be used.
+  // For now, neither of them work for offscreen canvas, so canvas workers can't support the luma track matte mask.
+  // Naming it solution 2 to mark the extra comment lines.
+  /*
+  var svgString = [
+    '<svg xmlns="http://www.w3.org/2000/svg">',
+    '<filter id="' + id + '">',
+    '<feColorMatrix type="matrix" color-interpolation-filters="sRGB" values="',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0',
+    '"/>',
+    '</filter>',
+    '</svg>',
+  ].join('');
+  var blob = new Blob([svgString], { type: 'image/svg+xml' });
+  var url = URL.createObjectURL(blob);
+  */
+
+  function createLumaSvgFilter() {
+    var _svg = createNS('svg');
+    var fil = createNS('filter');
+    var matrix = createNS('feColorMatrix');
+    fil.setAttribute('id', id);
+    matrix.setAttribute('type', 'matrix');
+    matrix.setAttribute('color-interpolation-filters', 'sRGB');
+    matrix.setAttribute('values', '0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0');
+    fil.appendChild(matrix);
+    _svg.appendChild(fil);
+    _svg.setAttribute('id', id + '_svg');
+    if (featureSupport.svgLumaHidden) {
+      _svg.style.display = 'none';
+    }
+    return _svg;
+  }
+
+  function loadLuma() {
+    if (!lumaBuffer) {
+      svg = createLumaSvgFilter();
+      document.body.appendChild(svg);
+      lumaBuffer = createTag('canvas');
+      lumaBufferCtx = lumaBuffer.getContext('2d');
+      // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
+      lumaBufferCtx.filter = 'url(#' + id + ')';
+      lumaBufferCtx.fillStyle = 'rgba(0,0,0,0)';
+      lumaBufferCtx.fillRect(0, 0, 1, 1);
+    }
+  }
+
+  function getLuma(canvas) {
+    if (!lumaBuffer) {
+      loadLuma();
+    }
+    lumaBuffer.width = canvas.width;
+    lumaBuffer.height = canvas.height;
+    // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
+    lumaBufferCtx.filter = 'url(#' + id + ')';
+    return lumaBuffer;
+  }
+  return {
+    load: loadLuma,
+    get: getLuma,
+  };
+});
+
+function createCanvas(width, height) {
+  if (featureSupport.offscreenCanvas) {
+    return new OffscreenCanvas(width, height);
+  }
+  var canvas = createTag('canvas');
+  canvas.width = width;
+  canvas.height = height;
+  return canvas;
+}
+
+const assetLoader = (function () {
+  return {
+    loadLumaCanvas: lumaLoader.load,
+    getLumaCanvas: lumaLoader.get,
+    createCanvas: createCanvas,
+  };
+}());
+
+var registeredEffects = {};
+
+function CVEffects(elem) {
+  var i;
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects[type]) {
+      var Effect = registeredEffects[type].effect;
+      filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+CVEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+CVEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect(id, effect) {
+  registeredEffects[id] = {
+    effect,
+  };
+}
+
+function CVMaskElement(data, element) {
+  this.data = data;
+  this.element = element;
+  this.masksProperties = this.data.masksProperties || [];
+  this.viewData = createSizedArray(this.masksProperties.length);
+  var i;
+  var len = this.masksProperties.length;
+  var hasMasks = false;
+  for (i = 0; i < len; i += 1) {
+    if (this.masksProperties[i].mode !== 'n') {
+      hasMasks = true;
+    }
+    this.viewData[i] = ShapePropertyFactory.getShapeProp(this.element, this.masksProperties[i], 3);
+  }
+  this.hasMasks = hasMasks;
+  if (hasMasks) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+CVMaskElement.prototype.renderFrame = function () {
+  if (!this.hasMasks) {
+    return;
+  }
+  var transform = this.element.finalTransform.mat;
+  var ctx = this.element.canvasContext;
+  var i;
+  var len = this.masksProperties.length;
+  var pt;
+  var pts;
+  var data;
+  ctx.beginPath();
+  for (i = 0; i < len; i += 1) {
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.masksProperties[i].inv) {
+        ctx.moveTo(0, 0);
+        ctx.lineTo(this.element.globalData.compSize.w, 0);
+        ctx.lineTo(this.element.globalData.compSize.w, this.element.globalData.compSize.h);
+        ctx.lineTo(0, this.element.globalData.compSize.h);
+        ctx.lineTo(0, 0);
+      }
+      data = this.viewData[i].v;
+      pt = transform.applyToPointArray(data.v[0][0], data.v[0][1], 0);
+      ctx.moveTo(pt[0], pt[1]);
+      var j;
+      var jLen = data._length;
+      for (j = 1; j < jLen; j += 1) {
+        pts = transform.applyToTriplePoints(data.o[j - 1], data.i[j], data.v[j]);
+        ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
+      }
+      pts = transform.applyToTriplePoints(data.o[j - 1], data.i[0], data.v[0]);
+      ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
+    }
+  }
+  this.element.globalData.renderer.save(true);
+  ctx.clip();
+};
+
+CVMaskElement.prototype.getMaskProperty = MaskElement.prototype.getMaskProperty;
+
+CVMaskElement.prototype.destroy = function () {
+  this.element = null;
+};
+
+function CVBaseElement() {
+}
+
+var operationsMap = {
+  1: 'source-in',
+  2: 'source-out',
+  3: 'source-in',
+  4: 'source-out',
+};
+
+CVBaseElement.prototype = {
+  createElements: function () {},
+  initRendererElement: function () {},
+  createContainerElements: function () {
+    // If the layer is masked we will use two buffers to store each different states of the drawing
+    // This solution is not ideal for several reason. But unfortunately, because of the recursive
+    // nature of the render tree, it's the only simple way to make sure one inner mask doesn't override an outer mask.
+    // TODO: try to reduce the size of these buffers to the size of the composition contaning the layer
+    // It might be challenging because the layer most likely is transformed in some way
+    if (this.data.tt >= 1) {
+      this.buffers = [];
+      var canvasContext = this.globalData.canvasContext;
+      var bufferCanvas = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
+      this.buffers.push(bufferCanvas);
+      var bufferCanvas2 = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
+      this.buffers.push(bufferCanvas2);
+      if (this.data.tt >= 3 && !document._isProxy) {
+        assetLoader.loadLumaCanvas();
+      }
+    }
+    this.canvasContext = this.globalData.canvasContext;
+    this.transformCanvas = this.globalData.transformCanvas;
+    this.renderableEffectsManager = new CVEffects(this);
+    this.searchEffectTransforms();
+  },
+  createContent: function () {},
+  setBlendMode: function () {
+    var globalData = this.globalData;
+    if (globalData.blendMode !== this.data.bm) {
+      globalData.blendMode = this.data.bm;
+      var blendModeValue = getBlendMode(this.data.bm);
+      globalData.canvasContext.globalCompositeOperation = blendModeValue;
+    }
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new CVMaskElement(this.data, this);
+    this.transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+  },
+  hideElement: function () {
+    if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+      this.hidden = true;
+    }
+  },
+  showElement: function () {
+    if (this.isInRange && !this.isTransparent) {
+      this.hidden = false;
+      this._isFirstFrame = true;
+      this.maskManager._isFirstFrame = true;
+    }
+  },
+  clearCanvas: function (canvasContext) {
+    canvasContext.clearRect(
+      this.transformCanvas.tx,
+      this.transformCanvas.ty,
+      this.transformCanvas.w * this.transformCanvas.sx,
+      this.transformCanvas.h * this.transformCanvas.sy
+    );
+  },
+  prepareLayer: function () {
+    if (this.data.tt >= 1) {
+      var buffer = this.buffers[0];
+      var bufferCtx = buffer.getContext('2d');
+      this.clearCanvas(bufferCtx);
+      // on the first buffer we store the current state of the global drawing
+      bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+      // The next four lines are to clear the canvas
+      // TODO: Check if there is a way to clear the canvas without resetting the transform
+      this.currentTransform = this.canvasContext.getTransform();
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+      this.clearCanvas(this.canvasContext);
+      this.canvasContext.setTransform(this.currentTransform);
+    }
+  },
+  exitLayer: function () {
+    if (this.data.tt >= 1) {
+      var buffer = this.buffers[1];
+      // On the second buffer we store the current state of the global drawing
+      // that only contains the content of this layer
+      // (if it is a composition, it also includes the nested layers)
+      var bufferCtx = buffer.getContext('2d');
+      this.clearCanvas(bufferCtx);
+      bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+      // We clear the canvas again
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+      this.clearCanvas(this.canvasContext);
+      this.canvasContext.setTransform(this.currentTransform);
+      // We draw the mask
+      const mask = this.comp.getElementById('tp' in this.data ? this.data.tp : this.data.ind - 1);
+      mask.renderFrame(true);
+      // We draw the second buffer (that contains the content of this layer)
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+
+      // If the mask is a Luma matte, we need to do two extra painting operations
+      // the _isProxy check is to avoid drawing a fake canvas in workers that will throw an error
+      if (this.data.tt >= 3 && !document._isProxy) {
+        // We copy the painted mask to a buffer that has a color matrix filter applied to it
+        // that applies the rgb values to the alpha channel
+        var lumaBuffer = assetLoader.getLumaCanvas(this.canvasContext.canvas);
+        var lumaBufferCtx = lumaBuffer.getContext('2d');
+        lumaBufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+        this.clearCanvas(this.canvasContext);
+        // we repaint the context with the mask applied to it
+        this.canvasContext.drawImage(lumaBuffer, 0, 0);
+      }
+      this.canvasContext.globalCompositeOperation = operationsMap[this.data.tt];
+      this.canvasContext.drawImage(buffer, 0, 0);
+      // We finally draw the first buffer (that contains the content of the global drawing)
+      // We use destination-over to draw the global drawing below the current layer
+      this.canvasContext.globalCompositeOperation = 'destination-over';
+      this.canvasContext.drawImage(this.buffers[0], 0, 0);
+      this.canvasContext.setTransform(this.currentTransform);
+      // We reset the globalCompositeOperation to source-over, the standard type of operation
+      this.canvasContext.globalCompositeOperation = 'source-over';
+    }
+  },
+  renderFrame: function (forceRender) {
+    if (this.hidden || this.data.hd) {
+      return;
+    }
+    if (this.data.td === 1 && !forceRender) {
+      return;
+    }
+    this.renderTransform();
+    this.renderRenderable();
+    this.renderLocalTransform();
+    this.setBlendMode();
+    var forceRealStack = this.data.ty === 0;
+    this.prepareLayer();
+    this.globalData.renderer.save(forceRealStack);
+    this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props);
+    this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity);
+    this.renderInnerContent();
+    this.globalData.renderer.restore(forceRealStack);
+    this.exitLayer();
+    if (this.maskManager.hasMasks) {
+      this.globalData.renderer.restore(true);
+    }
+    if (this._isFirstFrame) {
+      this._isFirstFrame = false;
+    }
+  },
+  destroy: function () {
+    this.canvasContext = null;
+    this.data = null;
+    this.globalData = null;
+    this.maskManager.destroy();
+  },
+  mHelper: new Matrix(),
+};
+CVBaseElement.prototype.hide = CVBaseElement.prototype.hideElement;
+CVBaseElement.prototype.show = CVBaseElement.prototype.showElement;
+
+function CVShapeData(element, data, styles, transformsManager) {
+  this.styledShapes = [];
+  this.tr = [0, 0, 0, 0, 0, 0];
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  this.sh = ShapePropertyFactory.getShapeProp(element, data, ty, element);
+  var i;
+  var len = styles.length;
+  var styledShape;
+  for (i = 0; i < len; i += 1) {
+    if (!styles[i].closed) {
+      styledShape = {
+        transforms: transformsManager.addTransformSequence(styles[i].transforms),
+        trNodes: [],
+      };
+      this.styledShapes.push(styledShape);
+      styles[i].elements.push(styledShape);
+    }
+  }
+}
+
+CVShapeData.prototype.setAsAnimated = SVGShapeData.prototype.setAsAnimated;
+
+function CVShapeElement(data, globalData, comp) {
+  this.shapes = [];
+  this.shapesData = data.shapes;
+  this.stylesList = [];
+  this.itemsData = [];
+  this.prevViewData = [];
+  this.shapeModifiers = [];
+  this.processedElements = [];
+  this.transformsManager = new ShapeTransformManager();
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, CVBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableElement], CVShapeElement);
+
+CVShapeElement.prototype.initElement = RenderableDOMElement.prototype.initElement;
+
+CVShapeElement.prototype.transformHelper = { opacity: 1, _opMdf: false };
+
+CVShapeElement.prototype.dashResetter = [];
+
+CVShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
+};
+
+CVShapeElement.prototype.createStyleElement = function (data, transforms) {
+  var styleElem = {
+    data: data,
+    type: data.ty,
+    preTransforms: this.transformsManager.addTransformSequence(transforms),
+    transforms: [],
+    elements: [],
+    closed: data.hd === true,
+  };
+  var elementData = {};
+  if (data.ty === 'fl' || data.ty === 'st') {
+    elementData.c = PropertyFactory.getProp(this, data.c, 1, 255, this);
+    if (!elementData.c.k) {
+      styleElem.co = 'rgb(' + bmFloor(elementData.c.v[0]) + ',' + bmFloor(elementData.c.v[1]) + ',' + bmFloor(elementData.c.v[2]) + ')';
+    }
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    elementData.s = PropertyFactory.getProp(this, data.s, 1, null, this);
+    elementData.e = PropertyFactory.getProp(this, data.e, 1, null, this);
+    elementData.h = PropertyFactory.getProp(this, data.h || { k: 0 }, 0, 0.01, this);
+    elementData.a = PropertyFactory.getProp(this, data.a || { k: 0 }, 0, degToRads, this);
+    elementData.g = new GradientProperty(this, data.g, this);
+  }
+  elementData.o = PropertyFactory.getProp(this, data.o, 0, 0.01, this);
+  if (data.ty === 'st' || data.ty === 'gs') {
+    styleElem.lc = lineCapEnum[data.lc || 2];
+    styleElem.lj = lineJoinEnum[data.lj || 2];
+    if (data.lj == 1) { // eslint-disable-line eqeqeq
+      styleElem.ml = data.ml;
+    }
+    elementData.w = PropertyFactory.getProp(this, data.w, 0, null, this);
+    if (!elementData.w.k) {
+      styleElem.wi = elementData.w.v;
+    }
+    if (data.d) {
+      var d = new DashProperty(this, data.d, 'canvas', this);
+      elementData.d = d;
+      if (!elementData.d.k) {
+        styleElem.da = elementData.d.dashArray;
+        styleElem.do = elementData.d.dashoffset[0];
+      }
+    }
+  } else {
+    styleElem.r = data.r === 2 ? 'evenodd' : 'nonzero';
+  }
+  this.stylesList.push(styleElem);
+  elementData.style = styleElem;
+  return elementData;
+};
+
+CVShapeElement.prototype.createGroupElement = function () {
+  var elementData = {
+    it: [],
+    prevViewData: [],
+  };
+  return elementData;
+};
+
+CVShapeElement.prototype.createTransformElement = function (data) {
+  var elementData = {
+    transform: {
+      opacity: 1,
+      _opMdf: false,
+      key: this.transformsManager.getNewKey(),
+      op: PropertyFactory.getProp(this, data.o, 0, 0.01, this),
+      mProps: TransformPropertyFactory.getTransformProperty(this, data, this),
+    },
+  };
+  return elementData;
+};
+
+CVShapeElement.prototype.createShapeElement = function (data) {
+  var elementData = new CVShapeData(this, data, this.stylesList, this.transformsManager);
+
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  return elementData;
+};
+
+CVShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+  this.transformsManager.processSequences(this._isFirstFrame);
+};
+
+CVShapeElement.prototype.addTransformToStyleList = function (transform) {
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    if (!this.stylesList[i].closed) {
+      this.stylesList[i].transforms.push(transform);
+    }
+  }
+};
+
+CVShapeElement.prototype.removeTransformFromStyleList = function () {
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    if (!this.stylesList[i].closed) {
+      this.stylesList[i].transforms.pop();
+    }
+  }
+};
+
+CVShapeElement.prototype.closeStyles = function (styles) {
+  var i;
+  var len = styles.length;
+  for (i = 0; i < len; i += 1) {
+    styles[i].closed = true;
+  }
+};
+
+CVShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, shouldRender, transforms) {
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var processedPos;
+  var modifier;
+  var currentTransform;
+  var ownTransforms = [].concat(transforms);
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._shouldRender = shouldRender;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], ownTransforms);
+      } else {
+        itemsData[i].style.closed = false;
+      }
+
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, shouldRender, ownTransforms);
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        currentTransform = this.createTransformElement(arr[i]);
+        itemsData[i] = currentTransform;
+      }
+      ownTransforms.push(itemsData[i]);
+      this.addTransformToStyleList(itemsData[i]);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i]);
+      }
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        shouldRender = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  this.removeTransformFromStyleList();
+  this.closeStyles(ownStyles);
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+CVShapeElement.prototype.renderInnerContent = function () {
+  this.transformHelper.opacity = 1;
+  this.transformHelper._opMdf = false;
+  this.renderModifiers();
+  this.transformsManager.processSequences(this._isFirstFrame);
+  this.renderShape(this.transformHelper, this.shapesData, this.itemsData, true);
+};
+
+CVShapeElement.prototype.renderShapeTransform = function (parentTransform, groupTransform) {
+  if (parentTransform._opMdf || groupTransform.op._mdf || this._isFirstFrame) {
+    groupTransform.opacity = parentTransform.opacity;
+    groupTransform.opacity *= groupTransform.op.v;
+    groupTransform._opMdf = true;
+  }
+};
+
+CVShapeElement.prototype.drawLayer = function () {
+  var i;
+  var len = this.stylesList.length;
+  var j;
+  var jLen;
+  var k;
+  var kLen;
+  var elems;
+  var nodes;
+  var renderer = this.globalData.renderer;
+  var ctx = this.globalData.canvasContext;
+  var type;
+  var currentStyle;
+  for (i = 0; i < len; i += 1) {
+    currentStyle = this.stylesList[i];
+    type = currentStyle.type;
+
+    // Skipping style when
+    // Stroke width equals 0
+    // style should not be rendered (extra unused repeaters)
+    // current opacity equals 0
+    // global opacity equals 0
+    if (!(((type === 'st' || type === 'gs') && currentStyle.wi === 0) || !currentStyle.data._shouldRender || currentStyle.coOp === 0 || this.globalData.currentGlobalAlpha === 0)) {
+      renderer.save();
+      elems = currentStyle.elements;
+      if (type === 'st' || type === 'gs') {
+        renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd);
+        // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
+        renderer.ctxLineWidth(currentStyle.wi);
+        // ctx.lineWidth = currentStyle.wi;
+        renderer.ctxLineCap(currentStyle.lc);
+        // ctx.lineCap = currentStyle.lc;
+        renderer.ctxLineJoin(currentStyle.lj);
+        // ctx.lineJoin = currentStyle.lj;
+        renderer.ctxMiterLimit(currentStyle.ml || 0);
+        // ctx.miterLimit = currentStyle.ml || 0;
+      } else {
+        renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd);
+        // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
+      }
+      renderer.ctxOpacity(currentStyle.coOp);
+      if (type !== 'st' && type !== 'gs') {
+        ctx.beginPath();
+      }
+      renderer.ctxTransform(currentStyle.preTransforms.finalTransform.props);
+      jLen = elems.length;
+      for (j = 0; j < jLen; j += 1) {
+        if (type === 'st' || type === 'gs') {
+          ctx.beginPath();
+          if (currentStyle.da) {
+            ctx.setLineDash(currentStyle.da);
+            ctx.lineDashOffset = currentStyle.do;
+          }
+        }
+        nodes = elems[j].trNodes;
+        kLen = nodes.length;
+
+        for (k = 0; k < kLen; k += 1) {
+          if (nodes[k].t === 'm') {
+            ctx.moveTo(nodes[k].p[0], nodes[k].p[1]);
+          } else if (nodes[k].t === 'c') {
+            ctx.bezierCurveTo(nodes[k].pts[0], nodes[k].pts[1], nodes[k].pts[2], nodes[k].pts[3], nodes[k].pts[4], nodes[k].pts[5]);
+          } else {
+            ctx.closePath();
+          }
+        }
+        if (type === 'st' || type === 'gs') {
+          // ctx.stroke();
+          renderer.ctxStroke();
+          if (currentStyle.da) {
+            ctx.setLineDash(this.dashResetter);
+          }
+        }
+      }
+      if (type !== 'st' && type !== 'gs') {
+        // ctx.fill(currentStyle.r);
+        this.globalData.renderer.ctxFill(currentStyle.r);
+      }
+      renderer.restore();
+    }
+  }
+};
+
+CVShapeElement.prototype.renderShape = function (parentTransform, items, data, isMain) {
+  var i;
+  var len = items.length - 1;
+  var groupTransform;
+  groupTransform = parentTransform;
+  for (i = len; i >= 0; i -= 1) {
+    if (items[i].ty === 'tr') {
+      groupTransform = data[i].transform;
+      this.renderShapeTransform(parentTransform, groupTransform);
+    } else if (items[i].ty === 'sh' || items[i].ty === 'el' || items[i].ty === 'rc' || items[i].ty === 'sr') {
+      this.renderPath(items[i], data[i]);
+    } else if (items[i].ty === 'fl') {
+      this.renderFill(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'st') {
+      this.renderStroke(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'gf' || items[i].ty === 'gs') {
+      this.renderGradientFill(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'gr') {
+      this.renderShape(groupTransform, items[i].it, data[i].it);
+    } else if (items[i].ty === 'tm') {
+      //
+    }
+  }
+  if (isMain) {
+    this.drawLayer();
+  }
+};
+
+CVShapeElement.prototype.renderStyledShape = function (styledShape, shape) {
+  if (this._isFirstFrame || shape._mdf || styledShape.transforms._mdf) {
+    var shapeNodes = styledShape.trNodes;
+    var paths = shape.paths;
+    var i;
+    var len;
+    var j;
+    var jLen = paths._length;
+    shapeNodes.length = 0;
+    var groupTransformMat = styledShape.transforms.finalTransform;
+    for (j = 0; j < jLen; j += 1) {
+      var pathNodes = paths.shapes[j];
+      if (pathNodes && pathNodes.v) {
+        len = pathNodes._length;
+        for (i = 1; i < len; i += 1) {
+          if (i === 1) {
+            shapeNodes.push({
+              t: 'm',
+              p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0),
+            });
+          }
+          shapeNodes.push({
+            t: 'c',
+            pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[i], pathNodes.v[i]),
+          });
+        }
+        if (len === 1) {
+          shapeNodes.push({
+            t: 'm',
+            p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0),
+          });
+        }
+        if (pathNodes.c && len) {
+          shapeNodes.push({
+            t: 'c',
+            pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[0], pathNodes.v[0]),
+          });
+          shapeNodes.push({
+            t: 'z',
+          });
+        }
+      }
+    }
+    styledShape.trNodes = shapeNodes;
+  }
+};
+
+CVShapeElement.prototype.renderPath = function (pathData, itemData) {
+  if (pathData.hd !== true && pathData._shouldRender) {
+    var i;
+    var len = itemData.styledShapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderStyledShape(itemData.styledShapes[i], itemData.sh);
+    }
+  }
+};
+
+CVShapeElement.prototype.renderFill = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+
+  if (itemData.c._mdf || this._isFirstFrame) {
+    styleElem.co = 'rgb('
+        + bmFloor(itemData.c.v[0]) + ','
+        + bmFloor(itemData.c.v[1]) + ','
+        + bmFloor(itemData.c.v[2]) + ')';
+  }
+  if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
+    styleElem.coOp = itemData.o.v * groupTransform.opacity;
+  }
+};
+
+CVShapeElement.prototype.renderGradientFill = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+  var grd;
+  if (!styleElem.grd || itemData.g._mdf || itemData.s._mdf || itemData.e._mdf || (styleData.t !== 1 && (itemData.h._mdf || itemData.a._mdf))) {
+    var ctx = this.globalData.canvasContext;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+    if (styleData.t === 1) {
+      grd = ctx.createLinearGradient(pt1[0], pt1[1], pt2[0], pt2[1]);
+    } else {
+      var rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+      var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+      var percent = itemData.h.v;
+      if (percent >= 1) {
+        percent = 0.99;
+      } else if (percent <= -1) {
+        percent = -0.99;
+      }
+      var dist = rad * percent;
+      var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+      var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+      grd = ctx.createRadialGradient(x, y, 0, pt1[0], pt1[1], rad);
+    }
+
+    var i;
+    var len = styleData.g.p;
+    var cValues = itemData.g.c;
+    var opacity = 1;
+
+    for (i = 0; i < len; i += 1) {
+      if (itemData.g._hasOpacity && itemData.g._collapsable) {
+        opacity = itemData.g.o[i * 2 + 1];
+      }
+      grd.addColorStop(cValues[i * 4] / 100, 'rgba(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ',' + opacity + ')');
+    }
+    styleElem.grd = grd;
+  }
+  styleElem.coOp = itemData.o.v * groupTransform.opacity;
+};
+
+CVShapeElement.prototype.renderStroke = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+  var d = itemData.d;
+  if (d && (d._mdf || this._isFirstFrame)) {
+    styleElem.da = d.dashArray;
+    styleElem.do = d.dashoffset[0];
+  }
+  if (itemData.c._mdf || this._isFirstFrame) {
+    styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
+  }
+  if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
+    styleElem.coOp = itemData.o.v * groupTransform.opacity;
+  }
+  if (itemData.w._mdf || this._isFirstFrame) {
+    styleElem.wi = itemData.w.v;
+  }
+};
+
+CVShapeElement.prototype.destroy = function () {
+  this.shapesData = null;
+  this.globalData = null;
+  this.canvasContext = null;
+  this.stylesList.length = 0;
+  this.itemsData.length = 0;
+};
+
+function CVTextElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.yOffset = 0;
+  this.fillColorAnim = false;
+  this.strokeColorAnim = false;
+  this.strokeWidthAnim = false;
+  this.stroke = false;
+  this.fill = false;
+  this.justifyOffset = 0;
+  this.currentRender = null;
+  this.renderType = 'canvas';
+  this.values = {
+    fill: 'rgba(0,0,0,0)',
+    stroke: 'rgba(0,0,0,0)',
+    sWidth: 0,
+    fValue: '',
+  };
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement, ITextElement], CVTextElement);
+
+CVTextElement.prototype.tHelper = createTag('canvas').getContext('2d');
+
+CVTextElement.prototype.buildNewText = function () {
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
+
+  var hasFill = false;
+  if (documentData.fc) {
+    hasFill = true;
+    this.values.fill = this.buildColor(documentData.fc);
+  } else {
+    this.values.fill = 'rgba(0,0,0,0)';
+  }
+  this.fill = hasFill;
+  var hasStroke = false;
+  if (documentData.sc) {
+    hasStroke = true;
+    this.values.stroke = this.buildColor(documentData.sc);
+    this.values.sWidth = documentData.sw;
+  }
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  var i;
+  var len;
+  var letters = documentData.l;
+  var matrixHelper = this.mHelper;
+  this.stroke = hasStroke;
+  this.values.fValue = documentData.finalSize + 'px ' + this.globalData.fontManager.getFontByName(documentData.f).fFamily;
+  len = documentData.finalText.length;
+  // this.tHelper.font = this.values.fValue;
+  var charData;
+  var shapeData;
+  var k;
+  var kLen;
+  var shapes;
+  var j;
+  var jLen;
+  var pathNodes;
+  var commands;
+  var pathArr;
+  var singleShape = this.data.singleShape;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var cnt = 0;
+  for (i = 0; i < len; i += 1) {
+    charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
+    shapeData = (charData && charData.data) || {};
+    matrixHelper.reset();
+    if (singleShape && letters[i].n) {
+      xPos = -trackingOffset;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      firstLine = false;
+    }
+    shapes = shapeData.shapes ? shapeData.shapes[0].it : [];
+    jLen = shapes.length;
+    matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
+    if (singleShape) {
+      this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+    }
+    commands = createSizedArray(jLen - 1);
+    var commandsCounter = 0;
+    for (j = 0; j < jLen; j += 1) {
+      if (shapes[j].ty === 'sh') {
+        kLen = shapes[j].ks.k.i.length;
+        pathNodes = shapes[j].ks.k;
+        pathArr = [];
+        for (k = 1; k < kLen; k += 1) {
+          if (k === 1) {
+            pathArr.push(matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
+          }
+          pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToY(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToX(pathNodes.v[k][0], pathNodes.v[k][1], 0), matrixHelper.applyToY(pathNodes.v[k][0], pathNodes.v[k][1], 0));
+        }
+        pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToY(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
+        commands[commandsCounter] = pathArr;
+        commandsCounter += 1;
+      }
+    }
+    if (singleShape) {
+      xPos += letters[i].l;
+      xPos += trackingOffset;
+    }
+    if (this.textSpans[cnt]) {
+      this.textSpans[cnt].elem = commands;
+    } else {
+      this.textSpans[cnt] = { elem: commands };
+    }
+    cnt += 1;
+  }
+};
+
+CVTextElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  var ctx = this.canvasContext;
+  ctx.font = this.values.fValue;
+  this.globalData.renderer.ctxLineCap('butt');
+  // ctx.lineCap = 'butt';
+  this.globalData.renderer.ctxLineJoin('miter');
+  // ctx.lineJoin = 'miter';
+  this.globalData.renderer.ctxMiterLimit(4);
+  // ctx.miterLimit = 4;
+
+  if (!this.data.singleShape) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+  }
+
+  var i;
+  var len;
+  var j;
+  var jLen;
+  var k;
+  var kLen;
+  var renderedLetters = this.textAnimator.renderedLetters;
+
+  var letters = this.textProperty.currentData.l;
+
+  len = letters.length;
+  var renderedLetter;
+  var lastFill = null;
+  var lastStroke = null;
+  var lastStrokeW = null;
+  var commands;
+  var pathArr;
+  var renderer = this.globalData.renderer;
+  for (i = 0; i < len; i += 1) {
+    if (!letters[i].n) {
+      renderedLetter = renderedLetters[i];
+      if (renderedLetter) {
+        renderer.save();
+        renderer.ctxTransform(renderedLetter.p);
+        renderer.ctxOpacity(renderedLetter.o);
+      }
+      if (this.fill) {
+        if (renderedLetter && renderedLetter.fc) {
+          if (lastFill !== renderedLetter.fc) {
+            renderer.ctxFillStyle(renderedLetter.fc);
+            lastFill = renderedLetter.fc;
+            // ctx.fillStyle = renderedLetter.fc;
+          }
+        } else if (lastFill !== this.values.fill) {
+          lastFill = this.values.fill;
+          renderer.ctxFillStyle(this.values.fill);
+          // ctx.fillStyle = this.values.fill;
+        }
+        commands = this.textSpans[i].elem;
+        jLen = commands.length;
+        this.globalData.canvasContext.beginPath();
+        for (j = 0; j < jLen; j += 1) {
+          pathArr = commands[j];
+          kLen = pathArr.length;
+          this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
+          for (k = 2; k < kLen; k += 6) {
+            this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
+          }
+        }
+        this.globalData.canvasContext.closePath();
+        renderer.ctxFill();
+        // this.globalData.canvasContext.fill();
+        /// ctx.fillText(this.textSpans[i].val,0,0);
+      }
+      if (this.stroke) {
+        if (renderedLetter && renderedLetter.sw) {
+          if (lastStrokeW !== renderedLetter.sw) {
+            lastStrokeW = renderedLetter.sw;
+            renderer.ctxLineWidth(renderedLetter.sw);
+            // ctx.lineWidth = renderedLetter.sw;
+          }
+        } else if (lastStrokeW !== this.values.sWidth) {
+          lastStrokeW = this.values.sWidth;
+          renderer.ctxLineWidth(this.values.sWidth);
+          // ctx.lineWidth = this.values.sWidth;
+        }
+        if (renderedLetter && renderedLetter.sc) {
+          if (lastStroke !== renderedLetter.sc) {
+            lastStroke = renderedLetter.sc;
+            renderer.ctxStrokeStyle(renderedLetter.sc);
+            // ctx.strokeStyle = renderedLetter.sc;
+          }
+        } else if (lastStroke !== this.values.stroke) {
+          lastStroke = this.values.stroke;
+          renderer.ctxStrokeStyle(this.values.stroke);
+          // ctx.strokeStyle = this.values.stroke;
+        }
+        commands = this.textSpans[i].elem;
+        jLen = commands.length;
+        this.globalData.canvasContext.beginPath();
+        for (j = 0; j < jLen; j += 1) {
+          pathArr = commands[j];
+          kLen = pathArr.length;
+          this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
+          for (k = 2; k < kLen; k += 6) {
+            this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
+          }
+        }
+        this.globalData.canvasContext.closePath();
+        renderer.ctxStroke();
+        // this.globalData.canvasContext.stroke();
+        /// ctx.strokeText(letters[i].val,0,0);
+      }
+      if (renderedLetter) {
+        this.globalData.renderer.restore();
+      }
+    }
+  }
+};
+
+function CVImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  this.img = globalData.imageLoader.getAsset(this.assetData);
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVImageElement);
+
+CVImageElement.prototype.initElement = SVGShapeElement.prototype.initElement;
+CVImageElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
+
+CVImageElement.prototype.createContent = function () {
+  if (this.img.width && (this.assetData.w !== this.img.width || this.assetData.h !== this.img.height)) {
+    var canvas = createTag('canvas');
+    canvas.width = this.assetData.w;
+    canvas.height = this.assetData.h;
+    var ctx = canvas.getContext('2d');
+
+    var imgW = this.img.width;
+    var imgH = this.img.height;
+    var imgRel = imgW / imgH;
+    var canvasRel = this.assetData.w / this.assetData.h;
+    var widthCrop;
+    var heightCrop;
+    var par = this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio;
+    if ((imgRel > canvasRel && par === 'xMidYMid slice') || (imgRel < canvasRel && par !== 'xMidYMid slice')) {
+      heightCrop = imgH;
+      widthCrop = heightCrop * canvasRel;
+    } else {
+      widthCrop = imgW;
+      heightCrop = widthCrop / canvasRel;
+    }
+    ctx.drawImage(this.img, (imgW - widthCrop) / 2, (imgH - heightCrop) / 2, widthCrop, heightCrop, 0, 0, this.assetData.w, this.assetData.h);
+    this.img = canvas;
+  }
+};
+
+CVImageElement.prototype.renderInnerContent = function () {
+  this.canvasContext.drawImage(this.img, 0, 0);
+};
+
+CVImageElement.prototype.destroy = function () {
+  this.img = null;
+};
+
+function CVSolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVSolidElement);
+
+CVSolidElement.prototype.initElement = SVGShapeElement.prototype.initElement;
+CVSolidElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
+
+CVSolidElement.prototype.renderInnerContent = function () {
+  // var ctx = this.canvasContext;
+  this.globalData.renderer.ctxFillStyle(this.data.sc);
+  // ctx.fillStyle = this.data.sc;
+  this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh);
+  // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
+  //
+};
+
+function CanvasRendererBase() {
+}
+extendPrototype([BaseRenderer], CanvasRendererBase);
+
+CanvasRendererBase.prototype.createShape = function (data) {
+  return new CVShapeElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createText = function (data) {
+  return new CVTextElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createImage = function (data) {
+  return new CVImageElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createSolid = function (data) {
+  return new CVSolidElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
+
+CanvasRendererBase.prototype.ctxTransform = function (props) {
+  if (props[0] === 1 && props[1] === 0 && props[4] === 0 && props[5] === 1 && props[12] === 0 && props[13] === 0) {
+    return;
+  }
+  this.canvasContext.transform(props[0], props[1], props[4], props[5], props[12], props[13]);
+};
+
+CanvasRendererBase.prototype.ctxOpacity = function (op) {
+  this.canvasContext.globalAlpha *= op < 0 ? 0 : op;
+};
+
+CanvasRendererBase.prototype.ctxFillStyle = function (value) {
+  this.canvasContext.fillStyle = value;
+};
+
+CanvasRendererBase.prototype.ctxStrokeStyle = function (value) {
+  this.canvasContext.strokeStyle = value;
+};
+
+CanvasRendererBase.prototype.ctxLineWidth = function (value) {
+  this.canvasContext.lineWidth = value;
+};
+
+CanvasRendererBase.prototype.ctxLineCap = function (value) {
+  this.canvasContext.lineCap = value;
+};
+
+CanvasRendererBase.prototype.ctxLineJoin = function (value) {
+  this.canvasContext.lineJoin = value;
+};
+
+CanvasRendererBase.prototype.ctxMiterLimit = function (value) {
+  this.canvasContext.miterLimit = value;
+};
+
+CanvasRendererBase.prototype.ctxFill = function (rule) {
+  this.canvasContext.fill(rule);
+};
+
+CanvasRendererBase.prototype.ctxFillRect = function (x, y, w, h) {
+  this.canvasContext.fillRect(x, y, w, h);
+};
+
+CanvasRendererBase.prototype.ctxStroke = function () {
+  this.canvasContext.stroke();
+};
+
+CanvasRendererBase.prototype.reset = function () {
+  if (!this.renderConfig.clearCanvas) {
+    this.canvasContext.restore();
+    return;
+  }
+  this.contextData.reset();
+};
+
+CanvasRendererBase.prototype.save = function () {
+  this.canvasContext.save();
+};
+
+CanvasRendererBase.prototype.restore = function (actionFlag) {
+  if (!this.renderConfig.clearCanvas) {
+    this.canvasContext.restore();
+    return;
+  }
+  if (actionFlag) {
+    this.globalData.blendMode = 'source-over';
+  }
+  this.contextData.restore(actionFlag);
+};
+
+CanvasRendererBase.prototype.configAnimation = function (animData) {
+  if (this.animationItem.wrapper) {
+    this.animationItem.container = createTag('canvas');
+    var containerStyle = this.animationItem.container.style;
+    containerStyle.width = '100%';
+    containerStyle.height = '100%';
+    var origin = '0px 0px 0px';
+    containerStyle.transformOrigin = origin;
+    containerStyle.mozTransformOrigin = origin;
+    containerStyle.webkitTransformOrigin = origin;
+    containerStyle['-webkit-transform'] = origin;
+    containerStyle.contentVisibility = this.renderConfig.contentVisibility;
+    this.animationItem.wrapper.appendChild(this.animationItem.container);
+    this.canvasContext = this.animationItem.container.getContext('2d');
+    if (this.renderConfig.className) {
+      this.animationItem.container.setAttribute('class', this.renderConfig.className);
+    }
+    if (this.renderConfig.id) {
+      this.animationItem.container.setAttribute('id', this.renderConfig.id);
+    }
+  } else {
+    this.canvasContext = this.renderConfig.context;
+  }
+  this.contextData.setContext(this.canvasContext);
+  this.data = animData;
+  this.layers = animData.layers;
+  this.transformCanvas = {
+    w: animData.w,
+    h: animData.h,
+    sx: 0,
+    sy: 0,
+    tx: 0,
+    ty: 0,
+  };
+  this.setupGlobalData(animData, document.body);
+  this.globalData.canvasContext = this.canvasContext;
+  this.globalData.renderer = this;
+  this.globalData.isDashed = false;
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.globalData.transformCanvas = this.transformCanvas;
+  this.elements = createSizedArray(animData.layers.length);
+
+  this.updateContainerSize();
+};
+
+CanvasRendererBase.prototype.updateContainerSize = function (width, height) {
+  this.reset();
+  var elementWidth;
+  var elementHeight;
+  if (width) {
+    elementWidth = width;
+    elementHeight = height;
+    this.canvasContext.canvas.width = elementWidth;
+    this.canvasContext.canvas.height = elementHeight;
+  } else {
+    if (this.animationItem.wrapper && this.animationItem.container) {
+      elementWidth = this.animationItem.wrapper.offsetWidth;
+      elementHeight = this.animationItem.wrapper.offsetHeight;
+    } else {
+      elementWidth = this.canvasContext.canvas.width;
+      elementHeight = this.canvasContext.canvas.height;
+    }
+    this.canvasContext.canvas.width = elementWidth * this.renderConfig.dpr;
+    this.canvasContext.canvas.height = elementHeight * this.renderConfig.dpr;
+  }
+
+  var elementRel;
+  var animationRel;
+  if (this.renderConfig.preserveAspectRatio.indexOf('meet') !== -1 || this.renderConfig.preserveAspectRatio.indexOf('slice') !== -1) {
+    var par = this.renderConfig.preserveAspectRatio.split(' ');
+    var fillType = par[1] || 'meet';
+    var pos = par[0] || 'xMidYMid';
+    var xPos = pos.substr(0, 4);
+    var yPos = pos.substr(4);
+    elementRel = elementWidth / elementHeight;
+    animationRel = this.transformCanvas.w / this.transformCanvas.h;
+    if ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice')) {
+      this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+      this.transformCanvas.sy = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+    } else {
+      this.transformCanvas.sx = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+      this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+    }
+
+    if (xPos === 'xMid' && ((animationRel < elementRel && fillType === 'meet') || (animationRel > elementRel && fillType === 'slice'))) {
+      this.transformCanvas.tx = ((elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) / 2) * this.renderConfig.dpr;
+    } else if (xPos === 'xMax' && ((animationRel < elementRel && fillType === 'meet') || (animationRel > elementRel && fillType === 'slice'))) {
+      this.transformCanvas.tx = (elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) * this.renderConfig.dpr;
+    } else {
+      this.transformCanvas.tx = 0;
+    }
+    if (yPos === 'YMid' && ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice'))) {
+      this.transformCanvas.ty = ((elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w)) / 2) * this.renderConfig.dpr;
+    } else if (yPos === 'YMax' && ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice'))) {
+      this.transformCanvas.ty = ((elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w))) * this.renderConfig.dpr;
+    } else {
+      this.transformCanvas.ty = 0;
+    }
+  } else if (this.renderConfig.preserveAspectRatio === 'none') {
+    this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+    this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+    this.transformCanvas.tx = 0;
+    this.transformCanvas.ty = 0;
+  } else {
+    this.transformCanvas.sx = this.renderConfig.dpr;
+    this.transformCanvas.sy = this.renderConfig.dpr;
+    this.transformCanvas.tx = 0;
+    this.transformCanvas.ty = 0;
+  }
+  this.transformCanvas.props = [this.transformCanvas.sx, 0, 0, 0, 0, this.transformCanvas.sy, 0, 0, 0, 0, 1, 0, this.transformCanvas.tx, this.transformCanvas.ty, 0, 1];
+  /* var i, len = this.elements.length;
+    for(i=0;i<len;i+=1){
+        if(this.elements[i] && this.elements[i].data.ty === 0){
+            this.elements[i].resize(this.globalData.transformCanvas);
+        }
+    } */
+  this.ctxTransform(this.transformCanvas.props);
+  this.canvasContext.beginPath();
+  this.canvasContext.rect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
+  this.canvasContext.closePath();
+  this.canvasContext.clip();
+
+  this.renderFrame(this.renderedFrame, true);
+};
+
+CanvasRendererBase.prototype.destroy = function () {
+  if (this.renderConfig.clearCanvas && this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.globalData.canvasContext = null;
+  this.animationItem.container = null;
+  this.destroyed = true;
+};
+
+CanvasRendererBase.prototype.renderFrame = function (num, forceRender) {
+  if ((this.renderedFrame === num && this.renderConfig.clearCanvas === true && !forceRender) || this.destroyed || num === -1) {
+    return;
+  }
+  this.renderedFrame = num;
+  this.globalData.frameNum = num - this.animationItem._isFirstFrame;
+  this.globalData.frameId += 1;
+  this.globalData._mdf = !this.renderConfig.clearCanvas || forceRender;
+  this.globalData.projectInterface.currentFrame = num;
+
+  // console.log('--------');
+  // console.log('NEW: ',num);
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    if (this.renderConfig.clearCanvas === true) {
+      this.canvasContext.clearRect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
+    } else {
+      this.save();
+    }
+    for (i = len - 1; i >= 0; i -= 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+    if (this.renderConfig.clearCanvas !== true) {
+      this.restore();
+    }
+  }
+};
+
+CanvasRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  var element = this.createItem(this.layers[pos], this, this.globalData);
+  elements[pos] = element;
+  element.initExpressions();
+  /* if(this.layers[pos].ty === 0){
+        element.resize(this.globalData.transformCanvas);
+    } */
+};
+
+CanvasRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+  }
+};
+
+CanvasRendererBase.prototype.hide = function () {
+  this.animationItem.container.style.display = 'none';
+};
+
+CanvasRendererBase.prototype.show = function () {
+  this.animationItem.container.style.display = 'block';
+};
+
+function CanvasContext() {
+  this.opacity = -1;
+  this.transform = createTypedArray('float32', 16);
+  this.fillStyle = '';
+  this.strokeStyle = '';
+  this.lineWidth = '';
+  this.lineCap = '';
+  this.lineJoin = '';
+  this.miterLimit = '';
+  this.id = Math.random();
+}
+
+function CVContextData() {
+  this.stack = [];
+  this.cArrPos = 0;
+  this.cTr = new Matrix();
+  var i;
+  var len = 15;
+  for (i = 0; i < len; i += 1) {
+    var canvasContext = new CanvasContext();
+    this.stack[i] = canvasContext;
+  }
+  this._length = len;
+  this.nativeContext = null;
+  this.transformMat = new Matrix();
+  this.currentOpacity = 1;
+  //
+  this.currentFillStyle = '';
+  this.appliedFillStyle = '';
+  //
+  this.currentStrokeStyle = '';
+  this.appliedStrokeStyle = '';
+  //
+  this.currentLineWidth = '';
+  this.appliedLineWidth = '';
+  //
+  this.currentLineCap = '';
+  this.appliedLineCap = '';
+  //
+  this.currentLineJoin = '';
+  this.appliedLineJoin = '';
+  //
+  this.appliedMiterLimit = '';
+  this.currentMiterLimit = '';
+}
+
+CVContextData.prototype.duplicate = function () {
+  var newLength = this._length * 2;
+  var i = 0;
+  for (i = this._length; i < newLength; i += 1) {
+    this.stack[i] = new CanvasContext();
+  }
+  this._length = newLength;
+};
+
+CVContextData.prototype.reset = function () {
+  this.cArrPos = 0;
+  this.cTr.reset();
+  this.stack[this.cArrPos].opacity = 1;
+};
+
+CVContextData.prototype.restore = function (forceRestore) {
+  this.cArrPos -= 1;
+  var currentContext = this.stack[this.cArrPos];
+  var transform = currentContext.transform;
+  var i;
+  var arr = this.cTr.props;
+  for (i = 0; i < 16; i += 1) {
+    arr[i] = transform[i];
+  }
+  if (forceRestore) {
+    this.nativeContext.restore();
+    var prevStack = this.stack[this.cArrPos + 1];
+    this.appliedFillStyle = prevStack.fillStyle;
+    this.appliedStrokeStyle = prevStack.strokeStyle;
+    this.appliedLineWidth = prevStack.lineWidth;
+    this.appliedLineCap = prevStack.lineCap;
+    this.appliedLineJoin = prevStack.lineJoin;
+    this.appliedMiterLimit = prevStack.miterLimit;
+  }
+  this.nativeContext.setTransform(transform[0], transform[1], transform[4], transform[5], transform[12], transform[13]);
+  if (forceRestore || (currentContext.opacity !== -1 && this.currentOpacity !== currentContext.opacity)) {
+    this.nativeContext.globalAlpha = currentContext.opacity;
+    this.currentOpacity = currentContext.opacity;
+  }
+  this.currentFillStyle = currentContext.fillStyle;
+  this.currentStrokeStyle = currentContext.strokeStyle;
+  this.currentLineWidth = currentContext.lineWidth;
+  this.currentLineCap = currentContext.lineCap;
+  this.currentLineJoin = currentContext.lineJoin;
+  this.currentMiterLimit = currentContext.miterLimit;
+};
+
+CVContextData.prototype.save = function (saveOnNativeFlag) {
+  if (saveOnNativeFlag) {
+    this.nativeContext.save();
+  }
+  var props = this.cTr.props;
+  if (this._length <= this.cArrPos) {
+    this.duplicate();
+  }
+
+  var currentStack = this.stack[this.cArrPos];
+  var i;
+  for (i = 0; i < 16; i += 1) {
+    currentStack.transform[i] = props[i];
+  }
+  this.cArrPos += 1;
+  var newStack = this.stack[this.cArrPos];
+  newStack.opacity = currentStack.opacity;
+  newStack.fillStyle = currentStack.fillStyle;
+  newStack.strokeStyle = currentStack.strokeStyle;
+  newStack.lineWidth = currentStack.lineWidth;
+  newStack.lineCap = currentStack.lineCap;
+  newStack.lineJoin = currentStack.lineJoin;
+  newStack.miterLimit = currentStack.miterLimit;
+};
+
+CVContextData.prototype.setOpacity = function (value) {
+  this.stack[this.cArrPos].opacity = value;
+};
+
+CVContextData.prototype.setContext = function (value) {
+  this.nativeContext = value;
+};
+
+CVContextData.prototype.fillStyle = function (value) {
+  if (this.stack[this.cArrPos].fillStyle !== value) {
+    this.currentFillStyle = value;
+    this.stack[this.cArrPos].fillStyle = value;
+  }
+};
+
+CVContextData.prototype.strokeStyle = function (value) {
+  if (this.stack[this.cArrPos].strokeStyle !== value) {
+    this.currentStrokeStyle = value;
+    this.stack[this.cArrPos].strokeStyle = value;
+  }
+};
+
+CVContextData.prototype.lineWidth = function (value) {
+  if (this.stack[this.cArrPos].lineWidth !== value) {
+    this.currentLineWidth = value;
+    this.stack[this.cArrPos].lineWidth = value;
+  }
+};
+
+CVContextData.prototype.lineCap = function (value) {
+  if (this.stack[this.cArrPos].lineCap !== value) {
+    this.currentLineCap = value;
+    this.stack[this.cArrPos].lineCap = value;
+  }
+};
+
+CVContextData.prototype.lineJoin = function (value) {
+  if (this.stack[this.cArrPos].lineJoin !== value) {
+    this.currentLineJoin = value;
+    this.stack[this.cArrPos].lineJoin = value;
+  }
+};
+
+CVContextData.prototype.miterLimit = function (value) {
+  if (this.stack[this.cArrPos].miterLimit !== value) {
+    this.currentMiterLimit = value;
+    this.stack[this.cArrPos].miterLimit = value;
+  }
+};
+
+CVContextData.prototype.transform = function (props) {
+  this.transformMat.cloneFromProps(props);
+  // Taking the last transform value from the stored stack of transforms
+  var currentTransform = this.cTr;
+  // Applying the last transform value after the new transform to respect the order of transformations
+  this.transformMat.multiply(currentTransform);
+  // Storing the new transformed value in the stored transform
+  currentTransform.cloneFromProps(this.transformMat.props);
+  var trProps = currentTransform.props;
+  // Applying the new transform to the canvas
+  this.nativeContext.setTransform(trProps[0], trProps[1], trProps[4], trProps[5], trProps[12], trProps[13]);
+};
+
+CVContextData.prototype.opacity = function (op) {
+  var currentOpacity = this.stack[this.cArrPos].opacity;
+  currentOpacity *= op < 0 ? 0 : op;
+  if (this.stack[this.cArrPos].opacity !== currentOpacity) {
+    if (this.currentOpacity !== op) {
+      this.nativeContext.globalAlpha = op;
+      this.currentOpacity = op;
+    }
+    this.stack[this.cArrPos].opacity = currentOpacity;
+  }
+};
+
+CVContextData.prototype.fill = function (rule) {
+  if (this.appliedFillStyle !== this.currentFillStyle) {
+    this.appliedFillStyle = this.currentFillStyle;
+    this.nativeContext.fillStyle = this.appliedFillStyle;
+  }
+  this.nativeContext.fill(rule);
+};
+
+CVContextData.prototype.fillRect = function (x, y, w, h) {
+  if (this.appliedFillStyle !== this.currentFillStyle) {
+    this.appliedFillStyle = this.currentFillStyle;
+    this.nativeContext.fillStyle = this.appliedFillStyle;
+  }
+  this.nativeContext.fillRect(x, y, w, h);
+};
+
+CVContextData.prototype.stroke = function () {
+  if (this.appliedStrokeStyle !== this.currentStrokeStyle) {
+    this.appliedStrokeStyle = this.currentStrokeStyle;
+    this.nativeContext.strokeStyle = this.appliedStrokeStyle;
+  }
+  if (this.appliedLineWidth !== this.currentLineWidth) {
+    this.appliedLineWidth = this.currentLineWidth;
+    this.nativeContext.lineWidth = this.appliedLineWidth;
+  }
+  if (this.appliedLineCap !== this.currentLineCap) {
+    this.appliedLineCap = this.currentLineCap;
+    this.nativeContext.lineCap = this.appliedLineCap;
+  }
+  if (this.appliedLineJoin !== this.currentLineJoin) {
+    this.appliedLineJoin = this.currentLineJoin;
+    this.nativeContext.lineJoin = this.appliedLineJoin;
+  }
+  if (this.appliedMiterLimit !== this.currentMiterLimit) {
+    this.appliedMiterLimit = this.currentMiterLimit;
+    this.nativeContext.miterLimit = this.appliedMiterLimit;
+  }
+  this.nativeContext.stroke();
+};
+
+function CVCompElement(data, globalData, comp) {
+  this.completeLayers = false;
+  this.layers = data.layers;
+  this.pendingElements = [];
+  this.elements = createSizedArray(this.layers.length);
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([CanvasRendererBase, ICompElement, CVBaseElement], CVCompElement);
+
+CVCompElement.prototype.renderInnerContent = function () {
+  var ctx = this.canvasContext;
+  ctx.beginPath();
+  ctx.moveTo(0, 0);
+  ctx.lineTo(this.data.w, 0);
+  ctx.lineTo(this.data.w, this.data.h);
+  ctx.lineTo(0, this.data.h);
+  ctx.lineTo(0, 0);
+  ctx.clip();
+  var i;
+  var len = this.layers.length;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+CVCompElement.prototype.destroy = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+  this.layers = null;
+  this.elements = null;
+};
+
+CVCompElement.prototype.createComp = function (data) {
+  return new CVCompElement(data, this.globalData, this);
+};
+
+function CanvasRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.renderConfig = {
+    clearCanvas: (config && config.clearCanvas !== undefined) ? config.clearCanvas : true,
+    context: (config && config.context) || null,
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+  this.renderConfig.dpr = (config && config.dpr) || 1;
+  if (this.animationItem.wrapper) {
+    this.renderConfig.dpr = (config && config.dpr) || window.devicePixelRatio || 1;
+  }
+  this.renderedFrame = -1;
+  this.globalData = {
+    frameNum: -1,
+    _mdf: false,
+    renderConfig: this.renderConfig,
+    currentGlobalAlpha: -1,
+  };
+  this.contextData = new CVContextData();
+  this.elements = [];
+  this.pendingElements = [];
+  this.transformMat = new Matrix();
+  this.completeLayers = false;
+  this.rendererType = 'canvas';
+  if (this.renderConfig.clearCanvas) {
+    this.ctxTransform = this.contextData.transform.bind(this.contextData);
+    this.ctxOpacity = this.contextData.opacity.bind(this.contextData);
+    this.ctxFillStyle = this.contextData.fillStyle.bind(this.contextData);
+    this.ctxStrokeStyle = this.contextData.strokeStyle.bind(this.contextData);
+    this.ctxLineWidth = this.contextData.lineWidth.bind(this.contextData);
+    this.ctxLineCap = this.contextData.lineCap.bind(this.contextData);
+    this.ctxLineJoin = this.contextData.lineJoin.bind(this.contextData);
+    this.ctxMiterLimit = this.contextData.miterLimit.bind(this.contextData);
+    this.ctxFill = this.contextData.fill.bind(this.contextData);
+    this.ctxFillRect = this.contextData.fillRect.bind(this.contextData);
+    this.ctxStroke = this.contextData.stroke.bind(this.contextData);
+    this.save = this.contextData.save.bind(this.contextData);
+  }
+}
+extendPrototype([CanvasRendererBase], CanvasRenderer);
+
+CanvasRenderer.prototype.createComp = function (data) {
+  return new CVCompElement(data, this.globalData, this);
+};
+
+// Registering renderers
+registerRenderer('canvas', CanvasRenderer);
+
+// Registering shape modifiers
+ShapeModifiers.registerModifier('tm', TrimModifier);
+ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
+ShapeModifiers.registerModifier('rp', RepeaterModifier);
+ShapeModifiers.registerModifier('rd', RoundCornersModifier);
+ShapeModifiers.registerModifier('zz', ZigZagModifier);
+ShapeModifiers.registerModifier('op', OffsetPathModifier);
+
+const CompExpressionInterface = (function () {
+  return function (comp) {
+    function _thisLayerFunction(name) {
+      var i = 0;
+      var len = comp.layers.length;
+      while (i < len) {
+        if (comp.layers[i].nm === name || comp.layers[i].ind === name) {
+          return comp.elements[i].layerInterface;
+        }
+        i += 1;
+      }
+      return null;
+      // return {active:false};
+    }
+    Object.defineProperty(_thisLayerFunction, '_name', { value: comp.data.nm });
+    _thisLayerFunction.layer = _thisLayerFunction;
+    _thisLayerFunction.pixelAspect = 1;
+    _thisLayerFunction.height = comp.data.h || comp.globalData.compSize.h;
+    _thisLayerFunction.width = comp.data.w || comp.globalData.compSize.w;
+    _thisLayerFunction.pixelAspect = 1;
+    _thisLayerFunction.frameDuration = 1 / comp.globalData.frameRate;
+    _thisLayerFunction.displayStartTime = 0;
+    _thisLayerFunction.numLayers = comp.layers.length;
+    return _thisLayerFunction;
+  };
+}());
+
+/* eslint-disable */
+/*
+ Copyright 2014 David Bau.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ */
+
+function seedRandom(pool, math) {
+//
+// The following constants are related to IEEE 754 limits.
+//
+    var global = this,
+        width = 256,        // each RC4 output is 0 <= x < 256
+        chunks = 6,         // at least six RC4 outputs for each double
+        digits = 52,        // there are 52 significant digits in a double
+        rngname = 'random', // rngname: name for Math.random and Math.seedrandom
+        startdenom = math.pow(width, chunks),
+        significance = math.pow(2, digits),
+        overflow = significance * 2,
+        mask = width - 1,
+        nodecrypto;         // node.js crypto module, initialized at the bottom.
+
+//
+// seedrandom()
+// This is the seedrandom function described above.
+//
+    function seedrandom(seed, options, callback) {
+        var key = [];
+        options = (options === true) ? { entropy: true } : (options || {});
+
+        // Flatten the seed string or build one from local entropy if needed.
+        var shortseed = mixkey(flatten(
+            options.entropy ? [seed, tostring(pool)] :
+                (seed === null) ? autoseed() : seed, 3), key);
+
+        // Use the seed to initialize an ARC4 generator.
+        var arc4 = new ARC4(key);
+
+        // This function returns a random double in [0, 1) that contains
+        // randomness in every bit of the mantissa of the IEEE 754 value.
+        var prng = function() {
+            var n = arc4.g(chunks),             // Start with a numerator n < 2 ^ 48
+                d = startdenom,                 //   and denominator d = 2 ^ 48.
+                x = 0;                          //   and no 'extra last byte'.
+            while (n < significance) {          // Fill up all significant digits by
+                n = (n + x) * width;              //   shifting numerator and
+                d *= width;                       //   denominator and generating a
+                x = arc4.g(1);                    //   new least-significant-byte.
+            }
+            while (n >= overflow) {             // To avoid rounding up, before adding
+                n /= 2;                           //   last byte, shift everything
+                d /= 2;                           //   right using integer math until
+                x >>>= 1;                         //   we have exactly the desired bits.
+            }
+            return (n + x) / d;                 // Form the number within [0, 1).
+        };
+
+        prng.int32 = function() { return arc4.g(4) | 0; };
+        prng.quick = function() { return arc4.g(4) / 0x100000000; };
+        prng.double = prng;
+
+        // Mix the randomness into accumulated entropy.
+        mixkey(tostring(arc4.S), pool);
+
+        // Calling convention: what to return as a function of prng, seed, is_math.
+        return (options.pass || callback ||
+        function(prng, seed, is_math_call, state) {
+            if (state) {
+                // Load the arc4 state from the given state if it has an S array.
+                if (state.S) { copy(state, arc4); }
+                // Only provide the .state method if requested via options.state.
+                prng.state = function() { return copy(arc4, {}); };
+            }
+
+            // If called as a method of Math (Math.seedrandom()), mutate
+            // Math.random because that is how seedrandom.js has worked since v1.0.
+            if (is_math_call) { math[rngname] = prng; return seed; }
+
+            // Otherwise, it is a newer calling convention, so return the
+            // prng directly.
+            else return prng;
+        })(
+            prng,
+            shortseed,
+            'global' in options ? options.global : (this == math),
+            options.state);
+    }
+    math['seed' + rngname] = seedrandom;
+
+//
+// ARC4
+//
+// An ARC4 implementation.  The constructor takes a key in the form of
+// an array of at most (width) integers that should be 0 <= x < (width).
+//
+// The g(count) method returns a pseudorandom integer that concatenates
+// the next (count) outputs from ARC4.  Its return value is a number x
+// that is in the range 0 <= x < (width ^ count).
+//
+    function ARC4(key) {
+        var t, keylen = key.length,
+            me = this, i = 0, j = me.i = me.j = 0, s = me.S = [];
+
+        // The empty key [] is treated as [0].
+        if (!keylen) { key = [keylen++]; }
+
+        // Set up S using the standard key scheduling algorithm.
+        while (i < width) {
+            s[i] = i++;
+        }
+        for (i = 0; i < width; i++) {
+            s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))];
+            s[j] = t;
+        }
+
+        // The "g" method returns the next (count) outputs as one number.
+        me.g = function(count) {
+            // Using instance members instead of closure state nearly doubles speed.
+            var t, r = 0,
+                i = me.i, j = me.j, s = me.S;
+            while (count--) {
+                t = s[i = mask & (i + 1)];
+                r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))];
+            }
+            me.i = i; me.j = j;
+            return r;
+            // For robust unpredictability, the function call below automatically
+            // discards an initial batch of values.  This is called RC4-drop[256].
+            // See http://google.com/search?q=rsa+fluhrer+response&btnI
+        };
+    }
+
+//
+// copy()
+// Copies internal state of ARC4 to or from a plain object.
+//
+    function copy(f, t) {
+        t.i = f.i;
+        t.j = f.j;
+        t.S = f.S.slice();
+        return t;
+    }
+
+//
+// flatten()
+// Converts an object tree to nested arrays of strings.
+//
+    function flatten(obj, depth) {
+        var result = [], typ = (typeof obj), prop;
+        if (depth && typ == 'object') {
+            for (prop in obj) {
+                try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}
+            }
+        }
+        return (result.length ? result : typ == 'string' ? obj : obj + '\0');
+    }
+
+//
+// mixkey()
+// Mixes a string seed into a key that is an array of integers, and
+// returns a shortened string seed that is equivalent to the result key.
+//
+    function mixkey(seed, key) {
+        var stringseed = seed + '', smear, j = 0;
+        while (j < stringseed.length) {
+            key[mask & j] =
+                mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++));
+        }
+        return tostring(key);
+    }
+
+//
+// autoseed()
+// Returns an object for autoseeding, using window.crypto and Node crypto
+// module if available.
+//
+    function autoseed() {
+        try {
+            if (nodecrypto) { return tostring(nodecrypto.randomBytes(width)); }
+            var out = new Uint8Array(width);
+            (global.crypto || global.msCrypto).getRandomValues(out);
+            return tostring(out);
+        } catch (e) {
+            var browser = global.navigator,
+                plugins = browser && browser.plugins;
+            return [+new Date(), global, plugins, global.screen, tostring(pool)];
+        }
+    }
+
+//
+// tostring()
+// Converts an array of charcodes to a string
+//
+    function tostring(a) {
+        return String.fromCharCode.apply(0, a);
+    }
+
+//
+// When seedrandom.js is loaded, we immediately mix a few bits
+// from the built-in RNG into the entropy pool.  Because we do
+// not want to interfere with deterministic PRNG state later,
+// seedrandom will not call math.random on its own again after
+// initialization.
+//
+    mixkey(math.random(), pool);
+
+//
+// Nodejs and AMD support: export the implementation as a module using
+// either convention.
+//
+
+// End anonymous scope, and pass initial values.
+};
+
+function initialize$2(BMMath) {
+    seedRandom([], BMMath);
+}
+
+var propTypes = {
+  SHAPE: 'shape',
+};
+
+/* eslint-disable camelcase */
+
+const ExpressionManager = (function () {
+  'use strict';
+
+  var ob = {};
+  var Math = BMMath;
+  var window = null;
+  var document = null;
+  var XMLHttpRequest = null;
+  var fetch = null;
+  var frames = null;
+  var _lottieGlobal = {};
+  initialize$2(BMMath);
+
+  function resetFrame() {
+    _lottieGlobal = {};
+  }
+
+  function $bm_isInstanceOfArray(arr) {
+    return arr.constructor === Array || arr.constructor === Float32Array;
+  }
+
+  function isNumerable(tOfV, v) {
+    return tOfV === 'number' || v instanceof Number || tOfV === 'boolean' || tOfV === 'string';
+  }
+
+  function $bm_neg(a) {
+    var tOfA = typeof a;
+    if (tOfA === 'number' || a instanceof Number || tOfA === 'boolean') {
+      return -a;
+    }
+    if ($bm_isInstanceOfArray(a)) {
+      var i;
+      var lenA = a.length;
+      var retArr = [];
+      for (i = 0; i < lenA; i += 1) {
+        retArr[i] = -a[i];
+      }
+      return retArr;
+    }
+    if (a.propType) {
+      return a.v;
+    }
+    return -a;
+  }
+
+  var easeInBez = BezierFactory.getBezierEasing(0.333, 0, 0.833, 0.833, 'easeIn').get;
+  var easeOutBez = BezierFactory.getBezierEasing(0.167, 0.167, 0.667, 1, 'easeOut').get;
+  var easeInOutBez = BezierFactory.getBezierEasing(0.33, 0, 0.667, 1, 'easeInOut').get;
+
+  function sum(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    if ((isNumerable(tOfA, a) && isNumerable(tOfB, b)) || tOfA === 'string' || tOfB === 'string') {
+      return a + b;
+    }
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      a = a.slice(0);
+      a[0] += b;
+      return a;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      b = b.slice(0);
+      b[0] = a + b[0];
+      return b;
+    }
+    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
+      var i = 0;
+      var lenA = a.length;
+      var lenB = b.length;
+      var retArr = [];
+      while (i < lenA || i < lenB) {
+        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
+          retArr[i] = a[i] + b[i];
+        } else {
+          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
+        }
+        i += 1;
+      }
+      return retArr;
+    }
+    return 0;
+  }
+  var add = sum;
+
+  function sub(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      if (tOfA === 'string') {
+        a = parseInt(a, 10);
+      }
+      if (tOfB === 'string') {
+        b = parseInt(b, 10);
+      }
+      return a - b;
+    }
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      a = a.slice(0);
+      a[0] -= b;
+      return a;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      b = b.slice(0);
+      b[0] = a - b[0];
+      return b;
+    }
+    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
+      var i = 0;
+      var lenA = a.length;
+      var lenB = b.length;
+      var retArr = [];
+      while (i < lenA || i < lenB) {
+        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
+          retArr[i] = a[i] - b[i];
+        } else {
+          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
+        }
+        i += 1;
+      }
+      return retArr;
+    }
+    return 0;
+  }
+
+  function mul(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    var arr;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      return a * b;
+    }
+
+    var i;
+    var len;
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      len = a.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a[i] * b;
+      }
+      return arr;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      len = b.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a * b[i];
+      }
+      return arr;
+    }
+    return 0;
+  }
+
+  function div(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    var arr;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      return a / b;
+    }
+    var i;
+    var len;
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      len = a.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a[i] / b;
+      }
+      return arr;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      len = b.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a / b[i];
+      }
+      return arr;
+    }
+    return 0;
+  }
+  function mod(a, b) {
+    if (typeof a === 'string') {
+      a = parseInt(a, 10);
+    }
+    if (typeof b === 'string') {
+      b = parseInt(b, 10);
+    }
+    return a % b;
+  }
+  var $bm_sum = sum;
+  var $bm_sub = sub;
+  var $bm_mul = mul;
+  var $bm_div = div;
+  var $bm_mod = mod;
+
+  function clamp(num, min, max) {
+    if (min > max) {
+      var mm = max;
+      max = min;
+      min = mm;
+    }
+    return Math.min(Math.max(num, min), max);
+  }
+
+  function radiansToDegrees(val) {
+    return val / degToRads;
+  }
+  var radians_to_degrees = radiansToDegrees;
+
+  function degreesToRadians(val) {
+    return val * degToRads;
+  }
+  var degrees_to_radians = radiansToDegrees;
+
+  var helperLengthArray = [0, 0, 0, 0, 0, 0];
+
+  function length(arr1, arr2) {
+    if (typeof arr1 === 'number' || arr1 instanceof Number) {
+      arr2 = arr2 || 0;
+      return Math.abs(arr1 - arr2);
+    }
+    if (!arr2) {
+      arr2 = helperLengthArray;
+    }
+    var i;
+    var len = Math.min(arr1.length, arr2.length);
+    var addedLength = 0;
+    for (i = 0; i < len; i += 1) {
+      addedLength += Math.pow(arr2[i] - arr1[i], 2);
+    }
+    return Math.sqrt(addedLength);
+  }
+
+  function normalize(vec) {
+    return div(vec, length(vec));
+  }
+
+  function rgbToHsl(val) {
+    var r = val[0]; var g = val[1]; var b = val[2];
+    var max = Math.max(r, g, b);
+    var min = Math.min(r, g, b);
+    var h;
+    var s;
+    var l = (max + min) / 2;
+
+    if (max === min) {
+      h = 0; // achromatic
+      s = 0; // achromatic
+    } else {
+      var d = max - min;
+      s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+      switch (max) {
+        case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+        case g: h = (b - r) / d + 2; break;
+        case b: h = (r - g) / d + 4; break;
+        default: break;
+      }
+      h /= 6;
+    }
+
+    return [h, s, l, val[3]];
+  }
+
+  function hue2rgb(p, q, t) {
+    if (t < 0) t += 1;
+    if (t > 1) t -= 1;
+    if (t < 1 / 6) return p + (q - p) * 6 * t;
+    if (t < 1 / 2) return q;
+    if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
+    return p;
+  }
+
+  function hslToRgb(val) {
+    var h = val[0];
+    var s = val[1];
+    var l = val[2];
+
+    var r;
+    var g;
+    var b;
+
+    if (s === 0) {
+      r = l; // achromatic
+      b = l; // achromatic
+      g = l; // achromatic
+    } else {
+      var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+      var p = 2 * l - q;
+      r = hue2rgb(p, q, h + 1 / 3);
+      g = hue2rgb(p, q, h);
+      b = hue2rgb(p, q, h - 1 / 3);
+    }
+
+    return [r, g, b, val[3]];
+  }
+
+  function linear(t, tMin, tMax, value1, value2) {
+    if (value1 === undefined || value2 === undefined) {
+      value1 = tMin;
+      value2 = tMax;
+      tMin = 0;
+      tMax = 1;
+    }
+    if (tMax < tMin) {
+      var _tMin = tMax;
+      tMax = tMin;
+      tMin = _tMin;
+    }
+    if (t <= tMin) {
+      return value1;
+    } if (t >= tMax) {
+      return value2;
+    }
+    var perc = tMax === tMin ? 0 : (t - tMin) / (tMax - tMin);
+    if (!value1.length) {
+      return value1 + (value2 - value1) * perc;
+    }
+    var i;
+    var len = value1.length;
+    var arr = createTypedArray('float32', len);
+    for (i = 0; i < len; i += 1) {
+      arr[i] = value1[i] + (value2[i] - value1[i]) * perc;
+    }
+    return arr;
+  }
+  function random(min, max) {
+    if (max === undefined) {
+      if (min === undefined) {
+        min = 0;
+        max = 1;
+      } else {
+        max = min;
+        min = undefined;
+      }
+    }
+    if (max.length) {
+      var i;
+      var len = max.length;
+      if (!min) {
+        min = createTypedArray('float32', len);
+      }
+      var arr = createTypedArray('float32', len);
+      var rnd = BMMath.random();
+      for (i = 0; i < len; i += 1) {
+        arr[i] = min[i] + rnd * (max[i] - min[i]);
+      }
+      return arr;
+    }
+    if (min === undefined) {
+      min = 0;
+    }
+    var rndm = BMMath.random();
+    return min + rndm * (max - min);
+  }
+
+  function createPath(points, inTangents, outTangents, closed) {
+    var i;
+    var len = points.length;
+    var path = shapePool.newElement();
+    path.setPathData(!!closed, len);
+    var arrPlaceholder = [0, 0];
+    var inVertexPoint;
+    var outVertexPoint;
+    for (i = 0; i < len; i += 1) {
+      inVertexPoint = (inTangents && inTangents[i]) ? inTangents[i] : arrPlaceholder;
+      outVertexPoint = (outTangents && outTangents[i]) ? outTangents[i] : arrPlaceholder;
+      path.setTripleAt(points[i][0], points[i][1], outVertexPoint[0] + points[i][0], outVertexPoint[1] + points[i][1], inVertexPoint[0] + points[i][0], inVertexPoint[1] + points[i][1], i, true);
+    }
+    return path;
+  }
+
+  function initiateExpression(elem, data, property) {
+    // Bail out if we don't want expressions
+    function noOp(_value) {
+      return _value;
+    }
+    if (!elem.globalData.renderConfig.runExpressions) {
+      return noOp;
+    }
+
+    var val = data.x;
+    var needsVelocity = /velocity(?![\w\d])/.test(val);
+    var _needsRandom = val.indexOf('random') !== -1;
+    var elemType = elem.data.ty;
+    var transform;
+    var $bm_transform;
+    var content;
+    var effect;
+    var thisProperty = property;
+    thisProperty._name = elem.data.nm;
+    thisProperty.valueAtTime = thisProperty.getValueAtTime;
+    Object.defineProperty(thisProperty, 'value', {
+      get: function () {
+        return thisProperty.v;
+      },
+    });
+    elem.comp.frameDuration = 1 / elem.comp.globalData.frameRate;
+    elem.comp.displayStartTime = 0;
+    var inPoint = elem.data.ip / elem.comp.globalData.frameRate;
+    var outPoint = elem.data.op / elem.comp.globalData.frameRate;
+    var width = elem.data.sw ? elem.data.sw : 0;
+    var height = elem.data.sh ? elem.data.sh : 0;
+    var name = elem.data.nm;
+    var loopIn;
+    var loop_in;
+    var loopOut;
+    var loop_out;
+    var smooth;
+    var toWorld;
+    var fromWorld;
+    var fromComp;
+    var toComp;
+    var fromCompToSurface;
+    var position;
+    var rotation;
+    var anchorPoint;
+    var scale;
+    var thisLayer;
+    var thisComp;
+    var mask;
+    var valueAtTime;
+    var velocityAtTime;
+
+    var scoped_bm_rt;
+    // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
+    var expression_function = eval('[function _expression_function(){' + val + ';scoped_bm_rt=$bm_rt}]')[0]; // eslint-disable-line no-eval
+    var numKeys = property.kf ? data.k.length : 0;
+
+    var active = !this.data || this.data.hd !== true;
+
+    var wiggle = function wiggle(freq, amp) {
+      var iWiggle;
+      var j;
+      var lenWiggle = this.pv.length ? this.pv.length : 1;
+      var addedAmps = createTypedArray('float32', lenWiggle);
+      freq = 5;
+      var iterations = Math.floor(time * freq);
+      iWiggle = 0;
+      j = 0;
+      while (iWiggle < iterations) {
+        // var rnd = BMMath.random();
+        for (j = 0; j < lenWiggle; j += 1) {
+          addedAmps[j] += -amp + amp * 2 * BMMath.random();
+          // addedAmps[j] += -amp + amp*2*rnd;
+        }
+        iWiggle += 1;
+      }
+      // var rnd2 = BMMath.random();
+      var periods = time * freq;
+      var perc = periods - Math.floor(periods);
+      var arr = createTypedArray('float32', lenWiggle);
+      if (lenWiggle > 1) {
+        for (j = 0; j < lenWiggle; j += 1) {
+          arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc;
+          // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
+          // arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc);
+        }
+        return arr;
+      }
+      return this.pv + addedAmps[0] + (-amp + amp * 2 * BMMath.random()) * perc;
+    }.bind(this);
+
+    if (thisProperty.loopIn) {
+      loopIn = thisProperty.loopIn.bind(thisProperty);
+      loop_in = loopIn;
+    }
+
+    if (thisProperty.loopOut) {
+      loopOut = thisProperty.loopOut.bind(thisProperty);
+      loop_out = loopOut;
+    }
+
+    if (thisProperty.smooth) {
+      smooth = thisProperty.smooth.bind(thisProperty);
+    }
+
+    function loopInDuration(type, duration) {
+      return loopIn(type, duration, true);
+    }
+
+    function loopOutDuration(type, duration) {
+      return loopOut(type, duration, true);
+    }
+
+    if (this.getValueAtTime) {
+      valueAtTime = this.getValueAtTime.bind(this);
+    }
+
+    if (this.getVelocityAtTime) {
+      velocityAtTime = this.getVelocityAtTime.bind(this);
+    }
+
+    var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface);
+
+    function lookAt(elem1, elem2) {
+      var fVec = [elem2[0] - elem1[0], elem2[1] - elem1[1], elem2[2] - elem1[2]];
+      var pitch = Math.atan2(fVec[0], Math.sqrt(fVec[1] * fVec[1] + fVec[2] * fVec[2])) / degToRads;
+      var yaw = -Math.atan2(fVec[1], fVec[2]) / degToRads;
+      return [yaw, pitch, 0];
+    }
+
+    function easeOut(t, tMin, tMax, val1, val2) {
+      return applyEase(easeOutBez, t, tMin, tMax, val1, val2);
+    }
+
+    function easeIn(t, tMin, tMax, val1, val2) {
+      return applyEase(easeInBez, t, tMin, tMax, val1, val2);
+    }
+
+    function ease(t, tMin, tMax, val1, val2) {
+      return applyEase(easeInOutBez, t, tMin, tMax, val1, val2);
+    }
+
+    function applyEase(fn, t, tMin, tMax, val1, val2) {
+      if (val1 === undefined) {
+        val1 = tMin;
+        val2 = tMax;
+      } else {
+        t = (t - tMin) / (tMax - tMin);
+      }
+      if (t > 1) {
+        t = 1;
+      } else if (t < 0) {
+        t = 0;
+      }
+      var mult = fn(t);
+      if ($bm_isInstanceOfArray(val1)) {
+        var iKey;
+        var lenKey = val1.length;
+        var arr = createTypedArray('float32', lenKey);
+        for (iKey = 0; iKey < lenKey; iKey += 1) {
+          arr[iKey] = (val2[iKey] - val1[iKey]) * mult + val1[iKey];
+        }
+        return arr;
+      }
+      return (val2 - val1) * mult + val1;
+    }
+
+    function nearestKey(time) {
+      var iKey;
+      var lenKey = data.k.length;
+      var index;
+      var keyTime;
+      if (!data.k.length || typeof (data.k[0]) === 'number') {
+        index = 0;
+        keyTime = 0;
+      } else {
+        index = -1;
+        time *= elem.comp.globalData.frameRate;
+        if (time < data.k[0].t) {
+          index = 1;
+          keyTime = data.k[0].t;
+        } else {
+          for (iKey = 0; iKey < lenKey - 1; iKey += 1) {
+            if (time === data.k[iKey].t) {
+              index = iKey + 1;
+              keyTime = data.k[iKey].t;
+              break;
+            } else if (time > data.k[iKey].t && time < data.k[iKey + 1].t) {
+              if (time - data.k[iKey].t > data.k[iKey + 1].t - time) {
+                index = iKey + 2;
+                keyTime = data.k[iKey + 1].t;
+              } else {
+                index = iKey + 1;
+                keyTime = data.k[iKey].t;
+              }
+              break;
+            }
+          }
+          if (index === -1) {
+            index = iKey + 1;
+            keyTime = data.k[iKey].t;
+          }
+        }
+      }
+      var obKey = {};
+      obKey.index = index;
+      obKey.time = keyTime / elem.comp.globalData.frameRate;
+      return obKey;
+    }
+
+    function key(ind) {
+      var obKey;
+      var iKey;
+      var lenKey;
+      if (!data.k.length || typeof (data.k[0]) === 'number') {
+        throw new Error('The property has no keyframe at index ' + ind);
+      }
+      ind -= 1;
+      obKey = {
+        time: data.k[ind].t / elem.comp.globalData.frameRate,
+        value: [],
+      };
+      var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e;
+
+      lenKey = arr.length;
+      for (iKey = 0; iKey < lenKey; iKey += 1) {
+        obKey[iKey] = arr[iKey];
+        obKey.value[iKey] = arr[iKey];
+      }
+      return obKey;
+    }
+
+    function framesToTime(fr, fps) {
+      if (!fps) {
+        fps = elem.comp.globalData.frameRate;
+      }
+      return fr / fps;
+    }
+
+    function timeToFrames(t, fps) {
+      if (!t && t !== 0) {
+        t = time;
+      }
+      if (!fps) {
+        fps = elem.comp.globalData.frameRate;
+      }
+      return t * fps;
+    }
+
+    function seedRandom(seed) {
+      BMMath.seedrandom(randSeed + seed);
+    }
+
+    function sourceRectAtTime() {
+      return elem.sourceRectAtTime();
+    }
+
+    function substring(init, end) {
+      if (typeof value === 'string') {
+        if (end === undefined) {
+          return value.substring(init);
+        }
+        return value.substring(init, end);
+      }
+      return '';
+    }
+
+    function substr(init, end) {
+      if (typeof value === 'string') {
+        if (end === undefined) {
+          return value.substr(init);
+        }
+        return value.substr(init, end);
+      }
+      return '';
+    }
+
+    function posterizeTime(framesPerSecond) {
+      time = framesPerSecond === 0 ? 0 : Math.floor(time * framesPerSecond) / framesPerSecond;
+      value = valueAtTime(time);
+    }
+
+    var time;
+    var velocity;
+    var value;
+    var text;
+    var textIndex;
+    var textTotal;
+    var selectorValue;
+    var index = elem.data.ind;
+    var hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+    var parent;
+    var randSeed = Math.floor(Math.random() * 1000000);
+    var globalData = elem.globalData;
+
+    function executeExpression(_value) {
+      // globalData.pushExpression();
+      value = _value;
+      if (this.frameExpressionId === elem.globalData.frameId && this.propType !== 'textSelector') {
+        return value;
+      }
+      if (this.propType === 'textSelector') {
+        textIndex = this.textIndex;
+        textTotal = this.textTotal;
+        selectorValue = this.selectorValue;
+      }
+      if (!thisLayer) {
+        text = elem.layerInterface.text;
+        thisLayer = elem.layerInterface;
+        thisComp = elem.comp.compInterface;
+        toWorld = thisLayer.toWorld.bind(thisLayer);
+        fromWorld = thisLayer.fromWorld.bind(thisLayer);
+        fromComp = thisLayer.fromComp.bind(thisLayer);
+        toComp = thisLayer.toComp.bind(thisLayer);
+        mask = thisLayer.mask ? thisLayer.mask.bind(thisLayer) : null;
+        fromCompToSurface = fromComp;
+      }
+      if (!transform) {
+        transform = elem.layerInterface('ADBE Transform Group');
+        $bm_transform = transform;
+        if (transform) {
+          anchorPoint = transform.anchorPoint;
+          /* position = transform.position;
+                    rotation = transform.rotation;
+                    scale = transform.scale; */
+        }
+      }
+
+      if (elemType === 4 && !content) {
+        content = thisLayer('ADBE Root Vectors Group');
+      }
+      if (!effect) {
+        effect = thisLayer(4);
+      }
+      hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+      if (hasParent && !parent) {
+        parent = elem.hierarchy[0].layerInterface;
+      }
+      time = this.comp.renderedFrame / this.comp.globalData.frameRate;
+      if (_needsRandom) {
+        seedRandom(randSeed + time);
+      }
+      if (needsVelocity) {
+        velocity = velocityAtTime(time);
+      }
+      expression_function();
+      this.frameExpressionId = elem.globalData.frameId;
+
+      // TODO: Check if it's possible to return on ShapeInterface the .v value
+      // Changed this to a ternary operation because Rollup failed compiling it correctly
+      scoped_bm_rt = scoped_bm_rt.propType === propTypes.SHAPE
+        ? scoped_bm_rt.v
+        : scoped_bm_rt;
+      return scoped_bm_rt;
+    }
+    // Bundlers will see these as dead code and unless we reference them
+    executeExpression.__preventDeadCodeRemoval = [$bm_transform, anchorPoint, time, velocity, inPoint, outPoint, width, height, name, loop_in, loop_out, smooth, toComp, fromCompToSurface, toWorld, fromWorld, mask, position, rotation, scale, thisComp, numKeys, active, wiggle, loopInDuration, loopOutDuration, comp, lookAt, easeOut, easeIn, ease, nearestKey, key, text, textIndex, textTotal, selectorValue, framesToTime, timeToFrames, sourceRectAtTime, substring, substr, posterizeTime, index, globalData];
+    return executeExpression;
+  }
+
+  ob.initiateExpression = initiateExpression;
+  ob.__preventDeadCodeRemoval = [window, document, XMLHttpRequest, fetch, frames, $bm_neg, add, $bm_sum, $bm_sub, $bm_mul, $bm_div, $bm_mod, clamp, radians_to_degrees, degreesToRadians, degrees_to_radians, normalize, rgbToHsl, hslToRgb, linear, random, createPath, _lottieGlobal];
+  ob.resetFrame = resetFrame;
+  return ob;
+}());
+
+const Expressions = (function () {
+  var ob = {};
+  ob.initExpressions = initExpressions;
+  ob.resetFrame = ExpressionManager.resetFrame;
+
+  function initExpressions(animation) {
+    var stackCount = 0;
+    var registers = [];
+
+    function pushExpression() {
+      stackCount += 1;
+    }
+
+    function popExpression() {
+      stackCount -= 1;
+      if (stackCount === 0) {
+        releaseInstances();
+      }
+    }
+
+    function registerExpressionProperty(expression) {
+      if (registers.indexOf(expression) === -1) {
+        registers.push(expression);
+      }
+    }
+
+    function releaseInstances() {
+      var i;
+      var len = registers.length;
+      for (i = 0; i < len; i += 1) {
+        registers[i].release();
+      }
+      registers.length = 0;
+    }
+
+    animation.renderer.compInterface = CompExpressionInterface(animation.renderer);
+    animation.renderer.globalData.projectInterface.registerComposition(animation.renderer);
+    animation.renderer.globalData.pushExpression = pushExpression;
+    animation.renderer.globalData.popExpression = popExpression;
+    animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty;
+  }
+  return ob;
+}());
+
+const MaskManagerInterface = (function () {
+  function MaskInterface(mask, data) {
+    this._mask = mask;
+    this._data = data;
+  }
+  Object.defineProperty(MaskInterface.prototype, 'maskPath', {
+    get: function () {
+      if (this._mask.prop.k) {
+        this._mask.prop.getValue();
+      }
+      return this._mask.prop;
+    },
+  });
+  Object.defineProperty(MaskInterface.prototype, 'maskOpacity', {
+    get: function () {
+      if (this._mask.op.k) {
+        this._mask.op.getValue();
+      }
+      return this._mask.op.v * 100;
+    },
+  });
+
+  var MaskManager = function (maskManager) {
+    var _masksInterfaces = createSizedArray(maskManager.viewData.length);
+    var i;
+    var len = maskManager.viewData.length;
+    for (i = 0; i < len; i += 1) {
+      _masksInterfaces[i] = new MaskInterface(maskManager.viewData[i], maskManager.masksProperties[i]);
+    }
+
+    var maskFunction = function (name) {
+      i = 0;
+      while (i < len) {
+        if (maskManager.masksProperties[i].nm === name) {
+          return _masksInterfaces[i];
+        }
+        i += 1;
+      }
+      return null;
+    };
+    return maskFunction;
+  };
+  return MaskManager;
+}());
+
+const ExpressionPropertyInterface = (function () {
+  var defaultUnidimensionalValue = { pv: 0, v: 0, mult: 1 };
+  var defaultMultidimensionalValue = { pv: [0, 0, 0], v: [0, 0, 0], mult: 1 };
+
+  function completeProperty(expressionValue, property, type) {
+    Object.defineProperty(expressionValue, 'velocity', {
+      get: function () {
+        return property.getVelocityAtTime(property.comp.currentFrame);
+      },
+    });
+    expressionValue.numKeys = property.keyframes ? property.keyframes.length : 0;
+    expressionValue.key = function (pos) {
+      if (!expressionValue.numKeys) {
+        return 0;
+      }
+      var value = '';
+      if ('s' in property.keyframes[pos - 1]) {
+        value = property.keyframes[pos - 1].s;
+      } else if ('e' in property.keyframes[pos - 2]) {
+        value = property.keyframes[pos - 2].e;
+      } else {
+        value = property.keyframes[pos - 2].s;
+      }
+      var valueProp = type === 'unidimensional' ? new Number(value) : Object.assign({}, value); // eslint-disable-line no-new-wrappers
+      valueProp.time = property.keyframes[pos - 1].t / property.elem.comp.globalData.frameRate;
+      valueProp.value = type === 'unidimensional' ? value[0] : value;
+      return valueProp;
+    };
+    expressionValue.valueAtTime = property.getValueAtTime;
+    expressionValue.speedAtTime = property.getSpeedAtTime;
+    expressionValue.velocityAtTime = property.getVelocityAtTime;
+    expressionValue.propertyGroup = property.propertyGroup;
+  }
+
+  function UnidimensionalPropertyInterface(property) {
+    if (!property || !('pv' in property)) {
+      property = defaultUnidimensionalValue;
+    }
+    var mult = 1 / property.mult;
+    var val = property.pv * mult;
+    var expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
+    expressionValue.value = val;
+    completeProperty(expressionValue, property, 'unidimensional');
+
+    return function () {
+      if (property.k) {
+        property.getValue();
+      }
+      val = property.v * mult;
+      if (expressionValue.value !== val) {
+        expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
+        expressionValue.value = val;
+        expressionValue[0] = val;
+        completeProperty(expressionValue, property, 'unidimensional');
+      }
+      return expressionValue;
+    };
+  }
+
+  function MultidimensionalPropertyInterface(property) {
+    if (!property || !('pv' in property)) {
+      property = defaultMultidimensionalValue;
+    }
+    var mult = 1 / property.mult;
+    var len = (property.data && property.data.l) || property.pv.length;
+    var expressionValue = createTypedArray('float32', len);
+    var arrValue = createTypedArray('float32', len);
+    expressionValue.value = arrValue;
+    completeProperty(expressionValue, property, 'multidimensional');
+
+    return function () {
+      if (property.k) {
+        property.getValue();
+      }
+      for (var i = 0; i < len; i += 1) {
+        arrValue[i] = property.v[i] * mult;
+        expressionValue[i] = arrValue[i];
+      }
+      return expressionValue;
+    };
+  }
+
+  // TODO: try to avoid using this getter
+  function defaultGetter() {
+    return defaultUnidimensionalValue;
+  }
+
+  return function (property) {
+    if (!property) {
+      return defaultGetter;
+    } if (property.propType === 'unidimensional') {
+      return UnidimensionalPropertyInterface(property);
+    }
+    return MultidimensionalPropertyInterface(property);
+  };
+}());
+
+const TransformExpressionInterface = (function () {
+  return function (transform) {
+    function _thisFunction(name) {
+      switch (name) {
+        case 'scale':
+        case 'Scale':
+        case 'ADBE Scale':
+        case 6:
+          return _thisFunction.scale;
+        case 'rotation':
+        case 'Rotation':
+        case 'ADBE Rotation':
+        case 'ADBE Rotate Z':
+        case 10:
+          return _thisFunction.rotation;
+        case 'ADBE Rotate X':
+          return _thisFunction.xRotation;
+        case 'ADBE Rotate Y':
+          return _thisFunction.yRotation;
+        case 'position':
+        case 'Position':
+        case 'ADBE Position':
+        case 2:
+          return _thisFunction.position;
+        case 'ADBE Position_0':
+          return _thisFunction.xPosition;
+        case 'ADBE Position_1':
+          return _thisFunction.yPosition;
+        case 'ADBE Position_2':
+          return _thisFunction.zPosition;
+        case 'anchorPoint':
+        case 'AnchorPoint':
+        case 'Anchor Point':
+        case 'ADBE AnchorPoint':
+        case 1:
+          return _thisFunction.anchorPoint;
+        case 'opacity':
+        case 'Opacity':
+        case 11:
+          return _thisFunction.opacity;
+        default:
+          return null;
+      }
+    }
+    Object.defineProperty(_thisFunction, 'rotation', {
+      get: ExpressionPropertyInterface(transform.r || transform.rz),
+    });
+
+    Object.defineProperty(_thisFunction, 'zRotation', {
+      get: ExpressionPropertyInterface(transform.rz || transform.r),
+    });
+
+    Object.defineProperty(_thisFunction, 'xRotation', {
+      get: ExpressionPropertyInterface(transform.rx),
+    });
+
+    Object.defineProperty(_thisFunction, 'yRotation', {
+      get: ExpressionPropertyInterface(transform.ry),
+    });
+    Object.defineProperty(_thisFunction, 'scale', {
+      get: ExpressionPropertyInterface(transform.s),
+    });
+    var _px;
+    var _py;
+    var _pz;
+    var _transformFactory;
+    if (transform.p) {
+      _transformFactory = ExpressionPropertyInterface(transform.p);
+    } else {
+      _px = ExpressionPropertyInterface(transform.px);
+      _py = ExpressionPropertyInterface(transform.py);
+      if (transform.pz) {
+        _pz = ExpressionPropertyInterface(transform.pz);
+      }
+    }
+    Object.defineProperty(_thisFunction, 'position', {
+      get: function () {
+        if (transform.p) {
+          return _transformFactory();
+        }
+        return [
+          _px(),
+          _py(),
+          _pz ? _pz() : 0];
+      },
+    });
+
+    Object.defineProperty(_thisFunction, 'xPosition', {
+      get: ExpressionPropertyInterface(transform.px),
+    });
+
+    Object.defineProperty(_thisFunction, 'yPosition', {
+      get: ExpressionPropertyInterface(transform.py),
+    });
+
+    Object.defineProperty(_thisFunction, 'zPosition', {
+      get: ExpressionPropertyInterface(transform.pz),
+    });
+
+    Object.defineProperty(_thisFunction, 'anchorPoint', {
+      get: ExpressionPropertyInterface(transform.a),
+    });
+
+    Object.defineProperty(_thisFunction, 'opacity', {
+      get: ExpressionPropertyInterface(transform.o),
+    });
+
+    Object.defineProperty(_thisFunction, 'skew', {
+      get: ExpressionPropertyInterface(transform.sk),
+    });
+
+    Object.defineProperty(_thisFunction, 'skewAxis', {
+      get: ExpressionPropertyInterface(transform.sa),
+    });
+
+    Object.defineProperty(_thisFunction, 'orientation', {
+      get: ExpressionPropertyInterface(transform.or),
+    });
+
+    return _thisFunction;
+  };
+}());
+
+const LayerExpressionInterface = (function () {
+  function getMatrix(time) {
+    var toWorldMat = new Matrix();
+    if (time !== undefined) {
+      var propMatrix = this._elem.finalTransform.mProp.getValueAtTime(time);
+      propMatrix.clone(toWorldMat);
+    } else {
+      var transformMat = this._elem.finalTransform.mProp;
+      transformMat.applyToMatrix(toWorldMat);
+    }
+    return toWorldMat;
+  }
+
+  function toWorldVec(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    toWorldMat.props[12] = 0;
+    toWorldMat.props[13] = 0;
+    toWorldMat.props[14] = 0;
+    return this.applyPoint(toWorldMat, arr);
+  }
+
+  function toWorld(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    return this.applyPoint(toWorldMat, arr);
+  }
+
+  function fromWorldVec(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    toWorldMat.props[12] = 0;
+    toWorldMat.props[13] = 0;
+    toWorldMat.props[14] = 0;
+    return this.invertPoint(toWorldMat, arr);
+  }
+
+  function fromWorld(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    return this.invertPoint(toWorldMat, arr);
+  }
+
+  function applyPoint(matrix, arr) {
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
+      }
+    }
+    return matrix.applyToPointArray(arr[0], arr[1], arr[2] || 0);
+  }
+
+  function invertPoint(matrix, arr) {
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
+      }
+    }
+    return matrix.inversePoint(arr);
+  }
+
+  function fromComp(arr) {
+    var toWorldMat = new Matrix();
+    toWorldMat.reset();
+    this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
+      }
+      return toWorldMat.inversePoint(arr);
+    }
+    return toWorldMat.inversePoint(arr);
+  }
+
+  function sampleImage() {
+    return [1, 1, 1, 1];
+  }
+
+  return function (elem) {
+    var transformInterface;
+
+    function _registerMaskInterface(maskManager) {
+      _thisLayerFunction.mask = new MaskManagerInterface(maskManager, elem);
+    }
+    function _registerEffectsInterface(effects) {
+      _thisLayerFunction.effect = effects;
+    }
+
+    function _thisLayerFunction(name) {
+      switch (name) {
+        case 'ADBE Root Vectors Group':
+        case 'Contents':
+        case 2:
+          return _thisLayerFunction.shapeInterface;
+        case 1:
+        case 6:
+        case 'Transform':
+        case 'transform':
+        case 'ADBE Transform Group':
+          return transformInterface;
+        case 4:
+        case 'ADBE Effect Parade':
+        case 'effects':
+        case 'Effects':
+          return _thisLayerFunction.effect;
+        case 'ADBE Text Properties':
+          return _thisLayerFunction.textInterface;
+        default:
+          return null;
+      }
+    }
+    _thisLayerFunction.getMatrix = getMatrix;
+    _thisLayerFunction.invertPoint = invertPoint;
+    _thisLayerFunction.applyPoint = applyPoint;
+    _thisLayerFunction.toWorld = toWorld;
+    _thisLayerFunction.toWorldVec = toWorldVec;
+    _thisLayerFunction.fromWorld = fromWorld;
+    _thisLayerFunction.fromWorldVec = fromWorldVec;
+    _thisLayerFunction.toComp = toWorld;
+    _thisLayerFunction.fromComp = fromComp;
+    _thisLayerFunction.sampleImage = sampleImage;
+    _thisLayerFunction.sourceRectAtTime = elem.sourceRectAtTime.bind(elem);
+    _thisLayerFunction._elem = elem;
+    transformInterface = TransformExpressionInterface(elem.finalTransform.mProp);
+    var anchorPointDescriptor = getDescriptor(transformInterface, 'anchorPoint');
+    Object.defineProperties(_thisLayerFunction, {
+      hasParent: {
+        get: function () {
+          return elem.hierarchy.length;
+        },
+      },
+      parent: {
+        get: function () {
+          return elem.hierarchy[0].layerInterface;
+        },
+      },
+      rotation: getDescriptor(transformInterface, 'rotation'),
+      scale: getDescriptor(transformInterface, 'scale'),
+      position: getDescriptor(transformInterface, 'position'),
+      opacity: getDescriptor(transformInterface, 'opacity'),
+      anchorPoint: anchorPointDescriptor,
+      anchor_point: anchorPointDescriptor,
+      transform: {
+        get: function () {
+          return transformInterface;
+        },
+      },
+      active: {
+        get: function () {
+          return elem.isInRange;
+        },
+      },
+    });
+
+    _thisLayerFunction.startTime = elem.data.st;
+    _thisLayerFunction.index = elem.data.ind;
+    _thisLayerFunction.source = elem.data.refId;
+    _thisLayerFunction.height = elem.data.ty === 0 ? elem.data.h : 100;
+    _thisLayerFunction.width = elem.data.ty === 0 ? elem.data.w : 100;
+    _thisLayerFunction.inPoint = elem.data.ip / elem.comp.globalData.frameRate;
+    _thisLayerFunction.outPoint = elem.data.op / elem.comp.globalData.frameRate;
+    _thisLayerFunction._name = elem.data.nm;
+
+    _thisLayerFunction.registerMaskInterface = _registerMaskInterface;
+    _thisLayerFunction.registerEffectsInterface = _registerEffectsInterface;
+    return _thisLayerFunction;
+  };
+}());
+
+const propertyGroupFactory = (function () {
+  return function (interfaceFunction, parentPropertyGroup) {
+    return function (val) {
+      val = val === undefined ? 1 : val;
+      if (val <= 0) {
+        return interfaceFunction;
+      }
+      return parentPropertyGroup(val - 1);
+    };
+  };
+}());
+
+const PropertyInterface = (function () {
+  return function (propertyName, propertyGroup) {
+    var interfaceFunction = {
+      _name: propertyName,
+    };
+
+    function _propertyGroup(val) {
+      val = val === undefined ? 1 : val;
+      if (val <= 0) {
+        return interfaceFunction;
+      }
+      return propertyGroup(val - 1);
+    }
+
+    return _propertyGroup;
+  };
+}());
+
+const EffectsExpressionInterface = (function () {
+  var ob = {
+    createEffectsInterface: createEffectsInterface,
+  };
+
+  function createEffectsInterface(elem, propertyGroup) {
+    if (elem.effectsManager) {
+      var effectElements = [];
+      var effectsData = elem.data.ef;
+      var i;
+      var len = elem.effectsManager.effectElements.length;
+      for (i = 0; i < len; i += 1) {
+        effectElements.push(createGroupInterface(effectsData[i], elem.effectsManager.effectElements[i], propertyGroup, elem));
+      }
+
+      var effects = elem.data.ef || [];
+      var groupInterface = function (name) {
+        i = 0;
+        len = effects.length;
+        while (i < len) {
+          if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
+            return effectElements[i];
+          }
+          i += 1;
+        }
+        return null;
+      };
+      Object.defineProperty(groupInterface, 'numProperties', {
+        get: function () {
+          return effects.length;
+        },
+      });
+      return groupInterface;
+    }
+    return null;
+  }
+
+  function createGroupInterface(data, elements, propertyGroup, elem) {
+    function groupInterface(name) {
+      var effects = data.ef;
+      var i = 0;
+      var len = effects.length;
+      while (i < len) {
+        if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
+          if (effects[i].ty === 5) {
+            return effectElements[i];
+          }
+          return effectElements[i]();
+        }
+        i += 1;
+      }
+      throw new Error();
+    }
+    var _propertyGroup = propertyGroupFactory(groupInterface, propertyGroup);
+
+    var effectElements = [];
+    var i;
+    var len = data.ef.length;
+    for (i = 0; i < len; i += 1) {
+      if (data.ef[i].ty === 5) {
+        effectElements.push(createGroupInterface(data.ef[i], elements.effectElements[i], elements.effectElements[i].propertyGroup, elem));
+      } else {
+        effectElements.push(createValueInterface(elements.effectElements[i], data.ef[i].ty, elem, _propertyGroup));
+      }
+    }
+
+    if (data.mn === 'ADBE Color Control') {
+      Object.defineProperty(groupInterface, 'color', {
+        get: function () {
+          return effectElements[0]();
+        },
+      });
+    }
+    Object.defineProperties(groupInterface, {
+      numProperties: {
+        get: function () {
+          return data.np;
+        },
+      },
+      _name: { value: data.nm },
+      propertyGroup: { value: _propertyGroup },
+    });
+    groupInterface.enabled = data.en !== 0;
+    groupInterface.active = groupInterface.enabled;
+    return groupInterface;
+  }
+
+  function createValueInterface(element, type, elem, propertyGroup) {
+    var expressionProperty = ExpressionPropertyInterface(element.p);
+    function interfaceFunction() {
+      if (type === 10) {
+        return elem.comp.compInterface(element.p.v);
+      }
+      return expressionProperty();
+    }
+
+    if (element.p.setGroupProperty) {
+      element.p.setGroupProperty(PropertyInterface('', propertyGroup));
+    }
+
+    return interfaceFunction;
+  }
+
+  return ob;
+}());
+
+const ShapePathInterface = (
+
+  function () {
+    return function pathInterfaceFactory(shape, view, propertyGroup) {
+      var prop = view.sh;
+
+      function interfaceFunction(val) {
+        if (val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2) {
+          return interfaceFunction.path;
+        }
+        return null;
+      }
+
+      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+      prop.setGroupProperty(PropertyInterface('Path', _propertyGroup));
+      Object.defineProperties(interfaceFunction, {
+        path: {
+          get: function () {
+            if (prop.k) {
+              prop.getValue();
+            }
+            return prop;
+          },
+        },
+        shape: {
+          get: function () {
+            if (prop.k) {
+              prop.getValue();
+            }
+            return prop;
+          },
+        },
+        _name: { value: shape.nm },
+        ix: { value: shape.ix },
+        propertyIndex: { value: shape.ix },
+        mn: { value: shape.mn },
+        propertyGroup: { value: propertyGroup },
+      });
+      return interfaceFunction;
+    };
+  }()
+);
+
+const ShapeExpressionInterface = (function () {
+  function iterateElements(shapes, view, propertyGroup) {
+    var arr = [];
+    var i;
+    var len = shapes ? shapes.length : 0;
+    for (i = 0; i < len; i += 1) {
+      if (shapes[i].ty === 'gr') {
+        arr.push(groupInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'fl') {
+        arr.push(fillInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'st') {
+        arr.push(strokeInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'tm') {
+        arr.push(trimInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'tr') {
+        // arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
+      } else if (shapes[i].ty === 'el') {
+        arr.push(ellipseInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'sr') {
+        arr.push(starInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'sh') {
+        arr.push(ShapePathInterface(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'rc') {
+        arr.push(rectInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'rd') {
+        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;
+  }
+
+  function contentsInterfaceFactory(shape, view, propertyGroup) {
+    var interfaces;
+    var interfaceFunction = function _interfaceFunction(value) {
+      var i = 0;
+      var len = interfaces.length;
+      while (i < len) {
+        if (interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value) {
+          return interfaces[i];
+        }
+        i += 1;
+      }
+      if (typeof value === 'number') {
+        return interfaces[value - 1];
+      }
+      return null;
+    };
+
+    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup);
+    interfaceFunction.numProperties = interfaces.length;
+    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
+    interfaceFunction.transform = transformInterface;
+    interfaceFunction.propertyIndex = shape.cix;
+    interfaceFunction._name = shape.nm;
+
+    return interfaceFunction;
+  }
+
+  function groupInterfaceFactory(shape, view, propertyGroup) {
+    var interfaceFunction = function _interfaceFunction(value) {
+      switch (value) {
+        case 'ADBE Vectors Group':
+        case 'Contents':
+        case 2:
+          return interfaceFunction.content;
+          // Not necessary for now. Keeping them here in case a new case appears
+          // case 'ADBE Vector Transform Group':
+          // case 3:
+        default:
+          return interfaceFunction.transform;
+      }
+    };
+    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var content = contentsInterfaceFactory(shape, view, interfaceFunction.propertyGroup);
+    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
+    interfaceFunction.content = content;
+    interfaceFunction.transform = transformInterface;
+    Object.defineProperty(interfaceFunction, '_name', {
+      get: function () {
+        return shape.nm;
+      },
+    });
+    // interfaceFunction.content = interfaceFunction;
+    interfaceFunction.numProperties = shape.np;
+    interfaceFunction.propertyIndex = shape.ix;
+    interfaceFunction.nm = shape.nm;
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function fillInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      if (val === 'Color' || val === 'color') {
+        return interfaceFunction.color;
+      } if (val === 'Opacity' || val === 'opacity') {
+        return interfaceFunction.opacity;
+      }
+      return null;
+    }
+    Object.defineProperties(interfaceFunction, {
+      color: {
+        get: ExpressionPropertyInterface(view.c),
+      },
+      opacity: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      _name: { value: shape.nm },
+      mn: { value: shape.mn },
+    });
+
+    view.c.setGroupProperty(PropertyInterface('Color', propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
+    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 () {
+          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() {
+    function interfaceFunction() {
+      return null;
+    }
+    return interfaceFunction;
+  }
+
+  function strokeInterfaceFactory(shape, view, propertyGroup) {
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup);
+    function addPropertyToDashOb(i) {
+      Object.defineProperty(dashOb, shape.d[i].nm, {
+        get: ExpressionPropertyInterface(view.d.dataProps[i].p),
+      });
+    }
+    var i;
+    var len = shape.d ? shape.d.length : 0;
+    var dashOb = {};
+    for (i = 0; i < len; i += 1) {
+      addPropertyToDashOb(i);
+      view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup);
+    }
+
+    function interfaceFunction(val) {
+      if (val === 'Color' || val === 'color') {
+        return interfaceFunction.color;
+      } if (val === 'Opacity' || val === 'opacity') {
+        return interfaceFunction.opacity;
+      } if (val === 'Stroke Width' || val === 'stroke width') {
+        return interfaceFunction.strokeWidth;
+      }
+      return null;
+    }
+    Object.defineProperties(interfaceFunction, {
+      color: {
+        get: ExpressionPropertyInterface(view.c),
+      },
+      opacity: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      strokeWidth: {
+        get: ExpressionPropertyInterface(view.w),
+      },
+      dash: {
+        get: function () {
+          return dashOb;
+        },
+      },
+      _name: { value: shape.nm },
+      mn: { value: shape.mn },
+    });
+
+    view.c.setGroupProperty(PropertyInterface('Color', _propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    view.w.setGroupProperty(PropertyInterface('Stroke Width', _propertyGroup));
+    return interfaceFunction;
+  }
+
+  function trimInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      if (val === shape.e.ix || val === 'End' || val === 'end') {
+        return interfaceFunction.end;
+      }
+      if (val === shape.s.ix) {
+        return interfaceFunction.start;
+      }
+      if (val === shape.o.ix) {
+        return interfaceFunction.offset;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaceFunction.propertyIndex = shape.ix;
+
+    view.s.setGroupProperty(PropertyInterface('Start', _propertyGroup));
+    view.e.setGroupProperty(PropertyInterface('End', _propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
+    interfaceFunction.propertyIndex = shape.ix;
+    interfaceFunction.propertyGroup = propertyGroup;
+
+    Object.defineProperties(interfaceFunction, {
+      start: {
+        get: ExpressionPropertyInterface(view.s),
+      },
+      end: {
+        get: ExpressionPropertyInterface(view.e),
+      },
+      offset: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function transformInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.a.ix === value || value === 'Anchor Point') {
+        return interfaceFunction.anchorPoint;
+      }
+      if (shape.o.ix === value || value === 'Opacity') {
+        return interfaceFunction.opacity;
+      }
+      if (shape.p.ix === value || value === 'Position') {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value || value === 'Rotation' || value === 'ADBE Vector Rotation') {
+        return interfaceFunction.rotation;
+      }
+      if (shape.s.ix === value || value === 'Scale') {
+        return interfaceFunction.scale;
+      }
+      if ((shape.sk && shape.sk.ix === value) || value === 'Skew') {
+        return interfaceFunction.skew;
+      }
+      if ((shape.sa && shape.sa.ix === value) || value === 'Skew Axis') {
+        return interfaceFunction.skewAxis;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    view.transform.mProps.a.setGroupProperty(PropertyInterface('Anchor Point', _propertyGroup));
+    view.transform.mProps.s.setGroupProperty(PropertyInterface('Scale', _propertyGroup));
+    view.transform.mProps.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+    if (view.transform.mProps.sk) {
+      view.transform.mProps.sk.setGroupProperty(PropertyInterface('Skew', _propertyGroup));
+      view.transform.mProps.sa.setGroupProperty(PropertyInterface('Skew Angle', _propertyGroup));
+    }
+    view.transform.op.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    Object.defineProperties(interfaceFunction, {
+      opacity: {
+        get: ExpressionPropertyInterface(view.transform.mProps.o),
+      },
+      position: {
+        get: ExpressionPropertyInterface(view.transform.mProps.p),
+      },
+      anchorPoint: {
+        get: ExpressionPropertyInterface(view.transform.mProps.a),
+      },
+      scale: {
+        get: ExpressionPropertyInterface(view.transform.mProps.s),
+      },
+      rotation: {
+        get: ExpressionPropertyInterface(view.transform.mProps.r),
+      },
+      skew: {
+        get: ExpressionPropertyInterface(view.transform.mProps.sk),
+      },
+      skewAxis: {
+        get: ExpressionPropertyInterface(view.transform.mProps.sa),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.ty = 'tr';
+    interfaceFunction.mn = shape.mn;
+    interfaceFunction.propertyGroup = propertyGroup;
+    return interfaceFunction;
+  }
+
+  function ellipseInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.s.ix === value) {
+        return interfaceFunction.size;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaceFunction.propertyIndex = shape.ix;
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      size: {
+        get: ExpressionPropertyInterface(prop.s),
+      },
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function starInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value) {
+        return interfaceFunction.rotation;
+      }
+      if (shape.pt.ix === value) {
+        return interfaceFunction.points;
+      }
+      if (shape.or.ix === value || value === 'ADBE Vector Star Outer Radius') {
+        return interfaceFunction.outerRadius;
+      }
+      if (shape.os.ix === value) {
+        return interfaceFunction.outerRoundness;
+      }
+      if (shape.ir && (shape.ir.ix === value || value === 'ADBE Vector Star Inner Radius')) {
+        return interfaceFunction.innerRadius;
+      }
+      if (shape.is && shape.is.ix === value) {
+        return interfaceFunction.innerRoundness;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.or.setGroupProperty(PropertyInterface('Outer Radius', _propertyGroup));
+    prop.os.setGroupProperty(PropertyInterface('Outer Roundness', _propertyGroup));
+    prop.pt.setGroupProperty(PropertyInterface('Points', _propertyGroup));
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+    if (shape.ir) {
+      prop.ir.setGroupProperty(PropertyInterface('Inner Radius', _propertyGroup));
+      prop.is.setGroupProperty(PropertyInterface('Inner Roundness', _propertyGroup));
+    }
+
+    Object.defineProperties(interfaceFunction, {
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      rotation: {
+        get: ExpressionPropertyInterface(prop.r),
+      },
+      points: {
+        get: ExpressionPropertyInterface(prop.pt),
+      },
+      outerRadius: {
+        get: ExpressionPropertyInterface(prop.or),
+      },
+      outerRoundness: {
+        get: ExpressionPropertyInterface(prop.os),
+      },
+      innerRadius: {
+        get: ExpressionPropertyInterface(prop.ir),
+      },
+      innerRoundness: {
+        get: ExpressionPropertyInterface(prop.is),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function rectInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value) {
+        return interfaceFunction.roundness;
+      }
+      if (shape.s.ix === value || value === 'Size' || value === 'ADBE Vector Rect Size') {
+        return interfaceFunction.size;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
+    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      roundness: {
+        get: ExpressionPropertyInterface(prop.r),
+      },
+      size: {
+        get: ExpressionPropertyInterface(prop.s),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function roundedInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.r.ix === value || value === 'Round Corners 1') {
+        return interfaceFunction.radius;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.rd.setGroupProperty(PropertyInterface('Radius', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      radius: {
+        get: ExpressionPropertyInterface(prop.rd),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function repeaterInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.c.ix === value || value === 'Copies') {
+        return interfaceFunction.copies;
+      } if (shape.o.ix === value || value === 'Offset') {
+        return interfaceFunction.offset;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.c.setGroupProperty(PropertyInterface('Copies', _propertyGroup));
+    prop.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
+    Object.defineProperties(interfaceFunction, {
+      copies: {
+        get: ExpressionPropertyInterface(prop.c),
+      },
+      offset: {
+        get: ExpressionPropertyInterface(prop.o),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  return function (shapes, view, propertyGroup) {
+    var interfaces;
+    function _interfaceFunction(value) {
+      if (typeof value === 'number') {
+        value = value === undefined ? 1 : value;
+        if (value === 0) {
+          return propertyGroup;
+        }
+        return interfaces[value - 1];
+      }
+      var i = 0;
+      var len = interfaces.length;
+      while (i < len) {
+        if (interfaces[i]._name === value) {
+          return interfaces[i];
+        }
+        i += 1;
+      }
+      return null;
+    }
+    function parentGroupWrapper() {
+      return propertyGroup;
+    }
+    _interfaceFunction.propertyGroup = propertyGroupFactory(_interfaceFunction, parentGroupWrapper);
+    interfaces = iterateElements(shapes, view, _interfaceFunction.propertyGroup);
+    _interfaceFunction.numProperties = interfaces.length;
+    _interfaceFunction._name = 'Contents';
+    return _interfaceFunction;
+  };
+}());
+
+const TextExpressionInterface = (function () {
+  return function (elem) {
+    var _sourceText;
+    function _thisLayerFunction(name) {
+      switch (name) {
+        case 'ADBE Text Document':
+          return _thisLayerFunction.sourceText;
+        default:
+          return null;
+      }
+    }
+    Object.defineProperty(_thisLayerFunction, 'sourceText', {
+      get: function () {
+        elem.textProperty.getValue();
+        var stringValue = elem.textProperty.currentData.t;
+        if (!_sourceText || stringValue !== _sourceText.value) {
+          _sourceText = new String(stringValue); // eslint-disable-line no-new-wrappers
+          // If stringValue is an empty string, eval returns undefined, so it has to be returned as a String primitive
+          _sourceText.value = stringValue || new String(stringValue); // eslint-disable-line no-new-wrappers
+          Object.defineProperty(_sourceText, 'style', {
+            get: function () {
+              return {
+                fillColor: elem.textProperty.currentData.fc,
+              };
+            },
+          });
+        }
+        return _sourceText;
+      },
+    });
+    return _thisLayerFunction;
+  };
+}());
+
+const FootageInterface = (function () {
+  var outlineInterfaceFactory = (function (elem) {
+    var currentPropertyName = '';
+    var currentProperty = elem.getFootageData();
+    function init() {
+      currentPropertyName = '';
+      currentProperty = elem.getFootageData();
+      return searchProperty;
+    }
+    function searchProperty(value) {
+      if (currentProperty[value]) {
+        currentPropertyName = value;
+        currentProperty = currentProperty[value];
+        if (typeof currentProperty === 'object') {
+          return searchProperty;
+        }
+        return currentProperty;
+      }
+      var propertyNameIndex = value.indexOf(currentPropertyName);
+      if (propertyNameIndex !== -1) {
+        var index = parseInt(value.substr(propertyNameIndex + currentPropertyName.length), 10);
+        currentProperty = currentProperty[index];
+        if (typeof currentProperty === 'object') {
+          return searchProperty;
+        }
+        return currentProperty;
+      }
+      return '';
+    }
+    return init;
+  });
+
+  var dataInterfaceFactory = function (elem) {
+    function interfaceFunction(value) {
+      if (value === 'Outline') {
+        return interfaceFunction.outlineInterface();
+      }
+      return null;
+    }
+
+    interfaceFunction._name = 'Outline';
+    interfaceFunction.outlineInterface = outlineInterfaceFactory(elem);
+    return interfaceFunction;
+  };
+
+  return function (elem) {
+    function _interfaceFunction(value) {
+      if (value === 'Data') {
+        return _interfaceFunction.dataInterface;
+      }
+      return null;
+    }
+
+    _interfaceFunction._name = 'Data';
+    _interfaceFunction.dataInterface = dataInterfaceFactory(elem);
+    return _interfaceFunction;
+  };
+}());
+
+var interfaces = {
+  layer: LayerExpressionInterface,
+  effects: EffectsExpressionInterface,
+  comp: CompExpressionInterface,
+  shape: ShapeExpressionInterface,
+  text: TextExpressionInterface,
+  footage: FootageInterface,
+};
+
+function getInterface(type) {
+  return interfaces[type] || null;
+}
+
+const expressionHelpers = (function () {
+  function searchExpressions(elem, data, prop) {
+    if (data.x) {
+      prop.k = true;
+      prop.x = true;
+      prop.initiateExpression = ExpressionManager.initiateExpression;
+      prop.effectsSequence.push(prop.initiateExpression(elem, data, prop).bind(prop));
+    }
+  }
+
+  function getValueAtTime(frameNum) {
+    frameNum *= this.elem.globalData.frameRate;
+    frameNum -= this.offsetTime;
+    if (frameNum !== this._cachingAtTime.lastFrame) {
+      this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0;
+      this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime);
+      this._cachingAtTime.lastFrame = frameNum;
+    }
+    return this._cachingAtTime.value;
+  }
+
+  function getSpeedAtTime(frameNum) {
+    var delta = -0.01;
+    var v1 = this.getValueAtTime(frameNum);
+    var v2 = this.getValueAtTime(frameNum + delta);
+    var speed = 0;
+    if (v1.length) {
+      var i;
+      for (i = 0; i < v1.length; i += 1) {
+        speed += Math.pow(v2[i] - v1[i], 2);
+      }
+      speed = Math.sqrt(speed) * 100;
+    } else {
+      speed = 0;
+    }
+    return speed;
+  }
+
+  function getVelocityAtTime(frameNum) {
+    if (this.vel !== undefined) {
+      return this.vel;
+    }
+    var delta = -0.001;
+    // frameNum += this.elem.data.st;
+    var v1 = this.getValueAtTime(frameNum);
+    var v2 = this.getValueAtTime(frameNum + delta);
+    var velocity;
+    if (v1.length) {
+      velocity = createTypedArray('float32', v1.length);
+      var i;
+      for (i = 0; i < v1.length; i += 1) {
+        // removing frameRate
+        // if needed, don't add it here
+        // velocity[i] = this.elem.globalData.frameRate*((v2[i] - v1[i])/delta);
+        velocity[i] = (v2[i] - v1[i]) / delta;
+      }
+    } else {
+      velocity = (v2 - v1) / delta;
+    }
+    return velocity;
+  }
+
+  function getStaticValueAtTime() {
+    return this.pv;
+  }
+
+  function setGroupProperty(propertyGroup) {
+    this.propertyGroup = propertyGroup;
+  }
+
+  return {
+    searchExpressions: searchExpressions,
+    getSpeedAtTime: getSpeedAtTime,
+    getVelocityAtTime: getVelocityAtTime,
+    getValueAtTime: getValueAtTime,
+    getStaticValueAtTime: getStaticValueAtTime,
+    setGroupProperty: setGroupProperty,
+  };
+}());
+
+function addPropertyDecorator() {
+  function loopOut(type, duration, durationFlag) {
+    if (!this.k || !this.keyframes) {
+      return this.pv;
+    }
+    type = type ? type.toLowerCase() : '';
+    var currentFrame = this.comp.renderedFrame;
+    var keyframes = this.keyframes;
+    var lastKeyFrame = keyframes[keyframes.length - 1].t;
+    if (currentFrame <= lastKeyFrame) {
+      return this.pv;
+    }
+    var cycleDuration;
+    var firstKeyFrame;
+    if (!durationFlag) {
+      if (!duration || duration > keyframes.length - 1) {
+        duration = keyframes.length - 1;
+      }
+      firstKeyFrame = keyframes[keyframes.length - 1 - duration].t;
+      cycleDuration = lastKeyFrame - firstKeyFrame;
+    } else {
+      if (!duration) {
+        cycleDuration = Math.max(0, lastKeyFrame - this.elem.data.ip);
+      } else {
+        cycleDuration = Math.abs(lastKeyFrame - this.elem.comp.globalData.frameRate * duration);
+      }
+      firstKeyFrame = lastKeyFrame - cycleDuration;
+    }
+    var i;
+    var len;
+    var ret;
+    if (type === 'pingpong') {
+      var iterations = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
+      if (iterations % 2 !== 0) {
+          return this.getValueAtTime(((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      }
+    } else if (type === 'offset') {
+      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+        var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      var repeats = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
+      if (this.pv.length) {
+        ret = new Array(initV.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = (endV[i] - initV[i]) * repeats + current[i];
+        }
+        return ret;
+      }
+      return (endV - initV) * repeats + current;
+    } else if (type === 'continue') {
+      var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+      var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0);
+      if (this.pv.length) {
+        ret = new Array(lastValue.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+            ret[i] = lastValue[i] + (lastValue[i] - nextLastValue[i]) * ((currentFrame - lastKeyFrame) / this.comp.globalData.frameRate) / 0.0005; // eslint-disable-line
+        }
+        return ret;
+      }
+      return lastValue + (lastValue - nextLastValue) * (((currentFrame - lastKeyFrame)) / 0.001);
+    }
+      return this.getValueAtTime((((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+
+  }
+
+  function loopIn(type, duration, durationFlag) {
+    if (!this.k) {
+      return this.pv;
+    }
+    type = type ? type.toLowerCase() : '';
+    var currentFrame = this.comp.renderedFrame;
+    var keyframes = this.keyframes;
+    var firstKeyFrame = keyframes[0].t;
+    if (currentFrame >= firstKeyFrame) {
+      return this.pv;
+    }
+    var cycleDuration;
+    var lastKeyFrame;
+    if (!durationFlag) {
+      if (!duration || duration > keyframes.length - 1) {
+        duration = keyframes.length - 1;
+      }
+      lastKeyFrame = keyframes[duration].t;
+      cycleDuration = lastKeyFrame - firstKeyFrame;
+    } else {
+      if (!duration) {
+        cycleDuration = Math.max(0, this.elem.data.op - firstKeyFrame);
+      } else {
+        cycleDuration = Math.abs(this.elem.comp.globalData.frameRate * duration);
+      }
+      lastKeyFrame = firstKeyFrame + cycleDuration;
+    }
+    var i;
+    var len;
+    var ret;
+    if (type === 'pingpong') {
+      var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration);
+      if (iterations % 2 === 0) {
+          return this.getValueAtTime((((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      }
+    } else if (type === 'offset') {
+      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+      var current = this.getValueAtTime((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration) + firstKeyFrame) / this.comp.globalData.frameRate, 0);
+      var repeats = Math.floor((firstKeyFrame - currentFrame) / cycleDuration) + 1;
+      if (this.pv.length) {
+        ret = new Array(initV.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = current[i] - (endV[i] - initV[i]) * repeats;
+        }
+        return ret;
+      }
+      return current - (endV - initV) * repeats;
+    } else if (type === 'continue') {
+      var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0);
+      if (this.pv.length) {
+        ret = new Array(firstValue.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = firstValue[i] + ((firstValue[i] - nextFirstValue[i]) * (firstKeyFrame - currentFrame)) / 0.001;
+        }
+        return ret;
+      }
+      return firstValue + ((firstValue - nextFirstValue) * (firstKeyFrame - currentFrame)) / 0.001;
+    }
+      return this.getValueAtTime(((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame))) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+
+  }
+
+  function smooth(width, samples) {
+    if (!this.k) {
+      return this.pv;
+    }
+    width = (width || 0.4) * 0.5;
+    samples = Math.floor(samples || 5);
+    if (samples <= 1) {
+      return this.pv;
+    }
+    var currentTime = this.comp.renderedFrame / this.comp.globalData.frameRate;
+    var initFrame = currentTime - width;
+    var endFrame = currentTime + width;
+    var sampleFrequency = samples > 1 ? (endFrame - initFrame) / (samples - 1) : 1;
+    var i = 0;
+    var j = 0;
+    var value;
+    if (this.pv.length) {
+      value = createTypedArray('float32', this.pv.length);
+    } else {
+      value = 0;
+    }
+    var sampleValue;
+    while (i < samples) {
+      sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency);
+      if (this.pv.length) {
+        for (j = 0; j < this.pv.length; j += 1) {
+          value[j] += sampleValue[j];
+        }
+      } else {
+        value += sampleValue;
+      }
+      i += 1;
+    }
+    if (this.pv.length) {
+      for (j = 0; j < this.pv.length; j += 1) {
+        value[j] /= samples;
+      }
+    } else {
+      value /= samples;
+    }
+    return value;
+  }
+
+  function getTransformValueAtTime(time) {
+    if (!this._transformCachingAtTime) {
+      this._transformCachingAtTime = {
+        v: new Matrix(),
+      };
+    }
+    /// /
+    var matrix = this._transformCachingAtTime.v;
+    matrix.cloneFromProps(this.pre.props);
+    if (this.appliedTransformations < 1) {
+      var anchor = this.a.getValueAtTime(time);
+      matrix.translate(
+        -anchor[0] * this.a.mult,
+        -anchor[1] * this.a.mult,
+        anchor[2] * this.a.mult
+      );
+    }
+    if (this.appliedTransformations < 2) {
+      var scale = this.s.getValueAtTime(time);
+      matrix.scale(
+        scale[0] * this.s.mult,
+        scale[1] * this.s.mult,
+        scale[2] * this.s.mult
+      );
+    }
+    if (this.sk && this.appliedTransformations < 3) {
+      var skew = this.sk.getValueAtTime(time);
+      var skewAxis = this.sa.getValueAtTime(time);
+      matrix.skewFromAxis(-skew * this.sk.mult, skewAxis * this.sa.mult);
+    }
+    if (this.r && this.appliedTransformations < 4) {
+      var rotation = this.r.getValueAtTime(time);
+      matrix.rotate(-rotation * this.r.mult);
+    } else if (!this.r && this.appliedTransformations < 4) {
+      var rotationZ = this.rz.getValueAtTime(time);
+      var rotationY = this.ry.getValueAtTime(time);
+      var rotationX = this.rx.getValueAtTime(time);
+      var orientation = this.or.getValueAtTime(time);
+      matrix.rotateZ(-rotationZ * this.rz.mult)
+        .rotateY(rotationY * this.ry.mult)
+        .rotateX(rotationX * this.rx.mult)
+        .rotateZ(-orientation[2] * this.or.mult)
+        .rotateY(orientation[1] * this.or.mult)
+        .rotateX(orientation[0] * this.or.mult);
+    }
+    if (this.data.p && this.data.p.s) {
+      var positionX = this.px.getValueAtTime(time);
+      var positionY = this.py.getValueAtTime(time);
+      if (this.data.p.z) {
+        var positionZ = this.pz.getValueAtTime(time);
+        matrix.translate(
+          positionX * this.px.mult,
+          positionY * this.py.mult,
+          -positionZ * this.pz.mult
+        );
+      } else {
+        matrix.translate(positionX * this.px.mult, positionY * this.py.mult, 0);
+      }
+    } else {
+      var position = this.p.getValueAtTime(time);
+      matrix.translate(
+        position[0] * this.p.mult,
+        position[1] * this.p.mult,
+        -position[2] * this.p.mult
+      );
+    }
+    return matrix;
+    /// /
+  }
+
+  function getTransformStaticValueAtTime() {
+    return this.v.clone(new Matrix());
+  }
+
+  var getTransformProperty = TransformPropertyFactory.getTransformProperty;
+  TransformPropertyFactory.getTransformProperty = function (elem, data, container) {
+    var prop = getTransformProperty(elem, data, container);
+    if (prop.dynamicProperties.length) {
+      prop.getValueAtTime = getTransformValueAtTime.bind(prop);
+    } else {
+      prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop);
+    }
+    prop.setGroupProperty = expressionHelpers.setGroupProperty;
+    return prop;
+  };
+
+  var propertyGetProp = PropertyFactory.getProp;
+  PropertyFactory.getProp = function (elem, data, type, mult, container) {
+    var prop = propertyGetProp(elem, data, type, mult, container);
+    // prop.getVelocityAtTime = getVelocityAtTime;
+    // prop.loopOut = loopOut;
+    // prop.loopIn = loopIn;
+    if (prop.kf) {
+      prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop);
+    } else {
+      prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop);
+    }
+    prop.setGroupProperty = expressionHelpers.setGroupProperty;
+    prop.loopOut = loopOut;
+    prop.loopIn = loopIn;
+    prop.smooth = smooth;
+    prop.getVelocityAtTime = expressionHelpers.getVelocityAtTime.bind(prop);
+    prop.getSpeedAtTime = expressionHelpers.getSpeedAtTime.bind(prop);
+    prop.numKeys = data.a === 1 ? data.k.length : 0;
+    prop.propertyIndex = data.ix;
+    var value = 0;
+    if (type !== 0) {
+      value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length);
+    }
+    prop._cachingAtTime = {
+      lastFrame: initialDefaultFrame,
+      lastIndex: 0,
+      value: value,
+    };
+    expressionHelpers.searchExpressions(elem, data, prop);
+    if (prop.k) {
+      container.addDynamicProperty(prop);
+    }
+
+    return prop;
+  };
+
+  function getShapeValueAtTime(frameNum) {
+    // For now this caching object is created only when needed instead of creating it when the shape is initialized.
+    if (!this._cachingAtTime) {
+      this._cachingAtTime = {
+        shapeValue: shapePool.clone(this.pv),
+        lastIndex: 0,
+        lastTime: initialDefaultFrame,
+      };
+    }
+
+    frameNum *= this.elem.globalData.frameRate;
+    frameNum -= this.offsetTime;
+    if (frameNum !== this._cachingAtTime.lastTime) {
+      this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0;
+      this._cachingAtTime.lastTime = frameNum;
+      this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime);
+    }
+    return this._cachingAtTime.shapeValue;
+  }
+
+  var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction();
+  var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction();
+
+  function ShapeExpressions() {}
+  ShapeExpressions.prototype = {
+    vertices: function (prop, time) {
+      if (this.k) {
+        this.getValue();
+      }
+      var shapePath = this.v;
+      if (time !== undefined) {
+        shapePath = this.getValueAtTime(time, 0);
+      }
+      var i;
+      var len = shapePath._length;
+      var vertices = shapePath[prop];
+      var points = shapePath.v;
+      var arr = createSizedArray(len);
+      for (i = 0; i < len; i += 1) {
+        if (prop === 'i' || prop === 'o') {
+          arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]];
+        } else {
+          arr[i] = [vertices[i][0], vertices[i][1]];
+        }
+      }
+      return arr;
+    },
+    points: function (time) {
+      return this.vertices('v', time);
+    },
+    inTangents: function (time) {
+      return this.vertices('i', time);
+    },
+    outTangents: function (time) {
+      return this.vertices('o', time);
+    },
+    isClosed: function () {
+      return this.v.c;
+    },
+    pointOnPath: function (perc, time) {
+      var shapePath = this.v;
+      if (time !== undefined) {
+        shapePath = this.getValueAtTime(time, 0);
+      }
+      if (!this._segmentsLength) {
+        this._segmentsLength = bez.getSegmentsLength(shapePath);
+      }
+
+      var segmentsLength = this._segmentsLength;
+      var lengths = segmentsLength.lengths;
+      var lengthPos = segmentsLength.totalLength * perc;
+      var i = 0;
+      var len = lengths.length;
+      var accumulatedLength = 0;
+      var pt;
+      while (i < len) {
+        if (accumulatedLength + lengths[i].addedLength > lengthPos) {
+          var initIndex = i;
+          var endIndex = (shapePath.c && i === len - 1) ? 0 : i + 1;
+          var segmentPerc = (lengthPos - accumulatedLength) / lengths[i].addedLength;
+          pt = bez.getPointInSegment(shapePath.v[initIndex], shapePath.v[endIndex], shapePath.o[initIndex], shapePath.i[endIndex], segmentPerc, lengths[i]);
+          break;
+        } else {
+          accumulatedLength += lengths[i].addedLength;
+        }
+        i += 1;
+      }
+      if (!pt) {
+        pt = shapePath.c ? [shapePath.v[0][0], shapePath.v[0][1]] : [shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1]];
+      }
+      return pt;
+    },
+    vectorOnPath: function (perc, time, vectorType) {
+      // perc doesn't use triple equality because it can be a Number object as well as a primitive.
+      if (perc == 1) { // eslint-disable-line eqeqeq
+        perc = this.v.c;
+      } else if (perc == 0) { // eslint-disable-line eqeqeq
+        perc = 0.999;
+      }
+      var pt1 = this.pointOnPath(perc, time);
+      var pt2 = this.pointOnPath(perc + 0.001, time);
+      var xLength = pt2[0] - pt1[0];
+      var yLength = pt2[1] - pt1[1];
+      var magnitude = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2));
+      if (magnitude === 0) {
+        return [0, 0];
+      }
+      var unitVector = vectorType === 'tangent' ? [xLength / magnitude, yLength / magnitude] : [-yLength / magnitude, xLength / magnitude];
+      return unitVector;
+    },
+    tangentOnPath: function (perc, time) {
+      return this.vectorOnPath(perc, time, 'tangent');
+    },
+    normalOnPath: function (perc, time) {
+      return this.vectorOnPath(perc, time, 'normal');
+    },
+    setGroupProperty: expressionHelpers.setGroupProperty,
+    getValueAtTime: expressionHelpers.getStaticValueAtTime,
+  };
+  extendPrototype([ShapeExpressions], ShapePropertyConstructorFunction);
+  extendPrototype([ShapeExpressions], KeyframedShapePropertyConstructorFunction);
+  KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime;
+  KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression;
+
+  var propertyGetShapeProp = ShapePropertyFactory.getShapeProp;
+  ShapePropertyFactory.getShapeProp = function (elem, data, type, arr, trims) {
+    var prop = propertyGetShapeProp(elem, data, type, arr, trims);
+    prop.propertyIndex = data.ix;
+    prop.lock = false;
+    if (type === 3) {
+      expressionHelpers.searchExpressions(elem, data.pt, prop);
+    } else if (type === 4) {
+      expressionHelpers.searchExpressions(elem, data.ks, prop);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  };
+}
+
+function initialize$1() {
+  addPropertyDecorator();
+}
+
+function addDecorator() {
+  function searchExpressions() {
+    if (this.data.d.x) {
+      this.calculateExpression = ExpressionManager.initiateExpression.bind(this)(this.elem, this.data.d, this);
+      this.addEffect(this.getExpressionValue.bind(this));
+      return true;
+    }
+    return null;
+  }
+
+  TextProperty.prototype.getExpressionValue = function (currentValue, text) {
+    var newValue = this.calculateExpression(text);
+    if (currentValue.t !== newValue) {
+      var newData = {};
+      this.copyData(newData, currentValue);
+      newData.t = newValue.toString();
+      newData.__complete = false;
+      return newData;
+    }
+    return currentValue;
+  };
+
+  TextProperty.prototype.searchProperty = function () {
+    var isKeyframed = this.searchKeyframes();
+    var hasExpressions = this.searchExpressions();
+    this.kf = isKeyframed || hasExpressions;
+    return this.kf;
+  };
+
+  TextProperty.prototype.searchExpressions = searchExpressions;
+}
+
+function initialize() {
+  addDecorator();
+}
+
+function TransformEffect() {
+}
+
+TransformEffect.prototype.init = function (effectsManager) {
+  this.effectsManager = effectsManager;
+  this.type = effectTypes.TRANSFORM_EFFECT;
+  this.matrix = new Matrix();
+  this.opacity = -1;
+  this._mdf = false;
+  this._opMdf = false;
+};
+
+TransformEffect.prototype.renderFrame = function (forceFrame) {
+  this._opMdf = false;
+  this._mdf = false;
+  if (forceFrame || this.effectsManager._mdf) {
+    var effectElements = this.effectsManager.effectElements;
+    var anchor = effectElements[0].p.v;
+    var position = effectElements[1].p.v;
+    var isUniformScale = effectElements[2].p.v === 1;
+    var scaleHeight = effectElements[3].p.v;
+    var scaleWidth = isUniformScale ? scaleHeight : effectElements[4].p.v;
+    var skew = effectElements[5].p.v;
+    var skewAxis = effectElements[6].p.v;
+    var rotation = effectElements[7].p.v;
+    this.matrix.reset();
+    this.matrix.translate(-anchor[0], -anchor[1], anchor[2]);
+    this.matrix.scale(scaleWidth * 0.01, scaleHeight * 0.01, 1);
+    this.matrix.rotate(-rotation * degToRads);
+    this.matrix.skewFromAxis(-skew * degToRads, (skewAxis + 90) * degToRads);
+    this.matrix.translate(position[0], position[1], 0);
+    this._mdf = true;
+    if (this.opacity !== effectElements[8].p.v) {
+      this.opacity = effectElements[8].p.v;
+      this._opMdf = true;
+    }
+  }
+};
+
+function CVTransformEffect(effectsManager) {
+  this.init(effectsManager);
+}
+extendPrototype([TransformEffect], CVTransformEffect);
+
+// Registering expression plugin
+setExpressionsPlugin(Expressions);
+setExpressionInterfaces(getInterface);
+initialize$1();
+initialize();
+registerEffect(35, CVTransformEffect);
+
+export { lottie as default };
diff --git a/build/player/esm/lottie_html.min.js b/build/player/esm/lottie_html.min.js
new file mode 100644
index 0000000..af49cb8
--- /dev/null
+++ b/build/player/esm/lottie_html.min.js
@@ -0,0 +1,16301 @@
+const svgNS = 'http://www.w3.org/2000/svg';
+
+let locationHref = '';
+let _useWebWorker = false;
+
+const initialDefaultFrame = -999999;
+
+const setWebWorker = (flag) => { _useWebWorker = !!flag; };
+const getWebWorker = () => _useWebWorker;
+
+const setLocationHref = (value) => { locationHref = value; };
+const getLocationHref = () => locationHref;
+
+function createTag(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElement(type);
+}
+
+function extendPrototype(sources, destination) {
+  var i;
+  var len = sources.length;
+  var sourcePrototype;
+  for (i = 0; i < len; i += 1) {
+    sourcePrototype = sources[i].prototype;
+    for (var attr in sourcePrototype) {
+      if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
+    }
+  }
+}
+
+function getDescriptor(object, prop) {
+  return Object.getOwnPropertyDescriptor(object, prop);
+}
+
+function createProxyFunction(prototype) {
+  function ProxyFunction() {}
+  ProxyFunction.prototype = prototype;
+  return ProxyFunction;
+}
+
+// import Howl from '../../3rd_party/howler';
+
+const audioControllerFactory = (function () {
+  function AudioController(audioFactory) {
+    this.audios = [];
+    this.audioFactory = audioFactory;
+    this._volume = 1;
+    this._isMuted = false;
+  }
+
+  AudioController.prototype = {
+    addAudio: function (audio) {
+      this.audios.push(audio);
+    },
+    pause: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].pause();
+      }
+    },
+    resume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].resume();
+      }
+    },
+    setRate: function (rateValue) {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].setRate(rateValue);
+      }
+    },
+    createAudio: function (assetPath) {
+      if (this.audioFactory) {
+        return this.audioFactory(assetPath);
+      } if (window.Howl) {
+        return new window.Howl({
+          src: [assetPath],
+        });
+      }
+      return {
+        isPlaying: false,
+        play: function () { this.isPlaying = true; },
+        seek: function () { this.isPlaying = false; },
+        playing: function () {},
+        rate: function () {},
+        setVolume: function () {},
+      };
+    },
+    setAudioFactory: function (audioFactory) {
+      this.audioFactory = audioFactory;
+    },
+    setVolume: function (value) {
+      this._volume = value;
+      this._updateVolume();
+    },
+    mute: function () {
+      this._isMuted = true;
+      this._updateVolume();
+    },
+    unmute: function () {
+      this._isMuted = false;
+      this._updateVolume();
+    },
+    getVolume: function () {
+      return this._volume;
+    },
+    _updateVolume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
+      }
+    },
+  };
+
+  return function () {
+    return new AudioController();
+  };
+}());
+
+const createTypedArray = (function () {
+  function createRegularArray(type, len) {
+    var i = 0;
+    var arr = [];
+    var value;
+    switch (type) {
+      case 'int16':
+      case 'uint8c':
+        value = 1;
+        break;
+      default:
+        value = 1.1;
+        break;
+    }
+    for (i = 0; i < len; i += 1) {
+      arr.push(value);
+    }
+    return arr;
+  }
+  function createTypedArrayFactory(type, len) {
+    if (type === 'float32') {
+      return new Float32Array(len);
+    } if (type === 'int16') {
+      return new Int16Array(len);
+    } if (type === 'uint8c') {
+      return new Uint8ClampedArray(len);
+    }
+    return createRegularArray(type, len);
+  }
+  if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
+    return createTypedArrayFactory;
+  }
+  return createRegularArray;
+}());
+
+function createSizedArray(len) {
+  return Array.apply(null, { length: len });
+}
+
+let subframeEnabled = true;
+let expressionsPlugin = null;
+let expressionsInterfaces = null;
+let idPrefix$1 = '';
+const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+let _shouldRoundValues = false;
+const bmPow = Math.pow;
+const bmSqrt = Math.sqrt;
+const bmFloor = Math.floor;
+const bmMax = Math.max;
+const bmMin = Math.min;
+
+const BMMath = {};
+(function () {
+  var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
+  var i;
+  var len = propertyNames.length;
+  for (i = 0; i < len; i += 1) {
+    BMMath[propertyNames[i]] = Math[propertyNames[i]];
+  }
+}());
+
+function ProjectInterface$1() { return {}; }
+BMMath.random = Math.random;
+BMMath.abs = function (val) {
+  var tOfVal = typeof val;
+  if (tOfVal === 'object' && val.length) {
+    var absArr = createSizedArray(val.length);
+    var i;
+    var len = val.length;
+    for (i = 0; i < len; i += 1) {
+      absArr[i] = Math.abs(val[i]);
+    }
+    return absArr;
+  }
+  return Math.abs(val);
+};
+let defaultCurveSegments = 150;
+const degToRads = Math.PI / 180;
+const roundCorner = 0.5519;
+
+function roundValues(flag) {
+  _shouldRoundValues = !!flag;
+}
+
+function bmRnd(value) {
+  if (_shouldRoundValues) {
+    return Math.round(value);
+  }
+  return value;
+}
+
+function styleDiv(element) {
+  element.style.position = 'absolute';
+  element.style.top = 0;
+  element.style.left = 0;
+  element.style.display = 'block';
+  element.style.transformOrigin = '0 0';
+  element.style.webkitTransformOrigin = '0 0';
+  element.style.backfaceVisibility = 'visible';
+  element.style.webkitBackfaceVisibility = 'visible';
+  element.style.transformStyle = 'preserve-3d';
+  element.style.webkitTransformStyle = 'preserve-3d';
+  element.style.mozTransformStyle = 'preserve-3d';
+}
+
+function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
+  this.type = type;
+  this.currentTime = currentTime;
+  this.totalTime = totalTime;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteEvent(type, frameMultiplier) {
+  this.type = type;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
+  this.type = type;
+  this.currentLoop = currentLoop;
+  this.totalLoops = totalLoops;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMSegmentStartEvent(type, firstFrame, totalFrames) {
+  this.type = type;
+  this.firstFrame = firstFrame;
+  this.totalFrames = totalFrames;
+}
+
+function BMDestroyEvent(type, target) {
+  this.type = type;
+  this.target = target;
+}
+
+function BMRenderFrameErrorEvent(nativeError, currentTime) {
+  this.type = 'renderFrameError';
+  this.nativeError = nativeError;
+  this.currentTime = currentTime;
+}
+
+function BMConfigErrorEvent(nativeError) {
+  this.type = 'configError';
+  this.nativeError = nativeError;
+}
+
+function BMAnimationConfigErrorEvent(type, nativeError) {
+  this.type = type;
+  this.nativeError = nativeError;
+}
+
+const createElementID = (function () {
+  var _count = 0;
+  return function createID() {
+    _count += 1;
+    return idPrefix$1 + '__lottie_element_' + _count;
+  };
+}());
+
+function HSVtoRGB(h, s, v) {
+  var r;
+  var g;
+  var b;
+  var i;
+  var f;
+  var p;
+  var q;
+  var t;
+  i = Math.floor(h * 6);
+  f = h * 6 - i;
+  p = v * (1 - s);
+  q = v * (1 - f * s);
+  t = v * (1 - (1 - f) * s);
+  switch (i % 6) {
+    case 0: r = v; g = t; b = p; break;
+    case 1: r = q; g = v; b = p; break;
+    case 2: r = p; g = v; b = t; break;
+    case 3: r = p; g = q; b = v; break;
+    case 4: r = t; g = p; b = v; break;
+    case 5: r = v; g = p; b = q; break;
+    default: break;
+  }
+  return [r,
+    g,
+    b];
+}
+
+function RGBtoHSV(r, g, b) {
+  var max = Math.max(r, g, b);
+  var min = Math.min(r, g, b);
+  var d = max - min;
+  var h;
+  var s = (max === 0 ? 0 : d / max);
+  var v = max / 255;
+
+  switch (max) {
+    case min: h = 0; break;
+    case r: h = (g - b) + d * (g < b ? 6 : 0); h /= 6 * d; break;
+    case g: h = (b - r) + d * 2; h /= 6 * d; break;
+    case b: h = (r - g) + d * 4; h /= 6 * d; break;
+    default: break;
+  }
+
+  return [
+    h,
+    s,
+    v,
+  ];
+}
+
+function addSaturationToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[1] += offset;
+  if (hsv[1] > 1) {
+    hsv[1] = 1;
+  } else if (hsv[1] <= 0) {
+    hsv[1] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addBrightnessToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[2] += offset;
+  if (hsv[2] > 1) {
+    hsv[2] = 1;
+  } else if (hsv[2] < 0) {
+    hsv[2] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addHueToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[0] += offset / 360;
+  if (hsv[0] > 1) {
+    hsv[0] -= 1;
+  } else if (hsv[0] < 0) {
+    hsv[0] += 1;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+const rgbToHex = (function () {
+  var colorMap = [];
+  var i;
+  var hex;
+  for (i = 0; i < 256; i += 1) {
+    hex = i.toString(16);
+    colorMap[i] = hex.length === 1 ? '0' + hex : hex;
+  }
+
+  return function (r, g, b) {
+    if (r < 0) {
+      r = 0;
+    }
+    if (g < 0) {
+      g = 0;
+    }
+    if (b < 0) {
+      b = 0;
+    }
+    return '#' + colorMap[r] + colorMap[g] + colorMap[b];
+  };
+}());
+
+const setSubframeEnabled = (flag) => { subframeEnabled = !!flag; };
+const getSubframeEnabled = () => subframeEnabled;
+const setExpressionsPlugin = (value) => { expressionsPlugin = value; };
+const getExpressionsPlugin = () => expressionsPlugin;
+const setExpressionInterfaces = (value) => { expressionsInterfaces = value; };
+const getExpressionInterfaces = () => expressionsInterfaces;
+const setDefaultCurveSegments = (value) => { defaultCurveSegments = value; };
+const getDefaultCurveSegments = () => defaultCurveSegments;
+const setIdPrefix = (value) => { idPrefix$1 = value; };
+const getIdPrefix = () => idPrefix$1;
+
+function createNS(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElementNS(svgNS, type);
+}
+
+const dataManager = (function () {
+  var _counterId = 1;
+  var processes = [];
+  var workerFn;
+  var workerInstance;
+  var workerProxy = {
+    onmessage: function () {
+
+    },
+    postMessage: function (path) {
+      workerFn({
+        data: path,
+      });
+    },
+  };
+  var _workerSelf = {
+    postMessage: function (data) {
+      workerProxy.onmessage({
+        data: data,
+      });
+    },
+  };
+  function createWorker(fn) {
+    if (window.Worker && window.Blob && getWebWorker()) {
+      var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      var url = URL.createObjectURL(blob);
+      return new Worker(url);
+    }
+    workerFn = fn;
+    return workerProxy;
+  }
+
+  function setupWorker() {
+    if (!workerInstance) {
+      workerInstance = createWorker(function workerStart(e) {
+        function dataFunctionManager() {
+          function completeLayers(layers, comps) {
+            var layerData;
+            var i;
+            var len = layers.length;
+            var j;
+            var jLen;
+            var k;
+            var kLen;
+            for (i = 0; i < len; i += 1) {
+              layerData = layers[i];
+              if (('ks' in layerData) && !layerData.completed) {
+                layerData.completed = true;
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      convertPathsToAbsoluteValues(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) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 0) {
+                  layerData.layers = findCompLayers(layerData.refId, comps);
+                  completeLayers(layerData.layers, comps);
+                } else if (layerData.ty === 4) {
+                  completeShapes(layerData.shapes);
+                } else if (layerData.ty === 5) {
+                  completeText(layerData);
+                }
+              }
+            }
+          }
+
+          function completeChars(chars, assets) {
+            if (chars) {
+              var i = 0;
+              var len = chars.length;
+              for (i = 0; i < len; i += 1) {
+                if (chars[i].t === 1) {
+                  // var compData = findComp(chars[i].data.refId, assets);
+                  chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                  // chars[i].data.ip = 0;
+                  // chars[i].data.op = 99999;
+                  // chars[i].data.st = 0;
+                  // chars[i].data.sr = 1;
+                  // chars[i].w = compData.w;
+                  // chars[i].data.ks = {
+                  //   a: { k: [0, 0, 0], a: 0 },
+                  //   p: { k: [0, -compData.h, 0], a: 0 },
+                  //   r: { k: 0, a: 0 },
+                  //   s: { k: [100, 100], a: 0 },
+                  //   o: { k: 100, a: 0 },
+                  // };
+                  completeLayers(chars[i].data.layers, assets);
+                }
+              }
+            }
+          }
+
+          function findComp(id, comps) {
+            var i = 0;
+            var len = comps.length;
+            while (i < len) {
+              if (comps[i].id === id) {
+                return comps[i];
+              }
+              i += 1;
+            }
+            return null;
+          }
+
+          function findCompLayers(id, comps) {
+            var comp = findComp(id, comps);
+            if (comp) {
+              if (!comp.layers.__used) {
+                comp.layers.__used = true;
+                return comp.layers;
+              }
+              return JSON.parse(JSON.stringify(comp.layers));
+            }
+            return null;
+          }
+
+          function completeShapes(arr) {
+            var i;
+            var len = arr.length;
+            var j;
+            var jLen;
+            for (i = len - 1; i >= 0; i -= 1) {
+              if (arr[i].ty === 'sh') {
+                if (arr[i].ks.k.i) {
+                  convertPathsToAbsoluteValues(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) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
+                    }
+                    if (arr[i].ks.k[j].e) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
+                    }
+                  }
+                }
+              } else if (arr[i].ty === 'gr') {
+                completeShapes(arr[i].it);
+              }
+            }
+          }
+
+          function convertPathsToAbsoluteValues(path) {
+            var i;
+            var len = path.i.length;
+            for (i = 0; i < len; i += 1) {
+              path.i[i][0] += path.v[i][0];
+              path.i[i][1] += path.v[i][1];
+              path.o[i][0] += path.v[i][0];
+              path.o[i][1] += path.v[i][1];
+            }
+          }
+
+          function checkVersion(minimum, animVersionString) {
+            var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
+            if (minimum[0] > animVersion[0]) {
+              return true;
+            } if (animVersion[0] > minimum[0]) {
+              return false;
+            }
+            if (minimum[1] > animVersion[1]) {
+              return true;
+            } if (animVersion[1] > minimum[1]) {
+              return false;
+            }
+            if (minimum[2] > animVersion[2]) {
+              return true;
+            } if (animVersion[2] > minimum[2]) {
+              return false;
+            }
+            return null;
+          }
+
+          var checkText = (function () {
+            var minimumVersion = [4, 4, 14];
+
+            function updateTextLayer(textLayer) {
+              var documentData = textLayer.t.d;
+              textLayer.t.d = {
+                k: [
+                  {
+                    s: documentData,
+                    t: 0,
+                  },
+                ],
+              };
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkChars = (function () {
+            var minimumVersion = [4, 7, 99];
+            return function (animationData) {
+              if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
+                var i;
+                var len = animationData.chars.length;
+                for (i = 0; i < len; i += 1) {
+                  var charData = animationData.chars[i];
+                  if (charData.data && charData.data.shapes) {
+                    completeShapes(charData.data.shapes);
+                    charData.data.ip = 0;
+                    charData.data.op = 99999;
+                    charData.data.st = 0;
+                    charData.data.sr = 1;
+                    charData.data.ks = {
+                      p: { k: [0, 0], a: 0 },
+                      s: { k: [100, 100], a: 0 },
+                      a: { k: [0, 0], a: 0 },
+                      r: { k: 0, a: 0 },
+                      o: { k: 100, a: 0 },
+                    };
+                    if (!animationData.chars[i].t) {
+                      charData.data.shapes.push(
+                        {
+                          ty: 'no',
+                        }
+                      );
+                      charData.data.shapes[0].it.push(
+                        {
+                          p: { k: [0, 0], a: 0 },
+                          s: { k: [100, 100], a: 0 },
+                          a: { k: [0, 0], a: 0 },
+                          r: { k: 0, a: 0 },
+                          o: { k: 100, a: 0 },
+                          sk: { k: 0, a: 0 },
+                          sa: { k: 0, a: 0 },
+                          ty: 'tr',
+                        }
+                      );
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkPathProperties = (function () {
+            var minimumVersion = [5, 7, 15];
+
+            function updateTextLayer(textLayer) {
+              var pathData = textLayer.t.p;
+              if (typeof pathData.a === 'number') {
+                pathData.a = {
+                  a: 0,
+                  k: pathData.a,
+                };
+              }
+              if (typeof pathData.p === 'number') {
+                pathData.p = {
+                  a: 0,
+                  k: pathData.p,
+                };
+              }
+              if (typeof pathData.r === 'number') {
+                pathData.r = {
+                  a: 0,
+                  k: pathData.r,
+                };
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkColors = (function () {
+            var minimumVersion = [4, 1, 9];
+
+            function iterateShapes(shapes) {
+              var i;
+              var len = shapes.length;
+              var j;
+              var jLen;
+              for (i = 0; i < len; i += 1) {
+                if (shapes[i].ty === 'gr') {
+                  iterateShapes(shapes[i].it);
+                } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
+                  if (shapes[i].c.k && shapes[i].c.k[0].i) {
+                    jLen = shapes[i].c.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (shapes[i].c.k[j].s) {
+                        shapes[i].c.k[j].s[0] /= 255;
+                        shapes[i].c.k[j].s[1] /= 255;
+                        shapes[i].c.k[j].s[2] /= 255;
+                        shapes[i].c.k[j].s[3] /= 255;
+                      }
+                      if (shapes[i].c.k[j].e) {
+                        shapes[i].c.k[j].e[0] /= 255;
+                        shapes[i].c.k[j].e[1] /= 255;
+                        shapes[i].c.k[j].e[2] /= 255;
+                        shapes[i].c.k[j].e[3] /= 255;
+                      }
+                    }
+                  } else {
+                    shapes[i].c.k[0] /= 255;
+                    shapes[i].c.k[1] /= 255;
+                    shapes[i].c.k[2] /= 255;
+                    shapes[i].c.k[3] /= 255;
+                  }
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 4) {
+                  iterateShapes(layers[i].shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkShapes = (function () {
+            var minimumVersion = [4, 4, 18];
+
+            function completeClosingShapes(arr) {
+              var i;
+              var len = arr.length;
+              var j;
+              var jLen;
+              for (i = len - 1; i >= 0; i -= 1) {
+                if (arr[i].ty === 'sh') {
+                  if (arr[i].ks.k.i) {
+                    arr[i].ks.k.c = arr[i].closed;
+                  } else {
+                    jLen = arr[i].ks.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (arr[i].ks.k[j].s) {
+                        arr[i].ks.k[j].s[0].c = arr[i].closed;
+                      }
+                      if (arr[i].ks.k[j].e) {
+                        arr[i].ks.k[j].e[0].c = arr[i].closed;
+                      }
+                    }
+                  }
+                } else if (arr[i].ty === 'gr') {
+                  completeClosingShapes(arr[i].it);
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var layerData;
+              var i;
+              var len = layers.length;
+              var j;
+              var jLen;
+              var k;
+              var kLen;
+              for (i = 0; i < len; i += 1) {
+                layerData = layers[i];
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      maskProps[j].pt.k.c = maskProps[j].cl;
+                    } else {
+                      kLen = maskProps[j].pt.k.length;
+                      for (k = 0; k < kLen; k += 1) {
+                        if (maskProps[j].pt.k[k].s) {
+                          maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 4) {
+                  completeClosingShapes(layerData.shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          function completeData(animationData) {
+            if (animationData.__complete) {
+              return;
+            }
+            checkColors(animationData);
+            checkText(animationData);
+            checkChars(animationData);
+            checkPathProperties(animationData);
+            checkShapes(animationData);
+            completeLayers(animationData.layers, animationData.assets);
+            completeChars(animationData.chars, animationData.assets);
+            animationData.__complete = true;
+          }
+
+          function completeText(data) {
+            if (data.t.a.length === 0 && !('m' in data.t.p)) {
+              // data.singleShape = true;
+            }
+          }
+
+          var moduleOb = {};
+          moduleOb.completeData = completeData;
+          moduleOb.checkColors = checkColors;
+          moduleOb.checkChars = checkChars;
+          moduleOb.checkPathProperties = checkPathProperties;
+          moduleOb.checkShapes = checkShapes;
+          moduleOb.completeLayers = completeLayers;
+
+          return moduleOb;
+        }
+        if (!_workerSelf.dataManager) {
+          _workerSelf.dataManager = dataFunctionManager();
+        }
+
+        if (!_workerSelf.assetLoader) {
+          _workerSelf.assetLoader = (function () {
+            function formatResponse(xhr) {
+              // using typeof doubles the time of execution of this method,
+              // so if available, it's better to use the header to validate the type
+              var contentTypeHeader = xhr.getResponseHeader('content-type');
+              if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
+                return xhr.response;
+              }
+              if (xhr.response && typeof xhr.response === 'object') {
+                return xhr.response;
+              } if (xhr.response && typeof xhr.response === 'string') {
+                return JSON.parse(xhr.response);
+              } if (xhr.responseText) {
+                return JSON.parse(xhr.responseText);
+              }
+              return null;
+            }
+
+            function loadAsset(path, fullPath, callback, errorCallback) {
+              var response;
+              var xhr = new XMLHttpRequest();
+              // set responseType after calling open or IE will break.
+              try {
+                // This crashes on Android WebView prior to KitKat
+                xhr.responseType = 'json';
+              } catch (err) {} // eslint-disable-line no-empty
+              xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4) {
+                  if (xhr.status === 200) {
+                    response = formatResponse(xhr);
+                    callback(response);
+                  } else {
+                    try {
+                      response = formatResponse(xhr);
+                      callback(response);
+                    } catch (err) {
+                      if (errorCallback) {
+                        errorCallback(err);
+                      }
+                    }
+                  }
+                }
+              };
+              try {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), path, true);
+              } catch (error) {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
+              }
+              xhr.send();
+            }
+            return {
+              load: loadAsset,
+            };
+          }());
+        }
+
+        if (e.data.type === 'loadAnimation') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.dataManager.completeData(data);
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        } else if (e.data.type === 'complete') {
+          var animation = e.data.animation;
+          _workerSelf.dataManager.completeData(animation);
+          _workerSelf.postMessage({
+            id: e.data.id,
+            payload: animation,
+            status: 'success',
+          });
+        } else if (e.data.type === 'loadData') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        }
+      });
+
+      workerInstance.onmessage = function (event) {
+        var data = event.data;
+        var id = data.id;
+        var process = processes[id];
+        processes[id] = null;
+        if (data.status === 'success') {
+          process.onComplete(data.payload);
+        } else if (process.onError) {
+          process.onError();
+        }
+      };
+    }
+  }
+
+  function createProcess(onComplete, onError) {
+    _counterId += 1;
+    var id = 'processId_' + _counterId;
+    processes[id] = {
+      onComplete: onComplete,
+      onError: onError,
+    };
+    return id;
+  }
+
+  function loadAnimation(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadAnimation',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function loadData(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadData',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function completeAnimation(anim, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'complete',
+      animation: anim,
+      id: processId,
+    });
+  }
+
+  return {
+    loadAnimation: loadAnimation,
+    loadData: loadData,
+    completeAnimation: completeAnimation,
+  };
+}());
+
+const ImagePreloader = (function () {
+  var proxyImage = (function () {
+    var canvas = createTag('canvas');
+    canvas.width = 1;
+    canvas.height = 1;
+    var ctx = canvas.getContext('2d');
+    ctx.fillStyle = 'rgba(0,0,0,0)';
+    ctx.fillRect(0, 0, 1, 1);
+    return canvas;
+  }());
+
+  function imageLoaded() {
+    this.loadedAssets += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+  function footageLoaded() {
+    this.loadedFootagesCount += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+
+  function getAssetsPath(assetData, assetsPath, originalPath) {
+    var path = '';
+    if (assetData.e) {
+      path = assetData.p;
+    } else if (assetsPath) {
+      var imagePath = assetData.p;
+      if (imagePath.indexOf('images/') !== -1) {
+        imagePath = imagePath.split('/')[1];
+      }
+      path = assetsPath + imagePath;
+    } else {
+      path = originalPath;
+      path += assetData.u ? assetData.u : '';
+      path += assetData.p;
+    }
+    return path;
+  }
+
+  function testImageLoaded(img) {
+    var _count = 0;
+    var intervalId = setInterval(function () {
+      var box = img.getBBox();
+      if (box.width || _count > 500) {
+        this._imageLoaded();
+        clearInterval(intervalId);
+      }
+      _count += 1;
+    }.bind(this), 50);
+  }
+
+  function createImageData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createNS('image');
+    if (isSafari) {
+      this.testImageLoaded(img);
+    } else {
+      img.addEventListener('load', this._imageLoaded, false);
+    }
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
+    if (this._elementHelper.append) {
+      this._elementHelper.append(img);
+    } else {
+      this._elementHelper.appendChild(img);
+    }
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createImgData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createTag('img');
+    img.crossOrigin = 'anonymous';
+    img.addEventListener('load', this._imageLoaded, false);
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.src = path;
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createFootageData(data) {
+    var ob = {
+      assetData: data,
+    };
+    var path = getAssetsPath(data, this.assetsPath, this.path);
+    dataManager.loadData(path, function (footageData) {
+      ob.img = footageData;
+      this._footageLoaded();
+    }.bind(this), function () {
+      ob.img = {};
+      this._footageLoaded();
+    }.bind(this));
+    return ob;
+  }
+
+  function loadAssets(assets, cb) {
+    this.imagesLoadedCb = cb;
+    var i;
+    var len = assets.length;
+    for (i = 0; i < len; i += 1) {
+      if (!assets[i].layers) {
+        if (!assets[i].t || assets[i].t === 'seq') {
+          this.totalImages += 1;
+          this.images.push(this._createImageData(assets[i]));
+        } else if (assets[i].t === 3) {
+          this.totalFootages += 1;
+          this.images.push(this.createFootageData(assets[i]));
+        }
+      }
+    }
+  }
+
+  function setPath(path) {
+    this.path = path || '';
+  }
+
+  function setAssetsPath(path) {
+    this.assetsPath = path || '';
+  }
+
+  function getAsset(assetData) {
+    var i = 0;
+    var len = this.images.length;
+    while (i < len) {
+      if (this.images[i].assetData === assetData) {
+        return this.images[i].img;
+      }
+      i += 1;
+    }
+    return null;
+  }
+
+  function destroy() {
+    this.imagesLoadedCb = null;
+    this.images.length = 0;
+  }
+
+  function loadedImages() {
+    return this.totalImages === this.loadedAssets;
+  }
+
+  function loadedFootages() {
+    return this.totalFootages === this.loadedFootagesCount;
+  }
+
+  function setCacheType(type, elementHelper) {
+    if (type === 'svg') {
+      this._elementHelper = elementHelper;
+      this._createImageData = this.createImageData.bind(this);
+    } else {
+      this._createImageData = this.createImgData.bind(this);
+    }
+  }
+
+  function ImagePreloaderFactory() {
+    this._imageLoaded = imageLoaded.bind(this);
+    this._footageLoaded = footageLoaded.bind(this);
+    this.testImageLoaded = testImageLoaded.bind(this);
+    this.createFootageData = createFootageData.bind(this);
+    this.assetsPath = '';
+    this.path = '';
+    this.totalImages = 0;
+    this.totalFootages = 0;
+    this.loadedAssets = 0;
+    this.loadedFootagesCount = 0;
+    this.imagesLoadedCb = null;
+    this.images = [];
+  }
+
+  ImagePreloaderFactory.prototype = {
+    loadAssets: loadAssets,
+    setAssetsPath: setAssetsPath,
+    setPath: setPath,
+    loadedImages: loadedImages,
+    loadedFootages: loadedFootages,
+    destroy: destroy,
+    getAsset: getAsset,
+    createImgData: createImgData,
+    createImageData: createImageData,
+    imageLoaded: imageLoaded,
+    footageLoaded: footageLoaded,
+    setCacheType: setCacheType,
+  };
+
+  return ImagePreloaderFactory;
+}());
+
+function BaseEvent() {}
+BaseEvent.prototype = {
+  triggerEvent: function (eventName, args) {
+    if (this._cbs[eventName]) {
+      var callbacks = this._cbs[eventName];
+      for (var i = 0; i < callbacks.length; i += 1) {
+        callbacks[i](args);
+      }
+    }
+  },
+  addEventListener: function (eventName, callback) {
+    if (!this._cbs[eventName]) {
+      this._cbs[eventName] = [];
+    }
+    this._cbs[eventName].push(callback);
+
+    return function () {
+      this.removeEventListener(eventName, callback);
+    }.bind(this);
+  },
+  removeEventListener: function (eventName, callback) {
+    if (!callback) {
+      this._cbs[eventName] = null;
+    } else if (this._cbs[eventName]) {
+      var i = 0;
+      var len = this._cbs[eventName].length;
+      while (i < len) {
+        if (this._cbs[eventName][i] === callback) {
+          this._cbs[eventName].splice(i, 1);
+          i -= 1;
+          len -= 1;
+        }
+        i += 1;
+      }
+      if (!this._cbs[eventName].length) {
+        this._cbs[eventName] = null;
+      }
+    }
+  },
+};
+
+const markerParser = (
+
+  function () {
+    function parsePayloadLines(payload) {
+      var lines = payload.split('\r\n');
+      var keys = {};
+      var line;
+      var keysCount = 0;
+      for (var i = 0; i < lines.length; i += 1) {
+        line = lines[i].split(':');
+        if (line.length === 2) {
+          keys[line[0]] = line[1].trim();
+          keysCount += 1;
+        }
+      }
+      if (keysCount === 0) {
+        throw new Error();
+      }
+      return keys;
+    }
+
+    return function (_markers) {
+      var markers = [];
+      for (var i = 0; i < _markers.length; i += 1) {
+        var _marker = _markers[i];
+        var markerData = {
+          time: _marker.tm,
+          duration: _marker.dr,
+        };
+        try {
+          markerData.payload = JSON.parse(_markers[i].cm);
+        } catch (_) {
+          try {
+            markerData.payload = parsePayloadLines(_markers[i].cm);
+          } catch (__) {
+            markerData.payload = {
+              name: _markers[i].cm,
+            };
+          }
+        }
+        markers.push(markerData);
+      }
+      return markers;
+    };
+  }());
+
+const ProjectInterface = (function () {
+  function registerComposition(comp) {
+    this.compositions.push(comp);
+  }
+
+  return function () {
+    function _thisProjectFunction(name) {
+      var i = 0;
+      var len = this.compositions.length;
+      while (i < len) {
+        if (this.compositions[i].data && this.compositions[i].data.nm === name) {
+          if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
+            this.compositions[i].prepareFrame(this.currentFrame);
+          }
+          return this.compositions[i].compInterface;
+        }
+        i += 1;
+      }
+      return null;
+    }
+
+    _thisProjectFunction.compositions = [];
+    _thisProjectFunction.currentFrame = 0;
+
+    _thisProjectFunction.registerComposition = registerComposition;
+
+    return _thisProjectFunction;
+  };
+}());
+
+const renderers = {};
+
+const registerRenderer = (key, value) => {
+  renderers[key] = value;
+};
+
+function getRenderer(key) {
+  return renderers[key];
+}
+
+function getRegisteredRenderer() {
+  // Returns canvas by default for compatibility
+  if (renderers.canvas) {
+    return 'canvas';
+  }
+  // Returns any renderer that is registered
+  for (const key in renderers) {
+    if (renderers[key]) {
+      return key;
+    }
+  }
+  return '';
+}
+
+const AnimationItem = function () {
+  this._cbs = [];
+  this.name = '';
+  this.path = '';
+  this.isLoaded = false;
+  this.currentFrame = 0;
+  this.currentRawFrame = 0;
+  this.firstFrame = 0;
+  this.totalFrames = 0;
+  this.frameRate = 0;
+  this.frameMult = 0;
+  this.playSpeed = 1;
+  this.playDirection = 1;
+  this.playCount = 0;
+  this.animationData = {};
+  this.assets = [];
+  this.isPaused = true;
+  this.autoplay = false;
+  this.loop = true;
+  this.renderer = null;
+  this.animationID = createElementID();
+  this.assetsPath = '';
+  this.timeCompleted = 0;
+  this.segmentPos = 0;
+  this.isSubframeEnabled = getSubframeEnabled();
+  this.segments = [];
+  this._idle = true;
+  this._completedLoop = false;
+  this.projectInterface = ProjectInterface();
+  this.imagePreloader = new ImagePreloader();
+  this.audioController = audioControllerFactory();
+  this.markers = [];
+  this.configAnimation = this.configAnimation.bind(this);
+  this.onSetupError = this.onSetupError.bind(this);
+  this.onSegmentComplete = this.onSegmentComplete.bind(this);
+  this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
+  this.expressionsPlugin = getExpressionsPlugin();
+};
+
+extendPrototype([BaseEvent], AnimationItem);
+
+AnimationItem.prototype.setParams = function (params) {
+  if (params.wrapper || params.container) {
+    this.wrapper = params.wrapper || params.container;
+  }
+  var animType = 'svg';
+  if (params.animType) {
+    animType = params.animType;
+  } else if (params.renderer) {
+    animType = params.renderer;
+  }
+  const RendererClass = getRenderer(animType);
+  this.renderer = new RendererClass(this, params.rendererSettings);
+  this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
+  this.renderer.setProjectInterface(this.projectInterface);
+  this.animType = animType;
+  if (params.loop === ''
+        || params.loop === null
+        || params.loop === undefined
+        || params.loop === true) {
+    this.loop = true;
+  } else if (params.loop === false) {
+    this.loop = false;
+  } else {
+    this.loop = parseInt(params.loop, 10);
+  }
+  this.autoplay = 'autoplay' in params ? params.autoplay : true;
+  this.name = params.name ? params.name : '';
+  this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
+  this.assetsPath = params.assetsPath;
+  this.initialSegment = params.initialSegment;
+  if (params.audioFactory) {
+    this.audioController.setAudioFactory(params.audioFactory);
+  }
+  if (params.animationData) {
+    this.setupAnimation(params.animationData);
+  } else if (params.path) {
+    if (params.path.lastIndexOf('\\') !== -1) {
+      this.path = params.path.substr(0, params.path.lastIndexOf('\\') + 1);
+    } else {
+      this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
+    }
+    this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
+    this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
+    dataManager.loadAnimation(
+      params.path,
+      this.configAnimation,
+      this.onSetupError
+    );
+  }
+};
+
+AnimationItem.prototype.onSetupError = function () {
+  this.trigger('data_failed');
+};
+
+AnimationItem.prototype.setupAnimation = function (data) {
+  dataManager.completeAnimation(
+    data,
+    this.configAnimation
+  );
+};
+
+AnimationItem.prototype.setData = function (wrapper, animationData) {
+  if (animationData) {
+    if (typeof animationData !== 'object') {
+      animationData = JSON.parse(animationData);
+    }
+  }
+  var params = {
+    wrapper: wrapper,
+    animationData: animationData,
+  };
+  var wrapperAttributes = wrapper.attributes;
+
+  params.path = wrapperAttributes.getNamedItem('data-animation-path') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-animation-path').value
+    : wrapperAttributes.getNamedItem('data-bm-path') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-path').value
+      : wrapperAttributes.getNamedItem('bm-path')
+        ? wrapperAttributes.getNamedItem('bm-path').value
+        : '';
+  params.animType = wrapperAttributes.getNamedItem('data-anim-type') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-type').value
+    : wrapperAttributes.getNamedItem('data-bm-type') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-type').value
+      : wrapperAttributes.getNamedItem('bm-type') // eslint-disable-line no-nested-ternary
+        ? wrapperAttributes.getNamedItem('bm-type').value
+        : wrapperAttributes.getNamedItem('data-bm-renderer') // eslint-disable-line no-nested-ternary
+          ? wrapperAttributes.getNamedItem('data-bm-renderer').value
+          : wrapperAttributes.getNamedItem('bm-renderer')
+            ? wrapperAttributes.getNamedItem('bm-renderer').value
+            : getRegisteredRenderer() || 'canvas';
+
+  var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-loop').value
+    : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-loop').value
+      : wrapperAttributes.getNamedItem('bm-loop')
+        ? wrapperAttributes.getNamedItem('bm-loop').value
+        : '';
+  if (loop === 'false') {
+    params.loop = false;
+  } else if (loop === 'true') {
+    params.loop = true;
+  } else if (loop !== '') {
+    params.loop = parseInt(loop, 10);
+  }
+  var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-autoplay').value
+    : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-autoplay').value
+      : wrapperAttributes.getNamedItem('bm-autoplay')
+        ? wrapperAttributes.getNamedItem('bm-autoplay').value
+        : true;
+  params.autoplay = autoplay !== 'false';
+
+  params.name = wrapperAttributes.getNamedItem('data-name') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-name').value
+    : wrapperAttributes.getNamedItem('data-bm-name') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-name').value
+      : wrapperAttributes.getNamedItem('bm-name')
+        ? wrapperAttributes.getNamedItem('bm-name').value
+        : '';
+  var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-prerender').value
+    : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-prerender').value
+      : wrapperAttributes.getNamedItem('bm-prerender')
+        ? wrapperAttributes.getNamedItem('bm-prerender').value
+        : '';
+
+  if (prerender === 'false') {
+    params.prerender = false;
+  }
+  if (!params.path) {
+    this.trigger('destroy');
+  } else {
+    this.setParams(params);
+  }
+};
+
+AnimationItem.prototype.includeLayers = function (data) {
+  if (data.op > this.animationData.op) {
+    this.animationData.op = data.op;
+    this.totalFrames = Math.floor(data.op - this.animationData.ip);
+  }
+  var layers = this.animationData.layers;
+  var i;
+  var len = layers.length;
+  var newLayers = data.layers;
+  var j;
+  var jLen = newLayers.length;
+  for (j = 0; j < jLen; j += 1) {
+    i = 0;
+    while (i < len) {
+      if (layers[i].id === newLayers[j].id) {
+        layers[i] = newLayers[j];
+        break;
+      }
+      i += 1;
+    }
+  }
+  if (data.chars || data.fonts) {
+    this.renderer.globalData.fontManager.addChars(data.chars);
+    this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
+  }
+  if (data.assets) {
+    len = data.assets.length;
+    for (i = 0; i < len; i += 1) {
+      this.animationData.assets.push(data.assets[i]);
+    }
+  }
+  this.animationData.__complete = false;
+  dataManager.completeAnimation(
+    this.animationData,
+    this.onSegmentComplete
+  );
+};
+
+AnimationItem.prototype.onSegmentComplete = function (data) {
+  this.animationData = data;
+  var expressionsPlugin = getExpressionsPlugin();
+  if (expressionsPlugin) {
+    expressionsPlugin.initExpressions(this);
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.loadNextSegment = function () {
+  var segments = this.animationData.segments;
+  if (!segments || segments.length === 0 || !this.autoloadSegments) {
+    this.trigger('data_ready');
+    this.timeCompleted = this.totalFrames;
+    return;
+  }
+  var segment = segments.shift();
+  this.timeCompleted = segment.time * this.frameRate;
+  var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
+  this.segmentPos += 1;
+  dataManager.loadData(segmentPath, this.includeLayers.bind(this), function () {
+    this.trigger('data_failed');
+  }.bind(this));
+};
+
+AnimationItem.prototype.loadSegments = function () {
+  var segments = this.animationData.segments;
+  if (!segments) {
+    this.timeCompleted = this.totalFrames;
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.imagesLoaded = function () {
+  this.trigger('loaded_images');
+  this.checkLoaded();
+};
+
+AnimationItem.prototype.preloadImages = function () {
+  this.imagePreloader.setAssetsPath(this.assetsPath);
+  this.imagePreloader.setPath(this.path);
+  this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
+};
+
+AnimationItem.prototype.configAnimation = function (animData) {
+  if (!this.renderer) {
+    return;
+  }
+  try {
+    this.animationData = animData;
+    if (this.initialSegment) {
+      this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
+      this.firstFrame = Math.round(this.initialSegment[0]);
+    } else {
+      this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
+      this.firstFrame = Math.round(this.animationData.ip);
+    }
+    this.renderer.configAnimation(animData);
+    if (!animData.assets) {
+      animData.assets = [];
+    }
+
+    this.assets = this.animationData.assets;
+    this.frameRate = this.animationData.fr;
+    this.frameMult = this.animationData.fr / 1000;
+    this.renderer.searchExtraCompositions(animData.assets);
+    this.markers = markerParser(animData.markers || []);
+    this.trigger('config_ready');
+    this.preloadImages();
+    this.loadSegments();
+    this.updaFrameModifier();
+    this.waitForFontsLoaded();
+    if (this.isPaused) {
+      this.audioController.pause();
+    }
+  } catch (error) {
+    this.triggerConfigError(error);
+  }
+};
+
+AnimationItem.prototype.waitForFontsLoaded = function () {
+  if (!this.renderer) {
+    return;
+  }
+  if (this.renderer.globalData.fontManager.isLoaded) {
+    this.checkLoaded();
+  } else {
+    setTimeout(this.waitForFontsLoaded.bind(this), 20);
+  }
+};
+
+AnimationItem.prototype.checkLoaded = function () {
+  if (!this.isLoaded
+        && this.renderer.globalData.fontManager.isLoaded
+        && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas')
+        && (this.imagePreloader.loadedFootages())
+  ) {
+    this.isLoaded = true;
+    var expressionsPlugin = getExpressionsPlugin();
+    if (expressionsPlugin) {
+      expressionsPlugin.initExpressions(this);
+    }
+    this.renderer.initItems();
+    setTimeout(function () {
+      this.trigger('DOMLoaded');
+    }.bind(this), 0);
+    this.gotoFrame();
+    if (this.autoplay) {
+      this.play();
+    }
+  }
+};
+
+AnimationItem.prototype.resize = function (width, height) {
+  // Adding this validation for backwards compatibility in case an event object was being passed down
+  var _width = typeof width === 'number' ? width : undefined;
+  var _height = typeof height === 'number' ? height : undefined;
+  this.renderer.updateContainerSize(_width, _height);
+};
+
+AnimationItem.prototype.setSubframe = function (flag) {
+  this.isSubframeEnabled = !!flag;
+};
+
+AnimationItem.prototype.gotoFrame = function () {
+  this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
+
+  if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
+    this.currentFrame = this.timeCompleted;
+  }
+  this.trigger('enterFrame');
+  this.renderFrame();
+  this.trigger('drawnFrame');
+};
+
+AnimationItem.prototype.renderFrame = function () {
+  if (this.isLoaded === false || !this.renderer) {
+    return;
+  }
+  try {
+    if (this.expressionsPlugin) {
+      this.expressionsPlugin.resetFrame();
+    }
+    this.renderer.renderFrame(this.currentFrame + this.firstFrame);
+  } catch (error) {
+    this.triggerRenderFrameError(error);
+  }
+};
+
+AnimationItem.prototype.play = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.isPaused = false;
+    this.trigger('_play');
+    this.audioController.resume();
+    if (this._idle) {
+      this._idle = false;
+      this.trigger('_active');
+    }
+  }
+};
+
+AnimationItem.prototype.pause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === false) {
+    this.isPaused = true;
+    this.trigger('_pause');
+    this._idle = true;
+    this.trigger('_idle');
+    this.audioController.pause();
+  }
+};
+
+AnimationItem.prototype.togglePause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.play();
+  } else {
+    this.pause();
+  }
+};
+
+AnimationItem.prototype.stop = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.pause();
+  this.playCount = 0;
+  this._completedLoop = false;
+  this.setCurrentRawFrameValue(0);
+};
+
+AnimationItem.prototype.getMarkerData = function (markerName) {
+  var marker;
+  for (var i = 0; i < this.markers.length; i += 1) {
+    marker = this.markers[i];
+    if (marker.payload && marker.payload.name === markerName) {
+      return marker;
+    }
+  }
+  return null;
+};
+
+AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      this.goToAndStop(marker.time, true);
+    }
+  } else if (isFrame) {
+    this.setCurrentRawFrameValue(value);
+  } else {
+    this.setCurrentRawFrameValue(value * this.frameModifier);
+  }
+  this.pause();
+};
+
+AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      if (!marker.duration) {
+        this.goToAndStop(marker.time, true);
+      } else {
+        this.playSegments([marker.time, marker.time + marker.duration], true);
+      }
+    }
+  } else {
+    this.goToAndStop(numValue, isFrame, name);
+  }
+  this.play();
+};
+
+AnimationItem.prototype.advanceTime = function (value) {
+  if (this.isPaused === true || this.isLoaded === false) {
+    return;
+  }
+  var nextValue = this.currentRawFrame + value * this.frameModifier;
+  var _isComplete = false;
+  // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+  // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
+  if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
+    if (!this.loop || this.playCount === this.loop) {
+      if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
+        _isComplete = true;
+        nextValue = this.totalFrames - 1;
+      }
+    } else if (nextValue >= this.totalFrames) {
+      this.playCount += 1;
+      if (!this.checkSegments(nextValue % this.totalFrames)) {
+        this.setCurrentRawFrameValue(nextValue % this.totalFrames);
+        this._completedLoop = true;
+        this.trigger('loopComplete');
+      }
+    } else {
+      this.setCurrentRawFrameValue(nextValue);
+    }
+  } else if (nextValue < 0) {
+    if (!this.checkSegments(nextValue % this.totalFrames)) {
+      if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) { // eslint-disable-line no-plusplus
+        this.setCurrentRawFrameValue(this.totalFrames + (nextValue % this.totalFrames));
+        if (!this._completedLoop) {
+          this._completedLoop = true;
+        } else {
+          this.trigger('loopComplete');
+        }
+      } else {
+        _isComplete = true;
+        nextValue = 0;
+      }
+    }
+  } else {
+    this.setCurrentRawFrameValue(nextValue);
+  }
+  if (_isComplete) {
+    this.setCurrentRawFrameValue(nextValue);
+    this.pause();
+    this.trigger('complete');
+  }
+};
+
+AnimationItem.prototype.adjustSegment = function (arr, offset) {
+  this.playCount = 0;
+  if (arr[1] < arr[0]) {
+    if (this.frameModifier > 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(-1);
+      }
+    }
+    this.totalFrames = arr[0] - arr[1];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[1];
+    this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset);
+  } else if (arr[1] > arr[0]) {
+    if (this.frameModifier < 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(1);
+      }
+    }
+    this.totalFrames = arr[1] - arr[0];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[0];
+    this.setCurrentRawFrameValue(0.001 + offset);
+  }
+  this.trigger('segmentStart');
+};
+AnimationItem.prototype.setSegment = function (init, end) {
+  var pendingFrame = -1;
+  if (this.isPaused) {
+    if (this.currentRawFrame + this.firstFrame < init) {
+      pendingFrame = init;
+    } else if (this.currentRawFrame + this.firstFrame > end) {
+      pendingFrame = end - init;
+    }
+  }
+
+  this.firstFrame = init;
+  this.totalFrames = end - init;
+  this.timeCompleted = this.totalFrames;
+  if (pendingFrame !== -1) {
+    this.goToAndStop(pendingFrame, true);
+  }
+};
+
+AnimationItem.prototype.playSegments = function (arr, forceFlag) {
+  if (forceFlag) {
+    this.segments.length = 0;
+  }
+  if (typeof arr[0] === 'object') {
+    var i;
+    var len = arr.length;
+    for (i = 0; i < len; i += 1) {
+      this.segments.push(arr[i]);
+    }
+  } else {
+    this.segments.push(arr);
+  }
+  if (this.segments.length && forceFlag) {
+    this.adjustSegment(this.segments.shift(), 0);
+  }
+  if (this.isPaused) {
+    this.play();
+  }
+};
+
+AnimationItem.prototype.resetSegments = function (forceFlag) {
+  this.segments.length = 0;
+  this.segments.push([this.animationData.ip, this.animationData.op]);
+  if (forceFlag) {
+    this.checkSegments(0);
+  }
+};
+AnimationItem.prototype.checkSegments = function (offset) {
+  if (this.segments.length) {
+    this.adjustSegment(this.segments.shift(), offset);
+    return true;
+  }
+  return false;
+};
+
+AnimationItem.prototype.destroy = function (name) {
+  if ((name && this.name !== name) || !this.renderer) {
+    return;
+  }
+  this.renderer.destroy();
+  this.imagePreloader.destroy();
+  this.trigger('destroy');
+  this._cbs = null;
+  this.onEnterFrame = null;
+  this.onLoopComplete = null;
+  this.onComplete = null;
+  this.onSegmentStart = null;
+  this.onDestroy = null;
+  this.renderer = null;
+  this.expressionsPlugin = null;
+  this.imagePreloader = null;
+  this.projectInterface = null;
+};
+
+AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
+  this.currentRawFrame = value;
+  this.gotoFrame();
+};
+
+AnimationItem.prototype.setSpeed = function (val) {
+  this.playSpeed = val;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setDirection = function (val) {
+  this.playDirection = val < 0 ? -1 : 1;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setLoop = function (isLooping) {
+  this.loop = isLooping;
+};
+
+AnimationItem.prototype.setVolume = function (val, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.setVolume(val);
+};
+
+AnimationItem.prototype.getVolume = function () {
+  return this.audioController.getVolume();
+};
+
+AnimationItem.prototype.mute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.mute();
+};
+
+AnimationItem.prototype.unmute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.unmute();
+};
+
+AnimationItem.prototype.updaFrameModifier = function () {
+  this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
+  this.audioController.setRate(this.playSpeed * this.playDirection);
+};
+
+AnimationItem.prototype.getPath = function () {
+  return this.path;
+};
+
+AnimationItem.prototype.getAssetsPath = function (assetData) {
+  var path = '';
+  if (assetData.e) {
+    path = assetData.p;
+  } else if (this.assetsPath) {
+    var imagePath = assetData.p;
+    if (imagePath.indexOf('images/') !== -1) {
+      imagePath = imagePath.split('/')[1];
+    }
+    path = this.assetsPath + imagePath;
+  } else {
+    path = this.path;
+    path += assetData.u ? assetData.u : '';
+    path += assetData.p;
+  }
+  return path;
+};
+
+AnimationItem.prototype.getAssetData = function (id) {
+  var i = 0;
+  var len = this.assets.length;
+  while (i < len) {
+    if (id === this.assets[i].id) {
+      return this.assets[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+AnimationItem.prototype.hide = function () {
+  this.renderer.hide();
+};
+
+AnimationItem.prototype.show = function () {
+  this.renderer.show();
+};
+
+AnimationItem.prototype.getDuration = function (isFrame) {
+  return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
+};
+
+AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
+  try {
+    var element = this.renderer.getElementByPath(path);
+    element.updateDocumentData(documentData, index);
+  } catch (error) {
+    // TODO: decide how to handle catch case
+  }
+};
+
+AnimationItem.prototype.trigger = function (name) {
+  if (this._cbs && this._cbs[name]) {
+    switch (name) {
+      case 'enterFrame':
+        this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
+        break;
+      case 'drawnFrame':
+        this.drawnFrameEvent.currentTime = this.currentFrame;
+        this.drawnFrameEvent.totalTime = this.totalFrames;
+        this.drawnFrameEvent.direction = this.frameModifier;
+        this.triggerEvent(name, this.drawnFrameEvent);
+        break;
+      case 'loopComplete':
+        this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+        break;
+      case 'complete':
+        this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
+        break;
+      case 'segmentStart':
+        this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+        break;
+      case 'destroy':
+        this.triggerEvent(name, new BMDestroyEvent(name, this));
+        break;
+      default:
+        this.triggerEvent(name);
+    }
+  }
+  if (name === 'enterFrame' && this.onEnterFrame) {
+    this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
+  }
+  if (name === 'loopComplete' && this.onLoopComplete) {
+    this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+  }
+  if (name === 'complete' && this.onComplete) {
+    this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
+  }
+  if (name === 'segmentStart' && this.onSegmentStart) {
+    this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+  }
+  if (name === 'destroy' && this.onDestroy) {
+    this.onDestroy.call(this, new BMDestroyEvent(name, this));
+  }
+};
+
+AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
+  var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+AnimationItem.prototype.triggerConfigError = function (nativeError) {
+  var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+const animationManager = (function () {
+  var moduleOb = {};
+  var registeredAnimations = [];
+  var initTime = 0;
+  var len = 0;
+  var playingAnimationsNum = 0;
+  var _stopped = true;
+  var _isFrozen = false;
+
+  function removeElement(ev) {
+    var i = 0;
+    var animItem = ev.target;
+    while (i < len) {
+      if (registeredAnimations[i].animation === animItem) {
+        registeredAnimations.splice(i, 1);
+        i -= 1;
+        len -= 1;
+        if (!animItem.isPaused) {
+          subtractPlayingCount();
+        }
+      }
+      i += 1;
+    }
+  }
+
+  function registerAnimation(element, animationData) {
+    if (!element) {
+      return null;
+    }
+    var i = 0;
+    while (i < len) {
+      if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
+        return registeredAnimations[i].animation;
+      }
+      i += 1;
+    }
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, element);
+    animItem.setData(element, animationData);
+    return animItem;
+  }
+
+  function getRegisteredAnimations() {
+    var i;
+    var lenAnims = registeredAnimations.length;
+    var animations = [];
+    for (i = 0; i < lenAnims; i += 1) {
+      animations.push(registeredAnimations[i].animation);
+    }
+    return animations;
+  }
+
+  function addPlayingCount() {
+    playingAnimationsNum += 1;
+    activate();
+  }
+
+  function subtractPlayingCount() {
+    playingAnimationsNum -= 1;
+  }
+
+  function setupAnimation(animItem, element) {
+    animItem.addEventListener('destroy', removeElement);
+    animItem.addEventListener('_active', addPlayingCount);
+    animItem.addEventListener('_idle', subtractPlayingCount);
+    registeredAnimations.push({ elem: element, animation: animItem });
+    len += 1;
+  }
+
+  function loadAnimation(params) {
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, null);
+    animItem.setParams(params);
+    return animItem;
+  }
+
+  function setSpeed(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setSpeed(val, animation);
+    }
+  }
+
+  function setDirection(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setDirection(val, animation);
+    }
+  }
+
+  function play(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.play(animation);
+    }
+  }
+  function resume(nowTime) {
+    var elapsedTime = nowTime - initTime;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.advanceTime(elapsedTime);
+    }
+    initTime = nowTime;
+    if (playingAnimationsNum && !_isFrozen) {
+      window.requestAnimationFrame(resume);
+    } else {
+      _stopped = true;
+    }
+  }
+
+  function first(nowTime) {
+    initTime = nowTime;
+    window.requestAnimationFrame(resume);
+  }
+
+  function pause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.pause(animation);
+    }
+  }
+
+  function goToAndStop(value, isFrame, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
+    }
+  }
+
+  function stop(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.stop(animation);
+    }
+  }
+
+  function togglePause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.togglePause(animation);
+    }
+  }
+
+  function destroy(animation) {
+    var i;
+    for (i = (len - 1); i >= 0; i -= 1) {
+      registeredAnimations[i].animation.destroy(animation);
+    }
+  }
+
+  function searchAnimations(animationData, standalone, renderer) {
+    var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')),
+      [].slice.call(document.getElementsByClassName('bodymovin')));
+    var i;
+    var lenAnims = animElements.length;
+    for (i = 0; i < lenAnims; i += 1) {
+      if (renderer) {
+        animElements[i].setAttribute('data-bm-type', renderer);
+      }
+      registerAnimation(animElements[i], animationData);
+    }
+    if (standalone && lenAnims === 0) {
+      if (!renderer) {
+        renderer = 'svg';
+      }
+      var body = document.getElementsByTagName('body')[0];
+      body.innerText = '';
+      var div = createTag('div');
+      div.style.width = '100%';
+      div.style.height = '100%';
+      div.setAttribute('data-bm-type', renderer);
+      body.appendChild(div);
+      registerAnimation(div, animationData);
+    }
+  }
+
+  function resize() {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.resize();
+    }
+  }
+
+  function activate() {
+    if (!_isFrozen && playingAnimationsNum) {
+      if (_stopped) {
+        window.requestAnimationFrame(first);
+        _stopped = false;
+      }
+    }
+  }
+
+  function freeze() {
+    _isFrozen = true;
+  }
+
+  function unfreeze() {
+    _isFrozen = false;
+    activate();
+  }
+
+  function setVolume(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setVolume(val, animation);
+    }
+  }
+
+  function mute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.mute(animation);
+    }
+  }
+
+  function unmute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.unmute(animation);
+    }
+  }
+
+  moduleOb.registerAnimation = registerAnimation;
+  moduleOb.loadAnimation = loadAnimation;
+  moduleOb.setSpeed = setSpeed;
+  moduleOb.setDirection = setDirection;
+  moduleOb.play = play;
+  moduleOb.pause = pause;
+  moduleOb.stop = stop;
+  moduleOb.togglePause = togglePause;
+  moduleOb.searchAnimations = searchAnimations;
+  moduleOb.resize = resize;
+  // moduleOb.start = start;
+  moduleOb.goToAndStop = goToAndStop;
+  moduleOb.destroy = destroy;
+  moduleOb.freeze = freeze;
+  moduleOb.unfreeze = unfreeze;
+  moduleOb.setVolume = setVolume;
+  moduleOb.mute = mute;
+  moduleOb.unmute = unmute;
+  moduleOb.getRegisteredAnimations = getRegisteredAnimations;
+  return moduleOb;
+}());
+
+/* eslint-disable */
+const BezierFactory = (function () {
+  /**
+     * BezierEasing - use bezier curve for transition easing function
+     * by Gaëtan Renaudeau 2014 - 2015 – MIT License
+     *
+     * Credits: is based on Firefox's nsSMILKeySpline.cpp
+     * Usage:
+     * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
+     * spline.get(x) => returns the easing value | x must be in [0, 1] range
+     *
+     */
+
+  var ob = {};
+  ob.getBezierEasing = getBezierEasing;
+  var beziers = {};
+
+  function getBezierEasing(a, b, c, d, nm) {
+    var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
+    if (beziers[str]) {
+      return beziers[str];
+    }
+    var bezEasing = new BezierEasing([a, b, c, d]);
+    beziers[str] = bezEasing;
+    return bezEasing;
+  }
+
+  // These values are established by empiricism with tests (tradeoff: performance VS precision)
+  var NEWTON_ITERATIONS = 4;
+  var NEWTON_MIN_SLOPE = 0.001;
+  var SUBDIVISION_PRECISION = 0.0000001;
+  var SUBDIVISION_MAX_ITERATIONS = 10;
+
+  var kSplineTableSize = 11;
+  var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
+
+  var float32ArraySupported = typeof Float32Array === 'function';
+
+  function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
+  function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
+  function C(aA1) { return 3.0 * aA1; }
+
+  // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+  function calcBezier(aT, aA1, aA2) {
+    return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
+  }
+
+  // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+  function getSlope(aT, aA1, aA2) {
+    return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
+  }
+
+  function binarySubdivide(aX, aA, aB, mX1, mX2) {
+    var currentX,
+      currentT,
+      i = 0;
+    do {
+      currentT = aA + (aB - aA) / 2.0;
+      currentX = calcBezier(currentT, mX1, mX2) - aX;
+      if (currentX > 0.0) {
+        aB = currentT;
+      } else {
+        aA = currentT;
+      }
+    } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
+    return currentT;
+  }
+
+  function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
+    for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
+      var currentSlope = getSlope(aGuessT, mX1, mX2);
+      if (currentSlope === 0.0) return aGuessT;
+      var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
+      aGuessT -= currentX / currentSlope;
+    }
+    return aGuessT;
+  }
+
+  /**
+     * points is an array of [ mX1, mY1, mX2, mY2 ]
+     */
+  function BezierEasing(points) {
+    this._p = points;
+    this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
+    this._precomputed = false;
+
+    this.get = this.get.bind(this);
+  }
+
+  BezierEasing.prototype = {
+
+    get: function (x) {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      if (!this._precomputed) this._precompute();
+      if (mX1 === mY1 && mX2 === mY2) return x; // linear
+      // Because JavaScript number are imprecise, we should guarantee the extremes are right.
+      if (x === 0) return 0;
+      if (x === 1) return 1;
+      return calcBezier(this._getTForX(x), mY1, mY2);
+    },
+
+    // Private part
+
+    _precompute: function () {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      this._precomputed = true;
+      if (mX1 !== mY1 || mX2 !== mY2) { this._calcSampleValues(); }
+    },
+
+    _calcSampleValues: function () {
+      var mX1 = this._p[0],
+        mX2 = this._p[2];
+      for (var i = 0; i < kSplineTableSize; ++i) {
+        this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
+      }
+    },
+
+    /**
+         * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
+         */
+    _getTForX: function (aX) {
+      var mX1 = this._p[0],
+        mX2 = this._p[2],
+        mSampleValues = this._mSampleValues;
+
+      var intervalStart = 0.0;
+      var currentSample = 1;
+      var lastSample = kSplineTableSize - 1;
+
+      for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
+        intervalStart += kSampleStepSize;
+      }
+      --currentSample;
+
+      // Interpolate to provide an initial guess for t
+      var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
+      var guessForT = intervalStart + dist * kSampleStepSize;
+
+      var initialSlope = getSlope(guessForT, mX1, mX2);
+      if (initialSlope >= NEWTON_MIN_SLOPE) {
+        return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
+      } if (initialSlope === 0.0) {
+        return guessForT;
+      }
+      return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
+    },
+  };
+
+  return ob;
+}());
+
+const pooling = (function () {
+  function double(arr) {
+    return arr.concat(createSizedArray(arr.length));
+  }
+
+  return {
+    double: double,
+  };
+}());
+
+const poolFactory = (function () {
+  return function (initialLength, _create, _release) {
+    var _length = 0;
+    var _maxLength = initialLength;
+    var pool = createSizedArray(_maxLength);
+
+    var ob = {
+      newElement: newElement,
+      release: release,
+    };
+
+    function newElement() {
+      var element;
+      if (_length) {
+        _length -= 1;
+        element = pool[_length];
+      } else {
+        element = _create();
+      }
+      return element;
+    }
+
+    function release(element) {
+      if (_length === _maxLength) {
+        pool = pooling.double(pool);
+        _maxLength *= 2;
+      }
+      if (_release) {
+        _release(element);
+      }
+      pool[_length] = element;
+      _length += 1;
+    }
+
+    return ob;
+  };
+}());
+
+const bezierLengthPool = (function () {
+  function create() {
+    return {
+      addedLength: 0,
+      percents: createTypedArray('float32', getDefaultCurveSegments()),
+      lengths: createTypedArray('float32', getDefaultCurveSegments()),
+    };
+  }
+  return poolFactory(8, create);
+}());
+
+const segmentsLengthPool = (function () {
+  function create() {
+    return {
+      lengths: [],
+      totalLength: 0,
+    };
+  }
+
+  function release(element) {
+    var i;
+    var len = element.lengths.length;
+    for (i = 0; i < len; i += 1) {
+      bezierLengthPool.release(element.lengths[i]);
+    }
+    element.lengths.length = 0;
+  }
+
+  return poolFactory(8, create, release);
+}());
+
+function bezFunction() {
+  var math = Math;
+
+  function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
+    var det1 = (x1 * y2) + (y1 * x3) + (x2 * y3) - (x3 * y2) - (y3 * x1) - (x2 * y1);
+    return det1 > -0.001 && det1 < 0.001;
+  }
+
+  function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
+    if (z1 === 0 && z2 === 0 && z3 === 0) {
+      return pointOnLine2D(x1, y1, x2, y2, x3, y3);
+    }
+    var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
+    var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
+    var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
+    var diffDist;
+    if (dist1 > dist2) {
+      if (dist1 > dist3) {
+        diffDist = dist1 - dist2 - dist3;
+      } else {
+        diffDist = dist3 - dist2 - dist1;
+      }
+    } else if (dist3 > dist2) {
+      diffDist = dist3 - dist2 - dist1;
+    } else {
+      diffDist = dist2 - dist1 - dist3;
+    }
+    return diffDist > -0.0001 && diffDist < 0.0001;
+  }
+
+  var getBezierLength = (function () {
+    return function (pt1, pt2, pt3, pt4) {
+      var curveSegments = getDefaultCurveSegments();
+      var k;
+      var i;
+      var len;
+      var ptCoord;
+      var perc;
+      var addedLength = 0;
+      var ptDistance;
+      var point = [];
+      var lastPoint = [];
+      var lengthData = bezierLengthPool.newElement();
+      len = pt3.length;
+      for (k = 0; k < curveSegments; k += 1) {
+        perc = k / (curveSegments - 1);
+        ptDistance = 0;
+        for (i = 0; i < len; i += 1) {
+          ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
+          point[i] = ptCoord;
+          if (lastPoint[i] !== null) {
+            ptDistance += bmPow(point[i] - lastPoint[i], 2);
+          }
+          lastPoint[i] = point[i];
+        }
+        if (ptDistance) {
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+        }
+        lengthData.percents[k] = perc;
+        lengthData.lengths[k] = addedLength;
+      }
+      lengthData.addedLength = addedLength;
+      return lengthData;
+    };
+  }());
+
+  function getSegmentsLength(shapeData) {
+    var segmentsLength = segmentsLengthPool.newElement();
+    var closed = shapeData.c;
+    var pathV = shapeData.v;
+    var pathO = shapeData.o;
+    var pathI = shapeData.i;
+    var i;
+    var len = shapeData._length;
+    var lengths = segmentsLength.lengths;
+    var totalLength = 0;
+    for (i = 0; i < len - 1; i += 1) {
+      lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
+      totalLength += lengths[i].addedLength;
+    }
+    if (closed && len) {
+      lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
+      totalLength += lengths[i].addedLength;
+    }
+    segmentsLength.totalLength = totalLength;
+    return segmentsLength;
+  }
+
+  function BezierData(length) {
+    this.segmentLength = 0;
+    this.points = new Array(length);
+  }
+
+  function PointData(partial, point) {
+    this.partialLength = partial;
+    this.point = point;
+  }
+
+  var buildBezierData = (function () {
+    var storedData = {};
+
+    return function (pt1, pt2, pt3, pt4) {
+      var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
+      if (!storedData[bezierName]) {
+        var curveSegments = getDefaultCurveSegments();
+        var k;
+        var i;
+        var len;
+        var ptCoord;
+        var perc;
+        var addedLength = 0;
+        var ptDistance;
+        var point;
+        var lastPoint = null;
+        if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
+          curveSegments = 2;
+        }
+        var bezierData = new BezierData(curveSegments);
+        len = pt3.length;
+        for (k = 0; k < curveSegments; k += 1) {
+          point = createSizedArray(len);
+          perc = k / (curveSegments - 1);
+          ptDistance = 0;
+          for (i = 0; i < len; i += 1) {
+            ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
+            point[i] = ptCoord;
+            if (lastPoint !== null) {
+              ptDistance += bmPow(point[i] - lastPoint[i], 2);
+            }
+          }
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+          bezierData.points[k] = new PointData(ptDistance, point);
+          lastPoint = point;
+        }
+        bezierData.segmentLength = addedLength;
+        storedData[bezierName] = bezierData;
+      }
+      return storedData[bezierName];
+    };
+  }());
+
+  function getDistancePerc(perc, bezierData) {
+    var percents = bezierData.percents;
+    var lengths = bezierData.lengths;
+    var len = percents.length;
+    var initPos = bmFloor((len - 1) * perc);
+    var lengthPos = perc * bezierData.addedLength;
+    var lPerc = 0;
+    if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
+      return percents[initPos];
+    }
+    var dir = lengths[initPos] > lengthPos ? -1 : 1;
+    var flag = true;
+    while (flag) {
+      if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
+        lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
+        flag = false;
+      } else {
+        initPos += dir;
+      }
+      if (initPos < 0 || initPos >= len - 1) {
+        // FIX for TypedArrays that don't store floating point values with enough accuracy
+        if (initPos === len - 1) {
+          return percents[initPos];
+        }
+        flag = false;
+      }
+    }
+    return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
+  }
+
+  function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
+    var t1 = getDistancePerc(percent, bezierData);
+    var u1 = 1 - t1;
+    var ptX = math.round((u1 * u1 * u1 * pt1[0] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[0] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[0] + t1 * t1 * t1 * pt2[0]) * 1000) / 1000;
+    var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
+    return [ptX, ptY];
+  }
+
+  var bezierSegmentPoints = createTypedArray('float32', 8);
+
+  function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
+    if (startPerc < 0) {
+      startPerc = 0;
+    } else if (startPerc > 1) {
+      startPerc = 1;
+    }
+    var t0 = getDistancePerc(startPerc, bezierData);
+    endPerc = endPerc > 1 ? 1 : endPerc;
+    var t1 = getDistancePerc(endPerc, bezierData);
+    var i;
+    var len = pt1.length;
+    var u0 = 1 - t0;
+    var u1 = 1 - t1;
+    var u0u0u0 = u0 * u0 * u0;
+    var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0t0 = t0 * t0 * t0;
+    //
+    var u0u0u1 = u0 * u0 * u1;
+    var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0t1 = t0 * t0 * t1;
+    //
+    var u0u1u1 = u0 * u1 * u1;
+    var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1t1 = t0 * t1 * t1;
+    //
+    var u1u1u1 = u1 * u1 * u1;
+    var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1t1 = t1 * t1 * t1;
+    for (i = 0; i < len; i += 1) {
+      bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+    }
+
+    return bezierSegmentPoints;
+  }
+
+  return {
+    getSegmentsLength: getSegmentsLength,
+    getNewSegment: getNewSegment,
+    getPointInSegment: getPointInSegment,
+    buildBezierData: buildBezierData,
+    pointOnLine2D: pointOnLine2D,
+    pointOnLine3D: pointOnLine3D,
+  };
+}
+
+const bez = bezFunction();
+
+var initFrame = initialDefaultFrame;
+var mathAbs = Math.abs;
+
+function interpolateValue(frameNum, caching) {
+  var offsetTime = this.offsetTime;
+  var newValue;
+  if (this.propType === 'multidimensional') {
+    newValue = createTypedArray('float32', this.pv.length);
+  }
+  var iterationIndex = caching.lastIndex;
+  var i = iterationIndex;
+  var len = this.keyframes.length - 1;
+  var flag = true;
+  var keyData;
+  var nextKeyData;
+  var keyframeMetadata;
+
+  while (flag) {
+    keyData = this.keyframes[i];
+    nextKeyData = this.keyframes[i + 1];
+    if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
+      if (keyData.h) {
+        keyData = nextKeyData;
+      }
+      iterationIndex = 0;
+      break;
+    }
+    if ((nextKeyData.t - offsetTime) > frameNum) {
+      iterationIndex = i;
+      break;
+    }
+    if (i < len - 1) {
+      i += 1;
+    } else {
+      iterationIndex = 0;
+      flag = false;
+    }
+  }
+  keyframeMetadata = this.keyframesMetadata[i] || {};
+
+  var k;
+  var kLen;
+  var perc;
+  var jLen;
+  var j;
+  var fnc;
+  var nextKeyTime = nextKeyData.t - offsetTime;
+  var keyTime = keyData.t - offsetTime;
+  var endValue;
+  if (keyData.to) {
+    if (!keyframeMetadata.bezierData) {
+      keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
+    }
+    var bezierData = keyframeMetadata.bezierData;
+    if (frameNum >= nextKeyTime || frameNum < keyTime) {
+      var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
+      kLen = bezierData.points[ind].point.length;
+      for (k = 0; k < kLen; k += 1) {
+        newValue[k] = bezierData.points[ind].point[k];
+      }
+      // caching._lastKeyframeIndex = -1;
+    } else {
+      if (keyframeMetadata.__fnct) {
+        fnc = keyframeMetadata.__fnct;
+      } else {
+        fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
+        keyframeMetadata.__fnct = fnc;
+      }
+      perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+      var distanceInLine = bezierData.segmentLength * perc;
+
+      var segmentPerc;
+      var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0;
+      j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0;
+      flag = true;
+      jLen = bezierData.points.length;
+      while (flag) {
+        addedLength += bezierData.points[j].partialLength;
+        if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k];
+          }
+          break;
+        } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
+          segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
+          }
+          break;
+        }
+        if (j < jLen - 1) {
+          j += 1;
+        } else {
+          flag = false;
+        }
+      }
+      caching._lastPoint = j;
+      caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
+      caching._lastKeyframeIndex = i;
+    }
+  } else {
+    var outX;
+    var outY;
+    var inX;
+    var inY;
+    var keyValue;
+    len = keyData.s.length;
+    endValue = nextKeyData.s || keyData.e;
+    if (this.sh && keyData.h !== 1) {
+      if (frameNum >= nextKeyTime) {
+        newValue[0] = endValue[0];
+        newValue[1] = endValue[1];
+        newValue[2] = endValue[2];
+      } else if (frameNum <= keyTime) {
+        newValue[0] = keyData.s[0];
+        newValue[1] = keyData.s[1];
+        newValue[2] = keyData.s[2];
+      } else {
+        var quatStart = createQuaternion(keyData.s);
+        var quatEnd = createQuaternion(endValue);
+        var time = (frameNum - keyTime) / (nextKeyTime - keyTime);
+        quaternionToEuler(newValue, slerp(quatStart, quatEnd, time));
+      }
+    } else {
+      for (i = 0; i < len; i += 1) {
+        if (keyData.h !== 1) {
+          if (frameNum >= nextKeyTime) {
+            perc = 1;
+          } else if (frameNum < keyTime) {
+            perc = 0;
+          } else {
+            if (keyData.o.x.constructor === Array) {
+              if (!keyframeMetadata.__fnct) {
+                keyframeMetadata.__fnct = [];
+              }
+              if (!keyframeMetadata.__fnct[i]) {
+                outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
+                outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
+                inX = keyData.i.x[i] === undefined ? keyData.i.x[0] : keyData.i.x[i];
+                inY = keyData.i.y[i] === undefined ? keyData.i.y[0] : keyData.i.y[i];
+                fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+                keyframeMetadata.__fnct[i] = fnc;
+              } else {
+                fnc = keyframeMetadata.__fnct[i];
+              }
+            } else if (!keyframeMetadata.__fnct) {
+              outX = keyData.o.x;
+              outY = keyData.o.y;
+              inX = keyData.i.x;
+              inY = keyData.i.y;
+              fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+              keyData.keyframeMetadata = fnc;
+            } else {
+              fnc = keyframeMetadata.__fnct;
+            }
+            perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+          }
+        }
+
+        endValue = nextKeyData.s || keyData.e;
+        keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
+
+        if (this.propType === 'multidimensional') {
+          newValue[i] = keyValue;
+        } else {
+          newValue = keyValue;
+        }
+      }
+    }
+  }
+  caching.lastIndex = iterationIndex;
+  return newValue;
+}
+
+// based on @Toji's https://github.com/toji/gl-matrix/
+function slerp(a, b, t) {
+  var out = [];
+  var ax = a[0];
+  var ay = a[1];
+  var az = a[2];
+  var aw = a[3];
+  var bx = b[0];
+  var by = b[1];
+  var bz = b[2];
+  var bw = b[3];
+
+  var omega;
+  var cosom;
+  var sinom;
+  var scale0;
+  var scale1;
+
+  cosom = ax * bx + ay * by + az * bz + aw * bw;
+  if (cosom < 0.0) {
+    cosom = -cosom;
+    bx = -bx;
+    by = -by;
+    bz = -bz;
+    bw = -bw;
+  }
+  if ((1.0 - cosom) > 0.000001) {
+    omega = Math.acos(cosom);
+    sinom = Math.sin(omega);
+    scale0 = Math.sin((1.0 - t) * omega) / sinom;
+    scale1 = Math.sin(t * omega) / sinom;
+  } else {
+    scale0 = 1.0 - t;
+    scale1 = t;
+  }
+  out[0] = scale0 * ax + scale1 * bx;
+  out[1] = scale0 * ay + scale1 * by;
+  out[2] = scale0 * az + scale1 * bz;
+  out[3] = scale0 * aw + scale1 * bw;
+
+  return out;
+}
+
+function quaternionToEuler(out, quat) {
+  var qx = quat[0];
+  var qy = quat[1];
+  var qz = quat[2];
+  var qw = quat[3];
+  var heading = Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy * qy - 2 * qz * qz);
+  var attitude = Math.asin(2 * qx * qy + 2 * qz * qw);
+  var bank = Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx * qx - 2 * qz * qz);
+  out[0] = heading / degToRads;
+  out[1] = attitude / degToRads;
+  out[2] = bank / degToRads;
+}
+
+function createQuaternion(values) {
+  var heading = values[0] * degToRads;
+  var attitude = values[1] * degToRads;
+  var bank = values[2] * degToRads;
+  var c1 = Math.cos(heading / 2);
+  var c2 = Math.cos(attitude / 2);
+  var c3 = Math.cos(bank / 2);
+  var s1 = Math.sin(heading / 2);
+  var s2 = Math.sin(attitude / 2);
+  var s3 = Math.sin(bank / 2);
+  var w = c1 * c2 * c3 - s1 * s2 * s3;
+  var x = s1 * s2 * c3 + c1 * c2 * s3;
+  var y = s1 * c2 * c3 + c1 * s2 * s3;
+  var z = c1 * s2 * c3 - s1 * c2 * s3;
+
+  return [x, y, z, w];
+}
+
+function getValueAtCurrentTime() {
+  var frameNum = this.comp.renderedFrame - this.offsetTime;
+  var initTime = this.keyframes[0].t - this.offsetTime;
+  var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+  if (!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))) {
+    if (this._caching.lastFrame >= frameNum) {
+      this._caching._lastKeyframeIndex = -1;
+      this._caching.lastIndex = 0;
+    }
+
+    var renderResult = this.interpolateValue(frameNum, this._caching);
+    this.pv = renderResult;
+  }
+  this._caching.lastFrame = frameNum;
+  return this.pv;
+}
+
+function setVValue(val) {
+  var multipliedValue;
+  if (this.propType === 'unidimensional') {
+    multipliedValue = val * this.mult;
+    if (mathAbs(this.v - multipliedValue) > 0.00001) {
+      this.v = multipliedValue;
+      this._mdf = true;
+    }
+  } else {
+    var i = 0;
+    var len = this.v.length;
+    while (i < len) {
+      multipliedValue = val[i] * this.mult;
+      if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
+        this.v[i] = multipliedValue;
+        this._mdf = true;
+      }
+      i += 1;
+    }
+  }
+}
+
+function processEffectsSequence() {
+  if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
+    return;
+  }
+  if (this.lock) {
+    this.setVValue(this.pv);
+    return;
+  }
+  this.lock = true;
+  this._mdf = this._isFirstFrame;
+  var i;
+  var len = this.effectsSequence.length;
+  var finalValue = this.kf ? this.pv : this.data.k;
+  for (i = 0; i < len; i += 1) {
+    finalValue = this.effectsSequence[i](finalValue);
+  }
+  this.setVValue(finalValue);
+  this._isFirstFrame = false;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+}
+
+function addEffect(effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.container.addDynamicProperty(this);
+}
+
+function ValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this.v = mult ? data.k * mult : data.k;
+  this.pv = data.k;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.vel = 0;
+  this.effectsSequence = [];
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function MultiDimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.frameId = -1;
+  var i;
+  var len = data.k.length;
+  this.v = createTypedArray('float32', len);
+  this.pv = createTypedArray('float32', len);
+  this.vel = createTypedArray('float32', len);
+  for (i = 0; i < len; i += 1) {
+    this.v[i] = data.k[i] * this.mult;
+    this.pv[i] = data.k[i];
+  }
+  this._isFirstFrame = true;
+  this.effectsSequence = [];
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function KeyframedValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.frameId = -1;
+  this._caching = {
+    lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1,
+  };
+  this.k = true;
+  this.kf = true;
+  this.data = data;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.v = initFrame;
+  this.pv = initFrame;
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.addEffect = addEffect;
+}
+
+function KeyframedMultidimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  var i;
+  var len = data.k.length;
+  var s;
+  var e;
+  var to;
+  var ti;
+  for (i = 0; i < len - 1; i += 1) {
+    if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
+      s = data.k[i].s;
+      e = data.k[i + 1].s;
+      to = data.k[i].to;
+      ti = data.k[i].ti;
+      if ((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2]))) {
+        data.k[i].to = null;
+        data.k[i].ti = null;
+      }
+      if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
+        if (s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) {
+          data.k[i].to = null;
+          data.k[i].ti = null;
+        }
+      }
+    }
+  }
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.data = data;
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.k = true;
+  this.kf = true;
+  this._isFirstFrame = true;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.frameId = -1;
+  var arrLen = data.k[0].s.length;
+  this.v = createTypedArray('float32', arrLen);
+  this.pv = createTypedArray('float32', arrLen);
+  for (i = 0; i < arrLen; i += 1) {
+    this.v[i] = initFrame;
+    this.pv[i] = initFrame;
+  }
+  this._caching = { lastFrame: initFrame, lastIndex: 0, value: createTypedArray('float32', arrLen) };
+  this.addEffect = addEffect;
+}
+
+const PropertyFactory = (function () {
+  function getProp(elem, data, type, mult, container) {
+    if (data.sid) {
+      data = elem.globalData.slotManager.getProp(data);
+    }
+    var p;
+    if (!data.k.length) {
+      p = new ValueProperty(elem, data, mult, container);
+    } else if (typeof (data.k[0]) === 'number') {
+      p = new MultiDimensionalProperty(elem, data, mult, container);
+    } else {
+      switch (type) {
+        case 0:
+          p = new KeyframedValueProperty(elem, data, mult, container);
+          break;
+        case 1:
+          p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
+          break;
+        default:
+          break;
+      }
+    }
+    if (p.effectsSequence.length) {
+      container.addDynamicProperty(p);
+    }
+    return p;
+  }
+
+  var ob = {
+    getProp: getProp,
+  };
+  return ob;
+}());
+
+function DynamicPropertyContainer() {}
+DynamicPropertyContainer.prototype = {
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+      this.container.addDynamicProperty(this);
+      this._isAnimated = true;
+    }
+  },
+  iterateDynamicProperties: function () {
+    this._mdf = false;
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      this.dynamicProperties[i].getValue();
+      if (this.dynamicProperties[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  },
+  initDynamicPropertyContainer: function (container) {
+    this.container = container;
+    this.dynamicProperties = [];
+    this._mdf = false;
+    this._isAnimated = false;
+  },
+};
+
+const pointPool = (function () {
+  function create() {
+    return createTypedArray('float32', 2);
+  }
+  return poolFactory(8, create);
+}());
+
+function ShapePath() {
+  this.c = false;
+  this._length = 0;
+  this._maxLength = 8;
+  this.v = createSizedArray(this._maxLength);
+  this.o = createSizedArray(this._maxLength);
+  this.i = createSizedArray(this._maxLength);
+}
+
+ShapePath.prototype.setPathData = function (closed, len) {
+  this.c = closed;
+  this.setLength(len);
+  var i = 0;
+  while (i < len) {
+    this.v[i] = pointPool.newElement();
+    this.o[i] = pointPool.newElement();
+    this.i[i] = pointPool.newElement();
+    i += 1;
+  }
+};
+
+ShapePath.prototype.setLength = function (len) {
+  while (this._maxLength < len) {
+    this.doubleArrayLength();
+  }
+  this._length = len;
+};
+
+ShapePath.prototype.doubleArrayLength = function () {
+  this.v = this.v.concat(createSizedArray(this._maxLength));
+  this.i = this.i.concat(createSizedArray(this._maxLength));
+  this.o = this.o.concat(createSizedArray(this._maxLength));
+  this._maxLength *= 2;
+};
+
+ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
+  var arr;
+  this._length = Math.max(this._length, pos + 1);
+  if (this._length >= this._maxLength) {
+    this.doubleArrayLength();
+  }
+  switch (type) {
+    case 'v':
+      arr = this.v;
+      break;
+    case 'i':
+      arr = this.i;
+      break;
+    case 'o':
+      arr = this.o;
+      break;
+    default:
+      arr = [];
+      break;
+  }
+  if (!arr[pos] || (arr[pos] && !replace)) {
+    arr[pos] = pointPool.newElement();
+  }
+  arr[pos][0] = x;
+  arr[pos][1] = y;
+};
+
+ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
+  this.setXYAt(vX, vY, 'v', pos, replace);
+  this.setXYAt(oX, oY, 'o', pos, replace);
+  this.setXYAt(iX, iY, 'i', pos, replace);
+};
+
+ShapePath.prototype.reverse = function () {
+  var newPath = new ShapePath();
+  newPath.setPathData(this.c, this._length);
+  var vertices = this.v;
+  var outPoints = this.o;
+  var inPoints = this.i;
+  var init = 0;
+  if (this.c) {
+    newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
+    init = 1;
+  }
+  var cnt = this._length - 1;
+  var len = this._length;
+
+  var i;
+  for (i = init; i < len; i += 1) {
+    newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
+    cnt -= 1;
+  }
+  return newPath;
+};
+
+ShapePath.prototype.length = function () {
+  return this._length;
+};
+
+const shapePool = (function () {
+  function create() {
+    return new ShapePath();
+  }
+
+  function release(shapePath) {
+    var len = shapePath._length;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      pointPool.release(shapePath.v[i]);
+      pointPool.release(shapePath.i[i]);
+      pointPool.release(shapePath.o[i]);
+      shapePath.v[i] = null;
+      shapePath.i[i] = null;
+      shapePath.o[i] = null;
+    }
+    shapePath._length = 0;
+    shapePath.c = false;
+  }
+
+  function clone(shape) {
+    var cloned = factory.newElement();
+    var i;
+    var len = shape._length === undefined ? shape.v.length : shape._length;
+    cloned.setLength(len);
+    cloned.c = shape.c;
+
+    for (i = 0; i < len; i += 1) {
+      cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
+    }
+    return cloned;
+  }
+
+  var factory = poolFactory(4, create, release);
+  factory.clone = clone;
+
+  return factory;
+}());
+
+function ShapeCollection() {
+  this._length = 0;
+  this._maxLength = 4;
+  this.shapes = createSizedArray(this._maxLength);
+}
+
+ShapeCollection.prototype.addShape = function (shapeData) {
+  if (this._length === this._maxLength) {
+    this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
+    this._maxLength *= 2;
+  }
+  this.shapes[this._length] = shapeData;
+  this._length += 1;
+};
+
+ShapeCollection.prototype.releaseShapes = function () {
+  var i;
+  for (i = 0; i < this._length; i += 1) {
+    shapePool.release(this.shapes[i]);
+  }
+  this._length = 0;
+};
+
+const shapeCollectionPool = (function () {
+  var ob = {
+    newShapeCollection: newShapeCollection,
+    release: release,
+  };
+
+  var _length = 0;
+  var _maxLength = 4;
+  var pool = createSizedArray(_maxLength);
+
+  function newShapeCollection() {
+    var shapeCollection;
+    if (_length) {
+      _length -= 1;
+      shapeCollection = pool[_length];
+    } else {
+      shapeCollection = new ShapeCollection();
+    }
+    return shapeCollection;
+  }
+
+  function release(shapeCollection) {
+    var i;
+    var len = shapeCollection._length;
+    for (i = 0; i < len; i += 1) {
+      shapePool.release(shapeCollection.shapes[i]);
+    }
+    shapeCollection._length = 0;
+
+    if (_length === _maxLength) {
+      pool = pooling.double(pool);
+      _maxLength *= 2;
+    }
+    pool[_length] = shapeCollection;
+    _length += 1;
+  }
+
+  return ob;
+}());
+
+const ShapePropertyFactory = (function () {
+  var initFrame = -999999;
+
+  function interpolateShape(frameNum, previousValue, caching) {
+    var iterationIndex = caching.lastIndex;
+    var keyPropS;
+    var keyPropE;
+    var isHold;
+    var j;
+    var k;
+    var jLen;
+    var kLen;
+    var perc;
+    var vertexValue;
+    var kf = this.keyframes;
+    if (frameNum < kf[0].t - this.offsetTime) {
+      keyPropS = kf[0].s[0];
+      isHold = true;
+      iterationIndex = 0;
+    } else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) {
+      keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
+      /* if(kf[kf.length - 1].s){
+                keyPropS = kf[kf.length - 1].s[0];
+            }else{
+                keyPropS = kf[kf.length - 2].e[0];
+            } */
+      isHold = true;
+    } else {
+      var i = iterationIndex;
+      var len = kf.length - 1;
+      var flag = true;
+      var keyData;
+      var nextKeyData;
+      var keyframeMetadata;
+      while (flag) {
+        keyData = kf[i];
+        nextKeyData = kf[i + 1];
+        if ((nextKeyData.t - this.offsetTime) > frameNum) {
+          break;
+        }
+        if (i < len - 1) {
+          i += 1;
+        } else {
+          flag = false;
+        }
+      }
+      keyframeMetadata = this.keyframesMetadata[i] || {};
+      isHold = keyData.h === 1;
+      iterationIndex = i;
+      if (!isHold) {
+        if (frameNum >= nextKeyData.t - this.offsetTime) {
+          perc = 1;
+        } else if (frameNum < keyData.t - this.offsetTime) {
+          perc = 0;
+        } else {
+          var fnc;
+          if (keyframeMetadata.__fnct) {
+            fnc = keyframeMetadata.__fnct;
+          } else {
+            fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
+            keyframeMetadata.__fnct = fnc;
+          }
+          perc = fnc((frameNum - (keyData.t - this.offsetTime)) / ((nextKeyData.t - this.offsetTime) - (keyData.t - this.offsetTime)));
+        }
+        keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
+      }
+      keyPropS = keyData.s[0];
+    }
+    jLen = previousValue._length;
+    kLen = keyPropS.i[0].length;
+    caching.lastIndex = iterationIndex;
+
+    for (j = 0; j < jLen; j += 1) {
+      for (k = 0; k < kLen; k += 1) {
+        vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
+        previousValue.i[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc;
+        previousValue.o[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc;
+        previousValue.v[j][k] = vertexValue;
+      }
+    }
+  }
+
+  function interpolateShapeCurrentTime() {
+    var frameNum = this.comp.renderedFrame - this.offsetTime;
+    var initTime = this.keyframes[0].t - this.offsetTime;
+    var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+    var lastFrame = this._caching.lastFrame;
+    if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) {
+      /// /
+      this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
+      this.interpolateShape(frameNum, this.pv, this._caching);
+      /// /
+    }
+    this._caching.lastFrame = frameNum;
+    return this.pv;
+  }
+
+  function resetShape() {
+    this.paths = this.localShapeCollection;
+  }
+
+  function shapesEqual(shape1, shape2) {
+    if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
+      return false;
+    }
+    var i;
+    var len = shape1._length;
+    for (i = 0; i < len; i += 1) {
+      if (shape1.v[i][0] !== shape2.v[i][0]
+            || shape1.v[i][1] !== shape2.v[i][1]
+            || shape1.o[i][0] !== shape2.o[i][0]
+            || shape1.o[i][1] !== shape2.o[i][1]
+            || shape1.i[i][0] !== shape2.i[i][0]
+            || shape1.i[i][1] !== shape2.i[i][1]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  function setVValue(newPath) {
+    if (!shapesEqual(this.v, newPath)) {
+      this.v = shapePool.clone(newPath);
+      this.localShapeCollection.releaseShapes();
+      this.localShapeCollection.addShape(this.v);
+      this._mdf = true;
+      this.paths = this.localShapeCollection;
+    }
+  }
+
+  function processEffectsSequence() {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    } if (!this.effectsSequence.length) {
+      this._mdf = false;
+      return;
+    }
+    if (this.lock) {
+      this.setVValue(this.pv);
+      return;
+    }
+    this.lock = true;
+    this._mdf = false;
+    var finalValue;
+    if (this.kf) {
+      finalValue = this.pv;
+    } else if (this.data.ks) {
+      finalValue = this.data.ks.k;
+    } else {
+      finalValue = this.data.pt.k;
+    }
+    var i;
+    var len = this.effectsSequence.length;
+    for (i = 0; i < len; i += 1) {
+      finalValue = this.effectsSequence[i](finalValue);
+    }
+    this.setVValue(finalValue);
+    this.lock = false;
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function ShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.container = elem;
+    this.elem = elem;
+    this.data = data;
+    this.k = false;
+    this.kf = false;
+    this._mdf = false;
+    var pathData = type === 3 ? data.pt.k : data.ks.k;
+    this.v = shapePool.clone(pathData);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.reset = resetShape;
+    this.effectsSequence = [];
+  }
+
+  function addEffect(effectFunction) {
+    this.effectsSequence.push(effectFunction);
+    this.container.addDynamicProperty(this);
+  }
+
+  ShapeProperty.prototype.interpolateShape = interpolateShape;
+  ShapeProperty.prototype.getValue = processEffectsSequence;
+  ShapeProperty.prototype.setVValue = setVValue;
+  ShapeProperty.prototype.addEffect = addEffect;
+
+  function KeyframedShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.elem = elem;
+    this.container = elem;
+    this.offsetTime = elem.data.st;
+    this.keyframes = type === 3 ? data.pt.k : data.ks.k;
+    this.keyframesMetadata = [];
+    this.k = true;
+    this.kf = true;
+    var len = this.keyframes[0].s[0].i.length;
+    this.v = shapePool.newElement();
+    this.v.setPathData(this.keyframes[0].s[0].c, len);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.lastFrame = initFrame;
+    this.reset = resetShape;
+    this._caching = { lastFrame: initFrame, lastIndex: 0 };
+    this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
+  }
+  KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
+  KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
+  KeyframedShapeProperty.prototype.setVValue = setVValue;
+  KeyframedShapeProperty.prototype.addEffect = addEffect;
+
+  var EllShapeProperty = (function () {
+    var cPoint = roundCorner;
+
+    function EllShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 4);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.paths = this.localShapeCollection;
+      this.localShapeCollection.addShape(this.v);
+      this.d = data.d;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertEllToPath();
+      }
+    }
+
+    EllShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+
+        if (this._mdf) {
+          this.convertEllToPath();
+        }
+      },
+      convertEllToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var s0 = this.s.v[0] / 2;
+        var s1 = this.s.v[1] / 2;
+        var _cw = this.d !== 3;
+        var _v = this.v;
+        _v.v[0][0] = p0;
+        _v.v[0][1] = p1 - s1;
+        _v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.v[1][1] = p1;
+        _v.v[2][0] = p0;
+        _v.v[2][1] = p1 + s1;
+        _v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.v[3][1] = p1;
+        _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.i[0][1] = p1 - s1;
+        _v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.i[1][1] = p1 - s1 * cPoint;
+        _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.i[2][1] = p1 + s1;
+        _v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.i[3][1] = p1 + s1 * cPoint;
+        _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.o[0][1] = p1 - s1;
+        _v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.o[1][1] = p1 + s1 * cPoint;
+        _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.o[2][1] = p1 + s1;
+        _v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.o[3][1] = p1 - s1 * cPoint;
+      },
+    };
+
+    extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
+
+    return EllShapePropertyFactory;
+  }());
+
+  var StarShapeProperty = (function () {
+    function StarShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 0);
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.data = data;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      if (data.sy === 1) {
+        this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
+        this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
+        this.convertToPath = this.convertStarToPath;
+      } else {
+        this.convertToPath = this.convertPolygonToPath;
+      }
+      this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
+      this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this);
+      this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertToPath();
+      }
+    }
+
+    StarShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertToPath();
+        }
+      },
+      convertStarToPath: function () {
+        var numPts = Math.floor(this.pt.v) * 2;
+        var angle = (Math.PI * 2) / numPts;
+        /* this.v.v.length = numPts;
+                this.v.i.length = numPts;
+                this.v.o.length = numPts; */
+        var longFlag = true;
+        var longRad = this.or.v;
+        var shortRad = this.ir.v;
+        var longRound = this.os.v;
+        var shortRound = this.is.v;
+        var longPerimSegment = (2 * Math.PI * longRad) / (numPts * 2);
+        var shortPerimSegment = (2 * Math.PI * shortRad) / (numPts * 2);
+        var i;
+        var rad;
+        var roundness;
+        var perimSegment;
+        var currentAng = -Math.PI / 2;
+        currentAng += this.r.v;
+        var dir = this.data.d === 3 ? -1 : 1;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          rad = longFlag ? longRad : shortRad;
+          roundness = longFlag ? longRound : shortRound;
+          perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
+          /* this.v.v[i] = [x,y];
+                    this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
+                    this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
+                    this.v._length = numPts; */
+          longFlag = !longFlag;
+          currentAng += angle * dir;
+        }
+      },
+      convertPolygonToPath: function () {
+        var numPts = Math.floor(this.pt.v);
+        var angle = (Math.PI * 2) / numPts;
+        var rad = this.or.v;
+        var roundness = this.os.v;
+        var perimSegment = (2 * Math.PI * rad) / (numPts * 4);
+        var i;
+        var currentAng = -Math.PI * 0.5;
+        var dir = this.data.d === 3 ? -1 : 1;
+        currentAng += this.r.v;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+          currentAng += angle * dir;
+        }
+        this.paths.length = 0;
+        this.paths[0] = this.v;
+      },
+
+    };
+    extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
+
+    return StarShapePropertyFactory;
+  }());
+
+  var RectShapeProperty = (function () {
+    function RectShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.c = true;
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertRectToPath();
+      }
+    }
+
+    RectShapePropertyFactory.prototype = {
+      convertRectToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var v0 = this.s.v[0] / 2;
+        var v1 = this.s.v[1] / 2;
+        var round = bmMin(v0, v1, this.r.v);
+        var cPoint = round * (1 - roundCorner);
+        this.v._length = 0;
+
+        if (this.d === 2 || this.d === 1) {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
+          this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2);
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3);
+          }
+        } else {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true);
+          }
+        }
+      },
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertRectToPath();
+        }
+      },
+      reset: resetShape,
+    };
+    extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
+
+    return RectShapePropertyFactory;
+  }());
+
+  function getShapeProp(elem, data, type) {
+    var prop;
+    if (type === 3 || type === 4) {
+      var dataProp = type === 3 ? data.pt : data.ks;
+      var keys = dataProp.k;
+      if (keys.length) {
+        prop = new KeyframedShapeProperty(elem, data, type);
+      } else {
+        prop = new ShapeProperty(elem, data, type);
+      }
+    } else if (type === 5) {
+      prop = new RectShapeProperty(elem, data);
+    } else if (type === 6) {
+      prop = new EllShapeProperty(elem, data);
+    } else if (type === 7) {
+      prop = new StarShapeProperty(elem, data);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  }
+
+  function getConstructorFunction() {
+    return ShapeProperty;
+  }
+
+  function getKeyframedConstructorFunction() {
+    return KeyframedShapeProperty;
+  }
+
+  var ob = {};
+  ob.getShapeProp = getShapeProp;
+  ob.getConstructorFunction = getConstructorFunction;
+  ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction;
+  return ob;
+}());
+
+/*!
+ Transformation Matrix v2.0
+ (c) Epistemex 2014-2015
+ www.epistemex.com
+ By Ken Fyrstenberg
+ Contributions by leeoniya.
+ License: MIT, header required.
+ */
+
+/**
+ * 2D transformation matrix object initialized with identity matrix.
+ *
+ * The matrix can synchronize a canvas context by supplying the context
+ * as an argument, or later apply current absolute transform to an
+ * existing context.
+ *
+ * All values are handled as floating point values.
+ *
+ * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix
+ * @prop {number} a - scale x
+ * @prop {number} b - shear y
+ * @prop {number} c - shear x
+ * @prop {number} d - scale y
+ * @prop {number} e - translate x
+ * @prop {number} f - translate y
+ * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context
+ * @constructor
+ */
+
+const Matrix = (function () {
+  var _cos = Math.cos;
+  var _sin = Math.sin;
+  var _tan = Math.tan;
+  var _rnd = Math.round;
+
+  function reset() {
+    this.props[0] = 1;
+    this.props[1] = 0;
+    this.props[2] = 0;
+    this.props[3] = 0;
+    this.props[4] = 0;
+    this.props[5] = 1;
+    this.props[6] = 0;
+    this.props[7] = 0;
+    this.props[8] = 0;
+    this.props[9] = 0;
+    this.props[10] = 1;
+    this.props[11] = 0;
+    this.props[12] = 0;
+    this.props[13] = 0;
+    this.props[14] = 0;
+    this.props[15] = 1;
+    return this;
+  }
+
+  function rotate(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function rotateX(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateY(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateZ(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function shear(sx, sy) {
+    return this._t(1, sy, sx, 1, 0, 0);
+  }
+
+  function skew(ax, ay) {
+    return this.shear(_tan(ax), _tan(ay));
+  }
+
+  function skewFromAxis(ax, angle) {
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+    // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+  }
+
+  function scale(sx, sy, sz) {
+    if (!sz && sz !== 0) {
+      sz = 1;
+    }
+    if (sx === 1 && sy === 1 && sz === 1) {
+      return this;
+    }
+    return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
+  }
+
+  function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
+    this.props[0] = a;
+    this.props[1] = b;
+    this.props[2] = c;
+    this.props[3] = d;
+    this.props[4] = e;
+    this.props[5] = f;
+    this.props[6] = g;
+    this.props[7] = h;
+    this.props[8] = i;
+    this.props[9] = j;
+    this.props[10] = k;
+    this.props[11] = l;
+    this.props[12] = m;
+    this.props[13] = n;
+    this.props[14] = o;
+    this.props[15] = p;
+    return this;
+  }
+
+  function translate(tx, ty, tz) {
+    tz = tz || 0;
+    if (tx !== 0 || ty !== 0 || tz !== 0) {
+      return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
+    }
+    return this;
+  }
+
+  function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
+    var _p = this.props;
+
+    if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
+      // NOTE: commenting this condition because TurboFan deoptimizes code when present
+      // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
+      _p[12] = _p[12] * a2 + _p[15] * m2;
+      _p[13] = _p[13] * f2 + _p[15] * n2;
+      _p[14] = _p[14] * k2 + _p[15] * o2;
+      _p[15] *= p2;
+      // }
+      this._identityCalculated = false;
+      return this;
+    }
+
+    var a1 = _p[0];
+    var b1 = _p[1];
+    var c1 = _p[2];
+    var d1 = _p[3];
+    var e1 = _p[4];
+    var f1 = _p[5];
+    var g1 = _p[6];
+    var h1 = _p[7];
+    var i1 = _p[8];
+    var j1 = _p[9];
+    var k1 = _p[10];
+    var l1 = _p[11];
+    var m1 = _p[12];
+    var n1 = _p[13];
+    var o1 = _p[14];
+    var p1 = _p[15];
+
+    /* matrix order (canvas compatible):
+         * ace
+         * bdf
+         * 001
+         */
+    _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
+    _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
+    _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
+    _p[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2;
+
+    _p[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2;
+    _p[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2;
+    _p[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2;
+    _p[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2;
+
+    _p[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2;
+    _p[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2;
+    _p[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2;
+    _p[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2;
+
+    _p[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2;
+    _p[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2;
+    _p[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2;
+    _p[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2;
+
+    this._identityCalculated = false;
+    return this;
+  }
+
+  function multiply(matrix) {
+    var matrixProps = matrix.props;
+    return this.transform(
+      matrixProps[0],
+      matrixProps[1],
+      matrixProps[2],
+      matrixProps[3],
+      matrixProps[4],
+      matrixProps[5],
+      matrixProps[6],
+      matrixProps[7],
+      matrixProps[8],
+      matrixProps[9],
+      matrixProps[10],
+      matrixProps[11],
+      matrixProps[12],
+      matrixProps[13],
+      matrixProps[14],
+      matrixProps[15]
+    );
+  }
+
+  function isIdentity() {
+    if (!this._identityCalculated) {
+      this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
+      this._identityCalculated = true;
+    }
+    return this._identity;
+  }
+
+  function equals(matr) {
+    var i = 0;
+    while (i < 16) {
+      if (matr.props[i] !== this.props[i]) {
+        return false;
+      }
+      i += 1;
+    }
+    return true;
+  }
+
+  function clone(matr) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      matr.props[i] = this.props[i];
+    }
+    return matr;
+  }
+
+  function cloneFromProps(props) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      this.props[i] = props[i];
+    }
+  }
+
+  function applyToPoint(x, y, z) {
+    return {
+      x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+      y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+      z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+    };
+    /* return {
+         x: x * me.a + y * me.c + me.e,
+         y: x * me.b + y * me.d + me.f
+         }; */
+  }
+  function applyToX(x, y, z) {
+    return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
+  }
+  function applyToY(x, y, z) {
+    return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
+  }
+  function applyToZ(x, y, z) {
+    return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
+  }
+
+  function getInverseMatrix() {
+    var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
+    var a = this.props[5] / determinant;
+    var b = -this.props[1] / determinant;
+    var c = -this.props[4] / determinant;
+    var d = this.props[0] / determinant;
+    var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12]) / determinant;
+    var f = -(this.props[0] * this.props[13] - this.props[1] * this.props[12]) / determinant;
+    var inverseMatrix = new Matrix();
+    inverseMatrix.props[0] = a;
+    inverseMatrix.props[1] = b;
+    inverseMatrix.props[4] = c;
+    inverseMatrix.props[5] = d;
+    inverseMatrix.props[12] = e;
+    inverseMatrix.props[13] = f;
+    return inverseMatrix;
+  }
+
+  function inversePoint(pt) {
+    var inverseMatrix = this.getInverseMatrix();
+    return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
+  }
+
+  function inversePoints(pts) {
+    var i;
+    var len = pts.length;
+    var retPts = [];
+    for (i = 0; i < len; i += 1) {
+      retPts[i] = inversePoint(pts[i]);
+    }
+    return retPts;
+  }
+
+  function applyToTriplePoints(pt1, pt2, pt3) {
+    var arr = createTypedArray('float32', 6);
+    if (this.isIdentity()) {
+      arr[0] = pt1[0];
+      arr[1] = pt1[1];
+      arr[2] = pt2[0];
+      arr[3] = pt2[1];
+      arr[4] = pt3[0];
+      arr[5] = pt3[1];
+    } else {
+      var p0 = this.props[0];
+      var p1 = this.props[1];
+      var p4 = this.props[4];
+      var p5 = this.props[5];
+      var p12 = this.props[12];
+      var p13 = this.props[13];
+      arr[0] = pt1[0] * p0 + pt1[1] * p4 + p12;
+      arr[1] = pt1[0] * p1 + pt1[1] * p5 + p13;
+      arr[2] = pt2[0] * p0 + pt2[1] * p4 + p12;
+      arr[3] = pt2[0] * p1 + pt2[1] * p5 + p13;
+      arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
+      arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
+    }
+    return arr;
+  }
+
+  function applyToPointArray(x, y, z) {
+    var arr;
+    if (this.isIdentity()) {
+      arr = [x, y, z];
+    } else {
+      arr = [
+        x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+        x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+        x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+      ];
+    }
+    return arr;
+  }
+
+  function applyToPointStringified(x, y) {
+    if (this.isIdentity()) {
+      return x + ',' + y;
+    }
+    var _p = this.props;
+    return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
+  }
+
+  function toCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var i = 0;
+    var props = this.props;
+    var cssValue = 'matrix3d(';
+    var v = 10000;
+    while (i < 16) {
+      cssValue += _rnd(props[i] * v) / v;
+      cssValue += i === 15 ? ')' : ',';
+      i += 1;
+    }
+    return cssValue;
+  }
+
+  function roundMatrixProperty(val) {
+    var v = 10000;
+    if ((val < 0.000001 && val > 0) || (val > -0.000001 && val < 0)) {
+      return _rnd(val * v) / v;
+    }
+    return val;
+  }
+
+  function to2dCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var props = this.props;
+    var _a = roundMatrixProperty(props[0]);
+    var _b = roundMatrixProperty(props[1]);
+    var _c = roundMatrixProperty(props[4]);
+    var _d = roundMatrixProperty(props[5]);
+    var _e = roundMatrixProperty(props[12]);
+    var _f = roundMatrixProperty(props[13]);
+    return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
+  }
+
+  return function () {
+    this.reset = reset;
+    this.rotate = rotate;
+    this.rotateX = rotateX;
+    this.rotateY = rotateY;
+    this.rotateZ = rotateZ;
+    this.skew = skew;
+    this.skewFromAxis = skewFromAxis;
+    this.shear = shear;
+    this.scale = scale;
+    this.setTransform = setTransform;
+    this.translate = translate;
+    this.transform = transform;
+    this.multiply = multiply;
+    this.applyToPoint = applyToPoint;
+    this.applyToX = applyToX;
+    this.applyToY = applyToY;
+    this.applyToZ = applyToZ;
+    this.applyToPointArray = applyToPointArray;
+    this.applyToTriplePoints = applyToTriplePoints;
+    this.applyToPointStringified = applyToPointStringified;
+    this.toCSS = toCSS;
+    this.to2dCSS = to2dCSS;
+    this.clone = clone;
+    this.cloneFromProps = cloneFromProps;
+    this.equals = equals;
+    this.inversePoints = inversePoints;
+    this.inversePoint = inversePoint;
+    this.getInverseMatrix = getInverseMatrix;
+    this._t = this.transform;
+    this.isIdentity = isIdentity;
+    this._identity = true;
+    this._identityCalculated = false;
+
+    this.props = createTypedArray('float32', 16);
+    this.reset();
+  };
+}());
+
+const lottie = {};
+var standalone = '__[STANDALONE]__';
+var animationData = '__[ANIMATIONDATA]__';
+var renderer = '';
+
+function setLocation(href) {
+  setLocationHref(href);
+}
+
+function searchAnimations() {
+  if (standalone === true) {
+    animationManager.searchAnimations(animationData, standalone, renderer);
+  } else {
+    animationManager.searchAnimations();
+  }
+}
+
+function setSubframeRendering(flag) {
+  setSubframeEnabled(flag);
+}
+
+function setPrefix(prefix) {
+  setIdPrefix(prefix);
+}
+
+function loadAnimation(params) {
+  if (standalone === true) {
+    params.animationData = JSON.parse(animationData);
+  }
+  return animationManager.loadAnimation(params);
+}
+
+function setQuality(value) {
+  if (typeof value === 'string') {
+    switch (value) {
+      case 'high':
+        setDefaultCurveSegments(200);
+        break;
+      default:
+      case 'medium':
+        setDefaultCurveSegments(50);
+        break;
+      case 'low':
+        setDefaultCurveSegments(10);
+        break;
+    }
+  } else if (!isNaN(value) && value > 1) {
+    setDefaultCurveSegments(value);
+  }
+  if (getDefaultCurveSegments() >= 50) {
+    roundValues(false);
+  } else {
+    roundValues(true);
+  }
+}
+
+function inBrowser() {
+  return typeof navigator !== 'undefined';
+}
+
+function installPlugin(type, plugin) {
+  if (type === 'expressions') {
+    setExpressionsPlugin(plugin);
+  }
+}
+
+function getFactory(name) {
+  switch (name) {
+    case 'propertyFactory':
+      return PropertyFactory;
+    case 'shapePropertyFactory':
+      return ShapePropertyFactory;
+    case 'matrix':
+      return Matrix;
+    default:
+      return null;
+  }
+}
+
+lottie.play = animationManager.play;
+lottie.pause = animationManager.pause;
+lottie.setLocationHref = setLocation;
+lottie.togglePause = animationManager.togglePause;
+lottie.setSpeed = animationManager.setSpeed;
+lottie.setDirection = animationManager.setDirection;
+lottie.stop = animationManager.stop;
+lottie.searchAnimations = searchAnimations;
+lottie.registerAnimation = animationManager.registerAnimation;
+lottie.loadAnimation = loadAnimation;
+lottie.setSubframeRendering = setSubframeRendering;
+lottie.resize = animationManager.resize;
+// lottie.start = start;
+lottie.goToAndStop = animationManager.goToAndStop;
+lottie.destroy = animationManager.destroy;
+lottie.setQuality = setQuality;
+lottie.inBrowser = inBrowser;
+lottie.installPlugin = installPlugin;
+lottie.freeze = animationManager.freeze;
+lottie.unfreeze = animationManager.unfreeze;
+lottie.setVolume = animationManager.setVolume;
+lottie.mute = animationManager.mute;
+lottie.unmute = animationManager.unmute;
+lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations;
+lottie.useWebWorker = setWebWorker;
+lottie.setIDPrefix = setPrefix;
+lottie.__getFactory = getFactory;
+lottie.version = '[[BM_VERSION]]';
+
+function checkReady() {
+  if (document.readyState === 'complete') {
+    clearInterval(readyStateCheckInterval);
+    searchAnimations();
+  }
+}
+
+function getQueryVariable(variable) {
+  var vars = queryString.split('&');
+  for (var i = 0; i < vars.length; i += 1) {
+    var pair = vars[i].split('=');
+    if (decodeURIComponent(pair[0]) == variable) { // eslint-disable-line eqeqeq
+      return decodeURIComponent(pair[1]);
+    }
+  }
+  return null;
+}
+var queryString = '';
+if (standalone) {
+  var scripts = document.getElementsByTagName('script');
+  var index = scripts.length - 1;
+  var myScript = scripts[index] || {
+    src: '',
+  };
+  queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
+  renderer = getQueryVariable('renderer');
+}
+var readyStateCheckInterval = setInterval(checkReady, 100);
+
+// this adds bodymovin to the window object for backwards compatibility
+try {
+  if (!(typeof exports === 'object' && typeof module !== 'undefined')
+    && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
+  ) {
+    window.bodymovin = lottie;
+  }
+} catch (err) {
+  //
+}
+
+const ShapeModifiers = (function () {
+  var ob = {};
+  var modifiers = {};
+  ob.registerModifier = registerModifier;
+  ob.getModifier = getModifier;
+
+  function registerModifier(nm, factory) {
+    if (!modifiers[nm]) {
+      modifiers[nm] = factory;
+    }
+  }
+
+  function getModifier(nm, elem, data) {
+    return new modifiers[nm](elem, data);
+  }
+
+  return ob;
+}());
+
+function ShapeModifier() {}
+ShapeModifier.prototype.initModifierProperties = function () {};
+ShapeModifier.prototype.addShapeToModifier = function () {};
+ShapeModifier.prototype.addShape = function (data) {
+  if (!this.closed) {
+    // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
+    data.sh.container.addDynamicProperty(data.sh);
+    var shapeData = { shape: data.sh, data: data, localShapeCollection: shapeCollectionPool.newShapeCollection() };
+    this.shapes.push(shapeData);
+    this.addShapeToModifier(shapeData);
+    if (this._isAnimated) {
+      data.setAsAnimated();
+    }
+  }
+};
+ShapeModifier.prototype.init = function (elem, data) {
+  this.shapes = [];
+  this.elem = elem;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, data);
+  this.frameId = initialDefaultFrame;
+  this.closed = false;
+  this.k = false;
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+ShapeModifier.prototype.processKeys = function () {
+  if (this.elem.globalData.frameId === this.frameId) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+extendPrototype([DynamicPropertyContainer], ShapeModifier);
+
+function TrimModifier() {
+}
+extendPrototype([ShapeModifier], TrimModifier);
+TrimModifier.prototype.initModifierProperties = function (elem, data) {
+  this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this);
+  this.sValue = 0;
+  this.eValue = 0;
+  this.getValue = this.processKeys;
+  this.m = data.m;
+  this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
+};
+
+TrimModifier.prototype.addShapeToModifier = function (shapeData) {
+  shapeData.pathsData = [];
+};
+
+TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
+  var segments = [];
+  if (e <= 1) {
+    segments.push({
+      s: s,
+      e: e,
+    });
+  } else if (s >= 1) {
+    segments.push({
+      s: s - 1,
+      e: e - 1,
+    });
+  } else {
+    segments.push({
+      s: s,
+      e: 1,
+    });
+    segments.push({
+      s: 0,
+      e: e - 1,
+    });
+  }
+  var shapeSegments = [];
+  var i;
+  var len = segments.length;
+  var segmentOb;
+  for (i = 0; i < len; i += 1) {
+    segmentOb = segments[i];
+    if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
+      var shapeS;
+      var shapeE;
+      if (segmentOb.s * totalModifierLength <= addedLength) {
+        shapeS = 0;
+      } else {
+        shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
+      }
+      if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
+        shapeE = 1;
+      } else {
+        shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength);
+      }
+      shapeSegments.push([shapeS, shapeE]);
+    }
+  }
+  if (!shapeSegments.length) {
+    shapeSegments.push([0, 0]);
+  }
+  return shapeSegments;
+};
+
+TrimModifier.prototype.releasePathsData = function (pathsData) {
+  var i;
+  var len = pathsData.length;
+  for (i = 0; i < len; i += 1) {
+    segmentsLengthPool.release(pathsData[i]);
+  }
+  pathsData.length = 0;
+  return pathsData;
+};
+
+TrimModifier.prototype.processShapes = function (_isFirstFrame) {
+  var s;
+  var e;
+  if (this._mdf || _isFirstFrame) {
+    var o = (this.o.v % 360) / 360;
+    if (o < 0) {
+      o += 1;
+    }
+    if (this.s.v > 1) {
+      s = 1 + o;
+    } else if (this.s.v < 0) {
+      s = 0 + o;
+    } else {
+      s = this.s.v + o;
+    }
+    if (this.e.v > 1) {
+      e = 1 + o;
+    } else if (this.e.v < 0) {
+      e = 0 + o;
+    } else {
+      e = this.e.v + o;
+    }
+
+    if (s > e) {
+      var _s = s;
+      s = e;
+      e = _s;
+    }
+    s = Math.round(s * 10000) * 0.0001;
+    e = Math.round(e * 10000) * 0.0001;
+    this.sValue = s;
+    this.eValue = e;
+  } else {
+    s = this.sValue;
+    e = this.eValue;
+  }
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var pathsData;
+  var pathData;
+  var totalShapeLength;
+  var totalModifierLength = 0;
+
+  if (e === s) {
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].localShapeCollection.releaseShapes();
+      this.shapes[i].shape._mdf = true;
+      this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
+      if (this._mdf) {
+        this.shapes[i].pathsData.length = 0;
+      }
+    }
+  } else if (!((e === 1 && s === 0) || (e === 0 && s === 1))) {
+    var segments = [];
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
+      if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
+        shapeData.shape.paths = shapeData.localShapeCollection;
+      } else {
+        shapePaths = shapeData.shape.paths;
+        jLen = shapePaths._length;
+        totalShapeLength = 0;
+        if (!shapeData.shape._mdf && shapeData.pathsData.length) {
+          totalShapeLength = shapeData.totalShapeLength;
+        } else {
+          pathsData = this.releasePathsData(shapeData.pathsData);
+          for (j = 0; j < jLen; j += 1) {
+            pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
+            pathsData.push(pathData);
+            totalShapeLength += pathData.totalLength;
+          }
+          shapeData.totalShapeLength = totalShapeLength;
+          shapeData.pathsData = pathsData;
+        }
+
+        totalModifierLength += totalShapeLength;
+        shapeData.shape._mdf = true;
+      }
+    }
+    var shapeS = s;
+    var shapeE = e;
+    var addedLength = 0;
+    var edges;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shapeData = this.shapes[i];
+      if (shapeData.shape._mdf) {
+        localShapeCollection = shapeData.localShapeCollection;
+        localShapeCollection.releaseShapes();
+        // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
+        if (this.m === 2 && len > 1) {
+          edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
+          addedLength += shapeData.totalShapeLength;
+        } else {
+          edges = [[shapeS, shapeE]];
+        }
+        jLen = edges.length;
+        for (j = 0; j < jLen; j += 1) {
+          shapeS = edges[j][0];
+          shapeE = edges[j][1];
+          segments.length = 0;
+          if (shapeE <= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength * shapeE,
+            });
+          } else if (shapeS >= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * (shapeS - 1),
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          } else {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength,
+            });
+            segments.push({
+              s: 0,
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          }
+          var newShapesData = this.addShapes(shapeData, segments[0]);
+          if (segments[0].s !== segments[0].e) {
+            if (segments.length > 1) {
+              var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
+              if (lastShapeInCollection.c) {
+                var lastShape = newShapesData.pop();
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1], lastShape);
+              } else {
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1]);
+              }
+            }
+            this.addPaths(newShapesData, localShapeCollection);
+          }
+        }
+        shapeData.shape.paths = localShapeCollection;
+      }
+    }
+  } else if (this._mdf) {
+    for (i = 0; i < len; i += 1) {
+      // Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween.
+      // Don't remove this even if it's losing cached info.
+      this.shapes[i].pathsData.length = 0;
+      this.shapes[i].shape._mdf = true;
+    }
+  }
+};
+
+TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
+  var i;
+  var len = newPaths.length;
+  for (i = 0; i < len; i += 1) {
+    localShapeCollection.addShape(newPaths[i]);
+  }
+};
+
+TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
+  shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
+  shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
+  }
+  shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
+  shapePath.setXYAt(points[1], points[5], 'o', pos);
+  shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(points[0], points[4], 'v', pos);
+  }
+  shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
+  var pathsData = shapeData.pathsData;
+  var shapePaths = shapeData.shape.paths.shapes;
+  var i;
+  var len = shapeData.shape.paths._length;
+  var j;
+  var jLen;
+  var addedLength = 0;
+  var currentLengthData;
+  var segmentCount;
+  var lengths;
+  var segment;
+  var shapes = [];
+  var initPos;
+  var newShape = true;
+  if (!shapePath) {
+    shapePath = shapePool.newElement();
+    segmentCount = 0;
+    initPos = 0;
+  } else {
+    segmentCount = shapePath._length;
+    initPos = shapePath._length;
+  }
+  shapes.push(shapePath);
+  for (i = 0; i < len; i += 1) {
+    lengths = pathsData[i].lengths;
+    shapePath.c = shapePaths[i].c;
+    jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
+    for (j = 1; j < jLen; j += 1) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
+        addedLength += currentLengthData.addedLength;
+        shapePath.c = false;
+      } else if (addedLength > shapeSegment.e) {
+        shapePath.c = false;
+        break;
+      } else {
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+        addedLength += currentLengthData.addedLength;
+        segmentCount += 1;
+      }
+    }
+    if (shapePaths[i].c && lengths.length) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength <= shapeSegment.e) {
+        var segmentLength = lengths[j - 1].addedLength;
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+      } else {
+        shapePath.c = false;
+      }
+      addedLength += currentLengthData.addedLength;
+      segmentCount += 1;
+    }
+    if (shapePath._length) {
+      shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
+      shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
+    }
+    if (addedLength > shapeSegment.e) {
+      break;
+    }
+    if (i < len - 1) {
+      shapePath = shapePool.newElement();
+      newShape = true;
+      shapes.push(shapePath);
+      segmentCount = 0;
+    }
+  }
+  return shapes;
+};
+
+function PuckerAndBloatModifier() {}
+extendPrototype([ShapeModifier], PuckerAndBloatModifier);
+PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this._isAnimated = !!this.amount.effectsSequence.length;
+};
+
+PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
+  var percent = amount / 100;
+  var centerPoint = [0, 0];
+  var pathLength = path._length;
+  var i = 0;
+  for (i = 0; i < pathLength; i += 1) {
+    centerPoint[0] += path.v[i][0];
+    centerPoint[1] += path.v[i][1];
+  }
+  centerPoint[0] /= pathLength;
+  centerPoint[1] /= pathLength;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < pathLength; i += 1) {
+    vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
+    vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
+    oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent;
+    oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent;
+    iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent;
+    iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
+    clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
+  }
+  return clonedPath;
+};
+
+PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+const TransformPropertyFactory = (function () {
+  var defaultVector = [0, 0];
+
+  function applyToMatrix(mat) {
+    var _mdf = this._mdf;
+    this.iterateDynamicProperties();
+    this._mdf = this._mdf || _mdf;
+    if (this.a) {
+      mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+    }
+    if (this.s) {
+      mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+    }
+    if (this.sk) {
+      mat.skewFromAxis(-this.sk.v, this.sa.v);
+    }
+    if (this.r) {
+      mat.rotate(-this.r.v);
+    } else {
+      mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+    }
+    if (this.data.p.s) {
+      if (this.data.p.z) {
+        mat.translate(this.px.v, this.py.v, -this.pz.v);
+      } else {
+        mat.translate(this.px.v, this.py.v, 0);
+      }
+    } else {
+      mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+    }
+  }
+  function processKeys(forceRender) {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    }
+    if (this._isDirty) {
+      this.precalculateMatrix();
+      this._isDirty = false;
+    }
+
+    this.iterateDynamicProperties();
+
+    if (this._mdf || forceRender) {
+      var frameRate;
+      this.v.cloneFromProps(this.pre.props);
+      if (this.appliedTransformations < 1) {
+        this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      }
+      if (this.appliedTransformations < 2) {
+        this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      }
+      if (this.sk && this.appliedTransformations < 3) {
+        this.v.skewFromAxis(-this.sk.v, this.sa.v);
+      }
+      if (this.r && this.appliedTransformations < 4) {
+        this.v.rotate(-this.r.v);
+      } else if (!this.r && this.appliedTransformations < 4) {
+        this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+          .rotateY(this.or.v[1])
+          .rotateX(this.or.v[0]);
+      }
+      if (this.autoOriented) {
+        var v1;
+        var v2;
+        frameRate = this.elem.globalData.frameRate;
+        if (this.p && this.p.keyframes && this.p.getValueAtTime) {
+          if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
+            v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0);
+          } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0);
+            v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0);
+          } else {
+            v1 = this.p.pv;
+            v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime);
+          }
+        } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) {
+          v1 = [];
+          v2 = [];
+          var px = this.px;
+          var py = this.py;
+          if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
+            v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
+            v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate, 0);
+          } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate), 0);
+            v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate), 0);
+            v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0);
+          } else {
+            v1 = [px.pv, py.pv];
+            v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime);
+            v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime);
+          }
+        } else {
+          v2 = defaultVector;
+          v1 = v2;
+        }
+        this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
+      }
+      if (this.data.p && this.data.p.s) {
+        if (this.data.p.z) {
+          this.v.translate(this.px.v, this.py.v, -this.pz.v);
+        } else {
+          this.v.translate(this.px.v, this.py.v, 0);
+        }
+      } else {
+        this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+      }
+    }
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function precalculateMatrix() {
+    this.appliedTransformations = 0;
+    this.pre.reset();
+
+    if (!this.a.effectsSequence.length) {
+      this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      this.appliedTransformations = 1;
+    } else {
+      return;
+    }
+    if (!this.s.effectsSequence.length) {
+      this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      this.appliedTransformations = 2;
+    } else {
+      return;
+    }
+    if (this.sk) {
+      if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
+        this.pre.skewFromAxis(-this.sk.v, this.sa.v);
+        this.appliedTransformations = 3;
+      } else {
+        return;
+      }
+    }
+    if (this.r) {
+      if (!this.r.effectsSequence.length) {
+        this.pre.rotate(-this.r.v);
+        this.appliedTransformations = 4;
+      }
+    } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) {
+      this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+      this.appliedTransformations = 4;
+    }
+  }
+
+  function autoOrient() {
+    //
+    // var prevP = this.getValueAtTime();
+  }
+
+  function addDynamicProperty(prop) {
+    this._addDynamicProperty(prop);
+    this.elem.addDynamicProperty(prop);
+    this._isDirty = true;
+  }
+
+  function TransformProperty(elem, data, container) {
+    this.elem = elem;
+    this.frameId = -1;
+    this.propType = 'transform';
+    this.data = data;
+    this.v = new Matrix();
+    // Precalculated matrix with non animated properties
+    this.pre = new Matrix();
+    this.appliedTransformations = 0;
+    this.initDynamicPropertyContainer(container || elem);
+    if (data.p && data.p.s) {
+      this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
+      this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
+      if (data.p.z) {
+        this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
+      }
+    } else {
+      this.p = PropertyFactory.getProp(elem, data.p || { k: [0, 0, 0] }, 1, 0, this);
+    }
+    if (data.rx) {
+      this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
+      this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
+      this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
+      if (data.or.k[0].ti) {
+        var i;
+        var len = data.or.k.length;
+        for (i = 0; i < len; i += 1) {
+          data.or.k[i].to = null;
+          data.or.k[i].ti = null;
+        }
+      }
+      this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+      // sh Indicates it needs to be capped between -180 and 180
+      this.or.sh = true;
+    } else {
+      this.r = PropertyFactory.getProp(elem, data.r || { k: 0 }, 0, degToRads, this);
+    }
+    if (data.sk) {
+      this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
+      this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
+    }
+    this.a = PropertyFactory.getProp(elem, data.a || { k: [0, 0, 0] }, 1, 0, this);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: [100, 100, 100] }, 1, 0.01, this);
+    // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
+    if (data.o) {
+      this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
+    } else {
+      this.o = { _mdf: false, v: 1 };
+    }
+    this._isDirty = true;
+    if (!this.dynamicProperties.length) {
+      this.getValue(true);
+    }
+  }
+
+  TransformProperty.prototype = {
+    applyToMatrix: applyToMatrix,
+    getValue: processKeys,
+    precalculateMatrix: precalculateMatrix,
+    autoOrient: autoOrient,
+  };
+
+  extendPrototype([DynamicPropertyContainer], TransformProperty);
+  TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
+  TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
+
+  function getTransformProperty(elem, data, container) {
+    return new TransformProperty(elem, data, container);
+  }
+
+  return {
+    getTransformProperty: getTransformProperty,
+  };
+}());
+
+function RepeaterModifier() {}
+extendPrototype([ShapeModifier], RepeaterModifier);
+
+RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, null, this);
+  this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this);
+  this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
+  this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
+  this.data = data;
+  if (!this.dynamicProperties.length) {
+    this.getValue(true);
+  }
+  this._isAnimated = !!this.dynamicProperties.length;
+  this.pMatrix = new Matrix();
+  this.rMatrix = new Matrix();
+  this.sMatrix = new Matrix();
+  this.tMatrix = new Matrix();
+  this.matrix = new Matrix();
+};
+
+RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
+  var dir = inv ? -1 : 1;
+  var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
+  var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
+  pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
+  rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  rMatrix.rotate(-transform.r.v * dir * perc);
+  rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+  sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
+  sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+};
+
+RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
+  this.elem = elem;
+  this.arr = arr;
+  this.pos = pos;
+  this.elemsData = elemsData;
+  this._currentCopies = 0;
+  this._elements = [];
+  this._groups = [];
+  this.frameId = -1;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, arr[pos]);
+  while (pos > 0) {
+    pos -= 1;
+    // this._elements.unshift(arr.splice(pos,1)[0]);
+    this._elements.unshift(arr[pos]);
+  }
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+
+RepeaterModifier.prototype.resetElements = function (elements) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._processed = false;
+    if (elements[i].ty === 'gr') {
+      this.resetElements(elements[i].it);
+    }
+  }
+};
+
+RepeaterModifier.prototype.cloneElements = function (elements) {
+  var newElements = JSON.parse(JSON.stringify(elements));
+  this.resetElements(newElements);
+  return newElements;
+};
+
+RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._render = renderFlag;
+    if (elements[i].ty === 'gr') {
+      this.changeGroupRender(elements[i].it, renderFlag);
+    }
+  }
+};
+
+RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
+  var items;
+  var itemsTransform;
+  var i;
+  var dir;
+  var cont;
+  var hasReloaded = false;
+  if (this._mdf || _isFirstFrame) {
+    var copies = Math.ceil(this.c.v);
+    if (this._groups.length < copies) {
+      while (this._groups.length < copies) {
+        var group = {
+          it: this.cloneElements(this._elements),
+          ty: 'gr',
+        };
+        group.it.push({
+          a: { a: 0, ix: 1, k: [0, 0] }, nm: 'Transform', o: { a: 0, ix: 7, k: 100 }, p: { a: 0, ix: 2, k: [0, 0] }, r: { a: 1, ix: 6, k: [{ s: 0, e: 0, t: 0 }, { s: 0, e: 0, t: 1 }] }, s: { a: 0, ix: 3, k: [100, 100] }, sa: { a: 0, ix: 5, k: 0 }, sk: { a: 0, ix: 4, k: 0 }, ty: 'tr',
+        });
+
+        this.arr.splice(0, 0, group);
+        this._groups.splice(0, 0, group);
+        this._currentCopies += 1;
+      }
+      this.elem.reloadShapes();
+      hasReloaded = true;
+    }
+    cont = 0;
+    var renderFlag;
+    for (i = 0; i <= this._groups.length - 1; i += 1) {
+      renderFlag = cont < copies;
+      this._groups[i]._render = renderFlag;
+      this.changeGroupRender(this._groups[i].it, renderFlag);
+      if (!renderFlag) {
+        var elems = this.elemsData[i].it;
+        var transformData = elems[elems.length - 1];
+        if (transformData.transform.op.v !== 0) {
+          transformData.transform.op._mdf = true;
+          transformData.transform.op.v = 0;
+        } else {
+          transformData.transform.op._mdf = false;
+        }
+      }
+      cont += 1;
+    }
+
+    this._currentCopies = copies;
+    /// /
+
+    var offset = this.o.v;
+    var offsetModulo = offset % 1;
+    var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
+    var pProps = this.pMatrix.props;
+    var rProps = this.rMatrix.props;
+    var sProps = this.sMatrix.props;
+    this.pMatrix.reset();
+    this.rMatrix.reset();
+    this.sMatrix.reset();
+    this.tMatrix.reset();
+    this.matrix.reset();
+    var iteration = 0;
+
+    if (offset > 0) {
+      while (iteration < roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        iteration += 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
+        iteration += offsetModulo;
+      }
+    } else if (offset < 0) {
+      while (iteration > roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
+        iteration -= 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
+        iteration -= offsetModulo;
+      }
+    }
+    i = this.data.m === 1 ? 0 : this._currentCopies - 1;
+    dir = this.data.m === 1 ? 1 : -1;
+    cont = this._currentCopies;
+    var j;
+    var jLen;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      jLen = itemsTransform.length;
+      items[items.length - 1].transform.mProps._mdf = true;
+      items[items.length - 1].transform.op._mdf = true;
+      items[items.length - 1].transform.op.v = this._currentCopies === 1
+        ? this.so.v
+        : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
+
+      if (iteration !== 0) {
+        if ((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)) {
+          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        }
+        this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
+        this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
+        this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
+
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+        this.matrix.reset();
+      } else {
+        this.matrix.reset();
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+      }
+      iteration += 1;
+      cont -= 1;
+      i += dir;
+    }
+  } else {
+    cont = this._currentCopies;
+    i = 0;
+    dir = 1;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      items[items.length - 1].transform.mProps._mdf = false;
+      items[items.length - 1].transform.op._mdf = false;
+      cont -= 1;
+      i += dir;
+    }
+  }
+  return hasReloaded;
+};
+
+RepeaterModifier.prototype.addShape = function () {};
+
+function RoundCornersModifier() {}
+extendPrototype([ShapeModifier], RoundCornersModifier);
+RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this._isAnimated = !!this.rd.effectsSequence.length;
+};
+
+RoundCornersModifier.prototype.processPath = function (path, round) {
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var i;
+  var len = path._length;
+  var currentV;
+  var currentI;
+  var currentO;
+  var closerV;
+  var distance;
+  var newPosPerc;
+  var index = 0;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < len; i += 1) {
+    currentV = path.v[i];
+    currentO = path.o[i];
+    currentI = path.i[i];
+    if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
+      if ((i === 0 || i === len - 1) && !path.c) {
+        clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
+        /* clonedPath.v[index] = currentV;
+                clonedPath.o[index] = currentO;
+                clonedPath.i[index] = currentI; */
+        index += 1;
+      } else {
+        if (i === 0) {
+          closerV = path.v[len - 1];
+        } else {
+          closerV = path.v[i - 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = iX;
+        iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
+        vY = iY;
+        oX = vX - (vX - currentV[0]) * roundCorner;
+        oY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+
+        if (i === len - 1) {
+          closerV = path.v[0];
+        } else {
+          closerV = path.v[i + 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = oX;
+        oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc;
+        vY = oY;
+        iX = vX - (vX - currentV[0]) * roundCorner;
+        iY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+      }
+    } else {
+      clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index);
+      index += 1;
+    }
+  }
+  return clonedPath;
+};
+
+RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var rd = this.rd.v;
+
+  if (rd !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function floatEqual(a, b) {
+  return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
+}
+
+function floatZero(f) {
+  return Math.abs(f) <= 0.00001;
+}
+
+function lerp(p0, p1, amount) {
+  return p0 * (1 - amount) + p1 * amount;
+}
+
+function lerpPoint(p0, p1, amount) {
+  return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
+}
+
+function quadRoots(a, b, c) {
+  // no root
+  if (a === 0) return [];
+  var s = b * b - 4 * a * c;
+  // Complex roots
+  if (s < 0) return [];
+  var singleRoot = -b / (2 * a);
+  // 1 root
+  if (s === 0) return [singleRoot];
+  var delta = Math.sqrt(s) / (2 * a);
+  // 2 roots
+  return [singleRoot - delta, singleRoot + delta];
+}
+
+function polynomialCoefficients(p0, p1, p2, p3) {
+  return [
+    -p0 + 3 * p1 - 3 * p2 + p3,
+    3 * p0 - 6 * p1 + 3 * p2,
+    -3 * p0 + 3 * p1,
+    p0,
+  ];
+}
+
+function singlePoint(p) {
+  return new PolynomialBezier(p, p, p, p, false);
+}
+
+function PolynomialBezier(p0, p1, p2, p3, linearize) {
+  if (linearize && pointEqual(p0, p1)) {
+    p1 = lerpPoint(p0, p3, 1 / 3);
+  }
+  if (linearize && pointEqual(p2, p3)) {
+    p2 = lerpPoint(p0, p3, 2 / 3);
+  }
+  var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
+  var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
+  this.a = [coeffx[0], coeffy[0]];
+  this.b = [coeffx[1], coeffy[1]];
+  this.c = [coeffx[2], coeffy[2]];
+  this.d = [coeffx[3], coeffy[3]];
+  this.points = [p0, p1, p2, p3];
+}
+PolynomialBezier.prototype.point = function (t) {
+  return [
+    (((this.a[0] * t) + this.b[0]) * t + this.c[0]) * t + this.d[0],
+    (((this.a[1] * t) + this.b[1]) * t + this.c[1]) * t + this.d[1],
+  ];
+};
+PolynomialBezier.prototype.derivative = function (t) {
+  return [
+    (3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0],
+    (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1],
+  ];
+};
+PolynomialBezier.prototype.tangentAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[1], p[0]);
+};
+PolynomialBezier.prototype.normalAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[0], p[1]);
+};
+
+PolynomialBezier.prototype.inflectionPoints = function () {
+  var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
+  if (floatZero(denom)) return [];
+  var tcusp = (-0.5 * (this.a[1] * this.c[0] - this.a[0] * this.c[1])) / denom;
+  var square = tcusp * tcusp - ((1 / 3) * (this.b[1] * this.c[0] - this.b[0] * this.c[1])) / denom;
+  if (square < 0) return [];
+  var root = Math.sqrt(square);
+  if (floatZero(root)) {
+    if (root > 0 && root < 1) return [tcusp];
+    return [];
+  }
+  return [tcusp - root, tcusp + root].filter(function (r) { return r > 0 && r < 1; });
+};
+PolynomialBezier.prototype.split = function (t) {
+  if (t <= 0) return [singlePoint(this.points[0]), this];
+  if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
+  var p10 = lerpPoint(this.points[0], this.points[1], t);
+  var p11 = lerpPoint(this.points[1], this.points[2], t);
+  var p12 = lerpPoint(this.points[2], this.points[3], t);
+  var p20 = lerpPoint(p10, p11, t);
+  var p21 = lerpPoint(p11, p12, t);
+  var p3 = lerpPoint(p20, p21, t);
+  return [
+    new PolynomialBezier(this.points[0], p10, p20, p3, true),
+    new PolynomialBezier(p3, p21, p12, this.points[3], true),
+  ];
+};
+function extrema(bez, comp) {
+  var min = bez.points[0][comp];
+  var max = bez.points[bez.points.length - 1][comp];
+  if (min > max) {
+    var e = max;
+    max = min;
+    min = e;
+  }
+  // Derivative roots to find min/max
+  var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
+  for (var i = 0; i < f.length; i += 1) {
+    if (f[i] > 0 && f[i] < 1) {
+      var val = bez.point(f[i])[comp];
+      if (val < min) min = val;
+      else if (val > max) max = val;
+    }
+  }
+  return {
+    min: min,
+    max: max,
+  };
+}
+PolynomialBezier.prototype.bounds = function () {
+  return {
+    x: extrema(this, 0),
+    y: extrema(this, 1),
+  };
+};
+PolynomialBezier.prototype.boundingBox = function () {
+  var bounds = this.bounds();
+  return {
+    left: bounds.x.min,
+    right: bounds.x.max,
+    top: bounds.y.min,
+    bottom: bounds.y.max,
+    width: bounds.x.max - bounds.x.min,
+    height: bounds.y.max - bounds.y.min,
+    cx: (bounds.x.max + bounds.x.min) / 2,
+    cy: (bounds.y.max + bounds.y.min) / 2,
+  };
+};
+
+function intersectData(bez, t1, t2) {
+  var box = bez.boundingBox();
+  return {
+    cx: box.cx,
+    cy: box.cy,
+    width: box.width,
+    height: box.height,
+    bez: bez,
+    t: (t1 + t2) / 2,
+    t1: t1,
+    t2: t2,
+  };
+}
+function splitData(data) {
+  var split = data.bez.split(0.5);
+  return [
+    intersectData(split[0], data.t1, data.t),
+    intersectData(split[1], data.t, data.t2),
+  ];
+}
+
+function boxIntersect(b1, b2) {
+  return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width
+    && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
+}
+
+function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
+  if (!boxIntersect(d1, d2)) return;
+  if (depth >= maxRecursion || (d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance)) {
+    intersections.push([d1.t, d2.t]);
+    return;
+  }
+  var d1s = splitData(d1);
+  var d2s = splitData(d2);
+  intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[0], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+}
+
+PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
+  if (tolerance === undefined) tolerance = 2;
+  if (maxRecursion === undefined) maxRecursion = 7;
+  var intersections = [];
+  intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
+  return intersections;
+};
+
+PolynomialBezier.shapeSegment = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
+};
+
+PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
+};
+
+function crossProduct(a, b) {
+  return [
+    a[1] * b[2] - a[2] * b[1],
+    a[2] * b[0] - a[0] * b[2],
+    a[0] * b[1] - a[1] * b[0],
+  ];
+}
+
+function lineIntersection(start1, end1, start2, end2) {
+  var v1 = [start1[0], start1[1], 1];
+  var v2 = [end1[0], end1[1], 1];
+  var v3 = [start2[0], start2[1], 1];
+  var v4 = [end2[0], end2[1], 1];
+
+  var r = crossProduct(
+    crossProduct(v1, v2),
+    crossProduct(v3, v4)
+  );
+
+  if (floatZero(r[2])) return null;
+
+  return [r[0] / r[2], r[1] / r[2]];
+}
+
+function polarOffset(p, angle, length) {
+  return [
+    p[0] + Math.cos(angle) * length,
+    p[1] - Math.sin(angle) * length,
+  ];
+}
+
+function pointDistance(p1, p2) {
+  return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
+}
+
+function pointEqual(p1, p2) {
+  return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
+}
+
+function ZigZagModifier() {}
+extendPrototype([ShapeModifier], ZigZagModifier);
+ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
+  this.frequency = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
+  this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
+};
+
+function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
+  var angO = angle - Math.PI / 2;
+  var angI = angle + Math.PI / 2;
+  var px = point[0] + Math.cos(angle) * direction * amplitude;
+  var py = point[1] - Math.sin(angle) * direction * amplitude;
+
+  outputBezier.setTripleAt(
+    px,
+    py,
+    px + Math.cos(angO) * outAmplitude,
+    py - Math.sin(angO) * outAmplitude,
+    px + Math.cos(angI) * inAmplitude,
+    py - Math.sin(angI) * inAmplitude,
+    outputBezier.length()
+  );
+}
+
+function getPerpendicularVector(pt1, pt2) {
+  var vector = [
+    pt2[0] - pt1[0],
+    pt2[1] - pt1[1],
+  ];
+  var rot = -Math.PI * 0.5;
+  var rotatedVector = [
+    Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1],
+    Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1],
+  ];
+  return rotatedVector;
+}
+
+function getProjectingAngle(path, cur) {
+  var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
+  var nextIndex = (cur + 1) % path.length();
+  var prevPoint = path.v[prevIndex];
+  var nextPoint = path.v[nextIndex];
+  var pVector = getPerpendicularVector(prevPoint, nextPoint);
+  return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
+}
+
+function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
+  var angle = getProjectingAngle(path, cur);
+  var point = path.v[cur % path._length];
+  var prevPoint = path.v[cur === 0 ? path._length - 1 : cur - 1];
+  var nextPoint = path.v[(cur + 1) % path._length];
+  var prevDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - prevPoint[0], 2) + Math.pow(point[1] - prevPoint[1], 2))
+    : 0;
+  var nextDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2))
+    : 0;
+
+  setPoint(
+    outputBezier,
+    path.v[cur % path._length],
+    angle,
+    direction,
+    amplitude,
+    nextDist / ((frequency + 1) * 2),
+    prevDist / ((frequency + 1) * 2),
+    pointType
+  );
+}
+
+function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
+  for (var i = 0; i < frequency; i += 1) {
+    var t = (i + 1) / (frequency + 1);
+
+    var dist = pointType === 2
+      ? Math.sqrt(Math.pow(segment.points[3][0] - segment.points[0][0], 2) + Math.pow(segment.points[3][1] - segment.points[0][1], 2))
+      : 0;
+
+    var angle = segment.normalAngle(t);
+    var point = segment.point(t);
+    setPoint(
+      outputBezier,
+      point,
+      angle,
+      direction,
+      amplitude,
+      dist / ((frequency + 1) * 2),
+      dist / ((frequency + 1) * 2),
+      pointType
+    );
+
+    direction = -direction;
+  }
+
+  return direction;
+}
+
+ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
+  var count = path._length;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+
+  if (!path.c) {
+    count -= 1;
+  }
+
+  if (count === 0) return clonedPath;
+
+  var direction = -1;
+  var segment = PolynomialBezier.shapeSegment(path, 0);
+  zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
+
+  for (var i = 0; i < count; i += 1) {
+    direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
+
+    if (i === count - 1 && !path.c) {
+      segment = null;
+    } else {
+      segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
+    }
+
+    zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
+  }
+
+  return clonedPath;
+};
+
+ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amplitude = this.amplitude.v;
+  var frequency = Math.max(0, Math.round(this.frequency.v));
+  var pointType = this.pointsType.v;
+
+  if (amplitude !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function linearOffset(p1, p2, amount) {
+  var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
+  return [
+    polarOffset(p1, angle, amount),
+    polarOffset(p2, angle, amount),
+  ];
+}
+
+function offsetSegment(segment, amount) {
+  var p0; var p1a; var p1b; var p2b; var p2a; var
+    p3;
+  var e;
+  e = linearOffset(segment.points[0], segment.points[1], amount);
+  p0 = e[0];
+  p1a = e[1];
+  e = linearOffset(segment.points[1], segment.points[2], amount);
+  p1b = e[0];
+  p2b = e[1];
+  e = linearOffset(segment.points[2], segment.points[3], amount);
+  p2a = e[0];
+  p3 = e[1];
+  var p1 = lineIntersection(p0, p1a, p1b, p2b);
+  if (p1 === null) p1 = p1a;
+  var p2 = lineIntersection(p2a, p3, p1b, p2b);
+  if (p2 === null) p2 = p2a;
+
+  return new PolynomialBezier(p0, p1, p2, p3);
+}
+
+function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
+  var p0 = seg1.points[3];
+  var p1 = seg2.points[0];
+
+  // Bevel
+  if (lineJoin === 3) return p0;
+
+  // Connected, they don't need a joint
+  if (pointEqual(p0, p1)) return p0;
+
+  // Round
+  if (lineJoin === 2) {
+    var angleOut = -seg1.tangentAngle(1);
+    var angleIn = -seg2.tangentAngle(0) + Math.PI;
+    var center = lineIntersection(
+      p0,
+      polarOffset(p0, angleOut + Math.PI / 2, 100),
+      p1,
+      polarOffset(p1, angleOut + Math.PI / 2, 100)
+    );
+    var radius = center ? pointDistance(center, p0) : pointDistance(p0, p1) / 2;
+
+    var tan = polarOffset(p0, angleOut, 2 * radius * roundCorner);
+    outputBezier.setXYAt(tan[0], tan[1], 'o', outputBezier.length() - 1);
+
+    tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
+    outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
+
+    return p1;
+  }
+
+  // Miter
+  var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
+  var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
+  var intersection = lineIntersection(t0, p0, p1, t1);
+  if (intersection && pointDistance(intersection, p0) < miterLimit) {
+    outputBezier.setTripleAt(
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      outputBezier.length()
+    );
+    return intersection;
+  }
+
+  return p0;
+}
+
+function getIntersection(a, b) {
+  const intersect = a.intersections(b);
+
+  if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
+
+  if (intersect.length) return intersect[0];
+
+  return null;
+}
+
+function pruneSegmentIntersection(a, b) {
+  var outa = a.slice();
+  var outb = b.slice();
+  var intersect = getIntersection(a[a.length - 1], b[0]);
+  if (intersect) {
+    outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
+    outb[0] = b[0].split(intersect[1])[1];
+  }
+  if (a.length > 1 && b.length > 1) {
+    intersect = getIntersection(a[0], b[b.length - 1]);
+    if (intersect) {
+      return [
+        [a[0].split(intersect[0])[0]],
+        [b[b.length - 1].split(intersect[1])[1]],
+      ];
+    }
+  }
+  return [outa, outb];
+}
+
+function pruneIntersections(segments) {
+  var e;
+  for (var i = 1; i < segments.length; i += 1) {
+    e = pruneSegmentIntersection(segments[i - 1], segments[i]);
+    segments[i - 1] = e[0];
+    segments[i] = e[1];
+  }
+
+  if (segments.length > 1) {
+    e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
+    segments[segments.length - 1] = e[0];
+    segments[0] = e[1];
+  }
+
+  return segments;
+}
+
+function offsetSegmentSplit(segment, amount) {
+  /*
+    We split each bezier segment into smaller pieces based
+    on inflection points, this ensures the control point
+    polygon is convex.
+
+    (A cubic bezier can have none, one, or two inflection points)
+  */
+  var flex = segment.inflectionPoints();
+  var left;
+  var right;
+  var split;
+  var mid;
+
+  if (flex.length === 0) {
+    return [offsetSegment(segment, amount)];
+  }
+
+  if (flex.length === 1 || floatEqual(flex[1], 1)) {
+    split = segment.split(flex[0]);
+    left = split[0];
+    right = split[1];
+
+    return [
+      offsetSegment(left, amount),
+      offsetSegment(right, amount),
+    ];
+  }
+
+  split = segment.split(flex[0]);
+  left = split[0];
+  var t = (flex[1] - flex[0]) / (1 - flex[0]);
+  split = split[1].split(t);
+  mid = split[0];
+  right = split[1];
+
+  return [
+    offsetSegment(left, amount),
+    offsetSegment(mid, amount),
+    offsetSegment(right, amount),
+  ];
+}
+
+function OffsetPathModifier() {}
+
+extendPrototype([ShapeModifier], OffsetPathModifier);
+OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this.miterLimit = PropertyFactory.getProp(elem, data.ml, 0, null, this);
+  this.lineJoin = data.lj;
+  this._isAnimated = this.amount.effectsSequence.length !== 0;
+};
+
+OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
+  var outputBezier = shapePool.newElement();
+  outputBezier.c = inputBezier.c;
+  var count = inputBezier.length();
+  if (!inputBezier.c) {
+    count -= 1;
+  }
+  var i; var j; var segment;
+  var multiSegments = [];
+
+  for (i = 0; i < count; i += 1) {
+    segment = PolynomialBezier.shapeSegment(inputBezier, i);
+    multiSegments.push(offsetSegmentSplit(segment, amount));
+  }
+
+  if (!inputBezier.c) {
+    for (i = count - 1; i >= 0; i -= 1) {
+      segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
+      multiSegments.push(offsetSegmentSplit(segment, amount));
+    }
+  }
+
+  multiSegments = pruneIntersections(multiSegments);
+
+  // Add bezier segments to the output and apply line joints
+  var lastPoint = null;
+  var lastSeg = null;
+
+  for (i = 0; i < multiSegments.length; i += 1) {
+    var multiSegment = multiSegments[i];
+
+    if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
+
+    lastSeg = multiSegment[multiSegment.length - 1];
+
+    for (j = 0; j < multiSegment.length; j += 1) {
+      segment = multiSegment[j];
+
+      if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
+        outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
+      } else {
+        outputBezier.setTripleAt(
+          segment.points[0][0],
+          segment.points[0][1],
+          segment.points[1][0],
+          segment.points[1][1],
+          segment.points[0][0],
+          segment.points[0][1],
+          outputBezier.length()
+        );
+      }
+
+      outputBezier.setTripleAt(
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[2][0],
+        segment.points[2][1],
+        outputBezier.length()
+      );
+
+      lastPoint = segment.points[3];
+    }
+  }
+
+  if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
+
+  return outputBezier;
+};
+
+OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+  var miterLimit = this.miterLimit.v;
+  var lineJoin = this.lineJoin;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function getFontProperties(fontData) {
+  var styles = fontData.fStyle ? fontData.fStyle.split(' ') : [];
+
+  var fWeight = 'normal'; var
+    fStyle = 'normal';
+  var len = styles.length;
+  var styleName;
+  for (var i = 0; i < len; i += 1) {
+    styleName = styles[i].toLowerCase();
+    switch (styleName) {
+      case 'italic':
+        fStyle = 'italic';
+        break;
+      case 'bold':
+        fWeight = '700';
+        break;
+      case 'black':
+        fWeight = '900';
+        break;
+      case 'medium':
+        fWeight = '500';
+        break;
+      case 'regular':
+      case 'normal':
+        fWeight = '400';
+        break;
+      case 'light':
+      case 'thin':
+        fWeight = '200';
+        break;
+      default:
+        break;
+    }
+  }
+
+  return {
+    style: fStyle,
+    weight: fontData.fWeight || fWeight,
+  };
+}
+
+const FontManager = (function () {
+  var maxWaitingTime = 5000;
+  var emptyChar = {
+    w: 0,
+    size: 0,
+    shapes: [],
+    data: {
+      shapes: [],
+    },
+  };
+  var combinedCharacters = [];
+  // Hindi characters
+  combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366,
+    2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379,
+    2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
+
+  var BLACK_FLAG_CODE_POINT = 127988;
+  var CANCEL_TAG_CODE_POINT = 917631;
+  var A_TAG_CODE_POINT = 917601;
+  var Z_TAG_CODE_POINT = 917626;
+  var VARIATION_SELECTOR_16_CODE_POINT = 65039;
+  var ZERO_WIDTH_JOINER_CODE_POINT = 8205;
+  var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
+  var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
+
+  var surrogateModifiers = [
+    'd83cdffb',
+    'd83cdffc',
+    'd83cdffd',
+    'd83cdffe',
+    'd83cdfff',
+  ];
+
+  function trimFontOptions(font) {
+    var familyArray = font.split(',');
+    var i;
+    var len = familyArray.length;
+    var enabledFamilies = [];
+    for (i = 0; i < len; i += 1) {
+      if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
+        enabledFamilies.push(familyArray[i]);
+      }
+    }
+    return enabledFamilies.join(',');
+  }
+
+  function setUpNode(font, family) {
+    var parentNode = createTag('span');
+    // Node is invisible to screen readers.
+    parentNode.setAttribute('aria-hidden', true);
+    parentNode.style.fontFamily = family;
+    var node = createTag('span');
+    // Characters that vary significantly among different fonts
+    node.innerText = 'giItT1WQy@!-/#';
+    // Visible - so we can measure it - but not on the screen
+    parentNode.style.position = 'absolute';
+    parentNode.style.left = '-10000px';
+    parentNode.style.top = '-10000px';
+    // Large font size makes even subtle changes obvious
+    parentNode.style.fontSize = '300px';
+    // Reset any font properties
+    parentNode.style.fontVariant = 'normal';
+    parentNode.style.fontStyle = 'normal';
+    parentNode.style.fontWeight = 'normal';
+    parentNode.style.letterSpacing = '0';
+    parentNode.appendChild(node);
+    document.body.appendChild(parentNode);
+
+    // Remember width with no applied web font
+    var width = node.offsetWidth;
+    node.style.fontFamily = trimFontOptions(font) + ', ' + family;
+    return { node: node, w: width, parent: parentNode };
+  }
+
+  function checkLoadedFonts() {
+    var i;
+    var len = this.fonts.length;
+    var node;
+    var w;
+    var loadedCount = len;
+    for (i = 0; i < len; i += 1) {
+      if (this.fonts[i].loaded) {
+        loadedCount -= 1;
+      } else if (this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0) {
+        this.fonts[i].loaded = true;
+      } else {
+        node = this.fonts[i].monoCase.node;
+        w = this.fonts[i].monoCase.w;
+        if (node.offsetWidth !== w) {
+          loadedCount -= 1;
+          this.fonts[i].loaded = true;
+        } else {
+          node = this.fonts[i].sansCase.node;
+          w = this.fonts[i].sansCase.w;
+          if (node.offsetWidth !== w) {
+            loadedCount -= 1;
+            this.fonts[i].loaded = true;
+          }
+        }
+        if (this.fonts[i].loaded) {
+          this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
+          this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
+        }
+      }
+    }
+
+    if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
+      setTimeout(this.checkLoadedFontsBinded, 20);
+    } else {
+      setTimeout(this.setIsLoadedBinded, 10);
+    }
+  }
+
+  function createHelper(fontData, def) {
+    var engine = (document.body && def) ? 'svg' : 'canvas';
+    var helper;
+    var fontProps = getFontProperties(fontData);
+    if (engine === 'svg') {
+      var tHelper = createNS('text');
+      tHelper.style.fontSize = '100px';
+      // tHelper.style.fontFamily = fontData.fFamily;
+      tHelper.setAttribute('font-family', fontData.fFamily);
+      tHelper.setAttribute('font-style', fontProps.style);
+      tHelper.setAttribute('font-weight', fontProps.weight);
+      tHelper.textContent = '1';
+      if (fontData.fClass) {
+        tHelper.style.fontFamily = 'inherit';
+        tHelper.setAttribute('class', fontData.fClass);
+      } else {
+        tHelper.style.fontFamily = fontData.fFamily;
+      }
+      def.appendChild(tHelper);
+      helper = tHelper;
+    } else {
+      var tCanvasHelper = new OffscreenCanvas(500, 500).getContext('2d');
+      tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
+      helper = tCanvasHelper;
+    }
+    function measure(text) {
+      if (engine === 'svg') {
+        helper.textContent = text;
+        return helper.getComputedTextLength();
+      }
+      return helper.measureText(text).width;
+    }
+    return {
+      measureText: measure,
+    };
+  }
+
+  function addFonts(fontData, defs) {
+    if (!fontData) {
+      this.isLoaded = true;
+      return;
+    }
+    if (this.chars) {
+      this.isLoaded = true;
+      this.fonts = fontData.list;
+      return;
+    }
+    if (!document.body) {
+      this.isLoaded = true;
+      fontData.list.forEach((data) => {
+        data.helper = createHelper(data);
+        data.cache = {};
+      });
+      this.fonts = fontData.list;
+      return;
+    }
+
+    var fontArr = fontData.list;
+    var i;
+    var len = fontArr.length;
+    var _pendingFonts = len;
+    for (i = 0; i < len; i += 1) {
+      var shouldLoadFont = true;
+      var loadedSelector;
+      var j;
+      fontArr[i].loaded = false;
+      fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
+      fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
+      if (!fontArr[i].fPath) {
+        fontArr[i].loaded = true;
+        _pendingFonts -= 1;
+      } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
+        loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
+
+        if (loadedSelector.length > 0) {
+          shouldLoadFont = false;
+        }
+
+        if (shouldLoadFont) {
+          var s = createTag('style');
+          s.setAttribute('f-forigin', fontArr[i].fOrigin);
+          s.setAttribute('f-origin', fontArr[i].origin);
+          s.setAttribute('f-family', fontArr[i].fFamily);
+          s.type = 'text/css';
+          s.innerText = '@font-face {font-family: ' + fontArr[i].fFamily + "; font-style: normal; src: url('" + fontArr[i].fPath + "');}";
+          defs.appendChild(s);
+        }
+      } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
+        loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var l = createTag('link');
+          l.setAttribute('f-forigin', fontArr[i].fOrigin);
+          l.setAttribute('f-origin', fontArr[i].origin);
+          l.type = 'text/css';
+          l.rel = 'stylesheet';
+          l.href = fontArr[i].fPath;
+          document.body.appendChild(l);
+        }
+      } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
+        loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (fontArr[i].fPath === loadedSelector[j].src) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var sc = createTag('link');
+          sc.setAttribute('f-forigin', fontArr[i].fOrigin);
+          sc.setAttribute('f-origin', fontArr[i].origin);
+          sc.setAttribute('rel', 'stylesheet');
+          sc.setAttribute('href', fontArr[i].fPath);
+          defs.appendChild(sc);
+        }
+      }
+      fontArr[i].helper = createHelper(fontArr[i], defs);
+      fontArr[i].cache = {};
+      this.fonts.push(fontArr[i]);
+    }
+    if (_pendingFonts === 0) {
+      this.isLoaded = true;
+    } else {
+      // On some cases even if the font is loaded, it won't load correctly when measuring text on canvas.
+      // Adding this timeout seems to fix it
+      setTimeout(this.checkLoadedFonts.bind(this), 100);
+    }
+  }
+
+  function addChars(chars) {
+    if (!chars) {
+      return;
+    }
+    if (!this.chars) {
+      this.chars = [];
+    }
+    var i;
+    var len = chars.length;
+    var j;
+    var jLen = this.chars.length;
+    var found;
+    for (i = 0; i < len; i += 1) {
+      j = 0;
+      found = false;
+      while (j < jLen) {
+        if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
+          found = true;
+        }
+        j += 1;
+      }
+      if (!found) {
+        this.chars.push(chars[i]);
+        jLen += 1;
+      }
+    }
+  }
+
+  function getCharData(char, style, font) {
+    var i = 0;
+    var len = this.chars.length;
+    while (i < len) {
+      if (this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font) {
+        return this.chars[i];
+      }
+      i += 1;
+    }
+    if (((typeof char === 'string' && char.charCodeAt(0) !== 13) || !char)
+            && console
+            && console.warn // eslint-disable-line no-console
+            && !this._warned
+    ) {
+      this._warned = true;
+      console.warn('Missing character from exported characters list: ', char, style, font); // eslint-disable-line no-console
+    }
+    return emptyChar;
+  }
+
+  function measureText(char, fontName, size) {
+    var fontData = this.getFontByName(fontName);
+    // Using the char instead of char.charCodeAt(0)
+    // to avoid collisions between equal chars
+    var index = char;
+    if (!fontData.cache[index]) {
+      var tHelper = fontData.helper;
+      if (char === ' ') {
+        var doubleSize = tHelper.measureText('|' + char + '|');
+        var singleSize = tHelper.measureText('||');
+        fontData.cache[index] = (doubleSize - singleSize) / 100;
+      } else {
+        fontData.cache[index] = tHelper.measureText(char) / 100;
+      }
+    }
+    return fontData.cache[index] * size;
+  }
+
+  function getFontByName(name) {
+    var i = 0;
+    var len = this.fonts.length;
+    while (i < len) {
+      if (this.fonts[i].fName === name) {
+        return this.fonts[i];
+      }
+      i += 1;
+    }
+    return this.fonts[0];
+  }
+
+  function getCodePoint(string) {
+    var codePoint = 0;
+    var first = string.charCodeAt(0);
+    if (first >= 0xD800 && first <= 0xDBFF) {
+      var second = string.charCodeAt(1);
+      if (second >= 0xDC00 && second <= 0xDFFF) {
+        codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+      }
+    }
+    return codePoint;
+  }
+
+  // Skin tone modifiers
+  function isModifier(firstCharCode, secondCharCode) {
+    var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
+    return surrogateModifiers.indexOf(sum) !== -1;
+  }
+
+  function isZeroWidthJoiner(charCode) {
+    return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
+  }
+
+  // This codepoint may change the appearance of the preceding character.
+  // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
+  // as a colorful image as compared to a monochrome text variant.
+  function isVariationSelector(charCode) {
+    return charCode === VARIATION_SELECTOR_16_CODE_POINT;
+  }
+
+  // The regional indicator symbols are a set of 26 alphabetic Unicode
+  /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
+  // two-letter country codes in a way that allows optional special treatment.
+  function isRegionalCode(string) {
+    var codePoint = getCodePoint(string);
+    if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
+      return true;
+    }
+    return false;
+  }
+
+  // Some Emoji implementations represent combinations of
+  // two “regional indicator” letters as a single flag symbol.
+  function isFlagEmoji(string) {
+    return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
+  }
+
+  function isCombinedCharacter(char) {
+    return combinedCharacters.indexOf(char) !== -1;
+  }
+
+  // Regional flags start with a BLACK_FLAG_CODE_POINT
+  // folowed by 5 chars in the TAG range
+  // and end with a CANCEL_TAG_CODE_POINT
+  function isRegionalFlag(text, index) {
+    var codePoint = getCodePoint(text.substr(index, 2));
+    if (codePoint !== BLACK_FLAG_CODE_POINT) {
+      return false;
+    }
+    var count = 0;
+    index += 2;
+    while (count < 5) {
+      codePoint = getCodePoint(text.substr(index, 2));
+      if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
+        return false;
+      }
+      count += 1;
+      index += 2;
+    }
+    return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
+  }
+
+  function setIsLoaded() {
+    this.isLoaded = true;
+  }
+
+  var Font = function () {
+    this.fonts = [];
+    this.chars = null;
+    this.typekitLoaded = 0;
+    this.isLoaded = false;
+    this._warned = false;
+    this.initTime = Date.now();
+    this.setIsLoadedBinded = this.setIsLoaded.bind(this);
+    this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
+  };
+  Font.isModifier = isModifier;
+  Font.isZeroWidthJoiner = isZeroWidthJoiner;
+  Font.isFlagEmoji = isFlagEmoji;
+  Font.isRegionalCode = isRegionalCode;
+  Font.isCombinedCharacter = isCombinedCharacter;
+  Font.isRegionalFlag = isRegionalFlag;
+  Font.isVariationSelector = isVariationSelector;
+  Font.BLACK_FLAG_CODE_POINT = BLACK_FLAG_CODE_POINT;
+
+  var fontPrototype = {
+    addChars: addChars,
+    addFonts: addFonts,
+    getCharData: getCharData,
+    getFontByName: getFontByName,
+    measureText: measureText,
+    checkLoadedFonts: checkLoadedFonts,
+    setIsLoaded: setIsLoaded,
+  };
+
+  Font.prototype = fontPrototype;
+
+  return Font;
+}());
+
+function SlotManager(animationData) {
+  this.animationData = animationData;
+}
+SlotManager.prototype.getProp = function (data) {
+  if (this.animationData.slots
+    && this.animationData.slots[data.sid]
+  ) {
+    return Object.assign(data, this.animationData.slots[data.sid].p);
+  }
+  return data;
+};
+
+function slotFactory(animationData) {
+  return new SlotManager(animationData);
+}
+
+function RenderableElement() {
+
+}
+
+RenderableElement.prototype = {
+  initRenderable: function () {
+    // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
+    this.isInRange = false;
+    // layer's display state
+    this.hidden = false;
+    // If layer's transparency equals 0, it can be hidden
+    this.isTransparent = false;
+    // list of animated components
+    this.renderableComponents = [];
+  },
+  addRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) === -1) {
+      this.renderableComponents.push(component);
+    }
+  },
+  removeRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) !== -1) {
+      this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1);
+    }
+  },
+  prepareRenderableFrame: function (num) {
+    this.checkLayerLimits(num);
+  },
+  checkTransparency: function () {
+    if (this.finalTransform.mProp.o.v <= 0) {
+      if (!this.isTransparent && this.globalData.renderConfig.hideOnTransparent) {
+        this.isTransparent = true;
+        this.hide();
+      }
+    } else if (this.isTransparent) {
+      this.isTransparent = false;
+      this.show();
+    }
+  },
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     *
+     */
+  checkLayerLimits: function (num) {
+    if (this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) {
+      if (this.isInRange !== true) {
+        this.globalData._mdf = true;
+        this._mdf = true;
+        this.isInRange = true;
+        this.show();
+      }
+    } else if (this.isInRange !== false) {
+      this.globalData._mdf = true;
+      this.isInRange = false;
+      this.hide();
+    }
+  },
+  renderRenderable: function () {
+    var i;
+    var len = this.renderableComponents.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderableComponents[i].renderFrame(this._isFirstFrame);
+    }
+    /* this.maskManager.renderFrame(this.finalTransform.mat);
+        this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
+  },
+  sourceRectAtTime: function () {
+    return {
+      top: 0,
+      left: 0,
+      width: 100,
+      height: 100,
+    };
+  },
+  getLayerSize: function () {
+    if (this.data.ty === 5) {
+      return { w: this.data.textData.width, h: this.data.textData.height };
+    }
+    return { w: this.data.width, h: this.data.height };
+  },
+};
+
+const getBlendMode = (function () {
+  var blendModeEnums = {
+    0: 'source-over',
+    1: 'multiply',
+    2: 'screen',
+    3: 'overlay',
+    4: 'darken',
+    5: 'lighten',
+    6: 'color-dodge',
+    7: 'color-burn',
+    8: 'hard-light',
+    9: 'soft-light',
+    10: 'difference',
+    11: 'exclusion',
+    12: 'hue',
+    13: 'saturation',
+    14: 'color',
+    15: 'luminosity',
+  };
+
+  return function (mode) {
+    return blendModeEnums[mode] || '';
+  };
+}());
+
+function SliderEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function AngleEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function ColorEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function PointEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function LayerIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function MaskIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function CheckboxEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function NoValueEffect() {
+  this.p = {};
+}
+
+function EffectsManager(data, element) {
+  var effects = data.ef || [];
+  this.effectElements = [];
+  var i;
+  var len = effects.length;
+  var effectItem;
+  for (i = 0; i < len; i += 1) {
+    effectItem = new GroupEffect(effects[i], element);
+    this.effectElements.push(effectItem);
+  }
+}
+
+function GroupEffect(data, element) {
+  this.init(data, element);
+}
+
+extendPrototype([DynamicPropertyContainer], GroupEffect);
+
+GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
+
+GroupEffect.prototype.init = function (data, element) {
+  this.data = data;
+  this.effectElements = [];
+  this.initDynamicPropertyContainer(element);
+  var i;
+  var len = this.data.ef.length;
+  var eff;
+  var effects = this.data.ef;
+  for (i = 0; i < len; i += 1) {
+    eff = null;
+    switch (effects[i].ty) {
+      case 0:
+        eff = new SliderEffect(effects[i], element, this);
+        break;
+      case 1:
+        eff = new AngleEffect(effects[i], element, this);
+        break;
+      case 2:
+        eff = new ColorEffect(effects[i], element, this);
+        break;
+      case 3:
+        eff = new PointEffect(effects[i], element, this);
+        break;
+      case 4:
+      case 7:
+        eff = new CheckboxEffect(effects[i], element, this);
+        break;
+      case 10:
+        eff = new LayerIndexEffect(effects[i], element, this);
+        break;
+      case 11:
+        eff = new MaskIndexEffect(effects[i], element, this);
+        break;
+      case 5:
+        eff = new EffectsManager(effects[i], element, this);
+        break;
+        // case 6:
+      default:
+        eff = new NoValueEffect(effects[i], element, this);
+        break;
+    }
+    if (eff) {
+      this.effectElements.push(eff);
+    }
+  }
+};
+
+function BaseElement() {
+}
+
+BaseElement.prototype = {
+  checkMasks: function () {
+    if (!this.data.hasMask) {
+      return false;
+    }
+    var i = 0;
+    var len = this.data.masksProperties.length;
+    while (i < len) {
+      if ((this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false)) {
+        return true;
+      }
+      i += 1;
+    }
+    return false;
+  },
+  initExpressions: function () {
+    const expressionsInterfaces = getExpressionInterfaces();
+    if (!expressionsInterfaces) {
+      return;
+    }
+    const LayerExpressionInterface = expressionsInterfaces('layer');
+    const EffectsExpressionInterface = expressionsInterfaces('effects');
+    const ShapeExpressionInterface = expressionsInterfaces('shape');
+    const TextExpressionInterface = expressionsInterfaces('text');
+    const CompExpressionInterface = expressionsInterfaces('comp');
+    this.layerInterface = LayerExpressionInterface(this);
+    if (this.data.hasMask && this.maskManager) {
+      this.layerInterface.registerMaskInterface(this.maskManager);
+    }
+    var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
+    this.layerInterface.registerEffectsInterface(effectsInterface);
+
+    if (this.data.ty === 0 || this.data.xt) {
+      this.compInterface = CompExpressionInterface(this);
+    } else if (this.data.ty === 4) {
+      this.layerInterface.shapeInterface = ShapeExpressionInterface(this.shapesData, this.itemsData, this.layerInterface);
+      this.layerInterface.content = this.layerInterface.shapeInterface;
+    } else if (this.data.ty === 5) {
+      this.layerInterface.textInterface = TextExpressionInterface(this);
+      this.layerInterface.text = this.layerInterface.textInterface;
+    }
+  },
+  setBlendMode: function () {
+    var blendModeValue = getBlendMode(this.data.bm);
+    var elem = this.baseElement || this.layerElement;
+
+    elem.style['mix-blend-mode'] = blendModeValue;
+  },
+  initBaseData: function (data, globalData, comp) {
+    this.globalData = globalData;
+    this.comp = comp;
+    this.data = data;
+    this.layerId = createElementID();
+
+    // Stretch factor for old animations missing this property.
+    if (!this.data.sr) {
+      this.data.sr = 1;
+    }
+    // effects manager
+    this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
+  },
+  getType: function () {
+    return this.type;
+  },
+  sourceRectAtTime: function () {},
+};
+
+/**
+ * @file
+ * Handles element's layer frame update.
+ * Checks layer in point and out point
+ *
+ */
+
+function FrameElement() {}
+
+FrameElement.prototype = {
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     */
+  initFrame: function () {
+    // set to true when inpoint is rendered
+    this._isFirstFrame = false;
+    // list of animated properties
+    this.dynamicProperties = [];
+    // If layer has been modified in current tick this will be true
+    this._mdf = false;
+  },
+  /**
+     * @function
+     * Calculates all dynamic values
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     * @param {boolean} isVisible
+     * if layers is currently in range
+     *
+     */
+  prepareProperties: function (num, isVisible) {
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      if (isVisible || (this._isParent && this.dynamicProperties[i].propType === 'transform')) {
+        this.dynamicProperties[i].getValue();
+        if (this.dynamicProperties[i]._mdf) {
+          this.globalData._mdf = true;
+          this._mdf = true;
+        }
+      }
+    }
+  },
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+    }
+  },
+};
+
+function FootageElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.footageData = globalData.imageLoader.getAsset(this.assetData);
+  this.initBaseData(data, globalData, comp);
+}
+
+FootageElement.prototype.prepareFrame = function () {
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
+
+FootageElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+FootageElement.prototype.renderFrame = function () {
+};
+
+FootageElement.prototype.destroy = function () {
+};
+
+FootageElement.prototype.initExpressions = function () {
+  const expressionsInterfaces = getExpressionInterfaces();
+  if (!expressionsInterfaces) {
+    return;
+  }
+  const FootageInterface = expressionsInterfaces('footage');
+  this.layerInterface = FootageInterface(this);
+};
+
+FootageElement.prototype.getFootageData = function () {
+  return this.footageData;
+};
+
+function AudioElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initBaseData(data, globalData, comp);
+  this._isPlaying = false;
+  this._canPlay = false;
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  this.audio = this.globalData.audioController.createAudio(assetPath);
+  this._currentTime = 0;
+  this.globalData.audioController.addAudio(this);
+  this._volumeMultiplier = 1;
+  this._volume = 1;
+  this._previousVolume = null;
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+  this.lv = PropertyFactory.getProp(this, data.au && data.au.lv ? data.au.lv : { k: [100] }, 1, 0.01, this);
+}
+
+AudioElement.prototype.prepareFrame = function (num) {
+  this.prepareRenderableFrame(num, true);
+  this.prepareProperties(num, true);
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    this._currentTime = timeRemapped;
+  } else {
+    this._currentTime = num / this.data.sr;
+  }
+  this._volume = this.lv.v[0];
+  var totalVolume = this._volume * this._volumeMultiplier;
+  if (this._previousVolume !== totalVolume) {
+    this._previousVolume = totalVolume;
+    this.audio.volume(totalVolume);
+  }
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
+
+AudioElement.prototype.renderFrame = function () {
+  if (this.isInRange && this._canPlay) {
+    if (!this._isPlaying) {
+      this.audio.play();
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+      this._isPlaying = true;
+    } else if (!this.audio.playing()
+      || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1
+    ) {
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+    }
+  }
+};
+
+AudioElement.prototype.show = function () {
+  // this.audio.play()
+};
+
+AudioElement.prototype.hide = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+};
+
+AudioElement.prototype.pause = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+  this._canPlay = false;
+};
+
+AudioElement.prototype.resume = function () {
+  this._canPlay = true;
+};
+
+AudioElement.prototype.setRate = function (rateValue) {
+  this.audio.rate(rateValue);
+};
+
+AudioElement.prototype.volume = function (volumeValue) {
+  this._volumeMultiplier = volumeValue;
+  this._previousVolume = volumeValue * this._volume;
+  this.audio.volume(this._previousVolume);
+};
+
+AudioElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+AudioElement.prototype.destroy = function () {
+};
+
+AudioElement.prototype.sourceRectAtTime = function () {
+};
+
+AudioElement.prototype.initExpressions = function () {
+};
+
+function BaseRenderer() {}
+BaseRenderer.prototype.checkLayers = function (num) {
+  var i;
+  var len = this.layers.length;
+  var data;
+  this.completeLayers = true;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (!this.elements[i]) {
+      data = this.layers[i];
+      if (data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) {
+        this.buildItem(i);
+      }
+    }
+    this.completeLayers = this.elements[i] ? this.completeLayers : false;
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.createItem = function (layer) {
+  switch (layer.ty) {
+    case 2:
+      return this.createImage(layer);
+    case 0:
+      return this.createComp(layer);
+    case 1:
+      return this.createSolid(layer);
+    case 3:
+      return this.createNull(layer);
+    case 4:
+      return this.createShape(layer);
+    case 5:
+      return this.createText(layer);
+    case 6:
+      return this.createAudio(layer);
+    case 13:
+      return this.createCamera(layer);
+    case 15:
+      return this.createFootage(layer);
+    default:
+      return this.createNull(layer);
+  }
+};
+
+BaseRenderer.prototype.createCamera = function () {
+  throw new Error('You\'re using a 3d camera. Try the html renderer.');
+};
+
+BaseRenderer.prototype.createAudio = function (data) {
+  return new AudioElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.createFootage = function (data) {
+  return new FootageElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.buildAllItems = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    this.buildItem(i);
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.includeLayers = function (newLayers) {
+  this.completeLayers = false;
+  var i;
+  var len = newLayers.length;
+  var j;
+  var jLen = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    j = 0;
+    while (j < jLen) {
+      if (this.layers[j].id === newLayers[i].id) {
+        this.layers[j] = newLayers[i];
+        break;
+      }
+      j += 1;
+    }
+  }
+};
+
+BaseRenderer.prototype.setProjectInterface = function (pInterface) {
+  this.globalData.projectInterface = pInterface;
+};
+
+BaseRenderer.prototype.initItems = function () {
+  if (!this.globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+};
+BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
+  var elements = this.elements;
+  var layers = this.layers;
+  var i = 0;
+  var len = layers.length;
+  while (i < len) {
+    if (layers[i].ind == parentName) { // eslint-disable-line eqeqeq
+      if (!elements[i] || elements[i] === true) {
+        this.buildItem(i);
+        this.addPendingElement(element);
+      } else {
+        hierarchy.push(elements[i]);
+        elements[i].setAsParent();
+        if (layers[i].parent !== undefined) {
+          this.buildElementParenting(element, layers[i].parent, hierarchy);
+        } else {
+          element.setHierarchy(hierarchy);
+        }
+      }
+    }
+    i += 1;
+  }
+};
+
+BaseRenderer.prototype.addPendingElement = function (element) {
+  this.pendingElements.push(element);
+};
+
+BaseRenderer.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var len = assets.length;
+  for (i = 0; i < len; i += 1) {
+    if (assets[i].xt) {
+      var comp = this.createComp(assets[i]);
+      comp.initExpressions();
+      this.globalData.projectInterface.registerComposition(comp);
+    }
+  }
+};
+
+BaseRenderer.prototype.getElementById = function (ind) {
+  var i;
+  var len = this.elements.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i].data.ind === ind) {
+      return this.elements[i];
+    }
+  }
+  return null;
+};
+
+BaseRenderer.prototype.getElementByPath = function (path) {
+  var pathValue = path.shift();
+  var element;
+  if (typeof pathValue === 'number') {
+    element = this.elements[pathValue];
+  } else {
+    var i;
+    var len = this.elements.length;
+    for (i = 0; i < len; i += 1) {
+      if (this.elements[i].data.nm === pathValue) {
+        element = this.elements[i];
+        break;
+      }
+    }
+  }
+  if (path.length === 0) {
+    return element;
+  }
+  return element.getElementByPath(path);
+};
+
+BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
+  this.globalData.fontManager = new FontManager();
+  this.globalData.slotManager = slotFactory(animData);
+  this.globalData.fontManager.addChars(animData.chars);
+  this.globalData.fontManager.addFonts(animData.fonts, fontsContainer);
+  this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+  this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+  this.globalData.imageLoader = this.animationItem.imagePreloader;
+  this.globalData.audioController = this.animationItem.audioController;
+  this.globalData.frameId = 0;
+  this.globalData.frameRate = animData.fr;
+  this.globalData.nm = animData.nm;
+  this.globalData.compSize = {
+    w: animData.w,
+    h: animData.h,
+  };
+};
+
+var effectTypes = {
+  TRANSFORM_EFFECT: 'transformEFfect',
+};
+
+function TransformElement() {}
+
+TransformElement.prototype = {
+  initTransform: function () {
+    var mat = new Matrix();
+    this.finalTransform = {
+      mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : { o: 0 },
+      _matMdf: false,
+      _localMatMdf: false,
+      _opMdf: false,
+      mat: mat,
+      localMat: mat,
+      localOpacity: 1,
+    };
+    if (this.data.ao) {
+      this.finalTransform.mProp.autoOriented = true;
+    }
+
+    // TODO: check TYPE 11: Guided elements
+    if (this.data.ty !== 11) {
+      // this.createElements();
+    }
+  },
+  renderTransform: function () {
+    this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
+    this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
+
+    if (this.hierarchy) {
+      var mat;
+      var finalMat = this.finalTransform.mat;
+      var i = 0;
+      var len = this.hierarchy.length;
+      // Checking if any of the transformation matrices in the hierarchy chain has changed.
+      if (!this.finalTransform._matMdf) {
+        while (i < len) {
+          if (this.hierarchy[i].finalTransform.mProp._mdf) {
+            this.finalTransform._matMdf = true;
+            break;
+          }
+          i += 1;
+        }
+      }
+
+      if (this.finalTransform._matMdf) {
+        mat = this.finalTransform.mProp.v.props;
+        finalMat.cloneFromProps(mat);
+        for (i = 0; i < len; i += 1) {
+          finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
+        }
+      }
+    }
+    if (!this.localTransforms || this.finalTransform._matMdf) {
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+    }
+    if (this.finalTransform._opMdf) {
+      this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderLocalTransform: function () {
+    if (this.localTransforms) {
+      var i = 0;
+      var len = this.localTransforms.length;
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+      if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
+        while (i < len) {
+          if (this.localTransforms[i]._mdf) {
+            this.finalTransform._localMatMdf = true;
+          }
+          if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
+            this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+            this.finalTransform._opMdf = true;
+          }
+          i += 1;
+        }
+      }
+      if (this.finalTransform._localMatMdf) {
+        var localMat = this.finalTransform.localMat;
+        this.localTransforms[0].matrix.clone(localMat);
+        for (i = 1; i < len; i += 1) {
+          var lmat = this.localTransforms[i].matrix;
+          localMat.multiply(lmat);
+        }
+        localMat.multiply(this.finalTransform.mat);
+      }
+      if (this.finalTransform._opMdf) {
+        var localOp = this.finalTransform.localOpacity;
+        for (i = 0; i < len; i += 1) {
+          localOp *= this.localTransforms[i].opacity * 0.01;
+        }
+        this.finalTransform.localOpacity = localOp;
+      }
+    }
+  },
+  searchEffectTransforms: function () {
+    if (this.renderableEffectsManager) {
+      var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+      if (transformEffects.length) {
+        this.localTransforms = [];
+        this.finalTransform.localMat = new Matrix();
+        var i = 0;
+        var len = transformEffects.length;
+        for (i = 0; i < len; i += 1) {
+          this.localTransforms.push(transformEffects[i]);
+        }
+      }
+    }
+  },
+  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;
+    var len = transforms.length;
+    var 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;
+  },
+  mHelper: new Matrix(),
+};
+
+function MaskElement(data, element, globalData) {
+  this.data = data;
+  this.element = element;
+  this.globalData = globalData;
+  this.storedData = [];
+  this.masksProperties = this.data.masksProperties || [];
+  this.maskElement = null;
+  var defs = this.globalData.defs;
+  var i;
+  var len = this.masksProperties ? this.masksProperties.length : 0;
+  this.viewData = createSizedArray(len);
+  this.solidPath = '';
+
+  var path;
+  var properties = this.masksProperties;
+  var count = 0;
+  var currentMasks = [];
+  var j;
+  var jLen;
+  var layerId = createElementID();
+  var rect;
+  var expansor;
+  var feMorph;
+  var x;
+  var maskType = 'clipPath';
+  var maskRef = 'clip-path';
+  for (i = 0; i < len; i += 1) {
+    if ((properties[i].mode !== 'a' && properties[i].mode !== 'n') || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
+      maskType = 'mask';
+      maskRef = 'mask';
+    }
+
+    if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
+      rect = createNS('rect');
+      rect.setAttribute('fill', '#ffffff');
+      rect.setAttribute('width', this.element.comp.data.w || 0);
+      rect.setAttribute('height', this.element.comp.data.h || 0);
+      currentMasks.push(rect);
+    } else {
+      rect = null;
+    }
+
+    path = createNS('path');
+    if (properties[i].mode === 'n') {
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        elem: path,
+        lastPath: '',
+      };
+      defs.appendChild(path);
+    } else {
+      count += 1;
+
+      path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      path.setAttribute('clip-rule', 'nonzero');
+      var filterID;
+
+      if (properties[i].x.k !== 0) {
+        maskType = 'mask';
+        maskRef = 'mask';
+        x = PropertyFactory.getProp(this.element, properties[i].x, 0, null, this.element);
+        filterID = createElementID();
+        expansor = createNS('filter');
+        expansor.setAttribute('id', filterID);
+        feMorph = createNS('feMorphology');
+        feMorph.setAttribute('operator', 'erode');
+        feMorph.setAttribute('in', 'SourceGraphic');
+        feMorph.setAttribute('radius', '0');
+        expansor.appendChild(feMorph);
+        defs.appendChild(expansor);
+        path.setAttribute('stroke', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      } else {
+        feMorph = null;
+        x = null;
+      }
+
+      // TODO move this to a factory or to a constructor
+      this.storedData[i] = {
+        elem: path,
+        x: x,
+        expan: feMorph,
+        lastPath: '',
+        lastOperator: '',
+        filterId: filterID,
+        lastRadius: 0,
+      };
+      if (properties[i].mode === 'i') {
+        jLen = currentMasks.length;
+        var g = createNS('g');
+        for (j = 0; j < jLen; j += 1) {
+          g.appendChild(currentMasks[j]);
+        }
+        var mask = createNS('mask');
+        mask.setAttribute('mask-type', 'alpha');
+        mask.setAttribute('id', layerId + '_' + count);
+        mask.appendChild(path);
+        defs.appendChild(mask);
+        g.setAttribute('mask', 'url(' + getLocationHref() + '#' + layerId + '_' + count + ')');
+
+        currentMasks.length = 0;
+        currentMasks.push(g);
+      } else {
+        currentMasks.push(path);
+      }
+      if (properties[i].inv && !this.solidPath) {
+        this.solidPath = this.createLayerSolidPath();
+      }
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        elem: path,
+        lastPath: '',
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        invRect: rect,
+      };
+      if (!this.viewData[i].prop.k) {
+        this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
+      }
+    }
+  }
+
+  this.maskElement = createNS(maskType);
+
+  len = currentMasks.length;
+  for (i = 0; i < len; i += 1) {
+    this.maskElement.appendChild(currentMasks[i]);
+  }
+
+  if (count > 0) {
+    this.maskElement.setAttribute('id', layerId);
+    this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
+    defs.appendChild(this.maskElement);
+  }
+  if (this.viewData.length) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+MaskElement.prototype.getMaskProperty = function (pos) {
+  return this.viewData[pos].prop;
+};
+
+MaskElement.prototype.renderFrame = function (isFirstFrame) {
+  var finalMat = this.element.finalTransform.mat;
+  var i;
+  var len = this.masksProperties.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.viewData[i].prop._mdf || isFirstFrame) {
+      this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
+    }
+    if (this.viewData[i].op._mdf || isFirstFrame) {
+      this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
+    }
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
+        this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
+      }
+      if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
+        var feMorph = this.storedData[i].expan;
+        if (this.storedData[i].x.v < 0) {
+          if (this.storedData[i].lastOperator !== 'erode') {
+            this.storedData[i].lastOperator = 'erode';
+            this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
+          }
+          feMorph.setAttribute('radius', -this.storedData[i].x.v);
+        } else {
+          if (this.storedData[i].lastOperator !== 'dilate') {
+            this.storedData[i].lastOperator = 'dilate';
+            this.storedData[i].elem.setAttribute('filter', null);
+          }
+          this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
+        }
+      }
+    }
+  }
+};
+
+MaskElement.prototype.getMaskelement = function () {
+  return this.maskElement;
+};
+
+MaskElement.prototype.createLayerSolidPath = function () {
+  var path = 'M0,0 ';
+  path += ' h' + this.globalData.compSize.w;
+  path += ' v' + this.globalData.compSize.h;
+  path += ' h-' + this.globalData.compSize.w;
+  path += ' v-' + this.globalData.compSize.h + ' ';
+  return path;
+};
+
+MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
+  var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  var i;
+  var len;
+  len = pathNodes._length;
+  for (i = 1; i < len; i += 1) {
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
+  }
+  // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+  if (pathNodes.c && len > 1) {
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  }
+  // pathNodes.__renderedString = pathString;
+
+  if (viewData.lastPath !== pathString) {
+    var pathShapeValue = '';
+    if (viewData.elem) {
+      if (pathNodes.c) {
+        pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
+      }
+      viewData.elem.setAttribute('d', pathShapeValue);
+    }
+    viewData.lastPath = pathString;
+  }
+};
+
+MaskElement.prototype.destroy = function () {
+  this.element = null;
+  this.globalData = null;
+  this.maskElement = null;
+  this.data = null;
+  this.masksProperties = null;
+};
+
+const filtersFactory = (function () {
+  var ob = {};
+  ob.createFilter = createFilter;
+  ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
+
+  function createFilter(filId, skipCoordinates) {
+    var fil = createNS('filter');
+    fil.setAttribute('id', filId);
+    if (skipCoordinates !== true) {
+      fil.setAttribute('filterUnits', 'objectBoundingBox');
+      fil.setAttribute('x', '0%');
+      fil.setAttribute('y', '0%');
+      fil.setAttribute('width', '100%');
+      fil.setAttribute('height', '100%');
+    }
+    return fil;
+  }
+
+  function createAlphaToLuminanceFilter() {
+    var feColorMatrix = createNS('feColorMatrix');
+    feColorMatrix.setAttribute('type', 'matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+    feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
+    return feColorMatrix;
+  }
+
+  return ob;
+}());
+
+const featureSupport = (function () {
+  var ob = {
+    maskType: true,
+    svgLumaHidden: true,
+    offscreenCanvas: typeof OffscreenCanvas !== 'undefined',
+  };
+  if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
+    ob.maskType = false;
+  }
+  if (/firefox/i.test(navigator.userAgent)) {
+    ob.svgLumaHidden = false;
+  }
+  return ob;
+}());
+
+var registeredEffects$1 = {};
+var idPrefix = 'filter_result_';
+
+function SVGEffects(elem) {
+  var i;
+  var source = 'SourceGraphic';
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  var filId = createElementID();
+  var fil = filtersFactory.createFilter(filId, true);
+  var count = 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects$1[type]) {
+      var Effect = registeredEffects$1[type].effect;
+      filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
+      source = idPrefix + count;
+      if (registeredEffects$1[type].countsAsEffect) {
+        count += 1;
+      }
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (count) {
+    elem.globalData.defs.appendChild(fil);
+    elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+SVGEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect$1(id, effect, countsAsEffect) {
+  registeredEffects$1[id] = {
+    effect,
+    countsAsEffect,
+  };
+}
+
+function SVGBaseElement() {
+}
+
+SVGBaseElement.prototype = {
+  initRendererElement: function () {
+    this.layerElement = createNS('g');
+  },
+  createContainerElements: function () {
+    this.matteElement = createNS('g');
+    this.transformedElement = this.layerElement;
+    this.maskedElement = this.layerElement;
+    this._sizeChanged = false;
+    var layerElementParent = null;
+    // If this layer acts as a mask for the following layer
+    if (this.data.td) {
+      this.matteMasks = {};
+      var gg = createNS('g');
+      gg.setAttribute('id', this.layerId);
+      gg.appendChild(this.layerElement);
+      layerElementParent = gg;
+      this.globalData.defs.appendChild(gg);
+    } else if (this.data.tt) {
+      this.matteElement.appendChild(this.layerElement);
+      layerElementParent = this.matteElement;
+      this.baseElement = this.matteElement;
+    } else {
+      this.baseElement = this.layerElement;
+    }
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
+    if (this.data.ty === 0 && !this.data.hd) {
+      var cp = createNS('clipPath');
+      var pt = createNS('path');
+      pt.setAttribute('d', 'M0,0 L' + this.data.w + ',0 L' + this.data.w + ',' + this.data.h + ' L0,' + this.data.h + 'z');
+      var clipId = createElementID();
+      cp.setAttribute('id', clipId);
+      cp.appendChild(pt);
+      this.globalData.defs.appendChild(cp);
+
+      if (this.checkMasks()) {
+        var cpGroup = createNS('g');
+        cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+        cpGroup.appendChild(this.layerElement);
+        this.transformedElement = cpGroup;
+        if (layerElementParent) {
+          layerElementParent.appendChild(this.transformedElement);
+        } else {
+          this.baseElement = this.transformedElement;
+        }
+      } else {
+        this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+      }
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    if (this.finalTransform._localMatMdf) {
+      this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
+    }
+    if (this.finalTransform._opMdf) {
+      this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
+    }
+  },
+  destroyBaseElement: function () {
+    this.layerElement = null;
+    this.matteElement = null;
+    this.maskManager.destroy();
+  },
+  getBaseElement: function () {
+    if (this.data.hd) {
+      return null;
+    }
+    return this.baseElement;
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+    this.renderableEffectsManager = new SVGEffects(this);
+    this.searchEffectTransforms();
+  },
+  getMatte: function (matteType) {
+    // This should not be a common case. But for backward compatibility, we'll create the matte object.
+    // It solves animations that have two consecutive layers marked as matte masks.
+    // Which is an undefined behavior in AE.
+    if (!this.matteMasks) {
+      this.matteMasks = {};
+    }
+    if (!this.matteMasks[matteType]) {
+      var id = this.layerId + '_' + matteType;
+      var filId;
+      var fil;
+      var useElement;
+      var gg;
+      if (matteType === 1 || matteType === 3) {
+        var masker = createNS('mask');
+        masker.setAttribute('id', id);
+        masker.setAttribute('mask-type', matteType === 3 ? 'luminance' : 'alpha');
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        masker.appendChild(useElement);
+        this.globalData.defs.appendChild(masker);
+        if (!featureSupport.maskType && matteType === 1) {
+          masker.setAttribute('mask-type', 'luminance');
+          filId = createElementID();
+          fil = filtersFactory.createFilter(filId);
+          this.globalData.defs.appendChild(fil);
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          gg.appendChild(useElement);
+          masker.appendChild(gg);
+          gg.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        }
+      } else if (matteType === 2) {
+        var maskGroup = createNS('mask');
+        maskGroup.setAttribute('id', id);
+        maskGroup.setAttribute('mask-type', 'alpha');
+        var maskGrouper = createNS('g');
+        maskGroup.appendChild(maskGrouper);
+        filId = createElementID();
+        fil = filtersFactory.createFilter(filId);
+        /// /
+        var feCTr = createNS('feComponentTransfer');
+        feCTr.setAttribute('in', 'SourceGraphic');
+        fil.appendChild(feCTr);
+        var feFunc = createNS('feFuncA');
+        feFunc.setAttribute('type', 'table');
+        feFunc.setAttribute('tableValues', '1.0 0.0');
+        feCTr.appendChild(feFunc);
+        /// /
+        this.globalData.defs.appendChild(fil);
+        var alphaRect = createNS('rect');
+        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');
+        alphaRect.setAttribute('opacity', '0');
+        maskGrouper.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        maskGrouper.appendChild(alphaRect);
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        maskGrouper.appendChild(useElement);
+        if (!featureSupport.maskType) {
+          maskGroup.setAttribute('mask-type', 'luminance');
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          maskGrouper.appendChild(alphaRect);
+          gg.appendChild(this.layerElement);
+          maskGrouper.appendChild(gg);
+        }
+        this.globalData.defs.appendChild(maskGroup);
+      }
+      this.matteMasks[matteType] = id;
+    }
+    return this.matteMasks[matteType];
+  },
+  setMatte: function (id) {
+    if (!this.matteElement) {
+      return;
+    }
+    this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+  },
+};
+
+/**
+ * @file
+ * Handles AE's layer parenting property.
+ *
+ */
+
+function HierarchyElement() {}
+
+HierarchyElement.prototype = {
+  /**
+     * @function
+     * Initializes hierarchy properties
+     *
+     */
+  initHierarchy: function () {
+    // element's parent list
+    this.hierarchy = [];
+    // if element is parent of another layer _isParent will be true
+    this._isParent = false;
+    this.checkParenting();
+  },
+  /**
+     * @function
+     * Sets layer's hierarchy.
+     * @param {array} hierarch
+     * layer's parent list
+     *
+     */
+  setHierarchy: function (hierarchy) {
+    this.hierarchy = hierarchy;
+  },
+  /**
+     * @function
+     * Sets layer as parent.
+     *
+     */
+  setAsParent: function () {
+    this._isParent = true;
+  },
+  /**
+     * @function
+     * Searches layer's parenting chain
+     *
+     */
+  checkParenting: function () {
+    if (this.data.parent !== undefined) {
+      this.comp.buildElementParenting(this, this.data.parent, []);
+    }
+  },
+};
+
+function RenderableDOMElement() {}
+
+(function () {
+  var _prototype = {
+    initElement: function (data, globalData, comp) {
+      this.initFrame();
+      this.initBaseData(data, globalData, comp);
+      this.initTransform(data, globalData, comp);
+      this.initHierarchy();
+      this.initRenderable();
+      this.initRendererElement();
+      this.createContainerElements();
+      this.createRenderableComponents();
+      this.createContent();
+      this.hide();
+    },
+    hide: function () {
+      // console.log('HIDE', this);
+      if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+        var elem = this.baseElement || this.layerElement;
+        elem.style.display = 'none';
+        this.hidden = true;
+      }
+    },
+    show: function () {
+      // console.log('SHOW', this);
+      if (this.isInRange && !this.isTransparent) {
+        if (!this.data.hd) {
+          var elem = this.baseElement || this.layerElement;
+          elem.style.display = 'block';
+        }
+        this.hidden = false;
+        this._isFirstFrame = true;
+      }
+    },
+    renderFrame: function () {
+      // If it is exported as hidden (data.hd === true) no need to render
+      // If it is not visible no need to render
+      if (this.data.hd || this.hidden) {
+        return;
+      }
+      this.renderTransform();
+      this.renderRenderable();
+      this.renderLocalTransform();
+      this.renderElement();
+      this.renderInnerContent();
+      if (this._isFirstFrame) {
+        this._isFirstFrame = false;
+      }
+    },
+    renderInnerContent: function () {},
+    prepareFrame: function (num) {
+      this._mdf = false;
+      this.prepareRenderableFrame(num);
+      this.prepareProperties(num, this.isInRange);
+      this.checkTransparency();
+    },
+    destroy: function () {
+      this.innerElem = null;
+      this.destroyBaseElement();
+    },
+  };
+  extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement);
+}());
+
+function IImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  if (this.assetData && this.assetData.sid) {
+    this.assetData = globalData.slotManager.getProp(this.assetData);
+  }
+  this.initElement(data, globalData, comp);
+  this.sourceRect = {
+    top: 0, left: 0, width: this.assetData.w, height: this.assetData.h,
+  };
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
+
+IImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+
+  this.innerElem = createNS('image');
+  this.innerElem.setAttribute('width', this.assetData.w + 'px');
+  this.innerElem.setAttribute('height', this.assetData.h + 'px');
+  this.innerElem.setAttribute('preserveAspectRatio', this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio);
+  this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+
+  this.layerElement.appendChild(this.innerElem);
+};
+
+IImageElement.prototype.sourceRectAtTime = function () {
+  return this.sourceRect;
+};
+
+function ProcessedElement(element, position) {
+  this.elem = element;
+  this.pos = position;
+}
+
+function IShapeElement() {
+}
+
+IShapeElement.prototype = {
+  addShapeToModifiers: function (data) {
+    var i;
+    var len = this.shapeModifiers.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapeModifiers[i].addShape(data);
+    }
+  },
+  isShapeInAnimatedModifiers: function (data) {
+    var i = 0;
+    var len = this.shapeModifiers.length;
+    while (i < len) {
+      if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
+        return true;
+      }
+    }
+    return false;
+  },
+  renderModifiers: function () {
+    if (!this.shapeModifiers.length) {
+      return;
+    }
+    var i;
+    var len = this.shapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].sh.reset();
+    }
+
+    len = this.shapeModifiers.length;
+    var shouldBreakProcess;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+      // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+      // TODO: find a better solution for this
+      if (shouldBreakProcess) {
+        break;
+      }
+    }
+  },
+
+  searchProcessedElement: function (elem) {
+    var elements = this.processedElements;
+    var i = 0;
+    var len = elements.length;
+    while (i < len) {
+      if (elements[i].elem === elem) {
+        return elements[i].pos;
+      }
+      i += 1;
+    }
+    return 0;
+  },
+  addProcessedElement: function (elem, pos) {
+    var elements = this.processedElements;
+    var i = elements.length;
+    while (i) {
+      i -= 1;
+      if (elements[i].elem === elem) {
+        elements[i].pos = pos;
+        return;
+      }
+    }
+    elements.push(new ProcessedElement(elem, pos));
+  },
+  prepareFrame: function (num) {
+    this.prepareRenderableFrame(num);
+    this.prepareProperties(num, this.isInRange);
+  },
+};
+
+const lineCapEnum = {
+  1: 'butt',
+  2: 'round',
+  3: 'square',
+};
+
+const lineJoinEnum = {
+  1: 'miter',
+  2: 'round',
+  3: 'bevel',
+};
+
+function SVGShapeData(transformers, level, shape) {
+  this.caches = [];
+  this.styles = [];
+  this.transformers = transformers;
+  this.lStr = '';
+  this.sh = shape;
+  this.lvl = level;
+  // TODO find if there are some cases where _isAnimated can be false.
+  // For now, since shapes add up with other shapes. They have to be calculated every time.
+  // One way of finding out is checking if all styles associated to this shape depend only of this shape
+  this._isAnimated = !!shape.k;
+  // TODO: commenting this for now since all shapes are animated
+  var i = 0;
+  var len = transformers.length;
+  while (i < len) {
+    if (transformers[i].mProps.dynamicProperties.length) {
+      this._isAnimated = true;
+      break;
+    }
+    i += 1;
+  }
+}
+
+SVGShapeData.prototype.setAsAnimated = function () {
+  this._isAnimated = true;
+};
+
+function SVGStyleData(data, level) {
+  this.data = data;
+  this.type = data.ty;
+  this.d = '';
+  this.lvl = level;
+  this._mdf = false;
+  this.closed = data.hd === true;
+  this.pElem = createNS('path');
+  this.msElem = null;
+}
+
+SVGStyleData.prototype.reset = function () {
+  this.d = '';
+  this._mdf = false;
+};
+
+function DashProperty(elem, data, renderer, container) {
+  this.elem = elem;
+  this.frameId = -1;
+  this.dataProps = createSizedArray(data.length);
+  this.renderer = renderer;
+  this.k = false;
+  this.dashStr = '';
+  this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0);
+  this.dashoffset = createTypedArray('float32', 1);
+  this.initDynamicPropertyContainer(container);
+  var i;
+  var len = data.length || 0;
+  var prop;
+  for (i = 0; i < len; i += 1) {
+    prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
+    this.k = prop.k || this.k;
+    this.dataProps[i] = { n: data[i].n, p: prop };
+  }
+  if (!this.k) {
+    this.getValue(true);
+  }
+  this._isAnimated = this.k;
+}
+
+DashProperty.prototype.getValue = function (forceRender) {
+  if (this.elem.globalData.frameId === this.frameId && !forceRender) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+  this._mdf = this._mdf || forceRender;
+  if (this._mdf) {
+    var i = 0;
+    var len = this.dataProps.length;
+    if (this.renderer === 'svg') {
+      this.dashStr = '';
+    }
+    for (i = 0; i < len; i += 1) {
+      if (this.dataProps[i].n !== 'o') {
+        if (this.renderer === 'svg') {
+          this.dashStr += ' ' + this.dataProps[i].p.v;
+        } else {
+          this.dashArray[i] = this.dataProps[i].p.v;
+        }
+      } else {
+        this.dashoffset[0] = this.dataProps[i].p.v;
+      }
+    }
+  }
+};
+extendPrototype([DynamicPropertyContainer], DashProperty);
+
+function SVGStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
+
+function SVGFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
+
+function SVGNoStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
+
+function GradientProperty(elem, data, container) {
+  this.data = data;
+  this.c = createTypedArray('uint8c', data.p * 4);
+  var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p * 4) : data.k.k.length - data.p * 4;
+  this.o = createTypedArray('float32', cLength);
+  this._cmdf = false;
+  this._omdf = false;
+  this._collapsable = this.checkCollapsable();
+  this._hasOpacity = cLength;
+  this.initDynamicPropertyContainer(container);
+  this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this);
+  this.k = this.prop.k;
+  this.getValue(true);
+}
+
+GradientProperty.prototype.comparePoints = function (values, points) {
+  var i = 0;
+  var len = this.o.length / 2;
+  var diff;
+  while (i < len) {
+    diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
+    if (diff > 0.01) {
+      return false;
+    }
+    i += 1;
+  }
+  return true;
+};
+
+GradientProperty.prototype.checkCollapsable = function () {
+  if (this.o.length / 2 !== this.c.length / 4) {
+    return false;
+  }
+  if (this.data.k.k[0].s) {
+    var i = 0;
+    var len = this.data.k.k.length;
+    while (i < len) {
+      if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
+        return false;
+      }
+      i += 1;
+    }
+  } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
+    return false;
+  }
+  return true;
+};
+
+GradientProperty.prototype.getValue = function (forceRender) {
+  this.prop.getValue();
+  this._mdf = false;
+  this._cmdf = false;
+  this._omdf = false;
+  if (this.prop._mdf || forceRender) {
+    var i;
+    var len = this.data.p * 4;
+    var mult;
+    var val;
+    for (i = 0; i < len; i += 1) {
+      mult = i % 4 === 0 ? 100 : 255;
+      val = Math.round(this.prop.v[i] * mult);
+      if (this.c[i] !== val) {
+        this.c[i] = val;
+        this._cmdf = !forceRender;
+      }
+    }
+    if (this.o.length) {
+      len = this.prop.v.length;
+      for (i = this.data.p * 4; i < len; i += 1) {
+        mult = i % 2 === 0 ? 100 : 1;
+        val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
+        if (this.o[i - this.data.p * 4] !== val) {
+          this.o[i - this.data.p * 4] = val;
+          this._omdf = !forceRender;
+        }
+      }
+    }
+    this._mdf = !forceRender;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], GradientProperty);
+
+function SVGGradientFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.initGradientData(elem, data, styleOb);
+}
+
+SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 1, null, this);
+  this.h = PropertyFactory.getProp(elem, data.h || { k: 0 }, 0, 0.01, this);
+  this.a = PropertyFactory.getProp(elem, data.a || { k: 0 }, 0, degToRads, this);
+  this.g = new GradientProperty(elem, data.g, this);
+  this.style = styleOb;
+  this.stops = [];
+  this.setGradientData(styleOb.pElem, data);
+  this.setGradientOpacity(data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+};
+
+SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
+  var gradientId = createElementID();
+  var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+  gfill.setAttribute('id', gradientId);
+  gfill.setAttribute('spreadMethod', 'pad');
+  gfill.setAttribute('gradientUnits', 'userSpaceOnUse');
+  var stops = [];
+  var stop;
+  var j;
+  var jLen;
+  jLen = data.g.p * 4;
+  for (j = 0; j < jLen; j += 4) {
+    stop = createNS('stop');
+    gfill.appendChild(stop);
+    stops.push(stop);
+  }
+  pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
+  this.gf = gfill;
+  this.cst = stops;
+};
+
+SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
+  if (this.g._hasOpacity && !this.g._collapsable) {
+    var stop;
+    var j;
+    var jLen;
+    var mask = createNS('mask');
+    var maskElement = createNS('path');
+    mask.appendChild(maskElement);
+    var opacityId = createElementID();
+    var maskId = createElementID();
+    mask.setAttribute('id', maskId);
+    var opFill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+    opFill.setAttribute('id', opacityId);
+    opFill.setAttribute('spreadMethod', 'pad');
+    opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
+    jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
+    var stops = this.stops;
+    for (j = data.g.p * 4; j < jLen; j += 2) {
+      stop = createNS('stop');
+      stop.setAttribute('stop-color', 'rgb(255,255,255)');
+      opFill.appendChild(stop);
+      stops.push(stop);
+    }
+    maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
+    this.maskId = maskId;
+    styleOb.msElem = maskElement;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
+
+function SVGGradientStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.initGradientData(elem, data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
+
+function ShapeGroupData() {
+  this.it = [];
+  this.prevViewData = [];
+  this.gr = createNS('g');
+}
+
+function SVGTransformData(mProps, op, container) {
+  this.transform = {
+    mProps: mProps,
+    op: op,
+    container: container,
+  };
+  this.elements = [];
+  this._isAnimated = this.transform.mProps.dynamicProperties.length || this.transform.op.effectsSequence.length;
+}
+
+const buildShapeString = function (pathNodes, length, closed, mat) {
+  if (length === 0) {
+    return '';
+  }
+  var _o = pathNodes.o;
+  var _i = pathNodes.i;
+  var _v = pathNodes.v;
+  var i;
+  var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+  for (i = 1; i < length; i += 1) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
+  }
+  if (closed && length) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+    shapeString += 'z';
+  }
+  return shapeString;
+};
+
+const SVGElementsRenderer = (function () {
+  var _identityMatrix = new Matrix();
+  var _matrixHelper = new Matrix();
+
+  var ob = {
+    createRenderFunction: createRenderFunction,
+  };
+
+  function createRenderFunction(data) {
+    switch (data.ty) {
+      case 'fl':
+        return renderFill;
+      case 'gf':
+        return renderGradient;
+      case 'gs':
+        return renderGradientStroke;
+      case 'st':
+        return renderStroke;
+      case 'sh':
+      case 'el':
+      case 'rc':
+      case 'sr':
+        return renderPath;
+      case 'tr':
+        return renderContentTransform;
+      case 'no':
+        return renderNoop;
+      default:
+        return null;
+    }
+  }
+
+  function renderContentTransform(styleData, itemData, isFirstFrame) {
+    if (isFirstFrame || itemData.transform.op._mdf) {
+      itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
+    }
+    if (isFirstFrame || itemData.transform.mProps._mdf) {
+      itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
+    }
+  }
+
+  function renderNoop() {
+
+  }
+
+  function renderPath(styleData, itemData, isFirstFrame) {
+    var j;
+    var jLen;
+    var pathStringTransformed;
+    var redraw;
+    var pathNodes;
+    var l;
+    var lLen = itemData.styles.length;
+    var lvl = itemData.lvl;
+    var paths;
+    var mat;
+    var iterations;
+    var k;
+    for (l = 0; l < lLen; l += 1) {
+      redraw = itemData.sh._mdf || isFirstFrame;
+      if (itemData.styles[l].lvl < lvl) {
+        mat = _matrixHelper.reset();
+        iterations = lvl - itemData.styles[l].lvl;
+        k = itemData.transformers.length - 1;
+        while (!redraw && iterations > 0) {
+          redraw = itemData.transformers[k].mProps._mdf || redraw;
+          iterations -= 1;
+          k -= 1;
+        }
+        if (redraw) {
+          iterations = lvl - itemData.styles[l].lvl;
+          k = itemData.transformers.length - 1;
+          while (iterations > 0) {
+            mat.multiply(itemData.transformers[k].mProps.v);
+            iterations -= 1;
+            k -= 1;
+          }
+        }
+      } else {
+        mat = _identityMatrix;
+      }
+      paths = itemData.sh.paths;
+      jLen = paths._length;
+      if (redraw) {
+        pathStringTransformed = '';
+        for (j = 0; j < jLen; j += 1) {
+          pathNodes = paths.shapes[j];
+          if (pathNodes && pathNodes._length) {
+            pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
+          }
+        }
+        itemData.caches[l] = pathStringTransformed;
+      } else {
+        pathStringTransformed = itemData.caches[l];
+      }
+      itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
+      itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
+    }
+  }
+
+  function renderFill(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+
+    if (itemData.c._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
+    }
+  }
+
+  function renderGradientStroke(styleData, itemData, isFirstFrame) {
+    renderGradient(styleData, itemData, isFirstFrame);
+    renderStroke(styleData, itemData, isFirstFrame);
+  }
+
+  function renderGradient(styleData, itemData, isFirstFrame) {
+    var gfill = itemData.gf;
+    var hasOpacity = itemData.g._hasOpacity;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+
+    if (itemData.o._mdf || isFirstFrame) {
+      var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
+      itemData.style.pElem.setAttribute(attr, itemData.o.v);
+    }
+    if (itemData.s._mdf || isFirstFrame) {
+      var attr1 = styleData.t === 1 ? 'x1' : 'cx';
+      var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
+      gfill.setAttribute(attr1, pt1[0]);
+      gfill.setAttribute(attr2, pt1[1]);
+      if (hasOpacity && !itemData.g._collapsable) {
+        itemData.of.setAttribute(attr1, pt1[0]);
+        itemData.of.setAttribute(attr2, pt1[1]);
+      }
+    }
+    var stops;
+    var i;
+    var len;
+    var stop;
+    if (itemData.g._cmdf || isFirstFrame) {
+      stops = itemData.cst;
+      var cValues = itemData.g.c;
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        stop.setAttribute('offset', cValues[i * 4] + '%');
+        stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
+      }
+    }
+    if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
+      var oValues = itemData.g.o;
+      if (itemData.g._collapsable) {
+        stops = itemData.cst;
+      } else {
+        stops = itemData.ost;
+      }
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        if (!itemData.g._collapsable) {
+          stop.setAttribute('offset', oValues[i * 2] + '%');
+        }
+        stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
+      }
+    }
+    if (styleData.t === 1) {
+      if (itemData.e._mdf || isFirstFrame) {
+        gfill.setAttribute('x2', pt2[0]);
+        gfill.setAttribute('y2', pt2[1]);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('x2', pt2[0]);
+          itemData.of.setAttribute('y2', pt2[1]);
+        }
+      }
+    } else {
+      var rad;
+      if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
+        rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        gfill.setAttribute('r', rad);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('r', rad);
+        }
+      }
+      if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (!rad) {
+          rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        }
+        var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+        var percent = itemData.h.v;
+        if (percent >= 1) {
+          percent = 0.99;
+        } else if (percent <= -1) {
+          percent = -0.99;
+        }
+        var dist = rad * percent;
+        var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+        var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+        gfill.setAttribute('fx', x);
+        gfill.setAttribute('fy', y);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('fx', x);
+          itemData.of.setAttribute('fy', y);
+        }
+      }
+      // gfill.setAttribute('fy','200');
+    }
+  }
+
+  function renderStroke(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+    var d = itemData.d;
+    if (d && (d._mdf || isFirstFrame) && d.dashStr) {
+      styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
+      styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
+    }
+    if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
+      styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
+    }
+    if (itemData.w._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
+      if (styleElem.msElem) {
+        styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
+      }
+    }
+  }
+
+  return ob;
+}());
+
+function SVGShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
+
+SVGShapeElement.prototype.initSecondaryElement = function () {
+};
+
+SVGShapeElement.prototype.identityMatrix = new Matrix();
+
+SVGShapeElement.prototype.buildExpressionInterface = function () {};
+
+SVGShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+};
+
+/*
+This method searches for multiple shapes that affect a single element and one of them is animated
+*/
+SVGShapeElement.prototype.filterUniqueShapes = function () {
+  var i;
+  var len = this.shapes.length;
+  var shape;
+  var j;
+  var jLen = this.stylesList.length;
+  var style;
+  var tempShapes = [];
+  var areAnimated = false;
+  for (j = 0; j < jLen; j += 1) {
+    style = this.stylesList[j];
+    areAnimated = false;
+    tempShapes.length = 0;
+    for (i = 0; i < len; i += 1) {
+      shape = this.shapes[i];
+      if (shape.styles.indexOf(style) !== -1) {
+        tempShapes.push(shape);
+        areAnimated = shape._isAnimated || areAnimated;
+      }
+    }
+    if (tempShapes.length > 1 && areAnimated) {
+      this.setShapesAsAnimated(tempShapes);
+    }
+  }
+};
+
+SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
+  var i;
+  var len = shapes.length;
+  for (i = 0; i < len; i += 1) {
+    shapes[i].setAsAnimated();
+  }
+};
+
+SVGShapeElement.prototype.createStyleElement = function (data, level) {
+  // TODO: prevent drawing of hidden styles
+  var elementData;
+  var styleOb = new SVGStyleData(data, level);
+
+  var pathElement = styleOb.pElem;
+  if (data.ty === 'st') {
+    elementData = new SVGStrokeStyleData(this, data, styleOb);
+  } else if (data.ty === 'fl') {
+    elementData = new SVGFillStyleData(this, data, styleOb);
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
+    elementData = new GradientConstructor(this, data, styleOb);
+    this.globalData.defs.appendChild(elementData.gf);
+    if (elementData.maskId) {
+      this.globalData.defs.appendChild(elementData.ms);
+      this.globalData.defs.appendChild(elementData.of);
+      pathElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + elementData.maskId + ')');
+    }
+  } else if (data.ty === 'no') {
+    elementData = new SVGNoStyleData(this, data, styleOb);
+  }
+
+  if (data.ty === 'st' || data.ty === 'gs') {
+    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);
+    }
+  }
+
+  if (data.r === 2) {
+    pathElement.setAttribute('fill-rule', 'evenodd');
+  }
+
+  if (data.ln) {
+    pathElement.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    pathElement.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  this.stylesList.push(styleOb);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createGroupElement = function (data) {
+  var elementData = new ShapeGroupData();
+  if (data.ln) {
+    elementData.gr.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    elementData.gr.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  return elementData;
+};
+
+SVGShapeElement.prototype.createTransformElement = function (data, container) {
+  var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
+  var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
+  var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
+  var i = 0;
+  var len = this.animatedContents.length;
+  while (i < len) {
+    if (this.animatedContents[i].element === element) {
+      return;
+    }
+    i += 1;
+  }
+  this.animatedContents.push({
+    fn: SVGElementsRenderer.createRenderFunction(data),
+    element: element,
+    data: data,
+  });
+};
+
+SVGShapeElement.prototype.setElementStyles = function (elementData) {
+  var arr = elementData.styles;
+  var j;
+  var jLen = this.stylesList.length;
+  for (j = 0; j < jLen; j += 1) {
+    if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
+      arr.push(this.stylesList[j]);
+    }
+  }
+};
+
+SVGShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+};
+
+SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
+  var ownTransformers = [].concat(transformers);
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var currentTransform;
+  var modifier;
+  var processedPos;
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._render = render;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], level);
+      } else {
+        itemsData[i].style.closed = arr[i].hd;
+      }
+      if (arr[i]._render) {
+        if (itemsData[i].style.pElem.parentNode !== container) {
+          container.appendChild(itemsData[i].style.pElem);
+        }
+      }
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
+      if (arr[i]._render) {
+        if (itemsData[i].gr.parentNode !== container) {
+          container.appendChild(itemsData[i].gr);
+        }
+      }
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        itemsData[i] = this.createTransformElement(arr[i], container);
+      }
+      currentTransform = itemsData[i].transform;
+      ownTransformers.push(currentTransform);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
+      }
+      this.setElementStyles(itemsData[i]);
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        render = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  len = ownStyles.length;
+  for (i = 0; i < len; i += 1) {
+    ownStyles[i].closed = true;
+  }
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+SVGShapeElement.prototype.renderInnerContent = function () {
+  this.renderModifiers();
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    this.stylesList[i].reset();
+  }
+  this.renderShape();
+  for (i = 0; i < len; i += 1) {
+    if (this.stylesList[i]._mdf || this._isFirstFrame) {
+      if (this.stylesList[i].msElem) {
+        this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+        // Adding M0 0 fixes same mask bug on all browsers
+        this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
+      }
+      this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
+    }
+  }
+};
+
+SVGShapeElement.prototype.renderShape = function () {
+  var i;
+  var len = this.animatedContents.length;
+  var animatedContent;
+  for (i = 0; i < len; i += 1) {
+    animatedContent = this.animatedContents[i];
+    if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
+      animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
+    }
+  }
+};
+
+SVGShapeElement.prototype.destroy = function () {
+  this.destroyBaseElement();
+  this.shapesData = null;
+  this.itemsData = null;
+};
+
+function LetterProps(o, sw, sc, fc, m, p) {
+  this.o = o;
+  this.sw = sw;
+  this.sc = sc;
+  this.fc = fc;
+  this.m = m;
+  this.p = p;
+  this._mdf = {
+    o: true,
+    sw: !!sw,
+    sc: !!sc,
+    fc: !!fc,
+    m: true,
+    p: true,
+  };
+}
+
+LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
+  this._mdf.o = false;
+  this._mdf.sw = false;
+  this._mdf.sc = false;
+  this._mdf.fc = false;
+  this._mdf.m = false;
+  this._mdf.p = false;
+  var updated = false;
+
+  if (this.o !== o) {
+    this.o = o;
+    this._mdf.o = true;
+    updated = true;
+  }
+  if (this.sw !== sw) {
+    this.sw = sw;
+    this._mdf.sw = true;
+    updated = true;
+  }
+  if (this.sc !== sc) {
+    this.sc = sc;
+    this._mdf.sc = true;
+    updated = true;
+  }
+  if (this.fc !== fc) {
+    this.fc = fc;
+    this._mdf.fc = true;
+    updated = true;
+  }
+  if (this.m !== m) {
+    this.m = m;
+    this._mdf.m = true;
+    updated = true;
+  }
+  if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
+    this.p = p;
+    this._mdf.p = true;
+    updated = true;
+  }
+  return updated;
+};
+
+function TextProperty(elem, data) {
+  this._frameId = initialDefaultFrame;
+  this.pv = '';
+  this.v = '';
+  this.kf = false;
+  this._isFirstFrame = true;
+  this._mdf = false;
+  if (data.d && data.d.sid) {
+    data.d = elem.globalData.slotManager.getProp(data.d);
+  }
+  this.data = data;
+  this.elem = elem;
+  this.comp = this.elem.comp;
+  this.keysIndex = 0;
+  this.canResize = false;
+  this.minimumFontSize = 1;
+  this.effectsSequence = [];
+  this.currentData = {
+    ascent: 0,
+    boxWidth: this.defaultBoxWidth,
+    f: '',
+    fStyle: '',
+    fWeight: '',
+    fc: '',
+    j: '',
+    justifyOffset: '',
+    l: [],
+    lh: 0,
+    lineWidths: [],
+    ls: '',
+    of: '',
+    s: '',
+    sc: '',
+    sw: 0,
+    t: 0,
+    tr: 0,
+    sz: 0,
+    ps: null,
+    fillColorAnim: false,
+    strokeColorAnim: false,
+    strokeWidthAnim: false,
+    yOffset: 0,
+    finalSize: 0,
+    finalText: [],
+    finalLineHeight: 0,
+    __complete: false,
+
+  };
+  this.copyData(this.currentData, this.data.d.k[0].s);
+
+  if (!this.searchProperty()) {
+    this.completeTextData(this.currentData);
+  }
+}
+
+TextProperty.prototype.defaultBoxWidth = [0, 0];
+
+TextProperty.prototype.copyData = function (obj, data) {
+  for (var s in data) {
+    if (Object.prototype.hasOwnProperty.call(data, s)) {
+      obj[s] = data[s];
+    }
+  }
+  return obj;
+};
+
+TextProperty.prototype.setCurrentData = function (data) {
+  if (!data.__complete) {
+    this.completeTextData(data);
+  }
+  this.currentData = data;
+  this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
+  this._mdf = true;
+};
+
+TextProperty.prototype.searchProperty = function () {
+  return this.searchKeyframes();
+};
+
+TextProperty.prototype.searchKeyframes = function () {
+  this.kf = this.data.d.k.length > 1;
+  if (this.kf) {
+    this.addEffect(this.getKeyframeValue.bind(this));
+  }
+  return this.kf;
+};
+
+TextProperty.prototype.addEffect = function (effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.getValue = function (_finalValue) {
+  if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
+    return;
+  }
+  this.currentData.t = this.data.d.k[this.keysIndex].s.t;
+  var currentValue = this.currentData;
+  var currentIndex = this.keysIndex;
+  if (this.lock) {
+    this.setCurrentData(this.currentData);
+    return;
+  }
+  this.lock = true;
+  this._mdf = false;
+  var i; var
+    len = this.effectsSequence.length;
+  var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
+  for (i = 0; i < len; i += 1) {
+    // Checking if index changed to prevent creating a new object every time the expression updates.
+    if (currentIndex !== this.keysIndex) {
+      finalValue = this.effectsSequence[i](finalValue, finalValue.t);
+    } else {
+      finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
+    }
+  }
+  if (currentValue !== finalValue) {
+    this.setCurrentData(finalValue);
+  }
+  this.v = this.currentData;
+  this.pv = this.v;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+};
+
+TextProperty.prototype.getKeyframeValue = function () {
+  var textKeys = this.data.d.k;
+  var frameNum = this.elem.comp.renderedFrame;
+  var i = 0; var
+    len = textKeys.length;
+  while (i <= len - 1) {
+    if (i === len - 1 || textKeys[i + 1].t > frameNum) {
+      break;
+    }
+    i += 1;
+  }
+  if (this.keysIndex !== i) {
+    this.keysIndex = i;
+  }
+  return this.data.d.k[this.keysIndex].s;
+};
+
+TextProperty.prototype.buildFinalText = function (text) {
+  var charactersArray = [];
+  var i = 0;
+  var len = text.length;
+  var charCode;
+  var secondCharCode;
+  var shouldCombine = false;
+  var shouldCombineNext = false;
+  var currentChars = '';
+  while (i < len) {
+    shouldCombine = shouldCombineNext;
+    shouldCombineNext = false;
+    charCode = text.charCodeAt(i);
+    currentChars = text.charAt(i);
+    if (FontManager.isCombinedCharacter(charCode)) {
+      shouldCombine = true;
+      // It's a potential surrogate pair (this is the High surrogate)
+    } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+      if (FontManager.isRegionalFlag(text, i)) {
+        currentChars = text.substr(i, 14);
+      } else {
+        secondCharCode = text.charCodeAt(i + 1);
+        // It's a surrogate pair (this is the Low surrogate)
+        if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
+          if (FontManager.isModifier(charCode, secondCharCode)) {
+            currentChars = text.substr(i, 2);
+            shouldCombine = true;
+          } else if (FontManager.isFlagEmoji(text.substr(i, 4))) {
+            currentChars = text.substr(i, 4);
+          } else {
+            currentChars = text.substr(i, 2);
+          }
+        }
+      }
+    } else if (charCode > 0xDBFF) {
+      secondCharCode = text.charCodeAt(i + 1);
+      if (FontManager.isVariationSelector(charCode)) {
+        shouldCombine = true;
+      }
+    } else if (FontManager.isZeroWidthJoiner(charCode)) {
+      shouldCombine = true;
+      shouldCombineNext = true;
+    }
+    if (shouldCombine) {
+      charactersArray[charactersArray.length - 1] += currentChars;
+      shouldCombine = false;
+    } else {
+      charactersArray.push(currentChars);
+    }
+    i += currentChars.length;
+  }
+  return charactersArray;
+};
+
+TextProperty.prototype.completeTextData = function (documentData) {
+  documentData.__complete = true;
+  var fontManager = this.elem.globalData.fontManager;
+  var data = this.data;
+  var letters = [];
+  var i; var
+    len;
+  var newLineFlag; var index = 0; var
+    val;
+  var anchorGrouping = data.m.g;
+  var currentSize = 0; var currentPos = 0; var currentLine = 0; var
+    lineWidths = [];
+  var lineWidth = 0;
+  var maxLineWidth = 0;
+  var j; var
+    jLen;
+  var fontData = fontManager.getFontByName(documentData.f);
+  var charData; var
+    cLength = 0;
+
+  var fontProps = getFontProperties(fontData);
+  documentData.fWeight = fontProps.weight;
+  documentData.fStyle = fontProps.style;
+  documentData.finalSize = documentData.s;
+  documentData.finalText = this.buildFinalText(documentData.t);
+  len = documentData.finalText.length;
+  documentData.finalLineHeight = documentData.lh;
+  var trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+  var charCode;
+  if (documentData.sz) {
+    var flag = true;
+    var boxWidth = documentData.sz[0];
+    var boxHeight = documentData.sz[1];
+    var currentHeight; var
+      finalText;
+    while (flag) {
+      finalText = this.buildFinalText(documentData.t);
+      currentHeight = 0;
+      lineWidth = 0;
+      len = finalText.length;
+      trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+      var lastSpaceIndex = -1;
+      for (i = 0; i < len; i += 1) {
+        charCode = finalText[i].charCodeAt(0);
+        newLineFlag = false;
+        if (finalText[i] === ' ') {
+          lastSpaceIndex = i;
+        } else if (charCode === 13 || charCode === 3) {
+          lineWidth = 0;
+          newLineFlag = true;
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+        }
+        if (fontManager.chars) {
+          charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
+          cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+        } else {
+          // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
+          cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
+        }
+        if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
+          if (lastSpaceIndex === -1) {
+            len += 1;
+          } else {
+            i = lastSpaceIndex;
+          }
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+          finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+          // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
+          lastSpaceIndex = -1;
+          lineWidth = 0;
+        } else {
+          lineWidth += cLength;
+          lineWidth += trackingOffset;
+        }
+      }
+      currentHeight += (fontData.ascent * documentData.finalSize) / 100;
+      if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
+        documentData.finalSize -= 1;
+        documentData.finalLineHeight = (documentData.finalSize * documentData.lh) / documentData.s;
+      } else {
+        documentData.finalText = finalText;
+        len = documentData.finalText.length;
+        flag = false;
+      }
+    }
+  }
+  lineWidth = -trackingOffset;
+  cLength = 0;
+  var uncollapsedSpaces = 0;
+  var currentChar;
+  for (i = 0; i < len; i += 1) {
+    newLineFlag = false;
+    currentChar = documentData.finalText[i];
+    charCode = currentChar.charCodeAt(0);
+    if (charCode === 13 || charCode === 3) {
+      uncollapsedSpaces = 0;
+      lineWidths.push(lineWidth);
+      maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+      lineWidth = -2 * trackingOffset;
+      val = '';
+      newLineFlag = true;
+      currentLine += 1;
+    } else {
+      val = currentChar;
+    }
+    if (fontManager.chars) {
+      charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
+      cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+    } else {
+      // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
+      // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
+      cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
+    }
+
+    //
+    if (currentChar === ' ') {
+      uncollapsedSpaces += cLength + trackingOffset;
+    } else {
+      lineWidth += cLength + trackingOffset + uncollapsedSpaces;
+      uncollapsedSpaces = 0;
+    }
+    letters.push({
+      l: cLength, an: cLength, add: currentSize, n: newLineFlag, anIndexes: [], val: val, line: currentLine, animatorJustifyOffset: 0,
+    });
+    if (anchorGrouping == 2) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || val === ' ' || i === len - 1) {
+        if (val === '' || val === ' ') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        index += 1;
+        currentSize = 0;
+      }
+    } else if (anchorGrouping == 3) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || i === len - 1) {
+        if (val === '') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        currentSize = 0;
+        index += 1;
+      }
+    } else {
+      letters[index].ind = index;
+      letters[index].extra = 0;
+      index += 1;
+    }
+  }
+  documentData.l = letters;
+  maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+  lineWidths.push(lineWidth);
+  if (documentData.sz) {
+    documentData.boxWidth = documentData.sz[0];
+    documentData.justifyOffset = 0;
+  } else {
+    documentData.boxWidth = maxLineWidth;
+    switch (documentData.j) {
+      case 1:
+        documentData.justifyOffset = -documentData.boxWidth;
+        break;
+      case 2:
+        documentData.justifyOffset = -documentData.boxWidth / 2;
+        break;
+      default:
+        documentData.justifyOffset = 0;
+    }
+  }
+  documentData.lineWidths = lineWidths;
+
+  var animators = data.a; var animatorData; var
+    letterData;
+  jLen = animators.length;
+  var based; var ind; var
+    indexes = [];
+  for (j = 0; j < jLen; j += 1) {
+    animatorData = animators[j];
+    if (animatorData.a.sc) {
+      documentData.strokeColorAnim = true;
+    }
+    if (animatorData.a.sw) {
+      documentData.strokeWidthAnim = true;
+    }
+    if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
+      documentData.fillColorAnim = true;
+    }
+    ind = 0;
+    based = animatorData.s.b;
+    for (i = 0; i < len; i += 1) {
+      letterData = letters[i];
+      letterData.anIndexes[j] = ind;
+      if ((based == 1 && letterData.val !== '') || (based == 2 && letterData.val !== '' && letterData.val !== ' ') || (based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1)) || (based == 4 && (letterData.n || i == len - 1))) { // eslint-disable-line eqeqeq
+        if (animatorData.s.rn === 1) {
+          indexes.push(ind);
+        }
+        ind += 1;
+      }
+    }
+    data.a[j].s.totalChars = ind;
+    var currentInd = -1; var
+      newInd;
+    if (animatorData.s.rn === 1) {
+      for (i = 0; i < len; i += 1) {
+        letterData = letters[i];
+        if (currentInd != letterData.anIndexes[j]) { // eslint-disable-line eqeqeq
+          currentInd = letterData.anIndexes[j];
+          newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
+        }
+        letterData.anIndexes[j] = newInd;
+      }
+    }
+  }
+  documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
+  documentData.ls = documentData.ls || 0;
+  documentData.ascent = (fontData.ascent * documentData.finalSize) / 100;
+};
+
+TextProperty.prototype.updateDocumentData = function (newData, index) {
+  index = index === undefined ? this.keysIndex : index;
+  var dData = this.copyData({}, this.data.d.k[index].s);
+  dData = this.copyData(dData, newData);
+  this.data.d.k[index].s = dData;
+  this.recalculate(index);
+  this.setCurrentData(dData);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.recalculate = function (index) {
+  var dData = this.data.d.k[index].s;
+  dData.__complete = false;
+  this.keysIndex = 0;
+  this._isFirstFrame = true;
+  this.getValue(dData);
+};
+
+TextProperty.prototype.canResizeFont = function (_canResize) {
+  this.canResize = _canResize;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
+  this.minimumFontSize = Math.floor(_fontValue) || 1;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+const TextSelectorProp = (function () {
+  var max = Math.max;
+  var min = Math.min;
+  var floor = Math.floor;
+
+  function TextSelectorPropFactory(elem, data) {
+    this._currentTextLength = -1;
+    this.k = false;
+    this.data = data;
+    this.elem = elem;
+    this.comp = elem.comp;
+    this.finalS = 0;
+    this.finalE = 0;
+    this.initDynamicPropertyContainer(elem);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: 0 }, 0, 0, this);
+    if ('e' in data) {
+      this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
+    } else {
+      this.e = { v: 100 };
+    }
+    this.o = PropertyFactory.getProp(elem, data.o || { k: 0 }, 0, 0, this);
+    this.xe = PropertyFactory.getProp(elem, data.xe || { k: 0 }, 0, 0, this);
+    this.ne = PropertyFactory.getProp(elem, data.ne || { k: 0 }, 0, 0, this);
+    this.sm = PropertyFactory.getProp(elem, data.sm || { k: 100 }, 0, 0, this);
+    this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
+    if (!this.dynamicProperties.length) {
+      this.getValue();
+    }
+  }
+
+  TextSelectorPropFactory.prototype = {
+    getMult: function (ind) {
+      if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
+        this.getValue();
+      }
+      var x1 = 0;
+      var y1 = 0;
+      var x2 = 1;
+      var y2 = 1;
+      if (this.ne.v > 0) {
+        x1 = this.ne.v / 100.0;
+      } else {
+        y1 = -this.ne.v / 100.0;
+      }
+      if (this.xe.v > 0) {
+        x2 = 1.0 - this.xe.v / 100.0;
+      } else {
+        y2 = 1.0 + this.xe.v / 100.0;
+      }
+      var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
+
+      var mult = 0;
+      var s = this.finalS;
+      var e = this.finalE;
+      var type = this.data.sh;
+      if (type === 2) {
+        if (e === s) {
+          mult = ind >= e ? 1 : 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+        mult = easer(mult);
+      } else if (type === 3) {
+        if (e === s) {
+          mult = ind >= e ? 0 : 1;
+        } else {
+          mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+
+        mult = easer(mult);
+      } else if (type === 4) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+          if (mult < 0.5) {
+            mult *= 2;
+          } else {
+            mult = 1 - 2 * (mult - 0.5);
+          }
+        }
+        mult = easer(mult);
+      } else if (type === 5) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          var tot = e - s;
+          /* ind += 0.5;
+                    mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          var x = -tot / 2 + ind;
+          var a = tot / 2;
+          mult = Math.sqrt(1 - (x * x) / (a * a));
+        }
+        mult = easer(mult);
+      } else if (type === 6) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; // eslint-disable-line
+        }
+        mult = easer(mult);
+      } else {
+        if (ind >= floor(s)) {
+          if (ind - s < 0) {
+            mult = max(0, min(min(e, 1) - (s - ind), 1));
+          } else {
+            mult = max(0, min(e - ind, 1));
+          }
+        }
+        mult = easer(mult);
+      }
+      // Smoothness implementation.
+      // The smoothness represents a reduced range of the original [0; 1] range.
+      // if smoothness is 25%, the new range will be [0.375; 0.625]
+      // Steps are:
+      // - find the lower value of the new range (threshold)
+      // - if multiplier is smaller than that value, floor it to 0
+      // - if it is larger,
+      //     - subtract the threshold
+      //     - divide it by the smoothness (this will return the range to [0; 1])
+      // Note: If it doesn't work on some scenarios, consider applying it before the easer.
+      if (this.sm.v !== 100) {
+        var smoothness = this.sm.v * 0.01;
+        if (smoothness === 0) {
+          smoothness = 0.00000001;
+        }
+        var threshold = 0.5 - smoothness * 0.5;
+        if (mult < threshold) {
+          mult = 0;
+        } else {
+          mult = (mult - threshold) / smoothness;
+          if (mult > 1) {
+            mult = 1;
+          }
+        }
+      }
+      return mult * this.a.v;
+    },
+    getValue: function (newCharsFlag) {
+      this.iterateDynamicProperties();
+      this._mdf = newCharsFlag || this._mdf;
+      this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
+      if (newCharsFlag && this.data.r === 2) {
+        this.e.v = this._currentTextLength;
+      }
+      var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
+      var o = this.o.v / divisor;
+      var s = this.s.v / divisor + o;
+      var e = (this.e.v / divisor) + o;
+      if (s > e) {
+        var _s = s;
+        s = e;
+        e = _s;
+      }
+      this.finalS = s;
+      this.finalE = e;
+    },
+  };
+  extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
+
+  function getTextSelectorProp(elem, data, arr) {
+    return new TextSelectorPropFactory(elem, data, arr);
+  }
+
+  return {
+    getTextSelectorProp: getTextSelectorProp,
+  };
+}());
+
+function TextAnimatorDataProperty(elem, animatorProps, container) {
+  var defaultData = { propType: false };
+  var getProp = PropertyFactory.getProp;
+  var textAnimatorAnimatables = animatorProps.a;
+  this.a = {
+    r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData,
+    rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData,
+    ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData,
+    sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData,
+    sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData,
+    s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData,
+    a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData,
+    o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData,
+    p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData,
+    sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData,
+    sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData,
+    fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData,
+    fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData,
+    fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData,
+    fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData,
+    t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData,
+  };
+
+  this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container);
+  this.s.t = animatorProps.s.t;
+}
+
+function TextAnimatorProperty(textData, renderType, elem) {
+  this._isFirstFrame = true;
+  this._hasMaskedPath = false;
+  this._frameId = -1;
+  this._textData = textData;
+  this._renderType = renderType;
+  this._elem = elem;
+  this._animatorsData = createSizedArray(this._textData.a.length);
+  this._pathData = {};
+  this._moreOptions = {
+    alignment: {},
+  };
+  this.renderedLetters = [];
+  this.lettersChangedFlag = false;
+  this.initDynamicPropertyContainer(elem);
+}
+
+TextAnimatorProperty.prototype.searchProperties = function () {
+  var i;
+  var len = this._textData.a.length;
+  var animatorProps;
+  var getProp = PropertyFactory.getProp;
+  for (i = 0; i < len; i += 1) {
+    animatorProps = this._textData.a[i];
+    this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
+  }
+  if (this._textData.p && 'm' in this._textData.p) {
+    this._pathData = {
+      a: getProp(this._elem, this._textData.p.a, 0, 0, this),
+      f: getProp(this._elem, this._textData.p.f, 0, 0, this),
+      l: getProp(this._elem, this._textData.p.l, 0, 0, this),
+      r: getProp(this._elem, this._textData.p.r, 0, 0, this),
+      p: getProp(this._elem, this._textData.p.p, 0, 0, this),
+      m: this._elem.maskManager.getMaskProperty(this._textData.p.m),
+    };
+    this._hasMaskedPath = true;
+  } else {
+    this._hasMaskedPath = false;
+  }
+  this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
+};
+
+TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
+  this.lettersChangedFlag = lettersChangedFlag;
+  if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
+    return;
+  }
+  this._isFirstFrame = false;
+  var alignment = this._moreOptions.alignment.v;
+  var animators = this._animatorsData;
+  var textData = this._textData;
+  var matrixHelper = this.mHelper;
+  var renderType = this._renderType;
+  var renderedLettersCount = this.renderedLetters.length;
+  var xPos;
+  var yPos;
+  var i;
+  var len;
+  var letters = documentData.l;
+  var pathInfo;
+  var currentLength;
+  var currentPoint;
+  var segmentLength;
+  var flag;
+  var pointInd;
+  var segmentInd;
+  var prevPoint;
+  var points;
+  var segments;
+  var partialLength;
+  var totalLength;
+  var perc;
+  var tanAngle;
+  var mask;
+  if (this._hasMaskedPath) {
+    mask = this._pathData.m;
+    if (!this._pathData.n || this._pathData._mdf) {
+      var paths = mask.v;
+      if (this._pathData.r.v) {
+        paths = paths.reverse();
+      }
+      // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
+      pathInfo = {
+        tLength: 0,
+        segments: [],
+      };
+      len = paths._length - 1;
+      var bezierData;
+      totalLength = 0;
+      for (i = 0; i < len; i += 1) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[i + 1],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      i = len;
+      if (mask.v.c) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[0],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      this._pathData.pi = pathInfo;
+    }
+    pathInfo = this._pathData.pi;
+
+    currentLength = this._pathData.f.v;
+    segmentInd = 0;
+    pointInd = 1;
+    segmentLength = 0;
+    flag = true;
+    segments = pathInfo.segments;
+    if (currentLength < 0 && mask.v.c) {
+      if (pathInfo.tLength < Math.abs(currentLength)) {
+        currentLength = -Math.abs(currentLength) % pathInfo.tLength;
+      }
+      segmentInd = segments.length - 1;
+      points = segments[segmentInd].points;
+      pointInd = points.length - 1;
+      while (currentLength < 0) {
+        currentLength += points[pointInd].partialLength;
+        pointInd -= 1;
+        if (pointInd < 0) {
+          segmentInd -= 1;
+          points = segments[segmentInd].points;
+          pointInd = points.length - 1;
+        }
+      }
+    }
+    points = segments[segmentInd].points;
+    prevPoint = points[pointInd - 1];
+    currentPoint = points[pointInd];
+    partialLength = currentPoint.partialLength;
+  }
+
+  len = letters.length;
+  xPos = 0;
+  yPos = 0;
+  var yOff = documentData.finalSize * 1.2 * 0.714;
+  var firstLine = true;
+  var animatorProps;
+  var animatorSelector;
+  var j;
+  var jLen;
+  var letterValue;
+
+  jLen = animators.length;
+
+  var mult;
+  var ind = -1;
+  var offf;
+  var xPathPos;
+  var yPathPos;
+  var initPathPos = currentLength;
+  var initSegmentInd = segmentInd;
+  var initPointInd = pointInd;
+  var currentLine = -1;
+  var elemOpacity;
+  var sc;
+  var sw;
+  var fc;
+  var k;
+  var letterSw;
+  var letterSc;
+  var letterFc;
+  var letterM = '';
+  var letterP = this.defaultPropsArray;
+  var letterO;
+
+  //
+  if (documentData.j === 2 || documentData.j === 1) {
+    var animatorJustifyOffset = 0;
+    var animatorFirstCharOffset = 0;
+    var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
+    var lastIndex = 0;
+    var isNewLine = true;
+
+    for (i = 0; i < len; i += 1) {
+      if (letters[i].n) {
+        if (animatorJustifyOffset) {
+          animatorJustifyOffset += animatorFirstCharOffset;
+        }
+        while (lastIndex < i) {
+          letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+          lastIndex += 1;
+        }
+        animatorJustifyOffset = 0;
+        isNewLine = true;
+      } else {
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.t.propType) {
+            if (isNewLine && documentData.j === 2) {
+              animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
+            }
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
+            } else {
+              animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult;
+            }
+          }
+        }
+        isNewLine = false;
+      }
+    }
+    if (animatorJustifyOffset) {
+      animatorJustifyOffset += animatorFirstCharOffset;
+    }
+    while (lastIndex < i) {
+      letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+      lastIndex += 1;
+    }
+  }
+  //
+
+  for (i = 0; i < len; i += 1) {
+    matrixHelper.reset();
+    elemOpacity = 1;
+    if (letters[i].n) {
+      xPos = 0;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      currentLength = initPathPos;
+      firstLine = false;
+      if (this._hasMaskedPath) {
+        segmentInd = initSegmentInd;
+        pointInd = initPointInd;
+        points = segments[segmentInd].points;
+        prevPoint = points[pointInd - 1];
+        currentPoint = points[pointInd];
+        partialLength = currentPoint.partialLength;
+        segmentLength = 0;
+      }
+      letterM = '';
+      letterFc = '';
+      letterSw = '';
+      letterO = '';
+      letterP = this.defaultPropsArray;
+    } else {
+      if (this._hasMaskedPath) {
+        if (currentLine !== letters[i].line) {
+          switch (documentData.j) {
+            case 1:
+              currentLength += totalLength - documentData.lineWidths[letters[i].line];
+              break;
+            case 2:
+              currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
+              break;
+            default:
+              break;
+          }
+          currentLine = letters[i].line;
+        }
+        if (ind !== letters[i].ind) {
+          if (letters[ind]) {
+            currentLength += letters[ind].extra;
+          }
+          currentLength += letters[i].an / 2;
+          ind = letters[i].ind;
+        }
+        currentLength += (alignment[0] * letters[i].an) * 0.005;
+        var animatorOffset = 0;
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.p.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.p.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.p.v[0] * mult;
+            }
+          }
+          if (animatorProps.a.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.a.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.a.v[0] * mult;
+            }
+          }
+        }
+        flag = true;
+        // Force alignment only works with a single line for now
+        if (this._pathData.a.v) {
+          currentLength = letters[0].an * 0.5 + ((totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind) / (len - 1);
+          currentLength += this._pathData.f.v;
+        }
+        while (flag) {
+          if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
+            perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
+            xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
+            yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
+            matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, -(alignment[1] * yOff) * 0.01);
+            flag = false;
+          } else if (points) {
+            segmentLength += currentPoint.partialLength;
+            pointInd += 1;
+            if (pointInd >= points.length) {
+              pointInd = 0;
+              segmentInd += 1;
+              if (!segments[segmentInd]) {
+                if (mask.v.c) {
+                  pointInd = 0;
+                  segmentInd = 0;
+                  points = segments[segmentInd].points;
+                } else {
+                  segmentLength -= currentPoint.partialLength;
+                  points = null;
+                }
+              } else {
+                points = segments[segmentInd].points;
+              }
+            }
+            if (points) {
+              prevPoint = currentPoint;
+              currentPoint = points[pointInd];
+              partialLength = currentPoint.partialLength;
+            }
+          }
+        }
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+      } else {
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+
+        // Grouping alignment
+        matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, (-alignment[1] * yOff) * 0.01, 0);
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.t.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
+          if (xPos !== 0 || documentData.j !== 0) {
+            if (this._hasMaskedPath) {
+              if (mult.length) {
+                currentLength += animatorProps.t.v * mult[0];
+              } else {
+                currentLength += animatorProps.t.v * mult;
+              }
+            } else if (mult.length) {
+              xPos += animatorProps.t.v * mult[0];
+            } else {
+              xPos += animatorProps.t.v * mult;
+            }
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        sw = documentData.sw || 0;
+      }
+      if (documentData.strokeColorAnim) {
+        if (documentData.sc) {
+          sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
+        } else {
+          sc = [0, 0, 0];
+        }
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.a.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+
+          if (mult.length) {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.s.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (mult.length) {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult[0]), 1 + ((animatorProps.s.v[1] - 1) * mult[1]), 1);
+          } else {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult), 1 + ((animatorProps.s.v[1] - 1) * mult), 1);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        animatorSelector = animators[j].s;
+        mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+        if (animatorProps.sk.propType) {
+          if (mult.length) {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
+          } else {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
+          }
+        }
+        if (animatorProps.r.propType) {
+          if (mult.length) {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
+          } else {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult);
+          }
+        }
+        if (animatorProps.ry.propType) {
+          if (mult.length) {
+            matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
+          } else {
+            matrixHelper.rotateY(animatorProps.ry.v * mult);
+          }
+        }
+        if (animatorProps.rx.propType) {
+          if (mult.length) {
+            matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
+          } else {
+            matrixHelper.rotateX(animatorProps.rx.v * mult);
+          }
+        }
+        if (animatorProps.o.propType) {
+          if (mult.length) {
+            elemOpacity += ((animatorProps.o.v) * mult[0] - elemOpacity) * mult[0];
+          } else {
+            elemOpacity += ((animatorProps.o.v) * mult - elemOpacity) * mult;
+          }
+        }
+        if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
+          if (mult.length) {
+            sw += animatorProps.sw.v * mult[0];
+          } else {
+            sw += animatorProps.sw.v * mult;
+          }
+        }
+        if (documentData.strokeColorAnim && animatorProps.sc.propType) {
+          for (k = 0; k < 3; k += 1) {
+            if (mult.length) {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0];
+            } else {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult;
+            }
+          }
+        }
+        if (documentData.fillColorAnim && documentData.fc) {
+          if (animatorProps.fc.propType) {
+            for (k = 0; k < 3; k += 1) {
+              if (mult.length) {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0];
+              } else {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult;
+              }
+            }
+          }
+          if (animatorProps.fh.propType) {
+            if (mult.length) {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
+            } else {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult);
+            }
+          }
+          if (animatorProps.fs.propType) {
+            if (mult.length) {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
+            } else {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
+            }
+          }
+          if (animatorProps.fb.propType) {
+            if (mult.length) {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
+            } else {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult);
+            }
+          }
+        }
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+
+        if (animatorProps.p.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (this._hasMaskedPath) {
+            if (mult.length) {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
+            } else {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+            }
+          } else if (mult.length) {
+            matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        letterSw = sw < 0 ? 0 : sw;
+      }
+      if (documentData.strokeColorAnim) {
+        letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
+      }
+
+      if (this._hasMaskedPath) {
+        matrixHelper.translate(0, -documentData.ls);
+
+        matrixHelper.translate(0, (alignment[1] * yOff) * 0.01 + yPos, 0);
+        if (this._pathData.p.v) {
+          tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
+          var rot = (Math.atan(tanAngle) * 180) / Math.PI;
+          if (currentPoint.point[0] < prevPoint.point[0]) {
+            rot += 180;
+          }
+          matrixHelper.rotate((-rot * Math.PI) / 180);
+        }
+        matrixHelper.translate(xPathPos, yPathPos, 0);
+        currentLength -= (alignment[0] * letters[i].an) * 0.005;
+        if (letters[i + 1] && ind !== letters[i + 1].ind) {
+          currentLength += letters[i].an / 2;
+          currentLength += (documentData.tr * 0.001) * documentData.finalSize;
+        }
+      } else {
+        matrixHelper.translate(xPos, yPos, 0);
+
+        if (documentData.ps) {
+          // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
+          matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+        }
+        switch (documentData.j) {
+          case 1:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
+            break;
+          case 2:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
+            break;
+          default:
+            break;
+        }
+        matrixHelper.translate(0, -documentData.ls);
+        matrixHelper.translate(offf, 0, 0);
+        matrixHelper.translate((alignment[0] * letters[i].an) * 0.005, (alignment[1] * yOff) * 0.01, 0);
+        xPos += letters[i].l + (documentData.tr * 0.001) * documentData.finalSize;
+      }
+      if (renderType === 'html') {
+        letterM = matrixHelper.toCSS();
+      } else if (renderType === 'svg') {
+        letterM = matrixHelper.to2dCSS();
+      } else {
+        letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
+      }
+      letterO = elemOpacity;
+    }
+
+    if (renderedLettersCount <= i) {
+      letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
+      this.renderedLetters.push(letterValue);
+      renderedLettersCount += 1;
+      this.lettersChangedFlag = true;
+    } else {
+      letterValue = this.renderedLetters[i];
+      this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag;
+    }
+  }
+};
+
+TextAnimatorProperty.prototype.getValue = function () {
+  if (this._elem.globalData.frameId === this._frameId) {
+    return;
+  }
+  this._frameId = this._elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+TextAnimatorProperty.prototype.mHelper = new Matrix();
+TextAnimatorProperty.prototype.defaultPropsArray = [];
+extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
+
+function ITextElement() {
+}
+
+ITextElement.prototype.initElement = function (data, globalData, comp) {
+  this.lettersChangedFlag = true;
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.textProperty = new TextProperty(this, data.t, this.dynamicProperties);
+  this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this);
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+  this.initRenderable();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  this.createContent();
+  this.hide();
+  this.textAnimator.searchProperties(this.dynamicProperties);
+};
+
+ITextElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+};
+
+ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
+  var j;
+  var jLen = shapes.length;
+  var pathNodes;
+  var shapeStr = '';
+  for (j = 0; j < jLen; j += 1) {
+    if (shapes[j].ty === 'sh') {
+      pathNodes = shapes[j].ks.k;
+      shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
+    }
+  }
+  return shapeStr;
+};
+
+ITextElement.prototype.updateDocumentData = function (newData, index) {
+  this.textProperty.updateDocumentData(newData, index);
+};
+
+ITextElement.prototype.canResizeFont = function (_canResize) {
+  this.textProperty.canResizeFont(_canResize);
+};
+
+ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
+  this.textProperty.setMinimumFontSize(_fontSize);
+};
+
+ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
+  if (documentData.ps) {
+    matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+  }
+  matrixHelper.translate(0, -documentData.ls, 0);
+  switch (documentData.j) {
+    case 1:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
+      break;
+    case 2:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
+      break;
+    default:
+      break;
+  }
+  matrixHelper.translate(xPos, yPos, 0);
+};
+
+ITextElement.prototype.buildColor = function (colorData) {
+  return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
+};
+
+ITextElement.prototype.emptyProp = new LetterProps();
+
+ITextElement.prototype.destroy = function () {
+
+};
+
+ITextElement.prototype.validateText = function () {
+  if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
+    this.buildNewText();
+    this.textProperty._isFirstFrame = false;
+    this.textProperty._mdf = false;
+  }
+};
+
+var emptyShapeData = {
+  shapes: [],
+};
+
+function SVGTextLottieElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.renderType = 'svg';
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
+
+SVGTextLottieElement.prototype.createContent = function () {
+  if (this.data.singleShape && !this.globalData.fontManager.chars) {
+    this.textContainer = createNS('text');
+  }
+};
+
+SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
+  var i = 0;
+  var len = textArray.length;
+  var textContents = [];
+  var currentTextContent = '';
+  while (i < len) {
+    if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
+      textContents.push(currentTextContent);
+      currentTextContent = '';
+    } else {
+      currentTextContent += textArray[i];
+    }
+    i += 1;
+  }
+  textContents.push(currentTextContent);
+  return textContents;
+};
+
+SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
+  // data should probably be cloned to apply scale separately to each instance of a text on different layers
+  // but since text internal content gets only rendered once and then it's never rerendered,
+  // it's probably safe not to clone data and reuse always the same instance even if the object is mutated.
+  // Avoiding cloning is preferred since cloning each character shape data is expensive
+  if (data.shapes && data.shapes.length) {
+    var shape = data.shapes[0];
+    if (shape.it) {
+      var shapeItem = shape.it[shape.it.length - 1];
+      if (shapeItem.s) {
+        shapeItem.s.k[0] = scale;
+        shapeItem.s.k[1] = scale;
+      }
+    }
+  }
+  return data;
+};
+
+SVGTextLottieElement.prototype.buildNewText = function () {
+  this.addDynamicProperty(this);
+  var i;
+  var len;
+
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
+  if (documentData.fc) {
+    this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
+  } else {
+    this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
+  }
+  if (documentData.sc) {
+    this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
+    this.layerElement.setAttribute('stroke-width', documentData.sw);
+  }
+  this.layerElement.setAttribute('font-size', documentData.finalSize);
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (fontData.fClass) {
+    this.layerElement.setAttribute('class', fontData.fClass);
+  } else {
+    this.layerElement.setAttribute('font-family', fontData.fFamily);
+    var fWeight = documentData.fWeight;
+    var fStyle = documentData.fStyle;
+    this.layerElement.setAttribute('font-style', fStyle);
+    this.layerElement.setAttribute('font-weight', fWeight);
+  }
+  this.layerElement.setAttribute('aria-label', documentData.t);
+
+  var letters = documentData.l || [];
+  var usesGlyphs = !!this.globalData.fontManager.chars;
+  len = letters.length;
+
+  var tSpan;
+  var matrixHelper = this.mHelper;
+  var shapeStr = '';
+  var singleShape = this.data.singleShape;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  if (singleShape && !usesGlyphs && !documentData.sz) {
+    var tElement = this.textContainer;
+    var justify = 'start';
+    switch (documentData.j) {
+      case 1:
+        justify = 'end';
+        break;
+      case 2:
+        justify = 'middle';
+        break;
+      default:
+        justify = 'start';
+        break;
+    }
+    tElement.setAttribute('text-anchor', justify);
+    tElement.setAttribute('letter-spacing', trackingOffset);
+    var textContent = this.buildTextContents(documentData.finalText);
+    len = textContent.length;
+    yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
+    for (i = 0; i < len; i += 1) {
+      tSpan = this.textSpans[i].span || createNS('tspan');
+      tSpan.textContent = textContent[i];
+      tSpan.setAttribute('x', 0);
+      tSpan.setAttribute('y', yPos);
+      tSpan.style.display = 'inherit';
+      tElement.appendChild(tSpan);
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          glyph: null,
+        };
+      }
+      this.textSpans[i].span = tSpan;
+      yPos += documentData.finalLineHeight;
+    }
+
+    this.layerElement.appendChild(tElement);
+  } else {
+    var cachedSpansLength = this.textSpans.length;
+    var charData;
+    for (i = 0; i < len; i += 1) {
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          childSpan: null,
+          glyph: null,
+        };
+      }
+      if (!usesGlyphs || !singleShape || i === 0) {
+        tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
+        if (cachedSpansLength <= i) {
+          tSpan.setAttribute('stroke-linecap', 'butt');
+          tSpan.setAttribute('stroke-linejoin', 'round');
+          tSpan.setAttribute('stroke-miterlimit', '4');
+          this.textSpans[i].span = tSpan;
+          if (usesGlyphs) {
+            var childSpan = createNS('g');
+            tSpan.appendChild(childSpan);
+            this.textSpans[i].childSpan = childSpan;
+          }
+          this.textSpans[i].span = tSpan;
+          this.layerElement.appendChild(tSpan);
+        }
+        tSpan.style.display = 'inherit';
+      }
+
+      matrixHelper.reset();
+      if (singleShape) {
+        if (letters[i].n) {
+          xPos = -trackingOffset;
+          yPos += documentData.yOffset;
+          yPos += firstLine ? 1 : 0;
+          firstLine = false;
+        }
+        this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+        xPos += letters[i].l || 0;
+        // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
+        xPos += trackingOffset;
+      }
+      if (usesGlyphs) {
+        charData = this.globalData.fontManager.getCharData(
+          documentData.finalText[i],
+          fontData.fStyle,
+          this.globalData.fontManager.getFontByName(documentData.f).fFamily
+        );
+        var glyphElement;
+        // t === 1 means the character has been replaced with an animated shaped
+        if (charData.t === 1) {
+          glyphElement = new SVGCompElement(charData.data, this.globalData, this);
+        } else {
+          var data = emptyShapeData;
+          if (charData.data && charData.data.shapes) {
+            data = this.buildShapeData(charData.data, documentData.finalSize);
+          }
+          glyphElement = new SVGShapeElement(data, this.globalData, this);
+        }
+        if (this.textSpans[i].glyph) {
+          var glyph = this.textSpans[i].glyph;
+          this.textSpans[i].childSpan.removeChild(glyph.layerElement);
+          glyph.destroy();
+        }
+        this.textSpans[i].glyph = glyphElement;
+        glyphElement._debug = true;
+        glyphElement.prepareFrame(0);
+        glyphElement.renderFrame();
+        this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+        // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+        // this might have issues with strokes and might need a different solution
+        if (charData.t === 1) {
+          this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
+        }
+      } else {
+        if (singleShape) {
+          tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
+        }
+        tSpan.textContent = letters[i].val;
+        tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      }
+      //
+    }
+    if (singleShape && tSpan) {
+      tSpan.setAttribute('d', shapeStr);
+    }
+  }
+  while (i < this.textSpans.length) {
+    this.textSpans[i].span.style.display = 'none';
+    i += 1;
+  }
+
+  this._sizeChanged = true;
+};
+
+SVGTextLottieElement.prototype.sourceRectAtTime = function () {
+  this.prepareFrame(this.comp.renderedFrame - this.data.st);
+  this.renderInnerContent();
+  if (this._sizeChanged) {
+    this._sizeChanged = false;
+    var textBox = this.layerElement.getBBox();
+    this.bbox = {
+      top: textBox.y,
+      left: textBox.x,
+      width: textBox.width,
+      height: textBox.height,
+    };
+  }
+  return this.bbox;
+};
+
+SVGTextLottieElement.prototype.getValue = function () {
+  var i;
+  var len = this.textSpans.length;
+  var glyphElement;
+  this.renderedFrame = this.comp.renderedFrame;
+  for (i = 0; i < len; i += 1) {
+    glyphElement = this.textSpans[i].glyph;
+    if (glyphElement) {
+      glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
+      if (glyphElement._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+SVGTextLottieElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  if (!this.data.singleShape || this._mdf) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+    if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
+      this._sizeChanged = true;
+      var i;
+      var len;
+      var renderedLetters = this.textAnimator.renderedLetters;
+
+      var letters = this.textProperty.currentData.l;
+
+      len = letters.length;
+      var renderedLetter;
+      var textSpan;
+      var glyphElement;
+      for (i = 0; i < len; i += 1) {
+        if (!letters[i].n) {
+          renderedLetter = renderedLetters[i];
+          textSpan = this.textSpans[i].span;
+          glyphElement = this.textSpans[i].glyph;
+          if (glyphElement) {
+            glyphElement.renderFrame();
+          }
+          if (renderedLetter._mdf.m) {
+            textSpan.setAttribute('transform', renderedLetter.m);
+          }
+          if (renderedLetter._mdf.o) {
+            textSpan.setAttribute('opacity', renderedLetter.o);
+          }
+          if (renderedLetter._mdf.sw) {
+            textSpan.setAttribute('stroke-width', renderedLetter.sw);
+          }
+          if (renderedLetter._mdf.sc) {
+            textSpan.setAttribute('stroke', renderedLetter.sc);
+          }
+          if (renderedLetter._mdf.fc) {
+            textSpan.setAttribute('fill', renderedLetter.fc);
+          }
+        }
+      }
+    }
+  }
+};
+
+function ISolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([IImageElement], ISolidElement);
+
+ISolidElement.prototype.createContent = function () {
+  var rect = createNS('rect');
+  /// /rect.style.width = this.data.sw;
+  /// /rect.style.height = this.data.sh;
+  /// /rect.style.fill = this.data.sc;
+  rect.setAttribute('width', this.data.sw);
+  rect.setAttribute('height', this.data.sh);
+  rect.setAttribute('fill', this.data.sc);
+  this.layerElement.appendChild(rect);
+};
+
+function NullElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initFrame();
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+}
+
+NullElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+NullElement.prototype.renderFrame = function () {
+};
+
+NullElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+NullElement.prototype.destroy = function () {
+};
+
+NullElement.prototype.sourceRectAtTime = function () {
+};
+
+NullElement.prototype.hide = function () {
+};
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
+
+function SVGRendererBase() {
+}
+
+extendPrototype([BaseRenderer], SVGRendererBase);
+
+SVGRendererBase.prototype.createNull = function (data) {
+  return new NullElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createShape = function (data) {
+  return new SVGShapeElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createText = function (data) {
+  return new SVGTextLottieElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createImage = function (data) {
+  return new IImageElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createSolid = function (data) {
+  return new ISolidElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.configAnimation = function (animData) {
+  this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+  this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+  if (this.renderConfig.viewBoxSize) {
+    this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
+  } else {
+    this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
+  }
+
+  if (!this.renderConfig.viewBoxOnly) {
+    this.svgElement.setAttribute('width', animData.w);
+    this.svgElement.setAttribute('height', animData.h);
+    this.svgElement.style.width = '100%';
+    this.svgElement.style.height = '100%';
+    this.svgElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
+  }
+  if (this.renderConfig.width) {
+    this.svgElement.setAttribute('width', this.renderConfig.width);
+  }
+  if (this.renderConfig.height) {
+    this.svgElement.setAttribute('height', this.renderConfig.height);
+  }
+  if (this.renderConfig.className) {
+    this.svgElement.setAttribute('class', this.renderConfig.className);
+  }
+  if (this.renderConfig.id) {
+    this.svgElement.setAttribute('id', this.renderConfig.id);
+  }
+  if (this.renderConfig.focusable !== undefined) {
+    this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
+  }
+  this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+  // this.layerElement.style.transform = 'translate3d(0,0,0)';
+  // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
+  this.animationItem.wrapper.appendChild(this.svgElement);
+  // Mask animation
+  var defs = this.globalData.defs;
+
+  this.setupGlobalData(animData, defs);
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.data = animData;
+
+  var maskElement = createNS('clipPath');
+  var rect = createNS('rect');
+  rect.setAttribute('width', animData.w);
+  rect.setAttribute('height', animData.h);
+  rect.setAttribute('x', 0);
+  rect.setAttribute('y', 0);
+  var maskId = createElementID();
+  maskElement.setAttribute('id', maskId);
+  maskElement.appendChild(rect);
+  this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')');
+
+  defs.appendChild(maskElement);
+  this.layers = animData.layers;
+  this.elements = createSizedArray(animData.layers.length);
+};
+
+SVGRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.layerElement = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+SVGRendererBase.prototype.updateContainerSize = function () {
+};
+
+SVGRendererBase.prototype.findIndexByInd = function (ind) {
+  var i = 0;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.layers[i].ind === ind) {
+      return i;
+    }
+  }
+  return -1;
+};
+
+SVGRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  elements[pos] = true;
+  var element = this.createItem(this.layers[pos]);
+
+  elements[pos] = element;
+  if (getExpressionsPlugin()) {
+    if (this.layers[pos].ty === 0) {
+      this.globalData.projectInterface.registerComposition(element);
+    }
+    element.initExpressions();
+  }
+  this.appendElementInPos(element, pos);
+  if (this.layers[pos].tt) {
+    var elementIndex = ('tp' in this.layers[pos])
+      ? this.findIndexByInd(this.layers[pos].tp)
+      : pos - 1;
+    if (elementIndex === -1) {
+      return;
+    }
+    if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
+      this.buildItem(elementIndex);
+      this.addPendingElement(element);
+    } else {
+      var matteElement = elements[elementIndex];
+      var matteMask = matteElement.getMatte(this.layers[pos].tt);
+      element.setMatte(matteMask);
+    }
+  }
+};
+
+SVGRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+    if (element.data.tt) {
+      var i = 0;
+      var len = this.elements.length;
+      while (i < len) {
+        if (this.elements[i] === element) {
+          var elementIndex = 'tp' in element.data
+            ? this.findIndexByInd(element.data.tp)
+            : i - 1;
+          var matteElement = this.elements[elementIndex];
+          var matteMask = matteElement.getMatte(this.layers[i].tt);
+          element.setMatte(matteMask);
+          break;
+        }
+        i += 1;
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.renderFrame = function (num) {
+  if (this.renderedFrame === num || this.destroyed) {
+    return;
+  }
+  if (num === null) {
+    num = this.renderedFrame;
+  } else {
+    this.renderedFrame = num;
+  }
+  // console.log('-------');
+  // console.log('FRAME ',num);
+  this.globalData.frameNum = num;
+  this.globalData.frameId += 1;
+  this.globalData.projectInterface.currentFrame = num;
+  this.globalData._mdf = false;
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    for (i = 0; i < len; i += 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
+  var newElement = element.getBaseElement();
+  if (!newElement) {
+    return;
+  }
+  var i = 0;
+  var nextElement;
+  while (i < pos) {
+    if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
+      nextElement = this.elements[i].getBaseElement();
+    }
+    i += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(newElement, nextElement);
+  } else {
+    this.layerElement.appendChild(newElement);
+  }
+};
+
+SVGRendererBase.prototype.hide = function () {
+  this.layerElement.style.display = 'none';
+};
+
+SVGRendererBase.prototype.show = function () {
+  this.layerElement.style.display = 'block';
+};
+
+function ICompElement() {}
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
+
+ICompElement.prototype.initElement = function (data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initTransform(data, globalData, comp);
+  this.initRenderable();
+  this.initHierarchy();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  if (this.data.xt || !globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+  this.hide();
+};
+
+/* ICompElement.prototype.hide = function(){
+    if(!this.hidden){
+        this.hideElement();
+        var i,len = this.elements.length;
+        for( i = 0; i < len; i+=1 ){
+            if(this.elements[i]){
+                this.elements[i].hide();
+            }
+        }
+    }
+}; */
+
+ICompElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+  if (!this.isInRange && !this.data.xt) {
+    return;
+  }
+
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    if (timeRemapped === this.data.op) {
+      timeRemapped = this.data.op - 1;
+    }
+    this.renderedFrame = timeRemapped;
+  } else {
+    this.renderedFrame = num / this.data.sr;
+  }
+  var i;
+  var len = this.elements.length;
+  if (!this.completeLayers) {
+    this.checkLayers(this.renderedFrame);
+  }
+  // This iteration needs to be backwards because of how expressions connect between each other
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
+      if (this.elements[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+ICompElement.prototype.renderInnerContent = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+ICompElement.prototype.setElements = function (elems) {
+  this.elements = elems;
+};
+
+ICompElement.prototype.getElements = function () {
+  return this.elements;
+};
+
+ICompElement.prototype.destroyElements = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+};
+
+ICompElement.prototype.destroy = function () {
+  this.destroyElements();
+  this.destroyBaseElement();
+};
+
+function SVGCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = true;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
+
+SVGCompElement.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function SVGRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.layers = null;
+  this.renderedFrame = -1;
+  this.svgElement = createNS('svg');
+  var ariaLabel = '';
+  if (config && config.title) {
+    var titleElement = createNS('title');
+    var titleId = createElementID();
+    titleElement.setAttribute('id', titleId);
+    titleElement.textContent = config.title;
+    this.svgElement.appendChild(titleElement);
+    ariaLabel += titleId;
+  }
+  if (config && config.description) {
+    var descElement = createNS('desc');
+    var descId = createElementID();
+    descElement.setAttribute('id', descId);
+    descElement.textContent = config.description;
+    this.svgElement.appendChild(descElement);
+    ariaLabel += ' ' + descId;
+  }
+  if (ariaLabel) {
+    this.svgElement.setAttribute('aria-labelledby', ariaLabel);
+  }
+  var defs = createNS('defs');
+  this.svgElement.appendChild(defs);
+  var maskElement = createNS('g');
+  this.svgElement.appendChild(maskElement);
+  this.layerElement = maskElement;
+  this.renderConfig = {
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    hideOnTransparent: !((config && config.hideOnTransparent === false)),
+    viewBoxOnly: (config && config.viewBoxOnly) || false,
+    viewBoxSize: (config && config.viewBoxSize) || false,
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    focusable: config && config.focusable,
+    filterSize: {
+      width: (config && config.filterSize && config.filterSize.width) || '100%',
+      height: (config && config.filterSize && config.filterSize.height) || '100%',
+      x: (config && config.filterSize && config.filterSize.x) || '0%',
+      y: (config && config.filterSize && config.filterSize.y) || '0%',
+    },
+    width: (config && config.width),
+    height: (config && config.height),
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+
+  this.globalData = {
+    _mdf: false,
+    frameNum: -1,
+    defs: defs,
+    renderConfig: this.renderConfig,
+  };
+  this.elements = [];
+  this.pendingElements = [];
+  this.destroyed = false;
+  this.rendererType = 'svg';
+}
+
+extendPrototype([SVGRendererBase], SVGRenderer);
+
+SVGRenderer.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+var registeredEffects = {};
+
+function CVEffects(elem) {
+  var i;
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects[type]) {
+      var Effect = registeredEffects[type].effect;
+      filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+CVEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+CVEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect(id, effect) {
+  registeredEffects[id] = {
+    effect,
+  };
+}
+
+function HBaseElement() {}
+HBaseElement.prototype = {
+  checkBlendMode: function () {},
+  initRendererElement: function () {
+    this.baseElement = createTag(this.data.tg || 'div');
+    if (this.data.hasMask) {
+      this.svgElement = createNS('svg');
+      this.layerElement = createNS('g');
+      this.maskedElement = this.layerElement;
+      this.svgElement.appendChild(this.layerElement);
+      this.baseElement.appendChild(this.svgElement);
+    } else {
+      this.layerElement = this.baseElement;
+    }
+    styleDiv(this.baseElement);
+  },
+  createContainerElements: function () {
+    this.renderableEffectsManager = new CVEffects(this);
+    this.transformedElement = this.baseElement;
+    this.maskedElement = this.layerElement;
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    var transformedElementStyle = this.transformedElement ? this.transformedElement.style : {};
+    if (this.finalTransform._matMdf) {
+      var matrixValue = this.finalTransform.mat.toCSS();
+      transformedElementStyle.transform = matrixValue;
+      transformedElementStyle.webkitTransform = matrixValue;
+    }
+    if (this.finalTransform._opMdf) {
+      transformedElementStyle.opacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderFrame: function () {
+    // If it is exported as hidden (data.hd === true) no need to render
+    // If it is not visible no need to render
+    if (this.data.hd || this.hidden) {
+      return;
+    }
+    this.renderTransform();
+    this.renderRenderable();
+    this.renderElement();
+    this.renderInnerContent();
+    if (this._isFirstFrame) {
+      this._isFirstFrame = false;
+    }
+  },
+  destroy: function () {
+    this.layerElement = null;
+    this.transformedElement = null;
+    if (this.matteElement) {
+      this.matteElement = null;
+    }
+    if (this.maskManager) {
+      this.maskManager.destroy();
+      this.maskManager = null;
+    }
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+  },
+  addEffects: function () {
+  },
+  setMatte: function () {},
+};
+HBaseElement.prototype.getBaseElement = SVGBaseElement.prototype.getBaseElement;
+HBaseElement.prototype.destroyBaseElement = HBaseElement.prototype.destroy;
+HBaseElement.prototype.buildElementParenting = BaseRenderer.prototype.buildElementParenting;
+
+function HSolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], HSolidElement);
+
+HSolidElement.prototype.createContent = function () {
+  var rect;
+  if (this.data.hasMask) {
+    rect = createNS('rect');
+    rect.setAttribute('width', this.data.sw);
+    rect.setAttribute('height', this.data.sh);
+    rect.setAttribute('fill', this.data.sc);
+    this.svgElement.setAttribute('width', this.data.sw);
+    this.svgElement.setAttribute('height', this.data.sh);
+  } else {
+    rect = createTag('div');
+    rect.style.width = this.data.sw + 'px';
+    rect.style.height = this.data.sh + 'px';
+    rect.style.backgroundColor = this.data.sc;
+  }
+  this.layerElement.appendChild(rect);
+};
+
+function HShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.shapesContainer = createNS('g');
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  this.currentBBox = {
+    x: 999999,
+    y: -999999,
+    h: 0,
+    w: 0,
+  };
+}
+extendPrototype([BaseElement, TransformElement, HSolidElement, SVGShapeElement, HBaseElement, HierarchyElement, FrameElement, RenderableElement], HShapeElement);
+HShapeElement.prototype._renderShapeFrame = HShapeElement.prototype.renderInnerContent;
+
+HShapeElement.prototype.createContent = function () {
+  var cont;
+  this.baseElement.style.fontSize = 0;
+  if (this.data.hasMask) {
+    this.layerElement.appendChild(this.shapesContainer);
+    cont = this.svgElement;
+  } else {
+    cont = createNS('svg');
+    var size = this.comp.data ? this.comp.data : this.globalData.compSize;
+    cont.setAttribute('width', size.w);
+    cont.setAttribute('height', size.h);
+    cont.appendChild(this.shapesContainer);
+    this.layerElement.appendChild(cont);
+  }
+
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.shapesContainer, 0, [], true);
+  this.filterUniqueShapes();
+  this.shapeCont = cont;
+};
+
+HShapeElement.prototype.getTransformedPoint = function (transformers, point) {
+  var i;
+  var len = transformers.length;
+  for (i = 0; i < len; i += 1) {
+    point = transformers[i].mProps.v.applyToPointArray(point[0], point[1], 0);
+  }
+  return point;
+};
+
+HShapeElement.prototype.calculateShapeBoundingBox = function (item, boundingBox) {
+  var shape = item.sh.v;
+  var transformers = item.transformers;
+  var i;
+  var len = shape._length;
+  var vPoint;
+  var oPoint;
+  var nextIPoint;
+  var nextVPoint;
+  if (len <= 1) {
+    return;
+  }
+  for (i = 0; i < len - 1; i += 1) {
+    vPoint = this.getTransformedPoint(transformers, shape.v[i]);
+    oPoint = this.getTransformedPoint(transformers, shape.o[i]);
+    nextIPoint = this.getTransformedPoint(transformers, shape.i[i + 1]);
+    nextVPoint = this.getTransformedPoint(transformers, shape.v[i + 1]);
+    this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
+  }
+  if (shape.c) {
+    vPoint = this.getTransformedPoint(transformers, shape.v[i]);
+    oPoint = this.getTransformedPoint(transformers, shape.o[i]);
+    nextIPoint = this.getTransformedPoint(transformers, shape.i[0]);
+    nextVPoint = this.getTransformedPoint(transformers, shape.v[0]);
+    this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
+  }
+};
+
+HShapeElement.prototype.checkBounds = function (vPoint, oPoint, nextIPoint, nextVPoint, boundingBox) {
+  this.getBoundsOfCurve(vPoint, oPoint, nextIPoint, nextVPoint);
+  var bounds = this.shapeBoundingBox;
+  boundingBox.x = bmMin(bounds.left, boundingBox.x);
+  boundingBox.xMax = bmMax(bounds.right, boundingBox.xMax);
+  boundingBox.y = bmMin(bounds.top, boundingBox.y);
+  boundingBox.yMax = bmMax(bounds.bottom, boundingBox.yMax);
+};
+
+HShapeElement.prototype.shapeBoundingBox = {
+  left: 0,
+  right: 0,
+  top: 0,
+  bottom: 0,
+};
+
+HShapeElement.prototype.tempBoundingBox = {
+  x: 0,
+  xMax: 0,
+  y: 0,
+  yMax: 0,
+  width: 0,
+  height: 0,
+};
+
+HShapeElement.prototype.getBoundsOfCurve = function (p0, p1, p2, p3) {
+  var bounds = [[p0[0], p3[0]], [p0[1], p3[1]]];
+
+  for (var a, b, c, t, b2ac, t1, t2, i = 0; i < 2; ++i) { // eslint-disable-line no-plusplus
+    b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];
+    a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];
+    c = 3 * p1[i] - 3 * p0[i];
+
+    b |= 0; // eslint-disable-line no-bitwise
+    a |= 0; // eslint-disable-line no-bitwise
+    c |= 0; // eslint-disable-line no-bitwise
+
+    if (a === 0 && b === 0) {
+      //
+    } else if (a === 0) {
+      t = -c / b;
+
+      if (t > 0 && t < 1) {
+        bounds[i].push(this.calculateF(t, p0, p1, p2, p3, i));
+      }
+    } else {
+      b2ac = b * b - 4 * c * a;
+
+      if (b2ac >= 0) {
+        t1 = (-b + bmSqrt(b2ac)) / (2 * a);
+        if (t1 > 0 && t1 < 1) bounds[i].push(this.calculateF(t1, p0, p1, p2, p3, i));
+        t2 = (-b - bmSqrt(b2ac)) / (2 * a);
+        if (t2 > 0 && t2 < 1) bounds[i].push(this.calculateF(t2, p0, p1, p2, p3, i));
+      }
+    }
+  }
+
+  this.shapeBoundingBox.left = bmMin.apply(null, bounds[0]);
+  this.shapeBoundingBox.top = bmMin.apply(null, bounds[1]);
+  this.shapeBoundingBox.right = bmMax.apply(null, bounds[0]);
+  this.shapeBoundingBox.bottom = bmMax.apply(null, bounds[1]);
+};
+
+HShapeElement.prototype.calculateF = function (t, p0, p1, p2, p3, i) {
+  return bmPow(1 - t, 3) * p0[i]
+        + 3 * bmPow(1 - t, 2) * t * p1[i]
+        + 3 * (1 - t) * bmPow(t, 2) * p2[i]
+        + bmPow(t, 3) * p3[i];
+};
+
+HShapeElement.prototype.calculateBoundingBox = function (itemsData, boundingBox) {
+  var i;
+  var len = itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    if (itemsData[i] && itemsData[i].sh) {
+      this.calculateShapeBoundingBox(itemsData[i], boundingBox);
+    } else if (itemsData[i] && itemsData[i].it) {
+      this.calculateBoundingBox(itemsData[i].it, boundingBox);
+    } else if (itemsData[i] && itemsData[i].style && itemsData[i].w) {
+      this.expandStrokeBoundingBox(itemsData[i].w, boundingBox);
+    }
+  }
+};
+
+HShapeElement.prototype.expandStrokeBoundingBox = function (widthProperty, boundingBox) {
+  var width = 0;
+  if (widthProperty.keyframes) {
+    for (var i = 0; i < widthProperty.keyframes.length; i += 1) {
+      var kfw = widthProperty.keyframes[i].s;
+      if (kfw > width) {
+        width = kfw;
+      }
+    }
+    width *= widthProperty.mult;
+  } else {
+    width = widthProperty.v * widthProperty.mult;
+  }
+
+  boundingBox.x -= width;
+  boundingBox.xMax += width;
+  boundingBox.y -= width;
+  boundingBox.yMax += width;
+};
+
+HShapeElement.prototype.currentBoxContains = function (box) {
+  return this.currentBBox.x <= box.x
+    && this.currentBBox.y <= box.y
+    && this.currentBBox.width + this.currentBBox.x >= box.x + box.width
+    && this.currentBBox.height + this.currentBBox.y >= box.y + box.height;
+};
+
+HShapeElement.prototype.renderInnerContent = function () {
+  this._renderShapeFrame();
+
+  if (!this.hidden && (this._isFirstFrame || this._mdf)) {
+    var tempBoundingBox = this.tempBoundingBox;
+    var max = 999999;
+    tempBoundingBox.x = max;
+    tempBoundingBox.xMax = -max;
+    tempBoundingBox.y = max;
+    tempBoundingBox.yMax = -max;
+    this.calculateBoundingBox(this.itemsData, tempBoundingBox);
+    tempBoundingBox.width = tempBoundingBox.xMax < tempBoundingBox.x ? 0 : tempBoundingBox.xMax - tempBoundingBox.x;
+    tempBoundingBox.height = tempBoundingBox.yMax < tempBoundingBox.y ? 0 : tempBoundingBox.yMax - tempBoundingBox.y;
+    // var tempBoundingBox = this.shapeCont.getBBox();
+    if (this.currentBoxContains(tempBoundingBox)) {
+      return;
+    }
+    var changed = false;
+    if (this.currentBBox.w !== tempBoundingBox.width) {
+      this.currentBBox.w = tempBoundingBox.width;
+      this.shapeCont.setAttribute('width', tempBoundingBox.width);
+      changed = true;
+    }
+    if (this.currentBBox.h !== tempBoundingBox.height) {
+      this.currentBBox.h = tempBoundingBox.height;
+      this.shapeCont.setAttribute('height', tempBoundingBox.height);
+      changed = true;
+    }
+    if (changed || this.currentBBox.x !== tempBoundingBox.x || this.currentBBox.y !== tempBoundingBox.y) {
+      this.currentBBox.w = tempBoundingBox.width;
+      this.currentBBox.h = tempBoundingBox.height;
+      this.currentBBox.x = tempBoundingBox.x;
+      this.currentBBox.y = tempBoundingBox.y;
+
+      this.shapeCont.setAttribute('viewBox', this.currentBBox.x + ' ' + this.currentBBox.y + ' ' + this.currentBBox.w + ' ' + this.currentBBox.h);
+      var shapeStyle = this.shapeCont.style;
+      var shapeTransform = 'translate(' + this.currentBBox.x + 'px,' + this.currentBBox.y + 'px)';
+      shapeStyle.transform = shapeTransform;
+      shapeStyle.webkitTransform = shapeTransform;
+    }
+  }
+};
+
+function HTextElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.textPaths = [];
+  this.currentBBox = {
+    x: 999999,
+    y: -999999,
+    h: 0,
+    w: 0,
+  };
+  this.renderType = 'svg';
+  this.isMasked = false;
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], HTextElement);
+
+HTextElement.prototype.createContent = function () {
+  this.isMasked = this.checkMasks();
+  if (this.isMasked) {
+    this.renderType = 'svg';
+    this.compW = this.comp.data.w;
+    this.compH = this.comp.data.h;
+    this.svgElement.setAttribute('width', this.compW);
+    this.svgElement.setAttribute('height', this.compH);
+    var g = createNS('g');
+    this.maskedElement.appendChild(g);
+    this.innerElem = g;
+  } else {
+    this.renderType = 'html';
+    this.innerElem = this.layerElement;
+  }
+
+  this.checkParenting();
+};
+
+HTextElement.prototype.buildNewText = function () {
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
+  var innerElemStyle = this.innerElem.style;
+  var textColor = documentData.fc ? this.buildColor(documentData.fc) : 'rgba(0,0,0,0)';
+  innerElemStyle.fill = textColor;
+  innerElemStyle.color = textColor;
+  if (documentData.sc) {
+    innerElemStyle.stroke = this.buildColor(documentData.sc);
+    innerElemStyle.strokeWidth = documentData.sw + 'px';
+  }
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (!this.globalData.fontManager.chars) {
+    innerElemStyle.fontSize = documentData.finalSize + 'px';
+    innerElemStyle.lineHeight = documentData.finalSize + 'px';
+    if (fontData.fClass) {
+      this.innerElem.className = fontData.fClass;
+    } else {
+      innerElemStyle.fontFamily = fontData.fFamily;
+      var fWeight = documentData.fWeight;
+      var fStyle = documentData.fStyle;
+      innerElemStyle.fontStyle = fStyle;
+      innerElemStyle.fontWeight = fWeight;
+    }
+  }
+  var i;
+  var len;
+
+  var letters = documentData.l;
+  len = letters.length;
+  var tSpan;
+  var tParent;
+  var tCont;
+  var matrixHelper = this.mHelper;
+  var shapes;
+  var shapeStr = '';
+  var cnt = 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.globalData.fontManager.chars) {
+      if (!this.textPaths[cnt]) {
+        tSpan = createNS('path');
+        tSpan.setAttribute('stroke-linecap', lineCapEnum[1]);
+        tSpan.setAttribute('stroke-linejoin', lineJoinEnum[2]);
+        tSpan.setAttribute('stroke-miterlimit', '4');
+      } else {
+        tSpan = this.textPaths[cnt];
+      }
+      if (!this.isMasked) {
+        if (this.textSpans[cnt]) {
+          tParent = this.textSpans[cnt];
+          tCont = tParent.children[0];
+        } else {
+          tParent = createTag('div');
+          tParent.style.lineHeight = 0;
+          tCont = createNS('svg');
+          tCont.appendChild(tSpan);
+          styleDiv(tParent);
+        }
+      }
+    } else if (!this.isMasked) {
+      if (this.textSpans[cnt]) {
+        tParent = this.textSpans[cnt];
+        tSpan = this.textPaths[cnt];
+      } else {
+        tParent = createTag('span');
+        styleDiv(tParent);
+        tSpan = createTag('span');
+        styleDiv(tSpan);
+        tParent.appendChild(tSpan);
+      }
+    } else {
+      tSpan = this.textPaths[cnt] ? this.textPaths[cnt] : createNS('text');
+    }
+    // tSpan.setAttribute('visibility', 'hidden');
+    if (this.globalData.fontManager.chars) {
+      var charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
+      var shapeData;
+      if (charData) {
+        shapeData = charData.data;
+      } else {
+        shapeData = null;
+      }
+      matrixHelper.reset();
+      if (shapeData && shapeData.shapes && shapeData.shapes.length) {
+        shapes = shapeData.shapes[0].it;
+        matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
+        shapeStr = this.createPathShape(matrixHelper, shapes);
+        tSpan.setAttribute('d', shapeStr);
+      }
+      if (!this.isMasked) {
+        this.innerElem.appendChild(tParent);
+        if (shapeData && shapeData.shapes) {
+          // document.body.appendChild is needed to get exact measure of shape
+          document.body.appendChild(tCont);
+          var boundingBox = tCont.getBBox();
+          tCont.setAttribute('width', boundingBox.width + 2);
+          tCont.setAttribute('height', boundingBox.height + 2);
+          tCont.setAttribute('viewBox', (boundingBox.x - 1) + ' ' + (boundingBox.y - 1) + ' ' + (boundingBox.width + 2) + ' ' + (boundingBox.height + 2));
+          var tContStyle = tCont.style;
+          var tContTranslation = 'translate(' + (boundingBox.x - 1) + 'px,' + (boundingBox.y - 1) + 'px)';
+          tContStyle.transform = tContTranslation;
+          tContStyle.webkitTransform = tContTranslation;
+
+          letters[i].yOffset = boundingBox.y - 1;
+        } else {
+          tCont.setAttribute('width', 1);
+          tCont.setAttribute('height', 1);
+        }
+        tParent.appendChild(tCont);
+      } else {
+        this.innerElem.appendChild(tSpan);
+      }
+    } else {
+      tSpan.textContent = letters[i].val;
+      tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      if (!this.isMasked) {
+        this.innerElem.appendChild(tParent);
+        //
+        var tStyle = tSpan.style;
+        var tSpanTranslation = 'translate3d(0,' + -documentData.finalSize / 1.2 + 'px,0)';
+        tStyle.transform = tSpanTranslation;
+        tStyle.webkitTransform = tSpanTranslation;
+      } else {
+        this.innerElem.appendChild(tSpan);
+      }
+    }
+    //
+    if (!this.isMasked) {
+      this.textSpans[cnt] = tParent;
+    } else {
+      this.textSpans[cnt] = tSpan;
+    }
+    this.textSpans[cnt].style.display = 'block';
+    this.textPaths[cnt] = tSpan;
+    cnt += 1;
+  }
+  while (cnt < this.textSpans.length) {
+    this.textSpans[cnt].style.display = 'none';
+    cnt += 1;
+  }
+};
+
+HTextElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  var svgStyle;
+  if (this.data.singleShape) {
+    if (!this._isFirstFrame && !this.lettersChangedFlag) {
+      return;
+    } if (this.isMasked && this.finalTransform._matMdf) {
+      // Todo Benchmark if using this is better than getBBox
+      this.svgElement.setAttribute('viewBox', -this.finalTransform.mProp.p.v[0] + ' ' + -this.finalTransform.mProp.p.v[1] + ' ' + this.compW + ' ' + this.compH);
+      svgStyle = this.svgElement.style;
+      var translation = 'translate(' + -this.finalTransform.mProp.p.v[0] + 'px,' + -this.finalTransform.mProp.p.v[1] + 'px)';
+      svgStyle.transform = translation;
+      svgStyle.webkitTransform = translation;
+    }
+  }
+
+  this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+  if (!this.lettersChangedFlag && !this.textAnimator.lettersChangedFlag) {
+    return;
+  }
+  var i;
+  var len;
+  var count = 0;
+  var renderedLetters = this.textAnimator.renderedLetters;
+
+  var letters = this.textProperty.currentData.l;
+
+  len = letters.length;
+  var renderedLetter;
+  var textSpan;
+  var textPath;
+  for (i = 0; i < len; i += 1) {
+    if (letters[i].n) {
+      count += 1;
+    } else {
+      textSpan = this.textSpans[i];
+      textPath = this.textPaths[i];
+      renderedLetter = renderedLetters[count];
+      count += 1;
+      if (renderedLetter._mdf.m) {
+        if (!this.isMasked) {
+          textSpan.style.webkitTransform = renderedLetter.m;
+          textSpan.style.transform = renderedLetter.m;
+        } else {
+          textSpan.setAttribute('transform', renderedLetter.m);
+        }
+      }
+      /// /textSpan.setAttribute('opacity',renderedLetter.o);
+      textSpan.style.opacity = renderedLetter.o;
+      if (renderedLetter.sw && renderedLetter._mdf.sw) {
+        textPath.setAttribute('stroke-width', renderedLetter.sw);
+      }
+      if (renderedLetter.sc && renderedLetter._mdf.sc) {
+        textPath.setAttribute('stroke', renderedLetter.sc);
+      }
+      if (renderedLetter.fc && renderedLetter._mdf.fc) {
+        textPath.setAttribute('fill', renderedLetter.fc);
+        textPath.style.color = renderedLetter.fc;
+      }
+    }
+  }
+
+  if (this.innerElem.getBBox && !this.hidden && (this._isFirstFrame || this._mdf)) {
+    var boundingBox = this.innerElem.getBBox();
+
+    if (this.currentBBox.w !== boundingBox.width) {
+      this.currentBBox.w = boundingBox.width;
+      this.svgElement.setAttribute('width', boundingBox.width);
+    }
+    if (this.currentBBox.h !== boundingBox.height) {
+      this.currentBBox.h = boundingBox.height;
+      this.svgElement.setAttribute('height', boundingBox.height);
+    }
+
+    var margin = 1;
+    if (this.currentBBox.w !== (boundingBox.width + margin * 2) || this.currentBBox.h !== (boundingBox.height + margin * 2) || this.currentBBox.x !== (boundingBox.x - margin) || this.currentBBox.y !== (boundingBox.y - margin)) {
+      this.currentBBox.w = boundingBox.width + margin * 2;
+      this.currentBBox.h = boundingBox.height + margin * 2;
+      this.currentBBox.x = boundingBox.x - margin;
+      this.currentBBox.y = boundingBox.y - margin;
+
+      this.svgElement.setAttribute('viewBox', this.currentBBox.x + ' ' + this.currentBBox.y + ' ' + this.currentBBox.w + ' ' + this.currentBBox.h);
+      svgStyle = this.svgElement.style;
+      var svgTransform = 'translate(' + this.currentBBox.x + 'px,' + this.currentBBox.y + 'px)';
+      svgStyle.transform = svgTransform;
+      svgStyle.webkitTransform = svgTransform;
+    }
+  }
+};
+
+function HCameraElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initHierarchy();
+  var getProp = PropertyFactory.getProp;
+  this.pe = getProp(this, data.pe, 0, 0, this);
+  if (data.ks.p.s) {
+    this.px = getProp(this, data.ks.p.x, 1, 0, this);
+    this.py = getProp(this, data.ks.p.y, 1, 0, this);
+    this.pz = getProp(this, data.ks.p.z, 1, 0, this);
+  } else {
+    this.p = getProp(this, data.ks.p, 1, 0, this);
+  }
+  if (data.ks.a) {
+    this.a = getProp(this, data.ks.a, 1, 0, this);
+  }
+  if (data.ks.or.k.length && data.ks.or.k[0].to) {
+    var i;
+    var len = data.ks.or.k.length;
+    for (i = 0; i < len; i += 1) {
+      data.ks.or.k[i].to = null;
+      data.ks.or.k[i].ti = null;
+    }
+  }
+  this.or = getProp(this, data.ks.or, 1, degToRads, this);
+  this.or.sh = true;
+  this.rx = getProp(this, data.ks.rx, 0, degToRads, this);
+  this.ry = getProp(this, data.ks.ry, 0, degToRads, this);
+  this.rz = getProp(this, data.ks.rz, 0, degToRads, this);
+  this.mat = new Matrix();
+  this._prevMat = new Matrix();
+  this._isFirstFrame = true;
+
+  // TODO: find a better way to make the HCamera element to be compatible with the LayerInterface and TransformInterface.
+  this.finalTransform = {
+    mProp: this,
+  };
+}
+extendPrototype([BaseElement, FrameElement, HierarchyElement], HCameraElement);
+
+HCameraElement.prototype.setup = function () {
+  var i;
+  var len = this.comp.threeDElements.length;
+  var comp;
+  var perspectiveStyle;
+  var containerStyle;
+  for (i = 0; i < len; i += 1) {
+    // [perspectiveElem,container]
+    comp = this.comp.threeDElements[i];
+    if (comp.type === '3d') {
+      perspectiveStyle = comp.perspectiveElem.style;
+      containerStyle = comp.container.style;
+      var perspective = this.pe.v + 'px';
+      var origin = '0px 0px 0px';
+      var matrix = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)';
+      perspectiveStyle.perspective = perspective;
+      perspectiveStyle.webkitPerspective = perspective;
+      containerStyle.transformOrigin = origin;
+      containerStyle.mozTransformOrigin = origin;
+      containerStyle.webkitTransformOrigin = origin;
+      perspectiveStyle.transform = matrix;
+      perspectiveStyle.webkitTransform = matrix;
+    }
+  }
+};
+
+HCameraElement.prototype.createElements = function () {
+};
+
+HCameraElement.prototype.hide = function () {
+};
+
+HCameraElement.prototype.renderFrame = function () {
+  var _mdf = this._isFirstFrame;
+  var i;
+  var len;
+  if (this.hierarchy) {
+    len = this.hierarchy.length;
+    for (i = 0; i < len; i += 1) {
+      _mdf = this.hierarchy[i].finalTransform.mProp._mdf || _mdf;
+    }
+  }
+  if (_mdf || this.pe._mdf || (this.p && this.p._mdf) || (this.px && (this.px._mdf || this.py._mdf || this.pz._mdf)) || this.rx._mdf || this.ry._mdf || this.rz._mdf || this.or._mdf || (this.a && this.a._mdf)) {
+    this.mat.reset();
+
+    if (this.hierarchy) {
+      len = this.hierarchy.length - 1;
+      for (i = len; i >= 0; i -= 1) {
+        var mTransf = this.hierarchy[i].finalTransform.mProp;
+        this.mat.translate(-mTransf.p.v[0], -mTransf.p.v[1], mTransf.p.v[2]);
+        this.mat.rotateX(-mTransf.or.v[0]).rotateY(-mTransf.or.v[1]).rotateZ(mTransf.or.v[2]);
+        this.mat.rotateX(-mTransf.rx.v).rotateY(-mTransf.ry.v).rotateZ(mTransf.rz.v);
+        this.mat.scale(1 / mTransf.s.v[0], 1 / mTransf.s.v[1], 1 / mTransf.s.v[2]);
+        this.mat.translate(mTransf.a.v[0], mTransf.a.v[1], mTransf.a.v[2]);
+      }
+    }
+    if (this.p) {
+      this.mat.translate(-this.p.v[0], -this.p.v[1], this.p.v[2]);
+    } else {
+      this.mat.translate(-this.px.v, -this.py.v, this.pz.v);
+    }
+    if (this.a) {
+      var diffVector;
+      if (this.p) {
+        diffVector = [this.p.v[0] - this.a.v[0], this.p.v[1] - this.a.v[1], this.p.v[2] - this.a.v[2]];
+      } else {
+        diffVector = [this.px.v - this.a.v[0], this.py.v - this.a.v[1], this.pz.v - this.a.v[2]];
+      }
+      var mag = Math.sqrt(Math.pow(diffVector[0], 2) + Math.pow(diffVector[1], 2) + Math.pow(diffVector[2], 2));
+      // var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
+      var lookDir = [diffVector[0] / mag, diffVector[1] / mag, diffVector[2] / mag];
+      var lookLengthOnXZ = Math.sqrt(lookDir[2] * lookDir[2] + lookDir[0] * lookDir[0]);
+      var mRotationX = (Math.atan2(lookDir[1], lookLengthOnXZ));
+      var mRotationY = (Math.atan2(lookDir[0], -lookDir[2]));
+      this.mat.rotateY(mRotationY).rotateX(-mRotationX);
+    }
+    this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v);
+    this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]);
+    this.mat.translate(this.globalData.compSize.w / 2, this.globalData.compSize.h / 2, 0);
+    this.mat.translate(0, 0, this.pe.v);
+
+    var hasMatrixChanged = !this._prevMat.equals(this.mat);
+    if ((hasMatrixChanged || this.pe._mdf) && this.comp.threeDElements) {
+      len = this.comp.threeDElements.length;
+      var comp;
+      var perspectiveStyle;
+      var containerStyle;
+      for (i = 0; i < len; i += 1) {
+        comp = this.comp.threeDElements[i];
+        if (comp.type === '3d') {
+          if (hasMatrixChanged) {
+            var matValue = this.mat.toCSS();
+            containerStyle = comp.container.style;
+            containerStyle.transform = matValue;
+            containerStyle.webkitTransform = matValue;
+          }
+          if (this.pe._mdf) {
+            perspectiveStyle = comp.perspectiveElem.style;
+            perspectiveStyle.perspective = this.pe.v + 'px';
+            perspectiveStyle.webkitPerspective = this.pe.v + 'px';
+          }
+        }
+      }
+      this.mat.clone(this._prevMat);
+    }
+  }
+  this._isFirstFrame = false;
+};
+
+HCameraElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+HCameraElement.prototype.destroy = function () {
+};
+HCameraElement.prototype.getBaseElement = function () { return null; };
+
+function HImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, HBaseElement, HSolidElement, HierarchyElement, FrameElement, RenderableElement], HImageElement);
+
+HImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  var img = new Image();
+
+  if (this.data.hasMask) {
+    this.imageElem = createNS('image');
+    this.imageElem.setAttribute('width', this.assetData.w + 'px');
+    this.imageElem.setAttribute('height', this.assetData.h + 'px');
+    this.imageElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+    this.layerElement.appendChild(this.imageElem);
+    this.baseElement.setAttribute('width', this.assetData.w);
+    this.baseElement.setAttribute('height', this.assetData.h);
+  } else {
+    this.layerElement.appendChild(img);
+  }
+  img.crossOrigin = 'anonymous';
+  img.src = assetPath;
+  if (this.data.ln) {
+    this.baseElement.setAttribute('id', this.data.ln);
+  }
+};
+
+function HybridRendererBase(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),
+    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], HybridRendererBase);
+
+HybridRendererBase.prototype.buildItem = SVGRenderer.prototype.buildItem;
+
+HybridRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+  }
+};
+
+HybridRendererBase.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;
+      var nextLayer;
+      var 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);
+  }
+};
+
+HybridRendererBase.prototype.createShape = function (data) {
+  if (!this.supports3d) {
+    return new SVGShapeElement(data, this.globalData, this);
+  }
+  return new HShapeElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createText = function (data) {
+  if (!this.supports3d) {
+    return new SVGTextLottieElement(data, this.globalData, this);
+  }
+  return new HTextElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createCamera = function (data) {
+  this.camera = new HCameraElement(data, this.globalData, this);
+  return this.camera;
+};
+
+HybridRendererBase.prototype.createImage = function (data) {
+  if (!this.supports3d) {
+    return new IImageElement(data, this.globalData, this);
+  }
+  return new HImageElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createSolid = function (data) {
+  if (!this.supports3d) {
+    return new ISolidElement(data, this.globalData, this);
+  }
+  return new HSolidElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
+
+HybridRendererBase.prototype.getThreeDContainerByPos = function (pos) {
+  var i = 0;
+  var 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;
+  }
+  return null;
+};
+
+HybridRendererBase.prototype.createThreeDContainer = function (pos, type) {
+  var perspectiveElem = createTag('div');
+  var style;
+  var containerStyle;
+  styleDiv(perspectiveElem);
+  var container = createTag('div');
+  styleDiv(container);
+  if (type === '3d') {
+    style = perspectiveElem.style;
+    style.width = this.globalData.compSize.w + 'px';
+    style.height = this.globalData.compSize.h + 'px';
+    var center = '50% 50%';
+    style.webkitTransformOrigin = center;
+    style.mozTransformOrigin = center;
+    style.transformOrigin = center;
+    containerStyle = container.style;
+    var matrix = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)';
+    containerStyle.transform = matrix;
+    containerStyle.webkitTransform = matrix;
+  }
+
+  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;
+};
+
+HybridRendererBase.prototype.build3dContainers = function () {
+  var i;
+  var 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 -= 1) {
+    this.resizerElem.appendChild(this.threeDElements[i].perspectiveElem);
+  }
+};
+
+HybridRendererBase.prototype.addTo3dContainer = function (elem, pos) {
+  var i = 0;
+  var 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;
+  }
+};
+
+HybridRendererBase.prototype.configAnimation = function (animData) {
+  var resizerElem = createTag('div');
+  var wrapper = this.animationItem.wrapper;
+  var style = resizerElem.style;
+  style.width = animData.w + 'px';
+  style.height = animData.h + 'px';
+  this.resizerElem = resizerElem;
+  styleDiv(resizerElem);
+  style.transformStyle = 'flat';
+  style.mozTransformStyle = 'flat';
+  style.webkitTransformStyle = 'flat';
+  if (this.renderConfig.className) {
+    resizerElem.setAttribute('class', this.renderConfig.className);
+  }
+  wrapper.appendChild(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();
+};
+
+HybridRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.animationItem.container = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+HybridRendererBase.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;
+  var sy;
+  var tx;
+  var 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;
+  }
+  var style = this.resizerElem.style;
+  style.webkitTransform = 'matrix3d(' + sx + ',0,0,0,0,' + sy + ',0,0,0,0,1,0,' + tx + ',' + ty + ',0,1)';
+  style.transform = style.webkitTransform;
+};
+
+HybridRendererBase.prototype.renderFrame = SVGRenderer.prototype.renderFrame;
+
+HybridRendererBase.prototype.hide = function () {
+  this.resizerElem.style.display = 'none';
+};
+
+HybridRendererBase.prototype.show = function () {
+  this.resizerElem.style.display = 'block';
+};
+
+HybridRendererBase.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;
+    var len = this.threeDElements.length;
+    for (i = 0; i < len; i += 1) {
+      var style = this.threeDElements[i].perspectiveElem.style;
+      style.webkitPerspective = Math.sqrt(Math.pow(cWidth, 2) + Math.pow(cHeight, 2)) + 'px';
+      style.perspective = style.webkitPerspective;
+    }
+  }
+};
+
+HybridRendererBase.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var 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);
+    }
+  }
+};
+
+function HCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = !data.hasMask;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([HybridRendererBase, ICompElement, HBaseElement], HCompElement);
+HCompElement.prototype._createBaseContainerElements = HCompElement.prototype.createContainerElements;
+
+HCompElement.prototype.createContainerElements = function () {
+  this._createBaseContainerElements();
+  // divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
+  if (this.data.hasMask) {
+    this.svgElement.setAttribute('width', this.data.w);
+    this.svgElement.setAttribute('height', this.data.h);
+    this.transformedElement = this.baseElement;
+  } else {
+    this.transformedElement = this.layerElement;
+  }
+};
+
+HCompElement.prototype.addTo3dContainer = function (elem, pos) {
+  var j = 0;
+  var nextElement;
+  while (j < pos) {
+    if (this.elements[j] && this.elements[j].getBaseElement) {
+      nextElement = this.elements[j].getBaseElement();
+    }
+    j += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(elem, nextElement);
+  } else {
+    this.layerElement.appendChild(elem);
+  }
+};
+
+HCompElement.prototype.createComp = function (data) {
+  if (!this.supports3d) {
+    return new SVGCompElement(data, this.globalData, this);
+  }
+  return new HCompElement(data, this.globalData, this);
+};
+
+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),
+    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%',
+    },
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+  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([HybridRendererBase], HybridRenderer);
+
+HybridRenderer.prototype.createComp = function (data) {
+  if (!this.supports3d) {
+    return new SVGCompElement(data, this.globalData, this);
+  }
+  return new HCompElement(data, this.globalData, this);
+};
+
+// Registering renderers
+registerRenderer('html', HybridRenderer);
+
+// Registering shape modifiers
+ShapeModifiers.registerModifier('tm', TrimModifier);
+ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
+ShapeModifiers.registerModifier('rp', RepeaterModifier);
+ShapeModifiers.registerModifier('rd', RoundCornersModifier);
+ShapeModifiers.registerModifier('zz', ZigZagModifier);
+ShapeModifiers.registerModifier('op', OffsetPathModifier);
+
+const CompExpressionInterface = (function () {
+  return function (comp) {
+    function _thisLayerFunction(name) {
+      var i = 0;
+      var len = comp.layers.length;
+      while (i < len) {
+        if (comp.layers[i].nm === name || comp.layers[i].ind === name) {
+          return comp.elements[i].layerInterface;
+        }
+        i += 1;
+      }
+      return null;
+      // return {active:false};
+    }
+    Object.defineProperty(_thisLayerFunction, '_name', { value: comp.data.nm });
+    _thisLayerFunction.layer = _thisLayerFunction;
+    _thisLayerFunction.pixelAspect = 1;
+    _thisLayerFunction.height = comp.data.h || comp.globalData.compSize.h;
+    _thisLayerFunction.width = comp.data.w || comp.globalData.compSize.w;
+    _thisLayerFunction.pixelAspect = 1;
+    _thisLayerFunction.frameDuration = 1 / comp.globalData.frameRate;
+    _thisLayerFunction.displayStartTime = 0;
+    _thisLayerFunction.numLayers = comp.layers.length;
+    return _thisLayerFunction;
+  };
+}());
+
+/* eslint-disable */
+/*
+ Copyright 2014 David Bau.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ */
+
+function seedRandom(pool, math) {
+//
+// The following constants are related to IEEE 754 limits.
+//
+    var global = this,
+        width = 256,        // each RC4 output is 0 <= x < 256
+        chunks = 6,         // at least six RC4 outputs for each double
+        digits = 52,        // there are 52 significant digits in a double
+        rngname = 'random', // rngname: name for Math.random and Math.seedrandom
+        startdenom = math.pow(width, chunks),
+        significance = math.pow(2, digits),
+        overflow = significance * 2,
+        mask = width - 1,
+        nodecrypto;         // node.js crypto module, initialized at the bottom.
+
+//
+// seedrandom()
+// This is the seedrandom function described above.
+//
+    function seedrandom(seed, options, callback) {
+        var key = [];
+        options = (options === true) ? { entropy: true } : (options || {});
+
+        // Flatten the seed string or build one from local entropy if needed.
+        var shortseed = mixkey(flatten(
+            options.entropy ? [seed, tostring(pool)] :
+                (seed === null) ? autoseed() : seed, 3), key);
+
+        // Use the seed to initialize an ARC4 generator.
+        var arc4 = new ARC4(key);
+
+        // This function returns a random double in [0, 1) that contains
+        // randomness in every bit of the mantissa of the IEEE 754 value.
+        var prng = function() {
+            var n = arc4.g(chunks),             // Start with a numerator n < 2 ^ 48
+                d = startdenom,                 //   and denominator d = 2 ^ 48.
+                x = 0;                          //   and no 'extra last byte'.
+            while (n < significance) {          // Fill up all significant digits by
+                n = (n + x) * width;              //   shifting numerator and
+                d *= width;                       //   denominator and generating a
+                x = arc4.g(1);                    //   new least-significant-byte.
+            }
+            while (n >= overflow) {             // To avoid rounding up, before adding
+                n /= 2;                           //   last byte, shift everything
+                d /= 2;                           //   right using integer math until
+                x >>>= 1;                         //   we have exactly the desired bits.
+            }
+            return (n + x) / d;                 // Form the number within [0, 1).
+        };
+
+        prng.int32 = function() { return arc4.g(4) | 0; };
+        prng.quick = function() { return arc4.g(4) / 0x100000000; };
+        prng.double = prng;
+
+        // Mix the randomness into accumulated entropy.
+        mixkey(tostring(arc4.S), pool);
+
+        // Calling convention: what to return as a function of prng, seed, is_math.
+        return (options.pass || callback ||
+        function(prng, seed, is_math_call, state) {
+            if (state) {
+                // Load the arc4 state from the given state if it has an S array.
+                if (state.S) { copy(state, arc4); }
+                // Only provide the .state method if requested via options.state.
+                prng.state = function() { return copy(arc4, {}); };
+            }
+
+            // If called as a method of Math (Math.seedrandom()), mutate
+            // Math.random because that is how seedrandom.js has worked since v1.0.
+            if (is_math_call) { math[rngname] = prng; return seed; }
+
+            // Otherwise, it is a newer calling convention, so return the
+            // prng directly.
+            else return prng;
+        })(
+            prng,
+            shortseed,
+            'global' in options ? options.global : (this == math),
+            options.state);
+    }
+    math['seed' + rngname] = seedrandom;
+
+//
+// ARC4
+//
+// An ARC4 implementation.  The constructor takes a key in the form of
+// an array of at most (width) integers that should be 0 <= x < (width).
+//
+// The g(count) method returns a pseudorandom integer that concatenates
+// the next (count) outputs from ARC4.  Its return value is a number x
+// that is in the range 0 <= x < (width ^ count).
+//
+    function ARC4(key) {
+        var t, keylen = key.length,
+            me = this, i = 0, j = me.i = me.j = 0, s = me.S = [];
+
+        // The empty key [] is treated as [0].
+        if (!keylen) { key = [keylen++]; }
+
+        // Set up S using the standard key scheduling algorithm.
+        while (i < width) {
+            s[i] = i++;
+        }
+        for (i = 0; i < width; i++) {
+            s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))];
+            s[j] = t;
+        }
+
+        // The "g" method returns the next (count) outputs as one number.
+        me.g = function(count) {
+            // Using instance members instead of closure state nearly doubles speed.
+            var t, r = 0,
+                i = me.i, j = me.j, s = me.S;
+            while (count--) {
+                t = s[i = mask & (i + 1)];
+                r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))];
+            }
+            me.i = i; me.j = j;
+            return r;
+            // For robust unpredictability, the function call below automatically
+            // discards an initial batch of values.  This is called RC4-drop[256].
+            // See http://google.com/search?q=rsa+fluhrer+response&btnI
+        };
+    }
+
+//
+// copy()
+// Copies internal state of ARC4 to or from a plain object.
+//
+    function copy(f, t) {
+        t.i = f.i;
+        t.j = f.j;
+        t.S = f.S.slice();
+        return t;
+    }
+
+//
+// flatten()
+// Converts an object tree to nested arrays of strings.
+//
+    function flatten(obj, depth) {
+        var result = [], typ = (typeof obj), prop;
+        if (depth && typ == 'object') {
+            for (prop in obj) {
+                try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}
+            }
+        }
+        return (result.length ? result : typ == 'string' ? obj : obj + '\0');
+    }
+
+//
+// mixkey()
+// Mixes a string seed into a key that is an array of integers, and
+// returns a shortened string seed that is equivalent to the result key.
+//
+    function mixkey(seed, key) {
+        var stringseed = seed + '', smear, j = 0;
+        while (j < stringseed.length) {
+            key[mask & j] =
+                mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++));
+        }
+        return tostring(key);
+    }
+
+//
+// autoseed()
+// Returns an object for autoseeding, using window.crypto and Node crypto
+// module if available.
+//
+    function autoseed() {
+        try {
+            if (nodecrypto) { return tostring(nodecrypto.randomBytes(width)); }
+            var out = new Uint8Array(width);
+            (global.crypto || global.msCrypto).getRandomValues(out);
+            return tostring(out);
+        } catch (e) {
+            var browser = global.navigator,
+                plugins = browser && browser.plugins;
+            return [+new Date(), global, plugins, global.screen, tostring(pool)];
+        }
+    }
+
+//
+// tostring()
+// Converts an array of charcodes to a string
+//
+    function tostring(a) {
+        return String.fromCharCode.apply(0, a);
+    }
+
+//
+// When seedrandom.js is loaded, we immediately mix a few bits
+// from the built-in RNG into the entropy pool.  Because we do
+// not want to interfere with deterministic PRNG state later,
+// seedrandom will not call math.random on its own again after
+// initialization.
+//
+    mixkey(math.random(), pool);
+
+//
+// Nodejs and AMD support: export the implementation as a module using
+// either convention.
+//
+
+// End anonymous scope, and pass initial values.
+};
+
+function initialize$2(BMMath) {
+    seedRandom([], BMMath);
+}
+
+var propTypes = {
+  SHAPE: 'shape',
+};
+
+/* eslint-disable camelcase */
+
+const ExpressionManager = (function () {
+  'use strict';
+
+  var ob = {};
+  var Math = BMMath;
+  var window = null;
+  var document = null;
+  var XMLHttpRequest = null;
+  var fetch = null;
+  var frames = null;
+  var _lottieGlobal = {};
+  initialize$2(BMMath);
+
+  function resetFrame() {
+    _lottieGlobal = {};
+  }
+
+  function $bm_isInstanceOfArray(arr) {
+    return arr.constructor === Array || arr.constructor === Float32Array;
+  }
+
+  function isNumerable(tOfV, v) {
+    return tOfV === 'number' || v instanceof Number || tOfV === 'boolean' || tOfV === 'string';
+  }
+
+  function $bm_neg(a) {
+    var tOfA = typeof a;
+    if (tOfA === 'number' || a instanceof Number || tOfA === 'boolean') {
+      return -a;
+    }
+    if ($bm_isInstanceOfArray(a)) {
+      var i;
+      var lenA = a.length;
+      var retArr = [];
+      for (i = 0; i < lenA; i += 1) {
+        retArr[i] = -a[i];
+      }
+      return retArr;
+    }
+    if (a.propType) {
+      return a.v;
+    }
+    return -a;
+  }
+
+  var easeInBez = BezierFactory.getBezierEasing(0.333, 0, 0.833, 0.833, 'easeIn').get;
+  var easeOutBez = BezierFactory.getBezierEasing(0.167, 0.167, 0.667, 1, 'easeOut').get;
+  var easeInOutBez = BezierFactory.getBezierEasing(0.33, 0, 0.667, 1, 'easeInOut').get;
+
+  function sum(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    if ((isNumerable(tOfA, a) && isNumerable(tOfB, b)) || tOfA === 'string' || tOfB === 'string') {
+      return a + b;
+    }
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      a = a.slice(0);
+      a[0] += b;
+      return a;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      b = b.slice(0);
+      b[0] = a + b[0];
+      return b;
+    }
+    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
+      var i = 0;
+      var lenA = a.length;
+      var lenB = b.length;
+      var retArr = [];
+      while (i < lenA || i < lenB) {
+        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
+          retArr[i] = a[i] + b[i];
+        } else {
+          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
+        }
+        i += 1;
+      }
+      return retArr;
+    }
+    return 0;
+  }
+  var add = sum;
+
+  function sub(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      if (tOfA === 'string') {
+        a = parseInt(a, 10);
+      }
+      if (tOfB === 'string') {
+        b = parseInt(b, 10);
+      }
+      return a - b;
+    }
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      a = a.slice(0);
+      a[0] -= b;
+      return a;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      b = b.slice(0);
+      b[0] = a - b[0];
+      return b;
+    }
+    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
+      var i = 0;
+      var lenA = a.length;
+      var lenB = b.length;
+      var retArr = [];
+      while (i < lenA || i < lenB) {
+        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
+          retArr[i] = a[i] - b[i];
+        } else {
+          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
+        }
+        i += 1;
+      }
+      return retArr;
+    }
+    return 0;
+  }
+
+  function mul(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    var arr;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      return a * b;
+    }
+
+    var i;
+    var len;
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      len = a.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a[i] * b;
+      }
+      return arr;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      len = b.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a * b[i];
+      }
+      return arr;
+    }
+    return 0;
+  }
+
+  function div(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    var arr;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      return a / b;
+    }
+    var i;
+    var len;
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      len = a.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a[i] / b;
+      }
+      return arr;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      len = b.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a / b[i];
+      }
+      return arr;
+    }
+    return 0;
+  }
+  function mod(a, b) {
+    if (typeof a === 'string') {
+      a = parseInt(a, 10);
+    }
+    if (typeof b === 'string') {
+      b = parseInt(b, 10);
+    }
+    return a % b;
+  }
+  var $bm_sum = sum;
+  var $bm_sub = sub;
+  var $bm_mul = mul;
+  var $bm_div = div;
+  var $bm_mod = mod;
+
+  function clamp(num, min, max) {
+    if (min > max) {
+      var mm = max;
+      max = min;
+      min = mm;
+    }
+    return Math.min(Math.max(num, min), max);
+  }
+
+  function radiansToDegrees(val) {
+    return val / degToRads;
+  }
+  var radians_to_degrees = radiansToDegrees;
+
+  function degreesToRadians(val) {
+    return val * degToRads;
+  }
+  var degrees_to_radians = radiansToDegrees;
+
+  var helperLengthArray = [0, 0, 0, 0, 0, 0];
+
+  function length(arr1, arr2) {
+    if (typeof arr1 === 'number' || arr1 instanceof Number) {
+      arr2 = arr2 || 0;
+      return Math.abs(arr1 - arr2);
+    }
+    if (!arr2) {
+      arr2 = helperLengthArray;
+    }
+    var i;
+    var len = Math.min(arr1.length, arr2.length);
+    var addedLength = 0;
+    for (i = 0; i < len; i += 1) {
+      addedLength += Math.pow(arr2[i] - arr1[i], 2);
+    }
+    return Math.sqrt(addedLength);
+  }
+
+  function normalize(vec) {
+    return div(vec, length(vec));
+  }
+
+  function rgbToHsl(val) {
+    var r = val[0]; var g = val[1]; var b = val[2];
+    var max = Math.max(r, g, b);
+    var min = Math.min(r, g, b);
+    var h;
+    var s;
+    var l = (max + min) / 2;
+
+    if (max === min) {
+      h = 0; // achromatic
+      s = 0; // achromatic
+    } else {
+      var d = max - min;
+      s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+      switch (max) {
+        case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+        case g: h = (b - r) / d + 2; break;
+        case b: h = (r - g) / d + 4; break;
+        default: break;
+      }
+      h /= 6;
+    }
+
+    return [h, s, l, val[3]];
+  }
+
+  function hue2rgb(p, q, t) {
+    if (t < 0) t += 1;
+    if (t > 1) t -= 1;
+    if (t < 1 / 6) return p + (q - p) * 6 * t;
+    if (t < 1 / 2) return q;
+    if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
+    return p;
+  }
+
+  function hslToRgb(val) {
+    var h = val[0];
+    var s = val[1];
+    var l = val[2];
+
+    var r;
+    var g;
+    var b;
+
+    if (s === 0) {
+      r = l; // achromatic
+      b = l; // achromatic
+      g = l; // achromatic
+    } else {
+      var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+      var p = 2 * l - q;
+      r = hue2rgb(p, q, h + 1 / 3);
+      g = hue2rgb(p, q, h);
+      b = hue2rgb(p, q, h - 1 / 3);
+    }
+
+    return [r, g, b, val[3]];
+  }
+
+  function linear(t, tMin, tMax, value1, value2) {
+    if (value1 === undefined || value2 === undefined) {
+      value1 = tMin;
+      value2 = tMax;
+      tMin = 0;
+      tMax = 1;
+    }
+    if (tMax < tMin) {
+      var _tMin = tMax;
+      tMax = tMin;
+      tMin = _tMin;
+    }
+    if (t <= tMin) {
+      return value1;
+    } if (t >= tMax) {
+      return value2;
+    }
+    var perc = tMax === tMin ? 0 : (t - tMin) / (tMax - tMin);
+    if (!value1.length) {
+      return value1 + (value2 - value1) * perc;
+    }
+    var i;
+    var len = value1.length;
+    var arr = createTypedArray('float32', len);
+    for (i = 0; i < len; i += 1) {
+      arr[i] = value1[i] + (value2[i] - value1[i]) * perc;
+    }
+    return arr;
+  }
+  function random(min, max) {
+    if (max === undefined) {
+      if (min === undefined) {
+        min = 0;
+        max = 1;
+      } else {
+        max = min;
+        min = undefined;
+      }
+    }
+    if (max.length) {
+      var i;
+      var len = max.length;
+      if (!min) {
+        min = createTypedArray('float32', len);
+      }
+      var arr = createTypedArray('float32', len);
+      var rnd = BMMath.random();
+      for (i = 0; i < len; i += 1) {
+        arr[i] = min[i] + rnd * (max[i] - min[i]);
+      }
+      return arr;
+    }
+    if (min === undefined) {
+      min = 0;
+    }
+    var rndm = BMMath.random();
+    return min + rndm * (max - min);
+  }
+
+  function createPath(points, inTangents, outTangents, closed) {
+    var i;
+    var len = points.length;
+    var path = shapePool.newElement();
+    path.setPathData(!!closed, len);
+    var arrPlaceholder = [0, 0];
+    var inVertexPoint;
+    var outVertexPoint;
+    for (i = 0; i < len; i += 1) {
+      inVertexPoint = (inTangents && inTangents[i]) ? inTangents[i] : arrPlaceholder;
+      outVertexPoint = (outTangents && outTangents[i]) ? outTangents[i] : arrPlaceholder;
+      path.setTripleAt(points[i][0], points[i][1], outVertexPoint[0] + points[i][0], outVertexPoint[1] + points[i][1], inVertexPoint[0] + points[i][0], inVertexPoint[1] + points[i][1], i, true);
+    }
+    return path;
+  }
+
+  function initiateExpression(elem, data, property) {
+    // Bail out if we don't want expressions
+    function noOp(_value) {
+      return _value;
+    }
+    if (!elem.globalData.renderConfig.runExpressions) {
+      return noOp;
+    }
+
+    var val = data.x;
+    var needsVelocity = /velocity(?![\w\d])/.test(val);
+    var _needsRandom = val.indexOf('random') !== -1;
+    var elemType = elem.data.ty;
+    var transform;
+    var $bm_transform;
+    var content;
+    var effect;
+    var thisProperty = property;
+    thisProperty._name = elem.data.nm;
+    thisProperty.valueAtTime = thisProperty.getValueAtTime;
+    Object.defineProperty(thisProperty, 'value', {
+      get: function () {
+        return thisProperty.v;
+      },
+    });
+    elem.comp.frameDuration = 1 / elem.comp.globalData.frameRate;
+    elem.comp.displayStartTime = 0;
+    var inPoint = elem.data.ip / elem.comp.globalData.frameRate;
+    var outPoint = elem.data.op / elem.comp.globalData.frameRate;
+    var width = elem.data.sw ? elem.data.sw : 0;
+    var height = elem.data.sh ? elem.data.sh : 0;
+    var name = elem.data.nm;
+    var loopIn;
+    var loop_in;
+    var loopOut;
+    var loop_out;
+    var smooth;
+    var toWorld;
+    var fromWorld;
+    var fromComp;
+    var toComp;
+    var fromCompToSurface;
+    var position;
+    var rotation;
+    var anchorPoint;
+    var scale;
+    var thisLayer;
+    var thisComp;
+    var mask;
+    var valueAtTime;
+    var velocityAtTime;
+
+    var scoped_bm_rt;
+    // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
+    var expression_function = eval('[function _expression_function(){' + val + ';scoped_bm_rt=$bm_rt}]')[0]; // eslint-disable-line no-eval
+    var numKeys = property.kf ? data.k.length : 0;
+
+    var active = !this.data || this.data.hd !== true;
+
+    var wiggle = function wiggle(freq, amp) {
+      var iWiggle;
+      var j;
+      var lenWiggle = this.pv.length ? this.pv.length : 1;
+      var addedAmps = createTypedArray('float32', lenWiggle);
+      freq = 5;
+      var iterations = Math.floor(time * freq);
+      iWiggle = 0;
+      j = 0;
+      while (iWiggle < iterations) {
+        // var rnd = BMMath.random();
+        for (j = 0; j < lenWiggle; j += 1) {
+          addedAmps[j] += -amp + amp * 2 * BMMath.random();
+          // addedAmps[j] += -amp + amp*2*rnd;
+        }
+        iWiggle += 1;
+      }
+      // var rnd2 = BMMath.random();
+      var periods = time * freq;
+      var perc = periods - Math.floor(periods);
+      var arr = createTypedArray('float32', lenWiggle);
+      if (lenWiggle > 1) {
+        for (j = 0; j < lenWiggle; j += 1) {
+          arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc;
+          // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
+          // arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc);
+        }
+        return arr;
+      }
+      return this.pv + addedAmps[0] + (-amp + amp * 2 * BMMath.random()) * perc;
+    }.bind(this);
+
+    if (thisProperty.loopIn) {
+      loopIn = thisProperty.loopIn.bind(thisProperty);
+      loop_in = loopIn;
+    }
+
+    if (thisProperty.loopOut) {
+      loopOut = thisProperty.loopOut.bind(thisProperty);
+      loop_out = loopOut;
+    }
+
+    if (thisProperty.smooth) {
+      smooth = thisProperty.smooth.bind(thisProperty);
+    }
+
+    function loopInDuration(type, duration) {
+      return loopIn(type, duration, true);
+    }
+
+    function loopOutDuration(type, duration) {
+      return loopOut(type, duration, true);
+    }
+
+    if (this.getValueAtTime) {
+      valueAtTime = this.getValueAtTime.bind(this);
+    }
+
+    if (this.getVelocityAtTime) {
+      velocityAtTime = this.getVelocityAtTime.bind(this);
+    }
+
+    var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface);
+
+    function lookAt(elem1, elem2) {
+      var fVec = [elem2[0] - elem1[0], elem2[1] - elem1[1], elem2[2] - elem1[2]];
+      var pitch = Math.atan2(fVec[0], Math.sqrt(fVec[1] * fVec[1] + fVec[2] * fVec[2])) / degToRads;
+      var yaw = -Math.atan2(fVec[1], fVec[2]) / degToRads;
+      return [yaw, pitch, 0];
+    }
+
+    function easeOut(t, tMin, tMax, val1, val2) {
+      return applyEase(easeOutBez, t, tMin, tMax, val1, val2);
+    }
+
+    function easeIn(t, tMin, tMax, val1, val2) {
+      return applyEase(easeInBez, t, tMin, tMax, val1, val2);
+    }
+
+    function ease(t, tMin, tMax, val1, val2) {
+      return applyEase(easeInOutBez, t, tMin, tMax, val1, val2);
+    }
+
+    function applyEase(fn, t, tMin, tMax, val1, val2) {
+      if (val1 === undefined) {
+        val1 = tMin;
+        val2 = tMax;
+      } else {
+        t = (t - tMin) / (tMax - tMin);
+      }
+      if (t > 1) {
+        t = 1;
+      } else if (t < 0) {
+        t = 0;
+      }
+      var mult = fn(t);
+      if ($bm_isInstanceOfArray(val1)) {
+        var iKey;
+        var lenKey = val1.length;
+        var arr = createTypedArray('float32', lenKey);
+        for (iKey = 0; iKey < lenKey; iKey += 1) {
+          arr[iKey] = (val2[iKey] - val1[iKey]) * mult + val1[iKey];
+        }
+        return arr;
+      }
+      return (val2 - val1) * mult + val1;
+    }
+
+    function nearestKey(time) {
+      var iKey;
+      var lenKey = data.k.length;
+      var index;
+      var keyTime;
+      if (!data.k.length || typeof (data.k[0]) === 'number') {
+        index = 0;
+        keyTime = 0;
+      } else {
+        index = -1;
+        time *= elem.comp.globalData.frameRate;
+        if (time < data.k[0].t) {
+          index = 1;
+          keyTime = data.k[0].t;
+        } else {
+          for (iKey = 0; iKey < lenKey - 1; iKey += 1) {
+            if (time === data.k[iKey].t) {
+              index = iKey + 1;
+              keyTime = data.k[iKey].t;
+              break;
+            } else if (time > data.k[iKey].t && time < data.k[iKey + 1].t) {
+              if (time - data.k[iKey].t > data.k[iKey + 1].t - time) {
+                index = iKey + 2;
+                keyTime = data.k[iKey + 1].t;
+              } else {
+                index = iKey + 1;
+                keyTime = data.k[iKey].t;
+              }
+              break;
+            }
+          }
+          if (index === -1) {
+            index = iKey + 1;
+            keyTime = data.k[iKey].t;
+          }
+        }
+      }
+      var obKey = {};
+      obKey.index = index;
+      obKey.time = keyTime / elem.comp.globalData.frameRate;
+      return obKey;
+    }
+
+    function key(ind) {
+      var obKey;
+      var iKey;
+      var lenKey;
+      if (!data.k.length || typeof (data.k[0]) === 'number') {
+        throw new Error('The property has no keyframe at index ' + ind);
+      }
+      ind -= 1;
+      obKey = {
+        time: data.k[ind].t / elem.comp.globalData.frameRate,
+        value: [],
+      };
+      var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e;
+
+      lenKey = arr.length;
+      for (iKey = 0; iKey < lenKey; iKey += 1) {
+        obKey[iKey] = arr[iKey];
+        obKey.value[iKey] = arr[iKey];
+      }
+      return obKey;
+    }
+
+    function framesToTime(fr, fps) {
+      if (!fps) {
+        fps = elem.comp.globalData.frameRate;
+      }
+      return fr / fps;
+    }
+
+    function timeToFrames(t, fps) {
+      if (!t && t !== 0) {
+        t = time;
+      }
+      if (!fps) {
+        fps = elem.comp.globalData.frameRate;
+      }
+      return t * fps;
+    }
+
+    function seedRandom(seed) {
+      BMMath.seedrandom(randSeed + seed);
+    }
+
+    function sourceRectAtTime() {
+      return elem.sourceRectAtTime();
+    }
+
+    function substring(init, end) {
+      if (typeof value === 'string') {
+        if (end === undefined) {
+          return value.substring(init);
+        }
+        return value.substring(init, end);
+      }
+      return '';
+    }
+
+    function substr(init, end) {
+      if (typeof value === 'string') {
+        if (end === undefined) {
+          return value.substr(init);
+        }
+        return value.substr(init, end);
+      }
+      return '';
+    }
+
+    function posterizeTime(framesPerSecond) {
+      time = framesPerSecond === 0 ? 0 : Math.floor(time * framesPerSecond) / framesPerSecond;
+      value = valueAtTime(time);
+    }
+
+    var time;
+    var velocity;
+    var value;
+    var text;
+    var textIndex;
+    var textTotal;
+    var selectorValue;
+    var index = elem.data.ind;
+    var hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+    var parent;
+    var randSeed = Math.floor(Math.random() * 1000000);
+    var globalData = elem.globalData;
+
+    function executeExpression(_value) {
+      // globalData.pushExpression();
+      value = _value;
+      if (this.frameExpressionId === elem.globalData.frameId && this.propType !== 'textSelector') {
+        return value;
+      }
+      if (this.propType === 'textSelector') {
+        textIndex = this.textIndex;
+        textTotal = this.textTotal;
+        selectorValue = this.selectorValue;
+      }
+      if (!thisLayer) {
+        text = elem.layerInterface.text;
+        thisLayer = elem.layerInterface;
+        thisComp = elem.comp.compInterface;
+        toWorld = thisLayer.toWorld.bind(thisLayer);
+        fromWorld = thisLayer.fromWorld.bind(thisLayer);
+        fromComp = thisLayer.fromComp.bind(thisLayer);
+        toComp = thisLayer.toComp.bind(thisLayer);
+        mask = thisLayer.mask ? thisLayer.mask.bind(thisLayer) : null;
+        fromCompToSurface = fromComp;
+      }
+      if (!transform) {
+        transform = elem.layerInterface('ADBE Transform Group');
+        $bm_transform = transform;
+        if (transform) {
+          anchorPoint = transform.anchorPoint;
+          /* position = transform.position;
+                    rotation = transform.rotation;
+                    scale = transform.scale; */
+        }
+      }
+
+      if (elemType === 4 && !content) {
+        content = thisLayer('ADBE Root Vectors Group');
+      }
+      if (!effect) {
+        effect = thisLayer(4);
+      }
+      hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+      if (hasParent && !parent) {
+        parent = elem.hierarchy[0].layerInterface;
+      }
+      time = this.comp.renderedFrame / this.comp.globalData.frameRate;
+      if (_needsRandom) {
+        seedRandom(randSeed + time);
+      }
+      if (needsVelocity) {
+        velocity = velocityAtTime(time);
+      }
+      expression_function();
+      this.frameExpressionId = elem.globalData.frameId;
+
+      // TODO: Check if it's possible to return on ShapeInterface the .v value
+      // Changed this to a ternary operation because Rollup failed compiling it correctly
+      scoped_bm_rt = scoped_bm_rt.propType === propTypes.SHAPE
+        ? scoped_bm_rt.v
+        : scoped_bm_rt;
+      return scoped_bm_rt;
+    }
+    // Bundlers will see these as dead code and unless we reference them
+    executeExpression.__preventDeadCodeRemoval = [$bm_transform, anchorPoint, time, velocity, inPoint, outPoint, width, height, name, loop_in, loop_out, smooth, toComp, fromCompToSurface, toWorld, fromWorld, mask, position, rotation, scale, thisComp, numKeys, active, wiggle, loopInDuration, loopOutDuration, comp, lookAt, easeOut, easeIn, ease, nearestKey, key, text, textIndex, textTotal, selectorValue, framesToTime, timeToFrames, sourceRectAtTime, substring, substr, posterizeTime, index, globalData];
+    return executeExpression;
+  }
+
+  ob.initiateExpression = initiateExpression;
+  ob.__preventDeadCodeRemoval = [window, document, XMLHttpRequest, fetch, frames, $bm_neg, add, $bm_sum, $bm_sub, $bm_mul, $bm_div, $bm_mod, clamp, radians_to_degrees, degreesToRadians, degrees_to_radians, normalize, rgbToHsl, hslToRgb, linear, random, createPath, _lottieGlobal];
+  ob.resetFrame = resetFrame;
+  return ob;
+}());
+
+const Expressions = (function () {
+  var ob = {};
+  ob.initExpressions = initExpressions;
+  ob.resetFrame = ExpressionManager.resetFrame;
+
+  function initExpressions(animation) {
+    var stackCount = 0;
+    var registers = [];
+
+    function pushExpression() {
+      stackCount += 1;
+    }
+
+    function popExpression() {
+      stackCount -= 1;
+      if (stackCount === 0) {
+        releaseInstances();
+      }
+    }
+
+    function registerExpressionProperty(expression) {
+      if (registers.indexOf(expression) === -1) {
+        registers.push(expression);
+      }
+    }
+
+    function releaseInstances() {
+      var i;
+      var len = registers.length;
+      for (i = 0; i < len; i += 1) {
+        registers[i].release();
+      }
+      registers.length = 0;
+    }
+
+    animation.renderer.compInterface = CompExpressionInterface(animation.renderer);
+    animation.renderer.globalData.projectInterface.registerComposition(animation.renderer);
+    animation.renderer.globalData.pushExpression = pushExpression;
+    animation.renderer.globalData.popExpression = popExpression;
+    animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty;
+  }
+  return ob;
+}());
+
+const MaskManagerInterface = (function () {
+  function MaskInterface(mask, data) {
+    this._mask = mask;
+    this._data = data;
+  }
+  Object.defineProperty(MaskInterface.prototype, 'maskPath', {
+    get: function () {
+      if (this._mask.prop.k) {
+        this._mask.prop.getValue();
+      }
+      return this._mask.prop;
+    },
+  });
+  Object.defineProperty(MaskInterface.prototype, 'maskOpacity', {
+    get: function () {
+      if (this._mask.op.k) {
+        this._mask.op.getValue();
+      }
+      return this._mask.op.v * 100;
+    },
+  });
+
+  var MaskManager = function (maskManager) {
+    var _masksInterfaces = createSizedArray(maskManager.viewData.length);
+    var i;
+    var len = maskManager.viewData.length;
+    for (i = 0; i < len; i += 1) {
+      _masksInterfaces[i] = new MaskInterface(maskManager.viewData[i], maskManager.masksProperties[i]);
+    }
+
+    var maskFunction = function (name) {
+      i = 0;
+      while (i < len) {
+        if (maskManager.masksProperties[i].nm === name) {
+          return _masksInterfaces[i];
+        }
+        i += 1;
+      }
+      return null;
+    };
+    return maskFunction;
+  };
+  return MaskManager;
+}());
+
+const ExpressionPropertyInterface = (function () {
+  var defaultUnidimensionalValue = { pv: 0, v: 0, mult: 1 };
+  var defaultMultidimensionalValue = { pv: [0, 0, 0], v: [0, 0, 0], mult: 1 };
+
+  function completeProperty(expressionValue, property, type) {
+    Object.defineProperty(expressionValue, 'velocity', {
+      get: function () {
+        return property.getVelocityAtTime(property.comp.currentFrame);
+      },
+    });
+    expressionValue.numKeys = property.keyframes ? property.keyframes.length : 0;
+    expressionValue.key = function (pos) {
+      if (!expressionValue.numKeys) {
+        return 0;
+      }
+      var value = '';
+      if ('s' in property.keyframes[pos - 1]) {
+        value = property.keyframes[pos - 1].s;
+      } else if ('e' in property.keyframes[pos - 2]) {
+        value = property.keyframes[pos - 2].e;
+      } else {
+        value = property.keyframes[pos - 2].s;
+      }
+      var valueProp = type === 'unidimensional' ? new Number(value) : Object.assign({}, value); // eslint-disable-line no-new-wrappers
+      valueProp.time = property.keyframes[pos - 1].t / property.elem.comp.globalData.frameRate;
+      valueProp.value = type === 'unidimensional' ? value[0] : value;
+      return valueProp;
+    };
+    expressionValue.valueAtTime = property.getValueAtTime;
+    expressionValue.speedAtTime = property.getSpeedAtTime;
+    expressionValue.velocityAtTime = property.getVelocityAtTime;
+    expressionValue.propertyGroup = property.propertyGroup;
+  }
+
+  function UnidimensionalPropertyInterface(property) {
+    if (!property || !('pv' in property)) {
+      property = defaultUnidimensionalValue;
+    }
+    var mult = 1 / property.mult;
+    var val = property.pv * mult;
+    var expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
+    expressionValue.value = val;
+    completeProperty(expressionValue, property, 'unidimensional');
+
+    return function () {
+      if (property.k) {
+        property.getValue();
+      }
+      val = property.v * mult;
+      if (expressionValue.value !== val) {
+        expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
+        expressionValue.value = val;
+        expressionValue[0] = val;
+        completeProperty(expressionValue, property, 'unidimensional');
+      }
+      return expressionValue;
+    };
+  }
+
+  function MultidimensionalPropertyInterface(property) {
+    if (!property || !('pv' in property)) {
+      property = defaultMultidimensionalValue;
+    }
+    var mult = 1 / property.mult;
+    var len = (property.data && property.data.l) || property.pv.length;
+    var expressionValue = createTypedArray('float32', len);
+    var arrValue = createTypedArray('float32', len);
+    expressionValue.value = arrValue;
+    completeProperty(expressionValue, property, 'multidimensional');
+
+    return function () {
+      if (property.k) {
+        property.getValue();
+      }
+      for (var i = 0; i < len; i += 1) {
+        arrValue[i] = property.v[i] * mult;
+        expressionValue[i] = arrValue[i];
+      }
+      return expressionValue;
+    };
+  }
+
+  // TODO: try to avoid using this getter
+  function defaultGetter() {
+    return defaultUnidimensionalValue;
+  }
+
+  return function (property) {
+    if (!property) {
+      return defaultGetter;
+    } if (property.propType === 'unidimensional') {
+      return UnidimensionalPropertyInterface(property);
+    }
+    return MultidimensionalPropertyInterface(property);
+  };
+}());
+
+const TransformExpressionInterface = (function () {
+  return function (transform) {
+    function _thisFunction(name) {
+      switch (name) {
+        case 'scale':
+        case 'Scale':
+        case 'ADBE Scale':
+        case 6:
+          return _thisFunction.scale;
+        case 'rotation':
+        case 'Rotation':
+        case 'ADBE Rotation':
+        case 'ADBE Rotate Z':
+        case 10:
+          return _thisFunction.rotation;
+        case 'ADBE Rotate X':
+          return _thisFunction.xRotation;
+        case 'ADBE Rotate Y':
+          return _thisFunction.yRotation;
+        case 'position':
+        case 'Position':
+        case 'ADBE Position':
+        case 2:
+          return _thisFunction.position;
+        case 'ADBE Position_0':
+          return _thisFunction.xPosition;
+        case 'ADBE Position_1':
+          return _thisFunction.yPosition;
+        case 'ADBE Position_2':
+          return _thisFunction.zPosition;
+        case 'anchorPoint':
+        case 'AnchorPoint':
+        case 'Anchor Point':
+        case 'ADBE AnchorPoint':
+        case 1:
+          return _thisFunction.anchorPoint;
+        case 'opacity':
+        case 'Opacity':
+        case 11:
+          return _thisFunction.opacity;
+        default:
+          return null;
+      }
+    }
+    Object.defineProperty(_thisFunction, 'rotation', {
+      get: ExpressionPropertyInterface(transform.r || transform.rz),
+    });
+
+    Object.defineProperty(_thisFunction, 'zRotation', {
+      get: ExpressionPropertyInterface(transform.rz || transform.r),
+    });
+
+    Object.defineProperty(_thisFunction, 'xRotation', {
+      get: ExpressionPropertyInterface(transform.rx),
+    });
+
+    Object.defineProperty(_thisFunction, 'yRotation', {
+      get: ExpressionPropertyInterface(transform.ry),
+    });
+    Object.defineProperty(_thisFunction, 'scale', {
+      get: ExpressionPropertyInterface(transform.s),
+    });
+    var _px;
+    var _py;
+    var _pz;
+    var _transformFactory;
+    if (transform.p) {
+      _transformFactory = ExpressionPropertyInterface(transform.p);
+    } else {
+      _px = ExpressionPropertyInterface(transform.px);
+      _py = ExpressionPropertyInterface(transform.py);
+      if (transform.pz) {
+        _pz = ExpressionPropertyInterface(transform.pz);
+      }
+    }
+    Object.defineProperty(_thisFunction, 'position', {
+      get: function () {
+        if (transform.p) {
+          return _transformFactory();
+        }
+        return [
+          _px(),
+          _py(),
+          _pz ? _pz() : 0];
+      },
+    });
+
+    Object.defineProperty(_thisFunction, 'xPosition', {
+      get: ExpressionPropertyInterface(transform.px),
+    });
+
+    Object.defineProperty(_thisFunction, 'yPosition', {
+      get: ExpressionPropertyInterface(transform.py),
+    });
+
+    Object.defineProperty(_thisFunction, 'zPosition', {
+      get: ExpressionPropertyInterface(transform.pz),
+    });
+
+    Object.defineProperty(_thisFunction, 'anchorPoint', {
+      get: ExpressionPropertyInterface(transform.a),
+    });
+
+    Object.defineProperty(_thisFunction, 'opacity', {
+      get: ExpressionPropertyInterface(transform.o),
+    });
+
+    Object.defineProperty(_thisFunction, 'skew', {
+      get: ExpressionPropertyInterface(transform.sk),
+    });
+
+    Object.defineProperty(_thisFunction, 'skewAxis', {
+      get: ExpressionPropertyInterface(transform.sa),
+    });
+
+    Object.defineProperty(_thisFunction, 'orientation', {
+      get: ExpressionPropertyInterface(transform.or),
+    });
+
+    return _thisFunction;
+  };
+}());
+
+const LayerExpressionInterface = (function () {
+  function getMatrix(time) {
+    var toWorldMat = new Matrix();
+    if (time !== undefined) {
+      var propMatrix = this._elem.finalTransform.mProp.getValueAtTime(time);
+      propMatrix.clone(toWorldMat);
+    } else {
+      var transformMat = this._elem.finalTransform.mProp;
+      transformMat.applyToMatrix(toWorldMat);
+    }
+    return toWorldMat;
+  }
+
+  function toWorldVec(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    toWorldMat.props[12] = 0;
+    toWorldMat.props[13] = 0;
+    toWorldMat.props[14] = 0;
+    return this.applyPoint(toWorldMat, arr);
+  }
+
+  function toWorld(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    return this.applyPoint(toWorldMat, arr);
+  }
+
+  function fromWorldVec(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    toWorldMat.props[12] = 0;
+    toWorldMat.props[13] = 0;
+    toWorldMat.props[14] = 0;
+    return this.invertPoint(toWorldMat, arr);
+  }
+
+  function fromWorld(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    return this.invertPoint(toWorldMat, arr);
+  }
+
+  function applyPoint(matrix, arr) {
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
+      }
+    }
+    return matrix.applyToPointArray(arr[0], arr[1], arr[2] || 0);
+  }
+
+  function invertPoint(matrix, arr) {
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
+      }
+    }
+    return matrix.inversePoint(arr);
+  }
+
+  function fromComp(arr) {
+    var toWorldMat = new Matrix();
+    toWorldMat.reset();
+    this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
+      }
+      return toWorldMat.inversePoint(arr);
+    }
+    return toWorldMat.inversePoint(arr);
+  }
+
+  function sampleImage() {
+    return [1, 1, 1, 1];
+  }
+
+  return function (elem) {
+    var transformInterface;
+
+    function _registerMaskInterface(maskManager) {
+      _thisLayerFunction.mask = new MaskManagerInterface(maskManager, elem);
+    }
+    function _registerEffectsInterface(effects) {
+      _thisLayerFunction.effect = effects;
+    }
+
+    function _thisLayerFunction(name) {
+      switch (name) {
+        case 'ADBE Root Vectors Group':
+        case 'Contents':
+        case 2:
+          return _thisLayerFunction.shapeInterface;
+        case 1:
+        case 6:
+        case 'Transform':
+        case 'transform':
+        case 'ADBE Transform Group':
+          return transformInterface;
+        case 4:
+        case 'ADBE Effect Parade':
+        case 'effects':
+        case 'Effects':
+          return _thisLayerFunction.effect;
+        case 'ADBE Text Properties':
+          return _thisLayerFunction.textInterface;
+        default:
+          return null;
+      }
+    }
+    _thisLayerFunction.getMatrix = getMatrix;
+    _thisLayerFunction.invertPoint = invertPoint;
+    _thisLayerFunction.applyPoint = applyPoint;
+    _thisLayerFunction.toWorld = toWorld;
+    _thisLayerFunction.toWorldVec = toWorldVec;
+    _thisLayerFunction.fromWorld = fromWorld;
+    _thisLayerFunction.fromWorldVec = fromWorldVec;
+    _thisLayerFunction.toComp = toWorld;
+    _thisLayerFunction.fromComp = fromComp;
+    _thisLayerFunction.sampleImage = sampleImage;
+    _thisLayerFunction.sourceRectAtTime = elem.sourceRectAtTime.bind(elem);
+    _thisLayerFunction._elem = elem;
+    transformInterface = TransformExpressionInterface(elem.finalTransform.mProp);
+    var anchorPointDescriptor = getDescriptor(transformInterface, 'anchorPoint');
+    Object.defineProperties(_thisLayerFunction, {
+      hasParent: {
+        get: function () {
+          return elem.hierarchy.length;
+        },
+      },
+      parent: {
+        get: function () {
+          return elem.hierarchy[0].layerInterface;
+        },
+      },
+      rotation: getDescriptor(transformInterface, 'rotation'),
+      scale: getDescriptor(transformInterface, 'scale'),
+      position: getDescriptor(transformInterface, 'position'),
+      opacity: getDescriptor(transformInterface, 'opacity'),
+      anchorPoint: anchorPointDescriptor,
+      anchor_point: anchorPointDescriptor,
+      transform: {
+        get: function () {
+          return transformInterface;
+        },
+      },
+      active: {
+        get: function () {
+          return elem.isInRange;
+        },
+      },
+    });
+
+    _thisLayerFunction.startTime = elem.data.st;
+    _thisLayerFunction.index = elem.data.ind;
+    _thisLayerFunction.source = elem.data.refId;
+    _thisLayerFunction.height = elem.data.ty === 0 ? elem.data.h : 100;
+    _thisLayerFunction.width = elem.data.ty === 0 ? elem.data.w : 100;
+    _thisLayerFunction.inPoint = elem.data.ip / elem.comp.globalData.frameRate;
+    _thisLayerFunction.outPoint = elem.data.op / elem.comp.globalData.frameRate;
+    _thisLayerFunction._name = elem.data.nm;
+
+    _thisLayerFunction.registerMaskInterface = _registerMaskInterface;
+    _thisLayerFunction.registerEffectsInterface = _registerEffectsInterface;
+    return _thisLayerFunction;
+  };
+}());
+
+const propertyGroupFactory = (function () {
+  return function (interfaceFunction, parentPropertyGroup) {
+    return function (val) {
+      val = val === undefined ? 1 : val;
+      if (val <= 0) {
+        return interfaceFunction;
+      }
+      return parentPropertyGroup(val - 1);
+    };
+  };
+}());
+
+const PropertyInterface = (function () {
+  return function (propertyName, propertyGroup) {
+    var interfaceFunction = {
+      _name: propertyName,
+    };
+
+    function _propertyGroup(val) {
+      val = val === undefined ? 1 : val;
+      if (val <= 0) {
+        return interfaceFunction;
+      }
+      return propertyGroup(val - 1);
+    }
+
+    return _propertyGroup;
+  };
+}());
+
+const EffectsExpressionInterface = (function () {
+  var ob = {
+    createEffectsInterface: createEffectsInterface,
+  };
+
+  function createEffectsInterface(elem, propertyGroup) {
+    if (elem.effectsManager) {
+      var effectElements = [];
+      var effectsData = elem.data.ef;
+      var i;
+      var len = elem.effectsManager.effectElements.length;
+      for (i = 0; i < len; i += 1) {
+        effectElements.push(createGroupInterface(effectsData[i], elem.effectsManager.effectElements[i], propertyGroup, elem));
+      }
+
+      var effects = elem.data.ef || [];
+      var groupInterface = function (name) {
+        i = 0;
+        len = effects.length;
+        while (i < len) {
+          if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
+            return effectElements[i];
+          }
+          i += 1;
+        }
+        return null;
+      };
+      Object.defineProperty(groupInterface, 'numProperties', {
+        get: function () {
+          return effects.length;
+        },
+      });
+      return groupInterface;
+    }
+    return null;
+  }
+
+  function createGroupInterface(data, elements, propertyGroup, elem) {
+    function groupInterface(name) {
+      var effects = data.ef;
+      var i = 0;
+      var len = effects.length;
+      while (i < len) {
+        if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
+          if (effects[i].ty === 5) {
+            return effectElements[i];
+          }
+          return effectElements[i]();
+        }
+        i += 1;
+      }
+      throw new Error();
+    }
+    var _propertyGroup = propertyGroupFactory(groupInterface, propertyGroup);
+
+    var effectElements = [];
+    var i;
+    var len = data.ef.length;
+    for (i = 0; i < len; i += 1) {
+      if (data.ef[i].ty === 5) {
+        effectElements.push(createGroupInterface(data.ef[i], elements.effectElements[i], elements.effectElements[i].propertyGroup, elem));
+      } else {
+        effectElements.push(createValueInterface(elements.effectElements[i], data.ef[i].ty, elem, _propertyGroup));
+      }
+    }
+
+    if (data.mn === 'ADBE Color Control') {
+      Object.defineProperty(groupInterface, 'color', {
+        get: function () {
+          return effectElements[0]();
+        },
+      });
+    }
+    Object.defineProperties(groupInterface, {
+      numProperties: {
+        get: function () {
+          return data.np;
+        },
+      },
+      _name: { value: data.nm },
+      propertyGroup: { value: _propertyGroup },
+    });
+    groupInterface.enabled = data.en !== 0;
+    groupInterface.active = groupInterface.enabled;
+    return groupInterface;
+  }
+
+  function createValueInterface(element, type, elem, propertyGroup) {
+    var expressionProperty = ExpressionPropertyInterface(element.p);
+    function interfaceFunction() {
+      if (type === 10) {
+        return elem.comp.compInterface(element.p.v);
+      }
+      return expressionProperty();
+    }
+
+    if (element.p.setGroupProperty) {
+      element.p.setGroupProperty(PropertyInterface('', propertyGroup));
+    }
+
+    return interfaceFunction;
+  }
+
+  return ob;
+}());
+
+const ShapePathInterface = (
+
+  function () {
+    return function pathInterfaceFactory(shape, view, propertyGroup) {
+      var prop = view.sh;
+
+      function interfaceFunction(val) {
+        if (val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2) {
+          return interfaceFunction.path;
+        }
+        return null;
+      }
+
+      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+      prop.setGroupProperty(PropertyInterface('Path', _propertyGroup));
+      Object.defineProperties(interfaceFunction, {
+        path: {
+          get: function () {
+            if (prop.k) {
+              prop.getValue();
+            }
+            return prop;
+          },
+        },
+        shape: {
+          get: function () {
+            if (prop.k) {
+              prop.getValue();
+            }
+            return prop;
+          },
+        },
+        _name: { value: shape.nm },
+        ix: { value: shape.ix },
+        propertyIndex: { value: shape.ix },
+        mn: { value: shape.mn },
+        propertyGroup: { value: propertyGroup },
+      });
+      return interfaceFunction;
+    };
+  }()
+);
+
+const ShapeExpressionInterface = (function () {
+  function iterateElements(shapes, view, propertyGroup) {
+    var arr = [];
+    var i;
+    var len = shapes ? shapes.length : 0;
+    for (i = 0; i < len; i += 1) {
+      if (shapes[i].ty === 'gr') {
+        arr.push(groupInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'fl') {
+        arr.push(fillInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'st') {
+        arr.push(strokeInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'tm') {
+        arr.push(trimInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'tr') {
+        // arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
+      } else if (shapes[i].ty === 'el') {
+        arr.push(ellipseInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'sr') {
+        arr.push(starInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'sh') {
+        arr.push(ShapePathInterface(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'rc') {
+        arr.push(rectInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'rd') {
+        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;
+  }
+
+  function contentsInterfaceFactory(shape, view, propertyGroup) {
+    var interfaces;
+    var interfaceFunction = function _interfaceFunction(value) {
+      var i = 0;
+      var len = interfaces.length;
+      while (i < len) {
+        if (interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value) {
+          return interfaces[i];
+        }
+        i += 1;
+      }
+      if (typeof value === 'number') {
+        return interfaces[value - 1];
+      }
+      return null;
+    };
+
+    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup);
+    interfaceFunction.numProperties = interfaces.length;
+    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
+    interfaceFunction.transform = transformInterface;
+    interfaceFunction.propertyIndex = shape.cix;
+    interfaceFunction._name = shape.nm;
+
+    return interfaceFunction;
+  }
+
+  function groupInterfaceFactory(shape, view, propertyGroup) {
+    var interfaceFunction = function _interfaceFunction(value) {
+      switch (value) {
+        case 'ADBE Vectors Group':
+        case 'Contents':
+        case 2:
+          return interfaceFunction.content;
+          // Not necessary for now. Keeping them here in case a new case appears
+          // case 'ADBE Vector Transform Group':
+          // case 3:
+        default:
+          return interfaceFunction.transform;
+      }
+    };
+    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var content = contentsInterfaceFactory(shape, view, interfaceFunction.propertyGroup);
+    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
+    interfaceFunction.content = content;
+    interfaceFunction.transform = transformInterface;
+    Object.defineProperty(interfaceFunction, '_name', {
+      get: function () {
+        return shape.nm;
+      },
+    });
+    // interfaceFunction.content = interfaceFunction;
+    interfaceFunction.numProperties = shape.np;
+    interfaceFunction.propertyIndex = shape.ix;
+    interfaceFunction.nm = shape.nm;
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function fillInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      if (val === 'Color' || val === 'color') {
+        return interfaceFunction.color;
+      } if (val === 'Opacity' || val === 'opacity') {
+        return interfaceFunction.opacity;
+      }
+      return null;
+    }
+    Object.defineProperties(interfaceFunction, {
+      color: {
+        get: ExpressionPropertyInterface(view.c),
+      },
+      opacity: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      _name: { value: shape.nm },
+      mn: { value: shape.mn },
+    });
+
+    view.c.setGroupProperty(PropertyInterface('Color', propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
+    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 () {
+          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() {
+    function interfaceFunction() {
+      return null;
+    }
+    return interfaceFunction;
+  }
+
+  function strokeInterfaceFactory(shape, view, propertyGroup) {
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup);
+    function addPropertyToDashOb(i) {
+      Object.defineProperty(dashOb, shape.d[i].nm, {
+        get: ExpressionPropertyInterface(view.d.dataProps[i].p),
+      });
+    }
+    var i;
+    var len = shape.d ? shape.d.length : 0;
+    var dashOb = {};
+    for (i = 0; i < len; i += 1) {
+      addPropertyToDashOb(i);
+      view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup);
+    }
+
+    function interfaceFunction(val) {
+      if (val === 'Color' || val === 'color') {
+        return interfaceFunction.color;
+      } if (val === 'Opacity' || val === 'opacity') {
+        return interfaceFunction.opacity;
+      } if (val === 'Stroke Width' || val === 'stroke width') {
+        return interfaceFunction.strokeWidth;
+      }
+      return null;
+    }
+    Object.defineProperties(interfaceFunction, {
+      color: {
+        get: ExpressionPropertyInterface(view.c),
+      },
+      opacity: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      strokeWidth: {
+        get: ExpressionPropertyInterface(view.w),
+      },
+      dash: {
+        get: function () {
+          return dashOb;
+        },
+      },
+      _name: { value: shape.nm },
+      mn: { value: shape.mn },
+    });
+
+    view.c.setGroupProperty(PropertyInterface('Color', _propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    view.w.setGroupProperty(PropertyInterface('Stroke Width', _propertyGroup));
+    return interfaceFunction;
+  }
+
+  function trimInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      if (val === shape.e.ix || val === 'End' || val === 'end') {
+        return interfaceFunction.end;
+      }
+      if (val === shape.s.ix) {
+        return interfaceFunction.start;
+      }
+      if (val === shape.o.ix) {
+        return interfaceFunction.offset;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaceFunction.propertyIndex = shape.ix;
+
+    view.s.setGroupProperty(PropertyInterface('Start', _propertyGroup));
+    view.e.setGroupProperty(PropertyInterface('End', _propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
+    interfaceFunction.propertyIndex = shape.ix;
+    interfaceFunction.propertyGroup = propertyGroup;
+
+    Object.defineProperties(interfaceFunction, {
+      start: {
+        get: ExpressionPropertyInterface(view.s),
+      },
+      end: {
+        get: ExpressionPropertyInterface(view.e),
+      },
+      offset: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function transformInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.a.ix === value || value === 'Anchor Point') {
+        return interfaceFunction.anchorPoint;
+      }
+      if (shape.o.ix === value || value === 'Opacity') {
+        return interfaceFunction.opacity;
+      }
+      if (shape.p.ix === value || value === 'Position') {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value || value === 'Rotation' || value === 'ADBE Vector Rotation') {
+        return interfaceFunction.rotation;
+      }
+      if (shape.s.ix === value || value === 'Scale') {
+        return interfaceFunction.scale;
+      }
+      if ((shape.sk && shape.sk.ix === value) || value === 'Skew') {
+        return interfaceFunction.skew;
+      }
+      if ((shape.sa && shape.sa.ix === value) || value === 'Skew Axis') {
+        return interfaceFunction.skewAxis;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    view.transform.mProps.a.setGroupProperty(PropertyInterface('Anchor Point', _propertyGroup));
+    view.transform.mProps.s.setGroupProperty(PropertyInterface('Scale', _propertyGroup));
+    view.transform.mProps.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+    if (view.transform.mProps.sk) {
+      view.transform.mProps.sk.setGroupProperty(PropertyInterface('Skew', _propertyGroup));
+      view.transform.mProps.sa.setGroupProperty(PropertyInterface('Skew Angle', _propertyGroup));
+    }
+    view.transform.op.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    Object.defineProperties(interfaceFunction, {
+      opacity: {
+        get: ExpressionPropertyInterface(view.transform.mProps.o),
+      },
+      position: {
+        get: ExpressionPropertyInterface(view.transform.mProps.p),
+      },
+      anchorPoint: {
+        get: ExpressionPropertyInterface(view.transform.mProps.a),
+      },
+      scale: {
+        get: ExpressionPropertyInterface(view.transform.mProps.s),
+      },
+      rotation: {
+        get: ExpressionPropertyInterface(view.transform.mProps.r),
+      },
+      skew: {
+        get: ExpressionPropertyInterface(view.transform.mProps.sk),
+      },
+      skewAxis: {
+        get: ExpressionPropertyInterface(view.transform.mProps.sa),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.ty = 'tr';
+    interfaceFunction.mn = shape.mn;
+    interfaceFunction.propertyGroup = propertyGroup;
+    return interfaceFunction;
+  }
+
+  function ellipseInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.s.ix === value) {
+        return interfaceFunction.size;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaceFunction.propertyIndex = shape.ix;
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      size: {
+        get: ExpressionPropertyInterface(prop.s),
+      },
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function starInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value) {
+        return interfaceFunction.rotation;
+      }
+      if (shape.pt.ix === value) {
+        return interfaceFunction.points;
+      }
+      if (shape.or.ix === value || value === 'ADBE Vector Star Outer Radius') {
+        return interfaceFunction.outerRadius;
+      }
+      if (shape.os.ix === value) {
+        return interfaceFunction.outerRoundness;
+      }
+      if (shape.ir && (shape.ir.ix === value || value === 'ADBE Vector Star Inner Radius')) {
+        return interfaceFunction.innerRadius;
+      }
+      if (shape.is && shape.is.ix === value) {
+        return interfaceFunction.innerRoundness;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.or.setGroupProperty(PropertyInterface('Outer Radius', _propertyGroup));
+    prop.os.setGroupProperty(PropertyInterface('Outer Roundness', _propertyGroup));
+    prop.pt.setGroupProperty(PropertyInterface('Points', _propertyGroup));
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+    if (shape.ir) {
+      prop.ir.setGroupProperty(PropertyInterface('Inner Radius', _propertyGroup));
+      prop.is.setGroupProperty(PropertyInterface('Inner Roundness', _propertyGroup));
+    }
+
+    Object.defineProperties(interfaceFunction, {
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      rotation: {
+        get: ExpressionPropertyInterface(prop.r),
+      },
+      points: {
+        get: ExpressionPropertyInterface(prop.pt),
+      },
+      outerRadius: {
+        get: ExpressionPropertyInterface(prop.or),
+      },
+      outerRoundness: {
+        get: ExpressionPropertyInterface(prop.os),
+      },
+      innerRadius: {
+        get: ExpressionPropertyInterface(prop.ir),
+      },
+      innerRoundness: {
+        get: ExpressionPropertyInterface(prop.is),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function rectInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value) {
+        return interfaceFunction.roundness;
+      }
+      if (shape.s.ix === value || value === 'Size' || value === 'ADBE Vector Rect Size') {
+        return interfaceFunction.size;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
+    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      roundness: {
+        get: ExpressionPropertyInterface(prop.r),
+      },
+      size: {
+        get: ExpressionPropertyInterface(prop.s),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function roundedInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.r.ix === value || value === 'Round Corners 1') {
+        return interfaceFunction.radius;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.rd.setGroupProperty(PropertyInterface('Radius', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      radius: {
+        get: ExpressionPropertyInterface(prop.rd),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function repeaterInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.c.ix === value || value === 'Copies') {
+        return interfaceFunction.copies;
+      } if (shape.o.ix === value || value === 'Offset') {
+        return interfaceFunction.offset;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.c.setGroupProperty(PropertyInterface('Copies', _propertyGroup));
+    prop.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
+    Object.defineProperties(interfaceFunction, {
+      copies: {
+        get: ExpressionPropertyInterface(prop.c),
+      },
+      offset: {
+        get: ExpressionPropertyInterface(prop.o),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  return function (shapes, view, propertyGroup) {
+    var interfaces;
+    function _interfaceFunction(value) {
+      if (typeof value === 'number') {
+        value = value === undefined ? 1 : value;
+        if (value === 0) {
+          return propertyGroup;
+        }
+        return interfaces[value - 1];
+      }
+      var i = 0;
+      var len = interfaces.length;
+      while (i < len) {
+        if (interfaces[i]._name === value) {
+          return interfaces[i];
+        }
+        i += 1;
+      }
+      return null;
+    }
+    function parentGroupWrapper() {
+      return propertyGroup;
+    }
+    _interfaceFunction.propertyGroup = propertyGroupFactory(_interfaceFunction, parentGroupWrapper);
+    interfaces = iterateElements(shapes, view, _interfaceFunction.propertyGroup);
+    _interfaceFunction.numProperties = interfaces.length;
+    _interfaceFunction._name = 'Contents';
+    return _interfaceFunction;
+  };
+}());
+
+const TextExpressionInterface = (function () {
+  return function (elem) {
+    var _sourceText;
+    function _thisLayerFunction(name) {
+      switch (name) {
+        case 'ADBE Text Document':
+          return _thisLayerFunction.sourceText;
+        default:
+          return null;
+      }
+    }
+    Object.defineProperty(_thisLayerFunction, 'sourceText', {
+      get: function () {
+        elem.textProperty.getValue();
+        var stringValue = elem.textProperty.currentData.t;
+        if (!_sourceText || stringValue !== _sourceText.value) {
+          _sourceText = new String(stringValue); // eslint-disable-line no-new-wrappers
+          // If stringValue is an empty string, eval returns undefined, so it has to be returned as a String primitive
+          _sourceText.value = stringValue || new String(stringValue); // eslint-disable-line no-new-wrappers
+          Object.defineProperty(_sourceText, 'style', {
+            get: function () {
+              return {
+                fillColor: elem.textProperty.currentData.fc,
+              };
+            },
+          });
+        }
+        return _sourceText;
+      },
+    });
+    return _thisLayerFunction;
+  };
+}());
+
+const FootageInterface = (function () {
+  var outlineInterfaceFactory = (function (elem) {
+    var currentPropertyName = '';
+    var currentProperty = elem.getFootageData();
+    function init() {
+      currentPropertyName = '';
+      currentProperty = elem.getFootageData();
+      return searchProperty;
+    }
+    function searchProperty(value) {
+      if (currentProperty[value]) {
+        currentPropertyName = value;
+        currentProperty = currentProperty[value];
+        if (typeof currentProperty === 'object') {
+          return searchProperty;
+        }
+        return currentProperty;
+      }
+      var propertyNameIndex = value.indexOf(currentPropertyName);
+      if (propertyNameIndex !== -1) {
+        var index = parseInt(value.substr(propertyNameIndex + currentPropertyName.length), 10);
+        currentProperty = currentProperty[index];
+        if (typeof currentProperty === 'object') {
+          return searchProperty;
+        }
+        return currentProperty;
+      }
+      return '';
+    }
+    return init;
+  });
+
+  var dataInterfaceFactory = function (elem) {
+    function interfaceFunction(value) {
+      if (value === 'Outline') {
+        return interfaceFunction.outlineInterface();
+      }
+      return null;
+    }
+
+    interfaceFunction._name = 'Outline';
+    interfaceFunction.outlineInterface = outlineInterfaceFactory(elem);
+    return interfaceFunction;
+  };
+
+  return function (elem) {
+    function _interfaceFunction(value) {
+      if (value === 'Data') {
+        return _interfaceFunction.dataInterface;
+      }
+      return null;
+    }
+
+    _interfaceFunction._name = 'Data';
+    _interfaceFunction.dataInterface = dataInterfaceFactory(elem);
+    return _interfaceFunction;
+  };
+}());
+
+var interfaces = {
+  layer: LayerExpressionInterface,
+  effects: EffectsExpressionInterface,
+  comp: CompExpressionInterface,
+  shape: ShapeExpressionInterface,
+  text: TextExpressionInterface,
+  footage: FootageInterface,
+};
+
+function getInterface(type) {
+  return interfaces[type] || null;
+}
+
+const expressionHelpers = (function () {
+  function searchExpressions(elem, data, prop) {
+    if (data.x) {
+      prop.k = true;
+      prop.x = true;
+      prop.initiateExpression = ExpressionManager.initiateExpression;
+      prop.effectsSequence.push(prop.initiateExpression(elem, data, prop).bind(prop));
+    }
+  }
+
+  function getValueAtTime(frameNum) {
+    frameNum *= this.elem.globalData.frameRate;
+    frameNum -= this.offsetTime;
+    if (frameNum !== this._cachingAtTime.lastFrame) {
+      this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0;
+      this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime);
+      this._cachingAtTime.lastFrame = frameNum;
+    }
+    return this._cachingAtTime.value;
+  }
+
+  function getSpeedAtTime(frameNum) {
+    var delta = -0.01;
+    var v1 = this.getValueAtTime(frameNum);
+    var v2 = this.getValueAtTime(frameNum + delta);
+    var speed = 0;
+    if (v1.length) {
+      var i;
+      for (i = 0; i < v1.length; i += 1) {
+        speed += Math.pow(v2[i] - v1[i], 2);
+      }
+      speed = Math.sqrt(speed) * 100;
+    } else {
+      speed = 0;
+    }
+    return speed;
+  }
+
+  function getVelocityAtTime(frameNum) {
+    if (this.vel !== undefined) {
+      return this.vel;
+    }
+    var delta = -0.001;
+    // frameNum += this.elem.data.st;
+    var v1 = this.getValueAtTime(frameNum);
+    var v2 = this.getValueAtTime(frameNum + delta);
+    var velocity;
+    if (v1.length) {
+      velocity = createTypedArray('float32', v1.length);
+      var i;
+      for (i = 0; i < v1.length; i += 1) {
+        // removing frameRate
+        // if needed, don't add it here
+        // velocity[i] = this.elem.globalData.frameRate*((v2[i] - v1[i])/delta);
+        velocity[i] = (v2[i] - v1[i]) / delta;
+      }
+    } else {
+      velocity = (v2 - v1) / delta;
+    }
+    return velocity;
+  }
+
+  function getStaticValueAtTime() {
+    return this.pv;
+  }
+
+  function setGroupProperty(propertyGroup) {
+    this.propertyGroup = propertyGroup;
+  }
+
+  return {
+    searchExpressions: searchExpressions,
+    getSpeedAtTime: getSpeedAtTime,
+    getVelocityAtTime: getVelocityAtTime,
+    getValueAtTime: getValueAtTime,
+    getStaticValueAtTime: getStaticValueAtTime,
+    setGroupProperty: setGroupProperty,
+  };
+}());
+
+function addPropertyDecorator() {
+  function loopOut(type, duration, durationFlag) {
+    if (!this.k || !this.keyframes) {
+      return this.pv;
+    }
+    type = type ? type.toLowerCase() : '';
+    var currentFrame = this.comp.renderedFrame;
+    var keyframes = this.keyframes;
+    var lastKeyFrame = keyframes[keyframes.length - 1].t;
+    if (currentFrame <= lastKeyFrame) {
+      return this.pv;
+    }
+    var cycleDuration;
+    var firstKeyFrame;
+    if (!durationFlag) {
+      if (!duration || duration > keyframes.length - 1) {
+        duration = keyframes.length - 1;
+      }
+      firstKeyFrame = keyframes[keyframes.length - 1 - duration].t;
+      cycleDuration = lastKeyFrame - firstKeyFrame;
+    } else {
+      if (!duration) {
+        cycleDuration = Math.max(0, lastKeyFrame - this.elem.data.ip);
+      } else {
+        cycleDuration = Math.abs(lastKeyFrame - this.elem.comp.globalData.frameRate * duration);
+      }
+      firstKeyFrame = lastKeyFrame - cycleDuration;
+    }
+    var i;
+    var len;
+    var ret;
+    if (type === 'pingpong') {
+      var iterations = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
+      if (iterations % 2 !== 0) {
+          return this.getValueAtTime(((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      }
+    } else if (type === 'offset') {
+      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+        var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      var repeats = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
+      if (this.pv.length) {
+        ret = new Array(initV.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = (endV[i] - initV[i]) * repeats + current[i];
+        }
+        return ret;
+      }
+      return (endV - initV) * repeats + current;
+    } else if (type === 'continue') {
+      var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+      var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0);
+      if (this.pv.length) {
+        ret = new Array(lastValue.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+            ret[i] = lastValue[i] + (lastValue[i] - nextLastValue[i]) * ((currentFrame - lastKeyFrame) / this.comp.globalData.frameRate) / 0.0005; // eslint-disable-line
+        }
+        return ret;
+      }
+      return lastValue + (lastValue - nextLastValue) * (((currentFrame - lastKeyFrame)) / 0.001);
+    }
+      return this.getValueAtTime((((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+
+  }
+
+  function loopIn(type, duration, durationFlag) {
+    if (!this.k) {
+      return this.pv;
+    }
+    type = type ? type.toLowerCase() : '';
+    var currentFrame = this.comp.renderedFrame;
+    var keyframes = this.keyframes;
+    var firstKeyFrame = keyframes[0].t;
+    if (currentFrame >= firstKeyFrame) {
+      return this.pv;
+    }
+    var cycleDuration;
+    var lastKeyFrame;
+    if (!durationFlag) {
+      if (!duration || duration > keyframes.length - 1) {
+        duration = keyframes.length - 1;
+      }
+      lastKeyFrame = keyframes[duration].t;
+      cycleDuration = lastKeyFrame - firstKeyFrame;
+    } else {
+      if (!duration) {
+        cycleDuration = Math.max(0, this.elem.data.op - firstKeyFrame);
+      } else {
+        cycleDuration = Math.abs(this.elem.comp.globalData.frameRate * duration);
+      }
+      lastKeyFrame = firstKeyFrame + cycleDuration;
+    }
+    var i;
+    var len;
+    var ret;
+    if (type === 'pingpong') {
+      var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration);
+      if (iterations % 2 === 0) {
+          return this.getValueAtTime((((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      }
+    } else if (type === 'offset') {
+      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+      var current = this.getValueAtTime((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration) + firstKeyFrame) / this.comp.globalData.frameRate, 0);
+      var repeats = Math.floor((firstKeyFrame - currentFrame) / cycleDuration) + 1;
+      if (this.pv.length) {
+        ret = new Array(initV.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = current[i] - (endV[i] - initV[i]) * repeats;
+        }
+        return ret;
+      }
+      return current - (endV - initV) * repeats;
+    } else if (type === 'continue') {
+      var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0);
+      if (this.pv.length) {
+        ret = new Array(firstValue.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = firstValue[i] + ((firstValue[i] - nextFirstValue[i]) * (firstKeyFrame - currentFrame)) / 0.001;
+        }
+        return ret;
+      }
+      return firstValue + ((firstValue - nextFirstValue) * (firstKeyFrame - currentFrame)) / 0.001;
+    }
+      return this.getValueAtTime(((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame))) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+
+  }
+
+  function smooth(width, samples) {
+    if (!this.k) {
+      return this.pv;
+    }
+    width = (width || 0.4) * 0.5;
+    samples = Math.floor(samples || 5);
+    if (samples <= 1) {
+      return this.pv;
+    }
+    var currentTime = this.comp.renderedFrame / this.comp.globalData.frameRate;
+    var initFrame = currentTime - width;
+    var endFrame = currentTime + width;
+    var sampleFrequency = samples > 1 ? (endFrame - initFrame) / (samples - 1) : 1;
+    var i = 0;
+    var j = 0;
+    var value;
+    if (this.pv.length) {
+      value = createTypedArray('float32', this.pv.length);
+    } else {
+      value = 0;
+    }
+    var sampleValue;
+    while (i < samples) {
+      sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency);
+      if (this.pv.length) {
+        for (j = 0; j < this.pv.length; j += 1) {
+          value[j] += sampleValue[j];
+        }
+      } else {
+        value += sampleValue;
+      }
+      i += 1;
+    }
+    if (this.pv.length) {
+      for (j = 0; j < this.pv.length; j += 1) {
+        value[j] /= samples;
+      }
+    } else {
+      value /= samples;
+    }
+    return value;
+  }
+
+  function getTransformValueAtTime(time) {
+    if (!this._transformCachingAtTime) {
+      this._transformCachingAtTime = {
+        v: new Matrix(),
+      };
+    }
+    /// /
+    var matrix = this._transformCachingAtTime.v;
+    matrix.cloneFromProps(this.pre.props);
+    if (this.appliedTransformations < 1) {
+      var anchor = this.a.getValueAtTime(time);
+      matrix.translate(
+        -anchor[0] * this.a.mult,
+        -anchor[1] * this.a.mult,
+        anchor[2] * this.a.mult
+      );
+    }
+    if (this.appliedTransformations < 2) {
+      var scale = this.s.getValueAtTime(time);
+      matrix.scale(
+        scale[0] * this.s.mult,
+        scale[1] * this.s.mult,
+        scale[2] * this.s.mult
+      );
+    }
+    if (this.sk && this.appliedTransformations < 3) {
+      var skew = this.sk.getValueAtTime(time);
+      var skewAxis = this.sa.getValueAtTime(time);
+      matrix.skewFromAxis(-skew * this.sk.mult, skewAxis * this.sa.mult);
+    }
+    if (this.r && this.appliedTransformations < 4) {
+      var rotation = this.r.getValueAtTime(time);
+      matrix.rotate(-rotation * this.r.mult);
+    } else if (!this.r && this.appliedTransformations < 4) {
+      var rotationZ = this.rz.getValueAtTime(time);
+      var rotationY = this.ry.getValueAtTime(time);
+      var rotationX = this.rx.getValueAtTime(time);
+      var orientation = this.or.getValueAtTime(time);
+      matrix.rotateZ(-rotationZ * this.rz.mult)
+        .rotateY(rotationY * this.ry.mult)
+        .rotateX(rotationX * this.rx.mult)
+        .rotateZ(-orientation[2] * this.or.mult)
+        .rotateY(orientation[1] * this.or.mult)
+        .rotateX(orientation[0] * this.or.mult);
+    }
+    if (this.data.p && this.data.p.s) {
+      var positionX = this.px.getValueAtTime(time);
+      var positionY = this.py.getValueAtTime(time);
+      if (this.data.p.z) {
+        var positionZ = this.pz.getValueAtTime(time);
+        matrix.translate(
+          positionX * this.px.mult,
+          positionY * this.py.mult,
+          -positionZ * this.pz.mult
+        );
+      } else {
+        matrix.translate(positionX * this.px.mult, positionY * this.py.mult, 0);
+      }
+    } else {
+      var position = this.p.getValueAtTime(time);
+      matrix.translate(
+        position[0] * this.p.mult,
+        position[1] * this.p.mult,
+        -position[2] * this.p.mult
+      );
+    }
+    return matrix;
+    /// /
+  }
+
+  function getTransformStaticValueAtTime() {
+    return this.v.clone(new Matrix());
+  }
+
+  var getTransformProperty = TransformPropertyFactory.getTransformProperty;
+  TransformPropertyFactory.getTransformProperty = function (elem, data, container) {
+    var prop = getTransformProperty(elem, data, container);
+    if (prop.dynamicProperties.length) {
+      prop.getValueAtTime = getTransformValueAtTime.bind(prop);
+    } else {
+      prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop);
+    }
+    prop.setGroupProperty = expressionHelpers.setGroupProperty;
+    return prop;
+  };
+
+  var propertyGetProp = PropertyFactory.getProp;
+  PropertyFactory.getProp = function (elem, data, type, mult, container) {
+    var prop = propertyGetProp(elem, data, type, mult, container);
+    // prop.getVelocityAtTime = getVelocityAtTime;
+    // prop.loopOut = loopOut;
+    // prop.loopIn = loopIn;
+    if (prop.kf) {
+      prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop);
+    } else {
+      prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop);
+    }
+    prop.setGroupProperty = expressionHelpers.setGroupProperty;
+    prop.loopOut = loopOut;
+    prop.loopIn = loopIn;
+    prop.smooth = smooth;
+    prop.getVelocityAtTime = expressionHelpers.getVelocityAtTime.bind(prop);
+    prop.getSpeedAtTime = expressionHelpers.getSpeedAtTime.bind(prop);
+    prop.numKeys = data.a === 1 ? data.k.length : 0;
+    prop.propertyIndex = data.ix;
+    var value = 0;
+    if (type !== 0) {
+      value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length);
+    }
+    prop._cachingAtTime = {
+      lastFrame: initialDefaultFrame,
+      lastIndex: 0,
+      value: value,
+    };
+    expressionHelpers.searchExpressions(elem, data, prop);
+    if (prop.k) {
+      container.addDynamicProperty(prop);
+    }
+
+    return prop;
+  };
+
+  function getShapeValueAtTime(frameNum) {
+    // For now this caching object is created only when needed instead of creating it when the shape is initialized.
+    if (!this._cachingAtTime) {
+      this._cachingAtTime = {
+        shapeValue: shapePool.clone(this.pv),
+        lastIndex: 0,
+        lastTime: initialDefaultFrame,
+      };
+    }
+
+    frameNum *= this.elem.globalData.frameRate;
+    frameNum -= this.offsetTime;
+    if (frameNum !== this._cachingAtTime.lastTime) {
+      this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0;
+      this._cachingAtTime.lastTime = frameNum;
+      this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime);
+    }
+    return this._cachingAtTime.shapeValue;
+  }
+
+  var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction();
+  var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction();
+
+  function ShapeExpressions() {}
+  ShapeExpressions.prototype = {
+    vertices: function (prop, time) {
+      if (this.k) {
+        this.getValue();
+      }
+      var shapePath = this.v;
+      if (time !== undefined) {
+        shapePath = this.getValueAtTime(time, 0);
+      }
+      var i;
+      var len = shapePath._length;
+      var vertices = shapePath[prop];
+      var points = shapePath.v;
+      var arr = createSizedArray(len);
+      for (i = 0; i < len; i += 1) {
+        if (prop === 'i' || prop === 'o') {
+          arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]];
+        } else {
+          arr[i] = [vertices[i][0], vertices[i][1]];
+        }
+      }
+      return arr;
+    },
+    points: function (time) {
+      return this.vertices('v', time);
+    },
+    inTangents: function (time) {
+      return this.vertices('i', time);
+    },
+    outTangents: function (time) {
+      return this.vertices('o', time);
+    },
+    isClosed: function () {
+      return this.v.c;
+    },
+    pointOnPath: function (perc, time) {
+      var shapePath = this.v;
+      if (time !== undefined) {
+        shapePath = this.getValueAtTime(time, 0);
+      }
+      if (!this._segmentsLength) {
+        this._segmentsLength = bez.getSegmentsLength(shapePath);
+      }
+
+      var segmentsLength = this._segmentsLength;
+      var lengths = segmentsLength.lengths;
+      var lengthPos = segmentsLength.totalLength * perc;
+      var i = 0;
+      var len = lengths.length;
+      var accumulatedLength = 0;
+      var pt;
+      while (i < len) {
+        if (accumulatedLength + lengths[i].addedLength > lengthPos) {
+          var initIndex = i;
+          var endIndex = (shapePath.c && i === len - 1) ? 0 : i + 1;
+          var segmentPerc = (lengthPos - accumulatedLength) / lengths[i].addedLength;
+          pt = bez.getPointInSegment(shapePath.v[initIndex], shapePath.v[endIndex], shapePath.o[initIndex], shapePath.i[endIndex], segmentPerc, lengths[i]);
+          break;
+        } else {
+          accumulatedLength += lengths[i].addedLength;
+        }
+        i += 1;
+      }
+      if (!pt) {
+        pt = shapePath.c ? [shapePath.v[0][0], shapePath.v[0][1]] : [shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1]];
+      }
+      return pt;
+    },
+    vectorOnPath: function (perc, time, vectorType) {
+      // perc doesn't use triple equality because it can be a Number object as well as a primitive.
+      if (perc == 1) { // eslint-disable-line eqeqeq
+        perc = this.v.c;
+      } else if (perc == 0) { // eslint-disable-line eqeqeq
+        perc = 0.999;
+      }
+      var pt1 = this.pointOnPath(perc, time);
+      var pt2 = this.pointOnPath(perc + 0.001, time);
+      var xLength = pt2[0] - pt1[0];
+      var yLength = pt2[1] - pt1[1];
+      var magnitude = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2));
+      if (magnitude === 0) {
+        return [0, 0];
+      }
+      var unitVector = vectorType === 'tangent' ? [xLength / magnitude, yLength / magnitude] : [-yLength / magnitude, xLength / magnitude];
+      return unitVector;
+    },
+    tangentOnPath: function (perc, time) {
+      return this.vectorOnPath(perc, time, 'tangent');
+    },
+    normalOnPath: function (perc, time) {
+      return this.vectorOnPath(perc, time, 'normal');
+    },
+    setGroupProperty: expressionHelpers.setGroupProperty,
+    getValueAtTime: expressionHelpers.getStaticValueAtTime,
+  };
+  extendPrototype([ShapeExpressions], ShapePropertyConstructorFunction);
+  extendPrototype([ShapeExpressions], KeyframedShapePropertyConstructorFunction);
+  KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime;
+  KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression;
+
+  var propertyGetShapeProp = ShapePropertyFactory.getShapeProp;
+  ShapePropertyFactory.getShapeProp = function (elem, data, type, arr, trims) {
+    var prop = propertyGetShapeProp(elem, data, type, arr, trims);
+    prop.propertyIndex = data.ix;
+    prop.lock = false;
+    if (type === 3) {
+      expressionHelpers.searchExpressions(elem, data.pt, prop);
+    } else if (type === 4) {
+      expressionHelpers.searchExpressions(elem, data.ks, prop);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  };
+}
+
+function initialize$1() {
+  addPropertyDecorator();
+}
+
+function addDecorator() {
+  function searchExpressions() {
+    if (this.data.d.x) {
+      this.calculateExpression = ExpressionManager.initiateExpression.bind(this)(this.elem, this.data.d, this);
+      this.addEffect(this.getExpressionValue.bind(this));
+      return true;
+    }
+    return null;
+  }
+
+  TextProperty.prototype.getExpressionValue = function (currentValue, text) {
+    var newValue = this.calculateExpression(text);
+    if (currentValue.t !== newValue) {
+      var newData = {};
+      this.copyData(newData, currentValue);
+      newData.t = newValue.toString();
+      newData.__complete = false;
+      return newData;
+    }
+    return currentValue;
+  };
+
+  TextProperty.prototype.searchProperty = function () {
+    var isKeyframed = this.searchKeyframes();
+    var hasExpressions = this.searchExpressions();
+    this.kf = isKeyframed || hasExpressions;
+    return this.kf;
+  };
+
+  TextProperty.prototype.searchExpressions = searchExpressions;
+}
+
+function initialize() {
+  addDecorator();
+}
+
+function SVGComposableEffect() {
+
+}
+SVGComposableEffect.prototype = {
+  createMergeNode: (resultId, ins) => {
+    var feMerge = createNS('feMerge');
+    feMerge.setAttribute('result', resultId);
+    var feMergeNode;
+    var i;
+    for (i = 0; i < ins.length; i += 1) {
+      feMergeNode = createNS('feMergeNode');
+      feMergeNode.setAttribute('in', ins[i]);
+      feMerge.appendChild(feMergeNode);
+      feMerge.appendChild(feMergeNode);
+    }
+    return feMerge;
+  },
+};
+
+var linearFilterValue = '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0';
+
+function SVGTintFilter(filter, filterManager, elem, id, source) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'linearRGB');
+  feColorMatrix.setAttribute('values', linearFilterValue + ' 1 0');
+  this.linearFilter = feColorMatrix;
+  feColorMatrix.setAttribute('result', id + '_tint_1');
+  filter.appendChild(feColorMatrix);
+  feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+  feColorMatrix.setAttribute('values', '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0');
+  feColorMatrix.setAttribute('result', id + '_tint_2');
+  filter.appendChild(feColorMatrix);
+  this.matrixFilter = feColorMatrix;
+  var feMerge = this.createMergeNode(
+    id,
+    [
+      source,
+      id + '_tint_1',
+      id + '_tint_2',
+    ]
+  );
+  filter.appendChild(feMerge);
+}
+extendPrototype([SVGComposableEffect], SVGTintFilter);
+
+SVGTintFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var colorBlack = this.filterManager.effectElements[0].p.v;
+    var colorWhite = this.filterManager.effectElements[1].p.v;
+    var opacity = this.filterManager.effectElements[2].p.v / 100;
+    this.linearFilter.setAttribute('values', linearFilterValue + ' ' + opacity + ' 0');
+    this.matrixFilter.setAttribute('values', (colorWhite[0] - colorBlack[0]) + ' 0 0 0 ' + colorBlack[0] + ' ' + (colorWhite[1] - colorBlack[1]) + ' 0 0 0 ' + colorBlack[1] + ' ' + (colorWhite[2] - colorBlack[2]) + ' 0 0 0 ' + colorBlack[2] + ' 0 0 0 1 0');
+  }
+};
+
+function SVGFillFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+  feColorMatrix.setAttribute('values', '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0');
+  feColorMatrix.setAttribute('result', id);
+  filter.appendChild(feColorMatrix);
+  this.matrixFilter = feColorMatrix;
+}
+
+SVGFillFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var color = this.filterManager.effectElements[2].p.v;
+    var opacity = this.filterManager.effectElements[6].p.v;
+    this.matrixFilter.setAttribute('values', '0 0 0 0 ' + color[0] + ' 0 0 0 0 ' + color[1] + ' 0 0 0 0 ' + color[2] + ' 0 0 0 ' + opacity + ' 0');
+  }
+};
+
+function SVGStrokeEffect(fil, filterManager, elem) {
+  this.initialized = false;
+  this.filterManager = filterManager;
+  this.elem = elem;
+  this.paths = [];
+}
+
+SVGStrokeEffect.prototype.initialize = function () {
+  var elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
+  var path;
+  var groupPath;
+  var i;
+  var len;
+  if (this.filterManager.effectElements[1].p.v === 1) {
+    len = this.elem.maskManager.masksProperties.length;
+    i = 0;
+  } else {
+    i = this.filterManager.effectElements[0].p.v - 1;
+    len = i + 1;
+  }
+  groupPath = createNS('g');
+  groupPath.setAttribute('fill', 'none');
+  groupPath.setAttribute('stroke-linecap', 'round');
+  groupPath.setAttribute('stroke-dashoffset', 1);
+  for (i; i < len; i += 1) {
+    path = createNS('path');
+    groupPath.appendChild(path);
+    this.paths.push({ p: path, m: i });
+  }
+  if (this.filterManager.effectElements[10].p.v === 3) {
+    var mask = createNS('mask');
+    var id = createElementID();
+    mask.setAttribute('id', id);
+    mask.setAttribute('mask-type', 'alpha');
+    mask.appendChild(groupPath);
+    this.elem.globalData.defs.appendChild(mask);
+    var g = createNS('g');
+    g.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+    while (elemChildren[0]) {
+      g.appendChild(elemChildren[0]);
+    }
+    this.elem.layerElement.appendChild(g);
+    this.masker = mask;
+    groupPath.setAttribute('stroke', '#fff');
+  } else if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
+    if (this.filterManager.effectElements[10].p.v === 2) {
+      elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
+      while (elemChildren.length) {
+        this.elem.layerElement.removeChild(elemChildren[0]);
+      }
+    }
+    this.elem.layerElement.appendChild(groupPath);
+    this.elem.layerElement.removeAttribute('mask');
+    groupPath.setAttribute('stroke', '#fff');
+  }
+  this.initialized = true;
+  this.pathMasker = groupPath;
+};
+
+SVGStrokeEffect.prototype.renderFrame = function (forceRender) {
+  if (!this.initialized) {
+    this.initialize();
+  }
+  var i;
+  var len = this.paths.length;
+  var mask;
+  var path;
+  for (i = 0; i < len; i += 1) {
+    if (this.paths[i].m !== -1) {
+      mask = this.elem.maskManager.viewData[this.paths[i].m];
+      path = this.paths[i].p;
+      if (forceRender || this.filterManager._mdf || mask.prop._mdf) {
+        path.setAttribute('d', mask.lastPath);
+      }
+      if (forceRender || this.filterManager.effectElements[9].p._mdf || this.filterManager.effectElements[4].p._mdf || this.filterManager.effectElements[7].p._mdf || this.filterManager.effectElements[8].p._mdf || mask.prop._mdf) {
+        var dasharrayValue;
+        if (this.filterManager.effectElements[7].p.v !== 0 || this.filterManager.effectElements[8].p.v !== 100) {
+          var s = Math.min(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
+          var e = Math.max(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
+          var l = path.getTotalLength();
+          dasharrayValue = '0 0 0 ' + l * s + ' ';
+          var lineLength = l * (e - s);
+          var segment = 1 + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
+          var units = Math.floor(lineLength / segment);
+          var j;
+          for (j = 0; j < units; j += 1) {
+            dasharrayValue += '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01 + ' ';
+          }
+          dasharrayValue += '0 ' + l * 10 + ' 0 0';
+        } else {
+          dasharrayValue = '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
+        }
+        path.setAttribute('stroke-dasharray', dasharrayValue);
+      }
+    }
+  }
+  if (forceRender || this.filterManager.effectElements[4].p._mdf) {
+    this.pathMasker.setAttribute('stroke-width', this.filterManager.effectElements[4].p.v * 2);
+  }
+
+  if (forceRender || this.filterManager.effectElements[6].p._mdf) {
+    this.pathMasker.setAttribute('opacity', this.filterManager.effectElements[6].p.v);
+  }
+  if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
+    if (forceRender || this.filterManager.effectElements[3].p._mdf) {
+      var color = this.filterManager.effectElements[3].p.v;
+      this.pathMasker.setAttribute('stroke', 'rgb(' + bmFloor(color[0] * 255) + ',' + bmFloor(color[1] * 255) + ',' + bmFloor(color[2] * 255) + ')');
+    }
+  }
+};
+
+function SVGTritoneFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'linearRGB');
+  feColorMatrix.setAttribute('values', '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0');
+  filter.appendChild(feColorMatrix);
+  var feComponentTransfer = createNS('feComponentTransfer');
+  feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+  feComponentTransfer.setAttribute('result', id);
+  this.matrixFilter = feComponentTransfer;
+  var feFuncR = createNS('feFuncR');
+  feFuncR.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncR);
+  this.feFuncR = feFuncR;
+  var feFuncG = createNS('feFuncG');
+  feFuncG.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncG);
+  this.feFuncG = feFuncG;
+  var feFuncB = createNS('feFuncB');
+  feFuncB.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncB);
+  this.feFuncB = feFuncB;
+  filter.appendChild(feComponentTransfer);
+}
+
+SVGTritoneFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var color1 = this.filterManager.effectElements[0].p.v;
+    var color2 = this.filterManager.effectElements[1].p.v;
+    var color3 = this.filterManager.effectElements[2].p.v;
+    var tableR = color3[0] + ' ' + color2[0] + ' ' + color1[0];
+    var tableG = color3[1] + ' ' + color2[1] + ' ' + color1[1];
+    var tableB = color3[2] + ' ' + color2[2] + ' ' + color1[2];
+    this.feFuncR.setAttribute('tableValues', tableR);
+    this.feFuncG.setAttribute('tableValues', tableG);
+    this.feFuncB.setAttribute('tableValues', tableB);
+  }
+};
+
+function SVGProLevelsFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var effectElements = this.filterManager.effectElements;
+  var feComponentTransfer = createNS('feComponentTransfer');
+
+  // Red
+  if (effectElements[10].p.k || effectElements[10].p.v !== 0 || effectElements[11].p.k || effectElements[11].p.v !== 1 || effectElements[12].p.k || effectElements[12].p.v !== 1 || effectElements[13].p.k || effectElements[13].p.v !== 0 || effectElements[14].p.k || effectElements[14].p.v !== 1) {
+    this.feFuncR = this.createFeFunc('feFuncR', feComponentTransfer);
+  }
+  // Green
+  if (effectElements[17].p.k || effectElements[17].p.v !== 0 || effectElements[18].p.k || effectElements[18].p.v !== 1 || effectElements[19].p.k || effectElements[19].p.v !== 1 || effectElements[20].p.k || effectElements[20].p.v !== 0 || effectElements[21].p.k || effectElements[21].p.v !== 1) {
+    this.feFuncG = this.createFeFunc('feFuncG', feComponentTransfer);
+  }
+  // Blue
+  if (effectElements[24].p.k || effectElements[24].p.v !== 0 || effectElements[25].p.k || effectElements[25].p.v !== 1 || effectElements[26].p.k || effectElements[26].p.v !== 1 || effectElements[27].p.k || effectElements[27].p.v !== 0 || effectElements[28].p.k || effectElements[28].p.v !== 1) {
+    this.feFuncB = this.createFeFunc('feFuncB', feComponentTransfer);
+  }
+  // Alpha
+  if (effectElements[31].p.k || effectElements[31].p.v !== 0 || effectElements[32].p.k || effectElements[32].p.v !== 1 || effectElements[33].p.k || effectElements[33].p.v !== 1 || effectElements[34].p.k || effectElements[34].p.v !== 0 || effectElements[35].p.k || effectElements[35].p.v !== 1) {
+    this.feFuncA = this.createFeFunc('feFuncA', feComponentTransfer);
+  }
+  // RGB
+  if (this.feFuncR || this.feFuncG || this.feFuncB || this.feFuncA) {
+    feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+    filter.appendChild(feComponentTransfer);
+  }
+
+  if (effectElements[3].p.k || effectElements[3].p.v !== 0 || effectElements[4].p.k || effectElements[4].p.v !== 1 || effectElements[5].p.k || effectElements[5].p.v !== 1 || effectElements[6].p.k || effectElements[6].p.v !== 0 || effectElements[7].p.k || effectElements[7].p.v !== 1) {
+    feComponentTransfer = createNS('feComponentTransfer');
+    feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+    feComponentTransfer.setAttribute('result', id);
+    filter.appendChild(feComponentTransfer);
+    this.feFuncRComposed = this.createFeFunc('feFuncR', feComponentTransfer);
+    this.feFuncGComposed = this.createFeFunc('feFuncG', feComponentTransfer);
+    this.feFuncBComposed = this.createFeFunc('feFuncB', feComponentTransfer);
+  }
+}
+
+SVGProLevelsFilter.prototype.createFeFunc = function (type, feComponentTransfer) {
+  var feFunc = createNS(type);
+  feFunc.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFunc);
+  return feFunc;
+};
+
+SVGProLevelsFilter.prototype.getTableValue = function (inputBlack, inputWhite, gamma, outputBlack, outputWhite) {
+  var cnt = 0;
+  var segments = 256;
+  var perc;
+  var min = Math.min(inputBlack, inputWhite);
+  var max = Math.max(inputBlack, inputWhite);
+  var table = Array.call(null, { length: segments });
+  var colorValue;
+  var pos = 0;
+  var outputDelta = outputWhite - outputBlack;
+  var inputDelta = inputWhite - inputBlack;
+  while (cnt <= 256) {
+    perc = cnt / 256;
+    if (perc <= min) {
+      colorValue = inputDelta < 0 ? outputWhite : outputBlack;
+    } else if (perc >= max) {
+      colorValue = inputDelta < 0 ? outputBlack : outputWhite;
+    } else {
+      colorValue = (outputBlack + outputDelta * Math.pow((perc - inputBlack) / inputDelta, 1 / gamma));
+    }
+    table[pos] = colorValue;
+    pos += 1;
+    cnt += 256 / (segments - 1);
+  }
+  return table.join(' ');
+};
+
+SVGProLevelsFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var val;
+    var effectElements = this.filterManager.effectElements;
+    if (this.feFuncRComposed && (forceRender || effectElements[3].p._mdf || effectElements[4].p._mdf || effectElements[5].p._mdf || effectElements[6].p._mdf || effectElements[7].p._mdf)) {
+      val = this.getTableValue(effectElements[3].p.v, effectElements[4].p.v, effectElements[5].p.v, effectElements[6].p.v, effectElements[7].p.v);
+      this.feFuncRComposed.setAttribute('tableValues', val);
+      this.feFuncGComposed.setAttribute('tableValues', val);
+      this.feFuncBComposed.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncR && (forceRender || effectElements[10].p._mdf || effectElements[11].p._mdf || effectElements[12].p._mdf || effectElements[13].p._mdf || effectElements[14].p._mdf)) {
+      val = this.getTableValue(effectElements[10].p.v, effectElements[11].p.v, effectElements[12].p.v, effectElements[13].p.v, effectElements[14].p.v);
+      this.feFuncR.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncG && (forceRender || effectElements[17].p._mdf || effectElements[18].p._mdf || effectElements[19].p._mdf || effectElements[20].p._mdf || effectElements[21].p._mdf)) {
+      val = this.getTableValue(effectElements[17].p.v, effectElements[18].p.v, effectElements[19].p.v, effectElements[20].p.v, effectElements[21].p.v);
+      this.feFuncG.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncB && (forceRender || effectElements[24].p._mdf || effectElements[25].p._mdf || effectElements[26].p._mdf || effectElements[27].p._mdf || effectElements[28].p._mdf)) {
+      val = this.getTableValue(effectElements[24].p.v, effectElements[25].p.v, effectElements[26].p.v, effectElements[27].p.v, effectElements[28].p.v);
+      this.feFuncB.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncA && (forceRender || effectElements[31].p._mdf || effectElements[32].p._mdf || effectElements[33].p._mdf || effectElements[34].p._mdf || effectElements[35].p._mdf)) {
+      val = this.getTableValue(effectElements[31].p.v, effectElements[32].p.v, effectElements[33].p.v, effectElements[34].p.v, effectElements[35].p.v);
+      this.feFuncA.setAttribute('tableValues', val);
+    }
+  }
+};
+
+function SVGDropShadowEffect(filter, filterManager, elem, id, source) {
+  var globalFilterSize = filterManager.container.globalData.renderConfig.filterSize;
+  var filterSize = filterManager.data.fs || globalFilterSize;
+  filter.setAttribute('x', filterSize.x || globalFilterSize.x);
+  filter.setAttribute('y', filterSize.y || globalFilterSize.y);
+  filter.setAttribute('width', filterSize.width || globalFilterSize.width);
+  filter.setAttribute('height', filterSize.height || globalFilterSize.height);
+  this.filterManager = filterManager;
+
+  var feGaussianBlur = createNS('feGaussianBlur');
+  feGaussianBlur.setAttribute('in', 'SourceAlpha');
+  feGaussianBlur.setAttribute('result', id + '_drop_shadow_1');
+  feGaussianBlur.setAttribute('stdDeviation', '0');
+  this.feGaussianBlur = feGaussianBlur;
+  filter.appendChild(feGaussianBlur);
+
+  var feOffset = createNS('feOffset');
+  feOffset.setAttribute('dx', '25');
+  feOffset.setAttribute('dy', '0');
+  feOffset.setAttribute('in', id + '_drop_shadow_1');
+  feOffset.setAttribute('result', id + '_drop_shadow_2');
+  this.feOffset = feOffset;
+  filter.appendChild(feOffset);
+  var feFlood = createNS('feFlood');
+  feFlood.setAttribute('flood-color', '#00ff00');
+  feFlood.setAttribute('flood-opacity', '1');
+  feFlood.setAttribute('result', id + '_drop_shadow_3');
+  this.feFlood = feFlood;
+  filter.appendChild(feFlood);
+
+  var feComposite = createNS('feComposite');
+  feComposite.setAttribute('in', id + '_drop_shadow_3');
+  feComposite.setAttribute('in2', id + '_drop_shadow_2');
+  feComposite.setAttribute('operator', 'in');
+  feComposite.setAttribute('result', id + '_drop_shadow_4');
+  filter.appendChild(feComposite);
+
+  var feMerge = this.createMergeNode(
+    id,
+    [
+      id + '_drop_shadow_4',
+      source,
+    ]
+  );
+  filter.appendChild(feMerge);
+  //
+}
+extendPrototype([SVGComposableEffect], SVGDropShadowEffect);
+
+SVGDropShadowEffect.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    if (forceRender || this.filterManager.effectElements[4].p._mdf) {
+      this.feGaussianBlur.setAttribute('stdDeviation', this.filterManager.effectElements[4].p.v / 4);
+    }
+    if (forceRender || this.filterManager.effectElements[0].p._mdf) {
+      var col = this.filterManager.effectElements[0].p.v;
+      this.feFlood.setAttribute('flood-color', rgbToHex(Math.round(col[0] * 255), Math.round(col[1] * 255), Math.round(col[2] * 255)));
+    }
+    if (forceRender || this.filterManager.effectElements[1].p._mdf) {
+      this.feFlood.setAttribute('flood-opacity', this.filterManager.effectElements[1].p.v / 255);
+    }
+    if (forceRender || this.filterManager.effectElements[2].p._mdf || this.filterManager.effectElements[3].p._mdf) {
+      var distance = this.filterManager.effectElements[3].p.v;
+      var angle = (this.filterManager.effectElements[2].p.v - 90) * degToRads;
+      var x = distance * Math.cos(angle);
+      var y = distance * Math.sin(angle);
+      this.feOffset.setAttribute('dx', x);
+      this.feOffset.setAttribute('dy', y);
+    }
+  }
+};
+
+var _svgMatteSymbols = [];
+
+function SVGMatte3Effect(filterElem, filterManager, elem) {
+  this.initialized = false;
+  this.filterManager = filterManager;
+  this.filterElem = filterElem;
+  this.elem = elem;
+  elem.matteElement = createNS('g');
+  elem.matteElement.appendChild(elem.layerElement);
+  elem.matteElement.appendChild(elem.transformedElement);
+  elem.baseElement = elem.matteElement;
+}
+
+SVGMatte3Effect.prototype.findSymbol = function (mask) {
+  var i = 0;
+  var len = _svgMatteSymbols.length;
+  while (i < len) {
+    if (_svgMatteSymbols[i] === mask) {
+      return _svgMatteSymbols[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+SVGMatte3Effect.prototype.replaceInParent = function (mask, symbolId) {
+  var parentNode = mask.layerElement.parentNode;
+  if (!parentNode) {
+    return;
+  }
+  var children = parentNode.children;
+  var i = 0;
+  var len = children.length;
+  while (i < len) {
+    if (children[i] === mask.layerElement) {
+      break;
+    }
+    i += 1;
+  }
+  var nextChild;
+  if (i <= len - 2) {
+    nextChild = children[i + 1];
+  }
+  var useElem = createNS('use');
+  useElem.setAttribute('href', '#' + symbolId);
+  if (nextChild) {
+    parentNode.insertBefore(useElem, nextChild);
+  } else {
+    parentNode.appendChild(useElem);
+  }
+};
+
+SVGMatte3Effect.prototype.setElementAsMask = function (elem, mask) {
+  if (!this.findSymbol(mask)) {
+    var symbolId = createElementID();
+    var masker = createNS('mask');
+    masker.setAttribute('id', mask.layerId);
+    masker.setAttribute('mask-type', 'alpha');
+    _svgMatteSymbols.push(mask);
+    var defs = elem.globalData.defs;
+    defs.appendChild(masker);
+    var symbol = createNS('symbol');
+    symbol.setAttribute('id', symbolId);
+    this.replaceInParent(mask, symbolId);
+    symbol.appendChild(mask.layerElement);
+    defs.appendChild(symbol);
+    var useElem = createNS('use');
+    useElem.setAttribute('href', '#' + symbolId);
+    masker.appendChild(useElem);
+    mask.data.hd = false;
+    mask.show();
+  }
+  elem.setMatte(mask.layerId);
+};
+
+SVGMatte3Effect.prototype.initialize = function () {
+  var ind = this.filterManager.effectElements[0].p.v;
+  var elements = this.elem.comp.elements;
+  var i = 0;
+  var len = elements.length;
+  while (i < len) {
+    if (elements[i] && elements[i].data.ind === ind) {
+      this.setElementAsMask(this.elem, elements[i]);
+    }
+    i += 1;
+  }
+  this.initialized = true;
+};
+
+SVGMatte3Effect.prototype.renderFrame = function () {
+  if (!this.initialized) {
+    this.initialize();
+  }
+};
+
+function SVGGaussianBlurEffect(filter, filterManager, elem, id) {
+  // Outset the filter region by 100% on all sides to accommodate blur expansion.
+  filter.setAttribute('x', '-100%');
+  filter.setAttribute('y', '-100%');
+  filter.setAttribute('width', '300%');
+  filter.setAttribute('height', '300%');
+
+  this.filterManager = filterManager;
+  var feGaussianBlur = createNS('feGaussianBlur');
+  feGaussianBlur.setAttribute('result', id);
+  filter.appendChild(feGaussianBlur);
+  this.feGaussianBlur = feGaussianBlur;
+}
+
+SVGGaussianBlurEffect.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    // Empirical value, matching AE's blur appearance.
+    var kBlurrinessToSigma = 0.3;
+    var sigma = this.filterManager.effectElements[0].p.v * kBlurrinessToSigma;
+
+    // Dimensions mapping:
+    //
+    //   1 -> horizontal & vertical
+    //   2 -> horizontal only
+    //   3 -> vertical only
+    //
+    var dimensions = this.filterManager.effectElements[1].p.v;
+    var sigmaX = (dimensions == 3) ? 0 : sigma; // eslint-disable-line eqeqeq
+    var sigmaY = (dimensions == 2) ? 0 : sigma; // eslint-disable-line eqeqeq
+
+    this.feGaussianBlur.setAttribute('stdDeviation', sigmaX + ' ' + sigmaY);
+
+    // Repeat edges mapping:
+    //
+    //   0 -> off -> duplicate
+    //   1 -> on  -> wrap
+    var edgeMode = (this.filterManager.effectElements[2].p.v == 1) ? 'wrap' : 'duplicate'; // eslint-disable-line eqeqeq
+    this.feGaussianBlur.setAttribute('edgeMode', edgeMode);
+  }
+};
+
+function TransformEffect() {
+}
+
+TransformEffect.prototype.init = function (effectsManager) {
+  this.effectsManager = effectsManager;
+  this.type = effectTypes.TRANSFORM_EFFECT;
+  this.matrix = new Matrix();
+  this.opacity = -1;
+  this._mdf = false;
+  this._opMdf = false;
+};
+
+TransformEffect.prototype.renderFrame = function (forceFrame) {
+  this._opMdf = false;
+  this._mdf = false;
+  if (forceFrame || this.effectsManager._mdf) {
+    var effectElements = this.effectsManager.effectElements;
+    var anchor = effectElements[0].p.v;
+    var position = effectElements[1].p.v;
+    var isUniformScale = effectElements[2].p.v === 1;
+    var scaleHeight = effectElements[3].p.v;
+    var scaleWidth = isUniformScale ? scaleHeight : effectElements[4].p.v;
+    var skew = effectElements[5].p.v;
+    var skewAxis = effectElements[6].p.v;
+    var rotation = effectElements[7].p.v;
+    this.matrix.reset();
+    this.matrix.translate(-anchor[0], -anchor[1], anchor[2]);
+    this.matrix.scale(scaleWidth * 0.01, scaleHeight * 0.01, 1);
+    this.matrix.rotate(-rotation * degToRads);
+    this.matrix.skewFromAxis(-skew * degToRads, (skewAxis + 90) * degToRads);
+    this.matrix.translate(position[0], position[1], 0);
+    this._mdf = true;
+    if (this.opacity !== effectElements[8].p.v) {
+      this.opacity = effectElements[8].p.v;
+      this._opMdf = true;
+    }
+  }
+};
+
+function SVGTransformEffect(_, filterManager) {
+  this.init(filterManager);
+}
+
+extendPrototype([TransformEffect], SVGTransformEffect);
+
+// Registering expression plugin
+setExpressionsPlugin(Expressions);
+setExpressionInterfaces(getInterface);
+initialize$1();
+initialize();
+registerEffect$1(20, SVGTintFilter, true);
+registerEffect$1(21, SVGFillFilter, true);
+registerEffect$1(22, SVGStrokeEffect, false);
+registerEffect$1(23, SVGTritoneFilter, true);
+registerEffect$1(24, SVGProLevelsFilter, true);
+registerEffect$1(25, SVGDropShadowEffect, true);
+registerEffect$1(28, SVGMatte3Effect, false);
+registerEffect$1(29, SVGGaussianBlurEffect, true);
+registerEffect$1(35, SVGTransformEffect, false);
+
+export { lottie as default };
diff --git a/build/player/esm/lottie_light.min.js b/build/player/esm/lottie_light.min.js
new file mode 100644
index 0000000..1e83094
--- /dev/null
+++ b/build/player/esm/lottie_light.min.js
@@ -0,0 +1,11580 @@
+const svgNS = 'http://www.w3.org/2000/svg';
+
+let locationHref = '';
+let _useWebWorker = false;
+
+const initialDefaultFrame = -999999;
+
+const setWebWorker = (flag) => { _useWebWorker = !!flag; };
+const getWebWorker = () => _useWebWorker;
+
+const setLocationHref = (value) => { locationHref = value; };
+const getLocationHref = () => locationHref;
+
+function createTag(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElement(type);
+}
+
+function extendPrototype(sources, destination) {
+  var i;
+  var len = sources.length;
+  var sourcePrototype;
+  for (i = 0; i < len; i += 1) {
+    sourcePrototype = sources[i].prototype;
+    for (var attr in sourcePrototype) {
+      if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
+    }
+  }
+}
+
+function getDescriptor(object, prop) {
+  return Object.getOwnPropertyDescriptor(object, prop);
+}
+
+function createProxyFunction(prototype) {
+  function ProxyFunction() {}
+  ProxyFunction.prototype = prototype;
+  return ProxyFunction;
+}
+
+// import Howl from '../../3rd_party/howler';
+
+const audioControllerFactory = (function () {
+  function AudioController(audioFactory) {
+    this.audios = [];
+    this.audioFactory = audioFactory;
+    this._volume = 1;
+    this._isMuted = false;
+  }
+
+  AudioController.prototype = {
+    addAudio: function (audio) {
+      this.audios.push(audio);
+    },
+    pause: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].pause();
+      }
+    },
+    resume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].resume();
+      }
+    },
+    setRate: function (rateValue) {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].setRate(rateValue);
+      }
+    },
+    createAudio: function (assetPath) {
+      if (this.audioFactory) {
+        return this.audioFactory(assetPath);
+      } if (window.Howl) {
+        return new window.Howl({
+          src: [assetPath],
+        });
+      }
+      return {
+        isPlaying: false,
+        play: function () { this.isPlaying = true; },
+        seek: function () { this.isPlaying = false; },
+        playing: function () {},
+        rate: function () {},
+        setVolume: function () {},
+      };
+    },
+    setAudioFactory: function (audioFactory) {
+      this.audioFactory = audioFactory;
+    },
+    setVolume: function (value) {
+      this._volume = value;
+      this._updateVolume();
+    },
+    mute: function () {
+      this._isMuted = true;
+      this._updateVolume();
+    },
+    unmute: function () {
+      this._isMuted = false;
+      this._updateVolume();
+    },
+    getVolume: function () {
+      return this._volume;
+    },
+    _updateVolume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
+      }
+    },
+  };
+
+  return function () {
+    return new AudioController();
+  };
+}());
+
+const createTypedArray = (function () {
+  function createRegularArray(type, len) {
+    var i = 0;
+    var arr = [];
+    var value;
+    switch (type) {
+      case 'int16':
+      case 'uint8c':
+        value = 1;
+        break;
+      default:
+        value = 1.1;
+        break;
+    }
+    for (i = 0; i < len; i += 1) {
+      arr.push(value);
+    }
+    return arr;
+  }
+  function createTypedArrayFactory(type, len) {
+    if (type === 'float32') {
+      return new Float32Array(len);
+    } if (type === 'int16') {
+      return new Int16Array(len);
+    } if (type === 'uint8c') {
+      return new Uint8ClampedArray(len);
+    }
+    return createRegularArray(type, len);
+  }
+  if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
+    return createTypedArrayFactory;
+  }
+  return createRegularArray;
+}());
+
+function createSizedArray(len) {
+  return Array.apply(null, { length: len });
+}
+
+let subframeEnabled = true;
+let expressionsPlugin = null;
+let expressionsInterfaces = null;
+let idPrefix$1 = '';
+const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+let _shouldRoundValues = false;
+const bmPow = Math.pow;
+const bmSqrt = Math.sqrt;
+const bmFloor = Math.floor;
+const bmMax = Math.max;
+const bmMin = Math.min;
+
+const BMMath = {};
+(function () {
+  var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
+  var i;
+  var len = propertyNames.length;
+  for (i = 0; i < len; i += 1) {
+    BMMath[propertyNames[i]] = Math[propertyNames[i]];
+  }
+}());
+
+function ProjectInterface$1() { return {}; }
+BMMath.random = Math.random;
+BMMath.abs = function (val) {
+  var tOfVal = typeof val;
+  if (tOfVal === 'object' && val.length) {
+    var absArr = createSizedArray(val.length);
+    var i;
+    var len = val.length;
+    for (i = 0; i < len; i += 1) {
+      absArr[i] = Math.abs(val[i]);
+    }
+    return absArr;
+  }
+  return Math.abs(val);
+};
+let defaultCurveSegments = 150;
+const degToRads = Math.PI / 180;
+const roundCorner = 0.5519;
+
+function roundValues(flag) {
+  _shouldRoundValues = !!flag;
+}
+
+function bmRnd(value) {
+  if (_shouldRoundValues) {
+    return Math.round(value);
+  }
+  return value;
+}
+
+function styleDiv(element) {
+  element.style.position = 'absolute';
+  element.style.top = 0;
+  element.style.left = 0;
+  element.style.display = 'block';
+  element.style.transformOrigin = '0 0';
+  element.style.webkitTransformOrigin = '0 0';
+  element.style.backfaceVisibility = 'visible';
+  element.style.webkitBackfaceVisibility = 'visible';
+  element.style.transformStyle = 'preserve-3d';
+  element.style.webkitTransformStyle = 'preserve-3d';
+  element.style.mozTransformStyle = 'preserve-3d';
+}
+
+function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
+  this.type = type;
+  this.currentTime = currentTime;
+  this.totalTime = totalTime;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteEvent(type, frameMultiplier) {
+  this.type = type;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
+  this.type = type;
+  this.currentLoop = currentLoop;
+  this.totalLoops = totalLoops;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMSegmentStartEvent(type, firstFrame, totalFrames) {
+  this.type = type;
+  this.firstFrame = firstFrame;
+  this.totalFrames = totalFrames;
+}
+
+function BMDestroyEvent(type, target) {
+  this.type = type;
+  this.target = target;
+}
+
+function BMRenderFrameErrorEvent(nativeError, currentTime) {
+  this.type = 'renderFrameError';
+  this.nativeError = nativeError;
+  this.currentTime = currentTime;
+}
+
+function BMConfigErrorEvent(nativeError) {
+  this.type = 'configError';
+  this.nativeError = nativeError;
+}
+
+function BMAnimationConfigErrorEvent(type, nativeError) {
+  this.type = type;
+  this.nativeError = nativeError;
+}
+
+const createElementID = (function () {
+  var _count = 0;
+  return function createID() {
+    _count += 1;
+    return idPrefix$1 + '__lottie_element_' + _count;
+  };
+}());
+
+function HSVtoRGB(h, s, v) {
+  var r;
+  var g;
+  var b;
+  var i;
+  var f;
+  var p;
+  var q;
+  var t;
+  i = Math.floor(h * 6);
+  f = h * 6 - i;
+  p = v * (1 - s);
+  q = v * (1 - f * s);
+  t = v * (1 - (1 - f) * s);
+  switch (i % 6) {
+    case 0: r = v; g = t; b = p; break;
+    case 1: r = q; g = v; b = p; break;
+    case 2: r = p; g = v; b = t; break;
+    case 3: r = p; g = q; b = v; break;
+    case 4: r = t; g = p; b = v; break;
+    case 5: r = v; g = p; b = q; break;
+    default: break;
+  }
+  return [r,
+    g,
+    b];
+}
+
+function RGBtoHSV(r, g, b) {
+  var max = Math.max(r, g, b);
+  var min = Math.min(r, g, b);
+  var d = max - min;
+  var h;
+  var s = (max === 0 ? 0 : d / max);
+  var v = max / 255;
+
+  switch (max) {
+    case min: h = 0; break;
+    case r: h = (g - b) + d * (g < b ? 6 : 0); h /= 6 * d; break;
+    case g: h = (b - r) + d * 2; h /= 6 * d; break;
+    case b: h = (r - g) + d * 4; h /= 6 * d; break;
+    default: break;
+  }
+
+  return [
+    h,
+    s,
+    v,
+  ];
+}
+
+function addSaturationToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[1] += offset;
+  if (hsv[1] > 1) {
+    hsv[1] = 1;
+  } else if (hsv[1] <= 0) {
+    hsv[1] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addBrightnessToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[2] += offset;
+  if (hsv[2] > 1) {
+    hsv[2] = 1;
+  } else if (hsv[2] < 0) {
+    hsv[2] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addHueToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[0] += offset / 360;
+  if (hsv[0] > 1) {
+    hsv[0] -= 1;
+  } else if (hsv[0] < 0) {
+    hsv[0] += 1;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+const rgbToHex = (function () {
+  var colorMap = [];
+  var i;
+  var hex;
+  for (i = 0; i < 256; i += 1) {
+    hex = i.toString(16);
+    colorMap[i] = hex.length === 1 ? '0' + hex : hex;
+  }
+
+  return function (r, g, b) {
+    if (r < 0) {
+      r = 0;
+    }
+    if (g < 0) {
+      g = 0;
+    }
+    if (b < 0) {
+      b = 0;
+    }
+    return '#' + colorMap[r] + colorMap[g] + colorMap[b];
+  };
+}());
+
+const setSubframeEnabled = (flag) => { subframeEnabled = !!flag; };
+const getSubframeEnabled = () => subframeEnabled;
+const setExpressionsPlugin = (value) => { expressionsPlugin = value; };
+const getExpressionsPlugin = () => expressionsPlugin;
+const setExpressionInterfaces = (value) => { expressionsInterfaces = value; };
+const getExpressionInterfaces = () => expressionsInterfaces;
+const setDefaultCurveSegments = (value) => { defaultCurveSegments = value; };
+const getDefaultCurveSegments = () => defaultCurveSegments;
+const setIdPrefix = (value) => { idPrefix$1 = value; };
+const getIdPrefix = () => idPrefix$1;
+
+function createNS(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElementNS(svgNS, type);
+}
+
+const dataManager = (function () {
+  var _counterId = 1;
+  var processes = [];
+  var workerFn;
+  var workerInstance;
+  var workerProxy = {
+    onmessage: function () {
+
+    },
+    postMessage: function (path) {
+      workerFn({
+        data: path,
+      });
+    },
+  };
+  var _workerSelf = {
+    postMessage: function (data) {
+      workerProxy.onmessage({
+        data: data,
+      });
+    },
+  };
+  function createWorker(fn) {
+    if (window.Worker && window.Blob && getWebWorker()) {
+      var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      var url = URL.createObjectURL(blob);
+      return new Worker(url);
+    }
+    workerFn = fn;
+    return workerProxy;
+  }
+
+  function setupWorker() {
+    if (!workerInstance) {
+      workerInstance = createWorker(function workerStart(e) {
+        function dataFunctionManager() {
+          function completeLayers(layers, comps) {
+            var layerData;
+            var i;
+            var len = layers.length;
+            var j;
+            var jLen;
+            var k;
+            var kLen;
+            for (i = 0; i < len; i += 1) {
+              layerData = layers[i];
+              if (('ks' in layerData) && !layerData.completed) {
+                layerData.completed = true;
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      convertPathsToAbsoluteValues(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) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 0) {
+                  layerData.layers = findCompLayers(layerData.refId, comps);
+                  completeLayers(layerData.layers, comps);
+                } else if (layerData.ty === 4) {
+                  completeShapes(layerData.shapes);
+                } else if (layerData.ty === 5) {
+                  completeText(layerData);
+                }
+              }
+            }
+          }
+
+          function completeChars(chars, assets) {
+            if (chars) {
+              var i = 0;
+              var len = chars.length;
+              for (i = 0; i < len; i += 1) {
+                if (chars[i].t === 1) {
+                  // var compData = findComp(chars[i].data.refId, assets);
+                  chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                  // chars[i].data.ip = 0;
+                  // chars[i].data.op = 99999;
+                  // chars[i].data.st = 0;
+                  // chars[i].data.sr = 1;
+                  // chars[i].w = compData.w;
+                  // chars[i].data.ks = {
+                  //   a: { k: [0, 0, 0], a: 0 },
+                  //   p: { k: [0, -compData.h, 0], a: 0 },
+                  //   r: { k: 0, a: 0 },
+                  //   s: { k: [100, 100], a: 0 },
+                  //   o: { k: 100, a: 0 },
+                  // };
+                  completeLayers(chars[i].data.layers, assets);
+                }
+              }
+            }
+          }
+
+          function findComp(id, comps) {
+            var i = 0;
+            var len = comps.length;
+            while (i < len) {
+              if (comps[i].id === id) {
+                return comps[i];
+              }
+              i += 1;
+            }
+            return null;
+          }
+
+          function findCompLayers(id, comps) {
+            var comp = findComp(id, comps);
+            if (comp) {
+              if (!comp.layers.__used) {
+                comp.layers.__used = true;
+                return comp.layers;
+              }
+              return JSON.parse(JSON.stringify(comp.layers));
+            }
+            return null;
+          }
+
+          function completeShapes(arr) {
+            var i;
+            var len = arr.length;
+            var j;
+            var jLen;
+            for (i = len - 1; i >= 0; i -= 1) {
+              if (arr[i].ty === 'sh') {
+                if (arr[i].ks.k.i) {
+                  convertPathsToAbsoluteValues(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) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
+                    }
+                    if (arr[i].ks.k[j].e) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
+                    }
+                  }
+                }
+              } else if (arr[i].ty === 'gr') {
+                completeShapes(arr[i].it);
+              }
+            }
+          }
+
+          function convertPathsToAbsoluteValues(path) {
+            var i;
+            var len = path.i.length;
+            for (i = 0; i < len; i += 1) {
+              path.i[i][0] += path.v[i][0];
+              path.i[i][1] += path.v[i][1];
+              path.o[i][0] += path.v[i][0];
+              path.o[i][1] += path.v[i][1];
+            }
+          }
+
+          function checkVersion(minimum, animVersionString) {
+            var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
+            if (minimum[0] > animVersion[0]) {
+              return true;
+            } if (animVersion[0] > minimum[0]) {
+              return false;
+            }
+            if (minimum[1] > animVersion[1]) {
+              return true;
+            } if (animVersion[1] > minimum[1]) {
+              return false;
+            }
+            if (minimum[2] > animVersion[2]) {
+              return true;
+            } if (animVersion[2] > minimum[2]) {
+              return false;
+            }
+            return null;
+          }
+
+          var checkText = (function () {
+            var minimumVersion = [4, 4, 14];
+
+            function updateTextLayer(textLayer) {
+              var documentData = textLayer.t.d;
+              textLayer.t.d = {
+                k: [
+                  {
+                    s: documentData,
+                    t: 0,
+                  },
+                ],
+              };
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkChars = (function () {
+            var minimumVersion = [4, 7, 99];
+            return function (animationData) {
+              if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
+                var i;
+                var len = animationData.chars.length;
+                for (i = 0; i < len; i += 1) {
+                  var charData = animationData.chars[i];
+                  if (charData.data && charData.data.shapes) {
+                    completeShapes(charData.data.shapes);
+                    charData.data.ip = 0;
+                    charData.data.op = 99999;
+                    charData.data.st = 0;
+                    charData.data.sr = 1;
+                    charData.data.ks = {
+                      p: { k: [0, 0], a: 0 },
+                      s: { k: [100, 100], a: 0 },
+                      a: { k: [0, 0], a: 0 },
+                      r: { k: 0, a: 0 },
+                      o: { k: 100, a: 0 },
+                    };
+                    if (!animationData.chars[i].t) {
+                      charData.data.shapes.push(
+                        {
+                          ty: 'no',
+                        }
+                      );
+                      charData.data.shapes[0].it.push(
+                        {
+                          p: { k: [0, 0], a: 0 },
+                          s: { k: [100, 100], a: 0 },
+                          a: { k: [0, 0], a: 0 },
+                          r: { k: 0, a: 0 },
+                          o: { k: 100, a: 0 },
+                          sk: { k: 0, a: 0 },
+                          sa: { k: 0, a: 0 },
+                          ty: 'tr',
+                        }
+                      );
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkPathProperties = (function () {
+            var minimumVersion = [5, 7, 15];
+
+            function updateTextLayer(textLayer) {
+              var pathData = textLayer.t.p;
+              if (typeof pathData.a === 'number') {
+                pathData.a = {
+                  a: 0,
+                  k: pathData.a,
+                };
+              }
+              if (typeof pathData.p === 'number') {
+                pathData.p = {
+                  a: 0,
+                  k: pathData.p,
+                };
+              }
+              if (typeof pathData.r === 'number') {
+                pathData.r = {
+                  a: 0,
+                  k: pathData.r,
+                };
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkColors = (function () {
+            var minimumVersion = [4, 1, 9];
+
+            function iterateShapes(shapes) {
+              var i;
+              var len = shapes.length;
+              var j;
+              var jLen;
+              for (i = 0; i < len; i += 1) {
+                if (shapes[i].ty === 'gr') {
+                  iterateShapes(shapes[i].it);
+                } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
+                  if (shapes[i].c.k && shapes[i].c.k[0].i) {
+                    jLen = shapes[i].c.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (shapes[i].c.k[j].s) {
+                        shapes[i].c.k[j].s[0] /= 255;
+                        shapes[i].c.k[j].s[1] /= 255;
+                        shapes[i].c.k[j].s[2] /= 255;
+                        shapes[i].c.k[j].s[3] /= 255;
+                      }
+                      if (shapes[i].c.k[j].e) {
+                        shapes[i].c.k[j].e[0] /= 255;
+                        shapes[i].c.k[j].e[1] /= 255;
+                        shapes[i].c.k[j].e[2] /= 255;
+                        shapes[i].c.k[j].e[3] /= 255;
+                      }
+                    }
+                  } else {
+                    shapes[i].c.k[0] /= 255;
+                    shapes[i].c.k[1] /= 255;
+                    shapes[i].c.k[2] /= 255;
+                    shapes[i].c.k[3] /= 255;
+                  }
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 4) {
+                  iterateShapes(layers[i].shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkShapes = (function () {
+            var minimumVersion = [4, 4, 18];
+
+            function completeClosingShapes(arr) {
+              var i;
+              var len = arr.length;
+              var j;
+              var jLen;
+              for (i = len - 1; i >= 0; i -= 1) {
+                if (arr[i].ty === 'sh') {
+                  if (arr[i].ks.k.i) {
+                    arr[i].ks.k.c = arr[i].closed;
+                  } else {
+                    jLen = arr[i].ks.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (arr[i].ks.k[j].s) {
+                        arr[i].ks.k[j].s[0].c = arr[i].closed;
+                      }
+                      if (arr[i].ks.k[j].e) {
+                        arr[i].ks.k[j].e[0].c = arr[i].closed;
+                      }
+                    }
+                  }
+                } else if (arr[i].ty === 'gr') {
+                  completeClosingShapes(arr[i].it);
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var layerData;
+              var i;
+              var len = layers.length;
+              var j;
+              var jLen;
+              var k;
+              var kLen;
+              for (i = 0; i < len; i += 1) {
+                layerData = layers[i];
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      maskProps[j].pt.k.c = maskProps[j].cl;
+                    } else {
+                      kLen = maskProps[j].pt.k.length;
+                      for (k = 0; k < kLen; k += 1) {
+                        if (maskProps[j].pt.k[k].s) {
+                          maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 4) {
+                  completeClosingShapes(layerData.shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          function completeData(animationData) {
+            if (animationData.__complete) {
+              return;
+            }
+            checkColors(animationData);
+            checkText(animationData);
+            checkChars(animationData);
+            checkPathProperties(animationData);
+            checkShapes(animationData);
+            completeLayers(animationData.layers, animationData.assets);
+            completeChars(animationData.chars, animationData.assets);
+            animationData.__complete = true;
+          }
+
+          function completeText(data) {
+            if (data.t.a.length === 0 && !('m' in data.t.p)) {
+              // data.singleShape = true;
+            }
+          }
+
+          var moduleOb = {};
+          moduleOb.completeData = completeData;
+          moduleOb.checkColors = checkColors;
+          moduleOb.checkChars = checkChars;
+          moduleOb.checkPathProperties = checkPathProperties;
+          moduleOb.checkShapes = checkShapes;
+          moduleOb.completeLayers = completeLayers;
+
+          return moduleOb;
+        }
+        if (!_workerSelf.dataManager) {
+          _workerSelf.dataManager = dataFunctionManager();
+        }
+
+        if (!_workerSelf.assetLoader) {
+          _workerSelf.assetLoader = (function () {
+            function formatResponse(xhr) {
+              // using typeof doubles the time of execution of this method,
+              // so if available, it's better to use the header to validate the type
+              var contentTypeHeader = xhr.getResponseHeader('content-type');
+              if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
+                return xhr.response;
+              }
+              if (xhr.response && typeof xhr.response === 'object') {
+                return xhr.response;
+              } if (xhr.response && typeof xhr.response === 'string') {
+                return JSON.parse(xhr.response);
+              } if (xhr.responseText) {
+                return JSON.parse(xhr.responseText);
+              }
+              return null;
+            }
+
+            function loadAsset(path, fullPath, callback, errorCallback) {
+              var response;
+              var xhr = new XMLHttpRequest();
+              // set responseType after calling open or IE will break.
+              try {
+                // This crashes on Android WebView prior to KitKat
+                xhr.responseType = 'json';
+              } catch (err) {} // eslint-disable-line no-empty
+              xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4) {
+                  if (xhr.status === 200) {
+                    response = formatResponse(xhr);
+                    callback(response);
+                  } else {
+                    try {
+                      response = formatResponse(xhr);
+                      callback(response);
+                    } catch (err) {
+                      if (errorCallback) {
+                        errorCallback(err);
+                      }
+                    }
+                  }
+                }
+              };
+              try {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), path, true);
+              } catch (error) {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
+              }
+              xhr.send();
+            }
+            return {
+              load: loadAsset,
+            };
+          }());
+        }
+
+        if (e.data.type === 'loadAnimation') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.dataManager.completeData(data);
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        } else if (e.data.type === 'complete') {
+          var animation = e.data.animation;
+          _workerSelf.dataManager.completeData(animation);
+          _workerSelf.postMessage({
+            id: e.data.id,
+            payload: animation,
+            status: 'success',
+          });
+        } else if (e.data.type === 'loadData') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        }
+      });
+
+      workerInstance.onmessage = function (event) {
+        var data = event.data;
+        var id = data.id;
+        var process = processes[id];
+        processes[id] = null;
+        if (data.status === 'success') {
+          process.onComplete(data.payload);
+        } else if (process.onError) {
+          process.onError();
+        }
+      };
+    }
+  }
+
+  function createProcess(onComplete, onError) {
+    _counterId += 1;
+    var id = 'processId_' + _counterId;
+    processes[id] = {
+      onComplete: onComplete,
+      onError: onError,
+    };
+    return id;
+  }
+
+  function loadAnimation(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadAnimation',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function loadData(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadData',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function completeAnimation(anim, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'complete',
+      animation: anim,
+      id: processId,
+    });
+  }
+
+  return {
+    loadAnimation: loadAnimation,
+    loadData: loadData,
+    completeAnimation: completeAnimation,
+  };
+}());
+
+const ImagePreloader = (function () {
+  var proxyImage = (function () {
+    var canvas = createTag('canvas');
+    canvas.width = 1;
+    canvas.height = 1;
+    var ctx = canvas.getContext('2d');
+    ctx.fillStyle = 'rgba(0,0,0,0)';
+    ctx.fillRect(0, 0, 1, 1);
+    return canvas;
+  }());
+
+  function imageLoaded() {
+    this.loadedAssets += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+  function footageLoaded() {
+    this.loadedFootagesCount += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+
+  function getAssetsPath(assetData, assetsPath, originalPath) {
+    var path = '';
+    if (assetData.e) {
+      path = assetData.p;
+    } else if (assetsPath) {
+      var imagePath = assetData.p;
+      if (imagePath.indexOf('images/') !== -1) {
+        imagePath = imagePath.split('/')[1];
+      }
+      path = assetsPath + imagePath;
+    } else {
+      path = originalPath;
+      path += assetData.u ? assetData.u : '';
+      path += assetData.p;
+    }
+    return path;
+  }
+
+  function testImageLoaded(img) {
+    var _count = 0;
+    var intervalId = setInterval(function () {
+      var box = img.getBBox();
+      if (box.width || _count > 500) {
+        this._imageLoaded();
+        clearInterval(intervalId);
+      }
+      _count += 1;
+    }.bind(this), 50);
+  }
+
+  function createImageData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createNS('image');
+    if (isSafari) {
+      this.testImageLoaded(img);
+    } else {
+      img.addEventListener('load', this._imageLoaded, false);
+    }
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
+    if (this._elementHelper.append) {
+      this._elementHelper.append(img);
+    } else {
+      this._elementHelper.appendChild(img);
+    }
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createImgData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createTag('img');
+    img.crossOrigin = 'anonymous';
+    img.addEventListener('load', this._imageLoaded, false);
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.src = path;
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createFootageData(data) {
+    var ob = {
+      assetData: data,
+    };
+    var path = getAssetsPath(data, this.assetsPath, this.path);
+    dataManager.loadData(path, function (footageData) {
+      ob.img = footageData;
+      this._footageLoaded();
+    }.bind(this), function () {
+      ob.img = {};
+      this._footageLoaded();
+    }.bind(this));
+    return ob;
+  }
+
+  function loadAssets(assets, cb) {
+    this.imagesLoadedCb = cb;
+    var i;
+    var len = assets.length;
+    for (i = 0; i < len; i += 1) {
+      if (!assets[i].layers) {
+        if (!assets[i].t || assets[i].t === 'seq') {
+          this.totalImages += 1;
+          this.images.push(this._createImageData(assets[i]));
+        } else if (assets[i].t === 3) {
+          this.totalFootages += 1;
+          this.images.push(this.createFootageData(assets[i]));
+        }
+      }
+    }
+  }
+
+  function setPath(path) {
+    this.path = path || '';
+  }
+
+  function setAssetsPath(path) {
+    this.assetsPath = path || '';
+  }
+
+  function getAsset(assetData) {
+    var i = 0;
+    var len = this.images.length;
+    while (i < len) {
+      if (this.images[i].assetData === assetData) {
+        return this.images[i].img;
+      }
+      i += 1;
+    }
+    return null;
+  }
+
+  function destroy() {
+    this.imagesLoadedCb = null;
+    this.images.length = 0;
+  }
+
+  function loadedImages() {
+    return this.totalImages === this.loadedAssets;
+  }
+
+  function loadedFootages() {
+    return this.totalFootages === this.loadedFootagesCount;
+  }
+
+  function setCacheType(type, elementHelper) {
+    if (type === 'svg') {
+      this._elementHelper = elementHelper;
+      this._createImageData = this.createImageData.bind(this);
+    } else {
+      this._createImageData = this.createImgData.bind(this);
+    }
+  }
+
+  function ImagePreloaderFactory() {
+    this._imageLoaded = imageLoaded.bind(this);
+    this._footageLoaded = footageLoaded.bind(this);
+    this.testImageLoaded = testImageLoaded.bind(this);
+    this.createFootageData = createFootageData.bind(this);
+    this.assetsPath = '';
+    this.path = '';
+    this.totalImages = 0;
+    this.totalFootages = 0;
+    this.loadedAssets = 0;
+    this.loadedFootagesCount = 0;
+    this.imagesLoadedCb = null;
+    this.images = [];
+  }
+
+  ImagePreloaderFactory.prototype = {
+    loadAssets: loadAssets,
+    setAssetsPath: setAssetsPath,
+    setPath: setPath,
+    loadedImages: loadedImages,
+    loadedFootages: loadedFootages,
+    destroy: destroy,
+    getAsset: getAsset,
+    createImgData: createImgData,
+    createImageData: createImageData,
+    imageLoaded: imageLoaded,
+    footageLoaded: footageLoaded,
+    setCacheType: setCacheType,
+  };
+
+  return ImagePreloaderFactory;
+}());
+
+function BaseEvent() {}
+BaseEvent.prototype = {
+  triggerEvent: function (eventName, args) {
+    if (this._cbs[eventName]) {
+      var callbacks = this._cbs[eventName];
+      for (var i = 0; i < callbacks.length; i += 1) {
+        callbacks[i](args);
+      }
+    }
+  },
+  addEventListener: function (eventName, callback) {
+    if (!this._cbs[eventName]) {
+      this._cbs[eventName] = [];
+    }
+    this._cbs[eventName].push(callback);
+
+    return function () {
+      this.removeEventListener(eventName, callback);
+    }.bind(this);
+  },
+  removeEventListener: function (eventName, callback) {
+    if (!callback) {
+      this._cbs[eventName] = null;
+    } else if (this._cbs[eventName]) {
+      var i = 0;
+      var len = this._cbs[eventName].length;
+      while (i < len) {
+        if (this._cbs[eventName][i] === callback) {
+          this._cbs[eventName].splice(i, 1);
+          i -= 1;
+          len -= 1;
+        }
+        i += 1;
+      }
+      if (!this._cbs[eventName].length) {
+        this._cbs[eventName] = null;
+      }
+    }
+  },
+};
+
+const markerParser = (
+
+  function () {
+    function parsePayloadLines(payload) {
+      var lines = payload.split('\r\n');
+      var keys = {};
+      var line;
+      var keysCount = 0;
+      for (var i = 0; i < lines.length; i += 1) {
+        line = lines[i].split(':');
+        if (line.length === 2) {
+          keys[line[0]] = line[1].trim();
+          keysCount += 1;
+        }
+      }
+      if (keysCount === 0) {
+        throw new Error();
+      }
+      return keys;
+    }
+
+    return function (_markers) {
+      var markers = [];
+      for (var i = 0; i < _markers.length; i += 1) {
+        var _marker = _markers[i];
+        var markerData = {
+          time: _marker.tm,
+          duration: _marker.dr,
+        };
+        try {
+          markerData.payload = JSON.parse(_markers[i].cm);
+        } catch (_) {
+          try {
+            markerData.payload = parsePayloadLines(_markers[i].cm);
+          } catch (__) {
+            markerData.payload = {
+              name: _markers[i].cm,
+            };
+          }
+        }
+        markers.push(markerData);
+      }
+      return markers;
+    };
+  }());
+
+const ProjectInterface = (function () {
+  function registerComposition(comp) {
+    this.compositions.push(comp);
+  }
+
+  return function () {
+    function _thisProjectFunction(name) {
+      var i = 0;
+      var len = this.compositions.length;
+      while (i < len) {
+        if (this.compositions[i].data && this.compositions[i].data.nm === name) {
+          if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
+            this.compositions[i].prepareFrame(this.currentFrame);
+          }
+          return this.compositions[i].compInterface;
+        }
+        i += 1;
+      }
+      return null;
+    }
+
+    _thisProjectFunction.compositions = [];
+    _thisProjectFunction.currentFrame = 0;
+
+    _thisProjectFunction.registerComposition = registerComposition;
+
+    return _thisProjectFunction;
+  };
+}());
+
+const renderers = {};
+
+const registerRenderer = (key, value) => {
+  renderers[key] = value;
+};
+
+function getRenderer(key) {
+  return renderers[key];
+}
+
+function getRegisteredRenderer() {
+  // Returns canvas by default for compatibility
+  if (renderers.canvas) {
+    return 'canvas';
+  }
+  // Returns any renderer that is registered
+  for (const key in renderers) {
+    if (renderers[key]) {
+      return key;
+    }
+  }
+  return '';
+}
+
+const AnimationItem = function () {
+  this._cbs = [];
+  this.name = '';
+  this.path = '';
+  this.isLoaded = false;
+  this.currentFrame = 0;
+  this.currentRawFrame = 0;
+  this.firstFrame = 0;
+  this.totalFrames = 0;
+  this.frameRate = 0;
+  this.frameMult = 0;
+  this.playSpeed = 1;
+  this.playDirection = 1;
+  this.playCount = 0;
+  this.animationData = {};
+  this.assets = [];
+  this.isPaused = true;
+  this.autoplay = false;
+  this.loop = true;
+  this.renderer = null;
+  this.animationID = createElementID();
+  this.assetsPath = '';
+  this.timeCompleted = 0;
+  this.segmentPos = 0;
+  this.isSubframeEnabled = getSubframeEnabled();
+  this.segments = [];
+  this._idle = true;
+  this._completedLoop = false;
+  this.projectInterface = ProjectInterface();
+  this.imagePreloader = new ImagePreloader();
+  this.audioController = audioControllerFactory();
+  this.markers = [];
+  this.configAnimation = this.configAnimation.bind(this);
+  this.onSetupError = this.onSetupError.bind(this);
+  this.onSegmentComplete = this.onSegmentComplete.bind(this);
+  this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
+  this.expressionsPlugin = getExpressionsPlugin();
+};
+
+extendPrototype([BaseEvent], AnimationItem);
+
+AnimationItem.prototype.setParams = function (params) {
+  if (params.wrapper || params.container) {
+    this.wrapper = params.wrapper || params.container;
+  }
+  var animType = 'svg';
+  if (params.animType) {
+    animType = params.animType;
+  } else if (params.renderer) {
+    animType = params.renderer;
+  }
+  const RendererClass = getRenderer(animType);
+  this.renderer = new RendererClass(this, params.rendererSettings);
+  this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
+  this.renderer.setProjectInterface(this.projectInterface);
+  this.animType = animType;
+  if (params.loop === ''
+        || params.loop === null
+        || params.loop === undefined
+        || params.loop === true) {
+    this.loop = true;
+  } else if (params.loop === false) {
+    this.loop = false;
+  } else {
+    this.loop = parseInt(params.loop, 10);
+  }
+  this.autoplay = 'autoplay' in params ? params.autoplay : true;
+  this.name = params.name ? params.name : '';
+  this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
+  this.assetsPath = params.assetsPath;
+  this.initialSegment = params.initialSegment;
+  if (params.audioFactory) {
+    this.audioController.setAudioFactory(params.audioFactory);
+  }
+  if (params.animationData) {
+    this.setupAnimation(params.animationData);
+  } else if (params.path) {
+    if (params.path.lastIndexOf('\\') !== -1) {
+      this.path = params.path.substr(0, params.path.lastIndexOf('\\') + 1);
+    } else {
+      this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
+    }
+    this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
+    this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
+    dataManager.loadAnimation(
+      params.path,
+      this.configAnimation,
+      this.onSetupError
+    );
+  }
+};
+
+AnimationItem.prototype.onSetupError = function () {
+  this.trigger('data_failed');
+};
+
+AnimationItem.prototype.setupAnimation = function (data) {
+  dataManager.completeAnimation(
+    data,
+    this.configAnimation
+  );
+};
+
+AnimationItem.prototype.setData = function (wrapper, animationData) {
+  if (animationData) {
+    if (typeof animationData !== 'object') {
+      animationData = JSON.parse(animationData);
+    }
+  }
+  var params = {
+    wrapper: wrapper,
+    animationData: animationData,
+  };
+  var wrapperAttributes = wrapper.attributes;
+
+  params.path = wrapperAttributes.getNamedItem('data-animation-path') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-animation-path').value
+    : wrapperAttributes.getNamedItem('data-bm-path') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-path').value
+      : wrapperAttributes.getNamedItem('bm-path')
+        ? wrapperAttributes.getNamedItem('bm-path').value
+        : '';
+  params.animType = wrapperAttributes.getNamedItem('data-anim-type') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-type').value
+    : wrapperAttributes.getNamedItem('data-bm-type') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-type').value
+      : wrapperAttributes.getNamedItem('bm-type') // eslint-disable-line no-nested-ternary
+        ? wrapperAttributes.getNamedItem('bm-type').value
+        : wrapperAttributes.getNamedItem('data-bm-renderer') // eslint-disable-line no-nested-ternary
+          ? wrapperAttributes.getNamedItem('data-bm-renderer').value
+          : wrapperAttributes.getNamedItem('bm-renderer')
+            ? wrapperAttributes.getNamedItem('bm-renderer').value
+            : getRegisteredRenderer() || 'canvas';
+
+  var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-loop').value
+    : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-loop').value
+      : wrapperAttributes.getNamedItem('bm-loop')
+        ? wrapperAttributes.getNamedItem('bm-loop').value
+        : '';
+  if (loop === 'false') {
+    params.loop = false;
+  } else if (loop === 'true') {
+    params.loop = true;
+  } else if (loop !== '') {
+    params.loop = parseInt(loop, 10);
+  }
+  var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-autoplay').value
+    : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-autoplay').value
+      : wrapperAttributes.getNamedItem('bm-autoplay')
+        ? wrapperAttributes.getNamedItem('bm-autoplay').value
+        : true;
+  params.autoplay = autoplay !== 'false';
+
+  params.name = wrapperAttributes.getNamedItem('data-name') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-name').value
+    : wrapperAttributes.getNamedItem('data-bm-name') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-name').value
+      : wrapperAttributes.getNamedItem('bm-name')
+        ? wrapperAttributes.getNamedItem('bm-name').value
+        : '';
+  var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-prerender').value
+    : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-prerender').value
+      : wrapperAttributes.getNamedItem('bm-prerender')
+        ? wrapperAttributes.getNamedItem('bm-prerender').value
+        : '';
+
+  if (prerender === 'false') {
+    params.prerender = false;
+  }
+  if (!params.path) {
+    this.trigger('destroy');
+  } else {
+    this.setParams(params);
+  }
+};
+
+AnimationItem.prototype.includeLayers = function (data) {
+  if (data.op > this.animationData.op) {
+    this.animationData.op = data.op;
+    this.totalFrames = Math.floor(data.op - this.animationData.ip);
+  }
+  var layers = this.animationData.layers;
+  var i;
+  var len = layers.length;
+  var newLayers = data.layers;
+  var j;
+  var jLen = newLayers.length;
+  for (j = 0; j < jLen; j += 1) {
+    i = 0;
+    while (i < len) {
+      if (layers[i].id === newLayers[j].id) {
+        layers[i] = newLayers[j];
+        break;
+      }
+      i += 1;
+    }
+  }
+  if (data.chars || data.fonts) {
+    this.renderer.globalData.fontManager.addChars(data.chars);
+    this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
+  }
+  if (data.assets) {
+    len = data.assets.length;
+    for (i = 0; i < len; i += 1) {
+      this.animationData.assets.push(data.assets[i]);
+    }
+  }
+  this.animationData.__complete = false;
+  dataManager.completeAnimation(
+    this.animationData,
+    this.onSegmentComplete
+  );
+};
+
+AnimationItem.prototype.onSegmentComplete = function (data) {
+  this.animationData = data;
+  var expressionsPlugin = getExpressionsPlugin();
+  if (expressionsPlugin) {
+    expressionsPlugin.initExpressions(this);
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.loadNextSegment = function () {
+  var segments = this.animationData.segments;
+  if (!segments || segments.length === 0 || !this.autoloadSegments) {
+    this.trigger('data_ready');
+    this.timeCompleted = this.totalFrames;
+    return;
+  }
+  var segment = segments.shift();
+  this.timeCompleted = segment.time * this.frameRate;
+  var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
+  this.segmentPos += 1;
+  dataManager.loadData(segmentPath, this.includeLayers.bind(this), function () {
+    this.trigger('data_failed');
+  }.bind(this));
+};
+
+AnimationItem.prototype.loadSegments = function () {
+  var segments = this.animationData.segments;
+  if (!segments) {
+    this.timeCompleted = this.totalFrames;
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.imagesLoaded = function () {
+  this.trigger('loaded_images');
+  this.checkLoaded();
+};
+
+AnimationItem.prototype.preloadImages = function () {
+  this.imagePreloader.setAssetsPath(this.assetsPath);
+  this.imagePreloader.setPath(this.path);
+  this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
+};
+
+AnimationItem.prototype.configAnimation = function (animData) {
+  if (!this.renderer) {
+    return;
+  }
+  try {
+    this.animationData = animData;
+    if (this.initialSegment) {
+      this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
+      this.firstFrame = Math.round(this.initialSegment[0]);
+    } else {
+      this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
+      this.firstFrame = Math.round(this.animationData.ip);
+    }
+    this.renderer.configAnimation(animData);
+    if (!animData.assets) {
+      animData.assets = [];
+    }
+
+    this.assets = this.animationData.assets;
+    this.frameRate = this.animationData.fr;
+    this.frameMult = this.animationData.fr / 1000;
+    this.renderer.searchExtraCompositions(animData.assets);
+    this.markers = markerParser(animData.markers || []);
+    this.trigger('config_ready');
+    this.preloadImages();
+    this.loadSegments();
+    this.updaFrameModifier();
+    this.waitForFontsLoaded();
+    if (this.isPaused) {
+      this.audioController.pause();
+    }
+  } catch (error) {
+    this.triggerConfigError(error);
+  }
+};
+
+AnimationItem.prototype.waitForFontsLoaded = function () {
+  if (!this.renderer) {
+    return;
+  }
+  if (this.renderer.globalData.fontManager.isLoaded) {
+    this.checkLoaded();
+  } else {
+    setTimeout(this.waitForFontsLoaded.bind(this), 20);
+  }
+};
+
+AnimationItem.prototype.checkLoaded = function () {
+  if (!this.isLoaded
+        && this.renderer.globalData.fontManager.isLoaded
+        && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas')
+        && (this.imagePreloader.loadedFootages())
+  ) {
+    this.isLoaded = true;
+    var expressionsPlugin = getExpressionsPlugin();
+    if (expressionsPlugin) {
+      expressionsPlugin.initExpressions(this);
+    }
+    this.renderer.initItems();
+    setTimeout(function () {
+      this.trigger('DOMLoaded');
+    }.bind(this), 0);
+    this.gotoFrame();
+    if (this.autoplay) {
+      this.play();
+    }
+  }
+};
+
+AnimationItem.prototype.resize = function (width, height) {
+  // Adding this validation for backwards compatibility in case an event object was being passed down
+  var _width = typeof width === 'number' ? width : undefined;
+  var _height = typeof height === 'number' ? height : undefined;
+  this.renderer.updateContainerSize(_width, _height);
+};
+
+AnimationItem.prototype.setSubframe = function (flag) {
+  this.isSubframeEnabled = !!flag;
+};
+
+AnimationItem.prototype.gotoFrame = function () {
+  this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
+
+  if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
+    this.currentFrame = this.timeCompleted;
+  }
+  this.trigger('enterFrame');
+  this.renderFrame();
+  this.trigger('drawnFrame');
+};
+
+AnimationItem.prototype.renderFrame = function () {
+  if (this.isLoaded === false || !this.renderer) {
+    return;
+  }
+  try {
+    if (this.expressionsPlugin) {
+      this.expressionsPlugin.resetFrame();
+    }
+    this.renderer.renderFrame(this.currentFrame + this.firstFrame);
+  } catch (error) {
+    this.triggerRenderFrameError(error);
+  }
+};
+
+AnimationItem.prototype.play = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.isPaused = false;
+    this.trigger('_play');
+    this.audioController.resume();
+    if (this._idle) {
+      this._idle = false;
+      this.trigger('_active');
+    }
+  }
+};
+
+AnimationItem.prototype.pause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === false) {
+    this.isPaused = true;
+    this.trigger('_pause');
+    this._idle = true;
+    this.trigger('_idle');
+    this.audioController.pause();
+  }
+};
+
+AnimationItem.prototype.togglePause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.play();
+  } else {
+    this.pause();
+  }
+};
+
+AnimationItem.prototype.stop = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.pause();
+  this.playCount = 0;
+  this._completedLoop = false;
+  this.setCurrentRawFrameValue(0);
+};
+
+AnimationItem.prototype.getMarkerData = function (markerName) {
+  var marker;
+  for (var i = 0; i < this.markers.length; i += 1) {
+    marker = this.markers[i];
+    if (marker.payload && marker.payload.name === markerName) {
+      return marker;
+    }
+  }
+  return null;
+};
+
+AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      this.goToAndStop(marker.time, true);
+    }
+  } else if (isFrame) {
+    this.setCurrentRawFrameValue(value);
+  } else {
+    this.setCurrentRawFrameValue(value * this.frameModifier);
+  }
+  this.pause();
+};
+
+AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      if (!marker.duration) {
+        this.goToAndStop(marker.time, true);
+      } else {
+        this.playSegments([marker.time, marker.time + marker.duration], true);
+      }
+    }
+  } else {
+    this.goToAndStop(numValue, isFrame, name);
+  }
+  this.play();
+};
+
+AnimationItem.prototype.advanceTime = function (value) {
+  if (this.isPaused === true || this.isLoaded === false) {
+    return;
+  }
+  var nextValue = this.currentRawFrame + value * this.frameModifier;
+  var _isComplete = false;
+  // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+  // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
+  if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
+    if (!this.loop || this.playCount === this.loop) {
+      if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
+        _isComplete = true;
+        nextValue = this.totalFrames - 1;
+      }
+    } else if (nextValue >= this.totalFrames) {
+      this.playCount += 1;
+      if (!this.checkSegments(nextValue % this.totalFrames)) {
+        this.setCurrentRawFrameValue(nextValue % this.totalFrames);
+        this._completedLoop = true;
+        this.trigger('loopComplete');
+      }
+    } else {
+      this.setCurrentRawFrameValue(nextValue);
+    }
+  } else if (nextValue < 0) {
+    if (!this.checkSegments(nextValue % this.totalFrames)) {
+      if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) { // eslint-disable-line no-plusplus
+        this.setCurrentRawFrameValue(this.totalFrames + (nextValue % this.totalFrames));
+        if (!this._completedLoop) {
+          this._completedLoop = true;
+        } else {
+          this.trigger('loopComplete');
+        }
+      } else {
+        _isComplete = true;
+        nextValue = 0;
+      }
+    }
+  } else {
+    this.setCurrentRawFrameValue(nextValue);
+  }
+  if (_isComplete) {
+    this.setCurrentRawFrameValue(nextValue);
+    this.pause();
+    this.trigger('complete');
+  }
+};
+
+AnimationItem.prototype.adjustSegment = function (arr, offset) {
+  this.playCount = 0;
+  if (arr[1] < arr[0]) {
+    if (this.frameModifier > 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(-1);
+      }
+    }
+    this.totalFrames = arr[0] - arr[1];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[1];
+    this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset);
+  } else if (arr[1] > arr[0]) {
+    if (this.frameModifier < 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(1);
+      }
+    }
+    this.totalFrames = arr[1] - arr[0];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[0];
+    this.setCurrentRawFrameValue(0.001 + offset);
+  }
+  this.trigger('segmentStart');
+};
+AnimationItem.prototype.setSegment = function (init, end) {
+  var pendingFrame = -1;
+  if (this.isPaused) {
+    if (this.currentRawFrame + this.firstFrame < init) {
+      pendingFrame = init;
+    } else if (this.currentRawFrame + this.firstFrame > end) {
+      pendingFrame = end - init;
+    }
+  }
+
+  this.firstFrame = init;
+  this.totalFrames = end - init;
+  this.timeCompleted = this.totalFrames;
+  if (pendingFrame !== -1) {
+    this.goToAndStop(pendingFrame, true);
+  }
+};
+
+AnimationItem.prototype.playSegments = function (arr, forceFlag) {
+  if (forceFlag) {
+    this.segments.length = 0;
+  }
+  if (typeof arr[0] === 'object') {
+    var i;
+    var len = arr.length;
+    for (i = 0; i < len; i += 1) {
+      this.segments.push(arr[i]);
+    }
+  } else {
+    this.segments.push(arr);
+  }
+  if (this.segments.length && forceFlag) {
+    this.adjustSegment(this.segments.shift(), 0);
+  }
+  if (this.isPaused) {
+    this.play();
+  }
+};
+
+AnimationItem.prototype.resetSegments = function (forceFlag) {
+  this.segments.length = 0;
+  this.segments.push([this.animationData.ip, this.animationData.op]);
+  if (forceFlag) {
+    this.checkSegments(0);
+  }
+};
+AnimationItem.prototype.checkSegments = function (offset) {
+  if (this.segments.length) {
+    this.adjustSegment(this.segments.shift(), offset);
+    return true;
+  }
+  return false;
+};
+
+AnimationItem.prototype.destroy = function (name) {
+  if ((name && this.name !== name) || !this.renderer) {
+    return;
+  }
+  this.renderer.destroy();
+  this.imagePreloader.destroy();
+  this.trigger('destroy');
+  this._cbs = null;
+  this.onEnterFrame = null;
+  this.onLoopComplete = null;
+  this.onComplete = null;
+  this.onSegmentStart = null;
+  this.onDestroy = null;
+  this.renderer = null;
+  this.expressionsPlugin = null;
+  this.imagePreloader = null;
+  this.projectInterface = null;
+};
+
+AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
+  this.currentRawFrame = value;
+  this.gotoFrame();
+};
+
+AnimationItem.prototype.setSpeed = function (val) {
+  this.playSpeed = val;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setDirection = function (val) {
+  this.playDirection = val < 0 ? -1 : 1;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setLoop = function (isLooping) {
+  this.loop = isLooping;
+};
+
+AnimationItem.prototype.setVolume = function (val, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.setVolume(val);
+};
+
+AnimationItem.prototype.getVolume = function () {
+  return this.audioController.getVolume();
+};
+
+AnimationItem.prototype.mute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.mute();
+};
+
+AnimationItem.prototype.unmute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.unmute();
+};
+
+AnimationItem.prototype.updaFrameModifier = function () {
+  this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
+  this.audioController.setRate(this.playSpeed * this.playDirection);
+};
+
+AnimationItem.prototype.getPath = function () {
+  return this.path;
+};
+
+AnimationItem.prototype.getAssetsPath = function (assetData) {
+  var path = '';
+  if (assetData.e) {
+    path = assetData.p;
+  } else if (this.assetsPath) {
+    var imagePath = assetData.p;
+    if (imagePath.indexOf('images/') !== -1) {
+      imagePath = imagePath.split('/')[1];
+    }
+    path = this.assetsPath + imagePath;
+  } else {
+    path = this.path;
+    path += assetData.u ? assetData.u : '';
+    path += assetData.p;
+  }
+  return path;
+};
+
+AnimationItem.prototype.getAssetData = function (id) {
+  var i = 0;
+  var len = this.assets.length;
+  while (i < len) {
+    if (id === this.assets[i].id) {
+      return this.assets[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+AnimationItem.prototype.hide = function () {
+  this.renderer.hide();
+};
+
+AnimationItem.prototype.show = function () {
+  this.renderer.show();
+};
+
+AnimationItem.prototype.getDuration = function (isFrame) {
+  return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
+};
+
+AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
+  try {
+    var element = this.renderer.getElementByPath(path);
+    element.updateDocumentData(documentData, index);
+  } catch (error) {
+    // TODO: decide how to handle catch case
+  }
+};
+
+AnimationItem.prototype.trigger = function (name) {
+  if (this._cbs && this._cbs[name]) {
+    switch (name) {
+      case 'enterFrame':
+        this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
+        break;
+      case 'drawnFrame':
+        this.drawnFrameEvent.currentTime = this.currentFrame;
+        this.drawnFrameEvent.totalTime = this.totalFrames;
+        this.drawnFrameEvent.direction = this.frameModifier;
+        this.triggerEvent(name, this.drawnFrameEvent);
+        break;
+      case 'loopComplete':
+        this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+        break;
+      case 'complete':
+        this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
+        break;
+      case 'segmentStart':
+        this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+        break;
+      case 'destroy':
+        this.triggerEvent(name, new BMDestroyEvent(name, this));
+        break;
+      default:
+        this.triggerEvent(name);
+    }
+  }
+  if (name === 'enterFrame' && this.onEnterFrame) {
+    this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
+  }
+  if (name === 'loopComplete' && this.onLoopComplete) {
+    this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+  }
+  if (name === 'complete' && this.onComplete) {
+    this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
+  }
+  if (name === 'segmentStart' && this.onSegmentStart) {
+    this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+  }
+  if (name === 'destroy' && this.onDestroy) {
+    this.onDestroy.call(this, new BMDestroyEvent(name, this));
+  }
+};
+
+AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
+  var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+AnimationItem.prototype.triggerConfigError = function (nativeError) {
+  var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+const animationManager = (function () {
+  var moduleOb = {};
+  var registeredAnimations = [];
+  var initTime = 0;
+  var len = 0;
+  var playingAnimationsNum = 0;
+  var _stopped = true;
+  var _isFrozen = false;
+
+  function removeElement(ev) {
+    var i = 0;
+    var animItem = ev.target;
+    while (i < len) {
+      if (registeredAnimations[i].animation === animItem) {
+        registeredAnimations.splice(i, 1);
+        i -= 1;
+        len -= 1;
+        if (!animItem.isPaused) {
+          subtractPlayingCount();
+        }
+      }
+      i += 1;
+    }
+  }
+
+  function registerAnimation(element, animationData) {
+    if (!element) {
+      return null;
+    }
+    var i = 0;
+    while (i < len) {
+      if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
+        return registeredAnimations[i].animation;
+      }
+      i += 1;
+    }
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, element);
+    animItem.setData(element, animationData);
+    return animItem;
+  }
+
+  function getRegisteredAnimations() {
+    var i;
+    var lenAnims = registeredAnimations.length;
+    var animations = [];
+    for (i = 0; i < lenAnims; i += 1) {
+      animations.push(registeredAnimations[i].animation);
+    }
+    return animations;
+  }
+
+  function addPlayingCount() {
+    playingAnimationsNum += 1;
+    activate();
+  }
+
+  function subtractPlayingCount() {
+    playingAnimationsNum -= 1;
+  }
+
+  function setupAnimation(animItem, element) {
+    animItem.addEventListener('destroy', removeElement);
+    animItem.addEventListener('_active', addPlayingCount);
+    animItem.addEventListener('_idle', subtractPlayingCount);
+    registeredAnimations.push({ elem: element, animation: animItem });
+    len += 1;
+  }
+
+  function loadAnimation(params) {
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, null);
+    animItem.setParams(params);
+    return animItem;
+  }
+
+  function setSpeed(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setSpeed(val, animation);
+    }
+  }
+
+  function setDirection(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setDirection(val, animation);
+    }
+  }
+
+  function play(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.play(animation);
+    }
+  }
+  function resume(nowTime) {
+    var elapsedTime = nowTime - initTime;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.advanceTime(elapsedTime);
+    }
+    initTime = nowTime;
+    if (playingAnimationsNum && !_isFrozen) {
+      window.requestAnimationFrame(resume);
+    } else {
+      _stopped = true;
+    }
+  }
+
+  function first(nowTime) {
+    initTime = nowTime;
+    window.requestAnimationFrame(resume);
+  }
+
+  function pause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.pause(animation);
+    }
+  }
+
+  function goToAndStop(value, isFrame, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
+    }
+  }
+
+  function stop(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.stop(animation);
+    }
+  }
+
+  function togglePause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.togglePause(animation);
+    }
+  }
+
+  function destroy(animation) {
+    var i;
+    for (i = (len - 1); i >= 0; i -= 1) {
+      registeredAnimations[i].animation.destroy(animation);
+    }
+  }
+
+  function searchAnimations(animationData, standalone, renderer) {
+    var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')),
+      [].slice.call(document.getElementsByClassName('bodymovin')));
+    var i;
+    var lenAnims = animElements.length;
+    for (i = 0; i < lenAnims; i += 1) {
+      if (renderer) {
+        animElements[i].setAttribute('data-bm-type', renderer);
+      }
+      registerAnimation(animElements[i], animationData);
+    }
+    if (standalone && lenAnims === 0) {
+      if (!renderer) {
+        renderer = 'svg';
+      }
+      var body = document.getElementsByTagName('body')[0];
+      body.innerText = '';
+      var div = createTag('div');
+      div.style.width = '100%';
+      div.style.height = '100%';
+      div.setAttribute('data-bm-type', renderer);
+      body.appendChild(div);
+      registerAnimation(div, animationData);
+    }
+  }
+
+  function resize() {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.resize();
+    }
+  }
+
+  function activate() {
+    if (!_isFrozen && playingAnimationsNum) {
+      if (_stopped) {
+        window.requestAnimationFrame(first);
+        _stopped = false;
+      }
+    }
+  }
+
+  function freeze() {
+    _isFrozen = true;
+  }
+
+  function unfreeze() {
+    _isFrozen = false;
+    activate();
+  }
+
+  function setVolume(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setVolume(val, animation);
+    }
+  }
+
+  function mute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.mute(animation);
+    }
+  }
+
+  function unmute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.unmute(animation);
+    }
+  }
+
+  moduleOb.registerAnimation = registerAnimation;
+  moduleOb.loadAnimation = loadAnimation;
+  moduleOb.setSpeed = setSpeed;
+  moduleOb.setDirection = setDirection;
+  moduleOb.play = play;
+  moduleOb.pause = pause;
+  moduleOb.stop = stop;
+  moduleOb.togglePause = togglePause;
+  moduleOb.searchAnimations = searchAnimations;
+  moduleOb.resize = resize;
+  // moduleOb.start = start;
+  moduleOb.goToAndStop = goToAndStop;
+  moduleOb.destroy = destroy;
+  moduleOb.freeze = freeze;
+  moduleOb.unfreeze = unfreeze;
+  moduleOb.setVolume = setVolume;
+  moduleOb.mute = mute;
+  moduleOb.unmute = unmute;
+  moduleOb.getRegisteredAnimations = getRegisteredAnimations;
+  return moduleOb;
+}());
+
+/* eslint-disable */
+const BezierFactory = (function () {
+  /**
+     * BezierEasing - use bezier curve for transition easing function
+     * by Gaëtan Renaudeau 2014 - 2015 – MIT License
+     *
+     * Credits: is based on Firefox's nsSMILKeySpline.cpp
+     * Usage:
+     * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
+     * spline.get(x) => returns the easing value | x must be in [0, 1] range
+     *
+     */
+
+  var ob = {};
+  ob.getBezierEasing = getBezierEasing;
+  var beziers = {};
+
+  function getBezierEasing(a, b, c, d, nm) {
+    var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
+    if (beziers[str]) {
+      return beziers[str];
+    }
+    var bezEasing = new BezierEasing([a, b, c, d]);
+    beziers[str] = bezEasing;
+    return bezEasing;
+  }
+
+  // These values are established by empiricism with tests (tradeoff: performance VS precision)
+  var NEWTON_ITERATIONS = 4;
+  var NEWTON_MIN_SLOPE = 0.001;
+  var SUBDIVISION_PRECISION = 0.0000001;
+  var SUBDIVISION_MAX_ITERATIONS = 10;
+
+  var kSplineTableSize = 11;
+  var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
+
+  var float32ArraySupported = typeof Float32Array === 'function';
+
+  function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
+  function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
+  function C(aA1) { return 3.0 * aA1; }
+
+  // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+  function calcBezier(aT, aA1, aA2) {
+    return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
+  }
+
+  // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+  function getSlope(aT, aA1, aA2) {
+    return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
+  }
+
+  function binarySubdivide(aX, aA, aB, mX1, mX2) {
+    var currentX,
+      currentT,
+      i = 0;
+    do {
+      currentT = aA + (aB - aA) / 2.0;
+      currentX = calcBezier(currentT, mX1, mX2) - aX;
+      if (currentX > 0.0) {
+        aB = currentT;
+      } else {
+        aA = currentT;
+      }
+    } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
+    return currentT;
+  }
+
+  function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
+    for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
+      var currentSlope = getSlope(aGuessT, mX1, mX2);
+      if (currentSlope === 0.0) return aGuessT;
+      var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
+      aGuessT -= currentX / currentSlope;
+    }
+    return aGuessT;
+  }
+
+  /**
+     * points is an array of [ mX1, mY1, mX2, mY2 ]
+     */
+  function BezierEasing(points) {
+    this._p = points;
+    this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
+    this._precomputed = false;
+
+    this.get = this.get.bind(this);
+  }
+
+  BezierEasing.prototype = {
+
+    get: function (x) {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      if (!this._precomputed) this._precompute();
+      if (mX1 === mY1 && mX2 === mY2) return x; // linear
+      // Because JavaScript number are imprecise, we should guarantee the extremes are right.
+      if (x === 0) return 0;
+      if (x === 1) return 1;
+      return calcBezier(this._getTForX(x), mY1, mY2);
+    },
+
+    // Private part
+
+    _precompute: function () {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      this._precomputed = true;
+      if (mX1 !== mY1 || mX2 !== mY2) { this._calcSampleValues(); }
+    },
+
+    _calcSampleValues: function () {
+      var mX1 = this._p[0],
+        mX2 = this._p[2];
+      for (var i = 0; i < kSplineTableSize; ++i) {
+        this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
+      }
+    },
+
+    /**
+         * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
+         */
+    _getTForX: function (aX) {
+      var mX1 = this._p[0],
+        mX2 = this._p[2],
+        mSampleValues = this._mSampleValues;
+
+      var intervalStart = 0.0;
+      var currentSample = 1;
+      var lastSample = kSplineTableSize - 1;
+
+      for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
+        intervalStart += kSampleStepSize;
+      }
+      --currentSample;
+
+      // Interpolate to provide an initial guess for t
+      var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
+      var guessForT = intervalStart + dist * kSampleStepSize;
+
+      var initialSlope = getSlope(guessForT, mX1, mX2);
+      if (initialSlope >= NEWTON_MIN_SLOPE) {
+        return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
+      } if (initialSlope === 0.0) {
+        return guessForT;
+      }
+      return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
+    },
+  };
+
+  return ob;
+}());
+
+const pooling = (function () {
+  function double(arr) {
+    return arr.concat(createSizedArray(arr.length));
+  }
+
+  return {
+    double: double,
+  };
+}());
+
+const poolFactory = (function () {
+  return function (initialLength, _create, _release) {
+    var _length = 0;
+    var _maxLength = initialLength;
+    var pool = createSizedArray(_maxLength);
+
+    var ob = {
+      newElement: newElement,
+      release: release,
+    };
+
+    function newElement() {
+      var element;
+      if (_length) {
+        _length -= 1;
+        element = pool[_length];
+      } else {
+        element = _create();
+      }
+      return element;
+    }
+
+    function release(element) {
+      if (_length === _maxLength) {
+        pool = pooling.double(pool);
+        _maxLength *= 2;
+      }
+      if (_release) {
+        _release(element);
+      }
+      pool[_length] = element;
+      _length += 1;
+    }
+
+    return ob;
+  };
+}());
+
+const bezierLengthPool = (function () {
+  function create() {
+    return {
+      addedLength: 0,
+      percents: createTypedArray('float32', getDefaultCurveSegments()),
+      lengths: createTypedArray('float32', getDefaultCurveSegments()),
+    };
+  }
+  return poolFactory(8, create);
+}());
+
+const segmentsLengthPool = (function () {
+  function create() {
+    return {
+      lengths: [],
+      totalLength: 0,
+    };
+  }
+
+  function release(element) {
+    var i;
+    var len = element.lengths.length;
+    for (i = 0; i < len; i += 1) {
+      bezierLengthPool.release(element.lengths[i]);
+    }
+    element.lengths.length = 0;
+  }
+
+  return poolFactory(8, create, release);
+}());
+
+function bezFunction() {
+  var math = Math;
+
+  function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
+    var det1 = (x1 * y2) + (y1 * x3) + (x2 * y3) - (x3 * y2) - (y3 * x1) - (x2 * y1);
+    return det1 > -0.001 && det1 < 0.001;
+  }
+
+  function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
+    if (z1 === 0 && z2 === 0 && z3 === 0) {
+      return pointOnLine2D(x1, y1, x2, y2, x3, y3);
+    }
+    var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
+    var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
+    var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
+    var diffDist;
+    if (dist1 > dist2) {
+      if (dist1 > dist3) {
+        diffDist = dist1 - dist2 - dist3;
+      } else {
+        diffDist = dist3 - dist2 - dist1;
+      }
+    } else if (dist3 > dist2) {
+      diffDist = dist3 - dist2 - dist1;
+    } else {
+      diffDist = dist2 - dist1 - dist3;
+    }
+    return diffDist > -0.0001 && diffDist < 0.0001;
+  }
+
+  var getBezierLength = (function () {
+    return function (pt1, pt2, pt3, pt4) {
+      var curveSegments = getDefaultCurveSegments();
+      var k;
+      var i;
+      var len;
+      var ptCoord;
+      var perc;
+      var addedLength = 0;
+      var ptDistance;
+      var point = [];
+      var lastPoint = [];
+      var lengthData = bezierLengthPool.newElement();
+      len = pt3.length;
+      for (k = 0; k < curveSegments; k += 1) {
+        perc = k / (curveSegments - 1);
+        ptDistance = 0;
+        for (i = 0; i < len; i += 1) {
+          ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
+          point[i] = ptCoord;
+          if (lastPoint[i] !== null) {
+            ptDistance += bmPow(point[i] - lastPoint[i], 2);
+          }
+          lastPoint[i] = point[i];
+        }
+        if (ptDistance) {
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+        }
+        lengthData.percents[k] = perc;
+        lengthData.lengths[k] = addedLength;
+      }
+      lengthData.addedLength = addedLength;
+      return lengthData;
+    };
+  }());
+
+  function getSegmentsLength(shapeData) {
+    var segmentsLength = segmentsLengthPool.newElement();
+    var closed = shapeData.c;
+    var pathV = shapeData.v;
+    var pathO = shapeData.o;
+    var pathI = shapeData.i;
+    var i;
+    var len = shapeData._length;
+    var lengths = segmentsLength.lengths;
+    var totalLength = 0;
+    for (i = 0; i < len - 1; i += 1) {
+      lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
+      totalLength += lengths[i].addedLength;
+    }
+    if (closed && len) {
+      lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
+      totalLength += lengths[i].addedLength;
+    }
+    segmentsLength.totalLength = totalLength;
+    return segmentsLength;
+  }
+
+  function BezierData(length) {
+    this.segmentLength = 0;
+    this.points = new Array(length);
+  }
+
+  function PointData(partial, point) {
+    this.partialLength = partial;
+    this.point = point;
+  }
+
+  var buildBezierData = (function () {
+    var storedData = {};
+
+    return function (pt1, pt2, pt3, pt4) {
+      var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
+      if (!storedData[bezierName]) {
+        var curveSegments = getDefaultCurveSegments();
+        var k;
+        var i;
+        var len;
+        var ptCoord;
+        var perc;
+        var addedLength = 0;
+        var ptDistance;
+        var point;
+        var lastPoint = null;
+        if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
+          curveSegments = 2;
+        }
+        var bezierData = new BezierData(curveSegments);
+        len = pt3.length;
+        for (k = 0; k < curveSegments; k += 1) {
+          point = createSizedArray(len);
+          perc = k / (curveSegments - 1);
+          ptDistance = 0;
+          for (i = 0; i < len; i += 1) {
+            ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
+            point[i] = ptCoord;
+            if (lastPoint !== null) {
+              ptDistance += bmPow(point[i] - lastPoint[i], 2);
+            }
+          }
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+          bezierData.points[k] = new PointData(ptDistance, point);
+          lastPoint = point;
+        }
+        bezierData.segmentLength = addedLength;
+        storedData[bezierName] = bezierData;
+      }
+      return storedData[bezierName];
+    };
+  }());
+
+  function getDistancePerc(perc, bezierData) {
+    var percents = bezierData.percents;
+    var lengths = bezierData.lengths;
+    var len = percents.length;
+    var initPos = bmFloor((len - 1) * perc);
+    var lengthPos = perc * bezierData.addedLength;
+    var lPerc = 0;
+    if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
+      return percents[initPos];
+    }
+    var dir = lengths[initPos] > lengthPos ? -1 : 1;
+    var flag = true;
+    while (flag) {
+      if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
+        lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
+        flag = false;
+      } else {
+        initPos += dir;
+      }
+      if (initPos < 0 || initPos >= len - 1) {
+        // FIX for TypedArrays that don't store floating point values with enough accuracy
+        if (initPos === len - 1) {
+          return percents[initPos];
+        }
+        flag = false;
+      }
+    }
+    return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
+  }
+
+  function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
+    var t1 = getDistancePerc(percent, bezierData);
+    var u1 = 1 - t1;
+    var ptX = math.round((u1 * u1 * u1 * pt1[0] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[0] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[0] + t1 * t1 * t1 * pt2[0]) * 1000) / 1000;
+    var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
+    return [ptX, ptY];
+  }
+
+  var bezierSegmentPoints = createTypedArray('float32', 8);
+
+  function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
+    if (startPerc < 0) {
+      startPerc = 0;
+    } else if (startPerc > 1) {
+      startPerc = 1;
+    }
+    var t0 = getDistancePerc(startPerc, bezierData);
+    endPerc = endPerc > 1 ? 1 : endPerc;
+    var t1 = getDistancePerc(endPerc, bezierData);
+    var i;
+    var len = pt1.length;
+    var u0 = 1 - t0;
+    var u1 = 1 - t1;
+    var u0u0u0 = u0 * u0 * u0;
+    var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0t0 = t0 * t0 * t0;
+    //
+    var u0u0u1 = u0 * u0 * u1;
+    var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0t1 = t0 * t0 * t1;
+    //
+    var u0u1u1 = u0 * u1 * u1;
+    var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1t1 = t0 * t1 * t1;
+    //
+    var u1u1u1 = u1 * u1 * u1;
+    var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1t1 = t1 * t1 * t1;
+    for (i = 0; i < len; i += 1) {
+      bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+    }
+
+    return bezierSegmentPoints;
+  }
+
+  return {
+    getSegmentsLength: getSegmentsLength,
+    getNewSegment: getNewSegment,
+    getPointInSegment: getPointInSegment,
+    buildBezierData: buildBezierData,
+    pointOnLine2D: pointOnLine2D,
+    pointOnLine3D: pointOnLine3D,
+  };
+}
+
+const bez = bezFunction();
+
+var initFrame = initialDefaultFrame;
+var mathAbs = Math.abs;
+
+function interpolateValue(frameNum, caching) {
+  var offsetTime = this.offsetTime;
+  var newValue;
+  if (this.propType === 'multidimensional') {
+    newValue = createTypedArray('float32', this.pv.length);
+  }
+  var iterationIndex = caching.lastIndex;
+  var i = iterationIndex;
+  var len = this.keyframes.length - 1;
+  var flag = true;
+  var keyData;
+  var nextKeyData;
+  var keyframeMetadata;
+
+  while (flag) {
+    keyData = this.keyframes[i];
+    nextKeyData = this.keyframes[i + 1];
+    if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
+      if (keyData.h) {
+        keyData = nextKeyData;
+      }
+      iterationIndex = 0;
+      break;
+    }
+    if ((nextKeyData.t - offsetTime) > frameNum) {
+      iterationIndex = i;
+      break;
+    }
+    if (i < len - 1) {
+      i += 1;
+    } else {
+      iterationIndex = 0;
+      flag = false;
+    }
+  }
+  keyframeMetadata = this.keyframesMetadata[i] || {};
+
+  var k;
+  var kLen;
+  var perc;
+  var jLen;
+  var j;
+  var fnc;
+  var nextKeyTime = nextKeyData.t - offsetTime;
+  var keyTime = keyData.t - offsetTime;
+  var endValue;
+  if (keyData.to) {
+    if (!keyframeMetadata.bezierData) {
+      keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
+    }
+    var bezierData = keyframeMetadata.bezierData;
+    if (frameNum >= nextKeyTime || frameNum < keyTime) {
+      var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
+      kLen = bezierData.points[ind].point.length;
+      for (k = 0; k < kLen; k += 1) {
+        newValue[k] = bezierData.points[ind].point[k];
+      }
+      // caching._lastKeyframeIndex = -1;
+    } else {
+      if (keyframeMetadata.__fnct) {
+        fnc = keyframeMetadata.__fnct;
+      } else {
+        fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
+        keyframeMetadata.__fnct = fnc;
+      }
+      perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+      var distanceInLine = bezierData.segmentLength * perc;
+
+      var segmentPerc;
+      var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0;
+      j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0;
+      flag = true;
+      jLen = bezierData.points.length;
+      while (flag) {
+        addedLength += bezierData.points[j].partialLength;
+        if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k];
+          }
+          break;
+        } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
+          segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
+          }
+          break;
+        }
+        if (j < jLen - 1) {
+          j += 1;
+        } else {
+          flag = false;
+        }
+      }
+      caching._lastPoint = j;
+      caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
+      caching._lastKeyframeIndex = i;
+    }
+  } else {
+    var outX;
+    var outY;
+    var inX;
+    var inY;
+    var keyValue;
+    len = keyData.s.length;
+    endValue = nextKeyData.s || keyData.e;
+    if (this.sh && keyData.h !== 1) {
+      if (frameNum >= nextKeyTime) {
+        newValue[0] = endValue[0];
+        newValue[1] = endValue[1];
+        newValue[2] = endValue[2];
+      } else if (frameNum <= keyTime) {
+        newValue[0] = keyData.s[0];
+        newValue[1] = keyData.s[1];
+        newValue[2] = keyData.s[2];
+      } else {
+        var quatStart = createQuaternion(keyData.s);
+        var quatEnd = createQuaternion(endValue);
+        var time = (frameNum - keyTime) / (nextKeyTime - keyTime);
+        quaternionToEuler(newValue, slerp(quatStart, quatEnd, time));
+      }
+    } else {
+      for (i = 0; i < len; i += 1) {
+        if (keyData.h !== 1) {
+          if (frameNum >= nextKeyTime) {
+            perc = 1;
+          } else if (frameNum < keyTime) {
+            perc = 0;
+          } else {
+            if (keyData.o.x.constructor === Array) {
+              if (!keyframeMetadata.__fnct) {
+                keyframeMetadata.__fnct = [];
+              }
+              if (!keyframeMetadata.__fnct[i]) {
+                outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
+                outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
+                inX = keyData.i.x[i] === undefined ? keyData.i.x[0] : keyData.i.x[i];
+                inY = keyData.i.y[i] === undefined ? keyData.i.y[0] : keyData.i.y[i];
+                fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+                keyframeMetadata.__fnct[i] = fnc;
+              } else {
+                fnc = keyframeMetadata.__fnct[i];
+              }
+            } else if (!keyframeMetadata.__fnct) {
+              outX = keyData.o.x;
+              outY = keyData.o.y;
+              inX = keyData.i.x;
+              inY = keyData.i.y;
+              fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+              keyData.keyframeMetadata = fnc;
+            } else {
+              fnc = keyframeMetadata.__fnct;
+            }
+            perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+          }
+        }
+
+        endValue = nextKeyData.s || keyData.e;
+        keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
+
+        if (this.propType === 'multidimensional') {
+          newValue[i] = keyValue;
+        } else {
+          newValue = keyValue;
+        }
+      }
+    }
+  }
+  caching.lastIndex = iterationIndex;
+  return newValue;
+}
+
+// based on @Toji's https://github.com/toji/gl-matrix/
+function slerp(a, b, t) {
+  var out = [];
+  var ax = a[0];
+  var ay = a[1];
+  var az = a[2];
+  var aw = a[3];
+  var bx = b[0];
+  var by = b[1];
+  var bz = b[2];
+  var bw = b[3];
+
+  var omega;
+  var cosom;
+  var sinom;
+  var scale0;
+  var scale1;
+
+  cosom = ax * bx + ay * by + az * bz + aw * bw;
+  if (cosom < 0.0) {
+    cosom = -cosom;
+    bx = -bx;
+    by = -by;
+    bz = -bz;
+    bw = -bw;
+  }
+  if ((1.0 - cosom) > 0.000001) {
+    omega = Math.acos(cosom);
+    sinom = Math.sin(omega);
+    scale0 = Math.sin((1.0 - t) * omega) / sinom;
+    scale1 = Math.sin(t * omega) / sinom;
+  } else {
+    scale0 = 1.0 - t;
+    scale1 = t;
+  }
+  out[0] = scale0 * ax + scale1 * bx;
+  out[1] = scale0 * ay + scale1 * by;
+  out[2] = scale0 * az + scale1 * bz;
+  out[3] = scale0 * aw + scale1 * bw;
+
+  return out;
+}
+
+function quaternionToEuler(out, quat) {
+  var qx = quat[0];
+  var qy = quat[1];
+  var qz = quat[2];
+  var qw = quat[3];
+  var heading = Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy * qy - 2 * qz * qz);
+  var attitude = Math.asin(2 * qx * qy + 2 * qz * qw);
+  var bank = Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx * qx - 2 * qz * qz);
+  out[0] = heading / degToRads;
+  out[1] = attitude / degToRads;
+  out[2] = bank / degToRads;
+}
+
+function createQuaternion(values) {
+  var heading = values[0] * degToRads;
+  var attitude = values[1] * degToRads;
+  var bank = values[2] * degToRads;
+  var c1 = Math.cos(heading / 2);
+  var c2 = Math.cos(attitude / 2);
+  var c3 = Math.cos(bank / 2);
+  var s1 = Math.sin(heading / 2);
+  var s2 = Math.sin(attitude / 2);
+  var s3 = Math.sin(bank / 2);
+  var w = c1 * c2 * c3 - s1 * s2 * s3;
+  var x = s1 * s2 * c3 + c1 * c2 * s3;
+  var y = s1 * c2 * c3 + c1 * s2 * s3;
+  var z = c1 * s2 * c3 - s1 * c2 * s3;
+
+  return [x, y, z, w];
+}
+
+function getValueAtCurrentTime() {
+  var frameNum = this.comp.renderedFrame - this.offsetTime;
+  var initTime = this.keyframes[0].t - this.offsetTime;
+  var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+  if (!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))) {
+    if (this._caching.lastFrame >= frameNum) {
+      this._caching._lastKeyframeIndex = -1;
+      this._caching.lastIndex = 0;
+    }
+
+    var renderResult = this.interpolateValue(frameNum, this._caching);
+    this.pv = renderResult;
+  }
+  this._caching.lastFrame = frameNum;
+  return this.pv;
+}
+
+function setVValue(val) {
+  var multipliedValue;
+  if (this.propType === 'unidimensional') {
+    multipliedValue = val * this.mult;
+    if (mathAbs(this.v - multipliedValue) > 0.00001) {
+      this.v = multipliedValue;
+      this._mdf = true;
+    }
+  } else {
+    var i = 0;
+    var len = this.v.length;
+    while (i < len) {
+      multipliedValue = val[i] * this.mult;
+      if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
+        this.v[i] = multipliedValue;
+        this._mdf = true;
+      }
+      i += 1;
+    }
+  }
+}
+
+function processEffectsSequence() {
+  if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
+    return;
+  }
+  if (this.lock) {
+    this.setVValue(this.pv);
+    return;
+  }
+  this.lock = true;
+  this._mdf = this._isFirstFrame;
+  var i;
+  var len = this.effectsSequence.length;
+  var finalValue = this.kf ? this.pv : this.data.k;
+  for (i = 0; i < len; i += 1) {
+    finalValue = this.effectsSequence[i](finalValue);
+  }
+  this.setVValue(finalValue);
+  this._isFirstFrame = false;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+}
+
+function addEffect(effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.container.addDynamicProperty(this);
+}
+
+function ValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this.v = mult ? data.k * mult : data.k;
+  this.pv = data.k;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.vel = 0;
+  this.effectsSequence = [];
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function MultiDimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.frameId = -1;
+  var i;
+  var len = data.k.length;
+  this.v = createTypedArray('float32', len);
+  this.pv = createTypedArray('float32', len);
+  this.vel = createTypedArray('float32', len);
+  for (i = 0; i < len; i += 1) {
+    this.v[i] = data.k[i] * this.mult;
+    this.pv[i] = data.k[i];
+  }
+  this._isFirstFrame = true;
+  this.effectsSequence = [];
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function KeyframedValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.frameId = -1;
+  this._caching = {
+    lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1,
+  };
+  this.k = true;
+  this.kf = true;
+  this.data = data;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.v = initFrame;
+  this.pv = initFrame;
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.addEffect = addEffect;
+}
+
+function KeyframedMultidimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  var i;
+  var len = data.k.length;
+  var s;
+  var e;
+  var to;
+  var ti;
+  for (i = 0; i < len - 1; i += 1) {
+    if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
+      s = data.k[i].s;
+      e = data.k[i + 1].s;
+      to = data.k[i].to;
+      ti = data.k[i].ti;
+      if ((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2]))) {
+        data.k[i].to = null;
+        data.k[i].ti = null;
+      }
+      if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
+        if (s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) {
+          data.k[i].to = null;
+          data.k[i].ti = null;
+        }
+      }
+    }
+  }
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.data = data;
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.k = true;
+  this.kf = true;
+  this._isFirstFrame = true;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.frameId = -1;
+  var arrLen = data.k[0].s.length;
+  this.v = createTypedArray('float32', arrLen);
+  this.pv = createTypedArray('float32', arrLen);
+  for (i = 0; i < arrLen; i += 1) {
+    this.v[i] = initFrame;
+    this.pv[i] = initFrame;
+  }
+  this._caching = { lastFrame: initFrame, lastIndex: 0, value: createTypedArray('float32', arrLen) };
+  this.addEffect = addEffect;
+}
+
+const PropertyFactory = (function () {
+  function getProp(elem, data, type, mult, container) {
+    if (data.sid) {
+      data = elem.globalData.slotManager.getProp(data);
+    }
+    var p;
+    if (!data.k.length) {
+      p = new ValueProperty(elem, data, mult, container);
+    } else if (typeof (data.k[0]) === 'number') {
+      p = new MultiDimensionalProperty(elem, data, mult, container);
+    } else {
+      switch (type) {
+        case 0:
+          p = new KeyframedValueProperty(elem, data, mult, container);
+          break;
+        case 1:
+          p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
+          break;
+        default:
+          break;
+      }
+    }
+    if (p.effectsSequence.length) {
+      container.addDynamicProperty(p);
+    }
+    return p;
+  }
+
+  var ob = {
+    getProp: getProp,
+  };
+  return ob;
+}());
+
+function DynamicPropertyContainer() {}
+DynamicPropertyContainer.prototype = {
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+      this.container.addDynamicProperty(this);
+      this._isAnimated = true;
+    }
+  },
+  iterateDynamicProperties: function () {
+    this._mdf = false;
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      this.dynamicProperties[i].getValue();
+      if (this.dynamicProperties[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  },
+  initDynamicPropertyContainer: function (container) {
+    this.container = container;
+    this.dynamicProperties = [];
+    this._mdf = false;
+    this._isAnimated = false;
+  },
+};
+
+const pointPool = (function () {
+  function create() {
+    return createTypedArray('float32', 2);
+  }
+  return poolFactory(8, create);
+}());
+
+function ShapePath() {
+  this.c = false;
+  this._length = 0;
+  this._maxLength = 8;
+  this.v = createSizedArray(this._maxLength);
+  this.o = createSizedArray(this._maxLength);
+  this.i = createSizedArray(this._maxLength);
+}
+
+ShapePath.prototype.setPathData = function (closed, len) {
+  this.c = closed;
+  this.setLength(len);
+  var i = 0;
+  while (i < len) {
+    this.v[i] = pointPool.newElement();
+    this.o[i] = pointPool.newElement();
+    this.i[i] = pointPool.newElement();
+    i += 1;
+  }
+};
+
+ShapePath.prototype.setLength = function (len) {
+  while (this._maxLength < len) {
+    this.doubleArrayLength();
+  }
+  this._length = len;
+};
+
+ShapePath.prototype.doubleArrayLength = function () {
+  this.v = this.v.concat(createSizedArray(this._maxLength));
+  this.i = this.i.concat(createSizedArray(this._maxLength));
+  this.o = this.o.concat(createSizedArray(this._maxLength));
+  this._maxLength *= 2;
+};
+
+ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
+  var arr;
+  this._length = Math.max(this._length, pos + 1);
+  if (this._length >= this._maxLength) {
+    this.doubleArrayLength();
+  }
+  switch (type) {
+    case 'v':
+      arr = this.v;
+      break;
+    case 'i':
+      arr = this.i;
+      break;
+    case 'o':
+      arr = this.o;
+      break;
+    default:
+      arr = [];
+      break;
+  }
+  if (!arr[pos] || (arr[pos] && !replace)) {
+    arr[pos] = pointPool.newElement();
+  }
+  arr[pos][0] = x;
+  arr[pos][1] = y;
+};
+
+ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
+  this.setXYAt(vX, vY, 'v', pos, replace);
+  this.setXYAt(oX, oY, 'o', pos, replace);
+  this.setXYAt(iX, iY, 'i', pos, replace);
+};
+
+ShapePath.prototype.reverse = function () {
+  var newPath = new ShapePath();
+  newPath.setPathData(this.c, this._length);
+  var vertices = this.v;
+  var outPoints = this.o;
+  var inPoints = this.i;
+  var init = 0;
+  if (this.c) {
+    newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
+    init = 1;
+  }
+  var cnt = this._length - 1;
+  var len = this._length;
+
+  var i;
+  for (i = init; i < len; i += 1) {
+    newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
+    cnt -= 1;
+  }
+  return newPath;
+};
+
+ShapePath.prototype.length = function () {
+  return this._length;
+};
+
+const shapePool = (function () {
+  function create() {
+    return new ShapePath();
+  }
+
+  function release(shapePath) {
+    var len = shapePath._length;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      pointPool.release(shapePath.v[i]);
+      pointPool.release(shapePath.i[i]);
+      pointPool.release(shapePath.o[i]);
+      shapePath.v[i] = null;
+      shapePath.i[i] = null;
+      shapePath.o[i] = null;
+    }
+    shapePath._length = 0;
+    shapePath.c = false;
+  }
+
+  function clone(shape) {
+    var cloned = factory.newElement();
+    var i;
+    var len = shape._length === undefined ? shape.v.length : shape._length;
+    cloned.setLength(len);
+    cloned.c = shape.c;
+
+    for (i = 0; i < len; i += 1) {
+      cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
+    }
+    return cloned;
+  }
+
+  var factory = poolFactory(4, create, release);
+  factory.clone = clone;
+
+  return factory;
+}());
+
+function ShapeCollection() {
+  this._length = 0;
+  this._maxLength = 4;
+  this.shapes = createSizedArray(this._maxLength);
+}
+
+ShapeCollection.prototype.addShape = function (shapeData) {
+  if (this._length === this._maxLength) {
+    this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
+    this._maxLength *= 2;
+  }
+  this.shapes[this._length] = shapeData;
+  this._length += 1;
+};
+
+ShapeCollection.prototype.releaseShapes = function () {
+  var i;
+  for (i = 0; i < this._length; i += 1) {
+    shapePool.release(this.shapes[i]);
+  }
+  this._length = 0;
+};
+
+const shapeCollectionPool = (function () {
+  var ob = {
+    newShapeCollection: newShapeCollection,
+    release: release,
+  };
+
+  var _length = 0;
+  var _maxLength = 4;
+  var pool = createSizedArray(_maxLength);
+
+  function newShapeCollection() {
+    var shapeCollection;
+    if (_length) {
+      _length -= 1;
+      shapeCollection = pool[_length];
+    } else {
+      shapeCollection = new ShapeCollection();
+    }
+    return shapeCollection;
+  }
+
+  function release(shapeCollection) {
+    var i;
+    var len = shapeCollection._length;
+    for (i = 0; i < len; i += 1) {
+      shapePool.release(shapeCollection.shapes[i]);
+    }
+    shapeCollection._length = 0;
+
+    if (_length === _maxLength) {
+      pool = pooling.double(pool);
+      _maxLength *= 2;
+    }
+    pool[_length] = shapeCollection;
+    _length += 1;
+  }
+
+  return ob;
+}());
+
+const ShapePropertyFactory = (function () {
+  var initFrame = -999999;
+
+  function interpolateShape(frameNum, previousValue, caching) {
+    var iterationIndex = caching.lastIndex;
+    var keyPropS;
+    var keyPropE;
+    var isHold;
+    var j;
+    var k;
+    var jLen;
+    var kLen;
+    var perc;
+    var vertexValue;
+    var kf = this.keyframes;
+    if (frameNum < kf[0].t - this.offsetTime) {
+      keyPropS = kf[0].s[0];
+      isHold = true;
+      iterationIndex = 0;
+    } else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) {
+      keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
+      /* if(kf[kf.length - 1].s){
+                keyPropS = kf[kf.length - 1].s[0];
+            }else{
+                keyPropS = kf[kf.length - 2].e[0];
+            } */
+      isHold = true;
+    } else {
+      var i = iterationIndex;
+      var len = kf.length - 1;
+      var flag = true;
+      var keyData;
+      var nextKeyData;
+      var keyframeMetadata;
+      while (flag) {
+        keyData = kf[i];
+        nextKeyData = kf[i + 1];
+        if ((nextKeyData.t - this.offsetTime) > frameNum) {
+          break;
+        }
+        if (i < len - 1) {
+          i += 1;
+        } else {
+          flag = false;
+        }
+      }
+      keyframeMetadata = this.keyframesMetadata[i] || {};
+      isHold = keyData.h === 1;
+      iterationIndex = i;
+      if (!isHold) {
+        if (frameNum >= nextKeyData.t - this.offsetTime) {
+          perc = 1;
+        } else if (frameNum < keyData.t - this.offsetTime) {
+          perc = 0;
+        } else {
+          var fnc;
+          if (keyframeMetadata.__fnct) {
+            fnc = keyframeMetadata.__fnct;
+          } else {
+            fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
+            keyframeMetadata.__fnct = fnc;
+          }
+          perc = fnc((frameNum - (keyData.t - this.offsetTime)) / ((nextKeyData.t - this.offsetTime) - (keyData.t - this.offsetTime)));
+        }
+        keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
+      }
+      keyPropS = keyData.s[0];
+    }
+    jLen = previousValue._length;
+    kLen = keyPropS.i[0].length;
+    caching.lastIndex = iterationIndex;
+
+    for (j = 0; j < jLen; j += 1) {
+      for (k = 0; k < kLen; k += 1) {
+        vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
+        previousValue.i[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc;
+        previousValue.o[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc;
+        previousValue.v[j][k] = vertexValue;
+      }
+    }
+  }
+
+  function interpolateShapeCurrentTime() {
+    var frameNum = this.comp.renderedFrame - this.offsetTime;
+    var initTime = this.keyframes[0].t - this.offsetTime;
+    var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+    var lastFrame = this._caching.lastFrame;
+    if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) {
+      /// /
+      this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
+      this.interpolateShape(frameNum, this.pv, this._caching);
+      /// /
+    }
+    this._caching.lastFrame = frameNum;
+    return this.pv;
+  }
+
+  function resetShape() {
+    this.paths = this.localShapeCollection;
+  }
+
+  function shapesEqual(shape1, shape2) {
+    if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
+      return false;
+    }
+    var i;
+    var len = shape1._length;
+    for (i = 0; i < len; i += 1) {
+      if (shape1.v[i][0] !== shape2.v[i][0]
+            || shape1.v[i][1] !== shape2.v[i][1]
+            || shape1.o[i][0] !== shape2.o[i][0]
+            || shape1.o[i][1] !== shape2.o[i][1]
+            || shape1.i[i][0] !== shape2.i[i][0]
+            || shape1.i[i][1] !== shape2.i[i][1]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  function setVValue(newPath) {
+    if (!shapesEqual(this.v, newPath)) {
+      this.v = shapePool.clone(newPath);
+      this.localShapeCollection.releaseShapes();
+      this.localShapeCollection.addShape(this.v);
+      this._mdf = true;
+      this.paths = this.localShapeCollection;
+    }
+  }
+
+  function processEffectsSequence() {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    } if (!this.effectsSequence.length) {
+      this._mdf = false;
+      return;
+    }
+    if (this.lock) {
+      this.setVValue(this.pv);
+      return;
+    }
+    this.lock = true;
+    this._mdf = false;
+    var finalValue;
+    if (this.kf) {
+      finalValue = this.pv;
+    } else if (this.data.ks) {
+      finalValue = this.data.ks.k;
+    } else {
+      finalValue = this.data.pt.k;
+    }
+    var i;
+    var len = this.effectsSequence.length;
+    for (i = 0; i < len; i += 1) {
+      finalValue = this.effectsSequence[i](finalValue);
+    }
+    this.setVValue(finalValue);
+    this.lock = false;
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function ShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.container = elem;
+    this.elem = elem;
+    this.data = data;
+    this.k = false;
+    this.kf = false;
+    this._mdf = false;
+    var pathData = type === 3 ? data.pt.k : data.ks.k;
+    this.v = shapePool.clone(pathData);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.reset = resetShape;
+    this.effectsSequence = [];
+  }
+
+  function addEffect(effectFunction) {
+    this.effectsSequence.push(effectFunction);
+    this.container.addDynamicProperty(this);
+  }
+
+  ShapeProperty.prototype.interpolateShape = interpolateShape;
+  ShapeProperty.prototype.getValue = processEffectsSequence;
+  ShapeProperty.prototype.setVValue = setVValue;
+  ShapeProperty.prototype.addEffect = addEffect;
+
+  function KeyframedShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.elem = elem;
+    this.container = elem;
+    this.offsetTime = elem.data.st;
+    this.keyframes = type === 3 ? data.pt.k : data.ks.k;
+    this.keyframesMetadata = [];
+    this.k = true;
+    this.kf = true;
+    var len = this.keyframes[0].s[0].i.length;
+    this.v = shapePool.newElement();
+    this.v.setPathData(this.keyframes[0].s[0].c, len);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.lastFrame = initFrame;
+    this.reset = resetShape;
+    this._caching = { lastFrame: initFrame, lastIndex: 0 };
+    this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
+  }
+  KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
+  KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
+  KeyframedShapeProperty.prototype.setVValue = setVValue;
+  KeyframedShapeProperty.prototype.addEffect = addEffect;
+
+  var EllShapeProperty = (function () {
+    var cPoint = roundCorner;
+
+    function EllShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 4);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.paths = this.localShapeCollection;
+      this.localShapeCollection.addShape(this.v);
+      this.d = data.d;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertEllToPath();
+      }
+    }
+
+    EllShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+
+        if (this._mdf) {
+          this.convertEllToPath();
+        }
+      },
+      convertEllToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var s0 = this.s.v[0] / 2;
+        var s1 = this.s.v[1] / 2;
+        var _cw = this.d !== 3;
+        var _v = this.v;
+        _v.v[0][0] = p0;
+        _v.v[0][1] = p1 - s1;
+        _v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.v[1][1] = p1;
+        _v.v[2][0] = p0;
+        _v.v[2][1] = p1 + s1;
+        _v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.v[3][1] = p1;
+        _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.i[0][1] = p1 - s1;
+        _v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.i[1][1] = p1 - s1 * cPoint;
+        _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.i[2][1] = p1 + s1;
+        _v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.i[3][1] = p1 + s1 * cPoint;
+        _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.o[0][1] = p1 - s1;
+        _v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.o[1][1] = p1 + s1 * cPoint;
+        _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.o[2][1] = p1 + s1;
+        _v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.o[3][1] = p1 - s1 * cPoint;
+      },
+    };
+
+    extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
+
+    return EllShapePropertyFactory;
+  }());
+
+  var StarShapeProperty = (function () {
+    function StarShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 0);
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.data = data;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      if (data.sy === 1) {
+        this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
+        this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
+        this.convertToPath = this.convertStarToPath;
+      } else {
+        this.convertToPath = this.convertPolygonToPath;
+      }
+      this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
+      this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this);
+      this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertToPath();
+      }
+    }
+
+    StarShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertToPath();
+        }
+      },
+      convertStarToPath: function () {
+        var numPts = Math.floor(this.pt.v) * 2;
+        var angle = (Math.PI * 2) / numPts;
+        /* this.v.v.length = numPts;
+                this.v.i.length = numPts;
+                this.v.o.length = numPts; */
+        var longFlag = true;
+        var longRad = this.or.v;
+        var shortRad = this.ir.v;
+        var longRound = this.os.v;
+        var shortRound = this.is.v;
+        var longPerimSegment = (2 * Math.PI * longRad) / (numPts * 2);
+        var shortPerimSegment = (2 * Math.PI * shortRad) / (numPts * 2);
+        var i;
+        var rad;
+        var roundness;
+        var perimSegment;
+        var currentAng = -Math.PI / 2;
+        currentAng += this.r.v;
+        var dir = this.data.d === 3 ? -1 : 1;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          rad = longFlag ? longRad : shortRad;
+          roundness = longFlag ? longRound : shortRound;
+          perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
+          /* this.v.v[i] = [x,y];
+                    this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
+                    this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
+                    this.v._length = numPts; */
+          longFlag = !longFlag;
+          currentAng += angle * dir;
+        }
+      },
+      convertPolygonToPath: function () {
+        var numPts = Math.floor(this.pt.v);
+        var angle = (Math.PI * 2) / numPts;
+        var rad = this.or.v;
+        var roundness = this.os.v;
+        var perimSegment = (2 * Math.PI * rad) / (numPts * 4);
+        var i;
+        var currentAng = -Math.PI * 0.5;
+        var dir = this.data.d === 3 ? -1 : 1;
+        currentAng += this.r.v;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+          currentAng += angle * dir;
+        }
+        this.paths.length = 0;
+        this.paths[0] = this.v;
+      },
+
+    };
+    extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
+
+    return StarShapePropertyFactory;
+  }());
+
+  var RectShapeProperty = (function () {
+    function RectShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.c = true;
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertRectToPath();
+      }
+    }
+
+    RectShapePropertyFactory.prototype = {
+      convertRectToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var v0 = this.s.v[0] / 2;
+        var v1 = this.s.v[1] / 2;
+        var round = bmMin(v0, v1, this.r.v);
+        var cPoint = round * (1 - roundCorner);
+        this.v._length = 0;
+
+        if (this.d === 2 || this.d === 1) {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
+          this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2);
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3);
+          }
+        } else {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true);
+          }
+        }
+      },
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertRectToPath();
+        }
+      },
+      reset: resetShape,
+    };
+    extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
+
+    return RectShapePropertyFactory;
+  }());
+
+  function getShapeProp(elem, data, type) {
+    var prop;
+    if (type === 3 || type === 4) {
+      var dataProp = type === 3 ? data.pt : data.ks;
+      var keys = dataProp.k;
+      if (keys.length) {
+        prop = new KeyframedShapeProperty(elem, data, type);
+      } else {
+        prop = new ShapeProperty(elem, data, type);
+      }
+    } else if (type === 5) {
+      prop = new RectShapeProperty(elem, data);
+    } else if (type === 6) {
+      prop = new EllShapeProperty(elem, data);
+    } else if (type === 7) {
+      prop = new StarShapeProperty(elem, data);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  }
+
+  function getConstructorFunction() {
+    return ShapeProperty;
+  }
+
+  function getKeyframedConstructorFunction() {
+    return KeyframedShapeProperty;
+  }
+
+  var ob = {};
+  ob.getShapeProp = getShapeProp;
+  ob.getConstructorFunction = getConstructorFunction;
+  ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction;
+  return ob;
+}());
+
+/*!
+ Transformation Matrix v2.0
+ (c) Epistemex 2014-2015
+ www.epistemex.com
+ By Ken Fyrstenberg
+ Contributions by leeoniya.
+ License: MIT, header required.
+ */
+
+/**
+ * 2D transformation matrix object initialized with identity matrix.
+ *
+ * The matrix can synchronize a canvas context by supplying the context
+ * as an argument, or later apply current absolute transform to an
+ * existing context.
+ *
+ * All values are handled as floating point values.
+ *
+ * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix
+ * @prop {number} a - scale x
+ * @prop {number} b - shear y
+ * @prop {number} c - shear x
+ * @prop {number} d - scale y
+ * @prop {number} e - translate x
+ * @prop {number} f - translate y
+ * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context
+ * @constructor
+ */
+
+const Matrix = (function () {
+  var _cos = Math.cos;
+  var _sin = Math.sin;
+  var _tan = Math.tan;
+  var _rnd = Math.round;
+
+  function reset() {
+    this.props[0] = 1;
+    this.props[1] = 0;
+    this.props[2] = 0;
+    this.props[3] = 0;
+    this.props[4] = 0;
+    this.props[5] = 1;
+    this.props[6] = 0;
+    this.props[7] = 0;
+    this.props[8] = 0;
+    this.props[9] = 0;
+    this.props[10] = 1;
+    this.props[11] = 0;
+    this.props[12] = 0;
+    this.props[13] = 0;
+    this.props[14] = 0;
+    this.props[15] = 1;
+    return this;
+  }
+
+  function rotate(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function rotateX(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateY(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateZ(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function shear(sx, sy) {
+    return this._t(1, sy, sx, 1, 0, 0);
+  }
+
+  function skew(ax, ay) {
+    return this.shear(_tan(ax), _tan(ay));
+  }
+
+  function skewFromAxis(ax, angle) {
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+    // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+  }
+
+  function scale(sx, sy, sz) {
+    if (!sz && sz !== 0) {
+      sz = 1;
+    }
+    if (sx === 1 && sy === 1 && sz === 1) {
+      return this;
+    }
+    return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
+  }
+
+  function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
+    this.props[0] = a;
+    this.props[1] = b;
+    this.props[2] = c;
+    this.props[3] = d;
+    this.props[4] = e;
+    this.props[5] = f;
+    this.props[6] = g;
+    this.props[7] = h;
+    this.props[8] = i;
+    this.props[9] = j;
+    this.props[10] = k;
+    this.props[11] = l;
+    this.props[12] = m;
+    this.props[13] = n;
+    this.props[14] = o;
+    this.props[15] = p;
+    return this;
+  }
+
+  function translate(tx, ty, tz) {
+    tz = tz || 0;
+    if (tx !== 0 || ty !== 0 || tz !== 0) {
+      return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
+    }
+    return this;
+  }
+
+  function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
+    var _p = this.props;
+
+    if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
+      // NOTE: commenting this condition because TurboFan deoptimizes code when present
+      // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
+      _p[12] = _p[12] * a2 + _p[15] * m2;
+      _p[13] = _p[13] * f2 + _p[15] * n2;
+      _p[14] = _p[14] * k2 + _p[15] * o2;
+      _p[15] *= p2;
+      // }
+      this._identityCalculated = false;
+      return this;
+    }
+
+    var a1 = _p[0];
+    var b1 = _p[1];
+    var c1 = _p[2];
+    var d1 = _p[3];
+    var e1 = _p[4];
+    var f1 = _p[5];
+    var g1 = _p[6];
+    var h1 = _p[7];
+    var i1 = _p[8];
+    var j1 = _p[9];
+    var k1 = _p[10];
+    var l1 = _p[11];
+    var m1 = _p[12];
+    var n1 = _p[13];
+    var o1 = _p[14];
+    var p1 = _p[15];
+
+    /* matrix order (canvas compatible):
+         * ace
+         * bdf
+         * 001
+         */
+    _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
+    _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
+    _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
+    _p[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2;
+
+    _p[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2;
+    _p[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2;
+    _p[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2;
+    _p[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2;
+
+    _p[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2;
+    _p[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2;
+    _p[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2;
+    _p[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2;
+
+    _p[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2;
+    _p[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2;
+    _p[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2;
+    _p[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2;
+
+    this._identityCalculated = false;
+    return this;
+  }
+
+  function multiply(matrix) {
+    var matrixProps = matrix.props;
+    return this.transform(
+      matrixProps[0],
+      matrixProps[1],
+      matrixProps[2],
+      matrixProps[3],
+      matrixProps[4],
+      matrixProps[5],
+      matrixProps[6],
+      matrixProps[7],
+      matrixProps[8],
+      matrixProps[9],
+      matrixProps[10],
+      matrixProps[11],
+      matrixProps[12],
+      matrixProps[13],
+      matrixProps[14],
+      matrixProps[15]
+    );
+  }
+
+  function isIdentity() {
+    if (!this._identityCalculated) {
+      this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
+      this._identityCalculated = true;
+    }
+    return this._identity;
+  }
+
+  function equals(matr) {
+    var i = 0;
+    while (i < 16) {
+      if (matr.props[i] !== this.props[i]) {
+        return false;
+      }
+      i += 1;
+    }
+    return true;
+  }
+
+  function clone(matr) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      matr.props[i] = this.props[i];
+    }
+    return matr;
+  }
+
+  function cloneFromProps(props) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      this.props[i] = props[i];
+    }
+  }
+
+  function applyToPoint(x, y, z) {
+    return {
+      x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+      y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+      z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+    };
+    /* return {
+         x: x * me.a + y * me.c + me.e,
+         y: x * me.b + y * me.d + me.f
+         }; */
+  }
+  function applyToX(x, y, z) {
+    return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
+  }
+  function applyToY(x, y, z) {
+    return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
+  }
+  function applyToZ(x, y, z) {
+    return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
+  }
+
+  function getInverseMatrix() {
+    var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
+    var a = this.props[5] / determinant;
+    var b = -this.props[1] / determinant;
+    var c = -this.props[4] / determinant;
+    var d = this.props[0] / determinant;
+    var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12]) / determinant;
+    var f = -(this.props[0] * this.props[13] - this.props[1] * this.props[12]) / determinant;
+    var inverseMatrix = new Matrix();
+    inverseMatrix.props[0] = a;
+    inverseMatrix.props[1] = b;
+    inverseMatrix.props[4] = c;
+    inverseMatrix.props[5] = d;
+    inverseMatrix.props[12] = e;
+    inverseMatrix.props[13] = f;
+    return inverseMatrix;
+  }
+
+  function inversePoint(pt) {
+    var inverseMatrix = this.getInverseMatrix();
+    return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
+  }
+
+  function inversePoints(pts) {
+    var i;
+    var len = pts.length;
+    var retPts = [];
+    for (i = 0; i < len; i += 1) {
+      retPts[i] = inversePoint(pts[i]);
+    }
+    return retPts;
+  }
+
+  function applyToTriplePoints(pt1, pt2, pt3) {
+    var arr = createTypedArray('float32', 6);
+    if (this.isIdentity()) {
+      arr[0] = pt1[0];
+      arr[1] = pt1[1];
+      arr[2] = pt2[0];
+      arr[3] = pt2[1];
+      arr[4] = pt3[0];
+      arr[5] = pt3[1];
+    } else {
+      var p0 = this.props[0];
+      var p1 = this.props[1];
+      var p4 = this.props[4];
+      var p5 = this.props[5];
+      var p12 = this.props[12];
+      var p13 = this.props[13];
+      arr[0] = pt1[0] * p0 + pt1[1] * p4 + p12;
+      arr[1] = pt1[0] * p1 + pt1[1] * p5 + p13;
+      arr[2] = pt2[0] * p0 + pt2[1] * p4 + p12;
+      arr[3] = pt2[0] * p1 + pt2[1] * p5 + p13;
+      arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
+      arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
+    }
+    return arr;
+  }
+
+  function applyToPointArray(x, y, z) {
+    var arr;
+    if (this.isIdentity()) {
+      arr = [x, y, z];
+    } else {
+      arr = [
+        x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+        x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+        x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+      ];
+    }
+    return arr;
+  }
+
+  function applyToPointStringified(x, y) {
+    if (this.isIdentity()) {
+      return x + ',' + y;
+    }
+    var _p = this.props;
+    return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
+  }
+
+  function toCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var i = 0;
+    var props = this.props;
+    var cssValue = 'matrix3d(';
+    var v = 10000;
+    while (i < 16) {
+      cssValue += _rnd(props[i] * v) / v;
+      cssValue += i === 15 ? ')' : ',';
+      i += 1;
+    }
+    return cssValue;
+  }
+
+  function roundMatrixProperty(val) {
+    var v = 10000;
+    if ((val < 0.000001 && val > 0) || (val > -0.000001 && val < 0)) {
+      return _rnd(val * v) / v;
+    }
+    return val;
+  }
+
+  function to2dCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var props = this.props;
+    var _a = roundMatrixProperty(props[0]);
+    var _b = roundMatrixProperty(props[1]);
+    var _c = roundMatrixProperty(props[4]);
+    var _d = roundMatrixProperty(props[5]);
+    var _e = roundMatrixProperty(props[12]);
+    var _f = roundMatrixProperty(props[13]);
+    return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
+  }
+
+  return function () {
+    this.reset = reset;
+    this.rotate = rotate;
+    this.rotateX = rotateX;
+    this.rotateY = rotateY;
+    this.rotateZ = rotateZ;
+    this.skew = skew;
+    this.skewFromAxis = skewFromAxis;
+    this.shear = shear;
+    this.scale = scale;
+    this.setTransform = setTransform;
+    this.translate = translate;
+    this.transform = transform;
+    this.multiply = multiply;
+    this.applyToPoint = applyToPoint;
+    this.applyToX = applyToX;
+    this.applyToY = applyToY;
+    this.applyToZ = applyToZ;
+    this.applyToPointArray = applyToPointArray;
+    this.applyToTriplePoints = applyToTriplePoints;
+    this.applyToPointStringified = applyToPointStringified;
+    this.toCSS = toCSS;
+    this.to2dCSS = to2dCSS;
+    this.clone = clone;
+    this.cloneFromProps = cloneFromProps;
+    this.equals = equals;
+    this.inversePoints = inversePoints;
+    this.inversePoint = inversePoint;
+    this.getInverseMatrix = getInverseMatrix;
+    this._t = this.transform;
+    this.isIdentity = isIdentity;
+    this._identity = true;
+    this._identityCalculated = false;
+
+    this.props = createTypedArray('float32', 16);
+    this.reset();
+  };
+}());
+
+const lottie = {};
+var standalone = '__[STANDALONE]__';
+var animationData = '__[ANIMATIONDATA]__';
+var renderer = '';
+
+function setLocation(href) {
+  setLocationHref(href);
+}
+
+function searchAnimations() {
+  if (standalone === true) {
+    animationManager.searchAnimations(animationData, standalone, renderer);
+  } else {
+    animationManager.searchAnimations();
+  }
+}
+
+function setSubframeRendering(flag) {
+  setSubframeEnabled(flag);
+}
+
+function setPrefix(prefix) {
+  setIdPrefix(prefix);
+}
+
+function loadAnimation(params) {
+  if (standalone === true) {
+    params.animationData = JSON.parse(animationData);
+  }
+  return animationManager.loadAnimation(params);
+}
+
+function setQuality(value) {
+  if (typeof value === 'string') {
+    switch (value) {
+      case 'high':
+        setDefaultCurveSegments(200);
+        break;
+      default:
+      case 'medium':
+        setDefaultCurveSegments(50);
+        break;
+      case 'low':
+        setDefaultCurveSegments(10);
+        break;
+    }
+  } else if (!isNaN(value) && value > 1) {
+    setDefaultCurveSegments(value);
+  }
+  if (getDefaultCurveSegments() >= 50) {
+    roundValues(false);
+  } else {
+    roundValues(true);
+  }
+}
+
+function inBrowser() {
+  return typeof navigator !== 'undefined';
+}
+
+function installPlugin(type, plugin) {
+  if (type === 'expressions') {
+    setExpressionsPlugin(plugin);
+  }
+}
+
+function getFactory(name) {
+  switch (name) {
+    case 'propertyFactory':
+      return PropertyFactory;
+    case 'shapePropertyFactory':
+      return ShapePropertyFactory;
+    case 'matrix':
+      return Matrix;
+    default:
+      return null;
+  }
+}
+
+lottie.play = animationManager.play;
+lottie.pause = animationManager.pause;
+lottie.setLocationHref = setLocation;
+lottie.togglePause = animationManager.togglePause;
+lottie.setSpeed = animationManager.setSpeed;
+lottie.setDirection = animationManager.setDirection;
+lottie.stop = animationManager.stop;
+lottie.searchAnimations = searchAnimations;
+lottie.registerAnimation = animationManager.registerAnimation;
+lottie.loadAnimation = loadAnimation;
+lottie.setSubframeRendering = setSubframeRendering;
+lottie.resize = animationManager.resize;
+// lottie.start = start;
+lottie.goToAndStop = animationManager.goToAndStop;
+lottie.destroy = animationManager.destroy;
+lottie.setQuality = setQuality;
+lottie.inBrowser = inBrowser;
+lottie.installPlugin = installPlugin;
+lottie.freeze = animationManager.freeze;
+lottie.unfreeze = animationManager.unfreeze;
+lottie.setVolume = animationManager.setVolume;
+lottie.mute = animationManager.mute;
+lottie.unmute = animationManager.unmute;
+lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations;
+lottie.useWebWorker = setWebWorker;
+lottie.setIDPrefix = setPrefix;
+lottie.__getFactory = getFactory;
+lottie.version = '[[BM_VERSION]]';
+
+function checkReady() {
+  if (document.readyState === 'complete') {
+    clearInterval(readyStateCheckInterval);
+    searchAnimations();
+  }
+}
+
+function getQueryVariable(variable) {
+  var vars = queryString.split('&');
+  for (var i = 0; i < vars.length; i += 1) {
+    var pair = vars[i].split('=');
+    if (decodeURIComponent(pair[0]) == variable) { // eslint-disable-line eqeqeq
+      return decodeURIComponent(pair[1]);
+    }
+  }
+  return null;
+}
+var queryString = '';
+if (standalone) {
+  var scripts = document.getElementsByTagName('script');
+  var index = scripts.length - 1;
+  var myScript = scripts[index] || {
+    src: '',
+  };
+  queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
+  renderer = getQueryVariable('renderer');
+}
+var readyStateCheckInterval = setInterval(checkReady, 100);
+
+// this adds bodymovin to the window object for backwards compatibility
+try {
+  if (!(typeof exports === 'object' && typeof module !== 'undefined')
+    && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
+  ) {
+    window.bodymovin = lottie;
+  }
+} catch (err) {
+  //
+}
+
+const ShapeModifiers = (function () {
+  var ob = {};
+  var modifiers = {};
+  ob.registerModifier = registerModifier;
+  ob.getModifier = getModifier;
+
+  function registerModifier(nm, factory) {
+    if (!modifiers[nm]) {
+      modifiers[nm] = factory;
+    }
+  }
+
+  function getModifier(nm, elem, data) {
+    return new modifiers[nm](elem, data);
+  }
+
+  return ob;
+}());
+
+function ShapeModifier() {}
+ShapeModifier.prototype.initModifierProperties = function () {};
+ShapeModifier.prototype.addShapeToModifier = function () {};
+ShapeModifier.prototype.addShape = function (data) {
+  if (!this.closed) {
+    // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
+    data.sh.container.addDynamicProperty(data.sh);
+    var shapeData = { shape: data.sh, data: data, localShapeCollection: shapeCollectionPool.newShapeCollection() };
+    this.shapes.push(shapeData);
+    this.addShapeToModifier(shapeData);
+    if (this._isAnimated) {
+      data.setAsAnimated();
+    }
+  }
+};
+ShapeModifier.prototype.init = function (elem, data) {
+  this.shapes = [];
+  this.elem = elem;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, data);
+  this.frameId = initialDefaultFrame;
+  this.closed = false;
+  this.k = false;
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+ShapeModifier.prototype.processKeys = function () {
+  if (this.elem.globalData.frameId === this.frameId) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+extendPrototype([DynamicPropertyContainer], ShapeModifier);
+
+function TrimModifier() {
+}
+extendPrototype([ShapeModifier], TrimModifier);
+TrimModifier.prototype.initModifierProperties = function (elem, data) {
+  this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this);
+  this.sValue = 0;
+  this.eValue = 0;
+  this.getValue = this.processKeys;
+  this.m = data.m;
+  this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
+};
+
+TrimModifier.prototype.addShapeToModifier = function (shapeData) {
+  shapeData.pathsData = [];
+};
+
+TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
+  var segments = [];
+  if (e <= 1) {
+    segments.push({
+      s: s,
+      e: e,
+    });
+  } else if (s >= 1) {
+    segments.push({
+      s: s - 1,
+      e: e - 1,
+    });
+  } else {
+    segments.push({
+      s: s,
+      e: 1,
+    });
+    segments.push({
+      s: 0,
+      e: e - 1,
+    });
+  }
+  var shapeSegments = [];
+  var i;
+  var len = segments.length;
+  var segmentOb;
+  for (i = 0; i < len; i += 1) {
+    segmentOb = segments[i];
+    if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
+      var shapeS;
+      var shapeE;
+      if (segmentOb.s * totalModifierLength <= addedLength) {
+        shapeS = 0;
+      } else {
+        shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
+      }
+      if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
+        shapeE = 1;
+      } else {
+        shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength);
+      }
+      shapeSegments.push([shapeS, shapeE]);
+    }
+  }
+  if (!shapeSegments.length) {
+    shapeSegments.push([0, 0]);
+  }
+  return shapeSegments;
+};
+
+TrimModifier.prototype.releasePathsData = function (pathsData) {
+  var i;
+  var len = pathsData.length;
+  for (i = 0; i < len; i += 1) {
+    segmentsLengthPool.release(pathsData[i]);
+  }
+  pathsData.length = 0;
+  return pathsData;
+};
+
+TrimModifier.prototype.processShapes = function (_isFirstFrame) {
+  var s;
+  var e;
+  if (this._mdf || _isFirstFrame) {
+    var o = (this.o.v % 360) / 360;
+    if (o < 0) {
+      o += 1;
+    }
+    if (this.s.v > 1) {
+      s = 1 + o;
+    } else if (this.s.v < 0) {
+      s = 0 + o;
+    } else {
+      s = this.s.v + o;
+    }
+    if (this.e.v > 1) {
+      e = 1 + o;
+    } else if (this.e.v < 0) {
+      e = 0 + o;
+    } else {
+      e = this.e.v + o;
+    }
+
+    if (s > e) {
+      var _s = s;
+      s = e;
+      e = _s;
+    }
+    s = Math.round(s * 10000) * 0.0001;
+    e = Math.round(e * 10000) * 0.0001;
+    this.sValue = s;
+    this.eValue = e;
+  } else {
+    s = this.sValue;
+    e = this.eValue;
+  }
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var pathsData;
+  var pathData;
+  var totalShapeLength;
+  var totalModifierLength = 0;
+
+  if (e === s) {
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].localShapeCollection.releaseShapes();
+      this.shapes[i].shape._mdf = true;
+      this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
+      if (this._mdf) {
+        this.shapes[i].pathsData.length = 0;
+      }
+    }
+  } else if (!((e === 1 && s === 0) || (e === 0 && s === 1))) {
+    var segments = [];
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
+      if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
+        shapeData.shape.paths = shapeData.localShapeCollection;
+      } else {
+        shapePaths = shapeData.shape.paths;
+        jLen = shapePaths._length;
+        totalShapeLength = 0;
+        if (!shapeData.shape._mdf && shapeData.pathsData.length) {
+          totalShapeLength = shapeData.totalShapeLength;
+        } else {
+          pathsData = this.releasePathsData(shapeData.pathsData);
+          for (j = 0; j < jLen; j += 1) {
+            pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
+            pathsData.push(pathData);
+            totalShapeLength += pathData.totalLength;
+          }
+          shapeData.totalShapeLength = totalShapeLength;
+          shapeData.pathsData = pathsData;
+        }
+
+        totalModifierLength += totalShapeLength;
+        shapeData.shape._mdf = true;
+      }
+    }
+    var shapeS = s;
+    var shapeE = e;
+    var addedLength = 0;
+    var edges;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shapeData = this.shapes[i];
+      if (shapeData.shape._mdf) {
+        localShapeCollection = shapeData.localShapeCollection;
+        localShapeCollection.releaseShapes();
+        // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
+        if (this.m === 2 && len > 1) {
+          edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
+          addedLength += shapeData.totalShapeLength;
+        } else {
+          edges = [[shapeS, shapeE]];
+        }
+        jLen = edges.length;
+        for (j = 0; j < jLen; j += 1) {
+          shapeS = edges[j][0];
+          shapeE = edges[j][1];
+          segments.length = 0;
+          if (shapeE <= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength * shapeE,
+            });
+          } else if (shapeS >= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * (shapeS - 1),
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          } else {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength,
+            });
+            segments.push({
+              s: 0,
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          }
+          var newShapesData = this.addShapes(shapeData, segments[0]);
+          if (segments[0].s !== segments[0].e) {
+            if (segments.length > 1) {
+              var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
+              if (lastShapeInCollection.c) {
+                var lastShape = newShapesData.pop();
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1], lastShape);
+              } else {
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1]);
+              }
+            }
+            this.addPaths(newShapesData, localShapeCollection);
+          }
+        }
+        shapeData.shape.paths = localShapeCollection;
+      }
+    }
+  } else if (this._mdf) {
+    for (i = 0; i < len; i += 1) {
+      // Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween.
+      // Don't remove this even if it's losing cached info.
+      this.shapes[i].pathsData.length = 0;
+      this.shapes[i].shape._mdf = true;
+    }
+  }
+};
+
+TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
+  var i;
+  var len = newPaths.length;
+  for (i = 0; i < len; i += 1) {
+    localShapeCollection.addShape(newPaths[i]);
+  }
+};
+
+TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
+  shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
+  shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
+  }
+  shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
+  shapePath.setXYAt(points[1], points[5], 'o', pos);
+  shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(points[0], points[4], 'v', pos);
+  }
+  shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
+  var pathsData = shapeData.pathsData;
+  var shapePaths = shapeData.shape.paths.shapes;
+  var i;
+  var len = shapeData.shape.paths._length;
+  var j;
+  var jLen;
+  var addedLength = 0;
+  var currentLengthData;
+  var segmentCount;
+  var lengths;
+  var segment;
+  var shapes = [];
+  var initPos;
+  var newShape = true;
+  if (!shapePath) {
+    shapePath = shapePool.newElement();
+    segmentCount = 0;
+    initPos = 0;
+  } else {
+    segmentCount = shapePath._length;
+    initPos = shapePath._length;
+  }
+  shapes.push(shapePath);
+  for (i = 0; i < len; i += 1) {
+    lengths = pathsData[i].lengths;
+    shapePath.c = shapePaths[i].c;
+    jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
+    for (j = 1; j < jLen; j += 1) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
+        addedLength += currentLengthData.addedLength;
+        shapePath.c = false;
+      } else if (addedLength > shapeSegment.e) {
+        shapePath.c = false;
+        break;
+      } else {
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+        addedLength += currentLengthData.addedLength;
+        segmentCount += 1;
+      }
+    }
+    if (shapePaths[i].c && lengths.length) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength <= shapeSegment.e) {
+        var segmentLength = lengths[j - 1].addedLength;
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+      } else {
+        shapePath.c = false;
+      }
+      addedLength += currentLengthData.addedLength;
+      segmentCount += 1;
+    }
+    if (shapePath._length) {
+      shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
+      shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
+    }
+    if (addedLength > shapeSegment.e) {
+      break;
+    }
+    if (i < len - 1) {
+      shapePath = shapePool.newElement();
+      newShape = true;
+      shapes.push(shapePath);
+      segmentCount = 0;
+    }
+  }
+  return shapes;
+};
+
+function PuckerAndBloatModifier() {}
+extendPrototype([ShapeModifier], PuckerAndBloatModifier);
+PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this._isAnimated = !!this.amount.effectsSequence.length;
+};
+
+PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
+  var percent = amount / 100;
+  var centerPoint = [0, 0];
+  var pathLength = path._length;
+  var i = 0;
+  for (i = 0; i < pathLength; i += 1) {
+    centerPoint[0] += path.v[i][0];
+    centerPoint[1] += path.v[i][1];
+  }
+  centerPoint[0] /= pathLength;
+  centerPoint[1] /= pathLength;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < pathLength; i += 1) {
+    vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
+    vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
+    oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent;
+    oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent;
+    iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent;
+    iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
+    clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
+  }
+  return clonedPath;
+};
+
+PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+const TransformPropertyFactory = (function () {
+  var defaultVector = [0, 0];
+
+  function applyToMatrix(mat) {
+    var _mdf = this._mdf;
+    this.iterateDynamicProperties();
+    this._mdf = this._mdf || _mdf;
+    if (this.a) {
+      mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+    }
+    if (this.s) {
+      mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+    }
+    if (this.sk) {
+      mat.skewFromAxis(-this.sk.v, this.sa.v);
+    }
+    if (this.r) {
+      mat.rotate(-this.r.v);
+    } else {
+      mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+    }
+    if (this.data.p.s) {
+      if (this.data.p.z) {
+        mat.translate(this.px.v, this.py.v, -this.pz.v);
+      } else {
+        mat.translate(this.px.v, this.py.v, 0);
+      }
+    } else {
+      mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+    }
+  }
+  function processKeys(forceRender) {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    }
+    if (this._isDirty) {
+      this.precalculateMatrix();
+      this._isDirty = false;
+    }
+
+    this.iterateDynamicProperties();
+
+    if (this._mdf || forceRender) {
+      var frameRate;
+      this.v.cloneFromProps(this.pre.props);
+      if (this.appliedTransformations < 1) {
+        this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      }
+      if (this.appliedTransformations < 2) {
+        this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      }
+      if (this.sk && this.appliedTransformations < 3) {
+        this.v.skewFromAxis(-this.sk.v, this.sa.v);
+      }
+      if (this.r && this.appliedTransformations < 4) {
+        this.v.rotate(-this.r.v);
+      } else if (!this.r && this.appliedTransformations < 4) {
+        this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+          .rotateY(this.or.v[1])
+          .rotateX(this.or.v[0]);
+      }
+      if (this.autoOriented) {
+        var v1;
+        var v2;
+        frameRate = this.elem.globalData.frameRate;
+        if (this.p && this.p.keyframes && this.p.getValueAtTime) {
+          if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
+            v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0);
+          } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0);
+            v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0);
+          } else {
+            v1 = this.p.pv;
+            v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime);
+          }
+        } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) {
+          v1 = [];
+          v2 = [];
+          var px = this.px;
+          var py = this.py;
+          if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
+            v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
+            v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate, 0);
+          } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate), 0);
+            v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate), 0);
+            v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0);
+          } else {
+            v1 = [px.pv, py.pv];
+            v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime);
+            v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime);
+          }
+        } else {
+          v2 = defaultVector;
+          v1 = v2;
+        }
+        this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
+      }
+      if (this.data.p && this.data.p.s) {
+        if (this.data.p.z) {
+          this.v.translate(this.px.v, this.py.v, -this.pz.v);
+        } else {
+          this.v.translate(this.px.v, this.py.v, 0);
+        }
+      } else {
+        this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+      }
+    }
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function precalculateMatrix() {
+    this.appliedTransformations = 0;
+    this.pre.reset();
+
+    if (!this.a.effectsSequence.length) {
+      this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      this.appliedTransformations = 1;
+    } else {
+      return;
+    }
+    if (!this.s.effectsSequence.length) {
+      this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      this.appliedTransformations = 2;
+    } else {
+      return;
+    }
+    if (this.sk) {
+      if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
+        this.pre.skewFromAxis(-this.sk.v, this.sa.v);
+        this.appliedTransformations = 3;
+      } else {
+        return;
+      }
+    }
+    if (this.r) {
+      if (!this.r.effectsSequence.length) {
+        this.pre.rotate(-this.r.v);
+        this.appliedTransformations = 4;
+      }
+    } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) {
+      this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+      this.appliedTransformations = 4;
+    }
+  }
+
+  function autoOrient() {
+    //
+    // var prevP = this.getValueAtTime();
+  }
+
+  function addDynamicProperty(prop) {
+    this._addDynamicProperty(prop);
+    this.elem.addDynamicProperty(prop);
+    this._isDirty = true;
+  }
+
+  function TransformProperty(elem, data, container) {
+    this.elem = elem;
+    this.frameId = -1;
+    this.propType = 'transform';
+    this.data = data;
+    this.v = new Matrix();
+    // Precalculated matrix with non animated properties
+    this.pre = new Matrix();
+    this.appliedTransformations = 0;
+    this.initDynamicPropertyContainer(container || elem);
+    if (data.p && data.p.s) {
+      this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
+      this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
+      if (data.p.z) {
+        this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
+      }
+    } else {
+      this.p = PropertyFactory.getProp(elem, data.p || { k: [0, 0, 0] }, 1, 0, this);
+    }
+    if (data.rx) {
+      this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
+      this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
+      this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
+      if (data.or.k[0].ti) {
+        var i;
+        var len = data.or.k.length;
+        for (i = 0; i < len; i += 1) {
+          data.or.k[i].to = null;
+          data.or.k[i].ti = null;
+        }
+      }
+      this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+      // sh Indicates it needs to be capped between -180 and 180
+      this.or.sh = true;
+    } else {
+      this.r = PropertyFactory.getProp(elem, data.r || { k: 0 }, 0, degToRads, this);
+    }
+    if (data.sk) {
+      this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
+      this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
+    }
+    this.a = PropertyFactory.getProp(elem, data.a || { k: [0, 0, 0] }, 1, 0, this);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: [100, 100, 100] }, 1, 0.01, this);
+    // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
+    if (data.o) {
+      this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
+    } else {
+      this.o = { _mdf: false, v: 1 };
+    }
+    this._isDirty = true;
+    if (!this.dynamicProperties.length) {
+      this.getValue(true);
+    }
+  }
+
+  TransformProperty.prototype = {
+    applyToMatrix: applyToMatrix,
+    getValue: processKeys,
+    precalculateMatrix: precalculateMatrix,
+    autoOrient: autoOrient,
+  };
+
+  extendPrototype([DynamicPropertyContainer], TransformProperty);
+  TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
+  TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
+
+  function getTransformProperty(elem, data, container) {
+    return new TransformProperty(elem, data, container);
+  }
+
+  return {
+    getTransformProperty: getTransformProperty,
+  };
+}());
+
+function RepeaterModifier() {}
+extendPrototype([ShapeModifier], RepeaterModifier);
+
+RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, null, this);
+  this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this);
+  this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
+  this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
+  this.data = data;
+  if (!this.dynamicProperties.length) {
+    this.getValue(true);
+  }
+  this._isAnimated = !!this.dynamicProperties.length;
+  this.pMatrix = new Matrix();
+  this.rMatrix = new Matrix();
+  this.sMatrix = new Matrix();
+  this.tMatrix = new Matrix();
+  this.matrix = new Matrix();
+};
+
+RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
+  var dir = inv ? -1 : 1;
+  var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
+  var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
+  pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
+  rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  rMatrix.rotate(-transform.r.v * dir * perc);
+  rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+  sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
+  sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+};
+
+RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
+  this.elem = elem;
+  this.arr = arr;
+  this.pos = pos;
+  this.elemsData = elemsData;
+  this._currentCopies = 0;
+  this._elements = [];
+  this._groups = [];
+  this.frameId = -1;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, arr[pos]);
+  while (pos > 0) {
+    pos -= 1;
+    // this._elements.unshift(arr.splice(pos,1)[0]);
+    this._elements.unshift(arr[pos]);
+  }
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+
+RepeaterModifier.prototype.resetElements = function (elements) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._processed = false;
+    if (elements[i].ty === 'gr') {
+      this.resetElements(elements[i].it);
+    }
+  }
+};
+
+RepeaterModifier.prototype.cloneElements = function (elements) {
+  var newElements = JSON.parse(JSON.stringify(elements));
+  this.resetElements(newElements);
+  return newElements;
+};
+
+RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._render = renderFlag;
+    if (elements[i].ty === 'gr') {
+      this.changeGroupRender(elements[i].it, renderFlag);
+    }
+  }
+};
+
+RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
+  var items;
+  var itemsTransform;
+  var i;
+  var dir;
+  var cont;
+  var hasReloaded = false;
+  if (this._mdf || _isFirstFrame) {
+    var copies = Math.ceil(this.c.v);
+    if (this._groups.length < copies) {
+      while (this._groups.length < copies) {
+        var group = {
+          it: this.cloneElements(this._elements),
+          ty: 'gr',
+        };
+        group.it.push({
+          a: { a: 0, ix: 1, k: [0, 0] }, nm: 'Transform', o: { a: 0, ix: 7, k: 100 }, p: { a: 0, ix: 2, k: [0, 0] }, r: { a: 1, ix: 6, k: [{ s: 0, e: 0, t: 0 }, { s: 0, e: 0, t: 1 }] }, s: { a: 0, ix: 3, k: [100, 100] }, sa: { a: 0, ix: 5, k: 0 }, sk: { a: 0, ix: 4, k: 0 }, ty: 'tr',
+        });
+
+        this.arr.splice(0, 0, group);
+        this._groups.splice(0, 0, group);
+        this._currentCopies += 1;
+      }
+      this.elem.reloadShapes();
+      hasReloaded = true;
+    }
+    cont = 0;
+    var renderFlag;
+    for (i = 0; i <= this._groups.length - 1; i += 1) {
+      renderFlag = cont < copies;
+      this._groups[i]._render = renderFlag;
+      this.changeGroupRender(this._groups[i].it, renderFlag);
+      if (!renderFlag) {
+        var elems = this.elemsData[i].it;
+        var transformData = elems[elems.length - 1];
+        if (transformData.transform.op.v !== 0) {
+          transformData.transform.op._mdf = true;
+          transformData.transform.op.v = 0;
+        } else {
+          transformData.transform.op._mdf = false;
+        }
+      }
+      cont += 1;
+    }
+
+    this._currentCopies = copies;
+    /// /
+
+    var offset = this.o.v;
+    var offsetModulo = offset % 1;
+    var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
+    var pProps = this.pMatrix.props;
+    var rProps = this.rMatrix.props;
+    var sProps = this.sMatrix.props;
+    this.pMatrix.reset();
+    this.rMatrix.reset();
+    this.sMatrix.reset();
+    this.tMatrix.reset();
+    this.matrix.reset();
+    var iteration = 0;
+
+    if (offset > 0) {
+      while (iteration < roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        iteration += 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
+        iteration += offsetModulo;
+      }
+    } else if (offset < 0) {
+      while (iteration > roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
+        iteration -= 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
+        iteration -= offsetModulo;
+      }
+    }
+    i = this.data.m === 1 ? 0 : this._currentCopies - 1;
+    dir = this.data.m === 1 ? 1 : -1;
+    cont = this._currentCopies;
+    var j;
+    var jLen;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      jLen = itemsTransform.length;
+      items[items.length - 1].transform.mProps._mdf = true;
+      items[items.length - 1].transform.op._mdf = true;
+      items[items.length - 1].transform.op.v = this._currentCopies === 1
+        ? this.so.v
+        : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
+
+      if (iteration !== 0) {
+        if ((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)) {
+          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        }
+        this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
+        this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
+        this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
+
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+        this.matrix.reset();
+      } else {
+        this.matrix.reset();
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+      }
+      iteration += 1;
+      cont -= 1;
+      i += dir;
+    }
+  } else {
+    cont = this._currentCopies;
+    i = 0;
+    dir = 1;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      items[items.length - 1].transform.mProps._mdf = false;
+      items[items.length - 1].transform.op._mdf = false;
+      cont -= 1;
+      i += dir;
+    }
+  }
+  return hasReloaded;
+};
+
+RepeaterModifier.prototype.addShape = function () {};
+
+function RoundCornersModifier() {}
+extendPrototype([ShapeModifier], RoundCornersModifier);
+RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this._isAnimated = !!this.rd.effectsSequence.length;
+};
+
+RoundCornersModifier.prototype.processPath = function (path, round) {
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var i;
+  var len = path._length;
+  var currentV;
+  var currentI;
+  var currentO;
+  var closerV;
+  var distance;
+  var newPosPerc;
+  var index = 0;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < len; i += 1) {
+    currentV = path.v[i];
+    currentO = path.o[i];
+    currentI = path.i[i];
+    if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
+      if ((i === 0 || i === len - 1) && !path.c) {
+        clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
+        /* clonedPath.v[index] = currentV;
+                clonedPath.o[index] = currentO;
+                clonedPath.i[index] = currentI; */
+        index += 1;
+      } else {
+        if (i === 0) {
+          closerV = path.v[len - 1];
+        } else {
+          closerV = path.v[i - 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = iX;
+        iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
+        vY = iY;
+        oX = vX - (vX - currentV[0]) * roundCorner;
+        oY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+
+        if (i === len - 1) {
+          closerV = path.v[0];
+        } else {
+          closerV = path.v[i + 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = oX;
+        oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc;
+        vY = oY;
+        iX = vX - (vX - currentV[0]) * roundCorner;
+        iY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+      }
+    } else {
+      clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index);
+      index += 1;
+    }
+  }
+  return clonedPath;
+};
+
+RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var rd = this.rd.v;
+
+  if (rd !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function floatEqual(a, b) {
+  return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
+}
+
+function floatZero(f) {
+  return Math.abs(f) <= 0.00001;
+}
+
+function lerp(p0, p1, amount) {
+  return p0 * (1 - amount) + p1 * amount;
+}
+
+function lerpPoint(p0, p1, amount) {
+  return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
+}
+
+function quadRoots(a, b, c) {
+  // no root
+  if (a === 0) return [];
+  var s = b * b - 4 * a * c;
+  // Complex roots
+  if (s < 0) return [];
+  var singleRoot = -b / (2 * a);
+  // 1 root
+  if (s === 0) return [singleRoot];
+  var delta = Math.sqrt(s) / (2 * a);
+  // 2 roots
+  return [singleRoot - delta, singleRoot + delta];
+}
+
+function polynomialCoefficients(p0, p1, p2, p3) {
+  return [
+    -p0 + 3 * p1 - 3 * p2 + p3,
+    3 * p0 - 6 * p1 + 3 * p2,
+    -3 * p0 + 3 * p1,
+    p0,
+  ];
+}
+
+function singlePoint(p) {
+  return new PolynomialBezier(p, p, p, p, false);
+}
+
+function PolynomialBezier(p0, p1, p2, p3, linearize) {
+  if (linearize && pointEqual(p0, p1)) {
+    p1 = lerpPoint(p0, p3, 1 / 3);
+  }
+  if (linearize && pointEqual(p2, p3)) {
+    p2 = lerpPoint(p0, p3, 2 / 3);
+  }
+  var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
+  var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
+  this.a = [coeffx[0], coeffy[0]];
+  this.b = [coeffx[1], coeffy[1]];
+  this.c = [coeffx[2], coeffy[2]];
+  this.d = [coeffx[3], coeffy[3]];
+  this.points = [p0, p1, p2, p3];
+}
+PolynomialBezier.prototype.point = function (t) {
+  return [
+    (((this.a[0] * t) + this.b[0]) * t + this.c[0]) * t + this.d[0],
+    (((this.a[1] * t) + this.b[1]) * t + this.c[1]) * t + this.d[1],
+  ];
+};
+PolynomialBezier.prototype.derivative = function (t) {
+  return [
+    (3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0],
+    (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1],
+  ];
+};
+PolynomialBezier.prototype.tangentAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[1], p[0]);
+};
+PolynomialBezier.prototype.normalAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[0], p[1]);
+};
+
+PolynomialBezier.prototype.inflectionPoints = function () {
+  var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
+  if (floatZero(denom)) return [];
+  var tcusp = (-0.5 * (this.a[1] * this.c[0] - this.a[0] * this.c[1])) / denom;
+  var square = tcusp * tcusp - ((1 / 3) * (this.b[1] * this.c[0] - this.b[0] * this.c[1])) / denom;
+  if (square < 0) return [];
+  var root = Math.sqrt(square);
+  if (floatZero(root)) {
+    if (root > 0 && root < 1) return [tcusp];
+    return [];
+  }
+  return [tcusp - root, tcusp + root].filter(function (r) { return r > 0 && r < 1; });
+};
+PolynomialBezier.prototype.split = function (t) {
+  if (t <= 0) return [singlePoint(this.points[0]), this];
+  if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
+  var p10 = lerpPoint(this.points[0], this.points[1], t);
+  var p11 = lerpPoint(this.points[1], this.points[2], t);
+  var p12 = lerpPoint(this.points[2], this.points[3], t);
+  var p20 = lerpPoint(p10, p11, t);
+  var p21 = lerpPoint(p11, p12, t);
+  var p3 = lerpPoint(p20, p21, t);
+  return [
+    new PolynomialBezier(this.points[0], p10, p20, p3, true),
+    new PolynomialBezier(p3, p21, p12, this.points[3], true),
+  ];
+};
+function extrema(bez, comp) {
+  var min = bez.points[0][comp];
+  var max = bez.points[bez.points.length - 1][comp];
+  if (min > max) {
+    var e = max;
+    max = min;
+    min = e;
+  }
+  // Derivative roots to find min/max
+  var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
+  for (var i = 0; i < f.length; i += 1) {
+    if (f[i] > 0 && f[i] < 1) {
+      var val = bez.point(f[i])[comp];
+      if (val < min) min = val;
+      else if (val > max) max = val;
+    }
+  }
+  return {
+    min: min,
+    max: max,
+  };
+}
+PolynomialBezier.prototype.bounds = function () {
+  return {
+    x: extrema(this, 0),
+    y: extrema(this, 1),
+  };
+};
+PolynomialBezier.prototype.boundingBox = function () {
+  var bounds = this.bounds();
+  return {
+    left: bounds.x.min,
+    right: bounds.x.max,
+    top: bounds.y.min,
+    bottom: bounds.y.max,
+    width: bounds.x.max - bounds.x.min,
+    height: bounds.y.max - bounds.y.min,
+    cx: (bounds.x.max + bounds.x.min) / 2,
+    cy: (bounds.y.max + bounds.y.min) / 2,
+  };
+};
+
+function intersectData(bez, t1, t2) {
+  var box = bez.boundingBox();
+  return {
+    cx: box.cx,
+    cy: box.cy,
+    width: box.width,
+    height: box.height,
+    bez: bez,
+    t: (t1 + t2) / 2,
+    t1: t1,
+    t2: t2,
+  };
+}
+function splitData(data) {
+  var split = data.bez.split(0.5);
+  return [
+    intersectData(split[0], data.t1, data.t),
+    intersectData(split[1], data.t, data.t2),
+  ];
+}
+
+function boxIntersect(b1, b2) {
+  return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width
+    && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
+}
+
+function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
+  if (!boxIntersect(d1, d2)) return;
+  if (depth >= maxRecursion || (d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance)) {
+    intersections.push([d1.t, d2.t]);
+    return;
+  }
+  var d1s = splitData(d1);
+  var d2s = splitData(d2);
+  intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[0], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+}
+
+PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
+  if (tolerance === undefined) tolerance = 2;
+  if (maxRecursion === undefined) maxRecursion = 7;
+  var intersections = [];
+  intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
+  return intersections;
+};
+
+PolynomialBezier.shapeSegment = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
+};
+
+PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
+};
+
+function crossProduct(a, b) {
+  return [
+    a[1] * b[2] - a[2] * b[1],
+    a[2] * b[0] - a[0] * b[2],
+    a[0] * b[1] - a[1] * b[0],
+  ];
+}
+
+function lineIntersection(start1, end1, start2, end2) {
+  var v1 = [start1[0], start1[1], 1];
+  var v2 = [end1[0], end1[1], 1];
+  var v3 = [start2[0], start2[1], 1];
+  var v4 = [end2[0], end2[1], 1];
+
+  var r = crossProduct(
+    crossProduct(v1, v2),
+    crossProduct(v3, v4)
+  );
+
+  if (floatZero(r[2])) return null;
+
+  return [r[0] / r[2], r[1] / r[2]];
+}
+
+function polarOffset(p, angle, length) {
+  return [
+    p[0] + Math.cos(angle) * length,
+    p[1] - Math.sin(angle) * length,
+  ];
+}
+
+function pointDistance(p1, p2) {
+  return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
+}
+
+function pointEqual(p1, p2) {
+  return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
+}
+
+function ZigZagModifier() {}
+extendPrototype([ShapeModifier], ZigZagModifier);
+ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
+  this.frequency = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
+  this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
+};
+
+function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
+  var angO = angle - Math.PI / 2;
+  var angI = angle + Math.PI / 2;
+  var px = point[0] + Math.cos(angle) * direction * amplitude;
+  var py = point[1] - Math.sin(angle) * direction * amplitude;
+
+  outputBezier.setTripleAt(
+    px,
+    py,
+    px + Math.cos(angO) * outAmplitude,
+    py - Math.sin(angO) * outAmplitude,
+    px + Math.cos(angI) * inAmplitude,
+    py - Math.sin(angI) * inAmplitude,
+    outputBezier.length()
+  );
+}
+
+function getPerpendicularVector(pt1, pt2) {
+  var vector = [
+    pt2[0] - pt1[0],
+    pt2[1] - pt1[1],
+  ];
+  var rot = -Math.PI * 0.5;
+  var rotatedVector = [
+    Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1],
+    Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1],
+  ];
+  return rotatedVector;
+}
+
+function getProjectingAngle(path, cur) {
+  var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
+  var nextIndex = (cur + 1) % path.length();
+  var prevPoint = path.v[prevIndex];
+  var nextPoint = path.v[nextIndex];
+  var pVector = getPerpendicularVector(prevPoint, nextPoint);
+  return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
+}
+
+function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
+  var angle = getProjectingAngle(path, cur);
+  var point = path.v[cur % path._length];
+  var prevPoint = path.v[cur === 0 ? path._length - 1 : cur - 1];
+  var nextPoint = path.v[(cur + 1) % path._length];
+  var prevDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - prevPoint[0], 2) + Math.pow(point[1] - prevPoint[1], 2))
+    : 0;
+  var nextDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2))
+    : 0;
+
+  setPoint(
+    outputBezier,
+    path.v[cur % path._length],
+    angle,
+    direction,
+    amplitude,
+    nextDist / ((frequency + 1) * 2),
+    prevDist / ((frequency + 1) * 2),
+    pointType
+  );
+}
+
+function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
+  for (var i = 0; i < frequency; i += 1) {
+    var t = (i + 1) / (frequency + 1);
+
+    var dist = pointType === 2
+      ? Math.sqrt(Math.pow(segment.points[3][0] - segment.points[0][0], 2) + Math.pow(segment.points[3][1] - segment.points[0][1], 2))
+      : 0;
+
+    var angle = segment.normalAngle(t);
+    var point = segment.point(t);
+    setPoint(
+      outputBezier,
+      point,
+      angle,
+      direction,
+      amplitude,
+      dist / ((frequency + 1) * 2),
+      dist / ((frequency + 1) * 2),
+      pointType
+    );
+
+    direction = -direction;
+  }
+
+  return direction;
+}
+
+ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
+  var count = path._length;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+
+  if (!path.c) {
+    count -= 1;
+  }
+
+  if (count === 0) return clonedPath;
+
+  var direction = -1;
+  var segment = PolynomialBezier.shapeSegment(path, 0);
+  zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
+
+  for (var i = 0; i < count; i += 1) {
+    direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
+
+    if (i === count - 1 && !path.c) {
+      segment = null;
+    } else {
+      segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
+    }
+
+    zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
+  }
+
+  return clonedPath;
+};
+
+ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amplitude = this.amplitude.v;
+  var frequency = Math.max(0, Math.round(this.frequency.v));
+  var pointType = this.pointsType.v;
+
+  if (amplitude !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function linearOffset(p1, p2, amount) {
+  var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
+  return [
+    polarOffset(p1, angle, amount),
+    polarOffset(p2, angle, amount),
+  ];
+}
+
+function offsetSegment(segment, amount) {
+  var p0; var p1a; var p1b; var p2b; var p2a; var
+    p3;
+  var e;
+  e = linearOffset(segment.points[0], segment.points[1], amount);
+  p0 = e[0];
+  p1a = e[1];
+  e = linearOffset(segment.points[1], segment.points[2], amount);
+  p1b = e[0];
+  p2b = e[1];
+  e = linearOffset(segment.points[2], segment.points[3], amount);
+  p2a = e[0];
+  p3 = e[1];
+  var p1 = lineIntersection(p0, p1a, p1b, p2b);
+  if (p1 === null) p1 = p1a;
+  var p2 = lineIntersection(p2a, p3, p1b, p2b);
+  if (p2 === null) p2 = p2a;
+
+  return new PolynomialBezier(p0, p1, p2, p3);
+}
+
+function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
+  var p0 = seg1.points[3];
+  var p1 = seg2.points[0];
+
+  // Bevel
+  if (lineJoin === 3) return p0;
+
+  // Connected, they don't need a joint
+  if (pointEqual(p0, p1)) return p0;
+
+  // Round
+  if (lineJoin === 2) {
+    var angleOut = -seg1.tangentAngle(1);
+    var angleIn = -seg2.tangentAngle(0) + Math.PI;
+    var center = lineIntersection(
+      p0,
+      polarOffset(p0, angleOut + Math.PI / 2, 100),
+      p1,
+      polarOffset(p1, angleOut + Math.PI / 2, 100)
+    );
+    var radius = center ? pointDistance(center, p0) : pointDistance(p0, p1) / 2;
+
+    var tan = polarOffset(p0, angleOut, 2 * radius * roundCorner);
+    outputBezier.setXYAt(tan[0], tan[1], 'o', outputBezier.length() - 1);
+
+    tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
+    outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
+
+    return p1;
+  }
+
+  // Miter
+  var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
+  var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
+  var intersection = lineIntersection(t0, p0, p1, t1);
+  if (intersection && pointDistance(intersection, p0) < miterLimit) {
+    outputBezier.setTripleAt(
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      outputBezier.length()
+    );
+    return intersection;
+  }
+
+  return p0;
+}
+
+function getIntersection(a, b) {
+  const intersect = a.intersections(b);
+
+  if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
+
+  if (intersect.length) return intersect[0];
+
+  return null;
+}
+
+function pruneSegmentIntersection(a, b) {
+  var outa = a.slice();
+  var outb = b.slice();
+  var intersect = getIntersection(a[a.length - 1], b[0]);
+  if (intersect) {
+    outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
+    outb[0] = b[0].split(intersect[1])[1];
+  }
+  if (a.length > 1 && b.length > 1) {
+    intersect = getIntersection(a[0], b[b.length - 1]);
+    if (intersect) {
+      return [
+        [a[0].split(intersect[0])[0]],
+        [b[b.length - 1].split(intersect[1])[1]],
+      ];
+    }
+  }
+  return [outa, outb];
+}
+
+function pruneIntersections(segments) {
+  var e;
+  for (var i = 1; i < segments.length; i += 1) {
+    e = pruneSegmentIntersection(segments[i - 1], segments[i]);
+    segments[i - 1] = e[0];
+    segments[i] = e[1];
+  }
+
+  if (segments.length > 1) {
+    e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
+    segments[segments.length - 1] = e[0];
+    segments[0] = e[1];
+  }
+
+  return segments;
+}
+
+function offsetSegmentSplit(segment, amount) {
+  /*
+    We split each bezier segment into smaller pieces based
+    on inflection points, this ensures the control point
+    polygon is convex.
+
+    (A cubic bezier can have none, one, or two inflection points)
+  */
+  var flex = segment.inflectionPoints();
+  var left;
+  var right;
+  var split;
+  var mid;
+
+  if (flex.length === 0) {
+    return [offsetSegment(segment, amount)];
+  }
+
+  if (flex.length === 1 || floatEqual(flex[1], 1)) {
+    split = segment.split(flex[0]);
+    left = split[0];
+    right = split[1];
+
+    return [
+      offsetSegment(left, amount),
+      offsetSegment(right, amount),
+    ];
+  }
+
+  split = segment.split(flex[0]);
+  left = split[0];
+  var t = (flex[1] - flex[0]) / (1 - flex[0]);
+  split = split[1].split(t);
+  mid = split[0];
+  right = split[1];
+
+  return [
+    offsetSegment(left, amount),
+    offsetSegment(mid, amount),
+    offsetSegment(right, amount),
+  ];
+}
+
+function OffsetPathModifier() {}
+
+extendPrototype([ShapeModifier], OffsetPathModifier);
+OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this.miterLimit = PropertyFactory.getProp(elem, data.ml, 0, null, this);
+  this.lineJoin = data.lj;
+  this._isAnimated = this.amount.effectsSequence.length !== 0;
+};
+
+OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
+  var outputBezier = shapePool.newElement();
+  outputBezier.c = inputBezier.c;
+  var count = inputBezier.length();
+  if (!inputBezier.c) {
+    count -= 1;
+  }
+  var i; var j; var segment;
+  var multiSegments = [];
+
+  for (i = 0; i < count; i += 1) {
+    segment = PolynomialBezier.shapeSegment(inputBezier, i);
+    multiSegments.push(offsetSegmentSplit(segment, amount));
+  }
+
+  if (!inputBezier.c) {
+    for (i = count - 1; i >= 0; i -= 1) {
+      segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
+      multiSegments.push(offsetSegmentSplit(segment, amount));
+    }
+  }
+
+  multiSegments = pruneIntersections(multiSegments);
+
+  // Add bezier segments to the output and apply line joints
+  var lastPoint = null;
+  var lastSeg = null;
+
+  for (i = 0; i < multiSegments.length; i += 1) {
+    var multiSegment = multiSegments[i];
+
+    if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
+
+    lastSeg = multiSegment[multiSegment.length - 1];
+
+    for (j = 0; j < multiSegment.length; j += 1) {
+      segment = multiSegment[j];
+
+      if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
+        outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
+      } else {
+        outputBezier.setTripleAt(
+          segment.points[0][0],
+          segment.points[0][1],
+          segment.points[1][0],
+          segment.points[1][1],
+          segment.points[0][0],
+          segment.points[0][1],
+          outputBezier.length()
+        );
+      }
+
+      outputBezier.setTripleAt(
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[2][0],
+        segment.points[2][1],
+        outputBezier.length()
+      );
+
+      lastPoint = segment.points[3];
+    }
+  }
+
+  if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
+
+  return outputBezier;
+};
+
+OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+  var miterLimit = this.miterLimit.v;
+  var lineJoin = this.lineJoin;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function getFontProperties(fontData) {
+  var styles = fontData.fStyle ? fontData.fStyle.split(' ') : [];
+
+  var fWeight = 'normal'; var
+    fStyle = 'normal';
+  var len = styles.length;
+  var styleName;
+  for (var i = 0; i < len; i += 1) {
+    styleName = styles[i].toLowerCase();
+    switch (styleName) {
+      case 'italic':
+        fStyle = 'italic';
+        break;
+      case 'bold':
+        fWeight = '700';
+        break;
+      case 'black':
+        fWeight = '900';
+        break;
+      case 'medium':
+        fWeight = '500';
+        break;
+      case 'regular':
+      case 'normal':
+        fWeight = '400';
+        break;
+      case 'light':
+      case 'thin':
+        fWeight = '200';
+        break;
+      default:
+        break;
+    }
+  }
+
+  return {
+    style: fStyle,
+    weight: fontData.fWeight || fWeight,
+  };
+}
+
+const FontManager = (function () {
+  var maxWaitingTime = 5000;
+  var emptyChar = {
+    w: 0,
+    size: 0,
+    shapes: [],
+    data: {
+      shapes: [],
+    },
+  };
+  var combinedCharacters = [];
+  // Hindi characters
+  combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366,
+    2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379,
+    2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
+
+  var BLACK_FLAG_CODE_POINT = 127988;
+  var CANCEL_TAG_CODE_POINT = 917631;
+  var A_TAG_CODE_POINT = 917601;
+  var Z_TAG_CODE_POINT = 917626;
+  var VARIATION_SELECTOR_16_CODE_POINT = 65039;
+  var ZERO_WIDTH_JOINER_CODE_POINT = 8205;
+  var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
+  var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
+
+  var surrogateModifiers = [
+    'd83cdffb',
+    'd83cdffc',
+    'd83cdffd',
+    'd83cdffe',
+    'd83cdfff',
+  ];
+
+  function trimFontOptions(font) {
+    var familyArray = font.split(',');
+    var i;
+    var len = familyArray.length;
+    var enabledFamilies = [];
+    for (i = 0; i < len; i += 1) {
+      if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
+        enabledFamilies.push(familyArray[i]);
+      }
+    }
+    return enabledFamilies.join(',');
+  }
+
+  function setUpNode(font, family) {
+    var parentNode = createTag('span');
+    // Node is invisible to screen readers.
+    parentNode.setAttribute('aria-hidden', true);
+    parentNode.style.fontFamily = family;
+    var node = createTag('span');
+    // Characters that vary significantly among different fonts
+    node.innerText = 'giItT1WQy@!-/#';
+    // Visible - so we can measure it - but not on the screen
+    parentNode.style.position = 'absolute';
+    parentNode.style.left = '-10000px';
+    parentNode.style.top = '-10000px';
+    // Large font size makes even subtle changes obvious
+    parentNode.style.fontSize = '300px';
+    // Reset any font properties
+    parentNode.style.fontVariant = 'normal';
+    parentNode.style.fontStyle = 'normal';
+    parentNode.style.fontWeight = 'normal';
+    parentNode.style.letterSpacing = '0';
+    parentNode.appendChild(node);
+    document.body.appendChild(parentNode);
+
+    // Remember width with no applied web font
+    var width = node.offsetWidth;
+    node.style.fontFamily = trimFontOptions(font) + ', ' + family;
+    return { node: node, w: width, parent: parentNode };
+  }
+
+  function checkLoadedFonts() {
+    var i;
+    var len = this.fonts.length;
+    var node;
+    var w;
+    var loadedCount = len;
+    for (i = 0; i < len; i += 1) {
+      if (this.fonts[i].loaded) {
+        loadedCount -= 1;
+      } else if (this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0) {
+        this.fonts[i].loaded = true;
+      } else {
+        node = this.fonts[i].monoCase.node;
+        w = this.fonts[i].monoCase.w;
+        if (node.offsetWidth !== w) {
+          loadedCount -= 1;
+          this.fonts[i].loaded = true;
+        } else {
+          node = this.fonts[i].sansCase.node;
+          w = this.fonts[i].sansCase.w;
+          if (node.offsetWidth !== w) {
+            loadedCount -= 1;
+            this.fonts[i].loaded = true;
+          }
+        }
+        if (this.fonts[i].loaded) {
+          this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
+          this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
+        }
+      }
+    }
+
+    if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
+      setTimeout(this.checkLoadedFontsBinded, 20);
+    } else {
+      setTimeout(this.setIsLoadedBinded, 10);
+    }
+  }
+
+  function createHelper(fontData, def) {
+    var engine = (document.body && def) ? 'svg' : 'canvas';
+    var helper;
+    var fontProps = getFontProperties(fontData);
+    if (engine === 'svg') {
+      var tHelper = createNS('text');
+      tHelper.style.fontSize = '100px';
+      // tHelper.style.fontFamily = fontData.fFamily;
+      tHelper.setAttribute('font-family', fontData.fFamily);
+      tHelper.setAttribute('font-style', fontProps.style);
+      tHelper.setAttribute('font-weight', fontProps.weight);
+      tHelper.textContent = '1';
+      if (fontData.fClass) {
+        tHelper.style.fontFamily = 'inherit';
+        tHelper.setAttribute('class', fontData.fClass);
+      } else {
+        tHelper.style.fontFamily = fontData.fFamily;
+      }
+      def.appendChild(tHelper);
+      helper = tHelper;
+    } else {
+      var tCanvasHelper = new OffscreenCanvas(500, 500).getContext('2d');
+      tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
+      helper = tCanvasHelper;
+    }
+    function measure(text) {
+      if (engine === 'svg') {
+        helper.textContent = text;
+        return helper.getComputedTextLength();
+      }
+      return helper.measureText(text).width;
+    }
+    return {
+      measureText: measure,
+    };
+  }
+
+  function addFonts(fontData, defs) {
+    if (!fontData) {
+      this.isLoaded = true;
+      return;
+    }
+    if (this.chars) {
+      this.isLoaded = true;
+      this.fonts = fontData.list;
+      return;
+    }
+    if (!document.body) {
+      this.isLoaded = true;
+      fontData.list.forEach((data) => {
+        data.helper = createHelper(data);
+        data.cache = {};
+      });
+      this.fonts = fontData.list;
+      return;
+    }
+
+    var fontArr = fontData.list;
+    var i;
+    var len = fontArr.length;
+    var _pendingFonts = len;
+    for (i = 0; i < len; i += 1) {
+      var shouldLoadFont = true;
+      var loadedSelector;
+      var j;
+      fontArr[i].loaded = false;
+      fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
+      fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
+      if (!fontArr[i].fPath) {
+        fontArr[i].loaded = true;
+        _pendingFonts -= 1;
+      } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
+        loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
+
+        if (loadedSelector.length > 0) {
+          shouldLoadFont = false;
+        }
+
+        if (shouldLoadFont) {
+          var s = createTag('style');
+          s.setAttribute('f-forigin', fontArr[i].fOrigin);
+          s.setAttribute('f-origin', fontArr[i].origin);
+          s.setAttribute('f-family', fontArr[i].fFamily);
+          s.type = 'text/css';
+          s.innerText = '@font-face {font-family: ' + fontArr[i].fFamily + "; font-style: normal; src: url('" + fontArr[i].fPath + "');}";
+          defs.appendChild(s);
+        }
+      } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
+        loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var l = createTag('link');
+          l.setAttribute('f-forigin', fontArr[i].fOrigin);
+          l.setAttribute('f-origin', fontArr[i].origin);
+          l.type = 'text/css';
+          l.rel = 'stylesheet';
+          l.href = fontArr[i].fPath;
+          document.body.appendChild(l);
+        }
+      } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
+        loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (fontArr[i].fPath === loadedSelector[j].src) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var sc = createTag('link');
+          sc.setAttribute('f-forigin', fontArr[i].fOrigin);
+          sc.setAttribute('f-origin', fontArr[i].origin);
+          sc.setAttribute('rel', 'stylesheet');
+          sc.setAttribute('href', fontArr[i].fPath);
+          defs.appendChild(sc);
+        }
+      }
+      fontArr[i].helper = createHelper(fontArr[i], defs);
+      fontArr[i].cache = {};
+      this.fonts.push(fontArr[i]);
+    }
+    if (_pendingFonts === 0) {
+      this.isLoaded = true;
+    } else {
+      // On some cases even if the font is loaded, it won't load correctly when measuring text on canvas.
+      // Adding this timeout seems to fix it
+      setTimeout(this.checkLoadedFonts.bind(this), 100);
+    }
+  }
+
+  function addChars(chars) {
+    if (!chars) {
+      return;
+    }
+    if (!this.chars) {
+      this.chars = [];
+    }
+    var i;
+    var len = chars.length;
+    var j;
+    var jLen = this.chars.length;
+    var found;
+    for (i = 0; i < len; i += 1) {
+      j = 0;
+      found = false;
+      while (j < jLen) {
+        if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
+          found = true;
+        }
+        j += 1;
+      }
+      if (!found) {
+        this.chars.push(chars[i]);
+        jLen += 1;
+      }
+    }
+  }
+
+  function getCharData(char, style, font) {
+    var i = 0;
+    var len = this.chars.length;
+    while (i < len) {
+      if (this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font) {
+        return this.chars[i];
+      }
+      i += 1;
+    }
+    if (((typeof char === 'string' && char.charCodeAt(0) !== 13) || !char)
+            && console
+            && console.warn // eslint-disable-line no-console
+            && !this._warned
+    ) {
+      this._warned = true;
+      console.warn('Missing character from exported characters list: ', char, style, font); // eslint-disable-line no-console
+    }
+    return emptyChar;
+  }
+
+  function measureText(char, fontName, size) {
+    var fontData = this.getFontByName(fontName);
+    // Using the char instead of char.charCodeAt(0)
+    // to avoid collisions between equal chars
+    var index = char;
+    if (!fontData.cache[index]) {
+      var tHelper = fontData.helper;
+      if (char === ' ') {
+        var doubleSize = tHelper.measureText('|' + char + '|');
+        var singleSize = tHelper.measureText('||');
+        fontData.cache[index] = (doubleSize - singleSize) / 100;
+      } else {
+        fontData.cache[index] = tHelper.measureText(char) / 100;
+      }
+    }
+    return fontData.cache[index] * size;
+  }
+
+  function getFontByName(name) {
+    var i = 0;
+    var len = this.fonts.length;
+    while (i < len) {
+      if (this.fonts[i].fName === name) {
+        return this.fonts[i];
+      }
+      i += 1;
+    }
+    return this.fonts[0];
+  }
+
+  function getCodePoint(string) {
+    var codePoint = 0;
+    var first = string.charCodeAt(0);
+    if (first >= 0xD800 && first <= 0xDBFF) {
+      var second = string.charCodeAt(1);
+      if (second >= 0xDC00 && second <= 0xDFFF) {
+        codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+      }
+    }
+    return codePoint;
+  }
+
+  // Skin tone modifiers
+  function isModifier(firstCharCode, secondCharCode) {
+    var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
+    return surrogateModifiers.indexOf(sum) !== -1;
+  }
+
+  function isZeroWidthJoiner(charCode) {
+    return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
+  }
+
+  // This codepoint may change the appearance of the preceding character.
+  // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
+  // as a colorful image as compared to a monochrome text variant.
+  function isVariationSelector(charCode) {
+    return charCode === VARIATION_SELECTOR_16_CODE_POINT;
+  }
+
+  // The regional indicator symbols are a set of 26 alphabetic Unicode
+  /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
+  // two-letter country codes in a way that allows optional special treatment.
+  function isRegionalCode(string) {
+    var codePoint = getCodePoint(string);
+    if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
+      return true;
+    }
+    return false;
+  }
+
+  // Some Emoji implementations represent combinations of
+  // two “regional indicator” letters as a single flag symbol.
+  function isFlagEmoji(string) {
+    return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
+  }
+
+  function isCombinedCharacter(char) {
+    return combinedCharacters.indexOf(char) !== -1;
+  }
+
+  // Regional flags start with a BLACK_FLAG_CODE_POINT
+  // folowed by 5 chars in the TAG range
+  // and end with a CANCEL_TAG_CODE_POINT
+  function isRegionalFlag(text, index) {
+    var codePoint = getCodePoint(text.substr(index, 2));
+    if (codePoint !== BLACK_FLAG_CODE_POINT) {
+      return false;
+    }
+    var count = 0;
+    index += 2;
+    while (count < 5) {
+      codePoint = getCodePoint(text.substr(index, 2));
+      if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
+        return false;
+      }
+      count += 1;
+      index += 2;
+    }
+    return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
+  }
+
+  function setIsLoaded() {
+    this.isLoaded = true;
+  }
+
+  var Font = function () {
+    this.fonts = [];
+    this.chars = null;
+    this.typekitLoaded = 0;
+    this.isLoaded = false;
+    this._warned = false;
+    this.initTime = Date.now();
+    this.setIsLoadedBinded = this.setIsLoaded.bind(this);
+    this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
+  };
+  Font.isModifier = isModifier;
+  Font.isZeroWidthJoiner = isZeroWidthJoiner;
+  Font.isFlagEmoji = isFlagEmoji;
+  Font.isRegionalCode = isRegionalCode;
+  Font.isCombinedCharacter = isCombinedCharacter;
+  Font.isRegionalFlag = isRegionalFlag;
+  Font.isVariationSelector = isVariationSelector;
+  Font.BLACK_FLAG_CODE_POINT = BLACK_FLAG_CODE_POINT;
+
+  var fontPrototype = {
+    addChars: addChars,
+    addFonts: addFonts,
+    getCharData: getCharData,
+    getFontByName: getFontByName,
+    measureText: measureText,
+    checkLoadedFonts: checkLoadedFonts,
+    setIsLoaded: setIsLoaded,
+  };
+
+  Font.prototype = fontPrototype;
+
+  return Font;
+}());
+
+function SlotManager(animationData) {
+  this.animationData = animationData;
+}
+SlotManager.prototype.getProp = function (data) {
+  if (this.animationData.slots
+    && this.animationData.slots[data.sid]
+  ) {
+    return Object.assign(data, this.animationData.slots[data.sid].p);
+  }
+  return data;
+};
+
+function slotFactory(animationData) {
+  return new SlotManager(animationData);
+}
+
+function RenderableElement() {
+
+}
+
+RenderableElement.prototype = {
+  initRenderable: function () {
+    // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
+    this.isInRange = false;
+    // layer's display state
+    this.hidden = false;
+    // If layer's transparency equals 0, it can be hidden
+    this.isTransparent = false;
+    // list of animated components
+    this.renderableComponents = [];
+  },
+  addRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) === -1) {
+      this.renderableComponents.push(component);
+    }
+  },
+  removeRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) !== -1) {
+      this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1);
+    }
+  },
+  prepareRenderableFrame: function (num) {
+    this.checkLayerLimits(num);
+  },
+  checkTransparency: function () {
+    if (this.finalTransform.mProp.o.v <= 0) {
+      if (!this.isTransparent && this.globalData.renderConfig.hideOnTransparent) {
+        this.isTransparent = true;
+        this.hide();
+      }
+    } else if (this.isTransparent) {
+      this.isTransparent = false;
+      this.show();
+    }
+  },
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     *
+     */
+  checkLayerLimits: function (num) {
+    if (this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) {
+      if (this.isInRange !== true) {
+        this.globalData._mdf = true;
+        this._mdf = true;
+        this.isInRange = true;
+        this.show();
+      }
+    } else if (this.isInRange !== false) {
+      this.globalData._mdf = true;
+      this.isInRange = false;
+      this.hide();
+    }
+  },
+  renderRenderable: function () {
+    var i;
+    var len = this.renderableComponents.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderableComponents[i].renderFrame(this._isFirstFrame);
+    }
+    /* this.maskManager.renderFrame(this.finalTransform.mat);
+        this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
+  },
+  sourceRectAtTime: function () {
+    return {
+      top: 0,
+      left: 0,
+      width: 100,
+      height: 100,
+    };
+  },
+  getLayerSize: function () {
+    if (this.data.ty === 5) {
+      return { w: this.data.textData.width, h: this.data.textData.height };
+    }
+    return { w: this.data.width, h: this.data.height };
+  },
+};
+
+const getBlendMode = (function () {
+  var blendModeEnums = {
+    0: 'source-over',
+    1: 'multiply',
+    2: 'screen',
+    3: 'overlay',
+    4: 'darken',
+    5: 'lighten',
+    6: 'color-dodge',
+    7: 'color-burn',
+    8: 'hard-light',
+    9: 'soft-light',
+    10: 'difference',
+    11: 'exclusion',
+    12: 'hue',
+    13: 'saturation',
+    14: 'color',
+    15: 'luminosity',
+  };
+
+  return function (mode) {
+    return blendModeEnums[mode] || '';
+  };
+}());
+
+function SliderEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function AngleEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function ColorEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function PointEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function LayerIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function MaskIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function CheckboxEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function NoValueEffect() {
+  this.p = {};
+}
+
+function EffectsManager(data, element) {
+  var effects = data.ef || [];
+  this.effectElements = [];
+  var i;
+  var len = effects.length;
+  var effectItem;
+  for (i = 0; i < len; i += 1) {
+    effectItem = new GroupEffect(effects[i], element);
+    this.effectElements.push(effectItem);
+  }
+}
+
+function GroupEffect(data, element) {
+  this.init(data, element);
+}
+
+extendPrototype([DynamicPropertyContainer], GroupEffect);
+
+GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
+
+GroupEffect.prototype.init = function (data, element) {
+  this.data = data;
+  this.effectElements = [];
+  this.initDynamicPropertyContainer(element);
+  var i;
+  var len = this.data.ef.length;
+  var eff;
+  var effects = this.data.ef;
+  for (i = 0; i < len; i += 1) {
+    eff = null;
+    switch (effects[i].ty) {
+      case 0:
+        eff = new SliderEffect(effects[i], element, this);
+        break;
+      case 1:
+        eff = new AngleEffect(effects[i], element, this);
+        break;
+      case 2:
+        eff = new ColorEffect(effects[i], element, this);
+        break;
+      case 3:
+        eff = new PointEffect(effects[i], element, this);
+        break;
+      case 4:
+      case 7:
+        eff = new CheckboxEffect(effects[i], element, this);
+        break;
+      case 10:
+        eff = new LayerIndexEffect(effects[i], element, this);
+        break;
+      case 11:
+        eff = new MaskIndexEffect(effects[i], element, this);
+        break;
+      case 5:
+        eff = new EffectsManager(effects[i], element, this);
+        break;
+        // case 6:
+      default:
+        eff = new NoValueEffect(effects[i], element, this);
+        break;
+    }
+    if (eff) {
+      this.effectElements.push(eff);
+    }
+  }
+};
+
+function BaseElement() {
+}
+
+BaseElement.prototype = {
+  checkMasks: function () {
+    if (!this.data.hasMask) {
+      return false;
+    }
+    var i = 0;
+    var len = this.data.masksProperties.length;
+    while (i < len) {
+      if ((this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false)) {
+        return true;
+      }
+      i += 1;
+    }
+    return false;
+  },
+  initExpressions: function () {
+    const expressionsInterfaces = getExpressionInterfaces();
+    if (!expressionsInterfaces) {
+      return;
+    }
+    const LayerExpressionInterface = expressionsInterfaces('layer');
+    const EffectsExpressionInterface = expressionsInterfaces('effects');
+    const ShapeExpressionInterface = expressionsInterfaces('shape');
+    const TextExpressionInterface = expressionsInterfaces('text');
+    const CompExpressionInterface = expressionsInterfaces('comp');
+    this.layerInterface = LayerExpressionInterface(this);
+    if (this.data.hasMask && this.maskManager) {
+      this.layerInterface.registerMaskInterface(this.maskManager);
+    }
+    var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
+    this.layerInterface.registerEffectsInterface(effectsInterface);
+
+    if (this.data.ty === 0 || this.data.xt) {
+      this.compInterface = CompExpressionInterface(this);
+    } else if (this.data.ty === 4) {
+      this.layerInterface.shapeInterface = ShapeExpressionInterface(this.shapesData, this.itemsData, this.layerInterface);
+      this.layerInterface.content = this.layerInterface.shapeInterface;
+    } else if (this.data.ty === 5) {
+      this.layerInterface.textInterface = TextExpressionInterface(this);
+      this.layerInterface.text = this.layerInterface.textInterface;
+    }
+  },
+  setBlendMode: function () {
+    var blendModeValue = getBlendMode(this.data.bm);
+    var elem = this.baseElement || this.layerElement;
+
+    elem.style['mix-blend-mode'] = blendModeValue;
+  },
+  initBaseData: function (data, globalData, comp) {
+    this.globalData = globalData;
+    this.comp = comp;
+    this.data = data;
+    this.layerId = createElementID();
+
+    // Stretch factor for old animations missing this property.
+    if (!this.data.sr) {
+      this.data.sr = 1;
+    }
+    // effects manager
+    this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
+  },
+  getType: function () {
+    return this.type;
+  },
+  sourceRectAtTime: function () {},
+};
+
+/**
+ * @file
+ * Handles element's layer frame update.
+ * Checks layer in point and out point
+ *
+ */
+
+function FrameElement() {}
+
+FrameElement.prototype = {
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     */
+  initFrame: function () {
+    // set to true when inpoint is rendered
+    this._isFirstFrame = false;
+    // list of animated properties
+    this.dynamicProperties = [];
+    // If layer has been modified in current tick this will be true
+    this._mdf = false;
+  },
+  /**
+     * @function
+     * Calculates all dynamic values
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     * @param {boolean} isVisible
+     * if layers is currently in range
+     *
+     */
+  prepareProperties: function (num, isVisible) {
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      if (isVisible || (this._isParent && this.dynamicProperties[i].propType === 'transform')) {
+        this.dynamicProperties[i].getValue();
+        if (this.dynamicProperties[i]._mdf) {
+          this.globalData._mdf = true;
+          this._mdf = true;
+        }
+      }
+    }
+  },
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+    }
+  },
+};
+
+function FootageElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.footageData = globalData.imageLoader.getAsset(this.assetData);
+  this.initBaseData(data, globalData, comp);
+}
+
+FootageElement.prototype.prepareFrame = function () {
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
+
+FootageElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+FootageElement.prototype.renderFrame = function () {
+};
+
+FootageElement.prototype.destroy = function () {
+};
+
+FootageElement.prototype.initExpressions = function () {
+  const expressionsInterfaces = getExpressionInterfaces();
+  if (!expressionsInterfaces) {
+    return;
+  }
+  const FootageInterface = expressionsInterfaces('footage');
+  this.layerInterface = FootageInterface(this);
+};
+
+FootageElement.prototype.getFootageData = function () {
+  return this.footageData;
+};
+
+function AudioElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initBaseData(data, globalData, comp);
+  this._isPlaying = false;
+  this._canPlay = false;
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  this.audio = this.globalData.audioController.createAudio(assetPath);
+  this._currentTime = 0;
+  this.globalData.audioController.addAudio(this);
+  this._volumeMultiplier = 1;
+  this._volume = 1;
+  this._previousVolume = null;
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+  this.lv = PropertyFactory.getProp(this, data.au && data.au.lv ? data.au.lv : { k: [100] }, 1, 0.01, this);
+}
+
+AudioElement.prototype.prepareFrame = function (num) {
+  this.prepareRenderableFrame(num, true);
+  this.prepareProperties(num, true);
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    this._currentTime = timeRemapped;
+  } else {
+    this._currentTime = num / this.data.sr;
+  }
+  this._volume = this.lv.v[0];
+  var totalVolume = this._volume * this._volumeMultiplier;
+  if (this._previousVolume !== totalVolume) {
+    this._previousVolume = totalVolume;
+    this.audio.volume(totalVolume);
+  }
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
+
+AudioElement.prototype.renderFrame = function () {
+  if (this.isInRange && this._canPlay) {
+    if (!this._isPlaying) {
+      this.audio.play();
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+      this._isPlaying = true;
+    } else if (!this.audio.playing()
+      || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1
+    ) {
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+    }
+  }
+};
+
+AudioElement.prototype.show = function () {
+  // this.audio.play()
+};
+
+AudioElement.prototype.hide = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+};
+
+AudioElement.prototype.pause = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+  this._canPlay = false;
+};
+
+AudioElement.prototype.resume = function () {
+  this._canPlay = true;
+};
+
+AudioElement.prototype.setRate = function (rateValue) {
+  this.audio.rate(rateValue);
+};
+
+AudioElement.prototype.volume = function (volumeValue) {
+  this._volumeMultiplier = volumeValue;
+  this._previousVolume = volumeValue * this._volume;
+  this.audio.volume(this._previousVolume);
+};
+
+AudioElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+AudioElement.prototype.destroy = function () {
+};
+
+AudioElement.prototype.sourceRectAtTime = function () {
+};
+
+AudioElement.prototype.initExpressions = function () {
+};
+
+function BaseRenderer() {}
+BaseRenderer.prototype.checkLayers = function (num) {
+  var i;
+  var len = this.layers.length;
+  var data;
+  this.completeLayers = true;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (!this.elements[i]) {
+      data = this.layers[i];
+      if (data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) {
+        this.buildItem(i);
+      }
+    }
+    this.completeLayers = this.elements[i] ? this.completeLayers : false;
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.createItem = function (layer) {
+  switch (layer.ty) {
+    case 2:
+      return this.createImage(layer);
+    case 0:
+      return this.createComp(layer);
+    case 1:
+      return this.createSolid(layer);
+    case 3:
+      return this.createNull(layer);
+    case 4:
+      return this.createShape(layer);
+    case 5:
+      return this.createText(layer);
+    case 6:
+      return this.createAudio(layer);
+    case 13:
+      return this.createCamera(layer);
+    case 15:
+      return this.createFootage(layer);
+    default:
+      return this.createNull(layer);
+  }
+};
+
+BaseRenderer.prototype.createCamera = function () {
+  throw new Error('You\'re using a 3d camera. Try the html renderer.');
+};
+
+BaseRenderer.prototype.createAudio = function (data) {
+  return new AudioElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.createFootage = function (data) {
+  return new FootageElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.buildAllItems = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    this.buildItem(i);
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.includeLayers = function (newLayers) {
+  this.completeLayers = false;
+  var i;
+  var len = newLayers.length;
+  var j;
+  var jLen = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    j = 0;
+    while (j < jLen) {
+      if (this.layers[j].id === newLayers[i].id) {
+        this.layers[j] = newLayers[i];
+        break;
+      }
+      j += 1;
+    }
+  }
+};
+
+BaseRenderer.prototype.setProjectInterface = function (pInterface) {
+  this.globalData.projectInterface = pInterface;
+};
+
+BaseRenderer.prototype.initItems = function () {
+  if (!this.globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+};
+BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
+  var elements = this.elements;
+  var layers = this.layers;
+  var i = 0;
+  var len = layers.length;
+  while (i < len) {
+    if (layers[i].ind == parentName) { // eslint-disable-line eqeqeq
+      if (!elements[i] || elements[i] === true) {
+        this.buildItem(i);
+        this.addPendingElement(element);
+      } else {
+        hierarchy.push(elements[i]);
+        elements[i].setAsParent();
+        if (layers[i].parent !== undefined) {
+          this.buildElementParenting(element, layers[i].parent, hierarchy);
+        } else {
+          element.setHierarchy(hierarchy);
+        }
+      }
+    }
+    i += 1;
+  }
+};
+
+BaseRenderer.prototype.addPendingElement = function (element) {
+  this.pendingElements.push(element);
+};
+
+BaseRenderer.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var len = assets.length;
+  for (i = 0; i < len; i += 1) {
+    if (assets[i].xt) {
+      var comp = this.createComp(assets[i]);
+      comp.initExpressions();
+      this.globalData.projectInterface.registerComposition(comp);
+    }
+  }
+};
+
+BaseRenderer.prototype.getElementById = function (ind) {
+  var i;
+  var len = this.elements.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i].data.ind === ind) {
+      return this.elements[i];
+    }
+  }
+  return null;
+};
+
+BaseRenderer.prototype.getElementByPath = function (path) {
+  var pathValue = path.shift();
+  var element;
+  if (typeof pathValue === 'number') {
+    element = this.elements[pathValue];
+  } else {
+    var i;
+    var len = this.elements.length;
+    for (i = 0; i < len; i += 1) {
+      if (this.elements[i].data.nm === pathValue) {
+        element = this.elements[i];
+        break;
+      }
+    }
+  }
+  if (path.length === 0) {
+    return element;
+  }
+  return element.getElementByPath(path);
+};
+
+BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
+  this.globalData.fontManager = new FontManager();
+  this.globalData.slotManager = slotFactory(animData);
+  this.globalData.fontManager.addChars(animData.chars);
+  this.globalData.fontManager.addFonts(animData.fonts, fontsContainer);
+  this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+  this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+  this.globalData.imageLoader = this.animationItem.imagePreloader;
+  this.globalData.audioController = this.animationItem.audioController;
+  this.globalData.frameId = 0;
+  this.globalData.frameRate = animData.fr;
+  this.globalData.nm = animData.nm;
+  this.globalData.compSize = {
+    w: animData.w,
+    h: animData.h,
+  };
+};
+
+var effectTypes = {
+  TRANSFORM_EFFECT: 'transformEFfect',
+};
+
+function TransformElement() {}
+
+TransformElement.prototype = {
+  initTransform: function () {
+    var mat = new Matrix();
+    this.finalTransform = {
+      mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : { o: 0 },
+      _matMdf: false,
+      _localMatMdf: false,
+      _opMdf: false,
+      mat: mat,
+      localMat: mat,
+      localOpacity: 1,
+    };
+    if (this.data.ao) {
+      this.finalTransform.mProp.autoOriented = true;
+    }
+
+    // TODO: check TYPE 11: Guided elements
+    if (this.data.ty !== 11) {
+      // this.createElements();
+    }
+  },
+  renderTransform: function () {
+    this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
+    this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
+
+    if (this.hierarchy) {
+      var mat;
+      var finalMat = this.finalTransform.mat;
+      var i = 0;
+      var len = this.hierarchy.length;
+      // Checking if any of the transformation matrices in the hierarchy chain has changed.
+      if (!this.finalTransform._matMdf) {
+        while (i < len) {
+          if (this.hierarchy[i].finalTransform.mProp._mdf) {
+            this.finalTransform._matMdf = true;
+            break;
+          }
+          i += 1;
+        }
+      }
+
+      if (this.finalTransform._matMdf) {
+        mat = this.finalTransform.mProp.v.props;
+        finalMat.cloneFromProps(mat);
+        for (i = 0; i < len; i += 1) {
+          finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
+        }
+      }
+    }
+    if (!this.localTransforms || this.finalTransform._matMdf) {
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+    }
+    if (this.finalTransform._opMdf) {
+      this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderLocalTransform: function () {
+    if (this.localTransforms) {
+      var i = 0;
+      var len = this.localTransforms.length;
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+      if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
+        while (i < len) {
+          if (this.localTransforms[i]._mdf) {
+            this.finalTransform._localMatMdf = true;
+          }
+          if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
+            this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+            this.finalTransform._opMdf = true;
+          }
+          i += 1;
+        }
+      }
+      if (this.finalTransform._localMatMdf) {
+        var localMat = this.finalTransform.localMat;
+        this.localTransforms[0].matrix.clone(localMat);
+        for (i = 1; i < len; i += 1) {
+          var lmat = this.localTransforms[i].matrix;
+          localMat.multiply(lmat);
+        }
+        localMat.multiply(this.finalTransform.mat);
+      }
+      if (this.finalTransform._opMdf) {
+        var localOp = this.finalTransform.localOpacity;
+        for (i = 0; i < len; i += 1) {
+          localOp *= this.localTransforms[i].opacity * 0.01;
+        }
+        this.finalTransform.localOpacity = localOp;
+      }
+    }
+  },
+  searchEffectTransforms: function () {
+    if (this.renderableEffectsManager) {
+      var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+      if (transformEffects.length) {
+        this.localTransforms = [];
+        this.finalTransform.localMat = new Matrix();
+        var i = 0;
+        var len = transformEffects.length;
+        for (i = 0; i < len; i += 1) {
+          this.localTransforms.push(transformEffects[i]);
+        }
+      }
+    }
+  },
+  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;
+    var len = transforms.length;
+    var 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;
+  },
+  mHelper: new Matrix(),
+};
+
+function MaskElement(data, element, globalData) {
+  this.data = data;
+  this.element = element;
+  this.globalData = globalData;
+  this.storedData = [];
+  this.masksProperties = this.data.masksProperties || [];
+  this.maskElement = null;
+  var defs = this.globalData.defs;
+  var i;
+  var len = this.masksProperties ? this.masksProperties.length : 0;
+  this.viewData = createSizedArray(len);
+  this.solidPath = '';
+
+  var path;
+  var properties = this.masksProperties;
+  var count = 0;
+  var currentMasks = [];
+  var j;
+  var jLen;
+  var layerId = createElementID();
+  var rect;
+  var expansor;
+  var feMorph;
+  var x;
+  var maskType = 'clipPath';
+  var maskRef = 'clip-path';
+  for (i = 0; i < len; i += 1) {
+    if ((properties[i].mode !== 'a' && properties[i].mode !== 'n') || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
+      maskType = 'mask';
+      maskRef = 'mask';
+    }
+
+    if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
+      rect = createNS('rect');
+      rect.setAttribute('fill', '#ffffff');
+      rect.setAttribute('width', this.element.comp.data.w || 0);
+      rect.setAttribute('height', this.element.comp.data.h || 0);
+      currentMasks.push(rect);
+    } else {
+      rect = null;
+    }
+
+    path = createNS('path');
+    if (properties[i].mode === 'n') {
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        elem: path,
+        lastPath: '',
+      };
+      defs.appendChild(path);
+    } else {
+      count += 1;
+
+      path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      path.setAttribute('clip-rule', 'nonzero');
+      var filterID;
+
+      if (properties[i].x.k !== 0) {
+        maskType = 'mask';
+        maskRef = 'mask';
+        x = PropertyFactory.getProp(this.element, properties[i].x, 0, null, this.element);
+        filterID = createElementID();
+        expansor = createNS('filter');
+        expansor.setAttribute('id', filterID);
+        feMorph = createNS('feMorphology');
+        feMorph.setAttribute('operator', 'erode');
+        feMorph.setAttribute('in', 'SourceGraphic');
+        feMorph.setAttribute('radius', '0');
+        expansor.appendChild(feMorph);
+        defs.appendChild(expansor);
+        path.setAttribute('stroke', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      } else {
+        feMorph = null;
+        x = null;
+      }
+
+      // TODO move this to a factory or to a constructor
+      this.storedData[i] = {
+        elem: path,
+        x: x,
+        expan: feMorph,
+        lastPath: '',
+        lastOperator: '',
+        filterId: filterID,
+        lastRadius: 0,
+      };
+      if (properties[i].mode === 'i') {
+        jLen = currentMasks.length;
+        var g = createNS('g');
+        for (j = 0; j < jLen; j += 1) {
+          g.appendChild(currentMasks[j]);
+        }
+        var mask = createNS('mask');
+        mask.setAttribute('mask-type', 'alpha');
+        mask.setAttribute('id', layerId + '_' + count);
+        mask.appendChild(path);
+        defs.appendChild(mask);
+        g.setAttribute('mask', 'url(' + getLocationHref() + '#' + layerId + '_' + count + ')');
+
+        currentMasks.length = 0;
+        currentMasks.push(g);
+      } else {
+        currentMasks.push(path);
+      }
+      if (properties[i].inv && !this.solidPath) {
+        this.solidPath = this.createLayerSolidPath();
+      }
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        elem: path,
+        lastPath: '',
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        invRect: rect,
+      };
+      if (!this.viewData[i].prop.k) {
+        this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
+      }
+    }
+  }
+
+  this.maskElement = createNS(maskType);
+
+  len = currentMasks.length;
+  for (i = 0; i < len; i += 1) {
+    this.maskElement.appendChild(currentMasks[i]);
+  }
+
+  if (count > 0) {
+    this.maskElement.setAttribute('id', layerId);
+    this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
+    defs.appendChild(this.maskElement);
+  }
+  if (this.viewData.length) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+MaskElement.prototype.getMaskProperty = function (pos) {
+  return this.viewData[pos].prop;
+};
+
+MaskElement.prototype.renderFrame = function (isFirstFrame) {
+  var finalMat = this.element.finalTransform.mat;
+  var i;
+  var len = this.masksProperties.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.viewData[i].prop._mdf || isFirstFrame) {
+      this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
+    }
+    if (this.viewData[i].op._mdf || isFirstFrame) {
+      this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
+    }
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
+        this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
+      }
+      if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
+        var feMorph = this.storedData[i].expan;
+        if (this.storedData[i].x.v < 0) {
+          if (this.storedData[i].lastOperator !== 'erode') {
+            this.storedData[i].lastOperator = 'erode';
+            this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
+          }
+          feMorph.setAttribute('radius', -this.storedData[i].x.v);
+        } else {
+          if (this.storedData[i].lastOperator !== 'dilate') {
+            this.storedData[i].lastOperator = 'dilate';
+            this.storedData[i].elem.setAttribute('filter', null);
+          }
+          this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
+        }
+      }
+    }
+  }
+};
+
+MaskElement.prototype.getMaskelement = function () {
+  return this.maskElement;
+};
+
+MaskElement.prototype.createLayerSolidPath = function () {
+  var path = 'M0,0 ';
+  path += ' h' + this.globalData.compSize.w;
+  path += ' v' + this.globalData.compSize.h;
+  path += ' h-' + this.globalData.compSize.w;
+  path += ' v-' + this.globalData.compSize.h + ' ';
+  return path;
+};
+
+MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
+  var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  var i;
+  var len;
+  len = pathNodes._length;
+  for (i = 1; i < len; i += 1) {
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
+  }
+  // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+  if (pathNodes.c && len > 1) {
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  }
+  // pathNodes.__renderedString = pathString;
+
+  if (viewData.lastPath !== pathString) {
+    var pathShapeValue = '';
+    if (viewData.elem) {
+      if (pathNodes.c) {
+        pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
+      }
+      viewData.elem.setAttribute('d', pathShapeValue);
+    }
+    viewData.lastPath = pathString;
+  }
+};
+
+MaskElement.prototype.destroy = function () {
+  this.element = null;
+  this.globalData = null;
+  this.maskElement = null;
+  this.data = null;
+  this.masksProperties = null;
+};
+
+const filtersFactory = (function () {
+  var ob = {};
+  ob.createFilter = createFilter;
+  ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
+
+  function createFilter(filId, skipCoordinates) {
+    var fil = createNS('filter');
+    fil.setAttribute('id', filId);
+    if (skipCoordinates !== true) {
+      fil.setAttribute('filterUnits', 'objectBoundingBox');
+      fil.setAttribute('x', '0%');
+      fil.setAttribute('y', '0%');
+      fil.setAttribute('width', '100%');
+      fil.setAttribute('height', '100%');
+    }
+    return fil;
+  }
+
+  function createAlphaToLuminanceFilter() {
+    var feColorMatrix = createNS('feColorMatrix');
+    feColorMatrix.setAttribute('type', 'matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+    feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
+    return feColorMatrix;
+  }
+
+  return ob;
+}());
+
+const featureSupport = (function () {
+  var ob = {
+    maskType: true,
+    svgLumaHidden: true,
+    offscreenCanvas: typeof OffscreenCanvas !== 'undefined',
+  };
+  if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
+    ob.maskType = false;
+  }
+  if (/firefox/i.test(navigator.userAgent)) {
+    ob.svgLumaHidden = false;
+  }
+  return ob;
+}());
+
+var registeredEffects = {};
+var idPrefix = 'filter_result_';
+
+function SVGEffects(elem) {
+  var i;
+  var source = 'SourceGraphic';
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  var filId = createElementID();
+  var fil = filtersFactory.createFilter(filId, true);
+  var count = 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects[type]) {
+      var Effect = registeredEffects[type].effect;
+      filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
+      source = idPrefix + count;
+      if (registeredEffects[type].countsAsEffect) {
+        count += 1;
+      }
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (count) {
+    elem.globalData.defs.appendChild(fil);
+    elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+SVGEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect(id, effect, countsAsEffect) {
+  registeredEffects[id] = {
+    effect,
+    countsAsEffect,
+  };
+}
+
+function SVGBaseElement() {
+}
+
+SVGBaseElement.prototype = {
+  initRendererElement: function () {
+    this.layerElement = createNS('g');
+  },
+  createContainerElements: function () {
+    this.matteElement = createNS('g');
+    this.transformedElement = this.layerElement;
+    this.maskedElement = this.layerElement;
+    this._sizeChanged = false;
+    var layerElementParent = null;
+    // If this layer acts as a mask for the following layer
+    if (this.data.td) {
+      this.matteMasks = {};
+      var gg = createNS('g');
+      gg.setAttribute('id', this.layerId);
+      gg.appendChild(this.layerElement);
+      layerElementParent = gg;
+      this.globalData.defs.appendChild(gg);
+    } else if (this.data.tt) {
+      this.matteElement.appendChild(this.layerElement);
+      layerElementParent = this.matteElement;
+      this.baseElement = this.matteElement;
+    } else {
+      this.baseElement = this.layerElement;
+    }
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
+    if (this.data.ty === 0 && !this.data.hd) {
+      var cp = createNS('clipPath');
+      var pt = createNS('path');
+      pt.setAttribute('d', 'M0,0 L' + this.data.w + ',0 L' + this.data.w + ',' + this.data.h + ' L0,' + this.data.h + 'z');
+      var clipId = createElementID();
+      cp.setAttribute('id', clipId);
+      cp.appendChild(pt);
+      this.globalData.defs.appendChild(cp);
+
+      if (this.checkMasks()) {
+        var cpGroup = createNS('g');
+        cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+        cpGroup.appendChild(this.layerElement);
+        this.transformedElement = cpGroup;
+        if (layerElementParent) {
+          layerElementParent.appendChild(this.transformedElement);
+        } else {
+          this.baseElement = this.transformedElement;
+        }
+      } else {
+        this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+      }
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    if (this.finalTransform._localMatMdf) {
+      this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
+    }
+    if (this.finalTransform._opMdf) {
+      this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
+    }
+  },
+  destroyBaseElement: function () {
+    this.layerElement = null;
+    this.matteElement = null;
+    this.maskManager.destroy();
+  },
+  getBaseElement: function () {
+    if (this.data.hd) {
+      return null;
+    }
+    return this.baseElement;
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+    this.renderableEffectsManager = new SVGEffects(this);
+    this.searchEffectTransforms();
+  },
+  getMatte: function (matteType) {
+    // This should not be a common case. But for backward compatibility, we'll create the matte object.
+    // It solves animations that have two consecutive layers marked as matte masks.
+    // Which is an undefined behavior in AE.
+    if (!this.matteMasks) {
+      this.matteMasks = {};
+    }
+    if (!this.matteMasks[matteType]) {
+      var id = this.layerId + '_' + matteType;
+      var filId;
+      var fil;
+      var useElement;
+      var gg;
+      if (matteType === 1 || matteType === 3) {
+        var masker = createNS('mask');
+        masker.setAttribute('id', id);
+        masker.setAttribute('mask-type', matteType === 3 ? 'luminance' : 'alpha');
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        masker.appendChild(useElement);
+        this.globalData.defs.appendChild(masker);
+        if (!featureSupport.maskType && matteType === 1) {
+          masker.setAttribute('mask-type', 'luminance');
+          filId = createElementID();
+          fil = filtersFactory.createFilter(filId);
+          this.globalData.defs.appendChild(fil);
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          gg.appendChild(useElement);
+          masker.appendChild(gg);
+          gg.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        }
+      } else if (matteType === 2) {
+        var maskGroup = createNS('mask');
+        maskGroup.setAttribute('id', id);
+        maskGroup.setAttribute('mask-type', 'alpha');
+        var maskGrouper = createNS('g');
+        maskGroup.appendChild(maskGrouper);
+        filId = createElementID();
+        fil = filtersFactory.createFilter(filId);
+        /// /
+        var feCTr = createNS('feComponentTransfer');
+        feCTr.setAttribute('in', 'SourceGraphic');
+        fil.appendChild(feCTr);
+        var feFunc = createNS('feFuncA');
+        feFunc.setAttribute('type', 'table');
+        feFunc.setAttribute('tableValues', '1.0 0.0');
+        feCTr.appendChild(feFunc);
+        /// /
+        this.globalData.defs.appendChild(fil);
+        var alphaRect = createNS('rect');
+        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');
+        alphaRect.setAttribute('opacity', '0');
+        maskGrouper.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        maskGrouper.appendChild(alphaRect);
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        maskGrouper.appendChild(useElement);
+        if (!featureSupport.maskType) {
+          maskGroup.setAttribute('mask-type', 'luminance');
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          maskGrouper.appendChild(alphaRect);
+          gg.appendChild(this.layerElement);
+          maskGrouper.appendChild(gg);
+        }
+        this.globalData.defs.appendChild(maskGroup);
+      }
+      this.matteMasks[matteType] = id;
+    }
+    return this.matteMasks[matteType];
+  },
+  setMatte: function (id) {
+    if (!this.matteElement) {
+      return;
+    }
+    this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+  },
+};
+
+/**
+ * @file
+ * Handles AE's layer parenting property.
+ *
+ */
+
+function HierarchyElement() {}
+
+HierarchyElement.prototype = {
+  /**
+     * @function
+     * Initializes hierarchy properties
+     *
+     */
+  initHierarchy: function () {
+    // element's parent list
+    this.hierarchy = [];
+    // if element is parent of another layer _isParent will be true
+    this._isParent = false;
+    this.checkParenting();
+  },
+  /**
+     * @function
+     * Sets layer's hierarchy.
+     * @param {array} hierarch
+     * layer's parent list
+     *
+     */
+  setHierarchy: function (hierarchy) {
+    this.hierarchy = hierarchy;
+  },
+  /**
+     * @function
+     * Sets layer as parent.
+     *
+     */
+  setAsParent: function () {
+    this._isParent = true;
+  },
+  /**
+     * @function
+     * Searches layer's parenting chain
+     *
+     */
+  checkParenting: function () {
+    if (this.data.parent !== undefined) {
+      this.comp.buildElementParenting(this, this.data.parent, []);
+    }
+  },
+};
+
+function RenderableDOMElement() {}
+
+(function () {
+  var _prototype = {
+    initElement: function (data, globalData, comp) {
+      this.initFrame();
+      this.initBaseData(data, globalData, comp);
+      this.initTransform(data, globalData, comp);
+      this.initHierarchy();
+      this.initRenderable();
+      this.initRendererElement();
+      this.createContainerElements();
+      this.createRenderableComponents();
+      this.createContent();
+      this.hide();
+    },
+    hide: function () {
+      // console.log('HIDE', this);
+      if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+        var elem = this.baseElement || this.layerElement;
+        elem.style.display = 'none';
+        this.hidden = true;
+      }
+    },
+    show: function () {
+      // console.log('SHOW', this);
+      if (this.isInRange && !this.isTransparent) {
+        if (!this.data.hd) {
+          var elem = this.baseElement || this.layerElement;
+          elem.style.display = 'block';
+        }
+        this.hidden = false;
+        this._isFirstFrame = true;
+      }
+    },
+    renderFrame: function () {
+      // If it is exported as hidden (data.hd === true) no need to render
+      // If it is not visible no need to render
+      if (this.data.hd || this.hidden) {
+        return;
+      }
+      this.renderTransform();
+      this.renderRenderable();
+      this.renderLocalTransform();
+      this.renderElement();
+      this.renderInnerContent();
+      if (this._isFirstFrame) {
+        this._isFirstFrame = false;
+      }
+    },
+    renderInnerContent: function () {},
+    prepareFrame: function (num) {
+      this._mdf = false;
+      this.prepareRenderableFrame(num);
+      this.prepareProperties(num, this.isInRange);
+      this.checkTransparency();
+    },
+    destroy: function () {
+      this.innerElem = null;
+      this.destroyBaseElement();
+    },
+  };
+  extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement);
+}());
+
+function IImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  if (this.assetData && this.assetData.sid) {
+    this.assetData = globalData.slotManager.getProp(this.assetData);
+  }
+  this.initElement(data, globalData, comp);
+  this.sourceRect = {
+    top: 0, left: 0, width: this.assetData.w, height: this.assetData.h,
+  };
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
+
+IImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+
+  this.innerElem = createNS('image');
+  this.innerElem.setAttribute('width', this.assetData.w + 'px');
+  this.innerElem.setAttribute('height', this.assetData.h + 'px');
+  this.innerElem.setAttribute('preserveAspectRatio', this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio);
+  this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+
+  this.layerElement.appendChild(this.innerElem);
+};
+
+IImageElement.prototype.sourceRectAtTime = function () {
+  return this.sourceRect;
+};
+
+function ProcessedElement(element, position) {
+  this.elem = element;
+  this.pos = position;
+}
+
+function IShapeElement() {
+}
+
+IShapeElement.prototype = {
+  addShapeToModifiers: function (data) {
+    var i;
+    var len = this.shapeModifiers.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapeModifiers[i].addShape(data);
+    }
+  },
+  isShapeInAnimatedModifiers: function (data) {
+    var i = 0;
+    var len = this.shapeModifiers.length;
+    while (i < len) {
+      if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
+        return true;
+      }
+    }
+    return false;
+  },
+  renderModifiers: function () {
+    if (!this.shapeModifiers.length) {
+      return;
+    }
+    var i;
+    var len = this.shapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].sh.reset();
+    }
+
+    len = this.shapeModifiers.length;
+    var shouldBreakProcess;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+      // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+      // TODO: find a better solution for this
+      if (shouldBreakProcess) {
+        break;
+      }
+    }
+  },
+
+  searchProcessedElement: function (elem) {
+    var elements = this.processedElements;
+    var i = 0;
+    var len = elements.length;
+    while (i < len) {
+      if (elements[i].elem === elem) {
+        return elements[i].pos;
+      }
+      i += 1;
+    }
+    return 0;
+  },
+  addProcessedElement: function (elem, pos) {
+    var elements = this.processedElements;
+    var i = elements.length;
+    while (i) {
+      i -= 1;
+      if (elements[i].elem === elem) {
+        elements[i].pos = pos;
+        return;
+      }
+    }
+    elements.push(new ProcessedElement(elem, pos));
+  },
+  prepareFrame: function (num) {
+    this.prepareRenderableFrame(num);
+    this.prepareProperties(num, this.isInRange);
+  },
+};
+
+const lineCapEnum = {
+  1: 'butt',
+  2: 'round',
+  3: 'square',
+};
+
+const lineJoinEnum = {
+  1: 'miter',
+  2: 'round',
+  3: 'bevel',
+};
+
+function SVGShapeData(transformers, level, shape) {
+  this.caches = [];
+  this.styles = [];
+  this.transformers = transformers;
+  this.lStr = '';
+  this.sh = shape;
+  this.lvl = level;
+  // TODO find if there are some cases where _isAnimated can be false.
+  // For now, since shapes add up with other shapes. They have to be calculated every time.
+  // One way of finding out is checking if all styles associated to this shape depend only of this shape
+  this._isAnimated = !!shape.k;
+  // TODO: commenting this for now since all shapes are animated
+  var i = 0;
+  var len = transformers.length;
+  while (i < len) {
+    if (transformers[i].mProps.dynamicProperties.length) {
+      this._isAnimated = true;
+      break;
+    }
+    i += 1;
+  }
+}
+
+SVGShapeData.prototype.setAsAnimated = function () {
+  this._isAnimated = true;
+};
+
+function SVGStyleData(data, level) {
+  this.data = data;
+  this.type = data.ty;
+  this.d = '';
+  this.lvl = level;
+  this._mdf = false;
+  this.closed = data.hd === true;
+  this.pElem = createNS('path');
+  this.msElem = null;
+}
+
+SVGStyleData.prototype.reset = function () {
+  this.d = '';
+  this._mdf = false;
+};
+
+function DashProperty(elem, data, renderer, container) {
+  this.elem = elem;
+  this.frameId = -1;
+  this.dataProps = createSizedArray(data.length);
+  this.renderer = renderer;
+  this.k = false;
+  this.dashStr = '';
+  this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0);
+  this.dashoffset = createTypedArray('float32', 1);
+  this.initDynamicPropertyContainer(container);
+  var i;
+  var len = data.length || 0;
+  var prop;
+  for (i = 0; i < len; i += 1) {
+    prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
+    this.k = prop.k || this.k;
+    this.dataProps[i] = { n: data[i].n, p: prop };
+  }
+  if (!this.k) {
+    this.getValue(true);
+  }
+  this._isAnimated = this.k;
+}
+
+DashProperty.prototype.getValue = function (forceRender) {
+  if (this.elem.globalData.frameId === this.frameId && !forceRender) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+  this._mdf = this._mdf || forceRender;
+  if (this._mdf) {
+    var i = 0;
+    var len = this.dataProps.length;
+    if (this.renderer === 'svg') {
+      this.dashStr = '';
+    }
+    for (i = 0; i < len; i += 1) {
+      if (this.dataProps[i].n !== 'o') {
+        if (this.renderer === 'svg') {
+          this.dashStr += ' ' + this.dataProps[i].p.v;
+        } else {
+          this.dashArray[i] = this.dataProps[i].p.v;
+        }
+      } else {
+        this.dashoffset[0] = this.dataProps[i].p.v;
+      }
+    }
+  }
+};
+extendPrototype([DynamicPropertyContainer], DashProperty);
+
+function SVGStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
+
+function SVGFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
+
+function SVGNoStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
+
+function GradientProperty(elem, data, container) {
+  this.data = data;
+  this.c = createTypedArray('uint8c', data.p * 4);
+  var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p * 4) : data.k.k.length - data.p * 4;
+  this.o = createTypedArray('float32', cLength);
+  this._cmdf = false;
+  this._omdf = false;
+  this._collapsable = this.checkCollapsable();
+  this._hasOpacity = cLength;
+  this.initDynamicPropertyContainer(container);
+  this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this);
+  this.k = this.prop.k;
+  this.getValue(true);
+}
+
+GradientProperty.prototype.comparePoints = function (values, points) {
+  var i = 0;
+  var len = this.o.length / 2;
+  var diff;
+  while (i < len) {
+    diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
+    if (diff > 0.01) {
+      return false;
+    }
+    i += 1;
+  }
+  return true;
+};
+
+GradientProperty.prototype.checkCollapsable = function () {
+  if (this.o.length / 2 !== this.c.length / 4) {
+    return false;
+  }
+  if (this.data.k.k[0].s) {
+    var i = 0;
+    var len = this.data.k.k.length;
+    while (i < len) {
+      if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
+        return false;
+      }
+      i += 1;
+    }
+  } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
+    return false;
+  }
+  return true;
+};
+
+GradientProperty.prototype.getValue = function (forceRender) {
+  this.prop.getValue();
+  this._mdf = false;
+  this._cmdf = false;
+  this._omdf = false;
+  if (this.prop._mdf || forceRender) {
+    var i;
+    var len = this.data.p * 4;
+    var mult;
+    var val;
+    for (i = 0; i < len; i += 1) {
+      mult = i % 4 === 0 ? 100 : 255;
+      val = Math.round(this.prop.v[i] * mult);
+      if (this.c[i] !== val) {
+        this.c[i] = val;
+        this._cmdf = !forceRender;
+      }
+    }
+    if (this.o.length) {
+      len = this.prop.v.length;
+      for (i = this.data.p * 4; i < len; i += 1) {
+        mult = i % 2 === 0 ? 100 : 1;
+        val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
+        if (this.o[i - this.data.p * 4] !== val) {
+          this.o[i - this.data.p * 4] = val;
+          this._omdf = !forceRender;
+        }
+      }
+    }
+    this._mdf = !forceRender;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], GradientProperty);
+
+function SVGGradientFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.initGradientData(elem, data, styleOb);
+}
+
+SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 1, null, this);
+  this.h = PropertyFactory.getProp(elem, data.h || { k: 0 }, 0, 0.01, this);
+  this.a = PropertyFactory.getProp(elem, data.a || { k: 0 }, 0, degToRads, this);
+  this.g = new GradientProperty(elem, data.g, this);
+  this.style = styleOb;
+  this.stops = [];
+  this.setGradientData(styleOb.pElem, data);
+  this.setGradientOpacity(data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+};
+
+SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
+  var gradientId = createElementID();
+  var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+  gfill.setAttribute('id', gradientId);
+  gfill.setAttribute('spreadMethod', 'pad');
+  gfill.setAttribute('gradientUnits', 'userSpaceOnUse');
+  var stops = [];
+  var stop;
+  var j;
+  var jLen;
+  jLen = data.g.p * 4;
+  for (j = 0; j < jLen; j += 4) {
+    stop = createNS('stop');
+    gfill.appendChild(stop);
+    stops.push(stop);
+  }
+  pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
+  this.gf = gfill;
+  this.cst = stops;
+};
+
+SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
+  if (this.g._hasOpacity && !this.g._collapsable) {
+    var stop;
+    var j;
+    var jLen;
+    var mask = createNS('mask');
+    var maskElement = createNS('path');
+    mask.appendChild(maskElement);
+    var opacityId = createElementID();
+    var maskId = createElementID();
+    mask.setAttribute('id', maskId);
+    var opFill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+    opFill.setAttribute('id', opacityId);
+    opFill.setAttribute('spreadMethod', 'pad');
+    opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
+    jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
+    var stops = this.stops;
+    for (j = data.g.p * 4; j < jLen; j += 2) {
+      stop = createNS('stop');
+      stop.setAttribute('stop-color', 'rgb(255,255,255)');
+      opFill.appendChild(stop);
+      stops.push(stop);
+    }
+    maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
+    this.maskId = maskId;
+    styleOb.msElem = maskElement;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
+
+function SVGGradientStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.initGradientData(elem, data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
+
+function ShapeGroupData() {
+  this.it = [];
+  this.prevViewData = [];
+  this.gr = createNS('g');
+}
+
+function SVGTransformData(mProps, op, container) {
+  this.transform = {
+    mProps: mProps,
+    op: op,
+    container: container,
+  };
+  this.elements = [];
+  this._isAnimated = this.transform.mProps.dynamicProperties.length || this.transform.op.effectsSequence.length;
+}
+
+const buildShapeString = function (pathNodes, length, closed, mat) {
+  if (length === 0) {
+    return '';
+  }
+  var _o = pathNodes.o;
+  var _i = pathNodes.i;
+  var _v = pathNodes.v;
+  var i;
+  var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+  for (i = 1; i < length; i += 1) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
+  }
+  if (closed && length) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+    shapeString += 'z';
+  }
+  return shapeString;
+};
+
+const SVGElementsRenderer = (function () {
+  var _identityMatrix = new Matrix();
+  var _matrixHelper = new Matrix();
+
+  var ob = {
+    createRenderFunction: createRenderFunction,
+  };
+
+  function createRenderFunction(data) {
+    switch (data.ty) {
+      case 'fl':
+        return renderFill;
+      case 'gf':
+        return renderGradient;
+      case 'gs':
+        return renderGradientStroke;
+      case 'st':
+        return renderStroke;
+      case 'sh':
+      case 'el':
+      case 'rc':
+      case 'sr':
+        return renderPath;
+      case 'tr':
+        return renderContentTransform;
+      case 'no':
+        return renderNoop;
+      default:
+        return null;
+    }
+  }
+
+  function renderContentTransform(styleData, itemData, isFirstFrame) {
+    if (isFirstFrame || itemData.transform.op._mdf) {
+      itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
+    }
+    if (isFirstFrame || itemData.transform.mProps._mdf) {
+      itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
+    }
+  }
+
+  function renderNoop() {
+
+  }
+
+  function renderPath(styleData, itemData, isFirstFrame) {
+    var j;
+    var jLen;
+    var pathStringTransformed;
+    var redraw;
+    var pathNodes;
+    var l;
+    var lLen = itemData.styles.length;
+    var lvl = itemData.lvl;
+    var paths;
+    var mat;
+    var iterations;
+    var k;
+    for (l = 0; l < lLen; l += 1) {
+      redraw = itemData.sh._mdf || isFirstFrame;
+      if (itemData.styles[l].lvl < lvl) {
+        mat = _matrixHelper.reset();
+        iterations = lvl - itemData.styles[l].lvl;
+        k = itemData.transformers.length - 1;
+        while (!redraw && iterations > 0) {
+          redraw = itemData.transformers[k].mProps._mdf || redraw;
+          iterations -= 1;
+          k -= 1;
+        }
+        if (redraw) {
+          iterations = lvl - itemData.styles[l].lvl;
+          k = itemData.transformers.length - 1;
+          while (iterations > 0) {
+            mat.multiply(itemData.transformers[k].mProps.v);
+            iterations -= 1;
+            k -= 1;
+          }
+        }
+      } else {
+        mat = _identityMatrix;
+      }
+      paths = itemData.sh.paths;
+      jLen = paths._length;
+      if (redraw) {
+        pathStringTransformed = '';
+        for (j = 0; j < jLen; j += 1) {
+          pathNodes = paths.shapes[j];
+          if (pathNodes && pathNodes._length) {
+            pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
+          }
+        }
+        itemData.caches[l] = pathStringTransformed;
+      } else {
+        pathStringTransformed = itemData.caches[l];
+      }
+      itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
+      itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
+    }
+  }
+
+  function renderFill(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+
+    if (itemData.c._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
+    }
+  }
+
+  function renderGradientStroke(styleData, itemData, isFirstFrame) {
+    renderGradient(styleData, itemData, isFirstFrame);
+    renderStroke(styleData, itemData, isFirstFrame);
+  }
+
+  function renderGradient(styleData, itemData, isFirstFrame) {
+    var gfill = itemData.gf;
+    var hasOpacity = itemData.g._hasOpacity;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+
+    if (itemData.o._mdf || isFirstFrame) {
+      var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
+      itemData.style.pElem.setAttribute(attr, itemData.o.v);
+    }
+    if (itemData.s._mdf || isFirstFrame) {
+      var attr1 = styleData.t === 1 ? 'x1' : 'cx';
+      var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
+      gfill.setAttribute(attr1, pt1[0]);
+      gfill.setAttribute(attr2, pt1[1]);
+      if (hasOpacity && !itemData.g._collapsable) {
+        itemData.of.setAttribute(attr1, pt1[0]);
+        itemData.of.setAttribute(attr2, pt1[1]);
+      }
+    }
+    var stops;
+    var i;
+    var len;
+    var stop;
+    if (itemData.g._cmdf || isFirstFrame) {
+      stops = itemData.cst;
+      var cValues = itemData.g.c;
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        stop.setAttribute('offset', cValues[i * 4] + '%');
+        stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
+      }
+    }
+    if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
+      var oValues = itemData.g.o;
+      if (itemData.g._collapsable) {
+        stops = itemData.cst;
+      } else {
+        stops = itemData.ost;
+      }
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        if (!itemData.g._collapsable) {
+          stop.setAttribute('offset', oValues[i * 2] + '%');
+        }
+        stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
+      }
+    }
+    if (styleData.t === 1) {
+      if (itemData.e._mdf || isFirstFrame) {
+        gfill.setAttribute('x2', pt2[0]);
+        gfill.setAttribute('y2', pt2[1]);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('x2', pt2[0]);
+          itemData.of.setAttribute('y2', pt2[1]);
+        }
+      }
+    } else {
+      var rad;
+      if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
+        rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        gfill.setAttribute('r', rad);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('r', rad);
+        }
+      }
+      if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (!rad) {
+          rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        }
+        var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+        var percent = itemData.h.v;
+        if (percent >= 1) {
+          percent = 0.99;
+        } else if (percent <= -1) {
+          percent = -0.99;
+        }
+        var dist = rad * percent;
+        var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+        var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+        gfill.setAttribute('fx', x);
+        gfill.setAttribute('fy', y);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('fx', x);
+          itemData.of.setAttribute('fy', y);
+        }
+      }
+      // gfill.setAttribute('fy','200');
+    }
+  }
+
+  function renderStroke(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+    var d = itemData.d;
+    if (d && (d._mdf || isFirstFrame) && d.dashStr) {
+      styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
+      styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
+    }
+    if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
+      styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
+    }
+    if (itemData.w._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
+      if (styleElem.msElem) {
+        styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
+      }
+    }
+  }
+
+  return ob;
+}());
+
+function SVGShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
+
+SVGShapeElement.prototype.initSecondaryElement = function () {
+};
+
+SVGShapeElement.prototype.identityMatrix = new Matrix();
+
+SVGShapeElement.prototype.buildExpressionInterface = function () {};
+
+SVGShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+};
+
+/*
+This method searches for multiple shapes that affect a single element and one of them is animated
+*/
+SVGShapeElement.prototype.filterUniqueShapes = function () {
+  var i;
+  var len = this.shapes.length;
+  var shape;
+  var j;
+  var jLen = this.stylesList.length;
+  var style;
+  var tempShapes = [];
+  var areAnimated = false;
+  for (j = 0; j < jLen; j += 1) {
+    style = this.stylesList[j];
+    areAnimated = false;
+    tempShapes.length = 0;
+    for (i = 0; i < len; i += 1) {
+      shape = this.shapes[i];
+      if (shape.styles.indexOf(style) !== -1) {
+        tempShapes.push(shape);
+        areAnimated = shape._isAnimated || areAnimated;
+      }
+    }
+    if (tempShapes.length > 1 && areAnimated) {
+      this.setShapesAsAnimated(tempShapes);
+    }
+  }
+};
+
+SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
+  var i;
+  var len = shapes.length;
+  for (i = 0; i < len; i += 1) {
+    shapes[i].setAsAnimated();
+  }
+};
+
+SVGShapeElement.prototype.createStyleElement = function (data, level) {
+  // TODO: prevent drawing of hidden styles
+  var elementData;
+  var styleOb = new SVGStyleData(data, level);
+
+  var pathElement = styleOb.pElem;
+  if (data.ty === 'st') {
+    elementData = new SVGStrokeStyleData(this, data, styleOb);
+  } else if (data.ty === 'fl') {
+    elementData = new SVGFillStyleData(this, data, styleOb);
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
+    elementData = new GradientConstructor(this, data, styleOb);
+    this.globalData.defs.appendChild(elementData.gf);
+    if (elementData.maskId) {
+      this.globalData.defs.appendChild(elementData.ms);
+      this.globalData.defs.appendChild(elementData.of);
+      pathElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + elementData.maskId + ')');
+    }
+  } else if (data.ty === 'no') {
+    elementData = new SVGNoStyleData(this, data, styleOb);
+  }
+
+  if (data.ty === 'st' || data.ty === 'gs') {
+    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);
+    }
+  }
+
+  if (data.r === 2) {
+    pathElement.setAttribute('fill-rule', 'evenodd');
+  }
+
+  if (data.ln) {
+    pathElement.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    pathElement.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  this.stylesList.push(styleOb);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createGroupElement = function (data) {
+  var elementData = new ShapeGroupData();
+  if (data.ln) {
+    elementData.gr.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    elementData.gr.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  return elementData;
+};
+
+SVGShapeElement.prototype.createTransformElement = function (data, container) {
+  var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
+  var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
+  var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
+  var i = 0;
+  var len = this.animatedContents.length;
+  while (i < len) {
+    if (this.animatedContents[i].element === element) {
+      return;
+    }
+    i += 1;
+  }
+  this.animatedContents.push({
+    fn: SVGElementsRenderer.createRenderFunction(data),
+    element: element,
+    data: data,
+  });
+};
+
+SVGShapeElement.prototype.setElementStyles = function (elementData) {
+  var arr = elementData.styles;
+  var j;
+  var jLen = this.stylesList.length;
+  for (j = 0; j < jLen; j += 1) {
+    if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
+      arr.push(this.stylesList[j]);
+    }
+  }
+};
+
+SVGShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+};
+
+SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
+  var ownTransformers = [].concat(transformers);
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var currentTransform;
+  var modifier;
+  var processedPos;
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._render = render;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], level);
+      } else {
+        itemsData[i].style.closed = arr[i].hd;
+      }
+      if (arr[i]._render) {
+        if (itemsData[i].style.pElem.parentNode !== container) {
+          container.appendChild(itemsData[i].style.pElem);
+        }
+      }
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
+      if (arr[i]._render) {
+        if (itemsData[i].gr.parentNode !== container) {
+          container.appendChild(itemsData[i].gr);
+        }
+      }
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        itemsData[i] = this.createTransformElement(arr[i], container);
+      }
+      currentTransform = itemsData[i].transform;
+      ownTransformers.push(currentTransform);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
+      }
+      this.setElementStyles(itemsData[i]);
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        render = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  len = ownStyles.length;
+  for (i = 0; i < len; i += 1) {
+    ownStyles[i].closed = true;
+  }
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+SVGShapeElement.prototype.renderInnerContent = function () {
+  this.renderModifiers();
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    this.stylesList[i].reset();
+  }
+  this.renderShape();
+  for (i = 0; i < len; i += 1) {
+    if (this.stylesList[i]._mdf || this._isFirstFrame) {
+      if (this.stylesList[i].msElem) {
+        this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+        // Adding M0 0 fixes same mask bug on all browsers
+        this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
+      }
+      this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
+    }
+  }
+};
+
+SVGShapeElement.prototype.renderShape = function () {
+  var i;
+  var len = this.animatedContents.length;
+  var animatedContent;
+  for (i = 0; i < len; i += 1) {
+    animatedContent = this.animatedContents[i];
+    if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
+      animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
+    }
+  }
+};
+
+SVGShapeElement.prototype.destroy = function () {
+  this.destroyBaseElement();
+  this.shapesData = null;
+  this.itemsData = null;
+};
+
+function LetterProps(o, sw, sc, fc, m, p) {
+  this.o = o;
+  this.sw = sw;
+  this.sc = sc;
+  this.fc = fc;
+  this.m = m;
+  this.p = p;
+  this._mdf = {
+    o: true,
+    sw: !!sw,
+    sc: !!sc,
+    fc: !!fc,
+    m: true,
+    p: true,
+  };
+}
+
+LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
+  this._mdf.o = false;
+  this._mdf.sw = false;
+  this._mdf.sc = false;
+  this._mdf.fc = false;
+  this._mdf.m = false;
+  this._mdf.p = false;
+  var updated = false;
+
+  if (this.o !== o) {
+    this.o = o;
+    this._mdf.o = true;
+    updated = true;
+  }
+  if (this.sw !== sw) {
+    this.sw = sw;
+    this._mdf.sw = true;
+    updated = true;
+  }
+  if (this.sc !== sc) {
+    this.sc = sc;
+    this._mdf.sc = true;
+    updated = true;
+  }
+  if (this.fc !== fc) {
+    this.fc = fc;
+    this._mdf.fc = true;
+    updated = true;
+  }
+  if (this.m !== m) {
+    this.m = m;
+    this._mdf.m = true;
+    updated = true;
+  }
+  if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
+    this.p = p;
+    this._mdf.p = true;
+    updated = true;
+  }
+  return updated;
+};
+
+function TextProperty(elem, data) {
+  this._frameId = initialDefaultFrame;
+  this.pv = '';
+  this.v = '';
+  this.kf = false;
+  this._isFirstFrame = true;
+  this._mdf = false;
+  if (data.d && data.d.sid) {
+    data.d = elem.globalData.slotManager.getProp(data.d);
+  }
+  this.data = data;
+  this.elem = elem;
+  this.comp = this.elem.comp;
+  this.keysIndex = 0;
+  this.canResize = false;
+  this.minimumFontSize = 1;
+  this.effectsSequence = [];
+  this.currentData = {
+    ascent: 0,
+    boxWidth: this.defaultBoxWidth,
+    f: '',
+    fStyle: '',
+    fWeight: '',
+    fc: '',
+    j: '',
+    justifyOffset: '',
+    l: [],
+    lh: 0,
+    lineWidths: [],
+    ls: '',
+    of: '',
+    s: '',
+    sc: '',
+    sw: 0,
+    t: 0,
+    tr: 0,
+    sz: 0,
+    ps: null,
+    fillColorAnim: false,
+    strokeColorAnim: false,
+    strokeWidthAnim: false,
+    yOffset: 0,
+    finalSize: 0,
+    finalText: [],
+    finalLineHeight: 0,
+    __complete: false,
+
+  };
+  this.copyData(this.currentData, this.data.d.k[0].s);
+
+  if (!this.searchProperty()) {
+    this.completeTextData(this.currentData);
+  }
+}
+
+TextProperty.prototype.defaultBoxWidth = [0, 0];
+
+TextProperty.prototype.copyData = function (obj, data) {
+  for (var s in data) {
+    if (Object.prototype.hasOwnProperty.call(data, s)) {
+      obj[s] = data[s];
+    }
+  }
+  return obj;
+};
+
+TextProperty.prototype.setCurrentData = function (data) {
+  if (!data.__complete) {
+    this.completeTextData(data);
+  }
+  this.currentData = data;
+  this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
+  this._mdf = true;
+};
+
+TextProperty.prototype.searchProperty = function () {
+  return this.searchKeyframes();
+};
+
+TextProperty.prototype.searchKeyframes = function () {
+  this.kf = this.data.d.k.length > 1;
+  if (this.kf) {
+    this.addEffect(this.getKeyframeValue.bind(this));
+  }
+  return this.kf;
+};
+
+TextProperty.prototype.addEffect = function (effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.getValue = function (_finalValue) {
+  if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
+    return;
+  }
+  this.currentData.t = this.data.d.k[this.keysIndex].s.t;
+  var currentValue = this.currentData;
+  var currentIndex = this.keysIndex;
+  if (this.lock) {
+    this.setCurrentData(this.currentData);
+    return;
+  }
+  this.lock = true;
+  this._mdf = false;
+  var i; var
+    len = this.effectsSequence.length;
+  var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
+  for (i = 0; i < len; i += 1) {
+    // Checking if index changed to prevent creating a new object every time the expression updates.
+    if (currentIndex !== this.keysIndex) {
+      finalValue = this.effectsSequence[i](finalValue, finalValue.t);
+    } else {
+      finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
+    }
+  }
+  if (currentValue !== finalValue) {
+    this.setCurrentData(finalValue);
+  }
+  this.v = this.currentData;
+  this.pv = this.v;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+};
+
+TextProperty.prototype.getKeyframeValue = function () {
+  var textKeys = this.data.d.k;
+  var frameNum = this.elem.comp.renderedFrame;
+  var i = 0; var
+    len = textKeys.length;
+  while (i <= len - 1) {
+    if (i === len - 1 || textKeys[i + 1].t > frameNum) {
+      break;
+    }
+    i += 1;
+  }
+  if (this.keysIndex !== i) {
+    this.keysIndex = i;
+  }
+  return this.data.d.k[this.keysIndex].s;
+};
+
+TextProperty.prototype.buildFinalText = function (text) {
+  var charactersArray = [];
+  var i = 0;
+  var len = text.length;
+  var charCode;
+  var secondCharCode;
+  var shouldCombine = false;
+  var shouldCombineNext = false;
+  var currentChars = '';
+  while (i < len) {
+    shouldCombine = shouldCombineNext;
+    shouldCombineNext = false;
+    charCode = text.charCodeAt(i);
+    currentChars = text.charAt(i);
+    if (FontManager.isCombinedCharacter(charCode)) {
+      shouldCombine = true;
+      // It's a potential surrogate pair (this is the High surrogate)
+    } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+      if (FontManager.isRegionalFlag(text, i)) {
+        currentChars = text.substr(i, 14);
+      } else {
+        secondCharCode = text.charCodeAt(i + 1);
+        // It's a surrogate pair (this is the Low surrogate)
+        if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
+          if (FontManager.isModifier(charCode, secondCharCode)) {
+            currentChars = text.substr(i, 2);
+            shouldCombine = true;
+          } else if (FontManager.isFlagEmoji(text.substr(i, 4))) {
+            currentChars = text.substr(i, 4);
+          } else {
+            currentChars = text.substr(i, 2);
+          }
+        }
+      }
+    } else if (charCode > 0xDBFF) {
+      secondCharCode = text.charCodeAt(i + 1);
+      if (FontManager.isVariationSelector(charCode)) {
+        shouldCombine = true;
+      }
+    } else if (FontManager.isZeroWidthJoiner(charCode)) {
+      shouldCombine = true;
+      shouldCombineNext = true;
+    }
+    if (shouldCombine) {
+      charactersArray[charactersArray.length - 1] += currentChars;
+      shouldCombine = false;
+    } else {
+      charactersArray.push(currentChars);
+    }
+    i += currentChars.length;
+  }
+  return charactersArray;
+};
+
+TextProperty.prototype.completeTextData = function (documentData) {
+  documentData.__complete = true;
+  var fontManager = this.elem.globalData.fontManager;
+  var data = this.data;
+  var letters = [];
+  var i; var
+    len;
+  var newLineFlag; var index = 0; var
+    val;
+  var anchorGrouping = data.m.g;
+  var currentSize = 0; var currentPos = 0; var currentLine = 0; var
+    lineWidths = [];
+  var lineWidth = 0;
+  var maxLineWidth = 0;
+  var j; var
+    jLen;
+  var fontData = fontManager.getFontByName(documentData.f);
+  var charData; var
+    cLength = 0;
+
+  var fontProps = getFontProperties(fontData);
+  documentData.fWeight = fontProps.weight;
+  documentData.fStyle = fontProps.style;
+  documentData.finalSize = documentData.s;
+  documentData.finalText = this.buildFinalText(documentData.t);
+  len = documentData.finalText.length;
+  documentData.finalLineHeight = documentData.lh;
+  var trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+  var charCode;
+  if (documentData.sz) {
+    var flag = true;
+    var boxWidth = documentData.sz[0];
+    var boxHeight = documentData.sz[1];
+    var currentHeight; var
+      finalText;
+    while (flag) {
+      finalText = this.buildFinalText(documentData.t);
+      currentHeight = 0;
+      lineWidth = 0;
+      len = finalText.length;
+      trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+      var lastSpaceIndex = -1;
+      for (i = 0; i < len; i += 1) {
+        charCode = finalText[i].charCodeAt(0);
+        newLineFlag = false;
+        if (finalText[i] === ' ') {
+          lastSpaceIndex = i;
+        } else if (charCode === 13 || charCode === 3) {
+          lineWidth = 0;
+          newLineFlag = true;
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+        }
+        if (fontManager.chars) {
+          charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
+          cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+        } else {
+          // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
+          cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
+        }
+        if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
+          if (lastSpaceIndex === -1) {
+            len += 1;
+          } else {
+            i = lastSpaceIndex;
+          }
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+          finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+          // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
+          lastSpaceIndex = -1;
+          lineWidth = 0;
+        } else {
+          lineWidth += cLength;
+          lineWidth += trackingOffset;
+        }
+      }
+      currentHeight += (fontData.ascent * documentData.finalSize) / 100;
+      if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
+        documentData.finalSize -= 1;
+        documentData.finalLineHeight = (documentData.finalSize * documentData.lh) / documentData.s;
+      } else {
+        documentData.finalText = finalText;
+        len = documentData.finalText.length;
+        flag = false;
+      }
+    }
+  }
+  lineWidth = -trackingOffset;
+  cLength = 0;
+  var uncollapsedSpaces = 0;
+  var currentChar;
+  for (i = 0; i < len; i += 1) {
+    newLineFlag = false;
+    currentChar = documentData.finalText[i];
+    charCode = currentChar.charCodeAt(0);
+    if (charCode === 13 || charCode === 3) {
+      uncollapsedSpaces = 0;
+      lineWidths.push(lineWidth);
+      maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+      lineWidth = -2 * trackingOffset;
+      val = '';
+      newLineFlag = true;
+      currentLine += 1;
+    } else {
+      val = currentChar;
+    }
+    if (fontManager.chars) {
+      charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
+      cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+    } else {
+      // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
+      // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
+      cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
+    }
+
+    //
+    if (currentChar === ' ') {
+      uncollapsedSpaces += cLength + trackingOffset;
+    } else {
+      lineWidth += cLength + trackingOffset + uncollapsedSpaces;
+      uncollapsedSpaces = 0;
+    }
+    letters.push({
+      l: cLength, an: cLength, add: currentSize, n: newLineFlag, anIndexes: [], val: val, line: currentLine, animatorJustifyOffset: 0,
+    });
+    if (anchorGrouping == 2) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || val === ' ' || i === len - 1) {
+        if (val === '' || val === ' ') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        index += 1;
+        currentSize = 0;
+      }
+    } else if (anchorGrouping == 3) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || i === len - 1) {
+        if (val === '') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        currentSize = 0;
+        index += 1;
+      }
+    } else {
+      letters[index].ind = index;
+      letters[index].extra = 0;
+      index += 1;
+    }
+  }
+  documentData.l = letters;
+  maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+  lineWidths.push(lineWidth);
+  if (documentData.sz) {
+    documentData.boxWidth = documentData.sz[0];
+    documentData.justifyOffset = 0;
+  } else {
+    documentData.boxWidth = maxLineWidth;
+    switch (documentData.j) {
+      case 1:
+        documentData.justifyOffset = -documentData.boxWidth;
+        break;
+      case 2:
+        documentData.justifyOffset = -documentData.boxWidth / 2;
+        break;
+      default:
+        documentData.justifyOffset = 0;
+    }
+  }
+  documentData.lineWidths = lineWidths;
+
+  var animators = data.a; var animatorData; var
+    letterData;
+  jLen = animators.length;
+  var based; var ind; var
+    indexes = [];
+  for (j = 0; j < jLen; j += 1) {
+    animatorData = animators[j];
+    if (animatorData.a.sc) {
+      documentData.strokeColorAnim = true;
+    }
+    if (animatorData.a.sw) {
+      documentData.strokeWidthAnim = true;
+    }
+    if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
+      documentData.fillColorAnim = true;
+    }
+    ind = 0;
+    based = animatorData.s.b;
+    for (i = 0; i < len; i += 1) {
+      letterData = letters[i];
+      letterData.anIndexes[j] = ind;
+      if ((based == 1 && letterData.val !== '') || (based == 2 && letterData.val !== '' && letterData.val !== ' ') || (based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1)) || (based == 4 && (letterData.n || i == len - 1))) { // eslint-disable-line eqeqeq
+        if (animatorData.s.rn === 1) {
+          indexes.push(ind);
+        }
+        ind += 1;
+      }
+    }
+    data.a[j].s.totalChars = ind;
+    var currentInd = -1; var
+      newInd;
+    if (animatorData.s.rn === 1) {
+      for (i = 0; i < len; i += 1) {
+        letterData = letters[i];
+        if (currentInd != letterData.anIndexes[j]) { // eslint-disable-line eqeqeq
+          currentInd = letterData.anIndexes[j];
+          newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
+        }
+        letterData.anIndexes[j] = newInd;
+      }
+    }
+  }
+  documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
+  documentData.ls = documentData.ls || 0;
+  documentData.ascent = (fontData.ascent * documentData.finalSize) / 100;
+};
+
+TextProperty.prototype.updateDocumentData = function (newData, index) {
+  index = index === undefined ? this.keysIndex : index;
+  var dData = this.copyData({}, this.data.d.k[index].s);
+  dData = this.copyData(dData, newData);
+  this.data.d.k[index].s = dData;
+  this.recalculate(index);
+  this.setCurrentData(dData);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.recalculate = function (index) {
+  var dData = this.data.d.k[index].s;
+  dData.__complete = false;
+  this.keysIndex = 0;
+  this._isFirstFrame = true;
+  this.getValue(dData);
+};
+
+TextProperty.prototype.canResizeFont = function (_canResize) {
+  this.canResize = _canResize;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
+  this.minimumFontSize = Math.floor(_fontValue) || 1;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+const TextSelectorProp = (function () {
+  var max = Math.max;
+  var min = Math.min;
+  var floor = Math.floor;
+
+  function TextSelectorPropFactory(elem, data) {
+    this._currentTextLength = -1;
+    this.k = false;
+    this.data = data;
+    this.elem = elem;
+    this.comp = elem.comp;
+    this.finalS = 0;
+    this.finalE = 0;
+    this.initDynamicPropertyContainer(elem);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: 0 }, 0, 0, this);
+    if ('e' in data) {
+      this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
+    } else {
+      this.e = { v: 100 };
+    }
+    this.o = PropertyFactory.getProp(elem, data.o || { k: 0 }, 0, 0, this);
+    this.xe = PropertyFactory.getProp(elem, data.xe || { k: 0 }, 0, 0, this);
+    this.ne = PropertyFactory.getProp(elem, data.ne || { k: 0 }, 0, 0, this);
+    this.sm = PropertyFactory.getProp(elem, data.sm || { k: 100 }, 0, 0, this);
+    this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
+    if (!this.dynamicProperties.length) {
+      this.getValue();
+    }
+  }
+
+  TextSelectorPropFactory.prototype = {
+    getMult: function (ind) {
+      if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
+        this.getValue();
+      }
+      var x1 = 0;
+      var y1 = 0;
+      var x2 = 1;
+      var y2 = 1;
+      if (this.ne.v > 0) {
+        x1 = this.ne.v / 100.0;
+      } else {
+        y1 = -this.ne.v / 100.0;
+      }
+      if (this.xe.v > 0) {
+        x2 = 1.0 - this.xe.v / 100.0;
+      } else {
+        y2 = 1.0 + this.xe.v / 100.0;
+      }
+      var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
+
+      var mult = 0;
+      var s = this.finalS;
+      var e = this.finalE;
+      var type = this.data.sh;
+      if (type === 2) {
+        if (e === s) {
+          mult = ind >= e ? 1 : 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+        mult = easer(mult);
+      } else if (type === 3) {
+        if (e === s) {
+          mult = ind >= e ? 0 : 1;
+        } else {
+          mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+
+        mult = easer(mult);
+      } else if (type === 4) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+          if (mult < 0.5) {
+            mult *= 2;
+          } else {
+            mult = 1 - 2 * (mult - 0.5);
+          }
+        }
+        mult = easer(mult);
+      } else if (type === 5) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          var tot = e - s;
+          /* ind += 0.5;
+                    mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          var x = -tot / 2 + ind;
+          var a = tot / 2;
+          mult = Math.sqrt(1 - (x * x) / (a * a));
+        }
+        mult = easer(mult);
+      } else if (type === 6) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; // eslint-disable-line
+        }
+        mult = easer(mult);
+      } else {
+        if (ind >= floor(s)) {
+          if (ind - s < 0) {
+            mult = max(0, min(min(e, 1) - (s - ind), 1));
+          } else {
+            mult = max(0, min(e - ind, 1));
+          }
+        }
+        mult = easer(mult);
+      }
+      // Smoothness implementation.
+      // The smoothness represents a reduced range of the original [0; 1] range.
+      // if smoothness is 25%, the new range will be [0.375; 0.625]
+      // Steps are:
+      // - find the lower value of the new range (threshold)
+      // - if multiplier is smaller than that value, floor it to 0
+      // - if it is larger,
+      //     - subtract the threshold
+      //     - divide it by the smoothness (this will return the range to [0; 1])
+      // Note: If it doesn't work on some scenarios, consider applying it before the easer.
+      if (this.sm.v !== 100) {
+        var smoothness = this.sm.v * 0.01;
+        if (smoothness === 0) {
+          smoothness = 0.00000001;
+        }
+        var threshold = 0.5 - smoothness * 0.5;
+        if (mult < threshold) {
+          mult = 0;
+        } else {
+          mult = (mult - threshold) / smoothness;
+          if (mult > 1) {
+            mult = 1;
+          }
+        }
+      }
+      return mult * this.a.v;
+    },
+    getValue: function (newCharsFlag) {
+      this.iterateDynamicProperties();
+      this._mdf = newCharsFlag || this._mdf;
+      this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
+      if (newCharsFlag && this.data.r === 2) {
+        this.e.v = this._currentTextLength;
+      }
+      var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
+      var o = this.o.v / divisor;
+      var s = this.s.v / divisor + o;
+      var e = (this.e.v / divisor) + o;
+      if (s > e) {
+        var _s = s;
+        s = e;
+        e = _s;
+      }
+      this.finalS = s;
+      this.finalE = e;
+    },
+  };
+  extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
+
+  function getTextSelectorProp(elem, data, arr) {
+    return new TextSelectorPropFactory(elem, data, arr);
+  }
+
+  return {
+    getTextSelectorProp: getTextSelectorProp,
+  };
+}());
+
+function TextAnimatorDataProperty(elem, animatorProps, container) {
+  var defaultData = { propType: false };
+  var getProp = PropertyFactory.getProp;
+  var textAnimatorAnimatables = animatorProps.a;
+  this.a = {
+    r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData,
+    rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData,
+    ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData,
+    sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData,
+    sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData,
+    s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData,
+    a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData,
+    o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData,
+    p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData,
+    sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData,
+    sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData,
+    fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData,
+    fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData,
+    fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData,
+    fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData,
+    t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData,
+  };
+
+  this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container);
+  this.s.t = animatorProps.s.t;
+}
+
+function TextAnimatorProperty(textData, renderType, elem) {
+  this._isFirstFrame = true;
+  this._hasMaskedPath = false;
+  this._frameId = -1;
+  this._textData = textData;
+  this._renderType = renderType;
+  this._elem = elem;
+  this._animatorsData = createSizedArray(this._textData.a.length);
+  this._pathData = {};
+  this._moreOptions = {
+    alignment: {},
+  };
+  this.renderedLetters = [];
+  this.lettersChangedFlag = false;
+  this.initDynamicPropertyContainer(elem);
+}
+
+TextAnimatorProperty.prototype.searchProperties = function () {
+  var i;
+  var len = this._textData.a.length;
+  var animatorProps;
+  var getProp = PropertyFactory.getProp;
+  for (i = 0; i < len; i += 1) {
+    animatorProps = this._textData.a[i];
+    this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
+  }
+  if (this._textData.p && 'm' in this._textData.p) {
+    this._pathData = {
+      a: getProp(this._elem, this._textData.p.a, 0, 0, this),
+      f: getProp(this._elem, this._textData.p.f, 0, 0, this),
+      l: getProp(this._elem, this._textData.p.l, 0, 0, this),
+      r: getProp(this._elem, this._textData.p.r, 0, 0, this),
+      p: getProp(this._elem, this._textData.p.p, 0, 0, this),
+      m: this._elem.maskManager.getMaskProperty(this._textData.p.m),
+    };
+    this._hasMaskedPath = true;
+  } else {
+    this._hasMaskedPath = false;
+  }
+  this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
+};
+
+TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
+  this.lettersChangedFlag = lettersChangedFlag;
+  if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
+    return;
+  }
+  this._isFirstFrame = false;
+  var alignment = this._moreOptions.alignment.v;
+  var animators = this._animatorsData;
+  var textData = this._textData;
+  var matrixHelper = this.mHelper;
+  var renderType = this._renderType;
+  var renderedLettersCount = this.renderedLetters.length;
+  var xPos;
+  var yPos;
+  var i;
+  var len;
+  var letters = documentData.l;
+  var pathInfo;
+  var currentLength;
+  var currentPoint;
+  var segmentLength;
+  var flag;
+  var pointInd;
+  var segmentInd;
+  var prevPoint;
+  var points;
+  var segments;
+  var partialLength;
+  var totalLength;
+  var perc;
+  var tanAngle;
+  var mask;
+  if (this._hasMaskedPath) {
+    mask = this._pathData.m;
+    if (!this._pathData.n || this._pathData._mdf) {
+      var paths = mask.v;
+      if (this._pathData.r.v) {
+        paths = paths.reverse();
+      }
+      // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
+      pathInfo = {
+        tLength: 0,
+        segments: [],
+      };
+      len = paths._length - 1;
+      var bezierData;
+      totalLength = 0;
+      for (i = 0; i < len; i += 1) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[i + 1],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      i = len;
+      if (mask.v.c) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[0],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      this._pathData.pi = pathInfo;
+    }
+    pathInfo = this._pathData.pi;
+
+    currentLength = this._pathData.f.v;
+    segmentInd = 0;
+    pointInd = 1;
+    segmentLength = 0;
+    flag = true;
+    segments = pathInfo.segments;
+    if (currentLength < 0 && mask.v.c) {
+      if (pathInfo.tLength < Math.abs(currentLength)) {
+        currentLength = -Math.abs(currentLength) % pathInfo.tLength;
+      }
+      segmentInd = segments.length - 1;
+      points = segments[segmentInd].points;
+      pointInd = points.length - 1;
+      while (currentLength < 0) {
+        currentLength += points[pointInd].partialLength;
+        pointInd -= 1;
+        if (pointInd < 0) {
+          segmentInd -= 1;
+          points = segments[segmentInd].points;
+          pointInd = points.length - 1;
+        }
+      }
+    }
+    points = segments[segmentInd].points;
+    prevPoint = points[pointInd - 1];
+    currentPoint = points[pointInd];
+    partialLength = currentPoint.partialLength;
+  }
+
+  len = letters.length;
+  xPos = 0;
+  yPos = 0;
+  var yOff = documentData.finalSize * 1.2 * 0.714;
+  var firstLine = true;
+  var animatorProps;
+  var animatorSelector;
+  var j;
+  var jLen;
+  var letterValue;
+
+  jLen = animators.length;
+
+  var mult;
+  var ind = -1;
+  var offf;
+  var xPathPos;
+  var yPathPos;
+  var initPathPos = currentLength;
+  var initSegmentInd = segmentInd;
+  var initPointInd = pointInd;
+  var currentLine = -1;
+  var elemOpacity;
+  var sc;
+  var sw;
+  var fc;
+  var k;
+  var letterSw;
+  var letterSc;
+  var letterFc;
+  var letterM = '';
+  var letterP = this.defaultPropsArray;
+  var letterO;
+
+  //
+  if (documentData.j === 2 || documentData.j === 1) {
+    var animatorJustifyOffset = 0;
+    var animatorFirstCharOffset = 0;
+    var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
+    var lastIndex = 0;
+    var isNewLine = true;
+
+    for (i = 0; i < len; i += 1) {
+      if (letters[i].n) {
+        if (animatorJustifyOffset) {
+          animatorJustifyOffset += animatorFirstCharOffset;
+        }
+        while (lastIndex < i) {
+          letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+          lastIndex += 1;
+        }
+        animatorJustifyOffset = 0;
+        isNewLine = true;
+      } else {
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.t.propType) {
+            if (isNewLine && documentData.j === 2) {
+              animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
+            }
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
+            } else {
+              animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult;
+            }
+          }
+        }
+        isNewLine = false;
+      }
+    }
+    if (animatorJustifyOffset) {
+      animatorJustifyOffset += animatorFirstCharOffset;
+    }
+    while (lastIndex < i) {
+      letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+      lastIndex += 1;
+    }
+  }
+  //
+
+  for (i = 0; i < len; i += 1) {
+    matrixHelper.reset();
+    elemOpacity = 1;
+    if (letters[i].n) {
+      xPos = 0;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      currentLength = initPathPos;
+      firstLine = false;
+      if (this._hasMaskedPath) {
+        segmentInd = initSegmentInd;
+        pointInd = initPointInd;
+        points = segments[segmentInd].points;
+        prevPoint = points[pointInd - 1];
+        currentPoint = points[pointInd];
+        partialLength = currentPoint.partialLength;
+        segmentLength = 0;
+      }
+      letterM = '';
+      letterFc = '';
+      letterSw = '';
+      letterO = '';
+      letterP = this.defaultPropsArray;
+    } else {
+      if (this._hasMaskedPath) {
+        if (currentLine !== letters[i].line) {
+          switch (documentData.j) {
+            case 1:
+              currentLength += totalLength - documentData.lineWidths[letters[i].line];
+              break;
+            case 2:
+              currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
+              break;
+            default:
+              break;
+          }
+          currentLine = letters[i].line;
+        }
+        if (ind !== letters[i].ind) {
+          if (letters[ind]) {
+            currentLength += letters[ind].extra;
+          }
+          currentLength += letters[i].an / 2;
+          ind = letters[i].ind;
+        }
+        currentLength += (alignment[0] * letters[i].an) * 0.005;
+        var animatorOffset = 0;
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.p.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.p.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.p.v[0] * mult;
+            }
+          }
+          if (animatorProps.a.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.a.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.a.v[0] * mult;
+            }
+          }
+        }
+        flag = true;
+        // Force alignment only works with a single line for now
+        if (this._pathData.a.v) {
+          currentLength = letters[0].an * 0.5 + ((totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind) / (len - 1);
+          currentLength += this._pathData.f.v;
+        }
+        while (flag) {
+          if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
+            perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
+            xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
+            yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
+            matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, -(alignment[1] * yOff) * 0.01);
+            flag = false;
+          } else if (points) {
+            segmentLength += currentPoint.partialLength;
+            pointInd += 1;
+            if (pointInd >= points.length) {
+              pointInd = 0;
+              segmentInd += 1;
+              if (!segments[segmentInd]) {
+                if (mask.v.c) {
+                  pointInd = 0;
+                  segmentInd = 0;
+                  points = segments[segmentInd].points;
+                } else {
+                  segmentLength -= currentPoint.partialLength;
+                  points = null;
+                }
+              } else {
+                points = segments[segmentInd].points;
+              }
+            }
+            if (points) {
+              prevPoint = currentPoint;
+              currentPoint = points[pointInd];
+              partialLength = currentPoint.partialLength;
+            }
+          }
+        }
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+      } else {
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+
+        // Grouping alignment
+        matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, (-alignment[1] * yOff) * 0.01, 0);
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.t.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
+          if (xPos !== 0 || documentData.j !== 0) {
+            if (this._hasMaskedPath) {
+              if (mult.length) {
+                currentLength += animatorProps.t.v * mult[0];
+              } else {
+                currentLength += animatorProps.t.v * mult;
+              }
+            } else if (mult.length) {
+              xPos += animatorProps.t.v * mult[0];
+            } else {
+              xPos += animatorProps.t.v * mult;
+            }
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        sw = documentData.sw || 0;
+      }
+      if (documentData.strokeColorAnim) {
+        if (documentData.sc) {
+          sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
+        } else {
+          sc = [0, 0, 0];
+        }
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.a.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+
+          if (mult.length) {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.s.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (mult.length) {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult[0]), 1 + ((animatorProps.s.v[1] - 1) * mult[1]), 1);
+          } else {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult), 1 + ((animatorProps.s.v[1] - 1) * mult), 1);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        animatorSelector = animators[j].s;
+        mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+        if (animatorProps.sk.propType) {
+          if (mult.length) {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
+          } else {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
+          }
+        }
+        if (animatorProps.r.propType) {
+          if (mult.length) {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
+          } else {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult);
+          }
+        }
+        if (animatorProps.ry.propType) {
+          if (mult.length) {
+            matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
+          } else {
+            matrixHelper.rotateY(animatorProps.ry.v * mult);
+          }
+        }
+        if (animatorProps.rx.propType) {
+          if (mult.length) {
+            matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
+          } else {
+            matrixHelper.rotateX(animatorProps.rx.v * mult);
+          }
+        }
+        if (animatorProps.o.propType) {
+          if (mult.length) {
+            elemOpacity += ((animatorProps.o.v) * mult[0] - elemOpacity) * mult[0];
+          } else {
+            elemOpacity += ((animatorProps.o.v) * mult - elemOpacity) * mult;
+          }
+        }
+        if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
+          if (mult.length) {
+            sw += animatorProps.sw.v * mult[0];
+          } else {
+            sw += animatorProps.sw.v * mult;
+          }
+        }
+        if (documentData.strokeColorAnim && animatorProps.sc.propType) {
+          for (k = 0; k < 3; k += 1) {
+            if (mult.length) {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0];
+            } else {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult;
+            }
+          }
+        }
+        if (documentData.fillColorAnim && documentData.fc) {
+          if (animatorProps.fc.propType) {
+            for (k = 0; k < 3; k += 1) {
+              if (mult.length) {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0];
+              } else {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult;
+              }
+            }
+          }
+          if (animatorProps.fh.propType) {
+            if (mult.length) {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
+            } else {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult);
+            }
+          }
+          if (animatorProps.fs.propType) {
+            if (mult.length) {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
+            } else {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
+            }
+          }
+          if (animatorProps.fb.propType) {
+            if (mult.length) {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
+            } else {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult);
+            }
+          }
+        }
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+
+        if (animatorProps.p.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (this._hasMaskedPath) {
+            if (mult.length) {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
+            } else {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+            }
+          } else if (mult.length) {
+            matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        letterSw = sw < 0 ? 0 : sw;
+      }
+      if (documentData.strokeColorAnim) {
+        letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
+      }
+
+      if (this._hasMaskedPath) {
+        matrixHelper.translate(0, -documentData.ls);
+
+        matrixHelper.translate(0, (alignment[1] * yOff) * 0.01 + yPos, 0);
+        if (this._pathData.p.v) {
+          tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
+          var rot = (Math.atan(tanAngle) * 180) / Math.PI;
+          if (currentPoint.point[0] < prevPoint.point[0]) {
+            rot += 180;
+          }
+          matrixHelper.rotate((-rot * Math.PI) / 180);
+        }
+        matrixHelper.translate(xPathPos, yPathPos, 0);
+        currentLength -= (alignment[0] * letters[i].an) * 0.005;
+        if (letters[i + 1] && ind !== letters[i + 1].ind) {
+          currentLength += letters[i].an / 2;
+          currentLength += (documentData.tr * 0.001) * documentData.finalSize;
+        }
+      } else {
+        matrixHelper.translate(xPos, yPos, 0);
+
+        if (documentData.ps) {
+          // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
+          matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+        }
+        switch (documentData.j) {
+          case 1:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
+            break;
+          case 2:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
+            break;
+          default:
+            break;
+        }
+        matrixHelper.translate(0, -documentData.ls);
+        matrixHelper.translate(offf, 0, 0);
+        matrixHelper.translate((alignment[0] * letters[i].an) * 0.005, (alignment[1] * yOff) * 0.01, 0);
+        xPos += letters[i].l + (documentData.tr * 0.001) * documentData.finalSize;
+      }
+      if (renderType === 'html') {
+        letterM = matrixHelper.toCSS();
+      } else if (renderType === 'svg') {
+        letterM = matrixHelper.to2dCSS();
+      } else {
+        letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
+      }
+      letterO = elemOpacity;
+    }
+
+    if (renderedLettersCount <= i) {
+      letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
+      this.renderedLetters.push(letterValue);
+      renderedLettersCount += 1;
+      this.lettersChangedFlag = true;
+    } else {
+      letterValue = this.renderedLetters[i];
+      this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag;
+    }
+  }
+};
+
+TextAnimatorProperty.prototype.getValue = function () {
+  if (this._elem.globalData.frameId === this._frameId) {
+    return;
+  }
+  this._frameId = this._elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+TextAnimatorProperty.prototype.mHelper = new Matrix();
+TextAnimatorProperty.prototype.defaultPropsArray = [];
+extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
+
+function ITextElement() {
+}
+
+ITextElement.prototype.initElement = function (data, globalData, comp) {
+  this.lettersChangedFlag = true;
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.textProperty = new TextProperty(this, data.t, this.dynamicProperties);
+  this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this);
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+  this.initRenderable();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  this.createContent();
+  this.hide();
+  this.textAnimator.searchProperties(this.dynamicProperties);
+};
+
+ITextElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+};
+
+ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
+  var j;
+  var jLen = shapes.length;
+  var pathNodes;
+  var shapeStr = '';
+  for (j = 0; j < jLen; j += 1) {
+    if (shapes[j].ty === 'sh') {
+      pathNodes = shapes[j].ks.k;
+      shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
+    }
+  }
+  return shapeStr;
+};
+
+ITextElement.prototype.updateDocumentData = function (newData, index) {
+  this.textProperty.updateDocumentData(newData, index);
+};
+
+ITextElement.prototype.canResizeFont = function (_canResize) {
+  this.textProperty.canResizeFont(_canResize);
+};
+
+ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
+  this.textProperty.setMinimumFontSize(_fontSize);
+};
+
+ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
+  if (documentData.ps) {
+    matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+  }
+  matrixHelper.translate(0, -documentData.ls, 0);
+  switch (documentData.j) {
+    case 1:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
+      break;
+    case 2:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
+      break;
+    default:
+      break;
+  }
+  matrixHelper.translate(xPos, yPos, 0);
+};
+
+ITextElement.prototype.buildColor = function (colorData) {
+  return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
+};
+
+ITextElement.prototype.emptyProp = new LetterProps();
+
+ITextElement.prototype.destroy = function () {
+
+};
+
+ITextElement.prototype.validateText = function () {
+  if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
+    this.buildNewText();
+    this.textProperty._isFirstFrame = false;
+    this.textProperty._mdf = false;
+  }
+};
+
+var emptyShapeData = {
+  shapes: [],
+};
+
+function SVGTextLottieElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.renderType = 'svg';
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
+
+SVGTextLottieElement.prototype.createContent = function () {
+  if (this.data.singleShape && !this.globalData.fontManager.chars) {
+    this.textContainer = createNS('text');
+  }
+};
+
+SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
+  var i = 0;
+  var len = textArray.length;
+  var textContents = [];
+  var currentTextContent = '';
+  while (i < len) {
+    if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
+      textContents.push(currentTextContent);
+      currentTextContent = '';
+    } else {
+      currentTextContent += textArray[i];
+    }
+    i += 1;
+  }
+  textContents.push(currentTextContent);
+  return textContents;
+};
+
+SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
+  // data should probably be cloned to apply scale separately to each instance of a text on different layers
+  // but since text internal content gets only rendered once and then it's never rerendered,
+  // it's probably safe not to clone data and reuse always the same instance even if the object is mutated.
+  // Avoiding cloning is preferred since cloning each character shape data is expensive
+  if (data.shapes && data.shapes.length) {
+    var shape = data.shapes[0];
+    if (shape.it) {
+      var shapeItem = shape.it[shape.it.length - 1];
+      if (shapeItem.s) {
+        shapeItem.s.k[0] = scale;
+        shapeItem.s.k[1] = scale;
+      }
+    }
+  }
+  return data;
+};
+
+SVGTextLottieElement.prototype.buildNewText = function () {
+  this.addDynamicProperty(this);
+  var i;
+  var len;
+
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
+  if (documentData.fc) {
+    this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
+  } else {
+    this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
+  }
+  if (documentData.sc) {
+    this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
+    this.layerElement.setAttribute('stroke-width', documentData.sw);
+  }
+  this.layerElement.setAttribute('font-size', documentData.finalSize);
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (fontData.fClass) {
+    this.layerElement.setAttribute('class', fontData.fClass);
+  } else {
+    this.layerElement.setAttribute('font-family', fontData.fFamily);
+    var fWeight = documentData.fWeight;
+    var fStyle = documentData.fStyle;
+    this.layerElement.setAttribute('font-style', fStyle);
+    this.layerElement.setAttribute('font-weight', fWeight);
+  }
+  this.layerElement.setAttribute('aria-label', documentData.t);
+
+  var letters = documentData.l || [];
+  var usesGlyphs = !!this.globalData.fontManager.chars;
+  len = letters.length;
+
+  var tSpan;
+  var matrixHelper = this.mHelper;
+  var shapeStr = '';
+  var singleShape = this.data.singleShape;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  if (singleShape && !usesGlyphs && !documentData.sz) {
+    var tElement = this.textContainer;
+    var justify = 'start';
+    switch (documentData.j) {
+      case 1:
+        justify = 'end';
+        break;
+      case 2:
+        justify = 'middle';
+        break;
+      default:
+        justify = 'start';
+        break;
+    }
+    tElement.setAttribute('text-anchor', justify);
+    tElement.setAttribute('letter-spacing', trackingOffset);
+    var textContent = this.buildTextContents(documentData.finalText);
+    len = textContent.length;
+    yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
+    for (i = 0; i < len; i += 1) {
+      tSpan = this.textSpans[i].span || createNS('tspan');
+      tSpan.textContent = textContent[i];
+      tSpan.setAttribute('x', 0);
+      tSpan.setAttribute('y', yPos);
+      tSpan.style.display = 'inherit';
+      tElement.appendChild(tSpan);
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          glyph: null,
+        };
+      }
+      this.textSpans[i].span = tSpan;
+      yPos += documentData.finalLineHeight;
+    }
+
+    this.layerElement.appendChild(tElement);
+  } else {
+    var cachedSpansLength = this.textSpans.length;
+    var charData;
+    for (i = 0; i < len; i += 1) {
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          childSpan: null,
+          glyph: null,
+        };
+      }
+      if (!usesGlyphs || !singleShape || i === 0) {
+        tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
+        if (cachedSpansLength <= i) {
+          tSpan.setAttribute('stroke-linecap', 'butt');
+          tSpan.setAttribute('stroke-linejoin', 'round');
+          tSpan.setAttribute('stroke-miterlimit', '4');
+          this.textSpans[i].span = tSpan;
+          if (usesGlyphs) {
+            var childSpan = createNS('g');
+            tSpan.appendChild(childSpan);
+            this.textSpans[i].childSpan = childSpan;
+          }
+          this.textSpans[i].span = tSpan;
+          this.layerElement.appendChild(tSpan);
+        }
+        tSpan.style.display = 'inherit';
+      }
+
+      matrixHelper.reset();
+      if (singleShape) {
+        if (letters[i].n) {
+          xPos = -trackingOffset;
+          yPos += documentData.yOffset;
+          yPos += firstLine ? 1 : 0;
+          firstLine = false;
+        }
+        this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+        xPos += letters[i].l || 0;
+        // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
+        xPos += trackingOffset;
+      }
+      if (usesGlyphs) {
+        charData = this.globalData.fontManager.getCharData(
+          documentData.finalText[i],
+          fontData.fStyle,
+          this.globalData.fontManager.getFontByName(documentData.f).fFamily
+        );
+        var glyphElement;
+        // t === 1 means the character has been replaced with an animated shaped
+        if (charData.t === 1) {
+          glyphElement = new SVGCompElement(charData.data, this.globalData, this);
+        } else {
+          var data = emptyShapeData;
+          if (charData.data && charData.data.shapes) {
+            data = this.buildShapeData(charData.data, documentData.finalSize);
+          }
+          glyphElement = new SVGShapeElement(data, this.globalData, this);
+        }
+        if (this.textSpans[i].glyph) {
+          var glyph = this.textSpans[i].glyph;
+          this.textSpans[i].childSpan.removeChild(glyph.layerElement);
+          glyph.destroy();
+        }
+        this.textSpans[i].glyph = glyphElement;
+        glyphElement._debug = true;
+        glyphElement.prepareFrame(0);
+        glyphElement.renderFrame();
+        this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+        // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+        // this might have issues with strokes and might need a different solution
+        if (charData.t === 1) {
+          this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
+        }
+      } else {
+        if (singleShape) {
+          tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
+        }
+        tSpan.textContent = letters[i].val;
+        tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      }
+      //
+    }
+    if (singleShape && tSpan) {
+      tSpan.setAttribute('d', shapeStr);
+    }
+  }
+  while (i < this.textSpans.length) {
+    this.textSpans[i].span.style.display = 'none';
+    i += 1;
+  }
+
+  this._sizeChanged = true;
+};
+
+SVGTextLottieElement.prototype.sourceRectAtTime = function () {
+  this.prepareFrame(this.comp.renderedFrame - this.data.st);
+  this.renderInnerContent();
+  if (this._sizeChanged) {
+    this._sizeChanged = false;
+    var textBox = this.layerElement.getBBox();
+    this.bbox = {
+      top: textBox.y,
+      left: textBox.x,
+      width: textBox.width,
+      height: textBox.height,
+    };
+  }
+  return this.bbox;
+};
+
+SVGTextLottieElement.prototype.getValue = function () {
+  var i;
+  var len = this.textSpans.length;
+  var glyphElement;
+  this.renderedFrame = this.comp.renderedFrame;
+  for (i = 0; i < len; i += 1) {
+    glyphElement = this.textSpans[i].glyph;
+    if (glyphElement) {
+      glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
+      if (glyphElement._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+SVGTextLottieElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  if (!this.data.singleShape || this._mdf) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+    if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
+      this._sizeChanged = true;
+      var i;
+      var len;
+      var renderedLetters = this.textAnimator.renderedLetters;
+
+      var letters = this.textProperty.currentData.l;
+
+      len = letters.length;
+      var renderedLetter;
+      var textSpan;
+      var glyphElement;
+      for (i = 0; i < len; i += 1) {
+        if (!letters[i].n) {
+          renderedLetter = renderedLetters[i];
+          textSpan = this.textSpans[i].span;
+          glyphElement = this.textSpans[i].glyph;
+          if (glyphElement) {
+            glyphElement.renderFrame();
+          }
+          if (renderedLetter._mdf.m) {
+            textSpan.setAttribute('transform', renderedLetter.m);
+          }
+          if (renderedLetter._mdf.o) {
+            textSpan.setAttribute('opacity', renderedLetter.o);
+          }
+          if (renderedLetter._mdf.sw) {
+            textSpan.setAttribute('stroke-width', renderedLetter.sw);
+          }
+          if (renderedLetter._mdf.sc) {
+            textSpan.setAttribute('stroke', renderedLetter.sc);
+          }
+          if (renderedLetter._mdf.fc) {
+            textSpan.setAttribute('fill', renderedLetter.fc);
+          }
+        }
+      }
+    }
+  }
+};
+
+function ISolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([IImageElement], ISolidElement);
+
+ISolidElement.prototype.createContent = function () {
+  var rect = createNS('rect');
+  /// /rect.style.width = this.data.sw;
+  /// /rect.style.height = this.data.sh;
+  /// /rect.style.fill = this.data.sc;
+  rect.setAttribute('width', this.data.sw);
+  rect.setAttribute('height', this.data.sh);
+  rect.setAttribute('fill', this.data.sc);
+  this.layerElement.appendChild(rect);
+};
+
+function NullElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initFrame();
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+}
+
+NullElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+NullElement.prototype.renderFrame = function () {
+};
+
+NullElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+NullElement.prototype.destroy = function () {
+};
+
+NullElement.prototype.sourceRectAtTime = function () {
+};
+
+NullElement.prototype.hide = function () {
+};
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
+
+function SVGRendererBase() {
+}
+
+extendPrototype([BaseRenderer], SVGRendererBase);
+
+SVGRendererBase.prototype.createNull = function (data) {
+  return new NullElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createShape = function (data) {
+  return new SVGShapeElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createText = function (data) {
+  return new SVGTextLottieElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createImage = function (data) {
+  return new IImageElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createSolid = function (data) {
+  return new ISolidElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.configAnimation = function (animData) {
+  this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+  this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+  if (this.renderConfig.viewBoxSize) {
+    this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
+  } else {
+    this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
+  }
+
+  if (!this.renderConfig.viewBoxOnly) {
+    this.svgElement.setAttribute('width', animData.w);
+    this.svgElement.setAttribute('height', animData.h);
+    this.svgElement.style.width = '100%';
+    this.svgElement.style.height = '100%';
+    this.svgElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
+  }
+  if (this.renderConfig.width) {
+    this.svgElement.setAttribute('width', this.renderConfig.width);
+  }
+  if (this.renderConfig.height) {
+    this.svgElement.setAttribute('height', this.renderConfig.height);
+  }
+  if (this.renderConfig.className) {
+    this.svgElement.setAttribute('class', this.renderConfig.className);
+  }
+  if (this.renderConfig.id) {
+    this.svgElement.setAttribute('id', this.renderConfig.id);
+  }
+  if (this.renderConfig.focusable !== undefined) {
+    this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
+  }
+  this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+  // this.layerElement.style.transform = 'translate3d(0,0,0)';
+  // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
+  this.animationItem.wrapper.appendChild(this.svgElement);
+  // Mask animation
+  var defs = this.globalData.defs;
+
+  this.setupGlobalData(animData, defs);
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.data = animData;
+
+  var maskElement = createNS('clipPath');
+  var rect = createNS('rect');
+  rect.setAttribute('width', animData.w);
+  rect.setAttribute('height', animData.h);
+  rect.setAttribute('x', 0);
+  rect.setAttribute('y', 0);
+  var maskId = createElementID();
+  maskElement.setAttribute('id', maskId);
+  maskElement.appendChild(rect);
+  this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')');
+
+  defs.appendChild(maskElement);
+  this.layers = animData.layers;
+  this.elements = createSizedArray(animData.layers.length);
+};
+
+SVGRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.layerElement = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+SVGRendererBase.prototype.updateContainerSize = function () {
+};
+
+SVGRendererBase.prototype.findIndexByInd = function (ind) {
+  var i = 0;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.layers[i].ind === ind) {
+      return i;
+    }
+  }
+  return -1;
+};
+
+SVGRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  elements[pos] = true;
+  var element = this.createItem(this.layers[pos]);
+
+  elements[pos] = element;
+  if (getExpressionsPlugin()) {
+    if (this.layers[pos].ty === 0) {
+      this.globalData.projectInterface.registerComposition(element);
+    }
+    element.initExpressions();
+  }
+  this.appendElementInPos(element, pos);
+  if (this.layers[pos].tt) {
+    var elementIndex = ('tp' in this.layers[pos])
+      ? this.findIndexByInd(this.layers[pos].tp)
+      : pos - 1;
+    if (elementIndex === -1) {
+      return;
+    }
+    if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
+      this.buildItem(elementIndex);
+      this.addPendingElement(element);
+    } else {
+      var matteElement = elements[elementIndex];
+      var matteMask = matteElement.getMatte(this.layers[pos].tt);
+      element.setMatte(matteMask);
+    }
+  }
+};
+
+SVGRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+    if (element.data.tt) {
+      var i = 0;
+      var len = this.elements.length;
+      while (i < len) {
+        if (this.elements[i] === element) {
+          var elementIndex = 'tp' in element.data
+            ? this.findIndexByInd(element.data.tp)
+            : i - 1;
+          var matteElement = this.elements[elementIndex];
+          var matteMask = matteElement.getMatte(this.layers[i].tt);
+          element.setMatte(matteMask);
+          break;
+        }
+        i += 1;
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.renderFrame = function (num) {
+  if (this.renderedFrame === num || this.destroyed) {
+    return;
+  }
+  if (num === null) {
+    num = this.renderedFrame;
+  } else {
+    this.renderedFrame = num;
+  }
+  // console.log('-------');
+  // console.log('FRAME ',num);
+  this.globalData.frameNum = num;
+  this.globalData.frameId += 1;
+  this.globalData.projectInterface.currentFrame = num;
+  this.globalData._mdf = false;
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    for (i = 0; i < len; i += 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
+  var newElement = element.getBaseElement();
+  if (!newElement) {
+    return;
+  }
+  var i = 0;
+  var nextElement;
+  while (i < pos) {
+    if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
+      nextElement = this.elements[i].getBaseElement();
+    }
+    i += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(newElement, nextElement);
+  } else {
+    this.layerElement.appendChild(newElement);
+  }
+};
+
+SVGRendererBase.prototype.hide = function () {
+  this.layerElement.style.display = 'none';
+};
+
+SVGRendererBase.prototype.show = function () {
+  this.layerElement.style.display = 'block';
+};
+
+function ICompElement() {}
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
+
+ICompElement.prototype.initElement = function (data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initTransform(data, globalData, comp);
+  this.initRenderable();
+  this.initHierarchy();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  if (this.data.xt || !globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+  this.hide();
+};
+
+/* ICompElement.prototype.hide = function(){
+    if(!this.hidden){
+        this.hideElement();
+        var i,len = this.elements.length;
+        for( i = 0; i < len; i+=1 ){
+            if(this.elements[i]){
+                this.elements[i].hide();
+            }
+        }
+    }
+}; */
+
+ICompElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+  if (!this.isInRange && !this.data.xt) {
+    return;
+  }
+
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    if (timeRemapped === this.data.op) {
+      timeRemapped = this.data.op - 1;
+    }
+    this.renderedFrame = timeRemapped;
+  } else {
+    this.renderedFrame = num / this.data.sr;
+  }
+  var i;
+  var len = this.elements.length;
+  if (!this.completeLayers) {
+    this.checkLayers(this.renderedFrame);
+  }
+  // This iteration needs to be backwards because of how expressions connect between each other
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
+      if (this.elements[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+ICompElement.prototype.renderInnerContent = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+ICompElement.prototype.setElements = function (elems) {
+  this.elements = elems;
+};
+
+ICompElement.prototype.getElements = function () {
+  return this.elements;
+};
+
+ICompElement.prototype.destroyElements = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+};
+
+ICompElement.prototype.destroy = function () {
+  this.destroyElements();
+  this.destroyBaseElement();
+};
+
+function SVGCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = true;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
+
+SVGCompElement.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function SVGRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.layers = null;
+  this.renderedFrame = -1;
+  this.svgElement = createNS('svg');
+  var ariaLabel = '';
+  if (config && config.title) {
+    var titleElement = createNS('title');
+    var titleId = createElementID();
+    titleElement.setAttribute('id', titleId);
+    titleElement.textContent = config.title;
+    this.svgElement.appendChild(titleElement);
+    ariaLabel += titleId;
+  }
+  if (config && config.description) {
+    var descElement = createNS('desc');
+    var descId = createElementID();
+    descElement.setAttribute('id', descId);
+    descElement.textContent = config.description;
+    this.svgElement.appendChild(descElement);
+    ariaLabel += ' ' + descId;
+  }
+  if (ariaLabel) {
+    this.svgElement.setAttribute('aria-labelledby', ariaLabel);
+  }
+  var defs = createNS('defs');
+  this.svgElement.appendChild(defs);
+  var maskElement = createNS('g');
+  this.svgElement.appendChild(maskElement);
+  this.layerElement = maskElement;
+  this.renderConfig = {
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    hideOnTransparent: !((config && config.hideOnTransparent === false)),
+    viewBoxOnly: (config && config.viewBoxOnly) || false,
+    viewBoxSize: (config && config.viewBoxSize) || false,
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    focusable: config && config.focusable,
+    filterSize: {
+      width: (config && config.filterSize && config.filterSize.width) || '100%',
+      height: (config && config.filterSize && config.filterSize.height) || '100%',
+      x: (config && config.filterSize && config.filterSize.x) || '0%',
+      y: (config && config.filterSize && config.filterSize.y) || '0%',
+    },
+    width: (config && config.width),
+    height: (config && config.height),
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+
+  this.globalData = {
+    _mdf: false,
+    frameNum: -1,
+    defs: defs,
+    renderConfig: this.renderConfig,
+  };
+  this.elements = [];
+  this.pendingElements = [];
+  this.destroyed = false;
+  this.rendererType = 'svg';
+}
+
+extendPrototype([SVGRendererBase], SVGRenderer);
+
+SVGRenderer.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+// Registering renderers
+registerRenderer('svg', SVGRenderer);
+
+// Registering shape modifiers
+ShapeModifiers.registerModifier('tm', TrimModifier);
+ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
+ShapeModifiers.registerModifier('rp', RepeaterModifier);
+ShapeModifiers.registerModifier('rd', RoundCornersModifier);
+ShapeModifiers.registerModifier('zz', ZigZagModifier);
+ShapeModifiers.registerModifier('op', OffsetPathModifier);
+
+export { lottie as default };
diff --git a/build/player/esm/lottie_light_canvas.min.js b/build/player/esm/lottie_light_canvas.min.js
new file mode 100644
index 0000000..ebe31cd
--- /dev/null
+++ b/build/player/esm/lottie_light_canvas.min.js
@@ -0,0 +1,13445 @@
+const svgNS = 'http://www.w3.org/2000/svg';
+
+let locationHref = '';
+let _useWebWorker = false;
+
+const initialDefaultFrame = -999999;
+
+const setWebWorker = (flag) => { _useWebWorker = !!flag; };
+const getWebWorker = () => _useWebWorker;
+
+const setLocationHref = (value) => { locationHref = value; };
+const getLocationHref = () => locationHref;
+
+function createTag(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElement(type);
+}
+
+function extendPrototype(sources, destination) {
+  var i;
+  var len = sources.length;
+  var sourcePrototype;
+  for (i = 0; i < len; i += 1) {
+    sourcePrototype = sources[i].prototype;
+    for (var attr in sourcePrototype) {
+      if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
+    }
+  }
+}
+
+function getDescriptor(object, prop) {
+  return Object.getOwnPropertyDescriptor(object, prop);
+}
+
+function createProxyFunction(prototype) {
+  function ProxyFunction() {}
+  ProxyFunction.prototype = prototype;
+  return ProxyFunction;
+}
+
+// import Howl from '../../3rd_party/howler';
+
+const audioControllerFactory = (function () {
+  function AudioController(audioFactory) {
+    this.audios = [];
+    this.audioFactory = audioFactory;
+    this._volume = 1;
+    this._isMuted = false;
+  }
+
+  AudioController.prototype = {
+    addAudio: function (audio) {
+      this.audios.push(audio);
+    },
+    pause: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].pause();
+      }
+    },
+    resume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].resume();
+      }
+    },
+    setRate: function (rateValue) {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].setRate(rateValue);
+      }
+    },
+    createAudio: function (assetPath) {
+      if (this.audioFactory) {
+        return this.audioFactory(assetPath);
+      } if (window.Howl) {
+        return new window.Howl({
+          src: [assetPath],
+        });
+      }
+      return {
+        isPlaying: false,
+        play: function () { this.isPlaying = true; },
+        seek: function () { this.isPlaying = false; },
+        playing: function () {},
+        rate: function () {},
+        setVolume: function () {},
+      };
+    },
+    setAudioFactory: function (audioFactory) {
+      this.audioFactory = audioFactory;
+    },
+    setVolume: function (value) {
+      this._volume = value;
+      this._updateVolume();
+    },
+    mute: function () {
+      this._isMuted = true;
+      this._updateVolume();
+    },
+    unmute: function () {
+      this._isMuted = false;
+      this._updateVolume();
+    },
+    getVolume: function () {
+      return this._volume;
+    },
+    _updateVolume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
+      }
+    },
+  };
+
+  return function () {
+    return new AudioController();
+  };
+}());
+
+const createTypedArray = (function () {
+  function createRegularArray(type, len) {
+    var i = 0;
+    var arr = [];
+    var value;
+    switch (type) {
+      case 'int16':
+      case 'uint8c':
+        value = 1;
+        break;
+      default:
+        value = 1.1;
+        break;
+    }
+    for (i = 0; i < len; i += 1) {
+      arr.push(value);
+    }
+    return arr;
+  }
+  function createTypedArrayFactory(type, len) {
+    if (type === 'float32') {
+      return new Float32Array(len);
+    } if (type === 'int16') {
+      return new Int16Array(len);
+    } if (type === 'uint8c') {
+      return new Uint8ClampedArray(len);
+    }
+    return createRegularArray(type, len);
+  }
+  if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
+    return createTypedArrayFactory;
+  }
+  return createRegularArray;
+}());
+
+function createSizedArray(len) {
+  return Array.apply(null, { length: len });
+}
+
+let subframeEnabled = true;
+let expressionsPlugin = null;
+let expressionsInterfaces = null;
+let idPrefix$1 = '';
+const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+let _shouldRoundValues = false;
+const bmPow = Math.pow;
+const bmSqrt = Math.sqrt;
+const bmFloor = Math.floor;
+const bmMax = Math.max;
+const bmMin = Math.min;
+
+const BMMath = {};
+(function () {
+  var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
+  var i;
+  var len = propertyNames.length;
+  for (i = 0; i < len; i += 1) {
+    BMMath[propertyNames[i]] = Math[propertyNames[i]];
+  }
+}());
+
+function ProjectInterface$1() { return {}; }
+BMMath.random = Math.random;
+BMMath.abs = function (val) {
+  var tOfVal = typeof val;
+  if (tOfVal === 'object' && val.length) {
+    var absArr = createSizedArray(val.length);
+    var i;
+    var len = val.length;
+    for (i = 0; i < len; i += 1) {
+      absArr[i] = Math.abs(val[i]);
+    }
+    return absArr;
+  }
+  return Math.abs(val);
+};
+let defaultCurveSegments = 150;
+const degToRads = Math.PI / 180;
+const roundCorner = 0.5519;
+
+function roundValues(flag) {
+  _shouldRoundValues = !!flag;
+}
+
+function bmRnd(value) {
+  if (_shouldRoundValues) {
+    return Math.round(value);
+  }
+  return value;
+}
+
+function styleDiv(element) {
+  element.style.position = 'absolute';
+  element.style.top = 0;
+  element.style.left = 0;
+  element.style.display = 'block';
+  element.style.transformOrigin = '0 0';
+  element.style.webkitTransformOrigin = '0 0';
+  element.style.backfaceVisibility = 'visible';
+  element.style.webkitBackfaceVisibility = 'visible';
+  element.style.transformStyle = 'preserve-3d';
+  element.style.webkitTransformStyle = 'preserve-3d';
+  element.style.mozTransformStyle = 'preserve-3d';
+}
+
+function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
+  this.type = type;
+  this.currentTime = currentTime;
+  this.totalTime = totalTime;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteEvent(type, frameMultiplier) {
+  this.type = type;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
+  this.type = type;
+  this.currentLoop = currentLoop;
+  this.totalLoops = totalLoops;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMSegmentStartEvent(type, firstFrame, totalFrames) {
+  this.type = type;
+  this.firstFrame = firstFrame;
+  this.totalFrames = totalFrames;
+}
+
+function BMDestroyEvent(type, target) {
+  this.type = type;
+  this.target = target;
+}
+
+function BMRenderFrameErrorEvent(nativeError, currentTime) {
+  this.type = 'renderFrameError';
+  this.nativeError = nativeError;
+  this.currentTime = currentTime;
+}
+
+function BMConfigErrorEvent(nativeError) {
+  this.type = 'configError';
+  this.nativeError = nativeError;
+}
+
+function BMAnimationConfigErrorEvent(type, nativeError) {
+  this.type = type;
+  this.nativeError = nativeError;
+}
+
+const createElementID = (function () {
+  var _count = 0;
+  return function createID() {
+    _count += 1;
+    return idPrefix$1 + '__lottie_element_' + _count;
+  };
+}());
+
+function HSVtoRGB(h, s, v) {
+  var r;
+  var g;
+  var b;
+  var i;
+  var f;
+  var p;
+  var q;
+  var t;
+  i = Math.floor(h * 6);
+  f = h * 6 - i;
+  p = v * (1 - s);
+  q = v * (1 - f * s);
+  t = v * (1 - (1 - f) * s);
+  switch (i % 6) {
+    case 0: r = v; g = t; b = p; break;
+    case 1: r = q; g = v; b = p; break;
+    case 2: r = p; g = v; b = t; break;
+    case 3: r = p; g = q; b = v; break;
+    case 4: r = t; g = p; b = v; break;
+    case 5: r = v; g = p; b = q; break;
+    default: break;
+  }
+  return [r,
+    g,
+    b];
+}
+
+function RGBtoHSV(r, g, b) {
+  var max = Math.max(r, g, b);
+  var min = Math.min(r, g, b);
+  var d = max - min;
+  var h;
+  var s = (max === 0 ? 0 : d / max);
+  var v = max / 255;
+
+  switch (max) {
+    case min: h = 0; break;
+    case r: h = (g - b) + d * (g < b ? 6 : 0); h /= 6 * d; break;
+    case g: h = (b - r) + d * 2; h /= 6 * d; break;
+    case b: h = (r - g) + d * 4; h /= 6 * d; break;
+    default: break;
+  }
+
+  return [
+    h,
+    s,
+    v,
+  ];
+}
+
+function addSaturationToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[1] += offset;
+  if (hsv[1] > 1) {
+    hsv[1] = 1;
+  } else if (hsv[1] <= 0) {
+    hsv[1] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addBrightnessToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[2] += offset;
+  if (hsv[2] > 1) {
+    hsv[2] = 1;
+  } else if (hsv[2] < 0) {
+    hsv[2] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addHueToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[0] += offset / 360;
+  if (hsv[0] > 1) {
+    hsv[0] -= 1;
+  } else if (hsv[0] < 0) {
+    hsv[0] += 1;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+const rgbToHex = (function () {
+  var colorMap = [];
+  var i;
+  var hex;
+  for (i = 0; i < 256; i += 1) {
+    hex = i.toString(16);
+    colorMap[i] = hex.length === 1 ? '0' + hex : hex;
+  }
+
+  return function (r, g, b) {
+    if (r < 0) {
+      r = 0;
+    }
+    if (g < 0) {
+      g = 0;
+    }
+    if (b < 0) {
+      b = 0;
+    }
+    return '#' + colorMap[r] + colorMap[g] + colorMap[b];
+  };
+}());
+
+const setSubframeEnabled = (flag) => { subframeEnabled = !!flag; };
+const getSubframeEnabled = () => subframeEnabled;
+const setExpressionsPlugin = (value) => { expressionsPlugin = value; };
+const getExpressionsPlugin = () => expressionsPlugin;
+const setExpressionInterfaces = (value) => { expressionsInterfaces = value; };
+const getExpressionInterfaces = () => expressionsInterfaces;
+const setDefaultCurveSegments = (value) => { defaultCurveSegments = value; };
+const getDefaultCurveSegments = () => defaultCurveSegments;
+const setIdPrefix = (value) => { idPrefix$1 = value; };
+const getIdPrefix = () => idPrefix$1;
+
+function createNS(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElementNS(svgNS, type);
+}
+
+const dataManager = (function () {
+  var _counterId = 1;
+  var processes = [];
+  var workerFn;
+  var workerInstance;
+  var workerProxy = {
+    onmessage: function () {
+
+    },
+    postMessage: function (path) {
+      workerFn({
+        data: path,
+      });
+    },
+  };
+  var _workerSelf = {
+    postMessage: function (data) {
+      workerProxy.onmessage({
+        data: data,
+      });
+    },
+  };
+  function createWorker(fn) {
+    if (window.Worker && window.Blob && getWebWorker()) {
+      var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      var url = URL.createObjectURL(blob);
+      return new Worker(url);
+    }
+    workerFn = fn;
+    return workerProxy;
+  }
+
+  function setupWorker() {
+    if (!workerInstance) {
+      workerInstance = createWorker(function workerStart(e) {
+        function dataFunctionManager() {
+          function completeLayers(layers, comps) {
+            var layerData;
+            var i;
+            var len = layers.length;
+            var j;
+            var jLen;
+            var k;
+            var kLen;
+            for (i = 0; i < len; i += 1) {
+              layerData = layers[i];
+              if (('ks' in layerData) && !layerData.completed) {
+                layerData.completed = true;
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      convertPathsToAbsoluteValues(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) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 0) {
+                  layerData.layers = findCompLayers(layerData.refId, comps);
+                  completeLayers(layerData.layers, comps);
+                } else if (layerData.ty === 4) {
+                  completeShapes(layerData.shapes);
+                } else if (layerData.ty === 5) {
+                  completeText(layerData);
+                }
+              }
+            }
+          }
+
+          function completeChars(chars, assets) {
+            if (chars) {
+              var i = 0;
+              var len = chars.length;
+              for (i = 0; i < len; i += 1) {
+                if (chars[i].t === 1) {
+                  // var compData = findComp(chars[i].data.refId, assets);
+                  chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                  // chars[i].data.ip = 0;
+                  // chars[i].data.op = 99999;
+                  // chars[i].data.st = 0;
+                  // chars[i].data.sr = 1;
+                  // chars[i].w = compData.w;
+                  // chars[i].data.ks = {
+                  //   a: { k: [0, 0, 0], a: 0 },
+                  //   p: { k: [0, -compData.h, 0], a: 0 },
+                  //   r: { k: 0, a: 0 },
+                  //   s: { k: [100, 100], a: 0 },
+                  //   o: { k: 100, a: 0 },
+                  // };
+                  completeLayers(chars[i].data.layers, assets);
+                }
+              }
+            }
+          }
+
+          function findComp(id, comps) {
+            var i = 0;
+            var len = comps.length;
+            while (i < len) {
+              if (comps[i].id === id) {
+                return comps[i];
+              }
+              i += 1;
+            }
+            return null;
+          }
+
+          function findCompLayers(id, comps) {
+            var comp = findComp(id, comps);
+            if (comp) {
+              if (!comp.layers.__used) {
+                comp.layers.__used = true;
+                return comp.layers;
+              }
+              return JSON.parse(JSON.stringify(comp.layers));
+            }
+            return null;
+          }
+
+          function completeShapes(arr) {
+            var i;
+            var len = arr.length;
+            var j;
+            var jLen;
+            for (i = len - 1; i >= 0; i -= 1) {
+              if (arr[i].ty === 'sh') {
+                if (arr[i].ks.k.i) {
+                  convertPathsToAbsoluteValues(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) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
+                    }
+                    if (arr[i].ks.k[j].e) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
+                    }
+                  }
+                }
+              } else if (arr[i].ty === 'gr') {
+                completeShapes(arr[i].it);
+              }
+            }
+          }
+
+          function convertPathsToAbsoluteValues(path) {
+            var i;
+            var len = path.i.length;
+            for (i = 0; i < len; i += 1) {
+              path.i[i][0] += path.v[i][0];
+              path.i[i][1] += path.v[i][1];
+              path.o[i][0] += path.v[i][0];
+              path.o[i][1] += path.v[i][1];
+            }
+          }
+
+          function checkVersion(minimum, animVersionString) {
+            var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
+            if (minimum[0] > animVersion[0]) {
+              return true;
+            } if (animVersion[0] > minimum[0]) {
+              return false;
+            }
+            if (minimum[1] > animVersion[1]) {
+              return true;
+            } if (animVersion[1] > minimum[1]) {
+              return false;
+            }
+            if (minimum[2] > animVersion[2]) {
+              return true;
+            } if (animVersion[2] > minimum[2]) {
+              return false;
+            }
+            return null;
+          }
+
+          var checkText = (function () {
+            var minimumVersion = [4, 4, 14];
+
+            function updateTextLayer(textLayer) {
+              var documentData = textLayer.t.d;
+              textLayer.t.d = {
+                k: [
+                  {
+                    s: documentData,
+                    t: 0,
+                  },
+                ],
+              };
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkChars = (function () {
+            var minimumVersion = [4, 7, 99];
+            return function (animationData) {
+              if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
+                var i;
+                var len = animationData.chars.length;
+                for (i = 0; i < len; i += 1) {
+                  var charData = animationData.chars[i];
+                  if (charData.data && charData.data.shapes) {
+                    completeShapes(charData.data.shapes);
+                    charData.data.ip = 0;
+                    charData.data.op = 99999;
+                    charData.data.st = 0;
+                    charData.data.sr = 1;
+                    charData.data.ks = {
+                      p: { k: [0, 0], a: 0 },
+                      s: { k: [100, 100], a: 0 },
+                      a: { k: [0, 0], a: 0 },
+                      r: { k: 0, a: 0 },
+                      o: { k: 100, a: 0 },
+                    };
+                    if (!animationData.chars[i].t) {
+                      charData.data.shapes.push(
+                        {
+                          ty: 'no',
+                        }
+                      );
+                      charData.data.shapes[0].it.push(
+                        {
+                          p: { k: [0, 0], a: 0 },
+                          s: { k: [100, 100], a: 0 },
+                          a: { k: [0, 0], a: 0 },
+                          r: { k: 0, a: 0 },
+                          o: { k: 100, a: 0 },
+                          sk: { k: 0, a: 0 },
+                          sa: { k: 0, a: 0 },
+                          ty: 'tr',
+                        }
+                      );
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkPathProperties = (function () {
+            var minimumVersion = [5, 7, 15];
+
+            function updateTextLayer(textLayer) {
+              var pathData = textLayer.t.p;
+              if (typeof pathData.a === 'number') {
+                pathData.a = {
+                  a: 0,
+                  k: pathData.a,
+                };
+              }
+              if (typeof pathData.p === 'number') {
+                pathData.p = {
+                  a: 0,
+                  k: pathData.p,
+                };
+              }
+              if (typeof pathData.r === 'number') {
+                pathData.r = {
+                  a: 0,
+                  k: pathData.r,
+                };
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkColors = (function () {
+            var minimumVersion = [4, 1, 9];
+
+            function iterateShapes(shapes) {
+              var i;
+              var len = shapes.length;
+              var j;
+              var jLen;
+              for (i = 0; i < len; i += 1) {
+                if (shapes[i].ty === 'gr') {
+                  iterateShapes(shapes[i].it);
+                } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
+                  if (shapes[i].c.k && shapes[i].c.k[0].i) {
+                    jLen = shapes[i].c.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (shapes[i].c.k[j].s) {
+                        shapes[i].c.k[j].s[0] /= 255;
+                        shapes[i].c.k[j].s[1] /= 255;
+                        shapes[i].c.k[j].s[2] /= 255;
+                        shapes[i].c.k[j].s[3] /= 255;
+                      }
+                      if (shapes[i].c.k[j].e) {
+                        shapes[i].c.k[j].e[0] /= 255;
+                        shapes[i].c.k[j].e[1] /= 255;
+                        shapes[i].c.k[j].e[2] /= 255;
+                        shapes[i].c.k[j].e[3] /= 255;
+                      }
+                    }
+                  } else {
+                    shapes[i].c.k[0] /= 255;
+                    shapes[i].c.k[1] /= 255;
+                    shapes[i].c.k[2] /= 255;
+                    shapes[i].c.k[3] /= 255;
+                  }
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 4) {
+                  iterateShapes(layers[i].shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkShapes = (function () {
+            var minimumVersion = [4, 4, 18];
+
+            function completeClosingShapes(arr) {
+              var i;
+              var len = arr.length;
+              var j;
+              var jLen;
+              for (i = len - 1; i >= 0; i -= 1) {
+                if (arr[i].ty === 'sh') {
+                  if (arr[i].ks.k.i) {
+                    arr[i].ks.k.c = arr[i].closed;
+                  } else {
+                    jLen = arr[i].ks.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (arr[i].ks.k[j].s) {
+                        arr[i].ks.k[j].s[0].c = arr[i].closed;
+                      }
+                      if (arr[i].ks.k[j].e) {
+                        arr[i].ks.k[j].e[0].c = arr[i].closed;
+                      }
+                    }
+                  }
+                } else if (arr[i].ty === 'gr') {
+                  completeClosingShapes(arr[i].it);
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var layerData;
+              var i;
+              var len = layers.length;
+              var j;
+              var jLen;
+              var k;
+              var kLen;
+              for (i = 0; i < len; i += 1) {
+                layerData = layers[i];
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      maskProps[j].pt.k.c = maskProps[j].cl;
+                    } else {
+                      kLen = maskProps[j].pt.k.length;
+                      for (k = 0; k < kLen; k += 1) {
+                        if (maskProps[j].pt.k[k].s) {
+                          maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 4) {
+                  completeClosingShapes(layerData.shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          function completeData(animationData) {
+            if (animationData.__complete) {
+              return;
+            }
+            checkColors(animationData);
+            checkText(animationData);
+            checkChars(animationData);
+            checkPathProperties(animationData);
+            checkShapes(animationData);
+            completeLayers(animationData.layers, animationData.assets);
+            completeChars(animationData.chars, animationData.assets);
+            animationData.__complete = true;
+          }
+
+          function completeText(data) {
+            if (data.t.a.length === 0 && !('m' in data.t.p)) {
+              // data.singleShape = true;
+            }
+          }
+
+          var moduleOb = {};
+          moduleOb.completeData = completeData;
+          moduleOb.checkColors = checkColors;
+          moduleOb.checkChars = checkChars;
+          moduleOb.checkPathProperties = checkPathProperties;
+          moduleOb.checkShapes = checkShapes;
+          moduleOb.completeLayers = completeLayers;
+
+          return moduleOb;
+        }
+        if (!_workerSelf.dataManager) {
+          _workerSelf.dataManager = dataFunctionManager();
+        }
+
+        if (!_workerSelf.assetLoader) {
+          _workerSelf.assetLoader = (function () {
+            function formatResponse(xhr) {
+              // using typeof doubles the time of execution of this method,
+              // so if available, it's better to use the header to validate the type
+              var contentTypeHeader = xhr.getResponseHeader('content-type');
+              if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
+                return xhr.response;
+              }
+              if (xhr.response && typeof xhr.response === 'object') {
+                return xhr.response;
+              } if (xhr.response && typeof xhr.response === 'string') {
+                return JSON.parse(xhr.response);
+              } if (xhr.responseText) {
+                return JSON.parse(xhr.responseText);
+              }
+              return null;
+            }
+
+            function loadAsset(path, fullPath, callback, errorCallback) {
+              var response;
+              var xhr = new XMLHttpRequest();
+              // set responseType after calling open or IE will break.
+              try {
+                // This crashes on Android WebView prior to KitKat
+                xhr.responseType = 'json';
+              } catch (err) {} // eslint-disable-line no-empty
+              xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4) {
+                  if (xhr.status === 200) {
+                    response = formatResponse(xhr);
+                    callback(response);
+                  } else {
+                    try {
+                      response = formatResponse(xhr);
+                      callback(response);
+                    } catch (err) {
+                      if (errorCallback) {
+                        errorCallback(err);
+                      }
+                    }
+                  }
+                }
+              };
+              try {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), path, true);
+              } catch (error) {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
+              }
+              xhr.send();
+            }
+            return {
+              load: loadAsset,
+            };
+          }());
+        }
+
+        if (e.data.type === 'loadAnimation') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.dataManager.completeData(data);
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        } else if (e.data.type === 'complete') {
+          var animation = e.data.animation;
+          _workerSelf.dataManager.completeData(animation);
+          _workerSelf.postMessage({
+            id: e.data.id,
+            payload: animation,
+            status: 'success',
+          });
+        } else if (e.data.type === 'loadData') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        }
+      });
+
+      workerInstance.onmessage = function (event) {
+        var data = event.data;
+        var id = data.id;
+        var process = processes[id];
+        processes[id] = null;
+        if (data.status === 'success') {
+          process.onComplete(data.payload);
+        } else if (process.onError) {
+          process.onError();
+        }
+      };
+    }
+  }
+
+  function createProcess(onComplete, onError) {
+    _counterId += 1;
+    var id = 'processId_' + _counterId;
+    processes[id] = {
+      onComplete: onComplete,
+      onError: onError,
+    };
+    return id;
+  }
+
+  function loadAnimation(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadAnimation',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function loadData(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadData',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function completeAnimation(anim, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'complete',
+      animation: anim,
+      id: processId,
+    });
+  }
+
+  return {
+    loadAnimation: loadAnimation,
+    loadData: loadData,
+    completeAnimation: completeAnimation,
+  };
+}());
+
+const ImagePreloader = (function () {
+  var proxyImage = (function () {
+    var canvas = createTag('canvas');
+    canvas.width = 1;
+    canvas.height = 1;
+    var ctx = canvas.getContext('2d');
+    ctx.fillStyle = 'rgba(0,0,0,0)';
+    ctx.fillRect(0, 0, 1, 1);
+    return canvas;
+  }());
+
+  function imageLoaded() {
+    this.loadedAssets += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+  function footageLoaded() {
+    this.loadedFootagesCount += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+
+  function getAssetsPath(assetData, assetsPath, originalPath) {
+    var path = '';
+    if (assetData.e) {
+      path = assetData.p;
+    } else if (assetsPath) {
+      var imagePath = assetData.p;
+      if (imagePath.indexOf('images/') !== -1) {
+        imagePath = imagePath.split('/')[1];
+      }
+      path = assetsPath + imagePath;
+    } else {
+      path = originalPath;
+      path += assetData.u ? assetData.u : '';
+      path += assetData.p;
+    }
+    return path;
+  }
+
+  function testImageLoaded(img) {
+    var _count = 0;
+    var intervalId = setInterval(function () {
+      var box = img.getBBox();
+      if (box.width || _count > 500) {
+        this._imageLoaded();
+        clearInterval(intervalId);
+      }
+      _count += 1;
+    }.bind(this), 50);
+  }
+
+  function createImageData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createNS('image');
+    if (isSafari) {
+      this.testImageLoaded(img);
+    } else {
+      img.addEventListener('load', this._imageLoaded, false);
+    }
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
+    if (this._elementHelper.append) {
+      this._elementHelper.append(img);
+    } else {
+      this._elementHelper.appendChild(img);
+    }
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createImgData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createTag('img');
+    img.crossOrigin = 'anonymous';
+    img.addEventListener('load', this._imageLoaded, false);
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.src = path;
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createFootageData(data) {
+    var ob = {
+      assetData: data,
+    };
+    var path = getAssetsPath(data, this.assetsPath, this.path);
+    dataManager.loadData(path, function (footageData) {
+      ob.img = footageData;
+      this._footageLoaded();
+    }.bind(this), function () {
+      ob.img = {};
+      this._footageLoaded();
+    }.bind(this));
+    return ob;
+  }
+
+  function loadAssets(assets, cb) {
+    this.imagesLoadedCb = cb;
+    var i;
+    var len = assets.length;
+    for (i = 0; i < len; i += 1) {
+      if (!assets[i].layers) {
+        if (!assets[i].t || assets[i].t === 'seq') {
+          this.totalImages += 1;
+          this.images.push(this._createImageData(assets[i]));
+        } else if (assets[i].t === 3) {
+          this.totalFootages += 1;
+          this.images.push(this.createFootageData(assets[i]));
+        }
+      }
+    }
+  }
+
+  function setPath(path) {
+    this.path = path || '';
+  }
+
+  function setAssetsPath(path) {
+    this.assetsPath = path || '';
+  }
+
+  function getAsset(assetData) {
+    var i = 0;
+    var len = this.images.length;
+    while (i < len) {
+      if (this.images[i].assetData === assetData) {
+        return this.images[i].img;
+      }
+      i += 1;
+    }
+    return null;
+  }
+
+  function destroy() {
+    this.imagesLoadedCb = null;
+    this.images.length = 0;
+  }
+
+  function loadedImages() {
+    return this.totalImages === this.loadedAssets;
+  }
+
+  function loadedFootages() {
+    return this.totalFootages === this.loadedFootagesCount;
+  }
+
+  function setCacheType(type, elementHelper) {
+    if (type === 'svg') {
+      this._elementHelper = elementHelper;
+      this._createImageData = this.createImageData.bind(this);
+    } else {
+      this._createImageData = this.createImgData.bind(this);
+    }
+  }
+
+  function ImagePreloaderFactory() {
+    this._imageLoaded = imageLoaded.bind(this);
+    this._footageLoaded = footageLoaded.bind(this);
+    this.testImageLoaded = testImageLoaded.bind(this);
+    this.createFootageData = createFootageData.bind(this);
+    this.assetsPath = '';
+    this.path = '';
+    this.totalImages = 0;
+    this.totalFootages = 0;
+    this.loadedAssets = 0;
+    this.loadedFootagesCount = 0;
+    this.imagesLoadedCb = null;
+    this.images = [];
+  }
+
+  ImagePreloaderFactory.prototype = {
+    loadAssets: loadAssets,
+    setAssetsPath: setAssetsPath,
+    setPath: setPath,
+    loadedImages: loadedImages,
+    loadedFootages: loadedFootages,
+    destroy: destroy,
+    getAsset: getAsset,
+    createImgData: createImgData,
+    createImageData: createImageData,
+    imageLoaded: imageLoaded,
+    footageLoaded: footageLoaded,
+    setCacheType: setCacheType,
+  };
+
+  return ImagePreloaderFactory;
+}());
+
+function BaseEvent() {}
+BaseEvent.prototype = {
+  triggerEvent: function (eventName, args) {
+    if (this._cbs[eventName]) {
+      var callbacks = this._cbs[eventName];
+      for (var i = 0; i < callbacks.length; i += 1) {
+        callbacks[i](args);
+      }
+    }
+  },
+  addEventListener: function (eventName, callback) {
+    if (!this._cbs[eventName]) {
+      this._cbs[eventName] = [];
+    }
+    this._cbs[eventName].push(callback);
+
+    return function () {
+      this.removeEventListener(eventName, callback);
+    }.bind(this);
+  },
+  removeEventListener: function (eventName, callback) {
+    if (!callback) {
+      this._cbs[eventName] = null;
+    } else if (this._cbs[eventName]) {
+      var i = 0;
+      var len = this._cbs[eventName].length;
+      while (i < len) {
+        if (this._cbs[eventName][i] === callback) {
+          this._cbs[eventName].splice(i, 1);
+          i -= 1;
+          len -= 1;
+        }
+        i += 1;
+      }
+      if (!this._cbs[eventName].length) {
+        this._cbs[eventName] = null;
+      }
+    }
+  },
+};
+
+const markerParser = (
+
+  function () {
+    function parsePayloadLines(payload) {
+      var lines = payload.split('\r\n');
+      var keys = {};
+      var line;
+      var keysCount = 0;
+      for (var i = 0; i < lines.length; i += 1) {
+        line = lines[i].split(':');
+        if (line.length === 2) {
+          keys[line[0]] = line[1].trim();
+          keysCount += 1;
+        }
+      }
+      if (keysCount === 0) {
+        throw new Error();
+      }
+      return keys;
+    }
+
+    return function (_markers) {
+      var markers = [];
+      for (var i = 0; i < _markers.length; i += 1) {
+        var _marker = _markers[i];
+        var markerData = {
+          time: _marker.tm,
+          duration: _marker.dr,
+        };
+        try {
+          markerData.payload = JSON.parse(_markers[i].cm);
+        } catch (_) {
+          try {
+            markerData.payload = parsePayloadLines(_markers[i].cm);
+          } catch (__) {
+            markerData.payload = {
+              name: _markers[i].cm,
+            };
+          }
+        }
+        markers.push(markerData);
+      }
+      return markers;
+    };
+  }());
+
+const ProjectInterface = (function () {
+  function registerComposition(comp) {
+    this.compositions.push(comp);
+  }
+
+  return function () {
+    function _thisProjectFunction(name) {
+      var i = 0;
+      var len = this.compositions.length;
+      while (i < len) {
+        if (this.compositions[i].data && this.compositions[i].data.nm === name) {
+          if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
+            this.compositions[i].prepareFrame(this.currentFrame);
+          }
+          return this.compositions[i].compInterface;
+        }
+        i += 1;
+      }
+      return null;
+    }
+
+    _thisProjectFunction.compositions = [];
+    _thisProjectFunction.currentFrame = 0;
+
+    _thisProjectFunction.registerComposition = registerComposition;
+
+    return _thisProjectFunction;
+  };
+}());
+
+const renderers = {};
+
+const registerRenderer = (key, value) => {
+  renderers[key] = value;
+};
+
+function getRenderer(key) {
+  return renderers[key];
+}
+
+function getRegisteredRenderer() {
+  // Returns canvas by default for compatibility
+  if (renderers.canvas) {
+    return 'canvas';
+  }
+  // Returns any renderer that is registered
+  for (const key in renderers) {
+    if (renderers[key]) {
+      return key;
+    }
+  }
+  return '';
+}
+
+const AnimationItem = function () {
+  this._cbs = [];
+  this.name = '';
+  this.path = '';
+  this.isLoaded = false;
+  this.currentFrame = 0;
+  this.currentRawFrame = 0;
+  this.firstFrame = 0;
+  this.totalFrames = 0;
+  this.frameRate = 0;
+  this.frameMult = 0;
+  this.playSpeed = 1;
+  this.playDirection = 1;
+  this.playCount = 0;
+  this.animationData = {};
+  this.assets = [];
+  this.isPaused = true;
+  this.autoplay = false;
+  this.loop = true;
+  this.renderer = null;
+  this.animationID = createElementID();
+  this.assetsPath = '';
+  this.timeCompleted = 0;
+  this.segmentPos = 0;
+  this.isSubframeEnabled = getSubframeEnabled();
+  this.segments = [];
+  this._idle = true;
+  this._completedLoop = false;
+  this.projectInterface = ProjectInterface();
+  this.imagePreloader = new ImagePreloader();
+  this.audioController = audioControllerFactory();
+  this.markers = [];
+  this.configAnimation = this.configAnimation.bind(this);
+  this.onSetupError = this.onSetupError.bind(this);
+  this.onSegmentComplete = this.onSegmentComplete.bind(this);
+  this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
+  this.expressionsPlugin = getExpressionsPlugin();
+};
+
+extendPrototype([BaseEvent], AnimationItem);
+
+AnimationItem.prototype.setParams = function (params) {
+  if (params.wrapper || params.container) {
+    this.wrapper = params.wrapper || params.container;
+  }
+  var animType = 'svg';
+  if (params.animType) {
+    animType = params.animType;
+  } else if (params.renderer) {
+    animType = params.renderer;
+  }
+  const RendererClass = getRenderer(animType);
+  this.renderer = new RendererClass(this, params.rendererSettings);
+  this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
+  this.renderer.setProjectInterface(this.projectInterface);
+  this.animType = animType;
+  if (params.loop === ''
+        || params.loop === null
+        || params.loop === undefined
+        || params.loop === true) {
+    this.loop = true;
+  } else if (params.loop === false) {
+    this.loop = false;
+  } else {
+    this.loop = parseInt(params.loop, 10);
+  }
+  this.autoplay = 'autoplay' in params ? params.autoplay : true;
+  this.name = params.name ? params.name : '';
+  this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
+  this.assetsPath = params.assetsPath;
+  this.initialSegment = params.initialSegment;
+  if (params.audioFactory) {
+    this.audioController.setAudioFactory(params.audioFactory);
+  }
+  if (params.animationData) {
+    this.setupAnimation(params.animationData);
+  } else if (params.path) {
+    if (params.path.lastIndexOf('\\') !== -1) {
+      this.path = params.path.substr(0, params.path.lastIndexOf('\\') + 1);
+    } else {
+      this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
+    }
+    this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
+    this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
+    dataManager.loadAnimation(
+      params.path,
+      this.configAnimation,
+      this.onSetupError
+    );
+  }
+};
+
+AnimationItem.prototype.onSetupError = function () {
+  this.trigger('data_failed');
+};
+
+AnimationItem.prototype.setupAnimation = function (data) {
+  dataManager.completeAnimation(
+    data,
+    this.configAnimation
+  );
+};
+
+AnimationItem.prototype.setData = function (wrapper, animationData) {
+  if (animationData) {
+    if (typeof animationData !== 'object') {
+      animationData = JSON.parse(animationData);
+    }
+  }
+  var params = {
+    wrapper: wrapper,
+    animationData: animationData,
+  };
+  var wrapperAttributes = wrapper.attributes;
+
+  params.path = wrapperAttributes.getNamedItem('data-animation-path') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-animation-path').value
+    : wrapperAttributes.getNamedItem('data-bm-path') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-path').value
+      : wrapperAttributes.getNamedItem('bm-path')
+        ? wrapperAttributes.getNamedItem('bm-path').value
+        : '';
+  params.animType = wrapperAttributes.getNamedItem('data-anim-type') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-type').value
+    : wrapperAttributes.getNamedItem('data-bm-type') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-type').value
+      : wrapperAttributes.getNamedItem('bm-type') // eslint-disable-line no-nested-ternary
+        ? wrapperAttributes.getNamedItem('bm-type').value
+        : wrapperAttributes.getNamedItem('data-bm-renderer') // eslint-disable-line no-nested-ternary
+          ? wrapperAttributes.getNamedItem('data-bm-renderer').value
+          : wrapperAttributes.getNamedItem('bm-renderer')
+            ? wrapperAttributes.getNamedItem('bm-renderer').value
+            : getRegisteredRenderer() || 'canvas';
+
+  var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-loop').value
+    : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-loop').value
+      : wrapperAttributes.getNamedItem('bm-loop')
+        ? wrapperAttributes.getNamedItem('bm-loop').value
+        : '';
+  if (loop === 'false') {
+    params.loop = false;
+  } else if (loop === 'true') {
+    params.loop = true;
+  } else if (loop !== '') {
+    params.loop = parseInt(loop, 10);
+  }
+  var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-autoplay').value
+    : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-autoplay').value
+      : wrapperAttributes.getNamedItem('bm-autoplay')
+        ? wrapperAttributes.getNamedItem('bm-autoplay').value
+        : true;
+  params.autoplay = autoplay !== 'false';
+
+  params.name = wrapperAttributes.getNamedItem('data-name') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-name').value
+    : wrapperAttributes.getNamedItem('data-bm-name') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-name').value
+      : wrapperAttributes.getNamedItem('bm-name')
+        ? wrapperAttributes.getNamedItem('bm-name').value
+        : '';
+  var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-prerender').value
+    : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-prerender').value
+      : wrapperAttributes.getNamedItem('bm-prerender')
+        ? wrapperAttributes.getNamedItem('bm-prerender').value
+        : '';
+
+  if (prerender === 'false') {
+    params.prerender = false;
+  }
+  if (!params.path) {
+    this.trigger('destroy');
+  } else {
+    this.setParams(params);
+  }
+};
+
+AnimationItem.prototype.includeLayers = function (data) {
+  if (data.op > this.animationData.op) {
+    this.animationData.op = data.op;
+    this.totalFrames = Math.floor(data.op - this.animationData.ip);
+  }
+  var layers = this.animationData.layers;
+  var i;
+  var len = layers.length;
+  var newLayers = data.layers;
+  var j;
+  var jLen = newLayers.length;
+  for (j = 0; j < jLen; j += 1) {
+    i = 0;
+    while (i < len) {
+      if (layers[i].id === newLayers[j].id) {
+        layers[i] = newLayers[j];
+        break;
+      }
+      i += 1;
+    }
+  }
+  if (data.chars || data.fonts) {
+    this.renderer.globalData.fontManager.addChars(data.chars);
+    this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
+  }
+  if (data.assets) {
+    len = data.assets.length;
+    for (i = 0; i < len; i += 1) {
+      this.animationData.assets.push(data.assets[i]);
+    }
+  }
+  this.animationData.__complete = false;
+  dataManager.completeAnimation(
+    this.animationData,
+    this.onSegmentComplete
+  );
+};
+
+AnimationItem.prototype.onSegmentComplete = function (data) {
+  this.animationData = data;
+  var expressionsPlugin = getExpressionsPlugin();
+  if (expressionsPlugin) {
+    expressionsPlugin.initExpressions(this);
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.loadNextSegment = function () {
+  var segments = this.animationData.segments;
+  if (!segments || segments.length === 0 || !this.autoloadSegments) {
+    this.trigger('data_ready');
+    this.timeCompleted = this.totalFrames;
+    return;
+  }
+  var segment = segments.shift();
+  this.timeCompleted = segment.time * this.frameRate;
+  var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
+  this.segmentPos += 1;
+  dataManager.loadData(segmentPath, this.includeLayers.bind(this), function () {
+    this.trigger('data_failed');
+  }.bind(this));
+};
+
+AnimationItem.prototype.loadSegments = function () {
+  var segments = this.animationData.segments;
+  if (!segments) {
+    this.timeCompleted = this.totalFrames;
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.imagesLoaded = function () {
+  this.trigger('loaded_images');
+  this.checkLoaded();
+};
+
+AnimationItem.prototype.preloadImages = function () {
+  this.imagePreloader.setAssetsPath(this.assetsPath);
+  this.imagePreloader.setPath(this.path);
+  this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
+};
+
+AnimationItem.prototype.configAnimation = function (animData) {
+  if (!this.renderer) {
+    return;
+  }
+  try {
+    this.animationData = animData;
+    if (this.initialSegment) {
+      this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
+      this.firstFrame = Math.round(this.initialSegment[0]);
+    } else {
+      this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
+      this.firstFrame = Math.round(this.animationData.ip);
+    }
+    this.renderer.configAnimation(animData);
+    if (!animData.assets) {
+      animData.assets = [];
+    }
+
+    this.assets = this.animationData.assets;
+    this.frameRate = this.animationData.fr;
+    this.frameMult = this.animationData.fr / 1000;
+    this.renderer.searchExtraCompositions(animData.assets);
+    this.markers = markerParser(animData.markers || []);
+    this.trigger('config_ready');
+    this.preloadImages();
+    this.loadSegments();
+    this.updaFrameModifier();
+    this.waitForFontsLoaded();
+    if (this.isPaused) {
+      this.audioController.pause();
+    }
+  } catch (error) {
+    this.triggerConfigError(error);
+  }
+};
+
+AnimationItem.prototype.waitForFontsLoaded = function () {
+  if (!this.renderer) {
+    return;
+  }
+  if (this.renderer.globalData.fontManager.isLoaded) {
+    this.checkLoaded();
+  } else {
+    setTimeout(this.waitForFontsLoaded.bind(this), 20);
+  }
+};
+
+AnimationItem.prototype.checkLoaded = function () {
+  if (!this.isLoaded
+        && this.renderer.globalData.fontManager.isLoaded
+        && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas')
+        && (this.imagePreloader.loadedFootages())
+  ) {
+    this.isLoaded = true;
+    var expressionsPlugin = getExpressionsPlugin();
+    if (expressionsPlugin) {
+      expressionsPlugin.initExpressions(this);
+    }
+    this.renderer.initItems();
+    setTimeout(function () {
+      this.trigger('DOMLoaded');
+    }.bind(this), 0);
+    this.gotoFrame();
+    if (this.autoplay) {
+      this.play();
+    }
+  }
+};
+
+AnimationItem.prototype.resize = function (width, height) {
+  // Adding this validation for backwards compatibility in case an event object was being passed down
+  var _width = typeof width === 'number' ? width : undefined;
+  var _height = typeof height === 'number' ? height : undefined;
+  this.renderer.updateContainerSize(_width, _height);
+};
+
+AnimationItem.prototype.setSubframe = function (flag) {
+  this.isSubframeEnabled = !!flag;
+};
+
+AnimationItem.prototype.gotoFrame = function () {
+  this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
+
+  if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
+    this.currentFrame = this.timeCompleted;
+  }
+  this.trigger('enterFrame');
+  this.renderFrame();
+  this.trigger('drawnFrame');
+};
+
+AnimationItem.prototype.renderFrame = function () {
+  if (this.isLoaded === false || !this.renderer) {
+    return;
+  }
+  try {
+    if (this.expressionsPlugin) {
+      this.expressionsPlugin.resetFrame();
+    }
+    this.renderer.renderFrame(this.currentFrame + this.firstFrame);
+  } catch (error) {
+    this.triggerRenderFrameError(error);
+  }
+};
+
+AnimationItem.prototype.play = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.isPaused = false;
+    this.trigger('_play');
+    this.audioController.resume();
+    if (this._idle) {
+      this._idle = false;
+      this.trigger('_active');
+    }
+  }
+};
+
+AnimationItem.prototype.pause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === false) {
+    this.isPaused = true;
+    this.trigger('_pause');
+    this._idle = true;
+    this.trigger('_idle');
+    this.audioController.pause();
+  }
+};
+
+AnimationItem.prototype.togglePause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.play();
+  } else {
+    this.pause();
+  }
+};
+
+AnimationItem.prototype.stop = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.pause();
+  this.playCount = 0;
+  this._completedLoop = false;
+  this.setCurrentRawFrameValue(0);
+};
+
+AnimationItem.prototype.getMarkerData = function (markerName) {
+  var marker;
+  for (var i = 0; i < this.markers.length; i += 1) {
+    marker = this.markers[i];
+    if (marker.payload && marker.payload.name === markerName) {
+      return marker;
+    }
+  }
+  return null;
+};
+
+AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      this.goToAndStop(marker.time, true);
+    }
+  } else if (isFrame) {
+    this.setCurrentRawFrameValue(value);
+  } else {
+    this.setCurrentRawFrameValue(value * this.frameModifier);
+  }
+  this.pause();
+};
+
+AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      if (!marker.duration) {
+        this.goToAndStop(marker.time, true);
+      } else {
+        this.playSegments([marker.time, marker.time + marker.duration], true);
+      }
+    }
+  } else {
+    this.goToAndStop(numValue, isFrame, name);
+  }
+  this.play();
+};
+
+AnimationItem.prototype.advanceTime = function (value) {
+  if (this.isPaused === true || this.isLoaded === false) {
+    return;
+  }
+  var nextValue = this.currentRawFrame + value * this.frameModifier;
+  var _isComplete = false;
+  // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+  // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
+  if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
+    if (!this.loop || this.playCount === this.loop) {
+      if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
+        _isComplete = true;
+        nextValue = this.totalFrames - 1;
+      }
+    } else if (nextValue >= this.totalFrames) {
+      this.playCount += 1;
+      if (!this.checkSegments(nextValue % this.totalFrames)) {
+        this.setCurrentRawFrameValue(nextValue % this.totalFrames);
+        this._completedLoop = true;
+        this.trigger('loopComplete');
+      }
+    } else {
+      this.setCurrentRawFrameValue(nextValue);
+    }
+  } else if (nextValue < 0) {
+    if (!this.checkSegments(nextValue % this.totalFrames)) {
+      if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) { // eslint-disable-line no-plusplus
+        this.setCurrentRawFrameValue(this.totalFrames + (nextValue % this.totalFrames));
+        if (!this._completedLoop) {
+          this._completedLoop = true;
+        } else {
+          this.trigger('loopComplete');
+        }
+      } else {
+        _isComplete = true;
+        nextValue = 0;
+      }
+    }
+  } else {
+    this.setCurrentRawFrameValue(nextValue);
+  }
+  if (_isComplete) {
+    this.setCurrentRawFrameValue(nextValue);
+    this.pause();
+    this.trigger('complete');
+  }
+};
+
+AnimationItem.prototype.adjustSegment = function (arr, offset) {
+  this.playCount = 0;
+  if (arr[1] < arr[0]) {
+    if (this.frameModifier > 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(-1);
+      }
+    }
+    this.totalFrames = arr[0] - arr[1];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[1];
+    this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset);
+  } else if (arr[1] > arr[0]) {
+    if (this.frameModifier < 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(1);
+      }
+    }
+    this.totalFrames = arr[1] - arr[0];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[0];
+    this.setCurrentRawFrameValue(0.001 + offset);
+  }
+  this.trigger('segmentStart');
+};
+AnimationItem.prototype.setSegment = function (init, end) {
+  var pendingFrame = -1;
+  if (this.isPaused) {
+    if (this.currentRawFrame + this.firstFrame < init) {
+      pendingFrame = init;
+    } else if (this.currentRawFrame + this.firstFrame > end) {
+      pendingFrame = end - init;
+    }
+  }
+
+  this.firstFrame = init;
+  this.totalFrames = end - init;
+  this.timeCompleted = this.totalFrames;
+  if (pendingFrame !== -1) {
+    this.goToAndStop(pendingFrame, true);
+  }
+};
+
+AnimationItem.prototype.playSegments = function (arr, forceFlag) {
+  if (forceFlag) {
+    this.segments.length = 0;
+  }
+  if (typeof arr[0] === 'object') {
+    var i;
+    var len = arr.length;
+    for (i = 0; i < len; i += 1) {
+      this.segments.push(arr[i]);
+    }
+  } else {
+    this.segments.push(arr);
+  }
+  if (this.segments.length && forceFlag) {
+    this.adjustSegment(this.segments.shift(), 0);
+  }
+  if (this.isPaused) {
+    this.play();
+  }
+};
+
+AnimationItem.prototype.resetSegments = function (forceFlag) {
+  this.segments.length = 0;
+  this.segments.push([this.animationData.ip, this.animationData.op]);
+  if (forceFlag) {
+    this.checkSegments(0);
+  }
+};
+AnimationItem.prototype.checkSegments = function (offset) {
+  if (this.segments.length) {
+    this.adjustSegment(this.segments.shift(), offset);
+    return true;
+  }
+  return false;
+};
+
+AnimationItem.prototype.destroy = function (name) {
+  if ((name && this.name !== name) || !this.renderer) {
+    return;
+  }
+  this.renderer.destroy();
+  this.imagePreloader.destroy();
+  this.trigger('destroy');
+  this._cbs = null;
+  this.onEnterFrame = null;
+  this.onLoopComplete = null;
+  this.onComplete = null;
+  this.onSegmentStart = null;
+  this.onDestroy = null;
+  this.renderer = null;
+  this.expressionsPlugin = null;
+  this.imagePreloader = null;
+  this.projectInterface = null;
+};
+
+AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
+  this.currentRawFrame = value;
+  this.gotoFrame();
+};
+
+AnimationItem.prototype.setSpeed = function (val) {
+  this.playSpeed = val;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setDirection = function (val) {
+  this.playDirection = val < 0 ? -1 : 1;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setLoop = function (isLooping) {
+  this.loop = isLooping;
+};
+
+AnimationItem.prototype.setVolume = function (val, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.setVolume(val);
+};
+
+AnimationItem.prototype.getVolume = function () {
+  return this.audioController.getVolume();
+};
+
+AnimationItem.prototype.mute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.mute();
+};
+
+AnimationItem.prototype.unmute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.unmute();
+};
+
+AnimationItem.prototype.updaFrameModifier = function () {
+  this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
+  this.audioController.setRate(this.playSpeed * this.playDirection);
+};
+
+AnimationItem.prototype.getPath = function () {
+  return this.path;
+};
+
+AnimationItem.prototype.getAssetsPath = function (assetData) {
+  var path = '';
+  if (assetData.e) {
+    path = assetData.p;
+  } else if (this.assetsPath) {
+    var imagePath = assetData.p;
+    if (imagePath.indexOf('images/') !== -1) {
+      imagePath = imagePath.split('/')[1];
+    }
+    path = this.assetsPath + imagePath;
+  } else {
+    path = this.path;
+    path += assetData.u ? assetData.u : '';
+    path += assetData.p;
+  }
+  return path;
+};
+
+AnimationItem.prototype.getAssetData = function (id) {
+  var i = 0;
+  var len = this.assets.length;
+  while (i < len) {
+    if (id === this.assets[i].id) {
+      return this.assets[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+AnimationItem.prototype.hide = function () {
+  this.renderer.hide();
+};
+
+AnimationItem.prototype.show = function () {
+  this.renderer.show();
+};
+
+AnimationItem.prototype.getDuration = function (isFrame) {
+  return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
+};
+
+AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
+  try {
+    var element = this.renderer.getElementByPath(path);
+    element.updateDocumentData(documentData, index);
+  } catch (error) {
+    // TODO: decide how to handle catch case
+  }
+};
+
+AnimationItem.prototype.trigger = function (name) {
+  if (this._cbs && this._cbs[name]) {
+    switch (name) {
+      case 'enterFrame':
+        this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
+        break;
+      case 'drawnFrame':
+        this.drawnFrameEvent.currentTime = this.currentFrame;
+        this.drawnFrameEvent.totalTime = this.totalFrames;
+        this.drawnFrameEvent.direction = this.frameModifier;
+        this.triggerEvent(name, this.drawnFrameEvent);
+        break;
+      case 'loopComplete':
+        this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+        break;
+      case 'complete':
+        this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
+        break;
+      case 'segmentStart':
+        this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+        break;
+      case 'destroy':
+        this.triggerEvent(name, new BMDestroyEvent(name, this));
+        break;
+      default:
+        this.triggerEvent(name);
+    }
+  }
+  if (name === 'enterFrame' && this.onEnterFrame) {
+    this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
+  }
+  if (name === 'loopComplete' && this.onLoopComplete) {
+    this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+  }
+  if (name === 'complete' && this.onComplete) {
+    this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
+  }
+  if (name === 'segmentStart' && this.onSegmentStart) {
+    this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+  }
+  if (name === 'destroy' && this.onDestroy) {
+    this.onDestroy.call(this, new BMDestroyEvent(name, this));
+  }
+};
+
+AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
+  var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+AnimationItem.prototype.triggerConfigError = function (nativeError) {
+  var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+const animationManager = (function () {
+  var moduleOb = {};
+  var registeredAnimations = [];
+  var initTime = 0;
+  var len = 0;
+  var playingAnimationsNum = 0;
+  var _stopped = true;
+  var _isFrozen = false;
+
+  function removeElement(ev) {
+    var i = 0;
+    var animItem = ev.target;
+    while (i < len) {
+      if (registeredAnimations[i].animation === animItem) {
+        registeredAnimations.splice(i, 1);
+        i -= 1;
+        len -= 1;
+        if (!animItem.isPaused) {
+          subtractPlayingCount();
+        }
+      }
+      i += 1;
+    }
+  }
+
+  function registerAnimation(element, animationData) {
+    if (!element) {
+      return null;
+    }
+    var i = 0;
+    while (i < len) {
+      if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
+        return registeredAnimations[i].animation;
+      }
+      i += 1;
+    }
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, element);
+    animItem.setData(element, animationData);
+    return animItem;
+  }
+
+  function getRegisteredAnimations() {
+    var i;
+    var lenAnims = registeredAnimations.length;
+    var animations = [];
+    for (i = 0; i < lenAnims; i += 1) {
+      animations.push(registeredAnimations[i].animation);
+    }
+    return animations;
+  }
+
+  function addPlayingCount() {
+    playingAnimationsNum += 1;
+    activate();
+  }
+
+  function subtractPlayingCount() {
+    playingAnimationsNum -= 1;
+  }
+
+  function setupAnimation(animItem, element) {
+    animItem.addEventListener('destroy', removeElement);
+    animItem.addEventListener('_active', addPlayingCount);
+    animItem.addEventListener('_idle', subtractPlayingCount);
+    registeredAnimations.push({ elem: element, animation: animItem });
+    len += 1;
+  }
+
+  function loadAnimation(params) {
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, null);
+    animItem.setParams(params);
+    return animItem;
+  }
+
+  function setSpeed(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setSpeed(val, animation);
+    }
+  }
+
+  function setDirection(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setDirection(val, animation);
+    }
+  }
+
+  function play(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.play(animation);
+    }
+  }
+  function resume(nowTime) {
+    var elapsedTime = nowTime - initTime;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.advanceTime(elapsedTime);
+    }
+    initTime = nowTime;
+    if (playingAnimationsNum && !_isFrozen) {
+      window.requestAnimationFrame(resume);
+    } else {
+      _stopped = true;
+    }
+  }
+
+  function first(nowTime) {
+    initTime = nowTime;
+    window.requestAnimationFrame(resume);
+  }
+
+  function pause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.pause(animation);
+    }
+  }
+
+  function goToAndStop(value, isFrame, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
+    }
+  }
+
+  function stop(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.stop(animation);
+    }
+  }
+
+  function togglePause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.togglePause(animation);
+    }
+  }
+
+  function destroy(animation) {
+    var i;
+    for (i = (len - 1); i >= 0; i -= 1) {
+      registeredAnimations[i].animation.destroy(animation);
+    }
+  }
+
+  function searchAnimations(animationData, standalone, renderer) {
+    var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')),
+      [].slice.call(document.getElementsByClassName('bodymovin')));
+    var i;
+    var lenAnims = animElements.length;
+    for (i = 0; i < lenAnims; i += 1) {
+      if (renderer) {
+        animElements[i].setAttribute('data-bm-type', renderer);
+      }
+      registerAnimation(animElements[i], animationData);
+    }
+    if (standalone && lenAnims === 0) {
+      if (!renderer) {
+        renderer = 'svg';
+      }
+      var body = document.getElementsByTagName('body')[0];
+      body.innerText = '';
+      var div = createTag('div');
+      div.style.width = '100%';
+      div.style.height = '100%';
+      div.setAttribute('data-bm-type', renderer);
+      body.appendChild(div);
+      registerAnimation(div, animationData);
+    }
+  }
+
+  function resize() {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.resize();
+    }
+  }
+
+  function activate() {
+    if (!_isFrozen && playingAnimationsNum) {
+      if (_stopped) {
+        window.requestAnimationFrame(first);
+        _stopped = false;
+      }
+    }
+  }
+
+  function freeze() {
+    _isFrozen = true;
+  }
+
+  function unfreeze() {
+    _isFrozen = false;
+    activate();
+  }
+
+  function setVolume(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setVolume(val, animation);
+    }
+  }
+
+  function mute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.mute(animation);
+    }
+  }
+
+  function unmute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.unmute(animation);
+    }
+  }
+
+  moduleOb.registerAnimation = registerAnimation;
+  moduleOb.loadAnimation = loadAnimation;
+  moduleOb.setSpeed = setSpeed;
+  moduleOb.setDirection = setDirection;
+  moduleOb.play = play;
+  moduleOb.pause = pause;
+  moduleOb.stop = stop;
+  moduleOb.togglePause = togglePause;
+  moduleOb.searchAnimations = searchAnimations;
+  moduleOb.resize = resize;
+  // moduleOb.start = start;
+  moduleOb.goToAndStop = goToAndStop;
+  moduleOb.destroy = destroy;
+  moduleOb.freeze = freeze;
+  moduleOb.unfreeze = unfreeze;
+  moduleOb.setVolume = setVolume;
+  moduleOb.mute = mute;
+  moduleOb.unmute = unmute;
+  moduleOb.getRegisteredAnimations = getRegisteredAnimations;
+  return moduleOb;
+}());
+
+/* eslint-disable */
+const BezierFactory = (function () {
+  /**
+     * BezierEasing - use bezier curve for transition easing function
+     * by Gaëtan Renaudeau 2014 - 2015 – MIT License
+     *
+     * Credits: is based on Firefox's nsSMILKeySpline.cpp
+     * Usage:
+     * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
+     * spline.get(x) => returns the easing value | x must be in [0, 1] range
+     *
+     */
+
+  var ob = {};
+  ob.getBezierEasing = getBezierEasing;
+  var beziers = {};
+
+  function getBezierEasing(a, b, c, d, nm) {
+    var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
+    if (beziers[str]) {
+      return beziers[str];
+    }
+    var bezEasing = new BezierEasing([a, b, c, d]);
+    beziers[str] = bezEasing;
+    return bezEasing;
+  }
+
+  // These values are established by empiricism with tests (tradeoff: performance VS precision)
+  var NEWTON_ITERATIONS = 4;
+  var NEWTON_MIN_SLOPE = 0.001;
+  var SUBDIVISION_PRECISION = 0.0000001;
+  var SUBDIVISION_MAX_ITERATIONS = 10;
+
+  var kSplineTableSize = 11;
+  var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
+
+  var float32ArraySupported = typeof Float32Array === 'function';
+
+  function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
+  function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
+  function C(aA1) { return 3.0 * aA1; }
+
+  // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+  function calcBezier(aT, aA1, aA2) {
+    return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
+  }
+
+  // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+  function getSlope(aT, aA1, aA2) {
+    return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
+  }
+
+  function binarySubdivide(aX, aA, aB, mX1, mX2) {
+    var currentX,
+      currentT,
+      i = 0;
+    do {
+      currentT = aA + (aB - aA) / 2.0;
+      currentX = calcBezier(currentT, mX1, mX2) - aX;
+      if (currentX > 0.0) {
+        aB = currentT;
+      } else {
+        aA = currentT;
+      }
+    } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
+    return currentT;
+  }
+
+  function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
+    for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
+      var currentSlope = getSlope(aGuessT, mX1, mX2);
+      if (currentSlope === 0.0) return aGuessT;
+      var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
+      aGuessT -= currentX / currentSlope;
+    }
+    return aGuessT;
+  }
+
+  /**
+     * points is an array of [ mX1, mY1, mX2, mY2 ]
+     */
+  function BezierEasing(points) {
+    this._p = points;
+    this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
+    this._precomputed = false;
+
+    this.get = this.get.bind(this);
+  }
+
+  BezierEasing.prototype = {
+
+    get: function (x) {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      if (!this._precomputed) this._precompute();
+      if (mX1 === mY1 && mX2 === mY2) return x; // linear
+      // Because JavaScript number are imprecise, we should guarantee the extremes are right.
+      if (x === 0) return 0;
+      if (x === 1) return 1;
+      return calcBezier(this._getTForX(x), mY1, mY2);
+    },
+
+    // Private part
+
+    _precompute: function () {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      this._precomputed = true;
+      if (mX1 !== mY1 || mX2 !== mY2) { this._calcSampleValues(); }
+    },
+
+    _calcSampleValues: function () {
+      var mX1 = this._p[0],
+        mX2 = this._p[2];
+      for (var i = 0; i < kSplineTableSize; ++i) {
+        this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
+      }
+    },
+
+    /**
+         * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
+         */
+    _getTForX: function (aX) {
+      var mX1 = this._p[0],
+        mX2 = this._p[2],
+        mSampleValues = this._mSampleValues;
+
+      var intervalStart = 0.0;
+      var currentSample = 1;
+      var lastSample = kSplineTableSize - 1;
+
+      for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
+        intervalStart += kSampleStepSize;
+      }
+      --currentSample;
+
+      // Interpolate to provide an initial guess for t
+      var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
+      var guessForT = intervalStart + dist * kSampleStepSize;
+
+      var initialSlope = getSlope(guessForT, mX1, mX2);
+      if (initialSlope >= NEWTON_MIN_SLOPE) {
+        return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
+      } if (initialSlope === 0.0) {
+        return guessForT;
+      }
+      return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
+    },
+  };
+
+  return ob;
+}());
+
+const pooling = (function () {
+  function double(arr) {
+    return arr.concat(createSizedArray(arr.length));
+  }
+
+  return {
+    double: double,
+  };
+}());
+
+const poolFactory = (function () {
+  return function (initialLength, _create, _release) {
+    var _length = 0;
+    var _maxLength = initialLength;
+    var pool = createSizedArray(_maxLength);
+
+    var ob = {
+      newElement: newElement,
+      release: release,
+    };
+
+    function newElement() {
+      var element;
+      if (_length) {
+        _length -= 1;
+        element = pool[_length];
+      } else {
+        element = _create();
+      }
+      return element;
+    }
+
+    function release(element) {
+      if (_length === _maxLength) {
+        pool = pooling.double(pool);
+        _maxLength *= 2;
+      }
+      if (_release) {
+        _release(element);
+      }
+      pool[_length] = element;
+      _length += 1;
+    }
+
+    return ob;
+  };
+}());
+
+const bezierLengthPool = (function () {
+  function create() {
+    return {
+      addedLength: 0,
+      percents: createTypedArray('float32', getDefaultCurveSegments()),
+      lengths: createTypedArray('float32', getDefaultCurveSegments()),
+    };
+  }
+  return poolFactory(8, create);
+}());
+
+const segmentsLengthPool = (function () {
+  function create() {
+    return {
+      lengths: [],
+      totalLength: 0,
+    };
+  }
+
+  function release(element) {
+    var i;
+    var len = element.lengths.length;
+    for (i = 0; i < len; i += 1) {
+      bezierLengthPool.release(element.lengths[i]);
+    }
+    element.lengths.length = 0;
+  }
+
+  return poolFactory(8, create, release);
+}());
+
+function bezFunction() {
+  var math = Math;
+
+  function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
+    var det1 = (x1 * y2) + (y1 * x3) + (x2 * y3) - (x3 * y2) - (y3 * x1) - (x2 * y1);
+    return det1 > -0.001 && det1 < 0.001;
+  }
+
+  function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
+    if (z1 === 0 && z2 === 0 && z3 === 0) {
+      return pointOnLine2D(x1, y1, x2, y2, x3, y3);
+    }
+    var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
+    var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
+    var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
+    var diffDist;
+    if (dist1 > dist2) {
+      if (dist1 > dist3) {
+        diffDist = dist1 - dist2 - dist3;
+      } else {
+        diffDist = dist3 - dist2 - dist1;
+      }
+    } else if (dist3 > dist2) {
+      diffDist = dist3 - dist2 - dist1;
+    } else {
+      diffDist = dist2 - dist1 - dist3;
+    }
+    return diffDist > -0.0001 && diffDist < 0.0001;
+  }
+
+  var getBezierLength = (function () {
+    return function (pt1, pt2, pt3, pt4) {
+      var curveSegments = getDefaultCurveSegments();
+      var k;
+      var i;
+      var len;
+      var ptCoord;
+      var perc;
+      var addedLength = 0;
+      var ptDistance;
+      var point = [];
+      var lastPoint = [];
+      var lengthData = bezierLengthPool.newElement();
+      len = pt3.length;
+      for (k = 0; k < curveSegments; k += 1) {
+        perc = k / (curveSegments - 1);
+        ptDistance = 0;
+        for (i = 0; i < len; i += 1) {
+          ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
+          point[i] = ptCoord;
+          if (lastPoint[i] !== null) {
+            ptDistance += bmPow(point[i] - lastPoint[i], 2);
+          }
+          lastPoint[i] = point[i];
+        }
+        if (ptDistance) {
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+        }
+        lengthData.percents[k] = perc;
+        lengthData.lengths[k] = addedLength;
+      }
+      lengthData.addedLength = addedLength;
+      return lengthData;
+    };
+  }());
+
+  function getSegmentsLength(shapeData) {
+    var segmentsLength = segmentsLengthPool.newElement();
+    var closed = shapeData.c;
+    var pathV = shapeData.v;
+    var pathO = shapeData.o;
+    var pathI = shapeData.i;
+    var i;
+    var len = shapeData._length;
+    var lengths = segmentsLength.lengths;
+    var totalLength = 0;
+    for (i = 0; i < len - 1; i += 1) {
+      lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
+      totalLength += lengths[i].addedLength;
+    }
+    if (closed && len) {
+      lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
+      totalLength += lengths[i].addedLength;
+    }
+    segmentsLength.totalLength = totalLength;
+    return segmentsLength;
+  }
+
+  function BezierData(length) {
+    this.segmentLength = 0;
+    this.points = new Array(length);
+  }
+
+  function PointData(partial, point) {
+    this.partialLength = partial;
+    this.point = point;
+  }
+
+  var buildBezierData = (function () {
+    var storedData = {};
+
+    return function (pt1, pt2, pt3, pt4) {
+      var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
+      if (!storedData[bezierName]) {
+        var curveSegments = getDefaultCurveSegments();
+        var k;
+        var i;
+        var len;
+        var ptCoord;
+        var perc;
+        var addedLength = 0;
+        var ptDistance;
+        var point;
+        var lastPoint = null;
+        if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
+          curveSegments = 2;
+        }
+        var bezierData = new BezierData(curveSegments);
+        len = pt3.length;
+        for (k = 0; k < curveSegments; k += 1) {
+          point = createSizedArray(len);
+          perc = k / (curveSegments - 1);
+          ptDistance = 0;
+          for (i = 0; i < len; i += 1) {
+            ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
+            point[i] = ptCoord;
+            if (lastPoint !== null) {
+              ptDistance += bmPow(point[i] - lastPoint[i], 2);
+            }
+          }
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+          bezierData.points[k] = new PointData(ptDistance, point);
+          lastPoint = point;
+        }
+        bezierData.segmentLength = addedLength;
+        storedData[bezierName] = bezierData;
+      }
+      return storedData[bezierName];
+    };
+  }());
+
+  function getDistancePerc(perc, bezierData) {
+    var percents = bezierData.percents;
+    var lengths = bezierData.lengths;
+    var len = percents.length;
+    var initPos = bmFloor((len - 1) * perc);
+    var lengthPos = perc * bezierData.addedLength;
+    var lPerc = 0;
+    if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
+      return percents[initPos];
+    }
+    var dir = lengths[initPos] > lengthPos ? -1 : 1;
+    var flag = true;
+    while (flag) {
+      if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
+        lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
+        flag = false;
+      } else {
+        initPos += dir;
+      }
+      if (initPos < 0 || initPos >= len - 1) {
+        // FIX for TypedArrays that don't store floating point values with enough accuracy
+        if (initPos === len - 1) {
+          return percents[initPos];
+        }
+        flag = false;
+      }
+    }
+    return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
+  }
+
+  function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
+    var t1 = getDistancePerc(percent, bezierData);
+    var u1 = 1 - t1;
+    var ptX = math.round((u1 * u1 * u1 * pt1[0] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[0] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[0] + t1 * t1 * t1 * pt2[0]) * 1000) / 1000;
+    var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
+    return [ptX, ptY];
+  }
+
+  var bezierSegmentPoints = createTypedArray('float32', 8);
+
+  function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
+    if (startPerc < 0) {
+      startPerc = 0;
+    } else if (startPerc > 1) {
+      startPerc = 1;
+    }
+    var t0 = getDistancePerc(startPerc, bezierData);
+    endPerc = endPerc > 1 ? 1 : endPerc;
+    var t1 = getDistancePerc(endPerc, bezierData);
+    var i;
+    var len = pt1.length;
+    var u0 = 1 - t0;
+    var u1 = 1 - t1;
+    var u0u0u0 = u0 * u0 * u0;
+    var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0t0 = t0 * t0 * t0;
+    //
+    var u0u0u1 = u0 * u0 * u1;
+    var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0t1 = t0 * t0 * t1;
+    //
+    var u0u1u1 = u0 * u1 * u1;
+    var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1t1 = t0 * t1 * t1;
+    //
+    var u1u1u1 = u1 * u1 * u1;
+    var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1t1 = t1 * t1 * t1;
+    for (i = 0; i < len; i += 1) {
+      bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+    }
+
+    return bezierSegmentPoints;
+  }
+
+  return {
+    getSegmentsLength: getSegmentsLength,
+    getNewSegment: getNewSegment,
+    getPointInSegment: getPointInSegment,
+    buildBezierData: buildBezierData,
+    pointOnLine2D: pointOnLine2D,
+    pointOnLine3D: pointOnLine3D,
+  };
+}
+
+const bez = bezFunction();
+
+var initFrame = initialDefaultFrame;
+var mathAbs = Math.abs;
+
+function interpolateValue(frameNum, caching) {
+  var offsetTime = this.offsetTime;
+  var newValue;
+  if (this.propType === 'multidimensional') {
+    newValue = createTypedArray('float32', this.pv.length);
+  }
+  var iterationIndex = caching.lastIndex;
+  var i = iterationIndex;
+  var len = this.keyframes.length - 1;
+  var flag = true;
+  var keyData;
+  var nextKeyData;
+  var keyframeMetadata;
+
+  while (flag) {
+    keyData = this.keyframes[i];
+    nextKeyData = this.keyframes[i + 1];
+    if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
+      if (keyData.h) {
+        keyData = nextKeyData;
+      }
+      iterationIndex = 0;
+      break;
+    }
+    if ((nextKeyData.t - offsetTime) > frameNum) {
+      iterationIndex = i;
+      break;
+    }
+    if (i < len - 1) {
+      i += 1;
+    } else {
+      iterationIndex = 0;
+      flag = false;
+    }
+  }
+  keyframeMetadata = this.keyframesMetadata[i] || {};
+
+  var k;
+  var kLen;
+  var perc;
+  var jLen;
+  var j;
+  var fnc;
+  var nextKeyTime = nextKeyData.t - offsetTime;
+  var keyTime = keyData.t - offsetTime;
+  var endValue;
+  if (keyData.to) {
+    if (!keyframeMetadata.bezierData) {
+      keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
+    }
+    var bezierData = keyframeMetadata.bezierData;
+    if (frameNum >= nextKeyTime || frameNum < keyTime) {
+      var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
+      kLen = bezierData.points[ind].point.length;
+      for (k = 0; k < kLen; k += 1) {
+        newValue[k] = bezierData.points[ind].point[k];
+      }
+      // caching._lastKeyframeIndex = -1;
+    } else {
+      if (keyframeMetadata.__fnct) {
+        fnc = keyframeMetadata.__fnct;
+      } else {
+        fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
+        keyframeMetadata.__fnct = fnc;
+      }
+      perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+      var distanceInLine = bezierData.segmentLength * perc;
+
+      var segmentPerc;
+      var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0;
+      j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0;
+      flag = true;
+      jLen = bezierData.points.length;
+      while (flag) {
+        addedLength += bezierData.points[j].partialLength;
+        if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k];
+          }
+          break;
+        } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
+          segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
+          }
+          break;
+        }
+        if (j < jLen - 1) {
+          j += 1;
+        } else {
+          flag = false;
+        }
+      }
+      caching._lastPoint = j;
+      caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
+      caching._lastKeyframeIndex = i;
+    }
+  } else {
+    var outX;
+    var outY;
+    var inX;
+    var inY;
+    var keyValue;
+    len = keyData.s.length;
+    endValue = nextKeyData.s || keyData.e;
+    if (this.sh && keyData.h !== 1) {
+      if (frameNum >= nextKeyTime) {
+        newValue[0] = endValue[0];
+        newValue[1] = endValue[1];
+        newValue[2] = endValue[2];
+      } else if (frameNum <= keyTime) {
+        newValue[0] = keyData.s[0];
+        newValue[1] = keyData.s[1];
+        newValue[2] = keyData.s[2];
+      } else {
+        var quatStart = createQuaternion(keyData.s);
+        var quatEnd = createQuaternion(endValue);
+        var time = (frameNum - keyTime) / (nextKeyTime - keyTime);
+        quaternionToEuler(newValue, slerp(quatStart, quatEnd, time));
+      }
+    } else {
+      for (i = 0; i < len; i += 1) {
+        if (keyData.h !== 1) {
+          if (frameNum >= nextKeyTime) {
+            perc = 1;
+          } else if (frameNum < keyTime) {
+            perc = 0;
+          } else {
+            if (keyData.o.x.constructor === Array) {
+              if (!keyframeMetadata.__fnct) {
+                keyframeMetadata.__fnct = [];
+              }
+              if (!keyframeMetadata.__fnct[i]) {
+                outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
+                outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
+                inX = keyData.i.x[i] === undefined ? keyData.i.x[0] : keyData.i.x[i];
+                inY = keyData.i.y[i] === undefined ? keyData.i.y[0] : keyData.i.y[i];
+                fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+                keyframeMetadata.__fnct[i] = fnc;
+              } else {
+                fnc = keyframeMetadata.__fnct[i];
+              }
+            } else if (!keyframeMetadata.__fnct) {
+              outX = keyData.o.x;
+              outY = keyData.o.y;
+              inX = keyData.i.x;
+              inY = keyData.i.y;
+              fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+              keyData.keyframeMetadata = fnc;
+            } else {
+              fnc = keyframeMetadata.__fnct;
+            }
+            perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+          }
+        }
+
+        endValue = nextKeyData.s || keyData.e;
+        keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
+
+        if (this.propType === 'multidimensional') {
+          newValue[i] = keyValue;
+        } else {
+          newValue = keyValue;
+        }
+      }
+    }
+  }
+  caching.lastIndex = iterationIndex;
+  return newValue;
+}
+
+// based on @Toji's https://github.com/toji/gl-matrix/
+function slerp(a, b, t) {
+  var out = [];
+  var ax = a[0];
+  var ay = a[1];
+  var az = a[2];
+  var aw = a[3];
+  var bx = b[0];
+  var by = b[1];
+  var bz = b[2];
+  var bw = b[3];
+
+  var omega;
+  var cosom;
+  var sinom;
+  var scale0;
+  var scale1;
+
+  cosom = ax * bx + ay * by + az * bz + aw * bw;
+  if (cosom < 0.0) {
+    cosom = -cosom;
+    bx = -bx;
+    by = -by;
+    bz = -bz;
+    bw = -bw;
+  }
+  if ((1.0 - cosom) > 0.000001) {
+    omega = Math.acos(cosom);
+    sinom = Math.sin(omega);
+    scale0 = Math.sin((1.0 - t) * omega) / sinom;
+    scale1 = Math.sin(t * omega) / sinom;
+  } else {
+    scale0 = 1.0 - t;
+    scale1 = t;
+  }
+  out[0] = scale0 * ax + scale1 * bx;
+  out[1] = scale0 * ay + scale1 * by;
+  out[2] = scale0 * az + scale1 * bz;
+  out[3] = scale0 * aw + scale1 * bw;
+
+  return out;
+}
+
+function quaternionToEuler(out, quat) {
+  var qx = quat[0];
+  var qy = quat[1];
+  var qz = quat[2];
+  var qw = quat[3];
+  var heading = Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy * qy - 2 * qz * qz);
+  var attitude = Math.asin(2 * qx * qy + 2 * qz * qw);
+  var bank = Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx * qx - 2 * qz * qz);
+  out[0] = heading / degToRads;
+  out[1] = attitude / degToRads;
+  out[2] = bank / degToRads;
+}
+
+function createQuaternion(values) {
+  var heading = values[0] * degToRads;
+  var attitude = values[1] * degToRads;
+  var bank = values[2] * degToRads;
+  var c1 = Math.cos(heading / 2);
+  var c2 = Math.cos(attitude / 2);
+  var c3 = Math.cos(bank / 2);
+  var s1 = Math.sin(heading / 2);
+  var s2 = Math.sin(attitude / 2);
+  var s3 = Math.sin(bank / 2);
+  var w = c1 * c2 * c3 - s1 * s2 * s3;
+  var x = s1 * s2 * c3 + c1 * c2 * s3;
+  var y = s1 * c2 * c3 + c1 * s2 * s3;
+  var z = c1 * s2 * c3 - s1 * c2 * s3;
+
+  return [x, y, z, w];
+}
+
+function getValueAtCurrentTime() {
+  var frameNum = this.comp.renderedFrame - this.offsetTime;
+  var initTime = this.keyframes[0].t - this.offsetTime;
+  var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+  if (!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))) {
+    if (this._caching.lastFrame >= frameNum) {
+      this._caching._lastKeyframeIndex = -1;
+      this._caching.lastIndex = 0;
+    }
+
+    var renderResult = this.interpolateValue(frameNum, this._caching);
+    this.pv = renderResult;
+  }
+  this._caching.lastFrame = frameNum;
+  return this.pv;
+}
+
+function setVValue(val) {
+  var multipliedValue;
+  if (this.propType === 'unidimensional') {
+    multipliedValue = val * this.mult;
+    if (mathAbs(this.v - multipliedValue) > 0.00001) {
+      this.v = multipliedValue;
+      this._mdf = true;
+    }
+  } else {
+    var i = 0;
+    var len = this.v.length;
+    while (i < len) {
+      multipliedValue = val[i] * this.mult;
+      if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
+        this.v[i] = multipliedValue;
+        this._mdf = true;
+      }
+      i += 1;
+    }
+  }
+}
+
+function processEffectsSequence() {
+  if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
+    return;
+  }
+  if (this.lock) {
+    this.setVValue(this.pv);
+    return;
+  }
+  this.lock = true;
+  this._mdf = this._isFirstFrame;
+  var i;
+  var len = this.effectsSequence.length;
+  var finalValue = this.kf ? this.pv : this.data.k;
+  for (i = 0; i < len; i += 1) {
+    finalValue = this.effectsSequence[i](finalValue);
+  }
+  this.setVValue(finalValue);
+  this._isFirstFrame = false;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+}
+
+function addEffect(effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.container.addDynamicProperty(this);
+}
+
+function ValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this.v = mult ? data.k * mult : data.k;
+  this.pv = data.k;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.vel = 0;
+  this.effectsSequence = [];
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function MultiDimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.frameId = -1;
+  var i;
+  var len = data.k.length;
+  this.v = createTypedArray('float32', len);
+  this.pv = createTypedArray('float32', len);
+  this.vel = createTypedArray('float32', len);
+  for (i = 0; i < len; i += 1) {
+    this.v[i] = data.k[i] * this.mult;
+    this.pv[i] = data.k[i];
+  }
+  this._isFirstFrame = true;
+  this.effectsSequence = [];
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function KeyframedValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.frameId = -1;
+  this._caching = {
+    lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1,
+  };
+  this.k = true;
+  this.kf = true;
+  this.data = data;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.v = initFrame;
+  this.pv = initFrame;
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.addEffect = addEffect;
+}
+
+function KeyframedMultidimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  var i;
+  var len = data.k.length;
+  var s;
+  var e;
+  var to;
+  var ti;
+  for (i = 0; i < len - 1; i += 1) {
+    if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
+      s = data.k[i].s;
+      e = data.k[i + 1].s;
+      to = data.k[i].to;
+      ti = data.k[i].ti;
+      if ((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2]))) {
+        data.k[i].to = null;
+        data.k[i].ti = null;
+      }
+      if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
+        if (s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) {
+          data.k[i].to = null;
+          data.k[i].ti = null;
+        }
+      }
+    }
+  }
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.data = data;
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.k = true;
+  this.kf = true;
+  this._isFirstFrame = true;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.frameId = -1;
+  var arrLen = data.k[0].s.length;
+  this.v = createTypedArray('float32', arrLen);
+  this.pv = createTypedArray('float32', arrLen);
+  for (i = 0; i < arrLen; i += 1) {
+    this.v[i] = initFrame;
+    this.pv[i] = initFrame;
+  }
+  this._caching = { lastFrame: initFrame, lastIndex: 0, value: createTypedArray('float32', arrLen) };
+  this.addEffect = addEffect;
+}
+
+const PropertyFactory = (function () {
+  function getProp(elem, data, type, mult, container) {
+    if (data.sid) {
+      data = elem.globalData.slotManager.getProp(data);
+    }
+    var p;
+    if (!data.k.length) {
+      p = new ValueProperty(elem, data, mult, container);
+    } else if (typeof (data.k[0]) === 'number') {
+      p = new MultiDimensionalProperty(elem, data, mult, container);
+    } else {
+      switch (type) {
+        case 0:
+          p = new KeyframedValueProperty(elem, data, mult, container);
+          break;
+        case 1:
+          p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
+          break;
+        default:
+          break;
+      }
+    }
+    if (p.effectsSequence.length) {
+      container.addDynamicProperty(p);
+    }
+    return p;
+  }
+
+  var ob = {
+    getProp: getProp,
+  };
+  return ob;
+}());
+
+function DynamicPropertyContainer() {}
+DynamicPropertyContainer.prototype = {
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+      this.container.addDynamicProperty(this);
+      this._isAnimated = true;
+    }
+  },
+  iterateDynamicProperties: function () {
+    this._mdf = false;
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      this.dynamicProperties[i].getValue();
+      if (this.dynamicProperties[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  },
+  initDynamicPropertyContainer: function (container) {
+    this.container = container;
+    this.dynamicProperties = [];
+    this._mdf = false;
+    this._isAnimated = false;
+  },
+};
+
+const pointPool = (function () {
+  function create() {
+    return createTypedArray('float32', 2);
+  }
+  return poolFactory(8, create);
+}());
+
+function ShapePath() {
+  this.c = false;
+  this._length = 0;
+  this._maxLength = 8;
+  this.v = createSizedArray(this._maxLength);
+  this.o = createSizedArray(this._maxLength);
+  this.i = createSizedArray(this._maxLength);
+}
+
+ShapePath.prototype.setPathData = function (closed, len) {
+  this.c = closed;
+  this.setLength(len);
+  var i = 0;
+  while (i < len) {
+    this.v[i] = pointPool.newElement();
+    this.o[i] = pointPool.newElement();
+    this.i[i] = pointPool.newElement();
+    i += 1;
+  }
+};
+
+ShapePath.prototype.setLength = function (len) {
+  while (this._maxLength < len) {
+    this.doubleArrayLength();
+  }
+  this._length = len;
+};
+
+ShapePath.prototype.doubleArrayLength = function () {
+  this.v = this.v.concat(createSizedArray(this._maxLength));
+  this.i = this.i.concat(createSizedArray(this._maxLength));
+  this.o = this.o.concat(createSizedArray(this._maxLength));
+  this._maxLength *= 2;
+};
+
+ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
+  var arr;
+  this._length = Math.max(this._length, pos + 1);
+  if (this._length >= this._maxLength) {
+    this.doubleArrayLength();
+  }
+  switch (type) {
+    case 'v':
+      arr = this.v;
+      break;
+    case 'i':
+      arr = this.i;
+      break;
+    case 'o':
+      arr = this.o;
+      break;
+    default:
+      arr = [];
+      break;
+  }
+  if (!arr[pos] || (arr[pos] && !replace)) {
+    arr[pos] = pointPool.newElement();
+  }
+  arr[pos][0] = x;
+  arr[pos][1] = y;
+};
+
+ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
+  this.setXYAt(vX, vY, 'v', pos, replace);
+  this.setXYAt(oX, oY, 'o', pos, replace);
+  this.setXYAt(iX, iY, 'i', pos, replace);
+};
+
+ShapePath.prototype.reverse = function () {
+  var newPath = new ShapePath();
+  newPath.setPathData(this.c, this._length);
+  var vertices = this.v;
+  var outPoints = this.o;
+  var inPoints = this.i;
+  var init = 0;
+  if (this.c) {
+    newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
+    init = 1;
+  }
+  var cnt = this._length - 1;
+  var len = this._length;
+
+  var i;
+  for (i = init; i < len; i += 1) {
+    newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
+    cnt -= 1;
+  }
+  return newPath;
+};
+
+ShapePath.prototype.length = function () {
+  return this._length;
+};
+
+const shapePool = (function () {
+  function create() {
+    return new ShapePath();
+  }
+
+  function release(shapePath) {
+    var len = shapePath._length;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      pointPool.release(shapePath.v[i]);
+      pointPool.release(shapePath.i[i]);
+      pointPool.release(shapePath.o[i]);
+      shapePath.v[i] = null;
+      shapePath.i[i] = null;
+      shapePath.o[i] = null;
+    }
+    shapePath._length = 0;
+    shapePath.c = false;
+  }
+
+  function clone(shape) {
+    var cloned = factory.newElement();
+    var i;
+    var len = shape._length === undefined ? shape.v.length : shape._length;
+    cloned.setLength(len);
+    cloned.c = shape.c;
+
+    for (i = 0; i < len; i += 1) {
+      cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
+    }
+    return cloned;
+  }
+
+  var factory = poolFactory(4, create, release);
+  factory.clone = clone;
+
+  return factory;
+}());
+
+function ShapeCollection() {
+  this._length = 0;
+  this._maxLength = 4;
+  this.shapes = createSizedArray(this._maxLength);
+}
+
+ShapeCollection.prototype.addShape = function (shapeData) {
+  if (this._length === this._maxLength) {
+    this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
+    this._maxLength *= 2;
+  }
+  this.shapes[this._length] = shapeData;
+  this._length += 1;
+};
+
+ShapeCollection.prototype.releaseShapes = function () {
+  var i;
+  for (i = 0; i < this._length; i += 1) {
+    shapePool.release(this.shapes[i]);
+  }
+  this._length = 0;
+};
+
+const shapeCollectionPool = (function () {
+  var ob = {
+    newShapeCollection: newShapeCollection,
+    release: release,
+  };
+
+  var _length = 0;
+  var _maxLength = 4;
+  var pool = createSizedArray(_maxLength);
+
+  function newShapeCollection() {
+    var shapeCollection;
+    if (_length) {
+      _length -= 1;
+      shapeCollection = pool[_length];
+    } else {
+      shapeCollection = new ShapeCollection();
+    }
+    return shapeCollection;
+  }
+
+  function release(shapeCollection) {
+    var i;
+    var len = shapeCollection._length;
+    for (i = 0; i < len; i += 1) {
+      shapePool.release(shapeCollection.shapes[i]);
+    }
+    shapeCollection._length = 0;
+
+    if (_length === _maxLength) {
+      pool = pooling.double(pool);
+      _maxLength *= 2;
+    }
+    pool[_length] = shapeCollection;
+    _length += 1;
+  }
+
+  return ob;
+}());
+
+const ShapePropertyFactory = (function () {
+  var initFrame = -999999;
+
+  function interpolateShape(frameNum, previousValue, caching) {
+    var iterationIndex = caching.lastIndex;
+    var keyPropS;
+    var keyPropE;
+    var isHold;
+    var j;
+    var k;
+    var jLen;
+    var kLen;
+    var perc;
+    var vertexValue;
+    var kf = this.keyframes;
+    if (frameNum < kf[0].t - this.offsetTime) {
+      keyPropS = kf[0].s[0];
+      isHold = true;
+      iterationIndex = 0;
+    } else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) {
+      keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
+      /* if(kf[kf.length - 1].s){
+                keyPropS = kf[kf.length - 1].s[0];
+            }else{
+                keyPropS = kf[kf.length - 2].e[0];
+            } */
+      isHold = true;
+    } else {
+      var i = iterationIndex;
+      var len = kf.length - 1;
+      var flag = true;
+      var keyData;
+      var nextKeyData;
+      var keyframeMetadata;
+      while (flag) {
+        keyData = kf[i];
+        nextKeyData = kf[i + 1];
+        if ((nextKeyData.t - this.offsetTime) > frameNum) {
+          break;
+        }
+        if (i < len - 1) {
+          i += 1;
+        } else {
+          flag = false;
+        }
+      }
+      keyframeMetadata = this.keyframesMetadata[i] || {};
+      isHold = keyData.h === 1;
+      iterationIndex = i;
+      if (!isHold) {
+        if (frameNum >= nextKeyData.t - this.offsetTime) {
+          perc = 1;
+        } else if (frameNum < keyData.t - this.offsetTime) {
+          perc = 0;
+        } else {
+          var fnc;
+          if (keyframeMetadata.__fnct) {
+            fnc = keyframeMetadata.__fnct;
+          } else {
+            fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
+            keyframeMetadata.__fnct = fnc;
+          }
+          perc = fnc((frameNum - (keyData.t - this.offsetTime)) / ((nextKeyData.t - this.offsetTime) - (keyData.t - this.offsetTime)));
+        }
+        keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
+      }
+      keyPropS = keyData.s[0];
+    }
+    jLen = previousValue._length;
+    kLen = keyPropS.i[0].length;
+    caching.lastIndex = iterationIndex;
+
+    for (j = 0; j < jLen; j += 1) {
+      for (k = 0; k < kLen; k += 1) {
+        vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
+        previousValue.i[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc;
+        previousValue.o[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc;
+        previousValue.v[j][k] = vertexValue;
+      }
+    }
+  }
+
+  function interpolateShapeCurrentTime() {
+    var frameNum = this.comp.renderedFrame - this.offsetTime;
+    var initTime = this.keyframes[0].t - this.offsetTime;
+    var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+    var lastFrame = this._caching.lastFrame;
+    if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) {
+      /// /
+      this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
+      this.interpolateShape(frameNum, this.pv, this._caching);
+      /// /
+    }
+    this._caching.lastFrame = frameNum;
+    return this.pv;
+  }
+
+  function resetShape() {
+    this.paths = this.localShapeCollection;
+  }
+
+  function shapesEqual(shape1, shape2) {
+    if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
+      return false;
+    }
+    var i;
+    var len = shape1._length;
+    for (i = 0; i < len; i += 1) {
+      if (shape1.v[i][0] !== shape2.v[i][0]
+            || shape1.v[i][1] !== shape2.v[i][1]
+            || shape1.o[i][0] !== shape2.o[i][0]
+            || shape1.o[i][1] !== shape2.o[i][1]
+            || shape1.i[i][0] !== shape2.i[i][0]
+            || shape1.i[i][1] !== shape2.i[i][1]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  function setVValue(newPath) {
+    if (!shapesEqual(this.v, newPath)) {
+      this.v = shapePool.clone(newPath);
+      this.localShapeCollection.releaseShapes();
+      this.localShapeCollection.addShape(this.v);
+      this._mdf = true;
+      this.paths = this.localShapeCollection;
+    }
+  }
+
+  function processEffectsSequence() {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    } if (!this.effectsSequence.length) {
+      this._mdf = false;
+      return;
+    }
+    if (this.lock) {
+      this.setVValue(this.pv);
+      return;
+    }
+    this.lock = true;
+    this._mdf = false;
+    var finalValue;
+    if (this.kf) {
+      finalValue = this.pv;
+    } else if (this.data.ks) {
+      finalValue = this.data.ks.k;
+    } else {
+      finalValue = this.data.pt.k;
+    }
+    var i;
+    var len = this.effectsSequence.length;
+    for (i = 0; i < len; i += 1) {
+      finalValue = this.effectsSequence[i](finalValue);
+    }
+    this.setVValue(finalValue);
+    this.lock = false;
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function ShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.container = elem;
+    this.elem = elem;
+    this.data = data;
+    this.k = false;
+    this.kf = false;
+    this._mdf = false;
+    var pathData = type === 3 ? data.pt.k : data.ks.k;
+    this.v = shapePool.clone(pathData);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.reset = resetShape;
+    this.effectsSequence = [];
+  }
+
+  function addEffect(effectFunction) {
+    this.effectsSequence.push(effectFunction);
+    this.container.addDynamicProperty(this);
+  }
+
+  ShapeProperty.prototype.interpolateShape = interpolateShape;
+  ShapeProperty.prototype.getValue = processEffectsSequence;
+  ShapeProperty.prototype.setVValue = setVValue;
+  ShapeProperty.prototype.addEffect = addEffect;
+
+  function KeyframedShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.elem = elem;
+    this.container = elem;
+    this.offsetTime = elem.data.st;
+    this.keyframes = type === 3 ? data.pt.k : data.ks.k;
+    this.keyframesMetadata = [];
+    this.k = true;
+    this.kf = true;
+    var len = this.keyframes[0].s[0].i.length;
+    this.v = shapePool.newElement();
+    this.v.setPathData(this.keyframes[0].s[0].c, len);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.lastFrame = initFrame;
+    this.reset = resetShape;
+    this._caching = { lastFrame: initFrame, lastIndex: 0 };
+    this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
+  }
+  KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
+  KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
+  KeyframedShapeProperty.prototype.setVValue = setVValue;
+  KeyframedShapeProperty.prototype.addEffect = addEffect;
+
+  var EllShapeProperty = (function () {
+    var cPoint = roundCorner;
+
+    function EllShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 4);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.paths = this.localShapeCollection;
+      this.localShapeCollection.addShape(this.v);
+      this.d = data.d;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertEllToPath();
+      }
+    }
+
+    EllShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+
+        if (this._mdf) {
+          this.convertEllToPath();
+        }
+      },
+      convertEllToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var s0 = this.s.v[0] / 2;
+        var s1 = this.s.v[1] / 2;
+        var _cw = this.d !== 3;
+        var _v = this.v;
+        _v.v[0][0] = p0;
+        _v.v[0][1] = p1 - s1;
+        _v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.v[1][1] = p1;
+        _v.v[2][0] = p0;
+        _v.v[2][1] = p1 + s1;
+        _v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.v[3][1] = p1;
+        _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.i[0][1] = p1 - s1;
+        _v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.i[1][1] = p1 - s1 * cPoint;
+        _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.i[2][1] = p1 + s1;
+        _v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.i[3][1] = p1 + s1 * cPoint;
+        _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.o[0][1] = p1 - s1;
+        _v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.o[1][1] = p1 + s1 * cPoint;
+        _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.o[2][1] = p1 + s1;
+        _v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.o[3][1] = p1 - s1 * cPoint;
+      },
+    };
+
+    extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
+
+    return EllShapePropertyFactory;
+  }());
+
+  var StarShapeProperty = (function () {
+    function StarShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 0);
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.data = data;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      if (data.sy === 1) {
+        this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
+        this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
+        this.convertToPath = this.convertStarToPath;
+      } else {
+        this.convertToPath = this.convertPolygonToPath;
+      }
+      this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
+      this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this);
+      this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertToPath();
+      }
+    }
+
+    StarShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertToPath();
+        }
+      },
+      convertStarToPath: function () {
+        var numPts = Math.floor(this.pt.v) * 2;
+        var angle = (Math.PI * 2) / numPts;
+        /* this.v.v.length = numPts;
+                this.v.i.length = numPts;
+                this.v.o.length = numPts; */
+        var longFlag = true;
+        var longRad = this.or.v;
+        var shortRad = this.ir.v;
+        var longRound = this.os.v;
+        var shortRound = this.is.v;
+        var longPerimSegment = (2 * Math.PI * longRad) / (numPts * 2);
+        var shortPerimSegment = (2 * Math.PI * shortRad) / (numPts * 2);
+        var i;
+        var rad;
+        var roundness;
+        var perimSegment;
+        var currentAng = -Math.PI / 2;
+        currentAng += this.r.v;
+        var dir = this.data.d === 3 ? -1 : 1;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          rad = longFlag ? longRad : shortRad;
+          roundness = longFlag ? longRound : shortRound;
+          perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
+          /* this.v.v[i] = [x,y];
+                    this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
+                    this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
+                    this.v._length = numPts; */
+          longFlag = !longFlag;
+          currentAng += angle * dir;
+        }
+      },
+      convertPolygonToPath: function () {
+        var numPts = Math.floor(this.pt.v);
+        var angle = (Math.PI * 2) / numPts;
+        var rad = this.or.v;
+        var roundness = this.os.v;
+        var perimSegment = (2 * Math.PI * rad) / (numPts * 4);
+        var i;
+        var currentAng = -Math.PI * 0.5;
+        var dir = this.data.d === 3 ? -1 : 1;
+        currentAng += this.r.v;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+          currentAng += angle * dir;
+        }
+        this.paths.length = 0;
+        this.paths[0] = this.v;
+      },
+
+    };
+    extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
+
+    return StarShapePropertyFactory;
+  }());
+
+  var RectShapeProperty = (function () {
+    function RectShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.c = true;
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertRectToPath();
+      }
+    }
+
+    RectShapePropertyFactory.prototype = {
+      convertRectToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var v0 = this.s.v[0] / 2;
+        var v1 = this.s.v[1] / 2;
+        var round = bmMin(v0, v1, this.r.v);
+        var cPoint = round * (1 - roundCorner);
+        this.v._length = 0;
+
+        if (this.d === 2 || this.d === 1) {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
+          this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2);
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3);
+          }
+        } else {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true);
+          }
+        }
+      },
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertRectToPath();
+        }
+      },
+      reset: resetShape,
+    };
+    extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
+
+    return RectShapePropertyFactory;
+  }());
+
+  function getShapeProp(elem, data, type) {
+    var prop;
+    if (type === 3 || type === 4) {
+      var dataProp = type === 3 ? data.pt : data.ks;
+      var keys = dataProp.k;
+      if (keys.length) {
+        prop = new KeyframedShapeProperty(elem, data, type);
+      } else {
+        prop = new ShapeProperty(elem, data, type);
+      }
+    } else if (type === 5) {
+      prop = new RectShapeProperty(elem, data);
+    } else if (type === 6) {
+      prop = new EllShapeProperty(elem, data);
+    } else if (type === 7) {
+      prop = new StarShapeProperty(elem, data);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  }
+
+  function getConstructorFunction() {
+    return ShapeProperty;
+  }
+
+  function getKeyframedConstructorFunction() {
+    return KeyframedShapeProperty;
+  }
+
+  var ob = {};
+  ob.getShapeProp = getShapeProp;
+  ob.getConstructorFunction = getConstructorFunction;
+  ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction;
+  return ob;
+}());
+
+/*!
+ Transformation Matrix v2.0
+ (c) Epistemex 2014-2015
+ www.epistemex.com
+ By Ken Fyrstenberg
+ Contributions by leeoniya.
+ License: MIT, header required.
+ */
+
+/**
+ * 2D transformation matrix object initialized with identity matrix.
+ *
+ * The matrix can synchronize a canvas context by supplying the context
+ * as an argument, or later apply current absolute transform to an
+ * existing context.
+ *
+ * All values are handled as floating point values.
+ *
+ * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix
+ * @prop {number} a - scale x
+ * @prop {number} b - shear y
+ * @prop {number} c - shear x
+ * @prop {number} d - scale y
+ * @prop {number} e - translate x
+ * @prop {number} f - translate y
+ * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context
+ * @constructor
+ */
+
+const Matrix = (function () {
+  var _cos = Math.cos;
+  var _sin = Math.sin;
+  var _tan = Math.tan;
+  var _rnd = Math.round;
+
+  function reset() {
+    this.props[0] = 1;
+    this.props[1] = 0;
+    this.props[2] = 0;
+    this.props[3] = 0;
+    this.props[4] = 0;
+    this.props[5] = 1;
+    this.props[6] = 0;
+    this.props[7] = 0;
+    this.props[8] = 0;
+    this.props[9] = 0;
+    this.props[10] = 1;
+    this.props[11] = 0;
+    this.props[12] = 0;
+    this.props[13] = 0;
+    this.props[14] = 0;
+    this.props[15] = 1;
+    return this;
+  }
+
+  function rotate(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function rotateX(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateY(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateZ(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function shear(sx, sy) {
+    return this._t(1, sy, sx, 1, 0, 0);
+  }
+
+  function skew(ax, ay) {
+    return this.shear(_tan(ax), _tan(ay));
+  }
+
+  function skewFromAxis(ax, angle) {
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+    // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+  }
+
+  function scale(sx, sy, sz) {
+    if (!sz && sz !== 0) {
+      sz = 1;
+    }
+    if (sx === 1 && sy === 1 && sz === 1) {
+      return this;
+    }
+    return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
+  }
+
+  function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
+    this.props[0] = a;
+    this.props[1] = b;
+    this.props[2] = c;
+    this.props[3] = d;
+    this.props[4] = e;
+    this.props[5] = f;
+    this.props[6] = g;
+    this.props[7] = h;
+    this.props[8] = i;
+    this.props[9] = j;
+    this.props[10] = k;
+    this.props[11] = l;
+    this.props[12] = m;
+    this.props[13] = n;
+    this.props[14] = o;
+    this.props[15] = p;
+    return this;
+  }
+
+  function translate(tx, ty, tz) {
+    tz = tz || 0;
+    if (tx !== 0 || ty !== 0 || tz !== 0) {
+      return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
+    }
+    return this;
+  }
+
+  function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
+    var _p = this.props;
+
+    if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
+      // NOTE: commenting this condition because TurboFan deoptimizes code when present
+      // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
+      _p[12] = _p[12] * a2 + _p[15] * m2;
+      _p[13] = _p[13] * f2 + _p[15] * n2;
+      _p[14] = _p[14] * k2 + _p[15] * o2;
+      _p[15] *= p2;
+      // }
+      this._identityCalculated = false;
+      return this;
+    }
+
+    var a1 = _p[0];
+    var b1 = _p[1];
+    var c1 = _p[2];
+    var d1 = _p[3];
+    var e1 = _p[4];
+    var f1 = _p[5];
+    var g1 = _p[6];
+    var h1 = _p[7];
+    var i1 = _p[8];
+    var j1 = _p[9];
+    var k1 = _p[10];
+    var l1 = _p[11];
+    var m1 = _p[12];
+    var n1 = _p[13];
+    var o1 = _p[14];
+    var p1 = _p[15];
+
+    /* matrix order (canvas compatible):
+         * ace
+         * bdf
+         * 001
+         */
+    _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
+    _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
+    _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
+    _p[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2;
+
+    _p[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2;
+    _p[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2;
+    _p[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2;
+    _p[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2;
+
+    _p[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2;
+    _p[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2;
+    _p[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2;
+    _p[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2;
+
+    _p[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2;
+    _p[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2;
+    _p[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2;
+    _p[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2;
+
+    this._identityCalculated = false;
+    return this;
+  }
+
+  function multiply(matrix) {
+    var matrixProps = matrix.props;
+    return this.transform(
+      matrixProps[0],
+      matrixProps[1],
+      matrixProps[2],
+      matrixProps[3],
+      matrixProps[4],
+      matrixProps[5],
+      matrixProps[6],
+      matrixProps[7],
+      matrixProps[8],
+      matrixProps[9],
+      matrixProps[10],
+      matrixProps[11],
+      matrixProps[12],
+      matrixProps[13],
+      matrixProps[14],
+      matrixProps[15]
+    );
+  }
+
+  function isIdentity() {
+    if (!this._identityCalculated) {
+      this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
+      this._identityCalculated = true;
+    }
+    return this._identity;
+  }
+
+  function equals(matr) {
+    var i = 0;
+    while (i < 16) {
+      if (matr.props[i] !== this.props[i]) {
+        return false;
+      }
+      i += 1;
+    }
+    return true;
+  }
+
+  function clone(matr) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      matr.props[i] = this.props[i];
+    }
+    return matr;
+  }
+
+  function cloneFromProps(props) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      this.props[i] = props[i];
+    }
+  }
+
+  function applyToPoint(x, y, z) {
+    return {
+      x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+      y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+      z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+    };
+    /* return {
+         x: x * me.a + y * me.c + me.e,
+         y: x * me.b + y * me.d + me.f
+         }; */
+  }
+  function applyToX(x, y, z) {
+    return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
+  }
+  function applyToY(x, y, z) {
+    return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
+  }
+  function applyToZ(x, y, z) {
+    return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
+  }
+
+  function getInverseMatrix() {
+    var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
+    var a = this.props[5] / determinant;
+    var b = -this.props[1] / determinant;
+    var c = -this.props[4] / determinant;
+    var d = this.props[0] / determinant;
+    var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12]) / determinant;
+    var f = -(this.props[0] * this.props[13] - this.props[1] * this.props[12]) / determinant;
+    var inverseMatrix = new Matrix();
+    inverseMatrix.props[0] = a;
+    inverseMatrix.props[1] = b;
+    inverseMatrix.props[4] = c;
+    inverseMatrix.props[5] = d;
+    inverseMatrix.props[12] = e;
+    inverseMatrix.props[13] = f;
+    return inverseMatrix;
+  }
+
+  function inversePoint(pt) {
+    var inverseMatrix = this.getInverseMatrix();
+    return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
+  }
+
+  function inversePoints(pts) {
+    var i;
+    var len = pts.length;
+    var retPts = [];
+    for (i = 0; i < len; i += 1) {
+      retPts[i] = inversePoint(pts[i]);
+    }
+    return retPts;
+  }
+
+  function applyToTriplePoints(pt1, pt2, pt3) {
+    var arr = createTypedArray('float32', 6);
+    if (this.isIdentity()) {
+      arr[0] = pt1[0];
+      arr[1] = pt1[1];
+      arr[2] = pt2[0];
+      arr[3] = pt2[1];
+      arr[4] = pt3[0];
+      arr[5] = pt3[1];
+    } else {
+      var p0 = this.props[0];
+      var p1 = this.props[1];
+      var p4 = this.props[4];
+      var p5 = this.props[5];
+      var p12 = this.props[12];
+      var p13 = this.props[13];
+      arr[0] = pt1[0] * p0 + pt1[1] * p4 + p12;
+      arr[1] = pt1[0] * p1 + pt1[1] * p5 + p13;
+      arr[2] = pt2[0] * p0 + pt2[1] * p4 + p12;
+      arr[3] = pt2[0] * p1 + pt2[1] * p5 + p13;
+      arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
+      arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
+    }
+    return arr;
+  }
+
+  function applyToPointArray(x, y, z) {
+    var arr;
+    if (this.isIdentity()) {
+      arr = [x, y, z];
+    } else {
+      arr = [
+        x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+        x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+        x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+      ];
+    }
+    return arr;
+  }
+
+  function applyToPointStringified(x, y) {
+    if (this.isIdentity()) {
+      return x + ',' + y;
+    }
+    var _p = this.props;
+    return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
+  }
+
+  function toCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var i = 0;
+    var props = this.props;
+    var cssValue = 'matrix3d(';
+    var v = 10000;
+    while (i < 16) {
+      cssValue += _rnd(props[i] * v) / v;
+      cssValue += i === 15 ? ')' : ',';
+      i += 1;
+    }
+    return cssValue;
+  }
+
+  function roundMatrixProperty(val) {
+    var v = 10000;
+    if ((val < 0.000001 && val > 0) || (val > -0.000001 && val < 0)) {
+      return _rnd(val * v) / v;
+    }
+    return val;
+  }
+
+  function to2dCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var props = this.props;
+    var _a = roundMatrixProperty(props[0]);
+    var _b = roundMatrixProperty(props[1]);
+    var _c = roundMatrixProperty(props[4]);
+    var _d = roundMatrixProperty(props[5]);
+    var _e = roundMatrixProperty(props[12]);
+    var _f = roundMatrixProperty(props[13]);
+    return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
+  }
+
+  return function () {
+    this.reset = reset;
+    this.rotate = rotate;
+    this.rotateX = rotateX;
+    this.rotateY = rotateY;
+    this.rotateZ = rotateZ;
+    this.skew = skew;
+    this.skewFromAxis = skewFromAxis;
+    this.shear = shear;
+    this.scale = scale;
+    this.setTransform = setTransform;
+    this.translate = translate;
+    this.transform = transform;
+    this.multiply = multiply;
+    this.applyToPoint = applyToPoint;
+    this.applyToX = applyToX;
+    this.applyToY = applyToY;
+    this.applyToZ = applyToZ;
+    this.applyToPointArray = applyToPointArray;
+    this.applyToTriplePoints = applyToTriplePoints;
+    this.applyToPointStringified = applyToPointStringified;
+    this.toCSS = toCSS;
+    this.to2dCSS = to2dCSS;
+    this.clone = clone;
+    this.cloneFromProps = cloneFromProps;
+    this.equals = equals;
+    this.inversePoints = inversePoints;
+    this.inversePoint = inversePoint;
+    this.getInverseMatrix = getInverseMatrix;
+    this._t = this.transform;
+    this.isIdentity = isIdentity;
+    this._identity = true;
+    this._identityCalculated = false;
+
+    this.props = createTypedArray('float32', 16);
+    this.reset();
+  };
+}());
+
+const lottie = {};
+var standalone = '__[STANDALONE]__';
+var animationData = '__[ANIMATIONDATA]__';
+var renderer = '';
+
+function setLocation(href) {
+  setLocationHref(href);
+}
+
+function searchAnimations() {
+  if (standalone === true) {
+    animationManager.searchAnimations(animationData, standalone, renderer);
+  } else {
+    animationManager.searchAnimations();
+  }
+}
+
+function setSubframeRendering(flag) {
+  setSubframeEnabled(flag);
+}
+
+function setPrefix(prefix) {
+  setIdPrefix(prefix);
+}
+
+function loadAnimation(params) {
+  if (standalone === true) {
+    params.animationData = JSON.parse(animationData);
+  }
+  return animationManager.loadAnimation(params);
+}
+
+function setQuality(value) {
+  if (typeof value === 'string') {
+    switch (value) {
+      case 'high':
+        setDefaultCurveSegments(200);
+        break;
+      default:
+      case 'medium':
+        setDefaultCurveSegments(50);
+        break;
+      case 'low':
+        setDefaultCurveSegments(10);
+        break;
+    }
+  } else if (!isNaN(value) && value > 1) {
+    setDefaultCurveSegments(value);
+  }
+  if (getDefaultCurveSegments() >= 50) {
+    roundValues(false);
+  } else {
+    roundValues(true);
+  }
+}
+
+function inBrowser() {
+  return typeof navigator !== 'undefined';
+}
+
+function installPlugin(type, plugin) {
+  if (type === 'expressions') {
+    setExpressionsPlugin(plugin);
+  }
+}
+
+function getFactory(name) {
+  switch (name) {
+    case 'propertyFactory':
+      return PropertyFactory;
+    case 'shapePropertyFactory':
+      return ShapePropertyFactory;
+    case 'matrix':
+      return Matrix;
+    default:
+      return null;
+  }
+}
+
+lottie.play = animationManager.play;
+lottie.pause = animationManager.pause;
+lottie.setLocationHref = setLocation;
+lottie.togglePause = animationManager.togglePause;
+lottie.setSpeed = animationManager.setSpeed;
+lottie.setDirection = animationManager.setDirection;
+lottie.stop = animationManager.stop;
+lottie.searchAnimations = searchAnimations;
+lottie.registerAnimation = animationManager.registerAnimation;
+lottie.loadAnimation = loadAnimation;
+lottie.setSubframeRendering = setSubframeRendering;
+lottie.resize = animationManager.resize;
+// lottie.start = start;
+lottie.goToAndStop = animationManager.goToAndStop;
+lottie.destroy = animationManager.destroy;
+lottie.setQuality = setQuality;
+lottie.inBrowser = inBrowser;
+lottie.installPlugin = installPlugin;
+lottie.freeze = animationManager.freeze;
+lottie.unfreeze = animationManager.unfreeze;
+lottie.setVolume = animationManager.setVolume;
+lottie.mute = animationManager.mute;
+lottie.unmute = animationManager.unmute;
+lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations;
+lottie.useWebWorker = setWebWorker;
+lottie.setIDPrefix = setPrefix;
+lottie.__getFactory = getFactory;
+lottie.version = '[[BM_VERSION]]';
+
+function checkReady() {
+  if (document.readyState === 'complete') {
+    clearInterval(readyStateCheckInterval);
+    searchAnimations();
+  }
+}
+
+function getQueryVariable(variable) {
+  var vars = queryString.split('&');
+  for (var i = 0; i < vars.length; i += 1) {
+    var pair = vars[i].split('=');
+    if (decodeURIComponent(pair[0]) == variable) { // eslint-disable-line eqeqeq
+      return decodeURIComponent(pair[1]);
+    }
+  }
+  return null;
+}
+var queryString = '';
+if (standalone) {
+  var scripts = document.getElementsByTagName('script');
+  var index = scripts.length - 1;
+  var myScript = scripts[index] || {
+    src: '',
+  };
+  queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
+  renderer = getQueryVariable('renderer');
+}
+var readyStateCheckInterval = setInterval(checkReady, 100);
+
+// this adds bodymovin to the window object for backwards compatibility
+try {
+  if (!(typeof exports === 'object' && typeof module !== 'undefined')
+    && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
+  ) {
+    window.bodymovin = lottie;
+  }
+} catch (err) {
+  //
+}
+
+const ShapeModifiers = (function () {
+  var ob = {};
+  var modifiers = {};
+  ob.registerModifier = registerModifier;
+  ob.getModifier = getModifier;
+
+  function registerModifier(nm, factory) {
+    if (!modifiers[nm]) {
+      modifiers[nm] = factory;
+    }
+  }
+
+  function getModifier(nm, elem, data) {
+    return new modifiers[nm](elem, data);
+  }
+
+  return ob;
+}());
+
+function ShapeModifier() {}
+ShapeModifier.prototype.initModifierProperties = function () {};
+ShapeModifier.prototype.addShapeToModifier = function () {};
+ShapeModifier.prototype.addShape = function (data) {
+  if (!this.closed) {
+    // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
+    data.sh.container.addDynamicProperty(data.sh);
+    var shapeData = { shape: data.sh, data: data, localShapeCollection: shapeCollectionPool.newShapeCollection() };
+    this.shapes.push(shapeData);
+    this.addShapeToModifier(shapeData);
+    if (this._isAnimated) {
+      data.setAsAnimated();
+    }
+  }
+};
+ShapeModifier.prototype.init = function (elem, data) {
+  this.shapes = [];
+  this.elem = elem;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, data);
+  this.frameId = initialDefaultFrame;
+  this.closed = false;
+  this.k = false;
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+ShapeModifier.prototype.processKeys = function () {
+  if (this.elem.globalData.frameId === this.frameId) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+extendPrototype([DynamicPropertyContainer], ShapeModifier);
+
+function TrimModifier() {
+}
+extendPrototype([ShapeModifier], TrimModifier);
+TrimModifier.prototype.initModifierProperties = function (elem, data) {
+  this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this);
+  this.sValue = 0;
+  this.eValue = 0;
+  this.getValue = this.processKeys;
+  this.m = data.m;
+  this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
+};
+
+TrimModifier.prototype.addShapeToModifier = function (shapeData) {
+  shapeData.pathsData = [];
+};
+
+TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
+  var segments = [];
+  if (e <= 1) {
+    segments.push({
+      s: s,
+      e: e,
+    });
+  } else if (s >= 1) {
+    segments.push({
+      s: s - 1,
+      e: e - 1,
+    });
+  } else {
+    segments.push({
+      s: s,
+      e: 1,
+    });
+    segments.push({
+      s: 0,
+      e: e - 1,
+    });
+  }
+  var shapeSegments = [];
+  var i;
+  var len = segments.length;
+  var segmentOb;
+  for (i = 0; i < len; i += 1) {
+    segmentOb = segments[i];
+    if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
+      var shapeS;
+      var shapeE;
+      if (segmentOb.s * totalModifierLength <= addedLength) {
+        shapeS = 0;
+      } else {
+        shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
+      }
+      if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
+        shapeE = 1;
+      } else {
+        shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength);
+      }
+      shapeSegments.push([shapeS, shapeE]);
+    }
+  }
+  if (!shapeSegments.length) {
+    shapeSegments.push([0, 0]);
+  }
+  return shapeSegments;
+};
+
+TrimModifier.prototype.releasePathsData = function (pathsData) {
+  var i;
+  var len = pathsData.length;
+  for (i = 0; i < len; i += 1) {
+    segmentsLengthPool.release(pathsData[i]);
+  }
+  pathsData.length = 0;
+  return pathsData;
+};
+
+TrimModifier.prototype.processShapes = function (_isFirstFrame) {
+  var s;
+  var e;
+  if (this._mdf || _isFirstFrame) {
+    var o = (this.o.v % 360) / 360;
+    if (o < 0) {
+      o += 1;
+    }
+    if (this.s.v > 1) {
+      s = 1 + o;
+    } else if (this.s.v < 0) {
+      s = 0 + o;
+    } else {
+      s = this.s.v + o;
+    }
+    if (this.e.v > 1) {
+      e = 1 + o;
+    } else if (this.e.v < 0) {
+      e = 0 + o;
+    } else {
+      e = this.e.v + o;
+    }
+
+    if (s > e) {
+      var _s = s;
+      s = e;
+      e = _s;
+    }
+    s = Math.round(s * 10000) * 0.0001;
+    e = Math.round(e * 10000) * 0.0001;
+    this.sValue = s;
+    this.eValue = e;
+  } else {
+    s = this.sValue;
+    e = this.eValue;
+  }
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var pathsData;
+  var pathData;
+  var totalShapeLength;
+  var totalModifierLength = 0;
+
+  if (e === s) {
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].localShapeCollection.releaseShapes();
+      this.shapes[i].shape._mdf = true;
+      this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
+      if (this._mdf) {
+        this.shapes[i].pathsData.length = 0;
+      }
+    }
+  } else if (!((e === 1 && s === 0) || (e === 0 && s === 1))) {
+    var segments = [];
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
+      if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
+        shapeData.shape.paths = shapeData.localShapeCollection;
+      } else {
+        shapePaths = shapeData.shape.paths;
+        jLen = shapePaths._length;
+        totalShapeLength = 0;
+        if (!shapeData.shape._mdf && shapeData.pathsData.length) {
+          totalShapeLength = shapeData.totalShapeLength;
+        } else {
+          pathsData = this.releasePathsData(shapeData.pathsData);
+          for (j = 0; j < jLen; j += 1) {
+            pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
+            pathsData.push(pathData);
+            totalShapeLength += pathData.totalLength;
+          }
+          shapeData.totalShapeLength = totalShapeLength;
+          shapeData.pathsData = pathsData;
+        }
+
+        totalModifierLength += totalShapeLength;
+        shapeData.shape._mdf = true;
+      }
+    }
+    var shapeS = s;
+    var shapeE = e;
+    var addedLength = 0;
+    var edges;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shapeData = this.shapes[i];
+      if (shapeData.shape._mdf) {
+        localShapeCollection = shapeData.localShapeCollection;
+        localShapeCollection.releaseShapes();
+        // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
+        if (this.m === 2 && len > 1) {
+          edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
+          addedLength += shapeData.totalShapeLength;
+        } else {
+          edges = [[shapeS, shapeE]];
+        }
+        jLen = edges.length;
+        for (j = 0; j < jLen; j += 1) {
+          shapeS = edges[j][0];
+          shapeE = edges[j][1];
+          segments.length = 0;
+          if (shapeE <= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength * shapeE,
+            });
+          } else if (shapeS >= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * (shapeS - 1),
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          } else {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength,
+            });
+            segments.push({
+              s: 0,
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          }
+          var newShapesData = this.addShapes(shapeData, segments[0]);
+          if (segments[0].s !== segments[0].e) {
+            if (segments.length > 1) {
+              var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
+              if (lastShapeInCollection.c) {
+                var lastShape = newShapesData.pop();
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1], lastShape);
+              } else {
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1]);
+              }
+            }
+            this.addPaths(newShapesData, localShapeCollection);
+          }
+        }
+        shapeData.shape.paths = localShapeCollection;
+      }
+    }
+  } else if (this._mdf) {
+    for (i = 0; i < len; i += 1) {
+      // Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween.
+      // Don't remove this even if it's losing cached info.
+      this.shapes[i].pathsData.length = 0;
+      this.shapes[i].shape._mdf = true;
+    }
+  }
+};
+
+TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
+  var i;
+  var len = newPaths.length;
+  for (i = 0; i < len; i += 1) {
+    localShapeCollection.addShape(newPaths[i]);
+  }
+};
+
+TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
+  shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
+  shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
+  }
+  shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
+  shapePath.setXYAt(points[1], points[5], 'o', pos);
+  shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(points[0], points[4], 'v', pos);
+  }
+  shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
+  var pathsData = shapeData.pathsData;
+  var shapePaths = shapeData.shape.paths.shapes;
+  var i;
+  var len = shapeData.shape.paths._length;
+  var j;
+  var jLen;
+  var addedLength = 0;
+  var currentLengthData;
+  var segmentCount;
+  var lengths;
+  var segment;
+  var shapes = [];
+  var initPos;
+  var newShape = true;
+  if (!shapePath) {
+    shapePath = shapePool.newElement();
+    segmentCount = 0;
+    initPos = 0;
+  } else {
+    segmentCount = shapePath._length;
+    initPos = shapePath._length;
+  }
+  shapes.push(shapePath);
+  for (i = 0; i < len; i += 1) {
+    lengths = pathsData[i].lengths;
+    shapePath.c = shapePaths[i].c;
+    jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
+    for (j = 1; j < jLen; j += 1) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
+        addedLength += currentLengthData.addedLength;
+        shapePath.c = false;
+      } else if (addedLength > shapeSegment.e) {
+        shapePath.c = false;
+        break;
+      } else {
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+        addedLength += currentLengthData.addedLength;
+        segmentCount += 1;
+      }
+    }
+    if (shapePaths[i].c && lengths.length) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength <= shapeSegment.e) {
+        var segmentLength = lengths[j - 1].addedLength;
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+      } else {
+        shapePath.c = false;
+      }
+      addedLength += currentLengthData.addedLength;
+      segmentCount += 1;
+    }
+    if (shapePath._length) {
+      shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
+      shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
+    }
+    if (addedLength > shapeSegment.e) {
+      break;
+    }
+    if (i < len - 1) {
+      shapePath = shapePool.newElement();
+      newShape = true;
+      shapes.push(shapePath);
+      segmentCount = 0;
+    }
+  }
+  return shapes;
+};
+
+function PuckerAndBloatModifier() {}
+extendPrototype([ShapeModifier], PuckerAndBloatModifier);
+PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this._isAnimated = !!this.amount.effectsSequence.length;
+};
+
+PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
+  var percent = amount / 100;
+  var centerPoint = [0, 0];
+  var pathLength = path._length;
+  var i = 0;
+  for (i = 0; i < pathLength; i += 1) {
+    centerPoint[0] += path.v[i][0];
+    centerPoint[1] += path.v[i][1];
+  }
+  centerPoint[0] /= pathLength;
+  centerPoint[1] /= pathLength;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < pathLength; i += 1) {
+    vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
+    vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
+    oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent;
+    oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent;
+    iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent;
+    iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
+    clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
+  }
+  return clonedPath;
+};
+
+PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+const TransformPropertyFactory = (function () {
+  var defaultVector = [0, 0];
+
+  function applyToMatrix(mat) {
+    var _mdf = this._mdf;
+    this.iterateDynamicProperties();
+    this._mdf = this._mdf || _mdf;
+    if (this.a) {
+      mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+    }
+    if (this.s) {
+      mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+    }
+    if (this.sk) {
+      mat.skewFromAxis(-this.sk.v, this.sa.v);
+    }
+    if (this.r) {
+      mat.rotate(-this.r.v);
+    } else {
+      mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+    }
+    if (this.data.p.s) {
+      if (this.data.p.z) {
+        mat.translate(this.px.v, this.py.v, -this.pz.v);
+      } else {
+        mat.translate(this.px.v, this.py.v, 0);
+      }
+    } else {
+      mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+    }
+  }
+  function processKeys(forceRender) {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    }
+    if (this._isDirty) {
+      this.precalculateMatrix();
+      this._isDirty = false;
+    }
+
+    this.iterateDynamicProperties();
+
+    if (this._mdf || forceRender) {
+      var frameRate;
+      this.v.cloneFromProps(this.pre.props);
+      if (this.appliedTransformations < 1) {
+        this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      }
+      if (this.appliedTransformations < 2) {
+        this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      }
+      if (this.sk && this.appliedTransformations < 3) {
+        this.v.skewFromAxis(-this.sk.v, this.sa.v);
+      }
+      if (this.r && this.appliedTransformations < 4) {
+        this.v.rotate(-this.r.v);
+      } else if (!this.r && this.appliedTransformations < 4) {
+        this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+          .rotateY(this.or.v[1])
+          .rotateX(this.or.v[0]);
+      }
+      if (this.autoOriented) {
+        var v1;
+        var v2;
+        frameRate = this.elem.globalData.frameRate;
+        if (this.p && this.p.keyframes && this.p.getValueAtTime) {
+          if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
+            v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0);
+          } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0);
+            v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0);
+          } else {
+            v1 = this.p.pv;
+            v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime);
+          }
+        } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) {
+          v1 = [];
+          v2 = [];
+          var px = this.px;
+          var py = this.py;
+          if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
+            v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
+            v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate, 0);
+          } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate), 0);
+            v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate), 0);
+            v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0);
+          } else {
+            v1 = [px.pv, py.pv];
+            v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime);
+            v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime);
+          }
+        } else {
+          v2 = defaultVector;
+          v1 = v2;
+        }
+        this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
+      }
+      if (this.data.p && this.data.p.s) {
+        if (this.data.p.z) {
+          this.v.translate(this.px.v, this.py.v, -this.pz.v);
+        } else {
+          this.v.translate(this.px.v, this.py.v, 0);
+        }
+      } else {
+        this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+      }
+    }
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function precalculateMatrix() {
+    this.appliedTransformations = 0;
+    this.pre.reset();
+
+    if (!this.a.effectsSequence.length) {
+      this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      this.appliedTransformations = 1;
+    } else {
+      return;
+    }
+    if (!this.s.effectsSequence.length) {
+      this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      this.appliedTransformations = 2;
+    } else {
+      return;
+    }
+    if (this.sk) {
+      if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
+        this.pre.skewFromAxis(-this.sk.v, this.sa.v);
+        this.appliedTransformations = 3;
+      } else {
+        return;
+      }
+    }
+    if (this.r) {
+      if (!this.r.effectsSequence.length) {
+        this.pre.rotate(-this.r.v);
+        this.appliedTransformations = 4;
+      }
+    } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) {
+      this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+      this.appliedTransformations = 4;
+    }
+  }
+
+  function autoOrient() {
+    //
+    // var prevP = this.getValueAtTime();
+  }
+
+  function addDynamicProperty(prop) {
+    this._addDynamicProperty(prop);
+    this.elem.addDynamicProperty(prop);
+    this._isDirty = true;
+  }
+
+  function TransformProperty(elem, data, container) {
+    this.elem = elem;
+    this.frameId = -1;
+    this.propType = 'transform';
+    this.data = data;
+    this.v = new Matrix();
+    // Precalculated matrix with non animated properties
+    this.pre = new Matrix();
+    this.appliedTransformations = 0;
+    this.initDynamicPropertyContainer(container || elem);
+    if (data.p && data.p.s) {
+      this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
+      this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
+      if (data.p.z) {
+        this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
+      }
+    } else {
+      this.p = PropertyFactory.getProp(elem, data.p || { k: [0, 0, 0] }, 1, 0, this);
+    }
+    if (data.rx) {
+      this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
+      this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
+      this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
+      if (data.or.k[0].ti) {
+        var i;
+        var len = data.or.k.length;
+        for (i = 0; i < len; i += 1) {
+          data.or.k[i].to = null;
+          data.or.k[i].ti = null;
+        }
+      }
+      this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+      // sh Indicates it needs to be capped between -180 and 180
+      this.or.sh = true;
+    } else {
+      this.r = PropertyFactory.getProp(elem, data.r || { k: 0 }, 0, degToRads, this);
+    }
+    if (data.sk) {
+      this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
+      this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
+    }
+    this.a = PropertyFactory.getProp(elem, data.a || { k: [0, 0, 0] }, 1, 0, this);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: [100, 100, 100] }, 1, 0.01, this);
+    // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
+    if (data.o) {
+      this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
+    } else {
+      this.o = { _mdf: false, v: 1 };
+    }
+    this._isDirty = true;
+    if (!this.dynamicProperties.length) {
+      this.getValue(true);
+    }
+  }
+
+  TransformProperty.prototype = {
+    applyToMatrix: applyToMatrix,
+    getValue: processKeys,
+    precalculateMatrix: precalculateMatrix,
+    autoOrient: autoOrient,
+  };
+
+  extendPrototype([DynamicPropertyContainer], TransformProperty);
+  TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
+  TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
+
+  function getTransformProperty(elem, data, container) {
+    return new TransformProperty(elem, data, container);
+  }
+
+  return {
+    getTransformProperty: getTransformProperty,
+  };
+}());
+
+function RepeaterModifier() {}
+extendPrototype([ShapeModifier], RepeaterModifier);
+
+RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, null, this);
+  this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this);
+  this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
+  this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
+  this.data = data;
+  if (!this.dynamicProperties.length) {
+    this.getValue(true);
+  }
+  this._isAnimated = !!this.dynamicProperties.length;
+  this.pMatrix = new Matrix();
+  this.rMatrix = new Matrix();
+  this.sMatrix = new Matrix();
+  this.tMatrix = new Matrix();
+  this.matrix = new Matrix();
+};
+
+RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
+  var dir = inv ? -1 : 1;
+  var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
+  var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
+  pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
+  rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  rMatrix.rotate(-transform.r.v * dir * perc);
+  rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+  sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
+  sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+};
+
+RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
+  this.elem = elem;
+  this.arr = arr;
+  this.pos = pos;
+  this.elemsData = elemsData;
+  this._currentCopies = 0;
+  this._elements = [];
+  this._groups = [];
+  this.frameId = -1;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, arr[pos]);
+  while (pos > 0) {
+    pos -= 1;
+    // this._elements.unshift(arr.splice(pos,1)[0]);
+    this._elements.unshift(arr[pos]);
+  }
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+
+RepeaterModifier.prototype.resetElements = function (elements) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._processed = false;
+    if (elements[i].ty === 'gr') {
+      this.resetElements(elements[i].it);
+    }
+  }
+};
+
+RepeaterModifier.prototype.cloneElements = function (elements) {
+  var newElements = JSON.parse(JSON.stringify(elements));
+  this.resetElements(newElements);
+  return newElements;
+};
+
+RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._render = renderFlag;
+    if (elements[i].ty === 'gr') {
+      this.changeGroupRender(elements[i].it, renderFlag);
+    }
+  }
+};
+
+RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
+  var items;
+  var itemsTransform;
+  var i;
+  var dir;
+  var cont;
+  var hasReloaded = false;
+  if (this._mdf || _isFirstFrame) {
+    var copies = Math.ceil(this.c.v);
+    if (this._groups.length < copies) {
+      while (this._groups.length < copies) {
+        var group = {
+          it: this.cloneElements(this._elements),
+          ty: 'gr',
+        };
+        group.it.push({
+          a: { a: 0, ix: 1, k: [0, 0] }, nm: 'Transform', o: { a: 0, ix: 7, k: 100 }, p: { a: 0, ix: 2, k: [0, 0] }, r: { a: 1, ix: 6, k: [{ s: 0, e: 0, t: 0 }, { s: 0, e: 0, t: 1 }] }, s: { a: 0, ix: 3, k: [100, 100] }, sa: { a: 0, ix: 5, k: 0 }, sk: { a: 0, ix: 4, k: 0 }, ty: 'tr',
+        });
+
+        this.arr.splice(0, 0, group);
+        this._groups.splice(0, 0, group);
+        this._currentCopies += 1;
+      }
+      this.elem.reloadShapes();
+      hasReloaded = true;
+    }
+    cont = 0;
+    var renderFlag;
+    for (i = 0; i <= this._groups.length - 1; i += 1) {
+      renderFlag = cont < copies;
+      this._groups[i]._render = renderFlag;
+      this.changeGroupRender(this._groups[i].it, renderFlag);
+      if (!renderFlag) {
+        var elems = this.elemsData[i].it;
+        var transformData = elems[elems.length - 1];
+        if (transformData.transform.op.v !== 0) {
+          transformData.transform.op._mdf = true;
+          transformData.transform.op.v = 0;
+        } else {
+          transformData.transform.op._mdf = false;
+        }
+      }
+      cont += 1;
+    }
+
+    this._currentCopies = copies;
+    /// /
+
+    var offset = this.o.v;
+    var offsetModulo = offset % 1;
+    var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
+    var pProps = this.pMatrix.props;
+    var rProps = this.rMatrix.props;
+    var sProps = this.sMatrix.props;
+    this.pMatrix.reset();
+    this.rMatrix.reset();
+    this.sMatrix.reset();
+    this.tMatrix.reset();
+    this.matrix.reset();
+    var iteration = 0;
+
+    if (offset > 0) {
+      while (iteration < roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        iteration += 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
+        iteration += offsetModulo;
+      }
+    } else if (offset < 0) {
+      while (iteration > roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
+        iteration -= 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
+        iteration -= offsetModulo;
+      }
+    }
+    i = this.data.m === 1 ? 0 : this._currentCopies - 1;
+    dir = this.data.m === 1 ? 1 : -1;
+    cont = this._currentCopies;
+    var j;
+    var jLen;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      jLen = itemsTransform.length;
+      items[items.length - 1].transform.mProps._mdf = true;
+      items[items.length - 1].transform.op._mdf = true;
+      items[items.length - 1].transform.op.v = this._currentCopies === 1
+        ? this.so.v
+        : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
+
+      if (iteration !== 0) {
+        if ((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)) {
+          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        }
+        this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
+        this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
+        this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
+
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+        this.matrix.reset();
+      } else {
+        this.matrix.reset();
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+      }
+      iteration += 1;
+      cont -= 1;
+      i += dir;
+    }
+  } else {
+    cont = this._currentCopies;
+    i = 0;
+    dir = 1;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      items[items.length - 1].transform.mProps._mdf = false;
+      items[items.length - 1].transform.op._mdf = false;
+      cont -= 1;
+      i += dir;
+    }
+  }
+  return hasReloaded;
+};
+
+RepeaterModifier.prototype.addShape = function () {};
+
+function RoundCornersModifier() {}
+extendPrototype([ShapeModifier], RoundCornersModifier);
+RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this._isAnimated = !!this.rd.effectsSequence.length;
+};
+
+RoundCornersModifier.prototype.processPath = function (path, round) {
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var i;
+  var len = path._length;
+  var currentV;
+  var currentI;
+  var currentO;
+  var closerV;
+  var distance;
+  var newPosPerc;
+  var index = 0;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < len; i += 1) {
+    currentV = path.v[i];
+    currentO = path.o[i];
+    currentI = path.i[i];
+    if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
+      if ((i === 0 || i === len - 1) && !path.c) {
+        clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
+        /* clonedPath.v[index] = currentV;
+                clonedPath.o[index] = currentO;
+                clonedPath.i[index] = currentI; */
+        index += 1;
+      } else {
+        if (i === 0) {
+          closerV = path.v[len - 1];
+        } else {
+          closerV = path.v[i - 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = iX;
+        iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
+        vY = iY;
+        oX = vX - (vX - currentV[0]) * roundCorner;
+        oY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+
+        if (i === len - 1) {
+          closerV = path.v[0];
+        } else {
+          closerV = path.v[i + 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = oX;
+        oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc;
+        vY = oY;
+        iX = vX - (vX - currentV[0]) * roundCorner;
+        iY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+      }
+    } else {
+      clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index);
+      index += 1;
+    }
+  }
+  return clonedPath;
+};
+
+RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var rd = this.rd.v;
+
+  if (rd !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function floatEqual(a, b) {
+  return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
+}
+
+function floatZero(f) {
+  return Math.abs(f) <= 0.00001;
+}
+
+function lerp(p0, p1, amount) {
+  return p0 * (1 - amount) + p1 * amount;
+}
+
+function lerpPoint(p0, p1, amount) {
+  return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
+}
+
+function quadRoots(a, b, c) {
+  // no root
+  if (a === 0) return [];
+  var s = b * b - 4 * a * c;
+  // Complex roots
+  if (s < 0) return [];
+  var singleRoot = -b / (2 * a);
+  // 1 root
+  if (s === 0) return [singleRoot];
+  var delta = Math.sqrt(s) / (2 * a);
+  // 2 roots
+  return [singleRoot - delta, singleRoot + delta];
+}
+
+function polynomialCoefficients(p0, p1, p2, p3) {
+  return [
+    -p0 + 3 * p1 - 3 * p2 + p3,
+    3 * p0 - 6 * p1 + 3 * p2,
+    -3 * p0 + 3 * p1,
+    p0,
+  ];
+}
+
+function singlePoint(p) {
+  return new PolynomialBezier(p, p, p, p, false);
+}
+
+function PolynomialBezier(p0, p1, p2, p3, linearize) {
+  if (linearize && pointEqual(p0, p1)) {
+    p1 = lerpPoint(p0, p3, 1 / 3);
+  }
+  if (linearize && pointEqual(p2, p3)) {
+    p2 = lerpPoint(p0, p3, 2 / 3);
+  }
+  var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
+  var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
+  this.a = [coeffx[0], coeffy[0]];
+  this.b = [coeffx[1], coeffy[1]];
+  this.c = [coeffx[2], coeffy[2]];
+  this.d = [coeffx[3], coeffy[3]];
+  this.points = [p0, p1, p2, p3];
+}
+PolynomialBezier.prototype.point = function (t) {
+  return [
+    (((this.a[0] * t) + this.b[0]) * t + this.c[0]) * t + this.d[0],
+    (((this.a[1] * t) + this.b[1]) * t + this.c[1]) * t + this.d[1],
+  ];
+};
+PolynomialBezier.prototype.derivative = function (t) {
+  return [
+    (3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0],
+    (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1],
+  ];
+};
+PolynomialBezier.prototype.tangentAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[1], p[0]);
+};
+PolynomialBezier.prototype.normalAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[0], p[1]);
+};
+
+PolynomialBezier.prototype.inflectionPoints = function () {
+  var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
+  if (floatZero(denom)) return [];
+  var tcusp = (-0.5 * (this.a[1] * this.c[0] - this.a[0] * this.c[1])) / denom;
+  var square = tcusp * tcusp - ((1 / 3) * (this.b[1] * this.c[0] - this.b[0] * this.c[1])) / denom;
+  if (square < 0) return [];
+  var root = Math.sqrt(square);
+  if (floatZero(root)) {
+    if (root > 0 && root < 1) return [tcusp];
+    return [];
+  }
+  return [tcusp - root, tcusp + root].filter(function (r) { return r > 0 && r < 1; });
+};
+PolynomialBezier.prototype.split = function (t) {
+  if (t <= 0) return [singlePoint(this.points[0]), this];
+  if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
+  var p10 = lerpPoint(this.points[0], this.points[1], t);
+  var p11 = lerpPoint(this.points[1], this.points[2], t);
+  var p12 = lerpPoint(this.points[2], this.points[3], t);
+  var p20 = lerpPoint(p10, p11, t);
+  var p21 = lerpPoint(p11, p12, t);
+  var p3 = lerpPoint(p20, p21, t);
+  return [
+    new PolynomialBezier(this.points[0], p10, p20, p3, true),
+    new PolynomialBezier(p3, p21, p12, this.points[3], true),
+  ];
+};
+function extrema(bez, comp) {
+  var min = bez.points[0][comp];
+  var max = bez.points[bez.points.length - 1][comp];
+  if (min > max) {
+    var e = max;
+    max = min;
+    min = e;
+  }
+  // Derivative roots to find min/max
+  var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
+  for (var i = 0; i < f.length; i += 1) {
+    if (f[i] > 0 && f[i] < 1) {
+      var val = bez.point(f[i])[comp];
+      if (val < min) min = val;
+      else if (val > max) max = val;
+    }
+  }
+  return {
+    min: min,
+    max: max,
+  };
+}
+PolynomialBezier.prototype.bounds = function () {
+  return {
+    x: extrema(this, 0),
+    y: extrema(this, 1),
+  };
+};
+PolynomialBezier.prototype.boundingBox = function () {
+  var bounds = this.bounds();
+  return {
+    left: bounds.x.min,
+    right: bounds.x.max,
+    top: bounds.y.min,
+    bottom: bounds.y.max,
+    width: bounds.x.max - bounds.x.min,
+    height: bounds.y.max - bounds.y.min,
+    cx: (bounds.x.max + bounds.x.min) / 2,
+    cy: (bounds.y.max + bounds.y.min) / 2,
+  };
+};
+
+function intersectData(bez, t1, t2) {
+  var box = bez.boundingBox();
+  return {
+    cx: box.cx,
+    cy: box.cy,
+    width: box.width,
+    height: box.height,
+    bez: bez,
+    t: (t1 + t2) / 2,
+    t1: t1,
+    t2: t2,
+  };
+}
+function splitData(data) {
+  var split = data.bez.split(0.5);
+  return [
+    intersectData(split[0], data.t1, data.t),
+    intersectData(split[1], data.t, data.t2),
+  ];
+}
+
+function boxIntersect(b1, b2) {
+  return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width
+    && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
+}
+
+function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
+  if (!boxIntersect(d1, d2)) return;
+  if (depth >= maxRecursion || (d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance)) {
+    intersections.push([d1.t, d2.t]);
+    return;
+  }
+  var d1s = splitData(d1);
+  var d2s = splitData(d2);
+  intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[0], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+}
+
+PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
+  if (tolerance === undefined) tolerance = 2;
+  if (maxRecursion === undefined) maxRecursion = 7;
+  var intersections = [];
+  intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
+  return intersections;
+};
+
+PolynomialBezier.shapeSegment = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
+};
+
+PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
+};
+
+function crossProduct(a, b) {
+  return [
+    a[1] * b[2] - a[2] * b[1],
+    a[2] * b[0] - a[0] * b[2],
+    a[0] * b[1] - a[1] * b[0],
+  ];
+}
+
+function lineIntersection(start1, end1, start2, end2) {
+  var v1 = [start1[0], start1[1], 1];
+  var v2 = [end1[0], end1[1], 1];
+  var v3 = [start2[0], start2[1], 1];
+  var v4 = [end2[0], end2[1], 1];
+
+  var r = crossProduct(
+    crossProduct(v1, v2),
+    crossProduct(v3, v4)
+  );
+
+  if (floatZero(r[2])) return null;
+
+  return [r[0] / r[2], r[1] / r[2]];
+}
+
+function polarOffset(p, angle, length) {
+  return [
+    p[0] + Math.cos(angle) * length,
+    p[1] - Math.sin(angle) * length,
+  ];
+}
+
+function pointDistance(p1, p2) {
+  return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
+}
+
+function pointEqual(p1, p2) {
+  return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
+}
+
+function ZigZagModifier() {}
+extendPrototype([ShapeModifier], ZigZagModifier);
+ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
+  this.frequency = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
+  this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
+};
+
+function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
+  var angO = angle - Math.PI / 2;
+  var angI = angle + Math.PI / 2;
+  var px = point[0] + Math.cos(angle) * direction * amplitude;
+  var py = point[1] - Math.sin(angle) * direction * amplitude;
+
+  outputBezier.setTripleAt(
+    px,
+    py,
+    px + Math.cos(angO) * outAmplitude,
+    py - Math.sin(angO) * outAmplitude,
+    px + Math.cos(angI) * inAmplitude,
+    py - Math.sin(angI) * inAmplitude,
+    outputBezier.length()
+  );
+}
+
+function getPerpendicularVector(pt1, pt2) {
+  var vector = [
+    pt2[0] - pt1[0],
+    pt2[1] - pt1[1],
+  ];
+  var rot = -Math.PI * 0.5;
+  var rotatedVector = [
+    Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1],
+    Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1],
+  ];
+  return rotatedVector;
+}
+
+function getProjectingAngle(path, cur) {
+  var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
+  var nextIndex = (cur + 1) % path.length();
+  var prevPoint = path.v[prevIndex];
+  var nextPoint = path.v[nextIndex];
+  var pVector = getPerpendicularVector(prevPoint, nextPoint);
+  return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
+}
+
+function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
+  var angle = getProjectingAngle(path, cur);
+  var point = path.v[cur % path._length];
+  var prevPoint = path.v[cur === 0 ? path._length - 1 : cur - 1];
+  var nextPoint = path.v[(cur + 1) % path._length];
+  var prevDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - prevPoint[0], 2) + Math.pow(point[1] - prevPoint[1], 2))
+    : 0;
+  var nextDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2))
+    : 0;
+
+  setPoint(
+    outputBezier,
+    path.v[cur % path._length],
+    angle,
+    direction,
+    amplitude,
+    nextDist / ((frequency + 1) * 2),
+    prevDist / ((frequency + 1) * 2),
+    pointType
+  );
+}
+
+function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
+  for (var i = 0; i < frequency; i += 1) {
+    var t = (i + 1) / (frequency + 1);
+
+    var dist = pointType === 2
+      ? Math.sqrt(Math.pow(segment.points[3][0] - segment.points[0][0], 2) + Math.pow(segment.points[3][1] - segment.points[0][1], 2))
+      : 0;
+
+    var angle = segment.normalAngle(t);
+    var point = segment.point(t);
+    setPoint(
+      outputBezier,
+      point,
+      angle,
+      direction,
+      amplitude,
+      dist / ((frequency + 1) * 2),
+      dist / ((frequency + 1) * 2),
+      pointType
+    );
+
+    direction = -direction;
+  }
+
+  return direction;
+}
+
+ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
+  var count = path._length;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+
+  if (!path.c) {
+    count -= 1;
+  }
+
+  if (count === 0) return clonedPath;
+
+  var direction = -1;
+  var segment = PolynomialBezier.shapeSegment(path, 0);
+  zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
+
+  for (var i = 0; i < count; i += 1) {
+    direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
+
+    if (i === count - 1 && !path.c) {
+      segment = null;
+    } else {
+      segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
+    }
+
+    zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
+  }
+
+  return clonedPath;
+};
+
+ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amplitude = this.amplitude.v;
+  var frequency = Math.max(0, Math.round(this.frequency.v));
+  var pointType = this.pointsType.v;
+
+  if (amplitude !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function linearOffset(p1, p2, amount) {
+  var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
+  return [
+    polarOffset(p1, angle, amount),
+    polarOffset(p2, angle, amount),
+  ];
+}
+
+function offsetSegment(segment, amount) {
+  var p0; var p1a; var p1b; var p2b; var p2a; var
+    p3;
+  var e;
+  e = linearOffset(segment.points[0], segment.points[1], amount);
+  p0 = e[0];
+  p1a = e[1];
+  e = linearOffset(segment.points[1], segment.points[2], amount);
+  p1b = e[0];
+  p2b = e[1];
+  e = linearOffset(segment.points[2], segment.points[3], amount);
+  p2a = e[0];
+  p3 = e[1];
+  var p1 = lineIntersection(p0, p1a, p1b, p2b);
+  if (p1 === null) p1 = p1a;
+  var p2 = lineIntersection(p2a, p3, p1b, p2b);
+  if (p2 === null) p2 = p2a;
+
+  return new PolynomialBezier(p0, p1, p2, p3);
+}
+
+function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
+  var p0 = seg1.points[3];
+  var p1 = seg2.points[0];
+
+  // Bevel
+  if (lineJoin === 3) return p0;
+
+  // Connected, they don't need a joint
+  if (pointEqual(p0, p1)) return p0;
+
+  // Round
+  if (lineJoin === 2) {
+    var angleOut = -seg1.tangentAngle(1);
+    var angleIn = -seg2.tangentAngle(0) + Math.PI;
+    var center = lineIntersection(
+      p0,
+      polarOffset(p0, angleOut + Math.PI / 2, 100),
+      p1,
+      polarOffset(p1, angleOut + Math.PI / 2, 100)
+    );
+    var radius = center ? pointDistance(center, p0) : pointDistance(p0, p1) / 2;
+
+    var tan = polarOffset(p0, angleOut, 2 * radius * roundCorner);
+    outputBezier.setXYAt(tan[0], tan[1], 'o', outputBezier.length() - 1);
+
+    tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
+    outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
+
+    return p1;
+  }
+
+  // Miter
+  var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
+  var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
+  var intersection = lineIntersection(t0, p0, p1, t1);
+  if (intersection && pointDistance(intersection, p0) < miterLimit) {
+    outputBezier.setTripleAt(
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      outputBezier.length()
+    );
+    return intersection;
+  }
+
+  return p0;
+}
+
+function getIntersection(a, b) {
+  const intersect = a.intersections(b);
+
+  if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
+
+  if (intersect.length) return intersect[0];
+
+  return null;
+}
+
+function pruneSegmentIntersection(a, b) {
+  var outa = a.slice();
+  var outb = b.slice();
+  var intersect = getIntersection(a[a.length - 1], b[0]);
+  if (intersect) {
+    outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
+    outb[0] = b[0].split(intersect[1])[1];
+  }
+  if (a.length > 1 && b.length > 1) {
+    intersect = getIntersection(a[0], b[b.length - 1]);
+    if (intersect) {
+      return [
+        [a[0].split(intersect[0])[0]],
+        [b[b.length - 1].split(intersect[1])[1]],
+      ];
+    }
+  }
+  return [outa, outb];
+}
+
+function pruneIntersections(segments) {
+  var e;
+  for (var i = 1; i < segments.length; i += 1) {
+    e = pruneSegmentIntersection(segments[i - 1], segments[i]);
+    segments[i - 1] = e[0];
+    segments[i] = e[1];
+  }
+
+  if (segments.length > 1) {
+    e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
+    segments[segments.length - 1] = e[0];
+    segments[0] = e[1];
+  }
+
+  return segments;
+}
+
+function offsetSegmentSplit(segment, amount) {
+  /*
+    We split each bezier segment into smaller pieces based
+    on inflection points, this ensures the control point
+    polygon is convex.
+
+    (A cubic bezier can have none, one, or two inflection points)
+  */
+  var flex = segment.inflectionPoints();
+  var left;
+  var right;
+  var split;
+  var mid;
+
+  if (flex.length === 0) {
+    return [offsetSegment(segment, amount)];
+  }
+
+  if (flex.length === 1 || floatEqual(flex[1], 1)) {
+    split = segment.split(flex[0]);
+    left = split[0];
+    right = split[1];
+
+    return [
+      offsetSegment(left, amount),
+      offsetSegment(right, amount),
+    ];
+  }
+
+  split = segment.split(flex[0]);
+  left = split[0];
+  var t = (flex[1] - flex[0]) / (1 - flex[0]);
+  split = split[1].split(t);
+  mid = split[0];
+  right = split[1];
+
+  return [
+    offsetSegment(left, amount),
+    offsetSegment(mid, amount),
+    offsetSegment(right, amount),
+  ];
+}
+
+function OffsetPathModifier() {}
+
+extendPrototype([ShapeModifier], OffsetPathModifier);
+OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this.miterLimit = PropertyFactory.getProp(elem, data.ml, 0, null, this);
+  this.lineJoin = data.lj;
+  this._isAnimated = this.amount.effectsSequence.length !== 0;
+};
+
+OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
+  var outputBezier = shapePool.newElement();
+  outputBezier.c = inputBezier.c;
+  var count = inputBezier.length();
+  if (!inputBezier.c) {
+    count -= 1;
+  }
+  var i; var j; var segment;
+  var multiSegments = [];
+
+  for (i = 0; i < count; i += 1) {
+    segment = PolynomialBezier.shapeSegment(inputBezier, i);
+    multiSegments.push(offsetSegmentSplit(segment, amount));
+  }
+
+  if (!inputBezier.c) {
+    for (i = count - 1; i >= 0; i -= 1) {
+      segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
+      multiSegments.push(offsetSegmentSplit(segment, amount));
+    }
+  }
+
+  multiSegments = pruneIntersections(multiSegments);
+
+  // Add bezier segments to the output and apply line joints
+  var lastPoint = null;
+  var lastSeg = null;
+
+  for (i = 0; i < multiSegments.length; i += 1) {
+    var multiSegment = multiSegments[i];
+
+    if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
+
+    lastSeg = multiSegment[multiSegment.length - 1];
+
+    for (j = 0; j < multiSegment.length; j += 1) {
+      segment = multiSegment[j];
+
+      if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
+        outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
+      } else {
+        outputBezier.setTripleAt(
+          segment.points[0][0],
+          segment.points[0][1],
+          segment.points[1][0],
+          segment.points[1][1],
+          segment.points[0][0],
+          segment.points[0][1],
+          outputBezier.length()
+        );
+      }
+
+      outputBezier.setTripleAt(
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[2][0],
+        segment.points[2][1],
+        outputBezier.length()
+      );
+
+      lastPoint = segment.points[3];
+    }
+  }
+
+  if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
+
+  return outputBezier;
+};
+
+OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+  var miterLimit = this.miterLimit.v;
+  var lineJoin = this.lineJoin;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function getFontProperties(fontData) {
+  var styles = fontData.fStyle ? fontData.fStyle.split(' ') : [];
+
+  var fWeight = 'normal'; var
+    fStyle = 'normal';
+  var len = styles.length;
+  var styleName;
+  for (var i = 0; i < len; i += 1) {
+    styleName = styles[i].toLowerCase();
+    switch (styleName) {
+      case 'italic':
+        fStyle = 'italic';
+        break;
+      case 'bold':
+        fWeight = '700';
+        break;
+      case 'black':
+        fWeight = '900';
+        break;
+      case 'medium':
+        fWeight = '500';
+        break;
+      case 'regular':
+      case 'normal':
+        fWeight = '400';
+        break;
+      case 'light':
+      case 'thin':
+        fWeight = '200';
+        break;
+      default:
+        break;
+    }
+  }
+
+  return {
+    style: fStyle,
+    weight: fontData.fWeight || fWeight,
+  };
+}
+
+const FontManager = (function () {
+  var maxWaitingTime = 5000;
+  var emptyChar = {
+    w: 0,
+    size: 0,
+    shapes: [],
+    data: {
+      shapes: [],
+    },
+  };
+  var combinedCharacters = [];
+  // Hindi characters
+  combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366,
+    2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379,
+    2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
+
+  var BLACK_FLAG_CODE_POINT = 127988;
+  var CANCEL_TAG_CODE_POINT = 917631;
+  var A_TAG_CODE_POINT = 917601;
+  var Z_TAG_CODE_POINT = 917626;
+  var VARIATION_SELECTOR_16_CODE_POINT = 65039;
+  var ZERO_WIDTH_JOINER_CODE_POINT = 8205;
+  var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
+  var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
+
+  var surrogateModifiers = [
+    'd83cdffb',
+    'd83cdffc',
+    'd83cdffd',
+    'd83cdffe',
+    'd83cdfff',
+  ];
+
+  function trimFontOptions(font) {
+    var familyArray = font.split(',');
+    var i;
+    var len = familyArray.length;
+    var enabledFamilies = [];
+    for (i = 0; i < len; i += 1) {
+      if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
+        enabledFamilies.push(familyArray[i]);
+      }
+    }
+    return enabledFamilies.join(',');
+  }
+
+  function setUpNode(font, family) {
+    var parentNode = createTag('span');
+    // Node is invisible to screen readers.
+    parentNode.setAttribute('aria-hidden', true);
+    parentNode.style.fontFamily = family;
+    var node = createTag('span');
+    // Characters that vary significantly among different fonts
+    node.innerText = 'giItT1WQy@!-/#';
+    // Visible - so we can measure it - but not on the screen
+    parentNode.style.position = 'absolute';
+    parentNode.style.left = '-10000px';
+    parentNode.style.top = '-10000px';
+    // Large font size makes even subtle changes obvious
+    parentNode.style.fontSize = '300px';
+    // Reset any font properties
+    parentNode.style.fontVariant = 'normal';
+    parentNode.style.fontStyle = 'normal';
+    parentNode.style.fontWeight = 'normal';
+    parentNode.style.letterSpacing = '0';
+    parentNode.appendChild(node);
+    document.body.appendChild(parentNode);
+
+    // Remember width with no applied web font
+    var width = node.offsetWidth;
+    node.style.fontFamily = trimFontOptions(font) + ', ' + family;
+    return { node: node, w: width, parent: parentNode };
+  }
+
+  function checkLoadedFonts() {
+    var i;
+    var len = this.fonts.length;
+    var node;
+    var w;
+    var loadedCount = len;
+    for (i = 0; i < len; i += 1) {
+      if (this.fonts[i].loaded) {
+        loadedCount -= 1;
+      } else if (this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0) {
+        this.fonts[i].loaded = true;
+      } else {
+        node = this.fonts[i].monoCase.node;
+        w = this.fonts[i].monoCase.w;
+        if (node.offsetWidth !== w) {
+          loadedCount -= 1;
+          this.fonts[i].loaded = true;
+        } else {
+          node = this.fonts[i].sansCase.node;
+          w = this.fonts[i].sansCase.w;
+          if (node.offsetWidth !== w) {
+            loadedCount -= 1;
+            this.fonts[i].loaded = true;
+          }
+        }
+        if (this.fonts[i].loaded) {
+          this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
+          this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
+        }
+      }
+    }
+
+    if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
+      setTimeout(this.checkLoadedFontsBinded, 20);
+    } else {
+      setTimeout(this.setIsLoadedBinded, 10);
+    }
+  }
+
+  function createHelper(fontData, def) {
+    var engine = (document.body && def) ? 'svg' : 'canvas';
+    var helper;
+    var fontProps = getFontProperties(fontData);
+    if (engine === 'svg') {
+      var tHelper = createNS('text');
+      tHelper.style.fontSize = '100px';
+      // tHelper.style.fontFamily = fontData.fFamily;
+      tHelper.setAttribute('font-family', fontData.fFamily);
+      tHelper.setAttribute('font-style', fontProps.style);
+      tHelper.setAttribute('font-weight', fontProps.weight);
+      tHelper.textContent = '1';
+      if (fontData.fClass) {
+        tHelper.style.fontFamily = 'inherit';
+        tHelper.setAttribute('class', fontData.fClass);
+      } else {
+        tHelper.style.fontFamily = fontData.fFamily;
+      }
+      def.appendChild(tHelper);
+      helper = tHelper;
+    } else {
+      var tCanvasHelper = new OffscreenCanvas(500, 500).getContext('2d');
+      tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
+      helper = tCanvasHelper;
+    }
+    function measure(text) {
+      if (engine === 'svg') {
+        helper.textContent = text;
+        return helper.getComputedTextLength();
+      }
+      return helper.measureText(text).width;
+    }
+    return {
+      measureText: measure,
+    };
+  }
+
+  function addFonts(fontData, defs) {
+    if (!fontData) {
+      this.isLoaded = true;
+      return;
+    }
+    if (this.chars) {
+      this.isLoaded = true;
+      this.fonts = fontData.list;
+      return;
+    }
+    if (!document.body) {
+      this.isLoaded = true;
+      fontData.list.forEach((data) => {
+        data.helper = createHelper(data);
+        data.cache = {};
+      });
+      this.fonts = fontData.list;
+      return;
+    }
+
+    var fontArr = fontData.list;
+    var i;
+    var len = fontArr.length;
+    var _pendingFonts = len;
+    for (i = 0; i < len; i += 1) {
+      var shouldLoadFont = true;
+      var loadedSelector;
+      var j;
+      fontArr[i].loaded = false;
+      fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
+      fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
+      if (!fontArr[i].fPath) {
+        fontArr[i].loaded = true;
+        _pendingFonts -= 1;
+      } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
+        loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
+
+        if (loadedSelector.length > 0) {
+          shouldLoadFont = false;
+        }
+
+        if (shouldLoadFont) {
+          var s = createTag('style');
+          s.setAttribute('f-forigin', fontArr[i].fOrigin);
+          s.setAttribute('f-origin', fontArr[i].origin);
+          s.setAttribute('f-family', fontArr[i].fFamily);
+          s.type = 'text/css';
+          s.innerText = '@font-face {font-family: ' + fontArr[i].fFamily + "; font-style: normal; src: url('" + fontArr[i].fPath + "');}";
+          defs.appendChild(s);
+        }
+      } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
+        loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var l = createTag('link');
+          l.setAttribute('f-forigin', fontArr[i].fOrigin);
+          l.setAttribute('f-origin', fontArr[i].origin);
+          l.type = 'text/css';
+          l.rel = 'stylesheet';
+          l.href = fontArr[i].fPath;
+          document.body.appendChild(l);
+        }
+      } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
+        loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (fontArr[i].fPath === loadedSelector[j].src) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var sc = createTag('link');
+          sc.setAttribute('f-forigin', fontArr[i].fOrigin);
+          sc.setAttribute('f-origin', fontArr[i].origin);
+          sc.setAttribute('rel', 'stylesheet');
+          sc.setAttribute('href', fontArr[i].fPath);
+          defs.appendChild(sc);
+        }
+      }
+      fontArr[i].helper = createHelper(fontArr[i], defs);
+      fontArr[i].cache = {};
+      this.fonts.push(fontArr[i]);
+    }
+    if (_pendingFonts === 0) {
+      this.isLoaded = true;
+    } else {
+      // On some cases even if the font is loaded, it won't load correctly when measuring text on canvas.
+      // Adding this timeout seems to fix it
+      setTimeout(this.checkLoadedFonts.bind(this), 100);
+    }
+  }
+
+  function addChars(chars) {
+    if (!chars) {
+      return;
+    }
+    if (!this.chars) {
+      this.chars = [];
+    }
+    var i;
+    var len = chars.length;
+    var j;
+    var jLen = this.chars.length;
+    var found;
+    for (i = 0; i < len; i += 1) {
+      j = 0;
+      found = false;
+      while (j < jLen) {
+        if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
+          found = true;
+        }
+        j += 1;
+      }
+      if (!found) {
+        this.chars.push(chars[i]);
+        jLen += 1;
+      }
+    }
+  }
+
+  function getCharData(char, style, font) {
+    var i = 0;
+    var len = this.chars.length;
+    while (i < len) {
+      if (this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font) {
+        return this.chars[i];
+      }
+      i += 1;
+    }
+    if (((typeof char === 'string' && char.charCodeAt(0) !== 13) || !char)
+            && console
+            && console.warn // eslint-disable-line no-console
+            && !this._warned
+    ) {
+      this._warned = true;
+      console.warn('Missing character from exported characters list: ', char, style, font); // eslint-disable-line no-console
+    }
+    return emptyChar;
+  }
+
+  function measureText(char, fontName, size) {
+    var fontData = this.getFontByName(fontName);
+    // Using the char instead of char.charCodeAt(0)
+    // to avoid collisions between equal chars
+    var index = char;
+    if (!fontData.cache[index]) {
+      var tHelper = fontData.helper;
+      if (char === ' ') {
+        var doubleSize = tHelper.measureText('|' + char + '|');
+        var singleSize = tHelper.measureText('||');
+        fontData.cache[index] = (doubleSize - singleSize) / 100;
+      } else {
+        fontData.cache[index] = tHelper.measureText(char) / 100;
+      }
+    }
+    return fontData.cache[index] * size;
+  }
+
+  function getFontByName(name) {
+    var i = 0;
+    var len = this.fonts.length;
+    while (i < len) {
+      if (this.fonts[i].fName === name) {
+        return this.fonts[i];
+      }
+      i += 1;
+    }
+    return this.fonts[0];
+  }
+
+  function getCodePoint(string) {
+    var codePoint = 0;
+    var first = string.charCodeAt(0);
+    if (first >= 0xD800 && first <= 0xDBFF) {
+      var second = string.charCodeAt(1);
+      if (second >= 0xDC00 && second <= 0xDFFF) {
+        codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+      }
+    }
+    return codePoint;
+  }
+
+  // Skin tone modifiers
+  function isModifier(firstCharCode, secondCharCode) {
+    var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
+    return surrogateModifiers.indexOf(sum) !== -1;
+  }
+
+  function isZeroWidthJoiner(charCode) {
+    return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
+  }
+
+  // This codepoint may change the appearance of the preceding character.
+  // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
+  // as a colorful image as compared to a monochrome text variant.
+  function isVariationSelector(charCode) {
+    return charCode === VARIATION_SELECTOR_16_CODE_POINT;
+  }
+
+  // The regional indicator symbols are a set of 26 alphabetic Unicode
+  /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
+  // two-letter country codes in a way that allows optional special treatment.
+  function isRegionalCode(string) {
+    var codePoint = getCodePoint(string);
+    if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
+      return true;
+    }
+    return false;
+  }
+
+  // Some Emoji implementations represent combinations of
+  // two “regional indicator” letters as a single flag symbol.
+  function isFlagEmoji(string) {
+    return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
+  }
+
+  function isCombinedCharacter(char) {
+    return combinedCharacters.indexOf(char) !== -1;
+  }
+
+  // Regional flags start with a BLACK_FLAG_CODE_POINT
+  // folowed by 5 chars in the TAG range
+  // and end with a CANCEL_TAG_CODE_POINT
+  function isRegionalFlag(text, index) {
+    var codePoint = getCodePoint(text.substr(index, 2));
+    if (codePoint !== BLACK_FLAG_CODE_POINT) {
+      return false;
+    }
+    var count = 0;
+    index += 2;
+    while (count < 5) {
+      codePoint = getCodePoint(text.substr(index, 2));
+      if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
+        return false;
+      }
+      count += 1;
+      index += 2;
+    }
+    return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
+  }
+
+  function setIsLoaded() {
+    this.isLoaded = true;
+  }
+
+  var Font = function () {
+    this.fonts = [];
+    this.chars = null;
+    this.typekitLoaded = 0;
+    this.isLoaded = false;
+    this._warned = false;
+    this.initTime = Date.now();
+    this.setIsLoadedBinded = this.setIsLoaded.bind(this);
+    this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
+  };
+  Font.isModifier = isModifier;
+  Font.isZeroWidthJoiner = isZeroWidthJoiner;
+  Font.isFlagEmoji = isFlagEmoji;
+  Font.isRegionalCode = isRegionalCode;
+  Font.isCombinedCharacter = isCombinedCharacter;
+  Font.isRegionalFlag = isRegionalFlag;
+  Font.isVariationSelector = isVariationSelector;
+  Font.BLACK_FLAG_CODE_POINT = BLACK_FLAG_CODE_POINT;
+
+  var fontPrototype = {
+    addChars: addChars,
+    addFonts: addFonts,
+    getCharData: getCharData,
+    getFontByName: getFontByName,
+    measureText: measureText,
+    checkLoadedFonts: checkLoadedFonts,
+    setIsLoaded: setIsLoaded,
+  };
+
+  Font.prototype = fontPrototype;
+
+  return Font;
+}());
+
+function SlotManager(animationData) {
+  this.animationData = animationData;
+}
+SlotManager.prototype.getProp = function (data) {
+  if (this.animationData.slots
+    && this.animationData.slots[data.sid]
+  ) {
+    return Object.assign(data, this.animationData.slots[data.sid].p);
+  }
+  return data;
+};
+
+function slotFactory(animationData) {
+  return new SlotManager(animationData);
+}
+
+function RenderableElement() {
+
+}
+
+RenderableElement.prototype = {
+  initRenderable: function () {
+    // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
+    this.isInRange = false;
+    // layer's display state
+    this.hidden = false;
+    // If layer's transparency equals 0, it can be hidden
+    this.isTransparent = false;
+    // list of animated components
+    this.renderableComponents = [];
+  },
+  addRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) === -1) {
+      this.renderableComponents.push(component);
+    }
+  },
+  removeRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) !== -1) {
+      this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1);
+    }
+  },
+  prepareRenderableFrame: function (num) {
+    this.checkLayerLimits(num);
+  },
+  checkTransparency: function () {
+    if (this.finalTransform.mProp.o.v <= 0) {
+      if (!this.isTransparent && this.globalData.renderConfig.hideOnTransparent) {
+        this.isTransparent = true;
+        this.hide();
+      }
+    } else if (this.isTransparent) {
+      this.isTransparent = false;
+      this.show();
+    }
+  },
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     *
+     */
+  checkLayerLimits: function (num) {
+    if (this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) {
+      if (this.isInRange !== true) {
+        this.globalData._mdf = true;
+        this._mdf = true;
+        this.isInRange = true;
+        this.show();
+      }
+    } else if (this.isInRange !== false) {
+      this.globalData._mdf = true;
+      this.isInRange = false;
+      this.hide();
+    }
+  },
+  renderRenderable: function () {
+    var i;
+    var len = this.renderableComponents.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderableComponents[i].renderFrame(this._isFirstFrame);
+    }
+    /* this.maskManager.renderFrame(this.finalTransform.mat);
+        this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
+  },
+  sourceRectAtTime: function () {
+    return {
+      top: 0,
+      left: 0,
+      width: 100,
+      height: 100,
+    };
+  },
+  getLayerSize: function () {
+    if (this.data.ty === 5) {
+      return { w: this.data.textData.width, h: this.data.textData.height };
+    }
+    return { w: this.data.width, h: this.data.height };
+  },
+};
+
+const getBlendMode = (function () {
+  var blendModeEnums = {
+    0: 'source-over',
+    1: 'multiply',
+    2: 'screen',
+    3: 'overlay',
+    4: 'darken',
+    5: 'lighten',
+    6: 'color-dodge',
+    7: 'color-burn',
+    8: 'hard-light',
+    9: 'soft-light',
+    10: 'difference',
+    11: 'exclusion',
+    12: 'hue',
+    13: 'saturation',
+    14: 'color',
+    15: 'luminosity',
+  };
+
+  return function (mode) {
+    return blendModeEnums[mode] || '';
+  };
+}());
+
+function SliderEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function AngleEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function ColorEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function PointEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function LayerIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function MaskIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function CheckboxEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function NoValueEffect() {
+  this.p = {};
+}
+
+function EffectsManager(data, element) {
+  var effects = data.ef || [];
+  this.effectElements = [];
+  var i;
+  var len = effects.length;
+  var effectItem;
+  for (i = 0; i < len; i += 1) {
+    effectItem = new GroupEffect(effects[i], element);
+    this.effectElements.push(effectItem);
+  }
+}
+
+function GroupEffect(data, element) {
+  this.init(data, element);
+}
+
+extendPrototype([DynamicPropertyContainer], GroupEffect);
+
+GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
+
+GroupEffect.prototype.init = function (data, element) {
+  this.data = data;
+  this.effectElements = [];
+  this.initDynamicPropertyContainer(element);
+  var i;
+  var len = this.data.ef.length;
+  var eff;
+  var effects = this.data.ef;
+  for (i = 0; i < len; i += 1) {
+    eff = null;
+    switch (effects[i].ty) {
+      case 0:
+        eff = new SliderEffect(effects[i], element, this);
+        break;
+      case 1:
+        eff = new AngleEffect(effects[i], element, this);
+        break;
+      case 2:
+        eff = new ColorEffect(effects[i], element, this);
+        break;
+      case 3:
+        eff = new PointEffect(effects[i], element, this);
+        break;
+      case 4:
+      case 7:
+        eff = new CheckboxEffect(effects[i], element, this);
+        break;
+      case 10:
+        eff = new LayerIndexEffect(effects[i], element, this);
+        break;
+      case 11:
+        eff = new MaskIndexEffect(effects[i], element, this);
+        break;
+      case 5:
+        eff = new EffectsManager(effects[i], element, this);
+        break;
+        // case 6:
+      default:
+        eff = new NoValueEffect(effects[i], element, this);
+        break;
+    }
+    if (eff) {
+      this.effectElements.push(eff);
+    }
+  }
+};
+
+function BaseElement() {
+}
+
+BaseElement.prototype = {
+  checkMasks: function () {
+    if (!this.data.hasMask) {
+      return false;
+    }
+    var i = 0;
+    var len = this.data.masksProperties.length;
+    while (i < len) {
+      if ((this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false)) {
+        return true;
+      }
+      i += 1;
+    }
+    return false;
+  },
+  initExpressions: function () {
+    const expressionsInterfaces = getExpressionInterfaces();
+    if (!expressionsInterfaces) {
+      return;
+    }
+    const LayerExpressionInterface = expressionsInterfaces('layer');
+    const EffectsExpressionInterface = expressionsInterfaces('effects');
+    const ShapeExpressionInterface = expressionsInterfaces('shape');
+    const TextExpressionInterface = expressionsInterfaces('text');
+    const CompExpressionInterface = expressionsInterfaces('comp');
+    this.layerInterface = LayerExpressionInterface(this);
+    if (this.data.hasMask && this.maskManager) {
+      this.layerInterface.registerMaskInterface(this.maskManager);
+    }
+    var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
+    this.layerInterface.registerEffectsInterface(effectsInterface);
+
+    if (this.data.ty === 0 || this.data.xt) {
+      this.compInterface = CompExpressionInterface(this);
+    } else if (this.data.ty === 4) {
+      this.layerInterface.shapeInterface = ShapeExpressionInterface(this.shapesData, this.itemsData, this.layerInterface);
+      this.layerInterface.content = this.layerInterface.shapeInterface;
+    } else if (this.data.ty === 5) {
+      this.layerInterface.textInterface = TextExpressionInterface(this);
+      this.layerInterface.text = this.layerInterface.textInterface;
+    }
+  },
+  setBlendMode: function () {
+    var blendModeValue = getBlendMode(this.data.bm);
+    var elem = this.baseElement || this.layerElement;
+
+    elem.style['mix-blend-mode'] = blendModeValue;
+  },
+  initBaseData: function (data, globalData, comp) {
+    this.globalData = globalData;
+    this.comp = comp;
+    this.data = data;
+    this.layerId = createElementID();
+
+    // Stretch factor for old animations missing this property.
+    if (!this.data.sr) {
+      this.data.sr = 1;
+    }
+    // effects manager
+    this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
+  },
+  getType: function () {
+    return this.type;
+  },
+  sourceRectAtTime: function () {},
+};
+
+/**
+ * @file
+ * Handles element's layer frame update.
+ * Checks layer in point and out point
+ *
+ */
+
+function FrameElement() {}
+
+FrameElement.prototype = {
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     */
+  initFrame: function () {
+    // set to true when inpoint is rendered
+    this._isFirstFrame = false;
+    // list of animated properties
+    this.dynamicProperties = [];
+    // If layer has been modified in current tick this will be true
+    this._mdf = false;
+  },
+  /**
+     * @function
+     * Calculates all dynamic values
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     * @param {boolean} isVisible
+     * if layers is currently in range
+     *
+     */
+  prepareProperties: function (num, isVisible) {
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      if (isVisible || (this._isParent && this.dynamicProperties[i].propType === 'transform')) {
+        this.dynamicProperties[i].getValue();
+        if (this.dynamicProperties[i]._mdf) {
+          this.globalData._mdf = true;
+          this._mdf = true;
+        }
+      }
+    }
+  },
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+    }
+  },
+};
+
+function FootageElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.footageData = globalData.imageLoader.getAsset(this.assetData);
+  this.initBaseData(data, globalData, comp);
+}
+
+FootageElement.prototype.prepareFrame = function () {
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
+
+FootageElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+FootageElement.prototype.renderFrame = function () {
+};
+
+FootageElement.prototype.destroy = function () {
+};
+
+FootageElement.prototype.initExpressions = function () {
+  const expressionsInterfaces = getExpressionInterfaces();
+  if (!expressionsInterfaces) {
+    return;
+  }
+  const FootageInterface = expressionsInterfaces('footage');
+  this.layerInterface = FootageInterface(this);
+};
+
+FootageElement.prototype.getFootageData = function () {
+  return this.footageData;
+};
+
+function AudioElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initBaseData(data, globalData, comp);
+  this._isPlaying = false;
+  this._canPlay = false;
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  this.audio = this.globalData.audioController.createAudio(assetPath);
+  this._currentTime = 0;
+  this.globalData.audioController.addAudio(this);
+  this._volumeMultiplier = 1;
+  this._volume = 1;
+  this._previousVolume = null;
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+  this.lv = PropertyFactory.getProp(this, data.au && data.au.lv ? data.au.lv : { k: [100] }, 1, 0.01, this);
+}
+
+AudioElement.prototype.prepareFrame = function (num) {
+  this.prepareRenderableFrame(num, true);
+  this.prepareProperties(num, true);
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    this._currentTime = timeRemapped;
+  } else {
+    this._currentTime = num / this.data.sr;
+  }
+  this._volume = this.lv.v[0];
+  var totalVolume = this._volume * this._volumeMultiplier;
+  if (this._previousVolume !== totalVolume) {
+    this._previousVolume = totalVolume;
+    this.audio.volume(totalVolume);
+  }
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
+
+AudioElement.prototype.renderFrame = function () {
+  if (this.isInRange && this._canPlay) {
+    if (!this._isPlaying) {
+      this.audio.play();
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+      this._isPlaying = true;
+    } else if (!this.audio.playing()
+      || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1
+    ) {
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+    }
+  }
+};
+
+AudioElement.prototype.show = function () {
+  // this.audio.play()
+};
+
+AudioElement.prototype.hide = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+};
+
+AudioElement.prototype.pause = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+  this._canPlay = false;
+};
+
+AudioElement.prototype.resume = function () {
+  this._canPlay = true;
+};
+
+AudioElement.prototype.setRate = function (rateValue) {
+  this.audio.rate(rateValue);
+};
+
+AudioElement.prototype.volume = function (volumeValue) {
+  this._volumeMultiplier = volumeValue;
+  this._previousVolume = volumeValue * this._volume;
+  this.audio.volume(this._previousVolume);
+};
+
+AudioElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+AudioElement.prototype.destroy = function () {
+};
+
+AudioElement.prototype.sourceRectAtTime = function () {
+};
+
+AudioElement.prototype.initExpressions = function () {
+};
+
+function BaseRenderer() {}
+BaseRenderer.prototype.checkLayers = function (num) {
+  var i;
+  var len = this.layers.length;
+  var data;
+  this.completeLayers = true;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (!this.elements[i]) {
+      data = this.layers[i];
+      if (data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) {
+        this.buildItem(i);
+      }
+    }
+    this.completeLayers = this.elements[i] ? this.completeLayers : false;
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.createItem = function (layer) {
+  switch (layer.ty) {
+    case 2:
+      return this.createImage(layer);
+    case 0:
+      return this.createComp(layer);
+    case 1:
+      return this.createSolid(layer);
+    case 3:
+      return this.createNull(layer);
+    case 4:
+      return this.createShape(layer);
+    case 5:
+      return this.createText(layer);
+    case 6:
+      return this.createAudio(layer);
+    case 13:
+      return this.createCamera(layer);
+    case 15:
+      return this.createFootage(layer);
+    default:
+      return this.createNull(layer);
+  }
+};
+
+BaseRenderer.prototype.createCamera = function () {
+  throw new Error('You\'re using a 3d camera. Try the html renderer.');
+};
+
+BaseRenderer.prototype.createAudio = function (data) {
+  return new AudioElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.createFootage = function (data) {
+  return new FootageElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.buildAllItems = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    this.buildItem(i);
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.includeLayers = function (newLayers) {
+  this.completeLayers = false;
+  var i;
+  var len = newLayers.length;
+  var j;
+  var jLen = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    j = 0;
+    while (j < jLen) {
+      if (this.layers[j].id === newLayers[i].id) {
+        this.layers[j] = newLayers[i];
+        break;
+      }
+      j += 1;
+    }
+  }
+};
+
+BaseRenderer.prototype.setProjectInterface = function (pInterface) {
+  this.globalData.projectInterface = pInterface;
+};
+
+BaseRenderer.prototype.initItems = function () {
+  if (!this.globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+};
+BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
+  var elements = this.elements;
+  var layers = this.layers;
+  var i = 0;
+  var len = layers.length;
+  while (i < len) {
+    if (layers[i].ind == parentName) { // eslint-disable-line eqeqeq
+      if (!elements[i] || elements[i] === true) {
+        this.buildItem(i);
+        this.addPendingElement(element);
+      } else {
+        hierarchy.push(elements[i]);
+        elements[i].setAsParent();
+        if (layers[i].parent !== undefined) {
+          this.buildElementParenting(element, layers[i].parent, hierarchy);
+        } else {
+          element.setHierarchy(hierarchy);
+        }
+      }
+    }
+    i += 1;
+  }
+};
+
+BaseRenderer.prototype.addPendingElement = function (element) {
+  this.pendingElements.push(element);
+};
+
+BaseRenderer.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var len = assets.length;
+  for (i = 0; i < len; i += 1) {
+    if (assets[i].xt) {
+      var comp = this.createComp(assets[i]);
+      comp.initExpressions();
+      this.globalData.projectInterface.registerComposition(comp);
+    }
+  }
+};
+
+BaseRenderer.prototype.getElementById = function (ind) {
+  var i;
+  var len = this.elements.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i].data.ind === ind) {
+      return this.elements[i];
+    }
+  }
+  return null;
+};
+
+BaseRenderer.prototype.getElementByPath = function (path) {
+  var pathValue = path.shift();
+  var element;
+  if (typeof pathValue === 'number') {
+    element = this.elements[pathValue];
+  } else {
+    var i;
+    var len = this.elements.length;
+    for (i = 0; i < len; i += 1) {
+      if (this.elements[i].data.nm === pathValue) {
+        element = this.elements[i];
+        break;
+      }
+    }
+  }
+  if (path.length === 0) {
+    return element;
+  }
+  return element.getElementByPath(path);
+};
+
+BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
+  this.globalData.fontManager = new FontManager();
+  this.globalData.slotManager = slotFactory(animData);
+  this.globalData.fontManager.addChars(animData.chars);
+  this.globalData.fontManager.addFonts(animData.fonts, fontsContainer);
+  this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+  this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+  this.globalData.imageLoader = this.animationItem.imagePreloader;
+  this.globalData.audioController = this.animationItem.audioController;
+  this.globalData.frameId = 0;
+  this.globalData.frameRate = animData.fr;
+  this.globalData.nm = animData.nm;
+  this.globalData.compSize = {
+    w: animData.w,
+    h: animData.h,
+  };
+};
+
+var effectTypes = {
+  TRANSFORM_EFFECT: 'transformEFfect',
+};
+
+function TransformElement() {}
+
+TransformElement.prototype = {
+  initTransform: function () {
+    var mat = new Matrix();
+    this.finalTransform = {
+      mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : { o: 0 },
+      _matMdf: false,
+      _localMatMdf: false,
+      _opMdf: false,
+      mat: mat,
+      localMat: mat,
+      localOpacity: 1,
+    };
+    if (this.data.ao) {
+      this.finalTransform.mProp.autoOriented = true;
+    }
+
+    // TODO: check TYPE 11: Guided elements
+    if (this.data.ty !== 11) {
+      // this.createElements();
+    }
+  },
+  renderTransform: function () {
+    this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
+    this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
+
+    if (this.hierarchy) {
+      var mat;
+      var finalMat = this.finalTransform.mat;
+      var i = 0;
+      var len = this.hierarchy.length;
+      // Checking if any of the transformation matrices in the hierarchy chain has changed.
+      if (!this.finalTransform._matMdf) {
+        while (i < len) {
+          if (this.hierarchy[i].finalTransform.mProp._mdf) {
+            this.finalTransform._matMdf = true;
+            break;
+          }
+          i += 1;
+        }
+      }
+
+      if (this.finalTransform._matMdf) {
+        mat = this.finalTransform.mProp.v.props;
+        finalMat.cloneFromProps(mat);
+        for (i = 0; i < len; i += 1) {
+          finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
+        }
+      }
+    }
+    if (!this.localTransforms || this.finalTransform._matMdf) {
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+    }
+    if (this.finalTransform._opMdf) {
+      this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderLocalTransform: function () {
+    if (this.localTransforms) {
+      var i = 0;
+      var len = this.localTransforms.length;
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+      if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
+        while (i < len) {
+          if (this.localTransforms[i]._mdf) {
+            this.finalTransform._localMatMdf = true;
+          }
+          if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
+            this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+            this.finalTransform._opMdf = true;
+          }
+          i += 1;
+        }
+      }
+      if (this.finalTransform._localMatMdf) {
+        var localMat = this.finalTransform.localMat;
+        this.localTransforms[0].matrix.clone(localMat);
+        for (i = 1; i < len; i += 1) {
+          var lmat = this.localTransforms[i].matrix;
+          localMat.multiply(lmat);
+        }
+        localMat.multiply(this.finalTransform.mat);
+      }
+      if (this.finalTransform._opMdf) {
+        var localOp = this.finalTransform.localOpacity;
+        for (i = 0; i < len; i += 1) {
+          localOp *= this.localTransforms[i].opacity * 0.01;
+        }
+        this.finalTransform.localOpacity = localOp;
+      }
+    }
+  },
+  searchEffectTransforms: function () {
+    if (this.renderableEffectsManager) {
+      var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+      if (transformEffects.length) {
+        this.localTransforms = [];
+        this.finalTransform.localMat = new Matrix();
+        var i = 0;
+        var len = transformEffects.length;
+        for (i = 0; i < len; i += 1) {
+          this.localTransforms.push(transformEffects[i]);
+        }
+      }
+    }
+  },
+  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;
+    var len = transforms.length;
+    var 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;
+  },
+  mHelper: new Matrix(),
+};
+
+function MaskElement(data, element, globalData) {
+  this.data = data;
+  this.element = element;
+  this.globalData = globalData;
+  this.storedData = [];
+  this.masksProperties = this.data.masksProperties || [];
+  this.maskElement = null;
+  var defs = this.globalData.defs;
+  var i;
+  var len = this.masksProperties ? this.masksProperties.length : 0;
+  this.viewData = createSizedArray(len);
+  this.solidPath = '';
+
+  var path;
+  var properties = this.masksProperties;
+  var count = 0;
+  var currentMasks = [];
+  var j;
+  var jLen;
+  var layerId = createElementID();
+  var rect;
+  var expansor;
+  var feMorph;
+  var x;
+  var maskType = 'clipPath';
+  var maskRef = 'clip-path';
+  for (i = 0; i < len; i += 1) {
+    if ((properties[i].mode !== 'a' && properties[i].mode !== 'n') || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
+      maskType = 'mask';
+      maskRef = 'mask';
+    }
+
+    if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
+      rect = createNS('rect');
+      rect.setAttribute('fill', '#ffffff');
+      rect.setAttribute('width', this.element.comp.data.w || 0);
+      rect.setAttribute('height', this.element.comp.data.h || 0);
+      currentMasks.push(rect);
+    } else {
+      rect = null;
+    }
+
+    path = createNS('path');
+    if (properties[i].mode === 'n') {
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        elem: path,
+        lastPath: '',
+      };
+      defs.appendChild(path);
+    } else {
+      count += 1;
+
+      path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      path.setAttribute('clip-rule', 'nonzero');
+      var filterID;
+
+      if (properties[i].x.k !== 0) {
+        maskType = 'mask';
+        maskRef = 'mask';
+        x = PropertyFactory.getProp(this.element, properties[i].x, 0, null, this.element);
+        filterID = createElementID();
+        expansor = createNS('filter');
+        expansor.setAttribute('id', filterID);
+        feMorph = createNS('feMorphology');
+        feMorph.setAttribute('operator', 'erode');
+        feMorph.setAttribute('in', 'SourceGraphic');
+        feMorph.setAttribute('radius', '0');
+        expansor.appendChild(feMorph);
+        defs.appendChild(expansor);
+        path.setAttribute('stroke', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      } else {
+        feMorph = null;
+        x = null;
+      }
+
+      // TODO move this to a factory or to a constructor
+      this.storedData[i] = {
+        elem: path,
+        x: x,
+        expan: feMorph,
+        lastPath: '',
+        lastOperator: '',
+        filterId: filterID,
+        lastRadius: 0,
+      };
+      if (properties[i].mode === 'i') {
+        jLen = currentMasks.length;
+        var g = createNS('g');
+        for (j = 0; j < jLen; j += 1) {
+          g.appendChild(currentMasks[j]);
+        }
+        var mask = createNS('mask');
+        mask.setAttribute('mask-type', 'alpha');
+        mask.setAttribute('id', layerId + '_' + count);
+        mask.appendChild(path);
+        defs.appendChild(mask);
+        g.setAttribute('mask', 'url(' + getLocationHref() + '#' + layerId + '_' + count + ')');
+
+        currentMasks.length = 0;
+        currentMasks.push(g);
+      } else {
+        currentMasks.push(path);
+      }
+      if (properties[i].inv && !this.solidPath) {
+        this.solidPath = this.createLayerSolidPath();
+      }
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        elem: path,
+        lastPath: '',
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        invRect: rect,
+      };
+      if (!this.viewData[i].prop.k) {
+        this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
+      }
+    }
+  }
+
+  this.maskElement = createNS(maskType);
+
+  len = currentMasks.length;
+  for (i = 0; i < len; i += 1) {
+    this.maskElement.appendChild(currentMasks[i]);
+  }
+
+  if (count > 0) {
+    this.maskElement.setAttribute('id', layerId);
+    this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
+    defs.appendChild(this.maskElement);
+  }
+  if (this.viewData.length) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+MaskElement.prototype.getMaskProperty = function (pos) {
+  return this.viewData[pos].prop;
+};
+
+MaskElement.prototype.renderFrame = function (isFirstFrame) {
+  var finalMat = this.element.finalTransform.mat;
+  var i;
+  var len = this.masksProperties.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.viewData[i].prop._mdf || isFirstFrame) {
+      this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
+    }
+    if (this.viewData[i].op._mdf || isFirstFrame) {
+      this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
+    }
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
+        this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
+      }
+      if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
+        var feMorph = this.storedData[i].expan;
+        if (this.storedData[i].x.v < 0) {
+          if (this.storedData[i].lastOperator !== 'erode') {
+            this.storedData[i].lastOperator = 'erode';
+            this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
+          }
+          feMorph.setAttribute('radius', -this.storedData[i].x.v);
+        } else {
+          if (this.storedData[i].lastOperator !== 'dilate') {
+            this.storedData[i].lastOperator = 'dilate';
+            this.storedData[i].elem.setAttribute('filter', null);
+          }
+          this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
+        }
+      }
+    }
+  }
+};
+
+MaskElement.prototype.getMaskelement = function () {
+  return this.maskElement;
+};
+
+MaskElement.prototype.createLayerSolidPath = function () {
+  var path = 'M0,0 ';
+  path += ' h' + this.globalData.compSize.w;
+  path += ' v' + this.globalData.compSize.h;
+  path += ' h-' + this.globalData.compSize.w;
+  path += ' v-' + this.globalData.compSize.h + ' ';
+  return path;
+};
+
+MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
+  var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  var i;
+  var len;
+  len = pathNodes._length;
+  for (i = 1; i < len; i += 1) {
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
+  }
+  // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+  if (pathNodes.c && len > 1) {
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  }
+  // pathNodes.__renderedString = pathString;
+
+  if (viewData.lastPath !== pathString) {
+    var pathShapeValue = '';
+    if (viewData.elem) {
+      if (pathNodes.c) {
+        pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
+      }
+      viewData.elem.setAttribute('d', pathShapeValue);
+    }
+    viewData.lastPath = pathString;
+  }
+};
+
+MaskElement.prototype.destroy = function () {
+  this.element = null;
+  this.globalData = null;
+  this.maskElement = null;
+  this.data = null;
+  this.masksProperties = null;
+};
+
+const filtersFactory = (function () {
+  var ob = {};
+  ob.createFilter = createFilter;
+  ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
+
+  function createFilter(filId, skipCoordinates) {
+    var fil = createNS('filter');
+    fil.setAttribute('id', filId);
+    if (skipCoordinates !== true) {
+      fil.setAttribute('filterUnits', 'objectBoundingBox');
+      fil.setAttribute('x', '0%');
+      fil.setAttribute('y', '0%');
+      fil.setAttribute('width', '100%');
+      fil.setAttribute('height', '100%');
+    }
+    return fil;
+  }
+
+  function createAlphaToLuminanceFilter() {
+    var feColorMatrix = createNS('feColorMatrix');
+    feColorMatrix.setAttribute('type', 'matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+    feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
+    return feColorMatrix;
+  }
+
+  return ob;
+}());
+
+const featureSupport = (function () {
+  var ob = {
+    maskType: true,
+    svgLumaHidden: true,
+    offscreenCanvas: typeof OffscreenCanvas !== 'undefined',
+  };
+  if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
+    ob.maskType = false;
+  }
+  if (/firefox/i.test(navigator.userAgent)) {
+    ob.svgLumaHidden = false;
+  }
+  return ob;
+}());
+
+var registeredEffects$1 = {};
+var idPrefix = 'filter_result_';
+
+function SVGEffects(elem) {
+  var i;
+  var source = 'SourceGraphic';
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  var filId = createElementID();
+  var fil = filtersFactory.createFilter(filId, true);
+  var count = 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects$1[type]) {
+      var Effect = registeredEffects$1[type].effect;
+      filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
+      source = idPrefix + count;
+      if (registeredEffects$1[type].countsAsEffect) {
+        count += 1;
+      }
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (count) {
+    elem.globalData.defs.appendChild(fil);
+    elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+SVGEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect$1(id, effect, countsAsEffect) {
+  registeredEffects$1[id] = {
+    effect,
+    countsAsEffect,
+  };
+}
+
+function SVGBaseElement() {
+}
+
+SVGBaseElement.prototype = {
+  initRendererElement: function () {
+    this.layerElement = createNS('g');
+  },
+  createContainerElements: function () {
+    this.matteElement = createNS('g');
+    this.transformedElement = this.layerElement;
+    this.maskedElement = this.layerElement;
+    this._sizeChanged = false;
+    var layerElementParent = null;
+    // If this layer acts as a mask for the following layer
+    if (this.data.td) {
+      this.matteMasks = {};
+      var gg = createNS('g');
+      gg.setAttribute('id', this.layerId);
+      gg.appendChild(this.layerElement);
+      layerElementParent = gg;
+      this.globalData.defs.appendChild(gg);
+    } else if (this.data.tt) {
+      this.matteElement.appendChild(this.layerElement);
+      layerElementParent = this.matteElement;
+      this.baseElement = this.matteElement;
+    } else {
+      this.baseElement = this.layerElement;
+    }
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
+    if (this.data.ty === 0 && !this.data.hd) {
+      var cp = createNS('clipPath');
+      var pt = createNS('path');
+      pt.setAttribute('d', 'M0,0 L' + this.data.w + ',0 L' + this.data.w + ',' + this.data.h + ' L0,' + this.data.h + 'z');
+      var clipId = createElementID();
+      cp.setAttribute('id', clipId);
+      cp.appendChild(pt);
+      this.globalData.defs.appendChild(cp);
+
+      if (this.checkMasks()) {
+        var cpGroup = createNS('g');
+        cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+        cpGroup.appendChild(this.layerElement);
+        this.transformedElement = cpGroup;
+        if (layerElementParent) {
+          layerElementParent.appendChild(this.transformedElement);
+        } else {
+          this.baseElement = this.transformedElement;
+        }
+      } else {
+        this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+      }
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    if (this.finalTransform._localMatMdf) {
+      this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
+    }
+    if (this.finalTransform._opMdf) {
+      this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
+    }
+  },
+  destroyBaseElement: function () {
+    this.layerElement = null;
+    this.matteElement = null;
+    this.maskManager.destroy();
+  },
+  getBaseElement: function () {
+    if (this.data.hd) {
+      return null;
+    }
+    return this.baseElement;
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+    this.renderableEffectsManager = new SVGEffects(this);
+    this.searchEffectTransforms();
+  },
+  getMatte: function (matteType) {
+    // This should not be a common case. But for backward compatibility, we'll create the matte object.
+    // It solves animations that have two consecutive layers marked as matte masks.
+    // Which is an undefined behavior in AE.
+    if (!this.matteMasks) {
+      this.matteMasks = {};
+    }
+    if (!this.matteMasks[matteType]) {
+      var id = this.layerId + '_' + matteType;
+      var filId;
+      var fil;
+      var useElement;
+      var gg;
+      if (matteType === 1 || matteType === 3) {
+        var masker = createNS('mask');
+        masker.setAttribute('id', id);
+        masker.setAttribute('mask-type', matteType === 3 ? 'luminance' : 'alpha');
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        masker.appendChild(useElement);
+        this.globalData.defs.appendChild(masker);
+        if (!featureSupport.maskType && matteType === 1) {
+          masker.setAttribute('mask-type', 'luminance');
+          filId = createElementID();
+          fil = filtersFactory.createFilter(filId);
+          this.globalData.defs.appendChild(fil);
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          gg.appendChild(useElement);
+          masker.appendChild(gg);
+          gg.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        }
+      } else if (matteType === 2) {
+        var maskGroup = createNS('mask');
+        maskGroup.setAttribute('id', id);
+        maskGroup.setAttribute('mask-type', 'alpha');
+        var maskGrouper = createNS('g');
+        maskGroup.appendChild(maskGrouper);
+        filId = createElementID();
+        fil = filtersFactory.createFilter(filId);
+        /// /
+        var feCTr = createNS('feComponentTransfer');
+        feCTr.setAttribute('in', 'SourceGraphic');
+        fil.appendChild(feCTr);
+        var feFunc = createNS('feFuncA');
+        feFunc.setAttribute('type', 'table');
+        feFunc.setAttribute('tableValues', '1.0 0.0');
+        feCTr.appendChild(feFunc);
+        /// /
+        this.globalData.defs.appendChild(fil);
+        var alphaRect = createNS('rect');
+        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');
+        alphaRect.setAttribute('opacity', '0');
+        maskGrouper.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        maskGrouper.appendChild(alphaRect);
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        maskGrouper.appendChild(useElement);
+        if (!featureSupport.maskType) {
+          maskGroup.setAttribute('mask-type', 'luminance');
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          maskGrouper.appendChild(alphaRect);
+          gg.appendChild(this.layerElement);
+          maskGrouper.appendChild(gg);
+        }
+        this.globalData.defs.appendChild(maskGroup);
+      }
+      this.matteMasks[matteType] = id;
+    }
+    return this.matteMasks[matteType];
+  },
+  setMatte: function (id) {
+    if (!this.matteElement) {
+      return;
+    }
+    this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+  },
+};
+
+/**
+ * @file
+ * Handles AE's layer parenting property.
+ *
+ */
+
+function HierarchyElement() {}
+
+HierarchyElement.prototype = {
+  /**
+     * @function
+     * Initializes hierarchy properties
+     *
+     */
+  initHierarchy: function () {
+    // element's parent list
+    this.hierarchy = [];
+    // if element is parent of another layer _isParent will be true
+    this._isParent = false;
+    this.checkParenting();
+  },
+  /**
+     * @function
+     * Sets layer's hierarchy.
+     * @param {array} hierarch
+     * layer's parent list
+     *
+     */
+  setHierarchy: function (hierarchy) {
+    this.hierarchy = hierarchy;
+  },
+  /**
+     * @function
+     * Sets layer as parent.
+     *
+     */
+  setAsParent: function () {
+    this._isParent = true;
+  },
+  /**
+     * @function
+     * Searches layer's parenting chain
+     *
+     */
+  checkParenting: function () {
+    if (this.data.parent !== undefined) {
+      this.comp.buildElementParenting(this, this.data.parent, []);
+    }
+  },
+};
+
+function RenderableDOMElement() {}
+
+(function () {
+  var _prototype = {
+    initElement: function (data, globalData, comp) {
+      this.initFrame();
+      this.initBaseData(data, globalData, comp);
+      this.initTransform(data, globalData, comp);
+      this.initHierarchy();
+      this.initRenderable();
+      this.initRendererElement();
+      this.createContainerElements();
+      this.createRenderableComponents();
+      this.createContent();
+      this.hide();
+    },
+    hide: function () {
+      // console.log('HIDE', this);
+      if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+        var elem = this.baseElement || this.layerElement;
+        elem.style.display = 'none';
+        this.hidden = true;
+      }
+    },
+    show: function () {
+      // console.log('SHOW', this);
+      if (this.isInRange && !this.isTransparent) {
+        if (!this.data.hd) {
+          var elem = this.baseElement || this.layerElement;
+          elem.style.display = 'block';
+        }
+        this.hidden = false;
+        this._isFirstFrame = true;
+      }
+    },
+    renderFrame: function () {
+      // If it is exported as hidden (data.hd === true) no need to render
+      // If it is not visible no need to render
+      if (this.data.hd || this.hidden) {
+        return;
+      }
+      this.renderTransform();
+      this.renderRenderable();
+      this.renderLocalTransform();
+      this.renderElement();
+      this.renderInnerContent();
+      if (this._isFirstFrame) {
+        this._isFirstFrame = false;
+      }
+    },
+    renderInnerContent: function () {},
+    prepareFrame: function (num) {
+      this._mdf = false;
+      this.prepareRenderableFrame(num);
+      this.prepareProperties(num, this.isInRange);
+      this.checkTransparency();
+    },
+    destroy: function () {
+      this.innerElem = null;
+      this.destroyBaseElement();
+    },
+  };
+  extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement);
+}());
+
+function IImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  if (this.assetData && this.assetData.sid) {
+    this.assetData = globalData.slotManager.getProp(this.assetData);
+  }
+  this.initElement(data, globalData, comp);
+  this.sourceRect = {
+    top: 0, left: 0, width: this.assetData.w, height: this.assetData.h,
+  };
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
+
+IImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+
+  this.innerElem = createNS('image');
+  this.innerElem.setAttribute('width', this.assetData.w + 'px');
+  this.innerElem.setAttribute('height', this.assetData.h + 'px');
+  this.innerElem.setAttribute('preserveAspectRatio', this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio);
+  this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+
+  this.layerElement.appendChild(this.innerElem);
+};
+
+IImageElement.prototype.sourceRectAtTime = function () {
+  return this.sourceRect;
+};
+
+function ProcessedElement(element, position) {
+  this.elem = element;
+  this.pos = position;
+}
+
+function IShapeElement() {
+}
+
+IShapeElement.prototype = {
+  addShapeToModifiers: function (data) {
+    var i;
+    var len = this.shapeModifiers.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapeModifiers[i].addShape(data);
+    }
+  },
+  isShapeInAnimatedModifiers: function (data) {
+    var i = 0;
+    var len = this.shapeModifiers.length;
+    while (i < len) {
+      if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
+        return true;
+      }
+    }
+    return false;
+  },
+  renderModifiers: function () {
+    if (!this.shapeModifiers.length) {
+      return;
+    }
+    var i;
+    var len = this.shapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].sh.reset();
+    }
+
+    len = this.shapeModifiers.length;
+    var shouldBreakProcess;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+      // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+      // TODO: find a better solution for this
+      if (shouldBreakProcess) {
+        break;
+      }
+    }
+  },
+
+  searchProcessedElement: function (elem) {
+    var elements = this.processedElements;
+    var i = 0;
+    var len = elements.length;
+    while (i < len) {
+      if (elements[i].elem === elem) {
+        return elements[i].pos;
+      }
+      i += 1;
+    }
+    return 0;
+  },
+  addProcessedElement: function (elem, pos) {
+    var elements = this.processedElements;
+    var i = elements.length;
+    while (i) {
+      i -= 1;
+      if (elements[i].elem === elem) {
+        elements[i].pos = pos;
+        return;
+      }
+    }
+    elements.push(new ProcessedElement(elem, pos));
+  },
+  prepareFrame: function (num) {
+    this.prepareRenderableFrame(num);
+    this.prepareProperties(num, this.isInRange);
+  },
+};
+
+const lineCapEnum = {
+  1: 'butt',
+  2: 'round',
+  3: 'square',
+};
+
+const lineJoinEnum = {
+  1: 'miter',
+  2: 'round',
+  3: 'bevel',
+};
+
+function SVGShapeData(transformers, level, shape) {
+  this.caches = [];
+  this.styles = [];
+  this.transformers = transformers;
+  this.lStr = '';
+  this.sh = shape;
+  this.lvl = level;
+  // TODO find if there are some cases where _isAnimated can be false.
+  // For now, since shapes add up with other shapes. They have to be calculated every time.
+  // One way of finding out is checking if all styles associated to this shape depend only of this shape
+  this._isAnimated = !!shape.k;
+  // TODO: commenting this for now since all shapes are animated
+  var i = 0;
+  var len = transformers.length;
+  while (i < len) {
+    if (transformers[i].mProps.dynamicProperties.length) {
+      this._isAnimated = true;
+      break;
+    }
+    i += 1;
+  }
+}
+
+SVGShapeData.prototype.setAsAnimated = function () {
+  this._isAnimated = true;
+};
+
+function SVGStyleData(data, level) {
+  this.data = data;
+  this.type = data.ty;
+  this.d = '';
+  this.lvl = level;
+  this._mdf = false;
+  this.closed = data.hd === true;
+  this.pElem = createNS('path');
+  this.msElem = null;
+}
+
+SVGStyleData.prototype.reset = function () {
+  this.d = '';
+  this._mdf = false;
+};
+
+function DashProperty(elem, data, renderer, container) {
+  this.elem = elem;
+  this.frameId = -1;
+  this.dataProps = createSizedArray(data.length);
+  this.renderer = renderer;
+  this.k = false;
+  this.dashStr = '';
+  this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0);
+  this.dashoffset = createTypedArray('float32', 1);
+  this.initDynamicPropertyContainer(container);
+  var i;
+  var len = data.length || 0;
+  var prop;
+  for (i = 0; i < len; i += 1) {
+    prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
+    this.k = prop.k || this.k;
+    this.dataProps[i] = { n: data[i].n, p: prop };
+  }
+  if (!this.k) {
+    this.getValue(true);
+  }
+  this._isAnimated = this.k;
+}
+
+DashProperty.prototype.getValue = function (forceRender) {
+  if (this.elem.globalData.frameId === this.frameId && !forceRender) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+  this._mdf = this._mdf || forceRender;
+  if (this._mdf) {
+    var i = 0;
+    var len = this.dataProps.length;
+    if (this.renderer === 'svg') {
+      this.dashStr = '';
+    }
+    for (i = 0; i < len; i += 1) {
+      if (this.dataProps[i].n !== 'o') {
+        if (this.renderer === 'svg') {
+          this.dashStr += ' ' + this.dataProps[i].p.v;
+        } else {
+          this.dashArray[i] = this.dataProps[i].p.v;
+        }
+      } else {
+        this.dashoffset[0] = this.dataProps[i].p.v;
+      }
+    }
+  }
+};
+extendPrototype([DynamicPropertyContainer], DashProperty);
+
+function SVGStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
+
+function SVGFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
+
+function SVGNoStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
+
+function GradientProperty(elem, data, container) {
+  this.data = data;
+  this.c = createTypedArray('uint8c', data.p * 4);
+  var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p * 4) : data.k.k.length - data.p * 4;
+  this.o = createTypedArray('float32', cLength);
+  this._cmdf = false;
+  this._omdf = false;
+  this._collapsable = this.checkCollapsable();
+  this._hasOpacity = cLength;
+  this.initDynamicPropertyContainer(container);
+  this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this);
+  this.k = this.prop.k;
+  this.getValue(true);
+}
+
+GradientProperty.prototype.comparePoints = function (values, points) {
+  var i = 0;
+  var len = this.o.length / 2;
+  var diff;
+  while (i < len) {
+    diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
+    if (diff > 0.01) {
+      return false;
+    }
+    i += 1;
+  }
+  return true;
+};
+
+GradientProperty.prototype.checkCollapsable = function () {
+  if (this.o.length / 2 !== this.c.length / 4) {
+    return false;
+  }
+  if (this.data.k.k[0].s) {
+    var i = 0;
+    var len = this.data.k.k.length;
+    while (i < len) {
+      if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
+        return false;
+      }
+      i += 1;
+    }
+  } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
+    return false;
+  }
+  return true;
+};
+
+GradientProperty.prototype.getValue = function (forceRender) {
+  this.prop.getValue();
+  this._mdf = false;
+  this._cmdf = false;
+  this._omdf = false;
+  if (this.prop._mdf || forceRender) {
+    var i;
+    var len = this.data.p * 4;
+    var mult;
+    var val;
+    for (i = 0; i < len; i += 1) {
+      mult = i % 4 === 0 ? 100 : 255;
+      val = Math.round(this.prop.v[i] * mult);
+      if (this.c[i] !== val) {
+        this.c[i] = val;
+        this._cmdf = !forceRender;
+      }
+    }
+    if (this.o.length) {
+      len = this.prop.v.length;
+      for (i = this.data.p * 4; i < len; i += 1) {
+        mult = i % 2 === 0 ? 100 : 1;
+        val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
+        if (this.o[i - this.data.p * 4] !== val) {
+          this.o[i - this.data.p * 4] = val;
+          this._omdf = !forceRender;
+        }
+      }
+    }
+    this._mdf = !forceRender;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], GradientProperty);
+
+function SVGGradientFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.initGradientData(elem, data, styleOb);
+}
+
+SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 1, null, this);
+  this.h = PropertyFactory.getProp(elem, data.h || { k: 0 }, 0, 0.01, this);
+  this.a = PropertyFactory.getProp(elem, data.a || { k: 0 }, 0, degToRads, this);
+  this.g = new GradientProperty(elem, data.g, this);
+  this.style = styleOb;
+  this.stops = [];
+  this.setGradientData(styleOb.pElem, data);
+  this.setGradientOpacity(data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+};
+
+SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
+  var gradientId = createElementID();
+  var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+  gfill.setAttribute('id', gradientId);
+  gfill.setAttribute('spreadMethod', 'pad');
+  gfill.setAttribute('gradientUnits', 'userSpaceOnUse');
+  var stops = [];
+  var stop;
+  var j;
+  var jLen;
+  jLen = data.g.p * 4;
+  for (j = 0; j < jLen; j += 4) {
+    stop = createNS('stop');
+    gfill.appendChild(stop);
+    stops.push(stop);
+  }
+  pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
+  this.gf = gfill;
+  this.cst = stops;
+};
+
+SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
+  if (this.g._hasOpacity && !this.g._collapsable) {
+    var stop;
+    var j;
+    var jLen;
+    var mask = createNS('mask');
+    var maskElement = createNS('path');
+    mask.appendChild(maskElement);
+    var opacityId = createElementID();
+    var maskId = createElementID();
+    mask.setAttribute('id', maskId);
+    var opFill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+    opFill.setAttribute('id', opacityId);
+    opFill.setAttribute('spreadMethod', 'pad');
+    opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
+    jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
+    var stops = this.stops;
+    for (j = data.g.p * 4; j < jLen; j += 2) {
+      stop = createNS('stop');
+      stop.setAttribute('stop-color', 'rgb(255,255,255)');
+      opFill.appendChild(stop);
+      stops.push(stop);
+    }
+    maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
+    this.maskId = maskId;
+    styleOb.msElem = maskElement;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
+
+function SVGGradientStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.initGradientData(elem, data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
+
+function ShapeGroupData() {
+  this.it = [];
+  this.prevViewData = [];
+  this.gr = createNS('g');
+}
+
+function SVGTransformData(mProps, op, container) {
+  this.transform = {
+    mProps: mProps,
+    op: op,
+    container: container,
+  };
+  this.elements = [];
+  this._isAnimated = this.transform.mProps.dynamicProperties.length || this.transform.op.effectsSequence.length;
+}
+
+const buildShapeString = function (pathNodes, length, closed, mat) {
+  if (length === 0) {
+    return '';
+  }
+  var _o = pathNodes.o;
+  var _i = pathNodes.i;
+  var _v = pathNodes.v;
+  var i;
+  var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+  for (i = 1; i < length; i += 1) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
+  }
+  if (closed && length) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+    shapeString += 'z';
+  }
+  return shapeString;
+};
+
+const SVGElementsRenderer = (function () {
+  var _identityMatrix = new Matrix();
+  var _matrixHelper = new Matrix();
+
+  var ob = {
+    createRenderFunction: createRenderFunction,
+  };
+
+  function createRenderFunction(data) {
+    switch (data.ty) {
+      case 'fl':
+        return renderFill;
+      case 'gf':
+        return renderGradient;
+      case 'gs':
+        return renderGradientStroke;
+      case 'st':
+        return renderStroke;
+      case 'sh':
+      case 'el':
+      case 'rc':
+      case 'sr':
+        return renderPath;
+      case 'tr':
+        return renderContentTransform;
+      case 'no':
+        return renderNoop;
+      default:
+        return null;
+    }
+  }
+
+  function renderContentTransform(styleData, itemData, isFirstFrame) {
+    if (isFirstFrame || itemData.transform.op._mdf) {
+      itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
+    }
+    if (isFirstFrame || itemData.transform.mProps._mdf) {
+      itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
+    }
+  }
+
+  function renderNoop() {
+
+  }
+
+  function renderPath(styleData, itemData, isFirstFrame) {
+    var j;
+    var jLen;
+    var pathStringTransformed;
+    var redraw;
+    var pathNodes;
+    var l;
+    var lLen = itemData.styles.length;
+    var lvl = itemData.lvl;
+    var paths;
+    var mat;
+    var iterations;
+    var k;
+    for (l = 0; l < lLen; l += 1) {
+      redraw = itemData.sh._mdf || isFirstFrame;
+      if (itemData.styles[l].lvl < lvl) {
+        mat = _matrixHelper.reset();
+        iterations = lvl - itemData.styles[l].lvl;
+        k = itemData.transformers.length - 1;
+        while (!redraw && iterations > 0) {
+          redraw = itemData.transformers[k].mProps._mdf || redraw;
+          iterations -= 1;
+          k -= 1;
+        }
+        if (redraw) {
+          iterations = lvl - itemData.styles[l].lvl;
+          k = itemData.transformers.length - 1;
+          while (iterations > 0) {
+            mat.multiply(itemData.transformers[k].mProps.v);
+            iterations -= 1;
+            k -= 1;
+          }
+        }
+      } else {
+        mat = _identityMatrix;
+      }
+      paths = itemData.sh.paths;
+      jLen = paths._length;
+      if (redraw) {
+        pathStringTransformed = '';
+        for (j = 0; j < jLen; j += 1) {
+          pathNodes = paths.shapes[j];
+          if (pathNodes && pathNodes._length) {
+            pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
+          }
+        }
+        itemData.caches[l] = pathStringTransformed;
+      } else {
+        pathStringTransformed = itemData.caches[l];
+      }
+      itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
+      itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
+    }
+  }
+
+  function renderFill(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+
+    if (itemData.c._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
+    }
+  }
+
+  function renderGradientStroke(styleData, itemData, isFirstFrame) {
+    renderGradient(styleData, itemData, isFirstFrame);
+    renderStroke(styleData, itemData, isFirstFrame);
+  }
+
+  function renderGradient(styleData, itemData, isFirstFrame) {
+    var gfill = itemData.gf;
+    var hasOpacity = itemData.g._hasOpacity;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+
+    if (itemData.o._mdf || isFirstFrame) {
+      var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
+      itemData.style.pElem.setAttribute(attr, itemData.o.v);
+    }
+    if (itemData.s._mdf || isFirstFrame) {
+      var attr1 = styleData.t === 1 ? 'x1' : 'cx';
+      var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
+      gfill.setAttribute(attr1, pt1[0]);
+      gfill.setAttribute(attr2, pt1[1]);
+      if (hasOpacity && !itemData.g._collapsable) {
+        itemData.of.setAttribute(attr1, pt1[0]);
+        itemData.of.setAttribute(attr2, pt1[1]);
+      }
+    }
+    var stops;
+    var i;
+    var len;
+    var stop;
+    if (itemData.g._cmdf || isFirstFrame) {
+      stops = itemData.cst;
+      var cValues = itemData.g.c;
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        stop.setAttribute('offset', cValues[i * 4] + '%');
+        stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
+      }
+    }
+    if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
+      var oValues = itemData.g.o;
+      if (itemData.g._collapsable) {
+        stops = itemData.cst;
+      } else {
+        stops = itemData.ost;
+      }
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        if (!itemData.g._collapsable) {
+          stop.setAttribute('offset', oValues[i * 2] + '%');
+        }
+        stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
+      }
+    }
+    if (styleData.t === 1) {
+      if (itemData.e._mdf || isFirstFrame) {
+        gfill.setAttribute('x2', pt2[0]);
+        gfill.setAttribute('y2', pt2[1]);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('x2', pt2[0]);
+          itemData.of.setAttribute('y2', pt2[1]);
+        }
+      }
+    } else {
+      var rad;
+      if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
+        rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        gfill.setAttribute('r', rad);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('r', rad);
+        }
+      }
+      if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (!rad) {
+          rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        }
+        var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+        var percent = itemData.h.v;
+        if (percent >= 1) {
+          percent = 0.99;
+        } else if (percent <= -1) {
+          percent = -0.99;
+        }
+        var dist = rad * percent;
+        var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+        var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+        gfill.setAttribute('fx', x);
+        gfill.setAttribute('fy', y);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('fx', x);
+          itemData.of.setAttribute('fy', y);
+        }
+      }
+      // gfill.setAttribute('fy','200');
+    }
+  }
+
+  function renderStroke(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+    var d = itemData.d;
+    if (d && (d._mdf || isFirstFrame) && d.dashStr) {
+      styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
+      styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
+    }
+    if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
+      styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
+    }
+    if (itemData.w._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
+      if (styleElem.msElem) {
+        styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
+      }
+    }
+  }
+
+  return ob;
+}());
+
+function SVGShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
+
+SVGShapeElement.prototype.initSecondaryElement = function () {
+};
+
+SVGShapeElement.prototype.identityMatrix = new Matrix();
+
+SVGShapeElement.prototype.buildExpressionInterface = function () {};
+
+SVGShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+};
+
+/*
+This method searches for multiple shapes that affect a single element and one of them is animated
+*/
+SVGShapeElement.prototype.filterUniqueShapes = function () {
+  var i;
+  var len = this.shapes.length;
+  var shape;
+  var j;
+  var jLen = this.stylesList.length;
+  var style;
+  var tempShapes = [];
+  var areAnimated = false;
+  for (j = 0; j < jLen; j += 1) {
+    style = this.stylesList[j];
+    areAnimated = false;
+    tempShapes.length = 0;
+    for (i = 0; i < len; i += 1) {
+      shape = this.shapes[i];
+      if (shape.styles.indexOf(style) !== -1) {
+        tempShapes.push(shape);
+        areAnimated = shape._isAnimated || areAnimated;
+      }
+    }
+    if (tempShapes.length > 1 && areAnimated) {
+      this.setShapesAsAnimated(tempShapes);
+    }
+  }
+};
+
+SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
+  var i;
+  var len = shapes.length;
+  for (i = 0; i < len; i += 1) {
+    shapes[i].setAsAnimated();
+  }
+};
+
+SVGShapeElement.prototype.createStyleElement = function (data, level) {
+  // TODO: prevent drawing of hidden styles
+  var elementData;
+  var styleOb = new SVGStyleData(data, level);
+
+  var pathElement = styleOb.pElem;
+  if (data.ty === 'st') {
+    elementData = new SVGStrokeStyleData(this, data, styleOb);
+  } else if (data.ty === 'fl') {
+    elementData = new SVGFillStyleData(this, data, styleOb);
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
+    elementData = new GradientConstructor(this, data, styleOb);
+    this.globalData.defs.appendChild(elementData.gf);
+    if (elementData.maskId) {
+      this.globalData.defs.appendChild(elementData.ms);
+      this.globalData.defs.appendChild(elementData.of);
+      pathElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + elementData.maskId + ')');
+    }
+  } else if (data.ty === 'no') {
+    elementData = new SVGNoStyleData(this, data, styleOb);
+  }
+
+  if (data.ty === 'st' || data.ty === 'gs') {
+    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);
+    }
+  }
+
+  if (data.r === 2) {
+    pathElement.setAttribute('fill-rule', 'evenodd');
+  }
+
+  if (data.ln) {
+    pathElement.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    pathElement.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  this.stylesList.push(styleOb);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createGroupElement = function (data) {
+  var elementData = new ShapeGroupData();
+  if (data.ln) {
+    elementData.gr.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    elementData.gr.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  return elementData;
+};
+
+SVGShapeElement.prototype.createTransformElement = function (data, container) {
+  var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
+  var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
+  var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
+  var i = 0;
+  var len = this.animatedContents.length;
+  while (i < len) {
+    if (this.animatedContents[i].element === element) {
+      return;
+    }
+    i += 1;
+  }
+  this.animatedContents.push({
+    fn: SVGElementsRenderer.createRenderFunction(data),
+    element: element,
+    data: data,
+  });
+};
+
+SVGShapeElement.prototype.setElementStyles = function (elementData) {
+  var arr = elementData.styles;
+  var j;
+  var jLen = this.stylesList.length;
+  for (j = 0; j < jLen; j += 1) {
+    if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
+      arr.push(this.stylesList[j]);
+    }
+  }
+};
+
+SVGShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+};
+
+SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
+  var ownTransformers = [].concat(transformers);
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var currentTransform;
+  var modifier;
+  var processedPos;
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._render = render;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], level);
+      } else {
+        itemsData[i].style.closed = arr[i].hd;
+      }
+      if (arr[i]._render) {
+        if (itemsData[i].style.pElem.parentNode !== container) {
+          container.appendChild(itemsData[i].style.pElem);
+        }
+      }
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
+      if (arr[i]._render) {
+        if (itemsData[i].gr.parentNode !== container) {
+          container.appendChild(itemsData[i].gr);
+        }
+      }
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        itemsData[i] = this.createTransformElement(arr[i], container);
+      }
+      currentTransform = itemsData[i].transform;
+      ownTransformers.push(currentTransform);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
+      }
+      this.setElementStyles(itemsData[i]);
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        render = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  len = ownStyles.length;
+  for (i = 0; i < len; i += 1) {
+    ownStyles[i].closed = true;
+  }
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+SVGShapeElement.prototype.renderInnerContent = function () {
+  this.renderModifiers();
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    this.stylesList[i].reset();
+  }
+  this.renderShape();
+  for (i = 0; i < len; i += 1) {
+    if (this.stylesList[i]._mdf || this._isFirstFrame) {
+      if (this.stylesList[i].msElem) {
+        this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+        // Adding M0 0 fixes same mask bug on all browsers
+        this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
+      }
+      this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
+    }
+  }
+};
+
+SVGShapeElement.prototype.renderShape = function () {
+  var i;
+  var len = this.animatedContents.length;
+  var animatedContent;
+  for (i = 0; i < len; i += 1) {
+    animatedContent = this.animatedContents[i];
+    if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
+      animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
+    }
+  }
+};
+
+SVGShapeElement.prototype.destroy = function () {
+  this.destroyBaseElement();
+  this.shapesData = null;
+  this.itemsData = null;
+};
+
+function LetterProps(o, sw, sc, fc, m, p) {
+  this.o = o;
+  this.sw = sw;
+  this.sc = sc;
+  this.fc = fc;
+  this.m = m;
+  this.p = p;
+  this._mdf = {
+    o: true,
+    sw: !!sw,
+    sc: !!sc,
+    fc: !!fc,
+    m: true,
+    p: true,
+  };
+}
+
+LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
+  this._mdf.o = false;
+  this._mdf.sw = false;
+  this._mdf.sc = false;
+  this._mdf.fc = false;
+  this._mdf.m = false;
+  this._mdf.p = false;
+  var updated = false;
+
+  if (this.o !== o) {
+    this.o = o;
+    this._mdf.o = true;
+    updated = true;
+  }
+  if (this.sw !== sw) {
+    this.sw = sw;
+    this._mdf.sw = true;
+    updated = true;
+  }
+  if (this.sc !== sc) {
+    this.sc = sc;
+    this._mdf.sc = true;
+    updated = true;
+  }
+  if (this.fc !== fc) {
+    this.fc = fc;
+    this._mdf.fc = true;
+    updated = true;
+  }
+  if (this.m !== m) {
+    this.m = m;
+    this._mdf.m = true;
+    updated = true;
+  }
+  if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
+    this.p = p;
+    this._mdf.p = true;
+    updated = true;
+  }
+  return updated;
+};
+
+function TextProperty(elem, data) {
+  this._frameId = initialDefaultFrame;
+  this.pv = '';
+  this.v = '';
+  this.kf = false;
+  this._isFirstFrame = true;
+  this._mdf = false;
+  if (data.d && data.d.sid) {
+    data.d = elem.globalData.slotManager.getProp(data.d);
+  }
+  this.data = data;
+  this.elem = elem;
+  this.comp = this.elem.comp;
+  this.keysIndex = 0;
+  this.canResize = false;
+  this.minimumFontSize = 1;
+  this.effectsSequence = [];
+  this.currentData = {
+    ascent: 0,
+    boxWidth: this.defaultBoxWidth,
+    f: '',
+    fStyle: '',
+    fWeight: '',
+    fc: '',
+    j: '',
+    justifyOffset: '',
+    l: [],
+    lh: 0,
+    lineWidths: [],
+    ls: '',
+    of: '',
+    s: '',
+    sc: '',
+    sw: 0,
+    t: 0,
+    tr: 0,
+    sz: 0,
+    ps: null,
+    fillColorAnim: false,
+    strokeColorAnim: false,
+    strokeWidthAnim: false,
+    yOffset: 0,
+    finalSize: 0,
+    finalText: [],
+    finalLineHeight: 0,
+    __complete: false,
+
+  };
+  this.copyData(this.currentData, this.data.d.k[0].s);
+
+  if (!this.searchProperty()) {
+    this.completeTextData(this.currentData);
+  }
+}
+
+TextProperty.prototype.defaultBoxWidth = [0, 0];
+
+TextProperty.prototype.copyData = function (obj, data) {
+  for (var s in data) {
+    if (Object.prototype.hasOwnProperty.call(data, s)) {
+      obj[s] = data[s];
+    }
+  }
+  return obj;
+};
+
+TextProperty.prototype.setCurrentData = function (data) {
+  if (!data.__complete) {
+    this.completeTextData(data);
+  }
+  this.currentData = data;
+  this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
+  this._mdf = true;
+};
+
+TextProperty.prototype.searchProperty = function () {
+  return this.searchKeyframes();
+};
+
+TextProperty.prototype.searchKeyframes = function () {
+  this.kf = this.data.d.k.length > 1;
+  if (this.kf) {
+    this.addEffect(this.getKeyframeValue.bind(this));
+  }
+  return this.kf;
+};
+
+TextProperty.prototype.addEffect = function (effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.getValue = function (_finalValue) {
+  if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
+    return;
+  }
+  this.currentData.t = this.data.d.k[this.keysIndex].s.t;
+  var currentValue = this.currentData;
+  var currentIndex = this.keysIndex;
+  if (this.lock) {
+    this.setCurrentData(this.currentData);
+    return;
+  }
+  this.lock = true;
+  this._mdf = false;
+  var i; var
+    len = this.effectsSequence.length;
+  var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
+  for (i = 0; i < len; i += 1) {
+    // Checking if index changed to prevent creating a new object every time the expression updates.
+    if (currentIndex !== this.keysIndex) {
+      finalValue = this.effectsSequence[i](finalValue, finalValue.t);
+    } else {
+      finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
+    }
+  }
+  if (currentValue !== finalValue) {
+    this.setCurrentData(finalValue);
+  }
+  this.v = this.currentData;
+  this.pv = this.v;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+};
+
+TextProperty.prototype.getKeyframeValue = function () {
+  var textKeys = this.data.d.k;
+  var frameNum = this.elem.comp.renderedFrame;
+  var i = 0; var
+    len = textKeys.length;
+  while (i <= len - 1) {
+    if (i === len - 1 || textKeys[i + 1].t > frameNum) {
+      break;
+    }
+    i += 1;
+  }
+  if (this.keysIndex !== i) {
+    this.keysIndex = i;
+  }
+  return this.data.d.k[this.keysIndex].s;
+};
+
+TextProperty.prototype.buildFinalText = function (text) {
+  var charactersArray = [];
+  var i = 0;
+  var len = text.length;
+  var charCode;
+  var secondCharCode;
+  var shouldCombine = false;
+  var shouldCombineNext = false;
+  var currentChars = '';
+  while (i < len) {
+    shouldCombine = shouldCombineNext;
+    shouldCombineNext = false;
+    charCode = text.charCodeAt(i);
+    currentChars = text.charAt(i);
+    if (FontManager.isCombinedCharacter(charCode)) {
+      shouldCombine = true;
+      // It's a potential surrogate pair (this is the High surrogate)
+    } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+      if (FontManager.isRegionalFlag(text, i)) {
+        currentChars = text.substr(i, 14);
+      } else {
+        secondCharCode = text.charCodeAt(i + 1);
+        // It's a surrogate pair (this is the Low surrogate)
+        if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
+          if (FontManager.isModifier(charCode, secondCharCode)) {
+            currentChars = text.substr(i, 2);
+            shouldCombine = true;
+          } else if (FontManager.isFlagEmoji(text.substr(i, 4))) {
+            currentChars = text.substr(i, 4);
+          } else {
+            currentChars = text.substr(i, 2);
+          }
+        }
+      }
+    } else if (charCode > 0xDBFF) {
+      secondCharCode = text.charCodeAt(i + 1);
+      if (FontManager.isVariationSelector(charCode)) {
+        shouldCombine = true;
+      }
+    } else if (FontManager.isZeroWidthJoiner(charCode)) {
+      shouldCombine = true;
+      shouldCombineNext = true;
+    }
+    if (shouldCombine) {
+      charactersArray[charactersArray.length - 1] += currentChars;
+      shouldCombine = false;
+    } else {
+      charactersArray.push(currentChars);
+    }
+    i += currentChars.length;
+  }
+  return charactersArray;
+};
+
+TextProperty.prototype.completeTextData = function (documentData) {
+  documentData.__complete = true;
+  var fontManager = this.elem.globalData.fontManager;
+  var data = this.data;
+  var letters = [];
+  var i; var
+    len;
+  var newLineFlag; var index = 0; var
+    val;
+  var anchorGrouping = data.m.g;
+  var currentSize = 0; var currentPos = 0; var currentLine = 0; var
+    lineWidths = [];
+  var lineWidth = 0;
+  var maxLineWidth = 0;
+  var j; var
+    jLen;
+  var fontData = fontManager.getFontByName(documentData.f);
+  var charData; var
+    cLength = 0;
+
+  var fontProps = getFontProperties(fontData);
+  documentData.fWeight = fontProps.weight;
+  documentData.fStyle = fontProps.style;
+  documentData.finalSize = documentData.s;
+  documentData.finalText = this.buildFinalText(documentData.t);
+  len = documentData.finalText.length;
+  documentData.finalLineHeight = documentData.lh;
+  var trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+  var charCode;
+  if (documentData.sz) {
+    var flag = true;
+    var boxWidth = documentData.sz[0];
+    var boxHeight = documentData.sz[1];
+    var currentHeight; var
+      finalText;
+    while (flag) {
+      finalText = this.buildFinalText(documentData.t);
+      currentHeight = 0;
+      lineWidth = 0;
+      len = finalText.length;
+      trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+      var lastSpaceIndex = -1;
+      for (i = 0; i < len; i += 1) {
+        charCode = finalText[i].charCodeAt(0);
+        newLineFlag = false;
+        if (finalText[i] === ' ') {
+          lastSpaceIndex = i;
+        } else if (charCode === 13 || charCode === 3) {
+          lineWidth = 0;
+          newLineFlag = true;
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+        }
+        if (fontManager.chars) {
+          charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
+          cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+        } else {
+          // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
+          cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
+        }
+        if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
+          if (lastSpaceIndex === -1) {
+            len += 1;
+          } else {
+            i = lastSpaceIndex;
+          }
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+          finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+          // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
+          lastSpaceIndex = -1;
+          lineWidth = 0;
+        } else {
+          lineWidth += cLength;
+          lineWidth += trackingOffset;
+        }
+      }
+      currentHeight += (fontData.ascent * documentData.finalSize) / 100;
+      if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
+        documentData.finalSize -= 1;
+        documentData.finalLineHeight = (documentData.finalSize * documentData.lh) / documentData.s;
+      } else {
+        documentData.finalText = finalText;
+        len = documentData.finalText.length;
+        flag = false;
+      }
+    }
+  }
+  lineWidth = -trackingOffset;
+  cLength = 0;
+  var uncollapsedSpaces = 0;
+  var currentChar;
+  for (i = 0; i < len; i += 1) {
+    newLineFlag = false;
+    currentChar = documentData.finalText[i];
+    charCode = currentChar.charCodeAt(0);
+    if (charCode === 13 || charCode === 3) {
+      uncollapsedSpaces = 0;
+      lineWidths.push(lineWidth);
+      maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+      lineWidth = -2 * trackingOffset;
+      val = '';
+      newLineFlag = true;
+      currentLine += 1;
+    } else {
+      val = currentChar;
+    }
+    if (fontManager.chars) {
+      charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
+      cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+    } else {
+      // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
+      // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
+      cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
+    }
+
+    //
+    if (currentChar === ' ') {
+      uncollapsedSpaces += cLength + trackingOffset;
+    } else {
+      lineWidth += cLength + trackingOffset + uncollapsedSpaces;
+      uncollapsedSpaces = 0;
+    }
+    letters.push({
+      l: cLength, an: cLength, add: currentSize, n: newLineFlag, anIndexes: [], val: val, line: currentLine, animatorJustifyOffset: 0,
+    });
+    if (anchorGrouping == 2) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || val === ' ' || i === len - 1) {
+        if (val === '' || val === ' ') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        index += 1;
+        currentSize = 0;
+      }
+    } else if (anchorGrouping == 3) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || i === len - 1) {
+        if (val === '') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        currentSize = 0;
+        index += 1;
+      }
+    } else {
+      letters[index].ind = index;
+      letters[index].extra = 0;
+      index += 1;
+    }
+  }
+  documentData.l = letters;
+  maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+  lineWidths.push(lineWidth);
+  if (documentData.sz) {
+    documentData.boxWidth = documentData.sz[0];
+    documentData.justifyOffset = 0;
+  } else {
+    documentData.boxWidth = maxLineWidth;
+    switch (documentData.j) {
+      case 1:
+        documentData.justifyOffset = -documentData.boxWidth;
+        break;
+      case 2:
+        documentData.justifyOffset = -documentData.boxWidth / 2;
+        break;
+      default:
+        documentData.justifyOffset = 0;
+    }
+  }
+  documentData.lineWidths = lineWidths;
+
+  var animators = data.a; var animatorData; var
+    letterData;
+  jLen = animators.length;
+  var based; var ind; var
+    indexes = [];
+  for (j = 0; j < jLen; j += 1) {
+    animatorData = animators[j];
+    if (animatorData.a.sc) {
+      documentData.strokeColorAnim = true;
+    }
+    if (animatorData.a.sw) {
+      documentData.strokeWidthAnim = true;
+    }
+    if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
+      documentData.fillColorAnim = true;
+    }
+    ind = 0;
+    based = animatorData.s.b;
+    for (i = 0; i < len; i += 1) {
+      letterData = letters[i];
+      letterData.anIndexes[j] = ind;
+      if ((based == 1 && letterData.val !== '') || (based == 2 && letterData.val !== '' && letterData.val !== ' ') || (based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1)) || (based == 4 && (letterData.n || i == len - 1))) { // eslint-disable-line eqeqeq
+        if (animatorData.s.rn === 1) {
+          indexes.push(ind);
+        }
+        ind += 1;
+      }
+    }
+    data.a[j].s.totalChars = ind;
+    var currentInd = -1; var
+      newInd;
+    if (animatorData.s.rn === 1) {
+      for (i = 0; i < len; i += 1) {
+        letterData = letters[i];
+        if (currentInd != letterData.anIndexes[j]) { // eslint-disable-line eqeqeq
+          currentInd = letterData.anIndexes[j];
+          newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
+        }
+        letterData.anIndexes[j] = newInd;
+      }
+    }
+  }
+  documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
+  documentData.ls = documentData.ls || 0;
+  documentData.ascent = (fontData.ascent * documentData.finalSize) / 100;
+};
+
+TextProperty.prototype.updateDocumentData = function (newData, index) {
+  index = index === undefined ? this.keysIndex : index;
+  var dData = this.copyData({}, this.data.d.k[index].s);
+  dData = this.copyData(dData, newData);
+  this.data.d.k[index].s = dData;
+  this.recalculate(index);
+  this.setCurrentData(dData);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.recalculate = function (index) {
+  var dData = this.data.d.k[index].s;
+  dData.__complete = false;
+  this.keysIndex = 0;
+  this._isFirstFrame = true;
+  this.getValue(dData);
+};
+
+TextProperty.prototype.canResizeFont = function (_canResize) {
+  this.canResize = _canResize;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
+  this.minimumFontSize = Math.floor(_fontValue) || 1;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+const TextSelectorProp = (function () {
+  var max = Math.max;
+  var min = Math.min;
+  var floor = Math.floor;
+
+  function TextSelectorPropFactory(elem, data) {
+    this._currentTextLength = -1;
+    this.k = false;
+    this.data = data;
+    this.elem = elem;
+    this.comp = elem.comp;
+    this.finalS = 0;
+    this.finalE = 0;
+    this.initDynamicPropertyContainer(elem);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: 0 }, 0, 0, this);
+    if ('e' in data) {
+      this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
+    } else {
+      this.e = { v: 100 };
+    }
+    this.o = PropertyFactory.getProp(elem, data.o || { k: 0 }, 0, 0, this);
+    this.xe = PropertyFactory.getProp(elem, data.xe || { k: 0 }, 0, 0, this);
+    this.ne = PropertyFactory.getProp(elem, data.ne || { k: 0 }, 0, 0, this);
+    this.sm = PropertyFactory.getProp(elem, data.sm || { k: 100 }, 0, 0, this);
+    this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
+    if (!this.dynamicProperties.length) {
+      this.getValue();
+    }
+  }
+
+  TextSelectorPropFactory.prototype = {
+    getMult: function (ind) {
+      if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
+        this.getValue();
+      }
+      var x1 = 0;
+      var y1 = 0;
+      var x2 = 1;
+      var y2 = 1;
+      if (this.ne.v > 0) {
+        x1 = this.ne.v / 100.0;
+      } else {
+        y1 = -this.ne.v / 100.0;
+      }
+      if (this.xe.v > 0) {
+        x2 = 1.0 - this.xe.v / 100.0;
+      } else {
+        y2 = 1.0 + this.xe.v / 100.0;
+      }
+      var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
+
+      var mult = 0;
+      var s = this.finalS;
+      var e = this.finalE;
+      var type = this.data.sh;
+      if (type === 2) {
+        if (e === s) {
+          mult = ind >= e ? 1 : 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+        mult = easer(mult);
+      } else if (type === 3) {
+        if (e === s) {
+          mult = ind >= e ? 0 : 1;
+        } else {
+          mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+
+        mult = easer(mult);
+      } else if (type === 4) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+          if (mult < 0.5) {
+            mult *= 2;
+          } else {
+            mult = 1 - 2 * (mult - 0.5);
+          }
+        }
+        mult = easer(mult);
+      } else if (type === 5) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          var tot = e - s;
+          /* ind += 0.5;
+                    mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          var x = -tot / 2 + ind;
+          var a = tot / 2;
+          mult = Math.sqrt(1 - (x * x) / (a * a));
+        }
+        mult = easer(mult);
+      } else if (type === 6) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; // eslint-disable-line
+        }
+        mult = easer(mult);
+      } else {
+        if (ind >= floor(s)) {
+          if (ind - s < 0) {
+            mult = max(0, min(min(e, 1) - (s - ind), 1));
+          } else {
+            mult = max(0, min(e - ind, 1));
+          }
+        }
+        mult = easer(mult);
+      }
+      // Smoothness implementation.
+      // The smoothness represents a reduced range of the original [0; 1] range.
+      // if smoothness is 25%, the new range will be [0.375; 0.625]
+      // Steps are:
+      // - find the lower value of the new range (threshold)
+      // - if multiplier is smaller than that value, floor it to 0
+      // - if it is larger,
+      //     - subtract the threshold
+      //     - divide it by the smoothness (this will return the range to [0; 1])
+      // Note: If it doesn't work on some scenarios, consider applying it before the easer.
+      if (this.sm.v !== 100) {
+        var smoothness = this.sm.v * 0.01;
+        if (smoothness === 0) {
+          smoothness = 0.00000001;
+        }
+        var threshold = 0.5 - smoothness * 0.5;
+        if (mult < threshold) {
+          mult = 0;
+        } else {
+          mult = (mult - threshold) / smoothness;
+          if (mult > 1) {
+            mult = 1;
+          }
+        }
+      }
+      return mult * this.a.v;
+    },
+    getValue: function (newCharsFlag) {
+      this.iterateDynamicProperties();
+      this._mdf = newCharsFlag || this._mdf;
+      this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
+      if (newCharsFlag && this.data.r === 2) {
+        this.e.v = this._currentTextLength;
+      }
+      var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
+      var o = this.o.v / divisor;
+      var s = this.s.v / divisor + o;
+      var e = (this.e.v / divisor) + o;
+      if (s > e) {
+        var _s = s;
+        s = e;
+        e = _s;
+      }
+      this.finalS = s;
+      this.finalE = e;
+    },
+  };
+  extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
+
+  function getTextSelectorProp(elem, data, arr) {
+    return new TextSelectorPropFactory(elem, data, arr);
+  }
+
+  return {
+    getTextSelectorProp: getTextSelectorProp,
+  };
+}());
+
+function TextAnimatorDataProperty(elem, animatorProps, container) {
+  var defaultData = { propType: false };
+  var getProp = PropertyFactory.getProp;
+  var textAnimatorAnimatables = animatorProps.a;
+  this.a = {
+    r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData,
+    rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData,
+    ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData,
+    sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData,
+    sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData,
+    s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData,
+    a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData,
+    o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData,
+    p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData,
+    sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData,
+    sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData,
+    fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData,
+    fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData,
+    fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData,
+    fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData,
+    t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData,
+  };
+
+  this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container);
+  this.s.t = animatorProps.s.t;
+}
+
+function TextAnimatorProperty(textData, renderType, elem) {
+  this._isFirstFrame = true;
+  this._hasMaskedPath = false;
+  this._frameId = -1;
+  this._textData = textData;
+  this._renderType = renderType;
+  this._elem = elem;
+  this._animatorsData = createSizedArray(this._textData.a.length);
+  this._pathData = {};
+  this._moreOptions = {
+    alignment: {},
+  };
+  this.renderedLetters = [];
+  this.lettersChangedFlag = false;
+  this.initDynamicPropertyContainer(elem);
+}
+
+TextAnimatorProperty.prototype.searchProperties = function () {
+  var i;
+  var len = this._textData.a.length;
+  var animatorProps;
+  var getProp = PropertyFactory.getProp;
+  for (i = 0; i < len; i += 1) {
+    animatorProps = this._textData.a[i];
+    this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
+  }
+  if (this._textData.p && 'm' in this._textData.p) {
+    this._pathData = {
+      a: getProp(this._elem, this._textData.p.a, 0, 0, this),
+      f: getProp(this._elem, this._textData.p.f, 0, 0, this),
+      l: getProp(this._elem, this._textData.p.l, 0, 0, this),
+      r: getProp(this._elem, this._textData.p.r, 0, 0, this),
+      p: getProp(this._elem, this._textData.p.p, 0, 0, this),
+      m: this._elem.maskManager.getMaskProperty(this._textData.p.m),
+    };
+    this._hasMaskedPath = true;
+  } else {
+    this._hasMaskedPath = false;
+  }
+  this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
+};
+
+TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
+  this.lettersChangedFlag = lettersChangedFlag;
+  if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
+    return;
+  }
+  this._isFirstFrame = false;
+  var alignment = this._moreOptions.alignment.v;
+  var animators = this._animatorsData;
+  var textData = this._textData;
+  var matrixHelper = this.mHelper;
+  var renderType = this._renderType;
+  var renderedLettersCount = this.renderedLetters.length;
+  var xPos;
+  var yPos;
+  var i;
+  var len;
+  var letters = documentData.l;
+  var pathInfo;
+  var currentLength;
+  var currentPoint;
+  var segmentLength;
+  var flag;
+  var pointInd;
+  var segmentInd;
+  var prevPoint;
+  var points;
+  var segments;
+  var partialLength;
+  var totalLength;
+  var perc;
+  var tanAngle;
+  var mask;
+  if (this._hasMaskedPath) {
+    mask = this._pathData.m;
+    if (!this._pathData.n || this._pathData._mdf) {
+      var paths = mask.v;
+      if (this._pathData.r.v) {
+        paths = paths.reverse();
+      }
+      // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
+      pathInfo = {
+        tLength: 0,
+        segments: [],
+      };
+      len = paths._length - 1;
+      var bezierData;
+      totalLength = 0;
+      for (i = 0; i < len; i += 1) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[i + 1],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      i = len;
+      if (mask.v.c) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[0],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      this._pathData.pi = pathInfo;
+    }
+    pathInfo = this._pathData.pi;
+
+    currentLength = this._pathData.f.v;
+    segmentInd = 0;
+    pointInd = 1;
+    segmentLength = 0;
+    flag = true;
+    segments = pathInfo.segments;
+    if (currentLength < 0 && mask.v.c) {
+      if (pathInfo.tLength < Math.abs(currentLength)) {
+        currentLength = -Math.abs(currentLength) % pathInfo.tLength;
+      }
+      segmentInd = segments.length - 1;
+      points = segments[segmentInd].points;
+      pointInd = points.length - 1;
+      while (currentLength < 0) {
+        currentLength += points[pointInd].partialLength;
+        pointInd -= 1;
+        if (pointInd < 0) {
+          segmentInd -= 1;
+          points = segments[segmentInd].points;
+          pointInd = points.length - 1;
+        }
+      }
+    }
+    points = segments[segmentInd].points;
+    prevPoint = points[pointInd - 1];
+    currentPoint = points[pointInd];
+    partialLength = currentPoint.partialLength;
+  }
+
+  len = letters.length;
+  xPos = 0;
+  yPos = 0;
+  var yOff = documentData.finalSize * 1.2 * 0.714;
+  var firstLine = true;
+  var animatorProps;
+  var animatorSelector;
+  var j;
+  var jLen;
+  var letterValue;
+
+  jLen = animators.length;
+
+  var mult;
+  var ind = -1;
+  var offf;
+  var xPathPos;
+  var yPathPos;
+  var initPathPos = currentLength;
+  var initSegmentInd = segmentInd;
+  var initPointInd = pointInd;
+  var currentLine = -1;
+  var elemOpacity;
+  var sc;
+  var sw;
+  var fc;
+  var k;
+  var letterSw;
+  var letterSc;
+  var letterFc;
+  var letterM = '';
+  var letterP = this.defaultPropsArray;
+  var letterO;
+
+  //
+  if (documentData.j === 2 || documentData.j === 1) {
+    var animatorJustifyOffset = 0;
+    var animatorFirstCharOffset = 0;
+    var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
+    var lastIndex = 0;
+    var isNewLine = true;
+
+    for (i = 0; i < len; i += 1) {
+      if (letters[i].n) {
+        if (animatorJustifyOffset) {
+          animatorJustifyOffset += animatorFirstCharOffset;
+        }
+        while (lastIndex < i) {
+          letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+          lastIndex += 1;
+        }
+        animatorJustifyOffset = 0;
+        isNewLine = true;
+      } else {
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.t.propType) {
+            if (isNewLine && documentData.j === 2) {
+              animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
+            }
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
+            } else {
+              animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult;
+            }
+          }
+        }
+        isNewLine = false;
+      }
+    }
+    if (animatorJustifyOffset) {
+      animatorJustifyOffset += animatorFirstCharOffset;
+    }
+    while (lastIndex < i) {
+      letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+      lastIndex += 1;
+    }
+  }
+  //
+
+  for (i = 0; i < len; i += 1) {
+    matrixHelper.reset();
+    elemOpacity = 1;
+    if (letters[i].n) {
+      xPos = 0;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      currentLength = initPathPos;
+      firstLine = false;
+      if (this._hasMaskedPath) {
+        segmentInd = initSegmentInd;
+        pointInd = initPointInd;
+        points = segments[segmentInd].points;
+        prevPoint = points[pointInd - 1];
+        currentPoint = points[pointInd];
+        partialLength = currentPoint.partialLength;
+        segmentLength = 0;
+      }
+      letterM = '';
+      letterFc = '';
+      letterSw = '';
+      letterO = '';
+      letterP = this.defaultPropsArray;
+    } else {
+      if (this._hasMaskedPath) {
+        if (currentLine !== letters[i].line) {
+          switch (documentData.j) {
+            case 1:
+              currentLength += totalLength - documentData.lineWidths[letters[i].line];
+              break;
+            case 2:
+              currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
+              break;
+            default:
+              break;
+          }
+          currentLine = letters[i].line;
+        }
+        if (ind !== letters[i].ind) {
+          if (letters[ind]) {
+            currentLength += letters[ind].extra;
+          }
+          currentLength += letters[i].an / 2;
+          ind = letters[i].ind;
+        }
+        currentLength += (alignment[0] * letters[i].an) * 0.005;
+        var animatorOffset = 0;
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.p.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.p.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.p.v[0] * mult;
+            }
+          }
+          if (animatorProps.a.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.a.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.a.v[0] * mult;
+            }
+          }
+        }
+        flag = true;
+        // Force alignment only works with a single line for now
+        if (this._pathData.a.v) {
+          currentLength = letters[0].an * 0.5 + ((totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind) / (len - 1);
+          currentLength += this._pathData.f.v;
+        }
+        while (flag) {
+          if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
+            perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
+            xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
+            yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
+            matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, -(alignment[1] * yOff) * 0.01);
+            flag = false;
+          } else if (points) {
+            segmentLength += currentPoint.partialLength;
+            pointInd += 1;
+            if (pointInd >= points.length) {
+              pointInd = 0;
+              segmentInd += 1;
+              if (!segments[segmentInd]) {
+                if (mask.v.c) {
+                  pointInd = 0;
+                  segmentInd = 0;
+                  points = segments[segmentInd].points;
+                } else {
+                  segmentLength -= currentPoint.partialLength;
+                  points = null;
+                }
+              } else {
+                points = segments[segmentInd].points;
+              }
+            }
+            if (points) {
+              prevPoint = currentPoint;
+              currentPoint = points[pointInd];
+              partialLength = currentPoint.partialLength;
+            }
+          }
+        }
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+      } else {
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+
+        // Grouping alignment
+        matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, (-alignment[1] * yOff) * 0.01, 0);
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.t.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
+          if (xPos !== 0 || documentData.j !== 0) {
+            if (this._hasMaskedPath) {
+              if (mult.length) {
+                currentLength += animatorProps.t.v * mult[0];
+              } else {
+                currentLength += animatorProps.t.v * mult;
+              }
+            } else if (mult.length) {
+              xPos += animatorProps.t.v * mult[0];
+            } else {
+              xPos += animatorProps.t.v * mult;
+            }
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        sw = documentData.sw || 0;
+      }
+      if (documentData.strokeColorAnim) {
+        if (documentData.sc) {
+          sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
+        } else {
+          sc = [0, 0, 0];
+        }
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.a.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+
+          if (mult.length) {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.s.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (mult.length) {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult[0]), 1 + ((animatorProps.s.v[1] - 1) * mult[1]), 1);
+          } else {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult), 1 + ((animatorProps.s.v[1] - 1) * mult), 1);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        animatorSelector = animators[j].s;
+        mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+        if (animatorProps.sk.propType) {
+          if (mult.length) {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
+          } else {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
+          }
+        }
+        if (animatorProps.r.propType) {
+          if (mult.length) {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
+          } else {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult);
+          }
+        }
+        if (animatorProps.ry.propType) {
+          if (mult.length) {
+            matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
+          } else {
+            matrixHelper.rotateY(animatorProps.ry.v * mult);
+          }
+        }
+        if (animatorProps.rx.propType) {
+          if (mult.length) {
+            matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
+          } else {
+            matrixHelper.rotateX(animatorProps.rx.v * mult);
+          }
+        }
+        if (animatorProps.o.propType) {
+          if (mult.length) {
+            elemOpacity += ((animatorProps.o.v) * mult[0] - elemOpacity) * mult[0];
+          } else {
+            elemOpacity += ((animatorProps.o.v) * mult - elemOpacity) * mult;
+          }
+        }
+        if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
+          if (mult.length) {
+            sw += animatorProps.sw.v * mult[0];
+          } else {
+            sw += animatorProps.sw.v * mult;
+          }
+        }
+        if (documentData.strokeColorAnim && animatorProps.sc.propType) {
+          for (k = 0; k < 3; k += 1) {
+            if (mult.length) {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0];
+            } else {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult;
+            }
+          }
+        }
+        if (documentData.fillColorAnim && documentData.fc) {
+          if (animatorProps.fc.propType) {
+            for (k = 0; k < 3; k += 1) {
+              if (mult.length) {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0];
+              } else {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult;
+              }
+            }
+          }
+          if (animatorProps.fh.propType) {
+            if (mult.length) {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
+            } else {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult);
+            }
+          }
+          if (animatorProps.fs.propType) {
+            if (mult.length) {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
+            } else {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
+            }
+          }
+          if (animatorProps.fb.propType) {
+            if (mult.length) {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
+            } else {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult);
+            }
+          }
+        }
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+
+        if (animatorProps.p.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (this._hasMaskedPath) {
+            if (mult.length) {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
+            } else {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+            }
+          } else if (mult.length) {
+            matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        letterSw = sw < 0 ? 0 : sw;
+      }
+      if (documentData.strokeColorAnim) {
+        letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
+      }
+
+      if (this._hasMaskedPath) {
+        matrixHelper.translate(0, -documentData.ls);
+
+        matrixHelper.translate(0, (alignment[1] * yOff) * 0.01 + yPos, 0);
+        if (this._pathData.p.v) {
+          tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
+          var rot = (Math.atan(tanAngle) * 180) / Math.PI;
+          if (currentPoint.point[0] < prevPoint.point[0]) {
+            rot += 180;
+          }
+          matrixHelper.rotate((-rot * Math.PI) / 180);
+        }
+        matrixHelper.translate(xPathPos, yPathPos, 0);
+        currentLength -= (alignment[0] * letters[i].an) * 0.005;
+        if (letters[i + 1] && ind !== letters[i + 1].ind) {
+          currentLength += letters[i].an / 2;
+          currentLength += (documentData.tr * 0.001) * documentData.finalSize;
+        }
+      } else {
+        matrixHelper.translate(xPos, yPos, 0);
+
+        if (documentData.ps) {
+          // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
+          matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+        }
+        switch (documentData.j) {
+          case 1:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
+            break;
+          case 2:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
+            break;
+          default:
+            break;
+        }
+        matrixHelper.translate(0, -documentData.ls);
+        matrixHelper.translate(offf, 0, 0);
+        matrixHelper.translate((alignment[0] * letters[i].an) * 0.005, (alignment[1] * yOff) * 0.01, 0);
+        xPos += letters[i].l + (documentData.tr * 0.001) * documentData.finalSize;
+      }
+      if (renderType === 'html') {
+        letterM = matrixHelper.toCSS();
+      } else if (renderType === 'svg') {
+        letterM = matrixHelper.to2dCSS();
+      } else {
+        letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
+      }
+      letterO = elemOpacity;
+    }
+
+    if (renderedLettersCount <= i) {
+      letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
+      this.renderedLetters.push(letterValue);
+      renderedLettersCount += 1;
+      this.lettersChangedFlag = true;
+    } else {
+      letterValue = this.renderedLetters[i];
+      this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag;
+    }
+  }
+};
+
+TextAnimatorProperty.prototype.getValue = function () {
+  if (this._elem.globalData.frameId === this._frameId) {
+    return;
+  }
+  this._frameId = this._elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+TextAnimatorProperty.prototype.mHelper = new Matrix();
+TextAnimatorProperty.prototype.defaultPropsArray = [];
+extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
+
+function ITextElement() {
+}
+
+ITextElement.prototype.initElement = function (data, globalData, comp) {
+  this.lettersChangedFlag = true;
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.textProperty = new TextProperty(this, data.t, this.dynamicProperties);
+  this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this);
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+  this.initRenderable();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  this.createContent();
+  this.hide();
+  this.textAnimator.searchProperties(this.dynamicProperties);
+};
+
+ITextElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+};
+
+ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
+  var j;
+  var jLen = shapes.length;
+  var pathNodes;
+  var shapeStr = '';
+  for (j = 0; j < jLen; j += 1) {
+    if (shapes[j].ty === 'sh') {
+      pathNodes = shapes[j].ks.k;
+      shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
+    }
+  }
+  return shapeStr;
+};
+
+ITextElement.prototype.updateDocumentData = function (newData, index) {
+  this.textProperty.updateDocumentData(newData, index);
+};
+
+ITextElement.prototype.canResizeFont = function (_canResize) {
+  this.textProperty.canResizeFont(_canResize);
+};
+
+ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
+  this.textProperty.setMinimumFontSize(_fontSize);
+};
+
+ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
+  if (documentData.ps) {
+    matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+  }
+  matrixHelper.translate(0, -documentData.ls, 0);
+  switch (documentData.j) {
+    case 1:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
+      break;
+    case 2:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
+      break;
+    default:
+      break;
+  }
+  matrixHelper.translate(xPos, yPos, 0);
+};
+
+ITextElement.prototype.buildColor = function (colorData) {
+  return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
+};
+
+ITextElement.prototype.emptyProp = new LetterProps();
+
+ITextElement.prototype.destroy = function () {
+
+};
+
+ITextElement.prototype.validateText = function () {
+  if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
+    this.buildNewText();
+    this.textProperty._isFirstFrame = false;
+    this.textProperty._mdf = false;
+  }
+};
+
+var emptyShapeData = {
+  shapes: [],
+};
+
+function SVGTextLottieElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.renderType = 'svg';
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
+
+SVGTextLottieElement.prototype.createContent = function () {
+  if (this.data.singleShape && !this.globalData.fontManager.chars) {
+    this.textContainer = createNS('text');
+  }
+};
+
+SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
+  var i = 0;
+  var len = textArray.length;
+  var textContents = [];
+  var currentTextContent = '';
+  while (i < len) {
+    if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
+      textContents.push(currentTextContent);
+      currentTextContent = '';
+    } else {
+      currentTextContent += textArray[i];
+    }
+    i += 1;
+  }
+  textContents.push(currentTextContent);
+  return textContents;
+};
+
+SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
+  // data should probably be cloned to apply scale separately to each instance of a text on different layers
+  // but since text internal content gets only rendered once and then it's never rerendered,
+  // it's probably safe not to clone data and reuse always the same instance even if the object is mutated.
+  // Avoiding cloning is preferred since cloning each character shape data is expensive
+  if (data.shapes && data.shapes.length) {
+    var shape = data.shapes[0];
+    if (shape.it) {
+      var shapeItem = shape.it[shape.it.length - 1];
+      if (shapeItem.s) {
+        shapeItem.s.k[0] = scale;
+        shapeItem.s.k[1] = scale;
+      }
+    }
+  }
+  return data;
+};
+
+SVGTextLottieElement.prototype.buildNewText = function () {
+  this.addDynamicProperty(this);
+  var i;
+  var len;
+
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
+  if (documentData.fc) {
+    this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
+  } else {
+    this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
+  }
+  if (documentData.sc) {
+    this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
+    this.layerElement.setAttribute('stroke-width', documentData.sw);
+  }
+  this.layerElement.setAttribute('font-size', documentData.finalSize);
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (fontData.fClass) {
+    this.layerElement.setAttribute('class', fontData.fClass);
+  } else {
+    this.layerElement.setAttribute('font-family', fontData.fFamily);
+    var fWeight = documentData.fWeight;
+    var fStyle = documentData.fStyle;
+    this.layerElement.setAttribute('font-style', fStyle);
+    this.layerElement.setAttribute('font-weight', fWeight);
+  }
+  this.layerElement.setAttribute('aria-label', documentData.t);
+
+  var letters = documentData.l || [];
+  var usesGlyphs = !!this.globalData.fontManager.chars;
+  len = letters.length;
+
+  var tSpan;
+  var matrixHelper = this.mHelper;
+  var shapeStr = '';
+  var singleShape = this.data.singleShape;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  if (singleShape && !usesGlyphs && !documentData.sz) {
+    var tElement = this.textContainer;
+    var justify = 'start';
+    switch (documentData.j) {
+      case 1:
+        justify = 'end';
+        break;
+      case 2:
+        justify = 'middle';
+        break;
+      default:
+        justify = 'start';
+        break;
+    }
+    tElement.setAttribute('text-anchor', justify);
+    tElement.setAttribute('letter-spacing', trackingOffset);
+    var textContent = this.buildTextContents(documentData.finalText);
+    len = textContent.length;
+    yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
+    for (i = 0; i < len; i += 1) {
+      tSpan = this.textSpans[i].span || createNS('tspan');
+      tSpan.textContent = textContent[i];
+      tSpan.setAttribute('x', 0);
+      tSpan.setAttribute('y', yPos);
+      tSpan.style.display = 'inherit';
+      tElement.appendChild(tSpan);
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          glyph: null,
+        };
+      }
+      this.textSpans[i].span = tSpan;
+      yPos += documentData.finalLineHeight;
+    }
+
+    this.layerElement.appendChild(tElement);
+  } else {
+    var cachedSpansLength = this.textSpans.length;
+    var charData;
+    for (i = 0; i < len; i += 1) {
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          childSpan: null,
+          glyph: null,
+        };
+      }
+      if (!usesGlyphs || !singleShape || i === 0) {
+        tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
+        if (cachedSpansLength <= i) {
+          tSpan.setAttribute('stroke-linecap', 'butt');
+          tSpan.setAttribute('stroke-linejoin', 'round');
+          tSpan.setAttribute('stroke-miterlimit', '4');
+          this.textSpans[i].span = tSpan;
+          if (usesGlyphs) {
+            var childSpan = createNS('g');
+            tSpan.appendChild(childSpan);
+            this.textSpans[i].childSpan = childSpan;
+          }
+          this.textSpans[i].span = tSpan;
+          this.layerElement.appendChild(tSpan);
+        }
+        tSpan.style.display = 'inherit';
+      }
+
+      matrixHelper.reset();
+      if (singleShape) {
+        if (letters[i].n) {
+          xPos = -trackingOffset;
+          yPos += documentData.yOffset;
+          yPos += firstLine ? 1 : 0;
+          firstLine = false;
+        }
+        this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+        xPos += letters[i].l || 0;
+        // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
+        xPos += trackingOffset;
+      }
+      if (usesGlyphs) {
+        charData = this.globalData.fontManager.getCharData(
+          documentData.finalText[i],
+          fontData.fStyle,
+          this.globalData.fontManager.getFontByName(documentData.f).fFamily
+        );
+        var glyphElement;
+        // t === 1 means the character has been replaced with an animated shaped
+        if (charData.t === 1) {
+          glyphElement = new SVGCompElement(charData.data, this.globalData, this);
+        } else {
+          var data = emptyShapeData;
+          if (charData.data && charData.data.shapes) {
+            data = this.buildShapeData(charData.data, documentData.finalSize);
+          }
+          glyphElement = new SVGShapeElement(data, this.globalData, this);
+        }
+        if (this.textSpans[i].glyph) {
+          var glyph = this.textSpans[i].glyph;
+          this.textSpans[i].childSpan.removeChild(glyph.layerElement);
+          glyph.destroy();
+        }
+        this.textSpans[i].glyph = glyphElement;
+        glyphElement._debug = true;
+        glyphElement.prepareFrame(0);
+        glyphElement.renderFrame();
+        this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+        // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+        // this might have issues with strokes and might need a different solution
+        if (charData.t === 1) {
+          this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
+        }
+      } else {
+        if (singleShape) {
+          tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
+        }
+        tSpan.textContent = letters[i].val;
+        tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      }
+      //
+    }
+    if (singleShape && tSpan) {
+      tSpan.setAttribute('d', shapeStr);
+    }
+  }
+  while (i < this.textSpans.length) {
+    this.textSpans[i].span.style.display = 'none';
+    i += 1;
+  }
+
+  this._sizeChanged = true;
+};
+
+SVGTextLottieElement.prototype.sourceRectAtTime = function () {
+  this.prepareFrame(this.comp.renderedFrame - this.data.st);
+  this.renderInnerContent();
+  if (this._sizeChanged) {
+    this._sizeChanged = false;
+    var textBox = this.layerElement.getBBox();
+    this.bbox = {
+      top: textBox.y,
+      left: textBox.x,
+      width: textBox.width,
+      height: textBox.height,
+    };
+  }
+  return this.bbox;
+};
+
+SVGTextLottieElement.prototype.getValue = function () {
+  var i;
+  var len = this.textSpans.length;
+  var glyphElement;
+  this.renderedFrame = this.comp.renderedFrame;
+  for (i = 0; i < len; i += 1) {
+    glyphElement = this.textSpans[i].glyph;
+    if (glyphElement) {
+      glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
+      if (glyphElement._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+SVGTextLottieElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  if (!this.data.singleShape || this._mdf) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+    if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
+      this._sizeChanged = true;
+      var i;
+      var len;
+      var renderedLetters = this.textAnimator.renderedLetters;
+
+      var letters = this.textProperty.currentData.l;
+
+      len = letters.length;
+      var renderedLetter;
+      var textSpan;
+      var glyphElement;
+      for (i = 0; i < len; i += 1) {
+        if (!letters[i].n) {
+          renderedLetter = renderedLetters[i];
+          textSpan = this.textSpans[i].span;
+          glyphElement = this.textSpans[i].glyph;
+          if (glyphElement) {
+            glyphElement.renderFrame();
+          }
+          if (renderedLetter._mdf.m) {
+            textSpan.setAttribute('transform', renderedLetter.m);
+          }
+          if (renderedLetter._mdf.o) {
+            textSpan.setAttribute('opacity', renderedLetter.o);
+          }
+          if (renderedLetter._mdf.sw) {
+            textSpan.setAttribute('stroke-width', renderedLetter.sw);
+          }
+          if (renderedLetter._mdf.sc) {
+            textSpan.setAttribute('stroke', renderedLetter.sc);
+          }
+          if (renderedLetter._mdf.fc) {
+            textSpan.setAttribute('fill', renderedLetter.fc);
+          }
+        }
+      }
+    }
+  }
+};
+
+function ISolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([IImageElement], ISolidElement);
+
+ISolidElement.prototype.createContent = function () {
+  var rect = createNS('rect');
+  /// /rect.style.width = this.data.sw;
+  /// /rect.style.height = this.data.sh;
+  /// /rect.style.fill = this.data.sc;
+  rect.setAttribute('width', this.data.sw);
+  rect.setAttribute('height', this.data.sh);
+  rect.setAttribute('fill', this.data.sc);
+  this.layerElement.appendChild(rect);
+};
+
+function NullElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initFrame();
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+}
+
+NullElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+NullElement.prototype.renderFrame = function () {
+};
+
+NullElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+NullElement.prototype.destroy = function () {
+};
+
+NullElement.prototype.sourceRectAtTime = function () {
+};
+
+NullElement.prototype.hide = function () {
+};
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
+
+function SVGRendererBase() {
+}
+
+extendPrototype([BaseRenderer], SVGRendererBase);
+
+SVGRendererBase.prototype.createNull = function (data) {
+  return new NullElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createShape = function (data) {
+  return new SVGShapeElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createText = function (data) {
+  return new SVGTextLottieElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createImage = function (data) {
+  return new IImageElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createSolid = function (data) {
+  return new ISolidElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.configAnimation = function (animData) {
+  this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+  this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+  if (this.renderConfig.viewBoxSize) {
+    this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
+  } else {
+    this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
+  }
+
+  if (!this.renderConfig.viewBoxOnly) {
+    this.svgElement.setAttribute('width', animData.w);
+    this.svgElement.setAttribute('height', animData.h);
+    this.svgElement.style.width = '100%';
+    this.svgElement.style.height = '100%';
+    this.svgElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
+  }
+  if (this.renderConfig.width) {
+    this.svgElement.setAttribute('width', this.renderConfig.width);
+  }
+  if (this.renderConfig.height) {
+    this.svgElement.setAttribute('height', this.renderConfig.height);
+  }
+  if (this.renderConfig.className) {
+    this.svgElement.setAttribute('class', this.renderConfig.className);
+  }
+  if (this.renderConfig.id) {
+    this.svgElement.setAttribute('id', this.renderConfig.id);
+  }
+  if (this.renderConfig.focusable !== undefined) {
+    this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
+  }
+  this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+  // this.layerElement.style.transform = 'translate3d(0,0,0)';
+  // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
+  this.animationItem.wrapper.appendChild(this.svgElement);
+  // Mask animation
+  var defs = this.globalData.defs;
+
+  this.setupGlobalData(animData, defs);
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.data = animData;
+
+  var maskElement = createNS('clipPath');
+  var rect = createNS('rect');
+  rect.setAttribute('width', animData.w);
+  rect.setAttribute('height', animData.h);
+  rect.setAttribute('x', 0);
+  rect.setAttribute('y', 0);
+  var maskId = createElementID();
+  maskElement.setAttribute('id', maskId);
+  maskElement.appendChild(rect);
+  this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')');
+
+  defs.appendChild(maskElement);
+  this.layers = animData.layers;
+  this.elements = createSizedArray(animData.layers.length);
+};
+
+SVGRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.layerElement = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+SVGRendererBase.prototype.updateContainerSize = function () {
+};
+
+SVGRendererBase.prototype.findIndexByInd = function (ind) {
+  var i = 0;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.layers[i].ind === ind) {
+      return i;
+    }
+  }
+  return -1;
+};
+
+SVGRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  elements[pos] = true;
+  var element = this.createItem(this.layers[pos]);
+
+  elements[pos] = element;
+  if (getExpressionsPlugin()) {
+    if (this.layers[pos].ty === 0) {
+      this.globalData.projectInterface.registerComposition(element);
+    }
+    element.initExpressions();
+  }
+  this.appendElementInPos(element, pos);
+  if (this.layers[pos].tt) {
+    var elementIndex = ('tp' in this.layers[pos])
+      ? this.findIndexByInd(this.layers[pos].tp)
+      : pos - 1;
+    if (elementIndex === -1) {
+      return;
+    }
+    if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
+      this.buildItem(elementIndex);
+      this.addPendingElement(element);
+    } else {
+      var matteElement = elements[elementIndex];
+      var matteMask = matteElement.getMatte(this.layers[pos].tt);
+      element.setMatte(matteMask);
+    }
+  }
+};
+
+SVGRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+    if (element.data.tt) {
+      var i = 0;
+      var len = this.elements.length;
+      while (i < len) {
+        if (this.elements[i] === element) {
+          var elementIndex = 'tp' in element.data
+            ? this.findIndexByInd(element.data.tp)
+            : i - 1;
+          var matteElement = this.elements[elementIndex];
+          var matteMask = matteElement.getMatte(this.layers[i].tt);
+          element.setMatte(matteMask);
+          break;
+        }
+        i += 1;
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.renderFrame = function (num) {
+  if (this.renderedFrame === num || this.destroyed) {
+    return;
+  }
+  if (num === null) {
+    num = this.renderedFrame;
+  } else {
+    this.renderedFrame = num;
+  }
+  // console.log('-------');
+  // console.log('FRAME ',num);
+  this.globalData.frameNum = num;
+  this.globalData.frameId += 1;
+  this.globalData.projectInterface.currentFrame = num;
+  this.globalData._mdf = false;
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    for (i = 0; i < len; i += 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
+  var newElement = element.getBaseElement();
+  if (!newElement) {
+    return;
+  }
+  var i = 0;
+  var nextElement;
+  while (i < pos) {
+    if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
+      nextElement = this.elements[i].getBaseElement();
+    }
+    i += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(newElement, nextElement);
+  } else {
+    this.layerElement.appendChild(newElement);
+  }
+};
+
+SVGRendererBase.prototype.hide = function () {
+  this.layerElement.style.display = 'none';
+};
+
+SVGRendererBase.prototype.show = function () {
+  this.layerElement.style.display = 'block';
+};
+
+function ICompElement() {}
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
+
+ICompElement.prototype.initElement = function (data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initTransform(data, globalData, comp);
+  this.initRenderable();
+  this.initHierarchy();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  if (this.data.xt || !globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+  this.hide();
+};
+
+/* ICompElement.prototype.hide = function(){
+    if(!this.hidden){
+        this.hideElement();
+        var i,len = this.elements.length;
+        for( i = 0; i < len; i+=1 ){
+            if(this.elements[i]){
+                this.elements[i].hide();
+            }
+        }
+    }
+}; */
+
+ICompElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+  if (!this.isInRange && !this.data.xt) {
+    return;
+  }
+
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    if (timeRemapped === this.data.op) {
+      timeRemapped = this.data.op - 1;
+    }
+    this.renderedFrame = timeRemapped;
+  } else {
+    this.renderedFrame = num / this.data.sr;
+  }
+  var i;
+  var len = this.elements.length;
+  if (!this.completeLayers) {
+    this.checkLayers(this.renderedFrame);
+  }
+  // This iteration needs to be backwards because of how expressions connect between each other
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
+      if (this.elements[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+ICompElement.prototype.renderInnerContent = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+ICompElement.prototype.setElements = function (elems) {
+  this.elements = elems;
+};
+
+ICompElement.prototype.getElements = function () {
+  return this.elements;
+};
+
+ICompElement.prototype.destroyElements = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+};
+
+ICompElement.prototype.destroy = function () {
+  this.destroyElements();
+  this.destroyBaseElement();
+};
+
+function SVGCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = true;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
+
+SVGCompElement.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function SVGRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.layers = null;
+  this.renderedFrame = -1;
+  this.svgElement = createNS('svg');
+  var ariaLabel = '';
+  if (config && config.title) {
+    var titleElement = createNS('title');
+    var titleId = createElementID();
+    titleElement.setAttribute('id', titleId);
+    titleElement.textContent = config.title;
+    this.svgElement.appendChild(titleElement);
+    ariaLabel += titleId;
+  }
+  if (config && config.description) {
+    var descElement = createNS('desc');
+    var descId = createElementID();
+    descElement.setAttribute('id', descId);
+    descElement.textContent = config.description;
+    this.svgElement.appendChild(descElement);
+    ariaLabel += ' ' + descId;
+  }
+  if (ariaLabel) {
+    this.svgElement.setAttribute('aria-labelledby', ariaLabel);
+  }
+  var defs = createNS('defs');
+  this.svgElement.appendChild(defs);
+  var maskElement = createNS('g');
+  this.svgElement.appendChild(maskElement);
+  this.layerElement = maskElement;
+  this.renderConfig = {
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    hideOnTransparent: !((config && config.hideOnTransparent === false)),
+    viewBoxOnly: (config && config.viewBoxOnly) || false,
+    viewBoxSize: (config && config.viewBoxSize) || false,
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    focusable: config && config.focusable,
+    filterSize: {
+      width: (config && config.filterSize && config.filterSize.width) || '100%',
+      height: (config && config.filterSize && config.filterSize.height) || '100%',
+      x: (config && config.filterSize && config.filterSize.x) || '0%',
+      y: (config && config.filterSize && config.filterSize.y) || '0%',
+    },
+    width: (config && config.width),
+    height: (config && config.height),
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+
+  this.globalData = {
+    _mdf: false,
+    frameNum: -1,
+    defs: defs,
+    renderConfig: this.renderConfig,
+  };
+  this.elements = [];
+  this.pendingElements = [];
+  this.destroyed = false;
+  this.rendererType = 'svg';
+}
+
+extendPrototype([SVGRendererBase], SVGRenderer);
+
+SVGRenderer.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function ShapeTransformManager() {
+  this.sequences = {};
+  this.sequenceList = [];
+  this.transform_key_count = 0;
+}
+
+ShapeTransformManager.prototype = {
+  addTransformSequence: function (transforms) {
+    var i;
+    var len = transforms.length;
+    var key = '_';
+    for (i = 0; i < len; i += 1) {
+      key += transforms[i].transform.key + '_';
+    }
+    var sequence = this.sequences[key];
+    if (!sequence) {
+      sequence = {
+        transforms: [].concat(transforms),
+        finalTransform: new Matrix(),
+        _mdf: false,
+      };
+      this.sequences[key] = sequence;
+      this.sequenceList.push(sequence);
+    }
+    return sequence;
+  },
+  processSequence: function (sequence, isFirstFrame) {
+    var i = 0;
+    var len = sequence.transforms.length;
+    var _mdf = isFirstFrame;
+    while (i < len && !isFirstFrame) {
+      if (sequence.transforms[i].transform.mProps._mdf) {
+        _mdf = true;
+        break;
+      }
+      i += 1;
+    }
+    if (_mdf) {
+      sequence.finalTransform.reset();
+      for (i = len - 1; i >= 0; i -= 1) {
+        sequence.finalTransform.multiply(sequence.transforms[i].transform.mProps.v);
+      }
+    }
+    sequence._mdf = _mdf;
+  },
+  processSequences: function (isFirstFrame) {
+    var i;
+    var len = this.sequenceList.length;
+    for (i = 0; i < len; i += 1) {
+      this.processSequence(this.sequenceList[i], isFirstFrame);
+    }
+  },
+  getNewKey: function () {
+    this.transform_key_count += 1;
+    return '_' + this.transform_key_count;
+  },
+};
+
+var lumaLoader = (function () {
+  var id = '__lottie_element_luma_buffer';
+  var lumaBuffer = null;
+  var lumaBufferCtx = null;
+  var svg = null;
+
+  // This alternate solution has a slight delay before the filter is applied, resulting in a flicker on the first frame.
+  // Keeping this here for reference, and in the future, if offscreen canvas supports url filters, this can be used.
+  // For now, neither of them work for offscreen canvas, so canvas workers can't support the luma track matte mask.
+  // Naming it solution 2 to mark the extra comment lines.
+  /*
+  var svgString = [
+    '<svg xmlns="http://www.w3.org/2000/svg">',
+    '<filter id="' + id + '">',
+    '<feColorMatrix type="matrix" color-interpolation-filters="sRGB" values="',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0, ',
+    '0.3, 0.3, 0.3, 0, 0',
+    '"/>',
+    '</filter>',
+    '</svg>',
+  ].join('');
+  var blob = new Blob([svgString], { type: 'image/svg+xml' });
+  var url = URL.createObjectURL(blob);
+  */
+
+  function createLumaSvgFilter() {
+    var _svg = createNS('svg');
+    var fil = createNS('filter');
+    var matrix = createNS('feColorMatrix');
+    fil.setAttribute('id', id);
+    matrix.setAttribute('type', 'matrix');
+    matrix.setAttribute('color-interpolation-filters', 'sRGB');
+    matrix.setAttribute('values', '0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0');
+    fil.appendChild(matrix);
+    _svg.appendChild(fil);
+    _svg.setAttribute('id', id + '_svg');
+    if (featureSupport.svgLumaHidden) {
+      _svg.style.display = 'none';
+    }
+    return _svg;
+  }
+
+  function loadLuma() {
+    if (!lumaBuffer) {
+      svg = createLumaSvgFilter();
+      document.body.appendChild(svg);
+      lumaBuffer = createTag('canvas');
+      lumaBufferCtx = lumaBuffer.getContext('2d');
+      // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
+      lumaBufferCtx.filter = 'url(#' + id + ')';
+      lumaBufferCtx.fillStyle = 'rgba(0,0,0,0)';
+      lumaBufferCtx.fillRect(0, 0, 1, 1);
+    }
+  }
+
+  function getLuma(canvas) {
+    if (!lumaBuffer) {
+      loadLuma();
+    }
+    lumaBuffer.width = canvas.width;
+    lumaBuffer.height = canvas.height;
+    // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
+    lumaBufferCtx.filter = 'url(#' + id + ')';
+    return lumaBuffer;
+  }
+  return {
+    load: loadLuma,
+    get: getLuma,
+  };
+});
+
+function createCanvas(width, height) {
+  if (featureSupport.offscreenCanvas) {
+    return new OffscreenCanvas(width, height);
+  }
+  var canvas = createTag('canvas');
+  canvas.width = width;
+  canvas.height = height;
+  return canvas;
+}
+
+const assetLoader = (function () {
+  return {
+    loadLumaCanvas: lumaLoader.load,
+    getLumaCanvas: lumaLoader.get,
+    createCanvas: createCanvas,
+  };
+}());
+
+var registeredEffects = {};
+
+function CVEffects(elem) {
+  var i;
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects[type]) {
+      var Effect = registeredEffects[type].effect;
+      filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+CVEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+CVEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect(id, effect) {
+  registeredEffects[id] = {
+    effect,
+  };
+}
+
+function CVMaskElement(data, element) {
+  this.data = data;
+  this.element = element;
+  this.masksProperties = this.data.masksProperties || [];
+  this.viewData = createSizedArray(this.masksProperties.length);
+  var i;
+  var len = this.masksProperties.length;
+  var hasMasks = false;
+  for (i = 0; i < len; i += 1) {
+    if (this.masksProperties[i].mode !== 'n') {
+      hasMasks = true;
+    }
+    this.viewData[i] = ShapePropertyFactory.getShapeProp(this.element, this.masksProperties[i], 3);
+  }
+  this.hasMasks = hasMasks;
+  if (hasMasks) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+CVMaskElement.prototype.renderFrame = function () {
+  if (!this.hasMasks) {
+    return;
+  }
+  var transform = this.element.finalTransform.mat;
+  var ctx = this.element.canvasContext;
+  var i;
+  var len = this.masksProperties.length;
+  var pt;
+  var pts;
+  var data;
+  ctx.beginPath();
+  for (i = 0; i < len; i += 1) {
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.masksProperties[i].inv) {
+        ctx.moveTo(0, 0);
+        ctx.lineTo(this.element.globalData.compSize.w, 0);
+        ctx.lineTo(this.element.globalData.compSize.w, this.element.globalData.compSize.h);
+        ctx.lineTo(0, this.element.globalData.compSize.h);
+        ctx.lineTo(0, 0);
+      }
+      data = this.viewData[i].v;
+      pt = transform.applyToPointArray(data.v[0][0], data.v[0][1], 0);
+      ctx.moveTo(pt[0], pt[1]);
+      var j;
+      var jLen = data._length;
+      for (j = 1; j < jLen; j += 1) {
+        pts = transform.applyToTriplePoints(data.o[j - 1], data.i[j], data.v[j]);
+        ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
+      }
+      pts = transform.applyToTriplePoints(data.o[j - 1], data.i[0], data.v[0]);
+      ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
+    }
+  }
+  this.element.globalData.renderer.save(true);
+  ctx.clip();
+};
+
+CVMaskElement.prototype.getMaskProperty = MaskElement.prototype.getMaskProperty;
+
+CVMaskElement.prototype.destroy = function () {
+  this.element = null;
+};
+
+function CVBaseElement() {
+}
+
+var operationsMap = {
+  1: 'source-in',
+  2: 'source-out',
+  3: 'source-in',
+  4: 'source-out',
+};
+
+CVBaseElement.prototype = {
+  createElements: function () {},
+  initRendererElement: function () {},
+  createContainerElements: function () {
+    // If the layer is masked we will use two buffers to store each different states of the drawing
+    // This solution is not ideal for several reason. But unfortunately, because of the recursive
+    // nature of the render tree, it's the only simple way to make sure one inner mask doesn't override an outer mask.
+    // TODO: try to reduce the size of these buffers to the size of the composition contaning the layer
+    // It might be challenging because the layer most likely is transformed in some way
+    if (this.data.tt >= 1) {
+      this.buffers = [];
+      var canvasContext = this.globalData.canvasContext;
+      var bufferCanvas = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
+      this.buffers.push(bufferCanvas);
+      var bufferCanvas2 = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
+      this.buffers.push(bufferCanvas2);
+      if (this.data.tt >= 3 && !document._isProxy) {
+        assetLoader.loadLumaCanvas();
+      }
+    }
+    this.canvasContext = this.globalData.canvasContext;
+    this.transformCanvas = this.globalData.transformCanvas;
+    this.renderableEffectsManager = new CVEffects(this);
+    this.searchEffectTransforms();
+  },
+  createContent: function () {},
+  setBlendMode: function () {
+    var globalData = this.globalData;
+    if (globalData.blendMode !== this.data.bm) {
+      globalData.blendMode = this.data.bm;
+      var blendModeValue = getBlendMode(this.data.bm);
+      globalData.canvasContext.globalCompositeOperation = blendModeValue;
+    }
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new CVMaskElement(this.data, this);
+    this.transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+  },
+  hideElement: function () {
+    if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+      this.hidden = true;
+    }
+  },
+  showElement: function () {
+    if (this.isInRange && !this.isTransparent) {
+      this.hidden = false;
+      this._isFirstFrame = true;
+      this.maskManager._isFirstFrame = true;
+    }
+  },
+  clearCanvas: function (canvasContext) {
+    canvasContext.clearRect(
+      this.transformCanvas.tx,
+      this.transformCanvas.ty,
+      this.transformCanvas.w * this.transformCanvas.sx,
+      this.transformCanvas.h * this.transformCanvas.sy
+    );
+  },
+  prepareLayer: function () {
+    if (this.data.tt >= 1) {
+      var buffer = this.buffers[0];
+      var bufferCtx = buffer.getContext('2d');
+      this.clearCanvas(bufferCtx);
+      // on the first buffer we store the current state of the global drawing
+      bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+      // The next four lines are to clear the canvas
+      // TODO: Check if there is a way to clear the canvas without resetting the transform
+      this.currentTransform = this.canvasContext.getTransform();
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+      this.clearCanvas(this.canvasContext);
+      this.canvasContext.setTransform(this.currentTransform);
+    }
+  },
+  exitLayer: function () {
+    if (this.data.tt >= 1) {
+      var buffer = this.buffers[1];
+      // On the second buffer we store the current state of the global drawing
+      // that only contains the content of this layer
+      // (if it is a composition, it also includes the nested layers)
+      var bufferCtx = buffer.getContext('2d');
+      this.clearCanvas(bufferCtx);
+      bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+      // We clear the canvas again
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+      this.clearCanvas(this.canvasContext);
+      this.canvasContext.setTransform(this.currentTransform);
+      // We draw the mask
+      const mask = this.comp.getElementById('tp' in this.data ? this.data.tp : this.data.ind - 1);
+      mask.renderFrame(true);
+      // We draw the second buffer (that contains the content of this layer)
+      this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
+
+      // If the mask is a Luma matte, we need to do two extra painting operations
+      // the _isProxy check is to avoid drawing a fake canvas in workers that will throw an error
+      if (this.data.tt >= 3 && !document._isProxy) {
+        // We copy the painted mask to a buffer that has a color matrix filter applied to it
+        // that applies the rgb values to the alpha channel
+        var lumaBuffer = assetLoader.getLumaCanvas(this.canvasContext.canvas);
+        var lumaBufferCtx = lumaBuffer.getContext('2d');
+        lumaBufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+        this.clearCanvas(this.canvasContext);
+        // we repaint the context with the mask applied to it
+        this.canvasContext.drawImage(lumaBuffer, 0, 0);
+      }
+      this.canvasContext.globalCompositeOperation = operationsMap[this.data.tt];
+      this.canvasContext.drawImage(buffer, 0, 0);
+      // We finally draw the first buffer (that contains the content of the global drawing)
+      // We use destination-over to draw the global drawing below the current layer
+      this.canvasContext.globalCompositeOperation = 'destination-over';
+      this.canvasContext.drawImage(this.buffers[0], 0, 0);
+      this.canvasContext.setTransform(this.currentTransform);
+      // We reset the globalCompositeOperation to source-over, the standard type of operation
+      this.canvasContext.globalCompositeOperation = 'source-over';
+    }
+  },
+  renderFrame: function (forceRender) {
+    if (this.hidden || this.data.hd) {
+      return;
+    }
+    if (this.data.td === 1 && !forceRender) {
+      return;
+    }
+    this.renderTransform();
+    this.renderRenderable();
+    this.renderLocalTransform();
+    this.setBlendMode();
+    var forceRealStack = this.data.ty === 0;
+    this.prepareLayer();
+    this.globalData.renderer.save(forceRealStack);
+    this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props);
+    this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity);
+    this.renderInnerContent();
+    this.globalData.renderer.restore(forceRealStack);
+    this.exitLayer();
+    if (this.maskManager.hasMasks) {
+      this.globalData.renderer.restore(true);
+    }
+    if (this._isFirstFrame) {
+      this._isFirstFrame = false;
+    }
+  },
+  destroy: function () {
+    this.canvasContext = null;
+    this.data = null;
+    this.globalData = null;
+    this.maskManager.destroy();
+  },
+  mHelper: new Matrix(),
+};
+CVBaseElement.prototype.hide = CVBaseElement.prototype.hideElement;
+CVBaseElement.prototype.show = CVBaseElement.prototype.showElement;
+
+function CVShapeData(element, data, styles, transformsManager) {
+  this.styledShapes = [];
+  this.tr = [0, 0, 0, 0, 0, 0];
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  this.sh = ShapePropertyFactory.getShapeProp(element, data, ty, element);
+  var i;
+  var len = styles.length;
+  var styledShape;
+  for (i = 0; i < len; i += 1) {
+    if (!styles[i].closed) {
+      styledShape = {
+        transforms: transformsManager.addTransformSequence(styles[i].transforms),
+        trNodes: [],
+      };
+      this.styledShapes.push(styledShape);
+      styles[i].elements.push(styledShape);
+    }
+  }
+}
+
+CVShapeData.prototype.setAsAnimated = SVGShapeData.prototype.setAsAnimated;
+
+function CVShapeElement(data, globalData, comp) {
+  this.shapes = [];
+  this.shapesData = data.shapes;
+  this.stylesList = [];
+  this.itemsData = [];
+  this.prevViewData = [];
+  this.shapeModifiers = [];
+  this.processedElements = [];
+  this.transformsManager = new ShapeTransformManager();
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, CVBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableElement], CVShapeElement);
+
+CVShapeElement.prototype.initElement = RenderableDOMElement.prototype.initElement;
+
+CVShapeElement.prototype.transformHelper = { opacity: 1, _opMdf: false };
+
+CVShapeElement.prototype.dashResetter = [];
+
+CVShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
+};
+
+CVShapeElement.prototype.createStyleElement = function (data, transforms) {
+  var styleElem = {
+    data: data,
+    type: data.ty,
+    preTransforms: this.transformsManager.addTransformSequence(transforms),
+    transforms: [],
+    elements: [],
+    closed: data.hd === true,
+  };
+  var elementData = {};
+  if (data.ty === 'fl' || data.ty === 'st') {
+    elementData.c = PropertyFactory.getProp(this, data.c, 1, 255, this);
+    if (!elementData.c.k) {
+      styleElem.co = 'rgb(' + bmFloor(elementData.c.v[0]) + ',' + bmFloor(elementData.c.v[1]) + ',' + bmFloor(elementData.c.v[2]) + ')';
+    }
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    elementData.s = PropertyFactory.getProp(this, data.s, 1, null, this);
+    elementData.e = PropertyFactory.getProp(this, data.e, 1, null, this);
+    elementData.h = PropertyFactory.getProp(this, data.h || { k: 0 }, 0, 0.01, this);
+    elementData.a = PropertyFactory.getProp(this, data.a || { k: 0 }, 0, degToRads, this);
+    elementData.g = new GradientProperty(this, data.g, this);
+  }
+  elementData.o = PropertyFactory.getProp(this, data.o, 0, 0.01, this);
+  if (data.ty === 'st' || data.ty === 'gs') {
+    styleElem.lc = lineCapEnum[data.lc || 2];
+    styleElem.lj = lineJoinEnum[data.lj || 2];
+    if (data.lj == 1) { // eslint-disable-line eqeqeq
+      styleElem.ml = data.ml;
+    }
+    elementData.w = PropertyFactory.getProp(this, data.w, 0, null, this);
+    if (!elementData.w.k) {
+      styleElem.wi = elementData.w.v;
+    }
+    if (data.d) {
+      var d = new DashProperty(this, data.d, 'canvas', this);
+      elementData.d = d;
+      if (!elementData.d.k) {
+        styleElem.da = elementData.d.dashArray;
+        styleElem.do = elementData.d.dashoffset[0];
+      }
+    }
+  } else {
+    styleElem.r = data.r === 2 ? 'evenodd' : 'nonzero';
+  }
+  this.stylesList.push(styleElem);
+  elementData.style = styleElem;
+  return elementData;
+};
+
+CVShapeElement.prototype.createGroupElement = function () {
+  var elementData = {
+    it: [],
+    prevViewData: [],
+  };
+  return elementData;
+};
+
+CVShapeElement.prototype.createTransformElement = function (data) {
+  var elementData = {
+    transform: {
+      opacity: 1,
+      _opMdf: false,
+      key: this.transformsManager.getNewKey(),
+      op: PropertyFactory.getProp(this, data.o, 0, 0.01, this),
+      mProps: TransformPropertyFactory.getTransformProperty(this, data, this),
+    },
+  };
+  return elementData;
+};
+
+CVShapeElement.prototype.createShapeElement = function (data) {
+  var elementData = new CVShapeData(this, data, this.stylesList, this.transformsManager);
+
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  return elementData;
+};
+
+CVShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+  this.transformsManager.processSequences(this._isFirstFrame);
+};
+
+CVShapeElement.prototype.addTransformToStyleList = function (transform) {
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    if (!this.stylesList[i].closed) {
+      this.stylesList[i].transforms.push(transform);
+    }
+  }
+};
+
+CVShapeElement.prototype.removeTransformFromStyleList = function () {
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    if (!this.stylesList[i].closed) {
+      this.stylesList[i].transforms.pop();
+    }
+  }
+};
+
+CVShapeElement.prototype.closeStyles = function (styles) {
+  var i;
+  var len = styles.length;
+  for (i = 0; i < len; i += 1) {
+    styles[i].closed = true;
+  }
+};
+
+CVShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, shouldRender, transforms) {
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var processedPos;
+  var modifier;
+  var currentTransform;
+  var ownTransforms = [].concat(transforms);
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._shouldRender = shouldRender;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], ownTransforms);
+      } else {
+        itemsData[i].style.closed = false;
+      }
+
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, shouldRender, ownTransforms);
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        currentTransform = this.createTransformElement(arr[i]);
+        itemsData[i] = currentTransform;
+      }
+      ownTransforms.push(itemsData[i]);
+      this.addTransformToStyleList(itemsData[i]);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i]);
+      }
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        shouldRender = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  this.removeTransformFromStyleList();
+  this.closeStyles(ownStyles);
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+CVShapeElement.prototype.renderInnerContent = function () {
+  this.transformHelper.opacity = 1;
+  this.transformHelper._opMdf = false;
+  this.renderModifiers();
+  this.transformsManager.processSequences(this._isFirstFrame);
+  this.renderShape(this.transformHelper, this.shapesData, this.itemsData, true);
+};
+
+CVShapeElement.prototype.renderShapeTransform = function (parentTransform, groupTransform) {
+  if (parentTransform._opMdf || groupTransform.op._mdf || this._isFirstFrame) {
+    groupTransform.opacity = parentTransform.opacity;
+    groupTransform.opacity *= groupTransform.op.v;
+    groupTransform._opMdf = true;
+  }
+};
+
+CVShapeElement.prototype.drawLayer = function () {
+  var i;
+  var len = this.stylesList.length;
+  var j;
+  var jLen;
+  var k;
+  var kLen;
+  var elems;
+  var nodes;
+  var renderer = this.globalData.renderer;
+  var ctx = this.globalData.canvasContext;
+  var type;
+  var currentStyle;
+  for (i = 0; i < len; i += 1) {
+    currentStyle = this.stylesList[i];
+    type = currentStyle.type;
+
+    // Skipping style when
+    // Stroke width equals 0
+    // style should not be rendered (extra unused repeaters)
+    // current opacity equals 0
+    // global opacity equals 0
+    if (!(((type === 'st' || type === 'gs') && currentStyle.wi === 0) || !currentStyle.data._shouldRender || currentStyle.coOp === 0 || this.globalData.currentGlobalAlpha === 0)) {
+      renderer.save();
+      elems = currentStyle.elements;
+      if (type === 'st' || type === 'gs') {
+        renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd);
+        // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
+        renderer.ctxLineWidth(currentStyle.wi);
+        // ctx.lineWidth = currentStyle.wi;
+        renderer.ctxLineCap(currentStyle.lc);
+        // ctx.lineCap = currentStyle.lc;
+        renderer.ctxLineJoin(currentStyle.lj);
+        // ctx.lineJoin = currentStyle.lj;
+        renderer.ctxMiterLimit(currentStyle.ml || 0);
+        // ctx.miterLimit = currentStyle.ml || 0;
+      } else {
+        renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd);
+        // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
+      }
+      renderer.ctxOpacity(currentStyle.coOp);
+      if (type !== 'st' && type !== 'gs') {
+        ctx.beginPath();
+      }
+      renderer.ctxTransform(currentStyle.preTransforms.finalTransform.props);
+      jLen = elems.length;
+      for (j = 0; j < jLen; j += 1) {
+        if (type === 'st' || type === 'gs') {
+          ctx.beginPath();
+          if (currentStyle.da) {
+            ctx.setLineDash(currentStyle.da);
+            ctx.lineDashOffset = currentStyle.do;
+          }
+        }
+        nodes = elems[j].trNodes;
+        kLen = nodes.length;
+
+        for (k = 0; k < kLen; k += 1) {
+          if (nodes[k].t === 'm') {
+            ctx.moveTo(nodes[k].p[0], nodes[k].p[1]);
+          } else if (nodes[k].t === 'c') {
+            ctx.bezierCurveTo(nodes[k].pts[0], nodes[k].pts[1], nodes[k].pts[2], nodes[k].pts[3], nodes[k].pts[4], nodes[k].pts[5]);
+          } else {
+            ctx.closePath();
+          }
+        }
+        if (type === 'st' || type === 'gs') {
+          // ctx.stroke();
+          renderer.ctxStroke();
+          if (currentStyle.da) {
+            ctx.setLineDash(this.dashResetter);
+          }
+        }
+      }
+      if (type !== 'st' && type !== 'gs') {
+        // ctx.fill(currentStyle.r);
+        this.globalData.renderer.ctxFill(currentStyle.r);
+      }
+      renderer.restore();
+    }
+  }
+};
+
+CVShapeElement.prototype.renderShape = function (parentTransform, items, data, isMain) {
+  var i;
+  var len = items.length - 1;
+  var groupTransform;
+  groupTransform = parentTransform;
+  for (i = len; i >= 0; i -= 1) {
+    if (items[i].ty === 'tr') {
+      groupTransform = data[i].transform;
+      this.renderShapeTransform(parentTransform, groupTransform);
+    } else if (items[i].ty === 'sh' || items[i].ty === 'el' || items[i].ty === 'rc' || items[i].ty === 'sr') {
+      this.renderPath(items[i], data[i]);
+    } else if (items[i].ty === 'fl') {
+      this.renderFill(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'st') {
+      this.renderStroke(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'gf' || items[i].ty === 'gs') {
+      this.renderGradientFill(items[i], data[i], groupTransform);
+    } else if (items[i].ty === 'gr') {
+      this.renderShape(groupTransform, items[i].it, data[i].it);
+    } else if (items[i].ty === 'tm') {
+      //
+    }
+  }
+  if (isMain) {
+    this.drawLayer();
+  }
+};
+
+CVShapeElement.prototype.renderStyledShape = function (styledShape, shape) {
+  if (this._isFirstFrame || shape._mdf || styledShape.transforms._mdf) {
+    var shapeNodes = styledShape.trNodes;
+    var paths = shape.paths;
+    var i;
+    var len;
+    var j;
+    var jLen = paths._length;
+    shapeNodes.length = 0;
+    var groupTransformMat = styledShape.transforms.finalTransform;
+    for (j = 0; j < jLen; j += 1) {
+      var pathNodes = paths.shapes[j];
+      if (pathNodes && pathNodes.v) {
+        len = pathNodes._length;
+        for (i = 1; i < len; i += 1) {
+          if (i === 1) {
+            shapeNodes.push({
+              t: 'm',
+              p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0),
+            });
+          }
+          shapeNodes.push({
+            t: 'c',
+            pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[i], pathNodes.v[i]),
+          });
+        }
+        if (len === 1) {
+          shapeNodes.push({
+            t: 'm',
+            p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0),
+          });
+        }
+        if (pathNodes.c && len) {
+          shapeNodes.push({
+            t: 'c',
+            pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[0], pathNodes.v[0]),
+          });
+          shapeNodes.push({
+            t: 'z',
+          });
+        }
+      }
+    }
+    styledShape.trNodes = shapeNodes;
+  }
+};
+
+CVShapeElement.prototype.renderPath = function (pathData, itemData) {
+  if (pathData.hd !== true && pathData._shouldRender) {
+    var i;
+    var len = itemData.styledShapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderStyledShape(itemData.styledShapes[i], itemData.sh);
+    }
+  }
+};
+
+CVShapeElement.prototype.renderFill = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+
+  if (itemData.c._mdf || this._isFirstFrame) {
+    styleElem.co = 'rgb('
+        + bmFloor(itemData.c.v[0]) + ','
+        + bmFloor(itemData.c.v[1]) + ','
+        + bmFloor(itemData.c.v[2]) + ')';
+  }
+  if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
+    styleElem.coOp = itemData.o.v * groupTransform.opacity;
+  }
+};
+
+CVShapeElement.prototype.renderGradientFill = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+  var grd;
+  if (!styleElem.grd || itemData.g._mdf || itemData.s._mdf || itemData.e._mdf || (styleData.t !== 1 && (itemData.h._mdf || itemData.a._mdf))) {
+    var ctx = this.globalData.canvasContext;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+    if (styleData.t === 1) {
+      grd = ctx.createLinearGradient(pt1[0], pt1[1], pt2[0], pt2[1]);
+    } else {
+      var rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+      var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+      var percent = itemData.h.v;
+      if (percent >= 1) {
+        percent = 0.99;
+      } else if (percent <= -1) {
+        percent = -0.99;
+      }
+      var dist = rad * percent;
+      var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+      var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+      grd = ctx.createRadialGradient(x, y, 0, pt1[0], pt1[1], rad);
+    }
+
+    var i;
+    var len = styleData.g.p;
+    var cValues = itemData.g.c;
+    var opacity = 1;
+
+    for (i = 0; i < len; i += 1) {
+      if (itemData.g._hasOpacity && itemData.g._collapsable) {
+        opacity = itemData.g.o[i * 2 + 1];
+      }
+      grd.addColorStop(cValues[i * 4] / 100, 'rgba(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ',' + opacity + ')');
+    }
+    styleElem.grd = grd;
+  }
+  styleElem.coOp = itemData.o.v * groupTransform.opacity;
+};
+
+CVShapeElement.prototype.renderStroke = function (styleData, itemData, groupTransform) {
+  var styleElem = itemData.style;
+  var d = itemData.d;
+  if (d && (d._mdf || this._isFirstFrame)) {
+    styleElem.da = d.dashArray;
+    styleElem.do = d.dashoffset[0];
+  }
+  if (itemData.c._mdf || this._isFirstFrame) {
+    styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
+  }
+  if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
+    styleElem.coOp = itemData.o.v * groupTransform.opacity;
+  }
+  if (itemData.w._mdf || this._isFirstFrame) {
+    styleElem.wi = itemData.w.v;
+  }
+};
+
+CVShapeElement.prototype.destroy = function () {
+  this.shapesData = null;
+  this.globalData = null;
+  this.canvasContext = null;
+  this.stylesList.length = 0;
+  this.itemsData.length = 0;
+};
+
+function CVTextElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.yOffset = 0;
+  this.fillColorAnim = false;
+  this.strokeColorAnim = false;
+  this.strokeWidthAnim = false;
+  this.stroke = false;
+  this.fill = false;
+  this.justifyOffset = 0;
+  this.currentRender = null;
+  this.renderType = 'canvas';
+  this.values = {
+    fill: 'rgba(0,0,0,0)',
+    stroke: 'rgba(0,0,0,0)',
+    sWidth: 0,
+    fValue: '',
+  };
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement, ITextElement], CVTextElement);
+
+CVTextElement.prototype.tHelper = createTag('canvas').getContext('2d');
+
+CVTextElement.prototype.buildNewText = function () {
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
+
+  var hasFill = false;
+  if (documentData.fc) {
+    hasFill = true;
+    this.values.fill = this.buildColor(documentData.fc);
+  } else {
+    this.values.fill = 'rgba(0,0,0,0)';
+  }
+  this.fill = hasFill;
+  var hasStroke = false;
+  if (documentData.sc) {
+    hasStroke = true;
+    this.values.stroke = this.buildColor(documentData.sc);
+    this.values.sWidth = documentData.sw;
+  }
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  var i;
+  var len;
+  var letters = documentData.l;
+  var matrixHelper = this.mHelper;
+  this.stroke = hasStroke;
+  this.values.fValue = documentData.finalSize + 'px ' + this.globalData.fontManager.getFontByName(documentData.f).fFamily;
+  len = documentData.finalText.length;
+  // this.tHelper.font = this.values.fValue;
+  var charData;
+  var shapeData;
+  var k;
+  var kLen;
+  var shapes;
+  var j;
+  var jLen;
+  var pathNodes;
+  var commands;
+  var pathArr;
+  var singleShape = this.data.singleShape;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var cnt = 0;
+  for (i = 0; i < len; i += 1) {
+    charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
+    shapeData = (charData && charData.data) || {};
+    matrixHelper.reset();
+    if (singleShape && letters[i].n) {
+      xPos = -trackingOffset;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      firstLine = false;
+    }
+    shapes = shapeData.shapes ? shapeData.shapes[0].it : [];
+    jLen = shapes.length;
+    matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
+    if (singleShape) {
+      this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+    }
+    commands = createSizedArray(jLen - 1);
+    var commandsCounter = 0;
+    for (j = 0; j < jLen; j += 1) {
+      if (shapes[j].ty === 'sh') {
+        kLen = shapes[j].ks.k.i.length;
+        pathNodes = shapes[j].ks.k;
+        pathArr = [];
+        for (k = 1; k < kLen; k += 1) {
+          if (k === 1) {
+            pathArr.push(matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
+          }
+          pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToY(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToX(pathNodes.v[k][0], pathNodes.v[k][1], 0), matrixHelper.applyToY(pathNodes.v[k][0], pathNodes.v[k][1], 0));
+        }
+        pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToY(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
+        commands[commandsCounter] = pathArr;
+        commandsCounter += 1;
+      }
+    }
+    if (singleShape) {
+      xPos += letters[i].l;
+      xPos += trackingOffset;
+    }
+    if (this.textSpans[cnt]) {
+      this.textSpans[cnt].elem = commands;
+    } else {
+      this.textSpans[cnt] = { elem: commands };
+    }
+    cnt += 1;
+  }
+};
+
+CVTextElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  var ctx = this.canvasContext;
+  ctx.font = this.values.fValue;
+  this.globalData.renderer.ctxLineCap('butt');
+  // ctx.lineCap = 'butt';
+  this.globalData.renderer.ctxLineJoin('miter');
+  // ctx.lineJoin = 'miter';
+  this.globalData.renderer.ctxMiterLimit(4);
+  // ctx.miterLimit = 4;
+
+  if (!this.data.singleShape) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+  }
+
+  var i;
+  var len;
+  var j;
+  var jLen;
+  var k;
+  var kLen;
+  var renderedLetters = this.textAnimator.renderedLetters;
+
+  var letters = this.textProperty.currentData.l;
+
+  len = letters.length;
+  var renderedLetter;
+  var lastFill = null;
+  var lastStroke = null;
+  var lastStrokeW = null;
+  var commands;
+  var pathArr;
+  var renderer = this.globalData.renderer;
+  for (i = 0; i < len; i += 1) {
+    if (!letters[i].n) {
+      renderedLetter = renderedLetters[i];
+      if (renderedLetter) {
+        renderer.save();
+        renderer.ctxTransform(renderedLetter.p);
+        renderer.ctxOpacity(renderedLetter.o);
+      }
+      if (this.fill) {
+        if (renderedLetter && renderedLetter.fc) {
+          if (lastFill !== renderedLetter.fc) {
+            renderer.ctxFillStyle(renderedLetter.fc);
+            lastFill = renderedLetter.fc;
+            // ctx.fillStyle = renderedLetter.fc;
+          }
+        } else if (lastFill !== this.values.fill) {
+          lastFill = this.values.fill;
+          renderer.ctxFillStyle(this.values.fill);
+          // ctx.fillStyle = this.values.fill;
+        }
+        commands = this.textSpans[i].elem;
+        jLen = commands.length;
+        this.globalData.canvasContext.beginPath();
+        for (j = 0; j < jLen; j += 1) {
+          pathArr = commands[j];
+          kLen = pathArr.length;
+          this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
+          for (k = 2; k < kLen; k += 6) {
+            this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
+          }
+        }
+        this.globalData.canvasContext.closePath();
+        renderer.ctxFill();
+        // this.globalData.canvasContext.fill();
+        /// ctx.fillText(this.textSpans[i].val,0,0);
+      }
+      if (this.stroke) {
+        if (renderedLetter && renderedLetter.sw) {
+          if (lastStrokeW !== renderedLetter.sw) {
+            lastStrokeW = renderedLetter.sw;
+            renderer.ctxLineWidth(renderedLetter.sw);
+            // ctx.lineWidth = renderedLetter.sw;
+          }
+        } else if (lastStrokeW !== this.values.sWidth) {
+          lastStrokeW = this.values.sWidth;
+          renderer.ctxLineWidth(this.values.sWidth);
+          // ctx.lineWidth = this.values.sWidth;
+        }
+        if (renderedLetter && renderedLetter.sc) {
+          if (lastStroke !== renderedLetter.sc) {
+            lastStroke = renderedLetter.sc;
+            renderer.ctxStrokeStyle(renderedLetter.sc);
+            // ctx.strokeStyle = renderedLetter.sc;
+          }
+        } else if (lastStroke !== this.values.stroke) {
+          lastStroke = this.values.stroke;
+          renderer.ctxStrokeStyle(this.values.stroke);
+          // ctx.strokeStyle = this.values.stroke;
+        }
+        commands = this.textSpans[i].elem;
+        jLen = commands.length;
+        this.globalData.canvasContext.beginPath();
+        for (j = 0; j < jLen; j += 1) {
+          pathArr = commands[j];
+          kLen = pathArr.length;
+          this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
+          for (k = 2; k < kLen; k += 6) {
+            this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
+          }
+        }
+        this.globalData.canvasContext.closePath();
+        renderer.ctxStroke();
+        // this.globalData.canvasContext.stroke();
+        /// ctx.strokeText(letters[i].val,0,0);
+      }
+      if (renderedLetter) {
+        this.globalData.renderer.restore();
+      }
+    }
+  }
+};
+
+function CVImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  this.img = globalData.imageLoader.getAsset(this.assetData);
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVImageElement);
+
+CVImageElement.prototype.initElement = SVGShapeElement.prototype.initElement;
+CVImageElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
+
+CVImageElement.prototype.createContent = function () {
+  if (this.img.width && (this.assetData.w !== this.img.width || this.assetData.h !== this.img.height)) {
+    var canvas = createTag('canvas');
+    canvas.width = this.assetData.w;
+    canvas.height = this.assetData.h;
+    var ctx = canvas.getContext('2d');
+
+    var imgW = this.img.width;
+    var imgH = this.img.height;
+    var imgRel = imgW / imgH;
+    var canvasRel = this.assetData.w / this.assetData.h;
+    var widthCrop;
+    var heightCrop;
+    var par = this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio;
+    if ((imgRel > canvasRel && par === 'xMidYMid slice') || (imgRel < canvasRel && par !== 'xMidYMid slice')) {
+      heightCrop = imgH;
+      widthCrop = heightCrop * canvasRel;
+    } else {
+      widthCrop = imgW;
+      heightCrop = widthCrop / canvasRel;
+    }
+    ctx.drawImage(this.img, (imgW - widthCrop) / 2, (imgH - heightCrop) / 2, widthCrop, heightCrop, 0, 0, this.assetData.w, this.assetData.h);
+    this.img = canvas;
+  }
+};
+
+CVImageElement.prototype.renderInnerContent = function () {
+  this.canvasContext.drawImage(this.img, 0, 0);
+};
+
+CVImageElement.prototype.destroy = function () {
+  this.img = null;
+};
+
+function CVSolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVSolidElement);
+
+CVSolidElement.prototype.initElement = SVGShapeElement.prototype.initElement;
+CVSolidElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
+
+CVSolidElement.prototype.renderInnerContent = function () {
+  // var ctx = this.canvasContext;
+  this.globalData.renderer.ctxFillStyle(this.data.sc);
+  // ctx.fillStyle = this.data.sc;
+  this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh);
+  // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
+  //
+};
+
+function CanvasRendererBase() {
+}
+extendPrototype([BaseRenderer], CanvasRendererBase);
+
+CanvasRendererBase.prototype.createShape = function (data) {
+  return new CVShapeElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createText = function (data) {
+  return new CVTextElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createImage = function (data) {
+  return new CVImageElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createSolid = function (data) {
+  return new CVSolidElement(data, this.globalData, this);
+};
+
+CanvasRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
+
+CanvasRendererBase.prototype.ctxTransform = function (props) {
+  if (props[0] === 1 && props[1] === 0 && props[4] === 0 && props[5] === 1 && props[12] === 0 && props[13] === 0) {
+    return;
+  }
+  this.canvasContext.transform(props[0], props[1], props[4], props[5], props[12], props[13]);
+};
+
+CanvasRendererBase.prototype.ctxOpacity = function (op) {
+  this.canvasContext.globalAlpha *= op < 0 ? 0 : op;
+};
+
+CanvasRendererBase.prototype.ctxFillStyle = function (value) {
+  this.canvasContext.fillStyle = value;
+};
+
+CanvasRendererBase.prototype.ctxStrokeStyle = function (value) {
+  this.canvasContext.strokeStyle = value;
+};
+
+CanvasRendererBase.prototype.ctxLineWidth = function (value) {
+  this.canvasContext.lineWidth = value;
+};
+
+CanvasRendererBase.prototype.ctxLineCap = function (value) {
+  this.canvasContext.lineCap = value;
+};
+
+CanvasRendererBase.prototype.ctxLineJoin = function (value) {
+  this.canvasContext.lineJoin = value;
+};
+
+CanvasRendererBase.prototype.ctxMiterLimit = function (value) {
+  this.canvasContext.miterLimit = value;
+};
+
+CanvasRendererBase.prototype.ctxFill = function (rule) {
+  this.canvasContext.fill(rule);
+};
+
+CanvasRendererBase.prototype.ctxFillRect = function (x, y, w, h) {
+  this.canvasContext.fillRect(x, y, w, h);
+};
+
+CanvasRendererBase.prototype.ctxStroke = function () {
+  this.canvasContext.stroke();
+};
+
+CanvasRendererBase.prototype.reset = function () {
+  if (!this.renderConfig.clearCanvas) {
+    this.canvasContext.restore();
+    return;
+  }
+  this.contextData.reset();
+};
+
+CanvasRendererBase.prototype.save = function () {
+  this.canvasContext.save();
+};
+
+CanvasRendererBase.prototype.restore = function (actionFlag) {
+  if (!this.renderConfig.clearCanvas) {
+    this.canvasContext.restore();
+    return;
+  }
+  if (actionFlag) {
+    this.globalData.blendMode = 'source-over';
+  }
+  this.contextData.restore(actionFlag);
+};
+
+CanvasRendererBase.prototype.configAnimation = function (animData) {
+  if (this.animationItem.wrapper) {
+    this.animationItem.container = createTag('canvas');
+    var containerStyle = this.animationItem.container.style;
+    containerStyle.width = '100%';
+    containerStyle.height = '100%';
+    var origin = '0px 0px 0px';
+    containerStyle.transformOrigin = origin;
+    containerStyle.mozTransformOrigin = origin;
+    containerStyle.webkitTransformOrigin = origin;
+    containerStyle['-webkit-transform'] = origin;
+    containerStyle.contentVisibility = this.renderConfig.contentVisibility;
+    this.animationItem.wrapper.appendChild(this.animationItem.container);
+    this.canvasContext = this.animationItem.container.getContext('2d');
+    if (this.renderConfig.className) {
+      this.animationItem.container.setAttribute('class', this.renderConfig.className);
+    }
+    if (this.renderConfig.id) {
+      this.animationItem.container.setAttribute('id', this.renderConfig.id);
+    }
+  } else {
+    this.canvasContext = this.renderConfig.context;
+  }
+  this.contextData.setContext(this.canvasContext);
+  this.data = animData;
+  this.layers = animData.layers;
+  this.transformCanvas = {
+    w: animData.w,
+    h: animData.h,
+    sx: 0,
+    sy: 0,
+    tx: 0,
+    ty: 0,
+  };
+  this.setupGlobalData(animData, document.body);
+  this.globalData.canvasContext = this.canvasContext;
+  this.globalData.renderer = this;
+  this.globalData.isDashed = false;
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.globalData.transformCanvas = this.transformCanvas;
+  this.elements = createSizedArray(animData.layers.length);
+
+  this.updateContainerSize();
+};
+
+CanvasRendererBase.prototype.updateContainerSize = function (width, height) {
+  this.reset();
+  var elementWidth;
+  var elementHeight;
+  if (width) {
+    elementWidth = width;
+    elementHeight = height;
+    this.canvasContext.canvas.width = elementWidth;
+    this.canvasContext.canvas.height = elementHeight;
+  } else {
+    if (this.animationItem.wrapper && this.animationItem.container) {
+      elementWidth = this.animationItem.wrapper.offsetWidth;
+      elementHeight = this.animationItem.wrapper.offsetHeight;
+    } else {
+      elementWidth = this.canvasContext.canvas.width;
+      elementHeight = this.canvasContext.canvas.height;
+    }
+    this.canvasContext.canvas.width = elementWidth * this.renderConfig.dpr;
+    this.canvasContext.canvas.height = elementHeight * this.renderConfig.dpr;
+  }
+
+  var elementRel;
+  var animationRel;
+  if (this.renderConfig.preserveAspectRatio.indexOf('meet') !== -1 || this.renderConfig.preserveAspectRatio.indexOf('slice') !== -1) {
+    var par = this.renderConfig.preserveAspectRatio.split(' ');
+    var fillType = par[1] || 'meet';
+    var pos = par[0] || 'xMidYMid';
+    var xPos = pos.substr(0, 4);
+    var yPos = pos.substr(4);
+    elementRel = elementWidth / elementHeight;
+    animationRel = this.transformCanvas.w / this.transformCanvas.h;
+    if ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice')) {
+      this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+      this.transformCanvas.sy = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+    } else {
+      this.transformCanvas.sx = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+      this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+    }
+
+    if (xPos === 'xMid' && ((animationRel < elementRel && fillType === 'meet') || (animationRel > elementRel && fillType === 'slice'))) {
+      this.transformCanvas.tx = ((elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) / 2) * this.renderConfig.dpr;
+    } else if (xPos === 'xMax' && ((animationRel < elementRel && fillType === 'meet') || (animationRel > elementRel && fillType === 'slice'))) {
+      this.transformCanvas.tx = (elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) * this.renderConfig.dpr;
+    } else {
+      this.transformCanvas.tx = 0;
+    }
+    if (yPos === 'YMid' && ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice'))) {
+      this.transformCanvas.ty = ((elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w)) / 2) * this.renderConfig.dpr;
+    } else if (yPos === 'YMax' && ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice'))) {
+      this.transformCanvas.ty = ((elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w))) * this.renderConfig.dpr;
+    } else {
+      this.transformCanvas.ty = 0;
+    }
+  } else if (this.renderConfig.preserveAspectRatio === 'none') {
+    this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
+    this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
+    this.transformCanvas.tx = 0;
+    this.transformCanvas.ty = 0;
+  } else {
+    this.transformCanvas.sx = this.renderConfig.dpr;
+    this.transformCanvas.sy = this.renderConfig.dpr;
+    this.transformCanvas.tx = 0;
+    this.transformCanvas.ty = 0;
+  }
+  this.transformCanvas.props = [this.transformCanvas.sx, 0, 0, 0, 0, this.transformCanvas.sy, 0, 0, 0, 0, 1, 0, this.transformCanvas.tx, this.transformCanvas.ty, 0, 1];
+  /* var i, len = this.elements.length;
+    for(i=0;i<len;i+=1){
+        if(this.elements[i] && this.elements[i].data.ty === 0){
+            this.elements[i].resize(this.globalData.transformCanvas);
+        }
+    } */
+  this.ctxTransform(this.transformCanvas.props);
+  this.canvasContext.beginPath();
+  this.canvasContext.rect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
+  this.canvasContext.closePath();
+  this.canvasContext.clip();
+
+  this.renderFrame(this.renderedFrame, true);
+};
+
+CanvasRendererBase.prototype.destroy = function () {
+  if (this.renderConfig.clearCanvas && this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.globalData.canvasContext = null;
+  this.animationItem.container = null;
+  this.destroyed = true;
+};
+
+CanvasRendererBase.prototype.renderFrame = function (num, forceRender) {
+  if ((this.renderedFrame === num && this.renderConfig.clearCanvas === true && !forceRender) || this.destroyed || num === -1) {
+    return;
+  }
+  this.renderedFrame = num;
+  this.globalData.frameNum = num - this.animationItem._isFirstFrame;
+  this.globalData.frameId += 1;
+  this.globalData._mdf = !this.renderConfig.clearCanvas || forceRender;
+  this.globalData.projectInterface.currentFrame = num;
+
+  // console.log('--------');
+  // console.log('NEW: ',num);
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    if (this.renderConfig.clearCanvas === true) {
+      this.canvasContext.clearRect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
+    } else {
+      this.save();
+    }
+    for (i = len - 1; i >= 0; i -= 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+    if (this.renderConfig.clearCanvas !== true) {
+      this.restore();
+    }
+  }
+};
+
+CanvasRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  var element = this.createItem(this.layers[pos], this, this.globalData);
+  elements[pos] = element;
+  element.initExpressions();
+  /* if(this.layers[pos].ty === 0){
+        element.resize(this.globalData.transformCanvas);
+    } */
+};
+
+CanvasRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+  }
+};
+
+CanvasRendererBase.prototype.hide = function () {
+  this.animationItem.container.style.display = 'none';
+};
+
+CanvasRendererBase.prototype.show = function () {
+  this.animationItem.container.style.display = 'block';
+};
+
+function CanvasContext() {
+  this.opacity = -1;
+  this.transform = createTypedArray('float32', 16);
+  this.fillStyle = '';
+  this.strokeStyle = '';
+  this.lineWidth = '';
+  this.lineCap = '';
+  this.lineJoin = '';
+  this.miterLimit = '';
+  this.id = Math.random();
+}
+
+function CVContextData() {
+  this.stack = [];
+  this.cArrPos = 0;
+  this.cTr = new Matrix();
+  var i;
+  var len = 15;
+  for (i = 0; i < len; i += 1) {
+    var canvasContext = new CanvasContext();
+    this.stack[i] = canvasContext;
+  }
+  this._length = len;
+  this.nativeContext = null;
+  this.transformMat = new Matrix();
+  this.currentOpacity = 1;
+  //
+  this.currentFillStyle = '';
+  this.appliedFillStyle = '';
+  //
+  this.currentStrokeStyle = '';
+  this.appliedStrokeStyle = '';
+  //
+  this.currentLineWidth = '';
+  this.appliedLineWidth = '';
+  //
+  this.currentLineCap = '';
+  this.appliedLineCap = '';
+  //
+  this.currentLineJoin = '';
+  this.appliedLineJoin = '';
+  //
+  this.appliedMiterLimit = '';
+  this.currentMiterLimit = '';
+}
+
+CVContextData.prototype.duplicate = function () {
+  var newLength = this._length * 2;
+  var i = 0;
+  for (i = this._length; i < newLength; i += 1) {
+    this.stack[i] = new CanvasContext();
+  }
+  this._length = newLength;
+};
+
+CVContextData.prototype.reset = function () {
+  this.cArrPos = 0;
+  this.cTr.reset();
+  this.stack[this.cArrPos].opacity = 1;
+};
+
+CVContextData.prototype.restore = function (forceRestore) {
+  this.cArrPos -= 1;
+  var currentContext = this.stack[this.cArrPos];
+  var transform = currentContext.transform;
+  var i;
+  var arr = this.cTr.props;
+  for (i = 0; i < 16; i += 1) {
+    arr[i] = transform[i];
+  }
+  if (forceRestore) {
+    this.nativeContext.restore();
+    var prevStack = this.stack[this.cArrPos + 1];
+    this.appliedFillStyle = prevStack.fillStyle;
+    this.appliedStrokeStyle = prevStack.strokeStyle;
+    this.appliedLineWidth = prevStack.lineWidth;
+    this.appliedLineCap = prevStack.lineCap;
+    this.appliedLineJoin = prevStack.lineJoin;
+    this.appliedMiterLimit = prevStack.miterLimit;
+  }
+  this.nativeContext.setTransform(transform[0], transform[1], transform[4], transform[5], transform[12], transform[13]);
+  if (forceRestore || (currentContext.opacity !== -1 && this.currentOpacity !== currentContext.opacity)) {
+    this.nativeContext.globalAlpha = currentContext.opacity;
+    this.currentOpacity = currentContext.opacity;
+  }
+  this.currentFillStyle = currentContext.fillStyle;
+  this.currentStrokeStyle = currentContext.strokeStyle;
+  this.currentLineWidth = currentContext.lineWidth;
+  this.currentLineCap = currentContext.lineCap;
+  this.currentLineJoin = currentContext.lineJoin;
+  this.currentMiterLimit = currentContext.miterLimit;
+};
+
+CVContextData.prototype.save = function (saveOnNativeFlag) {
+  if (saveOnNativeFlag) {
+    this.nativeContext.save();
+  }
+  var props = this.cTr.props;
+  if (this._length <= this.cArrPos) {
+    this.duplicate();
+  }
+
+  var currentStack = this.stack[this.cArrPos];
+  var i;
+  for (i = 0; i < 16; i += 1) {
+    currentStack.transform[i] = props[i];
+  }
+  this.cArrPos += 1;
+  var newStack = this.stack[this.cArrPos];
+  newStack.opacity = currentStack.opacity;
+  newStack.fillStyle = currentStack.fillStyle;
+  newStack.strokeStyle = currentStack.strokeStyle;
+  newStack.lineWidth = currentStack.lineWidth;
+  newStack.lineCap = currentStack.lineCap;
+  newStack.lineJoin = currentStack.lineJoin;
+  newStack.miterLimit = currentStack.miterLimit;
+};
+
+CVContextData.prototype.setOpacity = function (value) {
+  this.stack[this.cArrPos].opacity = value;
+};
+
+CVContextData.prototype.setContext = function (value) {
+  this.nativeContext = value;
+};
+
+CVContextData.prototype.fillStyle = function (value) {
+  if (this.stack[this.cArrPos].fillStyle !== value) {
+    this.currentFillStyle = value;
+    this.stack[this.cArrPos].fillStyle = value;
+  }
+};
+
+CVContextData.prototype.strokeStyle = function (value) {
+  if (this.stack[this.cArrPos].strokeStyle !== value) {
+    this.currentStrokeStyle = value;
+    this.stack[this.cArrPos].strokeStyle = value;
+  }
+};
+
+CVContextData.prototype.lineWidth = function (value) {
+  if (this.stack[this.cArrPos].lineWidth !== value) {
+    this.currentLineWidth = value;
+    this.stack[this.cArrPos].lineWidth = value;
+  }
+};
+
+CVContextData.prototype.lineCap = function (value) {
+  if (this.stack[this.cArrPos].lineCap !== value) {
+    this.currentLineCap = value;
+    this.stack[this.cArrPos].lineCap = value;
+  }
+};
+
+CVContextData.prototype.lineJoin = function (value) {
+  if (this.stack[this.cArrPos].lineJoin !== value) {
+    this.currentLineJoin = value;
+    this.stack[this.cArrPos].lineJoin = value;
+  }
+};
+
+CVContextData.prototype.miterLimit = function (value) {
+  if (this.stack[this.cArrPos].miterLimit !== value) {
+    this.currentMiterLimit = value;
+    this.stack[this.cArrPos].miterLimit = value;
+  }
+};
+
+CVContextData.prototype.transform = function (props) {
+  this.transformMat.cloneFromProps(props);
+  // Taking the last transform value from the stored stack of transforms
+  var currentTransform = this.cTr;
+  // Applying the last transform value after the new transform to respect the order of transformations
+  this.transformMat.multiply(currentTransform);
+  // Storing the new transformed value in the stored transform
+  currentTransform.cloneFromProps(this.transformMat.props);
+  var trProps = currentTransform.props;
+  // Applying the new transform to the canvas
+  this.nativeContext.setTransform(trProps[0], trProps[1], trProps[4], trProps[5], trProps[12], trProps[13]);
+};
+
+CVContextData.prototype.opacity = function (op) {
+  var currentOpacity = this.stack[this.cArrPos].opacity;
+  currentOpacity *= op < 0 ? 0 : op;
+  if (this.stack[this.cArrPos].opacity !== currentOpacity) {
+    if (this.currentOpacity !== op) {
+      this.nativeContext.globalAlpha = op;
+      this.currentOpacity = op;
+    }
+    this.stack[this.cArrPos].opacity = currentOpacity;
+  }
+};
+
+CVContextData.prototype.fill = function (rule) {
+  if (this.appliedFillStyle !== this.currentFillStyle) {
+    this.appliedFillStyle = this.currentFillStyle;
+    this.nativeContext.fillStyle = this.appliedFillStyle;
+  }
+  this.nativeContext.fill(rule);
+};
+
+CVContextData.prototype.fillRect = function (x, y, w, h) {
+  if (this.appliedFillStyle !== this.currentFillStyle) {
+    this.appliedFillStyle = this.currentFillStyle;
+    this.nativeContext.fillStyle = this.appliedFillStyle;
+  }
+  this.nativeContext.fillRect(x, y, w, h);
+};
+
+CVContextData.prototype.stroke = function () {
+  if (this.appliedStrokeStyle !== this.currentStrokeStyle) {
+    this.appliedStrokeStyle = this.currentStrokeStyle;
+    this.nativeContext.strokeStyle = this.appliedStrokeStyle;
+  }
+  if (this.appliedLineWidth !== this.currentLineWidth) {
+    this.appliedLineWidth = this.currentLineWidth;
+    this.nativeContext.lineWidth = this.appliedLineWidth;
+  }
+  if (this.appliedLineCap !== this.currentLineCap) {
+    this.appliedLineCap = this.currentLineCap;
+    this.nativeContext.lineCap = this.appliedLineCap;
+  }
+  if (this.appliedLineJoin !== this.currentLineJoin) {
+    this.appliedLineJoin = this.currentLineJoin;
+    this.nativeContext.lineJoin = this.appliedLineJoin;
+  }
+  if (this.appliedMiterLimit !== this.currentMiterLimit) {
+    this.appliedMiterLimit = this.currentMiterLimit;
+    this.nativeContext.miterLimit = this.appliedMiterLimit;
+  }
+  this.nativeContext.stroke();
+};
+
+function CVCompElement(data, globalData, comp) {
+  this.completeLayers = false;
+  this.layers = data.layers;
+  this.pendingElements = [];
+  this.elements = createSizedArray(this.layers.length);
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([CanvasRendererBase, ICompElement, CVBaseElement], CVCompElement);
+
+CVCompElement.prototype.renderInnerContent = function () {
+  var ctx = this.canvasContext;
+  ctx.beginPath();
+  ctx.moveTo(0, 0);
+  ctx.lineTo(this.data.w, 0);
+  ctx.lineTo(this.data.w, this.data.h);
+  ctx.lineTo(0, this.data.h);
+  ctx.lineTo(0, 0);
+  ctx.clip();
+  var i;
+  var len = this.layers.length;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+CVCompElement.prototype.destroy = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+  this.layers = null;
+  this.elements = null;
+};
+
+CVCompElement.prototype.createComp = function (data) {
+  return new CVCompElement(data, this.globalData, this);
+};
+
+function CanvasRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.renderConfig = {
+    clearCanvas: (config && config.clearCanvas !== undefined) ? config.clearCanvas : true,
+    context: (config && config.context) || null,
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+  this.renderConfig.dpr = (config && config.dpr) || 1;
+  if (this.animationItem.wrapper) {
+    this.renderConfig.dpr = (config && config.dpr) || window.devicePixelRatio || 1;
+  }
+  this.renderedFrame = -1;
+  this.globalData = {
+    frameNum: -1,
+    _mdf: false,
+    renderConfig: this.renderConfig,
+    currentGlobalAlpha: -1,
+  };
+  this.contextData = new CVContextData();
+  this.elements = [];
+  this.pendingElements = [];
+  this.transformMat = new Matrix();
+  this.completeLayers = false;
+  this.rendererType = 'canvas';
+  if (this.renderConfig.clearCanvas) {
+    this.ctxTransform = this.contextData.transform.bind(this.contextData);
+    this.ctxOpacity = this.contextData.opacity.bind(this.contextData);
+    this.ctxFillStyle = this.contextData.fillStyle.bind(this.contextData);
+    this.ctxStrokeStyle = this.contextData.strokeStyle.bind(this.contextData);
+    this.ctxLineWidth = this.contextData.lineWidth.bind(this.contextData);
+    this.ctxLineCap = this.contextData.lineCap.bind(this.contextData);
+    this.ctxLineJoin = this.contextData.lineJoin.bind(this.contextData);
+    this.ctxMiterLimit = this.contextData.miterLimit.bind(this.contextData);
+    this.ctxFill = this.contextData.fill.bind(this.contextData);
+    this.ctxFillRect = this.contextData.fillRect.bind(this.contextData);
+    this.ctxStroke = this.contextData.stroke.bind(this.contextData);
+    this.save = this.contextData.save.bind(this.contextData);
+  }
+}
+extendPrototype([CanvasRendererBase], CanvasRenderer);
+
+CanvasRenderer.prototype.createComp = function (data) {
+  return new CVCompElement(data, this.globalData, this);
+};
+
+// Registering renderers
+registerRenderer('canvas', CanvasRenderer);
+
+// Registering shape modifiers
+ShapeModifiers.registerModifier('tm', TrimModifier);
+ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
+ShapeModifiers.registerModifier('rp', RepeaterModifier);
+ShapeModifiers.registerModifier('rd', RoundCornersModifier);
+ShapeModifiers.registerModifier('zz', ZigZagModifier);
+ShapeModifiers.registerModifier('op', OffsetPathModifier);
+
+export { lottie as default };
diff --git a/build/player/esm/lottie_light_html.min.js b/build/player/esm/lottie_light_html.min.js
new file mode 100644
index 0000000..574134d
--- /dev/null
+++ b/build/player/esm/lottie_light_html.min.js
@@ -0,0 +1,12832 @@
+const svgNS = 'http://www.w3.org/2000/svg';
+
+let locationHref = '';
+let _useWebWorker = false;
+
+const initialDefaultFrame = -999999;
+
+const setWebWorker = (flag) => { _useWebWorker = !!flag; };
+const getWebWorker = () => _useWebWorker;
+
+const setLocationHref = (value) => { locationHref = value; };
+const getLocationHref = () => locationHref;
+
+function createTag(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElement(type);
+}
+
+function extendPrototype(sources, destination) {
+  var i;
+  var len = sources.length;
+  var sourcePrototype;
+  for (i = 0; i < len; i += 1) {
+    sourcePrototype = sources[i].prototype;
+    for (var attr in sourcePrototype) {
+      if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
+    }
+  }
+}
+
+function getDescriptor(object, prop) {
+  return Object.getOwnPropertyDescriptor(object, prop);
+}
+
+function createProxyFunction(prototype) {
+  function ProxyFunction() {}
+  ProxyFunction.prototype = prototype;
+  return ProxyFunction;
+}
+
+// import Howl from '../../3rd_party/howler';
+
+const audioControllerFactory = (function () {
+  function AudioController(audioFactory) {
+    this.audios = [];
+    this.audioFactory = audioFactory;
+    this._volume = 1;
+    this._isMuted = false;
+  }
+
+  AudioController.prototype = {
+    addAudio: function (audio) {
+      this.audios.push(audio);
+    },
+    pause: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].pause();
+      }
+    },
+    resume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].resume();
+      }
+    },
+    setRate: function (rateValue) {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].setRate(rateValue);
+      }
+    },
+    createAudio: function (assetPath) {
+      if (this.audioFactory) {
+        return this.audioFactory(assetPath);
+      } if (window.Howl) {
+        return new window.Howl({
+          src: [assetPath],
+        });
+      }
+      return {
+        isPlaying: false,
+        play: function () { this.isPlaying = true; },
+        seek: function () { this.isPlaying = false; },
+        playing: function () {},
+        rate: function () {},
+        setVolume: function () {},
+      };
+    },
+    setAudioFactory: function (audioFactory) {
+      this.audioFactory = audioFactory;
+    },
+    setVolume: function (value) {
+      this._volume = value;
+      this._updateVolume();
+    },
+    mute: function () {
+      this._isMuted = true;
+      this._updateVolume();
+    },
+    unmute: function () {
+      this._isMuted = false;
+      this._updateVolume();
+    },
+    getVolume: function () {
+      return this._volume;
+    },
+    _updateVolume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
+      }
+    },
+  };
+
+  return function () {
+    return new AudioController();
+  };
+}());
+
+const createTypedArray = (function () {
+  function createRegularArray(type, len) {
+    var i = 0;
+    var arr = [];
+    var value;
+    switch (type) {
+      case 'int16':
+      case 'uint8c':
+        value = 1;
+        break;
+      default:
+        value = 1.1;
+        break;
+    }
+    for (i = 0; i < len; i += 1) {
+      arr.push(value);
+    }
+    return arr;
+  }
+  function createTypedArrayFactory(type, len) {
+    if (type === 'float32') {
+      return new Float32Array(len);
+    } if (type === 'int16') {
+      return new Int16Array(len);
+    } if (type === 'uint8c') {
+      return new Uint8ClampedArray(len);
+    }
+    return createRegularArray(type, len);
+  }
+  if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
+    return createTypedArrayFactory;
+  }
+  return createRegularArray;
+}());
+
+function createSizedArray(len) {
+  return Array.apply(null, { length: len });
+}
+
+let subframeEnabled = true;
+let expressionsPlugin = null;
+let expressionsInterfaces = null;
+let idPrefix$1 = '';
+const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+let _shouldRoundValues = false;
+const bmPow = Math.pow;
+const bmSqrt = Math.sqrt;
+const bmFloor = Math.floor;
+const bmMax = Math.max;
+const bmMin = Math.min;
+
+const BMMath = {};
+(function () {
+  var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
+  var i;
+  var len = propertyNames.length;
+  for (i = 0; i < len; i += 1) {
+    BMMath[propertyNames[i]] = Math[propertyNames[i]];
+  }
+}());
+
+function ProjectInterface$1() { return {}; }
+BMMath.random = Math.random;
+BMMath.abs = function (val) {
+  var tOfVal = typeof val;
+  if (tOfVal === 'object' && val.length) {
+    var absArr = createSizedArray(val.length);
+    var i;
+    var len = val.length;
+    for (i = 0; i < len; i += 1) {
+      absArr[i] = Math.abs(val[i]);
+    }
+    return absArr;
+  }
+  return Math.abs(val);
+};
+let defaultCurveSegments = 150;
+const degToRads = Math.PI / 180;
+const roundCorner = 0.5519;
+
+function roundValues(flag) {
+  _shouldRoundValues = !!flag;
+}
+
+function bmRnd(value) {
+  if (_shouldRoundValues) {
+    return Math.round(value);
+  }
+  return value;
+}
+
+function styleDiv(element) {
+  element.style.position = 'absolute';
+  element.style.top = 0;
+  element.style.left = 0;
+  element.style.display = 'block';
+  element.style.transformOrigin = '0 0';
+  element.style.webkitTransformOrigin = '0 0';
+  element.style.backfaceVisibility = 'visible';
+  element.style.webkitBackfaceVisibility = 'visible';
+  element.style.transformStyle = 'preserve-3d';
+  element.style.webkitTransformStyle = 'preserve-3d';
+  element.style.mozTransformStyle = 'preserve-3d';
+}
+
+function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
+  this.type = type;
+  this.currentTime = currentTime;
+  this.totalTime = totalTime;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteEvent(type, frameMultiplier) {
+  this.type = type;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
+  this.type = type;
+  this.currentLoop = currentLoop;
+  this.totalLoops = totalLoops;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMSegmentStartEvent(type, firstFrame, totalFrames) {
+  this.type = type;
+  this.firstFrame = firstFrame;
+  this.totalFrames = totalFrames;
+}
+
+function BMDestroyEvent(type, target) {
+  this.type = type;
+  this.target = target;
+}
+
+function BMRenderFrameErrorEvent(nativeError, currentTime) {
+  this.type = 'renderFrameError';
+  this.nativeError = nativeError;
+  this.currentTime = currentTime;
+}
+
+function BMConfigErrorEvent(nativeError) {
+  this.type = 'configError';
+  this.nativeError = nativeError;
+}
+
+function BMAnimationConfigErrorEvent(type, nativeError) {
+  this.type = type;
+  this.nativeError = nativeError;
+}
+
+const createElementID = (function () {
+  var _count = 0;
+  return function createID() {
+    _count += 1;
+    return idPrefix$1 + '__lottie_element_' + _count;
+  };
+}());
+
+function HSVtoRGB(h, s, v) {
+  var r;
+  var g;
+  var b;
+  var i;
+  var f;
+  var p;
+  var q;
+  var t;
+  i = Math.floor(h * 6);
+  f = h * 6 - i;
+  p = v * (1 - s);
+  q = v * (1 - f * s);
+  t = v * (1 - (1 - f) * s);
+  switch (i % 6) {
+    case 0: r = v; g = t; b = p; break;
+    case 1: r = q; g = v; b = p; break;
+    case 2: r = p; g = v; b = t; break;
+    case 3: r = p; g = q; b = v; break;
+    case 4: r = t; g = p; b = v; break;
+    case 5: r = v; g = p; b = q; break;
+    default: break;
+  }
+  return [r,
+    g,
+    b];
+}
+
+function RGBtoHSV(r, g, b) {
+  var max = Math.max(r, g, b);
+  var min = Math.min(r, g, b);
+  var d = max - min;
+  var h;
+  var s = (max === 0 ? 0 : d / max);
+  var v = max / 255;
+
+  switch (max) {
+    case min: h = 0; break;
+    case r: h = (g - b) + d * (g < b ? 6 : 0); h /= 6 * d; break;
+    case g: h = (b - r) + d * 2; h /= 6 * d; break;
+    case b: h = (r - g) + d * 4; h /= 6 * d; break;
+    default: break;
+  }
+
+  return [
+    h,
+    s,
+    v,
+  ];
+}
+
+function addSaturationToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[1] += offset;
+  if (hsv[1] > 1) {
+    hsv[1] = 1;
+  } else if (hsv[1] <= 0) {
+    hsv[1] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addBrightnessToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[2] += offset;
+  if (hsv[2] > 1) {
+    hsv[2] = 1;
+  } else if (hsv[2] < 0) {
+    hsv[2] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addHueToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[0] += offset / 360;
+  if (hsv[0] > 1) {
+    hsv[0] -= 1;
+  } else if (hsv[0] < 0) {
+    hsv[0] += 1;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+const rgbToHex = (function () {
+  var colorMap = [];
+  var i;
+  var hex;
+  for (i = 0; i < 256; i += 1) {
+    hex = i.toString(16);
+    colorMap[i] = hex.length === 1 ? '0' + hex : hex;
+  }
+
+  return function (r, g, b) {
+    if (r < 0) {
+      r = 0;
+    }
+    if (g < 0) {
+      g = 0;
+    }
+    if (b < 0) {
+      b = 0;
+    }
+    return '#' + colorMap[r] + colorMap[g] + colorMap[b];
+  };
+}());
+
+const setSubframeEnabled = (flag) => { subframeEnabled = !!flag; };
+const getSubframeEnabled = () => subframeEnabled;
+const setExpressionsPlugin = (value) => { expressionsPlugin = value; };
+const getExpressionsPlugin = () => expressionsPlugin;
+const setExpressionInterfaces = (value) => { expressionsInterfaces = value; };
+const getExpressionInterfaces = () => expressionsInterfaces;
+const setDefaultCurveSegments = (value) => { defaultCurveSegments = value; };
+const getDefaultCurveSegments = () => defaultCurveSegments;
+const setIdPrefix = (value) => { idPrefix$1 = value; };
+const getIdPrefix = () => idPrefix$1;
+
+function createNS(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElementNS(svgNS, type);
+}
+
+const dataManager = (function () {
+  var _counterId = 1;
+  var processes = [];
+  var workerFn;
+  var workerInstance;
+  var workerProxy = {
+    onmessage: function () {
+
+    },
+    postMessage: function (path) {
+      workerFn({
+        data: path,
+      });
+    },
+  };
+  var _workerSelf = {
+    postMessage: function (data) {
+      workerProxy.onmessage({
+        data: data,
+      });
+    },
+  };
+  function createWorker(fn) {
+    if (window.Worker && window.Blob && getWebWorker()) {
+      var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      var url = URL.createObjectURL(blob);
+      return new Worker(url);
+    }
+    workerFn = fn;
+    return workerProxy;
+  }
+
+  function setupWorker() {
+    if (!workerInstance) {
+      workerInstance = createWorker(function workerStart(e) {
+        function dataFunctionManager() {
+          function completeLayers(layers, comps) {
+            var layerData;
+            var i;
+            var len = layers.length;
+            var j;
+            var jLen;
+            var k;
+            var kLen;
+            for (i = 0; i < len; i += 1) {
+              layerData = layers[i];
+              if (('ks' in layerData) && !layerData.completed) {
+                layerData.completed = true;
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      convertPathsToAbsoluteValues(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) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 0) {
+                  layerData.layers = findCompLayers(layerData.refId, comps);
+                  completeLayers(layerData.layers, comps);
+                } else if (layerData.ty === 4) {
+                  completeShapes(layerData.shapes);
+                } else if (layerData.ty === 5) {
+                  completeText(layerData);
+                }
+              }
+            }
+          }
+
+          function completeChars(chars, assets) {
+            if (chars) {
+              var i = 0;
+              var len = chars.length;
+              for (i = 0; i < len; i += 1) {
+                if (chars[i].t === 1) {
+                  // var compData = findComp(chars[i].data.refId, assets);
+                  chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                  // chars[i].data.ip = 0;
+                  // chars[i].data.op = 99999;
+                  // chars[i].data.st = 0;
+                  // chars[i].data.sr = 1;
+                  // chars[i].w = compData.w;
+                  // chars[i].data.ks = {
+                  //   a: { k: [0, 0, 0], a: 0 },
+                  //   p: { k: [0, -compData.h, 0], a: 0 },
+                  //   r: { k: 0, a: 0 },
+                  //   s: { k: [100, 100], a: 0 },
+                  //   o: { k: 100, a: 0 },
+                  // };
+                  completeLayers(chars[i].data.layers, assets);
+                }
+              }
+            }
+          }
+
+          function findComp(id, comps) {
+            var i = 0;
+            var len = comps.length;
+            while (i < len) {
+              if (comps[i].id === id) {
+                return comps[i];
+              }
+              i += 1;
+            }
+            return null;
+          }
+
+          function findCompLayers(id, comps) {
+            var comp = findComp(id, comps);
+            if (comp) {
+              if (!comp.layers.__used) {
+                comp.layers.__used = true;
+                return comp.layers;
+              }
+              return JSON.parse(JSON.stringify(comp.layers));
+            }
+            return null;
+          }
+
+          function completeShapes(arr) {
+            var i;
+            var len = arr.length;
+            var j;
+            var jLen;
+            for (i = len - 1; i >= 0; i -= 1) {
+              if (arr[i].ty === 'sh') {
+                if (arr[i].ks.k.i) {
+                  convertPathsToAbsoluteValues(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) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
+                    }
+                    if (arr[i].ks.k[j].e) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
+                    }
+                  }
+                }
+              } else if (arr[i].ty === 'gr') {
+                completeShapes(arr[i].it);
+              }
+            }
+          }
+
+          function convertPathsToAbsoluteValues(path) {
+            var i;
+            var len = path.i.length;
+            for (i = 0; i < len; i += 1) {
+              path.i[i][0] += path.v[i][0];
+              path.i[i][1] += path.v[i][1];
+              path.o[i][0] += path.v[i][0];
+              path.o[i][1] += path.v[i][1];
+            }
+          }
+
+          function checkVersion(minimum, animVersionString) {
+            var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
+            if (minimum[0] > animVersion[0]) {
+              return true;
+            } if (animVersion[0] > minimum[0]) {
+              return false;
+            }
+            if (minimum[1] > animVersion[1]) {
+              return true;
+            } if (animVersion[1] > minimum[1]) {
+              return false;
+            }
+            if (minimum[2] > animVersion[2]) {
+              return true;
+            } if (animVersion[2] > minimum[2]) {
+              return false;
+            }
+            return null;
+          }
+
+          var checkText = (function () {
+            var minimumVersion = [4, 4, 14];
+
+            function updateTextLayer(textLayer) {
+              var documentData = textLayer.t.d;
+              textLayer.t.d = {
+                k: [
+                  {
+                    s: documentData,
+                    t: 0,
+                  },
+                ],
+              };
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkChars = (function () {
+            var minimumVersion = [4, 7, 99];
+            return function (animationData) {
+              if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
+                var i;
+                var len = animationData.chars.length;
+                for (i = 0; i < len; i += 1) {
+                  var charData = animationData.chars[i];
+                  if (charData.data && charData.data.shapes) {
+                    completeShapes(charData.data.shapes);
+                    charData.data.ip = 0;
+                    charData.data.op = 99999;
+                    charData.data.st = 0;
+                    charData.data.sr = 1;
+                    charData.data.ks = {
+                      p: { k: [0, 0], a: 0 },
+                      s: { k: [100, 100], a: 0 },
+                      a: { k: [0, 0], a: 0 },
+                      r: { k: 0, a: 0 },
+                      o: { k: 100, a: 0 },
+                    };
+                    if (!animationData.chars[i].t) {
+                      charData.data.shapes.push(
+                        {
+                          ty: 'no',
+                        }
+                      );
+                      charData.data.shapes[0].it.push(
+                        {
+                          p: { k: [0, 0], a: 0 },
+                          s: { k: [100, 100], a: 0 },
+                          a: { k: [0, 0], a: 0 },
+                          r: { k: 0, a: 0 },
+                          o: { k: 100, a: 0 },
+                          sk: { k: 0, a: 0 },
+                          sa: { k: 0, a: 0 },
+                          ty: 'tr',
+                        }
+                      );
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkPathProperties = (function () {
+            var minimumVersion = [5, 7, 15];
+
+            function updateTextLayer(textLayer) {
+              var pathData = textLayer.t.p;
+              if (typeof pathData.a === 'number') {
+                pathData.a = {
+                  a: 0,
+                  k: pathData.a,
+                };
+              }
+              if (typeof pathData.p === 'number') {
+                pathData.p = {
+                  a: 0,
+                  k: pathData.p,
+                };
+              }
+              if (typeof pathData.r === 'number') {
+                pathData.r = {
+                  a: 0,
+                  k: pathData.r,
+                };
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkColors = (function () {
+            var minimumVersion = [4, 1, 9];
+
+            function iterateShapes(shapes) {
+              var i;
+              var len = shapes.length;
+              var j;
+              var jLen;
+              for (i = 0; i < len; i += 1) {
+                if (shapes[i].ty === 'gr') {
+                  iterateShapes(shapes[i].it);
+                } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
+                  if (shapes[i].c.k && shapes[i].c.k[0].i) {
+                    jLen = shapes[i].c.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (shapes[i].c.k[j].s) {
+                        shapes[i].c.k[j].s[0] /= 255;
+                        shapes[i].c.k[j].s[1] /= 255;
+                        shapes[i].c.k[j].s[2] /= 255;
+                        shapes[i].c.k[j].s[3] /= 255;
+                      }
+                      if (shapes[i].c.k[j].e) {
+                        shapes[i].c.k[j].e[0] /= 255;
+                        shapes[i].c.k[j].e[1] /= 255;
+                        shapes[i].c.k[j].e[2] /= 255;
+                        shapes[i].c.k[j].e[3] /= 255;
+                      }
+                    }
+                  } else {
+                    shapes[i].c.k[0] /= 255;
+                    shapes[i].c.k[1] /= 255;
+                    shapes[i].c.k[2] /= 255;
+                    shapes[i].c.k[3] /= 255;
+                  }
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 4) {
+                  iterateShapes(layers[i].shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkShapes = (function () {
+            var minimumVersion = [4, 4, 18];
+
+            function completeClosingShapes(arr) {
+              var i;
+              var len = arr.length;
+              var j;
+              var jLen;
+              for (i = len - 1; i >= 0; i -= 1) {
+                if (arr[i].ty === 'sh') {
+                  if (arr[i].ks.k.i) {
+                    arr[i].ks.k.c = arr[i].closed;
+                  } else {
+                    jLen = arr[i].ks.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (arr[i].ks.k[j].s) {
+                        arr[i].ks.k[j].s[0].c = arr[i].closed;
+                      }
+                      if (arr[i].ks.k[j].e) {
+                        arr[i].ks.k[j].e[0].c = arr[i].closed;
+                      }
+                    }
+                  }
+                } else if (arr[i].ty === 'gr') {
+                  completeClosingShapes(arr[i].it);
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var layerData;
+              var i;
+              var len = layers.length;
+              var j;
+              var jLen;
+              var k;
+              var kLen;
+              for (i = 0; i < len; i += 1) {
+                layerData = layers[i];
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      maskProps[j].pt.k.c = maskProps[j].cl;
+                    } else {
+                      kLen = maskProps[j].pt.k.length;
+                      for (k = 0; k < kLen; k += 1) {
+                        if (maskProps[j].pt.k[k].s) {
+                          maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 4) {
+                  completeClosingShapes(layerData.shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          function completeData(animationData) {
+            if (animationData.__complete) {
+              return;
+            }
+            checkColors(animationData);
+            checkText(animationData);
+            checkChars(animationData);
+            checkPathProperties(animationData);
+            checkShapes(animationData);
+            completeLayers(animationData.layers, animationData.assets);
+            completeChars(animationData.chars, animationData.assets);
+            animationData.__complete = true;
+          }
+
+          function completeText(data) {
+            if (data.t.a.length === 0 && !('m' in data.t.p)) {
+              // data.singleShape = true;
+            }
+          }
+
+          var moduleOb = {};
+          moduleOb.completeData = completeData;
+          moduleOb.checkColors = checkColors;
+          moduleOb.checkChars = checkChars;
+          moduleOb.checkPathProperties = checkPathProperties;
+          moduleOb.checkShapes = checkShapes;
+          moduleOb.completeLayers = completeLayers;
+
+          return moduleOb;
+        }
+        if (!_workerSelf.dataManager) {
+          _workerSelf.dataManager = dataFunctionManager();
+        }
+
+        if (!_workerSelf.assetLoader) {
+          _workerSelf.assetLoader = (function () {
+            function formatResponse(xhr) {
+              // using typeof doubles the time of execution of this method,
+              // so if available, it's better to use the header to validate the type
+              var contentTypeHeader = xhr.getResponseHeader('content-type');
+              if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
+                return xhr.response;
+              }
+              if (xhr.response && typeof xhr.response === 'object') {
+                return xhr.response;
+              } if (xhr.response && typeof xhr.response === 'string') {
+                return JSON.parse(xhr.response);
+              } if (xhr.responseText) {
+                return JSON.parse(xhr.responseText);
+              }
+              return null;
+            }
+
+            function loadAsset(path, fullPath, callback, errorCallback) {
+              var response;
+              var xhr = new XMLHttpRequest();
+              // set responseType after calling open or IE will break.
+              try {
+                // This crashes on Android WebView prior to KitKat
+                xhr.responseType = 'json';
+              } catch (err) {} // eslint-disable-line no-empty
+              xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4) {
+                  if (xhr.status === 200) {
+                    response = formatResponse(xhr);
+                    callback(response);
+                  } else {
+                    try {
+                      response = formatResponse(xhr);
+                      callback(response);
+                    } catch (err) {
+                      if (errorCallback) {
+                        errorCallback(err);
+                      }
+                    }
+                  }
+                }
+              };
+              try {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), path, true);
+              } catch (error) {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
+              }
+              xhr.send();
+            }
+            return {
+              load: loadAsset,
+            };
+          }());
+        }
+
+        if (e.data.type === 'loadAnimation') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.dataManager.completeData(data);
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        } else if (e.data.type === 'complete') {
+          var animation = e.data.animation;
+          _workerSelf.dataManager.completeData(animation);
+          _workerSelf.postMessage({
+            id: e.data.id,
+            payload: animation,
+            status: 'success',
+          });
+        } else if (e.data.type === 'loadData') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        }
+      });
+
+      workerInstance.onmessage = function (event) {
+        var data = event.data;
+        var id = data.id;
+        var process = processes[id];
+        processes[id] = null;
+        if (data.status === 'success') {
+          process.onComplete(data.payload);
+        } else if (process.onError) {
+          process.onError();
+        }
+      };
+    }
+  }
+
+  function createProcess(onComplete, onError) {
+    _counterId += 1;
+    var id = 'processId_' + _counterId;
+    processes[id] = {
+      onComplete: onComplete,
+      onError: onError,
+    };
+    return id;
+  }
+
+  function loadAnimation(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadAnimation',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function loadData(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadData',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function completeAnimation(anim, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'complete',
+      animation: anim,
+      id: processId,
+    });
+  }
+
+  return {
+    loadAnimation: loadAnimation,
+    loadData: loadData,
+    completeAnimation: completeAnimation,
+  };
+}());
+
+const ImagePreloader = (function () {
+  var proxyImage = (function () {
+    var canvas = createTag('canvas');
+    canvas.width = 1;
+    canvas.height = 1;
+    var ctx = canvas.getContext('2d');
+    ctx.fillStyle = 'rgba(0,0,0,0)';
+    ctx.fillRect(0, 0, 1, 1);
+    return canvas;
+  }());
+
+  function imageLoaded() {
+    this.loadedAssets += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+  function footageLoaded() {
+    this.loadedFootagesCount += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+
+  function getAssetsPath(assetData, assetsPath, originalPath) {
+    var path = '';
+    if (assetData.e) {
+      path = assetData.p;
+    } else if (assetsPath) {
+      var imagePath = assetData.p;
+      if (imagePath.indexOf('images/') !== -1) {
+        imagePath = imagePath.split('/')[1];
+      }
+      path = assetsPath + imagePath;
+    } else {
+      path = originalPath;
+      path += assetData.u ? assetData.u : '';
+      path += assetData.p;
+    }
+    return path;
+  }
+
+  function testImageLoaded(img) {
+    var _count = 0;
+    var intervalId = setInterval(function () {
+      var box = img.getBBox();
+      if (box.width || _count > 500) {
+        this._imageLoaded();
+        clearInterval(intervalId);
+      }
+      _count += 1;
+    }.bind(this), 50);
+  }
+
+  function createImageData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createNS('image');
+    if (isSafari) {
+      this.testImageLoaded(img);
+    } else {
+      img.addEventListener('load', this._imageLoaded, false);
+    }
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
+    if (this._elementHelper.append) {
+      this._elementHelper.append(img);
+    } else {
+      this._elementHelper.appendChild(img);
+    }
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createImgData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createTag('img');
+    img.crossOrigin = 'anonymous';
+    img.addEventListener('load', this._imageLoaded, false);
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.src = path;
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createFootageData(data) {
+    var ob = {
+      assetData: data,
+    };
+    var path = getAssetsPath(data, this.assetsPath, this.path);
+    dataManager.loadData(path, function (footageData) {
+      ob.img = footageData;
+      this._footageLoaded();
+    }.bind(this), function () {
+      ob.img = {};
+      this._footageLoaded();
+    }.bind(this));
+    return ob;
+  }
+
+  function loadAssets(assets, cb) {
+    this.imagesLoadedCb = cb;
+    var i;
+    var len = assets.length;
+    for (i = 0; i < len; i += 1) {
+      if (!assets[i].layers) {
+        if (!assets[i].t || assets[i].t === 'seq') {
+          this.totalImages += 1;
+          this.images.push(this._createImageData(assets[i]));
+        } else if (assets[i].t === 3) {
+          this.totalFootages += 1;
+          this.images.push(this.createFootageData(assets[i]));
+        }
+      }
+    }
+  }
+
+  function setPath(path) {
+    this.path = path || '';
+  }
+
+  function setAssetsPath(path) {
+    this.assetsPath = path || '';
+  }
+
+  function getAsset(assetData) {
+    var i = 0;
+    var len = this.images.length;
+    while (i < len) {
+      if (this.images[i].assetData === assetData) {
+        return this.images[i].img;
+      }
+      i += 1;
+    }
+    return null;
+  }
+
+  function destroy() {
+    this.imagesLoadedCb = null;
+    this.images.length = 0;
+  }
+
+  function loadedImages() {
+    return this.totalImages === this.loadedAssets;
+  }
+
+  function loadedFootages() {
+    return this.totalFootages === this.loadedFootagesCount;
+  }
+
+  function setCacheType(type, elementHelper) {
+    if (type === 'svg') {
+      this._elementHelper = elementHelper;
+      this._createImageData = this.createImageData.bind(this);
+    } else {
+      this._createImageData = this.createImgData.bind(this);
+    }
+  }
+
+  function ImagePreloaderFactory() {
+    this._imageLoaded = imageLoaded.bind(this);
+    this._footageLoaded = footageLoaded.bind(this);
+    this.testImageLoaded = testImageLoaded.bind(this);
+    this.createFootageData = createFootageData.bind(this);
+    this.assetsPath = '';
+    this.path = '';
+    this.totalImages = 0;
+    this.totalFootages = 0;
+    this.loadedAssets = 0;
+    this.loadedFootagesCount = 0;
+    this.imagesLoadedCb = null;
+    this.images = [];
+  }
+
+  ImagePreloaderFactory.prototype = {
+    loadAssets: loadAssets,
+    setAssetsPath: setAssetsPath,
+    setPath: setPath,
+    loadedImages: loadedImages,
+    loadedFootages: loadedFootages,
+    destroy: destroy,
+    getAsset: getAsset,
+    createImgData: createImgData,
+    createImageData: createImageData,
+    imageLoaded: imageLoaded,
+    footageLoaded: footageLoaded,
+    setCacheType: setCacheType,
+  };
+
+  return ImagePreloaderFactory;
+}());
+
+function BaseEvent() {}
+BaseEvent.prototype = {
+  triggerEvent: function (eventName, args) {
+    if (this._cbs[eventName]) {
+      var callbacks = this._cbs[eventName];
+      for (var i = 0; i < callbacks.length; i += 1) {
+        callbacks[i](args);
+      }
+    }
+  },
+  addEventListener: function (eventName, callback) {
+    if (!this._cbs[eventName]) {
+      this._cbs[eventName] = [];
+    }
+    this._cbs[eventName].push(callback);
+
+    return function () {
+      this.removeEventListener(eventName, callback);
+    }.bind(this);
+  },
+  removeEventListener: function (eventName, callback) {
+    if (!callback) {
+      this._cbs[eventName] = null;
+    } else if (this._cbs[eventName]) {
+      var i = 0;
+      var len = this._cbs[eventName].length;
+      while (i < len) {
+        if (this._cbs[eventName][i] === callback) {
+          this._cbs[eventName].splice(i, 1);
+          i -= 1;
+          len -= 1;
+        }
+        i += 1;
+      }
+      if (!this._cbs[eventName].length) {
+        this._cbs[eventName] = null;
+      }
+    }
+  },
+};
+
+const markerParser = (
+
+  function () {
+    function parsePayloadLines(payload) {
+      var lines = payload.split('\r\n');
+      var keys = {};
+      var line;
+      var keysCount = 0;
+      for (var i = 0; i < lines.length; i += 1) {
+        line = lines[i].split(':');
+        if (line.length === 2) {
+          keys[line[0]] = line[1].trim();
+          keysCount += 1;
+        }
+      }
+      if (keysCount === 0) {
+        throw new Error();
+      }
+      return keys;
+    }
+
+    return function (_markers) {
+      var markers = [];
+      for (var i = 0; i < _markers.length; i += 1) {
+        var _marker = _markers[i];
+        var markerData = {
+          time: _marker.tm,
+          duration: _marker.dr,
+        };
+        try {
+          markerData.payload = JSON.parse(_markers[i].cm);
+        } catch (_) {
+          try {
+            markerData.payload = parsePayloadLines(_markers[i].cm);
+          } catch (__) {
+            markerData.payload = {
+              name: _markers[i].cm,
+            };
+          }
+        }
+        markers.push(markerData);
+      }
+      return markers;
+    };
+  }());
+
+const ProjectInterface = (function () {
+  function registerComposition(comp) {
+    this.compositions.push(comp);
+  }
+
+  return function () {
+    function _thisProjectFunction(name) {
+      var i = 0;
+      var len = this.compositions.length;
+      while (i < len) {
+        if (this.compositions[i].data && this.compositions[i].data.nm === name) {
+          if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
+            this.compositions[i].prepareFrame(this.currentFrame);
+          }
+          return this.compositions[i].compInterface;
+        }
+        i += 1;
+      }
+      return null;
+    }
+
+    _thisProjectFunction.compositions = [];
+    _thisProjectFunction.currentFrame = 0;
+
+    _thisProjectFunction.registerComposition = registerComposition;
+
+    return _thisProjectFunction;
+  };
+}());
+
+const renderers = {};
+
+const registerRenderer = (key, value) => {
+  renderers[key] = value;
+};
+
+function getRenderer(key) {
+  return renderers[key];
+}
+
+function getRegisteredRenderer() {
+  // Returns canvas by default for compatibility
+  if (renderers.canvas) {
+    return 'canvas';
+  }
+  // Returns any renderer that is registered
+  for (const key in renderers) {
+    if (renderers[key]) {
+      return key;
+    }
+  }
+  return '';
+}
+
+const AnimationItem = function () {
+  this._cbs = [];
+  this.name = '';
+  this.path = '';
+  this.isLoaded = false;
+  this.currentFrame = 0;
+  this.currentRawFrame = 0;
+  this.firstFrame = 0;
+  this.totalFrames = 0;
+  this.frameRate = 0;
+  this.frameMult = 0;
+  this.playSpeed = 1;
+  this.playDirection = 1;
+  this.playCount = 0;
+  this.animationData = {};
+  this.assets = [];
+  this.isPaused = true;
+  this.autoplay = false;
+  this.loop = true;
+  this.renderer = null;
+  this.animationID = createElementID();
+  this.assetsPath = '';
+  this.timeCompleted = 0;
+  this.segmentPos = 0;
+  this.isSubframeEnabled = getSubframeEnabled();
+  this.segments = [];
+  this._idle = true;
+  this._completedLoop = false;
+  this.projectInterface = ProjectInterface();
+  this.imagePreloader = new ImagePreloader();
+  this.audioController = audioControllerFactory();
+  this.markers = [];
+  this.configAnimation = this.configAnimation.bind(this);
+  this.onSetupError = this.onSetupError.bind(this);
+  this.onSegmentComplete = this.onSegmentComplete.bind(this);
+  this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
+  this.expressionsPlugin = getExpressionsPlugin();
+};
+
+extendPrototype([BaseEvent], AnimationItem);
+
+AnimationItem.prototype.setParams = function (params) {
+  if (params.wrapper || params.container) {
+    this.wrapper = params.wrapper || params.container;
+  }
+  var animType = 'svg';
+  if (params.animType) {
+    animType = params.animType;
+  } else if (params.renderer) {
+    animType = params.renderer;
+  }
+  const RendererClass = getRenderer(animType);
+  this.renderer = new RendererClass(this, params.rendererSettings);
+  this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
+  this.renderer.setProjectInterface(this.projectInterface);
+  this.animType = animType;
+  if (params.loop === ''
+        || params.loop === null
+        || params.loop === undefined
+        || params.loop === true) {
+    this.loop = true;
+  } else if (params.loop === false) {
+    this.loop = false;
+  } else {
+    this.loop = parseInt(params.loop, 10);
+  }
+  this.autoplay = 'autoplay' in params ? params.autoplay : true;
+  this.name = params.name ? params.name : '';
+  this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
+  this.assetsPath = params.assetsPath;
+  this.initialSegment = params.initialSegment;
+  if (params.audioFactory) {
+    this.audioController.setAudioFactory(params.audioFactory);
+  }
+  if (params.animationData) {
+    this.setupAnimation(params.animationData);
+  } else if (params.path) {
+    if (params.path.lastIndexOf('\\') !== -1) {
+      this.path = params.path.substr(0, params.path.lastIndexOf('\\') + 1);
+    } else {
+      this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
+    }
+    this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
+    this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
+    dataManager.loadAnimation(
+      params.path,
+      this.configAnimation,
+      this.onSetupError
+    );
+  }
+};
+
+AnimationItem.prototype.onSetupError = function () {
+  this.trigger('data_failed');
+};
+
+AnimationItem.prototype.setupAnimation = function (data) {
+  dataManager.completeAnimation(
+    data,
+    this.configAnimation
+  );
+};
+
+AnimationItem.prototype.setData = function (wrapper, animationData) {
+  if (animationData) {
+    if (typeof animationData !== 'object') {
+      animationData = JSON.parse(animationData);
+    }
+  }
+  var params = {
+    wrapper: wrapper,
+    animationData: animationData,
+  };
+  var wrapperAttributes = wrapper.attributes;
+
+  params.path = wrapperAttributes.getNamedItem('data-animation-path') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-animation-path').value
+    : wrapperAttributes.getNamedItem('data-bm-path') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-path').value
+      : wrapperAttributes.getNamedItem('bm-path')
+        ? wrapperAttributes.getNamedItem('bm-path').value
+        : '';
+  params.animType = wrapperAttributes.getNamedItem('data-anim-type') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-type').value
+    : wrapperAttributes.getNamedItem('data-bm-type') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-type').value
+      : wrapperAttributes.getNamedItem('bm-type') // eslint-disable-line no-nested-ternary
+        ? wrapperAttributes.getNamedItem('bm-type').value
+        : wrapperAttributes.getNamedItem('data-bm-renderer') // eslint-disable-line no-nested-ternary
+          ? wrapperAttributes.getNamedItem('data-bm-renderer').value
+          : wrapperAttributes.getNamedItem('bm-renderer')
+            ? wrapperAttributes.getNamedItem('bm-renderer').value
+            : getRegisteredRenderer() || 'canvas';
+
+  var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-loop').value
+    : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-loop').value
+      : wrapperAttributes.getNamedItem('bm-loop')
+        ? wrapperAttributes.getNamedItem('bm-loop').value
+        : '';
+  if (loop === 'false') {
+    params.loop = false;
+  } else if (loop === 'true') {
+    params.loop = true;
+  } else if (loop !== '') {
+    params.loop = parseInt(loop, 10);
+  }
+  var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-autoplay').value
+    : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-autoplay').value
+      : wrapperAttributes.getNamedItem('bm-autoplay')
+        ? wrapperAttributes.getNamedItem('bm-autoplay').value
+        : true;
+  params.autoplay = autoplay !== 'false';
+
+  params.name = wrapperAttributes.getNamedItem('data-name') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-name').value
+    : wrapperAttributes.getNamedItem('data-bm-name') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-name').value
+      : wrapperAttributes.getNamedItem('bm-name')
+        ? wrapperAttributes.getNamedItem('bm-name').value
+        : '';
+  var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-prerender').value
+    : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-prerender').value
+      : wrapperAttributes.getNamedItem('bm-prerender')
+        ? wrapperAttributes.getNamedItem('bm-prerender').value
+        : '';
+
+  if (prerender === 'false') {
+    params.prerender = false;
+  }
+  if (!params.path) {
+    this.trigger('destroy');
+  } else {
+    this.setParams(params);
+  }
+};
+
+AnimationItem.prototype.includeLayers = function (data) {
+  if (data.op > this.animationData.op) {
+    this.animationData.op = data.op;
+    this.totalFrames = Math.floor(data.op - this.animationData.ip);
+  }
+  var layers = this.animationData.layers;
+  var i;
+  var len = layers.length;
+  var newLayers = data.layers;
+  var j;
+  var jLen = newLayers.length;
+  for (j = 0; j < jLen; j += 1) {
+    i = 0;
+    while (i < len) {
+      if (layers[i].id === newLayers[j].id) {
+        layers[i] = newLayers[j];
+        break;
+      }
+      i += 1;
+    }
+  }
+  if (data.chars || data.fonts) {
+    this.renderer.globalData.fontManager.addChars(data.chars);
+    this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
+  }
+  if (data.assets) {
+    len = data.assets.length;
+    for (i = 0; i < len; i += 1) {
+      this.animationData.assets.push(data.assets[i]);
+    }
+  }
+  this.animationData.__complete = false;
+  dataManager.completeAnimation(
+    this.animationData,
+    this.onSegmentComplete
+  );
+};
+
+AnimationItem.prototype.onSegmentComplete = function (data) {
+  this.animationData = data;
+  var expressionsPlugin = getExpressionsPlugin();
+  if (expressionsPlugin) {
+    expressionsPlugin.initExpressions(this);
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.loadNextSegment = function () {
+  var segments = this.animationData.segments;
+  if (!segments || segments.length === 0 || !this.autoloadSegments) {
+    this.trigger('data_ready');
+    this.timeCompleted = this.totalFrames;
+    return;
+  }
+  var segment = segments.shift();
+  this.timeCompleted = segment.time * this.frameRate;
+  var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
+  this.segmentPos += 1;
+  dataManager.loadData(segmentPath, this.includeLayers.bind(this), function () {
+    this.trigger('data_failed');
+  }.bind(this));
+};
+
+AnimationItem.prototype.loadSegments = function () {
+  var segments = this.animationData.segments;
+  if (!segments) {
+    this.timeCompleted = this.totalFrames;
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.imagesLoaded = function () {
+  this.trigger('loaded_images');
+  this.checkLoaded();
+};
+
+AnimationItem.prototype.preloadImages = function () {
+  this.imagePreloader.setAssetsPath(this.assetsPath);
+  this.imagePreloader.setPath(this.path);
+  this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
+};
+
+AnimationItem.prototype.configAnimation = function (animData) {
+  if (!this.renderer) {
+    return;
+  }
+  try {
+    this.animationData = animData;
+    if (this.initialSegment) {
+      this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
+      this.firstFrame = Math.round(this.initialSegment[0]);
+    } else {
+      this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
+      this.firstFrame = Math.round(this.animationData.ip);
+    }
+    this.renderer.configAnimation(animData);
+    if (!animData.assets) {
+      animData.assets = [];
+    }
+
+    this.assets = this.animationData.assets;
+    this.frameRate = this.animationData.fr;
+    this.frameMult = this.animationData.fr / 1000;
+    this.renderer.searchExtraCompositions(animData.assets);
+    this.markers = markerParser(animData.markers || []);
+    this.trigger('config_ready');
+    this.preloadImages();
+    this.loadSegments();
+    this.updaFrameModifier();
+    this.waitForFontsLoaded();
+    if (this.isPaused) {
+      this.audioController.pause();
+    }
+  } catch (error) {
+    this.triggerConfigError(error);
+  }
+};
+
+AnimationItem.prototype.waitForFontsLoaded = function () {
+  if (!this.renderer) {
+    return;
+  }
+  if (this.renderer.globalData.fontManager.isLoaded) {
+    this.checkLoaded();
+  } else {
+    setTimeout(this.waitForFontsLoaded.bind(this), 20);
+  }
+};
+
+AnimationItem.prototype.checkLoaded = function () {
+  if (!this.isLoaded
+        && this.renderer.globalData.fontManager.isLoaded
+        && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas')
+        && (this.imagePreloader.loadedFootages())
+  ) {
+    this.isLoaded = true;
+    var expressionsPlugin = getExpressionsPlugin();
+    if (expressionsPlugin) {
+      expressionsPlugin.initExpressions(this);
+    }
+    this.renderer.initItems();
+    setTimeout(function () {
+      this.trigger('DOMLoaded');
+    }.bind(this), 0);
+    this.gotoFrame();
+    if (this.autoplay) {
+      this.play();
+    }
+  }
+};
+
+AnimationItem.prototype.resize = function (width, height) {
+  // Adding this validation for backwards compatibility in case an event object was being passed down
+  var _width = typeof width === 'number' ? width : undefined;
+  var _height = typeof height === 'number' ? height : undefined;
+  this.renderer.updateContainerSize(_width, _height);
+};
+
+AnimationItem.prototype.setSubframe = function (flag) {
+  this.isSubframeEnabled = !!flag;
+};
+
+AnimationItem.prototype.gotoFrame = function () {
+  this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
+
+  if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
+    this.currentFrame = this.timeCompleted;
+  }
+  this.trigger('enterFrame');
+  this.renderFrame();
+  this.trigger('drawnFrame');
+};
+
+AnimationItem.prototype.renderFrame = function () {
+  if (this.isLoaded === false || !this.renderer) {
+    return;
+  }
+  try {
+    if (this.expressionsPlugin) {
+      this.expressionsPlugin.resetFrame();
+    }
+    this.renderer.renderFrame(this.currentFrame + this.firstFrame);
+  } catch (error) {
+    this.triggerRenderFrameError(error);
+  }
+};
+
+AnimationItem.prototype.play = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.isPaused = false;
+    this.trigger('_play');
+    this.audioController.resume();
+    if (this._idle) {
+      this._idle = false;
+      this.trigger('_active');
+    }
+  }
+};
+
+AnimationItem.prototype.pause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === false) {
+    this.isPaused = true;
+    this.trigger('_pause');
+    this._idle = true;
+    this.trigger('_idle');
+    this.audioController.pause();
+  }
+};
+
+AnimationItem.prototype.togglePause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.play();
+  } else {
+    this.pause();
+  }
+};
+
+AnimationItem.prototype.stop = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.pause();
+  this.playCount = 0;
+  this._completedLoop = false;
+  this.setCurrentRawFrameValue(0);
+};
+
+AnimationItem.prototype.getMarkerData = function (markerName) {
+  var marker;
+  for (var i = 0; i < this.markers.length; i += 1) {
+    marker = this.markers[i];
+    if (marker.payload && marker.payload.name === markerName) {
+      return marker;
+    }
+  }
+  return null;
+};
+
+AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      this.goToAndStop(marker.time, true);
+    }
+  } else if (isFrame) {
+    this.setCurrentRawFrameValue(value);
+  } else {
+    this.setCurrentRawFrameValue(value * this.frameModifier);
+  }
+  this.pause();
+};
+
+AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      if (!marker.duration) {
+        this.goToAndStop(marker.time, true);
+      } else {
+        this.playSegments([marker.time, marker.time + marker.duration], true);
+      }
+    }
+  } else {
+    this.goToAndStop(numValue, isFrame, name);
+  }
+  this.play();
+};
+
+AnimationItem.prototype.advanceTime = function (value) {
+  if (this.isPaused === true || this.isLoaded === false) {
+    return;
+  }
+  var nextValue = this.currentRawFrame + value * this.frameModifier;
+  var _isComplete = false;
+  // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+  // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
+  if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
+    if (!this.loop || this.playCount === this.loop) {
+      if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
+        _isComplete = true;
+        nextValue = this.totalFrames - 1;
+      }
+    } else if (nextValue >= this.totalFrames) {
+      this.playCount += 1;
+      if (!this.checkSegments(nextValue % this.totalFrames)) {
+        this.setCurrentRawFrameValue(nextValue % this.totalFrames);
+        this._completedLoop = true;
+        this.trigger('loopComplete');
+      }
+    } else {
+      this.setCurrentRawFrameValue(nextValue);
+    }
+  } else if (nextValue < 0) {
+    if (!this.checkSegments(nextValue % this.totalFrames)) {
+      if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) { // eslint-disable-line no-plusplus
+        this.setCurrentRawFrameValue(this.totalFrames + (nextValue % this.totalFrames));
+        if (!this._completedLoop) {
+          this._completedLoop = true;
+        } else {
+          this.trigger('loopComplete');
+        }
+      } else {
+        _isComplete = true;
+        nextValue = 0;
+      }
+    }
+  } else {
+    this.setCurrentRawFrameValue(nextValue);
+  }
+  if (_isComplete) {
+    this.setCurrentRawFrameValue(nextValue);
+    this.pause();
+    this.trigger('complete');
+  }
+};
+
+AnimationItem.prototype.adjustSegment = function (arr, offset) {
+  this.playCount = 0;
+  if (arr[1] < arr[0]) {
+    if (this.frameModifier > 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(-1);
+      }
+    }
+    this.totalFrames = arr[0] - arr[1];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[1];
+    this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset);
+  } else if (arr[1] > arr[0]) {
+    if (this.frameModifier < 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(1);
+      }
+    }
+    this.totalFrames = arr[1] - arr[0];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[0];
+    this.setCurrentRawFrameValue(0.001 + offset);
+  }
+  this.trigger('segmentStart');
+};
+AnimationItem.prototype.setSegment = function (init, end) {
+  var pendingFrame = -1;
+  if (this.isPaused) {
+    if (this.currentRawFrame + this.firstFrame < init) {
+      pendingFrame = init;
+    } else if (this.currentRawFrame + this.firstFrame > end) {
+      pendingFrame = end - init;
+    }
+  }
+
+  this.firstFrame = init;
+  this.totalFrames = end - init;
+  this.timeCompleted = this.totalFrames;
+  if (pendingFrame !== -1) {
+    this.goToAndStop(pendingFrame, true);
+  }
+};
+
+AnimationItem.prototype.playSegments = function (arr, forceFlag) {
+  if (forceFlag) {
+    this.segments.length = 0;
+  }
+  if (typeof arr[0] === 'object') {
+    var i;
+    var len = arr.length;
+    for (i = 0; i < len; i += 1) {
+      this.segments.push(arr[i]);
+    }
+  } else {
+    this.segments.push(arr);
+  }
+  if (this.segments.length && forceFlag) {
+    this.adjustSegment(this.segments.shift(), 0);
+  }
+  if (this.isPaused) {
+    this.play();
+  }
+};
+
+AnimationItem.prototype.resetSegments = function (forceFlag) {
+  this.segments.length = 0;
+  this.segments.push([this.animationData.ip, this.animationData.op]);
+  if (forceFlag) {
+    this.checkSegments(0);
+  }
+};
+AnimationItem.prototype.checkSegments = function (offset) {
+  if (this.segments.length) {
+    this.adjustSegment(this.segments.shift(), offset);
+    return true;
+  }
+  return false;
+};
+
+AnimationItem.prototype.destroy = function (name) {
+  if ((name && this.name !== name) || !this.renderer) {
+    return;
+  }
+  this.renderer.destroy();
+  this.imagePreloader.destroy();
+  this.trigger('destroy');
+  this._cbs = null;
+  this.onEnterFrame = null;
+  this.onLoopComplete = null;
+  this.onComplete = null;
+  this.onSegmentStart = null;
+  this.onDestroy = null;
+  this.renderer = null;
+  this.expressionsPlugin = null;
+  this.imagePreloader = null;
+  this.projectInterface = null;
+};
+
+AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
+  this.currentRawFrame = value;
+  this.gotoFrame();
+};
+
+AnimationItem.prototype.setSpeed = function (val) {
+  this.playSpeed = val;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setDirection = function (val) {
+  this.playDirection = val < 0 ? -1 : 1;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setLoop = function (isLooping) {
+  this.loop = isLooping;
+};
+
+AnimationItem.prototype.setVolume = function (val, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.setVolume(val);
+};
+
+AnimationItem.prototype.getVolume = function () {
+  return this.audioController.getVolume();
+};
+
+AnimationItem.prototype.mute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.mute();
+};
+
+AnimationItem.prototype.unmute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.unmute();
+};
+
+AnimationItem.prototype.updaFrameModifier = function () {
+  this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
+  this.audioController.setRate(this.playSpeed * this.playDirection);
+};
+
+AnimationItem.prototype.getPath = function () {
+  return this.path;
+};
+
+AnimationItem.prototype.getAssetsPath = function (assetData) {
+  var path = '';
+  if (assetData.e) {
+    path = assetData.p;
+  } else if (this.assetsPath) {
+    var imagePath = assetData.p;
+    if (imagePath.indexOf('images/') !== -1) {
+      imagePath = imagePath.split('/')[1];
+    }
+    path = this.assetsPath + imagePath;
+  } else {
+    path = this.path;
+    path += assetData.u ? assetData.u : '';
+    path += assetData.p;
+  }
+  return path;
+};
+
+AnimationItem.prototype.getAssetData = function (id) {
+  var i = 0;
+  var len = this.assets.length;
+  while (i < len) {
+    if (id === this.assets[i].id) {
+      return this.assets[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+AnimationItem.prototype.hide = function () {
+  this.renderer.hide();
+};
+
+AnimationItem.prototype.show = function () {
+  this.renderer.show();
+};
+
+AnimationItem.prototype.getDuration = function (isFrame) {
+  return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
+};
+
+AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
+  try {
+    var element = this.renderer.getElementByPath(path);
+    element.updateDocumentData(documentData, index);
+  } catch (error) {
+    // TODO: decide how to handle catch case
+  }
+};
+
+AnimationItem.prototype.trigger = function (name) {
+  if (this._cbs && this._cbs[name]) {
+    switch (name) {
+      case 'enterFrame':
+        this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
+        break;
+      case 'drawnFrame':
+        this.drawnFrameEvent.currentTime = this.currentFrame;
+        this.drawnFrameEvent.totalTime = this.totalFrames;
+        this.drawnFrameEvent.direction = this.frameModifier;
+        this.triggerEvent(name, this.drawnFrameEvent);
+        break;
+      case 'loopComplete':
+        this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+        break;
+      case 'complete':
+        this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
+        break;
+      case 'segmentStart':
+        this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+        break;
+      case 'destroy':
+        this.triggerEvent(name, new BMDestroyEvent(name, this));
+        break;
+      default:
+        this.triggerEvent(name);
+    }
+  }
+  if (name === 'enterFrame' && this.onEnterFrame) {
+    this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
+  }
+  if (name === 'loopComplete' && this.onLoopComplete) {
+    this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+  }
+  if (name === 'complete' && this.onComplete) {
+    this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
+  }
+  if (name === 'segmentStart' && this.onSegmentStart) {
+    this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+  }
+  if (name === 'destroy' && this.onDestroy) {
+    this.onDestroy.call(this, new BMDestroyEvent(name, this));
+  }
+};
+
+AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
+  var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+AnimationItem.prototype.triggerConfigError = function (nativeError) {
+  var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+const animationManager = (function () {
+  var moduleOb = {};
+  var registeredAnimations = [];
+  var initTime = 0;
+  var len = 0;
+  var playingAnimationsNum = 0;
+  var _stopped = true;
+  var _isFrozen = false;
+
+  function removeElement(ev) {
+    var i = 0;
+    var animItem = ev.target;
+    while (i < len) {
+      if (registeredAnimations[i].animation === animItem) {
+        registeredAnimations.splice(i, 1);
+        i -= 1;
+        len -= 1;
+        if (!animItem.isPaused) {
+          subtractPlayingCount();
+        }
+      }
+      i += 1;
+    }
+  }
+
+  function registerAnimation(element, animationData) {
+    if (!element) {
+      return null;
+    }
+    var i = 0;
+    while (i < len) {
+      if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
+        return registeredAnimations[i].animation;
+      }
+      i += 1;
+    }
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, element);
+    animItem.setData(element, animationData);
+    return animItem;
+  }
+
+  function getRegisteredAnimations() {
+    var i;
+    var lenAnims = registeredAnimations.length;
+    var animations = [];
+    for (i = 0; i < lenAnims; i += 1) {
+      animations.push(registeredAnimations[i].animation);
+    }
+    return animations;
+  }
+
+  function addPlayingCount() {
+    playingAnimationsNum += 1;
+    activate();
+  }
+
+  function subtractPlayingCount() {
+    playingAnimationsNum -= 1;
+  }
+
+  function setupAnimation(animItem, element) {
+    animItem.addEventListener('destroy', removeElement);
+    animItem.addEventListener('_active', addPlayingCount);
+    animItem.addEventListener('_idle', subtractPlayingCount);
+    registeredAnimations.push({ elem: element, animation: animItem });
+    len += 1;
+  }
+
+  function loadAnimation(params) {
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, null);
+    animItem.setParams(params);
+    return animItem;
+  }
+
+  function setSpeed(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setSpeed(val, animation);
+    }
+  }
+
+  function setDirection(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setDirection(val, animation);
+    }
+  }
+
+  function play(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.play(animation);
+    }
+  }
+  function resume(nowTime) {
+    var elapsedTime = nowTime - initTime;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.advanceTime(elapsedTime);
+    }
+    initTime = nowTime;
+    if (playingAnimationsNum && !_isFrozen) {
+      window.requestAnimationFrame(resume);
+    } else {
+      _stopped = true;
+    }
+  }
+
+  function first(nowTime) {
+    initTime = nowTime;
+    window.requestAnimationFrame(resume);
+  }
+
+  function pause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.pause(animation);
+    }
+  }
+
+  function goToAndStop(value, isFrame, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
+    }
+  }
+
+  function stop(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.stop(animation);
+    }
+  }
+
+  function togglePause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.togglePause(animation);
+    }
+  }
+
+  function destroy(animation) {
+    var i;
+    for (i = (len - 1); i >= 0; i -= 1) {
+      registeredAnimations[i].animation.destroy(animation);
+    }
+  }
+
+  function searchAnimations(animationData, standalone, renderer) {
+    var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')),
+      [].slice.call(document.getElementsByClassName('bodymovin')));
+    var i;
+    var lenAnims = animElements.length;
+    for (i = 0; i < lenAnims; i += 1) {
+      if (renderer) {
+        animElements[i].setAttribute('data-bm-type', renderer);
+      }
+      registerAnimation(animElements[i], animationData);
+    }
+    if (standalone && lenAnims === 0) {
+      if (!renderer) {
+        renderer = 'svg';
+      }
+      var body = document.getElementsByTagName('body')[0];
+      body.innerText = '';
+      var div = createTag('div');
+      div.style.width = '100%';
+      div.style.height = '100%';
+      div.setAttribute('data-bm-type', renderer);
+      body.appendChild(div);
+      registerAnimation(div, animationData);
+    }
+  }
+
+  function resize() {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.resize();
+    }
+  }
+
+  function activate() {
+    if (!_isFrozen && playingAnimationsNum) {
+      if (_stopped) {
+        window.requestAnimationFrame(first);
+        _stopped = false;
+      }
+    }
+  }
+
+  function freeze() {
+    _isFrozen = true;
+  }
+
+  function unfreeze() {
+    _isFrozen = false;
+    activate();
+  }
+
+  function setVolume(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setVolume(val, animation);
+    }
+  }
+
+  function mute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.mute(animation);
+    }
+  }
+
+  function unmute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.unmute(animation);
+    }
+  }
+
+  moduleOb.registerAnimation = registerAnimation;
+  moduleOb.loadAnimation = loadAnimation;
+  moduleOb.setSpeed = setSpeed;
+  moduleOb.setDirection = setDirection;
+  moduleOb.play = play;
+  moduleOb.pause = pause;
+  moduleOb.stop = stop;
+  moduleOb.togglePause = togglePause;
+  moduleOb.searchAnimations = searchAnimations;
+  moduleOb.resize = resize;
+  // moduleOb.start = start;
+  moduleOb.goToAndStop = goToAndStop;
+  moduleOb.destroy = destroy;
+  moduleOb.freeze = freeze;
+  moduleOb.unfreeze = unfreeze;
+  moduleOb.setVolume = setVolume;
+  moduleOb.mute = mute;
+  moduleOb.unmute = unmute;
+  moduleOb.getRegisteredAnimations = getRegisteredAnimations;
+  return moduleOb;
+}());
+
+/* eslint-disable */
+const BezierFactory = (function () {
+  /**
+     * BezierEasing - use bezier curve for transition easing function
+     * by Gaëtan Renaudeau 2014 - 2015 – MIT License
+     *
+     * Credits: is based on Firefox's nsSMILKeySpline.cpp
+     * Usage:
+     * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
+     * spline.get(x) => returns the easing value | x must be in [0, 1] range
+     *
+     */
+
+  var ob = {};
+  ob.getBezierEasing = getBezierEasing;
+  var beziers = {};
+
+  function getBezierEasing(a, b, c, d, nm) {
+    var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
+    if (beziers[str]) {
+      return beziers[str];
+    }
+    var bezEasing = new BezierEasing([a, b, c, d]);
+    beziers[str] = bezEasing;
+    return bezEasing;
+  }
+
+  // These values are established by empiricism with tests (tradeoff: performance VS precision)
+  var NEWTON_ITERATIONS = 4;
+  var NEWTON_MIN_SLOPE = 0.001;
+  var SUBDIVISION_PRECISION = 0.0000001;
+  var SUBDIVISION_MAX_ITERATIONS = 10;
+
+  var kSplineTableSize = 11;
+  var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
+
+  var float32ArraySupported = typeof Float32Array === 'function';
+
+  function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
+  function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
+  function C(aA1) { return 3.0 * aA1; }
+
+  // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+  function calcBezier(aT, aA1, aA2) {
+    return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
+  }
+
+  // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+  function getSlope(aT, aA1, aA2) {
+    return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
+  }
+
+  function binarySubdivide(aX, aA, aB, mX1, mX2) {
+    var currentX,
+      currentT,
+      i = 0;
+    do {
+      currentT = aA + (aB - aA) / 2.0;
+      currentX = calcBezier(currentT, mX1, mX2) - aX;
+      if (currentX > 0.0) {
+        aB = currentT;
+      } else {
+        aA = currentT;
+      }
+    } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
+    return currentT;
+  }
+
+  function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
+    for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
+      var currentSlope = getSlope(aGuessT, mX1, mX2);
+      if (currentSlope === 0.0) return aGuessT;
+      var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
+      aGuessT -= currentX / currentSlope;
+    }
+    return aGuessT;
+  }
+
+  /**
+     * points is an array of [ mX1, mY1, mX2, mY2 ]
+     */
+  function BezierEasing(points) {
+    this._p = points;
+    this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
+    this._precomputed = false;
+
+    this.get = this.get.bind(this);
+  }
+
+  BezierEasing.prototype = {
+
+    get: function (x) {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      if (!this._precomputed) this._precompute();
+      if (mX1 === mY1 && mX2 === mY2) return x; // linear
+      // Because JavaScript number are imprecise, we should guarantee the extremes are right.
+      if (x === 0) return 0;
+      if (x === 1) return 1;
+      return calcBezier(this._getTForX(x), mY1, mY2);
+    },
+
+    // Private part
+
+    _precompute: function () {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      this._precomputed = true;
+      if (mX1 !== mY1 || mX2 !== mY2) { this._calcSampleValues(); }
+    },
+
+    _calcSampleValues: function () {
+      var mX1 = this._p[0],
+        mX2 = this._p[2];
+      for (var i = 0; i < kSplineTableSize; ++i) {
+        this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
+      }
+    },
+
+    /**
+         * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
+         */
+    _getTForX: function (aX) {
+      var mX1 = this._p[0],
+        mX2 = this._p[2],
+        mSampleValues = this._mSampleValues;
+
+      var intervalStart = 0.0;
+      var currentSample = 1;
+      var lastSample = kSplineTableSize - 1;
+
+      for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
+        intervalStart += kSampleStepSize;
+      }
+      --currentSample;
+
+      // Interpolate to provide an initial guess for t
+      var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
+      var guessForT = intervalStart + dist * kSampleStepSize;
+
+      var initialSlope = getSlope(guessForT, mX1, mX2);
+      if (initialSlope >= NEWTON_MIN_SLOPE) {
+        return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
+      } if (initialSlope === 0.0) {
+        return guessForT;
+      }
+      return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
+    },
+  };
+
+  return ob;
+}());
+
+const pooling = (function () {
+  function double(arr) {
+    return arr.concat(createSizedArray(arr.length));
+  }
+
+  return {
+    double: double,
+  };
+}());
+
+const poolFactory = (function () {
+  return function (initialLength, _create, _release) {
+    var _length = 0;
+    var _maxLength = initialLength;
+    var pool = createSizedArray(_maxLength);
+
+    var ob = {
+      newElement: newElement,
+      release: release,
+    };
+
+    function newElement() {
+      var element;
+      if (_length) {
+        _length -= 1;
+        element = pool[_length];
+      } else {
+        element = _create();
+      }
+      return element;
+    }
+
+    function release(element) {
+      if (_length === _maxLength) {
+        pool = pooling.double(pool);
+        _maxLength *= 2;
+      }
+      if (_release) {
+        _release(element);
+      }
+      pool[_length] = element;
+      _length += 1;
+    }
+
+    return ob;
+  };
+}());
+
+const bezierLengthPool = (function () {
+  function create() {
+    return {
+      addedLength: 0,
+      percents: createTypedArray('float32', getDefaultCurveSegments()),
+      lengths: createTypedArray('float32', getDefaultCurveSegments()),
+    };
+  }
+  return poolFactory(8, create);
+}());
+
+const segmentsLengthPool = (function () {
+  function create() {
+    return {
+      lengths: [],
+      totalLength: 0,
+    };
+  }
+
+  function release(element) {
+    var i;
+    var len = element.lengths.length;
+    for (i = 0; i < len; i += 1) {
+      bezierLengthPool.release(element.lengths[i]);
+    }
+    element.lengths.length = 0;
+  }
+
+  return poolFactory(8, create, release);
+}());
+
+function bezFunction() {
+  var math = Math;
+
+  function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
+    var det1 = (x1 * y2) + (y1 * x3) + (x2 * y3) - (x3 * y2) - (y3 * x1) - (x2 * y1);
+    return det1 > -0.001 && det1 < 0.001;
+  }
+
+  function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
+    if (z1 === 0 && z2 === 0 && z3 === 0) {
+      return pointOnLine2D(x1, y1, x2, y2, x3, y3);
+    }
+    var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
+    var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
+    var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
+    var diffDist;
+    if (dist1 > dist2) {
+      if (dist1 > dist3) {
+        diffDist = dist1 - dist2 - dist3;
+      } else {
+        diffDist = dist3 - dist2 - dist1;
+      }
+    } else if (dist3 > dist2) {
+      diffDist = dist3 - dist2 - dist1;
+    } else {
+      diffDist = dist2 - dist1 - dist3;
+    }
+    return diffDist > -0.0001 && diffDist < 0.0001;
+  }
+
+  var getBezierLength = (function () {
+    return function (pt1, pt2, pt3, pt4) {
+      var curveSegments = getDefaultCurveSegments();
+      var k;
+      var i;
+      var len;
+      var ptCoord;
+      var perc;
+      var addedLength = 0;
+      var ptDistance;
+      var point = [];
+      var lastPoint = [];
+      var lengthData = bezierLengthPool.newElement();
+      len = pt3.length;
+      for (k = 0; k < curveSegments; k += 1) {
+        perc = k / (curveSegments - 1);
+        ptDistance = 0;
+        for (i = 0; i < len; i += 1) {
+          ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
+          point[i] = ptCoord;
+          if (lastPoint[i] !== null) {
+            ptDistance += bmPow(point[i] - lastPoint[i], 2);
+          }
+          lastPoint[i] = point[i];
+        }
+        if (ptDistance) {
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+        }
+        lengthData.percents[k] = perc;
+        lengthData.lengths[k] = addedLength;
+      }
+      lengthData.addedLength = addedLength;
+      return lengthData;
+    };
+  }());
+
+  function getSegmentsLength(shapeData) {
+    var segmentsLength = segmentsLengthPool.newElement();
+    var closed = shapeData.c;
+    var pathV = shapeData.v;
+    var pathO = shapeData.o;
+    var pathI = shapeData.i;
+    var i;
+    var len = shapeData._length;
+    var lengths = segmentsLength.lengths;
+    var totalLength = 0;
+    for (i = 0; i < len - 1; i += 1) {
+      lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
+      totalLength += lengths[i].addedLength;
+    }
+    if (closed && len) {
+      lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
+      totalLength += lengths[i].addedLength;
+    }
+    segmentsLength.totalLength = totalLength;
+    return segmentsLength;
+  }
+
+  function BezierData(length) {
+    this.segmentLength = 0;
+    this.points = new Array(length);
+  }
+
+  function PointData(partial, point) {
+    this.partialLength = partial;
+    this.point = point;
+  }
+
+  var buildBezierData = (function () {
+    var storedData = {};
+
+    return function (pt1, pt2, pt3, pt4) {
+      var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
+      if (!storedData[bezierName]) {
+        var curveSegments = getDefaultCurveSegments();
+        var k;
+        var i;
+        var len;
+        var ptCoord;
+        var perc;
+        var addedLength = 0;
+        var ptDistance;
+        var point;
+        var lastPoint = null;
+        if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
+          curveSegments = 2;
+        }
+        var bezierData = new BezierData(curveSegments);
+        len = pt3.length;
+        for (k = 0; k < curveSegments; k += 1) {
+          point = createSizedArray(len);
+          perc = k / (curveSegments - 1);
+          ptDistance = 0;
+          for (i = 0; i < len; i += 1) {
+            ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
+            point[i] = ptCoord;
+            if (lastPoint !== null) {
+              ptDistance += bmPow(point[i] - lastPoint[i], 2);
+            }
+          }
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+          bezierData.points[k] = new PointData(ptDistance, point);
+          lastPoint = point;
+        }
+        bezierData.segmentLength = addedLength;
+        storedData[bezierName] = bezierData;
+      }
+      return storedData[bezierName];
+    };
+  }());
+
+  function getDistancePerc(perc, bezierData) {
+    var percents = bezierData.percents;
+    var lengths = bezierData.lengths;
+    var len = percents.length;
+    var initPos = bmFloor((len - 1) * perc);
+    var lengthPos = perc * bezierData.addedLength;
+    var lPerc = 0;
+    if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
+      return percents[initPos];
+    }
+    var dir = lengths[initPos] > lengthPos ? -1 : 1;
+    var flag = true;
+    while (flag) {
+      if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
+        lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
+        flag = false;
+      } else {
+        initPos += dir;
+      }
+      if (initPos < 0 || initPos >= len - 1) {
+        // FIX for TypedArrays that don't store floating point values with enough accuracy
+        if (initPos === len - 1) {
+          return percents[initPos];
+        }
+        flag = false;
+      }
+    }
+    return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
+  }
+
+  function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
+    var t1 = getDistancePerc(percent, bezierData);
+    var u1 = 1 - t1;
+    var ptX = math.round((u1 * u1 * u1 * pt1[0] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[0] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[0] + t1 * t1 * t1 * pt2[0]) * 1000) / 1000;
+    var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
+    return [ptX, ptY];
+  }
+
+  var bezierSegmentPoints = createTypedArray('float32', 8);
+
+  function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
+    if (startPerc < 0) {
+      startPerc = 0;
+    } else if (startPerc > 1) {
+      startPerc = 1;
+    }
+    var t0 = getDistancePerc(startPerc, bezierData);
+    endPerc = endPerc > 1 ? 1 : endPerc;
+    var t1 = getDistancePerc(endPerc, bezierData);
+    var i;
+    var len = pt1.length;
+    var u0 = 1 - t0;
+    var u1 = 1 - t1;
+    var u0u0u0 = u0 * u0 * u0;
+    var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0t0 = t0 * t0 * t0;
+    //
+    var u0u0u1 = u0 * u0 * u1;
+    var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0t1 = t0 * t0 * t1;
+    //
+    var u0u1u1 = u0 * u1 * u1;
+    var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1t1 = t0 * t1 * t1;
+    //
+    var u1u1u1 = u1 * u1 * u1;
+    var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1t1 = t1 * t1 * t1;
+    for (i = 0; i < len; i += 1) {
+      bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+    }
+
+    return bezierSegmentPoints;
+  }
+
+  return {
+    getSegmentsLength: getSegmentsLength,
+    getNewSegment: getNewSegment,
+    getPointInSegment: getPointInSegment,
+    buildBezierData: buildBezierData,
+    pointOnLine2D: pointOnLine2D,
+    pointOnLine3D: pointOnLine3D,
+  };
+}
+
+const bez = bezFunction();
+
+var initFrame = initialDefaultFrame;
+var mathAbs = Math.abs;
+
+function interpolateValue(frameNum, caching) {
+  var offsetTime = this.offsetTime;
+  var newValue;
+  if (this.propType === 'multidimensional') {
+    newValue = createTypedArray('float32', this.pv.length);
+  }
+  var iterationIndex = caching.lastIndex;
+  var i = iterationIndex;
+  var len = this.keyframes.length - 1;
+  var flag = true;
+  var keyData;
+  var nextKeyData;
+  var keyframeMetadata;
+
+  while (flag) {
+    keyData = this.keyframes[i];
+    nextKeyData = this.keyframes[i + 1];
+    if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
+      if (keyData.h) {
+        keyData = nextKeyData;
+      }
+      iterationIndex = 0;
+      break;
+    }
+    if ((nextKeyData.t - offsetTime) > frameNum) {
+      iterationIndex = i;
+      break;
+    }
+    if (i < len - 1) {
+      i += 1;
+    } else {
+      iterationIndex = 0;
+      flag = false;
+    }
+  }
+  keyframeMetadata = this.keyframesMetadata[i] || {};
+
+  var k;
+  var kLen;
+  var perc;
+  var jLen;
+  var j;
+  var fnc;
+  var nextKeyTime = nextKeyData.t - offsetTime;
+  var keyTime = keyData.t - offsetTime;
+  var endValue;
+  if (keyData.to) {
+    if (!keyframeMetadata.bezierData) {
+      keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
+    }
+    var bezierData = keyframeMetadata.bezierData;
+    if (frameNum >= nextKeyTime || frameNum < keyTime) {
+      var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
+      kLen = bezierData.points[ind].point.length;
+      for (k = 0; k < kLen; k += 1) {
+        newValue[k] = bezierData.points[ind].point[k];
+      }
+      // caching._lastKeyframeIndex = -1;
+    } else {
+      if (keyframeMetadata.__fnct) {
+        fnc = keyframeMetadata.__fnct;
+      } else {
+        fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
+        keyframeMetadata.__fnct = fnc;
+      }
+      perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+      var distanceInLine = bezierData.segmentLength * perc;
+
+      var segmentPerc;
+      var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0;
+      j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0;
+      flag = true;
+      jLen = bezierData.points.length;
+      while (flag) {
+        addedLength += bezierData.points[j].partialLength;
+        if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k];
+          }
+          break;
+        } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
+          segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
+          }
+          break;
+        }
+        if (j < jLen - 1) {
+          j += 1;
+        } else {
+          flag = false;
+        }
+      }
+      caching._lastPoint = j;
+      caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
+      caching._lastKeyframeIndex = i;
+    }
+  } else {
+    var outX;
+    var outY;
+    var inX;
+    var inY;
+    var keyValue;
+    len = keyData.s.length;
+    endValue = nextKeyData.s || keyData.e;
+    if (this.sh && keyData.h !== 1) {
+      if (frameNum >= nextKeyTime) {
+        newValue[0] = endValue[0];
+        newValue[1] = endValue[1];
+        newValue[2] = endValue[2];
+      } else if (frameNum <= keyTime) {
+        newValue[0] = keyData.s[0];
+        newValue[1] = keyData.s[1];
+        newValue[2] = keyData.s[2];
+      } else {
+        var quatStart = createQuaternion(keyData.s);
+        var quatEnd = createQuaternion(endValue);
+        var time = (frameNum - keyTime) / (nextKeyTime - keyTime);
+        quaternionToEuler(newValue, slerp(quatStart, quatEnd, time));
+      }
+    } else {
+      for (i = 0; i < len; i += 1) {
+        if (keyData.h !== 1) {
+          if (frameNum >= nextKeyTime) {
+            perc = 1;
+          } else if (frameNum < keyTime) {
+            perc = 0;
+          } else {
+            if (keyData.o.x.constructor === Array) {
+              if (!keyframeMetadata.__fnct) {
+                keyframeMetadata.__fnct = [];
+              }
+              if (!keyframeMetadata.__fnct[i]) {
+                outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
+                outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
+                inX = keyData.i.x[i] === undefined ? keyData.i.x[0] : keyData.i.x[i];
+                inY = keyData.i.y[i] === undefined ? keyData.i.y[0] : keyData.i.y[i];
+                fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+                keyframeMetadata.__fnct[i] = fnc;
+              } else {
+                fnc = keyframeMetadata.__fnct[i];
+              }
+            } else if (!keyframeMetadata.__fnct) {
+              outX = keyData.o.x;
+              outY = keyData.o.y;
+              inX = keyData.i.x;
+              inY = keyData.i.y;
+              fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+              keyData.keyframeMetadata = fnc;
+            } else {
+              fnc = keyframeMetadata.__fnct;
+            }
+            perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+          }
+        }
+
+        endValue = nextKeyData.s || keyData.e;
+        keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
+
+        if (this.propType === 'multidimensional') {
+          newValue[i] = keyValue;
+        } else {
+          newValue = keyValue;
+        }
+      }
+    }
+  }
+  caching.lastIndex = iterationIndex;
+  return newValue;
+}
+
+// based on @Toji's https://github.com/toji/gl-matrix/
+function slerp(a, b, t) {
+  var out = [];
+  var ax = a[0];
+  var ay = a[1];
+  var az = a[2];
+  var aw = a[3];
+  var bx = b[0];
+  var by = b[1];
+  var bz = b[2];
+  var bw = b[3];
+
+  var omega;
+  var cosom;
+  var sinom;
+  var scale0;
+  var scale1;
+
+  cosom = ax * bx + ay * by + az * bz + aw * bw;
+  if (cosom < 0.0) {
+    cosom = -cosom;
+    bx = -bx;
+    by = -by;
+    bz = -bz;
+    bw = -bw;
+  }
+  if ((1.0 - cosom) > 0.000001) {
+    omega = Math.acos(cosom);
+    sinom = Math.sin(omega);
+    scale0 = Math.sin((1.0 - t) * omega) / sinom;
+    scale1 = Math.sin(t * omega) / sinom;
+  } else {
+    scale0 = 1.0 - t;
+    scale1 = t;
+  }
+  out[0] = scale0 * ax + scale1 * bx;
+  out[1] = scale0 * ay + scale1 * by;
+  out[2] = scale0 * az + scale1 * bz;
+  out[3] = scale0 * aw + scale1 * bw;
+
+  return out;
+}
+
+function quaternionToEuler(out, quat) {
+  var qx = quat[0];
+  var qy = quat[1];
+  var qz = quat[2];
+  var qw = quat[3];
+  var heading = Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy * qy - 2 * qz * qz);
+  var attitude = Math.asin(2 * qx * qy + 2 * qz * qw);
+  var bank = Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx * qx - 2 * qz * qz);
+  out[0] = heading / degToRads;
+  out[1] = attitude / degToRads;
+  out[2] = bank / degToRads;
+}
+
+function createQuaternion(values) {
+  var heading = values[0] * degToRads;
+  var attitude = values[1] * degToRads;
+  var bank = values[2] * degToRads;
+  var c1 = Math.cos(heading / 2);
+  var c2 = Math.cos(attitude / 2);
+  var c3 = Math.cos(bank / 2);
+  var s1 = Math.sin(heading / 2);
+  var s2 = Math.sin(attitude / 2);
+  var s3 = Math.sin(bank / 2);
+  var w = c1 * c2 * c3 - s1 * s2 * s3;
+  var x = s1 * s2 * c3 + c1 * c2 * s3;
+  var y = s1 * c2 * c3 + c1 * s2 * s3;
+  var z = c1 * s2 * c3 - s1 * c2 * s3;
+
+  return [x, y, z, w];
+}
+
+function getValueAtCurrentTime() {
+  var frameNum = this.comp.renderedFrame - this.offsetTime;
+  var initTime = this.keyframes[0].t - this.offsetTime;
+  var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+  if (!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))) {
+    if (this._caching.lastFrame >= frameNum) {
+      this._caching._lastKeyframeIndex = -1;
+      this._caching.lastIndex = 0;
+    }
+
+    var renderResult = this.interpolateValue(frameNum, this._caching);
+    this.pv = renderResult;
+  }
+  this._caching.lastFrame = frameNum;
+  return this.pv;
+}
+
+function setVValue(val) {
+  var multipliedValue;
+  if (this.propType === 'unidimensional') {
+    multipliedValue = val * this.mult;
+    if (mathAbs(this.v - multipliedValue) > 0.00001) {
+      this.v = multipliedValue;
+      this._mdf = true;
+    }
+  } else {
+    var i = 0;
+    var len = this.v.length;
+    while (i < len) {
+      multipliedValue = val[i] * this.mult;
+      if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
+        this.v[i] = multipliedValue;
+        this._mdf = true;
+      }
+      i += 1;
+    }
+  }
+}
+
+function processEffectsSequence() {
+  if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
+    return;
+  }
+  if (this.lock) {
+    this.setVValue(this.pv);
+    return;
+  }
+  this.lock = true;
+  this._mdf = this._isFirstFrame;
+  var i;
+  var len = this.effectsSequence.length;
+  var finalValue = this.kf ? this.pv : this.data.k;
+  for (i = 0; i < len; i += 1) {
+    finalValue = this.effectsSequence[i](finalValue);
+  }
+  this.setVValue(finalValue);
+  this._isFirstFrame = false;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+}
+
+function addEffect(effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.container.addDynamicProperty(this);
+}
+
+function ValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this.v = mult ? data.k * mult : data.k;
+  this.pv = data.k;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.vel = 0;
+  this.effectsSequence = [];
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function MultiDimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.frameId = -1;
+  var i;
+  var len = data.k.length;
+  this.v = createTypedArray('float32', len);
+  this.pv = createTypedArray('float32', len);
+  this.vel = createTypedArray('float32', len);
+  for (i = 0; i < len; i += 1) {
+    this.v[i] = data.k[i] * this.mult;
+    this.pv[i] = data.k[i];
+  }
+  this._isFirstFrame = true;
+  this.effectsSequence = [];
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function KeyframedValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.frameId = -1;
+  this._caching = {
+    lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1,
+  };
+  this.k = true;
+  this.kf = true;
+  this.data = data;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.v = initFrame;
+  this.pv = initFrame;
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.addEffect = addEffect;
+}
+
+function KeyframedMultidimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  var i;
+  var len = data.k.length;
+  var s;
+  var e;
+  var to;
+  var ti;
+  for (i = 0; i < len - 1; i += 1) {
+    if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
+      s = data.k[i].s;
+      e = data.k[i + 1].s;
+      to = data.k[i].to;
+      ti = data.k[i].ti;
+      if ((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2]))) {
+        data.k[i].to = null;
+        data.k[i].ti = null;
+      }
+      if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
+        if (s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) {
+          data.k[i].to = null;
+          data.k[i].ti = null;
+        }
+      }
+    }
+  }
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.data = data;
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.k = true;
+  this.kf = true;
+  this._isFirstFrame = true;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.frameId = -1;
+  var arrLen = data.k[0].s.length;
+  this.v = createTypedArray('float32', arrLen);
+  this.pv = createTypedArray('float32', arrLen);
+  for (i = 0; i < arrLen; i += 1) {
+    this.v[i] = initFrame;
+    this.pv[i] = initFrame;
+  }
+  this._caching = { lastFrame: initFrame, lastIndex: 0, value: createTypedArray('float32', arrLen) };
+  this.addEffect = addEffect;
+}
+
+const PropertyFactory = (function () {
+  function getProp(elem, data, type, mult, container) {
+    if (data.sid) {
+      data = elem.globalData.slotManager.getProp(data);
+    }
+    var p;
+    if (!data.k.length) {
+      p = new ValueProperty(elem, data, mult, container);
+    } else if (typeof (data.k[0]) === 'number') {
+      p = new MultiDimensionalProperty(elem, data, mult, container);
+    } else {
+      switch (type) {
+        case 0:
+          p = new KeyframedValueProperty(elem, data, mult, container);
+          break;
+        case 1:
+          p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
+          break;
+        default:
+          break;
+      }
+    }
+    if (p.effectsSequence.length) {
+      container.addDynamicProperty(p);
+    }
+    return p;
+  }
+
+  var ob = {
+    getProp: getProp,
+  };
+  return ob;
+}());
+
+function DynamicPropertyContainer() {}
+DynamicPropertyContainer.prototype = {
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+      this.container.addDynamicProperty(this);
+      this._isAnimated = true;
+    }
+  },
+  iterateDynamicProperties: function () {
+    this._mdf = false;
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      this.dynamicProperties[i].getValue();
+      if (this.dynamicProperties[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  },
+  initDynamicPropertyContainer: function (container) {
+    this.container = container;
+    this.dynamicProperties = [];
+    this._mdf = false;
+    this._isAnimated = false;
+  },
+};
+
+const pointPool = (function () {
+  function create() {
+    return createTypedArray('float32', 2);
+  }
+  return poolFactory(8, create);
+}());
+
+function ShapePath() {
+  this.c = false;
+  this._length = 0;
+  this._maxLength = 8;
+  this.v = createSizedArray(this._maxLength);
+  this.o = createSizedArray(this._maxLength);
+  this.i = createSizedArray(this._maxLength);
+}
+
+ShapePath.prototype.setPathData = function (closed, len) {
+  this.c = closed;
+  this.setLength(len);
+  var i = 0;
+  while (i < len) {
+    this.v[i] = pointPool.newElement();
+    this.o[i] = pointPool.newElement();
+    this.i[i] = pointPool.newElement();
+    i += 1;
+  }
+};
+
+ShapePath.prototype.setLength = function (len) {
+  while (this._maxLength < len) {
+    this.doubleArrayLength();
+  }
+  this._length = len;
+};
+
+ShapePath.prototype.doubleArrayLength = function () {
+  this.v = this.v.concat(createSizedArray(this._maxLength));
+  this.i = this.i.concat(createSizedArray(this._maxLength));
+  this.o = this.o.concat(createSizedArray(this._maxLength));
+  this._maxLength *= 2;
+};
+
+ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
+  var arr;
+  this._length = Math.max(this._length, pos + 1);
+  if (this._length >= this._maxLength) {
+    this.doubleArrayLength();
+  }
+  switch (type) {
+    case 'v':
+      arr = this.v;
+      break;
+    case 'i':
+      arr = this.i;
+      break;
+    case 'o':
+      arr = this.o;
+      break;
+    default:
+      arr = [];
+      break;
+  }
+  if (!arr[pos] || (arr[pos] && !replace)) {
+    arr[pos] = pointPool.newElement();
+  }
+  arr[pos][0] = x;
+  arr[pos][1] = y;
+};
+
+ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
+  this.setXYAt(vX, vY, 'v', pos, replace);
+  this.setXYAt(oX, oY, 'o', pos, replace);
+  this.setXYAt(iX, iY, 'i', pos, replace);
+};
+
+ShapePath.prototype.reverse = function () {
+  var newPath = new ShapePath();
+  newPath.setPathData(this.c, this._length);
+  var vertices = this.v;
+  var outPoints = this.o;
+  var inPoints = this.i;
+  var init = 0;
+  if (this.c) {
+    newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
+    init = 1;
+  }
+  var cnt = this._length - 1;
+  var len = this._length;
+
+  var i;
+  for (i = init; i < len; i += 1) {
+    newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
+    cnt -= 1;
+  }
+  return newPath;
+};
+
+ShapePath.prototype.length = function () {
+  return this._length;
+};
+
+const shapePool = (function () {
+  function create() {
+    return new ShapePath();
+  }
+
+  function release(shapePath) {
+    var len = shapePath._length;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      pointPool.release(shapePath.v[i]);
+      pointPool.release(shapePath.i[i]);
+      pointPool.release(shapePath.o[i]);
+      shapePath.v[i] = null;
+      shapePath.i[i] = null;
+      shapePath.o[i] = null;
+    }
+    shapePath._length = 0;
+    shapePath.c = false;
+  }
+
+  function clone(shape) {
+    var cloned = factory.newElement();
+    var i;
+    var len = shape._length === undefined ? shape.v.length : shape._length;
+    cloned.setLength(len);
+    cloned.c = shape.c;
+
+    for (i = 0; i < len; i += 1) {
+      cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
+    }
+    return cloned;
+  }
+
+  var factory = poolFactory(4, create, release);
+  factory.clone = clone;
+
+  return factory;
+}());
+
+function ShapeCollection() {
+  this._length = 0;
+  this._maxLength = 4;
+  this.shapes = createSizedArray(this._maxLength);
+}
+
+ShapeCollection.prototype.addShape = function (shapeData) {
+  if (this._length === this._maxLength) {
+    this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
+    this._maxLength *= 2;
+  }
+  this.shapes[this._length] = shapeData;
+  this._length += 1;
+};
+
+ShapeCollection.prototype.releaseShapes = function () {
+  var i;
+  for (i = 0; i < this._length; i += 1) {
+    shapePool.release(this.shapes[i]);
+  }
+  this._length = 0;
+};
+
+const shapeCollectionPool = (function () {
+  var ob = {
+    newShapeCollection: newShapeCollection,
+    release: release,
+  };
+
+  var _length = 0;
+  var _maxLength = 4;
+  var pool = createSizedArray(_maxLength);
+
+  function newShapeCollection() {
+    var shapeCollection;
+    if (_length) {
+      _length -= 1;
+      shapeCollection = pool[_length];
+    } else {
+      shapeCollection = new ShapeCollection();
+    }
+    return shapeCollection;
+  }
+
+  function release(shapeCollection) {
+    var i;
+    var len = shapeCollection._length;
+    for (i = 0; i < len; i += 1) {
+      shapePool.release(shapeCollection.shapes[i]);
+    }
+    shapeCollection._length = 0;
+
+    if (_length === _maxLength) {
+      pool = pooling.double(pool);
+      _maxLength *= 2;
+    }
+    pool[_length] = shapeCollection;
+    _length += 1;
+  }
+
+  return ob;
+}());
+
+const ShapePropertyFactory = (function () {
+  var initFrame = -999999;
+
+  function interpolateShape(frameNum, previousValue, caching) {
+    var iterationIndex = caching.lastIndex;
+    var keyPropS;
+    var keyPropE;
+    var isHold;
+    var j;
+    var k;
+    var jLen;
+    var kLen;
+    var perc;
+    var vertexValue;
+    var kf = this.keyframes;
+    if (frameNum < kf[0].t - this.offsetTime) {
+      keyPropS = kf[0].s[0];
+      isHold = true;
+      iterationIndex = 0;
+    } else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) {
+      keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
+      /* if(kf[kf.length - 1].s){
+                keyPropS = kf[kf.length - 1].s[0];
+            }else{
+                keyPropS = kf[kf.length - 2].e[0];
+            } */
+      isHold = true;
+    } else {
+      var i = iterationIndex;
+      var len = kf.length - 1;
+      var flag = true;
+      var keyData;
+      var nextKeyData;
+      var keyframeMetadata;
+      while (flag) {
+        keyData = kf[i];
+        nextKeyData = kf[i + 1];
+        if ((nextKeyData.t - this.offsetTime) > frameNum) {
+          break;
+        }
+        if (i < len - 1) {
+          i += 1;
+        } else {
+          flag = false;
+        }
+      }
+      keyframeMetadata = this.keyframesMetadata[i] || {};
+      isHold = keyData.h === 1;
+      iterationIndex = i;
+      if (!isHold) {
+        if (frameNum >= nextKeyData.t - this.offsetTime) {
+          perc = 1;
+        } else if (frameNum < keyData.t - this.offsetTime) {
+          perc = 0;
+        } else {
+          var fnc;
+          if (keyframeMetadata.__fnct) {
+            fnc = keyframeMetadata.__fnct;
+          } else {
+            fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
+            keyframeMetadata.__fnct = fnc;
+          }
+          perc = fnc((frameNum - (keyData.t - this.offsetTime)) / ((nextKeyData.t - this.offsetTime) - (keyData.t - this.offsetTime)));
+        }
+        keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
+      }
+      keyPropS = keyData.s[0];
+    }
+    jLen = previousValue._length;
+    kLen = keyPropS.i[0].length;
+    caching.lastIndex = iterationIndex;
+
+    for (j = 0; j < jLen; j += 1) {
+      for (k = 0; k < kLen; k += 1) {
+        vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
+        previousValue.i[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc;
+        previousValue.o[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc;
+        previousValue.v[j][k] = vertexValue;
+      }
+    }
+  }
+
+  function interpolateShapeCurrentTime() {
+    var frameNum = this.comp.renderedFrame - this.offsetTime;
+    var initTime = this.keyframes[0].t - this.offsetTime;
+    var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+    var lastFrame = this._caching.lastFrame;
+    if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) {
+      /// /
+      this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
+      this.interpolateShape(frameNum, this.pv, this._caching);
+      /// /
+    }
+    this._caching.lastFrame = frameNum;
+    return this.pv;
+  }
+
+  function resetShape() {
+    this.paths = this.localShapeCollection;
+  }
+
+  function shapesEqual(shape1, shape2) {
+    if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
+      return false;
+    }
+    var i;
+    var len = shape1._length;
+    for (i = 0; i < len; i += 1) {
+      if (shape1.v[i][0] !== shape2.v[i][0]
+            || shape1.v[i][1] !== shape2.v[i][1]
+            || shape1.o[i][0] !== shape2.o[i][0]
+            || shape1.o[i][1] !== shape2.o[i][1]
+            || shape1.i[i][0] !== shape2.i[i][0]
+            || shape1.i[i][1] !== shape2.i[i][1]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  function setVValue(newPath) {
+    if (!shapesEqual(this.v, newPath)) {
+      this.v = shapePool.clone(newPath);
+      this.localShapeCollection.releaseShapes();
+      this.localShapeCollection.addShape(this.v);
+      this._mdf = true;
+      this.paths = this.localShapeCollection;
+    }
+  }
+
+  function processEffectsSequence() {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    } if (!this.effectsSequence.length) {
+      this._mdf = false;
+      return;
+    }
+    if (this.lock) {
+      this.setVValue(this.pv);
+      return;
+    }
+    this.lock = true;
+    this._mdf = false;
+    var finalValue;
+    if (this.kf) {
+      finalValue = this.pv;
+    } else if (this.data.ks) {
+      finalValue = this.data.ks.k;
+    } else {
+      finalValue = this.data.pt.k;
+    }
+    var i;
+    var len = this.effectsSequence.length;
+    for (i = 0; i < len; i += 1) {
+      finalValue = this.effectsSequence[i](finalValue);
+    }
+    this.setVValue(finalValue);
+    this.lock = false;
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function ShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.container = elem;
+    this.elem = elem;
+    this.data = data;
+    this.k = false;
+    this.kf = false;
+    this._mdf = false;
+    var pathData = type === 3 ? data.pt.k : data.ks.k;
+    this.v = shapePool.clone(pathData);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.reset = resetShape;
+    this.effectsSequence = [];
+  }
+
+  function addEffect(effectFunction) {
+    this.effectsSequence.push(effectFunction);
+    this.container.addDynamicProperty(this);
+  }
+
+  ShapeProperty.prototype.interpolateShape = interpolateShape;
+  ShapeProperty.prototype.getValue = processEffectsSequence;
+  ShapeProperty.prototype.setVValue = setVValue;
+  ShapeProperty.prototype.addEffect = addEffect;
+
+  function KeyframedShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.elem = elem;
+    this.container = elem;
+    this.offsetTime = elem.data.st;
+    this.keyframes = type === 3 ? data.pt.k : data.ks.k;
+    this.keyframesMetadata = [];
+    this.k = true;
+    this.kf = true;
+    var len = this.keyframes[0].s[0].i.length;
+    this.v = shapePool.newElement();
+    this.v.setPathData(this.keyframes[0].s[0].c, len);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.lastFrame = initFrame;
+    this.reset = resetShape;
+    this._caching = { lastFrame: initFrame, lastIndex: 0 };
+    this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
+  }
+  KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
+  KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
+  KeyframedShapeProperty.prototype.setVValue = setVValue;
+  KeyframedShapeProperty.prototype.addEffect = addEffect;
+
+  var EllShapeProperty = (function () {
+    var cPoint = roundCorner;
+
+    function EllShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 4);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.paths = this.localShapeCollection;
+      this.localShapeCollection.addShape(this.v);
+      this.d = data.d;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertEllToPath();
+      }
+    }
+
+    EllShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+
+        if (this._mdf) {
+          this.convertEllToPath();
+        }
+      },
+      convertEllToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var s0 = this.s.v[0] / 2;
+        var s1 = this.s.v[1] / 2;
+        var _cw = this.d !== 3;
+        var _v = this.v;
+        _v.v[0][0] = p0;
+        _v.v[0][1] = p1 - s1;
+        _v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.v[1][1] = p1;
+        _v.v[2][0] = p0;
+        _v.v[2][1] = p1 + s1;
+        _v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.v[3][1] = p1;
+        _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.i[0][1] = p1 - s1;
+        _v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.i[1][1] = p1 - s1 * cPoint;
+        _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.i[2][1] = p1 + s1;
+        _v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.i[3][1] = p1 + s1 * cPoint;
+        _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.o[0][1] = p1 - s1;
+        _v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.o[1][1] = p1 + s1 * cPoint;
+        _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.o[2][1] = p1 + s1;
+        _v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.o[3][1] = p1 - s1 * cPoint;
+      },
+    };
+
+    extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
+
+    return EllShapePropertyFactory;
+  }());
+
+  var StarShapeProperty = (function () {
+    function StarShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 0);
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.data = data;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      if (data.sy === 1) {
+        this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
+        this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
+        this.convertToPath = this.convertStarToPath;
+      } else {
+        this.convertToPath = this.convertPolygonToPath;
+      }
+      this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
+      this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this);
+      this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertToPath();
+      }
+    }
+
+    StarShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertToPath();
+        }
+      },
+      convertStarToPath: function () {
+        var numPts = Math.floor(this.pt.v) * 2;
+        var angle = (Math.PI * 2) / numPts;
+        /* this.v.v.length = numPts;
+                this.v.i.length = numPts;
+                this.v.o.length = numPts; */
+        var longFlag = true;
+        var longRad = this.or.v;
+        var shortRad = this.ir.v;
+        var longRound = this.os.v;
+        var shortRound = this.is.v;
+        var longPerimSegment = (2 * Math.PI * longRad) / (numPts * 2);
+        var shortPerimSegment = (2 * Math.PI * shortRad) / (numPts * 2);
+        var i;
+        var rad;
+        var roundness;
+        var perimSegment;
+        var currentAng = -Math.PI / 2;
+        currentAng += this.r.v;
+        var dir = this.data.d === 3 ? -1 : 1;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          rad = longFlag ? longRad : shortRad;
+          roundness = longFlag ? longRound : shortRound;
+          perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
+          /* this.v.v[i] = [x,y];
+                    this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
+                    this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
+                    this.v._length = numPts; */
+          longFlag = !longFlag;
+          currentAng += angle * dir;
+        }
+      },
+      convertPolygonToPath: function () {
+        var numPts = Math.floor(this.pt.v);
+        var angle = (Math.PI * 2) / numPts;
+        var rad = this.or.v;
+        var roundness = this.os.v;
+        var perimSegment = (2 * Math.PI * rad) / (numPts * 4);
+        var i;
+        var currentAng = -Math.PI * 0.5;
+        var dir = this.data.d === 3 ? -1 : 1;
+        currentAng += this.r.v;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+          currentAng += angle * dir;
+        }
+        this.paths.length = 0;
+        this.paths[0] = this.v;
+      },
+
+    };
+    extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
+
+    return StarShapePropertyFactory;
+  }());
+
+  var RectShapeProperty = (function () {
+    function RectShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.c = true;
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertRectToPath();
+      }
+    }
+
+    RectShapePropertyFactory.prototype = {
+      convertRectToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var v0 = this.s.v[0] / 2;
+        var v1 = this.s.v[1] / 2;
+        var round = bmMin(v0, v1, this.r.v);
+        var cPoint = round * (1 - roundCorner);
+        this.v._length = 0;
+
+        if (this.d === 2 || this.d === 1) {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
+          this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2);
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3);
+          }
+        } else {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true);
+          }
+        }
+      },
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertRectToPath();
+        }
+      },
+      reset: resetShape,
+    };
+    extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
+
+    return RectShapePropertyFactory;
+  }());
+
+  function getShapeProp(elem, data, type) {
+    var prop;
+    if (type === 3 || type === 4) {
+      var dataProp = type === 3 ? data.pt : data.ks;
+      var keys = dataProp.k;
+      if (keys.length) {
+        prop = new KeyframedShapeProperty(elem, data, type);
+      } else {
+        prop = new ShapeProperty(elem, data, type);
+      }
+    } else if (type === 5) {
+      prop = new RectShapeProperty(elem, data);
+    } else if (type === 6) {
+      prop = new EllShapeProperty(elem, data);
+    } else if (type === 7) {
+      prop = new StarShapeProperty(elem, data);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  }
+
+  function getConstructorFunction() {
+    return ShapeProperty;
+  }
+
+  function getKeyframedConstructorFunction() {
+    return KeyframedShapeProperty;
+  }
+
+  var ob = {};
+  ob.getShapeProp = getShapeProp;
+  ob.getConstructorFunction = getConstructorFunction;
+  ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction;
+  return ob;
+}());
+
+/*!
+ Transformation Matrix v2.0
+ (c) Epistemex 2014-2015
+ www.epistemex.com
+ By Ken Fyrstenberg
+ Contributions by leeoniya.
+ License: MIT, header required.
+ */
+
+/**
+ * 2D transformation matrix object initialized with identity matrix.
+ *
+ * The matrix can synchronize a canvas context by supplying the context
+ * as an argument, or later apply current absolute transform to an
+ * existing context.
+ *
+ * All values are handled as floating point values.
+ *
+ * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix
+ * @prop {number} a - scale x
+ * @prop {number} b - shear y
+ * @prop {number} c - shear x
+ * @prop {number} d - scale y
+ * @prop {number} e - translate x
+ * @prop {number} f - translate y
+ * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context
+ * @constructor
+ */
+
+const Matrix = (function () {
+  var _cos = Math.cos;
+  var _sin = Math.sin;
+  var _tan = Math.tan;
+  var _rnd = Math.round;
+
+  function reset() {
+    this.props[0] = 1;
+    this.props[1] = 0;
+    this.props[2] = 0;
+    this.props[3] = 0;
+    this.props[4] = 0;
+    this.props[5] = 1;
+    this.props[6] = 0;
+    this.props[7] = 0;
+    this.props[8] = 0;
+    this.props[9] = 0;
+    this.props[10] = 1;
+    this.props[11] = 0;
+    this.props[12] = 0;
+    this.props[13] = 0;
+    this.props[14] = 0;
+    this.props[15] = 1;
+    return this;
+  }
+
+  function rotate(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function rotateX(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateY(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateZ(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function shear(sx, sy) {
+    return this._t(1, sy, sx, 1, 0, 0);
+  }
+
+  function skew(ax, ay) {
+    return this.shear(_tan(ax), _tan(ay));
+  }
+
+  function skewFromAxis(ax, angle) {
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+    // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+  }
+
+  function scale(sx, sy, sz) {
+    if (!sz && sz !== 0) {
+      sz = 1;
+    }
+    if (sx === 1 && sy === 1 && sz === 1) {
+      return this;
+    }
+    return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
+  }
+
+  function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
+    this.props[0] = a;
+    this.props[1] = b;
+    this.props[2] = c;
+    this.props[3] = d;
+    this.props[4] = e;
+    this.props[5] = f;
+    this.props[6] = g;
+    this.props[7] = h;
+    this.props[8] = i;
+    this.props[9] = j;
+    this.props[10] = k;
+    this.props[11] = l;
+    this.props[12] = m;
+    this.props[13] = n;
+    this.props[14] = o;
+    this.props[15] = p;
+    return this;
+  }
+
+  function translate(tx, ty, tz) {
+    tz = tz || 0;
+    if (tx !== 0 || ty !== 0 || tz !== 0) {
+      return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
+    }
+    return this;
+  }
+
+  function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
+    var _p = this.props;
+
+    if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
+      // NOTE: commenting this condition because TurboFan deoptimizes code when present
+      // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
+      _p[12] = _p[12] * a2 + _p[15] * m2;
+      _p[13] = _p[13] * f2 + _p[15] * n2;
+      _p[14] = _p[14] * k2 + _p[15] * o2;
+      _p[15] *= p2;
+      // }
+      this._identityCalculated = false;
+      return this;
+    }
+
+    var a1 = _p[0];
+    var b1 = _p[1];
+    var c1 = _p[2];
+    var d1 = _p[3];
+    var e1 = _p[4];
+    var f1 = _p[5];
+    var g1 = _p[6];
+    var h1 = _p[7];
+    var i1 = _p[8];
+    var j1 = _p[9];
+    var k1 = _p[10];
+    var l1 = _p[11];
+    var m1 = _p[12];
+    var n1 = _p[13];
+    var o1 = _p[14];
+    var p1 = _p[15];
+
+    /* matrix order (canvas compatible):
+         * ace
+         * bdf
+         * 001
+         */
+    _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
+    _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
+    _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
+    _p[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2;
+
+    _p[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2;
+    _p[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2;
+    _p[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2;
+    _p[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2;
+
+    _p[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2;
+    _p[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2;
+    _p[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2;
+    _p[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2;
+
+    _p[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2;
+    _p[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2;
+    _p[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2;
+    _p[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2;
+
+    this._identityCalculated = false;
+    return this;
+  }
+
+  function multiply(matrix) {
+    var matrixProps = matrix.props;
+    return this.transform(
+      matrixProps[0],
+      matrixProps[1],
+      matrixProps[2],
+      matrixProps[3],
+      matrixProps[4],
+      matrixProps[5],
+      matrixProps[6],
+      matrixProps[7],
+      matrixProps[8],
+      matrixProps[9],
+      matrixProps[10],
+      matrixProps[11],
+      matrixProps[12],
+      matrixProps[13],
+      matrixProps[14],
+      matrixProps[15]
+    );
+  }
+
+  function isIdentity() {
+    if (!this._identityCalculated) {
+      this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
+      this._identityCalculated = true;
+    }
+    return this._identity;
+  }
+
+  function equals(matr) {
+    var i = 0;
+    while (i < 16) {
+      if (matr.props[i] !== this.props[i]) {
+        return false;
+      }
+      i += 1;
+    }
+    return true;
+  }
+
+  function clone(matr) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      matr.props[i] = this.props[i];
+    }
+    return matr;
+  }
+
+  function cloneFromProps(props) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      this.props[i] = props[i];
+    }
+  }
+
+  function applyToPoint(x, y, z) {
+    return {
+      x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+      y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+      z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+    };
+    /* return {
+         x: x * me.a + y * me.c + me.e,
+         y: x * me.b + y * me.d + me.f
+         }; */
+  }
+  function applyToX(x, y, z) {
+    return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
+  }
+  function applyToY(x, y, z) {
+    return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
+  }
+  function applyToZ(x, y, z) {
+    return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
+  }
+
+  function getInverseMatrix() {
+    var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
+    var a = this.props[5] / determinant;
+    var b = -this.props[1] / determinant;
+    var c = -this.props[4] / determinant;
+    var d = this.props[0] / determinant;
+    var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12]) / determinant;
+    var f = -(this.props[0] * this.props[13] - this.props[1] * this.props[12]) / determinant;
+    var inverseMatrix = new Matrix();
+    inverseMatrix.props[0] = a;
+    inverseMatrix.props[1] = b;
+    inverseMatrix.props[4] = c;
+    inverseMatrix.props[5] = d;
+    inverseMatrix.props[12] = e;
+    inverseMatrix.props[13] = f;
+    return inverseMatrix;
+  }
+
+  function inversePoint(pt) {
+    var inverseMatrix = this.getInverseMatrix();
+    return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
+  }
+
+  function inversePoints(pts) {
+    var i;
+    var len = pts.length;
+    var retPts = [];
+    for (i = 0; i < len; i += 1) {
+      retPts[i] = inversePoint(pts[i]);
+    }
+    return retPts;
+  }
+
+  function applyToTriplePoints(pt1, pt2, pt3) {
+    var arr = createTypedArray('float32', 6);
+    if (this.isIdentity()) {
+      arr[0] = pt1[0];
+      arr[1] = pt1[1];
+      arr[2] = pt2[0];
+      arr[3] = pt2[1];
+      arr[4] = pt3[0];
+      arr[5] = pt3[1];
+    } else {
+      var p0 = this.props[0];
+      var p1 = this.props[1];
+      var p4 = this.props[4];
+      var p5 = this.props[5];
+      var p12 = this.props[12];
+      var p13 = this.props[13];
+      arr[0] = pt1[0] * p0 + pt1[1] * p4 + p12;
+      arr[1] = pt1[0] * p1 + pt1[1] * p5 + p13;
+      arr[2] = pt2[0] * p0 + pt2[1] * p4 + p12;
+      arr[3] = pt2[0] * p1 + pt2[1] * p5 + p13;
+      arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
+      arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
+    }
+    return arr;
+  }
+
+  function applyToPointArray(x, y, z) {
+    var arr;
+    if (this.isIdentity()) {
+      arr = [x, y, z];
+    } else {
+      arr = [
+        x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+        x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+        x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+      ];
+    }
+    return arr;
+  }
+
+  function applyToPointStringified(x, y) {
+    if (this.isIdentity()) {
+      return x + ',' + y;
+    }
+    var _p = this.props;
+    return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
+  }
+
+  function toCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var i = 0;
+    var props = this.props;
+    var cssValue = 'matrix3d(';
+    var v = 10000;
+    while (i < 16) {
+      cssValue += _rnd(props[i] * v) / v;
+      cssValue += i === 15 ? ')' : ',';
+      i += 1;
+    }
+    return cssValue;
+  }
+
+  function roundMatrixProperty(val) {
+    var v = 10000;
+    if ((val < 0.000001 && val > 0) || (val > -0.000001 && val < 0)) {
+      return _rnd(val * v) / v;
+    }
+    return val;
+  }
+
+  function to2dCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var props = this.props;
+    var _a = roundMatrixProperty(props[0]);
+    var _b = roundMatrixProperty(props[1]);
+    var _c = roundMatrixProperty(props[4]);
+    var _d = roundMatrixProperty(props[5]);
+    var _e = roundMatrixProperty(props[12]);
+    var _f = roundMatrixProperty(props[13]);
+    return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
+  }
+
+  return function () {
+    this.reset = reset;
+    this.rotate = rotate;
+    this.rotateX = rotateX;
+    this.rotateY = rotateY;
+    this.rotateZ = rotateZ;
+    this.skew = skew;
+    this.skewFromAxis = skewFromAxis;
+    this.shear = shear;
+    this.scale = scale;
+    this.setTransform = setTransform;
+    this.translate = translate;
+    this.transform = transform;
+    this.multiply = multiply;
+    this.applyToPoint = applyToPoint;
+    this.applyToX = applyToX;
+    this.applyToY = applyToY;
+    this.applyToZ = applyToZ;
+    this.applyToPointArray = applyToPointArray;
+    this.applyToTriplePoints = applyToTriplePoints;
+    this.applyToPointStringified = applyToPointStringified;
+    this.toCSS = toCSS;
+    this.to2dCSS = to2dCSS;
+    this.clone = clone;
+    this.cloneFromProps = cloneFromProps;
+    this.equals = equals;
+    this.inversePoints = inversePoints;
+    this.inversePoint = inversePoint;
+    this.getInverseMatrix = getInverseMatrix;
+    this._t = this.transform;
+    this.isIdentity = isIdentity;
+    this._identity = true;
+    this._identityCalculated = false;
+
+    this.props = createTypedArray('float32', 16);
+    this.reset();
+  };
+}());
+
+const lottie = {};
+var standalone = '__[STANDALONE]__';
+var animationData = '__[ANIMATIONDATA]__';
+var renderer = '';
+
+function setLocation(href) {
+  setLocationHref(href);
+}
+
+function searchAnimations() {
+  if (standalone === true) {
+    animationManager.searchAnimations(animationData, standalone, renderer);
+  } else {
+    animationManager.searchAnimations();
+  }
+}
+
+function setSubframeRendering(flag) {
+  setSubframeEnabled(flag);
+}
+
+function setPrefix(prefix) {
+  setIdPrefix(prefix);
+}
+
+function loadAnimation(params) {
+  if (standalone === true) {
+    params.animationData = JSON.parse(animationData);
+  }
+  return animationManager.loadAnimation(params);
+}
+
+function setQuality(value) {
+  if (typeof value === 'string') {
+    switch (value) {
+      case 'high':
+        setDefaultCurveSegments(200);
+        break;
+      default:
+      case 'medium':
+        setDefaultCurveSegments(50);
+        break;
+      case 'low':
+        setDefaultCurveSegments(10);
+        break;
+    }
+  } else if (!isNaN(value) && value > 1) {
+    setDefaultCurveSegments(value);
+  }
+  if (getDefaultCurveSegments() >= 50) {
+    roundValues(false);
+  } else {
+    roundValues(true);
+  }
+}
+
+function inBrowser() {
+  return typeof navigator !== 'undefined';
+}
+
+function installPlugin(type, plugin) {
+  if (type === 'expressions') {
+    setExpressionsPlugin(plugin);
+  }
+}
+
+function getFactory(name) {
+  switch (name) {
+    case 'propertyFactory':
+      return PropertyFactory;
+    case 'shapePropertyFactory':
+      return ShapePropertyFactory;
+    case 'matrix':
+      return Matrix;
+    default:
+      return null;
+  }
+}
+
+lottie.play = animationManager.play;
+lottie.pause = animationManager.pause;
+lottie.setLocationHref = setLocation;
+lottie.togglePause = animationManager.togglePause;
+lottie.setSpeed = animationManager.setSpeed;
+lottie.setDirection = animationManager.setDirection;
+lottie.stop = animationManager.stop;
+lottie.searchAnimations = searchAnimations;
+lottie.registerAnimation = animationManager.registerAnimation;
+lottie.loadAnimation = loadAnimation;
+lottie.setSubframeRendering = setSubframeRendering;
+lottie.resize = animationManager.resize;
+// lottie.start = start;
+lottie.goToAndStop = animationManager.goToAndStop;
+lottie.destroy = animationManager.destroy;
+lottie.setQuality = setQuality;
+lottie.inBrowser = inBrowser;
+lottie.installPlugin = installPlugin;
+lottie.freeze = animationManager.freeze;
+lottie.unfreeze = animationManager.unfreeze;
+lottie.setVolume = animationManager.setVolume;
+lottie.mute = animationManager.mute;
+lottie.unmute = animationManager.unmute;
+lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations;
+lottie.useWebWorker = setWebWorker;
+lottie.setIDPrefix = setPrefix;
+lottie.__getFactory = getFactory;
+lottie.version = '[[BM_VERSION]]';
+
+function checkReady() {
+  if (document.readyState === 'complete') {
+    clearInterval(readyStateCheckInterval);
+    searchAnimations();
+  }
+}
+
+function getQueryVariable(variable) {
+  var vars = queryString.split('&');
+  for (var i = 0; i < vars.length; i += 1) {
+    var pair = vars[i].split('=');
+    if (decodeURIComponent(pair[0]) == variable) { // eslint-disable-line eqeqeq
+      return decodeURIComponent(pair[1]);
+    }
+  }
+  return null;
+}
+var queryString = '';
+if (standalone) {
+  var scripts = document.getElementsByTagName('script');
+  var index = scripts.length - 1;
+  var myScript = scripts[index] || {
+    src: '',
+  };
+  queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
+  renderer = getQueryVariable('renderer');
+}
+var readyStateCheckInterval = setInterval(checkReady, 100);
+
+// this adds bodymovin to the window object for backwards compatibility
+try {
+  if (!(typeof exports === 'object' && typeof module !== 'undefined')
+    && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
+  ) {
+    window.bodymovin = lottie;
+  }
+} catch (err) {
+  //
+}
+
+const ShapeModifiers = (function () {
+  var ob = {};
+  var modifiers = {};
+  ob.registerModifier = registerModifier;
+  ob.getModifier = getModifier;
+
+  function registerModifier(nm, factory) {
+    if (!modifiers[nm]) {
+      modifiers[nm] = factory;
+    }
+  }
+
+  function getModifier(nm, elem, data) {
+    return new modifiers[nm](elem, data);
+  }
+
+  return ob;
+}());
+
+function ShapeModifier() {}
+ShapeModifier.prototype.initModifierProperties = function () {};
+ShapeModifier.prototype.addShapeToModifier = function () {};
+ShapeModifier.prototype.addShape = function (data) {
+  if (!this.closed) {
+    // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
+    data.sh.container.addDynamicProperty(data.sh);
+    var shapeData = { shape: data.sh, data: data, localShapeCollection: shapeCollectionPool.newShapeCollection() };
+    this.shapes.push(shapeData);
+    this.addShapeToModifier(shapeData);
+    if (this._isAnimated) {
+      data.setAsAnimated();
+    }
+  }
+};
+ShapeModifier.prototype.init = function (elem, data) {
+  this.shapes = [];
+  this.elem = elem;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, data);
+  this.frameId = initialDefaultFrame;
+  this.closed = false;
+  this.k = false;
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+ShapeModifier.prototype.processKeys = function () {
+  if (this.elem.globalData.frameId === this.frameId) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+extendPrototype([DynamicPropertyContainer], ShapeModifier);
+
+function TrimModifier() {
+}
+extendPrototype([ShapeModifier], TrimModifier);
+TrimModifier.prototype.initModifierProperties = function (elem, data) {
+  this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this);
+  this.sValue = 0;
+  this.eValue = 0;
+  this.getValue = this.processKeys;
+  this.m = data.m;
+  this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
+};
+
+TrimModifier.prototype.addShapeToModifier = function (shapeData) {
+  shapeData.pathsData = [];
+};
+
+TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
+  var segments = [];
+  if (e <= 1) {
+    segments.push({
+      s: s,
+      e: e,
+    });
+  } else if (s >= 1) {
+    segments.push({
+      s: s - 1,
+      e: e - 1,
+    });
+  } else {
+    segments.push({
+      s: s,
+      e: 1,
+    });
+    segments.push({
+      s: 0,
+      e: e - 1,
+    });
+  }
+  var shapeSegments = [];
+  var i;
+  var len = segments.length;
+  var segmentOb;
+  for (i = 0; i < len; i += 1) {
+    segmentOb = segments[i];
+    if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
+      var shapeS;
+      var shapeE;
+      if (segmentOb.s * totalModifierLength <= addedLength) {
+        shapeS = 0;
+      } else {
+        shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
+      }
+      if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
+        shapeE = 1;
+      } else {
+        shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength);
+      }
+      shapeSegments.push([shapeS, shapeE]);
+    }
+  }
+  if (!shapeSegments.length) {
+    shapeSegments.push([0, 0]);
+  }
+  return shapeSegments;
+};
+
+TrimModifier.prototype.releasePathsData = function (pathsData) {
+  var i;
+  var len = pathsData.length;
+  for (i = 0; i < len; i += 1) {
+    segmentsLengthPool.release(pathsData[i]);
+  }
+  pathsData.length = 0;
+  return pathsData;
+};
+
+TrimModifier.prototype.processShapes = function (_isFirstFrame) {
+  var s;
+  var e;
+  if (this._mdf || _isFirstFrame) {
+    var o = (this.o.v % 360) / 360;
+    if (o < 0) {
+      o += 1;
+    }
+    if (this.s.v > 1) {
+      s = 1 + o;
+    } else if (this.s.v < 0) {
+      s = 0 + o;
+    } else {
+      s = this.s.v + o;
+    }
+    if (this.e.v > 1) {
+      e = 1 + o;
+    } else if (this.e.v < 0) {
+      e = 0 + o;
+    } else {
+      e = this.e.v + o;
+    }
+
+    if (s > e) {
+      var _s = s;
+      s = e;
+      e = _s;
+    }
+    s = Math.round(s * 10000) * 0.0001;
+    e = Math.round(e * 10000) * 0.0001;
+    this.sValue = s;
+    this.eValue = e;
+  } else {
+    s = this.sValue;
+    e = this.eValue;
+  }
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var pathsData;
+  var pathData;
+  var totalShapeLength;
+  var totalModifierLength = 0;
+
+  if (e === s) {
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].localShapeCollection.releaseShapes();
+      this.shapes[i].shape._mdf = true;
+      this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
+      if (this._mdf) {
+        this.shapes[i].pathsData.length = 0;
+      }
+    }
+  } else if (!((e === 1 && s === 0) || (e === 0 && s === 1))) {
+    var segments = [];
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
+      if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
+        shapeData.shape.paths = shapeData.localShapeCollection;
+      } else {
+        shapePaths = shapeData.shape.paths;
+        jLen = shapePaths._length;
+        totalShapeLength = 0;
+        if (!shapeData.shape._mdf && shapeData.pathsData.length) {
+          totalShapeLength = shapeData.totalShapeLength;
+        } else {
+          pathsData = this.releasePathsData(shapeData.pathsData);
+          for (j = 0; j < jLen; j += 1) {
+            pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
+            pathsData.push(pathData);
+            totalShapeLength += pathData.totalLength;
+          }
+          shapeData.totalShapeLength = totalShapeLength;
+          shapeData.pathsData = pathsData;
+        }
+
+        totalModifierLength += totalShapeLength;
+        shapeData.shape._mdf = true;
+      }
+    }
+    var shapeS = s;
+    var shapeE = e;
+    var addedLength = 0;
+    var edges;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shapeData = this.shapes[i];
+      if (shapeData.shape._mdf) {
+        localShapeCollection = shapeData.localShapeCollection;
+        localShapeCollection.releaseShapes();
+        // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
+        if (this.m === 2 && len > 1) {
+          edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
+          addedLength += shapeData.totalShapeLength;
+        } else {
+          edges = [[shapeS, shapeE]];
+        }
+        jLen = edges.length;
+        for (j = 0; j < jLen; j += 1) {
+          shapeS = edges[j][0];
+          shapeE = edges[j][1];
+          segments.length = 0;
+          if (shapeE <= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength * shapeE,
+            });
+          } else if (shapeS >= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * (shapeS - 1),
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          } else {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength,
+            });
+            segments.push({
+              s: 0,
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          }
+          var newShapesData = this.addShapes(shapeData, segments[0]);
+          if (segments[0].s !== segments[0].e) {
+            if (segments.length > 1) {
+              var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
+              if (lastShapeInCollection.c) {
+                var lastShape = newShapesData.pop();
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1], lastShape);
+              } else {
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1]);
+              }
+            }
+            this.addPaths(newShapesData, localShapeCollection);
+          }
+        }
+        shapeData.shape.paths = localShapeCollection;
+      }
+    }
+  } else if (this._mdf) {
+    for (i = 0; i < len; i += 1) {
+      // Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween.
+      // Don't remove this even if it's losing cached info.
+      this.shapes[i].pathsData.length = 0;
+      this.shapes[i].shape._mdf = true;
+    }
+  }
+};
+
+TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
+  var i;
+  var len = newPaths.length;
+  for (i = 0; i < len; i += 1) {
+    localShapeCollection.addShape(newPaths[i]);
+  }
+};
+
+TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
+  shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
+  shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
+  }
+  shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
+  shapePath.setXYAt(points[1], points[5], 'o', pos);
+  shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(points[0], points[4], 'v', pos);
+  }
+  shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
+  var pathsData = shapeData.pathsData;
+  var shapePaths = shapeData.shape.paths.shapes;
+  var i;
+  var len = shapeData.shape.paths._length;
+  var j;
+  var jLen;
+  var addedLength = 0;
+  var currentLengthData;
+  var segmentCount;
+  var lengths;
+  var segment;
+  var shapes = [];
+  var initPos;
+  var newShape = true;
+  if (!shapePath) {
+    shapePath = shapePool.newElement();
+    segmentCount = 0;
+    initPos = 0;
+  } else {
+    segmentCount = shapePath._length;
+    initPos = shapePath._length;
+  }
+  shapes.push(shapePath);
+  for (i = 0; i < len; i += 1) {
+    lengths = pathsData[i].lengths;
+    shapePath.c = shapePaths[i].c;
+    jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
+    for (j = 1; j < jLen; j += 1) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
+        addedLength += currentLengthData.addedLength;
+        shapePath.c = false;
+      } else if (addedLength > shapeSegment.e) {
+        shapePath.c = false;
+        break;
+      } else {
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+        addedLength += currentLengthData.addedLength;
+        segmentCount += 1;
+      }
+    }
+    if (shapePaths[i].c && lengths.length) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength <= shapeSegment.e) {
+        var segmentLength = lengths[j - 1].addedLength;
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+      } else {
+        shapePath.c = false;
+      }
+      addedLength += currentLengthData.addedLength;
+      segmentCount += 1;
+    }
+    if (shapePath._length) {
+      shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
+      shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
+    }
+    if (addedLength > shapeSegment.e) {
+      break;
+    }
+    if (i < len - 1) {
+      shapePath = shapePool.newElement();
+      newShape = true;
+      shapes.push(shapePath);
+      segmentCount = 0;
+    }
+  }
+  return shapes;
+};
+
+function PuckerAndBloatModifier() {}
+extendPrototype([ShapeModifier], PuckerAndBloatModifier);
+PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this._isAnimated = !!this.amount.effectsSequence.length;
+};
+
+PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
+  var percent = amount / 100;
+  var centerPoint = [0, 0];
+  var pathLength = path._length;
+  var i = 0;
+  for (i = 0; i < pathLength; i += 1) {
+    centerPoint[0] += path.v[i][0];
+    centerPoint[1] += path.v[i][1];
+  }
+  centerPoint[0] /= pathLength;
+  centerPoint[1] /= pathLength;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < pathLength; i += 1) {
+    vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
+    vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
+    oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent;
+    oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent;
+    iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent;
+    iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
+    clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
+  }
+  return clonedPath;
+};
+
+PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+const TransformPropertyFactory = (function () {
+  var defaultVector = [0, 0];
+
+  function applyToMatrix(mat) {
+    var _mdf = this._mdf;
+    this.iterateDynamicProperties();
+    this._mdf = this._mdf || _mdf;
+    if (this.a) {
+      mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+    }
+    if (this.s) {
+      mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+    }
+    if (this.sk) {
+      mat.skewFromAxis(-this.sk.v, this.sa.v);
+    }
+    if (this.r) {
+      mat.rotate(-this.r.v);
+    } else {
+      mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+    }
+    if (this.data.p.s) {
+      if (this.data.p.z) {
+        mat.translate(this.px.v, this.py.v, -this.pz.v);
+      } else {
+        mat.translate(this.px.v, this.py.v, 0);
+      }
+    } else {
+      mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+    }
+  }
+  function processKeys(forceRender) {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    }
+    if (this._isDirty) {
+      this.precalculateMatrix();
+      this._isDirty = false;
+    }
+
+    this.iterateDynamicProperties();
+
+    if (this._mdf || forceRender) {
+      var frameRate;
+      this.v.cloneFromProps(this.pre.props);
+      if (this.appliedTransformations < 1) {
+        this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      }
+      if (this.appliedTransformations < 2) {
+        this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      }
+      if (this.sk && this.appliedTransformations < 3) {
+        this.v.skewFromAxis(-this.sk.v, this.sa.v);
+      }
+      if (this.r && this.appliedTransformations < 4) {
+        this.v.rotate(-this.r.v);
+      } else if (!this.r && this.appliedTransformations < 4) {
+        this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+          .rotateY(this.or.v[1])
+          .rotateX(this.or.v[0]);
+      }
+      if (this.autoOriented) {
+        var v1;
+        var v2;
+        frameRate = this.elem.globalData.frameRate;
+        if (this.p && this.p.keyframes && this.p.getValueAtTime) {
+          if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
+            v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0);
+          } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0);
+            v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0);
+          } else {
+            v1 = this.p.pv;
+            v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime);
+          }
+        } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) {
+          v1 = [];
+          v2 = [];
+          var px = this.px;
+          var py = this.py;
+          if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
+            v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
+            v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate, 0);
+          } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate), 0);
+            v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate), 0);
+            v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0);
+          } else {
+            v1 = [px.pv, py.pv];
+            v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime);
+            v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime);
+          }
+        } else {
+          v2 = defaultVector;
+          v1 = v2;
+        }
+        this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
+      }
+      if (this.data.p && this.data.p.s) {
+        if (this.data.p.z) {
+          this.v.translate(this.px.v, this.py.v, -this.pz.v);
+        } else {
+          this.v.translate(this.px.v, this.py.v, 0);
+        }
+      } else {
+        this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+      }
+    }
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function precalculateMatrix() {
+    this.appliedTransformations = 0;
+    this.pre.reset();
+
+    if (!this.a.effectsSequence.length) {
+      this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      this.appliedTransformations = 1;
+    } else {
+      return;
+    }
+    if (!this.s.effectsSequence.length) {
+      this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      this.appliedTransformations = 2;
+    } else {
+      return;
+    }
+    if (this.sk) {
+      if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
+        this.pre.skewFromAxis(-this.sk.v, this.sa.v);
+        this.appliedTransformations = 3;
+      } else {
+        return;
+      }
+    }
+    if (this.r) {
+      if (!this.r.effectsSequence.length) {
+        this.pre.rotate(-this.r.v);
+        this.appliedTransformations = 4;
+      }
+    } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) {
+      this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+      this.appliedTransformations = 4;
+    }
+  }
+
+  function autoOrient() {
+    //
+    // var prevP = this.getValueAtTime();
+  }
+
+  function addDynamicProperty(prop) {
+    this._addDynamicProperty(prop);
+    this.elem.addDynamicProperty(prop);
+    this._isDirty = true;
+  }
+
+  function TransformProperty(elem, data, container) {
+    this.elem = elem;
+    this.frameId = -1;
+    this.propType = 'transform';
+    this.data = data;
+    this.v = new Matrix();
+    // Precalculated matrix with non animated properties
+    this.pre = new Matrix();
+    this.appliedTransformations = 0;
+    this.initDynamicPropertyContainer(container || elem);
+    if (data.p && data.p.s) {
+      this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
+      this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
+      if (data.p.z) {
+        this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
+      }
+    } else {
+      this.p = PropertyFactory.getProp(elem, data.p || { k: [0, 0, 0] }, 1, 0, this);
+    }
+    if (data.rx) {
+      this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
+      this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
+      this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
+      if (data.or.k[0].ti) {
+        var i;
+        var len = data.or.k.length;
+        for (i = 0; i < len; i += 1) {
+          data.or.k[i].to = null;
+          data.or.k[i].ti = null;
+        }
+      }
+      this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+      // sh Indicates it needs to be capped between -180 and 180
+      this.or.sh = true;
+    } else {
+      this.r = PropertyFactory.getProp(elem, data.r || { k: 0 }, 0, degToRads, this);
+    }
+    if (data.sk) {
+      this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
+      this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
+    }
+    this.a = PropertyFactory.getProp(elem, data.a || { k: [0, 0, 0] }, 1, 0, this);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: [100, 100, 100] }, 1, 0.01, this);
+    // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
+    if (data.o) {
+      this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
+    } else {
+      this.o = { _mdf: false, v: 1 };
+    }
+    this._isDirty = true;
+    if (!this.dynamicProperties.length) {
+      this.getValue(true);
+    }
+  }
+
+  TransformProperty.prototype = {
+    applyToMatrix: applyToMatrix,
+    getValue: processKeys,
+    precalculateMatrix: precalculateMatrix,
+    autoOrient: autoOrient,
+  };
+
+  extendPrototype([DynamicPropertyContainer], TransformProperty);
+  TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
+  TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
+
+  function getTransformProperty(elem, data, container) {
+    return new TransformProperty(elem, data, container);
+  }
+
+  return {
+    getTransformProperty: getTransformProperty,
+  };
+}());
+
+function RepeaterModifier() {}
+extendPrototype([ShapeModifier], RepeaterModifier);
+
+RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, null, this);
+  this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this);
+  this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
+  this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
+  this.data = data;
+  if (!this.dynamicProperties.length) {
+    this.getValue(true);
+  }
+  this._isAnimated = !!this.dynamicProperties.length;
+  this.pMatrix = new Matrix();
+  this.rMatrix = new Matrix();
+  this.sMatrix = new Matrix();
+  this.tMatrix = new Matrix();
+  this.matrix = new Matrix();
+};
+
+RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
+  var dir = inv ? -1 : 1;
+  var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
+  var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
+  pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
+  rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  rMatrix.rotate(-transform.r.v * dir * perc);
+  rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+  sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
+  sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+};
+
+RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
+  this.elem = elem;
+  this.arr = arr;
+  this.pos = pos;
+  this.elemsData = elemsData;
+  this._currentCopies = 0;
+  this._elements = [];
+  this._groups = [];
+  this.frameId = -1;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, arr[pos]);
+  while (pos > 0) {
+    pos -= 1;
+    // this._elements.unshift(arr.splice(pos,1)[0]);
+    this._elements.unshift(arr[pos]);
+  }
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+
+RepeaterModifier.prototype.resetElements = function (elements) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._processed = false;
+    if (elements[i].ty === 'gr') {
+      this.resetElements(elements[i].it);
+    }
+  }
+};
+
+RepeaterModifier.prototype.cloneElements = function (elements) {
+  var newElements = JSON.parse(JSON.stringify(elements));
+  this.resetElements(newElements);
+  return newElements;
+};
+
+RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._render = renderFlag;
+    if (elements[i].ty === 'gr') {
+      this.changeGroupRender(elements[i].it, renderFlag);
+    }
+  }
+};
+
+RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
+  var items;
+  var itemsTransform;
+  var i;
+  var dir;
+  var cont;
+  var hasReloaded = false;
+  if (this._mdf || _isFirstFrame) {
+    var copies = Math.ceil(this.c.v);
+    if (this._groups.length < copies) {
+      while (this._groups.length < copies) {
+        var group = {
+          it: this.cloneElements(this._elements),
+          ty: 'gr',
+        };
+        group.it.push({
+          a: { a: 0, ix: 1, k: [0, 0] }, nm: 'Transform', o: { a: 0, ix: 7, k: 100 }, p: { a: 0, ix: 2, k: [0, 0] }, r: { a: 1, ix: 6, k: [{ s: 0, e: 0, t: 0 }, { s: 0, e: 0, t: 1 }] }, s: { a: 0, ix: 3, k: [100, 100] }, sa: { a: 0, ix: 5, k: 0 }, sk: { a: 0, ix: 4, k: 0 }, ty: 'tr',
+        });
+
+        this.arr.splice(0, 0, group);
+        this._groups.splice(0, 0, group);
+        this._currentCopies += 1;
+      }
+      this.elem.reloadShapes();
+      hasReloaded = true;
+    }
+    cont = 0;
+    var renderFlag;
+    for (i = 0; i <= this._groups.length - 1; i += 1) {
+      renderFlag = cont < copies;
+      this._groups[i]._render = renderFlag;
+      this.changeGroupRender(this._groups[i].it, renderFlag);
+      if (!renderFlag) {
+        var elems = this.elemsData[i].it;
+        var transformData = elems[elems.length - 1];
+        if (transformData.transform.op.v !== 0) {
+          transformData.transform.op._mdf = true;
+          transformData.transform.op.v = 0;
+        } else {
+          transformData.transform.op._mdf = false;
+        }
+      }
+      cont += 1;
+    }
+
+    this._currentCopies = copies;
+    /// /
+
+    var offset = this.o.v;
+    var offsetModulo = offset % 1;
+    var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
+    var pProps = this.pMatrix.props;
+    var rProps = this.rMatrix.props;
+    var sProps = this.sMatrix.props;
+    this.pMatrix.reset();
+    this.rMatrix.reset();
+    this.sMatrix.reset();
+    this.tMatrix.reset();
+    this.matrix.reset();
+    var iteration = 0;
+
+    if (offset > 0) {
+      while (iteration < roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        iteration += 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
+        iteration += offsetModulo;
+      }
+    } else if (offset < 0) {
+      while (iteration > roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
+        iteration -= 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
+        iteration -= offsetModulo;
+      }
+    }
+    i = this.data.m === 1 ? 0 : this._currentCopies - 1;
+    dir = this.data.m === 1 ? 1 : -1;
+    cont = this._currentCopies;
+    var j;
+    var jLen;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      jLen = itemsTransform.length;
+      items[items.length - 1].transform.mProps._mdf = true;
+      items[items.length - 1].transform.op._mdf = true;
+      items[items.length - 1].transform.op.v = this._currentCopies === 1
+        ? this.so.v
+        : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
+
+      if (iteration !== 0) {
+        if ((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)) {
+          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        }
+        this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
+        this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
+        this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
+
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+        this.matrix.reset();
+      } else {
+        this.matrix.reset();
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+      }
+      iteration += 1;
+      cont -= 1;
+      i += dir;
+    }
+  } else {
+    cont = this._currentCopies;
+    i = 0;
+    dir = 1;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      items[items.length - 1].transform.mProps._mdf = false;
+      items[items.length - 1].transform.op._mdf = false;
+      cont -= 1;
+      i += dir;
+    }
+  }
+  return hasReloaded;
+};
+
+RepeaterModifier.prototype.addShape = function () {};
+
+function RoundCornersModifier() {}
+extendPrototype([ShapeModifier], RoundCornersModifier);
+RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this._isAnimated = !!this.rd.effectsSequence.length;
+};
+
+RoundCornersModifier.prototype.processPath = function (path, round) {
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var i;
+  var len = path._length;
+  var currentV;
+  var currentI;
+  var currentO;
+  var closerV;
+  var distance;
+  var newPosPerc;
+  var index = 0;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < len; i += 1) {
+    currentV = path.v[i];
+    currentO = path.o[i];
+    currentI = path.i[i];
+    if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
+      if ((i === 0 || i === len - 1) && !path.c) {
+        clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
+        /* clonedPath.v[index] = currentV;
+                clonedPath.o[index] = currentO;
+                clonedPath.i[index] = currentI; */
+        index += 1;
+      } else {
+        if (i === 0) {
+          closerV = path.v[len - 1];
+        } else {
+          closerV = path.v[i - 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = iX;
+        iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
+        vY = iY;
+        oX = vX - (vX - currentV[0]) * roundCorner;
+        oY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+
+        if (i === len - 1) {
+          closerV = path.v[0];
+        } else {
+          closerV = path.v[i + 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = oX;
+        oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc;
+        vY = oY;
+        iX = vX - (vX - currentV[0]) * roundCorner;
+        iY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+      }
+    } else {
+      clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index);
+      index += 1;
+    }
+  }
+  return clonedPath;
+};
+
+RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var rd = this.rd.v;
+
+  if (rd !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function floatEqual(a, b) {
+  return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
+}
+
+function floatZero(f) {
+  return Math.abs(f) <= 0.00001;
+}
+
+function lerp(p0, p1, amount) {
+  return p0 * (1 - amount) + p1 * amount;
+}
+
+function lerpPoint(p0, p1, amount) {
+  return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
+}
+
+function quadRoots(a, b, c) {
+  // no root
+  if (a === 0) return [];
+  var s = b * b - 4 * a * c;
+  // Complex roots
+  if (s < 0) return [];
+  var singleRoot = -b / (2 * a);
+  // 1 root
+  if (s === 0) return [singleRoot];
+  var delta = Math.sqrt(s) / (2 * a);
+  // 2 roots
+  return [singleRoot - delta, singleRoot + delta];
+}
+
+function polynomialCoefficients(p0, p1, p2, p3) {
+  return [
+    -p0 + 3 * p1 - 3 * p2 + p3,
+    3 * p0 - 6 * p1 + 3 * p2,
+    -3 * p0 + 3 * p1,
+    p0,
+  ];
+}
+
+function singlePoint(p) {
+  return new PolynomialBezier(p, p, p, p, false);
+}
+
+function PolynomialBezier(p0, p1, p2, p3, linearize) {
+  if (linearize && pointEqual(p0, p1)) {
+    p1 = lerpPoint(p0, p3, 1 / 3);
+  }
+  if (linearize && pointEqual(p2, p3)) {
+    p2 = lerpPoint(p0, p3, 2 / 3);
+  }
+  var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
+  var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
+  this.a = [coeffx[0], coeffy[0]];
+  this.b = [coeffx[1], coeffy[1]];
+  this.c = [coeffx[2], coeffy[2]];
+  this.d = [coeffx[3], coeffy[3]];
+  this.points = [p0, p1, p2, p3];
+}
+PolynomialBezier.prototype.point = function (t) {
+  return [
+    (((this.a[0] * t) + this.b[0]) * t + this.c[0]) * t + this.d[0],
+    (((this.a[1] * t) + this.b[1]) * t + this.c[1]) * t + this.d[1],
+  ];
+};
+PolynomialBezier.prototype.derivative = function (t) {
+  return [
+    (3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0],
+    (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1],
+  ];
+};
+PolynomialBezier.prototype.tangentAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[1], p[0]);
+};
+PolynomialBezier.prototype.normalAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[0], p[1]);
+};
+
+PolynomialBezier.prototype.inflectionPoints = function () {
+  var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
+  if (floatZero(denom)) return [];
+  var tcusp = (-0.5 * (this.a[1] * this.c[0] - this.a[0] * this.c[1])) / denom;
+  var square = tcusp * tcusp - ((1 / 3) * (this.b[1] * this.c[0] - this.b[0] * this.c[1])) / denom;
+  if (square < 0) return [];
+  var root = Math.sqrt(square);
+  if (floatZero(root)) {
+    if (root > 0 && root < 1) return [tcusp];
+    return [];
+  }
+  return [tcusp - root, tcusp + root].filter(function (r) { return r > 0 && r < 1; });
+};
+PolynomialBezier.prototype.split = function (t) {
+  if (t <= 0) return [singlePoint(this.points[0]), this];
+  if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
+  var p10 = lerpPoint(this.points[0], this.points[1], t);
+  var p11 = lerpPoint(this.points[1], this.points[2], t);
+  var p12 = lerpPoint(this.points[2], this.points[3], t);
+  var p20 = lerpPoint(p10, p11, t);
+  var p21 = lerpPoint(p11, p12, t);
+  var p3 = lerpPoint(p20, p21, t);
+  return [
+    new PolynomialBezier(this.points[0], p10, p20, p3, true),
+    new PolynomialBezier(p3, p21, p12, this.points[3], true),
+  ];
+};
+function extrema(bez, comp) {
+  var min = bez.points[0][comp];
+  var max = bez.points[bez.points.length - 1][comp];
+  if (min > max) {
+    var e = max;
+    max = min;
+    min = e;
+  }
+  // Derivative roots to find min/max
+  var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
+  for (var i = 0; i < f.length; i += 1) {
+    if (f[i] > 0 && f[i] < 1) {
+      var val = bez.point(f[i])[comp];
+      if (val < min) min = val;
+      else if (val > max) max = val;
+    }
+  }
+  return {
+    min: min,
+    max: max,
+  };
+}
+PolynomialBezier.prototype.bounds = function () {
+  return {
+    x: extrema(this, 0),
+    y: extrema(this, 1),
+  };
+};
+PolynomialBezier.prototype.boundingBox = function () {
+  var bounds = this.bounds();
+  return {
+    left: bounds.x.min,
+    right: bounds.x.max,
+    top: bounds.y.min,
+    bottom: bounds.y.max,
+    width: bounds.x.max - bounds.x.min,
+    height: bounds.y.max - bounds.y.min,
+    cx: (bounds.x.max + bounds.x.min) / 2,
+    cy: (bounds.y.max + bounds.y.min) / 2,
+  };
+};
+
+function intersectData(bez, t1, t2) {
+  var box = bez.boundingBox();
+  return {
+    cx: box.cx,
+    cy: box.cy,
+    width: box.width,
+    height: box.height,
+    bez: bez,
+    t: (t1 + t2) / 2,
+    t1: t1,
+    t2: t2,
+  };
+}
+function splitData(data) {
+  var split = data.bez.split(0.5);
+  return [
+    intersectData(split[0], data.t1, data.t),
+    intersectData(split[1], data.t, data.t2),
+  ];
+}
+
+function boxIntersect(b1, b2) {
+  return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width
+    && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
+}
+
+function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
+  if (!boxIntersect(d1, d2)) return;
+  if (depth >= maxRecursion || (d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance)) {
+    intersections.push([d1.t, d2.t]);
+    return;
+  }
+  var d1s = splitData(d1);
+  var d2s = splitData(d2);
+  intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[0], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+}
+
+PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
+  if (tolerance === undefined) tolerance = 2;
+  if (maxRecursion === undefined) maxRecursion = 7;
+  var intersections = [];
+  intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
+  return intersections;
+};
+
+PolynomialBezier.shapeSegment = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
+};
+
+PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
+};
+
+function crossProduct(a, b) {
+  return [
+    a[1] * b[2] - a[2] * b[1],
+    a[2] * b[0] - a[0] * b[2],
+    a[0] * b[1] - a[1] * b[0],
+  ];
+}
+
+function lineIntersection(start1, end1, start2, end2) {
+  var v1 = [start1[0], start1[1], 1];
+  var v2 = [end1[0], end1[1], 1];
+  var v3 = [start2[0], start2[1], 1];
+  var v4 = [end2[0], end2[1], 1];
+
+  var r = crossProduct(
+    crossProduct(v1, v2),
+    crossProduct(v3, v4)
+  );
+
+  if (floatZero(r[2])) return null;
+
+  return [r[0] / r[2], r[1] / r[2]];
+}
+
+function polarOffset(p, angle, length) {
+  return [
+    p[0] + Math.cos(angle) * length,
+    p[1] - Math.sin(angle) * length,
+  ];
+}
+
+function pointDistance(p1, p2) {
+  return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
+}
+
+function pointEqual(p1, p2) {
+  return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
+}
+
+function ZigZagModifier() {}
+extendPrototype([ShapeModifier], ZigZagModifier);
+ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
+  this.frequency = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
+  this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
+};
+
+function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
+  var angO = angle - Math.PI / 2;
+  var angI = angle + Math.PI / 2;
+  var px = point[0] + Math.cos(angle) * direction * amplitude;
+  var py = point[1] - Math.sin(angle) * direction * amplitude;
+
+  outputBezier.setTripleAt(
+    px,
+    py,
+    px + Math.cos(angO) * outAmplitude,
+    py - Math.sin(angO) * outAmplitude,
+    px + Math.cos(angI) * inAmplitude,
+    py - Math.sin(angI) * inAmplitude,
+    outputBezier.length()
+  );
+}
+
+function getPerpendicularVector(pt1, pt2) {
+  var vector = [
+    pt2[0] - pt1[0],
+    pt2[1] - pt1[1],
+  ];
+  var rot = -Math.PI * 0.5;
+  var rotatedVector = [
+    Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1],
+    Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1],
+  ];
+  return rotatedVector;
+}
+
+function getProjectingAngle(path, cur) {
+  var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
+  var nextIndex = (cur + 1) % path.length();
+  var prevPoint = path.v[prevIndex];
+  var nextPoint = path.v[nextIndex];
+  var pVector = getPerpendicularVector(prevPoint, nextPoint);
+  return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
+}
+
+function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
+  var angle = getProjectingAngle(path, cur);
+  var point = path.v[cur % path._length];
+  var prevPoint = path.v[cur === 0 ? path._length - 1 : cur - 1];
+  var nextPoint = path.v[(cur + 1) % path._length];
+  var prevDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - prevPoint[0], 2) + Math.pow(point[1] - prevPoint[1], 2))
+    : 0;
+  var nextDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2))
+    : 0;
+
+  setPoint(
+    outputBezier,
+    path.v[cur % path._length],
+    angle,
+    direction,
+    amplitude,
+    nextDist / ((frequency + 1) * 2),
+    prevDist / ((frequency + 1) * 2),
+    pointType
+  );
+}
+
+function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
+  for (var i = 0; i < frequency; i += 1) {
+    var t = (i + 1) / (frequency + 1);
+
+    var dist = pointType === 2
+      ? Math.sqrt(Math.pow(segment.points[3][0] - segment.points[0][0], 2) + Math.pow(segment.points[3][1] - segment.points[0][1], 2))
+      : 0;
+
+    var angle = segment.normalAngle(t);
+    var point = segment.point(t);
+    setPoint(
+      outputBezier,
+      point,
+      angle,
+      direction,
+      amplitude,
+      dist / ((frequency + 1) * 2),
+      dist / ((frequency + 1) * 2),
+      pointType
+    );
+
+    direction = -direction;
+  }
+
+  return direction;
+}
+
+ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
+  var count = path._length;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+
+  if (!path.c) {
+    count -= 1;
+  }
+
+  if (count === 0) return clonedPath;
+
+  var direction = -1;
+  var segment = PolynomialBezier.shapeSegment(path, 0);
+  zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
+
+  for (var i = 0; i < count; i += 1) {
+    direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
+
+    if (i === count - 1 && !path.c) {
+      segment = null;
+    } else {
+      segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
+    }
+
+    zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
+  }
+
+  return clonedPath;
+};
+
+ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amplitude = this.amplitude.v;
+  var frequency = Math.max(0, Math.round(this.frequency.v));
+  var pointType = this.pointsType.v;
+
+  if (amplitude !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function linearOffset(p1, p2, amount) {
+  var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
+  return [
+    polarOffset(p1, angle, amount),
+    polarOffset(p2, angle, amount),
+  ];
+}
+
+function offsetSegment(segment, amount) {
+  var p0; var p1a; var p1b; var p2b; var p2a; var
+    p3;
+  var e;
+  e = linearOffset(segment.points[0], segment.points[1], amount);
+  p0 = e[0];
+  p1a = e[1];
+  e = linearOffset(segment.points[1], segment.points[2], amount);
+  p1b = e[0];
+  p2b = e[1];
+  e = linearOffset(segment.points[2], segment.points[3], amount);
+  p2a = e[0];
+  p3 = e[1];
+  var p1 = lineIntersection(p0, p1a, p1b, p2b);
+  if (p1 === null) p1 = p1a;
+  var p2 = lineIntersection(p2a, p3, p1b, p2b);
+  if (p2 === null) p2 = p2a;
+
+  return new PolynomialBezier(p0, p1, p2, p3);
+}
+
+function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
+  var p0 = seg1.points[3];
+  var p1 = seg2.points[0];
+
+  // Bevel
+  if (lineJoin === 3) return p0;
+
+  // Connected, they don't need a joint
+  if (pointEqual(p0, p1)) return p0;
+
+  // Round
+  if (lineJoin === 2) {
+    var angleOut = -seg1.tangentAngle(1);
+    var angleIn = -seg2.tangentAngle(0) + Math.PI;
+    var center = lineIntersection(
+      p0,
+      polarOffset(p0, angleOut + Math.PI / 2, 100),
+      p1,
+      polarOffset(p1, angleOut + Math.PI / 2, 100)
+    );
+    var radius = center ? pointDistance(center, p0) : pointDistance(p0, p1) / 2;
+
+    var tan = polarOffset(p0, angleOut, 2 * radius * roundCorner);
+    outputBezier.setXYAt(tan[0], tan[1], 'o', outputBezier.length() - 1);
+
+    tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
+    outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
+
+    return p1;
+  }
+
+  // Miter
+  var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
+  var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
+  var intersection = lineIntersection(t0, p0, p1, t1);
+  if (intersection && pointDistance(intersection, p0) < miterLimit) {
+    outputBezier.setTripleAt(
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      outputBezier.length()
+    );
+    return intersection;
+  }
+
+  return p0;
+}
+
+function getIntersection(a, b) {
+  const intersect = a.intersections(b);
+
+  if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
+
+  if (intersect.length) return intersect[0];
+
+  return null;
+}
+
+function pruneSegmentIntersection(a, b) {
+  var outa = a.slice();
+  var outb = b.slice();
+  var intersect = getIntersection(a[a.length - 1], b[0]);
+  if (intersect) {
+    outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
+    outb[0] = b[0].split(intersect[1])[1];
+  }
+  if (a.length > 1 && b.length > 1) {
+    intersect = getIntersection(a[0], b[b.length - 1]);
+    if (intersect) {
+      return [
+        [a[0].split(intersect[0])[0]],
+        [b[b.length - 1].split(intersect[1])[1]],
+      ];
+    }
+  }
+  return [outa, outb];
+}
+
+function pruneIntersections(segments) {
+  var e;
+  for (var i = 1; i < segments.length; i += 1) {
+    e = pruneSegmentIntersection(segments[i - 1], segments[i]);
+    segments[i - 1] = e[0];
+    segments[i] = e[1];
+  }
+
+  if (segments.length > 1) {
+    e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
+    segments[segments.length - 1] = e[0];
+    segments[0] = e[1];
+  }
+
+  return segments;
+}
+
+function offsetSegmentSplit(segment, amount) {
+  /*
+    We split each bezier segment into smaller pieces based
+    on inflection points, this ensures the control point
+    polygon is convex.
+
+    (A cubic bezier can have none, one, or two inflection points)
+  */
+  var flex = segment.inflectionPoints();
+  var left;
+  var right;
+  var split;
+  var mid;
+
+  if (flex.length === 0) {
+    return [offsetSegment(segment, amount)];
+  }
+
+  if (flex.length === 1 || floatEqual(flex[1], 1)) {
+    split = segment.split(flex[0]);
+    left = split[0];
+    right = split[1];
+
+    return [
+      offsetSegment(left, amount),
+      offsetSegment(right, amount),
+    ];
+  }
+
+  split = segment.split(flex[0]);
+  left = split[0];
+  var t = (flex[1] - flex[0]) / (1 - flex[0]);
+  split = split[1].split(t);
+  mid = split[0];
+  right = split[1];
+
+  return [
+    offsetSegment(left, amount),
+    offsetSegment(mid, amount),
+    offsetSegment(right, amount),
+  ];
+}
+
+function OffsetPathModifier() {}
+
+extendPrototype([ShapeModifier], OffsetPathModifier);
+OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this.miterLimit = PropertyFactory.getProp(elem, data.ml, 0, null, this);
+  this.lineJoin = data.lj;
+  this._isAnimated = this.amount.effectsSequence.length !== 0;
+};
+
+OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
+  var outputBezier = shapePool.newElement();
+  outputBezier.c = inputBezier.c;
+  var count = inputBezier.length();
+  if (!inputBezier.c) {
+    count -= 1;
+  }
+  var i; var j; var segment;
+  var multiSegments = [];
+
+  for (i = 0; i < count; i += 1) {
+    segment = PolynomialBezier.shapeSegment(inputBezier, i);
+    multiSegments.push(offsetSegmentSplit(segment, amount));
+  }
+
+  if (!inputBezier.c) {
+    for (i = count - 1; i >= 0; i -= 1) {
+      segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
+      multiSegments.push(offsetSegmentSplit(segment, amount));
+    }
+  }
+
+  multiSegments = pruneIntersections(multiSegments);
+
+  // Add bezier segments to the output and apply line joints
+  var lastPoint = null;
+  var lastSeg = null;
+
+  for (i = 0; i < multiSegments.length; i += 1) {
+    var multiSegment = multiSegments[i];
+
+    if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
+
+    lastSeg = multiSegment[multiSegment.length - 1];
+
+    for (j = 0; j < multiSegment.length; j += 1) {
+      segment = multiSegment[j];
+
+      if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
+        outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
+      } else {
+        outputBezier.setTripleAt(
+          segment.points[0][0],
+          segment.points[0][1],
+          segment.points[1][0],
+          segment.points[1][1],
+          segment.points[0][0],
+          segment.points[0][1],
+          outputBezier.length()
+        );
+      }
+
+      outputBezier.setTripleAt(
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[2][0],
+        segment.points[2][1],
+        outputBezier.length()
+      );
+
+      lastPoint = segment.points[3];
+    }
+  }
+
+  if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
+
+  return outputBezier;
+};
+
+OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+  var miterLimit = this.miterLimit.v;
+  var lineJoin = this.lineJoin;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function getFontProperties(fontData) {
+  var styles = fontData.fStyle ? fontData.fStyle.split(' ') : [];
+
+  var fWeight = 'normal'; var
+    fStyle = 'normal';
+  var len = styles.length;
+  var styleName;
+  for (var i = 0; i < len; i += 1) {
+    styleName = styles[i].toLowerCase();
+    switch (styleName) {
+      case 'italic':
+        fStyle = 'italic';
+        break;
+      case 'bold':
+        fWeight = '700';
+        break;
+      case 'black':
+        fWeight = '900';
+        break;
+      case 'medium':
+        fWeight = '500';
+        break;
+      case 'regular':
+      case 'normal':
+        fWeight = '400';
+        break;
+      case 'light':
+      case 'thin':
+        fWeight = '200';
+        break;
+      default:
+        break;
+    }
+  }
+
+  return {
+    style: fStyle,
+    weight: fontData.fWeight || fWeight,
+  };
+}
+
+const FontManager = (function () {
+  var maxWaitingTime = 5000;
+  var emptyChar = {
+    w: 0,
+    size: 0,
+    shapes: [],
+    data: {
+      shapes: [],
+    },
+  };
+  var combinedCharacters = [];
+  // Hindi characters
+  combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366,
+    2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379,
+    2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
+
+  var BLACK_FLAG_CODE_POINT = 127988;
+  var CANCEL_TAG_CODE_POINT = 917631;
+  var A_TAG_CODE_POINT = 917601;
+  var Z_TAG_CODE_POINT = 917626;
+  var VARIATION_SELECTOR_16_CODE_POINT = 65039;
+  var ZERO_WIDTH_JOINER_CODE_POINT = 8205;
+  var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
+  var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
+
+  var surrogateModifiers = [
+    'd83cdffb',
+    'd83cdffc',
+    'd83cdffd',
+    'd83cdffe',
+    'd83cdfff',
+  ];
+
+  function trimFontOptions(font) {
+    var familyArray = font.split(',');
+    var i;
+    var len = familyArray.length;
+    var enabledFamilies = [];
+    for (i = 0; i < len; i += 1) {
+      if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
+        enabledFamilies.push(familyArray[i]);
+      }
+    }
+    return enabledFamilies.join(',');
+  }
+
+  function setUpNode(font, family) {
+    var parentNode = createTag('span');
+    // Node is invisible to screen readers.
+    parentNode.setAttribute('aria-hidden', true);
+    parentNode.style.fontFamily = family;
+    var node = createTag('span');
+    // Characters that vary significantly among different fonts
+    node.innerText = 'giItT1WQy@!-/#';
+    // Visible - so we can measure it - but not on the screen
+    parentNode.style.position = 'absolute';
+    parentNode.style.left = '-10000px';
+    parentNode.style.top = '-10000px';
+    // Large font size makes even subtle changes obvious
+    parentNode.style.fontSize = '300px';
+    // Reset any font properties
+    parentNode.style.fontVariant = 'normal';
+    parentNode.style.fontStyle = 'normal';
+    parentNode.style.fontWeight = 'normal';
+    parentNode.style.letterSpacing = '0';
+    parentNode.appendChild(node);
+    document.body.appendChild(parentNode);
+
+    // Remember width with no applied web font
+    var width = node.offsetWidth;
+    node.style.fontFamily = trimFontOptions(font) + ', ' + family;
+    return { node: node, w: width, parent: parentNode };
+  }
+
+  function checkLoadedFonts() {
+    var i;
+    var len = this.fonts.length;
+    var node;
+    var w;
+    var loadedCount = len;
+    for (i = 0; i < len; i += 1) {
+      if (this.fonts[i].loaded) {
+        loadedCount -= 1;
+      } else if (this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0) {
+        this.fonts[i].loaded = true;
+      } else {
+        node = this.fonts[i].monoCase.node;
+        w = this.fonts[i].monoCase.w;
+        if (node.offsetWidth !== w) {
+          loadedCount -= 1;
+          this.fonts[i].loaded = true;
+        } else {
+          node = this.fonts[i].sansCase.node;
+          w = this.fonts[i].sansCase.w;
+          if (node.offsetWidth !== w) {
+            loadedCount -= 1;
+            this.fonts[i].loaded = true;
+          }
+        }
+        if (this.fonts[i].loaded) {
+          this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
+          this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
+        }
+      }
+    }
+
+    if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
+      setTimeout(this.checkLoadedFontsBinded, 20);
+    } else {
+      setTimeout(this.setIsLoadedBinded, 10);
+    }
+  }
+
+  function createHelper(fontData, def) {
+    var engine = (document.body && def) ? 'svg' : 'canvas';
+    var helper;
+    var fontProps = getFontProperties(fontData);
+    if (engine === 'svg') {
+      var tHelper = createNS('text');
+      tHelper.style.fontSize = '100px';
+      // tHelper.style.fontFamily = fontData.fFamily;
+      tHelper.setAttribute('font-family', fontData.fFamily);
+      tHelper.setAttribute('font-style', fontProps.style);
+      tHelper.setAttribute('font-weight', fontProps.weight);
+      tHelper.textContent = '1';
+      if (fontData.fClass) {
+        tHelper.style.fontFamily = 'inherit';
+        tHelper.setAttribute('class', fontData.fClass);
+      } else {
+        tHelper.style.fontFamily = fontData.fFamily;
+      }
+      def.appendChild(tHelper);
+      helper = tHelper;
+    } else {
+      var tCanvasHelper = new OffscreenCanvas(500, 500).getContext('2d');
+      tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
+      helper = tCanvasHelper;
+    }
+    function measure(text) {
+      if (engine === 'svg') {
+        helper.textContent = text;
+        return helper.getComputedTextLength();
+      }
+      return helper.measureText(text).width;
+    }
+    return {
+      measureText: measure,
+    };
+  }
+
+  function addFonts(fontData, defs) {
+    if (!fontData) {
+      this.isLoaded = true;
+      return;
+    }
+    if (this.chars) {
+      this.isLoaded = true;
+      this.fonts = fontData.list;
+      return;
+    }
+    if (!document.body) {
+      this.isLoaded = true;
+      fontData.list.forEach((data) => {
+        data.helper = createHelper(data);
+        data.cache = {};
+      });
+      this.fonts = fontData.list;
+      return;
+    }
+
+    var fontArr = fontData.list;
+    var i;
+    var len = fontArr.length;
+    var _pendingFonts = len;
+    for (i = 0; i < len; i += 1) {
+      var shouldLoadFont = true;
+      var loadedSelector;
+      var j;
+      fontArr[i].loaded = false;
+      fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
+      fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
+      if (!fontArr[i].fPath) {
+        fontArr[i].loaded = true;
+        _pendingFonts -= 1;
+      } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
+        loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
+
+        if (loadedSelector.length > 0) {
+          shouldLoadFont = false;
+        }
+
+        if (shouldLoadFont) {
+          var s = createTag('style');
+          s.setAttribute('f-forigin', fontArr[i].fOrigin);
+          s.setAttribute('f-origin', fontArr[i].origin);
+          s.setAttribute('f-family', fontArr[i].fFamily);
+          s.type = 'text/css';
+          s.innerText = '@font-face {font-family: ' + fontArr[i].fFamily + "; font-style: normal; src: url('" + fontArr[i].fPath + "');}";
+          defs.appendChild(s);
+        }
+      } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
+        loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var l = createTag('link');
+          l.setAttribute('f-forigin', fontArr[i].fOrigin);
+          l.setAttribute('f-origin', fontArr[i].origin);
+          l.type = 'text/css';
+          l.rel = 'stylesheet';
+          l.href = fontArr[i].fPath;
+          document.body.appendChild(l);
+        }
+      } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
+        loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (fontArr[i].fPath === loadedSelector[j].src) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var sc = createTag('link');
+          sc.setAttribute('f-forigin', fontArr[i].fOrigin);
+          sc.setAttribute('f-origin', fontArr[i].origin);
+          sc.setAttribute('rel', 'stylesheet');
+          sc.setAttribute('href', fontArr[i].fPath);
+          defs.appendChild(sc);
+        }
+      }
+      fontArr[i].helper = createHelper(fontArr[i], defs);
+      fontArr[i].cache = {};
+      this.fonts.push(fontArr[i]);
+    }
+    if (_pendingFonts === 0) {
+      this.isLoaded = true;
+    } else {
+      // On some cases even if the font is loaded, it won't load correctly when measuring text on canvas.
+      // Adding this timeout seems to fix it
+      setTimeout(this.checkLoadedFonts.bind(this), 100);
+    }
+  }
+
+  function addChars(chars) {
+    if (!chars) {
+      return;
+    }
+    if (!this.chars) {
+      this.chars = [];
+    }
+    var i;
+    var len = chars.length;
+    var j;
+    var jLen = this.chars.length;
+    var found;
+    for (i = 0; i < len; i += 1) {
+      j = 0;
+      found = false;
+      while (j < jLen) {
+        if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
+          found = true;
+        }
+        j += 1;
+      }
+      if (!found) {
+        this.chars.push(chars[i]);
+        jLen += 1;
+      }
+    }
+  }
+
+  function getCharData(char, style, font) {
+    var i = 0;
+    var len = this.chars.length;
+    while (i < len) {
+      if (this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font) {
+        return this.chars[i];
+      }
+      i += 1;
+    }
+    if (((typeof char === 'string' && char.charCodeAt(0) !== 13) || !char)
+            && console
+            && console.warn // eslint-disable-line no-console
+            && !this._warned
+    ) {
+      this._warned = true;
+      console.warn('Missing character from exported characters list: ', char, style, font); // eslint-disable-line no-console
+    }
+    return emptyChar;
+  }
+
+  function measureText(char, fontName, size) {
+    var fontData = this.getFontByName(fontName);
+    // Using the char instead of char.charCodeAt(0)
+    // to avoid collisions between equal chars
+    var index = char;
+    if (!fontData.cache[index]) {
+      var tHelper = fontData.helper;
+      if (char === ' ') {
+        var doubleSize = tHelper.measureText('|' + char + '|');
+        var singleSize = tHelper.measureText('||');
+        fontData.cache[index] = (doubleSize - singleSize) / 100;
+      } else {
+        fontData.cache[index] = tHelper.measureText(char) / 100;
+      }
+    }
+    return fontData.cache[index] * size;
+  }
+
+  function getFontByName(name) {
+    var i = 0;
+    var len = this.fonts.length;
+    while (i < len) {
+      if (this.fonts[i].fName === name) {
+        return this.fonts[i];
+      }
+      i += 1;
+    }
+    return this.fonts[0];
+  }
+
+  function getCodePoint(string) {
+    var codePoint = 0;
+    var first = string.charCodeAt(0);
+    if (first >= 0xD800 && first <= 0xDBFF) {
+      var second = string.charCodeAt(1);
+      if (second >= 0xDC00 && second <= 0xDFFF) {
+        codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+      }
+    }
+    return codePoint;
+  }
+
+  // Skin tone modifiers
+  function isModifier(firstCharCode, secondCharCode) {
+    var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
+    return surrogateModifiers.indexOf(sum) !== -1;
+  }
+
+  function isZeroWidthJoiner(charCode) {
+    return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
+  }
+
+  // This codepoint may change the appearance of the preceding character.
+  // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
+  // as a colorful image as compared to a monochrome text variant.
+  function isVariationSelector(charCode) {
+    return charCode === VARIATION_SELECTOR_16_CODE_POINT;
+  }
+
+  // The regional indicator symbols are a set of 26 alphabetic Unicode
+  /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
+  // two-letter country codes in a way that allows optional special treatment.
+  function isRegionalCode(string) {
+    var codePoint = getCodePoint(string);
+    if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
+      return true;
+    }
+    return false;
+  }
+
+  // Some Emoji implementations represent combinations of
+  // two “regional indicator” letters as a single flag symbol.
+  function isFlagEmoji(string) {
+    return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
+  }
+
+  function isCombinedCharacter(char) {
+    return combinedCharacters.indexOf(char) !== -1;
+  }
+
+  // Regional flags start with a BLACK_FLAG_CODE_POINT
+  // folowed by 5 chars in the TAG range
+  // and end with a CANCEL_TAG_CODE_POINT
+  function isRegionalFlag(text, index) {
+    var codePoint = getCodePoint(text.substr(index, 2));
+    if (codePoint !== BLACK_FLAG_CODE_POINT) {
+      return false;
+    }
+    var count = 0;
+    index += 2;
+    while (count < 5) {
+      codePoint = getCodePoint(text.substr(index, 2));
+      if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
+        return false;
+      }
+      count += 1;
+      index += 2;
+    }
+    return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
+  }
+
+  function setIsLoaded() {
+    this.isLoaded = true;
+  }
+
+  var Font = function () {
+    this.fonts = [];
+    this.chars = null;
+    this.typekitLoaded = 0;
+    this.isLoaded = false;
+    this._warned = false;
+    this.initTime = Date.now();
+    this.setIsLoadedBinded = this.setIsLoaded.bind(this);
+    this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
+  };
+  Font.isModifier = isModifier;
+  Font.isZeroWidthJoiner = isZeroWidthJoiner;
+  Font.isFlagEmoji = isFlagEmoji;
+  Font.isRegionalCode = isRegionalCode;
+  Font.isCombinedCharacter = isCombinedCharacter;
+  Font.isRegionalFlag = isRegionalFlag;
+  Font.isVariationSelector = isVariationSelector;
+  Font.BLACK_FLAG_CODE_POINT = BLACK_FLAG_CODE_POINT;
+
+  var fontPrototype = {
+    addChars: addChars,
+    addFonts: addFonts,
+    getCharData: getCharData,
+    getFontByName: getFontByName,
+    measureText: measureText,
+    checkLoadedFonts: checkLoadedFonts,
+    setIsLoaded: setIsLoaded,
+  };
+
+  Font.prototype = fontPrototype;
+
+  return Font;
+}());
+
+function SlotManager(animationData) {
+  this.animationData = animationData;
+}
+SlotManager.prototype.getProp = function (data) {
+  if (this.animationData.slots
+    && this.animationData.slots[data.sid]
+  ) {
+    return Object.assign(data, this.animationData.slots[data.sid].p);
+  }
+  return data;
+};
+
+function slotFactory(animationData) {
+  return new SlotManager(animationData);
+}
+
+function RenderableElement() {
+
+}
+
+RenderableElement.prototype = {
+  initRenderable: function () {
+    // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
+    this.isInRange = false;
+    // layer's display state
+    this.hidden = false;
+    // If layer's transparency equals 0, it can be hidden
+    this.isTransparent = false;
+    // list of animated components
+    this.renderableComponents = [];
+  },
+  addRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) === -1) {
+      this.renderableComponents.push(component);
+    }
+  },
+  removeRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) !== -1) {
+      this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1);
+    }
+  },
+  prepareRenderableFrame: function (num) {
+    this.checkLayerLimits(num);
+  },
+  checkTransparency: function () {
+    if (this.finalTransform.mProp.o.v <= 0) {
+      if (!this.isTransparent && this.globalData.renderConfig.hideOnTransparent) {
+        this.isTransparent = true;
+        this.hide();
+      }
+    } else if (this.isTransparent) {
+      this.isTransparent = false;
+      this.show();
+    }
+  },
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     *
+     */
+  checkLayerLimits: function (num) {
+    if (this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) {
+      if (this.isInRange !== true) {
+        this.globalData._mdf = true;
+        this._mdf = true;
+        this.isInRange = true;
+        this.show();
+      }
+    } else if (this.isInRange !== false) {
+      this.globalData._mdf = true;
+      this.isInRange = false;
+      this.hide();
+    }
+  },
+  renderRenderable: function () {
+    var i;
+    var len = this.renderableComponents.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderableComponents[i].renderFrame(this._isFirstFrame);
+    }
+    /* this.maskManager.renderFrame(this.finalTransform.mat);
+        this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
+  },
+  sourceRectAtTime: function () {
+    return {
+      top: 0,
+      left: 0,
+      width: 100,
+      height: 100,
+    };
+  },
+  getLayerSize: function () {
+    if (this.data.ty === 5) {
+      return { w: this.data.textData.width, h: this.data.textData.height };
+    }
+    return { w: this.data.width, h: this.data.height };
+  },
+};
+
+const getBlendMode = (function () {
+  var blendModeEnums = {
+    0: 'source-over',
+    1: 'multiply',
+    2: 'screen',
+    3: 'overlay',
+    4: 'darken',
+    5: 'lighten',
+    6: 'color-dodge',
+    7: 'color-burn',
+    8: 'hard-light',
+    9: 'soft-light',
+    10: 'difference',
+    11: 'exclusion',
+    12: 'hue',
+    13: 'saturation',
+    14: 'color',
+    15: 'luminosity',
+  };
+
+  return function (mode) {
+    return blendModeEnums[mode] || '';
+  };
+}());
+
+function SliderEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function AngleEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function ColorEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function PointEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function LayerIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function MaskIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function CheckboxEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function NoValueEffect() {
+  this.p = {};
+}
+
+function EffectsManager(data, element) {
+  var effects = data.ef || [];
+  this.effectElements = [];
+  var i;
+  var len = effects.length;
+  var effectItem;
+  for (i = 0; i < len; i += 1) {
+    effectItem = new GroupEffect(effects[i], element);
+    this.effectElements.push(effectItem);
+  }
+}
+
+function GroupEffect(data, element) {
+  this.init(data, element);
+}
+
+extendPrototype([DynamicPropertyContainer], GroupEffect);
+
+GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
+
+GroupEffect.prototype.init = function (data, element) {
+  this.data = data;
+  this.effectElements = [];
+  this.initDynamicPropertyContainer(element);
+  var i;
+  var len = this.data.ef.length;
+  var eff;
+  var effects = this.data.ef;
+  for (i = 0; i < len; i += 1) {
+    eff = null;
+    switch (effects[i].ty) {
+      case 0:
+        eff = new SliderEffect(effects[i], element, this);
+        break;
+      case 1:
+        eff = new AngleEffect(effects[i], element, this);
+        break;
+      case 2:
+        eff = new ColorEffect(effects[i], element, this);
+        break;
+      case 3:
+        eff = new PointEffect(effects[i], element, this);
+        break;
+      case 4:
+      case 7:
+        eff = new CheckboxEffect(effects[i], element, this);
+        break;
+      case 10:
+        eff = new LayerIndexEffect(effects[i], element, this);
+        break;
+      case 11:
+        eff = new MaskIndexEffect(effects[i], element, this);
+        break;
+      case 5:
+        eff = new EffectsManager(effects[i], element, this);
+        break;
+        // case 6:
+      default:
+        eff = new NoValueEffect(effects[i], element, this);
+        break;
+    }
+    if (eff) {
+      this.effectElements.push(eff);
+    }
+  }
+};
+
+function BaseElement() {
+}
+
+BaseElement.prototype = {
+  checkMasks: function () {
+    if (!this.data.hasMask) {
+      return false;
+    }
+    var i = 0;
+    var len = this.data.masksProperties.length;
+    while (i < len) {
+      if ((this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false)) {
+        return true;
+      }
+      i += 1;
+    }
+    return false;
+  },
+  initExpressions: function () {
+    const expressionsInterfaces = getExpressionInterfaces();
+    if (!expressionsInterfaces) {
+      return;
+    }
+    const LayerExpressionInterface = expressionsInterfaces('layer');
+    const EffectsExpressionInterface = expressionsInterfaces('effects');
+    const ShapeExpressionInterface = expressionsInterfaces('shape');
+    const TextExpressionInterface = expressionsInterfaces('text');
+    const CompExpressionInterface = expressionsInterfaces('comp');
+    this.layerInterface = LayerExpressionInterface(this);
+    if (this.data.hasMask && this.maskManager) {
+      this.layerInterface.registerMaskInterface(this.maskManager);
+    }
+    var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
+    this.layerInterface.registerEffectsInterface(effectsInterface);
+
+    if (this.data.ty === 0 || this.data.xt) {
+      this.compInterface = CompExpressionInterface(this);
+    } else if (this.data.ty === 4) {
+      this.layerInterface.shapeInterface = ShapeExpressionInterface(this.shapesData, this.itemsData, this.layerInterface);
+      this.layerInterface.content = this.layerInterface.shapeInterface;
+    } else if (this.data.ty === 5) {
+      this.layerInterface.textInterface = TextExpressionInterface(this);
+      this.layerInterface.text = this.layerInterface.textInterface;
+    }
+  },
+  setBlendMode: function () {
+    var blendModeValue = getBlendMode(this.data.bm);
+    var elem = this.baseElement || this.layerElement;
+
+    elem.style['mix-blend-mode'] = blendModeValue;
+  },
+  initBaseData: function (data, globalData, comp) {
+    this.globalData = globalData;
+    this.comp = comp;
+    this.data = data;
+    this.layerId = createElementID();
+
+    // Stretch factor for old animations missing this property.
+    if (!this.data.sr) {
+      this.data.sr = 1;
+    }
+    // effects manager
+    this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
+  },
+  getType: function () {
+    return this.type;
+  },
+  sourceRectAtTime: function () {},
+};
+
+/**
+ * @file
+ * Handles element's layer frame update.
+ * Checks layer in point and out point
+ *
+ */
+
+function FrameElement() {}
+
+FrameElement.prototype = {
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     */
+  initFrame: function () {
+    // set to true when inpoint is rendered
+    this._isFirstFrame = false;
+    // list of animated properties
+    this.dynamicProperties = [];
+    // If layer has been modified in current tick this will be true
+    this._mdf = false;
+  },
+  /**
+     * @function
+     * Calculates all dynamic values
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     * @param {boolean} isVisible
+     * if layers is currently in range
+     *
+     */
+  prepareProperties: function (num, isVisible) {
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      if (isVisible || (this._isParent && this.dynamicProperties[i].propType === 'transform')) {
+        this.dynamicProperties[i].getValue();
+        if (this.dynamicProperties[i]._mdf) {
+          this.globalData._mdf = true;
+          this._mdf = true;
+        }
+      }
+    }
+  },
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+    }
+  },
+};
+
+function FootageElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.footageData = globalData.imageLoader.getAsset(this.assetData);
+  this.initBaseData(data, globalData, comp);
+}
+
+FootageElement.prototype.prepareFrame = function () {
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
+
+FootageElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+FootageElement.prototype.renderFrame = function () {
+};
+
+FootageElement.prototype.destroy = function () {
+};
+
+FootageElement.prototype.initExpressions = function () {
+  const expressionsInterfaces = getExpressionInterfaces();
+  if (!expressionsInterfaces) {
+    return;
+  }
+  const FootageInterface = expressionsInterfaces('footage');
+  this.layerInterface = FootageInterface(this);
+};
+
+FootageElement.prototype.getFootageData = function () {
+  return this.footageData;
+};
+
+function AudioElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initBaseData(data, globalData, comp);
+  this._isPlaying = false;
+  this._canPlay = false;
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  this.audio = this.globalData.audioController.createAudio(assetPath);
+  this._currentTime = 0;
+  this.globalData.audioController.addAudio(this);
+  this._volumeMultiplier = 1;
+  this._volume = 1;
+  this._previousVolume = null;
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+  this.lv = PropertyFactory.getProp(this, data.au && data.au.lv ? data.au.lv : { k: [100] }, 1, 0.01, this);
+}
+
+AudioElement.prototype.prepareFrame = function (num) {
+  this.prepareRenderableFrame(num, true);
+  this.prepareProperties(num, true);
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    this._currentTime = timeRemapped;
+  } else {
+    this._currentTime = num / this.data.sr;
+  }
+  this._volume = this.lv.v[0];
+  var totalVolume = this._volume * this._volumeMultiplier;
+  if (this._previousVolume !== totalVolume) {
+    this._previousVolume = totalVolume;
+    this.audio.volume(totalVolume);
+  }
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
+
+AudioElement.prototype.renderFrame = function () {
+  if (this.isInRange && this._canPlay) {
+    if (!this._isPlaying) {
+      this.audio.play();
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+      this._isPlaying = true;
+    } else if (!this.audio.playing()
+      || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1
+    ) {
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+    }
+  }
+};
+
+AudioElement.prototype.show = function () {
+  // this.audio.play()
+};
+
+AudioElement.prototype.hide = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+};
+
+AudioElement.prototype.pause = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+  this._canPlay = false;
+};
+
+AudioElement.prototype.resume = function () {
+  this._canPlay = true;
+};
+
+AudioElement.prototype.setRate = function (rateValue) {
+  this.audio.rate(rateValue);
+};
+
+AudioElement.prototype.volume = function (volumeValue) {
+  this._volumeMultiplier = volumeValue;
+  this._previousVolume = volumeValue * this._volume;
+  this.audio.volume(this._previousVolume);
+};
+
+AudioElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+AudioElement.prototype.destroy = function () {
+};
+
+AudioElement.prototype.sourceRectAtTime = function () {
+};
+
+AudioElement.prototype.initExpressions = function () {
+};
+
+function BaseRenderer() {}
+BaseRenderer.prototype.checkLayers = function (num) {
+  var i;
+  var len = this.layers.length;
+  var data;
+  this.completeLayers = true;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (!this.elements[i]) {
+      data = this.layers[i];
+      if (data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) {
+        this.buildItem(i);
+      }
+    }
+    this.completeLayers = this.elements[i] ? this.completeLayers : false;
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.createItem = function (layer) {
+  switch (layer.ty) {
+    case 2:
+      return this.createImage(layer);
+    case 0:
+      return this.createComp(layer);
+    case 1:
+      return this.createSolid(layer);
+    case 3:
+      return this.createNull(layer);
+    case 4:
+      return this.createShape(layer);
+    case 5:
+      return this.createText(layer);
+    case 6:
+      return this.createAudio(layer);
+    case 13:
+      return this.createCamera(layer);
+    case 15:
+      return this.createFootage(layer);
+    default:
+      return this.createNull(layer);
+  }
+};
+
+BaseRenderer.prototype.createCamera = function () {
+  throw new Error('You\'re using a 3d camera. Try the html renderer.');
+};
+
+BaseRenderer.prototype.createAudio = function (data) {
+  return new AudioElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.createFootage = function (data) {
+  return new FootageElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.buildAllItems = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    this.buildItem(i);
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.includeLayers = function (newLayers) {
+  this.completeLayers = false;
+  var i;
+  var len = newLayers.length;
+  var j;
+  var jLen = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    j = 0;
+    while (j < jLen) {
+      if (this.layers[j].id === newLayers[i].id) {
+        this.layers[j] = newLayers[i];
+        break;
+      }
+      j += 1;
+    }
+  }
+};
+
+BaseRenderer.prototype.setProjectInterface = function (pInterface) {
+  this.globalData.projectInterface = pInterface;
+};
+
+BaseRenderer.prototype.initItems = function () {
+  if (!this.globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+};
+BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
+  var elements = this.elements;
+  var layers = this.layers;
+  var i = 0;
+  var len = layers.length;
+  while (i < len) {
+    if (layers[i].ind == parentName) { // eslint-disable-line eqeqeq
+      if (!elements[i] || elements[i] === true) {
+        this.buildItem(i);
+        this.addPendingElement(element);
+      } else {
+        hierarchy.push(elements[i]);
+        elements[i].setAsParent();
+        if (layers[i].parent !== undefined) {
+          this.buildElementParenting(element, layers[i].parent, hierarchy);
+        } else {
+          element.setHierarchy(hierarchy);
+        }
+      }
+    }
+    i += 1;
+  }
+};
+
+BaseRenderer.prototype.addPendingElement = function (element) {
+  this.pendingElements.push(element);
+};
+
+BaseRenderer.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var len = assets.length;
+  for (i = 0; i < len; i += 1) {
+    if (assets[i].xt) {
+      var comp = this.createComp(assets[i]);
+      comp.initExpressions();
+      this.globalData.projectInterface.registerComposition(comp);
+    }
+  }
+};
+
+BaseRenderer.prototype.getElementById = function (ind) {
+  var i;
+  var len = this.elements.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i].data.ind === ind) {
+      return this.elements[i];
+    }
+  }
+  return null;
+};
+
+BaseRenderer.prototype.getElementByPath = function (path) {
+  var pathValue = path.shift();
+  var element;
+  if (typeof pathValue === 'number') {
+    element = this.elements[pathValue];
+  } else {
+    var i;
+    var len = this.elements.length;
+    for (i = 0; i < len; i += 1) {
+      if (this.elements[i].data.nm === pathValue) {
+        element = this.elements[i];
+        break;
+      }
+    }
+  }
+  if (path.length === 0) {
+    return element;
+  }
+  return element.getElementByPath(path);
+};
+
+BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
+  this.globalData.fontManager = new FontManager();
+  this.globalData.slotManager = slotFactory(animData);
+  this.globalData.fontManager.addChars(animData.chars);
+  this.globalData.fontManager.addFonts(animData.fonts, fontsContainer);
+  this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+  this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+  this.globalData.imageLoader = this.animationItem.imagePreloader;
+  this.globalData.audioController = this.animationItem.audioController;
+  this.globalData.frameId = 0;
+  this.globalData.frameRate = animData.fr;
+  this.globalData.nm = animData.nm;
+  this.globalData.compSize = {
+    w: animData.w,
+    h: animData.h,
+  };
+};
+
+var effectTypes = {
+  TRANSFORM_EFFECT: 'transformEFfect',
+};
+
+function TransformElement() {}
+
+TransformElement.prototype = {
+  initTransform: function () {
+    var mat = new Matrix();
+    this.finalTransform = {
+      mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : { o: 0 },
+      _matMdf: false,
+      _localMatMdf: false,
+      _opMdf: false,
+      mat: mat,
+      localMat: mat,
+      localOpacity: 1,
+    };
+    if (this.data.ao) {
+      this.finalTransform.mProp.autoOriented = true;
+    }
+
+    // TODO: check TYPE 11: Guided elements
+    if (this.data.ty !== 11) {
+      // this.createElements();
+    }
+  },
+  renderTransform: function () {
+    this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
+    this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
+
+    if (this.hierarchy) {
+      var mat;
+      var finalMat = this.finalTransform.mat;
+      var i = 0;
+      var len = this.hierarchy.length;
+      // Checking if any of the transformation matrices in the hierarchy chain has changed.
+      if (!this.finalTransform._matMdf) {
+        while (i < len) {
+          if (this.hierarchy[i].finalTransform.mProp._mdf) {
+            this.finalTransform._matMdf = true;
+            break;
+          }
+          i += 1;
+        }
+      }
+
+      if (this.finalTransform._matMdf) {
+        mat = this.finalTransform.mProp.v.props;
+        finalMat.cloneFromProps(mat);
+        for (i = 0; i < len; i += 1) {
+          finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
+        }
+      }
+    }
+    if (!this.localTransforms || this.finalTransform._matMdf) {
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+    }
+    if (this.finalTransform._opMdf) {
+      this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderLocalTransform: function () {
+    if (this.localTransforms) {
+      var i = 0;
+      var len = this.localTransforms.length;
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+      if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
+        while (i < len) {
+          if (this.localTransforms[i]._mdf) {
+            this.finalTransform._localMatMdf = true;
+          }
+          if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
+            this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+            this.finalTransform._opMdf = true;
+          }
+          i += 1;
+        }
+      }
+      if (this.finalTransform._localMatMdf) {
+        var localMat = this.finalTransform.localMat;
+        this.localTransforms[0].matrix.clone(localMat);
+        for (i = 1; i < len; i += 1) {
+          var lmat = this.localTransforms[i].matrix;
+          localMat.multiply(lmat);
+        }
+        localMat.multiply(this.finalTransform.mat);
+      }
+      if (this.finalTransform._opMdf) {
+        var localOp = this.finalTransform.localOpacity;
+        for (i = 0; i < len; i += 1) {
+          localOp *= this.localTransforms[i].opacity * 0.01;
+        }
+        this.finalTransform.localOpacity = localOp;
+      }
+    }
+  },
+  searchEffectTransforms: function () {
+    if (this.renderableEffectsManager) {
+      var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+      if (transformEffects.length) {
+        this.localTransforms = [];
+        this.finalTransform.localMat = new Matrix();
+        var i = 0;
+        var len = transformEffects.length;
+        for (i = 0; i < len; i += 1) {
+          this.localTransforms.push(transformEffects[i]);
+        }
+      }
+    }
+  },
+  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;
+    var len = transforms.length;
+    var 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;
+  },
+  mHelper: new Matrix(),
+};
+
+function MaskElement(data, element, globalData) {
+  this.data = data;
+  this.element = element;
+  this.globalData = globalData;
+  this.storedData = [];
+  this.masksProperties = this.data.masksProperties || [];
+  this.maskElement = null;
+  var defs = this.globalData.defs;
+  var i;
+  var len = this.masksProperties ? this.masksProperties.length : 0;
+  this.viewData = createSizedArray(len);
+  this.solidPath = '';
+
+  var path;
+  var properties = this.masksProperties;
+  var count = 0;
+  var currentMasks = [];
+  var j;
+  var jLen;
+  var layerId = createElementID();
+  var rect;
+  var expansor;
+  var feMorph;
+  var x;
+  var maskType = 'clipPath';
+  var maskRef = 'clip-path';
+  for (i = 0; i < len; i += 1) {
+    if ((properties[i].mode !== 'a' && properties[i].mode !== 'n') || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
+      maskType = 'mask';
+      maskRef = 'mask';
+    }
+
+    if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
+      rect = createNS('rect');
+      rect.setAttribute('fill', '#ffffff');
+      rect.setAttribute('width', this.element.comp.data.w || 0);
+      rect.setAttribute('height', this.element.comp.data.h || 0);
+      currentMasks.push(rect);
+    } else {
+      rect = null;
+    }
+
+    path = createNS('path');
+    if (properties[i].mode === 'n') {
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        elem: path,
+        lastPath: '',
+      };
+      defs.appendChild(path);
+    } else {
+      count += 1;
+
+      path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      path.setAttribute('clip-rule', 'nonzero');
+      var filterID;
+
+      if (properties[i].x.k !== 0) {
+        maskType = 'mask';
+        maskRef = 'mask';
+        x = PropertyFactory.getProp(this.element, properties[i].x, 0, null, this.element);
+        filterID = createElementID();
+        expansor = createNS('filter');
+        expansor.setAttribute('id', filterID);
+        feMorph = createNS('feMorphology');
+        feMorph.setAttribute('operator', 'erode');
+        feMorph.setAttribute('in', 'SourceGraphic');
+        feMorph.setAttribute('radius', '0');
+        expansor.appendChild(feMorph);
+        defs.appendChild(expansor);
+        path.setAttribute('stroke', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      } else {
+        feMorph = null;
+        x = null;
+      }
+
+      // TODO move this to a factory or to a constructor
+      this.storedData[i] = {
+        elem: path,
+        x: x,
+        expan: feMorph,
+        lastPath: '',
+        lastOperator: '',
+        filterId: filterID,
+        lastRadius: 0,
+      };
+      if (properties[i].mode === 'i') {
+        jLen = currentMasks.length;
+        var g = createNS('g');
+        for (j = 0; j < jLen; j += 1) {
+          g.appendChild(currentMasks[j]);
+        }
+        var mask = createNS('mask');
+        mask.setAttribute('mask-type', 'alpha');
+        mask.setAttribute('id', layerId + '_' + count);
+        mask.appendChild(path);
+        defs.appendChild(mask);
+        g.setAttribute('mask', 'url(' + getLocationHref() + '#' + layerId + '_' + count + ')');
+
+        currentMasks.length = 0;
+        currentMasks.push(g);
+      } else {
+        currentMasks.push(path);
+      }
+      if (properties[i].inv && !this.solidPath) {
+        this.solidPath = this.createLayerSolidPath();
+      }
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        elem: path,
+        lastPath: '',
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        invRect: rect,
+      };
+      if (!this.viewData[i].prop.k) {
+        this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
+      }
+    }
+  }
+
+  this.maskElement = createNS(maskType);
+
+  len = currentMasks.length;
+  for (i = 0; i < len; i += 1) {
+    this.maskElement.appendChild(currentMasks[i]);
+  }
+
+  if (count > 0) {
+    this.maskElement.setAttribute('id', layerId);
+    this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
+    defs.appendChild(this.maskElement);
+  }
+  if (this.viewData.length) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+MaskElement.prototype.getMaskProperty = function (pos) {
+  return this.viewData[pos].prop;
+};
+
+MaskElement.prototype.renderFrame = function (isFirstFrame) {
+  var finalMat = this.element.finalTransform.mat;
+  var i;
+  var len = this.masksProperties.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.viewData[i].prop._mdf || isFirstFrame) {
+      this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
+    }
+    if (this.viewData[i].op._mdf || isFirstFrame) {
+      this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
+    }
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
+        this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
+      }
+      if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
+        var feMorph = this.storedData[i].expan;
+        if (this.storedData[i].x.v < 0) {
+          if (this.storedData[i].lastOperator !== 'erode') {
+            this.storedData[i].lastOperator = 'erode';
+            this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
+          }
+          feMorph.setAttribute('radius', -this.storedData[i].x.v);
+        } else {
+          if (this.storedData[i].lastOperator !== 'dilate') {
+            this.storedData[i].lastOperator = 'dilate';
+            this.storedData[i].elem.setAttribute('filter', null);
+          }
+          this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
+        }
+      }
+    }
+  }
+};
+
+MaskElement.prototype.getMaskelement = function () {
+  return this.maskElement;
+};
+
+MaskElement.prototype.createLayerSolidPath = function () {
+  var path = 'M0,0 ';
+  path += ' h' + this.globalData.compSize.w;
+  path += ' v' + this.globalData.compSize.h;
+  path += ' h-' + this.globalData.compSize.w;
+  path += ' v-' + this.globalData.compSize.h + ' ';
+  return path;
+};
+
+MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
+  var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  var i;
+  var len;
+  len = pathNodes._length;
+  for (i = 1; i < len; i += 1) {
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
+  }
+  // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+  if (pathNodes.c && len > 1) {
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  }
+  // pathNodes.__renderedString = pathString;
+
+  if (viewData.lastPath !== pathString) {
+    var pathShapeValue = '';
+    if (viewData.elem) {
+      if (pathNodes.c) {
+        pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
+      }
+      viewData.elem.setAttribute('d', pathShapeValue);
+    }
+    viewData.lastPath = pathString;
+  }
+};
+
+MaskElement.prototype.destroy = function () {
+  this.element = null;
+  this.globalData = null;
+  this.maskElement = null;
+  this.data = null;
+  this.masksProperties = null;
+};
+
+const filtersFactory = (function () {
+  var ob = {};
+  ob.createFilter = createFilter;
+  ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
+
+  function createFilter(filId, skipCoordinates) {
+    var fil = createNS('filter');
+    fil.setAttribute('id', filId);
+    if (skipCoordinates !== true) {
+      fil.setAttribute('filterUnits', 'objectBoundingBox');
+      fil.setAttribute('x', '0%');
+      fil.setAttribute('y', '0%');
+      fil.setAttribute('width', '100%');
+      fil.setAttribute('height', '100%');
+    }
+    return fil;
+  }
+
+  function createAlphaToLuminanceFilter() {
+    var feColorMatrix = createNS('feColorMatrix');
+    feColorMatrix.setAttribute('type', 'matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+    feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
+    return feColorMatrix;
+  }
+
+  return ob;
+}());
+
+const featureSupport = (function () {
+  var ob = {
+    maskType: true,
+    svgLumaHidden: true,
+    offscreenCanvas: typeof OffscreenCanvas !== 'undefined',
+  };
+  if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
+    ob.maskType = false;
+  }
+  if (/firefox/i.test(navigator.userAgent)) {
+    ob.svgLumaHidden = false;
+  }
+  return ob;
+}());
+
+var registeredEffects$1 = {};
+var idPrefix = 'filter_result_';
+
+function SVGEffects(elem) {
+  var i;
+  var source = 'SourceGraphic';
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  var filId = createElementID();
+  var fil = filtersFactory.createFilter(filId, true);
+  var count = 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects$1[type]) {
+      var Effect = registeredEffects$1[type].effect;
+      filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
+      source = idPrefix + count;
+      if (registeredEffects$1[type].countsAsEffect) {
+        count += 1;
+      }
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (count) {
+    elem.globalData.defs.appendChild(fil);
+    elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+SVGEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect$1(id, effect, countsAsEffect) {
+  registeredEffects$1[id] = {
+    effect,
+    countsAsEffect,
+  };
+}
+
+function SVGBaseElement() {
+}
+
+SVGBaseElement.prototype = {
+  initRendererElement: function () {
+    this.layerElement = createNS('g');
+  },
+  createContainerElements: function () {
+    this.matteElement = createNS('g');
+    this.transformedElement = this.layerElement;
+    this.maskedElement = this.layerElement;
+    this._sizeChanged = false;
+    var layerElementParent = null;
+    // If this layer acts as a mask for the following layer
+    if (this.data.td) {
+      this.matteMasks = {};
+      var gg = createNS('g');
+      gg.setAttribute('id', this.layerId);
+      gg.appendChild(this.layerElement);
+      layerElementParent = gg;
+      this.globalData.defs.appendChild(gg);
+    } else if (this.data.tt) {
+      this.matteElement.appendChild(this.layerElement);
+      layerElementParent = this.matteElement;
+      this.baseElement = this.matteElement;
+    } else {
+      this.baseElement = this.layerElement;
+    }
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
+    if (this.data.ty === 0 && !this.data.hd) {
+      var cp = createNS('clipPath');
+      var pt = createNS('path');
+      pt.setAttribute('d', 'M0,0 L' + this.data.w + ',0 L' + this.data.w + ',' + this.data.h + ' L0,' + this.data.h + 'z');
+      var clipId = createElementID();
+      cp.setAttribute('id', clipId);
+      cp.appendChild(pt);
+      this.globalData.defs.appendChild(cp);
+
+      if (this.checkMasks()) {
+        var cpGroup = createNS('g');
+        cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+        cpGroup.appendChild(this.layerElement);
+        this.transformedElement = cpGroup;
+        if (layerElementParent) {
+          layerElementParent.appendChild(this.transformedElement);
+        } else {
+          this.baseElement = this.transformedElement;
+        }
+      } else {
+        this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+      }
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    if (this.finalTransform._localMatMdf) {
+      this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
+    }
+    if (this.finalTransform._opMdf) {
+      this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
+    }
+  },
+  destroyBaseElement: function () {
+    this.layerElement = null;
+    this.matteElement = null;
+    this.maskManager.destroy();
+  },
+  getBaseElement: function () {
+    if (this.data.hd) {
+      return null;
+    }
+    return this.baseElement;
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+    this.renderableEffectsManager = new SVGEffects(this);
+    this.searchEffectTransforms();
+  },
+  getMatte: function (matteType) {
+    // This should not be a common case. But for backward compatibility, we'll create the matte object.
+    // It solves animations that have two consecutive layers marked as matte masks.
+    // Which is an undefined behavior in AE.
+    if (!this.matteMasks) {
+      this.matteMasks = {};
+    }
+    if (!this.matteMasks[matteType]) {
+      var id = this.layerId + '_' + matteType;
+      var filId;
+      var fil;
+      var useElement;
+      var gg;
+      if (matteType === 1 || matteType === 3) {
+        var masker = createNS('mask');
+        masker.setAttribute('id', id);
+        masker.setAttribute('mask-type', matteType === 3 ? 'luminance' : 'alpha');
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        masker.appendChild(useElement);
+        this.globalData.defs.appendChild(masker);
+        if (!featureSupport.maskType && matteType === 1) {
+          masker.setAttribute('mask-type', 'luminance');
+          filId = createElementID();
+          fil = filtersFactory.createFilter(filId);
+          this.globalData.defs.appendChild(fil);
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          gg.appendChild(useElement);
+          masker.appendChild(gg);
+          gg.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        }
+      } else if (matteType === 2) {
+        var maskGroup = createNS('mask');
+        maskGroup.setAttribute('id', id);
+        maskGroup.setAttribute('mask-type', 'alpha');
+        var maskGrouper = createNS('g');
+        maskGroup.appendChild(maskGrouper);
+        filId = createElementID();
+        fil = filtersFactory.createFilter(filId);
+        /// /
+        var feCTr = createNS('feComponentTransfer');
+        feCTr.setAttribute('in', 'SourceGraphic');
+        fil.appendChild(feCTr);
+        var feFunc = createNS('feFuncA');
+        feFunc.setAttribute('type', 'table');
+        feFunc.setAttribute('tableValues', '1.0 0.0');
+        feCTr.appendChild(feFunc);
+        /// /
+        this.globalData.defs.appendChild(fil);
+        var alphaRect = createNS('rect');
+        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');
+        alphaRect.setAttribute('opacity', '0');
+        maskGrouper.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        maskGrouper.appendChild(alphaRect);
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        maskGrouper.appendChild(useElement);
+        if (!featureSupport.maskType) {
+          maskGroup.setAttribute('mask-type', 'luminance');
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          maskGrouper.appendChild(alphaRect);
+          gg.appendChild(this.layerElement);
+          maskGrouper.appendChild(gg);
+        }
+        this.globalData.defs.appendChild(maskGroup);
+      }
+      this.matteMasks[matteType] = id;
+    }
+    return this.matteMasks[matteType];
+  },
+  setMatte: function (id) {
+    if (!this.matteElement) {
+      return;
+    }
+    this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+  },
+};
+
+/**
+ * @file
+ * Handles AE's layer parenting property.
+ *
+ */
+
+function HierarchyElement() {}
+
+HierarchyElement.prototype = {
+  /**
+     * @function
+     * Initializes hierarchy properties
+     *
+     */
+  initHierarchy: function () {
+    // element's parent list
+    this.hierarchy = [];
+    // if element is parent of another layer _isParent will be true
+    this._isParent = false;
+    this.checkParenting();
+  },
+  /**
+     * @function
+     * Sets layer's hierarchy.
+     * @param {array} hierarch
+     * layer's parent list
+     *
+     */
+  setHierarchy: function (hierarchy) {
+    this.hierarchy = hierarchy;
+  },
+  /**
+     * @function
+     * Sets layer as parent.
+     *
+     */
+  setAsParent: function () {
+    this._isParent = true;
+  },
+  /**
+     * @function
+     * Searches layer's parenting chain
+     *
+     */
+  checkParenting: function () {
+    if (this.data.parent !== undefined) {
+      this.comp.buildElementParenting(this, this.data.parent, []);
+    }
+  },
+};
+
+function RenderableDOMElement() {}
+
+(function () {
+  var _prototype = {
+    initElement: function (data, globalData, comp) {
+      this.initFrame();
+      this.initBaseData(data, globalData, comp);
+      this.initTransform(data, globalData, comp);
+      this.initHierarchy();
+      this.initRenderable();
+      this.initRendererElement();
+      this.createContainerElements();
+      this.createRenderableComponents();
+      this.createContent();
+      this.hide();
+    },
+    hide: function () {
+      // console.log('HIDE', this);
+      if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+        var elem = this.baseElement || this.layerElement;
+        elem.style.display = 'none';
+        this.hidden = true;
+      }
+    },
+    show: function () {
+      // console.log('SHOW', this);
+      if (this.isInRange && !this.isTransparent) {
+        if (!this.data.hd) {
+          var elem = this.baseElement || this.layerElement;
+          elem.style.display = 'block';
+        }
+        this.hidden = false;
+        this._isFirstFrame = true;
+      }
+    },
+    renderFrame: function () {
+      // If it is exported as hidden (data.hd === true) no need to render
+      // If it is not visible no need to render
+      if (this.data.hd || this.hidden) {
+        return;
+      }
+      this.renderTransform();
+      this.renderRenderable();
+      this.renderLocalTransform();
+      this.renderElement();
+      this.renderInnerContent();
+      if (this._isFirstFrame) {
+        this._isFirstFrame = false;
+      }
+    },
+    renderInnerContent: function () {},
+    prepareFrame: function (num) {
+      this._mdf = false;
+      this.prepareRenderableFrame(num);
+      this.prepareProperties(num, this.isInRange);
+      this.checkTransparency();
+    },
+    destroy: function () {
+      this.innerElem = null;
+      this.destroyBaseElement();
+    },
+  };
+  extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement);
+}());
+
+function IImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  if (this.assetData && this.assetData.sid) {
+    this.assetData = globalData.slotManager.getProp(this.assetData);
+  }
+  this.initElement(data, globalData, comp);
+  this.sourceRect = {
+    top: 0, left: 0, width: this.assetData.w, height: this.assetData.h,
+  };
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
+
+IImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+
+  this.innerElem = createNS('image');
+  this.innerElem.setAttribute('width', this.assetData.w + 'px');
+  this.innerElem.setAttribute('height', this.assetData.h + 'px');
+  this.innerElem.setAttribute('preserveAspectRatio', this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio);
+  this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+
+  this.layerElement.appendChild(this.innerElem);
+};
+
+IImageElement.prototype.sourceRectAtTime = function () {
+  return this.sourceRect;
+};
+
+function ProcessedElement(element, position) {
+  this.elem = element;
+  this.pos = position;
+}
+
+function IShapeElement() {
+}
+
+IShapeElement.prototype = {
+  addShapeToModifiers: function (data) {
+    var i;
+    var len = this.shapeModifiers.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapeModifiers[i].addShape(data);
+    }
+  },
+  isShapeInAnimatedModifiers: function (data) {
+    var i = 0;
+    var len = this.shapeModifiers.length;
+    while (i < len) {
+      if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
+        return true;
+      }
+    }
+    return false;
+  },
+  renderModifiers: function () {
+    if (!this.shapeModifiers.length) {
+      return;
+    }
+    var i;
+    var len = this.shapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].sh.reset();
+    }
+
+    len = this.shapeModifiers.length;
+    var shouldBreakProcess;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+      // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+      // TODO: find a better solution for this
+      if (shouldBreakProcess) {
+        break;
+      }
+    }
+  },
+
+  searchProcessedElement: function (elem) {
+    var elements = this.processedElements;
+    var i = 0;
+    var len = elements.length;
+    while (i < len) {
+      if (elements[i].elem === elem) {
+        return elements[i].pos;
+      }
+      i += 1;
+    }
+    return 0;
+  },
+  addProcessedElement: function (elem, pos) {
+    var elements = this.processedElements;
+    var i = elements.length;
+    while (i) {
+      i -= 1;
+      if (elements[i].elem === elem) {
+        elements[i].pos = pos;
+        return;
+      }
+    }
+    elements.push(new ProcessedElement(elem, pos));
+  },
+  prepareFrame: function (num) {
+    this.prepareRenderableFrame(num);
+    this.prepareProperties(num, this.isInRange);
+  },
+};
+
+const lineCapEnum = {
+  1: 'butt',
+  2: 'round',
+  3: 'square',
+};
+
+const lineJoinEnum = {
+  1: 'miter',
+  2: 'round',
+  3: 'bevel',
+};
+
+function SVGShapeData(transformers, level, shape) {
+  this.caches = [];
+  this.styles = [];
+  this.transformers = transformers;
+  this.lStr = '';
+  this.sh = shape;
+  this.lvl = level;
+  // TODO find if there are some cases where _isAnimated can be false.
+  // For now, since shapes add up with other shapes. They have to be calculated every time.
+  // One way of finding out is checking if all styles associated to this shape depend only of this shape
+  this._isAnimated = !!shape.k;
+  // TODO: commenting this for now since all shapes are animated
+  var i = 0;
+  var len = transformers.length;
+  while (i < len) {
+    if (transformers[i].mProps.dynamicProperties.length) {
+      this._isAnimated = true;
+      break;
+    }
+    i += 1;
+  }
+}
+
+SVGShapeData.prototype.setAsAnimated = function () {
+  this._isAnimated = true;
+};
+
+function SVGStyleData(data, level) {
+  this.data = data;
+  this.type = data.ty;
+  this.d = '';
+  this.lvl = level;
+  this._mdf = false;
+  this.closed = data.hd === true;
+  this.pElem = createNS('path');
+  this.msElem = null;
+}
+
+SVGStyleData.prototype.reset = function () {
+  this.d = '';
+  this._mdf = false;
+};
+
+function DashProperty(elem, data, renderer, container) {
+  this.elem = elem;
+  this.frameId = -1;
+  this.dataProps = createSizedArray(data.length);
+  this.renderer = renderer;
+  this.k = false;
+  this.dashStr = '';
+  this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0);
+  this.dashoffset = createTypedArray('float32', 1);
+  this.initDynamicPropertyContainer(container);
+  var i;
+  var len = data.length || 0;
+  var prop;
+  for (i = 0; i < len; i += 1) {
+    prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
+    this.k = prop.k || this.k;
+    this.dataProps[i] = { n: data[i].n, p: prop };
+  }
+  if (!this.k) {
+    this.getValue(true);
+  }
+  this._isAnimated = this.k;
+}
+
+DashProperty.prototype.getValue = function (forceRender) {
+  if (this.elem.globalData.frameId === this.frameId && !forceRender) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+  this._mdf = this._mdf || forceRender;
+  if (this._mdf) {
+    var i = 0;
+    var len = this.dataProps.length;
+    if (this.renderer === 'svg') {
+      this.dashStr = '';
+    }
+    for (i = 0; i < len; i += 1) {
+      if (this.dataProps[i].n !== 'o') {
+        if (this.renderer === 'svg') {
+          this.dashStr += ' ' + this.dataProps[i].p.v;
+        } else {
+          this.dashArray[i] = this.dataProps[i].p.v;
+        }
+      } else {
+        this.dashoffset[0] = this.dataProps[i].p.v;
+      }
+    }
+  }
+};
+extendPrototype([DynamicPropertyContainer], DashProperty);
+
+function SVGStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
+
+function SVGFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
+
+function SVGNoStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
+
+function GradientProperty(elem, data, container) {
+  this.data = data;
+  this.c = createTypedArray('uint8c', data.p * 4);
+  var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p * 4) : data.k.k.length - data.p * 4;
+  this.o = createTypedArray('float32', cLength);
+  this._cmdf = false;
+  this._omdf = false;
+  this._collapsable = this.checkCollapsable();
+  this._hasOpacity = cLength;
+  this.initDynamicPropertyContainer(container);
+  this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this);
+  this.k = this.prop.k;
+  this.getValue(true);
+}
+
+GradientProperty.prototype.comparePoints = function (values, points) {
+  var i = 0;
+  var len = this.o.length / 2;
+  var diff;
+  while (i < len) {
+    diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
+    if (diff > 0.01) {
+      return false;
+    }
+    i += 1;
+  }
+  return true;
+};
+
+GradientProperty.prototype.checkCollapsable = function () {
+  if (this.o.length / 2 !== this.c.length / 4) {
+    return false;
+  }
+  if (this.data.k.k[0].s) {
+    var i = 0;
+    var len = this.data.k.k.length;
+    while (i < len) {
+      if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
+        return false;
+      }
+      i += 1;
+    }
+  } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
+    return false;
+  }
+  return true;
+};
+
+GradientProperty.prototype.getValue = function (forceRender) {
+  this.prop.getValue();
+  this._mdf = false;
+  this._cmdf = false;
+  this._omdf = false;
+  if (this.prop._mdf || forceRender) {
+    var i;
+    var len = this.data.p * 4;
+    var mult;
+    var val;
+    for (i = 0; i < len; i += 1) {
+      mult = i % 4 === 0 ? 100 : 255;
+      val = Math.round(this.prop.v[i] * mult);
+      if (this.c[i] !== val) {
+        this.c[i] = val;
+        this._cmdf = !forceRender;
+      }
+    }
+    if (this.o.length) {
+      len = this.prop.v.length;
+      for (i = this.data.p * 4; i < len; i += 1) {
+        mult = i % 2 === 0 ? 100 : 1;
+        val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
+        if (this.o[i - this.data.p * 4] !== val) {
+          this.o[i - this.data.p * 4] = val;
+          this._omdf = !forceRender;
+        }
+      }
+    }
+    this._mdf = !forceRender;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], GradientProperty);
+
+function SVGGradientFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.initGradientData(elem, data, styleOb);
+}
+
+SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 1, null, this);
+  this.h = PropertyFactory.getProp(elem, data.h || { k: 0 }, 0, 0.01, this);
+  this.a = PropertyFactory.getProp(elem, data.a || { k: 0 }, 0, degToRads, this);
+  this.g = new GradientProperty(elem, data.g, this);
+  this.style = styleOb;
+  this.stops = [];
+  this.setGradientData(styleOb.pElem, data);
+  this.setGradientOpacity(data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+};
+
+SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
+  var gradientId = createElementID();
+  var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+  gfill.setAttribute('id', gradientId);
+  gfill.setAttribute('spreadMethod', 'pad');
+  gfill.setAttribute('gradientUnits', 'userSpaceOnUse');
+  var stops = [];
+  var stop;
+  var j;
+  var jLen;
+  jLen = data.g.p * 4;
+  for (j = 0; j < jLen; j += 4) {
+    stop = createNS('stop');
+    gfill.appendChild(stop);
+    stops.push(stop);
+  }
+  pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
+  this.gf = gfill;
+  this.cst = stops;
+};
+
+SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
+  if (this.g._hasOpacity && !this.g._collapsable) {
+    var stop;
+    var j;
+    var jLen;
+    var mask = createNS('mask');
+    var maskElement = createNS('path');
+    mask.appendChild(maskElement);
+    var opacityId = createElementID();
+    var maskId = createElementID();
+    mask.setAttribute('id', maskId);
+    var opFill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+    opFill.setAttribute('id', opacityId);
+    opFill.setAttribute('spreadMethod', 'pad');
+    opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
+    jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
+    var stops = this.stops;
+    for (j = data.g.p * 4; j < jLen; j += 2) {
+      stop = createNS('stop');
+      stop.setAttribute('stop-color', 'rgb(255,255,255)');
+      opFill.appendChild(stop);
+      stops.push(stop);
+    }
+    maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
+    this.maskId = maskId;
+    styleOb.msElem = maskElement;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
+
+function SVGGradientStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.initGradientData(elem, data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
+
+function ShapeGroupData() {
+  this.it = [];
+  this.prevViewData = [];
+  this.gr = createNS('g');
+}
+
+function SVGTransformData(mProps, op, container) {
+  this.transform = {
+    mProps: mProps,
+    op: op,
+    container: container,
+  };
+  this.elements = [];
+  this._isAnimated = this.transform.mProps.dynamicProperties.length || this.transform.op.effectsSequence.length;
+}
+
+const buildShapeString = function (pathNodes, length, closed, mat) {
+  if (length === 0) {
+    return '';
+  }
+  var _o = pathNodes.o;
+  var _i = pathNodes.i;
+  var _v = pathNodes.v;
+  var i;
+  var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+  for (i = 1; i < length; i += 1) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
+  }
+  if (closed && length) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+    shapeString += 'z';
+  }
+  return shapeString;
+};
+
+const SVGElementsRenderer = (function () {
+  var _identityMatrix = new Matrix();
+  var _matrixHelper = new Matrix();
+
+  var ob = {
+    createRenderFunction: createRenderFunction,
+  };
+
+  function createRenderFunction(data) {
+    switch (data.ty) {
+      case 'fl':
+        return renderFill;
+      case 'gf':
+        return renderGradient;
+      case 'gs':
+        return renderGradientStroke;
+      case 'st':
+        return renderStroke;
+      case 'sh':
+      case 'el':
+      case 'rc':
+      case 'sr':
+        return renderPath;
+      case 'tr':
+        return renderContentTransform;
+      case 'no':
+        return renderNoop;
+      default:
+        return null;
+    }
+  }
+
+  function renderContentTransform(styleData, itemData, isFirstFrame) {
+    if (isFirstFrame || itemData.transform.op._mdf) {
+      itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
+    }
+    if (isFirstFrame || itemData.transform.mProps._mdf) {
+      itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
+    }
+  }
+
+  function renderNoop() {
+
+  }
+
+  function renderPath(styleData, itemData, isFirstFrame) {
+    var j;
+    var jLen;
+    var pathStringTransformed;
+    var redraw;
+    var pathNodes;
+    var l;
+    var lLen = itemData.styles.length;
+    var lvl = itemData.lvl;
+    var paths;
+    var mat;
+    var iterations;
+    var k;
+    for (l = 0; l < lLen; l += 1) {
+      redraw = itemData.sh._mdf || isFirstFrame;
+      if (itemData.styles[l].lvl < lvl) {
+        mat = _matrixHelper.reset();
+        iterations = lvl - itemData.styles[l].lvl;
+        k = itemData.transformers.length - 1;
+        while (!redraw && iterations > 0) {
+          redraw = itemData.transformers[k].mProps._mdf || redraw;
+          iterations -= 1;
+          k -= 1;
+        }
+        if (redraw) {
+          iterations = lvl - itemData.styles[l].lvl;
+          k = itemData.transformers.length - 1;
+          while (iterations > 0) {
+            mat.multiply(itemData.transformers[k].mProps.v);
+            iterations -= 1;
+            k -= 1;
+          }
+        }
+      } else {
+        mat = _identityMatrix;
+      }
+      paths = itemData.sh.paths;
+      jLen = paths._length;
+      if (redraw) {
+        pathStringTransformed = '';
+        for (j = 0; j < jLen; j += 1) {
+          pathNodes = paths.shapes[j];
+          if (pathNodes && pathNodes._length) {
+            pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
+          }
+        }
+        itemData.caches[l] = pathStringTransformed;
+      } else {
+        pathStringTransformed = itemData.caches[l];
+      }
+      itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
+      itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
+    }
+  }
+
+  function renderFill(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+
+    if (itemData.c._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
+    }
+  }
+
+  function renderGradientStroke(styleData, itemData, isFirstFrame) {
+    renderGradient(styleData, itemData, isFirstFrame);
+    renderStroke(styleData, itemData, isFirstFrame);
+  }
+
+  function renderGradient(styleData, itemData, isFirstFrame) {
+    var gfill = itemData.gf;
+    var hasOpacity = itemData.g._hasOpacity;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+
+    if (itemData.o._mdf || isFirstFrame) {
+      var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
+      itemData.style.pElem.setAttribute(attr, itemData.o.v);
+    }
+    if (itemData.s._mdf || isFirstFrame) {
+      var attr1 = styleData.t === 1 ? 'x1' : 'cx';
+      var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
+      gfill.setAttribute(attr1, pt1[0]);
+      gfill.setAttribute(attr2, pt1[1]);
+      if (hasOpacity && !itemData.g._collapsable) {
+        itemData.of.setAttribute(attr1, pt1[0]);
+        itemData.of.setAttribute(attr2, pt1[1]);
+      }
+    }
+    var stops;
+    var i;
+    var len;
+    var stop;
+    if (itemData.g._cmdf || isFirstFrame) {
+      stops = itemData.cst;
+      var cValues = itemData.g.c;
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        stop.setAttribute('offset', cValues[i * 4] + '%');
+        stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
+      }
+    }
+    if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
+      var oValues = itemData.g.o;
+      if (itemData.g._collapsable) {
+        stops = itemData.cst;
+      } else {
+        stops = itemData.ost;
+      }
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        if (!itemData.g._collapsable) {
+          stop.setAttribute('offset', oValues[i * 2] + '%');
+        }
+        stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
+      }
+    }
+    if (styleData.t === 1) {
+      if (itemData.e._mdf || isFirstFrame) {
+        gfill.setAttribute('x2', pt2[0]);
+        gfill.setAttribute('y2', pt2[1]);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('x2', pt2[0]);
+          itemData.of.setAttribute('y2', pt2[1]);
+        }
+      }
+    } else {
+      var rad;
+      if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
+        rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        gfill.setAttribute('r', rad);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('r', rad);
+        }
+      }
+      if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (!rad) {
+          rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        }
+        var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+        var percent = itemData.h.v;
+        if (percent >= 1) {
+          percent = 0.99;
+        } else if (percent <= -1) {
+          percent = -0.99;
+        }
+        var dist = rad * percent;
+        var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+        var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+        gfill.setAttribute('fx', x);
+        gfill.setAttribute('fy', y);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('fx', x);
+          itemData.of.setAttribute('fy', y);
+        }
+      }
+      // gfill.setAttribute('fy','200');
+    }
+  }
+
+  function renderStroke(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+    var d = itemData.d;
+    if (d && (d._mdf || isFirstFrame) && d.dashStr) {
+      styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
+      styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
+    }
+    if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
+      styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
+    }
+    if (itemData.w._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
+      if (styleElem.msElem) {
+        styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
+      }
+    }
+  }
+
+  return ob;
+}());
+
+function SVGShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
+
+SVGShapeElement.prototype.initSecondaryElement = function () {
+};
+
+SVGShapeElement.prototype.identityMatrix = new Matrix();
+
+SVGShapeElement.prototype.buildExpressionInterface = function () {};
+
+SVGShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+};
+
+/*
+This method searches for multiple shapes that affect a single element and one of them is animated
+*/
+SVGShapeElement.prototype.filterUniqueShapes = function () {
+  var i;
+  var len = this.shapes.length;
+  var shape;
+  var j;
+  var jLen = this.stylesList.length;
+  var style;
+  var tempShapes = [];
+  var areAnimated = false;
+  for (j = 0; j < jLen; j += 1) {
+    style = this.stylesList[j];
+    areAnimated = false;
+    tempShapes.length = 0;
+    for (i = 0; i < len; i += 1) {
+      shape = this.shapes[i];
+      if (shape.styles.indexOf(style) !== -1) {
+        tempShapes.push(shape);
+        areAnimated = shape._isAnimated || areAnimated;
+      }
+    }
+    if (tempShapes.length > 1 && areAnimated) {
+      this.setShapesAsAnimated(tempShapes);
+    }
+  }
+};
+
+SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
+  var i;
+  var len = shapes.length;
+  for (i = 0; i < len; i += 1) {
+    shapes[i].setAsAnimated();
+  }
+};
+
+SVGShapeElement.prototype.createStyleElement = function (data, level) {
+  // TODO: prevent drawing of hidden styles
+  var elementData;
+  var styleOb = new SVGStyleData(data, level);
+
+  var pathElement = styleOb.pElem;
+  if (data.ty === 'st') {
+    elementData = new SVGStrokeStyleData(this, data, styleOb);
+  } else if (data.ty === 'fl') {
+    elementData = new SVGFillStyleData(this, data, styleOb);
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
+    elementData = new GradientConstructor(this, data, styleOb);
+    this.globalData.defs.appendChild(elementData.gf);
+    if (elementData.maskId) {
+      this.globalData.defs.appendChild(elementData.ms);
+      this.globalData.defs.appendChild(elementData.of);
+      pathElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + elementData.maskId + ')');
+    }
+  } else if (data.ty === 'no') {
+    elementData = new SVGNoStyleData(this, data, styleOb);
+  }
+
+  if (data.ty === 'st' || data.ty === 'gs') {
+    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);
+    }
+  }
+
+  if (data.r === 2) {
+    pathElement.setAttribute('fill-rule', 'evenodd');
+  }
+
+  if (data.ln) {
+    pathElement.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    pathElement.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  this.stylesList.push(styleOb);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createGroupElement = function (data) {
+  var elementData = new ShapeGroupData();
+  if (data.ln) {
+    elementData.gr.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    elementData.gr.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  return elementData;
+};
+
+SVGShapeElement.prototype.createTransformElement = function (data, container) {
+  var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
+  var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
+  var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
+  var i = 0;
+  var len = this.animatedContents.length;
+  while (i < len) {
+    if (this.animatedContents[i].element === element) {
+      return;
+    }
+    i += 1;
+  }
+  this.animatedContents.push({
+    fn: SVGElementsRenderer.createRenderFunction(data),
+    element: element,
+    data: data,
+  });
+};
+
+SVGShapeElement.prototype.setElementStyles = function (elementData) {
+  var arr = elementData.styles;
+  var j;
+  var jLen = this.stylesList.length;
+  for (j = 0; j < jLen; j += 1) {
+    if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
+      arr.push(this.stylesList[j]);
+    }
+  }
+};
+
+SVGShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+};
+
+SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
+  var ownTransformers = [].concat(transformers);
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var currentTransform;
+  var modifier;
+  var processedPos;
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._render = render;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], level);
+      } else {
+        itemsData[i].style.closed = arr[i].hd;
+      }
+      if (arr[i]._render) {
+        if (itemsData[i].style.pElem.parentNode !== container) {
+          container.appendChild(itemsData[i].style.pElem);
+        }
+      }
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
+      if (arr[i]._render) {
+        if (itemsData[i].gr.parentNode !== container) {
+          container.appendChild(itemsData[i].gr);
+        }
+      }
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        itemsData[i] = this.createTransformElement(arr[i], container);
+      }
+      currentTransform = itemsData[i].transform;
+      ownTransformers.push(currentTransform);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
+      }
+      this.setElementStyles(itemsData[i]);
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        render = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  len = ownStyles.length;
+  for (i = 0; i < len; i += 1) {
+    ownStyles[i].closed = true;
+  }
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+SVGShapeElement.prototype.renderInnerContent = function () {
+  this.renderModifiers();
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    this.stylesList[i].reset();
+  }
+  this.renderShape();
+  for (i = 0; i < len; i += 1) {
+    if (this.stylesList[i]._mdf || this._isFirstFrame) {
+      if (this.stylesList[i].msElem) {
+        this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+        // Adding M0 0 fixes same mask bug on all browsers
+        this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
+      }
+      this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
+    }
+  }
+};
+
+SVGShapeElement.prototype.renderShape = function () {
+  var i;
+  var len = this.animatedContents.length;
+  var animatedContent;
+  for (i = 0; i < len; i += 1) {
+    animatedContent = this.animatedContents[i];
+    if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
+      animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
+    }
+  }
+};
+
+SVGShapeElement.prototype.destroy = function () {
+  this.destroyBaseElement();
+  this.shapesData = null;
+  this.itemsData = null;
+};
+
+function LetterProps(o, sw, sc, fc, m, p) {
+  this.o = o;
+  this.sw = sw;
+  this.sc = sc;
+  this.fc = fc;
+  this.m = m;
+  this.p = p;
+  this._mdf = {
+    o: true,
+    sw: !!sw,
+    sc: !!sc,
+    fc: !!fc,
+    m: true,
+    p: true,
+  };
+}
+
+LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
+  this._mdf.o = false;
+  this._mdf.sw = false;
+  this._mdf.sc = false;
+  this._mdf.fc = false;
+  this._mdf.m = false;
+  this._mdf.p = false;
+  var updated = false;
+
+  if (this.o !== o) {
+    this.o = o;
+    this._mdf.o = true;
+    updated = true;
+  }
+  if (this.sw !== sw) {
+    this.sw = sw;
+    this._mdf.sw = true;
+    updated = true;
+  }
+  if (this.sc !== sc) {
+    this.sc = sc;
+    this._mdf.sc = true;
+    updated = true;
+  }
+  if (this.fc !== fc) {
+    this.fc = fc;
+    this._mdf.fc = true;
+    updated = true;
+  }
+  if (this.m !== m) {
+    this.m = m;
+    this._mdf.m = true;
+    updated = true;
+  }
+  if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
+    this.p = p;
+    this._mdf.p = true;
+    updated = true;
+  }
+  return updated;
+};
+
+function TextProperty(elem, data) {
+  this._frameId = initialDefaultFrame;
+  this.pv = '';
+  this.v = '';
+  this.kf = false;
+  this._isFirstFrame = true;
+  this._mdf = false;
+  if (data.d && data.d.sid) {
+    data.d = elem.globalData.slotManager.getProp(data.d);
+  }
+  this.data = data;
+  this.elem = elem;
+  this.comp = this.elem.comp;
+  this.keysIndex = 0;
+  this.canResize = false;
+  this.minimumFontSize = 1;
+  this.effectsSequence = [];
+  this.currentData = {
+    ascent: 0,
+    boxWidth: this.defaultBoxWidth,
+    f: '',
+    fStyle: '',
+    fWeight: '',
+    fc: '',
+    j: '',
+    justifyOffset: '',
+    l: [],
+    lh: 0,
+    lineWidths: [],
+    ls: '',
+    of: '',
+    s: '',
+    sc: '',
+    sw: 0,
+    t: 0,
+    tr: 0,
+    sz: 0,
+    ps: null,
+    fillColorAnim: false,
+    strokeColorAnim: false,
+    strokeWidthAnim: false,
+    yOffset: 0,
+    finalSize: 0,
+    finalText: [],
+    finalLineHeight: 0,
+    __complete: false,
+
+  };
+  this.copyData(this.currentData, this.data.d.k[0].s);
+
+  if (!this.searchProperty()) {
+    this.completeTextData(this.currentData);
+  }
+}
+
+TextProperty.prototype.defaultBoxWidth = [0, 0];
+
+TextProperty.prototype.copyData = function (obj, data) {
+  for (var s in data) {
+    if (Object.prototype.hasOwnProperty.call(data, s)) {
+      obj[s] = data[s];
+    }
+  }
+  return obj;
+};
+
+TextProperty.prototype.setCurrentData = function (data) {
+  if (!data.__complete) {
+    this.completeTextData(data);
+  }
+  this.currentData = data;
+  this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
+  this._mdf = true;
+};
+
+TextProperty.prototype.searchProperty = function () {
+  return this.searchKeyframes();
+};
+
+TextProperty.prototype.searchKeyframes = function () {
+  this.kf = this.data.d.k.length > 1;
+  if (this.kf) {
+    this.addEffect(this.getKeyframeValue.bind(this));
+  }
+  return this.kf;
+};
+
+TextProperty.prototype.addEffect = function (effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.getValue = function (_finalValue) {
+  if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
+    return;
+  }
+  this.currentData.t = this.data.d.k[this.keysIndex].s.t;
+  var currentValue = this.currentData;
+  var currentIndex = this.keysIndex;
+  if (this.lock) {
+    this.setCurrentData(this.currentData);
+    return;
+  }
+  this.lock = true;
+  this._mdf = false;
+  var i; var
+    len = this.effectsSequence.length;
+  var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
+  for (i = 0; i < len; i += 1) {
+    // Checking if index changed to prevent creating a new object every time the expression updates.
+    if (currentIndex !== this.keysIndex) {
+      finalValue = this.effectsSequence[i](finalValue, finalValue.t);
+    } else {
+      finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
+    }
+  }
+  if (currentValue !== finalValue) {
+    this.setCurrentData(finalValue);
+  }
+  this.v = this.currentData;
+  this.pv = this.v;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+};
+
+TextProperty.prototype.getKeyframeValue = function () {
+  var textKeys = this.data.d.k;
+  var frameNum = this.elem.comp.renderedFrame;
+  var i = 0; var
+    len = textKeys.length;
+  while (i <= len - 1) {
+    if (i === len - 1 || textKeys[i + 1].t > frameNum) {
+      break;
+    }
+    i += 1;
+  }
+  if (this.keysIndex !== i) {
+    this.keysIndex = i;
+  }
+  return this.data.d.k[this.keysIndex].s;
+};
+
+TextProperty.prototype.buildFinalText = function (text) {
+  var charactersArray = [];
+  var i = 0;
+  var len = text.length;
+  var charCode;
+  var secondCharCode;
+  var shouldCombine = false;
+  var shouldCombineNext = false;
+  var currentChars = '';
+  while (i < len) {
+    shouldCombine = shouldCombineNext;
+    shouldCombineNext = false;
+    charCode = text.charCodeAt(i);
+    currentChars = text.charAt(i);
+    if (FontManager.isCombinedCharacter(charCode)) {
+      shouldCombine = true;
+      // It's a potential surrogate pair (this is the High surrogate)
+    } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+      if (FontManager.isRegionalFlag(text, i)) {
+        currentChars = text.substr(i, 14);
+      } else {
+        secondCharCode = text.charCodeAt(i + 1);
+        // It's a surrogate pair (this is the Low surrogate)
+        if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
+          if (FontManager.isModifier(charCode, secondCharCode)) {
+            currentChars = text.substr(i, 2);
+            shouldCombine = true;
+          } else if (FontManager.isFlagEmoji(text.substr(i, 4))) {
+            currentChars = text.substr(i, 4);
+          } else {
+            currentChars = text.substr(i, 2);
+          }
+        }
+      }
+    } else if (charCode > 0xDBFF) {
+      secondCharCode = text.charCodeAt(i + 1);
+      if (FontManager.isVariationSelector(charCode)) {
+        shouldCombine = true;
+      }
+    } else if (FontManager.isZeroWidthJoiner(charCode)) {
+      shouldCombine = true;
+      shouldCombineNext = true;
+    }
+    if (shouldCombine) {
+      charactersArray[charactersArray.length - 1] += currentChars;
+      shouldCombine = false;
+    } else {
+      charactersArray.push(currentChars);
+    }
+    i += currentChars.length;
+  }
+  return charactersArray;
+};
+
+TextProperty.prototype.completeTextData = function (documentData) {
+  documentData.__complete = true;
+  var fontManager = this.elem.globalData.fontManager;
+  var data = this.data;
+  var letters = [];
+  var i; var
+    len;
+  var newLineFlag; var index = 0; var
+    val;
+  var anchorGrouping = data.m.g;
+  var currentSize = 0; var currentPos = 0; var currentLine = 0; var
+    lineWidths = [];
+  var lineWidth = 0;
+  var maxLineWidth = 0;
+  var j; var
+    jLen;
+  var fontData = fontManager.getFontByName(documentData.f);
+  var charData; var
+    cLength = 0;
+
+  var fontProps = getFontProperties(fontData);
+  documentData.fWeight = fontProps.weight;
+  documentData.fStyle = fontProps.style;
+  documentData.finalSize = documentData.s;
+  documentData.finalText = this.buildFinalText(documentData.t);
+  len = documentData.finalText.length;
+  documentData.finalLineHeight = documentData.lh;
+  var trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+  var charCode;
+  if (documentData.sz) {
+    var flag = true;
+    var boxWidth = documentData.sz[0];
+    var boxHeight = documentData.sz[1];
+    var currentHeight; var
+      finalText;
+    while (flag) {
+      finalText = this.buildFinalText(documentData.t);
+      currentHeight = 0;
+      lineWidth = 0;
+      len = finalText.length;
+      trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+      var lastSpaceIndex = -1;
+      for (i = 0; i < len; i += 1) {
+        charCode = finalText[i].charCodeAt(0);
+        newLineFlag = false;
+        if (finalText[i] === ' ') {
+          lastSpaceIndex = i;
+        } else if (charCode === 13 || charCode === 3) {
+          lineWidth = 0;
+          newLineFlag = true;
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+        }
+        if (fontManager.chars) {
+          charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
+          cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+        } else {
+          // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
+          cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
+        }
+        if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
+          if (lastSpaceIndex === -1) {
+            len += 1;
+          } else {
+            i = lastSpaceIndex;
+          }
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+          finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+          // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
+          lastSpaceIndex = -1;
+          lineWidth = 0;
+        } else {
+          lineWidth += cLength;
+          lineWidth += trackingOffset;
+        }
+      }
+      currentHeight += (fontData.ascent * documentData.finalSize) / 100;
+      if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
+        documentData.finalSize -= 1;
+        documentData.finalLineHeight = (documentData.finalSize * documentData.lh) / documentData.s;
+      } else {
+        documentData.finalText = finalText;
+        len = documentData.finalText.length;
+        flag = false;
+      }
+    }
+  }
+  lineWidth = -trackingOffset;
+  cLength = 0;
+  var uncollapsedSpaces = 0;
+  var currentChar;
+  for (i = 0; i < len; i += 1) {
+    newLineFlag = false;
+    currentChar = documentData.finalText[i];
+    charCode = currentChar.charCodeAt(0);
+    if (charCode === 13 || charCode === 3) {
+      uncollapsedSpaces = 0;
+      lineWidths.push(lineWidth);
+      maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+      lineWidth = -2 * trackingOffset;
+      val = '';
+      newLineFlag = true;
+      currentLine += 1;
+    } else {
+      val = currentChar;
+    }
+    if (fontManager.chars) {
+      charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
+      cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+    } else {
+      // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
+      // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
+      cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
+    }
+
+    //
+    if (currentChar === ' ') {
+      uncollapsedSpaces += cLength + trackingOffset;
+    } else {
+      lineWidth += cLength + trackingOffset + uncollapsedSpaces;
+      uncollapsedSpaces = 0;
+    }
+    letters.push({
+      l: cLength, an: cLength, add: currentSize, n: newLineFlag, anIndexes: [], val: val, line: currentLine, animatorJustifyOffset: 0,
+    });
+    if (anchorGrouping == 2) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || val === ' ' || i === len - 1) {
+        if (val === '' || val === ' ') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        index += 1;
+        currentSize = 0;
+      }
+    } else if (anchorGrouping == 3) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || i === len - 1) {
+        if (val === '') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        currentSize = 0;
+        index += 1;
+      }
+    } else {
+      letters[index].ind = index;
+      letters[index].extra = 0;
+      index += 1;
+    }
+  }
+  documentData.l = letters;
+  maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+  lineWidths.push(lineWidth);
+  if (documentData.sz) {
+    documentData.boxWidth = documentData.sz[0];
+    documentData.justifyOffset = 0;
+  } else {
+    documentData.boxWidth = maxLineWidth;
+    switch (documentData.j) {
+      case 1:
+        documentData.justifyOffset = -documentData.boxWidth;
+        break;
+      case 2:
+        documentData.justifyOffset = -documentData.boxWidth / 2;
+        break;
+      default:
+        documentData.justifyOffset = 0;
+    }
+  }
+  documentData.lineWidths = lineWidths;
+
+  var animators = data.a; var animatorData; var
+    letterData;
+  jLen = animators.length;
+  var based; var ind; var
+    indexes = [];
+  for (j = 0; j < jLen; j += 1) {
+    animatorData = animators[j];
+    if (animatorData.a.sc) {
+      documentData.strokeColorAnim = true;
+    }
+    if (animatorData.a.sw) {
+      documentData.strokeWidthAnim = true;
+    }
+    if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
+      documentData.fillColorAnim = true;
+    }
+    ind = 0;
+    based = animatorData.s.b;
+    for (i = 0; i < len; i += 1) {
+      letterData = letters[i];
+      letterData.anIndexes[j] = ind;
+      if ((based == 1 && letterData.val !== '') || (based == 2 && letterData.val !== '' && letterData.val !== ' ') || (based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1)) || (based == 4 && (letterData.n || i == len - 1))) { // eslint-disable-line eqeqeq
+        if (animatorData.s.rn === 1) {
+          indexes.push(ind);
+        }
+        ind += 1;
+      }
+    }
+    data.a[j].s.totalChars = ind;
+    var currentInd = -1; var
+      newInd;
+    if (animatorData.s.rn === 1) {
+      for (i = 0; i < len; i += 1) {
+        letterData = letters[i];
+        if (currentInd != letterData.anIndexes[j]) { // eslint-disable-line eqeqeq
+          currentInd = letterData.anIndexes[j];
+          newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
+        }
+        letterData.anIndexes[j] = newInd;
+      }
+    }
+  }
+  documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
+  documentData.ls = documentData.ls || 0;
+  documentData.ascent = (fontData.ascent * documentData.finalSize) / 100;
+};
+
+TextProperty.prototype.updateDocumentData = function (newData, index) {
+  index = index === undefined ? this.keysIndex : index;
+  var dData = this.copyData({}, this.data.d.k[index].s);
+  dData = this.copyData(dData, newData);
+  this.data.d.k[index].s = dData;
+  this.recalculate(index);
+  this.setCurrentData(dData);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.recalculate = function (index) {
+  var dData = this.data.d.k[index].s;
+  dData.__complete = false;
+  this.keysIndex = 0;
+  this._isFirstFrame = true;
+  this.getValue(dData);
+};
+
+TextProperty.prototype.canResizeFont = function (_canResize) {
+  this.canResize = _canResize;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
+  this.minimumFontSize = Math.floor(_fontValue) || 1;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+const TextSelectorProp = (function () {
+  var max = Math.max;
+  var min = Math.min;
+  var floor = Math.floor;
+
+  function TextSelectorPropFactory(elem, data) {
+    this._currentTextLength = -1;
+    this.k = false;
+    this.data = data;
+    this.elem = elem;
+    this.comp = elem.comp;
+    this.finalS = 0;
+    this.finalE = 0;
+    this.initDynamicPropertyContainer(elem);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: 0 }, 0, 0, this);
+    if ('e' in data) {
+      this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
+    } else {
+      this.e = { v: 100 };
+    }
+    this.o = PropertyFactory.getProp(elem, data.o || { k: 0 }, 0, 0, this);
+    this.xe = PropertyFactory.getProp(elem, data.xe || { k: 0 }, 0, 0, this);
+    this.ne = PropertyFactory.getProp(elem, data.ne || { k: 0 }, 0, 0, this);
+    this.sm = PropertyFactory.getProp(elem, data.sm || { k: 100 }, 0, 0, this);
+    this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
+    if (!this.dynamicProperties.length) {
+      this.getValue();
+    }
+  }
+
+  TextSelectorPropFactory.prototype = {
+    getMult: function (ind) {
+      if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
+        this.getValue();
+      }
+      var x1 = 0;
+      var y1 = 0;
+      var x2 = 1;
+      var y2 = 1;
+      if (this.ne.v > 0) {
+        x1 = this.ne.v / 100.0;
+      } else {
+        y1 = -this.ne.v / 100.0;
+      }
+      if (this.xe.v > 0) {
+        x2 = 1.0 - this.xe.v / 100.0;
+      } else {
+        y2 = 1.0 + this.xe.v / 100.0;
+      }
+      var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
+
+      var mult = 0;
+      var s = this.finalS;
+      var e = this.finalE;
+      var type = this.data.sh;
+      if (type === 2) {
+        if (e === s) {
+          mult = ind >= e ? 1 : 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+        mult = easer(mult);
+      } else if (type === 3) {
+        if (e === s) {
+          mult = ind >= e ? 0 : 1;
+        } else {
+          mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+
+        mult = easer(mult);
+      } else if (type === 4) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+          if (mult < 0.5) {
+            mult *= 2;
+          } else {
+            mult = 1 - 2 * (mult - 0.5);
+          }
+        }
+        mult = easer(mult);
+      } else if (type === 5) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          var tot = e - s;
+          /* ind += 0.5;
+                    mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          var x = -tot / 2 + ind;
+          var a = tot / 2;
+          mult = Math.sqrt(1 - (x * x) / (a * a));
+        }
+        mult = easer(mult);
+      } else if (type === 6) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; // eslint-disable-line
+        }
+        mult = easer(mult);
+      } else {
+        if (ind >= floor(s)) {
+          if (ind - s < 0) {
+            mult = max(0, min(min(e, 1) - (s - ind), 1));
+          } else {
+            mult = max(0, min(e - ind, 1));
+          }
+        }
+        mult = easer(mult);
+      }
+      // Smoothness implementation.
+      // The smoothness represents a reduced range of the original [0; 1] range.
+      // if smoothness is 25%, the new range will be [0.375; 0.625]
+      // Steps are:
+      // - find the lower value of the new range (threshold)
+      // - if multiplier is smaller than that value, floor it to 0
+      // - if it is larger,
+      //     - subtract the threshold
+      //     - divide it by the smoothness (this will return the range to [0; 1])
+      // Note: If it doesn't work on some scenarios, consider applying it before the easer.
+      if (this.sm.v !== 100) {
+        var smoothness = this.sm.v * 0.01;
+        if (smoothness === 0) {
+          smoothness = 0.00000001;
+        }
+        var threshold = 0.5 - smoothness * 0.5;
+        if (mult < threshold) {
+          mult = 0;
+        } else {
+          mult = (mult - threshold) / smoothness;
+          if (mult > 1) {
+            mult = 1;
+          }
+        }
+      }
+      return mult * this.a.v;
+    },
+    getValue: function (newCharsFlag) {
+      this.iterateDynamicProperties();
+      this._mdf = newCharsFlag || this._mdf;
+      this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
+      if (newCharsFlag && this.data.r === 2) {
+        this.e.v = this._currentTextLength;
+      }
+      var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
+      var o = this.o.v / divisor;
+      var s = this.s.v / divisor + o;
+      var e = (this.e.v / divisor) + o;
+      if (s > e) {
+        var _s = s;
+        s = e;
+        e = _s;
+      }
+      this.finalS = s;
+      this.finalE = e;
+    },
+  };
+  extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
+
+  function getTextSelectorProp(elem, data, arr) {
+    return new TextSelectorPropFactory(elem, data, arr);
+  }
+
+  return {
+    getTextSelectorProp: getTextSelectorProp,
+  };
+}());
+
+function TextAnimatorDataProperty(elem, animatorProps, container) {
+  var defaultData = { propType: false };
+  var getProp = PropertyFactory.getProp;
+  var textAnimatorAnimatables = animatorProps.a;
+  this.a = {
+    r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData,
+    rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData,
+    ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData,
+    sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData,
+    sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData,
+    s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData,
+    a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData,
+    o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData,
+    p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData,
+    sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData,
+    sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData,
+    fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData,
+    fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData,
+    fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData,
+    fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData,
+    t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData,
+  };
+
+  this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container);
+  this.s.t = animatorProps.s.t;
+}
+
+function TextAnimatorProperty(textData, renderType, elem) {
+  this._isFirstFrame = true;
+  this._hasMaskedPath = false;
+  this._frameId = -1;
+  this._textData = textData;
+  this._renderType = renderType;
+  this._elem = elem;
+  this._animatorsData = createSizedArray(this._textData.a.length);
+  this._pathData = {};
+  this._moreOptions = {
+    alignment: {},
+  };
+  this.renderedLetters = [];
+  this.lettersChangedFlag = false;
+  this.initDynamicPropertyContainer(elem);
+}
+
+TextAnimatorProperty.prototype.searchProperties = function () {
+  var i;
+  var len = this._textData.a.length;
+  var animatorProps;
+  var getProp = PropertyFactory.getProp;
+  for (i = 0; i < len; i += 1) {
+    animatorProps = this._textData.a[i];
+    this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
+  }
+  if (this._textData.p && 'm' in this._textData.p) {
+    this._pathData = {
+      a: getProp(this._elem, this._textData.p.a, 0, 0, this),
+      f: getProp(this._elem, this._textData.p.f, 0, 0, this),
+      l: getProp(this._elem, this._textData.p.l, 0, 0, this),
+      r: getProp(this._elem, this._textData.p.r, 0, 0, this),
+      p: getProp(this._elem, this._textData.p.p, 0, 0, this),
+      m: this._elem.maskManager.getMaskProperty(this._textData.p.m),
+    };
+    this._hasMaskedPath = true;
+  } else {
+    this._hasMaskedPath = false;
+  }
+  this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
+};
+
+TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
+  this.lettersChangedFlag = lettersChangedFlag;
+  if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
+    return;
+  }
+  this._isFirstFrame = false;
+  var alignment = this._moreOptions.alignment.v;
+  var animators = this._animatorsData;
+  var textData = this._textData;
+  var matrixHelper = this.mHelper;
+  var renderType = this._renderType;
+  var renderedLettersCount = this.renderedLetters.length;
+  var xPos;
+  var yPos;
+  var i;
+  var len;
+  var letters = documentData.l;
+  var pathInfo;
+  var currentLength;
+  var currentPoint;
+  var segmentLength;
+  var flag;
+  var pointInd;
+  var segmentInd;
+  var prevPoint;
+  var points;
+  var segments;
+  var partialLength;
+  var totalLength;
+  var perc;
+  var tanAngle;
+  var mask;
+  if (this._hasMaskedPath) {
+    mask = this._pathData.m;
+    if (!this._pathData.n || this._pathData._mdf) {
+      var paths = mask.v;
+      if (this._pathData.r.v) {
+        paths = paths.reverse();
+      }
+      // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
+      pathInfo = {
+        tLength: 0,
+        segments: [],
+      };
+      len = paths._length - 1;
+      var bezierData;
+      totalLength = 0;
+      for (i = 0; i < len; i += 1) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[i + 1],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      i = len;
+      if (mask.v.c) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[0],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      this._pathData.pi = pathInfo;
+    }
+    pathInfo = this._pathData.pi;
+
+    currentLength = this._pathData.f.v;
+    segmentInd = 0;
+    pointInd = 1;
+    segmentLength = 0;
+    flag = true;
+    segments = pathInfo.segments;
+    if (currentLength < 0 && mask.v.c) {
+      if (pathInfo.tLength < Math.abs(currentLength)) {
+        currentLength = -Math.abs(currentLength) % pathInfo.tLength;
+      }
+      segmentInd = segments.length - 1;
+      points = segments[segmentInd].points;
+      pointInd = points.length - 1;
+      while (currentLength < 0) {
+        currentLength += points[pointInd].partialLength;
+        pointInd -= 1;
+        if (pointInd < 0) {
+          segmentInd -= 1;
+          points = segments[segmentInd].points;
+          pointInd = points.length - 1;
+        }
+      }
+    }
+    points = segments[segmentInd].points;
+    prevPoint = points[pointInd - 1];
+    currentPoint = points[pointInd];
+    partialLength = currentPoint.partialLength;
+  }
+
+  len = letters.length;
+  xPos = 0;
+  yPos = 0;
+  var yOff = documentData.finalSize * 1.2 * 0.714;
+  var firstLine = true;
+  var animatorProps;
+  var animatorSelector;
+  var j;
+  var jLen;
+  var letterValue;
+
+  jLen = animators.length;
+
+  var mult;
+  var ind = -1;
+  var offf;
+  var xPathPos;
+  var yPathPos;
+  var initPathPos = currentLength;
+  var initSegmentInd = segmentInd;
+  var initPointInd = pointInd;
+  var currentLine = -1;
+  var elemOpacity;
+  var sc;
+  var sw;
+  var fc;
+  var k;
+  var letterSw;
+  var letterSc;
+  var letterFc;
+  var letterM = '';
+  var letterP = this.defaultPropsArray;
+  var letterO;
+
+  //
+  if (documentData.j === 2 || documentData.j === 1) {
+    var animatorJustifyOffset = 0;
+    var animatorFirstCharOffset = 0;
+    var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
+    var lastIndex = 0;
+    var isNewLine = true;
+
+    for (i = 0; i < len; i += 1) {
+      if (letters[i].n) {
+        if (animatorJustifyOffset) {
+          animatorJustifyOffset += animatorFirstCharOffset;
+        }
+        while (lastIndex < i) {
+          letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+          lastIndex += 1;
+        }
+        animatorJustifyOffset = 0;
+        isNewLine = true;
+      } else {
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.t.propType) {
+            if (isNewLine && documentData.j === 2) {
+              animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
+            }
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
+            } else {
+              animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult;
+            }
+          }
+        }
+        isNewLine = false;
+      }
+    }
+    if (animatorJustifyOffset) {
+      animatorJustifyOffset += animatorFirstCharOffset;
+    }
+    while (lastIndex < i) {
+      letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+      lastIndex += 1;
+    }
+  }
+  //
+
+  for (i = 0; i < len; i += 1) {
+    matrixHelper.reset();
+    elemOpacity = 1;
+    if (letters[i].n) {
+      xPos = 0;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      currentLength = initPathPos;
+      firstLine = false;
+      if (this._hasMaskedPath) {
+        segmentInd = initSegmentInd;
+        pointInd = initPointInd;
+        points = segments[segmentInd].points;
+        prevPoint = points[pointInd - 1];
+        currentPoint = points[pointInd];
+        partialLength = currentPoint.partialLength;
+        segmentLength = 0;
+      }
+      letterM = '';
+      letterFc = '';
+      letterSw = '';
+      letterO = '';
+      letterP = this.defaultPropsArray;
+    } else {
+      if (this._hasMaskedPath) {
+        if (currentLine !== letters[i].line) {
+          switch (documentData.j) {
+            case 1:
+              currentLength += totalLength - documentData.lineWidths[letters[i].line];
+              break;
+            case 2:
+              currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
+              break;
+            default:
+              break;
+          }
+          currentLine = letters[i].line;
+        }
+        if (ind !== letters[i].ind) {
+          if (letters[ind]) {
+            currentLength += letters[ind].extra;
+          }
+          currentLength += letters[i].an / 2;
+          ind = letters[i].ind;
+        }
+        currentLength += (alignment[0] * letters[i].an) * 0.005;
+        var animatorOffset = 0;
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.p.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.p.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.p.v[0] * mult;
+            }
+          }
+          if (animatorProps.a.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.a.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.a.v[0] * mult;
+            }
+          }
+        }
+        flag = true;
+        // Force alignment only works with a single line for now
+        if (this._pathData.a.v) {
+          currentLength = letters[0].an * 0.5 + ((totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind) / (len - 1);
+          currentLength += this._pathData.f.v;
+        }
+        while (flag) {
+          if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
+            perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
+            xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
+            yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
+            matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, -(alignment[1] * yOff) * 0.01);
+            flag = false;
+          } else if (points) {
+            segmentLength += currentPoint.partialLength;
+            pointInd += 1;
+            if (pointInd >= points.length) {
+              pointInd = 0;
+              segmentInd += 1;
+              if (!segments[segmentInd]) {
+                if (mask.v.c) {
+                  pointInd = 0;
+                  segmentInd = 0;
+                  points = segments[segmentInd].points;
+                } else {
+                  segmentLength -= currentPoint.partialLength;
+                  points = null;
+                }
+              } else {
+                points = segments[segmentInd].points;
+              }
+            }
+            if (points) {
+              prevPoint = currentPoint;
+              currentPoint = points[pointInd];
+              partialLength = currentPoint.partialLength;
+            }
+          }
+        }
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+      } else {
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+
+        // Grouping alignment
+        matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, (-alignment[1] * yOff) * 0.01, 0);
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.t.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
+          if (xPos !== 0 || documentData.j !== 0) {
+            if (this._hasMaskedPath) {
+              if (mult.length) {
+                currentLength += animatorProps.t.v * mult[0];
+              } else {
+                currentLength += animatorProps.t.v * mult;
+              }
+            } else if (mult.length) {
+              xPos += animatorProps.t.v * mult[0];
+            } else {
+              xPos += animatorProps.t.v * mult;
+            }
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        sw = documentData.sw || 0;
+      }
+      if (documentData.strokeColorAnim) {
+        if (documentData.sc) {
+          sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
+        } else {
+          sc = [0, 0, 0];
+        }
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.a.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+
+          if (mult.length) {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.s.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (mult.length) {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult[0]), 1 + ((animatorProps.s.v[1] - 1) * mult[1]), 1);
+          } else {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult), 1 + ((animatorProps.s.v[1] - 1) * mult), 1);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        animatorSelector = animators[j].s;
+        mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+        if (animatorProps.sk.propType) {
+          if (mult.length) {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
+          } else {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
+          }
+        }
+        if (animatorProps.r.propType) {
+          if (mult.length) {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
+          } else {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult);
+          }
+        }
+        if (animatorProps.ry.propType) {
+          if (mult.length) {
+            matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
+          } else {
+            matrixHelper.rotateY(animatorProps.ry.v * mult);
+          }
+        }
+        if (animatorProps.rx.propType) {
+          if (mult.length) {
+            matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
+          } else {
+            matrixHelper.rotateX(animatorProps.rx.v * mult);
+          }
+        }
+        if (animatorProps.o.propType) {
+          if (mult.length) {
+            elemOpacity += ((animatorProps.o.v) * mult[0] - elemOpacity) * mult[0];
+          } else {
+            elemOpacity += ((animatorProps.o.v) * mult - elemOpacity) * mult;
+          }
+        }
+        if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
+          if (mult.length) {
+            sw += animatorProps.sw.v * mult[0];
+          } else {
+            sw += animatorProps.sw.v * mult;
+          }
+        }
+        if (documentData.strokeColorAnim && animatorProps.sc.propType) {
+          for (k = 0; k < 3; k += 1) {
+            if (mult.length) {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0];
+            } else {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult;
+            }
+          }
+        }
+        if (documentData.fillColorAnim && documentData.fc) {
+          if (animatorProps.fc.propType) {
+            for (k = 0; k < 3; k += 1) {
+              if (mult.length) {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0];
+              } else {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult;
+              }
+            }
+          }
+          if (animatorProps.fh.propType) {
+            if (mult.length) {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
+            } else {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult);
+            }
+          }
+          if (animatorProps.fs.propType) {
+            if (mult.length) {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
+            } else {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
+            }
+          }
+          if (animatorProps.fb.propType) {
+            if (mult.length) {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
+            } else {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult);
+            }
+          }
+        }
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+
+        if (animatorProps.p.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (this._hasMaskedPath) {
+            if (mult.length) {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
+            } else {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+            }
+          } else if (mult.length) {
+            matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        letterSw = sw < 0 ? 0 : sw;
+      }
+      if (documentData.strokeColorAnim) {
+        letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
+      }
+
+      if (this._hasMaskedPath) {
+        matrixHelper.translate(0, -documentData.ls);
+
+        matrixHelper.translate(0, (alignment[1] * yOff) * 0.01 + yPos, 0);
+        if (this._pathData.p.v) {
+          tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
+          var rot = (Math.atan(tanAngle) * 180) / Math.PI;
+          if (currentPoint.point[0] < prevPoint.point[0]) {
+            rot += 180;
+          }
+          matrixHelper.rotate((-rot * Math.PI) / 180);
+        }
+        matrixHelper.translate(xPathPos, yPathPos, 0);
+        currentLength -= (alignment[0] * letters[i].an) * 0.005;
+        if (letters[i + 1] && ind !== letters[i + 1].ind) {
+          currentLength += letters[i].an / 2;
+          currentLength += (documentData.tr * 0.001) * documentData.finalSize;
+        }
+      } else {
+        matrixHelper.translate(xPos, yPos, 0);
+
+        if (documentData.ps) {
+          // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
+          matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+        }
+        switch (documentData.j) {
+          case 1:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
+            break;
+          case 2:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
+            break;
+          default:
+            break;
+        }
+        matrixHelper.translate(0, -documentData.ls);
+        matrixHelper.translate(offf, 0, 0);
+        matrixHelper.translate((alignment[0] * letters[i].an) * 0.005, (alignment[1] * yOff) * 0.01, 0);
+        xPos += letters[i].l + (documentData.tr * 0.001) * documentData.finalSize;
+      }
+      if (renderType === 'html') {
+        letterM = matrixHelper.toCSS();
+      } else if (renderType === 'svg') {
+        letterM = matrixHelper.to2dCSS();
+      } else {
+        letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
+      }
+      letterO = elemOpacity;
+    }
+
+    if (renderedLettersCount <= i) {
+      letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
+      this.renderedLetters.push(letterValue);
+      renderedLettersCount += 1;
+      this.lettersChangedFlag = true;
+    } else {
+      letterValue = this.renderedLetters[i];
+      this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag;
+    }
+  }
+};
+
+TextAnimatorProperty.prototype.getValue = function () {
+  if (this._elem.globalData.frameId === this._frameId) {
+    return;
+  }
+  this._frameId = this._elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+TextAnimatorProperty.prototype.mHelper = new Matrix();
+TextAnimatorProperty.prototype.defaultPropsArray = [];
+extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
+
+function ITextElement() {
+}
+
+ITextElement.prototype.initElement = function (data, globalData, comp) {
+  this.lettersChangedFlag = true;
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.textProperty = new TextProperty(this, data.t, this.dynamicProperties);
+  this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this);
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+  this.initRenderable();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  this.createContent();
+  this.hide();
+  this.textAnimator.searchProperties(this.dynamicProperties);
+};
+
+ITextElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+};
+
+ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
+  var j;
+  var jLen = shapes.length;
+  var pathNodes;
+  var shapeStr = '';
+  for (j = 0; j < jLen; j += 1) {
+    if (shapes[j].ty === 'sh') {
+      pathNodes = shapes[j].ks.k;
+      shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
+    }
+  }
+  return shapeStr;
+};
+
+ITextElement.prototype.updateDocumentData = function (newData, index) {
+  this.textProperty.updateDocumentData(newData, index);
+};
+
+ITextElement.prototype.canResizeFont = function (_canResize) {
+  this.textProperty.canResizeFont(_canResize);
+};
+
+ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
+  this.textProperty.setMinimumFontSize(_fontSize);
+};
+
+ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
+  if (documentData.ps) {
+    matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+  }
+  matrixHelper.translate(0, -documentData.ls, 0);
+  switch (documentData.j) {
+    case 1:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
+      break;
+    case 2:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
+      break;
+    default:
+      break;
+  }
+  matrixHelper.translate(xPos, yPos, 0);
+};
+
+ITextElement.prototype.buildColor = function (colorData) {
+  return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
+};
+
+ITextElement.prototype.emptyProp = new LetterProps();
+
+ITextElement.prototype.destroy = function () {
+
+};
+
+ITextElement.prototype.validateText = function () {
+  if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
+    this.buildNewText();
+    this.textProperty._isFirstFrame = false;
+    this.textProperty._mdf = false;
+  }
+};
+
+var emptyShapeData = {
+  shapes: [],
+};
+
+function SVGTextLottieElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.renderType = 'svg';
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
+
+SVGTextLottieElement.prototype.createContent = function () {
+  if (this.data.singleShape && !this.globalData.fontManager.chars) {
+    this.textContainer = createNS('text');
+  }
+};
+
+SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
+  var i = 0;
+  var len = textArray.length;
+  var textContents = [];
+  var currentTextContent = '';
+  while (i < len) {
+    if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
+      textContents.push(currentTextContent);
+      currentTextContent = '';
+    } else {
+      currentTextContent += textArray[i];
+    }
+    i += 1;
+  }
+  textContents.push(currentTextContent);
+  return textContents;
+};
+
+SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
+  // data should probably be cloned to apply scale separately to each instance of a text on different layers
+  // but since text internal content gets only rendered once and then it's never rerendered,
+  // it's probably safe not to clone data and reuse always the same instance even if the object is mutated.
+  // Avoiding cloning is preferred since cloning each character shape data is expensive
+  if (data.shapes && data.shapes.length) {
+    var shape = data.shapes[0];
+    if (shape.it) {
+      var shapeItem = shape.it[shape.it.length - 1];
+      if (shapeItem.s) {
+        shapeItem.s.k[0] = scale;
+        shapeItem.s.k[1] = scale;
+      }
+    }
+  }
+  return data;
+};
+
+SVGTextLottieElement.prototype.buildNewText = function () {
+  this.addDynamicProperty(this);
+  var i;
+  var len;
+
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
+  if (documentData.fc) {
+    this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
+  } else {
+    this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
+  }
+  if (documentData.sc) {
+    this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
+    this.layerElement.setAttribute('stroke-width', documentData.sw);
+  }
+  this.layerElement.setAttribute('font-size', documentData.finalSize);
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (fontData.fClass) {
+    this.layerElement.setAttribute('class', fontData.fClass);
+  } else {
+    this.layerElement.setAttribute('font-family', fontData.fFamily);
+    var fWeight = documentData.fWeight;
+    var fStyle = documentData.fStyle;
+    this.layerElement.setAttribute('font-style', fStyle);
+    this.layerElement.setAttribute('font-weight', fWeight);
+  }
+  this.layerElement.setAttribute('aria-label', documentData.t);
+
+  var letters = documentData.l || [];
+  var usesGlyphs = !!this.globalData.fontManager.chars;
+  len = letters.length;
+
+  var tSpan;
+  var matrixHelper = this.mHelper;
+  var shapeStr = '';
+  var singleShape = this.data.singleShape;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  if (singleShape && !usesGlyphs && !documentData.sz) {
+    var tElement = this.textContainer;
+    var justify = 'start';
+    switch (documentData.j) {
+      case 1:
+        justify = 'end';
+        break;
+      case 2:
+        justify = 'middle';
+        break;
+      default:
+        justify = 'start';
+        break;
+    }
+    tElement.setAttribute('text-anchor', justify);
+    tElement.setAttribute('letter-spacing', trackingOffset);
+    var textContent = this.buildTextContents(documentData.finalText);
+    len = textContent.length;
+    yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
+    for (i = 0; i < len; i += 1) {
+      tSpan = this.textSpans[i].span || createNS('tspan');
+      tSpan.textContent = textContent[i];
+      tSpan.setAttribute('x', 0);
+      tSpan.setAttribute('y', yPos);
+      tSpan.style.display = 'inherit';
+      tElement.appendChild(tSpan);
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          glyph: null,
+        };
+      }
+      this.textSpans[i].span = tSpan;
+      yPos += documentData.finalLineHeight;
+    }
+
+    this.layerElement.appendChild(tElement);
+  } else {
+    var cachedSpansLength = this.textSpans.length;
+    var charData;
+    for (i = 0; i < len; i += 1) {
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          childSpan: null,
+          glyph: null,
+        };
+      }
+      if (!usesGlyphs || !singleShape || i === 0) {
+        tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
+        if (cachedSpansLength <= i) {
+          tSpan.setAttribute('stroke-linecap', 'butt');
+          tSpan.setAttribute('stroke-linejoin', 'round');
+          tSpan.setAttribute('stroke-miterlimit', '4');
+          this.textSpans[i].span = tSpan;
+          if (usesGlyphs) {
+            var childSpan = createNS('g');
+            tSpan.appendChild(childSpan);
+            this.textSpans[i].childSpan = childSpan;
+          }
+          this.textSpans[i].span = tSpan;
+          this.layerElement.appendChild(tSpan);
+        }
+        tSpan.style.display = 'inherit';
+      }
+
+      matrixHelper.reset();
+      if (singleShape) {
+        if (letters[i].n) {
+          xPos = -trackingOffset;
+          yPos += documentData.yOffset;
+          yPos += firstLine ? 1 : 0;
+          firstLine = false;
+        }
+        this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+        xPos += letters[i].l || 0;
+        // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
+        xPos += trackingOffset;
+      }
+      if (usesGlyphs) {
+        charData = this.globalData.fontManager.getCharData(
+          documentData.finalText[i],
+          fontData.fStyle,
+          this.globalData.fontManager.getFontByName(documentData.f).fFamily
+        );
+        var glyphElement;
+        // t === 1 means the character has been replaced with an animated shaped
+        if (charData.t === 1) {
+          glyphElement = new SVGCompElement(charData.data, this.globalData, this);
+        } else {
+          var data = emptyShapeData;
+          if (charData.data && charData.data.shapes) {
+            data = this.buildShapeData(charData.data, documentData.finalSize);
+          }
+          glyphElement = new SVGShapeElement(data, this.globalData, this);
+        }
+        if (this.textSpans[i].glyph) {
+          var glyph = this.textSpans[i].glyph;
+          this.textSpans[i].childSpan.removeChild(glyph.layerElement);
+          glyph.destroy();
+        }
+        this.textSpans[i].glyph = glyphElement;
+        glyphElement._debug = true;
+        glyphElement.prepareFrame(0);
+        glyphElement.renderFrame();
+        this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+        // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+        // this might have issues with strokes and might need a different solution
+        if (charData.t === 1) {
+          this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
+        }
+      } else {
+        if (singleShape) {
+          tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
+        }
+        tSpan.textContent = letters[i].val;
+        tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      }
+      //
+    }
+    if (singleShape && tSpan) {
+      tSpan.setAttribute('d', shapeStr);
+    }
+  }
+  while (i < this.textSpans.length) {
+    this.textSpans[i].span.style.display = 'none';
+    i += 1;
+  }
+
+  this._sizeChanged = true;
+};
+
+SVGTextLottieElement.prototype.sourceRectAtTime = function () {
+  this.prepareFrame(this.comp.renderedFrame - this.data.st);
+  this.renderInnerContent();
+  if (this._sizeChanged) {
+    this._sizeChanged = false;
+    var textBox = this.layerElement.getBBox();
+    this.bbox = {
+      top: textBox.y,
+      left: textBox.x,
+      width: textBox.width,
+      height: textBox.height,
+    };
+  }
+  return this.bbox;
+};
+
+SVGTextLottieElement.prototype.getValue = function () {
+  var i;
+  var len = this.textSpans.length;
+  var glyphElement;
+  this.renderedFrame = this.comp.renderedFrame;
+  for (i = 0; i < len; i += 1) {
+    glyphElement = this.textSpans[i].glyph;
+    if (glyphElement) {
+      glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
+      if (glyphElement._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+SVGTextLottieElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  if (!this.data.singleShape || this._mdf) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+    if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
+      this._sizeChanged = true;
+      var i;
+      var len;
+      var renderedLetters = this.textAnimator.renderedLetters;
+
+      var letters = this.textProperty.currentData.l;
+
+      len = letters.length;
+      var renderedLetter;
+      var textSpan;
+      var glyphElement;
+      for (i = 0; i < len; i += 1) {
+        if (!letters[i].n) {
+          renderedLetter = renderedLetters[i];
+          textSpan = this.textSpans[i].span;
+          glyphElement = this.textSpans[i].glyph;
+          if (glyphElement) {
+            glyphElement.renderFrame();
+          }
+          if (renderedLetter._mdf.m) {
+            textSpan.setAttribute('transform', renderedLetter.m);
+          }
+          if (renderedLetter._mdf.o) {
+            textSpan.setAttribute('opacity', renderedLetter.o);
+          }
+          if (renderedLetter._mdf.sw) {
+            textSpan.setAttribute('stroke-width', renderedLetter.sw);
+          }
+          if (renderedLetter._mdf.sc) {
+            textSpan.setAttribute('stroke', renderedLetter.sc);
+          }
+          if (renderedLetter._mdf.fc) {
+            textSpan.setAttribute('fill', renderedLetter.fc);
+          }
+        }
+      }
+    }
+  }
+};
+
+function ISolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([IImageElement], ISolidElement);
+
+ISolidElement.prototype.createContent = function () {
+  var rect = createNS('rect');
+  /// /rect.style.width = this.data.sw;
+  /// /rect.style.height = this.data.sh;
+  /// /rect.style.fill = this.data.sc;
+  rect.setAttribute('width', this.data.sw);
+  rect.setAttribute('height', this.data.sh);
+  rect.setAttribute('fill', this.data.sc);
+  this.layerElement.appendChild(rect);
+};
+
+function NullElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initFrame();
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+}
+
+NullElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+NullElement.prototype.renderFrame = function () {
+};
+
+NullElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+NullElement.prototype.destroy = function () {
+};
+
+NullElement.prototype.sourceRectAtTime = function () {
+};
+
+NullElement.prototype.hide = function () {
+};
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
+
+function SVGRendererBase() {
+}
+
+extendPrototype([BaseRenderer], SVGRendererBase);
+
+SVGRendererBase.prototype.createNull = function (data) {
+  return new NullElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createShape = function (data) {
+  return new SVGShapeElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createText = function (data) {
+  return new SVGTextLottieElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createImage = function (data) {
+  return new IImageElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createSolid = function (data) {
+  return new ISolidElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.configAnimation = function (animData) {
+  this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+  this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+  if (this.renderConfig.viewBoxSize) {
+    this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
+  } else {
+    this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
+  }
+
+  if (!this.renderConfig.viewBoxOnly) {
+    this.svgElement.setAttribute('width', animData.w);
+    this.svgElement.setAttribute('height', animData.h);
+    this.svgElement.style.width = '100%';
+    this.svgElement.style.height = '100%';
+    this.svgElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
+  }
+  if (this.renderConfig.width) {
+    this.svgElement.setAttribute('width', this.renderConfig.width);
+  }
+  if (this.renderConfig.height) {
+    this.svgElement.setAttribute('height', this.renderConfig.height);
+  }
+  if (this.renderConfig.className) {
+    this.svgElement.setAttribute('class', this.renderConfig.className);
+  }
+  if (this.renderConfig.id) {
+    this.svgElement.setAttribute('id', this.renderConfig.id);
+  }
+  if (this.renderConfig.focusable !== undefined) {
+    this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
+  }
+  this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+  // this.layerElement.style.transform = 'translate3d(0,0,0)';
+  // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
+  this.animationItem.wrapper.appendChild(this.svgElement);
+  // Mask animation
+  var defs = this.globalData.defs;
+
+  this.setupGlobalData(animData, defs);
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.data = animData;
+
+  var maskElement = createNS('clipPath');
+  var rect = createNS('rect');
+  rect.setAttribute('width', animData.w);
+  rect.setAttribute('height', animData.h);
+  rect.setAttribute('x', 0);
+  rect.setAttribute('y', 0);
+  var maskId = createElementID();
+  maskElement.setAttribute('id', maskId);
+  maskElement.appendChild(rect);
+  this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')');
+
+  defs.appendChild(maskElement);
+  this.layers = animData.layers;
+  this.elements = createSizedArray(animData.layers.length);
+};
+
+SVGRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.layerElement = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+SVGRendererBase.prototype.updateContainerSize = function () {
+};
+
+SVGRendererBase.prototype.findIndexByInd = function (ind) {
+  var i = 0;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.layers[i].ind === ind) {
+      return i;
+    }
+  }
+  return -1;
+};
+
+SVGRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  elements[pos] = true;
+  var element = this.createItem(this.layers[pos]);
+
+  elements[pos] = element;
+  if (getExpressionsPlugin()) {
+    if (this.layers[pos].ty === 0) {
+      this.globalData.projectInterface.registerComposition(element);
+    }
+    element.initExpressions();
+  }
+  this.appendElementInPos(element, pos);
+  if (this.layers[pos].tt) {
+    var elementIndex = ('tp' in this.layers[pos])
+      ? this.findIndexByInd(this.layers[pos].tp)
+      : pos - 1;
+    if (elementIndex === -1) {
+      return;
+    }
+    if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
+      this.buildItem(elementIndex);
+      this.addPendingElement(element);
+    } else {
+      var matteElement = elements[elementIndex];
+      var matteMask = matteElement.getMatte(this.layers[pos].tt);
+      element.setMatte(matteMask);
+    }
+  }
+};
+
+SVGRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+    if (element.data.tt) {
+      var i = 0;
+      var len = this.elements.length;
+      while (i < len) {
+        if (this.elements[i] === element) {
+          var elementIndex = 'tp' in element.data
+            ? this.findIndexByInd(element.data.tp)
+            : i - 1;
+          var matteElement = this.elements[elementIndex];
+          var matteMask = matteElement.getMatte(this.layers[i].tt);
+          element.setMatte(matteMask);
+          break;
+        }
+        i += 1;
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.renderFrame = function (num) {
+  if (this.renderedFrame === num || this.destroyed) {
+    return;
+  }
+  if (num === null) {
+    num = this.renderedFrame;
+  } else {
+    this.renderedFrame = num;
+  }
+  // console.log('-------');
+  // console.log('FRAME ',num);
+  this.globalData.frameNum = num;
+  this.globalData.frameId += 1;
+  this.globalData.projectInterface.currentFrame = num;
+  this.globalData._mdf = false;
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    for (i = 0; i < len; i += 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
+  var newElement = element.getBaseElement();
+  if (!newElement) {
+    return;
+  }
+  var i = 0;
+  var nextElement;
+  while (i < pos) {
+    if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
+      nextElement = this.elements[i].getBaseElement();
+    }
+    i += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(newElement, nextElement);
+  } else {
+    this.layerElement.appendChild(newElement);
+  }
+};
+
+SVGRendererBase.prototype.hide = function () {
+  this.layerElement.style.display = 'none';
+};
+
+SVGRendererBase.prototype.show = function () {
+  this.layerElement.style.display = 'block';
+};
+
+function ICompElement() {}
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
+
+ICompElement.prototype.initElement = function (data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initTransform(data, globalData, comp);
+  this.initRenderable();
+  this.initHierarchy();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  if (this.data.xt || !globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+  this.hide();
+};
+
+/* ICompElement.prototype.hide = function(){
+    if(!this.hidden){
+        this.hideElement();
+        var i,len = this.elements.length;
+        for( i = 0; i < len; i+=1 ){
+            if(this.elements[i]){
+                this.elements[i].hide();
+            }
+        }
+    }
+}; */
+
+ICompElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+  if (!this.isInRange && !this.data.xt) {
+    return;
+  }
+
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    if (timeRemapped === this.data.op) {
+      timeRemapped = this.data.op - 1;
+    }
+    this.renderedFrame = timeRemapped;
+  } else {
+    this.renderedFrame = num / this.data.sr;
+  }
+  var i;
+  var len = this.elements.length;
+  if (!this.completeLayers) {
+    this.checkLayers(this.renderedFrame);
+  }
+  // This iteration needs to be backwards because of how expressions connect between each other
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
+      if (this.elements[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+ICompElement.prototype.renderInnerContent = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+ICompElement.prototype.setElements = function (elems) {
+  this.elements = elems;
+};
+
+ICompElement.prototype.getElements = function () {
+  return this.elements;
+};
+
+ICompElement.prototype.destroyElements = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+};
+
+ICompElement.prototype.destroy = function () {
+  this.destroyElements();
+  this.destroyBaseElement();
+};
+
+function SVGCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = true;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
+
+SVGCompElement.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function SVGRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.layers = null;
+  this.renderedFrame = -1;
+  this.svgElement = createNS('svg');
+  var ariaLabel = '';
+  if (config && config.title) {
+    var titleElement = createNS('title');
+    var titleId = createElementID();
+    titleElement.setAttribute('id', titleId);
+    titleElement.textContent = config.title;
+    this.svgElement.appendChild(titleElement);
+    ariaLabel += titleId;
+  }
+  if (config && config.description) {
+    var descElement = createNS('desc');
+    var descId = createElementID();
+    descElement.setAttribute('id', descId);
+    descElement.textContent = config.description;
+    this.svgElement.appendChild(descElement);
+    ariaLabel += ' ' + descId;
+  }
+  if (ariaLabel) {
+    this.svgElement.setAttribute('aria-labelledby', ariaLabel);
+  }
+  var defs = createNS('defs');
+  this.svgElement.appendChild(defs);
+  var maskElement = createNS('g');
+  this.svgElement.appendChild(maskElement);
+  this.layerElement = maskElement;
+  this.renderConfig = {
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    hideOnTransparent: !((config && config.hideOnTransparent === false)),
+    viewBoxOnly: (config && config.viewBoxOnly) || false,
+    viewBoxSize: (config && config.viewBoxSize) || false,
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    focusable: config && config.focusable,
+    filterSize: {
+      width: (config && config.filterSize && config.filterSize.width) || '100%',
+      height: (config && config.filterSize && config.filterSize.height) || '100%',
+      x: (config && config.filterSize && config.filterSize.x) || '0%',
+      y: (config && config.filterSize && config.filterSize.y) || '0%',
+    },
+    width: (config && config.width),
+    height: (config && config.height),
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+
+  this.globalData = {
+    _mdf: false,
+    frameNum: -1,
+    defs: defs,
+    renderConfig: this.renderConfig,
+  };
+  this.elements = [];
+  this.pendingElements = [];
+  this.destroyed = false;
+  this.rendererType = 'svg';
+}
+
+extendPrototype([SVGRendererBase], SVGRenderer);
+
+SVGRenderer.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+var registeredEffects = {};
+
+function CVEffects(elem) {
+  var i;
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects[type]) {
+      var Effect = registeredEffects[type].effect;
+      filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+CVEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+CVEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect(id, effect) {
+  registeredEffects[id] = {
+    effect,
+  };
+}
+
+function HBaseElement() {}
+HBaseElement.prototype = {
+  checkBlendMode: function () {},
+  initRendererElement: function () {
+    this.baseElement = createTag(this.data.tg || 'div');
+    if (this.data.hasMask) {
+      this.svgElement = createNS('svg');
+      this.layerElement = createNS('g');
+      this.maskedElement = this.layerElement;
+      this.svgElement.appendChild(this.layerElement);
+      this.baseElement.appendChild(this.svgElement);
+    } else {
+      this.layerElement = this.baseElement;
+    }
+    styleDiv(this.baseElement);
+  },
+  createContainerElements: function () {
+    this.renderableEffectsManager = new CVEffects(this);
+    this.transformedElement = this.baseElement;
+    this.maskedElement = this.layerElement;
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    var transformedElementStyle = this.transformedElement ? this.transformedElement.style : {};
+    if (this.finalTransform._matMdf) {
+      var matrixValue = this.finalTransform.mat.toCSS();
+      transformedElementStyle.transform = matrixValue;
+      transformedElementStyle.webkitTransform = matrixValue;
+    }
+    if (this.finalTransform._opMdf) {
+      transformedElementStyle.opacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderFrame: function () {
+    // If it is exported as hidden (data.hd === true) no need to render
+    // If it is not visible no need to render
+    if (this.data.hd || this.hidden) {
+      return;
+    }
+    this.renderTransform();
+    this.renderRenderable();
+    this.renderElement();
+    this.renderInnerContent();
+    if (this._isFirstFrame) {
+      this._isFirstFrame = false;
+    }
+  },
+  destroy: function () {
+    this.layerElement = null;
+    this.transformedElement = null;
+    if (this.matteElement) {
+      this.matteElement = null;
+    }
+    if (this.maskManager) {
+      this.maskManager.destroy();
+      this.maskManager = null;
+    }
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+  },
+  addEffects: function () {
+  },
+  setMatte: function () {},
+};
+HBaseElement.prototype.getBaseElement = SVGBaseElement.prototype.getBaseElement;
+HBaseElement.prototype.destroyBaseElement = HBaseElement.prototype.destroy;
+HBaseElement.prototype.buildElementParenting = BaseRenderer.prototype.buildElementParenting;
+
+function HSolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], HSolidElement);
+
+HSolidElement.prototype.createContent = function () {
+  var rect;
+  if (this.data.hasMask) {
+    rect = createNS('rect');
+    rect.setAttribute('width', this.data.sw);
+    rect.setAttribute('height', this.data.sh);
+    rect.setAttribute('fill', this.data.sc);
+    this.svgElement.setAttribute('width', this.data.sw);
+    this.svgElement.setAttribute('height', this.data.sh);
+  } else {
+    rect = createTag('div');
+    rect.style.width = this.data.sw + 'px';
+    rect.style.height = this.data.sh + 'px';
+    rect.style.backgroundColor = this.data.sc;
+  }
+  this.layerElement.appendChild(rect);
+};
+
+function HShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.shapesContainer = createNS('g');
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  this.currentBBox = {
+    x: 999999,
+    y: -999999,
+    h: 0,
+    w: 0,
+  };
+}
+extendPrototype([BaseElement, TransformElement, HSolidElement, SVGShapeElement, HBaseElement, HierarchyElement, FrameElement, RenderableElement], HShapeElement);
+HShapeElement.prototype._renderShapeFrame = HShapeElement.prototype.renderInnerContent;
+
+HShapeElement.prototype.createContent = function () {
+  var cont;
+  this.baseElement.style.fontSize = 0;
+  if (this.data.hasMask) {
+    this.layerElement.appendChild(this.shapesContainer);
+    cont = this.svgElement;
+  } else {
+    cont = createNS('svg');
+    var size = this.comp.data ? this.comp.data : this.globalData.compSize;
+    cont.setAttribute('width', size.w);
+    cont.setAttribute('height', size.h);
+    cont.appendChild(this.shapesContainer);
+    this.layerElement.appendChild(cont);
+  }
+
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.shapesContainer, 0, [], true);
+  this.filterUniqueShapes();
+  this.shapeCont = cont;
+};
+
+HShapeElement.prototype.getTransformedPoint = function (transformers, point) {
+  var i;
+  var len = transformers.length;
+  for (i = 0; i < len; i += 1) {
+    point = transformers[i].mProps.v.applyToPointArray(point[0], point[1], 0);
+  }
+  return point;
+};
+
+HShapeElement.prototype.calculateShapeBoundingBox = function (item, boundingBox) {
+  var shape = item.sh.v;
+  var transformers = item.transformers;
+  var i;
+  var len = shape._length;
+  var vPoint;
+  var oPoint;
+  var nextIPoint;
+  var nextVPoint;
+  if (len <= 1) {
+    return;
+  }
+  for (i = 0; i < len - 1; i += 1) {
+    vPoint = this.getTransformedPoint(transformers, shape.v[i]);
+    oPoint = this.getTransformedPoint(transformers, shape.o[i]);
+    nextIPoint = this.getTransformedPoint(transformers, shape.i[i + 1]);
+    nextVPoint = this.getTransformedPoint(transformers, shape.v[i + 1]);
+    this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
+  }
+  if (shape.c) {
+    vPoint = this.getTransformedPoint(transformers, shape.v[i]);
+    oPoint = this.getTransformedPoint(transformers, shape.o[i]);
+    nextIPoint = this.getTransformedPoint(transformers, shape.i[0]);
+    nextVPoint = this.getTransformedPoint(transformers, shape.v[0]);
+    this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
+  }
+};
+
+HShapeElement.prototype.checkBounds = function (vPoint, oPoint, nextIPoint, nextVPoint, boundingBox) {
+  this.getBoundsOfCurve(vPoint, oPoint, nextIPoint, nextVPoint);
+  var bounds = this.shapeBoundingBox;
+  boundingBox.x = bmMin(bounds.left, boundingBox.x);
+  boundingBox.xMax = bmMax(bounds.right, boundingBox.xMax);
+  boundingBox.y = bmMin(bounds.top, boundingBox.y);
+  boundingBox.yMax = bmMax(bounds.bottom, boundingBox.yMax);
+};
+
+HShapeElement.prototype.shapeBoundingBox = {
+  left: 0,
+  right: 0,
+  top: 0,
+  bottom: 0,
+};
+
+HShapeElement.prototype.tempBoundingBox = {
+  x: 0,
+  xMax: 0,
+  y: 0,
+  yMax: 0,
+  width: 0,
+  height: 0,
+};
+
+HShapeElement.prototype.getBoundsOfCurve = function (p0, p1, p2, p3) {
+  var bounds = [[p0[0], p3[0]], [p0[1], p3[1]]];
+
+  for (var a, b, c, t, b2ac, t1, t2, i = 0; i < 2; ++i) { // eslint-disable-line no-plusplus
+    b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];
+    a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];
+    c = 3 * p1[i] - 3 * p0[i];
+
+    b |= 0; // eslint-disable-line no-bitwise
+    a |= 0; // eslint-disable-line no-bitwise
+    c |= 0; // eslint-disable-line no-bitwise
+
+    if (a === 0 && b === 0) {
+      //
+    } else if (a === 0) {
+      t = -c / b;
+
+      if (t > 0 && t < 1) {
+        bounds[i].push(this.calculateF(t, p0, p1, p2, p3, i));
+      }
+    } else {
+      b2ac = b * b - 4 * c * a;
+
+      if (b2ac >= 0) {
+        t1 = (-b + bmSqrt(b2ac)) / (2 * a);
+        if (t1 > 0 && t1 < 1) bounds[i].push(this.calculateF(t1, p0, p1, p2, p3, i));
+        t2 = (-b - bmSqrt(b2ac)) / (2 * a);
+        if (t2 > 0 && t2 < 1) bounds[i].push(this.calculateF(t2, p0, p1, p2, p3, i));
+      }
+    }
+  }
+
+  this.shapeBoundingBox.left = bmMin.apply(null, bounds[0]);
+  this.shapeBoundingBox.top = bmMin.apply(null, bounds[1]);
+  this.shapeBoundingBox.right = bmMax.apply(null, bounds[0]);
+  this.shapeBoundingBox.bottom = bmMax.apply(null, bounds[1]);
+};
+
+HShapeElement.prototype.calculateF = function (t, p0, p1, p2, p3, i) {
+  return bmPow(1 - t, 3) * p0[i]
+        + 3 * bmPow(1 - t, 2) * t * p1[i]
+        + 3 * (1 - t) * bmPow(t, 2) * p2[i]
+        + bmPow(t, 3) * p3[i];
+};
+
+HShapeElement.prototype.calculateBoundingBox = function (itemsData, boundingBox) {
+  var i;
+  var len = itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    if (itemsData[i] && itemsData[i].sh) {
+      this.calculateShapeBoundingBox(itemsData[i], boundingBox);
+    } else if (itemsData[i] && itemsData[i].it) {
+      this.calculateBoundingBox(itemsData[i].it, boundingBox);
+    } else if (itemsData[i] && itemsData[i].style && itemsData[i].w) {
+      this.expandStrokeBoundingBox(itemsData[i].w, boundingBox);
+    }
+  }
+};
+
+HShapeElement.prototype.expandStrokeBoundingBox = function (widthProperty, boundingBox) {
+  var width = 0;
+  if (widthProperty.keyframes) {
+    for (var i = 0; i < widthProperty.keyframes.length; i += 1) {
+      var kfw = widthProperty.keyframes[i].s;
+      if (kfw > width) {
+        width = kfw;
+      }
+    }
+    width *= widthProperty.mult;
+  } else {
+    width = widthProperty.v * widthProperty.mult;
+  }
+
+  boundingBox.x -= width;
+  boundingBox.xMax += width;
+  boundingBox.y -= width;
+  boundingBox.yMax += width;
+};
+
+HShapeElement.prototype.currentBoxContains = function (box) {
+  return this.currentBBox.x <= box.x
+    && this.currentBBox.y <= box.y
+    && this.currentBBox.width + this.currentBBox.x >= box.x + box.width
+    && this.currentBBox.height + this.currentBBox.y >= box.y + box.height;
+};
+
+HShapeElement.prototype.renderInnerContent = function () {
+  this._renderShapeFrame();
+
+  if (!this.hidden && (this._isFirstFrame || this._mdf)) {
+    var tempBoundingBox = this.tempBoundingBox;
+    var max = 999999;
+    tempBoundingBox.x = max;
+    tempBoundingBox.xMax = -max;
+    tempBoundingBox.y = max;
+    tempBoundingBox.yMax = -max;
+    this.calculateBoundingBox(this.itemsData, tempBoundingBox);
+    tempBoundingBox.width = tempBoundingBox.xMax < tempBoundingBox.x ? 0 : tempBoundingBox.xMax - tempBoundingBox.x;
+    tempBoundingBox.height = tempBoundingBox.yMax < tempBoundingBox.y ? 0 : tempBoundingBox.yMax - tempBoundingBox.y;
+    // var tempBoundingBox = this.shapeCont.getBBox();
+    if (this.currentBoxContains(tempBoundingBox)) {
+      return;
+    }
+    var changed = false;
+    if (this.currentBBox.w !== tempBoundingBox.width) {
+      this.currentBBox.w = tempBoundingBox.width;
+      this.shapeCont.setAttribute('width', tempBoundingBox.width);
+      changed = true;
+    }
+    if (this.currentBBox.h !== tempBoundingBox.height) {
+      this.currentBBox.h = tempBoundingBox.height;
+      this.shapeCont.setAttribute('height', tempBoundingBox.height);
+      changed = true;
+    }
+    if (changed || this.currentBBox.x !== tempBoundingBox.x || this.currentBBox.y !== tempBoundingBox.y) {
+      this.currentBBox.w = tempBoundingBox.width;
+      this.currentBBox.h = tempBoundingBox.height;
+      this.currentBBox.x = tempBoundingBox.x;
+      this.currentBBox.y = tempBoundingBox.y;
+
+      this.shapeCont.setAttribute('viewBox', this.currentBBox.x + ' ' + this.currentBBox.y + ' ' + this.currentBBox.w + ' ' + this.currentBBox.h);
+      var shapeStyle = this.shapeCont.style;
+      var shapeTransform = 'translate(' + this.currentBBox.x + 'px,' + this.currentBBox.y + 'px)';
+      shapeStyle.transform = shapeTransform;
+      shapeStyle.webkitTransform = shapeTransform;
+    }
+  }
+};
+
+function HTextElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.textPaths = [];
+  this.currentBBox = {
+    x: 999999,
+    y: -999999,
+    h: 0,
+    w: 0,
+  };
+  this.renderType = 'svg';
+  this.isMasked = false;
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], HTextElement);
+
+HTextElement.prototype.createContent = function () {
+  this.isMasked = this.checkMasks();
+  if (this.isMasked) {
+    this.renderType = 'svg';
+    this.compW = this.comp.data.w;
+    this.compH = this.comp.data.h;
+    this.svgElement.setAttribute('width', this.compW);
+    this.svgElement.setAttribute('height', this.compH);
+    var g = createNS('g');
+    this.maskedElement.appendChild(g);
+    this.innerElem = g;
+  } else {
+    this.renderType = 'html';
+    this.innerElem = this.layerElement;
+  }
+
+  this.checkParenting();
+};
+
+HTextElement.prototype.buildNewText = function () {
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
+  var innerElemStyle = this.innerElem.style;
+  var textColor = documentData.fc ? this.buildColor(documentData.fc) : 'rgba(0,0,0,0)';
+  innerElemStyle.fill = textColor;
+  innerElemStyle.color = textColor;
+  if (documentData.sc) {
+    innerElemStyle.stroke = this.buildColor(documentData.sc);
+    innerElemStyle.strokeWidth = documentData.sw + 'px';
+  }
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (!this.globalData.fontManager.chars) {
+    innerElemStyle.fontSize = documentData.finalSize + 'px';
+    innerElemStyle.lineHeight = documentData.finalSize + 'px';
+    if (fontData.fClass) {
+      this.innerElem.className = fontData.fClass;
+    } else {
+      innerElemStyle.fontFamily = fontData.fFamily;
+      var fWeight = documentData.fWeight;
+      var fStyle = documentData.fStyle;
+      innerElemStyle.fontStyle = fStyle;
+      innerElemStyle.fontWeight = fWeight;
+    }
+  }
+  var i;
+  var len;
+
+  var letters = documentData.l;
+  len = letters.length;
+  var tSpan;
+  var tParent;
+  var tCont;
+  var matrixHelper = this.mHelper;
+  var shapes;
+  var shapeStr = '';
+  var cnt = 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.globalData.fontManager.chars) {
+      if (!this.textPaths[cnt]) {
+        tSpan = createNS('path');
+        tSpan.setAttribute('stroke-linecap', lineCapEnum[1]);
+        tSpan.setAttribute('stroke-linejoin', lineJoinEnum[2]);
+        tSpan.setAttribute('stroke-miterlimit', '4');
+      } else {
+        tSpan = this.textPaths[cnt];
+      }
+      if (!this.isMasked) {
+        if (this.textSpans[cnt]) {
+          tParent = this.textSpans[cnt];
+          tCont = tParent.children[0];
+        } else {
+          tParent = createTag('div');
+          tParent.style.lineHeight = 0;
+          tCont = createNS('svg');
+          tCont.appendChild(tSpan);
+          styleDiv(tParent);
+        }
+      }
+    } else if (!this.isMasked) {
+      if (this.textSpans[cnt]) {
+        tParent = this.textSpans[cnt];
+        tSpan = this.textPaths[cnt];
+      } else {
+        tParent = createTag('span');
+        styleDiv(tParent);
+        tSpan = createTag('span');
+        styleDiv(tSpan);
+        tParent.appendChild(tSpan);
+      }
+    } else {
+      tSpan = this.textPaths[cnt] ? this.textPaths[cnt] : createNS('text');
+    }
+    // tSpan.setAttribute('visibility', 'hidden');
+    if (this.globalData.fontManager.chars) {
+      var charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
+      var shapeData;
+      if (charData) {
+        shapeData = charData.data;
+      } else {
+        shapeData = null;
+      }
+      matrixHelper.reset();
+      if (shapeData && shapeData.shapes && shapeData.shapes.length) {
+        shapes = shapeData.shapes[0].it;
+        matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
+        shapeStr = this.createPathShape(matrixHelper, shapes);
+        tSpan.setAttribute('d', shapeStr);
+      }
+      if (!this.isMasked) {
+        this.innerElem.appendChild(tParent);
+        if (shapeData && shapeData.shapes) {
+          // document.body.appendChild is needed to get exact measure of shape
+          document.body.appendChild(tCont);
+          var boundingBox = tCont.getBBox();
+          tCont.setAttribute('width', boundingBox.width + 2);
+          tCont.setAttribute('height', boundingBox.height + 2);
+          tCont.setAttribute('viewBox', (boundingBox.x - 1) + ' ' + (boundingBox.y - 1) + ' ' + (boundingBox.width + 2) + ' ' + (boundingBox.height + 2));
+          var tContStyle = tCont.style;
+          var tContTranslation = 'translate(' + (boundingBox.x - 1) + 'px,' + (boundingBox.y - 1) + 'px)';
+          tContStyle.transform = tContTranslation;
+          tContStyle.webkitTransform = tContTranslation;
+
+          letters[i].yOffset = boundingBox.y - 1;
+        } else {
+          tCont.setAttribute('width', 1);
+          tCont.setAttribute('height', 1);
+        }
+        tParent.appendChild(tCont);
+      } else {
+        this.innerElem.appendChild(tSpan);
+      }
+    } else {
+      tSpan.textContent = letters[i].val;
+      tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      if (!this.isMasked) {
+        this.innerElem.appendChild(tParent);
+        //
+        var tStyle = tSpan.style;
+        var tSpanTranslation = 'translate3d(0,' + -documentData.finalSize / 1.2 + 'px,0)';
+        tStyle.transform = tSpanTranslation;
+        tStyle.webkitTransform = tSpanTranslation;
+      } else {
+        this.innerElem.appendChild(tSpan);
+      }
+    }
+    //
+    if (!this.isMasked) {
+      this.textSpans[cnt] = tParent;
+    } else {
+      this.textSpans[cnt] = tSpan;
+    }
+    this.textSpans[cnt].style.display = 'block';
+    this.textPaths[cnt] = tSpan;
+    cnt += 1;
+  }
+  while (cnt < this.textSpans.length) {
+    this.textSpans[cnt].style.display = 'none';
+    cnt += 1;
+  }
+};
+
+HTextElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  var svgStyle;
+  if (this.data.singleShape) {
+    if (!this._isFirstFrame && !this.lettersChangedFlag) {
+      return;
+    } if (this.isMasked && this.finalTransform._matMdf) {
+      // Todo Benchmark if using this is better than getBBox
+      this.svgElement.setAttribute('viewBox', -this.finalTransform.mProp.p.v[0] + ' ' + -this.finalTransform.mProp.p.v[1] + ' ' + this.compW + ' ' + this.compH);
+      svgStyle = this.svgElement.style;
+      var translation = 'translate(' + -this.finalTransform.mProp.p.v[0] + 'px,' + -this.finalTransform.mProp.p.v[1] + 'px)';
+      svgStyle.transform = translation;
+      svgStyle.webkitTransform = translation;
+    }
+  }
+
+  this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+  if (!this.lettersChangedFlag && !this.textAnimator.lettersChangedFlag) {
+    return;
+  }
+  var i;
+  var len;
+  var count = 0;
+  var renderedLetters = this.textAnimator.renderedLetters;
+
+  var letters = this.textProperty.currentData.l;
+
+  len = letters.length;
+  var renderedLetter;
+  var textSpan;
+  var textPath;
+  for (i = 0; i < len; i += 1) {
+    if (letters[i].n) {
+      count += 1;
+    } else {
+      textSpan = this.textSpans[i];
+      textPath = this.textPaths[i];
+      renderedLetter = renderedLetters[count];
+      count += 1;
+      if (renderedLetter._mdf.m) {
+        if (!this.isMasked) {
+          textSpan.style.webkitTransform = renderedLetter.m;
+          textSpan.style.transform = renderedLetter.m;
+        } else {
+          textSpan.setAttribute('transform', renderedLetter.m);
+        }
+      }
+      /// /textSpan.setAttribute('opacity',renderedLetter.o);
+      textSpan.style.opacity = renderedLetter.o;
+      if (renderedLetter.sw && renderedLetter._mdf.sw) {
+        textPath.setAttribute('stroke-width', renderedLetter.sw);
+      }
+      if (renderedLetter.sc && renderedLetter._mdf.sc) {
+        textPath.setAttribute('stroke', renderedLetter.sc);
+      }
+      if (renderedLetter.fc && renderedLetter._mdf.fc) {
+        textPath.setAttribute('fill', renderedLetter.fc);
+        textPath.style.color = renderedLetter.fc;
+      }
+    }
+  }
+
+  if (this.innerElem.getBBox && !this.hidden && (this._isFirstFrame || this._mdf)) {
+    var boundingBox = this.innerElem.getBBox();
+
+    if (this.currentBBox.w !== boundingBox.width) {
+      this.currentBBox.w = boundingBox.width;
+      this.svgElement.setAttribute('width', boundingBox.width);
+    }
+    if (this.currentBBox.h !== boundingBox.height) {
+      this.currentBBox.h = boundingBox.height;
+      this.svgElement.setAttribute('height', boundingBox.height);
+    }
+
+    var margin = 1;
+    if (this.currentBBox.w !== (boundingBox.width + margin * 2) || this.currentBBox.h !== (boundingBox.height + margin * 2) || this.currentBBox.x !== (boundingBox.x - margin) || this.currentBBox.y !== (boundingBox.y - margin)) {
+      this.currentBBox.w = boundingBox.width + margin * 2;
+      this.currentBBox.h = boundingBox.height + margin * 2;
+      this.currentBBox.x = boundingBox.x - margin;
+      this.currentBBox.y = boundingBox.y - margin;
+
+      this.svgElement.setAttribute('viewBox', this.currentBBox.x + ' ' + this.currentBBox.y + ' ' + this.currentBBox.w + ' ' + this.currentBBox.h);
+      svgStyle = this.svgElement.style;
+      var svgTransform = 'translate(' + this.currentBBox.x + 'px,' + this.currentBBox.y + 'px)';
+      svgStyle.transform = svgTransform;
+      svgStyle.webkitTransform = svgTransform;
+    }
+  }
+};
+
+function HCameraElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initHierarchy();
+  var getProp = PropertyFactory.getProp;
+  this.pe = getProp(this, data.pe, 0, 0, this);
+  if (data.ks.p.s) {
+    this.px = getProp(this, data.ks.p.x, 1, 0, this);
+    this.py = getProp(this, data.ks.p.y, 1, 0, this);
+    this.pz = getProp(this, data.ks.p.z, 1, 0, this);
+  } else {
+    this.p = getProp(this, data.ks.p, 1, 0, this);
+  }
+  if (data.ks.a) {
+    this.a = getProp(this, data.ks.a, 1, 0, this);
+  }
+  if (data.ks.or.k.length && data.ks.or.k[0].to) {
+    var i;
+    var len = data.ks.or.k.length;
+    for (i = 0; i < len; i += 1) {
+      data.ks.or.k[i].to = null;
+      data.ks.or.k[i].ti = null;
+    }
+  }
+  this.or = getProp(this, data.ks.or, 1, degToRads, this);
+  this.or.sh = true;
+  this.rx = getProp(this, data.ks.rx, 0, degToRads, this);
+  this.ry = getProp(this, data.ks.ry, 0, degToRads, this);
+  this.rz = getProp(this, data.ks.rz, 0, degToRads, this);
+  this.mat = new Matrix();
+  this._prevMat = new Matrix();
+  this._isFirstFrame = true;
+
+  // TODO: find a better way to make the HCamera element to be compatible with the LayerInterface and TransformInterface.
+  this.finalTransform = {
+    mProp: this,
+  };
+}
+extendPrototype([BaseElement, FrameElement, HierarchyElement], HCameraElement);
+
+HCameraElement.prototype.setup = function () {
+  var i;
+  var len = this.comp.threeDElements.length;
+  var comp;
+  var perspectiveStyle;
+  var containerStyle;
+  for (i = 0; i < len; i += 1) {
+    // [perspectiveElem,container]
+    comp = this.comp.threeDElements[i];
+    if (comp.type === '3d') {
+      perspectiveStyle = comp.perspectiveElem.style;
+      containerStyle = comp.container.style;
+      var perspective = this.pe.v + 'px';
+      var origin = '0px 0px 0px';
+      var matrix = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)';
+      perspectiveStyle.perspective = perspective;
+      perspectiveStyle.webkitPerspective = perspective;
+      containerStyle.transformOrigin = origin;
+      containerStyle.mozTransformOrigin = origin;
+      containerStyle.webkitTransformOrigin = origin;
+      perspectiveStyle.transform = matrix;
+      perspectiveStyle.webkitTransform = matrix;
+    }
+  }
+};
+
+HCameraElement.prototype.createElements = function () {
+};
+
+HCameraElement.prototype.hide = function () {
+};
+
+HCameraElement.prototype.renderFrame = function () {
+  var _mdf = this._isFirstFrame;
+  var i;
+  var len;
+  if (this.hierarchy) {
+    len = this.hierarchy.length;
+    for (i = 0; i < len; i += 1) {
+      _mdf = this.hierarchy[i].finalTransform.mProp._mdf || _mdf;
+    }
+  }
+  if (_mdf || this.pe._mdf || (this.p && this.p._mdf) || (this.px && (this.px._mdf || this.py._mdf || this.pz._mdf)) || this.rx._mdf || this.ry._mdf || this.rz._mdf || this.or._mdf || (this.a && this.a._mdf)) {
+    this.mat.reset();
+
+    if (this.hierarchy) {
+      len = this.hierarchy.length - 1;
+      for (i = len; i >= 0; i -= 1) {
+        var mTransf = this.hierarchy[i].finalTransform.mProp;
+        this.mat.translate(-mTransf.p.v[0], -mTransf.p.v[1], mTransf.p.v[2]);
+        this.mat.rotateX(-mTransf.or.v[0]).rotateY(-mTransf.or.v[1]).rotateZ(mTransf.or.v[2]);
+        this.mat.rotateX(-mTransf.rx.v).rotateY(-mTransf.ry.v).rotateZ(mTransf.rz.v);
+        this.mat.scale(1 / mTransf.s.v[0], 1 / mTransf.s.v[1], 1 / mTransf.s.v[2]);
+        this.mat.translate(mTransf.a.v[0], mTransf.a.v[1], mTransf.a.v[2]);
+      }
+    }
+    if (this.p) {
+      this.mat.translate(-this.p.v[0], -this.p.v[1], this.p.v[2]);
+    } else {
+      this.mat.translate(-this.px.v, -this.py.v, this.pz.v);
+    }
+    if (this.a) {
+      var diffVector;
+      if (this.p) {
+        diffVector = [this.p.v[0] - this.a.v[0], this.p.v[1] - this.a.v[1], this.p.v[2] - this.a.v[2]];
+      } else {
+        diffVector = [this.px.v - this.a.v[0], this.py.v - this.a.v[1], this.pz.v - this.a.v[2]];
+      }
+      var mag = Math.sqrt(Math.pow(diffVector[0], 2) + Math.pow(diffVector[1], 2) + Math.pow(diffVector[2], 2));
+      // var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
+      var lookDir = [diffVector[0] / mag, diffVector[1] / mag, diffVector[2] / mag];
+      var lookLengthOnXZ = Math.sqrt(lookDir[2] * lookDir[2] + lookDir[0] * lookDir[0]);
+      var mRotationX = (Math.atan2(lookDir[1], lookLengthOnXZ));
+      var mRotationY = (Math.atan2(lookDir[0], -lookDir[2]));
+      this.mat.rotateY(mRotationY).rotateX(-mRotationX);
+    }
+    this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v);
+    this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]);
+    this.mat.translate(this.globalData.compSize.w / 2, this.globalData.compSize.h / 2, 0);
+    this.mat.translate(0, 0, this.pe.v);
+
+    var hasMatrixChanged = !this._prevMat.equals(this.mat);
+    if ((hasMatrixChanged || this.pe._mdf) && this.comp.threeDElements) {
+      len = this.comp.threeDElements.length;
+      var comp;
+      var perspectiveStyle;
+      var containerStyle;
+      for (i = 0; i < len; i += 1) {
+        comp = this.comp.threeDElements[i];
+        if (comp.type === '3d') {
+          if (hasMatrixChanged) {
+            var matValue = this.mat.toCSS();
+            containerStyle = comp.container.style;
+            containerStyle.transform = matValue;
+            containerStyle.webkitTransform = matValue;
+          }
+          if (this.pe._mdf) {
+            perspectiveStyle = comp.perspectiveElem.style;
+            perspectiveStyle.perspective = this.pe.v + 'px';
+            perspectiveStyle.webkitPerspective = this.pe.v + 'px';
+          }
+        }
+      }
+      this.mat.clone(this._prevMat);
+    }
+  }
+  this._isFirstFrame = false;
+};
+
+HCameraElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+HCameraElement.prototype.destroy = function () {
+};
+HCameraElement.prototype.getBaseElement = function () { return null; };
+
+function HImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, HBaseElement, HSolidElement, HierarchyElement, FrameElement, RenderableElement], HImageElement);
+
+HImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  var img = new Image();
+
+  if (this.data.hasMask) {
+    this.imageElem = createNS('image');
+    this.imageElem.setAttribute('width', this.assetData.w + 'px');
+    this.imageElem.setAttribute('height', this.assetData.h + 'px');
+    this.imageElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+    this.layerElement.appendChild(this.imageElem);
+    this.baseElement.setAttribute('width', this.assetData.w);
+    this.baseElement.setAttribute('height', this.assetData.h);
+  } else {
+    this.layerElement.appendChild(img);
+  }
+  img.crossOrigin = 'anonymous';
+  img.src = assetPath;
+  if (this.data.ln) {
+    this.baseElement.setAttribute('id', this.data.ln);
+  }
+};
+
+function HybridRendererBase(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),
+    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], HybridRendererBase);
+
+HybridRendererBase.prototype.buildItem = SVGRenderer.prototype.buildItem;
+
+HybridRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+  }
+};
+
+HybridRendererBase.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;
+      var nextLayer;
+      var 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);
+  }
+};
+
+HybridRendererBase.prototype.createShape = function (data) {
+  if (!this.supports3d) {
+    return new SVGShapeElement(data, this.globalData, this);
+  }
+  return new HShapeElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createText = function (data) {
+  if (!this.supports3d) {
+    return new SVGTextLottieElement(data, this.globalData, this);
+  }
+  return new HTextElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createCamera = function (data) {
+  this.camera = new HCameraElement(data, this.globalData, this);
+  return this.camera;
+};
+
+HybridRendererBase.prototype.createImage = function (data) {
+  if (!this.supports3d) {
+    return new IImageElement(data, this.globalData, this);
+  }
+  return new HImageElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createSolid = function (data) {
+  if (!this.supports3d) {
+    return new ISolidElement(data, this.globalData, this);
+  }
+  return new HSolidElement(data, this.globalData, this);
+};
+
+HybridRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
+
+HybridRendererBase.prototype.getThreeDContainerByPos = function (pos) {
+  var i = 0;
+  var 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;
+  }
+  return null;
+};
+
+HybridRendererBase.prototype.createThreeDContainer = function (pos, type) {
+  var perspectiveElem = createTag('div');
+  var style;
+  var containerStyle;
+  styleDiv(perspectiveElem);
+  var container = createTag('div');
+  styleDiv(container);
+  if (type === '3d') {
+    style = perspectiveElem.style;
+    style.width = this.globalData.compSize.w + 'px';
+    style.height = this.globalData.compSize.h + 'px';
+    var center = '50% 50%';
+    style.webkitTransformOrigin = center;
+    style.mozTransformOrigin = center;
+    style.transformOrigin = center;
+    containerStyle = container.style;
+    var matrix = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)';
+    containerStyle.transform = matrix;
+    containerStyle.webkitTransform = matrix;
+  }
+
+  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;
+};
+
+HybridRendererBase.prototype.build3dContainers = function () {
+  var i;
+  var 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 -= 1) {
+    this.resizerElem.appendChild(this.threeDElements[i].perspectiveElem);
+  }
+};
+
+HybridRendererBase.prototype.addTo3dContainer = function (elem, pos) {
+  var i = 0;
+  var 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;
+  }
+};
+
+HybridRendererBase.prototype.configAnimation = function (animData) {
+  var resizerElem = createTag('div');
+  var wrapper = this.animationItem.wrapper;
+  var style = resizerElem.style;
+  style.width = animData.w + 'px';
+  style.height = animData.h + 'px';
+  this.resizerElem = resizerElem;
+  styleDiv(resizerElem);
+  style.transformStyle = 'flat';
+  style.mozTransformStyle = 'flat';
+  style.webkitTransformStyle = 'flat';
+  if (this.renderConfig.className) {
+    resizerElem.setAttribute('class', this.renderConfig.className);
+  }
+  wrapper.appendChild(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();
+};
+
+HybridRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.animationItem.container = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+HybridRendererBase.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;
+  var sy;
+  var tx;
+  var 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;
+  }
+  var style = this.resizerElem.style;
+  style.webkitTransform = 'matrix3d(' + sx + ',0,0,0,0,' + sy + ',0,0,0,0,1,0,' + tx + ',' + ty + ',0,1)';
+  style.transform = style.webkitTransform;
+};
+
+HybridRendererBase.prototype.renderFrame = SVGRenderer.prototype.renderFrame;
+
+HybridRendererBase.prototype.hide = function () {
+  this.resizerElem.style.display = 'none';
+};
+
+HybridRendererBase.prototype.show = function () {
+  this.resizerElem.style.display = 'block';
+};
+
+HybridRendererBase.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;
+    var len = this.threeDElements.length;
+    for (i = 0; i < len; i += 1) {
+      var style = this.threeDElements[i].perspectiveElem.style;
+      style.webkitPerspective = Math.sqrt(Math.pow(cWidth, 2) + Math.pow(cHeight, 2)) + 'px';
+      style.perspective = style.webkitPerspective;
+    }
+  }
+};
+
+HybridRendererBase.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var 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);
+    }
+  }
+};
+
+function HCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = !data.hasMask;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([HybridRendererBase, ICompElement, HBaseElement], HCompElement);
+HCompElement.prototype._createBaseContainerElements = HCompElement.prototype.createContainerElements;
+
+HCompElement.prototype.createContainerElements = function () {
+  this._createBaseContainerElements();
+  // divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
+  if (this.data.hasMask) {
+    this.svgElement.setAttribute('width', this.data.w);
+    this.svgElement.setAttribute('height', this.data.h);
+    this.transformedElement = this.baseElement;
+  } else {
+    this.transformedElement = this.layerElement;
+  }
+};
+
+HCompElement.prototype.addTo3dContainer = function (elem, pos) {
+  var j = 0;
+  var nextElement;
+  while (j < pos) {
+    if (this.elements[j] && this.elements[j].getBaseElement) {
+      nextElement = this.elements[j].getBaseElement();
+    }
+    j += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(elem, nextElement);
+  } else {
+    this.layerElement.appendChild(elem);
+  }
+};
+
+HCompElement.prototype.createComp = function (data) {
+  if (!this.supports3d) {
+    return new SVGCompElement(data, this.globalData, this);
+  }
+  return new HCompElement(data, this.globalData, this);
+};
+
+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),
+    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%',
+    },
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+  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([HybridRendererBase], HybridRenderer);
+
+HybridRenderer.prototype.createComp = function (data) {
+  if (!this.supports3d) {
+    return new SVGCompElement(data, this.globalData, this);
+  }
+  return new HCompElement(data, this.globalData, this);
+};
+
+// Registering renderers
+registerRenderer('html', HybridRenderer);
+
+// Registering shape modifiers
+ShapeModifiers.registerModifier('tm', TrimModifier);
+ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
+ShapeModifiers.registerModifier('rp', RepeaterModifier);
+ShapeModifiers.registerModifier('rd', RoundCornersModifier);
+ShapeModifiers.registerModifier('zz', ZigZagModifier);
+ShapeModifiers.registerModifier('op', OffsetPathModifier);
+
+export { lottie as default };
diff --git a/build/player/esm/lottie_svg.min.js b/build/player/esm/lottie_svg.min.js
new file mode 100644
index 0000000..145d49f
--- /dev/null
+++ b/build/player/esm/lottie_svg.min.js
@@ -0,0 +1,15049 @@
+const svgNS = 'http://www.w3.org/2000/svg';
+
+let locationHref = '';
+let _useWebWorker = false;
+
+const initialDefaultFrame = -999999;
+
+const setWebWorker = (flag) => { _useWebWorker = !!flag; };
+const getWebWorker = () => _useWebWorker;
+
+const setLocationHref = (value) => { locationHref = value; };
+const getLocationHref = () => locationHref;
+
+function createTag(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElement(type);
+}
+
+function extendPrototype(sources, destination) {
+  var i;
+  var len = sources.length;
+  var sourcePrototype;
+  for (i = 0; i < len; i += 1) {
+    sourcePrototype = sources[i].prototype;
+    for (var attr in sourcePrototype) {
+      if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
+    }
+  }
+}
+
+function getDescriptor(object, prop) {
+  return Object.getOwnPropertyDescriptor(object, prop);
+}
+
+function createProxyFunction(prototype) {
+  function ProxyFunction() {}
+  ProxyFunction.prototype = prototype;
+  return ProxyFunction;
+}
+
+// import Howl from '../../3rd_party/howler';
+
+const audioControllerFactory = (function () {
+  function AudioController(audioFactory) {
+    this.audios = [];
+    this.audioFactory = audioFactory;
+    this._volume = 1;
+    this._isMuted = false;
+  }
+
+  AudioController.prototype = {
+    addAudio: function (audio) {
+      this.audios.push(audio);
+    },
+    pause: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].pause();
+      }
+    },
+    resume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].resume();
+      }
+    },
+    setRate: function (rateValue) {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].setRate(rateValue);
+      }
+    },
+    createAudio: function (assetPath) {
+      if (this.audioFactory) {
+        return this.audioFactory(assetPath);
+      } if (window.Howl) {
+        return new window.Howl({
+          src: [assetPath],
+        });
+      }
+      return {
+        isPlaying: false,
+        play: function () { this.isPlaying = true; },
+        seek: function () { this.isPlaying = false; },
+        playing: function () {},
+        rate: function () {},
+        setVolume: function () {},
+      };
+    },
+    setAudioFactory: function (audioFactory) {
+      this.audioFactory = audioFactory;
+    },
+    setVolume: function (value) {
+      this._volume = value;
+      this._updateVolume();
+    },
+    mute: function () {
+      this._isMuted = true;
+      this._updateVolume();
+    },
+    unmute: function () {
+      this._isMuted = false;
+      this._updateVolume();
+    },
+    getVolume: function () {
+      return this._volume;
+    },
+    _updateVolume: function () {
+      var i;
+      var len = this.audios.length;
+      for (i = 0; i < len; i += 1) {
+        this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
+      }
+    },
+  };
+
+  return function () {
+    return new AudioController();
+  };
+}());
+
+const createTypedArray = (function () {
+  function createRegularArray(type, len) {
+    var i = 0;
+    var arr = [];
+    var value;
+    switch (type) {
+      case 'int16':
+      case 'uint8c':
+        value = 1;
+        break;
+      default:
+        value = 1.1;
+        break;
+    }
+    for (i = 0; i < len; i += 1) {
+      arr.push(value);
+    }
+    return arr;
+  }
+  function createTypedArrayFactory(type, len) {
+    if (type === 'float32') {
+      return new Float32Array(len);
+    } if (type === 'int16') {
+      return new Int16Array(len);
+    } if (type === 'uint8c') {
+      return new Uint8ClampedArray(len);
+    }
+    return createRegularArray(type, len);
+  }
+  if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
+    return createTypedArrayFactory;
+  }
+  return createRegularArray;
+}());
+
+function createSizedArray(len) {
+  return Array.apply(null, { length: len });
+}
+
+let subframeEnabled = true;
+let expressionsPlugin = null;
+let expressionsInterfaces = null;
+let idPrefix$1 = '';
+const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+let _shouldRoundValues = false;
+const bmPow = Math.pow;
+const bmSqrt = Math.sqrt;
+const bmFloor = Math.floor;
+const bmMax = Math.max;
+const bmMin = Math.min;
+
+const BMMath = {};
+(function () {
+  var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
+  var i;
+  var len = propertyNames.length;
+  for (i = 0; i < len; i += 1) {
+    BMMath[propertyNames[i]] = Math[propertyNames[i]];
+  }
+}());
+
+function ProjectInterface$1() { return {}; }
+BMMath.random = Math.random;
+BMMath.abs = function (val) {
+  var tOfVal = typeof val;
+  if (tOfVal === 'object' && val.length) {
+    var absArr = createSizedArray(val.length);
+    var i;
+    var len = val.length;
+    for (i = 0; i < len; i += 1) {
+      absArr[i] = Math.abs(val[i]);
+    }
+    return absArr;
+  }
+  return Math.abs(val);
+};
+let defaultCurveSegments = 150;
+const degToRads = Math.PI / 180;
+const roundCorner = 0.5519;
+
+function roundValues(flag) {
+  _shouldRoundValues = !!flag;
+}
+
+function bmRnd(value) {
+  if (_shouldRoundValues) {
+    return Math.round(value);
+  }
+  return value;
+}
+
+function styleDiv(element) {
+  element.style.position = 'absolute';
+  element.style.top = 0;
+  element.style.left = 0;
+  element.style.display = 'block';
+  element.style.transformOrigin = '0 0';
+  element.style.webkitTransformOrigin = '0 0';
+  element.style.backfaceVisibility = 'visible';
+  element.style.webkitBackfaceVisibility = 'visible';
+  element.style.transformStyle = 'preserve-3d';
+  element.style.webkitTransformStyle = 'preserve-3d';
+  element.style.mozTransformStyle = 'preserve-3d';
+}
+
+function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
+  this.type = type;
+  this.currentTime = currentTime;
+  this.totalTime = totalTime;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteEvent(type, frameMultiplier) {
+  this.type = type;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
+  this.type = type;
+  this.currentLoop = currentLoop;
+  this.totalLoops = totalLoops;
+  this.direction = frameMultiplier < 0 ? -1 : 1;
+}
+
+function BMSegmentStartEvent(type, firstFrame, totalFrames) {
+  this.type = type;
+  this.firstFrame = firstFrame;
+  this.totalFrames = totalFrames;
+}
+
+function BMDestroyEvent(type, target) {
+  this.type = type;
+  this.target = target;
+}
+
+function BMRenderFrameErrorEvent(nativeError, currentTime) {
+  this.type = 'renderFrameError';
+  this.nativeError = nativeError;
+  this.currentTime = currentTime;
+}
+
+function BMConfigErrorEvent(nativeError) {
+  this.type = 'configError';
+  this.nativeError = nativeError;
+}
+
+function BMAnimationConfigErrorEvent(type, nativeError) {
+  this.type = type;
+  this.nativeError = nativeError;
+}
+
+const createElementID = (function () {
+  var _count = 0;
+  return function createID() {
+    _count += 1;
+    return idPrefix$1 + '__lottie_element_' + _count;
+  };
+}());
+
+function HSVtoRGB(h, s, v) {
+  var r;
+  var g;
+  var b;
+  var i;
+  var f;
+  var p;
+  var q;
+  var t;
+  i = Math.floor(h * 6);
+  f = h * 6 - i;
+  p = v * (1 - s);
+  q = v * (1 - f * s);
+  t = v * (1 - (1 - f) * s);
+  switch (i % 6) {
+    case 0: r = v; g = t; b = p; break;
+    case 1: r = q; g = v; b = p; break;
+    case 2: r = p; g = v; b = t; break;
+    case 3: r = p; g = q; b = v; break;
+    case 4: r = t; g = p; b = v; break;
+    case 5: r = v; g = p; b = q; break;
+    default: break;
+  }
+  return [r,
+    g,
+    b];
+}
+
+function RGBtoHSV(r, g, b) {
+  var max = Math.max(r, g, b);
+  var min = Math.min(r, g, b);
+  var d = max - min;
+  var h;
+  var s = (max === 0 ? 0 : d / max);
+  var v = max / 255;
+
+  switch (max) {
+    case min: h = 0; break;
+    case r: h = (g - b) + d * (g < b ? 6 : 0); h /= 6 * d; break;
+    case g: h = (b - r) + d * 2; h /= 6 * d; break;
+    case b: h = (r - g) + d * 4; h /= 6 * d; break;
+    default: break;
+  }
+
+  return [
+    h,
+    s,
+    v,
+  ];
+}
+
+function addSaturationToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[1] += offset;
+  if (hsv[1] > 1) {
+    hsv[1] = 1;
+  } else if (hsv[1] <= 0) {
+    hsv[1] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addBrightnessToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[2] += offset;
+  if (hsv[2] > 1) {
+    hsv[2] = 1;
+  } else if (hsv[2] < 0) {
+    hsv[2] = 0;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+function addHueToRGB(color, offset) {
+  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
+  hsv[0] += offset / 360;
+  if (hsv[0] > 1) {
+    hsv[0] -= 1;
+  } else if (hsv[0] < 0) {
+    hsv[0] += 1;
+  }
+  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
+}
+
+const rgbToHex = (function () {
+  var colorMap = [];
+  var i;
+  var hex;
+  for (i = 0; i < 256; i += 1) {
+    hex = i.toString(16);
+    colorMap[i] = hex.length === 1 ? '0' + hex : hex;
+  }
+
+  return function (r, g, b) {
+    if (r < 0) {
+      r = 0;
+    }
+    if (g < 0) {
+      g = 0;
+    }
+    if (b < 0) {
+      b = 0;
+    }
+    return '#' + colorMap[r] + colorMap[g] + colorMap[b];
+  };
+}());
+
+const setSubframeEnabled = (flag) => { subframeEnabled = !!flag; };
+const getSubframeEnabled = () => subframeEnabled;
+const setExpressionsPlugin = (value) => { expressionsPlugin = value; };
+const getExpressionsPlugin = () => expressionsPlugin;
+const setExpressionInterfaces = (value) => { expressionsInterfaces = value; };
+const getExpressionInterfaces = () => expressionsInterfaces;
+const setDefaultCurveSegments = (value) => { defaultCurveSegments = value; };
+const getDefaultCurveSegments = () => defaultCurveSegments;
+const setIdPrefix = (value) => { idPrefix$1 = value; };
+const getIdPrefix = () => idPrefix$1;
+
+function createNS(type) {
+  // return {appendChild:function(){},setAttribute:function(){},style:{}}
+  return document.createElementNS(svgNS, type);
+}
+
+const dataManager = (function () {
+  var _counterId = 1;
+  var processes = [];
+  var workerFn;
+  var workerInstance;
+  var workerProxy = {
+    onmessage: function () {
+
+    },
+    postMessage: function (path) {
+      workerFn({
+        data: path,
+      });
+    },
+  };
+  var _workerSelf = {
+    postMessage: function (data) {
+      workerProxy.onmessage({
+        data: data,
+      });
+    },
+  };
+  function createWorker(fn) {
+    if (window.Worker && window.Blob && getWebWorker()) {
+      var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
+      var url = URL.createObjectURL(blob);
+      return new Worker(url);
+    }
+    workerFn = fn;
+    return workerProxy;
+  }
+
+  function setupWorker() {
+    if (!workerInstance) {
+      workerInstance = createWorker(function workerStart(e) {
+        function dataFunctionManager() {
+          function completeLayers(layers, comps) {
+            var layerData;
+            var i;
+            var len = layers.length;
+            var j;
+            var jLen;
+            var k;
+            var kLen;
+            for (i = 0; i < len; i += 1) {
+              layerData = layers[i];
+              if (('ks' in layerData) && !layerData.completed) {
+                layerData.completed = true;
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      convertPathsToAbsoluteValues(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) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 0) {
+                  layerData.layers = findCompLayers(layerData.refId, comps);
+                  completeLayers(layerData.layers, comps);
+                } else if (layerData.ty === 4) {
+                  completeShapes(layerData.shapes);
+                } else if (layerData.ty === 5) {
+                  completeText(layerData);
+                }
+              }
+            }
+          }
+
+          function completeChars(chars, assets) {
+            if (chars) {
+              var i = 0;
+              var len = chars.length;
+              for (i = 0; i < len; i += 1) {
+                if (chars[i].t === 1) {
+                  // var compData = findComp(chars[i].data.refId, assets);
+                  chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                  // chars[i].data.ip = 0;
+                  // chars[i].data.op = 99999;
+                  // chars[i].data.st = 0;
+                  // chars[i].data.sr = 1;
+                  // chars[i].w = compData.w;
+                  // chars[i].data.ks = {
+                  //   a: { k: [0, 0, 0], a: 0 },
+                  //   p: { k: [0, -compData.h, 0], a: 0 },
+                  //   r: { k: 0, a: 0 },
+                  //   s: { k: [100, 100], a: 0 },
+                  //   o: { k: 100, a: 0 },
+                  // };
+                  completeLayers(chars[i].data.layers, assets);
+                }
+              }
+            }
+          }
+
+          function findComp(id, comps) {
+            var i = 0;
+            var len = comps.length;
+            while (i < len) {
+              if (comps[i].id === id) {
+                return comps[i];
+              }
+              i += 1;
+            }
+            return null;
+          }
+
+          function findCompLayers(id, comps) {
+            var comp = findComp(id, comps);
+            if (comp) {
+              if (!comp.layers.__used) {
+                comp.layers.__used = true;
+                return comp.layers;
+              }
+              return JSON.parse(JSON.stringify(comp.layers));
+            }
+            return null;
+          }
+
+          function completeShapes(arr) {
+            var i;
+            var len = arr.length;
+            var j;
+            var jLen;
+            for (i = len - 1; i >= 0; i -= 1) {
+              if (arr[i].ty === 'sh') {
+                if (arr[i].ks.k.i) {
+                  convertPathsToAbsoluteValues(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) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
+                    }
+                    if (arr[i].ks.k[j].e) {
+                      convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
+                    }
+                  }
+                }
+              } else if (arr[i].ty === 'gr') {
+                completeShapes(arr[i].it);
+              }
+            }
+          }
+
+          function convertPathsToAbsoluteValues(path) {
+            var i;
+            var len = path.i.length;
+            for (i = 0; i < len; i += 1) {
+              path.i[i][0] += path.v[i][0];
+              path.i[i][1] += path.v[i][1];
+              path.o[i][0] += path.v[i][0];
+              path.o[i][1] += path.v[i][1];
+            }
+          }
+
+          function checkVersion(minimum, animVersionString) {
+            var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
+            if (minimum[0] > animVersion[0]) {
+              return true;
+            } if (animVersion[0] > minimum[0]) {
+              return false;
+            }
+            if (minimum[1] > animVersion[1]) {
+              return true;
+            } if (animVersion[1] > minimum[1]) {
+              return false;
+            }
+            if (minimum[2] > animVersion[2]) {
+              return true;
+            } if (animVersion[2] > minimum[2]) {
+              return false;
+            }
+            return null;
+          }
+
+          var checkText = (function () {
+            var minimumVersion = [4, 4, 14];
+
+            function updateTextLayer(textLayer) {
+              var documentData = textLayer.t.d;
+              textLayer.t.d = {
+                k: [
+                  {
+                    s: documentData,
+                    t: 0,
+                  },
+                ],
+              };
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkChars = (function () {
+            var minimumVersion = [4, 7, 99];
+            return function (animationData) {
+              if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
+                var i;
+                var len = animationData.chars.length;
+                for (i = 0; i < len; i += 1) {
+                  var charData = animationData.chars[i];
+                  if (charData.data && charData.data.shapes) {
+                    completeShapes(charData.data.shapes);
+                    charData.data.ip = 0;
+                    charData.data.op = 99999;
+                    charData.data.st = 0;
+                    charData.data.sr = 1;
+                    charData.data.ks = {
+                      p: { k: [0, 0], a: 0 },
+                      s: { k: [100, 100], a: 0 },
+                      a: { k: [0, 0], a: 0 },
+                      r: { k: 0, a: 0 },
+                      o: { k: 100, a: 0 },
+                    };
+                    if (!animationData.chars[i].t) {
+                      charData.data.shapes.push(
+                        {
+                          ty: 'no',
+                        }
+                      );
+                      charData.data.shapes[0].it.push(
+                        {
+                          p: { k: [0, 0], a: 0 },
+                          s: { k: [100, 100], a: 0 },
+                          a: { k: [0, 0], a: 0 },
+                          r: { k: 0, a: 0 },
+                          o: { k: 100, a: 0 },
+                          sk: { k: 0, a: 0 },
+                          sa: { k: 0, a: 0 },
+                          ty: 'tr',
+                        }
+                      );
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkPathProperties = (function () {
+            var minimumVersion = [5, 7, 15];
+
+            function updateTextLayer(textLayer) {
+              var pathData = textLayer.t.p;
+              if (typeof pathData.a === 'number') {
+                pathData.a = {
+                  a: 0,
+                  k: pathData.a,
+                };
+              }
+              if (typeof pathData.p === 'number') {
+                pathData.p = {
+                  a: 0,
+                  k: pathData.p,
+                };
+              }
+              if (typeof pathData.r === 'number') {
+                pathData.r = {
+                  a: 0,
+                  k: pathData.r,
+                };
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 5) {
+                  updateTextLayer(layers[i]);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkColors = (function () {
+            var minimumVersion = [4, 1, 9];
+
+            function iterateShapes(shapes) {
+              var i;
+              var len = shapes.length;
+              var j;
+              var jLen;
+              for (i = 0; i < len; i += 1) {
+                if (shapes[i].ty === 'gr') {
+                  iterateShapes(shapes[i].it);
+                } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
+                  if (shapes[i].c.k && shapes[i].c.k[0].i) {
+                    jLen = shapes[i].c.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (shapes[i].c.k[j].s) {
+                        shapes[i].c.k[j].s[0] /= 255;
+                        shapes[i].c.k[j].s[1] /= 255;
+                        shapes[i].c.k[j].s[2] /= 255;
+                        shapes[i].c.k[j].s[3] /= 255;
+                      }
+                      if (shapes[i].c.k[j].e) {
+                        shapes[i].c.k[j].e[0] /= 255;
+                        shapes[i].c.k[j].e[1] /= 255;
+                        shapes[i].c.k[j].e[2] /= 255;
+                        shapes[i].c.k[j].e[3] /= 255;
+                      }
+                    }
+                  } else {
+                    shapes[i].c.k[0] /= 255;
+                    shapes[i].c.k[1] /= 255;
+                    shapes[i].c.k[2] /= 255;
+                    shapes[i].c.k[3] /= 255;
+                  }
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var i;
+              var len = layers.length;
+              for (i = 0; i < len; i += 1) {
+                if (layers[i].ty === 4) {
+                  iterateShapes(layers[i].shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          var checkShapes = (function () {
+            var minimumVersion = [4, 4, 18];
+
+            function completeClosingShapes(arr) {
+              var i;
+              var len = arr.length;
+              var j;
+              var jLen;
+              for (i = len - 1; i >= 0; i -= 1) {
+                if (arr[i].ty === 'sh') {
+                  if (arr[i].ks.k.i) {
+                    arr[i].ks.k.c = arr[i].closed;
+                  } else {
+                    jLen = arr[i].ks.k.length;
+                    for (j = 0; j < jLen; j += 1) {
+                      if (arr[i].ks.k[j].s) {
+                        arr[i].ks.k[j].s[0].c = arr[i].closed;
+                      }
+                      if (arr[i].ks.k[j].e) {
+                        arr[i].ks.k[j].e[0].c = arr[i].closed;
+                      }
+                    }
+                  }
+                } else if (arr[i].ty === 'gr') {
+                  completeClosingShapes(arr[i].it);
+                }
+              }
+            }
+
+            function iterateLayers(layers) {
+              var layerData;
+              var i;
+              var len = layers.length;
+              var j;
+              var jLen;
+              var k;
+              var kLen;
+              for (i = 0; i < len; i += 1) {
+                layerData = layers[i];
+                if (layerData.hasMask) {
+                  var maskProps = layerData.masksProperties;
+                  jLen = maskProps.length;
+                  for (j = 0; j < jLen; j += 1) {
+                    if (maskProps[j].pt.k.i) {
+                      maskProps[j].pt.k.c = maskProps[j].cl;
+                    } else {
+                      kLen = maskProps[j].pt.k.length;
+                      for (k = 0; k < kLen; k += 1) {
+                        if (maskProps[j].pt.k[k].s) {
+                          maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
+                        }
+                        if (maskProps[j].pt.k[k].e) {
+                          maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
+                        }
+                      }
+                    }
+                  }
+                }
+                if (layerData.ty === 4) {
+                  completeClosingShapes(layerData.shapes);
+                }
+              }
+            }
+
+            return function (animationData) {
+              if (checkVersion(minimumVersion, animationData.v)) {
+                iterateLayers(animationData.layers);
+                if (animationData.assets) {
+                  var i;
+                  var len = animationData.assets.length;
+                  for (i = 0; i < len; i += 1) {
+                    if (animationData.assets[i].layers) {
+                      iterateLayers(animationData.assets[i].layers);
+                    }
+                  }
+                }
+              }
+            };
+          }());
+
+          function completeData(animationData) {
+            if (animationData.__complete) {
+              return;
+            }
+            checkColors(animationData);
+            checkText(animationData);
+            checkChars(animationData);
+            checkPathProperties(animationData);
+            checkShapes(animationData);
+            completeLayers(animationData.layers, animationData.assets);
+            completeChars(animationData.chars, animationData.assets);
+            animationData.__complete = true;
+          }
+
+          function completeText(data) {
+            if (data.t.a.length === 0 && !('m' in data.t.p)) {
+              // data.singleShape = true;
+            }
+          }
+
+          var moduleOb = {};
+          moduleOb.completeData = completeData;
+          moduleOb.checkColors = checkColors;
+          moduleOb.checkChars = checkChars;
+          moduleOb.checkPathProperties = checkPathProperties;
+          moduleOb.checkShapes = checkShapes;
+          moduleOb.completeLayers = completeLayers;
+
+          return moduleOb;
+        }
+        if (!_workerSelf.dataManager) {
+          _workerSelf.dataManager = dataFunctionManager();
+        }
+
+        if (!_workerSelf.assetLoader) {
+          _workerSelf.assetLoader = (function () {
+            function formatResponse(xhr) {
+              // using typeof doubles the time of execution of this method,
+              // so if available, it's better to use the header to validate the type
+              var contentTypeHeader = xhr.getResponseHeader('content-type');
+              if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
+                return xhr.response;
+              }
+              if (xhr.response && typeof xhr.response === 'object') {
+                return xhr.response;
+              } if (xhr.response && typeof xhr.response === 'string') {
+                return JSON.parse(xhr.response);
+              } if (xhr.responseText) {
+                return JSON.parse(xhr.responseText);
+              }
+              return null;
+            }
+
+            function loadAsset(path, fullPath, callback, errorCallback) {
+              var response;
+              var xhr = new XMLHttpRequest();
+              // set responseType after calling open or IE will break.
+              try {
+                // This crashes on Android WebView prior to KitKat
+                xhr.responseType = 'json';
+              } catch (err) {} // eslint-disable-line no-empty
+              xhr.onreadystatechange = function () {
+                if (xhr.readyState === 4) {
+                  if (xhr.status === 200) {
+                    response = formatResponse(xhr);
+                    callback(response);
+                  } else {
+                    try {
+                      response = formatResponse(xhr);
+                      callback(response);
+                    } catch (err) {
+                      if (errorCallback) {
+                        errorCallback(err);
+                      }
+                    }
+                  }
+                }
+              };
+              try {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), path, true);
+              } catch (error) {
+                // Hack to workaround banner validation
+                xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
+              }
+              xhr.send();
+            }
+            return {
+              load: loadAsset,
+            };
+          }());
+        }
+
+        if (e.data.type === 'loadAnimation') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.dataManager.completeData(data);
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        } else if (e.data.type === 'complete') {
+          var animation = e.data.animation;
+          _workerSelf.dataManager.completeData(animation);
+          _workerSelf.postMessage({
+            id: e.data.id,
+            payload: animation,
+            status: 'success',
+          });
+        } else if (e.data.type === 'loadData') {
+          _workerSelf.assetLoader.load(
+            e.data.path,
+            e.data.fullPath,
+            function (data) {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                payload: data,
+                status: 'success',
+              });
+            },
+            function () {
+              _workerSelf.postMessage({
+                id: e.data.id,
+                status: 'error',
+              });
+            }
+          );
+        }
+      });
+
+      workerInstance.onmessage = function (event) {
+        var data = event.data;
+        var id = data.id;
+        var process = processes[id];
+        processes[id] = null;
+        if (data.status === 'success') {
+          process.onComplete(data.payload);
+        } else if (process.onError) {
+          process.onError();
+        }
+      };
+    }
+  }
+
+  function createProcess(onComplete, onError) {
+    _counterId += 1;
+    var id = 'processId_' + _counterId;
+    processes[id] = {
+      onComplete: onComplete,
+      onError: onError,
+    };
+    return id;
+  }
+
+  function loadAnimation(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadAnimation',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function loadData(path, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'loadData',
+      path: path,
+      fullPath: window.location.origin + window.location.pathname,
+      id: processId,
+    });
+  }
+
+  function completeAnimation(anim, onComplete, onError) {
+    setupWorker();
+    var processId = createProcess(onComplete, onError);
+    workerInstance.postMessage({
+      type: 'complete',
+      animation: anim,
+      id: processId,
+    });
+  }
+
+  return {
+    loadAnimation: loadAnimation,
+    loadData: loadData,
+    completeAnimation: completeAnimation,
+  };
+}());
+
+const ImagePreloader = (function () {
+  var proxyImage = (function () {
+    var canvas = createTag('canvas');
+    canvas.width = 1;
+    canvas.height = 1;
+    var ctx = canvas.getContext('2d');
+    ctx.fillStyle = 'rgba(0,0,0,0)';
+    ctx.fillRect(0, 0, 1, 1);
+    return canvas;
+  }());
+
+  function imageLoaded() {
+    this.loadedAssets += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+  function footageLoaded() {
+    this.loadedFootagesCount += 1;
+    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
+      if (this.imagesLoadedCb) {
+        this.imagesLoadedCb(null);
+      }
+    }
+  }
+
+  function getAssetsPath(assetData, assetsPath, originalPath) {
+    var path = '';
+    if (assetData.e) {
+      path = assetData.p;
+    } else if (assetsPath) {
+      var imagePath = assetData.p;
+      if (imagePath.indexOf('images/') !== -1) {
+        imagePath = imagePath.split('/')[1];
+      }
+      path = assetsPath + imagePath;
+    } else {
+      path = originalPath;
+      path += assetData.u ? assetData.u : '';
+      path += assetData.p;
+    }
+    return path;
+  }
+
+  function testImageLoaded(img) {
+    var _count = 0;
+    var intervalId = setInterval(function () {
+      var box = img.getBBox();
+      if (box.width || _count > 500) {
+        this._imageLoaded();
+        clearInterval(intervalId);
+      }
+      _count += 1;
+    }.bind(this), 50);
+  }
+
+  function createImageData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createNS('image');
+    if (isSafari) {
+      this.testImageLoaded(img);
+    } else {
+      img.addEventListener('load', this._imageLoaded, false);
+    }
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
+    if (this._elementHelper.append) {
+      this._elementHelper.append(img);
+    } else {
+      this._elementHelper.appendChild(img);
+    }
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createImgData(assetData) {
+    var path = getAssetsPath(assetData, this.assetsPath, this.path);
+    var img = createTag('img');
+    img.crossOrigin = 'anonymous';
+    img.addEventListener('load', this._imageLoaded, false);
+    img.addEventListener('error', function () {
+      ob.img = proxyImage;
+      this._imageLoaded();
+    }.bind(this), false);
+    img.src = path;
+    var ob = {
+      img: img,
+      assetData: assetData,
+    };
+    return ob;
+  }
+
+  function createFootageData(data) {
+    var ob = {
+      assetData: data,
+    };
+    var path = getAssetsPath(data, this.assetsPath, this.path);
+    dataManager.loadData(path, function (footageData) {
+      ob.img = footageData;
+      this._footageLoaded();
+    }.bind(this), function () {
+      ob.img = {};
+      this._footageLoaded();
+    }.bind(this));
+    return ob;
+  }
+
+  function loadAssets(assets, cb) {
+    this.imagesLoadedCb = cb;
+    var i;
+    var len = assets.length;
+    for (i = 0; i < len; i += 1) {
+      if (!assets[i].layers) {
+        if (!assets[i].t || assets[i].t === 'seq') {
+          this.totalImages += 1;
+          this.images.push(this._createImageData(assets[i]));
+        } else if (assets[i].t === 3) {
+          this.totalFootages += 1;
+          this.images.push(this.createFootageData(assets[i]));
+        }
+      }
+    }
+  }
+
+  function setPath(path) {
+    this.path = path || '';
+  }
+
+  function setAssetsPath(path) {
+    this.assetsPath = path || '';
+  }
+
+  function getAsset(assetData) {
+    var i = 0;
+    var len = this.images.length;
+    while (i < len) {
+      if (this.images[i].assetData === assetData) {
+        return this.images[i].img;
+      }
+      i += 1;
+    }
+    return null;
+  }
+
+  function destroy() {
+    this.imagesLoadedCb = null;
+    this.images.length = 0;
+  }
+
+  function loadedImages() {
+    return this.totalImages === this.loadedAssets;
+  }
+
+  function loadedFootages() {
+    return this.totalFootages === this.loadedFootagesCount;
+  }
+
+  function setCacheType(type, elementHelper) {
+    if (type === 'svg') {
+      this._elementHelper = elementHelper;
+      this._createImageData = this.createImageData.bind(this);
+    } else {
+      this._createImageData = this.createImgData.bind(this);
+    }
+  }
+
+  function ImagePreloaderFactory() {
+    this._imageLoaded = imageLoaded.bind(this);
+    this._footageLoaded = footageLoaded.bind(this);
+    this.testImageLoaded = testImageLoaded.bind(this);
+    this.createFootageData = createFootageData.bind(this);
+    this.assetsPath = '';
+    this.path = '';
+    this.totalImages = 0;
+    this.totalFootages = 0;
+    this.loadedAssets = 0;
+    this.loadedFootagesCount = 0;
+    this.imagesLoadedCb = null;
+    this.images = [];
+  }
+
+  ImagePreloaderFactory.prototype = {
+    loadAssets: loadAssets,
+    setAssetsPath: setAssetsPath,
+    setPath: setPath,
+    loadedImages: loadedImages,
+    loadedFootages: loadedFootages,
+    destroy: destroy,
+    getAsset: getAsset,
+    createImgData: createImgData,
+    createImageData: createImageData,
+    imageLoaded: imageLoaded,
+    footageLoaded: footageLoaded,
+    setCacheType: setCacheType,
+  };
+
+  return ImagePreloaderFactory;
+}());
+
+function BaseEvent() {}
+BaseEvent.prototype = {
+  triggerEvent: function (eventName, args) {
+    if (this._cbs[eventName]) {
+      var callbacks = this._cbs[eventName];
+      for (var i = 0; i < callbacks.length; i += 1) {
+        callbacks[i](args);
+      }
+    }
+  },
+  addEventListener: function (eventName, callback) {
+    if (!this._cbs[eventName]) {
+      this._cbs[eventName] = [];
+    }
+    this._cbs[eventName].push(callback);
+
+    return function () {
+      this.removeEventListener(eventName, callback);
+    }.bind(this);
+  },
+  removeEventListener: function (eventName, callback) {
+    if (!callback) {
+      this._cbs[eventName] = null;
+    } else if (this._cbs[eventName]) {
+      var i = 0;
+      var len = this._cbs[eventName].length;
+      while (i < len) {
+        if (this._cbs[eventName][i] === callback) {
+          this._cbs[eventName].splice(i, 1);
+          i -= 1;
+          len -= 1;
+        }
+        i += 1;
+      }
+      if (!this._cbs[eventName].length) {
+        this._cbs[eventName] = null;
+      }
+    }
+  },
+};
+
+const markerParser = (
+
+  function () {
+    function parsePayloadLines(payload) {
+      var lines = payload.split('\r\n');
+      var keys = {};
+      var line;
+      var keysCount = 0;
+      for (var i = 0; i < lines.length; i += 1) {
+        line = lines[i].split(':');
+        if (line.length === 2) {
+          keys[line[0]] = line[1].trim();
+          keysCount += 1;
+        }
+      }
+      if (keysCount === 0) {
+        throw new Error();
+      }
+      return keys;
+    }
+
+    return function (_markers) {
+      var markers = [];
+      for (var i = 0; i < _markers.length; i += 1) {
+        var _marker = _markers[i];
+        var markerData = {
+          time: _marker.tm,
+          duration: _marker.dr,
+        };
+        try {
+          markerData.payload = JSON.parse(_markers[i].cm);
+        } catch (_) {
+          try {
+            markerData.payload = parsePayloadLines(_markers[i].cm);
+          } catch (__) {
+            markerData.payload = {
+              name: _markers[i].cm,
+            };
+          }
+        }
+        markers.push(markerData);
+      }
+      return markers;
+    };
+  }());
+
+const ProjectInterface = (function () {
+  function registerComposition(comp) {
+    this.compositions.push(comp);
+  }
+
+  return function () {
+    function _thisProjectFunction(name) {
+      var i = 0;
+      var len = this.compositions.length;
+      while (i < len) {
+        if (this.compositions[i].data && this.compositions[i].data.nm === name) {
+          if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
+            this.compositions[i].prepareFrame(this.currentFrame);
+          }
+          return this.compositions[i].compInterface;
+        }
+        i += 1;
+      }
+      return null;
+    }
+
+    _thisProjectFunction.compositions = [];
+    _thisProjectFunction.currentFrame = 0;
+
+    _thisProjectFunction.registerComposition = registerComposition;
+
+    return _thisProjectFunction;
+  };
+}());
+
+const renderers = {};
+
+const registerRenderer = (key, value) => {
+  renderers[key] = value;
+};
+
+function getRenderer(key) {
+  return renderers[key];
+}
+
+function getRegisteredRenderer() {
+  // Returns canvas by default for compatibility
+  if (renderers.canvas) {
+    return 'canvas';
+  }
+  // Returns any renderer that is registered
+  for (const key in renderers) {
+    if (renderers[key]) {
+      return key;
+    }
+  }
+  return '';
+}
+
+const AnimationItem = function () {
+  this._cbs = [];
+  this.name = '';
+  this.path = '';
+  this.isLoaded = false;
+  this.currentFrame = 0;
+  this.currentRawFrame = 0;
+  this.firstFrame = 0;
+  this.totalFrames = 0;
+  this.frameRate = 0;
+  this.frameMult = 0;
+  this.playSpeed = 1;
+  this.playDirection = 1;
+  this.playCount = 0;
+  this.animationData = {};
+  this.assets = [];
+  this.isPaused = true;
+  this.autoplay = false;
+  this.loop = true;
+  this.renderer = null;
+  this.animationID = createElementID();
+  this.assetsPath = '';
+  this.timeCompleted = 0;
+  this.segmentPos = 0;
+  this.isSubframeEnabled = getSubframeEnabled();
+  this.segments = [];
+  this._idle = true;
+  this._completedLoop = false;
+  this.projectInterface = ProjectInterface();
+  this.imagePreloader = new ImagePreloader();
+  this.audioController = audioControllerFactory();
+  this.markers = [];
+  this.configAnimation = this.configAnimation.bind(this);
+  this.onSetupError = this.onSetupError.bind(this);
+  this.onSegmentComplete = this.onSegmentComplete.bind(this);
+  this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
+  this.expressionsPlugin = getExpressionsPlugin();
+};
+
+extendPrototype([BaseEvent], AnimationItem);
+
+AnimationItem.prototype.setParams = function (params) {
+  if (params.wrapper || params.container) {
+    this.wrapper = params.wrapper || params.container;
+  }
+  var animType = 'svg';
+  if (params.animType) {
+    animType = params.animType;
+  } else if (params.renderer) {
+    animType = params.renderer;
+  }
+  const RendererClass = getRenderer(animType);
+  this.renderer = new RendererClass(this, params.rendererSettings);
+  this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
+  this.renderer.setProjectInterface(this.projectInterface);
+  this.animType = animType;
+  if (params.loop === ''
+        || params.loop === null
+        || params.loop === undefined
+        || params.loop === true) {
+    this.loop = true;
+  } else if (params.loop === false) {
+    this.loop = false;
+  } else {
+    this.loop = parseInt(params.loop, 10);
+  }
+  this.autoplay = 'autoplay' in params ? params.autoplay : true;
+  this.name = params.name ? params.name : '';
+  this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
+  this.assetsPath = params.assetsPath;
+  this.initialSegment = params.initialSegment;
+  if (params.audioFactory) {
+    this.audioController.setAudioFactory(params.audioFactory);
+  }
+  if (params.animationData) {
+    this.setupAnimation(params.animationData);
+  } else if (params.path) {
+    if (params.path.lastIndexOf('\\') !== -1) {
+      this.path = params.path.substr(0, params.path.lastIndexOf('\\') + 1);
+    } else {
+      this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
+    }
+    this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
+    this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
+    dataManager.loadAnimation(
+      params.path,
+      this.configAnimation,
+      this.onSetupError
+    );
+  }
+};
+
+AnimationItem.prototype.onSetupError = function () {
+  this.trigger('data_failed');
+};
+
+AnimationItem.prototype.setupAnimation = function (data) {
+  dataManager.completeAnimation(
+    data,
+    this.configAnimation
+  );
+};
+
+AnimationItem.prototype.setData = function (wrapper, animationData) {
+  if (animationData) {
+    if (typeof animationData !== 'object') {
+      animationData = JSON.parse(animationData);
+    }
+  }
+  var params = {
+    wrapper: wrapper,
+    animationData: animationData,
+  };
+  var wrapperAttributes = wrapper.attributes;
+
+  params.path = wrapperAttributes.getNamedItem('data-animation-path') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-animation-path').value
+    : wrapperAttributes.getNamedItem('data-bm-path') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-path').value
+      : wrapperAttributes.getNamedItem('bm-path')
+        ? wrapperAttributes.getNamedItem('bm-path').value
+        : '';
+  params.animType = wrapperAttributes.getNamedItem('data-anim-type') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-type').value
+    : wrapperAttributes.getNamedItem('data-bm-type') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-type').value
+      : wrapperAttributes.getNamedItem('bm-type') // eslint-disable-line no-nested-ternary
+        ? wrapperAttributes.getNamedItem('bm-type').value
+        : wrapperAttributes.getNamedItem('data-bm-renderer') // eslint-disable-line no-nested-ternary
+          ? wrapperAttributes.getNamedItem('data-bm-renderer').value
+          : wrapperAttributes.getNamedItem('bm-renderer')
+            ? wrapperAttributes.getNamedItem('bm-renderer').value
+            : getRegisteredRenderer() || 'canvas';
+
+  var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-loop').value
+    : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-loop').value
+      : wrapperAttributes.getNamedItem('bm-loop')
+        ? wrapperAttributes.getNamedItem('bm-loop').value
+        : '';
+  if (loop === 'false') {
+    params.loop = false;
+  } else if (loop === 'true') {
+    params.loop = true;
+  } else if (loop !== '') {
+    params.loop = parseInt(loop, 10);
+  }
+  var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-autoplay').value
+    : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-autoplay').value
+      : wrapperAttributes.getNamedItem('bm-autoplay')
+        ? wrapperAttributes.getNamedItem('bm-autoplay').value
+        : true;
+  params.autoplay = autoplay !== 'false';
+
+  params.name = wrapperAttributes.getNamedItem('data-name') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-name').value
+    : wrapperAttributes.getNamedItem('data-bm-name') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-name').value
+      : wrapperAttributes.getNamedItem('bm-name')
+        ? wrapperAttributes.getNamedItem('bm-name').value
+        : '';
+  var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
+    ? wrapperAttributes.getNamedItem('data-anim-prerender').value
+    : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
+      ? wrapperAttributes.getNamedItem('data-bm-prerender').value
+      : wrapperAttributes.getNamedItem('bm-prerender')
+        ? wrapperAttributes.getNamedItem('bm-prerender').value
+        : '';
+
+  if (prerender === 'false') {
+    params.prerender = false;
+  }
+  if (!params.path) {
+    this.trigger('destroy');
+  } else {
+    this.setParams(params);
+  }
+};
+
+AnimationItem.prototype.includeLayers = function (data) {
+  if (data.op > this.animationData.op) {
+    this.animationData.op = data.op;
+    this.totalFrames = Math.floor(data.op - this.animationData.ip);
+  }
+  var layers = this.animationData.layers;
+  var i;
+  var len = layers.length;
+  var newLayers = data.layers;
+  var j;
+  var jLen = newLayers.length;
+  for (j = 0; j < jLen; j += 1) {
+    i = 0;
+    while (i < len) {
+      if (layers[i].id === newLayers[j].id) {
+        layers[i] = newLayers[j];
+        break;
+      }
+      i += 1;
+    }
+  }
+  if (data.chars || data.fonts) {
+    this.renderer.globalData.fontManager.addChars(data.chars);
+    this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
+  }
+  if (data.assets) {
+    len = data.assets.length;
+    for (i = 0; i < len; i += 1) {
+      this.animationData.assets.push(data.assets[i]);
+    }
+  }
+  this.animationData.__complete = false;
+  dataManager.completeAnimation(
+    this.animationData,
+    this.onSegmentComplete
+  );
+};
+
+AnimationItem.prototype.onSegmentComplete = function (data) {
+  this.animationData = data;
+  var expressionsPlugin = getExpressionsPlugin();
+  if (expressionsPlugin) {
+    expressionsPlugin.initExpressions(this);
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.loadNextSegment = function () {
+  var segments = this.animationData.segments;
+  if (!segments || segments.length === 0 || !this.autoloadSegments) {
+    this.trigger('data_ready');
+    this.timeCompleted = this.totalFrames;
+    return;
+  }
+  var segment = segments.shift();
+  this.timeCompleted = segment.time * this.frameRate;
+  var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
+  this.segmentPos += 1;
+  dataManager.loadData(segmentPath, this.includeLayers.bind(this), function () {
+    this.trigger('data_failed');
+  }.bind(this));
+};
+
+AnimationItem.prototype.loadSegments = function () {
+  var segments = this.animationData.segments;
+  if (!segments) {
+    this.timeCompleted = this.totalFrames;
+  }
+  this.loadNextSegment();
+};
+
+AnimationItem.prototype.imagesLoaded = function () {
+  this.trigger('loaded_images');
+  this.checkLoaded();
+};
+
+AnimationItem.prototype.preloadImages = function () {
+  this.imagePreloader.setAssetsPath(this.assetsPath);
+  this.imagePreloader.setPath(this.path);
+  this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
+};
+
+AnimationItem.prototype.configAnimation = function (animData) {
+  if (!this.renderer) {
+    return;
+  }
+  try {
+    this.animationData = animData;
+    if (this.initialSegment) {
+      this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
+      this.firstFrame = Math.round(this.initialSegment[0]);
+    } else {
+      this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
+      this.firstFrame = Math.round(this.animationData.ip);
+    }
+    this.renderer.configAnimation(animData);
+    if (!animData.assets) {
+      animData.assets = [];
+    }
+
+    this.assets = this.animationData.assets;
+    this.frameRate = this.animationData.fr;
+    this.frameMult = this.animationData.fr / 1000;
+    this.renderer.searchExtraCompositions(animData.assets);
+    this.markers = markerParser(animData.markers || []);
+    this.trigger('config_ready');
+    this.preloadImages();
+    this.loadSegments();
+    this.updaFrameModifier();
+    this.waitForFontsLoaded();
+    if (this.isPaused) {
+      this.audioController.pause();
+    }
+  } catch (error) {
+    this.triggerConfigError(error);
+  }
+};
+
+AnimationItem.prototype.waitForFontsLoaded = function () {
+  if (!this.renderer) {
+    return;
+  }
+  if (this.renderer.globalData.fontManager.isLoaded) {
+    this.checkLoaded();
+  } else {
+    setTimeout(this.waitForFontsLoaded.bind(this), 20);
+  }
+};
+
+AnimationItem.prototype.checkLoaded = function () {
+  if (!this.isLoaded
+        && this.renderer.globalData.fontManager.isLoaded
+        && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas')
+        && (this.imagePreloader.loadedFootages())
+  ) {
+    this.isLoaded = true;
+    var expressionsPlugin = getExpressionsPlugin();
+    if (expressionsPlugin) {
+      expressionsPlugin.initExpressions(this);
+    }
+    this.renderer.initItems();
+    setTimeout(function () {
+      this.trigger('DOMLoaded');
+    }.bind(this), 0);
+    this.gotoFrame();
+    if (this.autoplay) {
+      this.play();
+    }
+  }
+};
+
+AnimationItem.prototype.resize = function (width, height) {
+  // Adding this validation for backwards compatibility in case an event object was being passed down
+  var _width = typeof width === 'number' ? width : undefined;
+  var _height = typeof height === 'number' ? height : undefined;
+  this.renderer.updateContainerSize(_width, _height);
+};
+
+AnimationItem.prototype.setSubframe = function (flag) {
+  this.isSubframeEnabled = !!flag;
+};
+
+AnimationItem.prototype.gotoFrame = function () {
+  this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
+
+  if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
+    this.currentFrame = this.timeCompleted;
+  }
+  this.trigger('enterFrame');
+  this.renderFrame();
+  this.trigger('drawnFrame');
+};
+
+AnimationItem.prototype.renderFrame = function () {
+  if (this.isLoaded === false || !this.renderer) {
+    return;
+  }
+  try {
+    if (this.expressionsPlugin) {
+      this.expressionsPlugin.resetFrame();
+    }
+    this.renderer.renderFrame(this.currentFrame + this.firstFrame);
+  } catch (error) {
+    this.triggerRenderFrameError(error);
+  }
+};
+
+AnimationItem.prototype.play = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.isPaused = false;
+    this.trigger('_play');
+    this.audioController.resume();
+    if (this._idle) {
+      this._idle = false;
+      this.trigger('_active');
+    }
+  }
+};
+
+AnimationItem.prototype.pause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === false) {
+    this.isPaused = true;
+    this.trigger('_pause');
+    this._idle = true;
+    this.trigger('_idle');
+    this.audioController.pause();
+  }
+};
+
+AnimationItem.prototype.togglePause = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  if (this.isPaused === true) {
+    this.play();
+  } else {
+    this.pause();
+  }
+};
+
+AnimationItem.prototype.stop = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.pause();
+  this.playCount = 0;
+  this._completedLoop = false;
+  this.setCurrentRawFrameValue(0);
+};
+
+AnimationItem.prototype.getMarkerData = function (markerName) {
+  var marker;
+  for (var i = 0; i < this.markers.length; i += 1) {
+    marker = this.markers[i];
+    if (marker.payload && marker.payload.name === markerName) {
+      return marker;
+    }
+  }
+  return null;
+};
+
+AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      this.goToAndStop(marker.time, true);
+    }
+  } else if (isFrame) {
+    this.setCurrentRawFrameValue(value);
+  } else {
+    this.setCurrentRawFrameValue(value * this.frameModifier);
+  }
+  this.pause();
+};
+
+AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  var numValue = Number(value);
+  if (isNaN(numValue)) {
+    var marker = this.getMarkerData(value);
+    if (marker) {
+      if (!marker.duration) {
+        this.goToAndStop(marker.time, true);
+      } else {
+        this.playSegments([marker.time, marker.time + marker.duration], true);
+      }
+    }
+  } else {
+    this.goToAndStop(numValue, isFrame, name);
+  }
+  this.play();
+};
+
+AnimationItem.prototype.advanceTime = function (value) {
+  if (this.isPaused === true || this.isLoaded === false) {
+    return;
+  }
+  var nextValue = this.currentRawFrame + value * this.frameModifier;
+  var _isComplete = false;
+  // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+  // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
+  if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
+    if (!this.loop || this.playCount === this.loop) {
+      if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
+        _isComplete = true;
+        nextValue = this.totalFrames - 1;
+      }
+    } else if (nextValue >= this.totalFrames) {
+      this.playCount += 1;
+      if (!this.checkSegments(nextValue % this.totalFrames)) {
+        this.setCurrentRawFrameValue(nextValue % this.totalFrames);
+        this._completedLoop = true;
+        this.trigger('loopComplete');
+      }
+    } else {
+      this.setCurrentRawFrameValue(nextValue);
+    }
+  } else if (nextValue < 0) {
+    if (!this.checkSegments(nextValue % this.totalFrames)) {
+      if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) { // eslint-disable-line no-plusplus
+        this.setCurrentRawFrameValue(this.totalFrames + (nextValue % this.totalFrames));
+        if (!this._completedLoop) {
+          this._completedLoop = true;
+        } else {
+          this.trigger('loopComplete');
+        }
+      } else {
+        _isComplete = true;
+        nextValue = 0;
+      }
+    }
+  } else {
+    this.setCurrentRawFrameValue(nextValue);
+  }
+  if (_isComplete) {
+    this.setCurrentRawFrameValue(nextValue);
+    this.pause();
+    this.trigger('complete');
+  }
+};
+
+AnimationItem.prototype.adjustSegment = function (arr, offset) {
+  this.playCount = 0;
+  if (arr[1] < arr[0]) {
+    if (this.frameModifier > 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(-1);
+      }
+    }
+    this.totalFrames = arr[0] - arr[1];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[1];
+    this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset);
+  } else if (arr[1] > arr[0]) {
+    if (this.frameModifier < 0) {
+      if (this.playSpeed < 0) {
+        this.setSpeed(-this.playSpeed);
+      } else {
+        this.setDirection(1);
+      }
+    }
+    this.totalFrames = arr[1] - arr[0];
+    this.timeCompleted = this.totalFrames;
+    this.firstFrame = arr[0];
+    this.setCurrentRawFrameValue(0.001 + offset);
+  }
+  this.trigger('segmentStart');
+};
+AnimationItem.prototype.setSegment = function (init, end) {
+  var pendingFrame = -1;
+  if (this.isPaused) {
+    if (this.currentRawFrame + this.firstFrame < init) {
+      pendingFrame = init;
+    } else if (this.currentRawFrame + this.firstFrame > end) {
+      pendingFrame = end - init;
+    }
+  }
+
+  this.firstFrame = init;
+  this.totalFrames = end - init;
+  this.timeCompleted = this.totalFrames;
+  if (pendingFrame !== -1) {
+    this.goToAndStop(pendingFrame, true);
+  }
+};
+
+AnimationItem.prototype.playSegments = function (arr, forceFlag) {
+  if (forceFlag) {
+    this.segments.length = 0;
+  }
+  if (typeof arr[0] === 'object') {
+    var i;
+    var len = arr.length;
+    for (i = 0; i < len; i += 1) {
+      this.segments.push(arr[i]);
+    }
+  } else {
+    this.segments.push(arr);
+  }
+  if (this.segments.length && forceFlag) {
+    this.adjustSegment(this.segments.shift(), 0);
+  }
+  if (this.isPaused) {
+    this.play();
+  }
+};
+
+AnimationItem.prototype.resetSegments = function (forceFlag) {
+  this.segments.length = 0;
+  this.segments.push([this.animationData.ip, this.animationData.op]);
+  if (forceFlag) {
+    this.checkSegments(0);
+  }
+};
+AnimationItem.prototype.checkSegments = function (offset) {
+  if (this.segments.length) {
+    this.adjustSegment(this.segments.shift(), offset);
+    return true;
+  }
+  return false;
+};
+
+AnimationItem.prototype.destroy = function (name) {
+  if ((name && this.name !== name) || !this.renderer) {
+    return;
+  }
+  this.renderer.destroy();
+  this.imagePreloader.destroy();
+  this.trigger('destroy');
+  this._cbs = null;
+  this.onEnterFrame = null;
+  this.onLoopComplete = null;
+  this.onComplete = null;
+  this.onSegmentStart = null;
+  this.onDestroy = null;
+  this.renderer = null;
+  this.expressionsPlugin = null;
+  this.imagePreloader = null;
+  this.projectInterface = null;
+};
+
+AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
+  this.currentRawFrame = value;
+  this.gotoFrame();
+};
+
+AnimationItem.prototype.setSpeed = function (val) {
+  this.playSpeed = val;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setDirection = function (val) {
+  this.playDirection = val < 0 ? -1 : 1;
+  this.updaFrameModifier();
+};
+
+AnimationItem.prototype.setLoop = function (isLooping) {
+  this.loop = isLooping;
+};
+
+AnimationItem.prototype.setVolume = function (val, name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.setVolume(val);
+};
+
+AnimationItem.prototype.getVolume = function () {
+  return this.audioController.getVolume();
+};
+
+AnimationItem.prototype.mute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.mute();
+};
+
+AnimationItem.prototype.unmute = function (name) {
+  if (name && this.name !== name) {
+    return;
+  }
+  this.audioController.unmute();
+};
+
+AnimationItem.prototype.updaFrameModifier = function () {
+  this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
+  this.audioController.setRate(this.playSpeed * this.playDirection);
+};
+
+AnimationItem.prototype.getPath = function () {
+  return this.path;
+};
+
+AnimationItem.prototype.getAssetsPath = function (assetData) {
+  var path = '';
+  if (assetData.e) {
+    path = assetData.p;
+  } else if (this.assetsPath) {
+    var imagePath = assetData.p;
+    if (imagePath.indexOf('images/') !== -1) {
+      imagePath = imagePath.split('/')[1];
+    }
+    path = this.assetsPath + imagePath;
+  } else {
+    path = this.path;
+    path += assetData.u ? assetData.u : '';
+    path += assetData.p;
+  }
+  return path;
+};
+
+AnimationItem.prototype.getAssetData = function (id) {
+  var i = 0;
+  var len = this.assets.length;
+  while (i < len) {
+    if (id === this.assets[i].id) {
+      return this.assets[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+AnimationItem.prototype.hide = function () {
+  this.renderer.hide();
+};
+
+AnimationItem.prototype.show = function () {
+  this.renderer.show();
+};
+
+AnimationItem.prototype.getDuration = function (isFrame) {
+  return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
+};
+
+AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
+  try {
+    var element = this.renderer.getElementByPath(path);
+    element.updateDocumentData(documentData, index);
+  } catch (error) {
+    // TODO: decide how to handle catch case
+  }
+};
+
+AnimationItem.prototype.trigger = function (name) {
+  if (this._cbs && this._cbs[name]) {
+    switch (name) {
+      case 'enterFrame':
+        this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
+        break;
+      case 'drawnFrame':
+        this.drawnFrameEvent.currentTime = this.currentFrame;
+        this.drawnFrameEvent.totalTime = this.totalFrames;
+        this.drawnFrameEvent.direction = this.frameModifier;
+        this.triggerEvent(name, this.drawnFrameEvent);
+        break;
+      case 'loopComplete':
+        this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+        break;
+      case 'complete':
+        this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
+        break;
+      case 'segmentStart':
+        this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+        break;
+      case 'destroy':
+        this.triggerEvent(name, new BMDestroyEvent(name, this));
+        break;
+      default:
+        this.triggerEvent(name);
+    }
+  }
+  if (name === 'enterFrame' && this.onEnterFrame) {
+    this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
+  }
+  if (name === 'loopComplete' && this.onLoopComplete) {
+    this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
+  }
+  if (name === 'complete' && this.onComplete) {
+    this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
+  }
+  if (name === 'segmentStart' && this.onSegmentStart) {
+    this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
+  }
+  if (name === 'destroy' && this.onDestroy) {
+    this.onDestroy.call(this, new BMDestroyEvent(name, this));
+  }
+};
+
+AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
+  var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+AnimationItem.prototype.triggerConfigError = function (nativeError) {
+  var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
+  this.triggerEvent('error', error);
+
+  if (this.onError) {
+    this.onError.call(this, error);
+  }
+};
+
+const animationManager = (function () {
+  var moduleOb = {};
+  var registeredAnimations = [];
+  var initTime = 0;
+  var len = 0;
+  var playingAnimationsNum = 0;
+  var _stopped = true;
+  var _isFrozen = false;
+
+  function removeElement(ev) {
+    var i = 0;
+    var animItem = ev.target;
+    while (i < len) {
+      if (registeredAnimations[i].animation === animItem) {
+        registeredAnimations.splice(i, 1);
+        i -= 1;
+        len -= 1;
+        if (!animItem.isPaused) {
+          subtractPlayingCount();
+        }
+      }
+      i += 1;
+    }
+  }
+
+  function registerAnimation(element, animationData) {
+    if (!element) {
+      return null;
+    }
+    var i = 0;
+    while (i < len) {
+      if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
+        return registeredAnimations[i].animation;
+      }
+      i += 1;
+    }
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, element);
+    animItem.setData(element, animationData);
+    return animItem;
+  }
+
+  function getRegisteredAnimations() {
+    var i;
+    var lenAnims = registeredAnimations.length;
+    var animations = [];
+    for (i = 0; i < lenAnims; i += 1) {
+      animations.push(registeredAnimations[i].animation);
+    }
+    return animations;
+  }
+
+  function addPlayingCount() {
+    playingAnimationsNum += 1;
+    activate();
+  }
+
+  function subtractPlayingCount() {
+    playingAnimationsNum -= 1;
+  }
+
+  function setupAnimation(animItem, element) {
+    animItem.addEventListener('destroy', removeElement);
+    animItem.addEventListener('_active', addPlayingCount);
+    animItem.addEventListener('_idle', subtractPlayingCount);
+    registeredAnimations.push({ elem: element, animation: animItem });
+    len += 1;
+  }
+
+  function loadAnimation(params) {
+    var animItem = new AnimationItem();
+    setupAnimation(animItem, null);
+    animItem.setParams(params);
+    return animItem;
+  }
+
+  function setSpeed(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setSpeed(val, animation);
+    }
+  }
+
+  function setDirection(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setDirection(val, animation);
+    }
+  }
+
+  function play(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.play(animation);
+    }
+  }
+  function resume(nowTime) {
+    var elapsedTime = nowTime - initTime;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.advanceTime(elapsedTime);
+    }
+    initTime = nowTime;
+    if (playingAnimationsNum && !_isFrozen) {
+      window.requestAnimationFrame(resume);
+    } else {
+      _stopped = true;
+    }
+  }
+
+  function first(nowTime) {
+    initTime = nowTime;
+    window.requestAnimationFrame(resume);
+  }
+
+  function pause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.pause(animation);
+    }
+  }
+
+  function goToAndStop(value, isFrame, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
+    }
+  }
+
+  function stop(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.stop(animation);
+    }
+  }
+
+  function togglePause(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.togglePause(animation);
+    }
+  }
+
+  function destroy(animation) {
+    var i;
+    for (i = (len - 1); i >= 0; i -= 1) {
+      registeredAnimations[i].animation.destroy(animation);
+    }
+  }
+
+  function searchAnimations(animationData, standalone, renderer) {
+    var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')),
+      [].slice.call(document.getElementsByClassName('bodymovin')));
+    var i;
+    var lenAnims = animElements.length;
+    for (i = 0; i < lenAnims; i += 1) {
+      if (renderer) {
+        animElements[i].setAttribute('data-bm-type', renderer);
+      }
+      registerAnimation(animElements[i], animationData);
+    }
+    if (standalone && lenAnims === 0) {
+      if (!renderer) {
+        renderer = 'svg';
+      }
+      var body = document.getElementsByTagName('body')[0];
+      body.innerText = '';
+      var div = createTag('div');
+      div.style.width = '100%';
+      div.style.height = '100%';
+      div.setAttribute('data-bm-type', renderer);
+      body.appendChild(div);
+      registerAnimation(div, animationData);
+    }
+  }
+
+  function resize() {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.resize();
+    }
+  }
+
+  function activate() {
+    if (!_isFrozen && playingAnimationsNum) {
+      if (_stopped) {
+        window.requestAnimationFrame(first);
+        _stopped = false;
+      }
+    }
+  }
+
+  function freeze() {
+    _isFrozen = true;
+  }
+
+  function unfreeze() {
+    _isFrozen = false;
+    activate();
+  }
+
+  function setVolume(val, animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.setVolume(val, animation);
+    }
+  }
+
+  function mute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.mute(animation);
+    }
+  }
+
+  function unmute(animation) {
+    var i;
+    for (i = 0; i < len; i += 1) {
+      registeredAnimations[i].animation.unmute(animation);
+    }
+  }
+
+  moduleOb.registerAnimation = registerAnimation;
+  moduleOb.loadAnimation = loadAnimation;
+  moduleOb.setSpeed = setSpeed;
+  moduleOb.setDirection = setDirection;
+  moduleOb.play = play;
+  moduleOb.pause = pause;
+  moduleOb.stop = stop;
+  moduleOb.togglePause = togglePause;
+  moduleOb.searchAnimations = searchAnimations;
+  moduleOb.resize = resize;
+  // moduleOb.start = start;
+  moduleOb.goToAndStop = goToAndStop;
+  moduleOb.destroy = destroy;
+  moduleOb.freeze = freeze;
+  moduleOb.unfreeze = unfreeze;
+  moduleOb.setVolume = setVolume;
+  moduleOb.mute = mute;
+  moduleOb.unmute = unmute;
+  moduleOb.getRegisteredAnimations = getRegisteredAnimations;
+  return moduleOb;
+}());
+
+/* eslint-disable */
+const BezierFactory = (function () {
+  /**
+     * BezierEasing - use bezier curve for transition easing function
+     * by Gaëtan Renaudeau 2014 - 2015 – MIT License
+     *
+     * Credits: is based on Firefox's nsSMILKeySpline.cpp
+     * Usage:
+     * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
+     * spline.get(x) => returns the easing value | x must be in [0, 1] range
+     *
+     */
+
+  var ob = {};
+  ob.getBezierEasing = getBezierEasing;
+  var beziers = {};
+
+  function getBezierEasing(a, b, c, d, nm) {
+    var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
+    if (beziers[str]) {
+      return beziers[str];
+    }
+    var bezEasing = new BezierEasing([a, b, c, d]);
+    beziers[str] = bezEasing;
+    return bezEasing;
+  }
+
+  // These values are established by empiricism with tests (tradeoff: performance VS precision)
+  var NEWTON_ITERATIONS = 4;
+  var NEWTON_MIN_SLOPE = 0.001;
+  var SUBDIVISION_PRECISION = 0.0000001;
+  var SUBDIVISION_MAX_ITERATIONS = 10;
+
+  var kSplineTableSize = 11;
+  var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
+
+  var float32ArraySupported = typeof Float32Array === 'function';
+
+  function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
+  function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
+  function C(aA1) { return 3.0 * aA1; }
+
+  // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+  function calcBezier(aT, aA1, aA2) {
+    return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
+  }
+
+  // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+  function getSlope(aT, aA1, aA2) {
+    return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
+  }
+
+  function binarySubdivide(aX, aA, aB, mX1, mX2) {
+    var currentX,
+      currentT,
+      i = 0;
+    do {
+      currentT = aA + (aB - aA) / 2.0;
+      currentX = calcBezier(currentT, mX1, mX2) - aX;
+      if (currentX > 0.0) {
+        aB = currentT;
+      } else {
+        aA = currentT;
+      }
+    } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
+    return currentT;
+  }
+
+  function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
+    for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
+      var currentSlope = getSlope(aGuessT, mX1, mX2);
+      if (currentSlope === 0.0) return aGuessT;
+      var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
+      aGuessT -= currentX / currentSlope;
+    }
+    return aGuessT;
+  }
+
+  /**
+     * points is an array of [ mX1, mY1, mX2, mY2 ]
+     */
+  function BezierEasing(points) {
+    this._p = points;
+    this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
+    this._precomputed = false;
+
+    this.get = this.get.bind(this);
+  }
+
+  BezierEasing.prototype = {
+
+    get: function (x) {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      if (!this._precomputed) this._precompute();
+      if (mX1 === mY1 && mX2 === mY2) return x; // linear
+      // Because JavaScript number are imprecise, we should guarantee the extremes are right.
+      if (x === 0) return 0;
+      if (x === 1) return 1;
+      return calcBezier(this._getTForX(x), mY1, mY2);
+    },
+
+    // Private part
+
+    _precompute: function () {
+      var mX1 = this._p[0],
+        mY1 = this._p[1],
+        mX2 = this._p[2],
+        mY2 = this._p[3];
+      this._precomputed = true;
+      if (mX1 !== mY1 || mX2 !== mY2) { this._calcSampleValues(); }
+    },
+
+    _calcSampleValues: function () {
+      var mX1 = this._p[0],
+        mX2 = this._p[2];
+      for (var i = 0; i < kSplineTableSize; ++i) {
+        this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
+      }
+    },
+
+    /**
+         * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
+         */
+    _getTForX: function (aX) {
+      var mX1 = this._p[0],
+        mX2 = this._p[2],
+        mSampleValues = this._mSampleValues;
+
+      var intervalStart = 0.0;
+      var currentSample = 1;
+      var lastSample = kSplineTableSize - 1;
+
+      for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
+        intervalStart += kSampleStepSize;
+      }
+      --currentSample;
+
+      // Interpolate to provide an initial guess for t
+      var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
+      var guessForT = intervalStart + dist * kSampleStepSize;
+
+      var initialSlope = getSlope(guessForT, mX1, mX2);
+      if (initialSlope >= NEWTON_MIN_SLOPE) {
+        return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
+      } if (initialSlope === 0.0) {
+        return guessForT;
+      }
+      return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
+    },
+  };
+
+  return ob;
+}());
+
+const pooling = (function () {
+  function double(arr) {
+    return arr.concat(createSizedArray(arr.length));
+  }
+
+  return {
+    double: double,
+  };
+}());
+
+const poolFactory = (function () {
+  return function (initialLength, _create, _release) {
+    var _length = 0;
+    var _maxLength = initialLength;
+    var pool = createSizedArray(_maxLength);
+
+    var ob = {
+      newElement: newElement,
+      release: release,
+    };
+
+    function newElement() {
+      var element;
+      if (_length) {
+        _length -= 1;
+        element = pool[_length];
+      } else {
+        element = _create();
+      }
+      return element;
+    }
+
+    function release(element) {
+      if (_length === _maxLength) {
+        pool = pooling.double(pool);
+        _maxLength *= 2;
+      }
+      if (_release) {
+        _release(element);
+      }
+      pool[_length] = element;
+      _length += 1;
+    }
+
+    return ob;
+  };
+}());
+
+const bezierLengthPool = (function () {
+  function create() {
+    return {
+      addedLength: 0,
+      percents: createTypedArray('float32', getDefaultCurveSegments()),
+      lengths: createTypedArray('float32', getDefaultCurveSegments()),
+    };
+  }
+  return poolFactory(8, create);
+}());
+
+const segmentsLengthPool = (function () {
+  function create() {
+    return {
+      lengths: [],
+      totalLength: 0,
+    };
+  }
+
+  function release(element) {
+    var i;
+    var len = element.lengths.length;
+    for (i = 0; i < len; i += 1) {
+      bezierLengthPool.release(element.lengths[i]);
+    }
+    element.lengths.length = 0;
+  }
+
+  return poolFactory(8, create, release);
+}());
+
+function bezFunction() {
+  var math = Math;
+
+  function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
+    var det1 = (x1 * y2) + (y1 * x3) + (x2 * y3) - (x3 * y2) - (y3 * x1) - (x2 * y1);
+    return det1 > -0.001 && det1 < 0.001;
+  }
+
+  function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
+    if (z1 === 0 && z2 === 0 && z3 === 0) {
+      return pointOnLine2D(x1, y1, x2, y2, x3, y3);
+    }
+    var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
+    var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
+    var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
+    var diffDist;
+    if (dist1 > dist2) {
+      if (dist1 > dist3) {
+        diffDist = dist1 - dist2 - dist3;
+      } else {
+        diffDist = dist3 - dist2 - dist1;
+      }
+    } else if (dist3 > dist2) {
+      diffDist = dist3 - dist2 - dist1;
+    } else {
+      diffDist = dist2 - dist1 - dist3;
+    }
+    return diffDist > -0.0001 && diffDist < 0.0001;
+  }
+
+  var getBezierLength = (function () {
+    return function (pt1, pt2, pt3, pt4) {
+      var curveSegments = getDefaultCurveSegments();
+      var k;
+      var i;
+      var len;
+      var ptCoord;
+      var perc;
+      var addedLength = 0;
+      var ptDistance;
+      var point = [];
+      var lastPoint = [];
+      var lengthData = bezierLengthPool.newElement();
+      len = pt3.length;
+      for (k = 0; k < curveSegments; k += 1) {
+        perc = k / (curveSegments - 1);
+        ptDistance = 0;
+        for (i = 0; i < len; i += 1) {
+          ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
+          point[i] = ptCoord;
+          if (lastPoint[i] !== null) {
+            ptDistance += bmPow(point[i] - lastPoint[i], 2);
+          }
+          lastPoint[i] = point[i];
+        }
+        if (ptDistance) {
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+        }
+        lengthData.percents[k] = perc;
+        lengthData.lengths[k] = addedLength;
+      }
+      lengthData.addedLength = addedLength;
+      return lengthData;
+    };
+  }());
+
+  function getSegmentsLength(shapeData) {
+    var segmentsLength = segmentsLengthPool.newElement();
+    var closed = shapeData.c;
+    var pathV = shapeData.v;
+    var pathO = shapeData.o;
+    var pathI = shapeData.i;
+    var i;
+    var len = shapeData._length;
+    var lengths = segmentsLength.lengths;
+    var totalLength = 0;
+    for (i = 0; i < len - 1; i += 1) {
+      lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
+      totalLength += lengths[i].addedLength;
+    }
+    if (closed && len) {
+      lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
+      totalLength += lengths[i].addedLength;
+    }
+    segmentsLength.totalLength = totalLength;
+    return segmentsLength;
+  }
+
+  function BezierData(length) {
+    this.segmentLength = 0;
+    this.points = new Array(length);
+  }
+
+  function PointData(partial, point) {
+    this.partialLength = partial;
+    this.point = point;
+  }
+
+  var buildBezierData = (function () {
+    var storedData = {};
+
+    return function (pt1, pt2, pt3, pt4) {
+      var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
+      if (!storedData[bezierName]) {
+        var curveSegments = getDefaultCurveSegments();
+        var k;
+        var i;
+        var len;
+        var ptCoord;
+        var perc;
+        var addedLength = 0;
+        var ptDistance;
+        var point;
+        var lastPoint = null;
+        if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
+          curveSegments = 2;
+        }
+        var bezierData = new BezierData(curveSegments);
+        len = pt3.length;
+        for (k = 0; k < curveSegments; k += 1) {
+          point = createSizedArray(len);
+          perc = k / (curveSegments - 1);
+          ptDistance = 0;
+          for (i = 0; i < len; i += 1) {
+            ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
+            point[i] = ptCoord;
+            if (lastPoint !== null) {
+              ptDistance += bmPow(point[i] - lastPoint[i], 2);
+            }
+          }
+          ptDistance = bmSqrt(ptDistance);
+          addedLength += ptDistance;
+          bezierData.points[k] = new PointData(ptDistance, point);
+          lastPoint = point;
+        }
+        bezierData.segmentLength = addedLength;
+        storedData[bezierName] = bezierData;
+      }
+      return storedData[bezierName];
+    };
+  }());
+
+  function getDistancePerc(perc, bezierData) {
+    var percents = bezierData.percents;
+    var lengths = bezierData.lengths;
+    var len = percents.length;
+    var initPos = bmFloor((len - 1) * perc);
+    var lengthPos = perc * bezierData.addedLength;
+    var lPerc = 0;
+    if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
+      return percents[initPos];
+    }
+    var dir = lengths[initPos] > lengthPos ? -1 : 1;
+    var flag = true;
+    while (flag) {
+      if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
+        lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
+        flag = false;
+      } else {
+        initPos += dir;
+      }
+      if (initPos < 0 || initPos >= len - 1) {
+        // FIX for TypedArrays that don't store floating point values with enough accuracy
+        if (initPos === len - 1) {
+          return percents[initPos];
+        }
+        flag = false;
+      }
+    }
+    return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
+  }
+
+  function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
+    var t1 = getDistancePerc(percent, bezierData);
+    var u1 = 1 - t1;
+    var ptX = math.round((u1 * u1 * u1 * pt1[0] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[0] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[0] + t1 * t1 * t1 * pt2[0]) * 1000) / 1000;
+    var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
+    return [ptX, ptY];
+  }
+
+  var bezierSegmentPoints = createTypedArray('float32', 8);
+
+  function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
+    if (startPerc < 0) {
+      startPerc = 0;
+    } else if (startPerc > 1) {
+      startPerc = 1;
+    }
+    var t0 = getDistancePerc(startPerc, bezierData);
+    endPerc = endPerc > 1 ? 1 : endPerc;
+    var t1 = getDistancePerc(endPerc, bezierData);
+    var i;
+    var len = pt1.length;
+    var u0 = 1 - t0;
+    var u1 = 1 - t1;
+    var u0u0u0 = u0 * u0 * u0;
+    var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
+    var t0t0t0 = t0 * t0 * t0;
+    //
+    var u0u0u1 = u0 * u0 * u1;
+    var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
+    var t0t0t1 = t0 * t0 * t1;
+    //
+    var u0u1u1 = u0 * u1 * u1;
+    var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
+    var t0t1t1 = t0 * t1 * t1;
+    //
+    var u1u1u1 = u1 * u1 * u1;
+    var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
+    var t1t1t1 = t1 * t1 * t1;
+    for (i = 0; i < len; i += 1) {
+      bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+      bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
+    }
+
+    return bezierSegmentPoints;
+  }
+
+  return {
+    getSegmentsLength: getSegmentsLength,
+    getNewSegment: getNewSegment,
+    getPointInSegment: getPointInSegment,
+    buildBezierData: buildBezierData,
+    pointOnLine2D: pointOnLine2D,
+    pointOnLine3D: pointOnLine3D,
+  };
+}
+
+const bez = bezFunction();
+
+var initFrame = initialDefaultFrame;
+var mathAbs = Math.abs;
+
+function interpolateValue(frameNum, caching) {
+  var offsetTime = this.offsetTime;
+  var newValue;
+  if (this.propType === 'multidimensional') {
+    newValue = createTypedArray('float32', this.pv.length);
+  }
+  var iterationIndex = caching.lastIndex;
+  var i = iterationIndex;
+  var len = this.keyframes.length - 1;
+  var flag = true;
+  var keyData;
+  var nextKeyData;
+  var keyframeMetadata;
+
+  while (flag) {
+    keyData = this.keyframes[i];
+    nextKeyData = this.keyframes[i + 1];
+    if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
+      if (keyData.h) {
+        keyData = nextKeyData;
+      }
+      iterationIndex = 0;
+      break;
+    }
+    if ((nextKeyData.t - offsetTime) > frameNum) {
+      iterationIndex = i;
+      break;
+    }
+    if (i < len - 1) {
+      i += 1;
+    } else {
+      iterationIndex = 0;
+      flag = false;
+    }
+  }
+  keyframeMetadata = this.keyframesMetadata[i] || {};
+
+  var k;
+  var kLen;
+  var perc;
+  var jLen;
+  var j;
+  var fnc;
+  var nextKeyTime = nextKeyData.t - offsetTime;
+  var keyTime = keyData.t - offsetTime;
+  var endValue;
+  if (keyData.to) {
+    if (!keyframeMetadata.bezierData) {
+      keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
+    }
+    var bezierData = keyframeMetadata.bezierData;
+    if (frameNum >= nextKeyTime || frameNum < keyTime) {
+      var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
+      kLen = bezierData.points[ind].point.length;
+      for (k = 0; k < kLen; k += 1) {
+        newValue[k] = bezierData.points[ind].point[k];
+      }
+      // caching._lastKeyframeIndex = -1;
+    } else {
+      if (keyframeMetadata.__fnct) {
+        fnc = keyframeMetadata.__fnct;
+      } else {
+        fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
+        keyframeMetadata.__fnct = fnc;
+      }
+      perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+      var distanceInLine = bezierData.segmentLength * perc;
+
+      var segmentPerc;
+      var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0;
+      j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0;
+      flag = true;
+      jLen = bezierData.points.length;
+      while (flag) {
+        addedLength += bezierData.points[j].partialLength;
+        if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k];
+          }
+          break;
+        } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
+          segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
+          kLen = bezierData.points[j].point.length;
+          for (k = 0; k < kLen; k += 1) {
+            newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
+          }
+          break;
+        }
+        if (j < jLen - 1) {
+          j += 1;
+        } else {
+          flag = false;
+        }
+      }
+      caching._lastPoint = j;
+      caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
+      caching._lastKeyframeIndex = i;
+    }
+  } else {
+    var outX;
+    var outY;
+    var inX;
+    var inY;
+    var keyValue;
+    len = keyData.s.length;
+    endValue = nextKeyData.s || keyData.e;
+    if (this.sh && keyData.h !== 1) {
+      if (frameNum >= nextKeyTime) {
+        newValue[0] = endValue[0];
+        newValue[1] = endValue[1];
+        newValue[2] = endValue[2];
+      } else if (frameNum <= keyTime) {
+        newValue[0] = keyData.s[0];
+        newValue[1] = keyData.s[1];
+        newValue[2] = keyData.s[2];
+      } else {
+        var quatStart = createQuaternion(keyData.s);
+        var quatEnd = createQuaternion(endValue);
+        var time = (frameNum - keyTime) / (nextKeyTime - keyTime);
+        quaternionToEuler(newValue, slerp(quatStart, quatEnd, time));
+      }
+    } else {
+      for (i = 0; i < len; i += 1) {
+        if (keyData.h !== 1) {
+          if (frameNum >= nextKeyTime) {
+            perc = 1;
+          } else if (frameNum < keyTime) {
+            perc = 0;
+          } else {
+            if (keyData.o.x.constructor === Array) {
+              if (!keyframeMetadata.__fnct) {
+                keyframeMetadata.__fnct = [];
+              }
+              if (!keyframeMetadata.__fnct[i]) {
+                outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
+                outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
+                inX = keyData.i.x[i] === undefined ? keyData.i.x[0] : keyData.i.x[i];
+                inY = keyData.i.y[i] === undefined ? keyData.i.y[0] : keyData.i.y[i];
+                fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+                keyframeMetadata.__fnct[i] = fnc;
+              } else {
+                fnc = keyframeMetadata.__fnct[i];
+              }
+            } else if (!keyframeMetadata.__fnct) {
+              outX = keyData.o.x;
+              outY = keyData.o.y;
+              inX = keyData.i.x;
+              inY = keyData.i.y;
+              fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
+              keyData.keyframeMetadata = fnc;
+            } else {
+              fnc = keyframeMetadata.__fnct;
+            }
+            perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
+          }
+        }
+
+        endValue = nextKeyData.s || keyData.e;
+        keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
+
+        if (this.propType === 'multidimensional') {
+          newValue[i] = keyValue;
+        } else {
+          newValue = keyValue;
+        }
+      }
+    }
+  }
+  caching.lastIndex = iterationIndex;
+  return newValue;
+}
+
+// based on @Toji's https://github.com/toji/gl-matrix/
+function slerp(a, b, t) {
+  var out = [];
+  var ax = a[0];
+  var ay = a[1];
+  var az = a[2];
+  var aw = a[3];
+  var bx = b[0];
+  var by = b[1];
+  var bz = b[2];
+  var bw = b[3];
+
+  var omega;
+  var cosom;
+  var sinom;
+  var scale0;
+  var scale1;
+
+  cosom = ax * bx + ay * by + az * bz + aw * bw;
+  if (cosom < 0.0) {
+    cosom = -cosom;
+    bx = -bx;
+    by = -by;
+    bz = -bz;
+    bw = -bw;
+  }
+  if ((1.0 - cosom) > 0.000001) {
+    omega = Math.acos(cosom);
+    sinom = Math.sin(omega);
+    scale0 = Math.sin((1.0 - t) * omega) / sinom;
+    scale1 = Math.sin(t * omega) / sinom;
+  } else {
+    scale0 = 1.0 - t;
+    scale1 = t;
+  }
+  out[0] = scale0 * ax + scale1 * bx;
+  out[1] = scale0 * ay + scale1 * by;
+  out[2] = scale0 * az + scale1 * bz;
+  out[3] = scale0 * aw + scale1 * bw;
+
+  return out;
+}
+
+function quaternionToEuler(out, quat) {
+  var qx = quat[0];
+  var qy = quat[1];
+  var qz = quat[2];
+  var qw = quat[3];
+  var heading = Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy * qy - 2 * qz * qz);
+  var attitude = Math.asin(2 * qx * qy + 2 * qz * qw);
+  var bank = Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx * qx - 2 * qz * qz);
+  out[0] = heading / degToRads;
+  out[1] = attitude / degToRads;
+  out[2] = bank / degToRads;
+}
+
+function createQuaternion(values) {
+  var heading = values[0] * degToRads;
+  var attitude = values[1] * degToRads;
+  var bank = values[2] * degToRads;
+  var c1 = Math.cos(heading / 2);
+  var c2 = Math.cos(attitude / 2);
+  var c3 = Math.cos(bank / 2);
+  var s1 = Math.sin(heading / 2);
+  var s2 = Math.sin(attitude / 2);
+  var s3 = Math.sin(bank / 2);
+  var w = c1 * c2 * c3 - s1 * s2 * s3;
+  var x = s1 * s2 * c3 + c1 * c2 * s3;
+  var y = s1 * c2 * c3 + c1 * s2 * s3;
+  var z = c1 * s2 * c3 - s1 * c2 * s3;
+
+  return [x, y, z, w];
+}
+
+function getValueAtCurrentTime() {
+  var frameNum = this.comp.renderedFrame - this.offsetTime;
+  var initTime = this.keyframes[0].t - this.offsetTime;
+  var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+  if (!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))) {
+    if (this._caching.lastFrame >= frameNum) {
+      this._caching._lastKeyframeIndex = -1;
+      this._caching.lastIndex = 0;
+    }
+
+    var renderResult = this.interpolateValue(frameNum, this._caching);
+    this.pv = renderResult;
+  }
+  this._caching.lastFrame = frameNum;
+  return this.pv;
+}
+
+function setVValue(val) {
+  var multipliedValue;
+  if (this.propType === 'unidimensional') {
+    multipliedValue = val * this.mult;
+    if (mathAbs(this.v - multipliedValue) > 0.00001) {
+      this.v = multipliedValue;
+      this._mdf = true;
+    }
+  } else {
+    var i = 0;
+    var len = this.v.length;
+    while (i < len) {
+      multipliedValue = val[i] * this.mult;
+      if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
+        this.v[i] = multipliedValue;
+        this._mdf = true;
+      }
+      i += 1;
+    }
+  }
+}
+
+function processEffectsSequence() {
+  if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
+    return;
+  }
+  if (this.lock) {
+    this.setVValue(this.pv);
+    return;
+  }
+  this.lock = true;
+  this._mdf = this._isFirstFrame;
+  var i;
+  var len = this.effectsSequence.length;
+  var finalValue = this.kf ? this.pv : this.data.k;
+  for (i = 0; i < len; i += 1) {
+    finalValue = this.effectsSequence[i](finalValue);
+  }
+  this.setVValue(finalValue);
+  this._isFirstFrame = false;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+}
+
+function addEffect(effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.container.addDynamicProperty(this);
+}
+
+function ValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this.v = mult ? data.k * mult : data.k;
+  this.pv = data.k;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.vel = 0;
+  this.effectsSequence = [];
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function MultiDimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  this.mult = mult || 1;
+  this.data = data;
+  this._mdf = false;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.k = false;
+  this.kf = false;
+  this.frameId = -1;
+  var i;
+  var len = data.k.length;
+  this.v = createTypedArray('float32', len);
+  this.pv = createTypedArray('float32', len);
+  this.vel = createTypedArray('float32', len);
+  for (i = 0; i < len; i += 1) {
+    this.v[i] = data.k[i] * this.mult;
+    this.pv[i] = data.k[i];
+  }
+  this._isFirstFrame = true;
+  this.effectsSequence = [];
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.addEffect = addEffect;
+}
+
+function KeyframedValueProperty(elem, data, mult, container) {
+  this.propType = 'unidimensional';
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.frameId = -1;
+  this._caching = {
+    lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1,
+  };
+  this.k = true;
+  this.kf = true;
+  this.data = data;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.v = initFrame;
+  this.pv = initFrame;
+  this._isFirstFrame = true;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.addEffect = addEffect;
+}
+
+function KeyframedMultidimensionalProperty(elem, data, mult, container) {
+  this.propType = 'multidimensional';
+  var i;
+  var len = data.k.length;
+  var s;
+  var e;
+  var to;
+  var ti;
+  for (i = 0; i < len - 1; i += 1) {
+    if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
+      s = data.k[i].s;
+      e = data.k[i + 1].s;
+      to = data.k[i].to;
+      ti = data.k[i].ti;
+      if ((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2]))) {
+        data.k[i].to = null;
+        data.k[i].ti = null;
+      }
+      if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
+        if (s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) {
+          data.k[i].to = null;
+          data.k[i].ti = null;
+        }
+      }
+    }
+  }
+  this.effectsSequence = [getValueAtCurrentTime.bind(this)];
+  this.data = data;
+  this.keyframes = data.k;
+  this.keyframesMetadata = [];
+  this.offsetTime = elem.data.st;
+  this.k = true;
+  this.kf = true;
+  this._isFirstFrame = true;
+  this.mult = mult || 1;
+  this.elem = elem;
+  this.container = container;
+  this.comp = elem.comp;
+  this.getValue = processEffectsSequence;
+  this.setVValue = setVValue;
+  this.interpolateValue = interpolateValue;
+  this.frameId = -1;
+  var arrLen = data.k[0].s.length;
+  this.v = createTypedArray('float32', arrLen);
+  this.pv = createTypedArray('float32', arrLen);
+  for (i = 0; i < arrLen; i += 1) {
+    this.v[i] = initFrame;
+    this.pv[i] = initFrame;
+  }
+  this._caching = { lastFrame: initFrame, lastIndex: 0, value: createTypedArray('float32', arrLen) };
+  this.addEffect = addEffect;
+}
+
+const PropertyFactory = (function () {
+  function getProp(elem, data, type, mult, container) {
+    if (data.sid) {
+      data = elem.globalData.slotManager.getProp(data);
+    }
+    var p;
+    if (!data.k.length) {
+      p = new ValueProperty(elem, data, mult, container);
+    } else if (typeof (data.k[0]) === 'number') {
+      p = new MultiDimensionalProperty(elem, data, mult, container);
+    } else {
+      switch (type) {
+        case 0:
+          p = new KeyframedValueProperty(elem, data, mult, container);
+          break;
+        case 1:
+          p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
+          break;
+        default:
+          break;
+      }
+    }
+    if (p.effectsSequence.length) {
+      container.addDynamicProperty(p);
+    }
+    return p;
+  }
+
+  var ob = {
+    getProp: getProp,
+  };
+  return ob;
+}());
+
+function DynamicPropertyContainer() {}
+DynamicPropertyContainer.prototype = {
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+      this.container.addDynamicProperty(this);
+      this._isAnimated = true;
+    }
+  },
+  iterateDynamicProperties: function () {
+    this._mdf = false;
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      this.dynamicProperties[i].getValue();
+      if (this.dynamicProperties[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  },
+  initDynamicPropertyContainer: function (container) {
+    this.container = container;
+    this.dynamicProperties = [];
+    this._mdf = false;
+    this._isAnimated = false;
+  },
+};
+
+const pointPool = (function () {
+  function create() {
+    return createTypedArray('float32', 2);
+  }
+  return poolFactory(8, create);
+}());
+
+function ShapePath() {
+  this.c = false;
+  this._length = 0;
+  this._maxLength = 8;
+  this.v = createSizedArray(this._maxLength);
+  this.o = createSizedArray(this._maxLength);
+  this.i = createSizedArray(this._maxLength);
+}
+
+ShapePath.prototype.setPathData = function (closed, len) {
+  this.c = closed;
+  this.setLength(len);
+  var i = 0;
+  while (i < len) {
+    this.v[i] = pointPool.newElement();
+    this.o[i] = pointPool.newElement();
+    this.i[i] = pointPool.newElement();
+    i += 1;
+  }
+};
+
+ShapePath.prototype.setLength = function (len) {
+  while (this._maxLength < len) {
+    this.doubleArrayLength();
+  }
+  this._length = len;
+};
+
+ShapePath.prototype.doubleArrayLength = function () {
+  this.v = this.v.concat(createSizedArray(this._maxLength));
+  this.i = this.i.concat(createSizedArray(this._maxLength));
+  this.o = this.o.concat(createSizedArray(this._maxLength));
+  this._maxLength *= 2;
+};
+
+ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
+  var arr;
+  this._length = Math.max(this._length, pos + 1);
+  if (this._length >= this._maxLength) {
+    this.doubleArrayLength();
+  }
+  switch (type) {
+    case 'v':
+      arr = this.v;
+      break;
+    case 'i':
+      arr = this.i;
+      break;
+    case 'o':
+      arr = this.o;
+      break;
+    default:
+      arr = [];
+      break;
+  }
+  if (!arr[pos] || (arr[pos] && !replace)) {
+    arr[pos] = pointPool.newElement();
+  }
+  arr[pos][0] = x;
+  arr[pos][1] = y;
+};
+
+ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
+  this.setXYAt(vX, vY, 'v', pos, replace);
+  this.setXYAt(oX, oY, 'o', pos, replace);
+  this.setXYAt(iX, iY, 'i', pos, replace);
+};
+
+ShapePath.prototype.reverse = function () {
+  var newPath = new ShapePath();
+  newPath.setPathData(this.c, this._length);
+  var vertices = this.v;
+  var outPoints = this.o;
+  var inPoints = this.i;
+  var init = 0;
+  if (this.c) {
+    newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
+    init = 1;
+  }
+  var cnt = this._length - 1;
+  var len = this._length;
+
+  var i;
+  for (i = init; i < len; i += 1) {
+    newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
+    cnt -= 1;
+  }
+  return newPath;
+};
+
+ShapePath.prototype.length = function () {
+  return this._length;
+};
+
+const shapePool = (function () {
+  function create() {
+    return new ShapePath();
+  }
+
+  function release(shapePath) {
+    var len = shapePath._length;
+    var i;
+    for (i = 0; i < len; i += 1) {
+      pointPool.release(shapePath.v[i]);
+      pointPool.release(shapePath.i[i]);
+      pointPool.release(shapePath.o[i]);
+      shapePath.v[i] = null;
+      shapePath.i[i] = null;
+      shapePath.o[i] = null;
+    }
+    shapePath._length = 0;
+    shapePath.c = false;
+  }
+
+  function clone(shape) {
+    var cloned = factory.newElement();
+    var i;
+    var len = shape._length === undefined ? shape.v.length : shape._length;
+    cloned.setLength(len);
+    cloned.c = shape.c;
+
+    for (i = 0; i < len; i += 1) {
+      cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
+    }
+    return cloned;
+  }
+
+  var factory = poolFactory(4, create, release);
+  factory.clone = clone;
+
+  return factory;
+}());
+
+function ShapeCollection() {
+  this._length = 0;
+  this._maxLength = 4;
+  this.shapes = createSizedArray(this._maxLength);
+}
+
+ShapeCollection.prototype.addShape = function (shapeData) {
+  if (this._length === this._maxLength) {
+    this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
+    this._maxLength *= 2;
+  }
+  this.shapes[this._length] = shapeData;
+  this._length += 1;
+};
+
+ShapeCollection.prototype.releaseShapes = function () {
+  var i;
+  for (i = 0; i < this._length; i += 1) {
+    shapePool.release(this.shapes[i]);
+  }
+  this._length = 0;
+};
+
+const shapeCollectionPool = (function () {
+  var ob = {
+    newShapeCollection: newShapeCollection,
+    release: release,
+  };
+
+  var _length = 0;
+  var _maxLength = 4;
+  var pool = createSizedArray(_maxLength);
+
+  function newShapeCollection() {
+    var shapeCollection;
+    if (_length) {
+      _length -= 1;
+      shapeCollection = pool[_length];
+    } else {
+      shapeCollection = new ShapeCollection();
+    }
+    return shapeCollection;
+  }
+
+  function release(shapeCollection) {
+    var i;
+    var len = shapeCollection._length;
+    for (i = 0; i < len; i += 1) {
+      shapePool.release(shapeCollection.shapes[i]);
+    }
+    shapeCollection._length = 0;
+
+    if (_length === _maxLength) {
+      pool = pooling.double(pool);
+      _maxLength *= 2;
+    }
+    pool[_length] = shapeCollection;
+    _length += 1;
+  }
+
+  return ob;
+}());
+
+const ShapePropertyFactory = (function () {
+  var initFrame = -999999;
+
+  function interpolateShape(frameNum, previousValue, caching) {
+    var iterationIndex = caching.lastIndex;
+    var keyPropS;
+    var keyPropE;
+    var isHold;
+    var j;
+    var k;
+    var jLen;
+    var kLen;
+    var perc;
+    var vertexValue;
+    var kf = this.keyframes;
+    if (frameNum < kf[0].t - this.offsetTime) {
+      keyPropS = kf[0].s[0];
+      isHold = true;
+      iterationIndex = 0;
+    } else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) {
+      keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
+      /* if(kf[kf.length - 1].s){
+                keyPropS = kf[kf.length - 1].s[0];
+            }else{
+                keyPropS = kf[kf.length - 2].e[0];
+            } */
+      isHold = true;
+    } else {
+      var i = iterationIndex;
+      var len = kf.length - 1;
+      var flag = true;
+      var keyData;
+      var nextKeyData;
+      var keyframeMetadata;
+      while (flag) {
+        keyData = kf[i];
+        nextKeyData = kf[i + 1];
+        if ((nextKeyData.t - this.offsetTime) > frameNum) {
+          break;
+        }
+        if (i < len - 1) {
+          i += 1;
+        } else {
+          flag = false;
+        }
+      }
+      keyframeMetadata = this.keyframesMetadata[i] || {};
+      isHold = keyData.h === 1;
+      iterationIndex = i;
+      if (!isHold) {
+        if (frameNum >= nextKeyData.t - this.offsetTime) {
+          perc = 1;
+        } else if (frameNum < keyData.t - this.offsetTime) {
+          perc = 0;
+        } else {
+          var fnc;
+          if (keyframeMetadata.__fnct) {
+            fnc = keyframeMetadata.__fnct;
+          } else {
+            fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
+            keyframeMetadata.__fnct = fnc;
+          }
+          perc = fnc((frameNum - (keyData.t - this.offsetTime)) / ((nextKeyData.t - this.offsetTime) - (keyData.t - this.offsetTime)));
+        }
+        keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
+      }
+      keyPropS = keyData.s[0];
+    }
+    jLen = previousValue._length;
+    kLen = keyPropS.i[0].length;
+    caching.lastIndex = iterationIndex;
+
+    for (j = 0; j < jLen; j += 1) {
+      for (k = 0; k < kLen; k += 1) {
+        vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
+        previousValue.i[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc;
+        previousValue.o[j][k] = vertexValue;
+        vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc;
+        previousValue.v[j][k] = vertexValue;
+      }
+    }
+  }
+
+  function interpolateShapeCurrentTime() {
+    var frameNum = this.comp.renderedFrame - this.offsetTime;
+    var initTime = this.keyframes[0].t - this.offsetTime;
+    var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
+    var lastFrame = this._caching.lastFrame;
+    if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) {
+      /// /
+      this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
+      this.interpolateShape(frameNum, this.pv, this._caching);
+      /// /
+    }
+    this._caching.lastFrame = frameNum;
+    return this.pv;
+  }
+
+  function resetShape() {
+    this.paths = this.localShapeCollection;
+  }
+
+  function shapesEqual(shape1, shape2) {
+    if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
+      return false;
+    }
+    var i;
+    var len = shape1._length;
+    for (i = 0; i < len; i += 1) {
+      if (shape1.v[i][0] !== shape2.v[i][0]
+            || shape1.v[i][1] !== shape2.v[i][1]
+            || shape1.o[i][0] !== shape2.o[i][0]
+            || shape1.o[i][1] !== shape2.o[i][1]
+            || shape1.i[i][0] !== shape2.i[i][0]
+            || shape1.i[i][1] !== shape2.i[i][1]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  function setVValue(newPath) {
+    if (!shapesEqual(this.v, newPath)) {
+      this.v = shapePool.clone(newPath);
+      this.localShapeCollection.releaseShapes();
+      this.localShapeCollection.addShape(this.v);
+      this._mdf = true;
+      this.paths = this.localShapeCollection;
+    }
+  }
+
+  function processEffectsSequence() {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    } if (!this.effectsSequence.length) {
+      this._mdf = false;
+      return;
+    }
+    if (this.lock) {
+      this.setVValue(this.pv);
+      return;
+    }
+    this.lock = true;
+    this._mdf = false;
+    var finalValue;
+    if (this.kf) {
+      finalValue = this.pv;
+    } else if (this.data.ks) {
+      finalValue = this.data.ks.k;
+    } else {
+      finalValue = this.data.pt.k;
+    }
+    var i;
+    var len = this.effectsSequence.length;
+    for (i = 0; i < len; i += 1) {
+      finalValue = this.effectsSequence[i](finalValue);
+    }
+    this.setVValue(finalValue);
+    this.lock = false;
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function ShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.container = elem;
+    this.elem = elem;
+    this.data = data;
+    this.k = false;
+    this.kf = false;
+    this._mdf = false;
+    var pathData = type === 3 ? data.pt.k : data.ks.k;
+    this.v = shapePool.clone(pathData);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.reset = resetShape;
+    this.effectsSequence = [];
+  }
+
+  function addEffect(effectFunction) {
+    this.effectsSequence.push(effectFunction);
+    this.container.addDynamicProperty(this);
+  }
+
+  ShapeProperty.prototype.interpolateShape = interpolateShape;
+  ShapeProperty.prototype.getValue = processEffectsSequence;
+  ShapeProperty.prototype.setVValue = setVValue;
+  ShapeProperty.prototype.addEffect = addEffect;
+
+  function KeyframedShapeProperty(elem, data, type) {
+    this.propType = 'shape';
+    this.comp = elem.comp;
+    this.elem = elem;
+    this.container = elem;
+    this.offsetTime = elem.data.st;
+    this.keyframes = type === 3 ? data.pt.k : data.ks.k;
+    this.keyframesMetadata = [];
+    this.k = true;
+    this.kf = true;
+    var len = this.keyframes[0].s[0].i.length;
+    this.v = shapePool.newElement();
+    this.v.setPathData(this.keyframes[0].s[0].c, len);
+    this.pv = shapePool.clone(this.v);
+    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+    this.paths = this.localShapeCollection;
+    this.paths.addShape(this.v);
+    this.lastFrame = initFrame;
+    this.reset = resetShape;
+    this._caching = { lastFrame: initFrame, lastIndex: 0 };
+    this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
+  }
+  KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
+  KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
+  KeyframedShapeProperty.prototype.setVValue = setVValue;
+  KeyframedShapeProperty.prototype.addEffect = addEffect;
+
+  var EllShapeProperty = (function () {
+    var cPoint = roundCorner;
+
+    function EllShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 4);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.paths = this.localShapeCollection;
+      this.localShapeCollection.addShape(this.v);
+      this.d = data.d;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertEllToPath();
+      }
+    }
+
+    EllShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+
+        if (this._mdf) {
+          this.convertEllToPath();
+        }
+      },
+      convertEllToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var s0 = this.s.v[0] / 2;
+        var s1 = this.s.v[1] / 2;
+        var _cw = this.d !== 3;
+        var _v = this.v;
+        _v.v[0][0] = p0;
+        _v.v[0][1] = p1 - s1;
+        _v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.v[1][1] = p1;
+        _v.v[2][0] = p0;
+        _v.v[2][1] = p1 + s1;
+        _v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.v[3][1] = p1;
+        _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.i[0][1] = p1 - s1;
+        _v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.i[1][1] = p1 - s1 * cPoint;
+        _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.i[2][1] = p1 + s1;
+        _v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.i[3][1] = p1 + s1 * cPoint;
+        _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
+        _v.o[0][1] = p1 - s1;
+        _v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
+        _v.o[1][1] = p1 + s1 * cPoint;
+        _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
+        _v.o[2][1] = p1 + s1;
+        _v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
+        _v.o[3][1] = p1 - s1 * cPoint;
+      },
+    };
+
+    extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
+
+    return EllShapePropertyFactory;
+  }());
+
+  var StarShapeProperty = (function () {
+    function StarShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.setPathData(true, 0);
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.data = data;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      if (data.sy === 1) {
+        this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
+        this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
+        this.convertToPath = this.convertStarToPath;
+      } else {
+        this.convertToPath = this.convertPolygonToPath;
+      }
+      this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
+      this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this);
+      this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this);
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertToPath();
+      }
+    }
+
+    StarShapePropertyFactory.prototype = {
+      reset: resetShape,
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertToPath();
+        }
+      },
+      convertStarToPath: function () {
+        var numPts = Math.floor(this.pt.v) * 2;
+        var angle = (Math.PI * 2) / numPts;
+        /* this.v.v.length = numPts;
+                this.v.i.length = numPts;
+                this.v.o.length = numPts; */
+        var longFlag = true;
+        var longRad = this.or.v;
+        var shortRad = this.ir.v;
+        var longRound = this.os.v;
+        var shortRound = this.is.v;
+        var longPerimSegment = (2 * Math.PI * longRad) / (numPts * 2);
+        var shortPerimSegment = (2 * Math.PI * shortRad) / (numPts * 2);
+        var i;
+        var rad;
+        var roundness;
+        var perimSegment;
+        var currentAng = -Math.PI / 2;
+        currentAng += this.r.v;
+        var dir = this.data.d === 3 ? -1 : 1;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          rad = longFlag ? longRad : shortRad;
+          roundness = longFlag ? longRound : shortRound;
+          perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
+          /* this.v.v[i] = [x,y];
+                    this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
+                    this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
+                    this.v._length = numPts; */
+          longFlag = !longFlag;
+          currentAng += angle * dir;
+        }
+      },
+      convertPolygonToPath: function () {
+        var numPts = Math.floor(this.pt.v);
+        var angle = (Math.PI * 2) / numPts;
+        var rad = this.or.v;
+        var roundness = this.os.v;
+        var perimSegment = (2 * Math.PI * rad) / (numPts * 4);
+        var i;
+        var currentAng = -Math.PI * 0.5;
+        var dir = this.data.d === 3 ? -1 : 1;
+        currentAng += this.r.v;
+        this.v._length = 0;
+        for (i = 0; i < numPts; i += 1) {
+          var x = rad * Math.cos(currentAng);
+          var y = rad * Math.sin(currentAng);
+          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
+          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
+          x += +this.p.v[0];
+          y += +this.p.v[1];
+          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+          currentAng += angle * dir;
+        }
+        this.paths.length = 0;
+        this.paths[0] = this.v;
+      },
+
+    };
+    extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
+
+    return StarShapePropertyFactory;
+  }());
+
+  var RectShapeProperty = (function () {
+    function RectShapePropertyFactory(elem, data) {
+      this.v = shapePool.newElement();
+      this.v.c = true;
+      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
+      this.localShapeCollection.addShape(this.v);
+      this.paths = this.localShapeCollection;
+      this.elem = elem;
+      this.comp = elem.comp;
+      this.frameId = -1;
+      this.d = data.d;
+      this.initDynamicPropertyContainer(elem);
+      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
+      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
+      this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
+      if (this.dynamicProperties.length) {
+        this.k = true;
+      } else {
+        this.k = false;
+        this.convertRectToPath();
+      }
+    }
+
+    RectShapePropertyFactory.prototype = {
+      convertRectToPath: function () {
+        var p0 = this.p.v[0];
+        var p1 = this.p.v[1];
+        var v0 = this.s.v[0] / 2;
+        var v1 = this.s.v[1] / 2;
+        var round = bmMin(v0, v1, this.r.v);
+        var cPoint = round * (1 - roundCorner);
+        this.v._length = 0;
+
+        if (this.d === 2 || this.d === 1) {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
+          this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2);
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3);
+          }
+        } else {
+          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
+          if (round !== 0) {
+            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
+            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true);
+            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true);
+            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true);
+          } else {
+            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true);
+            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true);
+            this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true);
+          }
+        }
+      },
+      getValue: function () {
+        if (this.elem.globalData.frameId === this.frameId) {
+          return;
+        }
+        this.frameId = this.elem.globalData.frameId;
+        this.iterateDynamicProperties();
+        if (this._mdf) {
+          this.convertRectToPath();
+        }
+      },
+      reset: resetShape,
+    };
+    extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
+
+    return RectShapePropertyFactory;
+  }());
+
+  function getShapeProp(elem, data, type) {
+    var prop;
+    if (type === 3 || type === 4) {
+      var dataProp = type === 3 ? data.pt : data.ks;
+      var keys = dataProp.k;
+      if (keys.length) {
+        prop = new KeyframedShapeProperty(elem, data, type);
+      } else {
+        prop = new ShapeProperty(elem, data, type);
+      }
+    } else if (type === 5) {
+      prop = new RectShapeProperty(elem, data);
+    } else if (type === 6) {
+      prop = new EllShapeProperty(elem, data);
+    } else if (type === 7) {
+      prop = new StarShapeProperty(elem, data);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  }
+
+  function getConstructorFunction() {
+    return ShapeProperty;
+  }
+
+  function getKeyframedConstructorFunction() {
+    return KeyframedShapeProperty;
+  }
+
+  var ob = {};
+  ob.getShapeProp = getShapeProp;
+  ob.getConstructorFunction = getConstructorFunction;
+  ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction;
+  return ob;
+}());
+
+/*!
+ Transformation Matrix v2.0
+ (c) Epistemex 2014-2015
+ www.epistemex.com
+ By Ken Fyrstenberg
+ Contributions by leeoniya.
+ License: MIT, header required.
+ */
+
+/**
+ * 2D transformation matrix object initialized with identity matrix.
+ *
+ * The matrix can synchronize a canvas context by supplying the context
+ * as an argument, or later apply current absolute transform to an
+ * existing context.
+ *
+ * All values are handled as floating point values.
+ *
+ * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix
+ * @prop {number} a - scale x
+ * @prop {number} b - shear y
+ * @prop {number} c - shear x
+ * @prop {number} d - scale y
+ * @prop {number} e - translate x
+ * @prop {number} f - translate y
+ * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context
+ * @constructor
+ */
+
+const Matrix = (function () {
+  var _cos = Math.cos;
+  var _sin = Math.sin;
+  var _tan = Math.tan;
+  var _rnd = Math.round;
+
+  function reset() {
+    this.props[0] = 1;
+    this.props[1] = 0;
+    this.props[2] = 0;
+    this.props[3] = 0;
+    this.props[4] = 0;
+    this.props[5] = 1;
+    this.props[6] = 0;
+    this.props[7] = 0;
+    this.props[8] = 0;
+    this.props[9] = 0;
+    this.props[10] = 1;
+    this.props[11] = 0;
+    this.props[12] = 0;
+    this.props[13] = 0;
+    this.props[14] = 0;
+    this.props[15] = 1;
+    return this;
+  }
+
+  function rotate(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function rotateX(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateY(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
+  }
+
+  function rotateZ(angle) {
+    if (angle === 0) {
+      return this;
+    }
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+  }
+
+  function shear(sx, sy) {
+    return this._t(1, sy, sx, 1, 0, 0);
+  }
+
+  function skew(ax, ay) {
+    return this.shear(_tan(ax), _tan(ay));
+  }
+
+  function skewFromAxis(ax, angle) {
+    var mCos = _cos(angle);
+    var mSin = _sin(angle);
+    return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
+      ._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+    // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+  }
+
+  function scale(sx, sy, sz) {
+    if (!sz && sz !== 0) {
+      sz = 1;
+    }
+    if (sx === 1 && sy === 1 && sz === 1) {
+      return this;
+    }
+    return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
+  }
+
+  function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
+    this.props[0] = a;
+    this.props[1] = b;
+    this.props[2] = c;
+    this.props[3] = d;
+    this.props[4] = e;
+    this.props[5] = f;
+    this.props[6] = g;
+    this.props[7] = h;
+    this.props[8] = i;
+    this.props[9] = j;
+    this.props[10] = k;
+    this.props[11] = l;
+    this.props[12] = m;
+    this.props[13] = n;
+    this.props[14] = o;
+    this.props[15] = p;
+    return this;
+  }
+
+  function translate(tx, ty, tz) {
+    tz = tz || 0;
+    if (tx !== 0 || ty !== 0 || tz !== 0) {
+      return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
+    }
+    return this;
+  }
+
+  function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
+    var _p = this.props;
+
+    if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
+      // NOTE: commenting this condition because TurboFan deoptimizes code when present
+      // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
+      _p[12] = _p[12] * a2 + _p[15] * m2;
+      _p[13] = _p[13] * f2 + _p[15] * n2;
+      _p[14] = _p[14] * k2 + _p[15] * o2;
+      _p[15] *= p2;
+      // }
+      this._identityCalculated = false;
+      return this;
+    }
+
+    var a1 = _p[0];
+    var b1 = _p[1];
+    var c1 = _p[2];
+    var d1 = _p[3];
+    var e1 = _p[4];
+    var f1 = _p[5];
+    var g1 = _p[6];
+    var h1 = _p[7];
+    var i1 = _p[8];
+    var j1 = _p[9];
+    var k1 = _p[10];
+    var l1 = _p[11];
+    var m1 = _p[12];
+    var n1 = _p[13];
+    var o1 = _p[14];
+    var p1 = _p[15];
+
+    /* matrix order (canvas compatible):
+         * ace
+         * bdf
+         * 001
+         */
+    _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
+    _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
+    _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
+    _p[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2;
+
+    _p[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2;
+    _p[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2;
+    _p[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2;
+    _p[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2;
+
+    _p[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2;
+    _p[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2;
+    _p[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2;
+    _p[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2;
+
+    _p[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2;
+    _p[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2;
+    _p[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2;
+    _p[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2;
+
+    this._identityCalculated = false;
+    return this;
+  }
+
+  function multiply(matrix) {
+    var matrixProps = matrix.props;
+    return this.transform(
+      matrixProps[0],
+      matrixProps[1],
+      matrixProps[2],
+      matrixProps[3],
+      matrixProps[4],
+      matrixProps[5],
+      matrixProps[6],
+      matrixProps[7],
+      matrixProps[8],
+      matrixProps[9],
+      matrixProps[10],
+      matrixProps[11],
+      matrixProps[12],
+      matrixProps[13],
+      matrixProps[14],
+      matrixProps[15]
+    );
+  }
+
+  function isIdentity() {
+    if (!this._identityCalculated) {
+      this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
+      this._identityCalculated = true;
+    }
+    return this._identity;
+  }
+
+  function equals(matr) {
+    var i = 0;
+    while (i < 16) {
+      if (matr.props[i] !== this.props[i]) {
+        return false;
+      }
+      i += 1;
+    }
+    return true;
+  }
+
+  function clone(matr) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      matr.props[i] = this.props[i];
+    }
+    return matr;
+  }
+
+  function cloneFromProps(props) {
+    var i;
+    for (i = 0; i < 16; i += 1) {
+      this.props[i] = props[i];
+    }
+  }
+
+  function applyToPoint(x, y, z) {
+    return {
+      x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+      y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+      z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+    };
+    /* return {
+         x: x * me.a + y * me.c + me.e,
+         y: x * me.b + y * me.d + me.f
+         }; */
+  }
+  function applyToX(x, y, z) {
+    return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
+  }
+  function applyToY(x, y, z) {
+    return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
+  }
+  function applyToZ(x, y, z) {
+    return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
+  }
+
+  function getInverseMatrix() {
+    var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
+    var a = this.props[5] / determinant;
+    var b = -this.props[1] / determinant;
+    var c = -this.props[4] / determinant;
+    var d = this.props[0] / determinant;
+    var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12]) / determinant;
+    var f = -(this.props[0] * this.props[13] - this.props[1] * this.props[12]) / determinant;
+    var inverseMatrix = new Matrix();
+    inverseMatrix.props[0] = a;
+    inverseMatrix.props[1] = b;
+    inverseMatrix.props[4] = c;
+    inverseMatrix.props[5] = d;
+    inverseMatrix.props[12] = e;
+    inverseMatrix.props[13] = f;
+    return inverseMatrix;
+  }
+
+  function inversePoint(pt) {
+    var inverseMatrix = this.getInverseMatrix();
+    return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
+  }
+
+  function inversePoints(pts) {
+    var i;
+    var len = pts.length;
+    var retPts = [];
+    for (i = 0; i < len; i += 1) {
+      retPts[i] = inversePoint(pts[i]);
+    }
+    return retPts;
+  }
+
+  function applyToTriplePoints(pt1, pt2, pt3) {
+    var arr = createTypedArray('float32', 6);
+    if (this.isIdentity()) {
+      arr[0] = pt1[0];
+      arr[1] = pt1[1];
+      arr[2] = pt2[0];
+      arr[3] = pt2[1];
+      arr[4] = pt3[0];
+      arr[5] = pt3[1];
+    } else {
+      var p0 = this.props[0];
+      var p1 = this.props[1];
+      var p4 = this.props[4];
+      var p5 = this.props[5];
+      var p12 = this.props[12];
+      var p13 = this.props[13];
+      arr[0] = pt1[0] * p0 + pt1[1] * p4 + p12;
+      arr[1] = pt1[0] * p1 + pt1[1] * p5 + p13;
+      arr[2] = pt2[0] * p0 + pt2[1] * p4 + p12;
+      arr[3] = pt2[0] * p1 + pt2[1] * p5 + p13;
+      arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
+      arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
+    }
+    return arr;
+  }
+
+  function applyToPointArray(x, y, z) {
+    var arr;
+    if (this.isIdentity()) {
+      arr = [x, y, z];
+    } else {
+      arr = [
+        x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
+        x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
+        x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
+      ];
+    }
+    return arr;
+  }
+
+  function applyToPointStringified(x, y) {
+    if (this.isIdentity()) {
+      return x + ',' + y;
+    }
+    var _p = this.props;
+    return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
+  }
+
+  function toCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var i = 0;
+    var props = this.props;
+    var cssValue = 'matrix3d(';
+    var v = 10000;
+    while (i < 16) {
+      cssValue += _rnd(props[i] * v) / v;
+      cssValue += i === 15 ? ')' : ',';
+      i += 1;
+    }
+    return cssValue;
+  }
+
+  function roundMatrixProperty(val) {
+    var v = 10000;
+    if ((val < 0.000001 && val > 0) || (val > -0.000001 && val < 0)) {
+      return _rnd(val * v) / v;
+    }
+    return val;
+  }
+
+  function to2dCSS() {
+    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
+    /* if(this.isIdentity()) {
+            return '';
+        } */
+    var props = this.props;
+    var _a = roundMatrixProperty(props[0]);
+    var _b = roundMatrixProperty(props[1]);
+    var _c = roundMatrixProperty(props[4]);
+    var _d = roundMatrixProperty(props[5]);
+    var _e = roundMatrixProperty(props[12]);
+    var _f = roundMatrixProperty(props[13]);
+    return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
+  }
+
+  return function () {
+    this.reset = reset;
+    this.rotate = rotate;
+    this.rotateX = rotateX;
+    this.rotateY = rotateY;
+    this.rotateZ = rotateZ;
+    this.skew = skew;
+    this.skewFromAxis = skewFromAxis;
+    this.shear = shear;
+    this.scale = scale;
+    this.setTransform = setTransform;
+    this.translate = translate;
+    this.transform = transform;
+    this.multiply = multiply;
+    this.applyToPoint = applyToPoint;
+    this.applyToX = applyToX;
+    this.applyToY = applyToY;
+    this.applyToZ = applyToZ;
+    this.applyToPointArray = applyToPointArray;
+    this.applyToTriplePoints = applyToTriplePoints;
+    this.applyToPointStringified = applyToPointStringified;
+    this.toCSS = toCSS;
+    this.to2dCSS = to2dCSS;
+    this.clone = clone;
+    this.cloneFromProps = cloneFromProps;
+    this.equals = equals;
+    this.inversePoints = inversePoints;
+    this.inversePoint = inversePoint;
+    this.getInverseMatrix = getInverseMatrix;
+    this._t = this.transform;
+    this.isIdentity = isIdentity;
+    this._identity = true;
+    this._identityCalculated = false;
+
+    this.props = createTypedArray('float32', 16);
+    this.reset();
+  };
+}());
+
+const lottie = {};
+var standalone = '__[STANDALONE]__';
+var animationData = '__[ANIMATIONDATA]__';
+var renderer = '';
+
+function setLocation(href) {
+  setLocationHref(href);
+}
+
+function searchAnimations() {
+  if (standalone === true) {
+    animationManager.searchAnimations(animationData, standalone, renderer);
+  } else {
+    animationManager.searchAnimations();
+  }
+}
+
+function setSubframeRendering(flag) {
+  setSubframeEnabled(flag);
+}
+
+function setPrefix(prefix) {
+  setIdPrefix(prefix);
+}
+
+function loadAnimation(params) {
+  if (standalone === true) {
+    params.animationData = JSON.parse(animationData);
+  }
+  return animationManager.loadAnimation(params);
+}
+
+function setQuality(value) {
+  if (typeof value === 'string') {
+    switch (value) {
+      case 'high':
+        setDefaultCurveSegments(200);
+        break;
+      default:
+      case 'medium':
+        setDefaultCurveSegments(50);
+        break;
+      case 'low':
+        setDefaultCurveSegments(10);
+        break;
+    }
+  } else if (!isNaN(value) && value > 1) {
+    setDefaultCurveSegments(value);
+  }
+  if (getDefaultCurveSegments() >= 50) {
+    roundValues(false);
+  } else {
+    roundValues(true);
+  }
+}
+
+function inBrowser() {
+  return typeof navigator !== 'undefined';
+}
+
+function installPlugin(type, plugin) {
+  if (type === 'expressions') {
+    setExpressionsPlugin(plugin);
+  }
+}
+
+function getFactory(name) {
+  switch (name) {
+    case 'propertyFactory':
+      return PropertyFactory;
+    case 'shapePropertyFactory':
+      return ShapePropertyFactory;
+    case 'matrix':
+      return Matrix;
+    default:
+      return null;
+  }
+}
+
+lottie.play = animationManager.play;
+lottie.pause = animationManager.pause;
+lottie.setLocationHref = setLocation;
+lottie.togglePause = animationManager.togglePause;
+lottie.setSpeed = animationManager.setSpeed;
+lottie.setDirection = animationManager.setDirection;
+lottie.stop = animationManager.stop;
+lottie.searchAnimations = searchAnimations;
+lottie.registerAnimation = animationManager.registerAnimation;
+lottie.loadAnimation = loadAnimation;
+lottie.setSubframeRendering = setSubframeRendering;
+lottie.resize = animationManager.resize;
+// lottie.start = start;
+lottie.goToAndStop = animationManager.goToAndStop;
+lottie.destroy = animationManager.destroy;
+lottie.setQuality = setQuality;
+lottie.inBrowser = inBrowser;
+lottie.installPlugin = installPlugin;
+lottie.freeze = animationManager.freeze;
+lottie.unfreeze = animationManager.unfreeze;
+lottie.setVolume = animationManager.setVolume;
+lottie.mute = animationManager.mute;
+lottie.unmute = animationManager.unmute;
+lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations;
+lottie.useWebWorker = setWebWorker;
+lottie.setIDPrefix = setPrefix;
+lottie.__getFactory = getFactory;
+lottie.version = '[[BM_VERSION]]';
+
+function checkReady() {
+  if (document.readyState === 'complete') {
+    clearInterval(readyStateCheckInterval);
+    searchAnimations();
+  }
+}
+
+function getQueryVariable(variable) {
+  var vars = queryString.split('&');
+  for (var i = 0; i < vars.length; i += 1) {
+    var pair = vars[i].split('=');
+    if (decodeURIComponent(pair[0]) == variable) { // eslint-disable-line eqeqeq
+      return decodeURIComponent(pair[1]);
+    }
+  }
+  return null;
+}
+var queryString = '';
+if (standalone) {
+  var scripts = document.getElementsByTagName('script');
+  var index = scripts.length - 1;
+  var myScript = scripts[index] || {
+    src: '',
+  };
+  queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
+  renderer = getQueryVariable('renderer');
+}
+var readyStateCheckInterval = setInterval(checkReady, 100);
+
+// this adds bodymovin to the window object for backwards compatibility
+try {
+  if (!(typeof exports === 'object' && typeof module !== 'undefined')
+    && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
+  ) {
+    window.bodymovin = lottie;
+  }
+} catch (err) {
+  //
+}
+
+const ShapeModifiers = (function () {
+  var ob = {};
+  var modifiers = {};
+  ob.registerModifier = registerModifier;
+  ob.getModifier = getModifier;
+
+  function registerModifier(nm, factory) {
+    if (!modifiers[nm]) {
+      modifiers[nm] = factory;
+    }
+  }
+
+  function getModifier(nm, elem, data) {
+    return new modifiers[nm](elem, data);
+  }
+
+  return ob;
+}());
+
+function ShapeModifier() {}
+ShapeModifier.prototype.initModifierProperties = function () {};
+ShapeModifier.prototype.addShapeToModifier = function () {};
+ShapeModifier.prototype.addShape = function (data) {
+  if (!this.closed) {
+    // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
+    data.sh.container.addDynamicProperty(data.sh);
+    var shapeData = { shape: data.sh, data: data, localShapeCollection: shapeCollectionPool.newShapeCollection() };
+    this.shapes.push(shapeData);
+    this.addShapeToModifier(shapeData);
+    if (this._isAnimated) {
+      data.setAsAnimated();
+    }
+  }
+};
+ShapeModifier.prototype.init = function (elem, data) {
+  this.shapes = [];
+  this.elem = elem;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, data);
+  this.frameId = initialDefaultFrame;
+  this.closed = false;
+  this.k = false;
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+ShapeModifier.prototype.processKeys = function () {
+  if (this.elem.globalData.frameId === this.frameId) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+extendPrototype([DynamicPropertyContainer], ShapeModifier);
+
+function TrimModifier() {
+}
+extendPrototype([ShapeModifier], TrimModifier);
+TrimModifier.prototype.initModifierProperties = function (elem, data) {
+  this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this);
+  this.sValue = 0;
+  this.eValue = 0;
+  this.getValue = this.processKeys;
+  this.m = data.m;
+  this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
+};
+
+TrimModifier.prototype.addShapeToModifier = function (shapeData) {
+  shapeData.pathsData = [];
+};
+
+TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
+  var segments = [];
+  if (e <= 1) {
+    segments.push({
+      s: s,
+      e: e,
+    });
+  } else if (s >= 1) {
+    segments.push({
+      s: s - 1,
+      e: e - 1,
+    });
+  } else {
+    segments.push({
+      s: s,
+      e: 1,
+    });
+    segments.push({
+      s: 0,
+      e: e - 1,
+    });
+  }
+  var shapeSegments = [];
+  var i;
+  var len = segments.length;
+  var segmentOb;
+  for (i = 0; i < len; i += 1) {
+    segmentOb = segments[i];
+    if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
+      var shapeS;
+      var shapeE;
+      if (segmentOb.s * totalModifierLength <= addedLength) {
+        shapeS = 0;
+      } else {
+        shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
+      }
+      if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
+        shapeE = 1;
+      } else {
+        shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength);
+      }
+      shapeSegments.push([shapeS, shapeE]);
+    }
+  }
+  if (!shapeSegments.length) {
+    shapeSegments.push([0, 0]);
+  }
+  return shapeSegments;
+};
+
+TrimModifier.prototype.releasePathsData = function (pathsData) {
+  var i;
+  var len = pathsData.length;
+  for (i = 0; i < len; i += 1) {
+    segmentsLengthPool.release(pathsData[i]);
+  }
+  pathsData.length = 0;
+  return pathsData;
+};
+
+TrimModifier.prototype.processShapes = function (_isFirstFrame) {
+  var s;
+  var e;
+  if (this._mdf || _isFirstFrame) {
+    var o = (this.o.v % 360) / 360;
+    if (o < 0) {
+      o += 1;
+    }
+    if (this.s.v > 1) {
+      s = 1 + o;
+    } else if (this.s.v < 0) {
+      s = 0 + o;
+    } else {
+      s = this.s.v + o;
+    }
+    if (this.e.v > 1) {
+      e = 1 + o;
+    } else if (this.e.v < 0) {
+      e = 0 + o;
+    } else {
+      e = this.e.v + o;
+    }
+
+    if (s > e) {
+      var _s = s;
+      s = e;
+      e = _s;
+    }
+    s = Math.round(s * 10000) * 0.0001;
+    e = Math.round(e * 10000) * 0.0001;
+    this.sValue = s;
+    this.eValue = e;
+  } else {
+    s = this.sValue;
+    e = this.eValue;
+  }
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var pathsData;
+  var pathData;
+  var totalShapeLength;
+  var totalModifierLength = 0;
+
+  if (e === s) {
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].localShapeCollection.releaseShapes();
+      this.shapes[i].shape._mdf = true;
+      this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
+      if (this._mdf) {
+        this.shapes[i].pathsData.length = 0;
+      }
+    }
+  } else if (!((e === 1 && s === 0) || (e === 0 && s === 1))) {
+    var segments = [];
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
+      if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
+        shapeData.shape.paths = shapeData.localShapeCollection;
+      } else {
+        shapePaths = shapeData.shape.paths;
+        jLen = shapePaths._length;
+        totalShapeLength = 0;
+        if (!shapeData.shape._mdf && shapeData.pathsData.length) {
+          totalShapeLength = shapeData.totalShapeLength;
+        } else {
+          pathsData = this.releasePathsData(shapeData.pathsData);
+          for (j = 0; j < jLen; j += 1) {
+            pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
+            pathsData.push(pathData);
+            totalShapeLength += pathData.totalLength;
+          }
+          shapeData.totalShapeLength = totalShapeLength;
+          shapeData.pathsData = pathsData;
+        }
+
+        totalModifierLength += totalShapeLength;
+        shapeData.shape._mdf = true;
+      }
+    }
+    var shapeS = s;
+    var shapeE = e;
+    var addedLength = 0;
+    var edges;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shapeData = this.shapes[i];
+      if (shapeData.shape._mdf) {
+        localShapeCollection = shapeData.localShapeCollection;
+        localShapeCollection.releaseShapes();
+        // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
+        if (this.m === 2 && len > 1) {
+          edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
+          addedLength += shapeData.totalShapeLength;
+        } else {
+          edges = [[shapeS, shapeE]];
+        }
+        jLen = edges.length;
+        for (j = 0; j < jLen; j += 1) {
+          shapeS = edges[j][0];
+          shapeE = edges[j][1];
+          segments.length = 0;
+          if (shapeE <= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength * shapeE,
+            });
+          } else if (shapeS >= 1) {
+            segments.push({
+              s: shapeData.totalShapeLength * (shapeS - 1),
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          } else {
+            segments.push({
+              s: shapeData.totalShapeLength * shapeS,
+              e: shapeData.totalShapeLength,
+            });
+            segments.push({
+              s: 0,
+              e: shapeData.totalShapeLength * (shapeE - 1),
+            });
+          }
+          var newShapesData = this.addShapes(shapeData, segments[0]);
+          if (segments[0].s !== segments[0].e) {
+            if (segments.length > 1) {
+              var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
+              if (lastShapeInCollection.c) {
+                var lastShape = newShapesData.pop();
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1], lastShape);
+              } else {
+                this.addPaths(newShapesData, localShapeCollection);
+                newShapesData = this.addShapes(shapeData, segments[1]);
+              }
+            }
+            this.addPaths(newShapesData, localShapeCollection);
+          }
+        }
+        shapeData.shape.paths = localShapeCollection;
+      }
+    }
+  } else if (this._mdf) {
+    for (i = 0; i < len; i += 1) {
+      // Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween.
+      // Don't remove this even if it's losing cached info.
+      this.shapes[i].pathsData.length = 0;
+      this.shapes[i].shape._mdf = true;
+    }
+  }
+};
+
+TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
+  var i;
+  var len = newPaths.length;
+  for (i = 0; i < len; i += 1) {
+    localShapeCollection.addShape(newPaths[i]);
+  }
+};
+
+TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
+  shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
+  shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
+  }
+  shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
+  shapePath.setXYAt(points[1], points[5], 'o', pos);
+  shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
+  if (newShape) {
+    shapePath.setXYAt(points[0], points[4], 'v', pos);
+  }
+  shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
+};
+
+TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
+  var pathsData = shapeData.pathsData;
+  var shapePaths = shapeData.shape.paths.shapes;
+  var i;
+  var len = shapeData.shape.paths._length;
+  var j;
+  var jLen;
+  var addedLength = 0;
+  var currentLengthData;
+  var segmentCount;
+  var lengths;
+  var segment;
+  var shapes = [];
+  var initPos;
+  var newShape = true;
+  if (!shapePath) {
+    shapePath = shapePool.newElement();
+    segmentCount = 0;
+    initPos = 0;
+  } else {
+    segmentCount = shapePath._length;
+    initPos = shapePath._length;
+  }
+  shapes.push(shapePath);
+  for (i = 0; i < len; i += 1) {
+    lengths = pathsData[i].lengths;
+    shapePath.c = shapePaths[i].c;
+    jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
+    for (j = 1; j < jLen; j += 1) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
+        addedLength += currentLengthData.addedLength;
+        shapePath.c = false;
+      } else if (addedLength > shapeSegment.e) {
+        shapePath.c = false;
+        break;
+      } else {
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+        addedLength += currentLengthData.addedLength;
+        segmentCount += 1;
+      }
+    }
+    if (shapePaths[i].c && lengths.length) {
+      currentLengthData = lengths[j - 1];
+      if (addedLength <= shapeSegment.e) {
+        var segmentLength = lengths[j - 1].addedLength;
+        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
+          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
+          newShape = false;
+        } else {
+          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
+          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
+          newShape = false;
+          shapePath.c = false;
+        }
+      } else {
+        shapePath.c = false;
+      }
+      addedLength += currentLengthData.addedLength;
+      segmentCount += 1;
+    }
+    if (shapePath._length) {
+      shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
+      shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
+    }
+    if (addedLength > shapeSegment.e) {
+      break;
+    }
+    if (i < len - 1) {
+      shapePath = shapePool.newElement();
+      newShape = true;
+      shapes.push(shapePath);
+      segmentCount = 0;
+    }
+  }
+  return shapes;
+};
+
+function PuckerAndBloatModifier() {}
+extendPrototype([ShapeModifier], PuckerAndBloatModifier);
+PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this._isAnimated = !!this.amount.effectsSequence.length;
+};
+
+PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
+  var percent = amount / 100;
+  var centerPoint = [0, 0];
+  var pathLength = path._length;
+  var i = 0;
+  for (i = 0; i < pathLength; i += 1) {
+    centerPoint[0] += path.v[i][0];
+    centerPoint[1] += path.v[i][1];
+  }
+  centerPoint[0] /= pathLength;
+  centerPoint[1] /= pathLength;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < pathLength; i += 1) {
+    vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
+    vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
+    oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent;
+    oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent;
+    iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent;
+    iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
+    clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
+  }
+  return clonedPath;
+};
+
+PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+const TransformPropertyFactory = (function () {
+  var defaultVector = [0, 0];
+
+  function applyToMatrix(mat) {
+    var _mdf = this._mdf;
+    this.iterateDynamicProperties();
+    this._mdf = this._mdf || _mdf;
+    if (this.a) {
+      mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+    }
+    if (this.s) {
+      mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+    }
+    if (this.sk) {
+      mat.skewFromAxis(-this.sk.v, this.sa.v);
+    }
+    if (this.r) {
+      mat.rotate(-this.r.v);
+    } else {
+      mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+    }
+    if (this.data.p.s) {
+      if (this.data.p.z) {
+        mat.translate(this.px.v, this.py.v, -this.pz.v);
+      } else {
+        mat.translate(this.px.v, this.py.v, 0);
+      }
+    } else {
+      mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+    }
+  }
+  function processKeys(forceRender) {
+    if (this.elem.globalData.frameId === this.frameId) {
+      return;
+    }
+    if (this._isDirty) {
+      this.precalculateMatrix();
+      this._isDirty = false;
+    }
+
+    this.iterateDynamicProperties();
+
+    if (this._mdf || forceRender) {
+      var frameRate;
+      this.v.cloneFromProps(this.pre.props);
+      if (this.appliedTransformations < 1) {
+        this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      }
+      if (this.appliedTransformations < 2) {
+        this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      }
+      if (this.sk && this.appliedTransformations < 3) {
+        this.v.skewFromAxis(-this.sk.v, this.sa.v);
+      }
+      if (this.r && this.appliedTransformations < 4) {
+        this.v.rotate(-this.r.v);
+      } else if (!this.r && this.appliedTransformations < 4) {
+        this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+          .rotateY(this.or.v[1])
+          .rotateX(this.or.v[0]);
+      }
+      if (this.autoOriented) {
+        var v1;
+        var v2;
+        frameRate = this.elem.globalData.frameRate;
+        if (this.p && this.p.keyframes && this.p.getValueAtTime) {
+          if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
+            v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0);
+          } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) {
+            v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0);
+            v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0);
+          } else {
+            v1 = this.p.pv;
+            v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime);
+          }
+        } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) {
+          v1 = [];
+          v2 = [];
+          var px = this.px;
+          var py = this.py;
+          if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
+            v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
+            v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate, 0);
+          } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) {
+            v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate), 0);
+            v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate), 0);
+            v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0);
+            v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0);
+          } else {
+            v1 = [px.pv, py.pv];
+            v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime);
+            v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime);
+          }
+        } else {
+          v2 = defaultVector;
+          v1 = v2;
+        }
+        this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
+      }
+      if (this.data.p && this.data.p.s) {
+        if (this.data.p.z) {
+          this.v.translate(this.px.v, this.py.v, -this.pz.v);
+        } else {
+          this.v.translate(this.px.v, this.py.v, 0);
+        }
+      } else {
+        this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
+      }
+    }
+    this.frameId = this.elem.globalData.frameId;
+  }
+
+  function precalculateMatrix() {
+    this.appliedTransformations = 0;
+    this.pre.reset();
+
+    if (!this.a.effectsSequence.length) {
+      this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
+      this.appliedTransformations = 1;
+    } else {
+      return;
+    }
+    if (!this.s.effectsSequence.length) {
+      this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
+      this.appliedTransformations = 2;
+    } else {
+      return;
+    }
+    if (this.sk) {
+      if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
+        this.pre.skewFromAxis(-this.sk.v, this.sa.v);
+        this.appliedTransformations = 3;
+      } else {
+        return;
+      }
+    }
+    if (this.r) {
+      if (!this.r.effectsSequence.length) {
+        this.pre.rotate(-this.r.v);
+        this.appliedTransformations = 4;
+      }
+    } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) {
+      this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
+        .rotateY(this.or.v[1])
+        .rotateX(this.or.v[0]);
+      this.appliedTransformations = 4;
+    }
+  }
+
+  function autoOrient() {
+    //
+    // var prevP = this.getValueAtTime();
+  }
+
+  function addDynamicProperty(prop) {
+    this._addDynamicProperty(prop);
+    this.elem.addDynamicProperty(prop);
+    this._isDirty = true;
+  }
+
+  function TransformProperty(elem, data, container) {
+    this.elem = elem;
+    this.frameId = -1;
+    this.propType = 'transform';
+    this.data = data;
+    this.v = new Matrix();
+    // Precalculated matrix with non animated properties
+    this.pre = new Matrix();
+    this.appliedTransformations = 0;
+    this.initDynamicPropertyContainer(container || elem);
+    if (data.p && data.p.s) {
+      this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
+      this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
+      if (data.p.z) {
+        this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
+      }
+    } else {
+      this.p = PropertyFactory.getProp(elem, data.p || { k: [0, 0, 0] }, 1, 0, this);
+    }
+    if (data.rx) {
+      this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
+      this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
+      this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
+      if (data.or.k[0].ti) {
+        var i;
+        var len = data.or.k.length;
+        for (i = 0; i < len; i += 1) {
+          data.or.k[i].to = null;
+          data.or.k[i].ti = null;
+        }
+      }
+      this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+      // sh Indicates it needs to be capped between -180 and 180
+      this.or.sh = true;
+    } else {
+      this.r = PropertyFactory.getProp(elem, data.r || { k: 0 }, 0, degToRads, this);
+    }
+    if (data.sk) {
+      this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
+      this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
+    }
+    this.a = PropertyFactory.getProp(elem, data.a || { k: [0, 0, 0] }, 1, 0, this);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: [100, 100, 100] }, 1, 0.01, this);
+    // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
+    if (data.o) {
+      this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
+    } else {
+      this.o = { _mdf: false, v: 1 };
+    }
+    this._isDirty = true;
+    if (!this.dynamicProperties.length) {
+      this.getValue(true);
+    }
+  }
+
+  TransformProperty.prototype = {
+    applyToMatrix: applyToMatrix,
+    getValue: processKeys,
+    precalculateMatrix: precalculateMatrix,
+    autoOrient: autoOrient,
+  };
+
+  extendPrototype([DynamicPropertyContainer], TransformProperty);
+  TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
+  TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
+
+  function getTransformProperty(elem, data, container) {
+    return new TransformProperty(elem, data, container);
+  }
+
+  return {
+    getTransformProperty: getTransformProperty,
+  };
+}());
+
+function RepeaterModifier() {}
+extendPrototype([ShapeModifier], RepeaterModifier);
+
+RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
+  this.o = PropertyFactory.getProp(elem, data.o, 0, null, this);
+  this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this);
+  this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
+  this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
+  this.data = data;
+  if (!this.dynamicProperties.length) {
+    this.getValue(true);
+  }
+  this._isAnimated = !!this.dynamicProperties.length;
+  this.pMatrix = new Matrix();
+  this.rMatrix = new Matrix();
+  this.sMatrix = new Matrix();
+  this.tMatrix = new Matrix();
+  this.matrix = new Matrix();
+};
+
+RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
+  var dir = inv ? -1 : 1;
+  var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
+  var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
+  pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
+  rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  rMatrix.rotate(-transform.r.v * dir * perc);
+  rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+  sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
+  sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
+  sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
+};
+
+RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
+  this.elem = elem;
+  this.arr = arr;
+  this.pos = pos;
+  this.elemsData = elemsData;
+  this._currentCopies = 0;
+  this._elements = [];
+  this._groups = [];
+  this.frameId = -1;
+  this.initDynamicPropertyContainer(elem);
+  this.initModifierProperties(elem, arr[pos]);
+  while (pos > 0) {
+    pos -= 1;
+    // this._elements.unshift(arr.splice(pos,1)[0]);
+    this._elements.unshift(arr[pos]);
+  }
+  if (this.dynamicProperties.length) {
+    this.k = true;
+  } else {
+    this.getValue(true);
+  }
+};
+
+RepeaterModifier.prototype.resetElements = function (elements) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._processed = false;
+    if (elements[i].ty === 'gr') {
+      this.resetElements(elements[i].it);
+    }
+  }
+};
+
+RepeaterModifier.prototype.cloneElements = function (elements) {
+  var newElements = JSON.parse(JSON.stringify(elements));
+  this.resetElements(newElements);
+  return newElements;
+};
+
+RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
+  var i;
+  var len = elements.length;
+  for (i = 0; i < len; i += 1) {
+    elements[i]._render = renderFlag;
+    if (elements[i].ty === 'gr') {
+      this.changeGroupRender(elements[i].it, renderFlag);
+    }
+  }
+};
+
+RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
+  var items;
+  var itemsTransform;
+  var i;
+  var dir;
+  var cont;
+  var hasReloaded = false;
+  if (this._mdf || _isFirstFrame) {
+    var copies = Math.ceil(this.c.v);
+    if (this._groups.length < copies) {
+      while (this._groups.length < copies) {
+        var group = {
+          it: this.cloneElements(this._elements),
+          ty: 'gr',
+        };
+        group.it.push({
+          a: { a: 0, ix: 1, k: [0, 0] }, nm: 'Transform', o: { a: 0, ix: 7, k: 100 }, p: { a: 0, ix: 2, k: [0, 0] }, r: { a: 1, ix: 6, k: [{ s: 0, e: 0, t: 0 }, { s: 0, e: 0, t: 1 }] }, s: { a: 0, ix: 3, k: [100, 100] }, sa: { a: 0, ix: 5, k: 0 }, sk: { a: 0, ix: 4, k: 0 }, ty: 'tr',
+        });
+
+        this.arr.splice(0, 0, group);
+        this._groups.splice(0, 0, group);
+        this._currentCopies += 1;
+      }
+      this.elem.reloadShapes();
+      hasReloaded = true;
+    }
+    cont = 0;
+    var renderFlag;
+    for (i = 0; i <= this._groups.length - 1; i += 1) {
+      renderFlag = cont < copies;
+      this._groups[i]._render = renderFlag;
+      this.changeGroupRender(this._groups[i].it, renderFlag);
+      if (!renderFlag) {
+        var elems = this.elemsData[i].it;
+        var transformData = elems[elems.length - 1];
+        if (transformData.transform.op.v !== 0) {
+          transformData.transform.op._mdf = true;
+          transformData.transform.op.v = 0;
+        } else {
+          transformData.transform.op._mdf = false;
+        }
+      }
+      cont += 1;
+    }
+
+    this._currentCopies = copies;
+    /// /
+
+    var offset = this.o.v;
+    var offsetModulo = offset % 1;
+    var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
+    var pProps = this.pMatrix.props;
+    var rProps = this.rMatrix.props;
+    var sProps = this.sMatrix.props;
+    this.pMatrix.reset();
+    this.rMatrix.reset();
+    this.sMatrix.reset();
+    this.tMatrix.reset();
+    this.matrix.reset();
+    var iteration = 0;
+
+    if (offset > 0) {
+      while (iteration < roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        iteration += 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
+        iteration += offsetModulo;
+      }
+    } else if (offset < 0) {
+      while (iteration > roundOffset) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
+        iteration -= 1;
+      }
+      if (offsetModulo) {
+        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
+        iteration -= offsetModulo;
+      }
+    }
+    i = this.data.m === 1 ? 0 : this._currentCopies - 1;
+    dir = this.data.m === 1 ? 1 : -1;
+    cont = this._currentCopies;
+    var j;
+    var jLen;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      jLen = itemsTransform.length;
+      items[items.length - 1].transform.mProps._mdf = true;
+      items[items.length - 1].transform.op._mdf = true;
+      items[items.length - 1].transform.op.v = this._currentCopies === 1
+        ? this.so.v
+        : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
+
+      if (iteration !== 0) {
+        if ((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)) {
+          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
+        }
+        this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
+        this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
+        this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
+
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+        this.matrix.reset();
+      } else {
+        this.matrix.reset();
+        for (j = 0; j < jLen; j += 1) {
+          itemsTransform[j] = this.matrix.props[j];
+        }
+      }
+      iteration += 1;
+      cont -= 1;
+      i += dir;
+    }
+  } else {
+    cont = this._currentCopies;
+    i = 0;
+    dir = 1;
+    while (cont) {
+      items = this.elemsData[i].it;
+      itemsTransform = items[items.length - 1].transform.mProps.v.props;
+      items[items.length - 1].transform.mProps._mdf = false;
+      items[items.length - 1].transform.op._mdf = false;
+      cont -= 1;
+      i += dir;
+    }
+  }
+  return hasReloaded;
+};
+
+RepeaterModifier.prototype.addShape = function () {};
+
+function RoundCornersModifier() {}
+extendPrototype([ShapeModifier], RoundCornersModifier);
+RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this._isAnimated = !!this.rd.effectsSequence.length;
+};
+
+RoundCornersModifier.prototype.processPath = function (path, round) {
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+  var i;
+  var len = path._length;
+  var currentV;
+  var currentI;
+  var currentO;
+  var closerV;
+  var distance;
+  var newPosPerc;
+  var index = 0;
+  var vX;
+  var vY;
+  var oX;
+  var oY;
+  var iX;
+  var iY;
+  for (i = 0; i < len; i += 1) {
+    currentV = path.v[i];
+    currentO = path.o[i];
+    currentI = path.i[i];
+    if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
+      if ((i === 0 || i === len - 1) && !path.c) {
+        clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
+        /* clonedPath.v[index] = currentV;
+                clonedPath.o[index] = currentO;
+                clonedPath.i[index] = currentI; */
+        index += 1;
+      } else {
+        if (i === 0) {
+          closerV = path.v[len - 1];
+        } else {
+          closerV = path.v[i - 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = iX;
+        iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
+        vY = iY;
+        oX = vX - (vX - currentV[0]) * roundCorner;
+        oY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+
+        if (i === len - 1) {
+          closerV = path.v[0];
+        } else {
+          closerV = path.v[i + 1];
+        }
+        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
+        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
+        oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
+        vX = oX;
+        oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc;
+        vY = oY;
+        iX = vX - (vX - currentV[0]) * roundCorner;
+        iY = vY - (vY - currentV[1]) * roundCorner;
+        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
+        index += 1;
+      }
+    } else {
+      clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index);
+      index += 1;
+    }
+  }
+  return clonedPath;
+};
+
+RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var rd = this.rd.v;
+
+  if (rd !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function floatEqual(a, b) {
+  return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
+}
+
+function floatZero(f) {
+  return Math.abs(f) <= 0.00001;
+}
+
+function lerp(p0, p1, amount) {
+  return p0 * (1 - amount) + p1 * amount;
+}
+
+function lerpPoint(p0, p1, amount) {
+  return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
+}
+
+function quadRoots(a, b, c) {
+  // no root
+  if (a === 0) return [];
+  var s = b * b - 4 * a * c;
+  // Complex roots
+  if (s < 0) return [];
+  var singleRoot = -b / (2 * a);
+  // 1 root
+  if (s === 0) return [singleRoot];
+  var delta = Math.sqrt(s) / (2 * a);
+  // 2 roots
+  return [singleRoot - delta, singleRoot + delta];
+}
+
+function polynomialCoefficients(p0, p1, p2, p3) {
+  return [
+    -p0 + 3 * p1 - 3 * p2 + p3,
+    3 * p0 - 6 * p1 + 3 * p2,
+    -3 * p0 + 3 * p1,
+    p0,
+  ];
+}
+
+function singlePoint(p) {
+  return new PolynomialBezier(p, p, p, p, false);
+}
+
+function PolynomialBezier(p0, p1, p2, p3, linearize) {
+  if (linearize && pointEqual(p0, p1)) {
+    p1 = lerpPoint(p0, p3, 1 / 3);
+  }
+  if (linearize && pointEqual(p2, p3)) {
+    p2 = lerpPoint(p0, p3, 2 / 3);
+  }
+  var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
+  var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
+  this.a = [coeffx[0], coeffy[0]];
+  this.b = [coeffx[1], coeffy[1]];
+  this.c = [coeffx[2], coeffy[2]];
+  this.d = [coeffx[3], coeffy[3]];
+  this.points = [p0, p1, p2, p3];
+}
+PolynomialBezier.prototype.point = function (t) {
+  return [
+    (((this.a[0] * t) + this.b[0]) * t + this.c[0]) * t + this.d[0],
+    (((this.a[1] * t) + this.b[1]) * t + this.c[1]) * t + this.d[1],
+  ];
+};
+PolynomialBezier.prototype.derivative = function (t) {
+  return [
+    (3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0],
+    (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1],
+  ];
+};
+PolynomialBezier.prototype.tangentAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[1], p[0]);
+};
+PolynomialBezier.prototype.normalAngle = function (t) {
+  var p = this.derivative(t);
+  return Math.atan2(p[0], p[1]);
+};
+
+PolynomialBezier.prototype.inflectionPoints = function () {
+  var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
+  if (floatZero(denom)) return [];
+  var tcusp = (-0.5 * (this.a[1] * this.c[0] - this.a[0] * this.c[1])) / denom;
+  var square = tcusp * tcusp - ((1 / 3) * (this.b[1] * this.c[0] - this.b[0] * this.c[1])) / denom;
+  if (square < 0) return [];
+  var root = Math.sqrt(square);
+  if (floatZero(root)) {
+    if (root > 0 && root < 1) return [tcusp];
+    return [];
+  }
+  return [tcusp - root, tcusp + root].filter(function (r) { return r > 0 && r < 1; });
+};
+PolynomialBezier.prototype.split = function (t) {
+  if (t <= 0) return [singlePoint(this.points[0]), this];
+  if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
+  var p10 = lerpPoint(this.points[0], this.points[1], t);
+  var p11 = lerpPoint(this.points[1], this.points[2], t);
+  var p12 = lerpPoint(this.points[2], this.points[3], t);
+  var p20 = lerpPoint(p10, p11, t);
+  var p21 = lerpPoint(p11, p12, t);
+  var p3 = lerpPoint(p20, p21, t);
+  return [
+    new PolynomialBezier(this.points[0], p10, p20, p3, true),
+    new PolynomialBezier(p3, p21, p12, this.points[3], true),
+  ];
+};
+function extrema(bez, comp) {
+  var min = bez.points[0][comp];
+  var max = bez.points[bez.points.length - 1][comp];
+  if (min > max) {
+    var e = max;
+    max = min;
+    min = e;
+  }
+  // Derivative roots to find min/max
+  var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
+  for (var i = 0; i < f.length; i += 1) {
+    if (f[i] > 0 && f[i] < 1) {
+      var val = bez.point(f[i])[comp];
+      if (val < min) min = val;
+      else if (val > max) max = val;
+    }
+  }
+  return {
+    min: min,
+    max: max,
+  };
+}
+PolynomialBezier.prototype.bounds = function () {
+  return {
+    x: extrema(this, 0),
+    y: extrema(this, 1),
+  };
+};
+PolynomialBezier.prototype.boundingBox = function () {
+  var bounds = this.bounds();
+  return {
+    left: bounds.x.min,
+    right: bounds.x.max,
+    top: bounds.y.min,
+    bottom: bounds.y.max,
+    width: bounds.x.max - bounds.x.min,
+    height: bounds.y.max - bounds.y.min,
+    cx: (bounds.x.max + bounds.x.min) / 2,
+    cy: (bounds.y.max + bounds.y.min) / 2,
+  };
+};
+
+function intersectData(bez, t1, t2) {
+  var box = bez.boundingBox();
+  return {
+    cx: box.cx,
+    cy: box.cy,
+    width: box.width,
+    height: box.height,
+    bez: bez,
+    t: (t1 + t2) / 2,
+    t1: t1,
+    t2: t2,
+  };
+}
+function splitData(data) {
+  var split = data.bez.split(0.5);
+  return [
+    intersectData(split[0], data.t1, data.t),
+    intersectData(split[1], data.t, data.t2),
+  ];
+}
+
+function boxIntersect(b1, b2) {
+  return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width
+    && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
+}
+
+function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
+  if (!boxIntersect(d1, d2)) return;
+  if (depth >= maxRecursion || (d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance)) {
+    intersections.push([d1.t, d2.t]);
+    return;
+  }
+  var d1s = splitData(d1);
+  var d2s = splitData(d2);
+  intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[0], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
+  intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
+}
+
+PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
+  if (tolerance === undefined) tolerance = 2;
+  if (maxRecursion === undefined) maxRecursion = 7;
+  var intersections = [];
+  intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
+  return intersections;
+};
+
+PolynomialBezier.shapeSegment = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
+};
+
+PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
+  var nextIndex = (index + 1) % shapePath.length();
+  return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
+};
+
+function crossProduct(a, b) {
+  return [
+    a[1] * b[2] - a[2] * b[1],
+    a[2] * b[0] - a[0] * b[2],
+    a[0] * b[1] - a[1] * b[0],
+  ];
+}
+
+function lineIntersection(start1, end1, start2, end2) {
+  var v1 = [start1[0], start1[1], 1];
+  var v2 = [end1[0], end1[1], 1];
+  var v3 = [start2[0], start2[1], 1];
+  var v4 = [end2[0], end2[1], 1];
+
+  var r = crossProduct(
+    crossProduct(v1, v2),
+    crossProduct(v3, v4)
+  );
+
+  if (floatZero(r[2])) return null;
+
+  return [r[0] / r[2], r[1] / r[2]];
+}
+
+function polarOffset(p, angle, length) {
+  return [
+    p[0] + Math.cos(angle) * length,
+    p[1] - Math.sin(angle) * length,
+  ];
+}
+
+function pointDistance(p1, p2) {
+  return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
+}
+
+function pointEqual(p1, p2) {
+  return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
+}
+
+function ZigZagModifier() {}
+extendPrototype([ShapeModifier], ZigZagModifier);
+ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
+  this.frequency = PropertyFactory.getProp(elem, data.r, 0, null, this);
+  this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
+  this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
+};
+
+function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
+  var angO = angle - Math.PI / 2;
+  var angI = angle + Math.PI / 2;
+  var px = point[0] + Math.cos(angle) * direction * amplitude;
+  var py = point[1] - Math.sin(angle) * direction * amplitude;
+
+  outputBezier.setTripleAt(
+    px,
+    py,
+    px + Math.cos(angO) * outAmplitude,
+    py - Math.sin(angO) * outAmplitude,
+    px + Math.cos(angI) * inAmplitude,
+    py - Math.sin(angI) * inAmplitude,
+    outputBezier.length()
+  );
+}
+
+function getPerpendicularVector(pt1, pt2) {
+  var vector = [
+    pt2[0] - pt1[0],
+    pt2[1] - pt1[1],
+  ];
+  var rot = -Math.PI * 0.5;
+  var rotatedVector = [
+    Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1],
+    Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1],
+  ];
+  return rotatedVector;
+}
+
+function getProjectingAngle(path, cur) {
+  var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
+  var nextIndex = (cur + 1) % path.length();
+  var prevPoint = path.v[prevIndex];
+  var nextPoint = path.v[nextIndex];
+  var pVector = getPerpendicularVector(prevPoint, nextPoint);
+  return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
+}
+
+function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
+  var angle = getProjectingAngle(path, cur);
+  var point = path.v[cur % path._length];
+  var prevPoint = path.v[cur === 0 ? path._length - 1 : cur - 1];
+  var nextPoint = path.v[(cur + 1) % path._length];
+  var prevDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - prevPoint[0], 2) + Math.pow(point[1] - prevPoint[1], 2))
+    : 0;
+  var nextDist = pointType === 2
+    ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2))
+    : 0;
+
+  setPoint(
+    outputBezier,
+    path.v[cur % path._length],
+    angle,
+    direction,
+    amplitude,
+    nextDist / ((frequency + 1) * 2),
+    prevDist / ((frequency + 1) * 2),
+    pointType
+  );
+}
+
+function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
+  for (var i = 0; i < frequency; i += 1) {
+    var t = (i + 1) / (frequency + 1);
+
+    var dist = pointType === 2
+      ? Math.sqrt(Math.pow(segment.points[3][0] - segment.points[0][0], 2) + Math.pow(segment.points[3][1] - segment.points[0][1], 2))
+      : 0;
+
+    var angle = segment.normalAngle(t);
+    var point = segment.point(t);
+    setPoint(
+      outputBezier,
+      point,
+      angle,
+      direction,
+      amplitude,
+      dist / ((frequency + 1) * 2),
+      dist / ((frequency + 1) * 2),
+      pointType
+    );
+
+    direction = -direction;
+  }
+
+  return direction;
+}
+
+ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
+  var count = path._length;
+  var clonedPath = shapePool.newElement();
+  clonedPath.c = path.c;
+
+  if (!path.c) {
+    count -= 1;
+  }
+
+  if (count === 0) return clonedPath;
+
+  var direction = -1;
+  var segment = PolynomialBezier.shapeSegment(path, 0);
+  zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
+
+  for (var i = 0; i < count; i += 1) {
+    direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
+
+    if (i === count - 1 && !path.c) {
+      segment = null;
+    } else {
+      segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
+    }
+
+    zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
+  }
+
+  return clonedPath;
+};
+
+ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amplitude = this.amplitude.v;
+  var frequency = Math.max(0, Math.round(this.frequency.v));
+  var pointType = this.pointsType.v;
+
+  if (amplitude !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function linearOffset(p1, p2, amount) {
+  var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
+  return [
+    polarOffset(p1, angle, amount),
+    polarOffset(p2, angle, amount),
+  ];
+}
+
+function offsetSegment(segment, amount) {
+  var p0; var p1a; var p1b; var p2b; var p2a; var
+    p3;
+  var e;
+  e = linearOffset(segment.points[0], segment.points[1], amount);
+  p0 = e[0];
+  p1a = e[1];
+  e = linearOffset(segment.points[1], segment.points[2], amount);
+  p1b = e[0];
+  p2b = e[1];
+  e = linearOffset(segment.points[2], segment.points[3], amount);
+  p2a = e[0];
+  p3 = e[1];
+  var p1 = lineIntersection(p0, p1a, p1b, p2b);
+  if (p1 === null) p1 = p1a;
+  var p2 = lineIntersection(p2a, p3, p1b, p2b);
+  if (p2 === null) p2 = p2a;
+
+  return new PolynomialBezier(p0, p1, p2, p3);
+}
+
+function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
+  var p0 = seg1.points[3];
+  var p1 = seg2.points[0];
+
+  // Bevel
+  if (lineJoin === 3) return p0;
+
+  // Connected, they don't need a joint
+  if (pointEqual(p0, p1)) return p0;
+
+  // Round
+  if (lineJoin === 2) {
+    var angleOut = -seg1.tangentAngle(1);
+    var angleIn = -seg2.tangentAngle(0) + Math.PI;
+    var center = lineIntersection(
+      p0,
+      polarOffset(p0, angleOut + Math.PI / 2, 100),
+      p1,
+      polarOffset(p1, angleOut + Math.PI / 2, 100)
+    );
+    var radius = center ? pointDistance(center, p0) : pointDistance(p0, p1) / 2;
+
+    var tan = polarOffset(p0, angleOut, 2 * radius * roundCorner);
+    outputBezier.setXYAt(tan[0], tan[1], 'o', outputBezier.length() - 1);
+
+    tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
+    outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
+
+    return p1;
+  }
+
+  // Miter
+  var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
+  var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
+  var intersection = lineIntersection(t0, p0, p1, t1);
+  if (intersection && pointDistance(intersection, p0) < miterLimit) {
+    outputBezier.setTripleAt(
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      intersection[0],
+      intersection[1],
+      outputBezier.length()
+    );
+    return intersection;
+  }
+
+  return p0;
+}
+
+function getIntersection(a, b) {
+  const intersect = a.intersections(b);
+
+  if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
+
+  if (intersect.length) return intersect[0];
+
+  return null;
+}
+
+function pruneSegmentIntersection(a, b) {
+  var outa = a.slice();
+  var outb = b.slice();
+  var intersect = getIntersection(a[a.length - 1], b[0]);
+  if (intersect) {
+    outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
+    outb[0] = b[0].split(intersect[1])[1];
+  }
+  if (a.length > 1 && b.length > 1) {
+    intersect = getIntersection(a[0], b[b.length - 1]);
+    if (intersect) {
+      return [
+        [a[0].split(intersect[0])[0]],
+        [b[b.length - 1].split(intersect[1])[1]],
+      ];
+    }
+  }
+  return [outa, outb];
+}
+
+function pruneIntersections(segments) {
+  var e;
+  for (var i = 1; i < segments.length; i += 1) {
+    e = pruneSegmentIntersection(segments[i - 1], segments[i]);
+    segments[i - 1] = e[0];
+    segments[i] = e[1];
+  }
+
+  if (segments.length > 1) {
+    e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
+    segments[segments.length - 1] = e[0];
+    segments[0] = e[1];
+  }
+
+  return segments;
+}
+
+function offsetSegmentSplit(segment, amount) {
+  /*
+    We split each bezier segment into smaller pieces based
+    on inflection points, this ensures the control point
+    polygon is convex.
+
+    (A cubic bezier can have none, one, or two inflection points)
+  */
+  var flex = segment.inflectionPoints();
+  var left;
+  var right;
+  var split;
+  var mid;
+
+  if (flex.length === 0) {
+    return [offsetSegment(segment, amount)];
+  }
+
+  if (flex.length === 1 || floatEqual(flex[1], 1)) {
+    split = segment.split(flex[0]);
+    left = split[0];
+    right = split[1];
+
+    return [
+      offsetSegment(left, amount),
+      offsetSegment(right, amount),
+    ];
+  }
+
+  split = segment.split(flex[0]);
+  left = split[0];
+  var t = (flex[1] - flex[0]) / (1 - flex[0]);
+  split = split[1].split(t);
+  mid = split[0];
+  right = split[1];
+
+  return [
+    offsetSegment(left, amount),
+    offsetSegment(mid, amount),
+    offsetSegment(right, amount),
+  ];
+}
+
+function OffsetPathModifier() {}
+
+extendPrototype([ShapeModifier], OffsetPathModifier);
+OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
+  this.getValue = this.processKeys;
+  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
+  this.miterLimit = PropertyFactory.getProp(elem, data.ml, 0, null, this);
+  this.lineJoin = data.lj;
+  this._isAnimated = this.amount.effectsSequence.length !== 0;
+};
+
+OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
+  var outputBezier = shapePool.newElement();
+  outputBezier.c = inputBezier.c;
+  var count = inputBezier.length();
+  if (!inputBezier.c) {
+    count -= 1;
+  }
+  var i; var j; var segment;
+  var multiSegments = [];
+
+  for (i = 0; i < count; i += 1) {
+    segment = PolynomialBezier.shapeSegment(inputBezier, i);
+    multiSegments.push(offsetSegmentSplit(segment, amount));
+  }
+
+  if (!inputBezier.c) {
+    for (i = count - 1; i >= 0; i -= 1) {
+      segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
+      multiSegments.push(offsetSegmentSplit(segment, amount));
+    }
+  }
+
+  multiSegments = pruneIntersections(multiSegments);
+
+  // Add bezier segments to the output and apply line joints
+  var lastPoint = null;
+  var lastSeg = null;
+
+  for (i = 0; i < multiSegments.length; i += 1) {
+    var multiSegment = multiSegments[i];
+
+    if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
+
+    lastSeg = multiSegment[multiSegment.length - 1];
+
+    for (j = 0; j < multiSegment.length; j += 1) {
+      segment = multiSegment[j];
+
+      if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
+        outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
+      } else {
+        outputBezier.setTripleAt(
+          segment.points[0][0],
+          segment.points[0][1],
+          segment.points[1][0],
+          segment.points[1][1],
+          segment.points[0][0],
+          segment.points[0][1],
+          outputBezier.length()
+        );
+      }
+
+      outputBezier.setTripleAt(
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[3][0],
+        segment.points[3][1],
+        segment.points[2][0],
+        segment.points[2][1],
+        outputBezier.length()
+      );
+
+      lastPoint = segment.points[3];
+    }
+  }
+
+  if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
+
+  return outputBezier;
+};
+
+OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
+  var shapePaths;
+  var i;
+  var len = this.shapes.length;
+  var j;
+  var jLen;
+  var amount = this.amount.v;
+  var miterLimit = this.miterLimit.v;
+  var lineJoin = this.lineJoin;
+
+  if (amount !== 0) {
+    var shapeData;
+    var localShapeCollection;
+    for (i = 0; i < len; i += 1) {
+      shapeData = this.shapes[i];
+      localShapeCollection = shapeData.localShapeCollection;
+      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
+        localShapeCollection.releaseShapes();
+        shapeData.shape._mdf = true;
+        shapePaths = shapeData.shape.paths.shapes;
+        jLen = shapeData.shape.paths._length;
+        for (j = 0; j < jLen; j += 1) {
+          localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
+        }
+      }
+      shapeData.shape.paths = shapeData.localShapeCollection;
+    }
+  }
+  if (!this.dynamicProperties.length) {
+    this._mdf = false;
+  }
+};
+
+function getFontProperties(fontData) {
+  var styles = fontData.fStyle ? fontData.fStyle.split(' ') : [];
+
+  var fWeight = 'normal'; var
+    fStyle = 'normal';
+  var len = styles.length;
+  var styleName;
+  for (var i = 0; i < len; i += 1) {
+    styleName = styles[i].toLowerCase();
+    switch (styleName) {
+      case 'italic':
+        fStyle = 'italic';
+        break;
+      case 'bold':
+        fWeight = '700';
+        break;
+      case 'black':
+        fWeight = '900';
+        break;
+      case 'medium':
+        fWeight = '500';
+        break;
+      case 'regular':
+      case 'normal':
+        fWeight = '400';
+        break;
+      case 'light':
+      case 'thin':
+        fWeight = '200';
+        break;
+      default:
+        break;
+    }
+  }
+
+  return {
+    style: fStyle,
+    weight: fontData.fWeight || fWeight,
+  };
+}
+
+const FontManager = (function () {
+  var maxWaitingTime = 5000;
+  var emptyChar = {
+    w: 0,
+    size: 0,
+    shapes: [],
+    data: {
+      shapes: [],
+    },
+  };
+  var combinedCharacters = [];
+  // Hindi characters
+  combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366,
+    2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379,
+    2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
+
+  var BLACK_FLAG_CODE_POINT = 127988;
+  var CANCEL_TAG_CODE_POINT = 917631;
+  var A_TAG_CODE_POINT = 917601;
+  var Z_TAG_CODE_POINT = 917626;
+  var VARIATION_SELECTOR_16_CODE_POINT = 65039;
+  var ZERO_WIDTH_JOINER_CODE_POINT = 8205;
+  var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
+  var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
+
+  var surrogateModifiers = [
+    'd83cdffb',
+    'd83cdffc',
+    'd83cdffd',
+    'd83cdffe',
+    'd83cdfff',
+  ];
+
+  function trimFontOptions(font) {
+    var familyArray = font.split(',');
+    var i;
+    var len = familyArray.length;
+    var enabledFamilies = [];
+    for (i = 0; i < len; i += 1) {
+      if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
+        enabledFamilies.push(familyArray[i]);
+      }
+    }
+    return enabledFamilies.join(',');
+  }
+
+  function setUpNode(font, family) {
+    var parentNode = createTag('span');
+    // Node is invisible to screen readers.
+    parentNode.setAttribute('aria-hidden', true);
+    parentNode.style.fontFamily = family;
+    var node = createTag('span');
+    // Characters that vary significantly among different fonts
+    node.innerText = 'giItT1WQy@!-/#';
+    // Visible - so we can measure it - but not on the screen
+    parentNode.style.position = 'absolute';
+    parentNode.style.left = '-10000px';
+    parentNode.style.top = '-10000px';
+    // Large font size makes even subtle changes obvious
+    parentNode.style.fontSize = '300px';
+    // Reset any font properties
+    parentNode.style.fontVariant = 'normal';
+    parentNode.style.fontStyle = 'normal';
+    parentNode.style.fontWeight = 'normal';
+    parentNode.style.letterSpacing = '0';
+    parentNode.appendChild(node);
+    document.body.appendChild(parentNode);
+
+    // Remember width with no applied web font
+    var width = node.offsetWidth;
+    node.style.fontFamily = trimFontOptions(font) + ', ' + family;
+    return { node: node, w: width, parent: parentNode };
+  }
+
+  function checkLoadedFonts() {
+    var i;
+    var len = this.fonts.length;
+    var node;
+    var w;
+    var loadedCount = len;
+    for (i = 0; i < len; i += 1) {
+      if (this.fonts[i].loaded) {
+        loadedCount -= 1;
+      } else if (this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0) {
+        this.fonts[i].loaded = true;
+      } else {
+        node = this.fonts[i].monoCase.node;
+        w = this.fonts[i].monoCase.w;
+        if (node.offsetWidth !== w) {
+          loadedCount -= 1;
+          this.fonts[i].loaded = true;
+        } else {
+          node = this.fonts[i].sansCase.node;
+          w = this.fonts[i].sansCase.w;
+          if (node.offsetWidth !== w) {
+            loadedCount -= 1;
+            this.fonts[i].loaded = true;
+          }
+        }
+        if (this.fonts[i].loaded) {
+          this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
+          this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
+        }
+      }
+    }
+
+    if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
+      setTimeout(this.checkLoadedFontsBinded, 20);
+    } else {
+      setTimeout(this.setIsLoadedBinded, 10);
+    }
+  }
+
+  function createHelper(fontData, def) {
+    var engine = (document.body && def) ? 'svg' : 'canvas';
+    var helper;
+    var fontProps = getFontProperties(fontData);
+    if (engine === 'svg') {
+      var tHelper = createNS('text');
+      tHelper.style.fontSize = '100px';
+      // tHelper.style.fontFamily = fontData.fFamily;
+      tHelper.setAttribute('font-family', fontData.fFamily);
+      tHelper.setAttribute('font-style', fontProps.style);
+      tHelper.setAttribute('font-weight', fontProps.weight);
+      tHelper.textContent = '1';
+      if (fontData.fClass) {
+        tHelper.style.fontFamily = 'inherit';
+        tHelper.setAttribute('class', fontData.fClass);
+      } else {
+        tHelper.style.fontFamily = fontData.fFamily;
+      }
+      def.appendChild(tHelper);
+      helper = tHelper;
+    } else {
+      var tCanvasHelper = new OffscreenCanvas(500, 500).getContext('2d');
+      tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
+      helper = tCanvasHelper;
+    }
+    function measure(text) {
+      if (engine === 'svg') {
+        helper.textContent = text;
+        return helper.getComputedTextLength();
+      }
+      return helper.measureText(text).width;
+    }
+    return {
+      measureText: measure,
+    };
+  }
+
+  function addFonts(fontData, defs) {
+    if (!fontData) {
+      this.isLoaded = true;
+      return;
+    }
+    if (this.chars) {
+      this.isLoaded = true;
+      this.fonts = fontData.list;
+      return;
+    }
+    if (!document.body) {
+      this.isLoaded = true;
+      fontData.list.forEach((data) => {
+        data.helper = createHelper(data);
+        data.cache = {};
+      });
+      this.fonts = fontData.list;
+      return;
+    }
+
+    var fontArr = fontData.list;
+    var i;
+    var len = fontArr.length;
+    var _pendingFonts = len;
+    for (i = 0; i < len; i += 1) {
+      var shouldLoadFont = true;
+      var loadedSelector;
+      var j;
+      fontArr[i].loaded = false;
+      fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
+      fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
+      if (!fontArr[i].fPath) {
+        fontArr[i].loaded = true;
+        _pendingFonts -= 1;
+      } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
+        loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
+
+        if (loadedSelector.length > 0) {
+          shouldLoadFont = false;
+        }
+
+        if (shouldLoadFont) {
+          var s = createTag('style');
+          s.setAttribute('f-forigin', fontArr[i].fOrigin);
+          s.setAttribute('f-origin', fontArr[i].origin);
+          s.setAttribute('f-family', fontArr[i].fFamily);
+          s.type = 'text/css';
+          s.innerText = '@font-face {font-family: ' + fontArr[i].fFamily + "; font-style: normal; src: url('" + fontArr[i].fPath + "');}";
+          defs.appendChild(s);
+        }
+      } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
+        loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var l = createTag('link');
+          l.setAttribute('f-forigin', fontArr[i].fOrigin);
+          l.setAttribute('f-origin', fontArr[i].origin);
+          l.type = 'text/css';
+          l.rel = 'stylesheet';
+          l.href = fontArr[i].fPath;
+          document.body.appendChild(l);
+        }
+      } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
+        loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
+
+        for (j = 0; j < loadedSelector.length; j += 1) {
+          if (fontArr[i].fPath === loadedSelector[j].src) {
+            // Font is already loaded
+            shouldLoadFont = false;
+          }
+        }
+
+        if (shouldLoadFont) {
+          var sc = createTag('link');
+          sc.setAttribute('f-forigin', fontArr[i].fOrigin);
+          sc.setAttribute('f-origin', fontArr[i].origin);
+          sc.setAttribute('rel', 'stylesheet');
+          sc.setAttribute('href', fontArr[i].fPath);
+          defs.appendChild(sc);
+        }
+      }
+      fontArr[i].helper = createHelper(fontArr[i], defs);
+      fontArr[i].cache = {};
+      this.fonts.push(fontArr[i]);
+    }
+    if (_pendingFonts === 0) {
+      this.isLoaded = true;
+    } else {
+      // On some cases even if the font is loaded, it won't load correctly when measuring text on canvas.
+      // Adding this timeout seems to fix it
+      setTimeout(this.checkLoadedFonts.bind(this), 100);
+    }
+  }
+
+  function addChars(chars) {
+    if (!chars) {
+      return;
+    }
+    if (!this.chars) {
+      this.chars = [];
+    }
+    var i;
+    var len = chars.length;
+    var j;
+    var jLen = this.chars.length;
+    var found;
+    for (i = 0; i < len; i += 1) {
+      j = 0;
+      found = false;
+      while (j < jLen) {
+        if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
+          found = true;
+        }
+        j += 1;
+      }
+      if (!found) {
+        this.chars.push(chars[i]);
+        jLen += 1;
+      }
+    }
+  }
+
+  function getCharData(char, style, font) {
+    var i = 0;
+    var len = this.chars.length;
+    while (i < len) {
+      if (this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font) {
+        return this.chars[i];
+      }
+      i += 1;
+    }
+    if (((typeof char === 'string' && char.charCodeAt(0) !== 13) || !char)
+            && console
+            && console.warn // eslint-disable-line no-console
+            && !this._warned
+    ) {
+      this._warned = true;
+      console.warn('Missing character from exported characters list: ', char, style, font); // eslint-disable-line no-console
+    }
+    return emptyChar;
+  }
+
+  function measureText(char, fontName, size) {
+    var fontData = this.getFontByName(fontName);
+    // Using the char instead of char.charCodeAt(0)
+    // to avoid collisions between equal chars
+    var index = char;
+    if (!fontData.cache[index]) {
+      var tHelper = fontData.helper;
+      if (char === ' ') {
+        var doubleSize = tHelper.measureText('|' + char + '|');
+        var singleSize = tHelper.measureText('||');
+        fontData.cache[index] = (doubleSize - singleSize) / 100;
+      } else {
+        fontData.cache[index] = tHelper.measureText(char) / 100;
+      }
+    }
+    return fontData.cache[index] * size;
+  }
+
+  function getFontByName(name) {
+    var i = 0;
+    var len = this.fonts.length;
+    while (i < len) {
+      if (this.fonts[i].fName === name) {
+        return this.fonts[i];
+      }
+      i += 1;
+    }
+    return this.fonts[0];
+  }
+
+  function getCodePoint(string) {
+    var codePoint = 0;
+    var first = string.charCodeAt(0);
+    if (first >= 0xD800 && first <= 0xDBFF) {
+      var second = string.charCodeAt(1);
+      if (second >= 0xDC00 && second <= 0xDFFF) {
+        codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
+      }
+    }
+    return codePoint;
+  }
+
+  // Skin tone modifiers
+  function isModifier(firstCharCode, secondCharCode) {
+    var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
+    return surrogateModifiers.indexOf(sum) !== -1;
+  }
+
+  function isZeroWidthJoiner(charCode) {
+    return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
+  }
+
+  // This codepoint may change the appearance of the preceding character.
+  // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
+  // as a colorful image as compared to a monochrome text variant.
+  function isVariationSelector(charCode) {
+    return charCode === VARIATION_SELECTOR_16_CODE_POINT;
+  }
+
+  // The regional indicator symbols are a set of 26 alphabetic Unicode
+  /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
+  // two-letter country codes in a way that allows optional special treatment.
+  function isRegionalCode(string) {
+    var codePoint = getCodePoint(string);
+    if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
+      return true;
+    }
+    return false;
+  }
+
+  // Some Emoji implementations represent combinations of
+  // two “regional indicator” letters as a single flag symbol.
+  function isFlagEmoji(string) {
+    return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
+  }
+
+  function isCombinedCharacter(char) {
+    return combinedCharacters.indexOf(char) !== -1;
+  }
+
+  // Regional flags start with a BLACK_FLAG_CODE_POINT
+  // folowed by 5 chars in the TAG range
+  // and end with a CANCEL_TAG_CODE_POINT
+  function isRegionalFlag(text, index) {
+    var codePoint = getCodePoint(text.substr(index, 2));
+    if (codePoint !== BLACK_FLAG_CODE_POINT) {
+      return false;
+    }
+    var count = 0;
+    index += 2;
+    while (count < 5) {
+      codePoint = getCodePoint(text.substr(index, 2));
+      if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
+        return false;
+      }
+      count += 1;
+      index += 2;
+    }
+    return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
+  }
+
+  function setIsLoaded() {
+    this.isLoaded = true;
+  }
+
+  var Font = function () {
+    this.fonts = [];
+    this.chars = null;
+    this.typekitLoaded = 0;
+    this.isLoaded = false;
+    this._warned = false;
+    this.initTime = Date.now();
+    this.setIsLoadedBinded = this.setIsLoaded.bind(this);
+    this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
+  };
+  Font.isModifier = isModifier;
+  Font.isZeroWidthJoiner = isZeroWidthJoiner;
+  Font.isFlagEmoji = isFlagEmoji;
+  Font.isRegionalCode = isRegionalCode;
+  Font.isCombinedCharacter = isCombinedCharacter;
+  Font.isRegionalFlag = isRegionalFlag;
+  Font.isVariationSelector = isVariationSelector;
+  Font.BLACK_FLAG_CODE_POINT = BLACK_FLAG_CODE_POINT;
+
+  var fontPrototype = {
+    addChars: addChars,
+    addFonts: addFonts,
+    getCharData: getCharData,
+    getFontByName: getFontByName,
+    measureText: measureText,
+    checkLoadedFonts: checkLoadedFonts,
+    setIsLoaded: setIsLoaded,
+  };
+
+  Font.prototype = fontPrototype;
+
+  return Font;
+}());
+
+function SlotManager(animationData) {
+  this.animationData = animationData;
+}
+SlotManager.prototype.getProp = function (data) {
+  if (this.animationData.slots
+    && this.animationData.slots[data.sid]
+  ) {
+    return Object.assign(data, this.animationData.slots[data.sid].p);
+  }
+  return data;
+};
+
+function slotFactory(animationData) {
+  return new SlotManager(animationData);
+}
+
+function RenderableElement() {
+
+}
+
+RenderableElement.prototype = {
+  initRenderable: function () {
+    // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
+    this.isInRange = false;
+    // layer's display state
+    this.hidden = false;
+    // If layer's transparency equals 0, it can be hidden
+    this.isTransparent = false;
+    // list of animated components
+    this.renderableComponents = [];
+  },
+  addRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) === -1) {
+      this.renderableComponents.push(component);
+    }
+  },
+  removeRenderableComponent: function (component) {
+    if (this.renderableComponents.indexOf(component) !== -1) {
+      this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1);
+    }
+  },
+  prepareRenderableFrame: function (num) {
+    this.checkLayerLimits(num);
+  },
+  checkTransparency: function () {
+    if (this.finalTransform.mProp.o.v <= 0) {
+      if (!this.isTransparent && this.globalData.renderConfig.hideOnTransparent) {
+        this.isTransparent = true;
+        this.hide();
+      }
+    } else if (this.isTransparent) {
+      this.isTransparent = false;
+      this.show();
+    }
+  },
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     *
+     */
+  checkLayerLimits: function (num) {
+    if (this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) {
+      if (this.isInRange !== true) {
+        this.globalData._mdf = true;
+        this._mdf = true;
+        this.isInRange = true;
+        this.show();
+      }
+    } else if (this.isInRange !== false) {
+      this.globalData._mdf = true;
+      this.isInRange = false;
+      this.hide();
+    }
+  },
+  renderRenderable: function () {
+    var i;
+    var len = this.renderableComponents.length;
+    for (i = 0; i < len; i += 1) {
+      this.renderableComponents[i].renderFrame(this._isFirstFrame);
+    }
+    /* this.maskManager.renderFrame(this.finalTransform.mat);
+        this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
+  },
+  sourceRectAtTime: function () {
+    return {
+      top: 0,
+      left: 0,
+      width: 100,
+      height: 100,
+    };
+  },
+  getLayerSize: function () {
+    if (this.data.ty === 5) {
+      return { w: this.data.textData.width, h: this.data.textData.height };
+    }
+    return { w: this.data.width, h: this.data.height };
+  },
+};
+
+const getBlendMode = (function () {
+  var blendModeEnums = {
+    0: 'source-over',
+    1: 'multiply',
+    2: 'screen',
+    3: 'overlay',
+    4: 'darken',
+    5: 'lighten',
+    6: 'color-dodge',
+    7: 'color-burn',
+    8: 'hard-light',
+    9: 'soft-light',
+    10: 'difference',
+    11: 'exclusion',
+    12: 'hue',
+    13: 'saturation',
+    14: 'color',
+    15: 'luminosity',
+  };
+
+  return function (mode) {
+    return blendModeEnums[mode] || '';
+  };
+}());
+
+function SliderEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function AngleEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function ColorEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function PointEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
+}
+function LayerIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function MaskIndexEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function CheckboxEffect(data, elem, container) {
+  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
+}
+function NoValueEffect() {
+  this.p = {};
+}
+
+function EffectsManager(data, element) {
+  var effects = data.ef || [];
+  this.effectElements = [];
+  var i;
+  var len = effects.length;
+  var effectItem;
+  for (i = 0; i < len; i += 1) {
+    effectItem = new GroupEffect(effects[i], element);
+    this.effectElements.push(effectItem);
+  }
+}
+
+function GroupEffect(data, element) {
+  this.init(data, element);
+}
+
+extendPrototype([DynamicPropertyContainer], GroupEffect);
+
+GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
+
+GroupEffect.prototype.init = function (data, element) {
+  this.data = data;
+  this.effectElements = [];
+  this.initDynamicPropertyContainer(element);
+  var i;
+  var len = this.data.ef.length;
+  var eff;
+  var effects = this.data.ef;
+  for (i = 0; i < len; i += 1) {
+    eff = null;
+    switch (effects[i].ty) {
+      case 0:
+        eff = new SliderEffect(effects[i], element, this);
+        break;
+      case 1:
+        eff = new AngleEffect(effects[i], element, this);
+        break;
+      case 2:
+        eff = new ColorEffect(effects[i], element, this);
+        break;
+      case 3:
+        eff = new PointEffect(effects[i], element, this);
+        break;
+      case 4:
+      case 7:
+        eff = new CheckboxEffect(effects[i], element, this);
+        break;
+      case 10:
+        eff = new LayerIndexEffect(effects[i], element, this);
+        break;
+      case 11:
+        eff = new MaskIndexEffect(effects[i], element, this);
+        break;
+      case 5:
+        eff = new EffectsManager(effects[i], element, this);
+        break;
+        // case 6:
+      default:
+        eff = new NoValueEffect(effects[i], element, this);
+        break;
+    }
+    if (eff) {
+      this.effectElements.push(eff);
+    }
+  }
+};
+
+function BaseElement() {
+}
+
+BaseElement.prototype = {
+  checkMasks: function () {
+    if (!this.data.hasMask) {
+      return false;
+    }
+    var i = 0;
+    var len = this.data.masksProperties.length;
+    while (i < len) {
+      if ((this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false)) {
+        return true;
+      }
+      i += 1;
+    }
+    return false;
+  },
+  initExpressions: function () {
+    const expressionsInterfaces = getExpressionInterfaces();
+    if (!expressionsInterfaces) {
+      return;
+    }
+    const LayerExpressionInterface = expressionsInterfaces('layer');
+    const EffectsExpressionInterface = expressionsInterfaces('effects');
+    const ShapeExpressionInterface = expressionsInterfaces('shape');
+    const TextExpressionInterface = expressionsInterfaces('text');
+    const CompExpressionInterface = expressionsInterfaces('comp');
+    this.layerInterface = LayerExpressionInterface(this);
+    if (this.data.hasMask && this.maskManager) {
+      this.layerInterface.registerMaskInterface(this.maskManager);
+    }
+    var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
+    this.layerInterface.registerEffectsInterface(effectsInterface);
+
+    if (this.data.ty === 0 || this.data.xt) {
+      this.compInterface = CompExpressionInterface(this);
+    } else if (this.data.ty === 4) {
+      this.layerInterface.shapeInterface = ShapeExpressionInterface(this.shapesData, this.itemsData, this.layerInterface);
+      this.layerInterface.content = this.layerInterface.shapeInterface;
+    } else if (this.data.ty === 5) {
+      this.layerInterface.textInterface = TextExpressionInterface(this);
+      this.layerInterface.text = this.layerInterface.textInterface;
+    }
+  },
+  setBlendMode: function () {
+    var blendModeValue = getBlendMode(this.data.bm);
+    var elem = this.baseElement || this.layerElement;
+
+    elem.style['mix-blend-mode'] = blendModeValue;
+  },
+  initBaseData: function (data, globalData, comp) {
+    this.globalData = globalData;
+    this.comp = comp;
+    this.data = data;
+    this.layerId = createElementID();
+
+    // Stretch factor for old animations missing this property.
+    if (!this.data.sr) {
+      this.data.sr = 1;
+    }
+    // effects manager
+    this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
+  },
+  getType: function () {
+    return this.type;
+  },
+  sourceRectAtTime: function () {},
+};
+
+/**
+ * @file
+ * Handles element's layer frame update.
+ * Checks layer in point and out point
+ *
+ */
+
+function FrameElement() {}
+
+FrameElement.prototype = {
+  /**
+     * @function
+     * Initializes frame related properties.
+     *
+     */
+  initFrame: function () {
+    // set to true when inpoint is rendered
+    this._isFirstFrame = false;
+    // list of animated properties
+    this.dynamicProperties = [];
+    // If layer has been modified in current tick this will be true
+    this._mdf = false;
+  },
+  /**
+     * @function
+     * Calculates all dynamic values
+     *
+     * @param {number} num
+     * current frame number in Layer's time
+     * @param {boolean} isVisible
+     * if layers is currently in range
+     *
+     */
+  prepareProperties: function (num, isVisible) {
+    var i;
+    var len = this.dynamicProperties.length;
+    for (i = 0; i < len; i += 1) {
+      if (isVisible || (this._isParent && this.dynamicProperties[i].propType === 'transform')) {
+        this.dynamicProperties[i].getValue();
+        if (this.dynamicProperties[i]._mdf) {
+          this.globalData._mdf = true;
+          this._mdf = true;
+        }
+      }
+    }
+  },
+  addDynamicProperty: function (prop) {
+    if (this.dynamicProperties.indexOf(prop) === -1) {
+      this.dynamicProperties.push(prop);
+    }
+  },
+};
+
+function FootageElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.footageData = globalData.imageLoader.getAsset(this.assetData);
+  this.initBaseData(data, globalData, comp);
+}
+
+FootageElement.prototype.prepareFrame = function () {
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
+
+FootageElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+FootageElement.prototype.renderFrame = function () {
+};
+
+FootageElement.prototype.destroy = function () {
+};
+
+FootageElement.prototype.initExpressions = function () {
+  const expressionsInterfaces = getExpressionInterfaces();
+  if (!expressionsInterfaces) {
+    return;
+  }
+  const FootageInterface = expressionsInterfaces('footage');
+  this.layerInterface = FootageInterface(this);
+};
+
+FootageElement.prototype.getFootageData = function () {
+  return this.footageData;
+};
+
+function AudioElement(data, globalData, comp) {
+  this.initFrame();
+  this.initRenderable();
+  this.assetData = globalData.getAssetData(data.refId);
+  this.initBaseData(data, globalData, comp);
+  this._isPlaying = false;
+  this._canPlay = false;
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+  this.audio = this.globalData.audioController.createAudio(assetPath);
+  this._currentTime = 0;
+  this.globalData.audioController.addAudio(this);
+  this._volumeMultiplier = 1;
+  this._volume = 1;
+  this._previousVolume = null;
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+  this.lv = PropertyFactory.getProp(this, data.au && data.au.lv ? data.au.lv : { k: [100] }, 1, 0.01, this);
+}
+
+AudioElement.prototype.prepareFrame = function (num) {
+  this.prepareRenderableFrame(num, true);
+  this.prepareProperties(num, true);
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    this._currentTime = timeRemapped;
+  } else {
+    this._currentTime = num / this.data.sr;
+  }
+  this._volume = this.lv.v[0];
+  var totalVolume = this._volume * this._volumeMultiplier;
+  if (this._previousVolume !== totalVolume) {
+    this._previousVolume = totalVolume;
+    this.audio.volume(totalVolume);
+  }
+};
+
+extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
+
+AudioElement.prototype.renderFrame = function () {
+  if (this.isInRange && this._canPlay) {
+    if (!this._isPlaying) {
+      this.audio.play();
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+      this._isPlaying = true;
+    } else if (!this.audio.playing()
+      || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1
+    ) {
+      this.audio.seek(this._currentTime / this.globalData.frameRate);
+    }
+  }
+};
+
+AudioElement.prototype.show = function () {
+  // this.audio.play()
+};
+
+AudioElement.prototype.hide = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+};
+
+AudioElement.prototype.pause = function () {
+  this.audio.pause();
+  this._isPlaying = false;
+  this._canPlay = false;
+};
+
+AudioElement.prototype.resume = function () {
+  this._canPlay = true;
+};
+
+AudioElement.prototype.setRate = function (rateValue) {
+  this.audio.rate(rateValue);
+};
+
+AudioElement.prototype.volume = function (volumeValue) {
+  this._volumeMultiplier = volumeValue;
+  this._previousVolume = volumeValue * this._volume;
+  this.audio.volume(this._previousVolume);
+};
+
+AudioElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+AudioElement.prototype.destroy = function () {
+};
+
+AudioElement.prototype.sourceRectAtTime = function () {
+};
+
+AudioElement.prototype.initExpressions = function () {
+};
+
+function BaseRenderer() {}
+BaseRenderer.prototype.checkLayers = function (num) {
+  var i;
+  var len = this.layers.length;
+  var data;
+  this.completeLayers = true;
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (!this.elements[i]) {
+      data = this.layers[i];
+      if (data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) {
+        this.buildItem(i);
+      }
+    }
+    this.completeLayers = this.elements[i] ? this.completeLayers : false;
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.createItem = function (layer) {
+  switch (layer.ty) {
+    case 2:
+      return this.createImage(layer);
+    case 0:
+      return this.createComp(layer);
+    case 1:
+      return this.createSolid(layer);
+    case 3:
+      return this.createNull(layer);
+    case 4:
+      return this.createShape(layer);
+    case 5:
+      return this.createText(layer);
+    case 6:
+      return this.createAudio(layer);
+    case 13:
+      return this.createCamera(layer);
+    case 15:
+      return this.createFootage(layer);
+    default:
+      return this.createNull(layer);
+  }
+};
+
+BaseRenderer.prototype.createCamera = function () {
+  throw new Error('You\'re using a 3d camera. Try the html renderer.');
+};
+
+BaseRenderer.prototype.createAudio = function (data) {
+  return new AudioElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.createFootage = function (data) {
+  return new FootageElement(data, this.globalData, this);
+};
+
+BaseRenderer.prototype.buildAllItems = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    this.buildItem(i);
+  }
+  this.checkPendingElements();
+};
+
+BaseRenderer.prototype.includeLayers = function (newLayers) {
+  this.completeLayers = false;
+  var i;
+  var len = newLayers.length;
+  var j;
+  var jLen = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    j = 0;
+    while (j < jLen) {
+      if (this.layers[j].id === newLayers[i].id) {
+        this.layers[j] = newLayers[i];
+        break;
+      }
+      j += 1;
+    }
+  }
+};
+
+BaseRenderer.prototype.setProjectInterface = function (pInterface) {
+  this.globalData.projectInterface = pInterface;
+};
+
+BaseRenderer.prototype.initItems = function () {
+  if (!this.globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+};
+BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
+  var elements = this.elements;
+  var layers = this.layers;
+  var i = 0;
+  var len = layers.length;
+  while (i < len) {
+    if (layers[i].ind == parentName) { // eslint-disable-line eqeqeq
+      if (!elements[i] || elements[i] === true) {
+        this.buildItem(i);
+        this.addPendingElement(element);
+      } else {
+        hierarchy.push(elements[i]);
+        elements[i].setAsParent();
+        if (layers[i].parent !== undefined) {
+          this.buildElementParenting(element, layers[i].parent, hierarchy);
+        } else {
+          element.setHierarchy(hierarchy);
+        }
+      }
+    }
+    i += 1;
+  }
+};
+
+BaseRenderer.prototype.addPendingElement = function (element) {
+  this.pendingElements.push(element);
+};
+
+BaseRenderer.prototype.searchExtraCompositions = function (assets) {
+  var i;
+  var len = assets.length;
+  for (i = 0; i < len; i += 1) {
+    if (assets[i].xt) {
+      var comp = this.createComp(assets[i]);
+      comp.initExpressions();
+      this.globalData.projectInterface.registerComposition(comp);
+    }
+  }
+};
+
+BaseRenderer.prototype.getElementById = function (ind) {
+  var i;
+  var len = this.elements.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i].data.ind === ind) {
+      return this.elements[i];
+    }
+  }
+  return null;
+};
+
+BaseRenderer.prototype.getElementByPath = function (path) {
+  var pathValue = path.shift();
+  var element;
+  if (typeof pathValue === 'number') {
+    element = this.elements[pathValue];
+  } else {
+    var i;
+    var len = this.elements.length;
+    for (i = 0; i < len; i += 1) {
+      if (this.elements[i].data.nm === pathValue) {
+        element = this.elements[i];
+        break;
+      }
+    }
+  }
+  if (path.length === 0) {
+    return element;
+  }
+  return element.getElementByPath(path);
+};
+
+BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
+  this.globalData.fontManager = new FontManager();
+  this.globalData.slotManager = slotFactory(animData);
+  this.globalData.fontManager.addChars(animData.chars);
+  this.globalData.fontManager.addFonts(animData.fonts, fontsContainer);
+  this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
+  this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
+  this.globalData.imageLoader = this.animationItem.imagePreloader;
+  this.globalData.audioController = this.animationItem.audioController;
+  this.globalData.frameId = 0;
+  this.globalData.frameRate = animData.fr;
+  this.globalData.nm = animData.nm;
+  this.globalData.compSize = {
+    w: animData.w,
+    h: animData.h,
+  };
+};
+
+var effectTypes = {
+  TRANSFORM_EFFECT: 'transformEFfect',
+};
+
+function TransformElement() {}
+
+TransformElement.prototype = {
+  initTransform: function () {
+    var mat = new Matrix();
+    this.finalTransform = {
+      mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : { o: 0 },
+      _matMdf: false,
+      _localMatMdf: false,
+      _opMdf: false,
+      mat: mat,
+      localMat: mat,
+      localOpacity: 1,
+    };
+    if (this.data.ao) {
+      this.finalTransform.mProp.autoOriented = true;
+    }
+
+    // TODO: check TYPE 11: Guided elements
+    if (this.data.ty !== 11) {
+      // this.createElements();
+    }
+  },
+  renderTransform: function () {
+    this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
+    this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
+
+    if (this.hierarchy) {
+      var mat;
+      var finalMat = this.finalTransform.mat;
+      var i = 0;
+      var len = this.hierarchy.length;
+      // Checking if any of the transformation matrices in the hierarchy chain has changed.
+      if (!this.finalTransform._matMdf) {
+        while (i < len) {
+          if (this.hierarchy[i].finalTransform.mProp._mdf) {
+            this.finalTransform._matMdf = true;
+            break;
+          }
+          i += 1;
+        }
+      }
+
+      if (this.finalTransform._matMdf) {
+        mat = this.finalTransform.mProp.v.props;
+        finalMat.cloneFromProps(mat);
+        for (i = 0; i < len; i += 1) {
+          finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
+        }
+      }
+    }
+    if (!this.localTransforms || this.finalTransform._matMdf) {
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+    }
+    if (this.finalTransform._opMdf) {
+      this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+    }
+  },
+  renderLocalTransform: function () {
+    if (this.localTransforms) {
+      var i = 0;
+      var len = this.localTransforms.length;
+      this.finalTransform._localMatMdf = this.finalTransform._matMdf;
+      if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
+        while (i < len) {
+          if (this.localTransforms[i]._mdf) {
+            this.finalTransform._localMatMdf = true;
+          }
+          if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
+            this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
+            this.finalTransform._opMdf = true;
+          }
+          i += 1;
+        }
+      }
+      if (this.finalTransform._localMatMdf) {
+        var localMat = this.finalTransform.localMat;
+        this.localTransforms[0].matrix.clone(localMat);
+        for (i = 1; i < len; i += 1) {
+          var lmat = this.localTransforms[i].matrix;
+          localMat.multiply(lmat);
+        }
+        localMat.multiply(this.finalTransform.mat);
+      }
+      if (this.finalTransform._opMdf) {
+        var localOp = this.finalTransform.localOpacity;
+        for (i = 0; i < len; i += 1) {
+          localOp *= this.localTransforms[i].opacity * 0.01;
+        }
+        this.finalTransform.localOpacity = localOp;
+      }
+    }
+  },
+  searchEffectTransforms: function () {
+    if (this.renderableEffectsManager) {
+      var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
+      if (transformEffects.length) {
+        this.localTransforms = [];
+        this.finalTransform.localMat = new Matrix();
+        var i = 0;
+        var len = transformEffects.length;
+        for (i = 0; i < len; i += 1) {
+          this.localTransforms.push(transformEffects[i]);
+        }
+      }
+    }
+  },
+  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;
+    var len = transforms.length;
+    var 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;
+  },
+  mHelper: new Matrix(),
+};
+
+function MaskElement(data, element, globalData) {
+  this.data = data;
+  this.element = element;
+  this.globalData = globalData;
+  this.storedData = [];
+  this.masksProperties = this.data.masksProperties || [];
+  this.maskElement = null;
+  var defs = this.globalData.defs;
+  var i;
+  var len = this.masksProperties ? this.masksProperties.length : 0;
+  this.viewData = createSizedArray(len);
+  this.solidPath = '';
+
+  var path;
+  var properties = this.masksProperties;
+  var count = 0;
+  var currentMasks = [];
+  var j;
+  var jLen;
+  var layerId = createElementID();
+  var rect;
+  var expansor;
+  var feMorph;
+  var x;
+  var maskType = 'clipPath';
+  var maskRef = 'clip-path';
+  for (i = 0; i < len; i += 1) {
+    if ((properties[i].mode !== 'a' && properties[i].mode !== 'n') || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
+      maskType = 'mask';
+      maskRef = 'mask';
+    }
+
+    if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
+      rect = createNS('rect');
+      rect.setAttribute('fill', '#ffffff');
+      rect.setAttribute('width', this.element.comp.data.w || 0);
+      rect.setAttribute('height', this.element.comp.data.h || 0);
+      currentMasks.push(rect);
+    } else {
+      rect = null;
+    }
+
+    path = createNS('path');
+    if (properties[i].mode === 'n') {
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        elem: path,
+        lastPath: '',
+      };
+      defs.appendChild(path);
+    } else {
+      count += 1;
+
+      path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      path.setAttribute('clip-rule', 'nonzero');
+      var filterID;
+
+      if (properties[i].x.k !== 0) {
+        maskType = 'mask';
+        maskRef = 'mask';
+        x = PropertyFactory.getProp(this.element, properties[i].x, 0, null, this.element);
+        filterID = createElementID();
+        expansor = createNS('filter');
+        expansor.setAttribute('id', filterID);
+        feMorph = createNS('feMorphology');
+        feMorph.setAttribute('operator', 'erode');
+        feMorph.setAttribute('in', 'SourceGraphic');
+        feMorph.setAttribute('radius', '0');
+        expansor.appendChild(feMorph);
+        defs.appendChild(expansor);
+        path.setAttribute('stroke', properties[i].mode === 's' ? '#000000' : '#ffffff');
+      } else {
+        feMorph = null;
+        x = null;
+      }
+
+      // TODO move this to a factory or to a constructor
+      this.storedData[i] = {
+        elem: path,
+        x: x,
+        expan: feMorph,
+        lastPath: '',
+        lastOperator: '',
+        filterId: filterID,
+        lastRadius: 0,
+      };
+      if (properties[i].mode === 'i') {
+        jLen = currentMasks.length;
+        var g = createNS('g');
+        for (j = 0; j < jLen; j += 1) {
+          g.appendChild(currentMasks[j]);
+        }
+        var mask = createNS('mask');
+        mask.setAttribute('mask-type', 'alpha');
+        mask.setAttribute('id', layerId + '_' + count);
+        mask.appendChild(path);
+        defs.appendChild(mask);
+        g.setAttribute('mask', 'url(' + getLocationHref() + '#' + layerId + '_' + count + ')');
+
+        currentMasks.length = 0;
+        currentMasks.push(g);
+      } else {
+        currentMasks.push(path);
+      }
+      if (properties[i].inv && !this.solidPath) {
+        this.solidPath = this.createLayerSolidPath();
+      }
+      // TODO move this to a factory or to a constructor
+      this.viewData[i] = {
+        elem: path,
+        lastPath: '',
+        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
+        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
+        invRect: rect,
+      };
+      if (!this.viewData[i].prop.k) {
+        this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
+      }
+    }
+  }
+
+  this.maskElement = createNS(maskType);
+
+  len = currentMasks.length;
+  for (i = 0; i < len; i += 1) {
+    this.maskElement.appendChild(currentMasks[i]);
+  }
+
+  if (count > 0) {
+    this.maskElement.setAttribute('id', layerId);
+    this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
+    defs.appendChild(this.maskElement);
+  }
+  if (this.viewData.length) {
+    this.element.addRenderableComponent(this);
+  }
+}
+
+MaskElement.prototype.getMaskProperty = function (pos) {
+  return this.viewData[pos].prop;
+};
+
+MaskElement.prototype.renderFrame = function (isFirstFrame) {
+  var finalMat = this.element.finalTransform.mat;
+  var i;
+  var len = this.masksProperties.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.viewData[i].prop._mdf || isFirstFrame) {
+      this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
+    }
+    if (this.viewData[i].op._mdf || isFirstFrame) {
+      this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
+    }
+    if (this.masksProperties[i].mode !== 'n') {
+      if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
+        this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
+      }
+      if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
+        var feMorph = this.storedData[i].expan;
+        if (this.storedData[i].x.v < 0) {
+          if (this.storedData[i].lastOperator !== 'erode') {
+            this.storedData[i].lastOperator = 'erode';
+            this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
+          }
+          feMorph.setAttribute('radius', -this.storedData[i].x.v);
+        } else {
+          if (this.storedData[i].lastOperator !== 'dilate') {
+            this.storedData[i].lastOperator = 'dilate';
+            this.storedData[i].elem.setAttribute('filter', null);
+          }
+          this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
+        }
+      }
+    }
+  }
+};
+
+MaskElement.prototype.getMaskelement = function () {
+  return this.maskElement;
+};
+
+MaskElement.prototype.createLayerSolidPath = function () {
+  var path = 'M0,0 ';
+  path += ' h' + this.globalData.compSize.w;
+  path += ' v' + this.globalData.compSize.h;
+  path += ' h-' + this.globalData.compSize.w;
+  path += ' v-' + this.globalData.compSize.h + ' ';
+  return path;
+};
+
+MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
+  var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  var i;
+  var len;
+  len = pathNodes._length;
+  for (i = 1; i < len; i += 1) {
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
+  }
+  // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
+  if (pathNodes.c && len > 1) {
+    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
+  }
+  // pathNodes.__renderedString = pathString;
+
+  if (viewData.lastPath !== pathString) {
+    var pathShapeValue = '';
+    if (viewData.elem) {
+      if (pathNodes.c) {
+        pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
+      }
+      viewData.elem.setAttribute('d', pathShapeValue);
+    }
+    viewData.lastPath = pathString;
+  }
+};
+
+MaskElement.prototype.destroy = function () {
+  this.element = null;
+  this.globalData = null;
+  this.maskElement = null;
+  this.data = null;
+  this.masksProperties = null;
+};
+
+const filtersFactory = (function () {
+  var ob = {};
+  ob.createFilter = createFilter;
+  ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
+
+  function createFilter(filId, skipCoordinates) {
+    var fil = createNS('filter');
+    fil.setAttribute('id', filId);
+    if (skipCoordinates !== true) {
+      fil.setAttribute('filterUnits', 'objectBoundingBox');
+      fil.setAttribute('x', '0%');
+      fil.setAttribute('y', '0%');
+      fil.setAttribute('width', '100%');
+      fil.setAttribute('height', '100%');
+    }
+    return fil;
+  }
+
+  function createAlphaToLuminanceFilter() {
+    var feColorMatrix = createNS('feColorMatrix');
+    feColorMatrix.setAttribute('type', 'matrix');
+    feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+    feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
+    return feColorMatrix;
+  }
+
+  return ob;
+}());
+
+const featureSupport = (function () {
+  var ob = {
+    maskType: true,
+    svgLumaHidden: true,
+    offscreenCanvas: typeof OffscreenCanvas !== 'undefined',
+  };
+  if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
+    ob.maskType = false;
+  }
+  if (/firefox/i.test(navigator.userAgent)) {
+    ob.svgLumaHidden = false;
+  }
+  return ob;
+}());
+
+var registeredEffects = {};
+var idPrefix = 'filter_result_';
+
+function SVGEffects(elem) {
+  var i;
+  var source = 'SourceGraphic';
+  var len = elem.data.ef ? elem.data.ef.length : 0;
+  var filId = createElementID();
+  var fil = filtersFactory.createFilter(filId, true);
+  var count = 0;
+  this.filters = [];
+  var filterManager;
+  for (i = 0; i < len; i += 1) {
+    filterManager = null;
+    var type = elem.data.ef[i].ty;
+    if (registeredEffects[type]) {
+      var Effect = registeredEffects[type].effect;
+      filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
+      source = idPrefix + count;
+      if (registeredEffects[type].countsAsEffect) {
+        count += 1;
+      }
+    }
+    if (filterManager) {
+      this.filters.push(filterManager);
+    }
+  }
+  if (count) {
+    elem.globalData.defs.appendChild(fil);
+    elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+  }
+  if (this.filters.length) {
+    elem.addRenderableComponent(this);
+  }
+}
+
+SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
+  var i;
+  var len = this.filters.length;
+  for (i = 0; i < len; i += 1) {
+    this.filters[i].renderFrame(_isFirstFrame);
+  }
+};
+
+SVGEffects.prototype.getEffects = function (type) {
+  var i;
+  var len = this.filters.length;
+  var effects = [];
+  for (i = 0; i < len; i += 1) {
+    if (this.filters[i].type === type) {
+      effects.push(this.filters[i]);
+    }
+  }
+  return effects;
+};
+
+function registerEffect(id, effect, countsAsEffect) {
+  registeredEffects[id] = {
+    effect,
+    countsAsEffect,
+  };
+}
+
+function SVGBaseElement() {
+}
+
+SVGBaseElement.prototype = {
+  initRendererElement: function () {
+    this.layerElement = createNS('g');
+  },
+  createContainerElements: function () {
+    this.matteElement = createNS('g');
+    this.transformedElement = this.layerElement;
+    this.maskedElement = this.layerElement;
+    this._sizeChanged = false;
+    var layerElementParent = null;
+    // If this layer acts as a mask for the following layer
+    if (this.data.td) {
+      this.matteMasks = {};
+      var gg = createNS('g');
+      gg.setAttribute('id', this.layerId);
+      gg.appendChild(this.layerElement);
+      layerElementParent = gg;
+      this.globalData.defs.appendChild(gg);
+    } else if (this.data.tt) {
+      this.matteElement.appendChild(this.layerElement);
+      layerElementParent = this.matteElement;
+      this.baseElement = this.matteElement;
+    } else {
+      this.baseElement = this.layerElement;
+    }
+    if (this.data.ln) {
+      this.layerElement.setAttribute('id', this.data.ln);
+    }
+    if (this.data.cl) {
+      this.layerElement.setAttribute('class', this.data.cl);
+    }
+    // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
+    if (this.data.ty === 0 && !this.data.hd) {
+      var cp = createNS('clipPath');
+      var pt = createNS('path');
+      pt.setAttribute('d', 'M0,0 L' + this.data.w + ',0 L' + this.data.w + ',' + this.data.h + ' L0,' + this.data.h + 'z');
+      var clipId = createElementID();
+      cp.setAttribute('id', clipId);
+      cp.appendChild(pt);
+      this.globalData.defs.appendChild(cp);
+
+      if (this.checkMasks()) {
+        var cpGroup = createNS('g');
+        cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+        cpGroup.appendChild(this.layerElement);
+        this.transformedElement = cpGroup;
+        if (layerElementParent) {
+          layerElementParent.appendChild(this.transformedElement);
+        } else {
+          this.baseElement = this.transformedElement;
+        }
+      } else {
+        this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
+      }
+    }
+    if (this.data.bm !== 0) {
+      this.setBlendMode();
+    }
+  },
+  renderElement: function () {
+    if (this.finalTransform._localMatMdf) {
+      this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
+    }
+    if (this.finalTransform._opMdf) {
+      this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
+    }
+  },
+  destroyBaseElement: function () {
+    this.layerElement = null;
+    this.matteElement = null;
+    this.maskManager.destroy();
+  },
+  getBaseElement: function () {
+    if (this.data.hd) {
+      return null;
+    }
+    return this.baseElement;
+  },
+  createRenderableComponents: function () {
+    this.maskManager = new MaskElement(this.data, this, this.globalData);
+    this.renderableEffectsManager = new SVGEffects(this);
+    this.searchEffectTransforms();
+  },
+  getMatte: function (matteType) {
+    // This should not be a common case. But for backward compatibility, we'll create the matte object.
+    // It solves animations that have two consecutive layers marked as matte masks.
+    // Which is an undefined behavior in AE.
+    if (!this.matteMasks) {
+      this.matteMasks = {};
+    }
+    if (!this.matteMasks[matteType]) {
+      var id = this.layerId + '_' + matteType;
+      var filId;
+      var fil;
+      var useElement;
+      var gg;
+      if (matteType === 1 || matteType === 3) {
+        var masker = createNS('mask');
+        masker.setAttribute('id', id);
+        masker.setAttribute('mask-type', matteType === 3 ? 'luminance' : 'alpha');
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        masker.appendChild(useElement);
+        this.globalData.defs.appendChild(masker);
+        if (!featureSupport.maskType && matteType === 1) {
+          masker.setAttribute('mask-type', 'luminance');
+          filId = createElementID();
+          fil = filtersFactory.createFilter(filId);
+          this.globalData.defs.appendChild(fil);
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          gg.appendChild(useElement);
+          masker.appendChild(gg);
+          gg.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        }
+      } else if (matteType === 2) {
+        var maskGroup = createNS('mask');
+        maskGroup.setAttribute('id', id);
+        maskGroup.setAttribute('mask-type', 'alpha');
+        var maskGrouper = createNS('g');
+        maskGroup.appendChild(maskGrouper);
+        filId = createElementID();
+        fil = filtersFactory.createFilter(filId);
+        /// /
+        var feCTr = createNS('feComponentTransfer');
+        feCTr.setAttribute('in', 'SourceGraphic');
+        fil.appendChild(feCTr);
+        var feFunc = createNS('feFuncA');
+        feFunc.setAttribute('type', 'table');
+        feFunc.setAttribute('tableValues', '1.0 0.0');
+        feCTr.appendChild(feFunc);
+        /// /
+        this.globalData.defs.appendChild(fil);
+        var alphaRect = createNS('rect');
+        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');
+        alphaRect.setAttribute('opacity', '0');
+        maskGrouper.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
+        maskGrouper.appendChild(alphaRect);
+        useElement = createNS('use');
+        useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
+        maskGrouper.appendChild(useElement);
+        if (!featureSupport.maskType) {
+          maskGroup.setAttribute('mask-type', 'luminance');
+          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
+          gg = createNS('g');
+          maskGrouper.appendChild(alphaRect);
+          gg.appendChild(this.layerElement);
+          maskGrouper.appendChild(gg);
+        }
+        this.globalData.defs.appendChild(maskGroup);
+      }
+      this.matteMasks[matteType] = id;
+    }
+    return this.matteMasks[matteType];
+  },
+  setMatte: function (id) {
+    if (!this.matteElement) {
+      return;
+    }
+    this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+  },
+};
+
+/**
+ * @file
+ * Handles AE's layer parenting property.
+ *
+ */
+
+function HierarchyElement() {}
+
+HierarchyElement.prototype = {
+  /**
+     * @function
+     * Initializes hierarchy properties
+     *
+     */
+  initHierarchy: function () {
+    // element's parent list
+    this.hierarchy = [];
+    // if element is parent of another layer _isParent will be true
+    this._isParent = false;
+    this.checkParenting();
+  },
+  /**
+     * @function
+     * Sets layer's hierarchy.
+     * @param {array} hierarch
+     * layer's parent list
+     *
+     */
+  setHierarchy: function (hierarchy) {
+    this.hierarchy = hierarchy;
+  },
+  /**
+     * @function
+     * Sets layer as parent.
+     *
+     */
+  setAsParent: function () {
+    this._isParent = true;
+  },
+  /**
+     * @function
+     * Searches layer's parenting chain
+     *
+     */
+  checkParenting: function () {
+    if (this.data.parent !== undefined) {
+      this.comp.buildElementParenting(this, this.data.parent, []);
+    }
+  },
+};
+
+function RenderableDOMElement() {}
+
+(function () {
+  var _prototype = {
+    initElement: function (data, globalData, comp) {
+      this.initFrame();
+      this.initBaseData(data, globalData, comp);
+      this.initTransform(data, globalData, comp);
+      this.initHierarchy();
+      this.initRenderable();
+      this.initRendererElement();
+      this.createContainerElements();
+      this.createRenderableComponents();
+      this.createContent();
+      this.hide();
+    },
+    hide: function () {
+      // console.log('HIDE', this);
+      if (!this.hidden && (!this.isInRange || this.isTransparent)) {
+        var elem = this.baseElement || this.layerElement;
+        elem.style.display = 'none';
+        this.hidden = true;
+      }
+    },
+    show: function () {
+      // console.log('SHOW', this);
+      if (this.isInRange && !this.isTransparent) {
+        if (!this.data.hd) {
+          var elem = this.baseElement || this.layerElement;
+          elem.style.display = 'block';
+        }
+        this.hidden = false;
+        this._isFirstFrame = true;
+      }
+    },
+    renderFrame: function () {
+      // If it is exported as hidden (data.hd === true) no need to render
+      // If it is not visible no need to render
+      if (this.data.hd || this.hidden) {
+        return;
+      }
+      this.renderTransform();
+      this.renderRenderable();
+      this.renderLocalTransform();
+      this.renderElement();
+      this.renderInnerContent();
+      if (this._isFirstFrame) {
+        this._isFirstFrame = false;
+      }
+    },
+    renderInnerContent: function () {},
+    prepareFrame: function (num) {
+      this._mdf = false;
+      this.prepareRenderableFrame(num);
+      this.prepareProperties(num, this.isInRange);
+      this.checkTransparency();
+    },
+    destroy: function () {
+      this.innerElem = null;
+      this.destroyBaseElement();
+    },
+  };
+  extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement);
+}());
+
+function IImageElement(data, globalData, comp) {
+  this.assetData = globalData.getAssetData(data.refId);
+  if (this.assetData && this.assetData.sid) {
+    this.assetData = globalData.slotManager.getProp(this.assetData);
+  }
+  this.initElement(data, globalData, comp);
+  this.sourceRect = {
+    top: 0, left: 0, width: this.assetData.w, height: this.assetData.h,
+  };
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
+
+IImageElement.prototype.createContent = function () {
+  var assetPath = this.globalData.getAssetsPath(this.assetData);
+
+  this.innerElem = createNS('image');
+  this.innerElem.setAttribute('width', this.assetData.w + 'px');
+  this.innerElem.setAttribute('height', this.assetData.h + 'px');
+  this.innerElem.setAttribute('preserveAspectRatio', this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio);
+  this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
+
+  this.layerElement.appendChild(this.innerElem);
+};
+
+IImageElement.prototype.sourceRectAtTime = function () {
+  return this.sourceRect;
+};
+
+function ProcessedElement(element, position) {
+  this.elem = element;
+  this.pos = position;
+}
+
+function IShapeElement() {
+}
+
+IShapeElement.prototype = {
+  addShapeToModifiers: function (data) {
+    var i;
+    var len = this.shapeModifiers.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapeModifiers[i].addShape(data);
+    }
+  },
+  isShapeInAnimatedModifiers: function (data) {
+    var i = 0;
+    var len = this.shapeModifiers.length;
+    while (i < len) {
+      if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
+        return true;
+      }
+    }
+    return false;
+  },
+  renderModifiers: function () {
+    if (!this.shapeModifiers.length) {
+      return;
+    }
+    var i;
+    var len = this.shapes.length;
+    for (i = 0; i < len; i += 1) {
+      this.shapes[i].sh.reset();
+    }
+
+    len = this.shapeModifiers.length;
+    var shouldBreakProcess;
+    for (i = len - 1; i >= 0; i -= 1) {
+      shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+      // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+      // TODO: find a better solution for this
+      if (shouldBreakProcess) {
+        break;
+      }
+    }
+  },
+
+  searchProcessedElement: function (elem) {
+    var elements = this.processedElements;
+    var i = 0;
+    var len = elements.length;
+    while (i < len) {
+      if (elements[i].elem === elem) {
+        return elements[i].pos;
+      }
+      i += 1;
+    }
+    return 0;
+  },
+  addProcessedElement: function (elem, pos) {
+    var elements = this.processedElements;
+    var i = elements.length;
+    while (i) {
+      i -= 1;
+      if (elements[i].elem === elem) {
+        elements[i].pos = pos;
+        return;
+      }
+    }
+    elements.push(new ProcessedElement(elem, pos));
+  },
+  prepareFrame: function (num) {
+    this.prepareRenderableFrame(num);
+    this.prepareProperties(num, this.isInRange);
+  },
+};
+
+const lineCapEnum = {
+  1: 'butt',
+  2: 'round',
+  3: 'square',
+};
+
+const lineJoinEnum = {
+  1: 'miter',
+  2: 'round',
+  3: 'bevel',
+};
+
+function SVGShapeData(transformers, level, shape) {
+  this.caches = [];
+  this.styles = [];
+  this.transformers = transformers;
+  this.lStr = '';
+  this.sh = shape;
+  this.lvl = level;
+  // TODO find if there are some cases where _isAnimated can be false.
+  // For now, since shapes add up with other shapes. They have to be calculated every time.
+  // One way of finding out is checking if all styles associated to this shape depend only of this shape
+  this._isAnimated = !!shape.k;
+  // TODO: commenting this for now since all shapes are animated
+  var i = 0;
+  var len = transformers.length;
+  while (i < len) {
+    if (transformers[i].mProps.dynamicProperties.length) {
+      this._isAnimated = true;
+      break;
+    }
+    i += 1;
+  }
+}
+
+SVGShapeData.prototype.setAsAnimated = function () {
+  this._isAnimated = true;
+};
+
+function SVGStyleData(data, level) {
+  this.data = data;
+  this.type = data.ty;
+  this.d = '';
+  this.lvl = level;
+  this._mdf = false;
+  this.closed = data.hd === true;
+  this.pElem = createNS('path');
+  this.msElem = null;
+}
+
+SVGStyleData.prototype.reset = function () {
+  this.d = '';
+  this._mdf = false;
+};
+
+function DashProperty(elem, data, renderer, container) {
+  this.elem = elem;
+  this.frameId = -1;
+  this.dataProps = createSizedArray(data.length);
+  this.renderer = renderer;
+  this.k = false;
+  this.dashStr = '';
+  this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0);
+  this.dashoffset = createTypedArray('float32', 1);
+  this.initDynamicPropertyContainer(container);
+  var i;
+  var len = data.length || 0;
+  var prop;
+  for (i = 0; i < len; i += 1) {
+    prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
+    this.k = prop.k || this.k;
+    this.dataProps[i] = { n: data[i].n, p: prop };
+  }
+  if (!this.k) {
+    this.getValue(true);
+  }
+  this._isAnimated = this.k;
+}
+
+DashProperty.prototype.getValue = function (forceRender) {
+  if (this.elem.globalData.frameId === this.frameId && !forceRender) {
+    return;
+  }
+  this.frameId = this.elem.globalData.frameId;
+  this.iterateDynamicProperties();
+  this._mdf = this._mdf || forceRender;
+  if (this._mdf) {
+    var i = 0;
+    var len = this.dataProps.length;
+    if (this.renderer === 'svg') {
+      this.dashStr = '';
+    }
+    for (i = 0; i < len; i += 1) {
+      if (this.dataProps[i].n !== 'o') {
+        if (this.renderer === 'svg') {
+          this.dashStr += ' ' + this.dataProps[i].p.v;
+        } else {
+          this.dashArray[i] = this.dataProps[i].p.v;
+        }
+      } else {
+        this.dashoffset[0] = this.dataProps[i].p.v;
+      }
+    }
+  }
+};
+extendPrototype([DynamicPropertyContainer], DashProperty);
+
+function SVGStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
+
+function SVGFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
+
+function SVGNoStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.style = styleOb;
+}
+
+extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
+
+function GradientProperty(elem, data, container) {
+  this.data = data;
+  this.c = createTypedArray('uint8c', data.p * 4);
+  var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p * 4) : data.k.k.length - data.p * 4;
+  this.o = createTypedArray('float32', cLength);
+  this._cmdf = false;
+  this._omdf = false;
+  this._collapsable = this.checkCollapsable();
+  this._hasOpacity = cLength;
+  this.initDynamicPropertyContainer(container);
+  this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this);
+  this.k = this.prop.k;
+  this.getValue(true);
+}
+
+GradientProperty.prototype.comparePoints = function (values, points) {
+  var i = 0;
+  var len = this.o.length / 2;
+  var diff;
+  while (i < len) {
+    diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
+    if (diff > 0.01) {
+      return false;
+    }
+    i += 1;
+  }
+  return true;
+};
+
+GradientProperty.prototype.checkCollapsable = function () {
+  if (this.o.length / 2 !== this.c.length / 4) {
+    return false;
+  }
+  if (this.data.k.k[0].s) {
+    var i = 0;
+    var len = this.data.k.k.length;
+    while (i < len) {
+      if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
+        return false;
+      }
+      i += 1;
+    }
+  } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
+    return false;
+  }
+  return true;
+};
+
+GradientProperty.prototype.getValue = function (forceRender) {
+  this.prop.getValue();
+  this._mdf = false;
+  this._cmdf = false;
+  this._omdf = false;
+  if (this.prop._mdf || forceRender) {
+    var i;
+    var len = this.data.p * 4;
+    var mult;
+    var val;
+    for (i = 0; i < len; i += 1) {
+      mult = i % 4 === 0 ? 100 : 255;
+      val = Math.round(this.prop.v[i] * mult);
+      if (this.c[i] !== val) {
+        this.c[i] = val;
+        this._cmdf = !forceRender;
+      }
+    }
+    if (this.o.length) {
+      len = this.prop.v.length;
+      for (i = this.data.p * 4; i < len; i += 1) {
+        mult = i % 2 === 0 ? 100 : 1;
+        val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
+        if (this.o[i - this.data.p * 4] !== val) {
+          this.o[i - this.data.p * 4] = val;
+          this._omdf = !forceRender;
+        }
+      }
+    }
+    this._mdf = !forceRender;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], GradientProperty);
+
+function SVGGradientFillStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.initGradientData(elem, data, styleOb);
+}
+
+SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
+  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
+  this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
+  this.e = PropertyFactory.getProp(elem, data.e, 1, null, this);
+  this.h = PropertyFactory.getProp(elem, data.h || { k: 0 }, 0, 0.01, this);
+  this.a = PropertyFactory.getProp(elem, data.a || { k: 0 }, 0, degToRads, this);
+  this.g = new GradientProperty(elem, data.g, this);
+  this.style = styleOb;
+  this.stops = [];
+  this.setGradientData(styleOb.pElem, data);
+  this.setGradientOpacity(data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+};
+
+SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
+  var gradientId = createElementID();
+  var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+  gfill.setAttribute('id', gradientId);
+  gfill.setAttribute('spreadMethod', 'pad');
+  gfill.setAttribute('gradientUnits', 'userSpaceOnUse');
+  var stops = [];
+  var stop;
+  var j;
+  var jLen;
+  jLen = data.g.p * 4;
+  for (j = 0; j < jLen; j += 4) {
+    stop = createNS('stop');
+    gfill.appendChild(stop);
+    stops.push(stop);
+  }
+  pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
+  this.gf = gfill;
+  this.cst = stops;
+};
+
+SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
+  if (this.g._hasOpacity && !this.g._collapsable) {
+    var stop;
+    var j;
+    var jLen;
+    var mask = createNS('mask');
+    var maskElement = createNS('path');
+    mask.appendChild(maskElement);
+    var opacityId = createElementID();
+    var maskId = createElementID();
+    mask.setAttribute('id', maskId);
+    var opFill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
+    opFill.setAttribute('id', opacityId);
+    opFill.setAttribute('spreadMethod', 'pad');
+    opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
+    jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
+    var stops = this.stops;
+    for (j = data.g.p * 4; j < jLen; j += 2) {
+      stop = createNS('stop');
+      stop.setAttribute('stop-color', 'rgb(255,255,255)');
+      opFill.appendChild(stop);
+      stops.push(stop);
+    }
+    maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
+    this.maskId = maskId;
+    styleOb.msElem = maskElement;
+  }
+};
+
+extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
+
+function SVGGradientStrokeStyleData(elem, data, styleOb) {
+  this.initDynamicPropertyContainer(elem);
+  this.getValue = this.iterateDynamicProperties;
+  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
+  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
+  this.initGradientData(elem, data, styleOb);
+  this._isAnimated = !!this._isAnimated;
+}
+
+extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
+
+function ShapeGroupData() {
+  this.it = [];
+  this.prevViewData = [];
+  this.gr = createNS('g');
+}
+
+function SVGTransformData(mProps, op, container) {
+  this.transform = {
+    mProps: mProps,
+    op: op,
+    container: container,
+  };
+  this.elements = [];
+  this._isAnimated = this.transform.mProps.dynamicProperties.length || this.transform.op.effectsSequence.length;
+}
+
+const buildShapeString = function (pathNodes, length, closed, mat) {
+  if (length === 0) {
+    return '';
+  }
+  var _o = pathNodes.o;
+  var _i = pathNodes.i;
+  var _v = pathNodes.v;
+  var i;
+  var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+  for (i = 1; i < length; i += 1) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
+  }
+  if (closed && length) {
+    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
+    shapeString += 'z';
+  }
+  return shapeString;
+};
+
+const SVGElementsRenderer = (function () {
+  var _identityMatrix = new Matrix();
+  var _matrixHelper = new Matrix();
+
+  var ob = {
+    createRenderFunction: createRenderFunction,
+  };
+
+  function createRenderFunction(data) {
+    switch (data.ty) {
+      case 'fl':
+        return renderFill;
+      case 'gf':
+        return renderGradient;
+      case 'gs':
+        return renderGradientStroke;
+      case 'st':
+        return renderStroke;
+      case 'sh':
+      case 'el':
+      case 'rc':
+      case 'sr':
+        return renderPath;
+      case 'tr':
+        return renderContentTransform;
+      case 'no':
+        return renderNoop;
+      default:
+        return null;
+    }
+  }
+
+  function renderContentTransform(styleData, itemData, isFirstFrame) {
+    if (isFirstFrame || itemData.transform.op._mdf) {
+      itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
+    }
+    if (isFirstFrame || itemData.transform.mProps._mdf) {
+      itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
+    }
+  }
+
+  function renderNoop() {
+
+  }
+
+  function renderPath(styleData, itemData, isFirstFrame) {
+    var j;
+    var jLen;
+    var pathStringTransformed;
+    var redraw;
+    var pathNodes;
+    var l;
+    var lLen = itemData.styles.length;
+    var lvl = itemData.lvl;
+    var paths;
+    var mat;
+    var iterations;
+    var k;
+    for (l = 0; l < lLen; l += 1) {
+      redraw = itemData.sh._mdf || isFirstFrame;
+      if (itemData.styles[l].lvl < lvl) {
+        mat = _matrixHelper.reset();
+        iterations = lvl - itemData.styles[l].lvl;
+        k = itemData.transformers.length - 1;
+        while (!redraw && iterations > 0) {
+          redraw = itemData.transformers[k].mProps._mdf || redraw;
+          iterations -= 1;
+          k -= 1;
+        }
+        if (redraw) {
+          iterations = lvl - itemData.styles[l].lvl;
+          k = itemData.transformers.length - 1;
+          while (iterations > 0) {
+            mat.multiply(itemData.transformers[k].mProps.v);
+            iterations -= 1;
+            k -= 1;
+          }
+        }
+      } else {
+        mat = _identityMatrix;
+      }
+      paths = itemData.sh.paths;
+      jLen = paths._length;
+      if (redraw) {
+        pathStringTransformed = '';
+        for (j = 0; j < jLen; j += 1) {
+          pathNodes = paths.shapes[j];
+          if (pathNodes && pathNodes._length) {
+            pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
+          }
+        }
+        itemData.caches[l] = pathStringTransformed;
+      } else {
+        pathStringTransformed = itemData.caches[l];
+      }
+      itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
+      itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
+    }
+  }
+
+  function renderFill(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+
+    if (itemData.c._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
+    }
+  }
+
+  function renderGradientStroke(styleData, itemData, isFirstFrame) {
+    renderGradient(styleData, itemData, isFirstFrame);
+    renderStroke(styleData, itemData, isFirstFrame);
+  }
+
+  function renderGradient(styleData, itemData, isFirstFrame) {
+    var gfill = itemData.gf;
+    var hasOpacity = itemData.g._hasOpacity;
+    var pt1 = itemData.s.v;
+    var pt2 = itemData.e.v;
+
+    if (itemData.o._mdf || isFirstFrame) {
+      var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
+      itemData.style.pElem.setAttribute(attr, itemData.o.v);
+    }
+    if (itemData.s._mdf || isFirstFrame) {
+      var attr1 = styleData.t === 1 ? 'x1' : 'cx';
+      var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
+      gfill.setAttribute(attr1, pt1[0]);
+      gfill.setAttribute(attr2, pt1[1]);
+      if (hasOpacity && !itemData.g._collapsable) {
+        itemData.of.setAttribute(attr1, pt1[0]);
+        itemData.of.setAttribute(attr2, pt1[1]);
+      }
+    }
+    var stops;
+    var i;
+    var len;
+    var stop;
+    if (itemData.g._cmdf || isFirstFrame) {
+      stops = itemData.cst;
+      var cValues = itemData.g.c;
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        stop.setAttribute('offset', cValues[i * 4] + '%');
+        stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
+      }
+    }
+    if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
+      var oValues = itemData.g.o;
+      if (itemData.g._collapsable) {
+        stops = itemData.cst;
+      } else {
+        stops = itemData.ost;
+      }
+      len = stops.length;
+      for (i = 0; i < len; i += 1) {
+        stop = stops[i];
+        if (!itemData.g._collapsable) {
+          stop.setAttribute('offset', oValues[i * 2] + '%');
+        }
+        stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
+      }
+    }
+    if (styleData.t === 1) {
+      if (itemData.e._mdf || isFirstFrame) {
+        gfill.setAttribute('x2', pt2[0]);
+        gfill.setAttribute('y2', pt2[1]);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('x2', pt2[0]);
+          itemData.of.setAttribute('y2', pt2[1]);
+        }
+      }
+    } else {
+      var rad;
+      if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
+        rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        gfill.setAttribute('r', rad);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('r', rad);
+        }
+      }
+      if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (!rad) {
+          rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
+        }
+        var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
+
+        var percent = itemData.h.v;
+        if (percent >= 1) {
+          percent = 0.99;
+        } else if (percent <= -1) {
+          percent = -0.99;
+        }
+        var dist = rad * percent;
+        var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
+        var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
+        gfill.setAttribute('fx', x);
+        gfill.setAttribute('fy', y);
+        if (hasOpacity && !itemData.g._collapsable) {
+          itemData.of.setAttribute('fx', x);
+          itemData.of.setAttribute('fy', y);
+        }
+      }
+      // gfill.setAttribute('fy','200');
+    }
+  }
+
+  function renderStroke(styleData, itemData, isFirstFrame) {
+    var styleElem = itemData.style;
+    var d = itemData.d;
+    if (d && (d._mdf || isFirstFrame) && d.dashStr) {
+      styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
+      styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
+    }
+    if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
+      styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
+    }
+    if (itemData.o._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
+    }
+    if (itemData.w._mdf || isFirstFrame) {
+      styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
+      if (styleElem.msElem) {
+        styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
+      }
+    }
+  }
+
+  return ob;
+}());
+
+function SVGShapeElement(data, globalData, comp) {
+  // List of drawable elements
+  this.shapes = [];
+  // Full shape data
+  this.shapesData = data.shapes;
+  // List of styles that will be applied to shapes
+  this.stylesList = [];
+  // List of modifiers that will be applied to shapes
+  this.shapeModifiers = [];
+  // List of items in shape tree
+  this.itemsData = [];
+  // List of items in previous shape tree
+  this.processedElements = [];
+  // List of animated components
+  this.animatedContents = [];
+  this.initElement(data, globalData, comp);
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+  // List of elements that have been created
+  this.prevViewData = [];
+  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
+
+SVGShapeElement.prototype.initSecondaryElement = function () {
+};
+
+SVGShapeElement.prototype.identityMatrix = new Matrix();
+
+SVGShapeElement.prototype.buildExpressionInterface = function () {};
+
+SVGShapeElement.prototype.createContent = function () {
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+};
+
+/*
+This method searches for multiple shapes that affect a single element and one of them is animated
+*/
+SVGShapeElement.prototype.filterUniqueShapes = function () {
+  var i;
+  var len = this.shapes.length;
+  var shape;
+  var j;
+  var jLen = this.stylesList.length;
+  var style;
+  var tempShapes = [];
+  var areAnimated = false;
+  for (j = 0; j < jLen; j += 1) {
+    style = this.stylesList[j];
+    areAnimated = false;
+    tempShapes.length = 0;
+    for (i = 0; i < len; i += 1) {
+      shape = this.shapes[i];
+      if (shape.styles.indexOf(style) !== -1) {
+        tempShapes.push(shape);
+        areAnimated = shape._isAnimated || areAnimated;
+      }
+    }
+    if (tempShapes.length > 1 && areAnimated) {
+      this.setShapesAsAnimated(tempShapes);
+    }
+  }
+};
+
+SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
+  var i;
+  var len = shapes.length;
+  for (i = 0; i < len; i += 1) {
+    shapes[i].setAsAnimated();
+  }
+};
+
+SVGShapeElement.prototype.createStyleElement = function (data, level) {
+  // TODO: prevent drawing of hidden styles
+  var elementData;
+  var styleOb = new SVGStyleData(data, level);
+
+  var pathElement = styleOb.pElem;
+  if (data.ty === 'st') {
+    elementData = new SVGStrokeStyleData(this, data, styleOb);
+  } else if (data.ty === 'fl') {
+    elementData = new SVGFillStyleData(this, data, styleOb);
+  } else if (data.ty === 'gf' || data.ty === 'gs') {
+    var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
+    elementData = new GradientConstructor(this, data, styleOb);
+    this.globalData.defs.appendChild(elementData.gf);
+    if (elementData.maskId) {
+      this.globalData.defs.appendChild(elementData.ms);
+      this.globalData.defs.appendChild(elementData.of);
+      pathElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + elementData.maskId + ')');
+    }
+  } else if (data.ty === 'no') {
+    elementData = new SVGNoStyleData(this, data, styleOb);
+  }
+
+  if (data.ty === 'st' || data.ty === 'gs') {
+    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);
+    }
+  }
+
+  if (data.r === 2) {
+    pathElement.setAttribute('fill-rule', 'evenodd');
+  }
+
+  if (data.ln) {
+    pathElement.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    pathElement.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  this.stylesList.push(styleOb);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createGroupElement = function (data) {
+  var elementData = new ShapeGroupData();
+  if (data.ln) {
+    elementData.gr.setAttribute('id', data.ln);
+  }
+  if (data.cl) {
+    elementData.gr.setAttribute('class', data.cl);
+  }
+  if (data.bm) {
+    elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
+  }
+  return elementData;
+};
+
+SVGShapeElement.prototype.createTransformElement = function (data, container) {
+  var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
+  var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
+  var ty = 4;
+  if (data.ty === 'rc') {
+    ty = 5;
+  } else if (data.ty === 'el') {
+    ty = 6;
+  } else if (data.ty === 'sr') {
+    ty = 7;
+  }
+  var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
+  var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
+  this.shapes.push(elementData);
+  this.addShapeToModifiers(elementData);
+  this.addToAnimatedContents(data, elementData);
+  return elementData;
+};
+
+SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
+  var i = 0;
+  var len = this.animatedContents.length;
+  while (i < len) {
+    if (this.animatedContents[i].element === element) {
+      return;
+    }
+    i += 1;
+  }
+  this.animatedContents.push({
+    fn: SVGElementsRenderer.createRenderFunction(data),
+    element: element,
+    data: data,
+  });
+};
+
+SVGShapeElement.prototype.setElementStyles = function (elementData) {
+  var arr = elementData.styles;
+  var j;
+  var jLen = this.stylesList.length;
+  for (j = 0; j < jLen; j += 1) {
+    if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
+      arr.push(this.stylesList[j]);
+    }
+  }
+};
+
+SVGShapeElement.prototype.reloadShapes = function () {
+  this._isFirstFrame = true;
+  var i;
+  var len = this.itemsData.length;
+  for (i = 0; i < len; i += 1) {
+    this.prevViewData[i] = this.itemsData[i];
+  }
+  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
+  this.filterUniqueShapes();
+  len = this.dynamicProperties.length;
+  for (i = 0; i < len; i += 1) {
+    this.dynamicProperties[i].getValue();
+  }
+  this.renderModifiers();
+};
+
+SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
+  var ownTransformers = [].concat(transformers);
+  var i;
+  var len = arr.length - 1;
+  var j;
+  var jLen;
+  var ownStyles = [];
+  var ownModifiers = [];
+  var currentTransform;
+  var modifier;
+  var processedPos;
+  for (i = len; i >= 0; i -= 1) {
+    processedPos = this.searchProcessedElement(arr[i]);
+    if (!processedPos) {
+      arr[i]._render = render;
+    } else {
+      itemsData[i] = prevViewData[processedPos - 1];
+    }
+    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
+      if (!processedPos) {
+        itemsData[i] = this.createStyleElement(arr[i], level);
+      } else {
+        itemsData[i].style.closed = arr[i].hd;
+      }
+      if (arr[i]._render) {
+        if (itemsData[i].style.pElem.parentNode !== container) {
+          container.appendChild(itemsData[i].style.pElem);
+        }
+      }
+      ownStyles.push(itemsData[i].style);
+    } else if (arr[i].ty === 'gr') {
+      if (!processedPos) {
+        itemsData[i] = this.createGroupElement(arr[i]);
+      } else {
+        jLen = itemsData[i].it.length;
+        for (j = 0; j < jLen; j += 1) {
+          itemsData[i].prevViewData[j] = itemsData[i].it[j];
+        }
+      }
+      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
+      if (arr[i]._render) {
+        if (itemsData[i].gr.parentNode !== container) {
+          container.appendChild(itemsData[i].gr);
+        }
+      }
+    } else if (arr[i].ty === 'tr') {
+      if (!processedPos) {
+        itemsData[i] = this.createTransformElement(arr[i], container);
+      }
+      currentTransform = itemsData[i].transform;
+      ownTransformers.push(currentTransform);
+    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
+      if (!processedPos) {
+        itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
+      }
+      this.setElementStyles(itemsData[i]);
+    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        modifier.init(this, arr[i]);
+        itemsData[i] = modifier;
+        this.shapeModifiers.push(modifier);
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = false;
+      }
+      ownModifiers.push(modifier);
+    } else if (arr[i].ty === 'rp') {
+      if (!processedPos) {
+        modifier = ShapeModifiers.getModifier(arr[i].ty);
+        itemsData[i] = modifier;
+        modifier.init(this, arr, i, itemsData);
+        this.shapeModifiers.push(modifier);
+        render = false;
+      } else {
+        modifier = itemsData[i];
+        modifier.closed = true;
+      }
+      ownModifiers.push(modifier);
+    }
+    this.addProcessedElement(arr[i], i + 1);
+  }
+  len = ownStyles.length;
+  for (i = 0; i < len; i += 1) {
+    ownStyles[i].closed = true;
+  }
+  len = ownModifiers.length;
+  for (i = 0; i < len; i += 1) {
+    ownModifiers[i].closed = true;
+  }
+};
+
+SVGShapeElement.prototype.renderInnerContent = function () {
+  this.renderModifiers();
+  var i;
+  var len = this.stylesList.length;
+  for (i = 0; i < len; i += 1) {
+    this.stylesList[i].reset();
+  }
+  this.renderShape();
+  for (i = 0; i < len; i += 1) {
+    if (this.stylesList[i]._mdf || this._isFirstFrame) {
+      if (this.stylesList[i].msElem) {
+        this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+        // Adding M0 0 fixes same mask bug on all browsers
+        this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
+      }
+      this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
+    }
+  }
+};
+
+SVGShapeElement.prototype.renderShape = function () {
+  var i;
+  var len = this.animatedContents.length;
+  var animatedContent;
+  for (i = 0; i < len; i += 1) {
+    animatedContent = this.animatedContents[i];
+    if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
+      animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
+    }
+  }
+};
+
+SVGShapeElement.prototype.destroy = function () {
+  this.destroyBaseElement();
+  this.shapesData = null;
+  this.itemsData = null;
+};
+
+function LetterProps(o, sw, sc, fc, m, p) {
+  this.o = o;
+  this.sw = sw;
+  this.sc = sc;
+  this.fc = fc;
+  this.m = m;
+  this.p = p;
+  this._mdf = {
+    o: true,
+    sw: !!sw,
+    sc: !!sc,
+    fc: !!fc,
+    m: true,
+    p: true,
+  };
+}
+
+LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
+  this._mdf.o = false;
+  this._mdf.sw = false;
+  this._mdf.sc = false;
+  this._mdf.fc = false;
+  this._mdf.m = false;
+  this._mdf.p = false;
+  var updated = false;
+
+  if (this.o !== o) {
+    this.o = o;
+    this._mdf.o = true;
+    updated = true;
+  }
+  if (this.sw !== sw) {
+    this.sw = sw;
+    this._mdf.sw = true;
+    updated = true;
+  }
+  if (this.sc !== sc) {
+    this.sc = sc;
+    this._mdf.sc = true;
+    updated = true;
+  }
+  if (this.fc !== fc) {
+    this.fc = fc;
+    this._mdf.fc = true;
+    updated = true;
+  }
+  if (this.m !== m) {
+    this.m = m;
+    this._mdf.m = true;
+    updated = true;
+  }
+  if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
+    this.p = p;
+    this._mdf.p = true;
+    updated = true;
+  }
+  return updated;
+};
+
+function TextProperty(elem, data) {
+  this._frameId = initialDefaultFrame;
+  this.pv = '';
+  this.v = '';
+  this.kf = false;
+  this._isFirstFrame = true;
+  this._mdf = false;
+  if (data.d && data.d.sid) {
+    data.d = elem.globalData.slotManager.getProp(data.d);
+  }
+  this.data = data;
+  this.elem = elem;
+  this.comp = this.elem.comp;
+  this.keysIndex = 0;
+  this.canResize = false;
+  this.minimumFontSize = 1;
+  this.effectsSequence = [];
+  this.currentData = {
+    ascent: 0,
+    boxWidth: this.defaultBoxWidth,
+    f: '',
+    fStyle: '',
+    fWeight: '',
+    fc: '',
+    j: '',
+    justifyOffset: '',
+    l: [],
+    lh: 0,
+    lineWidths: [],
+    ls: '',
+    of: '',
+    s: '',
+    sc: '',
+    sw: 0,
+    t: 0,
+    tr: 0,
+    sz: 0,
+    ps: null,
+    fillColorAnim: false,
+    strokeColorAnim: false,
+    strokeWidthAnim: false,
+    yOffset: 0,
+    finalSize: 0,
+    finalText: [],
+    finalLineHeight: 0,
+    __complete: false,
+
+  };
+  this.copyData(this.currentData, this.data.d.k[0].s);
+
+  if (!this.searchProperty()) {
+    this.completeTextData(this.currentData);
+  }
+}
+
+TextProperty.prototype.defaultBoxWidth = [0, 0];
+
+TextProperty.prototype.copyData = function (obj, data) {
+  for (var s in data) {
+    if (Object.prototype.hasOwnProperty.call(data, s)) {
+      obj[s] = data[s];
+    }
+  }
+  return obj;
+};
+
+TextProperty.prototype.setCurrentData = function (data) {
+  if (!data.__complete) {
+    this.completeTextData(data);
+  }
+  this.currentData = data;
+  this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
+  this._mdf = true;
+};
+
+TextProperty.prototype.searchProperty = function () {
+  return this.searchKeyframes();
+};
+
+TextProperty.prototype.searchKeyframes = function () {
+  this.kf = this.data.d.k.length > 1;
+  if (this.kf) {
+    this.addEffect(this.getKeyframeValue.bind(this));
+  }
+  return this.kf;
+};
+
+TextProperty.prototype.addEffect = function (effectFunction) {
+  this.effectsSequence.push(effectFunction);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.getValue = function (_finalValue) {
+  if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
+    return;
+  }
+  this.currentData.t = this.data.d.k[this.keysIndex].s.t;
+  var currentValue = this.currentData;
+  var currentIndex = this.keysIndex;
+  if (this.lock) {
+    this.setCurrentData(this.currentData);
+    return;
+  }
+  this.lock = true;
+  this._mdf = false;
+  var i; var
+    len = this.effectsSequence.length;
+  var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
+  for (i = 0; i < len; i += 1) {
+    // Checking if index changed to prevent creating a new object every time the expression updates.
+    if (currentIndex !== this.keysIndex) {
+      finalValue = this.effectsSequence[i](finalValue, finalValue.t);
+    } else {
+      finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
+    }
+  }
+  if (currentValue !== finalValue) {
+    this.setCurrentData(finalValue);
+  }
+  this.v = this.currentData;
+  this.pv = this.v;
+  this.lock = false;
+  this.frameId = this.elem.globalData.frameId;
+};
+
+TextProperty.prototype.getKeyframeValue = function () {
+  var textKeys = this.data.d.k;
+  var frameNum = this.elem.comp.renderedFrame;
+  var i = 0; var
+    len = textKeys.length;
+  while (i <= len - 1) {
+    if (i === len - 1 || textKeys[i + 1].t > frameNum) {
+      break;
+    }
+    i += 1;
+  }
+  if (this.keysIndex !== i) {
+    this.keysIndex = i;
+  }
+  return this.data.d.k[this.keysIndex].s;
+};
+
+TextProperty.prototype.buildFinalText = function (text) {
+  var charactersArray = [];
+  var i = 0;
+  var len = text.length;
+  var charCode;
+  var secondCharCode;
+  var shouldCombine = false;
+  var shouldCombineNext = false;
+  var currentChars = '';
+  while (i < len) {
+    shouldCombine = shouldCombineNext;
+    shouldCombineNext = false;
+    charCode = text.charCodeAt(i);
+    currentChars = text.charAt(i);
+    if (FontManager.isCombinedCharacter(charCode)) {
+      shouldCombine = true;
+      // It's a potential surrogate pair (this is the High surrogate)
+    } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+      if (FontManager.isRegionalFlag(text, i)) {
+        currentChars = text.substr(i, 14);
+      } else {
+        secondCharCode = text.charCodeAt(i + 1);
+        // It's a surrogate pair (this is the Low surrogate)
+        if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
+          if (FontManager.isModifier(charCode, secondCharCode)) {
+            currentChars = text.substr(i, 2);
+            shouldCombine = true;
+          } else if (FontManager.isFlagEmoji(text.substr(i, 4))) {
+            currentChars = text.substr(i, 4);
+          } else {
+            currentChars = text.substr(i, 2);
+          }
+        }
+      }
+    } else if (charCode > 0xDBFF) {
+      secondCharCode = text.charCodeAt(i + 1);
+      if (FontManager.isVariationSelector(charCode)) {
+        shouldCombine = true;
+      }
+    } else if (FontManager.isZeroWidthJoiner(charCode)) {
+      shouldCombine = true;
+      shouldCombineNext = true;
+    }
+    if (shouldCombine) {
+      charactersArray[charactersArray.length - 1] += currentChars;
+      shouldCombine = false;
+    } else {
+      charactersArray.push(currentChars);
+    }
+    i += currentChars.length;
+  }
+  return charactersArray;
+};
+
+TextProperty.prototype.completeTextData = function (documentData) {
+  documentData.__complete = true;
+  var fontManager = this.elem.globalData.fontManager;
+  var data = this.data;
+  var letters = [];
+  var i; var
+    len;
+  var newLineFlag; var index = 0; var
+    val;
+  var anchorGrouping = data.m.g;
+  var currentSize = 0; var currentPos = 0; var currentLine = 0; var
+    lineWidths = [];
+  var lineWidth = 0;
+  var maxLineWidth = 0;
+  var j; var
+    jLen;
+  var fontData = fontManager.getFontByName(documentData.f);
+  var charData; var
+    cLength = 0;
+
+  var fontProps = getFontProperties(fontData);
+  documentData.fWeight = fontProps.weight;
+  documentData.fStyle = fontProps.style;
+  documentData.finalSize = documentData.s;
+  documentData.finalText = this.buildFinalText(documentData.t);
+  len = documentData.finalText.length;
+  documentData.finalLineHeight = documentData.lh;
+  var trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+  var charCode;
+  if (documentData.sz) {
+    var flag = true;
+    var boxWidth = documentData.sz[0];
+    var boxHeight = documentData.sz[1];
+    var currentHeight; var
+      finalText;
+    while (flag) {
+      finalText = this.buildFinalText(documentData.t);
+      currentHeight = 0;
+      lineWidth = 0;
+      len = finalText.length;
+      trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
+      var lastSpaceIndex = -1;
+      for (i = 0; i < len; i += 1) {
+        charCode = finalText[i].charCodeAt(0);
+        newLineFlag = false;
+        if (finalText[i] === ' ') {
+          lastSpaceIndex = i;
+        } else if (charCode === 13 || charCode === 3) {
+          lineWidth = 0;
+          newLineFlag = true;
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+        }
+        if (fontManager.chars) {
+          charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
+          cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+        } else {
+          // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
+          cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
+        }
+        if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
+          if (lastSpaceIndex === -1) {
+            len += 1;
+          } else {
+            i = lastSpaceIndex;
+          }
+          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
+          finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+          // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
+          lastSpaceIndex = -1;
+          lineWidth = 0;
+        } else {
+          lineWidth += cLength;
+          lineWidth += trackingOffset;
+        }
+      }
+      currentHeight += (fontData.ascent * documentData.finalSize) / 100;
+      if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
+        documentData.finalSize -= 1;
+        documentData.finalLineHeight = (documentData.finalSize * documentData.lh) / documentData.s;
+      } else {
+        documentData.finalText = finalText;
+        len = documentData.finalText.length;
+        flag = false;
+      }
+    }
+  }
+  lineWidth = -trackingOffset;
+  cLength = 0;
+  var uncollapsedSpaces = 0;
+  var currentChar;
+  for (i = 0; i < len; i += 1) {
+    newLineFlag = false;
+    currentChar = documentData.finalText[i];
+    charCode = currentChar.charCodeAt(0);
+    if (charCode === 13 || charCode === 3) {
+      uncollapsedSpaces = 0;
+      lineWidths.push(lineWidth);
+      maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+      lineWidth = -2 * trackingOffset;
+      val = '';
+      newLineFlag = true;
+      currentLine += 1;
+    } else {
+      val = currentChar;
+    }
+    if (fontManager.chars) {
+      charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
+      cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
+    } else {
+      // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
+      // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
+      cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
+    }
+
+    //
+    if (currentChar === ' ') {
+      uncollapsedSpaces += cLength + trackingOffset;
+    } else {
+      lineWidth += cLength + trackingOffset + uncollapsedSpaces;
+      uncollapsedSpaces = 0;
+    }
+    letters.push({
+      l: cLength, an: cLength, add: currentSize, n: newLineFlag, anIndexes: [], val: val, line: currentLine, animatorJustifyOffset: 0,
+    });
+    if (anchorGrouping == 2) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || val === ' ' || i === len - 1) {
+        if (val === '' || val === ' ') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        index += 1;
+        currentSize = 0;
+      }
+    } else if (anchorGrouping == 3) { // eslint-disable-line eqeqeq
+      currentSize += cLength;
+      if (val === '' || i === len - 1) {
+        if (val === '') {
+          currentSize -= cLength;
+        }
+        while (currentPos <= i) {
+          letters[currentPos].an = currentSize;
+          letters[currentPos].ind = index;
+          letters[currentPos].extra = cLength;
+          currentPos += 1;
+        }
+        currentSize = 0;
+        index += 1;
+      }
+    } else {
+      letters[index].ind = index;
+      letters[index].extra = 0;
+      index += 1;
+    }
+  }
+  documentData.l = letters;
+  maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
+  lineWidths.push(lineWidth);
+  if (documentData.sz) {
+    documentData.boxWidth = documentData.sz[0];
+    documentData.justifyOffset = 0;
+  } else {
+    documentData.boxWidth = maxLineWidth;
+    switch (documentData.j) {
+      case 1:
+        documentData.justifyOffset = -documentData.boxWidth;
+        break;
+      case 2:
+        documentData.justifyOffset = -documentData.boxWidth / 2;
+        break;
+      default:
+        documentData.justifyOffset = 0;
+    }
+  }
+  documentData.lineWidths = lineWidths;
+
+  var animators = data.a; var animatorData; var
+    letterData;
+  jLen = animators.length;
+  var based; var ind; var
+    indexes = [];
+  for (j = 0; j < jLen; j += 1) {
+    animatorData = animators[j];
+    if (animatorData.a.sc) {
+      documentData.strokeColorAnim = true;
+    }
+    if (animatorData.a.sw) {
+      documentData.strokeWidthAnim = true;
+    }
+    if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
+      documentData.fillColorAnim = true;
+    }
+    ind = 0;
+    based = animatorData.s.b;
+    for (i = 0; i < len; i += 1) {
+      letterData = letters[i];
+      letterData.anIndexes[j] = ind;
+      if ((based == 1 && letterData.val !== '') || (based == 2 && letterData.val !== '' && letterData.val !== ' ') || (based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1)) || (based == 4 && (letterData.n || i == len - 1))) { // eslint-disable-line eqeqeq
+        if (animatorData.s.rn === 1) {
+          indexes.push(ind);
+        }
+        ind += 1;
+      }
+    }
+    data.a[j].s.totalChars = ind;
+    var currentInd = -1; var
+      newInd;
+    if (animatorData.s.rn === 1) {
+      for (i = 0; i < len; i += 1) {
+        letterData = letters[i];
+        if (currentInd != letterData.anIndexes[j]) { // eslint-disable-line eqeqeq
+          currentInd = letterData.anIndexes[j];
+          newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
+        }
+        letterData.anIndexes[j] = newInd;
+      }
+    }
+  }
+  documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
+  documentData.ls = documentData.ls || 0;
+  documentData.ascent = (fontData.ascent * documentData.finalSize) / 100;
+};
+
+TextProperty.prototype.updateDocumentData = function (newData, index) {
+  index = index === undefined ? this.keysIndex : index;
+  var dData = this.copyData({}, this.data.d.k[index].s);
+  dData = this.copyData(dData, newData);
+  this.data.d.k[index].s = dData;
+  this.recalculate(index);
+  this.setCurrentData(dData);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.recalculate = function (index) {
+  var dData = this.data.d.k[index].s;
+  dData.__complete = false;
+  this.keysIndex = 0;
+  this._isFirstFrame = true;
+  this.getValue(dData);
+};
+
+TextProperty.prototype.canResizeFont = function (_canResize) {
+  this.canResize = _canResize;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
+  this.minimumFontSize = Math.floor(_fontValue) || 1;
+  this.recalculate(this.keysIndex);
+  this.elem.addDynamicProperty(this);
+};
+
+const TextSelectorProp = (function () {
+  var max = Math.max;
+  var min = Math.min;
+  var floor = Math.floor;
+
+  function TextSelectorPropFactory(elem, data) {
+    this._currentTextLength = -1;
+    this.k = false;
+    this.data = data;
+    this.elem = elem;
+    this.comp = elem.comp;
+    this.finalS = 0;
+    this.finalE = 0;
+    this.initDynamicPropertyContainer(elem);
+    this.s = PropertyFactory.getProp(elem, data.s || { k: 0 }, 0, 0, this);
+    if ('e' in data) {
+      this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
+    } else {
+      this.e = { v: 100 };
+    }
+    this.o = PropertyFactory.getProp(elem, data.o || { k: 0 }, 0, 0, this);
+    this.xe = PropertyFactory.getProp(elem, data.xe || { k: 0 }, 0, 0, this);
+    this.ne = PropertyFactory.getProp(elem, data.ne || { k: 0 }, 0, 0, this);
+    this.sm = PropertyFactory.getProp(elem, data.sm || { k: 100 }, 0, 0, this);
+    this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
+    if (!this.dynamicProperties.length) {
+      this.getValue();
+    }
+  }
+
+  TextSelectorPropFactory.prototype = {
+    getMult: function (ind) {
+      if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
+        this.getValue();
+      }
+      var x1 = 0;
+      var y1 = 0;
+      var x2 = 1;
+      var y2 = 1;
+      if (this.ne.v > 0) {
+        x1 = this.ne.v / 100.0;
+      } else {
+        y1 = -this.ne.v / 100.0;
+      }
+      if (this.xe.v > 0) {
+        x2 = 1.0 - this.xe.v / 100.0;
+      } else {
+        y2 = 1.0 + this.xe.v / 100.0;
+      }
+      var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
+
+      var mult = 0;
+      var s = this.finalS;
+      var e = this.finalE;
+      var type = this.data.sh;
+      if (type === 2) {
+        if (e === s) {
+          mult = ind >= e ? 1 : 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+        mult = easer(mult);
+      } else if (type === 3) {
+        if (e === s) {
+          mult = ind >= e ? 0 : 1;
+        } else {
+          mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+        }
+
+        mult = easer(mult);
+      } else if (type === 4) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
+          if (mult < 0.5) {
+            mult *= 2;
+          } else {
+            mult = 1 - 2 * (mult - 0.5);
+          }
+        }
+        mult = easer(mult);
+      } else if (type === 5) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          var tot = e - s;
+          /* ind += 0.5;
+                    mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          var x = -tot / 2 + ind;
+          var a = tot / 2;
+          mult = Math.sqrt(1 - (x * x) / (a * a));
+        }
+        mult = easer(mult);
+      } else if (type === 6) {
+        if (e === s) {
+          mult = 0;
+        } else {
+          ind = min(max(0, ind + 0.5 - s), e - s);
+          mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; // eslint-disable-line
+        }
+        mult = easer(mult);
+      } else {
+        if (ind >= floor(s)) {
+          if (ind - s < 0) {
+            mult = max(0, min(min(e, 1) - (s - ind), 1));
+          } else {
+            mult = max(0, min(e - ind, 1));
+          }
+        }
+        mult = easer(mult);
+      }
+      // Smoothness implementation.
+      // The smoothness represents a reduced range of the original [0; 1] range.
+      // if smoothness is 25%, the new range will be [0.375; 0.625]
+      // Steps are:
+      // - find the lower value of the new range (threshold)
+      // - if multiplier is smaller than that value, floor it to 0
+      // - if it is larger,
+      //     - subtract the threshold
+      //     - divide it by the smoothness (this will return the range to [0; 1])
+      // Note: If it doesn't work on some scenarios, consider applying it before the easer.
+      if (this.sm.v !== 100) {
+        var smoothness = this.sm.v * 0.01;
+        if (smoothness === 0) {
+          smoothness = 0.00000001;
+        }
+        var threshold = 0.5 - smoothness * 0.5;
+        if (mult < threshold) {
+          mult = 0;
+        } else {
+          mult = (mult - threshold) / smoothness;
+          if (mult > 1) {
+            mult = 1;
+          }
+        }
+      }
+      return mult * this.a.v;
+    },
+    getValue: function (newCharsFlag) {
+      this.iterateDynamicProperties();
+      this._mdf = newCharsFlag || this._mdf;
+      this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
+      if (newCharsFlag && this.data.r === 2) {
+        this.e.v = this._currentTextLength;
+      }
+      var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
+      var o = this.o.v / divisor;
+      var s = this.s.v / divisor + o;
+      var e = (this.e.v / divisor) + o;
+      if (s > e) {
+        var _s = s;
+        s = e;
+        e = _s;
+      }
+      this.finalS = s;
+      this.finalE = e;
+    },
+  };
+  extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
+
+  function getTextSelectorProp(elem, data, arr) {
+    return new TextSelectorPropFactory(elem, data, arr);
+  }
+
+  return {
+    getTextSelectorProp: getTextSelectorProp,
+  };
+}());
+
+function TextAnimatorDataProperty(elem, animatorProps, container) {
+  var defaultData = { propType: false };
+  var getProp = PropertyFactory.getProp;
+  var textAnimatorAnimatables = animatorProps.a;
+  this.a = {
+    r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData,
+    rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData,
+    ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData,
+    sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData,
+    sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData,
+    s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData,
+    a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData,
+    o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData,
+    p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData,
+    sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData,
+    sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData,
+    fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData,
+    fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData,
+    fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData,
+    fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData,
+    t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData,
+  };
+
+  this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container);
+  this.s.t = animatorProps.s.t;
+}
+
+function TextAnimatorProperty(textData, renderType, elem) {
+  this._isFirstFrame = true;
+  this._hasMaskedPath = false;
+  this._frameId = -1;
+  this._textData = textData;
+  this._renderType = renderType;
+  this._elem = elem;
+  this._animatorsData = createSizedArray(this._textData.a.length);
+  this._pathData = {};
+  this._moreOptions = {
+    alignment: {},
+  };
+  this.renderedLetters = [];
+  this.lettersChangedFlag = false;
+  this.initDynamicPropertyContainer(elem);
+}
+
+TextAnimatorProperty.prototype.searchProperties = function () {
+  var i;
+  var len = this._textData.a.length;
+  var animatorProps;
+  var getProp = PropertyFactory.getProp;
+  for (i = 0; i < len; i += 1) {
+    animatorProps = this._textData.a[i];
+    this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
+  }
+  if (this._textData.p && 'm' in this._textData.p) {
+    this._pathData = {
+      a: getProp(this._elem, this._textData.p.a, 0, 0, this),
+      f: getProp(this._elem, this._textData.p.f, 0, 0, this),
+      l: getProp(this._elem, this._textData.p.l, 0, 0, this),
+      r: getProp(this._elem, this._textData.p.r, 0, 0, this),
+      p: getProp(this._elem, this._textData.p.p, 0, 0, this),
+      m: this._elem.maskManager.getMaskProperty(this._textData.p.m),
+    };
+    this._hasMaskedPath = true;
+  } else {
+    this._hasMaskedPath = false;
+  }
+  this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
+};
+
+TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
+  this.lettersChangedFlag = lettersChangedFlag;
+  if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
+    return;
+  }
+  this._isFirstFrame = false;
+  var alignment = this._moreOptions.alignment.v;
+  var animators = this._animatorsData;
+  var textData = this._textData;
+  var matrixHelper = this.mHelper;
+  var renderType = this._renderType;
+  var renderedLettersCount = this.renderedLetters.length;
+  var xPos;
+  var yPos;
+  var i;
+  var len;
+  var letters = documentData.l;
+  var pathInfo;
+  var currentLength;
+  var currentPoint;
+  var segmentLength;
+  var flag;
+  var pointInd;
+  var segmentInd;
+  var prevPoint;
+  var points;
+  var segments;
+  var partialLength;
+  var totalLength;
+  var perc;
+  var tanAngle;
+  var mask;
+  if (this._hasMaskedPath) {
+    mask = this._pathData.m;
+    if (!this._pathData.n || this._pathData._mdf) {
+      var paths = mask.v;
+      if (this._pathData.r.v) {
+        paths = paths.reverse();
+      }
+      // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
+      pathInfo = {
+        tLength: 0,
+        segments: [],
+      };
+      len = paths._length - 1;
+      var bezierData;
+      totalLength = 0;
+      for (i = 0; i < len; i += 1) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[i + 1],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      i = len;
+      if (mask.v.c) {
+        bezierData = bez.buildBezierData(paths.v[i],
+          paths.v[0],
+          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
+          [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
+        pathInfo.tLength += bezierData.segmentLength;
+        pathInfo.segments.push(bezierData);
+        totalLength += bezierData.segmentLength;
+      }
+      this._pathData.pi = pathInfo;
+    }
+    pathInfo = this._pathData.pi;
+
+    currentLength = this._pathData.f.v;
+    segmentInd = 0;
+    pointInd = 1;
+    segmentLength = 0;
+    flag = true;
+    segments = pathInfo.segments;
+    if (currentLength < 0 && mask.v.c) {
+      if (pathInfo.tLength < Math.abs(currentLength)) {
+        currentLength = -Math.abs(currentLength) % pathInfo.tLength;
+      }
+      segmentInd = segments.length - 1;
+      points = segments[segmentInd].points;
+      pointInd = points.length - 1;
+      while (currentLength < 0) {
+        currentLength += points[pointInd].partialLength;
+        pointInd -= 1;
+        if (pointInd < 0) {
+          segmentInd -= 1;
+          points = segments[segmentInd].points;
+          pointInd = points.length - 1;
+        }
+      }
+    }
+    points = segments[segmentInd].points;
+    prevPoint = points[pointInd - 1];
+    currentPoint = points[pointInd];
+    partialLength = currentPoint.partialLength;
+  }
+
+  len = letters.length;
+  xPos = 0;
+  yPos = 0;
+  var yOff = documentData.finalSize * 1.2 * 0.714;
+  var firstLine = true;
+  var animatorProps;
+  var animatorSelector;
+  var j;
+  var jLen;
+  var letterValue;
+
+  jLen = animators.length;
+
+  var mult;
+  var ind = -1;
+  var offf;
+  var xPathPos;
+  var yPathPos;
+  var initPathPos = currentLength;
+  var initSegmentInd = segmentInd;
+  var initPointInd = pointInd;
+  var currentLine = -1;
+  var elemOpacity;
+  var sc;
+  var sw;
+  var fc;
+  var k;
+  var letterSw;
+  var letterSc;
+  var letterFc;
+  var letterM = '';
+  var letterP = this.defaultPropsArray;
+  var letterO;
+
+  //
+  if (documentData.j === 2 || documentData.j === 1) {
+    var animatorJustifyOffset = 0;
+    var animatorFirstCharOffset = 0;
+    var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
+    var lastIndex = 0;
+    var isNewLine = true;
+
+    for (i = 0; i < len; i += 1) {
+      if (letters[i].n) {
+        if (animatorJustifyOffset) {
+          animatorJustifyOffset += animatorFirstCharOffset;
+        }
+        while (lastIndex < i) {
+          letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+          lastIndex += 1;
+        }
+        animatorJustifyOffset = 0;
+        isNewLine = true;
+      } else {
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.t.propType) {
+            if (isNewLine && documentData.j === 2) {
+              animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
+            }
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
+            } else {
+              animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult;
+            }
+          }
+        }
+        isNewLine = false;
+      }
+    }
+    if (animatorJustifyOffset) {
+      animatorJustifyOffset += animatorFirstCharOffset;
+    }
+    while (lastIndex < i) {
+      letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
+      lastIndex += 1;
+    }
+  }
+  //
+
+  for (i = 0; i < len; i += 1) {
+    matrixHelper.reset();
+    elemOpacity = 1;
+    if (letters[i].n) {
+      xPos = 0;
+      yPos += documentData.yOffset;
+      yPos += firstLine ? 1 : 0;
+      currentLength = initPathPos;
+      firstLine = false;
+      if (this._hasMaskedPath) {
+        segmentInd = initSegmentInd;
+        pointInd = initPointInd;
+        points = segments[segmentInd].points;
+        prevPoint = points[pointInd - 1];
+        currentPoint = points[pointInd];
+        partialLength = currentPoint.partialLength;
+        segmentLength = 0;
+      }
+      letterM = '';
+      letterFc = '';
+      letterSw = '';
+      letterO = '';
+      letterP = this.defaultPropsArray;
+    } else {
+      if (this._hasMaskedPath) {
+        if (currentLine !== letters[i].line) {
+          switch (documentData.j) {
+            case 1:
+              currentLength += totalLength - documentData.lineWidths[letters[i].line];
+              break;
+            case 2:
+              currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
+              break;
+            default:
+              break;
+          }
+          currentLine = letters[i].line;
+        }
+        if (ind !== letters[i].ind) {
+          if (letters[ind]) {
+            currentLength += letters[ind].extra;
+          }
+          currentLength += letters[i].an / 2;
+          ind = letters[i].ind;
+        }
+        currentLength += (alignment[0] * letters[i].an) * 0.005;
+        var animatorOffset = 0;
+        for (j = 0; j < jLen; j += 1) {
+          animatorProps = animators[j].a;
+          if (animatorProps.p.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.p.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.p.v[0] * mult;
+            }
+          }
+          if (animatorProps.a.propType) {
+            animatorSelector = animators[j].s;
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            if (mult.length) {
+              animatorOffset += animatorProps.a.v[0] * mult[0];
+            } else {
+              animatorOffset += animatorProps.a.v[0] * mult;
+            }
+          }
+        }
+        flag = true;
+        // Force alignment only works with a single line for now
+        if (this._pathData.a.v) {
+          currentLength = letters[0].an * 0.5 + ((totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind) / (len - 1);
+          currentLength += this._pathData.f.v;
+        }
+        while (flag) {
+          if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
+            perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
+            xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
+            yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
+            matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, -(alignment[1] * yOff) * 0.01);
+            flag = false;
+          } else if (points) {
+            segmentLength += currentPoint.partialLength;
+            pointInd += 1;
+            if (pointInd >= points.length) {
+              pointInd = 0;
+              segmentInd += 1;
+              if (!segments[segmentInd]) {
+                if (mask.v.c) {
+                  pointInd = 0;
+                  segmentInd = 0;
+                  points = segments[segmentInd].points;
+                } else {
+                  segmentLength -= currentPoint.partialLength;
+                  points = null;
+                }
+              } else {
+                points = segments[segmentInd].points;
+              }
+            }
+            if (points) {
+              prevPoint = currentPoint;
+              currentPoint = points[pointInd];
+              partialLength = currentPoint.partialLength;
+            }
+          }
+        }
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+      } else {
+        offf = letters[i].an / 2 - letters[i].add;
+        matrixHelper.translate(-offf, 0, 0);
+
+        // Grouping alignment
+        matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, (-alignment[1] * yOff) * 0.01, 0);
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.t.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
+          if (xPos !== 0 || documentData.j !== 0) {
+            if (this._hasMaskedPath) {
+              if (mult.length) {
+                currentLength += animatorProps.t.v * mult[0];
+              } else {
+                currentLength += animatorProps.t.v * mult;
+              }
+            } else if (mult.length) {
+              xPos += animatorProps.t.v * mult[0];
+            } else {
+              xPos += animatorProps.t.v * mult;
+            }
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        sw = documentData.sw || 0;
+      }
+      if (documentData.strokeColorAnim) {
+        if (documentData.sc) {
+          sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
+        } else {
+          sc = [0, 0, 0];
+        }
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.a.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+
+          if (mult.length) {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        if (animatorProps.s.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (mult.length) {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult[0]), 1 + ((animatorProps.s.v[1] - 1) * mult[1]), 1);
+          } else {
+            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult), 1 + ((animatorProps.s.v[1] - 1) * mult), 1);
+          }
+        }
+      }
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+        animatorSelector = animators[j].s;
+        mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+        if (animatorProps.sk.propType) {
+          if (mult.length) {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
+          } else {
+            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
+          }
+        }
+        if (animatorProps.r.propType) {
+          if (mult.length) {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
+          } else {
+            matrixHelper.rotateZ(-animatorProps.r.v * mult);
+          }
+        }
+        if (animatorProps.ry.propType) {
+          if (mult.length) {
+            matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
+          } else {
+            matrixHelper.rotateY(animatorProps.ry.v * mult);
+          }
+        }
+        if (animatorProps.rx.propType) {
+          if (mult.length) {
+            matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
+          } else {
+            matrixHelper.rotateX(animatorProps.rx.v * mult);
+          }
+        }
+        if (animatorProps.o.propType) {
+          if (mult.length) {
+            elemOpacity += ((animatorProps.o.v) * mult[0] - elemOpacity) * mult[0];
+          } else {
+            elemOpacity += ((animatorProps.o.v) * mult - elemOpacity) * mult;
+          }
+        }
+        if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
+          if (mult.length) {
+            sw += animatorProps.sw.v * mult[0];
+          } else {
+            sw += animatorProps.sw.v * mult;
+          }
+        }
+        if (documentData.strokeColorAnim && animatorProps.sc.propType) {
+          for (k = 0; k < 3; k += 1) {
+            if (mult.length) {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0];
+            } else {
+              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult;
+            }
+          }
+        }
+        if (documentData.fillColorAnim && documentData.fc) {
+          if (animatorProps.fc.propType) {
+            for (k = 0; k < 3; k += 1) {
+              if (mult.length) {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0];
+              } else {
+                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult;
+              }
+            }
+          }
+          if (animatorProps.fh.propType) {
+            if (mult.length) {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
+            } else {
+              fc = addHueToRGB(fc, animatorProps.fh.v * mult);
+            }
+          }
+          if (animatorProps.fs.propType) {
+            if (mult.length) {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
+            } else {
+              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
+            }
+          }
+          if (animatorProps.fb.propType) {
+            if (mult.length) {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
+            } else {
+              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult);
+            }
+          }
+        }
+      }
+
+      for (j = 0; j < jLen; j += 1) {
+        animatorProps = animators[j].a;
+
+        if (animatorProps.p.propType) {
+          animatorSelector = animators[j].s;
+          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+          if (this._hasMaskedPath) {
+            if (mult.length) {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
+            } else {
+              matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+            }
+          } else if (mult.length) {
+            matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
+          } else {
+            matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
+          }
+        }
+      }
+      if (documentData.strokeWidthAnim) {
+        letterSw = sw < 0 ? 0 : sw;
+      }
+      if (documentData.strokeColorAnim) {
+        letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
+      }
+      if (documentData.fillColorAnim && documentData.fc) {
+        letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
+      }
+
+      if (this._hasMaskedPath) {
+        matrixHelper.translate(0, -documentData.ls);
+
+        matrixHelper.translate(0, (alignment[1] * yOff) * 0.01 + yPos, 0);
+        if (this._pathData.p.v) {
+          tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
+          var rot = (Math.atan(tanAngle) * 180) / Math.PI;
+          if (currentPoint.point[0] < prevPoint.point[0]) {
+            rot += 180;
+          }
+          matrixHelper.rotate((-rot * Math.PI) / 180);
+        }
+        matrixHelper.translate(xPathPos, yPathPos, 0);
+        currentLength -= (alignment[0] * letters[i].an) * 0.005;
+        if (letters[i + 1] && ind !== letters[i + 1].ind) {
+          currentLength += letters[i].an / 2;
+          currentLength += (documentData.tr * 0.001) * documentData.finalSize;
+        }
+      } else {
+        matrixHelper.translate(xPos, yPos, 0);
+
+        if (documentData.ps) {
+          // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
+          matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+        }
+        switch (documentData.j) {
+          case 1:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
+            break;
+          case 2:
+            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
+            break;
+          default:
+            break;
+        }
+        matrixHelper.translate(0, -documentData.ls);
+        matrixHelper.translate(offf, 0, 0);
+        matrixHelper.translate((alignment[0] * letters[i].an) * 0.005, (alignment[1] * yOff) * 0.01, 0);
+        xPos += letters[i].l + (documentData.tr * 0.001) * documentData.finalSize;
+      }
+      if (renderType === 'html') {
+        letterM = matrixHelper.toCSS();
+      } else if (renderType === 'svg') {
+        letterM = matrixHelper.to2dCSS();
+      } else {
+        letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
+      }
+      letterO = elemOpacity;
+    }
+
+    if (renderedLettersCount <= i) {
+      letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
+      this.renderedLetters.push(letterValue);
+      renderedLettersCount += 1;
+      this.lettersChangedFlag = true;
+    } else {
+      letterValue = this.renderedLetters[i];
+      this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag;
+    }
+  }
+};
+
+TextAnimatorProperty.prototype.getValue = function () {
+  if (this._elem.globalData.frameId === this._frameId) {
+    return;
+  }
+  this._frameId = this._elem.globalData.frameId;
+  this.iterateDynamicProperties();
+};
+
+TextAnimatorProperty.prototype.mHelper = new Matrix();
+TextAnimatorProperty.prototype.defaultPropsArray = [];
+extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
+
+function ITextElement() {
+}
+
+ITextElement.prototype.initElement = function (data, globalData, comp) {
+  this.lettersChangedFlag = true;
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.textProperty = new TextProperty(this, data.t, this.dynamicProperties);
+  this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this);
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+  this.initRenderable();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  this.createContent();
+  this.hide();
+  this.textAnimator.searchProperties(this.dynamicProperties);
+};
+
+ITextElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+};
+
+ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
+  var j;
+  var jLen = shapes.length;
+  var pathNodes;
+  var shapeStr = '';
+  for (j = 0; j < jLen; j += 1) {
+    if (shapes[j].ty === 'sh') {
+      pathNodes = shapes[j].ks.k;
+      shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
+    }
+  }
+  return shapeStr;
+};
+
+ITextElement.prototype.updateDocumentData = function (newData, index) {
+  this.textProperty.updateDocumentData(newData, index);
+};
+
+ITextElement.prototype.canResizeFont = function (_canResize) {
+  this.textProperty.canResizeFont(_canResize);
+};
+
+ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
+  this.textProperty.setMinimumFontSize(_fontSize);
+};
+
+ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
+  if (documentData.ps) {
+    matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
+  }
+  matrixHelper.translate(0, -documentData.ls, 0);
+  switch (documentData.j) {
+    case 1:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
+      break;
+    case 2:
+      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
+      break;
+    default:
+      break;
+  }
+  matrixHelper.translate(xPos, yPos, 0);
+};
+
+ITextElement.prototype.buildColor = function (colorData) {
+  return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
+};
+
+ITextElement.prototype.emptyProp = new LetterProps();
+
+ITextElement.prototype.destroy = function () {
+
+};
+
+ITextElement.prototype.validateText = function () {
+  if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
+    this.buildNewText();
+    this.textProperty._isFirstFrame = false;
+    this.textProperty._mdf = false;
+  }
+};
+
+var emptyShapeData = {
+  shapes: [],
+};
+
+function SVGTextLottieElement(data, globalData, comp) {
+  this.textSpans = [];
+  this.renderType = 'svg';
+  this.initElement(data, globalData, comp);
+}
+
+extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
+
+SVGTextLottieElement.prototype.createContent = function () {
+  if (this.data.singleShape && !this.globalData.fontManager.chars) {
+    this.textContainer = createNS('text');
+  }
+};
+
+SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
+  var i = 0;
+  var len = textArray.length;
+  var textContents = [];
+  var currentTextContent = '';
+  while (i < len) {
+    if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
+      textContents.push(currentTextContent);
+      currentTextContent = '';
+    } else {
+      currentTextContent += textArray[i];
+    }
+    i += 1;
+  }
+  textContents.push(currentTextContent);
+  return textContents;
+};
+
+SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
+  // data should probably be cloned to apply scale separately to each instance of a text on different layers
+  // but since text internal content gets only rendered once and then it's never rerendered,
+  // it's probably safe not to clone data and reuse always the same instance even if the object is mutated.
+  // Avoiding cloning is preferred since cloning each character shape data is expensive
+  if (data.shapes && data.shapes.length) {
+    var shape = data.shapes[0];
+    if (shape.it) {
+      var shapeItem = shape.it[shape.it.length - 1];
+      if (shapeItem.s) {
+        shapeItem.s.k[0] = scale;
+        shapeItem.s.k[1] = scale;
+      }
+    }
+  }
+  return data;
+};
+
+SVGTextLottieElement.prototype.buildNewText = function () {
+  this.addDynamicProperty(this);
+  var i;
+  var len;
+
+  var documentData = this.textProperty.currentData;
+  this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
+  if (documentData.fc) {
+    this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
+  } else {
+    this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
+  }
+  if (documentData.sc) {
+    this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
+    this.layerElement.setAttribute('stroke-width', documentData.sw);
+  }
+  this.layerElement.setAttribute('font-size', documentData.finalSize);
+  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
+  if (fontData.fClass) {
+    this.layerElement.setAttribute('class', fontData.fClass);
+  } else {
+    this.layerElement.setAttribute('font-family', fontData.fFamily);
+    var fWeight = documentData.fWeight;
+    var fStyle = documentData.fStyle;
+    this.layerElement.setAttribute('font-style', fStyle);
+    this.layerElement.setAttribute('font-weight', fWeight);
+  }
+  this.layerElement.setAttribute('aria-label', documentData.t);
+
+  var letters = documentData.l || [];
+  var usesGlyphs = !!this.globalData.fontManager.chars;
+  len = letters.length;
+
+  var tSpan;
+  var matrixHelper = this.mHelper;
+  var shapeStr = '';
+  var singleShape = this.data.singleShape;
+  var xPos = 0;
+  var yPos = 0;
+  var firstLine = true;
+  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
+  if (singleShape && !usesGlyphs && !documentData.sz) {
+    var tElement = this.textContainer;
+    var justify = 'start';
+    switch (documentData.j) {
+      case 1:
+        justify = 'end';
+        break;
+      case 2:
+        justify = 'middle';
+        break;
+      default:
+        justify = 'start';
+        break;
+    }
+    tElement.setAttribute('text-anchor', justify);
+    tElement.setAttribute('letter-spacing', trackingOffset);
+    var textContent = this.buildTextContents(documentData.finalText);
+    len = textContent.length;
+    yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
+    for (i = 0; i < len; i += 1) {
+      tSpan = this.textSpans[i].span || createNS('tspan');
+      tSpan.textContent = textContent[i];
+      tSpan.setAttribute('x', 0);
+      tSpan.setAttribute('y', yPos);
+      tSpan.style.display = 'inherit';
+      tElement.appendChild(tSpan);
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          glyph: null,
+        };
+      }
+      this.textSpans[i].span = tSpan;
+      yPos += documentData.finalLineHeight;
+    }
+
+    this.layerElement.appendChild(tElement);
+  } else {
+    var cachedSpansLength = this.textSpans.length;
+    var charData;
+    for (i = 0; i < len; i += 1) {
+      if (!this.textSpans[i]) {
+        this.textSpans[i] = {
+          span: null,
+          childSpan: null,
+          glyph: null,
+        };
+      }
+      if (!usesGlyphs || !singleShape || i === 0) {
+        tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
+        if (cachedSpansLength <= i) {
+          tSpan.setAttribute('stroke-linecap', 'butt');
+          tSpan.setAttribute('stroke-linejoin', 'round');
+          tSpan.setAttribute('stroke-miterlimit', '4');
+          this.textSpans[i].span = tSpan;
+          if (usesGlyphs) {
+            var childSpan = createNS('g');
+            tSpan.appendChild(childSpan);
+            this.textSpans[i].childSpan = childSpan;
+          }
+          this.textSpans[i].span = tSpan;
+          this.layerElement.appendChild(tSpan);
+        }
+        tSpan.style.display = 'inherit';
+      }
+
+      matrixHelper.reset();
+      if (singleShape) {
+        if (letters[i].n) {
+          xPos = -trackingOffset;
+          yPos += documentData.yOffset;
+          yPos += firstLine ? 1 : 0;
+          firstLine = false;
+        }
+        this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
+        xPos += letters[i].l || 0;
+        // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
+        xPos += trackingOffset;
+      }
+      if (usesGlyphs) {
+        charData = this.globalData.fontManager.getCharData(
+          documentData.finalText[i],
+          fontData.fStyle,
+          this.globalData.fontManager.getFontByName(documentData.f).fFamily
+        );
+        var glyphElement;
+        // t === 1 means the character has been replaced with an animated shaped
+        if (charData.t === 1) {
+          glyphElement = new SVGCompElement(charData.data, this.globalData, this);
+        } else {
+          var data = emptyShapeData;
+          if (charData.data && charData.data.shapes) {
+            data = this.buildShapeData(charData.data, documentData.finalSize);
+          }
+          glyphElement = new SVGShapeElement(data, this.globalData, this);
+        }
+        if (this.textSpans[i].glyph) {
+          var glyph = this.textSpans[i].glyph;
+          this.textSpans[i].childSpan.removeChild(glyph.layerElement);
+          glyph.destroy();
+        }
+        this.textSpans[i].glyph = glyphElement;
+        glyphElement._debug = true;
+        glyphElement.prepareFrame(0);
+        glyphElement.renderFrame();
+        this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+        // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+        // this might have issues with strokes and might need a different solution
+        if (charData.t === 1) {
+          this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
+        }
+      } else {
+        if (singleShape) {
+          tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
+        }
+        tSpan.textContent = letters[i].val;
+        tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
+      }
+      //
+    }
+    if (singleShape && tSpan) {
+      tSpan.setAttribute('d', shapeStr);
+    }
+  }
+  while (i < this.textSpans.length) {
+    this.textSpans[i].span.style.display = 'none';
+    i += 1;
+  }
+
+  this._sizeChanged = true;
+};
+
+SVGTextLottieElement.prototype.sourceRectAtTime = function () {
+  this.prepareFrame(this.comp.renderedFrame - this.data.st);
+  this.renderInnerContent();
+  if (this._sizeChanged) {
+    this._sizeChanged = false;
+    var textBox = this.layerElement.getBBox();
+    this.bbox = {
+      top: textBox.y,
+      left: textBox.x,
+      width: textBox.width,
+      height: textBox.height,
+    };
+  }
+  return this.bbox;
+};
+
+SVGTextLottieElement.prototype.getValue = function () {
+  var i;
+  var len = this.textSpans.length;
+  var glyphElement;
+  this.renderedFrame = this.comp.renderedFrame;
+  for (i = 0; i < len; i += 1) {
+    glyphElement = this.textSpans[i].glyph;
+    if (glyphElement) {
+      glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
+      if (glyphElement._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+SVGTextLottieElement.prototype.renderInnerContent = function () {
+  this.validateText();
+  if (!this.data.singleShape || this._mdf) {
+    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
+    if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
+      this._sizeChanged = true;
+      var i;
+      var len;
+      var renderedLetters = this.textAnimator.renderedLetters;
+
+      var letters = this.textProperty.currentData.l;
+
+      len = letters.length;
+      var renderedLetter;
+      var textSpan;
+      var glyphElement;
+      for (i = 0; i < len; i += 1) {
+        if (!letters[i].n) {
+          renderedLetter = renderedLetters[i];
+          textSpan = this.textSpans[i].span;
+          glyphElement = this.textSpans[i].glyph;
+          if (glyphElement) {
+            glyphElement.renderFrame();
+          }
+          if (renderedLetter._mdf.m) {
+            textSpan.setAttribute('transform', renderedLetter.m);
+          }
+          if (renderedLetter._mdf.o) {
+            textSpan.setAttribute('opacity', renderedLetter.o);
+          }
+          if (renderedLetter._mdf.sw) {
+            textSpan.setAttribute('stroke-width', renderedLetter.sw);
+          }
+          if (renderedLetter._mdf.sc) {
+            textSpan.setAttribute('stroke', renderedLetter.sc);
+          }
+          if (renderedLetter._mdf.fc) {
+            textSpan.setAttribute('fill', renderedLetter.fc);
+          }
+        }
+      }
+    }
+  }
+};
+
+function ISolidElement(data, globalData, comp) {
+  this.initElement(data, globalData, comp);
+}
+extendPrototype([IImageElement], ISolidElement);
+
+ISolidElement.prototype.createContent = function () {
+  var rect = createNS('rect');
+  /// /rect.style.width = this.data.sw;
+  /// /rect.style.height = this.data.sh;
+  /// /rect.style.fill = this.data.sc;
+  rect.setAttribute('width', this.data.sw);
+  rect.setAttribute('height', this.data.sh);
+  rect.setAttribute('fill', this.data.sc);
+  this.layerElement.appendChild(rect);
+};
+
+function NullElement(data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initFrame();
+  this.initTransform(data, globalData, comp);
+  this.initHierarchy();
+}
+
+NullElement.prototype.prepareFrame = function (num) {
+  this.prepareProperties(num, true);
+};
+
+NullElement.prototype.renderFrame = function () {
+};
+
+NullElement.prototype.getBaseElement = function () {
+  return null;
+};
+
+NullElement.prototype.destroy = function () {
+};
+
+NullElement.prototype.sourceRectAtTime = function () {
+};
+
+NullElement.prototype.hide = function () {
+};
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
+
+function SVGRendererBase() {
+}
+
+extendPrototype([BaseRenderer], SVGRendererBase);
+
+SVGRendererBase.prototype.createNull = function (data) {
+  return new NullElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createShape = function (data) {
+  return new SVGShapeElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createText = function (data) {
+  return new SVGTextLottieElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createImage = function (data) {
+  return new IImageElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.createSolid = function (data) {
+  return new ISolidElement(data, this.globalData, this);
+};
+
+SVGRendererBase.prototype.configAnimation = function (animData) {
+  this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
+  this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+  if (this.renderConfig.viewBoxSize) {
+    this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
+  } else {
+    this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
+  }
+
+  if (!this.renderConfig.viewBoxOnly) {
+    this.svgElement.setAttribute('width', animData.w);
+    this.svgElement.setAttribute('height', animData.h);
+    this.svgElement.style.width = '100%';
+    this.svgElement.style.height = '100%';
+    this.svgElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
+  }
+  if (this.renderConfig.width) {
+    this.svgElement.setAttribute('width', this.renderConfig.width);
+  }
+  if (this.renderConfig.height) {
+    this.svgElement.setAttribute('height', this.renderConfig.height);
+  }
+  if (this.renderConfig.className) {
+    this.svgElement.setAttribute('class', this.renderConfig.className);
+  }
+  if (this.renderConfig.id) {
+    this.svgElement.setAttribute('id', this.renderConfig.id);
+  }
+  if (this.renderConfig.focusable !== undefined) {
+    this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
+  }
+  this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+  // this.layerElement.style.transform = 'translate3d(0,0,0)';
+  // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
+  this.animationItem.wrapper.appendChild(this.svgElement);
+  // Mask animation
+  var defs = this.globalData.defs;
+
+  this.setupGlobalData(animData, defs);
+  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
+  this.data = animData;
+
+  var maskElement = createNS('clipPath');
+  var rect = createNS('rect');
+  rect.setAttribute('width', animData.w);
+  rect.setAttribute('height', animData.h);
+  rect.setAttribute('x', 0);
+  rect.setAttribute('y', 0);
+  var maskId = createElementID();
+  maskElement.setAttribute('id', maskId);
+  maskElement.appendChild(rect);
+  this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')');
+
+  defs.appendChild(maskElement);
+  this.layers = animData.layers;
+  this.elements = createSizedArray(animData.layers.length);
+};
+
+SVGRendererBase.prototype.destroy = function () {
+  if (this.animationItem.wrapper) {
+    this.animationItem.wrapper.innerText = '';
+  }
+  this.layerElement = null;
+  this.globalData.defs = null;
+  var i;
+  var len = this.layers ? this.layers.length : 0;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i] && this.elements[i].destroy) {
+      this.elements[i].destroy();
+    }
+  }
+  this.elements.length = 0;
+  this.destroyed = true;
+  this.animationItem = null;
+};
+
+SVGRendererBase.prototype.updateContainerSize = function () {
+};
+
+SVGRendererBase.prototype.findIndexByInd = function (ind) {
+  var i = 0;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.layers[i].ind === ind) {
+      return i;
+    }
+  }
+  return -1;
+};
+
+SVGRendererBase.prototype.buildItem = function (pos) {
+  var elements = this.elements;
+  if (elements[pos] || this.layers[pos].ty === 99) {
+    return;
+  }
+  elements[pos] = true;
+  var element = this.createItem(this.layers[pos]);
+
+  elements[pos] = element;
+  if (getExpressionsPlugin()) {
+    if (this.layers[pos].ty === 0) {
+      this.globalData.projectInterface.registerComposition(element);
+    }
+    element.initExpressions();
+  }
+  this.appendElementInPos(element, pos);
+  if (this.layers[pos].tt) {
+    var elementIndex = ('tp' in this.layers[pos])
+      ? this.findIndexByInd(this.layers[pos].tp)
+      : pos - 1;
+    if (elementIndex === -1) {
+      return;
+    }
+    if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
+      this.buildItem(elementIndex);
+      this.addPendingElement(element);
+    } else {
+      var matteElement = elements[elementIndex];
+      var matteMask = matteElement.getMatte(this.layers[pos].tt);
+      element.setMatte(matteMask);
+    }
+  }
+};
+
+SVGRendererBase.prototype.checkPendingElements = function () {
+  while (this.pendingElements.length) {
+    var element = this.pendingElements.pop();
+    element.checkParenting();
+    if (element.data.tt) {
+      var i = 0;
+      var len = this.elements.length;
+      while (i < len) {
+        if (this.elements[i] === element) {
+          var elementIndex = 'tp' in element.data
+            ? this.findIndexByInd(element.data.tp)
+            : i - 1;
+          var matteElement = this.elements[elementIndex];
+          var matteMask = matteElement.getMatte(this.layers[i].tt);
+          element.setMatte(matteMask);
+          break;
+        }
+        i += 1;
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.renderFrame = function (num) {
+  if (this.renderedFrame === num || this.destroyed) {
+    return;
+  }
+  if (num === null) {
+    num = this.renderedFrame;
+  } else {
+    this.renderedFrame = num;
+  }
+  // console.log('-------');
+  // console.log('FRAME ',num);
+  this.globalData.frameNum = num;
+  this.globalData.frameId += 1;
+  this.globalData.projectInterface.currentFrame = num;
+  this.globalData._mdf = false;
+  var i;
+  var len = this.layers.length;
+  if (!this.completeLayers) {
+    this.checkLayers(num);
+  }
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(num - this.layers[i].st);
+    }
+  }
+  if (this.globalData._mdf) {
+    for (i = 0; i < len; i += 1) {
+      if (this.completeLayers || this.elements[i]) {
+        this.elements[i].renderFrame();
+      }
+    }
+  }
+};
+
+SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
+  var newElement = element.getBaseElement();
+  if (!newElement) {
+    return;
+  }
+  var i = 0;
+  var nextElement;
+  while (i < pos) {
+    if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
+      nextElement = this.elements[i].getBaseElement();
+    }
+    i += 1;
+  }
+  if (nextElement) {
+    this.layerElement.insertBefore(newElement, nextElement);
+  } else {
+    this.layerElement.appendChild(newElement);
+  }
+};
+
+SVGRendererBase.prototype.hide = function () {
+  this.layerElement.style.display = 'none';
+};
+
+SVGRendererBase.prototype.show = function () {
+  this.layerElement.style.display = 'block';
+};
+
+function ICompElement() {}
+
+extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
+
+ICompElement.prototype.initElement = function (data, globalData, comp) {
+  this.initFrame();
+  this.initBaseData(data, globalData, comp);
+  this.initTransform(data, globalData, comp);
+  this.initRenderable();
+  this.initHierarchy();
+  this.initRendererElement();
+  this.createContainerElements();
+  this.createRenderableComponents();
+  if (this.data.xt || !globalData.progressiveLoad) {
+    this.buildAllItems();
+  }
+  this.hide();
+};
+
+/* ICompElement.prototype.hide = function(){
+    if(!this.hidden){
+        this.hideElement();
+        var i,len = this.elements.length;
+        for( i = 0; i < len; i+=1 ){
+            if(this.elements[i]){
+                this.elements[i].hide();
+            }
+        }
+    }
+}; */
+
+ICompElement.prototype.prepareFrame = function (num) {
+  this._mdf = false;
+  this.prepareRenderableFrame(num);
+  this.prepareProperties(num, this.isInRange);
+  if (!this.isInRange && !this.data.xt) {
+    return;
+  }
+
+  if (!this.tm._placeholder) {
+    var timeRemapped = this.tm.v;
+    if (timeRemapped === this.data.op) {
+      timeRemapped = this.data.op - 1;
+    }
+    this.renderedFrame = timeRemapped;
+  } else {
+    this.renderedFrame = num / this.data.sr;
+  }
+  var i;
+  var len = this.elements.length;
+  if (!this.completeLayers) {
+    this.checkLayers(this.renderedFrame);
+  }
+  // This iteration needs to be backwards because of how expressions connect between each other
+  for (i = len - 1; i >= 0; i -= 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
+      if (this.elements[i]._mdf) {
+        this._mdf = true;
+      }
+    }
+  }
+};
+
+ICompElement.prototype.renderInnerContent = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.completeLayers || this.elements[i]) {
+      this.elements[i].renderFrame();
+    }
+  }
+};
+
+ICompElement.prototype.setElements = function (elems) {
+  this.elements = elems;
+};
+
+ICompElement.prototype.getElements = function () {
+  return this.elements;
+};
+
+ICompElement.prototype.destroyElements = function () {
+  var i;
+  var len = this.layers.length;
+  for (i = 0; i < len; i += 1) {
+    if (this.elements[i]) {
+      this.elements[i].destroy();
+    }
+  }
+};
+
+ICompElement.prototype.destroy = function () {
+  this.destroyElements();
+  this.destroyBaseElement();
+};
+
+function SVGCompElement(data, globalData, comp) {
+  this.layers = data.layers;
+  this.supports3d = true;
+  this.completeLayers = false;
+  this.pendingElements = [];
+  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
+  this.initElement(data, globalData, comp);
+  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
+}
+
+extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
+
+SVGCompElement.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+function SVGRenderer(animationItem, config) {
+  this.animationItem = animationItem;
+  this.layers = null;
+  this.renderedFrame = -1;
+  this.svgElement = createNS('svg');
+  var ariaLabel = '';
+  if (config && config.title) {
+    var titleElement = createNS('title');
+    var titleId = createElementID();
+    titleElement.setAttribute('id', titleId);
+    titleElement.textContent = config.title;
+    this.svgElement.appendChild(titleElement);
+    ariaLabel += titleId;
+  }
+  if (config && config.description) {
+    var descElement = createNS('desc');
+    var descId = createElementID();
+    descElement.setAttribute('id', descId);
+    descElement.textContent = config.description;
+    this.svgElement.appendChild(descElement);
+    ariaLabel += ' ' + descId;
+  }
+  if (ariaLabel) {
+    this.svgElement.setAttribute('aria-labelledby', ariaLabel);
+  }
+  var defs = createNS('defs');
+  this.svgElement.appendChild(defs);
+  var maskElement = createNS('g');
+  this.svgElement.appendChild(maskElement);
+  this.layerElement = maskElement;
+  this.renderConfig = {
+    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
+    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
+    contentVisibility: (config && config.contentVisibility) || 'visible',
+    progressiveLoad: (config && config.progressiveLoad) || false,
+    hideOnTransparent: !((config && config.hideOnTransparent === false)),
+    viewBoxOnly: (config && config.viewBoxOnly) || false,
+    viewBoxSize: (config && config.viewBoxSize) || false,
+    className: (config && config.className) || '',
+    id: (config && config.id) || '',
+    focusable: config && config.focusable,
+    filterSize: {
+      width: (config && config.filterSize && config.filterSize.width) || '100%',
+      height: (config && config.filterSize && config.filterSize.height) || '100%',
+      x: (config && config.filterSize && config.filterSize.x) || '0%',
+      y: (config && config.filterSize && config.filterSize.y) || '0%',
+    },
+    width: (config && config.width),
+    height: (config && config.height),
+    runExpressions: !config || config.runExpressions === undefined || config.runExpressions,
+  };
+
+  this.globalData = {
+    _mdf: false,
+    frameNum: -1,
+    defs: defs,
+    renderConfig: this.renderConfig,
+  };
+  this.elements = [];
+  this.pendingElements = [];
+  this.destroyed = false;
+  this.rendererType = 'svg';
+}
+
+extendPrototype([SVGRendererBase], SVGRenderer);
+
+SVGRenderer.prototype.createComp = function (data) {
+  return new SVGCompElement(data, this.globalData, this);
+};
+
+// Registering renderers
+registerRenderer('svg', SVGRenderer);
+
+// Registering shape modifiers
+ShapeModifiers.registerModifier('tm', TrimModifier);
+ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
+ShapeModifiers.registerModifier('rp', RepeaterModifier);
+ShapeModifiers.registerModifier('rd', RoundCornersModifier);
+ShapeModifiers.registerModifier('zz', ZigZagModifier);
+ShapeModifiers.registerModifier('op', OffsetPathModifier);
+
+const CompExpressionInterface = (function () {
+  return function (comp) {
+    function _thisLayerFunction(name) {
+      var i = 0;
+      var len = comp.layers.length;
+      while (i < len) {
+        if (comp.layers[i].nm === name || comp.layers[i].ind === name) {
+          return comp.elements[i].layerInterface;
+        }
+        i += 1;
+      }
+      return null;
+      // return {active:false};
+    }
+    Object.defineProperty(_thisLayerFunction, '_name', { value: comp.data.nm });
+    _thisLayerFunction.layer = _thisLayerFunction;
+    _thisLayerFunction.pixelAspect = 1;
+    _thisLayerFunction.height = comp.data.h || comp.globalData.compSize.h;
+    _thisLayerFunction.width = comp.data.w || comp.globalData.compSize.w;
+    _thisLayerFunction.pixelAspect = 1;
+    _thisLayerFunction.frameDuration = 1 / comp.globalData.frameRate;
+    _thisLayerFunction.displayStartTime = 0;
+    _thisLayerFunction.numLayers = comp.layers.length;
+    return _thisLayerFunction;
+  };
+}());
+
+/* eslint-disable */
+/*
+ Copyright 2014 David Bau.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ */
+
+function seedRandom(pool, math) {
+//
+// The following constants are related to IEEE 754 limits.
+//
+    var global = this,
+        width = 256,        // each RC4 output is 0 <= x < 256
+        chunks = 6,         // at least six RC4 outputs for each double
+        digits = 52,        // there are 52 significant digits in a double
+        rngname = 'random', // rngname: name for Math.random and Math.seedrandom
+        startdenom = math.pow(width, chunks),
+        significance = math.pow(2, digits),
+        overflow = significance * 2,
+        mask = width - 1,
+        nodecrypto;         // node.js crypto module, initialized at the bottom.
+
+//
+// seedrandom()
+// This is the seedrandom function described above.
+//
+    function seedrandom(seed, options, callback) {
+        var key = [];
+        options = (options === true) ? { entropy: true } : (options || {});
+
+        // Flatten the seed string or build one from local entropy if needed.
+        var shortseed = mixkey(flatten(
+            options.entropy ? [seed, tostring(pool)] :
+                (seed === null) ? autoseed() : seed, 3), key);
+
+        // Use the seed to initialize an ARC4 generator.
+        var arc4 = new ARC4(key);
+
+        // This function returns a random double in [0, 1) that contains
+        // randomness in every bit of the mantissa of the IEEE 754 value.
+        var prng = function() {
+            var n = arc4.g(chunks),             // Start with a numerator n < 2 ^ 48
+                d = startdenom,                 //   and denominator d = 2 ^ 48.
+                x = 0;                          //   and no 'extra last byte'.
+            while (n < significance) {          // Fill up all significant digits by
+                n = (n + x) * width;              //   shifting numerator and
+                d *= width;                       //   denominator and generating a
+                x = arc4.g(1);                    //   new least-significant-byte.
+            }
+            while (n >= overflow) {             // To avoid rounding up, before adding
+                n /= 2;                           //   last byte, shift everything
+                d /= 2;                           //   right using integer math until
+                x >>>= 1;                         //   we have exactly the desired bits.
+            }
+            return (n + x) / d;                 // Form the number within [0, 1).
+        };
+
+        prng.int32 = function() { return arc4.g(4) | 0; };
+        prng.quick = function() { return arc4.g(4) / 0x100000000; };
+        prng.double = prng;
+
+        // Mix the randomness into accumulated entropy.
+        mixkey(tostring(arc4.S), pool);
+
+        // Calling convention: what to return as a function of prng, seed, is_math.
+        return (options.pass || callback ||
+        function(prng, seed, is_math_call, state) {
+            if (state) {
+                // Load the arc4 state from the given state if it has an S array.
+                if (state.S) { copy(state, arc4); }
+                // Only provide the .state method if requested via options.state.
+                prng.state = function() { return copy(arc4, {}); };
+            }
+
+            // If called as a method of Math (Math.seedrandom()), mutate
+            // Math.random because that is how seedrandom.js has worked since v1.0.
+            if (is_math_call) { math[rngname] = prng; return seed; }
+
+            // Otherwise, it is a newer calling convention, so return the
+            // prng directly.
+            else return prng;
+        })(
+            prng,
+            shortseed,
+            'global' in options ? options.global : (this == math),
+            options.state);
+    }
+    math['seed' + rngname] = seedrandom;
+
+//
+// ARC4
+//
+// An ARC4 implementation.  The constructor takes a key in the form of
+// an array of at most (width) integers that should be 0 <= x < (width).
+//
+// The g(count) method returns a pseudorandom integer that concatenates
+// the next (count) outputs from ARC4.  Its return value is a number x
+// that is in the range 0 <= x < (width ^ count).
+//
+    function ARC4(key) {
+        var t, keylen = key.length,
+            me = this, i = 0, j = me.i = me.j = 0, s = me.S = [];
+
+        // The empty key [] is treated as [0].
+        if (!keylen) { key = [keylen++]; }
+
+        // Set up S using the standard key scheduling algorithm.
+        while (i < width) {
+            s[i] = i++;
+        }
+        for (i = 0; i < width; i++) {
+            s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))];
+            s[j] = t;
+        }
+
+        // The "g" method returns the next (count) outputs as one number.
+        me.g = function(count) {
+            // Using instance members instead of closure state nearly doubles speed.
+            var t, r = 0,
+                i = me.i, j = me.j, s = me.S;
+            while (count--) {
+                t = s[i = mask & (i + 1)];
+                r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))];
+            }
+            me.i = i; me.j = j;
+            return r;
+            // For robust unpredictability, the function call below automatically
+            // discards an initial batch of values.  This is called RC4-drop[256].
+            // See http://google.com/search?q=rsa+fluhrer+response&btnI
+        };
+    }
+
+//
+// copy()
+// Copies internal state of ARC4 to or from a plain object.
+//
+    function copy(f, t) {
+        t.i = f.i;
+        t.j = f.j;
+        t.S = f.S.slice();
+        return t;
+    }
+
+//
+// flatten()
+// Converts an object tree to nested arrays of strings.
+//
+    function flatten(obj, depth) {
+        var result = [], typ = (typeof obj), prop;
+        if (depth && typ == 'object') {
+            for (prop in obj) {
+                try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}
+            }
+        }
+        return (result.length ? result : typ == 'string' ? obj : obj + '\0');
+    }
+
+//
+// mixkey()
+// Mixes a string seed into a key that is an array of integers, and
+// returns a shortened string seed that is equivalent to the result key.
+//
+    function mixkey(seed, key) {
+        var stringseed = seed + '', smear, j = 0;
+        while (j < stringseed.length) {
+            key[mask & j] =
+                mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++));
+        }
+        return tostring(key);
+    }
+
+//
+// autoseed()
+// Returns an object for autoseeding, using window.crypto and Node crypto
+// module if available.
+//
+    function autoseed() {
+        try {
+            if (nodecrypto) { return tostring(nodecrypto.randomBytes(width)); }
+            var out = new Uint8Array(width);
+            (global.crypto || global.msCrypto).getRandomValues(out);
+            return tostring(out);
+        } catch (e) {
+            var browser = global.navigator,
+                plugins = browser && browser.plugins;
+            return [+new Date(), global, plugins, global.screen, tostring(pool)];
+        }
+    }
+
+//
+// tostring()
+// Converts an array of charcodes to a string
+//
+    function tostring(a) {
+        return String.fromCharCode.apply(0, a);
+    }
+
+//
+// When seedrandom.js is loaded, we immediately mix a few bits
+// from the built-in RNG into the entropy pool.  Because we do
+// not want to interfere with deterministic PRNG state later,
+// seedrandom will not call math.random on its own again after
+// initialization.
+//
+    mixkey(math.random(), pool);
+
+//
+// Nodejs and AMD support: export the implementation as a module using
+// either convention.
+//
+
+// End anonymous scope, and pass initial values.
+};
+
+function initialize$2(BMMath) {
+    seedRandom([], BMMath);
+}
+
+var propTypes = {
+  SHAPE: 'shape',
+};
+
+/* eslint-disable camelcase */
+
+const ExpressionManager = (function () {
+  'use strict';
+
+  var ob = {};
+  var Math = BMMath;
+  var window = null;
+  var document = null;
+  var XMLHttpRequest = null;
+  var fetch = null;
+  var frames = null;
+  var _lottieGlobal = {};
+  initialize$2(BMMath);
+
+  function resetFrame() {
+    _lottieGlobal = {};
+  }
+
+  function $bm_isInstanceOfArray(arr) {
+    return arr.constructor === Array || arr.constructor === Float32Array;
+  }
+
+  function isNumerable(tOfV, v) {
+    return tOfV === 'number' || v instanceof Number || tOfV === 'boolean' || tOfV === 'string';
+  }
+
+  function $bm_neg(a) {
+    var tOfA = typeof a;
+    if (tOfA === 'number' || a instanceof Number || tOfA === 'boolean') {
+      return -a;
+    }
+    if ($bm_isInstanceOfArray(a)) {
+      var i;
+      var lenA = a.length;
+      var retArr = [];
+      for (i = 0; i < lenA; i += 1) {
+        retArr[i] = -a[i];
+      }
+      return retArr;
+    }
+    if (a.propType) {
+      return a.v;
+    }
+    return -a;
+  }
+
+  var easeInBez = BezierFactory.getBezierEasing(0.333, 0, 0.833, 0.833, 'easeIn').get;
+  var easeOutBez = BezierFactory.getBezierEasing(0.167, 0.167, 0.667, 1, 'easeOut').get;
+  var easeInOutBez = BezierFactory.getBezierEasing(0.33, 0, 0.667, 1, 'easeInOut').get;
+
+  function sum(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    if ((isNumerable(tOfA, a) && isNumerable(tOfB, b)) || tOfA === 'string' || tOfB === 'string') {
+      return a + b;
+    }
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      a = a.slice(0);
+      a[0] += b;
+      return a;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      b = b.slice(0);
+      b[0] = a + b[0];
+      return b;
+    }
+    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
+      var i = 0;
+      var lenA = a.length;
+      var lenB = b.length;
+      var retArr = [];
+      while (i < lenA || i < lenB) {
+        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
+          retArr[i] = a[i] + b[i];
+        } else {
+          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
+        }
+        i += 1;
+      }
+      return retArr;
+    }
+    return 0;
+  }
+  var add = sum;
+
+  function sub(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      if (tOfA === 'string') {
+        a = parseInt(a, 10);
+      }
+      if (tOfB === 'string') {
+        b = parseInt(b, 10);
+      }
+      return a - b;
+    }
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      a = a.slice(0);
+      a[0] -= b;
+      return a;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      b = b.slice(0);
+      b[0] = a - b[0];
+      return b;
+    }
+    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
+      var i = 0;
+      var lenA = a.length;
+      var lenB = b.length;
+      var retArr = [];
+      while (i < lenA || i < lenB) {
+        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
+          retArr[i] = a[i] - b[i];
+        } else {
+          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
+        }
+        i += 1;
+      }
+      return retArr;
+    }
+    return 0;
+  }
+
+  function mul(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    var arr;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      return a * b;
+    }
+
+    var i;
+    var len;
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      len = a.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a[i] * b;
+      }
+      return arr;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      len = b.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a * b[i];
+      }
+      return arr;
+    }
+    return 0;
+  }
+
+  function div(a, b) {
+    var tOfA = typeof a;
+    var tOfB = typeof b;
+    var arr;
+    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
+      return a / b;
+    }
+    var i;
+    var len;
+    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
+      len = a.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a[i] / b;
+      }
+      return arr;
+    }
+    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
+      len = b.length;
+      arr = createTypedArray('float32', len);
+      for (i = 0; i < len; i += 1) {
+        arr[i] = a / b[i];
+      }
+      return arr;
+    }
+    return 0;
+  }
+  function mod(a, b) {
+    if (typeof a === 'string') {
+      a = parseInt(a, 10);
+    }
+    if (typeof b === 'string') {
+      b = parseInt(b, 10);
+    }
+    return a % b;
+  }
+  var $bm_sum = sum;
+  var $bm_sub = sub;
+  var $bm_mul = mul;
+  var $bm_div = div;
+  var $bm_mod = mod;
+
+  function clamp(num, min, max) {
+    if (min > max) {
+      var mm = max;
+      max = min;
+      min = mm;
+    }
+    return Math.min(Math.max(num, min), max);
+  }
+
+  function radiansToDegrees(val) {
+    return val / degToRads;
+  }
+  var radians_to_degrees = radiansToDegrees;
+
+  function degreesToRadians(val) {
+    return val * degToRads;
+  }
+  var degrees_to_radians = radiansToDegrees;
+
+  var helperLengthArray = [0, 0, 0, 0, 0, 0];
+
+  function length(arr1, arr2) {
+    if (typeof arr1 === 'number' || arr1 instanceof Number) {
+      arr2 = arr2 || 0;
+      return Math.abs(arr1 - arr2);
+    }
+    if (!arr2) {
+      arr2 = helperLengthArray;
+    }
+    var i;
+    var len = Math.min(arr1.length, arr2.length);
+    var addedLength = 0;
+    for (i = 0; i < len; i += 1) {
+      addedLength += Math.pow(arr2[i] - arr1[i], 2);
+    }
+    return Math.sqrt(addedLength);
+  }
+
+  function normalize(vec) {
+    return div(vec, length(vec));
+  }
+
+  function rgbToHsl(val) {
+    var r = val[0]; var g = val[1]; var b = val[2];
+    var max = Math.max(r, g, b);
+    var min = Math.min(r, g, b);
+    var h;
+    var s;
+    var l = (max + min) / 2;
+
+    if (max === min) {
+      h = 0; // achromatic
+      s = 0; // achromatic
+    } else {
+      var d = max - min;
+      s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+      switch (max) {
+        case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+        case g: h = (b - r) / d + 2; break;
+        case b: h = (r - g) / d + 4; break;
+        default: break;
+      }
+      h /= 6;
+    }
+
+    return [h, s, l, val[3]];
+  }
+
+  function hue2rgb(p, q, t) {
+    if (t < 0) t += 1;
+    if (t > 1) t -= 1;
+    if (t < 1 / 6) return p + (q - p) * 6 * t;
+    if (t < 1 / 2) return q;
+    if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
+    return p;
+  }
+
+  function hslToRgb(val) {
+    var h = val[0];
+    var s = val[1];
+    var l = val[2];
+
+    var r;
+    var g;
+    var b;
+
+    if (s === 0) {
+      r = l; // achromatic
+      b = l; // achromatic
+      g = l; // achromatic
+    } else {
+      var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+      var p = 2 * l - q;
+      r = hue2rgb(p, q, h + 1 / 3);
+      g = hue2rgb(p, q, h);
+      b = hue2rgb(p, q, h - 1 / 3);
+    }
+
+    return [r, g, b, val[3]];
+  }
+
+  function linear(t, tMin, tMax, value1, value2) {
+    if (value1 === undefined || value2 === undefined) {
+      value1 = tMin;
+      value2 = tMax;
+      tMin = 0;
+      tMax = 1;
+    }
+    if (tMax < tMin) {
+      var _tMin = tMax;
+      tMax = tMin;
+      tMin = _tMin;
+    }
+    if (t <= tMin) {
+      return value1;
+    } if (t >= tMax) {
+      return value2;
+    }
+    var perc = tMax === tMin ? 0 : (t - tMin) / (tMax - tMin);
+    if (!value1.length) {
+      return value1 + (value2 - value1) * perc;
+    }
+    var i;
+    var len = value1.length;
+    var arr = createTypedArray('float32', len);
+    for (i = 0; i < len; i += 1) {
+      arr[i] = value1[i] + (value2[i] - value1[i]) * perc;
+    }
+    return arr;
+  }
+  function random(min, max) {
+    if (max === undefined) {
+      if (min === undefined) {
+        min = 0;
+        max = 1;
+      } else {
+        max = min;
+        min = undefined;
+      }
+    }
+    if (max.length) {
+      var i;
+      var len = max.length;
+      if (!min) {
+        min = createTypedArray('float32', len);
+      }
+      var arr = createTypedArray('float32', len);
+      var rnd = BMMath.random();
+      for (i = 0; i < len; i += 1) {
+        arr[i] = min[i] + rnd * (max[i] - min[i]);
+      }
+      return arr;
+    }
+    if (min === undefined) {
+      min = 0;
+    }
+    var rndm = BMMath.random();
+    return min + rndm * (max - min);
+  }
+
+  function createPath(points, inTangents, outTangents, closed) {
+    var i;
+    var len = points.length;
+    var path = shapePool.newElement();
+    path.setPathData(!!closed, len);
+    var arrPlaceholder = [0, 0];
+    var inVertexPoint;
+    var outVertexPoint;
+    for (i = 0; i < len; i += 1) {
+      inVertexPoint = (inTangents && inTangents[i]) ? inTangents[i] : arrPlaceholder;
+      outVertexPoint = (outTangents && outTangents[i]) ? outTangents[i] : arrPlaceholder;
+      path.setTripleAt(points[i][0], points[i][1], outVertexPoint[0] + points[i][0], outVertexPoint[1] + points[i][1], inVertexPoint[0] + points[i][0], inVertexPoint[1] + points[i][1], i, true);
+    }
+    return path;
+  }
+
+  function initiateExpression(elem, data, property) {
+    // Bail out if we don't want expressions
+    function noOp(_value) {
+      return _value;
+    }
+    if (!elem.globalData.renderConfig.runExpressions) {
+      return noOp;
+    }
+
+    var val = data.x;
+    var needsVelocity = /velocity(?![\w\d])/.test(val);
+    var _needsRandom = val.indexOf('random') !== -1;
+    var elemType = elem.data.ty;
+    var transform;
+    var $bm_transform;
+    var content;
+    var effect;
+    var thisProperty = property;
+    thisProperty._name = elem.data.nm;
+    thisProperty.valueAtTime = thisProperty.getValueAtTime;
+    Object.defineProperty(thisProperty, 'value', {
+      get: function () {
+        return thisProperty.v;
+      },
+    });
+    elem.comp.frameDuration = 1 / elem.comp.globalData.frameRate;
+    elem.comp.displayStartTime = 0;
+    var inPoint = elem.data.ip / elem.comp.globalData.frameRate;
+    var outPoint = elem.data.op / elem.comp.globalData.frameRate;
+    var width = elem.data.sw ? elem.data.sw : 0;
+    var height = elem.data.sh ? elem.data.sh : 0;
+    var name = elem.data.nm;
+    var loopIn;
+    var loop_in;
+    var loopOut;
+    var loop_out;
+    var smooth;
+    var toWorld;
+    var fromWorld;
+    var fromComp;
+    var toComp;
+    var fromCompToSurface;
+    var position;
+    var rotation;
+    var anchorPoint;
+    var scale;
+    var thisLayer;
+    var thisComp;
+    var mask;
+    var valueAtTime;
+    var velocityAtTime;
+
+    var scoped_bm_rt;
+    // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
+    var expression_function = eval('[function _expression_function(){' + val + ';scoped_bm_rt=$bm_rt}]')[0]; // eslint-disable-line no-eval
+    var numKeys = property.kf ? data.k.length : 0;
+
+    var active = !this.data || this.data.hd !== true;
+
+    var wiggle = function wiggle(freq, amp) {
+      var iWiggle;
+      var j;
+      var lenWiggle = this.pv.length ? this.pv.length : 1;
+      var addedAmps = createTypedArray('float32', lenWiggle);
+      freq = 5;
+      var iterations = Math.floor(time * freq);
+      iWiggle = 0;
+      j = 0;
+      while (iWiggle < iterations) {
+        // var rnd = BMMath.random();
+        for (j = 0; j < lenWiggle; j += 1) {
+          addedAmps[j] += -amp + amp * 2 * BMMath.random();
+          // addedAmps[j] += -amp + amp*2*rnd;
+        }
+        iWiggle += 1;
+      }
+      // var rnd2 = BMMath.random();
+      var periods = time * freq;
+      var perc = periods - Math.floor(periods);
+      var arr = createTypedArray('float32', lenWiggle);
+      if (lenWiggle > 1) {
+        for (j = 0; j < lenWiggle; j += 1) {
+          arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc;
+          // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
+          // arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc);
+        }
+        return arr;
+      }
+      return this.pv + addedAmps[0] + (-amp + amp * 2 * BMMath.random()) * perc;
+    }.bind(this);
+
+    if (thisProperty.loopIn) {
+      loopIn = thisProperty.loopIn.bind(thisProperty);
+      loop_in = loopIn;
+    }
+
+    if (thisProperty.loopOut) {
+      loopOut = thisProperty.loopOut.bind(thisProperty);
+      loop_out = loopOut;
+    }
+
+    if (thisProperty.smooth) {
+      smooth = thisProperty.smooth.bind(thisProperty);
+    }
+
+    function loopInDuration(type, duration) {
+      return loopIn(type, duration, true);
+    }
+
+    function loopOutDuration(type, duration) {
+      return loopOut(type, duration, true);
+    }
+
+    if (this.getValueAtTime) {
+      valueAtTime = this.getValueAtTime.bind(this);
+    }
+
+    if (this.getVelocityAtTime) {
+      velocityAtTime = this.getVelocityAtTime.bind(this);
+    }
+
+    var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface);
+
+    function lookAt(elem1, elem2) {
+      var fVec = [elem2[0] - elem1[0], elem2[1] - elem1[1], elem2[2] - elem1[2]];
+      var pitch = Math.atan2(fVec[0], Math.sqrt(fVec[1] * fVec[1] + fVec[2] * fVec[2])) / degToRads;
+      var yaw = -Math.atan2(fVec[1], fVec[2]) / degToRads;
+      return [yaw, pitch, 0];
+    }
+
+    function easeOut(t, tMin, tMax, val1, val2) {
+      return applyEase(easeOutBez, t, tMin, tMax, val1, val2);
+    }
+
+    function easeIn(t, tMin, tMax, val1, val2) {
+      return applyEase(easeInBez, t, tMin, tMax, val1, val2);
+    }
+
+    function ease(t, tMin, tMax, val1, val2) {
+      return applyEase(easeInOutBez, t, tMin, tMax, val1, val2);
+    }
+
+    function applyEase(fn, t, tMin, tMax, val1, val2) {
+      if (val1 === undefined) {
+        val1 = tMin;
+        val2 = tMax;
+      } else {
+        t = (t - tMin) / (tMax - tMin);
+      }
+      if (t > 1) {
+        t = 1;
+      } else if (t < 0) {
+        t = 0;
+      }
+      var mult = fn(t);
+      if ($bm_isInstanceOfArray(val1)) {
+        var iKey;
+        var lenKey = val1.length;
+        var arr = createTypedArray('float32', lenKey);
+        for (iKey = 0; iKey < lenKey; iKey += 1) {
+          arr[iKey] = (val2[iKey] - val1[iKey]) * mult + val1[iKey];
+        }
+        return arr;
+      }
+      return (val2 - val1) * mult + val1;
+    }
+
+    function nearestKey(time) {
+      var iKey;
+      var lenKey = data.k.length;
+      var index;
+      var keyTime;
+      if (!data.k.length || typeof (data.k[0]) === 'number') {
+        index = 0;
+        keyTime = 0;
+      } else {
+        index = -1;
+        time *= elem.comp.globalData.frameRate;
+        if (time < data.k[0].t) {
+          index = 1;
+          keyTime = data.k[0].t;
+        } else {
+          for (iKey = 0; iKey < lenKey - 1; iKey += 1) {
+            if (time === data.k[iKey].t) {
+              index = iKey + 1;
+              keyTime = data.k[iKey].t;
+              break;
+            } else if (time > data.k[iKey].t && time < data.k[iKey + 1].t) {
+              if (time - data.k[iKey].t > data.k[iKey + 1].t - time) {
+                index = iKey + 2;
+                keyTime = data.k[iKey + 1].t;
+              } else {
+                index = iKey + 1;
+                keyTime = data.k[iKey].t;
+              }
+              break;
+            }
+          }
+          if (index === -1) {
+            index = iKey + 1;
+            keyTime = data.k[iKey].t;
+          }
+        }
+      }
+      var obKey = {};
+      obKey.index = index;
+      obKey.time = keyTime / elem.comp.globalData.frameRate;
+      return obKey;
+    }
+
+    function key(ind) {
+      var obKey;
+      var iKey;
+      var lenKey;
+      if (!data.k.length || typeof (data.k[0]) === 'number') {
+        throw new Error('The property has no keyframe at index ' + ind);
+      }
+      ind -= 1;
+      obKey = {
+        time: data.k[ind].t / elem.comp.globalData.frameRate,
+        value: [],
+      };
+      var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e;
+
+      lenKey = arr.length;
+      for (iKey = 0; iKey < lenKey; iKey += 1) {
+        obKey[iKey] = arr[iKey];
+        obKey.value[iKey] = arr[iKey];
+      }
+      return obKey;
+    }
+
+    function framesToTime(fr, fps) {
+      if (!fps) {
+        fps = elem.comp.globalData.frameRate;
+      }
+      return fr / fps;
+    }
+
+    function timeToFrames(t, fps) {
+      if (!t && t !== 0) {
+        t = time;
+      }
+      if (!fps) {
+        fps = elem.comp.globalData.frameRate;
+      }
+      return t * fps;
+    }
+
+    function seedRandom(seed) {
+      BMMath.seedrandom(randSeed + seed);
+    }
+
+    function sourceRectAtTime() {
+      return elem.sourceRectAtTime();
+    }
+
+    function substring(init, end) {
+      if (typeof value === 'string') {
+        if (end === undefined) {
+          return value.substring(init);
+        }
+        return value.substring(init, end);
+      }
+      return '';
+    }
+
+    function substr(init, end) {
+      if (typeof value === 'string') {
+        if (end === undefined) {
+          return value.substr(init);
+        }
+        return value.substr(init, end);
+      }
+      return '';
+    }
+
+    function posterizeTime(framesPerSecond) {
+      time = framesPerSecond === 0 ? 0 : Math.floor(time * framesPerSecond) / framesPerSecond;
+      value = valueAtTime(time);
+    }
+
+    var time;
+    var velocity;
+    var value;
+    var text;
+    var textIndex;
+    var textTotal;
+    var selectorValue;
+    var index = elem.data.ind;
+    var hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+    var parent;
+    var randSeed = Math.floor(Math.random() * 1000000);
+    var globalData = elem.globalData;
+
+    function executeExpression(_value) {
+      // globalData.pushExpression();
+      value = _value;
+      if (this.frameExpressionId === elem.globalData.frameId && this.propType !== 'textSelector') {
+        return value;
+      }
+      if (this.propType === 'textSelector') {
+        textIndex = this.textIndex;
+        textTotal = this.textTotal;
+        selectorValue = this.selectorValue;
+      }
+      if (!thisLayer) {
+        text = elem.layerInterface.text;
+        thisLayer = elem.layerInterface;
+        thisComp = elem.comp.compInterface;
+        toWorld = thisLayer.toWorld.bind(thisLayer);
+        fromWorld = thisLayer.fromWorld.bind(thisLayer);
+        fromComp = thisLayer.fromComp.bind(thisLayer);
+        toComp = thisLayer.toComp.bind(thisLayer);
+        mask = thisLayer.mask ? thisLayer.mask.bind(thisLayer) : null;
+        fromCompToSurface = fromComp;
+      }
+      if (!transform) {
+        transform = elem.layerInterface('ADBE Transform Group');
+        $bm_transform = transform;
+        if (transform) {
+          anchorPoint = transform.anchorPoint;
+          /* position = transform.position;
+                    rotation = transform.rotation;
+                    scale = transform.scale; */
+        }
+      }
+
+      if (elemType === 4 && !content) {
+        content = thisLayer('ADBE Root Vectors Group');
+      }
+      if (!effect) {
+        effect = thisLayer(4);
+      }
+      hasParent = !!(elem.hierarchy && elem.hierarchy.length);
+      if (hasParent && !parent) {
+        parent = elem.hierarchy[0].layerInterface;
+      }
+      time = this.comp.renderedFrame / this.comp.globalData.frameRate;
+      if (_needsRandom) {
+        seedRandom(randSeed + time);
+      }
+      if (needsVelocity) {
+        velocity = velocityAtTime(time);
+      }
+      expression_function();
+      this.frameExpressionId = elem.globalData.frameId;
+
+      // TODO: Check if it's possible to return on ShapeInterface the .v value
+      // Changed this to a ternary operation because Rollup failed compiling it correctly
+      scoped_bm_rt = scoped_bm_rt.propType === propTypes.SHAPE
+        ? scoped_bm_rt.v
+        : scoped_bm_rt;
+      return scoped_bm_rt;
+    }
+    // Bundlers will see these as dead code and unless we reference them
+    executeExpression.__preventDeadCodeRemoval = [$bm_transform, anchorPoint, time, velocity, inPoint, outPoint, width, height, name, loop_in, loop_out, smooth, toComp, fromCompToSurface, toWorld, fromWorld, mask, position, rotation, scale, thisComp, numKeys, active, wiggle, loopInDuration, loopOutDuration, comp, lookAt, easeOut, easeIn, ease, nearestKey, key, text, textIndex, textTotal, selectorValue, framesToTime, timeToFrames, sourceRectAtTime, substring, substr, posterizeTime, index, globalData];
+    return executeExpression;
+  }
+
+  ob.initiateExpression = initiateExpression;
+  ob.__preventDeadCodeRemoval = [window, document, XMLHttpRequest, fetch, frames, $bm_neg, add, $bm_sum, $bm_sub, $bm_mul, $bm_div, $bm_mod, clamp, radians_to_degrees, degreesToRadians, degrees_to_radians, normalize, rgbToHsl, hslToRgb, linear, random, createPath, _lottieGlobal];
+  ob.resetFrame = resetFrame;
+  return ob;
+}());
+
+const Expressions = (function () {
+  var ob = {};
+  ob.initExpressions = initExpressions;
+  ob.resetFrame = ExpressionManager.resetFrame;
+
+  function initExpressions(animation) {
+    var stackCount = 0;
+    var registers = [];
+
+    function pushExpression() {
+      stackCount += 1;
+    }
+
+    function popExpression() {
+      stackCount -= 1;
+      if (stackCount === 0) {
+        releaseInstances();
+      }
+    }
+
+    function registerExpressionProperty(expression) {
+      if (registers.indexOf(expression) === -1) {
+        registers.push(expression);
+      }
+    }
+
+    function releaseInstances() {
+      var i;
+      var len = registers.length;
+      for (i = 0; i < len; i += 1) {
+        registers[i].release();
+      }
+      registers.length = 0;
+    }
+
+    animation.renderer.compInterface = CompExpressionInterface(animation.renderer);
+    animation.renderer.globalData.projectInterface.registerComposition(animation.renderer);
+    animation.renderer.globalData.pushExpression = pushExpression;
+    animation.renderer.globalData.popExpression = popExpression;
+    animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty;
+  }
+  return ob;
+}());
+
+const MaskManagerInterface = (function () {
+  function MaskInterface(mask, data) {
+    this._mask = mask;
+    this._data = data;
+  }
+  Object.defineProperty(MaskInterface.prototype, 'maskPath', {
+    get: function () {
+      if (this._mask.prop.k) {
+        this._mask.prop.getValue();
+      }
+      return this._mask.prop;
+    },
+  });
+  Object.defineProperty(MaskInterface.prototype, 'maskOpacity', {
+    get: function () {
+      if (this._mask.op.k) {
+        this._mask.op.getValue();
+      }
+      return this._mask.op.v * 100;
+    },
+  });
+
+  var MaskManager = function (maskManager) {
+    var _masksInterfaces = createSizedArray(maskManager.viewData.length);
+    var i;
+    var len = maskManager.viewData.length;
+    for (i = 0; i < len; i += 1) {
+      _masksInterfaces[i] = new MaskInterface(maskManager.viewData[i], maskManager.masksProperties[i]);
+    }
+
+    var maskFunction = function (name) {
+      i = 0;
+      while (i < len) {
+        if (maskManager.masksProperties[i].nm === name) {
+          return _masksInterfaces[i];
+        }
+        i += 1;
+      }
+      return null;
+    };
+    return maskFunction;
+  };
+  return MaskManager;
+}());
+
+const ExpressionPropertyInterface = (function () {
+  var defaultUnidimensionalValue = { pv: 0, v: 0, mult: 1 };
+  var defaultMultidimensionalValue = { pv: [0, 0, 0], v: [0, 0, 0], mult: 1 };
+
+  function completeProperty(expressionValue, property, type) {
+    Object.defineProperty(expressionValue, 'velocity', {
+      get: function () {
+        return property.getVelocityAtTime(property.comp.currentFrame);
+      },
+    });
+    expressionValue.numKeys = property.keyframes ? property.keyframes.length : 0;
+    expressionValue.key = function (pos) {
+      if (!expressionValue.numKeys) {
+        return 0;
+      }
+      var value = '';
+      if ('s' in property.keyframes[pos - 1]) {
+        value = property.keyframes[pos - 1].s;
+      } else if ('e' in property.keyframes[pos - 2]) {
+        value = property.keyframes[pos - 2].e;
+      } else {
+        value = property.keyframes[pos - 2].s;
+      }
+      var valueProp = type === 'unidimensional' ? new Number(value) : Object.assign({}, value); // eslint-disable-line no-new-wrappers
+      valueProp.time = property.keyframes[pos - 1].t / property.elem.comp.globalData.frameRate;
+      valueProp.value = type === 'unidimensional' ? value[0] : value;
+      return valueProp;
+    };
+    expressionValue.valueAtTime = property.getValueAtTime;
+    expressionValue.speedAtTime = property.getSpeedAtTime;
+    expressionValue.velocityAtTime = property.getVelocityAtTime;
+    expressionValue.propertyGroup = property.propertyGroup;
+  }
+
+  function UnidimensionalPropertyInterface(property) {
+    if (!property || !('pv' in property)) {
+      property = defaultUnidimensionalValue;
+    }
+    var mult = 1 / property.mult;
+    var val = property.pv * mult;
+    var expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
+    expressionValue.value = val;
+    completeProperty(expressionValue, property, 'unidimensional');
+
+    return function () {
+      if (property.k) {
+        property.getValue();
+      }
+      val = property.v * mult;
+      if (expressionValue.value !== val) {
+        expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
+        expressionValue.value = val;
+        expressionValue[0] = val;
+        completeProperty(expressionValue, property, 'unidimensional');
+      }
+      return expressionValue;
+    };
+  }
+
+  function MultidimensionalPropertyInterface(property) {
+    if (!property || !('pv' in property)) {
+      property = defaultMultidimensionalValue;
+    }
+    var mult = 1 / property.mult;
+    var len = (property.data && property.data.l) || property.pv.length;
+    var expressionValue = createTypedArray('float32', len);
+    var arrValue = createTypedArray('float32', len);
+    expressionValue.value = arrValue;
+    completeProperty(expressionValue, property, 'multidimensional');
+
+    return function () {
+      if (property.k) {
+        property.getValue();
+      }
+      for (var i = 0; i < len; i += 1) {
+        arrValue[i] = property.v[i] * mult;
+        expressionValue[i] = arrValue[i];
+      }
+      return expressionValue;
+    };
+  }
+
+  // TODO: try to avoid using this getter
+  function defaultGetter() {
+    return defaultUnidimensionalValue;
+  }
+
+  return function (property) {
+    if (!property) {
+      return defaultGetter;
+    } if (property.propType === 'unidimensional') {
+      return UnidimensionalPropertyInterface(property);
+    }
+    return MultidimensionalPropertyInterface(property);
+  };
+}());
+
+const TransformExpressionInterface = (function () {
+  return function (transform) {
+    function _thisFunction(name) {
+      switch (name) {
+        case 'scale':
+        case 'Scale':
+        case 'ADBE Scale':
+        case 6:
+          return _thisFunction.scale;
+        case 'rotation':
+        case 'Rotation':
+        case 'ADBE Rotation':
+        case 'ADBE Rotate Z':
+        case 10:
+          return _thisFunction.rotation;
+        case 'ADBE Rotate X':
+          return _thisFunction.xRotation;
+        case 'ADBE Rotate Y':
+          return _thisFunction.yRotation;
+        case 'position':
+        case 'Position':
+        case 'ADBE Position':
+        case 2:
+          return _thisFunction.position;
+        case 'ADBE Position_0':
+          return _thisFunction.xPosition;
+        case 'ADBE Position_1':
+          return _thisFunction.yPosition;
+        case 'ADBE Position_2':
+          return _thisFunction.zPosition;
+        case 'anchorPoint':
+        case 'AnchorPoint':
+        case 'Anchor Point':
+        case 'ADBE AnchorPoint':
+        case 1:
+          return _thisFunction.anchorPoint;
+        case 'opacity':
+        case 'Opacity':
+        case 11:
+          return _thisFunction.opacity;
+        default:
+          return null;
+      }
+    }
+    Object.defineProperty(_thisFunction, 'rotation', {
+      get: ExpressionPropertyInterface(transform.r || transform.rz),
+    });
+
+    Object.defineProperty(_thisFunction, 'zRotation', {
+      get: ExpressionPropertyInterface(transform.rz || transform.r),
+    });
+
+    Object.defineProperty(_thisFunction, 'xRotation', {
+      get: ExpressionPropertyInterface(transform.rx),
+    });
+
+    Object.defineProperty(_thisFunction, 'yRotation', {
+      get: ExpressionPropertyInterface(transform.ry),
+    });
+    Object.defineProperty(_thisFunction, 'scale', {
+      get: ExpressionPropertyInterface(transform.s),
+    });
+    var _px;
+    var _py;
+    var _pz;
+    var _transformFactory;
+    if (transform.p) {
+      _transformFactory = ExpressionPropertyInterface(transform.p);
+    } else {
+      _px = ExpressionPropertyInterface(transform.px);
+      _py = ExpressionPropertyInterface(transform.py);
+      if (transform.pz) {
+        _pz = ExpressionPropertyInterface(transform.pz);
+      }
+    }
+    Object.defineProperty(_thisFunction, 'position', {
+      get: function () {
+        if (transform.p) {
+          return _transformFactory();
+        }
+        return [
+          _px(),
+          _py(),
+          _pz ? _pz() : 0];
+      },
+    });
+
+    Object.defineProperty(_thisFunction, 'xPosition', {
+      get: ExpressionPropertyInterface(transform.px),
+    });
+
+    Object.defineProperty(_thisFunction, 'yPosition', {
+      get: ExpressionPropertyInterface(transform.py),
+    });
+
+    Object.defineProperty(_thisFunction, 'zPosition', {
+      get: ExpressionPropertyInterface(transform.pz),
+    });
+
+    Object.defineProperty(_thisFunction, 'anchorPoint', {
+      get: ExpressionPropertyInterface(transform.a),
+    });
+
+    Object.defineProperty(_thisFunction, 'opacity', {
+      get: ExpressionPropertyInterface(transform.o),
+    });
+
+    Object.defineProperty(_thisFunction, 'skew', {
+      get: ExpressionPropertyInterface(transform.sk),
+    });
+
+    Object.defineProperty(_thisFunction, 'skewAxis', {
+      get: ExpressionPropertyInterface(transform.sa),
+    });
+
+    Object.defineProperty(_thisFunction, 'orientation', {
+      get: ExpressionPropertyInterface(transform.or),
+    });
+
+    return _thisFunction;
+  };
+}());
+
+const LayerExpressionInterface = (function () {
+  function getMatrix(time) {
+    var toWorldMat = new Matrix();
+    if (time !== undefined) {
+      var propMatrix = this._elem.finalTransform.mProp.getValueAtTime(time);
+      propMatrix.clone(toWorldMat);
+    } else {
+      var transformMat = this._elem.finalTransform.mProp;
+      transformMat.applyToMatrix(toWorldMat);
+    }
+    return toWorldMat;
+  }
+
+  function toWorldVec(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    toWorldMat.props[12] = 0;
+    toWorldMat.props[13] = 0;
+    toWorldMat.props[14] = 0;
+    return this.applyPoint(toWorldMat, arr);
+  }
+
+  function toWorld(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    return this.applyPoint(toWorldMat, arr);
+  }
+
+  function fromWorldVec(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    toWorldMat.props[12] = 0;
+    toWorldMat.props[13] = 0;
+    toWorldMat.props[14] = 0;
+    return this.invertPoint(toWorldMat, arr);
+  }
+
+  function fromWorld(arr, time) {
+    var toWorldMat = this.getMatrix(time);
+    return this.invertPoint(toWorldMat, arr);
+  }
+
+  function applyPoint(matrix, arr) {
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
+      }
+    }
+    return matrix.applyToPointArray(arr[0], arr[1], arr[2] || 0);
+  }
+
+  function invertPoint(matrix, arr) {
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
+      }
+    }
+    return matrix.inversePoint(arr);
+  }
+
+  function fromComp(arr) {
+    var toWorldMat = new Matrix();
+    toWorldMat.reset();
+    this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
+    if (this._elem.hierarchy && this._elem.hierarchy.length) {
+      var i;
+      var len = this._elem.hierarchy.length;
+      for (i = 0; i < len; i += 1) {
+        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
+      }
+      return toWorldMat.inversePoint(arr);
+    }
+    return toWorldMat.inversePoint(arr);
+  }
+
+  function sampleImage() {
+    return [1, 1, 1, 1];
+  }
+
+  return function (elem) {
+    var transformInterface;
+
+    function _registerMaskInterface(maskManager) {
+      _thisLayerFunction.mask = new MaskManagerInterface(maskManager, elem);
+    }
+    function _registerEffectsInterface(effects) {
+      _thisLayerFunction.effect = effects;
+    }
+
+    function _thisLayerFunction(name) {
+      switch (name) {
+        case 'ADBE Root Vectors Group':
+        case 'Contents':
+        case 2:
+          return _thisLayerFunction.shapeInterface;
+        case 1:
+        case 6:
+        case 'Transform':
+        case 'transform':
+        case 'ADBE Transform Group':
+          return transformInterface;
+        case 4:
+        case 'ADBE Effect Parade':
+        case 'effects':
+        case 'Effects':
+          return _thisLayerFunction.effect;
+        case 'ADBE Text Properties':
+          return _thisLayerFunction.textInterface;
+        default:
+          return null;
+      }
+    }
+    _thisLayerFunction.getMatrix = getMatrix;
+    _thisLayerFunction.invertPoint = invertPoint;
+    _thisLayerFunction.applyPoint = applyPoint;
+    _thisLayerFunction.toWorld = toWorld;
+    _thisLayerFunction.toWorldVec = toWorldVec;
+    _thisLayerFunction.fromWorld = fromWorld;
+    _thisLayerFunction.fromWorldVec = fromWorldVec;
+    _thisLayerFunction.toComp = toWorld;
+    _thisLayerFunction.fromComp = fromComp;
+    _thisLayerFunction.sampleImage = sampleImage;
+    _thisLayerFunction.sourceRectAtTime = elem.sourceRectAtTime.bind(elem);
+    _thisLayerFunction._elem = elem;
+    transformInterface = TransformExpressionInterface(elem.finalTransform.mProp);
+    var anchorPointDescriptor = getDescriptor(transformInterface, 'anchorPoint');
+    Object.defineProperties(_thisLayerFunction, {
+      hasParent: {
+        get: function () {
+          return elem.hierarchy.length;
+        },
+      },
+      parent: {
+        get: function () {
+          return elem.hierarchy[0].layerInterface;
+        },
+      },
+      rotation: getDescriptor(transformInterface, 'rotation'),
+      scale: getDescriptor(transformInterface, 'scale'),
+      position: getDescriptor(transformInterface, 'position'),
+      opacity: getDescriptor(transformInterface, 'opacity'),
+      anchorPoint: anchorPointDescriptor,
+      anchor_point: anchorPointDescriptor,
+      transform: {
+        get: function () {
+          return transformInterface;
+        },
+      },
+      active: {
+        get: function () {
+          return elem.isInRange;
+        },
+      },
+    });
+
+    _thisLayerFunction.startTime = elem.data.st;
+    _thisLayerFunction.index = elem.data.ind;
+    _thisLayerFunction.source = elem.data.refId;
+    _thisLayerFunction.height = elem.data.ty === 0 ? elem.data.h : 100;
+    _thisLayerFunction.width = elem.data.ty === 0 ? elem.data.w : 100;
+    _thisLayerFunction.inPoint = elem.data.ip / elem.comp.globalData.frameRate;
+    _thisLayerFunction.outPoint = elem.data.op / elem.comp.globalData.frameRate;
+    _thisLayerFunction._name = elem.data.nm;
+
+    _thisLayerFunction.registerMaskInterface = _registerMaskInterface;
+    _thisLayerFunction.registerEffectsInterface = _registerEffectsInterface;
+    return _thisLayerFunction;
+  };
+}());
+
+const propertyGroupFactory = (function () {
+  return function (interfaceFunction, parentPropertyGroup) {
+    return function (val) {
+      val = val === undefined ? 1 : val;
+      if (val <= 0) {
+        return interfaceFunction;
+      }
+      return parentPropertyGroup(val - 1);
+    };
+  };
+}());
+
+const PropertyInterface = (function () {
+  return function (propertyName, propertyGroup) {
+    var interfaceFunction = {
+      _name: propertyName,
+    };
+
+    function _propertyGroup(val) {
+      val = val === undefined ? 1 : val;
+      if (val <= 0) {
+        return interfaceFunction;
+      }
+      return propertyGroup(val - 1);
+    }
+
+    return _propertyGroup;
+  };
+}());
+
+const EffectsExpressionInterface = (function () {
+  var ob = {
+    createEffectsInterface: createEffectsInterface,
+  };
+
+  function createEffectsInterface(elem, propertyGroup) {
+    if (elem.effectsManager) {
+      var effectElements = [];
+      var effectsData = elem.data.ef;
+      var i;
+      var len = elem.effectsManager.effectElements.length;
+      for (i = 0; i < len; i += 1) {
+        effectElements.push(createGroupInterface(effectsData[i], elem.effectsManager.effectElements[i], propertyGroup, elem));
+      }
+
+      var effects = elem.data.ef || [];
+      var groupInterface = function (name) {
+        i = 0;
+        len = effects.length;
+        while (i < len) {
+          if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
+            return effectElements[i];
+          }
+          i += 1;
+        }
+        return null;
+      };
+      Object.defineProperty(groupInterface, 'numProperties', {
+        get: function () {
+          return effects.length;
+        },
+      });
+      return groupInterface;
+    }
+    return null;
+  }
+
+  function createGroupInterface(data, elements, propertyGroup, elem) {
+    function groupInterface(name) {
+      var effects = data.ef;
+      var i = 0;
+      var len = effects.length;
+      while (i < len) {
+        if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
+          if (effects[i].ty === 5) {
+            return effectElements[i];
+          }
+          return effectElements[i]();
+        }
+        i += 1;
+      }
+      throw new Error();
+    }
+    var _propertyGroup = propertyGroupFactory(groupInterface, propertyGroup);
+
+    var effectElements = [];
+    var i;
+    var len = data.ef.length;
+    for (i = 0; i < len; i += 1) {
+      if (data.ef[i].ty === 5) {
+        effectElements.push(createGroupInterface(data.ef[i], elements.effectElements[i], elements.effectElements[i].propertyGroup, elem));
+      } else {
+        effectElements.push(createValueInterface(elements.effectElements[i], data.ef[i].ty, elem, _propertyGroup));
+      }
+    }
+
+    if (data.mn === 'ADBE Color Control') {
+      Object.defineProperty(groupInterface, 'color', {
+        get: function () {
+          return effectElements[0]();
+        },
+      });
+    }
+    Object.defineProperties(groupInterface, {
+      numProperties: {
+        get: function () {
+          return data.np;
+        },
+      },
+      _name: { value: data.nm },
+      propertyGroup: { value: _propertyGroup },
+    });
+    groupInterface.enabled = data.en !== 0;
+    groupInterface.active = groupInterface.enabled;
+    return groupInterface;
+  }
+
+  function createValueInterface(element, type, elem, propertyGroup) {
+    var expressionProperty = ExpressionPropertyInterface(element.p);
+    function interfaceFunction() {
+      if (type === 10) {
+        return elem.comp.compInterface(element.p.v);
+      }
+      return expressionProperty();
+    }
+
+    if (element.p.setGroupProperty) {
+      element.p.setGroupProperty(PropertyInterface('', propertyGroup));
+    }
+
+    return interfaceFunction;
+  }
+
+  return ob;
+}());
+
+const ShapePathInterface = (
+
+  function () {
+    return function pathInterfaceFactory(shape, view, propertyGroup) {
+      var prop = view.sh;
+
+      function interfaceFunction(val) {
+        if (val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2) {
+          return interfaceFunction.path;
+        }
+        return null;
+      }
+
+      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+      prop.setGroupProperty(PropertyInterface('Path', _propertyGroup));
+      Object.defineProperties(interfaceFunction, {
+        path: {
+          get: function () {
+            if (prop.k) {
+              prop.getValue();
+            }
+            return prop;
+          },
+        },
+        shape: {
+          get: function () {
+            if (prop.k) {
+              prop.getValue();
+            }
+            return prop;
+          },
+        },
+        _name: { value: shape.nm },
+        ix: { value: shape.ix },
+        propertyIndex: { value: shape.ix },
+        mn: { value: shape.mn },
+        propertyGroup: { value: propertyGroup },
+      });
+      return interfaceFunction;
+    };
+  }()
+);
+
+const ShapeExpressionInterface = (function () {
+  function iterateElements(shapes, view, propertyGroup) {
+    var arr = [];
+    var i;
+    var len = shapes ? shapes.length : 0;
+    for (i = 0; i < len; i += 1) {
+      if (shapes[i].ty === 'gr') {
+        arr.push(groupInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'fl') {
+        arr.push(fillInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'st') {
+        arr.push(strokeInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'tm') {
+        arr.push(trimInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'tr') {
+        // arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
+      } else if (shapes[i].ty === 'el') {
+        arr.push(ellipseInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'sr') {
+        arr.push(starInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'sh') {
+        arr.push(ShapePathInterface(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'rc') {
+        arr.push(rectInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'rd') {
+        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;
+  }
+
+  function contentsInterfaceFactory(shape, view, propertyGroup) {
+    var interfaces;
+    var interfaceFunction = function _interfaceFunction(value) {
+      var i = 0;
+      var len = interfaces.length;
+      while (i < len) {
+        if (interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value) {
+          return interfaces[i];
+        }
+        i += 1;
+      }
+      if (typeof value === 'number') {
+        return interfaces[value - 1];
+      }
+      return null;
+    };
+
+    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup);
+    interfaceFunction.numProperties = interfaces.length;
+    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
+    interfaceFunction.transform = transformInterface;
+    interfaceFunction.propertyIndex = shape.cix;
+    interfaceFunction._name = shape.nm;
+
+    return interfaceFunction;
+  }
+
+  function groupInterfaceFactory(shape, view, propertyGroup) {
+    var interfaceFunction = function _interfaceFunction(value) {
+      switch (value) {
+        case 'ADBE Vectors Group':
+        case 'Contents':
+        case 2:
+          return interfaceFunction.content;
+          // Not necessary for now. Keeping them here in case a new case appears
+          // case 'ADBE Vector Transform Group':
+          // case 3:
+        default:
+          return interfaceFunction.transform;
+      }
+    };
+    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var content = contentsInterfaceFactory(shape, view, interfaceFunction.propertyGroup);
+    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
+    interfaceFunction.content = content;
+    interfaceFunction.transform = transformInterface;
+    Object.defineProperty(interfaceFunction, '_name', {
+      get: function () {
+        return shape.nm;
+      },
+    });
+    // interfaceFunction.content = interfaceFunction;
+    interfaceFunction.numProperties = shape.np;
+    interfaceFunction.propertyIndex = shape.ix;
+    interfaceFunction.nm = shape.nm;
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function fillInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      if (val === 'Color' || val === 'color') {
+        return interfaceFunction.color;
+      } if (val === 'Opacity' || val === 'opacity') {
+        return interfaceFunction.opacity;
+      }
+      return null;
+    }
+    Object.defineProperties(interfaceFunction, {
+      color: {
+        get: ExpressionPropertyInterface(view.c),
+      },
+      opacity: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      _name: { value: shape.nm },
+      mn: { value: shape.mn },
+    });
+
+    view.c.setGroupProperty(PropertyInterface('Color', propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
+    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 () {
+          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() {
+    function interfaceFunction() {
+      return null;
+    }
+    return interfaceFunction;
+  }
+
+  function strokeInterfaceFactory(shape, view, propertyGroup) {
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup);
+    function addPropertyToDashOb(i) {
+      Object.defineProperty(dashOb, shape.d[i].nm, {
+        get: ExpressionPropertyInterface(view.d.dataProps[i].p),
+      });
+    }
+    var i;
+    var len = shape.d ? shape.d.length : 0;
+    var dashOb = {};
+    for (i = 0; i < len; i += 1) {
+      addPropertyToDashOb(i);
+      view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup);
+    }
+
+    function interfaceFunction(val) {
+      if (val === 'Color' || val === 'color') {
+        return interfaceFunction.color;
+      } if (val === 'Opacity' || val === 'opacity') {
+        return interfaceFunction.opacity;
+      } if (val === 'Stroke Width' || val === 'stroke width') {
+        return interfaceFunction.strokeWidth;
+      }
+      return null;
+    }
+    Object.defineProperties(interfaceFunction, {
+      color: {
+        get: ExpressionPropertyInterface(view.c),
+      },
+      opacity: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      strokeWidth: {
+        get: ExpressionPropertyInterface(view.w),
+      },
+      dash: {
+        get: function () {
+          return dashOb;
+        },
+      },
+      _name: { value: shape.nm },
+      mn: { value: shape.mn },
+    });
+
+    view.c.setGroupProperty(PropertyInterface('Color', _propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    view.w.setGroupProperty(PropertyInterface('Stroke Width', _propertyGroup));
+    return interfaceFunction;
+  }
+
+  function trimInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      if (val === shape.e.ix || val === 'End' || val === 'end') {
+        return interfaceFunction.end;
+      }
+      if (val === shape.s.ix) {
+        return interfaceFunction.start;
+      }
+      if (val === shape.o.ix) {
+        return interfaceFunction.offset;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaceFunction.propertyIndex = shape.ix;
+
+    view.s.setGroupProperty(PropertyInterface('Start', _propertyGroup));
+    view.e.setGroupProperty(PropertyInterface('End', _propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
+    interfaceFunction.propertyIndex = shape.ix;
+    interfaceFunction.propertyGroup = propertyGroup;
+
+    Object.defineProperties(interfaceFunction, {
+      start: {
+        get: ExpressionPropertyInterface(view.s),
+      },
+      end: {
+        get: ExpressionPropertyInterface(view.e),
+      },
+      offset: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function transformInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.a.ix === value || value === 'Anchor Point') {
+        return interfaceFunction.anchorPoint;
+      }
+      if (shape.o.ix === value || value === 'Opacity') {
+        return interfaceFunction.opacity;
+      }
+      if (shape.p.ix === value || value === 'Position') {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value || value === 'Rotation' || value === 'ADBE Vector Rotation') {
+        return interfaceFunction.rotation;
+      }
+      if (shape.s.ix === value || value === 'Scale') {
+        return interfaceFunction.scale;
+      }
+      if ((shape.sk && shape.sk.ix === value) || value === 'Skew') {
+        return interfaceFunction.skew;
+      }
+      if ((shape.sa && shape.sa.ix === value) || value === 'Skew Axis') {
+        return interfaceFunction.skewAxis;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    view.transform.mProps.a.setGroupProperty(PropertyInterface('Anchor Point', _propertyGroup));
+    view.transform.mProps.s.setGroupProperty(PropertyInterface('Scale', _propertyGroup));
+    view.transform.mProps.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+    if (view.transform.mProps.sk) {
+      view.transform.mProps.sk.setGroupProperty(PropertyInterface('Skew', _propertyGroup));
+      view.transform.mProps.sa.setGroupProperty(PropertyInterface('Skew Angle', _propertyGroup));
+    }
+    view.transform.op.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
+    Object.defineProperties(interfaceFunction, {
+      opacity: {
+        get: ExpressionPropertyInterface(view.transform.mProps.o),
+      },
+      position: {
+        get: ExpressionPropertyInterface(view.transform.mProps.p),
+      },
+      anchorPoint: {
+        get: ExpressionPropertyInterface(view.transform.mProps.a),
+      },
+      scale: {
+        get: ExpressionPropertyInterface(view.transform.mProps.s),
+      },
+      rotation: {
+        get: ExpressionPropertyInterface(view.transform.mProps.r),
+      },
+      skew: {
+        get: ExpressionPropertyInterface(view.transform.mProps.sk),
+      },
+      skewAxis: {
+        get: ExpressionPropertyInterface(view.transform.mProps.sa),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.ty = 'tr';
+    interfaceFunction.mn = shape.mn;
+    interfaceFunction.propertyGroup = propertyGroup;
+    return interfaceFunction;
+  }
+
+  function ellipseInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.s.ix === value) {
+        return interfaceFunction.size;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    interfaceFunction.propertyIndex = shape.ix;
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      size: {
+        get: ExpressionPropertyInterface(prop.s),
+      },
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function starInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value) {
+        return interfaceFunction.rotation;
+      }
+      if (shape.pt.ix === value) {
+        return interfaceFunction.points;
+      }
+      if (shape.or.ix === value || value === 'ADBE Vector Star Outer Radius') {
+        return interfaceFunction.outerRadius;
+      }
+      if (shape.os.ix === value) {
+        return interfaceFunction.outerRoundness;
+      }
+      if (shape.ir && (shape.ir.ix === value || value === 'ADBE Vector Star Inner Radius')) {
+        return interfaceFunction.innerRadius;
+      }
+      if (shape.is && shape.is.ix === value) {
+        return interfaceFunction.innerRoundness;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.or.setGroupProperty(PropertyInterface('Outer Radius', _propertyGroup));
+    prop.os.setGroupProperty(PropertyInterface('Outer Roundness', _propertyGroup));
+    prop.pt.setGroupProperty(PropertyInterface('Points', _propertyGroup));
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+    if (shape.ir) {
+      prop.ir.setGroupProperty(PropertyInterface('Inner Radius', _propertyGroup));
+      prop.is.setGroupProperty(PropertyInterface('Inner Roundness', _propertyGroup));
+    }
+
+    Object.defineProperties(interfaceFunction, {
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      rotation: {
+        get: ExpressionPropertyInterface(prop.r),
+      },
+      points: {
+        get: ExpressionPropertyInterface(prop.pt),
+      },
+      outerRadius: {
+        get: ExpressionPropertyInterface(prop.or),
+      },
+      outerRoundness: {
+        get: ExpressionPropertyInterface(prop.os),
+      },
+      innerRadius: {
+        get: ExpressionPropertyInterface(prop.ir),
+      },
+      innerRoundness: {
+        get: ExpressionPropertyInterface(prop.is),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function rectInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.p.ix === value) {
+        return interfaceFunction.position;
+      }
+      if (shape.r.ix === value) {
+        return interfaceFunction.roundness;
+      }
+      if (shape.s.ix === value || value === 'Size' || value === 'ADBE Vector Rect Size') {
+        return interfaceFunction.size;
+      }
+      return null;
+    }
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+
+    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
+    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
+    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      position: {
+        get: ExpressionPropertyInterface(prop.p),
+      },
+      roundness: {
+        get: ExpressionPropertyInterface(prop.r),
+      },
+      size: {
+        get: ExpressionPropertyInterface(prop.s),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function roundedInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.r.ix === value || value === 'Round Corners 1') {
+        return interfaceFunction.radius;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.rd.setGroupProperty(PropertyInterface('Radius', _propertyGroup));
+
+    Object.defineProperties(interfaceFunction, {
+      radius: {
+        get: ExpressionPropertyInterface(prop.rd),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  function repeaterInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(value) {
+      if (shape.c.ix === value || value === 'Copies') {
+        return interfaceFunction.copies;
+      } if (shape.o.ix === value || value === 'Offset') {
+        return interfaceFunction.offset;
+      }
+      return null;
+    }
+
+    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
+    var prop = view;
+    interfaceFunction.propertyIndex = shape.ix;
+    prop.c.setGroupProperty(PropertyInterface('Copies', _propertyGroup));
+    prop.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
+    Object.defineProperties(interfaceFunction, {
+      copies: {
+        get: ExpressionPropertyInterface(prop.c),
+      },
+      offset: {
+        get: ExpressionPropertyInterface(prop.o),
+      },
+      _name: { value: shape.nm },
+    });
+    interfaceFunction.mn = shape.mn;
+    return interfaceFunction;
+  }
+
+  return function (shapes, view, propertyGroup) {
+    var interfaces;
+    function _interfaceFunction(value) {
+      if (typeof value === 'number') {
+        value = value === undefined ? 1 : value;
+        if (value === 0) {
+          return propertyGroup;
+        }
+        return interfaces[value - 1];
+      }
+      var i = 0;
+      var len = interfaces.length;
+      while (i < len) {
+        if (interfaces[i]._name === value) {
+          return interfaces[i];
+        }
+        i += 1;
+      }
+      return null;
+    }
+    function parentGroupWrapper() {
+      return propertyGroup;
+    }
+    _interfaceFunction.propertyGroup = propertyGroupFactory(_interfaceFunction, parentGroupWrapper);
+    interfaces = iterateElements(shapes, view, _interfaceFunction.propertyGroup);
+    _interfaceFunction.numProperties = interfaces.length;
+    _interfaceFunction._name = 'Contents';
+    return _interfaceFunction;
+  };
+}());
+
+const TextExpressionInterface = (function () {
+  return function (elem) {
+    var _sourceText;
+    function _thisLayerFunction(name) {
+      switch (name) {
+        case 'ADBE Text Document':
+          return _thisLayerFunction.sourceText;
+        default:
+          return null;
+      }
+    }
+    Object.defineProperty(_thisLayerFunction, 'sourceText', {
+      get: function () {
+        elem.textProperty.getValue();
+        var stringValue = elem.textProperty.currentData.t;
+        if (!_sourceText || stringValue !== _sourceText.value) {
+          _sourceText = new String(stringValue); // eslint-disable-line no-new-wrappers
+          // If stringValue is an empty string, eval returns undefined, so it has to be returned as a String primitive
+          _sourceText.value = stringValue || new String(stringValue); // eslint-disable-line no-new-wrappers
+          Object.defineProperty(_sourceText, 'style', {
+            get: function () {
+              return {
+                fillColor: elem.textProperty.currentData.fc,
+              };
+            },
+          });
+        }
+        return _sourceText;
+      },
+    });
+    return _thisLayerFunction;
+  };
+}());
+
+const FootageInterface = (function () {
+  var outlineInterfaceFactory = (function (elem) {
+    var currentPropertyName = '';
+    var currentProperty = elem.getFootageData();
+    function init() {
+      currentPropertyName = '';
+      currentProperty = elem.getFootageData();
+      return searchProperty;
+    }
+    function searchProperty(value) {
+      if (currentProperty[value]) {
+        currentPropertyName = value;
+        currentProperty = currentProperty[value];
+        if (typeof currentProperty === 'object') {
+          return searchProperty;
+        }
+        return currentProperty;
+      }
+      var propertyNameIndex = value.indexOf(currentPropertyName);
+      if (propertyNameIndex !== -1) {
+        var index = parseInt(value.substr(propertyNameIndex + currentPropertyName.length), 10);
+        currentProperty = currentProperty[index];
+        if (typeof currentProperty === 'object') {
+          return searchProperty;
+        }
+        return currentProperty;
+      }
+      return '';
+    }
+    return init;
+  });
+
+  var dataInterfaceFactory = function (elem) {
+    function interfaceFunction(value) {
+      if (value === 'Outline') {
+        return interfaceFunction.outlineInterface();
+      }
+      return null;
+    }
+
+    interfaceFunction._name = 'Outline';
+    interfaceFunction.outlineInterface = outlineInterfaceFactory(elem);
+    return interfaceFunction;
+  };
+
+  return function (elem) {
+    function _interfaceFunction(value) {
+      if (value === 'Data') {
+        return _interfaceFunction.dataInterface;
+      }
+      return null;
+    }
+
+    _interfaceFunction._name = 'Data';
+    _interfaceFunction.dataInterface = dataInterfaceFactory(elem);
+    return _interfaceFunction;
+  };
+}());
+
+var interfaces = {
+  layer: LayerExpressionInterface,
+  effects: EffectsExpressionInterface,
+  comp: CompExpressionInterface,
+  shape: ShapeExpressionInterface,
+  text: TextExpressionInterface,
+  footage: FootageInterface,
+};
+
+function getInterface(type) {
+  return interfaces[type] || null;
+}
+
+const expressionHelpers = (function () {
+  function searchExpressions(elem, data, prop) {
+    if (data.x) {
+      prop.k = true;
+      prop.x = true;
+      prop.initiateExpression = ExpressionManager.initiateExpression;
+      prop.effectsSequence.push(prop.initiateExpression(elem, data, prop).bind(prop));
+    }
+  }
+
+  function getValueAtTime(frameNum) {
+    frameNum *= this.elem.globalData.frameRate;
+    frameNum -= this.offsetTime;
+    if (frameNum !== this._cachingAtTime.lastFrame) {
+      this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0;
+      this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime);
+      this._cachingAtTime.lastFrame = frameNum;
+    }
+    return this._cachingAtTime.value;
+  }
+
+  function getSpeedAtTime(frameNum) {
+    var delta = -0.01;
+    var v1 = this.getValueAtTime(frameNum);
+    var v2 = this.getValueAtTime(frameNum + delta);
+    var speed = 0;
+    if (v1.length) {
+      var i;
+      for (i = 0; i < v1.length; i += 1) {
+        speed += Math.pow(v2[i] - v1[i], 2);
+      }
+      speed = Math.sqrt(speed) * 100;
+    } else {
+      speed = 0;
+    }
+    return speed;
+  }
+
+  function getVelocityAtTime(frameNum) {
+    if (this.vel !== undefined) {
+      return this.vel;
+    }
+    var delta = -0.001;
+    // frameNum += this.elem.data.st;
+    var v1 = this.getValueAtTime(frameNum);
+    var v2 = this.getValueAtTime(frameNum + delta);
+    var velocity;
+    if (v1.length) {
+      velocity = createTypedArray('float32', v1.length);
+      var i;
+      for (i = 0; i < v1.length; i += 1) {
+        // removing frameRate
+        // if needed, don't add it here
+        // velocity[i] = this.elem.globalData.frameRate*((v2[i] - v1[i])/delta);
+        velocity[i] = (v2[i] - v1[i]) / delta;
+      }
+    } else {
+      velocity = (v2 - v1) / delta;
+    }
+    return velocity;
+  }
+
+  function getStaticValueAtTime() {
+    return this.pv;
+  }
+
+  function setGroupProperty(propertyGroup) {
+    this.propertyGroup = propertyGroup;
+  }
+
+  return {
+    searchExpressions: searchExpressions,
+    getSpeedAtTime: getSpeedAtTime,
+    getVelocityAtTime: getVelocityAtTime,
+    getValueAtTime: getValueAtTime,
+    getStaticValueAtTime: getStaticValueAtTime,
+    setGroupProperty: setGroupProperty,
+  };
+}());
+
+function addPropertyDecorator() {
+  function loopOut(type, duration, durationFlag) {
+    if (!this.k || !this.keyframes) {
+      return this.pv;
+    }
+    type = type ? type.toLowerCase() : '';
+    var currentFrame = this.comp.renderedFrame;
+    var keyframes = this.keyframes;
+    var lastKeyFrame = keyframes[keyframes.length - 1].t;
+    if (currentFrame <= lastKeyFrame) {
+      return this.pv;
+    }
+    var cycleDuration;
+    var firstKeyFrame;
+    if (!durationFlag) {
+      if (!duration || duration > keyframes.length - 1) {
+        duration = keyframes.length - 1;
+      }
+      firstKeyFrame = keyframes[keyframes.length - 1 - duration].t;
+      cycleDuration = lastKeyFrame - firstKeyFrame;
+    } else {
+      if (!duration) {
+        cycleDuration = Math.max(0, lastKeyFrame - this.elem.data.ip);
+      } else {
+        cycleDuration = Math.abs(lastKeyFrame - this.elem.comp.globalData.frameRate * duration);
+      }
+      firstKeyFrame = lastKeyFrame - cycleDuration;
+    }
+    var i;
+    var len;
+    var ret;
+    if (type === 'pingpong') {
+      var iterations = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
+      if (iterations % 2 !== 0) {
+          return this.getValueAtTime(((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      }
+    } else if (type === 'offset') {
+      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+        var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      var repeats = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
+      if (this.pv.length) {
+        ret = new Array(initV.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = (endV[i] - initV[i]) * repeats + current[i];
+        }
+        return ret;
+      }
+      return (endV - initV) * repeats + current;
+    } else if (type === 'continue') {
+      var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+      var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0);
+      if (this.pv.length) {
+        ret = new Array(lastValue.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+            ret[i] = lastValue[i] + (lastValue[i] - nextLastValue[i]) * ((currentFrame - lastKeyFrame) / this.comp.globalData.frameRate) / 0.0005; // eslint-disable-line
+        }
+        return ret;
+      }
+      return lastValue + (lastValue - nextLastValue) * (((currentFrame - lastKeyFrame)) / 0.001);
+    }
+      return this.getValueAtTime((((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+
+  }
+
+  function loopIn(type, duration, durationFlag) {
+    if (!this.k) {
+      return this.pv;
+    }
+    type = type ? type.toLowerCase() : '';
+    var currentFrame = this.comp.renderedFrame;
+    var keyframes = this.keyframes;
+    var firstKeyFrame = keyframes[0].t;
+    if (currentFrame >= firstKeyFrame) {
+      return this.pv;
+    }
+    var cycleDuration;
+    var lastKeyFrame;
+    if (!durationFlag) {
+      if (!duration || duration > keyframes.length - 1) {
+        duration = keyframes.length - 1;
+      }
+      lastKeyFrame = keyframes[duration].t;
+      cycleDuration = lastKeyFrame - firstKeyFrame;
+    } else {
+      if (!duration) {
+        cycleDuration = Math.max(0, this.elem.data.op - firstKeyFrame);
+      } else {
+        cycleDuration = Math.abs(this.elem.comp.globalData.frameRate * duration);
+      }
+      lastKeyFrame = firstKeyFrame + cycleDuration;
+    }
+    var i;
+    var len;
+    var ret;
+    if (type === 'pingpong') {
+      var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration);
+      if (iterations % 2 === 0) {
+          return this.getValueAtTime((((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+      }
+    } else if (type === 'offset') {
+      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
+      var current = this.getValueAtTime((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration) + firstKeyFrame) / this.comp.globalData.frameRate, 0);
+      var repeats = Math.floor((firstKeyFrame - currentFrame) / cycleDuration) + 1;
+      if (this.pv.length) {
+        ret = new Array(initV.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = current[i] - (endV[i] - initV[i]) * repeats;
+        }
+        return ret;
+      }
+      return current - (endV - initV) * repeats;
+    } else if (type === 'continue') {
+      var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
+      var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0);
+      if (this.pv.length) {
+        ret = new Array(firstValue.length);
+        len = ret.length;
+        for (i = 0; i < len; i += 1) {
+          ret[i] = firstValue[i] + ((firstValue[i] - nextFirstValue[i]) * (firstKeyFrame - currentFrame)) / 0.001;
+        }
+        return ret;
+      }
+      return firstValue + ((firstValue - nextFirstValue) * (firstKeyFrame - currentFrame)) / 0.001;
+    }
+      return this.getValueAtTime(((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame))) / this.comp.globalData.frameRate, 0); // eslint-disable-line
+
+  }
+
+  function smooth(width, samples) {
+    if (!this.k) {
+      return this.pv;
+    }
+    width = (width || 0.4) * 0.5;
+    samples = Math.floor(samples || 5);
+    if (samples <= 1) {
+      return this.pv;
+    }
+    var currentTime = this.comp.renderedFrame / this.comp.globalData.frameRate;
+    var initFrame = currentTime - width;
+    var endFrame = currentTime + width;
+    var sampleFrequency = samples > 1 ? (endFrame - initFrame) / (samples - 1) : 1;
+    var i = 0;
+    var j = 0;
+    var value;
+    if (this.pv.length) {
+      value = createTypedArray('float32', this.pv.length);
+    } else {
+      value = 0;
+    }
+    var sampleValue;
+    while (i < samples) {
+      sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency);
+      if (this.pv.length) {
+        for (j = 0; j < this.pv.length; j += 1) {
+          value[j] += sampleValue[j];
+        }
+      } else {
+        value += sampleValue;
+      }
+      i += 1;
+    }
+    if (this.pv.length) {
+      for (j = 0; j < this.pv.length; j += 1) {
+        value[j] /= samples;
+      }
+    } else {
+      value /= samples;
+    }
+    return value;
+  }
+
+  function getTransformValueAtTime(time) {
+    if (!this._transformCachingAtTime) {
+      this._transformCachingAtTime = {
+        v: new Matrix(),
+      };
+    }
+    /// /
+    var matrix = this._transformCachingAtTime.v;
+    matrix.cloneFromProps(this.pre.props);
+    if (this.appliedTransformations < 1) {
+      var anchor = this.a.getValueAtTime(time);
+      matrix.translate(
+        -anchor[0] * this.a.mult,
+        -anchor[1] * this.a.mult,
+        anchor[2] * this.a.mult
+      );
+    }
+    if (this.appliedTransformations < 2) {
+      var scale = this.s.getValueAtTime(time);
+      matrix.scale(
+        scale[0] * this.s.mult,
+        scale[1] * this.s.mult,
+        scale[2] * this.s.mult
+      );
+    }
+    if (this.sk && this.appliedTransformations < 3) {
+      var skew = this.sk.getValueAtTime(time);
+      var skewAxis = this.sa.getValueAtTime(time);
+      matrix.skewFromAxis(-skew * this.sk.mult, skewAxis * this.sa.mult);
+    }
+    if (this.r && this.appliedTransformations < 4) {
+      var rotation = this.r.getValueAtTime(time);
+      matrix.rotate(-rotation * this.r.mult);
+    } else if (!this.r && this.appliedTransformations < 4) {
+      var rotationZ = this.rz.getValueAtTime(time);
+      var rotationY = this.ry.getValueAtTime(time);
+      var rotationX = this.rx.getValueAtTime(time);
+      var orientation = this.or.getValueAtTime(time);
+      matrix.rotateZ(-rotationZ * this.rz.mult)
+        .rotateY(rotationY * this.ry.mult)
+        .rotateX(rotationX * this.rx.mult)
+        .rotateZ(-orientation[2] * this.or.mult)
+        .rotateY(orientation[1] * this.or.mult)
+        .rotateX(orientation[0] * this.or.mult);
+    }
+    if (this.data.p && this.data.p.s) {
+      var positionX = this.px.getValueAtTime(time);
+      var positionY = this.py.getValueAtTime(time);
+      if (this.data.p.z) {
+        var positionZ = this.pz.getValueAtTime(time);
+        matrix.translate(
+          positionX * this.px.mult,
+          positionY * this.py.mult,
+          -positionZ * this.pz.mult
+        );
+      } else {
+        matrix.translate(positionX * this.px.mult, positionY * this.py.mult, 0);
+      }
+    } else {
+      var position = this.p.getValueAtTime(time);
+      matrix.translate(
+        position[0] * this.p.mult,
+        position[1] * this.p.mult,
+        -position[2] * this.p.mult
+      );
+    }
+    return matrix;
+    /// /
+  }
+
+  function getTransformStaticValueAtTime() {
+    return this.v.clone(new Matrix());
+  }
+
+  var getTransformProperty = TransformPropertyFactory.getTransformProperty;
+  TransformPropertyFactory.getTransformProperty = function (elem, data, container) {
+    var prop = getTransformProperty(elem, data, container);
+    if (prop.dynamicProperties.length) {
+      prop.getValueAtTime = getTransformValueAtTime.bind(prop);
+    } else {
+      prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop);
+    }
+    prop.setGroupProperty = expressionHelpers.setGroupProperty;
+    return prop;
+  };
+
+  var propertyGetProp = PropertyFactory.getProp;
+  PropertyFactory.getProp = function (elem, data, type, mult, container) {
+    var prop = propertyGetProp(elem, data, type, mult, container);
+    // prop.getVelocityAtTime = getVelocityAtTime;
+    // prop.loopOut = loopOut;
+    // prop.loopIn = loopIn;
+    if (prop.kf) {
+      prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop);
+    } else {
+      prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop);
+    }
+    prop.setGroupProperty = expressionHelpers.setGroupProperty;
+    prop.loopOut = loopOut;
+    prop.loopIn = loopIn;
+    prop.smooth = smooth;
+    prop.getVelocityAtTime = expressionHelpers.getVelocityAtTime.bind(prop);
+    prop.getSpeedAtTime = expressionHelpers.getSpeedAtTime.bind(prop);
+    prop.numKeys = data.a === 1 ? data.k.length : 0;
+    prop.propertyIndex = data.ix;
+    var value = 0;
+    if (type !== 0) {
+      value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length);
+    }
+    prop._cachingAtTime = {
+      lastFrame: initialDefaultFrame,
+      lastIndex: 0,
+      value: value,
+    };
+    expressionHelpers.searchExpressions(elem, data, prop);
+    if (prop.k) {
+      container.addDynamicProperty(prop);
+    }
+
+    return prop;
+  };
+
+  function getShapeValueAtTime(frameNum) {
+    // For now this caching object is created only when needed instead of creating it when the shape is initialized.
+    if (!this._cachingAtTime) {
+      this._cachingAtTime = {
+        shapeValue: shapePool.clone(this.pv),
+        lastIndex: 0,
+        lastTime: initialDefaultFrame,
+      };
+    }
+
+    frameNum *= this.elem.globalData.frameRate;
+    frameNum -= this.offsetTime;
+    if (frameNum !== this._cachingAtTime.lastTime) {
+      this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0;
+      this._cachingAtTime.lastTime = frameNum;
+      this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime);
+    }
+    return this._cachingAtTime.shapeValue;
+  }
+
+  var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction();
+  var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction();
+
+  function ShapeExpressions() {}
+  ShapeExpressions.prototype = {
+    vertices: function (prop, time) {
+      if (this.k) {
+        this.getValue();
+      }
+      var shapePath = this.v;
+      if (time !== undefined) {
+        shapePath = this.getValueAtTime(time, 0);
+      }
+      var i;
+      var len = shapePath._length;
+      var vertices = shapePath[prop];
+      var points = shapePath.v;
+      var arr = createSizedArray(len);
+      for (i = 0; i < len; i += 1) {
+        if (prop === 'i' || prop === 'o') {
+          arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]];
+        } else {
+          arr[i] = [vertices[i][0], vertices[i][1]];
+        }
+      }
+      return arr;
+    },
+    points: function (time) {
+      return this.vertices('v', time);
+    },
+    inTangents: function (time) {
+      return this.vertices('i', time);
+    },
+    outTangents: function (time) {
+      return this.vertices('o', time);
+    },
+    isClosed: function () {
+      return this.v.c;
+    },
+    pointOnPath: function (perc, time) {
+      var shapePath = this.v;
+      if (time !== undefined) {
+        shapePath = this.getValueAtTime(time, 0);
+      }
+      if (!this._segmentsLength) {
+        this._segmentsLength = bez.getSegmentsLength(shapePath);
+      }
+
+      var segmentsLength = this._segmentsLength;
+      var lengths = segmentsLength.lengths;
+      var lengthPos = segmentsLength.totalLength * perc;
+      var i = 0;
+      var len = lengths.length;
+      var accumulatedLength = 0;
+      var pt;
+      while (i < len) {
+        if (accumulatedLength + lengths[i].addedLength > lengthPos) {
+          var initIndex = i;
+          var endIndex = (shapePath.c && i === len - 1) ? 0 : i + 1;
+          var segmentPerc = (lengthPos - accumulatedLength) / lengths[i].addedLength;
+          pt = bez.getPointInSegment(shapePath.v[initIndex], shapePath.v[endIndex], shapePath.o[initIndex], shapePath.i[endIndex], segmentPerc, lengths[i]);
+          break;
+        } else {
+          accumulatedLength += lengths[i].addedLength;
+        }
+        i += 1;
+      }
+      if (!pt) {
+        pt = shapePath.c ? [shapePath.v[0][0], shapePath.v[0][1]] : [shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1]];
+      }
+      return pt;
+    },
+    vectorOnPath: function (perc, time, vectorType) {
+      // perc doesn't use triple equality because it can be a Number object as well as a primitive.
+      if (perc == 1) { // eslint-disable-line eqeqeq
+        perc = this.v.c;
+      } else if (perc == 0) { // eslint-disable-line eqeqeq
+        perc = 0.999;
+      }
+      var pt1 = this.pointOnPath(perc, time);
+      var pt2 = this.pointOnPath(perc + 0.001, time);
+      var xLength = pt2[0] - pt1[0];
+      var yLength = pt2[1] - pt1[1];
+      var magnitude = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2));
+      if (magnitude === 0) {
+        return [0, 0];
+      }
+      var unitVector = vectorType === 'tangent' ? [xLength / magnitude, yLength / magnitude] : [-yLength / magnitude, xLength / magnitude];
+      return unitVector;
+    },
+    tangentOnPath: function (perc, time) {
+      return this.vectorOnPath(perc, time, 'tangent');
+    },
+    normalOnPath: function (perc, time) {
+      return this.vectorOnPath(perc, time, 'normal');
+    },
+    setGroupProperty: expressionHelpers.setGroupProperty,
+    getValueAtTime: expressionHelpers.getStaticValueAtTime,
+  };
+  extendPrototype([ShapeExpressions], ShapePropertyConstructorFunction);
+  extendPrototype([ShapeExpressions], KeyframedShapePropertyConstructorFunction);
+  KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime;
+  KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression;
+
+  var propertyGetShapeProp = ShapePropertyFactory.getShapeProp;
+  ShapePropertyFactory.getShapeProp = function (elem, data, type, arr, trims) {
+    var prop = propertyGetShapeProp(elem, data, type, arr, trims);
+    prop.propertyIndex = data.ix;
+    prop.lock = false;
+    if (type === 3) {
+      expressionHelpers.searchExpressions(elem, data.pt, prop);
+    } else if (type === 4) {
+      expressionHelpers.searchExpressions(elem, data.ks, prop);
+    }
+    if (prop.k) {
+      elem.addDynamicProperty(prop);
+    }
+    return prop;
+  };
+}
+
+function initialize$1() {
+  addPropertyDecorator();
+}
+
+function addDecorator() {
+  function searchExpressions() {
+    if (this.data.d.x) {
+      this.calculateExpression = ExpressionManager.initiateExpression.bind(this)(this.elem, this.data.d, this);
+      this.addEffect(this.getExpressionValue.bind(this));
+      return true;
+    }
+    return null;
+  }
+
+  TextProperty.prototype.getExpressionValue = function (currentValue, text) {
+    var newValue = this.calculateExpression(text);
+    if (currentValue.t !== newValue) {
+      var newData = {};
+      this.copyData(newData, currentValue);
+      newData.t = newValue.toString();
+      newData.__complete = false;
+      return newData;
+    }
+    return currentValue;
+  };
+
+  TextProperty.prototype.searchProperty = function () {
+    var isKeyframed = this.searchKeyframes();
+    var hasExpressions = this.searchExpressions();
+    this.kf = isKeyframed || hasExpressions;
+    return this.kf;
+  };
+
+  TextProperty.prototype.searchExpressions = searchExpressions;
+}
+
+function initialize() {
+  addDecorator();
+}
+
+function SVGComposableEffect() {
+
+}
+SVGComposableEffect.prototype = {
+  createMergeNode: (resultId, ins) => {
+    var feMerge = createNS('feMerge');
+    feMerge.setAttribute('result', resultId);
+    var feMergeNode;
+    var i;
+    for (i = 0; i < ins.length; i += 1) {
+      feMergeNode = createNS('feMergeNode');
+      feMergeNode.setAttribute('in', ins[i]);
+      feMerge.appendChild(feMergeNode);
+      feMerge.appendChild(feMergeNode);
+    }
+    return feMerge;
+  },
+};
+
+var linearFilterValue = '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0';
+
+function SVGTintFilter(filter, filterManager, elem, id, source) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'linearRGB');
+  feColorMatrix.setAttribute('values', linearFilterValue + ' 1 0');
+  this.linearFilter = feColorMatrix;
+  feColorMatrix.setAttribute('result', id + '_tint_1');
+  filter.appendChild(feColorMatrix);
+  feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+  feColorMatrix.setAttribute('values', '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0');
+  feColorMatrix.setAttribute('result', id + '_tint_2');
+  filter.appendChild(feColorMatrix);
+  this.matrixFilter = feColorMatrix;
+  var feMerge = this.createMergeNode(
+    id,
+    [
+      source,
+      id + '_tint_1',
+      id + '_tint_2',
+    ]
+  );
+  filter.appendChild(feMerge);
+}
+extendPrototype([SVGComposableEffect], SVGTintFilter);
+
+SVGTintFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var colorBlack = this.filterManager.effectElements[0].p.v;
+    var colorWhite = this.filterManager.effectElements[1].p.v;
+    var opacity = this.filterManager.effectElements[2].p.v / 100;
+    this.linearFilter.setAttribute('values', linearFilterValue + ' ' + opacity + ' 0');
+    this.matrixFilter.setAttribute('values', (colorWhite[0] - colorBlack[0]) + ' 0 0 0 ' + colorBlack[0] + ' ' + (colorWhite[1] - colorBlack[1]) + ' 0 0 0 ' + colorBlack[1] + ' ' + (colorWhite[2] - colorBlack[2]) + ' 0 0 0 ' + colorBlack[2] + ' 0 0 0 1 0');
+  }
+};
+
+function SVGFillFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
+  feColorMatrix.setAttribute('values', '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0');
+  feColorMatrix.setAttribute('result', id);
+  filter.appendChild(feColorMatrix);
+  this.matrixFilter = feColorMatrix;
+}
+
+SVGFillFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var color = this.filterManager.effectElements[2].p.v;
+    var opacity = this.filterManager.effectElements[6].p.v;
+    this.matrixFilter.setAttribute('values', '0 0 0 0 ' + color[0] + ' 0 0 0 0 ' + color[1] + ' 0 0 0 0 ' + color[2] + ' 0 0 0 ' + opacity + ' 0');
+  }
+};
+
+function SVGStrokeEffect(fil, filterManager, elem) {
+  this.initialized = false;
+  this.filterManager = filterManager;
+  this.elem = elem;
+  this.paths = [];
+}
+
+SVGStrokeEffect.prototype.initialize = function () {
+  var elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
+  var path;
+  var groupPath;
+  var i;
+  var len;
+  if (this.filterManager.effectElements[1].p.v === 1) {
+    len = this.elem.maskManager.masksProperties.length;
+    i = 0;
+  } else {
+    i = this.filterManager.effectElements[0].p.v - 1;
+    len = i + 1;
+  }
+  groupPath = createNS('g');
+  groupPath.setAttribute('fill', 'none');
+  groupPath.setAttribute('stroke-linecap', 'round');
+  groupPath.setAttribute('stroke-dashoffset', 1);
+  for (i; i < len; i += 1) {
+    path = createNS('path');
+    groupPath.appendChild(path);
+    this.paths.push({ p: path, m: i });
+  }
+  if (this.filterManager.effectElements[10].p.v === 3) {
+    var mask = createNS('mask');
+    var id = createElementID();
+    mask.setAttribute('id', id);
+    mask.setAttribute('mask-type', 'alpha');
+    mask.appendChild(groupPath);
+    this.elem.globalData.defs.appendChild(mask);
+    var g = createNS('g');
+    g.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
+    while (elemChildren[0]) {
+      g.appendChild(elemChildren[0]);
+    }
+    this.elem.layerElement.appendChild(g);
+    this.masker = mask;
+    groupPath.setAttribute('stroke', '#fff');
+  } else if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
+    if (this.filterManager.effectElements[10].p.v === 2) {
+      elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
+      while (elemChildren.length) {
+        this.elem.layerElement.removeChild(elemChildren[0]);
+      }
+    }
+    this.elem.layerElement.appendChild(groupPath);
+    this.elem.layerElement.removeAttribute('mask');
+    groupPath.setAttribute('stroke', '#fff');
+  }
+  this.initialized = true;
+  this.pathMasker = groupPath;
+};
+
+SVGStrokeEffect.prototype.renderFrame = function (forceRender) {
+  if (!this.initialized) {
+    this.initialize();
+  }
+  var i;
+  var len = this.paths.length;
+  var mask;
+  var path;
+  for (i = 0; i < len; i += 1) {
+    if (this.paths[i].m !== -1) {
+      mask = this.elem.maskManager.viewData[this.paths[i].m];
+      path = this.paths[i].p;
+      if (forceRender || this.filterManager._mdf || mask.prop._mdf) {
+        path.setAttribute('d', mask.lastPath);
+      }
+      if (forceRender || this.filterManager.effectElements[9].p._mdf || this.filterManager.effectElements[4].p._mdf || this.filterManager.effectElements[7].p._mdf || this.filterManager.effectElements[8].p._mdf || mask.prop._mdf) {
+        var dasharrayValue;
+        if (this.filterManager.effectElements[7].p.v !== 0 || this.filterManager.effectElements[8].p.v !== 100) {
+          var s = Math.min(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
+          var e = Math.max(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
+          var l = path.getTotalLength();
+          dasharrayValue = '0 0 0 ' + l * s + ' ';
+          var lineLength = l * (e - s);
+          var segment = 1 + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
+          var units = Math.floor(lineLength / segment);
+          var j;
+          for (j = 0; j < units; j += 1) {
+            dasharrayValue += '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01 + ' ';
+          }
+          dasharrayValue += '0 ' + l * 10 + ' 0 0';
+        } else {
+          dasharrayValue = '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
+        }
+        path.setAttribute('stroke-dasharray', dasharrayValue);
+      }
+    }
+  }
+  if (forceRender || this.filterManager.effectElements[4].p._mdf) {
+    this.pathMasker.setAttribute('stroke-width', this.filterManager.effectElements[4].p.v * 2);
+  }
+
+  if (forceRender || this.filterManager.effectElements[6].p._mdf) {
+    this.pathMasker.setAttribute('opacity', this.filterManager.effectElements[6].p.v);
+  }
+  if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
+    if (forceRender || this.filterManager.effectElements[3].p._mdf) {
+      var color = this.filterManager.effectElements[3].p.v;
+      this.pathMasker.setAttribute('stroke', 'rgb(' + bmFloor(color[0] * 255) + ',' + bmFloor(color[1] * 255) + ',' + bmFloor(color[2] * 255) + ')');
+    }
+  }
+};
+
+function SVGTritoneFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var feColorMatrix = createNS('feColorMatrix');
+  feColorMatrix.setAttribute('type', 'matrix');
+  feColorMatrix.setAttribute('color-interpolation-filters', 'linearRGB');
+  feColorMatrix.setAttribute('values', '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0');
+  filter.appendChild(feColorMatrix);
+  var feComponentTransfer = createNS('feComponentTransfer');
+  feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+  feComponentTransfer.setAttribute('result', id);
+  this.matrixFilter = feComponentTransfer;
+  var feFuncR = createNS('feFuncR');
+  feFuncR.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncR);
+  this.feFuncR = feFuncR;
+  var feFuncG = createNS('feFuncG');
+  feFuncG.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncG);
+  this.feFuncG = feFuncG;
+  var feFuncB = createNS('feFuncB');
+  feFuncB.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFuncB);
+  this.feFuncB = feFuncB;
+  filter.appendChild(feComponentTransfer);
+}
+
+SVGTritoneFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var color1 = this.filterManager.effectElements[0].p.v;
+    var color2 = this.filterManager.effectElements[1].p.v;
+    var color3 = this.filterManager.effectElements[2].p.v;
+    var tableR = color3[0] + ' ' + color2[0] + ' ' + color1[0];
+    var tableG = color3[1] + ' ' + color2[1] + ' ' + color1[1];
+    var tableB = color3[2] + ' ' + color2[2] + ' ' + color1[2];
+    this.feFuncR.setAttribute('tableValues', tableR);
+    this.feFuncG.setAttribute('tableValues', tableG);
+    this.feFuncB.setAttribute('tableValues', tableB);
+  }
+};
+
+function SVGProLevelsFilter(filter, filterManager, elem, id) {
+  this.filterManager = filterManager;
+  var effectElements = this.filterManager.effectElements;
+  var feComponentTransfer = createNS('feComponentTransfer');
+
+  // Red
+  if (effectElements[10].p.k || effectElements[10].p.v !== 0 || effectElements[11].p.k || effectElements[11].p.v !== 1 || effectElements[12].p.k || effectElements[12].p.v !== 1 || effectElements[13].p.k || effectElements[13].p.v !== 0 || effectElements[14].p.k || effectElements[14].p.v !== 1) {
+    this.feFuncR = this.createFeFunc('feFuncR', feComponentTransfer);
+  }
+  // Green
+  if (effectElements[17].p.k || effectElements[17].p.v !== 0 || effectElements[18].p.k || effectElements[18].p.v !== 1 || effectElements[19].p.k || effectElements[19].p.v !== 1 || effectElements[20].p.k || effectElements[20].p.v !== 0 || effectElements[21].p.k || effectElements[21].p.v !== 1) {
+    this.feFuncG = this.createFeFunc('feFuncG', feComponentTransfer);
+  }
+  // Blue
+  if (effectElements[24].p.k || effectElements[24].p.v !== 0 || effectElements[25].p.k || effectElements[25].p.v !== 1 || effectElements[26].p.k || effectElements[26].p.v !== 1 || effectElements[27].p.k || effectElements[27].p.v !== 0 || effectElements[28].p.k || effectElements[28].p.v !== 1) {
+    this.feFuncB = this.createFeFunc('feFuncB', feComponentTransfer);
+  }
+  // Alpha
+  if (effectElements[31].p.k || effectElements[31].p.v !== 0 || effectElements[32].p.k || effectElements[32].p.v !== 1 || effectElements[33].p.k || effectElements[33].p.v !== 1 || effectElements[34].p.k || effectElements[34].p.v !== 0 || effectElements[35].p.k || effectElements[35].p.v !== 1) {
+    this.feFuncA = this.createFeFunc('feFuncA', feComponentTransfer);
+  }
+  // RGB
+  if (this.feFuncR || this.feFuncG || this.feFuncB || this.feFuncA) {
+    feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+    filter.appendChild(feComponentTransfer);
+  }
+
+  if (effectElements[3].p.k || effectElements[3].p.v !== 0 || effectElements[4].p.k || effectElements[4].p.v !== 1 || effectElements[5].p.k || effectElements[5].p.v !== 1 || effectElements[6].p.k || effectElements[6].p.v !== 0 || effectElements[7].p.k || effectElements[7].p.v !== 1) {
+    feComponentTransfer = createNS('feComponentTransfer');
+    feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
+    feComponentTransfer.setAttribute('result', id);
+    filter.appendChild(feComponentTransfer);
+    this.feFuncRComposed = this.createFeFunc('feFuncR', feComponentTransfer);
+    this.feFuncGComposed = this.createFeFunc('feFuncG', feComponentTransfer);
+    this.feFuncBComposed = this.createFeFunc('feFuncB', feComponentTransfer);
+  }
+}
+
+SVGProLevelsFilter.prototype.createFeFunc = function (type, feComponentTransfer) {
+  var feFunc = createNS(type);
+  feFunc.setAttribute('type', 'table');
+  feComponentTransfer.appendChild(feFunc);
+  return feFunc;
+};
+
+SVGProLevelsFilter.prototype.getTableValue = function (inputBlack, inputWhite, gamma, outputBlack, outputWhite) {
+  var cnt = 0;
+  var segments = 256;
+  var perc;
+  var min = Math.min(inputBlack, inputWhite);
+  var max = Math.max(inputBlack, inputWhite);
+  var table = Array.call(null, { length: segments });
+  var colorValue;
+  var pos = 0;
+  var outputDelta = outputWhite - outputBlack;
+  var inputDelta = inputWhite - inputBlack;
+  while (cnt <= 256) {
+    perc = cnt / 256;
+    if (perc <= min) {
+      colorValue = inputDelta < 0 ? outputWhite : outputBlack;
+    } else if (perc >= max) {
+      colorValue = inputDelta < 0 ? outputBlack : outputWhite;
+    } else {
+      colorValue = (outputBlack + outputDelta * Math.pow((perc - inputBlack) / inputDelta, 1 / gamma));
+    }
+    table[pos] = colorValue;
+    pos += 1;
+    cnt += 256 / (segments - 1);
+  }
+  return table.join(' ');
+};
+
+SVGProLevelsFilter.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    var val;
+    var effectElements = this.filterManager.effectElements;
+    if (this.feFuncRComposed && (forceRender || effectElements[3].p._mdf || effectElements[4].p._mdf || effectElements[5].p._mdf || effectElements[6].p._mdf || effectElements[7].p._mdf)) {
+      val = this.getTableValue(effectElements[3].p.v, effectElements[4].p.v, effectElements[5].p.v, effectElements[6].p.v, effectElements[7].p.v);
+      this.feFuncRComposed.setAttribute('tableValues', val);
+      this.feFuncGComposed.setAttribute('tableValues', val);
+      this.feFuncBComposed.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncR && (forceRender || effectElements[10].p._mdf || effectElements[11].p._mdf || effectElements[12].p._mdf || effectElements[13].p._mdf || effectElements[14].p._mdf)) {
+      val = this.getTableValue(effectElements[10].p.v, effectElements[11].p.v, effectElements[12].p.v, effectElements[13].p.v, effectElements[14].p.v);
+      this.feFuncR.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncG && (forceRender || effectElements[17].p._mdf || effectElements[18].p._mdf || effectElements[19].p._mdf || effectElements[20].p._mdf || effectElements[21].p._mdf)) {
+      val = this.getTableValue(effectElements[17].p.v, effectElements[18].p.v, effectElements[19].p.v, effectElements[20].p.v, effectElements[21].p.v);
+      this.feFuncG.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncB && (forceRender || effectElements[24].p._mdf || effectElements[25].p._mdf || effectElements[26].p._mdf || effectElements[27].p._mdf || effectElements[28].p._mdf)) {
+      val = this.getTableValue(effectElements[24].p.v, effectElements[25].p.v, effectElements[26].p.v, effectElements[27].p.v, effectElements[28].p.v);
+      this.feFuncB.setAttribute('tableValues', val);
+    }
+
+    if (this.feFuncA && (forceRender || effectElements[31].p._mdf || effectElements[32].p._mdf || effectElements[33].p._mdf || effectElements[34].p._mdf || effectElements[35].p._mdf)) {
+      val = this.getTableValue(effectElements[31].p.v, effectElements[32].p.v, effectElements[33].p.v, effectElements[34].p.v, effectElements[35].p.v);
+      this.feFuncA.setAttribute('tableValues', val);
+    }
+  }
+};
+
+function SVGDropShadowEffect(filter, filterManager, elem, id, source) {
+  var globalFilterSize = filterManager.container.globalData.renderConfig.filterSize;
+  var filterSize = filterManager.data.fs || globalFilterSize;
+  filter.setAttribute('x', filterSize.x || globalFilterSize.x);
+  filter.setAttribute('y', filterSize.y || globalFilterSize.y);
+  filter.setAttribute('width', filterSize.width || globalFilterSize.width);
+  filter.setAttribute('height', filterSize.height || globalFilterSize.height);
+  this.filterManager = filterManager;
+
+  var feGaussianBlur = createNS('feGaussianBlur');
+  feGaussianBlur.setAttribute('in', 'SourceAlpha');
+  feGaussianBlur.setAttribute('result', id + '_drop_shadow_1');
+  feGaussianBlur.setAttribute('stdDeviation', '0');
+  this.feGaussianBlur = feGaussianBlur;
+  filter.appendChild(feGaussianBlur);
+
+  var feOffset = createNS('feOffset');
+  feOffset.setAttribute('dx', '25');
+  feOffset.setAttribute('dy', '0');
+  feOffset.setAttribute('in', id + '_drop_shadow_1');
+  feOffset.setAttribute('result', id + '_drop_shadow_2');
+  this.feOffset = feOffset;
+  filter.appendChild(feOffset);
+  var feFlood = createNS('feFlood');
+  feFlood.setAttribute('flood-color', '#00ff00');
+  feFlood.setAttribute('flood-opacity', '1');
+  feFlood.setAttribute('result', id + '_drop_shadow_3');
+  this.feFlood = feFlood;
+  filter.appendChild(feFlood);
+
+  var feComposite = createNS('feComposite');
+  feComposite.setAttribute('in', id + '_drop_shadow_3');
+  feComposite.setAttribute('in2', id + '_drop_shadow_2');
+  feComposite.setAttribute('operator', 'in');
+  feComposite.setAttribute('result', id + '_drop_shadow_4');
+  filter.appendChild(feComposite);
+
+  var feMerge = this.createMergeNode(
+    id,
+    [
+      id + '_drop_shadow_4',
+      source,
+    ]
+  );
+  filter.appendChild(feMerge);
+  //
+}
+extendPrototype([SVGComposableEffect], SVGDropShadowEffect);
+
+SVGDropShadowEffect.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    if (forceRender || this.filterManager.effectElements[4].p._mdf) {
+      this.feGaussianBlur.setAttribute('stdDeviation', this.filterManager.effectElements[4].p.v / 4);
+    }
+    if (forceRender || this.filterManager.effectElements[0].p._mdf) {
+      var col = this.filterManager.effectElements[0].p.v;
+      this.feFlood.setAttribute('flood-color', rgbToHex(Math.round(col[0] * 255), Math.round(col[1] * 255), Math.round(col[2] * 255)));
+    }
+    if (forceRender || this.filterManager.effectElements[1].p._mdf) {
+      this.feFlood.setAttribute('flood-opacity', this.filterManager.effectElements[1].p.v / 255);
+    }
+    if (forceRender || this.filterManager.effectElements[2].p._mdf || this.filterManager.effectElements[3].p._mdf) {
+      var distance = this.filterManager.effectElements[3].p.v;
+      var angle = (this.filterManager.effectElements[2].p.v - 90) * degToRads;
+      var x = distance * Math.cos(angle);
+      var y = distance * Math.sin(angle);
+      this.feOffset.setAttribute('dx', x);
+      this.feOffset.setAttribute('dy', y);
+    }
+  }
+};
+
+var _svgMatteSymbols = [];
+
+function SVGMatte3Effect(filterElem, filterManager, elem) {
+  this.initialized = false;
+  this.filterManager = filterManager;
+  this.filterElem = filterElem;
+  this.elem = elem;
+  elem.matteElement = createNS('g');
+  elem.matteElement.appendChild(elem.layerElement);
+  elem.matteElement.appendChild(elem.transformedElement);
+  elem.baseElement = elem.matteElement;
+}
+
+SVGMatte3Effect.prototype.findSymbol = function (mask) {
+  var i = 0;
+  var len = _svgMatteSymbols.length;
+  while (i < len) {
+    if (_svgMatteSymbols[i] === mask) {
+      return _svgMatteSymbols[i];
+    }
+    i += 1;
+  }
+  return null;
+};
+
+SVGMatte3Effect.prototype.replaceInParent = function (mask, symbolId) {
+  var parentNode = mask.layerElement.parentNode;
+  if (!parentNode) {
+    return;
+  }
+  var children = parentNode.children;
+  var i = 0;
+  var len = children.length;
+  while (i < len) {
+    if (children[i] === mask.layerElement) {
+      break;
+    }
+    i += 1;
+  }
+  var nextChild;
+  if (i <= len - 2) {
+    nextChild = children[i + 1];
+  }
+  var useElem = createNS('use');
+  useElem.setAttribute('href', '#' + symbolId);
+  if (nextChild) {
+    parentNode.insertBefore(useElem, nextChild);
+  } else {
+    parentNode.appendChild(useElem);
+  }
+};
+
+SVGMatte3Effect.prototype.setElementAsMask = function (elem, mask) {
+  if (!this.findSymbol(mask)) {
+    var symbolId = createElementID();
+    var masker = createNS('mask');
+    masker.setAttribute('id', mask.layerId);
+    masker.setAttribute('mask-type', 'alpha');
+    _svgMatteSymbols.push(mask);
+    var defs = elem.globalData.defs;
+    defs.appendChild(masker);
+    var symbol = createNS('symbol');
+    symbol.setAttribute('id', symbolId);
+    this.replaceInParent(mask, symbolId);
+    symbol.appendChild(mask.layerElement);
+    defs.appendChild(symbol);
+    var useElem = createNS('use');
+    useElem.setAttribute('href', '#' + symbolId);
+    masker.appendChild(useElem);
+    mask.data.hd = false;
+    mask.show();
+  }
+  elem.setMatte(mask.layerId);
+};
+
+SVGMatte3Effect.prototype.initialize = function () {
+  var ind = this.filterManager.effectElements[0].p.v;
+  var elements = this.elem.comp.elements;
+  var i = 0;
+  var len = elements.length;
+  while (i < len) {
+    if (elements[i] && elements[i].data.ind === ind) {
+      this.setElementAsMask(this.elem, elements[i]);
+    }
+    i += 1;
+  }
+  this.initialized = true;
+};
+
+SVGMatte3Effect.prototype.renderFrame = function () {
+  if (!this.initialized) {
+    this.initialize();
+  }
+};
+
+function SVGGaussianBlurEffect(filter, filterManager, elem, id) {
+  // Outset the filter region by 100% on all sides to accommodate blur expansion.
+  filter.setAttribute('x', '-100%');
+  filter.setAttribute('y', '-100%');
+  filter.setAttribute('width', '300%');
+  filter.setAttribute('height', '300%');
+
+  this.filterManager = filterManager;
+  var feGaussianBlur = createNS('feGaussianBlur');
+  feGaussianBlur.setAttribute('result', id);
+  filter.appendChild(feGaussianBlur);
+  this.feGaussianBlur = feGaussianBlur;
+}
+
+SVGGaussianBlurEffect.prototype.renderFrame = function (forceRender) {
+  if (forceRender || this.filterManager._mdf) {
+    // Empirical value, matching AE's blur appearance.
+    var kBlurrinessToSigma = 0.3;
+    var sigma = this.filterManager.effectElements[0].p.v * kBlurrinessToSigma;
+
+    // Dimensions mapping:
+    //
+    //   1 -> horizontal & vertical
+    //   2 -> horizontal only
+    //   3 -> vertical only
+    //
+    var dimensions = this.filterManager.effectElements[1].p.v;
+    var sigmaX = (dimensions == 3) ? 0 : sigma; // eslint-disable-line eqeqeq
+    var sigmaY = (dimensions == 2) ? 0 : sigma; // eslint-disable-line eqeqeq
+
+    this.feGaussianBlur.setAttribute('stdDeviation', sigmaX + ' ' + sigmaY);
+
+    // Repeat edges mapping:
+    //
+    //   0 -> off -> duplicate
+    //   1 -> on  -> wrap
+    var edgeMode = (this.filterManager.effectElements[2].p.v == 1) ? 'wrap' : 'duplicate'; // eslint-disable-line eqeqeq
+    this.feGaussianBlur.setAttribute('edgeMode', edgeMode);
+  }
+};
+
+function TransformEffect() {
+}
+
+TransformEffect.prototype.init = function (effectsManager) {
+  this.effectsManager = effectsManager;
+  this.type = effectTypes.TRANSFORM_EFFECT;
+  this.matrix = new Matrix();
+  this.opacity = -1;
+  this._mdf = false;
+  this._opMdf = false;
+};
+
+TransformEffect.prototype.renderFrame = function (forceFrame) {
+  this._opMdf = false;
+  this._mdf = false;
+  if (forceFrame || this.effectsManager._mdf) {
+    var effectElements = this.effectsManager.effectElements;
+    var anchor = effectElements[0].p.v;
+    var position = effectElements[1].p.v;
+    var isUniformScale = effectElements[2].p.v === 1;
+    var scaleHeight = effectElements[3].p.v;
+    var scaleWidth = isUniformScale ? scaleHeight : effectElements[4].p.v;
+    var skew = effectElements[5].p.v;
+    var skewAxis = effectElements[6].p.v;
+    var rotation = effectElements[7].p.v;
+    this.matrix.reset();
+    this.matrix.translate(-anchor[0], -anchor[1], anchor[2]);
+    this.matrix.scale(scaleWidth * 0.01, scaleHeight * 0.01, 1);
+    this.matrix.rotate(-rotation * degToRads);
+    this.matrix.skewFromAxis(-skew * degToRads, (skewAxis + 90) * degToRads);
+    this.matrix.translate(position[0], position[1], 0);
+    this._mdf = true;
+    if (this.opacity !== effectElements[8].p.v) {
+      this.opacity = effectElements[8].p.v;
+      this._opMdf = true;
+    }
+  }
+};
+
+function SVGTransformEffect(_, filterManager) {
+  this.init(filterManager);
+}
+
+extendPrototype([TransformEffect], SVGTransformEffect);
+
+// Registering expression plugin
+setExpressionsPlugin(Expressions);
+setExpressionInterfaces(getInterface);
+initialize$1();
+initialize();
+registerEffect(20, SVGTintFilter, true);
+registerEffect(21, SVGFillFilter, true);
+registerEffect(22, SVGStrokeEffect, false);
+registerEffect(23, SVGTritoneFilter, true);
+registerEffect(24, SVGProLevelsFilter, true);
+registerEffect(25, SVGDropShadowEffect, true);
+registerEffect(28, SVGMatte3Effect, false);
+registerEffect(29, SVGGaussianBlurEffect, true);
+registerEffect(35, SVGTransformEffect, false);
+
+export { lottie as default };
diff --git a/build/player/lottie.js b/build/player/lottie.js
index 1366af4..ecaaf2d 100644
--- a/build/player/lottie.js
+++ b/build/player/lottie.js
@@ -1,4 +1,4 @@
-(typeof navigator !== "undefined") && (function (global, factory) {
+(typeof document !== "undefined") && (typeof navigator !== "undefined") && (function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
   typeof define === 'function' && define.amd ? define(factory) :
   (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lottie = factory());
@@ -8,19 +8,15 @@
   var locationHref = '';
   var _useWebWorker = false;
   var initialDefaultFrame = -999999;
-
   var setWebWorker = function setWebWorker(flag) {
     _useWebWorker = !!flag;
   };
-
   var getWebWorker = function getWebWorker() {
     return _useWebWorker;
   };
-
   var setLocationHref = function setLocationHref(value) {
     locationHref = value;
   };
-
   var getLocationHref = function getLocationHref() {
     return locationHref;
   };
@@ -34,28 +30,24 @@
     var i;
     var len = sources.length;
     var sourcePrototype;
-
     for (i = 0; i < len; i += 1) {
       sourcePrototype = sources[i].prototype;
-
       for (var attr in sourcePrototype) {
         if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
       }
     }
   }
-
   function getDescriptor(object, prop) {
     return Object.getOwnPropertyDescriptor(object, prop);
   }
-
   function createProxyFunction(prototype) {
     function ProxyFunction() {}
-
     ProxyFunction.prototype = prototype;
     return ProxyFunction;
   }
 
   // import Howl from '../../3rd_party/howler';
+
   var audioControllerFactory = function () {
     function AudioController(audioFactory) {
       this.audios = [];
@@ -63,7 +55,6 @@
       this._volume = 1;
       this._isMuted = false;
     }
-
     AudioController.prototype = {
       addAudio: function addAudio(audio) {
         this.audios.push(audio);
@@ -71,7 +62,6 @@
       pause: function pause() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].pause();
         }
@@ -79,7 +69,6 @@
       resume: function resume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].resume();
         }
@@ -87,7 +76,6 @@
       setRate: function setRate(rateValue) {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].setRate(rateValue);
         }
@@ -96,13 +84,11 @@
         if (this.audioFactory) {
           return this.audioFactory(assetPath);
         }
-
         if (window.Howl) {
           return new window.Howl({
             src: [assetPath]
           });
         }
-
         return {
           isPlaying: false,
           play: function play() {
@@ -121,17 +107,14 @@
       },
       setVolume: function setVolume(value) {
         this._volume = value;
-
         this._updateVolume();
       },
       mute: function mute() {
         this._isMuted = true;
-
         this._updateVolume();
       },
       unmute: function unmute() {
         this._isMuted = false;
-
         this._updateVolume();
       },
       getVolume: function getVolume() {
@@ -140,7 +123,6 @@
       _updateVolume: function _updateVolume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
         }
@@ -156,55 +138,44 @@
       var i = 0;
       var arr = [];
       var value;
-
       switch (type) {
         case 'int16':
         case 'uint8c':
           value = 1;
           break;
-
         default:
           value = 1.1;
           break;
       }
-
       for (i = 0; i < len; i += 1) {
         arr.push(value);
       }
-
       return arr;
     }
-
     function createTypedArrayFactory(type, len) {
       if (type === 'float32') {
         return new Float32Array(len);
       }
-
       if (type === 'int16') {
         return new Int16Array(len);
       }
-
       if (type === 'uint8c') {
         return new Uint8ClampedArray(len);
       }
-
       return createRegularArray(type, len);
     }
-
     if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
       return createTypedArrayFactory;
     }
-
     return createRegularArray;
   }();
-
   function createSizedArray(len) {
     return Array.apply(null, {
       length: len
     });
   }
 
-  function _typeof$6(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$6 = function _typeof(obj) { return typeof obj; }; } else { _typeof$6 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$6(obj); }
+  function _typeof$6(o) { "@babel/helpers - typeof"; return _typeof$6 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$6(o); }
   var subframeEnabled = true;
   var expressionsPlugin = null;
   var expressionsInterfaces = null;
@@ -217,57 +188,43 @@
   var bmMax = Math.max;
   var bmMin = Math.min;
   var BMMath = {};
-
   (function () {
     var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
     var i;
     var len = propertyNames.length;
-
     for (i = 0; i < len; i += 1) {
       BMMath[propertyNames[i]] = Math[propertyNames[i]];
     }
   })();
-
   function ProjectInterface$1() {
     return {};
   }
-
   BMMath.random = Math.random;
-
   BMMath.abs = function (val) {
     var tOfVal = _typeof$6(val);
-
     if (tOfVal === 'object' && val.length) {
       var absArr = createSizedArray(val.length);
       var i;
       var len = val.length;
-
       for (i = 0; i < len; i += 1) {
         absArr[i] = Math.abs(val[i]);
       }
-
       return absArr;
     }
-
     return Math.abs(val);
   };
-
   var defaultCurveSegments = 150;
   var degToRads = Math.PI / 180;
   var roundCorner = 0.5519;
-
   function roundValues(flag) {
     _shouldRoundValues = !!flag;
   }
-
   function bmRnd(value) {
     if (_shouldRoundValues) {
       return Math.round(value);
     }
-
     return value;
   }
-
   function styleDiv(element) {
     element.style.position = 'absolute';
     element.style.top = 0;
@@ -281,53 +238,44 @@
     element.style.webkitTransformStyle = 'preserve-3d';
     element.style.mozTransformStyle = 'preserve-3d';
   }
-
   function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
     this.type = type;
     this.currentTime = currentTime;
     this.totalTime = totalTime;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteEvent(type, frameMultiplier) {
     this.type = type;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
     this.type = type;
     this.currentLoop = currentLoop;
     this.totalLoops = totalLoops;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMSegmentStartEvent(type, firstFrame, totalFrames) {
     this.type = type;
     this.firstFrame = firstFrame;
     this.totalFrames = totalFrames;
   }
-
   function BMDestroyEvent(type, target) {
     this.type = type;
     this.target = target;
   }
-
   function BMRenderFrameErrorEvent(nativeError, currentTime) {
     this.type = 'renderFrameError';
     this.nativeError = nativeError;
     this.currentTime = currentTime;
   }
-
   function BMConfigErrorEvent(nativeError) {
     this.type = 'configError';
     this.nativeError = nativeError;
   }
-
   function BMAnimationConfigErrorEvent(type, nativeError) {
     this.type = type;
     this.nativeError = nativeError;
   }
-
   var createElementID = function () {
     var _count = 0;
     return function createID() {
@@ -335,7 +283,6 @@
       return idPrefix$1 + '__lottie_element_' + _count;
     };
   }();
-
   function HSVtoRGB(h, s, v) {
     var r;
     var g;
@@ -350,51 +297,42 @@
     p = v * (1 - s);
     q = v * (1 - f * s);
     t = v * (1 - (1 - f) * s);
-
     switch (i % 6) {
       case 0:
         r = v;
         g = t;
         b = p;
         break;
-
       case 1:
         r = q;
         g = v;
         b = p;
         break;
-
       case 2:
         r = p;
         g = v;
         b = t;
         break;
-
       case 3:
         r = p;
         g = q;
         b = v;
         break;
-
       case 4:
         r = t;
         g = p;
         b = v;
         break;
-
       case 5:
         r = v;
         g = p;
         b = q;
         break;
-
       default:
         break;
     }
-
     return [r, g, b];
   }
-
   function RGBtoHSV(r, g, b) {
     var max = Math.max(r, g, b);
     var min = Math.min(r, g, b);
@@ -402,136 +340,105 @@
     var h;
     var s = max === 0 ? 0 : d / max;
     var v = max / 255;
-
     switch (max) {
       case min:
         h = 0;
         break;
-
       case r:
         h = g - b + d * (g < b ? 6 : 0);
         h /= 6 * d;
         break;
-
       case g:
         h = b - r + d * 2;
         h /= 6 * d;
         break;
-
       case b:
         h = r - g + d * 4;
         h /= 6 * d;
         break;
-
       default:
         break;
     }
-
     return [h, s, v];
   }
-
   function addSaturationToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[1] += offset;
-
     if (hsv[1] > 1) {
       hsv[1] = 1;
     } else if (hsv[1] <= 0) {
       hsv[1] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addBrightnessToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[2] += offset;
-
     if (hsv[2] > 1) {
       hsv[2] = 1;
     } else if (hsv[2] < 0) {
       hsv[2] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addHueToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[0] += offset / 360;
-
     if (hsv[0] > 1) {
       hsv[0] -= 1;
     } else if (hsv[0] < 0) {
       hsv[0] += 1;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   var rgbToHex = function () {
     var colorMap = [];
     var i;
     var hex;
-
     for (i = 0; i < 256; i += 1) {
       hex = i.toString(16);
       colorMap[i] = hex.length === 1 ? '0' + hex : hex;
     }
-
     return function (r, g, b) {
       if (r < 0) {
         r = 0;
       }
-
       if (g < 0) {
         g = 0;
       }
-
       if (b < 0) {
         b = 0;
       }
-
       return '#' + colorMap[r] + colorMap[g] + colorMap[b];
     };
   }();
-
   var setSubframeEnabled = function setSubframeEnabled(flag) {
     subframeEnabled = !!flag;
   };
-
   var getSubframeEnabled = function getSubframeEnabled() {
     return subframeEnabled;
   };
-
   var setExpressionsPlugin = function setExpressionsPlugin(value) {
     expressionsPlugin = value;
   };
-
   var getExpressionsPlugin = function getExpressionsPlugin() {
     return expressionsPlugin;
   };
-
   var setExpressionInterfaces = function setExpressionInterfaces(value) {
     expressionsInterfaces = value;
   };
-
   var getExpressionInterfaces = function getExpressionInterfaces() {
     return expressionsInterfaces;
   };
-
   var setDefaultCurveSegments = function setDefaultCurveSegments(value) {
     defaultCurveSegments = value;
   };
-
   var getDefaultCurveSegments = function getDefaultCurveSegments() {
     return defaultCurveSegments;
   };
-
   var setIdPrefix = function setIdPrefix(value) {
     idPrefix$1 = value;
   };
-
   var getIdPrefix = function getIdPrefix() {
     return idPrefix$1;
   };
@@ -541,8 +448,7 @@
     return document.createElementNS(svgNS, type);
   }
 
-  function _typeof$5(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$5 = function _typeof(obj) { return typeof obj; }; } else { _typeof$5 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$5(obj); }
-
+  function _typeof$5(o) { "@babel/helpers - typeof"; return _typeof$5 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$5(o); }
   var dataManager = function () {
     var _counterId = 1;
     var processes = [];
@@ -563,21 +469,18 @@
         });
       }
     };
-
     function createWorker(fn) {
       if (window.Worker && window.Blob && getWebWorker()) {
         var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], {
           type: 'text/javascript'
-        }); // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
-
+        });
+        // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
         var url = URL.createObjectURL(blob);
         return new Worker(url);
       }
-
       workerFn = fn;
       return workerProxy;
     }
-
     function setupWorker() {
       if (!workerInstance) {
         workerInstance = createWorker(function workerStart(e) {
@@ -590,28 +493,22 @@
               var jLen;
               var k;
               var kLen;
-
               for (i = 0; i < len; i += 1) {
                 layerData = layers[i];
-
                 if ('ks' in layerData && !layerData.completed) {
                   layerData.completed = true;
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         convertPathsToAbsoluteValues(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) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
                           }
@@ -619,7 +516,6 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 0) {
                     layerData.layers = findCompLayers(layerData.refId, comps);
                     completeLayers(layerData.layers, comps);
@@ -631,16 +527,15 @@
                 }
               }
             }
-
             function completeChars(chars, assets) {
               if (chars) {
                 var i = 0;
                 var len = chars.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (chars[i].t === 1) {
                     // var compData = findComp(chars[i].data.refId, assets);
-                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets); // chars[i].data.ip = 0;
+                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                    // chars[i].data.ip = 0;
                     // chars[i].data.op = 99999;
                     // chars[i].data.st = 0;
                     // chars[i].data.sr = 1;
@@ -652,61 +547,48 @@
                     //   s: { k: [100, 100], a: 0 },
                     //   o: { k: 100, a: 0 },
                     // };
-
                     completeLayers(chars[i].data.layers, assets);
                   }
                 }
               }
             }
-
             function findComp(id, comps) {
               var i = 0;
               var len = comps.length;
-
               while (i < len) {
                 if (comps[i].id === id) {
                   return comps[i];
                 }
-
                 i += 1;
               }
-
               return null;
             }
-
             function findCompLayers(id, comps) {
               var comp = findComp(id, comps);
-
               if (comp) {
                 if (!comp.layers.__used) {
                   comp.layers.__used = true;
                   return comp.layers;
                 }
-
                 return JSON.parse(JSON.stringify(comp.layers));
               }
-
               return null;
             }
-
             function completeShapes(arr) {
               var i;
               var len = arr.length;
               var j;
               var jLen;
-
               for (i = len - 1; i >= 0; i -= 1) {
                 if (arr[i].ty === 'sh') {
                   if (arr[i].ks.k.i) {
                     convertPathsToAbsoluteValues(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) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
                       }
-
                       if (arr[i].ks.k[j].e) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
                       }
@@ -717,11 +599,9 @@
                 }
               }
             }
-
             function convertPathsToAbsoluteValues(path) {
               var i;
               var len = path.i.length;
-
               for (i = 0; i < len; i += 1) {
                 path.i[i][0] += path.v[i][0];
                 path.i[i][1] += path.v[i][1];
@@ -729,40 +609,30 @@
                 path.o[i][1] += path.v[i][1];
               }
             }
-
             function checkVersion(minimum, animVersionString) {
               var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
-
               if (minimum[0] > animVersion[0]) {
                 return true;
               }
-
               if (animVersion[0] > minimum[0]) {
                 return false;
               }
-
               if (minimum[1] > animVersion[1]) {
                 return true;
               }
-
               if (animVersion[1] > minimum[1]) {
                 return false;
               }
-
               if (minimum[2] > animVersion[2]) {
                 return true;
               }
-
               if (animVersion[2] > minimum[2]) {
                 return false;
               }
-
               return null;
             }
-
             var checkText = function () {
               var minimumVersion = [4, 4, 14];
-
               function updateTextLayer(textLayer) {
                 var documentData = textLayer.t.d;
                 textLayer.t.d = {
@@ -772,26 +642,21 @@
                   }]
                 };
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -801,17 +666,14 @@
                 }
               };
             }();
-
             var checkChars = function () {
               var minimumVersion = [4, 7, 99];
               return function (animationData) {
                 if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
                   var i;
                   var len = animationData.chars.length;
-
                   for (i = 0; i < len; i += 1) {
                     var charData = animationData.chars[i];
-
                     if (charData.data && charData.data.shapes) {
                       completeShapes(charData.data.shapes);
                       charData.data.ip = 0;
@@ -840,7 +702,6 @@
                           a: 0
                         }
                       };
-
                       if (!animationData.chars[i].t) {
                         charData.data.shapes.push({
                           ty: 'no'
@@ -882,27 +743,22 @@
                 }
               };
             }();
-
             var checkPathProperties = function () {
               var minimumVersion = [5, 7, 15];
-
               function updateTextLayer(textLayer) {
                 var pathData = textLayer.t.p;
-
                 if (typeof pathData.a === 'number') {
                   pathData.a = {
                     a: 0,
                     k: pathData.a
                   };
                 }
-
                 if (typeof pathData.p === 'number') {
                   pathData.p = {
                     a: 0,
                     k: pathData.p
                   };
                 }
-
                 if (typeof pathData.r === 'number') {
                   pathData.r = {
                     a: 0,
@@ -910,26 +766,21 @@
                   };
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -939,23 +790,19 @@
                 }
               };
             }();
-
             var checkColors = function () {
               var minimumVersion = [4, 1, 9];
-
               function iterateShapes(shapes) {
                 var i;
                 var len = shapes.length;
                 var j;
                 var jLen;
-
                 for (i = 0; i < len; i += 1) {
                   if (shapes[i].ty === 'gr') {
                     iterateShapes(shapes[i].it);
                   } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
                     if (shapes[i].c.k && shapes[i].c.k[0].i) {
                       jLen = shapes[i].c.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (shapes[i].c.k[j].s) {
                           shapes[i].c.k[j].s[0] /= 255;
@@ -963,7 +810,6 @@
                           shapes[i].c.k[j].s[2] /= 255;
                           shapes[i].c.k[j].s[3] /= 255;
                         }
-
                         if (shapes[i].c.k[j].e) {
                           shapes[i].c.k[j].e[0] /= 255;
                           shapes[i].c.k[j].e[1] /= 255;
@@ -980,26 +826,21 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 4) {
                     iterateShapes(layers[i].shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1009,28 +850,23 @@
                 }
               };
             }();
-
             var checkShapes = function () {
               var minimumVersion = [4, 4, 18];
-
               function completeClosingShapes(arr) {
                 var i;
                 var len = arr.length;
                 var j;
                 var jLen;
-
                 for (i = len - 1; i >= 0; i -= 1) {
                   if (arr[i].ty === 'sh') {
                     if (arr[i].ks.k.i) {
                       arr[i].ks.k.c = arr[i].closed;
                     } else {
                       jLen = arr[i].ks.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (arr[i].ks.k[j].s) {
                           arr[i].ks.k[j].s[0].c = arr[i].closed;
                         }
-
                         if (arr[i].ks.k[j].e) {
                           arr[i].ks.k[j].e[0].c = arr[i].closed;
                         }
@@ -1041,7 +877,6 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var layerData;
                 var i;
@@ -1050,25 +885,20 @@
                 var jLen;
                 var k;
                 var kLen;
-
                 for (i = 0; i < len; i += 1) {
                   layerData = layers[i];
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         maskProps[j].pt.k.c = maskProps[j].cl;
                       } else {
                         kLen = maskProps[j].pt.k.length;
-
                         for (k = 0; k < kLen; k += 1) {
                           if (maskProps[j].pt.k[k].s) {
                             maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
                           }
@@ -1076,21 +906,17 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 4) {
                     completeClosingShapes(layerData.shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1100,12 +926,10 @@
                 }
               };
             }();
-
             function completeData(animationData) {
               if (animationData.__complete) {
                 return;
               }
-
               checkColors(animationData);
               checkText(animationData);
               checkChars(animationData);
@@ -1115,12 +939,11 @@
               completeChars(animationData.chars, animationData.assets);
               animationData.__complete = true;
             }
-
             function completeText(data) {
-              if (data.t.a.length === 0 && !('m' in data.t.p)) {// data.singleShape = true;
+              if (data.t.a.length === 0 && !('m' in data.t.p)) {
+                // data.singleShape = true;
               }
             }
-
             var moduleOb = {};
             moduleOb.completeData = completeData;
             moduleOb.checkColors = checkColors;
@@ -1130,47 +953,37 @@
             moduleOb.completeLayers = completeLayers;
             return moduleOb;
           }
-
           if (!_workerSelf.dataManager) {
             _workerSelf.dataManager = dataFunctionManager();
           }
-
           if (!_workerSelf.assetLoader) {
             _workerSelf.assetLoader = function () {
               function formatResponse(xhr) {
                 // using typeof doubles the time of execution of this method,
                 // so if available, it's better to use the header to validate the type
                 var contentTypeHeader = xhr.getResponseHeader('content-type');
-
                 if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
                   return xhr.response;
                 }
-
                 if (xhr.response && _typeof$5(xhr.response) === 'object') {
                   return xhr.response;
                 }
-
                 if (xhr.response && typeof xhr.response === 'string') {
                   return JSON.parse(xhr.response);
                 }
-
                 if (xhr.responseText) {
                   return JSON.parse(xhr.responseText);
                 }
-
                 return null;
               }
-
               function loadAsset(path, fullPath, callback, errorCallback) {
                 var response;
-                var xhr = new XMLHttpRequest(); // set responseType after calling open or IE will break.
-
+                var xhr = new XMLHttpRequest();
+                // set responseType after calling open or IE will break.
                 try {
                   // This crashes on Android WebView prior to KitKat
                   xhr.responseType = 'json';
                 } catch (err) {} // eslint-disable-line no-empty
-
-
                 xhr.onreadystatechange = function () {
                   if (xhr.readyState === 4) {
                     if (xhr.status === 200) {
@@ -1188,7 +1001,6 @@
                     }
                   }
                 };
-
                 try {
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), path, true);
@@ -1196,20 +1008,16 @@
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
                 }
-
                 xhr.send();
               }
-
               return {
                 load: loadAsset
               };
             }();
           }
-
           if (e.data.type === 'loadAnimation') {
             _workerSelf.assetLoader.load(e.data.path, e.data.fullPath, function (data) {
               _workerSelf.dataManager.completeData(data);
-
               _workerSelf.postMessage({
                 id: e.data.id,
                 payload: data,
@@ -1223,9 +1031,7 @@
             });
           } else if (e.data.type === 'complete') {
             var animation = e.data.animation;
-
             _workerSelf.dataManager.completeData(animation);
-
             _workerSelf.postMessage({
               id: e.data.id,
               payload: animation,
@@ -1246,13 +1052,11 @@
             });
           }
         });
-
         workerInstance.onmessage = function (event) {
           var data = event.data;
           var id = data.id;
           var process = processes[id];
           processes[id] = null;
-
           if (data.status === 'success') {
             process.onComplete(data.payload);
           } else if (process.onError) {
@@ -1261,7 +1065,6 @@
         };
       }
     }
-
     function createProcess(onComplete, onError) {
       _counterId += 1;
       var id = 'processId_' + _counterId;
@@ -1271,7 +1074,6 @@
       };
       return id;
     }
-
     function loadAnimation(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1282,7 +1084,6 @@
         id: processId
       });
     }
-
     function loadData(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1293,7 +1094,6 @@
         id: processId
       });
     }
-
     function completeAnimation(anim, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1303,7 +1103,6 @@
         id: processId
       });
     }
-
     return {
       loadAnimation: loadAnimation,
       loadData: loadData,
@@ -1321,94 +1120,74 @@
       ctx.fillRect(0, 0, 1, 1);
       return canvas;
     }();
-
     function imageLoaded() {
       this.loadedAssets += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function footageLoaded() {
       this.loadedFootagesCount += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function getAssetsPath(assetData, assetsPath, originalPath) {
       var path = '';
-
       if (assetData.e) {
         path = assetData.p;
       } else if (assetsPath) {
         var imagePath = assetData.p;
-
         if (imagePath.indexOf('images/') !== -1) {
           imagePath = imagePath.split('/')[1];
         }
-
         path = assetsPath + imagePath;
       } else {
         path = originalPath;
         path += assetData.u ? assetData.u : '';
         path += assetData.p;
       }
-
       return path;
     }
-
     function testImageLoaded(img) {
       var _count = 0;
       var intervalId = setInterval(function () {
         var box = img.getBBox();
-
         if (box.width || _count > 500) {
           this._imageLoaded();
-
           clearInterval(intervalId);
         }
-
         _count += 1;
       }.bind(this), 50);
     }
-
     function createImageData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createNS('image');
-
       if (isSafari) {
         this.testImageLoaded(img);
       } else {
         img.addEventListener('load', this._imageLoaded, false);
       }
-
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
-
       if (this._elementHelper.append) {
         this._elementHelper.append(img);
       } else {
         this._elementHelper.appendChild(img);
       }
-
       var ob = {
         img: img,
         assetData: assetData
       };
       return ob;
     }
-
     function createImgData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createTag('img');
@@ -1416,7 +1195,6 @@
       img.addEventListener('load', this._imageLoaded, false);
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.src = path;
@@ -1426,7 +1204,6 @@
       };
       return ob;
     }
-
     function createFootageData(data) {
       var ob = {
         assetData: data
@@ -1434,21 +1211,17 @@
       var path = getAssetsPath(data, this.assetsPath, this.path);
       dataManager.loadData(path, function (footageData) {
         ob.img = footageData;
-
         this._footageLoaded();
       }.bind(this), function () {
         ob.img = {};
-
         this._footageLoaded();
       }.bind(this));
       return ob;
     }
-
     function loadAssets(assets, cb) {
       this.imagesLoadedCb = cb;
       var i;
       var len = assets.length;
-
       for (i = 0; i < len; i += 1) {
         if (!assets[i].layers) {
           if (!assets[i].t || assets[i].t === 'seq') {
@@ -1461,43 +1234,33 @@
         }
       }
     }
-
     function setPath(path) {
       this.path = path || '';
     }
-
     function setAssetsPath(path) {
       this.assetsPath = path || '';
     }
-
     function getAsset(assetData) {
       var i = 0;
       var len = this.images.length;
-
       while (i < len) {
         if (this.images[i].assetData === assetData) {
           return this.images[i].img;
         }
-
         i += 1;
       }
-
       return null;
     }
-
     function destroy() {
       this.imagesLoadedCb = null;
       this.images.length = 0;
     }
-
     function loadedImages() {
       return this.totalImages === this.loadedAssets;
     }
-
     function loadedFootages() {
       return this.totalFootages === this.loadedFootagesCount;
     }
-
     function setCacheType(type, elementHelper) {
       if (type === 'svg') {
         this._elementHelper = elementHelper;
@@ -1506,7 +1269,6 @@
         this._createImageData = this.createImgData.bind(this);
       }
     }
-
     function ImagePreloaderFactory() {
       this._imageLoaded = imageLoaded.bind(this);
       this._footageLoaded = footageLoaded.bind(this);
@@ -1521,7 +1283,6 @@
       this.imagesLoadedCb = null;
       this.images = [];
     }
-
     ImagePreloaderFactory.prototype = {
       loadAssets: loadAssets,
       setAssetsPath: setAssetsPath,
@@ -1540,12 +1301,10 @@
   }();
 
   function BaseEvent() {}
-
   BaseEvent.prototype = {
     triggerEvent: function triggerEvent(eventName, args) {
       if (this._cbs[eventName]) {
         var callbacks = this._cbs[eventName];
-
         for (var i = 0; i < callbacks.length; i += 1) {
           callbacks[i](args);
         }
@@ -1555,9 +1314,7 @@
       if (!this._cbs[eventName]) {
         this._cbs[eventName] = [];
       }
-
       this._cbs[eventName].push(callback);
-
       return function () {
         this.removeEventListener(eventName, callback);
       }.bind(this);
@@ -1568,18 +1325,14 @@
       } else if (this._cbs[eventName]) {
         var i = 0;
         var len = this._cbs[eventName].length;
-
         while (i < len) {
           if (this._cbs[eventName][i] === callback) {
             this._cbs[eventName].splice(i, 1);
-
             i -= 1;
             len -= 1;
           }
-
           i += 1;
         }
-
         if (!this._cbs[eventName].length) {
           this._cbs[eventName] = null;
         }
@@ -1593,33 +1346,26 @@
       var keys = {};
       var line;
       var keysCount = 0;
-
       for (var i = 0; i < lines.length; i += 1) {
         line = lines[i].split(':');
-
         if (line.length === 2) {
           keys[line[0]] = line[1].trim();
           keysCount += 1;
         }
       }
-
       if (keysCount === 0) {
         throw new Error();
       }
-
       return keys;
     }
-
     return function (_markers) {
       var markers = [];
-
       for (var i = 0; i < _markers.length; i += 1) {
         var _marker = _markers[i];
         var markerData = {
           time: _marker.tm,
           duration: _marker.dr
         };
-
         try {
           markerData.payload = JSON.parse(_markers[i].cm);
         } catch (_) {
@@ -1631,10 +1377,8 @@
             };
           }
         }
-
         markers.push(markerData);
       }
-
       return markers;
     };
   }();
@@ -1643,27 +1387,21 @@
     function registerComposition(comp) {
       this.compositions.push(comp);
     }
-
     return function () {
       function _thisProjectFunction(name) {
         var i = 0;
         var len = this.compositions.length;
-
         while (i < len) {
           if (this.compositions[i].data && this.compositions[i].data.nm === name) {
             if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
               this.compositions[i].prepareFrame(this.currentFrame);
             }
-
             return this.compositions[i].compInterface;
           }
-
           i += 1;
         }
-
         return null;
       }
-
       _thisProjectFunction.compositions = [];
       _thisProjectFunction.currentFrame = 0;
       _thisProjectFunction.registerComposition = registerComposition;
@@ -1672,33 +1410,27 @@
   }();
 
   var renderers = {};
-
   var registerRenderer = function registerRenderer(key, value) {
     renderers[key] = value;
   };
-
   function getRenderer(key) {
     return renderers[key];
   }
-
   function getRegisteredRenderer() {
     // Returns canvas by default for compatibility
     if (renderers.canvas) {
       return 'canvas';
-    } // Returns any renderer that is registered
-
-
+    }
+    // Returns any renderer that is registered
     for (var key in renderers) {
       if (renderers[key]) {
         return key;
       }
     }
-
     return '';
   }
 
-  function _typeof$4(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$4 = function _typeof(obj) { return typeof obj; }; } else { _typeof$4 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$4(obj); }
-
+  function _typeof$4(o) { "@babel/helpers - typeof"; return _typeof$4 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$4(o); }
   var AnimationItem = function AnimationItem() {
     this._cbs = [];
     this.name = '';
@@ -1737,28 +1469,22 @@
     this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
     this.expressionsPlugin = getExpressionsPlugin();
   };
-
   extendPrototype([BaseEvent], AnimationItem);
-
   AnimationItem.prototype.setParams = function (params) {
     if (params.wrapper || params.container) {
       this.wrapper = params.wrapper || params.container;
     }
-
     var animType = 'svg';
-
     if (params.animType) {
       animType = params.animType;
     } else if (params.renderer) {
       animType = params.renderer;
     }
-
     var RendererClass = getRenderer(animType);
     this.renderer = new RendererClass(this, params.rendererSettings);
     this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
     this.renderer.setProjectInterface(this.projectInterface);
     this.animType = animType;
-
     if (params.loop === '' || params.loop === null || params.loop === undefined || params.loop === true) {
       this.loop = true;
     } else if (params.loop === false) {
@@ -1766,17 +1492,14 @@
     } else {
       this.loop = parseInt(params.loop, 10);
     }
-
     this.autoplay = 'autoplay' in params ? params.autoplay : true;
     this.name = params.name ? params.name : '';
     this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
     this.assetsPath = params.assetsPath;
     this.initialSegment = params.initialSegment;
-
     if (params.audioFactory) {
       this.audioController.setAudioFactory(params.audioFactory);
     }
-
     if (params.animationData) {
       this.setupAnimation(params.animationData);
     } else if (params.path) {
@@ -1785,28 +1508,23 @@
       } else {
         this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
       }
-
       this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
       this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
       dataManager.loadAnimation(params.path, this.configAnimation, this.onSetupError);
     }
   };
-
   AnimationItem.prototype.onSetupError = function () {
     this.trigger('data_failed');
   };
-
   AnimationItem.prototype.setupAnimation = function (data) {
     dataManager.completeAnimation(data, this.configAnimation);
   };
-
   AnimationItem.prototype.setData = function (wrapper, animationData) {
     if (animationData) {
       if (_typeof$4(animationData) !== 'object') {
         animationData = JSON.parse(animationData);
       }
     }
-
     var params = {
       wrapper: wrapper,
       animationData: animationData
@@ -1823,7 +1541,6 @@
     var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-loop').value : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-loop').value : wrapperAttributes.getNamedItem('bm-loop') ? wrapperAttributes.getNamedItem('bm-loop').value : '';
-
     if (loop === 'false') {
       params.loop = false;
     } else if (loop === 'true') {
@@ -1831,7 +1548,6 @@
     } else if (loop !== '') {
       params.loop = parseInt(loop, 10);
     }
-
     var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-autoplay').value : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-autoplay').value : wrapperAttributes.getNamedItem('bm-autoplay') ? wrapperAttributes.getNamedItem('bm-autoplay').value : true;
@@ -1842,81 +1558,64 @@
     var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-prerender').value : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-prerender').value : wrapperAttributes.getNamedItem('bm-prerender') ? wrapperAttributes.getNamedItem('bm-prerender').value : '';
-
     if (prerender === 'false') {
       params.prerender = false;
     }
-
     if (!params.path) {
       this.trigger('destroy');
     } else {
       this.setParams(params);
     }
   };
-
   AnimationItem.prototype.includeLayers = function (data) {
     if (data.op > this.animationData.op) {
       this.animationData.op = data.op;
       this.totalFrames = Math.floor(data.op - this.animationData.ip);
     }
-
     var layers = this.animationData.layers;
     var i;
     var len = layers.length;
     var newLayers = data.layers;
     var j;
     var jLen = newLayers.length;
-
     for (j = 0; j < jLen; j += 1) {
       i = 0;
-
       while (i < len) {
         if (layers[i].id === newLayers[j].id) {
           layers[i] = newLayers[j];
           break;
         }
-
         i += 1;
       }
     }
-
     if (data.chars || data.fonts) {
       this.renderer.globalData.fontManager.addChars(data.chars);
       this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
     }
-
     if (data.assets) {
       len = data.assets.length;
-
       for (i = 0; i < len; i += 1) {
         this.animationData.assets.push(data.assets[i]);
       }
     }
-
     this.animationData.__complete = false;
     dataManager.completeAnimation(this.animationData, this.onSegmentComplete);
   };
-
   AnimationItem.prototype.onSegmentComplete = function (data) {
     this.animationData = data;
     var expressionsPlugin = getExpressionsPlugin();
-
     if (expressionsPlugin) {
       expressionsPlugin.initExpressions(this);
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.loadNextSegment = function () {
     var segments = this.animationData.segments;
-
     if (!segments || segments.length === 0 || !this.autoloadSegments) {
       this.trigger('data_ready');
       this.timeCompleted = this.totalFrames;
       return;
     }
-
     var segment = segments.shift();
     this.timeCompleted = segment.time * this.frameRate;
     var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
@@ -1925,36 +1624,28 @@
       this.trigger('data_failed');
     }.bind(this));
   };
-
   AnimationItem.prototype.loadSegments = function () {
     var segments = this.animationData.segments;
-
     if (!segments) {
       this.timeCompleted = this.totalFrames;
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.imagesLoaded = function () {
     this.trigger('loaded_images');
     this.checkLoaded();
   };
-
   AnimationItem.prototype.preloadImages = function () {
     this.imagePreloader.setAssetsPath(this.assetsPath);
     this.imagePreloader.setPath(this.path);
     this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
   };
-
   AnimationItem.prototype.configAnimation = function (animData) {
     if (!this.renderer) {
       return;
     }
-
     try {
       this.animationData = animData;
-
       if (this.initialSegment) {
         this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
         this.firstFrame = Math.round(this.initialSegment[0]);
@@ -1962,13 +1653,10 @@
         this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
         this.firstFrame = Math.round(this.animationData.ip);
       }
-
       this.renderer.configAnimation(animData);
-
       if (!animData.assets) {
         animData.assets = [];
       }
-
       this.assets = this.animationData.assets;
       this.frameRate = this.animationData.fr;
       this.frameMult = this.animationData.fr / 1000;
@@ -1979,7 +1667,6 @@
       this.loadSegments();
       this.updaFrameModifier();
       this.waitForFontsLoaded();
-
       if (this.isPaused) {
         this.audioController.pause();
       }
@@ -1987,103 +1674,83 @@
       this.triggerConfigError(error);
     }
   };
-
   AnimationItem.prototype.waitForFontsLoaded = function () {
     if (!this.renderer) {
       return;
     }
-
     if (this.renderer.globalData.fontManager.isLoaded) {
       this.checkLoaded();
     } else {
       setTimeout(this.waitForFontsLoaded.bind(this), 20);
     }
   };
-
   AnimationItem.prototype.checkLoaded = function () {
     if (!this.isLoaded && this.renderer.globalData.fontManager.isLoaded && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas') && this.imagePreloader.loadedFootages()) {
       this.isLoaded = true;
       var expressionsPlugin = getExpressionsPlugin();
-
       if (expressionsPlugin) {
         expressionsPlugin.initExpressions(this);
       }
-
       this.renderer.initItems();
       setTimeout(function () {
         this.trigger('DOMLoaded');
       }.bind(this), 0);
       this.gotoFrame();
-
       if (this.autoplay) {
         this.play();
       }
     }
   };
-
   AnimationItem.prototype.resize = function (width, height) {
     // Adding this validation for backwards compatibility in case an event object was being passed down
     var _width = typeof width === 'number' ? width : undefined;
-
     var _height = typeof height === 'number' ? height : undefined;
-
     this.renderer.updateContainerSize(_width, _height);
   };
-
   AnimationItem.prototype.setSubframe = function (flag) {
     this.isSubframeEnabled = !!flag;
   };
-
   AnimationItem.prototype.gotoFrame = function () {
     this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
 
     if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
       this.currentFrame = this.timeCompleted;
     }
-
     this.trigger('enterFrame');
     this.renderFrame();
     this.trigger('drawnFrame');
   };
-
   AnimationItem.prototype.renderFrame = function () {
     if (this.isLoaded === false || !this.renderer) {
       return;
     }
-
     try {
       if (this.expressionsPlugin) {
         this.expressionsPlugin.resetFrame();
       }
-
       this.renderer.renderFrame(this.currentFrame + this.firstFrame);
     } catch (error) {
       this.triggerRenderFrameError(error);
     }
   };
-
   AnimationItem.prototype.play = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.isPaused = false;
       this.trigger('_play');
       this.audioController.resume();
-
       if (this._idle) {
         this._idle = false;
         this.trigger('_active');
       }
     }
   };
-
   AnimationItem.prototype.pause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === false) {
       this.isPaused = true;
       this.trigger('_pause');
@@ -2092,54 +1759,42 @@
       this.audioController.pause();
     }
   };
-
   AnimationItem.prototype.togglePause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.play();
     } else {
       this.pause();
     }
   };
-
   AnimationItem.prototype.stop = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.pause();
     this.playCount = 0;
     this._completedLoop = false;
     this.setCurrentRawFrameValue(0);
   };
-
   AnimationItem.prototype.getMarkerData = function (markerName) {
     var marker;
-
     for (var i = 0; i < this.markers.length; i += 1) {
       marker = this.markers[i];
-
       if (marker.payload && marker.payload.name === markerName) {
         return marker;
       }
     }
-
     return null;
   };
-
   AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         this.goToAndStop(marker.time, true);
       }
@@ -2148,20 +1803,15 @@
     } else {
       this.setCurrentRawFrameValue(value * this.frameModifier);
     }
-
     this.pause();
   };
-
   AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         if (!marker.duration) {
           this.goToAndStop(marker.time, true);
@@ -2172,19 +1822,16 @@
     } else {
       this.goToAndStop(numValue, isFrame, name);
     }
-
     this.play();
   };
-
   AnimationItem.prototype.advanceTime = function (value) {
     if (this.isPaused === true || this.isLoaded === false) {
       return;
     }
-
     var nextValue = this.currentRawFrame + value * this.frameModifier;
-    var _isComplete = false; // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+    var _isComplete = false;
+    // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
     // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
-
     if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
       if (!this.loop || this.playCount === this.loop) {
         if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
@@ -2193,7 +1840,6 @@
         }
       } else if (nextValue >= this.totalFrames) {
         this.playCount += 1;
-
         if (!this.checkSegments(nextValue % this.totalFrames)) {
           this.setCurrentRawFrameValue(nextValue % this.totalFrames);
           this._completedLoop = true;
@@ -2207,7 +1853,6 @@
         if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) {
           // eslint-disable-line no-plusplus
           this.setCurrentRawFrameValue(this.totalFrames + nextValue % this.totalFrames);
-
           if (!this._completedLoop) {
             this._completedLoop = true;
           } else {
@@ -2221,17 +1866,14 @@
     } else {
       this.setCurrentRawFrameValue(nextValue);
     }
-
     if (_isComplete) {
       this.setCurrentRawFrameValue(nextValue);
       this.pause();
       this.trigger('complete');
     }
   };
-
   AnimationItem.prototype.adjustSegment = function (arr, offset) {
     this.playCount = 0;
-
     if (arr[1] < arr[0]) {
       if (this.frameModifier > 0) {
         if (this.playSpeed < 0) {
@@ -2240,7 +1882,6 @@
           this.setDirection(-1);
         }
       }
-
       this.totalFrames = arr[0] - arr[1];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[1];
@@ -2253,19 +1894,15 @@
           this.setDirection(1);
         }
       }
-
       this.totalFrames = arr[1] - arr[0];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[0];
       this.setCurrentRawFrameValue(0.001 + offset);
     }
-
     this.trigger('segmentStart');
   };
-
   AnimationItem.prototype.setSegment = function (init, end) {
     var pendingFrame = -1;
-
     if (this.isPaused) {
       if (this.currentRawFrame + this.firstFrame < init) {
         pendingFrame = init;
@@ -2273,64 +1910,51 @@
         pendingFrame = end - init;
       }
     }
-
     this.firstFrame = init;
     this.totalFrames = end - init;
     this.timeCompleted = this.totalFrames;
-
     if (pendingFrame !== -1) {
       this.goToAndStop(pendingFrame, true);
     }
   };
-
   AnimationItem.prototype.playSegments = function (arr, forceFlag) {
     if (forceFlag) {
       this.segments.length = 0;
     }
-
     if (_typeof$4(arr[0]) === 'object') {
       var i;
       var len = arr.length;
-
       for (i = 0; i < len; i += 1) {
         this.segments.push(arr[i]);
       }
     } else {
       this.segments.push(arr);
     }
-
     if (this.segments.length && forceFlag) {
       this.adjustSegment(this.segments.shift(), 0);
     }
-
     if (this.isPaused) {
       this.play();
     }
   };
-
   AnimationItem.prototype.resetSegments = function (forceFlag) {
     this.segments.length = 0;
     this.segments.push([this.animationData.ip, this.animationData.op]);
-
     if (forceFlag) {
       this.checkSegments(0);
     }
   };
-
   AnimationItem.prototype.checkSegments = function (offset) {
     if (this.segments.length) {
       this.adjustSegment(this.segments.shift(), offset);
       return true;
     }
-
     return false;
   };
-
   AnimationItem.prototype.destroy = function (name) {
     if (name && this.name !== name || !this.renderer) {
       return;
     }
-
     this.renderer.destroy();
     this.imagePreloader.destroy();
     this.trigger('destroy');
@@ -2345,189 +1969,148 @@
     this.imagePreloader = null;
     this.projectInterface = null;
   };
-
   AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
     this.currentRawFrame = value;
     this.gotoFrame();
   };
-
   AnimationItem.prototype.setSpeed = function (val) {
     this.playSpeed = val;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setDirection = function (val) {
     this.playDirection = val < 0 ? -1 : 1;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setLoop = function (isLooping) {
     this.loop = isLooping;
   };
-
   AnimationItem.prototype.setVolume = function (val, name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.setVolume(val);
   };
-
   AnimationItem.prototype.getVolume = function () {
     return this.audioController.getVolume();
   };
-
   AnimationItem.prototype.mute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.mute();
   };
-
   AnimationItem.prototype.unmute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.unmute();
   };
-
   AnimationItem.prototype.updaFrameModifier = function () {
     this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
     this.audioController.setRate(this.playSpeed * this.playDirection);
   };
-
   AnimationItem.prototype.getPath = function () {
     return this.path;
   };
-
   AnimationItem.prototype.getAssetsPath = function (assetData) {
     var path = '';
-
     if (assetData.e) {
       path = assetData.p;
     } else if (this.assetsPath) {
       var imagePath = assetData.p;
-
       if (imagePath.indexOf('images/') !== -1) {
         imagePath = imagePath.split('/')[1];
       }
-
       path = this.assetsPath + imagePath;
     } else {
       path = this.path;
       path += assetData.u ? assetData.u : '';
       path += assetData.p;
     }
-
     return path;
   };
-
   AnimationItem.prototype.getAssetData = function (id) {
     var i = 0;
     var len = this.assets.length;
-
     while (i < len) {
       if (id === this.assets[i].id) {
         return this.assets[i];
       }
-
       i += 1;
     }
-
     return null;
   };
-
   AnimationItem.prototype.hide = function () {
     this.renderer.hide();
   };
-
   AnimationItem.prototype.show = function () {
     this.renderer.show();
   };
-
   AnimationItem.prototype.getDuration = function (isFrame) {
     return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
   };
-
   AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
     try {
       var element = this.renderer.getElementByPath(path);
       element.updateDocumentData(documentData, index);
-    } catch (error) {// TODO: decide how to handle catch case
+    } catch (error) {
+      // TODO: decide how to handle catch case
     }
   };
-
   AnimationItem.prototype.trigger = function (name) {
     if (this._cbs && this._cbs[name]) {
       switch (name) {
         case 'enterFrame':
           this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
           break;
-
         case 'drawnFrame':
           this.drawnFrameEvent.currentTime = this.currentFrame;
           this.drawnFrameEvent.totalTime = this.totalFrames;
           this.drawnFrameEvent.direction = this.frameModifier;
           this.triggerEvent(name, this.drawnFrameEvent);
           break;
-
         case 'loopComplete':
           this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
           break;
-
         case 'complete':
           this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
           break;
-
         case 'segmentStart':
           this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
           break;
-
         case 'destroy':
           this.triggerEvent(name, new BMDestroyEvent(name, this));
           break;
-
         default:
           this.triggerEvent(name);
       }
     }
-
     if (name === 'enterFrame' && this.onEnterFrame) {
       this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
     }
-
     if (name === 'loopComplete' && this.onLoopComplete) {
       this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
     }
-
     if (name === 'complete' && this.onComplete) {
       this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
     }
-
     if (name === 'segmentStart' && this.onSegmentStart) {
       this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
     }
-
     if (name === 'destroy' && this.onDestroy) {
       this.onDestroy.call(this, new BMDestroyEvent(name, this));
     }
   };
-
   AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
     var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
   };
-
   AnimationItem.prototype.triggerConfigError = function (nativeError) {
     var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
@@ -2541,68 +2124,53 @@
     var playingAnimationsNum = 0;
     var _stopped = true;
     var _isFrozen = false;
-
     function removeElement(ev) {
       var i = 0;
       var animItem = ev.target;
-
       while (i < len) {
         if (registeredAnimations[i].animation === animItem) {
           registeredAnimations.splice(i, 1);
           i -= 1;
           len -= 1;
-
           if (!animItem.isPaused) {
             subtractPlayingCount();
           }
         }
-
         i += 1;
       }
     }
-
     function registerAnimation(element, animationData) {
       if (!element) {
         return null;
       }
-
       var i = 0;
-
       while (i < len) {
         if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
           return registeredAnimations[i].animation;
         }
-
         i += 1;
       }
-
       var animItem = new AnimationItem();
       setupAnimation(animItem, element);
       animItem.setData(element, animationData);
       return animItem;
     }
-
     function getRegisteredAnimations() {
       var i;
       var lenAnims = registeredAnimations.length;
       var animations = [];
-
       for (i = 0; i < lenAnims; i += 1) {
         animations.push(registeredAnimations[i].animation);
       }
-
       return animations;
     }
-
     function addPlayingCount() {
       playingAnimationsNum += 1;
       activate();
     }
-
     function subtractPlayingCount() {
       playingAnimationsNum -= 1;
     }
-
     function setupAnimation(animItem, element) {
       animItem.addEventListener('destroy', removeElement);
       animItem.addEventListener('_active', addPlayingCount);
@@ -2613,118 +2181,91 @@
       });
       len += 1;
     }
-
     function loadAnimation(params) {
       var animItem = new AnimationItem();
       setupAnimation(animItem, null);
       animItem.setParams(params);
       return animItem;
     }
-
     function setSpeed(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setSpeed(val, animation);
       }
     }
-
     function setDirection(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setDirection(val, animation);
       }
     }
-
     function play(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.play(animation);
       }
     }
-
     function resume(nowTime) {
       var elapsedTime = nowTime - initTime;
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.advanceTime(elapsedTime);
       }
-
       initTime = nowTime;
-
       if (playingAnimationsNum && !_isFrozen) {
         window.requestAnimationFrame(resume);
       } else {
         _stopped = true;
       }
     }
-
     function first(nowTime) {
       initTime = nowTime;
       window.requestAnimationFrame(resume);
     }
-
     function pause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.pause(animation);
       }
     }
-
     function goToAndStop(value, isFrame, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
       }
     }
-
     function stop(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.stop(animation);
       }
     }
-
     function togglePause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.togglePause(animation);
       }
     }
-
     function destroy(animation) {
       var i;
-
       for (i = len - 1; i >= 0; i -= 1) {
         registeredAnimations[i].animation.destroy(animation);
       }
     }
-
     function searchAnimations(animationData, standalone, renderer) {
       var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')), [].slice.call(document.getElementsByClassName('bodymovin')));
       var i;
       var lenAnims = animElements.length;
-
       for (i = 0; i < lenAnims; i += 1) {
         if (renderer) {
           animElements[i].setAttribute('data-bm-type', renderer);
         }
-
         registerAnimation(animElements[i], animationData);
       }
-
       if (standalone && lenAnims === 0) {
         if (!renderer) {
           renderer = 'svg';
         }
-
         var body = document.getElementsByTagName('body')[0];
         body.innerText = '';
         var div = createTag('div');
@@ -2735,15 +2276,12 @@
         registerAnimation(div, animationData);
       }
     }
-
     function resize() {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.resize();
       }
     }
-
     function activate() {
       if (!_isFrozen && playingAnimationsNum) {
         if (_stopped) {
@@ -2752,40 +2290,31 @@
         }
       }
     }
-
     function freeze() {
       _isFrozen = true;
     }
-
     function unfreeze() {
       _isFrozen = false;
       activate();
     }
-
     function setVolume(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setVolume(val, animation);
       }
     }
-
     function mute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.mute(animation);
       }
     }
-
     function unmute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.unmute(animation);
       }
     }
-
     moduleOb.registerAnimation = registerAnimation;
     moduleOb.loadAnimation = loadAnimation;
     moduleOb.setSpeed = setSpeed;
@@ -2795,8 +2324,8 @@
     moduleOb.stop = stop;
     moduleOb.togglePause = togglePause;
     moduleOb.searchAnimations = searchAnimations;
-    moduleOb.resize = resize; // moduleOb.start = start;
-
+    moduleOb.resize = resize;
+    // moduleOb.start = start;
     moduleOb.goToAndStop = goToAndStop;
     moduleOb.destroy = destroy;
     moduleOb.freeze = freeze;
@@ -2820,23 +2349,21 @@
        * spline.get(x) => returns the easing value | x must be in [0, 1] range
        *
        */
+
     var ob = {};
     ob.getBezierEasing = getBezierEasing;
     var beziers = {};
-
     function getBezierEasing(a, b, c, d, nm) {
       var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
-
       if (beziers[str]) {
         return beziers[str];
       }
-
       var bezEasing = new BezierEasing([a, b, c, d]);
       beziers[str] = bezEasing;
       return bezEasing;
-    } // These values are established by empiricism with tests (tradeoff: performance VS precision)
+    }
 
-
+    // These values are established by empiricism with tests (tradeoff: performance VS precision)
     var NEWTON_ITERATIONS = 4;
     var NEWTON_MIN_SLOPE = 0.001;
     var SUBDIVISION_PRECISION = 0.0000001;
@@ -2844,48 +2371,40 @@
     var kSplineTableSize = 11;
     var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
     var float32ArraySupported = typeof Float32Array === 'function';
-
     function A(aA1, aA2) {
       return 1.0 - 3.0 * aA2 + 3.0 * aA1;
     }
-
     function B(aA1, aA2) {
       return 3.0 * aA2 - 6.0 * aA1;
     }
-
     function C(aA1) {
       return 3.0 * aA1;
-    } // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+    }
 
-
+    // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
     function calcBezier(aT, aA1, aA2) {
       return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
-    } // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+    }
 
-
+    // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
     function getSlope(aT, aA1, aA2) {
       return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
     }
-
     function binarySubdivide(aX, aA, aB, mX1, mX2) {
       var currentX,
-          currentT,
-          i = 0;
-
+        currentT,
+        i = 0;
       do {
         currentT = aA + (aB - aA) / 2.0;
         currentX = calcBezier(currentT, mX1, mX2) - aX;
-
         if (currentX > 0.0) {
           aB = currentT;
         } else {
           aA = currentT;
         }
       } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
-
       return currentT;
     }
-
     function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
       for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
         var currentSlope = getSlope(aGuessT, mX1, mX2);
@@ -2893,85 +2412,75 @@
         var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
         aGuessT -= currentX / currentSlope;
       }
-
       return aGuessT;
     }
+
     /**
        * points is an array of [ mX1, mY1, mX2, mY2 ]
        */
-
-
     function BezierEasing(points) {
       this._p = points;
       this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
       this._precomputed = false;
       this.get = this.get.bind(this);
     }
-
     BezierEasing.prototype = {
       get: function get(x) {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         if (!this._precomputed) this._precompute();
         if (mX1 === mY1 && mX2 === mY2) return x; // linear
         // Because JavaScript number are imprecise, we should guarantee the extremes are right.
-
         if (x === 0) return 0;
         if (x === 1) return 1;
         return calcBezier(this._getTForX(x), mY1, mY2);
       },
       // Private part
+
       _precompute: function _precompute() {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         this._precomputed = true;
-
         if (mX1 !== mY1 || mX2 !== mY2) {
           this._calcSampleValues();
         }
       },
       _calcSampleValues: function _calcSampleValues() {
         var mX1 = this._p[0],
-            mX2 = this._p[2];
-
+          mX2 = this._p[2];
         for (var i = 0; i < kSplineTableSize; ++i) {
           this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
         }
       },
-
       /**
            * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
            */
       _getTForX: function _getTForX(aX) {
         var mX1 = this._p[0],
-            mX2 = this._p[2],
-            mSampleValues = this._mSampleValues;
+          mX2 = this._p[2],
+          mSampleValues = this._mSampleValues;
         var intervalStart = 0.0;
         var currentSample = 1;
         var lastSample = kSplineTableSize - 1;
-
         for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
           intervalStart += kSampleStepSize;
         }
+        --currentSample;
 
-        --currentSample; // Interpolate to provide an initial guess for t
-
+        // Interpolate to provide an initial guess for t
         var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
         var guessForT = intervalStart + dist * kSampleStepSize;
         var initialSlope = getSlope(guessForT, mX1, mX2);
-
         if (initialSlope >= NEWTON_MIN_SLOPE) {
           return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
         }
-
         if (initialSlope === 0.0) {
           return guessForT;
         }
-
         return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
       }
     };
@@ -2982,7 +2491,6 @@
     function _double(arr) {
       return arr.concat(createSizedArray(arr.length));
     }
-
     return {
       "double": _double
     };
@@ -2997,34 +2505,27 @@
         newElement: newElement,
         release: release
       };
-
       function newElement() {
         var element;
-
         if (_length) {
           _length -= 1;
           element = pool[_length];
         } else {
           element = _create();
         }
-
         return element;
       }
-
       function release(element) {
         if (_length === _maxLength) {
           pool = pooling["double"](pool);
           _maxLength *= 2;
         }
-
         if (_release) {
           _release(element);
         }
-
         pool[_length] = element;
         _length += 1;
       }
-
       return ob;
     };
   }();
@@ -3037,7 +2538,6 @@
         lengths: createTypedArray('float32', getDefaultCurveSegments())
       };
     }
-
     return poolFactory(8, create);
   }();
 
@@ -3048,39 +2548,31 @@
         totalLength: 0
       };
     }
-
     function release(element) {
       var i;
       var len = element.lengths.length;
-
       for (i = 0; i < len; i += 1) {
         bezierLengthPool.release(element.lengths[i]);
       }
-
       element.lengths.length = 0;
     }
-
     return poolFactory(8, create, release);
   }();
 
   function bezFunction() {
     var math = Math;
-
     function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
       var det1 = x1 * y2 + y1 * x3 + x2 * y3 - x3 * y2 - y3 * x1 - x2 * y1;
       return det1 > -0.001 && det1 < 0.001;
     }
-
     function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
       if (z1 === 0 && z2 === 0 && z3 === 0) {
         return pointOnLine2D(x1, y1, x2, y2, x3, y3);
       }
-
       var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
       var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
       var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
       var diffDist;
-
       if (dist1 > dist2) {
         if (dist1 > dist3) {
           diffDist = dist1 - dist2 - dist3;
@@ -3092,10 +2584,8 @@
       } else {
         diffDist = dist2 - dist1 - dist3;
       }
-
       return diffDist > -0.0001 && diffDist < 0.0001;
     }
-
     var getBezierLength = function () {
       return function (pt1, pt2, pt3, pt4) {
         var curveSegments = getDefaultCurveSegments();
@@ -3110,36 +2600,28 @@
         var lastPoint = [];
         var lengthData = bezierLengthPool.newElement();
         len = pt3.length;
-
         for (k = 0; k < curveSegments; k += 1) {
           perc = k / (curveSegments - 1);
           ptDistance = 0;
-
           for (i = 0; i < len; i += 1) {
             ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
             point[i] = ptCoord;
-
             if (lastPoint[i] !== null) {
               ptDistance += bmPow(point[i] - lastPoint[i], 2);
             }
-
             lastPoint[i] = point[i];
           }
-
           if (ptDistance) {
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
           }
-
           lengthData.percents[k] = perc;
           lengthData.lengths[k] = addedLength;
         }
-
         lengthData.addedLength = addedLength;
         return lengthData;
       };
     }();
-
     function getSegmentsLength(shapeData) {
       var segmentsLength = segmentsLengthPool.newElement();
       var closed = shapeData.c;
@@ -3150,36 +2632,29 @@
       var len = shapeData._length;
       var lengths = segmentsLength.lengths;
       var totalLength = 0;
-
       for (i = 0; i < len - 1; i += 1) {
         lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
         totalLength += lengths[i].addedLength;
       }
-
       if (closed && len) {
         lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
         totalLength += lengths[i].addedLength;
       }
-
       segmentsLength.totalLength = totalLength;
       return segmentsLength;
     }
-
     function BezierData(length) {
       this.segmentLength = 0;
       this.points = new Array(length);
     }
-
     function PointData(partial, point) {
       this.partialLength = partial;
       this.point = point;
     }
-
     var buildBezierData = function () {
       var storedData = {};
       return function (pt1, pt2, pt3, pt4) {
         var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
-
         if (!storedData[bezierName]) {
           var curveSegments = getDefaultCurveSegments();
           var k;
@@ -3191,42 +2666,33 @@
           var ptDistance;
           var point;
           var lastPoint = null;
-
           if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
             curveSegments = 2;
           }
-
           var bezierData = new BezierData(curveSegments);
           len = pt3.length;
-
           for (k = 0; k < curveSegments; k += 1) {
             point = createSizedArray(len);
             perc = k / (curveSegments - 1);
             ptDistance = 0;
-
             for (i = 0; i < len; i += 1) {
               ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
               point[i] = ptCoord;
-
               if (lastPoint !== null) {
                 ptDistance += bmPow(point[i] - lastPoint[i], 2);
               }
             }
-
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
             bezierData.points[k] = new PointData(ptDistance, point);
             lastPoint = point;
           }
-
           bezierData.segmentLength = addedLength;
           storedData[bezierName] = bezierData;
         }
-
         return storedData[bezierName];
       };
     }();
-
     function getDistancePerc(perc, bezierData) {
       var percents = bezierData.percents;
       var lengths = bezierData.lengths;
@@ -3234,14 +2700,11 @@
       var initPos = bmFloor((len - 1) * perc);
       var lengthPos = perc * bezierData.addedLength;
       var lPerc = 0;
-
       if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
         return percents[initPos];
       }
-
       var dir = lengths[initPos] > lengthPos ? -1 : 1;
       var flag = true;
-
       while (flag) {
         if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
           lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
@@ -3249,20 +2712,16 @@
         } else {
           initPos += dir;
         }
-
         if (initPos < 0 || initPos >= len - 1) {
           // FIX for TypedArrays that don't store floating point values with enough accuracy
           if (initPos === len - 1) {
             return percents[initPos];
           }
-
           flag = false;
         }
       }
-
       return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
     }
-
     function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
       var t1 = getDistancePerc(percent, bezierData);
       var u1 = 1 - t1;
@@ -3270,16 +2729,13 @@
       var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
       return [ptX, ptY];
     }
-
     var bezierSegmentPoints = createTypedArray('float32', 8);
-
     function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
       if (startPerc < 0) {
         startPerc = 0;
       } else if (startPerc > 1) {
         startPerc = 1;
       }
-
       var t0 = getDistancePerc(startPerc, bezierData);
       endPerc = endPerc > 1 ? 1 : endPerc;
       var t1 = getDistancePerc(endPerc, bezierData);
@@ -3289,45 +2745,31 @@
       var u1 = 1 - t1;
       var u0u0u0 = u0 * u0 * u0;
       var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
-
       var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
-
-      var t0t0t0 = t0 * t0 * t0; //
-
+      var t0t0t0 = t0 * t0 * t0;
+      //
       var u0u0u1 = u0 * u0 * u1;
       var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
-
       var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
-
-      var t0t0t1 = t0 * t0 * t1; //
-
+      var t0t0t1 = t0 * t0 * t1;
+      //
       var u0u1u1 = u0 * u1 * u1;
       var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
-
       var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
-
-      var t0t1t1 = t0 * t1 * t1; //
-
+      var t0t1t1 = t0 * t1 * t1;
+      //
       var u1u1u1 = u1 * u1 * u1;
       var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1t1 = t1 * t1 * t1;
-
       for (i = 0; i < len; i += 1) {
         bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
       }
-
       return bezierSegmentPoints;
     }
-
     return {
       getSegmentsLength: getSegmentsLength,
       getNewSegment: getNewSegment,
@@ -3337,20 +2779,16 @@
       pointOnLine3D: pointOnLine3D
     };
   }
-
   var bez = bezFunction();
 
   var initFrame = initialDefaultFrame;
   var mathAbs = Math.abs;
-
   function interpolateValue(frameNum, caching) {
     var offsetTime = this.offsetTime;
     var newValue;
-
     if (this.propType === 'multidimensional') {
       newValue = createTypedArray('float32', this.pv.length);
     }
-
     var iterationIndex = caching.lastIndex;
     var i = iterationIndex;
     var len = this.keyframes.length - 1;
@@ -3358,25 +2796,20 @@
     var keyData;
     var nextKeyData;
     var keyframeMetadata;
-
     while (flag) {
       keyData = this.keyframes[i];
       nextKeyData = this.keyframes[i + 1];
-
       if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
         if (keyData.h) {
           keyData = nextKeyData;
         }
-
         iterationIndex = 0;
         break;
       }
-
       if (nextKeyData.t - offsetTime > frameNum) {
         iterationIndex = i;
         break;
       }
-
       if (i < len - 1) {
         i += 1;
       } else {
@@ -3384,7 +2817,6 @@
         flag = false;
       }
     }
-
     keyframeMetadata = this.keyframesMetadata[i] || {};
     var k;
     var kLen;
@@ -3395,22 +2827,18 @@
     var nextKeyTime = nextKeyData.t - offsetTime;
     var keyTime = keyData.t - offsetTime;
     var endValue;
-
     if (keyData.to) {
       if (!keyframeMetadata.bezierData) {
         keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
       }
-
       var bezierData = keyframeMetadata.bezierData;
-
       if (frameNum >= nextKeyTime || frameNum < keyTime) {
         var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
         kLen = bezierData.points[ind].point.length;
-
         for (k = 0; k < kLen; k += 1) {
           newValue[k] = bezierData.points[ind].point[k];
-        } // caching._lastKeyframeIndex = -1;
-
+        }
+        // caching._lastKeyframeIndex = -1;
       } else {
         if (keyframeMetadata.__fnct) {
           fnc = keyframeMetadata.__fnct;
@@ -3418,7 +2846,6 @@
           fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
           keyframeMetadata.__fnct = fnc;
         }
-
         perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
         var distanceInLine = bezierData.segmentLength * perc;
         var segmentPerc;
@@ -3426,36 +2853,28 @@
         j = caching.lastFrame < frameNum && caching._lastKeyframeIndex === i ? caching._lastPoint : 0;
         flag = true;
         jLen = bezierData.points.length;
-
         while (flag) {
           addedLength += bezierData.points[j].partialLength;
-
           if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k];
             }
-
             break;
           } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
             segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
             }
-
             break;
           }
-
           if (j < jLen - 1) {
             j += 1;
           } else {
             flag = false;
           }
         }
-
         caching._lastPoint = j;
         caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
         caching._lastKeyframeIndex = i;
@@ -3468,7 +2887,6 @@
       var keyValue;
       len = keyData.s.length;
       endValue = nextKeyData.s || keyData.e;
-
       if (this.sh && keyData.h !== 1) {
         if (frameNum >= nextKeyTime) {
           newValue[0] = endValue[0];
@@ -3496,7 +2914,6 @@
                 if (!keyframeMetadata.__fnct) {
                   keyframeMetadata.__fnct = [];
                 }
-
                 if (!keyframeMetadata.__fnct[i]) {
                   outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
                   outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
@@ -3517,14 +2934,11 @@
               } else {
                 fnc = keyframeMetadata.__fnct;
               }
-
               perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
             }
           }
-
           endValue = nextKeyData.s || keyData.e;
           keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
-
           if (this.propType === 'multidimensional') {
             newValue[i] = keyValue;
           } else {
@@ -3533,12 +2947,11 @@
         }
       }
     }
-
     caching.lastIndex = iterationIndex;
     return newValue;
-  } // based on @Toji's https://github.com/toji/gl-matrix/
+  }
 
-
+  // based on @Toji's https://github.com/toji/gl-matrix/
   function slerp(a, b, t) {
     var out = [];
     var ax = a[0];
@@ -3555,7 +2968,6 @@
     var scale0;
     var scale1;
     cosom = ax * bx + ay * by + az * bz + aw * bw;
-
     if (cosom < 0.0) {
       cosom = -cosom;
       bx = -bx;
@@ -3563,7 +2975,6 @@
       bz = -bz;
       bw = -bw;
     }
-
     if (1.0 - cosom > 0.000001) {
       omega = Math.acos(cosom);
       sinom = Math.sin(omega);
@@ -3573,14 +2984,12 @@
       scale0 = 1.0 - t;
       scale1 = t;
     }
-
     out[0] = scale0 * ax + scale1 * bx;
     out[1] = scale0 * ay + scale1 * by;
     out[2] = scale0 * az + scale1 * bz;
     out[3] = scale0 * aw + scale1 * bw;
     return out;
   }
-
   function quaternionToEuler(out, quat) {
     var qx = quat[0];
     var qy = quat[1];
@@ -3593,7 +3002,6 @@
     out[1] = attitude / degToRads;
     out[2] = bank / degToRads;
   }
-
   function createQuaternion(values) {
     var heading = values[0] * degToRads;
     var attitude = values[1] * degToRads;
@@ -3610,32 +3018,25 @@
     var z = c1 * s2 * c3 - s1 * c2 * s3;
     return [x, y, z, w];
   }
-
   function getValueAtCurrentTime() {
     var frameNum = this.comp.renderedFrame - this.offsetTime;
     var initTime = this.keyframes[0].t - this.offsetTime;
     var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
-
     if (!(frameNum === this._caching.lastFrame || this._caching.lastFrame !== initFrame && (this._caching.lastFrame >= endTime && frameNum >= endTime || this._caching.lastFrame < initTime && frameNum < initTime))) {
       if (this._caching.lastFrame >= frameNum) {
         this._caching._lastKeyframeIndex = -1;
         this._caching.lastIndex = 0;
       }
-
       var renderResult = this.interpolateValue(frameNum, this._caching);
       this.pv = renderResult;
     }
-
     this._caching.lastFrame = frameNum;
     return this.pv;
   }
-
   function setVValue(val) {
     var multipliedValue;
-
     if (this.propType === 'unidimensional') {
       multipliedValue = val * this.mult;
-
       if (mathAbs(this.v - multipliedValue) > 0.00001) {
         this.v = multipliedValue;
         this._mdf = true;
@@ -3643,51 +3044,41 @@
     } else {
       var i = 0;
       var len = this.v.length;
-
       while (i < len) {
         multipliedValue = val[i] * this.mult;
-
         if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
           this.v[i] = multipliedValue;
           this._mdf = true;
         }
-
         i += 1;
       }
     }
   }
-
   function processEffectsSequence() {
     if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
       return;
     }
-
     if (this.lock) {
       this.setVValue(this.pv);
       return;
     }
-
     this.lock = true;
     this._mdf = this._isFirstFrame;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = this.kf ? this.pv : this.data.k;
-
     for (i = 0; i < len; i += 1) {
       finalValue = this.effectsSequence[i](finalValue);
     }
-
     this.setVValue(finalValue);
     this._isFirstFrame = false;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   }
-
   function addEffect(effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.container.addDynamicProperty(this);
   }
-
   function ValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.mult = mult || 1;
@@ -3707,7 +3098,6 @@
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function MultiDimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     this.mult = mult || 1;
@@ -3724,19 +3114,16 @@
     this.v = createTypedArray('float32', len);
     this.pv = createTypedArray('float32', len);
     this.vel = createTypedArray('float32', len);
-
     for (i = 0; i < len; i += 1) {
       this.v[i] = data.k[i] * this.mult;
       this.pv[i] = data.k[i];
     }
-
     this._isFirstFrame = true;
     this.effectsSequence = [];
     this.getValue = processEffectsSequence;
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function KeyframedValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.keyframes = data.k;
@@ -3765,7 +3152,6 @@
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.addEffect = addEffect;
   }
-
   function KeyframedMultidimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     var i;
@@ -3774,19 +3160,16 @@
     var e;
     var to;
     var ti;
-
     for (i = 0; i < len - 1; i += 1) {
       if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
         s = data.k[i].s;
         e = data.k[i + 1].s;
         to = data.k[i].to;
         ti = data.k[i].ti;
-
         if (s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1]) || s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2])) {
           data.k[i].to = null;
           data.k[i].ti = null;
         }
-
         if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
           if (s.length === 2 || s[2] === e[2] && to[2] === 0 && ti[2] === 0) {
             data.k[i].to = null;
@@ -3795,7 +3178,6 @@
         }
       }
     }
-
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.data = data;
     this.keyframes = data.k;
@@ -3815,12 +3197,10 @@
     var arrLen = data.k[0].s.length;
     this.v = createTypedArray('float32', arrLen);
     this.pv = createTypedArray('float32', arrLen);
-
     for (i = 0; i < arrLen; i += 1) {
       this.v[i] = initFrame;
       this.pv[i] = initFrame;
     }
-
     this._caching = {
       lastFrame: initFrame,
       lastIndex: 0,
@@ -3828,15 +3208,12 @@
     };
     this.addEffect = addEffect;
   }
-
   var PropertyFactory = function () {
     function getProp(elem, data, type, mult, container) {
       if (data.sid) {
         data = elem.globalData.slotManager.getProp(data);
       }
-
       var p;
-
       if (!data.k.length) {
         p = new ValueProperty(elem, data, mult, container);
       } else if (typeof data.k[0] === 'number') {
@@ -3846,23 +3223,18 @@
           case 0:
             p = new KeyframedValueProperty(elem, data, mult, container);
             break;
-
           case 1:
             p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
             break;
-
           default:
             break;
         }
       }
-
       if (p.effectsSequence.length) {
         container.addDynamicProperty(p);
       }
-
       return p;
     }
-
     var ob = {
       getProp: getProp
     };
@@ -3870,7 +3242,6 @@
   }();
 
   function DynamicPropertyContainer() {}
-
   DynamicPropertyContainer.prototype = {
     addDynamicProperty: function addDynamicProperty(prop) {
       if (this.dynamicProperties.indexOf(prop) === -1) {
@@ -3883,10 +3254,8 @@
       this._mdf = false;
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         this.dynamicProperties[i].getValue();
-
         if (this.dynamicProperties[i]._mdf) {
           this._mdf = true;
         }
@@ -3904,7 +3273,6 @@
     function create() {
       return createTypedArray('float32', 2);
     }
-
     return poolFactory(8, create);
   }();
 
@@ -3916,12 +3284,10 @@
     this.o = createSizedArray(this._maxLength);
     this.i = createSizedArray(this._maxLength);
   }
-
   ShapePath.prototype.setPathData = function (closed, len) {
     this.c = closed;
     this.setLength(len);
     var i = 0;
-
     while (i < len) {
       this.v[i] = pointPool.newElement();
       this.o[i] = pointPool.newElement();
@@ -3929,62 +3295,49 @@
       i += 1;
     }
   };
-
   ShapePath.prototype.setLength = function (len) {
     while (this._maxLength < len) {
       this.doubleArrayLength();
     }
-
     this._length = len;
   };
-
   ShapePath.prototype.doubleArrayLength = function () {
     this.v = this.v.concat(createSizedArray(this._maxLength));
     this.i = this.i.concat(createSizedArray(this._maxLength));
     this.o = this.o.concat(createSizedArray(this._maxLength));
     this._maxLength *= 2;
   };
-
   ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
     var arr;
     this._length = Math.max(this._length, pos + 1);
-
     if (this._length >= this._maxLength) {
       this.doubleArrayLength();
     }
-
     switch (type) {
       case 'v':
         arr = this.v;
         break;
-
       case 'i':
         arr = this.i;
         break;
-
       case 'o':
         arr = this.o;
         break;
-
       default:
         arr = [];
         break;
     }
-
     if (!arr[pos] || arr[pos] && !replace) {
       arr[pos] = pointPool.newElement();
     }
-
     arr[pos][0] = x;
     arr[pos][1] = y;
   };
-
   ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
     this.setXYAt(vX, vY, 'v', pos, replace);
     this.setXYAt(oX, oY, 'o', pos, replace);
     this.setXYAt(iX, iY, 'i', pos, replace);
   };
-
   ShapePath.prototype.reverse = function () {
     var newPath = new ShapePath();
     newPath.setPathData(this.c, this._length);
@@ -3992,24 +3345,19 @@
     var outPoints = this.o;
     var inPoints = this.i;
     var init = 0;
-
     if (this.c) {
       newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
       init = 1;
     }
-
     var cnt = this._length - 1;
     var len = this._length;
     var i;
-
     for (i = init; i < len; i += 1) {
       newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
       cnt -= 1;
     }
-
     return newPath;
   };
-
   ShapePath.prototype.length = function () {
     return this._length;
   };
@@ -4018,11 +3366,9 @@
     function create() {
       return new ShapePath();
     }
-
     function release(shapePath) {
       var len = shapePath._length;
       var i;
-
       for (i = 0; i < len; i += 1) {
         pointPool.release(shapePath.v[i]);
         pointPool.release(shapePath.i[i]);
@@ -4031,25 +3377,20 @@
         shapePath.i[i] = null;
         shapePath.o[i] = null;
       }
-
       shapePath._length = 0;
       shapePath.c = false;
     }
-
     function clone(shape) {
       var cloned = factory.newElement();
       var i;
       var len = shape._length === undefined ? shape.v.length : shape._length;
       cloned.setLength(len);
       cloned.c = shape.c;
-
       for (i = 0; i < len; i += 1) {
         cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
       }
-
       return cloned;
     }
-
     var factory = poolFactory(4, create, release);
     factory.clone = clone;
     return factory;
@@ -4060,24 +3401,19 @@
     this._maxLength = 4;
     this.shapes = createSizedArray(this._maxLength);
   }
-
   ShapeCollection.prototype.addShape = function (shapeData) {
     if (this._length === this._maxLength) {
       this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
       this._maxLength *= 2;
     }
-
     this.shapes[this._length] = shapeData;
     this._length += 1;
   };
-
   ShapeCollection.prototype.releaseShapes = function () {
     var i;
-
     for (i = 0; i < this._length; i += 1) {
       shapePool.release(this.shapes[i]);
     }
-
     this._length = 0;
   };
 
@@ -4089,45 +3425,35 @@
     var _length = 0;
     var _maxLength = 4;
     var pool = createSizedArray(_maxLength);
-
     function newShapeCollection() {
       var shapeCollection;
-
       if (_length) {
         _length -= 1;
         shapeCollection = pool[_length];
       } else {
         shapeCollection = new ShapeCollection();
       }
-
       return shapeCollection;
     }
-
     function release(shapeCollection) {
       var i;
       var len = shapeCollection._length;
-
       for (i = 0; i < len; i += 1) {
         shapePool.release(shapeCollection.shapes[i]);
       }
-
       shapeCollection._length = 0;
-
       if (_length === _maxLength) {
         pool = pooling["double"](pool);
         _maxLength *= 2;
       }
-
       pool[_length] = shapeCollection;
       _length += 1;
     }
-
     return ob;
   }();
 
   var ShapePropertyFactory = function () {
     var initFrame = -999999;
-
     function interpolateShape(frameNum, previousValue, caching) {
       var iterationIndex = caching.lastIndex;
       var keyPropS;
@@ -4140,7 +3466,6 @@
       var perc;
       var vertexValue;
       var kf = this.keyframes;
-
       if (frameNum < kf[0].t - this.offsetTime) {
         keyPropS = kf[0].s[0];
         isHold = true;
@@ -4152,7 +3477,6 @@
               }else{
                   keyPropS = kf[kf.length - 2].e[0];
               } */
-
         isHold = true;
       } else {
         var i = iterationIndex;
@@ -4161,26 +3485,21 @@
         var keyData;
         var nextKeyData;
         var keyframeMetadata;
-
         while (flag) {
           keyData = kf[i];
           nextKeyData = kf[i + 1];
-
           if (nextKeyData.t - this.offsetTime > frameNum) {
             break;
           }
-
           if (i < len - 1) {
             i += 1;
           } else {
             flag = false;
           }
         }
-
         keyframeMetadata = this.keyframesMetadata[i] || {};
         isHold = keyData.h === 1;
         iterationIndex = i;
-
         if (!isHold) {
           if (frameNum >= nextKeyData.t - this.offsetTime) {
             perc = 1;
@@ -4188,27 +3507,21 @@
             perc = 0;
           } else {
             var fnc;
-
             if (keyframeMetadata.__fnct) {
               fnc = keyframeMetadata.__fnct;
             } else {
               fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
               keyframeMetadata.__fnct = fnc;
             }
-
             perc = fnc((frameNum - (keyData.t - this.offsetTime)) / (nextKeyData.t - this.offsetTime - (keyData.t - this.offsetTime)));
           }
-
           keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
         }
-
         keyPropS = keyData.s[0];
       }
-
       jLen = previousValue._length;
       kLen = keyPropS.i[0].length;
       caching.lastIndex = iterationIndex;
-
       for (j = 0; j < jLen; j += 1) {
         for (k = 0; k < kLen; k += 1) {
           vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
@@ -4220,44 +3533,36 @@
         }
       }
     }
-
     function interpolateShapeCurrentTime() {
       var frameNum = this.comp.renderedFrame - this.offsetTime;
       var initTime = this.keyframes[0].t - this.offsetTime;
       var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
       var lastFrame = this._caching.lastFrame;
-
       if (!(lastFrame !== initFrame && (lastFrame < initTime && frameNum < initTime || lastFrame > endTime && frameNum > endTime))) {
         /// /
         this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
-        this.interpolateShape(frameNum, this.pv, this._caching); /// /
+        this.interpolateShape(frameNum, this.pv, this._caching);
+        /// /
       }
-
       this._caching.lastFrame = frameNum;
       return this.pv;
     }
-
     function resetShape() {
       this.paths = this.localShapeCollection;
     }
-
     function shapesEqual(shape1, shape2) {
       if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
         return false;
       }
-
       var i;
       var len = shape1._length;
-
       for (i = 0; i < len; i += 1) {
         if (shape1.v[i][0] !== shape2.v[i][0] || shape1.v[i][1] !== shape2.v[i][1] || shape1.o[i][0] !== shape2.o[i][0] || shape1.o[i][1] !== shape2.o[i][1] || shape1.i[i][0] !== shape2.i[i][0] || shape1.i[i][1] !== shape2.i[i][1]) {
           return false;
         }
       }
-
       return true;
     }
-
     function setVValue(newPath) {
       if (!shapesEqual(this.v, newPath)) {
         this.v = shapePool.clone(newPath);
@@ -4267,26 +3572,21 @@
         this.paths = this.localShapeCollection;
       }
     }
-
     function processEffectsSequence() {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (!this.effectsSequence.length) {
         this._mdf = false;
         return;
       }
-
       if (this.lock) {
         this.setVValue(this.pv);
         return;
       }
-
       this.lock = true;
       this._mdf = false;
       var finalValue;
-
       if (this.kf) {
         finalValue = this.pv;
       } else if (this.data.ks) {
@@ -4294,19 +3594,15 @@
       } else {
         finalValue = this.data.pt.k;
       }
-
       var i;
       var len = this.effectsSequence.length;
-
       for (i = 0; i < len; i += 1) {
         finalValue = this.effectsSequence[i](finalValue);
       }
-
       this.setVValue(finalValue);
       this.lock = false;
       this.frameId = this.elem.globalData.frameId;
     }
-
     function ShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4325,17 +3621,14 @@
       this.reset = resetShape;
       this.effectsSequence = [];
     }
-
     function addEffect(effectFunction) {
       this.effectsSequence.push(effectFunction);
       this.container.addDynamicProperty(this);
     }
-
     ShapeProperty.prototype.interpolateShape = interpolateShape;
     ShapeProperty.prototype.getValue = processEffectsSequence;
     ShapeProperty.prototype.setVValue = setVValue;
     ShapeProperty.prototype.addEffect = addEffect;
-
     function KeyframedShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4361,15 +3654,12 @@
       };
       this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
     }
-
     KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
     KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
     KeyframedShapeProperty.prototype.setVValue = setVValue;
     KeyframedShapeProperty.prototype.addEffect = addEffect;
-
     var EllShapeProperty = function () {
       var cPoint = roundCorner;
-
       function EllShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
         this.v.setPathData(true, 4);
@@ -4383,7 +3673,6 @@
         this.initDynamicPropertyContainer(elem);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4391,17 +3680,14 @@
           this.convertEllToPath();
         }
       }
-
       EllShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertEllToPath();
           }
@@ -4411,9 +3697,7 @@
           var p1 = this.p.v[1];
           var s0 = this.s.v[0] / 2;
           var s1 = this.s.v[1] / 2;
-
           var _cw = this.d !== 3;
-
           var _v = this.v;
           _v.v[0][0] = p0;
           _v.v[0][1] = p1 - s1;
@@ -4444,7 +3728,6 @@
       extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
       return EllShapePropertyFactory;
     }();
-
     var StarShapeProperty = function () {
       function StarShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4455,7 +3738,6 @@
         this.frameId = -1;
         this.d = data.d;
         this.initDynamicPropertyContainer(elem);
-
         if (data.sy === 1) {
           this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
           this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
@@ -4463,7 +3745,6 @@
         } else {
           this.convertToPath = this.convertPolygonToPath;
         }
-
         this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
@@ -4472,7 +3753,6 @@
         this.localShapeCollection = shapeCollectionPool.newShapeCollection();
         this.localShapeCollection.addShape(this.v);
         this.paths = this.localShapeCollection;
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4480,17 +3760,14 @@
           this.convertToPath();
         }
       }
-
       StarShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertToPath();
           }
@@ -4501,7 +3778,6 @@
           /* this.v.v.length = numPts;
                   this.v.i.length = numPts;
                   this.v.o.length = numPts; */
-
           var longFlag = true;
           var longRad = this.or.v;
           var shortRad = this.ir.v;
@@ -4517,7 +3793,6 @@
           currentAng += this.r.v;
           var dir = this.data.d === 3 ? -1 : 1;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             rad = longFlag ? longRad : shortRad;
             roundness = longFlag ? longRound : shortRound;
@@ -4529,11 +3804,11 @@
             x += +this.p.v[0];
             y += +this.p.v[1];
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
             /* this.v.v[i] = [x,y];
                       this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
                       this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
                       this.v._length = numPts; */
-
             longFlag = !longFlag;
             currentAng += angle * dir;
           }
@@ -4549,7 +3824,6 @@
           var dir = this.data.d === 3 ? -1 : 1;
           currentAng += this.r.v;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             var x = rad * Math.cos(currentAng);
             var y = rad * Math.sin(currentAng);
@@ -4560,7 +3834,6 @@
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
             currentAng += angle * dir;
           }
-
           this.paths.length = 0;
           this.paths[0] = this.v;
         }
@@ -4568,7 +3841,6 @@
       extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
       return StarShapePropertyFactory;
     }();
-
     var RectShapeProperty = function () {
       function RectShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4584,7 +3856,6 @@
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4592,7 +3863,6 @@
           this.convertRectToPath();
         }
       }
-
       RectShapePropertyFactory.prototype = {
         convertRectToPath: function convertRectToPath() {
           var p0 = this.p.v[0];
@@ -4602,11 +3872,9 @@
           var round = bmMin(v0, v1, this.r.v);
           var cPoint = round * (1 - roundCorner);
           this.v._length = 0;
-
           if (this.d === 2 || this.d === 1) {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
             this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
               this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
@@ -4620,7 +3888,6 @@
             }
           } else {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
               this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
@@ -4640,10 +3907,8 @@
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertRectToPath();
           }
@@ -4653,14 +3918,11 @@
       extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
       return RectShapePropertyFactory;
     }();
-
     function getShapeProp(elem, data, type) {
       var prop;
-
       if (type === 3 || type === 4) {
         var dataProp = type === 3 ? data.pt : data.ks;
         var keys = dataProp.k;
-
         if (keys.length) {
           prop = new KeyframedShapeProperty(elem, data, type);
         } else {
@@ -4673,22 +3935,17 @@
       } else if (type === 7) {
         prop = new StarShapeProperty(elem, data);
       }
-
       if (prop.k) {
         elem.addDynamicProperty(prop);
       }
-
       return prop;
     }
-
     function getConstructorFunction() {
       return ShapeProperty;
     }
-
     function getKeyframedConstructorFunction() {
       return KeyframedShapeProperty;
     }
-
     var ob = {};
     ob.getShapeProp = getShapeProp;
     ob.getConstructorFunction = getConstructorFunction;
@@ -4730,7 +3987,6 @@
     var _sin = Math.sin;
     var _tan = Math.tan;
     var _rnd = Math.round;
-
     function reset() {
       this.props[0] = 1;
       this.props[1] = 0;
@@ -4750,83 +4006,59 @@
       this.props[15] = 1;
       return this;
     }
-
     function rotate(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function rotateX(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateY(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateZ(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function shear(sx, sy) {
       return this._t(1, sy, sx, 1, 0, 0);
     }
-
     function skew(ax, ay) {
       return this.shear(_tan(ax), _tan(ay));
     }
-
     function skewFromAxis(ax, angle) {
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
-      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+      // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
     }
-
     function scale(sx, sy, sz) {
       if (!sz && sz !== 0) {
         sz = 1;
       }
-
       if (sx === 1 && sy === 1 && sz === 1) {
         return this;
       }
-
       return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
     }
-
     function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
       this.props[0] = a;
       this.props[1] = b;
@@ -4846,32 +4078,26 @@
       this.props[15] = p;
       return this;
     }
-
     function translate(tx, ty, tz) {
       tz = tz || 0;
-
       if (tx !== 0 || ty !== 0 || tz !== 0) {
         return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
       }
-
       return this;
     }
-
     function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
       var _p = this.props;
-
       if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
         // NOTE: commenting this condition because TurboFan deoptimizes code when present
         // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
         _p[12] = _p[12] * a2 + _p[15] * m2;
         _p[13] = _p[13] * f2 + _p[15] * n2;
         _p[14] = _p[14] * k2 + _p[15] * o2;
-        _p[15] *= p2; // }
-
+        _p[15] *= p2;
+        // }
         this._identityCalculated = false;
         return this;
       }
-
       var a1 = _p[0];
       var b1 = _p[1];
       var c1 = _p[2];
@@ -4888,12 +4114,12 @@
       var n1 = _p[13];
       var o1 = _p[14];
       var p1 = _p[15];
+
       /* matrix order (canvas compatible):
            * ace
            * bdf
            * 001
            */
-
       _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
       _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
       _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
@@ -4913,53 +4139,40 @@
       this._identityCalculated = false;
       return this;
     }
-
     function multiply(matrix) {
       var matrixProps = matrix.props;
       return this.transform(matrixProps[0], matrixProps[1], matrixProps[2], matrixProps[3], matrixProps[4], matrixProps[5], matrixProps[6], matrixProps[7], matrixProps[8], matrixProps[9], matrixProps[10], matrixProps[11], matrixProps[12], matrixProps[13], matrixProps[14], matrixProps[15]);
     }
-
     function isIdentity() {
       if (!this._identityCalculated) {
         this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
         this._identityCalculated = true;
       }
-
       return this._identity;
     }
-
     function equals(matr) {
       var i = 0;
-
       while (i < 16) {
         if (matr.props[i] !== this.props[i]) {
           return false;
         }
-
         i += 1;
       }
-
       return true;
     }
-
     function clone(matr) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         matr.props[i] = this.props[i];
       }
-
       return matr;
     }
-
     function cloneFromProps(props) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         this.props[i] = props[i];
       }
     }
-
     function applyToPoint(x, y, z) {
       return {
         x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
@@ -4971,19 +4184,15 @@
            y: x * me.b + y * me.d + me.f
            }; */
     }
-
     function applyToX(x, y, z) {
       return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
     }
-
     function applyToY(x, y, z) {
       return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
     }
-
     function applyToZ(x, y, z) {
       return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
     }
-
     function getInverseMatrix() {
       var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
       var a = this.props[5] / determinant;
@@ -5001,27 +4210,21 @@
       inverseMatrix.props[13] = f;
       return inverseMatrix;
     }
-
     function inversePoint(pt) {
       var inverseMatrix = this.getInverseMatrix();
       return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
     }
-
     function inversePoints(pts) {
       var i;
       var len = pts.length;
       var retPts = [];
-
       for (i = 0; i < len; i += 1) {
         retPts[i] = inversePoint(pts[i]);
       }
-
       return retPts;
     }
-
     function applyToTriplePoints(pt1, pt2, pt3) {
       var arr = createTypedArray('float32', 6);
-
       if (this.isIdentity()) {
         arr[0] = pt1[0];
         arr[1] = pt1[1];
@@ -5043,34 +4246,26 @@
         arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
         arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
       }
-
       return arr;
     }
-
     function applyToPointArray(x, y, z) {
       var arr;
-
       if (this.isIdentity()) {
         arr = [x, y, z];
       } else {
         arr = [x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12], x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13], x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14]];
       }
-
       return arr;
     }
-
     function applyToPointStringified(x, y) {
       if (this.isIdentity()) {
         return x + ',' + y;
       }
-
       var _p = this.props;
       return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
     }
-
     function toCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
@@ -5078,49 +4273,34 @@
       var props = this.props;
       var cssValue = 'matrix3d(';
       var v = 10000;
-
       while (i < 16) {
         cssValue += _rnd(props[i] * v) / v;
         cssValue += i === 15 ? ')' : ',';
         i += 1;
       }
-
       return cssValue;
     }
-
     function roundMatrixProperty(val) {
       var v = 10000;
-
       if (val < 0.000001 && val > 0 || val > -0.000001 && val < 0) {
         return _rnd(val * v) / v;
       }
-
       return val;
     }
-
     function to2dCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
       var props = this.props;
-
       var _a = roundMatrixProperty(props[0]);
-
       var _b = roundMatrixProperty(props[1]);
-
       var _c = roundMatrixProperty(props[4]);
-
       var _d = roundMatrixProperty(props[5]);
-
       var _e = roundMatrixProperty(props[12]);
-
       var _f = roundMatrixProperty(props[13]);
-
       return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
     }
-
     return function () {
       this.reset = reset;
       this.rotate = rotate;
@@ -5159,16 +4339,14 @@
     };
   }();
 
-  function _typeof$3(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$3 = function _typeof(obj) { return typeof obj; }; } else { _typeof$3 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$3(obj); }
+  function _typeof$3(o) { "@babel/helpers - typeof"; return _typeof$3 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$3(o); }
   var lottie = {};
   var standalone = '__[STANDALONE]__';
   var animationData = '__[ANIMATIONDATA]__';
   var renderer = '';
-
   function setLocation(href) {
     setLocationHref(href);
   }
-
   function searchAnimations() {
     if (standalone === true) {
       animationManager.searchAnimations(animationData, standalone, renderer);
@@ -5176,35 +4354,28 @@
       animationManager.searchAnimations();
     }
   }
-
   function setSubframeRendering(flag) {
     setSubframeEnabled(flag);
   }
-
   function setPrefix(prefix) {
     setIdPrefix(prefix);
   }
-
   function loadAnimation(params) {
     if (standalone === true) {
       params.animationData = JSON.parse(animationData);
     }
-
     return animationManager.loadAnimation(params);
   }
-
   function setQuality(value) {
     if (typeof value === 'string') {
       switch (value) {
         case 'high':
           setDefaultCurveSegments(200);
           break;
-
         default:
         case 'medium':
           setDefaultCurveSegments(50);
           break;
-
         case 'low':
           setDefaultCurveSegments(10);
           break;
@@ -5212,40 +4383,32 @@
     } else if (!isNaN(value) && value > 1) {
       setDefaultCurveSegments(value);
     }
-
     if (getDefaultCurveSegments() >= 50) {
       roundValues(false);
     } else {
       roundValues(true);
     }
   }
-
   function inBrowser() {
     return typeof navigator !== 'undefined';
   }
-
   function installPlugin(type, plugin) {
     if (type === 'expressions') {
       setExpressionsPlugin(plugin);
     }
   }
-
   function getFactory(name) {
     switch (name) {
       case 'propertyFactory':
         return PropertyFactory;
-
       case 'shapePropertyFactory':
         return ShapePropertyFactory;
-
       case 'matrix':
         return Matrix;
-
       default:
         return null;
     }
   }
-
   lottie.play = animationManager.play;
   lottie.pause = animationManager.pause;
   lottie.setLocationHref = setLocation;
@@ -5257,8 +4420,8 @@
   lottie.registerAnimation = animationManager.registerAnimation;
   lottie.loadAnimation = loadAnimation;
   lottie.setSubframeRendering = setSubframeRendering;
-  lottie.resize = animationManager.resize; // lottie.start = start;
-
+  lottie.resize = animationManager.resize;
+  // lottie.start = start;
   lottie.goToAndStop = animationManager.goToAndStop;
   lottie.destroy = animationManager.destroy;
   lottie.setQuality = setQuality;
@@ -5273,32 +4436,25 @@
   lottie.useWebWorker = setWebWorker;
   lottie.setIDPrefix = setPrefix;
   lottie.__getFactory = getFactory;
-  lottie.version = '5.12.2';
-
+  lottie.version = '5.13.0';
   function checkReady() {
     if (document.readyState === 'complete') {
       clearInterval(readyStateCheckInterval);
       searchAnimations();
     }
   }
-
   function getQueryVariable(variable) {
     var vars = queryString.split('&');
-
     for (var i = 0; i < vars.length; i += 1) {
       var pair = vars[i].split('=');
-
       if (decodeURIComponent(pair[0]) == variable) {
         // eslint-disable-line eqeqeq
         return decodeURIComponent(pair[1]);
       }
     }
-
     return null;
   }
-
   var queryString = '';
-
   if (standalone) {
     var scripts = document.getElementsByTagName('script');
     var index = scripts.length - 1;
@@ -5306,18 +4462,18 @@
       src: ''
     };
     queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
-
     renderer = getQueryVariable('renderer');
   }
+  var readyStateCheckInterval = setInterval(checkReady, 100);
 
-  var readyStateCheckInterval = setInterval(checkReady, 100); // this adds bodymovin to the window object for backwards compatibility
-
+  // this adds bodymovin to the window object for backwards compatibility
   try {
     if (!((typeof exports === "undefined" ? "undefined" : _typeof$3(exports)) === 'object' && typeof module !== 'undefined') && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
     ) {
       window.bodymovin = lottie;
     }
-  } catch (err) {//
+  } catch (err) {
+    //
   }
 
   var ShapeModifiers = function () {
@@ -5325,26 +4481,19 @@
     var modifiers = {};
     ob.registerModifier = registerModifier;
     ob.getModifier = getModifier;
-
     function registerModifier(nm, factory) {
       if (!modifiers[nm]) {
         modifiers[nm] = factory;
       }
     }
-
     function getModifier(nm, elem, data) {
       return new modifiers[nm](elem, data);
     }
-
     return ob;
   }();
-
   function ShapeModifier() {}
-
   ShapeModifier.prototype.initModifierProperties = function () {};
-
   ShapeModifier.prototype.addShapeToModifier = function () {};
-
   ShapeModifier.prototype.addShape = function (data) {
     if (!this.closed) {
       // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
@@ -5356,13 +4505,11 @@
       };
       this.shapes.push(shapeData);
       this.addShapeToModifier(shapeData);
-
       if (this._isAnimated) {
         data.setAsAnimated();
       }
     }
   };
-
   ShapeModifier.prototype.init = function (elem, data) {
     this.shapes = [];
     this.elem = elem;
@@ -5371,29 +4518,23 @@
     this.frameId = initialDefaultFrame;
     this.closed = false;
     this.k = false;
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   ShapeModifier.prototype.processKeys = function () {
     if (this.elem.globalData.frameId === this.frameId) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   extendPrototype([DynamicPropertyContainer], ShapeModifier);
 
   function TrimModifier() {}
-
   extendPrototype([ShapeModifier], TrimModifier);
-
   TrimModifier.prototype.initModifierProperties = function (elem, data) {
     this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
     this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
@@ -5404,14 +4545,11 @@
     this.m = data.m;
     this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
   };
-
   TrimModifier.prototype.addShapeToModifier = function (shapeData) {
     shapeData.pathsData = [];
   };
-
   TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
     var segments = [];
-
     if (e <= 1) {
       segments.push({
         s: s,
@@ -5432,65 +4570,50 @@
         e: e - 1
       });
     }
-
     var shapeSegments = [];
     var i;
     var len = segments.length;
     var segmentOb;
-
     for (i = 0; i < len; i += 1) {
       segmentOb = segments[i];
-
       if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
         var shapeS;
         var shapeE;
-
         if (segmentOb.s * totalModifierLength <= addedLength) {
           shapeS = 0;
         } else {
           shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
         }
-
         if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
           shapeE = 1;
         } else {
           shapeE = (segmentOb.e * totalModifierLength - addedLength) / shapeLength;
         }
-
         shapeSegments.push([shapeS, shapeE]);
       }
     }
-
     if (!shapeSegments.length) {
       shapeSegments.push([0, 0]);
     }
-
     return shapeSegments;
   };
-
   TrimModifier.prototype.releasePathsData = function (pathsData) {
     var i;
     var len = pathsData.length;
-
     for (i = 0; i < len; i += 1) {
       segmentsLengthPool.release(pathsData[i]);
     }
-
     pathsData.length = 0;
     return pathsData;
   };
-
   TrimModifier.prototype.processShapes = function (_isFirstFrame) {
     var s;
     var e;
-
     if (this._mdf || _isFirstFrame) {
       var o = this.o.v % 360 / 360;
-
       if (o < 0) {
         o += 1;
       }
-
       if (this.s.v > 1) {
         s = 1 + o;
       } else if (this.s.v < 0) {
@@ -5498,7 +4621,6 @@
       } else {
         s = this.s.v + o;
       }
-
       if (this.e.v > 1) {
         e = 1 + o;
       } else if (this.e.v < 0) {
@@ -5506,13 +4628,11 @@
       } else {
         e = this.e.v + o;
       }
-
       if (s > e) {
         var _s = s;
         s = e;
         e = _s;
       }
-
       s = Math.round(s * 10000) * 0.0001;
       e = Math.round(e * 10000) * 0.0001;
       this.sValue = s;
@@ -5521,7 +4641,6 @@
       s = this.sValue;
       e = this.eValue;
     }
-
     var shapePaths;
     var i;
     var len = this.shapes.length;
@@ -5531,13 +4650,11 @@
     var pathData;
     var totalShapeLength;
     var totalModifierLength = 0;
-
     if (e === s) {
       for (i = 0; i < len; i += 1) {
         this.shapes[i].localShapeCollection.releaseShapes();
         this.shapes[i].shape._mdf = true;
         this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
-
         if (this._mdf) {
           this.shapes[i].pathsData.length = 0;
         }
@@ -5546,63 +4663,52 @@
       var segments = [];
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
-        shapeData = this.shapes[i]; // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
-
+        shapeData = this.shapes[i];
+        // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
         if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
           shapeData.shape.paths = shapeData.localShapeCollection;
         } else {
           shapePaths = shapeData.shape.paths;
           jLen = shapePaths._length;
           totalShapeLength = 0;
-
           if (!shapeData.shape._mdf && shapeData.pathsData.length) {
             totalShapeLength = shapeData.totalShapeLength;
           } else {
             pathsData = this.releasePathsData(shapeData.pathsData);
-
             for (j = 0; j < jLen; j += 1) {
               pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
               pathsData.push(pathData);
               totalShapeLength += pathData.totalLength;
             }
-
             shapeData.totalShapeLength = totalShapeLength;
             shapeData.pathsData = pathsData;
           }
-
           totalModifierLength += totalShapeLength;
           shapeData.shape._mdf = true;
         }
       }
-
       var shapeS = s;
       var shapeE = e;
       var addedLength = 0;
       var edges;
-
       for (i = len - 1; i >= 0; i -= 1) {
         shapeData = this.shapes[i];
-
         if (shapeData.shape._mdf) {
           localShapeCollection = shapeData.localShapeCollection;
-          localShapeCollection.releaseShapes(); // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
-
+          localShapeCollection.releaseShapes();
+          // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
           if (this.m === 2 && len > 1) {
             edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
             addedLength += shapeData.totalShapeLength;
           } else {
             edges = [[shapeS, shapeE]];
           }
-
           jLen = edges.length;
-
           for (j = 0; j < jLen; j += 1) {
             shapeS = edges[j][0];
             shapeE = edges[j][1];
             segments.length = 0;
-
             if (shapeE <= 1) {
               segments.push({
                 s: shapeData.totalShapeLength * shapeS,
@@ -5623,13 +4729,10 @@
                 e: shapeData.totalShapeLength * (shapeE - 1)
               });
             }
-
             var newShapesData = this.addShapes(shapeData, segments[0]);
-
             if (segments[0].s !== segments[0].e) {
               if (segments.length > 1) {
                 var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
-
                 if (lastShapeInCollection.c) {
                   var lastShape = newShapesData.pop();
                   this.addPaths(newShapesData, localShapeCollection);
@@ -5639,11 +4742,9 @@
                   newShapesData = this.addShapes(shapeData, segments[1]);
                 }
               }
-
               this.addPaths(newShapesData, localShapeCollection);
             }
           }
-
           shapeData.shape.paths = localShapeCollection;
         }
       }
@@ -5656,38 +4757,29 @@
       }
     }
   };
-
   TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
     var i;
     var len = newPaths.length;
-
     for (i = 0; i < len; i += 1) {
       localShapeCollection.addShape(newPaths[i]);
     }
   };
-
   TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
     shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
     shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
     }
-
     shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
     shapePath.setXYAt(points[1], points[5], 'o', pos);
     shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(points[0], points[4], 'v', pos);
     }
-
     shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
     var pathsData = shapeData.pathsData;
     var shapePaths = shapeData.shape.paths.shapes;
@@ -5703,7 +4795,6 @@
     var shapes = [];
     var initPos;
     var newShape = true;
-
     if (!shapePath) {
       shapePath = shapePool.newElement();
       segmentCount = 0;
@@ -5712,17 +4803,13 @@
       segmentCount = shapePath._length;
       initPos = shapePath._length;
     }
-
     shapes.push(shapePath);
-
     for (i = 0; i < len; i += 1) {
       lengths = pathsData[i].lengths;
       shapePath.c = shapePaths[i].c;
       jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
-
       for (j = 1; j < jLen; j += 1) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
           addedLength += currentLengthData.addedLength;
           shapePath.c = false;
@@ -5735,50 +4822,42 @@
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
-
           addedLength += currentLengthData.addedLength;
           segmentCount += 1;
         }
       }
-
       if (shapePaths[i].c && lengths.length) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength <= shapeSegment.e) {
           var segmentLength = lengths[j - 1].addedLength;
-
           if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
             this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
         } else {
           shapePath.c = false;
         }
-
         addedLength += currentLengthData.addedLength;
         segmentCount += 1;
       }
-
       if (shapePath._length) {
         shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
         shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
       }
-
       if (addedLength > shapeSegment.e) {
         break;
       }
-
       if (i < len - 1) {
         shapePath = shapePool.newElement();
         newShape = true;
@@ -5786,31 +4865,25 @@
         segmentCount = 0;
       }
     }
-
     return shapes;
   };
 
   function PuckerAndBloatModifier() {}
-
   extendPrototype([ShapeModifier], PuckerAndBloatModifier);
-
   PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
     this._isAnimated = !!this.amount.effectsSequence.length;
   };
-
   PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
     var percent = amount / 100;
     var centerPoint = [0, 0];
     var pathLength = path._length;
     var i = 0;
-
     for (i = 0; i < pathLength; i += 1) {
       centerPoint[0] += path.v[i][0];
       centerPoint[1] += path.v[i][1];
     }
-
     centerPoint[0] /= pathLength;
     centerPoint[1] /= pathLength;
     var clonedPath = shapePool.newElement();
@@ -5821,7 +4894,6 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < pathLength; i += 1) {
       vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
       vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
@@ -5831,10 +4903,8 @@
       iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
       clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
     }
-
     return clonedPath;
   };
-
   PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -5842,30 +4912,24 @@
     var j;
     var jLen;
     var amount = this.amount.v;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -5873,30 +4937,24 @@
 
   var TransformPropertyFactory = function () {
     var defaultVector = [0, 0];
-
     function applyToMatrix(mat) {
       var _mdf = this._mdf;
       this.iterateDynamicProperties();
       this._mdf = this._mdf || _mdf;
-
       if (this.a) {
         mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
       }
-
       if (this.s) {
         mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
       }
-
       if (this.sk) {
         mat.skewFromAxis(-this.sk.v, this.sa.v);
       }
-
       if (this.r) {
         mat.rotate(-this.r.v);
       } else {
         mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
       }
-
       if (this.data.p.s) {
         if (this.data.p.z) {
           mat.translate(this.px.v, this.py.v, -this.pz.v);
@@ -5907,46 +4965,36 @@
         mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
       }
     }
-
     function processKeys(forceRender) {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (this._isDirty) {
         this.precalculateMatrix();
         this._isDirty = false;
       }
-
       this.iterateDynamicProperties();
-
       if (this._mdf || forceRender) {
         var frameRate;
         this.v.cloneFromProps(this.pre.props);
-
         if (this.appliedTransformations < 1) {
           this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         }
-
         if (this.appliedTransformations < 2) {
           this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         }
-
         if (this.sk && this.appliedTransformations < 3) {
           this.v.skewFromAxis(-this.sk.v, this.sa.v);
         }
-
         if (this.r && this.appliedTransformations < 4) {
           this.v.rotate(-this.r.v);
         } else if (!this.r && this.appliedTransformations < 4) {
           this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
         }
-
         if (this.autoOriented) {
           var v1;
           var v2;
           frameRate = this.elem.globalData.frameRate;
-
           if (this.p && this.p.keyframes && this.p.getValueAtTime) {
             if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
               v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
@@ -5963,7 +5011,6 @@
             v2 = [];
             var px = this.px;
             var py = this.py;
-
             if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
               v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
               v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
@@ -5983,10 +5030,8 @@
             v2 = defaultVector;
             v1 = v2;
           }
-
           this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
         }
-
         if (this.data.p && this.data.p.s) {
           if (this.data.p.z) {
             this.v.translate(this.px.v, this.py.v, -this.pz.v);
@@ -5997,28 +5042,23 @@
           this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
         }
       }
-
       this.frameId = this.elem.globalData.frameId;
     }
-
     function precalculateMatrix() {
       this.appliedTransformations = 0;
       this.pre.reset();
-
       if (!this.a.effectsSequence.length) {
         this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         this.appliedTransformations = 1;
       } else {
         return;
       }
-
       if (!this.s.effectsSequence.length) {
         this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         this.appliedTransformations = 2;
       } else {
         return;
       }
-
       if (this.sk) {
         if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
           this.pre.skewFromAxis(-this.sk.v, this.sa.v);
@@ -6027,7 +5067,6 @@
           return;
         }
       }
-
       if (this.r) {
         if (!this.r.effectsSequence.length) {
           this.pre.rotate(-this.r.v);
@@ -6038,33 +5077,28 @@
         this.appliedTransformations = 4;
       }
     }
-
-    function autoOrient() {//
+    function autoOrient() {
+      //
       // var prevP = this.getValueAtTime();
     }
-
     function addDynamicProperty(prop) {
       this._addDynamicProperty(prop);
-
       this.elem.addDynamicProperty(prop);
       this._isDirty = true;
     }
-
     function TransformProperty(elem, data, container) {
       this.elem = elem;
       this.frameId = -1;
       this.propType = 'transform';
       this.data = data;
-      this.v = new Matrix(); // Precalculated matrix with non animated properties
-
+      this.v = new Matrix();
+      // Precalculated matrix with non animated properties
       this.pre = new Matrix();
       this.appliedTransformations = 0;
       this.initDynamicPropertyContainer(container || elem);
-
       if (data.p && data.p.s) {
         this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
         this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
-
         if (data.p.z) {
           this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
         }
@@ -6073,43 +5107,37 @@
           k: [0, 0, 0]
         }, 1, 0, this);
       }
-
       if (data.rx) {
         this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
         this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
         this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
-
         if (data.or.k[0].ti) {
           var i;
           var len = data.or.k.length;
-
           for (i = 0; i < len; i += 1) {
             data.or.k[i].to = null;
             data.or.k[i].ti = null;
           }
         }
-
-        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this); // sh Indicates it needs to be capped between -180 and 180
-
+        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+        // sh Indicates it needs to be capped between -180 and 180
         this.or.sh = true;
       } else {
         this.r = PropertyFactory.getProp(elem, data.r || {
           k: 0
         }, 0, degToRads, this);
       }
-
       if (data.sk) {
         this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
         this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
       }
-
       this.a = PropertyFactory.getProp(elem, data.a || {
         k: [0, 0, 0]
       }, 1, 0, this);
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: [100, 100, 100]
-      }, 1, 0.01, this); // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
-
+      }, 1, 0.01, this);
+      // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
       if (data.o) {
         this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
       } else {
@@ -6118,14 +5146,11 @@
           v: 1
         };
       }
-
       this._isDirty = true;
-
       if (!this.dynamicProperties.length) {
         this.getValue(true);
       }
     }
-
     TransformProperty.prototype = {
       applyToMatrix: applyToMatrix,
       getValue: processKeys,
@@ -6135,20 +5160,16 @@
     extendPrototype([DynamicPropertyContainer], TransformProperty);
     TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
     TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
-
     function getTransformProperty(elem, data, container) {
       return new TransformProperty(elem, data, container);
     }
-
     return {
       getTransformProperty: getTransformProperty
     };
   }();
 
   function RepeaterModifier() {}
-
   extendPrototype([ShapeModifier], RepeaterModifier);
-
   RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
@@ -6157,11 +5178,9 @@
     this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
     this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
     this.data = data;
-
     if (!this.dynamicProperties.length) {
       this.getValue(true);
     }
-
     this._isAnimated = !!this.dynamicProperties.length;
     this.pMatrix = new Matrix();
     this.rMatrix = new Matrix();
@@ -6169,7 +5188,6 @@
     this.tMatrix = new Matrix();
     this.matrix = new Matrix();
   };
-
   RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
     var dir = inv ? -1 : 1;
     var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
@@ -6182,7 +5200,6 @@
     sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
     sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
   };
-
   RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
     this.elem = elem;
     this.arr = arr;
@@ -6194,52 +5211,42 @@
     this.frameId = -1;
     this.initDynamicPropertyContainer(elem);
     this.initModifierProperties(elem, arr[pos]);
-
     while (pos > 0) {
-      pos -= 1; // this._elements.unshift(arr.splice(pos,1)[0]);
-
+      pos -= 1;
+      // this._elements.unshift(arr.splice(pos,1)[0]);
       this._elements.unshift(arr[pos]);
     }
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   RepeaterModifier.prototype.resetElements = function (elements) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._processed = false;
-
       if (elements[i].ty === 'gr') {
         this.resetElements(elements[i].it);
       }
     }
   };
-
   RepeaterModifier.prototype.cloneElements = function (elements) {
     var newElements = JSON.parse(JSON.stringify(elements));
     this.resetElements(newElements);
     return newElements;
   };
-
   RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._render = renderFlag;
-
       if (elements[i].ty === 'gr') {
         this.changeGroupRender(elements[i].it, renderFlag);
       }
     }
   };
-
   RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
     var items;
     var itemsTransform;
@@ -6247,10 +5254,8 @@
     var dir;
     var cont;
     var hasReloaded = false;
-
     if (this._mdf || _isFirstFrame) {
       var copies = Math.ceil(this.c.v);
-
       if (this._groups.length < copies) {
         while (this._groups.length < copies) {
           var group = {
@@ -6305,28 +5310,21 @@
             ty: 'tr'
           });
           this.arr.splice(0, 0, group);
-
           this._groups.splice(0, 0, group);
-
           this._currentCopies += 1;
         }
-
         this.elem.reloadShapes();
         hasReloaded = true;
       }
-
       cont = 0;
       var renderFlag;
-
       for (i = 0; i <= this._groups.length - 1; i += 1) {
         renderFlag = cont < copies;
         this._groups[i]._render = renderFlag;
         this.changeGroupRender(this._groups[i].it, renderFlag);
-
         if (!renderFlag) {
           var elems = this.elemsData[i].it;
           var transformData = elems[elems.length - 1];
-
           if (transformData.transform.op.v !== 0) {
             transformData.transform.op._mdf = true;
             transformData.transform.op.v = 0;
@@ -6334,11 +5332,10 @@
             transformData.transform.op._mdf = false;
           }
         }
-
         cont += 1;
       }
-
-      this._currentCopies = copies; /// /
+      this._currentCopies = copies;
+      /// /
 
       var offset = this.o.v;
       var offsetModulo = offset % 1;
@@ -6352,13 +5349,11 @@
       this.tMatrix.reset();
       this.matrix.reset();
       var iteration = 0;
-
       if (offset > 0) {
         while (iteration < roundOffset) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           iteration += 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
           iteration += offsetModulo;
@@ -6368,19 +5363,16 @@
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
           iteration -= 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
           iteration -= offsetModulo;
         }
       }
-
       i = this.data.m === 1 ? 0 : this._currentCopies - 1;
       dir = this.data.m === 1 ? 1 : -1;
       cont = this._currentCopies;
       var j;
       var jLen;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6388,29 +5380,23 @@
         items[items.length - 1].transform.mProps._mdf = true;
         items[items.length - 1].transform.op._mdf = true;
         items[items.length - 1].transform.op.v = this._currentCopies === 1 ? this.so.v : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
-
         if (iteration !== 0) {
           if (i !== 0 && dir === 1 || i !== this._currentCopies - 1 && dir === -1) {
             this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           }
-
           this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
           this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
           this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
-
           this.matrix.reset();
         } else {
           this.matrix.reset();
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
         }
-
         iteration += 1;
         cont -= 1;
         i += dir;
@@ -6419,7 +5405,6 @@
       cont = this._currentCopies;
       i = 0;
       dir = 1;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6429,22 +5414,17 @@
         i += dir;
       }
     }
-
     return hasReloaded;
   };
-
   RepeaterModifier.prototype.addShape = function () {};
 
   function RoundCornersModifier() {}
-
   extendPrototype([ShapeModifier], RoundCornersModifier);
-
   RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
     this._isAnimated = !!this.rd.effectsSequence.length;
   };
-
   RoundCornersModifier.prototype.processPath = function (path, round) {
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
@@ -6463,19 +5443,16 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < len; i += 1) {
       currentV = path.v[i];
       currentO = path.o[i];
       currentI = path.i[i];
-
       if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
         if ((i === 0 || i === len - 1) && !path.c) {
           clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
           /* clonedPath.v[index] = currentV;
                   clonedPath.o[index] = currentO;
                   clonedPath.i[index] = currentI; */
-
           index += 1;
         } else {
           if (i === 0) {
@@ -6483,7 +5460,6 @@
           } else {
             closerV = path.v[i - 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6494,13 +5470,11 @@
           oY = vY - (vY - currentV[1]) * roundCorner;
           clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
           index += 1;
-
           if (i === len - 1) {
             closerV = path.v[0];
           } else {
             closerV = path.v[i + 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6517,10 +5491,8 @@
         index += 1;
       }
     }
-
     return clonedPath;
   };
-
   RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6528,30 +5500,24 @@
     var j;
     var jLen;
     var rd = this.rd.v;
-
     if (rd !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6560,50 +5526,41 @@
   function floatEqual(a, b) {
     return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
   }
-
   function floatZero(f) {
     return Math.abs(f) <= 0.00001;
   }
-
   function lerp(p0, p1, amount) {
     return p0 * (1 - amount) + p1 * amount;
   }
-
   function lerpPoint(p0, p1, amount) {
     return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
   }
-
   function quadRoots(a, b, c) {
     // no root
     if (a === 0) return [];
-    var s = b * b - 4 * a * c; // Complex roots
-
+    var s = b * b - 4 * a * c;
+    // Complex roots
     if (s < 0) return [];
-    var singleRoot = -b / (2 * a); // 1 root
-
+    var singleRoot = -b / (2 * a);
+    // 1 root
     if (s === 0) return [singleRoot];
-    var delta = Math.sqrt(s) / (2 * a); // 2 roots
-
+    var delta = Math.sqrt(s) / (2 * a);
+    // 2 roots
     return [singleRoot - delta, singleRoot + delta];
   }
-
   function polynomialCoefficients(p0, p1, p2, p3) {
     return [-p0 + 3 * p1 - 3 * p2 + p3, 3 * p0 - 6 * p1 + 3 * p2, -3 * p0 + 3 * p1, p0];
   }
-
   function singlePoint(p) {
     return new PolynomialBezier(p, p, p, p, false);
   }
-
   function PolynomialBezier(p0, p1, p2, p3, linearize) {
     if (linearize && pointEqual(p0, p1)) {
       p1 = lerpPoint(p0, p3, 1 / 3);
     }
-
     if (linearize && pointEqual(p2, p3)) {
       p2 = lerpPoint(p0, p3, 2 / 3);
     }
-
     var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
     var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
     this.a = [coeffx[0], coeffy[0]];
@@ -6612,25 +5569,20 @@
     this.d = [coeffx[3], coeffy[3]];
     this.points = [p0, p1, p2, p3];
   }
-
   PolynomialBezier.prototype.point = function (t) {
     return [((this.a[0] * t + this.b[0]) * t + this.c[0]) * t + this.d[0], ((this.a[1] * t + this.b[1]) * t + this.c[1]) * t + this.d[1]];
   };
-
   PolynomialBezier.prototype.derivative = function (t) {
     return [(3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0], (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1]];
   };
-
   PolynomialBezier.prototype.tangentAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[1], p[0]);
   };
-
   PolynomialBezier.prototype.normalAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[0], p[1]);
   };
-
   PolynomialBezier.prototype.inflectionPoints = function () {
     var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
     if (floatZero(denom)) return [];
@@ -6638,17 +5590,14 @@
     var square = tcusp * tcusp - 1 / 3 * (this.b[1] * this.c[0] - this.b[0] * this.c[1]) / denom;
     if (square < 0) return [];
     var root = Math.sqrt(square);
-
     if (floatZero(root)) {
       if (root > 0 && root < 1) return [tcusp];
       return [];
     }
-
     return [tcusp - root, tcusp + root].filter(function (r) {
       return r > 0 && r < 1;
     });
   };
-
   PolynomialBezier.prototype.split = function (t) {
     if (t <= 0) return [singlePoint(this.points[0]), this];
     if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
@@ -6660,40 +5609,33 @@
     var p3 = lerpPoint(p20, p21, t);
     return [new PolynomialBezier(this.points[0], p10, p20, p3, true), new PolynomialBezier(p3, p21, p12, this.points[3], true)];
   };
-
   function extrema(bez, comp) {
     var min = bez.points[0][comp];
     var max = bez.points[bez.points.length - 1][comp];
-
     if (min > max) {
       var e = max;
       max = min;
       min = e;
-    } // Derivative roots to find min/max
-
-
+    }
+    // Derivative roots to find min/max
     var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
-
     for (var i = 0; i < f.length; i += 1) {
       if (f[i] > 0 && f[i] < 1) {
         var val = bez.point(f[i])[comp];
         if (val < min) min = val;else if (val > max) max = val;
       }
     }
-
     return {
       min: min,
       max: max
     };
   }
-
   PolynomialBezier.prototype.bounds = function () {
     return {
       x: extrema(this, 0),
       y: extrema(this, 1)
     };
   };
-
   PolynomialBezier.prototype.boundingBox = function () {
     var bounds = this.bounds();
     return {
@@ -6707,7 +5649,6 @@
       cy: (bounds.y.max + bounds.y.min) / 2
     };
   };
-
   function intersectData(bez, t1, t2) {
     var box = bez.boundingBox();
     return {
@@ -6721,24 +5662,19 @@
       t2: t2
     };
   }
-
   function splitData(data) {
     var split = data.bez.split(0.5);
     return [intersectData(split[0], data.t1, data.t), intersectData(split[1], data.t, data.t2)];
   }
-
   function boxIntersect(b1, b2) {
     return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
   }
-
   function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
     if (!boxIntersect(d1, d2)) return;
-
     if (depth >= maxRecursion || d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance) {
       intersections.push([d1.t, d2.t]);
       return;
     }
-
     var d1s = splitData(d1);
     var d2s = splitData(d2);
     intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
@@ -6746,7 +5682,6 @@
     intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
     intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
   }
-
   PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
     if (tolerance === undefined) tolerance = 2;
     if (maxRecursion === undefined) maxRecursion = 7;
@@ -6754,21 +5689,17 @@
     intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
     return intersections;
   };
-
   PolynomialBezier.shapeSegment = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
   };
-
   PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
   };
-
   function crossProduct(a, b) {
     return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
   }
-
   function lineIntersection(start1, end1, start2, end2) {
     var v1 = [start1[0], start1[1], 1];
     var v2 = [end1[0], end1[1], 1];
@@ -6778,23 +5709,18 @@
     if (floatZero(r[2])) return null;
     return [r[0] / r[2], r[1] / r[2]];
   }
-
   function polarOffset(p, angle, length) {
     return [p[0] + Math.cos(angle) * length, p[1] - Math.sin(angle) * length];
   }
-
   function pointDistance(p1, p2) {
     return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
   }
-
   function pointEqual(p1, p2) {
     return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
   }
 
   function ZigZagModifier() {}
-
   extendPrototype([ShapeModifier], ZigZagModifier);
-
   ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
@@ -6802,7 +5728,6 @@
     this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
     this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
   };
-
   function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
     var angO = angle - Math.PI / 2;
     var angI = angle + Math.PI / 2;
@@ -6810,14 +5735,12 @@
     var py = point[1] - Math.sin(angle) * direction * amplitude;
     outputBezier.setTripleAt(px, py, px + Math.cos(angO) * outAmplitude, py - Math.sin(angO) * outAmplitude, px + Math.cos(angI) * inAmplitude, py - Math.sin(angI) * inAmplitude, outputBezier.length());
   }
-
   function getPerpendicularVector(pt1, pt2) {
     var vector = [pt2[0] - pt1[0], pt2[1] - pt1[1]];
     var rot = -Math.PI * 0.5;
     var rotatedVector = [Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1], Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1]];
     return rotatedVector;
   }
-
   function getProjectingAngle(path, cur) {
     var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
     var nextIndex = (cur + 1) % path.length();
@@ -6826,7 +5749,6 @@
     var pVector = getPerpendicularVector(prevPoint, nextPoint);
     return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
   }
-
   function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
     var angle = getProjectingAngle(path, cur);
     var point = path.v[cur % path._length];
@@ -6836,7 +5758,6 @@
     var nextDist = pointType === 2 ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2)) : 0;
     setPoint(outputBezier, path.v[cur % path._length], angle, direction, amplitude, nextDist / ((frequency + 1) * 2), prevDist / ((frequency + 1) * 2), pointType);
   }
-
   function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
     for (var i = 0; i < frequency; i += 1) {
       var t = (i + 1) / (frequency + 1);
@@ -6846,39 +5767,30 @@
       setPoint(outputBezier, point, angle, direction, amplitude, dist / ((frequency + 1) * 2), dist / ((frequency + 1) * 2), pointType);
       direction = -direction;
     }
-
     return direction;
   }
-
   ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
     var count = path._length;
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
-
     if (!path.c) {
       count -= 1;
     }
-
     if (count === 0) return clonedPath;
     var direction = -1;
     var segment = PolynomialBezier.shapeSegment(path, 0);
     zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
-
     for (var i = 0; i < count; i += 1) {
       direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
-
       if (i === count - 1 && !path.c) {
         segment = null;
       } else {
         segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
       }
-
       zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
     }
-
     return clonedPath;
   };
-
   ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6888,30 +5800,24 @@
     var amplitude = this.amplitude.v;
     var frequency = Math.max(0, Math.round(this.frequency.v));
     var pointType = this.pointsType.v;
-
     if (amplitude !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6921,7 +5827,6 @@
     var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
     return [polarOffset(p1, angle, amount), polarOffset(p2, angle, amount)];
   }
-
   function offsetSegment(segment, amount) {
     var p0;
     var p1a;
@@ -6945,15 +5850,17 @@
     if (p2 === null) p2 = p2a;
     return new PolynomialBezier(p0, p1, p2, p3);
   }
-
   function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
     var p0 = seg1.points[3];
-    var p1 = seg2.points[0]; // Bevel
+    var p1 = seg2.points[0];
 
-    if (lineJoin === 3) return p0; // Connected, they don't need a joint
+    // Bevel
+    if (lineJoin === 3) return p0;
 
-    if (pointEqual(p0, p1)) return p0; // Round
+    // Connected, they don't need a joint
+    if (pointEqual(p0, p1)) return p0;
 
+    // Round
     if (lineJoin === 2) {
       var angleOut = -seg1.tangentAngle(1);
       var angleIn = -seg2.tangentAngle(0) + Math.PI;
@@ -6964,91 +5871,75 @@
       tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
       outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
       return p1;
-    } // Miter
+    }
 
-
+    // Miter
     var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
     var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
     var intersection = lineIntersection(t0, p0, p1, t1);
-
     if (intersection && pointDistance(intersection, p0) < miterLimit) {
       outputBezier.setTripleAt(intersection[0], intersection[1], intersection[0], intersection[1], intersection[0], intersection[1], outputBezier.length());
       return intersection;
     }
-
     return p0;
   }
-
   function getIntersection(a, b) {
     var intersect = a.intersections(b);
     if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
     if (intersect.length) return intersect[0];
     return null;
   }
-
   function pruneSegmentIntersection(a, b) {
     var outa = a.slice();
     var outb = b.slice();
     var intersect = getIntersection(a[a.length - 1], b[0]);
-
     if (intersect) {
       outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
       outb[0] = b[0].split(intersect[1])[1];
     }
-
     if (a.length > 1 && b.length > 1) {
       intersect = getIntersection(a[0], b[b.length - 1]);
-
       if (intersect) {
         return [[a[0].split(intersect[0])[0]], [b[b.length - 1].split(intersect[1])[1]]];
       }
     }
-
     return [outa, outb];
   }
-
   function pruneIntersections(segments) {
     var e;
-
     for (var i = 1; i < segments.length; i += 1) {
       e = pruneSegmentIntersection(segments[i - 1], segments[i]);
       segments[i - 1] = e[0];
       segments[i] = e[1];
     }
-
     if (segments.length > 1) {
       e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
       segments[segments.length - 1] = e[0];
       segments[0] = e[1];
     }
-
     return segments;
   }
-
   function offsetSegmentSplit(segment, amount) {
     /*
       We split each bezier segment into smaller pieces based
       on inflection points, this ensures the control point
       polygon is convex.
-        (A cubic bezier can have none, one, or two inflection points)
+       (A cubic bezier can have none, one, or two inflection points)
     */
     var flex = segment.inflectionPoints();
     var left;
     var right;
     var split;
     var mid;
-
     if (flex.length === 0) {
       return [offsetSegment(segment, amount)];
     }
-
     if (flex.length === 1 || floatEqual(flex[1], 1)) {
       split = segment.split(flex[0]);
       left = split[0];
       right = split[1];
       return [offsetSegment(left, amount), offsetSegment(right, amount)];
     }
-
     split = segment.split(flex[0]);
     left = split[0];
     var t = (flex[1] - flex[0]) / (1 - flex[0]);
@@ -7057,11 +5948,8 @@
     right = split[1];
     return [offsetSegment(left, amount), offsetSegment(mid, amount), offsetSegment(right, amount)];
   }
-
   function OffsetPathModifier() {}
-
   extendPrototype([ShapeModifier], OffsetPathModifier);
-
   OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
@@ -7069,61 +5957,50 @@
     this.lineJoin = data.lj;
     this._isAnimated = this.amount.effectsSequence.length !== 0;
   };
-
   OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
     var outputBezier = shapePool.newElement();
     outputBezier.c = inputBezier.c;
     var count = inputBezier.length();
-
     if (!inputBezier.c) {
       count -= 1;
     }
-
     var i;
     var j;
     var segment;
     var multiSegments = [];
-
     for (i = 0; i < count; i += 1) {
       segment = PolynomialBezier.shapeSegment(inputBezier, i);
       multiSegments.push(offsetSegmentSplit(segment, amount));
     }
-
     if (!inputBezier.c) {
       for (i = count - 1; i >= 0; i -= 1) {
         segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
         multiSegments.push(offsetSegmentSplit(segment, amount));
       }
     }
+    multiSegments = pruneIntersections(multiSegments);
 
-    multiSegments = pruneIntersections(multiSegments); // Add bezier segments to the output and apply line joints
-
+    // Add bezier segments to the output and apply line joints
     var lastPoint = null;
     var lastSeg = null;
-
     for (i = 0; i < multiSegments.length; i += 1) {
       var multiSegment = multiSegments[i];
       if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
       lastSeg = multiSegment[multiSegment.length - 1];
-
       for (j = 0; j < multiSegment.length; j += 1) {
         segment = multiSegment[j];
-
         if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
           outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
         } else {
           outputBezier.setTripleAt(segment.points[0][0], segment.points[0][1], segment.points[1][0], segment.points[1][1], segment.points[0][0], segment.points[0][1], outputBezier.length());
         }
-
         outputBezier.setTripleAt(segment.points[3][0], segment.points[3][1], segment.points[3][0], segment.points[3][1], segment.points[2][0], segment.points[2][1], outputBezier.length());
         lastPoint = segment.points[3];
       }
     }
-
     if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
     return outputBezier;
   };
-
   OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -7133,30 +6010,24 @@
     var amount = this.amount.v;
     var miterLimit = this.miterLimit.v;
     var lineJoin = this.lineJoin;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -7168,42 +6039,33 @@
     var fStyle = 'normal';
     var len = styles.length;
     var styleName;
-
     for (var i = 0; i < len; i += 1) {
       styleName = styles[i].toLowerCase();
-
       switch (styleName) {
         case 'italic':
           fStyle = 'italic';
           break;
-
         case 'bold':
           fWeight = '700';
           break;
-
         case 'black':
           fWeight = '900';
           break;
-
         case 'medium':
           fWeight = '500';
           break;
-
         case 'regular':
         case 'normal':
           fWeight = '400';
           break;
-
         case 'light':
         case 'thin':
           fWeight = '200';
           break;
-
         default:
           break;
       }
     }
-
     return {
       style: fStyle,
       weight: fontData.fWeight || fWeight
@@ -7220,8 +6082,8 @@
         shapes: []
       }
     };
-    var combinedCharacters = []; // Hindi characters
-
+    var combinedCharacters = [];
+    // Hindi characters
     combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
     var BLACK_FLAG_CODE_POINT = 127988;
     var CANCEL_TAG_CODE_POINT = 917631;
@@ -7232,44 +6094,41 @@
     var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
     var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
     var surrogateModifiers = ['d83cdffb', 'd83cdffc', 'd83cdffd', 'd83cdffe', 'd83cdfff'];
-
     function trimFontOptions(font) {
       var familyArray = font.split(',');
       var i;
       var len = familyArray.length;
       var enabledFamilies = [];
-
       for (i = 0; i < len; i += 1) {
         if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
           enabledFamilies.push(familyArray[i]);
         }
       }
-
       return enabledFamilies.join(',');
     }
-
     function setUpNode(font, family) {
-      var parentNode = createTag('span'); // Node is invisible to screen readers.
-
+      var parentNode = createTag('span');
+      // Node is invisible to screen readers.
       parentNode.setAttribute('aria-hidden', true);
       parentNode.style.fontFamily = family;
-      var node = createTag('span'); // Characters that vary significantly among different fonts
-
-      node.innerText = 'giItT1WQy@!-/#'; // Visible - so we can measure it - but not on the screen
-
+      var node = createTag('span');
+      // Characters that vary significantly among different fonts
+      node.innerText = 'giItT1WQy@!-/#';
+      // Visible - so we can measure it - but not on the screen
       parentNode.style.position = 'absolute';
       parentNode.style.left = '-10000px';
-      parentNode.style.top = '-10000px'; // Large font size makes even subtle changes obvious
-
-      parentNode.style.fontSize = '300px'; // Reset any font properties
-
+      parentNode.style.top = '-10000px';
+      // Large font size makes even subtle changes obvious
+      parentNode.style.fontSize = '300px';
+      // Reset any font properties
       parentNode.style.fontVariant = 'normal';
       parentNode.style.fontStyle = 'normal';
       parentNode.style.fontWeight = 'normal';
       parentNode.style.letterSpacing = '0';
       parentNode.appendChild(node);
-      document.body.appendChild(parentNode); // Remember width with no applied web font
+      document.body.appendChild(parentNode);
 
+      // Remember width with no applied web font
       var width = node.offsetWidth;
       node.style.fontFamily = trimFontOptions(font) + ', ' + family;
       return {
@@ -7278,14 +6137,12 @@
         parent: parentNode
       };
     }
-
     function checkLoadedFonts() {
       var i;
       var len = this.fonts.length;
       var node;
       var w;
       var loadedCount = len;
-
       for (i = 0; i < len; i += 1) {
         if (this.fonts[i].loaded) {
           loadedCount -= 1;
@@ -7294,55 +6151,47 @@
         } else {
           node = this.fonts[i].monoCase.node;
           w = this.fonts[i].monoCase.w;
-
           if (node.offsetWidth !== w) {
             loadedCount -= 1;
             this.fonts[i].loaded = true;
           } else {
             node = this.fonts[i].sansCase.node;
             w = this.fonts[i].sansCase.w;
-
             if (node.offsetWidth !== w) {
               loadedCount -= 1;
               this.fonts[i].loaded = true;
             }
           }
-
           if (this.fonts[i].loaded) {
             this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
             this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
           }
         }
       }
-
       if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
         setTimeout(this.checkLoadedFontsBinded, 20);
       } else {
         setTimeout(this.setIsLoadedBinded, 10);
       }
     }
-
     function createHelper(fontData, def) {
       var engine = document.body && def ? 'svg' : 'canvas';
       var helper;
       var fontProps = getFontProperties(fontData);
-
       if (engine === 'svg') {
         var tHelper = createNS('text');
-        tHelper.style.fontSize = '100px'; // tHelper.style.fontFamily = fontData.fFamily;
-
+        tHelper.style.fontSize = '100px';
+        // tHelper.style.fontFamily = fontData.fFamily;
         tHelper.setAttribute('font-family', fontData.fFamily);
         tHelper.setAttribute('font-style', fontProps.style);
         tHelper.setAttribute('font-weight', fontProps.weight);
         tHelper.textContent = '1';
-
         if (fontData.fClass) {
           tHelper.style.fontFamily = 'inherit';
           tHelper.setAttribute('class', fontData.fClass);
         } else {
           tHelper.style.fontFamily = fontData.fFamily;
         }
-
         def.appendChild(tHelper);
         helper = tHelper;
       } else {
@@ -7350,33 +6199,27 @@
         tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
         helper = tCanvasHelper;
       }
-
       function measure(text) {
         if (engine === 'svg') {
           helper.textContent = text;
           return helper.getComputedTextLength();
         }
-
         return helper.measureText(text).width;
       }
-
       return {
         measureText: measure
       };
     }
-
     function addFonts(fontData, defs) {
       if (!fontData) {
         this.isLoaded = true;
         return;
       }
-
       if (this.chars) {
         this.isLoaded = true;
         this.fonts = fontData.list;
         return;
       }
-
       if (!document.body) {
         this.isLoaded = true;
         fontData.list.forEach(function (data) {
@@ -7386,12 +6229,10 @@
         this.fonts = fontData.list;
         return;
       }
-
       var fontArr = fontData.list;
       var i;
       var len = fontArr.length;
       var _pendingFonts = len;
-
       for (i = 0; i < len; i += 1) {
         var shouldLoadFont = true;
         var loadedSelector;
@@ -7399,17 +6240,14 @@
         fontArr[i].loaded = false;
         fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
         fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
-
         if (!fontArr[i].fPath) {
           fontArr[i].loaded = true;
           _pendingFonts -= 1;
         } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
           loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
-
           if (loadedSelector.length > 0) {
             shouldLoadFont = false;
           }
-
           if (shouldLoadFont) {
             var s = createTag('style');
             s.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7421,14 +6259,12 @@
           }
         } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
           loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var l = createTag('link');
             l.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7440,14 +6276,12 @@
           }
         } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
           loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (fontArr[i].fPath === loadedSelector[j].src) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var sc = createTag('link');
             sc.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7457,12 +6291,10 @@
             defs.appendChild(sc);
           }
         }
-
         fontArr[i].helper = createHelper(fontArr[i], defs);
         fontArr[i].cache = {};
         this.fonts.push(fontArr[i]);
       }
-
       if (_pendingFonts === 0) {
         this.isLoaded = true;
       } else {
@@ -7471,71 +6303,56 @@
         setTimeout(this.checkLoadedFonts.bind(this), 100);
       }
     }
-
     function addChars(chars) {
       if (!chars) {
         return;
       }
-
       if (!this.chars) {
         this.chars = [];
       }
-
       var i;
       var len = chars.length;
       var j;
       var jLen = this.chars.length;
       var found;
-
       for (i = 0; i < len; i += 1) {
         j = 0;
         found = false;
-
         while (j < jLen) {
           if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
             found = true;
           }
-
           j += 1;
         }
-
         if (!found) {
           this.chars.push(chars[i]);
           jLen += 1;
         }
       }
     }
-
     function getCharData(_char, style, font) {
       var i = 0;
       var len = this.chars.length;
-
       while (i < len) {
         if (this.chars[i].ch === _char && this.chars[i].style === style && this.chars[i].fFamily === font) {
           return this.chars[i];
         }
-
         i += 1;
       }
-
       if ((typeof _char === 'string' && _char.charCodeAt(0) !== 13 || !_char) && console && console.warn // eslint-disable-line no-console
       && !this._warned) {
         this._warned = true;
         console.warn('Missing character from exported characters list: ', _char, style, font); // eslint-disable-line no-console
       }
-
       return emptyChar;
     }
-
     function measureText(_char2, fontName, size) {
-      var fontData = this.getFontByName(fontName); // Using the char instead of char.charCodeAt(0)
+      var fontData = this.getFontByName(fontName);
+      // Using the char instead of char.charCodeAt(0)
       // to avoid collisions between equal chars
-
       var index = _char2;
-
       if (!fontData.cache[index]) {
         var tHelper = fontData.helper;
-
         if (_char2 === ' ') {
           var doubleSize = tHelper.measureText('|' + _char2 + '|');
           var singleSize = tHelper.measureText('||');
@@ -7544,111 +6361,90 @@
           fontData.cache[index] = tHelper.measureText(_char2) / 100;
         }
       }
-
       return fontData.cache[index] * size;
     }
-
     function getFontByName(name) {
       var i = 0;
       var len = this.fonts.length;
-
       while (i < len) {
         if (this.fonts[i].fName === name) {
           return this.fonts[i];
         }
-
         i += 1;
       }
-
       return this.fonts[0];
     }
-
     function getCodePoint(string) {
       var codePoint = 0;
       var first = string.charCodeAt(0);
-
       if (first >= 0xD800 && first <= 0xDBFF) {
         var second = string.charCodeAt(1);
-
         if (second >= 0xDC00 && second <= 0xDFFF) {
           codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
         }
       }
-
       return codePoint;
-    } // Skin tone modifiers
+    }
 
-
+    // Skin tone modifiers
     function isModifier(firstCharCode, secondCharCode) {
       var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
       return surrogateModifiers.indexOf(sum) !== -1;
     }
-
     function isZeroWidthJoiner(charCode) {
       return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
-    } // This codepoint may change the appearance of the preceding character.
+    }
+
+    // This codepoint may change the appearance of the preceding character.
     // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
     // as a colorful image as compared to a monochrome text variant.
-
-
     function isVariationSelector(charCode) {
       return charCode === VARIATION_SELECTOR_16_CODE_POINT;
-    } // The regional indicator symbols are a set of 26 alphabetic Unicode
+    }
+
+    // The regional indicator symbols are a set of 26 alphabetic Unicode
     /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
     // two-letter country codes in a way that allows optional special treatment.
-
-
     function isRegionalCode(string) {
       var codePoint = getCodePoint(string);
-
       if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
         return true;
       }
-
       return false;
-    } // Some Emoji implementations represent combinations of
+    }
+
+    // Some Emoji implementations represent combinations of
     // two “regional indicator” letters as a single flag symbol.
-
-
     function isFlagEmoji(string) {
       return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
     }
-
     function isCombinedCharacter(_char3) {
       return combinedCharacters.indexOf(_char3) !== -1;
-    } // Regional flags start with a BLACK_FLAG_CODE_POINT
+    }
+
+    // Regional flags start with a BLACK_FLAG_CODE_POINT
     // folowed by 5 chars in the TAG range
     // and end with a CANCEL_TAG_CODE_POINT
-
-
     function isRegionalFlag(text, index) {
       var codePoint = getCodePoint(text.substr(index, 2));
-
       if (codePoint !== BLACK_FLAG_CODE_POINT) {
         return false;
       }
-
       var count = 0;
       index += 2;
-
       while (count < 5) {
         codePoint = getCodePoint(text.substr(index, 2));
-
         if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
           return false;
         }
-
         count += 1;
         index += 2;
       }
-
       return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
     }
-
     function setIsLoaded() {
       this.isLoaded = true;
     }
-
     var Font = function Font() {
       this.fonts = [];
       this.chars = null;
@@ -7659,7 +6455,6 @@
       this.setIsLoadedBinded = this.setIsLoaded.bind(this);
       this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
     };
-
     Font.isModifier = isModifier;
     Font.isZeroWidthJoiner = isZeroWidthJoiner;
     Font.isFlagEmoji = isFlagEmoji;
@@ -7684,30 +6479,26 @@
   function SlotManager(animationData) {
     this.animationData = animationData;
   }
-
   SlotManager.prototype.getProp = function (data) {
     if (this.animationData.slots && this.animationData.slots[data.sid]) {
       return Object.assign(data, this.animationData.slots[data.sid].p);
     }
-
     return data;
   };
-
   function slotFactory(animationData) {
     return new SlotManager(animationData);
   }
 
   function RenderableElement() {}
-
   RenderableElement.prototype = {
     initRenderable: function initRenderable() {
       // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
-      this.isInRange = false; // layer's display state
-
-      this.hidden = false; // If layer's transparency equals 0, it can be hidden
-
-      this.isTransparent = false; // list of animated components
-
+      this.isInRange = false;
+      // layer's display state
+      this.hidden = false;
+      // If layer's transparency equals 0, it can be hidden
+      this.isTransparent = false;
+      // list of animated components
       this.renderableComponents = [];
     },
     addRenderableComponent: function addRenderableComponent(component) {
@@ -7734,7 +6525,6 @@
         this.show();
       }
     },
-
     /**
        * @function
        * Initializes frame related properties.
@@ -7760,13 +6550,11 @@
     renderRenderable: function renderRenderable() {
       var i;
       var len = this.renderableComponents.length;
-
       for (i = 0; i < len; i += 1) {
         this.renderableComponents[i].renderFrame(this._isFirstFrame);
       }
       /* this.maskManager.renderFrame(this.finalTransform.mat);
           this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
-
     },
     sourceRectAtTime: function sourceRectAtTime() {
       return {
@@ -7783,7 +6571,6 @@
           h: this.data.textData.height
         };
       }
-
       return {
         w: this.data.width,
         h: this.data.height
@@ -7818,31 +6605,24 @@
   function SliderEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function AngleEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function ColorEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function PointEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function LayerIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function MaskIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function CheckboxEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function NoValueEffect() {
     this.p = {};
   }
@@ -7853,20 +6633,16 @@
     var i;
     var len = effects.length;
     var effectItem;
-
     for (i = 0; i < len; i += 1) {
       effectItem = new GroupEffect(effects[i], element);
       this.effectElements.push(effectItem);
     }
   }
-
   function GroupEffect(data, element) {
     this.init(data, element);
   }
-
   extendPrototype([DynamicPropertyContainer], GroupEffect);
   GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
-
   GroupEffect.prototype.init = function (data, element) {
     this.data = data;
     this.effectElements = [];
@@ -7875,50 +6651,39 @@
     var len = this.data.ef.length;
     var eff;
     var effects = this.data.ef;
-
     for (i = 0; i < len; i += 1) {
       eff = null;
-
       switch (effects[i].ty) {
         case 0:
           eff = new SliderEffect(effects[i], element, this);
           break;
-
         case 1:
           eff = new AngleEffect(effects[i], element, this);
           break;
-
         case 2:
           eff = new ColorEffect(effects[i], element, this);
           break;
-
         case 3:
           eff = new PointEffect(effects[i], element, this);
           break;
-
         case 4:
         case 7:
           eff = new CheckboxEffect(effects[i], element, this);
           break;
-
         case 10:
           eff = new LayerIndexEffect(effects[i], element, this);
           break;
-
         case 11:
           eff = new MaskIndexEffect(effects[i], element, this);
           break;
-
         case 5:
           eff = new EffectsManager(effects[i], element, this);
           break;
         // case 6:
-
         default:
           eff = new NoValueEffect(effects[i], element, this);
           break;
       }
-
       if (eff) {
         this.effectElements.push(eff);
       }
@@ -7926,47 +6691,37 @@
   };
 
   function BaseElement() {}
-
   BaseElement.prototype = {
     checkMasks: function checkMasks() {
       if (!this.data.hasMask) {
         return false;
       }
-
       var i = 0;
       var len = this.data.masksProperties.length;
-
       while (i < len) {
         if (this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false) {
           return true;
         }
-
         i += 1;
       }
-
       return false;
     },
     initExpressions: function initExpressions() {
       var expressionsInterfaces = getExpressionInterfaces();
-
       if (!expressionsInterfaces) {
         return;
       }
-
       var LayerExpressionInterface = expressionsInterfaces('layer');
       var EffectsExpressionInterface = expressionsInterfaces('effects');
       var ShapeExpressionInterface = expressionsInterfaces('shape');
       var TextExpressionInterface = expressionsInterfaces('text');
       var CompExpressionInterface = expressionsInterfaces('comp');
       this.layerInterface = LayerExpressionInterface(this);
-
       if (this.data.hasMask && this.maskManager) {
         this.layerInterface.registerMaskInterface(this.maskManager);
       }
-
       var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
       this.layerInterface.registerEffectsInterface(effectsInterface);
-
       if (this.data.ty === 0 || this.data.xt) {
         this.compInterface = CompExpressionInterface(this);
       } else if (this.data.ty === 4) {
@@ -7986,13 +6741,13 @@
       this.globalData = globalData;
       this.comp = comp;
       this.data = data;
-      this.layerId = createElementID(); // Stretch factor for old animations missing this property.
+      this.layerId = createElementID();
 
+      // Stretch factor for old animations missing this property.
       if (!this.data.sr) {
         this.data.sr = 1;
-      } // effects manager
-
-
+      }
+      // effects manager
       this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
     },
     getType: function getType() {
@@ -8007,8 +6762,8 @@
    * Checks layer in point and out point
    *
    */
-  function FrameElement() {}
 
+  function FrameElement() {}
   FrameElement.prototype = {
     /**
        * @function
@@ -8017,13 +6772,12 @@
        */
     initFrame: function initFrame() {
       // set to true when inpoint is rendered
-      this._isFirstFrame = false; // list of animated properties
-
-      this.dynamicProperties = []; // If layer has been modified in current tick this will be true
-
+      this._isFirstFrame = false;
+      // list of animated properties
+      this.dynamicProperties = [];
+      // If layer has been modified in current tick this will be true
       this._mdf = false;
     },
-
     /**
        * @function
        * Calculates all dynamic values
@@ -8037,11 +6791,9 @@
     prepareProperties: function prepareProperties(num, isVisible) {
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         if (isVisible || this._isParent && this.dynamicProperties[i].propType === 'transform') {
           this.dynamicProperties[i].getValue();
-
           if (this.dynamicProperties[i]._mdf) {
             this.globalData._mdf = true;
             this._mdf = true;
@@ -8063,30 +6815,21 @@
     this.footageData = globalData.imageLoader.getAsset(this.assetData);
     this.initBaseData(data, globalData, comp);
   }
-
   FootageElement.prototype.prepareFrame = function () {};
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
-
   FootageElement.prototype.getBaseElement = function () {
     return null;
   };
-
   FootageElement.prototype.renderFrame = function () {};
-
   FootageElement.prototype.destroy = function () {};
-
   FootageElement.prototype.initExpressions = function () {
     var expressionsInterfaces = getExpressionInterfaces();
-
     if (!expressionsInterfaces) {
       return;
     }
-
     var FootageInterface = expressionsInterfaces('footage');
     this.layerInterface = FootageInterface(this);
   };
-
   FootageElement.prototype.getFootageData = function () {
     return this.footageData;
   };
@@ -8112,29 +6855,23 @@
       k: [100]
     }, 1, 0.01, this);
   }
-
   AudioElement.prototype.prepareFrame = function (num) {
     this.prepareRenderableFrame(num, true);
     this.prepareProperties(num, true);
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
       this._currentTime = timeRemapped;
     } else {
       this._currentTime = num / this.data.sr;
     }
-
     this._volume = this.lv.v[0];
     var totalVolume = this._volume * this._volumeMultiplier;
-
     if (this._previousVolume !== totalVolume) {
       this._previousVolume = totalVolume;
       this.audio.volume(totalVolume);
     }
   };
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
-
   AudioElement.prototype.renderFrame = function () {
     if (this.isInRange && this._canPlay) {
       if (!this._isPlaying) {
@@ -8146,162 +6883,124 @@
       }
     }
   };
-
-  AudioElement.prototype.show = function () {// this.audio.play()
+  AudioElement.prototype.show = function () {
+    // this.audio.play()
   };
-
   AudioElement.prototype.hide = function () {
     this.audio.pause();
     this._isPlaying = false;
   };
-
   AudioElement.prototype.pause = function () {
     this.audio.pause();
     this._isPlaying = false;
     this._canPlay = false;
   };
-
   AudioElement.prototype.resume = function () {
     this._canPlay = true;
   };
-
   AudioElement.prototype.setRate = function (rateValue) {
     this.audio.rate(rateValue);
   };
-
   AudioElement.prototype.volume = function (volumeValue) {
     this._volumeMultiplier = volumeValue;
     this._previousVolume = volumeValue * this._volume;
     this.audio.volume(this._previousVolume);
   };
-
   AudioElement.prototype.getBaseElement = function () {
     return null;
   };
-
   AudioElement.prototype.destroy = function () {};
-
   AudioElement.prototype.sourceRectAtTime = function () {};
-
   AudioElement.prototype.initExpressions = function () {};
 
   function BaseRenderer() {}
-
   BaseRenderer.prototype.checkLayers = function (num) {
     var i;
     var len = this.layers.length;
     var data;
     this.completeLayers = true;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (!this.elements[i]) {
         data = this.layers[i];
-
         if (data.ip - data.st <= num - this.layers[i].st && data.op - data.st > num - this.layers[i].st) {
           this.buildItem(i);
         }
       }
-
       this.completeLayers = this.elements[i] ? this.completeLayers : false;
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.createItem = function (layer) {
     switch (layer.ty) {
       case 2:
         return this.createImage(layer);
-
       case 0:
         return this.createComp(layer);
-
       case 1:
         return this.createSolid(layer);
-
       case 3:
         return this.createNull(layer);
-
       case 4:
         return this.createShape(layer);
-
       case 5:
         return this.createText(layer);
-
       case 6:
         return this.createAudio(layer);
-
       case 13:
         return this.createCamera(layer);
-
       case 15:
         return this.createFootage(layer);
-
       default:
         return this.createNull(layer);
     }
   };
-
   BaseRenderer.prototype.createCamera = function () {
     throw new Error('You\'re using a 3d camera. Try the html renderer.');
   };
-
   BaseRenderer.prototype.createAudio = function (data) {
     return new AudioElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.createFootage = function (data) {
     return new FootageElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.buildAllItems = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       this.buildItem(i);
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.includeLayers = function (newLayers) {
     this.completeLayers = false;
     var i;
     var len = newLayers.length;
     var j;
     var jLen = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       j = 0;
-
       while (j < jLen) {
         if (this.layers[j].id === newLayers[i].id) {
           this.layers[j] = newLayers[i];
           break;
         }
-
         j += 1;
       }
     }
   };
-
   BaseRenderer.prototype.setProjectInterface = function (pInterface) {
     this.globalData.projectInterface = pInterface;
   };
-
   BaseRenderer.prototype.initItems = function () {
     if (!this.globalData.progressiveLoad) {
       this.buildAllItems();
     }
   };
-
   BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
     var elements = this.elements;
     var layers = this.layers;
     var i = 0;
     var len = layers.length;
-
     while (i < len) {
       if (layers[i].ind == parentName) {
         // eslint-disable-line eqeqeq
@@ -8311,7 +7010,6 @@
         } else {
           hierarchy.push(elements[i]);
           elements[i].setAsParent();
-
           if (layers[i].parent !== undefined) {
             this.buildElementParenting(element, layers[i].parent, hierarchy);
           } else {
@@ -8319,19 +7017,15 @@
           }
         }
       }
-
       i += 1;
     }
   };
-
   BaseRenderer.prototype.addPendingElement = function (element) {
     this.pendingElements.push(element);
   };
-
   BaseRenderer.prototype.searchExtraCompositions = function (assets) {
     var i;
     var len = assets.length;
-
     for (i = 0; i < len; i += 1) {
       if (assets[i].xt) {
         var comp = this.createComp(assets[i]);
@@ -8340,30 +7034,24 @@
       }
     }
   };
-
   BaseRenderer.prototype.getElementById = function (ind) {
     var i;
     var len = this.elements.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i].data.ind === ind) {
         return this.elements[i];
       }
     }
-
     return null;
   };
-
   BaseRenderer.prototype.getElementByPath = function (path) {
     var pathValue = path.shift();
     var element;
-
     if (typeof pathValue === 'number') {
       element = this.elements[pathValue];
     } else {
       var i;
       var len = this.elements.length;
-
       for (i = 0; i < len; i += 1) {
         if (this.elements[i].data.nm === pathValue) {
           element = this.elements[i];
@@ -8371,14 +7059,11 @@
         }
       }
     }
-
     if (path.length === 0) {
       return element;
     }
-
     return element.getElementByPath(path);
   };
-
   BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
     this.globalData.fontManager = new FontManager();
     this.globalData.slotManager = slotFactory(animData);
@@ -8402,7 +7087,6 @@
   };
 
   function TransformElement() {}
-
   TransformElement.prototype = {
     initTransform: function initTransform() {
       var mat = new Matrix();
@@ -8417,50 +7101,44 @@
         localMat: mat,
         localOpacity: 1
       };
-
       if (this.data.ao) {
         this.finalTransform.mProp.autoOriented = true;
-      } // TODO: check TYPE 11: Guided elements
+      }
 
-
-      if (this.data.ty !== 11) {// this.createElements();
+      // TODO: check TYPE 11: Guided elements
+      if (this.data.ty !== 11) {
+        // this.createElements();
       }
     },
     renderTransform: function renderTransform() {
       this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
       this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
-
       if (this.hierarchy) {
         var mat;
         var finalMat = this.finalTransform.mat;
         var i = 0;
-        var len = this.hierarchy.length; // Checking if any of the transformation matrices in the hierarchy chain has changed.
-
+        var len = this.hierarchy.length;
+        // Checking if any of the transformation matrices in the hierarchy chain has changed.
         if (!this.finalTransform._matMdf) {
           while (i < len) {
             if (this.hierarchy[i].finalTransform.mProp._mdf) {
               this.finalTransform._matMdf = true;
               break;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._matMdf) {
           mat = this.finalTransform.mProp.v.props;
           finalMat.cloneFromProps(mat);
-
           for (i = 0; i < len; i += 1) {
             finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
           }
         }
       }
-
-      if (this.finalTransform._matMdf) {
+      if (!this.localTransforms || this.finalTransform._matMdf) {
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
       }
-
       if (this.finalTransform._opMdf) {
         this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
       }
@@ -8470,41 +7148,32 @@
         var i = 0;
         var len = this.localTransforms.length;
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
-
         if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
           while (i < len) {
             if (this.localTransforms[i]._mdf) {
               this.finalTransform._localMatMdf = true;
             }
-
             if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
               this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
               this.finalTransform._opMdf = true;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._localMatMdf) {
           var localMat = this.finalTransform.localMat;
           this.localTransforms[0].matrix.clone(localMat);
-
           for (i = 1; i < len; i += 1) {
             var lmat = this.localTransforms[i].matrix;
             localMat.multiply(lmat);
           }
-
           localMat.multiply(this.finalTransform.mat);
         }
-
         if (this.finalTransform._opMdf) {
           var localOp = this.finalTransform.localOpacity;
-
           for (i = 0; i < len; i += 1) {
             localOp *= this.localTransforms[i].opacity * 0.01;
           }
-
           this.finalTransform.localOpacity = localOp;
         }
       }
@@ -8512,13 +7181,11 @@
     searchEffectTransforms: function searchEffectTransforms() {
       if (this.renderableEffectsManager) {
         var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
-
         if (transformEffects.length) {
           this.localTransforms = [];
           this.finalTransform.localMat = new Matrix();
           var i = 0;
           var len = transformEffects.length;
-
           for (i = 0; i < len; i += 1) {
             this.localTransforms.push(transformEffects[i]);
           }
@@ -8530,29 +7197,24 @@
       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;
       var len = transforms.length;
       var 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]);
-
+        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;
     },
     mHelper: new Matrix()
@@ -8583,13 +7245,11 @@
     var x;
     var maskType = 'clipPath';
     var maskRef = 'clip-path';
-
     for (i = 0; i < len; i += 1) {
       if (properties[i].mode !== 'a' && properties[i].mode !== 'n' || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
         maskType = 'mask';
         maskRef = 'mask';
       }
-
       if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
         rect = createNS('rect');
         rect.setAttribute('fill', '#ffffff');
@@ -8599,9 +7259,7 @@
       } else {
         rect = null;
       }
-
       path = createNS('path');
-
       if (properties[i].mode === 'n') {
         // TODO move this to a factory or to a constructor
         this.viewData[i] = {
@@ -8616,7 +7274,6 @@
         path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
         path.setAttribute('clip-rule', 'nonzero');
         var filterID;
-
         if (properties[i].x.k !== 0) {
           maskType = 'mask';
           maskRef = 'mask';
@@ -8634,9 +7291,9 @@
         } else {
           feMorph = null;
           x = null;
-        } // TODO move this to a factory or to a constructor
+        }
 
-
+        // TODO move this to a factory or to a constructor
         this.storedData[i] = {
           elem: path,
           x: x,
@@ -8646,15 +7303,12 @@
           filterId: filterID,
           lastRadius: 0
         };
-
         if (properties[i].mode === 'i') {
           jLen = currentMasks.length;
           var g = createNS('g');
-
           for (j = 0; j < jLen; j += 1) {
             g.appendChild(currentMasks[j]);
           }
-
           var mask = createNS('mask');
           mask.setAttribute('mask-type', 'alpha');
           mask.setAttribute('id', layerId + '_' + count);
@@ -8666,12 +7320,10 @@
         } else {
           currentMasks.push(path);
         }
-
         if (properties[i].inv && !this.solidPath) {
           this.solidPath = this.createLayerSolidPath();
-        } // TODO move this to a factory or to a constructor
-
-
+        }
+        // TODO move this to a factory or to a constructor
         this.viewData[i] = {
           elem: path,
           lastPath: '',
@@ -8679,81 +7331,65 @@
           prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
           invRect: rect
         };
-
         if (!this.viewData[i].prop.k) {
           this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
         }
       }
     }
-
     this.maskElement = createNS(maskType);
     len = currentMasks.length;
-
     for (i = 0; i < len; i += 1) {
       this.maskElement.appendChild(currentMasks[i]);
     }
-
     if (count > 0) {
       this.maskElement.setAttribute('id', layerId);
       this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
       defs.appendChild(this.maskElement);
     }
-
     if (this.viewData.length) {
       this.element.addRenderableComponent(this);
     }
   }
-
   MaskElement.prototype.getMaskProperty = function (pos) {
     return this.viewData[pos].prop;
   };
-
   MaskElement.prototype.renderFrame = function (isFirstFrame) {
     var finalMat = this.element.finalTransform.mat;
     var i;
     var len = this.masksProperties.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.viewData[i].prop._mdf || isFirstFrame) {
         this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
       }
-
       if (this.viewData[i].op._mdf || isFirstFrame) {
         this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
       }
-
       if (this.masksProperties[i].mode !== 'n') {
         if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
           this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
         }
-
         if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
           var feMorph = this.storedData[i].expan;
-
           if (this.storedData[i].x.v < 0) {
             if (this.storedData[i].lastOperator !== 'erode') {
               this.storedData[i].lastOperator = 'erode';
               this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
             }
-
             feMorph.setAttribute('radius', -this.storedData[i].x.v);
           } else {
             if (this.storedData[i].lastOperator !== 'dilate') {
               this.storedData[i].lastOperator = 'dilate';
               this.storedData[i].elem.setAttribute('filter', null);
             }
-
             this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
           }
         }
       }
     }
   };
-
   MaskElement.prototype.getMaskelement = function () {
     return this.maskElement;
   };
-
   MaskElement.prototype.createLayerSolidPath = function () {
     var path = 'M0,0 ';
     path += ' h' + this.globalData.compSize.w;
@@ -8762,39 +7398,32 @@
     path += ' v-' + this.globalData.compSize.h + ' ';
     return path;
   };
-
   MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
     var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
     var i;
     var len;
     len = pathNodes._length;
-
     for (i = 1; i < len; i += 1) {
       // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
-    } // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
-
-
+    }
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
     if (pathNodes.c && len > 1) {
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
-    } // pathNodes.__renderedString = pathString;
-
+    }
+    // pathNodes.__renderedString = pathString;
 
     if (viewData.lastPath !== pathString) {
       var pathShapeValue = '';
-
       if (viewData.elem) {
         if (pathNodes.c) {
           pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
         }
-
         viewData.elem.setAttribute('d', pathShapeValue);
       }
-
       viewData.lastPath = pathString;
     }
   };
-
   MaskElement.prototype.destroy = function () {
     this.element = null;
     this.globalData = null;
@@ -8807,11 +7436,9 @@
     var ob = {};
     ob.createFilter = createFilter;
     ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
-
     function createFilter(filId, skipCoordinates) {
       var fil = createNS('filter');
       fil.setAttribute('id', filId);
-
       if (skipCoordinates !== true) {
         fil.setAttribute('filterUnits', 'objectBoundingBox');
         fil.setAttribute('x', '0%');
@@ -8819,10 +7446,8 @@
         fil.setAttribute('width', '100%');
         fil.setAttribute('height', '100%');
       }
-
       return fil;
     }
-
     function createAlphaToLuminanceFilter() {
       var feColorMatrix = createNS('feColorMatrix');
       feColorMatrix.setAttribute('type', 'matrix');
@@ -8830,7 +7455,6 @@
       feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
       return feColorMatrix;
     }
-
     return ob;
   }();
 
@@ -8840,21 +7464,17 @@
       svgLumaHidden: true,
       offscreenCanvas: typeof OffscreenCanvas !== 'undefined'
     };
-
     if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
       ob.maskType = false;
     }
-
     if (/firefox/i.test(navigator.userAgent)) {
       ob.svgLumaHidden = false;
     }
-
     return ob;
   }();
 
   var registeredEffects$1 = {};
   var idPrefix = 'filter_result_';
-
   function SVGEffects(elem) {
     var i;
     var source = 'SourceGraphic';
@@ -8864,59 +7484,47 @@
     var count = 0;
     this.filters = [];
     var filterManager;
-
     for (i = 0; i < len; i += 1) {
       filterManager = null;
       var type = elem.data.ef[i].ty;
-
       if (registeredEffects$1[type]) {
         var Effect = registeredEffects$1[type].effect;
         filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
         source = idPrefix + count;
-
         if (registeredEffects$1[type].countsAsEffect) {
           count += 1;
         }
       }
-
       if (filterManager) {
         this.filters.push(filterManager);
       }
     }
-
     if (count) {
       elem.globalData.defs.appendChild(fil);
       elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
     }
-
     if (this.filters.length) {
       elem.addRenderableComponent(this);
     }
   }
-
   SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
     var i;
     var len = this.filters.length;
-
     for (i = 0; i < len; i += 1) {
       this.filters[i].renderFrame(_isFirstFrame);
     }
   };
-
   SVGEffects.prototype.getEffects = function (type) {
     var i;
     var len = this.filters.length;
     var effects = [];
-
     for (i = 0; i < len; i += 1) {
       if (this.filters[i].type === type) {
         effects.push(this.filters[i]);
       }
     }
-
     return effects;
   };
-
   function registerEffect$1(id, effect, countsAsEffect) {
     registeredEffects$1[id] = {
       effect: effect,
@@ -8925,7 +7533,6 @@
   }
 
   function SVGBaseElement() {}
-
   SVGBaseElement.prototype = {
     initRendererElement: function initRendererElement() {
       this.layerElement = createNS('g');
@@ -8935,8 +7542,8 @@
       this.transformedElement = this.layerElement;
       this.maskedElement = this.layerElement;
       this._sizeChanged = false;
-      var layerElementParent = null; // If this layer acts as a mask for the following layer
-
+      var layerElementParent = null;
+      // If this layer acts as a mask for the following layer
       if (this.data.td) {
         this.matteMasks = {};
         var gg = createNS('g');
@@ -8951,16 +7558,13 @@
       } else {
         this.baseElement = this.layerElement;
       }
-
       if (this.data.ln) {
         this.layerElement.setAttribute('id', this.data.ln);
       }
-
       if (this.data.cl) {
         this.layerElement.setAttribute('class', this.data.cl);
-      } // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
-
-
+      }
+      // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
       if (this.data.ty === 0 && !this.data.hd) {
         var cp = createNS('clipPath');
         var pt = createNS('path');
@@ -8969,13 +7573,11 @@
         cp.setAttribute('id', clipId);
         cp.appendChild(pt);
         this.globalData.defs.appendChild(cp);
-
         if (this.checkMasks()) {
           var cpGroup = createNS('g');
           cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
           cpGroup.appendChild(this.layerElement);
           this.transformedElement = cpGroup;
-
           if (layerElementParent) {
             layerElementParent.appendChild(this.transformedElement);
           } else {
@@ -8985,7 +7587,6 @@
           this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
         }
       }
-
       if (this.data.bm !== 0) {
         this.setBlendMode();
       }
@@ -8994,7 +7595,6 @@
       if (this.finalTransform._localMatMdf) {
         this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
       }
-
       if (this.finalTransform._opMdf) {
         this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
       }
@@ -9008,7 +7608,6 @@
       if (this.data.hd) {
         return null;
       }
-
       return this.baseElement;
     },
     createRenderableComponents: function createRenderableComponents() {
@@ -9023,14 +7622,12 @@
       if (!this.matteMasks) {
         this.matteMasks = {};
       }
-
       if (!this.matteMasks[matteType]) {
         var id = this.layerId + '_' + matteType;
         var filId;
         var fil;
         var useElement;
         var gg;
-
         if (matteType === 1 || matteType === 3) {
           var masker = createNS('mask');
           masker.setAttribute('id', id);
@@ -9039,7 +7636,6 @@
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           masker.appendChild(useElement);
           this.globalData.defs.appendChild(masker);
-
           if (!featureSupport.maskType && matteType === 1) {
             masker.setAttribute('mask-type', 'luminance');
             filId = createElementID();
@@ -9058,16 +7654,16 @@
           var maskGrouper = createNS('g');
           maskGroup.appendChild(maskGrouper);
           filId = createElementID();
-          fil = filtersFactory.createFilter(filId); /// /
-
+          fil = filtersFactory.createFilter(filId);
+          /// /
           var feCTr = createNS('feComponentTransfer');
           feCTr.setAttribute('in', 'SourceGraphic');
           fil.appendChild(feCTr);
           var feFunc = createNS('feFuncA');
           feFunc.setAttribute('type', 'table');
           feFunc.setAttribute('tableValues', '1.0 0.0');
-          feCTr.appendChild(feFunc); /// /
-
+          feCTr.appendChild(feFunc);
+          /// /
           this.globalData.defs.appendChild(fil);
           var alphaRect = createNS('rect');
           alphaRect.setAttribute('width', this.comp.data.w);
@@ -9081,7 +7677,6 @@
           useElement = createNS('use');
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           maskGrouper.appendChild(useElement);
-
           if (!featureSupport.maskType) {
             maskGroup.setAttribute('mask-type', 'luminance');
             fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
@@ -9090,20 +7685,16 @@
             gg.appendChild(this.layerElement);
             maskGrouper.appendChild(gg);
           }
-
           this.globalData.defs.appendChild(maskGroup);
         }
-
         this.matteMasks[matteType] = id;
       }
-
       return this.matteMasks[matteType];
     },
     setMatte: function setMatte(id) {
       if (!this.matteElement) {
         return;
       }
-
       this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
     }
   };
@@ -9113,8 +7704,8 @@
    * Handles AE's layer parenting property.
    *
    */
-  function HierarchyElement() {}
 
+  function HierarchyElement() {}
   HierarchyElement.prototype = {
     /**
        * @function
@@ -9123,12 +7714,11 @@
        */
     initHierarchy: function initHierarchy() {
       // element's parent list
-      this.hierarchy = []; // if element is parent of another layer _isParent will be true
-
+      this.hierarchy = [];
+      // if element is parent of another layer _isParent will be true
       this._isParent = false;
       this.checkParenting();
     },
-
     /**
        * @function
        * Sets layer's hierarchy.
@@ -9139,7 +7729,6 @@
     setHierarchy: function setHierarchy(hierarchy) {
       this.hierarchy = hierarchy;
     },
-
     /**
        * @function
        * Sets layer as parent.
@@ -9148,7 +7737,6 @@
     setAsParent: function setAsParent() {
       this._isParent = true;
     },
-
     /**
        * @function
        * Searches layer's parenting chain
@@ -9162,7 +7750,6 @@
   };
 
   function RenderableDOMElement() {}
-
   (function () {
     var _prototype = {
       initElement: function initElement(data, globalData, comp) {
@@ -9192,7 +7779,6 @@
             var elem = this.baseElement || this.layerElement;
             elem.style.display = 'block';
           }
-
           this.hidden = false;
           this._isFirstFrame = true;
         }
@@ -9203,13 +7789,11 @@
         if (this.data.hd || this.hidden) {
           return;
         }
-
         this.renderTransform();
         this.renderRenderable();
         this.renderLocalTransform();
         this.renderElement();
         this.renderInnerContent();
-
         if (this._isFirstFrame) {
           this._isFirstFrame = false;
         }
@@ -9231,11 +7815,9 @@
 
   function IImageElement(data, globalData, comp) {
     this.assetData = globalData.getAssetData(data.refId);
-
     if (this.assetData && this.assetData.sid) {
       this.assetData = globalData.slotManager.getProp(this.assetData);
     }
-
     this.initElement(data, globalData, comp);
     this.sourceRect = {
       top: 0,
@@ -9244,9 +7826,7 @@
       height: this.assetData.h
     };
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
-
   IImageElement.prototype.createContent = function () {
     var assetPath = this.globalData.getAssetsPath(this.assetData);
     this.innerElem = createNS('image');
@@ -9256,7 +7836,6 @@
     this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
     this.layerElement.appendChild(this.innerElem);
   };
-
   IImageElement.prototype.sourceRectAtTime = function () {
     return this.sourceRect;
   };
@@ -9267,12 +7846,10 @@
   }
 
   function IShapeElement() {}
-
   IShapeElement.prototype = {
     addShapeToModifiers: function addShapeToModifiers(data) {
       var i;
       var len = this.shapeModifiers.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapeModifiers[i].addShape(data);
       }
@@ -9280,34 +7857,28 @@
     isShapeInAnimatedModifiers: function isShapeInAnimatedModifiers(data) {
       var i = 0;
       var len = this.shapeModifiers.length;
-
       while (i < len) {
         if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
           return true;
         }
       }
-
       return false;
     },
     renderModifiers: function renderModifiers() {
       if (!this.shapeModifiers.length) {
         return;
       }
-
       var i;
       var len = this.shapes.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapes[i].sh.reset();
       }
-
       len = this.shapeModifiers.length;
       var shouldBreakProcess;
-
       for (i = len - 1; i >= 0; i -= 1) {
-        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame); // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+        // workaround to fix cases where a repeater resets the shape so the following processes get called twice
         // TODO: find a better solution for this
-
         if (shouldBreakProcess) {
           break;
         }
@@ -9317,30 +7888,24 @@
       var elements = this.processedElements;
       var i = 0;
       var len = elements.length;
-
       while (i < len) {
         if (elements[i].elem === elem) {
           return elements[i].pos;
         }
-
         i += 1;
       }
-
       return 0;
     },
     addProcessedElement: function addProcessedElement(elem, pos) {
       var elements = this.processedElements;
       var i = elements.length;
-
       while (i) {
         i -= 1;
-
         if (elements[i].elem === elem) {
           elements[i].pos = pos;
           return;
         }
       }
-
       elements.push(new ProcessedElement(elem, pos));
     },
     prepareFrame: function prepareFrame(num) {
@@ -9366,25 +7931,22 @@
     this.transformers = transformers;
     this.lStr = '';
     this.sh = shape;
-    this.lvl = level; // TODO find if there are some cases where _isAnimated can be false.
+    this.lvl = level;
+    // TODO find if there are some cases where _isAnimated can be false.
     // For now, since shapes add up with other shapes. They have to be calculated every time.
     // One way of finding out is checking if all styles associated to this shape depend only of this shape
-
-    this._isAnimated = !!shape.k; // TODO: commenting this for now since all shapes are animated
-
+    this._isAnimated = !!shape.k;
+    // TODO: commenting this for now since all shapes are animated
     var i = 0;
     var len = transformers.length;
-
     while (i < len) {
       if (transformers[i].mProps.dynamicProperties.length) {
         this._isAnimated = true;
         break;
       }
-
       i += 1;
     }
   }
-
   SVGShapeData.prototype.setAsAnimated = function () {
     this._isAnimated = true;
   };
@@ -9399,7 +7961,6 @@
     this.pElem = createNS('path');
     this.msElem = null;
   }
-
   SVGStyleData.prototype.reset = function () {
     this.d = '';
     this._mdf = false;
@@ -9418,7 +7979,6 @@
     var i;
     var len = data.length || 0;
     var prop;
-
     for (i = 0; i < len; i += 1) {
       prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
       this.k = prop.k || this.k;
@@ -9427,31 +7987,24 @@
         p: prop
       };
     }
-
     if (!this.k) {
       this.getValue(true);
     }
-
     this._isAnimated = this.k;
   }
-
   DashProperty.prototype.getValue = function (forceRender) {
     if (this.elem.globalData.frameId === this.frameId && !forceRender) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
     this._mdf = this._mdf || forceRender;
-
     if (this._mdf) {
       var i = 0;
       var len = this.dataProps.length;
-
       if (this.renderer === 'svg') {
         this.dashStr = '';
       }
-
       for (i = 0; i < len; i += 1) {
         if (this.dataProps[i].n !== 'o') {
           if (this.renderer === 'svg') {
@@ -9465,7 +8018,6 @@
       }
     }
   };
-
   extendPrototype([DynamicPropertyContainer], DashProperty);
 
   function SVGStrokeStyleData(elem, data, styleOb) {
@@ -9478,7 +8030,6 @@
     this.style = styleOb;
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
 
   function SVGFillStyleData(elem, data, styleOb) {
@@ -9488,7 +8039,6 @@
     this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
 
   function SVGNoStyleData(elem, data, styleOb) {
@@ -9496,7 +8046,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
 
   function GradientProperty(elem, data, container) {
@@ -9513,88 +8062,69 @@
     this.k = this.prop.k;
     this.getValue(true);
   }
-
   GradientProperty.prototype.comparePoints = function (values, points) {
     var i = 0;
     var len = this.o.length / 2;
     var diff;
-
     while (i < len) {
       diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
-
       if (diff > 0.01) {
         return false;
       }
-
       i += 1;
     }
-
     return true;
   };
-
   GradientProperty.prototype.checkCollapsable = function () {
     if (this.o.length / 2 !== this.c.length / 4) {
       return false;
     }
-
     if (this.data.k.k[0].s) {
       var i = 0;
       var len = this.data.k.k.length;
-
       while (i < len) {
         if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
           return false;
         }
-
         i += 1;
       }
     } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
       return false;
     }
-
     return true;
   };
-
   GradientProperty.prototype.getValue = function (forceRender) {
     this.prop.getValue();
     this._mdf = false;
     this._cmdf = false;
     this._omdf = false;
-
     if (this.prop._mdf || forceRender) {
       var i;
       var len = this.data.p * 4;
       var mult;
       var val;
-
       for (i = 0; i < len; i += 1) {
         mult = i % 4 === 0 ? 100 : 255;
         val = Math.round(this.prop.v[i] * mult);
-
         if (this.c[i] !== val) {
           this.c[i] = val;
           this._cmdf = !forceRender;
         }
       }
-
       if (this.o.length) {
         len = this.prop.v.length;
-
         for (i = this.data.p * 4; i < len; i += 1) {
           mult = i % 2 === 0 ? 100 : 1;
           val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
-
           if (this.o[i - this.data.p * 4] !== val) {
             this.o[i - this.data.p * 4] = val;
             this._omdf = !forceRender;
           }
         }
       }
-
       this._mdf = !forceRender;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], GradientProperty);
 
   function SVGGradientFillStyleData(elem, data, styleOb) {
@@ -9602,7 +8132,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.initGradientData(elem, data, styleOb);
   }
-
   SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
     this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
     this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
@@ -9620,7 +8149,6 @@
     this.setGradientOpacity(data, styleOb);
     this._isAnimated = !!this._isAnimated;
   };
-
   SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
     var gradientId = createElementID();
     var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
@@ -9632,18 +8160,15 @@
     var j;
     var jLen;
     jLen = data.g.p * 4;
-
     for (j = 0; j < jLen; j += 4) {
       stop = createNS('stop');
       gfill.appendChild(stop);
       stops.push(stop);
     }
-
     pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
     this.gf = gfill;
     this.cst = stops;
   };
-
   SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
     if (this.g._hasOpacity && !this.g._collapsable) {
       var stop;
@@ -9661,25 +8186,20 @@
       opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
       jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
       var stops = this.stops;
-
       for (j = data.g.p * 4; j < jLen; j += 2) {
         stop = createNS('stop');
         stop.setAttribute('stop-color', 'rgb(255,255,255)');
         opFill.appendChild(stop);
         stops.push(stop);
       }
-
       maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
@@ -9687,7 +8207,6 @@
       styleOb.msElem = maskElement;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
 
   function SVGGradientStrokeStyleData(elem, data, styleOb) {
@@ -9698,7 +8217,6 @@
     this.initGradientData(elem, data, styleOb);
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
 
   function ShapeGroupData() {
@@ -9721,77 +8239,59 @@
     if (length === 0) {
       return '';
     }
-
     var _o = pathNodes.o;
     var _i = pathNodes.i;
     var _v = pathNodes.v;
     var i;
     var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
-
     for (i = 1; i < length; i += 1) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
     }
-
     if (closed && length) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
       shapeString += 'z';
     }
-
     return shapeString;
   };
 
   var SVGElementsRenderer = function () {
     var _identityMatrix = new Matrix();
-
     var _matrixHelper = new Matrix();
-
     var ob = {
       createRenderFunction: createRenderFunction
     };
-
     function createRenderFunction(data) {
       switch (data.ty) {
         case 'fl':
           return renderFill;
-
         case 'gf':
           return renderGradient;
-
         case 'gs':
           return renderGradientStroke;
-
         case 'st':
           return renderStroke;
-
         case 'sh':
         case 'el':
         case 'rc':
         case 'sr':
           return renderPath;
-
         case 'tr':
           return renderContentTransform;
-
         case 'no':
           return renderNoop;
-
         default:
           return null;
       }
     }
-
     function renderContentTransform(styleData, itemData, isFirstFrame) {
       if (isFirstFrame || itemData.transform.op._mdf) {
         itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
       }
-
       if (isFirstFrame || itemData.transform.mProps._mdf) {
         itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
       }
     }
-
     function renderNoop() {}
-
     function renderPath(styleData, itemData, isFirstFrame) {
       var j;
       var jLen;
@@ -9805,25 +8305,20 @@
       var mat;
       var iterations;
       var k;
-
       for (l = 0; l < lLen; l += 1) {
         redraw = itemData.sh._mdf || isFirstFrame;
-
         if (itemData.styles[l].lvl < lvl) {
           mat = _matrixHelper.reset();
           iterations = lvl - itemData.styles[l].lvl;
           k = itemData.transformers.length - 1;
-
           while (!redraw && iterations > 0) {
             redraw = itemData.transformers[k].mProps._mdf || redraw;
             iterations -= 1;
             k -= 1;
           }
-
           if (redraw) {
             iterations = lvl - itemData.styles[l].lvl;
             k = itemData.transformers.length - 1;
-
             while (iterations > 0) {
               mat.multiply(itemData.transformers[k].mProps.v);
               iterations -= 1;
@@ -9833,115 +8328,90 @@
         } else {
           mat = _identityMatrix;
         }
-
         paths = itemData.sh.paths;
         jLen = paths._length;
-
         if (redraw) {
           pathStringTransformed = '';
-
           for (j = 0; j < jLen; j += 1) {
             pathNodes = paths.shapes[j];
-
             if (pathNodes && pathNodes._length) {
               pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
             }
           }
-
           itemData.caches[l] = pathStringTransformed;
         } else {
           pathStringTransformed = itemData.caches[l];
         }
-
         itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
         itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
       }
     }
-
     function renderFill(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
-
       if (itemData.c._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
       }
     }
-
     function renderGradientStroke(styleData, itemData, isFirstFrame) {
       renderGradient(styleData, itemData, isFirstFrame);
       renderStroke(styleData, itemData, isFirstFrame);
     }
-
     function renderGradient(styleData, itemData, isFirstFrame) {
       var gfill = itemData.gf;
       var hasOpacity = itemData.g._hasOpacity;
       var pt1 = itemData.s.v;
       var pt2 = itemData.e.v;
-
       if (itemData.o._mdf || isFirstFrame) {
         var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
         itemData.style.pElem.setAttribute(attr, itemData.o.v);
       }
-
       if (itemData.s._mdf || isFirstFrame) {
         var attr1 = styleData.t === 1 ? 'x1' : 'cx';
         var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
         gfill.setAttribute(attr1, pt1[0]);
         gfill.setAttribute(attr2, pt1[1]);
-
         if (hasOpacity && !itemData.g._collapsable) {
           itemData.of.setAttribute(attr1, pt1[0]);
           itemData.of.setAttribute(attr2, pt1[1]);
         }
       }
-
       var stops;
       var i;
       var len;
       var stop;
-
       if (itemData.g._cmdf || isFirstFrame) {
         stops = itemData.cst;
         var cValues = itemData.g.c;
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
           stop.setAttribute('offset', cValues[i * 4] + '%');
           stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
         }
       }
-
       if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
         var oValues = itemData.g.o;
-
         if (itemData.g._collapsable) {
           stops = itemData.cst;
         } else {
           stops = itemData.ost;
         }
-
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
-
           if (!itemData.g._collapsable) {
             stop.setAttribute('offset', oValues[i * 2] + '%');
           }
-
           stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
         }
       }
-
       if (styleData.t === 1) {
         if (itemData.e._mdf || isFirstFrame) {
           gfill.setAttribute('x2', pt2[0]);
           gfill.setAttribute('y2', pt2[1]);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('x2', pt2[0]);
             itemData.of.setAttribute('y2', pt2[1]);
@@ -9949,112 +8419,93 @@
         }
       } else {
         var rad;
-
         if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
           rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           gfill.setAttribute('r', rad);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('r', rad);
           }
         }
-
-        if (itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
           if (!rad) {
             rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           }
-
           var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
           var percent = itemData.h.v;
-
           if (percent >= 1) {
             percent = 0.99;
           } else if (percent <= -1) {
             percent = -0.99;
           }
-
           var dist = rad * percent;
           var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
           var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
           gfill.setAttribute('fx', x);
           gfill.setAttribute('fy', y);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('fx', x);
             itemData.of.setAttribute('fy', y);
           }
-        } // gfill.setAttribute('fy','200');
-
+        }
+        // gfill.setAttribute('fy','200');
       }
     }
-
     function renderStroke(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
       var d = itemData.d;
-
       if (d && (d._mdf || isFirstFrame) && d.dashStr) {
         styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
         styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
       }
-
       if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
         styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
       }
-
       if (itemData.w._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
-
         if (styleElem.msElem) {
           styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
         }
       }
     }
-
     return ob;
   }();
 
   function SVGShapeElement(data, globalData, comp) {
     // List of drawable elements
-    this.shapes = []; // Full shape data
-
-    this.shapesData = data.shapes; // List of styles that will be applied to shapes
-
-    this.stylesList = []; // List of modifiers that will be applied to shapes
-
-    this.shapeModifiers = []; // List of items in shape tree
-
-    this.itemsData = []; // List of items in previous shape tree
-
-    this.processedElements = []; // List of animated components
-
+    this.shapes = [];
+    // Full shape data
+    this.shapesData = data.shapes;
+    // List of styles that will be applied to shapes
+    this.stylesList = [];
+    // List of modifiers that will be applied to shapes
+    this.shapeModifiers = [];
+    // List of items in shape tree
+    this.itemsData = [];
+    // List of items in previous shape tree
+    this.processedElements = [];
+    // List of animated components
     this.animatedContents = [];
-    this.initElement(data, globalData, comp); // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.initElement(data, globalData, comp);
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
     // List of elements that have been created
-
-    this.prevViewData = []; // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.prevViewData = [];
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
-
   SVGShapeElement.prototype.initSecondaryElement = function () {};
-
   SVGShapeElement.prototype.identityMatrix = new Matrix();
-
   SVGShapeElement.prototype.buildExpressionInterface = function () {};
-
   SVGShapeElement.prototype.createContent = function () {
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
   };
+
   /*
   This method searches for multiple shapes that affect a single element and one of them is animated
   */
-
-
   SVGShapeElement.prototype.filterUniqueShapes = function () {
     var i;
     var len = this.shapes.length;
@@ -10064,42 +8515,34 @@
     var style;
     var tempShapes = [];
     var areAnimated = false;
-
     for (j = 0; j < jLen; j += 1) {
       style = this.stylesList[j];
       areAnimated = false;
       tempShapes.length = 0;
-
       for (i = 0; i < len; i += 1) {
         shape = this.shapes[i];
-
         if (shape.styles.indexOf(style) !== -1) {
           tempShapes.push(shape);
           areAnimated = shape._isAnimated || areAnimated;
         }
       }
-
       if (tempShapes.length > 1 && areAnimated) {
         this.setShapesAsAnimated(tempShapes);
       }
     }
   };
-
   SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
     var i;
     var len = shapes.length;
-
     for (i = 0; i < len; i += 1) {
       shapes[i].setAsAnimated();
     }
   };
-
   SVGShapeElement.prototype.createStyleElement = function (data, level) {
     // TODO: prevent drawing of hidden styles
     var elementData;
     var styleOb = new SVGStyleData(data, level);
     var pathElement = styleOb.pElem;
-
     if (data.ty === 'st') {
       elementData = new SVGStrokeStyleData(this, data, styleOb);
     } else if (data.ty === 'fl') {
@@ -10108,7 +8551,6 @@
       var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
       elementData = new GradientConstructor(this, data, styleOb);
       this.globalData.defs.appendChild(elementData.gf);
-
       if (elementData.maskId) {
         this.globalData.defs.appendChild(elementData.ms);
         this.globalData.defs.appendChild(elementData.of);
@@ -10117,66 +8559,51 @@
     } else if (data.ty === 'no') {
       elementData = new SVGNoStyleData(this, data, styleOb);
     }
-
     if (data.ty === 'st' || data.ty === 'gs') {
       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);
       }
     }
-
     if (data.r === 2) {
       pathElement.setAttribute('fill-rule', 'evenodd');
     }
-
     if (data.ln) {
       pathElement.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       pathElement.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     this.stylesList.push(styleOb);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createGroupElement = function (data) {
     var elementData = new ShapeGroupData();
-
     if (data.ln) {
       elementData.gr.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       elementData.gr.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     return elementData;
   };
-
   SVGShapeElement.prototype.createTransformElement = function (data, container) {
     var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
     var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
     var ty = 4;
-
     if (data.ty === 'rc') {
       ty = 5;
     } else if (data.ty === 'el') {
@@ -10184,7 +8611,6 @@
     } else if (data.ty === 'sr') {
       ty = 7;
     }
-
     var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
     var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
     this.shapes.push(elementData);
@@ -10192,58 +8618,46 @@
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
     var i = 0;
     var len = this.animatedContents.length;
-
     while (i < len) {
       if (this.animatedContents[i].element === element) {
         return;
       }
-
       i += 1;
     }
-
     this.animatedContents.push({
       fn: SVGElementsRenderer.createRenderFunction(data),
       element: element,
       data: data
     });
   };
-
   SVGShapeElement.prototype.setElementStyles = function (elementData) {
     var arr = elementData.styles;
     var j;
     var jLen = this.stylesList.length;
-
     for (j = 0; j < jLen; j += 1) {
-      if (!this.stylesList[j].closed) {
+      if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
         arr.push(this.stylesList[j]);
       }
     }
   };
-
   SVGShapeElement.prototype.reloadShapes = function () {
     this._isFirstFrame = true;
     var i;
     var len = this.itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       this.prevViewData[i] = this.itemsData[i];
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
     len = this.dynamicProperties.length;
-
     for (i = 0; i < len; i += 1) {
       this.dynamicProperties[i].getValue();
     }
-
     this.renderModifiers();
   };
-
   SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
     var ownTransformers = [].concat(transformers);
     var i;
@@ -10255,43 +8669,35 @@
     var currentTransform;
     var modifier;
     var processedPos;
-
     for (i = len; i >= 0; i -= 1) {
       processedPos = this.searchProcessedElement(arr[i]);
-
       if (!processedPos) {
         arr[i]._render = render;
       } else {
         itemsData[i] = prevViewData[processedPos - 1];
       }
-
       if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
         if (!processedPos) {
           itemsData[i] = this.createStyleElement(arr[i], level);
         } else {
-          itemsData[i].style.closed = false;
+          itemsData[i].style.closed = arr[i].hd;
         }
-
         if (arr[i]._render) {
           if (itemsData[i].style.pElem.parentNode !== container) {
             container.appendChild(itemsData[i].style.pElem);
           }
         }
-
         ownStyles.push(itemsData[i].style);
       } else if (arr[i].ty === 'gr') {
         if (!processedPos) {
           itemsData[i] = this.createGroupElement(arr[i]);
         } else {
           jLen = itemsData[i].it.length;
-
           for (j = 0; j < jLen; j += 1) {
             itemsData[i].prevViewData[j] = itemsData[i].it[j];
           }
         }
-
         this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
-
         if (arr[i]._render) {
           if (itemsData[i].gr.parentNode !== container) {
             container.appendChild(itemsData[i].gr);
@@ -10301,14 +8707,12 @@
         if (!processedPos) {
           itemsData[i] = this.createTransformElement(arr[i], container);
         }
-
         currentTransform = itemsData[i].transform;
         ownTransformers.push(currentTransform);
       } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
         if (!processedPos) {
           itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
         }
-
         this.setElementStyles(itemsData[i]);
       } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
         if (!processedPos) {
@@ -10320,7 +8724,6 @@
           modifier = itemsData[i];
           modifier.closed = false;
         }
-
         ownModifiers.push(modifier);
       } else if (arr[i].ty === 'rp') {
         if (!processedPos) {
@@ -10333,64 +8736,49 @@
           modifier = itemsData[i];
           modifier.closed = true;
         }
-
         ownModifiers.push(modifier);
       }
-
       this.addProcessedElement(arr[i], i + 1);
     }
-
     len = ownStyles.length;
-
     for (i = 0; i < len; i += 1) {
       ownStyles[i].closed = true;
     }
-
     len = ownModifiers.length;
-
     for (i = 0; i < len; i += 1) {
       ownModifiers[i].closed = true;
     }
   };
-
   SVGShapeElement.prototype.renderInnerContent = function () {
     this.renderModifiers();
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       this.stylesList[i].reset();
     }
-
     this.renderShape();
-
     for (i = 0; i < len; i += 1) {
       if (this.stylesList[i]._mdf || this._isFirstFrame) {
         if (this.stylesList[i].msElem) {
-          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d); // Adding M0 0 fixes same mask bug on all browsers
-
+          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+          // Adding M0 0 fixes same mask bug on all browsers
           this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
         }
-
         this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
       }
     }
   };
-
   SVGShapeElement.prototype.renderShape = function () {
     var i;
     var len = this.animatedContents.length;
     var animatedContent;
-
     for (i = 0; i < len; i += 1) {
       animatedContent = this.animatedContents[i];
-
       if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
         animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
       }
     }
   };
-
   SVGShapeElement.prototype.destroy = function () {
     this.destroyBaseElement();
     this.shapesData = null;
@@ -10413,7 +8801,6 @@
       p: true
     };
   }
-
   LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
     this._mdf.o = false;
     this._mdf.sw = false;
@@ -10422,43 +8809,36 @@
     this._mdf.m = false;
     this._mdf.p = false;
     var updated = false;
-
     if (this.o !== o) {
       this.o = o;
       this._mdf.o = true;
       updated = true;
     }
-
     if (this.sw !== sw) {
       this.sw = sw;
       this._mdf.sw = true;
       updated = true;
     }
-
     if (this.sc !== sc) {
       this.sc = sc;
       this._mdf.sc = true;
       updated = true;
     }
-
     if (this.fc !== fc) {
       this.fc = fc;
       this._mdf.fc = true;
       updated = true;
     }
-
     if (this.m !== m) {
       this.m = m;
       this._mdf.m = true;
       updated = true;
     }
-
     if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
       this.p = p;
       this._mdf.p = true;
       updated = true;
     }
-
     return updated;
   };
 
@@ -10469,11 +8849,9 @@
     this.kf = false;
     this._isFirstFrame = true;
     this._mdf = false;
-
     if (data.d && data.d.sid) {
       data.d = elem.globalData.slotManager.getProp(data.d);
     }
-
     this.data = data;
     this.elem = elem;
     this.comp = this.elem.comp;
@@ -10512,73 +8890,57 @@
       __complete: false
     };
     this.copyData(this.currentData, this.data.d.k[0].s);
-
     if (!this.searchProperty()) {
       this.completeTextData(this.currentData);
     }
   }
-
   TextProperty.prototype.defaultBoxWidth = [0, 0];
-
   TextProperty.prototype.copyData = function (obj, data) {
     for (var s in data) {
       if (Object.prototype.hasOwnProperty.call(data, s)) {
         obj[s] = data[s];
       }
     }
-
     return obj;
   };
-
   TextProperty.prototype.setCurrentData = function (data) {
     if (!data.__complete) {
       this.completeTextData(data);
     }
-
     this.currentData = data;
     this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
     this._mdf = true;
   };
-
   TextProperty.prototype.searchProperty = function () {
     return this.searchKeyframes();
   };
-
   TextProperty.prototype.searchKeyframes = function () {
     this.kf = this.data.d.k.length > 1;
-
     if (this.kf) {
       this.addEffect(this.getKeyframeValue.bind(this));
     }
-
     return this.kf;
   };
-
   TextProperty.prototype.addEffect = function (effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.getValue = function (_finalValue) {
     if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
       return;
     }
-
     this.currentData.t = this.data.d.k[this.keysIndex].s.t;
     var currentValue = this.currentData;
     var currentIndex = this.keysIndex;
-
     if (this.lock) {
       this.setCurrentData(this.currentData);
       return;
     }
-
     this.lock = true;
     this._mdf = false;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
-
     for (i = 0; i < len; i += 1) {
       // Checking if index changed to prevent creating a new object every time the expression updates.
       if (currentIndex !== this.keysIndex) {
@@ -10587,38 +8949,30 @@
         finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
       }
     }
-
     if (currentValue !== finalValue) {
       this.setCurrentData(finalValue);
     }
-
     this.v = this.currentData;
     this.pv = this.v;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   };
-
   TextProperty.prototype.getKeyframeValue = function () {
     var textKeys = this.data.d.k;
     var frameNum = this.elem.comp.renderedFrame;
     var i = 0;
     var len = textKeys.length;
-
     while (i <= len - 1) {
       if (i === len - 1 || textKeys[i + 1].t > frameNum) {
         break;
       }
-
       i += 1;
     }
-
     if (this.keysIndex !== i) {
       this.keysIndex = i;
     }
-
     return this.data.d.k[this.keysIndex].s;
   };
-
   TextProperty.prototype.buildFinalText = function (text) {
     var charactersArray = [];
     var i = 0;
@@ -10628,21 +8982,20 @@
     var shouldCombine = false;
     var shouldCombineNext = false;
     var currentChars = '';
-
     while (i < len) {
       shouldCombine = shouldCombineNext;
       shouldCombineNext = false;
       charCode = text.charCodeAt(i);
       currentChars = text.charAt(i);
-
       if (FontManager.isCombinedCharacter(charCode)) {
-        shouldCombine = true; // It's a potential surrogate pair (this is the High surrogate)
+        shouldCombine = true;
+        // It's a potential surrogate pair (this is the High surrogate)
       } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
         if (FontManager.isRegionalFlag(text, i)) {
           currentChars = text.substr(i, 14);
         } else {
-          secondCharCode = text.charCodeAt(i + 1); // It's a surrogate pair (this is the Low surrogate)
-
+          secondCharCode = text.charCodeAt(i + 1);
+          // It's a surrogate pair (this is the Low surrogate)
           if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
             if (FontManager.isModifier(charCode, secondCharCode)) {
               currentChars = text.substr(i, 2);
@@ -10656,7 +9009,6 @@
         }
       } else if (charCode > 0xDBFF) {
         secondCharCode = text.charCodeAt(i + 1);
-
         if (FontManager.isVariationSelector(charCode)) {
           shouldCombine = true;
         }
@@ -10664,20 +9016,16 @@
         shouldCombine = true;
         shouldCombineNext = true;
       }
-
       if (shouldCombine) {
         charactersArray[charactersArray.length - 1] += currentChars;
         shouldCombine = false;
       } else {
         charactersArray.push(currentChars);
       }
-
       i += currentChars.length;
     }
-
     return charactersArray;
   };
-
   TextProperty.prototype.completeTextData = function (documentData) {
     documentData.__complete = true;
     var fontManager = this.elem.globalData.fontManager;
@@ -10709,14 +9057,12 @@
     documentData.finalLineHeight = documentData.lh;
     var trackingOffset = documentData.tr / 1000 * documentData.finalSize;
     var charCode;
-
     if (documentData.sz) {
       var flag = true;
       var boxWidth = documentData.sz[0];
       var boxHeight = documentData.sz[1];
       var currentHeight;
       var finalText;
-
       while (flag) {
         finalText = this.buildFinalText(documentData.t);
         currentHeight = 0;
@@ -10724,11 +9070,9 @@
         len = finalText.length;
         trackingOffset = documentData.tr / 1000 * documentData.finalSize;
         var lastSpaceIndex = -1;
-
         for (i = 0; i < len; i += 1) {
           charCode = finalText[i].charCodeAt(0);
           newLineFlag = false;
-
           if (finalText[i] === ' ') {
             lastSpaceIndex = i;
           } else if (charCode === 13 || charCode === 3) {
@@ -10736,7 +9080,6 @@
             newLineFlag = true;
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
           }
-
           if (fontManager.chars) {
             charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
             cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -10744,17 +9087,15 @@
             // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
             cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
           }
-
           if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
             if (lastSpaceIndex === -1) {
               len += 1;
             } else {
               i = lastSpaceIndex;
             }
-
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
-            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r'); // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
-
+            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+            // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
             lastSpaceIndex = -1;
             lineWidth = 0;
           } else {
@@ -10762,9 +9103,7 @@
             lineWidth += trackingOffset;
           }
         }
-
         currentHeight += fontData.ascent * documentData.finalSize / 100;
-
         if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
           documentData.finalSize -= 1;
           documentData.finalLineHeight = documentData.finalSize * documentData.lh / documentData.s;
@@ -10775,17 +9114,14 @@
         }
       }
     }
-
     lineWidth = -trackingOffset;
     cLength = 0;
     var uncollapsedSpaces = 0;
     var currentChar;
-
     for (i = 0; i < len; i += 1) {
       newLineFlag = false;
       currentChar = documentData.finalText[i];
       charCode = currentChar.charCodeAt(0);
-
       if (charCode === 13 || charCode === 3) {
         uncollapsedSpaces = 0;
         lineWidths.push(lineWidth);
@@ -10797,7 +9133,6 @@
       } else {
         val = currentChar;
       }
-
       if (fontManager.chars) {
         charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
         cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -10805,16 +9140,15 @@
         // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
         // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
         cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
-      } //
+      }
 
-
+      //
       if (currentChar === ' ') {
         uncollapsedSpaces += cLength + trackingOffset;
       } else {
         lineWidth += cLength + trackingOffset + uncollapsedSpaces;
         uncollapsedSpaces = 0;
       }
-
       letters.push({
         l: cLength,
         an: cLength,
@@ -10825,42 +9159,35 @@
         line: currentLine,
         animatorJustifyOffset: 0
       });
-
       if (anchorGrouping == 2) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || val === ' ' || i === len - 1) {
           if (val === '' || val === ' ') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           index += 1;
           currentSize = 0;
         }
       } else if (anchorGrouping == 3) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || i === len - 1) {
           if (val === '') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           currentSize = 0;
           index += 1;
         }
@@ -10870,31 +9197,25 @@
         index += 1;
       }
     }
-
     documentData.l = letters;
     maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
     lineWidths.push(lineWidth);
-
     if (documentData.sz) {
       documentData.boxWidth = documentData.sz[0];
       documentData.justifyOffset = 0;
     } else {
       documentData.boxWidth = maxLineWidth;
-
       switch (documentData.j) {
         case 1:
           documentData.justifyOffset = -documentData.boxWidth;
           break;
-
         case 2:
           documentData.justifyOffset = -documentData.boxWidth / 2;
           break;
-
         default:
           documentData.justifyOffset = 0;
       }
     }
-
     documentData.lineWidths = lineWidths;
     var animators = data.a;
     var animatorData;
@@ -10903,63 +9224,49 @@
     var based;
     var ind;
     var indexes = [];
-
     for (j = 0; j < jLen; j += 1) {
       animatorData = animators[j];
-
       if (animatorData.a.sc) {
         documentData.strokeColorAnim = true;
       }
-
       if (animatorData.a.sw) {
         documentData.strokeWidthAnim = true;
       }
-
       if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
         documentData.fillColorAnim = true;
       }
-
       ind = 0;
       based = animatorData.s.b;
-
       for (i = 0; i < len; i += 1) {
         letterData = letters[i];
         letterData.anIndexes[j] = ind;
-
         if (based == 1 && letterData.val !== '' || based == 2 && letterData.val !== '' && letterData.val !== ' ' || based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1) || based == 4 && (letterData.n || i == len - 1)) {
           // eslint-disable-line eqeqeq
           if (animatorData.s.rn === 1) {
             indexes.push(ind);
           }
-
           ind += 1;
         }
       }
-
       data.a[j].s.totalChars = ind;
       var currentInd = -1;
       var newInd;
-
       if (animatorData.s.rn === 1) {
         for (i = 0; i < len; i += 1) {
           letterData = letters[i];
-
           if (currentInd != letterData.anIndexes[j]) {
             // eslint-disable-line eqeqeq
             currentInd = letterData.anIndexes[j];
             newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
           }
-
           letterData.anIndexes[j] = newInd;
         }
       }
     }
-
     documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
     documentData.ls = documentData.ls || 0;
     documentData.ascent = fontData.ascent * documentData.finalSize / 100;
   };
-
   TextProperty.prototype.updateDocumentData = function (newData, index) {
     index = index === undefined ? this.keysIndex : index;
     var dData = this.copyData({}, this.data.d.k[index].s);
@@ -10969,7 +9276,6 @@
     this.setCurrentData(dData);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.recalculate = function (index) {
     var dData = this.data.d.k[index].s;
     dData.__complete = false;
@@ -10977,13 +9283,11 @@
     this._isFirstFrame = true;
     this.getValue(dData);
   };
-
   TextProperty.prototype.canResizeFont = function (_canResize) {
     this.canResize = _canResize;
     this.recalculate(this.keysIndex);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
     this.minimumFontSize = Math.floor(_fontValue) || 1;
     this.recalculate(this.keysIndex);
@@ -10994,7 +9298,6 @@
     var max = Math.max;
     var min = Math.min;
     var floor = Math.floor;
-
     function TextSelectorPropFactory(elem, data) {
       this._currentTextLength = -1;
       this.k = false;
@@ -11007,7 +9310,6 @@
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: 0
       }, 0, 0, this);
-
       if ('e' in data) {
         this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
       } else {
@@ -11015,7 +9317,6 @@
           v: 100
         };
       }
-
       this.o = PropertyFactory.getProp(elem, data.o || {
         k: 0
       }, 0, 0, this);
@@ -11029,48 +9330,40 @@
         k: 100
       }, 0, 0, this);
       this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
-
       if (!this.dynamicProperties.length) {
         this.getValue();
       }
     }
-
     TextSelectorPropFactory.prototype = {
       getMult: function getMult(ind) {
         if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
           this.getValue();
         }
-
         var x1 = 0;
         var y1 = 0;
         var x2 = 1;
         var y2 = 1;
-
         if (this.ne.v > 0) {
           x1 = this.ne.v / 100.0;
         } else {
           y1 = -this.ne.v / 100.0;
         }
-
         if (this.xe.v > 0) {
           x2 = 1.0 - this.xe.v / 100.0;
         } else {
           y2 = 1.0 + this.xe.v / 100.0;
         }
-
         var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
         var mult = 0;
         var s = this.finalS;
         var e = this.finalE;
         var type = this.data.sh;
-
         if (type === 2) {
           if (e === s) {
             mult = ind >= e ? 1 : 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 3) {
           if (e === s) {
@@ -11078,21 +9371,18 @@
           } else {
             mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 4) {
           if (e === s) {
             mult = 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
-
             if (mult < 0.5) {
               mult *= 2;
             } else {
               mult = 1 - 2 * (mult - 0.5);
             }
           }
-
           mult = easer(mult);
         } else if (type === 5) {
           if (e === s) {
@@ -11101,13 +9391,11 @@
             var tot = e - s;
             /* ind += 0.5;
                       mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
-
             ind = min(max(0, ind + 0.5 - s), e - s);
             var x = -tot / 2 + ind;
             var a = tot / 2;
             mult = Math.sqrt(1 - x * x / (a * a));
           }
-
           mult = easer(mult);
         } else if (type === 6) {
           if (e === s) {
@@ -11116,7 +9404,6 @@
             ind = min(max(0, ind + 0.5 - s), e - s);
             mult = (1 + Math.cos(Math.PI + Math.PI * 2 * ind / (e - s))) / 2; // eslint-disable-line
           }
-
           mult = easer(mult);
         } else {
           if (ind >= floor(s)) {
@@ -11126,9 +9413,9 @@
               mult = max(0, min(e - ind, 1));
             }
           }
-
           mult = easer(mult);
-        } // Smoothness implementation.
+        }
+        // Smoothness implementation.
         // The smoothness represents a reduced range of the original [0; 1] range.
         // if smoothness is 25%, the new range will be [0.375; 0.625]
         // Steps are:
@@ -11138,60 +9425,47 @@
         //     - subtract the threshold
         //     - divide it by the smoothness (this will return the range to [0; 1])
         // Note: If it doesn't work on some scenarios, consider applying it before the easer.
-
-
         if (this.sm.v !== 100) {
           var smoothness = this.sm.v * 0.01;
-
           if (smoothness === 0) {
             smoothness = 0.00000001;
           }
-
           var threshold = 0.5 - smoothness * 0.5;
-
           if (mult < threshold) {
             mult = 0;
           } else {
             mult = (mult - threshold) / smoothness;
-
             if (mult > 1) {
               mult = 1;
             }
           }
         }
-
         return mult * this.a.v;
       },
       getValue: function getValue(newCharsFlag) {
         this.iterateDynamicProperties();
         this._mdf = newCharsFlag || this._mdf;
         this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
-
         if (newCharsFlag && this.data.r === 2) {
           this.e.v = this._currentTextLength;
         }
-
         var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
         var o = this.o.v / divisor;
         var s = this.s.v / divisor + o;
         var e = this.e.v / divisor + o;
-
         if (s > e) {
           var _s = s;
           s = e;
           e = _s;
         }
-
         this.finalS = s;
         this.finalE = e;
       }
     };
     extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
-
     function getTextSelectorProp(elem, data, arr) {
       return new TextSelectorPropFactory(elem, data, arr);
     }
-
     return {
       getTextSelectorProp: getTextSelectorProp
     };
@@ -11241,18 +9515,15 @@
     this.lettersChangedFlag = false;
     this.initDynamicPropertyContainer(elem);
   }
-
   TextAnimatorProperty.prototype.searchProperties = function () {
     var i;
     var len = this._textData.a.length;
     var animatorProps;
     var getProp = PropertyFactory.getProp;
-
     for (i = 0; i < len; i += 1) {
       animatorProps = this._textData.a[i];
       this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
     }
-
     if (this._textData.p && 'm' in this._textData.p) {
       this._pathData = {
         a: getProp(this._elem, this._textData.p.a, 0, 0, this),
@@ -11266,17 +9537,13 @@
     } else {
       this._hasMaskedPath = false;
     }
-
     this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
   };
-
   TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
     this.lettersChangedFlag = lettersChangedFlag;
-
     if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
       return;
     }
-
     this._isFirstFrame = false;
     var alignment = this._moreOptions.alignment.v;
     var animators = this._animatorsData;
@@ -11304,18 +9571,14 @@
     var perc;
     var tanAngle;
     var mask;
-
     if (this._hasMaskedPath) {
       mask = this._pathData.m;
-
       if (!this._pathData.n || this._pathData._mdf) {
         var paths = mask.v;
-
         if (this._pathData.r.v) {
           paths = paths.reverse();
-        } // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
-
-
+        }
+        // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
         pathInfo = {
           tLength: 0,
           segments: []
@@ -11323,26 +9586,21 @@
         len = paths._length - 1;
         var bezierData;
         totalLength = 0;
-
         for (i = 0; i < len; i += 1) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[i + 1], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         i = len;
-
         if (mask.v.c) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[0], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         this._pathData.pi = pathInfo;
       }
-
       pathInfo = this._pathData.pi;
       currentLength = this._pathData.f.v;
       segmentInd = 0;
@@ -11350,20 +9608,16 @@
       segmentLength = 0;
       flag = true;
       segments = pathInfo.segments;
-
       if (currentLength < 0 && mask.v.c) {
         if (pathInfo.tLength < Math.abs(currentLength)) {
           currentLength = -Math.abs(currentLength) % pathInfo.tLength;
         }
-
         segmentInd = segments.length - 1;
         points = segments[segmentInd].points;
         pointInd = points.length - 1;
-
         while (currentLength < 0) {
           currentLength += points[pointInd].partialLength;
           pointInd -= 1;
-
           if (pointInd < 0) {
             segmentInd -= 1;
             points = segments[segmentInd].points;
@@ -11371,13 +9625,11 @@
           }
         }
       }
-
       points = segments[segmentInd].points;
       prevPoint = points[pointInd - 1];
       currentPoint = points[pointInd];
       partialLength = currentPoint.partialLength;
     }
-
     len = letters.length;
     xPos = 0;
     yPos = 0;
@@ -11408,40 +9660,35 @@
     var letterFc;
     var letterM = '';
     var letterP = this.defaultPropsArray;
-    var letterO; //
+    var letterO;
 
+    //
     if (documentData.j === 2 || documentData.j === 1) {
       var animatorJustifyOffset = 0;
       var animatorFirstCharOffset = 0;
       var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
       var lastIndex = 0;
       var isNewLine = true;
-
       for (i = 0; i < len; i += 1) {
         if (letters[i].n) {
           if (animatorJustifyOffset) {
             animatorJustifyOffset += animatorFirstCharOffset;
           }
-
           while (lastIndex < i) {
             letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
             lastIndex += 1;
           }
-
           animatorJustifyOffset = 0;
           isNewLine = true;
         } else {
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.t.propType) {
               if (isNewLine && documentData.j === 2) {
                 animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
               }
-
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
               } else {
@@ -11449,33 +9696,28 @@
               }
             }
           }
-
           isNewLine = false;
         }
       }
-
       if (animatorJustifyOffset) {
         animatorJustifyOffset += animatorFirstCharOffset;
       }
-
       while (lastIndex < i) {
         letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
         lastIndex += 1;
       }
-    } //
-
+    }
+    //
 
     for (i = 0; i < len; i += 1) {
       matrixHelper.reset();
       elemOpacity = 1;
-
       if (letters[i].n) {
         xPos = 0;
         yPos += documentData.yOffset;
         yPos += firstLine ? 1 : 0;
         currentLength = initPathPos;
         firstLine = false;
-
         if (this._hasMaskedPath) {
           segmentInd = initSegmentInd;
           pointInd = initPointInd;
@@ -11485,7 +9727,6 @@
           partialLength = currentPoint.partialLength;
           segmentLength = 0;
         }
-
         letterM = '';
         letterFc = '';
         letterSw = '';
@@ -11498,48 +9739,37 @@
               case 1:
                 currentLength += totalLength - documentData.lineWidths[letters[i].line];
                 break;
-
               case 2:
                 currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
                 break;
-
               default:
                 break;
             }
-
             currentLine = letters[i].line;
           }
-
           if (ind !== letters[i].ind) {
             if (letters[ind]) {
               currentLength += letters[ind].extra;
             }
-
             currentLength += letters[i].an / 2;
             ind = letters[i].ind;
           }
-
           currentLength += alignment[0] * letters[i].an * 0.005;
           var animatorOffset = 0;
-
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.p.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.p.v[0] * mult[0];
               } else {
                 animatorOffset += animatorProps.p.v[0] * mult;
               }
             }
-
             if (animatorProps.a.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.a.v[0] * mult[0];
               } else {
@@ -11547,14 +9777,12 @@
               }
             }
           }
-
-          flag = true; // Force alignment only works with a single line for now
-
+          flag = true;
+          // Force alignment only works with a single line for now
           if (this._pathData.a.v) {
             currentLength = letters[0].an * 0.5 + (totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind / (len - 1);
             currentLength += this._pathData.f.v;
           }
-
           while (flag) {
             if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
               perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
@@ -11565,11 +9793,9 @@
             } else if (points) {
               segmentLength += currentPoint.partialLength;
               pointInd += 1;
-
               if (pointInd >= points.length) {
                 pointInd = 0;
                 segmentInd += 1;
-
                 if (!segments[segmentInd]) {
                   if (mask.v.c) {
                     pointInd = 0;
@@ -11583,7 +9809,6 @@
                   points = segments[segmentInd].points;
                 }
               }
-
               if (points) {
                 prevPoint = currentPoint;
                 currentPoint = points[pointInd];
@@ -11591,23 +9816,21 @@
               }
             }
           }
-
           offf = letters[i].an / 2 - letters[i].add;
           matrixHelper.translate(-offf, 0, 0);
         } else {
           offf = letters[i].an / 2 - letters[i].add;
-          matrixHelper.translate(-offf, 0, 0); // Grouping alignment
+          matrixHelper.translate(-offf, 0, 0);
 
+          // Grouping alignment
           matrixHelper.translate(-alignment[0] * letters[i].an * 0.005, -alignment[1] * yOff * 0.01, 0);
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.t.propType) {
             animatorSelector = animators[j].s;
-            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars); // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
-
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
             if (xPos !== 0 || documentData.j !== 0) {
               if (this._hasMaskedPath) {
                 if (mult.length) {
@@ -11623,11 +9846,9 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           sw = documentData.sw || 0;
         }
-
         if (documentData.strokeColorAnim) {
           if (documentData.sc) {
             sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
@@ -11635,18 +9856,14 @@
             sc = [0, 0, 0];
           }
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.a.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
             } else {
@@ -11654,14 +9871,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.s.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.scale(1 + (animatorProps.s.v[0] - 1) * mult[0], 1 + (animatorProps.s.v[1] - 1) * mult[1], 1);
             } else {
@@ -11669,12 +9883,10 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
           animatorSelector = animators[j].s;
           mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
           if (animatorProps.sk.propType) {
             if (mult.length) {
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
@@ -11682,7 +9894,6 @@
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
             }
           }
-
           if (animatorProps.r.propType) {
             if (mult.length) {
               matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
@@ -11690,7 +9901,6 @@
               matrixHelper.rotateZ(-animatorProps.r.v * mult);
             }
           }
-
           if (animatorProps.ry.propType) {
             if (mult.length) {
               matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
@@ -11698,7 +9908,6 @@
               matrixHelper.rotateY(animatorProps.ry.v * mult);
             }
           }
-
           if (animatorProps.rx.propType) {
             if (mult.length) {
               matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
@@ -11706,7 +9915,6 @@
               matrixHelper.rotateX(animatorProps.rx.v * mult);
             }
           }
-
           if (animatorProps.o.propType) {
             if (mult.length) {
               elemOpacity += (animatorProps.o.v * mult[0] - elemOpacity) * mult[0];
@@ -11714,7 +9922,6 @@
               elemOpacity += (animatorProps.o.v * mult - elemOpacity) * mult;
             }
           }
-
           if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
             if (mult.length) {
               sw += animatorProps.sw.v * mult[0];
@@ -11722,7 +9929,6 @@
               sw += animatorProps.sw.v * mult;
             }
           }
-
           if (documentData.strokeColorAnim && animatorProps.sc.propType) {
             for (k = 0; k < 3; k += 1) {
               if (mult.length) {
@@ -11732,7 +9938,6 @@
               }
             }
           }
-
           if (documentData.fillColorAnim && documentData.fc) {
             if (animatorProps.fc.propType) {
               for (k = 0; k < 3; k += 1) {
@@ -11743,7 +9948,6 @@
                 }
               }
             }
-
             if (animatorProps.fh.propType) {
               if (mult.length) {
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
@@ -11751,7 +9955,6 @@
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult);
               }
             }
-
             if (animatorProps.fs.propType) {
               if (mult.length) {
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
@@ -11759,7 +9962,6 @@
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
               }
             }
-
             if (animatorProps.fb.propType) {
               if (mult.length) {
                 fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
@@ -11769,14 +9971,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.p.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (this._hasMaskedPath) {
               if (mult.length) {
                 matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
@@ -11790,68 +9989,53 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           letterSw = sw < 0 ? 0 : sw;
         }
-
         if (documentData.strokeColorAnim) {
           letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
         }
-
         if (this._hasMaskedPath) {
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(0, alignment[1] * yOff * 0.01 + yPos, 0);
-
           if (this._pathData.p.v) {
             tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
             var rot = Math.atan(tanAngle) * 180 / Math.PI;
-
             if (currentPoint.point[0] < prevPoint.point[0]) {
               rot += 180;
             }
-
             matrixHelper.rotate(-rot * Math.PI / 180);
           }
-
           matrixHelper.translate(xPathPos, yPathPos, 0);
           currentLength -= alignment[0] * letters[i].an * 0.005;
-
           if (letters[i + 1] && ind !== letters[i + 1].ind) {
             currentLength += letters[i].an / 2;
             currentLength += documentData.tr * 0.001 * documentData.finalSize;
           }
         } else {
           matrixHelper.translate(xPos, yPos, 0);
-
           if (documentData.ps) {
             // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
             matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
           }
-
           switch (documentData.j) {
             case 1:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
               break;
-
             case 2:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
               break;
-
             default:
               break;
           }
-
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(offf, 0, 0);
           matrixHelper.translate(alignment[0] * letters[i].an * 0.005, alignment[1] * yOff * 0.01, 0);
           xPos += letters[i].l + documentData.tr * 0.001 * documentData.finalSize;
         }
-
         if (renderType === 'html') {
           letterM = matrixHelper.toCSS();
         } else if (renderType === 'svg') {
@@ -11859,10 +10043,8 @@
         } else {
           letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
         }
-
         letterO = elemOpacity;
       }
-
       if (renderedLettersCount <= i) {
         letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
         this.renderedLetters.push(letterValue);
@@ -11874,22 +10056,18 @@
       }
     }
   };
-
   TextAnimatorProperty.prototype.getValue = function () {
     if (this._elem.globalData.frameId === this._frameId) {
       return;
     }
-
     this._frameId = this._elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   TextAnimatorProperty.prototype.mHelper = new Matrix();
   TextAnimatorProperty.prototype.defaultPropsArray = [];
   extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
 
   function ITextElement() {}
-
   ITextElement.prototype.initElement = function (data, globalData, comp) {
     this.lettersChangedFlag = true;
     this.initFrame();
@@ -11906,72 +10084,55 @@
     this.hide();
     this.textAnimator.searchProperties(this.dynamicProperties);
   };
-
   ITextElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
   };
-
   ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
     var j;
     var jLen = shapes.length;
     var pathNodes;
     var shapeStr = '';
-
     for (j = 0; j < jLen; j += 1) {
       if (shapes[j].ty === 'sh') {
         pathNodes = shapes[j].ks.k;
         shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
       }
     }
-
     return shapeStr;
   };
-
   ITextElement.prototype.updateDocumentData = function (newData, index) {
     this.textProperty.updateDocumentData(newData, index);
   };
-
   ITextElement.prototype.canResizeFont = function (_canResize) {
     this.textProperty.canResizeFont(_canResize);
   };
-
   ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
     this.textProperty.setMinimumFontSize(_fontSize);
   };
-
   ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
     if (documentData.ps) {
       matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
     }
-
     matrixHelper.translate(0, -documentData.ls, 0);
-
     switch (documentData.j) {
       case 1:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
         break;
-
       case 2:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
         break;
-
       default:
         break;
     }
-
     matrixHelper.translate(xPos, yPos, 0);
   };
-
   ITextElement.prototype.buildColor = function (colorData) {
     return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
   };
-
   ITextElement.prototype.emptyProp = new LetterProps();
-
   ITextElement.prototype.destroy = function () {};
-
   ITextElement.prototype.validateText = function () {
     if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
       this.buildNewText();
@@ -11983,27 +10144,22 @@
   var emptyShapeData = {
     shapes: []
   };
-
   function SVGTextLottieElement(data, globalData, comp) {
     this.textSpans = [];
     this.renderType = 'svg';
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
-
   SVGTextLottieElement.prototype.createContent = function () {
     if (this.data.singleShape && !this.globalData.fontManager.chars) {
       this.textContainer = createNS('text');
     }
   };
-
   SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
     var i = 0;
     var len = textArray.length;
     var textContents = [];
     var currentTextContent = '';
-
     while (i < len) {
       if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
         textContents.push(currentTextContent);
@@ -12011,14 +10167,11 @@
       } else {
         currentTextContent += textArray[i];
       }
-
       i += 1;
     }
-
     textContents.push(currentTextContent);
     return textContents;
   };
-
   SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
     // data should probably be cloned to apply scale separately to each instance of a text on different layers
     // but since text internal content gets only rendered once and then it's never rerendered,
@@ -12026,41 +10179,33 @@
     // Avoiding cloning is preferred since cloning each character shape data is expensive
     if (data.shapes && data.shapes.length) {
       var shape = data.shapes[0];
-
       if (shape.it) {
         var shapeItem = shape.it[shape.it.length - 1];
-
         if (shapeItem.s) {
           shapeItem.s.k[0] = scale;
           shapeItem.s.k[1] = scale;
         }
       }
     }
-
     return data;
   };
-
   SVGTextLottieElement.prototype.buildNewText = function () {
     this.addDynamicProperty(this);
     var i;
     var len;
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
-
     if (documentData.fc) {
       this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
     } else {
       this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
     }
-
     if (documentData.sc) {
       this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
       this.layerElement.setAttribute('stroke-width', documentData.sw);
     }
-
     this.layerElement.setAttribute('font-size', documentData.finalSize);
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
-
     if (fontData.fClass) {
       this.layerElement.setAttribute('class', fontData.fClass);
     } else {
@@ -12070,7 +10215,6 @@
       this.layerElement.setAttribute('font-style', fStyle);
       this.layerElement.setAttribute('font-weight', fWeight);
     }
-
     this.layerElement.setAttribute('aria-label', documentData.t);
     var letters = documentData.l || [];
     var usesGlyphs = !!this.globalData.fontManager.chars;
@@ -12083,31 +10227,25 @@
     var yPos = 0;
     var firstLine = true;
     var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
-
     if (singleShape && !usesGlyphs && !documentData.sz) {
       var tElement = this.textContainer;
       var justify = 'start';
-
       switch (documentData.j) {
         case 1:
           justify = 'end';
           break;
-
         case 2:
           justify = 'middle';
           break;
-
         default:
           justify = 'start';
           break;
       }
-
       tElement.setAttribute('text-anchor', justify);
       tElement.setAttribute('letter-spacing', trackingOffset);
       var textContent = this.buildTextContents(documentData.finalText);
       len = textContent.length;
       yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
-
       for (i = 0; i < len; i += 1) {
         tSpan = this.textSpans[i].span || createNS('tspan');
         tSpan.textContent = textContent[i];
@@ -12115,23 +10253,19 @@
         tSpan.setAttribute('y', yPos);
         tSpan.style.display = 'inherit';
         tElement.appendChild(tSpan);
-
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
             span: null,
             glyph: null
           };
         }
-
         this.textSpans[i].span = tSpan;
         yPos += documentData.finalLineHeight;
       }
-
       this.layerElement.appendChild(tElement);
     } else {
       var cachedSpansLength = this.textSpans.length;
       var charData;
-
       for (i = 0; i < len; i += 1) {
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
@@ -12140,31 +10274,24 @@
             glyph: null
           };
         }
-
         if (!usesGlyphs || !singleShape || i === 0) {
           tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
-
           if (cachedSpansLength <= i) {
             tSpan.setAttribute('stroke-linecap', 'butt');
             tSpan.setAttribute('stroke-linejoin', 'round');
             tSpan.setAttribute('stroke-miterlimit', '4');
             this.textSpans[i].span = tSpan;
-
             if (usesGlyphs) {
               var childSpan = createNS('g');
               tSpan.appendChild(childSpan);
               this.textSpans[i].childSpan = childSpan;
             }
-
             this.textSpans[i].span = tSpan;
             this.layerElement.appendChild(tSpan);
           }
-
           tSpan.style.display = 'inherit';
         }
-
         matrixHelper.reset();
-
         if (singleShape) {
           if (letters[i].n) {
             xPos = -trackingOffset;
@@ -12172,42 +10299,36 @@
             yPos += firstLine ? 1 : 0;
             firstLine = false;
           }
-
           this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
-          xPos += letters[i].l || 0; // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
-
+          xPos += letters[i].l || 0;
+          // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
           xPos += trackingOffset;
         }
-
         if (usesGlyphs) {
           charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
-          var glyphElement; // t === 1 means the character has been replaced with an animated shaped
-
+          var glyphElement;
+          // t === 1 means the character has been replaced with an animated shaped
           if (charData.t === 1) {
             glyphElement = new SVGCompElement(charData.data, this.globalData, this);
           } else {
             var data = emptyShapeData;
-
             if (charData.data && charData.data.shapes) {
               data = this.buildShapeData(charData.data, documentData.finalSize);
             }
-
             glyphElement = new SVGShapeElement(data, this.globalData, this);
           }
-
           if (this.textSpans[i].glyph) {
             var glyph = this.textSpans[i].glyph;
             this.textSpans[i].childSpan.removeChild(glyph.layerElement);
             glyph.destroy();
           }
-
           this.textSpans[i].glyph = glyphElement;
           glyphElement._debug = true;
           glyphElement.prepareFrame(0);
           glyphElement.renderFrame();
-          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement); // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+          // when using animated shapes, the layer will be scaled instead of replacing the internal scale
           // this might have issues with strokes and might need a different solution
-
           if (charData.t === 1) {
             this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
           }
@@ -12215,30 +10336,24 @@
           if (singleShape) {
             tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
           }
-
           tSpan.textContent = letters[i].val;
           tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
-        } //
-
+        }
+        //
       }
-
       if (singleShape && tSpan) {
         tSpan.setAttribute('d', shapeStr);
       }
     }
-
     while (i < this.textSpans.length) {
       this.textSpans[i].span.style.display = 'none';
       i += 1;
     }
-
     this._sizeChanged = true;
   };
-
   SVGTextLottieElement.prototype.sourceRectAtTime = function () {
     this.prepareFrame(this.comp.renderedFrame - this.data.st);
     this.renderInnerContent();
-
     if (this._sizeChanged) {
       this._sizeChanged = false;
       var textBox = this.layerElement.getBBox();
@@ -12249,35 +10364,27 @@
         height: textBox.height
       };
     }
-
     return this.bbox;
   };
-
   SVGTextLottieElement.prototype.getValue = function () {
     var i;
     var len = this.textSpans.length;
     var glyphElement;
     this.renderedFrame = this.comp.renderedFrame;
-
     for (i = 0; i < len; i += 1) {
       glyphElement = this.textSpans[i].glyph;
-
       if (glyphElement) {
         glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
-
         if (glyphElement._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   SVGTextLottieElement.prototype.renderInnerContent = function () {
     this.validateText();
-
     if (!this.data.singleShape || this._mdf) {
       this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
-
       if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
         this._sizeChanged = true;
         var i;
@@ -12288,33 +10395,26 @@
         var renderedLetter;
         var textSpan;
         var glyphElement;
-
         for (i = 0; i < len; i += 1) {
           if (!letters[i].n) {
             renderedLetter = renderedLetters[i];
             textSpan = this.textSpans[i].span;
             glyphElement = this.textSpans[i].glyph;
-
             if (glyphElement) {
               glyphElement.renderFrame();
             }
-
             if (renderedLetter._mdf.m) {
               textSpan.setAttribute('transform', renderedLetter.m);
             }
-
             if (renderedLetter._mdf.o) {
               textSpan.setAttribute('opacity', renderedLetter.o);
             }
-
             if (renderedLetter._mdf.sw) {
               textSpan.setAttribute('stroke-width', renderedLetter.sw);
             }
-
             if (renderedLetter._mdf.sc) {
               textSpan.setAttribute('stroke', renderedLetter.sc);
             }
-
             if (renderedLetter._mdf.fc) {
               textSpan.setAttribute('fill', renderedLetter.fc);
             }
@@ -12327,14 +10427,12 @@
   function ISolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([IImageElement], ISolidElement);
-
   ISolidElement.prototype.createContent = function () {
-    var rect = createNS('rect'); /// /rect.style.width = this.data.sw;
+    var rect = createNS('rect');
+    /// /rect.style.width = this.data.sw;
     /// /rect.style.height = this.data.sh;
     /// /rect.style.fill = this.data.sc;
-
     rect.setAttribute('width', this.data.sw);
     rect.setAttribute('height', this.data.sh);
     rect.setAttribute('fill', this.data.sc);
@@ -12348,59 +10446,43 @@
     this.initTransform(data, globalData, comp);
     this.initHierarchy();
   }
-
   NullElement.prototype.prepareFrame = function (num) {
     this.prepareProperties(num, true);
   };
-
   NullElement.prototype.renderFrame = function () {};
-
   NullElement.prototype.getBaseElement = function () {
     return null;
   };
-
   NullElement.prototype.destroy = function () {};
-
   NullElement.prototype.sourceRectAtTime = function () {};
-
   NullElement.prototype.hide = function () {};
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
 
   function SVGRendererBase() {}
-
   extendPrototype([BaseRenderer], SVGRendererBase);
-
   SVGRendererBase.prototype.createNull = function (data) {
     return new NullElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createShape = function (data) {
     return new SVGShapeElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createText = function (data) {
     return new SVGTextLottieElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createImage = function (data) {
     return new IImageElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createSolid = function (data) {
     return new ISolidElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.configAnimation = function (animData) {
     this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
     this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
-
     if (this.renderConfig.viewBoxSize) {
       this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
     } else {
       this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
     }
-
     if (!this.renderConfig.viewBoxOnly) {
       this.svgElement.setAttribute('width', animData.w);
       this.svgElement.setAttribute('height', animData.h);
@@ -12409,32 +10491,26 @@
       this.svgElement.style.transform = 'translate3d(0,0,0)';
       this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
     }
-
     if (this.renderConfig.width) {
       this.svgElement.setAttribute('width', this.renderConfig.width);
     }
-
     if (this.renderConfig.height) {
       this.svgElement.setAttribute('height', this.renderConfig.height);
     }
-
     if (this.renderConfig.className) {
       this.svgElement.setAttribute('class', this.renderConfig.className);
     }
-
     if (this.renderConfig.id) {
       this.svgElement.setAttribute('id', this.renderConfig.id);
     }
-
     if (this.renderConfig.focusable !== undefined) {
       this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
     }
-
-    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio); // this.layerElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+    // this.layerElement.style.transform = 'translate3d(0,0,0)';
     // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
-
-    this.animationItem.wrapper.appendChild(this.svgElement); // Mask animation
-
+    this.animationItem.wrapper.appendChild(this.svgElement);
+    // Mask animation
     var defs = this.globalData.defs;
     this.setupGlobalData(animData, defs);
     this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
@@ -12453,71 +10529,54 @@
     this.layers = animData.layers;
     this.elements = createSizedArray(animData.layers.length);
   };
-
   SVGRendererBase.prototype.destroy = function () {
     if (this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     this.layerElement = null;
     this.globalData.defs = null;
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.destroyed = true;
     this.animationItem = null;
   };
-
   SVGRendererBase.prototype.updateContainerSize = function () {};
-
   SVGRendererBase.prototype.findIndexByInd = function (ind) {
     var i = 0;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.layers[i].ind === ind) {
         return i;
       }
     }
-
     return -1;
   };
-
   SVGRendererBase.prototype.buildItem = function (pos) {
     var elements = this.elements;
-
     if (elements[pos] || this.layers[pos].ty === 99) {
       return;
     }
-
     elements[pos] = true;
     var element = this.createItem(this.layers[pos]);
     elements[pos] = element;
-
     if (getExpressionsPlugin()) {
       if (this.layers[pos].ty === 0) {
         this.globalData.projectInterface.registerComposition(element);
       }
-
       element.initExpressions();
     }
-
     this.appendElementInPos(element, pos);
-
     if (this.layers[pos].tt) {
       var elementIndex = 'tp' in this.layers[pos] ? this.findIndexByInd(this.layers[pos].tp) : pos - 1;
-
       if (elementIndex === -1) {
         return;
       }
-
       if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
         this.buildItem(elementIndex);
         this.addPendingElement(element);
@@ -12528,16 +10587,13 @@
       }
     }
   };
-
   SVGRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
-
       if (element.data.tt) {
         var i = 0;
         var len = this.elements.length;
-
         while (i < len) {
           if (this.elements[i] === element) {
             var elementIndex = 'tp' in element.data ? this.findIndexByInd(element.data.tp) : i - 1;
@@ -12546,43 +10602,36 @@
             element.setMatte(matteMask);
             break;
           }
-
           i += 1;
         }
       }
     }
   };
-
   SVGRendererBase.prototype.renderFrame = function (num) {
     if (this.renderedFrame === num || this.destroyed) {
       return;
     }
-
     if (num === null) {
       num = this.renderedFrame;
     } else {
       this.renderedFrame = num;
-    } // console.log('-------');
+    }
+    // console.log('-------');
     // console.log('FRAME ',num);
-
-
     this.globalData.frameNum = num;
     this.globalData.frameId += 1;
     this.globalData.projectInterface.currentFrame = num;
     this.globalData._mdf = false;
     var i;
     var len = this.layers.length;
-
     if (!this.completeLayers) {
       this.checkLayers(num);
     }
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(num - this.layers[i].st);
       }
     }
-
     if (this.globalData._mdf) {
       for (i = 0; i < len; i += 1) {
         if (this.completeLayers || this.elements[i]) {
@@ -12591,44 +10640,34 @@
       }
     }
   };
-
   SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
     var newElement = element.getBaseElement();
-
     if (!newElement) {
       return;
     }
-
     var i = 0;
     var nextElement;
-
     while (i < pos) {
       if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
         nextElement = this.elements[i].getBaseElement();
       }
-
       i += 1;
     }
-
     if (nextElement) {
       this.layerElement.insertBefore(newElement, nextElement);
     } else {
       this.layerElement.appendChild(newElement);
     }
   };
-
   SVGRendererBase.prototype.hide = function () {
     this.layerElement.style.display = 'none';
   };
-
   SVGRendererBase.prototype.show = function () {
     this.layerElement.style.display = 'block';
   };
 
   function ICompElement() {}
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
-
   ICompElement.prototype.initElement = function (data, globalData, comp) {
     this.initFrame();
     this.initBaseData(data, globalData, comp);
@@ -12638,13 +10677,12 @@
     this.initRendererElement();
     this.createContainerElements();
     this.createRenderableComponents();
-
     if (this.data.xt || !globalData.progressiveLoad) {
       this.buildAllItems();
     }
-
     this.hide();
   };
+
   /* ICompElement.prototype.hide = function(){
       if(!this.hidden){
           this.hideElement();
@@ -12657,77 +10695,61 @@
       }
   }; */
 
-
   ICompElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
-
     if (!this.isInRange && !this.data.xt) {
       return;
     }
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
-
       if (timeRemapped === this.data.op) {
         timeRemapped = this.data.op - 1;
       }
-
       this.renderedFrame = timeRemapped;
     } else {
       this.renderedFrame = num / this.data.sr;
     }
-
     var i;
     var len = this.elements.length;
-
     if (!this.completeLayers) {
       this.checkLayers(this.renderedFrame);
-    } // This iteration needs to be backwards because of how expressions connect between each other
-
-
+    }
+    // This iteration needs to be backwards because of how expressions connect between each other
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
-
         if (this.elements[i]._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   ICompElement.prototype.renderInnerContent = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].renderFrame();
       }
     }
   };
-
   ICompElement.prototype.setElements = function (elems) {
     this.elements = elems;
   };
-
   ICompElement.prototype.getElements = function () {
     return this.elements;
   };
-
   ICompElement.prototype.destroyElements = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i]) {
         this.elements[i].destroy();
       }
     }
   };
-
   ICompElement.prototype.destroy = function () {
     this.destroyElements();
     this.destroyBaseElement();
@@ -12744,9 +10766,7 @@
       _placeholder: true
     };
   }
-
   extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
-
   SVGCompElement.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
@@ -12757,7 +10777,6 @@
     this.renderedFrame = -1;
     this.svgElement = createNS('svg');
     var ariaLabel = '';
-
     if (config && config.title) {
       var titleElement = createNS('title');
       var titleId = createElementID();
@@ -12766,7 +10785,6 @@
       this.svgElement.appendChild(titleElement);
       ariaLabel += titleId;
     }
-
     if (config && config.description) {
       var descElement = createNS('desc');
       var descId = createElementID();
@@ -12775,11 +10793,9 @@
       this.svgElement.appendChild(descElement);
       ariaLabel += ' ' + descId;
     }
-
     if (ariaLabel) {
       this.svgElement.setAttribute('aria-labelledby', ariaLabel);
     }
-
     var defs = createNS('defs');
     this.svgElement.appendChild(defs);
     var maskElement = createNS('g');
@@ -12817,9 +10833,7 @@
     this.destroyed = false;
     this.rendererType = 'svg';
   }
-
   extendPrototype([SVGRendererBase], SVGRenderer);
-
   SVGRenderer.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
@@ -12829,19 +10843,15 @@
     this.sequenceList = [];
     this.transform_key_count = 0;
   }
-
   ShapeTransformManager.prototype = {
     addTransformSequence: function addTransformSequence(transforms) {
       var i;
       var len = transforms.length;
       var key = '_';
-
       for (i = 0; i < len; i += 1) {
         key += transforms[i].transform.key + '_';
       }
-
       var sequence = this.sequences[key];
-
       if (!sequence) {
         sequence = {
           transforms: [].concat(transforms),
@@ -12851,37 +10861,30 @@
         this.sequences[key] = sequence;
         this.sequenceList.push(sequence);
       }
-
       return sequence;
     },
     processSequence: function processSequence(sequence, isFirstFrame) {
       var i = 0;
       var len = sequence.transforms.length;
       var _mdf = isFirstFrame;
-
       while (i < len && !isFirstFrame) {
         if (sequence.transforms[i].transform.mProps._mdf) {
           _mdf = true;
           break;
         }
-
         i += 1;
       }
-
       if (_mdf) {
         sequence.finalTransform.reset();
-
         for (i = len - 1; i >= 0; i -= 1) {
           sequence.finalTransform.multiply(sequence.transforms[i].transform.mProps.v);
         }
       }
-
       sequence._mdf = _mdf;
     },
     processSequences: function processSequences(isFirstFrame) {
       var i;
       var len = this.sequenceList.length;
-
       for (i = 0; i < len; i += 1) {
         this.processSequence(this.sequenceList[i], isFirstFrame);
       }
@@ -12896,11 +10899,12 @@
     var id = '__lottie_element_luma_buffer';
     var lumaBuffer = null;
     var lumaBufferCtx = null;
-    var svg = null; // This alternate solution has a slight delay before the filter is applied, resulting in a flicker on the first frame.
+    var svg = null;
+
+    // This alternate solution has a slight delay before the filter is applied, resulting in a flicker on the first frame.
     // Keeping this here for reference, and in the future, if offscreen canvas supports url filters, this can be used.
     // For now, neither of them work for offscreen canvas, so canvas workers can't support the luma track matte mask.
     // Naming it solution 2 to mark the extra comment lines.
-
     /*
     var svgString = [
       '<svg xmlns="http://www.w3.org/2000/svg">',
@@ -12920,7 +10924,6 @@
 
     function createLumaSvgFilter() {
       var _svg = createNS('svg');
-
       var fil = createNS('filter');
       var matrix = createNS('feColorMatrix');
       fil.setAttribute('id', id);
@@ -12928,60 +10931,49 @@
       matrix.setAttribute('color-interpolation-filters', 'sRGB');
       matrix.setAttribute('values', '0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0');
       fil.appendChild(matrix);
-
       _svg.appendChild(fil);
-
       _svg.setAttribute('id', id + '_svg');
-
       if (featureSupport.svgLumaHidden) {
         _svg.style.display = 'none';
       }
-
       return _svg;
     }
-
     function loadLuma() {
       if (!lumaBuffer) {
         svg = createLumaSvgFilter();
         document.body.appendChild(svg);
         lumaBuffer = createTag('canvas');
-        lumaBufferCtx = lumaBuffer.getContext('2d'); // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
-
+        lumaBufferCtx = lumaBuffer.getContext('2d');
+        // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
         lumaBufferCtx.filter = 'url(#' + id + ')';
         lumaBufferCtx.fillStyle = 'rgba(0,0,0,0)';
         lumaBufferCtx.fillRect(0, 0, 1, 1);
       }
     }
-
     function getLuma(canvas) {
       if (!lumaBuffer) {
         loadLuma();
       }
-
       lumaBuffer.width = canvas.width;
-      lumaBuffer.height = canvas.height; // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
-
+      lumaBuffer.height = canvas.height;
+      // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
       lumaBufferCtx.filter = 'url(#' + id + ')';
       return lumaBuffer;
     }
-
     return {
       load: loadLuma,
       get: getLuma
     };
   };
-
   function createCanvas(width, height) {
     if (featureSupport.offscreenCanvas) {
       return new OffscreenCanvas(width, height);
     }
-
     var canvas = createTag('canvas');
     canvas.width = width;
     canvas.height = height;
     return canvas;
   }
-
   var assetLoader = function () {
     return {
       loadLumaCanvas: lumaLoader.load,
@@ -12991,55 +10983,44 @@
   }();
 
   var registeredEffects = {};
-
   function CVEffects(elem) {
     var i;
     var len = elem.data.ef ? elem.data.ef.length : 0;
     this.filters = [];
     var filterManager;
-
     for (i = 0; i < len; i += 1) {
       filterManager = null;
       var type = elem.data.ef[i].ty;
-
       if (registeredEffects[type]) {
         var Effect = registeredEffects[type].effect;
         filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
       }
-
       if (filterManager) {
         this.filters.push(filterManager);
       }
     }
-
     if (this.filters.length) {
       elem.addRenderableComponent(this);
     }
   }
-
   CVEffects.prototype.renderFrame = function (_isFirstFrame) {
     var i;
     var len = this.filters.length;
-
     for (i = 0; i < len; i += 1) {
       this.filters[i].renderFrame(_isFirstFrame);
     }
   };
-
   CVEffects.prototype.getEffects = function (type) {
     var i;
     var len = this.filters.length;
     var effects = [];
-
     for (i = 0; i < len; i += 1) {
       if (this.filters[i].type === type) {
         effects.push(this.filters[i]);
       }
     }
-
     return effects;
   };
-
   function registerEffect(id, effect) {
     registeredEffects[id] = {
       effect: effect
@@ -13054,27 +11035,21 @@
     var i;
     var len = this.masksProperties.length;
     var hasMasks = false;
-
     for (i = 0; i < len; i += 1) {
       if (this.masksProperties[i].mode !== 'n') {
         hasMasks = true;
       }
-
       this.viewData[i] = ShapePropertyFactory.getShapeProp(this.element, this.masksProperties[i], 3);
     }
-
     this.hasMasks = hasMasks;
-
     if (hasMasks) {
       this.element.addRenderableComponent(this);
     }
   }
-
   CVMaskElement.prototype.renderFrame = function () {
     if (!this.hasMasks) {
       return;
     }
-
     var transform = this.element.finalTransform.mat;
     var ctx = this.element.canvasContext;
     var i;
@@ -13083,7 +11058,6 @@
     var pts;
     var data;
     ctx.beginPath();
-
     for (i = 0; i < len; i += 1) {
       if (this.masksProperties[i].mode !== 'n') {
         if (this.masksProperties[i].inv) {
@@ -13093,35 +11067,28 @@
           ctx.lineTo(0, this.element.globalData.compSize.h);
           ctx.lineTo(0, 0);
         }
-
         data = this.viewData[i].v;
         pt = transform.applyToPointArray(data.v[0][0], data.v[0][1], 0);
         ctx.moveTo(pt[0], pt[1]);
         var j;
         var jLen = data._length;
-
         for (j = 1; j < jLen; j += 1) {
           pts = transform.applyToTriplePoints(data.o[j - 1], data.i[j], data.v[j]);
           ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
         }
-
         pts = transform.applyToTriplePoints(data.o[j - 1], data.i[0], data.v[0]);
         ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
       }
     }
-
     this.element.globalData.renderer.save(true);
     ctx.clip();
   };
-
   CVMaskElement.prototype.getMaskProperty = MaskElement.prototype.getMaskProperty;
-
   CVMaskElement.prototype.destroy = function () {
     this.element = null;
   };
 
   function CVBaseElement() {}
-
   var operationsMap = {
     1: 'source-in',
     2: 'source-out',
@@ -13144,12 +11111,10 @@
         this.buffers.push(bufferCanvas);
         var bufferCanvas2 = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
         this.buffers.push(bufferCanvas2);
-
         if (this.data.tt >= 3 && !document._isProxy) {
           assetLoader.loadLumaCanvas();
         }
       }
-
       this.canvasContext = this.globalData.canvasContext;
       this.transformCanvas = this.globalData.transformCanvas;
       this.renderableEffectsManager = new CVEffects(this);
@@ -13158,7 +11123,6 @@
     createContent: function createContent() {},
     setBlendMode: function setBlendMode() {
       var globalData = this.globalData;
-
       if (globalData.blendMode !== this.data.bm) {
         globalData.blendMode = this.data.bm;
         var blendModeValue = getBlendMode(this.data.bm);
@@ -13188,11 +11152,11 @@
       if (this.data.tt >= 1) {
         var buffer = this.buffers[0];
         var bufferCtx = buffer.getContext('2d');
-        this.clearCanvas(bufferCtx); // on the first buffer we store the current state of the global drawing
-
-        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0); // The next four lines are to clear the canvas
+        this.clearCanvas(bufferCtx);
+        // on the first buffer we store the current state of the global drawing
+        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+        // The next four lines are to clear the canvas
         // TODO: Check if there is a way to clear the canvas without resetting the transform
-
         this.currentTransform = this.canvasContext.getTransform();
         this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
         this.clearCanvas(this.canvasContext);
@@ -13201,43 +11165,43 @@
     },
     exitLayer: function exitLayer() {
       if (this.data.tt >= 1) {
-        var buffer = this.buffers[1]; // On the second buffer we store the current state of the global drawing
+        var buffer = this.buffers[1];
+        // On the second buffer we store the current state of the global drawing
         // that only contains the content of this layer
         // (if it is a composition, it also includes the nested layers)
-
         var bufferCtx = buffer.getContext('2d');
         this.clearCanvas(bufferCtx);
-        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0); // We clear the canvas again
-
+        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+        // We clear the canvas again
         this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
         this.clearCanvas(this.canvasContext);
-        this.canvasContext.setTransform(this.currentTransform); // We draw the mask
-
+        this.canvasContext.setTransform(this.currentTransform);
+        // We draw the mask
         var mask = this.comp.getElementById('tp' in this.data ? this.data.tp : this.data.ind - 1);
-        mask.renderFrame(true); // We draw the second buffer (that contains the content of this layer)
+        mask.renderFrame(true);
+        // We draw the second buffer (that contains the content of this layer)
+        this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
 
-        this.canvasContext.setTransform(1, 0, 0, 1, 0, 0); // If the mask is a Luma matte, we need to do two extra painting operations
+        // If the mask is a Luma matte, we need to do two extra painting operations
         // the _isProxy check is to avoid drawing a fake canvas in workers that will throw an error
-
         if (this.data.tt >= 3 && !document._isProxy) {
           // We copy the painted mask to a buffer that has a color matrix filter applied to it
           // that applies the rgb values to the alpha channel
           var lumaBuffer = assetLoader.getLumaCanvas(this.canvasContext.canvas);
           var lumaBufferCtx = lumaBuffer.getContext('2d');
           lumaBufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
-          this.clearCanvas(this.canvasContext); // we repaint the context with the mask applied to it
-
+          this.clearCanvas(this.canvasContext);
+          // we repaint the context with the mask applied to it
           this.canvasContext.drawImage(lumaBuffer, 0, 0);
         }
-
         this.canvasContext.globalCompositeOperation = operationsMap[this.data.tt];
-        this.canvasContext.drawImage(buffer, 0, 0); // We finally draw the first buffer (that contains the content of the global drawing)
+        this.canvasContext.drawImage(buffer, 0, 0);
+        // We finally draw the first buffer (that contains the content of the global drawing)
         // We use destination-over to draw the global drawing below the current layer
-
         this.canvasContext.globalCompositeOperation = 'destination-over';
         this.canvasContext.drawImage(this.buffers[0], 0, 0);
-        this.canvasContext.setTransform(this.currentTransform); // We reset the globalCompositeOperation to source-over, the standard type of operation
-
+        this.canvasContext.setTransform(this.currentTransform);
+        // We reset the globalCompositeOperation to source-over, the standard type of operation
         this.canvasContext.globalCompositeOperation = 'source-over';
       }
     },
@@ -13245,11 +11209,9 @@
       if (this.hidden || this.data.hd) {
         return;
       }
-
       if (this.data.td === 1 && !forceRender) {
         return;
       }
-
       this.renderTransform();
       this.renderRenderable();
       this.renderLocalTransform();
@@ -13262,11 +11224,9 @@
       this.renderInnerContent();
       this.globalData.renderer.restore(forceRealStack);
       this.exitLayer();
-
       if (this.maskManager.hasMasks) {
         this.globalData.renderer.restore(true);
       }
-
       if (this._isFirstFrame) {
         this._isFirstFrame = false;
       }
@@ -13286,7 +11246,6 @@
     this.styledShapes = [];
     this.tr = [0, 0, 0, 0, 0, 0];
     var ty = 4;
-
     if (data.ty === 'rc') {
       ty = 5;
     } else if (data.ty === 'el') {
@@ -13294,12 +11253,10 @@
     } else if (data.ty === 'sr') {
       ty = 7;
     }
-
     this.sh = ShapePropertyFactory.getShapeProp(element, data, ty, element);
     var i;
     var len = styles.length;
     var styledShape;
-
     for (i = 0; i < len; i += 1) {
       if (!styles[i].closed) {
         styledShape = {
@@ -13311,7 +11268,6 @@
       }
     }
   }
-
   CVShapeData.prototype.setAsAnimated = SVGShapeData.prototype.setAsAnimated;
 
   function CVShapeElement(data, globalData, comp) {
@@ -13325,7 +11281,6 @@
     this.transformsManager = new ShapeTransformManager();
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableElement], CVShapeElement);
   CVShapeElement.prototype.initElement = RenderableDOMElement.prototype.initElement;
   CVShapeElement.prototype.transformHelper = {
@@ -13333,11 +11288,9 @@
     _opMdf: false
   };
   CVShapeElement.prototype.dashResetter = [];
-
   CVShapeElement.prototype.createContent = function () {
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
   };
-
   CVShapeElement.prototype.createStyleElement = function (data, transforms) {
     var styleElem = {
       data: data,
@@ -13348,10 +11301,8 @@
       closed: data.hd === true
     };
     var elementData = {};
-
     if (data.ty === 'fl' || data.ty === 'st') {
       elementData.c = PropertyFactory.getProp(this, data.c, 1, 255, this);
-
       if (!elementData.c.k) {
         styleElem.co = 'rgb(' + bmFloor(elementData.c.v[0]) + ',' + bmFloor(elementData.c.v[1]) + ',' + bmFloor(elementData.c.v[2]) + ')';
       }
@@ -13366,28 +11317,21 @@
       }, 0, degToRads, this);
       elementData.g = new GradientProperty(this, data.g, this);
     }
-
     elementData.o = PropertyFactory.getProp(this, data.o, 0, 0.01, this);
-
     if (data.ty === 'st' || data.ty === 'gs') {
       styleElem.lc = lineCapEnum[data.lc || 2];
       styleElem.lj = lineJoinEnum[data.lj || 2];
-
       if (data.lj == 1) {
         // eslint-disable-line eqeqeq
         styleElem.ml = data.ml;
       }
-
       elementData.w = PropertyFactory.getProp(this, data.w, 0, null, this);
-
       if (!elementData.w.k) {
         styleElem.wi = elementData.w.v;
       }
-
       if (data.d) {
         var d = new DashProperty(this, data.d, 'canvas', this);
         elementData.d = d;
-
         if (!elementData.d.k) {
           styleElem.da = elementData.d.dashArray;
           styleElem["do"] = elementData.d.dashoffset[0];
@@ -13396,12 +11340,10 @@
     } else {
       styleElem.r = data.r === 2 ? 'evenodd' : 'nonzero';
     }
-
     this.stylesList.push(styleElem);
     elementData.style = styleElem;
     return elementData;
   };
-
   CVShapeElement.prototype.createGroupElement = function () {
     var elementData = {
       it: [],
@@ -13409,7 +11351,6 @@
     };
     return elementData;
   };
-
   CVShapeElement.prototype.createTransformElement = function (data) {
     var elementData = {
       transform: {
@@ -13422,65 +11363,52 @@
     };
     return elementData;
   };
-
   CVShapeElement.prototype.createShapeElement = function (data) {
     var elementData = new CVShapeData(this, data, this.stylesList, this.transformsManager);
     this.shapes.push(elementData);
     this.addShapeToModifiers(elementData);
     return elementData;
   };
-
   CVShapeElement.prototype.reloadShapes = function () {
     this._isFirstFrame = true;
     var i;
     var len = this.itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       this.prevViewData[i] = this.itemsData[i];
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
     len = this.dynamicProperties.length;
-
     for (i = 0; i < len; i += 1) {
       this.dynamicProperties[i].getValue();
     }
-
     this.renderModifiers();
     this.transformsManager.processSequences(this._isFirstFrame);
   };
-
   CVShapeElement.prototype.addTransformToStyleList = function (transform) {
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       if (!this.stylesList[i].closed) {
         this.stylesList[i].transforms.push(transform);
       }
     }
   };
-
   CVShapeElement.prototype.removeTransformFromStyleList = function () {
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       if (!this.stylesList[i].closed) {
         this.stylesList[i].transforms.pop();
       }
     }
   };
-
   CVShapeElement.prototype.closeStyles = function (styles) {
     var i;
     var len = styles.length;
-
     for (i = 0; i < len; i += 1) {
       styles[i].closed = true;
     }
   };
-
   CVShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, shouldRender, transforms) {
     var i;
     var len = arr.length - 1;
@@ -13492,42 +11420,35 @@
     var modifier;
     var currentTransform;
     var ownTransforms = [].concat(transforms);
-
     for (i = len; i >= 0; i -= 1) {
       processedPos = this.searchProcessedElement(arr[i]);
-
       if (!processedPos) {
         arr[i]._shouldRender = shouldRender;
       } else {
         itemsData[i] = prevViewData[processedPos - 1];
       }
-
       if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs') {
         if (!processedPos) {
           itemsData[i] = this.createStyleElement(arr[i], ownTransforms);
         } else {
           itemsData[i].style.closed = false;
         }
-
         ownStyles.push(itemsData[i].style);
       } else if (arr[i].ty === 'gr') {
         if (!processedPos) {
           itemsData[i] = this.createGroupElement(arr[i]);
         } else {
           jLen = itemsData[i].it.length;
-
           for (j = 0; j < jLen; j += 1) {
             itemsData[i].prevViewData[j] = itemsData[i].it[j];
           }
         }
-
         this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, shouldRender, ownTransforms);
       } else if (arr[i].ty === 'tr') {
         if (!processedPos) {
           currentTransform = this.createTransformElement(arr[i]);
           itemsData[i] = currentTransform;
         }
-
         ownTransforms.push(itemsData[i]);
         this.addTransformToStyleList(itemsData[i]);
       } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
@@ -13544,7 +11465,6 @@
           modifier = itemsData[i];
           modifier.closed = false;
         }
-
         ownModifiers.push(modifier);
       } else if (arr[i].ty === 'rp') {
         if (!processedPos) {
@@ -13557,22 +11477,17 @@
           modifier = itemsData[i];
           modifier.closed = true;
         }
-
         ownModifiers.push(modifier);
       }
-
       this.addProcessedElement(arr[i], i + 1);
     }
-
     this.removeTransformFromStyleList();
     this.closeStyles(ownStyles);
     len = ownModifiers.length;
-
     for (i = 0; i < len; i += 1) {
       ownModifiers[i].closed = true;
     }
   };
-
   CVShapeElement.prototype.renderInnerContent = function () {
     this.transformHelper.opacity = 1;
     this.transformHelper._opMdf = false;
@@ -13580,7 +11495,6 @@
     this.transformsManager.processSequences(this._isFirstFrame);
     this.renderShape(this.transformHelper, this.shapesData, this.itemsData, true);
   };
-
   CVShapeElement.prototype.renderShapeTransform = function (parentTransform, groupTransform) {
     if (parentTransform._opMdf || groupTransform.op._mdf || this._isFirstFrame) {
       groupTransform.opacity = parentTransform.opacity;
@@ -13588,7 +11502,6 @@
       groupTransform._opMdf = true;
     }
   };
-
   CVShapeElement.prototype.drawLayer = function () {
     var i;
     var len = this.stylesList.length;
@@ -13602,55 +11515,49 @@
     var ctx = this.globalData.canvasContext;
     var type;
     var currentStyle;
-
     for (i = 0; i < len; i += 1) {
       currentStyle = this.stylesList[i];
-      type = currentStyle.type; // Skipping style when
+      type = currentStyle.type;
+
+      // Skipping style when
       // Stroke width equals 0
       // style should not be rendered (extra unused repeaters)
       // current opacity equals 0
       // global opacity equals 0
-
       if (!((type === 'st' || type === 'gs') && currentStyle.wi === 0 || !currentStyle.data._shouldRender || currentStyle.coOp === 0 || this.globalData.currentGlobalAlpha === 0)) {
         renderer.save();
         elems = currentStyle.elements;
-
         if (type === 'st' || type === 'gs') {
-          renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd); // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
-
-          renderer.ctxLineWidth(currentStyle.wi); // ctx.lineWidth = currentStyle.wi;
-
-          renderer.ctxLineCap(currentStyle.lc); // ctx.lineCap = currentStyle.lc;
-
-          renderer.ctxLineJoin(currentStyle.lj); // ctx.lineJoin = currentStyle.lj;
-
-          renderer.ctxMiterLimit(currentStyle.ml || 0); // ctx.miterLimit = currentStyle.ml || 0;
+          renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd);
+          // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
+          renderer.ctxLineWidth(currentStyle.wi);
+          // ctx.lineWidth = currentStyle.wi;
+          renderer.ctxLineCap(currentStyle.lc);
+          // ctx.lineCap = currentStyle.lc;
+          renderer.ctxLineJoin(currentStyle.lj);
+          // ctx.lineJoin = currentStyle.lj;
+          renderer.ctxMiterLimit(currentStyle.ml || 0);
+          // ctx.miterLimit = currentStyle.ml || 0;
         } else {
-          renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd); // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
+          renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd);
+          // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
         }
-
         renderer.ctxOpacity(currentStyle.coOp);
-
         if (type !== 'st' && type !== 'gs') {
           ctx.beginPath();
         }
-
         renderer.ctxTransform(currentStyle.preTransforms.finalTransform.props);
         jLen = elems.length;
-
         for (j = 0; j < jLen; j += 1) {
           if (type === 'st' || type === 'gs') {
             ctx.beginPath();
-
             if (currentStyle.da) {
               ctx.setLineDash(currentStyle.da);
               ctx.lineDashOffset = currentStyle["do"];
             }
           }
-
           nodes = elems[j].trNodes;
           kLen = nodes.length;
-
           for (k = 0; k < kLen; k += 1) {
             if (nodes[k].t === 'm') {
               ctx.moveTo(nodes[k].p[0], nodes[k].p[1]);
@@ -13660,33 +11567,27 @@
               ctx.closePath();
             }
           }
-
           if (type === 'st' || type === 'gs') {
             // ctx.stroke();
             renderer.ctxStroke();
-
             if (currentStyle.da) {
               ctx.setLineDash(this.dashResetter);
             }
           }
         }
-
         if (type !== 'st' && type !== 'gs') {
           // ctx.fill(currentStyle.r);
           this.globalData.renderer.ctxFill(currentStyle.r);
         }
-
         renderer.restore();
       }
     }
   };
-
   CVShapeElement.prototype.renderShape = function (parentTransform, items, data, isMain) {
     var i;
     var len = items.length - 1;
     var groupTransform;
     groupTransform = parentTransform;
-
     for (i = len; i >= 0; i -= 1) {
       if (items[i].ty === 'tr') {
         groupTransform = data[i].transform;
@@ -13701,15 +11602,14 @@
         this.renderGradientFill(items[i], data[i], groupTransform);
       } else if (items[i].ty === 'gr') {
         this.renderShape(groupTransform, items[i].it, data[i].it);
-      } else if (items[i].ty === 'tm') {//
+      } else if (items[i].ty === 'tm') {
+        //
       }
     }
-
     if (isMain) {
       this.drawLayer();
     }
   };
-
   CVShapeElement.prototype.renderStyledShape = function (styledShape, shape) {
     if (this._isFirstFrame || shape._mdf || styledShape.transforms._mdf) {
       var shapeNodes = styledShape.trNodes;
@@ -13720,13 +11620,10 @@
       var jLen = paths._length;
       shapeNodes.length = 0;
       var groupTransformMat = styledShape.transforms.finalTransform;
-
       for (j = 0; j < jLen; j += 1) {
         var pathNodes = paths.shapes[j];
-
         if (pathNodes && pathNodes.v) {
           len = pathNodes._length;
-
           for (i = 1; i < len; i += 1) {
             if (i === 1) {
               shapeNodes.push({
@@ -13734,20 +11631,17 @@
                 p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0)
               });
             }
-
             shapeNodes.push({
               t: 'c',
               pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[i], pathNodes.v[i])
             });
           }
-
           if (len === 1) {
             shapeNodes.push({
               t: 'm',
               p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0)
             });
           }
-
           if (pathNodes.c && len) {
             shapeNodes.push({
               t: 'c',
@@ -13759,103 +11653,81 @@
           }
         }
       }
-
       styledShape.trNodes = shapeNodes;
     }
   };
-
   CVShapeElement.prototype.renderPath = function (pathData, itemData) {
     if (pathData.hd !== true && pathData._shouldRender) {
       var i;
       var len = itemData.styledShapes.length;
-
       for (i = 0; i < len; i += 1) {
         this.renderStyledShape(itemData.styledShapes[i], itemData.sh);
       }
     }
   };
-
   CVShapeElement.prototype.renderFill = function (styleData, itemData, groupTransform) {
     var styleElem = itemData.style;
-
     if (itemData.c._mdf || this._isFirstFrame) {
       styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
     }
-
     if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
       styleElem.coOp = itemData.o.v * groupTransform.opacity;
     }
   };
-
   CVShapeElement.prototype.renderGradientFill = function (styleData, itemData, groupTransform) {
     var styleElem = itemData.style;
     var grd;
-
     if (!styleElem.grd || itemData.g._mdf || itemData.s._mdf || itemData.e._mdf || styleData.t !== 1 && (itemData.h._mdf || itemData.a._mdf)) {
       var ctx = this.globalData.canvasContext;
       var pt1 = itemData.s.v;
       var pt2 = itemData.e.v;
-
       if (styleData.t === 1) {
         grd = ctx.createLinearGradient(pt1[0], pt1[1], pt2[0], pt2[1]);
       } else {
         var rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
         var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
         var percent = itemData.h.v;
-
         if (percent >= 1) {
           percent = 0.99;
         } else if (percent <= -1) {
           percent = -0.99;
         }
-
         var dist = rad * percent;
         var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
         var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
         grd = ctx.createRadialGradient(x, y, 0, pt1[0], pt1[1], rad);
       }
-
       var i;
       var len = styleData.g.p;
       var cValues = itemData.g.c;
       var opacity = 1;
-
       for (i = 0; i < len; i += 1) {
         if (itemData.g._hasOpacity && itemData.g._collapsable) {
           opacity = itemData.g.o[i * 2 + 1];
         }
-
         grd.addColorStop(cValues[i * 4] / 100, 'rgba(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ',' + opacity + ')');
       }
-
       styleElem.grd = grd;
     }
-
     styleElem.coOp = itemData.o.v * groupTransform.opacity;
   };
-
   CVShapeElement.prototype.renderStroke = function (styleData, itemData, groupTransform) {
     var styleElem = itemData.style;
     var d = itemData.d;
-
     if (d && (d._mdf || this._isFirstFrame)) {
       styleElem.da = d.dashArray;
       styleElem["do"] = d.dashoffset[0];
     }
-
     if (itemData.c._mdf || this._isFirstFrame) {
       styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
     }
-
     if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
       styleElem.coOp = itemData.o.v * groupTransform.opacity;
     }
-
     if (itemData.w._mdf || this._isFirstFrame) {
       styleElem.wi = itemData.w.v;
     }
   };
-
   CVShapeElement.prototype.destroy = function () {
     this.shapesData = null;
     this.globalData = null;
@@ -13883,31 +11755,25 @@
     };
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement, ITextElement], CVTextElement);
   CVTextElement.prototype.tHelper = createTag('canvas').getContext('2d');
-
   CVTextElement.prototype.buildNewText = function () {
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
     var hasFill = false;
-
     if (documentData.fc) {
       hasFill = true;
       this.values.fill = this.buildColor(documentData.fc);
     } else {
       this.values.fill = 'rgba(0,0,0,0)';
     }
-
     this.fill = hasFill;
     var hasStroke = false;
-
     if (documentData.sc) {
       hasStroke = true;
       this.values.stroke = this.buildColor(documentData.sc);
       this.values.sWidth = documentData.sw;
     }
-
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
     var i;
     var len;
@@ -13915,8 +11781,8 @@
     var matrixHelper = this.mHelper;
     this.stroke = hasStroke;
     this.values.fValue = documentData.finalSize + 'px ' + this.globalData.fontManager.getFontByName(documentData.f).fFamily;
-    len = documentData.finalText.length; // this.tHelper.font = this.values.fValue;
-
+    len = documentData.finalText.length;
+    // this.tHelper.font = this.values.fValue;
     var charData;
     var shapeData;
     var k;
@@ -13933,55 +11799,44 @@
     var yPos = 0;
     var firstLine = true;
     var cnt = 0;
-
     for (i = 0; i < len; i += 1) {
       charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
       shapeData = charData && charData.data || {};
       matrixHelper.reset();
-
       if (singleShape && letters[i].n) {
         xPos = -trackingOffset;
         yPos += documentData.yOffset;
         yPos += firstLine ? 1 : 0;
         firstLine = false;
       }
-
       shapes = shapeData.shapes ? shapeData.shapes[0].it : [];
       jLen = shapes.length;
       matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
-
       if (singleShape) {
         this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
       }
-
       commands = createSizedArray(jLen - 1);
       var commandsCounter = 0;
-
       for (j = 0; j < jLen; j += 1) {
         if (shapes[j].ty === 'sh') {
           kLen = shapes[j].ks.k.i.length;
           pathNodes = shapes[j].ks.k;
           pathArr = [];
-
           for (k = 1; k < kLen; k += 1) {
             if (k === 1) {
               pathArr.push(matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
             }
-
             pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToY(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToX(pathNodes.v[k][0], pathNodes.v[k][1], 0), matrixHelper.applyToY(pathNodes.v[k][0], pathNodes.v[k][1], 0));
           }
-
           pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToY(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
           commands[commandsCounter] = pathArr;
           commandsCounter += 1;
         }
       }
-
       if (singleShape) {
         xPos += letters[i].l;
         xPos += trackingOffset;
       }
-
       if (this.textSpans[cnt]) {
         this.textSpans[cnt].elem = commands;
       } else {
@@ -13989,25 +11844,23 @@
           elem: commands
         };
       }
-
       cnt += 1;
     }
   };
-
   CVTextElement.prototype.renderInnerContent = function () {
     this.validateText();
     var ctx = this.canvasContext;
     ctx.font = this.values.fValue;
-    this.globalData.renderer.ctxLineCap('butt'); // ctx.lineCap = 'butt';
-
-    this.globalData.renderer.ctxLineJoin('miter'); // ctx.lineJoin = 'miter';
-
-    this.globalData.renderer.ctxMiterLimit(4); // ctx.miterLimit = 4;
+    this.globalData.renderer.ctxLineCap('butt');
+    // ctx.lineCap = 'butt';
+    this.globalData.renderer.ctxLineJoin('miter');
+    // ctx.lineJoin = 'miter';
+    this.globalData.renderer.ctxMiterLimit(4);
+    // ctx.miterLimit = 4;
 
     if (!this.data.singleShape) {
       this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
     }
-
     var i;
     var len;
     var j;
@@ -14024,87 +11877,81 @@
     var commands;
     var pathArr;
     var renderer = this.globalData.renderer;
-
     for (i = 0; i < len; i += 1) {
       if (!letters[i].n) {
         renderedLetter = renderedLetters[i];
-
         if (renderedLetter) {
           renderer.save();
           renderer.ctxTransform(renderedLetter.p);
           renderer.ctxOpacity(renderedLetter.o);
         }
-
         if (this.fill) {
           if (renderedLetter && renderedLetter.fc) {
             if (lastFill !== renderedLetter.fc) {
               renderer.ctxFillStyle(renderedLetter.fc);
-              lastFill = renderedLetter.fc; // ctx.fillStyle = renderedLetter.fc;
+              lastFill = renderedLetter.fc;
+              // ctx.fillStyle = renderedLetter.fc;
             }
           } else if (lastFill !== this.values.fill) {
             lastFill = this.values.fill;
-            renderer.ctxFillStyle(this.values.fill); // ctx.fillStyle = this.values.fill;
+            renderer.ctxFillStyle(this.values.fill);
+            // ctx.fillStyle = this.values.fill;
           }
-
           commands = this.textSpans[i].elem;
           jLen = commands.length;
           this.globalData.canvasContext.beginPath();
-
           for (j = 0; j < jLen; j += 1) {
             pathArr = commands[j];
             kLen = pathArr.length;
             this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
-
             for (k = 2; k < kLen; k += 6) {
               this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
             }
           }
-
           this.globalData.canvasContext.closePath();
-          renderer.ctxFill(); // this.globalData.canvasContext.fill();
+          renderer.ctxFill();
+          // this.globalData.canvasContext.fill();
           /// ctx.fillText(this.textSpans[i].val,0,0);
         }
-
         if (this.stroke) {
           if (renderedLetter && renderedLetter.sw) {
             if (lastStrokeW !== renderedLetter.sw) {
               lastStrokeW = renderedLetter.sw;
-              renderer.ctxLineWidth(renderedLetter.sw); // ctx.lineWidth = renderedLetter.sw;
+              renderer.ctxLineWidth(renderedLetter.sw);
+              // ctx.lineWidth = renderedLetter.sw;
             }
           } else if (lastStrokeW !== this.values.sWidth) {
             lastStrokeW = this.values.sWidth;
-            renderer.ctxLineWidth(this.values.sWidth); // ctx.lineWidth = this.values.sWidth;
+            renderer.ctxLineWidth(this.values.sWidth);
+            // ctx.lineWidth = this.values.sWidth;
           }
-
           if (renderedLetter && renderedLetter.sc) {
             if (lastStroke !== renderedLetter.sc) {
               lastStroke = renderedLetter.sc;
-              renderer.ctxStrokeStyle(renderedLetter.sc); // ctx.strokeStyle = renderedLetter.sc;
+              renderer.ctxStrokeStyle(renderedLetter.sc);
+              // ctx.strokeStyle = renderedLetter.sc;
             }
           } else if (lastStroke !== this.values.stroke) {
             lastStroke = this.values.stroke;
-            renderer.ctxStrokeStyle(this.values.stroke); // ctx.strokeStyle = this.values.stroke;
+            renderer.ctxStrokeStyle(this.values.stroke);
+            // ctx.strokeStyle = this.values.stroke;
           }
-
           commands = this.textSpans[i].elem;
           jLen = commands.length;
           this.globalData.canvasContext.beginPath();
-
           for (j = 0; j < jLen; j += 1) {
             pathArr = commands[j];
             kLen = pathArr.length;
             this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
-
             for (k = 2; k < kLen; k += 6) {
               this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
             }
           }
-
           this.globalData.canvasContext.closePath();
-          renderer.ctxStroke(); // this.globalData.canvasContext.stroke();
+          renderer.ctxStroke();
+          // this.globalData.canvasContext.stroke();
           /// ctx.strokeText(letters[i].val,0,0);
         }
-
         if (renderedLetter) {
           this.globalData.renderer.restore();
         }
@@ -14117,11 +11964,9 @@
     this.img = globalData.imageLoader.getAsset(this.assetData);
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVImageElement);
   CVImageElement.prototype.initElement = SVGShapeElement.prototype.initElement;
   CVImageElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
-
   CVImageElement.prototype.createContent = function () {
     if (this.img.width && (this.assetData.w !== this.img.width || this.assetData.h !== this.img.height)) {
       var canvas = createTag('canvas');
@@ -14135,7 +11980,6 @@
       var widthCrop;
       var heightCrop;
       var par = this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio;
-
       if (imgRel > canvasRel && par === 'xMidYMid slice' || imgRel < canvasRel && par !== 'xMidYMid slice') {
         heightCrop = imgH;
         widthCrop = heightCrop * canvasRel;
@@ -14143,16 +11987,13 @@
         widthCrop = imgW;
         heightCrop = widthCrop / canvasRel;
       }
-
       ctx.drawImage(this.img, (imgW - widthCrop) / 2, (imgH - heightCrop) / 2, widthCrop, heightCrop, 0, 0, this.assetData.w, this.assetData.h);
       this.img = canvas;
     }
   };
-
   CVImageElement.prototype.renderInnerContent = function () {
     this.canvasContext.drawImage(this.img, 0, 0);
   };
-
   CVImageElement.prototype.destroy = function () {
     this.img = null;
   };
@@ -14160,115 +12001,89 @@
   function CVSolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVSolidElement);
   CVSolidElement.prototype.initElement = SVGShapeElement.prototype.initElement;
   CVSolidElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
-
   CVSolidElement.prototype.renderInnerContent = function () {
     // var ctx = this.canvasContext;
-    this.globalData.renderer.ctxFillStyle(this.data.sc); // ctx.fillStyle = this.data.sc;
-
-    this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh); // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
+    this.globalData.renderer.ctxFillStyle(this.data.sc);
+    // ctx.fillStyle = this.data.sc;
+    this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh);
+    // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
     //
   };
 
   function CanvasRendererBase() {}
-
   extendPrototype([BaseRenderer], CanvasRendererBase);
-
   CanvasRendererBase.prototype.createShape = function (data) {
     return new CVShapeElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createText = function (data) {
     return new CVTextElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createImage = function (data) {
     return new CVImageElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createSolid = function (data) {
     return new CVSolidElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
-
   CanvasRendererBase.prototype.ctxTransform = function (props) {
     if (props[0] === 1 && props[1] === 0 && props[4] === 0 && props[5] === 1 && props[12] === 0 && props[13] === 0) {
       return;
     }
-
     this.canvasContext.transform(props[0], props[1], props[4], props[5], props[12], props[13]);
   };
-
   CanvasRendererBase.prototype.ctxOpacity = function (op) {
     this.canvasContext.globalAlpha *= op < 0 ? 0 : op;
   };
-
   CanvasRendererBase.prototype.ctxFillStyle = function (value) {
     this.canvasContext.fillStyle = value;
   };
-
   CanvasRendererBase.prototype.ctxStrokeStyle = function (value) {
     this.canvasContext.strokeStyle = value;
   };
-
   CanvasRendererBase.prototype.ctxLineWidth = function (value) {
     this.canvasContext.lineWidth = value;
   };
-
   CanvasRendererBase.prototype.ctxLineCap = function (value) {
     this.canvasContext.lineCap = value;
   };
-
   CanvasRendererBase.prototype.ctxLineJoin = function (value) {
     this.canvasContext.lineJoin = value;
   };
-
   CanvasRendererBase.prototype.ctxMiterLimit = function (value) {
     this.canvasContext.miterLimit = value;
   };
-
   CanvasRendererBase.prototype.ctxFill = function (rule) {
     this.canvasContext.fill(rule);
   };
-
   CanvasRendererBase.prototype.ctxFillRect = function (x, y, w, h) {
     this.canvasContext.fillRect(x, y, w, h);
   };
-
   CanvasRendererBase.prototype.ctxStroke = function () {
     this.canvasContext.stroke();
   };
-
   CanvasRendererBase.prototype.reset = function () {
     if (!this.renderConfig.clearCanvas) {
       this.canvasContext.restore();
       return;
     }
-
     this.contextData.reset();
   };
-
   CanvasRendererBase.prototype.save = function () {
     this.canvasContext.save();
   };
-
   CanvasRendererBase.prototype.restore = function (actionFlag) {
     if (!this.renderConfig.clearCanvas) {
       this.canvasContext.restore();
       return;
     }
-
     if (actionFlag) {
       this.globalData.blendMode = 'source-over';
     }
-
     this.contextData.restore(actionFlag);
   };
-
   CanvasRendererBase.prototype.configAnimation = function (animData) {
     if (this.animationItem.wrapper) {
       this.animationItem.container = createTag('canvas');
@@ -14283,18 +12098,15 @@
       containerStyle.contentVisibility = this.renderConfig.contentVisibility;
       this.animationItem.wrapper.appendChild(this.animationItem.container);
       this.canvasContext = this.animationItem.container.getContext('2d');
-
       if (this.renderConfig.className) {
         this.animationItem.container.setAttribute('class', this.renderConfig.className);
       }
-
       if (this.renderConfig.id) {
         this.animationItem.container.setAttribute('id', this.renderConfig.id);
       }
     } else {
       this.canvasContext = this.renderConfig.context;
     }
-
     this.contextData.setContext(this.canvasContext);
     this.data = animData;
     this.layers = animData.layers;
@@ -14315,12 +12127,10 @@
     this.elements = createSizedArray(animData.layers.length);
     this.updateContainerSize();
   };
-
   CanvasRendererBase.prototype.updateContainerSize = function (width, height) {
     this.reset();
     var elementWidth;
     var elementHeight;
-
     if (width) {
       elementWidth = width;
       elementHeight = height;
@@ -14334,14 +12144,11 @@
         elementWidth = this.canvasContext.canvas.width;
         elementHeight = this.canvasContext.canvas.height;
       }
-
       this.canvasContext.canvas.width = elementWidth * this.renderConfig.dpr;
       this.canvasContext.canvas.height = elementHeight * this.renderConfig.dpr;
     }
-
     var elementRel;
     var animationRel;
-
     if (this.renderConfig.preserveAspectRatio.indexOf('meet') !== -1 || this.renderConfig.preserveAspectRatio.indexOf('slice') !== -1) {
       var par = this.renderConfig.preserveAspectRatio.split(' ');
       var fillType = par[1] || 'meet';
@@ -14350,7 +12157,6 @@
       var yPos = pos.substr(4);
       elementRel = elementWidth / elementHeight;
       animationRel = this.transformCanvas.w / this.transformCanvas.h;
-
       if (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice') {
         this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
         this.transformCanvas.sy = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
@@ -14358,7 +12164,6 @@
         this.transformCanvas.sx = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
         this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
       }
-
       if (xPos === 'xMid' && (animationRel < elementRel && fillType === 'meet' || animationRel > elementRel && fillType === 'slice')) {
         this.transformCanvas.tx = (elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) / 2 * this.renderConfig.dpr;
       } else if (xPos === 'xMax' && (animationRel < elementRel && fillType === 'meet' || animationRel > elementRel && fillType === 'slice')) {
@@ -14366,7 +12171,6 @@
       } else {
         this.transformCanvas.tx = 0;
       }
-
       if (yPos === 'YMid' && (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice')) {
         this.transformCanvas.ty = (elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w)) / 2 * this.renderConfig.dpr;
       } else if (yPos === 'YMax' && (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice')) {
@@ -14385,7 +12189,6 @@
       this.transformCanvas.tx = 0;
       this.transformCanvas.ty = 0;
     }
-
     this.transformCanvas.props = [this.transformCanvas.sx, 0, 0, 0, 0, this.transformCanvas.sy, 0, 0, 0, 0, 1, 0, this.transformCanvas.tx, this.transformCanvas.ty, 0, 1];
     /* var i, len = this.elements.length;
       for(i=0;i<len;i+=1){
@@ -14393,7 +12196,6 @@
               this.elements[i].resize(this.globalData.transformCanvas);
           }
       } */
-
     this.ctxTransform(this.transformCanvas.props);
     this.canvasContext.beginPath();
     this.canvasContext.rect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
@@ -14401,78 +12203,65 @@
     this.canvasContext.clip();
     this.renderFrame(this.renderedFrame, true);
   };
-
   CanvasRendererBase.prototype.destroy = function () {
     if (this.renderConfig.clearCanvas && this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.globalData.canvasContext = null;
     this.animationItem.container = null;
     this.destroyed = true;
   };
-
   CanvasRendererBase.prototype.renderFrame = function (num, forceRender) {
     if (this.renderedFrame === num && this.renderConfig.clearCanvas === true && !forceRender || this.destroyed || num === -1) {
       return;
     }
-
     this.renderedFrame = num;
     this.globalData.frameNum = num - this.animationItem._isFirstFrame;
     this.globalData.frameId += 1;
     this.globalData._mdf = !this.renderConfig.clearCanvas || forceRender;
-    this.globalData.projectInterface.currentFrame = num; // console.log('--------');
-    // console.log('NEW: ',num);
+    this.globalData.projectInterface.currentFrame = num;
 
+    // console.log('--------');
+    // console.log('NEW: ',num);
     var i;
     var len = this.layers.length;
-
     if (!this.completeLayers) {
       this.checkLayers(num);
     }
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(num - this.layers[i].st);
       }
     }
-
     if (this.globalData._mdf) {
       if (this.renderConfig.clearCanvas === true) {
         this.canvasContext.clearRect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
       } else {
         this.save();
       }
-
       for (i = len - 1; i >= 0; i -= 1) {
         if (this.completeLayers || this.elements[i]) {
           this.elements[i].renderFrame();
         }
       }
-
       if (this.renderConfig.clearCanvas !== true) {
         this.restore();
       }
     }
   };
-
   CanvasRendererBase.prototype.buildItem = function (pos) {
     var elements = this.elements;
-
     if (elements[pos] || this.layers[pos].ty === 99) {
       return;
     }
-
     var element = this.createItem(this.layers[pos], this, this.globalData);
     elements[pos] = element;
     element.initExpressions();
@@ -14480,18 +12269,15 @@
           element.resize(this.globalData.transformCanvas);
       } */
   };
-
   CanvasRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
     }
   };
-
   CanvasRendererBase.prototype.hide = function () {
     this.animationItem.container.style.display = 'none';
   };
-
   CanvasRendererBase.prototype.show = function () {
     this.animationItem.container.style.display = 'block';
   };
@@ -14507,71 +12293,61 @@
     this.miterLimit = '';
     this.id = Math.random();
   }
-
   function CVContextData() {
     this.stack = [];
     this.cArrPos = 0;
     this.cTr = new Matrix();
     var i;
     var len = 15;
-
     for (i = 0; i < len; i += 1) {
       var canvasContext = new CanvasContext();
       this.stack[i] = canvasContext;
     }
-
     this._length = len;
     this.nativeContext = null;
     this.transformMat = new Matrix();
-    this.currentOpacity = 1; //
-
+    this.currentOpacity = 1;
+    //
     this.currentFillStyle = '';
-    this.appliedFillStyle = ''; //
-
+    this.appliedFillStyle = '';
+    //
     this.currentStrokeStyle = '';
-    this.appliedStrokeStyle = ''; //
-
+    this.appliedStrokeStyle = '';
+    //
     this.currentLineWidth = '';
-    this.appliedLineWidth = ''; //
-
+    this.appliedLineWidth = '';
+    //
     this.currentLineCap = '';
-    this.appliedLineCap = ''; //
-
+    this.appliedLineCap = '';
+    //
     this.currentLineJoin = '';
-    this.appliedLineJoin = ''; //
-
+    this.appliedLineJoin = '';
+    //
     this.appliedMiterLimit = '';
     this.currentMiterLimit = '';
   }
-
   CVContextData.prototype.duplicate = function () {
     var newLength = this._length * 2;
     var i = 0;
-
     for (i = this._length; i < newLength; i += 1) {
       this.stack[i] = new CanvasContext();
     }
-
     this._length = newLength;
   };
-
   CVContextData.prototype.reset = function () {
     this.cArrPos = 0;
     this.cTr.reset();
     this.stack[this.cArrPos].opacity = 1;
   };
-
   CVContextData.prototype.restore = function (forceRestore) {
     this.cArrPos -= 1;
     var currentContext = this.stack[this.cArrPos];
     var transform = currentContext.transform;
     var i;
     var arr = this.cTr.props;
-
     for (i = 0; i < 16; i += 1) {
       arr[i] = transform[i];
     }
-
     if (forceRestore) {
       this.nativeContext.restore();
       var prevStack = this.stack[this.cArrPos + 1];
@@ -14582,14 +12358,11 @@
       this.appliedLineJoin = prevStack.lineJoin;
       this.appliedMiterLimit = prevStack.miterLimit;
     }
-
     this.nativeContext.setTransform(transform[0], transform[1], transform[4], transform[5], transform[12], transform[13]);
-
     if (forceRestore || currentContext.opacity !== -1 && this.currentOpacity !== currentContext.opacity) {
       this.nativeContext.globalAlpha = currentContext.opacity;
       this.currentOpacity = currentContext.opacity;
     }
-
     this.currentFillStyle = currentContext.fillStyle;
     this.currentStrokeStyle = currentContext.strokeStyle;
     this.currentLineWidth = currentContext.lineWidth;
@@ -14597,25 +12370,19 @@
     this.currentLineJoin = currentContext.lineJoin;
     this.currentMiterLimit = currentContext.miterLimit;
   };
-
   CVContextData.prototype.save = function (saveOnNativeFlag) {
     if (saveOnNativeFlag) {
       this.nativeContext.save();
     }
-
     var props = this.cTr.props;
-
     if (this._length <= this.cArrPos) {
       this.duplicate();
     }
-
     var currentStack = this.stack[this.cArrPos];
     var i;
-
     for (i = 0; i < 16; i += 1) {
       currentStack.transform[i] = props[i];
     }
-
     this.cArrPos += 1;
     var newStack = this.stack[this.cArrPos];
     newStack.opacity = currentStack.opacity;
@@ -14626,128 +12393,106 @@
     newStack.lineJoin = currentStack.lineJoin;
     newStack.miterLimit = currentStack.miterLimit;
   };
-
   CVContextData.prototype.setOpacity = function (value) {
     this.stack[this.cArrPos].opacity = value;
   };
-
   CVContextData.prototype.setContext = function (value) {
     this.nativeContext = value;
   };
-
   CVContextData.prototype.fillStyle = function (value) {
     if (this.stack[this.cArrPos].fillStyle !== value) {
       this.currentFillStyle = value;
       this.stack[this.cArrPos].fillStyle = value;
     }
   };
-
   CVContextData.prototype.strokeStyle = function (value) {
     if (this.stack[this.cArrPos].strokeStyle !== value) {
       this.currentStrokeStyle = value;
       this.stack[this.cArrPos].strokeStyle = value;
     }
   };
-
   CVContextData.prototype.lineWidth = function (value) {
     if (this.stack[this.cArrPos].lineWidth !== value) {
       this.currentLineWidth = value;
       this.stack[this.cArrPos].lineWidth = value;
     }
   };
-
   CVContextData.prototype.lineCap = function (value) {
     if (this.stack[this.cArrPos].lineCap !== value) {
       this.currentLineCap = value;
       this.stack[this.cArrPos].lineCap = value;
     }
   };
-
   CVContextData.prototype.lineJoin = function (value) {
     if (this.stack[this.cArrPos].lineJoin !== value) {
       this.currentLineJoin = value;
       this.stack[this.cArrPos].lineJoin = value;
     }
   };
-
   CVContextData.prototype.miterLimit = function (value) {
     if (this.stack[this.cArrPos].miterLimit !== value) {
       this.currentMiterLimit = value;
       this.stack[this.cArrPos].miterLimit = value;
     }
   };
-
   CVContextData.prototype.transform = function (props) {
-    this.transformMat.cloneFromProps(props); // Taking the last transform value from the stored stack of transforms
-
-    var currentTransform = this.cTr; // Applying the last transform value after the new transform to respect the order of transformations
-
-    this.transformMat.multiply(currentTransform); // Storing the new transformed value in the stored transform
-
+    this.transformMat.cloneFromProps(props);
+    // Taking the last transform value from the stored stack of transforms
+    var currentTransform = this.cTr;
+    // Applying the last transform value after the new transform to respect the order of transformations
+    this.transformMat.multiply(currentTransform);
+    // Storing the new transformed value in the stored transform
     currentTransform.cloneFromProps(this.transformMat.props);
-    var trProps = currentTransform.props; // Applying the new transform to the canvas
-
+    var trProps = currentTransform.props;
+    // Applying the new transform to the canvas
     this.nativeContext.setTransform(trProps[0], trProps[1], trProps[4], trProps[5], trProps[12], trProps[13]);
   };
-
   CVContextData.prototype.opacity = function (op) {
     var currentOpacity = this.stack[this.cArrPos].opacity;
     currentOpacity *= op < 0 ? 0 : op;
-
     if (this.stack[this.cArrPos].opacity !== currentOpacity) {
       if (this.currentOpacity !== op) {
         this.nativeContext.globalAlpha = op;
         this.currentOpacity = op;
       }
-
       this.stack[this.cArrPos].opacity = currentOpacity;
     }
   };
-
   CVContextData.prototype.fill = function (rule) {
     if (this.appliedFillStyle !== this.currentFillStyle) {
       this.appliedFillStyle = this.currentFillStyle;
       this.nativeContext.fillStyle = this.appliedFillStyle;
     }
-
     this.nativeContext.fill(rule);
   };
-
   CVContextData.prototype.fillRect = function (x, y, w, h) {
     if (this.appliedFillStyle !== this.currentFillStyle) {
       this.appliedFillStyle = this.currentFillStyle;
       this.nativeContext.fillStyle = this.appliedFillStyle;
     }
-
     this.nativeContext.fillRect(x, y, w, h);
   };
-
   CVContextData.prototype.stroke = function () {
     if (this.appliedStrokeStyle !== this.currentStrokeStyle) {
       this.appliedStrokeStyle = this.currentStrokeStyle;
       this.nativeContext.strokeStyle = this.appliedStrokeStyle;
     }
-
     if (this.appliedLineWidth !== this.currentLineWidth) {
       this.appliedLineWidth = this.currentLineWidth;
       this.nativeContext.lineWidth = this.appliedLineWidth;
     }
-
     if (this.appliedLineCap !== this.currentLineCap) {
       this.appliedLineCap = this.currentLineCap;
       this.nativeContext.lineCap = this.appliedLineCap;
     }
-
     if (this.appliedLineJoin !== this.currentLineJoin) {
       this.appliedLineJoin = this.currentLineJoin;
       this.nativeContext.lineJoin = this.appliedLineJoin;
     }
-
     if (this.appliedMiterLimit !== this.currentMiterLimit) {
       this.appliedMiterLimit = this.currentMiterLimit;
       this.nativeContext.miterLimit = this.appliedMiterLimit;
     }
-
     this.nativeContext.stroke();
   };
 
@@ -14761,9 +12506,7 @@
       _placeholder: true
     };
   }
-
   extendPrototype([CanvasRendererBase, ICompElement, CVBaseElement], CVCompElement);
-
   CVCompElement.prototype.renderInnerContent = function () {
     var ctx = this.canvasContext;
     ctx.beginPath();
@@ -14775,28 +12518,23 @@
     ctx.clip();
     var i;
     var len = this.layers.length;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].renderFrame();
       }
     }
   };
-
   CVCompElement.prototype.destroy = function () {
     var i;
     var len = this.layers.length;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.elements[i]) {
         this.elements[i].destroy();
       }
     }
-
     this.layers = null;
     this.elements = null;
   };
-
   CVCompElement.prototype.createComp = function (data) {
     return new CVCompElement(data, this.globalData, this);
   };
@@ -14815,11 +12553,9 @@
       runExpressions: !config || config.runExpressions === undefined || config.runExpressions
     };
     this.renderConfig.dpr = config && config.dpr || 1;
-
     if (this.animationItem.wrapper) {
       this.renderConfig.dpr = config && config.dpr || window.devicePixelRatio || 1;
     }
-
     this.renderedFrame = -1;
     this.globalData = {
       frameNum: -1,
@@ -14833,7 +12569,6 @@
     this.transformMat = new Matrix();
     this.completeLayers = false;
     this.rendererType = 'canvas';
-
     if (this.renderConfig.clearCanvas) {
       this.ctxTransform = this.contextData.transform.bind(this.contextData);
       this.ctxOpacity = this.contextData.opacity.bind(this.contextData);
@@ -14849,20 +12584,16 @@
       this.save = this.contextData.save.bind(this.contextData);
     }
   }
-
   extendPrototype([CanvasRendererBase], CanvasRenderer);
-
   CanvasRenderer.prototype.createComp = function (data) {
     return new CVCompElement(data, this.globalData, this);
   };
 
   function HBaseElement() {}
-
   HBaseElement.prototype = {
     checkBlendMode: function checkBlendMode() {},
     initRendererElement: function initRendererElement() {
       this.baseElement = createTag(this.data.tg || 'div');
-
       if (this.data.hasMask) {
         this.svgElement = createNS('svg');
         this.layerElement = createNS('g');
@@ -14872,35 +12603,29 @@
       } else {
         this.layerElement = this.baseElement;
       }
-
       styleDiv(this.baseElement);
     },
     createContainerElements: function createContainerElements() {
       this.renderableEffectsManager = new CVEffects(this);
       this.transformedElement = this.baseElement;
       this.maskedElement = this.layerElement;
-
       if (this.data.ln) {
         this.layerElement.setAttribute('id', this.data.ln);
       }
-
       if (this.data.cl) {
         this.layerElement.setAttribute('class', this.data.cl);
       }
-
       if (this.data.bm !== 0) {
         this.setBlendMode();
       }
     },
     renderElement: function renderElement() {
       var transformedElementStyle = this.transformedElement ? this.transformedElement.style : {};
-
       if (this.finalTransform._matMdf) {
         var matrixValue = this.finalTransform.mat.toCSS();
         transformedElementStyle.transform = matrixValue;
         transformedElementStyle.webkitTransform = matrixValue;
       }
-
       if (this.finalTransform._opMdf) {
         transformedElementStyle.opacity = this.finalTransform.mProp.o.v;
       }
@@ -14911,12 +12636,10 @@
       if (this.data.hd || this.hidden) {
         return;
       }
-
       this.renderTransform();
       this.renderRenderable();
       this.renderElement();
       this.renderInnerContent();
-
       if (this._isFirstFrame) {
         this._isFirstFrame = false;
       }
@@ -14924,11 +12647,9 @@
     destroy: function destroy() {
       this.layerElement = null;
       this.transformedElement = null;
-
       if (this.matteElement) {
         this.matteElement = null;
       }
-
       if (this.maskManager) {
         this.maskManager.destroy();
         this.maskManager = null;
@@ -14947,12 +12668,9 @@
   function HSolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], HSolidElement);
-
   HSolidElement.prototype.createContent = function () {
     var rect;
-
     if (this.data.hasMask) {
       rect = createNS('rect');
       rect.setAttribute('width', this.data.sw);
@@ -14966,29 +12684,28 @@
       rect.style.height = this.data.sh + 'px';
       rect.style.backgroundColor = this.data.sc;
     }
-
     this.layerElement.appendChild(rect);
   };
 
   function HShapeElement(data, globalData, comp) {
     // List of drawable elements
-    this.shapes = []; // Full shape data
-
-    this.shapesData = data.shapes; // List of styles that will be applied to shapes
-
-    this.stylesList = []; // List of modifiers that will be applied to shapes
-
-    this.shapeModifiers = []; // List of items in shape tree
-
-    this.itemsData = []; // List of items in previous shape tree
-
-    this.processedElements = []; // List of animated components
-
+    this.shapes = [];
+    // Full shape data
+    this.shapesData = data.shapes;
+    // List of styles that will be applied to shapes
+    this.stylesList = [];
+    // List of modifiers that will be applied to shapes
+    this.shapeModifiers = [];
+    // List of items in shape tree
+    this.itemsData = [];
+    // List of items in previous shape tree
+    this.processedElements = [];
+    // List of animated components
     this.animatedContents = [];
     this.shapesContainer = createNS('g');
-    this.initElement(data, globalData, comp); // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.initElement(data, globalData, comp);
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
     // List of elements that have been created
-
     this.prevViewData = [];
     this.currentBBox = {
       x: 999999,
@@ -14997,14 +12714,11 @@
       w: 0
     };
   }
-
   extendPrototype([BaseElement, TransformElement, HSolidElement, SVGShapeElement, HBaseElement, HierarchyElement, FrameElement, RenderableElement], HShapeElement);
   HShapeElement.prototype._renderShapeFrame = HShapeElement.prototype.renderInnerContent;
-
   HShapeElement.prototype.createContent = function () {
     var cont;
     this.baseElement.style.fontSize = 0;
-
     if (this.data.hasMask) {
       this.layerElement.appendChild(this.shapesContainer);
       cont = this.svgElement;
@@ -15016,23 +12730,18 @@
       cont.appendChild(this.shapesContainer);
       this.layerElement.appendChild(cont);
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.shapesContainer, 0, [], true);
     this.filterUniqueShapes();
     this.shapeCont = cont;
   };
-
   HShapeElement.prototype.getTransformedPoint = function (transformers, point) {
     var i;
     var len = transformers.length;
-
     for (i = 0; i < len; i += 1) {
       point = transformers[i].mProps.v.applyToPointArray(point[0], point[1], 0);
     }
-
     return point;
   };
-
   HShapeElement.prototype.calculateShapeBoundingBox = function (item, boundingBox) {
     var shape = item.sh.v;
     var transformers = item.transformers;
@@ -15042,11 +12751,9 @@
     var oPoint;
     var nextIPoint;
     var nextVPoint;
-
     if (len <= 1) {
       return;
     }
-
     for (i = 0; i < len - 1; i += 1) {
       vPoint = this.getTransformedPoint(transformers, shape.v[i]);
       oPoint = this.getTransformedPoint(transformers, shape.o[i]);
@@ -15054,7 +12761,6 @@
       nextVPoint = this.getTransformedPoint(transformers, shape.v[i + 1]);
       this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
     }
-
     if (shape.c) {
       vPoint = this.getTransformedPoint(transformers, shape.v[i]);
       oPoint = this.getTransformedPoint(transformers, shape.o[i]);
@@ -15063,7 +12769,6 @@
       this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
     }
   };
-
   HShapeElement.prototype.checkBounds = function (vPoint, oPoint, nextIPoint, nextVPoint, boundingBox) {
     this.getBoundsOfCurve(vPoint, oPoint, nextIPoint, nextVPoint);
     var bounds = this.shapeBoundingBox;
@@ -15072,7 +12777,6 @@
     boundingBox.y = bmMin(bounds.top, boundingBox.y);
     boundingBox.yMax = bmMax(bounds.bottom, boundingBox.yMax);
   };
-
   HShapeElement.prototype.shapeBoundingBox = {
     left: 0,
     right: 0,
@@ -15087,31 +12791,26 @@
     width: 0,
     height: 0
   };
-
   HShapeElement.prototype.getBoundsOfCurve = function (p0, p1, p2, p3) {
     var bounds = [[p0[0], p3[0]], [p0[1], p3[1]]];
-
     for (var a, b, c, t, b2ac, t1, t2, i = 0; i < 2; ++i) {
       // eslint-disable-line no-plusplus
       b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];
       a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];
       c = 3 * p1[i] - 3 * p0[i];
       b |= 0; // eslint-disable-line no-bitwise
-
       a |= 0; // eslint-disable-line no-bitwise
-
       c |= 0; // eslint-disable-line no-bitwise
 
-      if (a === 0 && b === 0) {//
+      if (a === 0 && b === 0) {
+        //
       } else if (a === 0) {
         t = -c / b;
-
         if (t > 0 && t < 1) {
           bounds[i].push(this.calculateF(t, p0, p1, p2, p3, i));
         }
       } else {
         b2ac = b * b - 4 * c * a;
-
         if (b2ac >= 0) {
           t1 = (-b + bmSqrt(b2ac)) / (2 * a);
           if (t1 > 0 && t1 < 1) bounds[i].push(this.calculateF(t1, p0, p1, p2, p3, i));
@@ -15120,21 +12819,17 @@
         }
       }
     }
-
     this.shapeBoundingBox.left = bmMin.apply(null, bounds[0]);
     this.shapeBoundingBox.top = bmMin.apply(null, bounds[1]);
     this.shapeBoundingBox.right = bmMax.apply(null, bounds[0]);
     this.shapeBoundingBox.bottom = bmMax.apply(null, bounds[1]);
   };
-
   HShapeElement.prototype.calculateF = function (t, p0, p1, p2, p3, i) {
     return bmPow(1 - t, 3) * p0[i] + 3 * bmPow(1 - t, 2) * t * p1[i] + 3 * (1 - t) * bmPow(t, 2) * p2[i] + bmPow(t, 3) * p3[i];
   };
-
   HShapeElement.prototype.calculateBoundingBox = function (itemsData, boundingBox) {
     var i;
     var len = itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       if (itemsData[i] && itemsData[i].sh) {
         this.calculateShapeBoundingBox(itemsData[i], boundingBox);
@@ -15145,37 +12840,29 @@
       }
     }
   };
-
   HShapeElement.prototype.expandStrokeBoundingBox = function (widthProperty, boundingBox) {
     var width = 0;
-
     if (widthProperty.keyframes) {
       for (var i = 0; i < widthProperty.keyframes.length; i += 1) {
         var kfw = widthProperty.keyframes[i].s;
-
         if (kfw > width) {
           width = kfw;
         }
       }
-
       width *= widthProperty.mult;
     } else {
       width = widthProperty.v * widthProperty.mult;
     }
-
     boundingBox.x -= width;
     boundingBox.xMax += width;
     boundingBox.y -= width;
     boundingBox.yMax += width;
   };
-
   HShapeElement.prototype.currentBoxContains = function (box) {
     return this.currentBBox.x <= box.x && this.currentBBox.y <= box.y && this.currentBBox.width + this.currentBBox.x >= box.x + box.width && this.currentBBox.height + this.currentBBox.y >= box.y + box.height;
   };
-
   HShapeElement.prototype.renderInnerContent = function () {
     this._renderShapeFrame();
-
     if (!this.hidden && (this._isFirstFrame || this._mdf)) {
       var tempBoundingBox = this.tempBoundingBox;
       var max = 999999;
@@ -15185,26 +12872,22 @@
       tempBoundingBox.yMax = -max;
       this.calculateBoundingBox(this.itemsData, tempBoundingBox);
       tempBoundingBox.width = tempBoundingBox.xMax < tempBoundingBox.x ? 0 : tempBoundingBox.xMax - tempBoundingBox.x;
-      tempBoundingBox.height = tempBoundingBox.yMax < tempBoundingBox.y ? 0 : tempBoundingBox.yMax - tempBoundingBox.y; // var tempBoundingBox = this.shapeCont.getBBox();
-
+      tempBoundingBox.height = tempBoundingBox.yMax < tempBoundingBox.y ? 0 : tempBoundingBox.yMax - tempBoundingBox.y;
+      // var tempBoundingBox = this.shapeCont.getBBox();
       if (this.currentBoxContains(tempBoundingBox)) {
         return;
       }
-
       var changed = false;
-
       if (this.currentBBox.w !== tempBoundingBox.width) {
         this.currentBBox.w = tempBoundingBox.width;
         this.shapeCont.setAttribute('width', tempBoundingBox.width);
         changed = true;
       }
-
       if (this.currentBBox.h !== tempBoundingBox.height) {
         this.currentBBox.h = tempBoundingBox.height;
         this.shapeCont.setAttribute('height', tempBoundingBox.height);
         changed = true;
       }
-
       if (changed || this.currentBBox.x !== tempBoundingBox.x || this.currentBBox.y !== tempBoundingBox.y) {
         this.currentBBox.w = tempBoundingBox.width;
         this.currentBBox.h = tempBoundingBox.height;
@@ -15232,12 +12915,9 @@
     this.isMasked = false;
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], HTextElement);
-
   HTextElement.prototype.createContent = function () {
     this.isMasked = this.checkMasks();
-
     if (this.isMasked) {
       this.renderType = 'svg';
       this.compW = this.comp.data.w;
@@ -15251,10 +12931,8 @@
       this.renderType = 'html';
       this.innerElem = this.layerElement;
     }
-
     this.checkParenting();
   };
-
   HTextElement.prototype.buildNewText = function () {
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
@@ -15262,18 +12940,14 @@
     var textColor = documentData.fc ? this.buildColor(documentData.fc) : 'rgba(0,0,0,0)';
     innerElemStyle.fill = textColor;
     innerElemStyle.color = textColor;
-
     if (documentData.sc) {
       innerElemStyle.stroke = this.buildColor(documentData.sc);
       innerElemStyle.strokeWidth = documentData.sw + 'px';
     }
-
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
-
     if (!this.globalData.fontManager.chars) {
       innerElemStyle.fontSize = documentData.finalSize + 'px';
       innerElemStyle.lineHeight = documentData.finalSize + 'px';
-
       if (fontData.fClass) {
         this.innerElem.className = fontData.fClass;
       } else {
@@ -15284,7 +12958,6 @@
         innerElemStyle.fontWeight = fWeight;
       }
     }
-
     var i;
     var len;
     var letters = documentData.l;
@@ -15296,7 +12969,6 @@
     var shapes;
     var shapeStr = '';
     var cnt = 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.globalData.fontManager.chars) {
         if (!this.textPaths[cnt]) {
@@ -15307,7 +12979,6 @@
         } else {
           tSpan = this.textPaths[cnt];
         }
-
         if (!this.isMasked) {
           if (this.textSpans[cnt]) {
             tParent = this.textSpans[cnt];
@@ -15333,31 +13004,25 @@
         }
       } else {
         tSpan = this.textPaths[cnt] ? this.textPaths[cnt] : createNS('text');
-      } // tSpan.setAttribute('visibility', 'hidden');
-
-
+      }
+      // tSpan.setAttribute('visibility', 'hidden');
       if (this.globalData.fontManager.chars) {
         var charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
         var shapeData;
-
         if (charData) {
           shapeData = charData.data;
         } else {
           shapeData = null;
         }
-
         matrixHelper.reset();
-
         if (shapeData && shapeData.shapes && shapeData.shapes.length) {
           shapes = shapeData.shapes[0].it;
           matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
           shapeStr = this.createPathShape(matrixHelper, shapes);
           tSpan.setAttribute('d', shapeStr);
         }
-
         if (!this.isMasked) {
           this.innerElem.appendChild(tParent);
-
           if (shapeData && shapeData.shapes) {
             // document.body.appendChild is needed to get exact measure of shape
             document.body.appendChild(tCont);
@@ -15374,7 +13039,6 @@
             tCont.setAttribute('width', 1);
             tCont.setAttribute('height', 1);
           }
-
           tParent.appendChild(tCont);
         } else {
           this.innerElem.appendChild(tSpan);
@@ -15382,10 +13046,9 @@
       } else {
         tSpan.textContent = letters[i].val;
         tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
-
         if (!this.isMasked) {
-          this.innerElem.appendChild(tParent); //
-
+          this.innerElem.appendChild(tParent);
+          //
           var tStyle = tSpan.style;
           var tSpanTranslation = 'translate3d(0,' + -documentData.finalSize / 1.2 + 'px,0)';
           tStyle.transform = tSpanTranslation;
@@ -15393,35 +13056,29 @@
         } else {
           this.innerElem.appendChild(tSpan);
         }
-      } //
-
-
+      }
+      //
       if (!this.isMasked) {
         this.textSpans[cnt] = tParent;
       } else {
         this.textSpans[cnt] = tSpan;
       }
-
       this.textSpans[cnt].style.display = 'block';
       this.textPaths[cnt] = tSpan;
       cnt += 1;
     }
-
     while (cnt < this.textSpans.length) {
       this.textSpans[cnt].style.display = 'none';
       cnt += 1;
     }
   };
-
   HTextElement.prototype.renderInnerContent = function () {
     this.validateText();
     var svgStyle;
-
     if (this.data.singleShape) {
       if (!this._isFirstFrame && !this.lettersChangedFlag) {
         return;
       }
-
       if (this.isMasked && this.finalTransform._matMdf) {
         // Todo Benchmark if using this is better than getBBox
         this.svgElement.setAttribute('viewBox', -this.finalTransform.mProp.p.v[0] + ' ' + -this.finalTransform.mProp.p.v[1] + ' ' + this.compW + ' ' + this.compH);
@@ -15431,13 +13088,10 @@
         svgStyle.webkitTransform = translation;
       }
     }
-
     this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
-
     if (!this.lettersChangedFlag && !this.textAnimator.lettersChangedFlag) {
       return;
     }
-
     var i;
     var len;
     var count = 0;
@@ -15447,7 +13101,6 @@
     var renderedLetter;
     var textSpan;
     var textPath;
-
     for (i = 0; i < len; i += 1) {
       if (letters[i].n) {
         count += 1;
@@ -15456,7 +13109,6 @@
         textPath = this.textPaths[i];
         renderedLetter = renderedLetters[count];
         count += 1;
-
         if (renderedLetter._mdf.m) {
           if (!this.isMasked) {
             textSpan.style.webkitTransform = renderedLetter.m;
@@ -15464,41 +13116,32 @@
           } else {
             textSpan.setAttribute('transform', renderedLetter.m);
           }
-        } /// /textSpan.setAttribute('opacity',renderedLetter.o);
-
-
+        }
+        /// /textSpan.setAttribute('opacity',renderedLetter.o);
         textSpan.style.opacity = renderedLetter.o;
-
         if (renderedLetter.sw && renderedLetter._mdf.sw) {
           textPath.setAttribute('stroke-width', renderedLetter.sw);
         }
-
         if (renderedLetter.sc && renderedLetter._mdf.sc) {
           textPath.setAttribute('stroke', renderedLetter.sc);
         }
-
         if (renderedLetter.fc && renderedLetter._mdf.fc) {
           textPath.setAttribute('fill', renderedLetter.fc);
           textPath.style.color = renderedLetter.fc;
         }
       }
     }
-
     if (this.innerElem.getBBox && !this.hidden && (this._isFirstFrame || this._mdf)) {
       var boundingBox = this.innerElem.getBBox();
-
       if (this.currentBBox.w !== boundingBox.width) {
         this.currentBBox.w = boundingBox.width;
         this.svgElement.setAttribute('width', boundingBox.width);
       }
-
       if (this.currentBBox.h !== boundingBox.height) {
         this.currentBBox.h = boundingBox.height;
         this.svgElement.setAttribute('height', boundingBox.height);
       }
-
       var margin = 1;
-
       if (this.currentBBox.w !== boundingBox.width + margin * 2 || this.currentBBox.h !== boundingBox.height + margin * 2 || this.currentBBox.x !== boundingBox.x - margin || this.currentBBox.y !== boundingBox.y - margin) {
         this.currentBBox.w = boundingBox.width + margin * 2;
         this.currentBBox.h = boundingBox.height + margin * 2;
@@ -15519,7 +13162,6 @@
     this.initHierarchy();
     var getProp = PropertyFactory.getProp;
     this.pe = getProp(this, data.pe, 0, 0, this);
-
     if (data.ks.p.s) {
       this.px = getProp(this, data.ks.p.x, 1, 0, this);
       this.py = getProp(this, data.ks.p.y, 1, 0, this);
@@ -15527,21 +13169,17 @@
     } else {
       this.p = getProp(this, data.ks.p, 1, 0, this);
     }
-
     if (data.ks.a) {
       this.a = getProp(this, data.ks.a, 1, 0, this);
     }
-
     if (data.ks.or.k.length && data.ks.or.k[0].to) {
       var i;
       var len = data.ks.or.k.length;
-
       for (i = 0; i < len; i += 1) {
         data.ks.or.k[i].to = null;
         data.ks.or.k[i].ti = null;
       }
     }
-
     this.or = getProp(this, data.ks.or, 1, degToRads, this);
     this.or.sh = true;
     this.rx = getProp(this, data.ks.rx, 0, degToRads, this);
@@ -15549,26 +13187,23 @@
     this.rz = getProp(this, data.ks.rz, 0, degToRads, this);
     this.mat = new Matrix();
     this._prevMat = new Matrix();
-    this._isFirstFrame = true; // TODO: find a better way to make the HCamera element to be compatible with the LayerInterface and TransformInterface.
+    this._isFirstFrame = true;
 
+    // TODO: find a better way to make the HCamera element to be compatible with the LayerInterface and TransformInterface.
     this.finalTransform = {
       mProp: this
     };
   }
-
   extendPrototype([BaseElement, FrameElement, HierarchyElement], HCameraElement);
-
   HCameraElement.prototype.setup = function () {
     var i;
     var len = this.comp.threeDElements.length;
     var comp;
     var perspectiveStyle;
     var containerStyle;
-
     for (i = 0; i < len; i += 1) {
       // [perspectiveElem,container]
       comp = this.comp.threeDElements[i];
-
       if (comp.type === '3d') {
         perspectiveStyle = comp.perspectiveElem.style;
         containerStyle = comp.container.style;
@@ -15585,30 +13220,22 @@
       }
     }
   };
-
   HCameraElement.prototype.createElements = function () {};
-
   HCameraElement.prototype.hide = function () {};
-
   HCameraElement.prototype.renderFrame = function () {
     var _mdf = this._isFirstFrame;
     var i;
     var len;
-
     if (this.hierarchy) {
       len = this.hierarchy.length;
-
       for (i = 0; i < len; i += 1) {
         _mdf = this.hierarchy[i].finalTransform.mProp._mdf || _mdf;
       }
     }
-
     if (_mdf || this.pe._mdf || this.p && this.p._mdf || this.px && (this.px._mdf || this.py._mdf || this.pz._mdf) || this.rx._mdf || this.ry._mdf || this.rz._mdf || this.or._mdf || this.a && this.a._mdf) {
       this.mat.reset();
-
       if (this.hierarchy) {
         len = this.hierarchy.length - 1;
-
         for (i = len; i >= 0; i -= 1) {
           var mTransf = this.hierarchy[i].finalTransform.mProp;
           this.mat.translate(-mTransf.p.v[0], -mTransf.p.v[1], mTransf.p.v[2]);
@@ -15618,46 +13245,38 @@
           this.mat.translate(mTransf.a.v[0], mTransf.a.v[1], mTransf.a.v[2]);
         }
       }
-
       if (this.p) {
         this.mat.translate(-this.p.v[0], -this.p.v[1], this.p.v[2]);
       } else {
         this.mat.translate(-this.px.v, -this.py.v, this.pz.v);
       }
-
       if (this.a) {
         var diffVector;
-
         if (this.p) {
           diffVector = [this.p.v[0] - this.a.v[0], this.p.v[1] - this.a.v[1], this.p.v[2] - this.a.v[2]];
         } else {
           diffVector = [this.px.v - this.a.v[0], this.py.v - this.a.v[1], this.pz.v - this.a.v[2]];
         }
-
-        var mag = Math.sqrt(Math.pow(diffVector[0], 2) + Math.pow(diffVector[1], 2) + Math.pow(diffVector[2], 2)); // var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
-
+        var mag = Math.sqrt(Math.pow(diffVector[0], 2) + Math.pow(diffVector[1], 2) + Math.pow(diffVector[2], 2));
+        // var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
         var lookDir = [diffVector[0] / mag, diffVector[1] / mag, diffVector[2] / mag];
         var lookLengthOnXZ = Math.sqrt(lookDir[2] * lookDir[2] + lookDir[0] * lookDir[0]);
         var mRotationX = Math.atan2(lookDir[1], lookLengthOnXZ);
         var mRotationY = Math.atan2(lookDir[0], -lookDir[2]);
         this.mat.rotateY(mRotationY).rotateX(-mRotationX);
       }
-
       this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v);
       this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]);
       this.mat.translate(this.globalData.compSize.w / 2, this.globalData.compSize.h / 2, 0);
       this.mat.translate(0, 0, this.pe.v);
       var hasMatrixChanged = !this._prevMat.equals(this.mat);
-
       if ((hasMatrixChanged || this.pe._mdf) && this.comp.threeDElements) {
         len = this.comp.threeDElements.length;
         var comp;
         var perspectiveStyle;
         var containerStyle;
-
         for (i = 0; i < len; i += 1) {
           comp = this.comp.threeDElements[i];
-
           if (comp.type === '3d') {
             if (hasMatrixChanged) {
               var matValue = this.mat.toCSS();
@@ -15665,7 +13284,6 @@
               containerStyle.transform = matValue;
               containerStyle.webkitTransform = matValue;
             }
-
             if (this.pe._mdf) {
               perspectiveStyle = comp.perspectiveElem.style;
               perspectiveStyle.perspective = this.pe.v + 'px';
@@ -15673,20 +13291,15 @@
             }
           }
         }
-
         this.mat.clone(this._prevMat);
       }
     }
-
     this._isFirstFrame = false;
   };
-
   HCameraElement.prototype.prepareFrame = function (num) {
     this.prepareProperties(num, true);
   };
-
   HCameraElement.prototype.destroy = function () {};
-
   HCameraElement.prototype.getBaseElement = function () {
     return null;
   };
@@ -15695,13 +13308,10 @@
     this.assetData = globalData.getAssetData(data.refId);
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, HBaseElement, HSolidElement, HierarchyElement, FrameElement, RenderableElement], HImageElement);
-
   HImageElement.prototype.createContent = function () {
     var assetPath = this.globalData.getAssetsPath(this.assetData);
     var img = new Image();
-
     if (this.data.hasMask) {
       this.imageElem = createNS('image');
       this.imageElem.setAttribute('width', this.assetData.w + 'px');
@@ -15713,10 +13323,8 @@
     } else {
       this.layerElement.appendChild(img);
     }
-
     img.crossOrigin = 'anonymous';
     img.src = assetPath;
-
     if (this.data.ln) {
       this.baseElement.setAttribute('id', this.data.ln);
     }
@@ -15750,26 +13358,20 @@
     this.supports3d = true;
     this.rendererType = 'html';
   }
-
   extendPrototype([BaseRenderer], HybridRendererBase);
   HybridRendererBase.prototype.buildItem = SVGRenderer.prototype.buildItem;
-
   HybridRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
     }
   };
-
   HybridRendererBase.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);
@@ -15778,17 +13380,14 @@
         var nextDOMElement;
         var nextLayer;
         var 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);
@@ -15801,61 +13400,46 @@
       this.addTo3dContainer(newDOMElement, pos);
     }
   };
-
   HybridRendererBase.prototype.createShape = function (data) {
     if (!this.supports3d) {
       return new SVGShapeElement(data, this.globalData, this);
     }
-
     return new HShapeElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createText = function (data) {
     if (!this.supports3d) {
       return new SVGTextLottieElement(data, this.globalData, this);
     }
-
     return new HTextElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createCamera = function (data) {
     this.camera = new HCameraElement(data, this.globalData, this);
     return this.camera;
   };
-
   HybridRendererBase.prototype.createImage = function (data) {
     if (!this.supports3d) {
       return new IImageElement(data, this.globalData, this);
     }
-
     return new HImageElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createSolid = function (data) {
     if (!this.supports3d) {
       return new ISolidElement(data, this.globalData, this);
     }
-
     return new HSolidElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
-
   HybridRendererBase.prototype.getThreeDContainerByPos = function (pos) {
     var i = 0;
     var 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;
     }
-
     return null;
   };
-
   HybridRendererBase.prototype.createThreeDContainer = function (pos, type) {
     var perspectiveElem = createTag('div');
     var style;
@@ -15863,7 +13447,6 @@
     styleDiv(perspectiveElem);
     var container = createTag('div');
     styleDiv(container);
-
     if (type === '3d') {
       style = perspectiveElem.style;
       style.width = this.globalData.compSize.w + 'px';
@@ -15877,9 +13460,8 @@
       containerStyle.transform = matrix;
       containerStyle.webkitTransform = matrix;
     }
-
-    perspectiveElem.appendChild(container); // this.resizerElem.appendChild(perspectiveElem);
-
+    perspectiveElem.appendChild(container);
+    // this.resizerElem.appendChild(perspectiveElem);
     var threeDContainerData = {
       container: container,
       perspectiveElem: perspectiveElem,
@@ -15890,68 +13472,54 @@
     this.threeDElements.push(threeDContainerData);
     return threeDContainerData;
   };
-
   HybridRendererBase.prototype.build3dContainers = function () {
     var i;
     var 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 -= 1) {
       this.resizerElem.appendChild(this.threeDElements[i].perspectiveElem);
     }
   };
-
   HybridRendererBase.prototype.addTo3dContainer = function (elem, pos) {
     var i = 0;
     var 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;
     }
   };
-
   HybridRendererBase.prototype.configAnimation = function (animData) {
     var resizerElem = createTag('div');
     var wrapper = this.animationItem.wrapper;
@@ -15963,11 +13531,9 @@
     style.transformStyle = 'flat';
     style.mozTransformStyle = 'flat';
     style.webkitTransformStyle = 'flat';
-
     if (this.renderConfig.className) {
       resizerElem.setAttribute('class', this.renderConfig.className);
     }
-
     wrapper.appendChild(resizerElem);
     style.overflow = 'hidden';
     var svg = createNS('svg');
@@ -15977,8 +13543,8 @@
     this.resizerElem.appendChild(svg);
     var defs = createNS('defs');
     svg.appendChild(defs);
-    this.data = animData; // Mask animation
-
+    this.data = animData;
+    // Mask animation
     this.setupGlobalData(animData, svg);
     this.globalData.defs = defs;
     this.layers = animData.layers;
@@ -15986,28 +13552,23 @@
     this.build3dContainers();
     this.updateContainerSize();
   };
-
   HybridRendererBase.prototype.destroy = function () {
     if (this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     this.animationItem.container = null;
     this.globalData.defs = null;
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.destroyed = true;
     this.animationItem = null;
   };
-
   HybridRendererBase.prototype.updateContainerSize = function () {
     var elementWidth = this.animationItem.wrapper.offsetWidth;
     var elementHeight = this.animationItem.wrapper.offsetHeight;
@@ -16017,7 +13578,6 @@
     var sy;
     var tx;
     var ty;
-
     if (animationRel > elementRel) {
       sx = elementWidth / this.globalData.compSize.w;
       sy = elementWidth / this.globalData.compSize.w;
@@ -16029,25 +13589,19 @@
       tx = (elementWidth - this.globalData.compSize.w * (elementHeight / this.globalData.compSize.h)) / 2;
       ty = 0;
     }
-
     var style = this.resizerElem.style;
     style.webkitTransform = 'matrix3d(' + sx + ',0,0,0,0,' + sy + ',0,0,0,0,1,0,' + tx + ',' + ty + ',0,1)';
     style.transform = style.webkitTransform;
   };
-
   HybridRendererBase.prototype.renderFrame = SVGRenderer.prototype.renderFrame;
-
   HybridRendererBase.prototype.hide = function () {
     this.resizerElem.style.display = 'none';
   };
-
   HybridRendererBase.prototype.show = function () {
     this.resizerElem.style.display = 'block';
   };
-
   HybridRendererBase.prototype.initItems = function () {
     this.buildAllItems();
-
     if (this.camera) {
       this.camera.setup();
     } else {
@@ -16055,7 +13609,6 @@
       var cHeight = this.globalData.compSize.h;
       var i;
       var len = this.threeDElements.length;
-
       for (i = 0; i < len; i += 1) {
         var style = this.threeDElements[i].perspectiveElem.style;
         style.webkitPerspective = Math.sqrt(Math.pow(cWidth, 2) + Math.pow(cHeight, 2)) + 'px';
@@ -16063,12 +13616,10 @@
       }
     }
   };
-
   HybridRendererBase.prototype.searchExtraCompositions = function (assets) {
     var i;
     var 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);
@@ -16089,14 +13640,11 @@
       _placeholder: true
     };
   }
-
   extendPrototype([HybridRendererBase, ICompElement, HBaseElement], HCompElement);
   HCompElement.prototype._createBaseContainerElements = HCompElement.prototype.createContainerElements;
-
   HCompElement.prototype.createContainerElements = function () {
-    this._createBaseContainerElements(); // divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
-
-
+    this._createBaseContainerElements();
+    // divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
     if (this.data.hasMask) {
       this.svgElement.setAttribute('width', this.data.w);
       this.svgElement.setAttribute('height', this.data.h);
@@ -16105,31 +13653,25 @@
       this.transformedElement = this.layerElement;
     }
   };
-
   HCompElement.prototype.addTo3dContainer = function (elem, pos) {
     var j = 0;
     var nextElement;
-
     while (j < pos) {
       if (this.elements[j] && this.elements[j].getBaseElement) {
         nextElement = this.elements[j].getBaseElement();
       }
-
       j += 1;
     }
-
     if (nextElement) {
       this.layerElement.insertBefore(elem, nextElement);
     } else {
       this.layerElement.appendChild(elem);
     }
   };
-
   HCompElement.prototype.createComp = function (data) {
     if (!this.supports3d) {
       return new SVGCompElement(data, this.globalData, this);
     }
-
     return new HCompElement(data, this.globalData, this);
   };
 
@@ -16162,14 +13704,11 @@
     this.supports3d = true;
     this.rendererType = 'html';
   }
-
   extendPrototype([HybridRendererBase], HybridRenderer);
-
   HybridRenderer.prototype.createComp = function (data) {
     if (!this.supports3d) {
       return new SVGCompElement(data, this.globalData, this);
     }
-
     return new HCompElement(data, this.globalData, this);
   };
 
@@ -16178,18 +13717,15 @@
       function _thisLayerFunction(name) {
         var i = 0;
         var len = comp.layers.length;
-
         while (i < len) {
           if (comp.layers[i].nm === name || comp.layers[i].ind === name) {
             return comp.elements[i].layerInterface;
           }
-
           i += 1;
         }
-
-        return null; // return {active:false};
+        return null;
+        // return {active:false};
       }
-
       Object.defineProperty(_thisLayerFunction, '_name', {
         value: comp.data.nm
       });
@@ -16205,10 +13741,8 @@
     };
   }();
 
-  function _typeof$2(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$2 = function _typeof(obj) { return typeof obj; }; } else { _typeof$2 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$2(obj); }
-
+  function _typeof$2(o) { "@babel/helpers - typeof"; return _typeof$2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$2(o); }
   /* eslint-disable */
-
   /*
    Copyright 2014 David Bau.
 
@@ -16232,105 +13766,103 @@
    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
    */
+
   function seedRandom(pool, math) {
     //
     // The following constants are related to IEEE 754 limits.
     //
     var global = this,
-        width = 256,
-        // each RC4 output is 0 <= x < 256
-    chunks = 6,
-        // at least six RC4 outputs for each double
-    digits = 52,
-        // there are 52 significant digits in a double
-    rngname = 'random',
-        // rngname: name for Math.random and Math.seedrandom
-    startdenom = math.pow(width, chunks),
-        significance = math.pow(2, digits),
-        overflow = significance * 2,
-        mask = width - 1,
-        nodecrypto; // node.js crypto module, initialized at the bottom.
+      width = 256,
+      // each RC4 output is 0 <= x < 256
+      chunks = 6,
+      // at least six RC4 outputs for each double
+      digits = 52,
+      // there are 52 significant digits in a double
+      rngname = 'random',
+      // rngname: name for Math.random and Math.seedrandom
+      startdenom = math.pow(width, chunks),
+      significance = math.pow(2, digits),
+      overflow = significance * 2,
+      mask = width - 1,
+      nodecrypto; // node.js crypto module, initialized at the bottom.
+
     //
     // seedrandom()
     // This is the seedrandom function described above.
     //
-
     function seedrandom(seed, options, callback) {
       var key = [];
       options = options === true ? {
         entropy: true
-      } : options || {}; // Flatten the seed string or build one from local entropy if needed.
+      } : options || {};
 
-      var shortseed = mixkey(flatten(options.entropy ? [seed, tostring(pool)] : seed === null ? autoseed() : seed, 3), key); // Use the seed to initialize an ARC4 generator.
+      // Flatten the seed string or build one from local entropy if needed.
+      var shortseed = mixkey(flatten(options.entropy ? [seed, tostring(pool)] : seed === null ? autoseed() : seed, 3), key);
 
-      var arc4 = new ARC4(key); // This function returns a random double in [0, 1) that contains
+      // Use the seed to initialize an ARC4 generator.
+      var arc4 = new ARC4(key);
+
+      // This function returns a random double in [0, 1) that contains
       // randomness in every bit of the mantissa of the IEEE 754 value.
-
       var prng = function prng() {
         var n = arc4.g(chunks),
-            // Start with a numerator n < 2 ^ 48
-        d = startdenom,
-            //   and denominator d = 2 ^ 48.
-        x = 0; //   and no 'extra last byte'.
-
+          // Start with a numerator n < 2 ^ 48
+          d = startdenom,
+          //   and denominator d = 2 ^ 48.
+          x = 0; //   and no 'extra last byte'.
         while (n < significance) {
           // Fill up all significant digits by
           n = (n + x) * width; //   shifting numerator and
-
           d *= width; //   denominator and generating a
-
           x = arc4.g(1); //   new least-significant-byte.
         }
-
         while (n >= overflow) {
           // To avoid rounding up, before adding
           n /= 2; //   last byte, shift everything
-
           d /= 2; //   right using integer math until
-
           x >>>= 1; //   we have exactly the desired bits.
         }
-
         return (n + x) / d; // Form the number within [0, 1).
       };
-
       prng.int32 = function () {
         return arc4.g(4) | 0;
       };
-
       prng.quick = function () {
         return arc4.g(4) / 0x100000000;
       };
+      prng["double"] = prng;
 
-      prng["double"] = prng; // Mix the randomness into accumulated entropy.
+      // Mix the randomness into accumulated entropy.
+      mixkey(tostring(arc4.S), pool);
 
-      mixkey(tostring(arc4.S), pool); // Calling convention: what to return as a function of prng, seed, is_math.
-
+      // Calling convention: what to return as a function of prng, seed, is_math.
       return (options.pass || callback || function (prng, seed, is_math_call, state) {
         if (state) {
           // Load the arc4 state from the given state if it has an S array.
           if (state.S) {
             copy(state, arc4);
-          } // Only provide the .state method if requested via options.state.
-
-
+          }
+          // Only provide the .state method if requested via options.state.
           prng.state = function () {
             return copy(arc4, {});
           };
-        } // If called as a method of Math (Math.seedrandom()), mutate
+        }
+
+        // If called as a method of Math (Math.seedrandom()), mutate
         // Math.random because that is how seedrandom.js has worked since v1.0.
-
-
         if (is_math_call) {
           math[rngname] = prng;
           return seed;
-        } // Otherwise, it is a newer calling convention, so return the
+        }
+
+        // Otherwise, it is a newer calling convention, so return the
         // prng directly.
         else return prng;
       })(prng, shortseed, 'global' in options ? options.global : this == math, options.state);
     }
+    math['seed' + rngname] = seedrandom;
 
-    math['seed' + rngname] = seedrandom; //
+    //
     // ARC4
     //
     // An ARC4 implementation.  The constructor takes a key in the form of
@@ -16340,71 +13872,68 @@
     // the next (count) outputs from ARC4.  Its return value is a number x
     // that is in the range 0 <= x < (width ^ count).
     //
-
     function ARC4(key) {
       var t,
-          keylen = key.length,
-          me = this,
-          i = 0,
-          j = me.i = me.j = 0,
-          s = me.S = []; // The empty key [] is treated as [0].
+        keylen = key.length,
+        me = this,
+        i = 0,
+        j = me.i = me.j = 0,
+        s = me.S = [];
 
+      // The empty key [] is treated as [0].
       if (!keylen) {
         key = [keylen++];
-      } // Set up S using the standard key scheduling algorithm.
+      }
 
-
+      // Set up S using the standard key scheduling algorithm.
       while (i < width) {
         s[i] = i++;
       }
-
       for (i = 0; i < width; i++) {
         s[i] = s[j = mask & j + key[i % keylen] + (t = s[i])];
         s[j] = t;
-      } // The "g" method returns the next (count) outputs as one number.
+      }
 
-
+      // The "g" method returns the next (count) outputs as one number.
       me.g = function (count) {
         // Using instance members instead of closure state nearly doubles speed.
         var t,
-            r = 0,
-            i = me.i,
-            j = me.j,
-            s = me.S;
-
+          r = 0,
+          i = me.i,
+          j = me.j,
+          s = me.S;
         while (count--) {
           t = s[i = mask & i + 1];
           r = r * width + s[mask & (s[i] = s[j = mask & j + t]) + (s[j] = t)];
         }
-
         me.i = i;
         me.j = j;
-        return r; // For robust unpredictability, the function call below automatically
+        return r;
+        // For robust unpredictability, the function call below automatically
         // discards an initial batch of values.  This is called RC4-drop[256].
         // See http://google.com/search?q=rsa+fluhrer+response&btnI
       };
-    } //
+    }
+
+    //
     // copy()
     // Copies internal state of ARC4 to or from a plain object.
     //
-
-
     function copy(f, t) {
       t.i = f.i;
       t.j = f.j;
       t.S = f.S.slice();
       return t;
-    } //
+    }
+
+    //
     // flatten()
     // Converts an object tree to nested arrays of strings.
     //
-
-
     function flatten(obj, depth) {
       var result = [],
-          typ = _typeof$2(obj),
-          prop;
-
+        typ = _typeof$2(obj),
+        prop;
       if (depth && typ == 'object') {
         for (prop in obj) {
           try {
@@ -16412,72 +13941,69 @@
           } catch (e) {}
         }
       }
-
       return result.length ? result : typ == 'string' ? obj : obj + '\0';
-    } //
+    }
+
+    //
     // mixkey()
     // Mixes a string seed into a key that is an array of integers, and
     // returns a shortened string seed that is equivalent to the result key.
     //
-
-
     function mixkey(seed, key) {
       var stringseed = seed + '',
-          smear,
-          j = 0;
-
+        smear,
+        j = 0;
       while (j < stringseed.length) {
         key[mask & j] = mask & (smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++);
       }
-
       return tostring(key);
-    } //
+    }
+
+    //
     // autoseed()
     // Returns an object for autoseeding, using window.crypto and Node crypto
     // module if available.
     //
-
-
     function autoseed() {
       try {
         if (nodecrypto) {
           return tostring(nodecrypto.randomBytes(width));
         }
-
         var out = new Uint8Array(width);
         (global.crypto || global.msCrypto).getRandomValues(out);
         return tostring(out);
       } catch (e) {
         var browser = global.navigator,
-            plugins = browser && browser.plugins;
+          plugins = browser && browser.plugins;
         return [+new Date(), global, plugins, global.screen, tostring(pool)];
       }
-    } //
+    }
+
+    //
     // tostring()
     // Converts an array of charcodes to a string
     //
-
-
     function tostring(a) {
       return String.fromCharCode.apply(0, a);
-    } //
+    }
+
+    //
     // When seedrandom.js is loaded, we immediately mix a few bits
     // from the built-in RNG into the entropy pool.  Because we do
     // not want to interfere with deterministic PRNG state later,
     // seedrandom will not call math.random on its own again after
     // initialization.
     //
+    mixkey(math.random(), pool);
 
-
-    mixkey(math.random(), pool); //
+    //
     // Nodejs and AMD support: export the implementation as a module using
     // either convention.
     //
+
     // End anonymous scope, and pass initial values.
   }
-
   ;
-
   function initialize$2(BMMath) {
     seedRandom([], BMMath);
   }
@@ -16486,8 +14012,7 @@
     SHAPE: 'shape'
   };
 
-  function _typeof$1(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$1 = function _typeof(obj) { return typeof obj; }; } else { _typeof$1 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$1(obj); }
-
+  function _typeof$1(o) { "@babel/helpers - typeof"; return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$1(o); }
   var ExpressionManager = function () {
     'use strict';
 
@@ -16500,289 +14025,214 @@
     var frames = null;
     var _lottieGlobal = {};
     initialize$2(BMMath);
-
     function resetFrame() {
       _lottieGlobal = {};
     }
-
     function $bm_isInstanceOfArray(arr) {
       return arr.constructor === Array || arr.constructor === Float32Array;
     }
-
     function isNumerable(tOfV, v) {
       return tOfV === 'number' || v instanceof Number || tOfV === 'boolean' || tOfV === 'string';
     }
-
     function $bm_neg(a) {
       var tOfA = _typeof$1(a);
-
       if (tOfA === 'number' || a instanceof Number || tOfA === 'boolean') {
         return -a;
       }
-
       if ($bm_isInstanceOfArray(a)) {
         var i;
         var lenA = a.length;
         var retArr = [];
-
         for (i = 0; i < lenA; i += 1) {
           retArr[i] = -a[i];
         }
-
         return retArr;
       }
-
       if (a.propType) {
         return a.v;
       }
-
       return -a;
     }
-
     var easeInBez = BezierFactory.getBezierEasing(0.333, 0, 0.833, 0.833, 'easeIn').get;
     var easeOutBez = BezierFactory.getBezierEasing(0.167, 0.167, 0.667, 1, 'easeOut').get;
     var easeInOutBez = BezierFactory.getBezierEasing(0.33, 0, 0.667, 1, 'easeInOut').get;
-
     function sum(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b) || tOfA === 'string' || tOfB === 'string') {
         return a + b;
       }
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         a = a.slice(0);
         a[0] += b;
         return a;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         b = b.slice(0);
         b[0] = a + b[0];
         return b;
       }
-
       if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
         var i = 0;
         var lenA = a.length;
         var lenB = b.length;
         var retArr = [];
-
         while (i < lenA || i < lenB) {
           if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
             retArr[i] = a[i] + b[i];
           } else {
             retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
           }
-
           i += 1;
         }
-
         return retArr;
       }
-
       return 0;
     }
-
     var add = sum;
-
     function sub(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         if (tOfA === 'string') {
           a = parseInt(a, 10);
         }
-
         if (tOfB === 'string') {
           b = parseInt(b, 10);
         }
-
         return a - b;
       }
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         a = a.slice(0);
         a[0] -= b;
         return a;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         b = b.slice(0);
         b[0] = a - b[0];
         return b;
       }
-
       if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
         var i = 0;
         var lenA = a.length;
         var lenB = b.length;
         var retArr = [];
-
         while (i < lenA || i < lenB) {
           if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
             retArr[i] = a[i] - b[i];
           } else {
             retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
           }
-
           i += 1;
         }
-
         return retArr;
       }
-
       return 0;
     }
-
     function mul(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       var arr;
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         return a * b;
       }
-
       var i;
       var len;
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         len = a.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a[i] * b;
         }
-
         return arr;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         len = b.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a * b[i];
         }
-
         return arr;
       }
-
       return 0;
     }
-
     function div(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       var arr;
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         return a / b;
       }
-
       var i;
       var len;
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         len = a.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a[i] / b;
         }
-
         return arr;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         len = b.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a / b[i];
         }
-
         return arr;
       }
-
       return 0;
     }
-
     function mod(a, b) {
       if (typeof a === 'string') {
         a = parseInt(a, 10);
       }
-
       if (typeof b === 'string') {
         b = parseInt(b, 10);
       }
-
       return a % b;
     }
-
     var $bm_sum = sum;
     var $bm_sub = sub;
     var $bm_mul = mul;
     var $bm_div = div;
     var $bm_mod = mod;
-
     function clamp(num, min, max) {
       if (min > max) {
         var mm = max;
         max = min;
         min = mm;
       }
-
       return Math.min(Math.max(num, min), max);
     }
-
     function radiansToDegrees(val) {
       return val / degToRads;
     }
-
     var radians_to_degrees = radiansToDegrees;
-
     function degreesToRadians(val) {
       return val * degToRads;
     }
-
     var degrees_to_radians = radiansToDegrees;
     var helperLengthArray = [0, 0, 0, 0, 0, 0];
-
     function length(arr1, arr2) {
       if (typeof arr1 === 'number' || arr1 instanceof Number) {
         arr2 = arr2 || 0;
         return Math.abs(arr1 - arr2);
       }
-
       if (!arr2) {
         arr2 = helperLengthArray;
       }
-
       var i;
       var len = Math.min(arr1.length, arr2.length);
       var addedLength = 0;
-
       for (i = 0; i < len; i += 1) {
         addedLength += Math.pow(arr2[i] - arr1[i], 2);
       }
-
       return Math.sqrt(addedLength);
     }
-
     function normalize(vec) {
       return div(vec, length(vec));
     }
-
     function rgbToHsl(val) {
       var r = val[0];
       var g = val[1];
@@ -16792,38 +14242,29 @@
       var h;
       var s;
       var l = (max + min) / 2;
-
       if (max === min) {
         h = 0; // achromatic
-
         s = 0; // achromatic
       } else {
         var d = max - min;
         s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
-
         switch (max) {
           case r:
             h = (g - b) / d + (g < b ? 6 : 0);
             break;
-
           case g:
             h = (b - r) / d + 2;
             break;
-
           case b:
             h = (r - g) / d + 4;
             break;
-
           default:
             break;
         }
-
         h /= 6;
       }
-
       return [h, s, l, val[3]];
     }
-
     function hue2rgb(p, q, t) {
       if (t < 0) t += 1;
       if (t > 1) t -= 1;
@@ -16832,7 +14273,6 @@
       if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
       return p;
     }
-
     function hslToRgb(val) {
       var h = val[0];
       var s = val[1];
@@ -16840,12 +14280,9 @@
       var r;
       var g;
       var b;
-
       if (s === 0) {
         r = l; // achromatic
-
         b = l; // achromatic
-
         g = l; // achromatic
       } else {
         var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
@@ -16854,10 +14291,8 @@
         g = hue2rgb(p, q, h);
         b = hue2rgb(p, q, h - 1 / 3);
       }
-
       return [r, g, b, val[3]];
     }
-
     function linear(t, tMin, tMax, value1, value2) {
       if (value1 === undefined || value2 === undefined) {
         value1 = tMin;
@@ -16865,38 +14300,29 @@
         tMin = 0;
         tMax = 1;
       }
-
       if (tMax < tMin) {
         var _tMin = tMax;
         tMax = tMin;
         tMin = _tMin;
       }
-
       if (t <= tMin) {
         return value1;
       }
-
       if (t >= tMax) {
         return value2;
       }
-
       var perc = tMax === tMin ? 0 : (t - tMin) / (tMax - tMin);
-
       if (!value1.length) {
         return value1 + (value2 - value1) * perc;
       }
-
       var i;
       var len = value1.length;
       var arr = createTypedArray('float32', len);
-
       for (i = 0; i < len; i += 1) {
         arr[i] = value1[i] + (value2[i] - value1[i]) * perc;
       }
-
       return arr;
     }
-
     function random(min, max) {
       if (max === undefined) {
         if (min === undefined) {
@@ -16907,33 +14333,25 @@
           min = undefined;
         }
       }
-
       if (max.length) {
         var i;
         var len = max.length;
-
         if (!min) {
           min = createTypedArray('float32', len);
         }
-
         var arr = createTypedArray('float32', len);
         var rnd = BMMath.random();
-
         for (i = 0; i < len; i += 1) {
           arr[i] = min[i] + rnd * (max[i] - min[i]);
         }
-
         return arr;
       }
-
       if (min === undefined) {
         min = 0;
       }
-
       var rndm = BMMath.random();
       return min + rndm * (max - min);
     }
-
     function createPath(points, inTangents, outTangents, closed) {
       var i;
       var len = points.length;
@@ -16942,37 +14360,31 @@
       var arrPlaceholder = [0, 0];
       var inVertexPoint;
       var outVertexPoint;
-
       for (i = 0; i < len; i += 1) {
         inVertexPoint = inTangents && inTangents[i] ? inTangents[i] : arrPlaceholder;
         outVertexPoint = outTangents && outTangents[i] ? outTangents[i] : arrPlaceholder;
         path.setTripleAt(points[i][0], points[i][1], outVertexPoint[0] + points[i][0], outVertexPoint[1] + points[i][1], inVertexPoint[0] + points[i][0], inVertexPoint[1] + points[i][1], i, true);
       }
-
       return path;
     }
-
     function initiateExpression(elem, data, property) {
       // Bail out if we don't want expressions
       function noOp(_value) {
         return _value;
       }
-
       if (!elem.globalData.renderConfig.runExpressions) {
         return noOp;
       }
-
       var val = data.x;
       var needsVelocity = /velocity(?![\w\d])/.test(val);
-
       var _needsRandom = val.indexOf('random') !== -1;
-
       var elemType = elem.data.ty;
       var transform;
       var $bm_transform;
       var content;
       var effect;
       var thisProperty = property;
+      thisProperty._name = elem.data.nm;
       thisProperty.valueAtTime = thisProperty.getValueAtTime;
       Object.defineProperty(thisProperty, 'value', {
         get: function get() {
@@ -17005,13 +14417,11 @@
       var mask;
       var valueAtTime;
       var velocityAtTime;
-      var scoped_bm_rt; // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
-
+      var scoped_bm_rt;
+      // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
       var expression_function = eval('[function _expression_function(){' + val + ';scoped_bm_rt=$bm_rt}]')[0]; // eslint-disable-line no-eval
-
       var numKeys = property.kf ? data.k.length : 0;
       var active = !this.data || this.data.hd !== true;
-
       var wiggle = function wiggle(freq, amp) {
         var iWiggle;
         var j;
@@ -17021,84 +14431,67 @@
         var iterations = Math.floor(time * freq);
         iWiggle = 0;
         j = 0;
-
         while (iWiggle < iterations) {
           // var rnd = BMMath.random();
           for (j = 0; j < lenWiggle; j += 1) {
-            addedAmps[j] += -amp + amp * 2 * BMMath.random(); // addedAmps[j] += -amp + amp*2*rnd;
+            addedAmps[j] += -amp + amp * 2 * BMMath.random();
+            // addedAmps[j] += -amp + amp*2*rnd;
           }
-
           iWiggle += 1;
-        } // var rnd2 = BMMath.random();
-
-
+        }
+        // var rnd2 = BMMath.random();
         var periods = time * freq;
         var perc = periods - Math.floor(periods);
         var arr = createTypedArray('float32', lenWiggle);
-
         if (lenWiggle > 1) {
           for (j = 0; j < lenWiggle; j += 1) {
-            arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc; // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
+            arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc;
+            // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
             // arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc);
           }
-
           return arr;
         }
-
         return this.pv + addedAmps[0] + (-amp + amp * 2 * BMMath.random()) * perc;
       }.bind(this);
-
       if (thisProperty.loopIn) {
         loopIn = thisProperty.loopIn.bind(thisProperty);
         loop_in = loopIn;
       }
-
       if (thisProperty.loopOut) {
         loopOut = thisProperty.loopOut.bind(thisProperty);
         loop_out = loopOut;
       }
-
       if (thisProperty.smooth) {
         smooth = thisProperty.smooth.bind(thisProperty);
       }
-
       function loopInDuration(type, duration) {
         return loopIn(type, duration, true);
       }
-
       function loopOutDuration(type, duration) {
         return loopOut(type, duration, true);
       }
-
       if (this.getValueAtTime) {
         valueAtTime = this.getValueAtTime.bind(this);
       }
-
       if (this.getVelocityAtTime) {
         velocityAtTime = this.getVelocityAtTime.bind(this);
       }
-
       var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface);
-
       function lookAt(elem1, elem2) {
         var fVec = [elem2[0] - elem1[0], elem2[1] - elem1[1], elem2[2] - elem1[2]];
         var pitch = Math.atan2(fVec[0], Math.sqrt(fVec[1] * fVec[1] + fVec[2] * fVec[2])) / degToRads;
         var yaw = -Math.atan2(fVec[1], fVec[2]) / degToRads;
         return [yaw, pitch, 0];
       }
-
       function easeOut(t, tMin, tMax, val1, val2) {
         return applyEase(easeOutBez, t, tMin, tMax, val1, val2);
       }
-
       function easeIn(t, tMin, tMax, val1, val2) {
         return applyEase(easeInBez, t, tMin, tMax, val1, val2);
       }
-
       function ease(t, tMin, tMax, val1, val2) {
         return applyEase(easeInOutBez, t, tMin, tMax, val1, val2);
       }
-
       function applyEase(fn, t, tMin, tMax, val1, val2) {
         if (val1 === undefined) {
           val1 = tMin;
@@ -17106,43 +14499,34 @@
         } else {
           t = (t - tMin) / (tMax - tMin);
         }
-
         if (t > 1) {
           t = 1;
         } else if (t < 0) {
           t = 0;
         }
-
         var mult = fn(t);
-
         if ($bm_isInstanceOfArray(val1)) {
           var iKey;
           var lenKey = val1.length;
           var arr = createTypedArray('float32', lenKey);
-
           for (iKey = 0; iKey < lenKey; iKey += 1) {
             arr[iKey] = (val2[iKey] - val1[iKey]) * mult + val1[iKey];
           }
-
           return arr;
         }
-
         return (val2 - val1) * mult + val1;
       }
-
       function nearestKey(time) {
         var iKey;
         var lenKey = data.k.length;
         var index;
         var keyTime;
-
         if (!data.k.length || typeof data.k[0] === 'number') {
           index = 0;
           keyTime = 0;
         } else {
           index = -1;
           time *= elem.comp.globalData.frameRate;
-
           if (time < data.k[0].t) {
             index = 1;
             keyTime = data.k[0].t;
@@ -17160,33 +14544,27 @@
                   index = iKey + 1;
                   keyTime = data.k[iKey].t;
                 }
-
                 break;
               }
             }
-
             if (index === -1) {
               index = iKey + 1;
               keyTime = data.k[iKey].t;
             }
           }
         }
-
         var obKey = {};
         obKey.index = index;
         obKey.time = keyTime / elem.comp.globalData.frameRate;
         return obKey;
       }
-
       function key(ind) {
         var obKey;
         var iKey;
         var lenKey;
-
         if (!data.k.length || typeof data.k[0] === 'number') {
           throw new Error('The property has no keyframe at index ' + ind);
         }
-
         ind -= 1;
         obKey = {
           time: data.k[ind].t / elem.comp.globalData.frameRate,
@@ -17194,72 +14572,55 @@
         };
         var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e;
         lenKey = arr.length;
-
         for (iKey = 0; iKey < lenKey; iKey += 1) {
           obKey[iKey] = arr[iKey];
           obKey.value[iKey] = arr[iKey];
         }
-
         return obKey;
       }
-
       function framesToTime(fr, fps) {
         if (!fps) {
           fps = elem.comp.globalData.frameRate;
         }
-
         return fr / fps;
       }
-
       function timeToFrames(t, fps) {
         if (!t && t !== 0) {
           t = time;
         }
-
         if (!fps) {
           fps = elem.comp.globalData.frameRate;
         }
-
         return t * fps;
       }
-
       function seedRandom(seed) {
         BMMath.seedrandom(randSeed + seed);
       }
-
       function sourceRectAtTime() {
         return elem.sourceRectAtTime();
       }
-
       function substring(init, end) {
         if (typeof value === 'string') {
           if (end === undefined) {
             return value.substring(init);
           }
-
           return value.substring(init, end);
         }
-
         return '';
       }
-
       function substr(init, end) {
         if (typeof value === 'string') {
           if (end === undefined) {
             return value.substr(init);
           }
-
           return value.substr(init, end);
         }
-
         return '';
       }
-
       function posterizeTime(framesPerSecond) {
         time = framesPerSecond === 0 ? 0 : Math.floor(time * framesPerSecond) / framesPerSecond;
         value = valueAtTime(time);
       }
-
       var time;
       var velocity;
       var value;
@@ -17272,21 +14633,17 @@
       var parent;
       var randSeed = Math.floor(Math.random() * 1000000);
       var globalData = elem.globalData;
-
       function executeExpression(_value) {
         // globalData.pushExpression();
         value = _value;
-
         if (this.frameExpressionId === elem.globalData.frameId && this.propType !== 'textSelector') {
           return value;
         }
-
         if (this.propType === 'textSelector') {
           textIndex = this.textIndex;
           textTotal = this.textTotal;
           selectorValue = this.selectorValue;
         }
-
         if (!thisLayer) {
           text = elem.layerInterface.text;
           thisLayer = elem.layerInterface;
@@ -17298,11 +14655,9 @@
           mask = thisLayer.mask ? thisLayer.mask.bind(thisLayer) : null;
           fromCompToSurface = fromComp;
         }
-
         if (!transform) {
           transform = elem.layerInterface('ADBE Transform Group');
           $bm_transform = transform;
-
           if (transform) {
             anchorPoint = transform.anchorPoint;
             /* position = transform.position;
@@ -17310,44 +14665,35 @@
                       scale = transform.scale; */
           }
         }
-
         if (elemType === 4 && !content) {
           content = thisLayer('ADBE Root Vectors Group');
         }
-
         if (!effect) {
           effect = thisLayer(4);
         }
-
         hasParent = !!(elem.hierarchy && elem.hierarchy.length);
-
         if (hasParent && !parent) {
           parent = elem.hierarchy[0].layerInterface;
         }
-
         time = this.comp.renderedFrame / this.comp.globalData.frameRate;
-
         if (_needsRandom) {
           seedRandom(randSeed + time);
         }
-
         if (needsVelocity) {
           velocity = velocityAtTime(time);
         }
-
         expression_function();
-        this.frameExpressionId = elem.globalData.frameId; // TODO: Check if it's possible to return on ShapeInterface the .v value
-        // Changed this to a ternary operation because Rollup failed compiling it correctly
+        this.frameExpressionId = elem.globalData.frameId;
 
+        // TODO: Check if it's possible to return on ShapeInterface the .v value
+        // Changed this to a ternary operation because Rollup failed compiling it correctly
         scoped_bm_rt = scoped_bm_rt.propType === propTypes.SHAPE ? scoped_bm_rt.v : scoped_bm_rt;
         return scoped_bm_rt;
-      } // Bundlers will see these as dead code and unless we reference them
-
-
+      }
+      // Bundlers will see these as dead code and unless we reference them
       executeExpression.__preventDeadCodeRemoval = [$bm_transform, anchorPoint, time, velocity, inPoint, outPoint, width, height, name, loop_in, loop_out, smooth, toComp, fromCompToSurface, toWorld, fromWorld, mask, position, rotation, scale, thisComp, numKeys, active, wiggle, loopInDuration, loopOutDuration, comp, lookAt, easeOut, easeIn, ease, nearestKey, key, text, textIndex, textTotal, selectorValue, framesToTime, timeToFrames, sourceRectAtTime, substring, substr, posterizeTime, index, globalData];
       return executeExpression;
     }
-
     ob.initiateExpression = initiateExpression;
     ob.__preventDeadCodeRemoval = [window, document, XMLHttpRequest, fetch, frames, $bm_neg, add, $bm_sum, $bm_sub, $bm_mul, $bm_div, $bm_mod, clamp, radians_to_degrees, degreesToRadians, degrees_to_radians, normalize, rgbToHsl, hslToRgb, linear, random, createPath, _lottieGlobal];
     ob.resetFrame = resetFrame;
@@ -17358,47 +14704,37 @@
     var ob = {};
     ob.initExpressions = initExpressions;
     ob.resetFrame = ExpressionManager.resetFrame;
-
     function initExpressions(animation) {
       var stackCount = 0;
       var registers = [];
-
       function pushExpression() {
         stackCount += 1;
       }
-
       function popExpression() {
         stackCount -= 1;
-
         if (stackCount === 0) {
           releaseInstances();
         }
       }
-
       function registerExpressionProperty(expression) {
         if (registers.indexOf(expression) === -1) {
           registers.push(expression);
         }
       }
-
       function releaseInstances() {
         var i;
         var len = registers.length;
-
         for (i = 0; i < len; i += 1) {
           registers[i].release();
         }
-
         registers.length = 0;
       }
-
       animation.renderer.compInterface = CompExpressionInterface(animation.renderer);
       animation.renderer.globalData.projectInterface.registerComposition(animation.renderer);
       animation.renderer.globalData.pushExpression = pushExpression;
       animation.renderer.globalData.popExpression = popExpression;
       animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty;
     }
-
     return ob;
   }();
 
@@ -17407,13 +14743,11 @@
       this._mask = mask;
       this._data = data;
     }
-
     Object.defineProperty(MaskInterface.prototype, 'maskPath', {
       get: function get() {
         if (this._mask.prop.k) {
           this._mask.prop.getValue();
         }
-
         return this._mask.prop;
       }
     });
@@ -17422,38 +14756,28 @@
         if (this._mask.op.k) {
           this._mask.op.getValue();
         }
-
         return this._mask.op.v * 100;
       }
     });
-
     var MaskManager = function MaskManager(maskManager) {
       var _masksInterfaces = createSizedArray(maskManager.viewData.length);
-
       var i;
       var len = maskManager.viewData.length;
-
       for (i = 0; i < len; i += 1) {
         _masksInterfaces[i] = new MaskInterface(maskManager.viewData[i], maskManager.masksProperties[i]);
       }
-
       var maskFunction = function maskFunction(name) {
         i = 0;
-
         while (i < len) {
           if (maskManager.masksProperties[i].nm === name) {
             return _masksInterfaces[i];
           }
-
           i += 1;
         }
-
         return null;
       };
-
       return maskFunction;
     };
-
     return MaskManager;
   }();
 
@@ -17468,7 +14792,6 @@
       v: [0, 0, 0],
       mult: 1
     };
-
     function completeProperty(expressionValue, property, type) {
       Object.defineProperty(expressionValue, 'velocity', {
         get: function get() {
@@ -17476,14 +14799,11 @@
         }
       });
       expressionValue.numKeys = property.keyframes ? property.keyframes.length : 0;
-
       expressionValue.key = function (pos) {
         if (!expressionValue.numKeys) {
           return 0;
         }
-
         var value = '';
-
         if ('s' in property.keyframes[pos - 1]) {
           value = property.keyframes[pos - 1].s;
         } else if ('e' in property.keyframes[pos - 2]) {
@@ -17491,54 +14811,43 @@
         } else {
           value = property.keyframes[pos - 2].s;
         }
-
         var valueProp = type === 'unidimensional' ? new Number(value) : Object.assign({}, value); // eslint-disable-line no-new-wrappers
-
         valueProp.time = property.keyframes[pos - 1].t / property.elem.comp.globalData.frameRate;
         valueProp.value = type === 'unidimensional' ? value[0] : value;
         return valueProp;
       };
-
       expressionValue.valueAtTime = property.getValueAtTime;
       expressionValue.speedAtTime = property.getSpeedAtTime;
       expressionValue.velocityAtTime = property.getVelocityAtTime;
       expressionValue.propertyGroup = property.propertyGroup;
     }
-
     function UnidimensionalPropertyInterface(property) {
       if (!property || !('pv' in property)) {
         property = defaultUnidimensionalValue;
       }
-
       var mult = 1 / property.mult;
       var val = property.pv * mult;
       var expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
-
       expressionValue.value = val;
       completeProperty(expressionValue, property, 'unidimensional');
       return function () {
         if (property.k) {
           property.getValue();
         }
-
         val = property.v * mult;
-
         if (expressionValue.value !== val) {
           expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
-
           expressionValue.value = val;
+          expressionValue[0] = val;
           completeProperty(expressionValue, property, 'unidimensional');
         }
-
         return expressionValue;
       };
     }
-
     function MultidimensionalPropertyInterface(property) {
       if (!property || !('pv' in property)) {
         property = defaultMultidimensionalValue;
       }
-
       var mult = 1 / property.mult;
       var len = property.data && property.data.l || property.pv.length;
       var expressionValue = createTypedArray('float32', len);
@@ -17549,30 +14858,25 @@
         if (property.k) {
           property.getValue();
         }
-
         for (var i = 0; i < len; i += 1) {
           arrValue[i] = property.v[i] * mult;
           expressionValue[i] = arrValue[i];
         }
-
         return expressionValue;
       };
-    } // TODO: try to avoid using this getter
+    }
 
-
+    // TODO: try to avoid using this getter
     function defaultGetter() {
       return defaultUnidimensionalValue;
     }
-
     return function (property) {
       if (!property) {
         return defaultGetter;
       }
-
       if (property.propType === 'unidimensional') {
         return UnidimensionalPropertyInterface(property);
       }
-
       return MultidimensionalPropertyInterface(property);
     };
   }();
@@ -17586,52 +14890,41 @@
           case 'ADBE Scale':
           case 6:
             return _thisFunction.scale;
-
           case 'rotation':
           case 'Rotation':
           case 'ADBE Rotation':
           case 'ADBE Rotate Z':
           case 10:
             return _thisFunction.rotation;
-
           case 'ADBE Rotate X':
             return _thisFunction.xRotation;
-
           case 'ADBE Rotate Y':
             return _thisFunction.yRotation;
-
           case 'position':
           case 'Position':
           case 'ADBE Position':
           case 2:
             return _thisFunction.position;
-
           case 'ADBE Position_0':
             return _thisFunction.xPosition;
-
           case 'ADBE Position_1':
             return _thisFunction.yPosition;
-
           case 'ADBE Position_2':
             return _thisFunction.zPosition;
-
           case 'anchorPoint':
           case 'AnchorPoint':
           case 'Anchor Point':
           case 'ADBE AnchorPoint':
           case 1:
             return _thisFunction.anchorPoint;
-
           case 'opacity':
           case 'Opacity':
           case 11:
             return _thisFunction.opacity;
-
           default:
             return null;
         }
       }
-
       Object.defineProperty(_thisFunction, 'rotation', {
         get: ExpressionPropertyInterface(transform.r || transform.rz)
       });
@@ -17647,32 +14940,24 @@
       Object.defineProperty(_thisFunction, 'scale', {
         get: ExpressionPropertyInterface(transform.s)
       });
-
       var _px;
-
       var _py;
-
       var _pz;
-
       var _transformFactory;
-
       if (transform.p) {
         _transformFactory = ExpressionPropertyInterface(transform.p);
       } else {
         _px = ExpressionPropertyInterface(transform.px);
         _py = ExpressionPropertyInterface(transform.py);
-
         if (transform.pz) {
           _pz = ExpressionPropertyInterface(transform.pz);
         }
       }
-
       Object.defineProperty(_thisFunction, 'position', {
         get: function get() {
           if (transform.p) {
             return _transformFactory();
           }
-
           return [_px(), _py(), _pz ? _pz() : 0];
         }
       });
@@ -17707,19 +14992,15 @@
   var LayerExpressionInterface = function () {
     function getMatrix(time) {
       var toWorldMat = new Matrix();
-
       if (time !== undefined) {
         var propMatrix = this._elem.finalTransform.mProp.getValueAtTime(time);
-
         propMatrix.clone(toWorldMat);
       } else {
         var transformMat = this._elem.finalTransform.mProp;
         transformMat.applyToMatrix(toWorldMat);
       }
-
       return toWorldMat;
     }
-
     function toWorldVec(arr, time) {
       var toWorldMat = this.getMatrix(time);
       toWorldMat.props[12] = 0;
@@ -17727,12 +15008,10 @@
       toWorldMat.props[14] = 0;
       return this.applyPoint(toWorldMat, arr);
     }
-
     function toWorld(arr, time) {
       var toWorldMat = this.getMatrix(time);
       return this.applyPoint(toWorldMat, arr);
     }
-
     function fromWorldVec(arr, time) {
       var toWorldMat = this.getMatrix(time);
       toWorldMat.props[12] = 0;
@@ -17740,101 +15019,78 @@
       toWorldMat.props[14] = 0;
       return this.invertPoint(toWorldMat, arr);
     }
-
     function fromWorld(arr, time) {
       var toWorldMat = this.getMatrix(time);
       return this.invertPoint(toWorldMat, arr);
     }
-
     function applyPoint(matrix, arr) {
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
         }
       }
-
       return matrix.applyToPointArray(arr[0], arr[1], arr[2] || 0);
     }
-
     function invertPoint(matrix, arr) {
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
         }
       }
-
       return matrix.inversePoint(arr);
     }
-
     function fromComp(arr) {
       var toWorldMat = new Matrix();
       toWorldMat.reset();
-
       this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
-
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
         }
-
         return toWorldMat.inversePoint(arr);
       }
-
       return toWorldMat.inversePoint(arr);
     }
-
     function sampleImage() {
       return [1, 1, 1, 1];
     }
-
     return function (elem) {
       var transformInterface;
-
       function _registerMaskInterface(maskManager) {
         _thisLayerFunction.mask = new MaskManagerInterface(maskManager, elem);
       }
-
       function _registerEffectsInterface(effects) {
         _thisLayerFunction.effect = effects;
       }
-
       function _thisLayerFunction(name) {
         switch (name) {
           case 'ADBE Root Vectors Group':
           case 'Contents':
           case 2:
             return _thisLayerFunction.shapeInterface;
-
           case 1:
           case 6:
           case 'Transform':
           case 'transform':
           case 'ADBE Transform Group':
             return transformInterface;
-
           case 4:
           case 'ADBE Effect Parade':
           case 'effects':
           case 'Effects':
             return _thisLayerFunction.effect;
-
           case 'ADBE Text Properties':
             return _thisLayerFunction.textInterface;
-
           default:
             return null;
         }
       }
-
       _thisLayerFunction.getMatrix = getMatrix;
       _thisLayerFunction.invertPoint = invertPoint;
       _thisLayerFunction.applyPoint = applyPoint;
@@ -17895,11 +15151,9 @@
     return function (interfaceFunction, parentPropertyGroup) {
       return function (val) {
         val = val === undefined ? 1 : val;
-
         if (val <= 0) {
           return interfaceFunction;
         }
-
         return parentPropertyGroup(val - 1);
       };
     };
@@ -17910,17 +15164,13 @@
       var interfaceFunction = {
         _name: propertyName
       };
-
       function _propertyGroup(val) {
         val = val === undefined ? 1 : val;
-
         if (val <= 0) {
           return interfaceFunction;
         }
-
         return propertyGroup(val - 1);
       }
-
       return _propertyGroup;
     };
   }();
@@ -17929,35 +15179,27 @@
     var ob = {
       createEffectsInterface: createEffectsInterface
     };
-
     function createEffectsInterface(elem, propertyGroup) {
       if (elem.effectsManager) {
         var effectElements = [];
         var effectsData = elem.data.ef;
         var i;
         var len = elem.effectsManager.effectElements.length;
-
         for (i = 0; i < len; i += 1) {
           effectElements.push(createGroupInterface(effectsData[i], elem.effectsManager.effectElements[i], propertyGroup, elem));
         }
-
         var effects = elem.data.ef || [];
-
         var groupInterface = function groupInterface(name) {
           i = 0;
           len = effects.length;
-
           while (i < len) {
             if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
               return effectElements[i];
             }
-
             i += 1;
           }
-
           return null;
         };
-
         Object.defineProperty(groupInterface, 'numProperties', {
           get: function get() {
             return effects.length;
@@ -17965,37 +15207,28 @@
         });
         return groupInterface;
       }
-
       return null;
     }
-
     function createGroupInterface(data, elements, propertyGroup, elem) {
       function groupInterface(name) {
         var effects = data.ef;
         var i = 0;
         var len = effects.length;
-
         while (i < len) {
           if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
             if (effects[i].ty === 5) {
               return effectElements[i];
             }
-
             return effectElements[i]();
           }
-
           i += 1;
         }
-
         throw new Error();
       }
-
       var _propertyGroup = propertyGroupFactory(groupInterface, propertyGroup);
-
       var effectElements = [];
       var i;
       var len = data.ef.length;
-
       for (i = 0; i < len; i += 1) {
         if (data.ef[i].ty === 5) {
           effectElements.push(createGroupInterface(data.ef[i], elements.effectElements[i], elements.effectElements[i].propertyGroup, elem));
@@ -18003,7 +15236,6 @@
           effectElements.push(createValueInterface(elements.effectElements[i], data.ef[i].ty, elem, _propertyGroup));
         }
       }
-
       if (data.mn === 'ADBE Color Control') {
         Object.defineProperty(groupInterface, 'color', {
           get: function get() {
@@ -18011,7 +15243,6 @@
           }
         });
       }
-
       Object.defineProperties(groupInterface, {
         numProperties: {
           get: function get() {
@@ -18029,42 +15260,32 @@
       groupInterface.active = groupInterface.enabled;
       return groupInterface;
     }
-
     function createValueInterface(element, type, elem, propertyGroup) {
       var expressionProperty = ExpressionPropertyInterface(element.p);
-
       function interfaceFunction() {
         if (type === 10) {
           return elem.comp.compInterface(element.p.v);
         }
-
         return expressionProperty();
       }
-
       if (element.p.setGroupProperty) {
         element.p.setGroupProperty(PropertyInterface('', propertyGroup));
       }
-
       return interfaceFunction;
     }
-
     return ob;
   }();
 
   var ShapePathInterface = function () {
     return function pathInterfaceFactory(shape, view, propertyGroup) {
       var prop = view.sh;
-
       function interfaceFunction(val) {
         if (val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2) {
           return interfaceFunction.path;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       prop.setGroupProperty(PropertyInterface('Path', _propertyGroup));
       Object.defineProperties(interfaceFunction, {
         path: {
@@ -18072,7 +15293,6 @@
             if (prop.k) {
               prop.getValue();
             }
-
             return prop;
           }
         },
@@ -18081,7 +15301,6 @@
             if (prop.k) {
               prop.getValue();
             }
-
             return prop;
           }
         },
@@ -18110,7 +15329,6 @@
       var arr = [];
       var i;
       var len = shapes ? shapes.length : 0;
-
       for (i = 0; i < len; i += 1) {
         if (shapes[i].ty === 'gr') {
           arr.push(groupInterfaceFactory(shapes[i], view[i], propertyGroup));
@@ -18120,7 +15338,8 @@
           arr.push(strokeInterfaceFactory(shapes[i], view[i], propertyGroup));
         } else if (shapes[i].ty === 'tm') {
           arr.push(trimInterfaceFactory(shapes[i], view[i], propertyGroup));
-        } else if (shapes[i].ty === 'tr') {// arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
+        } else if (shapes[i].ty === 'tr') {
+          // arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
         } else if (shapes[i].ty === 'el') {
           arr.push(ellipseInterfaceFactory(shapes[i], view[i], propertyGroup));
         } else if (shapes[i].ty === 'sr') {
@@ -18139,32 +15358,24 @@
           arr.push(defaultInterfaceFactory(shapes[i], view[i], propertyGroup));
         }
       }
-
       return arr;
     }
-
     function contentsInterfaceFactory(shape, view, propertyGroup) {
       var interfaces;
-
       var interfaceFunction = function _interfaceFunction(value) {
         var i = 0;
         var len = interfaces.length;
-
         while (i < len) {
           if (interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value) {
             return interfaces[i];
           }
-
           i += 1;
         }
-
         if (typeof value === 'number') {
           return interfaces[value - 1];
         }
-
         return null;
       };
-
       interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
       interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup);
       interfaceFunction.numProperties = interfaces.length;
@@ -18174,7 +15385,6 @@
       interfaceFunction._name = shape.nm;
       return interfaceFunction;
     }
-
     function groupInterfaceFactory(shape, view, propertyGroup) {
       var interfaceFunction = function _interfaceFunction(value) {
         switch (value) {
@@ -18185,12 +15395,10 @@
           // Not necessary for now. Keeping them here in case a new case appears
           // case 'ADBE Vector Transform Group':
           // case 3:
-
           default:
             return interfaceFunction.transform;
         }
       };
-
       interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
       var content = contentsInterfaceFactory(shape, view, interfaceFunction.propertyGroup);
       var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
@@ -18200,28 +15408,24 @@
         get: function get() {
           return shape.nm;
         }
-      }); // interfaceFunction.content = interfaceFunction;
-
+      });
+      // interfaceFunction.content = interfaceFunction;
       interfaceFunction.numProperties = shape.np;
       interfaceFunction.propertyIndex = shape.ix;
       interfaceFunction.nm = shape.nm;
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function fillInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(val) {
         if (val === 'Color' || val === 'color') {
           return interfaceFunction.color;
         }
-
         if (val === 'Opacity' || val === 'opacity') {
           return interfaceFunction.opacity;
         }
-
         return null;
       }
-
       Object.defineProperties(interfaceFunction, {
         color: {
           get: ExpressionPropertyInterface(view.c)
@@ -18240,24 +15444,19 @@
       view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
       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)
@@ -18285,51 +15484,39 @@
       view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
       return interfaceFunction;
     }
-
     function defaultInterfaceFactory() {
       function interfaceFunction() {
         return null;
       }
-
       return interfaceFunction;
     }
-
     function strokeInterfaceFactory(shape, view, propertyGroup) {
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup);
-
       function addPropertyToDashOb(i) {
         Object.defineProperty(dashOb, shape.d[i].nm, {
           get: ExpressionPropertyInterface(view.d.dataProps[i].p)
         });
       }
-
       var i;
       var len = shape.d ? shape.d.length : 0;
       var dashOb = {};
-
       for (i = 0; i < len; i += 1) {
         addPropertyToDashOb(i);
         view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup);
       }
-
       function interfaceFunction(val) {
         if (val === 'Color' || val === 'color') {
           return interfaceFunction.color;
         }
-
         if (val === 'Opacity' || val === 'opacity') {
           return interfaceFunction.opacity;
         }
-
         if (val === 'Stroke Width' || val === 'stroke width') {
           return interfaceFunction.strokeWidth;
         }
-
         return null;
       }
-
       Object.defineProperties(interfaceFunction, {
         color: {
           get: ExpressionPropertyInterface(view.c)
@@ -18357,26 +15544,20 @@
       view.w.setGroupProperty(PropertyInterface('Stroke Width', _propertyGroup));
       return interfaceFunction;
     }
-
     function trimInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(val) {
         if (val === shape.e.ix || val === 'End' || val === 'end') {
           return interfaceFunction.end;
         }
-
         if (val === shape.s.ix) {
           return interfaceFunction.start;
         }
-
         if (val === shape.o.ix) {
           return interfaceFunction.offset;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       interfaceFunction.propertyIndex = shape.ix;
       view.s.setGroupProperty(PropertyInterface('Start', _propertyGroup));
       view.e.setGroupProperty(PropertyInterface('End', _propertyGroup));
@@ -18400,53 +15581,41 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function transformInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.a.ix === value || value === 'Anchor Point') {
           return interfaceFunction.anchorPoint;
         }
-
         if (shape.o.ix === value || value === 'Opacity') {
           return interfaceFunction.opacity;
         }
-
         if (shape.p.ix === value || value === 'Position') {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value || value === 'Rotation' || value === 'ADBE Vector Rotation') {
           return interfaceFunction.rotation;
         }
-
         if (shape.s.ix === value || value === 'Scale') {
           return interfaceFunction.scale;
         }
-
         if (shape.sk && shape.sk.ix === value || value === 'Skew') {
           return interfaceFunction.skew;
         }
-
         if (shape.sa && shape.sa.ix === value || value === 'Skew Axis') {
           return interfaceFunction.skewAxis;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
       view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
       view.transform.mProps.a.setGroupProperty(PropertyInterface('Anchor Point', _propertyGroup));
       view.transform.mProps.s.setGroupProperty(PropertyInterface('Scale', _propertyGroup));
       view.transform.mProps.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
-
       if (view.transform.mProps.sk) {
         view.transform.mProps.sk.setGroupProperty(PropertyInterface('Skew', _propertyGroup));
         view.transform.mProps.sa.setGroupProperty(PropertyInterface('Skew Angle', _propertyGroup));
       }
-
       view.transform.op.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
       Object.defineProperties(interfaceFunction, {
         opacity: {
@@ -18479,22 +15648,17 @@
       interfaceFunction.propertyGroup = propertyGroup;
       return interfaceFunction;
     }
-
     function ellipseInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.s.ix === value) {
           return interfaceFunction.size;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       interfaceFunction.propertyIndex = shape.ix;
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
@@ -18513,42 +15677,32 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function starInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value) {
           return interfaceFunction.rotation;
         }
-
         if (shape.pt.ix === value) {
           return interfaceFunction.points;
         }
-
         if (shape.or.ix === value || value === 'ADBE Vector Star Outer Radius') {
           return interfaceFunction.outerRadius;
         }
-
         if (shape.os.ix === value) {
           return interfaceFunction.outerRoundness;
         }
-
         if (shape.ir && (shape.ir.ix === value || value === 'ADBE Vector Star Inner Radius')) {
           return interfaceFunction.innerRadius;
         }
-
         if (shape.is && shape.is.ix === value) {
           return interfaceFunction.innerRoundness;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       interfaceFunction.propertyIndex = shape.ix;
       prop.or.setGroupProperty(PropertyInterface('Outer Radius', _propertyGroup));
@@ -18556,12 +15710,10 @@
       prop.pt.setGroupProperty(PropertyInterface('Points', _propertyGroup));
       prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
       prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
-
       if (shape.ir) {
         prop.ir.setGroupProperty(PropertyInterface('Inner Radius', _propertyGroup));
         prop.is.setGroupProperty(PropertyInterface('Inner Roundness', _propertyGroup));
       }
-
       Object.defineProperties(interfaceFunction, {
         position: {
           get: ExpressionPropertyInterface(prop.p)
@@ -18591,26 +15743,20 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function rectInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value) {
           return interfaceFunction.roundness;
         }
-
         if (shape.s.ix === value || value === 'Size' || value === 'ADBE Vector Rect Size') {
           return interfaceFunction.size;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       interfaceFunction.propertyIndex = shape.ix;
       prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
@@ -18633,18 +15779,14 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function roundedInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.r.ix === value || value === 'Round Corners 1') {
           return interfaceFunction.radius;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view;
       interfaceFunction.propertyIndex = shape.ix;
       prop.rd.setGroupProperty(PropertyInterface('Radius', _propertyGroup));
@@ -18659,22 +15801,17 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function repeaterInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.c.ix === value || value === 'Copies') {
           return interfaceFunction.copies;
         }
-
         if (shape.o.ix === value || value === 'Offset') {
           return interfaceFunction.offset;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view;
       interfaceFunction.propertyIndex = shape.ix;
       prop.c.setGroupProperty(PropertyInterface('Copies', _propertyGroup));
@@ -18693,39 +15830,29 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     return function (shapes, view, propertyGroup) {
       var interfaces;
-
       function _interfaceFunction(value) {
         if (typeof value === 'number') {
           value = value === undefined ? 1 : value;
-
           if (value === 0) {
             return propertyGroup;
           }
-
           return interfaces[value - 1];
         }
-
         var i = 0;
         var len = interfaces.length;
-
         while (i < len) {
           if (interfaces[i]._name === value) {
             return interfaces[i];
           }
-
           i += 1;
         }
-
         return null;
       }
-
       function parentGroupWrapper() {
         return propertyGroup;
       }
-
       _interfaceFunction.propertyGroup = propertyGroupFactory(_interfaceFunction, parentGroupWrapper);
       interfaces = iterateElements(shapes, view, _interfaceFunction.propertyGroup);
       _interfaceFunction.numProperties = interfaces.length;
@@ -18737,28 +15864,22 @@
   var TextExpressionInterface = function () {
     return function (elem) {
       var _sourceText;
-
       function _thisLayerFunction(name) {
         switch (name) {
           case 'ADBE Text Document':
             return _thisLayerFunction.sourceText;
-
           default:
             return null;
         }
       }
-
       Object.defineProperty(_thisLayerFunction, 'sourceText', {
         get: function get() {
           elem.textProperty.getValue();
           var stringValue = elem.textProperty.currentData.t;
-
           if (!_sourceText || stringValue !== _sourceText.value) {
             _sourceText = new String(stringValue); // eslint-disable-line no-new-wrappers
             // If stringValue is an empty string, eval returns undefined, so it has to be returned as a String primitive
-
             _sourceText.value = stringValue || new String(stringValue); // eslint-disable-line no-new-wrappers
-
             Object.defineProperty(_sourceText, 'style', {
               get: function get() {
                 return {
@@ -18767,7 +15888,6 @@
               }
             });
           }
-
           return _sourceText;
         }
       });
@@ -18775,73 +15895,56 @@
     };
   }();
 
-  function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
-
+  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
   var FootageInterface = function () {
     var outlineInterfaceFactory = function outlineInterfaceFactory(elem) {
       var currentPropertyName = '';
       var currentProperty = elem.getFootageData();
-
       function init() {
         currentPropertyName = '';
         currentProperty = elem.getFootageData();
         return searchProperty;
       }
-
       function searchProperty(value) {
         if (currentProperty[value]) {
           currentPropertyName = value;
           currentProperty = currentProperty[value];
-
           if (_typeof(currentProperty) === 'object') {
             return searchProperty;
           }
-
           return currentProperty;
         }
-
         var propertyNameIndex = value.indexOf(currentPropertyName);
-
         if (propertyNameIndex !== -1) {
           var index = parseInt(value.substr(propertyNameIndex + currentPropertyName.length), 10);
           currentProperty = currentProperty[index];
-
           if (_typeof(currentProperty) === 'object') {
             return searchProperty;
           }
-
           return currentProperty;
         }
-
         return '';
       }
-
       return init;
     };
-
     var dataInterfaceFactory = function dataInterfaceFactory(elem) {
       function interfaceFunction(value) {
         if (value === 'Outline') {
           return interfaceFunction.outlineInterface();
         }
-
         return null;
       }
-
       interfaceFunction._name = 'Outline';
       interfaceFunction.outlineInterface = outlineInterfaceFactory(elem);
       return interfaceFunction;
     };
-
     return function (elem) {
       function _interfaceFunction(value) {
         if (value === 'Data') {
           return _interfaceFunction.dataInterface;
         }
-
         return null;
       }
-
       _interfaceFunction._name = 'Data';
       _interfaceFunction.dataInterface = dataInterfaceFactory(elem);
       return _interfaceFunction;
@@ -18856,7 +15959,6 @@
     text: TextExpressionInterface,
     footage: FootageInterface
   };
-
   function getInterface(type) {
     return interfaces[type] || null;
   }
@@ -18870,56 +15972,44 @@
         prop.effectsSequence.push(prop.initiateExpression(elem, data, prop).bind(prop));
       }
     }
-
     function getValueAtTime(frameNum) {
       frameNum *= this.elem.globalData.frameRate;
       frameNum -= this.offsetTime;
-
       if (frameNum !== this._cachingAtTime.lastFrame) {
         this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0;
         this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime);
         this._cachingAtTime.lastFrame = frameNum;
       }
-
       return this._cachingAtTime.value;
     }
-
     function getSpeedAtTime(frameNum) {
       var delta = -0.01;
       var v1 = this.getValueAtTime(frameNum);
       var v2 = this.getValueAtTime(frameNum + delta);
       var speed = 0;
-
       if (v1.length) {
         var i;
-
         for (i = 0; i < v1.length; i += 1) {
           speed += Math.pow(v2[i] - v1[i], 2);
         }
-
         speed = Math.sqrt(speed) * 100;
       } else {
         speed = 0;
       }
-
       return speed;
     }
-
     function getVelocityAtTime(frameNum) {
       if (this.vel !== undefined) {
         return this.vel;
       }
-
-      var delta = -0.001; // frameNum += this.elem.data.st;
-
+      var delta = -0.001;
+      // frameNum += this.elem.data.st;
       var v1 = this.getValueAtTime(frameNum);
       var v2 = this.getValueAtTime(frameNum + delta);
       var velocity;
-
       if (v1.length) {
         velocity = createTypedArray('float32', v1.length);
         var i;
-
         for (i = 0; i < v1.length; i += 1) {
           // removing frameRate
           // if needed, don't add it here
@@ -18929,18 +16019,14 @@
       } else {
         velocity = (v2 - v1) / delta;
       }
-
       return velocity;
     }
-
     function getStaticValueAtTime() {
       return this.pv;
     }
-
     function setGroupProperty(propertyGroup) {
       this.propertyGroup = propertyGroup;
     }
-
     return {
       searchExpressions: searchExpressions,
       getSpeedAtTime: getSpeedAtTime,
@@ -18956,24 +16042,19 @@
       if (!this.k || !this.keyframes) {
         return this.pv;
       }
-
       type = type ? type.toLowerCase() : '';
       var currentFrame = this.comp.renderedFrame;
       var keyframes = this.keyframes;
       var lastKeyFrame = keyframes[keyframes.length - 1].t;
-
       if (currentFrame <= lastKeyFrame) {
         return this.pv;
       }
-
       var cycleDuration;
       var firstKeyFrame;
-
       if (!durationFlag) {
         if (!duration || duration > keyframes.length - 1) {
           duration = keyframes.length - 1;
         }
-
         firstKeyFrame = keyframes[keyframes.length - 1 - duration].t;
         cycleDuration = lastKeyFrame - firstKeyFrame;
       } else {
@@ -18982,17 +16063,13 @@
         } else {
           cycleDuration = Math.abs(lastKeyFrame - this.elem.comp.globalData.frameRate * duration);
         }
-
         firstKeyFrame = lastKeyFrame - cycleDuration;
       }
-
       var i;
       var len;
       var ret;
-
       if (type === 'pingpong') {
         var iterations = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
-
         if (iterations % 2 !== 0) {
           return this.getValueAtTime((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
         }
@@ -19000,64 +16077,48 @@
         var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
         var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
-
         var repeats = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
-
         if (this.pv.length) {
           ret = new Array(initV.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = (endV[i] - initV[i]) * repeats + current[i];
           }
-
           return ret;
         }
-
         return (endV - initV) * repeats + current;
       } else if (type === 'continue') {
         var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0);
-
         if (this.pv.length) {
           ret = new Array(lastValue.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = lastValue[i] + (lastValue[i] - nextLastValue[i]) * ((currentFrame - lastKeyFrame) / this.comp.globalData.frameRate) / 0.0005; // eslint-disable-line
           }
-
           return ret;
         }
-
         return lastValue + (lastValue - nextLastValue) * ((currentFrame - lastKeyFrame) / 0.001);
       }
-
       return this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
     }
-
     function loopIn(type, duration, durationFlag) {
       if (!this.k) {
         return this.pv;
       }
-
       type = type ? type.toLowerCase() : '';
       var currentFrame = this.comp.renderedFrame;
       var keyframes = this.keyframes;
       var firstKeyFrame = keyframes[0].t;
-
       if (currentFrame >= firstKeyFrame) {
         return this.pv;
       }
-
       var cycleDuration;
       var lastKeyFrame;
-
       if (!durationFlag) {
         if (!duration || duration > keyframes.length - 1) {
           duration = keyframes.length - 1;
         }
-
         lastKeyFrame = keyframes[duration].t;
         cycleDuration = lastKeyFrame - firstKeyFrame;
       } else {
@@ -19066,17 +16127,13 @@
         } else {
           cycleDuration = Math.abs(this.elem.comp.globalData.frameRate * duration);
         }
-
         lastKeyFrame = firstKeyFrame + cycleDuration;
       }
-
       var i;
       var len;
       var ret;
-
       if (type === 'pingpong') {
         var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration);
-
         if (iterations % 2 === 0) {
           return this.getValueAtTime(((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
         }
@@ -19085,52 +16142,39 @@
         var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var current = this.getValueAtTime((cycleDuration - (firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0);
         var repeats = Math.floor((firstKeyFrame - currentFrame) / cycleDuration) + 1;
-
         if (this.pv.length) {
           ret = new Array(initV.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = current[i] - (endV[i] - initV[i]) * repeats;
           }
-
           return ret;
         }
-
         return current - (endV - initV) * repeats;
       } else if (type === 'continue') {
         var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
         var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0);
-
         if (this.pv.length) {
           ret = new Array(firstValue.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = firstValue[i] + (firstValue[i] - nextFirstValue[i]) * (firstKeyFrame - currentFrame) / 0.001;
           }
-
           return ret;
         }
-
         return firstValue + (firstValue - nextFirstValue) * (firstKeyFrame - currentFrame) / 0.001;
       }
-
       return this.getValueAtTime((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
     }
-
     function smooth(width, samples) {
       if (!this.k) {
         return this.pv;
       }
-
       width = (width || 0.4) * 0.5;
       samples = Math.floor(samples || 5);
-
       if (samples <= 1) {
         return this.pv;
       }
-
       var currentTime = this.comp.renderedFrame / this.comp.globalData.frameRate;
       var initFrame = currentTime - width;
       var endFrame = currentTime + width;
@@ -19138,18 +16182,14 @@
       var i = 0;
       var j = 0;
       var value;
-
       if (this.pv.length) {
         value = createTypedArray('float32', this.pv.length);
       } else {
         value = 0;
       }
-
       var sampleValue;
-
       while (i < samples) {
         sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency);
-
         if (this.pv.length) {
           for (j = 0; j < this.pv.length; j += 1) {
             value[j] += sampleValue[j];
@@ -19157,10 +16197,8 @@
         } else {
           value += sampleValue;
         }
-
         i += 1;
       }
-
       if (this.pv.length) {
         for (j = 0; j < this.pv.length; j += 1) {
           value[j] /= samples;
@@ -19168,37 +16206,30 @@
       } else {
         value /= samples;
       }
-
       return value;
     }
-
     function getTransformValueAtTime(time) {
       if (!this._transformCachingAtTime) {
         this._transformCachingAtTime = {
           v: new Matrix()
         };
-      } /// /
-
-
+      }
+      /// /
       var matrix = this._transformCachingAtTime.v;
       matrix.cloneFromProps(this.pre.props);
-
       if (this.appliedTransformations < 1) {
         var anchor = this.a.getValueAtTime(time);
         matrix.translate(-anchor[0] * this.a.mult, -anchor[1] * this.a.mult, anchor[2] * this.a.mult);
       }
-
       if (this.appliedTransformations < 2) {
         var scale = this.s.getValueAtTime(time);
         matrix.scale(scale[0] * this.s.mult, scale[1] * this.s.mult, scale[2] * this.s.mult);
       }
-
       if (this.sk && this.appliedTransformations < 3) {
         var skew = this.sk.getValueAtTime(time);
         var skewAxis = this.sa.getValueAtTime(time);
         matrix.skewFromAxis(-skew * this.sk.mult, skewAxis * this.sa.mult);
       }
-
       if (this.r && this.appliedTransformations < 4) {
         var rotation = this.r.getValueAtTime(time);
         matrix.rotate(-rotation * this.r.mult);
@@ -19209,11 +16240,9 @@
         var orientation = this.or.getValueAtTime(time);
         matrix.rotateZ(-rotationZ * this.rz.mult).rotateY(rotationY * this.ry.mult).rotateX(rotationX * this.rx.mult).rotateZ(-orientation[2] * this.or.mult).rotateY(orientation[1] * this.or.mult).rotateX(orientation[0] * this.or.mult);
       }
-
       if (this.data.p && this.data.p.s) {
         var positionX = this.px.getValueAtTime(time);
         var positionY = this.py.getValueAtTime(time);
-
         if (this.data.p.z) {
           var positionZ = this.pz.getValueAtTime(time);
           matrix.translate(positionX * this.px.mult, positionY * this.py.mult, -positionZ * this.pz.mult);
@@ -19224,42 +16253,34 @@
         var position = this.p.getValueAtTime(time);
         matrix.translate(position[0] * this.p.mult, position[1] * this.p.mult, -position[2] * this.p.mult);
       }
-
-      return matrix; /// /
+      return matrix;
+      /// /
     }
-
     function getTransformStaticValueAtTime() {
       return this.v.clone(new Matrix());
     }
-
     var getTransformProperty = TransformPropertyFactory.getTransformProperty;
-
     TransformPropertyFactory.getTransformProperty = function (elem, data, container) {
       var prop = getTransformProperty(elem, data, container);
-
       if (prop.dynamicProperties.length) {
         prop.getValueAtTime = getTransformValueAtTime.bind(prop);
       } else {
         prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop);
       }
-
       prop.setGroupProperty = expressionHelpers.setGroupProperty;
       return prop;
     };
-
     var propertyGetProp = PropertyFactory.getProp;
-
     PropertyFactory.getProp = function (elem, data, type, mult, container) {
-      var prop = propertyGetProp(elem, data, type, mult, container); // prop.getVelocityAtTime = getVelocityAtTime;
+      var prop = propertyGetProp(elem, data, type, mult, container);
+      // prop.getVelocityAtTime = getVelocityAtTime;
       // prop.loopOut = loopOut;
       // prop.loopIn = loopIn;
-
       if (prop.kf) {
         prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop);
       } else {
         prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop);
       }
-
       prop.setGroupProperty = expressionHelpers.setGroupProperty;
       prop.loopOut = loopOut;
       prop.loopIn = loopIn;
@@ -19269,25 +16290,20 @@
       prop.numKeys = data.a === 1 ? data.k.length : 0;
       prop.propertyIndex = data.ix;
       var value = 0;
-
       if (type !== 0) {
         value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length);
       }
-
       prop._cachingAtTime = {
         lastFrame: initialDefaultFrame,
         lastIndex: 0,
         value: value
       };
       expressionHelpers.searchExpressions(elem, data, prop);
-
       if (prop.k) {
         container.addDynamicProperty(prop);
       }
-
       return prop;
     };
-
     function getShapeValueAtTime(frameNum) {
       // For now this caching object is created only when needed instead of creating it when the shape is initialized.
       if (!this._cachingAtTime) {
@@ -19297,42 +16313,32 @@
           lastTime: initialDefaultFrame
         };
       }
-
       frameNum *= this.elem.globalData.frameRate;
       frameNum -= this.offsetTime;
-
       if (frameNum !== this._cachingAtTime.lastTime) {
         this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0;
         this._cachingAtTime.lastTime = frameNum;
         this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime);
       }
-
       return this._cachingAtTime.shapeValue;
     }
-
     var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction();
     var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction();
-
     function ShapeExpressions() {}
-
     ShapeExpressions.prototype = {
       vertices: function vertices(prop, time) {
         if (this.k) {
           this.getValue();
         }
-
         var shapePath = this.v;
-
         if (time !== undefined) {
           shapePath = this.getValueAtTime(time, 0);
         }
-
         var i;
         var len = shapePath._length;
         var vertices = shapePath[prop];
         var points = shapePath.v;
         var arr = createSizedArray(len);
-
         for (i = 0; i < len; i += 1) {
           if (prop === 'i' || prop === 'o') {
             arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]];
@@ -19340,7 +16346,6 @@
             arr[i] = [vertices[i][0], vertices[i][1]];
           }
         }
-
         return arr;
       },
       points: function points(time) {
@@ -19357,15 +16362,12 @@
       },
       pointOnPath: function pointOnPath(perc, time) {
         var shapePath = this.v;
-
         if (time !== undefined) {
           shapePath = this.getValueAtTime(time, 0);
         }
-
         if (!this._segmentsLength) {
           this._segmentsLength = bez.getSegmentsLength(shapePath);
         }
-
         var segmentsLength = this._segmentsLength;
         var lengths = segmentsLength.lengths;
         var lengthPos = segmentsLength.totalLength * perc;
@@ -19373,7 +16375,6 @@
         var len = lengths.length;
         var accumulatedLength = 0;
         var pt;
-
         while (i < len) {
           if (accumulatedLength + lengths[i].addedLength > lengthPos) {
             var initIndex = i;
@@ -19384,14 +16385,11 @@
           } else {
             accumulatedLength += lengths[i].addedLength;
           }
-
           i += 1;
         }
-
         if (!pt) {
           pt = shapePath.c ? [shapePath.v[0][0], shapePath.v[0][1]] : [shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1]];
         }
-
         return pt;
       },
       vectorOnPath: function vectorOnPath(perc, time, vectorType) {
@@ -19403,17 +16401,14 @@
           // eslint-disable-line eqeqeq
           perc = 0.999;
         }
-
         var pt1 = this.pointOnPath(perc, time);
         var pt2 = this.pointOnPath(perc + 0.001, time);
         var xLength = pt2[0] - pt1[0];
         var yLength = pt2[1] - pt1[1];
         var magnitude = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2));
-
         if (magnitude === 0) {
           return [0, 0];
         }
-
         var unitVector = vectorType === 'tangent' ? [xLength / magnitude, yLength / magnitude] : [-yLength / magnitude, xLength / magnitude];
         return unitVector;
       },
@@ -19431,26 +16426,21 @@
     KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime;
     KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression;
     var propertyGetShapeProp = ShapePropertyFactory.getShapeProp;
-
     ShapePropertyFactory.getShapeProp = function (elem, data, type, arr, trims) {
       var prop = propertyGetShapeProp(elem, data, type, arr, trims);
       prop.propertyIndex = data.ix;
       prop.lock = false;
-
       if (type === 3) {
         expressionHelpers.searchExpressions(elem, data.pt, prop);
       } else if (type === 4) {
         expressionHelpers.searchExpressions(elem, data.ks, prop);
       }
-
       if (prop.k) {
         elem.addDynamicProperty(prop);
       }
-
       return prop;
     };
   }
-
   function initialize$1() {
     addPropertyDecorator();
   }
@@ -19462,13 +16452,10 @@
         this.addEffect(this.getExpressionValue.bind(this));
         return true;
       }
-
       return null;
     }
-
     TextProperty.prototype.getExpressionValue = function (currentValue, text) {
       var newValue = this.calculateExpression(text);
-
       if (currentValue.t !== newValue) {
         var newData = {};
         this.copyData(newData, currentValue);
@@ -19476,46 +16463,38 @@
         newData.__complete = false;
         return newData;
       }
-
       return currentValue;
     };
-
     TextProperty.prototype.searchProperty = function () {
       var isKeyframed = this.searchKeyframes();
       var hasExpressions = this.searchExpressions();
       this.kf = isKeyframed || hasExpressions;
       return this.kf;
     };
-
     TextProperty.prototype.searchExpressions = searchExpressions;
   }
-
   function initialize() {
     addDecorator();
   }
 
   function SVGComposableEffect() {}
-
   SVGComposableEffect.prototype = {
     createMergeNode: function createMergeNode(resultId, ins) {
       var feMerge = createNS('feMerge');
       feMerge.setAttribute('result', resultId);
       var feMergeNode;
       var i;
-
       for (i = 0; i < ins.length; i += 1) {
         feMergeNode = createNS('feMergeNode');
         feMergeNode.setAttribute('in', ins[i]);
         feMerge.appendChild(feMergeNode);
         feMerge.appendChild(feMergeNode);
       }
-
       return feMerge;
     }
   };
 
   var linearFilterValue = '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0';
-
   function SVGTintFilter(filter, filterManager, elem, id, source) {
     this.filterManager = filterManager;
     var feColorMatrix = createNS('feColorMatrix');
@@ -19535,9 +16514,7 @@
     var feMerge = this.createMergeNode(id, [source, id + '_tint_1', id + '_tint_2']);
     filter.appendChild(feMerge);
   }
-
   extendPrototype([SVGComposableEffect], SVGTintFilter);
-
   SVGTintFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var colorBlack = this.filterManager.effectElements[0].p.v;
@@ -19558,7 +16535,6 @@
     filter.appendChild(feColorMatrix);
     this.matrixFilter = feColorMatrix;
   }
-
   SVGFillFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var color = this.filterManager.effectElements[2].p.v;
@@ -19573,14 +16549,12 @@
     this.elem = elem;
     this.paths = [];
   }
-
   SVGStrokeEffect.prototype.initialize = function () {
     var elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
     var path;
     var groupPath;
     var i;
     var len;
-
     if (this.filterManager.effectElements[1].p.v === 1) {
       len = this.elem.maskManager.masksProperties.length;
       i = 0;
@@ -19588,12 +16562,10 @@
       i = this.filterManager.effectElements[0].p.v - 1;
       len = i + 1;
     }
-
     groupPath = createNS('g');
     groupPath.setAttribute('fill', 'none');
     groupPath.setAttribute('stroke-linecap', 'round');
     groupPath.setAttribute('stroke-dashoffset', 1);
-
     for (i; i < len; i += 1) {
       path = createNS('path');
       groupPath.appendChild(path);
@@ -19602,7 +16574,6 @@
         m: i
       });
     }
-
     if (this.filterManager.effectElements[10].p.v === 3) {
       var mask = createNS('mask');
       var id = createElementID();
@@ -19612,54 +16583,43 @@
       this.elem.globalData.defs.appendChild(mask);
       var g = createNS('g');
       g.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
-
       while (elemChildren[0]) {
         g.appendChild(elemChildren[0]);
       }
-
       this.elem.layerElement.appendChild(g);
       this.masker = mask;
       groupPath.setAttribute('stroke', '#fff');
     } else if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
       if (this.filterManager.effectElements[10].p.v === 2) {
         elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
-
         while (elemChildren.length) {
           this.elem.layerElement.removeChild(elemChildren[0]);
         }
       }
-
       this.elem.layerElement.appendChild(groupPath);
       this.elem.layerElement.removeAttribute('mask');
       groupPath.setAttribute('stroke', '#fff');
     }
-
     this.initialized = true;
     this.pathMasker = groupPath;
   };
-
   SVGStrokeEffect.prototype.renderFrame = function (forceRender) {
     if (!this.initialized) {
       this.initialize();
     }
-
     var i;
     var len = this.paths.length;
     var mask;
     var path;
-
     for (i = 0; i < len; i += 1) {
       if (this.paths[i].m !== -1) {
         mask = this.elem.maskManager.viewData[this.paths[i].m];
         path = this.paths[i].p;
-
         if (forceRender || this.filterManager._mdf || mask.prop._mdf) {
           path.setAttribute('d', mask.lastPath);
         }
-
         if (forceRender || this.filterManager.effectElements[9].p._mdf || this.filterManager.effectElements[4].p._mdf || this.filterManager.effectElements[7].p._mdf || this.filterManager.effectElements[8].p._mdf || mask.prop._mdf) {
           var dasharrayValue;
-
           if (this.filterManager.effectElements[7].p.v !== 0 || this.filterManager.effectElements[8].p.v !== 100) {
             var s = Math.min(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
             var e = Math.max(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
@@ -19669,29 +16629,23 @@
             var segment = 1 + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
             var units = Math.floor(lineLength / segment);
             var j;
-
             for (j = 0; j < units; j += 1) {
               dasharrayValue += '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01 + ' ';
             }
-
             dasharrayValue += '0 ' + l * 10 + ' 0 0';
           } else {
             dasharrayValue = '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
           }
-
           path.setAttribute('stroke-dasharray', dasharrayValue);
         }
       }
     }
-
     if (forceRender || this.filterManager.effectElements[4].p._mdf) {
       this.pathMasker.setAttribute('stroke-width', this.filterManager.effectElements[4].p.v * 2);
     }
-
     if (forceRender || this.filterManager.effectElements[6].p._mdf) {
       this.pathMasker.setAttribute('opacity', this.filterManager.effectElements[6].p.v);
     }
-
     if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
       if (forceRender || this.filterManager.effectElements[3].p._mdf) {
         var color = this.filterManager.effectElements[3].p.v;
@@ -19725,7 +16679,6 @@
     this.feFuncB = feFuncB;
     filter.appendChild(feComponentTransfer);
   }
-
   SVGTritoneFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var color1 = this.filterManager.effectElements[0].p.v;
@@ -19743,33 +16696,29 @@
   function SVGProLevelsFilter(filter, filterManager, elem, id) {
     this.filterManager = filterManager;
     var effectElements = this.filterManager.effectElements;
-    var feComponentTransfer = createNS('feComponentTransfer'); // Red
+    var feComponentTransfer = createNS('feComponentTransfer');
 
+    // Red
     if (effectElements[10].p.k || effectElements[10].p.v !== 0 || effectElements[11].p.k || effectElements[11].p.v !== 1 || effectElements[12].p.k || effectElements[12].p.v !== 1 || effectElements[13].p.k || effectElements[13].p.v !== 0 || effectElements[14].p.k || effectElements[14].p.v !== 1) {
       this.feFuncR = this.createFeFunc('feFuncR', feComponentTransfer);
-    } // Green
-
-
+    }
+    // Green
     if (effectElements[17].p.k || effectElements[17].p.v !== 0 || effectElements[18].p.k || effectElements[18].p.v !== 1 || effectElements[19].p.k || effectElements[19].p.v !== 1 || effectElements[20].p.k || effectElements[20].p.v !== 0 || effectElements[21].p.k || effectElements[21].p.v !== 1) {
       this.feFuncG = this.createFeFunc('feFuncG', feComponentTransfer);
-    } // Blue
-
-
+    }
+    // Blue
     if (effectElements[24].p.k || effectElements[24].p.v !== 0 || effectElements[25].p.k || effectElements[25].p.v !== 1 || effectElements[26].p.k || effectElements[26].p.v !== 1 || effectElements[27].p.k || effectElements[27].p.v !== 0 || effectElements[28].p.k || effectElements[28].p.v !== 1) {
       this.feFuncB = this.createFeFunc('feFuncB', feComponentTransfer);
-    } // Alpha
-
-
+    }
+    // Alpha
     if (effectElements[31].p.k || effectElements[31].p.v !== 0 || effectElements[32].p.k || effectElements[32].p.v !== 1 || effectElements[33].p.k || effectElements[33].p.v !== 1 || effectElements[34].p.k || effectElements[34].p.v !== 0 || effectElements[35].p.k || effectElements[35].p.v !== 1) {
       this.feFuncA = this.createFeFunc('feFuncA', feComponentTransfer);
-    } // RGB
-
-
+    }
+    // RGB
     if (this.feFuncR || this.feFuncG || this.feFuncB || this.feFuncA) {
       feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
       filter.appendChild(feComponentTransfer);
     }
-
     if (effectElements[3].p.k || effectElements[3].p.v !== 0 || effectElements[4].p.k || effectElements[4].p.v !== 1 || effectElements[5].p.k || effectElements[5].p.v !== 1 || effectElements[6].p.k || effectElements[6].p.v !== 0 || effectElements[7].p.k || effectElements[7].p.v !== 1) {
       feComponentTransfer = createNS('feComponentTransfer');
       feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
@@ -19780,14 +16729,12 @@
       this.feFuncBComposed = this.createFeFunc('feFuncB', feComponentTransfer);
     }
   }
-
   SVGProLevelsFilter.prototype.createFeFunc = function (type, feComponentTransfer) {
     var feFunc = createNS(type);
     feFunc.setAttribute('type', 'table');
     feComponentTransfer.appendChild(feFunc);
     return feFunc;
   };
-
   SVGProLevelsFilter.prototype.getTableValue = function (inputBlack, inputWhite, gamma, outputBlack, outputWhite) {
     var cnt = 0;
     var segments = 256;
@@ -19801,10 +16748,8 @@
     var pos = 0;
     var outputDelta = outputWhite - outputBlack;
     var inputDelta = inputWhite - inputBlack;
-
     while (cnt <= 256) {
       perc = cnt / 256;
-
       if (perc <= min) {
         colorValue = inputDelta < 0 ? outputWhite : outputBlack;
       } else if (perc >= max) {
@@ -19812,42 +16757,34 @@
       } else {
         colorValue = outputBlack + outputDelta * Math.pow((perc - inputBlack) / inputDelta, 1 / gamma);
       }
-
       table[pos] = colorValue;
       pos += 1;
       cnt += 256 / (segments - 1);
     }
-
     return table.join(' ');
   };
-
   SVGProLevelsFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var val;
       var effectElements = this.filterManager.effectElements;
-
       if (this.feFuncRComposed && (forceRender || effectElements[3].p._mdf || effectElements[4].p._mdf || effectElements[5].p._mdf || effectElements[6].p._mdf || effectElements[7].p._mdf)) {
         val = this.getTableValue(effectElements[3].p.v, effectElements[4].p.v, effectElements[5].p.v, effectElements[6].p.v, effectElements[7].p.v);
         this.feFuncRComposed.setAttribute('tableValues', val);
         this.feFuncGComposed.setAttribute('tableValues', val);
         this.feFuncBComposed.setAttribute('tableValues', val);
       }
-
       if (this.feFuncR && (forceRender || effectElements[10].p._mdf || effectElements[11].p._mdf || effectElements[12].p._mdf || effectElements[13].p._mdf || effectElements[14].p._mdf)) {
         val = this.getTableValue(effectElements[10].p.v, effectElements[11].p.v, effectElements[12].p.v, effectElements[13].p.v, effectElements[14].p.v);
         this.feFuncR.setAttribute('tableValues', val);
       }
-
       if (this.feFuncG && (forceRender || effectElements[17].p._mdf || effectElements[18].p._mdf || effectElements[19].p._mdf || effectElements[20].p._mdf || effectElements[21].p._mdf)) {
         val = this.getTableValue(effectElements[17].p.v, effectElements[18].p.v, effectElements[19].p.v, effectElements[20].p.v, effectElements[21].p.v);
         this.feFuncG.setAttribute('tableValues', val);
       }
-
       if (this.feFuncB && (forceRender || effectElements[24].p._mdf || effectElements[25].p._mdf || effectElements[26].p._mdf || effectElements[27].p._mdf || effectElements[28].p._mdf)) {
         val = this.getTableValue(effectElements[24].p.v, effectElements[25].p.v, effectElements[26].p.v, effectElements[27].p.v, effectElements[28].p.v);
         this.feFuncB.setAttribute('tableValues', val);
       }
-
       if (this.feFuncA && (forceRender || effectElements[31].p._mdf || effectElements[32].p._mdf || effectElements[33].p._mdf || effectElements[34].p._mdf || effectElements[35].p._mdf)) {
         val = this.getTableValue(effectElements[31].p.v, effectElements[32].p.v, effectElements[33].p.v, effectElements[34].p.v, effectElements[35].p.v);
         this.feFuncA.setAttribute('tableValues', val);
@@ -19889,26 +16826,22 @@
     feComposite.setAttribute('result', id + '_drop_shadow_4');
     filter.appendChild(feComposite);
     var feMerge = this.createMergeNode(id, [id + '_drop_shadow_4', source]);
-    filter.appendChild(feMerge); //
+    filter.appendChild(feMerge);
+    //
   }
-
   extendPrototype([SVGComposableEffect], SVGDropShadowEffect);
-
   SVGDropShadowEffect.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       if (forceRender || this.filterManager.effectElements[4].p._mdf) {
         this.feGaussianBlur.setAttribute('stdDeviation', this.filterManager.effectElements[4].p.v / 4);
       }
-
       if (forceRender || this.filterManager.effectElements[0].p._mdf) {
         var col = this.filterManager.effectElements[0].p.v;
         this.feFlood.setAttribute('flood-color', rgbToHex(Math.round(col[0] * 255), Math.round(col[1] * 255), Math.round(col[2] * 255)));
       }
-
       if (forceRender || this.filterManager.effectElements[1].p._mdf) {
         this.feFlood.setAttribute('flood-opacity', this.filterManager.effectElements[1].p.v / 255);
       }
-
       if (forceRender || this.filterManager.effectElements[2].p._mdf || this.filterManager.effectElements[3].p._mdf) {
         var distance = this.filterManager.effectElements[3].p.v;
         var angle = (this.filterManager.effectElements[2].p.v - 90) * degToRads;
@@ -19921,7 +16854,6 @@
   };
 
   var _svgMatteSymbols = [];
-
   function SVGMatte3Effect(filterElem, filterManager, elem) {
     this.initialized = false;
     this.filterManager = filterManager;
@@ -19932,66 +16864,50 @@
     elem.matteElement.appendChild(elem.transformedElement);
     elem.baseElement = elem.matteElement;
   }
-
   SVGMatte3Effect.prototype.findSymbol = function (mask) {
     var i = 0;
     var len = _svgMatteSymbols.length;
-
     while (i < len) {
       if (_svgMatteSymbols[i] === mask) {
         return _svgMatteSymbols[i];
       }
-
       i += 1;
     }
-
     return null;
   };
-
   SVGMatte3Effect.prototype.replaceInParent = function (mask, symbolId) {
     var parentNode = mask.layerElement.parentNode;
-
     if (!parentNode) {
       return;
     }
-
     var children = parentNode.children;
     var i = 0;
     var len = children.length;
-
     while (i < len) {
       if (children[i] === mask.layerElement) {
         break;
       }
-
       i += 1;
     }
-
     var nextChild;
-
     if (i <= len - 2) {
       nextChild = children[i + 1];
     }
-
     var useElem = createNS('use');
     useElem.setAttribute('href', '#' + symbolId);
-
     if (nextChild) {
       parentNode.insertBefore(useElem, nextChild);
     } else {
       parentNode.appendChild(useElem);
     }
   };
-
   SVGMatte3Effect.prototype.setElementAsMask = function (elem, mask) {
     if (!this.findSymbol(mask)) {
       var symbolId = createElementID();
       var masker = createNS('mask');
       masker.setAttribute('id', mask.layerId);
       masker.setAttribute('mask-type', 'alpha');
-
       _svgMatteSymbols.push(mask);
-
       var defs = elem.globalData.defs;
       defs.appendChild(masker);
       var symbol = createNS('symbol');
@@ -20005,27 +16921,21 @@
       mask.data.hd = false;
       mask.show();
     }
-
     elem.setMatte(mask.layerId);
   };
-
   SVGMatte3Effect.prototype.initialize = function () {
     var ind = this.filterManager.effectElements[0].p.v;
     var elements = this.elem.comp.elements;
     var i = 0;
     var len = elements.length;
-
     while (i < len) {
       if (elements[i] && elements[i].data.ind === ind) {
         this.setElementAsMask(this.elem, elements[i]);
       }
-
       i += 1;
     }
-
     this.initialized = true;
   };
-
   SVGMatte3Effect.prototype.renderFrame = function () {
     if (!this.initialized) {
       this.initialize();
@@ -20044,36 +16954,34 @@
     filter.appendChild(feGaussianBlur);
     this.feGaussianBlur = feGaussianBlur;
   }
-
   SVGGaussianBlurEffect.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       // Empirical value, matching AE's blur appearance.
       var kBlurrinessToSigma = 0.3;
-      var sigma = this.filterManager.effectElements[0].p.v * kBlurrinessToSigma; // Dimensions mapping:
+      var sigma = this.filterManager.effectElements[0].p.v * kBlurrinessToSigma;
+
+      // Dimensions mapping:
       //
       //   1 -> horizontal & vertical
       //   2 -> horizontal only
       //   3 -> vertical only
       //
-
       var dimensions = this.filterManager.effectElements[1].p.v;
       var sigmaX = dimensions == 3 ? 0 : sigma; // eslint-disable-line eqeqeq
-
       var sigmaY = dimensions == 2 ? 0 : sigma; // eslint-disable-line eqeqeq
 
-      this.feGaussianBlur.setAttribute('stdDeviation', sigmaX + ' ' + sigmaY); // Repeat edges mapping:
+      this.feGaussianBlur.setAttribute('stdDeviation', sigmaX + ' ' + sigmaY);
+
+      // Repeat edges mapping:
       //
       //   0 -> off -> duplicate
       //   1 -> on  -> wrap
-
       var edgeMode = this.filterManager.effectElements[2].p.v == 1 ? 'wrap' : 'duplicate'; // eslint-disable-line eqeqeq
-
       this.feGaussianBlur.setAttribute('edgeMode', edgeMode);
     }
   };
 
   function TransformEffect() {}
-
   TransformEffect.prototype.init = function (effectsManager) {
     this.effectsManager = effectsManager;
     this.type = effectTypes.TRANSFORM_EFFECT;
@@ -20082,11 +16990,9 @@
     this._mdf = false;
     this._opMdf = false;
   };
-
   TransformEffect.prototype.renderFrame = function (forceFrame) {
     this._opMdf = false;
     this._mdf = false;
-
     if (forceFrame || this.effectsManager._mdf) {
       var effectElements = this.effectsManager.effectElements;
       var anchor = effectElements[0].p.v;
@@ -20104,7 +17010,6 @@
       this.matrix.skewFromAxis(-skew * degToRads, (skewAxis + 90) * degToRads);
       this.matrix.translate(position[0], position[1], 0);
       this._mdf = true;
-
       if (this.opacity !== effectElements[8].p.v) {
         this.opacity = effectElements[8].p.v;
         this._opMdf = true;
@@ -20115,31 +17020,33 @@
   function SVGTransformEffect(_, filterManager) {
     this.init(filterManager);
   }
-
   extendPrototype([TransformEffect], SVGTransformEffect);
 
   function CVTransformEffect(effectsManager) {
     this.init(effectsManager);
   }
-
   extendPrototype([TransformEffect], CVTransformEffect);
 
+  // Registering renderers
   registerRenderer('canvas', CanvasRenderer);
   registerRenderer('html', HybridRenderer);
-  registerRenderer('svg', SVGRenderer); // Registering shape modifiers
+  registerRenderer('svg', SVGRenderer);
 
+  // Registering shape modifiers
   ShapeModifiers.registerModifier('tm', TrimModifier);
   ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
   ShapeModifiers.registerModifier('rp', RepeaterModifier);
   ShapeModifiers.registerModifier('rd', RoundCornersModifier);
   ShapeModifiers.registerModifier('zz', ZigZagModifier);
-  ShapeModifiers.registerModifier('op', OffsetPathModifier); // Registering expression plugin
+  ShapeModifiers.registerModifier('op', OffsetPathModifier);
 
+  // Registering expression plugin
   setExpressionsPlugin(Expressions);
   setExpressionInterfaces(getInterface);
   initialize$1();
-  initialize(); // Registering svg effects
+  initialize();
 
+  // Registering svg effects
   registerEffect$1(20, SVGTintFilter, true);
   registerEffect$1(21, SVGFillFilter, true);
   registerEffect$1(22, SVGStrokeEffect, false);
diff --git a/build/player/lottie.min.js b/build/player/lottie.min.js
index db3599b..0510559 100644
--- a/build/player/lottie.min.js
+++ b/build/player/lottie.min.js
@@ -1 +1 @@
-"undefined"!=typeof navigator&&function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lottie=e()}(this,(function(){"use strict";var svgNS="http://www.w3.org/2000/svg",locationHref="",_useWebWorker=!1,initialDefaultFrame=-999999,setWebWorker=function(t){_useWebWorker=!!t},getWebWorker=function(){return _useWebWorker},setLocationHref=function(t){locationHref=t},getLocationHref=function(){return locationHref};function createTag(t){return document.createElement(t)}function extendPrototype(t,e){var i,r,s=t.length;for(i=0;i<s;i+=1)for(var a in r=t[i].prototype)Object.prototype.hasOwnProperty.call(r,a)&&(e.prototype[a]=r[a])}function getDescriptor(t,e){return Object.getOwnPropertyDescriptor(t,e)}function createProxyFunction(t){function e(){}return e.prototype=t,e}var audioControllerFactory=function(){function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].pause()},resume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].resume()},setRate:function(t){var e,i=this.audios.length;for(e=0;e<i;e+=1)this.audios[e].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}}(),createTypedArray=function(){function t(t,e){var i,r=0,s=[];switch(t){case"int16":case"uint8c":i=1;break;default:i=1.1}for(r=0;r<e;r+=1)s.push(i);return s}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(e,i){return"float32"===e?new Float32Array(i):"int16"===e?new Int16Array(i):"uint8c"===e?new Uint8ClampedArray(i):t(e,i)}:t}();function createSizedArray(t){return Array.apply(null,{length:t})}function _typeof$6(t){return _typeof$6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$6(t)}var subframeEnabled=!0,expressionsPlugin=null,expressionsInterfaces=null,idPrefix$1="",isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),_shouldRoundValues=!1,bmPow=Math.pow,bmSqrt=Math.sqrt,bmFloor=Math.floor,bmMax=Math.max,bmMin=Math.min,BMMath={};function ProjectInterface$1(){return{}}!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],i=e.length;for(t=0;t<i;t+=1)BMMath[e[t]]=Math[e[t]]}(),BMMath.random=Math.random,BMMath.abs=function(t){if("object"===_typeof$6(t)&&t.length){var e,i=createSizedArray(t.length),r=t.length;for(e=0;e<r;e+=1)i[e]=Math.abs(t[e]);return i}return Math.abs(t)};var defaultCurveSegments=150,degToRads=Math.PI/180,roundCorner=.5519;function roundValues(t){_shouldRoundValues=!!t}function bmRnd(t){return _shouldRoundValues?Math.round(t):t}function styleDiv(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin="0 0",t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility="visible",t.style.webkitBackfaceVisibility="visible",t.style.transformStyle="preserve-3d",t.style.webkitTransformStyle="preserve-3d",t.style.mozTransformStyle="preserve-3d"}function BMEnterFrameEvent(t,e,i,r){this.type=t,this.currentTime=e,this.totalTime=i,this.direction=r<0?-1:1}function BMCompleteEvent(t,e){this.type=t,this.direction=e<0?-1:1}function BMCompleteLoopEvent(t,e,i,r){this.type=t,this.currentLoop=i,this.totalLoops=e,this.direction=r<0?-1:1}function BMSegmentStartEvent(t,e,i){this.type=t,this.firstFrame=e,this.totalFrames=i}function BMDestroyEvent(t,e){this.type=t,this.target=e}function BMRenderFrameErrorEvent(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function BMConfigErrorEvent(t){this.type="configError",this.nativeError=t}function BMAnimationConfigErrorEvent(t,e){this.type=t,this.nativeError=e}var createElementID=(_count=0,function(){return idPrefix$1+"__lottie_element_"+(_count+=1)}),_count;function HSVtoRGB(t,e,i){var r,s,a,n,o,h,l,p;switch(h=i*(1-e),l=i*(1-(o=6*t-(n=Math.floor(6*t)))*e),p=i*(1-(1-o)*e),n%6){case 0:r=i,s=p,a=h;break;case 1:r=l,s=i,a=h;break;case 2:r=h,s=i,a=p;break;case 3:r=h,s=l,a=i;break;case 4:r=p,s=h,a=i;break;case 5:r=i,s=h,a=l}return[r,s,a]}function RGBtoHSV(t,e,i){var r,s=Math.max(t,e,i),a=Math.min(t,e,i),n=s-a,o=0===s?0:n/s,h=s/255;switch(s){case a:r=0;break;case t:r=e-i+n*(e<i?6:0),r/=6*n;break;case e:r=i-t+2*n,r/=6*n;break;case i:r=t-e+4*n,r/=6*n}return[r,o,h]}function addSaturationToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[1]+=e,i[1]>1?i[1]=1:i[1]<=0&&(i[1]=0),HSVtoRGB(i[0],i[1],i[2])}function addBrightnessToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[2]+=e,i[2]>1?i[2]=1:i[2]<0&&(i[2]=0),HSVtoRGB(i[0],i[1],i[2])}function addHueToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[0]+=e/360,i[0]>1?i[0]-=1:i[0]<0&&(i[0]+=1),HSVtoRGB(i[0],i[1],i[2])}var rgbToHex=function(){var t,e,i=[];for(t=0;t<256;t+=1)e=t.toString(16),i[t]=1===e.length?"0"+e:e;return function(t,e,r){return t<0&&(t=0),e<0&&(e=0),r<0&&(r=0),"#"+i[t]+i[e]+i[r]}}(),setSubframeEnabled=function(t){subframeEnabled=!!t},getSubframeEnabled=function(){return subframeEnabled},setExpressionsPlugin=function(t){expressionsPlugin=t},getExpressionsPlugin=function(){return expressionsPlugin},setExpressionInterfaces=function(t){expressionsInterfaces=t},getExpressionInterfaces=function(){return expressionsInterfaces},setDefaultCurveSegments=function(t){defaultCurveSegments=t},getDefaultCurveSegments=function(){return defaultCurveSegments},setIdPrefix=function(t){idPrefix$1=t},getIdPrefix=function(){return idPrefix$1};function createNS(t){return document.createElementNS(svgNS,t)}function _typeof$5(t){return _typeof$5="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$5(t)}var dataManager=function(){var t,e,i=1,r=[],s={onmessage:function(){},postMessage:function(e){t({data:e})}},a={postMessage:function(t){s.onmessage({data:t})}};function n(){e||(e=function(e){if(window.Worker&&window.Blob&&getWebWorker()){var i=new Blob(["var _workerSelf = self; self.onmessage = ",e.toString()],{type:"text/javascript"}),r=URL.createObjectURL(i);return new Worker(r)}return t=e,s}((function(t){if(a.dataManager||(a.dataManager=function(){function t(s,a){var n,o,h,l,p,m,c=s.length;for(o=0;o<c;o+=1)if("ks"in(n=s[o])&&!n.completed){if(n.completed=!0,n.hasMask){var d=n.masksProperties;for(l=d.length,h=0;h<l;h+=1)if(d[h].pt.k.i)r(d[h].pt.k);else for(m=d[h].pt.k.length,p=0;p<m;p+=1)d[h].pt.k[p].s&&r(d[h].pt.k[p].s[0]),d[h].pt.k[p].e&&r(d[h].pt.k[p].e[0])}0===n.ty?(n.layers=e(n.refId,a),t(n.layers,a)):4===n.ty?i(n.shapes):5===n.ty&&f(n)}}function e(t,e){var i=function(t,e){for(var i=0,r=e.length;i<r;){if(e[i].id===t)return e[i];i+=1}return null}(t,e);return i?i.layers.__used?JSON.parse(JSON.stringify(i.layers)):(i.layers.__used=!0,i.layers):null}function i(t){var e,s,a;for(e=t.length-1;e>=0;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)r(t[e].ks.k);else for(a=t[e].ks.k.length,s=0;s<a;s+=1)t[e].ks.k[s].s&&r(t[e].ks.k[s].s[0]),t[e].ks.k[s].e&&r(t[e].ks.k[s].e[0]);else"gr"===t[e].ty&&i(t[e].it)}function r(t){var e,i=t.i.length;for(e=0;e<i;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function s(t,e){var i=e?e.split("."):[100,100,100];return t[0]>i[0]||!(i[0]>t[0])&&(t[1]>i[1]||!(i[1]>t[1])&&(t[2]>i[2]||!(i[2]>t[2])&&null))}var a,n=function(){var t=[4,4,14];function e(t){var e,i,r,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(r=void 0,r=(i=t[e]).t.d,i.t.d={k:[{s:r,t:0}]})}return function(i){if(s(t,i.v)&&(e(i.layers),i.assets)){var r,a=i.assets.length;for(r=0;r<a;r+=1)i.assets[r].layers&&e(i.assets[r].layers)}}}(),o=(a=[4,7,99],function(t){if(t.chars&&!s(a,t.v)){var e,r=t.chars.length;for(e=0;e<r;e+=1){var n=t.chars[e];n.data&&n.data.shapes&&(i(n.data.shapes),n.data.ip=0,n.data.op=99999,n.data.st=0,n.data.sr=1,n.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[e].t||(n.data.shapes.push({ty:"no"}),n.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}}}),h=function(){var t=[5,7,15];function e(t){var e,i,r=t.length;for(e=0;e<r;e+=1)5===t[e].ty&&(i=void 0,"number"==typeof(i=t[e].t.p).a&&(i.a={a:0,k:i.a}),"number"==typeof i.p&&(i.p={a:0,k:i.p}),"number"==typeof i.r&&(i.r={a:0,k:i.r}))}return function(i){if(s(t,i.v)&&(e(i.layers),i.assets)){var r,a=i.assets.length;for(r=0;r<a;r+=1)i.assets[r].layers&&e(i.assets[r].layers)}}}(),l=function(){var t=[4,1,9];function e(t){var i,r,s,a=t.length;for(i=0;i<a;i+=1)if("gr"===t[i].ty)e(t[i].it);else if("fl"===t[i].ty||"st"===t[i].ty)if(t[i].c.k&&t[i].c.k[0].i)for(s=t[i].c.k.length,r=0;r<s;r+=1)t[i].c.k[r].s&&(t[i].c.k[r].s[0]/=255,t[i].c.k[r].s[1]/=255,t[i].c.k[r].s[2]/=255,t[i].c.k[r].s[3]/=255),t[i].c.k[r].e&&(t[i].c.k[r].e[0]/=255,t[i].c.k[r].e[1]/=255,t[i].c.k[r].e[2]/=255,t[i].c.k[r].e[3]/=255);else t[i].c.k[0]/=255,t[i].c.k[1]/=255,t[i].c.k[2]/=255,t[i].c.k[3]/=255}function i(t){var i,r=t.length;for(i=0;i<r;i+=1)4===t[i].ty&&e(t[i].shapes)}return function(e){if(s(t,e.v)&&(i(e.layers),e.assets)){var r,a=e.assets.length;for(r=0;r<a;r+=1)e.assets[r].layers&&i(e.assets[r].layers)}}}(),p=function(){var t=[4,4,18];function e(t){var i,r,s;for(i=t.length-1;i>=0;i-=1)if("sh"===t[i].ty)if(t[i].ks.k.i)t[i].ks.k.c=t[i].closed;else for(s=t[i].ks.k.length,r=0;r<s;r+=1)t[i].ks.k[r].s&&(t[i].ks.k[r].s[0].c=t[i].closed),t[i].ks.k[r].e&&(t[i].ks.k[r].e[0].c=t[i].closed);else"gr"===t[i].ty&&e(t[i].it)}function i(t){var i,r,s,a,n,o,h=t.length;for(r=0;r<h;r+=1){if((i=t[r]).hasMask){var l=i.masksProperties;for(a=l.length,s=0;s<a;s+=1)if(l[s].pt.k.i)l[s].pt.k.c=l[s].cl;else for(o=l[s].pt.k.length,n=0;n<o;n+=1)l[s].pt.k[n].s&&(l[s].pt.k[n].s[0].c=l[s].cl),l[s].pt.k[n].e&&(l[s].pt.k[n].e[0].c=l[s].cl)}4===i.ty&&e(i.shapes)}}return function(e){if(s(t,e.v)&&(i(e.layers),e.assets)){var r,a=e.assets.length;for(r=0;r<a;r+=1)e.assets[r].layers&&i(e.assets[r].layers)}}}();function f(t){0===t.t.a.length&&t.t.p}var m={completeData:function(i){i.__complete||(l(i),n(i),o(i),h(i),p(i),t(i.layers,i.assets),function(i,r){if(i){var s=0,a=i.length;for(s=0;s<a;s+=1)1===i[s].t&&(i[s].data.layers=e(i[s].data.refId,r),t(i[s].data.layers,r))}}(i.chars,i.assets),i.__complete=!0)}};return m.checkColors=l,m.checkChars=o,m.checkPathProperties=h,m.checkShapes=p,m.completeLayers=t,m}()),a.assetLoader||(a.assetLoader=function(){function t(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")||t.response&&"object"===_typeof$5(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}return{load:function(e,i,r,s){var a,n=new XMLHttpRequest;try{n.responseType="json"}catch(t){}n.onreadystatechange=function(){if(4===n.readyState)if(200===n.status)a=t(n),r(a);else try{a=t(n),r(a)}catch(t){s&&s(t)}};try{n.open(["G","E","T"].join(""),e,!0)}catch(t){n.open(["G","E","T"].join(""),i+"/"+e,!0)}n.send()}}}()),"loadAnimation"===t.data.type)a.assetLoader.load(t.data.path,t.data.fullPath,(function(e){a.dataManager.completeData(e),a.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){a.postMessage({id:t.data.id,status:"error"})}));else if("complete"===t.data.type){var e=t.data.animation;a.dataManager.completeData(e),a.postMessage({id:t.data.id,payload:e,status:"success"})}else"loadData"===t.data.type&&a.assetLoader.load(t.data.path,t.data.fullPath,(function(e){a.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){a.postMessage({id:t.data.id,status:"error"})}))})),e.onmessage=function(t){var e=t.data,i=e.id,s=r[i];r[i]=null,"success"===e.status?s.onComplete(e.payload):s.onError&&s.onError()})}function o(t,e){var s="processId_"+(i+=1);return r[s]={onComplete:t,onError:e},s}return{loadAnimation:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:s})},loadData:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:s})},completeAnimation:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"complete",animation:t,id:s})}}}(),ImagePreloader=function(){var t=function(){var t=createTag("canvas");t.width=1,t.height=1;var e=t.getContext("2d");return e.fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1),t}();function e(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function i(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function r(t,e,i){var r="";if(t.e)r=t.p;else if(e){var s=t.p;-1!==s.indexOf("images/")&&(s=s.split("/")[1]),r=e+s}else r=i,r+=t.u?t.u:"",r+=t.p;return r}function s(t){var e=0,i=setInterval(function(){(t.getBBox().width||e>500)&&(this._imageLoaded(),clearInterval(i)),e+=1}.bind(this),50)}function a(t){var e={assetData:t},i=r(t,this.assetsPath,this.path);return dataManager.loadData(i,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}function n(){this._imageLoaded=e.bind(this),this._footageLoaded=i.bind(this),this.testImageLoaded=s.bind(this),this.createFootageData=a.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return n.prototype={loadAssets:function(t,e){var i;this.imagesLoadedCb=e;var r=t.length;for(i=0;i<r;i+=1)t[i].layers||(t[i].t&&"seq"!==t[i].t?3===t[i].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[i]))):(this.totalImages+=1,this.images.push(this._createImageData(t[i]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,i=this.images.length;e<i;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(e){var i=r(e,this.assetsPath,this.path),s=createTag("img");s.crossOrigin="anonymous",s.addEventListener("load",this._imageLoaded,!1),s.addEventListener("error",function(){a.img=t,this._imageLoaded()}.bind(this),!1),s.src=i;var a={img:s,assetData:e};return a},createImageData:function(e){var i=r(e,this.assetsPath,this.path),s=createNS("image");isSafari?this.testImageLoaded(s):s.addEventListener("load",this._imageLoaded,!1),s.addEventListener("error",function(){a.img=t,this._imageLoaded()}.bind(this),!1),s.setAttributeNS("http://www.w3.org/1999/xlink","href",i),this._elementHelper.append?this._elementHelper.append(s):this._elementHelper.appendChild(s);var a={img:s,assetData:e};return a},imageLoaded:e,footageLoaded:i,setCacheType:function(t,e){"svg"===t?(this._elementHelper=e,this._createImageData=this.createImageData.bind(this)):this._createImageData=this.createImgData.bind(this)}},n}();function BaseEvent(){}BaseEvent.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var i=this._cbs[t],r=0;r<i.length;r+=1)i[r](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var i=0,r=this._cbs[t].length;i<r;)this._cbs[t][i]===e&&(this._cbs[t].splice(i,1),i-=1,r-=1),i+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var markerParser=function(){function t(t){for(var e,i=t.split("\r\n"),r={},s=0,a=0;a<i.length;a+=1)2===(e=i[a].split(":")).length&&(r[e[0]]=e[1].trim(),s+=1);if(0===s)throw new Error;return r}return function(e){for(var i=[],r=0;r<e.length;r+=1){var s=e[r],a={time:s.tm,duration:s.dr};try{a.payload=JSON.parse(e[r].cm)}catch(i){try{a.payload=t(e[r].cm)}catch(t){a.payload={name:e[r].cm}}}i.push(a)}return i}}(),ProjectInterface=function(){function t(t){this.compositions.push(t)}return function(){function e(t){for(var e=0,i=this.compositions.length;e<i;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return e.compositions=[],e.currentFrame=0,e.registerComposition=t,e}}(),renderers={},registerRenderer=function(t,e){renderers[t]=e};function getRenderer(t){return renderers[t]}function getRegisteredRenderer(){if(renderers.canvas)return"canvas";for(var t in renderers)if(renderers[t])return t;return""}function _typeof$4(t){return _typeof$4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$4(t)}var AnimationItem=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=createElementID(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=getSubframeEnabled(),this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=ProjectInterface(),this.imagePreloader=new ImagePreloader,this.audioController=audioControllerFactory(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new BMEnterFrameEvent("drawnFrame",0,0,0),this.expressionsPlugin=getExpressionsPlugin()};extendPrototype([BaseEvent],AnimationItem),AnimationItem.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg";t.animType?e=t.animType:t.renderer&&(e=t.renderer);var i=getRenderer(e);this.renderer=new i(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||void 0===t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),dataManager.loadAnimation(t.path,this.configAnimation,this.onSetupError))},AnimationItem.prototype.onSetupError=function(){this.trigger("data_failed")},AnimationItem.prototype.setupAnimation=function(t){dataManager.completeAnimation(t,this.configAnimation)},AnimationItem.prototype.setData=function(t,e){e&&"object"!==_typeof$4(e)&&(e=JSON.parse(e));var i={wrapper:t,animationData:e},r=t.attributes;i.path=r.getNamedItem("data-animation-path")?r.getNamedItem("data-animation-path").value:r.getNamedItem("data-bm-path")?r.getNamedItem("data-bm-path").value:r.getNamedItem("bm-path")?r.getNamedItem("bm-path").value:"",i.animType=r.getNamedItem("data-anim-type")?r.getNamedItem("data-anim-type").value:r.getNamedItem("data-bm-type")?r.getNamedItem("data-bm-type").value:r.getNamedItem("bm-type")?r.getNamedItem("bm-type").value:r.getNamedItem("data-bm-renderer")?r.getNamedItem("data-bm-renderer").value:r.getNamedItem("bm-renderer")?r.getNamedItem("bm-renderer").value:getRegisteredRenderer()||"canvas";var s=r.getNamedItem("data-anim-loop")?r.getNamedItem("data-anim-loop").value:r.getNamedItem("data-bm-loop")?r.getNamedItem("data-bm-loop").value:r.getNamedItem("bm-loop")?r.getNamedItem("bm-loop").value:"";"false"===s?i.loop=!1:"true"===s?i.loop=!0:""!==s&&(i.loop=parseInt(s,10));var a=r.getNamedItem("data-anim-autoplay")?r.getNamedItem("data-anim-autoplay").value:r.getNamedItem("data-bm-autoplay")?r.getNamedItem("data-bm-autoplay").value:!r.getNamedItem("bm-autoplay")||r.getNamedItem("bm-autoplay").value;i.autoplay="false"!==a,i.name=r.getNamedItem("data-name")?r.getNamedItem("data-name").value:r.getNamedItem("data-bm-name")?r.getNamedItem("data-bm-name").value:r.getNamedItem("bm-name")?r.getNamedItem("bm-name").value:"","false"===(r.getNamedItem("data-anim-prerender")?r.getNamedItem("data-anim-prerender").value:r.getNamedItem("data-bm-prerender")?r.getNamedItem("data-bm-prerender").value:r.getNamedItem("bm-prerender")?r.getNamedItem("bm-prerender").value:"")&&(i.prerender=!1),i.path?this.setParams(i):this.trigger("destroy")},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,i,r=this.animationData.layers,s=r.length,a=t.layers,n=a.length;for(i=0;i<n;i+=1)for(e=0;e<s;){if(r[e].id===a[i].id){r[e]=a[i];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(s=t.assets.length,e=0;e<s;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,dataManager.completeAnimation(this.animationData,this.onSegmentComplete)},AnimationItem.prototype.onSegmentComplete=function(t){this.animationData=t;var e=getExpressionsPlugin();e&&e.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var i=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,dataManager.loadData(i,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},AnimationItem.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},AnimationItem.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=markerParser(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},AnimationItem.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},AnimationItem.prototype.checkLoaded=function(){if(!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()){this.isLoaded=!0;var t=getExpressionsPlugin();t&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play()}},AnimationItem.prototype.resize=function(t,e){var i="number"==typeof t?t:void 0,r="number"==typeof e?e:void 0;this.renderer.updateContainerSize(i,r)},AnimationItem.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},AnimationItem.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},AnimationItem.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},AnimationItem.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},AnimationItem.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.getMarkerData=function(t){for(var e,i=0;i<this.markers.length;i+=1)if((e=this.markers[i]).payload&&e.payload.name===t)return e;return null},AnimationItem.prototype.goToAndStop=function(t,e,i){if(!i||this.name===i){var r=Number(t);if(isNaN(r)){var s=this.getMarkerData(t);s&&this.goToAndStop(s.time,!0)}else e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier);this.pause()}},AnimationItem.prototype.goToAndPlay=function(t,e,i){if(!i||this.name===i){var r=Number(t);if(isNaN(r)){var s=this.getMarkerData(t);s&&(s.duration?this.playSegments([s.time,s.time+s.duration],!0):this.goToAndStop(s.time,!0))}else this.goToAndStop(r,e,i);this.play()}},AnimationItem.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,i=!1;e>=this.totalFrames-1&&this.frameModifier>0?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(i=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(i=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),i&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(this.frameModifier>0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var i=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?i=t:this.currentRawFrame+this.firstFrame>e&&(i=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==i&&this.goToAndStop(i,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===_typeof$4(t[0])){var i,r=t.length;for(i=0;i<r;i+=1)this.segments.push(t[i])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},AnimationItem.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},AnimationItem.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},AnimationItem.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},AnimationItem.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},AnimationItem.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},AnimationItem.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},AnimationItem.prototype.setLoop=function(t){this.loop=t},AnimationItem.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},AnimationItem.prototype.getVolume=function(){return this.audioController.getVolume()},AnimationItem.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},AnimationItem.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},AnimationItem.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},AnimationItem.prototype.getPath=function(){return this.path},AnimationItem.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var i=t.p;-1!==i.indexOf("images/")&&(i=i.split("/")[1]),e=this.assetsPath+i}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},AnimationItem.prototype.getAssetData=function(t){for(var e=0,i=this.assets.length;e<i;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},AnimationItem.prototype.hide=function(){this.renderer.hide()},AnimationItem.prototype.show=function(){this.renderer.show()},AnimationItem.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},AnimationItem.prototype.updateDocumentData=function(t,e,i){try{this.renderer.getElementByPath(t).updateDocumentData(e,i)}catch(t){}},AnimationItem.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new BMCompleteEvent(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new BMDestroyEvent(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new BMCompleteEvent(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new BMDestroyEvent(t,this))},AnimationItem.prototype.triggerRenderFrameError=function(t){var e=new BMRenderFrameErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)},AnimationItem.prototype.triggerConfigError=function(t){var e=new BMConfigErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)};var animationManager=function(){var t={},e=[],i=0,r=0,s=0,a=!0,n=!1;function o(t){for(var i=0,s=t.target;i<r;)e[i].animation===s&&(e.splice(i,1),i-=1,r-=1,s.isPaused||p()),i+=1}function h(t,i){if(!t)return null;for(var s=0;s<r;){if(e[s].elem===t&&null!==e[s].elem)return e[s].animation;s+=1}var a=new AnimationItem;return f(a,t),a.setData(t,i),a}function l(){s+=1,d()}function p(){s-=1}function f(t,i){t.addEventListener("destroy",o),t.addEventListener("_active",l),t.addEventListener("_idle",p),e.push({elem:i,animation:t}),r+=1}function m(t){var o,h=t-i;for(o=0;o<r;o+=1)e[o].animation.advanceTime(h);i=t,s&&!n?window.requestAnimationFrame(m):a=!0}function c(t){i=t,window.requestAnimationFrame(m)}function d(){!n&&s&&a&&(window.requestAnimationFrame(c),a=!1)}return t.registerAnimation=h,t.loadAnimation=function(t){var e=new AnimationItem;return f(e,null),e.setParams(t),e},t.setSpeed=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setSpeed(t,i)},t.setDirection=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setDirection(t,i)},t.play=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.play(t)},t.pause=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.pause(t)},t.stop=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.stop(t)},t.togglePause=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.togglePause(t)},t.searchAnimations=function(t,e,i){var r,s=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),a=s.length;for(r=0;r<a;r+=1)i&&s[r].setAttribute("data-bm-type",i),h(s[r],t);if(e&&0===a){i||(i="svg");var n=document.getElementsByTagName("body")[0];n.innerText="";var o=createTag("div");o.style.width="100%",o.style.height="100%",o.setAttribute("data-bm-type",i),n.appendChild(o),h(o,t)}},t.resize=function(){var t;for(t=0;t<r;t+=1)e[t].animation.resize()},t.goToAndStop=function(t,i,s){var a;for(a=0;a<r;a+=1)e[a].animation.goToAndStop(t,i,s)},t.destroy=function(t){var i;for(i=r-1;i>=0;i-=1)e[i].animation.destroy(t)},t.freeze=function(){n=!0},t.unfreeze=function(){n=!1,d()},t.setVolume=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setVolume(t,i)},t.mute=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.mute(t)},t.unmute=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.unmute(t)},t.getRegisteredAnimations=function(){var t,i=e.length,r=[];for(t=0;t<i;t+=1)r.push(e[t].animation);return r},t}(),BezierFactory=function(){var t={getBezierEasing:function(t,i,r,s,a){var n=a||("bez_"+t+"_"+i+"_"+r+"_"+s).replace(/\./g,"p");if(e[n])return e[n];var o=new l([t,i,r,s]);return e[n]=o,o}},e={};var i=.1,r="function"==typeof Float32Array;function s(t,e){return 1-3*e+3*t}function a(t,e){return 3*e-6*t}function n(t){return 3*t}function o(t,e,i){return((s(e,i)*t+a(e,i))*t+n(e))*t}function h(t,e,i){return 3*s(e,i)*t*t+2*a(e,i)*t+n(e)}function l(t){this._p=t,this._mSampleValues=r?new Float32Array(11):new Array(11),this._precomputed=!1,this.get=this.get.bind(this)}return l.prototype={get:function(t){var e=this._p[0],i=this._p[1],r=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===i&&r===s?t:0===t?0:1===t?1:o(this._getTForX(t),i,s)},_precompute:function(){var t=this._p[0],e=this._p[1],i=this._p[2],r=this._p[3];this._precomputed=!0,t===e&&i===r||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],r=0;r<11;++r)this._mSampleValues[r]=o(r*i,t,e)},_getTForX:function(t){for(var e=this._p[0],r=this._p[2],s=this._mSampleValues,a=0,n=1;10!==n&&s[n]<=t;++n)a+=i;var l=a+(t-s[--n])/(s[n+1]-s[n])*i,p=h(l,e,r);return p>=.001?function(t,e,i,r){for(var s=0;s<4;++s){var a=h(e,i,r);if(0===a)return e;e-=(o(e,i,r)-t)/a}return e}(t,l,e,r):0===p?l:function(t,e,i,r,s){var a,n,h=0;do{(a=o(n=e+(i-e)/2,r,s)-t)>0?i=n:e=n}while(Math.abs(a)>1e-7&&++h<10);return n}(t,a,a+i,e,r)}},t}(),pooling={double:function(t){return t.concat(createSizedArray(t.length))}},poolFactory=function(t,e,i){var r=0,s=t,a=createSizedArray(s);return{newElement:function(){return r?a[r-=1]:e()},release:function(t){r===s&&(a=pooling.double(a),s*=2),i&&i(t),a[r]=t,r+=1}}},bezierLengthPool=poolFactory(8,(function(){return{addedLength:0,percents:createTypedArray("float32",getDefaultCurveSegments()),lengths:createTypedArray("float32",getDefaultCurveSegments())}})),segmentsLengthPool=poolFactory(8,(function(){return{lengths:[],totalLength:0}}),(function(t){var e,i=t.lengths.length;for(e=0;e<i;e+=1)bezierLengthPool.release(t.lengths[e]);t.lengths.length=0}));function bezFunction(){var t=Math;function e(t,e,i,r,s,a){var n=t*r+e*s+i*a-s*r-a*t-i*e;return n>-.001&&n<.001}var i=function(t,e,i,r){var s,a,n,o,h,l,p=getDefaultCurveSegments(),f=0,m=[],c=[],d=bezierLengthPool.newElement();for(n=i.length,s=0;s<p;s+=1){for(h=s/(p-1),l=0,a=0;a<n;a+=1)o=bmPow(1-h,3)*t[a]+3*bmPow(1-h,2)*h*i[a]+3*(1-h)*bmPow(h,2)*r[a]+bmPow(h,3)*e[a],m[a]=o,null!==c[a]&&(l+=bmPow(m[a]-c[a],2)),c[a]=m[a];l&&(f+=l=bmSqrt(l)),d.percents[s]=h,d.lengths[s]=f}return d.addedLength=f,d};function r(t){this.segmentLength=0,this.points=new Array(t)}function s(t,e){this.partialLength=t,this.point=e}var a,n=(a={},function(t,i,n,o){var h=(t[0]+"_"+t[1]+"_"+i[0]+"_"+i[1]+"_"+n[0]+"_"+n[1]+"_"+o[0]+"_"+o[1]).replace(/\./g,"p");if(!a[h]){var l,p,f,m,c,d,u,y=getDefaultCurveSegments(),g=0,v=null;2===t.length&&(t[0]!==i[0]||t[1]!==i[1])&&e(t[0],t[1],i[0],i[1],t[0]+n[0],t[1]+n[1])&&e(t[0],t[1],i[0],i[1],i[0]+o[0],i[1]+o[1])&&(y=2);var b=new r(y);for(f=n.length,l=0;l<y;l+=1){for(u=createSizedArray(f),c=l/(y-1),d=0,p=0;p<f;p+=1)m=bmPow(1-c,3)*t[p]+3*bmPow(1-c,2)*c*(t[p]+n[p])+3*(1-c)*bmPow(c,2)*(i[p]+o[p])+bmPow(c,3)*i[p],u[p]=m,null!==v&&(d+=bmPow(u[p]-v[p],2));g+=d=bmSqrt(d),b.points[l]=new s(d,u),v=u}b.segmentLength=g,a[h]=b}return a[h]});function o(t,e){var i=e.percents,r=e.lengths,s=i.length,a=bmFloor((s-1)*t),n=t*e.addedLength,o=0;if(a===s-1||0===a||n===r[a])return i[a];for(var h=r[a]>n?-1:1,l=!0;l;)if(r[a]<=n&&r[a+1]>n?(o=(n-r[a])/(r[a+1]-r[a]),l=!1):a+=h,a<0||a>=s-1){if(a===s-1)return i[a];l=!1}return i[a]+(i[a+1]-i[a])*o}var h=createTypedArray("float32",8);return{getSegmentsLength:function(t){var e,r=segmentsLengthPool.newElement(),s=t.c,a=t.v,n=t.o,o=t.i,h=t._length,l=r.lengths,p=0;for(e=0;e<h-1;e+=1)l[e]=i(a[e],a[e+1],n[e],o[e+1]),p+=l[e].addedLength;return s&&h&&(l[e]=i(a[e],a[0],n[e],o[0]),p+=l[e].addedLength),r.totalLength=p,r},getNewSegment:function(e,i,r,s,a,n,l){a<0?a=0:a>1&&(a=1);var p,f=o(a,l),m=o(n=n>1?1:n,l),c=e.length,d=1-f,u=1-m,y=d*d*d,g=f*d*d*3,v=f*f*d*3,b=f*f*f,x=d*d*u,P=f*d*u+d*f*u+d*d*m,E=f*f*u+d*f*m+f*d*m,S=f*f*m,C=d*u*u,_=f*u*u+d*m*u+d*u*m,A=f*m*u+d*m*m+f*u*m,T=f*m*m,M=u*u*u,k=m*u*u+u*m*u+u*u*m,D=m*m*u+u*m*m+m*u*m,F=m*m*m;for(p=0;p<c;p+=1)h[4*p]=t.round(1e3*(y*e[p]+g*r[p]+v*s[p]+b*i[p]))/1e3,h[4*p+1]=t.round(1e3*(x*e[p]+P*r[p]+E*s[p]+S*i[p]))/1e3,h[4*p+2]=t.round(1e3*(C*e[p]+_*r[p]+A*s[p]+T*i[p]))/1e3,h[4*p+3]=t.round(1e3*(M*e[p]+k*r[p]+D*s[p]+F*i[p]))/1e3;return h},getPointInSegment:function(e,i,r,s,a,n){var h=o(a,n),l=1-h;return[t.round(1e3*(l*l*l*e[0]+(h*l*l+l*h*l+l*l*h)*r[0]+(h*h*l+l*h*h+h*l*h)*s[0]+h*h*h*i[0]))/1e3,t.round(1e3*(l*l*l*e[1]+(h*l*l+l*h*l+l*l*h)*r[1]+(h*h*l+l*h*h+h*l*h)*s[1]+h*h*h*i[1]))/1e3]},buildBezierData:n,pointOnLine2D:e,pointOnLine3D:function(i,r,s,a,n,o,h,l,p){if(0===s&&0===o&&0===p)return e(i,r,a,n,h,l);var f,m=t.sqrt(t.pow(a-i,2)+t.pow(n-r,2)+t.pow(o-s,2)),c=t.sqrt(t.pow(h-i,2)+t.pow(l-r,2)+t.pow(p-s,2)),d=t.sqrt(t.pow(h-a,2)+t.pow(l-n,2)+t.pow(p-o,2));return(f=m>c?m>d?m-c-d:d-c-m:d>c?d-c-m:c-m-d)>-1e-4&&f<1e-4}}}var bez=bezFunction(),initFrame=initialDefaultFrame,mathAbs=Math.abs;function interpolateValue(t,e){var i,r=this.offsetTime;"multidimensional"===this.propType&&(i=createTypedArray("float32",this.pv.length));for(var s,a,n,o,h,l,p,f,m,c=e.lastIndex,d=c,u=this.keyframes.length-1,y=!0;y;){if(s=this.keyframes[d],a=this.keyframes[d+1],d===u-1&&t>=a.t-r){s.h&&(s=a),c=0;break}if(a.t-r>t){c=d;break}d<u-1?d+=1:(c=0,y=!1)}n=this.keyframesMetadata[d]||{};var g,v=a.t-r,b=s.t-r;if(s.to){n.bezierData||(n.bezierData=bez.buildBezierData(s.s,a.s||s.e,s.to,s.ti));var x=n.bezierData;if(t>=v||t<b){var P=t>=v?x.points.length-1:0;for(h=x.points[P].point.length,o=0;o<h;o+=1)i[o]=x.points[P].point[o]}else{n.__fnct?m=n.__fnct:(m=BezierFactory.getBezierEasing(s.o.x,s.o.y,s.i.x,s.i.y,s.n).get,n.__fnct=m),l=m((t-b)/(v-b));var E,S=x.segmentLength*l,C=e.lastFrame<t&&e._lastKeyframeIndex===d?e._lastAddedLength:0;for(f=e.lastFrame<t&&e._lastKeyframeIndex===d?e._lastPoint:0,y=!0,p=x.points.length;y;){if(C+=x.points[f].partialLength,0===S||0===l||f===x.points.length-1){for(h=x.points[f].point.length,o=0;o<h;o+=1)i[o]=x.points[f].point[o];break}if(S>=C&&S<C+x.points[f+1].partialLength){for(E=(S-C)/x.points[f+1].partialLength,h=x.points[f].point.length,o=0;o<h;o+=1)i[o]=x.points[f].point[o]+(x.points[f+1].point[o]-x.points[f].point[o])*E;break}f<p-1?f+=1:y=!1}e._lastPoint=f,e._lastAddedLength=C-x.points[f].partialLength,e._lastKeyframeIndex=d}}else{var _,A,T,M,k;if(u=s.s.length,g=a.s||s.e,this.sh&&1!==s.h)if(t>=v)i[0]=g[0],i[1]=g[1],i[2]=g[2];else if(t<=b)i[0]=s.s[0],i[1]=s.s[1],i[2]=s.s[2];else{quaternionToEuler(i,slerp(createQuaternion(s.s),createQuaternion(g),(t-b)/(v-b)))}else for(d=0;d<u;d+=1)1!==s.h&&(t>=v?l=1:t<b?l=0:(s.o.x.constructor===Array?(n.__fnct||(n.__fnct=[]),n.__fnct[d]?m=n.__fnct[d]:(_=void 0===s.o.x[d]?s.o.x[0]:s.o.x[d],A=void 0===s.o.y[d]?s.o.y[0]:s.o.y[d],T=void 0===s.i.x[d]?s.i.x[0]:s.i.x[d],M=void 0===s.i.y[d]?s.i.y[0]:s.i.y[d],m=BezierFactory.getBezierEasing(_,A,T,M).get,n.__fnct[d]=m)):n.__fnct?m=n.__fnct:(_=s.o.x,A=s.o.y,T=s.i.x,M=s.i.y,m=BezierFactory.getBezierEasing(_,A,T,M).get,s.keyframeMetadata=m),l=m((t-b)/(v-b)))),g=a.s||s.e,k=1===s.h?s.s[d]:s.s[d]+(g[d]-s.s[d])*l,"multidimensional"===this.propType?i[d]=k:i=k}return e.lastIndex=c,i}function slerp(t,e,i){var r,s,a,n,o,h=[],l=t[0],p=t[1],f=t[2],m=t[3],c=e[0],d=e[1],u=e[2],y=e[3];return(s=l*c+p*d+f*u+m*y)<0&&(s=-s,c=-c,d=-d,u=-u,y=-y),1-s>1e-6?(r=Math.acos(s),a=Math.sin(r),n=Math.sin((1-i)*r)/a,o=Math.sin(i*r)/a):(n=1-i,o=i),h[0]=n*l+o*c,h[1]=n*p+o*d,h[2]=n*f+o*u,h[3]=n*m+o*y,h}function quaternionToEuler(t,e){var i=e[0],r=e[1],s=e[2],a=e[3],n=Math.atan2(2*r*a-2*i*s,1-2*r*r-2*s*s),o=Math.asin(2*i*r+2*s*a),h=Math.atan2(2*i*a-2*r*s,1-2*i*i-2*s*s);t[0]=n/degToRads,t[1]=o/degToRads,t[2]=h/degToRads}function createQuaternion(t){var e=t[0]*degToRads,i=t[1]*degToRads,r=t[2]*degToRads,s=Math.cos(e/2),a=Math.cos(i/2),n=Math.cos(r/2),o=Math.sin(e/2),h=Math.sin(i/2),l=Math.sin(r/2);return[o*h*n+s*a*l,o*a*n+s*h*l,s*h*n-o*a*l,s*a*n-o*h*l]}function getValueAtCurrentTime(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==initFrame&&(this._caching.lastFrame>=i&&t>=i||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var r=this.interpolateValue(t,this._caching);this.pv=r}return this._caching.lastFrame=t,this.pv}function setVValue(t){var e;if("unidimensional"===this.propType)e=t*this.mult,mathAbs(this.v-e)>1e-5&&(this.v=e,this._mdf=!0);else for(var i=0,r=this.v.length;i<r;)e=t[i]*this.mult,mathAbs(this.v[i]-e)>1e-5&&(this.v[i]=e,this._mdf=!0),i+=1}function processEffectsSequence(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t;this.lock=!0,this._mdf=this._isFirstFrame;var e=this.effectsSequence.length,i=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)i=this.effectsSequence[t](i);this.setVValue(i),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function addEffect(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function ValueProperty(t,e,i,r){this.propType="unidimensional",this.mult=i||1,this.data=e,this.v=i?e.k*i:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function MultiDimensionalProperty(t,e,i,r){var s;this.propType="multidimensional",this.mult=i||1,this.data=e,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var a=e.k.length;for(this.v=createTypedArray("float32",a),this.pv=createTypedArray("float32",a),this.vel=createTypedArray("float32",a),s=0;s<a;s+=1)this.v[s]=e.k[s]*this.mult,this.pv[s]=e.k[s];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function KeyframedValueProperty(t,e,i,r){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:initFrame,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.v=initFrame,this.pv=initFrame,this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.addEffect=addEffect}function KeyframedMultidimensionalProperty(t,e,i,r){var s;this.propType="multidimensional";var a,n,o,h,l=e.k.length;for(s=0;s<l-1;s+=1)e.k[s].to&&e.k[s].s&&e.k[s+1]&&e.k[s+1].s&&(a=e.k[s].s,n=e.k[s+1].s,o=e.k[s].to,h=e.k[s].ti,(2===a.length&&(a[0]!==n[0]||a[1]!==n[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],a[0]+o[0],a[1]+o[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],n[0]+h[0],n[1]+h[1])||3===a.length&&(a[0]!==n[0]||a[1]!==n[1]||a[2]!==n[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],a[0]+o[0],a[1]+o[1],a[2]+o[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],n[0]+h[0],n[1]+h[1],n[2]+h[2]))&&(e.k[s].to=null,e.k[s].ti=null),a[0]===n[0]&&a[1]===n[1]&&0===o[0]&&0===o[1]&&0===h[0]&&0===h[1]&&(2===a.length||a[2]===n[2]&&0===o[2]&&0===h[2])&&(e.k[s].to=null,e.k[s].ti=null));this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.frameId=-1;var p=e.k[0].s.length;for(this.v=createTypedArray("float32",p),this.pv=createTypedArray("float32",p),s=0;s<p;s+=1)this.v[s]=initFrame,this.pv[s]=initFrame;this._caching={lastFrame:initFrame,lastIndex:0,value:createTypedArray("float32",p)},this.addEffect=addEffect}var PropertyFactory={getProp:function(t,e,i,r,s){var a;if(e.sid&&(e=t.globalData.slotManager.getProp(e)),e.k.length)if("number"==typeof e.k[0])a=new MultiDimensionalProperty(t,e,r,s);else switch(i){case 0:a=new KeyframedValueProperty(t,e,r,s);break;case 1:a=new KeyframedMultidimensionalProperty(t,e,r,s)}else a=new ValueProperty(t,e,r,s);return a.effectsSequence.length&&s.addDynamicProperty(a),a}};function DynamicPropertyContainer(){}DynamicPropertyContainer.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){var t;this._mdf=!1;var e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var pointPool=poolFactory(8,(function(){return createTypedArray("float32",2)}));function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var i=0;i<e;)this.v[i]=pointPool.newElement(),this.o[i]=pointPool.newElement(),this.i[i]=pointPool.newElement(),i+=1},ShapePath.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},ShapePath.prototype.doubleArrayLength=function(){this.v=this.v.concat(createSizedArray(this._maxLength)),this.i=this.i.concat(createSizedArray(this._maxLength)),this.o=this.o.concat(createSizedArray(this._maxLength)),this._maxLength*=2},ShapePath.prototype.setXYAt=function(t,e,i,r,s){var a;switch(this._length=Math.max(this._length,r+1),this._length>=this._maxLength&&this.doubleArrayLength(),i){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o;break;default:a=[]}(!a[r]||a[r]&&!s)&&(a[r]=pointPool.newElement()),a[r][0]=t,a[r][1]=e},ShapePath.prototype.setTripleAt=function(t,e,i,r,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(i,r,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t=new ShapePath;t.setPathData(this.c,this._length);var e=this.v,i=this.o,r=this.i,s=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],r[0][0],r[0][1],i[0][0],i[0][1],0,!1),s=1);var a,n=this._length-1,o=this._length;for(a=s;a<o;a+=1)t.setTripleAt(e[n][0],e[n][1],r[n][0],r[n][1],i[n][0],i[n][1],a,!1),n-=1;return t},ShapePath.prototype.length=function(){return this._length};var shapePool=(factory=poolFactory(4,(function(){return new ShapePath}),(function(t){var e,i=t._length;for(e=0;e<i;e+=1)pointPool.release(t.v[e]),pointPool.release(t.i[e]),pointPool.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1})),factory.clone=function(t){var e,i=factory.newElement(),r=void 0===t._length?t.v.length:t._length;for(i.setLength(r),i.c=t.c,e=0;e<r;e+=1)i.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return i},factory),factory;function ShapeCollection(){this._length=0,this._maxLength=4,this.shapes=createSizedArray(this._maxLength)}ShapeCollection.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(createSizedArray(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},ShapeCollection.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)shapePool.release(this.shapes[t]);this._length=0};var shapeCollectionPool=(ob={newShapeCollection:function(){return _length?pool[_length-=1]:new ShapeCollection},release:function(t){var e,i=t._length;for(e=0;e<i;e+=1)shapePool.release(t.shapes[e]);t._length=0,_length===_maxLength&&(pool=pooling.double(pool),_maxLength*=2),pool[_length]=t,_length+=1}},_length=0,_maxLength=4,pool=createSizedArray(_maxLength),ob),ob,_length,_maxLength,pool,ShapePropertyFactory=function(){var t=-999999;function e(t,e,i){var r,s,a,n,o,h,l,p,f,m=i.lastIndex,c=this.keyframes;if(t<c[0].t-this.offsetTime)r=c[0].s[0],a=!0,m=0;else if(t>=c[c.length-1].t-this.offsetTime)r=c[c.length-1].s?c[c.length-1].s[0]:c[c.length-2].e[0],a=!0;else{for(var d,u,y,g=m,v=c.length-1,b=!0;b&&(d=c[g],!((u=c[g+1]).t-this.offsetTime>t));)g<v-1?g+=1:b=!1;if(y=this.keyframesMetadata[g]||{},m=g,!(a=1===d.h)){if(t>=u.t-this.offsetTime)p=1;else if(t<d.t-this.offsetTime)p=0;else{var x;y.__fnct?x=y.__fnct:(x=BezierFactory.getBezierEasing(d.o.x,d.o.y,d.i.x,d.i.y).get,y.__fnct=x),p=x((t-(d.t-this.offsetTime))/(u.t-this.offsetTime-(d.t-this.offsetTime)))}s=u.s?u.s[0]:d.e[0]}r=d.s[0]}for(h=e._length,l=r.i[0].length,i.lastIndex=m,n=0;n<h;n+=1)for(o=0;o<l;o+=1)f=a?r.i[n][o]:r.i[n][o]+(s.i[n][o]-r.i[n][o])*p,e.i[n][o]=f,f=a?r.o[n][o]:r.o[n][o]+(s.o[n][o]-r.o[n][o])*p,e.o[n][o]=f,f=a?r.v[n][o]:r.v[n][o]+(s.v[n][o]-r.v[n][o])*p,e.v[n][o]=f}function i(){var e=this.comp.renderedFrame-this.offsetTime,i=this.keyframes[0].t-this.offsetTime,r=this.keyframes[this.keyframes.length-1].t-this.offsetTime,s=this._caching.lastFrame;return s!==t&&(s<i&&e<i||s>r&&e>r)||(this._caching.lastIndex=s<e?this._caching.lastIndex:0,this.interpolateShape(e,this.pv,this._caching)),this._caching.lastFrame=e,this.pv}function r(){this.paths=this.localShapeCollection}function s(t){(function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var i,r=t._length;for(i=0;i<r;i+=1)if(t.v[i][0]!==e.v[i][0]||t.v[i][1]!==e.v[i][1]||t.o[i][0]!==e.o[i][0]||t.o[i][1]!==e.o[i][1]||t.i[i][0]!==e.i[i][0]||t.i[i][1]!==e.i[i][1])return!1;return!0})(this.v,t)||(this.v=shapePool.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function a(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t,e;this.lock=!0,this._mdf=!1,t=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k;var i=this.effectsSequence.length;for(e=0;e<i;e+=1)t=this.effectsSequence[e](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function n(t,e,i){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var s=3===i?e.pt.k:e.ks.k;this.v=shapePool.clone(s),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=r,this.effectsSequence=[]}function o(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function h(e,s,a){this.propType="shape",this.comp=e.comp,this.elem=e,this.container=e,this.offsetTime=e.data.st,this.keyframes=3===a?s.pt.k:s.ks.k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;var n=this.keyframes[0].s[0].i.length;this.v=shapePool.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,n),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=t,this.reset=r,this._caching={lastFrame:t,lastIndex:0},this.effectsSequence=[i.bind(this)]}n.prototype.interpolateShape=e,n.prototype.getValue=a,n.prototype.setVValue=s,n.prototype.addEffect=o,h.prototype.getValue=a,h.prototype.interpolateShape=e,h.prototype.setVValue=s,h.prototype.addEffect=o;var l=function(){var t=roundCorner;function e(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}return e.prototype={reset:r,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var e=this.p.v[0],i=this.p.v[1],r=this.s.v[0]/2,s=this.s.v[1]/2,a=3!==this.d,n=this.v;n.v[0][0]=e,n.v[0][1]=i-s,n.v[1][0]=a?e+r:e-r,n.v[1][1]=i,n.v[2][0]=e,n.v[2][1]=i+s,n.v[3][0]=a?e-r:e+r,n.v[3][1]=i,n.i[0][0]=a?e-r*t:e+r*t,n.i[0][1]=i-s,n.i[1][0]=a?e+r:e-r,n.i[1][1]=i-s*t,n.i[2][0]=a?e+r*t:e-r*t,n.i[2][1]=i+s,n.i[3][0]=a?e-r:e+r,n.i[3][1]=i+s*t,n.o[0][0]=a?e+r*t:e-r*t,n.o[0][1]=i-s,n.o[1][0]=a?e+r:e-r,n.o[1][1]=i+s*t,n.o[2][0]=a?e-r*t:e+r*t,n.o[2][1]=i+s,n.o[3][0]=a?e-r:e+r,n.o[3][1]=i-s*t}},extendPrototype([DynamicPropertyContainer],e),e}(),p=function(){function t(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=PropertyFactory.getProp(t,e.ir,0,0,this),this.is=PropertyFactory.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=PropertyFactory.getProp(t,e.pt,0,0,this),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,degToRads,this),this.or=PropertyFactory.getProp(t,e.or,0,0,this),this.os=PropertyFactory.getProp(t,e.os,0,.01,this),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}return t.prototype={reset:r,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,i,r,s=2*Math.floor(this.pt.v),a=2*Math.PI/s,n=!0,o=this.or.v,h=this.ir.v,l=this.os.v,p=this.is.v,f=2*Math.PI*o/(2*s),m=2*Math.PI*h/(2*s),c=-Math.PI/2;c+=this.r.v;var d=3===this.data.d?-1:1;for(this.v._length=0,t=0;t<s;t+=1){i=n?l:p,r=n?f:m;var u=(e=n?o:h)*Math.cos(c),y=e*Math.sin(c),g=0===u&&0===y?0:y/Math.sqrt(u*u+y*y),v=0===u&&0===y?0:-u/Math.sqrt(u*u+y*y);u+=+this.p.v[0],y+=+this.p.v[1],this.v.setTripleAt(u,y,u-g*r*i*d,y-v*r*i*d,u+g*r*i*d,y+v*r*i*d,t,!0),n=!n,c+=a*d}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),i=2*Math.PI/e,r=this.or.v,s=this.os.v,a=2*Math.PI*r/(4*e),n=.5*-Math.PI,o=3===this.data.d?-1:1;for(n+=this.r.v,this.v._length=0,t=0;t<e;t+=1){var h=r*Math.cos(n),l=r*Math.sin(n),p=0===h&&0===l?0:l/Math.sqrt(h*h+l*l),f=0===h&&0===l?0:-h/Math.sqrt(h*h+l*l);h+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(h,l,h-p*a*s*o,l-f*a*s*o,h+p*a*s*o,l+f*a*s*o,t,!0),n+=i*o}this.paths.length=0,this.paths[0]=this.v}},extendPrototype([DynamicPropertyContainer],t),t}(),f=function(){function t(t,e){this.v=shapePool.newElement(),this.v.c=!0,this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}return t.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,r=this.s.v[1]/2,s=bmMin(i,r,this.r.v),a=s*(1-roundCorner);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+s,t+i,e-r+a,0,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-a,t+i,e+r-s,1,!0),0!==s?(this.v.setTripleAt(t+i-s,e+r,t+i-s,e+r,t+i-a,e+r,2,!0),this.v.setTripleAt(t-i+s,e+r,t-i+a,e+r,t-i+s,e+r,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-s,t-i,e+r-a,4,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+a,t-i,e-r+s,5,!0),this.v.setTripleAt(t-i+s,e-r,t-i+s,e-r,t-i+a,e-r,6,!0),this.v.setTripleAt(t+i-s,e-r,t+i-a,e-r,t+i-s,e-r,7,!0)):(this.v.setTripleAt(t-i,e+r,t-i+a,e+r,t-i,e+r,2),this.v.setTripleAt(t-i,e-r,t-i,e-r+a,t-i,e-r,3))):(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+a,t+i,e-r+s,0,!0),0!==s?(this.v.setTripleAt(t+i-s,e-r,t+i-s,e-r,t+i-a,e-r,1,!0),this.v.setTripleAt(t-i+s,e-r,t-i+a,e-r,t-i+s,e-r,2,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+s,t-i,e-r+a,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-a,t-i,e+r-s,4,!0),this.v.setTripleAt(t-i+s,e+r,t-i+s,e+r,t-i+a,e+r,5,!0),this.v.setTripleAt(t+i-s,e+r,t+i-a,e+r,t+i-s,e+r,6,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-s,t+i,e+r-a,7,!0)):(this.v.setTripleAt(t-i,e-r,t-i+a,e-r,t-i,e-r,1,!0),this.v.setTripleAt(t-i,e+r,t-i,e+r-a,t-i,e+r,2,!0),this.v.setTripleAt(t+i,e+r,t+i-a,e+r,t+i,e+r,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:r},extendPrototype([DynamicPropertyContainer],t),t}();var m={getShapeProp:function(t,e,i){var r;return 3===i||4===i?r=(3===i?e.pt:e.ks).k.length?new h(t,e,i):new n(t,e,i):5===i?r=new f(t,e):6===i?r=new l(t,e):7===i&&(r=new p(t,e)),r.k&&t.addDynamicProperty(r),r},getConstructorFunction:function(){return n},getKeyframedConstructorFunction:function(){return h}};return m}(),Matrix=function(){var t=Math.cos,e=Math.sin,i=Math.tan,r=Math.round;function s(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function a(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,-s,0,0,s,r,0,0,0,0,1,0,0,0,0,1)}function n(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(1,0,0,0,0,r,-s,0,0,s,r,0,0,0,0,1)}function o(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,0,s,0,0,1,0,0,-s,0,r,0,0,0,0,1)}function h(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,-s,0,0,s,r,0,0,0,0,1,0,0,0,0,1)}function l(t,e){return this._t(1,e,t,1,0,0)}function p(t,e){return this.shear(i(t),i(e))}function f(r,s){var a=t(s),n=e(s);return this._t(a,n,0,0,-n,a,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,i(r),1,0,0,0,0,1,0,0,0,0,1)._t(a,-n,0,0,n,a,0,0,0,0,1,0,0,0,0,1)}function m(t,e,i){return i||0===i||(i=1),1===t&&1===e&&1===i?this:this._t(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1)}function c(t,e,i,r,s,a,n,o,h,l,p,f,m,c,d,u){return this.props[0]=t,this.props[1]=e,this.props[2]=i,this.props[3]=r,this.props[4]=s,this.props[5]=a,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=l,this.props[10]=p,this.props[11]=f,this.props[12]=m,this.props[13]=c,this.props[14]=d,this.props[15]=u,this}function d(t,e,i){return i=i||0,0!==t||0!==e||0!==i?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,i,1):this}function u(t,e,i,r,s,a,n,o,h,l,p,f,m,c,d,u){var y=this.props;if(1===t&&0===e&&0===i&&0===r&&0===s&&1===a&&0===n&&0===o&&0===h&&0===l&&1===p&&0===f)return y[12]=y[12]*t+y[15]*m,y[13]=y[13]*a+y[15]*c,y[14]=y[14]*p+y[15]*d,y[15]*=u,this._identityCalculated=!1,this;var g=y[0],v=y[1],b=y[2],x=y[3],P=y[4],E=y[5],S=y[6],C=y[7],_=y[8],A=y[9],T=y[10],M=y[11],k=y[12],D=y[13],F=y[14],w=y[15];return y[0]=g*t+v*s+b*h+x*m,y[1]=g*e+v*a+b*l+x*c,y[2]=g*i+v*n+b*p+x*d,y[3]=g*r+v*o+b*f+x*u,y[4]=P*t+E*s+S*h+C*m,y[5]=P*e+E*a+S*l+C*c,y[6]=P*i+E*n+S*p+C*d,y[7]=P*r+E*o+S*f+C*u,y[8]=_*t+A*s+T*h+M*m,y[9]=_*e+A*a+T*l+M*c,y[10]=_*i+A*n+T*p+M*d,y[11]=_*r+A*o+T*f+M*u,y[12]=k*t+D*s+F*h+w*m,y[13]=k*e+D*a+F*l+w*c,y[14]=k*i+D*n+F*p+w*d,y[15]=k*r+D*o+F*f+w*u,this._identityCalculated=!1,this}function y(t){var e=t.props;return this.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}function g(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function v(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function b(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function x(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function P(t,e,i){return{x:t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}}function E(t,e,i){return t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12]}function S(t,e,i){return t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13]}function C(t,e,i){return t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}function _(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,i=-this.props[1]/t,r=-this.props[4]/t,s=this.props[0]/t,a=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,n=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,o=new Matrix;return o.props[0]=e,o.props[1]=i,o.props[4]=r,o.props[5]=s,o.props[12]=a,o.props[13]=n,o}function A(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function T(t){var e,i=t.length,r=[];for(e=0;e<i;e+=1)r[e]=A(t[e]);return r}function M(t,e,i){var r=createTypedArray("float32",6);if(this.isIdentity())r[0]=t[0],r[1]=t[1],r[2]=e[0],r[3]=e[1],r[4]=i[0],r[5]=i[1];else{var s=this.props[0],a=this.props[1],n=this.props[4],o=this.props[5],h=this.props[12],l=this.props[13];r[0]=t[0]*s+t[1]*n+h,r[1]=t[0]*a+t[1]*o+l,r[2]=e[0]*s+e[1]*n+h,r[3]=e[0]*a+e[1]*o+l,r[4]=i[0]*s+i[1]*n+h,r[5]=i[0]*a+i[1]*o+l}return r}function k(t,e,i){return this.isIdentity()?[t,e,i]:[t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]]}function D(t,e){if(this.isIdentity())return t+","+e;var i=this.props;return Math.round(100*(t*i[0]+e*i[4]+i[12]))/100+","+Math.round(100*(t*i[1]+e*i[5]+i[13]))/100}function F(){for(var t=0,e=this.props,i="matrix3d(";t<16;)i+=r(1e4*e[t])/1e4,i+=15===t?")":",",t+=1;return i}function w(t){return t<1e-6&&t>0||t>-1e-6&&t<0?r(1e4*t)/1e4:t}function I(){var t=this.props;return"matrix("+w(t[0])+","+w(t[1])+","+w(t[4])+","+w(t[5])+","+w(t[12])+","+w(t[13])+")"}return function(){this.reset=s,this.rotate=a,this.rotateX=n,this.rotateY=o,this.rotateZ=h,this.skew=p,this.skewFromAxis=f,this.shear=l,this.scale=m,this.setTransform=c,this.translate=d,this.transform=u,this.multiply=y,this.applyToPoint=P,this.applyToX=E,this.applyToY=S,this.applyToZ=C,this.applyToPointArray=k,this.applyToTriplePoints=M,this.applyToPointStringified=D,this.toCSS=F,this.to2dCSS=I,this.clone=b,this.cloneFromProps=x,this.equals=v,this.inversePoints=T,this.inversePoint=A,this.getInverseMatrix=_,this._t=this.transform,this.isIdentity=g,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}}();function _typeof$3(t){return _typeof$3="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$3(t)}var lottie={},standalone="__[STANDALONE]__",animationData="__[ANIMATIONDATA]__",renderer="";function setLocation(t){setLocationHref(t)}function searchAnimations(){!0===standalone?animationManager.searchAnimations(animationData,standalone,renderer):animationManager.searchAnimations()}function setSubframeRendering(t){setSubframeEnabled(t)}function setPrefix(t){setIdPrefix(t)}function loadAnimation(t){return!0===standalone&&(t.animationData=JSON.parse(animationData)),animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":setDefaultCurveSegments(200);break;default:case"medium":setDefaultCurveSegments(50);break;case"low":setDefaultCurveSegments(10)}else!isNaN(t)&&t>1&&setDefaultCurveSegments(t);getDefaultCurveSegments()>=50?roundValues(!1):roundValues(!0)}function inBrowser(){return"undefined"!=typeof navigator}function installPlugin(t,e){"expressions"===t&&setExpressionsPlugin(e)}function getFactory(t){switch(t){case"propertyFactory":return PropertyFactory;case"shapePropertyFactory":return ShapePropertyFactory;case"matrix":return Matrix;default:return null}}function checkReady(){"complete"===document.readyState&&(clearInterval(readyStateCheckInterval),searchAnimations())}function getQueryVariable(t){for(var e=queryString.split("&"),i=0;i<e.length;i+=1){var r=e[i].split("=");if(decodeURIComponent(r[0])==t)return decodeURIComponent(r[1])}return null}lottie.play=animationManager.play,lottie.pause=animationManager.pause,lottie.setLocationHref=setLocation,lottie.togglePause=animationManager.togglePause,lottie.setSpeed=animationManager.setSpeed,lottie.setDirection=animationManager.setDirection,lottie.stop=animationManager.stop,lottie.searchAnimations=searchAnimations,lottie.registerAnimation=animationManager.registerAnimation,lottie.loadAnimation=loadAnimation,lottie.setSubframeRendering=setSubframeRendering,lottie.resize=animationManager.resize,lottie.goToAndStop=animationManager.goToAndStop,lottie.destroy=animationManager.destroy,lottie.setQuality=setQuality,lottie.inBrowser=inBrowser,lottie.installPlugin=installPlugin,lottie.freeze=animationManager.freeze,lottie.unfreeze=animationManager.unfreeze,lottie.setVolume=animationManager.setVolume,lottie.mute=animationManager.mute,lottie.unmute=animationManager.unmute,lottie.getRegisteredAnimations=animationManager.getRegisteredAnimations,lottie.useWebWorker=setWebWorker,lottie.setIDPrefix=setPrefix,lottie.__getFactory=getFactory,lottie.version="5.12.2";var queryString="";if(standalone){var scripts=document.getElementsByTagName("script"),index=scripts.length-1,myScript=scripts[index]||{src:""};queryString=myScript.src?myScript.src.replace(/^[^\?]+\??/,""):"",renderer=getQueryVariable("renderer")}var readyStateCheckInterval=setInterval(checkReady,100);try{"object"===("undefined"==typeof exports?"undefined":_typeof$3(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=lottie)}catch(t){}var ShapeModifiers=function(){var t={},e={};return t.registerModifier=function(t,i){e[t]||(e[t]=i)},t.getModifier=function(t,i,r){return new e[t](i,r)},t}();function ShapeModifier(){}function TrimModifier(){}function PuckerAndBloatModifier(){}ShapeModifier.prototype.initModifierProperties=function(){},ShapeModifier.prototype.addShapeToModifier=function(){},ShapeModifier.prototype.addShape=function(t){if(!this.closed){t.sh.container.addDynamicProperty(t.sh);var e={shape:t.sh,data:t,localShapeCollection:shapeCollectionPool.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},ShapeModifier.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=initialDefaultFrame,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},ShapeModifier.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},extendPrototype([DynamicPropertyContainer],ShapeModifier),extendPrototype([ShapeModifier],TrimModifier),TrimModifier.prototype.initModifierProperties=function(t,e){this.s=PropertyFactory.getProp(t,e.s,0,.01,this),this.e=PropertyFactory.getProp(t,e.e,0,.01,this),this.o=PropertyFactory.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},TrimModifier.prototype.addShapeToModifier=function(t){t.pathsData=[]},TrimModifier.prototype.calculateShapeEdges=function(t,e,i,r,s){var a=[];e<=1?a.push({s:t,e:e}):t>=1?a.push({s:t-1,e:e-1}):(a.push({s:t,e:1}),a.push({s:0,e:e-1}));var n,o,h=[],l=a.length;for(n=0;n<l;n+=1){var p,f;if(!((o=a[n]).e*s<r||o.s*s>r+i))p=o.s*s<=r?0:(o.s*s-r)/i,f=o.e*s>=r+i?1:(o.e*s-r)/i,h.push([p,f])}return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){var e,i=t.length;for(e=0;e<i;e+=1)segmentsLengthPool.release(t[e]);return t.length=0,t},TrimModifier.prototype.processShapes=function(t){var e,i,r,s;if(this._mdf||t){var a=this.o.v%360/360;if(a<0&&(a+=1),(e=this.s.v>1?1+a:this.s.v<0?0+a:this.s.v+a)>(i=this.e.v>1?1+a:this.e.v<0?0+a:this.e.v+a)){var n=e;e=i,i=n}e=1e-4*Math.round(1e4*e),i=1e-4*Math.round(1e4*i),this.sValue=e,this.eValue=i}else e=this.sValue,i=this.eValue;var o,h,l,p,f,m=this.shapes.length,c=0;if(i===e)for(s=0;s<m;s+=1)this.shapes[s].localShapeCollection.releaseShapes(),this.shapes[s].shape._mdf=!0,this.shapes[s].shape.paths=this.shapes[s].localShapeCollection,this._mdf&&(this.shapes[s].pathsData.length=0);else if(1===i&&0===e||0===i&&1===e){if(this._mdf)for(s=0;s<m;s+=1)this.shapes[s].pathsData.length=0,this.shapes[s].shape._mdf=!0}else{var d,u,y=[];for(s=0;s<m;s+=1)if((d=this.shapes[s]).shape._mdf||this._mdf||t||2===this.m){if(h=(r=d.shape.paths)._length,f=0,!d.shape._mdf&&d.pathsData.length)f=d.totalShapeLength;else{for(l=this.releasePathsData(d.pathsData),o=0;o<h;o+=1)p=bez.getSegmentsLength(r.shapes[o]),l.push(p),f+=p.totalLength;d.totalShapeLength=f,d.pathsData=l}c+=f,d.shape._mdf=!0}else d.shape.paths=d.localShapeCollection;var g,v=e,b=i,x=0;for(s=m-1;s>=0;s-=1)if((d=this.shapes[s]).shape._mdf){for((u=d.localShapeCollection).releaseShapes(),2===this.m&&m>1?(g=this.calculateShapeEdges(e,i,d.totalShapeLength,x,c),x+=d.totalShapeLength):g=[[v,b]],h=g.length,o=0;o<h;o+=1){v=g[o][0],b=g[o][1],y.length=0,b<=1?y.push({s:d.totalShapeLength*v,e:d.totalShapeLength*b}):v>=1?y.push({s:d.totalShapeLength*(v-1),e:d.totalShapeLength*(b-1)}):(y.push({s:d.totalShapeLength*v,e:d.totalShapeLength}),y.push({s:0,e:d.totalShapeLength*(b-1)}));var P=this.addShapes(d,y[0]);if(y[0].s!==y[0].e){if(y.length>1)if(d.shape.paths.shapes[d.shape.paths._length-1].c){var E=P.pop();this.addPaths(P,u),P=this.addShapes(d,y[1],E)}else this.addPaths(P,u),P=this.addShapes(d,y[1]);this.addPaths(P,u)}}d.shape.paths=u}}},TrimModifier.prototype.addPaths=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)e.addShape(t[i])},TrimModifier.prototype.addSegment=function(t,e,i,r,s,a,n){s.setXYAt(e[0],e[1],"o",a),s.setXYAt(i[0],i[1],"i",a+1),n&&s.setXYAt(t[0],t[1],"v",a),s.setXYAt(r[0],r[1],"v",a+1)},TrimModifier.prototype.addSegmentFromArray=function(t,e,i,r){e.setXYAt(t[1],t[5],"o",i),e.setXYAt(t[2],t[6],"i",i+1),r&&e.setXYAt(t[0],t[4],"v",i),e.setXYAt(t[3],t[7],"v",i+1)},TrimModifier.prototype.addShapes=function(t,e,i){var r,s,a,n,o,h,l,p,f=t.pathsData,m=t.shape.paths.shapes,c=t.shape.paths._length,d=0,u=[],y=!0;for(i?(o=i._length,p=i._length):(i=shapePool.newElement(),o=0,p=0),u.push(i),r=0;r<c;r+=1){for(h=f[r].lengths,i.c=m[r].c,a=m[r].c?h.length:h.length+1,s=1;s<a;s+=1)if(d+(n=h[s-1]).addedLength<e.s)d+=n.addedLength,i.c=!1;else{if(d>e.e){i.c=!1;break}e.s<=d&&e.e>=d+n.addedLength?(this.addSegment(m[r].v[s-1],m[r].o[s-1],m[r].i[s],m[r].v[s],i,o,y),y=!1):(l=bez.getNewSegment(m[r].v[s-1],m[r].v[s],m[r].o[s-1],m[r].i[s],(e.s-d)/n.addedLength,(e.e-d)/n.addedLength,h[s-1]),this.addSegmentFromArray(l,i,o,y),y=!1,i.c=!1),d+=n.addedLength,o+=1}if(m[r].c&&h.length){if(n=h[s-1],d<=e.e){var g=h[s-1].addedLength;e.s<=d&&e.e>=d+g?(this.addSegment(m[r].v[s-1],m[r].o[s-1],m[r].i[0],m[r].v[0],i,o,y),y=!1):(l=bez.getNewSegment(m[r].v[s-1],m[r].v[0],m[r].o[s-1],m[r].i[0],(e.s-d)/g,(e.e-d)/g,h[s-1]),this.addSegmentFromArray(l,i,o,y),y=!1,i.c=!1)}else i.c=!1;d+=n.addedLength,o+=1}if(i._length&&(i.setXYAt(i.v[p][0],i.v[p][1],"i",p),i.setXYAt(i.v[i._length-1][0],i.v[i._length-1][1],"o",i._length-1)),d>e.e)break;r<c-1&&(i=shapePool.newElement(),y=!0,u.push(i),o=0)}return u},extendPrototype([ShapeModifier],PuckerAndBloatModifier),PuckerAndBloatModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},PuckerAndBloatModifier.prototype.processPath=function(t,e){var i=e/100,r=[0,0],s=t._length,a=0;for(a=0;a<s;a+=1)r[0]+=t.v[a][0],r[1]+=t.v[a][1];r[0]/=s,r[1]/=s;var n,o,h,l,p,f,m=shapePool.newElement();for(m.c=t.c,a=0;a<s;a+=1)n=t.v[a][0]+(r[0]-t.v[a][0])*i,o=t.v[a][1]+(r[1]-t.v[a][1])*i,h=t.o[a][0]+(r[0]-t.o[a][0])*-i,l=t.o[a][1]+(r[1]-t.o[a][1])*-i,p=t.i[a][0]+(r[0]-t.i[a][0])*-i,f=t.i[a][1]+(r[1]-t.i[a][1])*-i,m.setTripleAt(n,o,h,l,p,f,a);return m},PuckerAndBloatModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amount.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var TransformPropertyFactory=function(){var t=[0,0];function e(t,e,i){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Matrix,this.pre=new Matrix,this.appliedTransformations=0,this.initDynamicPropertyContainer(i||t),e.p&&e.p.s?(this.px=PropertyFactory.getProp(t,e.p.x,0,0,this),this.py=PropertyFactory.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=PropertyFactory.getProp(t,e.p.z,0,0,this))):this.p=PropertyFactory.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=PropertyFactory.getProp(t,e.rx,0,degToRads,this),this.ry=PropertyFactory.getProp(t,e.ry,0,degToRads,this),this.rz=PropertyFactory.getProp(t,e.rz,0,degToRads,this),e.or.k[0].ti){var r,s=e.or.k.length;for(r=0;r<s;r+=1)e.or.k[r].to=null,e.or.k[r].ti=null}this.or=PropertyFactory.getProp(t,e.or,1,degToRads,this),this.or.sh=!0}else this.r=PropertyFactory.getProp(t,e.r||{k:0},0,degToRads,this);e.sk&&(this.sk=PropertyFactory.getProp(t,e.sk,0,degToRads,this),this.sa=PropertyFactory.getProp(t,e.sa,0,degToRads,this)),this.a=PropertyFactory.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=PropertyFactory.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=PropertyFactory.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return e.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(e){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||e){var i;if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var r,s;if(i=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime)this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(r=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/i,0),s=this.p.getValueAtTime(this.p.keyframes[0].t/i,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(r=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/i,0),s=this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/i,0)):(r=this.p.pv,s=this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/i,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){r=[],s=[];var a=this.px,n=this.py;a._caching.lastFrame+a.offsetTime<=a.keyframes[0].t?(r[0]=a.getValueAtTime((a.keyframes[0].t+.01)/i,0),r[1]=n.getValueAtTime((n.keyframes[0].t+.01)/i,0),s[0]=a.getValueAtTime(a.keyframes[0].t/i,0),s[1]=n.getValueAtTime(n.keyframes[0].t/i,0)):a._caching.lastFrame+a.offsetTime>=a.keyframes[a.keyframes.length-1].t?(r[0]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/i,0),r[1]=n.getValueAtTime(n.keyframes[n.keyframes.length-1].t/i,0),s[0]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/i,0),s[1]=n.getValueAtTime((n.keyframes[n.keyframes.length-1].t-.01)/i,0)):(r=[a.pv,n.pv],s[0]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/i,a.offsetTime),s[1]=n.getValueAtTime((n._caching.lastFrame+n.offsetTime-.01)/i,n.offsetTime))}else r=s=t;this.v.rotate(-Math.atan2(r[1]-s[1],r[0]-s[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],e),e.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},e.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,i,r){return new e(t,i,r)}}}();function RepeaterModifier(){}function RoundCornersModifier(){}function floatEqual(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function floatZero(t){return Math.abs(t)<=1e-5}function lerp(t,e,i){return t*(1-i)+e*i}function lerpPoint(t,e,i){return[lerp(t[0],e[0],i),lerp(t[1],e[1],i)]}function quadRoots(t,e,i){if(0===t)return[];var r=e*e-4*t*i;if(r<0)return[];var s=-e/(2*t);if(0===r)return[s];var a=Math.sqrt(r)/(2*t);return[s-a,s+a]}function polynomialCoefficients(t,e,i,r){return[3*e-t-3*i+r,3*t-6*e+3*i,-3*t+3*e,t]}function singlePoint(t){return new PolynomialBezier(t,t,t,t,!1)}function PolynomialBezier(t,e,i,r,s){s&&pointEqual(t,e)&&(e=lerpPoint(t,r,1/3)),s&&pointEqual(i,r)&&(i=lerpPoint(t,r,2/3));var a=polynomialCoefficients(t[0],e[0],i[0],r[0]),n=polynomialCoefficients(t[1],e[1],i[1],r[1]);this.a=[a[0],n[0]],this.b=[a[1],n[1]],this.c=[a[2],n[2]],this.d=[a[3],n[3]],this.points=[t,e,i,r]}function extrema(t,e){var i=t.points[0][e],r=t.points[t.points.length-1][e];if(i>r){var s=r;r=i,i=s}for(var a=quadRoots(3*t.a[e],2*t.b[e],t.c[e]),n=0;n<a.length;n+=1)if(a[n]>0&&a[n]<1){var o=t.point(a[n])[e];o<i?i=o:o>r&&(r=o)}return{min:i,max:r}}function intersectData(t,e,i){var r=t.boundingBox();return{cx:r.cx,cy:r.cy,width:r.width,height:r.height,bez:t,t:(e+i)/2,t1:e,t2:i}}function splitData(t){var e=t.bez.split(.5);return[intersectData(e[0],t.t1,t.t),intersectData(e[1],t.t,t.t2)]}function boxIntersect(t,e){return 2*Math.abs(t.cx-e.cx)<t.width+e.width&&2*Math.abs(t.cy-e.cy)<t.height+e.height}function intersectsImpl(t,e,i,r,s,a){if(boxIntersect(t,e))if(i>=a||t.width<=r&&t.height<=r&&e.width<=r&&e.height<=r)s.push([t.t,e.t]);else{var n=splitData(t),o=splitData(e);intersectsImpl(n[0],o[0],i+1,r,s,a),intersectsImpl(n[0],o[1],i+1,r,s,a),intersectsImpl(n[1],o[0],i+1,r,s,a),intersectsImpl(n[1],o[1],i+1,r,s,a)}}function crossProduct(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function lineIntersection(t,e,i,r){var s=[t[0],t[1],1],a=[e[0],e[1],1],n=[i[0],i[1],1],o=[r[0],r[1],1],h=crossProduct(crossProduct(s,a),crossProduct(n,o));return floatZero(h[2])?null:[h[0]/h[2],h[1]/h[2]]}function polarOffset(t,e,i){return[t[0]+Math.cos(e)*i,t[1]-Math.sin(e)*i]}function pointDistance(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function pointEqual(t,e){return floatEqual(t[0],e[0])&&floatEqual(t[1],e[1])}function ZigZagModifier(){}function setPoint(t,e,i,r,s,a,n){var o=i-Math.PI/2,h=i+Math.PI/2,l=e[0]+Math.cos(i)*r*s,p=e[1]-Math.sin(i)*r*s;t.setTripleAt(l,p,l+Math.cos(o)*a,p-Math.sin(o)*a,l+Math.cos(h)*n,p-Math.sin(h)*n,t.length())}function getPerpendicularVector(t,e){var i=[e[0]-t[0],e[1]-t[1]],r=.5*-Math.PI;return[Math.cos(r)*i[0]-Math.sin(r)*i[1],Math.sin(r)*i[0]+Math.cos(r)*i[1]]}function getProjectingAngle(t,e){var i=0===e?t.length()-1:e-1,r=(e+1)%t.length(),s=getPerpendicularVector(t.v[i],t.v[r]);return Math.atan2(0,1)-Math.atan2(s[1],s[0])}function zigZagCorner(t,e,i,r,s,a,n){var o=getProjectingAngle(e,i),h=e.v[i%e._length],l=e.v[0===i?e._length-1:i-1],p=e.v[(i+1)%e._length],f=2===a?Math.sqrt(Math.pow(h[0]-l[0],2)+Math.pow(h[1]-l[1],2)):0,m=2===a?Math.sqrt(Math.pow(h[0]-p[0],2)+Math.pow(h[1]-p[1],2)):0;setPoint(t,e.v[i%e._length],o,n,r,m/(2*(s+1)),f/(2*(s+1)),a)}function zigZagSegment(t,e,i,r,s,a){for(var n=0;n<r;n+=1){var o=(n+1)/(r+1),h=2===s?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(o);setPoint(t,e.point(o),l,a,i,h/(2*(r+1)),h/(2*(r+1)),s),a=-a}return a}function linearOffset(t,e,i){var r=Math.atan2(e[0]-t[0],e[1]-t[1]);return[polarOffset(t,r,i),polarOffset(e,r,i)]}function offsetSegment(t,e){var i,r,s,a,n,o,h;i=(h=linearOffset(t.points[0],t.points[1],e))[0],r=h[1],s=(h=linearOffset(t.points[1],t.points[2],e))[0],a=h[1],n=(h=linearOffset(t.points[2],t.points[3],e))[0],o=h[1];var l=lineIntersection(i,r,s,a);null===l&&(l=r);var p=lineIntersection(n,o,s,a);return null===p&&(p=n),new PolynomialBezier(i,l,p,o)}function joinLines(t,e,i,r,s){var a=e.points[3],n=i.points[0];if(3===r)return a;if(pointEqual(a,n))return a;if(2===r){var o=-e.tangentAngle(1),h=-i.tangentAngle(0)+Math.PI,l=lineIntersection(a,polarOffset(a,o+Math.PI/2,100),n,polarOffset(n,o+Math.PI/2,100)),p=l?pointDistance(l,a):pointDistance(a,n)/2,f=polarOffset(a,o,2*p*roundCorner);return t.setXYAt(f[0],f[1],"o",t.length()-1),f=polarOffset(n,h,2*p*roundCorner),t.setTripleAt(n[0],n[1],n[0],n[1],f[0],f[1],t.length()),n}var m=lineIntersection(pointEqual(a,e.points[2])?e.points[0]:e.points[2],a,n,pointEqual(n,i.points[1])?i.points[3]:i.points[1]);return m&&pointDistance(m,a)<s?(t.setTripleAt(m[0],m[1],m[0],m[1],m[0],m[1],t.length()),m):a}function getIntersection(t,e){var i=t.intersections(e);return i.length&&floatEqual(i[0][0],1)&&i.shift(),i.length?i[0]:null}function pruneSegmentIntersection(t,e){var i=t.slice(),r=e.slice(),s=getIntersection(t[t.length-1],e[0]);return s&&(i[t.length-1]=t[t.length-1].split(s[0])[0],r[0]=e[0].split(s[1])[1]),t.length>1&&e.length>1&&(s=getIntersection(t[0],e[e.length-1]))?[[t[0].split(s[0])[0]],[e[e.length-1].split(s[1])[1]]]:[i,r]}function pruneIntersections(t){for(var e,i=1;i<t.length;i+=1)e=pruneSegmentIntersection(t[i-1],t[i]),t[i-1]=e[0],t[i]=e[1];return t.length>1&&(e=pruneSegmentIntersection(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}function offsetSegmentSplit(t,e){var i,r,s,a,n=t.inflectionPoints();if(0===n.length)return[offsetSegment(t,e)];if(1===n.length||floatEqual(n[1],1))return i=(s=t.split(n[0]))[0],r=s[1],[offsetSegment(i,e),offsetSegment(r,e)];i=(s=t.split(n[0]))[0];var o=(n[1]-n[0])/(1-n[0]);return a=(s=s[1].split(o))[0],r=s[1],[offsetSegment(i,e),offsetSegment(a,e),offsetSegment(r,e)]}function OffsetPathModifier(){}function getFontProperties(t){for(var e=t.fStyle?t.fStyle.split(" "):[],i="normal",r="normal",s=e.length,a=0;a<s;a+=1)switch(e[a].toLowerCase()){case"italic":r="italic";break;case"bold":i="700";break;case"black":i="900";break;case"medium":i="500";break;case"regular":case"normal":i="400";break;case"light":case"thin":i="200"}return{style:r,weight:t.fWeight||i}}extendPrototype([ShapeModifier],RepeaterModifier),RepeaterModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=PropertyFactory.getProp(t,e.c,0,null,this),this.o=PropertyFactory.getProp(t,e.o,0,null,this),this.tr=TransformPropertyFactory.getTransformProperty(t,e.tr,this),this.so=PropertyFactory.getProp(t,e.tr.so,0,.01,this),this.eo=PropertyFactory.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Matrix,this.rMatrix=new Matrix,this.sMatrix=new Matrix,this.tMatrix=new Matrix,this.matrix=new Matrix},RepeaterModifier.prototype.applyTransforms=function(t,e,i,r,s,a){var n=a?-1:1,o=r.s.v[0]+(1-r.s.v[0])*(1-s),h=r.s.v[1]+(1-r.s.v[1])*(1-s);t.translate(r.p.v[0]*n*s,r.p.v[1]*n*s,r.p.v[2]),e.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),e.rotate(-r.r.v*n*s),e.translate(r.a.v[0],r.a.v[1],r.a.v[2]),i.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),i.scale(a?1/o:o,a?1/h:h),i.translate(r.a.v[0],r.a.v[1],r.a.v[2])},RepeaterModifier.prototype.init=function(t,e,i,r){for(this.elem=t,this.arr=e,this.pos=i,this.elemsData=r,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[i]);i>0;)i-=1,this._elements.unshift(e[i]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},RepeaterModifier.prototype.cloneElements=function(t){var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},RepeaterModifier.prototype.changeGroupRender=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)t[i]._render=e,"gr"===t[i].ty&&this.changeGroupRender(t[i].it,e)},RepeaterModifier.prototype.processShapes=function(t){var e,i,r,s,a,n=!1;if(this._mdf||t){var o,h=Math.ceil(this.c.v);if(this._groups.length<h){for(;this._groups.length<h;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(a=0,r=0;r<=this._groups.length-1;r+=1){if(o=a<h,this._groups[r]._render=o,this.changeGroupRender(this._groups[r].it,o),!o){var p=this.elemsData[r].it,f=p[p.length-1];0!==f.transform.op.v?(f.transform.op._mdf=!0,f.transform.op.v=0):f.transform.op._mdf=!1}a+=1}this._currentCopies=h;var m=this.o.v,c=m%1,d=m>0?Math.floor(m):Math.ceil(m),u=this.pMatrix.props,y=this.rMatrix.props,g=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var v,b,x=0;if(m>0){for(;x<d;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),x+=1;c&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,c,!1),x+=c)}else if(m<0){for(;x>d;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),x-=1;c&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-c,!0),x-=c)}for(r=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(b=(i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(r/(this._currentCopies-1)),0!==x){for((0!==r&&1===s||r!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]),this.matrix.transform(u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]),v=0;v<b;v+=1)i[v]=this.matrix.props[v];this.matrix.reset()}else for(this.matrix.reset(),v=0;v<b;v+=1)i[v]=this.matrix.props[v];x+=1,a-=1,r+=s}}else for(a=this._currentCopies,r=0,s=1;a;)i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,a-=1,r+=s;return n},RepeaterModifier.prototype.addShape=function(){},extendPrototype([ShapeModifier],RoundCornersModifier),RoundCornersModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=PropertyFactory.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},RoundCornersModifier.prototype.processPath=function(t,e){var i,r=shapePool.newElement();r.c=t.c;var s,a,n,o,h,l,p,f,m,c,d,u,y=t._length,g=0;for(i=0;i<y;i+=1)s=t.v[i],n=t.o[i],a=t.i[i],s[0]===n[0]&&s[1]===n[1]&&s[0]===a[0]&&s[1]===a[1]?0!==i&&i!==y-1||t.c?(o=0===i?t.v[y-1]:t.v[i-1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=d=s[0]+(o[0]-s[0])*l,f=u=s[1]-(s[1]-o[1])*l,m=p-(p-s[0])*roundCorner,c=f-(f-s[1])*roundCorner,r.setTripleAt(p,f,m,c,d,u,g),g+=1,o=i===y-1?t.v[0]:t.v[i+1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=m=s[0]+(o[0]-s[0])*l,f=c=s[1]+(o[1]-s[1])*l,d=p-(p-s[0])*roundCorner,u=f-(f-s[1])*roundCorner,r.setTripleAt(p,f,m,c,d,u,g),g+=1):(r.setTripleAt(s[0],s[1],n[0],n[1],a[0],a[1],g),g+=1):(r.setTripleAt(t.v[i][0],t.v[i][1],t.o[i][0],t.o[i][1],t.i[i][0],t.i[i][1],g),g+=1);return r},RoundCornersModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},PolynomialBezier.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},PolynomialBezier.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},PolynomialBezier.prototype.tangentAngle=function(t){var e=this.derivative(t);return Math.atan2(e[1],e[0])},PolynomialBezier.prototype.normalAngle=function(t){var e=this.derivative(t);return Math.atan2(e[0],e[1])},PolynomialBezier.prototype.inflectionPoints=function(){var t=this.a[1]*this.b[0]-this.a[0]*this.b[1];if(floatZero(t))return[];var e=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/t,i=e*e-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/t;if(i<0)return[];var r=Math.sqrt(i);return floatZero(r)?r>0&&r<1?[e]:[]:[e-r,e+r].filter((function(t){return t>0&&t<1}))},PolynomialBezier.prototype.split=function(t){if(t<=0)return[singlePoint(this.points[0]),this];if(t>=1)return[this,singlePoint(this.points[this.points.length-1])];var e=lerpPoint(this.points[0],this.points[1],t),i=lerpPoint(this.points[1],this.points[2],t),r=lerpPoint(this.points[2],this.points[3],t),s=lerpPoint(e,i,t),a=lerpPoint(i,r,t),n=lerpPoint(s,a,t);return[new PolynomialBezier(this.points[0],e,s,n,!0),new PolynomialBezier(n,a,r,this.points[3],!0)]},PolynomialBezier.prototype.bounds=function(){return{x:extrema(this,0),y:extrema(this,1)}},PolynomialBezier.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},PolynomialBezier.prototype.intersections=function(t,e,i){void 0===e&&(e=2),void 0===i&&(i=7);var r=[];return intersectsImpl(intersectData(this,0,1),intersectData(t,0,1),0,e,r,i),r},PolynomialBezier.shapeSegment=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[e],t.o[e],t.i[i],t.v[i],!0)},PolynomialBezier.shapeSegmentInverted=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[i],t.i[i],t.o[e],t.v[e],!0)},extendPrototype([ShapeModifier],ZigZagModifier),ZigZagModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=PropertyFactory.getProp(t,e.s,0,null,this),this.frequency=PropertyFactory.getProp(t,e.r,0,null,this),this.pointsType=PropertyFactory.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},ZigZagModifier.prototype.processPath=function(t,e,i,r){var s=t._length,a=shapePool.newElement();if(a.c=t.c,t.c||(s-=1),0===s)return a;var n=-1,o=PolynomialBezier.shapeSegment(t,0);zigZagCorner(a,t,0,e,i,r,n);for(var h=0;h<s;h+=1)n=zigZagSegment(a,o,e,i,r,-n),o=h!==s-1||t.c?PolynomialBezier.shapeSegment(t,(h+1)%s):null,zigZagCorner(a,t,h+1,e,i,r,n);return a},ZigZagModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amplitude.v,l=Math.max(0,Math.round(this.frequency.v)),p=this.pointsType.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h,l,p));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},extendPrototype([ShapeModifier],OffsetPathModifier),OffsetPathModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this.miterLimit=PropertyFactory.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},OffsetPathModifier.prototype.processPath=function(t,e,i,r){var s=shapePool.newElement();s.c=t.c;var a,n,o,h=t.length();t.c||(h-=1);var l=[];for(a=0;a<h;a+=1)o=PolynomialBezier.shapeSegment(t,a),l.push(offsetSegmentSplit(o,e));if(!t.c)for(a=h-1;a>=0;a-=1)o=PolynomialBezier.shapeSegmentInverted(t,a),l.push(offsetSegmentSplit(o,e));l=pruneIntersections(l);var p=null,f=null;for(a=0;a<l.length;a+=1){var m=l[a];for(f&&(p=joinLines(s,f,m[0],i,r)),f=m[m.length-1],n=0;n<m.length;n+=1)o=m[n],p&&pointEqual(o.points[0],p)?s.setXYAt(o.points[1][0],o.points[1][1],"o",s.length()-1):s.setTripleAt(o.points[0][0],o.points[0][1],o.points[1][0],o.points[1][1],o.points[0][0],o.points[0][1],s.length()),s.setTripleAt(o.points[3][0],o.points[3][1],o.points[3][0],o.points[3][1],o.points[2][0],o.points[2][1],s.length()),p=o.points[3]}return l.length&&joinLines(s,f,l[0][0],i,r),s},OffsetPathModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amount.v,l=this.miterLimit.v,p=this.lineJoin;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h,p,l));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var FontManager=function(){var t={w:0,size:0,shapes:[],data:{shapes:[]}},e=[];e=e.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);var i=127988,r=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function s(t,e){var i=createTag("span");i.setAttribute("aria-hidden",!0),i.style.fontFamily=e;var r=createTag("span");r.innerText="giItT1WQy@!-/#",i.style.position="absolute",i.style.left="-10000px",i.style.top="-10000px",i.style.fontSize="300px",i.style.fontVariant="normal",i.style.fontStyle="normal",i.style.fontWeight="normal",i.style.letterSpacing="0",i.appendChild(r),document.body.appendChild(i);var s=r.offsetWidth;return r.style.fontFamily=function(t){var e,i=t.split(","),r=i.length,s=[];for(e=0;e<r;e+=1)"sans-serif"!==i[e]&&"monospace"!==i[e]&&s.push(i[e]);return s.join(",")}(t)+", "+e,{node:r,w:s,parent:i}}function a(t,e){var i,r=document.body&&e?"svg":"canvas",s=getFontProperties(t);if("svg"===r){var a=createNS("text");a.style.fontSize="100px",a.setAttribute("font-family",t.fFamily),a.setAttribute("font-style",s.style),a.setAttribute("font-weight",s.weight),a.textContent="1",t.fClass?(a.style.fontFamily="inherit",a.setAttribute("class",t.fClass)):a.style.fontFamily=t.fFamily,e.appendChild(a),i=a}else{var n=new OffscreenCanvas(500,500).getContext("2d");n.font=s.style+" "+s.weight+" 100px "+t.fFamily,i=n}return{measureText:function(t){return"svg"===r?(i.textContent=t,i.getComputedTextLength()):i.measureText(t).width}}}function n(t){var e=0,i=t.charCodeAt(0);if(i>=55296&&i<=56319){var r=t.charCodeAt(1);r>=56320&&r<=57343&&(e=1024*(i-55296)+r-56320+65536)}return e}function o(t){var e=n(t);return e>=127462&&e<=127487}var h=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)};h.isModifier=function(t,e){var i=t.toString(16)+e.toString(16);return-1!==r.indexOf(i)},h.isZeroWidthJoiner=function(t){return 8205===t},h.isFlagEmoji=function(t){return o(t.substr(0,2))&&o(t.substr(2,2))},h.isRegionalCode=o,h.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},h.isRegionalFlag=function(t,e){var r=n(t.substr(e,2));if(r!==i)return!1;var s=0;for(e+=2;s<5;){if((r=n(t.substr(e,2)))<917601||r>917626)return!1;s+=1,e+=2}return 917631===n(t.substr(e,2))},h.isVariationSelector=function(t){return 65039===t},h.BLACK_FLAG_CODE_POINT=i;var l={addChars:function(t){if(t){var e;this.chars||(this.chars=[]);var i,r,s=t.length,a=this.chars.length;for(e=0;e<s;e+=1){for(i=0,r=!1;i<a;)this.chars[i].style===t[e].style&&this.chars[i].fFamily===t[e].fFamily&&this.chars[i].ch===t[e].ch&&(r=!0),i+=1;r||(this.chars.push(t[e]),a+=1)}}},addFonts:function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);if(!document.body)return this.isLoaded=!0,t.list.forEach((function(t){t.helper=a(t),t.cache={}})),void(this.fonts=t.list);var i,r=t.list,n=r.length,o=n;for(i=0;i<n;i+=1){var h,l,p=!0;if(r[i].loaded=!1,r[i].monoCase=s(r[i].fFamily,"monospace"),r[i].sansCase=s(r[i].fFamily,"sans-serif"),r[i].fPath){if("p"===r[i].fOrigin||3===r[i].origin){if((h=document.querySelectorAll('style[f-forigin="p"][f-family="'+r[i].fFamily+'"], style[f-origin="3"][f-family="'+r[i].fFamily+'"]')).length>0&&(p=!1),p){var f=createTag("style");f.setAttribute("f-forigin",r[i].fOrigin),f.setAttribute("f-origin",r[i].origin),f.setAttribute("f-family",r[i].fFamily),f.type="text/css",f.innerText="@font-face {font-family: "+r[i].fFamily+"; font-style: normal; src: url('"+r[i].fPath+"');}",e.appendChild(f)}}else if("g"===r[i].fOrigin||1===r[i].origin){for(h=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),l=0;l<h.length;l+=1)-1!==h[l].href.indexOf(r[i].fPath)&&(p=!1);if(p){var m=createTag("link");m.setAttribute("f-forigin",r[i].fOrigin),m.setAttribute("f-origin",r[i].origin),m.type="text/css",m.rel="stylesheet",m.href=r[i].fPath,document.body.appendChild(m)}}else if("t"===r[i].fOrigin||2===r[i].origin){for(h=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),l=0;l<h.length;l+=1)r[i].fPath===h[l].src&&(p=!1);if(p){var c=createTag("link");c.setAttribute("f-forigin",r[i].fOrigin),c.setAttribute("f-origin",r[i].origin),c.setAttribute("rel","stylesheet"),c.setAttribute("href",r[i].fPath),e.appendChild(c)}}}else r[i].loaded=!0,o-=1;r[i].helper=a(r[i],e),r[i].cache={},this.fonts.push(r[i])}0===o?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},getCharData:function(e,i,r){for(var s=0,a=this.chars.length;s<a;){if(this.chars[s].ch===e&&this.chars[s].style===i&&this.chars[s].fFamily===r)return this.chars[s];s+=1}return("string"==typeof e&&13!==e.charCodeAt(0)||!e)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",e,i,r)),t},getFontByName:function(t){for(var e=0,i=this.fonts.length;e<i;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,i){var r=this.getFontByName(e),s=t;if(!r.cache[s]){var a=r.helper;if(" "===t){var n=a.measureText("|"+t+"|"),o=a.measureText("||");r.cache[s]=(n-o)/100}else r.cache[s]=a.measureText(t)/100}return r.cache[s]*i},checkLoadedFonts:function(){var t,e,i,r=this.fonts.length,s=r;for(t=0;t<r;t+=1)this.fonts[t].loaded?s-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,i=this.fonts[t].monoCase.w,e.offsetWidth!==i?(s-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,i=this.fonts[t].sansCase.w,e.offsetWidth!==i&&(s-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==s&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}};return h.prototype=l,h}();function SlotManager(t){this.animationData=t}function slotFactory(t){return new SlotManager(t)}function RenderableElement(){}SlotManager.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},RenderableElement.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var getBlendMode=(blendModeEnums={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return blendModeEnums[t]||""}),blendModeEnums;function SliderEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function AngleEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function ColorEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function PointEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function LayerIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function MaskIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function CheckboxEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function NoValueEffect(){this.p={}}function EffectsManager(t,e){var i,r=t.ef||[];this.effectElements=[];var s,a=r.length;for(i=0;i<a;i+=1)s=new GroupEffect(r[i],e),this.effectElements.push(s)}function GroupEffect(t,e){this.init(t,e)}function BaseElement(){}function FrameElement(){}function FootageElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,i)}function AudioElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,i),this._isPlaying=!1,this._canPlay=!1;var r=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(r),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=PropertyFactory.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function BaseRenderer(){}extendPrototype([DynamicPropertyContainer],GroupEffect),GroupEffect.prototype.getValue=GroupEffect.prototype.iterateDynamicProperties,GroupEffect.prototype.init=function(t,e){var i;this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var r,s=this.data.ef.length,a=this.data.ef;for(i=0;i<s;i+=1){switch(r=null,a[i].ty){case 0:r=new SliderEffect(a[i],e,this);break;case 1:r=new AngleEffect(a[i],e,this);break;case 2:r=new ColorEffect(a[i],e,this);break;case 3:r=new PointEffect(a[i],e,this);break;case 4:case 7:r=new CheckboxEffect(a[i],e,this);break;case 10:r=new LayerIndexEffect(a[i],e,this);break;case 11:r=new MaskIndexEffect(a[i],e,this);break;case 5:r=new EffectsManager(a[i],e,this);break;default:r=new NoValueEffect(a[i],e,this)}r&&this.effectElements.push(r)}},BaseElement.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t=getExpressionInterfaces();if(t){var e=t("layer"),i=t("effects"),r=t("shape"),s=t("text"),a=t("comp");this.layerInterface=e(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var n=i.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(n),0===this.data.ty||this.data.xt?this.compInterface=a(this):4===this.data.ty?(this.layerInterface.shapeInterface=r(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=s(this),this.layerInterface.text=this.layerInterface.textInterface)}},setBlendMode:function(){var t=getBlendMode(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,i){this.globalData=e,this.comp=i,this.data=t,this.layerId=createElementID(),this.data.sr||(this.data.sr=1),this.effectsManager=new EffectsManager(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},FrameElement.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var i,r=this.dynamicProperties.length;for(i=0;i<r;i+=1)(e||this._isParent&&"transform"===this.dynamicProperties[i].propType)&&(this.dynamicProperties[i].getValue(),this.dynamicProperties[i]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},FootageElement.prototype.prepareFrame=function(){},extendPrototype([RenderableElement,BaseElement,FrameElement],FootageElement),FootageElement.prototype.getBaseElement=function(){return null},FootageElement.prototype.renderFrame=function(){},FootageElement.prototype.destroy=function(){},FootageElement.prototype.initExpressions=function(){var t=getExpressionInterfaces();if(t){var e=t("footage");this.layerInterface=e(this)}},FootageElement.prototype.getFootageData=function(){return this.footageData},AudioElement.prototype.prepareFrame=function(t){if(this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder)this._currentTime=t/this.data.sr;else{var e=this.tm.v;this._currentTime=e}this._volume=this.lv.v[0];var i=this._volume*this._volumeMultiplier;this._previousVolume!==i&&(this._previousVolume=i,this.audio.volume(i))},extendPrototype([RenderableElement,BaseElement,FrameElement],AudioElement),AudioElement.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek())>.1)&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},AudioElement.prototype.show=function(){},AudioElement.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},AudioElement.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},AudioElement.prototype.resume=function(){this._canPlay=!0},AudioElement.prototype.setRate=function(t){this.audio.rate(t)},AudioElement.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},AudioElement.prototype.getBaseElement=function(){return null},AudioElement.prototype.destroy=function(){},AudioElement.prototype.sourceRectAtTime=function(){},AudioElement.prototype.initExpressions=function(){},BaseRenderer.prototype.checkLayers=function(t){var e,i,r=this.layers.length;for(this.completeLayers=!0,e=r-1;e>=0;e-=1)this.elements[e]||(i=this.layers[e]).ip-i.st<=t-this.layers[e].st&&i.op-i.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:default:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t)}},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.createAudio=function(t){return new AudioElement(t,this.globalData,this)},BaseRenderer.prototype.createFootage=function(t){return new FootageElement(t,this.globalData,this)},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},BaseRenderer.prototype.includeLayers=function(t){var e;this.completeLayers=!1;var i,r=t.length,s=this.layers.length;for(e=0;e<r;e+=1)for(i=0;i<s;){if(this.layers[i].id===t[e].id){this.layers[i]=t[e];break}i+=1}},BaseRenderer.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},BaseRenderer.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},BaseRenderer.prototype.buildElementParenting=function(t,e,i){for(var r=this.elements,s=this.layers,a=0,n=s.length;a<n;)s[a].ind==e&&(r[a]&&!0!==r[a]?(i.push(r[a]),r[a].setAsParent(),void 0!==s[a].parent?this.buildElementParenting(t,s[a].parent,i):t.setHierarchy(i)):(this.buildItem(a),this.addPendingElement(t))),a+=1},BaseRenderer.prototype.addPendingElement=function(t){this.pendingElements.push(t)},BaseRenderer.prototype.searchExtraCompositions=function(t){var e,i=t.length;for(e=0;e<i;e+=1)if(t[e].xt){var r=this.createComp(t[e]);r.initExpressions(),this.globalData.projectInterface.registerComposition(r)}},BaseRenderer.prototype.getElementById=function(t){var e,i=this.elements.length;for(e=0;e<i;e+=1)if(this.elements[e].data.ind===t)return this.elements[e];return null},BaseRenderer.prototype.getElementByPath=function(t){var e,i=t.shift();if("number"==typeof i)e=this.elements[i];else{var r,s=this.elements.length;for(r=0;r<s;r+=1)if(this.elements[r].data.nm===i){e=this.elements[r];break}}return 0===t.length?e:e.getElementByPath(t)},BaseRenderer.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new FontManager,this.globalData.slotManager=slotFactory(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var effectTypes={TRANSFORM_EFFECT:"transformEFfect"};function TransformElement(){}function MaskElement(t,e,i){this.data=t,this.element=e,this.globalData=i,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var r,s,a=this.globalData.defs,n=this.masksProperties?this.masksProperties.length:0;this.viewData=createSizedArray(n),this.solidPath="";var o,h,l,p,f,m,c=this.masksProperties,d=0,u=[],y=createElementID(),g="clipPath",v="clip-path";for(r=0;r<n;r+=1)if(("a"!==c[r].mode&&"n"!==c[r].mode||c[r].inv||100!==c[r].o.k||c[r].o.x)&&(g="mask",v="mask"),"s"!==c[r].mode&&"i"!==c[r].mode||0!==d?l=null:((l=createNS("rect")).setAttribute("fill","#ffffff"),l.setAttribute("width",this.element.comp.data.w||0),l.setAttribute("height",this.element.comp.data.h||0),u.push(l)),s=createNS("path"),"n"===c[r].mode)this.viewData[r]={op:PropertyFactory.getProp(this.element,c[r].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[r],3),elem:s,lastPath:""},a.appendChild(s);else{var b;if(d+=1,s.setAttribute("fill","s"===c[r].mode?"#000000":"#ffffff"),s.setAttribute("clip-rule","nonzero"),0!==c[r].x.k?(g="mask",v="mask",m=PropertyFactory.getProp(this.element,c[r].x,0,null,this.element),b=createElementID(),(p=createNS("filter")).setAttribute("id",b),(f=createNS("feMorphology")).setAttribute("operator","erode"),f.setAttribute("in","SourceGraphic"),f.setAttribute("radius","0"),p.appendChild(f),a.appendChild(p),s.setAttribute("stroke","s"===c[r].mode?"#000000":"#ffffff")):(f=null,m=null),this.storedData[r]={elem:s,x:m,expan:f,lastPath:"",lastOperator:"",filterId:b,lastRadius:0},"i"===c[r].mode){h=u.length;var x=createNS("g");for(o=0;o<h;o+=1)x.appendChild(u[o]);var P=createNS("mask");P.setAttribute("mask-type","alpha"),P.setAttribute("id",y+"_"+d),P.appendChild(s),a.appendChild(P),x.setAttribute("mask","url("+getLocationHref()+"#"+y+"_"+d+")"),u.length=0,u.push(x)}else u.push(s);c[r].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[r]={elem:s,lastPath:"",op:PropertyFactory.getProp(this.element,c[r].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[r],3),invRect:l},this.viewData[r].prop.k||this.drawPath(c[r],this.viewData[r].prop.v,this.viewData[r])}for(this.maskElement=createNS(g),n=u.length,r=0;r<n;r+=1)this.maskElement.appendChild(u[r]);d>0&&(this.maskElement.setAttribute("id",y),this.element.maskedElement.setAttribute(v,"url("+getLocationHref()+"#"+y+")"),a.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}TransformElement.prototype={initTransform:function(){var t=new Matrix;this.finalTransform={mProp:this.data.ks?TransformPropertyFactory.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,i=0,r=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;i<r;){if(this.hierarchy[i].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}i+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),i=0;i<r;i+=1)e.multiply(this.hierarchy[i].finalTransform.mProp.v)}this.finalTransform._matMdf&&(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var i=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(i),t=1;t<e;t+=1){var r=this.localTransforms[t].matrix;i.multiply(r)}i.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){var s=this.finalTransform.localOpacity;for(t=0;t<e;t+=1)s*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=s}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new Matrix;var e=0,i=t.length;for(e=0;e<i;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var i,r=!0,s=this.comp;r;)s.finalTransform?(s.data.hasMask&&e.splice(0,0,s.finalTransform),s=s.comp):r=!1;var a,n=e.length;for(i=0;i<n;i+=1)a=e[i].mat.applyToPointArray(0,0,0),t=[t[0]-a[0],t[1]-a[1],0];return t},mHelper:new Matrix},MaskElement.prototype.getMaskProperty=function(t){return this.viewData[t].prop},MaskElement.prototype.renderFrame=function(t){var e,i=this.element.finalTransform.mat,r=this.masksProperties.length;for(e=0;e<r;e+=1)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[e].invRect.setAttribute("transform",i.getInverseMatrix().to2dCSS()),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var s=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+getLocationHref()+"#"+this.storedData[e].filterId+")")),s.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},MaskElement.prototype.getMaskelement=function(){return this.maskElement},MaskElement.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},MaskElement.prototype.drawPath=function(t,e,i){var r,s,a=" M"+e.v[0][0]+","+e.v[0][1];for(s=e._length,r=1;r<s;r+=1)a+=" C"+e.o[r-1][0]+","+e.o[r-1][1]+" "+e.i[r][0]+","+e.i[r][1]+" "+e.v[r][0]+","+e.v[r][1];if(e.c&&s>1&&(a+=" C"+e.o[r-1][0]+","+e.o[r-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),i.lastPath!==a){var n="";i.elem&&(e.c&&(n=t.inv?this.solidPath+a:a),i.elem.setAttribute("d",n)),i.lastPath=a}},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var filtersFactory=function(){var t={};return t.createFilter=function(t,e){var i=createNS("filter");i.setAttribute("id",t),!0!==e&&(i.setAttribute("filterUnits","objectBoundingBox"),i.setAttribute("x","0%"),i.setAttribute("y","0%"),i.setAttribute("width","100%"),i.setAttribute("height","100%"));return i},t.createAlphaToLuminanceFilter=function(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},t}(),featureSupport=function(){var t={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),/firefox/i.test(navigator.userAgent)&&(t.svgLumaHidden=!1),t}(),registeredEffects$1={},idPrefix="filter_result_";function SVGEffects(t){var e,i,r="SourceGraphic",s=t.data.ef?t.data.ef.length:0,a=createElementID(),n=filtersFactory.createFilter(a,!0),o=0;for(this.filters=[],e=0;e<s;e+=1){i=null;var h=t.data.ef[e].ty;if(registeredEffects$1[h])i=new(0,registeredEffects$1[h].effect)(n,t.effectsManager.effectElements[e],t,idPrefix+o,r),r=idPrefix+o,registeredEffects$1[h].countsAsEffect&&(o+=1);i&&this.filters.push(i)}o&&(t.globalData.defs.appendChild(n),t.layerElement.setAttribute("filter","url("+getLocationHref()+"#"+a+")")),this.filters.length&&t.addRenderableComponent(this)}function registerEffect$1(t,e,i){registeredEffects$1[t]={effect:e,countsAsEffect:i}}function SVGBaseElement(){}function HierarchyElement(){}function RenderableDOMElement(){}function IImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,i),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ProcessedElement(t,e){this.elem=t,this.pos=e}function IShapeElement(){}SVGEffects.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},SVGEffects.prototype.getEffects=function(t){var e,i=this.filters.length,r=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&r.push(this.filters[e]);return r},SVGBaseElement.prototype={initRendererElement:function(){this.layerElement=createNS("g")},createContainerElements:function(){this.matteElement=createNS("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t=null;if(this.data.td){this.matteMasks={};var e=createNS("g");e.setAttribute("id",this.layerId),e.appendChild(this.layerElement),t=e,this.globalData.defs.appendChild(e)}else this.data.tt?(this.matteElement.appendChild(this.layerElement),t=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var i=createNS("clipPath"),r=createNS("path");r.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var s=createElementID();if(i.setAttribute("id",s),i.appendChild(r),this.globalData.defs.appendChild(i),this.checkMasks()){var a=createNS("g");a.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),a.appendChild(this.layerElement),this.transformedElement=a,t?t.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData),this.renderableEffectsManager=new SVGEffects(this),this.searchEffectTransforms()},getMatte:function(t){if(this.matteMasks||(this.matteMasks={}),!this.matteMasks[t]){var e,i,r,s,a=this.layerId+"_"+t;if(1===t||3===t){var n=createNS("mask");n.setAttribute("id",a),n.setAttribute("mask-type",3===t?"luminance":"alpha"),(r=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),n.appendChild(r),this.globalData.defs.appendChild(n),featureSupport.maskType||1!==t||(n.setAttribute("mask-type","luminance"),e=createElementID(),i=filtersFactory.createFilter(e),this.globalData.defs.appendChild(i),i.appendChild(filtersFactory.createAlphaToLuminanceFilter()),(s=createNS("g")).appendChild(r),n.appendChild(s),s.setAttribute("filter","url("+getLocationHref()+"#"+e+")"))}else if(2===t){var o=createNS("mask");o.setAttribute("id",a),o.setAttribute("mask-type","alpha");var h=createNS("g");o.appendChild(h),e=createElementID(),i=filtersFactory.createFilter(e);var l=createNS("feComponentTransfer");l.setAttribute("in","SourceGraphic"),i.appendChild(l);var p=createNS("feFuncA");p.setAttribute("type","table"),p.setAttribute("tableValues","1.0 0.0"),l.appendChild(p),this.globalData.defs.appendChild(i);var f=createNS("rect");f.setAttribute("width",this.comp.data.w),f.setAttribute("height",this.comp.data.h),f.setAttribute("x","0"),f.setAttribute("y","0"),f.setAttribute("fill","#ffffff"),f.setAttribute("opacity","0"),h.setAttribute("filter","url("+getLocationHref()+"#"+e+")"),h.appendChild(f),(r=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),h.appendChild(r),featureSupport.maskType||(o.setAttribute("mask-type","luminance"),i.appendChild(filtersFactory.createAlphaToLuminanceFilter()),s=createNS("g"),h.appendChild(f),s.appendChild(this.layerElement),h.appendChild(s)),this.globalData.defs.appendChild(o)}this.matteMasks[t]=a}return this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+getLocationHref()+"#"+t+")")}},HierarchyElement.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},extendPrototype([RenderableElement,createProxyFunction({initElement:function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],RenderableDOMElement),extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],IImageElement),IImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=createNS("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},IImageElement.prototype.sourceRectAtTime=function(){return this.sourceRect},IShapeElement.prototype={addShapeToModifiers:function(t){var e,i=this.shapeModifiers.length;for(e=0;e<i;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;t>=0&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,i=0,r=e.length;i<r;){if(e[i].elem===t)return e[i].pos;i+=1}return 0},addProcessedElement:function(t,e){for(var i=this.processedElements,r=i.length;r;)if(i[r-=1].elem===t)return void(i[r].pos=e);i.push(new ProcessedElement(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var lineCapEnum={1:"butt",2:"round",3:"square"},lineJoinEnum={1:"miter",2:"round",3:"bevel"};function SVGShapeData(t,e,i){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=i,this.lvl=e,this._isAnimated=!!i.k;for(var r=0,s=t.length;r<s;){if(t[r].mProps.dynamicProperties.length){this._isAnimated=!0;break}r+=1}}function SVGStyleData(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=createNS("path"),this.msElem=null}function DashProperty(t,e,i,r){var s;this.elem=t,this.frameId=-1,this.dataProps=createSizedArray(e.length),this.renderer=i,this.k=!1,this.dashStr="",this.dashArray=createTypedArray("float32",e.length?e.length-1:0),this.dashoffset=createTypedArray("float32",1),this.initDynamicPropertyContainer(r);var a,n=e.length||0;for(s=0;s<n;s+=1)a=PropertyFactory.getProp(t,e[s].v,0,0,this),this.k=a.k||this.k,this.dataProps[s]={n:e[s].n,p:a};this.k||this.getValue(!0),this._isAnimated=this.k}function SVGStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i,this._isAnimated=!!this._isAnimated}function SVGFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i}function SVGNoStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=i}function GradientProperty(t,e,i){this.data=e,this.c=createTypedArray("uint8c",4*e.p);var r=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=createTypedArray("float32",r),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=r,this.initDynamicPropertyContainer(i),this.prop=PropertyFactory.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function SVGGradientFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,i)}function SVGGradientStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.initGradientData(t,e,i),this._isAnimated=!!this._isAnimated}function ShapeGroupData(){this.it=[],this.prevViewData=[],this.gr=createNS("g")}function SVGTransformData(t,e,i){this.transform={mProps:t,op:e,container:i},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}SVGShapeData.prototype.setAsAnimated=function(){this._isAnimated=!0},SVGStyleData.prototype.reset=function(){this.d="",this._mdf=!1},DashProperty.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,i=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<i;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},extendPrototype([DynamicPropertyContainer],DashProperty),extendPrototype([DynamicPropertyContainer],SVGStrokeStyleData),extendPrototype([DynamicPropertyContainer],SVGFillStyleData),extendPrototype([DynamicPropertyContainer],SVGNoStyleData),GradientProperty.prototype.comparePoints=function(t,e){for(var i=0,r=this.o.length/2;i<r;){if(Math.abs(t[4*i]-t[4*e+2*i])>.01)return!1;i+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},GradientProperty.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,i,r,s=4*this.data.p;for(e=0;e<s;e+=1)i=e%4==0?100:255,r=Math.round(this.prop.v[e]*i),this.c[e]!==r&&(this.c[e]=r,this._cmdf=!t);if(this.o.length)for(s=this.prop.v.length,e=4*this.data.p;e<s;e+=1)i=e%2==0?100:1,r=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==r&&(this.o[e-4*this.data.p]=r,this._omdf=!t);this._mdf=!t}},extendPrototype([DynamicPropertyContainer],GradientProperty),SVGGradientFillStyleData.prototype.initGradientData=function(t,e,i){this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.s=PropertyFactory.getProp(t,e.s,1,null,this),this.e=PropertyFactory.getProp(t,e.e,1,null,this),this.h=PropertyFactory.getProp(t,e.h||{k:0},0,.01,this),this.a=PropertyFactory.getProp(t,e.a||{k:0},0,degToRads,this),this.g=new GradientProperty(t,e.g,this),this.style=i,this.stops=[],this.setGradientData(i.pElem,e),this.setGradientOpacity(e,i),this._isAnimated=!!this._isAnimated},SVGGradientFillStyleData.prototype.setGradientData=function(t,e){var i=createElementID(),r=createNS(1===e.t?"linearGradient":"radialGradient");r.setAttribute("id",i),r.setAttribute("spreadMethod","pad"),r.setAttribute("gradientUnits","userSpaceOnUse");var s,a,n,o=[];for(n=4*e.g.p,a=0;a<n;a+=4)s=createNS("stop"),r.appendChild(s),o.push(s);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+getLocationHref()+"#"+i+")"),this.gf=r,this.cst=o},SVGGradientFillStyleData.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){var i,r,s,a=createNS("mask"),n=createNS("path");a.appendChild(n);var o=createElementID(),h=createElementID();a.setAttribute("id",h);var l=createNS(1===t.t?"linearGradient":"radialGradient");l.setAttribute("id",o),l.setAttribute("spreadMethod","pad"),l.setAttribute("gradientUnits","userSpaceOnUse"),s=t.g.k.k[0].s?t.g.k.k[0].s.length:t.g.k.k.length;var p=this.stops;for(r=4*t.g.p;r<s;r+=2)(i=createNS("stop")).setAttribute("stop-color","rgb(255,255,255)"),l.appendChild(i),p.push(i);n.setAttribute("gf"===t.ty?"fill":"stroke","url("+getLocationHref()+"#"+o+")"),"gs"===t.ty&&(n.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),n.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),1===t.lj&&n.setAttribute("stroke-miterlimit",t.ml)),this.of=l,this.ms=a,this.ost=p,this.maskId=h,e.msElem=n}},extendPrototype([DynamicPropertyContainer],SVGGradientFillStyleData),extendPrototype([SVGGradientFillStyleData,DynamicPropertyContainer],SVGGradientStrokeStyleData);var buildShapeString=function(t,e,i,r){if(0===e)return"";var s,a=t.o,n=t.i,o=t.v,h=" M"+r.applyToPointStringified(o[0][0],o[0][1]);for(s=1;s<e;s+=1)h+=" C"+r.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+r.applyToPointStringified(n[s][0],n[s][1])+" "+r.applyToPointStringified(o[s][0],o[s][1]);return i&&e&&(h+=" C"+r.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+r.applyToPointStringified(n[0][0],n[0][1])+" "+r.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},SVGElementsRenderer=function(){var t=new Matrix,e=new Matrix;function i(t,e,i){(i||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(i||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function r(){}function s(i,r,s){var a,n,o,h,l,p,f,m,c,d,u=r.styles.length,y=r.lvl;for(p=0;p<u;p+=1){if(h=r.sh._mdf||s,r.styles[p].lvl<y){for(m=e.reset(),c=y-r.styles[p].lvl,d=r.transformers.length-1;!h&&c>0;)h=r.transformers[d].mProps._mdf||h,c-=1,d-=1;if(h)for(c=y-r.styles[p].lvl,d=r.transformers.length-1;c>0;)m.multiply(r.transformers[d].mProps.v),c-=1,d-=1}else m=t;if(n=(f=r.sh.paths)._length,h){for(o="",a=0;a<n;a+=1)(l=f.shapes[a])&&l._length&&(o+=buildShapeString(l,l._length,l.c,m));r.caches[p]=o}else o=r.caches[p];r.styles[p].d+=!0===i.hd?"":o,r.styles[p]._mdf=h||r.styles[p]._mdf}}function a(t,e,i){var r=e.style;(e.c._mdf||i)&&r.pElem.setAttribute("fill","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("fill-opacity",e.o.v)}function n(t,e,i){o(t,e,i),h(t,e,i)}function o(t,e,i){var r,s,a,n,o,h=e.gf,l=e.g._hasOpacity,p=e.s.v,f=e.e.v;if(e.o._mdf||i){var m="gf"===t.ty?"fill-opacity":"stroke-opacity";e.style.pElem.setAttribute(m,e.o.v)}if(e.s._mdf||i){var c=1===t.t?"x1":"cx",d="x1"===c?"y1":"cy";h.setAttribute(c,p[0]),h.setAttribute(d,p[1]),l&&!e.g._collapsable&&(e.of.setAttribute(c,p[0]),e.of.setAttribute(d,p[1]))}if(e.g._cmdf||i){r=e.cst;var u=e.g.c;for(a=r.length,s=0;s<a;s+=1)(n=r[s]).setAttribute("offset",u[4*s]+"%"),n.setAttribute("stop-color","rgb("+u[4*s+1]+","+u[4*s+2]+","+u[4*s+3]+")")}if(l&&(e.g._omdf||i)){var y=e.g.o;for(a=(r=e.g._collapsable?e.cst:e.ost).length,s=0;s<a;s+=1)n=r[s],e.g._collapsable||n.setAttribute("offset",y[2*s]+"%"),n.setAttribute("stop-opacity",y[2*s+1])}if(1===t.t)(e.e._mdf||i)&&(h.setAttribute("x2",f[0]),h.setAttribute("y2",f[1]),l&&!e.g._collapsable&&(e.of.setAttribute("x2",f[0]),e.of.setAttribute("y2",f[1])));else if((e.s._mdf||e.e._mdf||i)&&(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)),h.setAttribute("r",o),l&&!e.g._collapsable&&e.of.setAttribute("r",o)),e.e._mdf||e.h._mdf||e.a._mdf||i){o||(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)));var g=Math.atan2(f[1]-p[1],f[0]-p[0]),v=e.h.v;v>=1?v=.99:v<=-1&&(v=-.99);var b=o*v,x=Math.cos(g+e.a.v)*b+p[0],P=Math.sin(g+e.a.v)*b+p[1];h.setAttribute("fx",x),h.setAttribute("fy",P),l&&!e.g._collapsable&&(e.of.setAttribute("fx",x),e.of.setAttribute("fy",P))}}function h(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||i)&&s.dashStr&&(r.pElem.setAttribute("stroke-dasharray",s.dashStr),r.pElem.setAttribute("stroke-dashoffset",s.dashoffset[0])),e.c&&(e.c._mdf||i)&&r.pElem.setAttribute("stroke","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||i)&&(r.pElem.setAttribute("stroke-width",e.w.v),r.msElem&&r.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function(t){switch(t.ty){case"fl":return a;case"gf":return o;case"gs":return n;case"st":return h;case"sh":case"el":case"rc":case"sr":return s;case"tr":return i;case"no":return r;default:return null}}}}();function SVGShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,i),this.prevViewData=[]}function LetterProps(t,e,i,r,s,a){this.o=t,this.sw=e,this.sc=i,this.fc=r,this.m=s,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!i,fc:!!r,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){var t,e,i,r,s=this.shapes.length,a=this.stylesList.length,n=[],o=!1;for(i=0;i<a;i+=1){for(r=this.stylesList[i],o=!1,n.length=0,t=0;t<s;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(r)&&(n.push(e),o=e._isAnimated||o);n.length>1&&o&&this.setShapesAsAnimated(n)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].setAsAnimated()},SVGShapeElement.prototype.createStyleElement=function(t,e){var i,r=new SVGStyleData(t,e),s=r.pElem;if("st"===t.ty)i=new SVGStrokeStyleData(this,t,r);else if("fl"===t.ty)i=new SVGFillStyleData(this,t,r);else if("gf"===t.ty||"gs"===t.ty){i=new("gf"===t.ty?SVGGradientFillStyleData:SVGGradientStrokeStyleData)(this,t,r),this.globalData.defs.appendChild(i.gf),i.maskId&&(this.globalData.defs.appendChild(i.ms),this.globalData.defs.appendChild(i.of),s.setAttribute("mask","url("+getLocationHref()+"#"+i.maskId+")"))}else"no"===t.ty&&(i=new SVGNoStyleData(this,t,r));return"st"!==t.ty&&"gs"!==t.ty||(s.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),s.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),s.setAttribute("fill-opacity","0"),1===t.lj&&s.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&s.setAttribute("fill-rule","evenodd"),t.ln&&s.setAttribute("id",t.ln),t.cl&&s.setAttribute("class",t.cl),t.bm&&(s.style["mix-blend-mode"]=getBlendMode(t.bm)),this.stylesList.push(r),this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createGroupElement=function(t){var e=new ShapeGroupData;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=getBlendMode(t.bm)),e},SVGShapeElement.prototype.createTransformElement=function(t,e){var i=TransformPropertyFactory.getTransformProperty(this,t,this),r=new SVGTransformData(i,i.o,e);return this.addToAnimatedContents(t,r),r},SVGShapeElement.prototype.createShapeElement=function(t,e,i){var r=4;"rc"===t.ty?r=5:"el"===t.ty?r=6:"sr"===t.ty&&(r=7);var s=new SVGShapeData(e,i,ShapePropertyFactory.getShapeProp(this,t,r,this));return this.shapes.push(s),this.addShapeToModifiers(s),this.addToAnimatedContents(t,s),s},SVGShapeElement.prototype.addToAnimatedContents=function(t,e){for(var i=0,r=this.animatedContents.length;i<r;){if(this.animatedContents[i].element===e)return;i+=1}this.animatedContents.push({fn:SVGElementsRenderer.createRenderFunction(t),element:e,data:t})},SVGShapeElement.prototype.setElementStyles=function(t){var e,i=t.styles,r=this.stylesList.length;for(e=0;e<r;e+=1)this.stylesList[e].closed||i.push(this.stylesList[e])},SVGShapeElement.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},SVGShapeElement.prototype.searchShapes=function(t,e,i,r,s,a,n){var o,h,l,p,f,m,c=[].concat(a),d=t.length-1,u=[],y=[];for(o=d;o>=0;o-=1){if((m=this.searchProcessedElement(t[o]))?e[o]=i[m-1]:t[o]._render=n,"fl"===t[o].ty||"st"===t[o].ty||"gf"===t[o].ty||"gs"===t[o].ty||"no"===t[o].ty)m?e[o].style.closed=!1:e[o]=this.createStyleElement(t[o],s),t[o]._render&&e[o].style.pElem.parentNode!==r&&r.appendChild(e[o].style.pElem),u.push(e[o].style);else if("gr"===t[o].ty){if(m)for(l=e[o].it.length,h=0;h<l;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,s+1,c,n),t[o]._render&&e[o].gr.parentNode!==r&&r.appendChild(e[o].gr)}else"tr"===t[o].ty?(m||(e[o]=this.createTransformElement(t[o],r)),p=e[o].transform,c.push(p)):"sh"===t[o].ty||"rc"===t[o].ty||"el"===t[o].ty||"sr"===t[o].ty?(m||(e[o]=this.createShapeElement(t[o],c,s)),this.setElementStyles(e[o])):"tm"===t[o].ty||"rd"===t[o].ty||"ms"===t[o].ty||"pb"===t[o].ty||"zz"===t[o].ty||"op"===t[o].ty?(m?(f=e[o]).closed=!1:((f=ShapeModifiers.getModifier(t[o].ty)).init(this,t[o]),e[o]=f,this.shapeModifiers.push(f)),y.push(f)):"rp"===t[o].ty&&(m?(f=e[o]).closed=!0:(f=ShapeModifiers.getModifier(t[o].ty),e[o]=f,f.init(this,t,o,e),this.shapeModifiers.push(f),n=!1),y.push(f));this.addProcessedElement(t[o],o+1)}for(d=u.length,o=0;o<d;o+=1)u[o].closed=!0;for(d=y.length,o=0;o<d;o+=1)y[o].closed=!0},SVGShapeElement.prototype.renderInnerContent=function(){var t;this.renderModifiers();var e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},SVGShapeElement.prototype.renderShape=function(){var t,e,i=this.animatedContents.length;for(t=0;t<i;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},SVGShapeElement.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},LetterProps.prototype.update=function(t,e,i,r,s,a){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1,this._mdf.p=!1;var n=!1;return this.o!==t&&(this.o=t,this._mdf.o=!0,n=!0),this.sw!==e&&(this.sw=e,this._mdf.sw=!0,n=!0),this.sc!==i&&(this.sc=i,this._mdf.sc=!0,n=!0),this.fc!==r&&(this.fc=r,this._mdf.fc=!0,n=!0),this.m!==s&&(this.m=s,this._mdf.m=!0,n=!0),!a.length||this.p[0]===a[0]&&this.p[1]===a[1]&&this.p[4]===a[4]&&this.p[5]===a[5]&&this.p[12]===a[12]&&this.p[13]===a[13]||(this.p=a,this._mdf.p=!0,n=!0),n},TextProperty.prototype.defaultBoxWidth=[0,0],TextProperty.prototype.copyData=function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},TextProperty.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},TextProperty.prototype.searchProperty=function(){return this.searchKeyframes()},TextProperty.prototype.searchKeyframes=function(){return this.kf=this.data.d.k.length>1,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,i=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{var r;this.lock=!0,this._mdf=!1;var s=this.effectsSequence.length,a=t||this.data.d.k[this.keysIndex].s;for(r=0;r<s;r+=1)a=i!==this.keysIndex?this.effectsSequence[r](a,a.t):this.effectsSequence[r](this.currentData,a.t);e!==a&&this.setCurrentData(a),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},TextProperty.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,i=0,r=t.length;i<=r-1&&!(i===r-1||t[i+1].t>e);)i+=1;return this.keysIndex!==i&&(this.keysIndex=i),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e,i,r=[],s=0,a=t.length,n=!1,o=!1,h="";s<a;)n=o,o=!1,e=t.charCodeAt(s),h=t.charAt(s),FontManager.isCombinedCharacter(e)?n=!0:e>=55296&&e<=56319?FontManager.isRegionalFlag(t,s)?h=t.substr(s,14):(i=t.charCodeAt(s+1))>=56320&&i<=57343&&(FontManager.isModifier(e,i)?(h=t.substr(s,2),n=!0):h=FontManager.isFlagEmoji(t.substr(s,4))?t.substr(s,4):t.substr(s,2)):e>56319?(i=t.charCodeAt(s+1),FontManager.isVariationSelector(e)&&(n=!0)):FontManager.isZeroWidthJoiner(e)&&(n=!0,o=!0),n?(r[r.length-1]+=h,n=!1):r.push(h),s+=h.length;return r},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,i,r,s,a,n,o,h=this.elem.globalData.fontManager,l=this.data,p=[],f=0,m=l.m.g,c=0,d=0,u=0,y=[],g=0,v=0,b=h.getFontByName(t.f),x=0,P=getFontProperties(b);t.fWeight=P.weight,t.fStyle=P.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),i=t.finalText.length,t.finalLineHeight=t.lh;var E,S=t.tr/1e3*t.finalSize;if(t.sz)for(var C,_,A=!0,T=t.sz[0],M=t.sz[1];A;){C=0,g=0,i=(_=this.buildFinalText(t.t)).length,S=t.tr/1e3*t.finalSize;var k=-1;for(e=0;e<i;e+=1)E=_[e].charCodeAt(0),r=!1," "===_[e]?k=e:13!==E&&3!==E||(g=0,r=!0,C+=t.finalLineHeight||1.2*t.finalSize),h.chars?(o=h.getCharData(_[e],b.fStyle,b.fFamily),x=r?0:o.w*t.finalSize/100):x=h.measureText(_[e],t.f,t.finalSize),g+x>T&&" "!==_[e]?(-1===k?i+=1:e=k,C+=t.finalLineHeight||1.2*t.finalSize,_.splice(e,k===e?1:0,"\r"),k=-1,g=0):(g+=x,g+=S);C+=b.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&M<C?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=_,i=t.finalText.length,A=!1)}g=-S,x=0;var D,F=0;for(e=0;e<i;e+=1)if(r=!1,13===(E=(D=t.finalText[e]).charCodeAt(0))||3===E?(F=0,y.push(g),v=g>v?g:v,g=-2*S,s="",r=!0,u+=1):s=D,h.chars?(o=h.getCharData(D,b.fStyle,h.getFontByName(t.f).fFamily),x=r?0:o.w*t.finalSize/100):x=h.measureText(s,t.f,t.finalSize)," "===D?F+=x+S:(g+=x+S+F,F=0),p.push({l:x,an:x,add:c,n:r,anIndexes:[],val:s,line:u,animatorJustifyOffset:0}),2==m){if(c+=x,""===s||" "===s||e===i-1){for(""!==s&&" "!==s||(c-=x);d<=e;)p[d].an=c,p[d].ind=f,p[d].extra=x,d+=1;f+=1,c=0}}else if(3==m){if(c+=x,""===s||e===i-1){for(""===s&&(c-=x);d<=e;)p[d].an=c,p[d].ind=f,p[d].extra=x,d+=1;c=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=g>v?g:v,y.push(g),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=y;var w,I,V,B,R=l.a;n=R.length;var L=[];for(a=0;a<n;a+=1){for((w=R[a]).a.sc&&(t.strokeColorAnim=!0),w.a.sw&&(t.strokeWidthAnim=!0),(w.a.fc||w.a.fh||w.a.fs||w.a.fb)&&(t.fillColorAnim=!0),B=0,V=w.s.b,e=0;e<i;e+=1)(I=p[e]).anIndexes[a]=B,(1==V&&""!==I.val||2==V&&""!==I.val&&" "!==I.val||3==V&&(I.n||" "==I.val||e==i-1)||4==V&&(I.n||e==i-1))&&(1===w.s.rn&&L.push(B),B+=1);l.a[a].s.totalChars=B;var G,z=-1;if(1===w.s.rn)for(e=0;e<i;e+=1)z!=(I=p[e]).anIndexes[a]&&(z=I.anIndexes[a],G=L.splice(Math.floor(Math.random()*L.length),1)[0]),I.anIndexes[a]=G}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=b.ascent*t.finalSize/100},TextProperty.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var i=this.copyData({},this.data.d.k[e].s);i=this.copyData(i,t),this.data.d.k[e].s=i,this.recalculate(e),this.setCurrentData(i),this.elem.addDynamicProperty(this)},TextProperty.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},TextProperty.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},TextProperty.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var TextSelectorProp=function(){var t=Math.max,e=Math.min,i=Math.floor;function r(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=PropertyFactory.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?PropertyFactory.getProp(t,e.e,0,0,this):{v:100},this.o=PropertyFactory.getProp(t,e.o||{k:0},0,0,this),this.xe=PropertyFactory.getProp(t,e.xe||{k:0},0,0,this),this.ne=PropertyFactory.getProp(t,e.ne||{k:0},0,0,this),this.sm=PropertyFactory.getProp(t,e.sm||{k:100},0,0,this),this.a=PropertyFactory.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return r.prototype={getMult:function(r){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var s=0,a=0,n=1,o=1;this.ne.v>0?s=this.ne.v/100:a=-this.ne.v/100,this.xe.v>0?n=1-this.xe.v/100:o=1+this.xe.v/100;var h=BezierFactory.getBezierEasing(s,a,n,o).get,l=0,p=this.finalS,f=this.finalE,m=this.data.sh;if(2===m)l=h(l=f===p?r>=f?1:0:t(0,e(.5/(f-p)+(r-p)/(f-p),1)));else if(3===m)l=h(l=f===p?r>=f?0:1:1-t(0,e(.5/(f-p)+(r-p)/(f-p),1)));else if(4===m)f===p?l=0:(l=t(0,e(.5/(f-p)+(r-p)/(f-p),1)))<.5?l*=2:l=1-2*(l-.5),l=h(l);else if(5===m){if(f===p)l=0;else{var c=f-p,d=-c/2+(r=e(t(0,r+.5-p),f-p)),u=c/2;l=Math.sqrt(1-d*d/(u*u))}l=h(l)}else 6===m?(f===p?l=0:(r=e(t(0,r+.5-p),f-p),l=(1+Math.cos(Math.PI+2*Math.PI*r/(f-p)))/2),l=h(l)):(r>=i(p)&&(l=t(0,e(r-p<0?e(f,1)-(p-r):f-r,1))),l=h(l));if(100!==this.sm.v){var y=.01*this.sm.v;0===y&&(y=1e-8);var g=.5-.5*y;l<g?l=0:(l=(l-g)/y)>1&&(l=1)}return l*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,i=this.o.v/e,r=this.s.v/e+i,s=this.e.v/e+i;if(r>s){var a=r;r=s,s=a}this.finalS=r,this.finalE=s}},extendPrototype([DynamicPropertyContainer],r),{getTextSelectorProp:function(t,e,i){return new r(t,e,i)}}}();function TextAnimatorDataProperty(t,e,i){var r={propType:!1},s=PropertyFactory.getProp,a=e.a;this.a={r:a.r?s(t,a.r,0,degToRads,i):r,rx:a.rx?s(t,a.rx,0,degToRads,i):r,ry:a.ry?s(t,a.ry,0,degToRads,i):r,sk:a.sk?s(t,a.sk,0,degToRads,i):r,sa:a.sa?s(t,a.sa,0,degToRads,i):r,s:a.s?s(t,a.s,1,.01,i):r,a:a.a?s(t,a.a,1,0,i):r,o:a.o?s(t,a.o,0,.01,i):r,p:a.p?s(t,a.p,1,0,i):r,sw:a.sw?s(t,a.sw,0,0,i):r,sc:a.sc?s(t,a.sc,1,0,i):r,fc:a.fc?s(t,a.fc,1,0,i):r,fh:a.fh?s(t,a.fh,0,0,i):r,fs:a.fs?s(t,a.fs,0,.01,i):r,fb:a.fb?s(t,a.fb,0,.01,i):r,t:a.t?s(t,a.t,0,0,i):r},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,i),this.s.t=e.s.t}function TextAnimatorProperty(t,e,i){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=i,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(i)}function ITextElement(){}TextAnimatorProperty.prototype.searchProperties=function(){var t,e,i=this._textData.a.length,r=PropertyFactory.getProp;for(t=0;t<i;t+=1)e=this._textData.a[t],this._animatorsData[t]=new TextAnimatorDataProperty(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:r(this._elem,this._textData.p.a,0,0,this),f:r(this._elem,this._textData.p.f,0,0,this),l:r(this._elem,this._textData.p.l,0,0,this),r:r(this._elem,this._textData.p.r,0,0,this),p:r(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=r(this._elem,this._textData.m.a,1,0,this)},TextAnimatorProperty.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var i,r,s,a,n,o,h,l,p,f,m,c,d,u,y,g,v,b,x,P=this._moreOptions.alignment.v,E=this._animatorsData,S=this._textData,C=this.mHelper,_=this._renderType,A=this.renderedLetters.length,T=t.l;if(this._hasMaskedPath){if(x=this._pathData.m,!this._pathData.n||this._pathData._mdf){var M,k=x.v;for(this._pathData.r.v&&(k=k.reverse()),n={tLength:0,segments:[]},a=k._length-1,g=0,s=0;s<a;s+=1)M=bez.buildBezierData(k.v[s],k.v[s+1],[k.o[s][0]-k.v[s][0],k.o[s][1]-k.v[s][1]],[k.i[s+1][0]-k.v[s+1][0],k.i[s+1][1]-k.v[s+1][1]]),n.tLength+=M.segmentLength,n.segments.push(M),g+=M.segmentLength;s=a,x.v.c&&(M=bez.buildBezierData(k.v[s],k.v[0],[k.o[s][0]-k.v[s][0],k.o[s][1]-k.v[s][1]],[k.i[0][0]-k.v[0][0],k.i[0][1]-k.v[0][1]]),n.tLength+=M.segmentLength,n.segments.push(M),g+=M.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,m=0,f=1,l=0,p=!0,u=n.segments,o<0&&x.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),f=(d=u[m=u.length-1].points).length-1;o<0;)o+=d[f].partialLength,(f-=1)<0&&(f=(d=u[m-=1].points).length-1);c=(d=u[m].points)[f-1],y=(h=d[f]).partialLength}a=T.length,i=0,r=0;var D,F,w,I,V,B=1.2*t.finalSize*.714,R=!0;w=E.length;var L,G,z,O,N,H,q,j,W,$,Y,J,X=-1,Z=o,K=m,U=f,Q=-1,tt="",et=this.defaultPropsArray;if(2===t.j||1===t.j){var it=0,rt=0,st=2===t.j?-.5:-1,at=0,nt=!0;for(s=0;s<a;s+=1)if(T[s].n){for(it&&(it+=rt);at<s;)T[at].animatorJustifyOffset=it,at+=1;it=0,nt=!0}else{for(F=0;F<w;F+=1)(D=E[F].a).t.propType&&(nt&&2===t.j&&(rt+=D.t.v*st),(V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?it+=D.t.v*V[0]*st:it+=D.t.v*V*st);nt=!1}for(it&&(it+=rt);at<s;)T[at].animatorJustifyOffset=it,at+=1}for(s=0;s<a;s+=1){if(C.reset(),O=1,T[s].n)i=0,r+=t.yOffset,r+=R?1:0,o=Z,R=!1,this._hasMaskedPath&&(f=U,c=(d=u[m=K].points)[f-1],y=(h=d[f]).partialLength,l=0),tt="",Y="",W="",J="",et=this.defaultPropsArray;else{if(this._hasMaskedPath){if(Q!==T[s].line){switch(t.j){case 1:o+=g-t.lineWidths[T[s].line];break;case 2:o+=(g-t.lineWidths[T[s].line])/2}Q=T[s].line}X!==T[s].ind&&(T[X]&&(o+=T[X].extra),o+=T[s].an/2,X=T[s].ind),o+=P[0]*T[s].an*.005;var ot=0;for(F=0;F<w;F+=1)(D=E[F].a).p.propType&&((V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?ot+=D.p.v[0]*V[0]:ot+=D.p.v[0]*V),D.a.propType&&((V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?ot+=D.a.v[0]*V[0]:ot+=D.a.v[0]*V);for(p=!0,this._pathData.a.v&&(o=.5*T[0].an+(g-this._pathData.f.v-.5*T[0].an-.5*T[T.length-1].an)*X/(a-1),o+=this._pathData.f.v);p;)l+y>=o+ot||!d?(v=(o+ot-l)/h.partialLength,G=c.point[0]+(h.point[0]-c.point[0])*v,z=c.point[1]+(h.point[1]-c.point[1])*v,C.translate(-P[0]*T[s].an*.005,-P[1]*B*.01),p=!1):d&&(l+=h.partialLength,(f+=1)>=d.length&&(f=0,u[m+=1]?d=u[m].points:x.v.c?(f=0,d=u[m=0].points):(l-=h.partialLength,d=null)),d&&(c=h,y=(h=d[f]).partialLength));L=T[s].an/2-T[s].add,C.translate(-L,0,0)}else L=T[s].an/2-T[s].add,C.translate(-L,0,0),C.translate(-P[0]*T[s].an*.005,-P[1]*B*.01,0);for(F=0;F<w;F+=1)(D=E[F].a).t.propType&&(V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars),0===i&&0===t.j||(this._hasMaskedPath?V.length?o+=D.t.v*V[0]:o+=D.t.v*V:V.length?i+=D.t.v*V[0]:i+=D.t.v*V));for(t.strokeWidthAnim&&(H=t.sw||0),t.strokeColorAnim&&(N=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(q=[t.fc[0],t.fc[1],t.fc[2]]),F=0;F<w;F+=1)(D=E[F].a).a.propType&&((V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?C.translate(-D.a.v[0]*V[0],-D.a.v[1]*V[1],D.a.v[2]*V[2]):C.translate(-D.a.v[0]*V,-D.a.v[1]*V,D.a.v[2]*V));for(F=0;F<w;F+=1)(D=E[F].a).s.propType&&((V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?C.scale(1+(D.s.v[0]-1)*V[0],1+(D.s.v[1]-1)*V[1],1):C.scale(1+(D.s.v[0]-1)*V,1+(D.s.v[1]-1)*V,1));for(F=0;F<w;F+=1){if(D=E[F].a,V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars),D.sk.propType&&(V.length?C.skewFromAxis(-D.sk.v*V[0],D.sa.v*V[1]):C.skewFromAxis(-D.sk.v*V,D.sa.v*V)),D.r.propType&&(V.length?C.rotateZ(-D.r.v*V[2]):C.rotateZ(-D.r.v*V)),D.ry.propType&&(V.length?C.rotateY(D.ry.v*V[1]):C.rotateY(D.ry.v*V)),D.rx.propType&&(V.length?C.rotateX(D.rx.v*V[0]):C.rotateX(D.rx.v*V)),D.o.propType&&(V.length?O+=(D.o.v*V[0]-O)*V[0]:O+=(D.o.v*V-O)*V),t.strokeWidthAnim&&D.sw.propType&&(V.length?H+=D.sw.v*V[0]:H+=D.sw.v*V),t.strokeColorAnim&&D.sc.propType)for(j=0;j<3;j+=1)V.length?N[j]+=(D.sc.v[j]-N[j])*V[0]:N[j]+=(D.sc.v[j]-N[j])*V;if(t.fillColorAnim&&t.fc){if(D.fc.propType)for(j=0;j<3;j+=1)V.length?q[j]+=(D.fc.v[j]-q[j])*V[0]:q[j]+=(D.fc.v[j]-q[j])*V;D.fh.propType&&(q=V.length?addHueToRGB(q,D.fh.v*V[0]):addHueToRGB(q,D.fh.v*V)),D.fs.propType&&(q=V.length?addSaturationToRGB(q,D.fs.v*V[0]):addSaturationToRGB(q,D.fs.v*V)),D.fb.propType&&(q=V.length?addBrightnessToRGB(q,D.fb.v*V[0]):addBrightnessToRGB(q,D.fb.v*V))}}for(F=0;F<w;F+=1)(D=E[F].a).p.propType&&(V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars),this._hasMaskedPath?V.length?C.translate(0,D.p.v[1]*V[0],-D.p.v[2]*V[1]):C.translate(0,D.p.v[1]*V,-D.p.v[2]*V):V.length?C.translate(D.p.v[0]*V[0],D.p.v[1]*V[1],-D.p.v[2]*V[2]):C.translate(D.p.v[0]*V,D.p.v[1]*V,-D.p.v[2]*V));if(t.strokeWidthAnim&&(W=H<0?0:H),t.strokeColorAnim&&($="rgb("+Math.round(255*N[0])+","+Math.round(255*N[1])+","+Math.round(255*N[2])+")"),t.fillColorAnim&&t.fc&&(Y="rgb("+Math.round(255*q[0])+","+Math.round(255*q[1])+","+Math.round(255*q[2])+")"),this._hasMaskedPath){if(C.translate(0,-t.ls),C.translate(0,P[1]*B*.01+r,0),this._pathData.p.v){b=(h.point[1]-c.point[1])/(h.point[0]-c.point[0]);var ht=180*Math.atan(b)/Math.PI;h.point[0]<c.point[0]&&(ht+=180),C.rotate(-ht*Math.PI/180)}C.translate(G,z,0),o-=P[0]*T[s].an*.005,T[s+1]&&X!==T[s+1].ind&&(o+=T[s].an/2,o+=.001*t.tr*t.finalSize)}else{switch(C.translate(i,r,0),t.ps&&C.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:C.translate(T[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[T[s].line]),0,0);break;case 2:C.translate(T[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[T[s].line])/2,0,0)}C.translate(0,-t.ls),C.translate(L,0,0),C.translate(P[0]*T[s].an*.005,P[1]*B*.01,0),i+=T[s].l+.001*t.tr*t.finalSize}"html"===_?tt=C.toCSS():"svg"===_?tt=C.to2dCSS():et=[C.props[0],C.props[1],C.props[2],C.props[3],C.props[4],C.props[5],C.props[6],C.props[7],C.props[8],C.props[9],C.props[10],C.props[11],C.props[12],C.props[13],C.props[14],C.props[15]],J=O}A<=s?(I=new LetterProps(J,W,$,Y,tt,et),this.renderedLetters.push(I),A+=1,this.lettersChangedFlag=!0):(I=this.renderedLetters[s],this.lettersChangedFlag=I.update(J,W,$,Y,tt,et)||this.lettersChangedFlag)}}},TextAnimatorProperty.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},TextAnimatorProperty.prototype.mHelper=new Matrix,TextAnimatorProperty.prototype.defaultPropsArray=[],extendPrototype([DynamicPropertyContainer],TextAnimatorProperty),ITextElement.prototype.initElement=function(t,e,i){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,i),this.textProperty=new TextProperty(this,t.t,this.dynamicProperties),this.textAnimator=new TextAnimatorProperty(t.t,this.renderType,this),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},ITextElement.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},ITextElement.prototype.createPathShape=function(t,e){var i,r,s=e.length,a="";for(i=0;i<s;i+=1)"sh"===e[i].ty&&(r=e[i].ks.k,a+=buildShapeString(r,r.i.length,!0,t));return a},ITextElement.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},ITextElement.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},ITextElement.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},ITextElement.prototype.applyTextPropertiesToMatrix=function(t,e,i,r,s){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i])/2,0,0)}e.translate(r,s,0)},ITextElement.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},ITextElement.prototype.emptyProp=new LetterProps,ITextElement.prototype.destroy=function(){},ITextElement.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var emptyShapeData={shapes:[]};function SVGTextLottieElement(t,e,i){this.textSpans=[],this.renderType="svg",this.initElement(t,e,i)}function ISolidElement(t,e,i){this.initElement(t,e,i)}function NullElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initFrame(),this.initTransform(t,e,i),this.initHierarchy()}function SVGRendererBase(){}function ICompElement(){}function SVGCompElement(t,e,i){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function SVGRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=createNS("svg");var i="";if(e&&e.title){var r=createNS("title"),s=createElementID();r.setAttribute("id",s),r.textContent=e.title,this.svgElement.appendChild(r),i+=s}if(e&&e.description){var a=createNS("desc"),n=createElementID();a.setAttribute("id",n),a.textContent=e.description,this.svgElement.appendChild(a),i+=" "+n}i&&this.svgElement.setAttribute("aria-labelledby",i);var o=createNS("defs");this.svgElement.appendChild(o);var h=createNS("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}function ShapeTransformManager(){this.sequences={},this.sequenceList=[],this.transform_key_count=0}extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],SVGTextLottieElement),SVGTextLottieElement.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=createNS("text"))},SVGTextLottieElement.prototype.buildTextContents=function(t){for(var e=0,i=t.length,r=[],s="";e<i;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(r.push(s),s=""):s+=t[e],e+=1;return r.push(s),r},SVGTextLottieElement.prototype.buildShapeData=function(t,e){if(t.shapes&&t.shapes.length){var i=t.shapes[0];if(i.it){var r=i.it[i.it.length-1];r.s&&(r.s.k[0]=e,r.s.k[1]=e)}}return t},SVGTextLottieElement.prototype.buildNewText=function(){var t,e;this.addDynamicProperty(this);var i=this.textProperty.currentData;this.renderedLetters=createSizedArray(i?i.l.length:0),i.fc?this.layerElement.setAttribute("fill",this.buildColor(i.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),i.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(i.sc)),this.layerElement.setAttribute("stroke-width",i.sw)),this.layerElement.setAttribute("font-size",i.finalSize);var r=this.globalData.fontManager.getFontByName(i.f);if(r.fClass)this.layerElement.setAttribute("class",r.fClass);else{this.layerElement.setAttribute("font-family",r.fFamily);var s=i.fWeight,a=i.fStyle;this.layerElement.setAttribute("font-style",a),this.layerElement.setAttribute("font-weight",s)}this.layerElement.setAttribute("aria-label",i.t);var n,o=i.l||[],h=!!this.globalData.fontManager.chars;e=o.length;var l=this.mHelper,p=this.data.singleShape,f=0,m=0,c=!0,d=.001*i.tr*i.finalSize;if(!p||h||i.sz){var u,y=this.textSpans.length;for(t=0;t<e;t+=1){if(this.textSpans[t]||(this.textSpans[t]={span:null,childSpan:null,glyph:null}),!h||!p||0===t){if(n=y>t?this.textSpans[t].span:createNS(h?"g":"text"),y<=t){if(n.setAttribute("stroke-linecap","butt"),n.setAttribute("stroke-linejoin","round"),n.setAttribute("stroke-miterlimit","4"),this.textSpans[t].span=n,h){var g=createNS("g");n.appendChild(g),this.textSpans[t].childSpan=g}this.textSpans[t].span=n,this.layerElement.appendChild(n)}n.style.display="inherit"}if(l.reset(),p&&(o[t].n&&(f=-d,m+=i.yOffset,m+=c?1:0,c=!1),this.applyTextPropertiesToMatrix(i,l,o[t].line,f,m),f+=o[t].l||0,f+=d),h){var v;if(1===(u=this.globalData.fontManager.getCharData(i.finalText[t],r.fStyle,this.globalData.fontManager.getFontByName(i.f).fFamily)).t)v=new SVGCompElement(u.data,this.globalData,this);else{var b=emptyShapeData;u.data&&u.data.shapes&&(b=this.buildShapeData(u.data,i.finalSize)),v=new SVGShapeElement(b,this.globalData,this)}if(this.textSpans[t].glyph){var x=this.textSpans[t].glyph;this.textSpans[t].childSpan.removeChild(x.layerElement),x.destroy()}this.textSpans[t].glyph=v,v._debug=!0,v.prepareFrame(0),v.renderFrame(),this.textSpans[t].childSpan.appendChild(v.layerElement),1===u.t&&this.textSpans[t].childSpan.setAttribute("transform","scale("+i.finalSize/100+","+i.finalSize/100+")")}else p&&n.setAttribute("transform","translate("+l.props[12]+","+l.props[13]+")"),n.textContent=o[t].val,n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}p&&n&&n.setAttribute("d","")}else{var P=this.textContainer,E="start";switch(i.j){case 1:E="end";break;case 2:E="middle";break;default:E="start"}P.setAttribute("text-anchor",E),P.setAttribute("letter-spacing",d);var S=this.buildTextContents(i.finalText);for(e=S.length,m=i.ps?i.ps[1]+i.ascent:0,t=0;t<e;t+=1)(n=this.textSpans[t].span||createNS("tspan")).textContent=S[t],n.setAttribute("x",0),n.setAttribute("y",m),n.style.display="inherit",P.appendChild(n),this.textSpans[t]||(this.textSpans[t]={span:null,glyph:null}),this.textSpans[t].span=n,m+=i.finalLineHeight;this.layerElement.appendChild(P)}for(;t<this.textSpans.length;)this.textSpans[t].span.style.display="none",t+=1;this._sizeChanged=!0},SVGTextLottieElement.prototype.sourceRectAtTime=function(){if(this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged){this._sizeChanged=!1;var t=this.layerElement.getBBox();this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}}return this.bbox},SVGTextLottieElement.prototype.getValue=function(){var t,e,i=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<i;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf&&(this._mdf=!0))},SVGTextLottieElement.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){var t,e;this._sizeChanged=!0;var i,r,s,a=this.textAnimator.renderedLetters,n=this.textProperty.currentData.l;for(e=n.length,t=0;t<e;t+=1)n[t].n||(i=a[t],r=this.textSpans[t].span,(s=this.textSpans[t].glyph)&&s.renderFrame(),i._mdf.m&&r.setAttribute("transform",i.m),i._mdf.o&&r.setAttribute("opacity",i.o),i._mdf.sw&&r.setAttribute("stroke-width",i.sw),i._mdf.sc&&r.setAttribute("stroke",i.sc),i._mdf.fc&&r.setAttribute("fill",i.fc))}},extendPrototype([IImageElement],ISolidElement),ISolidElement.prototype.createContent=function(){var t=createNS("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},NullElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},NullElement.prototype.renderFrame=function(){},NullElement.prototype.getBaseElement=function(){return null},NullElement.prototype.destroy=function(){},NullElement.prototype.sourceRectAtTime=function(){},NullElement.prototype.hide=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement],NullElement),extendPrototype([BaseRenderer],SVGRendererBase),SVGRendererBase.prototype.createNull=function(t){return new NullElement(t,this.globalData,this)},SVGRendererBase.prototype.createShape=function(t){return new SVGShapeElement(t,this.globalData,this)},SVGRendererBase.prototype.createText=function(t){return new SVGTextLottieElement(t,this.globalData,this)},SVGRendererBase.prototype.createImage=function(t){return new IImageElement(t,this.globalData,this)},SVGRendererBase.prototype.createSolid=function(t){return new ISolidElement(t,this.globalData,this)},SVGRendererBase.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var i=createNS("clipPath"),r=createNS("rect");r.setAttribute("width",t.w),r.setAttribute("height",t.h),r.setAttribute("x",0),r.setAttribute("y",0);var s=createElementID();i.setAttribute("id",s),i.appendChild(r),this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),e.appendChild(i),this.layers=t.layers,this.elements=createSizedArray(t.layers.length)},SVGRendererBase.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},SVGRendererBase.prototype.updateContainerSize=function(){},SVGRendererBase.prototype.findIndexByInd=function(t){var e=0,i=this.layers.length;for(e=0;e<i;e+=1)if(this.layers[e].ind===t)return e;return-1},SVGRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){e[t]=!0;var i=this.createItem(this.layers[t]);if(e[t]=i,getExpressionsPlugin()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(i),i.initExpressions()),this.appendElementInPos(i,t),this.layers[t].tt){var r="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1;if(-1===r)return;if(this.elements[r]&&!0!==this.elements[r]){var s=e[r].getMatte(this.layers[t].tt);i.setMatte(s)}else this.buildItem(r),this.addPendingElement(i)}}},SVGRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,i=this.elements.length;e<i;){if(this.elements[e]===t){var r="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,s=this.elements[r].getMatte(this.layers[e].tt);t.setMatte(s);break}e+=1}}},SVGRendererBase.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){var e;null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var i=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=i-1;e>=0;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<i;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},SVGRendererBase.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){for(var r,s=0;s<e;)this.elements[s]&&!0!==this.elements[s]&&this.elements[s].getBaseElement()&&(r=this.elements[s].getBaseElement()),s+=1;r?this.layerElement.insertBefore(i,r):this.layerElement.appendChild(i)}},SVGRendererBase.prototype.hide=function(){this.layerElement.style.display="none"},SVGRendererBase.prototype.show=function(){this.layerElement.style.display="block"},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement,RenderableDOMElement],ICompElement),ICompElement.prototype.initElement=function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},ICompElement.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var i,r=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),i=r-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&(this.elements[i].prepareFrame(this.renderedFrame-this.layers[i].st),this.elements[i]._mdf&&(this._mdf=!0))}},ICompElement.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},ICompElement.prototype.setElements=function(t){this.elements=t},ICompElement.prototype.getElements=function(){return this.elements},ICompElement.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},ICompElement.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},extendPrototype([SVGRendererBase,ICompElement,SVGBaseElement],SVGCompElement),SVGCompElement.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},extendPrototype([SVGRendererBase],SVGRenderer),SVGRenderer.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},ShapeTransformManager.prototype={addTransformSequence:function(t){var e,i=t.length,r="_";for(e=0;e<i;e+=1)r+=t[e].transform.key+"_";var s=this.sequences[r];return s||(s={transforms:[].concat(t),finalTransform:new Matrix,_mdf:!1},this.sequences[r]=s,this.sequenceList.push(s)),s},processSequence:function(t,e){for(var i=0,r=t.transforms.length,s=e;i<r&&!e;){if(t.transforms[i].transform.mProps._mdf){s=!0;break}i+=1}if(s)for(t.finalTransform.reset(),i=r-1;i>=0;i-=1)t.finalTransform.multiply(t.transforms[i].transform.mProps.v);t._mdf=s},processSequences:function(t){var e,i=this.sequenceList.length;for(e=0;e<i;e+=1)this.processSequence(this.sequenceList[e],t)},getNewKey:function(){return this.transform_key_count+=1,"_"+this.transform_key_count}};var lumaLoader=function(){var t="__lottie_element_luma_buffer",e=null,i=null,r=null;function s(){var s,a,n;e||(s=createNS("svg"),a=createNS("filter"),n=createNS("feColorMatrix"),a.setAttribute("id",t),n.setAttribute("type","matrix"),n.setAttribute("color-interpolation-filters","sRGB"),n.setAttribute("values","0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0"),a.appendChild(n),s.appendChild(a),s.setAttribute("id",t+"_svg"),featureSupport.svgLumaHidden&&(s.style.display="none"),r=s,document.body.appendChild(r),e=createTag("canvas"),(i=e.getContext("2d")).filter="url(#"+t+")",i.fillStyle="rgba(0,0,0,0)",i.fillRect(0,0,1,1))}return{load:s,get:function(r){return e||s(),e.width=r.width,e.height=r.height,i.filter="url(#"+t+")",e}}};function createCanvas(t,e){if(featureSupport.offscreenCanvas)return new OffscreenCanvas(t,e);var i=createTag("canvas");return i.width=t,i.height=e,i}var assetLoader={loadLumaCanvas:lumaLoader.load,getLumaCanvas:lumaLoader.get,createCanvas:createCanvas},registeredEffects={};function CVEffects(t){var e,i,r=t.data.ef?t.data.ef.length:0;for(this.filters=[],e=0;e<r;e+=1){i=null;var s=t.data.ef[e].ty;if(registeredEffects[s])i=new(0,registeredEffects[s].effect)(t.effectsManager.effectElements[e],t);i&&this.filters.push(i)}this.filters.length&&t.addRenderableComponent(this)}function registerEffect(t,e){registeredEffects[t]={effect:e}}function CVMaskElement(t,e){var i;this.data=t,this.element=e,this.masksProperties=this.data.masksProperties||[],this.viewData=createSizedArray(this.masksProperties.length);var r=this.masksProperties.length,s=!1;for(i=0;i<r;i+=1)"n"!==this.masksProperties[i].mode&&(s=!0),this.viewData[i]=ShapePropertyFactory.getShapeProp(this.element,this.masksProperties[i],3);this.hasMasks=s,s&&this.element.addRenderableComponent(this)}function CVBaseElement(){}CVEffects.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},CVEffects.prototype.getEffects=function(t){var e,i=this.filters.length,r=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&r.push(this.filters[e]);return r},CVMaskElement.prototype.renderFrame=function(){if(this.hasMasks){var t,e,i,r,s=this.element.finalTransform.mat,a=this.element.canvasContext,n=this.masksProperties.length;for(a.beginPath(),t=0;t<n;t+=1)if("n"!==this.masksProperties[t].mode){var o;this.masksProperties[t].inv&&(a.moveTo(0,0),a.lineTo(this.element.globalData.compSize.w,0),a.lineTo(this.element.globalData.compSize.w,this.element.globalData.compSize.h),a.lineTo(0,this.element.globalData.compSize.h),a.lineTo(0,0)),r=this.viewData[t].v,e=s.applyToPointArray(r.v[0][0],r.v[0][1],0),a.moveTo(e[0],e[1]);var h=r._length;for(o=1;o<h;o+=1)i=s.applyToTriplePoints(r.o[o-1],r.i[o],r.v[o]),a.bezierCurveTo(i[0],i[1],i[2],i[3],i[4],i[5]);i=s.applyToTriplePoints(r.o[o-1],r.i[0],r.v[0]),a.bezierCurveTo(i[0],i[1],i[2],i[3],i[4],i[5])}this.element.globalData.renderer.save(!0),a.clip()}},CVMaskElement.prototype.getMaskProperty=MaskElement.prototype.getMaskProperty,CVMaskElement.prototype.destroy=function(){this.element=null};var operationsMap={1:"source-in",2:"source-out",3:"source-in",4:"source-out"};function CVShapeData(t,e,i,r){this.styledShapes=[],this.tr=[0,0,0,0,0,0];var s,a=4;"rc"===e.ty?a=5:"el"===e.ty?a=6:"sr"===e.ty&&(a=7),this.sh=ShapePropertyFactory.getShapeProp(t,e,a,t);var n,o=i.length;for(s=0;s<o;s+=1)i[s].closed||(n={transforms:r.addTransformSequence(i[s].transforms),trNodes:[]},this.styledShapes.push(n),i[s].elements.push(n))}function CVShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.itemsData=[],this.prevViewData=[],this.shapeModifiers=[],this.processedElements=[],this.transformsManager=new ShapeTransformManager,this.initElement(t,e,i)}function CVTextElement(t,e,i){this.textSpans=[],this.yOffset=0,this.fillColorAnim=!1,this.strokeColorAnim=!1,this.strokeWidthAnim=!1,this.stroke=!1,this.fill=!1,this.justifyOffset=0,this.currentRender=null,this.renderType="canvas",this.values={fill:"rgba(0,0,0,0)",stroke:"rgba(0,0,0,0)",sWidth:0,fValue:""},this.initElement(t,e,i)}function CVImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.img=e.imageLoader.getAsset(this.assetData),this.initElement(t,e,i)}function CVSolidElement(t,e,i){this.initElement(t,e,i)}function CanvasRendererBase(){}function CanvasContext(){this.opacity=-1,this.transform=createTypedArray("float32",16),this.fillStyle="",this.strokeStyle="",this.lineWidth="",this.lineCap="",this.lineJoin="",this.miterLimit="",this.id=Math.random()}function CVContextData(){var t;this.stack=[],this.cArrPos=0,this.cTr=new Matrix;for(t=0;t<15;t+=1){var e=new CanvasContext;this.stack[t]=e}this._length=15,this.nativeContext=null,this.transformMat=new Matrix,this.currentOpacity=1,this.currentFillStyle="",this.appliedFillStyle="",this.currentStrokeStyle="",this.appliedStrokeStyle="",this.currentLineWidth="",this.appliedLineWidth="",this.currentLineCap="",this.appliedLineCap="",this.currentLineJoin="",this.appliedLineJoin="",this.appliedMiterLimit="",this.currentMiterLimit=""}function CVCompElement(t,e,i){this.completeLayers=!1,this.layers=t.layers,this.pendingElements=[],this.elements=createSizedArray(this.layers.length),this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function CanvasRenderer(t,e){this.animationItem=t,this.renderConfig={clearCanvas:!e||void 0===e.clearCanvas||e.clearCanvas,context:e&&e.context||null,progressiveLoad:e&&e.progressiveLoad||!1,preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",className:e&&e.className||"",id:e&&e.id||"",runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.renderConfig.dpr=e&&e.dpr||1,this.animationItem.wrapper&&(this.renderConfig.dpr=e&&e.dpr||window.devicePixelRatio||1),this.renderedFrame=-1,this.globalData={frameNum:-1,_mdf:!1,renderConfig:this.renderConfig,currentGlobalAlpha:-1},this.contextData=new CVContextData,this.elements=[],this.pendingElements=[],this.transformMat=new Matrix,this.completeLayers=!1,this.rendererType="canvas",this.renderConfig.clearCanvas&&(this.ctxTransform=this.contextData.transform.bind(this.contextData),this.ctxOpacity=this.contextData.opacity.bind(this.contextData),this.ctxFillStyle=this.contextData.fillStyle.bind(this.contextData),this.ctxStrokeStyle=this.contextData.strokeStyle.bind(this.contextData),this.ctxLineWidth=this.contextData.lineWidth.bind(this.contextData),this.ctxLineCap=this.contextData.lineCap.bind(this.contextData),this.ctxLineJoin=this.contextData.lineJoin.bind(this.contextData),this.ctxMiterLimit=this.contextData.miterLimit.bind(this.contextData),this.ctxFill=this.contextData.fill.bind(this.contextData),this.ctxFillRect=this.contextData.fillRect.bind(this.contextData),this.ctxStroke=this.contextData.stroke.bind(this.contextData),this.save=this.contextData.save.bind(this.contextData))}function HBaseElement(){}function HSolidElement(t,e,i){this.initElement(t,e,i)}function HShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.shapesContainer=createNS("g"),this.initElement(t,e,i),this.prevViewData=[],this.currentBBox={x:999999,y:-999999,h:0,w:0}}function HTextElement(t,e,i){this.textSpans=[],this.textPaths=[],this.currentBBox={x:999999,y:-999999,h:0,w:0},this.renderType="svg",this.isMasked=!1,this.initElement(t,e,i)}function HCameraElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initHierarchy();var r=PropertyFactory.getProp;if(this.pe=r(this,t.pe,0,0,this),t.ks.p.s?(this.px=r(this,t.ks.p.x,1,0,this),this.py=r(this,t.ks.p.y,1,0,this),this.pz=r(this,t.ks.p.z,1,0,this)):this.p=r(this,t.ks.p,1,0,this),t.ks.a&&(this.a=r(this,t.ks.a,1,0,this)),t.ks.or.k.length&&t.ks.or.k[0].to){var s,a=t.ks.or.k.length;for(s=0;s<a;s+=1)t.ks.or.k[s].to=null,t.ks.or.k[s].ti=null}this.or=r(this,t.ks.or,1,degToRads,this),this.or.sh=!0,this.rx=r(this,t.ks.rx,0,degToRads,this),this.ry=r(this,t.ks.ry,0,degToRads,this),this.rz=r(this,t.ks.rz,0,degToRads,this),this.mat=new Matrix,this._prevMat=new Matrix,this._isFirstFrame=!0,this.finalTransform={mProp:this}}function HImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.initElement(t,e,i)}function HybridRendererBase(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"}},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}function HCompElement(t,e,i){this.layers=t.layers,this.supports3d=!t.hasMask,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function HybridRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"},runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}CVBaseElement.prototype={createElements:function(){},initRendererElement:function(){},createContainerElements:function(){if(this.data.tt>=1){this.buffers=[];var t=this.globalData.canvasContext,e=assetLoader.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(e);var i=assetLoader.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(i),this.data.tt>=3&&!document._isProxy&&assetLoader.loadLumaCanvas()}this.canvasContext=this.globalData.canvasContext,this.transformCanvas=this.globalData.transformCanvas,this.renderableEffectsManager=new CVEffects(this),this.searchEffectTransforms()},createContent:function(){},setBlendMode:function(){var t=this.globalData;if(t.blendMode!==this.data.bm){t.blendMode=this.data.bm;var e=getBlendMode(this.data.bm);t.canvasContext.globalCompositeOperation=e}},createRenderableComponents:function(){this.maskManager=new CVMaskElement(this.data,this),this.transformEffects=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT)},hideElement:function(){this.hidden||this.isInRange&&!this.isTransparent||(this.hidden=!0)},showElement:function(){this.isInRange&&!this.isTransparent&&(this.hidden=!1,this._isFirstFrame=!0,this.maskManager._isFirstFrame=!0)},clearCanvas:function(t){t.clearRect(this.transformCanvas.tx,this.transformCanvas.ty,this.transformCanvas.w*this.transformCanvas.sx,this.transformCanvas.h*this.transformCanvas.sy)},prepareLayer:function(){if(this.data.tt>=1){var t=this.buffers[0].getContext("2d");this.clearCanvas(t),t.drawImage(this.canvasContext.canvas,0,0),this.currentTransform=this.canvasContext.getTransform(),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform)}},exitLayer:function(){if(this.data.tt>=1){var t=this.buffers[1],e=t.getContext("2d");if(this.clearCanvas(e),e.drawImage(this.canvasContext.canvas,0,0),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform),this.comp.getElementById("tp"in this.data?this.data.tp:this.data.ind-1).renderFrame(!0),this.canvasContext.setTransform(1,0,0,1,0,0),this.data.tt>=3&&!document._isProxy){var i=assetLoader.getLumaCanvas(this.canvasContext.canvas);i.getContext("2d").drawImage(this.canvasContext.canvas,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.drawImage(i,0,0)}this.canvasContext.globalCompositeOperation=operationsMap[this.data.tt],this.canvasContext.drawImage(t,0,0),this.canvasContext.globalCompositeOperation="destination-over",this.canvasContext.drawImage(this.buffers[0],0,0),this.canvasContext.setTransform(this.currentTransform),this.canvasContext.globalCompositeOperation="source-over"}},renderFrame:function(t){if(!this.hidden&&!this.data.hd&&(1!==this.data.td||t)){this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.setBlendMode();var e=0===this.data.ty;this.prepareLayer(),this.globalData.renderer.save(e),this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props),this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity),this.renderInnerContent(),this.globalData.renderer.restore(e),this.exitLayer(),this.maskManager.hasMasks&&this.globalData.renderer.restore(!0),this._isFirstFrame&&(this._isFirstFrame=!1)}},destroy:function(){this.canvasContext=null,this.data=null,this.globalData=null,this.maskManager.destroy()},mHelper:new Matrix},CVBaseElement.prototype.hide=CVBaseElement.prototype.hideElement,CVBaseElement.prototype.show=CVBaseElement.prototype.showElement,CVShapeData.prototype.setAsAnimated=SVGShapeData.prototype.setAsAnimated,extendPrototype([BaseElement,TransformElement,CVBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableElement],CVShapeElement),CVShapeElement.prototype.initElement=RenderableDOMElement.prototype.initElement,CVShapeElement.prototype.transformHelper={opacity:1,_opMdf:!1},CVShapeElement.prototype.dashResetter=[],CVShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[])},CVShapeElement.prototype.createStyleElement=function(t,e){var i={data:t,type:t.ty,preTransforms:this.transformsManager.addTransformSequence(e),transforms:[],elements:[],closed:!0===t.hd},r={};if("fl"===t.ty||"st"===t.ty?(r.c=PropertyFactory.getProp(this,t.c,1,255,this),r.c.k||(i.co="rgb("+bmFloor(r.c.v[0])+","+bmFloor(r.c.v[1])+","+bmFloor(r.c.v[2])+")")):"gf"!==t.ty&&"gs"!==t.ty||(r.s=PropertyFactory.getProp(this,t.s,1,null,this),r.e=PropertyFactory.getProp(this,t.e,1,null,this),r.h=PropertyFactory.getProp(this,t.h||{k:0},0,.01,this),r.a=PropertyFactory.getProp(this,t.a||{k:0},0,degToRads,this),r.g=new GradientProperty(this,t.g,this)),r.o=PropertyFactory.getProp(this,t.o,0,.01,this),"st"===t.ty||"gs"===t.ty){if(i.lc=lineCapEnum[t.lc||2],i.lj=lineJoinEnum[t.lj||2],1==t.lj&&(i.ml=t.ml),r.w=PropertyFactory.getProp(this,t.w,0,null,this),r.w.k||(i.wi=r.w.v),t.d){var s=new DashProperty(this,t.d,"canvas",this);r.d=s,r.d.k||(i.da=r.d.dashArray,i.do=r.d.dashoffset[0])}}else i.r=2===t.r?"evenodd":"nonzero";return this.stylesList.push(i),r.style=i,r},CVShapeElement.prototype.createGroupElement=function(){return{it:[],prevViewData:[]}},CVShapeElement.prototype.createTransformElement=function(t){return{transform:{opacity:1,_opMdf:!1,key:this.transformsManager.getNewKey(),op:PropertyFactory.getProp(this,t.o,0,.01,this),mProps:TransformPropertyFactory.getTransformProperty(this,t,this)}}},CVShapeElement.prototype.createShapeElement=function(t){var e=new CVShapeData(this,t,this.stylesList,this.transformsManager);return this.shapes.push(e),this.addShapeToModifiers(e),e},CVShapeElement.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[]),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame)},CVShapeElement.prototype.addTransformToStyleList=function(t){var e,i=this.stylesList.length;for(e=0;e<i;e+=1)this.stylesList[e].closed||this.stylesList[e].transforms.push(t)},CVShapeElement.prototype.removeTransformFromStyleList=function(){var t,e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].closed||this.stylesList[t].transforms.pop()},CVShapeElement.prototype.closeStyles=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].closed=!0},CVShapeElement.prototype.searchShapes=function(t,e,i,r,s){var a,n,o,h,l,p,f=t.length-1,m=[],c=[],d=[].concat(s);for(a=f;a>=0;a-=1){if((h=this.searchProcessedElement(t[a]))?e[a]=i[h-1]:t[a]._shouldRender=r,"fl"===t[a].ty||"st"===t[a].ty||"gf"===t[a].ty||"gs"===t[a].ty)h?e[a].style.closed=!1:e[a]=this.createStyleElement(t[a],d),m.push(e[a].style);else if("gr"===t[a].ty){if(h)for(o=e[a].it.length,n=0;n<o;n+=1)e[a].prevViewData[n]=e[a].it[n];else e[a]=this.createGroupElement(t[a]);this.searchShapes(t[a].it,e[a].it,e[a].prevViewData,r,d)}else"tr"===t[a].ty?(h||(p=this.createTransformElement(t[a]),e[a]=p),d.push(e[a]),this.addTransformToStyleList(e[a])):"sh"===t[a].ty||"rc"===t[a].ty||"el"===t[a].ty||"sr"===t[a].ty?h||(e[a]=this.createShapeElement(t[a])):"tm"===t[a].ty||"rd"===t[a].ty||"pb"===t[a].ty||"zz"===t[a].ty||"op"===t[a].ty?(h?(l=e[a]).closed=!1:((l=ShapeModifiers.getModifier(t[a].ty)).init(this,t[a]),e[a]=l,this.shapeModifiers.push(l)),c.push(l)):"rp"===t[a].ty&&(h?(l=e[a]).closed=!0:(l=ShapeModifiers.getModifier(t[a].ty),e[a]=l,l.init(this,t,a,e),this.shapeModifiers.push(l),r=!1),c.push(l));this.addProcessedElement(t[a],a+1)}for(this.removeTransformFromStyleList(),this.closeStyles(m),f=c.length,a=0;a<f;a+=1)c[a].closed=!0},CVShapeElement.prototype.renderInnerContent=function(){this.transformHelper.opacity=1,this.transformHelper._opMdf=!1,this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame),this.renderShape(this.transformHelper,this.shapesData,this.itemsData,!0)},CVShapeElement.prototype.renderShapeTransform=function(t,e){(t._opMdf||e.op._mdf||this._isFirstFrame)&&(e.opacity=t.opacity,e.opacity*=e.op.v,e._opMdf=!0)},CVShapeElement.prototype.drawLayer=function(){var t,e,i,r,s,a,n,o,h,l=this.stylesList.length,p=this.globalData.renderer,f=this.globalData.canvasContext;for(t=0;t<l;t+=1)if(("st"!==(o=(h=this.stylesList[t]).type)&&"gs"!==o||0!==h.wi)&&h.data._shouldRender&&0!==h.coOp&&0!==this.globalData.currentGlobalAlpha){for(p.save(),a=h.elements,"st"===o||"gs"===o?(p.ctxStrokeStyle("st"===o?h.co:h.grd),p.ctxLineWidth(h.wi),p.ctxLineCap(h.lc),p.ctxLineJoin(h.lj),p.ctxMiterLimit(h.ml||0)):p.ctxFillStyle("fl"===o?h.co:h.grd),p.ctxOpacity(h.coOp),"st"!==o&&"gs"!==o&&f.beginPath(),p.ctxTransform(h.preTransforms.finalTransform.props),i=a.length,e=0;e<i;e+=1){for("st"!==o&&"gs"!==o||(f.beginPath(),h.da&&(f.setLineDash(h.da),f.lineDashOffset=h.do)),s=(n=a[e].trNodes).length,r=0;r<s;r+=1)"m"===n[r].t?f.moveTo(n[r].p[0],n[r].p[1]):"c"===n[r].t?f.bezierCurveTo(n[r].pts[0],n[r].pts[1],n[r].pts[2],n[r].pts[3],n[r].pts[4],n[r].pts[5]):f.closePath();"st"!==o&&"gs"!==o||(p.ctxStroke(),h.da&&f.setLineDash(this.dashResetter))}"st"!==o&&"gs"!==o&&this.globalData.renderer.ctxFill(h.r),p.restore()}},CVShapeElement.prototype.renderShape=function(t,e,i,r){var s,a;for(a=t,s=e.length-1;s>=0;s-=1)"tr"===e[s].ty?(a=i[s].transform,this.renderShapeTransform(t,a)):"sh"===e[s].ty||"el"===e[s].ty||"rc"===e[s].ty||"sr"===e[s].ty?this.renderPath(e[s],i[s]):"fl"===e[s].ty?this.renderFill(e[s],i[s],a):"st"===e[s].ty?this.renderStroke(e[s],i[s],a):"gf"===e[s].ty||"gs"===e[s].ty?this.renderGradientFill(e[s],i[s],a):"gr"===e[s].ty?this.renderShape(a,e[s].it,i[s].it):e[s].ty;r&&this.drawLayer()},CVShapeElement.prototype.renderStyledShape=function(t,e){if(this._isFirstFrame||e._mdf||t.transforms._mdf){var i,r,s,a=t.trNodes,n=e.paths,o=n._length;a.length=0;var h=t.transforms.finalTransform;for(s=0;s<o;s+=1){var l=n.shapes[s];if(l&&l.v){for(r=l._length,i=1;i<r;i+=1)1===i&&a.push({t:"m",p:h.applyToPointArray(l.v[0][0],l.v[0][1],0)}),a.push({t:"c",pts:h.applyToTriplePoints(l.o[i-1],l.i[i],l.v[i])});1===r&&a.push({t:"m",p:h.applyToPointArray(l.v[0][0],l.v[0][1],0)}),l.c&&r&&(a.push({t:"c",pts:h.applyToTriplePoints(l.o[i-1],l.i[0],l.v[0])}),a.push({t:"z"}))}}t.trNodes=a}},CVShapeElement.prototype.renderPath=function(t,e){if(!0!==t.hd&&t._shouldRender){var i,r=e.styledShapes.length;for(i=0;i<r;i+=1)this.renderStyledShape(e.styledShapes[i],e.sh)}},CVShapeElement.prototype.renderFill=function(t,e,i){var r=e.style;(e.c._mdf||this._isFirstFrame)&&(r.co="rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i._opMdf||this._isFirstFrame)&&(r.coOp=e.o.v*i.opacity)},CVShapeElement.prototype.renderGradientFill=function(t,e,i){var r,s=e.style;if(!s.grd||e.g._mdf||e.s._mdf||e.e._mdf||1!==t.t&&(e.h._mdf||e.a._mdf)){var a,n=this.globalData.canvasContext,o=e.s.v,h=e.e.v;if(1===t.t)r=n.createLinearGradient(o[0],o[1],h[0],h[1]);else{var l=Math.sqrt(Math.pow(o[0]-h[0],2)+Math.pow(o[1]-h[1],2)),p=Math.atan2(h[1]-o[1],h[0]-o[0]),f=e.h.v;f>=1?f=.99:f<=-1&&(f=-.99);var m=l*f,c=Math.cos(p+e.a.v)*m+o[0],d=Math.sin(p+e.a.v)*m+o[1];r=n.createRadialGradient(c,d,0,o[0],o[1],l)}var u=t.g.p,y=e.g.c,g=1;for(a=0;a<u;a+=1)e.g._hasOpacity&&e.g._collapsable&&(g=e.g.o[2*a+1]),r.addColorStop(y[4*a]/100,"rgba("+y[4*a+1]+","+y[4*a+2]+","+y[4*a+3]+","+g+")");s.grd=r}s.coOp=e.o.v*i.opacity},CVShapeElement.prototype.renderStroke=function(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||this._isFirstFrame)&&(r.da=s.dashArray,r.do=s.dashoffset[0]),(e.c._mdf||this._isFirstFrame)&&(r.co="rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i._opMdf||this._isFirstFrame)&&(r.coOp=e.o.v*i.opacity),(e.w._mdf||this._isFirstFrame)&&(r.wi=e.w.v)},CVShapeElement.prototype.destroy=function(){this.shapesData=null,this.globalData=null,this.canvasContext=null,this.stylesList.length=0,this.itemsData.length=0},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement,ITextElement],CVTextElement),CVTextElement.prototype.tHelper=createTag("canvas").getContext("2d"),CVTextElement.prototype.buildNewText=function(){var t=this.textProperty.currentData;this.renderedLetters=createSizedArray(t.l?t.l.length:0);var e=!1;t.fc?(e=!0,this.values.fill=this.buildColor(t.fc)):this.values.fill="rgba(0,0,0,0)",this.fill=e;var i=!1;t.sc&&(i=!0,this.values.stroke=this.buildColor(t.sc),this.values.sWidth=t.sw);var r,s,a,n,o,h,l,p,f,m,c,d,u=this.globalData.fontManager.getFontByName(t.f),y=t.l,g=this.mHelper;this.stroke=i,this.values.fValue=t.finalSize+"px "+this.globalData.fontManager.getFontByName(t.f).fFamily,s=t.finalText.length;var v=this.data.singleShape,b=.001*t.tr*t.finalSize,x=0,P=0,E=!0,S=0;for(r=0;r<s;r+=1){n=(a=this.globalData.fontManager.getCharData(t.finalText[r],u.fStyle,this.globalData.fontManager.getFontByName(t.f).fFamily))&&a.data||{},g.reset(),v&&y[r].n&&(x=-b,P+=t.yOffset,P+=E?1:0,E=!1),f=(l=n.shapes?n.shapes[0].it:[]).length,g.scale(t.finalSize/100,t.finalSize/100),v&&this.applyTextPropertiesToMatrix(t,g,y[r].line,x,P),c=createSizedArray(f-1);var C=0;for(p=0;p<f;p+=1)if("sh"===l[p].ty){for(h=l[p].ks.k.i.length,m=l[p].ks.k,d=[],o=1;o<h;o+=1)1===o&&d.push(g.applyToX(m.v[0][0],m.v[0][1],0),g.applyToY(m.v[0][0],m.v[0][1],0)),d.push(g.applyToX(m.o[o-1][0],m.o[o-1][1],0),g.applyToY(m.o[o-1][0],m.o[o-1][1],0),g.applyToX(m.i[o][0],m.i[o][1],0),g.applyToY(m.i[o][0],m.i[o][1],0),g.applyToX(m.v[o][0],m.v[o][1],0),g.applyToY(m.v[o][0],m.v[o][1],0));d.push(g.applyToX(m.o[o-1][0],m.o[o-1][1],0),g.applyToY(m.o[o-1][0],m.o[o-1][1],0),g.applyToX(m.i[0][0],m.i[0][1],0),g.applyToY(m.i[0][0],m.i[0][1],0),g.applyToX(m.v[0][0],m.v[0][1],0),g.applyToY(m.v[0][0],m.v[0][1],0)),c[C]=d,C+=1}v&&(x+=y[r].l,x+=b),this.textSpans[S]?this.textSpans[S].elem=c:this.textSpans[S]={elem:c},S+=1}},CVTextElement.prototype.renderInnerContent=function(){var t,e,i,r,s,a;this.validateText(),this.canvasContext.font=this.values.fValue,this.globalData.renderer.ctxLineCap("butt"),this.globalData.renderer.ctxLineJoin("miter"),this.globalData.renderer.ctxMiterLimit(4),this.data.singleShape||this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag);var n,o=this.textAnimator.renderedLetters,h=this.textProperty.currentData.l;e=h.length;var l,p,f=null,m=null,c=null,d=this.globalData.renderer;for(t=0;t<e;t+=1)if(!h[t].n){if((n=o[t])&&(d.save(),d.ctxTransform(n.p),d.ctxOpacity(n.o)),this.fill){for(n&&n.fc?f!==n.fc&&(d.ctxFillStyle(n.fc),f=n.fc):f!==this.values.fill&&(f=this.values.fill,d.ctxFillStyle(this.values.fill)),r=(l=this.textSpans[t].elem).length,this.globalData.canvasContext.beginPath(),i=0;i<r;i+=1)for(a=(p=l[i]).length,this.globalData.canvasContext.moveTo(p[0],p[1]),s=2;s<a;s+=6)this.globalData.canvasContext.bezierCurveTo(p[s],p[s+1],p[s+2],p[s+3],p[s+4],p[s+5]);this.globalData.canvasContext.closePath(),d.ctxFill()}if(this.stroke){for(n&&n.sw?c!==n.sw&&(c=n.sw,d.ctxLineWidth(n.sw)):c!==this.values.sWidth&&(c=this.values.sWidth,d.ctxLineWidth(this.values.sWidth)),n&&n.sc?m!==n.sc&&(m=n.sc,d.ctxStrokeStyle(n.sc)):m!==this.values.stroke&&(m=this.values.stroke,d.ctxStrokeStyle(this.values.stroke)),r=(l=this.textSpans[t].elem).length,this.globalData.canvasContext.beginPath(),i=0;i<r;i+=1)for(a=(p=l[i]).length,this.globalData.canvasContext.moveTo(p[0],p[1]),s=2;s<a;s+=6)this.globalData.canvasContext.bezierCurveTo(p[s],p[s+1],p[s+2],p[s+3],p[s+4],p[s+5]);this.globalData.canvasContext.closePath(),d.ctxStroke()}n&&this.globalData.renderer.restore()}},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVImageElement),CVImageElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVImageElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVImageElement.prototype.createContent=function(){if(this.img.width&&(this.assetData.w!==this.img.width||this.assetData.h!==this.img.height)){var t=createTag("canvas");t.width=this.assetData.w,t.height=this.assetData.h;var e,i,r=t.getContext("2d"),s=this.img.width,a=this.img.height,n=s/a,o=this.assetData.w/this.assetData.h,h=this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio;n>o&&"xMidYMid slice"===h||n<o&&"xMidYMid slice"!==h?e=(i=a)*o:i=(e=s)/o,r.drawImage(this.img,(s-e)/2,(a-i)/2,e,i,0,0,this.assetData.w,this.assetData.h),this.img=t}},CVImageElement.prototype.renderInnerContent=function(){this.canvasContext.drawImage(this.img,0,0)},CVImageElement.prototype.destroy=function(){this.img=null},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVSolidElement),CVSolidElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVSolidElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVSolidElement.prototype.renderInnerContent=function(){this.globalData.renderer.ctxFillStyle(this.data.sc),this.globalData.renderer.ctxFillRect(0,0,this.data.sw,this.data.sh)},extendPrototype([BaseRenderer],CanvasRendererBase),CanvasRendererBase.prototype.createShape=function(t){return new CVShapeElement(t,this.globalData,this)},CanvasRendererBase.prototype.createText=function(t){return new CVTextElement(t,this.globalData,this)},CanvasRendererBase.prototype.createImage=function(t){return new CVImageElement(t,this.globalData,this)},CanvasRendererBase.prototype.createSolid=function(t){return new CVSolidElement(t,this.globalData,this)},CanvasRendererBase.prototype.createNull=SVGRenderer.prototype.createNull,CanvasRendererBase.prototype.ctxTransform=function(t){1===t[0]&&0===t[1]&&0===t[4]&&1===t[5]&&0===t[12]&&0===t[13]||this.canvasContext.transform(t[0],t[1],t[4],t[5],t[12],t[13])},CanvasRendererBase.prototype.ctxOpacity=function(t){this.canvasContext.globalAlpha*=t<0?0:t},CanvasRendererBase.prototype.ctxFillStyle=function(t){this.canvasContext.fillStyle=t},CanvasRendererBase.prototype.ctxStrokeStyle=function(t){this.canvasContext.strokeStyle=t},CanvasRendererBase.prototype.ctxLineWidth=function(t){this.canvasContext.lineWidth=t},CanvasRendererBase.prototype.ctxLineCap=function(t){this.canvasContext.lineCap=t},CanvasRendererBase.prototype.ctxLineJoin=function(t){this.canvasContext.lineJoin=t},CanvasRendererBase.prototype.ctxMiterLimit=function(t){this.canvasContext.miterLimit=t},CanvasRendererBase.prototype.ctxFill=function(t){this.canvasContext.fill(t)},CanvasRendererBase.prototype.ctxFillRect=function(t,e,i,r){this.canvasContext.fillRect(t,e,i,r)},CanvasRendererBase.prototype.ctxStroke=function(){this.canvasContext.stroke()},CanvasRendererBase.prototype.reset=function(){this.renderConfig.clearCanvas?this.contextData.reset():this.canvasContext.restore()},CanvasRendererBase.prototype.save=function(){this.canvasContext.save()},CanvasRendererBase.prototype.restore=function(t){this.renderConfig.clearCanvas?(t&&(this.globalData.blendMode="source-over"),this.contextData.restore(t)):this.canvasContext.restore()},CanvasRendererBase.prototype.configAnimation=function(t){if(this.animationItem.wrapper){this.animationItem.container=createTag("canvas");var e=this.animationItem.container.style;e.width="100%",e.height="100%";var i="0px 0px 0px";e.transformOrigin=i,e.mozTransformOrigin=i,e.webkitTransformOrigin=i,e["-webkit-transform"]=i,e.contentVisibility=this.renderConfig.contentVisibility,this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.animationItem.container.setAttribute("id",this.renderConfig.id)}else this.canvasContext=this.renderConfig.context;this.contextData.setContext(this.canvasContext),this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.setupGlobalData(t,document.body),this.globalData.canvasContext=this.canvasContext,this.globalData.renderer=this,this.globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=createSizedArray(t.layers.length),this.updateContainerSize()},CanvasRendererBase.prototype.updateContainerSize=function(t,e){var i,r,s,a;if(this.reset(),t?(i=t,r=e,this.canvasContext.canvas.width=i,this.canvasContext.canvas.height=r):(this.animationItem.wrapper&&this.animationItem.container?(i=this.animationItem.wrapper.offsetWidth,r=this.animationItem.wrapper.offsetHeight):(i=this.canvasContext.canvas.width,r=this.canvasContext.canvas.height),this.canvasContext.canvas.width=i*this.renderConfig.dpr,this.canvasContext.canvas.height=r*this.renderConfig.dpr),-1!==this.renderConfig.preserveAspectRatio.indexOf("meet")||-1!==this.renderConfig.preserveAspectRatio.indexOf("slice")){var n=this.renderConfig.preserveAspectRatio.split(" "),o=n[1]||"meet",h=n[0]||"xMidYMid",l=h.substr(0,4),p=h.substr(4);s=i/r,(a=this.transformCanvas.w/this.transformCanvas.h)>s&&"meet"===o||a<s&&"slice"===o?(this.transformCanvas.sx=i/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=i/(this.transformCanvas.w/this.renderConfig.dpr)):(this.transformCanvas.sx=r/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.sy=r/(this.transformCanvas.h/this.renderConfig.dpr)),this.transformCanvas.tx="xMid"===l&&(a<s&&"meet"===o||a>s&&"slice"===o)?(i-this.transformCanvas.w*(r/this.transformCanvas.h))/2*this.renderConfig.dpr:"xMax"===l&&(a<s&&"meet"===o||a>s&&"slice"===o)?(i-this.transformCanvas.w*(r/this.transformCanvas.h))*this.renderConfig.dpr:0,this.transformCanvas.ty="YMid"===p&&(a>s&&"meet"===o||a<s&&"slice"===o)?(r-this.transformCanvas.h*(i/this.transformCanvas.w))/2*this.renderConfig.dpr:"YMax"===p&&(a>s&&"meet"===o||a<s&&"slice"===o)?(r-this.transformCanvas.h*(i/this.transformCanvas.w))*this.renderConfig.dpr:0}else"none"===this.renderConfig.preserveAspectRatio?(this.transformCanvas.sx=i/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=r/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.tx=0,this.transformCanvas.ty=0):(this.transformCanvas.sx=this.renderConfig.dpr,this.transformCanvas.sy=this.renderConfig.dpr,this.transformCanvas.tx=0,this.transformCanvas.ty=0);this.transformCanvas.props=[this.transformCanvas.sx,0,0,0,0,this.transformCanvas.sy,0,0,0,0,1,0,this.transformCanvas.tx,this.transformCanvas.ty,0,1],this.ctxTransform(this.transformCanvas.props),this.canvasContext.beginPath(),this.canvasContext.rect(0,0,this.transformCanvas.w,this.transformCanvas.h),this.canvasContext.closePath(),this.canvasContext.clip(),this.renderFrame(this.renderedFrame,!0)},CanvasRendererBase.prototype.destroy=function(){var t;for(this.renderConfig.clearCanvas&&this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),t=(this.layers?this.layers.length:0)-1;t>=0;t-=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.globalData.canvasContext=null,this.animationItem.container=null,this.destroyed=!0},CanvasRendererBase.prototype.renderFrame=function(t,e){if((this.renderedFrame!==t||!0!==this.renderConfig.clearCanvas||e)&&!this.destroyed&&-1!==t){var i;this.renderedFrame=t,this.globalData.frameNum=t-this.animationItem._isFirstFrame,this.globalData.frameId+=1,this.globalData._mdf=!this.renderConfig.clearCanvas||e,this.globalData.projectInterface.currentFrame=t;var r=this.layers.length;for(this.completeLayers||this.checkLayers(t),i=r-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&this.elements[i].prepareFrame(t-this.layers[i].st);if(this.globalData._mdf){for(!0===this.renderConfig.clearCanvas?this.canvasContext.clearRect(0,0,this.transformCanvas.w,this.transformCanvas.h):this.save(),i=r-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&this.elements[i].renderFrame();!0!==this.renderConfig.clearCanvas&&this.restore()}}},CanvasRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){var i=this.createItem(this.layers[t],this,this.globalData);e[t]=i,i.initExpressions()}},CanvasRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},CanvasRendererBase.prototype.hide=function(){this.animationItem.container.style.display="none"},CanvasRendererBase.prototype.show=function(){this.animationItem.container.style.display="block"},CVContextData.prototype.duplicate=function(){var t=2*this._length,e=0;for(e=this._length;e<t;e+=1)this.stack[e]=new CanvasContext;this._length=t},CVContextData.prototype.reset=function(){this.cArrPos=0,this.cTr.reset(),this.stack[this.cArrPos].opacity=1},CVContextData.prototype.restore=function(t){this.cArrPos-=1;var e,i=this.stack[this.cArrPos],r=i.transform,s=this.cTr.props;for(e=0;e<16;e+=1)s[e]=r[e];if(t){this.nativeContext.restore();var a=this.stack[this.cArrPos+1];this.appliedFillStyle=a.fillStyle,this.appliedStrokeStyle=a.strokeStyle,this.appliedLineWidth=a.lineWidth,this.appliedLineCap=a.lineCap,this.appliedLineJoin=a.lineJoin,this.appliedMiterLimit=a.miterLimit}this.nativeContext.setTransform(r[0],r[1],r[4],r[5],r[12],r[13]),(t||-1!==i.opacity&&this.currentOpacity!==i.opacity)&&(this.nativeContext.globalAlpha=i.opacity,this.currentOpacity=i.opacity),this.currentFillStyle=i.fillStyle,this.currentStrokeStyle=i.strokeStyle,this.currentLineWidth=i.lineWidth,this.currentLineCap=i.lineCap,this.currentLineJoin=i.lineJoin,this.currentMiterLimit=i.miterLimit},CVContextData.prototype.save=function(t){t&&this.nativeContext.save();var e=this.cTr.props;this._length<=this.cArrPos&&this.duplicate();var i,r=this.stack[this.cArrPos];for(i=0;i<16;i+=1)r.transform[i]=e[i];this.cArrPos+=1;var s=this.stack[this.cArrPos];s.opacity=r.opacity,s.fillStyle=r.fillStyle,s.strokeStyle=r.strokeStyle,s.lineWidth=r.lineWidth,s.lineCap=r.lineCap,s.lineJoin=r.lineJoin,s.miterLimit=r.miterLimit},CVContextData.prototype.setOpacity=function(t){this.stack[this.cArrPos].opacity=t},CVContextData.prototype.setContext=function(t){this.nativeContext=t},CVContextData.prototype.fillStyle=function(t){this.stack[this.cArrPos].fillStyle!==t&&(this.currentFillStyle=t,this.stack[this.cArrPos].fillStyle=t)},CVContextData.prototype.strokeStyle=function(t){this.stack[this.cArrPos].strokeStyle!==t&&(this.currentStrokeStyle=t,this.stack[this.cArrPos].strokeStyle=t)},CVContextData.prototype.lineWidth=function(t){this.stack[this.cArrPos].lineWidth!==t&&(this.currentLineWidth=t,this.stack[this.cArrPos].lineWidth=t)},CVContextData.prototype.lineCap=function(t){this.stack[this.cArrPos].lineCap!==t&&(this.currentLineCap=t,this.stack[this.cArrPos].lineCap=t)},CVContextData.prototype.lineJoin=function(t){this.stack[this.cArrPos].lineJoin!==t&&(this.currentLineJoin=t,this.stack[this.cArrPos].lineJoin=t)},CVContextData.prototype.miterLimit=function(t){this.stack[this.cArrPos].miterLimit!==t&&(this.currentMiterLimit=t,this.stack[this.cArrPos].miterLimit=t)},CVContextData.prototype.transform=function(t){this.transformMat.cloneFromProps(t);var e=this.cTr;this.transformMat.multiply(e),e.cloneFromProps(this.transformMat.props);var i=e.props;this.nativeContext.setTransform(i[0],i[1],i[4],i[5],i[12],i[13])},CVContextData.prototype.opacity=function(t){var e=this.stack[this.cArrPos].opacity;e*=t<0?0:t,this.stack[this.cArrPos].opacity!==e&&(this.currentOpacity!==t&&(this.nativeContext.globalAlpha=t,this.currentOpacity=t),this.stack[this.cArrPos].opacity=e)},CVContextData.prototype.fill=function(t){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fill(t)},CVContextData.prototype.fillRect=function(t,e,i,r){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fillRect(t,e,i,r)},CVContextData.prototype.stroke=function(){this.appliedStrokeStyle!==this.currentStrokeStyle&&(this.appliedStrokeStyle=this.currentStrokeStyle,this.nativeContext.strokeStyle=this.appliedStrokeStyle),this.appliedLineWidth!==this.currentLineWidth&&(this.appliedLineWidth=this.currentLineWidth,this.nativeContext.lineWidth=this.appliedLineWidth),this.appliedLineCap!==this.currentLineCap&&(this.appliedLineCap=this.currentLineCap,this.nativeContext.lineCap=this.appliedLineCap),this.appliedLineJoin!==this.currentLineJoin&&(this.appliedLineJoin=this.currentLineJoin,this.nativeContext.lineJoin=this.appliedLineJoin),this.appliedMiterLimit!==this.currentMiterLimit&&(this.appliedMiterLimit=this.currentMiterLimit,this.nativeContext.miterLimit=this.appliedMiterLimit),this.nativeContext.stroke()},extendPrototype([CanvasRendererBase,ICompElement,CVBaseElement],CVCompElement),CVCompElement.prototype.renderInnerContent=function(){var t,e=this.canvasContext;for(e.beginPath(),e.moveTo(0,0),e.lineTo(this.data.w,0),e.lineTo(this.data.w,this.data.h),e.lineTo(0,this.data.h),e.lineTo(0,0),e.clip(),t=this.layers.length-1;t>=0;t-=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},CVCompElement.prototype.destroy=function(){var t;for(t=this.layers.length-1;t>=0;t-=1)this.elements[t]&&this.elements[t].destroy();this.layers=null,this.elements=null},CVCompElement.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},extendPrototype([CanvasRendererBase],CanvasRenderer),CanvasRenderer.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},HBaseElement.prototype={checkBlendMode:function(){},initRendererElement:function(){this.baseElement=createTag(this.data.tg||"div"),this.data.hasMask?(this.svgElement=createNS("svg"),this.layerElement=createNS("g"),this.maskedElement=this.layerElement,this.svgElement.appendChild(this.layerElement),this.baseElement.appendChild(this.svgElement)):this.layerElement=this.baseElement,styleDiv(this.baseElement)},createContainerElements:function(){this.renderableEffectsManager=new CVEffects(this),this.transformedElement=this.baseElement,this.maskedElement=this.layerElement,this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0!==this.data.bm&&this.setBlendMode()},renderElement:function(){var t=this.transformedElement?this.transformedElement.style:{};if(this.finalTransform._matMdf){var e=this.finalTransform.mat.toCSS();t.transform=e,t.webkitTransform=e}this.finalTransform._opMdf&&(t.opacity=this.finalTransform.mProp.o.v)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},destroy:function(){this.layerElement=null,this.transformedElement=null,this.matteElement&&(this.matteElement=null),this.maskManager&&(this.maskManager.destroy(),this.maskManager=null)},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData)},addEffects:function(){},setMatte:function(){}},HBaseElement.prototype.getBaseElement=SVGBaseElement.prototype.getBaseElement,HBaseElement.prototype.destroyBaseElement=HBaseElement.prototype.destroy,HBaseElement.prototype.buildElementParenting=BaseRenderer.prototype.buildElementParenting,extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],HSolidElement),HSolidElement.prototype.createContent=function(){var t;this.data.hasMask?((t=createNS("rect")).setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.svgElement.setAttribute("width",this.data.sw),this.svgElement.setAttribute("height",this.data.sh)):((t=createTag("div")).style.width=this.data.sw+"px",t.style.height=this.data.sh+"px",t.style.backgroundColor=this.data.sc),this.layerElement.appendChild(t)},extendPrototype([BaseElement,TransformElement,HSolidElement,SVGShapeElement,HBaseElement,HierarchyElement,FrameElement,RenderableElement],HShapeElement),HShapeElement.prototype._renderShapeFrame=HShapeElement.prototype.renderInnerContent,HShapeElement.prototype.createContent=function(){var t;if(this.baseElement.style.fontSize=0,this.data.hasMask)this.layerElement.appendChild(this.shapesContainer),t=this.svgElement;else{t=createNS("svg");var e=this.comp.data?this.comp.data:this.globalData.compSize;t.setAttribute("width",e.w),t.setAttribute("height",e.h),t.appendChild(this.shapesContainer),this.layerElement.appendChild(t)}this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.shapesContainer,0,[],!0),this.filterUniqueShapes(),this.shapeCont=t},HShapeElement.prototype.getTransformedPoint=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)e=t[i].mProps.v.applyToPointArray(e[0],e[1],0);return e},HShapeElement.prototype.calculateShapeBoundingBox=function(t,e){var i,r,s,a,n,o=t.sh.v,h=t.transformers,l=o._length;if(!(l<=1)){for(i=0;i<l-1;i+=1)r=this.getTransformedPoint(h,o.v[i]),s=this.getTransformedPoint(h,o.o[i]),a=this.getTransformedPoint(h,o.i[i+1]),n=this.getTransformedPoint(h,o.v[i+1]),this.checkBounds(r,s,a,n,e);o.c&&(r=this.getTransformedPoint(h,o.v[i]),s=this.getTransformedPoint(h,o.o[i]),a=this.getTransformedPoint(h,o.i[0]),n=this.getTransformedPoint(h,o.v[0]),this.checkBounds(r,s,a,n,e))}},HShapeElement.prototype.checkBounds=function(t,e,i,r,s){this.getBoundsOfCurve(t,e,i,r);var a=this.shapeBoundingBox;s.x=bmMin(a.left,s.x),s.xMax=bmMax(a.right,s.xMax),s.y=bmMin(a.top,s.y),s.yMax=bmMax(a.bottom,s.yMax)},HShapeElement.prototype.shapeBoundingBox={left:0,right:0,top:0,bottom:0},HShapeElement.prototype.tempBoundingBox={x:0,xMax:0,y:0,yMax:0,width:0,height:0},HShapeElement.prototype.getBoundsOfCurve=function(t,e,i,r){for(var s,a,n,o,h,l,p,f=[[t[0],r[0]],[t[1],r[1]]],m=0;m<2;++m)a=6*t[m]-12*e[m]+6*i[m],s=-3*t[m]+9*e[m]-9*i[m]+3*r[m],n=3*e[m]-3*t[m],a|=0,n|=0,0===(s|=0)&&0===a||(0===s?(o=-n/a)>0&&o<1&&f[m].push(this.calculateF(o,t,e,i,r,m)):(h=a*a-4*n*s)>=0&&((l=(-a+bmSqrt(h))/(2*s))>0&&l<1&&f[m].push(this.calculateF(l,t,e,i,r,m)),(p=(-a-bmSqrt(h))/(2*s))>0&&p<1&&f[m].push(this.calculateF(p,t,e,i,r,m))));this.shapeBoundingBox.left=bmMin.apply(null,f[0]),this.shapeBoundingBox.top=bmMin.apply(null,f[1]),this.shapeBoundingBox.right=bmMax.apply(null,f[0]),this.shapeBoundingBox.bottom=bmMax.apply(null,f[1])},HShapeElement.prototype.calculateF=function(t,e,i,r,s,a){return bmPow(1-t,3)*e[a]+3*bmPow(1-t,2)*t*i[a]+3*(1-t)*bmPow(t,2)*r[a]+bmPow(t,3)*s[a]},HShapeElement.prototype.calculateBoundingBox=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)t[i]&&t[i].sh?this.calculateShapeBoundingBox(t[i],e):t[i]&&t[i].it?this.calculateBoundingBox(t[i].it,e):t[i]&&t[i].style&&t[i].w&&this.expandStrokeBoundingBox(t[i].w,e)},HShapeElement.prototype.expandStrokeBoundingBox=function(t,e){var i=0;if(t.keyframes){for(var r=0;r<t.keyframes.length;r+=1){var s=t.keyframes[r].s;s>i&&(i=s)}i*=t.mult}else i=t.v*t.mult;e.x-=i,e.xMax+=i,e.y-=i,e.yMax+=i},HShapeElement.prototype.currentBoxContains=function(t){return this.currentBBox.x<=t.x&&this.currentBBox.y<=t.y&&this.currentBBox.width+this.currentBBox.x>=t.x+t.width&&this.currentBBox.height+this.currentBBox.y>=t.y+t.height},HShapeElement.prototype.renderInnerContent=function(){if(this._renderShapeFrame(),!this.hidden&&(this._isFirstFrame||this._mdf)){var t=this.tempBoundingBox,e=999999;if(t.x=e,t.xMax=-e,t.y=e,t.yMax=-e,this.calculateBoundingBox(this.itemsData,t),t.width=t.xMax<t.x?0:t.xMax-t.x,t.height=t.yMax<t.y?0:t.yMax-t.y,this.currentBoxContains(t))return;var i=!1;if(this.currentBBox.w!==t.width&&(this.currentBBox.w=t.width,this.shapeCont.setAttribute("width",t.width),i=!0),this.currentBBox.h!==t.height&&(this.currentBBox.h=t.height,this.shapeCont.setAttribute("height",t.height),i=!0),i||this.currentBBox.x!==t.x||this.currentBBox.y!==t.y){this.currentBBox.w=t.width,this.currentBBox.h=t.height,this.currentBBox.x=t.x,this.currentBBox.y=t.y,this.shapeCont.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h);var r=this.shapeCont.style,s="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)";r.transform=s,r.webkitTransform=s}}},extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],HTextElement),HTextElement.prototype.createContent=function(){if(this.isMasked=this.checkMasks(),this.isMasked){this.renderType="svg",this.compW=this.comp.data.w,this.compH=this.comp.data.h,this.svgElement.setAttribute("width",this.compW),this.svgElement.setAttribute("height",this.compH);var t=createNS("g");this.maskedElement.appendChild(t),this.innerElem=t}else this.renderType="html",this.innerElem=this.layerElement;this.checkParenting()},HTextElement.prototype.buildNewText=function(){var t=this.textProperty.currentData;this.renderedLetters=createSizedArray(t.l?t.l.length:0);var e=this.innerElem.style,i=t.fc?this.buildColor(t.fc):"rgba(0,0,0,0)";e.fill=i,e.color=i,t.sc&&(e.stroke=this.buildColor(t.sc),e.strokeWidth=t.sw+"px");var r,s,a=this.globalData.fontManager.getFontByName(t.f);if(!this.globalData.fontManager.chars)if(e.fontSize=t.finalSize+"px",e.lineHeight=t.finalSize+"px",a.fClass)this.innerElem.className=a.fClass;else{e.fontFamily=a.fFamily;var n=t.fWeight,o=t.fStyle;e.fontStyle=o,e.fontWeight=n}var h,l,p,f=t.l;s=f.length;var m,c=this.mHelper,d="",u=0;for(r=0;r<s;r+=1){if(this.globalData.fontManager.chars?(this.textPaths[u]?h=this.textPaths[u]:((h=createNS("path")).setAttribute("stroke-linecap",lineCapEnum[1]),h.setAttribute("stroke-linejoin",lineJoinEnum[2]),h.setAttribute("stroke-miterlimit","4")),this.isMasked||(this.textSpans[u]?p=(l=this.textSpans[u]).children[0]:((l=createTag("div")).style.lineHeight=0,(p=createNS("svg")).appendChild(h),styleDiv(l)))):this.isMasked?h=this.textPaths[u]?this.textPaths[u]:createNS("text"):this.textSpans[u]?(l=this.textSpans[u],h=this.textPaths[u]):(styleDiv(l=createTag("span")),styleDiv(h=createTag("span")),l.appendChild(h)),this.globalData.fontManager.chars){var y,g=this.globalData.fontManager.getCharData(t.finalText[r],a.fStyle,this.globalData.fontManager.getFontByName(t.f).fFamily);if(y=g?g.data:null,c.reset(),y&&y.shapes&&y.shapes.length&&(m=y.shapes[0].it,c.scale(t.finalSize/100,t.finalSize/100),d=this.createPathShape(c,m),h.setAttribute("d",d)),this.isMasked)this.innerElem.appendChild(h);else{if(this.innerElem.appendChild(l),y&&y.shapes){document.body.appendChild(p);var v=p.getBBox();p.setAttribute("width",v.width+2),p.setAttribute("height",v.height+2),p.setAttribute("viewBox",v.x-1+" "+(v.y-1)+" "+(v.width+2)+" "+(v.height+2));var b=p.style,x="translate("+(v.x-1)+"px,"+(v.y-1)+"px)";b.transform=x,b.webkitTransform=x,f[r].yOffset=v.y-1}else p.setAttribute("width",1),p.setAttribute("height",1);l.appendChild(p)}}else if(h.textContent=f[r].val,h.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),this.isMasked)this.innerElem.appendChild(h);else{this.innerElem.appendChild(l);var P=h.style,E="translate3d(0,"+-t.finalSize/1.2+"px,0)";P.transform=E,P.webkitTransform=E}this.isMasked?this.textSpans[u]=h:this.textSpans[u]=l,this.textSpans[u].style.display="block",this.textPaths[u]=h,u+=1}for(;u<this.textSpans.length;)this.textSpans[u].style.display="none",u+=1},HTextElement.prototype.renderInnerContent=function(){var t;if(this.validateText(),this.data.singleShape){if(!this._isFirstFrame&&!this.lettersChangedFlag)return;if(this.isMasked&&this.finalTransform._matMdf){this.svgElement.setAttribute("viewBox",-this.finalTransform.mProp.p.v[0]+" "+-this.finalTransform.mProp.p.v[1]+" "+this.compW+" "+this.compH),t=this.svgElement.style;var e="translate("+-this.finalTransform.mProp.p.v[0]+"px,"+-this.finalTransform.mProp.p.v[1]+"px)";t.transform=e,t.webkitTransform=e}}if(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag){var i,r,s,a,n,o=0,h=this.textAnimator.renderedLetters,l=this.textProperty.currentData.l;for(r=l.length,i=0;i<r;i+=1)l[i].n?o+=1:(a=this.textSpans[i],n=this.textPaths[i],s=h[o],o+=1,s._mdf.m&&(this.isMasked?a.setAttribute("transform",s.m):(a.style.webkitTransform=s.m,a.style.transform=s.m)),a.style.opacity=s.o,s.sw&&s._mdf.sw&&n.setAttribute("stroke-width",s.sw),s.sc&&s._mdf.sc&&n.setAttribute("stroke",s.sc),s.fc&&s._mdf.fc&&(n.setAttribute("fill",s.fc),n.style.color=s.fc));if(this.innerElem.getBBox&&!this.hidden&&(this._isFirstFrame||this._mdf)){var p=this.innerElem.getBBox();this.currentBBox.w!==p.width&&(this.currentBBox.w=p.width,this.svgElement.setAttribute("width",p.width)),this.currentBBox.h!==p.height&&(this.currentBBox.h=p.height,this.svgElement.setAttribute("height",p.height));if(this.currentBBox.w!==p.width+2||this.currentBBox.h!==p.height+2||this.currentBBox.x!==p.x-1||this.currentBBox.y!==p.y-1){this.currentBBox.w=p.width+2,this.currentBBox.h=p.height+2,this.currentBBox.x=p.x-1,this.currentBBox.y=p.y-1,this.svgElement.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h),t=this.svgElement.style;var f="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)";t.transform=f,t.webkitTransform=f}}}},extendPrototype([BaseElement,FrameElement,HierarchyElement],HCameraElement),HCameraElement.prototype.setup=function(){var t,e,i,r,s=this.comp.threeDElements.length;for(t=0;t<s;t+=1)if("3d"===(e=this.comp.threeDElements[t]).type){i=e.perspectiveElem.style,r=e.container.style;var a=this.pe.v+"px",n="0px 0px 0px",o="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";i.perspective=a,i.webkitPerspective=a,r.transformOrigin=n,r.mozTransformOrigin=n,r.webkitTransformOrigin=n,i.transform=o,i.webkitTransform=o}},HCameraElement.prototype.createElements=function(){},HCameraElement.prototype.hide=function(){},HCameraElement.prototype.renderFrame=function(){var t,e,i=this._isFirstFrame;if(this.hierarchy)for(e=this.hierarchy.length,t=0;t<e;t+=1)i=this.hierarchy[t].finalTransform.mProp._mdf||i;if(i||this.pe._mdf||this.p&&this.p._mdf||this.px&&(this.px._mdf||this.py._mdf||this.pz._mdf)||this.rx._mdf||this.ry._mdf||this.rz._mdf||this.or._mdf||this.a&&this.a._mdf){if(this.mat.reset(),this.hierarchy)for(t=e=this.hierarchy.length-1;t>=0;t-=1){var r=this.hierarchy[t].finalTransform.mProp;this.mat.translate(-r.p.v[0],-r.p.v[1],r.p.v[2]),this.mat.rotateX(-r.or.v[0]).rotateY(-r.or.v[1]).rotateZ(r.or.v[2]),this.mat.rotateX(-r.rx.v).rotateY(-r.ry.v).rotateZ(r.rz.v),this.mat.scale(1/r.s.v[0],1/r.s.v[1],1/r.s.v[2]),this.mat.translate(r.a.v[0],r.a.v[1],r.a.v[2])}if(this.p?this.mat.translate(-this.p.v[0],-this.p.v[1],this.p.v[2]):this.mat.translate(-this.px.v,-this.py.v,this.pz.v),this.a){var s;s=this.p?[this.p.v[0]-this.a.v[0],this.p.v[1]-this.a.v[1],this.p.v[2]-this.a.v[2]]:[this.px.v-this.a.v[0],this.py.v-this.a.v[1],this.pz.v-this.a.v[2]];var a=Math.sqrt(Math.pow(s[0],2)+Math.pow(s[1],2)+Math.pow(s[2],2)),n=[s[0]/a,s[1]/a,s[2]/a],o=Math.sqrt(n[2]*n[2]+n[0]*n[0]),h=Math.atan2(n[1],o),l=Math.atan2(n[0],-n[2]);this.mat.rotateY(l).rotateX(-h)}this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v),this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]),this.mat.translate(this.globalData.compSize.w/2,this.globalData.compSize.h/2,0),this.mat.translate(0,0,this.pe.v);var p=!this._prevMat.equals(this.mat);if((p||this.pe._mdf)&&this.comp.threeDElements){var f,m,c;for(e=this.comp.threeDElements.length,t=0;t<e;t+=1)if("3d"===(f=this.comp.threeDElements[t]).type){if(p){var d=this.mat.toCSS();(c=f.container.style).transform=d,c.webkitTransform=d}this.pe._mdf&&((m=f.perspectiveElem.style).perspective=this.pe.v+"px",m.webkitPerspective=this.pe.v+"px")}this.mat.clone(this._prevMat)}}this._isFirstFrame=!1},HCameraElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},HCameraElement.prototype.destroy=function(){},HCameraElement.prototype.getBaseElement=function(){return null},extendPrototype([BaseElement,TransformElement,HBaseElement,HSolidElement,HierarchyElement,FrameElement,RenderableElement],HImageElement),HImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData),e=new Image;this.data.hasMask?(this.imageElem=createNS("image"),this.imageElem.setAttribute("width",this.assetData.w+"px"),this.imageElem.setAttribute("height",this.assetData.h+"px"),this.imageElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.imageElem),this.baseElement.setAttribute("width",this.assetData.w),this.baseElement.setAttribute("height",this.assetData.h)):this.layerElement.appendChild(e),e.crossOrigin="anonymous",e.src=t,this.data.ln&&this.baseElement.setAttribute("id",this.data.ln)},extendPrototype([BaseRenderer],HybridRendererBase),HybridRendererBase.prototype.buildItem=SVGRenderer.prototype.buildItem,HybridRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},HybridRendererBase.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){var r=this.layers[e];if(r.ddd&&this.supports3d)this.addTo3dContainer(i,e);else if(this.threeDElements)this.addTo3dContainer(i,e);else{for(var s,a,n=0;n<e;)this.elements[n]&&!0!==this.elements[n]&&this.elements[n].getBaseElement&&(a=this.elements[n],s=(this.layers[n].ddd?this.getThreeDContainerByPos(n):a.getBaseElement())||s),n+=1;s?r.ddd&&this.supports3d||this.layerElement.insertBefore(i,s):r.ddd&&this.supports3d||this.layerElement.appendChild(i)}}},HybridRendererBase.prototype.createShape=function(t){return this.supports3d?new HShapeElement(t,this.globalData,this):new SVGShapeElement(t,this.globalData,this)},HybridRendererBase.prototype.createText=function(t){return this.supports3d?new HTextElement(t,this.globalData,this):new SVGTextLottieElement(t,this.globalData,this)},HybridRendererBase.prototype.createCamera=function(t){return this.camera=new HCameraElement(t,this.globalData,this),this.camera},HybridRendererBase.prototype.createImage=function(t){return this.supports3d?new HImageElement(t,this.globalData,this):new IImageElement(t,this.globalData,this)},HybridRendererBase.prototype.createSolid=function(t){return this.supports3d?new HSolidElement(t,this.globalData,this):new ISolidElement(t,this.globalData,this)},HybridRendererBase.prototype.createNull=SVGRenderer.prototype.createNull,HybridRendererBase.prototype.getThreeDContainerByPos=function(t){for(var e=0,i=this.threeDElements.length;e<i;){if(this.threeDElements[e].startPos<=t&&this.threeDElements[e].endPos>=t)return this.threeDElements[e].perspectiveElem;e+=1}return null},HybridRendererBase.prototype.createThreeDContainer=function(t,e){var i,r,s=createTag("div");styleDiv(s);var a=createTag("div");if(styleDiv(a),"3d"===e){(i=s.style).width=this.globalData.compSize.w+"px",i.height=this.globalData.compSize.h+"px";var n="50% 50%";i.webkitTransformOrigin=n,i.mozTransformOrigin=n,i.transformOrigin=n;var o="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";(r=a.style).transform=o,r.webkitTransform=o}s.appendChild(a);var h={container:a,perspectiveElem:s,startPos:t,endPos:t,type:e};return this.threeDElements.push(h),h},HybridRendererBase.prototype.build3dContainers=function(){var t,e,i=this.layers.length,r="";for(t=0;t<i;t+=1)this.layers[t].ddd&&3!==this.layers[t].ty?("3d"!==r&&(r="3d",e=this.createThreeDContainer(t,"3d")),e.endPos=Math.max(e.endPos,t)):("2d"!==r&&(r="2d",e=this.createThreeDContainer(t,"2d")),e.endPos=Math.max(e.endPos,t));for(t=(i=this.threeDElements.length)-1;t>=0;t-=1)this.resizerElem.appendChild(this.threeDElements[t].perspectiveElem)},HybridRendererBase.prototype.addTo3dContainer=function(t,e){for(var i=0,r=this.threeDElements.length;i<r;){if(e<=this.threeDElements[i].endPos){for(var s,a=this.threeDElements[i].startPos;a<e;)this.elements[a]&&this.elements[a].getBaseElement&&(s=this.elements[a].getBaseElement()),a+=1;s?this.threeDElements[i].container.insertBefore(t,s):this.threeDElements[i].container.appendChild(t);break}i+=1}},HybridRendererBase.prototype.configAnimation=function(t){var e=createTag("div"),i=this.animationItem.wrapper,r=e.style;r.width=t.w+"px",r.height=t.h+"px",this.resizerElem=e,styleDiv(e),r.transformStyle="flat",r.mozTransformStyle="flat",r.webkitTransformStyle="flat",this.renderConfig.className&&e.setAttribute("class",this.renderConfig.className),i.appendChild(e),r.overflow="hidden";var s=createNS("svg");s.setAttribute("width","1"),s.setAttribute("height","1"),styleDiv(s),this.resizerElem.appendChild(s);var a=createNS("defs");s.appendChild(a),this.data=t,this.setupGlobalData(t,s),this.globalData.defs=a,this.layers=t.layers,this.layerElement=this.resizerElem,this.build3dContainers(),this.updateContainerSize()},HybridRendererBase.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.animationItem.container=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},HybridRendererBase.prototype.updateContainerSize=function(){var t,e,i,r,s=this.animationItem.wrapper.offsetWidth,a=this.animationItem.wrapper.offsetHeight,n=s/a;this.globalData.compSize.w/this.globalData.compSize.h>n?(t=s/this.globalData.compSize.w,e=s/this.globalData.compSize.w,i=0,r=(a-this.globalData.compSize.h*(s/this.globalData.compSize.w))/2):(t=a/this.globalData.compSize.h,e=a/this.globalData.compSize.h,i=(s-this.globalData.compSize.w*(a/this.globalData.compSize.h))/2,r=0);var o=this.resizerElem.style;o.webkitTransform="matrix3d("+t+",0,0,0,0,"+e+",0,0,0,0,1,0,"+i+","+r+",0,1)",o.transform=o.webkitTransform},HybridRendererBase.prototype.renderFrame=SVGRenderer.prototype.renderFrame,HybridRendererBase.prototype.hide=function(){this.resizerElem.style.display="none"},HybridRendererBase.prototype.show=function(){this.resizerElem.style.display="block"},HybridRendererBase.prototype.initItems=function(){if(this.buildAllItems(),this.camera)this.camera.setup();else{var t,e=this.globalData.compSize.w,i=this.globalData.compSize.h,r=this.threeDElements.length;for(t=0;t<r;t+=1){var s=this.threeDElements[t].perspectiveElem.style;s.webkitPerspective=Math.sqrt(Math.pow(e,2)+Math.pow(i,2))+"px",s.perspective=s.webkitPerspective}}},HybridRendererBase.prototype.searchExtraCompositions=function(t){var e,i=t.length,r=createTag("div");for(e=0;e<i;e+=1)if(t[e].xt){var s=this.createComp(t[e],r,this.globalData.comp,null);s.initExpressions(),this.globalData.projectInterface.registerComposition(s)}},extendPrototype([HybridRendererBase,ICompElement,HBaseElement],HCompElement),HCompElement.prototype._createBaseContainerElements=HCompElement.prototype.createContainerElements,HCompElement.prototype.createContainerElements=function(){this._createBaseContainerElements(),this.data.hasMask?(this.svgElement.setAttribute("width",this.data.w),this.svgElement.setAttribute("height",this.data.h),this.transformedElement=this.baseElement):this.transformedElement=this.layerElement},HCompElement.prototype.addTo3dContainer=function(t,e){for(var i,r=0;r<e;)this.elements[r]&&this.elements[r].getBaseElement&&(i=this.elements[r].getBaseElement()),r+=1;i?this.layerElement.insertBefore(t,i):this.layerElement.appendChild(t)},HCompElement.prototype.createComp=function(t){return this.supports3d?new HCompElement(t,this.globalData,this):new SVGCompElement(t,this.globalData,this)},extendPrototype([HybridRendererBase],HybridRenderer),HybridRenderer.prototype.createComp=function(t){return this.supports3d?new HCompElement(t,this.globalData,this):new SVGCompElement(t,this.globalData,this)};var CompExpressionInterface=function(t){function e(e){for(var i=0,r=t.layers.length;i<r;){if(t.layers[i].nm===e||t.layers[i].ind===e)return t.elements[i].layerInterface;i+=1}return null}return Object.defineProperty(e,"_name",{value:t.data.nm}),e.layer=e,e.pixelAspect=1,e.height=t.data.h||t.globalData.compSize.h,e.width=t.data.w||t.globalData.compSize.w,e.pixelAspect=1,e.frameDuration=1/t.globalData.frameRate,e.displayStartTime=0,e.numLayers=t.layers.length,e};function _typeof$2(t){return _typeof$2="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$2(t)}function seedRandom(t,e){var i,r=this,s=256,a=e.pow(s,6),n=e.pow(2,52),o=2*n,h=255;function l(t){var e,i=t.length,r=this,a=0,n=r.i=r.j=0,o=r.S=[];for(i||(t=[i++]);a<s;)o[a]=a++;for(a=0;a<s;a++)o[a]=o[n=h&n+t[a%i]+(e=o[a])],o[n]=e;r.g=function(t){for(var e,i=0,a=r.i,n=r.j,o=r.S;t--;)e=o[a=h&a+1],i=i*s+o[h&(o[a]=o[n=h&n+e])+(o[n]=e)];return r.i=a,r.j=n,i}}function p(t,e){return e.i=t.i,e.j=t.j,e.S=t.S.slice(),e}function f(t,e){var i,r=[],s=_typeof$2(t);if(e&&"object"==s)for(i in t)try{r.push(f(t[i],e-1))}catch(t){}return r.length?r:"string"==s?t:t+"\0"}function m(t,e){for(var i,r=t+"",s=0;s<r.length;)e[h&s]=h&(i^=19*e[h&s])+r.charCodeAt(s++);return c(e)}function c(t){return String.fromCharCode.apply(0,t)}e.seedrandom=function(h,d,u){var y=[],g=m(f((d=!0===d?{entropy:!0}:d||{}).entropy?[h,c(t)]:null===h?function(){try{i;var e=new Uint8Array(s);return(r.crypto||r.msCrypto).getRandomValues(e),c(e)}catch(e){var a=r.navigator,n=a&&a.plugins;return[+new Date,r,n,r.screen,c(t)]}}():h,3),y),v=new l(y),b=function(){for(var t=v.g(6),e=a,i=0;t<n;)t=(t+i)*s,e*=s,i=v.g(1);for(;t>=o;)t/=2,e/=2,i>>>=1;return(t+i)/e};return b.int32=function(){return 0|v.g(4)},b.quick=function(){return v.g(4)/4294967296},b.double=b,m(c(v.S),t),(d.pass||u||function(t,i,r,s){return s&&(s.S&&p(s,v),t.state=function(){return p(v,{})}),r?(e.random=t,i):t})(b,g,"global"in d?d.global:this==e,d.state)},m(e.random(),t)}function initialize$2(t){seedRandom([],t)}var propTypes={SHAPE:"shape"};function _typeof$1(t){return _typeof$1="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$1(t)}var ExpressionManager=function(){var ob={},Math=BMMath,window=null,document=null,XMLHttpRequest=null,fetch=null,frames=null,_lottieGlobal={};function resetFrame(){_lottieGlobal={}}function $bm_isInstanceOfArray(t){return t.constructor===Array||t.constructor===Float32Array}function isNumerable(t,e){return"number"===t||e instanceof Number||"boolean"===t||"string"===t}function $bm_neg(t){var e=_typeof$1(t);if("number"===e||t instanceof Number||"boolean"===e)return-t;if($bm_isInstanceOfArray(t)){var i,r=t.length,s=[];for(i=0;i<r;i+=1)s[i]=-t[i];return s}return t.propType?t.v:-t}initialize$2(BMMath);var easeInBez=BezierFactory.getBezierEasing(.333,0,.833,.833,"easeIn").get,easeOutBez=BezierFactory.getBezierEasing(.167,.167,.667,1,"easeOut").get,easeInOutBez=BezierFactory.getBezierEasing(.33,0,.667,1,"easeInOut").get;function sum(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e)||"string"===i||"string"===r)return t+e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]+=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t+e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]+e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}var add=sum;function sub(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e))return"string"===i&&(t=parseInt(t,10)),"string"===r&&(e=parseInt(e,10)),t-e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]-=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t-e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]-e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}function mul(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t*e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]*e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t*e[r];return i}return 0}function div(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t/e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]/e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t/e[r];return i}return 0}function mod(t,e){return"string"==typeof t&&(t=parseInt(t,10)),"string"==typeof e&&(e=parseInt(e,10)),t%e}var $bm_sum=sum,$bm_sub=sub,$bm_mul=mul,$bm_div=div,$bm_mod=mod;function clamp(t,e,i){if(e>i){var r=i;i=e,e=r}return Math.min(Math.max(t,e),i)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return e=e||0,Math.abs(t-e);var i;e||(e=helperLengthArray);var r=Math.min(t.length,e.length),s=0;for(i=0;i<r;i+=1)s+=Math.pow(e[i]-t[i],2);return Math.sqrt(s)}function normalize(t){return div(t,length(t))}function rgbToHsl(t){var e,i,r=t[0],s=t[1],a=t[2],n=Math.max(r,s,a),o=Math.min(r,s,a),h=(n+o)/2;if(n===o)e=0,i=0;else{var l=n-o;switch(i=h>.5?l/(2-n-o):l/(n+o),n){case r:e=(s-a)/l+(s<a?6:0);break;case s:e=(a-r)/l+2;break;case a:e=(r-s)/l+4}e/=6}return[e,i,h,t[3]]}function hue2rgb(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}function hslToRgb(t){var e,i,r,s=t[0],a=t[1],n=t[2];if(0===a)e=n,r=n,i=n;else{var o=n<.5?n*(1+a):n+a-n*a,h=2*n-o;e=hue2rgb(h,o,s+1/3),i=hue2rgb(h,o,s),r=hue2rgb(h,o,s-1/3)}return[e,i,r,t[3]]}function linear(t,e,i,r,s){if(void 0!==r&&void 0!==s||(r=e,s=i,e=0,i=1),i<e){var a=i;i=e,e=a}if(t<=e)return r;if(t>=i)return s;var n,o=i===e?0:(t-e)/(i-e);if(!r.length)return r+(s-r)*o;var h=r.length,l=createTypedArray("float32",h);for(n=0;n<h;n+=1)l[n]=r[n]+(s[n]-r[n])*o;return l}function random(t,e){if(void 0===e&&(void 0===t?(t=0,e=1):(e=t,t=void 0)),e.length){var i,r=e.length;t||(t=createTypedArray("float32",r));var s=createTypedArray("float32",r),a=BMMath.random();for(i=0;i<r;i+=1)s[i]=t[i]+a*(e[i]-t[i]);return s}return void 0===t&&(t=0),t+BMMath.random()*(e-t)}function createPath(t,e,i,r){var s,a=t.length,n=shapePool.newElement();n.setPathData(!!r,a);var o,h,l=[0,0];for(s=0;s<a;s+=1)o=e&&e[s]?e[s]:l,h=i&&i[s]?i[s]:l,n.setTripleAt(t[s][0],t[s][1],h[0]+t[s][0],h[1]+t[s][1],o[0]+t[s][0],o[1]+t[s][1],s,!0);return n}function initiateExpression(elem,data,property){function noOp(t){return t}if(!elem.globalData.renderConfig.runExpressions)return noOp;var val=data.x,needsVelocity=/velocity(?![\w\d])/.test(val),_needsRandom=-1!==val.indexOf("random"),elemType=elem.data.ty,transform,$bm_transform,content,effect,thisProperty=property;thisProperty.valueAtTime=thisProperty.getValueAtTime,Object.defineProperty(thisProperty,"value",{get:function(){return thisProperty.v}}),elem.comp.frameDuration=1/elem.comp.globalData.frameRate,elem.comp.displayStartTime=0;var inPoint=elem.data.ip/elem.comp.globalData.frameRate,outPoint=elem.data.op/elem.comp.globalData.frameRate,width=elem.data.sw?elem.data.sw:0,height=elem.data.sh?elem.data.sh:0,name=elem.data.nm,loopIn,loop_in,loopOut,loop_out,smooth,toWorld,fromWorld,fromComp,toComp,fromCompToSurface,position,rotation,anchorPoint,scale,thisLayer,thisComp,mask,valueAtTime,velocityAtTime,scoped_bm_rt,expression_function=eval("[function _expression_function(){"+val+";scoped_bm_rt=$bm_rt}]")[0],numKeys=property.kf?data.k.length:0,active=!this.data||!0!==this.data.hd,wiggle=function(t,e){var i,r,s=this.pv.length?this.pv.length:1,a=createTypedArray("float32",s);var n=Math.floor(5*time);for(i=0,r=0;i<n;){for(r=0;r<s;r+=1)a[r]+=-e+2*e*BMMath.random();i+=1}var o=5*time,h=o-Math.floor(o),l=createTypedArray("float32",s);if(s>1){for(r=0;r<s;r+=1)l[r]=this.pv[r]+a[r]+(-e+2*e*BMMath.random())*h;return l}return this.pv+a[0]+(-e+2*e*BMMath.random())*h}.bind(this);function loopInDuration(t,e){return loopIn(t,e,!0)}function loopOutDuration(t,e){return loopOut(t,e,!0)}thisProperty.loopIn&&(loopIn=thisProperty.loopIn.bind(thisProperty),loop_in=loopIn),thisProperty.loopOut&&(loopOut=thisProperty.loopOut.bind(thisProperty),loop_out=loopOut),thisProperty.smooth&&(smooth=thisProperty.smooth.bind(thisProperty)),this.getValueAtTime&&(valueAtTime=this.getValueAtTime.bind(this)),this.getVelocityAtTime&&(velocityAtTime=this.getVelocityAtTime.bind(this));var comp=elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface),time,velocity,value,text,textIndex,textTotal,selectorValue;function lookAt(t,e){var i=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],r=Math.atan2(i[0],Math.sqrt(i[1]*i[1]+i[2]*i[2]))/degToRads;return[-Math.atan2(i[1],i[2])/degToRads,r,0]}function easeOut(t,e,i,r,s){return applyEase(easeOutBez,t,e,i,r,s)}function easeIn(t,e,i,r,s){return applyEase(easeInBez,t,e,i,r,s)}function ease(t,e,i,r,s){return applyEase(easeInOutBez,t,e,i,r,s)}function applyEase(t,e,i,r,s,a){void 0===s?(s=i,a=r):e=(e-i)/(r-i),e>1?e=1:e<0&&(e=0);var n=t(e);if($bm_isInstanceOfArray(s)){var o,h=s.length,l=createTypedArray("float32",h);for(o=0;o<h;o+=1)l[o]=(a[o]-s[o])*n+s[o];return l}return(a-s)*n+s}function nearestKey(t){var e,i,r,s=data.k.length;if(data.k.length&&"number"!=typeof data.k[0])if(i=-1,(t*=elem.comp.globalData.frameRate)<data.k[0].t)i=1,r=data.k[0].t;else{for(e=0;e<s-1;e+=1){if(t===data.k[e].t){i=e+1,r=data.k[e].t;break}if(t>data.k[e].t&&t<data.k[e+1].t){t-data.k[e].t>data.k[e+1].t-t?(i=e+2,r=data.k[e+1].t):(i=e+1,r=data.k[e].t);break}}-1===i&&(i=e+1,r=data.k[e].t)}else i=0,r=0;var a={};return a.index=i,a.time=r/elem.comp.globalData.frameRate,a}function key(t){var e,i,r;if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]};var s=Object.prototype.hasOwnProperty.call(data.k[t],"s")?data.k[t].s:data.k[t-1].e;for(r=s.length,i=0;i<r;i+=1)e[i]=s[i],e.value[i]=s[i];return e}function framesToTime(t,e){return e||(e=elem.comp.globalData.frameRate),t/e}function timeToFrames(t,e){return t||0===t||(t=time),e||(e=elem.comp.globalData.frameRate),t*e}function seedRandom(t){BMMath.seedrandom(randSeed+t)}function sourceRectAtTime(){return elem.sourceRectAtTime()}function substring(t,e){return"string"==typeof value?void 0===e?value.substring(t):value.substring(t,e):""}function substr(t,e){return"string"==typeof value?void 0===e?value.substr(t):value.substr(t,e):""}function posterizeTime(t){time=0===t?0:Math.floor(time*t)/t,value=valueAtTime(time)}var index=elem.data.ind,hasParent=!(!elem.hierarchy||!elem.hierarchy.length),parent,randSeed=Math.floor(1e6*Math.random()),globalData=elem.globalData;function executeExpression(t){return value=t,this.frameExpressionId===elem.globalData.frameId&&"textSelector"!==this.propType?value:("textSelector"===this.propType&&(textIndex=this.textIndex,textTotal=this.textTotal,selectorValue=this.selectorValue),thisLayer||(text=elem.layerInterface.text,thisLayer=elem.layerInterface,thisComp=elem.comp.compInterface,toWorld=thisLayer.toWorld.bind(thisLayer),fromWorld=thisLayer.fromWorld.bind(thisLayer),fromComp=thisLayer.fromComp.bind(thisLayer),toComp=thisLayer.toComp.bind(thisLayer),mask=thisLayer.mask?thisLayer.mask.bind(thisLayer):null,fromCompToSurface=fromComp),transform||(transform=elem.layerInterface("ADBE Transform Group"),$bm_transform=transform,transform&&(anchorPoint=transform.anchorPoint)),4!==elemType||content||(content=thisLayer("ADBE Root Vectors Group")),effect||(effect=thisLayer(4)),(hasParent=!(!elem.hierarchy||!elem.hierarchy.length))&&!parent&&(parent=elem.hierarchy[0].layerInterface),time=this.comp.renderedFrame/this.comp.globalData.frameRate,_needsRandom&&seedRandom(randSeed+time),needsVelocity&&(velocity=velocityAtTime(time)),expression_function(),this.frameExpressionId=elem.globalData.frameId,scoped_bm_rt=scoped_bm_rt.propType===propTypes.SHAPE?scoped_bm_rt.v:scoped_bm_rt)}return executeExpression.__preventDeadCodeRemoval=[$bm_transform,anchorPoint,time,velocity,inPoint,outPoint,width,height,name,loop_in,loop_out,smooth,toComp,fromCompToSurface,toWorld,fromWorld,mask,position,rotation,scale,thisComp,numKeys,active,wiggle,loopInDuration,loopOutDuration,comp,lookAt,easeOut,easeIn,ease,nearestKey,key,text,textIndex,textTotal,selectorValue,framesToTime,timeToFrames,sourceRectAtTime,substring,substr,posterizeTime,index,globalData],executeExpression}return ob.initiateExpression=initiateExpression,ob.__preventDeadCodeRemoval=[window,document,XMLHttpRequest,fetch,frames,$bm_neg,add,$bm_sum,$bm_sub,$bm_mul,$bm_div,$bm_mod,clamp,radians_to_degrees,degreesToRadians,degrees_to_radians,normalize,rgbToHsl,hslToRgb,linear,random,createPath,_lottieGlobal],ob.resetFrame=resetFrame,ob}(),Expressions=function(){var t={};return t.initExpressions=function(t){var e=0,i=[];t.renderer.compInterface=CompExpressionInterface(t.renderer),t.renderer.globalData.projectInterface.registerComposition(t.renderer),t.renderer.globalData.pushExpression=function(){e+=1},t.renderer.globalData.popExpression=function(){0==(e-=1)&&function(){var t,e=i.length;for(t=0;t<e;t+=1)i[t].release();i.length=0}()},t.renderer.globalData.registerExpressionProperty=function(t){-1===i.indexOf(t)&&i.push(t)}},t.resetFrame=ExpressionManager.resetFrame,t}(),MaskManagerInterface=function(){function t(t,e){this._mask=t,this._data=e}Object.defineProperty(t.prototype,"maskPath",{get:function(){return this._mask.prop.k&&this._mask.prop.getValue(),this._mask.prop}}),Object.defineProperty(t.prototype,"maskOpacity",{get:function(){return this._mask.op.k&&this._mask.op.getValue(),100*this._mask.op.v}});return function(e){var i,r=createSizedArray(e.viewData.length),s=e.viewData.length;for(i=0;i<s;i+=1)r[i]=new t(e.viewData[i],e.masksProperties[i]);return function(t){for(i=0;i<s;){if(e.masksProperties[i].nm===t)return r[i];i+=1}return null}}}(),ExpressionPropertyInterface=function(){var t={pv:0,v:0,mult:1},e={pv:[0,0,0],v:[0,0,0],mult:1};function i(t,e,i){Object.defineProperty(t,"velocity",{get:function(){return e.getVelocityAtTime(e.comp.currentFrame)}}),t.numKeys=e.keyframes?e.keyframes.length:0,t.key=function(r){if(!t.numKeys)return 0;var s="";s="s"in e.keyframes[r-1]?e.keyframes[r-1].s:"e"in e.keyframes[r-2]?e.keyframes[r-2].e:e.keyframes[r-2].s;var a="unidimensional"===i?new Number(s):Object.assign({},s);return a.time=e.keyframes[r-1].t/e.elem.comp.globalData.frameRate,a.value="unidimensional"===i?s[0]:s,a},t.valueAtTime=e.getValueAtTime,t.speedAtTime=e.getSpeedAtTime,t.velocityAtTime=e.getVelocityAtTime,t.propertyGroup=e.propertyGroup}function r(){return t}return function(s){return s?"unidimensional"===s.propType?function(e){e&&"pv"in e||(e=t);var r=1/e.mult,s=e.pv*r,a=new Number(s);return a.value=s,i(a,e,"unidimensional"),function(){return e.k&&e.getValue(),s=e.v*r,a.value!==s&&((a=new Number(s)).value=s,i(a,e,"unidimensional")),a}}(s):function(t){t&&"pv"in t||(t=e);var r=1/t.mult,s=t.data&&t.data.l||t.pv.length,a=createTypedArray("float32",s),n=createTypedArray("float32",s);return a.value=n,i(a,t,"multidimensional"),function(){t.k&&t.getValue();for(var e=0;e<s;e+=1)n[e]=t.v[e]*r,a[e]=n[e];return a}}(s):r}}(),TransformExpressionInterface=function(t){function e(t){switch(t){case"scale":case"Scale":case"ADBE Scale":case 6:return e.scale;case"rotation":case"Rotation":case"ADBE Rotation":case"ADBE Rotate Z":case 10:return e.rotation;case"ADBE Rotate X":return e.xRotation;case"ADBE Rotate Y":return e.yRotation;case"position":case"Position":case"ADBE Position":case 2:return e.position;case"ADBE Position_0":return e.xPosition;case"ADBE Position_1":return e.yPosition;case"ADBE Position_2":return e.zPosition;case"anchorPoint":case"AnchorPoint":case"Anchor Point":case"ADBE AnchorPoint":case 1:return e.anchorPoint;case"opacity":case"Opacity":case 11:return e.opacity;default:return null}}var i,r,s,a;return Object.defineProperty(e,"rotation",{get:ExpressionPropertyInterface(t.r||t.rz)}),Object.defineProperty(e,"zRotation",{get:ExpressionPropertyInterface(t.rz||t.r)}),Object.defineProperty(e,"xRotation",{get:ExpressionPropertyInterface(t.rx)}),Object.defineProperty(e,"yRotation",{get:ExpressionPropertyInterface(t.ry)}),Object.defineProperty(e,"scale",{get:ExpressionPropertyInterface(t.s)}),t.p?a=ExpressionPropertyInterface(t.p):(i=ExpressionPropertyInterface(t.px),r=ExpressionPropertyInterface(t.py),t.pz&&(s=ExpressionPropertyInterface(t.pz))),Object.defineProperty(e,"position",{get:function(){return t.p?a():[i(),r(),s?s():0]}}),Object.defineProperty(e,"xPosition",{get:ExpressionPropertyInterface(t.px)}),Object.defineProperty(e,"yPosition",{get:ExpressionPropertyInterface(t.py)}),Object.defineProperty(e,"zPosition",{get:ExpressionPropertyInterface(t.pz)}),Object.defineProperty(e,"anchorPoint",{get:ExpressionPropertyInterface(t.a)}),Object.defineProperty(e,"opacity",{get:ExpressionPropertyInterface(t.o)}),Object.defineProperty(e,"skew",{get:ExpressionPropertyInterface(t.sk)}),Object.defineProperty(e,"skewAxis",{get:ExpressionPropertyInterface(t.sa)}),Object.defineProperty(e,"orientation",{get:ExpressionPropertyInterface(t.or)}),e},LayerExpressionInterface=function(){function t(t){var e=new Matrix;void 0!==t?this._elem.finalTransform.mProp.getValueAtTime(t).clone(e):this._elem.finalTransform.mProp.applyToMatrix(e);return e}function e(t,e){var i=this.getMatrix(e);return i.props[12]=0,i.props[13]=0,i.props[14]=0,this.applyPoint(i,t)}function i(t,e){var i=this.getMatrix(e);return this.applyPoint(i,t)}function r(t,e){var i=this.getMatrix(e);return i.props[12]=0,i.props[13]=0,i.props[14]=0,this.invertPoint(i,t)}function s(t,e){var i=this.getMatrix(e);return this.invertPoint(i,t)}function a(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(t)}return t.applyToPointArray(e[0],e[1],e[2]||0)}function n(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(t)}return t.inversePoint(e)}function o(t){var e=new Matrix;if(e.reset(),this._elem.finalTransform.mProp.applyToMatrix(e),this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(e);return e.inversePoint(t)}return e.inversePoint(t)}function h(){return[1,1,1,1]}return function(l){var p;function f(t){switch(t){case"ADBE Root Vectors Group":case"Contents":case 2:return f.shapeInterface;case 1:case 6:case"Transform":case"transform":case"ADBE Transform Group":return p;case 4:case"ADBE Effect Parade":case"effects":case"Effects":return f.effect;case"ADBE Text Properties":return f.textInterface;default:return null}}f.getMatrix=t,f.invertPoint=n,f.applyPoint=a,f.toWorld=i,f.toWorldVec=e,f.fromWorld=s,f.fromWorldVec=r,f.toComp=i,f.fromComp=o,f.sampleImage=h,f.sourceRectAtTime=l.sourceRectAtTime.bind(l),f._elem=l;var m=getDescriptor(p=TransformExpressionInterface(l.finalTransform.mProp),"anchorPoint");return Object.defineProperties(f,{hasParent:{get:function(){return l.hierarchy.length}},parent:{get:function(){return l.hierarchy[0].layerInterface}},rotation:getDescriptor(p,"rotation"),scale:getDescriptor(p,"scale"),position:getDescriptor(p,"position"),opacity:getDescriptor(p,"opacity"),anchorPoint:m,anchor_point:m,transform:{get:function(){return p}},active:{get:function(){return l.isInRange}}}),f.startTime=l.data.st,f.index=l.data.ind,f.source=l.data.refId,f.height=0===l.data.ty?l.data.h:100,f.width=0===l.data.ty?l.data.w:100,f.inPoint=l.data.ip/l.comp.globalData.frameRate,f.outPoint=l.data.op/l.comp.globalData.frameRate,f._name=l.data.nm,f.registerMaskInterface=function(t){f.mask=new MaskManagerInterface(t,l)},f.registerEffectsInterface=function(t){f.effect=t},f}}(),propertyGroupFactory=function(t,e){return function(i){return(i=void 0===i?1:i)<=0?t:e(i-1)}},PropertyInterface=function(t,e){var i={_name:t};return function(t){return(t=void 0===t?1:t)<=0?i:e(t-1)}},EffectsExpressionInterface=function(){function t(i,r,s,a){function n(t){for(var e=i.ef,r=0,s=e.length;r<s;){if(t===e[r].nm||t===e[r].mn||t===e[r].ix)return 5===e[r].ty?l[r]:l[r]();r+=1}throw new Error}var o,h=propertyGroupFactory(n,s),l=[],p=i.ef.length;for(o=0;o<p;o+=1)5===i.ef[o].ty?l.push(t(i.ef[o],r.effectElements[o],r.effectElements[o].propertyGroup,a)):l.push(e(r.effectElements[o],i.ef[o].ty,a,h));return"ADBE Color Control"===i.mn&&Object.defineProperty(n,"color",{get:function(){return l[0]()}}),Object.defineProperties(n,{numProperties:{get:function(){return i.np}},_name:{value:i.nm},propertyGroup:{value:h}}),n.enabled=0!==i.en,n.active=n.enabled,n}function e(t,e,i,r){var s=ExpressionPropertyInterface(t.p);return t.p.setGroupProperty&&t.p.setGroupProperty(PropertyInterface("",r)),function(){return 10===e?i.comp.compInterface(t.p.v):s()}}return{createEffectsInterface:function(e,i){if(e.effectsManager){var r,s=[],a=e.data.ef,n=e.effectsManager.effectElements.length;for(r=0;r<n;r+=1)s.push(t(a[r],e.effectsManager.effectElements[r],i,e));var o=e.data.ef||[],h=function(t){for(r=0,n=o.length;r<n;){if(t===o[r].nm||t===o[r].mn||t===o[r].ix)return s[r];r+=1}return null};return Object.defineProperty(h,"numProperties",{get:function(){return o.length}}),h}return null}}}(),ShapePathInterface=function(t,e,i){var r=e.sh;function s(t){return"Shape"===t||"shape"===t||"Path"===t||"path"===t||"ADBE Vector Shape"===t||2===t?s.path:null}var a=propertyGroupFactory(s,i);return r.setGroupProperty(PropertyInterface("Path",a)),Object.defineProperties(s,{path:{get:function(){return r.k&&r.getValue(),r}},shape:{get:function(){return r.k&&r.getValue(),r}},_name:{value:t.nm},ix:{value:t.ix},propertyIndex:{value:t.ix},mn:{value:t.mn},propertyGroup:{value:i}}),s},ShapeExpressionInterface=function(){function t(t,o,c){var d,u=[],y=t?t.length:0;for(d=0;d<y;d+=1)"gr"===t[d].ty?u.push(e(t[d],o[d],c)):"fl"===t[d].ty?u.push(i(t[d],o[d],c)):"st"===t[d].ty?u.push(a(t[d],o[d],c)):"tm"===t[d].ty?u.push(n(t[d],o[d],c)):"tr"===t[d].ty||("el"===t[d].ty?u.push(h(t[d],o[d],c)):"sr"===t[d].ty?u.push(l(t[d],o[d],c)):"sh"===t[d].ty?u.push(ShapePathInterface(t[d],o[d],c)):"rc"===t[d].ty?u.push(p(t[d],o[d],c)):"rd"===t[d].ty?u.push(f(t[d],o[d],c)):"rp"===t[d].ty?u.push(m(t[d],o[d],c)):"gf"===t[d].ty?u.push(r(t[d],o[d],c)):u.push(s(t[d],o[d])));return u}function e(e,i,r){var s=function(t){switch(t){case"ADBE Vectors Group":case"Contents":case 2:return s.content;default:return s.transform}};s.propertyGroup=propertyGroupFactory(s,r);var a=function(e,i,r){var s,a=function(t){for(var e=0,i=s.length;e<i;){if(s[e]._name===t||s[e].mn===t||s[e].propertyIndex===t||s[e].ix===t||s[e].ind===t)return s[e];e+=1}return"number"==typeof t?s[t-1]:null};a.propertyGroup=propertyGroupFactory(a,r),s=t(e.it,i.it,a.propertyGroup),a.numProperties=s.length;var n=o(e.it[e.it.length-1],i.it[i.it.length-1],a.propertyGroup);return a.transform=n,a.propertyIndex=e.cix,a._name=e.nm,a}(e,i,s.propertyGroup),n=o(e.it[e.it.length-1],i.it[i.it.length-1],s.propertyGroup);return s.content=a,s.transform=n,Object.defineProperty(s,"_name",{get:function(){return e.nm}}),s.numProperties=e.np,s.propertyIndex=e.ix,s.nm=e.nm,s.mn=e.mn,s}function i(t,e,i){function r(t){return"Color"===t||"color"===t?r.color:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r}function r(t,e,i){function r(t){return"Start Point"===t||"start point"===t?r.startPoint:"End Point"===t||"end point"===t?r.endPoint:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{startPoint:{get:ExpressionPropertyInterface(e.s)},endPoint:{get:ExpressionPropertyInterface(e.e)},opacity:{get:ExpressionPropertyInterface(e.o)},type:{get:function(){return"a"}},_name:{value:t.nm},mn:{value:t.mn}}),e.s.setGroupProperty(PropertyInterface("Start Point",i)),e.e.setGroupProperty(PropertyInterface("End Point",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r}function s(){return function(){return null}}function a(t,e,i){var r,s=propertyGroupFactory(l,i),a=propertyGroupFactory(h,s);function n(i){Object.defineProperty(h,t.d[i].nm,{get:ExpressionPropertyInterface(e.d.dataProps[i].p)})}var o=t.d?t.d.length:0,h={};for(r=0;r<o;r+=1)n(r),e.d.dataProps[r].p.setGroupProperty(a);function l(t){return"Color"===t||"color"===t?l.color:"Opacity"===t||"opacity"===t?l.opacity:"Stroke Width"===t||"stroke width"===t?l.strokeWidth:null}return Object.defineProperties(l,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},strokeWidth:{get:ExpressionPropertyInterface(e.w)},dash:{get:function(){return h}},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",s)),e.o.setGroupProperty(PropertyInterface("Opacity",s)),e.w.setGroupProperty(PropertyInterface("Stroke Width",s)),l}function n(t,e,i){function r(e){return e===t.e.ix||"End"===e||"end"===e?r.end:e===t.s.ix?r.start:e===t.o.ix?r.offset:null}var s=propertyGroupFactory(r,i);return r.propertyIndex=t.ix,e.s.setGroupProperty(PropertyInterface("Start",s)),e.e.setGroupProperty(PropertyInterface("End",s)),e.o.setGroupProperty(PropertyInterface("Offset",s)),r.propertyIndex=t.ix,r.propertyGroup=i,Object.defineProperties(r,{start:{get:ExpressionPropertyInterface(e.s)},end:{get:ExpressionPropertyInterface(e.e)},offset:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm}}),r.mn=t.mn,r}function o(t,e,i){function r(e){return t.a.ix===e||"Anchor Point"===e?r.anchorPoint:t.o.ix===e||"Opacity"===e?r.opacity:t.p.ix===e||"Position"===e?r.position:t.r.ix===e||"Rotation"===e||"ADBE Vector Rotation"===e?r.rotation:t.s.ix===e||"Scale"===e?r.scale:t.sk&&t.sk.ix===e||"Skew"===e?r.skew:t.sa&&t.sa.ix===e||"Skew Axis"===e?r.skewAxis:null}var s=propertyGroupFactory(r,i);return e.transform.mProps.o.setGroupProperty(PropertyInterface("Opacity",s)),e.transform.mProps.p.setGroupProperty(PropertyInterface("Position",s)),e.transform.mProps.a.setGroupProperty(PropertyInterface("Anchor Point",s)),e.transform.mProps.s.setGroupProperty(PropertyInterface("Scale",s)),e.transform.mProps.r.setGroupProperty(PropertyInterface("Rotation",s)),e.transform.mProps.sk&&(e.transform.mProps.sk.setGroupProperty(PropertyInterface("Skew",s)),e.transform.mProps.sa.setGroupProperty(PropertyInterface("Skew Angle",s))),e.transform.op.setGroupProperty(PropertyInterface("Opacity",s)),Object.defineProperties(r,{opacity:{get:ExpressionPropertyInterface(e.transform.mProps.o)},position:{get:ExpressionPropertyInterface(e.transform.mProps.p)},anchorPoint:{get:ExpressionPropertyInterface(e.transform.mProps.a)},scale:{get:ExpressionPropertyInterface(e.transform.mProps.s)},rotation:{get:ExpressionPropertyInterface(e.transform.mProps.r)},skew:{get:ExpressionPropertyInterface(e.transform.mProps.sk)},skewAxis:{get:ExpressionPropertyInterface(e.transform.mProps.sa)},_name:{value:t.nm}}),r.ty="tr",r.mn=t.mn,r.propertyGroup=i,r}function h(t,e,i){function r(e){return t.p.ix===e?r.position:t.s.ix===e?r.size:null}var s=propertyGroupFactory(r,i);r.propertyIndex=t.ix;var a="tm"===e.sh.ty?e.sh.prop:e.sh;return a.s.setGroupProperty(PropertyInterface("Size",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),Object.defineProperties(r,{size:{get:ExpressionPropertyInterface(a.s)},position:{get:ExpressionPropertyInterface(a.p)},_name:{value:t.nm}}),r.mn=t.mn,r}function l(t,e,i){function r(e){return t.p.ix===e?r.position:t.r.ix===e?r.rotation:t.pt.ix===e?r.points:t.or.ix===e||"ADBE Vector Star Outer Radius"===e?r.outerRadius:t.os.ix===e?r.outerRoundness:!t.ir||t.ir.ix!==e&&"ADBE Vector Star Inner Radius"!==e?t.is&&t.is.ix===e?r.innerRoundness:null:r.innerRadius}var s=propertyGroupFactory(r,i),a="tm"===e.sh.ty?e.sh.prop:e.sh;return r.propertyIndex=t.ix,a.or.setGroupProperty(PropertyInterface("Outer Radius",s)),a.os.setGroupProperty(PropertyInterface("Outer Roundness",s)),a.pt.setGroupProperty(PropertyInterface("Points",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),t.ir&&(a.ir.setGroupProperty(PropertyInterface("Inner Radius",s)),a.is.setGroupProperty(PropertyInterface("Inner Roundness",s))),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(a.p)},rotation:{get:ExpressionPropertyInterface(a.r)},points:{get:ExpressionPropertyInterface(a.pt)},outerRadius:{get:ExpressionPropertyInterface(a.or)},outerRoundness:{get:ExpressionPropertyInterface(a.os)},innerRadius:{get:ExpressionPropertyInterface(a.ir)},innerRoundness:{get:ExpressionPropertyInterface(a.is)},_name:{value:t.nm}}),r.mn=t.mn,r}function p(t,e,i){function r(e){return t.p.ix===e?r.position:t.r.ix===e?r.roundness:t.s.ix===e||"Size"===e||"ADBE Vector Rect Size"===e?r.size:null}var s=propertyGroupFactory(r,i),a="tm"===e.sh.ty?e.sh.prop:e.sh;return r.propertyIndex=t.ix,a.p.setGroupProperty(PropertyInterface("Position",s)),a.s.setGroupProperty(PropertyInterface("Size",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(a.p)},roundness:{get:ExpressionPropertyInterface(a.r)},size:{get:ExpressionPropertyInterface(a.s)},_name:{value:t.nm}}),r.mn=t.mn,r}function f(t,e,i){function r(e){return t.r.ix===e||"Round Corners 1"===e?r.radius:null}var s=propertyGroupFactory(r,i),a=e;return r.propertyIndex=t.ix,a.rd.setGroupProperty(PropertyInterface("Radius",s)),Object.defineProperties(r,{radius:{get:ExpressionPropertyInterface(a.rd)},_name:{value:t.nm}}),r.mn=t.mn,r}function m(t,e,i){function r(e){return t.c.ix===e||"Copies"===e?r.copies:t.o.ix===e||"Offset"===e?r.offset:null}var s=propertyGroupFactory(r,i),a=e;return r.propertyIndex=t.ix,a.c.setGroupProperty(PropertyInterface("Copies",s)),a.o.setGroupProperty(PropertyInterface("Offset",s)),Object.defineProperties(r,{copies:{get:ExpressionPropertyInterface(a.c)},offset:{get:ExpressionPropertyInterface(a.o)},_name:{value:t.nm}}),r.mn=t.mn,r}return function(e,i,r){var s;function a(t){if("number"==typeof t)return 0===(t=void 0===t?1:t)?r:s[t-1];for(var e=0,i=s.length;e<i;){if(s[e]._name===t)return s[e];e+=1}return null}return a.propertyGroup=propertyGroupFactory(a,(function(){return r})),s=t(e,i,a.propertyGroup),a.numProperties=s.length,a._name="Contents",a}}(),TextExpressionInterface=function(t){var e;function i(t){return"ADBE Text Document"===t?i.sourceText:null}return Object.defineProperty(i,"sourceText",{get:function(){t.textProperty.getValue();var i=t.textProperty.currentData.t;return e&&i===e.value||((e=new String(i)).value=i||new String(i),Object.defineProperty(e,"style",{get:function(){return{fillColor:t.textProperty.currentData.fc}}})),e}}),i};function _typeof(t){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof(t)}var FootageInterface=(dataInterfaceFactory=function(t){function e(t){return"Outline"===t?e.outlineInterface():null}return e._name="Outline",e.outlineInterface=function(t){var e="",i=t.getFootageData();function r(t){if(i[t])return e=t,"object"===_typeof(i=i[t])?r:i;var s=t.indexOf(e);if(-1!==s){var a=parseInt(t.substr(s+e.length),10);return"object"===_typeof(i=i[a])?r:i}return""}return function(){return e="",i=t.getFootageData(),r}}(t),e},function(t){function e(t){return"Data"===t?e.dataInterface:null}return e._name="Data",e.dataInterface=dataInterfaceFactory(t),e}),dataInterfaceFactory,interfaces={layer:LayerExpressionInterface,effects:EffectsExpressionInterface,comp:CompExpressionInterface,shape:ShapeExpressionInterface,text:TextExpressionInterface,footage:FootageInterface};function getInterface(t){return interfaces[t]||null}var expressionHelpers={searchExpressions:function(t,e,i){e.x&&(i.k=!0,i.x=!0,i.initiateExpression=ExpressionManager.initiateExpression,i.effectsSequence.push(i.initiateExpression(t,e,i).bind(i)))},getSpeedAtTime:function(t){var e=this.getValueAtTime(t),i=this.getValueAtTime(t+-.01),r=0;if(e.length){var s;for(s=0;s<e.length;s+=1)r+=Math.pow(i[s]-e[s],2);r=100*Math.sqrt(r)}else r=0;return r},getVelocityAtTime:function(t){if(void 0!==this.vel)return this.vel;var e,i,r=-.001,s=this.getValueAtTime(t),a=this.getValueAtTime(t+r);if(s.length)for(e=createTypedArray("float32",s.length),i=0;i<s.length;i+=1)e[i]=(a[i]-s[i])/r;else e=(a-s)/r;return e},getValueAtTime:function(t){return t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastFrame&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastFrame<t?this._cachingAtTime.lastIndex:0,this._cachingAtTime.value=this.interpolateValue(t,this._cachingAtTime),this._cachingAtTime.lastFrame=t),this._cachingAtTime.value},getStaticValueAtTime:function(){return this.pv},setGroupProperty:function(t){this.propertyGroup=t}};function addPropertyDecorator(){function t(t,e,i){if(!this.k||!this.keyframes)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[l.length-1].t;if(h<=p)return this.pv;if(i?s=p-(r=e?Math.abs(p-this.elem.comp.globalData.frameRate*e):Math.max(0,p-this.elem.data.ip)):((!e||e>l.length-1)&&(e=l.length-1),r=p-(s=l[l.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/r)%2!=0)return this.getValueAtTime((r-(h-s)%r+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),m=this.getValueAtTime(p/this.comp.globalData.frameRate,0),c=this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0),d=Math.floor((h-s)/r);if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=(m[a]-f[a])*d+c[a];return o}return(m-f)*d+c}if("continue"===t){var u=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p-.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*((h-p)/this.comp.globalData.frameRate)/5e-4;return o}return u+(h-p)/.001*(u-y)}}return this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0)}function e(t,e,i){if(!this.k)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[0].t;if(h>=p)return this.pv;if(i?s=p+(r=e?Math.abs(this.elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-p)):((!e||e>l.length-1)&&(e=l.length-1),r=(s=l[e].t)-p),"pingpong"===t){if(Math.floor((p-h)/r)%2==0)return this.getValueAtTime(((p-h)%r+p)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(p/this.comp.globalData.frameRate,0),m=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime((r-(p-h)%r+p)/this.comp.globalData.frameRate,0),d=Math.floor((p-h)/r)+1;if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=c[a]-(m[a]-f[a])*d;return o}return c-(m-f)*d}if("continue"===t){var u=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p+.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*(p-h)/.001;return o}return u+(u-y)*(p-h)/.001}}return this.getValueAtTime((r-((p-h)%r+p))/this.comp.globalData.frameRate,0)}function i(t,e){if(!this.k)return this.pv;if(t=.5*(t||.4),(e=Math.floor(e||5))<=1)return this.pv;var i,r,s=this.comp.renderedFrame/this.comp.globalData.frameRate,a=s-t,n=e>1?(s+t-a)/(e-1):1,o=0,h=0;for(i=this.pv.length?createTypedArray("float32",this.pv.length):0;o<e;){if(r=this.getValueAtTime(a+o*n),this.pv.length)for(h=0;h<this.pv.length;h+=1)i[h]+=r[h];else i+=r;o+=1}if(this.pv.length)for(h=0;h<this.pv.length;h+=1)i[h]/=e;else i/=e;return i}function r(t){this._transformCachingAtTime||(this._transformCachingAtTime={v:new Matrix});var e=this._transformCachingAtTime.v;if(e.cloneFromProps(this.pre.props),this.appliedTransformations<1){var i=this.a.getValueAtTime(t);e.translate(-i[0]*this.a.mult,-i[1]*this.a.mult,i[2]*this.a.mult)}if(this.appliedTransformations<2){var r=this.s.getValueAtTime(t);e.scale(r[0]*this.s.mult,r[1]*this.s.mult,r[2]*this.s.mult)}if(this.sk&&this.appliedTransformations<3){var s=this.sk.getValueAtTime(t),a=this.sa.getValueAtTime(t);e.skewFromAxis(-s*this.sk.mult,a*this.sa.mult)}if(this.r&&this.appliedTransformations<4){var n=this.r.getValueAtTime(t);e.rotate(-n*this.r.mult)}else if(!this.r&&this.appliedTransformations<4){var o=this.rz.getValueAtTime(t),h=this.ry.getValueAtTime(t),l=this.rx.getValueAtTime(t),p=this.or.getValueAtTime(t);e.rotateZ(-o*this.rz.mult).rotateY(h*this.ry.mult).rotateX(l*this.rx.mult).rotateZ(-p[2]*this.or.mult).rotateY(p[1]*this.or.mult).rotateX(p[0]*this.or.mult)}if(this.data.p&&this.data.p.s){var f=this.px.getValueAtTime(t),m=this.py.getValueAtTime(t);if(this.data.p.z){var c=this.pz.getValueAtTime(t);e.translate(f*this.px.mult,m*this.py.mult,-c*this.pz.mult)}else e.translate(f*this.px.mult,m*this.py.mult,0)}else{var d=this.p.getValueAtTime(t);e.translate(d[0]*this.p.mult,d[1]*this.p.mult,-d[2]*this.p.mult)}return e}function s(){return this.v.clone(new Matrix)}var a=TransformPropertyFactory.getTransformProperty;TransformPropertyFactory.getTransformProperty=function(t,e,i){var n=a(t,e,i);return n.dynamicProperties.length?n.getValueAtTime=r.bind(n):n.getValueAtTime=s.bind(n),n.setGroupProperty=expressionHelpers.setGroupProperty,n};var n=PropertyFactory.getProp;PropertyFactory.getProp=function(r,s,a,o,h){var l=n(r,s,a,o,h);l.kf?l.getValueAtTime=expressionHelpers.getValueAtTime.bind(l):l.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(l),l.setGroupProperty=expressionHelpers.setGroupProperty,l.loopOut=t,l.loopIn=e,l.smooth=i,l.getVelocityAtTime=expressionHelpers.getVelocityAtTime.bind(l),l.getSpeedAtTime=expressionHelpers.getSpeedAtTime.bind(l),l.numKeys=1===s.a?s.k.length:0,l.propertyIndex=s.ix;var p=0;return 0!==a&&(p=createTypedArray("float32",1===s.a?s.k[0].s.length:s.k.length)),l._cachingAtTime={lastFrame:initialDefaultFrame,lastIndex:0,value:p},expressionHelpers.searchExpressions(r,s,l),l.k&&h.addDynamicProperty(l),l};var o=ShapePropertyFactory.getConstructorFunction(),h=ShapePropertyFactory.getKeyframedConstructorFunction();function l(){}l.prototype={vertices:function(t,e){this.k&&this.getValue();var i,r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0));var s=r._length,a=r[t],n=r.v,o=createSizedArray(s);for(i=0;i<s;i+=1)o[i]="i"===t||"o"===t?[a[i][0]-n[i][0],a[i][1]-n[i][1]]:[a[i][0],a[i][1]];return o},points:function(t){return this.vertices("v",t)},inTangents:function(t){return this.vertices("i",t)},outTangents:function(t){return this.vertices("o",t)},isClosed:function(){return this.v.c},pointOnPath:function(t,e){var i=this.v;void 0!==e&&(i=this.getValueAtTime(e,0)),this._segmentsLength||(this._segmentsLength=bez.getSegmentsLength(i));for(var r,s=this._segmentsLength,a=s.lengths,n=s.totalLength*t,o=0,h=a.length,l=0;o<h;){if(l+a[o].addedLength>n){var p=o,f=i.c&&o===h-1?0:o+1,m=(n-l)/a[o].addedLength;r=bez.getPointInSegment(i.v[p],i.v[f],i.o[p],i.i[f],m,a[o]);break}l+=a[o].addedLength,o+=1}return r||(r=i.c?[i.v[0][0],i.v[0][1]]:[i.v[i._length-1][0],i.v[i._length-1][1]]),r},vectorOnPath:function(t,e,i){1==t?t=this.v.c:0==t&&(t=.999);var r=this.pointOnPath(t,e),s=this.pointOnPath(t+.001,e),a=s[0]-r[0],n=s[1]-r[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return 0===o?[0,0]:"tangent"===i?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([l],o),extendPrototype([l],h),h.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shapePool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime<t?this._caching.lastIndex:0,this._cachingAtTime.lastTime=t,this.interpolateShape(t,this._cachingAtTime.shapeValue,this._cachingAtTime)),this._cachingAtTime.shapeValue},h.prototype.initiateExpression=ExpressionManager.initiateExpression;var p=ShapePropertyFactory.getShapeProp;ShapePropertyFactory.getShapeProp=function(t,e,i,r,s){var a=p(t,e,i,r,s);return a.propertyIndex=e.ix,a.lock=!1,3===i?expressionHelpers.searchExpressions(t,e.pt,a):4===i&&expressionHelpers.searchExpressions(t,e.ks,a),a.k&&t.addDynamicProperty(a),a}}function initialize$1(){addPropertyDecorator()}function addDecorator(){TextProperty.prototype.getExpressionValue=function(t,e){var i=this.calculateExpression(e);if(t.t!==i){var r={};return this.copyData(r,t),r.t=i.toString(),r.__complete=!1,r}return t},TextProperty.prototype.searchProperty=function(){var t=this.searchKeyframes(),e=this.searchExpressions();return this.kf=t||e,this.kf},TextProperty.prototype.searchExpressions=function(){return this.data.d.x?(this.calculateExpression=ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this),this.addEffect(this.getExpressionValue.bind(this)),!0):null}}function initialize(){addDecorator()}function SVGComposableEffect(){}SVGComposableEffect.prototype={createMergeNode:function(t,e){var i,r,s=createNS("feMerge");for(s.setAttribute("result",t),r=0;r<e.length;r+=1)(i=createNS("feMergeNode")).setAttribute("in",e[r]),s.appendChild(i),s.appendChild(i);return s}};var linearFilterValue="0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0";function SVGTintFilter(t,e,i,r,s){this.filterManager=e;var a=createNS("feColorMatrix");a.setAttribute("type","matrix"),a.setAttribute("color-interpolation-filters","linearRGB"),a.setAttribute("values",linearFilterValue+" 1 0"),this.linearFilter=a,a.setAttribute("result",r+"_tint_1"),t.appendChild(a),(a=createNS("feColorMatrix")).setAttribute("type","matrix"),a.setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),a.setAttribute("result",r+"_tint_2"),t.appendChild(a),this.matrixFilter=a;var n=this.createMergeNode(r,[s,r+"_tint_1",r+"_tint_2"]);t.appendChild(n)}function SVGFillFilter(t,e,i,r){this.filterManager=e;var s=createNS("feColorMatrix");s.setAttribute("type","matrix"),s.setAttribute("color-interpolation-filters","sRGB"),s.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),s.setAttribute("result",r),t.appendChild(s),this.matrixFilter=s}function SVGStrokeEffect(t,e,i){this.initialized=!1,this.filterManager=e,this.elem=i,this.paths=[]}function SVGTritoneFilter(t,e,i,r){this.filterManager=e;var s=createNS("feColorMatrix");s.setAttribute("type","matrix"),s.setAttribute("color-interpolation-filters","linearRGB"),s.setAttribute("values","0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0"),t.appendChild(s);var a=createNS("feComponentTransfer");a.setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("result",r),this.matrixFilter=a;var n=createNS("feFuncR");n.setAttribute("type","table"),a.appendChild(n),this.feFuncR=n;var o=createNS("feFuncG");o.setAttribute("type","table"),a.appendChild(o),this.feFuncG=o;var h=createNS("feFuncB");h.setAttribute("type","table"),a.appendChild(h),this.feFuncB=h,t.appendChild(a)}function SVGProLevelsFilter(t,e,i,r){this.filterManager=e;var s=this.filterManager.effectElements,a=createNS("feComponentTransfer");(s[10].p.k||0!==s[10].p.v||s[11].p.k||1!==s[11].p.v||s[12].p.k||1!==s[12].p.v||s[13].p.k||0!==s[13].p.v||s[14].p.k||1!==s[14].p.v)&&(this.feFuncR=this.createFeFunc("feFuncR",a)),(s[17].p.k||0!==s[17].p.v||s[18].p.k||1!==s[18].p.v||s[19].p.k||1!==s[19].p.v||s[20].p.k||0!==s[20].p.v||s[21].p.k||1!==s[21].p.v)&&(this.feFuncG=this.createFeFunc("feFuncG",a)),(s[24].p.k||0!==s[24].p.v||s[25].p.k||1!==s[25].p.v||s[26].p.k||1!==s[26].p.v||s[27].p.k||0!==s[27].p.v||s[28].p.k||1!==s[28].p.v)&&(this.feFuncB=this.createFeFunc("feFuncB",a)),(s[31].p.k||0!==s[31].p.v||s[32].p.k||1!==s[32].p.v||s[33].p.k||1!==s[33].p.v||s[34].p.k||0!==s[34].p.v||s[35].p.k||1!==s[35].p.v)&&(this.feFuncA=this.createFeFunc("feFuncA",a)),(this.feFuncR||this.feFuncG||this.feFuncB||this.feFuncA)&&(a.setAttribute("color-interpolation-filters","sRGB"),t.appendChild(a)),(s[3].p.k||0!==s[3].p.v||s[4].p.k||1!==s[4].p.v||s[5].p.k||1!==s[5].p.v||s[6].p.k||0!==s[6].p.v||s[7].p.k||1!==s[7].p.v)&&((a=createNS("feComponentTransfer")).setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("result",r),t.appendChild(a),this.feFuncRComposed=this.createFeFunc("feFuncR",a),this.feFuncGComposed=this.createFeFunc("feFuncG",a),this.feFuncBComposed=this.createFeFunc("feFuncB",a))}function SVGDropShadowEffect(t,e,i,r,s){var a=e.container.globalData.renderConfig.filterSize,n=e.data.fs||a;t.setAttribute("x",n.x||a.x),t.setAttribute("y",n.y||a.y),t.setAttribute("width",n.width||a.width),t.setAttribute("height",n.height||a.height),this.filterManager=e;var o=createNS("feGaussianBlur");o.setAttribute("in","SourceAlpha"),o.setAttribute("result",r+"_drop_shadow_1"),o.setAttribute("stdDeviation","0"),this.feGaussianBlur=o,t.appendChild(o);var h=createNS("feOffset");h.setAttribute("dx","25"),h.setAttribute("dy","0"),h.setAttribute("in",r+"_drop_shadow_1"),h.setAttribute("result",r+"_drop_shadow_2"),this.feOffset=h,t.appendChild(h);var l=createNS("feFlood");l.setAttribute("flood-color","#00ff00"),l.setAttribute("flood-opacity","1"),l.setAttribute("result",r+"_drop_shadow_3"),this.feFlood=l,t.appendChild(l);var p=createNS("feComposite");p.setAttribute("in",r+"_drop_shadow_3"),p.setAttribute("in2",r+"_drop_shadow_2"),p.setAttribute("operator","in"),p.setAttribute("result",r+"_drop_shadow_4"),t.appendChild(p);var f=this.createMergeNode(r,[r+"_drop_shadow_4",s]);t.appendChild(f)}extendPrototype([SVGComposableEffect],SVGTintFilter),SVGTintFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=this.filterManager.effectElements[2].p.v/100;this.linearFilter.setAttribute("values",linearFilterValue+" "+r+" 0"),this.matrixFilter.setAttribute("values",i[0]-e[0]+" 0 0 0 "+e[0]+" "+(i[1]-e[1])+" 0 0 0 "+e[1]+" "+(i[2]-e[2])+" 0 0 0 "+e[2]+" 0 0 0 1 0")}},SVGFillFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[2].p.v,i=this.filterManager.effectElements[6].p.v;this.matrixFilter.setAttribute("values","0 0 0 0 "+e[0]+" 0 0 0 0 "+e[1]+" 0 0 0 0 "+e[2]+" 0 0 0 "+i+" 0")}},SVGStrokeEffect.prototype.initialize=function(){var t,e,i,r,s=this.elem.layerElement.children||this.elem.layerElement.childNodes;for(1===this.filterManager.effectElements[1].p.v?(r=this.elem.maskManager.masksProperties.length,i=0):r=(i=this.filterManager.effectElements[0].p.v-1)+1,(e=createNS("g")).setAttribute("fill","none"),e.setAttribute("stroke-linecap","round"),e.setAttribute("stroke-dashoffset",1);i<r;i+=1)t=createNS("path"),e.appendChild(t),this.paths.push({p:t,m:i});if(3===this.filterManager.effectElements[10].p.v){var a=createNS("mask"),n=createElementID();a.setAttribute("id",n),a.setAttribute("mask-type","alpha"),a.appendChild(e),this.elem.globalData.defs.appendChild(a);var o=createNS("g");for(o.setAttribute("mask","url("+getLocationHref()+"#"+n+")");s[0];)o.appendChild(s[0]);this.elem.layerElement.appendChild(o),this.masker=a,e.setAttribute("stroke","#fff")}else if(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v){if(2===this.filterManager.effectElements[10].p.v)for(s=this.elem.layerElement.children||this.elem.layerElement.childNodes;s.length;)this.elem.layerElement.removeChild(s[0]);this.elem.layerElement.appendChild(e),this.elem.layerElement.removeAttribute("mask"),e.setAttribute("stroke","#fff")}this.initialized=!0,this.pathMasker=e},SVGStrokeEffect.prototype.renderFrame=function(t){var e;this.initialized||this.initialize();var i,r,s=this.paths.length;for(e=0;e<s;e+=1)if(-1!==this.paths[e].m&&(i=this.elem.maskManager.viewData[this.paths[e].m],r=this.paths[e].p,(t||this.filterManager._mdf||i.prop._mdf)&&r.setAttribute("d",i.lastPath),t||this.filterManager.effectElements[9].p._mdf||this.filterManager.effectElements[4].p._mdf||this.filterManager.effectElements[7].p._mdf||this.filterManager.effectElements[8].p._mdf||i.prop._mdf)){var a;if(0!==this.filterManager.effectElements[7].p.v||100!==this.filterManager.effectElements[8].p.v){var n=.01*Math.min(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),o=.01*Math.max(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),h=r.getTotalLength();a="0 0 0 "+h*n+" ";var l,p=h*(o-n),f=1+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01,m=Math.floor(p/f);for(l=0;l<m;l+=1)a+="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01+" ";a+="0 "+10*h+" 0 0"}else a="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01;r.setAttribute("stroke-dasharray",a)}if((t||this.filterManager.effectElements[4].p._mdf)&&this.pathMasker.setAttribute("stroke-width",2*this.filterManager.effectElements[4].p.v),(t||this.filterManager.effectElements[6].p._mdf)&&this.pathMasker.setAttribute("opacity",this.filterManager.effectElements[6].p.v),(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v)&&(t||this.filterManager.effectElements[3].p._mdf)){var c=this.filterManager.effectElements[3].p.v;this.pathMasker.setAttribute("stroke","rgb("+bmFloor(255*c[0])+","+bmFloor(255*c[1])+","+bmFloor(255*c[2])+")")}},SVGTritoneFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=this.filterManager.effectElements[2].p.v,s=r[0]+" "+i[0]+" "+e[0],a=r[1]+" "+i[1]+" "+e[1],n=r[2]+" "+i[2]+" "+e[2];this.feFuncR.setAttribute("tableValues",s),this.feFuncG.setAttribute("tableValues",a),this.feFuncB.setAttribute("tableValues",n)}},SVGProLevelsFilter.prototype.createFeFunc=function(t,e){var i=createNS(t);return i.setAttribute("type","table"),e.appendChild(i),i},SVGProLevelsFilter.prototype.getTableValue=function(t,e,i,r,s){for(var a,n,o=0,h=Math.min(t,e),l=Math.max(t,e),p=Array.call(null,{length:256}),f=0,m=s-r,c=e-t;o<=256;)n=(a=o/256)<=h?c<0?s:r:a>=l?c<0?r:s:r+m*Math.pow((a-t)/c,1/i),p[f]=n,f+=1,o+=256/255;return p.join(" ")},SVGProLevelsFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e,i=this.filterManager.effectElements;this.feFuncRComposed&&(t||i[3].p._mdf||i[4].p._mdf||i[5].p._mdf||i[6].p._mdf||i[7].p._mdf)&&(e=this.getTableValue(i[3].p.v,i[4].p.v,i[5].p.v,i[6].p.v,i[7].p.v),this.feFuncRComposed.setAttribute("tableValues",e),this.feFuncGComposed.setAttribute("tableValues",e),this.feFuncBComposed.setAttribute("tableValues",e)),this.feFuncR&&(t||i[10].p._mdf||i[11].p._mdf||i[12].p._mdf||i[13].p._mdf||i[14].p._mdf)&&(e=this.getTableValue(i[10].p.v,i[11].p.v,i[12].p.v,i[13].p.v,i[14].p.v),this.feFuncR.setAttribute("tableValues",e)),this.feFuncG&&(t||i[17].p._mdf||i[18].p._mdf||i[19].p._mdf||i[20].p._mdf||i[21].p._mdf)&&(e=this.getTableValue(i[17].p.v,i[18].p.v,i[19].p.v,i[20].p.v,i[21].p.v),this.feFuncG.setAttribute("tableValues",e)),this.feFuncB&&(t||i[24].p._mdf||i[25].p._mdf||i[26].p._mdf||i[27].p._mdf||i[28].p._mdf)&&(e=this.getTableValue(i[24].p.v,i[25].p.v,i[26].p.v,i[27].p.v,i[28].p.v),this.feFuncB.setAttribute("tableValues",e)),this.feFuncA&&(t||i[31].p._mdf||i[32].p._mdf||i[33].p._mdf||i[34].p._mdf||i[35].p._mdf)&&(e=this.getTableValue(i[31].p.v,i[32].p.v,i[33].p.v,i[34].p.v,i[35].p.v),this.feFuncA.setAttribute("tableValues",e))}},extendPrototype([SVGComposableEffect],SVGDropShadowEffect),SVGDropShadowEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){if((t||this.filterManager.effectElements[4].p._mdf)&&this.feGaussianBlur.setAttribute("stdDeviation",this.filterManager.effectElements[4].p.v/4),t||this.filterManager.effectElements[0].p._mdf){var e=this.filterManager.effectElements[0].p.v;this.feFlood.setAttribute("flood-color",rgbToHex(Math.round(255*e[0]),Math.round(255*e[1]),Math.round(255*e[2])))}if((t||this.filterManager.effectElements[1].p._mdf)&&this.feFlood.setAttribute("flood-opacity",this.filterManager.effectElements[1].p.v/255),t||this.filterManager.effectElements[2].p._mdf||this.filterManager.effectElements[3].p._mdf){var i=this.filterManager.effectElements[3].p.v,r=(this.filterManager.effectElements[2].p.v-90)*degToRads,s=i*Math.cos(r),a=i*Math.sin(r);this.feOffset.setAttribute("dx",s),this.feOffset.setAttribute("dy",a)}}};var _svgMatteSymbols=[];function SVGMatte3Effect(t,e,i){this.initialized=!1,this.filterManager=e,this.filterElem=t,this.elem=i,i.matteElement=createNS("g"),i.matteElement.appendChild(i.layerElement),i.matteElement.appendChild(i.transformedElement),i.baseElement=i.matteElement}function SVGGaussianBlurEffect(t,e,i,r){t.setAttribute("x","-100%"),t.setAttribute("y","-100%"),t.setAttribute("width","300%"),t.setAttribute("height","300%"),this.filterManager=e;var s=createNS("feGaussianBlur");s.setAttribute("result",r),t.appendChild(s),this.feGaussianBlur=s}function TransformEffect(){}function SVGTransformEffect(t,e){this.init(e)}function CVTransformEffect(t){this.init(t)}return SVGMatte3Effect.prototype.findSymbol=function(t){for(var e=0,i=_svgMatteSymbols.length;e<i;){if(_svgMatteSymbols[e]===t)return _svgMatteSymbols[e];e+=1}return null},SVGMatte3Effect.prototype.replaceInParent=function(t,e){var i=t.layerElement.parentNode;if(i){for(var r,s=i.children,a=0,n=s.length;a<n&&s[a]!==t.layerElement;)a+=1;a<=n-2&&(r=s[a+1]);var o=createNS("use");o.setAttribute("href","#"+e),r?i.insertBefore(o,r):i.appendChild(o)}},SVGMatte3Effect.prototype.setElementAsMask=function(t,e){if(!this.findSymbol(e)){var i=createElementID(),r=createNS("mask");r.setAttribute("id",e.layerId),r.setAttribute("mask-type","alpha"),_svgMatteSymbols.push(e);var s=t.globalData.defs;s.appendChild(r);var a=createNS("symbol");a.setAttribute("id",i),this.replaceInParent(e,i),a.appendChild(e.layerElement),s.appendChild(a);var n=createNS("use");n.setAttribute("href","#"+i),r.appendChild(n),e.data.hd=!1,e.show()}t.setMatte(e.layerId)},SVGMatte3Effect.prototype.initialize=function(){for(var t=this.filterManager.effectElements[0].p.v,e=this.elem.comp.elements,i=0,r=e.length;i<r;)e[i]&&e[i].data.ind===t&&this.setElementAsMask(this.elem,e[i]),i+=1;this.initialized=!0},SVGMatte3Effect.prototype.renderFrame=function(){this.initialized||this.initialize()},SVGGaussianBlurEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=.3*this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=3==i?0:e,s=2==i?0:e;this.feGaussianBlur.setAttribute("stdDeviation",r+" "+s);var a=1==this.filterManager.effectElements[2].p.v?"wrap":"duplicate";this.feGaussianBlur.setAttribute("edgeMode",a)}},TransformEffect.prototype.init=function(t){this.effectsManager=t,this.type=effectTypes.TRANSFORM_EFFECT,this.matrix=new Matrix,this.opacity=-1,this._mdf=!1,this._opMdf=!1},TransformEffect.prototype.renderFrame=function(t){if(this._opMdf=!1,this._mdf=!1,t||this.effectsManager._mdf){var e=this.effectsManager.effectElements,i=e[0].p.v,r=e[1].p.v,s=1===e[2].p.v,a=e[3].p.v,n=s?a:e[4].p.v,o=e[5].p.v,h=e[6].p.v,l=e[7].p.v;this.matrix.reset(),this.matrix.translate(-i[0],-i[1],i[2]),this.matrix.scale(.01*n,.01*a,1),this.matrix.rotate(-l*degToRads),this.matrix.skewFromAxis(-o*degToRads,(h+90)*degToRads),this.matrix.translate(r[0],r[1],0),this._mdf=!0,this.opacity!==e[8].p.v&&(this.opacity=e[8].p.v,this._opMdf=!0)}},extendPrototype([TransformEffect],SVGTransformEffect),extendPrototype([TransformEffect],CVTransformEffect),registerRenderer("canvas",CanvasRenderer),registerRenderer("html",HybridRenderer),registerRenderer("svg",SVGRenderer),ShapeModifiers.registerModifier("tm",TrimModifier),ShapeModifiers.registerModifier("pb",PuckerAndBloatModifier),ShapeModifiers.registerModifier("rp",RepeaterModifier),ShapeModifiers.registerModifier("rd",RoundCornersModifier),ShapeModifiers.registerModifier("zz",ZigZagModifier),ShapeModifiers.registerModifier("op",OffsetPathModifier),setExpressionsPlugin(Expressions),setExpressionInterfaces(getInterface),initialize$1(),initialize(),registerEffect$1(20,SVGTintFilter,!0),registerEffect$1(21,SVGFillFilter,!0),registerEffect$1(22,SVGStrokeEffect,!1),registerEffect$1(23,SVGTritoneFilter,!0),registerEffect$1(24,SVGProLevelsFilter,!0),registerEffect$1(25,SVGDropShadowEffect,!0),registerEffect$1(28,SVGMatte3Effect,!1),registerEffect$1(29,SVGGaussianBlurEffect,!0),registerEffect$1(35,SVGTransformEffect,!1),registerEffect(35,CVTransformEffect),lottie}));
+"undefined"!=typeof document&&"undefined"!=typeof navigator&&function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lottie=e()}(this,(function(){"use strict";var svgNS="http://www.w3.org/2000/svg",locationHref="",_useWebWorker=!1,initialDefaultFrame=-999999,setWebWorker=function(t){_useWebWorker=!!t},getWebWorker=function(){return _useWebWorker},setLocationHref=function(t){locationHref=t},getLocationHref=function(){return locationHref};function createTag(t){return document.createElement(t)}function extendPrototype(t,e){var i,r,s=t.length;for(i=0;i<s;i+=1)for(var a in r=t[i].prototype)Object.prototype.hasOwnProperty.call(r,a)&&(e.prototype[a]=r[a])}function getDescriptor(t,e){return Object.getOwnPropertyDescriptor(t,e)}function createProxyFunction(t){function e(){}return e.prototype=t,e}var audioControllerFactory=function(){function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].pause()},resume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].resume()},setRate:function(t){var e,i=this.audios.length;for(e=0;e<i;e+=1)this.audios[e].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}}(),createTypedArray=function(){function t(t,e){var i,r=0,s=[];switch(t){case"int16":case"uint8c":i=1;break;default:i=1.1}for(r=0;r<e;r+=1)s.push(i);return s}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(e,i){return"float32"===e?new Float32Array(i):"int16"===e?new Int16Array(i):"uint8c"===e?new Uint8ClampedArray(i):t(e,i)}:t}();function createSizedArray(t){return Array.apply(null,{length:t})}function _typeof$6(t){return _typeof$6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$6(t)}var subframeEnabled=!0,expressionsPlugin=null,expressionsInterfaces=null,idPrefix$1="",isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),_shouldRoundValues=!1,bmPow=Math.pow,bmSqrt=Math.sqrt,bmFloor=Math.floor,bmMax=Math.max,bmMin=Math.min,BMMath={};function ProjectInterface$1(){return{}}!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],i=e.length;for(t=0;t<i;t+=1)BMMath[e[t]]=Math[e[t]]}(),BMMath.random=Math.random,BMMath.abs=function(t){if("object"===_typeof$6(t)&&t.length){var e,i=createSizedArray(t.length),r=t.length;for(e=0;e<r;e+=1)i[e]=Math.abs(t[e]);return i}return Math.abs(t)};var defaultCurveSegments=150,degToRads=Math.PI/180,roundCorner=.5519;function roundValues(t){_shouldRoundValues=!!t}function bmRnd(t){return _shouldRoundValues?Math.round(t):t}function styleDiv(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin="0 0",t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility="visible",t.style.webkitBackfaceVisibility="visible",t.style.transformStyle="preserve-3d",t.style.webkitTransformStyle="preserve-3d",t.style.mozTransformStyle="preserve-3d"}function BMEnterFrameEvent(t,e,i,r){this.type=t,this.currentTime=e,this.totalTime=i,this.direction=r<0?-1:1}function BMCompleteEvent(t,e){this.type=t,this.direction=e<0?-1:1}function BMCompleteLoopEvent(t,e,i,r){this.type=t,this.currentLoop=i,this.totalLoops=e,this.direction=r<0?-1:1}function BMSegmentStartEvent(t,e,i){this.type=t,this.firstFrame=e,this.totalFrames=i}function BMDestroyEvent(t,e){this.type=t,this.target=e}function BMRenderFrameErrorEvent(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function BMConfigErrorEvent(t){this.type="configError",this.nativeError=t}function BMAnimationConfigErrorEvent(t,e){this.type=t,this.nativeError=e}var createElementID=(_count=0,function(){return idPrefix$1+"__lottie_element_"+(_count+=1)}),_count;function HSVtoRGB(t,e,i){var r,s,a,n,o,h,l,p;switch(h=i*(1-e),l=i*(1-(o=6*t-(n=Math.floor(6*t)))*e),p=i*(1-(1-o)*e),n%6){case 0:r=i,s=p,a=h;break;case 1:r=l,s=i,a=h;break;case 2:r=h,s=i,a=p;break;case 3:r=h,s=l,a=i;break;case 4:r=p,s=h,a=i;break;case 5:r=i,s=h,a=l}return[r,s,a]}function RGBtoHSV(t,e,i){var r,s=Math.max(t,e,i),a=Math.min(t,e,i),n=s-a,o=0===s?0:n/s,h=s/255;switch(s){case a:r=0;break;case t:r=e-i+n*(e<i?6:0),r/=6*n;break;case e:r=i-t+2*n,r/=6*n;break;case i:r=t-e+4*n,r/=6*n}return[r,o,h]}function addSaturationToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[1]+=e,i[1]>1?i[1]=1:i[1]<=0&&(i[1]=0),HSVtoRGB(i[0],i[1],i[2])}function addBrightnessToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[2]+=e,i[2]>1?i[2]=1:i[2]<0&&(i[2]=0),HSVtoRGB(i[0],i[1],i[2])}function addHueToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[0]+=e/360,i[0]>1?i[0]-=1:i[0]<0&&(i[0]+=1),HSVtoRGB(i[0],i[1],i[2])}var rgbToHex=function(){var t,e,i=[];for(t=0;t<256;t+=1)e=t.toString(16),i[t]=1===e.length?"0"+e:e;return function(t,e,r){return t<0&&(t=0),e<0&&(e=0),r<0&&(r=0),"#"+i[t]+i[e]+i[r]}}(),setSubframeEnabled=function(t){subframeEnabled=!!t},getSubframeEnabled=function(){return subframeEnabled},setExpressionsPlugin=function(t){expressionsPlugin=t},getExpressionsPlugin=function(){return expressionsPlugin},setExpressionInterfaces=function(t){expressionsInterfaces=t},getExpressionInterfaces=function(){return expressionsInterfaces},setDefaultCurveSegments=function(t){defaultCurveSegments=t},getDefaultCurveSegments=function(){return defaultCurveSegments},setIdPrefix=function(t){idPrefix$1=t},getIdPrefix=function(){return idPrefix$1};function createNS(t){return document.createElementNS(svgNS,t)}function _typeof$5(t){return _typeof$5="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$5(t)}var dataManager=function(){var t,e,i=1,r=[],s={onmessage:function(){},postMessage:function(e){t({data:e})}},a={postMessage:function(t){s.onmessage({data:t})}};function n(){e||(e=function(e){if(window.Worker&&window.Blob&&getWebWorker()){var i=new Blob(["var _workerSelf = self; self.onmessage = ",e.toString()],{type:"text/javascript"}),r=URL.createObjectURL(i);return new Worker(r)}return t=e,s}((function(t){if(a.dataManager||(a.dataManager=function(){function t(s,a){var n,o,h,l,p,m,c=s.length;for(o=0;o<c;o+=1)if("ks"in(n=s[o])&&!n.completed){if(n.completed=!0,n.hasMask){var d=n.masksProperties;for(l=d.length,h=0;h<l;h+=1)if(d[h].pt.k.i)r(d[h].pt.k);else for(m=d[h].pt.k.length,p=0;p<m;p+=1)d[h].pt.k[p].s&&r(d[h].pt.k[p].s[0]),d[h].pt.k[p].e&&r(d[h].pt.k[p].e[0])}0===n.ty?(n.layers=e(n.refId,a),t(n.layers,a)):4===n.ty?i(n.shapes):5===n.ty&&f(n)}}function e(t,e){var i=function(t,e){for(var i=0,r=e.length;i<r;){if(e[i].id===t)return e[i];i+=1}return null}(t,e);return i?i.layers.__used?JSON.parse(JSON.stringify(i.layers)):(i.layers.__used=!0,i.layers):null}function i(t){var e,s,a;for(e=t.length-1;e>=0;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)r(t[e].ks.k);else for(a=t[e].ks.k.length,s=0;s<a;s+=1)t[e].ks.k[s].s&&r(t[e].ks.k[s].s[0]),t[e].ks.k[s].e&&r(t[e].ks.k[s].e[0]);else"gr"===t[e].ty&&i(t[e].it)}function r(t){var e,i=t.i.length;for(e=0;e<i;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function s(t,e){var i=e?e.split("."):[100,100,100];return t[0]>i[0]||!(i[0]>t[0])&&(t[1]>i[1]||!(i[1]>t[1])&&(t[2]>i[2]||!(i[2]>t[2])&&null))}var a,n=function(){var t=[4,4,14];function e(t){var e,i,r,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(r=void 0,r=(i=t[e]).t.d,i.t.d={k:[{s:r,t:0}]})}return function(i){if(s(t,i.v)&&(e(i.layers),i.assets)){var r,a=i.assets.length;for(r=0;r<a;r+=1)i.assets[r].layers&&e(i.assets[r].layers)}}}(),o=(a=[4,7,99],function(t){if(t.chars&&!s(a,t.v)){var e,r=t.chars.length;for(e=0;e<r;e+=1){var n=t.chars[e];n.data&&n.data.shapes&&(i(n.data.shapes),n.data.ip=0,n.data.op=99999,n.data.st=0,n.data.sr=1,n.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[e].t||(n.data.shapes.push({ty:"no"}),n.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}}}),h=function(){var t=[5,7,15];function e(t){var e,i,r=t.length;for(e=0;e<r;e+=1)5===t[e].ty&&(i=void 0,"number"==typeof(i=t[e].t.p).a&&(i.a={a:0,k:i.a}),"number"==typeof i.p&&(i.p={a:0,k:i.p}),"number"==typeof i.r&&(i.r={a:0,k:i.r}))}return function(i){if(s(t,i.v)&&(e(i.layers),i.assets)){var r,a=i.assets.length;for(r=0;r<a;r+=1)i.assets[r].layers&&e(i.assets[r].layers)}}}(),l=function(){var t=[4,1,9];function e(t){var i,r,s,a=t.length;for(i=0;i<a;i+=1)if("gr"===t[i].ty)e(t[i].it);else if("fl"===t[i].ty||"st"===t[i].ty)if(t[i].c.k&&t[i].c.k[0].i)for(s=t[i].c.k.length,r=0;r<s;r+=1)t[i].c.k[r].s&&(t[i].c.k[r].s[0]/=255,t[i].c.k[r].s[1]/=255,t[i].c.k[r].s[2]/=255,t[i].c.k[r].s[3]/=255),t[i].c.k[r].e&&(t[i].c.k[r].e[0]/=255,t[i].c.k[r].e[1]/=255,t[i].c.k[r].e[2]/=255,t[i].c.k[r].e[3]/=255);else t[i].c.k[0]/=255,t[i].c.k[1]/=255,t[i].c.k[2]/=255,t[i].c.k[3]/=255}function i(t){var i,r=t.length;for(i=0;i<r;i+=1)4===t[i].ty&&e(t[i].shapes)}return function(e){if(s(t,e.v)&&(i(e.layers),e.assets)){var r,a=e.assets.length;for(r=0;r<a;r+=1)e.assets[r].layers&&i(e.assets[r].layers)}}}(),p=function(){var t=[4,4,18];function e(t){var i,r,s;for(i=t.length-1;i>=0;i-=1)if("sh"===t[i].ty)if(t[i].ks.k.i)t[i].ks.k.c=t[i].closed;else for(s=t[i].ks.k.length,r=0;r<s;r+=1)t[i].ks.k[r].s&&(t[i].ks.k[r].s[0].c=t[i].closed),t[i].ks.k[r].e&&(t[i].ks.k[r].e[0].c=t[i].closed);else"gr"===t[i].ty&&e(t[i].it)}function i(t){var i,r,s,a,n,o,h=t.length;for(r=0;r<h;r+=1){if((i=t[r]).hasMask){var l=i.masksProperties;for(a=l.length,s=0;s<a;s+=1)if(l[s].pt.k.i)l[s].pt.k.c=l[s].cl;else for(o=l[s].pt.k.length,n=0;n<o;n+=1)l[s].pt.k[n].s&&(l[s].pt.k[n].s[0].c=l[s].cl),l[s].pt.k[n].e&&(l[s].pt.k[n].e[0].c=l[s].cl)}4===i.ty&&e(i.shapes)}}return function(e){if(s(t,e.v)&&(i(e.layers),e.assets)){var r,a=e.assets.length;for(r=0;r<a;r+=1)e.assets[r].layers&&i(e.assets[r].layers)}}}();function f(t){0===t.t.a.length&&t.t.p}var m={completeData:function(i){i.__complete||(l(i),n(i),o(i),h(i),p(i),t(i.layers,i.assets),function(i,r){if(i){var s=0,a=i.length;for(s=0;s<a;s+=1)1===i[s].t&&(i[s].data.layers=e(i[s].data.refId,r),t(i[s].data.layers,r))}}(i.chars,i.assets),i.__complete=!0)}};return m.checkColors=l,m.checkChars=o,m.checkPathProperties=h,m.checkShapes=p,m.completeLayers=t,m}()),a.assetLoader||(a.assetLoader=function(){function t(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")||t.response&&"object"===_typeof$5(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}return{load:function(e,i,r,s){var a,n=new XMLHttpRequest;try{n.responseType="json"}catch(t){}n.onreadystatechange=function(){if(4===n.readyState)if(200===n.status)a=t(n),r(a);else try{a=t(n),r(a)}catch(t){s&&s(t)}};try{n.open(["G","E","T"].join(""),e,!0)}catch(t){n.open(["G","E","T"].join(""),i+"/"+e,!0)}n.send()}}}()),"loadAnimation"===t.data.type)a.assetLoader.load(t.data.path,t.data.fullPath,(function(e){a.dataManager.completeData(e),a.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){a.postMessage({id:t.data.id,status:"error"})}));else if("complete"===t.data.type){var e=t.data.animation;a.dataManager.completeData(e),a.postMessage({id:t.data.id,payload:e,status:"success"})}else"loadData"===t.data.type&&a.assetLoader.load(t.data.path,t.data.fullPath,(function(e){a.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){a.postMessage({id:t.data.id,status:"error"})}))})),e.onmessage=function(t){var e=t.data,i=e.id,s=r[i];r[i]=null,"success"===e.status?s.onComplete(e.payload):s.onError&&s.onError()})}function o(t,e){var s="processId_"+(i+=1);return r[s]={onComplete:t,onError:e},s}return{loadAnimation:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:s})},loadData:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:s})},completeAnimation:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"complete",animation:t,id:s})}}}(),ImagePreloader=function(){var t=function(){var t=createTag("canvas");t.width=1,t.height=1;var e=t.getContext("2d");return e.fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1),t}();function e(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function i(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function r(t,e,i){var r="";if(t.e)r=t.p;else if(e){var s=t.p;-1!==s.indexOf("images/")&&(s=s.split("/")[1]),r=e+s}else r=i,r+=t.u?t.u:"",r+=t.p;return r}function s(t){var e=0,i=setInterval(function(){(t.getBBox().width||e>500)&&(this._imageLoaded(),clearInterval(i)),e+=1}.bind(this),50)}function a(t){var e={assetData:t},i=r(t,this.assetsPath,this.path);return dataManager.loadData(i,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}function n(){this._imageLoaded=e.bind(this),this._footageLoaded=i.bind(this),this.testImageLoaded=s.bind(this),this.createFootageData=a.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return n.prototype={loadAssets:function(t,e){var i;this.imagesLoadedCb=e;var r=t.length;for(i=0;i<r;i+=1)t[i].layers||(t[i].t&&"seq"!==t[i].t?3===t[i].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[i]))):(this.totalImages+=1,this.images.push(this._createImageData(t[i]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,i=this.images.length;e<i;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(e){var i=r(e,this.assetsPath,this.path),s=createTag("img");s.crossOrigin="anonymous",s.addEventListener("load",this._imageLoaded,!1),s.addEventListener("error",function(){a.img=t,this._imageLoaded()}.bind(this),!1),s.src=i;var a={img:s,assetData:e};return a},createImageData:function(e){var i=r(e,this.assetsPath,this.path),s=createNS("image");isSafari?this.testImageLoaded(s):s.addEventListener("load",this._imageLoaded,!1),s.addEventListener("error",function(){a.img=t,this._imageLoaded()}.bind(this),!1),s.setAttributeNS("http://www.w3.org/1999/xlink","href",i),this._elementHelper.append?this._elementHelper.append(s):this._elementHelper.appendChild(s);var a={img:s,assetData:e};return a},imageLoaded:e,footageLoaded:i,setCacheType:function(t,e){"svg"===t?(this._elementHelper=e,this._createImageData=this.createImageData.bind(this)):this._createImageData=this.createImgData.bind(this)}},n}();function BaseEvent(){}BaseEvent.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var i=this._cbs[t],r=0;r<i.length;r+=1)i[r](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var i=0,r=this._cbs[t].length;i<r;)this._cbs[t][i]===e&&(this._cbs[t].splice(i,1),i-=1,r-=1),i+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var markerParser=function(){function t(t){for(var e,i=t.split("\r\n"),r={},s=0,a=0;a<i.length;a+=1)2===(e=i[a].split(":")).length&&(r[e[0]]=e[1].trim(),s+=1);if(0===s)throw new Error;return r}return function(e){for(var i=[],r=0;r<e.length;r+=1){var s=e[r],a={time:s.tm,duration:s.dr};try{a.payload=JSON.parse(e[r].cm)}catch(i){try{a.payload=t(e[r].cm)}catch(t){a.payload={name:e[r].cm}}}i.push(a)}return i}}(),ProjectInterface=function(){function t(t){this.compositions.push(t)}return function(){function e(t){for(var e=0,i=this.compositions.length;e<i;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return e.compositions=[],e.currentFrame=0,e.registerComposition=t,e}}(),renderers={},registerRenderer=function(t,e){renderers[t]=e};function getRenderer(t){return renderers[t]}function getRegisteredRenderer(){if(renderers.canvas)return"canvas";for(var t in renderers)if(renderers[t])return t;return""}function _typeof$4(t){return _typeof$4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$4(t)}var AnimationItem=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=createElementID(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=getSubframeEnabled(),this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=ProjectInterface(),this.imagePreloader=new ImagePreloader,this.audioController=audioControllerFactory(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new BMEnterFrameEvent("drawnFrame",0,0,0),this.expressionsPlugin=getExpressionsPlugin()};extendPrototype([BaseEvent],AnimationItem),AnimationItem.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg";t.animType?e=t.animType:t.renderer&&(e=t.renderer);var i=getRenderer(e);this.renderer=new i(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||void 0===t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),dataManager.loadAnimation(t.path,this.configAnimation,this.onSetupError))},AnimationItem.prototype.onSetupError=function(){this.trigger("data_failed")},AnimationItem.prototype.setupAnimation=function(t){dataManager.completeAnimation(t,this.configAnimation)},AnimationItem.prototype.setData=function(t,e){e&&"object"!==_typeof$4(e)&&(e=JSON.parse(e));var i={wrapper:t,animationData:e},r=t.attributes;i.path=r.getNamedItem("data-animation-path")?r.getNamedItem("data-animation-path").value:r.getNamedItem("data-bm-path")?r.getNamedItem("data-bm-path").value:r.getNamedItem("bm-path")?r.getNamedItem("bm-path").value:"",i.animType=r.getNamedItem("data-anim-type")?r.getNamedItem("data-anim-type").value:r.getNamedItem("data-bm-type")?r.getNamedItem("data-bm-type").value:r.getNamedItem("bm-type")?r.getNamedItem("bm-type").value:r.getNamedItem("data-bm-renderer")?r.getNamedItem("data-bm-renderer").value:r.getNamedItem("bm-renderer")?r.getNamedItem("bm-renderer").value:getRegisteredRenderer()||"canvas";var s=r.getNamedItem("data-anim-loop")?r.getNamedItem("data-anim-loop").value:r.getNamedItem("data-bm-loop")?r.getNamedItem("data-bm-loop").value:r.getNamedItem("bm-loop")?r.getNamedItem("bm-loop").value:"";"false"===s?i.loop=!1:"true"===s?i.loop=!0:""!==s&&(i.loop=parseInt(s,10));var a=r.getNamedItem("data-anim-autoplay")?r.getNamedItem("data-anim-autoplay").value:r.getNamedItem("data-bm-autoplay")?r.getNamedItem("data-bm-autoplay").value:!r.getNamedItem("bm-autoplay")||r.getNamedItem("bm-autoplay").value;i.autoplay="false"!==a,i.name=r.getNamedItem("data-name")?r.getNamedItem("data-name").value:r.getNamedItem("data-bm-name")?r.getNamedItem("data-bm-name").value:r.getNamedItem("bm-name")?r.getNamedItem("bm-name").value:"","false"===(r.getNamedItem("data-anim-prerender")?r.getNamedItem("data-anim-prerender").value:r.getNamedItem("data-bm-prerender")?r.getNamedItem("data-bm-prerender").value:r.getNamedItem("bm-prerender")?r.getNamedItem("bm-prerender").value:"")&&(i.prerender=!1),i.path?this.setParams(i):this.trigger("destroy")},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,i,r=this.animationData.layers,s=r.length,a=t.layers,n=a.length;for(i=0;i<n;i+=1)for(e=0;e<s;){if(r[e].id===a[i].id){r[e]=a[i];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(s=t.assets.length,e=0;e<s;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,dataManager.completeAnimation(this.animationData,this.onSegmentComplete)},AnimationItem.prototype.onSegmentComplete=function(t){this.animationData=t;var e=getExpressionsPlugin();e&&e.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var i=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,dataManager.loadData(i,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},AnimationItem.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},AnimationItem.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=markerParser(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},AnimationItem.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},AnimationItem.prototype.checkLoaded=function(){if(!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()){this.isLoaded=!0;var t=getExpressionsPlugin();t&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play()}},AnimationItem.prototype.resize=function(t,e){var i="number"==typeof t?t:void 0,r="number"==typeof e?e:void 0;this.renderer.updateContainerSize(i,r)},AnimationItem.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},AnimationItem.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},AnimationItem.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},AnimationItem.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},AnimationItem.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.getMarkerData=function(t){for(var e,i=0;i<this.markers.length;i+=1)if((e=this.markers[i]).payload&&e.payload.name===t)return e;return null},AnimationItem.prototype.goToAndStop=function(t,e,i){if(!i||this.name===i){var r=Number(t);if(isNaN(r)){var s=this.getMarkerData(t);s&&this.goToAndStop(s.time,!0)}else e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier);this.pause()}},AnimationItem.prototype.goToAndPlay=function(t,e,i){if(!i||this.name===i){var r=Number(t);if(isNaN(r)){var s=this.getMarkerData(t);s&&(s.duration?this.playSegments([s.time,s.time+s.duration],!0):this.goToAndStop(s.time,!0))}else this.goToAndStop(r,e,i);this.play()}},AnimationItem.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,i=!1;e>=this.totalFrames-1&&this.frameModifier>0?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(i=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(i=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),i&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(this.frameModifier>0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var i=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?i=t:this.currentRawFrame+this.firstFrame>e&&(i=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==i&&this.goToAndStop(i,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===_typeof$4(t[0])){var i,r=t.length;for(i=0;i<r;i+=1)this.segments.push(t[i])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},AnimationItem.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},AnimationItem.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},AnimationItem.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},AnimationItem.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},AnimationItem.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},AnimationItem.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},AnimationItem.prototype.setLoop=function(t){this.loop=t},AnimationItem.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},AnimationItem.prototype.getVolume=function(){return this.audioController.getVolume()},AnimationItem.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},AnimationItem.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},AnimationItem.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},AnimationItem.prototype.getPath=function(){return this.path},AnimationItem.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var i=t.p;-1!==i.indexOf("images/")&&(i=i.split("/")[1]),e=this.assetsPath+i}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},AnimationItem.prototype.getAssetData=function(t){for(var e=0,i=this.assets.length;e<i;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},AnimationItem.prototype.hide=function(){this.renderer.hide()},AnimationItem.prototype.show=function(){this.renderer.show()},AnimationItem.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},AnimationItem.prototype.updateDocumentData=function(t,e,i){try{this.renderer.getElementByPath(t).updateDocumentData(e,i)}catch(t){}},AnimationItem.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new BMCompleteEvent(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new BMDestroyEvent(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new BMCompleteEvent(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new BMDestroyEvent(t,this))},AnimationItem.prototype.triggerRenderFrameError=function(t){var e=new BMRenderFrameErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)},AnimationItem.prototype.triggerConfigError=function(t){var e=new BMConfigErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)};var animationManager=function(){var t={},e=[],i=0,r=0,s=0,a=!0,n=!1;function o(t){for(var i=0,s=t.target;i<r;)e[i].animation===s&&(e.splice(i,1),i-=1,r-=1,s.isPaused||p()),i+=1}function h(t,i){if(!t)return null;for(var s=0;s<r;){if(e[s].elem===t&&null!==e[s].elem)return e[s].animation;s+=1}var a=new AnimationItem;return f(a,t),a.setData(t,i),a}function l(){s+=1,d()}function p(){s-=1}function f(t,i){t.addEventListener("destroy",o),t.addEventListener("_active",l),t.addEventListener("_idle",p),e.push({elem:i,animation:t}),r+=1}function m(t){var o,h=t-i;for(o=0;o<r;o+=1)e[o].animation.advanceTime(h);i=t,s&&!n?window.requestAnimationFrame(m):a=!0}function c(t){i=t,window.requestAnimationFrame(m)}function d(){!n&&s&&a&&(window.requestAnimationFrame(c),a=!1)}return t.registerAnimation=h,t.loadAnimation=function(t){var e=new AnimationItem;return f(e,null),e.setParams(t),e},t.setSpeed=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setSpeed(t,i)},t.setDirection=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setDirection(t,i)},t.play=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.play(t)},t.pause=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.pause(t)},t.stop=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.stop(t)},t.togglePause=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.togglePause(t)},t.searchAnimations=function(t,e,i){var r,s=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),a=s.length;for(r=0;r<a;r+=1)i&&s[r].setAttribute("data-bm-type",i),h(s[r],t);if(e&&0===a){i||(i="svg");var n=document.getElementsByTagName("body")[0];n.innerText="";var o=createTag("div");o.style.width="100%",o.style.height="100%",o.setAttribute("data-bm-type",i),n.appendChild(o),h(o,t)}},t.resize=function(){var t;for(t=0;t<r;t+=1)e[t].animation.resize()},t.goToAndStop=function(t,i,s){var a;for(a=0;a<r;a+=1)e[a].animation.goToAndStop(t,i,s)},t.destroy=function(t){var i;for(i=r-1;i>=0;i-=1)e[i].animation.destroy(t)},t.freeze=function(){n=!0},t.unfreeze=function(){n=!1,d()},t.setVolume=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setVolume(t,i)},t.mute=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.mute(t)},t.unmute=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.unmute(t)},t.getRegisteredAnimations=function(){var t,i=e.length,r=[];for(t=0;t<i;t+=1)r.push(e[t].animation);return r},t}(),BezierFactory=function(){var t={getBezierEasing:function(t,i,r,s,a){var n=a||("bez_"+t+"_"+i+"_"+r+"_"+s).replace(/\./g,"p");if(e[n])return e[n];var o=new p([t,i,r,s]);return e[n]=o,o}},e={};var i=11,r=1/(i-1),s="function"==typeof Float32Array;function a(t,e){return 1-3*e+3*t}function n(t,e){return 3*e-6*t}function o(t){return 3*t}function h(t,e,i){return((a(e,i)*t+n(e,i))*t+o(e))*t}function l(t,e,i){return 3*a(e,i)*t*t+2*n(e,i)*t+o(e)}function p(t){this._p=t,this._mSampleValues=s?new Float32Array(i):new Array(i),this._precomputed=!1,this.get=this.get.bind(this)}return p.prototype={get:function(t){var e=this._p[0],i=this._p[1],r=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===i&&r===s?t:0===t?0:1===t?1:h(this._getTForX(t),i,s)},_precompute:function(){var t=this._p[0],e=this._p[1],i=this._p[2],r=this._p[3];this._precomputed=!0,t===e&&i===r||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],s=0;s<i;++s)this._mSampleValues[s]=h(s*r,t,e)},_getTForX:function(t){for(var e=this._p[0],s=this._p[2],a=this._mSampleValues,n=0,o=1,p=i-1;o!==p&&a[o]<=t;++o)n+=r;var f=n+(t-a[--o])/(a[o+1]-a[o])*r,m=l(f,e,s);return m>=.001?function(t,e,i,r){for(var s=0;s<4;++s){var a=l(e,i,r);if(0===a)return e;e-=(h(e,i,r)-t)/a}return e}(t,f,e,s):0===m?f:function(t,e,i,r,s){var a,n,o=0;do{(a=h(n=e+(i-e)/2,r,s)-t)>0?i=n:e=n}while(Math.abs(a)>1e-7&&++o<10);return n}(t,n,n+r,e,s)}},t}(),pooling={double:function(t){return t.concat(createSizedArray(t.length))}},poolFactory=function(t,e,i){var r=0,s=t,a=createSizedArray(s);return{newElement:function(){return r?a[r-=1]:e()},release:function(t){r===s&&(a=pooling.double(a),s*=2),i&&i(t),a[r]=t,r+=1}}},bezierLengthPool=poolFactory(8,(function(){return{addedLength:0,percents:createTypedArray("float32",getDefaultCurveSegments()),lengths:createTypedArray("float32",getDefaultCurveSegments())}})),segmentsLengthPool=poolFactory(8,(function(){return{lengths:[],totalLength:0}}),(function(t){var e,i=t.lengths.length;for(e=0;e<i;e+=1)bezierLengthPool.release(t.lengths[e]);t.lengths.length=0}));function bezFunction(){var t=Math;function e(t,e,i,r,s,a){var n=t*r+e*s+i*a-s*r-a*t-i*e;return n>-.001&&n<.001}var i=function(t,e,i,r){var s,a,n,o,h,l,p=getDefaultCurveSegments(),f=0,m=[],c=[],d=bezierLengthPool.newElement();for(n=i.length,s=0;s<p;s+=1){for(h=s/(p-1),l=0,a=0;a<n;a+=1)o=bmPow(1-h,3)*t[a]+3*bmPow(1-h,2)*h*i[a]+3*(1-h)*bmPow(h,2)*r[a]+bmPow(h,3)*e[a],m[a]=o,null!==c[a]&&(l+=bmPow(m[a]-c[a],2)),c[a]=m[a];l&&(f+=l=bmSqrt(l)),d.percents[s]=h,d.lengths[s]=f}return d.addedLength=f,d};function r(t){this.segmentLength=0,this.points=new Array(t)}function s(t,e){this.partialLength=t,this.point=e}var a,n=(a={},function(t,i,n,o){var h=(t[0]+"_"+t[1]+"_"+i[0]+"_"+i[1]+"_"+n[0]+"_"+n[1]+"_"+o[0]+"_"+o[1]).replace(/\./g,"p");if(!a[h]){var l,p,f,m,c,d,u,y=getDefaultCurveSegments(),g=0,v=null;2===t.length&&(t[0]!==i[0]||t[1]!==i[1])&&e(t[0],t[1],i[0],i[1],t[0]+n[0],t[1]+n[1])&&e(t[0],t[1],i[0],i[1],i[0]+o[0],i[1]+o[1])&&(y=2);var b=new r(y);for(f=n.length,l=0;l<y;l+=1){for(u=createSizedArray(f),c=l/(y-1),d=0,p=0;p<f;p+=1)m=bmPow(1-c,3)*t[p]+3*bmPow(1-c,2)*c*(t[p]+n[p])+3*(1-c)*bmPow(c,2)*(i[p]+o[p])+bmPow(c,3)*i[p],u[p]=m,null!==v&&(d+=bmPow(u[p]-v[p],2));g+=d=bmSqrt(d),b.points[l]=new s(d,u),v=u}b.segmentLength=g,a[h]=b}return a[h]});function o(t,e){var i=e.percents,r=e.lengths,s=i.length,a=bmFloor((s-1)*t),n=t*e.addedLength,o=0;if(a===s-1||0===a||n===r[a])return i[a];for(var h=r[a]>n?-1:1,l=!0;l;)if(r[a]<=n&&r[a+1]>n?(o=(n-r[a])/(r[a+1]-r[a]),l=!1):a+=h,a<0||a>=s-1){if(a===s-1)return i[a];l=!1}return i[a]+(i[a+1]-i[a])*o}var h=createTypedArray("float32",8);return{getSegmentsLength:function(t){var e,r=segmentsLengthPool.newElement(),s=t.c,a=t.v,n=t.o,o=t.i,h=t._length,l=r.lengths,p=0;for(e=0;e<h-1;e+=1)l[e]=i(a[e],a[e+1],n[e],o[e+1]),p+=l[e].addedLength;return s&&h&&(l[e]=i(a[e],a[0],n[e],o[0]),p+=l[e].addedLength),r.totalLength=p,r},getNewSegment:function(e,i,r,s,a,n,l){a<0?a=0:a>1&&(a=1);var p,f=o(a,l),m=o(n=n>1?1:n,l),c=e.length,d=1-f,u=1-m,y=d*d*d,g=f*d*d*3,v=f*f*d*3,b=f*f*f,x=d*d*u,P=f*d*u+d*f*u+d*d*m,E=f*f*u+d*f*m+f*d*m,S=f*f*m,C=d*u*u,_=f*u*u+d*m*u+d*u*m,A=f*m*u+d*m*m+f*u*m,T=f*m*m,M=u*u*u,k=m*u*u+u*m*u+u*u*m,D=m*m*u+u*m*m+m*u*m,F=m*m*m;for(p=0;p<c;p+=1)h[4*p]=t.round(1e3*(y*e[p]+g*r[p]+v*s[p]+b*i[p]))/1e3,h[4*p+1]=t.round(1e3*(x*e[p]+P*r[p]+E*s[p]+S*i[p]))/1e3,h[4*p+2]=t.round(1e3*(C*e[p]+_*r[p]+A*s[p]+T*i[p]))/1e3,h[4*p+3]=t.round(1e3*(M*e[p]+k*r[p]+D*s[p]+F*i[p]))/1e3;return h},getPointInSegment:function(e,i,r,s,a,n){var h=o(a,n),l=1-h;return[t.round(1e3*(l*l*l*e[0]+(h*l*l+l*h*l+l*l*h)*r[0]+(h*h*l+l*h*h+h*l*h)*s[0]+h*h*h*i[0]))/1e3,t.round(1e3*(l*l*l*e[1]+(h*l*l+l*h*l+l*l*h)*r[1]+(h*h*l+l*h*h+h*l*h)*s[1]+h*h*h*i[1]))/1e3]},buildBezierData:n,pointOnLine2D:e,pointOnLine3D:function(i,r,s,a,n,o,h,l,p){if(0===s&&0===o&&0===p)return e(i,r,a,n,h,l);var f,m=t.sqrt(t.pow(a-i,2)+t.pow(n-r,2)+t.pow(o-s,2)),c=t.sqrt(t.pow(h-i,2)+t.pow(l-r,2)+t.pow(p-s,2)),d=t.sqrt(t.pow(h-a,2)+t.pow(l-n,2)+t.pow(p-o,2));return(f=m>c?m>d?m-c-d:d-c-m:d>c?d-c-m:c-m-d)>-1e-4&&f<1e-4}}}var bez=bezFunction(),initFrame=initialDefaultFrame,mathAbs=Math.abs;function interpolateValue(t,e){var i,r=this.offsetTime;"multidimensional"===this.propType&&(i=createTypedArray("float32",this.pv.length));for(var s,a,n,o,h,l,p,f,m,c=e.lastIndex,d=c,u=this.keyframes.length-1,y=!0;y;){if(s=this.keyframes[d],a=this.keyframes[d+1],d===u-1&&t>=a.t-r){s.h&&(s=a),c=0;break}if(a.t-r>t){c=d;break}d<u-1?d+=1:(c=0,y=!1)}n=this.keyframesMetadata[d]||{};var g,v=a.t-r,b=s.t-r;if(s.to){n.bezierData||(n.bezierData=bez.buildBezierData(s.s,a.s||s.e,s.to,s.ti));var x=n.bezierData;if(t>=v||t<b){var P=t>=v?x.points.length-1:0;for(h=x.points[P].point.length,o=0;o<h;o+=1)i[o]=x.points[P].point[o]}else{n.__fnct?m=n.__fnct:(m=BezierFactory.getBezierEasing(s.o.x,s.o.y,s.i.x,s.i.y,s.n).get,n.__fnct=m),l=m((t-b)/(v-b));var E,S=x.segmentLength*l,C=e.lastFrame<t&&e._lastKeyframeIndex===d?e._lastAddedLength:0;for(f=e.lastFrame<t&&e._lastKeyframeIndex===d?e._lastPoint:0,y=!0,p=x.points.length;y;){if(C+=x.points[f].partialLength,0===S||0===l||f===x.points.length-1){for(h=x.points[f].point.length,o=0;o<h;o+=1)i[o]=x.points[f].point[o];break}if(S>=C&&S<C+x.points[f+1].partialLength){for(E=(S-C)/x.points[f+1].partialLength,h=x.points[f].point.length,o=0;o<h;o+=1)i[o]=x.points[f].point[o]+(x.points[f+1].point[o]-x.points[f].point[o])*E;break}f<p-1?f+=1:y=!1}e._lastPoint=f,e._lastAddedLength=C-x.points[f].partialLength,e._lastKeyframeIndex=d}}else{var _,A,T,M,k;if(u=s.s.length,g=a.s||s.e,this.sh&&1!==s.h)if(t>=v)i[0]=g[0],i[1]=g[1],i[2]=g[2];else if(t<=b)i[0]=s.s[0],i[1]=s.s[1],i[2]=s.s[2];else{quaternionToEuler(i,slerp(createQuaternion(s.s),createQuaternion(g),(t-b)/(v-b)))}else for(d=0;d<u;d+=1)1!==s.h&&(t>=v?l=1:t<b?l=0:(s.o.x.constructor===Array?(n.__fnct||(n.__fnct=[]),n.__fnct[d]?m=n.__fnct[d]:(_=void 0===s.o.x[d]?s.o.x[0]:s.o.x[d],A=void 0===s.o.y[d]?s.o.y[0]:s.o.y[d],T=void 0===s.i.x[d]?s.i.x[0]:s.i.x[d],M=void 0===s.i.y[d]?s.i.y[0]:s.i.y[d],m=BezierFactory.getBezierEasing(_,A,T,M).get,n.__fnct[d]=m)):n.__fnct?m=n.__fnct:(_=s.o.x,A=s.o.y,T=s.i.x,M=s.i.y,m=BezierFactory.getBezierEasing(_,A,T,M).get,s.keyframeMetadata=m),l=m((t-b)/(v-b)))),g=a.s||s.e,k=1===s.h?s.s[d]:s.s[d]+(g[d]-s.s[d])*l,"multidimensional"===this.propType?i[d]=k:i=k}return e.lastIndex=c,i}function slerp(t,e,i){var r,s,a,n,o,h=[],l=t[0],p=t[1],f=t[2],m=t[3],c=e[0],d=e[1],u=e[2],y=e[3];return(s=l*c+p*d+f*u+m*y)<0&&(s=-s,c=-c,d=-d,u=-u,y=-y),1-s>1e-6?(r=Math.acos(s),a=Math.sin(r),n=Math.sin((1-i)*r)/a,o=Math.sin(i*r)/a):(n=1-i,o=i),h[0]=n*l+o*c,h[1]=n*p+o*d,h[2]=n*f+o*u,h[3]=n*m+o*y,h}function quaternionToEuler(t,e){var i=e[0],r=e[1],s=e[2],a=e[3],n=Math.atan2(2*r*a-2*i*s,1-2*r*r-2*s*s),o=Math.asin(2*i*r+2*s*a),h=Math.atan2(2*i*a-2*r*s,1-2*i*i-2*s*s);t[0]=n/degToRads,t[1]=o/degToRads,t[2]=h/degToRads}function createQuaternion(t){var e=t[0]*degToRads,i=t[1]*degToRads,r=t[2]*degToRads,s=Math.cos(e/2),a=Math.cos(i/2),n=Math.cos(r/2),o=Math.sin(e/2),h=Math.sin(i/2),l=Math.sin(r/2);return[o*h*n+s*a*l,o*a*n+s*h*l,s*h*n-o*a*l,s*a*n-o*h*l]}function getValueAtCurrentTime(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==initFrame&&(this._caching.lastFrame>=i&&t>=i||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var r=this.interpolateValue(t,this._caching);this.pv=r}return this._caching.lastFrame=t,this.pv}function setVValue(t){var e;if("unidimensional"===this.propType)e=t*this.mult,mathAbs(this.v-e)>1e-5&&(this.v=e,this._mdf=!0);else for(var i=0,r=this.v.length;i<r;)e=t[i]*this.mult,mathAbs(this.v[i]-e)>1e-5&&(this.v[i]=e,this._mdf=!0),i+=1}function processEffectsSequence(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t;this.lock=!0,this._mdf=this._isFirstFrame;var e=this.effectsSequence.length,i=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)i=this.effectsSequence[t](i);this.setVValue(i),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function addEffect(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function ValueProperty(t,e,i,r){this.propType="unidimensional",this.mult=i||1,this.data=e,this.v=i?e.k*i:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function MultiDimensionalProperty(t,e,i,r){var s;this.propType="multidimensional",this.mult=i||1,this.data=e,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var a=e.k.length;for(this.v=createTypedArray("float32",a),this.pv=createTypedArray("float32",a),this.vel=createTypedArray("float32",a),s=0;s<a;s+=1)this.v[s]=e.k[s]*this.mult,this.pv[s]=e.k[s];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function KeyframedValueProperty(t,e,i,r){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:initFrame,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.v=initFrame,this.pv=initFrame,this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.addEffect=addEffect}function KeyframedMultidimensionalProperty(t,e,i,r){var s;this.propType="multidimensional";var a,n,o,h,l=e.k.length;for(s=0;s<l-1;s+=1)e.k[s].to&&e.k[s].s&&e.k[s+1]&&e.k[s+1].s&&(a=e.k[s].s,n=e.k[s+1].s,o=e.k[s].to,h=e.k[s].ti,(2===a.length&&(a[0]!==n[0]||a[1]!==n[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],a[0]+o[0],a[1]+o[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],n[0]+h[0],n[1]+h[1])||3===a.length&&(a[0]!==n[0]||a[1]!==n[1]||a[2]!==n[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],a[0]+o[0],a[1]+o[1],a[2]+o[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],n[0]+h[0],n[1]+h[1],n[2]+h[2]))&&(e.k[s].to=null,e.k[s].ti=null),a[0]===n[0]&&a[1]===n[1]&&0===o[0]&&0===o[1]&&0===h[0]&&0===h[1]&&(2===a.length||a[2]===n[2]&&0===o[2]&&0===h[2])&&(e.k[s].to=null,e.k[s].ti=null));this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.frameId=-1;var p=e.k[0].s.length;for(this.v=createTypedArray("float32",p),this.pv=createTypedArray("float32",p),s=0;s<p;s+=1)this.v[s]=initFrame,this.pv[s]=initFrame;this._caching={lastFrame:initFrame,lastIndex:0,value:createTypedArray("float32",p)},this.addEffect=addEffect}var PropertyFactory={getProp:function(t,e,i,r,s){var a;if(e.sid&&(e=t.globalData.slotManager.getProp(e)),e.k.length)if("number"==typeof e.k[0])a=new MultiDimensionalProperty(t,e,r,s);else switch(i){case 0:a=new KeyframedValueProperty(t,e,r,s);break;case 1:a=new KeyframedMultidimensionalProperty(t,e,r,s)}else a=new ValueProperty(t,e,r,s);return a.effectsSequence.length&&s.addDynamicProperty(a),a}};function DynamicPropertyContainer(){}DynamicPropertyContainer.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){var t;this._mdf=!1;var e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var pointPool=poolFactory(8,(function(){return createTypedArray("float32",2)}));function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var i=0;i<e;)this.v[i]=pointPool.newElement(),this.o[i]=pointPool.newElement(),this.i[i]=pointPool.newElement(),i+=1},ShapePath.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},ShapePath.prototype.doubleArrayLength=function(){this.v=this.v.concat(createSizedArray(this._maxLength)),this.i=this.i.concat(createSizedArray(this._maxLength)),this.o=this.o.concat(createSizedArray(this._maxLength)),this._maxLength*=2},ShapePath.prototype.setXYAt=function(t,e,i,r,s){var a;switch(this._length=Math.max(this._length,r+1),this._length>=this._maxLength&&this.doubleArrayLength(),i){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o;break;default:a=[]}(!a[r]||a[r]&&!s)&&(a[r]=pointPool.newElement()),a[r][0]=t,a[r][1]=e},ShapePath.prototype.setTripleAt=function(t,e,i,r,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(i,r,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t=new ShapePath;t.setPathData(this.c,this._length);var e=this.v,i=this.o,r=this.i,s=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],r[0][0],r[0][1],i[0][0],i[0][1],0,!1),s=1);var a,n=this._length-1,o=this._length;for(a=s;a<o;a+=1)t.setTripleAt(e[n][0],e[n][1],r[n][0],r[n][1],i[n][0],i[n][1],a,!1),n-=1;return t},ShapePath.prototype.length=function(){return this._length};var shapePool=(factory=poolFactory(4,(function(){return new ShapePath}),(function(t){var e,i=t._length;for(e=0;e<i;e+=1)pointPool.release(t.v[e]),pointPool.release(t.i[e]),pointPool.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1})),factory.clone=function(t){var e,i=factory.newElement(),r=void 0===t._length?t.v.length:t._length;for(i.setLength(r),i.c=t.c,e=0;e<r;e+=1)i.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return i},factory),factory;function ShapeCollection(){this._length=0,this._maxLength=4,this.shapes=createSizedArray(this._maxLength)}ShapeCollection.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(createSizedArray(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},ShapeCollection.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)shapePool.release(this.shapes[t]);this._length=0};var shapeCollectionPool=(ob={newShapeCollection:function(){return _length?pool[_length-=1]:new ShapeCollection},release:function(t){var e,i=t._length;for(e=0;e<i;e+=1)shapePool.release(t.shapes[e]);t._length=0,_length===_maxLength&&(pool=pooling.double(pool),_maxLength*=2),pool[_length]=t,_length+=1}},_length=0,_maxLength=4,pool=createSizedArray(_maxLength),ob),ob,_length,_maxLength,pool,ShapePropertyFactory=function(){var t=-999999;function e(t,e,i){var r,s,a,n,o,h,l,p,f,m=i.lastIndex,c=this.keyframes;if(t<c[0].t-this.offsetTime)r=c[0].s[0],a=!0,m=0;else if(t>=c[c.length-1].t-this.offsetTime)r=c[c.length-1].s?c[c.length-1].s[0]:c[c.length-2].e[0],a=!0;else{for(var d,u,y,g=m,v=c.length-1,b=!0;b&&(d=c[g],!((u=c[g+1]).t-this.offsetTime>t));)g<v-1?g+=1:b=!1;if(y=this.keyframesMetadata[g]||{},m=g,!(a=1===d.h)){if(t>=u.t-this.offsetTime)p=1;else if(t<d.t-this.offsetTime)p=0;else{var x;y.__fnct?x=y.__fnct:(x=BezierFactory.getBezierEasing(d.o.x,d.o.y,d.i.x,d.i.y).get,y.__fnct=x),p=x((t-(d.t-this.offsetTime))/(u.t-this.offsetTime-(d.t-this.offsetTime)))}s=u.s?u.s[0]:d.e[0]}r=d.s[0]}for(h=e._length,l=r.i[0].length,i.lastIndex=m,n=0;n<h;n+=1)for(o=0;o<l;o+=1)f=a?r.i[n][o]:r.i[n][o]+(s.i[n][o]-r.i[n][o])*p,e.i[n][o]=f,f=a?r.o[n][o]:r.o[n][o]+(s.o[n][o]-r.o[n][o])*p,e.o[n][o]=f,f=a?r.v[n][o]:r.v[n][o]+(s.v[n][o]-r.v[n][o])*p,e.v[n][o]=f}function i(){var e=this.comp.renderedFrame-this.offsetTime,i=this.keyframes[0].t-this.offsetTime,r=this.keyframes[this.keyframes.length-1].t-this.offsetTime,s=this._caching.lastFrame;return s!==t&&(s<i&&e<i||s>r&&e>r)||(this._caching.lastIndex=s<e?this._caching.lastIndex:0,this.interpolateShape(e,this.pv,this._caching)),this._caching.lastFrame=e,this.pv}function r(){this.paths=this.localShapeCollection}function s(t){(function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var i,r=t._length;for(i=0;i<r;i+=1)if(t.v[i][0]!==e.v[i][0]||t.v[i][1]!==e.v[i][1]||t.o[i][0]!==e.o[i][0]||t.o[i][1]!==e.o[i][1]||t.i[i][0]!==e.i[i][0]||t.i[i][1]!==e.i[i][1])return!1;return!0})(this.v,t)||(this.v=shapePool.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function a(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t,e;this.lock=!0,this._mdf=!1,t=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k;var i=this.effectsSequence.length;for(e=0;e<i;e+=1)t=this.effectsSequence[e](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function n(t,e,i){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var s=3===i?e.pt.k:e.ks.k;this.v=shapePool.clone(s),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=r,this.effectsSequence=[]}function o(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function h(e,s,a){this.propType="shape",this.comp=e.comp,this.elem=e,this.container=e,this.offsetTime=e.data.st,this.keyframes=3===a?s.pt.k:s.ks.k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;var n=this.keyframes[0].s[0].i.length;this.v=shapePool.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,n),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=t,this.reset=r,this._caching={lastFrame:t,lastIndex:0},this.effectsSequence=[i.bind(this)]}n.prototype.interpolateShape=e,n.prototype.getValue=a,n.prototype.setVValue=s,n.prototype.addEffect=o,h.prototype.getValue=a,h.prototype.interpolateShape=e,h.prototype.setVValue=s,h.prototype.addEffect=o;var l=function(){var t=roundCorner;function e(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}return e.prototype={reset:r,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var e=this.p.v[0],i=this.p.v[1],r=this.s.v[0]/2,s=this.s.v[1]/2,a=3!==this.d,n=this.v;n.v[0][0]=e,n.v[0][1]=i-s,n.v[1][0]=a?e+r:e-r,n.v[1][1]=i,n.v[2][0]=e,n.v[2][1]=i+s,n.v[3][0]=a?e-r:e+r,n.v[3][1]=i,n.i[0][0]=a?e-r*t:e+r*t,n.i[0][1]=i-s,n.i[1][0]=a?e+r:e-r,n.i[1][1]=i-s*t,n.i[2][0]=a?e+r*t:e-r*t,n.i[2][1]=i+s,n.i[3][0]=a?e-r:e+r,n.i[3][1]=i+s*t,n.o[0][0]=a?e+r*t:e-r*t,n.o[0][1]=i-s,n.o[1][0]=a?e+r:e-r,n.o[1][1]=i+s*t,n.o[2][0]=a?e-r*t:e+r*t,n.o[2][1]=i+s,n.o[3][0]=a?e-r:e+r,n.o[3][1]=i-s*t}},extendPrototype([DynamicPropertyContainer],e),e}(),p=function(){function t(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=PropertyFactory.getProp(t,e.ir,0,0,this),this.is=PropertyFactory.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=PropertyFactory.getProp(t,e.pt,0,0,this),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,degToRads,this),this.or=PropertyFactory.getProp(t,e.or,0,0,this),this.os=PropertyFactory.getProp(t,e.os,0,.01,this),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}return t.prototype={reset:r,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,i,r,s=2*Math.floor(this.pt.v),a=2*Math.PI/s,n=!0,o=this.or.v,h=this.ir.v,l=this.os.v,p=this.is.v,f=2*Math.PI*o/(2*s),m=2*Math.PI*h/(2*s),c=-Math.PI/2;c+=this.r.v;var d=3===this.data.d?-1:1;for(this.v._length=0,t=0;t<s;t+=1){i=n?l:p,r=n?f:m;var u=(e=n?o:h)*Math.cos(c),y=e*Math.sin(c),g=0===u&&0===y?0:y/Math.sqrt(u*u+y*y),v=0===u&&0===y?0:-u/Math.sqrt(u*u+y*y);u+=+this.p.v[0],y+=+this.p.v[1],this.v.setTripleAt(u,y,u-g*r*i*d,y-v*r*i*d,u+g*r*i*d,y+v*r*i*d,t,!0),n=!n,c+=a*d}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),i=2*Math.PI/e,r=this.or.v,s=this.os.v,a=2*Math.PI*r/(4*e),n=.5*-Math.PI,o=3===this.data.d?-1:1;for(n+=this.r.v,this.v._length=0,t=0;t<e;t+=1){var h=r*Math.cos(n),l=r*Math.sin(n),p=0===h&&0===l?0:l/Math.sqrt(h*h+l*l),f=0===h&&0===l?0:-h/Math.sqrt(h*h+l*l);h+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(h,l,h-p*a*s*o,l-f*a*s*o,h+p*a*s*o,l+f*a*s*o,t,!0),n+=i*o}this.paths.length=0,this.paths[0]=this.v}},extendPrototype([DynamicPropertyContainer],t),t}(),f=function(){function t(t,e){this.v=shapePool.newElement(),this.v.c=!0,this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}return t.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,r=this.s.v[1]/2,s=bmMin(i,r,this.r.v),a=s*(1-roundCorner);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+s,t+i,e-r+a,0,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-a,t+i,e+r-s,1,!0),0!==s?(this.v.setTripleAt(t+i-s,e+r,t+i-s,e+r,t+i-a,e+r,2,!0),this.v.setTripleAt(t-i+s,e+r,t-i+a,e+r,t-i+s,e+r,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-s,t-i,e+r-a,4,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+a,t-i,e-r+s,5,!0),this.v.setTripleAt(t-i+s,e-r,t-i+s,e-r,t-i+a,e-r,6,!0),this.v.setTripleAt(t+i-s,e-r,t+i-a,e-r,t+i-s,e-r,7,!0)):(this.v.setTripleAt(t-i,e+r,t-i+a,e+r,t-i,e+r,2),this.v.setTripleAt(t-i,e-r,t-i,e-r+a,t-i,e-r,3))):(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+a,t+i,e-r+s,0,!0),0!==s?(this.v.setTripleAt(t+i-s,e-r,t+i-s,e-r,t+i-a,e-r,1,!0),this.v.setTripleAt(t-i+s,e-r,t-i+a,e-r,t-i+s,e-r,2,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+s,t-i,e-r+a,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-a,t-i,e+r-s,4,!0),this.v.setTripleAt(t-i+s,e+r,t-i+s,e+r,t-i+a,e+r,5,!0),this.v.setTripleAt(t+i-s,e+r,t+i-a,e+r,t+i-s,e+r,6,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-s,t+i,e+r-a,7,!0)):(this.v.setTripleAt(t-i,e-r,t-i+a,e-r,t-i,e-r,1,!0),this.v.setTripleAt(t-i,e+r,t-i,e+r-a,t-i,e+r,2,!0),this.v.setTripleAt(t+i,e+r,t+i-a,e+r,t+i,e+r,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:r},extendPrototype([DynamicPropertyContainer],t),t}();var m={getShapeProp:function(t,e,i){var r;return 3===i||4===i?r=(3===i?e.pt:e.ks).k.length?new h(t,e,i):new n(t,e,i):5===i?r=new f(t,e):6===i?r=new l(t,e):7===i&&(r=new p(t,e)),r.k&&t.addDynamicProperty(r),r},getConstructorFunction:function(){return n},getKeyframedConstructorFunction:function(){return h}};return m}(),Matrix=function(){var t=Math.cos,e=Math.sin,i=Math.tan,r=Math.round;function s(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function a(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,-s,0,0,s,r,0,0,0,0,1,0,0,0,0,1)}function n(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(1,0,0,0,0,r,-s,0,0,s,r,0,0,0,0,1)}function o(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,0,s,0,0,1,0,0,-s,0,r,0,0,0,0,1)}function h(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,-s,0,0,s,r,0,0,0,0,1,0,0,0,0,1)}function l(t,e){return this._t(1,e,t,1,0,0)}function p(t,e){return this.shear(i(t),i(e))}function f(r,s){var a=t(s),n=e(s);return this._t(a,n,0,0,-n,a,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,i(r),1,0,0,0,0,1,0,0,0,0,1)._t(a,-n,0,0,n,a,0,0,0,0,1,0,0,0,0,1)}function m(t,e,i){return i||0===i||(i=1),1===t&&1===e&&1===i?this:this._t(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1)}function c(t,e,i,r,s,a,n,o,h,l,p,f,m,c,d,u){return this.props[0]=t,this.props[1]=e,this.props[2]=i,this.props[3]=r,this.props[4]=s,this.props[5]=a,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=l,this.props[10]=p,this.props[11]=f,this.props[12]=m,this.props[13]=c,this.props[14]=d,this.props[15]=u,this}function d(t,e,i){return i=i||0,0!==t||0!==e||0!==i?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,i,1):this}function u(t,e,i,r,s,a,n,o,h,l,p,f,m,c,d,u){var y=this.props;if(1===t&&0===e&&0===i&&0===r&&0===s&&1===a&&0===n&&0===o&&0===h&&0===l&&1===p&&0===f)return y[12]=y[12]*t+y[15]*m,y[13]=y[13]*a+y[15]*c,y[14]=y[14]*p+y[15]*d,y[15]*=u,this._identityCalculated=!1,this;var g=y[0],v=y[1],b=y[2],x=y[3],P=y[4],E=y[5],S=y[6],C=y[7],_=y[8],A=y[9],T=y[10],M=y[11],k=y[12],D=y[13],F=y[14],w=y[15];return y[0]=g*t+v*s+b*h+x*m,y[1]=g*e+v*a+b*l+x*c,y[2]=g*i+v*n+b*p+x*d,y[3]=g*r+v*o+b*f+x*u,y[4]=P*t+E*s+S*h+C*m,y[5]=P*e+E*a+S*l+C*c,y[6]=P*i+E*n+S*p+C*d,y[7]=P*r+E*o+S*f+C*u,y[8]=_*t+A*s+T*h+M*m,y[9]=_*e+A*a+T*l+M*c,y[10]=_*i+A*n+T*p+M*d,y[11]=_*r+A*o+T*f+M*u,y[12]=k*t+D*s+F*h+w*m,y[13]=k*e+D*a+F*l+w*c,y[14]=k*i+D*n+F*p+w*d,y[15]=k*r+D*o+F*f+w*u,this._identityCalculated=!1,this}function y(t){var e=t.props;return this.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}function g(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function v(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function b(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function x(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function P(t,e,i){return{x:t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}}function E(t,e,i){return t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12]}function S(t,e,i){return t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13]}function C(t,e,i){return t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}function _(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,i=-this.props[1]/t,r=-this.props[4]/t,s=this.props[0]/t,a=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,n=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,o=new Matrix;return o.props[0]=e,o.props[1]=i,o.props[4]=r,o.props[5]=s,o.props[12]=a,o.props[13]=n,o}function A(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function T(t){var e,i=t.length,r=[];for(e=0;e<i;e+=1)r[e]=A(t[e]);return r}function M(t,e,i){var r=createTypedArray("float32",6);if(this.isIdentity())r[0]=t[0],r[1]=t[1],r[2]=e[0],r[3]=e[1],r[4]=i[0],r[5]=i[1];else{var s=this.props[0],a=this.props[1],n=this.props[4],o=this.props[5],h=this.props[12],l=this.props[13];r[0]=t[0]*s+t[1]*n+h,r[1]=t[0]*a+t[1]*o+l,r[2]=e[0]*s+e[1]*n+h,r[3]=e[0]*a+e[1]*o+l,r[4]=i[0]*s+i[1]*n+h,r[5]=i[0]*a+i[1]*o+l}return r}function k(t,e,i){return this.isIdentity()?[t,e,i]:[t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]]}function D(t,e){if(this.isIdentity())return t+","+e;var i=this.props;return Math.round(100*(t*i[0]+e*i[4]+i[12]))/100+","+Math.round(100*(t*i[1]+e*i[5]+i[13]))/100}function F(){for(var t=0,e=this.props,i="matrix3d(";t<16;)i+=r(1e4*e[t])/1e4,i+=15===t?")":",",t+=1;return i}function w(t){return t<1e-6&&t>0||t>-1e-6&&t<0?r(1e4*t)/1e4:t}function I(){var t=this.props;return"matrix("+w(t[0])+","+w(t[1])+","+w(t[4])+","+w(t[5])+","+w(t[12])+","+w(t[13])+")"}return function(){this.reset=s,this.rotate=a,this.rotateX=n,this.rotateY=o,this.rotateZ=h,this.skew=p,this.skewFromAxis=f,this.shear=l,this.scale=m,this.setTransform=c,this.translate=d,this.transform=u,this.multiply=y,this.applyToPoint=P,this.applyToX=E,this.applyToY=S,this.applyToZ=C,this.applyToPointArray=k,this.applyToTriplePoints=M,this.applyToPointStringified=D,this.toCSS=F,this.to2dCSS=I,this.clone=b,this.cloneFromProps=x,this.equals=v,this.inversePoints=T,this.inversePoint=A,this.getInverseMatrix=_,this._t=this.transform,this.isIdentity=g,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}}();function _typeof$3(t){return _typeof$3="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$3(t)}var lottie={},standalone="__[STANDALONE]__",animationData="__[ANIMATIONDATA]__",renderer="";function setLocation(t){setLocationHref(t)}function searchAnimations(){!0===standalone?animationManager.searchAnimations(animationData,standalone,renderer):animationManager.searchAnimations()}function setSubframeRendering(t){setSubframeEnabled(t)}function setPrefix(t){setIdPrefix(t)}function loadAnimation(t){return!0===standalone&&(t.animationData=JSON.parse(animationData)),animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":setDefaultCurveSegments(200);break;default:case"medium":setDefaultCurveSegments(50);break;case"low":setDefaultCurveSegments(10)}else!isNaN(t)&&t>1&&setDefaultCurveSegments(t);getDefaultCurveSegments()>=50?roundValues(!1):roundValues(!0)}function inBrowser(){return"undefined"!=typeof navigator}function installPlugin(t,e){"expressions"===t&&setExpressionsPlugin(e)}function getFactory(t){switch(t){case"propertyFactory":return PropertyFactory;case"shapePropertyFactory":return ShapePropertyFactory;case"matrix":return Matrix;default:return null}}function checkReady(){"complete"===document.readyState&&(clearInterval(readyStateCheckInterval),searchAnimations())}function getQueryVariable(t){for(var e=queryString.split("&"),i=0;i<e.length;i+=1){var r=e[i].split("=");if(decodeURIComponent(r[0])==t)return decodeURIComponent(r[1])}return null}lottie.play=animationManager.play,lottie.pause=animationManager.pause,lottie.setLocationHref=setLocation,lottie.togglePause=animationManager.togglePause,lottie.setSpeed=animationManager.setSpeed,lottie.setDirection=animationManager.setDirection,lottie.stop=animationManager.stop,lottie.searchAnimations=searchAnimations,lottie.registerAnimation=animationManager.registerAnimation,lottie.loadAnimation=loadAnimation,lottie.setSubframeRendering=setSubframeRendering,lottie.resize=animationManager.resize,lottie.goToAndStop=animationManager.goToAndStop,lottie.destroy=animationManager.destroy,lottie.setQuality=setQuality,lottie.inBrowser=inBrowser,lottie.installPlugin=installPlugin,lottie.freeze=animationManager.freeze,lottie.unfreeze=animationManager.unfreeze,lottie.setVolume=animationManager.setVolume,lottie.mute=animationManager.mute,lottie.unmute=animationManager.unmute,lottie.getRegisteredAnimations=animationManager.getRegisteredAnimations,lottie.useWebWorker=setWebWorker,lottie.setIDPrefix=setPrefix,lottie.__getFactory=getFactory,lottie.version="5.13.0";var queryString="";if(standalone){var scripts=document.getElementsByTagName("script"),index=scripts.length-1,myScript=scripts[index]||{src:""};queryString=myScript.src?myScript.src.replace(/^[^\?]+\??/,""):"",renderer=getQueryVariable("renderer")}var readyStateCheckInterval=setInterval(checkReady,100);try{"object"===("undefined"==typeof exports?"undefined":_typeof$3(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=lottie)}catch(t){}var ShapeModifiers=function(){var t={},e={};return t.registerModifier=function(t,i){e[t]||(e[t]=i)},t.getModifier=function(t,i,r){return new e[t](i,r)},t}();function ShapeModifier(){}function TrimModifier(){}function PuckerAndBloatModifier(){}ShapeModifier.prototype.initModifierProperties=function(){},ShapeModifier.prototype.addShapeToModifier=function(){},ShapeModifier.prototype.addShape=function(t){if(!this.closed){t.sh.container.addDynamicProperty(t.sh);var e={shape:t.sh,data:t,localShapeCollection:shapeCollectionPool.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},ShapeModifier.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=initialDefaultFrame,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},ShapeModifier.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},extendPrototype([DynamicPropertyContainer],ShapeModifier),extendPrototype([ShapeModifier],TrimModifier),TrimModifier.prototype.initModifierProperties=function(t,e){this.s=PropertyFactory.getProp(t,e.s,0,.01,this),this.e=PropertyFactory.getProp(t,e.e,0,.01,this),this.o=PropertyFactory.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},TrimModifier.prototype.addShapeToModifier=function(t){t.pathsData=[]},TrimModifier.prototype.calculateShapeEdges=function(t,e,i,r,s){var a=[];e<=1?a.push({s:t,e:e}):t>=1?a.push({s:t-1,e:e-1}):(a.push({s:t,e:1}),a.push({s:0,e:e-1}));var n,o,h=[],l=a.length;for(n=0;n<l;n+=1){var p,f;if(!((o=a[n]).e*s<r||o.s*s>r+i))p=o.s*s<=r?0:(o.s*s-r)/i,f=o.e*s>=r+i?1:(o.e*s-r)/i,h.push([p,f])}return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){var e,i=t.length;for(e=0;e<i;e+=1)segmentsLengthPool.release(t[e]);return t.length=0,t},TrimModifier.prototype.processShapes=function(t){var e,i,r,s;if(this._mdf||t){var a=this.o.v%360/360;if(a<0&&(a+=1),(e=this.s.v>1?1+a:this.s.v<0?0+a:this.s.v+a)>(i=this.e.v>1?1+a:this.e.v<0?0+a:this.e.v+a)){var n=e;e=i,i=n}e=1e-4*Math.round(1e4*e),i=1e-4*Math.round(1e4*i),this.sValue=e,this.eValue=i}else e=this.sValue,i=this.eValue;var o,h,l,p,f,m=this.shapes.length,c=0;if(i===e)for(s=0;s<m;s+=1)this.shapes[s].localShapeCollection.releaseShapes(),this.shapes[s].shape._mdf=!0,this.shapes[s].shape.paths=this.shapes[s].localShapeCollection,this._mdf&&(this.shapes[s].pathsData.length=0);else if(1===i&&0===e||0===i&&1===e){if(this._mdf)for(s=0;s<m;s+=1)this.shapes[s].pathsData.length=0,this.shapes[s].shape._mdf=!0}else{var d,u,y=[];for(s=0;s<m;s+=1)if((d=this.shapes[s]).shape._mdf||this._mdf||t||2===this.m){if(h=(r=d.shape.paths)._length,f=0,!d.shape._mdf&&d.pathsData.length)f=d.totalShapeLength;else{for(l=this.releasePathsData(d.pathsData),o=0;o<h;o+=1)p=bez.getSegmentsLength(r.shapes[o]),l.push(p),f+=p.totalLength;d.totalShapeLength=f,d.pathsData=l}c+=f,d.shape._mdf=!0}else d.shape.paths=d.localShapeCollection;var g,v=e,b=i,x=0;for(s=m-1;s>=0;s-=1)if((d=this.shapes[s]).shape._mdf){for((u=d.localShapeCollection).releaseShapes(),2===this.m&&m>1?(g=this.calculateShapeEdges(e,i,d.totalShapeLength,x,c),x+=d.totalShapeLength):g=[[v,b]],h=g.length,o=0;o<h;o+=1){v=g[o][0],b=g[o][1],y.length=0,b<=1?y.push({s:d.totalShapeLength*v,e:d.totalShapeLength*b}):v>=1?y.push({s:d.totalShapeLength*(v-1),e:d.totalShapeLength*(b-1)}):(y.push({s:d.totalShapeLength*v,e:d.totalShapeLength}),y.push({s:0,e:d.totalShapeLength*(b-1)}));var P=this.addShapes(d,y[0]);if(y[0].s!==y[0].e){if(y.length>1)if(d.shape.paths.shapes[d.shape.paths._length-1].c){var E=P.pop();this.addPaths(P,u),P=this.addShapes(d,y[1],E)}else this.addPaths(P,u),P=this.addShapes(d,y[1]);this.addPaths(P,u)}}d.shape.paths=u}}},TrimModifier.prototype.addPaths=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)e.addShape(t[i])},TrimModifier.prototype.addSegment=function(t,e,i,r,s,a,n){s.setXYAt(e[0],e[1],"o",a),s.setXYAt(i[0],i[1],"i",a+1),n&&s.setXYAt(t[0],t[1],"v",a),s.setXYAt(r[0],r[1],"v",a+1)},TrimModifier.prototype.addSegmentFromArray=function(t,e,i,r){e.setXYAt(t[1],t[5],"o",i),e.setXYAt(t[2],t[6],"i",i+1),r&&e.setXYAt(t[0],t[4],"v",i),e.setXYAt(t[3],t[7],"v",i+1)},TrimModifier.prototype.addShapes=function(t,e,i){var r,s,a,n,o,h,l,p,f=t.pathsData,m=t.shape.paths.shapes,c=t.shape.paths._length,d=0,u=[],y=!0;for(i?(o=i._length,p=i._length):(i=shapePool.newElement(),o=0,p=0),u.push(i),r=0;r<c;r+=1){for(h=f[r].lengths,i.c=m[r].c,a=m[r].c?h.length:h.length+1,s=1;s<a;s+=1)if(d+(n=h[s-1]).addedLength<e.s)d+=n.addedLength,i.c=!1;else{if(d>e.e){i.c=!1;break}e.s<=d&&e.e>=d+n.addedLength?(this.addSegment(m[r].v[s-1],m[r].o[s-1],m[r].i[s],m[r].v[s],i,o,y),y=!1):(l=bez.getNewSegment(m[r].v[s-1],m[r].v[s],m[r].o[s-1],m[r].i[s],(e.s-d)/n.addedLength,(e.e-d)/n.addedLength,h[s-1]),this.addSegmentFromArray(l,i,o,y),y=!1,i.c=!1),d+=n.addedLength,o+=1}if(m[r].c&&h.length){if(n=h[s-1],d<=e.e){var g=h[s-1].addedLength;e.s<=d&&e.e>=d+g?(this.addSegment(m[r].v[s-1],m[r].o[s-1],m[r].i[0],m[r].v[0],i,o,y),y=!1):(l=bez.getNewSegment(m[r].v[s-1],m[r].v[0],m[r].o[s-1],m[r].i[0],(e.s-d)/g,(e.e-d)/g,h[s-1]),this.addSegmentFromArray(l,i,o,y),y=!1,i.c=!1)}else i.c=!1;d+=n.addedLength,o+=1}if(i._length&&(i.setXYAt(i.v[p][0],i.v[p][1],"i",p),i.setXYAt(i.v[i._length-1][0],i.v[i._length-1][1],"o",i._length-1)),d>e.e)break;r<c-1&&(i=shapePool.newElement(),y=!0,u.push(i),o=0)}return u},extendPrototype([ShapeModifier],PuckerAndBloatModifier),PuckerAndBloatModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},PuckerAndBloatModifier.prototype.processPath=function(t,e){var i=e/100,r=[0,0],s=t._length,a=0;for(a=0;a<s;a+=1)r[0]+=t.v[a][0],r[1]+=t.v[a][1];r[0]/=s,r[1]/=s;var n,o,h,l,p,f,m=shapePool.newElement();for(m.c=t.c,a=0;a<s;a+=1)n=t.v[a][0]+(r[0]-t.v[a][0])*i,o=t.v[a][1]+(r[1]-t.v[a][1])*i,h=t.o[a][0]+(r[0]-t.o[a][0])*-i,l=t.o[a][1]+(r[1]-t.o[a][1])*-i,p=t.i[a][0]+(r[0]-t.i[a][0])*-i,f=t.i[a][1]+(r[1]-t.i[a][1])*-i,m.setTripleAt(n,o,h,l,p,f,a);return m},PuckerAndBloatModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amount.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var TransformPropertyFactory=function(){var t=[0,0];function e(t,e,i){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Matrix,this.pre=new Matrix,this.appliedTransformations=0,this.initDynamicPropertyContainer(i||t),e.p&&e.p.s?(this.px=PropertyFactory.getProp(t,e.p.x,0,0,this),this.py=PropertyFactory.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=PropertyFactory.getProp(t,e.p.z,0,0,this))):this.p=PropertyFactory.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=PropertyFactory.getProp(t,e.rx,0,degToRads,this),this.ry=PropertyFactory.getProp(t,e.ry,0,degToRads,this),this.rz=PropertyFactory.getProp(t,e.rz,0,degToRads,this),e.or.k[0].ti){var r,s=e.or.k.length;for(r=0;r<s;r+=1)e.or.k[r].to=null,e.or.k[r].ti=null}this.or=PropertyFactory.getProp(t,e.or,1,degToRads,this),this.or.sh=!0}else this.r=PropertyFactory.getProp(t,e.r||{k:0},0,degToRads,this);e.sk&&(this.sk=PropertyFactory.getProp(t,e.sk,0,degToRads,this),this.sa=PropertyFactory.getProp(t,e.sa,0,degToRads,this)),this.a=PropertyFactory.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=PropertyFactory.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=PropertyFactory.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return e.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(e){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||e){var i;if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var r,s;if(i=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime)this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(r=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/i,0),s=this.p.getValueAtTime(this.p.keyframes[0].t/i,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(r=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/i,0),s=this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/i,0)):(r=this.p.pv,s=this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/i,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){r=[],s=[];var a=this.px,n=this.py;a._caching.lastFrame+a.offsetTime<=a.keyframes[0].t?(r[0]=a.getValueAtTime((a.keyframes[0].t+.01)/i,0),r[1]=n.getValueAtTime((n.keyframes[0].t+.01)/i,0),s[0]=a.getValueAtTime(a.keyframes[0].t/i,0),s[1]=n.getValueAtTime(n.keyframes[0].t/i,0)):a._caching.lastFrame+a.offsetTime>=a.keyframes[a.keyframes.length-1].t?(r[0]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/i,0),r[1]=n.getValueAtTime(n.keyframes[n.keyframes.length-1].t/i,0),s[0]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/i,0),s[1]=n.getValueAtTime((n.keyframes[n.keyframes.length-1].t-.01)/i,0)):(r=[a.pv,n.pv],s[0]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/i,a.offsetTime),s[1]=n.getValueAtTime((n._caching.lastFrame+n.offsetTime-.01)/i,n.offsetTime))}else r=s=t;this.v.rotate(-Math.atan2(r[1]-s[1],r[0]-s[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],e),e.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},e.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,i,r){return new e(t,i,r)}}}();function RepeaterModifier(){}function RoundCornersModifier(){}function floatEqual(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function floatZero(t){return Math.abs(t)<=1e-5}function lerp(t,e,i){return t*(1-i)+e*i}function lerpPoint(t,e,i){return[lerp(t[0],e[0],i),lerp(t[1],e[1],i)]}function quadRoots(t,e,i){if(0===t)return[];var r=e*e-4*t*i;if(r<0)return[];var s=-e/(2*t);if(0===r)return[s];var a=Math.sqrt(r)/(2*t);return[s-a,s+a]}function polynomialCoefficients(t,e,i,r){return[3*e-t-3*i+r,3*t-6*e+3*i,-3*t+3*e,t]}function singlePoint(t){return new PolynomialBezier(t,t,t,t,!1)}function PolynomialBezier(t,e,i,r,s){s&&pointEqual(t,e)&&(e=lerpPoint(t,r,1/3)),s&&pointEqual(i,r)&&(i=lerpPoint(t,r,2/3));var a=polynomialCoefficients(t[0],e[0],i[0],r[0]),n=polynomialCoefficients(t[1],e[1],i[1],r[1]);this.a=[a[0],n[0]],this.b=[a[1],n[1]],this.c=[a[2],n[2]],this.d=[a[3],n[3]],this.points=[t,e,i,r]}function extrema(t,e){var i=t.points[0][e],r=t.points[t.points.length-1][e];if(i>r){var s=r;r=i,i=s}for(var a=quadRoots(3*t.a[e],2*t.b[e],t.c[e]),n=0;n<a.length;n+=1)if(a[n]>0&&a[n]<1){var o=t.point(a[n])[e];o<i?i=o:o>r&&(r=o)}return{min:i,max:r}}function intersectData(t,e,i){var r=t.boundingBox();return{cx:r.cx,cy:r.cy,width:r.width,height:r.height,bez:t,t:(e+i)/2,t1:e,t2:i}}function splitData(t){var e=t.bez.split(.5);return[intersectData(e[0],t.t1,t.t),intersectData(e[1],t.t,t.t2)]}function boxIntersect(t,e){return 2*Math.abs(t.cx-e.cx)<t.width+e.width&&2*Math.abs(t.cy-e.cy)<t.height+e.height}function intersectsImpl(t,e,i,r,s,a){if(boxIntersect(t,e))if(i>=a||t.width<=r&&t.height<=r&&e.width<=r&&e.height<=r)s.push([t.t,e.t]);else{var n=splitData(t),o=splitData(e);intersectsImpl(n[0],o[0],i+1,r,s,a),intersectsImpl(n[0],o[1],i+1,r,s,a),intersectsImpl(n[1],o[0],i+1,r,s,a),intersectsImpl(n[1],o[1],i+1,r,s,a)}}function crossProduct(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function lineIntersection(t,e,i,r){var s=[t[0],t[1],1],a=[e[0],e[1],1],n=[i[0],i[1],1],o=[r[0],r[1],1],h=crossProduct(crossProduct(s,a),crossProduct(n,o));return floatZero(h[2])?null:[h[0]/h[2],h[1]/h[2]]}function polarOffset(t,e,i){return[t[0]+Math.cos(e)*i,t[1]-Math.sin(e)*i]}function pointDistance(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function pointEqual(t,e){return floatEqual(t[0],e[0])&&floatEqual(t[1],e[1])}function ZigZagModifier(){}function setPoint(t,e,i,r,s,a,n){var o=i-Math.PI/2,h=i+Math.PI/2,l=e[0]+Math.cos(i)*r*s,p=e[1]-Math.sin(i)*r*s;t.setTripleAt(l,p,l+Math.cos(o)*a,p-Math.sin(o)*a,l+Math.cos(h)*n,p-Math.sin(h)*n,t.length())}function getPerpendicularVector(t,e){var i=[e[0]-t[0],e[1]-t[1]],r=.5*-Math.PI;return[Math.cos(r)*i[0]-Math.sin(r)*i[1],Math.sin(r)*i[0]+Math.cos(r)*i[1]]}function getProjectingAngle(t,e){var i=0===e?t.length()-1:e-1,r=(e+1)%t.length(),s=getPerpendicularVector(t.v[i],t.v[r]);return Math.atan2(0,1)-Math.atan2(s[1],s[0])}function zigZagCorner(t,e,i,r,s,a,n){var o=getProjectingAngle(e,i),h=e.v[i%e._length],l=e.v[0===i?e._length-1:i-1],p=e.v[(i+1)%e._length],f=2===a?Math.sqrt(Math.pow(h[0]-l[0],2)+Math.pow(h[1]-l[1],2)):0,m=2===a?Math.sqrt(Math.pow(h[0]-p[0],2)+Math.pow(h[1]-p[1],2)):0;setPoint(t,e.v[i%e._length],o,n,r,m/(2*(s+1)),f/(2*(s+1)),a)}function zigZagSegment(t,e,i,r,s,a){for(var n=0;n<r;n+=1){var o=(n+1)/(r+1),h=2===s?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(o);setPoint(t,e.point(o),l,a,i,h/(2*(r+1)),h/(2*(r+1)),s),a=-a}return a}function linearOffset(t,e,i){var r=Math.atan2(e[0]-t[0],e[1]-t[1]);return[polarOffset(t,r,i),polarOffset(e,r,i)]}function offsetSegment(t,e){var i,r,s,a,n,o,h;i=(h=linearOffset(t.points[0],t.points[1],e))[0],r=h[1],s=(h=linearOffset(t.points[1],t.points[2],e))[0],a=h[1],n=(h=linearOffset(t.points[2],t.points[3],e))[0],o=h[1];var l=lineIntersection(i,r,s,a);null===l&&(l=r);var p=lineIntersection(n,o,s,a);return null===p&&(p=n),new PolynomialBezier(i,l,p,o)}function joinLines(t,e,i,r,s){var a=e.points[3],n=i.points[0];if(3===r)return a;if(pointEqual(a,n))return a;if(2===r){var o=-e.tangentAngle(1),h=-i.tangentAngle(0)+Math.PI,l=lineIntersection(a,polarOffset(a,o+Math.PI/2,100),n,polarOffset(n,o+Math.PI/2,100)),p=l?pointDistance(l,a):pointDistance(a,n)/2,f=polarOffset(a,o,2*p*roundCorner);return t.setXYAt(f[0],f[1],"o",t.length()-1),f=polarOffset(n,h,2*p*roundCorner),t.setTripleAt(n[0],n[1],n[0],n[1],f[0],f[1],t.length()),n}var m=lineIntersection(pointEqual(a,e.points[2])?e.points[0]:e.points[2],a,n,pointEqual(n,i.points[1])?i.points[3]:i.points[1]);return m&&pointDistance(m,a)<s?(t.setTripleAt(m[0],m[1],m[0],m[1],m[0],m[1],t.length()),m):a}function getIntersection(t,e){var i=t.intersections(e);return i.length&&floatEqual(i[0][0],1)&&i.shift(),i.length?i[0]:null}function pruneSegmentIntersection(t,e){var i=t.slice(),r=e.slice(),s=getIntersection(t[t.length-1],e[0]);return s&&(i[t.length-1]=t[t.length-1].split(s[0])[0],r[0]=e[0].split(s[1])[1]),t.length>1&&e.length>1&&(s=getIntersection(t[0],e[e.length-1]))?[[t[0].split(s[0])[0]],[e[e.length-1].split(s[1])[1]]]:[i,r]}function pruneIntersections(t){for(var e,i=1;i<t.length;i+=1)e=pruneSegmentIntersection(t[i-1],t[i]),t[i-1]=e[0],t[i]=e[1];return t.length>1&&(e=pruneSegmentIntersection(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}function offsetSegmentSplit(t,e){var i,r,s,a,n=t.inflectionPoints();if(0===n.length)return[offsetSegment(t,e)];if(1===n.length||floatEqual(n[1],1))return i=(s=t.split(n[0]))[0],r=s[1],[offsetSegment(i,e),offsetSegment(r,e)];i=(s=t.split(n[0]))[0];var o=(n[1]-n[0])/(1-n[0]);return a=(s=s[1].split(o))[0],r=s[1],[offsetSegment(i,e),offsetSegment(a,e),offsetSegment(r,e)]}function OffsetPathModifier(){}function getFontProperties(t){for(var e=t.fStyle?t.fStyle.split(" "):[],i="normal",r="normal",s=e.length,a=0;a<s;a+=1)switch(e[a].toLowerCase()){case"italic":r="italic";break;case"bold":i="700";break;case"black":i="900";break;case"medium":i="500";break;case"regular":case"normal":i="400";break;case"light":case"thin":i="200"}return{style:r,weight:t.fWeight||i}}extendPrototype([ShapeModifier],RepeaterModifier),RepeaterModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=PropertyFactory.getProp(t,e.c,0,null,this),this.o=PropertyFactory.getProp(t,e.o,0,null,this),this.tr=TransformPropertyFactory.getTransformProperty(t,e.tr,this),this.so=PropertyFactory.getProp(t,e.tr.so,0,.01,this),this.eo=PropertyFactory.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Matrix,this.rMatrix=new Matrix,this.sMatrix=new Matrix,this.tMatrix=new Matrix,this.matrix=new Matrix},RepeaterModifier.prototype.applyTransforms=function(t,e,i,r,s,a){var n=a?-1:1,o=r.s.v[0]+(1-r.s.v[0])*(1-s),h=r.s.v[1]+(1-r.s.v[1])*(1-s);t.translate(r.p.v[0]*n*s,r.p.v[1]*n*s,r.p.v[2]),e.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),e.rotate(-r.r.v*n*s),e.translate(r.a.v[0],r.a.v[1],r.a.v[2]),i.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),i.scale(a?1/o:o,a?1/h:h),i.translate(r.a.v[0],r.a.v[1],r.a.v[2])},RepeaterModifier.prototype.init=function(t,e,i,r){for(this.elem=t,this.arr=e,this.pos=i,this.elemsData=r,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[i]);i>0;)i-=1,this._elements.unshift(e[i]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},RepeaterModifier.prototype.cloneElements=function(t){var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},RepeaterModifier.prototype.changeGroupRender=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)t[i]._render=e,"gr"===t[i].ty&&this.changeGroupRender(t[i].it,e)},RepeaterModifier.prototype.processShapes=function(t){var e,i,r,s,a,n=!1;if(this._mdf||t){var o,h=Math.ceil(this.c.v);if(this._groups.length<h){for(;this._groups.length<h;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(a=0,r=0;r<=this._groups.length-1;r+=1){if(o=a<h,this._groups[r]._render=o,this.changeGroupRender(this._groups[r].it,o),!o){var p=this.elemsData[r].it,f=p[p.length-1];0!==f.transform.op.v?(f.transform.op._mdf=!0,f.transform.op.v=0):f.transform.op._mdf=!1}a+=1}this._currentCopies=h;var m=this.o.v,c=m%1,d=m>0?Math.floor(m):Math.ceil(m),u=this.pMatrix.props,y=this.rMatrix.props,g=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var v,b,x=0;if(m>0){for(;x<d;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),x+=1;c&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,c,!1),x+=c)}else if(m<0){for(;x>d;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),x-=1;c&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-c,!0),x-=c)}for(r=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(b=(i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(r/(this._currentCopies-1)),0!==x){for((0!==r&&1===s||r!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]),this.matrix.transform(u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]),v=0;v<b;v+=1)i[v]=this.matrix.props[v];this.matrix.reset()}else for(this.matrix.reset(),v=0;v<b;v+=1)i[v]=this.matrix.props[v];x+=1,a-=1,r+=s}}else for(a=this._currentCopies,r=0,s=1;a;)i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,a-=1,r+=s;return n},RepeaterModifier.prototype.addShape=function(){},extendPrototype([ShapeModifier],RoundCornersModifier),RoundCornersModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=PropertyFactory.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},RoundCornersModifier.prototype.processPath=function(t,e){var i,r=shapePool.newElement();r.c=t.c;var s,a,n,o,h,l,p,f,m,c,d,u,y=t._length,g=0;for(i=0;i<y;i+=1)s=t.v[i],n=t.o[i],a=t.i[i],s[0]===n[0]&&s[1]===n[1]&&s[0]===a[0]&&s[1]===a[1]?0!==i&&i!==y-1||t.c?(o=0===i?t.v[y-1]:t.v[i-1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=d=s[0]+(o[0]-s[0])*l,f=u=s[1]-(s[1]-o[1])*l,m=p-(p-s[0])*roundCorner,c=f-(f-s[1])*roundCorner,r.setTripleAt(p,f,m,c,d,u,g),g+=1,o=i===y-1?t.v[0]:t.v[i+1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=m=s[0]+(o[0]-s[0])*l,f=c=s[1]+(o[1]-s[1])*l,d=p-(p-s[0])*roundCorner,u=f-(f-s[1])*roundCorner,r.setTripleAt(p,f,m,c,d,u,g),g+=1):(r.setTripleAt(s[0],s[1],n[0],n[1],a[0],a[1],g),g+=1):(r.setTripleAt(t.v[i][0],t.v[i][1],t.o[i][0],t.o[i][1],t.i[i][0],t.i[i][1],g),g+=1);return r},RoundCornersModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},PolynomialBezier.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},PolynomialBezier.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},PolynomialBezier.prototype.tangentAngle=function(t){var e=this.derivative(t);return Math.atan2(e[1],e[0])},PolynomialBezier.prototype.normalAngle=function(t){var e=this.derivative(t);return Math.atan2(e[0],e[1])},PolynomialBezier.prototype.inflectionPoints=function(){var t=this.a[1]*this.b[0]-this.a[0]*this.b[1];if(floatZero(t))return[];var e=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/t,i=e*e-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/t;if(i<0)return[];var r=Math.sqrt(i);return floatZero(r)?r>0&&r<1?[e]:[]:[e-r,e+r].filter((function(t){return t>0&&t<1}))},PolynomialBezier.prototype.split=function(t){if(t<=0)return[singlePoint(this.points[0]),this];if(t>=1)return[this,singlePoint(this.points[this.points.length-1])];var e=lerpPoint(this.points[0],this.points[1],t),i=lerpPoint(this.points[1],this.points[2],t),r=lerpPoint(this.points[2],this.points[3],t),s=lerpPoint(e,i,t),a=lerpPoint(i,r,t),n=lerpPoint(s,a,t);return[new PolynomialBezier(this.points[0],e,s,n,!0),new PolynomialBezier(n,a,r,this.points[3],!0)]},PolynomialBezier.prototype.bounds=function(){return{x:extrema(this,0),y:extrema(this,1)}},PolynomialBezier.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},PolynomialBezier.prototype.intersections=function(t,e,i){void 0===e&&(e=2),void 0===i&&(i=7);var r=[];return intersectsImpl(intersectData(this,0,1),intersectData(t,0,1),0,e,r,i),r},PolynomialBezier.shapeSegment=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[e],t.o[e],t.i[i],t.v[i],!0)},PolynomialBezier.shapeSegmentInverted=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[i],t.i[i],t.o[e],t.v[e],!0)},extendPrototype([ShapeModifier],ZigZagModifier),ZigZagModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=PropertyFactory.getProp(t,e.s,0,null,this),this.frequency=PropertyFactory.getProp(t,e.r,0,null,this),this.pointsType=PropertyFactory.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},ZigZagModifier.prototype.processPath=function(t,e,i,r){var s=t._length,a=shapePool.newElement();if(a.c=t.c,t.c||(s-=1),0===s)return a;var n=-1,o=PolynomialBezier.shapeSegment(t,0);zigZagCorner(a,t,0,e,i,r,n);for(var h=0;h<s;h+=1)n=zigZagSegment(a,o,e,i,r,-n),o=h!==s-1||t.c?PolynomialBezier.shapeSegment(t,(h+1)%s):null,zigZagCorner(a,t,h+1,e,i,r,n);return a},ZigZagModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amplitude.v,l=Math.max(0,Math.round(this.frequency.v)),p=this.pointsType.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h,l,p));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},extendPrototype([ShapeModifier],OffsetPathModifier),OffsetPathModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this.miterLimit=PropertyFactory.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},OffsetPathModifier.prototype.processPath=function(t,e,i,r){var s=shapePool.newElement();s.c=t.c;var a,n,o,h=t.length();t.c||(h-=1);var l=[];for(a=0;a<h;a+=1)o=PolynomialBezier.shapeSegment(t,a),l.push(offsetSegmentSplit(o,e));if(!t.c)for(a=h-1;a>=0;a-=1)o=PolynomialBezier.shapeSegmentInverted(t,a),l.push(offsetSegmentSplit(o,e));l=pruneIntersections(l);var p=null,f=null;for(a=0;a<l.length;a+=1){var m=l[a];for(f&&(p=joinLines(s,f,m[0],i,r)),f=m[m.length-1],n=0;n<m.length;n+=1)o=m[n],p&&pointEqual(o.points[0],p)?s.setXYAt(o.points[1][0],o.points[1][1],"o",s.length()-1):s.setTripleAt(o.points[0][0],o.points[0][1],o.points[1][0],o.points[1][1],o.points[0][0],o.points[0][1],s.length()),s.setTripleAt(o.points[3][0],o.points[3][1],o.points[3][0],o.points[3][1],o.points[2][0],o.points[2][1],s.length()),p=o.points[3]}return l.length&&joinLines(s,f,l[0][0],i,r),s},OffsetPathModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amount.v,l=this.miterLimit.v,p=this.lineJoin;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h,p,l));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var FontManager=function(){var t={w:0,size:0,shapes:[],data:{shapes:[]}},e=[];e=e.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);var i=127988,r=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function s(t,e){var i=createTag("span");i.setAttribute("aria-hidden",!0),i.style.fontFamily=e;var r=createTag("span");r.innerText="giItT1WQy@!-/#",i.style.position="absolute",i.style.left="-10000px",i.style.top="-10000px",i.style.fontSize="300px",i.style.fontVariant="normal",i.style.fontStyle="normal",i.style.fontWeight="normal",i.style.letterSpacing="0",i.appendChild(r),document.body.appendChild(i);var s=r.offsetWidth;return r.style.fontFamily=function(t){var e,i=t.split(","),r=i.length,s=[];for(e=0;e<r;e+=1)"sans-serif"!==i[e]&&"monospace"!==i[e]&&s.push(i[e]);return s.join(",")}(t)+", "+e,{node:r,w:s,parent:i}}function a(t,e){var i,r=document.body&&e?"svg":"canvas",s=getFontProperties(t);if("svg"===r){var a=createNS("text");a.style.fontSize="100px",a.setAttribute("font-family",t.fFamily),a.setAttribute("font-style",s.style),a.setAttribute("font-weight",s.weight),a.textContent="1",t.fClass?(a.style.fontFamily="inherit",a.setAttribute("class",t.fClass)):a.style.fontFamily=t.fFamily,e.appendChild(a),i=a}else{var n=new OffscreenCanvas(500,500).getContext("2d");n.font=s.style+" "+s.weight+" 100px "+t.fFamily,i=n}return{measureText:function(t){return"svg"===r?(i.textContent=t,i.getComputedTextLength()):i.measureText(t).width}}}function n(t){var e=0,i=t.charCodeAt(0);if(i>=55296&&i<=56319){var r=t.charCodeAt(1);r>=56320&&r<=57343&&(e=1024*(i-55296)+r-56320+65536)}return e}function o(t){var e=n(t);return e>=127462&&e<=127487}var h=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)};h.isModifier=function(t,e){var i=t.toString(16)+e.toString(16);return-1!==r.indexOf(i)},h.isZeroWidthJoiner=function(t){return 8205===t},h.isFlagEmoji=function(t){return o(t.substr(0,2))&&o(t.substr(2,2))},h.isRegionalCode=o,h.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},h.isRegionalFlag=function(t,e){var r=n(t.substr(e,2));if(r!==i)return!1;var s=0;for(e+=2;s<5;){if((r=n(t.substr(e,2)))<917601||r>917626)return!1;s+=1,e+=2}return 917631===n(t.substr(e,2))},h.isVariationSelector=function(t){return 65039===t},h.BLACK_FLAG_CODE_POINT=i;var l={addChars:function(t){if(t){var e;this.chars||(this.chars=[]);var i,r,s=t.length,a=this.chars.length;for(e=0;e<s;e+=1){for(i=0,r=!1;i<a;)this.chars[i].style===t[e].style&&this.chars[i].fFamily===t[e].fFamily&&this.chars[i].ch===t[e].ch&&(r=!0),i+=1;r||(this.chars.push(t[e]),a+=1)}}},addFonts:function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);if(!document.body)return this.isLoaded=!0,t.list.forEach((function(t){t.helper=a(t),t.cache={}})),void(this.fonts=t.list);var i,r=t.list,n=r.length,o=n;for(i=0;i<n;i+=1){var h,l,p=!0;if(r[i].loaded=!1,r[i].monoCase=s(r[i].fFamily,"monospace"),r[i].sansCase=s(r[i].fFamily,"sans-serif"),r[i].fPath){if("p"===r[i].fOrigin||3===r[i].origin){if((h=document.querySelectorAll('style[f-forigin="p"][f-family="'+r[i].fFamily+'"], style[f-origin="3"][f-family="'+r[i].fFamily+'"]')).length>0&&(p=!1),p){var f=createTag("style");f.setAttribute("f-forigin",r[i].fOrigin),f.setAttribute("f-origin",r[i].origin),f.setAttribute("f-family",r[i].fFamily),f.type="text/css",f.innerText="@font-face {font-family: "+r[i].fFamily+"; font-style: normal; src: url('"+r[i].fPath+"');}",e.appendChild(f)}}else if("g"===r[i].fOrigin||1===r[i].origin){for(h=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),l=0;l<h.length;l+=1)-1!==h[l].href.indexOf(r[i].fPath)&&(p=!1);if(p){var m=createTag("link");m.setAttribute("f-forigin",r[i].fOrigin),m.setAttribute("f-origin",r[i].origin),m.type="text/css",m.rel="stylesheet",m.href=r[i].fPath,document.body.appendChild(m)}}else if("t"===r[i].fOrigin||2===r[i].origin){for(h=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),l=0;l<h.length;l+=1)r[i].fPath===h[l].src&&(p=!1);if(p){var c=createTag("link");c.setAttribute("f-forigin",r[i].fOrigin),c.setAttribute("f-origin",r[i].origin),c.setAttribute("rel","stylesheet"),c.setAttribute("href",r[i].fPath),e.appendChild(c)}}}else r[i].loaded=!0,o-=1;r[i].helper=a(r[i],e),r[i].cache={},this.fonts.push(r[i])}0===o?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},getCharData:function(e,i,r){for(var s=0,a=this.chars.length;s<a;){if(this.chars[s].ch===e&&this.chars[s].style===i&&this.chars[s].fFamily===r)return this.chars[s];s+=1}return("string"==typeof e&&13!==e.charCodeAt(0)||!e)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",e,i,r)),t},getFontByName:function(t){for(var e=0,i=this.fonts.length;e<i;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,i){var r=this.getFontByName(e),s=t;if(!r.cache[s]){var a=r.helper;if(" "===t){var n=a.measureText("|"+t+"|"),o=a.measureText("||");r.cache[s]=(n-o)/100}else r.cache[s]=a.measureText(t)/100}return r.cache[s]*i},checkLoadedFonts:function(){var t,e,i,r=this.fonts.length,s=r;for(t=0;t<r;t+=1)this.fonts[t].loaded?s-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,i=this.fonts[t].monoCase.w,e.offsetWidth!==i?(s-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,i=this.fonts[t].sansCase.w,e.offsetWidth!==i&&(s-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==s&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}};return h.prototype=l,h}();function SlotManager(t){this.animationData=t}function slotFactory(t){return new SlotManager(t)}function RenderableElement(){}SlotManager.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},RenderableElement.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var getBlendMode=(blendModeEnums={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return blendModeEnums[t]||""}),blendModeEnums;function SliderEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function AngleEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function ColorEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function PointEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function LayerIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function MaskIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function CheckboxEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function NoValueEffect(){this.p={}}function EffectsManager(t,e){var i,r=t.ef||[];this.effectElements=[];var s,a=r.length;for(i=0;i<a;i+=1)s=new GroupEffect(r[i],e),this.effectElements.push(s)}function GroupEffect(t,e){this.init(t,e)}function BaseElement(){}function FrameElement(){}function FootageElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,i)}function AudioElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,i),this._isPlaying=!1,this._canPlay=!1;var r=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(r),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=PropertyFactory.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function BaseRenderer(){}extendPrototype([DynamicPropertyContainer],GroupEffect),GroupEffect.prototype.getValue=GroupEffect.prototype.iterateDynamicProperties,GroupEffect.prototype.init=function(t,e){var i;this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var r,s=this.data.ef.length,a=this.data.ef;for(i=0;i<s;i+=1){switch(r=null,a[i].ty){case 0:r=new SliderEffect(a[i],e,this);break;case 1:r=new AngleEffect(a[i],e,this);break;case 2:r=new ColorEffect(a[i],e,this);break;case 3:r=new PointEffect(a[i],e,this);break;case 4:case 7:r=new CheckboxEffect(a[i],e,this);break;case 10:r=new LayerIndexEffect(a[i],e,this);break;case 11:r=new MaskIndexEffect(a[i],e,this);break;case 5:r=new EffectsManager(a[i],e,this);break;default:r=new NoValueEffect(a[i],e,this)}r&&this.effectElements.push(r)}},BaseElement.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t=getExpressionInterfaces();if(t){var e=t("layer"),i=t("effects"),r=t("shape"),s=t("text"),a=t("comp");this.layerInterface=e(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var n=i.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(n),0===this.data.ty||this.data.xt?this.compInterface=a(this):4===this.data.ty?(this.layerInterface.shapeInterface=r(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=s(this),this.layerInterface.text=this.layerInterface.textInterface)}},setBlendMode:function(){var t=getBlendMode(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,i){this.globalData=e,this.comp=i,this.data=t,this.layerId=createElementID(),this.data.sr||(this.data.sr=1),this.effectsManager=new EffectsManager(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},FrameElement.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var i,r=this.dynamicProperties.length;for(i=0;i<r;i+=1)(e||this._isParent&&"transform"===this.dynamicProperties[i].propType)&&(this.dynamicProperties[i].getValue(),this.dynamicProperties[i]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},FootageElement.prototype.prepareFrame=function(){},extendPrototype([RenderableElement,BaseElement,FrameElement],FootageElement),FootageElement.prototype.getBaseElement=function(){return null},FootageElement.prototype.renderFrame=function(){},FootageElement.prototype.destroy=function(){},FootageElement.prototype.initExpressions=function(){var t=getExpressionInterfaces();if(t){var e=t("footage");this.layerInterface=e(this)}},FootageElement.prototype.getFootageData=function(){return this.footageData},AudioElement.prototype.prepareFrame=function(t){if(this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder)this._currentTime=t/this.data.sr;else{var e=this.tm.v;this._currentTime=e}this._volume=this.lv.v[0];var i=this._volume*this._volumeMultiplier;this._previousVolume!==i&&(this._previousVolume=i,this.audio.volume(i))},extendPrototype([RenderableElement,BaseElement,FrameElement],AudioElement),AudioElement.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek())>.1)&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},AudioElement.prototype.show=function(){},AudioElement.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},AudioElement.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},AudioElement.prototype.resume=function(){this._canPlay=!0},AudioElement.prototype.setRate=function(t){this.audio.rate(t)},AudioElement.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},AudioElement.prototype.getBaseElement=function(){return null},AudioElement.prototype.destroy=function(){},AudioElement.prototype.sourceRectAtTime=function(){},AudioElement.prototype.initExpressions=function(){},BaseRenderer.prototype.checkLayers=function(t){var e,i,r=this.layers.length;for(this.completeLayers=!0,e=r-1;e>=0;e-=1)this.elements[e]||(i=this.layers[e]).ip-i.st<=t-this.layers[e].st&&i.op-i.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:default:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t)}},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.createAudio=function(t){return new AudioElement(t,this.globalData,this)},BaseRenderer.prototype.createFootage=function(t){return new FootageElement(t,this.globalData,this)},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},BaseRenderer.prototype.includeLayers=function(t){var e;this.completeLayers=!1;var i,r=t.length,s=this.layers.length;for(e=0;e<r;e+=1)for(i=0;i<s;){if(this.layers[i].id===t[e].id){this.layers[i]=t[e];break}i+=1}},BaseRenderer.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},BaseRenderer.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},BaseRenderer.prototype.buildElementParenting=function(t,e,i){for(var r=this.elements,s=this.layers,a=0,n=s.length;a<n;)s[a].ind==e&&(r[a]&&!0!==r[a]?(i.push(r[a]),r[a].setAsParent(),void 0!==s[a].parent?this.buildElementParenting(t,s[a].parent,i):t.setHierarchy(i)):(this.buildItem(a),this.addPendingElement(t))),a+=1},BaseRenderer.prototype.addPendingElement=function(t){this.pendingElements.push(t)},BaseRenderer.prototype.searchExtraCompositions=function(t){var e,i=t.length;for(e=0;e<i;e+=1)if(t[e].xt){var r=this.createComp(t[e]);r.initExpressions(),this.globalData.projectInterface.registerComposition(r)}},BaseRenderer.prototype.getElementById=function(t){var e,i=this.elements.length;for(e=0;e<i;e+=1)if(this.elements[e].data.ind===t)return this.elements[e];return null},BaseRenderer.prototype.getElementByPath=function(t){var e,i=t.shift();if("number"==typeof i)e=this.elements[i];else{var r,s=this.elements.length;for(r=0;r<s;r+=1)if(this.elements[r].data.nm===i){e=this.elements[r];break}}return 0===t.length?e:e.getElementByPath(t)},BaseRenderer.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new FontManager,this.globalData.slotManager=slotFactory(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var effectTypes={TRANSFORM_EFFECT:"transformEFfect"};function TransformElement(){}function MaskElement(t,e,i){this.data=t,this.element=e,this.globalData=i,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var r,s,a=this.globalData.defs,n=this.masksProperties?this.masksProperties.length:0;this.viewData=createSizedArray(n),this.solidPath="";var o,h,l,p,f,m,c=this.masksProperties,d=0,u=[],y=createElementID(),g="clipPath",v="clip-path";for(r=0;r<n;r+=1)if(("a"!==c[r].mode&&"n"!==c[r].mode||c[r].inv||100!==c[r].o.k||c[r].o.x)&&(g="mask",v="mask"),"s"!==c[r].mode&&"i"!==c[r].mode||0!==d?l=null:((l=createNS("rect")).setAttribute("fill","#ffffff"),l.setAttribute("width",this.element.comp.data.w||0),l.setAttribute("height",this.element.comp.data.h||0),u.push(l)),s=createNS("path"),"n"===c[r].mode)this.viewData[r]={op:PropertyFactory.getProp(this.element,c[r].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[r],3),elem:s,lastPath:""},a.appendChild(s);else{var b;if(d+=1,s.setAttribute("fill","s"===c[r].mode?"#000000":"#ffffff"),s.setAttribute("clip-rule","nonzero"),0!==c[r].x.k?(g="mask",v="mask",m=PropertyFactory.getProp(this.element,c[r].x,0,null,this.element),b=createElementID(),(p=createNS("filter")).setAttribute("id",b),(f=createNS("feMorphology")).setAttribute("operator","erode"),f.setAttribute("in","SourceGraphic"),f.setAttribute("radius","0"),p.appendChild(f),a.appendChild(p),s.setAttribute("stroke","s"===c[r].mode?"#000000":"#ffffff")):(f=null,m=null),this.storedData[r]={elem:s,x:m,expan:f,lastPath:"",lastOperator:"",filterId:b,lastRadius:0},"i"===c[r].mode){h=u.length;var x=createNS("g");for(o=0;o<h;o+=1)x.appendChild(u[o]);var P=createNS("mask");P.setAttribute("mask-type","alpha"),P.setAttribute("id",y+"_"+d),P.appendChild(s),a.appendChild(P),x.setAttribute("mask","url("+getLocationHref()+"#"+y+"_"+d+")"),u.length=0,u.push(x)}else u.push(s);c[r].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[r]={elem:s,lastPath:"",op:PropertyFactory.getProp(this.element,c[r].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[r],3),invRect:l},this.viewData[r].prop.k||this.drawPath(c[r],this.viewData[r].prop.v,this.viewData[r])}for(this.maskElement=createNS(g),n=u.length,r=0;r<n;r+=1)this.maskElement.appendChild(u[r]);d>0&&(this.maskElement.setAttribute("id",y),this.element.maskedElement.setAttribute(v,"url("+getLocationHref()+"#"+y+")"),a.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}TransformElement.prototype={initTransform:function(){var t=new Matrix;this.finalTransform={mProp:this.data.ks?TransformPropertyFactory.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,i=0,r=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;i<r;){if(this.hierarchy[i].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}i+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),i=0;i<r;i+=1)e.multiply(this.hierarchy[i].finalTransform.mProp.v)}this.localTransforms&&!this.finalTransform._matMdf||(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var i=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(i),t=1;t<e;t+=1){var r=this.localTransforms[t].matrix;i.multiply(r)}i.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){var s=this.finalTransform.localOpacity;for(t=0;t<e;t+=1)s*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=s}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new Matrix;var e=0,i=t.length;for(e=0;e<i;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var i,r=!0,s=this.comp;r;)s.finalTransform?(s.data.hasMask&&e.splice(0,0,s.finalTransform),s=s.comp):r=!1;var a,n=e.length;for(i=0;i<n;i+=1)a=e[i].mat.applyToPointArray(0,0,0),t=[t[0]-a[0],t[1]-a[1],0];return t},mHelper:new Matrix},MaskElement.prototype.getMaskProperty=function(t){return this.viewData[t].prop},MaskElement.prototype.renderFrame=function(t){var e,i=this.element.finalTransform.mat,r=this.masksProperties.length;for(e=0;e<r;e+=1)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[e].invRect.setAttribute("transform",i.getInverseMatrix().to2dCSS()),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var s=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+getLocationHref()+"#"+this.storedData[e].filterId+")")),s.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},MaskElement.prototype.getMaskelement=function(){return this.maskElement},MaskElement.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},MaskElement.prototype.drawPath=function(t,e,i){var r,s,a=" M"+e.v[0][0]+","+e.v[0][1];for(s=e._length,r=1;r<s;r+=1)a+=" C"+e.o[r-1][0]+","+e.o[r-1][1]+" "+e.i[r][0]+","+e.i[r][1]+" "+e.v[r][0]+","+e.v[r][1];if(e.c&&s>1&&(a+=" C"+e.o[r-1][0]+","+e.o[r-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),i.lastPath!==a){var n="";i.elem&&(e.c&&(n=t.inv?this.solidPath+a:a),i.elem.setAttribute("d",n)),i.lastPath=a}},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var filtersFactory=function(){var t={};return t.createFilter=function(t,e){var i=createNS("filter");i.setAttribute("id",t),!0!==e&&(i.setAttribute("filterUnits","objectBoundingBox"),i.setAttribute("x","0%"),i.setAttribute("y","0%"),i.setAttribute("width","100%"),i.setAttribute("height","100%"));return i},t.createAlphaToLuminanceFilter=function(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},t}(),featureSupport=function(){var t={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),/firefox/i.test(navigator.userAgent)&&(t.svgLumaHidden=!1),t}(),registeredEffects$1={},idPrefix="filter_result_";function SVGEffects(t){var e,i,r="SourceGraphic",s=t.data.ef?t.data.ef.length:0,a=createElementID(),n=filtersFactory.createFilter(a,!0),o=0;for(this.filters=[],e=0;e<s;e+=1){i=null;var h=t.data.ef[e].ty;if(registeredEffects$1[h])i=new(0,registeredEffects$1[h].effect)(n,t.effectsManager.effectElements[e],t,idPrefix+o,r),r=idPrefix+o,registeredEffects$1[h].countsAsEffect&&(o+=1);i&&this.filters.push(i)}o&&(t.globalData.defs.appendChild(n),t.layerElement.setAttribute("filter","url("+getLocationHref()+"#"+a+")")),this.filters.length&&t.addRenderableComponent(this)}function registerEffect$1(t,e,i){registeredEffects$1[t]={effect:e,countsAsEffect:i}}function SVGBaseElement(){}function HierarchyElement(){}function RenderableDOMElement(){}function IImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,i),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ProcessedElement(t,e){this.elem=t,this.pos=e}function IShapeElement(){}SVGEffects.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},SVGEffects.prototype.getEffects=function(t){var e,i=this.filters.length,r=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&r.push(this.filters[e]);return r},SVGBaseElement.prototype={initRendererElement:function(){this.layerElement=createNS("g")},createContainerElements:function(){this.matteElement=createNS("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t=null;if(this.data.td){this.matteMasks={};var e=createNS("g");e.setAttribute("id",this.layerId),e.appendChild(this.layerElement),t=e,this.globalData.defs.appendChild(e)}else this.data.tt?(this.matteElement.appendChild(this.layerElement),t=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var i=createNS("clipPath"),r=createNS("path");r.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var s=createElementID();if(i.setAttribute("id",s),i.appendChild(r),this.globalData.defs.appendChild(i),this.checkMasks()){var a=createNS("g");a.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),a.appendChild(this.layerElement),this.transformedElement=a,t?t.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData),this.renderableEffectsManager=new SVGEffects(this),this.searchEffectTransforms()},getMatte:function(t){if(this.matteMasks||(this.matteMasks={}),!this.matteMasks[t]){var e,i,r,s,a=this.layerId+"_"+t;if(1===t||3===t){var n=createNS("mask");n.setAttribute("id",a),n.setAttribute("mask-type",3===t?"luminance":"alpha"),(r=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),n.appendChild(r),this.globalData.defs.appendChild(n),featureSupport.maskType||1!==t||(n.setAttribute("mask-type","luminance"),e=createElementID(),i=filtersFactory.createFilter(e),this.globalData.defs.appendChild(i),i.appendChild(filtersFactory.createAlphaToLuminanceFilter()),(s=createNS("g")).appendChild(r),n.appendChild(s),s.setAttribute("filter","url("+getLocationHref()+"#"+e+")"))}else if(2===t){var o=createNS("mask");o.setAttribute("id",a),o.setAttribute("mask-type","alpha");var h=createNS("g");o.appendChild(h),e=createElementID(),i=filtersFactory.createFilter(e);var l=createNS("feComponentTransfer");l.setAttribute("in","SourceGraphic"),i.appendChild(l);var p=createNS("feFuncA");p.setAttribute("type","table"),p.setAttribute("tableValues","1.0 0.0"),l.appendChild(p),this.globalData.defs.appendChild(i);var f=createNS("rect");f.setAttribute("width",this.comp.data.w),f.setAttribute("height",this.comp.data.h),f.setAttribute("x","0"),f.setAttribute("y","0"),f.setAttribute("fill","#ffffff"),f.setAttribute("opacity","0"),h.setAttribute("filter","url("+getLocationHref()+"#"+e+")"),h.appendChild(f),(r=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),h.appendChild(r),featureSupport.maskType||(o.setAttribute("mask-type","luminance"),i.appendChild(filtersFactory.createAlphaToLuminanceFilter()),s=createNS("g"),h.appendChild(f),s.appendChild(this.layerElement),h.appendChild(s)),this.globalData.defs.appendChild(o)}this.matteMasks[t]=a}return this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+getLocationHref()+"#"+t+")")}},HierarchyElement.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},extendPrototype([RenderableElement,createProxyFunction({initElement:function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],RenderableDOMElement),extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],IImageElement),IImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=createNS("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},IImageElement.prototype.sourceRectAtTime=function(){return this.sourceRect},IShapeElement.prototype={addShapeToModifiers:function(t){var e,i=this.shapeModifiers.length;for(e=0;e<i;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;t>=0&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,i=0,r=e.length;i<r;){if(e[i].elem===t)return e[i].pos;i+=1}return 0},addProcessedElement:function(t,e){for(var i=this.processedElements,r=i.length;r;)if(i[r-=1].elem===t)return void(i[r].pos=e);i.push(new ProcessedElement(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var lineCapEnum={1:"butt",2:"round",3:"square"},lineJoinEnum={1:"miter",2:"round",3:"bevel"};function SVGShapeData(t,e,i){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=i,this.lvl=e,this._isAnimated=!!i.k;for(var r=0,s=t.length;r<s;){if(t[r].mProps.dynamicProperties.length){this._isAnimated=!0;break}r+=1}}function SVGStyleData(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=createNS("path"),this.msElem=null}function DashProperty(t,e,i,r){var s;this.elem=t,this.frameId=-1,this.dataProps=createSizedArray(e.length),this.renderer=i,this.k=!1,this.dashStr="",this.dashArray=createTypedArray("float32",e.length?e.length-1:0),this.dashoffset=createTypedArray("float32",1),this.initDynamicPropertyContainer(r);var a,n=e.length||0;for(s=0;s<n;s+=1)a=PropertyFactory.getProp(t,e[s].v,0,0,this),this.k=a.k||this.k,this.dataProps[s]={n:e[s].n,p:a};this.k||this.getValue(!0),this._isAnimated=this.k}function SVGStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i,this._isAnimated=!!this._isAnimated}function SVGFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i}function SVGNoStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=i}function GradientProperty(t,e,i){this.data=e,this.c=createTypedArray("uint8c",4*e.p);var r=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=createTypedArray("float32",r),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=r,this.initDynamicPropertyContainer(i),this.prop=PropertyFactory.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function SVGGradientFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,i)}function SVGGradientStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.initGradientData(t,e,i),this._isAnimated=!!this._isAnimated}function ShapeGroupData(){this.it=[],this.prevViewData=[],this.gr=createNS("g")}function SVGTransformData(t,e,i){this.transform={mProps:t,op:e,container:i},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}SVGShapeData.prototype.setAsAnimated=function(){this._isAnimated=!0},SVGStyleData.prototype.reset=function(){this.d="",this._mdf=!1},DashProperty.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,i=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<i;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},extendPrototype([DynamicPropertyContainer],DashProperty),extendPrototype([DynamicPropertyContainer],SVGStrokeStyleData),extendPrototype([DynamicPropertyContainer],SVGFillStyleData),extendPrototype([DynamicPropertyContainer],SVGNoStyleData),GradientProperty.prototype.comparePoints=function(t,e){for(var i=0,r=this.o.length/2;i<r;){if(Math.abs(t[4*i]-t[4*e+2*i])>.01)return!1;i+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},GradientProperty.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,i,r,s=4*this.data.p;for(e=0;e<s;e+=1)i=e%4==0?100:255,r=Math.round(this.prop.v[e]*i),this.c[e]!==r&&(this.c[e]=r,this._cmdf=!t);if(this.o.length)for(s=this.prop.v.length,e=4*this.data.p;e<s;e+=1)i=e%2==0?100:1,r=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==r&&(this.o[e-4*this.data.p]=r,this._omdf=!t);this._mdf=!t}},extendPrototype([DynamicPropertyContainer],GradientProperty),SVGGradientFillStyleData.prototype.initGradientData=function(t,e,i){this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.s=PropertyFactory.getProp(t,e.s,1,null,this),this.e=PropertyFactory.getProp(t,e.e,1,null,this),this.h=PropertyFactory.getProp(t,e.h||{k:0},0,.01,this),this.a=PropertyFactory.getProp(t,e.a||{k:0},0,degToRads,this),this.g=new GradientProperty(t,e.g,this),this.style=i,this.stops=[],this.setGradientData(i.pElem,e),this.setGradientOpacity(e,i),this._isAnimated=!!this._isAnimated},SVGGradientFillStyleData.prototype.setGradientData=function(t,e){var i=createElementID(),r=createNS(1===e.t?"linearGradient":"radialGradient");r.setAttribute("id",i),r.setAttribute("spreadMethod","pad"),r.setAttribute("gradientUnits","userSpaceOnUse");var s,a,n,o=[];for(n=4*e.g.p,a=0;a<n;a+=4)s=createNS("stop"),r.appendChild(s),o.push(s);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+getLocationHref()+"#"+i+")"),this.gf=r,this.cst=o},SVGGradientFillStyleData.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){var i,r,s,a=createNS("mask"),n=createNS("path");a.appendChild(n);var o=createElementID(),h=createElementID();a.setAttribute("id",h);var l=createNS(1===t.t?"linearGradient":"radialGradient");l.setAttribute("id",o),l.setAttribute("spreadMethod","pad"),l.setAttribute("gradientUnits","userSpaceOnUse"),s=t.g.k.k[0].s?t.g.k.k[0].s.length:t.g.k.k.length;var p=this.stops;for(r=4*t.g.p;r<s;r+=2)(i=createNS("stop")).setAttribute("stop-color","rgb(255,255,255)"),l.appendChild(i),p.push(i);n.setAttribute("gf"===t.ty?"fill":"stroke","url("+getLocationHref()+"#"+o+")"),"gs"===t.ty&&(n.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),n.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),1===t.lj&&n.setAttribute("stroke-miterlimit",t.ml)),this.of=l,this.ms=a,this.ost=p,this.maskId=h,e.msElem=n}},extendPrototype([DynamicPropertyContainer],SVGGradientFillStyleData),extendPrototype([SVGGradientFillStyleData,DynamicPropertyContainer],SVGGradientStrokeStyleData);var buildShapeString=function(t,e,i,r){if(0===e)return"";var s,a=t.o,n=t.i,o=t.v,h=" M"+r.applyToPointStringified(o[0][0],o[0][1]);for(s=1;s<e;s+=1)h+=" C"+r.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+r.applyToPointStringified(n[s][0],n[s][1])+" "+r.applyToPointStringified(o[s][0],o[s][1]);return i&&e&&(h+=" C"+r.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+r.applyToPointStringified(n[0][0],n[0][1])+" "+r.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},SVGElementsRenderer=function(){var t=new Matrix,e=new Matrix;function i(t,e,i){(i||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(i||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function r(){}function s(i,r,s){var a,n,o,h,l,p,f,m,c,d,u=r.styles.length,y=r.lvl;for(p=0;p<u;p+=1){if(h=r.sh._mdf||s,r.styles[p].lvl<y){for(m=e.reset(),c=y-r.styles[p].lvl,d=r.transformers.length-1;!h&&c>0;)h=r.transformers[d].mProps._mdf||h,c-=1,d-=1;if(h)for(c=y-r.styles[p].lvl,d=r.transformers.length-1;c>0;)m.multiply(r.transformers[d].mProps.v),c-=1,d-=1}else m=t;if(n=(f=r.sh.paths)._length,h){for(o="",a=0;a<n;a+=1)(l=f.shapes[a])&&l._length&&(o+=buildShapeString(l,l._length,l.c,m));r.caches[p]=o}else o=r.caches[p];r.styles[p].d+=!0===i.hd?"":o,r.styles[p]._mdf=h||r.styles[p]._mdf}}function a(t,e,i){var r=e.style;(e.c._mdf||i)&&r.pElem.setAttribute("fill","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("fill-opacity",e.o.v)}function n(t,e,i){o(t,e,i),h(t,e,i)}function o(t,e,i){var r,s,a,n,o,h=e.gf,l=e.g._hasOpacity,p=e.s.v,f=e.e.v;if(e.o._mdf||i){var m="gf"===t.ty?"fill-opacity":"stroke-opacity";e.style.pElem.setAttribute(m,e.o.v)}if(e.s._mdf||i){var c=1===t.t?"x1":"cx",d="x1"===c?"y1":"cy";h.setAttribute(c,p[0]),h.setAttribute(d,p[1]),l&&!e.g._collapsable&&(e.of.setAttribute(c,p[0]),e.of.setAttribute(d,p[1]))}if(e.g._cmdf||i){r=e.cst;var u=e.g.c;for(a=r.length,s=0;s<a;s+=1)(n=r[s]).setAttribute("offset",u[4*s]+"%"),n.setAttribute("stop-color","rgb("+u[4*s+1]+","+u[4*s+2]+","+u[4*s+3]+")")}if(l&&(e.g._omdf||i)){var y=e.g.o;for(a=(r=e.g._collapsable?e.cst:e.ost).length,s=0;s<a;s+=1)n=r[s],e.g._collapsable||n.setAttribute("offset",y[2*s]+"%"),n.setAttribute("stop-opacity",y[2*s+1])}if(1===t.t)(e.e._mdf||i)&&(h.setAttribute("x2",f[0]),h.setAttribute("y2",f[1]),l&&!e.g._collapsable&&(e.of.setAttribute("x2",f[0]),e.of.setAttribute("y2",f[1])));else if((e.s._mdf||e.e._mdf||i)&&(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)),h.setAttribute("r",o),l&&!e.g._collapsable&&e.of.setAttribute("r",o)),e.s._mdf||e.e._mdf||e.h._mdf||e.a._mdf||i){o||(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)));var g=Math.atan2(f[1]-p[1],f[0]-p[0]),v=e.h.v;v>=1?v=.99:v<=-1&&(v=-.99);var b=o*v,x=Math.cos(g+e.a.v)*b+p[0],P=Math.sin(g+e.a.v)*b+p[1];h.setAttribute("fx",x),h.setAttribute("fy",P),l&&!e.g._collapsable&&(e.of.setAttribute("fx",x),e.of.setAttribute("fy",P))}}function h(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||i)&&s.dashStr&&(r.pElem.setAttribute("stroke-dasharray",s.dashStr),r.pElem.setAttribute("stroke-dashoffset",s.dashoffset[0])),e.c&&(e.c._mdf||i)&&r.pElem.setAttribute("stroke","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||i)&&(r.pElem.setAttribute("stroke-width",e.w.v),r.msElem&&r.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function(t){switch(t.ty){case"fl":return a;case"gf":return o;case"gs":return n;case"st":return h;case"sh":case"el":case"rc":case"sr":return s;case"tr":return i;case"no":return r;default:return null}}}}();function SVGShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,i),this.prevViewData=[]}function LetterProps(t,e,i,r,s,a){this.o=t,this.sw=e,this.sc=i,this.fc=r,this.m=s,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!i,fc:!!r,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){var t,e,i,r,s=this.shapes.length,a=this.stylesList.length,n=[],o=!1;for(i=0;i<a;i+=1){for(r=this.stylesList[i],o=!1,n.length=0,t=0;t<s;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(r)&&(n.push(e),o=e._isAnimated||o);n.length>1&&o&&this.setShapesAsAnimated(n)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].setAsAnimated()},SVGShapeElement.prototype.createStyleElement=function(t,e){var i,r=new SVGStyleData(t,e),s=r.pElem;if("st"===t.ty)i=new SVGStrokeStyleData(this,t,r);else if("fl"===t.ty)i=new SVGFillStyleData(this,t,r);else if("gf"===t.ty||"gs"===t.ty){i=new("gf"===t.ty?SVGGradientFillStyleData:SVGGradientStrokeStyleData)(this,t,r),this.globalData.defs.appendChild(i.gf),i.maskId&&(this.globalData.defs.appendChild(i.ms),this.globalData.defs.appendChild(i.of),s.setAttribute("mask","url("+getLocationHref()+"#"+i.maskId+")"))}else"no"===t.ty&&(i=new SVGNoStyleData(this,t,r));return"st"!==t.ty&&"gs"!==t.ty||(s.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),s.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),s.setAttribute("fill-opacity","0"),1===t.lj&&s.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&s.setAttribute("fill-rule","evenodd"),t.ln&&s.setAttribute("id",t.ln),t.cl&&s.setAttribute("class",t.cl),t.bm&&(s.style["mix-blend-mode"]=getBlendMode(t.bm)),this.stylesList.push(r),this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createGroupElement=function(t){var e=new ShapeGroupData;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=getBlendMode(t.bm)),e},SVGShapeElement.prototype.createTransformElement=function(t,e){var i=TransformPropertyFactory.getTransformProperty(this,t,this),r=new SVGTransformData(i,i.o,e);return this.addToAnimatedContents(t,r),r},SVGShapeElement.prototype.createShapeElement=function(t,e,i){var r=4;"rc"===t.ty?r=5:"el"===t.ty?r=6:"sr"===t.ty&&(r=7);var s=new SVGShapeData(e,i,ShapePropertyFactory.getShapeProp(this,t,r,this));return this.shapes.push(s),this.addShapeToModifiers(s),this.addToAnimatedContents(t,s),s},SVGShapeElement.prototype.addToAnimatedContents=function(t,e){for(var i=0,r=this.animatedContents.length;i<r;){if(this.animatedContents[i].element===e)return;i+=1}this.animatedContents.push({fn:SVGElementsRenderer.createRenderFunction(t),element:e,data:t})},SVGShapeElement.prototype.setElementStyles=function(t){var e,i=t.styles,r=this.stylesList.length;for(e=0;e<r;e+=1)-1!==i.indexOf(this.stylesList[e])||this.stylesList[e].closed||i.push(this.stylesList[e])},SVGShapeElement.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},SVGShapeElement.prototype.searchShapes=function(t,e,i,r,s,a,n){var o,h,l,p,f,m,c=[].concat(a),d=t.length-1,u=[],y=[];for(o=d;o>=0;o-=1){if((m=this.searchProcessedElement(t[o]))?e[o]=i[m-1]:t[o]._render=n,"fl"===t[o].ty||"st"===t[o].ty||"gf"===t[o].ty||"gs"===t[o].ty||"no"===t[o].ty)m?e[o].style.closed=t[o].hd:e[o]=this.createStyleElement(t[o],s),t[o]._render&&e[o].style.pElem.parentNode!==r&&r.appendChild(e[o].style.pElem),u.push(e[o].style);else if("gr"===t[o].ty){if(m)for(l=e[o].it.length,h=0;h<l;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,s+1,c,n),t[o]._render&&e[o].gr.parentNode!==r&&r.appendChild(e[o].gr)}else"tr"===t[o].ty?(m||(e[o]=this.createTransformElement(t[o],r)),p=e[o].transform,c.push(p)):"sh"===t[o].ty||"rc"===t[o].ty||"el"===t[o].ty||"sr"===t[o].ty?(m||(e[o]=this.createShapeElement(t[o],c,s)),this.setElementStyles(e[o])):"tm"===t[o].ty||"rd"===t[o].ty||"ms"===t[o].ty||"pb"===t[o].ty||"zz"===t[o].ty||"op"===t[o].ty?(m?(f=e[o]).closed=!1:((f=ShapeModifiers.getModifier(t[o].ty)).init(this,t[o]),e[o]=f,this.shapeModifiers.push(f)),y.push(f)):"rp"===t[o].ty&&(m?(f=e[o]).closed=!0:(f=ShapeModifiers.getModifier(t[o].ty),e[o]=f,f.init(this,t,o,e),this.shapeModifiers.push(f),n=!1),y.push(f));this.addProcessedElement(t[o],o+1)}for(d=u.length,o=0;o<d;o+=1)u[o].closed=!0;for(d=y.length,o=0;o<d;o+=1)y[o].closed=!0},SVGShapeElement.prototype.renderInnerContent=function(){var t;this.renderModifiers();var e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},SVGShapeElement.prototype.renderShape=function(){var t,e,i=this.animatedContents.length;for(t=0;t<i;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},SVGShapeElement.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},LetterProps.prototype.update=function(t,e,i,r,s,a){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1,this._mdf.p=!1;var n=!1;return this.o!==t&&(this.o=t,this._mdf.o=!0,n=!0),this.sw!==e&&(this.sw=e,this._mdf.sw=!0,n=!0),this.sc!==i&&(this.sc=i,this._mdf.sc=!0,n=!0),this.fc!==r&&(this.fc=r,this._mdf.fc=!0,n=!0),this.m!==s&&(this.m=s,this._mdf.m=!0,n=!0),!a.length||this.p[0]===a[0]&&this.p[1]===a[1]&&this.p[4]===a[4]&&this.p[5]===a[5]&&this.p[12]===a[12]&&this.p[13]===a[13]||(this.p=a,this._mdf.p=!0,n=!0),n},TextProperty.prototype.defaultBoxWidth=[0,0],TextProperty.prototype.copyData=function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},TextProperty.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},TextProperty.prototype.searchProperty=function(){return this.searchKeyframes()},TextProperty.prototype.searchKeyframes=function(){return this.kf=this.data.d.k.length>1,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,i=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{var r;this.lock=!0,this._mdf=!1;var s=this.effectsSequence.length,a=t||this.data.d.k[this.keysIndex].s;for(r=0;r<s;r+=1)a=i!==this.keysIndex?this.effectsSequence[r](a,a.t):this.effectsSequence[r](this.currentData,a.t);e!==a&&this.setCurrentData(a),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},TextProperty.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,i=0,r=t.length;i<=r-1&&!(i===r-1||t[i+1].t>e);)i+=1;return this.keysIndex!==i&&(this.keysIndex=i),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e,i,r=[],s=0,a=t.length,n=!1,o=!1,h="";s<a;)n=o,o=!1,e=t.charCodeAt(s),h=t.charAt(s),FontManager.isCombinedCharacter(e)?n=!0:e>=55296&&e<=56319?FontManager.isRegionalFlag(t,s)?h=t.substr(s,14):(i=t.charCodeAt(s+1))>=56320&&i<=57343&&(FontManager.isModifier(e,i)?(h=t.substr(s,2),n=!0):h=FontManager.isFlagEmoji(t.substr(s,4))?t.substr(s,4):t.substr(s,2)):e>56319?(i=t.charCodeAt(s+1),FontManager.isVariationSelector(e)&&(n=!0)):FontManager.isZeroWidthJoiner(e)&&(n=!0,o=!0),n?(r[r.length-1]+=h,n=!1):r.push(h),s+=h.length;return r},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,i,r,s,a,n,o,h=this.elem.globalData.fontManager,l=this.data,p=[],f=0,m=l.m.g,c=0,d=0,u=0,y=[],g=0,v=0,b=h.getFontByName(t.f),x=0,P=getFontProperties(b);t.fWeight=P.weight,t.fStyle=P.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),i=t.finalText.length,t.finalLineHeight=t.lh;var E,S=t.tr/1e3*t.finalSize;if(t.sz)for(var C,_,A=!0,T=t.sz[0],M=t.sz[1];A;){C=0,g=0,i=(_=this.buildFinalText(t.t)).length,S=t.tr/1e3*t.finalSize;var k=-1;for(e=0;e<i;e+=1)E=_[e].charCodeAt(0),r=!1," "===_[e]?k=e:13!==E&&3!==E||(g=0,r=!0,C+=t.finalLineHeight||1.2*t.finalSize),h.chars?(o=h.getCharData(_[e],b.fStyle,b.fFamily),x=r?0:o.w*t.finalSize/100):x=h.measureText(_[e],t.f,t.finalSize),g+x>T&&" "!==_[e]?(-1===k?i+=1:e=k,C+=t.finalLineHeight||1.2*t.finalSize,_.splice(e,k===e?1:0,"\r"),k=-1,g=0):(g+=x,g+=S);C+=b.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&M<C?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=_,i=t.finalText.length,A=!1)}g=-S,x=0;var D,F=0;for(e=0;e<i;e+=1)if(r=!1,13===(E=(D=t.finalText[e]).charCodeAt(0))||3===E?(F=0,y.push(g),v=g>v?g:v,g=-2*S,s="",r=!0,u+=1):s=D,h.chars?(o=h.getCharData(D,b.fStyle,h.getFontByName(t.f).fFamily),x=r?0:o.w*t.finalSize/100):x=h.measureText(s,t.f,t.finalSize)," "===D?F+=x+S:(g+=x+S+F,F=0),p.push({l:x,an:x,add:c,n:r,anIndexes:[],val:s,line:u,animatorJustifyOffset:0}),2==m){if(c+=x,""===s||" "===s||e===i-1){for(""!==s&&" "!==s||(c-=x);d<=e;)p[d].an=c,p[d].ind=f,p[d].extra=x,d+=1;f+=1,c=0}}else if(3==m){if(c+=x,""===s||e===i-1){for(""===s&&(c-=x);d<=e;)p[d].an=c,p[d].ind=f,p[d].extra=x,d+=1;c=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=g>v?g:v,y.push(g),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=y;var w,I,V,B,R=l.a;n=R.length;var L=[];for(a=0;a<n;a+=1){for((w=R[a]).a.sc&&(t.strokeColorAnim=!0),w.a.sw&&(t.strokeWidthAnim=!0),(w.a.fc||w.a.fh||w.a.fs||w.a.fb)&&(t.fillColorAnim=!0),B=0,V=w.s.b,e=0;e<i;e+=1)(I=p[e]).anIndexes[a]=B,(1==V&&""!==I.val||2==V&&""!==I.val&&" "!==I.val||3==V&&(I.n||" "==I.val||e==i-1)||4==V&&(I.n||e==i-1))&&(1===w.s.rn&&L.push(B),B+=1);l.a[a].s.totalChars=B;var G,z=-1;if(1===w.s.rn)for(e=0;e<i;e+=1)z!=(I=p[e]).anIndexes[a]&&(z=I.anIndexes[a],G=L.splice(Math.floor(Math.random()*L.length),1)[0]),I.anIndexes[a]=G}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=b.ascent*t.finalSize/100},TextProperty.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var i=this.copyData({},this.data.d.k[e].s);i=this.copyData(i,t),this.data.d.k[e].s=i,this.recalculate(e),this.setCurrentData(i),this.elem.addDynamicProperty(this)},TextProperty.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},TextProperty.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},TextProperty.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var TextSelectorProp=function(){var t=Math.max,e=Math.min,i=Math.floor;function r(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=PropertyFactory.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?PropertyFactory.getProp(t,e.e,0,0,this):{v:100},this.o=PropertyFactory.getProp(t,e.o||{k:0},0,0,this),this.xe=PropertyFactory.getProp(t,e.xe||{k:0},0,0,this),this.ne=PropertyFactory.getProp(t,e.ne||{k:0},0,0,this),this.sm=PropertyFactory.getProp(t,e.sm||{k:100},0,0,this),this.a=PropertyFactory.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return r.prototype={getMult:function(r){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var s=0,a=0,n=1,o=1;this.ne.v>0?s=this.ne.v/100:a=-this.ne.v/100,this.xe.v>0?n=1-this.xe.v/100:o=1+this.xe.v/100;var h=BezierFactory.getBezierEasing(s,a,n,o).get,l=0,p=this.finalS,f=this.finalE,m=this.data.sh;if(2===m)l=h(l=f===p?r>=f?1:0:t(0,e(.5/(f-p)+(r-p)/(f-p),1)));else if(3===m)l=h(l=f===p?r>=f?0:1:1-t(0,e(.5/(f-p)+(r-p)/(f-p),1)));else if(4===m)f===p?l=0:(l=t(0,e(.5/(f-p)+(r-p)/(f-p),1)))<.5?l*=2:l=1-2*(l-.5),l=h(l);else if(5===m){if(f===p)l=0;else{var c=f-p,d=-c/2+(r=e(t(0,r+.5-p),f-p)),u=c/2;l=Math.sqrt(1-d*d/(u*u))}l=h(l)}else 6===m?(f===p?l=0:(r=e(t(0,r+.5-p),f-p),l=(1+Math.cos(Math.PI+2*Math.PI*r/(f-p)))/2),l=h(l)):(r>=i(p)&&(l=t(0,e(r-p<0?e(f,1)-(p-r):f-r,1))),l=h(l));if(100!==this.sm.v){var y=.01*this.sm.v;0===y&&(y=1e-8);var g=.5-.5*y;l<g?l=0:(l=(l-g)/y)>1&&(l=1)}return l*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,i=this.o.v/e,r=this.s.v/e+i,s=this.e.v/e+i;if(r>s){var a=r;r=s,s=a}this.finalS=r,this.finalE=s}},extendPrototype([DynamicPropertyContainer],r),{getTextSelectorProp:function(t,e,i){return new r(t,e,i)}}}();function TextAnimatorDataProperty(t,e,i){var r={propType:!1},s=PropertyFactory.getProp,a=e.a;this.a={r:a.r?s(t,a.r,0,degToRads,i):r,rx:a.rx?s(t,a.rx,0,degToRads,i):r,ry:a.ry?s(t,a.ry,0,degToRads,i):r,sk:a.sk?s(t,a.sk,0,degToRads,i):r,sa:a.sa?s(t,a.sa,0,degToRads,i):r,s:a.s?s(t,a.s,1,.01,i):r,a:a.a?s(t,a.a,1,0,i):r,o:a.o?s(t,a.o,0,.01,i):r,p:a.p?s(t,a.p,1,0,i):r,sw:a.sw?s(t,a.sw,0,0,i):r,sc:a.sc?s(t,a.sc,1,0,i):r,fc:a.fc?s(t,a.fc,1,0,i):r,fh:a.fh?s(t,a.fh,0,0,i):r,fs:a.fs?s(t,a.fs,0,.01,i):r,fb:a.fb?s(t,a.fb,0,.01,i):r,t:a.t?s(t,a.t,0,0,i):r},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,i),this.s.t=e.s.t}function TextAnimatorProperty(t,e,i){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=i,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(i)}function ITextElement(){}TextAnimatorProperty.prototype.searchProperties=function(){var t,e,i=this._textData.a.length,r=PropertyFactory.getProp;for(t=0;t<i;t+=1)e=this._textData.a[t],this._animatorsData[t]=new TextAnimatorDataProperty(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:r(this._elem,this._textData.p.a,0,0,this),f:r(this._elem,this._textData.p.f,0,0,this),l:r(this._elem,this._textData.p.l,0,0,this),r:r(this._elem,this._textData.p.r,0,0,this),p:r(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=r(this._elem,this._textData.m.a,1,0,this)},TextAnimatorProperty.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var i,r,s,a,n,o,h,l,p,f,m,c,d,u,y,g,v,b,x,P=this._moreOptions.alignment.v,E=this._animatorsData,S=this._textData,C=this.mHelper,_=this._renderType,A=this.renderedLetters.length,T=t.l;if(this._hasMaskedPath){if(x=this._pathData.m,!this._pathData.n||this._pathData._mdf){var M,k=x.v;for(this._pathData.r.v&&(k=k.reverse()),n={tLength:0,segments:[]},a=k._length-1,g=0,s=0;s<a;s+=1)M=bez.buildBezierData(k.v[s],k.v[s+1],[k.o[s][0]-k.v[s][0],k.o[s][1]-k.v[s][1]],[k.i[s+1][0]-k.v[s+1][0],k.i[s+1][1]-k.v[s+1][1]]),n.tLength+=M.segmentLength,n.segments.push(M),g+=M.segmentLength;s=a,x.v.c&&(M=bez.buildBezierData(k.v[s],k.v[0],[k.o[s][0]-k.v[s][0],k.o[s][1]-k.v[s][1]],[k.i[0][0]-k.v[0][0],k.i[0][1]-k.v[0][1]]),n.tLength+=M.segmentLength,n.segments.push(M),g+=M.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,m=0,f=1,l=0,p=!0,u=n.segments,o<0&&x.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),f=(d=u[m=u.length-1].points).length-1;o<0;)o+=d[f].partialLength,(f-=1)<0&&(f=(d=u[m-=1].points).length-1);c=(d=u[m].points)[f-1],y=(h=d[f]).partialLength}a=T.length,i=0,r=0;var D,F,w,I,V,B=1.2*t.finalSize*.714,R=!0;w=E.length;var L,G,z,O,N,H,q,j,W,$,Y,J,X=-1,Z=o,K=m,U=f,Q=-1,tt="",et=this.defaultPropsArray;if(2===t.j||1===t.j){var it=0,rt=0,st=2===t.j?-.5:-1,at=0,nt=!0;for(s=0;s<a;s+=1)if(T[s].n){for(it&&(it+=rt);at<s;)T[at].animatorJustifyOffset=it,at+=1;it=0,nt=!0}else{for(F=0;F<w;F+=1)(D=E[F].a).t.propType&&(nt&&2===t.j&&(rt+=D.t.v*st),(V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?it+=D.t.v*V[0]*st:it+=D.t.v*V*st);nt=!1}for(it&&(it+=rt);at<s;)T[at].animatorJustifyOffset=it,at+=1}for(s=0;s<a;s+=1){if(C.reset(),O=1,T[s].n)i=0,r+=t.yOffset,r+=R?1:0,o=Z,R=!1,this._hasMaskedPath&&(f=U,c=(d=u[m=K].points)[f-1],y=(h=d[f]).partialLength,l=0),tt="",Y="",W="",J="",et=this.defaultPropsArray;else{if(this._hasMaskedPath){if(Q!==T[s].line){switch(t.j){case 1:o+=g-t.lineWidths[T[s].line];break;case 2:o+=(g-t.lineWidths[T[s].line])/2}Q=T[s].line}X!==T[s].ind&&(T[X]&&(o+=T[X].extra),o+=T[s].an/2,X=T[s].ind),o+=P[0]*T[s].an*.005;var ot=0;for(F=0;F<w;F+=1)(D=E[F].a).p.propType&&((V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?ot+=D.p.v[0]*V[0]:ot+=D.p.v[0]*V),D.a.propType&&((V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?ot+=D.a.v[0]*V[0]:ot+=D.a.v[0]*V);for(p=!0,this._pathData.a.v&&(o=.5*T[0].an+(g-this._pathData.f.v-.5*T[0].an-.5*T[T.length-1].an)*X/(a-1),o+=this._pathData.f.v);p;)l+y>=o+ot||!d?(v=(o+ot-l)/h.partialLength,G=c.point[0]+(h.point[0]-c.point[0])*v,z=c.point[1]+(h.point[1]-c.point[1])*v,C.translate(-P[0]*T[s].an*.005,-P[1]*B*.01),p=!1):d&&(l+=h.partialLength,(f+=1)>=d.length&&(f=0,u[m+=1]?d=u[m].points:x.v.c?(f=0,d=u[m=0].points):(l-=h.partialLength,d=null)),d&&(c=h,y=(h=d[f]).partialLength));L=T[s].an/2-T[s].add,C.translate(-L,0,0)}else L=T[s].an/2-T[s].add,C.translate(-L,0,0),C.translate(-P[0]*T[s].an*.005,-P[1]*B*.01,0);for(F=0;F<w;F+=1)(D=E[F].a).t.propType&&(V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars),0===i&&0===t.j||(this._hasMaskedPath?V.length?o+=D.t.v*V[0]:o+=D.t.v*V:V.length?i+=D.t.v*V[0]:i+=D.t.v*V));for(t.strokeWidthAnim&&(H=t.sw||0),t.strokeColorAnim&&(N=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(q=[t.fc[0],t.fc[1],t.fc[2]]),F=0;F<w;F+=1)(D=E[F].a).a.propType&&((V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?C.translate(-D.a.v[0]*V[0],-D.a.v[1]*V[1],D.a.v[2]*V[2]):C.translate(-D.a.v[0]*V,-D.a.v[1]*V,D.a.v[2]*V));for(F=0;F<w;F+=1)(D=E[F].a).s.propType&&((V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?C.scale(1+(D.s.v[0]-1)*V[0],1+(D.s.v[1]-1)*V[1],1):C.scale(1+(D.s.v[0]-1)*V,1+(D.s.v[1]-1)*V,1));for(F=0;F<w;F+=1){if(D=E[F].a,V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars),D.sk.propType&&(V.length?C.skewFromAxis(-D.sk.v*V[0],D.sa.v*V[1]):C.skewFromAxis(-D.sk.v*V,D.sa.v*V)),D.r.propType&&(V.length?C.rotateZ(-D.r.v*V[2]):C.rotateZ(-D.r.v*V)),D.ry.propType&&(V.length?C.rotateY(D.ry.v*V[1]):C.rotateY(D.ry.v*V)),D.rx.propType&&(V.length?C.rotateX(D.rx.v*V[0]):C.rotateX(D.rx.v*V)),D.o.propType&&(V.length?O+=(D.o.v*V[0]-O)*V[0]:O+=(D.o.v*V-O)*V),t.strokeWidthAnim&&D.sw.propType&&(V.length?H+=D.sw.v*V[0]:H+=D.sw.v*V),t.strokeColorAnim&&D.sc.propType)for(j=0;j<3;j+=1)V.length?N[j]+=(D.sc.v[j]-N[j])*V[0]:N[j]+=(D.sc.v[j]-N[j])*V;if(t.fillColorAnim&&t.fc){if(D.fc.propType)for(j=0;j<3;j+=1)V.length?q[j]+=(D.fc.v[j]-q[j])*V[0]:q[j]+=(D.fc.v[j]-q[j])*V;D.fh.propType&&(q=V.length?addHueToRGB(q,D.fh.v*V[0]):addHueToRGB(q,D.fh.v*V)),D.fs.propType&&(q=V.length?addSaturationToRGB(q,D.fs.v*V[0]):addSaturationToRGB(q,D.fs.v*V)),D.fb.propType&&(q=V.length?addBrightnessToRGB(q,D.fb.v*V[0]):addBrightnessToRGB(q,D.fb.v*V))}}for(F=0;F<w;F+=1)(D=E[F].a).p.propType&&(V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars),this._hasMaskedPath?V.length?C.translate(0,D.p.v[1]*V[0],-D.p.v[2]*V[1]):C.translate(0,D.p.v[1]*V,-D.p.v[2]*V):V.length?C.translate(D.p.v[0]*V[0],D.p.v[1]*V[1],-D.p.v[2]*V[2]):C.translate(D.p.v[0]*V,D.p.v[1]*V,-D.p.v[2]*V));if(t.strokeWidthAnim&&(W=H<0?0:H),t.strokeColorAnim&&($="rgb("+Math.round(255*N[0])+","+Math.round(255*N[1])+","+Math.round(255*N[2])+")"),t.fillColorAnim&&t.fc&&(Y="rgb("+Math.round(255*q[0])+","+Math.round(255*q[1])+","+Math.round(255*q[2])+")"),this._hasMaskedPath){if(C.translate(0,-t.ls),C.translate(0,P[1]*B*.01+r,0),this._pathData.p.v){b=(h.point[1]-c.point[1])/(h.point[0]-c.point[0]);var ht=180*Math.atan(b)/Math.PI;h.point[0]<c.point[0]&&(ht+=180),C.rotate(-ht*Math.PI/180)}C.translate(G,z,0),o-=P[0]*T[s].an*.005,T[s+1]&&X!==T[s+1].ind&&(o+=T[s].an/2,o+=.001*t.tr*t.finalSize)}else{switch(C.translate(i,r,0),t.ps&&C.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:C.translate(T[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[T[s].line]),0,0);break;case 2:C.translate(T[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[T[s].line])/2,0,0)}C.translate(0,-t.ls),C.translate(L,0,0),C.translate(P[0]*T[s].an*.005,P[1]*B*.01,0),i+=T[s].l+.001*t.tr*t.finalSize}"html"===_?tt=C.toCSS():"svg"===_?tt=C.to2dCSS():et=[C.props[0],C.props[1],C.props[2],C.props[3],C.props[4],C.props[5],C.props[6],C.props[7],C.props[8],C.props[9],C.props[10],C.props[11],C.props[12],C.props[13],C.props[14],C.props[15]],J=O}A<=s?(I=new LetterProps(J,W,$,Y,tt,et),this.renderedLetters.push(I),A+=1,this.lettersChangedFlag=!0):(I=this.renderedLetters[s],this.lettersChangedFlag=I.update(J,W,$,Y,tt,et)||this.lettersChangedFlag)}}},TextAnimatorProperty.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},TextAnimatorProperty.prototype.mHelper=new Matrix,TextAnimatorProperty.prototype.defaultPropsArray=[],extendPrototype([DynamicPropertyContainer],TextAnimatorProperty),ITextElement.prototype.initElement=function(t,e,i){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,i),this.textProperty=new TextProperty(this,t.t,this.dynamicProperties),this.textAnimator=new TextAnimatorProperty(t.t,this.renderType,this),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},ITextElement.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},ITextElement.prototype.createPathShape=function(t,e){var i,r,s=e.length,a="";for(i=0;i<s;i+=1)"sh"===e[i].ty&&(r=e[i].ks.k,a+=buildShapeString(r,r.i.length,!0,t));return a},ITextElement.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},ITextElement.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},ITextElement.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},ITextElement.prototype.applyTextPropertiesToMatrix=function(t,e,i,r,s){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i])/2,0,0)}e.translate(r,s,0)},ITextElement.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},ITextElement.prototype.emptyProp=new LetterProps,ITextElement.prototype.destroy=function(){},ITextElement.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var emptyShapeData={shapes:[]};function SVGTextLottieElement(t,e,i){this.textSpans=[],this.renderType="svg",this.initElement(t,e,i)}function ISolidElement(t,e,i){this.initElement(t,e,i)}function NullElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initFrame(),this.initTransform(t,e,i),this.initHierarchy()}function SVGRendererBase(){}function ICompElement(){}function SVGCompElement(t,e,i){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function SVGRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=createNS("svg");var i="";if(e&&e.title){var r=createNS("title"),s=createElementID();r.setAttribute("id",s),r.textContent=e.title,this.svgElement.appendChild(r),i+=s}if(e&&e.description){var a=createNS("desc"),n=createElementID();a.setAttribute("id",n),a.textContent=e.description,this.svgElement.appendChild(a),i+=" "+n}i&&this.svgElement.setAttribute("aria-labelledby",i);var o=createNS("defs");this.svgElement.appendChild(o);var h=createNS("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}function ShapeTransformManager(){this.sequences={},this.sequenceList=[],this.transform_key_count=0}extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],SVGTextLottieElement),SVGTextLottieElement.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=createNS("text"))},SVGTextLottieElement.prototype.buildTextContents=function(t){for(var e=0,i=t.length,r=[],s="";e<i;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(r.push(s),s=""):s+=t[e],e+=1;return r.push(s),r},SVGTextLottieElement.prototype.buildShapeData=function(t,e){if(t.shapes&&t.shapes.length){var i=t.shapes[0];if(i.it){var r=i.it[i.it.length-1];r.s&&(r.s.k[0]=e,r.s.k[1]=e)}}return t},SVGTextLottieElement.prototype.buildNewText=function(){var t,e;this.addDynamicProperty(this);var i=this.textProperty.currentData;this.renderedLetters=createSizedArray(i?i.l.length:0),i.fc?this.layerElement.setAttribute("fill",this.buildColor(i.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),i.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(i.sc)),this.layerElement.setAttribute("stroke-width",i.sw)),this.layerElement.setAttribute("font-size",i.finalSize);var r=this.globalData.fontManager.getFontByName(i.f);if(r.fClass)this.layerElement.setAttribute("class",r.fClass);else{this.layerElement.setAttribute("font-family",r.fFamily);var s=i.fWeight,a=i.fStyle;this.layerElement.setAttribute("font-style",a),this.layerElement.setAttribute("font-weight",s)}this.layerElement.setAttribute("aria-label",i.t);var n,o=i.l||[],h=!!this.globalData.fontManager.chars;e=o.length;var l=this.mHelper,p=this.data.singleShape,f=0,m=0,c=!0,d=.001*i.tr*i.finalSize;if(!p||h||i.sz){var u,y=this.textSpans.length;for(t=0;t<e;t+=1){if(this.textSpans[t]||(this.textSpans[t]={span:null,childSpan:null,glyph:null}),!h||!p||0===t){if(n=y>t?this.textSpans[t].span:createNS(h?"g":"text"),y<=t){if(n.setAttribute("stroke-linecap","butt"),n.setAttribute("stroke-linejoin","round"),n.setAttribute("stroke-miterlimit","4"),this.textSpans[t].span=n,h){var g=createNS("g");n.appendChild(g),this.textSpans[t].childSpan=g}this.textSpans[t].span=n,this.layerElement.appendChild(n)}n.style.display="inherit"}if(l.reset(),p&&(o[t].n&&(f=-d,m+=i.yOffset,m+=c?1:0,c=!1),this.applyTextPropertiesToMatrix(i,l,o[t].line,f,m),f+=o[t].l||0,f+=d),h){var v;if(1===(u=this.globalData.fontManager.getCharData(i.finalText[t],r.fStyle,this.globalData.fontManager.getFontByName(i.f).fFamily)).t)v=new SVGCompElement(u.data,this.globalData,this);else{var b=emptyShapeData;u.data&&u.data.shapes&&(b=this.buildShapeData(u.data,i.finalSize)),v=new SVGShapeElement(b,this.globalData,this)}if(this.textSpans[t].glyph){var x=this.textSpans[t].glyph;this.textSpans[t].childSpan.removeChild(x.layerElement),x.destroy()}this.textSpans[t].glyph=v,v._debug=!0,v.prepareFrame(0),v.renderFrame(),this.textSpans[t].childSpan.appendChild(v.layerElement),1===u.t&&this.textSpans[t].childSpan.setAttribute("transform","scale("+i.finalSize/100+","+i.finalSize/100+")")}else p&&n.setAttribute("transform","translate("+l.props[12]+","+l.props[13]+")"),n.textContent=o[t].val,n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}p&&n&&n.setAttribute("d","")}else{var P=this.textContainer,E="start";switch(i.j){case 1:E="end";break;case 2:E="middle";break;default:E="start"}P.setAttribute("text-anchor",E),P.setAttribute("letter-spacing",d);var S=this.buildTextContents(i.finalText);for(e=S.length,m=i.ps?i.ps[1]+i.ascent:0,t=0;t<e;t+=1)(n=this.textSpans[t].span||createNS("tspan")).textContent=S[t],n.setAttribute("x",0),n.setAttribute("y",m),n.style.display="inherit",P.appendChild(n),this.textSpans[t]||(this.textSpans[t]={span:null,glyph:null}),this.textSpans[t].span=n,m+=i.finalLineHeight;this.layerElement.appendChild(P)}for(;t<this.textSpans.length;)this.textSpans[t].span.style.display="none",t+=1;this._sizeChanged=!0},SVGTextLottieElement.prototype.sourceRectAtTime=function(){if(this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged){this._sizeChanged=!1;var t=this.layerElement.getBBox();this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}}return this.bbox},SVGTextLottieElement.prototype.getValue=function(){var t,e,i=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<i;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf&&(this._mdf=!0))},SVGTextLottieElement.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){var t,e;this._sizeChanged=!0;var i,r,s,a=this.textAnimator.renderedLetters,n=this.textProperty.currentData.l;for(e=n.length,t=0;t<e;t+=1)n[t].n||(i=a[t],r=this.textSpans[t].span,(s=this.textSpans[t].glyph)&&s.renderFrame(),i._mdf.m&&r.setAttribute("transform",i.m),i._mdf.o&&r.setAttribute("opacity",i.o),i._mdf.sw&&r.setAttribute("stroke-width",i.sw),i._mdf.sc&&r.setAttribute("stroke",i.sc),i._mdf.fc&&r.setAttribute("fill",i.fc))}},extendPrototype([IImageElement],ISolidElement),ISolidElement.prototype.createContent=function(){var t=createNS("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},NullElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},NullElement.prototype.renderFrame=function(){},NullElement.prototype.getBaseElement=function(){return null},NullElement.prototype.destroy=function(){},NullElement.prototype.sourceRectAtTime=function(){},NullElement.prototype.hide=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement],NullElement),extendPrototype([BaseRenderer],SVGRendererBase),SVGRendererBase.prototype.createNull=function(t){return new NullElement(t,this.globalData,this)},SVGRendererBase.prototype.createShape=function(t){return new SVGShapeElement(t,this.globalData,this)},SVGRendererBase.prototype.createText=function(t){return new SVGTextLottieElement(t,this.globalData,this)},SVGRendererBase.prototype.createImage=function(t){return new IImageElement(t,this.globalData,this)},SVGRendererBase.prototype.createSolid=function(t){return new ISolidElement(t,this.globalData,this)},SVGRendererBase.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var i=createNS("clipPath"),r=createNS("rect");r.setAttribute("width",t.w),r.setAttribute("height",t.h),r.setAttribute("x",0),r.setAttribute("y",0);var s=createElementID();i.setAttribute("id",s),i.appendChild(r),this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),e.appendChild(i),this.layers=t.layers,this.elements=createSizedArray(t.layers.length)},SVGRendererBase.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},SVGRendererBase.prototype.updateContainerSize=function(){},SVGRendererBase.prototype.findIndexByInd=function(t){var e=0,i=this.layers.length;for(e=0;e<i;e+=1)if(this.layers[e].ind===t)return e;return-1},SVGRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){e[t]=!0;var i=this.createItem(this.layers[t]);if(e[t]=i,getExpressionsPlugin()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(i),i.initExpressions()),this.appendElementInPos(i,t),this.layers[t].tt){var r="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1;if(-1===r)return;if(this.elements[r]&&!0!==this.elements[r]){var s=e[r].getMatte(this.layers[t].tt);i.setMatte(s)}else this.buildItem(r),this.addPendingElement(i)}}},SVGRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,i=this.elements.length;e<i;){if(this.elements[e]===t){var r="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,s=this.elements[r].getMatte(this.layers[e].tt);t.setMatte(s);break}e+=1}}},SVGRendererBase.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){var e;null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var i=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=i-1;e>=0;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<i;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},SVGRendererBase.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){for(var r,s=0;s<e;)this.elements[s]&&!0!==this.elements[s]&&this.elements[s].getBaseElement()&&(r=this.elements[s].getBaseElement()),s+=1;r?this.layerElement.insertBefore(i,r):this.layerElement.appendChild(i)}},SVGRendererBase.prototype.hide=function(){this.layerElement.style.display="none"},SVGRendererBase.prototype.show=function(){this.layerElement.style.display="block"},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement,RenderableDOMElement],ICompElement),ICompElement.prototype.initElement=function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},ICompElement.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var i,r=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),i=r-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&(this.elements[i].prepareFrame(this.renderedFrame-this.layers[i].st),this.elements[i]._mdf&&(this._mdf=!0))}},ICompElement.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},ICompElement.prototype.setElements=function(t){this.elements=t},ICompElement.prototype.getElements=function(){return this.elements},ICompElement.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},ICompElement.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},extendPrototype([SVGRendererBase,ICompElement,SVGBaseElement],SVGCompElement),SVGCompElement.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},extendPrototype([SVGRendererBase],SVGRenderer),SVGRenderer.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},ShapeTransformManager.prototype={addTransformSequence:function(t){var e,i=t.length,r="_";for(e=0;e<i;e+=1)r+=t[e].transform.key+"_";var s=this.sequences[r];return s||(s={transforms:[].concat(t),finalTransform:new Matrix,_mdf:!1},this.sequences[r]=s,this.sequenceList.push(s)),s},processSequence:function(t,e){for(var i=0,r=t.transforms.length,s=e;i<r&&!e;){if(t.transforms[i].transform.mProps._mdf){s=!0;break}i+=1}if(s)for(t.finalTransform.reset(),i=r-1;i>=0;i-=1)t.finalTransform.multiply(t.transforms[i].transform.mProps.v);t._mdf=s},processSequences:function(t){var e,i=this.sequenceList.length;for(e=0;e<i;e+=1)this.processSequence(this.sequenceList[e],t)},getNewKey:function(){return this.transform_key_count+=1,"_"+this.transform_key_count}};var lumaLoader=function(){var t="__lottie_element_luma_buffer",e=null,i=null,r=null;function s(){var s,a,n;e||(s=createNS("svg"),a=createNS("filter"),n=createNS("feColorMatrix"),a.setAttribute("id",t),n.setAttribute("type","matrix"),n.setAttribute("color-interpolation-filters","sRGB"),n.setAttribute("values","0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0"),a.appendChild(n),s.appendChild(a),s.setAttribute("id",t+"_svg"),featureSupport.svgLumaHidden&&(s.style.display="none"),r=s,document.body.appendChild(r),e=createTag("canvas"),(i=e.getContext("2d")).filter="url(#"+t+")",i.fillStyle="rgba(0,0,0,0)",i.fillRect(0,0,1,1))}return{load:s,get:function(r){return e||s(),e.width=r.width,e.height=r.height,i.filter="url(#"+t+")",e}}};function createCanvas(t,e){if(featureSupport.offscreenCanvas)return new OffscreenCanvas(t,e);var i=createTag("canvas");return i.width=t,i.height=e,i}var assetLoader={loadLumaCanvas:lumaLoader.load,getLumaCanvas:lumaLoader.get,createCanvas:createCanvas},registeredEffects={};function CVEffects(t){var e,i,r=t.data.ef?t.data.ef.length:0;for(this.filters=[],e=0;e<r;e+=1){i=null;var s=t.data.ef[e].ty;if(registeredEffects[s])i=new(0,registeredEffects[s].effect)(t.effectsManager.effectElements[e],t);i&&this.filters.push(i)}this.filters.length&&t.addRenderableComponent(this)}function registerEffect(t,e){registeredEffects[t]={effect:e}}function CVMaskElement(t,e){var i;this.data=t,this.element=e,this.masksProperties=this.data.masksProperties||[],this.viewData=createSizedArray(this.masksProperties.length);var r=this.masksProperties.length,s=!1;for(i=0;i<r;i+=1)"n"!==this.masksProperties[i].mode&&(s=!0),this.viewData[i]=ShapePropertyFactory.getShapeProp(this.element,this.masksProperties[i],3);this.hasMasks=s,s&&this.element.addRenderableComponent(this)}function CVBaseElement(){}CVEffects.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},CVEffects.prototype.getEffects=function(t){var e,i=this.filters.length,r=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&r.push(this.filters[e]);return r},CVMaskElement.prototype.renderFrame=function(){if(this.hasMasks){var t,e,i,r,s=this.element.finalTransform.mat,a=this.element.canvasContext,n=this.masksProperties.length;for(a.beginPath(),t=0;t<n;t+=1)if("n"!==this.masksProperties[t].mode){var o;this.masksProperties[t].inv&&(a.moveTo(0,0),a.lineTo(this.element.globalData.compSize.w,0),a.lineTo(this.element.globalData.compSize.w,this.element.globalData.compSize.h),a.lineTo(0,this.element.globalData.compSize.h),a.lineTo(0,0)),r=this.viewData[t].v,e=s.applyToPointArray(r.v[0][0],r.v[0][1],0),a.moveTo(e[0],e[1]);var h=r._length;for(o=1;o<h;o+=1)i=s.applyToTriplePoints(r.o[o-1],r.i[o],r.v[o]),a.bezierCurveTo(i[0],i[1],i[2],i[3],i[4],i[5]);i=s.applyToTriplePoints(r.o[o-1],r.i[0],r.v[0]),a.bezierCurveTo(i[0],i[1],i[2],i[3],i[4],i[5])}this.element.globalData.renderer.save(!0),a.clip()}},CVMaskElement.prototype.getMaskProperty=MaskElement.prototype.getMaskProperty,CVMaskElement.prototype.destroy=function(){this.element=null};var operationsMap={1:"source-in",2:"source-out",3:"source-in",4:"source-out"};function CVShapeData(t,e,i,r){this.styledShapes=[],this.tr=[0,0,0,0,0,0];var s,a=4;"rc"===e.ty?a=5:"el"===e.ty?a=6:"sr"===e.ty&&(a=7),this.sh=ShapePropertyFactory.getShapeProp(t,e,a,t);var n,o=i.length;for(s=0;s<o;s+=1)i[s].closed||(n={transforms:r.addTransformSequence(i[s].transforms),trNodes:[]},this.styledShapes.push(n),i[s].elements.push(n))}function CVShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.itemsData=[],this.prevViewData=[],this.shapeModifiers=[],this.processedElements=[],this.transformsManager=new ShapeTransformManager,this.initElement(t,e,i)}function CVTextElement(t,e,i){this.textSpans=[],this.yOffset=0,this.fillColorAnim=!1,this.strokeColorAnim=!1,this.strokeWidthAnim=!1,this.stroke=!1,this.fill=!1,this.justifyOffset=0,this.currentRender=null,this.renderType="canvas",this.values={fill:"rgba(0,0,0,0)",stroke:"rgba(0,0,0,0)",sWidth:0,fValue:""},this.initElement(t,e,i)}function CVImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.img=e.imageLoader.getAsset(this.assetData),this.initElement(t,e,i)}function CVSolidElement(t,e,i){this.initElement(t,e,i)}function CanvasRendererBase(){}function CanvasContext(){this.opacity=-1,this.transform=createTypedArray("float32",16),this.fillStyle="",this.strokeStyle="",this.lineWidth="",this.lineCap="",this.lineJoin="",this.miterLimit="",this.id=Math.random()}function CVContextData(){var t;this.stack=[],this.cArrPos=0,this.cTr=new Matrix;for(t=0;t<15;t+=1){var e=new CanvasContext;this.stack[t]=e}this._length=15,this.nativeContext=null,this.transformMat=new Matrix,this.currentOpacity=1,this.currentFillStyle="",this.appliedFillStyle="",this.currentStrokeStyle="",this.appliedStrokeStyle="",this.currentLineWidth="",this.appliedLineWidth="",this.currentLineCap="",this.appliedLineCap="",this.currentLineJoin="",this.appliedLineJoin="",this.appliedMiterLimit="",this.currentMiterLimit=""}function CVCompElement(t,e,i){this.completeLayers=!1,this.layers=t.layers,this.pendingElements=[],this.elements=createSizedArray(this.layers.length),this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function CanvasRenderer(t,e){this.animationItem=t,this.renderConfig={clearCanvas:!e||void 0===e.clearCanvas||e.clearCanvas,context:e&&e.context||null,progressiveLoad:e&&e.progressiveLoad||!1,preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",className:e&&e.className||"",id:e&&e.id||"",runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.renderConfig.dpr=e&&e.dpr||1,this.animationItem.wrapper&&(this.renderConfig.dpr=e&&e.dpr||window.devicePixelRatio||1),this.renderedFrame=-1,this.globalData={frameNum:-1,_mdf:!1,renderConfig:this.renderConfig,currentGlobalAlpha:-1},this.contextData=new CVContextData,this.elements=[],this.pendingElements=[],this.transformMat=new Matrix,this.completeLayers=!1,this.rendererType="canvas",this.renderConfig.clearCanvas&&(this.ctxTransform=this.contextData.transform.bind(this.contextData),this.ctxOpacity=this.contextData.opacity.bind(this.contextData),this.ctxFillStyle=this.contextData.fillStyle.bind(this.contextData),this.ctxStrokeStyle=this.contextData.strokeStyle.bind(this.contextData),this.ctxLineWidth=this.contextData.lineWidth.bind(this.contextData),this.ctxLineCap=this.contextData.lineCap.bind(this.contextData),this.ctxLineJoin=this.contextData.lineJoin.bind(this.contextData),this.ctxMiterLimit=this.contextData.miterLimit.bind(this.contextData),this.ctxFill=this.contextData.fill.bind(this.contextData),this.ctxFillRect=this.contextData.fillRect.bind(this.contextData),this.ctxStroke=this.contextData.stroke.bind(this.contextData),this.save=this.contextData.save.bind(this.contextData))}function HBaseElement(){}function HSolidElement(t,e,i){this.initElement(t,e,i)}function HShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.shapesContainer=createNS("g"),this.initElement(t,e,i),this.prevViewData=[],this.currentBBox={x:999999,y:-999999,h:0,w:0}}function HTextElement(t,e,i){this.textSpans=[],this.textPaths=[],this.currentBBox={x:999999,y:-999999,h:0,w:0},this.renderType="svg",this.isMasked=!1,this.initElement(t,e,i)}function HCameraElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initHierarchy();var r=PropertyFactory.getProp;if(this.pe=r(this,t.pe,0,0,this),t.ks.p.s?(this.px=r(this,t.ks.p.x,1,0,this),this.py=r(this,t.ks.p.y,1,0,this),this.pz=r(this,t.ks.p.z,1,0,this)):this.p=r(this,t.ks.p,1,0,this),t.ks.a&&(this.a=r(this,t.ks.a,1,0,this)),t.ks.or.k.length&&t.ks.or.k[0].to){var s,a=t.ks.or.k.length;for(s=0;s<a;s+=1)t.ks.or.k[s].to=null,t.ks.or.k[s].ti=null}this.or=r(this,t.ks.or,1,degToRads,this),this.or.sh=!0,this.rx=r(this,t.ks.rx,0,degToRads,this),this.ry=r(this,t.ks.ry,0,degToRads,this),this.rz=r(this,t.ks.rz,0,degToRads,this),this.mat=new Matrix,this._prevMat=new Matrix,this._isFirstFrame=!0,this.finalTransform={mProp:this}}function HImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.initElement(t,e,i)}function HybridRendererBase(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"}},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}function HCompElement(t,e,i){this.layers=t.layers,this.supports3d=!t.hasMask,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function HybridRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"},runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}CVBaseElement.prototype={createElements:function(){},initRendererElement:function(){},createContainerElements:function(){if(this.data.tt>=1){this.buffers=[];var t=this.globalData.canvasContext,e=assetLoader.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(e);var i=assetLoader.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(i),this.data.tt>=3&&!document._isProxy&&assetLoader.loadLumaCanvas()}this.canvasContext=this.globalData.canvasContext,this.transformCanvas=this.globalData.transformCanvas,this.renderableEffectsManager=new CVEffects(this),this.searchEffectTransforms()},createContent:function(){},setBlendMode:function(){var t=this.globalData;if(t.blendMode!==this.data.bm){t.blendMode=this.data.bm;var e=getBlendMode(this.data.bm);t.canvasContext.globalCompositeOperation=e}},createRenderableComponents:function(){this.maskManager=new CVMaskElement(this.data,this),this.transformEffects=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT)},hideElement:function(){this.hidden||this.isInRange&&!this.isTransparent||(this.hidden=!0)},showElement:function(){this.isInRange&&!this.isTransparent&&(this.hidden=!1,this._isFirstFrame=!0,this.maskManager._isFirstFrame=!0)},clearCanvas:function(t){t.clearRect(this.transformCanvas.tx,this.transformCanvas.ty,this.transformCanvas.w*this.transformCanvas.sx,this.transformCanvas.h*this.transformCanvas.sy)},prepareLayer:function(){if(this.data.tt>=1){var t=this.buffers[0].getContext("2d");this.clearCanvas(t),t.drawImage(this.canvasContext.canvas,0,0),this.currentTransform=this.canvasContext.getTransform(),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform)}},exitLayer:function(){if(this.data.tt>=1){var t=this.buffers[1],e=t.getContext("2d");if(this.clearCanvas(e),e.drawImage(this.canvasContext.canvas,0,0),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform),this.comp.getElementById("tp"in this.data?this.data.tp:this.data.ind-1).renderFrame(!0),this.canvasContext.setTransform(1,0,0,1,0,0),this.data.tt>=3&&!document._isProxy){var i=assetLoader.getLumaCanvas(this.canvasContext.canvas);i.getContext("2d").drawImage(this.canvasContext.canvas,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.drawImage(i,0,0)}this.canvasContext.globalCompositeOperation=operationsMap[this.data.tt],this.canvasContext.drawImage(t,0,0),this.canvasContext.globalCompositeOperation="destination-over",this.canvasContext.drawImage(this.buffers[0],0,0),this.canvasContext.setTransform(this.currentTransform),this.canvasContext.globalCompositeOperation="source-over"}},renderFrame:function(t){if(!this.hidden&&!this.data.hd&&(1!==this.data.td||t)){this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.setBlendMode();var e=0===this.data.ty;this.prepareLayer(),this.globalData.renderer.save(e),this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props),this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity),this.renderInnerContent(),this.globalData.renderer.restore(e),this.exitLayer(),this.maskManager.hasMasks&&this.globalData.renderer.restore(!0),this._isFirstFrame&&(this._isFirstFrame=!1)}},destroy:function(){this.canvasContext=null,this.data=null,this.globalData=null,this.maskManager.destroy()},mHelper:new Matrix},CVBaseElement.prototype.hide=CVBaseElement.prototype.hideElement,CVBaseElement.prototype.show=CVBaseElement.prototype.showElement,CVShapeData.prototype.setAsAnimated=SVGShapeData.prototype.setAsAnimated,extendPrototype([BaseElement,TransformElement,CVBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableElement],CVShapeElement),CVShapeElement.prototype.initElement=RenderableDOMElement.prototype.initElement,CVShapeElement.prototype.transformHelper={opacity:1,_opMdf:!1},CVShapeElement.prototype.dashResetter=[],CVShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[])},CVShapeElement.prototype.createStyleElement=function(t,e){var i={data:t,type:t.ty,preTransforms:this.transformsManager.addTransformSequence(e),transforms:[],elements:[],closed:!0===t.hd},r={};if("fl"===t.ty||"st"===t.ty?(r.c=PropertyFactory.getProp(this,t.c,1,255,this),r.c.k||(i.co="rgb("+bmFloor(r.c.v[0])+","+bmFloor(r.c.v[1])+","+bmFloor(r.c.v[2])+")")):"gf"!==t.ty&&"gs"!==t.ty||(r.s=PropertyFactory.getProp(this,t.s,1,null,this),r.e=PropertyFactory.getProp(this,t.e,1,null,this),r.h=PropertyFactory.getProp(this,t.h||{k:0},0,.01,this),r.a=PropertyFactory.getProp(this,t.a||{k:0},0,degToRads,this),r.g=new GradientProperty(this,t.g,this)),r.o=PropertyFactory.getProp(this,t.o,0,.01,this),"st"===t.ty||"gs"===t.ty){if(i.lc=lineCapEnum[t.lc||2],i.lj=lineJoinEnum[t.lj||2],1==t.lj&&(i.ml=t.ml),r.w=PropertyFactory.getProp(this,t.w,0,null,this),r.w.k||(i.wi=r.w.v),t.d){var s=new DashProperty(this,t.d,"canvas",this);r.d=s,r.d.k||(i.da=r.d.dashArray,i.do=r.d.dashoffset[0])}}else i.r=2===t.r?"evenodd":"nonzero";return this.stylesList.push(i),r.style=i,r},CVShapeElement.prototype.createGroupElement=function(){return{it:[],prevViewData:[]}},CVShapeElement.prototype.createTransformElement=function(t){return{transform:{opacity:1,_opMdf:!1,key:this.transformsManager.getNewKey(),op:PropertyFactory.getProp(this,t.o,0,.01,this),mProps:TransformPropertyFactory.getTransformProperty(this,t,this)}}},CVShapeElement.prototype.createShapeElement=function(t){var e=new CVShapeData(this,t,this.stylesList,this.transformsManager);return this.shapes.push(e),this.addShapeToModifiers(e),e},CVShapeElement.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[]),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame)},CVShapeElement.prototype.addTransformToStyleList=function(t){var e,i=this.stylesList.length;for(e=0;e<i;e+=1)this.stylesList[e].closed||this.stylesList[e].transforms.push(t)},CVShapeElement.prototype.removeTransformFromStyleList=function(){var t,e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].closed||this.stylesList[t].transforms.pop()},CVShapeElement.prototype.closeStyles=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].closed=!0},CVShapeElement.prototype.searchShapes=function(t,e,i,r,s){var a,n,o,h,l,p,f=t.length-1,m=[],c=[],d=[].concat(s);for(a=f;a>=0;a-=1){if((h=this.searchProcessedElement(t[a]))?e[a]=i[h-1]:t[a]._shouldRender=r,"fl"===t[a].ty||"st"===t[a].ty||"gf"===t[a].ty||"gs"===t[a].ty)h?e[a].style.closed=!1:e[a]=this.createStyleElement(t[a],d),m.push(e[a].style);else if("gr"===t[a].ty){if(h)for(o=e[a].it.length,n=0;n<o;n+=1)e[a].prevViewData[n]=e[a].it[n];else e[a]=this.createGroupElement(t[a]);this.searchShapes(t[a].it,e[a].it,e[a].prevViewData,r,d)}else"tr"===t[a].ty?(h||(p=this.createTransformElement(t[a]),e[a]=p),d.push(e[a]),this.addTransformToStyleList(e[a])):"sh"===t[a].ty||"rc"===t[a].ty||"el"===t[a].ty||"sr"===t[a].ty?h||(e[a]=this.createShapeElement(t[a])):"tm"===t[a].ty||"rd"===t[a].ty||"pb"===t[a].ty||"zz"===t[a].ty||"op"===t[a].ty?(h?(l=e[a]).closed=!1:((l=ShapeModifiers.getModifier(t[a].ty)).init(this,t[a]),e[a]=l,this.shapeModifiers.push(l)),c.push(l)):"rp"===t[a].ty&&(h?(l=e[a]).closed=!0:(l=ShapeModifiers.getModifier(t[a].ty),e[a]=l,l.init(this,t,a,e),this.shapeModifiers.push(l),r=!1),c.push(l));this.addProcessedElement(t[a],a+1)}for(this.removeTransformFromStyleList(),this.closeStyles(m),f=c.length,a=0;a<f;a+=1)c[a].closed=!0},CVShapeElement.prototype.renderInnerContent=function(){this.transformHelper.opacity=1,this.transformHelper._opMdf=!1,this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame),this.renderShape(this.transformHelper,this.shapesData,this.itemsData,!0)},CVShapeElement.prototype.renderShapeTransform=function(t,e){(t._opMdf||e.op._mdf||this._isFirstFrame)&&(e.opacity=t.opacity,e.opacity*=e.op.v,e._opMdf=!0)},CVShapeElement.prototype.drawLayer=function(){var t,e,i,r,s,a,n,o,h,l=this.stylesList.length,p=this.globalData.renderer,f=this.globalData.canvasContext;for(t=0;t<l;t+=1)if(("st"!==(o=(h=this.stylesList[t]).type)&&"gs"!==o||0!==h.wi)&&h.data._shouldRender&&0!==h.coOp&&0!==this.globalData.currentGlobalAlpha){for(p.save(),a=h.elements,"st"===o||"gs"===o?(p.ctxStrokeStyle("st"===o?h.co:h.grd),p.ctxLineWidth(h.wi),p.ctxLineCap(h.lc),p.ctxLineJoin(h.lj),p.ctxMiterLimit(h.ml||0)):p.ctxFillStyle("fl"===o?h.co:h.grd),p.ctxOpacity(h.coOp),"st"!==o&&"gs"!==o&&f.beginPath(),p.ctxTransform(h.preTransforms.finalTransform.props),i=a.length,e=0;e<i;e+=1){for("st"!==o&&"gs"!==o||(f.beginPath(),h.da&&(f.setLineDash(h.da),f.lineDashOffset=h.do)),s=(n=a[e].trNodes).length,r=0;r<s;r+=1)"m"===n[r].t?f.moveTo(n[r].p[0],n[r].p[1]):"c"===n[r].t?f.bezierCurveTo(n[r].pts[0],n[r].pts[1],n[r].pts[2],n[r].pts[3],n[r].pts[4],n[r].pts[5]):f.closePath();"st"!==o&&"gs"!==o||(p.ctxStroke(),h.da&&f.setLineDash(this.dashResetter))}"st"!==o&&"gs"!==o&&this.globalData.renderer.ctxFill(h.r),p.restore()}},CVShapeElement.prototype.renderShape=function(t,e,i,r){var s,a;for(a=t,s=e.length-1;s>=0;s-=1)"tr"===e[s].ty?(a=i[s].transform,this.renderShapeTransform(t,a)):"sh"===e[s].ty||"el"===e[s].ty||"rc"===e[s].ty||"sr"===e[s].ty?this.renderPath(e[s],i[s]):"fl"===e[s].ty?this.renderFill(e[s],i[s],a):"st"===e[s].ty?this.renderStroke(e[s],i[s],a):"gf"===e[s].ty||"gs"===e[s].ty?this.renderGradientFill(e[s],i[s],a):"gr"===e[s].ty?this.renderShape(a,e[s].it,i[s].it):e[s].ty;r&&this.drawLayer()},CVShapeElement.prototype.renderStyledShape=function(t,e){if(this._isFirstFrame||e._mdf||t.transforms._mdf){var i,r,s,a=t.trNodes,n=e.paths,o=n._length;a.length=0;var h=t.transforms.finalTransform;for(s=0;s<o;s+=1){var l=n.shapes[s];if(l&&l.v){for(r=l._length,i=1;i<r;i+=1)1===i&&a.push({t:"m",p:h.applyToPointArray(l.v[0][0],l.v[0][1],0)}),a.push({t:"c",pts:h.applyToTriplePoints(l.o[i-1],l.i[i],l.v[i])});1===r&&a.push({t:"m",p:h.applyToPointArray(l.v[0][0],l.v[0][1],0)}),l.c&&r&&(a.push({t:"c",pts:h.applyToTriplePoints(l.o[i-1],l.i[0],l.v[0])}),a.push({t:"z"}))}}t.trNodes=a}},CVShapeElement.prototype.renderPath=function(t,e){if(!0!==t.hd&&t._shouldRender){var i,r=e.styledShapes.length;for(i=0;i<r;i+=1)this.renderStyledShape(e.styledShapes[i],e.sh)}},CVShapeElement.prototype.renderFill=function(t,e,i){var r=e.style;(e.c._mdf||this._isFirstFrame)&&(r.co="rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i._opMdf||this._isFirstFrame)&&(r.coOp=e.o.v*i.opacity)},CVShapeElement.prototype.renderGradientFill=function(t,e,i){var r,s=e.style;if(!s.grd||e.g._mdf||e.s._mdf||e.e._mdf||1!==t.t&&(e.h._mdf||e.a._mdf)){var a,n=this.globalData.canvasContext,o=e.s.v,h=e.e.v;if(1===t.t)r=n.createLinearGradient(o[0],o[1],h[0],h[1]);else{var l=Math.sqrt(Math.pow(o[0]-h[0],2)+Math.pow(o[1]-h[1],2)),p=Math.atan2(h[1]-o[1],h[0]-o[0]),f=e.h.v;f>=1?f=.99:f<=-1&&(f=-.99);var m=l*f,c=Math.cos(p+e.a.v)*m+o[0],d=Math.sin(p+e.a.v)*m+o[1];r=n.createRadialGradient(c,d,0,o[0],o[1],l)}var u=t.g.p,y=e.g.c,g=1;for(a=0;a<u;a+=1)e.g._hasOpacity&&e.g._collapsable&&(g=e.g.o[2*a+1]),r.addColorStop(y[4*a]/100,"rgba("+y[4*a+1]+","+y[4*a+2]+","+y[4*a+3]+","+g+")");s.grd=r}s.coOp=e.o.v*i.opacity},CVShapeElement.prototype.renderStroke=function(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||this._isFirstFrame)&&(r.da=s.dashArray,r.do=s.dashoffset[0]),(e.c._mdf||this._isFirstFrame)&&(r.co="rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i._opMdf||this._isFirstFrame)&&(r.coOp=e.o.v*i.opacity),(e.w._mdf||this._isFirstFrame)&&(r.wi=e.w.v)},CVShapeElement.prototype.destroy=function(){this.shapesData=null,this.globalData=null,this.canvasContext=null,this.stylesList.length=0,this.itemsData.length=0},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement,ITextElement],CVTextElement),CVTextElement.prototype.tHelper=createTag("canvas").getContext("2d"),CVTextElement.prototype.buildNewText=function(){var t=this.textProperty.currentData;this.renderedLetters=createSizedArray(t.l?t.l.length:0);var e=!1;t.fc?(e=!0,this.values.fill=this.buildColor(t.fc)):this.values.fill="rgba(0,0,0,0)",this.fill=e;var i=!1;t.sc&&(i=!0,this.values.stroke=this.buildColor(t.sc),this.values.sWidth=t.sw);var r,s,a,n,o,h,l,p,f,m,c,d,u=this.globalData.fontManager.getFontByName(t.f),y=t.l,g=this.mHelper;this.stroke=i,this.values.fValue=t.finalSize+"px "+this.globalData.fontManager.getFontByName(t.f).fFamily,s=t.finalText.length;var v=this.data.singleShape,b=.001*t.tr*t.finalSize,x=0,P=0,E=!0,S=0;for(r=0;r<s;r+=1){n=(a=this.globalData.fontManager.getCharData(t.finalText[r],u.fStyle,this.globalData.fontManager.getFontByName(t.f).fFamily))&&a.data||{},g.reset(),v&&y[r].n&&(x=-b,P+=t.yOffset,P+=E?1:0,E=!1),f=(l=n.shapes?n.shapes[0].it:[]).length,g.scale(t.finalSize/100,t.finalSize/100),v&&this.applyTextPropertiesToMatrix(t,g,y[r].line,x,P),c=createSizedArray(f-1);var C=0;for(p=0;p<f;p+=1)if("sh"===l[p].ty){for(h=l[p].ks.k.i.length,m=l[p].ks.k,d=[],o=1;o<h;o+=1)1===o&&d.push(g.applyToX(m.v[0][0],m.v[0][1],0),g.applyToY(m.v[0][0],m.v[0][1],0)),d.push(g.applyToX(m.o[o-1][0],m.o[o-1][1],0),g.applyToY(m.o[o-1][0],m.o[o-1][1],0),g.applyToX(m.i[o][0],m.i[o][1],0),g.applyToY(m.i[o][0],m.i[o][1],0),g.applyToX(m.v[o][0],m.v[o][1],0),g.applyToY(m.v[o][0],m.v[o][1],0));d.push(g.applyToX(m.o[o-1][0],m.o[o-1][1],0),g.applyToY(m.o[o-1][0],m.o[o-1][1],0),g.applyToX(m.i[0][0],m.i[0][1],0),g.applyToY(m.i[0][0],m.i[0][1],0),g.applyToX(m.v[0][0],m.v[0][1],0),g.applyToY(m.v[0][0],m.v[0][1],0)),c[C]=d,C+=1}v&&(x+=y[r].l,x+=b),this.textSpans[S]?this.textSpans[S].elem=c:this.textSpans[S]={elem:c},S+=1}},CVTextElement.prototype.renderInnerContent=function(){var t,e,i,r,s,a;this.validateText(),this.canvasContext.font=this.values.fValue,this.globalData.renderer.ctxLineCap("butt"),this.globalData.renderer.ctxLineJoin("miter"),this.globalData.renderer.ctxMiterLimit(4),this.data.singleShape||this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag);var n,o=this.textAnimator.renderedLetters,h=this.textProperty.currentData.l;e=h.length;var l,p,f=null,m=null,c=null,d=this.globalData.renderer;for(t=0;t<e;t+=1)if(!h[t].n){if((n=o[t])&&(d.save(),d.ctxTransform(n.p),d.ctxOpacity(n.o)),this.fill){for(n&&n.fc?f!==n.fc&&(d.ctxFillStyle(n.fc),f=n.fc):f!==this.values.fill&&(f=this.values.fill,d.ctxFillStyle(this.values.fill)),r=(l=this.textSpans[t].elem).length,this.globalData.canvasContext.beginPath(),i=0;i<r;i+=1)for(a=(p=l[i]).length,this.globalData.canvasContext.moveTo(p[0],p[1]),s=2;s<a;s+=6)this.globalData.canvasContext.bezierCurveTo(p[s],p[s+1],p[s+2],p[s+3],p[s+4],p[s+5]);this.globalData.canvasContext.closePath(),d.ctxFill()}if(this.stroke){for(n&&n.sw?c!==n.sw&&(c=n.sw,d.ctxLineWidth(n.sw)):c!==this.values.sWidth&&(c=this.values.sWidth,d.ctxLineWidth(this.values.sWidth)),n&&n.sc?m!==n.sc&&(m=n.sc,d.ctxStrokeStyle(n.sc)):m!==this.values.stroke&&(m=this.values.stroke,d.ctxStrokeStyle(this.values.stroke)),r=(l=this.textSpans[t].elem).length,this.globalData.canvasContext.beginPath(),i=0;i<r;i+=1)for(a=(p=l[i]).length,this.globalData.canvasContext.moveTo(p[0],p[1]),s=2;s<a;s+=6)this.globalData.canvasContext.bezierCurveTo(p[s],p[s+1],p[s+2],p[s+3],p[s+4],p[s+5]);this.globalData.canvasContext.closePath(),d.ctxStroke()}n&&this.globalData.renderer.restore()}},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVImageElement),CVImageElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVImageElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVImageElement.prototype.createContent=function(){if(this.img.width&&(this.assetData.w!==this.img.width||this.assetData.h!==this.img.height)){var t=createTag("canvas");t.width=this.assetData.w,t.height=this.assetData.h;var e,i,r=t.getContext("2d"),s=this.img.width,a=this.img.height,n=s/a,o=this.assetData.w/this.assetData.h,h=this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio;n>o&&"xMidYMid slice"===h||n<o&&"xMidYMid slice"!==h?e=(i=a)*o:i=(e=s)/o,r.drawImage(this.img,(s-e)/2,(a-i)/2,e,i,0,0,this.assetData.w,this.assetData.h),this.img=t}},CVImageElement.prototype.renderInnerContent=function(){this.canvasContext.drawImage(this.img,0,0)},CVImageElement.prototype.destroy=function(){this.img=null},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVSolidElement),CVSolidElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVSolidElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVSolidElement.prototype.renderInnerContent=function(){this.globalData.renderer.ctxFillStyle(this.data.sc),this.globalData.renderer.ctxFillRect(0,0,this.data.sw,this.data.sh)},extendPrototype([BaseRenderer],CanvasRendererBase),CanvasRendererBase.prototype.createShape=function(t){return new CVShapeElement(t,this.globalData,this)},CanvasRendererBase.prototype.createText=function(t){return new CVTextElement(t,this.globalData,this)},CanvasRendererBase.prototype.createImage=function(t){return new CVImageElement(t,this.globalData,this)},CanvasRendererBase.prototype.createSolid=function(t){return new CVSolidElement(t,this.globalData,this)},CanvasRendererBase.prototype.createNull=SVGRenderer.prototype.createNull,CanvasRendererBase.prototype.ctxTransform=function(t){1===t[0]&&0===t[1]&&0===t[4]&&1===t[5]&&0===t[12]&&0===t[13]||this.canvasContext.transform(t[0],t[1],t[4],t[5],t[12],t[13])},CanvasRendererBase.prototype.ctxOpacity=function(t){this.canvasContext.globalAlpha*=t<0?0:t},CanvasRendererBase.prototype.ctxFillStyle=function(t){this.canvasContext.fillStyle=t},CanvasRendererBase.prototype.ctxStrokeStyle=function(t){this.canvasContext.strokeStyle=t},CanvasRendererBase.prototype.ctxLineWidth=function(t){this.canvasContext.lineWidth=t},CanvasRendererBase.prototype.ctxLineCap=function(t){this.canvasContext.lineCap=t},CanvasRendererBase.prototype.ctxLineJoin=function(t){this.canvasContext.lineJoin=t},CanvasRendererBase.prototype.ctxMiterLimit=function(t){this.canvasContext.miterLimit=t},CanvasRendererBase.prototype.ctxFill=function(t){this.canvasContext.fill(t)},CanvasRendererBase.prototype.ctxFillRect=function(t,e,i,r){this.canvasContext.fillRect(t,e,i,r)},CanvasRendererBase.prototype.ctxStroke=function(){this.canvasContext.stroke()},CanvasRendererBase.prototype.reset=function(){this.renderConfig.clearCanvas?this.contextData.reset():this.canvasContext.restore()},CanvasRendererBase.prototype.save=function(){this.canvasContext.save()},CanvasRendererBase.prototype.restore=function(t){this.renderConfig.clearCanvas?(t&&(this.globalData.blendMode="source-over"),this.contextData.restore(t)):this.canvasContext.restore()},CanvasRendererBase.prototype.configAnimation=function(t){if(this.animationItem.wrapper){this.animationItem.container=createTag("canvas");var e=this.animationItem.container.style;e.width="100%",e.height="100%";var i="0px 0px 0px";e.transformOrigin=i,e.mozTransformOrigin=i,e.webkitTransformOrigin=i,e["-webkit-transform"]=i,e.contentVisibility=this.renderConfig.contentVisibility,this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.animationItem.container.setAttribute("id",this.renderConfig.id)}else this.canvasContext=this.renderConfig.context;this.contextData.setContext(this.canvasContext),this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.setupGlobalData(t,document.body),this.globalData.canvasContext=this.canvasContext,this.globalData.renderer=this,this.globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=createSizedArray(t.layers.length),this.updateContainerSize()},CanvasRendererBase.prototype.updateContainerSize=function(t,e){var i,r,s,a;if(this.reset(),t?(i=t,r=e,this.canvasContext.canvas.width=i,this.canvasContext.canvas.height=r):(this.animationItem.wrapper&&this.animationItem.container?(i=this.animationItem.wrapper.offsetWidth,r=this.animationItem.wrapper.offsetHeight):(i=this.canvasContext.canvas.width,r=this.canvasContext.canvas.height),this.canvasContext.canvas.width=i*this.renderConfig.dpr,this.canvasContext.canvas.height=r*this.renderConfig.dpr),-1!==this.renderConfig.preserveAspectRatio.indexOf("meet")||-1!==this.renderConfig.preserveAspectRatio.indexOf("slice")){var n=this.renderConfig.preserveAspectRatio.split(" "),o=n[1]||"meet",h=n[0]||"xMidYMid",l=h.substr(0,4),p=h.substr(4);s=i/r,(a=this.transformCanvas.w/this.transformCanvas.h)>s&&"meet"===o||a<s&&"slice"===o?(this.transformCanvas.sx=i/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=i/(this.transformCanvas.w/this.renderConfig.dpr)):(this.transformCanvas.sx=r/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.sy=r/(this.transformCanvas.h/this.renderConfig.dpr)),this.transformCanvas.tx="xMid"===l&&(a<s&&"meet"===o||a>s&&"slice"===o)?(i-this.transformCanvas.w*(r/this.transformCanvas.h))/2*this.renderConfig.dpr:"xMax"===l&&(a<s&&"meet"===o||a>s&&"slice"===o)?(i-this.transformCanvas.w*(r/this.transformCanvas.h))*this.renderConfig.dpr:0,this.transformCanvas.ty="YMid"===p&&(a>s&&"meet"===o||a<s&&"slice"===o)?(r-this.transformCanvas.h*(i/this.transformCanvas.w))/2*this.renderConfig.dpr:"YMax"===p&&(a>s&&"meet"===o||a<s&&"slice"===o)?(r-this.transformCanvas.h*(i/this.transformCanvas.w))*this.renderConfig.dpr:0}else"none"===this.renderConfig.preserveAspectRatio?(this.transformCanvas.sx=i/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=r/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.tx=0,this.transformCanvas.ty=0):(this.transformCanvas.sx=this.renderConfig.dpr,this.transformCanvas.sy=this.renderConfig.dpr,this.transformCanvas.tx=0,this.transformCanvas.ty=0);this.transformCanvas.props=[this.transformCanvas.sx,0,0,0,0,this.transformCanvas.sy,0,0,0,0,1,0,this.transformCanvas.tx,this.transformCanvas.ty,0,1],this.ctxTransform(this.transformCanvas.props),this.canvasContext.beginPath(),this.canvasContext.rect(0,0,this.transformCanvas.w,this.transformCanvas.h),this.canvasContext.closePath(),this.canvasContext.clip(),this.renderFrame(this.renderedFrame,!0)},CanvasRendererBase.prototype.destroy=function(){var t;for(this.renderConfig.clearCanvas&&this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),t=(this.layers?this.layers.length:0)-1;t>=0;t-=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.globalData.canvasContext=null,this.animationItem.container=null,this.destroyed=!0},CanvasRendererBase.prototype.renderFrame=function(t,e){if((this.renderedFrame!==t||!0!==this.renderConfig.clearCanvas||e)&&!this.destroyed&&-1!==t){var i;this.renderedFrame=t,this.globalData.frameNum=t-this.animationItem._isFirstFrame,this.globalData.frameId+=1,this.globalData._mdf=!this.renderConfig.clearCanvas||e,this.globalData.projectInterface.currentFrame=t;var r=this.layers.length;for(this.completeLayers||this.checkLayers(t),i=r-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&this.elements[i].prepareFrame(t-this.layers[i].st);if(this.globalData._mdf){for(!0===this.renderConfig.clearCanvas?this.canvasContext.clearRect(0,0,this.transformCanvas.w,this.transformCanvas.h):this.save(),i=r-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&this.elements[i].renderFrame();!0!==this.renderConfig.clearCanvas&&this.restore()}}},CanvasRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){var i=this.createItem(this.layers[t],this,this.globalData);e[t]=i,i.initExpressions()}},CanvasRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},CanvasRendererBase.prototype.hide=function(){this.animationItem.container.style.display="none"},CanvasRendererBase.prototype.show=function(){this.animationItem.container.style.display="block"},CVContextData.prototype.duplicate=function(){var t=2*this._length,e=0;for(e=this._length;e<t;e+=1)this.stack[e]=new CanvasContext;this._length=t},CVContextData.prototype.reset=function(){this.cArrPos=0,this.cTr.reset(),this.stack[this.cArrPos].opacity=1},CVContextData.prototype.restore=function(t){this.cArrPos-=1;var e,i=this.stack[this.cArrPos],r=i.transform,s=this.cTr.props;for(e=0;e<16;e+=1)s[e]=r[e];if(t){this.nativeContext.restore();var a=this.stack[this.cArrPos+1];this.appliedFillStyle=a.fillStyle,this.appliedStrokeStyle=a.strokeStyle,this.appliedLineWidth=a.lineWidth,this.appliedLineCap=a.lineCap,this.appliedLineJoin=a.lineJoin,this.appliedMiterLimit=a.miterLimit}this.nativeContext.setTransform(r[0],r[1],r[4],r[5],r[12],r[13]),(t||-1!==i.opacity&&this.currentOpacity!==i.opacity)&&(this.nativeContext.globalAlpha=i.opacity,this.currentOpacity=i.opacity),this.currentFillStyle=i.fillStyle,this.currentStrokeStyle=i.strokeStyle,this.currentLineWidth=i.lineWidth,this.currentLineCap=i.lineCap,this.currentLineJoin=i.lineJoin,this.currentMiterLimit=i.miterLimit},CVContextData.prototype.save=function(t){t&&this.nativeContext.save();var e=this.cTr.props;this._length<=this.cArrPos&&this.duplicate();var i,r=this.stack[this.cArrPos];for(i=0;i<16;i+=1)r.transform[i]=e[i];this.cArrPos+=1;var s=this.stack[this.cArrPos];s.opacity=r.opacity,s.fillStyle=r.fillStyle,s.strokeStyle=r.strokeStyle,s.lineWidth=r.lineWidth,s.lineCap=r.lineCap,s.lineJoin=r.lineJoin,s.miterLimit=r.miterLimit},CVContextData.prototype.setOpacity=function(t){this.stack[this.cArrPos].opacity=t},CVContextData.prototype.setContext=function(t){this.nativeContext=t},CVContextData.prototype.fillStyle=function(t){this.stack[this.cArrPos].fillStyle!==t&&(this.currentFillStyle=t,this.stack[this.cArrPos].fillStyle=t)},CVContextData.prototype.strokeStyle=function(t){this.stack[this.cArrPos].strokeStyle!==t&&(this.currentStrokeStyle=t,this.stack[this.cArrPos].strokeStyle=t)},CVContextData.prototype.lineWidth=function(t){this.stack[this.cArrPos].lineWidth!==t&&(this.currentLineWidth=t,this.stack[this.cArrPos].lineWidth=t)},CVContextData.prototype.lineCap=function(t){this.stack[this.cArrPos].lineCap!==t&&(this.currentLineCap=t,this.stack[this.cArrPos].lineCap=t)},CVContextData.prototype.lineJoin=function(t){this.stack[this.cArrPos].lineJoin!==t&&(this.currentLineJoin=t,this.stack[this.cArrPos].lineJoin=t)},CVContextData.prototype.miterLimit=function(t){this.stack[this.cArrPos].miterLimit!==t&&(this.currentMiterLimit=t,this.stack[this.cArrPos].miterLimit=t)},CVContextData.prototype.transform=function(t){this.transformMat.cloneFromProps(t);var e=this.cTr;this.transformMat.multiply(e),e.cloneFromProps(this.transformMat.props);var i=e.props;this.nativeContext.setTransform(i[0],i[1],i[4],i[5],i[12],i[13])},CVContextData.prototype.opacity=function(t){var e=this.stack[this.cArrPos].opacity;e*=t<0?0:t,this.stack[this.cArrPos].opacity!==e&&(this.currentOpacity!==t&&(this.nativeContext.globalAlpha=t,this.currentOpacity=t),this.stack[this.cArrPos].opacity=e)},CVContextData.prototype.fill=function(t){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fill(t)},CVContextData.prototype.fillRect=function(t,e,i,r){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fillRect(t,e,i,r)},CVContextData.prototype.stroke=function(){this.appliedStrokeStyle!==this.currentStrokeStyle&&(this.appliedStrokeStyle=this.currentStrokeStyle,this.nativeContext.strokeStyle=this.appliedStrokeStyle),this.appliedLineWidth!==this.currentLineWidth&&(this.appliedLineWidth=this.currentLineWidth,this.nativeContext.lineWidth=this.appliedLineWidth),this.appliedLineCap!==this.currentLineCap&&(this.appliedLineCap=this.currentLineCap,this.nativeContext.lineCap=this.appliedLineCap),this.appliedLineJoin!==this.currentLineJoin&&(this.appliedLineJoin=this.currentLineJoin,this.nativeContext.lineJoin=this.appliedLineJoin),this.appliedMiterLimit!==this.currentMiterLimit&&(this.appliedMiterLimit=this.currentMiterLimit,this.nativeContext.miterLimit=this.appliedMiterLimit),this.nativeContext.stroke()},extendPrototype([CanvasRendererBase,ICompElement,CVBaseElement],CVCompElement),CVCompElement.prototype.renderInnerContent=function(){var t,e=this.canvasContext;for(e.beginPath(),e.moveTo(0,0),e.lineTo(this.data.w,0),e.lineTo(this.data.w,this.data.h),e.lineTo(0,this.data.h),e.lineTo(0,0),e.clip(),t=this.layers.length-1;t>=0;t-=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},CVCompElement.prototype.destroy=function(){var t;for(t=this.layers.length-1;t>=0;t-=1)this.elements[t]&&this.elements[t].destroy();this.layers=null,this.elements=null},CVCompElement.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},extendPrototype([CanvasRendererBase],CanvasRenderer),CanvasRenderer.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},HBaseElement.prototype={checkBlendMode:function(){},initRendererElement:function(){this.baseElement=createTag(this.data.tg||"div"),this.data.hasMask?(this.svgElement=createNS("svg"),this.layerElement=createNS("g"),this.maskedElement=this.layerElement,this.svgElement.appendChild(this.layerElement),this.baseElement.appendChild(this.svgElement)):this.layerElement=this.baseElement,styleDiv(this.baseElement)},createContainerElements:function(){this.renderableEffectsManager=new CVEffects(this),this.transformedElement=this.baseElement,this.maskedElement=this.layerElement,this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0!==this.data.bm&&this.setBlendMode()},renderElement:function(){var t=this.transformedElement?this.transformedElement.style:{};if(this.finalTransform._matMdf){var e=this.finalTransform.mat.toCSS();t.transform=e,t.webkitTransform=e}this.finalTransform._opMdf&&(t.opacity=this.finalTransform.mProp.o.v)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},destroy:function(){this.layerElement=null,this.transformedElement=null,this.matteElement&&(this.matteElement=null),this.maskManager&&(this.maskManager.destroy(),this.maskManager=null)},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData)},addEffects:function(){},setMatte:function(){}},HBaseElement.prototype.getBaseElement=SVGBaseElement.prototype.getBaseElement,HBaseElement.prototype.destroyBaseElement=HBaseElement.prototype.destroy,HBaseElement.prototype.buildElementParenting=BaseRenderer.prototype.buildElementParenting,extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],HSolidElement),HSolidElement.prototype.createContent=function(){var t;this.data.hasMask?((t=createNS("rect")).setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.svgElement.setAttribute("width",this.data.sw),this.svgElement.setAttribute("height",this.data.sh)):((t=createTag("div")).style.width=this.data.sw+"px",t.style.height=this.data.sh+"px",t.style.backgroundColor=this.data.sc),this.layerElement.appendChild(t)},extendPrototype([BaseElement,TransformElement,HSolidElement,SVGShapeElement,HBaseElement,HierarchyElement,FrameElement,RenderableElement],HShapeElement),HShapeElement.prototype._renderShapeFrame=HShapeElement.prototype.renderInnerContent,HShapeElement.prototype.createContent=function(){var t;if(this.baseElement.style.fontSize=0,this.data.hasMask)this.layerElement.appendChild(this.shapesContainer),t=this.svgElement;else{t=createNS("svg");var e=this.comp.data?this.comp.data:this.globalData.compSize;t.setAttribute("width",e.w),t.setAttribute("height",e.h),t.appendChild(this.shapesContainer),this.layerElement.appendChild(t)}this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.shapesContainer,0,[],!0),this.filterUniqueShapes(),this.shapeCont=t},HShapeElement.prototype.getTransformedPoint=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)e=t[i].mProps.v.applyToPointArray(e[0],e[1],0);return e},HShapeElement.prototype.calculateShapeBoundingBox=function(t,e){var i,r,s,a,n,o=t.sh.v,h=t.transformers,l=o._length;if(!(l<=1)){for(i=0;i<l-1;i+=1)r=this.getTransformedPoint(h,o.v[i]),s=this.getTransformedPoint(h,o.o[i]),a=this.getTransformedPoint(h,o.i[i+1]),n=this.getTransformedPoint(h,o.v[i+1]),this.checkBounds(r,s,a,n,e);o.c&&(r=this.getTransformedPoint(h,o.v[i]),s=this.getTransformedPoint(h,o.o[i]),a=this.getTransformedPoint(h,o.i[0]),n=this.getTransformedPoint(h,o.v[0]),this.checkBounds(r,s,a,n,e))}},HShapeElement.prototype.checkBounds=function(t,e,i,r,s){this.getBoundsOfCurve(t,e,i,r);var a=this.shapeBoundingBox;s.x=bmMin(a.left,s.x),s.xMax=bmMax(a.right,s.xMax),s.y=bmMin(a.top,s.y),s.yMax=bmMax(a.bottom,s.yMax)},HShapeElement.prototype.shapeBoundingBox={left:0,right:0,top:0,bottom:0},HShapeElement.prototype.tempBoundingBox={x:0,xMax:0,y:0,yMax:0,width:0,height:0},HShapeElement.prototype.getBoundsOfCurve=function(t,e,i,r){for(var s,a,n,o,h,l,p,f=[[t[0],r[0]],[t[1],r[1]]],m=0;m<2;++m)a=6*t[m]-12*e[m]+6*i[m],s=-3*t[m]+9*e[m]-9*i[m]+3*r[m],n=3*e[m]-3*t[m],a|=0,n|=0,0===(s|=0)&&0===a||(0===s?(o=-n/a)>0&&o<1&&f[m].push(this.calculateF(o,t,e,i,r,m)):(h=a*a-4*n*s)>=0&&((l=(-a+bmSqrt(h))/(2*s))>0&&l<1&&f[m].push(this.calculateF(l,t,e,i,r,m)),(p=(-a-bmSqrt(h))/(2*s))>0&&p<1&&f[m].push(this.calculateF(p,t,e,i,r,m))));this.shapeBoundingBox.left=bmMin.apply(null,f[0]),this.shapeBoundingBox.top=bmMin.apply(null,f[1]),this.shapeBoundingBox.right=bmMax.apply(null,f[0]),this.shapeBoundingBox.bottom=bmMax.apply(null,f[1])},HShapeElement.prototype.calculateF=function(t,e,i,r,s,a){return bmPow(1-t,3)*e[a]+3*bmPow(1-t,2)*t*i[a]+3*(1-t)*bmPow(t,2)*r[a]+bmPow(t,3)*s[a]},HShapeElement.prototype.calculateBoundingBox=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)t[i]&&t[i].sh?this.calculateShapeBoundingBox(t[i],e):t[i]&&t[i].it?this.calculateBoundingBox(t[i].it,e):t[i]&&t[i].style&&t[i].w&&this.expandStrokeBoundingBox(t[i].w,e)},HShapeElement.prototype.expandStrokeBoundingBox=function(t,e){var i=0;if(t.keyframes){for(var r=0;r<t.keyframes.length;r+=1){var s=t.keyframes[r].s;s>i&&(i=s)}i*=t.mult}else i=t.v*t.mult;e.x-=i,e.xMax+=i,e.y-=i,e.yMax+=i},HShapeElement.prototype.currentBoxContains=function(t){return this.currentBBox.x<=t.x&&this.currentBBox.y<=t.y&&this.currentBBox.width+this.currentBBox.x>=t.x+t.width&&this.currentBBox.height+this.currentBBox.y>=t.y+t.height},HShapeElement.prototype.renderInnerContent=function(){if(this._renderShapeFrame(),!this.hidden&&(this._isFirstFrame||this._mdf)){var t=this.tempBoundingBox,e=999999;if(t.x=e,t.xMax=-e,t.y=e,t.yMax=-e,this.calculateBoundingBox(this.itemsData,t),t.width=t.xMax<t.x?0:t.xMax-t.x,t.height=t.yMax<t.y?0:t.yMax-t.y,this.currentBoxContains(t))return;var i=!1;if(this.currentBBox.w!==t.width&&(this.currentBBox.w=t.width,this.shapeCont.setAttribute("width",t.width),i=!0),this.currentBBox.h!==t.height&&(this.currentBBox.h=t.height,this.shapeCont.setAttribute("height",t.height),i=!0),i||this.currentBBox.x!==t.x||this.currentBBox.y!==t.y){this.currentBBox.w=t.width,this.currentBBox.h=t.height,this.currentBBox.x=t.x,this.currentBBox.y=t.y,this.shapeCont.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h);var r=this.shapeCont.style,s="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)";r.transform=s,r.webkitTransform=s}}},extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],HTextElement),HTextElement.prototype.createContent=function(){if(this.isMasked=this.checkMasks(),this.isMasked){this.renderType="svg",this.compW=this.comp.data.w,this.compH=this.comp.data.h,this.svgElement.setAttribute("width",this.compW),this.svgElement.setAttribute("height",this.compH);var t=createNS("g");this.maskedElement.appendChild(t),this.innerElem=t}else this.renderType="html",this.innerElem=this.layerElement;this.checkParenting()},HTextElement.prototype.buildNewText=function(){var t=this.textProperty.currentData;this.renderedLetters=createSizedArray(t.l?t.l.length:0);var e=this.innerElem.style,i=t.fc?this.buildColor(t.fc):"rgba(0,0,0,0)";e.fill=i,e.color=i,t.sc&&(e.stroke=this.buildColor(t.sc),e.strokeWidth=t.sw+"px");var r,s,a=this.globalData.fontManager.getFontByName(t.f);if(!this.globalData.fontManager.chars)if(e.fontSize=t.finalSize+"px",e.lineHeight=t.finalSize+"px",a.fClass)this.innerElem.className=a.fClass;else{e.fontFamily=a.fFamily;var n=t.fWeight,o=t.fStyle;e.fontStyle=o,e.fontWeight=n}var h,l,p,f=t.l;s=f.length;var m,c=this.mHelper,d="",u=0;for(r=0;r<s;r+=1){if(this.globalData.fontManager.chars?(this.textPaths[u]?h=this.textPaths[u]:((h=createNS("path")).setAttribute("stroke-linecap",lineCapEnum[1]),h.setAttribute("stroke-linejoin",lineJoinEnum[2]),h.setAttribute("stroke-miterlimit","4")),this.isMasked||(this.textSpans[u]?p=(l=this.textSpans[u]).children[0]:((l=createTag("div")).style.lineHeight=0,(p=createNS("svg")).appendChild(h),styleDiv(l)))):this.isMasked?h=this.textPaths[u]?this.textPaths[u]:createNS("text"):this.textSpans[u]?(l=this.textSpans[u],h=this.textPaths[u]):(styleDiv(l=createTag("span")),styleDiv(h=createTag("span")),l.appendChild(h)),this.globalData.fontManager.chars){var y,g=this.globalData.fontManager.getCharData(t.finalText[r],a.fStyle,this.globalData.fontManager.getFontByName(t.f).fFamily);if(y=g?g.data:null,c.reset(),y&&y.shapes&&y.shapes.length&&(m=y.shapes[0].it,c.scale(t.finalSize/100,t.finalSize/100),d=this.createPathShape(c,m),h.setAttribute("d",d)),this.isMasked)this.innerElem.appendChild(h);else{if(this.innerElem.appendChild(l),y&&y.shapes){document.body.appendChild(p);var v=p.getBBox();p.setAttribute("width",v.width+2),p.setAttribute("height",v.height+2),p.setAttribute("viewBox",v.x-1+" "+(v.y-1)+" "+(v.width+2)+" "+(v.height+2));var b=p.style,x="translate("+(v.x-1)+"px,"+(v.y-1)+"px)";b.transform=x,b.webkitTransform=x,f[r].yOffset=v.y-1}else p.setAttribute("width",1),p.setAttribute("height",1);l.appendChild(p)}}else if(h.textContent=f[r].val,h.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),this.isMasked)this.innerElem.appendChild(h);else{this.innerElem.appendChild(l);var P=h.style,E="translate3d(0,"+-t.finalSize/1.2+"px,0)";P.transform=E,P.webkitTransform=E}this.isMasked?this.textSpans[u]=h:this.textSpans[u]=l,this.textSpans[u].style.display="block",this.textPaths[u]=h,u+=1}for(;u<this.textSpans.length;)this.textSpans[u].style.display="none",u+=1},HTextElement.prototype.renderInnerContent=function(){var t;if(this.validateText(),this.data.singleShape){if(!this._isFirstFrame&&!this.lettersChangedFlag)return;if(this.isMasked&&this.finalTransform._matMdf){this.svgElement.setAttribute("viewBox",-this.finalTransform.mProp.p.v[0]+" "+-this.finalTransform.mProp.p.v[1]+" "+this.compW+" "+this.compH),t=this.svgElement.style;var e="translate("+-this.finalTransform.mProp.p.v[0]+"px,"+-this.finalTransform.mProp.p.v[1]+"px)";t.transform=e,t.webkitTransform=e}}if(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag){var i,r,s,a,n,o=0,h=this.textAnimator.renderedLetters,l=this.textProperty.currentData.l;for(r=l.length,i=0;i<r;i+=1)l[i].n?o+=1:(a=this.textSpans[i],n=this.textPaths[i],s=h[o],o+=1,s._mdf.m&&(this.isMasked?a.setAttribute("transform",s.m):(a.style.webkitTransform=s.m,a.style.transform=s.m)),a.style.opacity=s.o,s.sw&&s._mdf.sw&&n.setAttribute("stroke-width",s.sw),s.sc&&s._mdf.sc&&n.setAttribute("stroke",s.sc),s.fc&&s._mdf.fc&&(n.setAttribute("fill",s.fc),n.style.color=s.fc));if(this.innerElem.getBBox&&!this.hidden&&(this._isFirstFrame||this._mdf)){var p=this.innerElem.getBBox();this.currentBBox.w!==p.width&&(this.currentBBox.w=p.width,this.svgElement.setAttribute("width",p.width)),this.currentBBox.h!==p.height&&(this.currentBBox.h=p.height,this.svgElement.setAttribute("height",p.height));if(this.currentBBox.w!==p.width+2||this.currentBBox.h!==p.height+2||this.currentBBox.x!==p.x-1||this.currentBBox.y!==p.y-1){this.currentBBox.w=p.width+2,this.currentBBox.h=p.height+2,this.currentBBox.x=p.x-1,this.currentBBox.y=p.y-1,this.svgElement.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h),t=this.svgElement.style;var f="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)";t.transform=f,t.webkitTransform=f}}}},extendPrototype([BaseElement,FrameElement,HierarchyElement],HCameraElement),HCameraElement.prototype.setup=function(){var t,e,i,r,s=this.comp.threeDElements.length;for(t=0;t<s;t+=1)if("3d"===(e=this.comp.threeDElements[t]).type){i=e.perspectiveElem.style,r=e.container.style;var a=this.pe.v+"px",n="0px 0px 0px",o="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";i.perspective=a,i.webkitPerspective=a,r.transformOrigin=n,r.mozTransformOrigin=n,r.webkitTransformOrigin=n,i.transform=o,i.webkitTransform=o}},HCameraElement.prototype.createElements=function(){},HCameraElement.prototype.hide=function(){},HCameraElement.prototype.renderFrame=function(){var t,e,i=this._isFirstFrame;if(this.hierarchy)for(e=this.hierarchy.length,t=0;t<e;t+=1)i=this.hierarchy[t].finalTransform.mProp._mdf||i;if(i||this.pe._mdf||this.p&&this.p._mdf||this.px&&(this.px._mdf||this.py._mdf||this.pz._mdf)||this.rx._mdf||this.ry._mdf||this.rz._mdf||this.or._mdf||this.a&&this.a._mdf){if(this.mat.reset(),this.hierarchy)for(t=e=this.hierarchy.length-1;t>=0;t-=1){var r=this.hierarchy[t].finalTransform.mProp;this.mat.translate(-r.p.v[0],-r.p.v[1],r.p.v[2]),this.mat.rotateX(-r.or.v[0]).rotateY(-r.or.v[1]).rotateZ(r.or.v[2]),this.mat.rotateX(-r.rx.v).rotateY(-r.ry.v).rotateZ(r.rz.v),this.mat.scale(1/r.s.v[0],1/r.s.v[1],1/r.s.v[2]),this.mat.translate(r.a.v[0],r.a.v[1],r.a.v[2])}if(this.p?this.mat.translate(-this.p.v[0],-this.p.v[1],this.p.v[2]):this.mat.translate(-this.px.v,-this.py.v,this.pz.v),this.a){var s;s=this.p?[this.p.v[0]-this.a.v[0],this.p.v[1]-this.a.v[1],this.p.v[2]-this.a.v[2]]:[this.px.v-this.a.v[0],this.py.v-this.a.v[1],this.pz.v-this.a.v[2]];var a=Math.sqrt(Math.pow(s[0],2)+Math.pow(s[1],2)+Math.pow(s[2],2)),n=[s[0]/a,s[1]/a,s[2]/a],o=Math.sqrt(n[2]*n[2]+n[0]*n[0]),h=Math.atan2(n[1],o),l=Math.atan2(n[0],-n[2]);this.mat.rotateY(l).rotateX(-h)}this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v),this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]),this.mat.translate(this.globalData.compSize.w/2,this.globalData.compSize.h/2,0),this.mat.translate(0,0,this.pe.v);var p=!this._prevMat.equals(this.mat);if((p||this.pe._mdf)&&this.comp.threeDElements){var f,m,c;for(e=this.comp.threeDElements.length,t=0;t<e;t+=1)if("3d"===(f=this.comp.threeDElements[t]).type){if(p){var d=this.mat.toCSS();(c=f.container.style).transform=d,c.webkitTransform=d}this.pe._mdf&&((m=f.perspectiveElem.style).perspective=this.pe.v+"px",m.webkitPerspective=this.pe.v+"px")}this.mat.clone(this._prevMat)}}this._isFirstFrame=!1},HCameraElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},HCameraElement.prototype.destroy=function(){},HCameraElement.prototype.getBaseElement=function(){return null},extendPrototype([BaseElement,TransformElement,HBaseElement,HSolidElement,HierarchyElement,FrameElement,RenderableElement],HImageElement),HImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData),e=new Image;this.data.hasMask?(this.imageElem=createNS("image"),this.imageElem.setAttribute("width",this.assetData.w+"px"),this.imageElem.setAttribute("height",this.assetData.h+"px"),this.imageElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.imageElem),this.baseElement.setAttribute("width",this.assetData.w),this.baseElement.setAttribute("height",this.assetData.h)):this.layerElement.appendChild(e),e.crossOrigin="anonymous",e.src=t,this.data.ln&&this.baseElement.setAttribute("id",this.data.ln)},extendPrototype([BaseRenderer],HybridRendererBase),HybridRendererBase.prototype.buildItem=SVGRenderer.prototype.buildItem,HybridRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},HybridRendererBase.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){var r=this.layers[e];if(r.ddd&&this.supports3d)this.addTo3dContainer(i,e);else if(this.threeDElements)this.addTo3dContainer(i,e);else{for(var s,a,n=0;n<e;)this.elements[n]&&!0!==this.elements[n]&&this.elements[n].getBaseElement&&(a=this.elements[n],s=(this.layers[n].ddd?this.getThreeDContainerByPos(n):a.getBaseElement())||s),n+=1;s?r.ddd&&this.supports3d||this.layerElement.insertBefore(i,s):r.ddd&&this.supports3d||this.layerElement.appendChild(i)}}},HybridRendererBase.prototype.createShape=function(t){return this.supports3d?new HShapeElement(t,this.globalData,this):new SVGShapeElement(t,this.globalData,this)},HybridRendererBase.prototype.createText=function(t){return this.supports3d?new HTextElement(t,this.globalData,this):new SVGTextLottieElement(t,this.globalData,this)},HybridRendererBase.prototype.createCamera=function(t){return this.camera=new HCameraElement(t,this.globalData,this),this.camera},HybridRendererBase.prototype.createImage=function(t){return this.supports3d?new HImageElement(t,this.globalData,this):new IImageElement(t,this.globalData,this)},HybridRendererBase.prototype.createSolid=function(t){return this.supports3d?new HSolidElement(t,this.globalData,this):new ISolidElement(t,this.globalData,this)},HybridRendererBase.prototype.createNull=SVGRenderer.prototype.createNull,HybridRendererBase.prototype.getThreeDContainerByPos=function(t){for(var e=0,i=this.threeDElements.length;e<i;){if(this.threeDElements[e].startPos<=t&&this.threeDElements[e].endPos>=t)return this.threeDElements[e].perspectiveElem;e+=1}return null},HybridRendererBase.prototype.createThreeDContainer=function(t,e){var i,r,s=createTag("div");styleDiv(s);var a=createTag("div");if(styleDiv(a),"3d"===e){(i=s.style).width=this.globalData.compSize.w+"px",i.height=this.globalData.compSize.h+"px";var n="50% 50%";i.webkitTransformOrigin=n,i.mozTransformOrigin=n,i.transformOrigin=n;var o="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";(r=a.style).transform=o,r.webkitTransform=o}s.appendChild(a);var h={container:a,perspectiveElem:s,startPos:t,endPos:t,type:e};return this.threeDElements.push(h),h},HybridRendererBase.prototype.build3dContainers=function(){var t,e,i=this.layers.length,r="";for(t=0;t<i;t+=1)this.layers[t].ddd&&3!==this.layers[t].ty?("3d"!==r&&(r="3d",e=this.createThreeDContainer(t,"3d")),e.endPos=Math.max(e.endPos,t)):("2d"!==r&&(r="2d",e=this.createThreeDContainer(t,"2d")),e.endPos=Math.max(e.endPos,t));for(t=(i=this.threeDElements.length)-1;t>=0;t-=1)this.resizerElem.appendChild(this.threeDElements[t].perspectiveElem)},HybridRendererBase.prototype.addTo3dContainer=function(t,e){for(var i=0,r=this.threeDElements.length;i<r;){if(e<=this.threeDElements[i].endPos){for(var s,a=this.threeDElements[i].startPos;a<e;)this.elements[a]&&this.elements[a].getBaseElement&&(s=this.elements[a].getBaseElement()),a+=1;s?this.threeDElements[i].container.insertBefore(t,s):this.threeDElements[i].container.appendChild(t);break}i+=1}},HybridRendererBase.prototype.configAnimation=function(t){var e=createTag("div"),i=this.animationItem.wrapper,r=e.style;r.width=t.w+"px",r.height=t.h+"px",this.resizerElem=e,styleDiv(e),r.transformStyle="flat",r.mozTransformStyle="flat",r.webkitTransformStyle="flat",this.renderConfig.className&&e.setAttribute("class",this.renderConfig.className),i.appendChild(e),r.overflow="hidden";var s=createNS("svg");s.setAttribute("width","1"),s.setAttribute("height","1"),styleDiv(s),this.resizerElem.appendChild(s);var a=createNS("defs");s.appendChild(a),this.data=t,this.setupGlobalData(t,s),this.globalData.defs=a,this.layers=t.layers,this.layerElement=this.resizerElem,this.build3dContainers(),this.updateContainerSize()},HybridRendererBase.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.animationItem.container=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},HybridRendererBase.prototype.updateContainerSize=function(){var t,e,i,r,s=this.animationItem.wrapper.offsetWidth,a=this.animationItem.wrapper.offsetHeight,n=s/a;this.globalData.compSize.w/this.globalData.compSize.h>n?(t=s/this.globalData.compSize.w,e=s/this.globalData.compSize.w,i=0,r=(a-this.globalData.compSize.h*(s/this.globalData.compSize.w))/2):(t=a/this.globalData.compSize.h,e=a/this.globalData.compSize.h,i=(s-this.globalData.compSize.w*(a/this.globalData.compSize.h))/2,r=0);var o=this.resizerElem.style;o.webkitTransform="matrix3d("+t+",0,0,0,0,"+e+",0,0,0,0,1,0,"+i+","+r+",0,1)",o.transform=o.webkitTransform},HybridRendererBase.prototype.renderFrame=SVGRenderer.prototype.renderFrame,HybridRendererBase.prototype.hide=function(){this.resizerElem.style.display="none"},HybridRendererBase.prototype.show=function(){this.resizerElem.style.display="block"},HybridRendererBase.prototype.initItems=function(){if(this.buildAllItems(),this.camera)this.camera.setup();else{var t,e=this.globalData.compSize.w,i=this.globalData.compSize.h,r=this.threeDElements.length;for(t=0;t<r;t+=1){var s=this.threeDElements[t].perspectiveElem.style;s.webkitPerspective=Math.sqrt(Math.pow(e,2)+Math.pow(i,2))+"px",s.perspective=s.webkitPerspective}}},HybridRendererBase.prototype.searchExtraCompositions=function(t){var e,i=t.length,r=createTag("div");for(e=0;e<i;e+=1)if(t[e].xt){var s=this.createComp(t[e],r,this.globalData.comp,null);s.initExpressions(),this.globalData.projectInterface.registerComposition(s)}},extendPrototype([HybridRendererBase,ICompElement,HBaseElement],HCompElement),HCompElement.prototype._createBaseContainerElements=HCompElement.prototype.createContainerElements,HCompElement.prototype.createContainerElements=function(){this._createBaseContainerElements(),this.data.hasMask?(this.svgElement.setAttribute("width",this.data.w),this.svgElement.setAttribute("height",this.data.h),this.transformedElement=this.baseElement):this.transformedElement=this.layerElement},HCompElement.prototype.addTo3dContainer=function(t,e){for(var i,r=0;r<e;)this.elements[r]&&this.elements[r].getBaseElement&&(i=this.elements[r].getBaseElement()),r+=1;i?this.layerElement.insertBefore(t,i):this.layerElement.appendChild(t)},HCompElement.prototype.createComp=function(t){return this.supports3d?new HCompElement(t,this.globalData,this):new SVGCompElement(t,this.globalData,this)},extendPrototype([HybridRendererBase],HybridRenderer),HybridRenderer.prototype.createComp=function(t){return this.supports3d?new HCompElement(t,this.globalData,this):new SVGCompElement(t,this.globalData,this)};var CompExpressionInterface=function(t){function e(e){for(var i=0,r=t.layers.length;i<r;){if(t.layers[i].nm===e||t.layers[i].ind===e)return t.elements[i].layerInterface;i+=1}return null}return Object.defineProperty(e,"_name",{value:t.data.nm}),e.layer=e,e.pixelAspect=1,e.height=t.data.h||t.globalData.compSize.h,e.width=t.data.w||t.globalData.compSize.w,e.pixelAspect=1,e.frameDuration=1/t.globalData.frameRate,e.displayStartTime=0,e.numLayers=t.layers.length,e};function _typeof$2(t){return _typeof$2="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$2(t)}function seedRandom(t,e){var i,r=this,s=256,a="random",n=e.pow(s,6),o=e.pow(2,52),h=2*o,l=255;function p(t){var e,i=t.length,r=this,a=0,n=r.i=r.j=0,o=r.S=[];for(i||(t=[i++]);a<s;)o[a]=a++;for(a=0;a<s;a++)o[a]=o[n=l&n+t[a%i]+(e=o[a])],o[n]=e;r.g=function(t){for(var e,i=0,a=r.i,n=r.j,o=r.S;t--;)e=o[a=l&a+1],i=i*s+o[l&(o[a]=o[n=l&n+e])+(o[n]=e)];return r.i=a,r.j=n,i}}function f(t,e){return e.i=t.i,e.j=t.j,e.S=t.S.slice(),e}function m(t,e){var i,r=[],s=_typeof$2(t);if(e&&"object"==s)for(i in t)try{r.push(m(t[i],e-1))}catch(t){}return r.length?r:"string"==s?t:t+"\0"}function c(t,e){for(var i,r=t+"",s=0;s<r.length;)e[l&s]=l&(i^=19*e[l&s])+r.charCodeAt(s++);return d(e)}function d(t){return String.fromCharCode.apply(0,t)}e["seed"+a]=function(l,u,y){var g=[],v=c(m((u=!0===u?{entropy:!0}:u||{}).entropy?[l,d(t)]:null===l?function(){try{i;var e=new Uint8Array(s);return(r.crypto||r.msCrypto).getRandomValues(e),d(e)}catch(e){var a=r.navigator,n=a&&a.plugins;return[+new Date,r,n,r.screen,d(t)]}}():l,3),g),b=new p(g),x=function(){for(var t=b.g(6),e=n,i=0;t<o;)t=(t+i)*s,e*=s,i=b.g(1);for(;t>=h;)t/=2,e/=2,i>>>=1;return(t+i)/e};return x.int32=function(){return 0|b.g(4)},x.quick=function(){return b.g(4)/4294967296},x.double=x,c(d(b.S),t),(u.pass||y||function(t,i,r,s){return s&&(s.S&&f(s,b),t.state=function(){return f(b,{})}),r?(e[a]=t,i):t})(x,v,"global"in u?u.global:this==e,u.state)},c(e.random(),t)}function initialize$2(t){seedRandom([],t)}var propTypes={SHAPE:"shape"};function _typeof$1(t){return _typeof$1="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$1(t)}var ExpressionManager=function(){var ob={},Math=BMMath,window=null,document=null,XMLHttpRequest=null,fetch=null,frames=null,_lottieGlobal={};function resetFrame(){_lottieGlobal={}}function $bm_isInstanceOfArray(t){return t.constructor===Array||t.constructor===Float32Array}function isNumerable(t,e){return"number"===t||e instanceof Number||"boolean"===t||"string"===t}function $bm_neg(t){var e=_typeof$1(t);if("number"===e||t instanceof Number||"boolean"===e)return-t;if($bm_isInstanceOfArray(t)){var i,r=t.length,s=[];for(i=0;i<r;i+=1)s[i]=-t[i];return s}return t.propType?t.v:-t}initialize$2(BMMath);var easeInBez=BezierFactory.getBezierEasing(.333,0,.833,.833,"easeIn").get,easeOutBez=BezierFactory.getBezierEasing(.167,.167,.667,1,"easeOut").get,easeInOutBez=BezierFactory.getBezierEasing(.33,0,.667,1,"easeInOut").get;function sum(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e)||"string"===i||"string"===r)return t+e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]+=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t+e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]+e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}var add=sum;function sub(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e))return"string"===i&&(t=parseInt(t,10)),"string"===r&&(e=parseInt(e,10)),t-e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]-=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t-e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]-e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}function mul(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t*e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]*e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t*e[r];return i}return 0}function div(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t/e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]/e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t/e[r];return i}return 0}function mod(t,e){return"string"==typeof t&&(t=parseInt(t,10)),"string"==typeof e&&(e=parseInt(e,10)),t%e}var $bm_sum=sum,$bm_sub=sub,$bm_mul=mul,$bm_div=div,$bm_mod=mod;function clamp(t,e,i){if(e>i){var r=i;i=e,e=r}return Math.min(Math.max(t,e),i)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return e=e||0,Math.abs(t-e);var i;e||(e=helperLengthArray);var r=Math.min(t.length,e.length),s=0;for(i=0;i<r;i+=1)s+=Math.pow(e[i]-t[i],2);return Math.sqrt(s)}function normalize(t){return div(t,length(t))}function rgbToHsl(t){var e,i,r=t[0],s=t[1],a=t[2],n=Math.max(r,s,a),o=Math.min(r,s,a),h=(n+o)/2;if(n===o)e=0,i=0;else{var l=n-o;switch(i=h>.5?l/(2-n-o):l/(n+o),n){case r:e=(s-a)/l+(s<a?6:0);break;case s:e=(a-r)/l+2;break;case a:e=(r-s)/l+4}e/=6}return[e,i,h,t[3]]}function hue2rgb(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}function hslToRgb(t){var e,i,r,s=t[0],a=t[1],n=t[2];if(0===a)e=n,r=n,i=n;else{var o=n<.5?n*(1+a):n+a-n*a,h=2*n-o;e=hue2rgb(h,o,s+1/3),i=hue2rgb(h,o,s),r=hue2rgb(h,o,s-1/3)}return[e,i,r,t[3]]}function linear(t,e,i,r,s){if(void 0!==r&&void 0!==s||(r=e,s=i,e=0,i=1),i<e){var a=i;i=e,e=a}if(t<=e)return r;if(t>=i)return s;var n,o=i===e?0:(t-e)/(i-e);if(!r.length)return r+(s-r)*o;var h=r.length,l=createTypedArray("float32",h);for(n=0;n<h;n+=1)l[n]=r[n]+(s[n]-r[n])*o;return l}function random(t,e){if(void 0===e&&(void 0===t?(t=0,e=1):(e=t,t=void 0)),e.length){var i,r=e.length;t||(t=createTypedArray("float32",r));var s=createTypedArray("float32",r),a=BMMath.random();for(i=0;i<r;i+=1)s[i]=t[i]+a*(e[i]-t[i]);return s}return void 0===t&&(t=0),t+BMMath.random()*(e-t)}function createPath(t,e,i,r){var s,a=t.length,n=shapePool.newElement();n.setPathData(!!r,a);var o,h,l=[0,0];for(s=0;s<a;s+=1)o=e&&e[s]?e[s]:l,h=i&&i[s]?i[s]:l,n.setTripleAt(t[s][0],t[s][1],h[0]+t[s][0],h[1]+t[s][1],o[0]+t[s][0],o[1]+t[s][1],s,!0);return n}function initiateExpression(elem,data,property){function noOp(t){return t}if(!elem.globalData.renderConfig.runExpressions)return noOp;var val=data.x,needsVelocity=/velocity(?![\w\d])/.test(val),_needsRandom=-1!==val.indexOf("random"),elemType=elem.data.ty,transform,$bm_transform,content,effect,thisProperty=property;thisProperty._name=elem.data.nm,thisProperty.valueAtTime=thisProperty.getValueAtTime,Object.defineProperty(thisProperty,"value",{get:function(){return thisProperty.v}}),elem.comp.frameDuration=1/elem.comp.globalData.frameRate,elem.comp.displayStartTime=0;var inPoint=elem.data.ip/elem.comp.globalData.frameRate,outPoint=elem.data.op/elem.comp.globalData.frameRate,width=elem.data.sw?elem.data.sw:0,height=elem.data.sh?elem.data.sh:0,name=elem.data.nm,loopIn,loop_in,loopOut,loop_out,smooth,toWorld,fromWorld,fromComp,toComp,fromCompToSurface,position,rotation,anchorPoint,scale,thisLayer,thisComp,mask,valueAtTime,velocityAtTime,scoped_bm_rt,expression_function=eval("[function _expression_function(){"+val+";scoped_bm_rt=$bm_rt}]")[0],numKeys=property.kf?data.k.length:0,active=!this.data||!0!==this.data.hd,wiggle=function(t,e){var i,r,s=this.pv.length?this.pv.length:1,a=createTypedArray("float32",s);var n=Math.floor(5*time);for(i=0,r=0;i<n;){for(r=0;r<s;r+=1)a[r]+=-e+2*e*BMMath.random();i+=1}var o=5*time,h=o-Math.floor(o),l=createTypedArray("float32",s);if(s>1){for(r=0;r<s;r+=1)l[r]=this.pv[r]+a[r]+(-e+2*e*BMMath.random())*h;return l}return this.pv+a[0]+(-e+2*e*BMMath.random())*h}.bind(this);function loopInDuration(t,e){return loopIn(t,e,!0)}function loopOutDuration(t,e){return loopOut(t,e,!0)}thisProperty.loopIn&&(loopIn=thisProperty.loopIn.bind(thisProperty),loop_in=loopIn),thisProperty.loopOut&&(loopOut=thisProperty.loopOut.bind(thisProperty),loop_out=loopOut),thisProperty.smooth&&(smooth=thisProperty.smooth.bind(thisProperty)),this.getValueAtTime&&(valueAtTime=this.getValueAtTime.bind(this)),this.getVelocityAtTime&&(velocityAtTime=this.getVelocityAtTime.bind(this));var comp=elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface),time,velocity,value,text,textIndex,textTotal,selectorValue;function lookAt(t,e){var i=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],r=Math.atan2(i[0],Math.sqrt(i[1]*i[1]+i[2]*i[2]))/degToRads;return[-Math.atan2(i[1],i[2])/degToRads,r,0]}function easeOut(t,e,i,r,s){return applyEase(easeOutBez,t,e,i,r,s)}function easeIn(t,e,i,r,s){return applyEase(easeInBez,t,e,i,r,s)}function ease(t,e,i,r,s){return applyEase(easeInOutBez,t,e,i,r,s)}function applyEase(t,e,i,r,s,a){void 0===s?(s=i,a=r):e=(e-i)/(r-i),e>1?e=1:e<0&&(e=0);var n=t(e);if($bm_isInstanceOfArray(s)){var o,h=s.length,l=createTypedArray("float32",h);for(o=0;o<h;o+=1)l[o]=(a[o]-s[o])*n+s[o];return l}return(a-s)*n+s}function nearestKey(t){var e,i,r,s=data.k.length;if(data.k.length&&"number"!=typeof data.k[0])if(i=-1,(t*=elem.comp.globalData.frameRate)<data.k[0].t)i=1,r=data.k[0].t;else{for(e=0;e<s-1;e+=1){if(t===data.k[e].t){i=e+1,r=data.k[e].t;break}if(t>data.k[e].t&&t<data.k[e+1].t){t-data.k[e].t>data.k[e+1].t-t?(i=e+2,r=data.k[e+1].t):(i=e+1,r=data.k[e].t);break}}-1===i&&(i=e+1,r=data.k[e].t)}else i=0,r=0;var a={};return a.index=i,a.time=r/elem.comp.globalData.frameRate,a}function key(t){var e,i,r;if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]};var s=Object.prototype.hasOwnProperty.call(data.k[t],"s")?data.k[t].s:data.k[t-1].e;for(r=s.length,i=0;i<r;i+=1)e[i]=s[i],e.value[i]=s[i];return e}function framesToTime(t,e){return e||(e=elem.comp.globalData.frameRate),t/e}function timeToFrames(t,e){return t||0===t||(t=time),e||(e=elem.comp.globalData.frameRate),t*e}function seedRandom(t){BMMath.seedrandom(randSeed+t)}function sourceRectAtTime(){return elem.sourceRectAtTime()}function substring(t,e){return"string"==typeof value?void 0===e?value.substring(t):value.substring(t,e):""}function substr(t,e){return"string"==typeof value?void 0===e?value.substr(t):value.substr(t,e):""}function posterizeTime(t){time=0===t?0:Math.floor(time*t)/t,value=valueAtTime(time)}var index=elem.data.ind,hasParent=!(!elem.hierarchy||!elem.hierarchy.length),parent,randSeed=Math.floor(1e6*Math.random()),globalData=elem.globalData;function executeExpression(t){return value=t,this.frameExpressionId===elem.globalData.frameId&&"textSelector"!==this.propType?value:("textSelector"===this.propType&&(textIndex=this.textIndex,textTotal=this.textTotal,selectorValue=this.selectorValue),thisLayer||(text=elem.layerInterface.text,thisLayer=elem.layerInterface,thisComp=elem.comp.compInterface,toWorld=thisLayer.toWorld.bind(thisLayer),fromWorld=thisLayer.fromWorld.bind(thisLayer),fromComp=thisLayer.fromComp.bind(thisLayer),toComp=thisLayer.toComp.bind(thisLayer),mask=thisLayer.mask?thisLayer.mask.bind(thisLayer):null,fromCompToSurface=fromComp),transform||(transform=elem.layerInterface("ADBE Transform Group"),$bm_transform=transform,transform&&(anchorPoint=transform.anchorPoint)),4!==elemType||content||(content=thisLayer("ADBE Root Vectors Group")),effect||(effect=thisLayer(4)),(hasParent=!(!elem.hierarchy||!elem.hierarchy.length))&&!parent&&(parent=elem.hierarchy[0].layerInterface),time=this.comp.renderedFrame/this.comp.globalData.frameRate,_needsRandom&&seedRandom(randSeed+time),needsVelocity&&(velocity=velocityAtTime(time)),expression_function(),this.frameExpressionId=elem.globalData.frameId,scoped_bm_rt=scoped_bm_rt.propType===propTypes.SHAPE?scoped_bm_rt.v:scoped_bm_rt)}return executeExpression.__preventDeadCodeRemoval=[$bm_transform,anchorPoint,time,velocity,inPoint,outPoint,width,height,name,loop_in,loop_out,smooth,toComp,fromCompToSurface,toWorld,fromWorld,mask,position,rotation,scale,thisComp,numKeys,active,wiggle,loopInDuration,loopOutDuration,comp,lookAt,easeOut,easeIn,ease,nearestKey,key,text,textIndex,textTotal,selectorValue,framesToTime,timeToFrames,sourceRectAtTime,substring,substr,posterizeTime,index,globalData],executeExpression}return ob.initiateExpression=initiateExpression,ob.__preventDeadCodeRemoval=[window,document,XMLHttpRequest,fetch,frames,$bm_neg,add,$bm_sum,$bm_sub,$bm_mul,$bm_div,$bm_mod,clamp,radians_to_degrees,degreesToRadians,degrees_to_radians,normalize,rgbToHsl,hslToRgb,linear,random,createPath,_lottieGlobal],ob.resetFrame=resetFrame,ob}(),Expressions=function(){var t={};return t.initExpressions=function(t){var e=0,i=[];t.renderer.compInterface=CompExpressionInterface(t.renderer),t.renderer.globalData.projectInterface.registerComposition(t.renderer),t.renderer.globalData.pushExpression=function(){e+=1},t.renderer.globalData.popExpression=function(){0==(e-=1)&&function(){var t,e=i.length;for(t=0;t<e;t+=1)i[t].release();i.length=0}()},t.renderer.globalData.registerExpressionProperty=function(t){-1===i.indexOf(t)&&i.push(t)}},t.resetFrame=ExpressionManager.resetFrame,t}(),MaskManagerInterface=function(){function t(t,e){this._mask=t,this._data=e}Object.defineProperty(t.prototype,"maskPath",{get:function(){return this._mask.prop.k&&this._mask.prop.getValue(),this._mask.prop}}),Object.defineProperty(t.prototype,"maskOpacity",{get:function(){return this._mask.op.k&&this._mask.op.getValue(),100*this._mask.op.v}});return function(e){var i,r=createSizedArray(e.viewData.length),s=e.viewData.length;for(i=0;i<s;i+=1)r[i]=new t(e.viewData[i],e.masksProperties[i]);return function(t){for(i=0;i<s;){if(e.masksProperties[i].nm===t)return r[i];i+=1}return null}}}(),ExpressionPropertyInterface=function(){var t={pv:0,v:0,mult:1},e={pv:[0,0,0],v:[0,0,0],mult:1};function i(t,e,i){Object.defineProperty(t,"velocity",{get:function(){return e.getVelocityAtTime(e.comp.currentFrame)}}),t.numKeys=e.keyframes?e.keyframes.length:0,t.key=function(r){if(!t.numKeys)return 0;var s="";s="s"in e.keyframes[r-1]?e.keyframes[r-1].s:"e"in e.keyframes[r-2]?e.keyframes[r-2].e:e.keyframes[r-2].s;var a="unidimensional"===i?new Number(s):Object.assign({},s);return a.time=e.keyframes[r-1].t/e.elem.comp.globalData.frameRate,a.value="unidimensional"===i?s[0]:s,a},t.valueAtTime=e.getValueAtTime,t.speedAtTime=e.getSpeedAtTime,t.velocityAtTime=e.getVelocityAtTime,t.propertyGroup=e.propertyGroup}function r(){return t}return function(s){return s?"unidimensional"===s.propType?function(e){e&&"pv"in e||(e=t);var r=1/e.mult,s=e.pv*r,a=new Number(s);return a.value=s,i(a,e,"unidimensional"),function(){return e.k&&e.getValue(),s=e.v*r,a.value!==s&&((a=new Number(s)).value=s,a[0]=s,i(a,e,"unidimensional")),a}}(s):function(t){t&&"pv"in t||(t=e);var r=1/t.mult,s=t.data&&t.data.l||t.pv.length,a=createTypedArray("float32",s),n=createTypedArray("float32",s);return a.value=n,i(a,t,"multidimensional"),function(){t.k&&t.getValue();for(var e=0;e<s;e+=1)n[e]=t.v[e]*r,a[e]=n[e];return a}}(s):r}}(),TransformExpressionInterface=function(t){function e(t){switch(t){case"scale":case"Scale":case"ADBE Scale":case 6:return e.scale;case"rotation":case"Rotation":case"ADBE Rotation":case"ADBE Rotate Z":case 10:return e.rotation;case"ADBE Rotate X":return e.xRotation;case"ADBE Rotate Y":return e.yRotation;case"position":case"Position":case"ADBE Position":case 2:return e.position;case"ADBE Position_0":return e.xPosition;case"ADBE Position_1":return e.yPosition;case"ADBE Position_2":return e.zPosition;case"anchorPoint":case"AnchorPoint":case"Anchor Point":case"ADBE AnchorPoint":case 1:return e.anchorPoint;case"opacity":case"Opacity":case 11:return e.opacity;default:return null}}var i,r,s,a;return Object.defineProperty(e,"rotation",{get:ExpressionPropertyInterface(t.r||t.rz)}),Object.defineProperty(e,"zRotation",{get:ExpressionPropertyInterface(t.rz||t.r)}),Object.defineProperty(e,"xRotation",{get:ExpressionPropertyInterface(t.rx)}),Object.defineProperty(e,"yRotation",{get:ExpressionPropertyInterface(t.ry)}),Object.defineProperty(e,"scale",{get:ExpressionPropertyInterface(t.s)}),t.p?a=ExpressionPropertyInterface(t.p):(i=ExpressionPropertyInterface(t.px),r=ExpressionPropertyInterface(t.py),t.pz&&(s=ExpressionPropertyInterface(t.pz))),Object.defineProperty(e,"position",{get:function(){return t.p?a():[i(),r(),s?s():0]}}),Object.defineProperty(e,"xPosition",{get:ExpressionPropertyInterface(t.px)}),Object.defineProperty(e,"yPosition",{get:ExpressionPropertyInterface(t.py)}),Object.defineProperty(e,"zPosition",{get:ExpressionPropertyInterface(t.pz)}),Object.defineProperty(e,"anchorPoint",{get:ExpressionPropertyInterface(t.a)}),Object.defineProperty(e,"opacity",{get:ExpressionPropertyInterface(t.o)}),Object.defineProperty(e,"skew",{get:ExpressionPropertyInterface(t.sk)}),Object.defineProperty(e,"skewAxis",{get:ExpressionPropertyInterface(t.sa)}),Object.defineProperty(e,"orientation",{get:ExpressionPropertyInterface(t.or)}),e},LayerExpressionInterface=function(){function t(t){var e=new Matrix;void 0!==t?this._elem.finalTransform.mProp.getValueAtTime(t).clone(e):this._elem.finalTransform.mProp.applyToMatrix(e);return e}function e(t,e){var i=this.getMatrix(e);return i.props[12]=0,i.props[13]=0,i.props[14]=0,this.applyPoint(i,t)}function i(t,e){var i=this.getMatrix(e);return this.applyPoint(i,t)}function r(t,e){var i=this.getMatrix(e);return i.props[12]=0,i.props[13]=0,i.props[14]=0,this.invertPoint(i,t)}function s(t,e){var i=this.getMatrix(e);return this.invertPoint(i,t)}function a(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(t)}return t.applyToPointArray(e[0],e[1],e[2]||0)}function n(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(t)}return t.inversePoint(e)}function o(t){var e=new Matrix;if(e.reset(),this._elem.finalTransform.mProp.applyToMatrix(e),this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(e);return e.inversePoint(t)}return e.inversePoint(t)}function h(){return[1,1,1,1]}return function(l){var p;function f(t){switch(t){case"ADBE Root Vectors Group":case"Contents":case 2:return f.shapeInterface;case 1:case 6:case"Transform":case"transform":case"ADBE Transform Group":return p;case 4:case"ADBE Effect Parade":case"effects":case"Effects":return f.effect;case"ADBE Text Properties":return f.textInterface;default:return null}}f.getMatrix=t,f.invertPoint=n,f.applyPoint=a,f.toWorld=i,f.toWorldVec=e,f.fromWorld=s,f.fromWorldVec=r,f.toComp=i,f.fromComp=o,f.sampleImage=h,f.sourceRectAtTime=l.sourceRectAtTime.bind(l),f._elem=l;var m=getDescriptor(p=TransformExpressionInterface(l.finalTransform.mProp),"anchorPoint");return Object.defineProperties(f,{hasParent:{get:function(){return l.hierarchy.length}},parent:{get:function(){return l.hierarchy[0].layerInterface}},rotation:getDescriptor(p,"rotation"),scale:getDescriptor(p,"scale"),position:getDescriptor(p,"position"),opacity:getDescriptor(p,"opacity"),anchorPoint:m,anchor_point:m,transform:{get:function(){return p}},active:{get:function(){return l.isInRange}}}),f.startTime=l.data.st,f.index=l.data.ind,f.source=l.data.refId,f.height=0===l.data.ty?l.data.h:100,f.width=0===l.data.ty?l.data.w:100,f.inPoint=l.data.ip/l.comp.globalData.frameRate,f.outPoint=l.data.op/l.comp.globalData.frameRate,f._name=l.data.nm,f.registerMaskInterface=function(t){f.mask=new MaskManagerInterface(t,l)},f.registerEffectsInterface=function(t){f.effect=t},f}}(),propertyGroupFactory=function(t,e){return function(i){return(i=void 0===i?1:i)<=0?t:e(i-1)}},PropertyInterface=function(t,e){var i={_name:t};return function(t){return(t=void 0===t?1:t)<=0?i:e(t-1)}},EffectsExpressionInterface=function(){function t(i,r,s,a){function n(t){for(var e=i.ef,r=0,s=e.length;r<s;){if(t===e[r].nm||t===e[r].mn||t===e[r].ix)return 5===e[r].ty?l[r]:l[r]();r+=1}throw new Error}var o,h=propertyGroupFactory(n,s),l=[],p=i.ef.length;for(o=0;o<p;o+=1)5===i.ef[o].ty?l.push(t(i.ef[o],r.effectElements[o],r.effectElements[o].propertyGroup,a)):l.push(e(r.effectElements[o],i.ef[o].ty,a,h));return"ADBE Color Control"===i.mn&&Object.defineProperty(n,"color",{get:function(){return l[0]()}}),Object.defineProperties(n,{numProperties:{get:function(){return i.np}},_name:{value:i.nm},propertyGroup:{value:h}}),n.enabled=0!==i.en,n.active=n.enabled,n}function e(t,e,i,r){var s=ExpressionPropertyInterface(t.p);return t.p.setGroupProperty&&t.p.setGroupProperty(PropertyInterface("",r)),function(){return 10===e?i.comp.compInterface(t.p.v):s()}}return{createEffectsInterface:function(e,i){if(e.effectsManager){var r,s=[],a=e.data.ef,n=e.effectsManager.effectElements.length;for(r=0;r<n;r+=1)s.push(t(a[r],e.effectsManager.effectElements[r],i,e));var o=e.data.ef||[],h=function(t){for(r=0,n=o.length;r<n;){if(t===o[r].nm||t===o[r].mn||t===o[r].ix)return s[r];r+=1}return null};return Object.defineProperty(h,"numProperties",{get:function(){return o.length}}),h}return null}}}(),ShapePathInterface=function(t,e,i){var r=e.sh;function s(t){return"Shape"===t||"shape"===t||"Path"===t||"path"===t||"ADBE Vector Shape"===t||2===t?s.path:null}var a=propertyGroupFactory(s,i);return r.setGroupProperty(PropertyInterface("Path",a)),Object.defineProperties(s,{path:{get:function(){return r.k&&r.getValue(),r}},shape:{get:function(){return r.k&&r.getValue(),r}},_name:{value:t.nm},ix:{value:t.ix},propertyIndex:{value:t.ix},mn:{value:t.mn},propertyGroup:{value:i}}),s},ShapeExpressionInterface=function(){function t(t,o,c){var d,u=[],y=t?t.length:0;for(d=0;d<y;d+=1)"gr"===t[d].ty?u.push(e(t[d],o[d],c)):"fl"===t[d].ty?u.push(i(t[d],o[d],c)):"st"===t[d].ty?u.push(a(t[d],o[d],c)):"tm"===t[d].ty?u.push(n(t[d],o[d],c)):"tr"===t[d].ty||("el"===t[d].ty?u.push(h(t[d],o[d],c)):"sr"===t[d].ty?u.push(l(t[d],o[d],c)):"sh"===t[d].ty?u.push(ShapePathInterface(t[d],o[d],c)):"rc"===t[d].ty?u.push(p(t[d],o[d],c)):"rd"===t[d].ty?u.push(f(t[d],o[d],c)):"rp"===t[d].ty?u.push(m(t[d],o[d],c)):"gf"===t[d].ty?u.push(r(t[d],o[d],c)):u.push(s(t[d],o[d])));return u}function e(e,i,r){var s=function(t){switch(t){case"ADBE Vectors Group":case"Contents":case 2:return s.content;default:return s.transform}};s.propertyGroup=propertyGroupFactory(s,r);var a=function(e,i,r){var s,a=function(t){for(var e=0,i=s.length;e<i;){if(s[e]._name===t||s[e].mn===t||s[e].propertyIndex===t||s[e].ix===t||s[e].ind===t)return s[e];e+=1}return"number"==typeof t?s[t-1]:null};a.propertyGroup=propertyGroupFactory(a,r),s=t(e.it,i.it,a.propertyGroup),a.numProperties=s.length;var n=o(e.it[e.it.length-1],i.it[i.it.length-1],a.propertyGroup);return a.transform=n,a.propertyIndex=e.cix,a._name=e.nm,a}(e,i,s.propertyGroup),n=o(e.it[e.it.length-1],i.it[i.it.length-1],s.propertyGroup);return s.content=a,s.transform=n,Object.defineProperty(s,"_name",{get:function(){return e.nm}}),s.numProperties=e.np,s.propertyIndex=e.ix,s.nm=e.nm,s.mn=e.mn,s}function i(t,e,i){function r(t){return"Color"===t||"color"===t?r.color:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r}function r(t,e,i){function r(t){return"Start Point"===t||"start point"===t?r.startPoint:"End Point"===t||"end point"===t?r.endPoint:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{startPoint:{get:ExpressionPropertyInterface(e.s)},endPoint:{get:ExpressionPropertyInterface(e.e)},opacity:{get:ExpressionPropertyInterface(e.o)},type:{get:function(){return"a"}},_name:{value:t.nm},mn:{value:t.mn}}),e.s.setGroupProperty(PropertyInterface("Start Point",i)),e.e.setGroupProperty(PropertyInterface("End Point",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r}function s(){return function(){return null}}function a(t,e,i){var r,s=propertyGroupFactory(l,i),a=propertyGroupFactory(h,s);function n(i){Object.defineProperty(h,t.d[i].nm,{get:ExpressionPropertyInterface(e.d.dataProps[i].p)})}var o=t.d?t.d.length:0,h={};for(r=0;r<o;r+=1)n(r),e.d.dataProps[r].p.setGroupProperty(a);function l(t){return"Color"===t||"color"===t?l.color:"Opacity"===t||"opacity"===t?l.opacity:"Stroke Width"===t||"stroke width"===t?l.strokeWidth:null}return Object.defineProperties(l,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},strokeWidth:{get:ExpressionPropertyInterface(e.w)},dash:{get:function(){return h}},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",s)),e.o.setGroupProperty(PropertyInterface("Opacity",s)),e.w.setGroupProperty(PropertyInterface("Stroke Width",s)),l}function n(t,e,i){function r(e){return e===t.e.ix||"End"===e||"end"===e?r.end:e===t.s.ix?r.start:e===t.o.ix?r.offset:null}var s=propertyGroupFactory(r,i);return r.propertyIndex=t.ix,e.s.setGroupProperty(PropertyInterface("Start",s)),e.e.setGroupProperty(PropertyInterface("End",s)),e.o.setGroupProperty(PropertyInterface("Offset",s)),r.propertyIndex=t.ix,r.propertyGroup=i,Object.defineProperties(r,{start:{get:ExpressionPropertyInterface(e.s)},end:{get:ExpressionPropertyInterface(e.e)},offset:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm}}),r.mn=t.mn,r}function o(t,e,i){function r(e){return t.a.ix===e||"Anchor Point"===e?r.anchorPoint:t.o.ix===e||"Opacity"===e?r.opacity:t.p.ix===e||"Position"===e?r.position:t.r.ix===e||"Rotation"===e||"ADBE Vector Rotation"===e?r.rotation:t.s.ix===e||"Scale"===e?r.scale:t.sk&&t.sk.ix===e||"Skew"===e?r.skew:t.sa&&t.sa.ix===e||"Skew Axis"===e?r.skewAxis:null}var s=propertyGroupFactory(r,i);return e.transform.mProps.o.setGroupProperty(PropertyInterface("Opacity",s)),e.transform.mProps.p.setGroupProperty(PropertyInterface("Position",s)),e.transform.mProps.a.setGroupProperty(PropertyInterface("Anchor Point",s)),e.transform.mProps.s.setGroupProperty(PropertyInterface("Scale",s)),e.transform.mProps.r.setGroupProperty(PropertyInterface("Rotation",s)),e.transform.mProps.sk&&(e.transform.mProps.sk.setGroupProperty(PropertyInterface("Skew",s)),e.transform.mProps.sa.setGroupProperty(PropertyInterface("Skew Angle",s))),e.transform.op.setGroupProperty(PropertyInterface("Opacity",s)),Object.defineProperties(r,{opacity:{get:ExpressionPropertyInterface(e.transform.mProps.o)},position:{get:ExpressionPropertyInterface(e.transform.mProps.p)},anchorPoint:{get:ExpressionPropertyInterface(e.transform.mProps.a)},scale:{get:ExpressionPropertyInterface(e.transform.mProps.s)},rotation:{get:ExpressionPropertyInterface(e.transform.mProps.r)},skew:{get:ExpressionPropertyInterface(e.transform.mProps.sk)},skewAxis:{get:ExpressionPropertyInterface(e.transform.mProps.sa)},_name:{value:t.nm}}),r.ty="tr",r.mn=t.mn,r.propertyGroup=i,r}function h(t,e,i){function r(e){return t.p.ix===e?r.position:t.s.ix===e?r.size:null}var s=propertyGroupFactory(r,i);r.propertyIndex=t.ix;var a="tm"===e.sh.ty?e.sh.prop:e.sh;return a.s.setGroupProperty(PropertyInterface("Size",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),Object.defineProperties(r,{size:{get:ExpressionPropertyInterface(a.s)},position:{get:ExpressionPropertyInterface(a.p)},_name:{value:t.nm}}),r.mn=t.mn,r}function l(t,e,i){function r(e){return t.p.ix===e?r.position:t.r.ix===e?r.rotation:t.pt.ix===e?r.points:t.or.ix===e||"ADBE Vector Star Outer Radius"===e?r.outerRadius:t.os.ix===e?r.outerRoundness:!t.ir||t.ir.ix!==e&&"ADBE Vector Star Inner Radius"!==e?t.is&&t.is.ix===e?r.innerRoundness:null:r.innerRadius}var s=propertyGroupFactory(r,i),a="tm"===e.sh.ty?e.sh.prop:e.sh;return r.propertyIndex=t.ix,a.or.setGroupProperty(PropertyInterface("Outer Radius",s)),a.os.setGroupProperty(PropertyInterface("Outer Roundness",s)),a.pt.setGroupProperty(PropertyInterface("Points",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),t.ir&&(a.ir.setGroupProperty(PropertyInterface("Inner Radius",s)),a.is.setGroupProperty(PropertyInterface("Inner Roundness",s))),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(a.p)},rotation:{get:ExpressionPropertyInterface(a.r)},points:{get:ExpressionPropertyInterface(a.pt)},outerRadius:{get:ExpressionPropertyInterface(a.or)},outerRoundness:{get:ExpressionPropertyInterface(a.os)},innerRadius:{get:ExpressionPropertyInterface(a.ir)},innerRoundness:{get:ExpressionPropertyInterface(a.is)},_name:{value:t.nm}}),r.mn=t.mn,r}function p(t,e,i){function r(e){return t.p.ix===e?r.position:t.r.ix===e?r.roundness:t.s.ix===e||"Size"===e||"ADBE Vector Rect Size"===e?r.size:null}var s=propertyGroupFactory(r,i),a="tm"===e.sh.ty?e.sh.prop:e.sh;return r.propertyIndex=t.ix,a.p.setGroupProperty(PropertyInterface("Position",s)),a.s.setGroupProperty(PropertyInterface("Size",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(a.p)},roundness:{get:ExpressionPropertyInterface(a.r)},size:{get:ExpressionPropertyInterface(a.s)},_name:{value:t.nm}}),r.mn=t.mn,r}function f(t,e,i){function r(e){return t.r.ix===e||"Round Corners 1"===e?r.radius:null}var s=propertyGroupFactory(r,i),a=e;return r.propertyIndex=t.ix,a.rd.setGroupProperty(PropertyInterface("Radius",s)),Object.defineProperties(r,{radius:{get:ExpressionPropertyInterface(a.rd)},_name:{value:t.nm}}),r.mn=t.mn,r}function m(t,e,i){function r(e){return t.c.ix===e||"Copies"===e?r.copies:t.o.ix===e||"Offset"===e?r.offset:null}var s=propertyGroupFactory(r,i),a=e;return r.propertyIndex=t.ix,a.c.setGroupProperty(PropertyInterface("Copies",s)),a.o.setGroupProperty(PropertyInterface("Offset",s)),Object.defineProperties(r,{copies:{get:ExpressionPropertyInterface(a.c)},offset:{get:ExpressionPropertyInterface(a.o)},_name:{value:t.nm}}),r.mn=t.mn,r}return function(e,i,r){var s;function a(t){if("number"==typeof t)return 0===(t=void 0===t?1:t)?r:s[t-1];for(var e=0,i=s.length;e<i;){if(s[e]._name===t)return s[e];e+=1}return null}return a.propertyGroup=propertyGroupFactory(a,(function(){return r})),s=t(e,i,a.propertyGroup),a.numProperties=s.length,a._name="Contents",a}}(),TextExpressionInterface=function(t){var e;function i(t){return"ADBE Text Document"===t?i.sourceText:null}return Object.defineProperty(i,"sourceText",{get:function(){t.textProperty.getValue();var i=t.textProperty.currentData.t;return e&&i===e.value||((e=new String(i)).value=i||new String(i),Object.defineProperty(e,"style",{get:function(){return{fillColor:t.textProperty.currentData.fc}}})),e}}),i};function _typeof(t){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof(t)}var FootageInterface=(dataInterfaceFactory=function(t){function e(t){return"Outline"===t?e.outlineInterface():null}return e._name="Outline",e.outlineInterface=function(t){var e="",i=t.getFootageData();function r(t){if(i[t])return e=t,"object"===_typeof(i=i[t])?r:i;var s=t.indexOf(e);if(-1!==s){var a=parseInt(t.substr(s+e.length),10);return"object"===_typeof(i=i[a])?r:i}return""}return function(){return e="",i=t.getFootageData(),r}}(t),e},function(t){function e(t){return"Data"===t?e.dataInterface:null}return e._name="Data",e.dataInterface=dataInterfaceFactory(t),e}),dataInterfaceFactory,interfaces={layer:LayerExpressionInterface,effects:EffectsExpressionInterface,comp:CompExpressionInterface,shape:ShapeExpressionInterface,text:TextExpressionInterface,footage:FootageInterface};function getInterface(t){return interfaces[t]||null}var expressionHelpers={searchExpressions:function(t,e,i){e.x&&(i.k=!0,i.x=!0,i.initiateExpression=ExpressionManager.initiateExpression,i.effectsSequence.push(i.initiateExpression(t,e,i).bind(i)))},getSpeedAtTime:function(t){var e=this.getValueAtTime(t),i=this.getValueAtTime(t+-.01),r=0;if(e.length){var s;for(s=0;s<e.length;s+=1)r+=Math.pow(i[s]-e[s],2);r=100*Math.sqrt(r)}else r=0;return r},getVelocityAtTime:function(t){if(void 0!==this.vel)return this.vel;var e,i,r=-.001,s=this.getValueAtTime(t),a=this.getValueAtTime(t+r);if(s.length)for(e=createTypedArray("float32",s.length),i=0;i<s.length;i+=1)e[i]=(a[i]-s[i])/r;else e=(a-s)/r;return e},getValueAtTime:function(t){return t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastFrame&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastFrame<t?this._cachingAtTime.lastIndex:0,this._cachingAtTime.value=this.interpolateValue(t,this._cachingAtTime),this._cachingAtTime.lastFrame=t),this._cachingAtTime.value},getStaticValueAtTime:function(){return this.pv},setGroupProperty:function(t){this.propertyGroup=t}};function addPropertyDecorator(){function t(t,e,i){if(!this.k||!this.keyframes)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[l.length-1].t;if(h<=p)return this.pv;if(i?s=p-(r=e?Math.abs(p-this.elem.comp.globalData.frameRate*e):Math.max(0,p-this.elem.data.ip)):((!e||e>l.length-1)&&(e=l.length-1),r=p-(s=l[l.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/r)%2!=0)return this.getValueAtTime((r-(h-s)%r+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),m=this.getValueAtTime(p/this.comp.globalData.frameRate,0),c=this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0),d=Math.floor((h-s)/r);if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=(m[a]-f[a])*d+c[a];return o}return(m-f)*d+c}if("continue"===t){var u=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p-.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*((h-p)/this.comp.globalData.frameRate)/5e-4;return o}return u+(h-p)/.001*(u-y)}}return this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0)}function e(t,e,i){if(!this.k)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[0].t;if(h>=p)return this.pv;if(i?s=p+(r=e?Math.abs(this.elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-p)):((!e||e>l.length-1)&&(e=l.length-1),r=(s=l[e].t)-p),"pingpong"===t){if(Math.floor((p-h)/r)%2==0)return this.getValueAtTime(((p-h)%r+p)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(p/this.comp.globalData.frameRate,0),m=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime((r-(p-h)%r+p)/this.comp.globalData.frameRate,0),d=Math.floor((p-h)/r)+1;if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=c[a]-(m[a]-f[a])*d;return o}return c-(m-f)*d}if("continue"===t){var u=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p+.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*(p-h)/.001;return o}return u+(u-y)*(p-h)/.001}}return this.getValueAtTime((r-((p-h)%r+p))/this.comp.globalData.frameRate,0)}function i(t,e){if(!this.k)return this.pv;if(t=.5*(t||.4),(e=Math.floor(e||5))<=1)return this.pv;var i,r,s=this.comp.renderedFrame/this.comp.globalData.frameRate,a=s-t,n=e>1?(s+t-a)/(e-1):1,o=0,h=0;for(i=this.pv.length?createTypedArray("float32",this.pv.length):0;o<e;){if(r=this.getValueAtTime(a+o*n),this.pv.length)for(h=0;h<this.pv.length;h+=1)i[h]+=r[h];else i+=r;o+=1}if(this.pv.length)for(h=0;h<this.pv.length;h+=1)i[h]/=e;else i/=e;return i}function r(t){this._transformCachingAtTime||(this._transformCachingAtTime={v:new Matrix});var e=this._transformCachingAtTime.v;if(e.cloneFromProps(this.pre.props),this.appliedTransformations<1){var i=this.a.getValueAtTime(t);e.translate(-i[0]*this.a.mult,-i[1]*this.a.mult,i[2]*this.a.mult)}if(this.appliedTransformations<2){var r=this.s.getValueAtTime(t);e.scale(r[0]*this.s.mult,r[1]*this.s.mult,r[2]*this.s.mult)}if(this.sk&&this.appliedTransformations<3){var s=this.sk.getValueAtTime(t),a=this.sa.getValueAtTime(t);e.skewFromAxis(-s*this.sk.mult,a*this.sa.mult)}if(this.r&&this.appliedTransformations<4){var n=this.r.getValueAtTime(t);e.rotate(-n*this.r.mult)}else if(!this.r&&this.appliedTransformations<4){var o=this.rz.getValueAtTime(t),h=this.ry.getValueAtTime(t),l=this.rx.getValueAtTime(t),p=this.or.getValueAtTime(t);e.rotateZ(-o*this.rz.mult).rotateY(h*this.ry.mult).rotateX(l*this.rx.mult).rotateZ(-p[2]*this.or.mult).rotateY(p[1]*this.or.mult).rotateX(p[0]*this.or.mult)}if(this.data.p&&this.data.p.s){var f=this.px.getValueAtTime(t),m=this.py.getValueAtTime(t);if(this.data.p.z){var c=this.pz.getValueAtTime(t);e.translate(f*this.px.mult,m*this.py.mult,-c*this.pz.mult)}else e.translate(f*this.px.mult,m*this.py.mult,0)}else{var d=this.p.getValueAtTime(t);e.translate(d[0]*this.p.mult,d[1]*this.p.mult,-d[2]*this.p.mult)}return e}function s(){return this.v.clone(new Matrix)}var a=TransformPropertyFactory.getTransformProperty;TransformPropertyFactory.getTransformProperty=function(t,e,i){var n=a(t,e,i);return n.dynamicProperties.length?n.getValueAtTime=r.bind(n):n.getValueAtTime=s.bind(n),n.setGroupProperty=expressionHelpers.setGroupProperty,n};var n=PropertyFactory.getProp;PropertyFactory.getProp=function(r,s,a,o,h){var l=n(r,s,a,o,h);l.kf?l.getValueAtTime=expressionHelpers.getValueAtTime.bind(l):l.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(l),l.setGroupProperty=expressionHelpers.setGroupProperty,l.loopOut=t,l.loopIn=e,l.smooth=i,l.getVelocityAtTime=expressionHelpers.getVelocityAtTime.bind(l),l.getSpeedAtTime=expressionHelpers.getSpeedAtTime.bind(l),l.numKeys=1===s.a?s.k.length:0,l.propertyIndex=s.ix;var p=0;return 0!==a&&(p=createTypedArray("float32",1===s.a?s.k[0].s.length:s.k.length)),l._cachingAtTime={lastFrame:initialDefaultFrame,lastIndex:0,value:p},expressionHelpers.searchExpressions(r,s,l),l.k&&h.addDynamicProperty(l),l};var o=ShapePropertyFactory.getConstructorFunction(),h=ShapePropertyFactory.getKeyframedConstructorFunction();function l(){}l.prototype={vertices:function(t,e){this.k&&this.getValue();var i,r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0));var s=r._length,a=r[t],n=r.v,o=createSizedArray(s);for(i=0;i<s;i+=1)o[i]="i"===t||"o"===t?[a[i][0]-n[i][0],a[i][1]-n[i][1]]:[a[i][0],a[i][1]];return o},points:function(t){return this.vertices("v",t)},inTangents:function(t){return this.vertices("i",t)},outTangents:function(t){return this.vertices("o",t)},isClosed:function(){return this.v.c},pointOnPath:function(t,e){var i=this.v;void 0!==e&&(i=this.getValueAtTime(e,0)),this._segmentsLength||(this._segmentsLength=bez.getSegmentsLength(i));for(var r,s=this._segmentsLength,a=s.lengths,n=s.totalLength*t,o=0,h=a.length,l=0;o<h;){if(l+a[o].addedLength>n){var p=o,f=i.c&&o===h-1?0:o+1,m=(n-l)/a[o].addedLength;r=bez.getPointInSegment(i.v[p],i.v[f],i.o[p],i.i[f],m,a[o]);break}l+=a[o].addedLength,o+=1}return r||(r=i.c?[i.v[0][0],i.v[0][1]]:[i.v[i._length-1][0],i.v[i._length-1][1]]),r},vectorOnPath:function(t,e,i){1==t?t=this.v.c:0==t&&(t=.999);var r=this.pointOnPath(t,e),s=this.pointOnPath(t+.001,e),a=s[0]-r[0],n=s[1]-r[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return 0===o?[0,0]:"tangent"===i?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([l],o),extendPrototype([l],h),h.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shapePool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime<t?this._caching.lastIndex:0,this._cachingAtTime.lastTime=t,this.interpolateShape(t,this._cachingAtTime.shapeValue,this._cachingAtTime)),this._cachingAtTime.shapeValue},h.prototype.initiateExpression=ExpressionManager.initiateExpression;var p=ShapePropertyFactory.getShapeProp;ShapePropertyFactory.getShapeProp=function(t,e,i,r,s){var a=p(t,e,i,r,s);return a.propertyIndex=e.ix,a.lock=!1,3===i?expressionHelpers.searchExpressions(t,e.pt,a):4===i&&expressionHelpers.searchExpressions(t,e.ks,a),a.k&&t.addDynamicProperty(a),a}}function initialize$1(){addPropertyDecorator()}function addDecorator(){TextProperty.prototype.getExpressionValue=function(t,e){var i=this.calculateExpression(e);if(t.t!==i){var r={};return this.copyData(r,t),r.t=i.toString(),r.__complete=!1,r}return t},TextProperty.prototype.searchProperty=function(){var t=this.searchKeyframes(),e=this.searchExpressions();return this.kf=t||e,this.kf},TextProperty.prototype.searchExpressions=function(){return this.data.d.x?(this.calculateExpression=ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this),this.addEffect(this.getExpressionValue.bind(this)),!0):null}}function initialize(){addDecorator()}function SVGComposableEffect(){}SVGComposableEffect.prototype={createMergeNode:function(t,e){var i,r,s=createNS("feMerge");for(s.setAttribute("result",t),r=0;r<e.length;r+=1)(i=createNS("feMergeNode")).setAttribute("in",e[r]),s.appendChild(i),s.appendChild(i);return s}};var linearFilterValue="0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0";function SVGTintFilter(t,e,i,r,s){this.filterManager=e;var a=createNS("feColorMatrix");a.setAttribute("type","matrix"),a.setAttribute("color-interpolation-filters","linearRGB"),a.setAttribute("values",linearFilterValue+" 1 0"),this.linearFilter=a,a.setAttribute("result",r+"_tint_1"),t.appendChild(a),(a=createNS("feColorMatrix")).setAttribute("type","matrix"),a.setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),a.setAttribute("result",r+"_tint_2"),t.appendChild(a),this.matrixFilter=a;var n=this.createMergeNode(r,[s,r+"_tint_1",r+"_tint_2"]);t.appendChild(n)}function SVGFillFilter(t,e,i,r){this.filterManager=e;var s=createNS("feColorMatrix");s.setAttribute("type","matrix"),s.setAttribute("color-interpolation-filters","sRGB"),s.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),s.setAttribute("result",r),t.appendChild(s),this.matrixFilter=s}function SVGStrokeEffect(t,e,i){this.initialized=!1,this.filterManager=e,this.elem=i,this.paths=[]}function SVGTritoneFilter(t,e,i,r){this.filterManager=e;var s=createNS("feColorMatrix");s.setAttribute("type","matrix"),s.setAttribute("color-interpolation-filters","linearRGB"),s.setAttribute("values","0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0"),t.appendChild(s);var a=createNS("feComponentTransfer");a.setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("result",r),this.matrixFilter=a;var n=createNS("feFuncR");n.setAttribute("type","table"),a.appendChild(n),this.feFuncR=n;var o=createNS("feFuncG");o.setAttribute("type","table"),a.appendChild(o),this.feFuncG=o;var h=createNS("feFuncB");h.setAttribute("type","table"),a.appendChild(h),this.feFuncB=h,t.appendChild(a)}function SVGProLevelsFilter(t,e,i,r){this.filterManager=e;var s=this.filterManager.effectElements,a=createNS("feComponentTransfer");(s[10].p.k||0!==s[10].p.v||s[11].p.k||1!==s[11].p.v||s[12].p.k||1!==s[12].p.v||s[13].p.k||0!==s[13].p.v||s[14].p.k||1!==s[14].p.v)&&(this.feFuncR=this.createFeFunc("feFuncR",a)),(s[17].p.k||0!==s[17].p.v||s[18].p.k||1!==s[18].p.v||s[19].p.k||1!==s[19].p.v||s[20].p.k||0!==s[20].p.v||s[21].p.k||1!==s[21].p.v)&&(this.feFuncG=this.createFeFunc("feFuncG",a)),(s[24].p.k||0!==s[24].p.v||s[25].p.k||1!==s[25].p.v||s[26].p.k||1!==s[26].p.v||s[27].p.k||0!==s[27].p.v||s[28].p.k||1!==s[28].p.v)&&(this.feFuncB=this.createFeFunc("feFuncB",a)),(s[31].p.k||0!==s[31].p.v||s[32].p.k||1!==s[32].p.v||s[33].p.k||1!==s[33].p.v||s[34].p.k||0!==s[34].p.v||s[35].p.k||1!==s[35].p.v)&&(this.feFuncA=this.createFeFunc("feFuncA",a)),(this.feFuncR||this.feFuncG||this.feFuncB||this.feFuncA)&&(a.setAttribute("color-interpolation-filters","sRGB"),t.appendChild(a)),(s[3].p.k||0!==s[3].p.v||s[4].p.k||1!==s[4].p.v||s[5].p.k||1!==s[5].p.v||s[6].p.k||0!==s[6].p.v||s[7].p.k||1!==s[7].p.v)&&((a=createNS("feComponentTransfer")).setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("result",r),t.appendChild(a),this.feFuncRComposed=this.createFeFunc("feFuncR",a),this.feFuncGComposed=this.createFeFunc("feFuncG",a),this.feFuncBComposed=this.createFeFunc("feFuncB",a))}function SVGDropShadowEffect(t,e,i,r,s){var a=e.container.globalData.renderConfig.filterSize,n=e.data.fs||a;t.setAttribute("x",n.x||a.x),t.setAttribute("y",n.y||a.y),t.setAttribute("width",n.width||a.width),t.setAttribute("height",n.height||a.height),this.filterManager=e;var o=createNS("feGaussianBlur");o.setAttribute("in","SourceAlpha"),o.setAttribute("result",r+"_drop_shadow_1"),o.setAttribute("stdDeviation","0"),this.feGaussianBlur=o,t.appendChild(o);var h=createNS("feOffset");h.setAttribute("dx","25"),h.setAttribute("dy","0"),h.setAttribute("in",r+"_drop_shadow_1"),h.setAttribute("result",r+"_drop_shadow_2"),this.feOffset=h,t.appendChild(h);var l=createNS("feFlood");l.setAttribute("flood-color","#00ff00"),l.setAttribute("flood-opacity","1"),l.setAttribute("result",r+"_drop_shadow_3"),this.feFlood=l,t.appendChild(l);var p=createNS("feComposite");p.setAttribute("in",r+"_drop_shadow_3"),p.setAttribute("in2",r+"_drop_shadow_2"),p.setAttribute("operator","in"),p.setAttribute("result",r+"_drop_shadow_4"),t.appendChild(p);var f=this.createMergeNode(r,[r+"_drop_shadow_4",s]);t.appendChild(f)}extendPrototype([SVGComposableEffect],SVGTintFilter),SVGTintFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=this.filterManager.effectElements[2].p.v/100;this.linearFilter.setAttribute("values",linearFilterValue+" "+r+" 0"),this.matrixFilter.setAttribute("values",i[0]-e[0]+" 0 0 0 "+e[0]+" "+(i[1]-e[1])+" 0 0 0 "+e[1]+" "+(i[2]-e[2])+" 0 0 0 "+e[2]+" 0 0 0 1 0")}},SVGFillFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[2].p.v,i=this.filterManager.effectElements[6].p.v;this.matrixFilter.setAttribute("values","0 0 0 0 "+e[0]+" 0 0 0 0 "+e[1]+" 0 0 0 0 "+e[2]+" 0 0 0 "+i+" 0")}},SVGStrokeEffect.prototype.initialize=function(){var t,e,i,r,s=this.elem.layerElement.children||this.elem.layerElement.childNodes;for(1===this.filterManager.effectElements[1].p.v?(r=this.elem.maskManager.masksProperties.length,i=0):r=(i=this.filterManager.effectElements[0].p.v-1)+1,(e=createNS("g")).setAttribute("fill","none"),e.setAttribute("stroke-linecap","round"),e.setAttribute("stroke-dashoffset",1);i<r;i+=1)t=createNS("path"),e.appendChild(t),this.paths.push({p:t,m:i});if(3===this.filterManager.effectElements[10].p.v){var a=createNS("mask"),n=createElementID();a.setAttribute("id",n),a.setAttribute("mask-type","alpha"),a.appendChild(e),this.elem.globalData.defs.appendChild(a);var o=createNS("g");for(o.setAttribute("mask","url("+getLocationHref()+"#"+n+")");s[0];)o.appendChild(s[0]);this.elem.layerElement.appendChild(o),this.masker=a,e.setAttribute("stroke","#fff")}else if(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v){if(2===this.filterManager.effectElements[10].p.v)for(s=this.elem.layerElement.children||this.elem.layerElement.childNodes;s.length;)this.elem.layerElement.removeChild(s[0]);this.elem.layerElement.appendChild(e),this.elem.layerElement.removeAttribute("mask"),e.setAttribute("stroke","#fff")}this.initialized=!0,this.pathMasker=e},SVGStrokeEffect.prototype.renderFrame=function(t){var e;this.initialized||this.initialize();var i,r,s=this.paths.length;for(e=0;e<s;e+=1)if(-1!==this.paths[e].m&&(i=this.elem.maskManager.viewData[this.paths[e].m],r=this.paths[e].p,(t||this.filterManager._mdf||i.prop._mdf)&&r.setAttribute("d",i.lastPath),t||this.filterManager.effectElements[9].p._mdf||this.filterManager.effectElements[4].p._mdf||this.filterManager.effectElements[7].p._mdf||this.filterManager.effectElements[8].p._mdf||i.prop._mdf)){var a;if(0!==this.filterManager.effectElements[7].p.v||100!==this.filterManager.effectElements[8].p.v){var n=.01*Math.min(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),o=.01*Math.max(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),h=r.getTotalLength();a="0 0 0 "+h*n+" ";var l,p=h*(o-n),f=1+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01,m=Math.floor(p/f);for(l=0;l<m;l+=1)a+="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01+" ";a+="0 "+10*h+" 0 0"}else a="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01;r.setAttribute("stroke-dasharray",a)}if((t||this.filterManager.effectElements[4].p._mdf)&&this.pathMasker.setAttribute("stroke-width",2*this.filterManager.effectElements[4].p.v),(t||this.filterManager.effectElements[6].p._mdf)&&this.pathMasker.setAttribute("opacity",this.filterManager.effectElements[6].p.v),(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v)&&(t||this.filterManager.effectElements[3].p._mdf)){var c=this.filterManager.effectElements[3].p.v;this.pathMasker.setAttribute("stroke","rgb("+bmFloor(255*c[0])+","+bmFloor(255*c[1])+","+bmFloor(255*c[2])+")")}},SVGTritoneFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=this.filterManager.effectElements[2].p.v,s=r[0]+" "+i[0]+" "+e[0],a=r[1]+" "+i[1]+" "+e[1],n=r[2]+" "+i[2]+" "+e[2];this.feFuncR.setAttribute("tableValues",s),this.feFuncG.setAttribute("tableValues",a),this.feFuncB.setAttribute("tableValues",n)}},SVGProLevelsFilter.prototype.createFeFunc=function(t,e){var i=createNS(t);return i.setAttribute("type","table"),e.appendChild(i),i},SVGProLevelsFilter.prototype.getTableValue=function(t,e,i,r,s){for(var a,n,o=0,h=Math.min(t,e),l=Math.max(t,e),p=Array.call(null,{length:256}),f=0,m=s-r,c=e-t;o<=256;)n=(a=o/256)<=h?c<0?s:r:a>=l?c<0?r:s:r+m*Math.pow((a-t)/c,1/i),p[f]=n,f+=1,o+=256/255;return p.join(" ")},SVGProLevelsFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e,i=this.filterManager.effectElements;this.feFuncRComposed&&(t||i[3].p._mdf||i[4].p._mdf||i[5].p._mdf||i[6].p._mdf||i[7].p._mdf)&&(e=this.getTableValue(i[3].p.v,i[4].p.v,i[5].p.v,i[6].p.v,i[7].p.v),this.feFuncRComposed.setAttribute("tableValues",e),this.feFuncGComposed.setAttribute("tableValues",e),this.feFuncBComposed.setAttribute("tableValues",e)),this.feFuncR&&(t||i[10].p._mdf||i[11].p._mdf||i[12].p._mdf||i[13].p._mdf||i[14].p._mdf)&&(e=this.getTableValue(i[10].p.v,i[11].p.v,i[12].p.v,i[13].p.v,i[14].p.v),this.feFuncR.setAttribute("tableValues",e)),this.feFuncG&&(t||i[17].p._mdf||i[18].p._mdf||i[19].p._mdf||i[20].p._mdf||i[21].p._mdf)&&(e=this.getTableValue(i[17].p.v,i[18].p.v,i[19].p.v,i[20].p.v,i[21].p.v),this.feFuncG.setAttribute("tableValues",e)),this.feFuncB&&(t||i[24].p._mdf||i[25].p._mdf||i[26].p._mdf||i[27].p._mdf||i[28].p._mdf)&&(e=this.getTableValue(i[24].p.v,i[25].p.v,i[26].p.v,i[27].p.v,i[28].p.v),this.feFuncB.setAttribute("tableValues",e)),this.feFuncA&&(t||i[31].p._mdf||i[32].p._mdf||i[33].p._mdf||i[34].p._mdf||i[35].p._mdf)&&(e=this.getTableValue(i[31].p.v,i[32].p.v,i[33].p.v,i[34].p.v,i[35].p.v),this.feFuncA.setAttribute("tableValues",e))}},extendPrototype([SVGComposableEffect],SVGDropShadowEffect),SVGDropShadowEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){if((t||this.filterManager.effectElements[4].p._mdf)&&this.feGaussianBlur.setAttribute("stdDeviation",this.filterManager.effectElements[4].p.v/4),t||this.filterManager.effectElements[0].p._mdf){var e=this.filterManager.effectElements[0].p.v;this.feFlood.setAttribute("flood-color",rgbToHex(Math.round(255*e[0]),Math.round(255*e[1]),Math.round(255*e[2])))}if((t||this.filterManager.effectElements[1].p._mdf)&&this.feFlood.setAttribute("flood-opacity",this.filterManager.effectElements[1].p.v/255),t||this.filterManager.effectElements[2].p._mdf||this.filterManager.effectElements[3].p._mdf){var i=this.filterManager.effectElements[3].p.v,r=(this.filterManager.effectElements[2].p.v-90)*degToRads,s=i*Math.cos(r),a=i*Math.sin(r);this.feOffset.setAttribute("dx",s),this.feOffset.setAttribute("dy",a)}}};var _svgMatteSymbols=[];function SVGMatte3Effect(t,e,i){this.initialized=!1,this.filterManager=e,this.filterElem=t,this.elem=i,i.matteElement=createNS("g"),i.matteElement.appendChild(i.layerElement),i.matteElement.appendChild(i.transformedElement),i.baseElement=i.matteElement}function SVGGaussianBlurEffect(t,e,i,r){t.setAttribute("x","-100%"),t.setAttribute("y","-100%"),t.setAttribute("width","300%"),t.setAttribute("height","300%"),this.filterManager=e;var s=createNS("feGaussianBlur");s.setAttribute("result",r),t.appendChild(s),this.feGaussianBlur=s}function TransformEffect(){}function SVGTransformEffect(t,e){this.init(e)}function CVTransformEffect(t){this.init(t)}return SVGMatte3Effect.prototype.findSymbol=function(t){for(var e=0,i=_svgMatteSymbols.length;e<i;){if(_svgMatteSymbols[e]===t)return _svgMatteSymbols[e];e+=1}return null},SVGMatte3Effect.prototype.replaceInParent=function(t,e){var i=t.layerElement.parentNode;if(i){for(var r,s=i.children,a=0,n=s.length;a<n&&s[a]!==t.layerElement;)a+=1;a<=n-2&&(r=s[a+1]);var o=createNS("use");o.setAttribute("href","#"+e),r?i.insertBefore(o,r):i.appendChild(o)}},SVGMatte3Effect.prototype.setElementAsMask=function(t,e){if(!this.findSymbol(e)){var i=createElementID(),r=createNS("mask");r.setAttribute("id",e.layerId),r.setAttribute("mask-type","alpha"),_svgMatteSymbols.push(e);var s=t.globalData.defs;s.appendChild(r);var a=createNS("symbol");a.setAttribute("id",i),this.replaceInParent(e,i),a.appendChild(e.layerElement),s.appendChild(a);var n=createNS("use");n.setAttribute("href","#"+i),r.appendChild(n),e.data.hd=!1,e.show()}t.setMatte(e.layerId)},SVGMatte3Effect.prototype.initialize=function(){for(var t=this.filterManager.effectElements[0].p.v,e=this.elem.comp.elements,i=0,r=e.length;i<r;)e[i]&&e[i].data.ind===t&&this.setElementAsMask(this.elem,e[i]),i+=1;this.initialized=!0},SVGMatte3Effect.prototype.renderFrame=function(){this.initialized||this.initialize()},SVGGaussianBlurEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=.3*this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=3==i?0:e,s=2==i?0:e;this.feGaussianBlur.setAttribute("stdDeviation",r+" "+s);var a=1==this.filterManager.effectElements[2].p.v?"wrap":"duplicate";this.feGaussianBlur.setAttribute("edgeMode",a)}},TransformEffect.prototype.init=function(t){this.effectsManager=t,this.type=effectTypes.TRANSFORM_EFFECT,this.matrix=new Matrix,this.opacity=-1,this._mdf=!1,this._opMdf=!1},TransformEffect.prototype.renderFrame=function(t){if(this._opMdf=!1,this._mdf=!1,t||this.effectsManager._mdf){var e=this.effectsManager.effectElements,i=e[0].p.v,r=e[1].p.v,s=1===e[2].p.v,a=e[3].p.v,n=s?a:e[4].p.v,o=e[5].p.v,h=e[6].p.v,l=e[7].p.v;this.matrix.reset(),this.matrix.translate(-i[0],-i[1],i[2]),this.matrix.scale(.01*n,.01*a,1),this.matrix.rotate(-l*degToRads),this.matrix.skewFromAxis(-o*degToRads,(h+90)*degToRads),this.matrix.translate(r[0],r[1],0),this._mdf=!0,this.opacity!==e[8].p.v&&(this.opacity=e[8].p.v,this._opMdf=!0)}},extendPrototype([TransformEffect],SVGTransformEffect),extendPrototype([TransformEffect],CVTransformEffect),registerRenderer("canvas",CanvasRenderer),registerRenderer("html",HybridRenderer),registerRenderer("svg",SVGRenderer),ShapeModifiers.registerModifier("tm",TrimModifier),ShapeModifiers.registerModifier("pb",PuckerAndBloatModifier),ShapeModifiers.registerModifier("rp",RepeaterModifier),ShapeModifiers.registerModifier("rd",RoundCornersModifier),ShapeModifiers.registerModifier("zz",ZigZagModifier),ShapeModifiers.registerModifier("op",OffsetPathModifier),setExpressionsPlugin(Expressions),setExpressionInterfaces(getInterface),initialize$1(),initialize(),registerEffect$1(20,SVGTintFilter,!0),registerEffect$1(21,SVGFillFilter,!0),registerEffect$1(22,SVGStrokeEffect,!1),registerEffect$1(23,SVGTritoneFilter,!0),registerEffect$1(24,SVGProLevelsFilter,!0),registerEffect$1(25,SVGDropShadowEffect,!0),registerEffect$1(28,SVGMatte3Effect,!1),registerEffect$1(29,SVGGaussianBlurEffect,!0),registerEffect$1(35,SVGTransformEffect,!1),registerEffect(35,CVTransformEffect),lottie}));
diff --git a/build/player/lottie_canvas.js b/build/player/lottie_canvas.js
index 4a2deb7..9427156 100644
--- a/build/player/lottie_canvas.js
+++ b/build/player/lottie_canvas.js
@@ -1,4 +1,4 @@
-(typeof navigator !== "undefined") && (function (global, factory) {
+(typeof document !== "undefined") && (typeof navigator !== "undefined") && (function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
   typeof define === 'function' && define.amd ? define(factory) :
   (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lottie = factory());
@@ -8,19 +8,15 @@
   var locationHref = '';
   var _useWebWorker = false;
   var initialDefaultFrame = -999999;
-
   var setWebWorker = function setWebWorker(flag) {
     _useWebWorker = !!flag;
   };
-
   var getWebWorker = function getWebWorker() {
     return _useWebWorker;
   };
-
   var setLocationHref = function setLocationHref(value) {
     locationHref = value;
   };
-
   var getLocationHref = function getLocationHref() {
     return locationHref;
   };
@@ -34,28 +30,24 @@
     var i;
     var len = sources.length;
     var sourcePrototype;
-
     for (i = 0; i < len; i += 1) {
       sourcePrototype = sources[i].prototype;
-
       for (var attr in sourcePrototype) {
         if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
       }
     }
   }
-
   function getDescriptor(object, prop) {
     return Object.getOwnPropertyDescriptor(object, prop);
   }
-
   function createProxyFunction(prototype) {
     function ProxyFunction() {}
-
     ProxyFunction.prototype = prototype;
     return ProxyFunction;
   }
 
   // import Howl from '../../3rd_party/howler';
+
   var audioControllerFactory = function () {
     function AudioController(audioFactory) {
       this.audios = [];
@@ -63,7 +55,6 @@
       this._volume = 1;
       this._isMuted = false;
     }
-
     AudioController.prototype = {
       addAudio: function addAudio(audio) {
         this.audios.push(audio);
@@ -71,7 +62,6 @@
       pause: function pause() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].pause();
         }
@@ -79,7 +69,6 @@
       resume: function resume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].resume();
         }
@@ -87,7 +76,6 @@
       setRate: function setRate(rateValue) {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].setRate(rateValue);
         }
@@ -96,13 +84,11 @@
         if (this.audioFactory) {
           return this.audioFactory(assetPath);
         }
-
         if (window.Howl) {
           return new window.Howl({
             src: [assetPath]
           });
         }
-
         return {
           isPlaying: false,
           play: function play() {
@@ -121,17 +107,14 @@
       },
       setVolume: function setVolume(value) {
         this._volume = value;
-
         this._updateVolume();
       },
       mute: function mute() {
         this._isMuted = true;
-
         this._updateVolume();
       },
       unmute: function unmute() {
         this._isMuted = false;
-
         this._updateVolume();
       },
       getVolume: function getVolume() {
@@ -140,7 +123,6 @@
       _updateVolume: function _updateVolume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
         }
@@ -156,55 +138,44 @@
       var i = 0;
       var arr = [];
       var value;
-
       switch (type) {
         case 'int16':
         case 'uint8c':
           value = 1;
           break;
-
         default:
           value = 1.1;
           break;
       }
-
       for (i = 0; i < len; i += 1) {
         arr.push(value);
       }
-
       return arr;
     }
-
     function createTypedArrayFactory(type, len) {
       if (type === 'float32') {
         return new Float32Array(len);
       }
-
       if (type === 'int16') {
         return new Int16Array(len);
       }
-
       if (type === 'uint8c') {
         return new Uint8ClampedArray(len);
       }
-
       return createRegularArray(type, len);
     }
-
     if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
       return createTypedArrayFactory;
     }
-
     return createRegularArray;
   }();
-
   function createSizedArray(len) {
     return Array.apply(null, {
       length: len
     });
   }
 
-  function _typeof$6(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$6 = function _typeof(obj) { return typeof obj; }; } else { _typeof$6 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$6(obj); }
+  function _typeof$6(o) { "@babel/helpers - typeof"; return _typeof$6 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$6(o); }
   var subframeEnabled = true;
   var expressionsPlugin = null;
   var expressionsInterfaces = null;
@@ -217,57 +188,43 @@
   var bmMax = Math.max;
   var bmMin = Math.min;
   var BMMath = {};
-
   (function () {
     var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
     var i;
     var len = propertyNames.length;
-
     for (i = 0; i < len; i += 1) {
       BMMath[propertyNames[i]] = Math[propertyNames[i]];
     }
   })();
-
   function ProjectInterface$1() {
     return {};
   }
-
   BMMath.random = Math.random;
-
   BMMath.abs = function (val) {
     var tOfVal = _typeof$6(val);
-
     if (tOfVal === 'object' && val.length) {
       var absArr = createSizedArray(val.length);
       var i;
       var len = val.length;
-
       for (i = 0; i < len; i += 1) {
         absArr[i] = Math.abs(val[i]);
       }
-
       return absArr;
     }
-
     return Math.abs(val);
   };
-
   var defaultCurveSegments = 150;
   var degToRads = Math.PI / 180;
   var roundCorner = 0.5519;
-
   function roundValues(flag) {
     _shouldRoundValues = !!flag;
   }
-
   function bmRnd(value) {
     if (_shouldRoundValues) {
       return Math.round(value);
     }
-
     return value;
   }
-
   function styleDiv(element) {
     element.style.position = 'absolute';
     element.style.top = 0;
@@ -281,53 +238,44 @@
     element.style.webkitTransformStyle = 'preserve-3d';
     element.style.mozTransformStyle = 'preserve-3d';
   }
-
   function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
     this.type = type;
     this.currentTime = currentTime;
     this.totalTime = totalTime;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteEvent(type, frameMultiplier) {
     this.type = type;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
     this.type = type;
     this.currentLoop = currentLoop;
     this.totalLoops = totalLoops;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMSegmentStartEvent(type, firstFrame, totalFrames) {
     this.type = type;
     this.firstFrame = firstFrame;
     this.totalFrames = totalFrames;
   }
-
   function BMDestroyEvent(type, target) {
     this.type = type;
     this.target = target;
   }
-
   function BMRenderFrameErrorEvent(nativeError, currentTime) {
     this.type = 'renderFrameError';
     this.nativeError = nativeError;
     this.currentTime = currentTime;
   }
-
   function BMConfigErrorEvent(nativeError) {
     this.type = 'configError';
     this.nativeError = nativeError;
   }
-
   function BMAnimationConfigErrorEvent(type, nativeError) {
     this.type = type;
     this.nativeError = nativeError;
   }
-
   var createElementID = function () {
     var _count = 0;
     return function createID() {
@@ -335,7 +283,6 @@
       return idPrefix$1 + '__lottie_element_' + _count;
     };
   }();
-
   function HSVtoRGB(h, s, v) {
     var r;
     var g;
@@ -350,51 +297,42 @@
     p = v * (1 - s);
     q = v * (1 - f * s);
     t = v * (1 - (1 - f) * s);
-
     switch (i % 6) {
       case 0:
         r = v;
         g = t;
         b = p;
         break;
-
       case 1:
         r = q;
         g = v;
         b = p;
         break;
-
       case 2:
         r = p;
         g = v;
         b = t;
         break;
-
       case 3:
         r = p;
         g = q;
         b = v;
         break;
-
       case 4:
         r = t;
         g = p;
         b = v;
         break;
-
       case 5:
         r = v;
         g = p;
         b = q;
         break;
-
       default:
         break;
     }
-
     return [r, g, b];
   }
-
   function RGBtoHSV(r, g, b) {
     var max = Math.max(r, g, b);
     var min = Math.min(r, g, b);
@@ -402,136 +340,105 @@
     var h;
     var s = max === 0 ? 0 : d / max;
     var v = max / 255;
-
     switch (max) {
       case min:
         h = 0;
         break;
-
       case r:
         h = g - b + d * (g < b ? 6 : 0);
         h /= 6 * d;
         break;
-
       case g:
         h = b - r + d * 2;
         h /= 6 * d;
         break;
-
       case b:
         h = r - g + d * 4;
         h /= 6 * d;
         break;
-
       default:
         break;
     }
-
     return [h, s, v];
   }
-
   function addSaturationToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[1] += offset;
-
     if (hsv[1] > 1) {
       hsv[1] = 1;
     } else if (hsv[1] <= 0) {
       hsv[1] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addBrightnessToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[2] += offset;
-
     if (hsv[2] > 1) {
       hsv[2] = 1;
     } else if (hsv[2] < 0) {
       hsv[2] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addHueToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[0] += offset / 360;
-
     if (hsv[0] > 1) {
       hsv[0] -= 1;
     } else if (hsv[0] < 0) {
       hsv[0] += 1;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   var rgbToHex = function () {
     var colorMap = [];
     var i;
     var hex;
-
     for (i = 0; i < 256; i += 1) {
       hex = i.toString(16);
       colorMap[i] = hex.length === 1 ? '0' + hex : hex;
     }
-
     return function (r, g, b) {
       if (r < 0) {
         r = 0;
       }
-
       if (g < 0) {
         g = 0;
       }
-
       if (b < 0) {
         b = 0;
       }
-
       return '#' + colorMap[r] + colorMap[g] + colorMap[b];
     };
   }();
-
   var setSubframeEnabled = function setSubframeEnabled(flag) {
     subframeEnabled = !!flag;
   };
-
   var getSubframeEnabled = function getSubframeEnabled() {
     return subframeEnabled;
   };
-
   var setExpressionsPlugin = function setExpressionsPlugin(value) {
     expressionsPlugin = value;
   };
-
   var getExpressionsPlugin = function getExpressionsPlugin() {
     return expressionsPlugin;
   };
-
   var setExpressionInterfaces = function setExpressionInterfaces(value) {
     expressionsInterfaces = value;
   };
-
   var getExpressionInterfaces = function getExpressionInterfaces() {
     return expressionsInterfaces;
   };
-
   var setDefaultCurveSegments = function setDefaultCurveSegments(value) {
     defaultCurveSegments = value;
   };
-
   var getDefaultCurveSegments = function getDefaultCurveSegments() {
     return defaultCurveSegments;
   };
-
   var setIdPrefix = function setIdPrefix(value) {
     idPrefix$1 = value;
   };
-
   var getIdPrefix = function getIdPrefix() {
     return idPrefix$1;
   };
@@ -541,8 +448,7 @@
     return document.createElementNS(svgNS, type);
   }
 
-  function _typeof$5(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$5 = function _typeof(obj) { return typeof obj; }; } else { _typeof$5 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$5(obj); }
-
+  function _typeof$5(o) { "@babel/helpers - typeof"; return _typeof$5 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$5(o); }
   var dataManager = function () {
     var _counterId = 1;
     var processes = [];
@@ -563,21 +469,18 @@
         });
       }
     };
-
     function createWorker(fn) {
       if (window.Worker && window.Blob && getWebWorker()) {
         var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], {
           type: 'text/javascript'
-        }); // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
-
+        });
+        // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
         var url = URL.createObjectURL(blob);
         return new Worker(url);
       }
-
       workerFn = fn;
       return workerProxy;
     }
-
     function setupWorker() {
       if (!workerInstance) {
         workerInstance = createWorker(function workerStart(e) {
@@ -590,28 +493,22 @@
               var jLen;
               var k;
               var kLen;
-
               for (i = 0; i < len; i += 1) {
                 layerData = layers[i];
-
                 if ('ks' in layerData && !layerData.completed) {
                   layerData.completed = true;
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         convertPathsToAbsoluteValues(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) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
                           }
@@ -619,7 +516,6 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 0) {
                     layerData.layers = findCompLayers(layerData.refId, comps);
                     completeLayers(layerData.layers, comps);
@@ -631,16 +527,15 @@
                 }
               }
             }
-
             function completeChars(chars, assets) {
               if (chars) {
                 var i = 0;
                 var len = chars.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (chars[i].t === 1) {
                     // var compData = findComp(chars[i].data.refId, assets);
-                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets); // chars[i].data.ip = 0;
+                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                    // chars[i].data.ip = 0;
                     // chars[i].data.op = 99999;
                     // chars[i].data.st = 0;
                     // chars[i].data.sr = 1;
@@ -652,61 +547,48 @@
                     //   s: { k: [100, 100], a: 0 },
                     //   o: { k: 100, a: 0 },
                     // };
-
                     completeLayers(chars[i].data.layers, assets);
                   }
                 }
               }
             }
-
             function findComp(id, comps) {
               var i = 0;
               var len = comps.length;
-
               while (i < len) {
                 if (comps[i].id === id) {
                   return comps[i];
                 }
-
                 i += 1;
               }
-
               return null;
             }
-
             function findCompLayers(id, comps) {
               var comp = findComp(id, comps);
-
               if (comp) {
                 if (!comp.layers.__used) {
                   comp.layers.__used = true;
                   return comp.layers;
                 }
-
                 return JSON.parse(JSON.stringify(comp.layers));
               }
-
               return null;
             }
-
             function completeShapes(arr) {
               var i;
               var len = arr.length;
               var j;
               var jLen;
-
               for (i = len - 1; i >= 0; i -= 1) {
                 if (arr[i].ty === 'sh') {
                   if (arr[i].ks.k.i) {
                     convertPathsToAbsoluteValues(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) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
                       }
-
                       if (arr[i].ks.k[j].e) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
                       }
@@ -717,11 +599,9 @@
                 }
               }
             }
-
             function convertPathsToAbsoluteValues(path) {
               var i;
               var len = path.i.length;
-
               for (i = 0; i < len; i += 1) {
                 path.i[i][0] += path.v[i][0];
                 path.i[i][1] += path.v[i][1];
@@ -729,40 +609,30 @@
                 path.o[i][1] += path.v[i][1];
               }
             }
-
             function checkVersion(minimum, animVersionString) {
               var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
-
               if (minimum[0] > animVersion[0]) {
                 return true;
               }
-
               if (animVersion[0] > minimum[0]) {
                 return false;
               }
-
               if (minimum[1] > animVersion[1]) {
                 return true;
               }
-
               if (animVersion[1] > minimum[1]) {
                 return false;
               }
-
               if (minimum[2] > animVersion[2]) {
                 return true;
               }
-
               if (animVersion[2] > minimum[2]) {
                 return false;
               }
-
               return null;
             }
-
             var checkText = function () {
               var minimumVersion = [4, 4, 14];
-
               function updateTextLayer(textLayer) {
                 var documentData = textLayer.t.d;
                 textLayer.t.d = {
@@ -772,26 +642,21 @@
                   }]
                 };
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -801,17 +666,14 @@
                 }
               };
             }();
-
             var checkChars = function () {
               var minimumVersion = [4, 7, 99];
               return function (animationData) {
                 if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
                   var i;
                   var len = animationData.chars.length;
-
                   for (i = 0; i < len; i += 1) {
                     var charData = animationData.chars[i];
-
                     if (charData.data && charData.data.shapes) {
                       completeShapes(charData.data.shapes);
                       charData.data.ip = 0;
@@ -840,7 +702,6 @@
                           a: 0
                         }
                       };
-
                       if (!animationData.chars[i].t) {
                         charData.data.shapes.push({
                           ty: 'no'
@@ -882,27 +743,22 @@
                 }
               };
             }();
-
             var checkPathProperties = function () {
               var minimumVersion = [5, 7, 15];
-
               function updateTextLayer(textLayer) {
                 var pathData = textLayer.t.p;
-
                 if (typeof pathData.a === 'number') {
                   pathData.a = {
                     a: 0,
                     k: pathData.a
                   };
                 }
-
                 if (typeof pathData.p === 'number') {
                   pathData.p = {
                     a: 0,
                     k: pathData.p
                   };
                 }
-
                 if (typeof pathData.r === 'number') {
                   pathData.r = {
                     a: 0,
@@ -910,26 +766,21 @@
                   };
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -939,23 +790,19 @@
                 }
               };
             }();
-
             var checkColors = function () {
               var minimumVersion = [4, 1, 9];
-
               function iterateShapes(shapes) {
                 var i;
                 var len = shapes.length;
                 var j;
                 var jLen;
-
                 for (i = 0; i < len; i += 1) {
                   if (shapes[i].ty === 'gr') {
                     iterateShapes(shapes[i].it);
                   } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
                     if (shapes[i].c.k && shapes[i].c.k[0].i) {
                       jLen = shapes[i].c.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (shapes[i].c.k[j].s) {
                           shapes[i].c.k[j].s[0] /= 255;
@@ -963,7 +810,6 @@
                           shapes[i].c.k[j].s[2] /= 255;
                           shapes[i].c.k[j].s[3] /= 255;
                         }
-
                         if (shapes[i].c.k[j].e) {
                           shapes[i].c.k[j].e[0] /= 255;
                           shapes[i].c.k[j].e[1] /= 255;
@@ -980,26 +826,21 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 4) {
                     iterateShapes(layers[i].shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1009,28 +850,23 @@
                 }
               };
             }();
-
             var checkShapes = function () {
               var minimumVersion = [4, 4, 18];
-
               function completeClosingShapes(arr) {
                 var i;
                 var len = arr.length;
                 var j;
                 var jLen;
-
                 for (i = len - 1; i >= 0; i -= 1) {
                   if (arr[i].ty === 'sh') {
                     if (arr[i].ks.k.i) {
                       arr[i].ks.k.c = arr[i].closed;
                     } else {
                       jLen = arr[i].ks.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (arr[i].ks.k[j].s) {
                           arr[i].ks.k[j].s[0].c = arr[i].closed;
                         }
-
                         if (arr[i].ks.k[j].e) {
                           arr[i].ks.k[j].e[0].c = arr[i].closed;
                         }
@@ -1041,7 +877,6 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var layerData;
                 var i;
@@ -1050,25 +885,20 @@
                 var jLen;
                 var k;
                 var kLen;
-
                 for (i = 0; i < len; i += 1) {
                   layerData = layers[i];
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         maskProps[j].pt.k.c = maskProps[j].cl;
                       } else {
                         kLen = maskProps[j].pt.k.length;
-
                         for (k = 0; k < kLen; k += 1) {
                           if (maskProps[j].pt.k[k].s) {
                             maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
                           }
@@ -1076,21 +906,17 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 4) {
                     completeClosingShapes(layerData.shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1100,12 +926,10 @@
                 }
               };
             }();
-
             function completeData(animationData) {
               if (animationData.__complete) {
                 return;
               }
-
               checkColors(animationData);
               checkText(animationData);
               checkChars(animationData);
@@ -1115,12 +939,11 @@
               completeChars(animationData.chars, animationData.assets);
               animationData.__complete = true;
             }
-
             function completeText(data) {
-              if (data.t.a.length === 0 && !('m' in data.t.p)) {// data.singleShape = true;
+              if (data.t.a.length === 0 && !('m' in data.t.p)) {
+                // data.singleShape = true;
               }
             }
-
             var moduleOb = {};
             moduleOb.completeData = completeData;
             moduleOb.checkColors = checkColors;
@@ -1130,47 +953,37 @@
             moduleOb.completeLayers = completeLayers;
             return moduleOb;
           }
-
           if (!_workerSelf.dataManager) {
             _workerSelf.dataManager = dataFunctionManager();
           }
-
           if (!_workerSelf.assetLoader) {
             _workerSelf.assetLoader = function () {
               function formatResponse(xhr) {
                 // using typeof doubles the time of execution of this method,
                 // so if available, it's better to use the header to validate the type
                 var contentTypeHeader = xhr.getResponseHeader('content-type');
-
                 if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
                   return xhr.response;
                 }
-
                 if (xhr.response && _typeof$5(xhr.response) === 'object') {
                   return xhr.response;
                 }
-
                 if (xhr.response && typeof xhr.response === 'string') {
                   return JSON.parse(xhr.response);
                 }
-
                 if (xhr.responseText) {
                   return JSON.parse(xhr.responseText);
                 }
-
                 return null;
               }
-
               function loadAsset(path, fullPath, callback, errorCallback) {
                 var response;
-                var xhr = new XMLHttpRequest(); // set responseType after calling open or IE will break.
-
+                var xhr = new XMLHttpRequest();
+                // set responseType after calling open or IE will break.
                 try {
                   // This crashes on Android WebView prior to KitKat
                   xhr.responseType = 'json';
                 } catch (err) {} // eslint-disable-line no-empty
-
-
                 xhr.onreadystatechange = function () {
                   if (xhr.readyState === 4) {
                     if (xhr.status === 200) {
@@ -1188,7 +1001,6 @@
                     }
                   }
                 };
-
                 try {
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), path, true);
@@ -1196,20 +1008,16 @@
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
                 }
-
                 xhr.send();
               }
-
               return {
                 load: loadAsset
               };
             }();
           }
-
           if (e.data.type === 'loadAnimation') {
             _workerSelf.assetLoader.load(e.data.path, e.data.fullPath, function (data) {
               _workerSelf.dataManager.completeData(data);
-
               _workerSelf.postMessage({
                 id: e.data.id,
                 payload: data,
@@ -1223,9 +1031,7 @@
             });
           } else if (e.data.type === 'complete') {
             var animation = e.data.animation;
-
             _workerSelf.dataManager.completeData(animation);
-
             _workerSelf.postMessage({
               id: e.data.id,
               payload: animation,
@@ -1246,13 +1052,11 @@
             });
           }
         });
-
         workerInstance.onmessage = function (event) {
           var data = event.data;
           var id = data.id;
           var process = processes[id];
           processes[id] = null;
-
           if (data.status === 'success') {
             process.onComplete(data.payload);
           } else if (process.onError) {
@@ -1261,7 +1065,6 @@
         };
       }
     }
-
     function createProcess(onComplete, onError) {
       _counterId += 1;
       var id = 'processId_' + _counterId;
@@ -1271,7 +1074,6 @@
       };
       return id;
     }
-
     function loadAnimation(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1282,7 +1084,6 @@
         id: processId
       });
     }
-
     function loadData(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1293,7 +1094,6 @@
         id: processId
       });
     }
-
     function completeAnimation(anim, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1303,7 +1103,6 @@
         id: processId
       });
     }
-
     return {
       loadAnimation: loadAnimation,
       loadData: loadData,
@@ -1321,94 +1120,74 @@
       ctx.fillRect(0, 0, 1, 1);
       return canvas;
     }();
-
     function imageLoaded() {
       this.loadedAssets += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function footageLoaded() {
       this.loadedFootagesCount += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function getAssetsPath(assetData, assetsPath, originalPath) {
       var path = '';
-
       if (assetData.e) {
         path = assetData.p;
       } else if (assetsPath) {
         var imagePath = assetData.p;
-
         if (imagePath.indexOf('images/') !== -1) {
           imagePath = imagePath.split('/')[1];
         }
-
         path = assetsPath + imagePath;
       } else {
         path = originalPath;
         path += assetData.u ? assetData.u : '';
         path += assetData.p;
       }
-
       return path;
     }
-
     function testImageLoaded(img) {
       var _count = 0;
       var intervalId = setInterval(function () {
         var box = img.getBBox();
-
         if (box.width || _count > 500) {
           this._imageLoaded();
-
           clearInterval(intervalId);
         }
-
         _count += 1;
       }.bind(this), 50);
     }
-
     function createImageData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createNS('image');
-
       if (isSafari) {
         this.testImageLoaded(img);
       } else {
         img.addEventListener('load', this._imageLoaded, false);
       }
-
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
-
       if (this._elementHelper.append) {
         this._elementHelper.append(img);
       } else {
         this._elementHelper.appendChild(img);
       }
-
       var ob = {
         img: img,
         assetData: assetData
       };
       return ob;
     }
-
     function createImgData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createTag('img');
@@ -1416,7 +1195,6 @@
       img.addEventListener('load', this._imageLoaded, false);
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.src = path;
@@ -1426,7 +1204,6 @@
       };
       return ob;
     }
-
     function createFootageData(data) {
       var ob = {
         assetData: data
@@ -1434,21 +1211,17 @@
       var path = getAssetsPath(data, this.assetsPath, this.path);
       dataManager.loadData(path, function (footageData) {
         ob.img = footageData;
-
         this._footageLoaded();
       }.bind(this), function () {
         ob.img = {};
-
         this._footageLoaded();
       }.bind(this));
       return ob;
     }
-
     function loadAssets(assets, cb) {
       this.imagesLoadedCb = cb;
       var i;
       var len = assets.length;
-
       for (i = 0; i < len; i += 1) {
         if (!assets[i].layers) {
           if (!assets[i].t || assets[i].t === 'seq') {
@@ -1461,43 +1234,33 @@
         }
       }
     }
-
     function setPath(path) {
       this.path = path || '';
     }
-
     function setAssetsPath(path) {
       this.assetsPath = path || '';
     }
-
     function getAsset(assetData) {
       var i = 0;
       var len = this.images.length;
-
       while (i < len) {
         if (this.images[i].assetData === assetData) {
           return this.images[i].img;
         }
-
         i += 1;
       }
-
       return null;
     }
-
     function destroy() {
       this.imagesLoadedCb = null;
       this.images.length = 0;
     }
-
     function loadedImages() {
       return this.totalImages === this.loadedAssets;
     }
-
     function loadedFootages() {
       return this.totalFootages === this.loadedFootagesCount;
     }
-
     function setCacheType(type, elementHelper) {
       if (type === 'svg') {
         this._elementHelper = elementHelper;
@@ -1506,7 +1269,6 @@
         this._createImageData = this.createImgData.bind(this);
       }
     }
-
     function ImagePreloaderFactory() {
       this._imageLoaded = imageLoaded.bind(this);
       this._footageLoaded = footageLoaded.bind(this);
@@ -1521,7 +1283,6 @@
       this.imagesLoadedCb = null;
       this.images = [];
     }
-
     ImagePreloaderFactory.prototype = {
       loadAssets: loadAssets,
       setAssetsPath: setAssetsPath,
@@ -1540,12 +1301,10 @@
   }();
 
   function BaseEvent() {}
-
   BaseEvent.prototype = {
     triggerEvent: function triggerEvent(eventName, args) {
       if (this._cbs[eventName]) {
         var callbacks = this._cbs[eventName];
-
         for (var i = 0; i < callbacks.length; i += 1) {
           callbacks[i](args);
         }
@@ -1555,9 +1314,7 @@
       if (!this._cbs[eventName]) {
         this._cbs[eventName] = [];
       }
-
       this._cbs[eventName].push(callback);
-
       return function () {
         this.removeEventListener(eventName, callback);
       }.bind(this);
@@ -1568,18 +1325,14 @@
       } else if (this._cbs[eventName]) {
         var i = 0;
         var len = this._cbs[eventName].length;
-
         while (i < len) {
           if (this._cbs[eventName][i] === callback) {
             this._cbs[eventName].splice(i, 1);
-
             i -= 1;
             len -= 1;
           }
-
           i += 1;
         }
-
         if (!this._cbs[eventName].length) {
           this._cbs[eventName] = null;
         }
@@ -1593,33 +1346,26 @@
       var keys = {};
       var line;
       var keysCount = 0;
-
       for (var i = 0; i < lines.length; i += 1) {
         line = lines[i].split(':');
-
         if (line.length === 2) {
           keys[line[0]] = line[1].trim();
           keysCount += 1;
         }
       }
-
       if (keysCount === 0) {
         throw new Error();
       }
-
       return keys;
     }
-
     return function (_markers) {
       var markers = [];
-
       for (var i = 0; i < _markers.length; i += 1) {
         var _marker = _markers[i];
         var markerData = {
           time: _marker.tm,
           duration: _marker.dr
         };
-
         try {
           markerData.payload = JSON.parse(_markers[i].cm);
         } catch (_) {
@@ -1631,10 +1377,8 @@
             };
           }
         }
-
         markers.push(markerData);
       }
-
       return markers;
     };
   }();
@@ -1643,27 +1387,21 @@
     function registerComposition(comp) {
       this.compositions.push(comp);
     }
-
     return function () {
       function _thisProjectFunction(name) {
         var i = 0;
         var len = this.compositions.length;
-
         while (i < len) {
           if (this.compositions[i].data && this.compositions[i].data.nm === name) {
             if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
               this.compositions[i].prepareFrame(this.currentFrame);
             }
-
             return this.compositions[i].compInterface;
           }
-
           i += 1;
         }
-
         return null;
       }
-
       _thisProjectFunction.compositions = [];
       _thisProjectFunction.currentFrame = 0;
       _thisProjectFunction.registerComposition = registerComposition;
@@ -1672,33 +1410,27 @@
   }();
 
   var renderers = {};
-
   var registerRenderer = function registerRenderer(key, value) {
     renderers[key] = value;
   };
-
   function getRenderer(key) {
     return renderers[key];
   }
-
   function getRegisteredRenderer() {
     // Returns canvas by default for compatibility
     if (renderers.canvas) {
       return 'canvas';
-    } // Returns any renderer that is registered
-
-
+    }
+    // Returns any renderer that is registered
     for (var key in renderers) {
       if (renderers[key]) {
         return key;
       }
     }
-
     return '';
   }
 
-  function _typeof$4(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$4 = function _typeof(obj) { return typeof obj; }; } else { _typeof$4 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$4(obj); }
-
+  function _typeof$4(o) { "@babel/helpers - typeof"; return _typeof$4 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$4(o); }
   var AnimationItem = function AnimationItem() {
     this._cbs = [];
     this.name = '';
@@ -1737,28 +1469,22 @@
     this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
     this.expressionsPlugin = getExpressionsPlugin();
   };
-
   extendPrototype([BaseEvent], AnimationItem);
-
   AnimationItem.prototype.setParams = function (params) {
     if (params.wrapper || params.container) {
       this.wrapper = params.wrapper || params.container;
     }
-
     var animType = 'svg';
-
     if (params.animType) {
       animType = params.animType;
     } else if (params.renderer) {
       animType = params.renderer;
     }
-
     var RendererClass = getRenderer(animType);
     this.renderer = new RendererClass(this, params.rendererSettings);
     this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
     this.renderer.setProjectInterface(this.projectInterface);
     this.animType = animType;
-
     if (params.loop === '' || params.loop === null || params.loop === undefined || params.loop === true) {
       this.loop = true;
     } else if (params.loop === false) {
@@ -1766,17 +1492,14 @@
     } else {
       this.loop = parseInt(params.loop, 10);
     }
-
     this.autoplay = 'autoplay' in params ? params.autoplay : true;
     this.name = params.name ? params.name : '';
     this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
     this.assetsPath = params.assetsPath;
     this.initialSegment = params.initialSegment;
-
     if (params.audioFactory) {
       this.audioController.setAudioFactory(params.audioFactory);
     }
-
     if (params.animationData) {
       this.setupAnimation(params.animationData);
     } else if (params.path) {
@@ -1785,28 +1508,23 @@
       } else {
         this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
       }
-
       this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
       this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
       dataManager.loadAnimation(params.path, this.configAnimation, this.onSetupError);
     }
   };
-
   AnimationItem.prototype.onSetupError = function () {
     this.trigger('data_failed');
   };
-
   AnimationItem.prototype.setupAnimation = function (data) {
     dataManager.completeAnimation(data, this.configAnimation);
   };
-
   AnimationItem.prototype.setData = function (wrapper, animationData) {
     if (animationData) {
       if (_typeof$4(animationData) !== 'object') {
         animationData = JSON.parse(animationData);
       }
     }
-
     var params = {
       wrapper: wrapper,
       animationData: animationData
@@ -1823,7 +1541,6 @@
     var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-loop').value : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-loop').value : wrapperAttributes.getNamedItem('bm-loop') ? wrapperAttributes.getNamedItem('bm-loop').value : '';
-
     if (loop === 'false') {
       params.loop = false;
     } else if (loop === 'true') {
@@ -1831,7 +1548,6 @@
     } else if (loop !== '') {
       params.loop = parseInt(loop, 10);
     }
-
     var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-autoplay').value : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-autoplay').value : wrapperAttributes.getNamedItem('bm-autoplay') ? wrapperAttributes.getNamedItem('bm-autoplay').value : true;
@@ -1842,81 +1558,64 @@
     var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-prerender').value : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-prerender').value : wrapperAttributes.getNamedItem('bm-prerender') ? wrapperAttributes.getNamedItem('bm-prerender').value : '';
-
     if (prerender === 'false') {
       params.prerender = false;
     }
-
     if (!params.path) {
       this.trigger('destroy');
     } else {
       this.setParams(params);
     }
   };
-
   AnimationItem.prototype.includeLayers = function (data) {
     if (data.op > this.animationData.op) {
       this.animationData.op = data.op;
       this.totalFrames = Math.floor(data.op - this.animationData.ip);
     }
-
     var layers = this.animationData.layers;
     var i;
     var len = layers.length;
     var newLayers = data.layers;
     var j;
     var jLen = newLayers.length;
-
     for (j = 0; j < jLen; j += 1) {
       i = 0;
-
       while (i < len) {
         if (layers[i].id === newLayers[j].id) {
           layers[i] = newLayers[j];
           break;
         }
-
         i += 1;
       }
     }
-
     if (data.chars || data.fonts) {
       this.renderer.globalData.fontManager.addChars(data.chars);
       this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
     }
-
     if (data.assets) {
       len = data.assets.length;
-
       for (i = 0; i < len; i += 1) {
         this.animationData.assets.push(data.assets[i]);
       }
     }
-
     this.animationData.__complete = false;
     dataManager.completeAnimation(this.animationData, this.onSegmentComplete);
   };
-
   AnimationItem.prototype.onSegmentComplete = function (data) {
     this.animationData = data;
     var expressionsPlugin = getExpressionsPlugin();
-
     if (expressionsPlugin) {
       expressionsPlugin.initExpressions(this);
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.loadNextSegment = function () {
     var segments = this.animationData.segments;
-
     if (!segments || segments.length === 0 || !this.autoloadSegments) {
       this.trigger('data_ready');
       this.timeCompleted = this.totalFrames;
       return;
     }
-
     var segment = segments.shift();
     this.timeCompleted = segment.time * this.frameRate;
     var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
@@ -1925,36 +1624,28 @@
       this.trigger('data_failed');
     }.bind(this));
   };
-
   AnimationItem.prototype.loadSegments = function () {
     var segments = this.animationData.segments;
-
     if (!segments) {
       this.timeCompleted = this.totalFrames;
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.imagesLoaded = function () {
     this.trigger('loaded_images');
     this.checkLoaded();
   };
-
   AnimationItem.prototype.preloadImages = function () {
     this.imagePreloader.setAssetsPath(this.assetsPath);
     this.imagePreloader.setPath(this.path);
     this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
   };
-
   AnimationItem.prototype.configAnimation = function (animData) {
     if (!this.renderer) {
       return;
     }
-
     try {
       this.animationData = animData;
-
       if (this.initialSegment) {
         this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
         this.firstFrame = Math.round(this.initialSegment[0]);
@@ -1962,13 +1653,10 @@
         this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
         this.firstFrame = Math.round(this.animationData.ip);
       }
-
       this.renderer.configAnimation(animData);
-
       if (!animData.assets) {
         animData.assets = [];
       }
-
       this.assets = this.animationData.assets;
       this.frameRate = this.animationData.fr;
       this.frameMult = this.animationData.fr / 1000;
@@ -1979,7 +1667,6 @@
       this.loadSegments();
       this.updaFrameModifier();
       this.waitForFontsLoaded();
-
       if (this.isPaused) {
         this.audioController.pause();
       }
@@ -1987,103 +1674,83 @@
       this.triggerConfigError(error);
     }
   };
-
   AnimationItem.prototype.waitForFontsLoaded = function () {
     if (!this.renderer) {
       return;
     }
-
     if (this.renderer.globalData.fontManager.isLoaded) {
       this.checkLoaded();
     } else {
       setTimeout(this.waitForFontsLoaded.bind(this), 20);
     }
   };
-
   AnimationItem.prototype.checkLoaded = function () {
     if (!this.isLoaded && this.renderer.globalData.fontManager.isLoaded && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas') && this.imagePreloader.loadedFootages()) {
       this.isLoaded = true;
       var expressionsPlugin = getExpressionsPlugin();
-
       if (expressionsPlugin) {
         expressionsPlugin.initExpressions(this);
       }
-
       this.renderer.initItems();
       setTimeout(function () {
         this.trigger('DOMLoaded');
       }.bind(this), 0);
       this.gotoFrame();
-
       if (this.autoplay) {
         this.play();
       }
     }
   };
-
   AnimationItem.prototype.resize = function (width, height) {
     // Adding this validation for backwards compatibility in case an event object was being passed down
     var _width = typeof width === 'number' ? width : undefined;
-
     var _height = typeof height === 'number' ? height : undefined;
-
     this.renderer.updateContainerSize(_width, _height);
   };
-
   AnimationItem.prototype.setSubframe = function (flag) {
     this.isSubframeEnabled = !!flag;
   };
-
   AnimationItem.prototype.gotoFrame = function () {
     this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
 
     if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
       this.currentFrame = this.timeCompleted;
     }
-
     this.trigger('enterFrame');
     this.renderFrame();
     this.trigger('drawnFrame');
   };
-
   AnimationItem.prototype.renderFrame = function () {
     if (this.isLoaded === false || !this.renderer) {
       return;
     }
-
     try {
       if (this.expressionsPlugin) {
         this.expressionsPlugin.resetFrame();
       }
-
       this.renderer.renderFrame(this.currentFrame + this.firstFrame);
     } catch (error) {
       this.triggerRenderFrameError(error);
     }
   };
-
   AnimationItem.prototype.play = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.isPaused = false;
       this.trigger('_play');
       this.audioController.resume();
-
       if (this._idle) {
         this._idle = false;
         this.trigger('_active');
       }
     }
   };
-
   AnimationItem.prototype.pause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === false) {
       this.isPaused = true;
       this.trigger('_pause');
@@ -2092,54 +1759,42 @@
       this.audioController.pause();
     }
   };
-
   AnimationItem.prototype.togglePause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.play();
     } else {
       this.pause();
     }
   };
-
   AnimationItem.prototype.stop = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.pause();
     this.playCount = 0;
     this._completedLoop = false;
     this.setCurrentRawFrameValue(0);
   };
-
   AnimationItem.prototype.getMarkerData = function (markerName) {
     var marker;
-
     for (var i = 0; i < this.markers.length; i += 1) {
       marker = this.markers[i];
-
       if (marker.payload && marker.payload.name === markerName) {
         return marker;
       }
     }
-
     return null;
   };
-
   AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         this.goToAndStop(marker.time, true);
       }
@@ -2148,20 +1803,15 @@
     } else {
       this.setCurrentRawFrameValue(value * this.frameModifier);
     }
-
     this.pause();
   };
-
   AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         if (!marker.duration) {
           this.goToAndStop(marker.time, true);
@@ -2172,19 +1822,16 @@
     } else {
       this.goToAndStop(numValue, isFrame, name);
     }
-
     this.play();
   };
-
   AnimationItem.prototype.advanceTime = function (value) {
     if (this.isPaused === true || this.isLoaded === false) {
       return;
     }
-
     var nextValue = this.currentRawFrame + value * this.frameModifier;
-    var _isComplete = false; // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+    var _isComplete = false;
+    // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
     // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
-
     if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
       if (!this.loop || this.playCount === this.loop) {
         if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
@@ -2193,7 +1840,6 @@
         }
       } else if (nextValue >= this.totalFrames) {
         this.playCount += 1;
-
         if (!this.checkSegments(nextValue % this.totalFrames)) {
           this.setCurrentRawFrameValue(nextValue % this.totalFrames);
           this._completedLoop = true;
@@ -2207,7 +1853,6 @@
         if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) {
           // eslint-disable-line no-plusplus
           this.setCurrentRawFrameValue(this.totalFrames + nextValue % this.totalFrames);
-
           if (!this._completedLoop) {
             this._completedLoop = true;
           } else {
@@ -2221,17 +1866,14 @@
     } else {
       this.setCurrentRawFrameValue(nextValue);
     }
-
     if (_isComplete) {
       this.setCurrentRawFrameValue(nextValue);
       this.pause();
       this.trigger('complete');
     }
   };
-
   AnimationItem.prototype.adjustSegment = function (arr, offset) {
     this.playCount = 0;
-
     if (arr[1] < arr[0]) {
       if (this.frameModifier > 0) {
         if (this.playSpeed < 0) {
@@ -2240,7 +1882,6 @@
           this.setDirection(-1);
         }
       }
-
       this.totalFrames = arr[0] - arr[1];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[1];
@@ -2253,19 +1894,15 @@
           this.setDirection(1);
         }
       }
-
       this.totalFrames = arr[1] - arr[0];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[0];
       this.setCurrentRawFrameValue(0.001 + offset);
     }
-
     this.trigger('segmentStart');
   };
-
   AnimationItem.prototype.setSegment = function (init, end) {
     var pendingFrame = -1;
-
     if (this.isPaused) {
       if (this.currentRawFrame + this.firstFrame < init) {
         pendingFrame = init;
@@ -2273,64 +1910,51 @@
         pendingFrame = end - init;
       }
     }
-
     this.firstFrame = init;
     this.totalFrames = end - init;
     this.timeCompleted = this.totalFrames;
-
     if (pendingFrame !== -1) {
       this.goToAndStop(pendingFrame, true);
     }
   };
-
   AnimationItem.prototype.playSegments = function (arr, forceFlag) {
     if (forceFlag) {
       this.segments.length = 0;
     }
-
     if (_typeof$4(arr[0]) === 'object') {
       var i;
       var len = arr.length;
-
       for (i = 0; i < len; i += 1) {
         this.segments.push(arr[i]);
       }
     } else {
       this.segments.push(arr);
     }
-
     if (this.segments.length && forceFlag) {
       this.adjustSegment(this.segments.shift(), 0);
     }
-
     if (this.isPaused) {
       this.play();
     }
   };
-
   AnimationItem.prototype.resetSegments = function (forceFlag) {
     this.segments.length = 0;
     this.segments.push([this.animationData.ip, this.animationData.op]);
-
     if (forceFlag) {
       this.checkSegments(0);
     }
   };
-
   AnimationItem.prototype.checkSegments = function (offset) {
     if (this.segments.length) {
       this.adjustSegment(this.segments.shift(), offset);
       return true;
     }
-
     return false;
   };
-
   AnimationItem.prototype.destroy = function (name) {
     if (name && this.name !== name || !this.renderer) {
       return;
     }
-
     this.renderer.destroy();
     this.imagePreloader.destroy();
     this.trigger('destroy');
@@ -2345,189 +1969,148 @@
     this.imagePreloader = null;
     this.projectInterface = null;
   };
-
   AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
     this.currentRawFrame = value;
     this.gotoFrame();
   };
-
   AnimationItem.prototype.setSpeed = function (val) {
     this.playSpeed = val;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setDirection = function (val) {
     this.playDirection = val < 0 ? -1 : 1;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setLoop = function (isLooping) {
     this.loop = isLooping;
   };
-
   AnimationItem.prototype.setVolume = function (val, name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.setVolume(val);
   };
-
   AnimationItem.prototype.getVolume = function () {
     return this.audioController.getVolume();
   };
-
   AnimationItem.prototype.mute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.mute();
   };
-
   AnimationItem.prototype.unmute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.unmute();
   };
-
   AnimationItem.prototype.updaFrameModifier = function () {
     this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
     this.audioController.setRate(this.playSpeed * this.playDirection);
   };
-
   AnimationItem.prototype.getPath = function () {
     return this.path;
   };
-
   AnimationItem.prototype.getAssetsPath = function (assetData) {
     var path = '';
-
     if (assetData.e) {
       path = assetData.p;
     } else if (this.assetsPath) {
       var imagePath = assetData.p;
-
       if (imagePath.indexOf('images/') !== -1) {
         imagePath = imagePath.split('/')[1];
       }
-
       path = this.assetsPath + imagePath;
     } else {
       path = this.path;
       path += assetData.u ? assetData.u : '';
       path += assetData.p;
     }
-
     return path;
   };
-
   AnimationItem.prototype.getAssetData = function (id) {
     var i = 0;
     var len = this.assets.length;
-
     while (i < len) {
       if (id === this.assets[i].id) {
         return this.assets[i];
       }
-
       i += 1;
     }
-
     return null;
   };
-
   AnimationItem.prototype.hide = function () {
     this.renderer.hide();
   };
-
   AnimationItem.prototype.show = function () {
     this.renderer.show();
   };
-
   AnimationItem.prototype.getDuration = function (isFrame) {
     return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
   };
-
   AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
     try {
       var element = this.renderer.getElementByPath(path);
       element.updateDocumentData(documentData, index);
-    } catch (error) {// TODO: decide how to handle catch case
+    } catch (error) {
+      // TODO: decide how to handle catch case
     }
   };
-
   AnimationItem.prototype.trigger = function (name) {
     if (this._cbs && this._cbs[name]) {
       switch (name) {
         case 'enterFrame':
           this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
           break;
-
         case 'drawnFrame':
           this.drawnFrameEvent.currentTime = this.currentFrame;
           this.drawnFrameEvent.totalTime = this.totalFrames;
           this.drawnFrameEvent.direction = this.frameModifier;
           this.triggerEvent(name, this.drawnFrameEvent);
           break;
-
         case 'loopComplete':
           this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
           break;
-
         case 'complete':
           this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
           break;
-
         case 'segmentStart':
           this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
           break;
-
         case 'destroy':
           this.triggerEvent(name, new BMDestroyEvent(name, this));
           break;
-
         default:
           this.triggerEvent(name);
       }
     }
-
     if (name === 'enterFrame' && this.onEnterFrame) {
       this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
     }
-
     if (name === 'loopComplete' && this.onLoopComplete) {
       this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
     }
-
     if (name === 'complete' && this.onComplete) {
       this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
     }
-
     if (name === 'segmentStart' && this.onSegmentStart) {
       this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
     }
-
     if (name === 'destroy' && this.onDestroy) {
       this.onDestroy.call(this, new BMDestroyEvent(name, this));
     }
   };
-
   AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
     var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
   };
-
   AnimationItem.prototype.triggerConfigError = function (nativeError) {
     var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
@@ -2541,68 +2124,53 @@
     var playingAnimationsNum = 0;
     var _stopped = true;
     var _isFrozen = false;
-
     function removeElement(ev) {
       var i = 0;
       var animItem = ev.target;
-
       while (i < len) {
         if (registeredAnimations[i].animation === animItem) {
           registeredAnimations.splice(i, 1);
           i -= 1;
           len -= 1;
-
           if (!animItem.isPaused) {
             subtractPlayingCount();
           }
         }
-
         i += 1;
       }
     }
-
     function registerAnimation(element, animationData) {
       if (!element) {
         return null;
       }
-
       var i = 0;
-
       while (i < len) {
         if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
           return registeredAnimations[i].animation;
         }
-
         i += 1;
       }
-
       var animItem = new AnimationItem();
       setupAnimation(animItem, element);
       animItem.setData(element, animationData);
       return animItem;
     }
-
     function getRegisteredAnimations() {
       var i;
       var lenAnims = registeredAnimations.length;
       var animations = [];
-
       for (i = 0; i < lenAnims; i += 1) {
         animations.push(registeredAnimations[i].animation);
       }
-
       return animations;
     }
-
     function addPlayingCount() {
       playingAnimationsNum += 1;
       activate();
     }
-
     function subtractPlayingCount() {
       playingAnimationsNum -= 1;
     }
-
     function setupAnimation(animItem, element) {
       animItem.addEventListener('destroy', removeElement);
       animItem.addEventListener('_active', addPlayingCount);
@@ -2613,118 +2181,91 @@
       });
       len += 1;
     }
-
     function loadAnimation(params) {
       var animItem = new AnimationItem();
       setupAnimation(animItem, null);
       animItem.setParams(params);
       return animItem;
     }
-
     function setSpeed(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setSpeed(val, animation);
       }
     }
-
     function setDirection(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setDirection(val, animation);
       }
     }
-
     function play(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.play(animation);
       }
     }
-
     function resume(nowTime) {
       var elapsedTime = nowTime - initTime;
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.advanceTime(elapsedTime);
       }
-
       initTime = nowTime;
-
       if (playingAnimationsNum && !_isFrozen) {
         window.requestAnimationFrame(resume);
       } else {
         _stopped = true;
       }
     }
-
     function first(nowTime) {
       initTime = nowTime;
       window.requestAnimationFrame(resume);
     }
-
     function pause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.pause(animation);
       }
     }
-
     function goToAndStop(value, isFrame, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
       }
     }
-
     function stop(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.stop(animation);
       }
     }
-
     function togglePause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.togglePause(animation);
       }
     }
-
     function destroy(animation) {
       var i;
-
       for (i = len - 1; i >= 0; i -= 1) {
         registeredAnimations[i].animation.destroy(animation);
       }
     }
-
     function searchAnimations(animationData, standalone, renderer) {
       var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')), [].slice.call(document.getElementsByClassName('bodymovin')));
       var i;
       var lenAnims = animElements.length;
-
       for (i = 0; i < lenAnims; i += 1) {
         if (renderer) {
           animElements[i].setAttribute('data-bm-type', renderer);
         }
-
         registerAnimation(animElements[i], animationData);
       }
-
       if (standalone && lenAnims === 0) {
         if (!renderer) {
           renderer = 'svg';
         }
-
         var body = document.getElementsByTagName('body')[0];
         body.innerText = '';
         var div = createTag('div');
@@ -2735,15 +2276,12 @@
         registerAnimation(div, animationData);
       }
     }
-
     function resize() {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.resize();
       }
     }
-
     function activate() {
       if (!_isFrozen && playingAnimationsNum) {
         if (_stopped) {
@@ -2752,40 +2290,31 @@
         }
       }
     }
-
     function freeze() {
       _isFrozen = true;
     }
-
     function unfreeze() {
       _isFrozen = false;
       activate();
     }
-
     function setVolume(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setVolume(val, animation);
       }
     }
-
     function mute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.mute(animation);
       }
     }
-
     function unmute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.unmute(animation);
       }
     }
-
     moduleOb.registerAnimation = registerAnimation;
     moduleOb.loadAnimation = loadAnimation;
     moduleOb.setSpeed = setSpeed;
@@ -2795,8 +2324,8 @@
     moduleOb.stop = stop;
     moduleOb.togglePause = togglePause;
     moduleOb.searchAnimations = searchAnimations;
-    moduleOb.resize = resize; // moduleOb.start = start;
-
+    moduleOb.resize = resize;
+    // moduleOb.start = start;
     moduleOb.goToAndStop = goToAndStop;
     moduleOb.destroy = destroy;
     moduleOb.freeze = freeze;
@@ -2820,23 +2349,21 @@
        * spline.get(x) => returns the easing value | x must be in [0, 1] range
        *
        */
+
     var ob = {};
     ob.getBezierEasing = getBezierEasing;
     var beziers = {};
-
     function getBezierEasing(a, b, c, d, nm) {
       var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
-
       if (beziers[str]) {
         return beziers[str];
       }
-
       var bezEasing = new BezierEasing([a, b, c, d]);
       beziers[str] = bezEasing;
       return bezEasing;
-    } // These values are established by empiricism with tests (tradeoff: performance VS precision)
+    }
 
-
+    // These values are established by empiricism with tests (tradeoff: performance VS precision)
     var NEWTON_ITERATIONS = 4;
     var NEWTON_MIN_SLOPE = 0.001;
     var SUBDIVISION_PRECISION = 0.0000001;
@@ -2844,48 +2371,40 @@
     var kSplineTableSize = 11;
     var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
     var float32ArraySupported = typeof Float32Array === 'function';
-
     function A(aA1, aA2) {
       return 1.0 - 3.0 * aA2 + 3.0 * aA1;
     }
-
     function B(aA1, aA2) {
       return 3.0 * aA2 - 6.0 * aA1;
     }
-
     function C(aA1) {
       return 3.0 * aA1;
-    } // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+    }
 
-
+    // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
     function calcBezier(aT, aA1, aA2) {
       return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
-    } // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+    }
 
-
+    // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
     function getSlope(aT, aA1, aA2) {
       return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
     }
-
     function binarySubdivide(aX, aA, aB, mX1, mX2) {
       var currentX,
-          currentT,
-          i = 0;
-
+        currentT,
+        i = 0;
       do {
         currentT = aA + (aB - aA) / 2.0;
         currentX = calcBezier(currentT, mX1, mX2) - aX;
-
         if (currentX > 0.0) {
           aB = currentT;
         } else {
           aA = currentT;
         }
       } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
-
       return currentT;
     }
-
     function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
       for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
         var currentSlope = getSlope(aGuessT, mX1, mX2);
@@ -2893,85 +2412,75 @@
         var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
         aGuessT -= currentX / currentSlope;
       }
-
       return aGuessT;
     }
+
     /**
        * points is an array of [ mX1, mY1, mX2, mY2 ]
        */
-
-
     function BezierEasing(points) {
       this._p = points;
       this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
       this._precomputed = false;
       this.get = this.get.bind(this);
     }
-
     BezierEasing.prototype = {
       get: function get(x) {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         if (!this._precomputed) this._precompute();
         if (mX1 === mY1 && mX2 === mY2) return x; // linear
         // Because JavaScript number are imprecise, we should guarantee the extremes are right.
-
         if (x === 0) return 0;
         if (x === 1) return 1;
         return calcBezier(this._getTForX(x), mY1, mY2);
       },
       // Private part
+
       _precompute: function _precompute() {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         this._precomputed = true;
-
         if (mX1 !== mY1 || mX2 !== mY2) {
           this._calcSampleValues();
         }
       },
       _calcSampleValues: function _calcSampleValues() {
         var mX1 = this._p[0],
-            mX2 = this._p[2];
-
+          mX2 = this._p[2];
         for (var i = 0; i < kSplineTableSize; ++i) {
           this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
         }
       },
-
       /**
            * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
            */
       _getTForX: function _getTForX(aX) {
         var mX1 = this._p[0],
-            mX2 = this._p[2],
-            mSampleValues = this._mSampleValues;
+          mX2 = this._p[2],
+          mSampleValues = this._mSampleValues;
         var intervalStart = 0.0;
         var currentSample = 1;
         var lastSample = kSplineTableSize - 1;
-
         for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
           intervalStart += kSampleStepSize;
         }
+        --currentSample;
 
-        --currentSample; // Interpolate to provide an initial guess for t
-
+        // Interpolate to provide an initial guess for t
         var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
         var guessForT = intervalStart + dist * kSampleStepSize;
         var initialSlope = getSlope(guessForT, mX1, mX2);
-
         if (initialSlope >= NEWTON_MIN_SLOPE) {
           return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
         }
-
         if (initialSlope === 0.0) {
           return guessForT;
         }
-
         return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
       }
     };
@@ -2982,7 +2491,6 @@
     function _double(arr) {
       return arr.concat(createSizedArray(arr.length));
     }
-
     return {
       "double": _double
     };
@@ -2997,34 +2505,27 @@
         newElement: newElement,
         release: release
       };
-
       function newElement() {
         var element;
-
         if (_length) {
           _length -= 1;
           element = pool[_length];
         } else {
           element = _create();
         }
-
         return element;
       }
-
       function release(element) {
         if (_length === _maxLength) {
           pool = pooling["double"](pool);
           _maxLength *= 2;
         }
-
         if (_release) {
           _release(element);
         }
-
         pool[_length] = element;
         _length += 1;
       }
-
       return ob;
     };
   }();
@@ -3037,7 +2538,6 @@
         lengths: createTypedArray('float32', getDefaultCurveSegments())
       };
     }
-
     return poolFactory(8, create);
   }();
 
@@ -3048,39 +2548,31 @@
         totalLength: 0
       };
     }
-
     function release(element) {
       var i;
       var len = element.lengths.length;
-
       for (i = 0; i < len; i += 1) {
         bezierLengthPool.release(element.lengths[i]);
       }
-
       element.lengths.length = 0;
     }
-
     return poolFactory(8, create, release);
   }();
 
   function bezFunction() {
     var math = Math;
-
     function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
       var det1 = x1 * y2 + y1 * x3 + x2 * y3 - x3 * y2 - y3 * x1 - x2 * y1;
       return det1 > -0.001 && det1 < 0.001;
     }
-
     function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
       if (z1 === 0 && z2 === 0 && z3 === 0) {
         return pointOnLine2D(x1, y1, x2, y2, x3, y3);
       }
-
       var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
       var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
       var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
       var diffDist;
-
       if (dist1 > dist2) {
         if (dist1 > dist3) {
           diffDist = dist1 - dist2 - dist3;
@@ -3092,10 +2584,8 @@
       } else {
         diffDist = dist2 - dist1 - dist3;
       }
-
       return diffDist > -0.0001 && diffDist < 0.0001;
     }
-
     var getBezierLength = function () {
       return function (pt1, pt2, pt3, pt4) {
         var curveSegments = getDefaultCurveSegments();
@@ -3110,36 +2600,28 @@
         var lastPoint = [];
         var lengthData = bezierLengthPool.newElement();
         len = pt3.length;
-
         for (k = 0; k < curveSegments; k += 1) {
           perc = k / (curveSegments - 1);
           ptDistance = 0;
-
           for (i = 0; i < len; i += 1) {
             ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
             point[i] = ptCoord;
-
             if (lastPoint[i] !== null) {
               ptDistance += bmPow(point[i] - lastPoint[i], 2);
             }
-
             lastPoint[i] = point[i];
           }
-
           if (ptDistance) {
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
           }
-
           lengthData.percents[k] = perc;
           lengthData.lengths[k] = addedLength;
         }
-
         lengthData.addedLength = addedLength;
         return lengthData;
       };
     }();
-
     function getSegmentsLength(shapeData) {
       var segmentsLength = segmentsLengthPool.newElement();
       var closed = shapeData.c;
@@ -3150,36 +2632,29 @@
       var len = shapeData._length;
       var lengths = segmentsLength.lengths;
       var totalLength = 0;
-
       for (i = 0; i < len - 1; i += 1) {
         lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
         totalLength += lengths[i].addedLength;
       }
-
       if (closed && len) {
         lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
         totalLength += lengths[i].addedLength;
       }
-
       segmentsLength.totalLength = totalLength;
       return segmentsLength;
     }
-
     function BezierData(length) {
       this.segmentLength = 0;
       this.points = new Array(length);
     }
-
     function PointData(partial, point) {
       this.partialLength = partial;
       this.point = point;
     }
-
     var buildBezierData = function () {
       var storedData = {};
       return function (pt1, pt2, pt3, pt4) {
         var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
-
         if (!storedData[bezierName]) {
           var curveSegments = getDefaultCurveSegments();
           var k;
@@ -3191,42 +2666,33 @@
           var ptDistance;
           var point;
           var lastPoint = null;
-
           if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
             curveSegments = 2;
           }
-
           var bezierData = new BezierData(curveSegments);
           len = pt3.length;
-
           for (k = 0; k < curveSegments; k += 1) {
             point = createSizedArray(len);
             perc = k / (curveSegments - 1);
             ptDistance = 0;
-
             for (i = 0; i < len; i += 1) {
               ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
               point[i] = ptCoord;
-
               if (lastPoint !== null) {
                 ptDistance += bmPow(point[i] - lastPoint[i], 2);
               }
             }
-
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
             bezierData.points[k] = new PointData(ptDistance, point);
             lastPoint = point;
           }
-
           bezierData.segmentLength = addedLength;
           storedData[bezierName] = bezierData;
         }
-
         return storedData[bezierName];
       };
     }();
-
     function getDistancePerc(perc, bezierData) {
       var percents = bezierData.percents;
       var lengths = bezierData.lengths;
@@ -3234,14 +2700,11 @@
       var initPos = bmFloor((len - 1) * perc);
       var lengthPos = perc * bezierData.addedLength;
       var lPerc = 0;
-
       if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
         return percents[initPos];
       }
-
       var dir = lengths[initPos] > lengthPos ? -1 : 1;
       var flag = true;
-
       while (flag) {
         if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
           lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
@@ -3249,20 +2712,16 @@
         } else {
           initPos += dir;
         }
-
         if (initPos < 0 || initPos >= len - 1) {
           // FIX for TypedArrays that don't store floating point values with enough accuracy
           if (initPos === len - 1) {
             return percents[initPos];
           }
-
           flag = false;
         }
       }
-
       return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
     }
-
     function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
       var t1 = getDistancePerc(percent, bezierData);
       var u1 = 1 - t1;
@@ -3270,16 +2729,13 @@
       var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
       return [ptX, ptY];
     }
-
     var bezierSegmentPoints = createTypedArray('float32', 8);
-
     function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
       if (startPerc < 0) {
         startPerc = 0;
       } else if (startPerc > 1) {
         startPerc = 1;
       }
-
       var t0 = getDistancePerc(startPerc, bezierData);
       endPerc = endPerc > 1 ? 1 : endPerc;
       var t1 = getDistancePerc(endPerc, bezierData);
@@ -3289,45 +2745,31 @@
       var u1 = 1 - t1;
       var u0u0u0 = u0 * u0 * u0;
       var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
-
       var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
-
-      var t0t0t0 = t0 * t0 * t0; //
-
+      var t0t0t0 = t0 * t0 * t0;
+      //
       var u0u0u1 = u0 * u0 * u1;
       var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
-
       var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
-
-      var t0t0t1 = t0 * t0 * t1; //
-
+      var t0t0t1 = t0 * t0 * t1;
+      //
       var u0u1u1 = u0 * u1 * u1;
       var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
-
       var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
-
-      var t0t1t1 = t0 * t1 * t1; //
-
+      var t0t1t1 = t0 * t1 * t1;
+      //
       var u1u1u1 = u1 * u1 * u1;
       var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1t1 = t1 * t1 * t1;
-
       for (i = 0; i < len; i += 1) {
         bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
       }
-
       return bezierSegmentPoints;
     }
-
     return {
       getSegmentsLength: getSegmentsLength,
       getNewSegment: getNewSegment,
@@ -3337,20 +2779,16 @@
       pointOnLine3D: pointOnLine3D
     };
   }
-
   var bez = bezFunction();
 
   var initFrame = initialDefaultFrame;
   var mathAbs = Math.abs;
-
   function interpolateValue(frameNum, caching) {
     var offsetTime = this.offsetTime;
     var newValue;
-
     if (this.propType === 'multidimensional') {
       newValue = createTypedArray('float32', this.pv.length);
     }
-
     var iterationIndex = caching.lastIndex;
     var i = iterationIndex;
     var len = this.keyframes.length - 1;
@@ -3358,25 +2796,20 @@
     var keyData;
     var nextKeyData;
     var keyframeMetadata;
-
     while (flag) {
       keyData = this.keyframes[i];
       nextKeyData = this.keyframes[i + 1];
-
       if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
         if (keyData.h) {
           keyData = nextKeyData;
         }
-
         iterationIndex = 0;
         break;
       }
-
       if (nextKeyData.t - offsetTime > frameNum) {
         iterationIndex = i;
         break;
       }
-
       if (i < len - 1) {
         i += 1;
       } else {
@@ -3384,7 +2817,6 @@
         flag = false;
       }
     }
-
     keyframeMetadata = this.keyframesMetadata[i] || {};
     var k;
     var kLen;
@@ -3395,22 +2827,18 @@
     var nextKeyTime = nextKeyData.t - offsetTime;
     var keyTime = keyData.t - offsetTime;
     var endValue;
-
     if (keyData.to) {
       if (!keyframeMetadata.bezierData) {
         keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
       }
-
       var bezierData = keyframeMetadata.bezierData;
-
       if (frameNum >= nextKeyTime || frameNum < keyTime) {
         var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
         kLen = bezierData.points[ind].point.length;
-
         for (k = 0; k < kLen; k += 1) {
           newValue[k] = bezierData.points[ind].point[k];
-        } // caching._lastKeyframeIndex = -1;
-
+        }
+        // caching._lastKeyframeIndex = -1;
       } else {
         if (keyframeMetadata.__fnct) {
           fnc = keyframeMetadata.__fnct;
@@ -3418,7 +2846,6 @@
           fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
           keyframeMetadata.__fnct = fnc;
         }
-
         perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
         var distanceInLine = bezierData.segmentLength * perc;
         var segmentPerc;
@@ -3426,36 +2853,28 @@
         j = caching.lastFrame < frameNum && caching._lastKeyframeIndex === i ? caching._lastPoint : 0;
         flag = true;
         jLen = bezierData.points.length;
-
         while (flag) {
           addedLength += bezierData.points[j].partialLength;
-
           if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k];
             }
-
             break;
           } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
             segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
             }
-
             break;
           }
-
           if (j < jLen - 1) {
             j += 1;
           } else {
             flag = false;
           }
         }
-
         caching._lastPoint = j;
         caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
         caching._lastKeyframeIndex = i;
@@ -3468,7 +2887,6 @@
       var keyValue;
       len = keyData.s.length;
       endValue = nextKeyData.s || keyData.e;
-
       if (this.sh && keyData.h !== 1) {
         if (frameNum >= nextKeyTime) {
           newValue[0] = endValue[0];
@@ -3496,7 +2914,6 @@
                 if (!keyframeMetadata.__fnct) {
                   keyframeMetadata.__fnct = [];
                 }
-
                 if (!keyframeMetadata.__fnct[i]) {
                   outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
                   outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
@@ -3517,14 +2934,11 @@
               } else {
                 fnc = keyframeMetadata.__fnct;
               }
-
               perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
             }
           }
-
           endValue = nextKeyData.s || keyData.e;
           keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
-
           if (this.propType === 'multidimensional') {
             newValue[i] = keyValue;
           } else {
@@ -3533,12 +2947,11 @@
         }
       }
     }
-
     caching.lastIndex = iterationIndex;
     return newValue;
-  } // based on @Toji's https://github.com/toji/gl-matrix/
+  }
 
-
+  // based on @Toji's https://github.com/toji/gl-matrix/
   function slerp(a, b, t) {
     var out = [];
     var ax = a[0];
@@ -3555,7 +2968,6 @@
     var scale0;
     var scale1;
     cosom = ax * bx + ay * by + az * bz + aw * bw;
-
     if (cosom < 0.0) {
       cosom = -cosom;
       bx = -bx;
@@ -3563,7 +2975,6 @@
       bz = -bz;
       bw = -bw;
     }
-
     if (1.0 - cosom > 0.000001) {
       omega = Math.acos(cosom);
       sinom = Math.sin(omega);
@@ -3573,14 +2984,12 @@
       scale0 = 1.0 - t;
       scale1 = t;
     }
-
     out[0] = scale0 * ax + scale1 * bx;
     out[1] = scale0 * ay + scale1 * by;
     out[2] = scale0 * az + scale1 * bz;
     out[3] = scale0 * aw + scale1 * bw;
     return out;
   }
-
   function quaternionToEuler(out, quat) {
     var qx = quat[0];
     var qy = quat[1];
@@ -3593,7 +3002,6 @@
     out[1] = attitude / degToRads;
     out[2] = bank / degToRads;
   }
-
   function createQuaternion(values) {
     var heading = values[0] * degToRads;
     var attitude = values[1] * degToRads;
@@ -3610,32 +3018,25 @@
     var z = c1 * s2 * c3 - s1 * c2 * s3;
     return [x, y, z, w];
   }
-
   function getValueAtCurrentTime() {
     var frameNum = this.comp.renderedFrame - this.offsetTime;
     var initTime = this.keyframes[0].t - this.offsetTime;
     var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
-
     if (!(frameNum === this._caching.lastFrame || this._caching.lastFrame !== initFrame && (this._caching.lastFrame >= endTime && frameNum >= endTime || this._caching.lastFrame < initTime && frameNum < initTime))) {
       if (this._caching.lastFrame >= frameNum) {
         this._caching._lastKeyframeIndex = -1;
         this._caching.lastIndex = 0;
       }
-
       var renderResult = this.interpolateValue(frameNum, this._caching);
       this.pv = renderResult;
     }
-
     this._caching.lastFrame = frameNum;
     return this.pv;
   }
-
   function setVValue(val) {
     var multipliedValue;
-
     if (this.propType === 'unidimensional') {
       multipliedValue = val * this.mult;
-
       if (mathAbs(this.v - multipliedValue) > 0.00001) {
         this.v = multipliedValue;
         this._mdf = true;
@@ -3643,51 +3044,41 @@
     } else {
       var i = 0;
       var len = this.v.length;
-
       while (i < len) {
         multipliedValue = val[i] * this.mult;
-
         if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
           this.v[i] = multipliedValue;
           this._mdf = true;
         }
-
         i += 1;
       }
     }
   }
-
   function processEffectsSequence() {
     if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
       return;
     }
-
     if (this.lock) {
       this.setVValue(this.pv);
       return;
     }
-
     this.lock = true;
     this._mdf = this._isFirstFrame;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = this.kf ? this.pv : this.data.k;
-
     for (i = 0; i < len; i += 1) {
       finalValue = this.effectsSequence[i](finalValue);
     }
-
     this.setVValue(finalValue);
     this._isFirstFrame = false;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   }
-
   function addEffect(effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.container.addDynamicProperty(this);
   }
-
   function ValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.mult = mult || 1;
@@ -3707,7 +3098,6 @@
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function MultiDimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     this.mult = mult || 1;
@@ -3724,19 +3114,16 @@
     this.v = createTypedArray('float32', len);
     this.pv = createTypedArray('float32', len);
     this.vel = createTypedArray('float32', len);
-
     for (i = 0; i < len; i += 1) {
       this.v[i] = data.k[i] * this.mult;
       this.pv[i] = data.k[i];
     }
-
     this._isFirstFrame = true;
     this.effectsSequence = [];
     this.getValue = processEffectsSequence;
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function KeyframedValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.keyframes = data.k;
@@ -3765,7 +3152,6 @@
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.addEffect = addEffect;
   }
-
   function KeyframedMultidimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     var i;
@@ -3774,19 +3160,16 @@
     var e;
     var to;
     var ti;
-
     for (i = 0; i < len - 1; i += 1) {
       if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
         s = data.k[i].s;
         e = data.k[i + 1].s;
         to = data.k[i].to;
         ti = data.k[i].ti;
-
         if (s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1]) || s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2])) {
           data.k[i].to = null;
           data.k[i].ti = null;
         }
-
         if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
           if (s.length === 2 || s[2] === e[2] && to[2] === 0 && ti[2] === 0) {
             data.k[i].to = null;
@@ -3795,7 +3178,6 @@
         }
       }
     }
-
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.data = data;
     this.keyframes = data.k;
@@ -3815,12 +3197,10 @@
     var arrLen = data.k[0].s.length;
     this.v = createTypedArray('float32', arrLen);
     this.pv = createTypedArray('float32', arrLen);
-
     for (i = 0; i < arrLen; i += 1) {
       this.v[i] = initFrame;
       this.pv[i] = initFrame;
     }
-
     this._caching = {
       lastFrame: initFrame,
       lastIndex: 0,
@@ -3828,15 +3208,12 @@
     };
     this.addEffect = addEffect;
   }
-
   var PropertyFactory = function () {
     function getProp(elem, data, type, mult, container) {
       if (data.sid) {
         data = elem.globalData.slotManager.getProp(data);
       }
-
       var p;
-
       if (!data.k.length) {
         p = new ValueProperty(elem, data, mult, container);
       } else if (typeof data.k[0] === 'number') {
@@ -3846,23 +3223,18 @@
           case 0:
             p = new KeyframedValueProperty(elem, data, mult, container);
             break;
-
           case 1:
             p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
             break;
-
           default:
             break;
         }
       }
-
       if (p.effectsSequence.length) {
         container.addDynamicProperty(p);
       }
-
       return p;
     }
-
     var ob = {
       getProp: getProp
     };
@@ -3870,7 +3242,6 @@
   }();
 
   function DynamicPropertyContainer() {}
-
   DynamicPropertyContainer.prototype = {
     addDynamicProperty: function addDynamicProperty(prop) {
       if (this.dynamicProperties.indexOf(prop) === -1) {
@@ -3883,10 +3254,8 @@
       this._mdf = false;
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         this.dynamicProperties[i].getValue();
-
         if (this.dynamicProperties[i]._mdf) {
           this._mdf = true;
         }
@@ -3904,7 +3273,6 @@
     function create() {
       return createTypedArray('float32', 2);
     }
-
     return poolFactory(8, create);
   }();
 
@@ -3916,12 +3284,10 @@
     this.o = createSizedArray(this._maxLength);
     this.i = createSizedArray(this._maxLength);
   }
-
   ShapePath.prototype.setPathData = function (closed, len) {
     this.c = closed;
     this.setLength(len);
     var i = 0;
-
     while (i < len) {
       this.v[i] = pointPool.newElement();
       this.o[i] = pointPool.newElement();
@@ -3929,62 +3295,49 @@
       i += 1;
     }
   };
-
   ShapePath.prototype.setLength = function (len) {
     while (this._maxLength < len) {
       this.doubleArrayLength();
     }
-
     this._length = len;
   };
-
   ShapePath.prototype.doubleArrayLength = function () {
     this.v = this.v.concat(createSizedArray(this._maxLength));
     this.i = this.i.concat(createSizedArray(this._maxLength));
     this.o = this.o.concat(createSizedArray(this._maxLength));
     this._maxLength *= 2;
   };
-
   ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
     var arr;
     this._length = Math.max(this._length, pos + 1);
-
     if (this._length >= this._maxLength) {
       this.doubleArrayLength();
     }
-
     switch (type) {
       case 'v':
         arr = this.v;
         break;
-
       case 'i':
         arr = this.i;
         break;
-
       case 'o':
         arr = this.o;
         break;
-
       default:
         arr = [];
         break;
     }
-
     if (!arr[pos] || arr[pos] && !replace) {
       arr[pos] = pointPool.newElement();
     }
-
     arr[pos][0] = x;
     arr[pos][1] = y;
   };
-
   ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
     this.setXYAt(vX, vY, 'v', pos, replace);
     this.setXYAt(oX, oY, 'o', pos, replace);
     this.setXYAt(iX, iY, 'i', pos, replace);
   };
-
   ShapePath.prototype.reverse = function () {
     var newPath = new ShapePath();
     newPath.setPathData(this.c, this._length);
@@ -3992,24 +3345,19 @@
     var outPoints = this.o;
     var inPoints = this.i;
     var init = 0;
-
     if (this.c) {
       newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
       init = 1;
     }
-
     var cnt = this._length - 1;
     var len = this._length;
     var i;
-
     for (i = init; i < len; i += 1) {
       newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
       cnt -= 1;
     }
-
     return newPath;
   };
-
   ShapePath.prototype.length = function () {
     return this._length;
   };
@@ -4018,11 +3366,9 @@
     function create() {
       return new ShapePath();
     }
-
     function release(shapePath) {
       var len = shapePath._length;
       var i;
-
       for (i = 0; i < len; i += 1) {
         pointPool.release(shapePath.v[i]);
         pointPool.release(shapePath.i[i]);
@@ -4031,25 +3377,20 @@
         shapePath.i[i] = null;
         shapePath.o[i] = null;
       }
-
       shapePath._length = 0;
       shapePath.c = false;
     }
-
     function clone(shape) {
       var cloned = factory.newElement();
       var i;
       var len = shape._length === undefined ? shape.v.length : shape._length;
       cloned.setLength(len);
       cloned.c = shape.c;
-
       for (i = 0; i < len; i += 1) {
         cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
       }
-
       return cloned;
     }
-
     var factory = poolFactory(4, create, release);
     factory.clone = clone;
     return factory;
@@ -4060,24 +3401,19 @@
     this._maxLength = 4;
     this.shapes = createSizedArray(this._maxLength);
   }
-
   ShapeCollection.prototype.addShape = function (shapeData) {
     if (this._length === this._maxLength) {
       this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
       this._maxLength *= 2;
     }
-
     this.shapes[this._length] = shapeData;
     this._length += 1;
   };
-
   ShapeCollection.prototype.releaseShapes = function () {
     var i;
-
     for (i = 0; i < this._length; i += 1) {
       shapePool.release(this.shapes[i]);
     }
-
     this._length = 0;
   };
 
@@ -4089,45 +3425,35 @@
     var _length = 0;
     var _maxLength = 4;
     var pool = createSizedArray(_maxLength);
-
     function newShapeCollection() {
       var shapeCollection;
-
       if (_length) {
         _length -= 1;
         shapeCollection = pool[_length];
       } else {
         shapeCollection = new ShapeCollection();
       }
-
       return shapeCollection;
     }
-
     function release(shapeCollection) {
       var i;
       var len = shapeCollection._length;
-
       for (i = 0; i < len; i += 1) {
         shapePool.release(shapeCollection.shapes[i]);
       }
-
       shapeCollection._length = 0;
-
       if (_length === _maxLength) {
         pool = pooling["double"](pool);
         _maxLength *= 2;
       }
-
       pool[_length] = shapeCollection;
       _length += 1;
     }
-
     return ob;
   }();
 
   var ShapePropertyFactory = function () {
     var initFrame = -999999;
-
     function interpolateShape(frameNum, previousValue, caching) {
       var iterationIndex = caching.lastIndex;
       var keyPropS;
@@ -4140,7 +3466,6 @@
       var perc;
       var vertexValue;
       var kf = this.keyframes;
-
       if (frameNum < kf[0].t - this.offsetTime) {
         keyPropS = kf[0].s[0];
         isHold = true;
@@ -4152,7 +3477,6 @@
               }else{
                   keyPropS = kf[kf.length - 2].e[0];
               } */
-
         isHold = true;
       } else {
         var i = iterationIndex;
@@ -4161,26 +3485,21 @@
         var keyData;
         var nextKeyData;
         var keyframeMetadata;
-
         while (flag) {
           keyData = kf[i];
           nextKeyData = kf[i + 1];
-
           if (nextKeyData.t - this.offsetTime > frameNum) {
             break;
           }
-
           if (i < len - 1) {
             i += 1;
           } else {
             flag = false;
           }
         }
-
         keyframeMetadata = this.keyframesMetadata[i] || {};
         isHold = keyData.h === 1;
         iterationIndex = i;
-
         if (!isHold) {
           if (frameNum >= nextKeyData.t - this.offsetTime) {
             perc = 1;
@@ -4188,27 +3507,21 @@
             perc = 0;
           } else {
             var fnc;
-
             if (keyframeMetadata.__fnct) {
               fnc = keyframeMetadata.__fnct;
             } else {
               fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
               keyframeMetadata.__fnct = fnc;
             }
-
             perc = fnc((frameNum - (keyData.t - this.offsetTime)) / (nextKeyData.t - this.offsetTime - (keyData.t - this.offsetTime)));
           }
-
           keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
         }
-
         keyPropS = keyData.s[0];
       }
-
       jLen = previousValue._length;
       kLen = keyPropS.i[0].length;
       caching.lastIndex = iterationIndex;
-
       for (j = 0; j < jLen; j += 1) {
         for (k = 0; k < kLen; k += 1) {
           vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
@@ -4220,44 +3533,36 @@
         }
       }
     }
-
     function interpolateShapeCurrentTime() {
       var frameNum = this.comp.renderedFrame - this.offsetTime;
       var initTime = this.keyframes[0].t - this.offsetTime;
       var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
       var lastFrame = this._caching.lastFrame;
-
       if (!(lastFrame !== initFrame && (lastFrame < initTime && frameNum < initTime || lastFrame > endTime && frameNum > endTime))) {
         /// /
         this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
-        this.interpolateShape(frameNum, this.pv, this._caching); /// /
+        this.interpolateShape(frameNum, this.pv, this._caching);
+        /// /
       }
-
       this._caching.lastFrame = frameNum;
       return this.pv;
     }
-
     function resetShape() {
       this.paths = this.localShapeCollection;
     }
-
     function shapesEqual(shape1, shape2) {
       if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
         return false;
       }
-
       var i;
       var len = shape1._length;
-
       for (i = 0; i < len; i += 1) {
         if (shape1.v[i][0] !== shape2.v[i][0] || shape1.v[i][1] !== shape2.v[i][1] || shape1.o[i][0] !== shape2.o[i][0] || shape1.o[i][1] !== shape2.o[i][1] || shape1.i[i][0] !== shape2.i[i][0] || shape1.i[i][1] !== shape2.i[i][1]) {
           return false;
         }
       }
-
       return true;
     }
-
     function setVValue(newPath) {
       if (!shapesEqual(this.v, newPath)) {
         this.v = shapePool.clone(newPath);
@@ -4267,26 +3572,21 @@
         this.paths = this.localShapeCollection;
       }
     }
-
     function processEffectsSequence() {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (!this.effectsSequence.length) {
         this._mdf = false;
         return;
       }
-
       if (this.lock) {
         this.setVValue(this.pv);
         return;
       }
-
       this.lock = true;
       this._mdf = false;
       var finalValue;
-
       if (this.kf) {
         finalValue = this.pv;
       } else if (this.data.ks) {
@@ -4294,19 +3594,15 @@
       } else {
         finalValue = this.data.pt.k;
       }
-
       var i;
       var len = this.effectsSequence.length;
-
       for (i = 0; i < len; i += 1) {
         finalValue = this.effectsSequence[i](finalValue);
       }
-
       this.setVValue(finalValue);
       this.lock = false;
       this.frameId = this.elem.globalData.frameId;
     }
-
     function ShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4325,17 +3621,14 @@
       this.reset = resetShape;
       this.effectsSequence = [];
     }
-
     function addEffect(effectFunction) {
       this.effectsSequence.push(effectFunction);
       this.container.addDynamicProperty(this);
     }
-
     ShapeProperty.prototype.interpolateShape = interpolateShape;
     ShapeProperty.prototype.getValue = processEffectsSequence;
     ShapeProperty.prototype.setVValue = setVValue;
     ShapeProperty.prototype.addEffect = addEffect;
-
     function KeyframedShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4361,15 +3654,12 @@
       };
       this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
     }
-
     KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
     KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
     KeyframedShapeProperty.prototype.setVValue = setVValue;
     KeyframedShapeProperty.prototype.addEffect = addEffect;
-
     var EllShapeProperty = function () {
       var cPoint = roundCorner;
-
       function EllShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
         this.v.setPathData(true, 4);
@@ -4383,7 +3673,6 @@
         this.initDynamicPropertyContainer(elem);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4391,17 +3680,14 @@
           this.convertEllToPath();
         }
       }
-
       EllShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertEllToPath();
           }
@@ -4411,9 +3697,7 @@
           var p1 = this.p.v[1];
           var s0 = this.s.v[0] / 2;
           var s1 = this.s.v[1] / 2;
-
           var _cw = this.d !== 3;
-
           var _v = this.v;
           _v.v[0][0] = p0;
           _v.v[0][1] = p1 - s1;
@@ -4444,7 +3728,6 @@
       extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
       return EllShapePropertyFactory;
     }();
-
     var StarShapeProperty = function () {
       function StarShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4455,7 +3738,6 @@
         this.frameId = -1;
         this.d = data.d;
         this.initDynamicPropertyContainer(elem);
-
         if (data.sy === 1) {
           this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
           this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
@@ -4463,7 +3745,6 @@
         } else {
           this.convertToPath = this.convertPolygonToPath;
         }
-
         this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
@@ -4472,7 +3753,6 @@
         this.localShapeCollection = shapeCollectionPool.newShapeCollection();
         this.localShapeCollection.addShape(this.v);
         this.paths = this.localShapeCollection;
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4480,17 +3760,14 @@
           this.convertToPath();
         }
       }
-
       StarShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertToPath();
           }
@@ -4501,7 +3778,6 @@
           /* this.v.v.length = numPts;
                   this.v.i.length = numPts;
                   this.v.o.length = numPts; */
-
           var longFlag = true;
           var longRad = this.or.v;
           var shortRad = this.ir.v;
@@ -4517,7 +3793,6 @@
           currentAng += this.r.v;
           var dir = this.data.d === 3 ? -1 : 1;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             rad = longFlag ? longRad : shortRad;
             roundness = longFlag ? longRound : shortRound;
@@ -4529,11 +3804,11 @@
             x += +this.p.v[0];
             y += +this.p.v[1];
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
             /* this.v.v[i] = [x,y];
                       this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
                       this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
                       this.v._length = numPts; */
-
             longFlag = !longFlag;
             currentAng += angle * dir;
           }
@@ -4549,7 +3824,6 @@
           var dir = this.data.d === 3 ? -1 : 1;
           currentAng += this.r.v;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             var x = rad * Math.cos(currentAng);
             var y = rad * Math.sin(currentAng);
@@ -4560,7 +3834,6 @@
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
             currentAng += angle * dir;
           }
-
           this.paths.length = 0;
           this.paths[0] = this.v;
         }
@@ -4568,7 +3841,6 @@
       extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
       return StarShapePropertyFactory;
     }();
-
     var RectShapeProperty = function () {
       function RectShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4584,7 +3856,6 @@
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4592,7 +3863,6 @@
           this.convertRectToPath();
         }
       }
-
       RectShapePropertyFactory.prototype = {
         convertRectToPath: function convertRectToPath() {
           var p0 = this.p.v[0];
@@ -4602,11 +3872,9 @@
           var round = bmMin(v0, v1, this.r.v);
           var cPoint = round * (1 - roundCorner);
           this.v._length = 0;
-
           if (this.d === 2 || this.d === 1) {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
             this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
               this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
@@ -4620,7 +3888,6 @@
             }
           } else {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
               this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
@@ -4640,10 +3907,8 @@
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertRectToPath();
           }
@@ -4653,14 +3918,11 @@
       extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
       return RectShapePropertyFactory;
     }();
-
     function getShapeProp(elem, data, type) {
       var prop;
-
       if (type === 3 || type === 4) {
         var dataProp = type === 3 ? data.pt : data.ks;
         var keys = dataProp.k;
-
         if (keys.length) {
           prop = new KeyframedShapeProperty(elem, data, type);
         } else {
@@ -4673,22 +3935,17 @@
       } else if (type === 7) {
         prop = new StarShapeProperty(elem, data);
       }
-
       if (prop.k) {
         elem.addDynamicProperty(prop);
       }
-
       return prop;
     }
-
     function getConstructorFunction() {
       return ShapeProperty;
     }
-
     function getKeyframedConstructorFunction() {
       return KeyframedShapeProperty;
     }
-
     var ob = {};
     ob.getShapeProp = getShapeProp;
     ob.getConstructorFunction = getConstructorFunction;
@@ -4730,7 +3987,6 @@
     var _sin = Math.sin;
     var _tan = Math.tan;
     var _rnd = Math.round;
-
     function reset() {
       this.props[0] = 1;
       this.props[1] = 0;
@@ -4750,83 +4006,59 @@
       this.props[15] = 1;
       return this;
     }
-
     function rotate(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function rotateX(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateY(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateZ(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function shear(sx, sy) {
       return this._t(1, sy, sx, 1, 0, 0);
     }
-
     function skew(ax, ay) {
       return this.shear(_tan(ax), _tan(ay));
     }
-
     function skewFromAxis(ax, angle) {
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
-      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+      // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
     }
-
     function scale(sx, sy, sz) {
       if (!sz && sz !== 0) {
         sz = 1;
       }
-
       if (sx === 1 && sy === 1 && sz === 1) {
         return this;
       }
-
       return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
     }
-
     function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
       this.props[0] = a;
       this.props[1] = b;
@@ -4846,32 +4078,26 @@
       this.props[15] = p;
       return this;
     }
-
     function translate(tx, ty, tz) {
       tz = tz || 0;
-
       if (tx !== 0 || ty !== 0 || tz !== 0) {
         return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
       }
-
       return this;
     }
-
     function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
       var _p = this.props;
-
       if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
         // NOTE: commenting this condition because TurboFan deoptimizes code when present
         // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
         _p[12] = _p[12] * a2 + _p[15] * m2;
         _p[13] = _p[13] * f2 + _p[15] * n2;
         _p[14] = _p[14] * k2 + _p[15] * o2;
-        _p[15] *= p2; // }
-
+        _p[15] *= p2;
+        // }
         this._identityCalculated = false;
         return this;
       }
-
       var a1 = _p[0];
       var b1 = _p[1];
       var c1 = _p[2];
@@ -4888,12 +4114,12 @@
       var n1 = _p[13];
       var o1 = _p[14];
       var p1 = _p[15];
+
       /* matrix order (canvas compatible):
            * ace
            * bdf
            * 001
            */
-
       _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
       _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
       _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
@@ -4913,53 +4139,40 @@
       this._identityCalculated = false;
       return this;
     }
-
     function multiply(matrix) {
       var matrixProps = matrix.props;
       return this.transform(matrixProps[0], matrixProps[1], matrixProps[2], matrixProps[3], matrixProps[4], matrixProps[5], matrixProps[6], matrixProps[7], matrixProps[8], matrixProps[9], matrixProps[10], matrixProps[11], matrixProps[12], matrixProps[13], matrixProps[14], matrixProps[15]);
     }
-
     function isIdentity() {
       if (!this._identityCalculated) {
         this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
         this._identityCalculated = true;
       }
-
       return this._identity;
     }
-
     function equals(matr) {
       var i = 0;
-
       while (i < 16) {
         if (matr.props[i] !== this.props[i]) {
           return false;
         }
-
         i += 1;
       }
-
       return true;
     }
-
     function clone(matr) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         matr.props[i] = this.props[i];
       }
-
       return matr;
     }
-
     function cloneFromProps(props) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         this.props[i] = props[i];
       }
     }
-
     function applyToPoint(x, y, z) {
       return {
         x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
@@ -4971,19 +4184,15 @@
            y: x * me.b + y * me.d + me.f
            }; */
     }
-
     function applyToX(x, y, z) {
       return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
     }
-
     function applyToY(x, y, z) {
       return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
     }
-
     function applyToZ(x, y, z) {
       return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
     }
-
     function getInverseMatrix() {
       var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
       var a = this.props[5] / determinant;
@@ -5001,27 +4210,21 @@
       inverseMatrix.props[13] = f;
       return inverseMatrix;
     }
-
     function inversePoint(pt) {
       var inverseMatrix = this.getInverseMatrix();
       return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
     }
-
     function inversePoints(pts) {
       var i;
       var len = pts.length;
       var retPts = [];
-
       for (i = 0; i < len; i += 1) {
         retPts[i] = inversePoint(pts[i]);
       }
-
       return retPts;
     }
-
     function applyToTriplePoints(pt1, pt2, pt3) {
       var arr = createTypedArray('float32', 6);
-
       if (this.isIdentity()) {
         arr[0] = pt1[0];
         arr[1] = pt1[1];
@@ -5043,34 +4246,26 @@
         arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
         arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
       }
-
       return arr;
     }
-
     function applyToPointArray(x, y, z) {
       var arr;
-
       if (this.isIdentity()) {
         arr = [x, y, z];
       } else {
         arr = [x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12], x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13], x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14]];
       }
-
       return arr;
     }
-
     function applyToPointStringified(x, y) {
       if (this.isIdentity()) {
         return x + ',' + y;
       }
-
       var _p = this.props;
       return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
     }
-
     function toCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
@@ -5078,49 +4273,34 @@
       var props = this.props;
       var cssValue = 'matrix3d(';
       var v = 10000;
-
       while (i < 16) {
         cssValue += _rnd(props[i] * v) / v;
         cssValue += i === 15 ? ')' : ',';
         i += 1;
       }
-
       return cssValue;
     }
-
     function roundMatrixProperty(val) {
       var v = 10000;
-
       if (val < 0.000001 && val > 0 || val > -0.000001 && val < 0) {
         return _rnd(val * v) / v;
       }
-
       return val;
     }
-
     function to2dCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
       var props = this.props;
-
       var _a = roundMatrixProperty(props[0]);
-
       var _b = roundMatrixProperty(props[1]);
-
       var _c = roundMatrixProperty(props[4]);
-
       var _d = roundMatrixProperty(props[5]);
-
       var _e = roundMatrixProperty(props[12]);
-
       var _f = roundMatrixProperty(props[13]);
-
       return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
     }
-
     return function () {
       this.reset = reset;
       this.rotate = rotate;
@@ -5159,16 +4339,14 @@
     };
   }();
 
-  function _typeof$3(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$3 = function _typeof(obj) { return typeof obj; }; } else { _typeof$3 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$3(obj); }
+  function _typeof$3(o) { "@babel/helpers - typeof"; return _typeof$3 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$3(o); }
   var lottie = {};
   var standalone = '__[STANDALONE]__';
   var animationData = '__[ANIMATIONDATA]__';
   var renderer = '';
-
   function setLocation(href) {
     setLocationHref(href);
   }
-
   function searchAnimations() {
     if (standalone === true) {
       animationManager.searchAnimations(animationData, standalone, renderer);
@@ -5176,35 +4354,28 @@
       animationManager.searchAnimations();
     }
   }
-
   function setSubframeRendering(flag) {
     setSubframeEnabled(flag);
   }
-
   function setPrefix(prefix) {
     setIdPrefix(prefix);
   }
-
   function loadAnimation(params) {
     if (standalone === true) {
       params.animationData = JSON.parse(animationData);
     }
-
     return animationManager.loadAnimation(params);
   }
-
   function setQuality(value) {
     if (typeof value === 'string') {
       switch (value) {
         case 'high':
           setDefaultCurveSegments(200);
           break;
-
         default:
         case 'medium':
           setDefaultCurveSegments(50);
           break;
-
         case 'low':
           setDefaultCurveSegments(10);
           break;
@@ -5212,40 +4383,32 @@
     } else if (!isNaN(value) && value > 1) {
       setDefaultCurveSegments(value);
     }
-
     if (getDefaultCurveSegments() >= 50) {
       roundValues(false);
     } else {
       roundValues(true);
     }
   }
-
   function inBrowser() {
     return typeof navigator !== 'undefined';
   }
-
   function installPlugin(type, plugin) {
     if (type === 'expressions') {
       setExpressionsPlugin(plugin);
     }
   }
-
   function getFactory(name) {
     switch (name) {
       case 'propertyFactory':
         return PropertyFactory;
-
       case 'shapePropertyFactory':
         return ShapePropertyFactory;
-
       case 'matrix':
         return Matrix;
-
       default:
         return null;
     }
   }
-
   lottie.play = animationManager.play;
   lottie.pause = animationManager.pause;
   lottie.setLocationHref = setLocation;
@@ -5257,8 +4420,8 @@
   lottie.registerAnimation = animationManager.registerAnimation;
   lottie.loadAnimation = loadAnimation;
   lottie.setSubframeRendering = setSubframeRendering;
-  lottie.resize = animationManager.resize; // lottie.start = start;
-
+  lottie.resize = animationManager.resize;
+  // lottie.start = start;
   lottie.goToAndStop = animationManager.goToAndStop;
   lottie.destroy = animationManager.destroy;
   lottie.setQuality = setQuality;
@@ -5273,32 +4436,25 @@
   lottie.useWebWorker = setWebWorker;
   lottie.setIDPrefix = setPrefix;
   lottie.__getFactory = getFactory;
-  lottie.version = '5.12.2';
-
+  lottie.version = '5.13.0';
   function checkReady() {
     if (document.readyState === 'complete') {
       clearInterval(readyStateCheckInterval);
       searchAnimations();
     }
   }
-
   function getQueryVariable(variable) {
     var vars = queryString.split('&');
-
     for (var i = 0; i < vars.length; i += 1) {
       var pair = vars[i].split('=');
-
       if (decodeURIComponent(pair[0]) == variable) {
         // eslint-disable-line eqeqeq
         return decodeURIComponent(pair[1]);
       }
     }
-
     return null;
   }
-
   var queryString = '';
-
   if (standalone) {
     var scripts = document.getElementsByTagName('script');
     var index = scripts.length - 1;
@@ -5306,18 +4462,18 @@
       src: ''
     };
     queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
-
     renderer = getQueryVariable('renderer');
   }
+  var readyStateCheckInterval = setInterval(checkReady, 100);
 
-  var readyStateCheckInterval = setInterval(checkReady, 100); // this adds bodymovin to the window object for backwards compatibility
-
+  // this adds bodymovin to the window object for backwards compatibility
   try {
     if (!((typeof exports === "undefined" ? "undefined" : _typeof$3(exports)) === 'object' && typeof module !== 'undefined') && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
     ) {
       window.bodymovin = lottie;
     }
-  } catch (err) {//
+  } catch (err) {
+    //
   }
 
   var ShapeModifiers = function () {
@@ -5325,26 +4481,19 @@
     var modifiers = {};
     ob.registerModifier = registerModifier;
     ob.getModifier = getModifier;
-
     function registerModifier(nm, factory) {
       if (!modifiers[nm]) {
         modifiers[nm] = factory;
       }
     }
-
     function getModifier(nm, elem, data) {
       return new modifiers[nm](elem, data);
     }
-
     return ob;
   }();
-
   function ShapeModifier() {}
-
   ShapeModifier.prototype.initModifierProperties = function () {};
-
   ShapeModifier.prototype.addShapeToModifier = function () {};
-
   ShapeModifier.prototype.addShape = function (data) {
     if (!this.closed) {
       // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
@@ -5356,13 +4505,11 @@
       };
       this.shapes.push(shapeData);
       this.addShapeToModifier(shapeData);
-
       if (this._isAnimated) {
         data.setAsAnimated();
       }
     }
   };
-
   ShapeModifier.prototype.init = function (elem, data) {
     this.shapes = [];
     this.elem = elem;
@@ -5371,29 +4518,23 @@
     this.frameId = initialDefaultFrame;
     this.closed = false;
     this.k = false;
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   ShapeModifier.prototype.processKeys = function () {
     if (this.elem.globalData.frameId === this.frameId) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   extendPrototype([DynamicPropertyContainer], ShapeModifier);
 
   function TrimModifier() {}
-
   extendPrototype([ShapeModifier], TrimModifier);
-
   TrimModifier.prototype.initModifierProperties = function (elem, data) {
     this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
     this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
@@ -5404,14 +4545,11 @@
     this.m = data.m;
     this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
   };
-
   TrimModifier.prototype.addShapeToModifier = function (shapeData) {
     shapeData.pathsData = [];
   };
-
   TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
     var segments = [];
-
     if (e <= 1) {
       segments.push({
         s: s,
@@ -5432,65 +4570,50 @@
         e: e - 1
       });
     }
-
     var shapeSegments = [];
     var i;
     var len = segments.length;
     var segmentOb;
-
     for (i = 0; i < len; i += 1) {
       segmentOb = segments[i];
-
       if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
         var shapeS;
         var shapeE;
-
         if (segmentOb.s * totalModifierLength <= addedLength) {
           shapeS = 0;
         } else {
           shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
         }
-
         if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
           shapeE = 1;
         } else {
           shapeE = (segmentOb.e * totalModifierLength - addedLength) / shapeLength;
         }
-
         shapeSegments.push([shapeS, shapeE]);
       }
     }
-
     if (!shapeSegments.length) {
       shapeSegments.push([0, 0]);
     }
-
     return shapeSegments;
   };
-
   TrimModifier.prototype.releasePathsData = function (pathsData) {
     var i;
     var len = pathsData.length;
-
     for (i = 0; i < len; i += 1) {
       segmentsLengthPool.release(pathsData[i]);
     }
-
     pathsData.length = 0;
     return pathsData;
   };
-
   TrimModifier.prototype.processShapes = function (_isFirstFrame) {
     var s;
     var e;
-
     if (this._mdf || _isFirstFrame) {
       var o = this.o.v % 360 / 360;
-
       if (o < 0) {
         o += 1;
       }
-
       if (this.s.v > 1) {
         s = 1 + o;
       } else if (this.s.v < 0) {
@@ -5498,7 +4621,6 @@
       } else {
         s = this.s.v + o;
       }
-
       if (this.e.v > 1) {
         e = 1 + o;
       } else if (this.e.v < 0) {
@@ -5506,13 +4628,11 @@
       } else {
         e = this.e.v + o;
       }
-
       if (s > e) {
         var _s = s;
         s = e;
         e = _s;
       }
-
       s = Math.round(s * 10000) * 0.0001;
       e = Math.round(e * 10000) * 0.0001;
       this.sValue = s;
@@ -5521,7 +4641,6 @@
       s = this.sValue;
       e = this.eValue;
     }
-
     var shapePaths;
     var i;
     var len = this.shapes.length;
@@ -5531,13 +4650,11 @@
     var pathData;
     var totalShapeLength;
     var totalModifierLength = 0;
-
     if (e === s) {
       for (i = 0; i < len; i += 1) {
         this.shapes[i].localShapeCollection.releaseShapes();
         this.shapes[i].shape._mdf = true;
         this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
-
         if (this._mdf) {
           this.shapes[i].pathsData.length = 0;
         }
@@ -5546,63 +4663,52 @@
       var segments = [];
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
-        shapeData = this.shapes[i]; // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
-
+        shapeData = this.shapes[i];
+        // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
         if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
           shapeData.shape.paths = shapeData.localShapeCollection;
         } else {
           shapePaths = shapeData.shape.paths;
           jLen = shapePaths._length;
           totalShapeLength = 0;
-
           if (!shapeData.shape._mdf && shapeData.pathsData.length) {
             totalShapeLength = shapeData.totalShapeLength;
           } else {
             pathsData = this.releasePathsData(shapeData.pathsData);
-
             for (j = 0; j < jLen; j += 1) {
               pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
               pathsData.push(pathData);
               totalShapeLength += pathData.totalLength;
             }
-
             shapeData.totalShapeLength = totalShapeLength;
             shapeData.pathsData = pathsData;
           }
-
           totalModifierLength += totalShapeLength;
           shapeData.shape._mdf = true;
         }
       }
-
       var shapeS = s;
       var shapeE = e;
       var addedLength = 0;
       var edges;
-
       for (i = len - 1; i >= 0; i -= 1) {
         shapeData = this.shapes[i];
-
         if (shapeData.shape._mdf) {
           localShapeCollection = shapeData.localShapeCollection;
-          localShapeCollection.releaseShapes(); // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
-
+          localShapeCollection.releaseShapes();
+          // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
           if (this.m === 2 && len > 1) {
             edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
             addedLength += shapeData.totalShapeLength;
           } else {
             edges = [[shapeS, shapeE]];
           }
-
           jLen = edges.length;
-
           for (j = 0; j < jLen; j += 1) {
             shapeS = edges[j][0];
             shapeE = edges[j][1];
             segments.length = 0;
-
             if (shapeE <= 1) {
               segments.push({
                 s: shapeData.totalShapeLength * shapeS,
@@ -5623,13 +4729,10 @@
                 e: shapeData.totalShapeLength * (shapeE - 1)
               });
             }
-
             var newShapesData = this.addShapes(shapeData, segments[0]);
-
             if (segments[0].s !== segments[0].e) {
               if (segments.length > 1) {
                 var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
-
                 if (lastShapeInCollection.c) {
                   var lastShape = newShapesData.pop();
                   this.addPaths(newShapesData, localShapeCollection);
@@ -5639,11 +4742,9 @@
                   newShapesData = this.addShapes(shapeData, segments[1]);
                 }
               }
-
               this.addPaths(newShapesData, localShapeCollection);
             }
           }
-
           shapeData.shape.paths = localShapeCollection;
         }
       }
@@ -5656,38 +4757,29 @@
       }
     }
   };
-
   TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
     var i;
     var len = newPaths.length;
-
     for (i = 0; i < len; i += 1) {
       localShapeCollection.addShape(newPaths[i]);
     }
   };
-
   TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
     shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
     shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
     }
-
     shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
     shapePath.setXYAt(points[1], points[5], 'o', pos);
     shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(points[0], points[4], 'v', pos);
     }
-
     shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
     var pathsData = shapeData.pathsData;
     var shapePaths = shapeData.shape.paths.shapes;
@@ -5703,7 +4795,6 @@
     var shapes = [];
     var initPos;
     var newShape = true;
-
     if (!shapePath) {
       shapePath = shapePool.newElement();
       segmentCount = 0;
@@ -5712,17 +4803,13 @@
       segmentCount = shapePath._length;
       initPos = shapePath._length;
     }
-
     shapes.push(shapePath);
-
     for (i = 0; i < len; i += 1) {
       lengths = pathsData[i].lengths;
       shapePath.c = shapePaths[i].c;
       jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
-
       for (j = 1; j < jLen; j += 1) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
           addedLength += currentLengthData.addedLength;
           shapePath.c = false;
@@ -5735,50 +4822,42 @@
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
-
           addedLength += currentLengthData.addedLength;
           segmentCount += 1;
         }
       }
-
       if (shapePaths[i].c && lengths.length) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength <= shapeSegment.e) {
           var segmentLength = lengths[j - 1].addedLength;
-
           if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
             this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
         } else {
           shapePath.c = false;
         }
-
         addedLength += currentLengthData.addedLength;
         segmentCount += 1;
       }
-
       if (shapePath._length) {
         shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
         shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
       }
-
       if (addedLength > shapeSegment.e) {
         break;
       }
-
       if (i < len - 1) {
         shapePath = shapePool.newElement();
         newShape = true;
@@ -5786,31 +4865,25 @@
         segmentCount = 0;
       }
     }
-
     return shapes;
   };
 
   function PuckerAndBloatModifier() {}
-
   extendPrototype([ShapeModifier], PuckerAndBloatModifier);
-
   PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
     this._isAnimated = !!this.amount.effectsSequence.length;
   };
-
   PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
     var percent = amount / 100;
     var centerPoint = [0, 0];
     var pathLength = path._length;
     var i = 0;
-
     for (i = 0; i < pathLength; i += 1) {
       centerPoint[0] += path.v[i][0];
       centerPoint[1] += path.v[i][1];
     }
-
     centerPoint[0] /= pathLength;
     centerPoint[1] /= pathLength;
     var clonedPath = shapePool.newElement();
@@ -5821,7 +4894,6 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < pathLength; i += 1) {
       vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
       vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
@@ -5831,10 +4903,8 @@
       iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
       clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
     }
-
     return clonedPath;
   };
-
   PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -5842,30 +4912,24 @@
     var j;
     var jLen;
     var amount = this.amount.v;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -5873,30 +4937,24 @@
 
   var TransformPropertyFactory = function () {
     var defaultVector = [0, 0];
-
     function applyToMatrix(mat) {
       var _mdf = this._mdf;
       this.iterateDynamicProperties();
       this._mdf = this._mdf || _mdf;
-
       if (this.a) {
         mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
       }
-
       if (this.s) {
         mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
       }
-
       if (this.sk) {
         mat.skewFromAxis(-this.sk.v, this.sa.v);
       }
-
       if (this.r) {
         mat.rotate(-this.r.v);
       } else {
         mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
       }
-
       if (this.data.p.s) {
         if (this.data.p.z) {
           mat.translate(this.px.v, this.py.v, -this.pz.v);
@@ -5907,46 +4965,36 @@
         mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
       }
     }
-
     function processKeys(forceRender) {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (this._isDirty) {
         this.precalculateMatrix();
         this._isDirty = false;
       }
-
       this.iterateDynamicProperties();
-
       if (this._mdf || forceRender) {
         var frameRate;
         this.v.cloneFromProps(this.pre.props);
-
         if (this.appliedTransformations < 1) {
           this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         }
-
         if (this.appliedTransformations < 2) {
           this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         }
-
         if (this.sk && this.appliedTransformations < 3) {
           this.v.skewFromAxis(-this.sk.v, this.sa.v);
         }
-
         if (this.r && this.appliedTransformations < 4) {
           this.v.rotate(-this.r.v);
         } else if (!this.r && this.appliedTransformations < 4) {
           this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
         }
-
         if (this.autoOriented) {
           var v1;
           var v2;
           frameRate = this.elem.globalData.frameRate;
-
           if (this.p && this.p.keyframes && this.p.getValueAtTime) {
             if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
               v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
@@ -5963,7 +5011,6 @@
             v2 = [];
             var px = this.px;
             var py = this.py;
-
             if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
               v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
               v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
@@ -5983,10 +5030,8 @@
             v2 = defaultVector;
             v1 = v2;
           }
-
           this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
         }
-
         if (this.data.p && this.data.p.s) {
           if (this.data.p.z) {
             this.v.translate(this.px.v, this.py.v, -this.pz.v);
@@ -5997,28 +5042,23 @@
           this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
         }
       }
-
       this.frameId = this.elem.globalData.frameId;
     }
-
     function precalculateMatrix() {
       this.appliedTransformations = 0;
       this.pre.reset();
-
       if (!this.a.effectsSequence.length) {
         this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         this.appliedTransformations = 1;
       } else {
         return;
       }
-
       if (!this.s.effectsSequence.length) {
         this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         this.appliedTransformations = 2;
       } else {
         return;
       }
-
       if (this.sk) {
         if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
           this.pre.skewFromAxis(-this.sk.v, this.sa.v);
@@ -6027,7 +5067,6 @@
           return;
         }
       }
-
       if (this.r) {
         if (!this.r.effectsSequence.length) {
           this.pre.rotate(-this.r.v);
@@ -6038,33 +5077,28 @@
         this.appliedTransformations = 4;
       }
     }
-
-    function autoOrient() {//
+    function autoOrient() {
+      //
       // var prevP = this.getValueAtTime();
     }
-
     function addDynamicProperty(prop) {
       this._addDynamicProperty(prop);
-
       this.elem.addDynamicProperty(prop);
       this._isDirty = true;
     }
-
     function TransformProperty(elem, data, container) {
       this.elem = elem;
       this.frameId = -1;
       this.propType = 'transform';
       this.data = data;
-      this.v = new Matrix(); // Precalculated matrix with non animated properties
-
+      this.v = new Matrix();
+      // Precalculated matrix with non animated properties
       this.pre = new Matrix();
       this.appliedTransformations = 0;
       this.initDynamicPropertyContainer(container || elem);
-
       if (data.p && data.p.s) {
         this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
         this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
-
         if (data.p.z) {
           this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
         }
@@ -6073,43 +5107,37 @@
           k: [0, 0, 0]
         }, 1, 0, this);
       }
-
       if (data.rx) {
         this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
         this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
         this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
-
         if (data.or.k[0].ti) {
           var i;
           var len = data.or.k.length;
-
           for (i = 0; i < len; i += 1) {
             data.or.k[i].to = null;
             data.or.k[i].ti = null;
           }
         }
-
-        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this); // sh Indicates it needs to be capped between -180 and 180
-
+        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+        // sh Indicates it needs to be capped between -180 and 180
         this.or.sh = true;
       } else {
         this.r = PropertyFactory.getProp(elem, data.r || {
           k: 0
         }, 0, degToRads, this);
       }
-
       if (data.sk) {
         this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
         this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
       }
-
       this.a = PropertyFactory.getProp(elem, data.a || {
         k: [0, 0, 0]
       }, 1, 0, this);
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: [100, 100, 100]
-      }, 1, 0.01, this); // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
-
+      }, 1, 0.01, this);
+      // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
       if (data.o) {
         this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
       } else {
@@ -6118,14 +5146,11 @@
           v: 1
         };
       }
-
       this._isDirty = true;
-
       if (!this.dynamicProperties.length) {
         this.getValue(true);
       }
     }
-
     TransformProperty.prototype = {
       applyToMatrix: applyToMatrix,
       getValue: processKeys,
@@ -6135,20 +5160,16 @@
     extendPrototype([DynamicPropertyContainer], TransformProperty);
     TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
     TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
-
     function getTransformProperty(elem, data, container) {
       return new TransformProperty(elem, data, container);
     }
-
     return {
       getTransformProperty: getTransformProperty
     };
   }();
 
   function RepeaterModifier() {}
-
   extendPrototype([ShapeModifier], RepeaterModifier);
-
   RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
@@ -6157,11 +5178,9 @@
     this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
     this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
     this.data = data;
-
     if (!this.dynamicProperties.length) {
       this.getValue(true);
     }
-
     this._isAnimated = !!this.dynamicProperties.length;
     this.pMatrix = new Matrix();
     this.rMatrix = new Matrix();
@@ -6169,7 +5188,6 @@
     this.tMatrix = new Matrix();
     this.matrix = new Matrix();
   };
-
   RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
     var dir = inv ? -1 : 1;
     var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
@@ -6182,7 +5200,6 @@
     sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
     sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
   };
-
   RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
     this.elem = elem;
     this.arr = arr;
@@ -6194,52 +5211,42 @@
     this.frameId = -1;
     this.initDynamicPropertyContainer(elem);
     this.initModifierProperties(elem, arr[pos]);
-
     while (pos > 0) {
-      pos -= 1; // this._elements.unshift(arr.splice(pos,1)[0]);
-
+      pos -= 1;
+      // this._elements.unshift(arr.splice(pos,1)[0]);
       this._elements.unshift(arr[pos]);
     }
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   RepeaterModifier.prototype.resetElements = function (elements) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._processed = false;
-
       if (elements[i].ty === 'gr') {
         this.resetElements(elements[i].it);
       }
     }
   };
-
   RepeaterModifier.prototype.cloneElements = function (elements) {
     var newElements = JSON.parse(JSON.stringify(elements));
     this.resetElements(newElements);
     return newElements;
   };
-
   RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._render = renderFlag;
-
       if (elements[i].ty === 'gr') {
         this.changeGroupRender(elements[i].it, renderFlag);
       }
     }
   };
-
   RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
     var items;
     var itemsTransform;
@@ -6247,10 +5254,8 @@
     var dir;
     var cont;
     var hasReloaded = false;
-
     if (this._mdf || _isFirstFrame) {
       var copies = Math.ceil(this.c.v);
-
       if (this._groups.length < copies) {
         while (this._groups.length < copies) {
           var group = {
@@ -6305,28 +5310,21 @@
             ty: 'tr'
           });
           this.arr.splice(0, 0, group);
-
           this._groups.splice(0, 0, group);
-
           this._currentCopies += 1;
         }
-
         this.elem.reloadShapes();
         hasReloaded = true;
       }
-
       cont = 0;
       var renderFlag;
-
       for (i = 0; i <= this._groups.length - 1; i += 1) {
         renderFlag = cont < copies;
         this._groups[i]._render = renderFlag;
         this.changeGroupRender(this._groups[i].it, renderFlag);
-
         if (!renderFlag) {
           var elems = this.elemsData[i].it;
           var transformData = elems[elems.length - 1];
-
           if (transformData.transform.op.v !== 0) {
             transformData.transform.op._mdf = true;
             transformData.transform.op.v = 0;
@@ -6334,11 +5332,10 @@
             transformData.transform.op._mdf = false;
           }
         }
-
         cont += 1;
       }
-
-      this._currentCopies = copies; /// /
+      this._currentCopies = copies;
+      /// /
 
       var offset = this.o.v;
       var offsetModulo = offset % 1;
@@ -6352,13 +5349,11 @@
       this.tMatrix.reset();
       this.matrix.reset();
       var iteration = 0;
-
       if (offset > 0) {
         while (iteration < roundOffset) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           iteration += 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
           iteration += offsetModulo;
@@ -6368,19 +5363,16 @@
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
           iteration -= 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
           iteration -= offsetModulo;
         }
       }
-
       i = this.data.m === 1 ? 0 : this._currentCopies - 1;
       dir = this.data.m === 1 ? 1 : -1;
       cont = this._currentCopies;
       var j;
       var jLen;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6388,29 +5380,23 @@
         items[items.length - 1].transform.mProps._mdf = true;
         items[items.length - 1].transform.op._mdf = true;
         items[items.length - 1].transform.op.v = this._currentCopies === 1 ? this.so.v : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
-
         if (iteration !== 0) {
           if (i !== 0 && dir === 1 || i !== this._currentCopies - 1 && dir === -1) {
             this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           }
-
           this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
           this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
           this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
-
           this.matrix.reset();
         } else {
           this.matrix.reset();
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
         }
-
         iteration += 1;
         cont -= 1;
         i += dir;
@@ -6419,7 +5405,6 @@
       cont = this._currentCopies;
       i = 0;
       dir = 1;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6429,22 +5414,17 @@
         i += dir;
       }
     }
-
     return hasReloaded;
   };
-
   RepeaterModifier.prototype.addShape = function () {};
 
   function RoundCornersModifier() {}
-
   extendPrototype([ShapeModifier], RoundCornersModifier);
-
   RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
     this._isAnimated = !!this.rd.effectsSequence.length;
   };
-
   RoundCornersModifier.prototype.processPath = function (path, round) {
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
@@ -6463,19 +5443,16 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < len; i += 1) {
       currentV = path.v[i];
       currentO = path.o[i];
       currentI = path.i[i];
-
       if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
         if ((i === 0 || i === len - 1) && !path.c) {
           clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
           /* clonedPath.v[index] = currentV;
                   clonedPath.o[index] = currentO;
                   clonedPath.i[index] = currentI; */
-
           index += 1;
         } else {
           if (i === 0) {
@@ -6483,7 +5460,6 @@
           } else {
             closerV = path.v[i - 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6494,13 +5470,11 @@
           oY = vY - (vY - currentV[1]) * roundCorner;
           clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
           index += 1;
-
           if (i === len - 1) {
             closerV = path.v[0];
           } else {
             closerV = path.v[i + 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6517,10 +5491,8 @@
         index += 1;
       }
     }
-
     return clonedPath;
   };
-
   RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6528,30 +5500,24 @@
     var j;
     var jLen;
     var rd = this.rd.v;
-
     if (rd !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6560,50 +5526,41 @@
   function floatEqual(a, b) {
     return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
   }
-
   function floatZero(f) {
     return Math.abs(f) <= 0.00001;
   }
-
   function lerp(p0, p1, amount) {
     return p0 * (1 - amount) + p1 * amount;
   }
-
   function lerpPoint(p0, p1, amount) {
     return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
   }
-
   function quadRoots(a, b, c) {
     // no root
     if (a === 0) return [];
-    var s = b * b - 4 * a * c; // Complex roots
-
+    var s = b * b - 4 * a * c;
+    // Complex roots
     if (s < 0) return [];
-    var singleRoot = -b / (2 * a); // 1 root
-
+    var singleRoot = -b / (2 * a);
+    // 1 root
     if (s === 0) return [singleRoot];
-    var delta = Math.sqrt(s) / (2 * a); // 2 roots
-
+    var delta = Math.sqrt(s) / (2 * a);
+    // 2 roots
     return [singleRoot - delta, singleRoot + delta];
   }
-
   function polynomialCoefficients(p0, p1, p2, p3) {
     return [-p0 + 3 * p1 - 3 * p2 + p3, 3 * p0 - 6 * p1 + 3 * p2, -3 * p0 + 3 * p1, p0];
   }
-
   function singlePoint(p) {
     return new PolynomialBezier(p, p, p, p, false);
   }
-
   function PolynomialBezier(p0, p1, p2, p3, linearize) {
     if (linearize && pointEqual(p0, p1)) {
       p1 = lerpPoint(p0, p3, 1 / 3);
     }
-
     if (linearize && pointEqual(p2, p3)) {
       p2 = lerpPoint(p0, p3, 2 / 3);
     }
-
     var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
     var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
     this.a = [coeffx[0], coeffy[0]];
@@ -6612,25 +5569,20 @@
     this.d = [coeffx[3], coeffy[3]];
     this.points = [p0, p1, p2, p3];
   }
-
   PolynomialBezier.prototype.point = function (t) {
     return [((this.a[0] * t + this.b[0]) * t + this.c[0]) * t + this.d[0], ((this.a[1] * t + this.b[1]) * t + this.c[1]) * t + this.d[1]];
   };
-
   PolynomialBezier.prototype.derivative = function (t) {
     return [(3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0], (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1]];
   };
-
   PolynomialBezier.prototype.tangentAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[1], p[0]);
   };
-
   PolynomialBezier.prototype.normalAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[0], p[1]);
   };
-
   PolynomialBezier.prototype.inflectionPoints = function () {
     var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
     if (floatZero(denom)) return [];
@@ -6638,17 +5590,14 @@
     var square = tcusp * tcusp - 1 / 3 * (this.b[1] * this.c[0] - this.b[0] * this.c[1]) / denom;
     if (square < 0) return [];
     var root = Math.sqrt(square);
-
     if (floatZero(root)) {
       if (root > 0 && root < 1) return [tcusp];
       return [];
     }
-
     return [tcusp - root, tcusp + root].filter(function (r) {
       return r > 0 && r < 1;
     });
   };
-
   PolynomialBezier.prototype.split = function (t) {
     if (t <= 0) return [singlePoint(this.points[0]), this];
     if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
@@ -6660,40 +5609,33 @@
     var p3 = lerpPoint(p20, p21, t);
     return [new PolynomialBezier(this.points[0], p10, p20, p3, true), new PolynomialBezier(p3, p21, p12, this.points[3], true)];
   };
-
   function extrema(bez, comp) {
     var min = bez.points[0][comp];
     var max = bez.points[bez.points.length - 1][comp];
-
     if (min > max) {
       var e = max;
       max = min;
       min = e;
-    } // Derivative roots to find min/max
-
-
+    }
+    // Derivative roots to find min/max
     var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
-
     for (var i = 0; i < f.length; i += 1) {
       if (f[i] > 0 && f[i] < 1) {
         var val = bez.point(f[i])[comp];
         if (val < min) min = val;else if (val > max) max = val;
       }
     }
-
     return {
       min: min,
       max: max
     };
   }
-
   PolynomialBezier.prototype.bounds = function () {
     return {
       x: extrema(this, 0),
       y: extrema(this, 1)
     };
   };
-
   PolynomialBezier.prototype.boundingBox = function () {
     var bounds = this.bounds();
     return {
@@ -6707,7 +5649,6 @@
       cy: (bounds.y.max + bounds.y.min) / 2
     };
   };
-
   function intersectData(bez, t1, t2) {
     var box = bez.boundingBox();
     return {
@@ -6721,24 +5662,19 @@
       t2: t2
     };
   }
-
   function splitData(data) {
     var split = data.bez.split(0.5);
     return [intersectData(split[0], data.t1, data.t), intersectData(split[1], data.t, data.t2)];
   }
-
   function boxIntersect(b1, b2) {
     return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
   }
-
   function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
     if (!boxIntersect(d1, d2)) return;
-
     if (depth >= maxRecursion || d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance) {
       intersections.push([d1.t, d2.t]);
       return;
     }
-
     var d1s = splitData(d1);
     var d2s = splitData(d2);
     intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
@@ -6746,7 +5682,6 @@
     intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
     intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
   }
-
   PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
     if (tolerance === undefined) tolerance = 2;
     if (maxRecursion === undefined) maxRecursion = 7;
@@ -6754,21 +5689,17 @@
     intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
     return intersections;
   };
-
   PolynomialBezier.shapeSegment = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
   };
-
   PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
   };
-
   function crossProduct(a, b) {
     return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
   }
-
   function lineIntersection(start1, end1, start2, end2) {
     var v1 = [start1[0], start1[1], 1];
     var v2 = [end1[0], end1[1], 1];
@@ -6778,23 +5709,18 @@
     if (floatZero(r[2])) return null;
     return [r[0] / r[2], r[1] / r[2]];
   }
-
   function polarOffset(p, angle, length) {
     return [p[0] + Math.cos(angle) * length, p[1] - Math.sin(angle) * length];
   }
-
   function pointDistance(p1, p2) {
     return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
   }
-
   function pointEqual(p1, p2) {
     return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
   }
 
   function ZigZagModifier() {}
-
   extendPrototype([ShapeModifier], ZigZagModifier);
-
   ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
@@ -6802,7 +5728,6 @@
     this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
     this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
   };
-
   function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
     var angO = angle - Math.PI / 2;
     var angI = angle + Math.PI / 2;
@@ -6810,14 +5735,12 @@
     var py = point[1] - Math.sin(angle) * direction * amplitude;
     outputBezier.setTripleAt(px, py, px + Math.cos(angO) * outAmplitude, py - Math.sin(angO) * outAmplitude, px + Math.cos(angI) * inAmplitude, py - Math.sin(angI) * inAmplitude, outputBezier.length());
   }
-
   function getPerpendicularVector(pt1, pt2) {
     var vector = [pt2[0] - pt1[0], pt2[1] - pt1[1]];
     var rot = -Math.PI * 0.5;
     var rotatedVector = [Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1], Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1]];
     return rotatedVector;
   }
-
   function getProjectingAngle(path, cur) {
     var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
     var nextIndex = (cur + 1) % path.length();
@@ -6826,7 +5749,6 @@
     var pVector = getPerpendicularVector(prevPoint, nextPoint);
     return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
   }
-
   function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
     var angle = getProjectingAngle(path, cur);
     var point = path.v[cur % path._length];
@@ -6836,7 +5758,6 @@
     var nextDist = pointType === 2 ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2)) : 0;
     setPoint(outputBezier, path.v[cur % path._length], angle, direction, amplitude, nextDist / ((frequency + 1) * 2), prevDist / ((frequency + 1) * 2), pointType);
   }
-
   function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
     for (var i = 0; i < frequency; i += 1) {
       var t = (i + 1) / (frequency + 1);
@@ -6846,39 +5767,30 @@
       setPoint(outputBezier, point, angle, direction, amplitude, dist / ((frequency + 1) * 2), dist / ((frequency + 1) * 2), pointType);
       direction = -direction;
     }
-
     return direction;
   }
-
   ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
     var count = path._length;
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
-
     if (!path.c) {
       count -= 1;
     }
-
     if (count === 0) return clonedPath;
     var direction = -1;
     var segment = PolynomialBezier.shapeSegment(path, 0);
     zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
-
     for (var i = 0; i < count; i += 1) {
       direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
-
       if (i === count - 1 && !path.c) {
         segment = null;
       } else {
         segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
       }
-
       zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
     }
-
     return clonedPath;
   };
-
   ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6888,30 +5800,24 @@
     var amplitude = this.amplitude.v;
     var frequency = Math.max(0, Math.round(this.frequency.v));
     var pointType = this.pointsType.v;
-
     if (amplitude !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6921,7 +5827,6 @@
     var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
     return [polarOffset(p1, angle, amount), polarOffset(p2, angle, amount)];
   }
-
   function offsetSegment(segment, amount) {
     var p0;
     var p1a;
@@ -6945,15 +5850,17 @@
     if (p2 === null) p2 = p2a;
     return new PolynomialBezier(p0, p1, p2, p3);
   }
-
   function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
     var p0 = seg1.points[3];
-    var p1 = seg2.points[0]; // Bevel
+    var p1 = seg2.points[0];
 
-    if (lineJoin === 3) return p0; // Connected, they don't need a joint
+    // Bevel
+    if (lineJoin === 3) return p0;
 
-    if (pointEqual(p0, p1)) return p0; // Round
+    // Connected, they don't need a joint
+    if (pointEqual(p0, p1)) return p0;
 
+    // Round
     if (lineJoin === 2) {
       var angleOut = -seg1.tangentAngle(1);
       var angleIn = -seg2.tangentAngle(0) + Math.PI;
@@ -6964,91 +5871,75 @@
       tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
       outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
       return p1;
-    } // Miter
+    }
 
-
+    // Miter
     var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
     var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
     var intersection = lineIntersection(t0, p0, p1, t1);
-
     if (intersection && pointDistance(intersection, p0) < miterLimit) {
       outputBezier.setTripleAt(intersection[0], intersection[1], intersection[0], intersection[1], intersection[0], intersection[1], outputBezier.length());
       return intersection;
     }
-
     return p0;
   }
-
   function getIntersection(a, b) {
     var intersect = a.intersections(b);
     if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
     if (intersect.length) return intersect[0];
     return null;
   }
-
   function pruneSegmentIntersection(a, b) {
     var outa = a.slice();
     var outb = b.slice();
     var intersect = getIntersection(a[a.length - 1], b[0]);
-
     if (intersect) {
       outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
       outb[0] = b[0].split(intersect[1])[1];
     }
-
     if (a.length > 1 && b.length > 1) {
       intersect = getIntersection(a[0], b[b.length - 1]);
-
       if (intersect) {
         return [[a[0].split(intersect[0])[0]], [b[b.length - 1].split(intersect[1])[1]]];
       }
     }
-
     return [outa, outb];
   }
-
   function pruneIntersections(segments) {
     var e;
-
     for (var i = 1; i < segments.length; i += 1) {
       e = pruneSegmentIntersection(segments[i - 1], segments[i]);
       segments[i - 1] = e[0];
       segments[i] = e[1];
     }
-
     if (segments.length > 1) {
       e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
       segments[segments.length - 1] = e[0];
       segments[0] = e[1];
     }
-
     return segments;
   }
-
   function offsetSegmentSplit(segment, amount) {
     /*
       We split each bezier segment into smaller pieces based
       on inflection points, this ensures the control point
       polygon is convex.
-        (A cubic bezier can have none, one, or two inflection points)
+       (A cubic bezier can have none, one, or two inflection points)
     */
     var flex = segment.inflectionPoints();
     var left;
     var right;
     var split;
     var mid;
-
     if (flex.length === 0) {
       return [offsetSegment(segment, amount)];
     }
-
     if (flex.length === 1 || floatEqual(flex[1], 1)) {
       split = segment.split(flex[0]);
       left = split[0];
       right = split[1];
       return [offsetSegment(left, amount), offsetSegment(right, amount)];
     }
-
     split = segment.split(flex[0]);
     left = split[0];
     var t = (flex[1] - flex[0]) / (1 - flex[0]);
@@ -7057,11 +5948,8 @@
     right = split[1];
     return [offsetSegment(left, amount), offsetSegment(mid, amount), offsetSegment(right, amount)];
   }
-
   function OffsetPathModifier() {}
-
   extendPrototype([ShapeModifier], OffsetPathModifier);
-
   OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
@@ -7069,61 +5957,50 @@
     this.lineJoin = data.lj;
     this._isAnimated = this.amount.effectsSequence.length !== 0;
   };
-
   OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
     var outputBezier = shapePool.newElement();
     outputBezier.c = inputBezier.c;
     var count = inputBezier.length();
-
     if (!inputBezier.c) {
       count -= 1;
     }
-
     var i;
     var j;
     var segment;
     var multiSegments = [];
-
     for (i = 0; i < count; i += 1) {
       segment = PolynomialBezier.shapeSegment(inputBezier, i);
       multiSegments.push(offsetSegmentSplit(segment, amount));
     }
-
     if (!inputBezier.c) {
       for (i = count - 1; i >= 0; i -= 1) {
         segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
         multiSegments.push(offsetSegmentSplit(segment, amount));
       }
     }
+    multiSegments = pruneIntersections(multiSegments);
 
-    multiSegments = pruneIntersections(multiSegments); // Add bezier segments to the output and apply line joints
-
+    // Add bezier segments to the output and apply line joints
     var lastPoint = null;
     var lastSeg = null;
-
     for (i = 0; i < multiSegments.length; i += 1) {
       var multiSegment = multiSegments[i];
       if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
       lastSeg = multiSegment[multiSegment.length - 1];
-
       for (j = 0; j < multiSegment.length; j += 1) {
         segment = multiSegment[j];
-
         if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
           outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
         } else {
           outputBezier.setTripleAt(segment.points[0][0], segment.points[0][1], segment.points[1][0], segment.points[1][1], segment.points[0][0], segment.points[0][1], outputBezier.length());
         }
-
         outputBezier.setTripleAt(segment.points[3][0], segment.points[3][1], segment.points[3][0], segment.points[3][1], segment.points[2][0], segment.points[2][1], outputBezier.length());
         lastPoint = segment.points[3];
       }
     }
-
     if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
     return outputBezier;
   };
-
   OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -7133,30 +6010,24 @@
     var amount = this.amount.v;
     var miterLimit = this.miterLimit.v;
     var lineJoin = this.lineJoin;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -7168,42 +6039,33 @@
     var fStyle = 'normal';
     var len = styles.length;
     var styleName;
-
     for (var i = 0; i < len; i += 1) {
       styleName = styles[i].toLowerCase();
-
       switch (styleName) {
         case 'italic':
           fStyle = 'italic';
           break;
-
         case 'bold':
           fWeight = '700';
           break;
-
         case 'black':
           fWeight = '900';
           break;
-
         case 'medium':
           fWeight = '500';
           break;
-
         case 'regular':
         case 'normal':
           fWeight = '400';
           break;
-
         case 'light':
         case 'thin':
           fWeight = '200';
           break;
-
         default:
           break;
       }
     }
-
     return {
       style: fStyle,
       weight: fontData.fWeight || fWeight
@@ -7220,8 +6082,8 @@
         shapes: []
       }
     };
-    var combinedCharacters = []; // Hindi characters
-
+    var combinedCharacters = [];
+    // Hindi characters
     combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
     var BLACK_FLAG_CODE_POINT = 127988;
     var CANCEL_TAG_CODE_POINT = 917631;
@@ -7232,44 +6094,41 @@
     var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
     var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
     var surrogateModifiers = ['d83cdffb', 'd83cdffc', 'd83cdffd', 'd83cdffe', 'd83cdfff'];
-
     function trimFontOptions(font) {
       var familyArray = font.split(',');
       var i;
       var len = familyArray.length;
       var enabledFamilies = [];
-
       for (i = 0; i < len; i += 1) {
         if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
           enabledFamilies.push(familyArray[i]);
         }
       }
-
       return enabledFamilies.join(',');
     }
-
     function setUpNode(font, family) {
-      var parentNode = createTag('span'); // Node is invisible to screen readers.
-
+      var parentNode = createTag('span');
+      // Node is invisible to screen readers.
       parentNode.setAttribute('aria-hidden', true);
       parentNode.style.fontFamily = family;
-      var node = createTag('span'); // Characters that vary significantly among different fonts
-
-      node.innerText = 'giItT1WQy@!-/#'; // Visible - so we can measure it - but not on the screen
-
+      var node = createTag('span');
+      // Characters that vary significantly among different fonts
+      node.innerText = 'giItT1WQy@!-/#';
+      // Visible - so we can measure it - but not on the screen
       parentNode.style.position = 'absolute';
       parentNode.style.left = '-10000px';
-      parentNode.style.top = '-10000px'; // Large font size makes even subtle changes obvious
-
-      parentNode.style.fontSize = '300px'; // Reset any font properties
-
+      parentNode.style.top = '-10000px';
+      // Large font size makes even subtle changes obvious
+      parentNode.style.fontSize = '300px';
+      // Reset any font properties
       parentNode.style.fontVariant = 'normal';
       parentNode.style.fontStyle = 'normal';
       parentNode.style.fontWeight = 'normal';
       parentNode.style.letterSpacing = '0';
       parentNode.appendChild(node);
-      document.body.appendChild(parentNode); // Remember width with no applied web font
+      document.body.appendChild(parentNode);
 
+      // Remember width with no applied web font
       var width = node.offsetWidth;
       node.style.fontFamily = trimFontOptions(font) + ', ' + family;
       return {
@@ -7278,14 +6137,12 @@
         parent: parentNode
       };
     }
-
     function checkLoadedFonts() {
       var i;
       var len = this.fonts.length;
       var node;
       var w;
       var loadedCount = len;
-
       for (i = 0; i < len; i += 1) {
         if (this.fonts[i].loaded) {
           loadedCount -= 1;
@@ -7294,55 +6151,47 @@
         } else {
           node = this.fonts[i].monoCase.node;
           w = this.fonts[i].monoCase.w;
-
           if (node.offsetWidth !== w) {
             loadedCount -= 1;
             this.fonts[i].loaded = true;
           } else {
             node = this.fonts[i].sansCase.node;
             w = this.fonts[i].sansCase.w;
-
             if (node.offsetWidth !== w) {
               loadedCount -= 1;
               this.fonts[i].loaded = true;
             }
           }
-
           if (this.fonts[i].loaded) {
             this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
             this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
           }
         }
       }
-
       if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
         setTimeout(this.checkLoadedFontsBinded, 20);
       } else {
         setTimeout(this.setIsLoadedBinded, 10);
       }
     }
-
     function createHelper(fontData, def) {
       var engine = document.body && def ? 'svg' : 'canvas';
       var helper;
       var fontProps = getFontProperties(fontData);
-
       if (engine === 'svg') {
         var tHelper = createNS('text');
-        tHelper.style.fontSize = '100px'; // tHelper.style.fontFamily = fontData.fFamily;
-
+        tHelper.style.fontSize = '100px';
+        // tHelper.style.fontFamily = fontData.fFamily;
         tHelper.setAttribute('font-family', fontData.fFamily);
         tHelper.setAttribute('font-style', fontProps.style);
         tHelper.setAttribute('font-weight', fontProps.weight);
         tHelper.textContent = '1';
-
         if (fontData.fClass) {
           tHelper.style.fontFamily = 'inherit';
           tHelper.setAttribute('class', fontData.fClass);
         } else {
           tHelper.style.fontFamily = fontData.fFamily;
         }
-
         def.appendChild(tHelper);
         helper = tHelper;
       } else {
@@ -7350,33 +6199,27 @@
         tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
         helper = tCanvasHelper;
       }
-
       function measure(text) {
         if (engine === 'svg') {
           helper.textContent = text;
           return helper.getComputedTextLength();
         }
-
         return helper.measureText(text).width;
       }
-
       return {
         measureText: measure
       };
     }
-
     function addFonts(fontData, defs) {
       if (!fontData) {
         this.isLoaded = true;
         return;
       }
-
       if (this.chars) {
         this.isLoaded = true;
         this.fonts = fontData.list;
         return;
       }
-
       if (!document.body) {
         this.isLoaded = true;
         fontData.list.forEach(function (data) {
@@ -7386,12 +6229,10 @@
         this.fonts = fontData.list;
         return;
       }
-
       var fontArr = fontData.list;
       var i;
       var len = fontArr.length;
       var _pendingFonts = len;
-
       for (i = 0; i < len; i += 1) {
         var shouldLoadFont = true;
         var loadedSelector;
@@ -7399,17 +6240,14 @@
         fontArr[i].loaded = false;
         fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
         fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
-
         if (!fontArr[i].fPath) {
           fontArr[i].loaded = true;
           _pendingFonts -= 1;
         } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
           loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
-
           if (loadedSelector.length > 0) {
             shouldLoadFont = false;
           }
-
           if (shouldLoadFont) {
             var s = createTag('style');
             s.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7421,14 +6259,12 @@
           }
         } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
           loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var l = createTag('link');
             l.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7440,14 +6276,12 @@
           }
         } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
           loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (fontArr[i].fPath === loadedSelector[j].src) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var sc = createTag('link');
             sc.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7457,12 +6291,10 @@
             defs.appendChild(sc);
           }
         }
-
         fontArr[i].helper = createHelper(fontArr[i], defs);
         fontArr[i].cache = {};
         this.fonts.push(fontArr[i]);
       }
-
       if (_pendingFonts === 0) {
         this.isLoaded = true;
       } else {
@@ -7471,71 +6303,56 @@
         setTimeout(this.checkLoadedFonts.bind(this), 100);
       }
     }
-
     function addChars(chars) {
       if (!chars) {
         return;
       }
-
       if (!this.chars) {
         this.chars = [];
       }
-
       var i;
       var len = chars.length;
       var j;
       var jLen = this.chars.length;
       var found;
-
       for (i = 0; i < len; i += 1) {
         j = 0;
         found = false;
-
         while (j < jLen) {
           if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
             found = true;
           }
-
           j += 1;
         }
-
         if (!found) {
           this.chars.push(chars[i]);
           jLen += 1;
         }
       }
     }
-
     function getCharData(_char, style, font) {
       var i = 0;
       var len = this.chars.length;
-
       while (i < len) {
         if (this.chars[i].ch === _char && this.chars[i].style === style && this.chars[i].fFamily === font) {
           return this.chars[i];
         }
-
         i += 1;
       }
-
       if ((typeof _char === 'string' && _char.charCodeAt(0) !== 13 || !_char) && console && console.warn // eslint-disable-line no-console
       && !this._warned) {
         this._warned = true;
         console.warn('Missing character from exported characters list: ', _char, style, font); // eslint-disable-line no-console
       }
-
       return emptyChar;
     }
-
     function measureText(_char2, fontName, size) {
-      var fontData = this.getFontByName(fontName); // Using the char instead of char.charCodeAt(0)
+      var fontData = this.getFontByName(fontName);
+      // Using the char instead of char.charCodeAt(0)
       // to avoid collisions between equal chars
-
       var index = _char2;
-
       if (!fontData.cache[index]) {
         var tHelper = fontData.helper;
-
         if (_char2 === ' ') {
           var doubleSize = tHelper.measureText('|' + _char2 + '|');
           var singleSize = tHelper.measureText('||');
@@ -7544,111 +6361,90 @@
           fontData.cache[index] = tHelper.measureText(_char2) / 100;
         }
       }
-
       return fontData.cache[index] * size;
     }
-
     function getFontByName(name) {
       var i = 0;
       var len = this.fonts.length;
-
       while (i < len) {
         if (this.fonts[i].fName === name) {
           return this.fonts[i];
         }
-
         i += 1;
       }
-
       return this.fonts[0];
     }
-
     function getCodePoint(string) {
       var codePoint = 0;
       var first = string.charCodeAt(0);
-
       if (first >= 0xD800 && first <= 0xDBFF) {
         var second = string.charCodeAt(1);
-
         if (second >= 0xDC00 && second <= 0xDFFF) {
           codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
         }
       }
-
       return codePoint;
-    } // Skin tone modifiers
+    }
 
-
+    // Skin tone modifiers
     function isModifier(firstCharCode, secondCharCode) {
       var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
       return surrogateModifiers.indexOf(sum) !== -1;
     }
-
     function isZeroWidthJoiner(charCode) {
       return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
-    } // This codepoint may change the appearance of the preceding character.
+    }
+
+    // This codepoint may change the appearance of the preceding character.
     // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
     // as a colorful image as compared to a monochrome text variant.
-
-
     function isVariationSelector(charCode) {
       return charCode === VARIATION_SELECTOR_16_CODE_POINT;
-    } // The regional indicator symbols are a set of 26 alphabetic Unicode
+    }
+
+    // The regional indicator symbols are a set of 26 alphabetic Unicode
     /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
     // two-letter country codes in a way that allows optional special treatment.
-
-
     function isRegionalCode(string) {
       var codePoint = getCodePoint(string);
-
       if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
         return true;
       }
-
       return false;
-    } // Some Emoji implementations represent combinations of
+    }
+
+    // Some Emoji implementations represent combinations of
     // two “regional indicator” letters as a single flag symbol.
-
-
     function isFlagEmoji(string) {
       return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
     }
-
     function isCombinedCharacter(_char3) {
       return combinedCharacters.indexOf(_char3) !== -1;
-    } // Regional flags start with a BLACK_FLAG_CODE_POINT
+    }
+
+    // Regional flags start with a BLACK_FLAG_CODE_POINT
     // folowed by 5 chars in the TAG range
     // and end with a CANCEL_TAG_CODE_POINT
-
-
     function isRegionalFlag(text, index) {
       var codePoint = getCodePoint(text.substr(index, 2));
-
       if (codePoint !== BLACK_FLAG_CODE_POINT) {
         return false;
       }
-
       var count = 0;
       index += 2;
-
       while (count < 5) {
         codePoint = getCodePoint(text.substr(index, 2));
-
         if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
           return false;
         }
-
         count += 1;
         index += 2;
       }
-
       return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
     }
-
     function setIsLoaded() {
       this.isLoaded = true;
     }
-
     var Font = function Font() {
       this.fonts = [];
       this.chars = null;
@@ -7659,7 +6455,6 @@
       this.setIsLoadedBinded = this.setIsLoaded.bind(this);
       this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
     };
-
     Font.isModifier = isModifier;
     Font.isZeroWidthJoiner = isZeroWidthJoiner;
     Font.isFlagEmoji = isFlagEmoji;
@@ -7684,30 +6479,26 @@
   function SlotManager(animationData) {
     this.animationData = animationData;
   }
-
   SlotManager.prototype.getProp = function (data) {
     if (this.animationData.slots && this.animationData.slots[data.sid]) {
       return Object.assign(data, this.animationData.slots[data.sid].p);
     }
-
     return data;
   };
-
   function slotFactory(animationData) {
     return new SlotManager(animationData);
   }
 
   function RenderableElement() {}
-
   RenderableElement.prototype = {
     initRenderable: function initRenderable() {
       // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
-      this.isInRange = false; // layer's display state
-
-      this.hidden = false; // If layer's transparency equals 0, it can be hidden
-
-      this.isTransparent = false; // list of animated components
-
+      this.isInRange = false;
+      // layer's display state
+      this.hidden = false;
+      // If layer's transparency equals 0, it can be hidden
+      this.isTransparent = false;
+      // list of animated components
       this.renderableComponents = [];
     },
     addRenderableComponent: function addRenderableComponent(component) {
@@ -7734,7 +6525,6 @@
         this.show();
       }
     },
-
     /**
        * @function
        * Initializes frame related properties.
@@ -7760,13 +6550,11 @@
     renderRenderable: function renderRenderable() {
       var i;
       var len = this.renderableComponents.length;
-
       for (i = 0; i < len; i += 1) {
         this.renderableComponents[i].renderFrame(this._isFirstFrame);
       }
       /* this.maskManager.renderFrame(this.finalTransform.mat);
           this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
-
     },
     sourceRectAtTime: function sourceRectAtTime() {
       return {
@@ -7783,7 +6571,6 @@
           h: this.data.textData.height
         };
       }
-
       return {
         w: this.data.width,
         h: this.data.height
@@ -7818,31 +6605,24 @@
   function SliderEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function AngleEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function ColorEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function PointEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function LayerIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function MaskIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function CheckboxEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function NoValueEffect() {
     this.p = {};
   }
@@ -7853,20 +6633,16 @@
     var i;
     var len = effects.length;
     var effectItem;
-
     for (i = 0; i < len; i += 1) {
       effectItem = new GroupEffect(effects[i], element);
       this.effectElements.push(effectItem);
     }
   }
-
   function GroupEffect(data, element) {
     this.init(data, element);
   }
-
   extendPrototype([DynamicPropertyContainer], GroupEffect);
   GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
-
   GroupEffect.prototype.init = function (data, element) {
     this.data = data;
     this.effectElements = [];
@@ -7875,50 +6651,39 @@
     var len = this.data.ef.length;
     var eff;
     var effects = this.data.ef;
-
     for (i = 0; i < len; i += 1) {
       eff = null;
-
       switch (effects[i].ty) {
         case 0:
           eff = new SliderEffect(effects[i], element, this);
           break;
-
         case 1:
           eff = new AngleEffect(effects[i], element, this);
           break;
-
         case 2:
           eff = new ColorEffect(effects[i], element, this);
           break;
-
         case 3:
           eff = new PointEffect(effects[i], element, this);
           break;
-
         case 4:
         case 7:
           eff = new CheckboxEffect(effects[i], element, this);
           break;
-
         case 10:
           eff = new LayerIndexEffect(effects[i], element, this);
           break;
-
         case 11:
           eff = new MaskIndexEffect(effects[i], element, this);
           break;
-
         case 5:
           eff = new EffectsManager(effects[i], element, this);
           break;
         // case 6:
-
         default:
           eff = new NoValueEffect(effects[i], element, this);
           break;
       }
-
       if (eff) {
         this.effectElements.push(eff);
       }
@@ -7926,47 +6691,37 @@
   };
 
   function BaseElement() {}
-
   BaseElement.prototype = {
     checkMasks: function checkMasks() {
       if (!this.data.hasMask) {
         return false;
       }
-
       var i = 0;
       var len = this.data.masksProperties.length;
-
       while (i < len) {
         if (this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false) {
           return true;
         }
-
         i += 1;
       }
-
       return false;
     },
     initExpressions: function initExpressions() {
       var expressionsInterfaces = getExpressionInterfaces();
-
       if (!expressionsInterfaces) {
         return;
       }
-
       var LayerExpressionInterface = expressionsInterfaces('layer');
       var EffectsExpressionInterface = expressionsInterfaces('effects');
       var ShapeExpressionInterface = expressionsInterfaces('shape');
       var TextExpressionInterface = expressionsInterfaces('text');
       var CompExpressionInterface = expressionsInterfaces('comp');
       this.layerInterface = LayerExpressionInterface(this);
-
       if (this.data.hasMask && this.maskManager) {
         this.layerInterface.registerMaskInterface(this.maskManager);
       }
-
       var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
       this.layerInterface.registerEffectsInterface(effectsInterface);
-
       if (this.data.ty === 0 || this.data.xt) {
         this.compInterface = CompExpressionInterface(this);
       } else if (this.data.ty === 4) {
@@ -7986,13 +6741,13 @@
       this.globalData = globalData;
       this.comp = comp;
       this.data = data;
-      this.layerId = createElementID(); // Stretch factor for old animations missing this property.
+      this.layerId = createElementID();
 
+      // Stretch factor for old animations missing this property.
       if (!this.data.sr) {
         this.data.sr = 1;
-      } // effects manager
-
-
+      }
+      // effects manager
       this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
     },
     getType: function getType() {
@@ -8007,8 +6762,8 @@
    * Checks layer in point and out point
    *
    */
-  function FrameElement() {}
 
+  function FrameElement() {}
   FrameElement.prototype = {
     /**
        * @function
@@ -8017,13 +6772,12 @@
        */
     initFrame: function initFrame() {
       // set to true when inpoint is rendered
-      this._isFirstFrame = false; // list of animated properties
-
-      this.dynamicProperties = []; // If layer has been modified in current tick this will be true
-
+      this._isFirstFrame = false;
+      // list of animated properties
+      this.dynamicProperties = [];
+      // If layer has been modified in current tick this will be true
       this._mdf = false;
     },
-
     /**
        * @function
        * Calculates all dynamic values
@@ -8037,11 +6791,9 @@
     prepareProperties: function prepareProperties(num, isVisible) {
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         if (isVisible || this._isParent && this.dynamicProperties[i].propType === 'transform') {
           this.dynamicProperties[i].getValue();
-
           if (this.dynamicProperties[i]._mdf) {
             this.globalData._mdf = true;
             this._mdf = true;
@@ -8063,30 +6815,21 @@
     this.footageData = globalData.imageLoader.getAsset(this.assetData);
     this.initBaseData(data, globalData, comp);
   }
-
   FootageElement.prototype.prepareFrame = function () {};
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
-
   FootageElement.prototype.getBaseElement = function () {
     return null;
   };
-
   FootageElement.prototype.renderFrame = function () {};
-
   FootageElement.prototype.destroy = function () {};
-
   FootageElement.prototype.initExpressions = function () {
     var expressionsInterfaces = getExpressionInterfaces();
-
     if (!expressionsInterfaces) {
       return;
     }
-
     var FootageInterface = expressionsInterfaces('footage');
     this.layerInterface = FootageInterface(this);
   };
-
   FootageElement.prototype.getFootageData = function () {
     return this.footageData;
   };
@@ -8112,29 +6855,23 @@
       k: [100]
     }, 1, 0.01, this);
   }
-
   AudioElement.prototype.prepareFrame = function (num) {
     this.prepareRenderableFrame(num, true);
     this.prepareProperties(num, true);
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
       this._currentTime = timeRemapped;
     } else {
       this._currentTime = num / this.data.sr;
     }
-
     this._volume = this.lv.v[0];
     var totalVolume = this._volume * this._volumeMultiplier;
-
     if (this._previousVolume !== totalVolume) {
       this._previousVolume = totalVolume;
       this.audio.volume(totalVolume);
     }
   };
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
-
   AudioElement.prototype.renderFrame = function () {
     if (this.isInRange && this._canPlay) {
       if (!this._isPlaying) {
@@ -8146,162 +6883,124 @@
       }
     }
   };
-
-  AudioElement.prototype.show = function () {// this.audio.play()
+  AudioElement.prototype.show = function () {
+    // this.audio.play()
   };
-
   AudioElement.prototype.hide = function () {
     this.audio.pause();
     this._isPlaying = false;
   };
-
   AudioElement.prototype.pause = function () {
     this.audio.pause();
     this._isPlaying = false;
     this._canPlay = false;
   };
-
   AudioElement.prototype.resume = function () {
     this._canPlay = true;
   };
-
   AudioElement.prototype.setRate = function (rateValue) {
     this.audio.rate(rateValue);
   };
-
   AudioElement.prototype.volume = function (volumeValue) {
     this._volumeMultiplier = volumeValue;
     this._previousVolume = volumeValue * this._volume;
     this.audio.volume(this._previousVolume);
   };
-
   AudioElement.prototype.getBaseElement = function () {
     return null;
   };
-
   AudioElement.prototype.destroy = function () {};
-
   AudioElement.prototype.sourceRectAtTime = function () {};
-
   AudioElement.prototype.initExpressions = function () {};
 
   function BaseRenderer() {}
-
   BaseRenderer.prototype.checkLayers = function (num) {
     var i;
     var len = this.layers.length;
     var data;
     this.completeLayers = true;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (!this.elements[i]) {
         data = this.layers[i];
-
         if (data.ip - data.st <= num - this.layers[i].st && data.op - data.st > num - this.layers[i].st) {
           this.buildItem(i);
         }
       }
-
       this.completeLayers = this.elements[i] ? this.completeLayers : false;
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.createItem = function (layer) {
     switch (layer.ty) {
       case 2:
         return this.createImage(layer);
-
       case 0:
         return this.createComp(layer);
-
       case 1:
         return this.createSolid(layer);
-
       case 3:
         return this.createNull(layer);
-
       case 4:
         return this.createShape(layer);
-
       case 5:
         return this.createText(layer);
-
       case 6:
         return this.createAudio(layer);
-
       case 13:
         return this.createCamera(layer);
-
       case 15:
         return this.createFootage(layer);
-
       default:
         return this.createNull(layer);
     }
   };
-
   BaseRenderer.prototype.createCamera = function () {
     throw new Error('You\'re using a 3d camera. Try the html renderer.');
   };
-
   BaseRenderer.prototype.createAudio = function (data) {
     return new AudioElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.createFootage = function (data) {
     return new FootageElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.buildAllItems = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       this.buildItem(i);
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.includeLayers = function (newLayers) {
     this.completeLayers = false;
     var i;
     var len = newLayers.length;
     var j;
     var jLen = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       j = 0;
-
       while (j < jLen) {
         if (this.layers[j].id === newLayers[i].id) {
           this.layers[j] = newLayers[i];
           break;
         }
-
         j += 1;
       }
     }
   };
-
   BaseRenderer.prototype.setProjectInterface = function (pInterface) {
     this.globalData.projectInterface = pInterface;
   };
-
   BaseRenderer.prototype.initItems = function () {
     if (!this.globalData.progressiveLoad) {
       this.buildAllItems();
     }
   };
-
   BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
     var elements = this.elements;
     var layers = this.layers;
     var i = 0;
     var len = layers.length;
-
     while (i < len) {
       if (layers[i].ind == parentName) {
         // eslint-disable-line eqeqeq
@@ -8311,7 +7010,6 @@
         } else {
           hierarchy.push(elements[i]);
           elements[i].setAsParent();
-
           if (layers[i].parent !== undefined) {
             this.buildElementParenting(element, layers[i].parent, hierarchy);
           } else {
@@ -8319,19 +7017,15 @@
           }
         }
       }
-
       i += 1;
     }
   };
-
   BaseRenderer.prototype.addPendingElement = function (element) {
     this.pendingElements.push(element);
   };
-
   BaseRenderer.prototype.searchExtraCompositions = function (assets) {
     var i;
     var len = assets.length;
-
     for (i = 0; i < len; i += 1) {
       if (assets[i].xt) {
         var comp = this.createComp(assets[i]);
@@ -8340,30 +7034,24 @@
       }
     }
   };
-
   BaseRenderer.prototype.getElementById = function (ind) {
     var i;
     var len = this.elements.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i].data.ind === ind) {
         return this.elements[i];
       }
     }
-
     return null;
   };
-
   BaseRenderer.prototype.getElementByPath = function (path) {
     var pathValue = path.shift();
     var element;
-
     if (typeof pathValue === 'number') {
       element = this.elements[pathValue];
     } else {
       var i;
       var len = this.elements.length;
-
       for (i = 0; i < len; i += 1) {
         if (this.elements[i].data.nm === pathValue) {
           element = this.elements[i];
@@ -8371,14 +7059,11 @@
         }
       }
     }
-
     if (path.length === 0) {
       return element;
     }
-
     return element.getElementByPath(path);
   };
-
   BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
     this.globalData.fontManager = new FontManager();
     this.globalData.slotManager = slotFactory(animData);
@@ -8402,7 +7087,6 @@
   };
 
   function TransformElement() {}
-
   TransformElement.prototype = {
     initTransform: function initTransform() {
       var mat = new Matrix();
@@ -8417,50 +7101,44 @@
         localMat: mat,
         localOpacity: 1
       };
-
       if (this.data.ao) {
         this.finalTransform.mProp.autoOriented = true;
-      } // TODO: check TYPE 11: Guided elements
+      }
 
-
-      if (this.data.ty !== 11) {// this.createElements();
+      // TODO: check TYPE 11: Guided elements
+      if (this.data.ty !== 11) {
+        // this.createElements();
       }
     },
     renderTransform: function renderTransform() {
       this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
       this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
-
       if (this.hierarchy) {
         var mat;
         var finalMat = this.finalTransform.mat;
         var i = 0;
-        var len = this.hierarchy.length; // Checking if any of the transformation matrices in the hierarchy chain has changed.
-
+        var len = this.hierarchy.length;
+        // Checking if any of the transformation matrices in the hierarchy chain has changed.
         if (!this.finalTransform._matMdf) {
           while (i < len) {
             if (this.hierarchy[i].finalTransform.mProp._mdf) {
               this.finalTransform._matMdf = true;
               break;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._matMdf) {
           mat = this.finalTransform.mProp.v.props;
           finalMat.cloneFromProps(mat);
-
           for (i = 0; i < len; i += 1) {
             finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
           }
         }
       }
-
-      if (this.finalTransform._matMdf) {
+      if (!this.localTransforms || this.finalTransform._matMdf) {
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
       }
-
       if (this.finalTransform._opMdf) {
         this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
       }
@@ -8470,41 +7148,32 @@
         var i = 0;
         var len = this.localTransforms.length;
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
-
         if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
           while (i < len) {
             if (this.localTransforms[i]._mdf) {
               this.finalTransform._localMatMdf = true;
             }
-
             if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
               this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
               this.finalTransform._opMdf = true;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._localMatMdf) {
           var localMat = this.finalTransform.localMat;
           this.localTransforms[0].matrix.clone(localMat);
-
           for (i = 1; i < len; i += 1) {
             var lmat = this.localTransforms[i].matrix;
             localMat.multiply(lmat);
           }
-
           localMat.multiply(this.finalTransform.mat);
         }
-
         if (this.finalTransform._opMdf) {
           var localOp = this.finalTransform.localOpacity;
-
           for (i = 0; i < len; i += 1) {
             localOp *= this.localTransforms[i].opacity * 0.01;
           }
-
           this.finalTransform.localOpacity = localOp;
         }
       }
@@ -8512,13 +7181,11 @@
     searchEffectTransforms: function searchEffectTransforms() {
       if (this.renderableEffectsManager) {
         var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
-
         if (transformEffects.length) {
           this.localTransforms = [];
           this.finalTransform.localMat = new Matrix();
           var i = 0;
           var len = transformEffects.length;
-
           for (i = 0; i < len; i += 1) {
             this.localTransforms.push(transformEffects[i]);
           }
@@ -8530,29 +7197,24 @@
       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;
       var len = transforms.length;
       var 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]);
-
+        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;
     },
     mHelper: new Matrix()
@@ -8583,13 +7245,11 @@
     var x;
     var maskType = 'clipPath';
     var maskRef = 'clip-path';
-
     for (i = 0; i < len; i += 1) {
       if (properties[i].mode !== 'a' && properties[i].mode !== 'n' || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
         maskType = 'mask';
         maskRef = 'mask';
       }
-
       if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
         rect = createNS('rect');
         rect.setAttribute('fill', '#ffffff');
@@ -8599,9 +7259,7 @@
       } else {
         rect = null;
       }
-
       path = createNS('path');
-
       if (properties[i].mode === 'n') {
         // TODO move this to a factory or to a constructor
         this.viewData[i] = {
@@ -8616,7 +7274,6 @@
         path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
         path.setAttribute('clip-rule', 'nonzero');
         var filterID;
-
         if (properties[i].x.k !== 0) {
           maskType = 'mask';
           maskRef = 'mask';
@@ -8634,9 +7291,9 @@
         } else {
           feMorph = null;
           x = null;
-        } // TODO move this to a factory or to a constructor
+        }
 
-
+        // TODO move this to a factory or to a constructor
         this.storedData[i] = {
           elem: path,
           x: x,
@@ -8646,15 +7303,12 @@
           filterId: filterID,
           lastRadius: 0
         };
-
         if (properties[i].mode === 'i') {
           jLen = currentMasks.length;
           var g = createNS('g');
-
           for (j = 0; j < jLen; j += 1) {
             g.appendChild(currentMasks[j]);
           }
-
           var mask = createNS('mask');
           mask.setAttribute('mask-type', 'alpha');
           mask.setAttribute('id', layerId + '_' + count);
@@ -8666,12 +7320,10 @@
         } else {
           currentMasks.push(path);
         }
-
         if (properties[i].inv && !this.solidPath) {
           this.solidPath = this.createLayerSolidPath();
-        } // TODO move this to a factory or to a constructor
-
-
+        }
+        // TODO move this to a factory or to a constructor
         this.viewData[i] = {
           elem: path,
           lastPath: '',
@@ -8679,81 +7331,65 @@
           prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
           invRect: rect
         };
-
         if (!this.viewData[i].prop.k) {
           this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
         }
       }
     }
-
     this.maskElement = createNS(maskType);
     len = currentMasks.length;
-
     for (i = 0; i < len; i += 1) {
       this.maskElement.appendChild(currentMasks[i]);
     }
-
     if (count > 0) {
       this.maskElement.setAttribute('id', layerId);
       this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
       defs.appendChild(this.maskElement);
     }
-
     if (this.viewData.length) {
       this.element.addRenderableComponent(this);
     }
   }
-
   MaskElement.prototype.getMaskProperty = function (pos) {
     return this.viewData[pos].prop;
   };
-
   MaskElement.prototype.renderFrame = function (isFirstFrame) {
     var finalMat = this.element.finalTransform.mat;
     var i;
     var len = this.masksProperties.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.viewData[i].prop._mdf || isFirstFrame) {
         this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
       }
-
       if (this.viewData[i].op._mdf || isFirstFrame) {
         this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
       }
-
       if (this.masksProperties[i].mode !== 'n') {
         if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
           this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
         }
-
         if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
           var feMorph = this.storedData[i].expan;
-
           if (this.storedData[i].x.v < 0) {
             if (this.storedData[i].lastOperator !== 'erode') {
               this.storedData[i].lastOperator = 'erode';
               this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
             }
-
             feMorph.setAttribute('radius', -this.storedData[i].x.v);
           } else {
             if (this.storedData[i].lastOperator !== 'dilate') {
               this.storedData[i].lastOperator = 'dilate';
               this.storedData[i].elem.setAttribute('filter', null);
             }
-
             this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
           }
         }
       }
     }
   };
-
   MaskElement.prototype.getMaskelement = function () {
     return this.maskElement;
   };
-
   MaskElement.prototype.createLayerSolidPath = function () {
     var path = 'M0,0 ';
     path += ' h' + this.globalData.compSize.w;
@@ -8762,39 +7398,32 @@
     path += ' v-' + this.globalData.compSize.h + ' ';
     return path;
   };
-
   MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
     var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
     var i;
     var len;
     len = pathNodes._length;
-
     for (i = 1; i < len; i += 1) {
       // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
-    } // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
-
-
+    }
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
     if (pathNodes.c && len > 1) {
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
-    } // pathNodes.__renderedString = pathString;
-
+    }
+    // pathNodes.__renderedString = pathString;
 
     if (viewData.lastPath !== pathString) {
       var pathShapeValue = '';
-
       if (viewData.elem) {
         if (pathNodes.c) {
           pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
         }
-
         viewData.elem.setAttribute('d', pathShapeValue);
       }
-
       viewData.lastPath = pathString;
     }
   };
-
   MaskElement.prototype.destroy = function () {
     this.element = null;
     this.globalData = null;
@@ -8807,11 +7436,9 @@
     var ob = {};
     ob.createFilter = createFilter;
     ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
-
     function createFilter(filId, skipCoordinates) {
       var fil = createNS('filter');
       fil.setAttribute('id', filId);
-
       if (skipCoordinates !== true) {
         fil.setAttribute('filterUnits', 'objectBoundingBox');
         fil.setAttribute('x', '0%');
@@ -8819,10 +7446,8 @@
         fil.setAttribute('width', '100%');
         fil.setAttribute('height', '100%');
       }
-
       return fil;
     }
-
     function createAlphaToLuminanceFilter() {
       var feColorMatrix = createNS('feColorMatrix');
       feColorMatrix.setAttribute('type', 'matrix');
@@ -8830,7 +7455,6 @@
       feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
       return feColorMatrix;
     }
-
     return ob;
   }();
 
@@ -8840,21 +7464,17 @@
       svgLumaHidden: true,
       offscreenCanvas: typeof OffscreenCanvas !== 'undefined'
     };
-
     if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
       ob.maskType = false;
     }
-
     if (/firefox/i.test(navigator.userAgent)) {
       ob.svgLumaHidden = false;
     }
-
     return ob;
   }();
 
   var registeredEffects$1 = {};
   var idPrefix = 'filter_result_';
-
   function SVGEffects(elem) {
     var i;
     var source = 'SourceGraphic';
@@ -8864,59 +7484,47 @@
     var count = 0;
     this.filters = [];
     var filterManager;
-
     for (i = 0; i < len; i += 1) {
       filterManager = null;
       var type = elem.data.ef[i].ty;
-
       if (registeredEffects$1[type]) {
         var Effect = registeredEffects$1[type].effect;
         filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
         source = idPrefix + count;
-
         if (registeredEffects$1[type].countsAsEffect) {
           count += 1;
         }
       }
-
       if (filterManager) {
         this.filters.push(filterManager);
       }
     }
-
     if (count) {
       elem.globalData.defs.appendChild(fil);
       elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
     }
-
     if (this.filters.length) {
       elem.addRenderableComponent(this);
     }
   }
-
   SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
     var i;
     var len = this.filters.length;
-
     for (i = 0; i < len; i += 1) {
       this.filters[i].renderFrame(_isFirstFrame);
     }
   };
-
   SVGEffects.prototype.getEffects = function (type) {
     var i;
     var len = this.filters.length;
     var effects = [];
-
     for (i = 0; i < len; i += 1) {
       if (this.filters[i].type === type) {
         effects.push(this.filters[i]);
       }
     }
-
     return effects;
   };
-
   function registerEffect$1(id, effect, countsAsEffect) {
     registeredEffects$1[id] = {
       effect: effect,
@@ -8925,7 +7533,6 @@
   }
 
   function SVGBaseElement() {}
-
   SVGBaseElement.prototype = {
     initRendererElement: function initRendererElement() {
       this.layerElement = createNS('g');
@@ -8935,8 +7542,8 @@
       this.transformedElement = this.layerElement;
       this.maskedElement = this.layerElement;
       this._sizeChanged = false;
-      var layerElementParent = null; // If this layer acts as a mask for the following layer
-
+      var layerElementParent = null;
+      // If this layer acts as a mask for the following layer
       if (this.data.td) {
         this.matteMasks = {};
         var gg = createNS('g');
@@ -8951,16 +7558,13 @@
       } else {
         this.baseElement = this.layerElement;
       }
-
       if (this.data.ln) {
         this.layerElement.setAttribute('id', this.data.ln);
       }
-
       if (this.data.cl) {
         this.layerElement.setAttribute('class', this.data.cl);
-      } // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
-
-
+      }
+      // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
       if (this.data.ty === 0 && !this.data.hd) {
         var cp = createNS('clipPath');
         var pt = createNS('path');
@@ -8969,13 +7573,11 @@
         cp.setAttribute('id', clipId);
         cp.appendChild(pt);
         this.globalData.defs.appendChild(cp);
-
         if (this.checkMasks()) {
           var cpGroup = createNS('g');
           cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
           cpGroup.appendChild(this.layerElement);
           this.transformedElement = cpGroup;
-
           if (layerElementParent) {
             layerElementParent.appendChild(this.transformedElement);
           } else {
@@ -8985,7 +7587,6 @@
           this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
         }
       }
-
       if (this.data.bm !== 0) {
         this.setBlendMode();
       }
@@ -8994,7 +7595,6 @@
       if (this.finalTransform._localMatMdf) {
         this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
       }
-
       if (this.finalTransform._opMdf) {
         this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
       }
@@ -9008,7 +7608,6 @@
       if (this.data.hd) {
         return null;
       }
-
       return this.baseElement;
     },
     createRenderableComponents: function createRenderableComponents() {
@@ -9023,14 +7622,12 @@
       if (!this.matteMasks) {
         this.matteMasks = {};
       }
-
       if (!this.matteMasks[matteType]) {
         var id = this.layerId + '_' + matteType;
         var filId;
         var fil;
         var useElement;
         var gg;
-
         if (matteType === 1 || matteType === 3) {
           var masker = createNS('mask');
           masker.setAttribute('id', id);
@@ -9039,7 +7636,6 @@
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           masker.appendChild(useElement);
           this.globalData.defs.appendChild(masker);
-
           if (!featureSupport.maskType && matteType === 1) {
             masker.setAttribute('mask-type', 'luminance');
             filId = createElementID();
@@ -9058,16 +7654,16 @@
           var maskGrouper = createNS('g');
           maskGroup.appendChild(maskGrouper);
           filId = createElementID();
-          fil = filtersFactory.createFilter(filId); /// /
-
+          fil = filtersFactory.createFilter(filId);
+          /// /
           var feCTr = createNS('feComponentTransfer');
           feCTr.setAttribute('in', 'SourceGraphic');
           fil.appendChild(feCTr);
           var feFunc = createNS('feFuncA');
           feFunc.setAttribute('type', 'table');
           feFunc.setAttribute('tableValues', '1.0 0.0');
-          feCTr.appendChild(feFunc); /// /
-
+          feCTr.appendChild(feFunc);
+          /// /
           this.globalData.defs.appendChild(fil);
           var alphaRect = createNS('rect');
           alphaRect.setAttribute('width', this.comp.data.w);
@@ -9081,7 +7677,6 @@
           useElement = createNS('use');
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           maskGrouper.appendChild(useElement);
-
           if (!featureSupport.maskType) {
             maskGroup.setAttribute('mask-type', 'luminance');
             fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
@@ -9090,20 +7685,16 @@
             gg.appendChild(this.layerElement);
             maskGrouper.appendChild(gg);
           }
-
           this.globalData.defs.appendChild(maskGroup);
         }
-
         this.matteMasks[matteType] = id;
       }
-
       return this.matteMasks[matteType];
     },
     setMatte: function setMatte(id) {
       if (!this.matteElement) {
         return;
       }
-
       this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
     }
   };
@@ -9113,8 +7704,8 @@
    * Handles AE's layer parenting property.
    *
    */
-  function HierarchyElement() {}
 
+  function HierarchyElement() {}
   HierarchyElement.prototype = {
     /**
        * @function
@@ -9123,12 +7714,11 @@
        */
     initHierarchy: function initHierarchy() {
       // element's parent list
-      this.hierarchy = []; // if element is parent of another layer _isParent will be true
-
+      this.hierarchy = [];
+      // if element is parent of another layer _isParent will be true
       this._isParent = false;
       this.checkParenting();
     },
-
     /**
        * @function
        * Sets layer's hierarchy.
@@ -9139,7 +7729,6 @@
     setHierarchy: function setHierarchy(hierarchy) {
       this.hierarchy = hierarchy;
     },
-
     /**
        * @function
        * Sets layer as parent.
@@ -9148,7 +7737,6 @@
     setAsParent: function setAsParent() {
       this._isParent = true;
     },
-
     /**
        * @function
        * Searches layer's parenting chain
@@ -9162,7 +7750,6 @@
   };
 
   function RenderableDOMElement() {}
-
   (function () {
     var _prototype = {
       initElement: function initElement(data, globalData, comp) {
@@ -9192,7 +7779,6 @@
             var elem = this.baseElement || this.layerElement;
             elem.style.display = 'block';
           }
-
           this.hidden = false;
           this._isFirstFrame = true;
         }
@@ -9203,13 +7789,11 @@
         if (this.data.hd || this.hidden) {
           return;
         }
-
         this.renderTransform();
         this.renderRenderable();
         this.renderLocalTransform();
         this.renderElement();
         this.renderInnerContent();
-
         if (this._isFirstFrame) {
           this._isFirstFrame = false;
         }
@@ -9231,11 +7815,9 @@
 
   function IImageElement(data, globalData, comp) {
     this.assetData = globalData.getAssetData(data.refId);
-
     if (this.assetData && this.assetData.sid) {
       this.assetData = globalData.slotManager.getProp(this.assetData);
     }
-
     this.initElement(data, globalData, comp);
     this.sourceRect = {
       top: 0,
@@ -9244,9 +7826,7 @@
       height: this.assetData.h
     };
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
-
   IImageElement.prototype.createContent = function () {
     var assetPath = this.globalData.getAssetsPath(this.assetData);
     this.innerElem = createNS('image');
@@ -9256,7 +7836,6 @@
     this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
     this.layerElement.appendChild(this.innerElem);
   };
-
   IImageElement.prototype.sourceRectAtTime = function () {
     return this.sourceRect;
   };
@@ -9267,12 +7846,10 @@
   }
 
   function IShapeElement() {}
-
   IShapeElement.prototype = {
     addShapeToModifiers: function addShapeToModifiers(data) {
       var i;
       var len = this.shapeModifiers.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapeModifiers[i].addShape(data);
       }
@@ -9280,34 +7857,28 @@
     isShapeInAnimatedModifiers: function isShapeInAnimatedModifiers(data) {
       var i = 0;
       var len = this.shapeModifiers.length;
-
       while (i < len) {
         if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
           return true;
         }
       }
-
       return false;
     },
     renderModifiers: function renderModifiers() {
       if (!this.shapeModifiers.length) {
         return;
       }
-
       var i;
       var len = this.shapes.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapes[i].sh.reset();
       }
-
       len = this.shapeModifiers.length;
       var shouldBreakProcess;
-
       for (i = len - 1; i >= 0; i -= 1) {
-        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame); // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+        // workaround to fix cases where a repeater resets the shape so the following processes get called twice
         // TODO: find a better solution for this
-
         if (shouldBreakProcess) {
           break;
         }
@@ -9317,30 +7888,24 @@
       var elements = this.processedElements;
       var i = 0;
       var len = elements.length;
-
       while (i < len) {
         if (elements[i].elem === elem) {
           return elements[i].pos;
         }
-
         i += 1;
       }
-
       return 0;
     },
     addProcessedElement: function addProcessedElement(elem, pos) {
       var elements = this.processedElements;
       var i = elements.length;
-
       while (i) {
         i -= 1;
-
         if (elements[i].elem === elem) {
           elements[i].pos = pos;
           return;
         }
       }
-
       elements.push(new ProcessedElement(elem, pos));
     },
     prepareFrame: function prepareFrame(num) {
@@ -9366,25 +7931,22 @@
     this.transformers = transformers;
     this.lStr = '';
     this.sh = shape;
-    this.lvl = level; // TODO find if there are some cases where _isAnimated can be false.
+    this.lvl = level;
+    // TODO find if there are some cases where _isAnimated can be false.
     // For now, since shapes add up with other shapes. They have to be calculated every time.
     // One way of finding out is checking if all styles associated to this shape depend only of this shape
-
-    this._isAnimated = !!shape.k; // TODO: commenting this for now since all shapes are animated
-
+    this._isAnimated = !!shape.k;
+    // TODO: commenting this for now since all shapes are animated
     var i = 0;
     var len = transformers.length;
-
     while (i < len) {
       if (transformers[i].mProps.dynamicProperties.length) {
         this._isAnimated = true;
         break;
       }
-
       i += 1;
     }
   }
-
   SVGShapeData.prototype.setAsAnimated = function () {
     this._isAnimated = true;
   };
@@ -9399,7 +7961,6 @@
     this.pElem = createNS('path');
     this.msElem = null;
   }
-
   SVGStyleData.prototype.reset = function () {
     this.d = '';
     this._mdf = false;
@@ -9418,7 +7979,6 @@
     var i;
     var len = data.length || 0;
     var prop;
-
     for (i = 0; i < len; i += 1) {
       prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
       this.k = prop.k || this.k;
@@ -9427,31 +7987,24 @@
         p: prop
       };
     }
-
     if (!this.k) {
       this.getValue(true);
     }
-
     this._isAnimated = this.k;
   }
-
   DashProperty.prototype.getValue = function (forceRender) {
     if (this.elem.globalData.frameId === this.frameId && !forceRender) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
     this._mdf = this._mdf || forceRender;
-
     if (this._mdf) {
       var i = 0;
       var len = this.dataProps.length;
-
       if (this.renderer === 'svg') {
         this.dashStr = '';
       }
-
       for (i = 0; i < len; i += 1) {
         if (this.dataProps[i].n !== 'o') {
           if (this.renderer === 'svg') {
@@ -9465,7 +8018,6 @@
       }
     }
   };
-
   extendPrototype([DynamicPropertyContainer], DashProperty);
 
   function SVGStrokeStyleData(elem, data, styleOb) {
@@ -9478,7 +8030,6 @@
     this.style = styleOb;
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
 
   function SVGFillStyleData(elem, data, styleOb) {
@@ -9488,7 +8039,6 @@
     this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
 
   function SVGNoStyleData(elem, data, styleOb) {
@@ -9496,7 +8046,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
 
   function GradientProperty(elem, data, container) {
@@ -9513,88 +8062,69 @@
     this.k = this.prop.k;
     this.getValue(true);
   }
-
   GradientProperty.prototype.comparePoints = function (values, points) {
     var i = 0;
     var len = this.o.length / 2;
     var diff;
-
     while (i < len) {
       diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
-
       if (diff > 0.01) {
         return false;
       }
-
       i += 1;
     }
-
     return true;
   };
-
   GradientProperty.prototype.checkCollapsable = function () {
     if (this.o.length / 2 !== this.c.length / 4) {
       return false;
     }
-
     if (this.data.k.k[0].s) {
       var i = 0;
       var len = this.data.k.k.length;
-
       while (i < len) {
         if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
           return false;
         }
-
         i += 1;
       }
     } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
       return false;
     }
-
     return true;
   };
-
   GradientProperty.prototype.getValue = function (forceRender) {
     this.prop.getValue();
     this._mdf = false;
     this._cmdf = false;
     this._omdf = false;
-
     if (this.prop._mdf || forceRender) {
       var i;
       var len = this.data.p * 4;
       var mult;
       var val;
-
       for (i = 0; i < len; i += 1) {
         mult = i % 4 === 0 ? 100 : 255;
         val = Math.round(this.prop.v[i] * mult);
-
         if (this.c[i] !== val) {
           this.c[i] = val;
           this._cmdf = !forceRender;
         }
       }
-
       if (this.o.length) {
         len = this.prop.v.length;
-
         for (i = this.data.p * 4; i < len; i += 1) {
           mult = i % 2 === 0 ? 100 : 1;
           val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
-
           if (this.o[i - this.data.p * 4] !== val) {
             this.o[i - this.data.p * 4] = val;
             this._omdf = !forceRender;
           }
         }
       }
-
       this._mdf = !forceRender;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], GradientProperty);
 
   function SVGGradientFillStyleData(elem, data, styleOb) {
@@ -9602,7 +8132,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.initGradientData(elem, data, styleOb);
   }
-
   SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
     this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
     this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
@@ -9620,7 +8149,6 @@
     this.setGradientOpacity(data, styleOb);
     this._isAnimated = !!this._isAnimated;
   };
-
   SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
     var gradientId = createElementID();
     var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
@@ -9632,18 +8160,15 @@
     var j;
     var jLen;
     jLen = data.g.p * 4;
-
     for (j = 0; j < jLen; j += 4) {
       stop = createNS('stop');
       gfill.appendChild(stop);
       stops.push(stop);
     }
-
     pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
     this.gf = gfill;
     this.cst = stops;
   };
-
   SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
     if (this.g._hasOpacity && !this.g._collapsable) {
       var stop;
@@ -9661,25 +8186,20 @@
       opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
       jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
       var stops = this.stops;
-
       for (j = data.g.p * 4; j < jLen; j += 2) {
         stop = createNS('stop');
         stop.setAttribute('stop-color', 'rgb(255,255,255)');
         opFill.appendChild(stop);
         stops.push(stop);
       }
-
       maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
@@ -9687,7 +8207,6 @@
       styleOb.msElem = maskElement;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
 
   function SVGGradientStrokeStyleData(elem, data, styleOb) {
@@ -9698,7 +8217,6 @@
     this.initGradientData(elem, data, styleOb);
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
 
   function ShapeGroupData() {
@@ -9721,77 +8239,59 @@
     if (length === 0) {
       return '';
     }
-
     var _o = pathNodes.o;
     var _i = pathNodes.i;
     var _v = pathNodes.v;
     var i;
     var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
-
     for (i = 1; i < length; i += 1) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
     }
-
     if (closed && length) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
       shapeString += 'z';
     }
-
     return shapeString;
   };
 
   var SVGElementsRenderer = function () {
     var _identityMatrix = new Matrix();
-
     var _matrixHelper = new Matrix();
-
     var ob = {
       createRenderFunction: createRenderFunction
     };
-
     function createRenderFunction(data) {
       switch (data.ty) {
         case 'fl':
           return renderFill;
-
         case 'gf':
           return renderGradient;
-
         case 'gs':
           return renderGradientStroke;
-
         case 'st':
           return renderStroke;
-
         case 'sh':
         case 'el':
         case 'rc':
         case 'sr':
           return renderPath;
-
         case 'tr':
           return renderContentTransform;
-
         case 'no':
           return renderNoop;
-
         default:
           return null;
       }
     }
-
     function renderContentTransform(styleData, itemData, isFirstFrame) {
       if (isFirstFrame || itemData.transform.op._mdf) {
         itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
       }
-
       if (isFirstFrame || itemData.transform.mProps._mdf) {
         itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
       }
     }
-
     function renderNoop() {}
-
     function renderPath(styleData, itemData, isFirstFrame) {
       var j;
       var jLen;
@@ -9805,25 +8305,20 @@
       var mat;
       var iterations;
       var k;
-
       for (l = 0; l < lLen; l += 1) {
         redraw = itemData.sh._mdf || isFirstFrame;
-
         if (itemData.styles[l].lvl < lvl) {
           mat = _matrixHelper.reset();
           iterations = lvl - itemData.styles[l].lvl;
           k = itemData.transformers.length - 1;
-
           while (!redraw && iterations > 0) {
             redraw = itemData.transformers[k].mProps._mdf || redraw;
             iterations -= 1;
             k -= 1;
           }
-
           if (redraw) {
             iterations = lvl - itemData.styles[l].lvl;
             k = itemData.transformers.length - 1;
-
             while (iterations > 0) {
               mat.multiply(itemData.transformers[k].mProps.v);
               iterations -= 1;
@@ -9833,115 +8328,90 @@
         } else {
           mat = _identityMatrix;
         }
-
         paths = itemData.sh.paths;
         jLen = paths._length;
-
         if (redraw) {
           pathStringTransformed = '';
-
           for (j = 0; j < jLen; j += 1) {
             pathNodes = paths.shapes[j];
-
             if (pathNodes && pathNodes._length) {
               pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
             }
           }
-
           itemData.caches[l] = pathStringTransformed;
         } else {
           pathStringTransformed = itemData.caches[l];
         }
-
         itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
         itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
       }
     }
-
     function renderFill(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
-
       if (itemData.c._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
       }
     }
-
     function renderGradientStroke(styleData, itemData, isFirstFrame) {
       renderGradient(styleData, itemData, isFirstFrame);
       renderStroke(styleData, itemData, isFirstFrame);
     }
-
     function renderGradient(styleData, itemData, isFirstFrame) {
       var gfill = itemData.gf;
       var hasOpacity = itemData.g._hasOpacity;
       var pt1 = itemData.s.v;
       var pt2 = itemData.e.v;
-
       if (itemData.o._mdf || isFirstFrame) {
         var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
         itemData.style.pElem.setAttribute(attr, itemData.o.v);
       }
-
       if (itemData.s._mdf || isFirstFrame) {
         var attr1 = styleData.t === 1 ? 'x1' : 'cx';
         var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
         gfill.setAttribute(attr1, pt1[0]);
         gfill.setAttribute(attr2, pt1[1]);
-
         if (hasOpacity && !itemData.g._collapsable) {
           itemData.of.setAttribute(attr1, pt1[0]);
           itemData.of.setAttribute(attr2, pt1[1]);
         }
       }
-
       var stops;
       var i;
       var len;
       var stop;
-
       if (itemData.g._cmdf || isFirstFrame) {
         stops = itemData.cst;
         var cValues = itemData.g.c;
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
           stop.setAttribute('offset', cValues[i * 4] + '%');
           stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
         }
       }
-
       if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
         var oValues = itemData.g.o;
-
         if (itemData.g._collapsable) {
           stops = itemData.cst;
         } else {
           stops = itemData.ost;
         }
-
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
-
           if (!itemData.g._collapsable) {
             stop.setAttribute('offset', oValues[i * 2] + '%');
           }
-
           stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
         }
       }
-
       if (styleData.t === 1) {
         if (itemData.e._mdf || isFirstFrame) {
           gfill.setAttribute('x2', pt2[0]);
           gfill.setAttribute('y2', pt2[1]);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('x2', pt2[0]);
             itemData.of.setAttribute('y2', pt2[1]);
@@ -9949,112 +8419,93 @@
         }
       } else {
         var rad;
-
         if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
           rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           gfill.setAttribute('r', rad);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('r', rad);
           }
         }
-
-        if (itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
           if (!rad) {
             rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           }
-
           var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
           var percent = itemData.h.v;
-
           if (percent >= 1) {
             percent = 0.99;
           } else if (percent <= -1) {
             percent = -0.99;
           }
-
           var dist = rad * percent;
           var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
           var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
           gfill.setAttribute('fx', x);
           gfill.setAttribute('fy', y);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('fx', x);
             itemData.of.setAttribute('fy', y);
           }
-        } // gfill.setAttribute('fy','200');
-
+        }
+        // gfill.setAttribute('fy','200');
       }
     }
-
     function renderStroke(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
       var d = itemData.d;
-
       if (d && (d._mdf || isFirstFrame) && d.dashStr) {
         styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
         styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
       }
-
       if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
         styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
       }
-
       if (itemData.w._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
-
         if (styleElem.msElem) {
           styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
         }
       }
     }
-
     return ob;
   }();
 
   function SVGShapeElement(data, globalData, comp) {
     // List of drawable elements
-    this.shapes = []; // Full shape data
-
-    this.shapesData = data.shapes; // List of styles that will be applied to shapes
-
-    this.stylesList = []; // List of modifiers that will be applied to shapes
-
-    this.shapeModifiers = []; // List of items in shape tree
-
-    this.itemsData = []; // List of items in previous shape tree
-
-    this.processedElements = []; // List of animated components
-
+    this.shapes = [];
+    // Full shape data
+    this.shapesData = data.shapes;
+    // List of styles that will be applied to shapes
+    this.stylesList = [];
+    // List of modifiers that will be applied to shapes
+    this.shapeModifiers = [];
+    // List of items in shape tree
+    this.itemsData = [];
+    // List of items in previous shape tree
+    this.processedElements = [];
+    // List of animated components
     this.animatedContents = [];
-    this.initElement(data, globalData, comp); // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.initElement(data, globalData, comp);
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
     // List of elements that have been created
-
-    this.prevViewData = []; // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.prevViewData = [];
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
-
   SVGShapeElement.prototype.initSecondaryElement = function () {};
-
   SVGShapeElement.prototype.identityMatrix = new Matrix();
-
   SVGShapeElement.prototype.buildExpressionInterface = function () {};
-
   SVGShapeElement.prototype.createContent = function () {
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
   };
+
   /*
   This method searches for multiple shapes that affect a single element and one of them is animated
   */
-
-
   SVGShapeElement.prototype.filterUniqueShapes = function () {
     var i;
     var len = this.shapes.length;
@@ -10064,42 +8515,34 @@
     var style;
     var tempShapes = [];
     var areAnimated = false;
-
     for (j = 0; j < jLen; j += 1) {
       style = this.stylesList[j];
       areAnimated = false;
       tempShapes.length = 0;
-
       for (i = 0; i < len; i += 1) {
         shape = this.shapes[i];
-
         if (shape.styles.indexOf(style) !== -1) {
           tempShapes.push(shape);
           areAnimated = shape._isAnimated || areAnimated;
         }
       }
-
       if (tempShapes.length > 1 && areAnimated) {
         this.setShapesAsAnimated(tempShapes);
       }
     }
   };
-
   SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
     var i;
     var len = shapes.length;
-
     for (i = 0; i < len; i += 1) {
       shapes[i].setAsAnimated();
     }
   };
-
   SVGShapeElement.prototype.createStyleElement = function (data, level) {
     // TODO: prevent drawing of hidden styles
     var elementData;
     var styleOb = new SVGStyleData(data, level);
     var pathElement = styleOb.pElem;
-
     if (data.ty === 'st') {
       elementData = new SVGStrokeStyleData(this, data, styleOb);
     } else if (data.ty === 'fl') {
@@ -10108,7 +8551,6 @@
       var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
       elementData = new GradientConstructor(this, data, styleOb);
       this.globalData.defs.appendChild(elementData.gf);
-
       if (elementData.maskId) {
         this.globalData.defs.appendChild(elementData.ms);
         this.globalData.defs.appendChild(elementData.of);
@@ -10117,66 +8559,51 @@
     } else if (data.ty === 'no') {
       elementData = new SVGNoStyleData(this, data, styleOb);
     }
-
     if (data.ty === 'st' || data.ty === 'gs') {
       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);
       }
     }
-
     if (data.r === 2) {
       pathElement.setAttribute('fill-rule', 'evenodd');
     }
-
     if (data.ln) {
       pathElement.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       pathElement.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     this.stylesList.push(styleOb);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createGroupElement = function (data) {
     var elementData = new ShapeGroupData();
-
     if (data.ln) {
       elementData.gr.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       elementData.gr.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     return elementData;
   };
-
   SVGShapeElement.prototype.createTransformElement = function (data, container) {
     var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
     var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
     var ty = 4;
-
     if (data.ty === 'rc') {
       ty = 5;
     } else if (data.ty === 'el') {
@@ -10184,7 +8611,6 @@
     } else if (data.ty === 'sr') {
       ty = 7;
     }
-
     var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
     var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
     this.shapes.push(elementData);
@@ -10192,58 +8618,46 @@
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
     var i = 0;
     var len = this.animatedContents.length;
-
     while (i < len) {
       if (this.animatedContents[i].element === element) {
         return;
       }
-
       i += 1;
     }
-
     this.animatedContents.push({
       fn: SVGElementsRenderer.createRenderFunction(data),
       element: element,
       data: data
     });
   };
-
   SVGShapeElement.prototype.setElementStyles = function (elementData) {
     var arr = elementData.styles;
     var j;
     var jLen = this.stylesList.length;
-
     for (j = 0; j < jLen; j += 1) {
-      if (!this.stylesList[j].closed) {
+      if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
         arr.push(this.stylesList[j]);
       }
     }
   };
-
   SVGShapeElement.prototype.reloadShapes = function () {
     this._isFirstFrame = true;
     var i;
     var len = this.itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       this.prevViewData[i] = this.itemsData[i];
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
     len = this.dynamicProperties.length;
-
     for (i = 0; i < len; i += 1) {
       this.dynamicProperties[i].getValue();
     }
-
     this.renderModifiers();
   };
-
   SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
     var ownTransformers = [].concat(transformers);
     var i;
@@ -10255,43 +8669,35 @@
     var currentTransform;
     var modifier;
     var processedPos;
-
     for (i = len; i >= 0; i -= 1) {
       processedPos = this.searchProcessedElement(arr[i]);
-
       if (!processedPos) {
         arr[i]._render = render;
       } else {
         itemsData[i] = prevViewData[processedPos - 1];
       }
-
       if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
         if (!processedPos) {
           itemsData[i] = this.createStyleElement(arr[i], level);
         } else {
-          itemsData[i].style.closed = false;
+          itemsData[i].style.closed = arr[i].hd;
         }
-
         if (arr[i]._render) {
           if (itemsData[i].style.pElem.parentNode !== container) {
             container.appendChild(itemsData[i].style.pElem);
           }
         }
-
         ownStyles.push(itemsData[i].style);
       } else if (arr[i].ty === 'gr') {
         if (!processedPos) {
           itemsData[i] = this.createGroupElement(arr[i]);
         } else {
           jLen = itemsData[i].it.length;
-
           for (j = 0; j < jLen; j += 1) {
             itemsData[i].prevViewData[j] = itemsData[i].it[j];
           }
         }
-
         this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
-
         if (arr[i]._render) {
           if (itemsData[i].gr.parentNode !== container) {
             container.appendChild(itemsData[i].gr);
@@ -10301,14 +8707,12 @@
         if (!processedPos) {
           itemsData[i] = this.createTransformElement(arr[i], container);
         }
-
         currentTransform = itemsData[i].transform;
         ownTransformers.push(currentTransform);
       } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
         if (!processedPos) {
           itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
         }
-
         this.setElementStyles(itemsData[i]);
       } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
         if (!processedPos) {
@@ -10320,7 +8724,6 @@
           modifier = itemsData[i];
           modifier.closed = false;
         }
-
         ownModifiers.push(modifier);
       } else if (arr[i].ty === 'rp') {
         if (!processedPos) {
@@ -10333,64 +8736,49 @@
           modifier = itemsData[i];
           modifier.closed = true;
         }
-
         ownModifiers.push(modifier);
       }
-
       this.addProcessedElement(arr[i], i + 1);
     }
-
     len = ownStyles.length;
-
     for (i = 0; i < len; i += 1) {
       ownStyles[i].closed = true;
     }
-
     len = ownModifiers.length;
-
     for (i = 0; i < len; i += 1) {
       ownModifiers[i].closed = true;
     }
   };
-
   SVGShapeElement.prototype.renderInnerContent = function () {
     this.renderModifiers();
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       this.stylesList[i].reset();
     }
-
     this.renderShape();
-
     for (i = 0; i < len; i += 1) {
       if (this.stylesList[i]._mdf || this._isFirstFrame) {
         if (this.stylesList[i].msElem) {
-          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d); // Adding M0 0 fixes same mask bug on all browsers
-
+          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+          // Adding M0 0 fixes same mask bug on all browsers
           this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
         }
-
         this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
       }
     }
   };
-
   SVGShapeElement.prototype.renderShape = function () {
     var i;
     var len = this.animatedContents.length;
     var animatedContent;
-
     for (i = 0; i < len; i += 1) {
       animatedContent = this.animatedContents[i];
-
       if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
         animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
       }
     }
   };
-
   SVGShapeElement.prototype.destroy = function () {
     this.destroyBaseElement();
     this.shapesData = null;
@@ -10413,7 +8801,6 @@
       p: true
     };
   }
-
   LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
     this._mdf.o = false;
     this._mdf.sw = false;
@@ -10422,43 +8809,36 @@
     this._mdf.m = false;
     this._mdf.p = false;
     var updated = false;
-
     if (this.o !== o) {
       this.o = o;
       this._mdf.o = true;
       updated = true;
     }
-
     if (this.sw !== sw) {
       this.sw = sw;
       this._mdf.sw = true;
       updated = true;
     }
-
     if (this.sc !== sc) {
       this.sc = sc;
       this._mdf.sc = true;
       updated = true;
     }
-
     if (this.fc !== fc) {
       this.fc = fc;
       this._mdf.fc = true;
       updated = true;
     }
-
     if (this.m !== m) {
       this.m = m;
       this._mdf.m = true;
       updated = true;
     }
-
     if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
       this.p = p;
       this._mdf.p = true;
       updated = true;
     }
-
     return updated;
   };
 
@@ -10469,11 +8849,9 @@
     this.kf = false;
     this._isFirstFrame = true;
     this._mdf = false;
-
     if (data.d && data.d.sid) {
       data.d = elem.globalData.slotManager.getProp(data.d);
     }
-
     this.data = data;
     this.elem = elem;
     this.comp = this.elem.comp;
@@ -10512,73 +8890,57 @@
       __complete: false
     };
     this.copyData(this.currentData, this.data.d.k[0].s);
-
     if (!this.searchProperty()) {
       this.completeTextData(this.currentData);
     }
   }
-
   TextProperty.prototype.defaultBoxWidth = [0, 0];
-
   TextProperty.prototype.copyData = function (obj, data) {
     for (var s in data) {
       if (Object.prototype.hasOwnProperty.call(data, s)) {
         obj[s] = data[s];
       }
     }
-
     return obj;
   };
-
   TextProperty.prototype.setCurrentData = function (data) {
     if (!data.__complete) {
       this.completeTextData(data);
     }
-
     this.currentData = data;
     this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
     this._mdf = true;
   };
-
   TextProperty.prototype.searchProperty = function () {
     return this.searchKeyframes();
   };
-
   TextProperty.prototype.searchKeyframes = function () {
     this.kf = this.data.d.k.length > 1;
-
     if (this.kf) {
       this.addEffect(this.getKeyframeValue.bind(this));
     }
-
     return this.kf;
   };
-
   TextProperty.prototype.addEffect = function (effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.getValue = function (_finalValue) {
     if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
       return;
     }
-
     this.currentData.t = this.data.d.k[this.keysIndex].s.t;
     var currentValue = this.currentData;
     var currentIndex = this.keysIndex;
-
     if (this.lock) {
       this.setCurrentData(this.currentData);
       return;
     }
-
     this.lock = true;
     this._mdf = false;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
-
     for (i = 0; i < len; i += 1) {
       // Checking if index changed to prevent creating a new object every time the expression updates.
       if (currentIndex !== this.keysIndex) {
@@ -10587,38 +8949,30 @@
         finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
       }
     }
-
     if (currentValue !== finalValue) {
       this.setCurrentData(finalValue);
     }
-
     this.v = this.currentData;
     this.pv = this.v;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   };
-
   TextProperty.prototype.getKeyframeValue = function () {
     var textKeys = this.data.d.k;
     var frameNum = this.elem.comp.renderedFrame;
     var i = 0;
     var len = textKeys.length;
-
     while (i <= len - 1) {
       if (i === len - 1 || textKeys[i + 1].t > frameNum) {
         break;
       }
-
       i += 1;
     }
-
     if (this.keysIndex !== i) {
       this.keysIndex = i;
     }
-
     return this.data.d.k[this.keysIndex].s;
   };
-
   TextProperty.prototype.buildFinalText = function (text) {
     var charactersArray = [];
     var i = 0;
@@ -10628,21 +8982,20 @@
     var shouldCombine = false;
     var shouldCombineNext = false;
     var currentChars = '';
-
     while (i < len) {
       shouldCombine = shouldCombineNext;
       shouldCombineNext = false;
       charCode = text.charCodeAt(i);
       currentChars = text.charAt(i);
-
       if (FontManager.isCombinedCharacter(charCode)) {
-        shouldCombine = true; // It's a potential surrogate pair (this is the High surrogate)
+        shouldCombine = true;
+        // It's a potential surrogate pair (this is the High surrogate)
       } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
         if (FontManager.isRegionalFlag(text, i)) {
           currentChars = text.substr(i, 14);
         } else {
-          secondCharCode = text.charCodeAt(i + 1); // It's a surrogate pair (this is the Low surrogate)
-
+          secondCharCode = text.charCodeAt(i + 1);
+          // It's a surrogate pair (this is the Low surrogate)
           if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
             if (FontManager.isModifier(charCode, secondCharCode)) {
               currentChars = text.substr(i, 2);
@@ -10656,7 +9009,6 @@
         }
       } else if (charCode > 0xDBFF) {
         secondCharCode = text.charCodeAt(i + 1);
-
         if (FontManager.isVariationSelector(charCode)) {
           shouldCombine = true;
         }
@@ -10664,20 +9016,16 @@
         shouldCombine = true;
         shouldCombineNext = true;
       }
-
       if (shouldCombine) {
         charactersArray[charactersArray.length - 1] += currentChars;
         shouldCombine = false;
       } else {
         charactersArray.push(currentChars);
       }
-
       i += currentChars.length;
     }
-
     return charactersArray;
   };
-
   TextProperty.prototype.completeTextData = function (documentData) {
     documentData.__complete = true;
     var fontManager = this.elem.globalData.fontManager;
@@ -10709,14 +9057,12 @@
     documentData.finalLineHeight = documentData.lh;
     var trackingOffset = documentData.tr / 1000 * documentData.finalSize;
     var charCode;
-
     if (documentData.sz) {
       var flag = true;
       var boxWidth = documentData.sz[0];
       var boxHeight = documentData.sz[1];
       var currentHeight;
       var finalText;
-
       while (flag) {
         finalText = this.buildFinalText(documentData.t);
         currentHeight = 0;
@@ -10724,11 +9070,9 @@
         len = finalText.length;
         trackingOffset = documentData.tr / 1000 * documentData.finalSize;
         var lastSpaceIndex = -1;
-
         for (i = 0; i < len; i += 1) {
           charCode = finalText[i].charCodeAt(0);
           newLineFlag = false;
-
           if (finalText[i] === ' ') {
             lastSpaceIndex = i;
           } else if (charCode === 13 || charCode === 3) {
@@ -10736,7 +9080,6 @@
             newLineFlag = true;
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
           }
-
           if (fontManager.chars) {
             charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
             cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -10744,17 +9087,15 @@
             // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
             cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
           }
-
           if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
             if (lastSpaceIndex === -1) {
               len += 1;
             } else {
               i = lastSpaceIndex;
             }
-
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
-            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r'); // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
-
+            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+            // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
             lastSpaceIndex = -1;
             lineWidth = 0;
           } else {
@@ -10762,9 +9103,7 @@
             lineWidth += trackingOffset;
           }
         }
-
         currentHeight += fontData.ascent * documentData.finalSize / 100;
-
         if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
           documentData.finalSize -= 1;
           documentData.finalLineHeight = documentData.finalSize * documentData.lh / documentData.s;
@@ -10775,17 +9114,14 @@
         }
       }
     }
-
     lineWidth = -trackingOffset;
     cLength = 0;
     var uncollapsedSpaces = 0;
     var currentChar;
-
     for (i = 0; i < len; i += 1) {
       newLineFlag = false;
       currentChar = documentData.finalText[i];
       charCode = currentChar.charCodeAt(0);
-
       if (charCode === 13 || charCode === 3) {
         uncollapsedSpaces = 0;
         lineWidths.push(lineWidth);
@@ -10797,7 +9133,6 @@
       } else {
         val = currentChar;
       }
-
       if (fontManager.chars) {
         charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
         cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -10805,16 +9140,15 @@
         // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
         // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
         cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
-      } //
+      }
 
-
+      //
       if (currentChar === ' ') {
         uncollapsedSpaces += cLength + trackingOffset;
       } else {
         lineWidth += cLength + trackingOffset + uncollapsedSpaces;
         uncollapsedSpaces = 0;
       }
-
       letters.push({
         l: cLength,
         an: cLength,
@@ -10825,42 +9159,35 @@
         line: currentLine,
         animatorJustifyOffset: 0
       });
-
       if (anchorGrouping == 2) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || val === ' ' || i === len - 1) {
           if (val === '' || val === ' ') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           index += 1;
           currentSize = 0;
         }
       } else if (anchorGrouping == 3) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || i === len - 1) {
           if (val === '') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           currentSize = 0;
           index += 1;
         }
@@ -10870,31 +9197,25 @@
         index += 1;
       }
     }
-
     documentData.l = letters;
     maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
     lineWidths.push(lineWidth);
-
     if (documentData.sz) {
       documentData.boxWidth = documentData.sz[0];
       documentData.justifyOffset = 0;
     } else {
       documentData.boxWidth = maxLineWidth;
-
       switch (documentData.j) {
         case 1:
           documentData.justifyOffset = -documentData.boxWidth;
           break;
-
         case 2:
           documentData.justifyOffset = -documentData.boxWidth / 2;
           break;
-
         default:
           documentData.justifyOffset = 0;
       }
     }
-
     documentData.lineWidths = lineWidths;
     var animators = data.a;
     var animatorData;
@@ -10903,63 +9224,49 @@
     var based;
     var ind;
     var indexes = [];
-
     for (j = 0; j < jLen; j += 1) {
       animatorData = animators[j];
-
       if (animatorData.a.sc) {
         documentData.strokeColorAnim = true;
       }
-
       if (animatorData.a.sw) {
         documentData.strokeWidthAnim = true;
       }
-
       if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
         documentData.fillColorAnim = true;
       }
-
       ind = 0;
       based = animatorData.s.b;
-
       for (i = 0; i < len; i += 1) {
         letterData = letters[i];
         letterData.anIndexes[j] = ind;
-
         if (based == 1 && letterData.val !== '' || based == 2 && letterData.val !== '' && letterData.val !== ' ' || based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1) || based == 4 && (letterData.n || i == len - 1)) {
           // eslint-disable-line eqeqeq
           if (animatorData.s.rn === 1) {
             indexes.push(ind);
           }
-
           ind += 1;
         }
       }
-
       data.a[j].s.totalChars = ind;
       var currentInd = -1;
       var newInd;
-
       if (animatorData.s.rn === 1) {
         for (i = 0; i < len; i += 1) {
           letterData = letters[i];
-
           if (currentInd != letterData.anIndexes[j]) {
             // eslint-disable-line eqeqeq
             currentInd = letterData.anIndexes[j];
             newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
           }
-
           letterData.anIndexes[j] = newInd;
         }
       }
     }
-
     documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
     documentData.ls = documentData.ls || 0;
     documentData.ascent = fontData.ascent * documentData.finalSize / 100;
   };
-
   TextProperty.prototype.updateDocumentData = function (newData, index) {
     index = index === undefined ? this.keysIndex : index;
     var dData = this.copyData({}, this.data.d.k[index].s);
@@ -10969,7 +9276,6 @@
     this.setCurrentData(dData);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.recalculate = function (index) {
     var dData = this.data.d.k[index].s;
     dData.__complete = false;
@@ -10977,13 +9283,11 @@
     this._isFirstFrame = true;
     this.getValue(dData);
   };
-
   TextProperty.prototype.canResizeFont = function (_canResize) {
     this.canResize = _canResize;
     this.recalculate(this.keysIndex);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
     this.minimumFontSize = Math.floor(_fontValue) || 1;
     this.recalculate(this.keysIndex);
@@ -10994,7 +9298,6 @@
     var max = Math.max;
     var min = Math.min;
     var floor = Math.floor;
-
     function TextSelectorPropFactory(elem, data) {
       this._currentTextLength = -1;
       this.k = false;
@@ -11007,7 +9310,6 @@
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: 0
       }, 0, 0, this);
-
       if ('e' in data) {
         this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
       } else {
@@ -11015,7 +9317,6 @@
           v: 100
         };
       }
-
       this.o = PropertyFactory.getProp(elem, data.o || {
         k: 0
       }, 0, 0, this);
@@ -11029,48 +9330,40 @@
         k: 100
       }, 0, 0, this);
       this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
-
       if (!this.dynamicProperties.length) {
         this.getValue();
       }
     }
-
     TextSelectorPropFactory.prototype = {
       getMult: function getMult(ind) {
         if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
           this.getValue();
         }
-
         var x1 = 0;
         var y1 = 0;
         var x2 = 1;
         var y2 = 1;
-
         if (this.ne.v > 0) {
           x1 = this.ne.v / 100.0;
         } else {
           y1 = -this.ne.v / 100.0;
         }
-
         if (this.xe.v > 0) {
           x2 = 1.0 - this.xe.v / 100.0;
         } else {
           y2 = 1.0 + this.xe.v / 100.0;
         }
-
         var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
         var mult = 0;
         var s = this.finalS;
         var e = this.finalE;
         var type = this.data.sh;
-
         if (type === 2) {
           if (e === s) {
             mult = ind >= e ? 1 : 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 3) {
           if (e === s) {
@@ -11078,21 +9371,18 @@
           } else {
             mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 4) {
           if (e === s) {
             mult = 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
-
             if (mult < 0.5) {
               mult *= 2;
             } else {
               mult = 1 - 2 * (mult - 0.5);
             }
           }
-
           mult = easer(mult);
         } else if (type === 5) {
           if (e === s) {
@@ -11101,13 +9391,11 @@
             var tot = e - s;
             /* ind += 0.5;
                       mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
-
             ind = min(max(0, ind + 0.5 - s), e - s);
             var x = -tot / 2 + ind;
             var a = tot / 2;
             mult = Math.sqrt(1 - x * x / (a * a));
           }
-
           mult = easer(mult);
         } else if (type === 6) {
           if (e === s) {
@@ -11116,7 +9404,6 @@
             ind = min(max(0, ind + 0.5 - s), e - s);
             mult = (1 + Math.cos(Math.PI + Math.PI * 2 * ind / (e - s))) / 2; // eslint-disable-line
           }
-
           mult = easer(mult);
         } else {
           if (ind >= floor(s)) {
@@ -11126,9 +9413,9 @@
               mult = max(0, min(e - ind, 1));
             }
           }
-
           mult = easer(mult);
-        } // Smoothness implementation.
+        }
+        // Smoothness implementation.
         // The smoothness represents a reduced range of the original [0; 1] range.
         // if smoothness is 25%, the new range will be [0.375; 0.625]
         // Steps are:
@@ -11138,60 +9425,47 @@
         //     - subtract the threshold
         //     - divide it by the smoothness (this will return the range to [0; 1])
         // Note: If it doesn't work on some scenarios, consider applying it before the easer.
-
-
         if (this.sm.v !== 100) {
           var smoothness = this.sm.v * 0.01;
-
           if (smoothness === 0) {
             smoothness = 0.00000001;
           }
-
           var threshold = 0.5 - smoothness * 0.5;
-
           if (mult < threshold) {
             mult = 0;
           } else {
             mult = (mult - threshold) / smoothness;
-
             if (mult > 1) {
               mult = 1;
             }
           }
         }
-
         return mult * this.a.v;
       },
       getValue: function getValue(newCharsFlag) {
         this.iterateDynamicProperties();
         this._mdf = newCharsFlag || this._mdf;
         this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
-
         if (newCharsFlag && this.data.r === 2) {
           this.e.v = this._currentTextLength;
         }
-
         var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
         var o = this.o.v / divisor;
         var s = this.s.v / divisor + o;
         var e = this.e.v / divisor + o;
-
         if (s > e) {
           var _s = s;
           s = e;
           e = _s;
         }
-
         this.finalS = s;
         this.finalE = e;
       }
     };
     extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
-
     function getTextSelectorProp(elem, data, arr) {
       return new TextSelectorPropFactory(elem, data, arr);
     }
-
     return {
       getTextSelectorProp: getTextSelectorProp
     };
@@ -11241,18 +9515,15 @@
     this.lettersChangedFlag = false;
     this.initDynamicPropertyContainer(elem);
   }
-
   TextAnimatorProperty.prototype.searchProperties = function () {
     var i;
     var len = this._textData.a.length;
     var animatorProps;
     var getProp = PropertyFactory.getProp;
-
     for (i = 0; i < len; i += 1) {
       animatorProps = this._textData.a[i];
       this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
     }
-
     if (this._textData.p && 'm' in this._textData.p) {
       this._pathData = {
         a: getProp(this._elem, this._textData.p.a, 0, 0, this),
@@ -11266,17 +9537,13 @@
     } else {
       this._hasMaskedPath = false;
     }
-
     this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
   };
-
   TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
     this.lettersChangedFlag = lettersChangedFlag;
-
     if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
       return;
     }
-
     this._isFirstFrame = false;
     var alignment = this._moreOptions.alignment.v;
     var animators = this._animatorsData;
@@ -11304,18 +9571,14 @@
     var perc;
     var tanAngle;
     var mask;
-
     if (this._hasMaskedPath) {
       mask = this._pathData.m;
-
       if (!this._pathData.n || this._pathData._mdf) {
         var paths = mask.v;
-
         if (this._pathData.r.v) {
           paths = paths.reverse();
-        } // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
-
-
+        }
+        // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
         pathInfo = {
           tLength: 0,
           segments: []
@@ -11323,26 +9586,21 @@
         len = paths._length - 1;
         var bezierData;
         totalLength = 0;
-
         for (i = 0; i < len; i += 1) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[i + 1], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         i = len;
-
         if (mask.v.c) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[0], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         this._pathData.pi = pathInfo;
       }
-
       pathInfo = this._pathData.pi;
       currentLength = this._pathData.f.v;
       segmentInd = 0;
@@ -11350,20 +9608,16 @@
       segmentLength = 0;
       flag = true;
       segments = pathInfo.segments;
-
       if (currentLength < 0 && mask.v.c) {
         if (pathInfo.tLength < Math.abs(currentLength)) {
           currentLength = -Math.abs(currentLength) % pathInfo.tLength;
         }
-
         segmentInd = segments.length - 1;
         points = segments[segmentInd].points;
         pointInd = points.length - 1;
-
         while (currentLength < 0) {
           currentLength += points[pointInd].partialLength;
           pointInd -= 1;
-
           if (pointInd < 0) {
             segmentInd -= 1;
             points = segments[segmentInd].points;
@@ -11371,13 +9625,11 @@
           }
         }
       }
-
       points = segments[segmentInd].points;
       prevPoint = points[pointInd - 1];
       currentPoint = points[pointInd];
       partialLength = currentPoint.partialLength;
     }
-
     len = letters.length;
     xPos = 0;
     yPos = 0;
@@ -11408,40 +9660,35 @@
     var letterFc;
     var letterM = '';
     var letterP = this.defaultPropsArray;
-    var letterO; //
+    var letterO;
 
+    //
     if (documentData.j === 2 || documentData.j === 1) {
       var animatorJustifyOffset = 0;
       var animatorFirstCharOffset = 0;
       var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
       var lastIndex = 0;
       var isNewLine = true;
-
       for (i = 0; i < len; i += 1) {
         if (letters[i].n) {
           if (animatorJustifyOffset) {
             animatorJustifyOffset += animatorFirstCharOffset;
           }
-
           while (lastIndex < i) {
             letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
             lastIndex += 1;
           }
-
           animatorJustifyOffset = 0;
           isNewLine = true;
         } else {
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.t.propType) {
               if (isNewLine && documentData.j === 2) {
                 animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
               }
-
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
               } else {
@@ -11449,33 +9696,28 @@
               }
             }
           }
-
           isNewLine = false;
         }
       }
-
       if (animatorJustifyOffset) {
         animatorJustifyOffset += animatorFirstCharOffset;
       }
-
       while (lastIndex < i) {
         letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
         lastIndex += 1;
       }
-    } //
-
+    }
+    //
 
     for (i = 0; i < len; i += 1) {
       matrixHelper.reset();
       elemOpacity = 1;
-
       if (letters[i].n) {
         xPos = 0;
         yPos += documentData.yOffset;
         yPos += firstLine ? 1 : 0;
         currentLength = initPathPos;
         firstLine = false;
-
         if (this._hasMaskedPath) {
           segmentInd = initSegmentInd;
           pointInd = initPointInd;
@@ -11485,7 +9727,6 @@
           partialLength = currentPoint.partialLength;
           segmentLength = 0;
         }
-
         letterM = '';
         letterFc = '';
         letterSw = '';
@@ -11498,48 +9739,37 @@
               case 1:
                 currentLength += totalLength - documentData.lineWidths[letters[i].line];
                 break;
-
               case 2:
                 currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
                 break;
-
               default:
                 break;
             }
-
             currentLine = letters[i].line;
           }
-
           if (ind !== letters[i].ind) {
             if (letters[ind]) {
               currentLength += letters[ind].extra;
             }
-
             currentLength += letters[i].an / 2;
             ind = letters[i].ind;
           }
-
           currentLength += alignment[0] * letters[i].an * 0.005;
           var animatorOffset = 0;
-
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.p.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.p.v[0] * mult[0];
               } else {
                 animatorOffset += animatorProps.p.v[0] * mult;
               }
             }
-
             if (animatorProps.a.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.a.v[0] * mult[0];
               } else {
@@ -11547,14 +9777,12 @@
               }
             }
           }
-
-          flag = true; // Force alignment only works with a single line for now
-
+          flag = true;
+          // Force alignment only works with a single line for now
           if (this._pathData.a.v) {
             currentLength = letters[0].an * 0.5 + (totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind / (len - 1);
             currentLength += this._pathData.f.v;
           }
-
           while (flag) {
             if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
               perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
@@ -11565,11 +9793,9 @@
             } else if (points) {
               segmentLength += currentPoint.partialLength;
               pointInd += 1;
-
               if (pointInd >= points.length) {
                 pointInd = 0;
                 segmentInd += 1;
-
                 if (!segments[segmentInd]) {
                   if (mask.v.c) {
                     pointInd = 0;
@@ -11583,7 +9809,6 @@
                   points = segments[segmentInd].points;
                 }
               }
-
               if (points) {
                 prevPoint = currentPoint;
                 currentPoint = points[pointInd];
@@ -11591,23 +9816,21 @@
               }
             }
           }
-
           offf = letters[i].an / 2 - letters[i].add;
           matrixHelper.translate(-offf, 0, 0);
         } else {
           offf = letters[i].an / 2 - letters[i].add;
-          matrixHelper.translate(-offf, 0, 0); // Grouping alignment
+          matrixHelper.translate(-offf, 0, 0);
 
+          // Grouping alignment
           matrixHelper.translate(-alignment[0] * letters[i].an * 0.005, -alignment[1] * yOff * 0.01, 0);
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.t.propType) {
             animatorSelector = animators[j].s;
-            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars); // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
-
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
             if (xPos !== 0 || documentData.j !== 0) {
               if (this._hasMaskedPath) {
                 if (mult.length) {
@@ -11623,11 +9846,9 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           sw = documentData.sw || 0;
         }
-
         if (documentData.strokeColorAnim) {
           if (documentData.sc) {
             sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
@@ -11635,18 +9856,14 @@
             sc = [0, 0, 0];
           }
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.a.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
             } else {
@@ -11654,14 +9871,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.s.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.scale(1 + (animatorProps.s.v[0] - 1) * mult[0], 1 + (animatorProps.s.v[1] - 1) * mult[1], 1);
             } else {
@@ -11669,12 +9883,10 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
           animatorSelector = animators[j].s;
           mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
           if (animatorProps.sk.propType) {
             if (mult.length) {
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
@@ -11682,7 +9894,6 @@
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
             }
           }
-
           if (animatorProps.r.propType) {
             if (mult.length) {
               matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
@@ -11690,7 +9901,6 @@
               matrixHelper.rotateZ(-animatorProps.r.v * mult);
             }
           }
-
           if (animatorProps.ry.propType) {
             if (mult.length) {
               matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
@@ -11698,7 +9908,6 @@
               matrixHelper.rotateY(animatorProps.ry.v * mult);
             }
           }
-
           if (animatorProps.rx.propType) {
             if (mult.length) {
               matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
@@ -11706,7 +9915,6 @@
               matrixHelper.rotateX(animatorProps.rx.v * mult);
             }
           }
-
           if (animatorProps.o.propType) {
             if (mult.length) {
               elemOpacity += (animatorProps.o.v * mult[0] - elemOpacity) * mult[0];
@@ -11714,7 +9922,6 @@
               elemOpacity += (animatorProps.o.v * mult - elemOpacity) * mult;
             }
           }
-
           if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
             if (mult.length) {
               sw += animatorProps.sw.v * mult[0];
@@ -11722,7 +9929,6 @@
               sw += animatorProps.sw.v * mult;
             }
           }
-
           if (documentData.strokeColorAnim && animatorProps.sc.propType) {
             for (k = 0; k < 3; k += 1) {
               if (mult.length) {
@@ -11732,7 +9938,6 @@
               }
             }
           }
-
           if (documentData.fillColorAnim && documentData.fc) {
             if (animatorProps.fc.propType) {
               for (k = 0; k < 3; k += 1) {
@@ -11743,7 +9948,6 @@
                 }
               }
             }
-
             if (animatorProps.fh.propType) {
               if (mult.length) {
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
@@ -11751,7 +9955,6 @@
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult);
               }
             }
-
             if (animatorProps.fs.propType) {
               if (mult.length) {
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
@@ -11759,7 +9962,6 @@
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
               }
             }
-
             if (animatorProps.fb.propType) {
               if (mult.length) {
                 fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
@@ -11769,14 +9971,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.p.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (this._hasMaskedPath) {
               if (mult.length) {
                 matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
@@ -11790,68 +9989,53 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           letterSw = sw < 0 ? 0 : sw;
         }
-
         if (documentData.strokeColorAnim) {
           letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
         }
-
         if (this._hasMaskedPath) {
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(0, alignment[1] * yOff * 0.01 + yPos, 0);
-
           if (this._pathData.p.v) {
             tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
             var rot = Math.atan(tanAngle) * 180 / Math.PI;
-
             if (currentPoint.point[0] < prevPoint.point[0]) {
               rot += 180;
             }
-
             matrixHelper.rotate(-rot * Math.PI / 180);
           }
-
           matrixHelper.translate(xPathPos, yPathPos, 0);
           currentLength -= alignment[0] * letters[i].an * 0.005;
-
           if (letters[i + 1] && ind !== letters[i + 1].ind) {
             currentLength += letters[i].an / 2;
             currentLength += documentData.tr * 0.001 * documentData.finalSize;
           }
         } else {
           matrixHelper.translate(xPos, yPos, 0);
-
           if (documentData.ps) {
             // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
             matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
           }
-
           switch (documentData.j) {
             case 1:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
               break;
-
             case 2:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
               break;
-
             default:
               break;
           }
-
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(offf, 0, 0);
           matrixHelper.translate(alignment[0] * letters[i].an * 0.005, alignment[1] * yOff * 0.01, 0);
           xPos += letters[i].l + documentData.tr * 0.001 * documentData.finalSize;
         }
-
         if (renderType === 'html') {
           letterM = matrixHelper.toCSS();
         } else if (renderType === 'svg') {
@@ -11859,10 +10043,8 @@
         } else {
           letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
         }
-
         letterO = elemOpacity;
       }
-
       if (renderedLettersCount <= i) {
         letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
         this.renderedLetters.push(letterValue);
@@ -11874,22 +10056,18 @@
       }
     }
   };
-
   TextAnimatorProperty.prototype.getValue = function () {
     if (this._elem.globalData.frameId === this._frameId) {
       return;
     }
-
     this._frameId = this._elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   TextAnimatorProperty.prototype.mHelper = new Matrix();
   TextAnimatorProperty.prototype.defaultPropsArray = [];
   extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
 
   function ITextElement() {}
-
   ITextElement.prototype.initElement = function (data, globalData, comp) {
     this.lettersChangedFlag = true;
     this.initFrame();
@@ -11906,72 +10084,55 @@
     this.hide();
     this.textAnimator.searchProperties(this.dynamicProperties);
   };
-
   ITextElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
   };
-
   ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
     var j;
     var jLen = shapes.length;
     var pathNodes;
     var shapeStr = '';
-
     for (j = 0; j < jLen; j += 1) {
       if (shapes[j].ty === 'sh') {
         pathNodes = shapes[j].ks.k;
         shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
       }
     }
-
     return shapeStr;
   };
-
   ITextElement.prototype.updateDocumentData = function (newData, index) {
     this.textProperty.updateDocumentData(newData, index);
   };
-
   ITextElement.prototype.canResizeFont = function (_canResize) {
     this.textProperty.canResizeFont(_canResize);
   };
-
   ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
     this.textProperty.setMinimumFontSize(_fontSize);
   };
-
   ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
     if (documentData.ps) {
       matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
     }
-
     matrixHelper.translate(0, -documentData.ls, 0);
-
     switch (documentData.j) {
       case 1:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
         break;
-
       case 2:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
         break;
-
       default:
         break;
     }
-
     matrixHelper.translate(xPos, yPos, 0);
   };
-
   ITextElement.prototype.buildColor = function (colorData) {
     return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
   };
-
   ITextElement.prototype.emptyProp = new LetterProps();
-
   ITextElement.prototype.destroy = function () {};
-
   ITextElement.prototype.validateText = function () {
     if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
       this.buildNewText();
@@ -11983,27 +10144,22 @@
   var emptyShapeData = {
     shapes: []
   };
-
   function SVGTextLottieElement(data, globalData, comp) {
     this.textSpans = [];
     this.renderType = 'svg';
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
-
   SVGTextLottieElement.prototype.createContent = function () {
     if (this.data.singleShape && !this.globalData.fontManager.chars) {
       this.textContainer = createNS('text');
     }
   };
-
   SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
     var i = 0;
     var len = textArray.length;
     var textContents = [];
     var currentTextContent = '';
-
     while (i < len) {
       if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
         textContents.push(currentTextContent);
@@ -12011,14 +10167,11 @@
       } else {
         currentTextContent += textArray[i];
       }
-
       i += 1;
     }
-
     textContents.push(currentTextContent);
     return textContents;
   };
-
   SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
     // data should probably be cloned to apply scale separately to each instance of a text on different layers
     // but since text internal content gets only rendered once and then it's never rerendered,
@@ -12026,41 +10179,33 @@
     // Avoiding cloning is preferred since cloning each character shape data is expensive
     if (data.shapes && data.shapes.length) {
       var shape = data.shapes[0];
-
       if (shape.it) {
         var shapeItem = shape.it[shape.it.length - 1];
-
         if (shapeItem.s) {
           shapeItem.s.k[0] = scale;
           shapeItem.s.k[1] = scale;
         }
       }
     }
-
     return data;
   };
-
   SVGTextLottieElement.prototype.buildNewText = function () {
     this.addDynamicProperty(this);
     var i;
     var len;
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
-
     if (documentData.fc) {
       this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
     } else {
       this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
     }
-
     if (documentData.sc) {
       this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
       this.layerElement.setAttribute('stroke-width', documentData.sw);
     }
-
     this.layerElement.setAttribute('font-size', documentData.finalSize);
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
-
     if (fontData.fClass) {
       this.layerElement.setAttribute('class', fontData.fClass);
     } else {
@@ -12070,7 +10215,6 @@
       this.layerElement.setAttribute('font-style', fStyle);
       this.layerElement.setAttribute('font-weight', fWeight);
     }
-
     this.layerElement.setAttribute('aria-label', documentData.t);
     var letters = documentData.l || [];
     var usesGlyphs = !!this.globalData.fontManager.chars;
@@ -12083,31 +10227,25 @@
     var yPos = 0;
     var firstLine = true;
     var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
-
     if (singleShape && !usesGlyphs && !documentData.sz) {
       var tElement = this.textContainer;
       var justify = 'start';
-
       switch (documentData.j) {
         case 1:
           justify = 'end';
           break;
-
         case 2:
           justify = 'middle';
           break;
-
         default:
           justify = 'start';
           break;
       }
-
       tElement.setAttribute('text-anchor', justify);
       tElement.setAttribute('letter-spacing', trackingOffset);
       var textContent = this.buildTextContents(documentData.finalText);
       len = textContent.length;
       yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
-
       for (i = 0; i < len; i += 1) {
         tSpan = this.textSpans[i].span || createNS('tspan');
         tSpan.textContent = textContent[i];
@@ -12115,23 +10253,19 @@
         tSpan.setAttribute('y', yPos);
         tSpan.style.display = 'inherit';
         tElement.appendChild(tSpan);
-
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
             span: null,
             glyph: null
           };
         }
-
         this.textSpans[i].span = tSpan;
         yPos += documentData.finalLineHeight;
       }
-
       this.layerElement.appendChild(tElement);
     } else {
       var cachedSpansLength = this.textSpans.length;
       var charData;
-
       for (i = 0; i < len; i += 1) {
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
@@ -12140,31 +10274,24 @@
             glyph: null
           };
         }
-
         if (!usesGlyphs || !singleShape || i === 0) {
           tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
-
           if (cachedSpansLength <= i) {
             tSpan.setAttribute('stroke-linecap', 'butt');
             tSpan.setAttribute('stroke-linejoin', 'round');
             tSpan.setAttribute('stroke-miterlimit', '4');
             this.textSpans[i].span = tSpan;
-
             if (usesGlyphs) {
               var childSpan = createNS('g');
               tSpan.appendChild(childSpan);
               this.textSpans[i].childSpan = childSpan;
             }
-
             this.textSpans[i].span = tSpan;
             this.layerElement.appendChild(tSpan);
           }
-
           tSpan.style.display = 'inherit';
         }
-
         matrixHelper.reset();
-
         if (singleShape) {
           if (letters[i].n) {
             xPos = -trackingOffset;
@@ -12172,42 +10299,36 @@
             yPos += firstLine ? 1 : 0;
             firstLine = false;
           }
-
           this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
-          xPos += letters[i].l || 0; // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
-
+          xPos += letters[i].l || 0;
+          // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
           xPos += trackingOffset;
         }
-
         if (usesGlyphs) {
           charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
-          var glyphElement; // t === 1 means the character has been replaced with an animated shaped
-
+          var glyphElement;
+          // t === 1 means the character has been replaced with an animated shaped
           if (charData.t === 1) {
             glyphElement = new SVGCompElement(charData.data, this.globalData, this);
           } else {
             var data = emptyShapeData;
-
             if (charData.data && charData.data.shapes) {
               data = this.buildShapeData(charData.data, documentData.finalSize);
             }
-
             glyphElement = new SVGShapeElement(data, this.globalData, this);
           }
-
           if (this.textSpans[i].glyph) {
             var glyph = this.textSpans[i].glyph;
             this.textSpans[i].childSpan.removeChild(glyph.layerElement);
             glyph.destroy();
           }
-
           this.textSpans[i].glyph = glyphElement;
           glyphElement._debug = true;
           glyphElement.prepareFrame(0);
           glyphElement.renderFrame();
-          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement); // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+          // when using animated shapes, the layer will be scaled instead of replacing the internal scale
           // this might have issues with strokes and might need a different solution
-
           if (charData.t === 1) {
             this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
           }
@@ -12215,30 +10336,24 @@
           if (singleShape) {
             tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
           }
-
           tSpan.textContent = letters[i].val;
           tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
-        } //
-
+        }
+        //
       }
-
       if (singleShape && tSpan) {
         tSpan.setAttribute('d', shapeStr);
       }
     }
-
     while (i < this.textSpans.length) {
       this.textSpans[i].span.style.display = 'none';
       i += 1;
     }
-
     this._sizeChanged = true;
   };
-
   SVGTextLottieElement.prototype.sourceRectAtTime = function () {
     this.prepareFrame(this.comp.renderedFrame - this.data.st);
     this.renderInnerContent();
-
     if (this._sizeChanged) {
       this._sizeChanged = false;
       var textBox = this.layerElement.getBBox();
@@ -12249,35 +10364,27 @@
         height: textBox.height
       };
     }
-
     return this.bbox;
   };
-
   SVGTextLottieElement.prototype.getValue = function () {
     var i;
     var len = this.textSpans.length;
     var glyphElement;
     this.renderedFrame = this.comp.renderedFrame;
-
     for (i = 0; i < len; i += 1) {
       glyphElement = this.textSpans[i].glyph;
-
       if (glyphElement) {
         glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
-
         if (glyphElement._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   SVGTextLottieElement.prototype.renderInnerContent = function () {
     this.validateText();
-
     if (!this.data.singleShape || this._mdf) {
       this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
-
       if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
         this._sizeChanged = true;
         var i;
@@ -12288,33 +10395,26 @@
         var renderedLetter;
         var textSpan;
         var glyphElement;
-
         for (i = 0; i < len; i += 1) {
           if (!letters[i].n) {
             renderedLetter = renderedLetters[i];
             textSpan = this.textSpans[i].span;
             glyphElement = this.textSpans[i].glyph;
-
             if (glyphElement) {
               glyphElement.renderFrame();
             }
-
             if (renderedLetter._mdf.m) {
               textSpan.setAttribute('transform', renderedLetter.m);
             }
-
             if (renderedLetter._mdf.o) {
               textSpan.setAttribute('opacity', renderedLetter.o);
             }
-
             if (renderedLetter._mdf.sw) {
               textSpan.setAttribute('stroke-width', renderedLetter.sw);
             }
-
             if (renderedLetter._mdf.sc) {
               textSpan.setAttribute('stroke', renderedLetter.sc);
             }
-
             if (renderedLetter._mdf.fc) {
               textSpan.setAttribute('fill', renderedLetter.fc);
             }
@@ -12327,14 +10427,12 @@
   function ISolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([IImageElement], ISolidElement);
-
   ISolidElement.prototype.createContent = function () {
-    var rect = createNS('rect'); /// /rect.style.width = this.data.sw;
+    var rect = createNS('rect');
+    /// /rect.style.width = this.data.sw;
     /// /rect.style.height = this.data.sh;
     /// /rect.style.fill = this.data.sc;
-
     rect.setAttribute('width', this.data.sw);
     rect.setAttribute('height', this.data.sh);
     rect.setAttribute('fill', this.data.sc);
@@ -12348,59 +10446,43 @@
     this.initTransform(data, globalData, comp);
     this.initHierarchy();
   }
-
   NullElement.prototype.prepareFrame = function (num) {
     this.prepareProperties(num, true);
   };
-
   NullElement.prototype.renderFrame = function () {};
-
   NullElement.prototype.getBaseElement = function () {
     return null;
   };
-
   NullElement.prototype.destroy = function () {};
-
   NullElement.prototype.sourceRectAtTime = function () {};
-
   NullElement.prototype.hide = function () {};
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
 
   function SVGRendererBase() {}
-
   extendPrototype([BaseRenderer], SVGRendererBase);
-
   SVGRendererBase.prototype.createNull = function (data) {
     return new NullElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createShape = function (data) {
     return new SVGShapeElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createText = function (data) {
     return new SVGTextLottieElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createImage = function (data) {
     return new IImageElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createSolid = function (data) {
     return new ISolidElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.configAnimation = function (animData) {
     this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
     this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
-
     if (this.renderConfig.viewBoxSize) {
       this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
     } else {
       this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
     }
-
     if (!this.renderConfig.viewBoxOnly) {
       this.svgElement.setAttribute('width', animData.w);
       this.svgElement.setAttribute('height', animData.h);
@@ -12409,32 +10491,26 @@
       this.svgElement.style.transform = 'translate3d(0,0,0)';
       this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
     }
-
     if (this.renderConfig.width) {
       this.svgElement.setAttribute('width', this.renderConfig.width);
     }
-
     if (this.renderConfig.height) {
       this.svgElement.setAttribute('height', this.renderConfig.height);
     }
-
     if (this.renderConfig.className) {
       this.svgElement.setAttribute('class', this.renderConfig.className);
     }
-
     if (this.renderConfig.id) {
       this.svgElement.setAttribute('id', this.renderConfig.id);
     }
-
     if (this.renderConfig.focusable !== undefined) {
       this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
     }
-
-    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio); // this.layerElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+    // this.layerElement.style.transform = 'translate3d(0,0,0)';
     // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
-
-    this.animationItem.wrapper.appendChild(this.svgElement); // Mask animation
-
+    this.animationItem.wrapper.appendChild(this.svgElement);
+    // Mask animation
     var defs = this.globalData.defs;
     this.setupGlobalData(animData, defs);
     this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
@@ -12453,71 +10529,54 @@
     this.layers = animData.layers;
     this.elements = createSizedArray(animData.layers.length);
   };
-
   SVGRendererBase.prototype.destroy = function () {
     if (this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     this.layerElement = null;
     this.globalData.defs = null;
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.destroyed = true;
     this.animationItem = null;
   };
-
   SVGRendererBase.prototype.updateContainerSize = function () {};
-
   SVGRendererBase.prototype.findIndexByInd = function (ind) {
     var i = 0;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.layers[i].ind === ind) {
         return i;
       }
     }
-
     return -1;
   };
-
   SVGRendererBase.prototype.buildItem = function (pos) {
     var elements = this.elements;
-
     if (elements[pos] || this.layers[pos].ty === 99) {
       return;
     }
-
     elements[pos] = true;
     var element = this.createItem(this.layers[pos]);
     elements[pos] = element;
-
     if (getExpressionsPlugin()) {
       if (this.layers[pos].ty === 0) {
         this.globalData.projectInterface.registerComposition(element);
       }
-
       element.initExpressions();
     }
-
     this.appendElementInPos(element, pos);
-
     if (this.layers[pos].tt) {
       var elementIndex = 'tp' in this.layers[pos] ? this.findIndexByInd(this.layers[pos].tp) : pos - 1;
-
       if (elementIndex === -1) {
         return;
       }
-
       if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
         this.buildItem(elementIndex);
         this.addPendingElement(element);
@@ -12528,16 +10587,13 @@
       }
     }
   };
-
   SVGRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
-
       if (element.data.tt) {
         var i = 0;
         var len = this.elements.length;
-
         while (i < len) {
           if (this.elements[i] === element) {
             var elementIndex = 'tp' in element.data ? this.findIndexByInd(element.data.tp) : i - 1;
@@ -12546,43 +10602,36 @@
             element.setMatte(matteMask);
             break;
           }
-
           i += 1;
         }
       }
     }
   };
-
   SVGRendererBase.prototype.renderFrame = function (num) {
     if (this.renderedFrame === num || this.destroyed) {
       return;
     }
-
     if (num === null) {
       num = this.renderedFrame;
     } else {
       this.renderedFrame = num;
-    } // console.log('-------');
+    }
+    // console.log('-------');
     // console.log('FRAME ',num);
-
-
     this.globalData.frameNum = num;
     this.globalData.frameId += 1;
     this.globalData.projectInterface.currentFrame = num;
     this.globalData._mdf = false;
     var i;
     var len = this.layers.length;
-
     if (!this.completeLayers) {
       this.checkLayers(num);
     }
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(num - this.layers[i].st);
       }
     }
-
     if (this.globalData._mdf) {
       for (i = 0; i < len; i += 1) {
         if (this.completeLayers || this.elements[i]) {
@@ -12591,44 +10640,34 @@
       }
     }
   };
-
   SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
     var newElement = element.getBaseElement();
-
     if (!newElement) {
       return;
     }
-
     var i = 0;
     var nextElement;
-
     while (i < pos) {
       if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
         nextElement = this.elements[i].getBaseElement();
       }
-
       i += 1;
     }
-
     if (nextElement) {
       this.layerElement.insertBefore(newElement, nextElement);
     } else {
       this.layerElement.appendChild(newElement);
     }
   };
-
   SVGRendererBase.prototype.hide = function () {
     this.layerElement.style.display = 'none';
   };
-
   SVGRendererBase.prototype.show = function () {
     this.layerElement.style.display = 'block';
   };
 
   function ICompElement() {}
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
-
   ICompElement.prototype.initElement = function (data, globalData, comp) {
     this.initFrame();
     this.initBaseData(data, globalData, comp);
@@ -12638,13 +10677,12 @@
     this.initRendererElement();
     this.createContainerElements();
     this.createRenderableComponents();
-
     if (this.data.xt || !globalData.progressiveLoad) {
       this.buildAllItems();
     }
-
     this.hide();
   };
+
   /* ICompElement.prototype.hide = function(){
       if(!this.hidden){
           this.hideElement();
@@ -12657,77 +10695,61 @@
       }
   }; */
 
-
   ICompElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
-
     if (!this.isInRange && !this.data.xt) {
       return;
     }
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
-
       if (timeRemapped === this.data.op) {
         timeRemapped = this.data.op - 1;
       }
-
       this.renderedFrame = timeRemapped;
     } else {
       this.renderedFrame = num / this.data.sr;
     }
-
     var i;
     var len = this.elements.length;
-
     if (!this.completeLayers) {
       this.checkLayers(this.renderedFrame);
-    } // This iteration needs to be backwards because of how expressions connect between each other
-
-
+    }
+    // This iteration needs to be backwards because of how expressions connect between each other
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
-
         if (this.elements[i]._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   ICompElement.prototype.renderInnerContent = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].renderFrame();
       }
     }
   };
-
   ICompElement.prototype.setElements = function (elems) {
     this.elements = elems;
   };
-
   ICompElement.prototype.getElements = function () {
     return this.elements;
   };
-
   ICompElement.prototype.destroyElements = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i]) {
         this.elements[i].destroy();
       }
     }
   };
-
   ICompElement.prototype.destroy = function () {
     this.destroyElements();
     this.destroyBaseElement();
@@ -12744,9 +10766,7 @@
       _placeholder: true
     };
   }
-
   extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
-
   SVGCompElement.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
@@ -12757,7 +10777,6 @@
     this.renderedFrame = -1;
     this.svgElement = createNS('svg');
     var ariaLabel = '';
-
     if (config && config.title) {
       var titleElement = createNS('title');
       var titleId = createElementID();
@@ -12766,7 +10785,6 @@
       this.svgElement.appendChild(titleElement);
       ariaLabel += titleId;
     }
-
     if (config && config.description) {
       var descElement = createNS('desc');
       var descId = createElementID();
@@ -12775,11 +10793,9 @@
       this.svgElement.appendChild(descElement);
       ariaLabel += ' ' + descId;
     }
-
     if (ariaLabel) {
       this.svgElement.setAttribute('aria-labelledby', ariaLabel);
     }
-
     var defs = createNS('defs');
     this.svgElement.appendChild(defs);
     var maskElement = createNS('g');
@@ -12817,9 +10833,7 @@
     this.destroyed = false;
     this.rendererType = 'svg';
   }
-
   extendPrototype([SVGRendererBase], SVGRenderer);
-
   SVGRenderer.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
@@ -12829,19 +10843,15 @@
     this.sequenceList = [];
     this.transform_key_count = 0;
   }
-
   ShapeTransformManager.prototype = {
     addTransformSequence: function addTransformSequence(transforms) {
       var i;
       var len = transforms.length;
       var key = '_';
-
       for (i = 0; i < len; i += 1) {
         key += transforms[i].transform.key + '_';
       }
-
       var sequence = this.sequences[key];
-
       if (!sequence) {
         sequence = {
           transforms: [].concat(transforms),
@@ -12851,37 +10861,30 @@
         this.sequences[key] = sequence;
         this.sequenceList.push(sequence);
       }
-
       return sequence;
     },
     processSequence: function processSequence(sequence, isFirstFrame) {
       var i = 0;
       var len = sequence.transforms.length;
       var _mdf = isFirstFrame;
-
       while (i < len && !isFirstFrame) {
         if (sequence.transforms[i].transform.mProps._mdf) {
           _mdf = true;
           break;
         }
-
         i += 1;
       }
-
       if (_mdf) {
         sequence.finalTransform.reset();
-
         for (i = len - 1; i >= 0; i -= 1) {
           sequence.finalTransform.multiply(sequence.transforms[i].transform.mProps.v);
         }
       }
-
       sequence._mdf = _mdf;
     },
     processSequences: function processSequences(isFirstFrame) {
       var i;
       var len = this.sequenceList.length;
-
       for (i = 0; i < len; i += 1) {
         this.processSequence(this.sequenceList[i], isFirstFrame);
       }
@@ -12896,11 +10899,12 @@
     var id = '__lottie_element_luma_buffer';
     var lumaBuffer = null;
     var lumaBufferCtx = null;
-    var svg = null; // This alternate solution has a slight delay before the filter is applied, resulting in a flicker on the first frame.
+    var svg = null;
+
+    // This alternate solution has a slight delay before the filter is applied, resulting in a flicker on the first frame.
     // Keeping this here for reference, and in the future, if offscreen canvas supports url filters, this can be used.
     // For now, neither of them work for offscreen canvas, so canvas workers can't support the luma track matte mask.
     // Naming it solution 2 to mark the extra comment lines.
-
     /*
     var svgString = [
       '<svg xmlns="http://www.w3.org/2000/svg">',
@@ -12920,7 +10924,6 @@
 
     function createLumaSvgFilter() {
       var _svg = createNS('svg');
-
       var fil = createNS('filter');
       var matrix = createNS('feColorMatrix');
       fil.setAttribute('id', id);
@@ -12928,60 +10931,49 @@
       matrix.setAttribute('color-interpolation-filters', 'sRGB');
       matrix.setAttribute('values', '0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0');
       fil.appendChild(matrix);
-
       _svg.appendChild(fil);
-
       _svg.setAttribute('id', id + '_svg');
-
       if (featureSupport.svgLumaHidden) {
         _svg.style.display = 'none';
       }
-
       return _svg;
     }
-
     function loadLuma() {
       if (!lumaBuffer) {
         svg = createLumaSvgFilter();
         document.body.appendChild(svg);
         lumaBuffer = createTag('canvas');
-        lumaBufferCtx = lumaBuffer.getContext('2d'); // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
-
+        lumaBufferCtx = lumaBuffer.getContext('2d');
+        // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
         lumaBufferCtx.filter = 'url(#' + id + ')';
         lumaBufferCtx.fillStyle = 'rgba(0,0,0,0)';
         lumaBufferCtx.fillRect(0, 0, 1, 1);
       }
     }
-
     function getLuma(canvas) {
       if (!lumaBuffer) {
         loadLuma();
       }
-
       lumaBuffer.width = canvas.width;
-      lumaBuffer.height = canvas.height; // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
-
+      lumaBuffer.height = canvas.height;
+      // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
       lumaBufferCtx.filter = 'url(#' + id + ')';
       return lumaBuffer;
     }
-
     return {
       load: loadLuma,
       get: getLuma
     };
   };
-
   function createCanvas(width, height) {
     if (featureSupport.offscreenCanvas) {
       return new OffscreenCanvas(width, height);
     }
-
     var canvas = createTag('canvas');
     canvas.width = width;
     canvas.height = height;
     return canvas;
   }
-
   var assetLoader = function () {
     return {
       loadLumaCanvas: lumaLoader.load,
@@ -12991,55 +10983,44 @@
   }();
 
   var registeredEffects = {};
-
   function CVEffects(elem) {
     var i;
     var len = elem.data.ef ? elem.data.ef.length : 0;
     this.filters = [];
     var filterManager;
-
     for (i = 0; i < len; i += 1) {
       filterManager = null;
       var type = elem.data.ef[i].ty;
-
       if (registeredEffects[type]) {
         var Effect = registeredEffects[type].effect;
         filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
       }
-
       if (filterManager) {
         this.filters.push(filterManager);
       }
     }
-
     if (this.filters.length) {
       elem.addRenderableComponent(this);
     }
   }
-
   CVEffects.prototype.renderFrame = function (_isFirstFrame) {
     var i;
     var len = this.filters.length;
-
     for (i = 0; i < len; i += 1) {
       this.filters[i].renderFrame(_isFirstFrame);
     }
   };
-
   CVEffects.prototype.getEffects = function (type) {
     var i;
     var len = this.filters.length;
     var effects = [];
-
     for (i = 0; i < len; i += 1) {
       if (this.filters[i].type === type) {
         effects.push(this.filters[i]);
       }
     }
-
     return effects;
   };
-
   function registerEffect(id, effect) {
     registeredEffects[id] = {
       effect: effect
@@ -13054,27 +11035,21 @@
     var i;
     var len = this.masksProperties.length;
     var hasMasks = false;
-
     for (i = 0; i < len; i += 1) {
       if (this.masksProperties[i].mode !== 'n') {
         hasMasks = true;
       }
-
       this.viewData[i] = ShapePropertyFactory.getShapeProp(this.element, this.masksProperties[i], 3);
     }
-
     this.hasMasks = hasMasks;
-
     if (hasMasks) {
       this.element.addRenderableComponent(this);
     }
   }
-
   CVMaskElement.prototype.renderFrame = function () {
     if (!this.hasMasks) {
       return;
     }
-
     var transform = this.element.finalTransform.mat;
     var ctx = this.element.canvasContext;
     var i;
@@ -13083,7 +11058,6 @@
     var pts;
     var data;
     ctx.beginPath();
-
     for (i = 0; i < len; i += 1) {
       if (this.masksProperties[i].mode !== 'n') {
         if (this.masksProperties[i].inv) {
@@ -13093,35 +11067,28 @@
           ctx.lineTo(0, this.element.globalData.compSize.h);
           ctx.lineTo(0, 0);
         }
-
         data = this.viewData[i].v;
         pt = transform.applyToPointArray(data.v[0][0], data.v[0][1], 0);
         ctx.moveTo(pt[0], pt[1]);
         var j;
         var jLen = data._length;
-
         for (j = 1; j < jLen; j += 1) {
           pts = transform.applyToTriplePoints(data.o[j - 1], data.i[j], data.v[j]);
           ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
         }
-
         pts = transform.applyToTriplePoints(data.o[j - 1], data.i[0], data.v[0]);
         ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
       }
     }
-
     this.element.globalData.renderer.save(true);
     ctx.clip();
   };
-
   CVMaskElement.prototype.getMaskProperty = MaskElement.prototype.getMaskProperty;
-
   CVMaskElement.prototype.destroy = function () {
     this.element = null;
   };
 
   function CVBaseElement() {}
-
   var operationsMap = {
     1: 'source-in',
     2: 'source-out',
@@ -13144,12 +11111,10 @@
         this.buffers.push(bufferCanvas);
         var bufferCanvas2 = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
         this.buffers.push(bufferCanvas2);
-
         if (this.data.tt >= 3 && !document._isProxy) {
           assetLoader.loadLumaCanvas();
         }
       }
-
       this.canvasContext = this.globalData.canvasContext;
       this.transformCanvas = this.globalData.transformCanvas;
       this.renderableEffectsManager = new CVEffects(this);
@@ -13158,7 +11123,6 @@
     createContent: function createContent() {},
     setBlendMode: function setBlendMode() {
       var globalData = this.globalData;
-
       if (globalData.blendMode !== this.data.bm) {
         globalData.blendMode = this.data.bm;
         var blendModeValue = getBlendMode(this.data.bm);
@@ -13188,11 +11152,11 @@
       if (this.data.tt >= 1) {
         var buffer = this.buffers[0];
         var bufferCtx = buffer.getContext('2d');
-        this.clearCanvas(bufferCtx); // on the first buffer we store the current state of the global drawing
-
-        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0); // The next four lines are to clear the canvas
+        this.clearCanvas(bufferCtx);
+        // on the first buffer we store the current state of the global drawing
+        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+        // The next four lines are to clear the canvas
         // TODO: Check if there is a way to clear the canvas without resetting the transform
-
         this.currentTransform = this.canvasContext.getTransform();
         this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
         this.clearCanvas(this.canvasContext);
@@ -13201,43 +11165,43 @@
     },
     exitLayer: function exitLayer() {
       if (this.data.tt >= 1) {
-        var buffer = this.buffers[1]; // On the second buffer we store the current state of the global drawing
+        var buffer = this.buffers[1];
+        // On the second buffer we store the current state of the global drawing
         // that only contains the content of this layer
         // (if it is a composition, it also includes the nested layers)
-
         var bufferCtx = buffer.getContext('2d');
         this.clearCanvas(bufferCtx);
-        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0); // We clear the canvas again
-
+        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+        // We clear the canvas again
         this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
         this.clearCanvas(this.canvasContext);
-        this.canvasContext.setTransform(this.currentTransform); // We draw the mask
-
+        this.canvasContext.setTransform(this.currentTransform);
+        // We draw the mask
         var mask = this.comp.getElementById('tp' in this.data ? this.data.tp : this.data.ind - 1);
-        mask.renderFrame(true); // We draw the second buffer (that contains the content of this layer)
+        mask.renderFrame(true);
+        // We draw the second buffer (that contains the content of this layer)
+        this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
 
-        this.canvasContext.setTransform(1, 0, 0, 1, 0, 0); // If the mask is a Luma matte, we need to do two extra painting operations
+        // If the mask is a Luma matte, we need to do two extra painting operations
         // the _isProxy check is to avoid drawing a fake canvas in workers that will throw an error
-
         if (this.data.tt >= 3 && !document._isProxy) {
           // We copy the painted mask to a buffer that has a color matrix filter applied to it
           // that applies the rgb values to the alpha channel
           var lumaBuffer = assetLoader.getLumaCanvas(this.canvasContext.canvas);
           var lumaBufferCtx = lumaBuffer.getContext('2d');
           lumaBufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
-          this.clearCanvas(this.canvasContext); // we repaint the context with the mask applied to it
-
+          this.clearCanvas(this.canvasContext);
+          // we repaint the context with the mask applied to it
           this.canvasContext.drawImage(lumaBuffer, 0, 0);
         }
-
         this.canvasContext.globalCompositeOperation = operationsMap[this.data.tt];
-        this.canvasContext.drawImage(buffer, 0, 0); // We finally draw the first buffer (that contains the content of the global drawing)
+        this.canvasContext.drawImage(buffer, 0, 0);
+        // We finally draw the first buffer (that contains the content of the global drawing)
         // We use destination-over to draw the global drawing below the current layer
-
         this.canvasContext.globalCompositeOperation = 'destination-over';
         this.canvasContext.drawImage(this.buffers[0], 0, 0);
-        this.canvasContext.setTransform(this.currentTransform); // We reset the globalCompositeOperation to source-over, the standard type of operation
-
+        this.canvasContext.setTransform(this.currentTransform);
+        // We reset the globalCompositeOperation to source-over, the standard type of operation
         this.canvasContext.globalCompositeOperation = 'source-over';
       }
     },
@@ -13245,11 +11209,9 @@
       if (this.hidden || this.data.hd) {
         return;
       }
-
       if (this.data.td === 1 && !forceRender) {
         return;
       }
-
       this.renderTransform();
       this.renderRenderable();
       this.renderLocalTransform();
@@ -13262,11 +11224,9 @@
       this.renderInnerContent();
       this.globalData.renderer.restore(forceRealStack);
       this.exitLayer();
-
       if (this.maskManager.hasMasks) {
         this.globalData.renderer.restore(true);
       }
-
       if (this._isFirstFrame) {
         this._isFirstFrame = false;
       }
@@ -13286,7 +11246,6 @@
     this.styledShapes = [];
     this.tr = [0, 0, 0, 0, 0, 0];
     var ty = 4;
-
     if (data.ty === 'rc') {
       ty = 5;
     } else if (data.ty === 'el') {
@@ -13294,12 +11253,10 @@
     } else if (data.ty === 'sr') {
       ty = 7;
     }
-
     this.sh = ShapePropertyFactory.getShapeProp(element, data, ty, element);
     var i;
     var len = styles.length;
     var styledShape;
-
     for (i = 0; i < len; i += 1) {
       if (!styles[i].closed) {
         styledShape = {
@@ -13311,7 +11268,6 @@
       }
     }
   }
-
   CVShapeData.prototype.setAsAnimated = SVGShapeData.prototype.setAsAnimated;
 
   function CVShapeElement(data, globalData, comp) {
@@ -13325,7 +11281,6 @@
     this.transformsManager = new ShapeTransformManager();
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableElement], CVShapeElement);
   CVShapeElement.prototype.initElement = RenderableDOMElement.prototype.initElement;
   CVShapeElement.prototype.transformHelper = {
@@ -13333,11 +11288,9 @@
     _opMdf: false
   };
   CVShapeElement.prototype.dashResetter = [];
-
   CVShapeElement.prototype.createContent = function () {
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
   };
-
   CVShapeElement.prototype.createStyleElement = function (data, transforms) {
     var styleElem = {
       data: data,
@@ -13348,10 +11301,8 @@
       closed: data.hd === true
     };
     var elementData = {};
-
     if (data.ty === 'fl' || data.ty === 'st') {
       elementData.c = PropertyFactory.getProp(this, data.c, 1, 255, this);
-
       if (!elementData.c.k) {
         styleElem.co = 'rgb(' + bmFloor(elementData.c.v[0]) + ',' + bmFloor(elementData.c.v[1]) + ',' + bmFloor(elementData.c.v[2]) + ')';
       }
@@ -13366,28 +11317,21 @@
       }, 0, degToRads, this);
       elementData.g = new GradientProperty(this, data.g, this);
     }
-
     elementData.o = PropertyFactory.getProp(this, data.o, 0, 0.01, this);
-
     if (data.ty === 'st' || data.ty === 'gs') {
       styleElem.lc = lineCapEnum[data.lc || 2];
       styleElem.lj = lineJoinEnum[data.lj || 2];
-
       if (data.lj == 1) {
         // eslint-disable-line eqeqeq
         styleElem.ml = data.ml;
       }
-
       elementData.w = PropertyFactory.getProp(this, data.w, 0, null, this);
-
       if (!elementData.w.k) {
         styleElem.wi = elementData.w.v;
       }
-
       if (data.d) {
         var d = new DashProperty(this, data.d, 'canvas', this);
         elementData.d = d;
-
         if (!elementData.d.k) {
           styleElem.da = elementData.d.dashArray;
           styleElem["do"] = elementData.d.dashoffset[0];
@@ -13396,12 +11340,10 @@
     } else {
       styleElem.r = data.r === 2 ? 'evenodd' : 'nonzero';
     }
-
     this.stylesList.push(styleElem);
     elementData.style = styleElem;
     return elementData;
   };
-
   CVShapeElement.prototype.createGroupElement = function () {
     var elementData = {
       it: [],
@@ -13409,7 +11351,6 @@
     };
     return elementData;
   };
-
   CVShapeElement.prototype.createTransformElement = function (data) {
     var elementData = {
       transform: {
@@ -13422,65 +11363,52 @@
     };
     return elementData;
   };
-
   CVShapeElement.prototype.createShapeElement = function (data) {
     var elementData = new CVShapeData(this, data, this.stylesList, this.transformsManager);
     this.shapes.push(elementData);
     this.addShapeToModifiers(elementData);
     return elementData;
   };
-
   CVShapeElement.prototype.reloadShapes = function () {
     this._isFirstFrame = true;
     var i;
     var len = this.itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       this.prevViewData[i] = this.itemsData[i];
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
     len = this.dynamicProperties.length;
-
     for (i = 0; i < len; i += 1) {
       this.dynamicProperties[i].getValue();
     }
-
     this.renderModifiers();
     this.transformsManager.processSequences(this._isFirstFrame);
   };
-
   CVShapeElement.prototype.addTransformToStyleList = function (transform) {
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       if (!this.stylesList[i].closed) {
         this.stylesList[i].transforms.push(transform);
       }
     }
   };
-
   CVShapeElement.prototype.removeTransformFromStyleList = function () {
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       if (!this.stylesList[i].closed) {
         this.stylesList[i].transforms.pop();
       }
     }
   };
-
   CVShapeElement.prototype.closeStyles = function (styles) {
     var i;
     var len = styles.length;
-
     for (i = 0; i < len; i += 1) {
       styles[i].closed = true;
     }
   };
-
   CVShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, shouldRender, transforms) {
     var i;
     var len = arr.length - 1;
@@ -13492,42 +11420,35 @@
     var modifier;
     var currentTransform;
     var ownTransforms = [].concat(transforms);
-
     for (i = len; i >= 0; i -= 1) {
       processedPos = this.searchProcessedElement(arr[i]);
-
       if (!processedPos) {
         arr[i]._shouldRender = shouldRender;
       } else {
         itemsData[i] = prevViewData[processedPos - 1];
       }
-
       if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs') {
         if (!processedPos) {
           itemsData[i] = this.createStyleElement(arr[i], ownTransforms);
         } else {
           itemsData[i].style.closed = false;
         }
-
         ownStyles.push(itemsData[i].style);
       } else if (arr[i].ty === 'gr') {
         if (!processedPos) {
           itemsData[i] = this.createGroupElement(arr[i]);
         } else {
           jLen = itemsData[i].it.length;
-
           for (j = 0; j < jLen; j += 1) {
             itemsData[i].prevViewData[j] = itemsData[i].it[j];
           }
         }
-
         this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, shouldRender, ownTransforms);
       } else if (arr[i].ty === 'tr') {
         if (!processedPos) {
           currentTransform = this.createTransformElement(arr[i]);
           itemsData[i] = currentTransform;
         }
-
         ownTransforms.push(itemsData[i]);
         this.addTransformToStyleList(itemsData[i]);
       } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
@@ -13544,7 +11465,6 @@
           modifier = itemsData[i];
           modifier.closed = false;
         }
-
         ownModifiers.push(modifier);
       } else if (arr[i].ty === 'rp') {
         if (!processedPos) {
@@ -13557,22 +11477,17 @@
           modifier = itemsData[i];
           modifier.closed = true;
         }
-
         ownModifiers.push(modifier);
       }
-
       this.addProcessedElement(arr[i], i + 1);
     }
-
     this.removeTransformFromStyleList();
     this.closeStyles(ownStyles);
     len = ownModifiers.length;
-
     for (i = 0; i < len; i += 1) {
       ownModifiers[i].closed = true;
     }
   };
-
   CVShapeElement.prototype.renderInnerContent = function () {
     this.transformHelper.opacity = 1;
     this.transformHelper._opMdf = false;
@@ -13580,7 +11495,6 @@
     this.transformsManager.processSequences(this._isFirstFrame);
     this.renderShape(this.transformHelper, this.shapesData, this.itemsData, true);
   };
-
   CVShapeElement.prototype.renderShapeTransform = function (parentTransform, groupTransform) {
     if (parentTransform._opMdf || groupTransform.op._mdf || this._isFirstFrame) {
       groupTransform.opacity = parentTransform.opacity;
@@ -13588,7 +11502,6 @@
       groupTransform._opMdf = true;
     }
   };
-
   CVShapeElement.prototype.drawLayer = function () {
     var i;
     var len = this.stylesList.length;
@@ -13602,55 +11515,49 @@
     var ctx = this.globalData.canvasContext;
     var type;
     var currentStyle;
-
     for (i = 0; i < len; i += 1) {
       currentStyle = this.stylesList[i];
-      type = currentStyle.type; // Skipping style when
+      type = currentStyle.type;
+
+      // Skipping style when
       // Stroke width equals 0
       // style should not be rendered (extra unused repeaters)
       // current opacity equals 0
       // global opacity equals 0
-
       if (!((type === 'st' || type === 'gs') && currentStyle.wi === 0 || !currentStyle.data._shouldRender || currentStyle.coOp === 0 || this.globalData.currentGlobalAlpha === 0)) {
         renderer.save();
         elems = currentStyle.elements;
-
         if (type === 'st' || type === 'gs') {
-          renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd); // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
-
-          renderer.ctxLineWidth(currentStyle.wi); // ctx.lineWidth = currentStyle.wi;
-
-          renderer.ctxLineCap(currentStyle.lc); // ctx.lineCap = currentStyle.lc;
-
-          renderer.ctxLineJoin(currentStyle.lj); // ctx.lineJoin = currentStyle.lj;
-
-          renderer.ctxMiterLimit(currentStyle.ml || 0); // ctx.miterLimit = currentStyle.ml || 0;
+          renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd);
+          // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
+          renderer.ctxLineWidth(currentStyle.wi);
+          // ctx.lineWidth = currentStyle.wi;
+          renderer.ctxLineCap(currentStyle.lc);
+          // ctx.lineCap = currentStyle.lc;
+          renderer.ctxLineJoin(currentStyle.lj);
+          // ctx.lineJoin = currentStyle.lj;
+          renderer.ctxMiterLimit(currentStyle.ml || 0);
+          // ctx.miterLimit = currentStyle.ml || 0;
         } else {
-          renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd); // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
+          renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd);
+          // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
         }
-
         renderer.ctxOpacity(currentStyle.coOp);
-
         if (type !== 'st' && type !== 'gs') {
           ctx.beginPath();
         }
-
         renderer.ctxTransform(currentStyle.preTransforms.finalTransform.props);
         jLen = elems.length;
-
         for (j = 0; j < jLen; j += 1) {
           if (type === 'st' || type === 'gs') {
             ctx.beginPath();
-
             if (currentStyle.da) {
               ctx.setLineDash(currentStyle.da);
               ctx.lineDashOffset = currentStyle["do"];
             }
           }
-
           nodes = elems[j].trNodes;
           kLen = nodes.length;
-
           for (k = 0; k < kLen; k += 1) {
             if (nodes[k].t === 'm') {
               ctx.moveTo(nodes[k].p[0], nodes[k].p[1]);
@@ -13660,33 +11567,27 @@
               ctx.closePath();
             }
           }
-
           if (type === 'st' || type === 'gs') {
             // ctx.stroke();
             renderer.ctxStroke();
-
             if (currentStyle.da) {
               ctx.setLineDash(this.dashResetter);
             }
           }
         }
-
         if (type !== 'st' && type !== 'gs') {
           // ctx.fill(currentStyle.r);
           this.globalData.renderer.ctxFill(currentStyle.r);
         }
-
         renderer.restore();
       }
     }
   };
-
   CVShapeElement.prototype.renderShape = function (parentTransform, items, data, isMain) {
     var i;
     var len = items.length - 1;
     var groupTransform;
     groupTransform = parentTransform;
-
     for (i = len; i >= 0; i -= 1) {
       if (items[i].ty === 'tr') {
         groupTransform = data[i].transform;
@@ -13701,15 +11602,14 @@
         this.renderGradientFill(items[i], data[i], groupTransform);
       } else if (items[i].ty === 'gr') {
         this.renderShape(groupTransform, items[i].it, data[i].it);
-      } else if (items[i].ty === 'tm') {//
+      } else if (items[i].ty === 'tm') {
+        //
       }
     }
-
     if (isMain) {
       this.drawLayer();
     }
   };
-
   CVShapeElement.prototype.renderStyledShape = function (styledShape, shape) {
     if (this._isFirstFrame || shape._mdf || styledShape.transforms._mdf) {
       var shapeNodes = styledShape.trNodes;
@@ -13720,13 +11620,10 @@
       var jLen = paths._length;
       shapeNodes.length = 0;
       var groupTransformMat = styledShape.transforms.finalTransform;
-
       for (j = 0; j < jLen; j += 1) {
         var pathNodes = paths.shapes[j];
-
         if (pathNodes && pathNodes.v) {
           len = pathNodes._length;
-
           for (i = 1; i < len; i += 1) {
             if (i === 1) {
               shapeNodes.push({
@@ -13734,20 +11631,17 @@
                 p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0)
               });
             }
-
             shapeNodes.push({
               t: 'c',
               pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[i], pathNodes.v[i])
             });
           }
-
           if (len === 1) {
             shapeNodes.push({
               t: 'm',
               p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0)
             });
           }
-
           if (pathNodes.c && len) {
             shapeNodes.push({
               t: 'c',
@@ -13759,103 +11653,81 @@
           }
         }
       }
-
       styledShape.trNodes = shapeNodes;
     }
   };
-
   CVShapeElement.prototype.renderPath = function (pathData, itemData) {
     if (pathData.hd !== true && pathData._shouldRender) {
       var i;
       var len = itemData.styledShapes.length;
-
       for (i = 0; i < len; i += 1) {
         this.renderStyledShape(itemData.styledShapes[i], itemData.sh);
       }
     }
   };
-
   CVShapeElement.prototype.renderFill = function (styleData, itemData, groupTransform) {
     var styleElem = itemData.style;
-
     if (itemData.c._mdf || this._isFirstFrame) {
       styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
     }
-
     if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
       styleElem.coOp = itemData.o.v * groupTransform.opacity;
     }
   };
-
   CVShapeElement.prototype.renderGradientFill = function (styleData, itemData, groupTransform) {
     var styleElem = itemData.style;
     var grd;
-
     if (!styleElem.grd || itemData.g._mdf || itemData.s._mdf || itemData.e._mdf || styleData.t !== 1 && (itemData.h._mdf || itemData.a._mdf)) {
       var ctx = this.globalData.canvasContext;
       var pt1 = itemData.s.v;
       var pt2 = itemData.e.v;
-
       if (styleData.t === 1) {
         grd = ctx.createLinearGradient(pt1[0], pt1[1], pt2[0], pt2[1]);
       } else {
         var rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
         var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
         var percent = itemData.h.v;
-
         if (percent >= 1) {
           percent = 0.99;
         } else if (percent <= -1) {
           percent = -0.99;
         }
-
         var dist = rad * percent;
         var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
         var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
         grd = ctx.createRadialGradient(x, y, 0, pt1[0], pt1[1], rad);
       }
-
       var i;
       var len = styleData.g.p;
       var cValues = itemData.g.c;
       var opacity = 1;
-
       for (i = 0; i < len; i += 1) {
         if (itemData.g._hasOpacity && itemData.g._collapsable) {
           opacity = itemData.g.o[i * 2 + 1];
         }
-
         grd.addColorStop(cValues[i * 4] / 100, 'rgba(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ',' + opacity + ')');
       }
-
       styleElem.grd = grd;
     }
-
     styleElem.coOp = itemData.o.v * groupTransform.opacity;
   };
-
   CVShapeElement.prototype.renderStroke = function (styleData, itemData, groupTransform) {
     var styleElem = itemData.style;
     var d = itemData.d;
-
     if (d && (d._mdf || this._isFirstFrame)) {
       styleElem.da = d.dashArray;
       styleElem["do"] = d.dashoffset[0];
     }
-
     if (itemData.c._mdf || this._isFirstFrame) {
       styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
     }
-
     if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
       styleElem.coOp = itemData.o.v * groupTransform.opacity;
     }
-
     if (itemData.w._mdf || this._isFirstFrame) {
       styleElem.wi = itemData.w.v;
     }
   };
-
   CVShapeElement.prototype.destroy = function () {
     this.shapesData = null;
     this.globalData = null;
@@ -13883,31 +11755,25 @@
     };
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement, ITextElement], CVTextElement);
   CVTextElement.prototype.tHelper = createTag('canvas').getContext('2d');
-
   CVTextElement.prototype.buildNewText = function () {
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
     var hasFill = false;
-
     if (documentData.fc) {
       hasFill = true;
       this.values.fill = this.buildColor(documentData.fc);
     } else {
       this.values.fill = 'rgba(0,0,0,0)';
     }
-
     this.fill = hasFill;
     var hasStroke = false;
-
     if (documentData.sc) {
       hasStroke = true;
       this.values.stroke = this.buildColor(documentData.sc);
       this.values.sWidth = documentData.sw;
     }
-
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
     var i;
     var len;
@@ -13915,8 +11781,8 @@
     var matrixHelper = this.mHelper;
     this.stroke = hasStroke;
     this.values.fValue = documentData.finalSize + 'px ' + this.globalData.fontManager.getFontByName(documentData.f).fFamily;
-    len = documentData.finalText.length; // this.tHelper.font = this.values.fValue;
-
+    len = documentData.finalText.length;
+    // this.tHelper.font = this.values.fValue;
     var charData;
     var shapeData;
     var k;
@@ -13933,55 +11799,44 @@
     var yPos = 0;
     var firstLine = true;
     var cnt = 0;
-
     for (i = 0; i < len; i += 1) {
       charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
       shapeData = charData && charData.data || {};
       matrixHelper.reset();
-
       if (singleShape && letters[i].n) {
         xPos = -trackingOffset;
         yPos += documentData.yOffset;
         yPos += firstLine ? 1 : 0;
         firstLine = false;
       }
-
       shapes = shapeData.shapes ? shapeData.shapes[0].it : [];
       jLen = shapes.length;
       matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
-
       if (singleShape) {
         this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
       }
-
       commands = createSizedArray(jLen - 1);
       var commandsCounter = 0;
-
       for (j = 0; j < jLen; j += 1) {
         if (shapes[j].ty === 'sh') {
           kLen = shapes[j].ks.k.i.length;
           pathNodes = shapes[j].ks.k;
           pathArr = [];
-
           for (k = 1; k < kLen; k += 1) {
             if (k === 1) {
               pathArr.push(matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
             }
-
             pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToY(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToX(pathNodes.v[k][0], pathNodes.v[k][1], 0), matrixHelper.applyToY(pathNodes.v[k][0], pathNodes.v[k][1], 0));
           }
-
           pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToY(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
           commands[commandsCounter] = pathArr;
           commandsCounter += 1;
         }
       }
-
       if (singleShape) {
         xPos += letters[i].l;
         xPos += trackingOffset;
       }
-
       if (this.textSpans[cnt]) {
         this.textSpans[cnt].elem = commands;
       } else {
@@ -13989,25 +11844,23 @@
           elem: commands
         };
       }
-
       cnt += 1;
     }
   };
-
   CVTextElement.prototype.renderInnerContent = function () {
     this.validateText();
     var ctx = this.canvasContext;
     ctx.font = this.values.fValue;
-    this.globalData.renderer.ctxLineCap('butt'); // ctx.lineCap = 'butt';
-
-    this.globalData.renderer.ctxLineJoin('miter'); // ctx.lineJoin = 'miter';
-
-    this.globalData.renderer.ctxMiterLimit(4); // ctx.miterLimit = 4;
+    this.globalData.renderer.ctxLineCap('butt');
+    // ctx.lineCap = 'butt';
+    this.globalData.renderer.ctxLineJoin('miter');
+    // ctx.lineJoin = 'miter';
+    this.globalData.renderer.ctxMiterLimit(4);
+    // ctx.miterLimit = 4;
 
     if (!this.data.singleShape) {
       this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
     }
-
     var i;
     var len;
     var j;
@@ -14024,87 +11877,81 @@
     var commands;
     var pathArr;
     var renderer = this.globalData.renderer;
-
     for (i = 0; i < len; i += 1) {
       if (!letters[i].n) {
         renderedLetter = renderedLetters[i];
-
         if (renderedLetter) {
           renderer.save();
           renderer.ctxTransform(renderedLetter.p);
           renderer.ctxOpacity(renderedLetter.o);
         }
-
         if (this.fill) {
           if (renderedLetter && renderedLetter.fc) {
             if (lastFill !== renderedLetter.fc) {
               renderer.ctxFillStyle(renderedLetter.fc);
-              lastFill = renderedLetter.fc; // ctx.fillStyle = renderedLetter.fc;
+              lastFill = renderedLetter.fc;
+              // ctx.fillStyle = renderedLetter.fc;
             }
           } else if (lastFill !== this.values.fill) {
             lastFill = this.values.fill;
-            renderer.ctxFillStyle(this.values.fill); // ctx.fillStyle = this.values.fill;
+            renderer.ctxFillStyle(this.values.fill);
+            // ctx.fillStyle = this.values.fill;
           }
-
           commands = this.textSpans[i].elem;
           jLen = commands.length;
           this.globalData.canvasContext.beginPath();
-
           for (j = 0; j < jLen; j += 1) {
             pathArr = commands[j];
             kLen = pathArr.length;
             this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
-
             for (k = 2; k < kLen; k += 6) {
               this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
             }
           }
-
           this.globalData.canvasContext.closePath();
-          renderer.ctxFill(); // this.globalData.canvasContext.fill();
+          renderer.ctxFill();
+          // this.globalData.canvasContext.fill();
           /// ctx.fillText(this.textSpans[i].val,0,0);
         }
-
         if (this.stroke) {
           if (renderedLetter && renderedLetter.sw) {
             if (lastStrokeW !== renderedLetter.sw) {
               lastStrokeW = renderedLetter.sw;
-              renderer.ctxLineWidth(renderedLetter.sw); // ctx.lineWidth = renderedLetter.sw;
+              renderer.ctxLineWidth(renderedLetter.sw);
+              // ctx.lineWidth = renderedLetter.sw;
             }
           } else if (lastStrokeW !== this.values.sWidth) {
             lastStrokeW = this.values.sWidth;
-            renderer.ctxLineWidth(this.values.sWidth); // ctx.lineWidth = this.values.sWidth;
+            renderer.ctxLineWidth(this.values.sWidth);
+            // ctx.lineWidth = this.values.sWidth;
           }
-
           if (renderedLetter && renderedLetter.sc) {
             if (lastStroke !== renderedLetter.sc) {
               lastStroke = renderedLetter.sc;
-              renderer.ctxStrokeStyle(renderedLetter.sc); // ctx.strokeStyle = renderedLetter.sc;
+              renderer.ctxStrokeStyle(renderedLetter.sc);
+              // ctx.strokeStyle = renderedLetter.sc;
             }
           } else if (lastStroke !== this.values.stroke) {
             lastStroke = this.values.stroke;
-            renderer.ctxStrokeStyle(this.values.stroke); // ctx.strokeStyle = this.values.stroke;
+            renderer.ctxStrokeStyle(this.values.stroke);
+            // ctx.strokeStyle = this.values.stroke;
           }
-
           commands = this.textSpans[i].elem;
           jLen = commands.length;
           this.globalData.canvasContext.beginPath();
-
           for (j = 0; j < jLen; j += 1) {
             pathArr = commands[j];
             kLen = pathArr.length;
             this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
-
             for (k = 2; k < kLen; k += 6) {
               this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
             }
           }
-
           this.globalData.canvasContext.closePath();
-          renderer.ctxStroke(); // this.globalData.canvasContext.stroke();
+          renderer.ctxStroke();
+          // this.globalData.canvasContext.stroke();
           /// ctx.strokeText(letters[i].val,0,0);
         }
-
         if (renderedLetter) {
           this.globalData.renderer.restore();
         }
@@ -14117,11 +11964,9 @@
     this.img = globalData.imageLoader.getAsset(this.assetData);
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVImageElement);
   CVImageElement.prototype.initElement = SVGShapeElement.prototype.initElement;
   CVImageElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
-
   CVImageElement.prototype.createContent = function () {
     if (this.img.width && (this.assetData.w !== this.img.width || this.assetData.h !== this.img.height)) {
       var canvas = createTag('canvas');
@@ -14135,7 +11980,6 @@
       var widthCrop;
       var heightCrop;
       var par = this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio;
-
       if (imgRel > canvasRel && par === 'xMidYMid slice' || imgRel < canvasRel && par !== 'xMidYMid slice') {
         heightCrop = imgH;
         widthCrop = heightCrop * canvasRel;
@@ -14143,16 +11987,13 @@
         widthCrop = imgW;
         heightCrop = widthCrop / canvasRel;
       }
-
       ctx.drawImage(this.img, (imgW - widthCrop) / 2, (imgH - heightCrop) / 2, widthCrop, heightCrop, 0, 0, this.assetData.w, this.assetData.h);
       this.img = canvas;
     }
   };
-
   CVImageElement.prototype.renderInnerContent = function () {
     this.canvasContext.drawImage(this.img, 0, 0);
   };
-
   CVImageElement.prototype.destroy = function () {
     this.img = null;
   };
@@ -14160,115 +12001,89 @@
   function CVSolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVSolidElement);
   CVSolidElement.prototype.initElement = SVGShapeElement.prototype.initElement;
   CVSolidElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
-
   CVSolidElement.prototype.renderInnerContent = function () {
     // var ctx = this.canvasContext;
-    this.globalData.renderer.ctxFillStyle(this.data.sc); // ctx.fillStyle = this.data.sc;
-
-    this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh); // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
+    this.globalData.renderer.ctxFillStyle(this.data.sc);
+    // ctx.fillStyle = this.data.sc;
+    this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh);
+    // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
     //
   };
 
   function CanvasRendererBase() {}
-
   extendPrototype([BaseRenderer], CanvasRendererBase);
-
   CanvasRendererBase.prototype.createShape = function (data) {
     return new CVShapeElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createText = function (data) {
     return new CVTextElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createImage = function (data) {
     return new CVImageElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createSolid = function (data) {
     return new CVSolidElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
-
   CanvasRendererBase.prototype.ctxTransform = function (props) {
     if (props[0] === 1 && props[1] === 0 && props[4] === 0 && props[5] === 1 && props[12] === 0 && props[13] === 0) {
       return;
     }
-
     this.canvasContext.transform(props[0], props[1], props[4], props[5], props[12], props[13]);
   };
-
   CanvasRendererBase.prototype.ctxOpacity = function (op) {
     this.canvasContext.globalAlpha *= op < 0 ? 0 : op;
   };
-
   CanvasRendererBase.prototype.ctxFillStyle = function (value) {
     this.canvasContext.fillStyle = value;
   };
-
   CanvasRendererBase.prototype.ctxStrokeStyle = function (value) {
     this.canvasContext.strokeStyle = value;
   };
-
   CanvasRendererBase.prototype.ctxLineWidth = function (value) {
     this.canvasContext.lineWidth = value;
   };
-
   CanvasRendererBase.prototype.ctxLineCap = function (value) {
     this.canvasContext.lineCap = value;
   };
-
   CanvasRendererBase.prototype.ctxLineJoin = function (value) {
     this.canvasContext.lineJoin = value;
   };
-
   CanvasRendererBase.prototype.ctxMiterLimit = function (value) {
     this.canvasContext.miterLimit = value;
   };
-
   CanvasRendererBase.prototype.ctxFill = function (rule) {
     this.canvasContext.fill(rule);
   };
-
   CanvasRendererBase.prototype.ctxFillRect = function (x, y, w, h) {
     this.canvasContext.fillRect(x, y, w, h);
   };
-
   CanvasRendererBase.prototype.ctxStroke = function () {
     this.canvasContext.stroke();
   };
-
   CanvasRendererBase.prototype.reset = function () {
     if (!this.renderConfig.clearCanvas) {
       this.canvasContext.restore();
       return;
     }
-
     this.contextData.reset();
   };
-
   CanvasRendererBase.prototype.save = function () {
     this.canvasContext.save();
   };
-
   CanvasRendererBase.prototype.restore = function (actionFlag) {
     if (!this.renderConfig.clearCanvas) {
       this.canvasContext.restore();
       return;
     }
-
     if (actionFlag) {
       this.globalData.blendMode = 'source-over';
     }
-
     this.contextData.restore(actionFlag);
   };
-
   CanvasRendererBase.prototype.configAnimation = function (animData) {
     if (this.animationItem.wrapper) {
       this.animationItem.container = createTag('canvas');
@@ -14283,18 +12098,15 @@
       containerStyle.contentVisibility = this.renderConfig.contentVisibility;
       this.animationItem.wrapper.appendChild(this.animationItem.container);
       this.canvasContext = this.animationItem.container.getContext('2d');
-
       if (this.renderConfig.className) {
         this.animationItem.container.setAttribute('class', this.renderConfig.className);
       }
-
       if (this.renderConfig.id) {
         this.animationItem.container.setAttribute('id', this.renderConfig.id);
       }
     } else {
       this.canvasContext = this.renderConfig.context;
     }
-
     this.contextData.setContext(this.canvasContext);
     this.data = animData;
     this.layers = animData.layers;
@@ -14315,12 +12127,10 @@
     this.elements = createSizedArray(animData.layers.length);
     this.updateContainerSize();
   };
-
   CanvasRendererBase.prototype.updateContainerSize = function (width, height) {
     this.reset();
     var elementWidth;
     var elementHeight;
-
     if (width) {
       elementWidth = width;
       elementHeight = height;
@@ -14334,14 +12144,11 @@
         elementWidth = this.canvasContext.canvas.width;
         elementHeight = this.canvasContext.canvas.height;
       }
-
       this.canvasContext.canvas.width = elementWidth * this.renderConfig.dpr;
       this.canvasContext.canvas.height = elementHeight * this.renderConfig.dpr;
     }
-
     var elementRel;
     var animationRel;
-
     if (this.renderConfig.preserveAspectRatio.indexOf('meet') !== -1 || this.renderConfig.preserveAspectRatio.indexOf('slice') !== -1) {
       var par = this.renderConfig.preserveAspectRatio.split(' ');
       var fillType = par[1] || 'meet';
@@ -14350,7 +12157,6 @@
       var yPos = pos.substr(4);
       elementRel = elementWidth / elementHeight;
       animationRel = this.transformCanvas.w / this.transformCanvas.h;
-
       if (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice') {
         this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
         this.transformCanvas.sy = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
@@ -14358,7 +12164,6 @@
         this.transformCanvas.sx = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
         this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
       }
-
       if (xPos === 'xMid' && (animationRel < elementRel && fillType === 'meet' || animationRel > elementRel && fillType === 'slice')) {
         this.transformCanvas.tx = (elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) / 2 * this.renderConfig.dpr;
       } else if (xPos === 'xMax' && (animationRel < elementRel && fillType === 'meet' || animationRel > elementRel && fillType === 'slice')) {
@@ -14366,7 +12171,6 @@
       } else {
         this.transformCanvas.tx = 0;
       }
-
       if (yPos === 'YMid' && (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice')) {
         this.transformCanvas.ty = (elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w)) / 2 * this.renderConfig.dpr;
       } else if (yPos === 'YMax' && (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice')) {
@@ -14385,7 +12189,6 @@
       this.transformCanvas.tx = 0;
       this.transformCanvas.ty = 0;
     }
-
     this.transformCanvas.props = [this.transformCanvas.sx, 0, 0, 0, 0, this.transformCanvas.sy, 0, 0, 0, 0, 1, 0, this.transformCanvas.tx, this.transformCanvas.ty, 0, 1];
     /* var i, len = this.elements.length;
       for(i=0;i<len;i+=1){
@@ -14393,7 +12196,6 @@
               this.elements[i].resize(this.globalData.transformCanvas);
           }
       } */
-
     this.ctxTransform(this.transformCanvas.props);
     this.canvasContext.beginPath();
     this.canvasContext.rect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
@@ -14401,78 +12203,65 @@
     this.canvasContext.clip();
     this.renderFrame(this.renderedFrame, true);
   };
-
   CanvasRendererBase.prototype.destroy = function () {
     if (this.renderConfig.clearCanvas && this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.globalData.canvasContext = null;
     this.animationItem.container = null;
     this.destroyed = true;
   };
-
   CanvasRendererBase.prototype.renderFrame = function (num, forceRender) {
     if (this.renderedFrame === num && this.renderConfig.clearCanvas === true && !forceRender || this.destroyed || num === -1) {
       return;
     }
-
     this.renderedFrame = num;
     this.globalData.frameNum = num - this.animationItem._isFirstFrame;
     this.globalData.frameId += 1;
     this.globalData._mdf = !this.renderConfig.clearCanvas || forceRender;
-    this.globalData.projectInterface.currentFrame = num; // console.log('--------');
-    // console.log('NEW: ',num);
+    this.globalData.projectInterface.currentFrame = num;
 
+    // console.log('--------');
+    // console.log('NEW: ',num);
     var i;
     var len = this.layers.length;
-
     if (!this.completeLayers) {
       this.checkLayers(num);
     }
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(num - this.layers[i].st);
       }
     }
-
     if (this.globalData._mdf) {
       if (this.renderConfig.clearCanvas === true) {
         this.canvasContext.clearRect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
       } else {
         this.save();
       }
-
       for (i = len - 1; i >= 0; i -= 1) {
         if (this.completeLayers || this.elements[i]) {
           this.elements[i].renderFrame();
         }
       }
-
       if (this.renderConfig.clearCanvas !== true) {
         this.restore();
       }
     }
   };
-
   CanvasRendererBase.prototype.buildItem = function (pos) {
     var elements = this.elements;
-
     if (elements[pos] || this.layers[pos].ty === 99) {
       return;
     }
-
     var element = this.createItem(this.layers[pos], this, this.globalData);
     elements[pos] = element;
     element.initExpressions();
@@ -14480,18 +12269,15 @@
           element.resize(this.globalData.transformCanvas);
       } */
   };
-
   CanvasRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
     }
   };
-
   CanvasRendererBase.prototype.hide = function () {
     this.animationItem.container.style.display = 'none';
   };
-
   CanvasRendererBase.prototype.show = function () {
     this.animationItem.container.style.display = 'block';
   };
@@ -14507,71 +12293,61 @@
     this.miterLimit = '';
     this.id = Math.random();
   }
-
   function CVContextData() {
     this.stack = [];
     this.cArrPos = 0;
     this.cTr = new Matrix();
     var i;
     var len = 15;
-
     for (i = 0; i < len; i += 1) {
       var canvasContext = new CanvasContext();
       this.stack[i] = canvasContext;
     }
-
     this._length = len;
     this.nativeContext = null;
     this.transformMat = new Matrix();
-    this.currentOpacity = 1; //
-
+    this.currentOpacity = 1;
+    //
     this.currentFillStyle = '';
-    this.appliedFillStyle = ''; //
-
+    this.appliedFillStyle = '';
+    //
     this.currentStrokeStyle = '';
-    this.appliedStrokeStyle = ''; //
-
+    this.appliedStrokeStyle = '';
+    //
     this.currentLineWidth = '';
-    this.appliedLineWidth = ''; //
-
+    this.appliedLineWidth = '';
+    //
     this.currentLineCap = '';
-    this.appliedLineCap = ''; //
-
+    this.appliedLineCap = '';
+    //
     this.currentLineJoin = '';
-    this.appliedLineJoin = ''; //
-
+    this.appliedLineJoin = '';
+    //
     this.appliedMiterLimit = '';
     this.currentMiterLimit = '';
   }
-
   CVContextData.prototype.duplicate = function () {
     var newLength = this._length * 2;
     var i = 0;
-
     for (i = this._length; i < newLength; i += 1) {
       this.stack[i] = new CanvasContext();
     }
-
     this._length = newLength;
   };
-
   CVContextData.prototype.reset = function () {
     this.cArrPos = 0;
     this.cTr.reset();
     this.stack[this.cArrPos].opacity = 1;
   };
-
   CVContextData.prototype.restore = function (forceRestore) {
     this.cArrPos -= 1;
     var currentContext = this.stack[this.cArrPos];
     var transform = currentContext.transform;
     var i;
     var arr = this.cTr.props;
-
     for (i = 0; i < 16; i += 1) {
       arr[i] = transform[i];
     }
-
     if (forceRestore) {
       this.nativeContext.restore();
       var prevStack = this.stack[this.cArrPos + 1];
@@ -14582,14 +12358,11 @@
       this.appliedLineJoin = prevStack.lineJoin;
       this.appliedMiterLimit = prevStack.miterLimit;
     }
-
     this.nativeContext.setTransform(transform[0], transform[1], transform[4], transform[5], transform[12], transform[13]);
-
     if (forceRestore || currentContext.opacity !== -1 && this.currentOpacity !== currentContext.opacity) {
       this.nativeContext.globalAlpha = currentContext.opacity;
       this.currentOpacity = currentContext.opacity;
     }
-
     this.currentFillStyle = currentContext.fillStyle;
     this.currentStrokeStyle = currentContext.strokeStyle;
     this.currentLineWidth = currentContext.lineWidth;
@@ -14597,25 +12370,19 @@
     this.currentLineJoin = currentContext.lineJoin;
     this.currentMiterLimit = currentContext.miterLimit;
   };
-
   CVContextData.prototype.save = function (saveOnNativeFlag) {
     if (saveOnNativeFlag) {
       this.nativeContext.save();
     }
-
     var props = this.cTr.props;
-
     if (this._length <= this.cArrPos) {
       this.duplicate();
     }
-
     var currentStack = this.stack[this.cArrPos];
     var i;
-
     for (i = 0; i < 16; i += 1) {
       currentStack.transform[i] = props[i];
     }
-
     this.cArrPos += 1;
     var newStack = this.stack[this.cArrPos];
     newStack.opacity = currentStack.opacity;
@@ -14626,128 +12393,106 @@
     newStack.lineJoin = currentStack.lineJoin;
     newStack.miterLimit = currentStack.miterLimit;
   };
-
   CVContextData.prototype.setOpacity = function (value) {
     this.stack[this.cArrPos].opacity = value;
   };
-
   CVContextData.prototype.setContext = function (value) {
     this.nativeContext = value;
   };
-
   CVContextData.prototype.fillStyle = function (value) {
     if (this.stack[this.cArrPos].fillStyle !== value) {
       this.currentFillStyle = value;
       this.stack[this.cArrPos].fillStyle = value;
     }
   };
-
   CVContextData.prototype.strokeStyle = function (value) {
     if (this.stack[this.cArrPos].strokeStyle !== value) {
       this.currentStrokeStyle = value;
       this.stack[this.cArrPos].strokeStyle = value;
     }
   };
-
   CVContextData.prototype.lineWidth = function (value) {
     if (this.stack[this.cArrPos].lineWidth !== value) {
       this.currentLineWidth = value;
       this.stack[this.cArrPos].lineWidth = value;
     }
   };
-
   CVContextData.prototype.lineCap = function (value) {
     if (this.stack[this.cArrPos].lineCap !== value) {
       this.currentLineCap = value;
       this.stack[this.cArrPos].lineCap = value;
     }
   };
-
   CVContextData.prototype.lineJoin = function (value) {
     if (this.stack[this.cArrPos].lineJoin !== value) {
       this.currentLineJoin = value;
       this.stack[this.cArrPos].lineJoin = value;
     }
   };
-
   CVContextData.prototype.miterLimit = function (value) {
     if (this.stack[this.cArrPos].miterLimit !== value) {
       this.currentMiterLimit = value;
       this.stack[this.cArrPos].miterLimit = value;
     }
   };
-
   CVContextData.prototype.transform = function (props) {
-    this.transformMat.cloneFromProps(props); // Taking the last transform value from the stored stack of transforms
-
-    var currentTransform = this.cTr; // Applying the last transform value after the new transform to respect the order of transformations
-
-    this.transformMat.multiply(currentTransform); // Storing the new transformed value in the stored transform
-
+    this.transformMat.cloneFromProps(props);
+    // Taking the last transform value from the stored stack of transforms
+    var currentTransform = this.cTr;
+    // Applying the last transform value after the new transform to respect the order of transformations
+    this.transformMat.multiply(currentTransform);
+    // Storing the new transformed value in the stored transform
     currentTransform.cloneFromProps(this.transformMat.props);
-    var trProps = currentTransform.props; // Applying the new transform to the canvas
-
+    var trProps = currentTransform.props;
+    // Applying the new transform to the canvas
     this.nativeContext.setTransform(trProps[0], trProps[1], trProps[4], trProps[5], trProps[12], trProps[13]);
   };
-
   CVContextData.prototype.opacity = function (op) {
     var currentOpacity = this.stack[this.cArrPos].opacity;
     currentOpacity *= op < 0 ? 0 : op;
-
     if (this.stack[this.cArrPos].opacity !== currentOpacity) {
       if (this.currentOpacity !== op) {
         this.nativeContext.globalAlpha = op;
         this.currentOpacity = op;
       }
-
       this.stack[this.cArrPos].opacity = currentOpacity;
     }
   };
-
   CVContextData.prototype.fill = function (rule) {
     if (this.appliedFillStyle !== this.currentFillStyle) {
       this.appliedFillStyle = this.currentFillStyle;
       this.nativeContext.fillStyle = this.appliedFillStyle;
     }
-
     this.nativeContext.fill(rule);
   };
-
   CVContextData.prototype.fillRect = function (x, y, w, h) {
     if (this.appliedFillStyle !== this.currentFillStyle) {
       this.appliedFillStyle = this.currentFillStyle;
       this.nativeContext.fillStyle = this.appliedFillStyle;
     }
-
     this.nativeContext.fillRect(x, y, w, h);
   };
-
   CVContextData.prototype.stroke = function () {
     if (this.appliedStrokeStyle !== this.currentStrokeStyle) {
       this.appliedStrokeStyle = this.currentStrokeStyle;
       this.nativeContext.strokeStyle = this.appliedStrokeStyle;
     }
-
     if (this.appliedLineWidth !== this.currentLineWidth) {
       this.appliedLineWidth = this.currentLineWidth;
       this.nativeContext.lineWidth = this.appliedLineWidth;
     }
-
     if (this.appliedLineCap !== this.currentLineCap) {
       this.appliedLineCap = this.currentLineCap;
       this.nativeContext.lineCap = this.appliedLineCap;
     }
-
     if (this.appliedLineJoin !== this.currentLineJoin) {
       this.appliedLineJoin = this.currentLineJoin;
       this.nativeContext.lineJoin = this.appliedLineJoin;
     }
-
     if (this.appliedMiterLimit !== this.currentMiterLimit) {
       this.appliedMiterLimit = this.currentMiterLimit;
       this.nativeContext.miterLimit = this.appliedMiterLimit;
     }
-
     this.nativeContext.stroke();
   };
 
@@ -14761,9 +12506,7 @@
       _placeholder: true
     };
   }
-
   extendPrototype([CanvasRendererBase, ICompElement, CVBaseElement], CVCompElement);
-
   CVCompElement.prototype.renderInnerContent = function () {
     var ctx = this.canvasContext;
     ctx.beginPath();
@@ -14775,28 +12518,23 @@
     ctx.clip();
     var i;
     var len = this.layers.length;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].renderFrame();
       }
     }
   };
-
   CVCompElement.prototype.destroy = function () {
     var i;
     var len = this.layers.length;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.elements[i]) {
         this.elements[i].destroy();
       }
     }
-
     this.layers = null;
     this.elements = null;
   };
-
   CVCompElement.prototype.createComp = function (data) {
     return new CVCompElement(data, this.globalData, this);
   };
@@ -14815,11 +12553,9 @@
       runExpressions: !config || config.runExpressions === undefined || config.runExpressions
     };
     this.renderConfig.dpr = config && config.dpr || 1;
-
     if (this.animationItem.wrapper) {
       this.renderConfig.dpr = config && config.dpr || window.devicePixelRatio || 1;
     }
-
     this.renderedFrame = -1;
     this.globalData = {
       frameNum: -1,
@@ -14833,7 +12569,6 @@
     this.transformMat = new Matrix();
     this.completeLayers = false;
     this.rendererType = 'canvas';
-
     if (this.renderConfig.clearCanvas) {
       this.ctxTransform = this.contextData.transform.bind(this.contextData);
       this.ctxOpacity = this.contextData.opacity.bind(this.contextData);
@@ -14849,15 +12584,15 @@
       this.save = this.contextData.save.bind(this.contextData);
     }
   }
-
   extendPrototype([CanvasRendererBase], CanvasRenderer);
-
   CanvasRenderer.prototype.createComp = function (data) {
     return new CVCompElement(data, this.globalData, this);
   };
 
-  registerRenderer('canvas', CanvasRenderer); // Registering shape modifiers
+  // Registering renderers
+  registerRenderer('canvas', CanvasRenderer);
 
+  // Registering shape modifiers
   ShapeModifiers.registerModifier('tm', TrimModifier);
   ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
   ShapeModifiers.registerModifier('rp', RepeaterModifier);
@@ -14870,18 +12605,15 @@
       function _thisLayerFunction(name) {
         var i = 0;
         var len = comp.layers.length;
-
         while (i < len) {
           if (comp.layers[i].nm === name || comp.layers[i].ind === name) {
             return comp.elements[i].layerInterface;
           }
-
           i += 1;
         }
-
-        return null; // return {active:false};
+        return null;
+        // return {active:false};
       }
-
       Object.defineProperty(_thisLayerFunction, '_name', {
         value: comp.data.nm
       });
@@ -14897,10 +12629,8 @@
     };
   }();
 
-  function _typeof$2(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$2 = function _typeof(obj) { return typeof obj; }; } else { _typeof$2 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$2(obj); }
-
+  function _typeof$2(o) { "@babel/helpers - typeof"; return _typeof$2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$2(o); }
   /* eslint-disable */
-
   /*
    Copyright 2014 David Bau.
 
@@ -14924,105 +12654,103 @@
    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
    */
+
   function seedRandom(pool, math) {
     //
     // The following constants are related to IEEE 754 limits.
     //
     var global = this,
-        width = 256,
-        // each RC4 output is 0 <= x < 256
-    chunks = 6,
-        // at least six RC4 outputs for each double
-    digits = 52,
-        // there are 52 significant digits in a double
-    rngname = 'random',
-        // rngname: name for Math.random and Math.seedrandom
-    startdenom = math.pow(width, chunks),
-        significance = math.pow(2, digits),
-        overflow = significance * 2,
-        mask = width - 1,
-        nodecrypto; // node.js crypto module, initialized at the bottom.
+      width = 256,
+      // each RC4 output is 0 <= x < 256
+      chunks = 6,
+      // at least six RC4 outputs for each double
+      digits = 52,
+      // there are 52 significant digits in a double
+      rngname = 'random',
+      // rngname: name for Math.random and Math.seedrandom
+      startdenom = math.pow(width, chunks),
+      significance = math.pow(2, digits),
+      overflow = significance * 2,
+      mask = width - 1,
+      nodecrypto; // node.js crypto module, initialized at the bottom.
+
     //
     // seedrandom()
     // This is the seedrandom function described above.
     //
-
     function seedrandom(seed, options, callback) {
       var key = [];
       options = options === true ? {
         entropy: true
-      } : options || {}; // Flatten the seed string or build one from local entropy if needed.
+      } : options || {};
 
-      var shortseed = mixkey(flatten(options.entropy ? [seed, tostring(pool)] : seed === null ? autoseed() : seed, 3), key); // Use the seed to initialize an ARC4 generator.
+      // Flatten the seed string or build one from local entropy if needed.
+      var shortseed = mixkey(flatten(options.entropy ? [seed, tostring(pool)] : seed === null ? autoseed() : seed, 3), key);
 
-      var arc4 = new ARC4(key); // This function returns a random double in [0, 1) that contains
+      // Use the seed to initialize an ARC4 generator.
+      var arc4 = new ARC4(key);
+
+      // This function returns a random double in [0, 1) that contains
       // randomness in every bit of the mantissa of the IEEE 754 value.
-
       var prng = function prng() {
         var n = arc4.g(chunks),
-            // Start with a numerator n < 2 ^ 48
-        d = startdenom,
-            //   and denominator d = 2 ^ 48.
-        x = 0; //   and no 'extra last byte'.
-
+          // Start with a numerator n < 2 ^ 48
+          d = startdenom,
+          //   and denominator d = 2 ^ 48.
+          x = 0; //   and no 'extra last byte'.
         while (n < significance) {
           // Fill up all significant digits by
           n = (n + x) * width; //   shifting numerator and
-
           d *= width; //   denominator and generating a
-
           x = arc4.g(1); //   new least-significant-byte.
         }
-
         while (n >= overflow) {
           // To avoid rounding up, before adding
           n /= 2; //   last byte, shift everything
-
           d /= 2; //   right using integer math until
-
           x >>>= 1; //   we have exactly the desired bits.
         }
-
         return (n + x) / d; // Form the number within [0, 1).
       };
-
       prng.int32 = function () {
         return arc4.g(4) | 0;
       };
-
       prng.quick = function () {
         return arc4.g(4) / 0x100000000;
       };
+      prng["double"] = prng;
 
-      prng["double"] = prng; // Mix the randomness into accumulated entropy.
+      // Mix the randomness into accumulated entropy.
+      mixkey(tostring(arc4.S), pool);
 
-      mixkey(tostring(arc4.S), pool); // Calling convention: what to return as a function of prng, seed, is_math.
-
+      // Calling convention: what to return as a function of prng, seed, is_math.
       return (options.pass || callback || function (prng, seed, is_math_call, state) {
         if (state) {
           // Load the arc4 state from the given state if it has an S array.
           if (state.S) {
             copy(state, arc4);
-          } // Only provide the .state method if requested via options.state.
-
-
+          }
+          // Only provide the .state method if requested via options.state.
           prng.state = function () {
             return copy(arc4, {});
           };
-        } // If called as a method of Math (Math.seedrandom()), mutate
+        }
+
+        // If called as a method of Math (Math.seedrandom()), mutate
         // Math.random because that is how seedrandom.js has worked since v1.0.
-
-
         if (is_math_call) {
           math[rngname] = prng;
           return seed;
-        } // Otherwise, it is a newer calling convention, so return the
+        }
+
+        // Otherwise, it is a newer calling convention, so return the
         // prng directly.
         else return prng;
       })(prng, shortseed, 'global' in options ? options.global : this == math, options.state);
     }
+    math['seed' + rngname] = seedrandom;
 
-    math['seed' + rngname] = seedrandom; //
+    //
     // ARC4
     //
     // An ARC4 implementation.  The constructor takes a key in the form of
@@ -15032,71 +12760,68 @@
     // the next (count) outputs from ARC4.  Its return value is a number x
     // that is in the range 0 <= x < (width ^ count).
     //
-
     function ARC4(key) {
       var t,
-          keylen = key.length,
-          me = this,
-          i = 0,
-          j = me.i = me.j = 0,
-          s = me.S = []; // The empty key [] is treated as [0].
+        keylen = key.length,
+        me = this,
+        i = 0,
+        j = me.i = me.j = 0,
+        s = me.S = [];
 
+      // The empty key [] is treated as [0].
       if (!keylen) {
         key = [keylen++];
-      } // Set up S using the standard key scheduling algorithm.
+      }
 
-
+      // Set up S using the standard key scheduling algorithm.
       while (i < width) {
         s[i] = i++;
       }
-
       for (i = 0; i < width; i++) {
         s[i] = s[j = mask & j + key[i % keylen] + (t = s[i])];
         s[j] = t;
-      } // The "g" method returns the next (count) outputs as one number.
+      }
 
-
+      // The "g" method returns the next (count) outputs as one number.
       me.g = function (count) {
         // Using instance members instead of closure state nearly doubles speed.
         var t,
-            r = 0,
-            i = me.i,
-            j = me.j,
-            s = me.S;
-
+          r = 0,
+          i = me.i,
+          j = me.j,
+          s = me.S;
         while (count--) {
           t = s[i = mask & i + 1];
           r = r * width + s[mask & (s[i] = s[j = mask & j + t]) + (s[j] = t)];
         }
-
         me.i = i;
         me.j = j;
-        return r; // For robust unpredictability, the function call below automatically
+        return r;
+        // For robust unpredictability, the function call below automatically
         // discards an initial batch of values.  This is called RC4-drop[256].
         // See http://google.com/search?q=rsa+fluhrer+response&btnI
       };
-    } //
+    }
+
+    //
     // copy()
     // Copies internal state of ARC4 to or from a plain object.
     //
-
-
     function copy(f, t) {
       t.i = f.i;
       t.j = f.j;
       t.S = f.S.slice();
       return t;
-    } //
+    }
+
+    //
     // flatten()
     // Converts an object tree to nested arrays of strings.
     //
-
-
     function flatten(obj, depth) {
       var result = [],
-          typ = _typeof$2(obj),
-          prop;
-
+        typ = _typeof$2(obj),
+        prop;
       if (depth && typ == 'object') {
         for (prop in obj) {
           try {
@@ -15104,72 +12829,69 @@
           } catch (e) {}
         }
       }
-
       return result.length ? result : typ == 'string' ? obj : obj + '\0';
-    } //
+    }
+
+    //
     // mixkey()
     // Mixes a string seed into a key that is an array of integers, and
     // returns a shortened string seed that is equivalent to the result key.
     //
-
-
     function mixkey(seed, key) {
       var stringseed = seed + '',
-          smear,
-          j = 0;
-
+        smear,
+        j = 0;
       while (j < stringseed.length) {
         key[mask & j] = mask & (smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++);
       }
-
       return tostring(key);
-    } //
+    }
+
+    //
     // autoseed()
     // Returns an object for autoseeding, using window.crypto and Node crypto
     // module if available.
     //
-
-
     function autoseed() {
       try {
         if (nodecrypto) {
           return tostring(nodecrypto.randomBytes(width));
         }
-
         var out = new Uint8Array(width);
         (global.crypto || global.msCrypto).getRandomValues(out);
         return tostring(out);
       } catch (e) {
         var browser = global.navigator,
-            plugins = browser && browser.plugins;
+          plugins = browser && browser.plugins;
         return [+new Date(), global, plugins, global.screen, tostring(pool)];
       }
-    } //
+    }
+
+    //
     // tostring()
     // Converts an array of charcodes to a string
     //
-
-
     function tostring(a) {
       return String.fromCharCode.apply(0, a);
-    } //
+    }
+
+    //
     // When seedrandom.js is loaded, we immediately mix a few bits
     // from the built-in RNG into the entropy pool.  Because we do
     // not want to interfere with deterministic PRNG state later,
     // seedrandom will not call math.random on its own again after
     // initialization.
     //
+    mixkey(math.random(), pool);
 
-
-    mixkey(math.random(), pool); //
+    //
     // Nodejs and AMD support: export the implementation as a module using
     // either convention.
     //
+
     // End anonymous scope, and pass initial values.
   }
-
   ;
-
   function initialize$2(BMMath) {
     seedRandom([], BMMath);
   }
@@ -15178,8 +12900,7 @@
     SHAPE: 'shape'
   };
 
-  function _typeof$1(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$1 = function _typeof(obj) { return typeof obj; }; } else { _typeof$1 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$1(obj); }
-
+  function _typeof$1(o) { "@babel/helpers - typeof"; return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$1(o); }
   var ExpressionManager = function () {
     'use strict';
 
@@ -15192,289 +12913,214 @@
     var frames = null;
     var _lottieGlobal = {};
     initialize$2(BMMath);
-
     function resetFrame() {
       _lottieGlobal = {};
     }
-
     function $bm_isInstanceOfArray(arr) {
       return arr.constructor === Array || arr.constructor === Float32Array;
     }
-
     function isNumerable(tOfV, v) {
       return tOfV === 'number' || v instanceof Number || tOfV === 'boolean' || tOfV === 'string';
     }
-
     function $bm_neg(a) {
       var tOfA = _typeof$1(a);
-
       if (tOfA === 'number' || a instanceof Number || tOfA === 'boolean') {
         return -a;
       }
-
       if ($bm_isInstanceOfArray(a)) {
         var i;
         var lenA = a.length;
         var retArr = [];
-
         for (i = 0; i < lenA; i += 1) {
           retArr[i] = -a[i];
         }
-
         return retArr;
       }
-
       if (a.propType) {
         return a.v;
       }
-
       return -a;
     }
-
     var easeInBez = BezierFactory.getBezierEasing(0.333, 0, 0.833, 0.833, 'easeIn').get;
     var easeOutBez = BezierFactory.getBezierEasing(0.167, 0.167, 0.667, 1, 'easeOut').get;
     var easeInOutBez = BezierFactory.getBezierEasing(0.33, 0, 0.667, 1, 'easeInOut').get;
-
     function sum(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b) || tOfA === 'string' || tOfB === 'string') {
         return a + b;
       }
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         a = a.slice(0);
         a[0] += b;
         return a;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         b = b.slice(0);
         b[0] = a + b[0];
         return b;
       }
-
       if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
         var i = 0;
         var lenA = a.length;
         var lenB = b.length;
         var retArr = [];
-
         while (i < lenA || i < lenB) {
           if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
             retArr[i] = a[i] + b[i];
           } else {
             retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
           }
-
           i += 1;
         }
-
         return retArr;
       }
-
       return 0;
     }
-
     var add = sum;
-
     function sub(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         if (tOfA === 'string') {
           a = parseInt(a, 10);
         }
-
         if (tOfB === 'string') {
           b = parseInt(b, 10);
         }
-
         return a - b;
       }
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         a = a.slice(0);
         a[0] -= b;
         return a;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         b = b.slice(0);
         b[0] = a - b[0];
         return b;
       }
-
       if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
         var i = 0;
         var lenA = a.length;
         var lenB = b.length;
         var retArr = [];
-
         while (i < lenA || i < lenB) {
           if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
             retArr[i] = a[i] - b[i];
           } else {
             retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
           }
-
           i += 1;
         }
-
         return retArr;
       }
-
       return 0;
     }
-
     function mul(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       var arr;
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         return a * b;
       }
-
       var i;
       var len;
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         len = a.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a[i] * b;
         }
-
         return arr;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         len = b.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a * b[i];
         }
-
         return arr;
       }
-
       return 0;
     }
-
     function div(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       var arr;
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         return a / b;
       }
-
       var i;
       var len;
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         len = a.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a[i] / b;
         }
-
         return arr;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         len = b.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a / b[i];
         }
-
         return arr;
       }
-
       return 0;
     }
-
     function mod(a, b) {
       if (typeof a === 'string') {
         a = parseInt(a, 10);
       }
-
       if (typeof b === 'string') {
         b = parseInt(b, 10);
       }
-
       return a % b;
     }
-
     var $bm_sum = sum;
     var $bm_sub = sub;
     var $bm_mul = mul;
     var $bm_div = div;
     var $bm_mod = mod;
-
     function clamp(num, min, max) {
       if (min > max) {
         var mm = max;
         max = min;
         min = mm;
       }
-
       return Math.min(Math.max(num, min), max);
     }
-
     function radiansToDegrees(val) {
       return val / degToRads;
     }
-
     var radians_to_degrees = radiansToDegrees;
-
     function degreesToRadians(val) {
       return val * degToRads;
     }
-
     var degrees_to_radians = radiansToDegrees;
     var helperLengthArray = [0, 0, 0, 0, 0, 0];
-
     function length(arr1, arr2) {
       if (typeof arr1 === 'number' || arr1 instanceof Number) {
         arr2 = arr2 || 0;
         return Math.abs(arr1 - arr2);
       }
-
       if (!arr2) {
         arr2 = helperLengthArray;
       }
-
       var i;
       var len = Math.min(arr1.length, arr2.length);
       var addedLength = 0;
-
       for (i = 0; i < len; i += 1) {
         addedLength += Math.pow(arr2[i] - arr1[i], 2);
       }
-
       return Math.sqrt(addedLength);
     }
-
     function normalize(vec) {
       return div(vec, length(vec));
     }
-
     function rgbToHsl(val) {
       var r = val[0];
       var g = val[1];
@@ -15484,38 +13130,29 @@
       var h;
       var s;
       var l = (max + min) / 2;
-
       if (max === min) {
         h = 0; // achromatic
-
         s = 0; // achromatic
       } else {
         var d = max - min;
         s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
-
         switch (max) {
           case r:
             h = (g - b) / d + (g < b ? 6 : 0);
             break;
-
           case g:
             h = (b - r) / d + 2;
             break;
-
           case b:
             h = (r - g) / d + 4;
             break;
-
           default:
             break;
         }
-
         h /= 6;
       }
-
       return [h, s, l, val[3]];
     }
-
     function hue2rgb(p, q, t) {
       if (t < 0) t += 1;
       if (t > 1) t -= 1;
@@ -15524,7 +13161,6 @@
       if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
       return p;
     }
-
     function hslToRgb(val) {
       var h = val[0];
       var s = val[1];
@@ -15532,12 +13168,9 @@
       var r;
       var g;
       var b;
-
       if (s === 0) {
         r = l; // achromatic
-
         b = l; // achromatic
-
         g = l; // achromatic
       } else {
         var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
@@ -15546,10 +13179,8 @@
         g = hue2rgb(p, q, h);
         b = hue2rgb(p, q, h - 1 / 3);
       }
-
       return [r, g, b, val[3]];
     }
-
     function linear(t, tMin, tMax, value1, value2) {
       if (value1 === undefined || value2 === undefined) {
         value1 = tMin;
@@ -15557,38 +13188,29 @@
         tMin = 0;
         tMax = 1;
       }
-
       if (tMax < tMin) {
         var _tMin = tMax;
         tMax = tMin;
         tMin = _tMin;
       }
-
       if (t <= tMin) {
         return value1;
       }
-
       if (t >= tMax) {
         return value2;
       }
-
       var perc = tMax === tMin ? 0 : (t - tMin) / (tMax - tMin);
-
       if (!value1.length) {
         return value1 + (value2 - value1) * perc;
       }
-
       var i;
       var len = value1.length;
       var arr = createTypedArray('float32', len);
-
       for (i = 0; i < len; i += 1) {
         arr[i] = value1[i] + (value2[i] - value1[i]) * perc;
       }
-
       return arr;
     }
-
     function random(min, max) {
       if (max === undefined) {
         if (min === undefined) {
@@ -15599,33 +13221,25 @@
           min = undefined;
         }
       }
-
       if (max.length) {
         var i;
         var len = max.length;
-
         if (!min) {
           min = createTypedArray('float32', len);
         }
-
         var arr = createTypedArray('float32', len);
         var rnd = BMMath.random();
-
         for (i = 0; i < len; i += 1) {
           arr[i] = min[i] + rnd * (max[i] - min[i]);
         }
-
         return arr;
       }
-
       if (min === undefined) {
         min = 0;
       }
-
       var rndm = BMMath.random();
       return min + rndm * (max - min);
     }
-
     function createPath(points, inTangents, outTangents, closed) {
       var i;
       var len = points.length;
@@ -15634,37 +13248,31 @@
       var arrPlaceholder = [0, 0];
       var inVertexPoint;
       var outVertexPoint;
-
       for (i = 0; i < len; i += 1) {
         inVertexPoint = inTangents && inTangents[i] ? inTangents[i] : arrPlaceholder;
         outVertexPoint = outTangents && outTangents[i] ? outTangents[i] : arrPlaceholder;
         path.setTripleAt(points[i][0], points[i][1], outVertexPoint[0] + points[i][0], outVertexPoint[1] + points[i][1], inVertexPoint[0] + points[i][0], inVertexPoint[1] + points[i][1], i, true);
       }
-
       return path;
     }
-
     function initiateExpression(elem, data, property) {
       // Bail out if we don't want expressions
       function noOp(_value) {
         return _value;
       }
-
       if (!elem.globalData.renderConfig.runExpressions) {
         return noOp;
       }
-
       var val = data.x;
       var needsVelocity = /velocity(?![\w\d])/.test(val);
-
       var _needsRandom = val.indexOf('random') !== -1;
-
       var elemType = elem.data.ty;
       var transform;
       var $bm_transform;
       var content;
       var effect;
       var thisProperty = property;
+      thisProperty._name = elem.data.nm;
       thisProperty.valueAtTime = thisProperty.getValueAtTime;
       Object.defineProperty(thisProperty, 'value', {
         get: function get() {
@@ -15697,13 +13305,11 @@
       var mask;
       var valueAtTime;
       var velocityAtTime;
-      var scoped_bm_rt; // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
-
+      var scoped_bm_rt;
+      // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
       var expression_function = eval('[function _expression_function(){' + val + ';scoped_bm_rt=$bm_rt}]')[0]; // eslint-disable-line no-eval
-
       var numKeys = property.kf ? data.k.length : 0;
       var active = !this.data || this.data.hd !== true;
-
       var wiggle = function wiggle(freq, amp) {
         var iWiggle;
         var j;
@@ -15713,84 +13319,67 @@
         var iterations = Math.floor(time * freq);
         iWiggle = 0;
         j = 0;
-
         while (iWiggle < iterations) {
           // var rnd = BMMath.random();
           for (j = 0; j < lenWiggle; j += 1) {
-            addedAmps[j] += -amp + amp * 2 * BMMath.random(); // addedAmps[j] += -amp + amp*2*rnd;
+            addedAmps[j] += -amp + amp * 2 * BMMath.random();
+            // addedAmps[j] += -amp + amp*2*rnd;
           }
-
           iWiggle += 1;
-        } // var rnd2 = BMMath.random();
-
-
+        }
+        // var rnd2 = BMMath.random();
         var periods = time * freq;
         var perc = periods - Math.floor(periods);
         var arr = createTypedArray('float32', lenWiggle);
-
         if (lenWiggle > 1) {
           for (j = 0; j < lenWiggle; j += 1) {
-            arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc; // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
+            arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc;
+            // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
             // arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc);
           }
-
           return arr;
         }
-
         return this.pv + addedAmps[0] + (-amp + amp * 2 * BMMath.random()) * perc;
       }.bind(this);
-
       if (thisProperty.loopIn) {
         loopIn = thisProperty.loopIn.bind(thisProperty);
         loop_in = loopIn;
       }
-
       if (thisProperty.loopOut) {
         loopOut = thisProperty.loopOut.bind(thisProperty);
         loop_out = loopOut;
       }
-
       if (thisProperty.smooth) {
         smooth = thisProperty.smooth.bind(thisProperty);
       }
-
       function loopInDuration(type, duration) {
         return loopIn(type, duration, true);
       }
-
       function loopOutDuration(type, duration) {
         return loopOut(type, duration, true);
       }
-
       if (this.getValueAtTime) {
         valueAtTime = this.getValueAtTime.bind(this);
       }
-
       if (this.getVelocityAtTime) {
         velocityAtTime = this.getVelocityAtTime.bind(this);
       }
-
       var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface);
-
       function lookAt(elem1, elem2) {
         var fVec = [elem2[0] - elem1[0], elem2[1] - elem1[1], elem2[2] - elem1[2]];
         var pitch = Math.atan2(fVec[0], Math.sqrt(fVec[1] * fVec[1] + fVec[2] * fVec[2])) / degToRads;
         var yaw = -Math.atan2(fVec[1], fVec[2]) / degToRads;
         return [yaw, pitch, 0];
       }
-
       function easeOut(t, tMin, tMax, val1, val2) {
         return applyEase(easeOutBez, t, tMin, tMax, val1, val2);
       }
-
       function easeIn(t, tMin, tMax, val1, val2) {
         return applyEase(easeInBez, t, tMin, tMax, val1, val2);
       }
-
       function ease(t, tMin, tMax, val1, val2) {
         return applyEase(easeInOutBez, t, tMin, tMax, val1, val2);
       }
-
       function applyEase(fn, t, tMin, tMax, val1, val2) {
         if (val1 === undefined) {
           val1 = tMin;
@@ -15798,43 +13387,34 @@
         } else {
           t = (t - tMin) / (tMax - tMin);
         }
-
         if (t > 1) {
           t = 1;
         } else if (t < 0) {
           t = 0;
         }
-
         var mult = fn(t);
-
         if ($bm_isInstanceOfArray(val1)) {
           var iKey;
           var lenKey = val1.length;
           var arr = createTypedArray('float32', lenKey);
-
           for (iKey = 0; iKey < lenKey; iKey += 1) {
             arr[iKey] = (val2[iKey] - val1[iKey]) * mult + val1[iKey];
           }
-
           return arr;
         }
-
         return (val2 - val1) * mult + val1;
       }
-
       function nearestKey(time) {
         var iKey;
         var lenKey = data.k.length;
         var index;
         var keyTime;
-
         if (!data.k.length || typeof data.k[0] === 'number') {
           index = 0;
           keyTime = 0;
         } else {
           index = -1;
           time *= elem.comp.globalData.frameRate;
-
           if (time < data.k[0].t) {
             index = 1;
             keyTime = data.k[0].t;
@@ -15852,33 +13432,27 @@
                   index = iKey + 1;
                   keyTime = data.k[iKey].t;
                 }
-
                 break;
               }
             }
-
             if (index === -1) {
               index = iKey + 1;
               keyTime = data.k[iKey].t;
             }
           }
         }
-
         var obKey = {};
         obKey.index = index;
         obKey.time = keyTime / elem.comp.globalData.frameRate;
         return obKey;
       }
-
       function key(ind) {
         var obKey;
         var iKey;
         var lenKey;
-
         if (!data.k.length || typeof data.k[0] === 'number') {
           throw new Error('The property has no keyframe at index ' + ind);
         }
-
         ind -= 1;
         obKey = {
           time: data.k[ind].t / elem.comp.globalData.frameRate,
@@ -15886,72 +13460,55 @@
         };
         var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e;
         lenKey = arr.length;
-
         for (iKey = 0; iKey < lenKey; iKey += 1) {
           obKey[iKey] = arr[iKey];
           obKey.value[iKey] = arr[iKey];
         }
-
         return obKey;
       }
-
       function framesToTime(fr, fps) {
         if (!fps) {
           fps = elem.comp.globalData.frameRate;
         }
-
         return fr / fps;
       }
-
       function timeToFrames(t, fps) {
         if (!t && t !== 0) {
           t = time;
         }
-
         if (!fps) {
           fps = elem.comp.globalData.frameRate;
         }
-
         return t * fps;
       }
-
       function seedRandom(seed) {
         BMMath.seedrandom(randSeed + seed);
       }
-
       function sourceRectAtTime() {
         return elem.sourceRectAtTime();
       }
-
       function substring(init, end) {
         if (typeof value === 'string') {
           if (end === undefined) {
             return value.substring(init);
           }
-
           return value.substring(init, end);
         }
-
         return '';
       }
-
       function substr(init, end) {
         if (typeof value === 'string') {
           if (end === undefined) {
             return value.substr(init);
           }
-
           return value.substr(init, end);
         }
-
         return '';
       }
-
       function posterizeTime(framesPerSecond) {
         time = framesPerSecond === 0 ? 0 : Math.floor(time * framesPerSecond) / framesPerSecond;
         value = valueAtTime(time);
       }
-
       var time;
       var velocity;
       var value;
@@ -15964,21 +13521,17 @@
       var parent;
       var randSeed = Math.floor(Math.random() * 1000000);
       var globalData = elem.globalData;
-
       function executeExpression(_value) {
         // globalData.pushExpression();
         value = _value;
-
         if (this.frameExpressionId === elem.globalData.frameId && this.propType !== 'textSelector') {
           return value;
         }
-
         if (this.propType === 'textSelector') {
           textIndex = this.textIndex;
           textTotal = this.textTotal;
           selectorValue = this.selectorValue;
         }
-
         if (!thisLayer) {
           text = elem.layerInterface.text;
           thisLayer = elem.layerInterface;
@@ -15990,11 +13543,9 @@
           mask = thisLayer.mask ? thisLayer.mask.bind(thisLayer) : null;
           fromCompToSurface = fromComp;
         }
-
         if (!transform) {
           transform = elem.layerInterface('ADBE Transform Group');
           $bm_transform = transform;
-
           if (transform) {
             anchorPoint = transform.anchorPoint;
             /* position = transform.position;
@@ -16002,44 +13553,35 @@
                       scale = transform.scale; */
           }
         }
-
         if (elemType === 4 && !content) {
           content = thisLayer('ADBE Root Vectors Group');
         }
-
         if (!effect) {
           effect = thisLayer(4);
         }
-
         hasParent = !!(elem.hierarchy && elem.hierarchy.length);
-
         if (hasParent && !parent) {
           parent = elem.hierarchy[0].layerInterface;
         }
-
         time = this.comp.renderedFrame / this.comp.globalData.frameRate;
-
         if (_needsRandom) {
           seedRandom(randSeed + time);
         }
-
         if (needsVelocity) {
           velocity = velocityAtTime(time);
         }
-
         expression_function();
-        this.frameExpressionId = elem.globalData.frameId; // TODO: Check if it's possible to return on ShapeInterface the .v value
-        // Changed this to a ternary operation because Rollup failed compiling it correctly
+        this.frameExpressionId = elem.globalData.frameId;
 
+        // TODO: Check if it's possible to return on ShapeInterface the .v value
+        // Changed this to a ternary operation because Rollup failed compiling it correctly
         scoped_bm_rt = scoped_bm_rt.propType === propTypes.SHAPE ? scoped_bm_rt.v : scoped_bm_rt;
         return scoped_bm_rt;
-      } // Bundlers will see these as dead code and unless we reference them
-
-
+      }
+      // Bundlers will see these as dead code and unless we reference them
       executeExpression.__preventDeadCodeRemoval = [$bm_transform, anchorPoint, time, velocity, inPoint, outPoint, width, height, name, loop_in, loop_out, smooth, toComp, fromCompToSurface, toWorld, fromWorld, mask, position, rotation, scale, thisComp, numKeys, active, wiggle, loopInDuration, loopOutDuration, comp, lookAt, easeOut, easeIn, ease, nearestKey, key, text, textIndex, textTotal, selectorValue, framesToTime, timeToFrames, sourceRectAtTime, substring, substr, posterizeTime, index, globalData];
       return executeExpression;
     }
-
     ob.initiateExpression = initiateExpression;
     ob.__preventDeadCodeRemoval = [window, document, XMLHttpRequest, fetch, frames, $bm_neg, add, $bm_sum, $bm_sub, $bm_mul, $bm_div, $bm_mod, clamp, radians_to_degrees, degreesToRadians, degrees_to_radians, normalize, rgbToHsl, hslToRgb, linear, random, createPath, _lottieGlobal];
     ob.resetFrame = resetFrame;
@@ -16050,47 +13592,37 @@
     var ob = {};
     ob.initExpressions = initExpressions;
     ob.resetFrame = ExpressionManager.resetFrame;
-
     function initExpressions(animation) {
       var stackCount = 0;
       var registers = [];
-
       function pushExpression() {
         stackCount += 1;
       }
-
       function popExpression() {
         stackCount -= 1;
-
         if (stackCount === 0) {
           releaseInstances();
         }
       }
-
       function registerExpressionProperty(expression) {
         if (registers.indexOf(expression) === -1) {
           registers.push(expression);
         }
       }
-
       function releaseInstances() {
         var i;
         var len = registers.length;
-
         for (i = 0; i < len; i += 1) {
           registers[i].release();
         }
-
         registers.length = 0;
       }
-
       animation.renderer.compInterface = CompExpressionInterface(animation.renderer);
       animation.renderer.globalData.projectInterface.registerComposition(animation.renderer);
       animation.renderer.globalData.pushExpression = pushExpression;
       animation.renderer.globalData.popExpression = popExpression;
       animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty;
     }
-
     return ob;
   }();
 
@@ -16099,13 +13631,11 @@
       this._mask = mask;
       this._data = data;
     }
-
     Object.defineProperty(MaskInterface.prototype, 'maskPath', {
       get: function get() {
         if (this._mask.prop.k) {
           this._mask.prop.getValue();
         }
-
         return this._mask.prop;
       }
     });
@@ -16114,38 +13644,28 @@
         if (this._mask.op.k) {
           this._mask.op.getValue();
         }
-
         return this._mask.op.v * 100;
       }
     });
-
     var MaskManager = function MaskManager(maskManager) {
       var _masksInterfaces = createSizedArray(maskManager.viewData.length);
-
       var i;
       var len = maskManager.viewData.length;
-
       for (i = 0; i < len; i += 1) {
         _masksInterfaces[i] = new MaskInterface(maskManager.viewData[i], maskManager.masksProperties[i]);
       }
-
       var maskFunction = function maskFunction(name) {
         i = 0;
-
         while (i < len) {
           if (maskManager.masksProperties[i].nm === name) {
             return _masksInterfaces[i];
           }
-
           i += 1;
         }
-
         return null;
       };
-
       return maskFunction;
     };
-
     return MaskManager;
   }();
 
@@ -16160,7 +13680,6 @@
       v: [0, 0, 0],
       mult: 1
     };
-
     function completeProperty(expressionValue, property, type) {
       Object.defineProperty(expressionValue, 'velocity', {
         get: function get() {
@@ -16168,14 +13687,11 @@
         }
       });
       expressionValue.numKeys = property.keyframes ? property.keyframes.length : 0;
-
       expressionValue.key = function (pos) {
         if (!expressionValue.numKeys) {
           return 0;
         }
-
         var value = '';
-
         if ('s' in property.keyframes[pos - 1]) {
           value = property.keyframes[pos - 1].s;
         } else if ('e' in property.keyframes[pos - 2]) {
@@ -16183,54 +13699,43 @@
         } else {
           value = property.keyframes[pos - 2].s;
         }
-
         var valueProp = type === 'unidimensional' ? new Number(value) : Object.assign({}, value); // eslint-disable-line no-new-wrappers
-
         valueProp.time = property.keyframes[pos - 1].t / property.elem.comp.globalData.frameRate;
         valueProp.value = type === 'unidimensional' ? value[0] : value;
         return valueProp;
       };
-
       expressionValue.valueAtTime = property.getValueAtTime;
       expressionValue.speedAtTime = property.getSpeedAtTime;
       expressionValue.velocityAtTime = property.getVelocityAtTime;
       expressionValue.propertyGroup = property.propertyGroup;
     }
-
     function UnidimensionalPropertyInterface(property) {
       if (!property || !('pv' in property)) {
         property = defaultUnidimensionalValue;
       }
-
       var mult = 1 / property.mult;
       var val = property.pv * mult;
       var expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
-
       expressionValue.value = val;
       completeProperty(expressionValue, property, 'unidimensional');
       return function () {
         if (property.k) {
           property.getValue();
         }
-
         val = property.v * mult;
-
         if (expressionValue.value !== val) {
           expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
-
           expressionValue.value = val;
+          expressionValue[0] = val;
           completeProperty(expressionValue, property, 'unidimensional');
         }
-
         return expressionValue;
       };
     }
-
     function MultidimensionalPropertyInterface(property) {
       if (!property || !('pv' in property)) {
         property = defaultMultidimensionalValue;
       }
-
       var mult = 1 / property.mult;
       var len = property.data && property.data.l || property.pv.length;
       var expressionValue = createTypedArray('float32', len);
@@ -16241,30 +13746,25 @@
         if (property.k) {
           property.getValue();
         }
-
         for (var i = 0; i < len; i += 1) {
           arrValue[i] = property.v[i] * mult;
           expressionValue[i] = arrValue[i];
         }
-
         return expressionValue;
       };
-    } // TODO: try to avoid using this getter
+    }
 
-
+    // TODO: try to avoid using this getter
     function defaultGetter() {
       return defaultUnidimensionalValue;
     }
-
     return function (property) {
       if (!property) {
         return defaultGetter;
       }
-
       if (property.propType === 'unidimensional') {
         return UnidimensionalPropertyInterface(property);
       }
-
       return MultidimensionalPropertyInterface(property);
     };
   }();
@@ -16278,52 +13778,41 @@
           case 'ADBE Scale':
           case 6:
             return _thisFunction.scale;
-
           case 'rotation':
           case 'Rotation':
           case 'ADBE Rotation':
           case 'ADBE Rotate Z':
           case 10:
             return _thisFunction.rotation;
-
           case 'ADBE Rotate X':
             return _thisFunction.xRotation;
-
           case 'ADBE Rotate Y':
             return _thisFunction.yRotation;
-
           case 'position':
           case 'Position':
           case 'ADBE Position':
           case 2:
             return _thisFunction.position;
-
           case 'ADBE Position_0':
             return _thisFunction.xPosition;
-
           case 'ADBE Position_1':
             return _thisFunction.yPosition;
-
           case 'ADBE Position_2':
             return _thisFunction.zPosition;
-
           case 'anchorPoint':
           case 'AnchorPoint':
           case 'Anchor Point':
           case 'ADBE AnchorPoint':
           case 1:
             return _thisFunction.anchorPoint;
-
           case 'opacity':
           case 'Opacity':
           case 11:
             return _thisFunction.opacity;
-
           default:
             return null;
         }
       }
-
       Object.defineProperty(_thisFunction, 'rotation', {
         get: ExpressionPropertyInterface(transform.r || transform.rz)
       });
@@ -16339,32 +13828,24 @@
       Object.defineProperty(_thisFunction, 'scale', {
         get: ExpressionPropertyInterface(transform.s)
       });
-
       var _px;
-
       var _py;
-
       var _pz;
-
       var _transformFactory;
-
       if (transform.p) {
         _transformFactory = ExpressionPropertyInterface(transform.p);
       } else {
         _px = ExpressionPropertyInterface(transform.px);
         _py = ExpressionPropertyInterface(transform.py);
-
         if (transform.pz) {
           _pz = ExpressionPropertyInterface(transform.pz);
         }
       }
-
       Object.defineProperty(_thisFunction, 'position', {
         get: function get() {
           if (transform.p) {
             return _transformFactory();
           }
-
           return [_px(), _py(), _pz ? _pz() : 0];
         }
       });
@@ -16399,19 +13880,15 @@
   var LayerExpressionInterface = function () {
     function getMatrix(time) {
       var toWorldMat = new Matrix();
-
       if (time !== undefined) {
         var propMatrix = this._elem.finalTransform.mProp.getValueAtTime(time);
-
         propMatrix.clone(toWorldMat);
       } else {
         var transformMat = this._elem.finalTransform.mProp;
         transformMat.applyToMatrix(toWorldMat);
       }
-
       return toWorldMat;
     }
-
     function toWorldVec(arr, time) {
       var toWorldMat = this.getMatrix(time);
       toWorldMat.props[12] = 0;
@@ -16419,12 +13896,10 @@
       toWorldMat.props[14] = 0;
       return this.applyPoint(toWorldMat, arr);
     }
-
     function toWorld(arr, time) {
       var toWorldMat = this.getMatrix(time);
       return this.applyPoint(toWorldMat, arr);
     }
-
     function fromWorldVec(arr, time) {
       var toWorldMat = this.getMatrix(time);
       toWorldMat.props[12] = 0;
@@ -16432,101 +13907,78 @@
       toWorldMat.props[14] = 0;
       return this.invertPoint(toWorldMat, arr);
     }
-
     function fromWorld(arr, time) {
       var toWorldMat = this.getMatrix(time);
       return this.invertPoint(toWorldMat, arr);
     }
-
     function applyPoint(matrix, arr) {
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
         }
       }
-
       return matrix.applyToPointArray(arr[0], arr[1], arr[2] || 0);
     }
-
     function invertPoint(matrix, arr) {
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
         }
       }
-
       return matrix.inversePoint(arr);
     }
-
     function fromComp(arr) {
       var toWorldMat = new Matrix();
       toWorldMat.reset();
-
       this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
-
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
         }
-
         return toWorldMat.inversePoint(arr);
       }
-
       return toWorldMat.inversePoint(arr);
     }
-
     function sampleImage() {
       return [1, 1, 1, 1];
     }
-
     return function (elem) {
       var transformInterface;
-
       function _registerMaskInterface(maskManager) {
         _thisLayerFunction.mask = new MaskManagerInterface(maskManager, elem);
       }
-
       function _registerEffectsInterface(effects) {
         _thisLayerFunction.effect = effects;
       }
-
       function _thisLayerFunction(name) {
         switch (name) {
           case 'ADBE Root Vectors Group':
           case 'Contents':
           case 2:
             return _thisLayerFunction.shapeInterface;
-
           case 1:
           case 6:
           case 'Transform':
           case 'transform':
           case 'ADBE Transform Group':
             return transformInterface;
-
           case 4:
           case 'ADBE Effect Parade':
           case 'effects':
           case 'Effects':
             return _thisLayerFunction.effect;
-
           case 'ADBE Text Properties':
             return _thisLayerFunction.textInterface;
-
           default:
             return null;
         }
       }
-
       _thisLayerFunction.getMatrix = getMatrix;
       _thisLayerFunction.invertPoint = invertPoint;
       _thisLayerFunction.applyPoint = applyPoint;
@@ -16587,11 +14039,9 @@
     return function (interfaceFunction, parentPropertyGroup) {
       return function (val) {
         val = val === undefined ? 1 : val;
-
         if (val <= 0) {
           return interfaceFunction;
         }
-
         return parentPropertyGroup(val - 1);
       };
     };
@@ -16602,17 +14052,13 @@
       var interfaceFunction = {
         _name: propertyName
       };
-
       function _propertyGroup(val) {
         val = val === undefined ? 1 : val;
-
         if (val <= 0) {
           return interfaceFunction;
         }
-
         return propertyGroup(val - 1);
       }
-
       return _propertyGroup;
     };
   }();
@@ -16621,35 +14067,27 @@
     var ob = {
       createEffectsInterface: createEffectsInterface
     };
-
     function createEffectsInterface(elem, propertyGroup) {
       if (elem.effectsManager) {
         var effectElements = [];
         var effectsData = elem.data.ef;
         var i;
         var len = elem.effectsManager.effectElements.length;
-
         for (i = 0; i < len; i += 1) {
           effectElements.push(createGroupInterface(effectsData[i], elem.effectsManager.effectElements[i], propertyGroup, elem));
         }
-
         var effects = elem.data.ef || [];
-
         var groupInterface = function groupInterface(name) {
           i = 0;
           len = effects.length;
-
           while (i < len) {
             if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
               return effectElements[i];
             }
-
             i += 1;
           }
-
           return null;
         };
-
         Object.defineProperty(groupInterface, 'numProperties', {
           get: function get() {
             return effects.length;
@@ -16657,37 +14095,28 @@
         });
         return groupInterface;
       }
-
       return null;
     }
-
     function createGroupInterface(data, elements, propertyGroup, elem) {
       function groupInterface(name) {
         var effects = data.ef;
         var i = 0;
         var len = effects.length;
-
         while (i < len) {
           if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
             if (effects[i].ty === 5) {
               return effectElements[i];
             }
-
             return effectElements[i]();
           }
-
           i += 1;
         }
-
         throw new Error();
       }
-
       var _propertyGroup = propertyGroupFactory(groupInterface, propertyGroup);
-
       var effectElements = [];
       var i;
       var len = data.ef.length;
-
       for (i = 0; i < len; i += 1) {
         if (data.ef[i].ty === 5) {
           effectElements.push(createGroupInterface(data.ef[i], elements.effectElements[i], elements.effectElements[i].propertyGroup, elem));
@@ -16695,7 +14124,6 @@
           effectElements.push(createValueInterface(elements.effectElements[i], data.ef[i].ty, elem, _propertyGroup));
         }
       }
-
       if (data.mn === 'ADBE Color Control') {
         Object.defineProperty(groupInterface, 'color', {
           get: function get() {
@@ -16703,7 +14131,6 @@
           }
         });
       }
-
       Object.defineProperties(groupInterface, {
         numProperties: {
           get: function get() {
@@ -16721,42 +14148,32 @@
       groupInterface.active = groupInterface.enabled;
       return groupInterface;
     }
-
     function createValueInterface(element, type, elem, propertyGroup) {
       var expressionProperty = ExpressionPropertyInterface(element.p);
-
       function interfaceFunction() {
         if (type === 10) {
           return elem.comp.compInterface(element.p.v);
         }
-
         return expressionProperty();
       }
-
       if (element.p.setGroupProperty) {
         element.p.setGroupProperty(PropertyInterface('', propertyGroup));
       }
-
       return interfaceFunction;
     }
-
     return ob;
   }();
 
   var ShapePathInterface = function () {
     return function pathInterfaceFactory(shape, view, propertyGroup) {
       var prop = view.sh;
-
       function interfaceFunction(val) {
         if (val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2) {
           return interfaceFunction.path;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       prop.setGroupProperty(PropertyInterface('Path', _propertyGroup));
       Object.defineProperties(interfaceFunction, {
         path: {
@@ -16764,7 +14181,6 @@
             if (prop.k) {
               prop.getValue();
             }
-
             return prop;
           }
         },
@@ -16773,7 +14189,6 @@
             if (prop.k) {
               prop.getValue();
             }
-
             return prop;
           }
         },
@@ -16802,7 +14217,6 @@
       var arr = [];
       var i;
       var len = shapes ? shapes.length : 0;
-
       for (i = 0; i < len; i += 1) {
         if (shapes[i].ty === 'gr') {
           arr.push(groupInterfaceFactory(shapes[i], view[i], propertyGroup));
@@ -16812,7 +14226,8 @@
           arr.push(strokeInterfaceFactory(shapes[i], view[i], propertyGroup));
         } else if (shapes[i].ty === 'tm') {
           arr.push(trimInterfaceFactory(shapes[i], view[i], propertyGroup));
-        } else if (shapes[i].ty === 'tr') {// arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
+        } else if (shapes[i].ty === 'tr') {
+          // arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
         } else if (shapes[i].ty === 'el') {
           arr.push(ellipseInterfaceFactory(shapes[i], view[i], propertyGroup));
         } else if (shapes[i].ty === 'sr') {
@@ -16831,32 +14246,24 @@
           arr.push(defaultInterfaceFactory(shapes[i], view[i], propertyGroup));
         }
       }
-
       return arr;
     }
-
     function contentsInterfaceFactory(shape, view, propertyGroup) {
       var interfaces;
-
       var interfaceFunction = function _interfaceFunction(value) {
         var i = 0;
         var len = interfaces.length;
-
         while (i < len) {
           if (interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value) {
             return interfaces[i];
           }
-
           i += 1;
         }
-
         if (typeof value === 'number') {
           return interfaces[value - 1];
         }
-
         return null;
       };
-
       interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
       interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup);
       interfaceFunction.numProperties = interfaces.length;
@@ -16866,7 +14273,6 @@
       interfaceFunction._name = shape.nm;
       return interfaceFunction;
     }
-
     function groupInterfaceFactory(shape, view, propertyGroup) {
       var interfaceFunction = function _interfaceFunction(value) {
         switch (value) {
@@ -16877,12 +14283,10 @@
           // Not necessary for now. Keeping them here in case a new case appears
           // case 'ADBE Vector Transform Group':
           // case 3:
-
           default:
             return interfaceFunction.transform;
         }
       };
-
       interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
       var content = contentsInterfaceFactory(shape, view, interfaceFunction.propertyGroup);
       var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
@@ -16892,28 +14296,24 @@
         get: function get() {
           return shape.nm;
         }
-      }); // interfaceFunction.content = interfaceFunction;
-
+      });
+      // interfaceFunction.content = interfaceFunction;
       interfaceFunction.numProperties = shape.np;
       interfaceFunction.propertyIndex = shape.ix;
       interfaceFunction.nm = shape.nm;
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function fillInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(val) {
         if (val === 'Color' || val === 'color') {
           return interfaceFunction.color;
         }
-
         if (val === 'Opacity' || val === 'opacity') {
           return interfaceFunction.opacity;
         }
-
         return null;
       }
-
       Object.defineProperties(interfaceFunction, {
         color: {
           get: ExpressionPropertyInterface(view.c)
@@ -16932,24 +14332,19 @@
       view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
       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)
@@ -16977,51 +14372,39 @@
       view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
       return interfaceFunction;
     }
-
     function defaultInterfaceFactory() {
       function interfaceFunction() {
         return null;
       }
-
       return interfaceFunction;
     }
-
     function strokeInterfaceFactory(shape, view, propertyGroup) {
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup);
-
       function addPropertyToDashOb(i) {
         Object.defineProperty(dashOb, shape.d[i].nm, {
           get: ExpressionPropertyInterface(view.d.dataProps[i].p)
         });
       }
-
       var i;
       var len = shape.d ? shape.d.length : 0;
       var dashOb = {};
-
       for (i = 0; i < len; i += 1) {
         addPropertyToDashOb(i);
         view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup);
       }
-
       function interfaceFunction(val) {
         if (val === 'Color' || val === 'color') {
           return interfaceFunction.color;
         }
-
         if (val === 'Opacity' || val === 'opacity') {
           return interfaceFunction.opacity;
         }
-
         if (val === 'Stroke Width' || val === 'stroke width') {
           return interfaceFunction.strokeWidth;
         }
-
         return null;
       }
-
       Object.defineProperties(interfaceFunction, {
         color: {
           get: ExpressionPropertyInterface(view.c)
@@ -17049,26 +14432,20 @@
       view.w.setGroupProperty(PropertyInterface('Stroke Width', _propertyGroup));
       return interfaceFunction;
     }
-
     function trimInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(val) {
         if (val === shape.e.ix || val === 'End' || val === 'end') {
           return interfaceFunction.end;
         }
-
         if (val === shape.s.ix) {
           return interfaceFunction.start;
         }
-
         if (val === shape.o.ix) {
           return interfaceFunction.offset;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       interfaceFunction.propertyIndex = shape.ix;
       view.s.setGroupProperty(PropertyInterface('Start', _propertyGroup));
       view.e.setGroupProperty(PropertyInterface('End', _propertyGroup));
@@ -17092,53 +14469,41 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function transformInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.a.ix === value || value === 'Anchor Point') {
           return interfaceFunction.anchorPoint;
         }
-
         if (shape.o.ix === value || value === 'Opacity') {
           return interfaceFunction.opacity;
         }
-
         if (shape.p.ix === value || value === 'Position') {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value || value === 'Rotation' || value === 'ADBE Vector Rotation') {
           return interfaceFunction.rotation;
         }
-
         if (shape.s.ix === value || value === 'Scale') {
           return interfaceFunction.scale;
         }
-
         if (shape.sk && shape.sk.ix === value || value === 'Skew') {
           return interfaceFunction.skew;
         }
-
         if (shape.sa && shape.sa.ix === value || value === 'Skew Axis') {
           return interfaceFunction.skewAxis;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
       view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
       view.transform.mProps.a.setGroupProperty(PropertyInterface('Anchor Point', _propertyGroup));
       view.transform.mProps.s.setGroupProperty(PropertyInterface('Scale', _propertyGroup));
       view.transform.mProps.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
-
       if (view.transform.mProps.sk) {
         view.transform.mProps.sk.setGroupProperty(PropertyInterface('Skew', _propertyGroup));
         view.transform.mProps.sa.setGroupProperty(PropertyInterface('Skew Angle', _propertyGroup));
       }
-
       view.transform.op.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
       Object.defineProperties(interfaceFunction, {
         opacity: {
@@ -17171,22 +14536,17 @@
       interfaceFunction.propertyGroup = propertyGroup;
       return interfaceFunction;
     }
-
     function ellipseInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.s.ix === value) {
           return interfaceFunction.size;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       interfaceFunction.propertyIndex = shape.ix;
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
@@ -17205,42 +14565,32 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function starInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value) {
           return interfaceFunction.rotation;
         }
-
         if (shape.pt.ix === value) {
           return interfaceFunction.points;
         }
-
         if (shape.or.ix === value || value === 'ADBE Vector Star Outer Radius') {
           return interfaceFunction.outerRadius;
         }
-
         if (shape.os.ix === value) {
           return interfaceFunction.outerRoundness;
         }
-
         if (shape.ir && (shape.ir.ix === value || value === 'ADBE Vector Star Inner Radius')) {
           return interfaceFunction.innerRadius;
         }
-
         if (shape.is && shape.is.ix === value) {
           return interfaceFunction.innerRoundness;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       interfaceFunction.propertyIndex = shape.ix;
       prop.or.setGroupProperty(PropertyInterface('Outer Radius', _propertyGroup));
@@ -17248,12 +14598,10 @@
       prop.pt.setGroupProperty(PropertyInterface('Points', _propertyGroup));
       prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
       prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
-
       if (shape.ir) {
         prop.ir.setGroupProperty(PropertyInterface('Inner Radius', _propertyGroup));
         prop.is.setGroupProperty(PropertyInterface('Inner Roundness', _propertyGroup));
       }
-
       Object.defineProperties(interfaceFunction, {
         position: {
           get: ExpressionPropertyInterface(prop.p)
@@ -17283,26 +14631,20 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function rectInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value) {
           return interfaceFunction.roundness;
         }
-
         if (shape.s.ix === value || value === 'Size' || value === 'ADBE Vector Rect Size') {
           return interfaceFunction.size;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       interfaceFunction.propertyIndex = shape.ix;
       prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
@@ -17325,18 +14667,14 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function roundedInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.r.ix === value || value === 'Round Corners 1') {
           return interfaceFunction.radius;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view;
       interfaceFunction.propertyIndex = shape.ix;
       prop.rd.setGroupProperty(PropertyInterface('Radius', _propertyGroup));
@@ -17351,22 +14689,17 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function repeaterInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.c.ix === value || value === 'Copies') {
           return interfaceFunction.copies;
         }
-
         if (shape.o.ix === value || value === 'Offset') {
           return interfaceFunction.offset;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view;
       interfaceFunction.propertyIndex = shape.ix;
       prop.c.setGroupProperty(PropertyInterface('Copies', _propertyGroup));
@@ -17385,39 +14718,29 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     return function (shapes, view, propertyGroup) {
       var interfaces;
-
       function _interfaceFunction(value) {
         if (typeof value === 'number') {
           value = value === undefined ? 1 : value;
-
           if (value === 0) {
             return propertyGroup;
           }
-
           return interfaces[value - 1];
         }
-
         var i = 0;
         var len = interfaces.length;
-
         while (i < len) {
           if (interfaces[i]._name === value) {
             return interfaces[i];
           }
-
           i += 1;
         }
-
         return null;
       }
-
       function parentGroupWrapper() {
         return propertyGroup;
       }
-
       _interfaceFunction.propertyGroup = propertyGroupFactory(_interfaceFunction, parentGroupWrapper);
       interfaces = iterateElements(shapes, view, _interfaceFunction.propertyGroup);
       _interfaceFunction.numProperties = interfaces.length;
@@ -17429,28 +14752,22 @@
   var TextExpressionInterface = function () {
     return function (elem) {
       var _sourceText;
-
       function _thisLayerFunction(name) {
         switch (name) {
           case 'ADBE Text Document':
             return _thisLayerFunction.sourceText;
-
           default:
             return null;
         }
       }
-
       Object.defineProperty(_thisLayerFunction, 'sourceText', {
         get: function get() {
           elem.textProperty.getValue();
           var stringValue = elem.textProperty.currentData.t;
-
           if (!_sourceText || stringValue !== _sourceText.value) {
             _sourceText = new String(stringValue); // eslint-disable-line no-new-wrappers
             // If stringValue is an empty string, eval returns undefined, so it has to be returned as a String primitive
-
             _sourceText.value = stringValue || new String(stringValue); // eslint-disable-line no-new-wrappers
-
             Object.defineProperty(_sourceText, 'style', {
               get: function get() {
                 return {
@@ -17459,7 +14776,6 @@
               }
             });
           }
-
           return _sourceText;
         }
       });
@@ -17467,73 +14783,56 @@
     };
   }();
 
-  function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
-
+  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
   var FootageInterface = function () {
     var outlineInterfaceFactory = function outlineInterfaceFactory(elem) {
       var currentPropertyName = '';
       var currentProperty = elem.getFootageData();
-
       function init() {
         currentPropertyName = '';
         currentProperty = elem.getFootageData();
         return searchProperty;
       }
-
       function searchProperty(value) {
         if (currentProperty[value]) {
           currentPropertyName = value;
           currentProperty = currentProperty[value];
-
           if (_typeof(currentProperty) === 'object') {
             return searchProperty;
           }
-
           return currentProperty;
         }
-
         var propertyNameIndex = value.indexOf(currentPropertyName);
-
         if (propertyNameIndex !== -1) {
           var index = parseInt(value.substr(propertyNameIndex + currentPropertyName.length), 10);
           currentProperty = currentProperty[index];
-
           if (_typeof(currentProperty) === 'object') {
             return searchProperty;
           }
-
           return currentProperty;
         }
-
         return '';
       }
-
       return init;
     };
-
     var dataInterfaceFactory = function dataInterfaceFactory(elem) {
       function interfaceFunction(value) {
         if (value === 'Outline') {
           return interfaceFunction.outlineInterface();
         }
-
         return null;
       }
-
       interfaceFunction._name = 'Outline';
       interfaceFunction.outlineInterface = outlineInterfaceFactory(elem);
       return interfaceFunction;
     };
-
     return function (elem) {
       function _interfaceFunction(value) {
         if (value === 'Data') {
           return _interfaceFunction.dataInterface;
         }
-
         return null;
       }
-
       _interfaceFunction._name = 'Data';
       _interfaceFunction.dataInterface = dataInterfaceFactory(elem);
       return _interfaceFunction;
@@ -17548,7 +14847,6 @@
     text: TextExpressionInterface,
     footage: FootageInterface
   };
-
   function getInterface(type) {
     return interfaces[type] || null;
   }
@@ -17562,56 +14860,44 @@
         prop.effectsSequence.push(prop.initiateExpression(elem, data, prop).bind(prop));
       }
     }
-
     function getValueAtTime(frameNum) {
       frameNum *= this.elem.globalData.frameRate;
       frameNum -= this.offsetTime;
-
       if (frameNum !== this._cachingAtTime.lastFrame) {
         this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0;
         this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime);
         this._cachingAtTime.lastFrame = frameNum;
       }
-
       return this._cachingAtTime.value;
     }
-
     function getSpeedAtTime(frameNum) {
       var delta = -0.01;
       var v1 = this.getValueAtTime(frameNum);
       var v2 = this.getValueAtTime(frameNum + delta);
       var speed = 0;
-
       if (v1.length) {
         var i;
-
         for (i = 0; i < v1.length; i += 1) {
           speed += Math.pow(v2[i] - v1[i], 2);
         }
-
         speed = Math.sqrt(speed) * 100;
       } else {
         speed = 0;
       }
-
       return speed;
     }
-
     function getVelocityAtTime(frameNum) {
       if (this.vel !== undefined) {
         return this.vel;
       }
-
-      var delta = -0.001; // frameNum += this.elem.data.st;
-
+      var delta = -0.001;
+      // frameNum += this.elem.data.st;
       var v1 = this.getValueAtTime(frameNum);
       var v2 = this.getValueAtTime(frameNum + delta);
       var velocity;
-
       if (v1.length) {
         velocity = createTypedArray('float32', v1.length);
         var i;
-
         for (i = 0; i < v1.length; i += 1) {
           // removing frameRate
           // if needed, don't add it here
@@ -17621,18 +14907,14 @@
       } else {
         velocity = (v2 - v1) / delta;
       }
-
       return velocity;
     }
-
     function getStaticValueAtTime() {
       return this.pv;
     }
-
     function setGroupProperty(propertyGroup) {
       this.propertyGroup = propertyGroup;
     }
-
     return {
       searchExpressions: searchExpressions,
       getSpeedAtTime: getSpeedAtTime,
@@ -17648,24 +14930,19 @@
       if (!this.k || !this.keyframes) {
         return this.pv;
       }
-
       type = type ? type.toLowerCase() : '';
       var currentFrame = this.comp.renderedFrame;
       var keyframes = this.keyframes;
       var lastKeyFrame = keyframes[keyframes.length - 1].t;
-
       if (currentFrame <= lastKeyFrame) {
         return this.pv;
       }
-
       var cycleDuration;
       var firstKeyFrame;
-
       if (!durationFlag) {
         if (!duration || duration > keyframes.length - 1) {
           duration = keyframes.length - 1;
         }
-
         firstKeyFrame = keyframes[keyframes.length - 1 - duration].t;
         cycleDuration = lastKeyFrame - firstKeyFrame;
       } else {
@@ -17674,17 +14951,13 @@
         } else {
           cycleDuration = Math.abs(lastKeyFrame - this.elem.comp.globalData.frameRate * duration);
         }
-
         firstKeyFrame = lastKeyFrame - cycleDuration;
       }
-
       var i;
       var len;
       var ret;
-
       if (type === 'pingpong') {
         var iterations = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
-
         if (iterations % 2 !== 0) {
           return this.getValueAtTime((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
         }
@@ -17692,64 +14965,48 @@
         var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
         var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
-
         var repeats = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
-
         if (this.pv.length) {
           ret = new Array(initV.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = (endV[i] - initV[i]) * repeats + current[i];
           }
-
           return ret;
         }
-
         return (endV - initV) * repeats + current;
       } else if (type === 'continue') {
         var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0);
-
         if (this.pv.length) {
           ret = new Array(lastValue.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = lastValue[i] + (lastValue[i] - nextLastValue[i]) * ((currentFrame - lastKeyFrame) / this.comp.globalData.frameRate) / 0.0005; // eslint-disable-line
           }
-
           return ret;
         }
-
         return lastValue + (lastValue - nextLastValue) * ((currentFrame - lastKeyFrame) / 0.001);
       }
-
       return this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
     }
-
     function loopIn(type, duration, durationFlag) {
       if (!this.k) {
         return this.pv;
       }
-
       type = type ? type.toLowerCase() : '';
       var currentFrame = this.comp.renderedFrame;
       var keyframes = this.keyframes;
       var firstKeyFrame = keyframes[0].t;
-
       if (currentFrame >= firstKeyFrame) {
         return this.pv;
       }
-
       var cycleDuration;
       var lastKeyFrame;
-
       if (!durationFlag) {
         if (!duration || duration > keyframes.length - 1) {
           duration = keyframes.length - 1;
         }
-
         lastKeyFrame = keyframes[duration].t;
         cycleDuration = lastKeyFrame - firstKeyFrame;
       } else {
@@ -17758,17 +15015,13 @@
         } else {
           cycleDuration = Math.abs(this.elem.comp.globalData.frameRate * duration);
         }
-
         lastKeyFrame = firstKeyFrame + cycleDuration;
       }
-
       var i;
       var len;
       var ret;
-
       if (type === 'pingpong') {
         var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration);
-
         if (iterations % 2 === 0) {
           return this.getValueAtTime(((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
         }
@@ -17777,52 +15030,39 @@
         var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var current = this.getValueAtTime((cycleDuration - (firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0);
         var repeats = Math.floor((firstKeyFrame - currentFrame) / cycleDuration) + 1;
-
         if (this.pv.length) {
           ret = new Array(initV.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = current[i] - (endV[i] - initV[i]) * repeats;
           }
-
           return ret;
         }
-
         return current - (endV - initV) * repeats;
       } else if (type === 'continue') {
         var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
         var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0);
-
         if (this.pv.length) {
           ret = new Array(firstValue.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = firstValue[i] + (firstValue[i] - nextFirstValue[i]) * (firstKeyFrame - currentFrame) / 0.001;
           }
-
           return ret;
         }
-
         return firstValue + (firstValue - nextFirstValue) * (firstKeyFrame - currentFrame) / 0.001;
       }
-
       return this.getValueAtTime((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
     }
-
     function smooth(width, samples) {
       if (!this.k) {
         return this.pv;
       }
-
       width = (width || 0.4) * 0.5;
       samples = Math.floor(samples || 5);
-
       if (samples <= 1) {
         return this.pv;
       }
-
       var currentTime = this.comp.renderedFrame / this.comp.globalData.frameRate;
       var initFrame = currentTime - width;
       var endFrame = currentTime + width;
@@ -17830,18 +15070,14 @@
       var i = 0;
       var j = 0;
       var value;
-
       if (this.pv.length) {
         value = createTypedArray('float32', this.pv.length);
       } else {
         value = 0;
       }
-
       var sampleValue;
-
       while (i < samples) {
         sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency);
-
         if (this.pv.length) {
           for (j = 0; j < this.pv.length; j += 1) {
             value[j] += sampleValue[j];
@@ -17849,10 +15085,8 @@
         } else {
           value += sampleValue;
         }
-
         i += 1;
       }
-
       if (this.pv.length) {
         for (j = 0; j < this.pv.length; j += 1) {
           value[j] /= samples;
@@ -17860,37 +15094,30 @@
       } else {
         value /= samples;
       }
-
       return value;
     }
-
     function getTransformValueAtTime(time) {
       if (!this._transformCachingAtTime) {
         this._transformCachingAtTime = {
           v: new Matrix()
         };
-      } /// /
-
-
+      }
+      /// /
       var matrix = this._transformCachingAtTime.v;
       matrix.cloneFromProps(this.pre.props);
-
       if (this.appliedTransformations < 1) {
         var anchor = this.a.getValueAtTime(time);
         matrix.translate(-anchor[0] * this.a.mult, -anchor[1] * this.a.mult, anchor[2] * this.a.mult);
       }
-
       if (this.appliedTransformations < 2) {
         var scale = this.s.getValueAtTime(time);
         matrix.scale(scale[0] * this.s.mult, scale[1] * this.s.mult, scale[2] * this.s.mult);
       }
-
       if (this.sk && this.appliedTransformations < 3) {
         var skew = this.sk.getValueAtTime(time);
         var skewAxis = this.sa.getValueAtTime(time);
         matrix.skewFromAxis(-skew * this.sk.mult, skewAxis * this.sa.mult);
       }
-
       if (this.r && this.appliedTransformations < 4) {
         var rotation = this.r.getValueAtTime(time);
         matrix.rotate(-rotation * this.r.mult);
@@ -17901,11 +15128,9 @@
         var orientation = this.or.getValueAtTime(time);
         matrix.rotateZ(-rotationZ * this.rz.mult).rotateY(rotationY * this.ry.mult).rotateX(rotationX * this.rx.mult).rotateZ(-orientation[2] * this.or.mult).rotateY(orientation[1] * this.or.mult).rotateX(orientation[0] * this.or.mult);
       }
-
       if (this.data.p && this.data.p.s) {
         var positionX = this.px.getValueAtTime(time);
         var positionY = this.py.getValueAtTime(time);
-
         if (this.data.p.z) {
           var positionZ = this.pz.getValueAtTime(time);
           matrix.translate(positionX * this.px.mult, positionY * this.py.mult, -positionZ * this.pz.mult);
@@ -17916,42 +15141,34 @@
         var position = this.p.getValueAtTime(time);
         matrix.translate(position[0] * this.p.mult, position[1] * this.p.mult, -position[2] * this.p.mult);
       }
-
-      return matrix; /// /
+      return matrix;
+      /// /
     }
-
     function getTransformStaticValueAtTime() {
       return this.v.clone(new Matrix());
     }
-
     var getTransformProperty = TransformPropertyFactory.getTransformProperty;
-
     TransformPropertyFactory.getTransformProperty = function (elem, data, container) {
       var prop = getTransformProperty(elem, data, container);
-
       if (prop.dynamicProperties.length) {
         prop.getValueAtTime = getTransformValueAtTime.bind(prop);
       } else {
         prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop);
       }
-
       prop.setGroupProperty = expressionHelpers.setGroupProperty;
       return prop;
     };
-
     var propertyGetProp = PropertyFactory.getProp;
-
     PropertyFactory.getProp = function (elem, data, type, mult, container) {
-      var prop = propertyGetProp(elem, data, type, mult, container); // prop.getVelocityAtTime = getVelocityAtTime;
+      var prop = propertyGetProp(elem, data, type, mult, container);
+      // prop.getVelocityAtTime = getVelocityAtTime;
       // prop.loopOut = loopOut;
       // prop.loopIn = loopIn;
-
       if (prop.kf) {
         prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop);
       } else {
         prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop);
       }
-
       prop.setGroupProperty = expressionHelpers.setGroupProperty;
       prop.loopOut = loopOut;
       prop.loopIn = loopIn;
@@ -17961,25 +15178,20 @@
       prop.numKeys = data.a === 1 ? data.k.length : 0;
       prop.propertyIndex = data.ix;
       var value = 0;
-
       if (type !== 0) {
         value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length);
       }
-
       prop._cachingAtTime = {
         lastFrame: initialDefaultFrame,
         lastIndex: 0,
         value: value
       };
       expressionHelpers.searchExpressions(elem, data, prop);
-
       if (prop.k) {
         container.addDynamicProperty(prop);
       }
-
       return prop;
     };
-
     function getShapeValueAtTime(frameNum) {
       // For now this caching object is created only when needed instead of creating it when the shape is initialized.
       if (!this._cachingAtTime) {
@@ -17989,42 +15201,32 @@
           lastTime: initialDefaultFrame
         };
       }
-
       frameNum *= this.elem.globalData.frameRate;
       frameNum -= this.offsetTime;
-
       if (frameNum !== this._cachingAtTime.lastTime) {
         this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0;
         this._cachingAtTime.lastTime = frameNum;
         this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime);
       }
-
       return this._cachingAtTime.shapeValue;
     }
-
     var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction();
     var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction();
-
     function ShapeExpressions() {}
-
     ShapeExpressions.prototype = {
       vertices: function vertices(prop, time) {
         if (this.k) {
           this.getValue();
         }
-
         var shapePath = this.v;
-
         if (time !== undefined) {
           shapePath = this.getValueAtTime(time, 0);
         }
-
         var i;
         var len = shapePath._length;
         var vertices = shapePath[prop];
         var points = shapePath.v;
         var arr = createSizedArray(len);
-
         for (i = 0; i < len; i += 1) {
           if (prop === 'i' || prop === 'o') {
             arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]];
@@ -18032,7 +15234,6 @@
             arr[i] = [vertices[i][0], vertices[i][1]];
           }
         }
-
         return arr;
       },
       points: function points(time) {
@@ -18049,15 +15250,12 @@
       },
       pointOnPath: function pointOnPath(perc, time) {
         var shapePath = this.v;
-
         if (time !== undefined) {
           shapePath = this.getValueAtTime(time, 0);
         }
-
         if (!this._segmentsLength) {
           this._segmentsLength = bez.getSegmentsLength(shapePath);
         }
-
         var segmentsLength = this._segmentsLength;
         var lengths = segmentsLength.lengths;
         var lengthPos = segmentsLength.totalLength * perc;
@@ -18065,7 +15263,6 @@
         var len = lengths.length;
         var accumulatedLength = 0;
         var pt;
-
         while (i < len) {
           if (accumulatedLength + lengths[i].addedLength > lengthPos) {
             var initIndex = i;
@@ -18076,14 +15273,11 @@
           } else {
             accumulatedLength += lengths[i].addedLength;
           }
-
           i += 1;
         }
-
         if (!pt) {
           pt = shapePath.c ? [shapePath.v[0][0], shapePath.v[0][1]] : [shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1]];
         }
-
         return pt;
       },
       vectorOnPath: function vectorOnPath(perc, time, vectorType) {
@@ -18095,17 +15289,14 @@
           // eslint-disable-line eqeqeq
           perc = 0.999;
         }
-
         var pt1 = this.pointOnPath(perc, time);
         var pt2 = this.pointOnPath(perc + 0.001, time);
         var xLength = pt2[0] - pt1[0];
         var yLength = pt2[1] - pt1[1];
         var magnitude = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2));
-
         if (magnitude === 0) {
           return [0, 0];
         }
-
         var unitVector = vectorType === 'tangent' ? [xLength / magnitude, yLength / magnitude] : [-yLength / magnitude, xLength / magnitude];
         return unitVector;
       },
@@ -18123,26 +15314,21 @@
     KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime;
     KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression;
     var propertyGetShapeProp = ShapePropertyFactory.getShapeProp;
-
     ShapePropertyFactory.getShapeProp = function (elem, data, type, arr, trims) {
       var prop = propertyGetShapeProp(elem, data, type, arr, trims);
       prop.propertyIndex = data.ix;
       prop.lock = false;
-
       if (type === 3) {
         expressionHelpers.searchExpressions(elem, data.pt, prop);
       } else if (type === 4) {
         expressionHelpers.searchExpressions(elem, data.ks, prop);
       }
-
       if (prop.k) {
         elem.addDynamicProperty(prop);
       }
-
       return prop;
     };
   }
-
   function initialize$1() {
     addPropertyDecorator();
   }
@@ -18154,13 +15340,10 @@
         this.addEffect(this.getExpressionValue.bind(this));
         return true;
       }
-
       return null;
     }
-
     TextProperty.prototype.getExpressionValue = function (currentValue, text) {
       var newValue = this.calculateExpression(text);
-
       if (currentValue.t !== newValue) {
         var newData = {};
         this.copyData(newData, currentValue);
@@ -18168,26 +15351,21 @@
         newData.__complete = false;
         return newData;
       }
-
       return currentValue;
     };
-
     TextProperty.prototype.searchProperty = function () {
       var isKeyframed = this.searchKeyframes();
       var hasExpressions = this.searchExpressions();
       this.kf = isKeyframed || hasExpressions;
       return this.kf;
     };
-
     TextProperty.prototype.searchExpressions = searchExpressions;
   }
-
   function initialize() {
     addDecorator();
   }
 
   function TransformEffect() {}
-
   TransformEffect.prototype.init = function (effectsManager) {
     this.effectsManager = effectsManager;
     this.type = effectTypes.TRANSFORM_EFFECT;
@@ -18196,11 +15374,9 @@
     this._mdf = false;
     this._opMdf = false;
   };
-
   TransformEffect.prototype.renderFrame = function (forceFrame) {
     this._opMdf = false;
     this._mdf = false;
-
     if (forceFrame || this.effectsManager._mdf) {
       var effectElements = this.effectsManager.effectElements;
       var anchor = effectElements[0].p.v;
@@ -18218,7 +15394,6 @@
       this.matrix.skewFromAxis(-skew * degToRads, (skewAxis + 90) * degToRads);
       this.matrix.translate(position[0], position[1], 0);
       this._mdf = true;
-
       if (this.opacity !== effectElements[8].p.v) {
         this.opacity = effectElements[8].p.v;
         this._opMdf = true;
@@ -18229,9 +15404,9 @@
   function CVTransformEffect(effectsManager) {
     this.init(effectsManager);
   }
-
   extendPrototype([TransformEffect], CVTransformEffect);
 
+  // Registering expression plugin
   setExpressionsPlugin(Expressions);
   setExpressionInterfaces(getInterface);
   initialize$1();
diff --git a/build/player/lottie_canvas.min.js b/build/player/lottie_canvas.min.js
index eaa038d..fa75959 100644
--- a/build/player/lottie_canvas.min.js
+++ b/build/player/lottie_canvas.min.js
@@ -1 +1 @@
-"undefined"!=typeof navigator&&function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lottie=e()}(this,(function(){"use strict";var svgNS="http://www.w3.org/2000/svg",locationHref="",_useWebWorker=!1,initialDefaultFrame=-999999,setWebWorker=function(t){_useWebWorker=!!t},getWebWorker=function(){return _useWebWorker},setLocationHref=function(t){locationHref=t},getLocationHref=function(){return locationHref};function createTag(t){return document.createElement(t)}function extendPrototype(t,e){var i,r,s=t.length;for(i=0;i<s;i+=1)for(var a in r=t[i].prototype)Object.prototype.hasOwnProperty.call(r,a)&&(e.prototype[a]=r[a])}function getDescriptor(t,e){return Object.getOwnPropertyDescriptor(t,e)}function createProxyFunction(t){function e(){}return e.prototype=t,e}var audioControllerFactory=function(){function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].pause()},resume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].resume()},setRate:function(t){var e,i=this.audios.length;for(e=0;e<i;e+=1)this.audios[e].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}}(),createTypedArray=function(){function t(t,e){var i,r=0,s=[];switch(t){case"int16":case"uint8c":i=1;break;default:i=1.1}for(r=0;r<e;r+=1)s.push(i);return s}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(e,i){return"float32"===e?new Float32Array(i):"int16"===e?new Int16Array(i):"uint8c"===e?new Uint8ClampedArray(i):t(e,i)}:t}();function createSizedArray(t){return Array.apply(null,{length:t})}function _typeof$6(t){return _typeof$6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$6(t)}var subframeEnabled=!0,expressionsPlugin=null,expressionsInterfaces=null,idPrefix$1="",isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),_shouldRoundValues=!1,bmPow=Math.pow,bmSqrt=Math.sqrt,bmFloor=Math.floor,bmMax=Math.max,bmMin=Math.min,BMMath={};function ProjectInterface$1(){return{}}!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],i=e.length;for(t=0;t<i;t+=1)BMMath[e[t]]=Math[e[t]]}(),BMMath.random=Math.random,BMMath.abs=function(t){if("object"===_typeof$6(t)&&t.length){var e,i=createSizedArray(t.length),r=t.length;for(e=0;e<r;e+=1)i[e]=Math.abs(t[e]);return i}return Math.abs(t)};var defaultCurveSegments=150,degToRads=Math.PI/180,roundCorner=.5519;function roundValues(t){_shouldRoundValues=!!t}function bmRnd(t){return _shouldRoundValues?Math.round(t):t}function styleDiv(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin="0 0",t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility="visible",t.style.webkitBackfaceVisibility="visible",t.style.transformStyle="preserve-3d",t.style.webkitTransformStyle="preserve-3d",t.style.mozTransformStyle="preserve-3d"}function BMEnterFrameEvent(t,e,i,r){this.type=t,this.currentTime=e,this.totalTime=i,this.direction=r<0?-1:1}function BMCompleteEvent(t,e){this.type=t,this.direction=e<0?-1:1}function BMCompleteLoopEvent(t,e,i,r){this.type=t,this.currentLoop=i,this.totalLoops=e,this.direction=r<0?-1:1}function BMSegmentStartEvent(t,e,i){this.type=t,this.firstFrame=e,this.totalFrames=i}function BMDestroyEvent(t,e){this.type=t,this.target=e}function BMRenderFrameErrorEvent(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function BMConfigErrorEvent(t){this.type="configError",this.nativeError=t}function BMAnimationConfigErrorEvent(t,e){this.type=t,this.nativeError=e}var createElementID=(_count=0,function(){return idPrefix$1+"__lottie_element_"+(_count+=1)}),_count;function HSVtoRGB(t,e,i){var r,s,a,n,o,h,l,p;switch(h=i*(1-e),l=i*(1-(o=6*t-(n=Math.floor(6*t)))*e),p=i*(1-(1-o)*e),n%6){case 0:r=i,s=p,a=h;break;case 1:r=l,s=i,a=h;break;case 2:r=h,s=i,a=p;break;case 3:r=h,s=l,a=i;break;case 4:r=p,s=h,a=i;break;case 5:r=i,s=h,a=l}return[r,s,a]}function RGBtoHSV(t,e,i){var r,s=Math.max(t,e,i),a=Math.min(t,e,i),n=s-a,o=0===s?0:n/s,h=s/255;switch(s){case a:r=0;break;case t:r=e-i+n*(e<i?6:0),r/=6*n;break;case e:r=i-t+2*n,r/=6*n;break;case i:r=t-e+4*n,r/=6*n}return[r,o,h]}function addSaturationToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[1]+=e,i[1]>1?i[1]=1:i[1]<=0&&(i[1]=0),HSVtoRGB(i[0],i[1],i[2])}function addBrightnessToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[2]+=e,i[2]>1?i[2]=1:i[2]<0&&(i[2]=0),HSVtoRGB(i[0],i[1],i[2])}function addHueToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[0]+=e/360,i[0]>1?i[0]-=1:i[0]<0&&(i[0]+=1),HSVtoRGB(i[0],i[1],i[2])}var rgbToHex=function(){var t,e,i=[];for(t=0;t<256;t+=1)e=t.toString(16),i[t]=1===e.length?"0"+e:e;return function(t,e,r){return t<0&&(t=0),e<0&&(e=0),r<0&&(r=0),"#"+i[t]+i[e]+i[r]}}(),setSubframeEnabled=function(t){subframeEnabled=!!t},getSubframeEnabled=function(){return subframeEnabled},setExpressionsPlugin=function(t){expressionsPlugin=t},getExpressionsPlugin=function(){return expressionsPlugin},setExpressionInterfaces=function(t){expressionsInterfaces=t},getExpressionInterfaces=function(){return expressionsInterfaces},setDefaultCurveSegments=function(t){defaultCurveSegments=t},getDefaultCurveSegments=function(){return defaultCurveSegments},setIdPrefix=function(t){idPrefix$1=t},getIdPrefix=function(){return idPrefix$1};function createNS(t){return document.createElementNS(svgNS,t)}function _typeof$5(t){return _typeof$5="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$5(t)}var dataManager=function(){var t,e,i=1,r=[],s={onmessage:function(){},postMessage:function(e){t({data:e})}},a={postMessage:function(t){s.onmessage({data:t})}};function n(){e||(e=function(e){if(window.Worker&&window.Blob&&getWebWorker()){var i=new Blob(["var _workerSelf = self; self.onmessage = ",e.toString()],{type:"text/javascript"}),r=URL.createObjectURL(i);return new Worker(r)}return t=e,s}((function(t){if(a.dataManager||(a.dataManager=function(){function t(s,a){var n,o,h,l,p,c,m=s.length;for(o=0;o<m;o+=1)if("ks"in(n=s[o])&&!n.completed){if(n.completed=!0,n.hasMask){var d=n.masksProperties;for(l=d.length,h=0;h<l;h+=1)if(d[h].pt.k.i)r(d[h].pt.k);else for(c=d[h].pt.k.length,p=0;p<c;p+=1)d[h].pt.k[p].s&&r(d[h].pt.k[p].s[0]),d[h].pt.k[p].e&&r(d[h].pt.k[p].e[0])}0===n.ty?(n.layers=e(n.refId,a),t(n.layers,a)):4===n.ty?i(n.shapes):5===n.ty&&f(n)}}function e(t,e){var i=function(t,e){for(var i=0,r=e.length;i<r;){if(e[i].id===t)return e[i];i+=1}return null}(t,e);return i?i.layers.__used?JSON.parse(JSON.stringify(i.layers)):(i.layers.__used=!0,i.layers):null}function i(t){var e,s,a;for(e=t.length-1;e>=0;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)r(t[e].ks.k);else for(a=t[e].ks.k.length,s=0;s<a;s+=1)t[e].ks.k[s].s&&r(t[e].ks.k[s].s[0]),t[e].ks.k[s].e&&r(t[e].ks.k[s].e[0]);else"gr"===t[e].ty&&i(t[e].it)}function r(t){var e,i=t.i.length;for(e=0;e<i;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function s(t,e){var i=e?e.split("."):[100,100,100];return t[0]>i[0]||!(i[0]>t[0])&&(t[1]>i[1]||!(i[1]>t[1])&&(t[2]>i[2]||!(i[2]>t[2])&&null))}var a,n=function(){var t=[4,4,14];function e(t){var e,i,r,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(r=void 0,r=(i=t[e]).t.d,i.t.d={k:[{s:r,t:0}]})}return function(i){if(s(t,i.v)&&(e(i.layers),i.assets)){var r,a=i.assets.length;for(r=0;r<a;r+=1)i.assets[r].layers&&e(i.assets[r].layers)}}}(),o=(a=[4,7,99],function(t){if(t.chars&&!s(a,t.v)){var e,r=t.chars.length;for(e=0;e<r;e+=1){var n=t.chars[e];n.data&&n.data.shapes&&(i(n.data.shapes),n.data.ip=0,n.data.op=99999,n.data.st=0,n.data.sr=1,n.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[e].t||(n.data.shapes.push({ty:"no"}),n.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}}}),h=function(){var t=[5,7,15];function e(t){var e,i,r=t.length;for(e=0;e<r;e+=1)5===t[e].ty&&(i=void 0,"number"==typeof(i=t[e].t.p).a&&(i.a={a:0,k:i.a}),"number"==typeof i.p&&(i.p={a:0,k:i.p}),"number"==typeof i.r&&(i.r={a:0,k:i.r}))}return function(i){if(s(t,i.v)&&(e(i.layers),i.assets)){var r,a=i.assets.length;for(r=0;r<a;r+=1)i.assets[r].layers&&e(i.assets[r].layers)}}}(),l=function(){var t=[4,1,9];function e(t){var i,r,s,a=t.length;for(i=0;i<a;i+=1)if("gr"===t[i].ty)e(t[i].it);else if("fl"===t[i].ty||"st"===t[i].ty)if(t[i].c.k&&t[i].c.k[0].i)for(s=t[i].c.k.length,r=0;r<s;r+=1)t[i].c.k[r].s&&(t[i].c.k[r].s[0]/=255,t[i].c.k[r].s[1]/=255,t[i].c.k[r].s[2]/=255,t[i].c.k[r].s[3]/=255),t[i].c.k[r].e&&(t[i].c.k[r].e[0]/=255,t[i].c.k[r].e[1]/=255,t[i].c.k[r].e[2]/=255,t[i].c.k[r].e[3]/=255);else t[i].c.k[0]/=255,t[i].c.k[1]/=255,t[i].c.k[2]/=255,t[i].c.k[3]/=255}function i(t){var i,r=t.length;for(i=0;i<r;i+=1)4===t[i].ty&&e(t[i].shapes)}return function(e){if(s(t,e.v)&&(i(e.layers),e.assets)){var r,a=e.assets.length;for(r=0;r<a;r+=1)e.assets[r].layers&&i(e.assets[r].layers)}}}(),p=function(){var t=[4,4,18];function e(t){var i,r,s;for(i=t.length-1;i>=0;i-=1)if("sh"===t[i].ty)if(t[i].ks.k.i)t[i].ks.k.c=t[i].closed;else for(s=t[i].ks.k.length,r=0;r<s;r+=1)t[i].ks.k[r].s&&(t[i].ks.k[r].s[0].c=t[i].closed),t[i].ks.k[r].e&&(t[i].ks.k[r].e[0].c=t[i].closed);else"gr"===t[i].ty&&e(t[i].it)}function i(t){var i,r,s,a,n,o,h=t.length;for(r=0;r<h;r+=1){if((i=t[r]).hasMask){var l=i.masksProperties;for(a=l.length,s=0;s<a;s+=1)if(l[s].pt.k.i)l[s].pt.k.c=l[s].cl;else for(o=l[s].pt.k.length,n=0;n<o;n+=1)l[s].pt.k[n].s&&(l[s].pt.k[n].s[0].c=l[s].cl),l[s].pt.k[n].e&&(l[s].pt.k[n].e[0].c=l[s].cl)}4===i.ty&&e(i.shapes)}}return function(e){if(s(t,e.v)&&(i(e.layers),e.assets)){var r,a=e.assets.length;for(r=0;r<a;r+=1)e.assets[r].layers&&i(e.assets[r].layers)}}}();function f(t){0===t.t.a.length&&t.t.p}var c={completeData:function(i){i.__complete||(l(i),n(i),o(i),h(i),p(i),t(i.layers,i.assets),function(i,r){if(i){var s=0,a=i.length;for(s=0;s<a;s+=1)1===i[s].t&&(i[s].data.layers=e(i[s].data.refId,r),t(i[s].data.layers,r))}}(i.chars,i.assets),i.__complete=!0)}};return c.checkColors=l,c.checkChars=o,c.checkPathProperties=h,c.checkShapes=p,c.completeLayers=t,c}()),a.assetLoader||(a.assetLoader=function(){function t(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")||t.response&&"object"===_typeof$5(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}return{load:function(e,i,r,s){var a,n=new XMLHttpRequest;try{n.responseType="json"}catch(t){}n.onreadystatechange=function(){if(4===n.readyState)if(200===n.status)a=t(n),r(a);else try{a=t(n),r(a)}catch(t){s&&s(t)}};try{n.open(["G","E","T"].join(""),e,!0)}catch(t){n.open(["G","E","T"].join(""),i+"/"+e,!0)}n.send()}}}()),"loadAnimation"===t.data.type)a.assetLoader.load(t.data.path,t.data.fullPath,(function(e){a.dataManager.completeData(e),a.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){a.postMessage({id:t.data.id,status:"error"})}));else if("complete"===t.data.type){var e=t.data.animation;a.dataManager.completeData(e),a.postMessage({id:t.data.id,payload:e,status:"success"})}else"loadData"===t.data.type&&a.assetLoader.load(t.data.path,t.data.fullPath,(function(e){a.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){a.postMessage({id:t.data.id,status:"error"})}))})),e.onmessage=function(t){var e=t.data,i=e.id,s=r[i];r[i]=null,"success"===e.status?s.onComplete(e.payload):s.onError&&s.onError()})}function o(t,e){var s="processId_"+(i+=1);return r[s]={onComplete:t,onError:e},s}return{loadAnimation:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:s})},loadData:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:s})},completeAnimation:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"complete",animation:t,id:s})}}}(),ImagePreloader=function(){var t=function(){var t=createTag("canvas");t.width=1,t.height=1;var e=t.getContext("2d");return e.fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1),t}();function e(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function i(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function r(t,e,i){var r="";if(t.e)r=t.p;else if(e){var s=t.p;-1!==s.indexOf("images/")&&(s=s.split("/")[1]),r=e+s}else r=i,r+=t.u?t.u:"",r+=t.p;return r}function s(t){var e=0,i=setInterval(function(){(t.getBBox().width||e>500)&&(this._imageLoaded(),clearInterval(i)),e+=1}.bind(this),50)}function a(t){var e={assetData:t},i=r(t,this.assetsPath,this.path);return dataManager.loadData(i,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}function n(){this._imageLoaded=e.bind(this),this._footageLoaded=i.bind(this),this.testImageLoaded=s.bind(this),this.createFootageData=a.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return n.prototype={loadAssets:function(t,e){var i;this.imagesLoadedCb=e;var r=t.length;for(i=0;i<r;i+=1)t[i].layers||(t[i].t&&"seq"!==t[i].t?3===t[i].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[i]))):(this.totalImages+=1,this.images.push(this._createImageData(t[i]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,i=this.images.length;e<i;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(e){var i=r(e,this.assetsPath,this.path),s=createTag("img");s.crossOrigin="anonymous",s.addEventListener("load",this._imageLoaded,!1),s.addEventListener("error",function(){a.img=t,this._imageLoaded()}.bind(this),!1),s.src=i;var a={img:s,assetData:e};return a},createImageData:function(e){var i=r(e,this.assetsPath,this.path),s=createNS("image");isSafari?this.testImageLoaded(s):s.addEventListener("load",this._imageLoaded,!1),s.addEventListener("error",function(){a.img=t,this._imageLoaded()}.bind(this),!1),s.setAttributeNS("http://www.w3.org/1999/xlink","href",i),this._elementHelper.append?this._elementHelper.append(s):this._elementHelper.appendChild(s);var a={img:s,assetData:e};return a},imageLoaded:e,footageLoaded:i,setCacheType:function(t,e){"svg"===t?(this._elementHelper=e,this._createImageData=this.createImageData.bind(this)):this._createImageData=this.createImgData.bind(this)}},n}();function BaseEvent(){}BaseEvent.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var i=this._cbs[t],r=0;r<i.length;r+=1)i[r](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var i=0,r=this._cbs[t].length;i<r;)this._cbs[t][i]===e&&(this._cbs[t].splice(i,1),i-=1,r-=1),i+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var markerParser=function(){function t(t){for(var e,i=t.split("\r\n"),r={},s=0,a=0;a<i.length;a+=1)2===(e=i[a].split(":")).length&&(r[e[0]]=e[1].trim(),s+=1);if(0===s)throw new Error;return r}return function(e){for(var i=[],r=0;r<e.length;r+=1){var s=e[r],a={time:s.tm,duration:s.dr};try{a.payload=JSON.parse(e[r].cm)}catch(i){try{a.payload=t(e[r].cm)}catch(t){a.payload={name:e[r].cm}}}i.push(a)}return i}}(),ProjectInterface=function(){function t(t){this.compositions.push(t)}return function(){function e(t){for(var e=0,i=this.compositions.length;e<i;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return e.compositions=[],e.currentFrame=0,e.registerComposition=t,e}}(),renderers={},registerRenderer=function(t,e){renderers[t]=e};function getRenderer(t){return renderers[t]}function getRegisteredRenderer(){if(renderers.canvas)return"canvas";for(var t in renderers)if(renderers[t])return t;return""}function _typeof$4(t){return _typeof$4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$4(t)}var AnimationItem=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=createElementID(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=getSubframeEnabled(),this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=ProjectInterface(),this.imagePreloader=new ImagePreloader,this.audioController=audioControllerFactory(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new BMEnterFrameEvent("drawnFrame",0,0,0),this.expressionsPlugin=getExpressionsPlugin()};extendPrototype([BaseEvent],AnimationItem),AnimationItem.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg";t.animType?e=t.animType:t.renderer&&(e=t.renderer);var i=getRenderer(e);this.renderer=new i(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||void 0===t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),dataManager.loadAnimation(t.path,this.configAnimation,this.onSetupError))},AnimationItem.prototype.onSetupError=function(){this.trigger("data_failed")},AnimationItem.prototype.setupAnimation=function(t){dataManager.completeAnimation(t,this.configAnimation)},AnimationItem.prototype.setData=function(t,e){e&&"object"!==_typeof$4(e)&&(e=JSON.parse(e));var i={wrapper:t,animationData:e},r=t.attributes;i.path=r.getNamedItem("data-animation-path")?r.getNamedItem("data-animation-path").value:r.getNamedItem("data-bm-path")?r.getNamedItem("data-bm-path").value:r.getNamedItem("bm-path")?r.getNamedItem("bm-path").value:"",i.animType=r.getNamedItem("data-anim-type")?r.getNamedItem("data-anim-type").value:r.getNamedItem("data-bm-type")?r.getNamedItem("data-bm-type").value:r.getNamedItem("bm-type")?r.getNamedItem("bm-type").value:r.getNamedItem("data-bm-renderer")?r.getNamedItem("data-bm-renderer").value:r.getNamedItem("bm-renderer")?r.getNamedItem("bm-renderer").value:getRegisteredRenderer()||"canvas";var s=r.getNamedItem("data-anim-loop")?r.getNamedItem("data-anim-loop").value:r.getNamedItem("data-bm-loop")?r.getNamedItem("data-bm-loop").value:r.getNamedItem("bm-loop")?r.getNamedItem("bm-loop").value:"";"false"===s?i.loop=!1:"true"===s?i.loop=!0:""!==s&&(i.loop=parseInt(s,10));var a=r.getNamedItem("data-anim-autoplay")?r.getNamedItem("data-anim-autoplay").value:r.getNamedItem("data-bm-autoplay")?r.getNamedItem("data-bm-autoplay").value:!r.getNamedItem("bm-autoplay")||r.getNamedItem("bm-autoplay").value;i.autoplay="false"!==a,i.name=r.getNamedItem("data-name")?r.getNamedItem("data-name").value:r.getNamedItem("data-bm-name")?r.getNamedItem("data-bm-name").value:r.getNamedItem("bm-name")?r.getNamedItem("bm-name").value:"","false"===(r.getNamedItem("data-anim-prerender")?r.getNamedItem("data-anim-prerender").value:r.getNamedItem("data-bm-prerender")?r.getNamedItem("data-bm-prerender").value:r.getNamedItem("bm-prerender")?r.getNamedItem("bm-prerender").value:"")&&(i.prerender=!1),i.path?this.setParams(i):this.trigger("destroy")},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,i,r=this.animationData.layers,s=r.length,a=t.layers,n=a.length;for(i=0;i<n;i+=1)for(e=0;e<s;){if(r[e].id===a[i].id){r[e]=a[i];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(s=t.assets.length,e=0;e<s;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,dataManager.completeAnimation(this.animationData,this.onSegmentComplete)},AnimationItem.prototype.onSegmentComplete=function(t){this.animationData=t;var e=getExpressionsPlugin();e&&e.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var i=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,dataManager.loadData(i,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},AnimationItem.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},AnimationItem.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=markerParser(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},AnimationItem.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},AnimationItem.prototype.checkLoaded=function(){if(!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()){this.isLoaded=!0;var t=getExpressionsPlugin();t&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play()}},AnimationItem.prototype.resize=function(t,e){var i="number"==typeof t?t:void 0,r="number"==typeof e?e:void 0;this.renderer.updateContainerSize(i,r)},AnimationItem.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},AnimationItem.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},AnimationItem.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},AnimationItem.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},AnimationItem.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.getMarkerData=function(t){for(var e,i=0;i<this.markers.length;i+=1)if((e=this.markers[i]).payload&&e.payload.name===t)return e;return null},AnimationItem.prototype.goToAndStop=function(t,e,i){if(!i||this.name===i){var r=Number(t);if(isNaN(r)){var s=this.getMarkerData(t);s&&this.goToAndStop(s.time,!0)}else e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier);this.pause()}},AnimationItem.prototype.goToAndPlay=function(t,e,i){if(!i||this.name===i){var r=Number(t);if(isNaN(r)){var s=this.getMarkerData(t);s&&(s.duration?this.playSegments([s.time,s.time+s.duration],!0):this.goToAndStop(s.time,!0))}else this.goToAndStop(r,e,i);this.play()}},AnimationItem.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,i=!1;e>=this.totalFrames-1&&this.frameModifier>0?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(i=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(i=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),i&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(this.frameModifier>0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var i=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?i=t:this.currentRawFrame+this.firstFrame>e&&(i=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==i&&this.goToAndStop(i,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===_typeof$4(t[0])){var i,r=t.length;for(i=0;i<r;i+=1)this.segments.push(t[i])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},AnimationItem.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},AnimationItem.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},AnimationItem.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},AnimationItem.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},AnimationItem.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},AnimationItem.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},AnimationItem.prototype.setLoop=function(t){this.loop=t},AnimationItem.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},AnimationItem.prototype.getVolume=function(){return this.audioController.getVolume()},AnimationItem.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},AnimationItem.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},AnimationItem.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},AnimationItem.prototype.getPath=function(){return this.path},AnimationItem.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var i=t.p;-1!==i.indexOf("images/")&&(i=i.split("/")[1]),e=this.assetsPath+i}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},AnimationItem.prototype.getAssetData=function(t){for(var e=0,i=this.assets.length;e<i;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},AnimationItem.prototype.hide=function(){this.renderer.hide()},AnimationItem.prototype.show=function(){this.renderer.show()},AnimationItem.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},AnimationItem.prototype.updateDocumentData=function(t,e,i){try{this.renderer.getElementByPath(t).updateDocumentData(e,i)}catch(t){}},AnimationItem.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new BMCompleteEvent(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new BMDestroyEvent(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new BMCompleteEvent(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new BMDestroyEvent(t,this))},AnimationItem.prototype.triggerRenderFrameError=function(t){var e=new BMRenderFrameErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)},AnimationItem.prototype.triggerConfigError=function(t){var e=new BMConfigErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)};var animationManager=function(){var t={},e=[],i=0,r=0,s=0,a=!0,n=!1;function o(t){for(var i=0,s=t.target;i<r;)e[i].animation===s&&(e.splice(i,1),i-=1,r-=1,s.isPaused||p()),i+=1}function h(t,i){if(!t)return null;for(var s=0;s<r;){if(e[s].elem===t&&null!==e[s].elem)return e[s].animation;s+=1}var a=new AnimationItem;return f(a,t),a.setData(t,i),a}function l(){s+=1,d()}function p(){s-=1}function f(t,i){t.addEventListener("destroy",o),t.addEventListener("_active",l),t.addEventListener("_idle",p),e.push({elem:i,animation:t}),r+=1}function c(t){var o,h=t-i;for(o=0;o<r;o+=1)e[o].animation.advanceTime(h);i=t,s&&!n?window.requestAnimationFrame(c):a=!0}function m(t){i=t,window.requestAnimationFrame(c)}function d(){!n&&s&&a&&(window.requestAnimationFrame(m),a=!1)}return t.registerAnimation=h,t.loadAnimation=function(t){var e=new AnimationItem;return f(e,null),e.setParams(t),e},t.setSpeed=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setSpeed(t,i)},t.setDirection=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setDirection(t,i)},t.play=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.play(t)},t.pause=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.pause(t)},t.stop=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.stop(t)},t.togglePause=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.togglePause(t)},t.searchAnimations=function(t,e,i){var r,s=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),a=s.length;for(r=0;r<a;r+=1)i&&s[r].setAttribute("data-bm-type",i),h(s[r],t);if(e&&0===a){i||(i="svg");var n=document.getElementsByTagName("body")[0];n.innerText="";var o=createTag("div");o.style.width="100%",o.style.height="100%",o.setAttribute("data-bm-type",i),n.appendChild(o),h(o,t)}},t.resize=function(){var t;for(t=0;t<r;t+=1)e[t].animation.resize()},t.goToAndStop=function(t,i,s){var a;for(a=0;a<r;a+=1)e[a].animation.goToAndStop(t,i,s)},t.destroy=function(t){var i;for(i=r-1;i>=0;i-=1)e[i].animation.destroy(t)},t.freeze=function(){n=!0},t.unfreeze=function(){n=!1,d()},t.setVolume=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setVolume(t,i)},t.mute=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.mute(t)},t.unmute=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.unmute(t)},t.getRegisteredAnimations=function(){var t,i=e.length,r=[];for(t=0;t<i;t+=1)r.push(e[t].animation);return r},t}(),BezierFactory=function(){var t={getBezierEasing:function(t,i,r,s,a){var n=a||("bez_"+t+"_"+i+"_"+r+"_"+s).replace(/\./g,"p");if(e[n])return e[n];var o=new l([t,i,r,s]);return e[n]=o,o}},e={};var i=.1,r="function"==typeof Float32Array;function s(t,e){return 1-3*e+3*t}function a(t,e){return 3*e-6*t}function n(t){return 3*t}function o(t,e,i){return((s(e,i)*t+a(e,i))*t+n(e))*t}function h(t,e,i){return 3*s(e,i)*t*t+2*a(e,i)*t+n(e)}function l(t){this._p=t,this._mSampleValues=r?new Float32Array(11):new Array(11),this._precomputed=!1,this.get=this.get.bind(this)}return l.prototype={get:function(t){var e=this._p[0],i=this._p[1],r=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===i&&r===s?t:0===t?0:1===t?1:o(this._getTForX(t),i,s)},_precompute:function(){var t=this._p[0],e=this._p[1],i=this._p[2],r=this._p[3];this._precomputed=!0,t===e&&i===r||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],r=0;r<11;++r)this._mSampleValues[r]=o(r*i,t,e)},_getTForX:function(t){for(var e=this._p[0],r=this._p[2],s=this._mSampleValues,a=0,n=1;10!==n&&s[n]<=t;++n)a+=i;var l=a+(t-s[--n])/(s[n+1]-s[n])*i,p=h(l,e,r);return p>=.001?function(t,e,i,r){for(var s=0;s<4;++s){var a=h(e,i,r);if(0===a)return e;e-=(o(e,i,r)-t)/a}return e}(t,l,e,r):0===p?l:function(t,e,i,r,s){var a,n,h=0;do{(a=o(n=e+(i-e)/2,r,s)-t)>0?i=n:e=n}while(Math.abs(a)>1e-7&&++h<10);return n}(t,a,a+i,e,r)}},t}(),pooling={double:function(t){return t.concat(createSizedArray(t.length))}},poolFactory=function(t,e,i){var r=0,s=t,a=createSizedArray(s);return{newElement:function(){return r?a[r-=1]:e()},release:function(t){r===s&&(a=pooling.double(a),s*=2),i&&i(t),a[r]=t,r+=1}}},bezierLengthPool=poolFactory(8,(function(){return{addedLength:0,percents:createTypedArray("float32",getDefaultCurveSegments()),lengths:createTypedArray("float32",getDefaultCurveSegments())}})),segmentsLengthPool=poolFactory(8,(function(){return{lengths:[],totalLength:0}}),(function(t){var e,i=t.lengths.length;for(e=0;e<i;e+=1)bezierLengthPool.release(t.lengths[e]);t.lengths.length=0}));function bezFunction(){var t=Math;function e(t,e,i,r,s,a){var n=t*r+e*s+i*a-s*r-a*t-i*e;return n>-.001&&n<.001}var i=function(t,e,i,r){var s,a,n,o,h,l,p=getDefaultCurveSegments(),f=0,c=[],m=[],d=bezierLengthPool.newElement();for(n=i.length,s=0;s<p;s+=1){for(h=s/(p-1),l=0,a=0;a<n;a+=1)o=bmPow(1-h,3)*t[a]+3*bmPow(1-h,2)*h*i[a]+3*(1-h)*bmPow(h,2)*r[a]+bmPow(h,3)*e[a],c[a]=o,null!==m[a]&&(l+=bmPow(c[a]-m[a],2)),m[a]=c[a];l&&(f+=l=bmSqrt(l)),d.percents[s]=h,d.lengths[s]=f}return d.addedLength=f,d};function r(t){this.segmentLength=0,this.points=new Array(t)}function s(t,e){this.partialLength=t,this.point=e}var a,n=(a={},function(t,i,n,o){var h=(t[0]+"_"+t[1]+"_"+i[0]+"_"+i[1]+"_"+n[0]+"_"+n[1]+"_"+o[0]+"_"+o[1]).replace(/\./g,"p");if(!a[h]){var l,p,f,c,m,d,u,y=getDefaultCurveSegments(),g=0,v=null;2===t.length&&(t[0]!==i[0]||t[1]!==i[1])&&e(t[0],t[1],i[0],i[1],t[0]+n[0],t[1]+n[1])&&e(t[0],t[1],i[0],i[1],i[0]+o[0],i[1]+o[1])&&(y=2);var P=new r(y);for(f=n.length,l=0;l<y;l+=1){for(u=createSizedArray(f),m=l/(y-1),d=0,p=0;p<f;p+=1)c=bmPow(1-m,3)*t[p]+3*bmPow(1-m,2)*m*(t[p]+n[p])+3*(1-m)*bmPow(m,2)*(i[p]+o[p])+bmPow(m,3)*i[p],u[p]=c,null!==v&&(d+=bmPow(u[p]-v[p],2));g+=d=bmSqrt(d),P.points[l]=new s(d,u),v=u}P.segmentLength=g,a[h]=P}return a[h]});function o(t,e){var i=e.percents,r=e.lengths,s=i.length,a=bmFloor((s-1)*t),n=t*e.addedLength,o=0;if(a===s-1||0===a||n===r[a])return i[a];for(var h=r[a]>n?-1:1,l=!0;l;)if(r[a]<=n&&r[a+1]>n?(o=(n-r[a])/(r[a+1]-r[a]),l=!1):a+=h,a<0||a>=s-1){if(a===s-1)return i[a];l=!1}return i[a]+(i[a+1]-i[a])*o}var h=createTypedArray("float32",8);return{getSegmentsLength:function(t){var e,r=segmentsLengthPool.newElement(),s=t.c,a=t.v,n=t.o,o=t.i,h=t._length,l=r.lengths,p=0;for(e=0;e<h-1;e+=1)l[e]=i(a[e],a[e+1],n[e],o[e+1]),p+=l[e].addedLength;return s&&h&&(l[e]=i(a[e],a[0],n[e],o[0]),p+=l[e].addedLength),r.totalLength=p,r},getNewSegment:function(e,i,r,s,a,n,l){a<0?a=0:a>1&&(a=1);var p,f=o(a,l),c=o(n=n>1?1:n,l),m=e.length,d=1-f,u=1-c,y=d*d*d,g=f*d*d*3,v=f*f*d*3,P=f*f*f,b=d*d*u,x=f*d*u+d*f*u+d*d*c,S=f*f*u+d*f*c+f*d*c,C=f*f*c,E=d*u*u,_=f*u*u+d*c*u+d*u*c,T=f*c*u+d*c*c+f*u*c,A=f*c*c,D=u*u*u,k=c*u*u+u*c*u+u*u*c,M=c*c*u+u*c*c+c*u*c,I=c*c*c;for(p=0;p<m;p+=1)h[4*p]=t.round(1e3*(y*e[p]+g*r[p]+v*s[p]+P*i[p]))/1e3,h[4*p+1]=t.round(1e3*(b*e[p]+x*r[p]+S*s[p]+C*i[p]))/1e3,h[4*p+2]=t.round(1e3*(E*e[p]+_*r[p]+T*s[p]+A*i[p]))/1e3,h[4*p+3]=t.round(1e3*(D*e[p]+k*r[p]+M*s[p]+I*i[p]))/1e3;return h},getPointInSegment:function(e,i,r,s,a,n){var h=o(a,n),l=1-h;return[t.round(1e3*(l*l*l*e[0]+(h*l*l+l*h*l+l*l*h)*r[0]+(h*h*l+l*h*h+h*l*h)*s[0]+h*h*h*i[0]))/1e3,t.round(1e3*(l*l*l*e[1]+(h*l*l+l*h*l+l*l*h)*r[1]+(h*h*l+l*h*h+h*l*h)*s[1]+h*h*h*i[1]))/1e3]},buildBezierData:n,pointOnLine2D:e,pointOnLine3D:function(i,r,s,a,n,o,h,l,p){if(0===s&&0===o&&0===p)return e(i,r,a,n,h,l);var f,c=t.sqrt(t.pow(a-i,2)+t.pow(n-r,2)+t.pow(o-s,2)),m=t.sqrt(t.pow(h-i,2)+t.pow(l-r,2)+t.pow(p-s,2)),d=t.sqrt(t.pow(h-a,2)+t.pow(l-n,2)+t.pow(p-o,2));return(f=c>m?c>d?c-m-d:d-m-c:d>m?d-m-c:m-c-d)>-1e-4&&f<1e-4}}}var bez=bezFunction(),initFrame=initialDefaultFrame,mathAbs=Math.abs;function interpolateValue(t,e){var i,r=this.offsetTime;"multidimensional"===this.propType&&(i=createTypedArray("float32",this.pv.length));for(var s,a,n,o,h,l,p,f,c,m=e.lastIndex,d=m,u=this.keyframes.length-1,y=!0;y;){if(s=this.keyframes[d],a=this.keyframes[d+1],d===u-1&&t>=a.t-r){s.h&&(s=a),m=0;break}if(a.t-r>t){m=d;break}d<u-1?d+=1:(m=0,y=!1)}n=this.keyframesMetadata[d]||{};var g,v=a.t-r,P=s.t-r;if(s.to){n.bezierData||(n.bezierData=bez.buildBezierData(s.s,a.s||s.e,s.to,s.ti));var b=n.bezierData;if(t>=v||t<P){var x=t>=v?b.points.length-1:0;for(h=b.points[x].point.length,o=0;o<h;o+=1)i[o]=b.points[x].point[o]}else{n.__fnct?c=n.__fnct:(c=BezierFactory.getBezierEasing(s.o.x,s.o.y,s.i.x,s.i.y,s.n).get,n.__fnct=c),l=c((t-P)/(v-P));var S,C=b.segmentLength*l,E=e.lastFrame<t&&e._lastKeyframeIndex===d?e._lastAddedLength:0;for(f=e.lastFrame<t&&e._lastKeyframeIndex===d?e._lastPoint:0,y=!0,p=b.points.length;y;){if(E+=b.points[f].partialLength,0===C||0===l||f===b.points.length-1){for(h=b.points[f].point.length,o=0;o<h;o+=1)i[o]=b.points[f].point[o];break}if(C>=E&&C<E+b.points[f+1].partialLength){for(S=(C-E)/b.points[f+1].partialLength,h=b.points[f].point.length,o=0;o<h;o+=1)i[o]=b.points[f].point[o]+(b.points[f+1].point[o]-b.points[f].point[o])*S;break}f<p-1?f+=1:y=!1}e._lastPoint=f,e._lastAddedLength=E-b.points[f].partialLength,e._lastKeyframeIndex=d}}else{var _,T,A,D,k;if(u=s.s.length,g=a.s||s.e,this.sh&&1!==s.h)if(t>=v)i[0]=g[0],i[1]=g[1],i[2]=g[2];else if(t<=P)i[0]=s.s[0],i[1]=s.s[1],i[2]=s.s[2];else{quaternionToEuler(i,slerp(createQuaternion(s.s),createQuaternion(g),(t-P)/(v-P)))}else for(d=0;d<u;d+=1)1!==s.h&&(t>=v?l=1:t<P?l=0:(s.o.x.constructor===Array?(n.__fnct||(n.__fnct=[]),n.__fnct[d]?c=n.__fnct[d]:(_=void 0===s.o.x[d]?s.o.x[0]:s.o.x[d],T=void 0===s.o.y[d]?s.o.y[0]:s.o.y[d],A=void 0===s.i.x[d]?s.i.x[0]:s.i.x[d],D=void 0===s.i.y[d]?s.i.y[0]:s.i.y[d],c=BezierFactory.getBezierEasing(_,T,A,D).get,n.__fnct[d]=c)):n.__fnct?c=n.__fnct:(_=s.o.x,T=s.o.y,A=s.i.x,D=s.i.y,c=BezierFactory.getBezierEasing(_,T,A,D).get,s.keyframeMetadata=c),l=c((t-P)/(v-P)))),g=a.s||s.e,k=1===s.h?s.s[d]:s.s[d]+(g[d]-s.s[d])*l,"multidimensional"===this.propType?i[d]=k:i=k}return e.lastIndex=m,i}function slerp(t,e,i){var r,s,a,n,o,h=[],l=t[0],p=t[1],f=t[2],c=t[3],m=e[0],d=e[1],u=e[2],y=e[3];return(s=l*m+p*d+f*u+c*y)<0&&(s=-s,m=-m,d=-d,u=-u,y=-y),1-s>1e-6?(r=Math.acos(s),a=Math.sin(r),n=Math.sin((1-i)*r)/a,o=Math.sin(i*r)/a):(n=1-i,o=i),h[0]=n*l+o*m,h[1]=n*p+o*d,h[2]=n*f+o*u,h[3]=n*c+o*y,h}function quaternionToEuler(t,e){var i=e[0],r=e[1],s=e[2],a=e[3],n=Math.atan2(2*r*a-2*i*s,1-2*r*r-2*s*s),o=Math.asin(2*i*r+2*s*a),h=Math.atan2(2*i*a-2*r*s,1-2*i*i-2*s*s);t[0]=n/degToRads,t[1]=o/degToRads,t[2]=h/degToRads}function createQuaternion(t){var e=t[0]*degToRads,i=t[1]*degToRads,r=t[2]*degToRads,s=Math.cos(e/2),a=Math.cos(i/2),n=Math.cos(r/2),o=Math.sin(e/2),h=Math.sin(i/2),l=Math.sin(r/2);return[o*h*n+s*a*l,o*a*n+s*h*l,s*h*n-o*a*l,s*a*n-o*h*l]}function getValueAtCurrentTime(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==initFrame&&(this._caching.lastFrame>=i&&t>=i||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var r=this.interpolateValue(t,this._caching);this.pv=r}return this._caching.lastFrame=t,this.pv}function setVValue(t){var e;if("unidimensional"===this.propType)e=t*this.mult,mathAbs(this.v-e)>1e-5&&(this.v=e,this._mdf=!0);else for(var i=0,r=this.v.length;i<r;)e=t[i]*this.mult,mathAbs(this.v[i]-e)>1e-5&&(this.v[i]=e,this._mdf=!0),i+=1}function processEffectsSequence(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t;this.lock=!0,this._mdf=this._isFirstFrame;var e=this.effectsSequence.length,i=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)i=this.effectsSequence[t](i);this.setVValue(i),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function addEffect(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function ValueProperty(t,e,i,r){this.propType="unidimensional",this.mult=i||1,this.data=e,this.v=i?e.k*i:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function MultiDimensionalProperty(t,e,i,r){var s;this.propType="multidimensional",this.mult=i||1,this.data=e,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var a=e.k.length;for(this.v=createTypedArray("float32",a),this.pv=createTypedArray("float32",a),this.vel=createTypedArray("float32",a),s=0;s<a;s+=1)this.v[s]=e.k[s]*this.mult,this.pv[s]=e.k[s];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function KeyframedValueProperty(t,e,i,r){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:initFrame,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.v=initFrame,this.pv=initFrame,this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.addEffect=addEffect}function KeyframedMultidimensionalProperty(t,e,i,r){var s;this.propType="multidimensional";var a,n,o,h,l=e.k.length;for(s=0;s<l-1;s+=1)e.k[s].to&&e.k[s].s&&e.k[s+1]&&e.k[s+1].s&&(a=e.k[s].s,n=e.k[s+1].s,o=e.k[s].to,h=e.k[s].ti,(2===a.length&&(a[0]!==n[0]||a[1]!==n[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],a[0]+o[0],a[1]+o[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],n[0]+h[0],n[1]+h[1])||3===a.length&&(a[0]!==n[0]||a[1]!==n[1]||a[2]!==n[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],a[0]+o[0],a[1]+o[1],a[2]+o[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],n[0]+h[0],n[1]+h[1],n[2]+h[2]))&&(e.k[s].to=null,e.k[s].ti=null),a[0]===n[0]&&a[1]===n[1]&&0===o[0]&&0===o[1]&&0===h[0]&&0===h[1]&&(2===a.length||a[2]===n[2]&&0===o[2]&&0===h[2])&&(e.k[s].to=null,e.k[s].ti=null));this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.frameId=-1;var p=e.k[0].s.length;for(this.v=createTypedArray("float32",p),this.pv=createTypedArray("float32",p),s=0;s<p;s+=1)this.v[s]=initFrame,this.pv[s]=initFrame;this._caching={lastFrame:initFrame,lastIndex:0,value:createTypedArray("float32",p)},this.addEffect=addEffect}var PropertyFactory={getProp:function(t,e,i,r,s){var a;if(e.sid&&(e=t.globalData.slotManager.getProp(e)),e.k.length)if("number"==typeof e.k[0])a=new MultiDimensionalProperty(t,e,r,s);else switch(i){case 0:a=new KeyframedValueProperty(t,e,r,s);break;case 1:a=new KeyframedMultidimensionalProperty(t,e,r,s)}else a=new ValueProperty(t,e,r,s);return a.effectsSequence.length&&s.addDynamicProperty(a),a}};function DynamicPropertyContainer(){}DynamicPropertyContainer.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){var t;this._mdf=!1;var e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var pointPool=poolFactory(8,(function(){return createTypedArray("float32",2)}));function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var i=0;i<e;)this.v[i]=pointPool.newElement(),this.o[i]=pointPool.newElement(),this.i[i]=pointPool.newElement(),i+=1},ShapePath.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},ShapePath.prototype.doubleArrayLength=function(){this.v=this.v.concat(createSizedArray(this._maxLength)),this.i=this.i.concat(createSizedArray(this._maxLength)),this.o=this.o.concat(createSizedArray(this._maxLength)),this._maxLength*=2},ShapePath.prototype.setXYAt=function(t,e,i,r,s){var a;switch(this._length=Math.max(this._length,r+1),this._length>=this._maxLength&&this.doubleArrayLength(),i){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o;break;default:a=[]}(!a[r]||a[r]&&!s)&&(a[r]=pointPool.newElement()),a[r][0]=t,a[r][1]=e},ShapePath.prototype.setTripleAt=function(t,e,i,r,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(i,r,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t=new ShapePath;t.setPathData(this.c,this._length);var e=this.v,i=this.o,r=this.i,s=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],r[0][0],r[0][1],i[0][0],i[0][1],0,!1),s=1);var a,n=this._length-1,o=this._length;for(a=s;a<o;a+=1)t.setTripleAt(e[n][0],e[n][1],r[n][0],r[n][1],i[n][0],i[n][1],a,!1),n-=1;return t},ShapePath.prototype.length=function(){return this._length};var shapePool=(factory=poolFactory(4,(function(){return new ShapePath}),(function(t){var e,i=t._length;for(e=0;e<i;e+=1)pointPool.release(t.v[e]),pointPool.release(t.i[e]),pointPool.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1})),factory.clone=function(t){var e,i=factory.newElement(),r=void 0===t._length?t.v.length:t._length;for(i.setLength(r),i.c=t.c,e=0;e<r;e+=1)i.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return i},factory),factory;function ShapeCollection(){this._length=0,this._maxLength=4,this.shapes=createSizedArray(this._maxLength)}ShapeCollection.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(createSizedArray(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},ShapeCollection.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)shapePool.release(this.shapes[t]);this._length=0};var shapeCollectionPool=(ob={newShapeCollection:function(){return _length?pool[_length-=1]:new ShapeCollection},release:function(t){var e,i=t._length;for(e=0;e<i;e+=1)shapePool.release(t.shapes[e]);t._length=0,_length===_maxLength&&(pool=pooling.double(pool),_maxLength*=2),pool[_length]=t,_length+=1}},_length=0,_maxLength=4,pool=createSizedArray(_maxLength),ob),ob,_length,_maxLength,pool,ShapePropertyFactory=function(){var t=-999999;function e(t,e,i){var r,s,a,n,o,h,l,p,f,c=i.lastIndex,m=this.keyframes;if(t<m[0].t-this.offsetTime)r=m[0].s[0],a=!0,c=0;else if(t>=m[m.length-1].t-this.offsetTime)r=m[m.length-1].s?m[m.length-1].s[0]:m[m.length-2].e[0],a=!0;else{for(var d,u,y,g=c,v=m.length-1,P=!0;P&&(d=m[g],!((u=m[g+1]).t-this.offsetTime>t));)g<v-1?g+=1:P=!1;if(y=this.keyframesMetadata[g]||{},c=g,!(a=1===d.h)){if(t>=u.t-this.offsetTime)p=1;else if(t<d.t-this.offsetTime)p=0;else{var b;y.__fnct?b=y.__fnct:(b=BezierFactory.getBezierEasing(d.o.x,d.o.y,d.i.x,d.i.y).get,y.__fnct=b),p=b((t-(d.t-this.offsetTime))/(u.t-this.offsetTime-(d.t-this.offsetTime)))}s=u.s?u.s[0]:d.e[0]}r=d.s[0]}for(h=e._length,l=r.i[0].length,i.lastIndex=c,n=0;n<h;n+=1)for(o=0;o<l;o+=1)f=a?r.i[n][o]:r.i[n][o]+(s.i[n][o]-r.i[n][o])*p,e.i[n][o]=f,f=a?r.o[n][o]:r.o[n][o]+(s.o[n][o]-r.o[n][o])*p,e.o[n][o]=f,f=a?r.v[n][o]:r.v[n][o]+(s.v[n][o]-r.v[n][o])*p,e.v[n][o]=f}function i(){var e=this.comp.renderedFrame-this.offsetTime,i=this.keyframes[0].t-this.offsetTime,r=this.keyframes[this.keyframes.length-1].t-this.offsetTime,s=this._caching.lastFrame;return s!==t&&(s<i&&e<i||s>r&&e>r)||(this._caching.lastIndex=s<e?this._caching.lastIndex:0,this.interpolateShape(e,this.pv,this._caching)),this._caching.lastFrame=e,this.pv}function r(){this.paths=this.localShapeCollection}function s(t){(function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var i,r=t._length;for(i=0;i<r;i+=1)if(t.v[i][0]!==e.v[i][0]||t.v[i][1]!==e.v[i][1]||t.o[i][0]!==e.o[i][0]||t.o[i][1]!==e.o[i][1]||t.i[i][0]!==e.i[i][0]||t.i[i][1]!==e.i[i][1])return!1;return!0})(this.v,t)||(this.v=shapePool.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function a(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t,e;this.lock=!0,this._mdf=!1,t=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k;var i=this.effectsSequence.length;for(e=0;e<i;e+=1)t=this.effectsSequence[e](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function n(t,e,i){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var s=3===i?e.pt.k:e.ks.k;this.v=shapePool.clone(s),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=r,this.effectsSequence=[]}function o(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function h(e,s,a){this.propType="shape",this.comp=e.comp,this.elem=e,this.container=e,this.offsetTime=e.data.st,this.keyframes=3===a?s.pt.k:s.ks.k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;var n=this.keyframes[0].s[0].i.length;this.v=shapePool.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,n),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=t,this.reset=r,this._caching={lastFrame:t,lastIndex:0},this.effectsSequence=[i.bind(this)]}n.prototype.interpolateShape=e,n.prototype.getValue=a,n.prototype.setVValue=s,n.prototype.addEffect=o,h.prototype.getValue=a,h.prototype.interpolateShape=e,h.prototype.setVValue=s,h.prototype.addEffect=o;var l=function(){var t=roundCorner;function e(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}return e.prototype={reset:r,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var e=this.p.v[0],i=this.p.v[1],r=this.s.v[0]/2,s=this.s.v[1]/2,a=3!==this.d,n=this.v;n.v[0][0]=e,n.v[0][1]=i-s,n.v[1][0]=a?e+r:e-r,n.v[1][1]=i,n.v[2][0]=e,n.v[2][1]=i+s,n.v[3][0]=a?e-r:e+r,n.v[3][1]=i,n.i[0][0]=a?e-r*t:e+r*t,n.i[0][1]=i-s,n.i[1][0]=a?e+r:e-r,n.i[1][1]=i-s*t,n.i[2][0]=a?e+r*t:e-r*t,n.i[2][1]=i+s,n.i[3][0]=a?e-r:e+r,n.i[3][1]=i+s*t,n.o[0][0]=a?e+r*t:e-r*t,n.o[0][1]=i-s,n.o[1][0]=a?e+r:e-r,n.o[1][1]=i+s*t,n.o[2][0]=a?e-r*t:e+r*t,n.o[2][1]=i+s,n.o[3][0]=a?e-r:e+r,n.o[3][1]=i-s*t}},extendPrototype([DynamicPropertyContainer],e),e}(),p=function(){function t(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=PropertyFactory.getProp(t,e.ir,0,0,this),this.is=PropertyFactory.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=PropertyFactory.getProp(t,e.pt,0,0,this),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,degToRads,this),this.or=PropertyFactory.getProp(t,e.or,0,0,this),this.os=PropertyFactory.getProp(t,e.os,0,.01,this),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}return t.prototype={reset:r,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,i,r,s=2*Math.floor(this.pt.v),a=2*Math.PI/s,n=!0,o=this.or.v,h=this.ir.v,l=this.os.v,p=this.is.v,f=2*Math.PI*o/(2*s),c=2*Math.PI*h/(2*s),m=-Math.PI/2;m+=this.r.v;var d=3===this.data.d?-1:1;for(this.v._length=0,t=0;t<s;t+=1){i=n?l:p,r=n?f:c;var u=(e=n?o:h)*Math.cos(m),y=e*Math.sin(m),g=0===u&&0===y?0:y/Math.sqrt(u*u+y*y),v=0===u&&0===y?0:-u/Math.sqrt(u*u+y*y);u+=+this.p.v[0],y+=+this.p.v[1],this.v.setTripleAt(u,y,u-g*r*i*d,y-v*r*i*d,u+g*r*i*d,y+v*r*i*d,t,!0),n=!n,m+=a*d}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),i=2*Math.PI/e,r=this.or.v,s=this.os.v,a=2*Math.PI*r/(4*e),n=.5*-Math.PI,o=3===this.data.d?-1:1;for(n+=this.r.v,this.v._length=0,t=0;t<e;t+=1){var h=r*Math.cos(n),l=r*Math.sin(n),p=0===h&&0===l?0:l/Math.sqrt(h*h+l*l),f=0===h&&0===l?0:-h/Math.sqrt(h*h+l*l);h+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(h,l,h-p*a*s*o,l-f*a*s*o,h+p*a*s*o,l+f*a*s*o,t,!0),n+=i*o}this.paths.length=0,this.paths[0]=this.v}},extendPrototype([DynamicPropertyContainer],t),t}(),f=function(){function t(t,e){this.v=shapePool.newElement(),this.v.c=!0,this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}return t.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,r=this.s.v[1]/2,s=bmMin(i,r,this.r.v),a=s*(1-roundCorner);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+s,t+i,e-r+a,0,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-a,t+i,e+r-s,1,!0),0!==s?(this.v.setTripleAt(t+i-s,e+r,t+i-s,e+r,t+i-a,e+r,2,!0),this.v.setTripleAt(t-i+s,e+r,t-i+a,e+r,t-i+s,e+r,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-s,t-i,e+r-a,4,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+a,t-i,e-r+s,5,!0),this.v.setTripleAt(t-i+s,e-r,t-i+s,e-r,t-i+a,e-r,6,!0),this.v.setTripleAt(t+i-s,e-r,t+i-a,e-r,t+i-s,e-r,7,!0)):(this.v.setTripleAt(t-i,e+r,t-i+a,e+r,t-i,e+r,2),this.v.setTripleAt(t-i,e-r,t-i,e-r+a,t-i,e-r,3))):(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+a,t+i,e-r+s,0,!0),0!==s?(this.v.setTripleAt(t+i-s,e-r,t+i-s,e-r,t+i-a,e-r,1,!0),this.v.setTripleAt(t-i+s,e-r,t-i+a,e-r,t-i+s,e-r,2,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+s,t-i,e-r+a,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-a,t-i,e+r-s,4,!0),this.v.setTripleAt(t-i+s,e+r,t-i+s,e+r,t-i+a,e+r,5,!0),this.v.setTripleAt(t+i-s,e+r,t+i-a,e+r,t+i-s,e+r,6,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-s,t+i,e+r-a,7,!0)):(this.v.setTripleAt(t-i,e-r,t-i+a,e-r,t-i,e-r,1,!0),this.v.setTripleAt(t-i,e+r,t-i,e+r-a,t-i,e+r,2,!0),this.v.setTripleAt(t+i,e+r,t+i-a,e+r,t+i,e+r,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:r},extendPrototype([DynamicPropertyContainer],t),t}();var c={getShapeProp:function(t,e,i){var r;return 3===i||4===i?r=(3===i?e.pt:e.ks).k.length?new h(t,e,i):new n(t,e,i):5===i?r=new f(t,e):6===i?r=new l(t,e):7===i&&(r=new p(t,e)),r.k&&t.addDynamicProperty(r),r},getConstructorFunction:function(){return n},getKeyframedConstructorFunction:function(){return h}};return c}(),Matrix=function(){var t=Math.cos,e=Math.sin,i=Math.tan,r=Math.round;function s(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function a(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,-s,0,0,s,r,0,0,0,0,1,0,0,0,0,1)}function n(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(1,0,0,0,0,r,-s,0,0,s,r,0,0,0,0,1)}function o(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,0,s,0,0,1,0,0,-s,0,r,0,0,0,0,1)}function h(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,-s,0,0,s,r,0,0,0,0,1,0,0,0,0,1)}function l(t,e){return this._t(1,e,t,1,0,0)}function p(t,e){return this.shear(i(t),i(e))}function f(r,s){var a=t(s),n=e(s);return this._t(a,n,0,0,-n,a,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,i(r),1,0,0,0,0,1,0,0,0,0,1)._t(a,-n,0,0,n,a,0,0,0,0,1,0,0,0,0,1)}function c(t,e,i){return i||0===i||(i=1),1===t&&1===e&&1===i?this:this._t(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1)}function m(t,e,i,r,s,a,n,o,h,l,p,f,c,m,d,u){return this.props[0]=t,this.props[1]=e,this.props[2]=i,this.props[3]=r,this.props[4]=s,this.props[5]=a,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=l,this.props[10]=p,this.props[11]=f,this.props[12]=c,this.props[13]=m,this.props[14]=d,this.props[15]=u,this}function d(t,e,i){return i=i||0,0!==t||0!==e||0!==i?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,i,1):this}function u(t,e,i,r,s,a,n,o,h,l,p,f,c,m,d,u){var y=this.props;if(1===t&&0===e&&0===i&&0===r&&0===s&&1===a&&0===n&&0===o&&0===h&&0===l&&1===p&&0===f)return y[12]=y[12]*t+y[15]*c,y[13]=y[13]*a+y[15]*m,y[14]=y[14]*p+y[15]*d,y[15]*=u,this._identityCalculated=!1,this;var g=y[0],v=y[1],P=y[2],b=y[3],x=y[4],S=y[5],C=y[6],E=y[7],_=y[8],T=y[9],A=y[10],D=y[11],k=y[12],M=y[13],I=y[14],F=y[15];return y[0]=g*t+v*s+P*h+b*c,y[1]=g*e+v*a+P*l+b*m,y[2]=g*i+v*n+P*p+b*d,y[3]=g*r+v*o+P*f+b*u,y[4]=x*t+S*s+C*h+E*c,y[5]=x*e+S*a+C*l+E*m,y[6]=x*i+S*n+C*p+E*d,y[7]=x*r+S*o+C*f+E*u,y[8]=_*t+T*s+A*h+D*c,y[9]=_*e+T*a+A*l+D*m,y[10]=_*i+T*n+A*p+D*d,y[11]=_*r+T*o+A*f+D*u,y[12]=k*t+M*s+I*h+F*c,y[13]=k*e+M*a+I*l+F*m,y[14]=k*i+M*n+I*p+F*d,y[15]=k*r+M*o+I*f+F*u,this._identityCalculated=!1,this}function y(t){var e=t.props;return this.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}function g(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function v(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function P(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function b(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function x(t,e,i){return{x:t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}}function S(t,e,i){return t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12]}function C(t,e,i){return t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13]}function E(t,e,i){return t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}function _(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,i=-this.props[1]/t,r=-this.props[4]/t,s=this.props[0]/t,a=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,n=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,o=new Matrix;return o.props[0]=e,o.props[1]=i,o.props[4]=r,o.props[5]=s,o.props[12]=a,o.props[13]=n,o}function T(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function A(t){var e,i=t.length,r=[];for(e=0;e<i;e+=1)r[e]=T(t[e]);return r}function D(t,e,i){var r=createTypedArray("float32",6);if(this.isIdentity())r[0]=t[0],r[1]=t[1],r[2]=e[0],r[3]=e[1],r[4]=i[0],r[5]=i[1];else{var s=this.props[0],a=this.props[1],n=this.props[4],o=this.props[5],h=this.props[12],l=this.props[13];r[0]=t[0]*s+t[1]*n+h,r[1]=t[0]*a+t[1]*o+l,r[2]=e[0]*s+e[1]*n+h,r[3]=e[0]*a+e[1]*o+l,r[4]=i[0]*s+i[1]*n+h,r[5]=i[0]*a+i[1]*o+l}return r}function k(t,e,i){return this.isIdentity()?[t,e,i]:[t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]]}function M(t,e){if(this.isIdentity())return t+","+e;var i=this.props;return Math.round(100*(t*i[0]+e*i[4]+i[12]))/100+","+Math.round(100*(t*i[1]+e*i[5]+i[13]))/100}function I(){for(var t=0,e=this.props,i="matrix3d(";t<16;)i+=r(1e4*e[t])/1e4,i+=15===t?")":",",t+=1;return i}function F(t){return t<1e-6&&t>0||t>-1e-6&&t<0?r(1e4*t)/1e4:t}function w(){var t=this.props;return"matrix("+F(t[0])+","+F(t[1])+","+F(t[4])+","+F(t[5])+","+F(t[12])+","+F(t[13])+")"}return function(){this.reset=s,this.rotate=a,this.rotateX=n,this.rotateY=o,this.rotateZ=h,this.skew=p,this.skewFromAxis=f,this.shear=l,this.scale=c,this.setTransform=m,this.translate=d,this.transform=u,this.multiply=y,this.applyToPoint=x,this.applyToX=S,this.applyToY=C,this.applyToZ=E,this.applyToPointArray=k,this.applyToTriplePoints=D,this.applyToPointStringified=M,this.toCSS=I,this.to2dCSS=w,this.clone=P,this.cloneFromProps=b,this.equals=v,this.inversePoints=A,this.inversePoint=T,this.getInverseMatrix=_,this._t=this.transform,this.isIdentity=g,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}}();function _typeof$3(t){return _typeof$3="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$3(t)}var lottie={},standalone="__[STANDALONE]__",animationData="__[ANIMATIONDATA]__",renderer="";function setLocation(t){setLocationHref(t)}function searchAnimations(){!0===standalone?animationManager.searchAnimations(animationData,standalone,renderer):animationManager.searchAnimations()}function setSubframeRendering(t){setSubframeEnabled(t)}function setPrefix(t){setIdPrefix(t)}function loadAnimation(t){return!0===standalone&&(t.animationData=JSON.parse(animationData)),animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":setDefaultCurveSegments(200);break;default:case"medium":setDefaultCurveSegments(50);break;case"low":setDefaultCurveSegments(10)}else!isNaN(t)&&t>1&&setDefaultCurveSegments(t);getDefaultCurveSegments()>=50?roundValues(!1):roundValues(!0)}function inBrowser(){return"undefined"!=typeof navigator}function installPlugin(t,e){"expressions"===t&&setExpressionsPlugin(e)}function getFactory(t){switch(t){case"propertyFactory":return PropertyFactory;case"shapePropertyFactory":return ShapePropertyFactory;case"matrix":return Matrix;default:return null}}function checkReady(){"complete"===document.readyState&&(clearInterval(readyStateCheckInterval),searchAnimations())}function getQueryVariable(t){for(var e=queryString.split("&"),i=0;i<e.length;i+=1){var r=e[i].split("=");if(decodeURIComponent(r[0])==t)return decodeURIComponent(r[1])}return null}lottie.play=animationManager.play,lottie.pause=animationManager.pause,lottie.setLocationHref=setLocation,lottie.togglePause=animationManager.togglePause,lottie.setSpeed=animationManager.setSpeed,lottie.setDirection=animationManager.setDirection,lottie.stop=animationManager.stop,lottie.searchAnimations=searchAnimations,lottie.registerAnimation=animationManager.registerAnimation,lottie.loadAnimation=loadAnimation,lottie.setSubframeRendering=setSubframeRendering,lottie.resize=animationManager.resize,lottie.goToAndStop=animationManager.goToAndStop,lottie.destroy=animationManager.destroy,lottie.setQuality=setQuality,lottie.inBrowser=inBrowser,lottie.installPlugin=installPlugin,lottie.freeze=animationManager.freeze,lottie.unfreeze=animationManager.unfreeze,lottie.setVolume=animationManager.setVolume,lottie.mute=animationManager.mute,lottie.unmute=animationManager.unmute,lottie.getRegisteredAnimations=animationManager.getRegisteredAnimations,lottie.useWebWorker=setWebWorker,lottie.setIDPrefix=setPrefix,lottie.__getFactory=getFactory,lottie.version="5.12.2";var queryString="";if(standalone){var scripts=document.getElementsByTagName("script"),index=scripts.length-1,myScript=scripts[index]||{src:""};queryString=myScript.src?myScript.src.replace(/^[^\?]+\??/,""):"",renderer=getQueryVariable("renderer")}var readyStateCheckInterval=setInterval(checkReady,100);try{"object"===("undefined"==typeof exports?"undefined":_typeof$3(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=lottie)}catch(t){}var ShapeModifiers=function(){var t={},e={};return t.registerModifier=function(t,i){e[t]||(e[t]=i)},t.getModifier=function(t,i,r){return new e[t](i,r)},t}();function ShapeModifier(){}function TrimModifier(){}function PuckerAndBloatModifier(){}ShapeModifier.prototype.initModifierProperties=function(){},ShapeModifier.prototype.addShapeToModifier=function(){},ShapeModifier.prototype.addShape=function(t){if(!this.closed){t.sh.container.addDynamicProperty(t.sh);var e={shape:t.sh,data:t,localShapeCollection:shapeCollectionPool.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},ShapeModifier.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=initialDefaultFrame,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},ShapeModifier.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},extendPrototype([DynamicPropertyContainer],ShapeModifier),extendPrototype([ShapeModifier],TrimModifier),TrimModifier.prototype.initModifierProperties=function(t,e){this.s=PropertyFactory.getProp(t,e.s,0,.01,this),this.e=PropertyFactory.getProp(t,e.e,0,.01,this),this.o=PropertyFactory.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},TrimModifier.prototype.addShapeToModifier=function(t){t.pathsData=[]},TrimModifier.prototype.calculateShapeEdges=function(t,e,i,r,s){var a=[];e<=1?a.push({s:t,e:e}):t>=1?a.push({s:t-1,e:e-1}):(a.push({s:t,e:1}),a.push({s:0,e:e-1}));var n,o,h=[],l=a.length;for(n=0;n<l;n+=1){var p,f;if(!((o=a[n]).e*s<r||o.s*s>r+i))p=o.s*s<=r?0:(o.s*s-r)/i,f=o.e*s>=r+i?1:(o.e*s-r)/i,h.push([p,f])}return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){var e,i=t.length;for(e=0;e<i;e+=1)segmentsLengthPool.release(t[e]);return t.length=0,t},TrimModifier.prototype.processShapes=function(t){var e,i,r,s;if(this._mdf||t){var a=this.o.v%360/360;if(a<0&&(a+=1),(e=this.s.v>1?1+a:this.s.v<0?0+a:this.s.v+a)>(i=this.e.v>1?1+a:this.e.v<0?0+a:this.e.v+a)){var n=e;e=i,i=n}e=1e-4*Math.round(1e4*e),i=1e-4*Math.round(1e4*i),this.sValue=e,this.eValue=i}else e=this.sValue,i=this.eValue;var o,h,l,p,f,c=this.shapes.length,m=0;if(i===e)for(s=0;s<c;s+=1)this.shapes[s].localShapeCollection.releaseShapes(),this.shapes[s].shape._mdf=!0,this.shapes[s].shape.paths=this.shapes[s].localShapeCollection,this._mdf&&(this.shapes[s].pathsData.length=0);else if(1===i&&0===e||0===i&&1===e){if(this._mdf)for(s=0;s<c;s+=1)this.shapes[s].pathsData.length=0,this.shapes[s].shape._mdf=!0}else{var d,u,y=[];for(s=0;s<c;s+=1)if((d=this.shapes[s]).shape._mdf||this._mdf||t||2===this.m){if(h=(r=d.shape.paths)._length,f=0,!d.shape._mdf&&d.pathsData.length)f=d.totalShapeLength;else{for(l=this.releasePathsData(d.pathsData),o=0;o<h;o+=1)p=bez.getSegmentsLength(r.shapes[o]),l.push(p),f+=p.totalLength;d.totalShapeLength=f,d.pathsData=l}m+=f,d.shape._mdf=!0}else d.shape.paths=d.localShapeCollection;var g,v=e,P=i,b=0;for(s=c-1;s>=0;s-=1)if((d=this.shapes[s]).shape._mdf){for((u=d.localShapeCollection).releaseShapes(),2===this.m&&c>1?(g=this.calculateShapeEdges(e,i,d.totalShapeLength,b,m),b+=d.totalShapeLength):g=[[v,P]],h=g.length,o=0;o<h;o+=1){v=g[o][0],P=g[o][1],y.length=0,P<=1?y.push({s:d.totalShapeLength*v,e:d.totalShapeLength*P}):v>=1?y.push({s:d.totalShapeLength*(v-1),e:d.totalShapeLength*(P-1)}):(y.push({s:d.totalShapeLength*v,e:d.totalShapeLength}),y.push({s:0,e:d.totalShapeLength*(P-1)}));var x=this.addShapes(d,y[0]);if(y[0].s!==y[0].e){if(y.length>1)if(d.shape.paths.shapes[d.shape.paths._length-1].c){var S=x.pop();this.addPaths(x,u),x=this.addShapes(d,y[1],S)}else this.addPaths(x,u),x=this.addShapes(d,y[1]);this.addPaths(x,u)}}d.shape.paths=u}}},TrimModifier.prototype.addPaths=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)e.addShape(t[i])},TrimModifier.prototype.addSegment=function(t,e,i,r,s,a,n){s.setXYAt(e[0],e[1],"o",a),s.setXYAt(i[0],i[1],"i",a+1),n&&s.setXYAt(t[0],t[1],"v",a),s.setXYAt(r[0],r[1],"v",a+1)},TrimModifier.prototype.addSegmentFromArray=function(t,e,i,r){e.setXYAt(t[1],t[5],"o",i),e.setXYAt(t[2],t[6],"i",i+1),r&&e.setXYAt(t[0],t[4],"v",i),e.setXYAt(t[3],t[7],"v",i+1)},TrimModifier.prototype.addShapes=function(t,e,i){var r,s,a,n,o,h,l,p,f=t.pathsData,c=t.shape.paths.shapes,m=t.shape.paths._length,d=0,u=[],y=!0;for(i?(o=i._length,p=i._length):(i=shapePool.newElement(),o=0,p=0),u.push(i),r=0;r<m;r+=1){for(h=f[r].lengths,i.c=c[r].c,a=c[r].c?h.length:h.length+1,s=1;s<a;s+=1)if(d+(n=h[s-1]).addedLength<e.s)d+=n.addedLength,i.c=!1;else{if(d>e.e){i.c=!1;break}e.s<=d&&e.e>=d+n.addedLength?(this.addSegment(c[r].v[s-1],c[r].o[s-1],c[r].i[s],c[r].v[s],i,o,y),y=!1):(l=bez.getNewSegment(c[r].v[s-1],c[r].v[s],c[r].o[s-1],c[r].i[s],(e.s-d)/n.addedLength,(e.e-d)/n.addedLength,h[s-1]),this.addSegmentFromArray(l,i,o,y),y=!1,i.c=!1),d+=n.addedLength,o+=1}if(c[r].c&&h.length){if(n=h[s-1],d<=e.e){var g=h[s-1].addedLength;e.s<=d&&e.e>=d+g?(this.addSegment(c[r].v[s-1],c[r].o[s-1],c[r].i[0],c[r].v[0],i,o,y),y=!1):(l=bez.getNewSegment(c[r].v[s-1],c[r].v[0],c[r].o[s-1],c[r].i[0],(e.s-d)/g,(e.e-d)/g,h[s-1]),this.addSegmentFromArray(l,i,o,y),y=!1,i.c=!1)}else i.c=!1;d+=n.addedLength,o+=1}if(i._length&&(i.setXYAt(i.v[p][0],i.v[p][1],"i",p),i.setXYAt(i.v[i._length-1][0],i.v[i._length-1][1],"o",i._length-1)),d>e.e)break;r<m-1&&(i=shapePool.newElement(),y=!0,u.push(i),o=0)}return u},extendPrototype([ShapeModifier],PuckerAndBloatModifier),PuckerAndBloatModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},PuckerAndBloatModifier.prototype.processPath=function(t,e){var i=e/100,r=[0,0],s=t._length,a=0;for(a=0;a<s;a+=1)r[0]+=t.v[a][0],r[1]+=t.v[a][1];r[0]/=s,r[1]/=s;var n,o,h,l,p,f,c=shapePool.newElement();for(c.c=t.c,a=0;a<s;a+=1)n=t.v[a][0]+(r[0]-t.v[a][0])*i,o=t.v[a][1]+(r[1]-t.v[a][1])*i,h=t.o[a][0]+(r[0]-t.o[a][0])*-i,l=t.o[a][1]+(r[1]-t.o[a][1])*-i,p=t.i[a][0]+(r[0]-t.i[a][0])*-i,f=t.i[a][1]+(r[1]-t.i[a][1])*-i,c.setTripleAt(n,o,h,l,p,f,a);return c},PuckerAndBloatModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amount.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var TransformPropertyFactory=function(){var t=[0,0];function e(t,e,i){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Matrix,this.pre=new Matrix,this.appliedTransformations=0,this.initDynamicPropertyContainer(i||t),e.p&&e.p.s?(this.px=PropertyFactory.getProp(t,e.p.x,0,0,this),this.py=PropertyFactory.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=PropertyFactory.getProp(t,e.p.z,0,0,this))):this.p=PropertyFactory.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=PropertyFactory.getProp(t,e.rx,0,degToRads,this),this.ry=PropertyFactory.getProp(t,e.ry,0,degToRads,this),this.rz=PropertyFactory.getProp(t,e.rz,0,degToRads,this),e.or.k[0].ti){var r,s=e.or.k.length;for(r=0;r<s;r+=1)e.or.k[r].to=null,e.or.k[r].ti=null}this.or=PropertyFactory.getProp(t,e.or,1,degToRads,this),this.or.sh=!0}else this.r=PropertyFactory.getProp(t,e.r||{k:0},0,degToRads,this);e.sk&&(this.sk=PropertyFactory.getProp(t,e.sk,0,degToRads,this),this.sa=PropertyFactory.getProp(t,e.sa,0,degToRads,this)),this.a=PropertyFactory.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=PropertyFactory.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=PropertyFactory.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return e.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(e){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||e){var i;if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var r,s;if(i=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime)this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(r=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/i,0),s=this.p.getValueAtTime(this.p.keyframes[0].t/i,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(r=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/i,0),s=this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/i,0)):(r=this.p.pv,s=this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/i,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){r=[],s=[];var a=this.px,n=this.py;a._caching.lastFrame+a.offsetTime<=a.keyframes[0].t?(r[0]=a.getValueAtTime((a.keyframes[0].t+.01)/i,0),r[1]=n.getValueAtTime((n.keyframes[0].t+.01)/i,0),s[0]=a.getValueAtTime(a.keyframes[0].t/i,0),s[1]=n.getValueAtTime(n.keyframes[0].t/i,0)):a._caching.lastFrame+a.offsetTime>=a.keyframes[a.keyframes.length-1].t?(r[0]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/i,0),r[1]=n.getValueAtTime(n.keyframes[n.keyframes.length-1].t/i,0),s[0]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/i,0),s[1]=n.getValueAtTime((n.keyframes[n.keyframes.length-1].t-.01)/i,0)):(r=[a.pv,n.pv],s[0]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/i,a.offsetTime),s[1]=n.getValueAtTime((n._caching.lastFrame+n.offsetTime-.01)/i,n.offsetTime))}else r=s=t;this.v.rotate(-Math.atan2(r[1]-s[1],r[0]-s[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],e),e.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},e.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,i,r){return new e(t,i,r)}}}();function RepeaterModifier(){}function RoundCornersModifier(){}function floatEqual(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function floatZero(t){return Math.abs(t)<=1e-5}function lerp(t,e,i){return t*(1-i)+e*i}function lerpPoint(t,e,i){return[lerp(t[0],e[0],i),lerp(t[1],e[1],i)]}function quadRoots(t,e,i){if(0===t)return[];var r=e*e-4*t*i;if(r<0)return[];var s=-e/(2*t);if(0===r)return[s];var a=Math.sqrt(r)/(2*t);return[s-a,s+a]}function polynomialCoefficients(t,e,i,r){return[3*e-t-3*i+r,3*t-6*e+3*i,-3*t+3*e,t]}function singlePoint(t){return new PolynomialBezier(t,t,t,t,!1)}function PolynomialBezier(t,e,i,r,s){s&&pointEqual(t,e)&&(e=lerpPoint(t,r,1/3)),s&&pointEqual(i,r)&&(i=lerpPoint(t,r,2/3));var a=polynomialCoefficients(t[0],e[0],i[0],r[0]),n=polynomialCoefficients(t[1],e[1],i[1],r[1]);this.a=[a[0],n[0]],this.b=[a[1],n[1]],this.c=[a[2],n[2]],this.d=[a[3],n[3]],this.points=[t,e,i,r]}function extrema(t,e){var i=t.points[0][e],r=t.points[t.points.length-1][e];if(i>r){var s=r;r=i,i=s}for(var a=quadRoots(3*t.a[e],2*t.b[e],t.c[e]),n=0;n<a.length;n+=1)if(a[n]>0&&a[n]<1){var o=t.point(a[n])[e];o<i?i=o:o>r&&(r=o)}return{min:i,max:r}}function intersectData(t,e,i){var r=t.boundingBox();return{cx:r.cx,cy:r.cy,width:r.width,height:r.height,bez:t,t:(e+i)/2,t1:e,t2:i}}function splitData(t){var e=t.bez.split(.5);return[intersectData(e[0],t.t1,t.t),intersectData(e[1],t.t,t.t2)]}function boxIntersect(t,e){return 2*Math.abs(t.cx-e.cx)<t.width+e.width&&2*Math.abs(t.cy-e.cy)<t.height+e.height}function intersectsImpl(t,e,i,r,s,a){if(boxIntersect(t,e))if(i>=a||t.width<=r&&t.height<=r&&e.width<=r&&e.height<=r)s.push([t.t,e.t]);else{var n=splitData(t),o=splitData(e);intersectsImpl(n[0],o[0],i+1,r,s,a),intersectsImpl(n[0],o[1],i+1,r,s,a),intersectsImpl(n[1],o[0],i+1,r,s,a),intersectsImpl(n[1],o[1],i+1,r,s,a)}}function crossProduct(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function lineIntersection(t,e,i,r){var s=[t[0],t[1],1],a=[e[0],e[1],1],n=[i[0],i[1],1],o=[r[0],r[1],1],h=crossProduct(crossProduct(s,a),crossProduct(n,o));return floatZero(h[2])?null:[h[0]/h[2],h[1]/h[2]]}function polarOffset(t,e,i){return[t[0]+Math.cos(e)*i,t[1]-Math.sin(e)*i]}function pointDistance(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function pointEqual(t,e){return floatEqual(t[0],e[0])&&floatEqual(t[1],e[1])}function ZigZagModifier(){}function setPoint(t,e,i,r,s,a,n){var o=i-Math.PI/2,h=i+Math.PI/2,l=e[0]+Math.cos(i)*r*s,p=e[1]-Math.sin(i)*r*s;t.setTripleAt(l,p,l+Math.cos(o)*a,p-Math.sin(o)*a,l+Math.cos(h)*n,p-Math.sin(h)*n,t.length())}function getPerpendicularVector(t,e){var i=[e[0]-t[0],e[1]-t[1]],r=.5*-Math.PI;return[Math.cos(r)*i[0]-Math.sin(r)*i[1],Math.sin(r)*i[0]+Math.cos(r)*i[1]]}function getProjectingAngle(t,e){var i=0===e?t.length()-1:e-1,r=(e+1)%t.length(),s=getPerpendicularVector(t.v[i],t.v[r]);return Math.atan2(0,1)-Math.atan2(s[1],s[0])}function zigZagCorner(t,e,i,r,s,a,n){var o=getProjectingAngle(e,i),h=e.v[i%e._length],l=e.v[0===i?e._length-1:i-1],p=e.v[(i+1)%e._length],f=2===a?Math.sqrt(Math.pow(h[0]-l[0],2)+Math.pow(h[1]-l[1],2)):0,c=2===a?Math.sqrt(Math.pow(h[0]-p[0],2)+Math.pow(h[1]-p[1],2)):0;setPoint(t,e.v[i%e._length],o,n,r,c/(2*(s+1)),f/(2*(s+1)),a)}function zigZagSegment(t,e,i,r,s,a){for(var n=0;n<r;n+=1){var o=(n+1)/(r+1),h=2===s?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(o);setPoint(t,e.point(o),l,a,i,h/(2*(r+1)),h/(2*(r+1)),s),a=-a}return a}function linearOffset(t,e,i){var r=Math.atan2(e[0]-t[0],e[1]-t[1]);return[polarOffset(t,r,i),polarOffset(e,r,i)]}function offsetSegment(t,e){var i,r,s,a,n,o,h;i=(h=linearOffset(t.points[0],t.points[1],e))[0],r=h[1],s=(h=linearOffset(t.points[1],t.points[2],e))[0],a=h[1],n=(h=linearOffset(t.points[2],t.points[3],e))[0],o=h[1];var l=lineIntersection(i,r,s,a);null===l&&(l=r);var p=lineIntersection(n,o,s,a);return null===p&&(p=n),new PolynomialBezier(i,l,p,o)}function joinLines(t,e,i,r,s){var a=e.points[3],n=i.points[0];if(3===r)return a;if(pointEqual(a,n))return a;if(2===r){var o=-e.tangentAngle(1),h=-i.tangentAngle(0)+Math.PI,l=lineIntersection(a,polarOffset(a,o+Math.PI/2,100),n,polarOffset(n,o+Math.PI/2,100)),p=l?pointDistance(l,a):pointDistance(a,n)/2,f=polarOffset(a,o,2*p*roundCorner);return t.setXYAt(f[0],f[1],"o",t.length()-1),f=polarOffset(n,h,2*p*roundCorner),t.setTripleAt(n[0],n[1],n[0],n[1],f[0],f[1],t.length()),n}var c=lineIntersection(pointEqual(a,e.points[2])?e.points[0]:e.points[2],a,n,pointEqual(n,i.points[1])?i.points[3]:i.points[1]);return c&&pointDistance(c,a)<s?(t.setTripleAt(c[0],c[1],c[0],c[1],c[0],c[1],t.length()),c):a}function getIntersection(t,e){var i=t.intersections(e);return i.length&&floatEqual(i[0][0],1)&&i.shift(),i.length?i[0]:null}function pruneSegmentIntersection(t,e){var i=t.slice(),r=e.slice(),s=getIntersection(t[t.length-1],e[0]);return s&&(i[t.length-1]=t[t.length-1].split(s[0])[0],r[0]=e[0].split(s[1])[1]),t.length>1&&e.length>1&&(s=getIntersection(t[0],e[e.length-1]))?[[t[0].split(s[0])[0]],[e[e.length-1].split(s[1])[1]]]:[i,r]}function pruneIntersections(t){for(var e,i=1;i<t.length;i+=1)e=pruneSegmentIntersection(t[i-1],t[i]),t[i-1]=e[0],t[i]=e[1];return t.length>1&&(e=pruneSegmentIntersection(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}function offsetSegmentSplit(t,e){var i,r,s,a,n=t.inflectionPoints();if(0===n.length)return[offsetSegment(t,e)];if(1===n.length||floatEqual(n[1],1))return i=(s=t.split(n[0]))[0],r=s[1],[offsetSegment(i,e),offsetSegment(r,e)];i=(s=t.split(n[0]))[0];var o=(n[1]-n[0])/(1-n[0]);return a=(s=s[1].split(o))[0],r=s[1],[offsetSegment(i,e),offsetSegment(a,e),offsetSegment(r,e)]}function OffsetPathModifier(){}function getFontProperties(t){for(var e=t.fStyle?t.fStyle.split(" "):[],i="normal",r="normal",s=e.length,a=0;a<s;a+=1)switch(e[a].toLowerCase()){case"italic":r="italic";break;case"bold":i="700";break;case"black":i="900";break;case"medium":i="500";break;case"regular":case"normal":i="400";break;case"light":case"thin":i="200"}return{style:r,weight:t.fWeight||i}}extendPrototype([ShapeModifier],RepeaterModifier),RepeaterModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=PropertyFactory.getProp(t,e.c,0,null,this),this.o=PropertyFactory.getProp(t,e.o,0,null,this),this.tr=TransformPropertyFactory.getTransformProperty(t,e.tr,this),this.so=PropertyFactory.getProp(t,e.tr.so,0,.01,this),this.eo=PropertyFactory.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Matrix,this.rMatrix=new Matrix,this.sMatrix=new Matrix,this.tMatrix=new Matrix,this.matrix=new Matrix},RepeaterModifier.prototype.applyTransforms=function(t,e,i,r,s,a){var n=a?-1:1,o=r.s.v[0]+(1-r.s.v[0])*(1-s),h=r.s.v[1]+(1-r.s.v[1])*(1-s);t.translate(r.p.v[0]*n*s,r.p.v[1]*n*s,r.p.v[2]),e.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),e.rotate(-r.r.v*n*s),e.translate(r.a.v[0],r.a.v[1],r.a.v[2]),i.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),i.scale(a?1/o:o,a?1/h:h),i.translate(r.a.v[0],r.a.v[1],r.a.v[2])},RepeaterModifier.prototype.init=function(t,e,i,r){for(this.elem=t,this.arr=e,this.pos=i,this.elemsData=r,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[i]);i>0;)i-=1,this._elements.unshift(e[i]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},RepeaterModifier.prototype.cloneElements=function(t){var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},RepeaterModifier.prototype.changeGroupRender=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)t[i]._render=e,"gr"===t[i].ty&&this.changeGroupRender(t[i].it,e)},RepeaterModifier.prototype.processShapes=function(t){var e,i,r,s,a,n=!1;if(this._mdf||t){var o,h=Math.ceil(this.c.v);if(this._groups.length<h){for(;this._groups.length<h;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(a=0,r=0;r<=this._groups.length-1;r+=1){if(o=a<h,this._groups[r]._render=o,this.changeGroupRender(this._groups[r].it,o),!o){var p=this.elemsData[r].it,f=p[p.length-1];0!==f.transform.op.v?(f.transform.op._mdf=!0,f.transform.op.v=0):f.transform.op._mdf=!1}a+=1}this._currentCopies=h;var c=this.o.v,m=c%1,d=c>0?Math.floor(c):Math.ceil(c),u=this.pMatrix.props,y=this.rMatrix.props,g=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var v,P,b=0;if(c>0){for(;b<d;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),b+=1;m&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,m,!1),b+=m)}else if(c<0){for(;b>d;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),b-=1;m&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-m,!0),b-=m)}for(r=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(P=(i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(r/(this._currentCopies-1)),0!==b){for((0!==r&&1===s||r!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]),this.matrix.transform(u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]),v=0;v<P;v+=1)i[v]=this.matrix.props[v];this.matrix.reset()}else for(this.matrix.reset(),v=0;v<P;v+=1)i[v]=this.matrix.props[v];b+=1,a-=1,r+=s}}else for(a=this._currentCopies,r=0,s=1;a;)i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,a-=1,r+=s;return n},RepeaterModifier.prototype.addShape=function(){},extendPrototype([ShapeModifier],RoundCornersModifier),RoundCornersModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=PropertyFactory.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},RoundCornersModifier.prototype.processPath=function(t,e){var i,r=shapePool.newElement();r.c=t.c;var s,a,n,o,h,l,p,f,c,m,d,u,y=t._length,g=0;for(i=0;i<y;i+=1)s=t.v[i],n=t.o[i],a=t.i[i],s[0]===n[0]&&s[1]===n[1]&&s[0]===a[0]&&s[1]===a[1]?0!==i&&i!==y-1||t.c?(o=0===i?t.v[y-1]:t.v[i-1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=d=s[0]+(o[0]-s[0])*l,f=u=s[1]-(s[1]-o[1])*l,c=p-(p-s[0])*roundCorner,m=f-(f-s[1])*roundCorner,r.setTripleAt(p,f,c,m,d,u,g),g+=1,o=i===y-1?t.v[0]:t.v[i+1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=c=s[0]+(o[0]-s[0])*l,f=m=s[1]+(o[1]-s[1])*l,d=p-(p-s[0])*roundCorner,u=f-(f-s[1])*roundCorner,r.setTripleAt(p,f,c,m,d,u,g),g+=1):(r.setTripleAt(s[0],s[1],n[0],n[1],a[0],a[1],g),g+=1):(r.setTripleAt(t.v[i][0],t.v[i][1],t.o[i][0],t.o[i][1],t.i[i][0],t.i[i][1],g),g+=1);return r},RoundCornersModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},PolynomialBezier.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},PolynomialBezier.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},PolynomialBezier.prototype.tangentAngle=function(t){var e=this.derivative(t);return Math.atan2(e[1],e[0])},PolynomialBezier.prototype.normalAngle=function(t){var e=this.derivative(t);return Math.atan2(e[0],e[1])},PolynomialBezier.prototype.inflectionPoints=function(){var t=this.a[1]*this.b[0]-this.a[0]*this.b[1];if(floatZero(t))return[];var e=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/t,i=e*e-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/t;if(i<0)return[];var r=Math.sqrt(i);return floatZero(r)?r>0&&r<1?[e]:[]:[e-r,e+r].filter((function(t){return t>0&&t<1}))},PolynomialBezier.prototype.split=function(t){if(t<=0)return[singlePoint(this.points[0]),this];if(t>=1)return[this,singlePoint(this.points[this.points.length-1])];var e=lerpPoint(this.points[0],this.points[1],t),i=lerpPoint(this.points[1],this.points[2],t),r=lerpPoint(this.points[2],this.points[3],t),s=lerpPoint(e,i,t),a=lerpPoint(i,r,t),n=lerpPoint(s,a,t);return[new PolynomialBezier(this.points[0],e,s,n,!0),new PolynomialBezier(n,a,r,this.points[3],!0)]},PolynomialBezier.prototype.bounds=function(){return{x:extrema(this,0),y:extrema(this,1)}},PolynomialBezier.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},PolynomialBezier.prototype.intersections=function(t,e,i){void 0===e&&(e=2),void 0===i&&(i=7);var r=[];return intersectsImpl(intersectData(this,0,1),intersectData(t,0,1),0,e,r,i),r},PolynomialBezier.shapeSegment=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[e],t.o[e],t.i[i],t.v[i],!0)},PolynomialBezier.shapeSegmentInverted=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[i],t.i[i],t.o[e],t.v[e],!0)},extendPrototype([ShapeModifier],ZigZagModifier),ZigZagModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=PropertyFactory.getProp(t,e.s,0,null,this),this.frequency=PropertyFactory.getProp(t,e.r,0,null,this),this.pointsType=PropertyFactory.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},ZigZagModifier.prototype.processPath=function(t,e,i,r){var s=t._length,a=shapePool.newElement();if(a.c=t.c,t.c||(s-=1),0===s)return a;var n=-1,o=PolynomialBezier.shapeSegment(t,0);zigZagCorner(a,t,0,e,i,r,n);for(var h=0;h<s;h+=1)n=zigZagSegment(a,o,e,i,r,-n),o=h!==s-1||t.c?PolynomialBezier.shapeSegment(t,(h+1)%s):null,zigZagCorner(a,t,h+1,e,i,r,n);return a},ZigZagModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amplitude.v,l=Math.max(0,Math.round(this.frequency.v)),p=this.pointsType.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h,l,p));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},extendPrototype([ShapeModifier],OffsetPathModifier),OffsetPathModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this.miterLimit=PropertyFactory.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},OffsetPathModifier.prototype.processPath=function(t,e,i,r){var s=shapePool.newElement();s.c=t.c;var a,n,o,h=t.length();t.c||(h-=1);var l=[];for(a=0;a<h;a+=1)o=PolynomialBezier.shapeSegment(t,a),l.push(offsetSegmentSplit(o,e));if(!t.c)for(a=h-1;a>=0;a-=1)o=PolynomialBezier.shapeSegmentInverted(t,a),l.push(offsetSegmentSplit(o,e));l=pruneIntersections(l);var p=null,f=null;for(a=0;a<l.length;a+=1){var c=l[a];for(f&&(p=joinLines(s,f,c[0],i,r)),f=c[c.length-1],n=0;n<c.length;n+=1)o=c[n],p&&pointEqual(o.points[0],p)?s.setXYAt(o.points[1][0],o.points[1][1],"o",s.length()-1):s.setTripleAt(o.points[0][0],o.points[0][1],o.points[1][0],o.points[1][1],o.points[0][0],o.points[0][1],s.length()),s.setTripleAt(o.points[3][0],o.points[3][1],o.points[3][0],o.points[3][1],o.points[2][0],o.points[2][1],s.length()),p=o.points[3]}return l.length&&joinLines(s,f,l[0][0],i,r),s},OffsetPathModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amount.v,l=this.miterLimit.v,p=this.lineJoin;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h,p,l));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var FontManager=function(){var t={w:0,size:0,shapes:[],data:{shapes:[]}},e=[];e=e.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);var i=127988,r=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function s(t,e){var i=createTag("span");i.setAttribute("aria-hidden",!0),i.style.fontFamily=e;var r=createTag("span");r.innerText="giItT1WQy@!-/#",i.style.position="absolute",i.style.left="-10000px",i.style.top="-10000px",i.style.fontSize="300px",i.style.fontVariant="normal",i.style.fontStyle="normal",i.style.fontWeight="normal",i.style.letterSpacing="0",i.appendChild(r),document.body.appendChild(i);var s=r.offsetWidth;return r.style.fontFamily=function(t){var e,i=t.split(","),r=i.length,s=[];for(e=0;e<r;e+=1)"sans-serif"!==i[e]&&"monospace"!==i[e]&&s.push(i[e]);return s.join(",")}(t)+", "+e,{node:r,w:s,parent:i}}function a(t,e){var i,r=document.body&&e?"svg":"canvas",s=getFontProperties(t);if("svg"===r){var a=createNS("text");a.style.fontSize="100px",a.setAttribute("font-family",t.fFamily),a.setAttribute("font-style",s.style),a.setAttribute("font-weight",s.weight),a.textContent="1",t.fClass?(a.style.fontFamily="inherit",a.setAttribute("class",t.fClass)):a.style.fontFamily=t.fFamily,e.appendChild(a),i=a}else{var n=new OffscreenCanvas(500,500).getContext("2d");n.font=s.style+" "+s.weight+" 100px "+t.fFamily,i=n}return{measureText:function(t){return"svg"===r?(i.textContent=t,i.getComputedTextLength()):i.measureText(t).width}}}function n(t){var e=0,i=t.charCodeAt(0);if(i>=55296&&i<=56319){var r=t.charCodeAt(1);r>=56320&&r<=57343&&(e=1024*(i-55296)+r-56320+65536)}return e}function o(t){var e=n(t);return e>=127462&&e<=127487}var h=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)};h.isModifier=function(t,e){var i=t.toString(16)+e.toString(16);return-1!==r.indexOf(i)},h.isZeroWidthJoiner=function(t){return 8205===t},h.isFlagEmoji=function(t){return o(t.substr(0,2))&&o(t.substr(2,2))},h.isRegionalCode=o,h.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},h.isRegionalFlag=function(t,e){var r=n(t.substr(e,2));if(r!==i)return!1;var s=0;for(e+=2;s<5;){if((r=n(t.substr(e,2)))<917601||r>917626)return!1;s+=1,e+=2}return 917631===n(t.substr(e,2))},h.isVariationSelector=function(t){return 65039===t},h.BLACK_FLAG_CODE_POINT=i;var l={addChars:function(t){if(t){var e;this.chars||(this.chars=[]);var i,r,s=t.length,a=this.chars.length;for(e=0;e<s;e+=1){for(i=0,r=!1;i<a;)this.chars[i].style===t[e].style&&this.chars[i].fFamily===t[e].fFamily&&this.chars[i].ch===t[e].ch&&(r=!0),i+=1;r||(this.chars.push(t[e]),a+=1)}}},addFonts:function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);if(!document.body)return this.isLoaded=!0,t.list.forEach((function(t){t.helper=a(t),t.cache={}})),void(this.fonts=t.list);var i,r=t.list,n=r.length,o=n;for(i=0;i<n;i+=1){var h,l,p=!0;if(r[i].loaded=!1,r[i].monoCase=s(r[i].fFamily,"monospace"),r[i].sansCase=s(r[i].fFamily,"sans-serif"),r[i].fPath){if("p"===r[i].fOrigin||3===r[i].origin){if((h=document.querySelectorAll('style[f-forigin="p"][f-family="'+r[i].fFamily+'"], style[f-origin="3"][f-family="'+r[i].fFamily+'"]')).length>0&&(p=!1),p){var f=createTag("style");f.setAttribute("f-forigin",r[i].fOrigin),f.setAttribute("f-origin",r[i].origin),f.setAttribute("f-family",r[i].fFamily),f.type="text/css",f.innerText="@font-face {font-family: "+r[i].fFamily+"; font-style: normal; src: url('"+r[i].fPath+"');}",e.appendChild(f)}}else if("g"===r[i].fOrigin||1===r[i].origin){for(h=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),l=0;l<h.length;l+=1)-1!==h[l].href.indexOf(r[i].fPath)&&(p=!1);if(p){var c=createTag("link");c.setAttribute("f-forigin",r[i].fOrigin),c.setAttribute("f-origin",r[i].origin),c.type="text/css",c.rel="stylesheet",c.href=r[i].fPath,document.body.appendChild(c)}}else if("t"===r[i].fOrigin||2===r[i].origin){for(h=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),l=0;l<h.length;l+=1)r[i].fPath===h[l].src&&(p=!1);if(p){var m=createTag("link");m.setAttribute("f-forigin",r[i].fOrigin),m.setAttribute("f-origin",r[i].origin),m.setAttribute("rel","stylesheet"),m.setAttribute("href",r[i].fPath),e.appendChild(m)}}}else r[i].loaded=!0,o-=1;r[i].helper=a(r[i],e),r[i].cache={},this.fonts.push(r[i])}0===o?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},getCharData:function(e,i,r){for(var s=0,a=this.chars.length;s<a;){if(this.chars[s].ch===e&&this.chars[s].style===i&&this.chars[s].fFamily===r)return this.chars[s];s+=1}return("string"==typeof e&&13!==e.charCodeAt(0)||!e)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",e,i,r)),t},getFontByName:function(t){for(var e=0,i=this.fonts.length;e<i;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,i){var r=this.getFontByName(e),s=t;if(!r.cache[s]){var a=r.helper;if(" "===t){var n=a.measureText("|"+t+"|"),o=a.measureText("||");r.cache[s]=(n-o)/100}else r.cache[s]=a.measureText(t)/100}return r.cache[s]*i},checkLoadedFonts:function(){var t,e,i,r=this.fonts.length,s=r;for(t=0;t<r;t+=1)this.fonts[t].loaded?s-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,i=this.fonts[t].monoCase.w,e.offsetWidth!==i?(s-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,i=this.fonts[t].sansCase.w,e.offsetWidth!==i&&(s-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==s&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}};return h.prototype=l,h}();function SlotManager(t){this.animationData=t}function slotFactory(t){return new SlotManager(t)}function RenderableElement(){}SlotManager.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},RenderableElement.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var getBlendMode=(blendModeEnums={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return blendModeEnums[t]||""}),blendModeEnums;function SliderEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function AngleEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function ColorEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function PointEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function LayerIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function MaskIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function CheckboxEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function NoValueEffect(){this.p={}}function EffectsManager(t,e){var i,r=t.ef||[];this.effectElements=[];var s,a=r.length;for(i=0;i<a;i+=1)s=new GroupEffect(r[i],e),this.effectElements.push(s)}function GroupEffect(t,e){this.init(t,e)}function BaseElement(){}function FrameElement(){}function FootageElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,i)}function AudioElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,i),this._isPlaying=!1,this._canPlay=!1;var r=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(r),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=PropertyFactory.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function BaseRenderer(){}extendPrototype([DynamicPropertyContainer],GroupEffect),GroupEffect.prototype.getValue=GroupEffect.prototype.iterateDynamicProperties,GroupEffect.prototype.init=function(t,e){var i;this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var r,s=this.data.ef.length,a=this.data.ef;for(i=0;i<s;i+=1){switch(r=null,a[i].ty){case 0:r=new SliderEffect(a[i],e,this);break;case 1:r=new AngleEffect(a[i],e,this);break;case 2:r=new ColorEffect(a[i],e,this);break;case 3:r=new PointEffect(a[i],e,this);break;case 4:case 7:r=new CheckboxEffect(a[i],e,this);break;case 10:r=new LayerIndexEffect(a[i],e,this);break;case 11:r=new MaskIndexEffect(a[i],e,this);break;case 5:r=new EffectsManager(a[i],e,this);break;default:r=new NoValueEffect(a[i],e,this)}r&&this.effectElements.push(r)}},BaseElement.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t=getExpressionInterfaces();if(t){var e=t("layer"),i=t("effects"),r=t("shape"),s=t("text"),a=t("comp");this.layerInterface=e(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var n=i.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(n),0===this.data.ty||this.data.xt?this.compInterface=a(this):4===this.data.ty?(this.layerInterface.shapeInterface=r(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=s(this),this.layerInterface.text=this.layerInterface.textInterface)}},setBlendMode:function(){var t=getBlendMode(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,i){this.globalData=e,this.comp=i,this.data=t,this.layerId=createElementID(),this.data.sr||(this.data.sr=1),this.effectsManager=new EffectsManager(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},FrameElement.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var i,r=this.dynamicProperties.length;for(i=0;i<r;i+=1)(e||this._isParent&&"transform"===this.dynamicProperties[i].propType)&&(this.dynamicProperties[i].getValue(),this.dynamicProperties[i]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},FootageElement.prototype.prepareFrame=function(){},extendPrototype([RenderableElement,BaseElement,FrameElement],FootageElement),FootageElement.prototype.getBaseElement=function(){return null},FootageElement.prototype.renderFrame=function(){},FootageElement.prototype.destroy=function(){},FootageElement.prototype.initExpressions=function(){var t=getExpressionInterfaces();if(t){var e=t("footage");this.layerInterface=e(this)}},FootageElement.prototype.getFootageData=function(){return this.footageData},AudioElement.prototype.prepareFrame=function(t){if(this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder)this._currentTime=t/this.data.sr;else{var e=this.tm.v;this._currentTime=e}this._volume=this.lv.v[0];var i=this._volume*this._volumeMultiplier;this._previousVolume!==i&&(this._previousVolume=i,this.audio.volume(i))},extendPrototype([RenderableElement,BaseElement,FrameElement],AudioElement),AudioElement.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek())>.1)&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},AudioElement.prototype.show=function(){},AudioElement.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},AudioElement.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},AudioElement.prototype.resume=function(){this._canPlay=!0},AudioElement.prototype.setRate=function(t){this.audio.rate(t)},AudioElement.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},AudioElement.prototype.getBaseElement=function(){return null},AudioElement.prototype.destroy=function(){},AudioElement.prototype.sourceRectAtTime=function(){},AudioElement.prototype.initExpressions=function(){},BaseRenderer.prototype.checkLayers=function(t){var e,i,r=this.layers.length;for(this.completeLayers=!0,e=r-1;e>=0;e-=1)this.elements[e]||(i=this.layers[e]).ip-i.st<=t-this.layers[e].st&&i.op-i.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:default:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t)}},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.createAudio=function(t){return new AudioElement(t,this.globalData,this)},BaseRenderer.prototype.createFootage=function(t){return new FootageElement(t,this.globalData,this)},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},BaseRenderer.prototype.includeLayers=function(t){var e;this.completeLayers=!1;var i,r=t.length,s=this.layers.length;for(e=0;e<r;e+=1)for(i=0;i<s;){if(this.layers[i].id===t[e].id){this.layers[i]=t[e];break}i+=1}},BaseRenderer.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},BaseRenderer.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},BaseRenderer.prototype.buildElementParenting=function(t,e,i){for(var r=this.elements,s=this.layers,a=0,n=s.length;a<n;)s[a].ind==e&&(r[a]&&!0!==r[a]?(i.push(r[a]),r[a].setAsParent(),void 0!==s[a].parent?this.buildElementParenting(t,s[a].parent,i):t.setHierarchy(i)):(this.buildItem(a),this.addPendingElement(t))),a+=1},BaseRenderer.prototype.addPendingElement=function(t){this.pendingElements.push(t)},BaseRenderer.prototype.searchExtraCompositions=function(t){var e,i=t.length;for(e=0;e<i;e+=1)if(t[e].xt){var r=this.createComp(t[e]);r.initExpressions(),this.globalData.projectInterface.registerComposition(r)}},BaseRenderer.prototype.getElementById=function(t){var e,i=this.elements.length;for(e=0;e<i;e+=1)if(this.elements[e].data.ind===t)return this.elements[e];return null},BaseRenderer.prototype.getElementByPath=function(t){var e,i=t.shift();if("number"==typeof i)e=this.elements[i];else{var r,s=this.elements.length;for(r=0;r<s;r+=1)if(this.elements[r].data.nm===i){e=this.elements[r];break}}return 0===t.length?e:e.getElementByPath(t)},BaseRenderer.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new FontManager,this.globalData.slotManager=slotFactory(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var effectTypes={TRANSFORM_EFFECT:"transformEFfect"};function TransformElement(){}function MaskElement(t,e,i){this.data=t,this.element=e,this.globalData=i,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var r,s,a=this.globalData.defs,n=this.masksProperties?this.masksProperties.length:0;this.viewData=createSizedArray(n),this.solidPath="";var o,h,l,p,f,c,m=this.masksProperties,d=0,u=[],y=createElementID(),g="clipPath",v="clip-path";for(r=0;r<n;r+=1)if(("a"!==m[r].mode&&"n"!==m[r].mode||m[r].inv||100!==m[r].o.k||m[r].o.x)&&(g="mask",v="mask"),"s"!==m[r].mode&&"i"!==m[r].mode||0!==d?l=null:((l=createNS("rect")).setAttribute("fill","#ffffff"),l.setAttribute("width",this.element.comp.data.w||0),l.setAttribute("height",this.element.comp.data.h||0),u.push(l)),s=createNS("path"),"n"===m[r].mode)this.viewData[r]={op:PropertyFactory.getProp(this.element,m[r].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,m[r],3),elem:s,lastPath:""},a.appendChild(s);else{var P;if(d+=1,s.setAttribute("fill","s"===m[r].mode?"#000000":"#ffffff"),s.setAttribute("clip-rule","nonzero"),0!==m[r].x.k?(g="mask",v="mask",c=PropertyFactory.getProp(this.element,m[r].x,0,null,this.element),P=createElementID(),(p=createNS("filter")).setAttribute("id",P),(f=createNS("feMorphology")).setAttribute("operator","erode"),f.setAttribute("in","SourceGraphic"),f.setAttribute("radius","0"),p.appendChild(f),a.appendChild(p),s.setAttribute("stroke","s"===m[r].mode?"#000000":"#ffffff")):(f=null,c=null),this.storedData[r]={elem:s,x:c,expan:f,lastPath:"",lastOperator:"",filterId:P,lastRadius:0},"i"===m[r].mode){h=u.length;var b=createNS("g");for(o=0;o<h;o+=1)b.appendChild(u[o]);var x=createNS("mask");x.setAttribute("mask-type","alpha"),x.setAttribute("id",y+"_"+d),x.appendChild(s),a.appendChild(x),b.setAttribute("mask","url("+getLocationHref()+"#"+y+"_"+d+")"),u.length=0,u.push(b)}else u.push(s);m[r].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[r]={elem:s,lastPath:"",op:PropertyFactory.getProp(this.element,m[r].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,m[r],3),invRect:l},this.viewData[r].prop.k||this.drawPath(m[r],this.viewData[r].prop.v,this.viewData[r])}for(this.maskElement=createNS(g),n=u.length,r=0;r<n;r+=1)this.maskElement.appendChild(u[r]);d>0&&(this.maskElement.setAttribute("id",y),this.element.maskedElement.setAttribute(v,"url("+getLocationHref()+"#"+y+")"),a.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}TransformElement.prototype={initTransform:function(){var t=new Matrix;this.finalTransform={mProp:this.data.ks?TransformPropertyFactory.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,i=0,r=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;i<r;){if(this.hierarchy[i].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}i+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),i=0;i<r;i+=1)e.multiply(this.hierarchy[i].finalTransform.mProp.v)}this.finalTransform._matMdf&&(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var i=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(i),t=1;t<e;t+=1){var r=this.localTransforms[t].matrix;i.multiply(r)}i.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){var s=this.finalTransform.localOpacity;for(t=0;t<e;t+=1)s*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=s}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new Matrix;var e=0,i=t.length;for(e=0;e<i;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var i,r=!0,s=this.comp;r;)s.finalTransform?(s.data.hasMask&&e.splice(0,0,s.finalTransform),s=s.comp):r=!1;var a,n=e.length;for(i=0;i<n;i+=1)a=e[i].mat.applyToPointArray(0,0,0),t=[t[0]-a[0],t[1]-a[1],0];return t},mHelper:new Matrix},MaskElement.prototype.getMaskProperty=function(t){return this.viewData[t].prop},MaskElement.prototype.renderFrame=function(t){var e,i=this.element.finalTransform.mat,r=this.masksProperties.length;for(e=0;e<r;e+=1)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[e].invRect.setAttribute("transform",i.getInverseMatrix().to2dCSS()),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var s=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+getLocationHref()+"#"+this.storedData[e].filterId+")")),s.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},MaskElement.prototype.getMaskelement=function(){return this.maskElement},MaskElement.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},MaskElement.prototype.drawPath=function(t,e,i){var r,s,a=" M"+e.v[0][0]+","+e.v[0][1];for(s=e._length,r=1;r<s;r+=1)a+=" C"+e.o[r-1][0]+","+e.o[r-1][1]+" "+e.i[r][0]+","+e.i[r][1]+" "+e.v[r][0]+","+e.v[r][1];if(e.c&&s>1&&(a+=" C"+e.o[r-1][0]+","+e.o[r-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),i.lastPath!==a){var n="";i.elem&&(e.c&&(n=t.inv?this.solidPath+a:a),i.elem.setAttribute("d",n)),i.lastPath=a}},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var filtersFactory=function(){var t={};return t.createFilter=function(t,e){var i=createNS("filter");i.setAttribute("id",t),!0!==e&&(i.setAttribute("filterUnits","objectBoundingBox"),i.setAttribute("x","0%"),i.setAttribute("y","0%"),i.setAttribute("width","100%"),i.setAttribute("height","100%"));return i},t.createAlphaToLuminanceFilter=function(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},t}(),featureSupport=function(){var t={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),/firefox/i.test(navigator.userAgent)&&(t.svgLumaHidden=!1),t}(),registeredEffects$1={},idPrefix="filter_result_";function SVGEffects(t){var e,i,r="SourceGraphic",s=t.data.ef?t.data.ef.length:0,a=createElementID(),n=filtersFactory.createFilter(a,!0),o=0;for(this.filters=[],e=0;e<s;e+=1){i=null;var h=t.data.ef[e].ty;if(registeredEffects$1[h])i=new(0,registeredEffects$1[h].effect)(n,t.effectsManager.effectElements[e],t,idPrefix+o,r),r=idPrefix+o,registeredEffects$1[h].countsAsEffect&&(o+=1);i&&this.filters.push(i)}o&&(t.globalData.defs.appendChild(n),t.layerElement.setAttribute("filter","url("+getLocationHref()+"#"+a+")")),this.filters.length&&t.addRenderableComponent(this)}function registerEffect$1(t,e,i){registeredEffects$1[t]={effect:e,countsAsEffect:i}}function SVGBaseElement(){}function HierarchyElement(){}function RenderableDOMElement(){}function IImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,i),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ProcessedElement(t,e){this.elem=t,this.pos=e}function IShapeElement(){}SVGEffects.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},SVGEffects.prototype.getEffects=function(t){var e,i=this.filters.length,r=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&r.push(this.filters[e]);return r},SVGBaseElement.prototype={initRendererElement:function(){this.layerElement=createNS("g")},createContainerElements:function(){this.matteElement=createNS("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t=null;if(this.data.td){this.matteMasks={};var e=createNS("g");e.setAttribute("id",this.layerId),e.appendChild(this.layerElement),t=e,this.globalData.defs.appendChild(e)}else this.data.tt?(this.matteElement.appendChild(this.layerElement),t=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var i=createNS("clipPath"),r=createNS("path");r.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var s=createElementID();if(i.setAttribute("id",s),i.appendChild(r),this.globalData.defs.appendChild(i),this.checkMasks()){var a=createNS("g");a.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),a.appendChild(this.layerElement),this.transformedElement=a,t?t.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData),this.renderableEffectsManager=new SVGEffects(this),this.searchEffectTransforms()},getMatte:function(t){if(this.matteMasks||(this.matteMasks={}),!this.matteMasks[t]){var e,i,r,s,a=this.layerId+"_"+t;if(1===t||3===t){var n=createNS("mask");n.setAttribute("id",a),n.setAttribute("mask-type",3===t?"luminance":"alpha"),(r=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),n.appendChild(r),this.globalData.defs.appendChild(n),featureSupport.maskType||1!==t||(n.setAttribute("mask-type","luminance"),e=createElementID(),i=filtersFactory.createFilter(e),this.globalData.defs.appendChild(i),i.appendChild(filtersFactory.createAlphaToLuminanceFilter()),(s=createNS("g")).appendChild(r),n.appendChild(s),s.setAttribute("filter","url("+getLocationHref()+"#"+e+")"))}else if(2===t){var o=createNS("mask");o.setAttribute("id",a),o.setAttribute("mask-type","alpha");var h=createNS("g");o.appendChild(h),e=createElementID(),i=filtersFactory.createFilter(e);var l=createNS("feComponentTransfer");l.setAttribute("in","SourceGraphic"),i.appendChild(l);var p=createNS("feFuncA");p.setAttribute("type","table"),p.setAttribute("tableValues","1.0 0.0"),l.appendChild(p),this.globalData.defs.appendChild(i);var f=createNS("rect");f.setAttribute("width",this.comp.data.w),f.setAttribute("height",this.comp.data.h),f.setAttribute("x","0"),f.setAttribute("y","0"),f.setAttribute("fill","#ffffff"),f.setAttribute("opacity","0"),h.setAttribute("filter","url("+getLocationHref()+"#"+e+")"),h.appendChild(f),(r=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),h.appendChild(r),featureSupport.maskType||(o.setAttribute("mask-type","luminance"),i.appendChild(filtersFactory.createAlphaToLuminanceFilter()),s=createNS("g"),h.appendChild(f),s.appendChild(this.layerElement),h.appendChild(s)),this.globalData.defs.appendChild(o)}this.matteMasks[t]=a}return this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+getLocationHref()+"#"+t+")")}},HierarchyElement.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},extendPrototype([RenderableElement,createProxyFunction({initElement:function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],RenderableDOMElement),extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],IImageElement),IImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=createNS("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},IImageElement.prototype.sourceRectAtTime=function(){return this.sourceRect},IShapeElement.prototype={addShapeToModifiers:function(t){var e,i=this.shapeModifiers.length;for(e=0;e<i;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;t>=0&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,i=0,r=e.length;i<r;){if(e[i].elem===t)return e[i].pos;i+=1}return 0},addProcessedElement:function(t,e){for(var i=this.processedElements,r=i.length;r;)if(i[r-=1].elem===t)return void(i[r].pos=e);i.push(new ProcessedElement(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var lineCapEnum={1:"butt",2:"round",3:"square"},lineJoinEnum={1:"miter",2:"round",3:"bevel"};function SVGShapeData(t,e,i){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=i,this.lvl=e,this._isAnimated=!!i.k;for(var r=0,s=t.length;r<s;){if(t[r].mProps.dynamicProperties.length){this._isAnimated=!0;break}r+=1}}function SVGStyleData(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=createNS("path"),this.msElem=null}function DashProperty(t,e,i,r){var s;this.elem=t,this.frameId=-1,this.dataProps=createSizedArray(e.length),this.renderer=i,this.k=!1,this.dashStr="",this.dashArray=createTypedArray("float32",e.length?e.length-1:0),this.dashoffset=createTypedArray("float32",1),this.initDynamicPropertyContainer(r);var a,n=e.length||0;for(s=0;s<n;s+=1)a=PropertyFactory.getProp(t,e[s].v,0,0,this),this.k=a.k||this.k,this.dataProps[s]={n:e[s].n,p:a};this.k||this.getValue(!0),this._isAnimated=this.k}function SVGStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i,this._isAnimated=!!this._isAnimated}function SVGFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i}function SVGNoStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=i}function GradientProperty(t,e,i){this.data=e,this.c=createTypedArray("uint8c",4*e.p);var r=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=createTypedArray("float32",r),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=r,this.initDynamicPropertyContainer(i),this.prop=PropertyFactory.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function SVGGradientFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,i)}function SVGGradientStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.initGradientData(t,e,i),this._isAnimated=!!this._isAnimated}function ShapeGroupData(){this.it=[],this.prevViewData=[],this.gr=createNS("g")}function SVGTransformData(t,e,i){this.transform={mProps:t,op:e,container:i},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}SVGShapeData.prototype.setAsAnimated=function(){this._isAnimated=!0},SVGStyleData.prototype.reset=function(){this.d="",this._mdf=!1},DashProperty.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,i=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<i;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},extendPrototype([DynamicPropertyContainer],DashProperty),extendPrototype([DynamicPropertyContainer],SVGStrokeStyleData),extendPrototype([DynamicPropertyContainer],SVGFillStyleData),extendPrototype([DynamicPropertyContainer],SVGNoStyleData),GradientProperty.prototype.comparePoints=function(t,e){for(var i=0,r=this.o.length/2;i<r;){if(Math.abs(t[4*i]-t[4*e+2*i])>.01)return!1;i+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},GradientProperty.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,i,r,s=4*this.data.p;for(e=0;e<s;e+=1)i=e%4==0?100:255,r=Math.round(this.prop.v[e]*i),this.c[e]!==r&&(this.c[e]=r,this._cmdf=!t);if(this.o.length)for(s=this.prop.v.length,e=4*this.data.p;e<s;e+=1)i=e%2==0?100:1,r=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==r&&(this.o[e-4*this.data.p]=r,this._omdf=!t);this._mdf=!t}},extendPrototype([DynamicPropertyContainer],GradientProperty),SVGGradientFillStyleData.prototype.initGradientData=function(t,e,i){this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.s=PropertyFactory.getProp(t,e.s,1,null,this),this.e=PropertyFactory.getProp(t,e.e,1,null,this),this.h=PropertyFactory.getProp(t,e.h||{k:0},0,.01,this),this.a=PropertyFactory.getProp(t,e.a||{k:0},0,degToRads,this),this.g=new GradientProperty(t,e.g,this),this.style=i,this.stops=[],this.setGradientData(i.pElem,e),this.setGradientOpacity(e,i),this._isAnimated=!!this._isAnimated},SVGGradientFillStyleData.prototype.setGradientData=function(t,e){var i=createElementID(),r=createNS(1===e.t?"linearGradient":"radialGradient");r.setAttribute("id",i),r.setAttribute("spreadMethod","pad"),r.setAttribute("gradientUnits","userSpaceOnUse");var s,a,n,o=[];for(n=4*e.g.p,a=0;a<n;a+=4)s=createNS("stop"),r.appendChild(s),o.push(s);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+getLocationHref()+"#"+i+")"),this.gf=r,this.cst=o},SVGGradientFillStyleData.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){var i,r,s,a=createNS("mask"),n=createNS("path");a.appendChild(n);var o=createElementID(),h=createElementID();a.setAttribute("id",h);var l=createNS(1===t.t?"linearGradient":"radialGradient");l.setAttribute("id",o),l.setAttribute("spreadMethod","pad"),l.setAttribute("gradientUnits","userSpaceOnUse"),s=t.g.k.k[0].s?t.g.k.k[0].s.length:t.g.k.k.length;var p=this.stops;for(r=4*t.g.p;r<s;r+=2)(i=createNS("stop")).setAttribute("stop-color","rgb(255,255,255)"),l.appendChild(i),p.push(i);n.setAttribute("gf"===t.ty?"fill":"stroke","url("+getLocationHref()+"#"+o+")"),"gs"===t.ty&&(n.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),n.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),1===t.lj&&n.setAttribute("stroke-miterlimit",t.ml)),this.of=l,this.ms=a,this.ost=p,this.maskId=h,e.msElem=n}},extendPrototype([DynamicPropertyContainer],SVGGradientFillStyleData),extendPrototype([SVGGradientFillStyleData,DynamicPropertyContainer],SVGGradientStrokeStyleData);var buildShapeString=function(t,e,i,r){if(0===e)return"";var s,a=t.o,n=t.i,o=t.v,h=" M"+r.applyToPointStringified(o[0][0],o[0][1]);for(s=1;s<e;s+=1)h+=" C"+r.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+r.applyToPointStringified(n[s][0],n[s][1])+" "+r.applyToPointStringified(o[s][0],o[s][1]);return i&&e&&(h+=" C"+r.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+r.applyToPointStringified(n[0][0],n[0][1])+" "+r.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},SVGElementsRenderer=function(){var t=new Matrix,e=new Matrix;function i(t,e,i){(i||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(i||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function r(){}function s(i,r,s){var a,n,o,h,l,p,f,c,m,d,u=r.styles.length,y=r.lvl;for(p=0;p<u;p+=1){if(h=r.sh._mdf||s,r.styles[p].lvl<y){for(c=e.reset(),m=y-r.styles[p].lvl,d=r.transformers.length-1;!h&&m>0;)h=r.transformers[d].mProps._mdf||h,m-=1,d-=1;if(h)for(m=y-r.styles[p].lvl,d=r.transformers.length-1;m>0;)c.multiply(r.transformers[d].mProps.v),m-=1,d-=1}else c=t;if(n=(f=r.sh.paths)._length,h){for(o="",a=0;a<n;a+=1)(l=f.shapes[a])&&l._length&&(o+=buildShapeString(l,l._length,l.c,c));r.caches[p]=o}else o=r.caches[p];r.styles[p].d+=!0===i.hd?"":o,r.styles[p]._mdf=h||r.styles[p]._mdf}}function a(t,e,i){var r=e.style;(e.c._mdf||i)&&r.pElem.setAttribute("fill","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("fill-opacity",e.o.v)}function n(t,e,i){o(t,e,i),h(t,e,i)}function o(t,e,i){var r,s,a,n,o,h=e.gf,l=e.g._hasOpacity,p=e.s.v,f=e.e.v;if(e.o._mdf||i){var c="gf"===t.ty?"fill-opacity":"stroke-opacity";e.style.pElem.setAttribute(c,e.o.v)}if(e.s._mdf||i){var m=1===t.t?"x1":"cx",d="x1"===m?"y1":"cy";h.setAttribute(m,p[0]),h.setAttribute(d,p[1]),l&&!e.g._collapsable&&(e.of.setAttribute(m,p[0]),e.of.setAttribute(d,p[1]))}if(e.g._cmdf||i){r=e.cst;var u=e.g.c;for(a=r.length,s=0;s<a;s+=1)(n=r[s]).setAttribute("offset",u[4*s]+"%"),n.setAttribute("stop-color","rgb("+u[4*s+1]+","+u[4*s+2]+","+u[4*s+3]+")")}if(l&&(e.g._omdf||i)){var y=e.g.o;for(a=(r=e.g._collapsable?e.cst:e.ost).length,s=0;s<a;s+=1)n=r[s],e.g._collapsable||n.setAttribute("offset",y[2*s]+"%"),n.setAttribute("stop-opacity",y[2*s+1])}if(1===t.t)(e.e._mdf||i)&&(h.setAttribute("x2",f[0]),h.setAttribute("y2",f[1]),l&&!e.g._collapsable&&(e.of.setAttribute("x2",f[0]),e.of.setAttribute("y2",f[1])));else if((e.s._mdf||e.e._mdf||i)&&(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)),h.setAttribute("r",o),l&&!e.g._collapsable&&e.of.setAttribute("r",o)),e.e._mdf||e.h._mdf||e.a._mdf||i){o||(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)));var g=Math.atan2(f[1]-p[1],f[0]-p[0]),v=e.h.v;v>=1?v=.99:v<=-1&&(v=-.99);var P=o*v,b=Math.cos(g+e.a.v)*P+p[0],x=Math.sin(g+e.a.v)*P+p[1];h.setAttribute("fx",b),h.setAttribute("fy",x),l&&!e.g._collapsable&&(e.of.setAttribute("fx",b),e.of.setAttribute("fy",x))}}function h(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||i)&&s.dashStr&&(r.pElem.setAttribute("stroke-dasharray",s.dashStr),r.pElem.setAttribute("stroke-dashoffset",s.dashoffset[0])),e.c&&(e.c._mdf||i)&&r.pElem.setAttribute("stroke","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||i)&&(r.pElem.setAttribute("stroke-width",e.w.v),r.msElem&&r.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function(t){switch(t.ty){case"fl":return a;case"gf":return o;case"gs":return n;case"st":return h;case"sh":case"el":case"rc":case"sr":return s;case"tr":return i;case"no":return r;default:return null}}}}();function SVGShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,i),this.prevViewData=[]}function LetterProps(t,e,i,r,s,a){this.o=t,this.sw=e,this.sc=i,this.fc=r,this.m=s,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!i,fc:!!r,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){var t,e,i,r,s=this.shapes.length,a=this.stylesList.length,n=[],o=!1;for(i=0;i<a;i+=1){for(r=this.stylesList[i],o=!1,n.length=0,t=0;t<s;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(r)&&(n.push(e),o=e._isAnimated||o);n.length>1&&o&&this.setShapesAsAnimated(n)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].setAsAnimated()},SVGShapeElement.prototype.createStyleElement=function(t,e){var i,r=new SVGStyleData(t,e),s=r.pElem;if("st"===t.ty)i=new SVGStrokeStyleData(this,t,r);else if("fl"===t.ty)i=new SVGFillStyleData(this,t,r);else if("gf"===t.ty||"gs"===t.ty){i=new("gf"===t.ty?SVGGradientFillStyleData:SVGGradientStrokeStyleData)(this,t,r),this.globalData.defs.appendChild(i.gf),i.maskId&&(this.globalData.defs.appendChild(i.ms),this.globalData.defs.appendChild(i.of),s.setAttribute("mask","url("+getLocationHref()+"#"+i.maskId+")"))}else"no"===t.ty&&(i=new SVGNoStyleData(this,t,r));return"st"!==t.ty&&"gs"!==t.ty||(s.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),s.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),s.setAttribute("fill-opacity","0"),1===t.lj&&s.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&s.setAttribute("fill-rule","evenodd"),t.ln&&s.setAttribute("id",t.ln),t.cl&&s.setAttribute("class",t.cl),t.bm&&(s.style["mix-blend-mode"]=getBlendMode(t.bm)),this.stylesList.push(r),this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createGroupElement=function(t){var e=new ShapeGroupData;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=getBlendMode(t.bm)),e},SVGShapeElement.prototype.createTransformElement=function(t,e){var i=TransformPropertyFactory.getTransformProperty(this,t,this),r=new SVGTransformData(i,i.o,e);return this.addToAnimatedContents(t,r),r},SVGShapeElement.prototype.createShapeElement=function(t,e,i){var r=4;"rc"===t.ty?r=5:"el"===t.ty?r=6:"sr"===t.ty&&(r=7);var s=new SVGShapeData(e,i,ShapePropertyFactory.getShapeProp(this,t,r,this));return this.shapes.push(s),this.addShapeToModifiers(s),this.addToAnimatedContents(t,s),s},SVGShapeElement.prototype.addToAnimatedContents=function(t,e){for(var i=0,r=this.animatedContents.length;i<r;){if(this.animatedContents[i].element===e)return;i+=1}this.animatedContents.push({fn:SVGElementsRenderer.createRenderFunction(t),element:e,data:t})},SVGShapeElement.prototype.setElementStyles=function(t){var e,i=t.styles,r=this.stylesList.length;for(e=0;e<r;e+=1)this.stylesList[e].closed||i.push(this.stylesList[e])},SVGShapeElement.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},SVGShapeElement.prototype.searchShapes=function(t,e,i,r,s,a,n){var o,h,l,p,f,c,m=[].concat(a),d=t.length-1,u=[],y=[];for(o=d;o>=0;o-=1){if((c=this.searchProcessedElement(t[o]))?e[o]=i[c-1]:t[o]._render=n,"fl"===t[o].ty||"st"===t[o].ty||"gf"===t[o].ty||"gs"===t[o].ty||"no"===t[o].ty)c?e[o].style.closed=!1:e[o]=this.createStyleElement(t[o],s),t[o]._render&&e[o].style.pElem.parentNode!==r&&r.appendChild(e[o].style.pElem),u.push(e[o].style);else if("gr"===t[o].ty){if(c)for(l=e[o].it.length,h=0;h<l;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,s+1,m,n),t[o]._render&&e[o].gr.parentNode!==r&&r.appendChild(e[o].gr)}else"tr"===t[o].ty?(c||(e[o]=this.createTransformElement(t[o],r)),p=e[o].transform,m.push(p)):"sh"===t[o].ty||"rc"===t[o].ty||"el"===t[o].ty||"sr"===t[o].ty?(c||(e[o]=this.createShapeElement(t[o],m,s)),this.setElementStyles(e[o])):"tm"===t[o].ty||"rd"===t[o].ty||"ms"===t[o].ty||"pb"===t[o].ty||"zz"===t[o].ty||"op"===t[o].ty?(c?(f=e[o]).closed=!1:((f=ShapeModifiers.getModifier(t[o].ty)).init(this,t[o]),e[o]=f,this.shapeModifiers.push(f)),y.push(f)):"rp"===t[o].ty&&(c?(f=e[o]).closed=!0:(f=ShapeModifiers.getModifier(t[o].ty),e[o]=f,f.init(this,t,o,e),this.shapeModifiers.push(f),n=!1),y.push(f));this.addProcessedElement(t[o],o+1)}for(d=u.length,o=0;o<d;o+=1)u[o].closed=!0;for(d=y.length,o=0;o<d;o+=1)y[o].closed=!0},SVGShapeElement.prototype.renderInnerContent=function(){var t;this.renderModifiers();var e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},SVGShapeElement.prototype.renderShape=function(){var t,e,i=this.animatedContents.length;for(t=0;t<i;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},SVGShapeElement.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},LetterProps.prototype.update=function(t,e,i,r,s,a){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1,this._mdf.p=!1;var n=!1;return this.o!==t&&(this.o=t,this._mdf.o=!0,n=!0),this.sw!==e&&(this.sw=e,this._mdf.sw=!0,n=!0),this.sc!==i&&(this.sc=i,this._mdf.sc=!0,n=!0),this.fc!==r&&(this.fc=r,this._mdf.fc=!0,n=!0),this.m!==s&&(this.m=s,this._mdf.m=!0,n=!0),!a.length||this.p[0]===a[0]&&this.p[1]===a[1]&&this.p[4]===a[4]&&this.p[5]===a[5]&&this.p[12]===a[12]&&this.p[13]===a[13]||(this.p=a,this._mdf.p=!0,n=!0),n},TextProperty.prototype.defaultBoxWidth=[0,0],TextProperty.prototype.copyData=function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},TextProperty.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},TextProperty.prototype.searchProperty=function(){return this.searchKeyframes()},TextProperty.prototype.searchKeyframes=function(){return this.kf=this.data.d.k.length>1,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,i=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{var r;this.lock=!0,this._mdf=!1;var s=this.effectsSequence.length,a=t||this.data.d.k[this.keysIndex].s;for(r=0;r<s;r+=1)a=i!==this.keysIndex?this.effectsSequence[r](a,a.t):this.effectsSequence[r](this.currentData,a.t);e!==a&&this.setCurrentData(a),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},TextProperty.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,i=0,r=t.length;i<=r-1&&!(i===r-1||t[i+1].t>e);)i+=1;return this.keysIndex!==i&&(this.keysIndex=i),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e,i,r=[],s=0,a=t.length,n=!1,o=!1,h="";s<a;)n=o,o=!1,e=t.charCodeAt(s),h=t.charAt(s),FontManager.isCombinedCharacter(e)?n=!0:e>=55296&&e<=56319?FontManager.isRegionalFlag(t,s)?h=t.substr(s,14):(i=t.charCodeAt(s+1))>=56320&&i<=57343&&(FontManager.isModifier(e,i)?(h=t.substr(s,2),n=!0):h=FontManager.isFlagEmoji(t.substr(s,4))?t.substr(s,4):t.substr(s,2)):e>56319?(i=t.charCodeAt(s+1),FontManager.isVariationSelector(e)&&(n=!0)):FontManager.isZeroWidthJoiner(e)&&(n=!0,o=!0),n?(r[r.length-1]+=h,n=!1):r.push(h),s+=h.length;return r},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,i,r,s,a,n,o,h=this.elem.globalData.fontManager,l=this.data,p=[],f=0,c=l.m.g,m=0,d=0,u=0,y=[],g=0,v=0,P=h.getFontByName(t.f),b=0,x=getFontProperties(P);t.fWeight=x.weight,t.fStyle=x.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),i=t.finalText.length,t.finalLineHeight=t.lh;var S,C=t.tr/1e3*t.finalSize;if(t.sz)for(var E,_,T=!0,A=t.sz[0],D=t.sz[1];T;){E=0,g=0,i=(_=this.buildFinalText(t.t)).length,C=t.tr/1e3*t.finalSize;var k=-1;for(e=0;e<i;e+=1)S=_[e].charCodeAt(0),r=!1," "===_[e]?k=e:13!==S&&3!==S||(g=0,r=!0,E+=t.finalLineHeight||1.2*t.finalSize),h.chars?(o=h.getCharData(_[e],P.fStyle,P.fFamily),b=r?0:o.w*t.finalSize/100):b=h.measureText(_[e],t.f,t.finalSize),g+b>A&&" "!==_[e]?(-1===k?i+=1:e=k,E+=t.finalLineHeight||1.2*t.finalSize,_.splice(e,k===e?1:0,"\r"),k=-1,g=0):(g+=b,g+=C);E+=P.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&D<E?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=_,i=t.finalText.length,T=!1)}g=-C,b=0;var M,I=0;for(e=0;e<i;e+=1)if(r=!1,13===(S=(M=t.finalText[e]).charCodeAt(0))||3===S?(I=0,y.push(g),v=g>v?g:v,g=-2*C,s="",r=!0,u+=1):s=M,h.chars?(o=h.getCharData(M,P.fStyle,h.getFontByName(t.f).fFamily),b=r?0:o.w*t.finalSize/100):b=h.measureText(s,t.f,t.finalSize)," "===M?I+=b+C:(g+=b+C+I,I=0),p.push({l:b,an:b,add:m,n:r,anIndexes:[],val:s,line:u,animatorJustifyOffset:0}),2==c){if(m+=b,""===s||" "===s||e===i-1){for(""!==s&&" "!==s||(m-=b);d<=e;)p[d].an=m,p[d].ind=f,p[d].extra=b,d+=1;f+=1,m=0}}else if(3==c){if(m+=b,""===s||e===i-1){for(""===s&&(m-=b);d<=e;)p[d].an=m,p[d].ind=f,p[d].extra=b,d+=1;m=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=g>v?g:v,y.push(g),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=y;var F,w,V,L,R=l.a;n=R.length;var B=[];for(a=0;a<n;a+=1){for((F=R[a]).a.sc&&(t.strokeColorAnim=!0),F.a.sw&&(t.strokeWidthAnim=!0),(F.a.fc||F.a.fh||F.a.fs||F.a.fb)&&(t.fillColorAnim=!0),L=0,V=F.s.b,e=0;e<i;e+=1)(w=p[e]).anIndexes[a]=L,(1==V&&""!==w.val||2==V&&""!==w.val&&" "!==w.val||3==V&&(w.n||" "==w.val||e==i-1)||4==V&&(w.n||e==i-1))&&(1===F.s.rn&&B.push(L),L+=1);l.a[a].s.totalChars=L;var O,z=-1;if(1===F.s.rn)for(e=0;e<i;e+=1)z!=(w=p[e]).anIndexes[a]&&(z=w.anIndexes[a],O=B.splice(Math.floor(Math.random()*B.length),1)[0]),w.anIndexes[a]=O}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=P.ascent*t.finalSize/100},TextProperty.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var i=this.copyData({},this.data.d.k[e].s);i=this.copyData(i,t),this.data.d.k[e].s=i,this.recalculate(e),this.setCurrentData(i),this.elem.addDynamicProperty(this)},TextProperty.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},TextProperty.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},TextProperty.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var TextSelectorProp=function(){var t=Math.max,e=Math.min,i=Math.floor;function r(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=PropertyFactory.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?PropertyFactory.getProp(t,e.e,0,0,this):{v:100},this.o=PropertyFactory.getProp(t,e.o||{k:0},0,0,this),this.xe=PropertyFactory.getProp(t,e.xe||{k:0},0,0,this),this.ne=PropertyFactory.getProp(t,e.ne||{k:0},0,0,this),this.sm=PropertyFactory.getProp(t,e.sm||{k:100},0,0,this),this.a=PropertyFactory.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return r.prototype={getMult:function(r){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var s=0,a=0,n=1,o=1;this.ne.v>0?s=this.ne.v/100:a=-this.ne.v/100,this.xe.v>0?n=1-this.xe.v/100:o=1+this.xe.v/100;var h=BezierFactory.getBezierEasing(s,a,n,o).get,l=0,p=this.finalS,f=this.finalE,c=this.data.sh;if(2===c)l=h(l=f===p?r>=f?1:0:t(0,e(.5/(f-p)+(r-p)/(f-p),1)));else if(3===c)l=h(l=f===p?r>=f?0:1:1-t(0,e(.5/(f-p)+(r-p)/(f-p),1)));else if(4===c)f===p?l=0:(l=t(0,e(.5/(f-p)+(r-p)/(f-p),1)))<.5?l*=2:l=1-2*(l-.5),l=h(l);else if(5===c){if(f===p)l=0;else{var m=f-p,d=-m/2+(r=e(t(0,r+.5-p),f-p)),u=m/2;l=Math.sqrt(1-d*d/(u*u))}l=h(l)}else 6===c?(f===p?l=0:(r=e(t(0,r+.5-p),f-p),l=(1+Math.cos(Math.PI+2*Math.PI*r/(f-p)))/2),l=h(l)):(r>=i(p)&&(l=t(0,e(r-p<0?e(f,1)-(p-r):f-r,1))),l=h(l));if(100!==this.sm.v){var y=.01*this.sm.v;0===y&&(y=1e-8);var g=.5-.5*y;l<g?l=0:(l=(l-g)/y)>1&&(l=1)}return l*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,i=this.o.v/e,r=this.s.v/e+i,s=this.e.v/e+i;if(r>s){var a=r;r=s,s=a}this.finalS=r,this.finalE=s}},extendPrototype([DynamicPropertyContainer],r),{getTextSelectorProp:function(t,e,i){return new r(t,e,i)}}}();function TextAnimatorDataProperty(t,e,i){var r={propType:!1},s=PropertyFactory.getProp,a=e.a;this.a={r:a.r?s(t,a.r,0,degToRads,i):r,rx:a.rx?s(t,a.rx,0,degToRads,i):r,ry:a.ry?s(t,a.ry,0,degToRads,i):r,sk:a.sk?s(t,a.sk,0,degToRads,i):r,sa:a.sa?s(t,a.sa,0,degToRads,i):r,s:a.s?s(t,a.s,1,.01,i):r,a:a.a?s(t,a.a,1,0,i):r,o:a.o?s(t,a.o,0,.01,i):r,p:a.p?s(t,a.p,1,0,i):r,sw:a.sw?s(t,a.sw,0,0,i):r,sc:a.sc?s(t,a.sc,1,0,i):r,fc:a.fc?s(t,a.fc,1,0,i):r,fh:a.fh?s(t,a.fh,0,0,i):r,fs:a.fs?s(t,a.fs,0,.01,i):r,fb:a.fb?s(t,a.fb,0,.01,i):r,t:a.t?s(t,a.t,0,0,i):r},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,i),this.s.t=e.s.t}function TextAnimatorProperty(t,e,i){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=i,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(i)}function ITextElement(){}TextAnimatorProperty.prototype.searchProperties=function(){var t,e,i=this._textData.a.length,r=PropertyFactory.getProp;for(t=0;t<i;t+=1)e=this._textData.a[t],this._animatorsData[t]=new TextAnimatorDataProperty(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:r(this._elem,this._textData.p.a,0,0,this),f:r(this._elem,this._textData.p.f,0,0,this),l:r(this._elem,this._textData.p.l,0,0,this),r:r(this._elem,this._textData.p.r,0,0,this),p:r(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=r(this._elem,this._textData.m.a,1,0,this)},TextAnimatorProperty.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var i,r,s,a,n,o,h,l,p,f,c,m,d,u,y,g,v,P,b,x=this._moreOptions.alignment.v,S=this._animatorsData,C=this._textData,E=this.mHelper,_=this._renderType,T=this.renderedLetters.length,A=t.l;if(this._hasMaskedPath){if(b=this._pathData.m,!this._pathData.n||this._pathData._mdf){var D,k=b.v;for(this._pathData.r.v&&(k=k.reverse()),n={tLength:0,segments:[]},a=k._length-1,g=0,s=0;s<a;s+=1)D=bez.buildBezierData(k.v[s],k.v[s+1],[k.o[s][0]-k.v[s][0],k.o[s][1]-k.v[s][1]],[k.i[s+1][0]-k.v[s+1][0],k.i[s+1][1]-k.v[s+1][1]]),n.tLength+=D.segmentLength,n.segments.push(D),g+=D.segmentLength;s=a,b.v.c&&(D=bez.buildBezierData(k.v[s],k.v[0],[k.o[s][0]-k.v[s][0],k.o[s][1]-k.v[s][1]],[k.i[0][0]-k.v[0][0],k.i[0][1]-k.v[0][1]]),n.tLength+=D.segmentLength,n.segments.push(D),g+=D.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,c=0,f=1,l=0,p=!0,u=n.segments,o<0&&b.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),f=(d=u[c=u.length-1].points).length-1;o<0;)o+=d[f].partialLength,(f-=1)<0&&(f=(d=u[c-=1].points).length-1);m=(d=u[c].points)[f-1],y=(h=d[f]).partialLength}a=A.length,i=0,r=0;var M,I,F,w,V,L=1.2*t.finalSize*.714,R=!0;F=S.length;var B,O,z,G,N,j,q,W,H,$,J,Y,X=-1,Z=o,K=c,U=f,Q=-1,tt="",et=this.defaultPropsArray;if(2===t.j||1===t.j){var it=0,rt=0,st=2===t.j?-.5:-1,at=0,nt=!0;for(s=0;s<a;s+=1)if(A[s].n){for(it&&(it+=rt);at<s;)A[at].animatorJustifyOffset=it,at+=1;it=0,nt=!0}else{for(I=0;I<F;I+=1)(M=S[I].a).t.propType&&(nt&&2===t.j&&(rt+=M.t.v*st),(V=S[I].s.getMult(A[s].anIndexes[I],C.a[I].s.totalChars)).length?it+=M.t.v*V[0]*st:it+=M.t.v*V*st);nt=!1}for(it&&(it+=rt);at<s;)A[at].animatorJustifyOffset=it,at+=1}for(s=0;s<a;s+=1){if(E.reset(),G=1,A[s].n)i=0,r+=t.yOffset,r+=R?1:0,o=Z,R=!1,this._hasMaskedPath&&(f=U,m=(d=u[c=K].points)[f-1],y=(h=d[f]).partialLength,l=0),tt="",J="",H="",Y="",et=this.defaultPropsArray;else{if(this._hasMaskedPath){if(Q!==A[s].line){switch(t.j){case 1:o+=g-t.lineWidths[A[s].line];break;case 2:o+=(g-t.lineWidths[A[s].line])/2}Q=A[s].line}X!==A[s].ind&&(A[X]&&(o+=A[X].extra),o+=A[s].an/2,X=A[s].ind),o+=x[0]*A[s].an*.005;var ot=0;for(I=0;I<F;I+=1)(M=S[I].a).p.propType&&((V=S[I].s.getMult(A[s].anIndexes[I],C.a[I].s.totalChars)).length?ot+=M.p.v[0]*V[0]:ot+=M.p.v[0]*V),M.a.propType&&((V=S[I].s.getMult(A[s].anIndexes[I],C.a[I].s.totalChars)).length?ot+=M.a.v[0]*V[0]:ot+=M.a.v[0]*V);for(p=!0,this._pathData.a.v&&(o=.5*A[0].an+(g-this._pathData.f.v-.5*A[0].an-.5*A[A.length-1].an)*X/(a-1),o+=this._pathData.f.v);p;)l+y>=o+ot||!d?(v=(o+ot-l)/h.partialLength,O=m.point[0]+(h.point[0]-m.point[0])*v,z=m.point[1]+(h.point[1]-m.point[1])*v,E.translate(-x[0]*A[s].an*.005,-x[1]*L*.01),p=!1):d&&(l+=h.partialLength,(f+=1)>=d.length&&(f=0,u[c+=1]?d=u[c].points:b.v.c?(f=0,d=u[c=0].points):(l-=h.partialLength,d=null)),d&&(m=h,y=(h=d[f]).partialLength));B=A[s].an/2-A[s].add,E.translate(-B,0,0)}else B=A[s].an/2-A[s].add,E.translate(-B,0,0),E.translate(-x[0]*A[s].an*.005,-x[1]*L*.01,0);for(I=0;I<F;I+=1)(M=S[I].a).t.propType&&(V=S[I].s.getMult(A[s].anIndexes[I],C.a[I].s.totalChars),0===i&&0===t.j||(this._hasMaskedPath?V.length?o+=M.t.v*V[0]:o+=M.t.v*V:V.length?i+=M.t.v*V[0]:i+=M.t.v*V));for(t.strokeWidthAnim&&(j=t.sw||0),t.strokeColorAnim&&(N=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(q=[t.fc[0],t.fc[1],t.fc[2]]),I=0;I<F;I+=1)(M=S[I].a).a.propType&&((V=S[I].s.getMult(A[s].anIndexes[I],C.a[I].s.totalChars)).length?E.translate(-M.a.v[0]*V[0],-M.a.v[1]*V[1],M.a.v[2]*V[2]):E.translate(-M.a.v[0]*V,-M.a.v[1]*V,M.a.v[2]*V));for(I=0;I<F;I+=1)(M=S[I].a).s.propType&&((V=S[I].s.getMult(A[s].anIndexes[I],C.a[I].s.totalChars)).length?E.scale(1+(M.s.v[0]-1)*V[0],1+(M.s.v[1]-1)*V[1],1):E.scale(1+(M.s.v[0]-1)*V,1+(M.s.v[1]-1)*V,1));for(I=0;I<F;I+=1){if(M=S[I].a,V=S[I].s.getMult(A[s].anIndexes[I],C.a[I].s.totalChars),M.sk.propType&&(V.length?E.skewFromAxis(-M.sk.v*V[0],M.sa.v*V[1]):E.skewFromAxis(-M.sk.v*V,M.sa.v*V)),M.r.propType&&(V.length?E.rotateZ(-M.r.v*V[2]):E.rotateZ(-M.r.v*V)),M.ry.propType&&(V.length?E.rotateY(M.ry.v*V[1]):E.rotateY(M.ry.v*V)),M.rx.propType&&(V.length?E.rotateX(M.rx.v*V[0]):E.rotateX(M.rx.v*V)),M.o.propType&&(V.length?G+=(M.o.v*V[0]-G)*V[0]:G+=(M.o.v*V-G)*V),t.strokeWidthAnim&&M.sw.propType&&(V.length?j+=M.sw.v*V[0]:j+=M.sw.v*V),t.strokeColorAnim&&M.sc.propType)for(W=0;W<3;W+=1)V.length?N[W]+=(M.sc.v[W]-N[W])*V[0]:N[W]+=(M.sc.v[W]-N[W])*V;if(t.fillColorAnim&&t.fc){if(M.fc.propType)for(W=0;W<3;W+=1)V.length?q[W]+=(M.fc.v[W]-q[W])*V[0]:q[W]+=(M.fc.v[W]-q[W])*V;M.fh.propType&&(q=V.length?addHueToRGB(q,M.fh.v*V[0]):addHueToRGB(q,M.fh.v*V)),M.fs.propType&&(q=V.length?addSaturationToRGB(q,M.fs.v*V[0]):addSaturationToRGB(q,M.fs.v*V)),M.fb.propType&&(q=V.length?addBrightnessToRGB(q,M.fb.v*V[0]):addBrightnessToRGB(q,M.fb.v*V))}}for(I=0;I<F;I+=1)(M=S[I].a).p.propType&&(V=S[I].s.getMult(A[s].anIndexes[I],C.a[I].s.totalChars),this._hasMaskedPath?V.length?E.translate(0,M.p.v[1]*V[0],-M.p.v[2]*V[1]):E.translate(0,M.p.v[1]*V,-M.p.v[2]*V):V.length?E.translate(M.p.v[0]*V[0],M.p.v[1]*V[1],-M.p.v[2]*V[2]):E.translate(M.p.v[0]*V,M.p.v[1]*V,-M.p.v[2]*V));if(t.strokeWidthAnim&&(H=j<0?0:j),t.strokeColorAnim&&($="rgb("+Math.round(255*N[0])+","+Math.round(255*N[1])+","+Math.round(255*N[2])+")"),t.fillColorAnim&&t.fc&&(J="rgb("+Math.round(255*q[0])+","+Math.round(255*q[1])+","+Math.round(255*q[2])+")"),this._hasMaskedPath){if(E.translate(0,-t.ls),E.translate(0,x[1]*L*.01+r,0),this._pathData.p.v){P=(h.point[1]-m.point[1])/(h.point[0]-m.point[0]);var ht=180*Math.atan(P)/Math.PI;h.point[0]<m.point[0]&&(ht+=180),E.rotate(-ht*Math.PI/180)}E.translate(O,z,0),o-=x[0]*A[s].an*.005,A[s+1]&&X!==A[s+1].ind&&(o+=A[s].an/2,o+=.001*t.tr*t.finalSize)}else{switch(E.translate(i,r,0),t.ps&&E.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:E.translate(A[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[A[s].line]),0,0);break;case 2:E.translate(A[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[A[s].line])/2,0,0)}E.translate(0,-t.ls),E.translate(B,0,0),E.translate(x[0]*A[s].an*.005,x[1]*L*.01,0),i+=A[s].l+.001*t.tr*t.finalSize}"html"===_?tt=E.toCSS():"svg"===_?tt=E.to2dCSS():et=[E.props[0],E.props[1],E.props[2],E.props[3],E.props[4],E.props[5],E.props[6],E.props[7],E.props[8],E.props[9],E.props[10],E.props[11],E.props[12],E.props[13],E.props[14],E.props[15]],Y=G}T<=s?(w=new LetterProps(Y,H,$,J,tt,et),this.renderedLetters.push(w),T+=1,this.lettersChangedFlag=!0):(w=this.renderedLetters[s],this.lettersChangedFlag=w.update(Y,H,$,J,tt,et)||this.lettersChangedFlag)}}},TextAnimatorProperty.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},TextAnimatorProperty.prototype.mHelper=new Matrix,TextAnimatorProperty.prototype.defaultPropsArray=[],extendPrototype([DynamicPropertyContainer],TextAnimatorProperty),ITextElement.prototype.initElement=function(t,e,i){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,i),this.textProperty=new TextProperty(this,t.t,this.dynamicProperties),this.textAnimator=new TextAnimatorProperty(t.t,this.renderType,this),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},ITextElement.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},ITextElement.prototype.createPathShape=function(t,e){var i,r,s=e.length,a="";for(i=0;i<s;i+=1)"sh"===e[i].ty&&(r=e[i].ks.k,a+=buildShapeString(r,r.i.length,!0,t));return a},ITextElement.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},ITextElement.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},ITextElement.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},ITextElement.prototype.applyTextPropertiesToMatrix=function(t,e,i,r,s){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i])/2,0,0)}e.translate(r,s,0)},ITextElement.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},ITextElement.prototype.emptyProp=new LetterProps,ITextElement.prototype.destroy=function(){},ITextElement.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var emptyShapeData={shapes:[]};function SVGTextLottieElement(t,e,i){this.textSpans=[],this.renderType="svg",this.initElement(t,e,i)}function ISolidElement(t,e,i){this.initElement(t,e,i)}function NullElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initFrame(),this.initTransform(t,e,i),this.initHierarchy()}function SVGRendererBase(){}function ICompElement(){}function SVGCompElement(t,e,i){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function SVGRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=createNS("svg");var i="";if(e&&e.title){var r=createNS("title"),s=createElementID();r.setAttribute("id",s),r.textContent=e.title,this.svgElement.appendChild(r),i+=s}if(e&&e.description){var a=createNS("desc"),n=createElementID();a.setAttribute("id",n),a.textContent=e.description,this.svgElement.appendChild(a),i+=" "+n}i&&this.svgElement.setAttribute("aria-labelledby",i);var o=createNS("defs");this.svgElement.appendChild(o);var h=createNS("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}function ShapeTransformManager(){this.sequences={},this.sequenceList=[],this.transform_key_count=0}extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],SVGTextLottieElement),SVGTextLottieElement.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=createNS("text"))},SVGTextLottieElement.prototype.buildTextContents=function(t){for(var e=0,i=t.length,r=[],s="";e<i;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(r.push(s),s=""):s+=t[e],e+=1;return r.push(s),r},SVGTextLottieElement.prototype.buildShapeData=function(t,e){if(t.shapes&&t.shapes.length){var i=t.shapes[0];if(i.it){var r=i.it[i.it.length-1];r.s&&(r.s.k[0]=e,r.s.k[1]=e)}}return t},SVGTextLottieElement.prototype.buildNewText=function(){var t,e;this.addDynamicProperty(this);var i=this.textProperty.currentData;this.renderedLetters=createSizedArray(i?i.l.length:0),i.fc?this.layerElement.setAttribute("fill",this.buildColor(i.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),i.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(i.sc)),this.layerElement.setAttribute("stroke-width",i.sw)),this.layerElement.setAttribute("font-size",i.finalSize);var r=this.globalData.fontManager.getFontByName(i.f);if(r.fClass)this.layerElement.setAttribute("class",r.fClass);else{this.layerElement.setAttribute("font-family",r.fFamily);var s=i.fWeight,a=i.fStyle;this.layerElement.setAttribute("font-style",a),this.layerElement.setAttribute("font-weight",s)}this.layerElement.setAttribute("aria-label",i.t);var n,o=i.l||[],h=!!this.globalData.fontManager.chars;e=o.length;var l=this.mHelper,p=this.data.singleShape,f=0,c=0,m=!0,d=.001*i.tr*i.finalSize;if(!p||h||i.sz){var u,y=this.textSpans.length;for(t=0;t<e;t+=1){if(this.textSpans[t]||(this.textSpans[t]={span:null,childSpan:null,glyph:null}),!h||!p||0===t){if(n=y>t?this.textSpans[t].span:createNS(h?"g":"text"),y<=t){if(n.setAttribute("stroke-linecap","butt"),n.setAttribute("stroke-linejoin","round"),n.setAttribute("stroke-miterlimit","4"),this.textSpans[t].span=n,h){var g=createNS("g");n.appendChild(g),this.textSpans[t].childSpan=g}this.textSpans[t].span=n,this.layerElement.appendChild(n)}n.style.display="inherit"}if(l.reset(),p&&(o[t].n&&(f=-d,c+=i.yOffset,c+=m?1:0,m=!1),this.applyTextPropertiesToMatrix(i,l,o[t].line,f,c),f+=o[t].l||0,f+=d),h){var v;if(1===(u=this.globalData.fontManager.getCharData(i.finalText[t],r.fStyle,this.globalData.fontManager.getFontByName(i.f).fFamily)).t)v=new SVGCompElement(u.data,this.globalData,this);else{var P=emptyShapeData;u.data&&u.data.shapes&&(P=this.buildShapeData(u.data,i.finalSize)),v=new SVGShapeElement(P,this.globalData,this)}if(this.textSpans[t].glyph){var b=this.textSpans[t].glyph;this.textSpans[t].childSpan.removeChild(b.layerElement),b.destroy()}this.textSpans[t].glyph=v,v._debug=!0,v.prepareFrame(0),v.renderFrame(),this.textSpans[t].childSpan.appendChild(v.layerElement),1===u.t&&this.textSpans[t].childSpan.setAttribute("transform","scale("+i.finalSize/100+","+i.finalSize/100+")")}else p&&n.setAttribute("transform","translate("+l.props[12]+","+l.props[13]+")"),n.textContent=o[t].val,n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}p&&n&&n.setAttribute("d","")}else{var x=this.textContainer,S="start";switch(i.j){case 1:S="end";break;case 2:S="middle";break;default:S="start"}x.setAttribute("text-anchor",S),x.setAttribute("letter-spacing",d);var C=this.buildTextContents(i.finalText);for(e=C.length,c=i.ps?i.ps[1]+i.ascent:0,t=0;t<e;t+=1)(n=this.textSpans[t].span||createNS("tspan")).textContent=C[t],n.setAttribute("x",0),n.setAttribute("y",c),n.style.display="inherit",x.appendChild(n),this.textSpans[t]||(this.textSpans[t]={span:null,glyph:null}),this.textSpans[t].span=n,c+=i.finalLineHeight;this.layerElement.appendChild(x)}for(;t<this.textSpans.length;)this.textSpans[t].span.style.display="none",t+=1;this._sizeChanged=!0},SVGTextLottieElement.prototype.sourceRectAtTime=function(){if(this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged){this._sizeChanged=!1;var t=this.layerElement.getBBox();this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}}return this.bbox},SVGTextLottieElement.prototype.getValue=function(){var t,e,i=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<i;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf&&(this._mdf=!0))},SVGTextLottieElement.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){var t,e;this._sizeChanged=!0;var i,r,s,a=this.textAnimator.renderedLetters,n=this.textProperty.currentData.l;for(e=n.length,t=0;t<e;t+=1)n[t].n||(i=a[t],r=this.textSpans[t].span,(s=this.textSpans[t].glyph)&&s.renderFrame(),i._mdf.m&&r.setAttribute("transform",i.m),i._mdf.o&&r.setAttribute("opacity",i.o),i._mdf.sw&&r.setAttribute("stroke-width",i.sw),i._mdf.sc&&r.setAttribute("stroke",i.sc),i._mdf.fc&&r.setAttribute("fill",i.fc))}},extendPrototype([IImageElement],ISolidElement),ISolidElement.prototype.createContent=function(){var t=createNS("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},NullElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},NullElement.prototype.renderFrame=function(){},NullElement.prototype.getBaseElement=function(){return null},NullElement.prototype.destroy=function(){},NullElement.prototype.sourceRectAtTime=function(){},NullElement.prototype.hide=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement],NullElement),extendPrototype([BaseRenderer],SVGRendererBase),SVGRendererBase.prototype.createNull=function(t){return new NullElement(t,this.globalData,this)},SVGRendererBase.prototype.createShape=function(t){return new SVGShapeElement(t,this.globalData,this)},SVGRendererBase.prototype.createText=function(t){return new SVGTextLottieElement(t,this.globalData,this)},SVGRendererBase.prototype.createImage=function(t){return new IImageElement(t,this.globalData,this)},SVGRendererBase.prototype.createSolid=function(t){return new ISolidElement(t,this.globalData,this)},SVGRendererBase.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var i=createNS("clipPath"),r=createNS("rect");r.setAttribute("width",t.w),r.setAttribute("height",t.h),r.setAttribute("x",0),r.setAttribute("y",0);var s=createElementID();i.setAttribute("id",s),i.appendChild(r),this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),e.appendChild(i),this.layers=t.layers,this.elements=createSizedArray(t.layers.length)},SVGRendererBase.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},SVGRendererBase.prototype.updateContainerSize=function(){},SVGRendererBase.prototype.findIndexByInd=function(t){var e=0,i=this.layers.length;for(e=0;e<i;e+=1)if(this.layers[e].ind===t)return e;return-1},SVGRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){e[t]=!0;var i=this.createItem(this.layers[t]);if(e[t]=i,getExpressionsPlugin()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(i),i.initExpressions()),this.appendElementInPos(i,t),this.layers[t].tt){var r="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1;if(-1===r)return;if(this.elements[r]&&!0!==this.elements[r]){var s=e[r].getMatte(this.layers[t].tt);i.setMatte(s)}else this.buildItem(r),this.addPendingElement(i)}}},SVGRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,i=this.elements.length;e<i;){if(this.elements[e]===t){var r="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,s=this.elements[r].getMatte(this.layers[e].tt);t.setMatte(s);break}e+=1}}},SVGRendererBase.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){var e;null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var i=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=i-1;e>=0;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<i;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},SVGRendererBase.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){for(var r,s=0;s<e;)this.elements[s]&&!0!==this.elements[s]&&this.elements[s].getBaseElement()&&(r=this.elements[s].getBaseElement()),s+=1;r?this.layerElement.insertBefore(i,r):this.layerElement.appendChild(i)}},SVGRendererBase.prototype.hide=function(){this.layerElement.style.display="none"},SVGRendererBase.prototype.show=function(){this.layerElement.style.display="block"},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement,RenderableDOMElement],ICompElement),ICompElement.prototype.initElement=function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},ICompElement.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var i,r=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),i=r-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&(this.elements[i].prepareFrame(this.renderedFrame-this.layers[i].st),this.elements[i]._mdf&&(this._mdf=!0))}},ICompElement.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},ICompElement.prototype.setElements=function(t){this.elements=t},ICompElement.prototype.getElements=function(){return this.elements},ICompElement.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},ICompElement.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},extendPrototype([SVGRendererBase,ICompElement,SVGBaseElement],SVGCompElement),SVGCompElement.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},extendPrototype([SVGRendererBase],SVGRenderer),SVGRenderer.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},ShapeTransformManager.prototype={addTransformSequence:function(t){var e,i=t.length,r="_";for(e=0;e<i;e+=1)r+=t[e].transform.key+"_";var s=this.sequences[r];return s||(s={transforms:[].concat(t),finalTransform:new Matrix,_mdf:!1},this.sequences[r]=s,this.sequenceList.push(s)),s},processSequence:function(t,e){for(var i=0,r=t.transforms.length,s=e;i<r&&!e;){if(t.transforms[i].transform.mProps._mdf){s=!0;break}i+=1}if(s)for(t.finalTransform.reset(),i=r-1;i>=0;i-=1)t.finalTransform.multiply(t.transforms[i].transform.mProps.v);t._mdf=s},processSequences:function(t){var e,i=this.sequenceList.length;for(e=0;e<i;e+=1)this.processSequence(this.sequenceList[e],t)},getNewKey:function(){return this.transform_key_count+=1,"_"+this.transform_key_count}};var lumaLoader=function(){var t="__lottie_element_luma_buffer",e=null,i=null,r=null;function s(){var s,a,n;e||(s=createNS("svg"),a=createNS("filter"),n=createNS("feColorMatrix"),a.setAttribute("id",t),n.setAttribute("type","matrix"),n.setAttribute("color-interpolation-filters","sRGB"),n.setAttribute("values","0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0"),a.appendChild(n),s.appendChild(a),s.setAttribute("id",t+"_svg"),featureSupport.svgLumaHidden&&(s.style.display="none"),r=s,document.body.appendChild(r),e=createTag("canvas"),(i=e.getContext("2d")).filter="url(#"+t+")",i.fillStyle="rgba(0,0,0,0)",i.fillRect(0,0,1,1))}return{load:s,get:function(r){return e||s(),e.width=r.width,e.height=r.height,i.filter="url(#"+t+")",e}}};function createCanvas(t,e){if(featureSupport.offscreenCanvas)return new OffscreenCanvas(t,e);var i=createTag("canvas");return i.width=t,i.height=e,i}var assetLoader={loadLumaCanvas:lumaLoader.load,getLumaCanvas:lumaLoader.get,createCanvas:createCanvas},registeredEffects={};function CVEffects(t){var e,i,r=t.data.ef?t.data.ef.length:0;for(this.filters=[],e=0;e<r;e+=1){i=null;var s=t.data.ef[e].ty;if(registeredEffects[s])i=new(0,registeredEffects[s].effect)(t.effectsManager.effectElements[e],t);i&&this.filters.push(i)}this.filters.length&&t.addRenderableComponent(this)}function registerEffect(t,e){registeredEffects[t]={effect:e}}function CVMaskElement(t,e){var i;this.data=t,this.element=e,this.masksProperties=this.data.masksProperties||[],this.viewData=createSizedArray(this.masksProperties.length);var r=this.masksProperties.length,s=!1;for(i=0;i<r;i+=1)"n"!==this.masksProperties[i].mode&&(s=!0),this.viewData[i]=ShapePropertyFactory.getShapeProp(this.element,this.masksProperties[i],3);this.hasMasks=s,s&&this.element.addRenderableComponent(this)}function CVBaseElement(){}CVEffects.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},CVEffects.prototype.getEffects=function(t){var e,i=this.filters.length,r=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&r.push(this.filters[e]);return r},CVMaskElement.prototype.renderFrame=function(){if(this.hasMasks){var t,e,i,r,s=this.element.finalTransform.mat,a=this.element.canvasContext,n=this.masksProperties.length;for(a.beginPath(),t=0;t<n;t+=1)if("n"!==this.masksProperties[t].mode){var o;this.masksProperties[t].inv&&(a.moveTo(0,0),a.lineTo(this.element.globalData.compSize.w,0),a.lineTo(this.element.globalData.compSize.w,this.element.globalData.compSize.h),a.lineTo(0,this.element.globalData.compSize.h),a.lineTo(0,0)),r=this.viewData[t].v,e=s.applyToPointArray(r.v[0][0],r.v[0][1],0),a.moveTo(e[0],e[1]);var h=r._length;for(o=1;o<h;o+=1)i=s.applyToTriplePoints(r.o[o-1],r.i[o],r.v[o]),a.bezierCurveTo(i[0],i[1],i[2],i[3],i[4],i[5]);i=s.applyToTriplePoints(r.o[o-1],r.i[0],r.v[0]),a.bezierCurveTo(i[0],i[1],i[2],i[3],i[4],i[5])}this.element.globalData.renderer.save(!0),a.clip()}},CVMaskElement.prototype.getMaskProperty=MaskElement.prototype.getMaskProperty,CVMaskElement.prototype.destroy=function(){this.element=null};var operationsMap={1:"source-in",2:"source-out",3:"source-in",4:"source-out"};function CVShapeData(t,e,i,r){this.styledShapes=[],this.tr=[0,0,0,0,0,0];var s,a=4;"rc"===e.ty?a=5:"el"===e.ty?a=6:"sr"===e.ty&&(a=7),this.sh=ShapePropertyFactory.getShapeProp(t,e,a,t);var n,o=i.length;for(s=0;s<o;s+=1)i[s].closed||(n={transforms:r.addTransformSequence(i[s].transforms),trNodes:[]},this.styledShapes.push(n),i[s].elements.push(n))}function CVShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.itemsData=[],this.prevViewData=[],this.shapeModifiers=[],this.processedElements=[],this.transformsManager=new ShapeTransformManager,this.initElement(t,e,i)}function CVTextElement(t,e,i){this.textSpans=[],this.yOffset=0,this.fillColorAnim=!1,this.strokeColorAnim=!1,this.strokeWidthAnim=!1,this.stroke=!1,this.fill=!1,this.justifyOffset=0,this.currentRender=null,this.renderType="canvas",this.values={fill:"rgba(0,0,0,0)",stroke:"rgba(0,0,0,0)",sWidth:0,fValue:""},this.initElement(t,e,i)}function CVImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.img=e.imageLoader.getAsset(this.assetData),this.initElement(t,e,i)}function CVSolidElement(t,e,i){this.initElement(t,e,i)}function CanvasRendererBase(){}function CanvasContext(){this.opacity=-1,this.transform=createTypedArray("float32",16),this.fillStyle="",this.strokeStyle="",this.lineWidth="",this.lineCap="",this.lineJoin="",this.miterLimit="",this.id=Math.random()}function CVContextData(){var t;this.stack=[],this.cArrPos=0,this.cTr=new Matrix;for(t=0;t<15;t+=1){var e=new CanvasContext;this.stack[t]=e}this._length=15,this.nativeContext=null,this.transformMat=new Matrix,this.currentOpacity=1,this.currentFillStyle="",this.appliedFillStyle="",this.currentStrokeStyle="",this.appliedStrokeStyle="",this.currentLineWidth="",this.appliedLineWidth="",this.currentLineCap="",this.appliedLineCap="",this.currentLineJoin="",this.appliedLineJoin="",this.appliedMiterLimit="",this.currentMiterLimit=""}function CVCompElement(t,e,i){this.completeLayers=!1,this.layers=t.layers,this.pendingElements=[],this.elements=createSizedArray(this.layers.length),this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function CanvasRenderer(t,e){this.animationItem=t,this.renderConfig={clearCanvas:!e||void 0===e.clearCanvas||e.clearCanvas,context:e&&e.context||null,progressiveLoad:e&&e.progressiveLoad||!1,preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",className:e&&e.className||"",id:e&&e.id||"",runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.renderConfig.dpr=e&&e.dpr||1,this.animationItem.wrapper&&(this.renderConfig.dpr=e&&e.dpr||window.devicePixelRatio||1),this.renderedFrame=-1,this.globalData={frameNum:-1,_mdf:!1,renderConfig:this.renderConfig,currentGlobalAlpha:-1},this.contextData=new CVContextData,this.elements=[],this.pendingElements=[],this.transformMat=new Matrix,this.completeLayers=!1,this.rendererType="canvas",this.renderConfig.clearCanvas&&(this.ctxTransform=this.contextData.transform.bind(this.contextData),this.ctxOpacity=this.contextData.opacity.bind(this.contextData),this.ctxFillStyle=this.contextData.fillStyle.bind(this.contextData),this.ctxStrokeStyle=this.contextData.strokeStyle.bind(this.contextData),this.ctxLineWidth=this.contextData.lineWidth.bind(this.contextData),this.ctxLineCap=this.contextData.lineCap.bind(this.contextData),this.ctxLineJoin=this.contextData.lineJoin.bind(this.contextData),this.ctxMiterLimit=this.contextData.miterLimit.bind(this.contextData),this.ctxFill=this.contextData.fill.bind(this.contextData),this.ctxFillRect=this.contextData.fillRect.bind(this.contextData),this.ctxStroke=this.contextData.stroke.bind(this.contextData),this.save=this.contextData.save.bind(this.contextData))}CVBaseElement.prototype={createElements:function(){},initRendererElement:function(){},createContainerElements:function(){if(this.data.tt>=1){this.buffers=[];var t=this.globalData.canvasContext,e=assetLoader.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(e);var i=assetLoader.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(i),this.data.tt>=3&&!document._isProxy&&assetLoader.loadLumaCanvas()}this.canvasContext=this.globalData.canvasContext,this.transformCanvas=this.globalData.transformCanvas,this.renderableEffectsManager=new CVEffects(this),this.searchEffectTransforms()},createContent:function(){},setBlendMode:function(){var t=this.globalData;if(t.blendMode!==this.data.bm){t.blendMode=this.data.bm;var e=getBlendMode(this.data.bm);t.canvasContext.globalCompositeOperation=e}},createRenderableComponents:function(){this.maskManager=new CVMaskElement(this.data,this),this.transformEffects=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT)},hideElement:function(){this.hidden||this.isInRange&&!this.isTransparent||(this.hidden=!0)},showElement:function(){this.isInRange&&!this.isTransparent&&(this.hidden=!1,this._isFirstFrame=!0,this.maskManager._isFirstFrame=!0)},clearCanvas:function(t){t.clearRect(this.transformCanvas.tx,this.transformCanvas.ty,this.transformCanvas.w*this.transformCanvas.sx,this.transformCanvas.h*this.transformCanvas.sy)},prepareLayer:function(){if(this.data.tt>=1){var t=this.buffers[0].getContext("2d");this.clearCanvas(t),t.drawImage(this.canvasContext.canvas,0,0),this.currentTransform=this.canvasContext.getTransform(),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform)}},exitLayer:function(){if(this.data.tt>=1){var t=this.buffers[1],e=t.getContext("2d");if(this.clearCanvas(e),e.drawImage(this.canvasContext.canvas,0,0),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform),this.comp.getElementById("tp"in this.data?this.data.tp:this.data.ind-1).renderFrame(!0),this.canvasContext.setTransform(1,0,0,1,0,0),this.data.tt>=3&&!document._isProxy){var i=assetLoader.getLumaCanvas(this.canvasContext.canvas);i.getContext("2d").drawImage(this.canvasContext.canvas,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.drawImage(i,0,0)}this.canvasContext.globalCompositeOperation=operationsMap[this.data.tt],this.canvasContext.drawImage(t,0,0),this.canvasContext.globalCompositeOperation="destination-over",this.canvasContext.drawImage(this.buffers[0],0,0),this.canvasContext.setTransform(this.currentTransform),this.canvasContext.globalCompositeOperation="source-over"}},renderFrame:function(t){if(!this.hidden&&!this.data.hd&&(1!==this.data.td||t)){this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.setBlendMode();var e=0===this.data.ty;this.prepareLayer(),this.globalData.renderer.save(e),this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props),this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity),this.renderInnerContent(),this.globalData.renderer.restore(e),this.exitLayer(),this.maskManager.hasMasks&&this.globalData.renderer.restore(!0),this._isFirstFrame&&(this._isFirstFrame=!1)}},destroy:function(){this.canvasContext=null,this.data=null,this.globalData=null,this.maskManager.destroy()},mHelper:new Matrix},CVBaseElement.prototype.hide=CVBaseElement.prototype.hideElement,CVBaseElement.prototype.show=CVBaseElement.prototype.showElement,CVShapeData.prototype.setAsAnimated=SVGShapeData.prototype.setAsAnimated,extendPrototype([BaseElement,TransformElement,CVBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableElement],CVShapeElement),CVShapeElement.prototype.initElement=RenderableDOMElement.prototype.initElement,CVShapeElement.prototype.transformHelper={opacity:1,_opMdf:!1},CVShapeElement.prototype.dashResetter=[],CVShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[])},CVShapeElement.prototype.createStyleElement=function(t,e){var i={data:t,type:t.ty,preTransforms:this.transformsManager.addTransformSequence(e),transforms:[],elements:[],closed:!0===t.hd},r={};if("fl"===t.ty||"st"===t.ty?(r.c=PropertyFactory.getProp(this,t.c,1,255,this),r.c.k||(i.co="rgb("+bmFloor(r.c.v[0])+","+bmFloor(r.c.v[1])+","+bmFloor(r.c.v[2])+")")):"gf"!==t.ty&&"gs"!==t.ty||(r.s=PropertyFactory.getProp(this,t.s,1,null,this),r.e=PropertyFactory.getProp(this,t.e,1,null,this),r.h=PropertyFactory.getProp(this,t.h||{k:0},0,.01,this),r.a=PropertyFactory.getProp(this,t.a||{k:0},0,degToRads,this),r.g=new GradientProperty(this,t.g,this)),r.o=PropertyFactory.getProp(this,t.o,0,.01,this),"st"===t.ty||"gs"===t.ty){if(i.lc=lineCapEnum[t.lc||2],i.lj=lineJoinEnum[t.lj||2],1==t.lj&&(i.ml=t.ml),r.w=PropertyFactory.getProp(this,t.w,0,null,this),r.w.k||(i.wi=r.w.v),t.d){var s=new DashProperty(this,t.d,"canvas",this);r.d=s,r.d.k||(i.da=r.d.dashArray,i.do=r.d.dashoffset[0])}}else i.r=2===t.r?"evenodd":"nonzero";return this.stylesList.push(i),r.style=i,r},CVShapeElement.prototype.createGroupElement=function(){return{it:[],prevViewData:[]}},CVShapeElement.prototype.createTransformElement=function(t){return{transform:{opacity:1,_opMdf:!1,key:this.transformsManager.getNewKey(),op:PropertyFactory.getProp(this,t.o,0,.01,this),mProps:TransformPropertyFactory.getTransformProperty(this,t,this)}}},CVShapeElement.prototype.createShapeElement=function(t){var e=new CVShapeData(this,t,this.stylesList,this.transformsManager);return this.shapes.push(e),this.addShapeToModifiers(e),e},CVShapeElement.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[]),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame)},CVShapeElement.prototype.addTransformToStyleList=function(t){var e,i=this.stylesList.length;for(e=0;e<i;e+=1)this.stylesList[e].closed||this.stylesList[e].transforms.push(t)},CVShapeElement.prototype.removeTransformFromStyleList=function(){var t,e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].closed||this.stylesList[t].transforms.pop()},CVShapeElement.prototype.closeStyles=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].closed=!0},CVShapeElement.prototype.searchShapes=function(t,e,i,r,s){var a,n,o,h,l,p,f=t.length-1,c=[],m=[],d=[].concat(s);for(a=f;a>=0;a-=1){if((h=this.searchProcessedElement(t[a]))?e[a]=i[h-1]:t[a]._shouldRender=r,"fl"===t[a].ty||"st"===t[a].ty||"gf"===t[a].ty||"gs"===t[a].ty)h?e[a].style.closed=!1:e[a]=this.createStyleElement(t[a],d),c.push(e[a].style);else if("gr"===t[a].ty){if(h)for(o=e[a].it.length,n=0;n<o;n+=1)e[a].prevViewData[n]=e[a].it[n];else e[a]=this.createGroupElement(t[a]);this.searchShapes(t[a].it,e[a].it,e[a].prevViewData,r,d)}else"tr"===t[a].ty?(h||(p=this.createTransformElement(t[a]),e[a]=p),d.push(e[a]),this.addTransformToStyleList(e[a])):"sh"===t[a].ty||"rc"===t[a].ty||"el"===t[a].ty||"sr"===t[a].ty?h||(e[a]=this.createShapeElement(t[a])):"tm"===t[a].ty||"rd"===t[a].ty||"pb"===t[a].ty||"zz"===t[a].ty||"op"===t[a].ty?(h?(l=e[a]).closed=!1:((l=ShapeModifiers.getModifier(t[a].ty)).init(this,t[a]),e[a]=l,this.shapeModifiers.push(l)),m.push(l)):"rp"===t[a].ty&&(h?(l=e[a]).closed=!0:(l=ShapeModifiers.getModifier(t[a].ty),e[a]=l,l.init(this,t,a,e),this.shapeModifiers.push(l),r=!1),m.push(l));this.addProcessedElement(t[a],a+1)}for(this.removeTransformFromStyleList(),this.closeStyles(c),f=m.length,a=0;a<f;a+=1)m[a].closed=!0},CVShapeElement.prototype.renderInnerContent=function(){this.transformHelper.opacity=1,this.transformHelper._opMdf=!1,this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame),this.renderShape(this.transformHelper,this.shapesData,this.itemsData,!0)},CVShapeElement.prototype.renderShapeTransform=function(t,e){(t._opMdf||e.op._mdf||this._isFirstFrame)&&(e.opacity=t.opacity,e.opacity*=e.op.v,e._opMdf=!0)},CVShapeElement.prototype.drawLayer=function(){var t,e,i,r,s,a,n,o,h,l=this.stylesList.length,p=this.globalData.renderer,f=this.globalData.canvasContext;for(t=0;t<l;t+=1)if(("st"!==(o=(h=this.stylesList[t]).type)&&"gs"!==o||0!==h.wi)&&h.data._shouldRender&&0!==h.coOp&&0!==this.globalData.currentGlobalAlpha){for(p.save(),a=h.elements,"st"===o||"gs"===o?(p.ctxStrokeStyle("st"===o?h.co:h.grd),p.ctxLineWidth(h.wi),p.ctxLineCap(h.lc),p.ctxLineJoin(h.lj),p.ctxMiterLimit(h.ml||0)):p.ctxFillStyle("fl"===o?h.co:h.grd),p.ctxOpacity(h.coOp),"st"!==o&&"gs"!==o&&f.beginPath(),p.ctxTransform(h.preTransforms.finalTransform.props),i=a.length,e=0;e<i;e+=1){for("st"!==o&&"gs"!==o||(f.beginPath(),h.da&&(f.setLineDash(h.da),f.lineDashOffset=h.do)),s=(n=a[e].trNodes).length,r=0;r<s;r+=1)"m"===n[r].t?f.moveTo(n[r].p[0],n[r].p[1]):"c"===n[r].t?f.bezierCurveTo(n[r].pts[0],n[r].pts[1],n[r].pts[2],n[r].pts[3],n[r].pts[4],n[r].pts[5]):f.closePath();"st"!==o&&"gs"!==o||(p.ctxStroke(),h.da&&f.setLineDash(this.dashResetter))}"st"!==o&&"gs"!==o&&this.globalData.renderer.ctxFill(h.r),p.restore()}},CVShapeElement.prototype.renderShape=function(t,e,i,r){var s,a;for(a=t,s=e.length-1;s>=0;s-=1)"tr"===e[s].ty?(a=i[s].transform,this.renderShapeTransform(t,a)):"sh"===e[s].ty||"el"===e[s].ty||"rc"===e[s].ty||"sr"===e[s].ty?this.renderPath(e[s],i[s]):"fl"===e[s].ty?this.renderFill(e[s],i[s],a):"st"===e[s].ty?this.renderStroke(e[s],i[s],a):"gf"===e[s].ty||"gs"===e[s].ty?this.renderGradientFill(e[s],i[s],a):"gr"===e[s].ty?this.renderShape(a,e[s].it,i[s].it):e[s].ty;r&&this.drawLayer()},CVShapeElement.prototype.renderStyledShape=function(t,e){if(this._isFirstFrame||e._mdf||t.transforms._mdf){var i,r,s,a=t.trNodes,n=e.paths,o=n._length;a.length=0;var h=t.transforms.finalTransform;for(s=0;s<o;s+=1){var l=n.shapes[s];if(l&&l.v){for(r=l._length,i=1;i<r;i+=1)1===i&&a.push({t:"m",p:h.applyToPointArray(l.v[0][0],l.v[0][1],0)}),a.push({t:"c",pts:h.applyToTriplePoints(l.o[i-1],l.i[i],l.v[i])});1===r&&a.push({t:"m",p:h.applyToPointArray(l.v[0][0],l.v[0][1],0)}),l.c&&r&&(a.push({t:"c",pts:h.applyToTriplePoints(l.o[i-1],l.i[0],l.v[0])}),a.push({t:"z"}))}}t.trNodes=a}},CVShapeElement.prototype.renderPath=function(t,e){if(!0!==t.hd&&t._shouldRender){var i,r=e.styledShapes.length;for(i=0;i<r;i+=1)this.renderStyledShape(e.styledShapes[i],e.sh)}},CVShapeElement.prototype.renderFill=function(t,e,i){var r=e.style;(e.c._mdf||this._isFirstFrame)&&(r.co="rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i._opMdf||this._isFirstFrame)&&(r.coOp=e.o.v*i.opacity)},CVShapeElement.prototype.renderGradientFill=function(t,e,i){var r,s=e.style;if(!s.grd||e.g._mdf||e.s._mdf||e.e._mdf||1!==t.t&&(e.h._mdf||e.a._mdf)){var a,n=this.globalData.canvasContext,o=e.s.v,h=e.e.v;if(1===t.t)r=n.createLinearGradient(o[0],o[1],h[0],h[1]);else{var l=Math.sqrt(Math.pow(o[0]-h[0],2)+Math.pow(o[1]-h[1],2)),p=Math.atan2(h[1]-o[1],h[0]-o[0]),f=e.h.v;f>=1?f=.99:f<=-1&&(f=-.99);var c=l*f,m=Math.cos(p+e.a.v)*c+o[0],d=Math.sin(p+e.a.v)*c+o[1];r=n.createRadialGradient(m,d,0,o[0],o[1],l)}var u=t.g.p,y=e.g.c,g=1;for(a=0;a<u;a+=1)e.g._hasOpacity&&e.g._collapsable&&(g=e.g.o[2*a+1]),r.addColorStop(y[4*a]/100,"rgba("+y[4*a+1]+","+y[4*a+2]+","+y[4*a+3]+","+g+")");s.grd=r}s.coOp=e.o.v*i.opacity},CVShapeElement.prototype.renderStroke=function(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||this._isFirstFrame)&&(r.da=s.dashArray,r.do=s.dashoffset[0]),(e.c._mdf||this._isFirstFrame)&&(r.co="rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i._opMdf||this._isFirstFrame)&&(r.coOp=e.o.v*i.opacity),(e.w._mdf||this._isFirstFrame)&&(r.wi=e.w.v)},CVShapeElement.prototype.destroy=function(){this.shapesData=null,this.globalData=null,this.canvasContext=null,this.stylesList.length=0,this.itemsData.length=0},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement,ITextElement],CVTextElement),CVTextElement.prototype.tHelper=createTag("canvas").getContext("2d"),CVTextElement.prototype.buildNewText=function(){var t=this.textProperty.currentData;this.renderedLetters=createSizedArray(t.l?t.l.length:0);var e=!1;t.fc?(e=!0,this.values.fill=this.buildColor(t.fc)):this.values.fill="rgba(0,0,0,0)",this.fill=e;var i=!1;t.sc&&(i=!0,this.values.stroke=this.buildColor(t.sc),this.values.sWidth=t.sw);var r,s,a,n,o,h,l,p,f,c,m,d,u=this.globalData.fontManager.getFontByName(t.f),y=t.l,g=this.mHelper;this.stroke=i,this.values.fValue=t.finalSize+"px "+this.globalData.fontManager.getFontByName(t.f).fFamily,s=t.finalText.length;var v=this.data.singleShape,P=.001*t.tr*t.finalSize,b=0,x=0,S=!0,C=0;for(r=0;r<s;r+=1){n=(a=this.globalData.fontManager.getCharData(t.finalText[r],u.fStyle,this.globalData.fontManager.getFontByName(t.f).fFamily))&&a.data||{},g.reset(),v&&y[r].n&&(b=-P,x+=t.yOffset,x+=S?1:0,S=!1),f=(l=n.shapes?n.shapes[0].it:[]).length,g.scale(t.finalSize/100,t.finalSize/100),v&&this.applyTextPropertiesToMatrix(t,g,y[r].line,b,x),m=createSizedArray(f-1);var E=0;for(p=0;p<f;p+=1)if("sh"===l[p].ty){for(h=l[p].ks.k.i.length,c=l[p].ks.k,d=[],o=1;o<h;o+=1)1===o&&d.push(g.applyToX(c.v[0][0],c.v[0][1],0),g.applyToY(c.v[0][0],c.v[0][1],0)),d.push(g.applyToX(c.o[o-1][0],c.o[o-1][1],0),g.applyToY(c.o[o-1][0],c.o[o-1][1],0),g.applyToX(c.i[o][0],c.i[o][1],0),g.applyToY(c.i[o][0],c.i[o][1],0),g.applyToX(c.v[o][0],c.v[o][1],0),g.applyToY(c.v[o][0],c.v[o][1],0));d.push(g.applyToX(c.o[o-1][0],c.o[o-1][1],0),g.applyToY(c.o[o-1][0],c.o[o-1][1],0),g.applyToX(c.i[0][0],c.i[0][1],0),g.applyToY(c.i[0][0],c.i[0][1],0),g.applyToX(c.v[0][0],c.v[0][1],0),g.applyToY(c.v[0][0],c.v[0][1],0)),m[E]=d,E+=1}v&&(b+=y[r].l,b+=P),this.textSpans[C]?this.textSpans[C].elem=m:this.textSpans[C]={elem:m},C+=1}},CVTextElement.prototype.renderInnerContent=function(){var t,e,i,r,s,a;this.validateText(),this.canvasContext.font=this.values.fValue,this.globalData.renderer.ctxLineCap("butt"),this.globalData.renderer.ctxLineJoin("miter"),this.globalData.renderer.ctxMiterLimit(4),this.data.singleShape||this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag);var n,o=this.textAnimator.renderedLetters,h=this.textProperty.currentData.l;e=h.length;var l,p,f=null,c=null,m=null,d=this.globalData.renderer;for(t=0;t<e;t+=1)if(!h[t].n){if((n=o[t])&&(d.save(),d.ctxTransform(n.p),d.ctxOpacity(n.o)),this.fill){for(n&&n.fc?f!==n.fc&&(d.ctxFillStyle(n.fc),f=n.fc):f!==this.values.fill&&(f=this.values.fill,d.ctxFillStyle(this.values.fill)),r=(l=this.textSpans[t].elem).length,this.globalData.canvasContext.beginPath(),i=0;i<r;i+=1)for(a=(p=l[i]).length,this.globalData.canvasContext.moveTo(p[0],p[1]),s=2;s<a;s+=6)this.globalData.canvasContext.bezierCurveTo(p[s],p[s+1],p[s+2],p[s+3],p[s+4],p[s+5]);this.globalData.canvasContext.closePath(),d.ctxFill()}if(this.stroke){for(n&&n.sw?m!==n.sw&&(m=n.sw,d.ctxLineWidth(n.sw)):m!==this.values.sWidth&&(m=this.values.sWidth,d.ctxLineWidth(this.values.sWidth)),n&&n.sc?c!==n.sc&&(c=n.sc,d.ctxStrokeStyle(n.sc)):c!==this.values.stroke&&(c=this.values.stroke,d.ctxStrokeStyle(this.values.stroke)),r=(l=this.textSpans[t].elem).length,this.globalData.canvasContext.beginPath(),i=0;i<r;i+=1)for(a=(p=l[i]).length,this.globalData.canvasContext.moveTo(p[0],p[1]),s=2;s<a;s+=6)this.globalData.canvasContext.bezierCurveTo(p[s],p[s+1],p[s+2],p[s+3],p[s+4],p[s+5]);this.globalData.canvasContext.closePath(),d.ctxStroke()}n&&this.globalData.renderer.restore()}},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVImageElement),CVImageElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVImageElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVImageElement.prototype.createContent=function(){if(this.img.width&&(this.assetData.w!==this.img.width||this.assetData.h!==this.img.height)){var t=createTag("canvas");t.width=this.assetData.w,t.height=this.assetData.h;var e,i,r=t.getContext("2d"),s=this.img.width,a=this.img.height,n=s/a,o=this.assetData.w/this.assetData.h,h=this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio;n>o&&"xMidYMid slice"===h||n<o&&"xMidYMid slice"!==h?e=(i=a)*o:i=(e=s)/o,r.drawImage(this.img,(s-e)/2,(a-i)/2,e,i,0,0,this.assetData.w,this.assetData.h),this.img=t}},CVImageElement.prototype.renderInnerContent=function(){this.canvasContext.drawImage(this.img,0,0)},CVImageElement.prototype.destroy=function(){this.img=null},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVSolidElement),CVSolidElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVSolidElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVSolidElement.prototype.renderInnerContent=function(){this.globalData.renderer.ctxFillStyle(this.data.sc),this.globalData.renderer.ctxFillRect(0,0,this.data.sw,this.data.sh)},extendPrototype([BaseRenderer],CanvasRendererBase),CanvasRendererBase.prototype.createShape=function(t){return new CVShapeElement(t,this.globalData,this)},CanvasRendererBase.prototype.createText=function(t){return new CVTextElement(t,this.globalData,this)},CanvasRendererBase.prototype.createImage=function(t){return new CVImageElement(t,this.globalData,this)},CanvasRendererBase.prototype.createSolid=function(t){return new CVSolidElement(t,this.globalData,this)},CanvasRendererBase.prototype.createNull=SVGRenderer.prototype.createNull,CanvasRendererBase.prototype.ctxTransform=function(t){1===t[0]&&0===t[1]&&0===t[4]&&1===t[5]&&0===t[12]&&0===t[13]||this.canvasContext.transform(t[0],t[1],t[4],t[5],t[12],t[13])},CanvasRendererBase.prototype.ctxOpacity=function(t){this.canvasContext.globalAlpha*=t<0?0:t},CanvasRendererBase.prototype.ctxFillStyle=function(t){this.canvasContext.fillStyle=t},CanvasRendererBase.prototype.ctxStrokeStyle=function(t){this.canvasContext.strokeStyle=t},CanvasRendererBase.prototype.ctxLineWidth=function(t){this.canvasContext.lineWidth=t},CanvasRendererBase.prototype.ctxLineCap=function(t){this.canvasContext.lineCap=t},CanvasRendererBase.prototype.ctxLineJoin=function(t){this.canvasContext.lineJoin=t},CanvasRendererBase.prototype.ctxMiterLimit=function(t){this.canvasContext.miterLimit=t},CanvasRendererBase.prototype.ctxFill=function(t){this.canvasContext.fill(t)},CanvasRendererBase.prototype.ctxFillRect=function(t,e,i,r){this.canvasContext.fillRect(t,e,i,r)},CanvasRendererBase.prototype.ctxStroke=function(){this.canvasContext.stroke()},CanvasRendererBase.prototype.reset=function(){this.renderConfig.clearCanvas?this.contextData.reset():this.canvasContext.restore()},CanvasRendererBase.prototype.save=function(){this.canvasContext.save()},CanvasRendererBase.prototype.restore=function(t){this.renderConfig.clearCanvas?(t&&(this.globalData.blendMode="source-over"),this.contextData.restore(t)):this.canvasContext.restore()},CanvasRendererBase.prototype.configAnimation=function(t){if(this.animationItem.wrapper){this.animationItem.container=createTag("canvas");var e=this.animationItem.container.style;e.width="100%",e.height="100%";var i="0px 0px 0px";e.transformOrigin=i,e.mozTransformOrigin=i,e.webkitTransformOrigin=i,e["-webkit-transform"]=i,e.contentVisibility=this.renderConfig.contentVisibility,this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.animationItem.container.setAttribute("id",this.renderConfig.id)}else this.canvasContext=this.renderConfig.context;this.contextData.setContext(this.canvasContext),this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.setupGlobalData(t,document.body),this.globalData.canvasContext=this.canvasContext,this.globalData.renderer=this,this.globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=createSizedArray(t.layers.length),this.updateContainerSize()},CanvasRendererBase.prototype.updateContainerSize=function(t,e){var i,r,s,a;if(this.reset(),t?(i=t,r=e,this.canvasContext.canvas.width=i,this.canvasContext.canvas.height=r):(this.animationItem.wrapper&&this.animationItem.container?(i=this.animationItem.wrapper.offsetWidth,r=this.animationItem.wrapper.offsetHeight):(i=this.canvasContext.canvas.width,r=this.canvasContext.canvas.height),this.canvasContext.canvas.width=i*this.renderConfig.dpr,this.canvasContext.canvas.height=r*this.renderConfig.dpr),-1!==this.renderConfig.preserveAspectRatio.indexOf("meet")||-1!==this.renderConfig.preserveAspectRatio.indexOf("slice")){var n=this.renderConfig.preserveAspectRatio.split(" "),o=n[1]||"meet",h=n[0]||"xMidYMid",l=h.substr(0,4),p=h.substr(4);s=i/r,(a=this.transformCanvas.w/this.transformCanvas.h)>s&&"meet"===o||a<s&&"slice"===o?(this.transformCanvas.sx=i/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=i/(this.transformCanvas.w/this.renderConfig.dpr)):(this.transformCanvas.sx=r/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.sy=r/(this.transformCanvas.h/this.renderConfig.dpr)),this.transformCanvas.tx="xMid"===l&&(a<s&&"meet"===o||a>s&&"slice"===o)?(i-this.transformCanvas.w*(r/this.transformCanvas.h))/2*this.renderConfig.dpr:"xMax"===l&&(a<s&&"meet"===o||a>s&&"slice"===o)?(i-this.transformCanvas.w*(r/this.transformCanvas.h))*this.renderConfig.dpr:0,this.transformCanvas.ty="YMid"===p&&(a>s&&"meet"===o||a<s&&"slice"===o)?(r-this.transformCanvas.h*(i/this.transformCanvas.w))/2*this.renderConfig.dpr:"YMax"===p&&(a>s&&"meet"===o||a<s&&"slice"===o)?(r-this.transformCanvas.h*(i/this.transformCanvas.w))*this.renderConfig.dpr:0}else"none"===this.renderConfig.preserveAspectRatio?(this.transformCanvas.sx=i/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=r/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.tx=0,this.transformCanvas.ty=0):(this.transformCanvas.sx=this.renderConfig.dpr,this.transformCanvas.sy=this.renderConfig.dpr,this.transformCanvas.tx=0,this.transformCanvas.ty=0);this.transformCanvas.props=[this.transformCanvas.sx,0,0,0,0,this.transformCanvas.sy,0,0,0,0,1,0,this.transformCanvas.tx,this.transformCanvas.ty,0,1],this.ctxTransform(this.transformCanvas.props),this.canvasContext.beginPath(),this.canvasContext.rect(0,0,this.transformCanvas.w,this.transformCanvas.h),this.canvasContext.closePath(),this.canvasContext.clip(),this.renderFrame(this.renderedFrame,!0)},CanvasRendererBase.prototype.destroy=function(){var t;for(this.renderConfig.clearCanvas&&this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),t=(this.layers?this.layers.length:0)-1;t>=0;t-=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.globalData.canvasContext=null,this.animationItem.container=null,this.destroyed=!0},CanvasRendererBase.prototype.renderFrame=function(t,e){if((this.renderedFrame!==t||!0!==this.renderConfig.clearCanvas||e)&&!this.destroyed&&-1!==t){var i;this.renderedFrame=t,this.globalData.frameNum=t-this.animationItem._isFirstFrame,this.globalData.frameId+=1,this.globalData._mdf=!this.renderConfig.clearCanvas||e,this.globalData.projectInterface.currentFrame=t;var r=this.layers.length;for(this.completeLayers||this.checkLayers(t),i=r-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&this.elements[i].prepareFrame(t-this.layers[i].st);if(this.globalData._mdf){for(!0===this.renderConfig.clearCanvas?this.canvasContext.clearRect(0,0,this.transformCanvas.w,this.transformCanvas.h):this.save(),i=r-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&this.elements[i].renderFrame();!0!==this.renderConfig.clearCanvas&&this.restore()}}},CanvasRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){var i=this.createItem(this.layers[t],this,this.globalData);e[t]=i,i.initExpressions()}},CanvasRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},CanvasRendererBase.prototype.hide=function(){this.animationItem.container.style.display="none"},CanvasRendererBase.prototype.show=function(){this.animationItem.container.style.display="block"},CVContextData.prototype.duplicate=function(){var t=2*this._length,e=0;for(e=this._length;e<t;e+=1)this.stack[e]=new CanvasContext;this._length=t},CVContextData.prototype.reset=function(){this.cArrPos=0,this.cTr.reset(),this.stack[this.cArrPos].opacity=1},CVContextData.prototype.restore=function(t){this.cArrPos-=1;var e,i=this.stack[this.cArrPos],r=i.transform,s=this.cTr.props;for(e=0;e<16;e+=1)s[e]=r[e];if(t){this.nativeContext.restore();var a=this.stack[this.cArrPos+1];this.appliedFillStyle=a.fillStyle,this.appliedStrokeStyle=a.strokeStyle,this.appliedLineWidth=a.lineWidth,this.appliedLineCap=a.lineCap,this.appliedLineJoin=a.lineJoin,this.appliedMiterLimit=a.miterLimit}this.nativeContext.setTransform(r[0],r[1],r[4],r[5],r[12],r[13]),(t||-1!==i.opacity&&this.currentOpacity!==i.opacity)&&(this.nativeContext.globalAlpha=i.opacity,this.currentOpacity=i.opacity),this.currentFillStyle=i.fillStyle,this.currentStrokeStyle=i.strokeStyle,this.currentLineWidth=i.lineWidth,this.currentLineCap=i.lineCap,this.currentLineJoin=i.lineJoin,this.currentMiterLimit=i.miterLimit},CVContextData.prototype.save=function(t){t&&this.nativeContext.save();var e=this.cTr.props;this._length<=this.cArrPos&&this.duplicate();var i,r=this.stack[this.cArrPos];for(i=0;i<16;i+=1)r.transform[i]=e[i];this.cArrPos+=1;var s=this.stack[this.cArrPos];s.opacity=r.opacity,s.fillStyle=r.fillStyle,s.strokeStyle=r.strokeStyle,s.lineWidth=r.lineWidth,s.lineCap=r.lineCap,s.lineJoin=r.lineJoin,s.miterLimit=r.miterLimit},CVContextData.prototype.setOpacity=function(t){this.stack[this.cArrPos].opacity=t},CVContextData.prototype.setContext=function(t){this.nativeContext=t},CVContextData.prototype.fillStyle=function(t){this.stack[this.cArrPos].fillStyle!==t&&(this.currentFillStyle=t,this.stack[this.cArrPos].fillStyle=t)},CVContextData.prototype.strokeStyle=function(t){this.stack[this.cArrPos].strokeStyle!==t&&(this.currentStrokeStyle=t,this.stack[this.cArrPos].strokeStyle=t)},CVContextData.prototype.lineWidth=function(t){this.stack[this.cArrPos].lineWidth!==t&&(this.currentLineWidth=t,this.stack[this.cArrPos].lineWidth=t)},CVContextData.prototype.lineCap=function(t){this.stack[this.cArrPos].lineCap!==t&&(this.currentLineCap=t,this.stack[this.cArrPos].lineCap=t)},CVContextData.prototype.lineJoin=function(t){this.stack[this.cArrPos].lineJoin!==t&&(this.currentLineJoin=t,this.stack[this.cArrPos].lineJoin=t)},CVContextData.prototype.miterLimit=function(t){this.stack[this.cArrPos].miterLimit!==t&&(this.currentMiterLimit=t,this.stack[this.cArrPos].miterLimit=t)},CVContextData.prototype.transform=function(t){this.transformMat.cloneFromProps(t);var e=this.cTr;this.transformMat.multiply(e),e.cloneFromProps(this.transformMat.props);var i=e.props;this.nativeContext.setTransform(i[0],i[1],i[4],i[5],i[12],i[13])},CVContextData.prototype.opacity=function(t){var e=this.stack[this.cArrPos].opacity;e*=t<0?0:t,this.stack[this.cArrPos].opacity!==e&&(this.currentOpacity!==t&&(this.nativeContext.globalAlpha=t,this.currentOpacity=t),this.stack[this.cArrPos].opacity=e)},CVContextData.prototype.fill=function(t){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fill(t)},CVContextData.prototype.fillRect=function(t,e,i,r){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fillRect(t,e,i,r)},CVContextData.prototype.stroke=function(){this.appliedStrokeStyle!==this.currentStrokeStyle&&(this.appliedStrokeStyle=this.currentStrokeStyle,this.nativeContext.strokeStyle=this.appliedStrokeStyle),this.appliedLineWidth!==this.currentLineWidth&&(this.appliedLineWidth=this.currentLineWidth,this.nativeContext.lineWidth=this.appliedLineWidth),this.appliedLineCap!==this.currentLineCap&&(this.appliedLineCap=this.currentLineCap,this.nativeContext.lineCap=this.appliedLineCap),this.appliedLineJoin!==this.currentLineJoin&&(this.appliedLineJoin=this.currentLineJoin,this.nativeContext.lineJoin=this.appliedLineJoin),this.appliedMiterLimit!==this.currentMiterLimit&&(this.appliedMiterLimit=this.currentMiterLimit,this.nativeContext.miterLimit=this.appliedMiterLimit),this.nativeContext.stroke()},extendPrototype([CanvasRendererBase,ICompElement,CVBaseElement],CVCompElement),CVCompElement.prototype.renderInnerContent=function(){var t,e=this.canvasContext;for(e.beginPath(),e.moveTo(0,0),e.lineTo(this.data.w,0),e.lineTo(this.data.w,this.data.h),e.lineTo(0,this.data.h),e.lineTo(0,0),e.clip(),t=this.layers.length-1;t>=0;t-=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},CVCompElement.prototype.destroy=function(){var t;for(t=this.layers.length-1;t>=0;t-=1)this.elements[t]&&this.elements[t].destroy();this.layers=null,this.elements=null},CVCompElement.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},extendPrototype([CanvasRendererBase],CanvasRenderer),CanvasRenderer.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},registerRenderer("canvas",CanvasRenderer),ShapeModifiers.registerModifier("tm",TrimModifier),ShapeModifiers.registerModifier("pb",PuckerAndBloatModifier),ShapeModifiers.registerModifier("rp",RepeaterModifier),ShapeModifiers.registerModifier("rd",RoundCornersModifier),ShapeModifiers.registerModifier("zz",ZigZagModifier),ShapeModifiers.registerModifier("op",OffsetPathModifier);var CompExpressionInterface=function(t){function e(e){for(var i=0,r=t.layers.length;i<r;){if(t.layers[i].nm===e||t.layers[i].ind===e)return t.elements[i].layerInterface;i+=1}return null}return Object.defineProperty(e,"_name",{value:t.data.nm}),e.layer=e,e.pixelAspect=1,e.height=t.data.h||t.globalData.compSize.h,e.width=t.data.w||t.globalData.compSize.w,e.pixelAspect=1,e.frameDuration=1/t.globalData.frameRate,e.displayStartTime=0,e.numLayers=t.layers.length,e};function _typeof$2(t){return _typeof$2="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$2(t)}function seedRandom(t,e){var i,r=this,s=256,a=e.pow(s,6),n=e.pow(2,52),o=2*n,h=255;function l(t){var e,i=t.length,r=this,a=0,n=r.i=r.j=0,o=r.S=[];for(i||(t=[i++]);a<s;)o[a]=a++;for(a=0;a<s;a++)o[a]=o[n=h&n+t[a%i]+(e=o[a])],o[n]=e;r.g=function(t){for(var e,i=0,a=r.i,n=r.j,o=r.S;t--;)e=o[a=h&a+1],i=i*s+o[h&(o[a]=o[n=h&n+e])+(o[n]=e)];return r.i=a,r.j=n,i}}function p(t,e){return e.i=t.i,e.j=t.j,e.S=t.S.slice(),e}function f(t,e){var i,r=[],s=_typeof$2(t);if(e&&"object"==s)for(i in t)try{r.push(f(t[i],e-1))}catch(t){}return r.length?r:"string"==s?t:t+"\0"}function c(t,e){for(var i,r=t+"",s=0;s<r.length;)e[h&s]=h&(i^=19*e[h&s])+r.charCodeAt(s++);return m(e)}function m(t){return String.fromCharCode.apply(0,t)}e.seedrandom=function(h,d,u){var y=[],g=c(f((d=!0===d?{entropy:!0}:d||{}).entropy?[h,m(t)]:null===h?function(){try{i;var e=new Uint8Array(s);return(r.crypto||r.msCrypto).getRandomValues(e),m(e)}catch(e){var a=r.navigator,n=a&&a.plugins;return[+new Date,r,n,r.screen,m(t)]}}():h,3),y),v=new l(y),P=function(){for(var t=v.g(6),e=a,i=0;t<n;)t=(t+i)*s,e*=s,i=v.g(1);for(;t>=o;)t/=2,e/=2,i>>>=1;return(t+i)/e};return P.int32=function(){return 0|v.g(4)},P.quick=function(){return v.g(4)/4294967296},P.double=P,c(m(v.S),t),(d.pass||u||function(t,i,r,s){return s&&(s.S&&p(s,v),t.state=function(){return p(v,{})}),r?(e.random=t,i):t})(P,g,"global"in d?d.global:this==e,d.state)},c(e.random(),t)}function initialize$2(t){seedRandom([],t)}var propTypes={SHAPE:"shape"};function _typeof$1(t){return _typeof$1="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$1(t)}var ExpressionManager=function(){var ob={},Math=BMMath,window=null,document=null,XMLHttpRequest=null,fetch=null,frames=null,_lottieGlobal={};function resetFrame(){_lottieGlobal={}}function $bm_isInstanceOfArray(t){return t.constructor===Array||t.constructor===Float32Array}function isNumerable(t,e){return"number"===t||e instanceof Number||"boolean"===t||"string"===t}function $bm_neg(t){var e=_typeof$1(t);if("number"===e||t instanceof Number||"boolean"===e)return-t;if($bm_isInstanceOfArray(t)){var i,r=t.length,s=[];for(i=0;i<r;i+=1)s[i]=-t[i];return s}return t.propType?t.v:-t}initialize$2(BMMath);var easeInBez=BezierFactory.getBezierEasing(.333,0,.833,.833,"easeIn").get,easeOutBez=BezierFactory.getBezierEasing(.167,.167,.667,1,"easeOut").get,easeInOutBez=BezierFactory.getBezierEasing(.33,0,.667,1,"easeInOut").get;function sum(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e)||"string"===i||"string"===r)return t+e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]+=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t+e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]+e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}var add=sum;function sub(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e))return"string"===i&&(t=parseInt(t,10)),"string"===r&&(e=parseInt(e,10)),t-e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]-=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t-e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]-e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}function mul(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t*e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]*e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t*e[r];return i}return 0}function div(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t/e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]/e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t/e[r];return i}return 0}function mod(t,e){return"string"==typeof t&&(t=parseInt(t,10)),"string"==typeof e&&(e=parseInt(e,10)),t%e}var $bm_sum=sum,$bm_sub=sub,$bm_mul=mul,$bm_div=div,$bm_mod=mod;function clamp(t,e,i){if(e>i){var r=i;i=e,e=r}return Math.min(Math.max(t,e),i)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return e=e||0,Math.abs(t-e);var i;e||(e=helperLengthArray);var r=Math.min(t.length,e.length),s=0;for(i=0;i<r;i+=1)s+=Math.pow(e[i]-t[i],2);return Math.sqrt(s)}function normalize(t){return div(t,length(t))}function rgbToHsl(t){var e,i,r=t[0],s=t[1],a=t[2],n=Math.max(r,s,a),o=Math.min(r,s,a),h=(n+o)/2;if(n===o)e=0,i=0;else{var l=n-o;switch(i=h>.5?l/(2-n-o):l/(n+o),n){case r:e=(s-a)/l+(s<a?6:0);break;case s:e=(a-r)/l+2;break;case a:e=(r-s)/l+4}e/=6}return[e,i,h,t[3]]}function hue2rgb(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}function hslToRgb(t){var e,i,r,s=t[0],a=t[1],n=t[2];if(0===a)e=n,r=n,i=n;else{var o=n<.5?n*(1+a):n+a-n*a,h=2*n-o;e=hue2rgb(h,o,s+1/3),i=hue2rgb(h,o,s),r=hue2rgb(h,o,s-1/3)}return[e,i,r,t[3]]}function linear(t,e,i,r,s){if(void 0!==r&&void 0!==s||(r=e,s=i,e=0,i=1),i<e){var a=i;i=e,e=a}if(t<=e)return r;if(t>=i)return s;var n,o=i===e?0:(t-e)/(i-e);if(!r.length)return r+(s-r)*o;var h=r.length,l=createTypedArray("float32",h);for(n=0;n<h;n+=1)l[n]=r[n]+(s[n]-r[n])*o;return l}function random(t,e){if(void 0===e&&(void 0===t?(t=0,e=1):(e=t,t=void 0)),e.length){var i,r=e.length;t||(t=createTypedArray("float32",r));var s=createTypedArray("float32",r),a=BMMath.random();for(i=0;i<r;i+=1)s[i]=t[i]+a*(e[i]-t[i]);return s}return void 0===t&&(t=0),t+BMMath.random()*(e-t)}function createPath(t,e,i,r){var s,a=t.length,n=shapePool.newElement();n.setPathData(!!r,a);var o,h,l=[0,0];for(s=0;s<a;s+=1)o=e&&e[s]?e[s]:l,h=i&&i[s]?i[s]:l,n.setTripleAt(t[s][0],t[s][1],h[0]+t[s][0],h[1]+t[s][1],o[0]+t[s][0],o[1]+t[s][1],s,!0);return n}function initiateExpression(elem,data,property){function noOp(t){return t}if(!elem.globalData.renderConfig.runExpressions)return noOp;var val=data.x,needsVelocity=/velocity(?![\w\d])/.test(val),_needsRandom=-1!==val.indexOf("random"),elemType=elem.data.ty,transform,$bm_transform,content,effect,thisProperty=property;thisProperty.valueAtTime=thisProperty.getValueAtTime,Object.defineProperty(thisProperty,"value",{get:function(){return thisProperty.v}}),elem.comp.frameDuration=1/elem.comp.globalData.frameRate,elem.comp.displayStartTime=0;var inPoint=elem.data.ip/elem.comp.globalData.frameRate,outPoint=elem.data.op/elem.comp.globalData.frameRate,width=elem.data.sw?elem.data.sw:0,height=elem.data.sh?elem.data.sh:0,name=elem.data.nm,loopIn,loop_in,loopOut,loop_out,smooth,toWorld,fromWorld,fromComp,toComp,fromCompToSurface,position,rotation,anchorPoint,scale,thisLayer,thisComp,mask,valueAtTime,velocityAtTime,scoped_bm_rt,expression_function=eval("[function _expression_function(){"+val+";scoped_bm_rt=$bm_rt}]")[0],numKeys=property.kf?data.k.length:0,active=!this.data||!0!==this.data.hd,wiggle=function(t,e){var i,r,s=this.pv.length?this.pv.length:1,a=createTypedArray("float32",s);var n=Math.floor(5*time);for(i=0,r=0;i<n;){for(r=0;r<s;r+=1)a[r]+=-e+2*e*BMMath.random();i+=1}var o=5*time,h=o-Math.floor(o),l=createTypedArray("float32",s);if(s>1){for(r=0;r<s;r+=1)l[r]=this.pv[r]+a[r]+(-e+2*e*BMMath.random())*h;return l}return this.pv+a[0]+(-e+2*e*BMMath.random())*h}.bind(this);function loopInDuration(t,e){return loopIn(t,e,!0)}function loopOutDuration(t,e){return loopOut(t,e,!0)}thisProperty.loopIn&&(loopIn=thisProperty.loopIn.bind(thisProperty),loop_in=loopIn),thisProperty.loopOut&&(loopOut=thisProperty.loopOut.bind(thisProperty),loop_out=loopOut),thisProperty.smooth&&(smooth=thisProperty.smooth.bind(thisProperty)),this.getValueAtTime&&(valueAtTime=this.getValueAtTime.bind(this)),this.getVelocityAtTime&&(velocityAtTime=this.getVelocityAtTime.bind(this));var comp=elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface),time,velocity,value,text,textIndex,textTotal,selectorValue;function lookAt(t,e){var i=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],r=Math.atan2(i[0],Math.sqrt(i[1]*i[1]+i[2]*i[2]))/degToRads;return[-Math.atan2(i[1],i[2])/degToRads,r,0]}function easeOut(t,e,i,r,s){return applyEase(easeOutBez,t,e,i,r,s)}function easeIn(t,e,i,r,s){return applyEase(easeInBez,t,e,i,r,s)}function ease(t,e,i,r,s){return applyEase(easeInOutBez,t,e,i,r,s)}function applyEase(t,e,i,r,s,a){void 0===s?(s=i,a=r):e=(e-i)/(r-i),e>1?e=1:e<0&&(e=0);var n=t(e);if($bm_isInstanceOfArray(s)){var o,h=s.length,l=createTypedArray("float32",h);for(o=0;o<h;o+=1)l[o]=(a[o]-s[o])*n+s[o];return l}return(a-s)*n+s}function nearestKey(t){var e,i,r,s=data.k.length;if(data.k.length&&"number"!=typeof data.k[0])if(i=-1,(t*=elem.comp.globalData.frameRate)<data.k[0].t)i=1,r=data.k[0].t;else{for(e=0;e<s-1;e+=1){if(t===data.k[e].t){i=e+1,r=data.k[e].t;break}if(t>data.k[e].t&&t<data.k[e+1].t){t-data.k[e].t>data.k[e+1].t-t?(i=e+2,r=data.k[e+1].t):(i=e+1,r=data.k[e].t);break}}-1===i&&(i=e+1,r=data.k[e].t)}else i=0,r=0;var a={};return a.index=i,a.time=r/elem.comp.globalData.frameRate,a}function key(t){var e,i,r;if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]};var s=Object.prototype.hasOwnProperty.call(data.k[t],"s")?data.k[t].s:data.k[t-1].e;for(r=s.length,i=0;i<r;i+=1)e[i]=s[i],e.value[i]=s[i];return e}function framesToTime(t,e){return e||(e=elem.comp.globalData.frameRate),t/e}function timeToFrames(t,e){return t||0===t||(t=time),e||(e=elem.comp.globalData.frameRate),t*e}function seedRandom(t){BMMath.seedrandom(randSeed+t)}function sourceRectAtTime(){return elem.sourceRectAtTime()}function substring(t,e){return"string"==typeof value?void 0===e?value.substring(t):value.substring(t,e):""}function substr(t,e){return"string"==typeof value?void 0===e?value.substr(t):value.substr(t,e):""}function posterizeTime(t){time=0===t?0:Math.floor(time*t)/t,value=valueAtTime(time)}var index=elem.data.ind,hasParent=!(!elem.hierarchy||!elem.hierarchy.length),parent,randSeed=Math.floor(1e6*Math.random()),globalData=elem.globalData;function executeExpression(t){return value=t,this.frameExpressionId===elem.globalData.frameId&&"textSelector"!==this.propType?value:("textSelector"===this.propType&&(textIndex=this.textIndex,textTotal=this.textTotal,selectorValue=this.selectorValue),thisLayer||(text=elem.layerInterface.text,thisLayer=elem.layerInterface,thisComp=elem.comp.compInterface,toWorld=thisLayer.toWorld.bind(thisLayer),fromWorld=thisLayer.fromWorld.bind(thisLayer),fromComp=thisLayer.fromComp.bind(thisLayer),toComp=thisLayer.toComp.bind(thisLayer),mask=thisLayer.mask?thisLayer.mask.bind(thisLayer):null,fromCompToSurface=fromComp),transform||(transform=elem.layerInterface("ADBE Transform Group"),$bm_transform=transform,transform&&(anchorPoint=transform.anchorPoint)),4!==elemType||content||(content=thisLayer("ADBE Root Vectors Group")),effect||(effect=thisLayer(4)),(hasParent=!(!elem.hierarchy||!elem.hierarchy.length))&&!parent&&(parent=elem.hierarchy[0].layerInterface),time=this.comp.renderedFrame/this.comp.globalData.frameRate,_needsRandom&&seedRandom(randSeed+time),needsVelocity&&(velocity=velocityAtTime(time)),expression_function(),this.frameExpressionId=elem.globalData.frameId,scoped_bm_rt=scoped_bm_rt.propType===propTypes.SHAPE?scoped_bm_rt.v:scoped_bm_rt)}return executeExpression.__preventDeadCodeRemoval=[$bm_transform,anchorPoint,time,velocity,inPoint,outPoint,width,height,name,loop_in,loop_out,smooth,toComp,fromCompToSurface,toWorld,fromWorld,mask,position,rotation,scale,thisComp,numKeys,active,wiggle,loopInDuration,loopOutDuration,comp,lookAt,easeOut,easeIn,ease,nearestKey,key,text,textIndex,textTotal,selectorValue,framesToTime,timeToFrames,sourceRectAtTime,substring,substr,posterizeTime,index,globalData],executeExpression}return ob.initiateExpression=initiateExpression,ob.__preventDeadCodeRemoval=[window,document,XMLHttpRequest,fetch,frames,$bm_neg,add,$bm_sum,$bm_sub,$bm_mul,$bm_div,$bm_mod,clamp,radians_to_degrees,degreesToRadians,degrees_to_radians,normalize,rgbToHsl,hslToRgb,linear,random,createPath,_lottieGlobal],ob.resetFrame=resetFrame,ob}(),Expressions=function(){var t={};return t.initExpressions=function(t){var e=0,i=[];t.renderer.compInterface=CompExpressionInterface(t.renderer),t.renderer.globalData.projectInterface.registerComposition(t.renderer),t.renderer.globalData.pushExpression=function(){e+=1},t.renderer.globalData.popExpression=function(){0==(e-=1)&&function(){var t,e=i.length;for(t=0;t<e;t+=1)i[t].release();i.length=0}()},t.renderer.globalData.registerExpressionProperty=function(t){-1===i.indexOf(t)&&i.push(t)}},t.resetFrame=ExpressionManager.resetFrame,t}(),MaskManagerInterface=function(){function t(t,e){this._mask=t,this._data=e}Object.defineProperty(t.prototype,"maskPath",{get:function(){return this._mask.prop.k&&this._mask.prop.getValue(),this._mask.prop}}),Object.defineProperty(t.prototype,"maskOpacity",{get:function(){return this._mask.op.k&&this._mask.op.getValue(),100*this._mask.op.v}});return function(e){var i,r=createSizedArray(e.viewData.length),s=e.viewData.length;for(i=0;i<s;i+=1)r[i]=new t(e.viewData[i],e.masksProperties[i]);return function(t){for(i=0;i<s;){if(e.masksProperties[i].nm===t)return r[i];i+=1}return null}}}(),ExpressionPropertyInterface=function(){var t={pv:0,v:0,mult:1},e={pv:[0,0,0],v:[0,0,0],mult:1};function i(t,e,i){Object.defineProperty(t,"velocity",{get:function(){return e.getVelocityAtTime(e.comp.currentFrame)}}),t.numKeys=e.keyframes?e.keyframes.length:0,t.key=function(r){if(!t.numKeys)return 0;var s="";s="s"in e.keyframes[r-1]?e.keyframes[r-1].s:"e"in e.keyframes[r-2]?e.keyframes[r-2].e:e.keyframes[r-2].s;var a="unidimensional"===i?new Number(s):Object.assign({},s);return a.time=e.keyframes[r-1].t/e.elem.comp.globalData.frameRate,a.value="unidimensional"===i?s[0]:s,a},t.valueAtTime=e.getValueAtTime,t.speedAtTime=e.getSpeedAtTime,t.velocityAtTime=e.getVelocityAtTime,t.propertyGroup=e.propertyGroup}function r(){return t}return function(s){return s?"unidimensional"===s.propType?function(e){e&&"pv"in e||(e=t);var r=1/e.mult,s=e.pv*r,a=new Number(s);return a.value=s,i(a,e,"unidimensional"),function(){return e.k&&e.getValue(),s=e.v*r,a.value!==s&&((a=new Number(s)).value=s,i(a,e,"unidimensional")),a}}(s):function(t){t&&"pv"in t||(t=e);var r=1/t.mult,s=t.data&&t.data.l||t.pv.length,a=createTypedArray("float32",s),n=createTypedArray("float32",s);return a.value=n,i(a,t,"multidimensional"),function(){t.k&&t.getValue();for(var e=0;e<s;e+=1)n[e]=t.v[e]*r,a[e]=n[e];return a}}(s):r}}(),TransformExpressionInterface=function(t){function e(t){switch(t){case"scale":case"Scale":case"ADBE Scale":case 6:return e.scale;case"rotation":case"Rotation":case"ADBE Rotation":case"ADBE Rotate Z":case 10:return e.rotation;case"ADBE Rotate X":return e.xRotation;case"ADBE Rotate Y":return e.yRotation;case"position":case"Position":case"ADBE Position":case 2:return e.position;case"ADBE Position_0":return e.xPosition;case"ADBE Position_1":return e.yPosition;case"ADBE Position_2":return e.zPosition;case"anchorPoint":case"AnchorPoint":case"Anchor Point":case"ADBE AnchorPoint":case 1:return e.anchorPoint;case"opacity":case"Opacity":case 11:return e.opacity;default:return null}}var i,r,s,a;return Object.defineProperty(e,"rotation",{get:ExpressionPropertyInterface(t.r||t.rz)}),Object.defineProperty(e,"zRotation",{get:ExpressionPropertyInterface(t.rz||t.r)}),Object.defineProperty(e,"xRotation",{get:ExpressionPropertyInterface(t.rx)}),Object.defineProperty(e,"yRotation",{get:ExpressionPropertyInterface(t.ry)}),Object.defineProperty(e,"scale",{get:ExpressionPropertyInterface(t.s)}),t.p?a=ExpressionPropertyInterface(t.p):(i=ExpressionPropertyInterface(t.px),r=ExpressionPropertyInterface(t.py),t.pz&&(s=ExpressionPropertyInterface(t.pz))),Object.defineProperty(e,"position",{get:function(){return t.p?a():[i(),r(),s?s():0]}}),Object.defineProperty(e,"xPosition",{get:ExpressionPropertyInterface(t.px)}),Object.defineProperty(e,"yPosition",{get:ExpressionPropertyInterface(t.py)}),Object.defineProperty(e,"zPosition",{get:ExpressionPropertyInterface(t.pz)}),Object.defineProperty(e,"anchorPoint",{get:ExpressionPropertyInterface(t.a)}),Object.defineProperty(e,"opacity",{get:ExpressionPropertyInterface(t.o)}),Object.defineProperty(e,"skew",{get:ExpressionPropertyInterface(t.sk)}),Object.defineProperty(e,"skewAxis",{get:ExpressionPropertyInterface(t.sa)}),Object.defineProperty(e,"orientation",{get:ExpressionPropertyInterface(t.or)}),e},LayerExpressionInterface=function(){function t(t){var e=new Matrix;void 0!==t?this._elem.finalTransform.mProp.getValueAtTime(t).clone(e):this._elem.finalTransform.mProp.applyToMatrix(e);return e}function e(t,e){var i=this.getMatrix(e);return i.props[12]=0,i.props[13]=0,i.props[14]=0,this.applyPoint(i,t)}function i(t,e){var i=this.getMatrix(e);return this.applyPoint(i,t)}function r(t,e){var i=this.getMatrix(e);return i.props[12]=0,i.props[13]=0,i.props[14]=0,this.invertPoint(i,t)}function s(t,e){var i=this.getMatrix(e);return this.invertPoint(i,t)}function a(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(t)}return t.applyToPointArray(e[0],e[1],e[2]||0)}function n(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(t)}return t.inversePoint(e)}function o(t){var e=new Matrix;if(e.reset(),this._elem.finalTransform.mProp.applyToMatrix(e),this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(e);return e.inversePoint(t)}return e.inversePoint(t)}function h(){return[1,1,1,1]}return function(l){var p;function f(t){switch(t){case"ADBE Root Vectors Group":case"Contents":case 2:return f.shapeInterface;case 1:case 6:case"Transform":case"transform":case"ADBE Transform Group":return p;case 4:case"ADBE Effect Parade":case"effects":case"Effects":return f.effect;case"ADBE Text Properties":return f.textInterface;default:return null}}f.getMatrix=t,f.invertPoint=n,f.applyPoint=a,f.toWorld=i,f.toWorldVec=e,f.fromWorld=s,f.fromWorldVec=r,f.toComp=i,f.fromComp=o,f.sampleImage=h,f.sourceRectAtTime=l.sourceRectAtTime.bind(l),f._elem=l;var c=getDescriptor(p=TransformExpressionInterface(l.finalTransform.mProp),"anchorPoint");return Object.defineProperties(f,{hasParent:{get:function(){return l.hierarchy.length}},parent:{get:function(){return l.hierarchy[0].layerInterface}},rotation:getDescriptor(p,"rotation"),scale:getDescriptor(p,"scale"),position:getDescriptor(p,"position"),opacity:getDescriptor(p,"opacity"),anchorPoint:c,anchor_point:c,transform:{get:function(){return p}},active:{get:function(){return l.isInRange}}}),f.startTime=l.data.st,f.index=l.data.ind,f.source=l.data.refId,f.height=0===l.data.ty?l.data.h:100,f.width=0===l.data.ty?l.data.w:100,f.inPoint=l.data.ip/l.comp.globalData.frameRate,f.outPoint=l.data.op/l.comp.globalData.frameRate,f._name=l.data.nm,f.registerMaskInterface=function(t){f.mask=new MaskManagerInterface(t,l)},f.registerEffectsInterface=function(t){f.effect=t},f}}(),propertyGroupFactory=function(t,e){return function(i){return(i=void 0===i?1:i)<=0?t:e(i-1)}},PropertyInterface=function(t,e){var i={_name:t};return function(t){return(t=void 0===t?1:t)<=0?i:e(t-1)}},EffectsExpressionInterface=function(){function t(i,r,s,a){function n(t){for(var e=i.ef,r=0,s=e.length;r<s;){if(t===e[r].nm||t===e[r].mn||t===e[r].ix)return 5===e[r].ty?l[r]:l[r]();r+=1}throw new Error}var o,h=propertyGroupFactory(n,s),l=[],p=i.ef.length;for(o=0;o<p;o+=1)5===i.ef[o].ty?l.push(t(i.ef[o],r.effectElements[o],r.effectElements[o].propertyGroup,a)):l.push(e(r.effectElements[o],i.ef[o].ty,a,h));return"ADBE Color Control"===i.mn&&Object.defineProperty(n,"color",{get:function(){return l[0]()}}),Object.defineProperties(n,{numProperties:{get:function(){return i.np}},_name:{value:i.nm},propertyGroup:{value:h}}),n.enabled=0!==i.en,n.active=n.enabled,n}function e(t,e,i,r){var s=ExpressionPropertyInterface(t.p);return t.p.setGroupProperty&&t.p.setGroupProperty(PropertyInterface("",r)),function(){return 10===e?i.comp.compInterface(t.p.v):s()}}return{createEffectsInterface:function(e,i){if(e.effectsManager){var r,s=[],a=e.data.ef,n=e.effectsManager.effectElements.length;for(r=0;r<n;r+=1)s.push(t(a[r],e.effectsManager.effectElements[r],i,e));var o=e.data.ef||[],h=function(t){for(r=0,n=o.length;r<n;){if(t===o[r].nm||t===o[r].mn||t===o[r].ix)return s[r];r+=1}return null};return Object.defineProperty(h,"numProperties",{get:function(){return o.length}}),h}return null}}}(),ShapePathInterface=function(t,e,i){var r=e.sh;function s(t){return"Shape"===t||"shape"===t||"Path"===t||"path"===t||"ADBE Vector Shape"===t||2===t?s.path:null}var a=propertyGroupFactory(s,i);return r.setGroupProperty(PropertyInterface("Path",a)),Object.defineProperties(s,{path:{get:function(){return r.k&&r.getValue(),r}},shape:{get:function(){return r.k&&r.getValue(),r}},_name:{value:t.nm},ix:{value:t.ix},propertyIndex:{value:t.ix},mn:{value:t.mn},propertyGroup:{value:i}}),s},ShapeExpressionInterface=function(){function t(t,o,m){var d,u=[],y=t?t.length:0;for(d=0;d<y;d+=1)"gr"===t[d].ty?u.push(e(t[d],o[d],m)):"fl"===t[d].ty?u.push(i(t[d],o[d],m)):"st"===t[d].ty?u.push(a(t[d],o[d],m)):"tm"===t[d].ty?u.push(n(t[d],o[d],m)):"tr"===t[d].ty||("el"===t[d].ty?u.push(h(t[d],o[d],m)):"sr"===t[d].ty?u.push(l(t[d],o[d],m)):"sh"===t[d].ty?u.push(ShapePathInterface(t[d],o[d],m)):"rc"===t[d].ty?u.push(p(t[d],o[d],m)):"rd"===t[d].ty?u.push(f(t[d],o[d],m)):"rp"===t[d].ty?u.push(c(t[d],o[d],m)):"gf"===t[d].ty?u.push(r(t[d],o[d],m)):u.push(s(t[d],o[d])));return u}function e(e,i,r){var s=function(t){switch(t){case"ADBE Vectors Group":case"Contents":case 2:return s.content;default:return s.transform}};s.propertyGroup=propertyGroupFactory(s,r);var a=function(e,i,r){var s,a=function(t){for(var e=0,i=s.length;e<i;){if(s[e]._name===t||s[e].mn===t||s[e].propertyIndex===t||s[e].ix===t||s[e].ind===t)return s[e];e+=1}return"number"==typeof t?s[t-1]:null};a.propertyGroup=propertyGroupFactory(a,r),s=t(e.it,i.it,a.propertyGroup),a.numProperties=s.length;var n=o(e.it[e.it.length-1],i.it[i.it.length-1],a.propertyGroup);return a.transform=n,a.propertyIndex=e.cix,a._name=e.nm,a}(e,i,s.propertyGroup),n=o(e.it[e.it.length-1],i.it[i.it.length-1],s.propertyGroup);return s.content=a,s.transform=n,Object.defineProperty(s,"_name",{get:function(){return e.nm}}),s.numProperties=e.np,s.propertyIndex=e.ix,s.nm=e.nm,s.mn=e.mn,s}function i(t,e,i){function r(t){return"Color"===t||"color"===t?r.color:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r}function r(t,e,i){function r(t){return"Start Point"===t||"start point"===t?r.startPoint:"End Point"===t||"end point"===t?r.endPoint:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{startPoint:{get:ExpressionPropertyInterface(e.s)},endPoint:{get:ExpressionPropertyInterface(e.e)},opacity:{get:ExpressionPropertyInterface(e.o)},type:{get:function(){return"a"}},_name:{value:t.nm},mn:{value:t.mn}}),e.s.setGroupProperty(PropertyInterface("Start Point",i)),e.e.setGroupProperty(PropertyInterface("End Point",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r}function s(){return function(){return null}}function a(t,e,i){var r,s=propertyGroupFactory(l,i),a=propertyGroupFactory(h,s);function n(i){Object.defineProperty(h,t.d[i].nm,{get:ExpressionPropertyInterface(e.d.dataProps[i].p)})}var o=t.d?t.d.length:0,h={};for(r=0;r<o;r+=1)n(r),e.d.dataProps[r].p.setGroupProperty(a);function l(t){return"Color"===t||"color"===t?l.color:"Opacity"===t||"opacity"===t?l.opacity:"Stroke Width"===t||"stroke width"===t?l.strokeWidth:null}return Object.defineProperties(l,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},strokeWidth:{get:ExpressionPropertyInterface(e.w)},dash:{get:function(){return h}},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",s)),e.o.setGroupProperty(PropertyInterface("Opacity",s)),e.w.setGroupProperty(PropertyInterface("Stroke Width",s)),l}function n(t,e,i){function r(e){return e===t.e.ix||"End"===e||"end"===e?r.end:e===t.s.ix?r.start:e===t.o.ix?r.offset:null}var s=propertyGroupFactory(r,i);return r.propertyIndex=t.ix,e.s.setGroupProperty(PropertyInterface("Start",s)),e.e.setGroupProperty(PropertyInterface("End",s)),e.o.setGroupProperty(PropertyInterface("Offset",s)),r.propertyIndex=t.ix,r.propertyGroup=i,Object.defineProperties(r,{start:{get:ExpressionPropertyInterface(e.s)},end:{get:ExpressionPropertyInterface(e.e)},offset:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm}}),r.mn=t.mn,r}function o(t,e,i){function r(e){return t.a.ix===e||"Anchor Point"===e?r.anchorPoint:t.o.ix===e||"Opacity"===e?r.opacity:t.p.ix===e||"Position"===e?r.position:t.r.ix===e||"Rotation"===e||"ADBE Vector Rotation"===e?r.rotation:t.s.ix===e||"Scale"===e?r.scale:t.sk&&t.sk.ix===e||"Skew"===e?r.skew:t.sa&&t.sa.ix===e||"Skew Axis"===e?r.skewAxis:null}var s=propertyGroupFactory(r,i);return e.transform.mProps.o.setGroupProperty(PropertyInterface("Opacity",s)),e.transform.mProps.p.setGroupProperty(PropertyInterface("Position",s)),e.transform.mProps.a.setGroupProperty(PropertyInterface("Anchor Point",s)),e.transform.mProps.s.setGroupProperty(PropertyInterface("Scale",s)),e.transform.mProps.r.setGroupProperty(PropertyInterface("Rotation",s)),e.transform.mProps.sk&&(e.transform.mProps.sk.setGroupProperty(PropertyInterface("Skew",s)),e.transform.mProps.sa.setGroupProperty(PropertyInterface("Skew Angle",s))),e.transform.op.setGroupProperty(PropertyInterface("Opacity",s)),Object.defineProperties(r,{opacity:{get:ExpressionPropertyInterface(e.transform.mProps.o)},position:{get:ExpressionPropertyInterface(e.transform.mProps.p)},anchorPoint:{get:ExpressionPropertyInterface(e.transform.mProps.a)},scale:{get:ExpressionPropertyInterface(e.transform.mProps.s)},rotation:{get:ExpressionPropertyInterface(e.transform.mProps.r)},skew:{get:ExpressionPropertyInterface(e.transform.mProps.sk)},skewAxis:{get:ExpressionPropertyInterface(e.transform.mProps.sa)},_name:{value:t.nm}}),r.ty="tr",r.mn=t.mn,r.propertyGroup=i,r}function h(t,e,i){function r(e){return t.p.ix===e?r.position:t.s.ix===e?r.size:null}var s=propertyGroupFactory(r,i);r.propertyIndex=t.ix;var a="tm"===e.sh.ty?e.sh.prop:e.sh;return a.s.setGroupProperty(PropertyInterface("Size",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),Object.defineProperties(r,{size:{get:ExpressionPropertyInterface(a.s)},position:{get:ExpressionPropertyInterface(a.p)},_name:{value:t.nm}}),r.mn=t.mn,r}function l(t,e,i){function r(e){return t.p.ix===e?r.position:t.r.ix===e?r.rotation:t.pt.ix===e?r.points:t.or.ix===e||"ADBE Vector Star Outer Radius"===e?r.outerRadius:t.os.ix===e?r.outerRoundness:!t.ir||t.ir.ix!==e&&"ADBE Vector Star Inner Radius"!==e?t.is&&t.is.ix===e?r.innerRoundness:null:r.innerRadius}var s=propertyGroupFactory(r,i),a="tm"===e.sh.ty?e.sh.prop:e.sh;return r.propertyIndex=t.ix,a.or.setGroupProperty(PropertyInterface("Outer Radius",s)),a.os.setGroupProperty(PropertyInterface("Outer Roundness",s)),a.pt.setGroupProperty(PropertyInterface("Points",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),t.ir&&(a.ir.setGroupProperty(PropertyInterface("Inner Radius",s)),a.is.setGroupProperty(PropertyInterface("Inner Roundness",s))),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(a.p)},rotation:{get:ExpressionPropertyInterface(a.r)},points:{get:ExpressionPropertyInterface(a.pt)},outerRadius:{get:ExpressionPropertyInterface(a.or)},outerRoundness:{get:ExpressionPropertyInterface(a.os)},innerRadius:{get:ExpressionPropertyInterface(a.ir)},innerRoundness:{get:ExpressionPropertyInterface(a.is)},_name:{value:t.nm}}),r.mn=t.mn,r}function p(t,e,i){function r(e){return t.p.ix===e?r.position:t.r.ix===e?r.roundness:t.s.ix===e||"Size"===e||"ADBE Vector Rect Size"===e?r.size:null}var s=propertyGroupFactory(r,i),a="tm"===e.sh.ty?e.sh.prop:e.sh;return r.propertyIndex=t.ix,a.p.setGroupProperty(PropertyInterface("Position",s)),a.s.setGroupProperty(PropertyInterface("Size",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(a.p)},roundness:{get:ExpressionPropertyInterface(a.r)},size:{get:ExpressionPropertyInterface(a.s)},_name:{value:t.nm}}),r.mn=t.mn,r}function f(t,e,i){function r(e){return t.r.ix===e||"Round Corners 1"===e?r.radius:null}var s=propertyGroupFactory(r,i),a=e;return r.propertyIndex=t.ix,a.rd.setGroupProperty(PropertyInterface("Radius",s)),Object.defineProperties(r,{radius:{get:ExpressionPropertyInterface(a.rd)},_name:{value:t.nm}}),r.mn=t.mn,r}function c(t,e,i){function r(e){return t.c.ix===e||"Copies"===e?r.copies:t.o.ix===e||"Offset"===e?r.offset:null}var s=propertyGroupFactory(r,i),a=e;return r.propertyIndex=t.ix,a.c.setGroupProperty(PropertyInterface("Copies",s)),a.o.setGroupProperty(PropertyInterface("Offset",s)),Object.defineProperties(r,{copies:{get:ExpressionPropertyInterface(a.c)},offset:{get:ExpressionPropertyInterface(a.o)},_name:{value:t.nm}}),r.mn=t.mn,r}return function(e,i,r){var s;function a(t){if("number"==typeof t)return 0===(t=void 0===t?1:t)?r:s[t-1];for(var e=0,i=s.length;e<i;){if(s[e]._name===t)return s[e];e+=1}return null}return a.propertyGroup=propertyGroupFactory(a,(function(){return r})),s=t(e,i,a.propertyGroup),a.numProperties=s.length,a._name="Contents",a}}(),TextExpressionInterface=function(t){var e;function i(t){return"ADBE Text Document"===t?i.sourceText:null}return Object.defineProperty(i,"sourceText",{get:function(){t.textProperty.getValue();var i=t.textProperty.currentData.t;return e&&i===e.value||((e=new String(i)).value=i||new String(i),Object.defineProperty(e,"style",{get:function(){return{fillColor:t.textProperty.currentData.fc}}})),e}}),i};function _typeof(t){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof(t)}var FootageInterface=(dataInterfaceFactory=function(t){function e(t){return"Outline"===t?e.outlineInterface():null}return e._name="Outline",e.outlineInterface=function(t){var e="",i=t.getFootageData();function r(t){if(i[t])return e=t,"object"===_typeof(i=i[t])?r:i;var s=t.indexOf(e);if(-1!==s){var a=parseInt(t.substr(s+e.length),10);return"object"===_typeof(i=i[a])?r:i}return""}return function(){return e="",i=t.getFootageData(),r}}(t),e},function(t){function e(t){return"Data"===t?e.dataInterface:null}return e._name="Data",e.dataInterface=dataInterfaceFactory(t),e}),dataInterfaceFactory,interfaces={layer:LayerExpressionInterface,effects:EffectsExpressionInterface,comp:CompExpressionInterface,shape:ShapeExpressionInterface,text:TextExpressionInterface,footage:FootageInterface};function getInterface(t){return interfaces[t]||null}var expressionHelpers={searchExpressions:function(t,e,i){e.x&&(i.k=!0,i.x=!0,i.initiateExpression=ExpressionManager.initiateExpression,i.effectsSequence.push(i.initiateExpression(t,e,i).bind(i)))},getSpeedAtTime:function(t){var e=this.getValueAtTime(t),i=this.getValueAtTime(t+-.01),r=0;if(e.length){var s;for(s=0;s<e.length;s+=1)r+=Math.pow(i[s]-e[s],2);r=100*Math.sqrt(r)}else r=0;return r},getVelocityAtTime:function(t){if(void 0!==this.vel)return this.vel;var e,i,r=-.001,s=this.getValueAtTime(t),a=this.getValueAtTime(t+r);if(s.length)for(e=createTypedArray("float32",s.length),i=0;i<s.length;i+=1)e[i]=(a[i]-s[i])/r;else e=(a-s)/r;return e},getValueAtTime:function(t){return t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastFrame&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastFrame<t?this._cachingAtTime.lastIndex:0,this._cachingAtTime.value=this.interpolateValue(t,this._cachingAtTime),this._cachingAtTime.lastFrame=t),this._cachingAtTime.value},getStaticValueAtTime:function(){return this.pv},setGroupProperty:function(t){this.propertyGroup=t}};function addPropertyDecorator(){function t(t,e,i){if(!this.k||!this.keyframes)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[l.length-1].t;if(h<=p)return this.pv;if(i?s=p-(r=e?Math.abs(p-this.elem.comp.globalData.frameRate*e):Math.max(0,p-this.elem.data.ip)):((!e||e>l.length-1)&&(e=l.length-1),r=p-(s=l[l.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/r)%2!=0)return this.getValueAtTime((r-(h-s)%r+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime(p/this.comp.globalData.frameRate,0),m=this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0),d=Math.floor((h-s)/r);if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=(c[a]-f[a])*d+m[a];return o}return(c-f)*d+m}if("continue"===t){var u=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p-.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*((h-p)/this.comp.globalData.frameRate)/5e-4;return o}return u+(h-p)/.001*(u-y)}}return this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0)}function e(t,e,i){if(!this.k)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[0].t;if(h>=p)return this.pv;if(i?s=p+(r=e?Math.abs(this.elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-p)):((!e||e>l.length-1)&&(e=l.length-1),r=(s=l[e].t)-p),"pingpong"===t){if(Math.floor((p-h)/r)%2==0)return this.getValueAtTime(((p-h)%r+p)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(p/this.comp.globalData.frameRate,0),c=this.getValueAtTime(s/this.comp.globalData.frameRate,0),m=this.getValueAtTime((r-(p-h)%r+p)/this.comp.globalData.frameRate,0),d=Math.floor((p-h)/r)+1;if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=m[a]-(c[a]-f[a])*d;return o}return m-(c-f)*d}if("continue"===t){var u=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p+.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*(p-h)/.001;return o}return u+(u-y)*(p-h)/.001}}return this.getValueAtTime((r-((p-h)%r+p))/this.comp.globalData.frameRate,0)}function i(t,e){if(!this.k)return this.pv;if(t=.5*(t||.4),(e=Math.floor(e||5))<=1)return this.pv;var i,r,s=this.comp.renderedFrame/this.comp.globalData.frameRate,a=s-t,n=e>1?(s+t-a)/(e-1):1,o=0,h=0;for(i=this.pv.length?createTypedArray("float32",this.pv.length):0;o<e;){if(r=this.getValueAtTime(a+o*n),this.pv.length)for(h=0;h<this.pv.length;h+=1)i[h]+=r[h];else i+=r;o+=1}if(this.pv.length)for(h=0;h<this.pv.length;h+=1)i[h]/=e;else i/=e;return i}function r(t){this._transformCachingAtTime||(this._transformCachingAtTime={v:new Matrix});var e=this._transformCachingAtTime.v;if(e.cloneFromProps(this.pre.props),this.appliedTransformations<1){var i=this.a.getValueAtTime(t);e.translate(-i[0]*this.a.mult,-i[1]*this.a.mult,i[2]*this.a.mult)}if(this.appliedTransformations<2){var r=this.s.getValueAtTime(t);e.scale(r[0]*this.s.mult,r[1]*this.s.mult,r[2]*this.s.mult)}if(this.sk&&this.appliedTransformations<3){var s=this.sk.getValueAtTime(t),a=this.sa.getValueAtTime(t);e.skewFromAxis(-s*this.sk.mult,a*this.sa.mult)}if(this.r&&this.appliedTransformations<4){var n=this.r.getValueAtTime(t);e.rotate(-n*this.r.mult)}else if(!this.r&&this.appliedTransformations<4){var o=this.rz.getValueAtTime(t),h=this.ry.getValueAtTime(t),l=this.rx.getValueAtTime(t),p=this.or.getValueAtTime(t);e.rotateZ(-o*this.rz.mult).rotateY(h*this.ry.mult).rotateX(l*this.rx.mult).rotateZ(-p[2]*this.or.mult).rotateY(p[1]*this.or.mult).rotateX(p[0]*this.or.mult)}if(this.data.p&&this.data.p.s){var f=this.px.getValueAtTime(t),c=this.py.getValueAtTime(t);if(this.data.p.z){var m=this.pz.getValueAtTime(t);e.translate(f*this.px.mult,c*this.py.mult,-m*this.pz.mult)}else e.translate(f*this.px.mult,c*this.py.mult,0)}else{var d=this.p.getValueAtTime(t);e.translate(d[0]*this.p.mult,d[1]*this.p.mult,-d[2]*this.p.mult)}return e}function s(){return this.v.clone(new Matrix)}var a=TransformPropertyFactory.getTransformProperty;TransformPropertyFactory.getTransformProperty=function(t,e,i){var n=a(t,e,i);return n.dynamicProperties.length?n.getValueAtTime=r.bind(n):n.getValueAtTime=s.bind(n),n.setGroupProperty=expressionHelpers.setGroupProperty,n};var n=PropertyFactory.getProp;PropertyFactory.getProp=function(r,s,a,o,h){var l=n(r,s,a,o,h);l.kf?l.getValueAtTime=expressionHelpers.getValueAtTime.bind(l):l.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(l),l.setGroupProperty=expressionHelpers.setGroupProperty,l.loopOut=t,l.loopIn=e,l.smooth=i,l.getVelocityAtTime=expressionHelpers.getVelocityAtTime.bind(l),l.getSpeedAtTime=expressionHelpers.getSpeedAtTime.bind(l),l.numKeys=1===s.a?s.k.length:0,l.propertyIndex=s.ix;var p=0;return 0!==a&&(p=createTypedArray("float32",1===s.a?s.k[0].s.length:s.k.length)),l._cachingAtTime={lastFrame:initialDefaultFrame,lastIndex:0,value:p},expressionHelpers.searchExpressions(r,s,l),l.k&&h.addDynamicProperty(l),l};var o=ShapePropertyFactory.getConstructorFunction(),h=ShapePropertyFactory.getKeyframedConstructorFunction();function l(){}l.prototype={vertices:function(t,e){this.k&&this.getValue();var i,r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0));var s=r._length,a=r[t],n=r.v,o=createSizedArray(s);for(i=0;i<s;i+=1)o[i]="i"===t||"o"===t?[a[i][0]-n[i][0],a[i][1]-n[i][1]]:[a[i][0],a[i][1]];return o},points:function(t){return this.vertices("v",t)},inTangents:function(t){return this.vertices("i",t)},outTangents:function(t){return this.vertices("o",t)},isClosed:function(){return this.v.c},pointOnPath:function(t,e){var i=this.v;void 0!==e&&(i=this.getValueAtTime(e,0)),this._segmentsLength||(this._segmentsLength=bez.getSegmentsLength(i));for(var r,s=this._segmentsLength,a=s.lengths,n=s.totalLength*t,o=0,h=a.length,l=0;o<h;){if(l+a[o].addedLength>n){var p=o,f=i.c&&o===h-1?0:o+1,c=(n-l)/a[o].addedLength;r=bez.getPointInSegment(i.v[p],i.v[f],i.o[p],i.i[f],c,a[o]);break}l+=a[o].addedLength,o+=1}return r||(r=i.c?[i.v[0][0],i.v[0][1]]:[i.v[i._length-1][0],i.v[i._length-1][1]]),r},vectorOnPath:function(t,e,i){1==t?t=this.v.c:0==t&&(t=.999);var r=this.pointOnPath(t,e),s=this.pointOnPath(t+.001,e),a=s[0]-r[0],n=s[1]-r[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return 0===o?[0,0]:"tangent"===i?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([l],o),extendPrototype([l],h),h.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shapePool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime<t?this._caching.lastIndex:0,this._cachingAtTime.lastTime=t,this.interpolateShape(t,this._cachingAtTime.shapeValue,this._cachingAtTime)),this._cachingAtTime.shapeValue},h.prototype.initiateExpression=ExpressionManager.initiateExpression;var p=ShapePropertyFactory.getShapeProp;ShapePropertyFactory.getShapeProp=function(t,e,i,r,s){var a=p(t,e,i,r,s);return a.propertyIndex=e.ix,a.lock=!1,3===i?expressionHelpers.searchExpressions(t,e.pt,a):4===i&&expressionHelpers.searchExpressions(t,e.ks,a),a.k&&t.addDynamicProperty(a),a}}function initialize$1(){addPropertyDecorator()}function addDecorator(){TextProperty.prototype.getExpressionValue=function(t,e){var i=this.calculateExpression(e);if(t.t!==i){var r={};return this.copyData(r,t),r.t=i.toString(),r.__complete=!1,r}return t},TextProperty.prototype.searchProperty=function(){var t=this.searchKeyframes(),e=this.searchExpressions();return this.kf=t||e,this.kf},TextProperty.prototype.searchExpressions=function(){return this.data.d.x?(this.calculateExpression=ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this),this.addEffect(this.getExpressionValue.bind(this)),!0):null}}function initialize(){addDecorator()}function TransformEffect(){}function CVTransformEffect(t){this.init(t)}return TransformEffect.prototype.init=function(t){this.effectsManager=t,this.type=effectTypes.TRANSFORM_EFFECT,this.matrix=new Matrix,this.opacity=-1,this._mdf=!1,this._opMdf=!1},TransformEffect.prototype.renderFrame=function(t){if(this._opMdf=!1,this._mdf=!1,t||this.effectsManager._mdf){var e=this.effectsManager.effectElements,i=e[0].p.v,r=e[1].p.v,s=1===e[2].p.v,a=e[3].p.v,n=s?a:e[4].p.v,o=e[5].p.v,h=e[6].p.v,l=e[7].p.v;this.matrix.reset(),this.matrix.translate(-i[0],-i[1],i[2]),this.matrix.scale(.01*n,.01*a,1),this.matrix.rotate(-l*degToRads),this.matrix.skewFromAxis(-o*degToRads,(h+90)*degToRads),this.matrix.translate(r[0],r[1],0),this._mdf=!0,this.opacity!==e[8].p.v&&(this.opacity=e[8].p.v,this._opMdf=!0)}},extendPrototype([TransformEffect],CVTransformEffect),setExpressionsPlugin(Expressions),setExpressionInterfaces(getInterface),initialize$1(),initialize(),registerEffect(35,CVTransformEffect),lottie}));
+"undefined"!=typeof document&&"undefined"!=typeof navigator&&function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lottie=e()}(this,(function(){"use strict";var svgNS="http://www.w3.org/2000/svg",locationHref="",_useWebWorker=!1,initialDefaultFrame=-999999,setWebWorker=function(t){_useWebWorker=!!t},getWebWorker=function(){return _useWebWorker},setLocationHref=function(t){locationHref=t},getLocationHref=function(){return locationHref};function createTag(t){return document.createElement(t)}function extendPrototype(t,e){var i,r,s=t.length;for(i=0;i<s;i+=1)for(var a in r=t[i].prototype)Object.prototype.hasOwnProperty.call(r,a)&&(e.prototype[a]=r[a])}function getDescriptor(t,e){return Object.getOwnPropertyDescriptor(t,e)}function createProxyFunction(t){function e(){}return e.prototype=t,e}var audioControllerFactory=function(){function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].pause()},resume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].resume()},setRate:function(t){var e,i=this.audios.length;for(e=0;e<i;e+=1)this.audios[e].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}}(),createTypedArray=function(){function t(t,e){var i,r=0,s=[];switch(t){case"int16":case"uint8c":i=1;break;default:i=1.1}for(r=0;r<e;r+=1)s.push(i);return s}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(e,i){return"float32"===e?new Float32Array(i):"int16"===e?new Int16Array(i):"uint8c"===e?new Uint8ClampedArray(i):t(e,i)}:t}();function createSizedArray(t){return Array.apply(null,{length:t})}function _typeof$6(t){return _typeof$6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$6(t)}var subframeEnabled=!0,expressionsPlugin=null,expressionsInterfaces=null,idPrefix$1="",isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),_shouldRoundValues=!1,bmPow=Math.pow,bmSqrt=Math.sqrt,bmFloor=Math.floor,bmMax=Math.max,bmMin=Math.min,BMMath={};function ProjectInterface$1(){return{}}!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],i=e.length;for(t=0;t<i;t+=1)BMMath[e[t]]=Math[e[t]]}(),BMMath.random=Math.random,BMMath.abs=function(t){if("object"===_typeof$6(t)&&t.length){var e,i=createSizedArray(t.length),r=t.length;for(e=0;e<r;e+=1)i[e]=Math.abs(t[e]);return i}return Math.abs(t)};var defaultCurveSegments=150,degToRads=Math.PI/180,roundCorner=.5519;function roundValues(t){_shouldRoundValues=!!t}function bmRnd(t){return _shouldRoundValues?Math.round(t):t}function styleDiv(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin="0 0",t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility="visible",t.style.webkitBackfaceVisibility="visible",t.style.transformStyle="preserve-3d",t.style.webkitTransformStyle="preserve-3d",t.style.mozTransformStyle="preserve-3d"}function BMEnterFrameEvent(t,e,i,r){this.type=t,this.currentTime=e,this.totalTime=i,this.direction=r<0?-1:1}function BMCompleteEvent(t,e){this.type=t,this.direction=e<0?-1:1}function BMCompleteLoopEvent(t,e,i,r){this.type=t,this.currentLoop=i,this.totalLoops=e,this.direction=r<0?-1:1}function BMSegmentStartEvent(t,e,i){this.type=t,this.firstFrame=e,this.totalFrames=i}function BMDestroyEvent(t,e){this.type=t,this.target=e}function BMRenderFrameErrorEvent(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function BMConfigErrorEvent(t){this.type="configError",this.nativeError=t}function BMAnimationConfigErrorEvent(t,e){this.type=t,this.nativeError=e}var createElementID=(_count=0,function(){return idPrefix$1+"__lottie_element_"+(_count+=1)}),_count;function HSVtoRGB(t,e,i){var r,s,a,n,o,h,l,p;switch(h=i*(1-e),l=i*(1-(o=6*t-(n=Math.floor(6*t)))*e),p=i*(1-(1-o)*e),n%6){case 0:r=i,s=p,a=h;break;case 1:r=l,s=i,a=h;break;case 2:r=h,s=i,a=p;break;case 3:r=h,s=l,a=i;break;case 4:r=p,s=h,a=i;break;case 5:r=i,s=h,a=l}return[r,s,a]}function RGBtoHSV(t,e,i){var r,s=Math.max(t,e,i),a=Math.min(t,e,i),n=s-a,o=0===s?0:n/s,h=s/255;switch(s){case a:r=0;break;case t:r=e-i+n*(e<i?6:0),r/=6*n;break;case e:r=i-t+2*n,r/=6*n;break;case i:r=t-e+4*n,r/=6*n}return[r,o,h]}function addSaturationToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[1]+=e,i[1]>1?i[1]=1:i[1]<=0&&(i[1]=0),HSVtoRGB(i[0],i[1],i[2])}function addBrightnessToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[2]+=e,i[2]>1?i[2]=1:i[2]<0&&(i[2]=0),HSVtoRGB(i[0],i[1],i[2])}function addHueToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[0]+=e/360,i[0]>1?i[0]-=1:i[0]<0&&(i[0]+=1),HSVtoRGB(i[0],i[1],i[2])}var rgbToHex=function(){var t,e,i=[];for(t=0;t<256;t+=1)e=t.toString(16),i[t]=1===e.length?"0"+e:e;return function(t,e,r){return t<0&&(t=0),e<0&&(e=0),r<0&&(r=0),"#"+i[t]+i[e]+i[r]}}(),setSubframeEnabled=function(t){subframeEnabled=!!t},getSubframeEnabled=function(){return subframeEnabled},setExpressionsPlugin=function(t){expressionsPlugin=t},getExpressionsPlugin=function(){return expressionsPlugin},setExpressionInterfaces=function(t){expressionsInterfaces=t},getExpressionInterfaces=function(){return expressionsInterfaces},setDefaultCurveSegments=function(t){defaultCurveSegments=t},getDefaultCurveSegments=function(){return defaultCurveSegments},setIdPrefix=function(t){idPrefix$1=t},getIdPrefix=function(){return idPrefix$1};function createNS(t){return document.createElementNS(svgNS,t)}function _typeof$5(t){return _typeof$5="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$5(t)}var dataManager=function(){var t,e,i=1,r=[],s={onmessage:function(){},postMessage:function(e){t({data:e})}},a={postMessage:function(t){s.onmessage({data:t})}};function n(){e||(e=function(e){if(window.Worker&&window.Blob&&getWebWorker()){var i=new Blob(["var _workerSelf = self; self.onmessage = ",e.toString()],{type:"text/javascript"}),r=URL.createObjectURL(i);return new Worker(r)}return t=e,s}((function(t){if(a.dataManager||(a.dataManager=function(){function t(s,a){var n,o,h,l,p,c,m=s.length;for(o=0;o<m;o+=1)if("ks"in(n=s[o])&&!n.completed){if(n.completed=!0,n.hasMask){var d=n.masksProperties;for(l=d.length,h=0;h<l;h+=1)if(d[h].pt.k.i)r(d[h].pt.k);else for(c=d[h].pt.k.length,p=0;p<c;p+=1)d[h].pt.k[p].s&&r(d[h].pt.k[p].s[0]),d[h].pt.k[p].e&&r(d[h].pt.k[p].e[0])}0===n.ty?(n.layers=e(n.refId,a),t(n.layers,a)):4===n.ty?i(n.shapes):5===n.ty&&f(n)}}function e(t,e){var i=function(t,e){for(var i=0,r=e.length;i<r;){if(e[i].id===t)return e[i];i+=1}return null}(t,e);return i?i.layers.__used?JSON.parse(JSON.stringify(i.layers)):(i.layers.__used=!0,i.layers):null}function i(t){var e,s,a;for(e=t.length-1;e>=0;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)r(t[e].ks.k);else for(a=t[e].ks.k.length,s=0;s<a;s+=1)t[e].ks.k[s].s&&r(t[e].ks.k[s].s[0]),t[e].ks.k[s].e&&r(t[e].ks.k[s].e[0]);else"gr"===t[e].ty&&i(t[e].it)}function r(t){var e,i=t.i.length;for(e=0;e<i;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function s(t,e){var i=e?e.split("."):[100,100,100];return t[0]>i[0]||!(i[0]>t[0])&&(t[1]>i[1]||!(i[1]>t[1])&&(t[2]>i[2]||!(i[2]>t[2])&&null))}var a,n=function(){var t=[4,4,14];function e(t){var e,i,r,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(r=void 0,r=(i=t[e]).t.d,i.t.d={k:[{s:r,t:0}]})}return function(i){if(s(t,i.v)&&(e(i.layers),i.assets)){var r,a=i.assets.length;for(r=0;r<a;r+=1)i.assets[r].layers&&e(i.assets[r].layers)}}}(),o=(a=[4,7,99],function(t){if(t.chars&&!s(a,t.v)){var e,r=t.chars.length;for(e=0;e<r;e+=1){var n=t.chars[e];n.data&&n.data.shapes&&(i(n.data.shapes),n.data.ip=0,n.data.op=99999,n.data.st=0,n.data.sr=1,n.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[e].t||(n.data.shapes.push({ty:"no"}),n.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}}}),h=function(){var t=[5,7,15];function e(t){var e,i,r=t.length;for(e=0;e<r;e+=1)5===t[e].ty&&(i=void 0,"number"==typeof(i=t[e].t.p).a&&(i.a={a:0,k:i.a}),"number"==typeof i.p&&(i.p={a:0,k:i.p}),"number"==typeof i.r&&(i.r={a:0,k:i.r}))}return function(i){if(s(t,i.v)&&(e(i.layers),i.assets)){var r,a=i.assets.length;for(r=0;r<a;r+=1)i.assets[r].layers&&e(i.assets[r].layers)}}}(),l=function(){var t=[4,1,9];function e(t){var i,r,s,a=t.length;for(i=0;i<a;i+=1)if("gr"===t[i].ty)e(t[i].it);else if("fl"===t[i].ty||"st"===t[i].ty)if(t[i].c.k&&t[i].c.k[0].i)for(s=t[i].c.k.length,r=0;r<s;r+=1)t[i].c.k[r].s&&(t[i].c.k[r].s[0]/=255,t[i].c.k[r].s[1]/=255,t[i].c.k[r].s[2]/=255,t[i].c.k[r].s[3]/=255),t[i].c.k[r].e&&(t[i].c.k[r].e[0]/=255,t[i].c.k[r].e[1]/=255,t[i].c.k[r].e[2]/=255,t[i].c.k[r].e[3]/=255);else t[i].c.k[0]/=255,t[i].c.k[1]/=255,t[i].c.k[2]/=255,t[i].c.k[3]/=255}function i(t){var i,r=t.length;for(i=0;i<r;i+=1)4===t[i].ty&&e(t[i].shapes)}return function(e){if(s(t,e.v)&&(i(e.layers),e.assets)){var r,a=e.assets.length;for(r=0;r<a;r+=1)e.assets[r].layers&&i(e.assets[r].layers)}}}(),p=function(){var t=[4,4,18];function e(t){var i,r,s;for(i=t.length-1;i>=0;i-=1)if("sh"===t[i].ty)if(t[i].ks.k.i)t[i].ks.k.c=t[i].closed;else for(s=t[i].ks.k.length,r=0;r<s;r+=1)t[i].ks.k[r].s&&(t[i].ks.k[r].s[0].c=t[i].closed),t[i].ks.k[r].e&&(t[i].ks.k[r].e[0].c=t[i].closed);else"gr"===t[i].ty&&e(t[i].it)}function i(t){var i,r,s,a,n,o,h=t.length;for(r=0;r<h;r+=1){if((i=t[r]).hasMask){var l=i.masksProperties;for(a=l.length,s=0;s<a;s+=1)if(l[s].pt.k.i)l[s].pt.k.c=l[s].cl;else for(o=l[s].pt.k.length,n=0;n<o;n+=1)l[s].pt.k[n].s&&(l[s].pt.k[n].s[0].c=l[s].cl),l[s].pt.k[n].e&&(l[s].pt.k[n].e[0].c=l[s].cl)}4===i.ty&&e(i.shapes)}}return function(e){if(s(t,e.v)&&(i(e.layers),e.assets)){var r,a=e.assets.length;for(r=0;r<a;r+=1)e.assets[r].layers&&i(e.assets[r].layers)}}}();function f(t){0===t.t.a.length&&t.t.p}var c={completeData:function(i){i.__complete||(l(i),n(i),o(i),h(i),p(i),t(i.layers,i.assets),function(i,r){if(i){var s=0,a=i.length;for(s=0;s<a;s+=1)1===i[s].t&&(i[s].data.layers=e(i[s].data.refId,r),t(i[s].data.layers,r))}}(i.chars,i.assets),i.__complete=!0)}};return c.checkColors=l,c.checkChars=o,c.checkPathProperties=h,c.checkShapes=p,c.completeLayers=t,c}()),a.assetLoader||(a.assetLoader=function(){function t(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")||t.response&&"object"===_typeof$5(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}return{load:function(e,i,r,s){var a,n=new XMLHttpRequest;try{n.responseType="json"}catch(t){}n.onreadystatechange=function(){if(4===n.readyState)if(200===n.status)a=t(n),r(a);else try{a=t(n),r(a)}catch(t){s&&s(t)}};try{n.open(["G","E","T"].join(""),e,!0)}catch(t){n.open(["G","E","T"].join(""),i+"/"+e,!0)}n.send()}}}()),"loadAnimation"===t.data.type)a.assetLoader.load(t.data.path,t.data.fullPath,(function(e){a.dataManager.completeData(e),a.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){a.postMessage({id:t.data.id,status:"error"})}));else if("complete"===t.data.type){var e=t.data.animation;a.dataManager.completeData(e),a.postMessage({id:t.data.id,payload:e,status:"success"})}else"loadData"===t.data.type&&a.assetLoader.load(t.data.path,t.data.fullPath,(function(e){a.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){a.postMessage({id:t.data.id,status:"error"})}))})),e.onmessage=function(t){var e=t.data,i=e.id,s=r[i];r[i]=null,"success"===e.status?s.onComplete(e.payload):s.onError&&s.onError()})}function o(t,e){var s="processId_"+(i+=1);return r[s]={onComplete:t,onError:e},s}return{loadAnimation:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:s})},loadData:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:s})},completeAnimation:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"complete",animation:t,id:s})}}}(),ImagePreloader=function(){var t=function(){var t=createTag("canvas");t.width=1,t.height=1;var e=t.getContext("2d");return e.fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1),t}();function e(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function i(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function r(t,e,i){var r="";if(t.e)r=t.p;else if(e){var s=t.p;-1!==s.indexOf("images/")&&(s=s.split("/")[1]),r=e+s}else r=i,r+=t.u?t.u:"",r+=t.p;return r}function s(t){var e=0,i=setInterval(function(){(t.getBBox().width||e>500)&&(this._imageLoaded(),clearInterval(i)),e+=1}.bind(this),50)}function a(t){var e={assetData:t},i=r(t,this.assetsPath,this.path);return dataManager.loadData(i,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}function n(){this._imageLoaded=e.bind(this),this._footageLoaded=i.bind(this),this.testImageLoaded=s.bind(this),this.createFootageData=a.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return n.prototype={loadAssets:function(t,e){var i;this.imagesLoadedCb=e;var r=t.length;for(i=0;i<r;i+=1)t[i].layers||(t[i].t&&"seq"!==t[i].t?3===t[i].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[i]))):(this.totalImages+=1,this.images.push(this._createImageData(t[i]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,i=this.images.length;e<i;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(e){var i=r(e,this.assetsPath,this.path),s=createTag("img");s.crossOrigin="anonymous",s.addEventListener("load",this._imageLoaded,!1),s.addEventListener("error",function(){a.img=t,this._imageLoaded()}.bind(this),!1),s.src=i;var a={img:s,assetData:e};return a},createImageData:function(e){var i=r(e,this.assetsPath,this.path),s=createNS("image");isSafari?this.testImageLoaded(s):s.addEventListener("load",this._imageLoaded,!1),s.addEventListener("error",function(){a.img=t,this._imageLoaded()}.bind(this),!1),s.setAttributeNS("http://www.w3.org/1999/xlink","href",i),this._elementHelper.append?this._elementHelper.append(s):this._elementHelper.appendChild(s);var a={img:s,assetData:e};return a},imageLoaded:e,footageLoaded:i,setCacheType:function(t,e){"svg"===t?(this._elementHelper=e,this._createImageData=this.createImageData.bind(this)):this._createImageData=this.createImgData.bind(this)}},n}();function BaseEvent(){}BaseEvent.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var i=this._cbs[t],r=0;r<i.length;r+=1)i[r](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var i=0,r=this._cbs[t].length;i<r;)this._cbs[t][i]===e&&(this._cbs[t].splice(i,1),i-=1,r-=1),i+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var markerParser=function(){function t(t){for(var e,i=t.split("\r\n"),r={},s=0,a=0;a<i.length;a+=1)2===(e=i[a].split(":")).length&&(r[e[0]]=e[1].trim(),s+=1);if(0===s)throw new Error;return r}return function(e){for(var i=[],r=0;r<e.length;r+=1){var s=e[r],a={time:s.tm,duration:s.dr};try{a.payload=JSON.parse(e[r].cm)}catch(i){try{a.payload=t(e[r].cm)}catch(t){a.payload={name:e[r].cm}}}i.push(a)}return i}}(),ProjectInterface=function(){function t(t){this.compositions.push(t)}return function(){function e(t){for(var e=0,i=this.compositions.length;e<i;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return e.compositions=[],e.currentFrame=0,e.registerComposition=t,e}}(),renderers={},registerRenderer=function(t,e){renderers[t]=e};function getRenderer(t){return renderers[t]}function getRegisteredRenderer(){if(renderers.canvas)return"canvas";for(var t in renderers)if(renderers[t])return t;return""}function _typeof$4(t){return _typeof$4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$4(t)}var AnimationItem=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=createElementID(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=getSubframeEnabled(),this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=ProjectInterface(),this.imagePreloader=new ImagePreloader,this.audioController=audioControllerFactory(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new BMEnterFrameEvent("drawnFrame",0,0,0),this.expressionsPlugin=getExpressionsPlugin()};extendPrototype([BaseEvent],AnimationItem),AnimationItem.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg";t.animType?e=t.animType:t.renderer&&(e=t.renderer);var i=getRenderer(e);this.renderer=new i(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||void 0===t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),dataManager.loadAnimation(t.path,this.configAnimation,this.onSetupError))},AnimationItem.prototype.onSetupError=function(){this.trigger("data_failed")},AnimationItem.prototype.setupAnimation=function(t){dataManager.completeAnimation(t,this.configAnimation)},AnimationItem.prototype.setData=function(t,e){e&&"object"!==_typeof$4(e)&&(e=JSON.parse(e));var i={wrapper:t,animationData:e},r=t.attributes;i.path=r.getNamedItem("data-animation-path")?r.getNamedItem("data-animation-path").value:r.getNamedItem("data-bm-path")?r.getNamedItem("data-bm-path").value:r.getNamedItem("bm-path")?r.getNamedItem("bm-path").value:"",i.animType=r.getNamedItem("data-anim-type")?r.getNamedItem("data-anim-type").value:r.getNamedItem("data-bm-type")?r.getNamedItem("data-bm-type").value:r.getNamedItem("bm-type")?r.getNamedItem("bm-type").value:r.getNamedItem("data-bm-renderer")?r.getNamedItem("data-bm-renderer").value:r.getNamedItem("bm-renderer")?r.getNamedItem("bm-renderer").value:getRegisteredRenderer()||"canvas";var s=r.getNamedItem("data-anim-loop")?r.getNamedItem("data-anim-loop").value:r.getNamedItem("data-bm-loop")?r.getNamedItem("data-bm-loop").value:r.getNamedItem("bm-loop")?r.getNamedItem("bm-loop").value:"";"false"===s?i.loop=!1:"true"===s?i.loop=!0:""!==s&&(i.loop=parseInt(s,10));var a=r.getNamedItem("data-anim-autoplay")?r.getNamedItem("data-anim-autoplay").value:r.getNamedItem("data-bm-autoplay")?r.getNamedItem("data-bm-autoplay").value:!r.getNamedItem("bm-autoplay")||r.getNamedItem("bm-autoplay").value;i.autoplay="false"!==a,i.name=r.getNamedItem("data-name")?r.getNamedItem("data-name").value:r.getNamedItem("data-bm-name")?r.getNamedItem("data-bm-name").value:r.getNamedItem("bm-name")?r.getNamedItem("bm-name").value:"","false"===(r.getNamedItem("data-anim-prerender")?r.getNamedItem("data-anim-prerender").value:r.getNamedItem("data-bm-prerender")?r.getNamedItem("data-bm-prerender").value:r.getNamedItem("bm-prerender")?r.getNamedItem("bm-prerender").value:"")&&(i.prerender=!1),i.path?this.setParams(i):this.trigger("destroy")},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,i,r=this.animationData.layers,s=r.length,a=t.layers,n=a.length;for(i=0;i<n;i+=1)for(e=0;e<s;){if(r[e].id===a[i].id){r[e]=a[i];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(s=t.assets.length,e=0;e<s;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,dataManager.completeAnimation(this.animationData,this.onSegmentComplete)},AnimationItem.prototype.onSegmentComplete=function(t){this.animationData=t;var e=getExpressionsPlugin();e&&e.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var i=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,dataManager.loadData(i,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},AnimationItem.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},AnimationItem.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=markerParser(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},AnimationItem.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},AnimationItem.prototype.checkLoaded=function(){if(!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()){this.isLoaded=!0;var t=getExpressionsPlugin();t&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play()}},AnimationItem.prototype.resize=function(t,e){var i="number"==typeof t?t:void 0,r="number"==typeof e?e:void 0;this.renderer.updateContainerSize(i,r)},AnimationItem.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},AnimationItem.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},AnimationItem.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},AnimationItem.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},AnimationItem.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.getMarkerData=function(t){for(var e,i=0;i<this.markers.length;i+=1)if((e=this.markers[i]).payload&&e.payload.name===t)return e;return null},AnimationItem.prototype.goToAndStop=function(t,e,i){if(!i||this.name===i){var r=Number(t);if(isNaN(r)){var s=this.getMarkerData(t);s&&this.goToAndStop(s.time,!0)}else e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier);this.pause()}},AnimationItem.prototype.goToAndPlay=function(t,e,i){if(!i||this.name===i){var r=Number(t);if(isNaN(r)){var s=this.getMarkerData(t);s&&(s.duration?this.playSegments([s.time,s.time+s.duration],!0):this.goToAndStop(s.time,!0))}else this.goToAndStop(r,e,i);this.play()}},AnimationItem.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,i=!1;e>=this.totalFrames-1&&this.frameModifier>0?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(i=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(i=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),i&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(this.frameModifier>0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var i=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?i=t:this.currentRawFrame+this.firstFrame>e&&(i=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==i&&this.goToAndStop(i,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===_typeof$4(t[0])){var i,r=t.length;for(i=0;i<r;i+=1)this.segments.push(t[i])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},AnimationItem.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},AnimationItem.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},AnimationItem.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},AnimationItem.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},AnimationItem.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},AnimationItem.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},AnimationItem.prototype.setLoop=function(t){this.loop=t},AnimationItem.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},AnimationItem.prototype.getVolume=function(){return this.audioController.getVolume()},AnimationItem.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},AnimationItem.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},AnimationItem.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},AnimationItem.prototype.getPath=function(){return this.path},AnimationItem.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var i=t.p;-1!==i.indexOf("images/")&&(i=i.split("/")[1]),e=this.assetsPath+i}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},AnimationItem.prototype.getAssetData=function(t){for(var e=0,i=this.assets.length;e<i;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},AnimationItem.prototype.hide=function(){this.renderer.hide()},AnimationItem.prototype.show=function(){this.renderer.show()},AnimationItem.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},AnimationItem.prototype.updateDocumentData=function(t,e,i){try{this.renderer.getElementByPath(t).updateDocumentData(e,i)}catch(t){}},AnimationItem.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new BMCompleteEvent(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new BMDestroyEvent(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new BMCompleteEvent(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new BMDestroyEvent(t,this))},AnimationItem.prototype.triggerRenderFrameError=function(t){var e=new BMRenderFrameErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)},AnimationItem.prototype.triggerConfigError=function(t){var e=new BMConfigErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)};var animationManager=function(){var t={},e=[],i=0,r=0,s=0,a=!0,n=!1;function o(t){for(var i=0,s=t.target;i<r;)e[i].animation===s&&(e.splice(i,1),i-=1,r-=1,s.isPaused||p()),i+=1}function h(t,i){if(!t)return null;for(var s=0;s<r;){if(e[s].elem===t&&null!==e[s].elem)return e[s].animation;s+=1}var a=new AnimationItem;return f(a,t),a.setData(t,i),a}function l(){s+=1,d()}function p(){s-=1}function f(t,i){t.addEventListener("destroy",o),t.addEventListener("_active",l),t.addEventListener("_idle",p),e.push({elem:i,animation:t}),r+=1}function c(t){var o,h=t-i;for(o=0;o<r;o+=1)e[o].animation.advanceTime(h);i=t,s&&!n?window.requestAnimationFrame(c):a=!0}function m(t){i=t,window.requestAnimationFrame(c)}function d(){!n&&s&&a&&(window.requestAnimationFrame(m),a=!1)}return t.registerAnimation=h,t.loadAnimation=function(t){var e=new AnimationItem;return f(e,null),e.setParams(t),e},t.setSpeed=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setSpeed(t,i)},t.setDirection=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setDirection(t,i)},t.play=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.play(t)},t.pause=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.pause(t)},t.stop=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.stop(t)},t.togglePause=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.togglePause(t)},t.searchAnimations=function(t,e,i){var r,s=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),a=s.length;for(r=0;r<a;r+=1)i&&s[r].setAttribute("data-bm-type",i),h(s[r],t);if(e&&0===a){i||(i="svg");var n=document.getElementsByTagName("body")[0];n.innerText="";var o=createTag("div");o.style.width="100%",o.style.height="100%",o.setAttribute("data-bm-type",i),n.appendChild(o),h(o,t)}},t.resize=function(){var t;for(t=0;t<r;t+=1)e[t].animation.resize()},t.goToAndStop=function(t,i,s){var a;for(a=0;a<r;a+=1)e[a].animation.goToAndStop(t,i,s)},t.destroy=function(t){var i;for(i=r-1;i>=0;i-=1)e[i].animation.destroy(t)},t.freeze=function(){n=!0},t.unfreeze=function(){n=!1,d()},t.setVolume=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setVolume(t,i)},t.mute=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.mute(t)},t.unmute=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.unmute(t)},t.getRegisteredAnimations=function(){var t,i=e.length,r=[];for(t=0;t<i;t+=1)r.push(e[t].animation);return r},t}(),BezierFactory=function(){var t={getBezierEasing:function(t,i,r,s,a){var n=a||("bez_"+t+"_"+i+"_"+r+"_"+s).replace(/\./g,"p");if(e[n])return e[n];var o=new p([t,i,r,s]);return e[n]=o,o}},e={};var i=11,r=1/(i-1),s="function"==typeof Float32Array;function a(t,e){return 1-3*e+3*t}function n(t,e){return 3*e-6*t}function o(t){return 3*t}function h(t,e,i){return((a(e,i)*t+n(e,i))*t+o(e))*t}function l(t,e,i){return 3*a(e,i)*t*t+2*n(e,i)*t+o(e)}function p(t){this._p=t,this._mSampleValues=s?new Float32Array(i):new Array(i),this._precomputed=!1,this.get=this.get.bind(this)}return p.prototype={get:function(t){var e=this._p[0],i=this._p[1],r=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===i&&r===s?t:0===t?0:1===t?1:h(this._getTForX(t),i,s)},_precompute:function(){var t=this._p[0],e=this._p[1],i=this._p[2],r=this._p[3];this._precomputed=!0,t===e&&i===r||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],s=0;s<i;++s)this._mSampleValues[s]=h(s*r,t,e)},_getTForX:function(t){for(var e=this._p[0],s=this._p[2],a=this._mSampleValues,n=0,o=1,p=i-1;o!==p&&a[o]<=t;++o)n+=r;var f=n+(t-a[--o])/(a[o+1]-a[o])*r,c=l(f,e,s);return c>=.001?function(t,e,i,r){for(var s=0;s<4;++s){var a=l(e,i,r);if(0===a)return e;e-=(h(e,i,r)-t)/a}return e}(t,f,e,s):0===c?f:function(t,e,i,r,s){var a,n,o=0;do{(a=h(n=e+(i-e)/2,r,s)-t)>0?i=n:e=n}while(Math.abs(a)>1e-7&&++o<10);return n}(t,n,n+r,e,s)}},t}(),pooling={double:function(t){return t.concat(createSizedArray(t.length))}},poolFactory=function(t,e,i){var r=0,s=t,a=createSizedArray(s);return{newElement:function(){return r?a[r-=1]:e()},release:function(t){r===s&&(a=pooling.double(a),s*=2),i&&i(t),a[r]=t,r+=1}}},bezierLengthPool=poolFactory(8,(function(){return{addedLength:0,percents:createTypedArray("float32",getDefaultCurveSegments()),lengths:createTypedArray("float32",getDefaultCurveSegments())}})),segmentsLengthPool=poolFactory(8,(function(){return{lengths:[],totalLength:0}}),(function(t){var e,i=t.lengths.length;for(e=0;e<i;e+=1)bezierLengthPool.release(t.lengths[e]);t.lengths.length=0}));function bezFunction(){var t=Math;function e(t,e,i,r,s,a){var n=t*r+e*s+i*a-s*r-a*t-i*e;return n>-.001&&n<.001}var i=function(t,e,i,r){var s,a,n,o,h,l,p=getDefaultCurveSegments(),f=0,c=[],m=[],d=bezierLengthPool.newElement();for(n=i.length,s=0;s<p;s+=1){for(h=s/(p-1),l=0,a=0;a<n;a+=1)o=bmPow(1-h,3)*t[a]+3*bmPow(1-h,2)*h*i[a]+3*(1-h)*bmPow(h,2)*r[a]+bmPow(h,3)*e[a],c[a]=o,null!==m[a]&&(l+=bmPow(c[a]-m[a],2)),m[a]=c[a];l&&(f+=l=bmSqrt(l)),d.percents[s]=h,d.lengths[s]=f}return d.addedLength=f,d};function r(t){this.segmentLength=0,this.points=new Array(t)}function s(t,e){this.partialLength=t,this.point=e}var a,n=(a={},function(t,i,n,o){var h=(t[0]+"_"+t[1]+"_"+i[0]+"_"+i[1]+"_"+n[0]+"_"+n[1]+"_"+o[0]+"_"+o[1]).replace(/\./g,"p");if(!a[h]){var l,p,f,c,m,d,u,y=getDefaultCurveSegments(),g=0,v=null;2===t.length&&(t[0]!==i[0]||t[1]!==i[1])&&e(t[0],t[1],i[0],i[1],t[0]+n[0],t[1]+n[1])&&e(t[0],t[1],i[0],i[1],i[0]+o[0],i[1]+o[1])&&(y=2);var P=new r(y);for(f=n.length,l=0;l<y;l+=1){for(u=createSizedArray(f),m=l/(y-1),d=0,p=0;p<f;p+=1)c=bmPow(1-m,3)*t[p]+3*bmPow(1-m,2)*m*(t[p]+n[p])+3*(1-m)*bmPow(m,2)*(i[p]+o[p])+bmPow(m,3)*i[p],u[p]=c,null!==v&&(d+=bmPow(u[p]-v[p],2));g+=d=bmSqrt(d),P.points[l]=new s(d,u),v=u}P.segmentLength=g,a[h]=P}return a[h]});function o(t,e){var i=e.percents,r=e.lengths,s=i.length,a=bmFloor((s-1)*t),n=t*e.addedLength,o=0;if(a===s-1||0===a||n===r[a])return i[a];for(var h=r[a]>n?-1:1,l=!0;l;)if(r[a]<=n&&r[a+1]>n?(o=(n-r[a])/(r[a+1]-r[a]),l=!1):a+=h,a<0||a>=s-1){if(a===s-1)return i[a];l=!1}return i[a]+(i[a+1]-i[a])*o}var h=createTypedArray("float32",8);return{getSegmentsLength:function(t){var e,r=segmentsLengthPool.newElement(),s=t.c,a=t.v,n=t.o,o=t.i,h=t._length,l=r.lengths,p=0;for(e=0;e<h-1;e+=1)l[e]=i(a[e],a[e+1],n[e],o[e+1]),p+=l[e].addedLength;return s&&h&&(l[e]=i(a[e],a[0],n[e],o[0]),p+=l[e].addedLength),r.totalLength=p,r},getNewSegment:function(e,i,r,s,a,n,l){a<0?a=0:a>1&&(a=1);var p,f=o(a,l),c=o(n=n>1?1:n,l),m=e.length,d=1-f,u=1-c,y=d*d*d,g=f*d*d*3,v=f*f*d*3,P=f*f*f,b=d*d*u,x=f*d*u+d*f*u+d*d*c,S=f*f*u+d*f*c+f*d*c,C=f*f*c,E=d*u*u,_=f*u*u+d*c*u+d*u*c,T=f*c*u+d*c*c+f*u*c,A=f*c*c,D=u*u*u,k=c*u*u+u*c*u+u*u*c,M=c*c*u+u*c*c+c*u*c,I=c*c*c;for(p=0;p<m;p+=1)h[4*p]=t.round(1e3*(y*e[p]+g*r[p]+v*s[p]+P*i[p]))/1e3,h[4*p+1]=t.round(1e3*(b*e[p]+x*r[p]+S*s[p]+C*i[p]))/1e3,h[4*p+2]=t.round(1e3*(E*e[p]+_*r[p]+T*s[p]+A*i[p]))/1e3,h[4*p+3]=t.round(1e3*(D*e[p]+k*r[p]+M*s[p]+I*i[p]))/1e3;return h},getPointInSegment:function(e,i,r,s,a,n){var h=o(a,n),l=1-h;return[t.round(1e3*(l*l*l*e[0]+(h*l*l+l*h*l+l*l*h)*r[0]+(h*h*l+l*h*h+h*l*h)*s[0]+h*h*h*i[0]))/1e3,t.round(1e3*(l*l*l*e[1]+(h*l*l+l*h*l+l*l*h)*r[1]+(h*h*l+l*h*h+h*l*h)*s[1]+h*h*h*i[1]))/1e3]},buildBezierData:n,pointOnLine2D:e,pointOnLine3D:function(i,r,s,a,n,o,h,l,p){if(0===s&&0===o&&0===p)return e(i,r,a,n,h,l);var f,c=t.sqrt(t.pow(a-i,2)+t.pow(n-r,2)+t.pow(o-s,2)),m=t.sqrt(t.pow(h-i,2)+t.pow(l-r,2)+t.pow(p-s,2)),d=t.sqrt(t.pow(h-a,2)+t.pow(l-n,2)+t.pow(p-o,2));return(f=c>m?c>d?c-m-d:d-m-c:d>m?d-m-c:m-c-d)>-1e-4&&f<1e-4}}}var bez=bezFunction(),initFrame=initialDefaultFrame,mathAbs=Math.abs;function interpolateValue(t,e){var i,r=this.offsetTime;"multidimensional"===this.propType&&(i=createTypedArray("float32",this.pv.length));for(var s,a,n,o,h,l,p,f,c,m=e.lastIndex,d=m,u=this.keyframes.length-1,y=!0;y;){if(s=this.keyframes[d],a=this.keyframes[d+1],d===u-1&&t>=a.t-r){s.h&&(s=a),m=0;break}if(a.t-r>t){m=d;break}d<u-1?d+=1:(m=0,y=!1)}n=this.keyframesMetadata[d]||{};var g,v=a.t-r,P=s.t-r;if(s.to){n.bezierData||(n.bezierData=bez.buildBezierData(s.s,a.s||s.e,s.to,s.ti));var b=n.bezierData;if(t>=v||t<P){var x=t>=v?b.points.length-1:0;for(h=b.points[x].point.length,o=0;o<h;o+=1)i[o]=b.points[x].point[o]}else{n.__fnct?c=n.__fnct:(c=BezierFactory.getBezierEasing(s.o.x,s.o.y,s.i.x,s.i.y,s.n).get,n.__fnct=c),l=c((t-P)/(v-P));var S,C=b.segmentLength*l,E=e.lastFrame<t&&e._lastKeyframeIndex===d?e._lastAddedLength:0;for(f=e.lastFrame<t&&e._lastKeyframeIndex===d?e._lastPoint:0,y=!0,p=b.points.length;y;){if(E+=b.points[f].partialLength,0===C||0===l||f===b.points.length-1){for(h=b.points[f].point.length,o=0;o<h;o+=1)i[o]=b.points[f].point[o];break}if(C>=E&&C<E+b.points[f+1].partialLength){for(S=(C-E)/b.points[f+1].partialLength,h=b.points[f].point.length,o=0;o<h;o+=1)i[o]=b.points[f].point[o]+(b.points[f+1].point[o]-b.points[f].point[o])*S;break}f<p-1?f+=1:y=!1}e._lastPoint=f,e._lastAddedLength=E-b.points[f].partialLength,e._lastKeyframeIndex=d}}else{var _,T,A,D,k;if(u=s.s.length,g=a.s||s.e,this.sh&&1!==s.h)if(t>=v)i[0]=g[0],i[1]=g[1],i[2]=g[2];else if(t<=P)i[0]=s.s[0],i[1]=s.s[1],i[2]=s.s[2];else{quaternionToEuler(i,slerp(createQuaternion(s.s),createQuaternion(g),(t-P)/(v-P)))}else for(d=0;d<u;d+=1)1!==s.h&&(t>=v?l=1:t<P?l=0:(s.o.x.constructor===Array?(n.__fnct||(n.__fnct=[]),n.__fnct[d]?c=n.__fnct[d]:(_=void 0===s.o.x[d]?s.o.x[0]:s.o.x[d],T=void 0===s.o.y[d]?s.o.y[0]:s.o.y[d],A=void 0===s.i.x[d]?s.i.x[0]:s.i.x[d],D=void 0===s.i.y[d]?s.i.y[0]:s.i.y[d],c=BezierFactory.getBezierEasing(_,T,A,D).get,n.__fnct[d]=c)):n.__fnct?c=n.__fnct:(_=s.o.x,T=s.o.y,A=s.i.x,D=s.i.y,c=BezierFactory.getBezierEasing(_,T,A,D).get,s.keyframeMetadata=c),l=c((t-P)/(v-P)))),g=a.s||s.e,k=1===s.h?s.s[d]:s.s[d]+(g[d]-s.s[d])*l,"multidimensional"===this.propType?i[d]=k:i=k}return e.lastIndex=m,i}function slerp(t,e,i){var r,s,a,n,o,h=[],l=t[0],p=t[1],f=t[2],c=t[3],m=e[0],d=e[1],u=e[2],y=e[3];return(s=l*m+p*d+f*u+c*y)<0&&(s=-s,m=-m,d=-d,u=-u,y=-y),1-s>1e-6?(r=Math.acos(s),a=Math.sin(r),n=Math.sin((1-i)*r)/a,o=Math.sin(i*r)/a):(n=1-i,o=i),h[0]=n*l+o*m,h[1]=n*p+o*d,h[2]=n*f+o*u,h[3]=n*c+o*y,h}function quaternionToEuler(t,e){var i=e[0],r=e[1],s=e[2],a=e[3],n=Math.atan2(2*r*a-2*i*s,1-2*r*r-2*s*s),o=Math.asin(2*i*r+2*s*a),h=Math.atan2(2*i*a-2*r*s,1-2*i*i-2*s*s);t[0]=n/degToRads,t[1]=o/degToRads,t[2]=h/degToRads}function createQuaternion(t){var e=t[0]*degToRads,i=t[1]*degToRads,r=t[2]*degToRads,s=Math.cos(e/2),a=Math.cos(i/2),n=Math.cos(r/2),o=Math.sin(e/2),h=Math.sin(i/2),l=Math.sin(r/2);return[o*h*n+s*a*l,o*a*n+s*h*l,s*h*n-o*a*l,s*a*n-o*h*l]}function getValueAtCurrentTime(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==initFrame&&(this._caching.lastFrame>=i&&t>=i||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var r=this.interpolateValue(t,this._caching);this.pv=r}return this._caching.lastFrame=t,this.pv}function setVValue(t){var e;if("unidimensional"===this.propType)e=t*this.mult,mathAbs(this.v-e)>1e-5&&(this.v=e,this._mdf=!0);else for(var i=0,r=this.v.length;i<r;)e=t[i]*this.mult,mathAbs(this.v[i]-e)>1e-5&&(this.v[i]=e,this._mdf=!0),i+=1}function processEffectsSequence(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t;this.lock=!0,this._mdf=this._isFirstFrame;var e=this.effectsSequence.length,i=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)i=this.effectsSequence[t](i);this.setVValue(i),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function addEffect(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function ValueProperty(t,e,i,r){this.propType="unidimensional",this.mult=i||1,this.data=e,this.v=i?e.k*i:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function MultiDimensionalProperty(t,e,i,r){var s;this.propType="multidimensional",this.mult=i||1,this.data=e,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var a=e.k.length;for(this.v=createTypedArray("float32",a),this.pv=createTypedArray("float32",a),this.vel=createTypedArray("float32",a),s=0;s<a;s+=1)this.v[s]=e.k[s]*this.mult,this.pv[s]=e.k[s];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function KeyframedValueProperty(t,e,i,r){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:initFrame,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.v=initFrame,this.pv=initFrame,this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.addEffect=addEffect}function KeyframedMultidimensionalProperty(t,e,i,r){var s;this.propType="multidimensional";var a,n,o,h,l=e.k.length;for(s=0;s<l-1;s+=1)e.k[s].to&&e.k[s].s&&e.k[s+1]&&e.k[s+1].s&&(a=e.k[s].s,n=e.k[s+1].s,o=e.k[s].to,h=e.k[s].ti,(2===a.length&&(a[0]!==n[0]||a[1]!==n[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],a[0]+o[0],a[1]+o[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],n[0]+h[0],n[1]+h[1])||3===a.length&&(a[0]!==n[0]||a[1]!==n[1]||a[2]!==n[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],a[0]+o[0],a[1]+o[1],a[2]+o[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],n[0]+h[0],n[1]+h[1],n[2]+h[2]))&&(e.k[s].to=null,e.k[s].ti=null),a[0]===n[0]&&a[1]===n[1]&&0===o[0]&&0===o[1]&&0===h[0]&&0===h[1]&&(2===a.length||a[2]===n[2]&&0===o[2]&&0===h[2])&&(e.k[s].to=null,e.k[s].ti=null));this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.frameId=-1;var p=e.k[0].s.length;for(this.v=createTypedArray("float32",p),this.pv=createTypedArray("float32",p),s=0;s<p;s+=1)this.v[s]=initFrame,this.pv[s]=initFrame;this._caching={lastFrame:initFrame,lastIndex:0,value:createTypedArray("float32",p)},this.addEffect=addEffect}var PropertyFactory={getProp:function(t,e,i,r,s){var a;if(e.sid&&(e=t.globalData.slotManager.getProp(e)),e.k.length)if("number"==typeof e.k[0])a=new MultiDimensionalProperty(t,e,r,s);else switch(i){case 0:a=new KeyframedValueProperty(t,e,r,s);break;case 1:a=new KeyframedMultidimensionalProperty(t,e,r,s)}else a=new ValueProperty(t,e,r,s);return a.effectsSequence.length&&s.addDynamicProperty(a),a}};function DynamicPropertyContainer(){}DynamicPropertyContainer.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){var t;this._mdf=!1;var e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var pointPool=poolFactory(8,(function(){return createTypedArray("float32",2)}));function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var i=0;i<e;)this.v[i]=pointPool.newElement(),this.o[i]=pointPool.newElement(),this.i[i]=pointPool.newElement(),i+=1},ShapePath.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},ShapePath.prototype.doubleArrayLength=function(){this.v=this.v.concat(createSizedArray(this._maxLength)),this.i=this.i.concat(createSizedArray(this._maxLength)),this.o=this.o.concat(createSizedArray(this._maxLength)),this._maxLength*=2},ShapePath.prototype.setXYAt=function(t,e,i,r,s){var a;switch(this._length=Math.max(this._length,r+1),this._length>=this._maxLength&&this.doubleArrayLength(),i){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o;break;default:a=[]}(!a[r]||a[r]&&!s)&&(a[r]=pointPool.newElement()),a[r][0]=t,a[r][1]=e},ShapePath.prototype.setTripleAt=function(t,e,i,r,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(i,r,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t=new ShapePath;t.setPathData(this.c,this._length);var e=this.v,i=this.o,r=this.i,s=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],r[0][0],r[0][1],i[0][0],i[0][1],0,!1),s=1);var a,n=this._length-1,o=this._length;for(a=s;a<o;a+=1)t.setTripleAt(e[n][0],e[n][1],r[n][0],r[n][1],i[n][0],i[n][1],a,!1),n-=1;return t},ShapePath.prototype.length=function(){return this._length};var shapePool=(factory=poolFactory(4,(function(){return new ShapePath}),(function(t){var e,i=t._length;for(e=0;e<i;e+=1)pointPool.release(t.v[e]),pointPool.release(t.i[e]),pointPool.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1})),factory.clone=function(t){var e,i=factory.newElement(),r=void 0===t._length?t.v.length:t._length;for(i.setLength(r),i.c=t.c,e=0;e<r;e+=1)i.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return i},factory),factory;function ShapeCollection(){this._length=0,this._maxLength=4,this.shapes=createSizedArray(this._maxLength)}ShapeCollection.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(createSizedArray(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},ShapeCollection.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)shapePool.release(this.shapes[t]);this._length=0};var shapeCollectionPool=(ob={newShapeCollection:function(){return _length?pool[_length-=1]:new ShapeCollection},release:function(t){var e,i=t._length;for(e=0;e<i;e+=1)shapePool.release(t.shapes[e]);t._length=0,_length===_maxLength&&(pool=pooling.double(pool),_maxLength*=2),pool[_length]=t,_length+=1}},_length=0,_maxLength=4,pool=createSizedArray(_maxLength),ob),ob,_length,_maxLength,pool,ShapePropertyFactory=function(){var t=-999999;function e(t,e,i){var r,s,a,n,o,h,l,p,f,c=i.lastIndex,m=this.keyframes;if(t<m[0].t-this.offsetTime)r=m[0].s[0],a=!0,c=0;else if(t>=m[m.length-1].t-this.offsetTime)r=m[m.length-1].s?m[m.length-1].s[0]:m[m.length-2].e[0],a=!0;else{for(var d,u,y,g=c,v=m.length-1,P=!0;P&&(d=m[g],!((u=m[g+1]).t-this.offsetTime>t));)g<v-1?g+=1:P=!1;if(y=this.keyframesMetadata[g]||{},c=g,!(a=1===d.h)){if(t>=u.t-this.offsetTime)p=1;else if(t<d.t-this.offsetTime)p=0;else{var b;y.__fnct?b=y.__fnct:(b=BezierFactory.getBezierEasing(d.o.x,d.o.y,d.i.x,d.i.y).get,y.__fnct=b),p=b((t-(d.t-this.offsetTime))/(u.t-this.offsetTime-(d.t-this.offsetTime)))}s=u.s?u.s[0]:d.e[0]}r=d.s[0]}for(h=e._length,l=r.i[0].length,i.lastIndex=c,n=0;n<h;n+=1)for(o=0;o<l;o+=1)f=a?r.i[n][o]:r.i[n][o]+(s.i[n][o]-r.i[n][o])*p,e.i[n][o]=f,f=a?r.o[n][o]:r.o[n][o]+(s.o[n][o]-r.o[n][o])*p,e.o[n][o]=f,f=a?r.v[n][o]:r.v[n][o]+(s.v[n][o]-r.v[n][o])*p,e.v[n][o]=f}function i(){var e=this.comp.renderedFrame-this.offsetTime,i=this.keyframes[0].t-this.offsetTime,r=this.keyframes[this.keyframes.length-1].t-this.offsetTime,s=this._caching.lastFrame;return s!==t&&(s<i&&e<i||s>r&&e>r)||(this._caching.lastIndex=s<e?this._caching.lastIndex:0,this.interpolateShape(e,this.pv,this._caching)),this._caching.lastFrame=e,this.pv}function r(){this.paths=this.localShapeCollection}function s(t){(function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var i,r=t._length;for(i=0;i<r;i+=1)if(t.v[i][0]!==e.v[i][0]||t.v[i][1]!==e.v[i][1]||t.o[i][0]!==e.o[i][0]||t.o[i][1]!==e.o[i][1]||t.i[i][0]!==e.i[i][0]||t.i[i][1]!==e.i[i][1])return!1;return!0})(this.v,t)||(this.v=shapePool.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function a(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t,e;this.lock=!0,this._mdf=!1,t=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k;var i=this.effectsSequence.length;for(e=0;e<i;e+=1)t=this.effectsSequence[e](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function n(t,e,i){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var s=3===i?e.pt.k:e.ks.k;this.v=shapePool.clone(s),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=r,this.effectsSequence=[]}function o(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function h(e,s,a){this.propType="shape",this.comp=e.comp,this.elem=e,this.container=e,this.offsetTime=e.data.st,this.keyframes=3===a?s.pt.k:s.ks.k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;var n=this.keyframes[0].s[0].i.length;this.v=shapePool.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,n),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=t,this.reset=r,this._caching={lastFrame:t,lastIndex:0},this.effectsSequence=[i.bind(this)]}n.prototype.interpolateShape=e,n.prototype.getValue=a,n.prototype.setVValue=s,n.prototype.addEffect=o,h.prototype.getValue=a,h.prototype.interpolateShape=e,h.prototype.setVValue=s,h.prototype.addEffect=o;var l=function(){var t=roundCorner;function e(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}return e.prototype={reset:r,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var e=this.p.v[0],i=this.p.v[1],r=this.s.v[0]/2,s=this.s.v[1]/2,a=3!==this.d,n=this.v;n.v[0][0]=e,n.v[0][1]=i-s,n.v[1][0]=a?e+r:e-r,n.v[1][1]=i,n.v[2][0]=e,n.v[2][1]=i+s,n.v[3][0]=a?e-r:e+r,n.v[3][1]=i,n.i[0][0]=a?e-r*t:e+r*t,n.i[0][1]=i-s,n.i[1][0]=a?e+r:e-r,n.i[1][1]=i-s*t,n.i[2][0]=a?e+r*t:e-r*t,n.i[2][1]=i+s,n.i[3][0]=a?e-r:e+r,n.i[3][1]=i+s*t,n.o[0][0]=a?e+r*t:e-r*t,n.o[0][1]=i-s,n.o[1][0]=a?e+r:e-r,n.o[1][1]=i+s*t,n.o[2][0]=a?e-r*t:e+r*t,n.o[2][1]=i+s,n.o[3][0]=a?e-r:e+r,n.o[3][1]=i-s*t}},extendPrototype([DynamicPropertyContainer],e),e}(),p=function(){function t(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=PropertyFactory.getProp(t,e.ir,0,0,this),this.is=PropertyFactory.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=PropertyFactory.getProp(t,e.pt,0,0,this),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,degToRads,this),this.or=PropertyFactory.getProp(t,e.or,0,0,this),this.os=PropertyFactory.getProp(t,e.os,0,.01,this),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}return t.prototype={reset:r,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,i,r,s=2*Math.floor(this.pt.v),a=2*Math.PI/s,n=!0,o=this.or.v,h=this.ir.v,l=this.os.v,p=this.is.v,f=2*Math.PI*o/(2*s),c=2*Math.PI*h/(2*s),m=-Math.PI/2;m+=this.r.v;var d=3===this.data.d?-1:1;for(this.v._length=0,t=0;t<s;t+=1){i=n?l:p,r=n?f:c;var u=(e=n?o:h)*Math.cos(m),y=e*Math.sin(m),g=0===u&&0===y?0:y/Math.sqrt(u*u+y*y),v=0===u&&0===y?0:-u/Math.sqrt(u*u+y*y);u+=+this.p.v[0],y+=+this.p.v[1],this.v.setTripleAt(u,y,u-g*r*i*d,y-v*r*i*d,u+g*r*i*d,y+v*r*i*d,t,!0),n=!n,m+=a*d}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),i=2*Math.PI/e,r=this.or.v,s=this.os.v,a=2*Math.PI*r/(4*e),n=.5*-Math.PI,o=3===this.data.d?-1:1;for(n+=this.r.v,this.v._length=0,t=0;t<e;t+=1){var h=r*Math.cos(n),l=r*Math.sin(n),p=0===h&&0===l?0:l/Math.sqrt(h*h+l*l),f=0===h&&0===l?0:-h/Math.sqrt(h*h+l*l);h+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(h,l,h-p*a*s*o,l-f*a*s*o,h+p*a*s*o,l+f*a*s*o,t,!0),n+=i*o}this.paths.length=0,this.paths[0]=this.v}},extendPrototype([DynamicPropertyContainer],t),t}(),f=function(){function t(t,e){this.v=shapePool.newElement(),this.v.c=!0,this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}return t.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,r=this.s.v[1]/2,s=bmMin(i,r,this.r.v),a=s*(1-roundCorner);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+s,t+i,e-r+a,0,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-a,t+i,e+r-s,1,!0),0!==s?(this.v.setTripleAt(t+i-s,e+r,t+i-s,e+r,t+i-a,e+r,2,!0),this.v.setTripleAt(t-i+s,e+r,t-i+a,e+r,t-i+s,e+r,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-s,t-i,e+r-a,4,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+a,t-i,e-r+s,5,!0),this.v.setTripleAt(t-i+s,e-r,t-i+s,e-r,t-i+a,e-r,6,!0),this.v.setTripleAt(t+i-s,e-r,t+i-a,e-r,t+i-s,e-r,7,!0)):(this.v.setTripleAt(t-i,e+r,t-i+a,e+r,t-i,e+r,2),this.v.setTripleAt(t-i,e-r,t-i,e-r+a,t-i,e-r,3))):(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+a,t+i,e-r+s,0,!0),0!==s?(this.v.setTripleAt(t+i-s,e-r,t+i-s,e-r,t+i-a,e-r,1,!0),this.v.setTripleAt(t-i+s,e-r,t-i+a,e-r,t-i+s,e-r,2,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+s,t-i,e-r+a,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-a,t-i,e+r-s,4,!0),this.v.setTripleAt(t-i+s,e+r,t-i+s,e+r,t-i+a,e+r,5,!0),this.v.setTripleAt(t+i-s,e+r,t+i-a,e+r,t+i-s,e+r,6,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-s,t+i,e+r-a,7,!0)):(this.v.setTripleAt(t-i,e-r,t-i+a,e-r,t-i,e-r,1,!0),this.v.setTripleAt(t-i,e+r,t-i,e+r-a,t-i,e+r,2,!0),this.v.setTripleAt(t+i,e+r,t+i-a,e+r,t+i,e+r,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:r},extendPrototype([DynamicPropertyContainer],t),t}();var c={getShapeProp:function(t,e,i){var r;return 3===i||4===i?r=(3===i?e.pt:e.ks).k.length?new h(t,e,i):new n(t,e,i):5===i?r=new f(t,e):6===i?r=new l(t,e):7===i&&(r=new p(t,e)),r.k&&t.addDynamicProperty(r),r},getConstructorFunction:function(){return n},getKeyframedConstructorFunction:function(){return h}};return c}(),Matrix=function(){var t=Math.cos,e=Math.sin,i=Math.tan,r=Math.round;function s(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function a(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,-s,0,0,s,r,0,0,0,0,1,0,0,0,0,1)}function n(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(1,0,0,0,0,r,-s,0,0,s,r,0,0,0,0,1)}function o(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,0,s,0,0,1,0,0,-s,0,r,0,0,0,0,1)}function h(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,-s,0,0,s,r,0,0,0,0,1,0,0,0,0,1)}function l(t,e){return this._t(1,e,t,1,0,0)}function p(t,e){return this.shear(i(t),i(e))}function f(r,s){var a=t(s),n=e(s);return this._t(a,n,0,0,-n,a,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,i(r),1,0,0,0,0,1,0,0,0,0,1)._t(a,-n,0,0,n,a,0,0,0,0,1,0,0,0,0,1)}function c(t,e,i){return i||0===i||(i=1),1===t&&1===e&&1===i?this:this._t(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1)}function m(t,e,i,r,s,a,n,o,h,l,p,f,c,m,d,u){return this.props[0]=t,this.props[1]=e,this.props[2]=i,this.props[3]=r,this.props[4]=s,this.props[5]=a,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=l,this.props[10]=p,this.props[11]=f,this.props[12]=c,this.props[13]=m,this.props[14]=d,this.props[15]=u,this}function d(t,e,i){return i=i||0,0!==t||0!==e||0!==i?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,i,1):this}function u(t,e,i,r,s,a,n,o,h,l,p,f,c,m,d,u){var y=this.props;if(1===t&&0===e&&0===i&&0===r&&0===s&&1===a&&0===n&&0===o&&0===h&&0===l&&1===p&&0===f)return y[12]=y[12]*t+y[15]*c,y[13]=y[13]*a+y[15]*m,y[14]=y[14]*p+y[15]*d,y[15]*=u,this._identityCalculated=!1,this;var g=y[0],v=y[1],P=y[2],b=y[3],x=y[4],S=y[5],C=y[6],E=y[7],_=y[8],T=y[9],A=y[10],D=y[11],k=y[12],M=y[13],I=y[14],F=y[15];return y[0]=g*t+v*s+P*h+b*c,y[1]=g*e+v*a+P*l+b*m,y[2]=g*i+v*n+P*p+b*d,y[3]=g*r+v*o+P*f+b*u,y[4]=x*t+S*s+C*h+E*c,y[5]=x*e+S*a+C*l+E*m,y[6]=x*i+S*n+C*p+E*d,y[7]=x*r+S*o+C*f+E*u,y[8]=_*t+T*s+A*h+D*c,y[9]=_*e+T*a+A*l+D*m,y[10]=_*i+T*n+A*p+D*d,y[11]=_*r+T*o+A*f+D*u,y[12]=k*t+M*s+I*h+F*c,y[13]=k*e+M*a+I*l+F*m,y[14]=k*i+M*n+I*p+F*d,y[15]=k*r+M*o+I*f+F*u,this._identityCalculated=!1,this}function y(t){var e=t.props;return this.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}function g(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function v(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function P(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function b(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function x(t,e,i){return{x:t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}}function S(t,e,i){return t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12]}function C(t,e,i){return t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13]}function E(t,e,i){return t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}function _(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,i=-this.props[1]/t,r=-this.props[4]/t,s=this.props[0]/t,a=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,n=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,o=new Matrix;return o.props[0]=e,o.props[1]=i,o.props[4]=r,o.props[5]=s,o.props[12]=a,o.props[13]=n,o}function T(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function A(t){var e,i=t.length,r=[];for(e=0;e<i;e+=1)r[e]=T(t[e]);return r}function D(t,e,i){var r=createTypedArray("float32",6);if(this.isIdentity())r[0]=t[0],r[1]=t[1],r[2]=e[0],r[3]=e[1],r[4]=i[0],r[5]=i[1];else{var s=this.props[0],a=this.props[1],n=this.props[4],o=this.props[5],h=this.props[12],l=this.props[13];r[0]=t[0]*s+t[1]*n+h,r[1]=t[0]*a+t[1]*o+l,r[2]=e[0]*s+e[1]*n+h,r[3]=e[0]*a+e[1]*o+l,r[4]=i[0]*s+i[1]*n+h,r[5]=i[0]*a+i[1]*o+l}return r}function k(t,e,i){return this.isIdentity()?[t,e,i]:[t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]]}function M(t,e){if(this.isIdentity())return t+","+e;var i=this.props;return Math.round(100*(t*i[0]+e*i[4]+i[12]))/100+","+Math.round(100*(t*i[1]+e*i[5]+i[13]))/100}function I(){for(var t=0,e=this.props,i="matrix3d(";t<16;)i+=r(1e4*e[t])/1e4,i+=15===t?")":",",t+=1;return i}function F(t){return t<1e-6&&t>0||t>-1e-6&&t<0?r(1e4*t)/1e4:t}function w(){var t=this.props;return"matrix("+F(t[0])+","+F(t[1])+","+F(t[4])+","+F(t[5])+","+F(t[12])+","+F(t[13])+")"}return function(){this.reset=s,this.rotate=a,this.rotateX=n,this.rotateY=o,this.rotateZ=h,this.skew=p,this.skewFromAxis=f,this.shear=l,this.scale=c,this.setTransform=m,this.translate=d,this.transform=u,this.multiply=y,this.applyToPoint=x,this.applyToX=S,this.applyToY=C,this.applyToZ=E,this.applyToPointArray=k,this.applyToTriplePoints=D,this.applyToPointStringified=M,this.toCSS=I,this.to2dCSS=w,this.clone=P,this.cloneFromProps=b,this.equals=v,this.inversePoints=A,this.inversePoint=T,this.getInverseMatrix=_,this._t=this.transform,this.isIdentity=g,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}}();function _typeof$3(t){return _typeof$3="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$3(t)}var lottie={},standalone="__[STANDALONE]__",animationData="__[ANIMATIONDATA]__",renderer="";function setLocation(t){setLocationHref(t)}function searchAnimations(){!0===standalone?animationManager.searchAnimations(animationData,standalone,renderer):animationManager.searchAnimations()}function setSubframeRendering(t){setSubframeEnabled(t)}function setPrefix(t){setIdPrefix(t)}function loadAnimation(t){return!0===standalone&&(t.animationData=JSON.parse(animationData)),animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":setDefaultCurveSegments(200);break;default:case"medium":setDefaultCurveSegments(50);break;case"low":setDefaultCurveSegments(10)}else!isNaN(t)&&t>1&&setDefaultCurveSegments(t);getDefaultCurveSegments()>=50?roundValues(!1):roundValues(!0)}function inBrowser(){return"undefined"!=typeof navigator}function installPlugin(t,e){"expressions"===t&&setExpressionsPlugin(e)}function getFactory(t){switch(t){case"propertyFactory":return PropertyFactory;case"shapePropertyFactory":return ShapePropertyFactory;case"matrix":return Matrix;default:return null}}function checkReady(){"complete"===document.readyState&&(clearInterval(readyStateCheckInterval),searchAnimations())}function getQueryVariable(t){for(var e=queryString.split("&"),i=0;i<e.length;i+=1){var r=e[i].split("=");if(decodeURIComponent(r[0])==t)return decodeURIComponent(r[1])}return null}lottie.play=animationManager.play,lottie.pause=animationManager.pause,lottie.setLocationHref=setLocation,lottie.togglePause=animationManager.togglePause,lottie.setSpeed=animationManager.setSpeed,lottie.setDirection=animationManager.setDirection,lottie.stop=animationManager.stop,lottie.searchAnimations=searchAnimations,lottie.registerAnimation=animationManager.registerAnimation,lottie.loadAnimation=loadAnimation,lottie.setSubframeRendering=setSubframeRendering,lottie.resize=animationManager.resize,lottie.goToAndStop=animationManager.goToAndStop,lottie.destroy=animationManager.destroy,lottie.setQuality=setQuality,lottie.inBrowser=inBrowser,lottie.installPlugin=installPlugin,lottie.freeze=animationManager.freeze,lottie.unfreeze=animationManager.unfreeze,lottie.setVolume=animationManager.setVolume,lottie.mute=animationManager.mute,lottie.unmute=animationManager.unmute,lottie.getRegisteredAnimations=animationManager.getRegisteredAnimations,lottie.useWebWorker=setWebWorker,lottie.setIDPrefix=setPrefix,lottie.__getFactory=getFactory,lottie.version="5.13.0";var queryString="";if(standalone){var scripts=document.getElementsByTagName("script"),index=scripts.length-1,myScript=scripts[index]||{src:""};queryString=myScript.src?myScript.src.replace(/^[^\?]+\??/,""):"",renderer=getQueryVariable("renderer")}var readyStateCheckInterval=setInterval(checkReady,100);try{"object"===("undefined"==typeof exports?"undefined":_typeof$3(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=lottie)}catch(t){}var ShapeModifiers=function(){var t={},e={};return t.registerModifier=function(t,i){e[t]||(e[t]=i)},t.getModifier=function(t,i,r){return new e[t](i,r)},t}();function ShapeModifier(){}function TrimModifier(){}function PuckerAndBloatModifier(){}ShapeModifier.prototype.initModifierProperties=function(){},ShapeModifier.prototype.addShapeToModifier=function(){},ShapeModifier.prototype.addShape=function(t){if(!this.closed){t.sh.container.addDynamicProperty(t.sh);var e={shape:t.sh,data:t,localShapeCollection:shapeCollectionPool.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},ShapeModifier.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=initialDefaultFrame,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},ShapeModifier.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},extendPrototype([DynamicPropertyContainer],ShapeModifier),extendPrototype([ShapeModifier],TrimModifier),TrimModifier.prototype.initModifierProperties=function(t,e){this.s=PropertyFactory.getProp(t,e.s,0,.01,this),this.e=PropertyFactory.getProp(t,e.e,0,.01,this),this.o=PropertyFactory.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},TrimModifier.prototype.addShapeToModifier=function(t){t.pathsData=[]},TrimModifier.prototype.calculateShapeEdges=function(t,e,i,r,s){var a=[];e<=1?a.push({s:t,e:e}):t>=1?a.push({s:t-1,e:e-1}):(a.push({s:t,e:1}),a.push({s:0,e:e-1}));var n,o,h=[],l=a.length;for(n=0;n<l;n+=1){var p,f;if(!((o=a[n]).e*s<r||o.s*s>r+i))p=o.s*s<=r?0:(o.s*s-r)/i,f=o.e*s>=r+i?1:(o.e*s-r)/i,h.push([p,f])}return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){var e,i=t.length;for(e=0;e<i;e+=1)segmentsLengthPool.release(t[e]);return t.length=0,t},TrimModifier.prototype.processShapes=function(t){var e,i,r,s;if(this._mdf||t){var a=this.o.v%360/360;if(a<0&&(a+=1),(e=this.s.v>1?1+a:this.s.v<0?0+a:this.s.v+a)>(i=this.e.v>1?1+a:this.e.v<0?0+a:this.e.v+a)){var n=e;e=i,i=n}e=1e-4*Math.round(1e4*e),i=1e-4*Math.round(1e4*i),this.sValue=e,this.eValue=i}else e=this.sValue,i=this.eValue;var o,h,l,p,f,c=this.shapes.length,m=0;if(i===e)for(s=0;s<c;s+=1)this.shapes[s].localShapeCollection.releaseShapes(),this.shapes[s].shape._mdf=!0,this.shapes[s].shape.paths=this.shapes[s].localShapeCollection,this._mdf&&(this.shapes[s].pathsData.length=0);else if(1===i&&0===e||0===i&&1===e){if(this._mdf)for(s=0;s<c;s+=1)this.shapes[s].pathsData.length=0,this.shapes[s].shape._mdf=!0}else{var d,u,y=[];for(s=0;s<c;s+=1)if((d=this.shapes[s]).shape._mdf||this._mdf||t||2===this.m){if(h=(r=d.shape.paths)._length,f=0,!d.shape._mdf&&d.pathsData.length)f=d.totalShapeLength;else{for(l=this.releasePathsData(d.pathsData),o=0;o<h;o+=1)p=bez.getSegmentsLength(r.shapes[o]),l.push(p),f+=p.totalLength;d.totalShapeLength=f,d.pathsData=l}m+=f,d.shape._mdf=!0}else d.shape.paths=d.localShapeCollection;var g,v=e,P=i,b=0;for(s=c-1;s>=0;s-=1)if((d=this.shapes[s]).shape._mdf){for((u=d.localShapeCollection).releaseShapes(),2===this.m&&c>1?(g=this.calculateShapeEdges(e,i,d.totalShapeLength,b,m),b+=d.totalShapeLength):g=[[v,P]],h=g.length,o=0;o<h;o+=1){v=g[o][0],P=g[o][1],y.length=0,P<=1?y.push({s:d.totalShapeLength*v,e:d.totalShapeLength*P}):v>=1?y.push({s:d.totalShapeLength*(v-1),e:d.totalShapeLength*(P-1)}):(y.push({s:d.totalShapeLength*v,e:d.totalShapeLength}),y.push({s:0,e:d.totalShapeLength*(P-1)}));var x=this.addShapes(d,y[0]);if(y[0].s!==y[0].e){if(y.length>1)if(d.shape.paths.shapes[d.shape.paths._length-1].c){var S=x.pop();this.addPaths(x,u),x=this.addShapes(d,y[1],S)}else this.addPaths(x,u),x=this.addShapes(d,y[1]);this.addPaths(x,u)}}d.shape.paths=u}}},TrimModifier.prototype.addPaths=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)e.addShape(t[i])},TrimModifier.prototype.addSegment=function(t,e,i,r,s,a,n){s.setXYAt(e[0],e[1],"o",a),s.setXYAt(i[0],i[1],"i",a+1),n&&s.setXYAt(t[0],t[1],"v",a),s.setXYAt(r[0],r[1],"v",a+1)},TrimModifier.prototype.addSegmentFromArray=function(t,e,i,r){e.setXYAt(t[1],t[5],"o",i),e.setXYAt(t[2],t[6],"i",i+1),r&&e.setXYAt(t[0],t[4],"v",i),e.setXYAt(t[3],t[7],"v",i+1)},TrimModifier.prototype.addShapes=function(t,e,i){var r,s,a,n,o,h,l,p,f=t.pathsData,c=t.shape.paths.shapes,m=t.shape.paths._length,d=0,u=[],y=!0;for(i?(o=i._length,p=i._length):(i=shapePool.newElement(),o=0,p=0),u.push(i),r=0;r<m;r+=1){for(h=f[r].lengths,i.c=c[r].c,a=c[r].c?h.length:h.length+1,s=1;s<a;s+=1)if(d+(n=h[s-1]).addedLength<e.s)d+=n.addedLength,i.c=!1;else{if(d>e.e){i.c=!1;break}e.s<=d&&e.e>=d+n.addedLength?(this.addSegment(c[r].v[s-1],c[r].o[s-1],c[r].i[s],c[r].v[s],i,o,y),y=!1):(l=bez.getNewSegment(c[r].v[s-1],c[r].v[s],c[r].o[s-1],c[r].i[s],(e.s-d)/n.addedLength,(e.e-d)/n.addedLength,h[s-1]),this.addSegmentFromArray(l,i,o,y),y=!1,i.c=!1),d+=n.addedLength,o+=1}if(c[r].c&&h.length){if(n=h[s-1],d<=e.e){var g=h[s-1].addedLength;e.s<=d&&e.e>=d+g?(this.addSegment(c[r].v[s-1],c[r].o[s-1],c[r].i[0],c[r].v[0],i,o,y),y=!1):(l=bez.getNewSegment(c[r].v[s-1],c[r].v[0],c[r].o[s-1],c[r].i[0],(e.s-d)/g,(e.e-d)/g,h[s-1]),this.addSegmentFromArray(l,i,o,y),y=!1,i.c=!1)}else i.c=!1;d+=n.addedLength,o+=1}if(i._length&&(i.setXYAt(i.v[p][0],i.v[p][1],"i",p),i.setXYAt(i.v[i._length-1][0],i.v[i._length-1][1],"o",i._length-1)),d>e.e)break;r<m-1&&(i=shapePool.newElement(),y=!0,u.push(i),o=0)}return u},extendPrototype([ShapeModifier],PuckerAndBloatModifier),PuckerAndBloatModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},PuckerAndBloatModifier.prototype.processPath=function(t,e){var i=e/100,r=[0,0],s=t._length,a=0;for(a=0;a<s;a+=1)r[0]+=t.v[a][0],r[1]+=t.v[a][1];r[0]/=s,r[1]/=s;var n,o,h,l,p,f,c=shapePool.newElement();for(c.c=t.c,a=0;a<s;a+=1)n=t.v[a][0]+(r[0]-t.v[a][0])*i,o=t.v[a][1]+(r[1]-t.v[a][1])*i,h=t.o[a][0]+(r[0]-t.o[a][0])*-i,l=t.o[a][1]+(r[1]-t.o[a][1])*-i,p=t.i[a][0]+(r[0]-t.i[a][0])*-i,f=t.i[a][1]+(r[1]-t.i[a][1])*-i,c.setTripleAt(n,o,h,l,p,f,a);return c},PuckerAndBloatModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amount.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var TransformPropertyFactory=function(){var t=[0,0];function e(t,e,i){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Matrix,this.pre=new Matrix,this.appliedTransformations=0,this.initDynamicPropertyContainer(i||t),e.p&&e.p.s?(this.px=PropertyFactory.getProp(t,e.p.x,0,0,this),this.py=PropertyFactory.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=PropertyFactory.getProp(t,e.p.z,0,0,this))):this.p=PropertyFactory.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=PropertyFactory.getProp(t,e.rx,0,degToRads,this),this.ry=PropertyFactory.getProp(t,e.ry,0,degToRads,this),this.rz=PropertyFactory.getProp(t,e.rz,0,degToRads,this),e.or.k[0].ti){var r,s=e.or.k.length;for(r=0;r<s;r+=1)e.or.k[r].to=null,e.or.k[r].ti=null}this.or=PropertyFactory.getProp(t,e.or,1,degToRads,this),this.or.sh=!0}else this.r=PropertyFactory.getProp(t,e.r||{k:0},0,degToRads,this);e.sk&&(this.sk=PropertyFactory.getProp(t,e.sk,0,degToRads,this),this.sa=PropertyFactory.getProp(t,e.sa,0,degToRads,this)),this.a=PropertyFactory.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=PropertyFactory.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=PropertyFactory.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return e.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(e){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||e){var i;if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var r,s;if(i=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime)this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(r=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/i,0),s=this.p.getValueAtTime(this.p.keyframes[0].t/i,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(r=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/i,0),s=this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/i,0)):(r=this.p.pv,s=this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/i,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){r=[],s=[];var a=this.px,n=this.py;a._caching.lastFrame+a.offsetTime<=a.keyframes[0].t?(r[0]=a.getValueAtTime((a.keyframes[0].t+.01)/i,0),r[1]=n.getValueAtTime((n.keyframes[0].t+.01)/i,0),s[0]=a.getValueAtTime(a.keyframes[0].t/i,0),s[1]=n.getValueAtTime(n.keyframes[0].t/i,0)):a._caching.lastFrame+a.offsetTime>=a.keyframes[a.keyframes.length-1].t?(r[0]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/i,0),r[1]=n.getValueAtTime(n.keyframes[n.keyframes.length-1].t/i,0),s[0]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/i,0),s[1]=n.getValueAtTime((n.keyframes[n.keyframes.length-1].t-.01)/i,0)):(r=[a.pv,n.pv],s[0]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/i,a.offsetTime),s[1]=n.getValueAtTime((n._caching.lastFrame+n.offsetTime-.01)/i,n.offsetTime))}else r=s=t;this.v.rotate(-Math.atan2(r[1]-s[1],r[0]-s[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],e),e.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},e.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,i,r){return new e(t,i,r)}}}();function RepeaterModifier(){}function RoundCornersModifier(){}function floatEqual(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function floatZero(t){return Math.abs(t)<=1e-5}function lerp(t,e,i){return t*(1-i)+e*i}function lerpPoint(t,e,i){return[lerp(t[0],e[0],i),lerp(t[1],e[1],i)]}function quadRoots(t,e,i){if(0===t)return[];var r=e*e-4*t*i;if(r<0)return[];var s=-e/(2*t);if(0===r)return[s];var a=Math.sqrt(r)/(2*t);return[s-a,s+a]}function polynomialCoefficients(t,e,i,r){return[3*e-t-3*i+r,3*t-6*e+3*i,-3*t+3*e,t]}function singlePoint(t){return new PolynomialBezier(t,t,t,t,!1)}function PolynomialBezier(t,e,i,r,s){s&&pointEqual(t,e)&&(e=lerpPoint(t,r,1/3)),s&&pointEqual(i,r)&&(i=lerpPoint(t,r,2/3));var a=polynomialCoefficients(t[0],e[0],i[0],r[0]),n=polynomialCoefficients(t[1],e[1],i[1],r[1]);this.a=[a[0],n[0]],this.b=[a[1],n[1]],this.c=[a[2],n[2]],this.d=[a[3],n[3]],this.points=[t,e,i,r]}function extrema(t,e){var i=t.points[0][e],r=t.points[t.points.length-1][e];if(i>r){var s=r;r=i,i=s}for(var a=quadRoots(3*t.a[e],2*t.b[e],t.c[e]),n=0;n<a.length;n+=1)if(a[n]>0&&a[n]<1){var o=t.point(a[n])[e];o<i?i=o:o>r&&(r=o)}return{min:i,max:r}}function intersectData(t,e,i){var r=t.boundingBox();return{cx:r.cx,cy:r.cy,width:r.width,height:r.height,bez:t,t:(e+i)/2,t1:e,t2:i}}function splitData(t){var e=t.bez.split(.5);return[intersectData(e[0],t.t1,t.t),intersectData(e[1],t.t,t.t2)]}function boxIntersect(t,e){return 2*Math.abs(t.cx-e.cx)<t.width+e.width&&2*Math.abs(t.cy-e.cy)<t.height+e.height}function intersectsImpl(t,e,i,r,s,a){if(boxIntersect(t,e))if(i>=a||t.width<=r&&t.height<=r&&e.width<=r&&e.height<=r)s.push([t.t,e.t]);else{var n=splitData(t),o=splitData(e);intersectsImpl(n[0],o[0],i+1,r,s,a),intersectsImpl(n[0],o[1],i+1,r,s,a),intersectsImpl(n[1],o[0],i+1,r,s,a),intersectsImpl(n[1],o[1],i+1,r,s,a)}}function crossProduct(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function lineIntersection(t,e,i,r){var s=[t[0],t[1],1],a=[e[0],e[1],1],n=[i[0],i[1],1],o=[r[0],r[1],1],h=crossProduct(crossProduct(s,a),crossProduct(n,o));return floatZero(h[2])?null:[h[0]/h[2],h[1]/h[2]]}function polarOffset(t,e,i){return[t[0]+Math.cos(e)*i,t[1]-Math.sin(e)*i]}function pointDistance(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function pointEqual(t,e){return floatEqual(t[0],e[0])&&floatEqual(t[1],e[1])}function ZigZagModifier(){}function setPoint(t,e,i,r,s,a,n){var o=i-Math.PI/2,h=i+Math.PI/2,l=e[0]+Math.cos(i)*r*s,p=e[1]-Math.sin(i)*r*s;t.setTripleAt(l,p,l+Math.cos(o)*a,p-Math.sin(o)*a,l+Math.cos(h)*n,p-Math.sin(h)*n,t.length())}function getPerpendicularVector(t,e){var i=[e[0]-t[0],e[1]-t[1]],r=.5*-Math.PI;return[Math.cos(r)*i[0]-Math.sin(r)*i[1],Math.sin(r)*i[0]+Math.cos(r)*i[1]]}function getProjectingAngle(t,e){var i=0===e?t.length()-1:e-1,r=(e+1)%t.length(),s=getPerpendicularVector(t.v[i],t.v[r]);return Math.atan2(0,1)-Math.atan2(s[1],s[0])}function zigZagCorner(t,e,i,r,s,a,n){var o=getProjectingAngle(e,i),h=e.v[i%e._length],l=e.v[0===i?e._length-1:i-1],p=e.v[(i+1)%e._length],f=2===a?Math.sqrt(Math.pow(h[0]-l[0],2)+Math.pow(h[1]-l[1],2)):0,c=2===a?Math.sqrt(Math.pow(h[0]-p[0],2)+Math.pow(h[1]-p[1],2)):0;setPoint(t,e.v[i%e._length],o,n,r,c/(2*(s+1)),f/(2*(s+1)),a)}function zigZagSegment(t,e,i,r,s,a){for(var n=0;n<r;n+=1){var o=(n+1)/(r+1),h=2===s?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(o);setPoint(t,e.point(o),l,a,i,h/(2*(r+1)),h/(2*(r+1)),s),a=-a}return a}function linearOffset(t,e,i){var r=Math.atan2(e[0]-t[0],e[1]-t[1]);return[polarOffset(t,r,i),polarOffset(e,r,i)]}function offsetSegment(t,e){var i,r,s,a,n,o,h;i=(h=linearOffset(t.points[0],t.points[1],e))[0],r=h[1],s=(h=linearOffset(t.points[1],t.points[2],e))[0],a=h[1],n=(h=linearOffset(t.points[2],t.points[3],e))[0],o=h[1];var l=lineIntersection(i,r,s,a);null===l&&(l=r);var p=lineIntersection(n,o,s,a);return null===p&&(p=n),new PolynomialBezier(i,l,p,o)}function joinLines(t,e,i,r,s){var a=e.points[3],n=i.points[0];if(3===r)return a;if(pointEqual(a,n))return a;if(2===r){var o=-e.tangentAngle(1),h=-i.tangentAngle(0)+Math.PI,l=lineIntersection(a,polarOffset(a,o+Math.PI/2,100),n,polarOffset(n,o+Math.PI/2,100)),p=l?pointDistance(l,a):pointDistance(a,n)/2,f=polarOffset(a,o,2*p*roundCorner);return t.setXYAt(f[0],f[1],"o",t.length()-1),f=polarOffset(n,h,2*p*roundCorner),t.setTripleAt(n[0],n[1],n[0],n[1],f[0],f[1],t.length()),n}var c=lineIntersection(pointEqual(a,e.points[2])?e.points[0]:e.points[2],a,n,pointEqual(n,i.points[1])?i.points[3]:i.points[1]);return c&&pointDistance(c,a)<s?(t.setTripleAt(c[0],c[1],c[0],c[1],c[0],c[1],t.length()),c):a}function getIntersection(t,e){var i=t.intersections(e);return i.length&&floatEqual(i[0][0],1)&&i.shift(),i.length?i[0]:null}function pruneSegmentIntersection(t,e){var i=t.slice(),r=e.slice(),s=getIntersection(t[t.length-1],e[0]);return s&&(i[t.length-1]=t[t.length-1].split(s[0])[0],r[0]=e[0].split(s[1])[1]),t.length>1&&e.length>1&&(s=getIntersection(t[0],e[e.length-1]))?[[t[0].split(s[0])[0]],[e[e.length-1].split(s[1])[1]]]:[i,r]}function pruneIntersections(t){for(var e,i=1;i<t.length;i+=1)e=pruneSegmentIntersection(t[i-1],t[i]),t[i-1]=e[0],t[i]=e[1];return t.length>1&&(e=pruneSegmentIntersection(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}function offsetSegmentSplit(t,e){var i,r,s,a,n=t.inflectionPoints();if(0===n.length)return[offsetSegment(t,e)];if(1===n.length||floatEqual(n[1],1))return i=(s=t.split(n[0]))[0],r=s[1],[offsetSegment(i,e),offsetSegment(r,e)];i=(s=t.split(n[0]))[0];var o=(n[1]-n[0])/(1-n[0]);return a=(s=s[1].split(o))[0],r=s[1],[offsetSegment(i,e),offsetSegment(a,e),offsetSegment(r,e)]}function OffsetPathModifier(){}function getFontProperties(t){for(var e=t.fStyle?t.fStyle.split(" "):[],i="normal",r="normal",s=e.length,a=0;a<s;a+=1)switch(e[a].toLowerCase()){case"italic":r="italic";break;case"bold":i="700";break;case"black":i="900";break;case"medium":i="500";break;case"regular":case"normal":i="400";break;case"light":case"thin":i="200"}return{style:r,weight:t.fWeight||i}}extendPrototype([ShapeModifier],RepeaterModifier),RepeaterModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=PropertyFactory.getProp(t,e.c,0,null,this),this.o=PropertyFactory.getProp(t,e.o,0,null,this),this.tr=TransformPropertyFactory.getTransformProperty(t,e.tr,this),this.so=PropertyFactory.getProp(t,e.tr.so,0,.01,this),this.eo=PropertyFactory.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Matrix,this.rMatrix=new Matrix,this.sMatrix=new Matrix,this.tMatrix=new Matrix,this.matrix=new Matrix},RepeaterModifier.prototype.applyTransforms=function(t,e,i,r,s,a){var n=a?-1:1,o=r.s.v[0]+(1-r.s.v[0])*(1-s),h=r.s.v[1]+(1-r.s.v[1])*(1-s);t.translate(r.p.v[0]*n*s,r.p.v[1]*n*s,r.p.v[2]),e.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),e.rotate(-r.r.v*n*s),e.translate(r.a.v[0],r.a.v[1],r.a.v[2]),i.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),i.scale(a?1/o:o,a?1/h:h),i.translate(r.a.v[0],r.a.v[1],r.a.v[2])},RepeaterModifier.prototype.init=function(t,e,i,r){for(this.elem=t,this.arr=e,this.pos=i,this.elemsData=r,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[i]);i>0;)i-=1,this._elements.unshift(e[i]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},RepeaterModifier.prototype.cloneElements=function(t){var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},RepeaterModifier.prototype.changeGroupRender=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)t[i]._render=e,"gr"===t[i].ty&&this.changeGroupRender(t[i].it,e)},RepeaterModifier.prototype.processShapes=function(t){var e,i,r,s,a,n=!1;if(this._mdf||t){var o,h=Math.ceil(this.c.v);if(this._groups.length<h){for(;this._groups.length<h;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(a=0,r=0;r<=this._groups.length-1;r+=1){if(o=a<h,this._groups[r]._render=o,this.changeGroupRender(this._groups[r].it,o),!o){var p=this.elemsData[r].it,f=p[p.length-1];0!==f.transform.op.v?(f.transform.op._mdf=!0,f.transform.op.v=0):f.transform.op._mdf=!1}a+=1}this._currentCopies=h;var c=this.o.v,m=c%1,d=c>0?Math.floor(c):Math.ceil(c),u=this.pMatrix.props,y=this.rMatrix.props,g=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var v,P,b=0;if(c>0){for(;b<d;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),b+=1;m&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,m,!1),b+=m)}else if(c<0){for(;b>d;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),b-=1;m&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-m,!0),b-=m)}for(r=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(P=(i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(r/(this._currentCopies-1)),0!==b){for((0!==r&&1===s||r!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]),this.matrix.transform(u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]),v=0;v<P;v+=1)i[v]=this.matrix.props[v];this.matrix.reset()}else for(this.matrix.reset(),v=0;v<P;v+=1)i[v]=this.matrix.props[v];b+=1,a-=1,r+=s}}else for(a=this._currentCopies,r=0,s=1;a;)i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,a-=1,r+=s;return n},RepeaterModifier.prototype.addShape=function(){},extendPrototype([ShapeModifier],RoundCornersModifier),RoundCornersModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=PropertyFactory.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},RoundCornersModifier.prototype.processPath=function(t,e){var i,r=shapePool.newElement();r.c=t.c;var s,a,n,o,h,l,p,f,c,m,d,u,y=t._length,g=0;for(i=0;i<y;i+=1)s=t.v[i],n=t.o[i],a=t.i[i],s[0]===n[0]&&s[1]===n[1]&&s[0]===a[0]&&s[1]===a[1]?0!==i&&i!==y-1||t.c?(o=0===i?t.v[y-1]:t.v[i-1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=d=s[0]+(o[0]-s[0])*l,f=u=s[1]-(s[1]-o[1])*l,c=p-(p-s[0])*roundCorner,m=f-(f-s[1])*roundCorner,r.setTripleAt(p,f,c,m,d,u,g),g+=1,o=i===y-1?t.v[0]:t.v[i+1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=c=s[0]+(o[0]-s[0])*l,f=m=s[1]+(o[1]-s[1])*l,d=p-(p-s[0])*roundCorner,u=f-(f-s[1])*roundCorner,r.setTripleAt(p,f,c,m,d,u,g),g+=1):(r.setTripleAt(s[0],s[1],n[0],n[1],a[0],a[1],g),g+=1):(r.setTripleAt(t.v[i][0],t.v[i][1],t.o[i][0],t.o[i][1],t.i[i][0],t.i[i][1],g),g+=1);return r},RoundCornersModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},PolynomialBezier.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},PolynomialBezier.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},PolynomialBezier.prototype.tangentAngle=function(t){var e=this.derivative(t);return Math.atan2(e[1],e[0])},PolynomialBezier.prototype.normalAngle=function(t){var e=this.derivative(t);return Math.atan2(e[0],e[1])},PolynomialBezier.prototype.inflectionPoints=function(){var t=this.a[1]*this.b[0]-this.a[0]*this.b[1];if(floatZero(t))return[];var e=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/t,i=e*e-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/t;if(i<0)return[];var r=Math.sqrt(i);return floatZero(r)?r>0&&r<1?[e]:[]:[e-r,e+r].filter((function(t){return t>0&&t<1}))},PolynomialBezier.prototype.split=function(t){if(t<=0)return[singlePoint(this.points[0]),this];if(t>=1)return[this,singlePoint(this.points[this.points.length-1])];var e=lerpPoint(this.points[0],this.points[1],t),i=lerpPoint(this.points[1],this.points[2],t),r=lerpPoint(this.points[2],this.points[3],t),s=lerpPoint(e,i,t),a=lerpPoint(i,r,t),n=lerpPoint(s,a,t);return[new PolynomialBezier(this.points[0],e,s,n,!0),new PolynomialBezier(n,a,r,this.points[3],!0)]},PolynomialBezier.prototype.bounds=function(){return{x:extrema(this,0),y:extrema(this,1)}},PolynomialBezier.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},PolynomialBezier.prototype.intersections=function(t,e,i){void 0===e&&(e=2),void 0===i&&(i=7);var r=[];return intersectsImpl(intersectData(this,0,1),intersectData(t,0,1),0,e,r,i),r},PolynomialBezier.shapeSegment=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[e],t.o[e],t.i[i],t.v[i],!0)},PolynomialBezier.shapeSegmentInverted=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[i],t.i[i],t.o[e],t.v[e],!0)},extendPrototype([ShapeModifier],ZigZagModifier),ZigZagModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=PropertyFactory.getProp(t,e.s,0,null,this),this.frequency=PropertyFactory.getProp(t,e.r,0,null,this),this.pointsType=PropertyFactory.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},ZigZagModifier.prototype.processPath=function(t,e,i,r){var s=t._length,a=shapePool.newElement();if(a.c=t.c,t.c||(s-=1),0===s)return a;var n=-1,o=PolynomialBezier.shapeSegment(t,0);zigZagCorner(a,t,0,e,i,r,n);for(var h=0;h<s;h+=1)n=zigZagSegment(a,o,e,i,r,-n),o=h!==s-1||t.c?PolynomialBezier.shapeSegment(t,(h+1)%s):null,zigZagCorner(a,t,h+1,e,i,r,n);return a},ZigZagModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amplitude.v,l=Math.max(0,Math.round(this.frequency.v)),p=this.pointsType.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h,l,p));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},extendPrototype([ShapeModifier],OffsetPathModifier),OffsetPathModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this.miterLimit=PropertyFactory.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},OffsetPathModifier.prototype.processPath=function(t,e,i,r){var s=shapePool.newElement();s.c=t.c;var a,n,o,h=t.length();t.c||(h-=1);var l=[];for(a=0;a<h;a+=1)o=PolynomialBezier.shapeSegment(t,a),l.push(offsetSegmentSplit(o,e));if(!t.c)for(a=h-1;a>=0;a-=1)o=PolynomialBezier.shapeSegmentInverted(t,a),l.push(offsetSegmentSplit(o,e));l=pruneIntersections(l);var p=null,f=null;for(a=0;a<l.length;a+=1){var c=l[a];for(f&&(p=joinLines(s,f,c[0],i,r)),f=c[c.length-1],n=0;n<c.length;n+=1)o=c[n],p&&pointEqual(o.points[0],p)?s.setXYAt(o.points[1][0],o.points[1][1],"o",s.length()-1):s.setTripleAt(o.points[0][0],o.points[0][1],o.points[1][0],o.points[1][1],o.points[0][0],o.points[0][1],s.length()),s.setTripleAt(o.points[3][0],o.points[3][1],o.points[3][0],o.points[3][1],o.points[2][0],o.points[2][1],s.length()),p=o.points[3]}return l.length&&joinLines(s,f,l[0][0],i,r),s},OffsetPathModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amount.v,l=this.miterLimit.v,p=this.lineJoin;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h,p,l));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var FontManager=function(){var t={w:0,size:0,shapes:[],data:{shapes:[]}},e=[];e=e.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);var i=127988,r=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function s(t,e){var i=createTag("span");i.setAttribute("aria-hidden",!0),i.style.fontFamily=e;var r=createTag("span");r.innerText="giItT1WQy@!-/#",i.style.position="absolute",i.style.left="-10000px",i.style.top="-10000px",i.style.fontSize="300px",i.style.fontVariant="normal",i.style.fontStyle="normal",i.style.fontWeight="normal",i.style.letterSpacing="0",i.appendChild(r),document.body.appendChild(i);var s=r.offsetWidth;return r.style.fontFamily=function(t){var e,i=t.split(","),r=i.length,s=[];for(e=0;e<r;e+=1)"sans-serif"!==i[e]&&"monospace"!==i[e]&&s.push(i[e]);return s.join(",")}(t)+", "+e,{node:r,w:s,parent:i}}function a(t,e){var i,r=document.body&&e?"svg":"canvas",s=getFontProperties(t);if("svg"===r){var a=createNS("text");a.style.fontSize="100px",a.setAttribute("font-family",t.fFamily),a.setAttribute("font-style",s.style),a.setAttribute("font-weight",s.weight),a.textContent="1",t.fClass?(a.style.fontFamily="inherit",a.setAttribute("class",t.fClass)):a.style.fontFamily=t.fFamily,e.appendChild(a),i=a}else{var n=new OffscreenCanvas(500,500).getContext("2d");n.font=s.style+" "+s.weight+" 100px "+t.fFamily,i=n}return{measureText:function(t){return"svg"===r?(i.textContent=t,i.getComputedTextLength()):i.measureText(t).width}}}function n(t){var e=0,i=t.charCodeAt(0);if(i>=55296&&i<=56319){var r=t.charCodeAt(1);r>=56320&&r<=57343&&(e=1024*(i-55296)+r-56320+65536)}return e}function o(t){var e=n(t);return e>=127462&&e<=127487}var h=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)};h.isModifier=function(t,e){var i=t.toString(16)+e.toString(16);return-1!==r.indexOf(i)},h.isZeroWidthJoiner=function(t){return 8205===t},h.isFlagEmoji=function(t){return o(t.substr(0,2))&&o(t.substr(2,2))},h.isRegionalCode=o,h.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},h.isRegionalFlag=function(t,e){var r=n(t.substr(e,2));if(r!==i)return!1;var s=0;for(e+=2;s<5;){if((r=n(t.substr(e,2)))<917601||r>917626)return!1;s+=1,e+=2}return 917631===n(t.substr(e,2))},h.isVariationSelector=function(t){return 65039===t},h.BLACK_FLAG_CODE_POINT=i;var l={addChars:function(t){if(t){var e;this.chars||(this.chars=[]);var i,r,s=t.length,a=this.chars.length;for(e=0;e<s;e+=1){for(i=0,r=!1;i<a;)this.chars[i].style===t[e].style&&this.chars[i].fFamily===t[e].fFamily&&this.chars[i].ch===t[e].ch&&(r=!0),i+=1;r||(this.chars.push(t[e]),a+=1)}}},addFonts:function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);if(!document.body)return this.isLoaded=!0,t.list.forEach((function(t){t.helper=a(t),t.cache={}})),void(this.fonts=t.list);var i,r=t.list,n=r.length,o=n;for(i=0;i<n;i+=1){var h,l,p=!0;if(r[i].loaded=!1,r[i].monoCase=s(r[i].fFamily,"monospace"),r[i].sansCase=s(r[i].fFamily,"sans-serif"),r[i].fPath){if("p"===r[i].fOrigin||3===r[i].origin){if((h=document.querySelectorAll('style[f-forigin="p"][f-family="'+r[i].fFamily+'"], style[f-origin="3"][f-family="'+r[i].fFamily+'"]')).length>0&&(p=!1),p){var f=createTag("style");f.setAttribute("f-forigin",r[i].fOrigin),f.setAttribute("f-origin",r[i].origin),f.setAttribute("f-family",r[i].fFamily),f.type="text/css",f.innerText="@font-face {font-family: "+r[i].fFamily+"; font-style: normal; src: url('"+r[i].fPath+"');}",e.appendChild(f)}}else if("g"===r[i].fOrigin||1===r[i].origin){for(h=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),l=0;l<h.length;l+=1)-1!==h[l].href.indexOf(r[i].fPath)&&(p=!1);if(p){var c=createTag("link");c.setAttribute("f-forigin",r[i].fOrigin),c.setAttribute("f-origin",r[i].origin),c.type="text/css",c.rel="stylesheet",c.href=r[i].fPath,document.body.appendChild(c)}}else if("t"===r[i].fOrigin||2===r[i].origin){for(h=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),l=0;l<h.length;l+=1)r[i].fPath===h[l].src&&(p=!1);if(p){var m=createTag("link");m.setAttribute("f-forigin",r[i].fOrigin),m.setAttribute("f-origin",r[i].origin),m.setAttribute("rel","stylesheet"),m.setAttribute("href",r[i].fPath),e.appendChild(m)}}}else r[i].loaded=!0,o-=1;r[i].helper=a(r[i],e),r[i].cache={},this.fonts.push(r[i])}0===o?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},getCharData:function(e,i,r){for(var s=0,a=this.chars.length;s<a;){if(this.chars[s].ch===e&&this.chars[s].style===i&&this.chars[s].fFamily===r)return this.chars[s];s+=1}return("string"==typeof e&&13!==e.charCodeAt(0)||!e)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",e,i,r)),t},getFontByName:function(t){for(var e=0,i=this.fonts.length;e<i;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,i){var r=this.getFontByName(e),s=t;if(!r.cache[s]){var a=r.helper;if(" "===t){var n=a.measureText("|"+t+"|"),o=a.measureText("||");r.cache[s]=(n-o)/100}else r.cache[s]=a.measureText(t)/100}return r.cache[s]*i},checkLoadedFonts:function(){var t,e,i,r=this.fonts.length,s=r;for(t=0;t<r;t+=1)this.fonts[t].loaded?s-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,i=this.fonts[t].monoCase.w,e.offsetWidth!==i?(s-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,i=this.fonts[t].sansCase.w,e.offsetWidth!==i&&(s-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==s&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}};return h.prototype=l,h}();function SlotManager(t){this.animationData=t}function slotFactory(t){return new SlotManager(t)}function RenderableElement(){}SlotManager.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},RenderableElement.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var getBlendMode=(blendModeEnums={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return blendModeEnums[t]||""}),blendModeEnums;function SliderEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function AngleEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function ColorEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function PointEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function LayerIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function MaskIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function CheckboxEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function NoValueEffect(){this.p={}}function EffectsManager(t,e){var i,r=t.ef||[];this.effectElements=[];var s,a=r.length;for(i=0;i<a;i+=1)s=new GroupEffect(r[i],e),this.effectElements.push(s)}function GroupEffect(t,e){this.init(t,e)}function BaseElement(){}function FrameElement(){}function FootageElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,i)}function AudioElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,i),this._isPlaying=!1,this._canPlay=!1;var r=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(r),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=PropertyFactory.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function BaseRenderer(){}extendPrototype([DynamicPropertyContainer],GroupEffect),GroupEffect.prototype.getValue=GroupEffect.prototype.iterateDynamicProperties,GroupEffect.prototype.init=function(t,e){var i;this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var r,s=this.data.ef.length,a=this.data.ef;for(i=0;i<s;i+=1){switch(r=null,a[i].ty){case 0:r=new SliderEffect(a[i],e,this);break;case 1:r=new AngleEffect(a[i],e,this);break;case 2:r=new ColorEffect(a[i],e,this);break;case 3:r=new PointEffect(a[i],e,this);break;case 4:case 7:r=new CheckboxEffect(a[i],e,this);break;case 10:r=new LayerIndexEffect(a[i],e,this);break;case 11:r=new MaskIndexEffect(a[i],e,this);break;case 5:r=new EffectsManager(a[i],e,this);break;default:r=new NoValueEffect(a[i],e,this)}r&&this.effectElements.push(r)}},BaseElement.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t=getExpressionInterfaces();if(t){var e=t("layer"),i=t("effects"),r=t("shape"),s=t("text"),a=t("comp");this.layerInterface=e(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var n=i.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(n),0===this.data.ty||this.data.xt?this.compInterface=a(this):4===this.data.ty?(this.layerInterface.shapeInterface=r(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=s(this),this.layerInterface.text=this.layerInterface.textInterface)}},setBlendMode:function(){var t=getBlendMode(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,i){this.globalData=e,this.comp=i,this.data=t,this.layerId=createElementID(),this.data.sr||(this.data.sr=1),this.effectsManager=new EffectsManager(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},FrameElement.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var i,r=this.dynamicProperties.length;for(i=0;i<r;i+=1)(e||this._isParent&&"transform"===this.dynamicProperties[i].propType)&&(this.dynamicProperties[i].getValue(),this.dynamicProperties[i]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},FootageElement.prototype.prepareFrame=function(){},extendPrototype([RenderableElement,BaseElement,FrameElement],FootageElement),FootageElement.prototype.getBaseElement=function(){return null},FootageElement.prototype.renderFrame=function(){},FootageElement.prototype.destroy=function(){},FootageElement.prototype.initExpressions=function(){var t=getExpressionInterfaces();if(t){var e=t("footage");this.layerInterface=e(this)}},FootageElement.prototype.getFootageData=function(){return this.footageData},AudioElement.prototype.prepareFrame=function(t){if(this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder)this._currentTime=t/this.data.sr;else{var e=this.tm.v;this._currentTime=e}this._volume=this.lv.v[0];var i=this._volume*this._volumeMultiplier;this._previousVolume!==i&&(this._previousVolume=i,this.audio.volume(i))},extendPrototype([RenderableElement,BaseElement,FrameElement],AudioElement),AudioElement.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek())>.1)&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},AudioElement.prototype.show=function(){},AudioElement.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},AudioElement.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},AudioElement.prototype.resume=function(){this._canPlay=!0},AudioElement.prototype.setRate=function(t){this.audio.rate(t)},AudioElement.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},AudioElement.prototype.getBaseElement=function(){return null},AudioElement.prototype.destroy=function(){},AudioElement.prototype.sourceRectAtTime=function(){},AudioElement.prototype.initExpressions=function(){},BaseRenderer.prototype.checkLayers=function(t){var e,i,r=this.layers.length;for(this.completeLayers=!0,e=r-1;e>=0;e-=1)this.elements[e]||(i=this.layers[e]).ip-i.st<=t-this.layers[e].st&&i.op-i.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:default:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t)}},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.createAudio=function(t){return new AudioElement(t,this.globalData,this)},BaseRenderer.prototype.createFootage=function(t){return new FootageElement(t,this.globalData,this)},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},BaseRenderer.prototype.includeLayers=function(t){var e;this.completeLayers=!1;var i,r=t.length,s=this.layers.length;for(e=0;e<r;e+=1)for(i=0;i<s;){if(this.layers[i].id===t[e].id){this.layers[i]=t[e];break}i+=1}},BaseRenderer.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},BaseRenderer.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},BaseRenderer.prototype.buildElementParenting=function(t,e,i){for(var r=this.elements,s=this.layers,a=0,n=s.length;a<n;)s[a].ind==e&&(r[a]&&!0!==r[a]?(i.push(r[a]),r[a].setAsParent(),void 0!==s[a].parent?this.buildElementParenting(t,s[a].parent,i):t.setHierarchy(i)):(this.buildItem(a),this.addPendingElement(t))),a+=1},BaseRenderer.prototype.addPendingElement=function(t){this.pendingElements.push(t)},BaseRenderer.prototype.searchExtraCompositions=function(t){var e,i=t.length;for(e=0;e<i;e+=1)if(t[e].xt){var r=this.createComp(t[e]);r.initExpressions(),this.globalData.projectInterface.registerComposition(r)}},BaseRenderer.prototype.getElementById=function(t){var e,i=this.elements.length;for(e=0;e<i;e+=1)if(this.elements[e].data.ind===t)return this.elements[e];return null},BaseRenderer.prototype.getElementByPath=function(t){var e,i=t.shift();if("number"==typeof i)e=this.elements[i];else{var r,s=this.elements.length;for(r=0;r<s;r+=1)if(this.elements[r].data.nm===i){e=this.elements[r];break}}return 0===t.length?e:e.getElementByPath(t)},BaseRenderer.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new FontManager,this.globalData.slotManager=slotFactory(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var effectTypes={TRANSFORM_EFFECT:"transformEFfect"};function TransformElement(){}function MaskElement(t,e,i){this.data=t,this.element=e,this.globalData=i,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var r,s,a=this.globalData.defs,n=this.masksProperties?this.masksProperties.length:0;this.viewData=createSizedArray(n),this.solidPath="";var o,h,l,p,f,c,m=this.masksProperties,d=0,u=[],y=createElementID(),g="clipPath",v="clip-path";for(r=0;r<n;r+=1)if(("a"!==m[r].mode&&"n"!==m[r].mode||m[r].inv||100!==m[r].o.k||m[r].o.x)&&(g="mask",v="mask"),"s"!==m[r].mode&&"i"!==m[r].mode||0!==d?l=null:((l=createNS("rect")).setAttribute("fill","#ffffff"),l.setAttribute("width",this.element.comp.data.w||0),l.setAttribute("height",this.element.comp.data.h||0),u.push(l)),s=createNS("path"),"n"===m[r].mode)this.viewData[r]={op:PropertyFactory.getProp(this.element,m[r].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,m[r],3),elem:s,lastPath:""},a.appendChild(s);else{var P;if(d+=1,s.setAttribute("fill","s"===m[r].mode?"#000000":"#ffffff"),s.setAttribute("clip-rule","nonzero"),0!==m[r].x.k?(g="mask",v="mask",c=PropertyFactory.getProp(this.element,m[r].x,0,null,this.element),P=createElementID(),(p=createNS("filter")).setAttribute("id",P),(f=createNS("feMorphology")).setAttribute("operator","erode"),f.setAttribute("in","SourceGraphic"),f.setAttribute("radius","0"),p.appendChild(f),a.appendChild(p),s.setAttribute("stroke","s"===m[r].mode?"#000000":"#ffffff")):(f=null,c=null),this.storedData[r]={elem:s,x:c,expan:f,lastPath:"",lastOperator:"",filterId:P,lastRadius:0},"i"===m[r].mode){h=u.length;var b=createNS("g");for(o=0;o<h;o+=1)b.appendChild(u[o]);var x=createNS("mask");x.setAttribute("mask-type","alpha"),x.setAttribute("id",y+"_"+d),x.appendChild(s),a.appendChild(x),b.setAttribute("mask","url("+getLocationHref()+"#"+y+"_"+d+")"),u.length=0,u.push(b)}else u.push(s);m[r].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[r]={elem:s,lastPath:"",op:PropertyFactory.getProp(this.element,m[r].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,m[r],3),invRect:l},this.viewData[r].prop.k||this.drawPath(m[r],this.viewData[r].prop.v,this.viewData[r])}for(this.maskElement=createNS(g),n=u.length,r=0;r<n;r+=1)this.maskElement.appendChild(u[r]);d>0&&(this.maskElement.setAttribute("id",y),this.element.maskedElement.setAttribute(v,"url("+getLocationHref()+"#"+y+")"),a.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}TransformElement.prototype={initTransform:function(){var t=new Matrix;this.finalTransform={mProp:this.data.ks?TransformPropertyFactory.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,i=0,r=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;i<r;){if(this.hierarchy[i].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}i+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),i=0;i<r;i+=1)e.multiply(this.hierarchy[i].finalTransform.mProp.v)}this.localTransforms&&!this.finalTransform._matMdf||(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var i=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(i),t=1;t<e;t+=1){var r=this.localTransforms[t].matrix;i.multiply(r)}i.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){var s=this.finalTransform.localOpacity;for(t=0;t<e;t+=1)s*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=s}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new Matrix;var e=0,i=t.length;for(e=0;e<i;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var i,r=!0,s=this.comp;r;)s.finalTransform?(s.data.hasMask&&e.splice(0,0,s.finalTransform),s=s.comp):r=!1;var a,n=e.length;for(i=0;i<n;i+=1)a=e[i].mat.applyToPointArray(0,0,0),t=[t[0]-a[0],t[1]-a[1],0];return t},mHelper:new Matrix},MaskElement.prototype.getMaskProperty=function(t){return this.viewData[t].prop},MaskElement.prototype.renderFrame=function(t){var e,i=this.element.finalTransform.mat,r=this.masksProperties.length;for(e=0;e<r;e+=1)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[e].invRect.setAttribute("transform",i.getInverseMatrix().to2dCSS()),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var s=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+getLocationHref()+"#"+this.storedData[e].filterId+")")),s.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},MaskElement.prototype.getMaskelement=function(){return this.maskElement},MaskElement.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},MaskElement.prototype.drawPath=function(t,e,i){var r,s,a=" M"+e.v[0][0]+","+e.v[0][1];for(s=e._length,r=1;r<s;r+=1)a+=" C"+e.o[r-1][0]+","+e.o[r-1][1]+" "+e.i[r][0]+","+e.i[r][1]+" "+e.v[r][0]+","+e.v[r][1];if(e.c&&s>1&&(a+=" C"+e.o[r-1][0]+","+e.o[r-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),i.lastPath!==a){var n="";i.elem&&(e.c&&(n=t.inv?this.solidPath+a:a),i.elem.setAttribute("d",n)),i.lastPath=a}},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var filtersFactory=function(){var t={};return t.createFilter=function(t,e){var i=createNS("filter");i.setAttribute("id",t),!0!==e&&(i.setAttribute("filterUnits","objectBoundingBox"),i.setAttribute("x","0%"),i.setAttribute("y","0%"),i.setAttribute("width","100%"),i.setAttribute("height","100%"));return i},t.createAlphaToLuminanceFilter=function(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},t}(),featureSupport=function(){var t={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),/firefox/i.test(navigator.userAgent)&&(t.svgLumaHidden=!1),t}(),registeredEffects$1={},idPrefix="filter_result_";function SVGEffects(t){var e,i,r="SourceGraphic",s=t.data.ef?t.data.ef.length:0,a=createElementID(),n=filtersFactory.createFilter(a,!0),o=0;for(this.filters=[],e=0;e<s;e+=1){i=null;var h=t.data.ef[e].ty;if(registeredEffects$1[h])i=new(0,registeredEffects$1[h].effect)(n,t.effectsManager.effectElements[e],t,idPrefix+o,r),r=idPrefix+o,registeredEffects$1[h].countsAsEffect&&(o+=1);i&&this.filters.push(i)}o&&(t.globalData.defs.appendChild(n),t.layerElement.setAttribute("filter","url("+getLocationHref()+"#"+a+")")),this.filters.length&&t.addRenderableComponent(this)}function registerEffect$1(t,e,i){registeredEffects$1[t]={effect:e,countsAsEffect:i}}function SVGBaseElement(){}function HierarchyElement(){}function RenderableDOMElement(){}function IImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,i),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ProcessedElement(t,e){this.elem=t,this.pos=e}function IShapeElement(){}SVGEffects.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},SVGEffects.prototype.getEffects=function(t){var e,i=this.filters.length,r=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&r.push(this.filters[e]);return r},SVGBaseElement.prototype={initRendererElement:function(){this.layerElement=createNS("g")},createContainerElements:function(){this.matteElement=createNS("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t=null;if(this.data.td){this.matteMasks={};var e=createNS("g");e.setAttribute("id",this.layerId),e.appendChild(this.layerElement),t=e,this.globalData.defs.appendChild(e)}else this.data.tt?(this.matteElement.appendChild(this.layerElement),t=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var i=createNS("clipPath"),r=createNS("path");r.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var s=createElementID();if(i.setAttribute("id",s),i.appendChild(r),this.globalData.defs.appendChild(i),this.checkMasks()){var a=createNS("g");a.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),a.appendChild(this.layerElement),this.transformedElement=a,t?t.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData),this.renderableEffectsManager=new SVGEffects(this),this.searchEffectTransforms()},getMatte:function(t){if(this.matteMasks||(this.matteMasks={}),!this.matteMasks[t]){var e,i,r,s,a=this.layerId+"_"+t;if(1===t||3===t){var n=createNS("mask");n.setAttribute("id",a),n.setAttribute("mask-type",3===t?"luminance":"alpha"),(r=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),n.appendChild(r),this.globalData.defs.appendChild(n),featureSupport.maskType||1!==t||(n.setAttribute("mask-type","luminance"),e=createElementID(),i=filtersFactory.createFilter(e),this.globalData.defs.appendChild(i),i.appendChild(filtersFactory.createAlphaToLuminanceFilter()),(s=createNS("g")).appendChild(r),n.appendChild(s),s.setAttribute("filter","url("+getLocationHref()+"#"+e+")"))}else if(2===t){var o=createNS("mask");o.setAttribute("id",a),o.setAttribute("mask-type","alpha");var h=createNS("g");o.appendChild(h),e=createElementID(),i=filtersFactory.createFilter(e);var l=createNS("feComponentTransfer");l.setAttribute("in","SourceGraphic"),i.appendChild(l);var p=createNS("feFuncA");p.setAttribute("type","table"),p.setAttribute("tableValues","1.0 0.0"),l.appendChild(p),this.globalData.defs.appendChild(i);var f=createNS("rect");f.setAttribute("width",this.comp.data.w),f.setAttribute("height",this.comp.data.h),f.setAttribute("x","0"),f.setAttribute("y","0"),f.setAttribute("fill","#ffffff"),f.setAttribute("opacity","0"),h.setAttribute("filter","url("+getLocationHref()+"#"+e+")"),h.appendChild(f),(r=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),h.appendChild(r),featureSupport.maskType||(o.setAttribute("mask-type","luminance"),i.appendChild(filtersFactory.createAlphaToLuminanceFilter()),s=createNS("g"),h.appendChild(f),s.appendChild(this.layerElement),h.appendChild(s)),this.globalData.defs.appendChild(o)}this.matteMasks[t]=a}return this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+getLocationHref()+"#"+t+")")}},HierarchyElement.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},extendPrototype([RenderableElement,createProxyFunction({initElement:function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],RenderableDOMElement),extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],IImageElement),IImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=createNS("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},IImageElement.prototype.sourceRectAtTime=function(){return this.sourceRect},IShapeElement.prototype={addShapeToModifiers:function(t){var e,i=this.shapeModifiers.length;for(e=0;e<i;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;t>=0&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,i=0,r=e.length;i<r;){if(e[i].elem===t)return e[i].pos;i+=1}return 0},addProcessedElement:function(t,e){for(var i=this.processedElements,r=i.length;r;)if(i[r-=1].elem===t)return void(i[r].pos=e);i.push(new ProcessedElement(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var lineCapEnum={1:"butt",2:"round",3:"square"},lineJoinEnum={1:"miter",2:"round",3:"bevel"};function SVGShapeData(t,e,i){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=i,this.lvl=e,this._isAnimated=!!i.k;for(var r=0,s=t.length;r<s;){if(t[r].mProps.dynamicProperties.length){this._isAnimated=!0;break}r+=1}}function SVGStyleData(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=createNS("path"),this.msElem=null}function DashProperty(t,e,i,r){var s;this.elem=t,this.frameId=-1,this.dataProps=createSizedArray(e.length),this.renderer=i,this.k=!1,this.dashStr="",this.dashArray=createTypedArray("float32",e.length?e.length-1:0),this.dashoffset=createTypedArray("float32",1),this.initDynamicPropertyContainer(r);var a,n=e.length||0;for(s=0;s<n;s+=1)a=PropertyFactory.getProp(t,e[s].v,0,0,this),this.k=a.k||this.k,this.dataProps[s]={n:e[s].n,p:a};this.k||this.getValue(!0),this._isAnimated=this.k}function SVGStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i,this._isAnimated=!!this._isAnimated}function SVGFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i}function SVGNoStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=i}function GradientProperty(t,e,i){this.data=e,this.c=createTypedArray("uint8c",4*e.p);var r=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=createTypedArray("float32",r),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=r,this.initDynamicPropertyContainer(i),this.prop=PropertyFactory.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function SVGGradientFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,i)}function SVGGradientStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.initGradientData(t,e,i),this._isAnimated=!!this._isAnimated}function ShapeGroupData(){this.it=[],this.prevViewData=[],this.gr=createNS("g")}function SVGTransformData(t,e,i){this.transform={mProps:t,op:e,container:i},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}SVGShapeData.prototype.setAsAnimated=function(){this._isAnimated=!0},SVGStyleData.prototype.reset=function(){this.d="",this._mdf=!1},DashProperty.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,i=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<i;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},extendPrototype([DynamicPropertyContainer],DashProperty),extendPrototype([DynamicPropertyContainer],SVGStrokeStyleData),extendPrototype([DynamicPropertyContainer],SVGFillStyleData),extendPrototype([DynamicPropertyContainer],SVGNoStyleData),GradientProperty.prototype.comparePoints=function(t,e){for(var i=0,r=this.o.length/2;i<r;){if(Math.abs(t[4*i]-t[4*e+2*i])>.01)return!1;i+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},GradientProperty.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,i,r,s=4*this.data.p;for(e=0;e<s;e+=1)i=e%4==0?100:255,r=Math.round(this.prop.v[e]*i),this.c[e]!==r&&(this.c[e]=r,this._cmdf=!t);if(this.o.length)for(s=this.prop.v.length,e=4*this.data.p;e<s;e+=1)i=e%2==0?100:1,r=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==r&&(this.o[e-4*this.data.p]=r,this._omdf=!t);this._mdf=!t}},extendPrototype([DynamicPropertyContainer],GradientProperty),SVGGradientFillStyleData.prototype.initGradientData=function(t,e,i){this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.s=PropertyFactory.getProp(t,e.s,1,null,this),this.e=PropertyFactory.getProp(t,e.e,1,null,this),this.h=PropertyFactory.getProp(t,e.h||{k:0},0,.01,this),this.a=PropertyFactory.getProp(t,e.a||{k:0},0,degToRads,this),this.g=new GradientProperty(t,e.g,this),this.style=i,this.stops=[],this.setGradientData(i.pElem,e),this.setGradientOpacity(e,i),this._isAnimated=!!this._isAnimated},SVGGradientFillStyleData.prototype.setGradientData=function(t,e){var i=createElementID(),r=createNS(1===e.t?"linearGradient":"radialGradient");r.setAttribute("id",i),r.setAttribute("spreadMethod","pad"),r.setAttribute("gradientUnits","userSpaceOnUse");var s,a,n,o=[];for(n=4*e.g.p,a=0;a<n;a+=4)s=createNS("stop"),r.appendChild(s),o.push(s);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+getLocationHref()+"#"+i+")"),this.gf=r,this.cst=o},SVGGradientFillStyleData.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){var i,r,s,a=createNS("mask"),n=createNS("path");a.appendChild(n);var o=createElementID(),h=createElementID();a.setAttribute("id",h);var l=createNS(1===t.t?"linearGradient":"radialGradient");l.setAttribute("id",o),l.setAttribute("spreadMethod","pad"),l.setAttribute("gradientUnits","userSpaceOnUse"),s=t.g.k.k[0].s?t.g.k.k[0].s.length:t.g.k.k.length;var p=this.stops;for(r=4*t.g.p;r<s;r+=2)(i=createNS("stop")).setAttribute("stop-color","rgb(255,255,255)"),l.appendChild(i),p.push(i);n.setAttribute("gf"===t.ty?"fill":"stroke","url("+getLocationHref()+"#"+o+")"),"gs"===t.ty&&(n.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),n.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),1===t.lj&&n.setAttribute("stroke-miterlimit",t.ml)),this.of=l,this.ms=a,this.ost=p,this.maskId=h,e.msElem=n}},extendPrototype([DynamicPropertyContainer],SVGGradientFillStyleData),extendPrototype([SVGGradientFillStyleData,DynamicPropertyContainer],SVGGradientStrokeStyleData);var buildShapeString=function(t,e,i,r){if(0===e)return"";var s,a=t.o,n=t.i,o=t.v,h=" M"+r.applyToPointStringified(o[0][0],o[0][1]);for(s=1;s<e;s+=1)h+=" C"+r.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+r.applyToPointStringified(n[s][0],n[s][1])+" "+r.applyToPointStringified(o[s][0],o[s][1]);return i&&e&&(h+=" C"+r.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+r.applyToPointStringified(n[0][0],n[0][1])+" "+r.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},SVGElementsRenderer=function(){var t=new Matrix,e=new Matrix;function i(t,e,i){(i||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(i||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function r(){}function s(i,r,s){var a,n,o,h,l,p,f,c,m,d,u=r.styles.length,y=r.lvl;for(p=0;p<u;p+=1){if(h=r.sh._mdf||s,r.styles[p].lvl<y){for(c=e.reset(),m=y-r.styles[p].lvl,d=r.transformers.length-1;!h&&m>0;)h=r.transformers[d].mProps._mdf||h,m-=1,d-=1;if(h)for(m=y-r.styles[p].lvl,d=r.transformers.length-1;m>0;)c.multiply(r.transformers[d].mProps.v),m-=1,d-=1}else c=t;if(n=(f=r.sh.paths)._length,h){for(o="",a=0;a<n;a+=1)(l=f.shapes[a])&&l._length&&(o+=buildShapeString(l,l._length,l.c,c));r.caches[p]=o}else o=r.caches[p];r.styles[p].d+=!0===i.hd?"":o,r.styles[p]._mdf=h||r.styles[p]._mdf}}function a(t,e,i){var r=e.style;(e.c._mdf||i)&&r.pElem.setAttribute("fill","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("fill-opacity",e.o.v)}function n(t,e,i){o(t,e,i),h(t,e,i)}function o(t,e,i){var r,s,a,n,o,h=e.gf,l=e.g._hasOpacity,p=e.s.v,f=e.e.v;if(e.o._mdf||i){var c="gf"===t.ty?"fill-opacity":"stroke-opacity";e.style.pElem.setAttribute(c,e.o.v)}if(e.s._mdf||i){var m=1===t.t?"x1":"cx",d="x1"===m?"y1":"cy";h.setAttribute(m,p[0]),h.setAttribute(d,p[1]),l&&!e.g._collapsable&&(e.of.setAttribute(m,p[0]),e.of.setAttribute(d,p[1]))}if(e.g._cmdf||i){r=e.cst;var u=e.g.c;for(a=r.length,s=0;s<a;s+=1)(n=r[s]).setAttribute("offset",u[4*s]+"%"),n.setAttribute("stop-color","rgb("+u[4*s+1]+","+u[4*s+2]+","+u[4*s+3]+")")}if(l&&(e.g._omdf||i)){var y=e.g.o;for(a=(r=e.g._collapsable?e.cst:e.ost).length,s=0;s<a;s+=1)n=r[s],e.g._collapsable||n.setAttribute("offset",y[2*s]+"%"),n.setAttribute("stop-opacity",y[2*s+1])}if(1===t.t)(e.e._mdf||i)&&(h.setAttribute("x2",f[0]),h.setAttribute("y2",f[1]),l&&!e.g._collapsable&&(e.of.setAttribute("x2",f[0]),e.of.setAttribute("y2",f[1])));else if((e.s._mdf||e.e._mdf||i)&&(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)),h.setAttribute("r",o),l&&!e.g._collapsable&&e.of.setAttribute("r",o)),e.s._mdf||e.e._mdf||e.h._mdf||e.a._mdf||i){o||(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)));var g=Math.atan2(f[1]-p[1],f[0]-p[0]),v=e.h.v;v>=1?v=.99:v<=-1&&(v=-.99);var P=o*v,b=Math.cos(g+e.a.v)*P+p[0],x=Math.sin(g+e.a.v)*P+p[1];h.setAttribute("fx",b),h.setAttribute("fy",x),l&&!e.g._collapsable&&(e.of.setAttribute("fx",b),e.of.setAttribute("fy",x))}}function h(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||i)&&s.dashStr&&(r.pElem.setAttribute("stroke-dasharray",s.dashStr),r.pElem.setAttribute("stroke-dashoffset",s.dashoffset[0])),e.c&&(e.c._mdf||i)&&r.pElem.setAttribute("stroke","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||i)&&(r.pElem.setAttribute("stroke-width",e.w.v),r.msElem&&r.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function(t){switch(t.ty){case"fl":return a;case"gf":return o;case"gs":return n;case"st":return h;case"sh":case"el":case"rc":case"sr":return s;case"tr":return i;case"no":return r;default:return null}}}}();function SVGShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,i),this.prevViewData=[]}function LetterProps(t,e,i,r,s,a){this.o=t,this.sw=e,this.sc=i,this.fc=r,this.m=s,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!i,fc:!!r,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){var t,e,i,r,s=this.shapes.length,a=this.stylesList.length,n=[],o=!1;for(i=0;i<a;i+=1){for(r=this.stylesList[i],o=!1,n.length=0,t=0;t<s;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(r)&&(n.push(e),o=e._isAnimated||o);n.length>1&&o&&this.setShapesAsAnimated(n)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].setAsAnimated()},SVGShapeElement.prototype.createStyleElement=function(t,e){var i,r=new SVGStyleData(t,e),s=r.pElem;if("st"===t.ty)i=new SVGStrokeStyleData(this,t,r);else if("fl"===t.ty)i=new SVGFillStyleData(this,t,r);else if("gf"===t.ty||"gs"===t.ty){i=new("gf"===t.ty?SVGGradientFillStyleData:SVGGradientStrokeStyleData)(this,t,r),this.globalData.defs.appendChild(i.gf),i.maskId&&(this.globalData.defs.appendChild(i.ms),this.globalData.defs.appendChild(i.of),s.setAttribute("mask","url("+getLocationHref()+"#"+i.maskId+")"))}else"no"===t.ty&&(i=new SVGNoStyleData(this,t,r));return"st"!==t.ty&&"gs"!==t.ty||(s.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),s.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),s.setAttribute("fill-opacity","0"),1===t.lj&&s.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&s.setAttribute("fill-rule","evenodd"),t.ln&&s.setAttribute("id",t.ln),t.cl&&s.setAttribute("class",t.cl),t.bm&&(s.style["mix-blend-mode"]=getBlendMode(t.bm)),this.stylesList.push(r),this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createGroupElement=function(t){var e=new ShapeGroupData;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=getBlendMode(t.bm)),e},SVGShapeElement.prototype.createTransformElement=function(t,e){var i=TransformPropertyFactory.getTransformProperty(this,t,this),r=new SVGTransformData(i,i.o,e);return this.addToAnimatedContents(t,r),r},SVGShapeElement.prototype.createShapeElement=function(t,e,i){var r=4;"rc"===t.ty?r=5:"el"===t.ty?r=6:"sr"===t.ty&&(r=7);var s=new SVGShapeData(e,i,ShapePropertyFactory.getShapeProp(this,t,r,this));return this.shapes.push(s),this.addShapeToModifiers(s),this.addToAnimatedContents(t,s),s},SVGShapeElement.prototype.addToAnimatedContents=function(t,e){for(var i=0,r=this.animatedContents.length;i<r;){if(this.animatedContents[i].element===e)return;i+=1}this.animatedContents.push({fn:SVGElementsRenderer.createRenderFunction(t),element:e,data:t})},SVGShapeElement.prototype.setElementStyles=function(t){var e,i=t.styles,r=this.stylesList.length;for(e=0;e<r;e+=1)-1!==i.indexOf(this.stylesList[e])||this.stylesList[e].closed||i.push(this.stylesList[e])},SVGShapeElement.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},SVGShapeElement.prototype.searchShapes=function(t,e,i,r,s,a,n){var o,h,l,p,f,c,m=[].concat(a),d=t.length-1,u=[],y=[];for(o=d;o>=0;o-=1){if((c=this.searchProcessedElement(t[o]))?e[o]=i[c-1]:t[o]._render=n,"fl"===t[o].ty||"st"===t[o].ty||"gf"===t[o].ty||"gs"===t[o].ty||"no"===t[o].ty)c?e[o].style.closed=t[o].hd:e[o]=this.createStyleElement(t[o],s),t[o]._render&&e[o].style.pElem.parentNode!==r&&r.appendChild(e[o].style.pElem),u.push(e[o].style);else if("gr"===t[o].ty){if(c)for(l=e[o].it.length,h=0;h<l;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,s+1,m,n),t[o]._render&&e[o].gr.parentNode!==r&&r.appendChild(e[o].gr)}else"tr"===t[o].ty?(c||(e[o]=this.createTransformElement(t[o],r)),p=e[o].transform,m.push(p)):"sh"===t[o].ty||"rc"===t[o].ty||"el"===t[o].ty||"sr"===t[o].ty?(c||(e[o]=this.createShapeElement(t[o],m,s)),this.setElementStyles(e[o])):"tm"===t[o].ty||"rd"===t[o].ty||"ms"===t[o].ty||"pb"===t[o].ty||"zz"===t[o].ty||"op"===t[o].ty?(c?(f=e[o]).closed=!1:((f=ShapeModifiers.getModifier(t[o].ty)).init(this,t[o]),e[o]=f,this.shapeModifiers.push(f)),y.push(f)):"rp"===t[o].ty&&(c?(f=e[o]).closed=!0:(f=ShapeModifiers.getModifier(t[o].ty),e[o]=f,f.init(this,t,o,e),this.shapeModifiers.push(f),n=!1),y.push(f));this.addProcessedElement(t[o],o+1)}for(d=u.length,o=0;o<d;o+=1)u[o].closed=!0;for(d=y.length,o=0;o<d;o+=1)y[o].closed=!0},SVGShapeElement.prototype.renderInnerContent=function(){var t;this.renderModifiers();var e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},SVGShapeElement.prototype.renderShape=function(){var t,e,i=this.animatedContents.length;for(t=0;t<i;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},SVGShapeElement.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},LetterProps.prototype.update=function(t,e,i,r,s,a){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1,this._mdf.p=!1;var n=!1;return this.o!==t&&(this.o=t,this._mdf.o=!0,n=!0),this.sw!==e&&(this.sw=e,this._mdf.sw=!0,n=!0),this.sc!==i&&(this.sc=i,this._mdf.sc=!0,n=!0),this.fc!==r&&(this.fc=r,this._mdf.fc=!0,n=!0),this.m!==s&&(this.m=s,this._mdf.m=!0,n=!0),!a.length||this.p[0]===a[0]&&this.p[1]===a[1]&&this.p[4]===a[4]&&this.p[5]===a[5]&&this.p[12]===a[12]&&this.p[13]===a[13]||(this.p=a,this._mdf.p=!0,n=!0),n},TextProperty.prototype.defaultBoxWidth=[0,0],TextProperty.prototype.copyData=function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},TextProperty.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},TextProperty.prototype.searchProperty=function(){return this.searchKeyframes()},TextProperty.prototype.searchKeyframes=function(){return this.kf=this.data.d.k.length>1,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,i=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{var r;this.lock=!0,this._mdf=!1;var s=this.effectsSequence.length,a=t||this.data.d.k[this.keysIndex].s;for(r=0;r<s;r+=1)a=i!==this.keysIndex?this.effectsSequence[r](a,a.t):this.effectsSequence[r](this.currentData,a.t);e!==a&&this.setCurrentData(a),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},TextProperty.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,i=0,r=t.length;i<=r-1&&!(i===r-1||t[i+1].t>e);)i+=1;return this.keysIndex!==i&&(this.keysIndex=i),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e,i,r=[],s=0,a=t.length,n=!1,o=!1,h="";s<a;)n=o,o=!1,e=t.charCodeAt(s),h=t.charAt(s),FontManager.isCombinedCharacter(e)?n=!0:e>=55296&&e<=56319?FontManager.isRegionalFlag(t,s)?h=t.substr(s,14):(i=t.charCodeAt(s+1))>=56320&&i<=57343&&(FontManager.isModifier(e,i)?(h=t.substr(s,2),n=!0):h=FontManager.isFlagEmoji(t.substr(s,4))?t.substr(s,4):t.substr(s,2)):e>56319?(i=t.charCodeAt(s+1),FontManager.isVariationSelector(e)&&(n=!0)):FontManager.isZeroWidthJoiner(e)&&(n=!0,o=!0),n?(r[r.length-1]+=h,n=!1):r.push(h),s+=h.length;return r},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,i,r,s,a,n,o,h=this.elem.globalData.fontManager,l=this.data,p=[],f=0,c=l.m.g,m=0,d=0,u=0,y=[],g=0,v=0,P=h.getFontByName(t.f),b=0,x=getFontProperties(P);t.fWeight=x.weight,t.fStyle=x.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),i=t.finalText.length,t.finalLineHeight=t.lh;var S,C=t.tr/1e3*t.finalSize;if(t.sz)for(var E,_,T=!0,A=t.sz[0],D=t.sz[1];T;){E=0,g=0,i=(_=this.buildFinalText(t.t)).length,C=t.tr/1e3*t.finalSize;var k=-1;for(e=0;e<i;e+=1)S=_[e].charCodeAt(0),r=!1," "===_[e]?k=e:13!==S&&3!==S||(g=0,r=!0,E+=t.finalLineHeight||1.2*t.finalSize),h.chars?(o=h.getCharData(_[e],P.fStyle,P.fFamily),b=r?0:o.w*t.finalSize/100):b=h.measureText(_[e],t.f,t.finalSize),g+b>A&&" "!==_[e]?(-1===k?i+=1:e=k,E+=t.finalLineHeight||1.2*t.finalSize,_.splice(e,k===e?1:0,"\r"),k=-1,g=0):(g+=b,g+=C);E+=P.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&D<E?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=_,i=t.finalText.length,T=!1)}g=-C,b=0;var M,I=0;for(e=0;e<i;e+=1)if(r=!1,13===(S=(M=t.finalText[e]).charCodeAt(0))||3===S?(I=0,y.push(g),v=g>v?g:v,g=-2*C,s="",r=!0,u+=1):s=M,h.chars?(o=h.getCharData(M,P.fStyle,h.getFontByName(t.f).fFamily),b=r?0:o.w*t.finalSize/100):b=h.measureText(s,t.f,t.finalSize)," "===M?I+=b+C:(g+=b+C+I,I=0),p.push({l:b,an:b,add:m,n:r,anIndexes:[],val:s,line:u,animatorJustifyOffset:0}),2==c){if(m+=b,""===s||" "===s||e===i-1){for(""!==s&&" "!==s||(m-=b);d<=e;)p[d].an=m,p[d].ind=f,p[d].extra=b,d+=1;f+=1,m=0}}else if(3==c){if(m+=b,""===s||e===i-1){for(""===s&&(m-=b);d<=e;)p[d].an=m,p[d].ind=f,p[d].extra=b,d+=1;m=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=g>v?g:v,y.push(g),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=y;var F,w,V,L,R=l.a;n=R.length;var B=[];for(a=0;a<n;a+=1){for((F=R[a]).a.sc&&(t.strokeColorAnim=!0),F.a.sw&&(t.strokeWidthAnim=!0),(F.a.fc||F.a.fh||F.a.fs||F.a.fb)&&(t.fillColorAnim=!0),L=0,V=F.s.b,e=0;e<i;e+=1)(w=p[e]).anIndexes[a]=L,(1==V&&""!==w.val||2==V&&""!==w.val&&" "!==w.val||3==V&&(w.n||" "==w.val||e==i-1)||4==V&&(w.n||e==i-1))&&(1===F.s.rn&&B.push(L),L+=1);l.a[a].s.totalChars=L;var O,z=-1;if(1===F.s.rn)for(e=0;e<i;e+=1)z!=(w=p[e]).anIndexes[a]&&(z=w.anIndexes[a],O=B.splice(Math.floor(Math.random()*B.length),1)[0]),w.anIndexes[a]=O}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=P.ascent*t.finalSize/100},TextProperty.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var i=this.copyData({},this.data.d.k[e].s);i=this.copyData(i,t),this.data.d.k[e].s=i,this.recalculate(e),this.setCurrentData(i),this.elem.addDynamicProperty(this)},TextProperty.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},TextProperty.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},TextProperty.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var TextSelectorProp=function(){var t=Math.max,e=Math.min,i=Math.floor;function r(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=PropertyFactory.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?PropertyFactory.getProp(t,e.e,0,0,this):{v:100},this.o=PropertyFactory.getProp(t,e.o||{k:0},0,0,this),this.xe=PropertyFactory.getProp(t,e.xe||{k:0},0,0,this),this.ne=PropertyFactory.getProp(t,e.ne||{k:0},0,0,this),this.sm=PropertyFactory.getProp(t,e.sm||{k:100},0,0,this),this.a=PropertyFactory.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return r.prototype={getMult:function(r){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var s=0,a=0,n=1,o=1;this.ne.v>0?s=this.ne.v/100:a=-this.ne.v/100,this.xe.v>0?n=1-this.xe.v/100:o=1+this.xe.v/100;var h=BezierFactory.getBezierEasing(s,a,n,o).get,l=0,p=this.finalS,f=this.finalE,c=this.data.sh;if(2===c)l=h(l=f===p?r>=f?1:0:t(0,e(.5/(f-p)+(r-p)/(f-p),1)));else if(3===c)l=h(l=f===p?r>=f?0:1:1-t(0,e(.5/(f-p)+(r-p)/(f-p),1)));else if(4===c)f===p?l=0:(l=t(0,e(.5/(f-p)+(r-p)/(f-p),1)))<.5?l*=2:l=1-2*(l-.5),l=h(l);else if(5===c){if(f===p)l=0;else{var m=f-p,d=-m/2+(r=e(t(0,r+.5-p),f-p)),u=m/2;l=Math.sqrt(1-d*d/(u*u))}l=h(l)}else 6===c?(f===p?l=0:(r=e(t(0,r+.5-p),f-p),l=(1+Math.cos(Math.PI+2*Math.PI*r/(f-p)))/2),l=h(l)):(r>=i(p)&&(l=t(0,e(r-p<0?e(f,1)-(p-r):f-r,1))),l=h(l));if(100!==this.sm.v){var y=.01*this.sm.v;0===y&&(y=1e-8);var g=.5-.5*y;l<g?l=0:(l=(l-g)/y)>1&&(l=1)}return l*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,i=this.o.v/e,r=this.s.v/e+i,s=this.e.v/e+i;if(r>s){var a=r;r=s,s=a}this.finalS=r,this.finalE=s}},extendPrototype([DynamicPropertyContainer],r),{getTextSelectorProp:function(t,e,i){return new r(t,e,i)}}}();function TextAnimatorDataProperty(t,e,i){var r={propType:!1},s=PropertyFactory.getProp,a=e.a;this.a={r:a.r?s(t,a.r,0,degToRads,i):r,rx:a.rx?s(t,a.rx,0,degToRads,i):r,ry:a.ry?s(t,a.ry,0,degToRads,i):r,sk:a.sk?s(t,a.sk,0,degToRads,i):r,sa:a.sa?s(t,a.sa,0,degToRads,i):r,s:a.s?s(t,a.s,1,.01,i):r,a:a.a?s(t,a.a,1,0,i):r,o:a.o?s(t,a.o,0,.01,i):r,p:a.p?s(t,a.p,1,0,i):r,sw:a.sw?s(t,a.sw,0,0,i):r,sc:a.sc?s(t,a.sc,1,0,i):r,fc:a.fc?s(t,a.fc,1,0,i):r,fh:a.fh?s(t,a.fh,0,0,i):r,fs:a.fs?s(t,a.fs,0,.01,i):r,fb:a.fb?s(t,a.fb,0,.01,i):r,t:a.t?s(t,a.t,0,0,i):r},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,i),this.s.t=e.s.t}function TextAnimatorProperty(t,e,i){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=i,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(i)}function ITextElement(){}TextAnimatorProperty.prototype.searchProperties=function(){var t,e,i=this._textData.a.length,r=PropertyFactory.getProp;for(t=0;t<i;t+=1)e=this._textData.a[t],this._animatorsData[t]=new TextAnimatorDataProperty(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:r(this._elem,this._textData.p.a,0,0,this),f:r(this._elem,this._textData.p.f,0,0,this),l:r(this._elem,this._textData.p.l,0,0,this),r:r(this._elem,this._textData.p.r,0,0,this),p:r(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=r(this._elem,this._textData.m.a,1,0,this)},TextAnimatorProperty.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var i,r,s,a,n,o,h,l,p,f,c,m,d,u,y,g,v,P,b,x=this._moreOptions.alignment.v,S=this._animatorsData,C=this._textData,E=this.mHelper,_=this._renderType,T=this.renderedLetters.length,A=t.l;if(this._hasMaskedPath){if(b=this._pathData.m,!this._pathData.n||this._pathData._mdf){var D,k=b.v;for(this._pathData.r.v&&(k=k.reverse()),n={tLength:0,segments:[]},a=k._length-1,g=0,s=0;s<a;s+=1)D=bez.buildBezierData(k.v[s],k.v[s+1],[k.o[s][0]-k.v[s][0],k.o[s][1]-k.v[s][1]],[k.i[s+1][0]-k.v[s+1][0],k.i[s+1][1]-k.v[s+1][1]]),n.tLength+=D.segmentLength,n.segments.push(D),g+=D.segmentLength;s=a,b.v.c&&(D=bez.buildBezierData(k.v[s],k.v[0],[k.o[s][0]-k.v[s][0],k.o[s][1]-k.v[s][1]],[k.i[0][0]-k.v[0][0],k.i[0][1]-k.v[0][1]]),n.tLength+=D.segmentLength,n.segments.push(D),g+=D.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,c=0,f=1,l=0,p=!0,u=n.segments,o<0&&b.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),f=(d=u[c=u.length-1].points).length-1;o<0;)o+=d[f].partialLength,(f-=1)<0&&(f=(d=u[c-=1].points).length-1);m=(d=u[c].points)[f-1],y=(h=d[f]).partialLength}a=A.length,i=0,r=0;var M,I,F,w,V,L=1.2*t.finalSize*.714,R=!0;F=S.length;var B,O,z,G,N,j,q,W,H,$,J,Y,X=-1,Z=o,K=c,U=f,Q=-1,tt="",et=this.defaultPropsArray;if(2===t.j||1===t.j){var it=0,rt=0,st=2===t.j?-.5:-1,at=0,nt=!0;for(s=0;s<a;s+=1)if(A[s].n){for(it&&(it+=rt);at<s;)A[at].animatorJustifyOffset=it,at+=1;it=0,nt=!0}else{for(I=0;I<F;I+=1)(M=S[I].a).t.propType&&(nt&&2===t.j&&(rt+=M.t.v*st),(V=S[I].s.getMult(A[s].anIndexes[I],C.a[I].s.totalChars)).length?it+=M.t.v*V[0]*st:it+=M.t.v*V*st);nt=!1}for(it&&(it+=rt);at<s;)A[at].animatorJustifyOffset=it,at+=1}for(s=0;s<a;s+=1){if(E.reset(),G=1,A[s].n)i=0,r+=t.yOffset,r+=R?1:0,o=Z,R=!1,this._hasMaskedPath&&(f=U,m=(d=u[c=K].points)[f-1],y=(h=d[f]).partialLength,l=0),tt="",J="",H="",Y="",et=this.defaultPropsArray;else{if(this._hasMaskedPath){if(Q!==A[s].line){switch(t.j){case 1:o+=g-t.lineWidths[A[s].line];break;case 2:o+=(g-t.lineWidths[A[s].line])/2}Q=A[s].line}X!==A[s].ind&&(A[X]&&(o+=A[X].extra),o+=A[s].an/2,X=A[s].ind),o+=x[0]*A[s].an*.005;var ot=0;for(I=0;I<F;I+=1)(M=S[I].a).p.propType&&((V=S[I].s.getMult(A[s].anIndexes[I],C.a[I].s.totalChars)).length?ot+=M.p.v[0]*V[0]:ot+=M.p.v[0]*V),M.a.propType&&((V=S[I].s.getMult(A[s].anIndexes[I],C.a[I].s.totalChars)).length?ot+=M.a.v[0]*V[0]:ot+=M.a.v[0]*V);for(p=!0,this._pathData.a.v&&(o=.5*A[0].an+(g-this._pathData.f.v-.5*A[0].an-.5*A[A.length-1].an)*X/(a-1),o+=this._pathData.f.v);p;)l+y>=o+ot||!d?(v=(o+ot-l)/h.partialLength,O=m.point[0]+(h.point[0]-m.point[0])*v,z=m.point[1]+(h.point[1]-m.point[1])*v,E.translate(-x[0]*A[s].an*.005,-x[1]*L*.01),p=!1):d&&(l+=h.partialLength,(f+=1)>=d.length&&(f=0,u[c+=1]?d=u[c].points:b.v.c?(f=0,d=u[c=0].points):(l-=h.partialLength,d=null)),d&&(m=h,y=(h=d[f]).partialLength));B=A[s].an/2-A[s].add,E.translate(-B,0,0)}else B=A[s].an/2-A[s].add,E.translate(-B,0,0),E.translate(-x[0]*A[s].an*.005,-x[1]*L*.01,0);for(I=0;I<F;I+=1)(M=S[I].a).t.propType&&(V=S[I].s.getMult(A[s].anIndexes[I],C.a[I].s.totalChars),0===i&&0===t.j||(this._hasMaskedPath?V.length?o+=M.t.v*V[0]:o+=M.t.v*V:V.length?i+=M.t.v*V[0]:i+=M.t.v*V));for(t.strokeWidthAnim&&(j=t.sw||0),t.strokeColorAnim&&(N=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(q=[t.fc[0],t.fc[1],t.fc[2]]),I=0;I<F;I+=1)(M=S[I].a).a.propType&&((V=S[I].s.getMult(A[s].anIndexes[I],C.a[I].s.totalChars)).length?E.translate(-M.a.v[0]*V[0],-M.a.v[1]*V[1],M.a.v[2]*V[2]):E.translate(-M.a.v[0]*V,-M.a.v[1]*V,M.a.v[2]*V));for(I=0;I<F;I+=1)(M=S[I].a).s.propType&&((V=S[I].s.getMult(A[s].anIndexes[I],C.a[I].s.totalChars)).length?E.scale(1+(M.s.v[0]-1)*V[0],1+(M.s.v[1]-1)*V[1],1):E.scale(1+(M.s.v[0]-1)*V,1+(M.s.v[1]-1)*V,1));for(I=0;I<F;I+=1){if(M=S[I].a,V=S[I].s.getMult(A[s].anIndexes[I],C.a[I].s.totalChars),M.sk.propType&&(V.length?E.skewFromAxis(-M.sk.v*V[0],M.sa.v*V[1]):E.skewFromAxis(-M.sk.v*V,M.sa.v*V)),M.r.propType&&(V.length?E.rotateZ(-M.r.v*V[2]):E.rotateZ(-M.r.v*V)),M.ry.propType&&(V.length?E.rotateY(M.ry.v*V[1]):E.rotateY(M.ry.v*V)),M.rx.propType&&(V.length?E.rotateX(M.rx.v*V[0]):E.rotateX(M.rx.v*V)),M.o.propType&&(V.length?G+=(M.o.v*V[0]-G)*V[0]:G+=(M.o.v*V-G)*V),t.strokeWidthAnim&&M.sw.propType&&(V.length?j+=M.sw.v*V[0]:j+=M.sw.v*V),t.strokeColorAnim&&M.sc.propType)for(W=0;W<3;W+=1)V.length?N[W]+=(M.sc.v[W]-N[W])*V[0]:N[W]+=(M.sc.v[W]-N[W])*V;if(t.fillColorAnim&&t.fc){if(M.fc.propType)for(W=0;W<3;W+=1)V.length?q[W]+=(M.fc.v[W]-q[W])*V[0]:q[W]+=(M.fc.v[W]-q[W])*V;M.fh.propType&&(q=V.length?addHueToRGB(q,M.fh.v*V[0]):addHueToRGB(q,M.fh.v*V)),M.fs.propType&&(q=V.length?addSaturationToRGB(q,M.fs.v*V[0]):addSaturationToRGB(q,M.fs.v*V)),M.fb.propType&&(q=V.length?addBrightnessToRGB(q,M.fb.v*V[0]):addBrightnessToRGB(q,M.fb.v*V))}}for(I=0;I<F;I+=1)(M=S[I].a).p.propType&&(V=S[I].s.getMult(A[s].anIndexes[I],C.a[I].s.totalChars),this._hasMaskedPath?V.length?E.translate(0,M.p.v[1]*V[0],-M.p.v[2]*V[1]):E.translate(0,M.p.v[1]*V,-M.p.v[2]*V):V.length?E.translate(M.p.v[0]*V[0],M.p.v[1]*V[1],-M.p.v[2]*V[2]):E.translate(M.p.v[0]*V,M.p.v[1]*V,-M.p.v[2]*V));if(t.strokeWidthAnim&&(H=j<0?0:j),t.strokeColorAnim&&($="rgb("+Math.round(255*N[0])+","+Math.round(255*N[1])+","+Math.round(255*N[2])+")"),t.fillColorAnim&&t.fc&&(J="rgb("+Math.round(255*q[0])+","+Math.round(255*q[1])+","+Math.round(255*q[2])+")"),this._hasMaskedPath){if(E.translate(0,-t.ls),E.translate(0,x[1]*L*.01+r,0),this._pathData.p.v){P=(h.point[1]-m.point[1])/(h.point[0]-m.point[0]);var ht=180*Math.atan(P)/Math.PI;h.point[0]<m.point[0]&&(ht+=180),E.rotate(-ht*Math.PI/180)}E.translate(O,z,0),o-=x[0]*A[s].an*.005,A[s+1]&&X!==A[s+1].ind&&(o+=A[s].an/2,o+=.001*t.tr*t.finalSize)}else{switch(E.translate(i,r,0),t.ps&&E.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:E.translate(A[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[A[s].line]),0,0);break;case 2:E.translate(A[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[A[s].line])/2,0,0)}E.translate(0,-t.ls),E.translate(B,0,0),E.translate(x[0]*A[s].an*.005,x[1]*L*.01,0),i+=A[s].l+.001*t.tr*t.finalSize}"html"===_?tt=E.toCSS():"svg"===_?tt=E.to2dCSS():et=[E.props[0],E.props[1],E.props[2],E.props[3],E.props[4],E.props[5],E.props[6],E.props[7],E.props[8],E.props[9],E.props[10],E.props[11],E.props[12],E.props[13],E.props[14],E.props[15]],Y=G}T<=s?(w=new LetterProps(Y,H,$,J,tt,et),this.renderedLetters.push(w),T+=1,this.lettersChangedFlag=!0):(w=this.renderedLetters[s],this.lettersChangedFlag=w.update(Y,H,$,J,tt,et)||this.lettersChangedFlag)}}},TextAnimatorProperty.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},TextAnimatorProperty.prototype.mHelper=new Matrix,TextAnimatorProperty.prototype.defaultPropsArray=[],extendPrototype([DynamicPropertyContainer],TextAnimatorProperty),ITextElement.prototype.initElement=function(t,e,i){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,i),this.textProperty=new TextProperty(this,t.t,this.dynamicProperties),this.textAnimator=new TextAnimatorProperty(t.t,this.renderType,this),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},ITextElement.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},ITextElement.prototype.createPathShape=function(t,e){var i,r,s=e.length,a="";for(i=0;i<s;i+=1)"sh"===e[i].ty&&(r=e[i].ks.k,a+=buildShapeString(r,r.i.length,!0,t));return a},ITextElement.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},ITextElement.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},ITextElement.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},ITextElement.prototype.applyTextPropertiesToMatrix=function(t,e,i,r,s){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i])/2,0,0)}e.translate(r,s,0)},ITextElement.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},ITextElement.prototype.emptyProp=new LetterProps,ITextElement.prototype.destroy=function(){},ITextElement.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var emptyShapeData={shapes:[]};function SVGTextLottieElement(t,e,i){this.textSpans=[],this.renderType="svg",this.initElement(t,e,i)}function ISolidElement(t,e,i){this.initElement(t,e,i)}function NullElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initFrame(),this.initTransform(t,e,i),this.initHierarchy()}function SVGRendererBase(){}function ICompElement(){}function SVGCompElement(t,e,i){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function SVGRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=createNS("svg");var i="";if(e&&e.title){var r=createNS("title"),s=createElementID();r.setAttribute("id",s),r.textContent=e.title,this.svgElement.appendChild(r),i+=s}if(e&&e.description){var a=createNS("desc"),n=createElementID();a.setAttribute("id",n),a.textContent=e.description,this.svgElement.appendChild(a),i+=" "+n}i&&this.svgElement.setAttribute("aria-labelledby",i);var o=createNS("defs");this.svgElement.appendChild(o);var h=createNS("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}function ShapeTransformManager(){this.sequences={},this.sequenceList=[],this.transform_key_count=0}extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],SVGTextLottieElement),SVGTextLottieElement.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=createNS("text"))},SVGTextLottieElement.prototype.buildTextContents=function(t){for(var e=0,i=t.length,r=[],s="";e<i;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(r.push(s),s=""):s+=t[e],e+=1;return r.push(s),r},SVGTextLottieElement.prototype.buildShapeData=function(t,e){if(t.shapes&&t.shapes.length){var i=t.shapes[0];if(i.it){var r=i.it[i.it.length-1];r.s&&(r.s.k[0]=e,r.s.k[1]=e)}}return t},SVGTextLottieElement.prototype.buildNewText=function(){var t,e;this.addDynamicProperty(this);var i=this.textProperty.currentData;this.renderedLetters=createSizedArray(i?i.l.length:0),i.fc?this.layerElement.setAttribute("fill",this.buildColor(i.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),i.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(i.sc)),this.layerElement.setAttribute("stroke-width",i.sw)),this.layerElement.setAttribute("font-size",i.finalSize);var r=this.globalData.fontManager.getFontByName(i.f);if(r.fClass)this.layerElement.setAttribute("class",r.fClass);else{this.layerElement.setAttribute("font-family",r.fFamily);var s=i.fWeight,a=i.fStyle;this.layerElement.setAttribute("font-style",a),this.layerElement.setAttribute("font-weight",s)}this.layerElement.setAttribute("aria-label",i.t);var n,o=i.l||[],h=!!this.globalData.fontManager.chars;e=o.length;var l=this.mHelper,p=this.data.singleShape,f=0,c=0,m=!0,d=.001*i.tr*i.finalSize;if(!p||h||i.sz){var u,y=this.textSpans.length;for(t=0;t<e;t+=1){if(this.textSpans[t]||(this.textSpans[t]={span:null,childSpan:null,glyph:null}),!h||!p||0===t){if(n=y>t?this.textSpans[t].span:createNS(h?"g":"text"),y<=t){if(n.setAttribute("stroke-linecap","butt"),n.setAttribute("stroke-linejoin","round"),n.setAttribute("stroke-miterlimit","4"),this.textSpans[t].span=n,h){var g=createNS("g");n.appendChild(g),this.textSpans[t].childSpan=g}this.textSpans[t].span=n,this.layerElement.appendChild(n)}n.style.display="inherit"}if(l.reset(),p&&(o[t].n&&(f=-d,c+=i.yOffset,c+=m?1:0,m=!1),this.applyTextPropertiesToMatrix(i,l,o[t].line,f,c),f+=o[t].l||0,f+=d),h){var v;if(1===(u=this.globalData.fontManager.getCharData(i.finalText[t],r.fStyle,this.globalData.fontManager.getFontByName(i.f).fFamily)).t)v=new SVGCompElement(u.data,this.globalData,this);else{var P=emptyShapeData;u.data&&u.data.shapes&&(P=this.buildShapeData(u.data,i.finalSize)),v=new SVGShapeElement(P,this.globalData,this)}if(this.textSpans[t].glyph){var b=this.textSpans[t].glyph;this.textSpans[t].childSpan.removeChild(b.layerElement),b.destroy()}this.textSpans[t].glyph=v,v._debug=!0,v.prepareFrame(0),v.renderFrame(),this.textSpans[t].childSpan.appendChild(v.layerElement),1===u.t&&this.textSpans[t].childSpan.setAttribute("transform","scale("+i.finalSize/100+","+i.finalSize/100+")")}else p&&n.setAttribute("transform","translate("+l.props[12]+","+l.props[13]+")"),n.textContent=o[t].val,n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}p&&n&&n.setAttribute("d","")}else{var x=this.textContainer,S="start";switch(i.j){case 1:S="end";break;case 2:S="middle";break;default:S="start"}x.setAttribute("text-anchor",S),x.setAttribute("letter-spacing",d);var C=this.buildTextContents(i.finalText);for(e=C.length,c=i.ps?i.ps[1]+i.ascent:0,t=0;t<e;t+=1)(n=this.textSpans[t].span||createNS("tspan")).textContent=C[t],n.setAttribute("x",0),n.setAttribute("y",c),n.style.display="inherit",x.appendChild(n),this.textSpans[t]||(this.textSpans[t]={span:null,glyph:null}),this.textSpans[t].span=n,c+=i.finalLineHeight;this.layerElement.appendChild(x)}for(;t<this.textSpans.length;)this.textSpans[t].span.style.display="none",t+=1;this._sizeChanged=!0},SVGTextLottieElement.prototype.sourceRectAtTime=function(){if(this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged){this._sizeChanged=!1;var t=this.layerElement.getBBox();this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}}return this.bbox},SVGTextLottieElement.prototype.getValue=function(){var t,e,i=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<i;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf&&(this._mdf=!0))},SVGTextLottieElement.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){var t,e;this._sizeChanged=!0;var i,r,s,a=this.textAnimator.renderedLetters,n=this.textProperty.currentData.l;for(e=n.length,t=0;t<e;t+=1)n[t].n||(i=a[t],r=this.textSpans[t].span,(s=this.textSpans[t].glyph)&&s.renderFrame(),i._mdf.m&&r.setAttribute("transform",i.m),i._mdf.o&&r.setAttribute("opacity",i.o),i._mdf.sw&&r.setAttribute("stroke-width",i.sw),i._mdf.sc&&r.setAttribute("stroke",i.sc),i._mdf.fc&&r.setAttribute("fill",i.fc))}},extendPrototype([IImageElement],ISolidElement),ISolidElement.prototype.createContent=function(){var t=createNS("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},NullElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},NullElement.prototype.renderFrame=function(){},NullElement.prototype.getBaseElement=function(){return null},NullElement.prototype.destroy=function(){},NullElement.prototype.sourceRectAtTime=function(){},NullElement.prototype.hide=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement],NullElement),extendPrototype([BaseRenderer],SVGRendererBase),SVGRendererBase.prototype.createNull=function(t){return new NullElement(t,this.globalData,this)},SVGRendererBase.prototype.createShape=function(t){return new SVGShapeElement(t,this.globalData,this)},SVGRendererBase.prototype.createText=function(t){return new SVGTextLottieElement(t,this.globalData,this)},SVGRendererBase.prototype.createImage=function(t){return new IImageElement(t,this.globalData,this)},SVGRendererBase.prototype.createSolid=function(t){return new ISolidElement(t,this.globalData,this)},SVGRendererBase.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var i=createNS("clipPath"),r=createNS("rect");r.setAttribute("width",t.w),r.setAttribute("height",t.h),r.setAttribute("x",0),r.setAttribute("y",0);var s=createElementID();i.setAttribute("id",s),i.appendChild(r),this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),e.appendChild(i),this.layers=t.layers,this.elements=createSizedArray(t.layers.length)},SVGRendererBase.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},SVGRendererBase.prototype.updateContainerSize=function(){},SVGRendererBase.prototype.findIndexByInd=function(t){var e=0,i=this.layers.length;for(e=0;e<i;e+=1)if(this.layers[e].ind===t)return e;return-1},SVGRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){e[t]=!0;var i=this.createItem(this.layers[t]);if(e[t]=i,getExpressionsPlugin()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(i),i.initExpressions()),this.appendElementInPos(i,t),this.layers[t].tt){var r="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1;if(-1===r)return;if(this.elements[r]&&!0!==this.elements[r]){var s=e[r].getMatte(this.layers[t].tt);i.setMatte(s)}else this.buildItem(r),this.addPendingElement(i)}}},SVGRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,i=this.elements.length;e<i;){if(this.elements[e]===t){var r="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,s=this.elements[r].getMatte(this.layers[e].tt);t.setMatte(s);break}e+=1}}},SVGRendererBase.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){var e;null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var i=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=i-1;e>=0;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<i;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},SVGRendererBase.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){for(var r,s=0;s<e;)this.elements[s]&&!0!==this.elements[s]&&this.elements[s].getBaseElement()&&(r=this.elements[s].getBaseElement()),s+=1;r?this.layerElement.insertBefore(i,r):this.layerElement.appendChild(i)}},SVGRendererBase.prototype.hide=function(){this.layerElement.style.display="none"},SVGRendererBase.prototype.show=function(){this.layerElement.style.display="block"},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement,RenderableDOMElement],ICompElement),ICompElement.prototype.initElement=function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},ICompElement.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var i,r=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),i=r-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&(this.elements[i].prepareFrame(this.renderedFrame-this.layers[i].st),this.elements[i]._mdf&&(this._mdf=!0))}},ICompElement.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},ICompElement.prototype.setElements=function(t){this.elements=t},ICompElement.prototype.getElements=function(){return this.elements},ICompElement.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},ICompElement.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},extendPrototype([SVGRendererBase,ICompElement,SVGBaseElement],SVGCompElement),SVGCompElement.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},extendPrototype([SVGRendererBase],SVGRenderer),SVGRenderer.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},ShapeTransformManager.prototype={addTransformSequence:function(t){var e,i=t.length,r="_";for(e=0;e<i;e+=1)r+=t[e].transform.key+"_";var s=this.sequences[r];return s||(s={transforms:[].concat(t),finalTransform:new Matrix,_mdf:!1},this.sequences[r]=s,this.sequenceList.push(s)),s},processSequence:function(t,e){for(var i=0,r=t.transforms.length,s=e;i<r&&!e;){if(t.transforms[i].transform.mProps._mdf){s=!0;break}i+=1}if(s)for(t.finalTransform.reset(),i=r-1;i>=0;i-=1)t.finalTransform.multiply(t.transforms[i].transform.mProps.v);t._mdf=s},processSequences:function(t){var e,i=this.sequenceList.length;for(e=0;e<i;e+=1)this.processSequence(this.sequenceList[e],t)},getNewKey:function(){return this.transform_key_count+=1,"_"+this.transform_key_count}};var lumaLoader=function(){var t="__lottie_element_luma_buffer",e=null,i=null,r=null;function s(){var s,a,n;e||(s=createNS("svg"),a=createNS("filter"),n=createNS("feColorMatrix"),a.setAttribute("id",t),n.setAttribute("type","matrix"),n.setAttribute("color-interpolation-filters","sRGB"),n.setAttribute("values","0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0"),a.appendChild(n),s.appendChild(a),s.setAttribute("id",t+"_svg"),featureSupport.svgLumaHidden&&(s.style.display="none"),r=s,document.body.appendChild(r),e=createTag("canvas"),(i=e.getContext("2d")).filter="url(#"+t+")",i.fillStyle="rgba(0,0,0,0)",i.fillRect(0,0,1,1))}return{load:s,get:function(r){return e||s(),e.width=r.width,e.height=r.height,i.filter="url(#"+t+")",e}}};function createCanvas(t,e){if(featureSupport.offscreenCanvas)return new OffscreenCanvas(t,e);var i=createTag("canvas");return i.width=t,i.height=e,i}var assetLoader={loadLumaCanvas:lumaLoader.load,getLumaCanvas:lumaLoader.get,createCanvas:createCanvas},registeredEffects={};function CVEffects(t){var e,i,r=t.data.ef?t.data.ef.length:0;for(this.filters=[],e=0;e<r;e+=1){i=null;var s=t.data.ef[e].ty;if(registeredEffects[s])i=new(0,registeredEffects[s].effect)(t.effectsManager.effectElements[e],t);i&&this.filters.push(i)}this.filters.length&&t.addRenderableComponent(this)}function registerEffect(t,e){registeredEffects[t]={effect:e}}function CVMaskElement(t,e){var i;this.data=t,this.element=e,this.masksProperties=this.data.masksProperties||[],this.viewData=createSizedArray(this.masksProperties.length);var r=this.masksProperties.length,s=!1;for(i=0;i<r;i+=1)"n"!==this.masksProperties[i].mode&&(s=!0),this.viewData[i]=ShapePropertyFactory.getShapeProp(this.element,this.masksProperties[i],3);this.hasMasks=s,s&&this.element.addRenderableComponent(this)}function CVBaseElement(){}CVEffects.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},CVEffects.prototype.getEffects=function(t){var e,i=this.filters.length,r=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&r.push(this.filters[e]);return r},CVMaskElement.prototype.renderFrame=function(){if(this.hasMasks){var t,e,i,r,s=this.element.finalTransform.mat,a=this.element.canvasContext,n=this.masksProperties.length;for(a.beginPath(),t=0;t<n;t+=1)if("n"!==this.masksProperties[t].mode){var o;this.masksProperties[t].inv&&(a.moveTo(0,0),a.lineTo(this.element.globalData.compSize.w,0),a.lineTo(this.element.globalData.compSize.w,this.element.globalData.compSize.h),a.lineTo(0,this.element.globalData.compSize.h),a.lineTo(0,0)),r=this.viewData[t].v,e=s.applyToPointArray(r.v[0][0],r.v[0][1],0),a.moveTo(e[0],e[1]);var h=r._length;for(o=1;o<h;o+=1)i=s.applyToTriplePoints(r.o[o-1],r.i[o],r.v[o]),a.bezierCurveTo(i[0],i[1],i[2],i[3],i[4],i[5]);i=s.applyToTriplePoints(r.o[o-1],r.i[0],r.v[0]),a.bezierCurveTo(i[0],i[1],i[2],i[3],i[4],i[5])}this.element.globalData.renderer.save(!0),a.clip()}},CVMaskElement.prototype.getMaskProperty=MaskElement.prototype.getMaskProperty,CVMaskElement.prototype.destroy=function(){this.element=null};var operationsMap={1:"source-in",2:"source-out",3:"source-in",4:"source-out"};function CVShapeData(t,e,i,r){this.styledShapes=[],this.tr=[0,0,0,0,0,0];var s,a=4;"rc"===e.ty?a=5:"el"===e.ty?a=6:"sr"===e.ty&&(a=7),this.sh=ShapePropertyFactory.getShapeProp(t,e,a,t);var n,o=i.length;for(s=0;s<o;s+=1)i[s].closed||(n={transforms:r.addTransformSequence(i[s].transforms),trNodes:[]},this.styledShapes.push(n),i[s].elements.push(n))}function CVShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.itemsData=[],this.prevViewData=[],this.shapeModifiers=[],this.processedElements=[],this.transformsManager=new ShapeTransformManager,this.initElement(t,e,i)}function CVTextElement(t,e,i){this.textSpans=[],this.yOffset=0,this.fillColorAnim=!1,this.strokeColorAnim=!1,this.strokeWidthAnim=!1,this.stroke=!1,this.fill=!1,this.justifyOffset=0,this.currentRender=null,this.renderType="canvas",this.values={fill:"rgba(0,0,0,0)",stroke:"rgba(0,0,0,0)",sWidth:0,fValue:""},this.initElement(t,e,i)}function CVImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.img=e.imageLoader.getAsset(this.assetData),this.initElement(t,e,i)}function CVSolidElement(t,e,i){this.initElement(t,e,i)}function CanvasRendererBase(){}function CanvasContext(){this.opacity=-1,this.transform=createTypedArray("float32",16),this.fillStyle="",this.strokeStyle="",this.lineWidth="",this.lineCap="",this.lineJoin="",this.miterLimit="",this.id=Math.random()}function CVContextData(){var t;this.stack=[],this.cArrPos=0,this.cTr=new Matrix;for(t=0;t<15;t+=1){var e=new CanvasContext;this.stack[t]=e}this._length=15,this.nativeContext=null,this.transformMat=new Matrix,this.currentOpacity=1,this.currentFillStyle="",this.appliedFillStyle="",this.currentStrokeStyle="",this.appliedStrokeStyle="",this.currentLineWidth="",this.appliedLineWidth="",this.currentLineCap="",this.appliedLineCap="",this.currentLineJoin="",this.appliedLineJoin="",this.appliedMiterLimit="",this.currentMiterLimit=""}function CVCompElement(t,e,i){this.completeLayers=!1,this.layers=t.layers,this.pendingElements=[],this.elements=createSizedArray(this.layers.length),this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function CanvasRenderer(t,e){this.animationItem=t,this.renderConfig={clearCanvas:!e||void 0===e.clearCanvas||e.clearCanvas,context:e&&e.context||null,progressiveLoad:e&&e.progressiveLoad||!1,preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",className:e&&e.className||"",id:e&&e.id||"",runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.renderConfig.dpr=e&&e.dpr||1,this.animationItem.wrapper&&(this.renderConfig.dpr=e&&e.dpr||window.devicePixelRatio||1),this.renderedFrame=-1,this.globalData={frameNum:-1,_mdf:!1,renderConfig:this.renderConfig,currentGlobalAlpha:-1},this.contextData=new CVContextData,this.elements=[],this.pendingElements=[],this.transformMat=new Matrix,this.completeLayers=!1,this.rendererType="canvas",this.renderConfig.clearCanvas&&(this.ctxTransform=this.contextData.transform.bind(this.contextData),this.ctxOpacity=this.contextData.opacity.bind(this.contextData),this.ctxFillStyle=this.contextData.fillStyle.bind(this.contextData),this.ctxStrokeStyle=this.contextData.strokeStyle.bind(this.contextData),this.ctxLineWidth=this.contextData.lineWidth.bind(this.contextData),this.ctxLineCap=this.contextData.lineCap.bind(this.contextData),this.ctxLineJoin=this.contextData.lineJoin.bind(this.contextData),this.ctxMiterLimit=this.contextData.miterLimit.bind(this.contextData),this.ctxFill=this.contextData.fill.bind(this.contextData),this.ctxFillRect=this.contextData.fillRect.bind(this.contextData),this.ctxStroke=this.contextData.stroke.bind(this.contextData),this.save=this.contextData.save.bind(this.contextData))}CVBaseElement.prototype={createElements:function(){},initRendererElement:function(){},createContainerElements:function(){if(this.data.tt>=1){this.buffers=[];var t=this.globalData.canvasContext,e=assetLoader.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(e);var i=assetLoader.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(i),this.data.tt>=3&&!document._isProxy&&assetLoader.loadLumaCanvas()}this.canvasContext=this.globalData.canvasContext,this.transformCanvas=this.globalData.transformCanvas,this.renderableEffectsManager=new CVEffects(this),this.searchEffectTransforms()},createContent:function(){},setBlendMode:function(){var t=this.globalData;if(t.blendMode!==this.data.bm){t.blendMode=this.data.bm;var e=getBlendMode(this.data.bm);t.canvasContext.globalCompositeOperation=e}},createRenderableComponents:function(){this.maskManager=new CVMaskElement(this.data,this),this.transformEffects=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT)},hideElement:function(){this.hidden||this.isInRange&&!this.isTransparent||(this.hidden=!0)},showElement:function(){this.isInRange&&!this.isTransparent&&(this.hidden=!1,this._isFirstFrame=!0,this.maskManager._isFirstFrame=!0)},clearCanvas:function(t){t.clearRect(this.transformCanvas.tx,this.transformCanvas.ty,this.transformCanvas.w*this.transformCanvas.sx,this.transformCanvas.h*this.transformCanvas.sy)},prepareLayer:function(){if(this.data.tt>=1){var t=this.buffers[0].getContext("2d");this.clearCanvas(t),t.drawImage(this.canvasContext.canvas,0,0),this.currentTransform=this.canvasContext.getTransform(),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform)}},exitLayer:function(){if(this.data.tt>=1){var t=this.buffers[1],e=t.getContext("2d");if(this.clearCanvas(e),e.drawImage(this.canvasContext.canvas,0,0),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform),this.comp.getElementById("tp"in this.data?this.data.tp:this.data.ind-1).renderFrame(!0),this.canvasContext.setTransform(1,0,0,1,0,0),this.data.tt>=3&&!document._isProxy){var i=assetLoader.getLumaCanvas(this.canvasContext.canvas);i.getContext("2d").drawImage(this.canvasContext.canvas,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.drawImage(i,0,0)}this.canvasContext.globalCompositeOperation=operationsMap[this.data.tt],this.canvasContext.drawImage(t,0,0),this.canvasContext.globalCompositeOperation="destination-over",this.canvasContext.drawImage(this.buffers[0],0,0),this.canvasContext.setTransform(this.currentTransform),this.canvasContext.globalCompositeOperation="source-over"}},renderFrame:function(t){if(!this.hidden&&!this.data.hd&&(1!==this.data.td||t)){this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.setBlendMode();var e=0===this.data.ty;this.prepareLayer(),this.globalData.renderer.save(e),this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props),this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity),this.renderInnerContent(),this.globalData.renderer.restore(e),this.exitLayer(),this.maskManager.hasMasks&&this.globalData.renderer.restore(!0),this._isFirstFrame&&(this._isFirstFrame=!1)}},destroy:function(){this.canvasContext=null,this.data=null,this.globalData=null,this.maskManager.destroy()},mHelper:new Matrix},CVBaseElement.prototype.hide=CVBaseElement.prototype.hideElement,CVBaseElement.prototype.show=CVBaseElement.prototype.showElement,CVShapeData.prototype.setAsAnimated=SVGShapeData.prototype.setAsAnimated,extendPrototype([BaseElement,TransformElement,CVBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableElement],CVShapeElement),CVShapeElement.prototype.initElement=RenderableDOMElement.prototype.initElement,CVShapeElement.prototype.transformHelper={opacity:1,_opMdf:!1},CVShapeElement.prototype.dashResetter=[],CVShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[])},CVShapeElement.prototype.createStyleElement=function(t,e){var i={data:t,type:t.ty,preTransforms:this.transformsManager.addTransformSequence(e),transforms:[],elements:[],closed:!0===t.hd},r={};if("fl"===t.ty||"st"===t.ty?(r.c=PropertyFactory.getProp(this,t.c,1,255,this),r.c.k||(i.co="rgb("+bmFloor(r.c.v[0])+","+bmFloor(r.c.v[1])+","+bmFloor(r.c.v[2])+")")):"gf"!==t.ty&&"gs"!==t.ty||(r.s=PropertyFactory.getProp(this,t.s,1,null,this),r.e=PropertyFactory.getProp(this,t.e,1,null,this),r.h=PropertyFactory.getProp(this,t.h||{k:0},0,.01,this),r.a=PropertyFactory.getProp(this,t.a||{k:0},0,degToRads,this),r.g=new GradientProperty(this,t.g,this)),r.o=PropertyFactory.getProp(this,t.o,0,.01,this),"st"===t.ty||"gs"===t.ty){if(i.lc=lineCapEnum[t.lc||2],i.lj=lineJoinEnum[t.lj||2],1==t.lj&&(i.ml=t.ml),r.w=PropertyFactory.getProp(this,t.w,0,null,this),r.w.k||(i.wi=r.w.v),t.d){var s=new DashProperty(this,t.d,"canvas",this);r.d=s,r.d.k||(i.da=r.d.dashArray,i.do=r.d.dashoffset[0])}}else i.r=2===t.r?"evenodd":"nonzero";return this.stylesList.push(i),r.style=i,r},CVShapeElement.prototype.createGroupElement=function(){return{it:[],prevViewData:[]}},CVShapeElement.prototype.createTransformElement=function(t){return{transform:{opacity:1,_opMdf:!1,key:this.transformsManager.getNewKey(),op:PropertyFactory.getProp(this,t.o,0,.01,this),mProps:TransformPropertyFactory.getTransformProperty(this,t,this)}}},CVShapeElement.prototype.createShapeElement=function(t){var e=new CVShapeData(this,t,this.stylesList,this.transformsManager);return this.shapes.push(e),this.addShapeToModifiers(e),e},CVShapeElement.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[]),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame)},CVShapeElement.prototype.addTransformToStyleList=function(t){var e,i=this.stylesList.length;for(e=0;e<i;e+=1)this.stylesList[e].closed||this.stylesList[e].transforms.push(t)},CVShapeElement.prototype.removeTransformFromStyleList=function(){var t,e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].closed||this.stylesList[t].transforms.pop()},CVShapeElement.prototype.closeStyles=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].closed=!0},CVShapeElement.prototype.searchShapes=function(t,e,i,r,s){var a,n,o,h,l,p,f=t.length-1,c=[],m=[],d=[].concat(s);for(a=f;a>=0;a-=1){if((h=this.searchProcessedElement(t[a]))?e[a]=i[h-1]:t[a]._shouldRender=r,"fl"===t[a].ty||"st"===t[a].ty||"gf"===t[a].ty||"gs"===t[a].ty)h?e[a].style.closed=!1:e[a]=this.createStyleElement(t[a],d),c.push(e[a].style);else if("gr"===t[a].ty){if(h)for(o=e[a].it.length,n=0;n<o;n+=1)e[a].prevViewData[n]=e[a].it[n];else e[a]=this.createGroupElement(t[a]);this.searchShapes(t[a].it,e[a].it,e[a].prevViewData,r,d)}else"tr"===t[a].ty?(h||(p=this.createTransformElement(t[a]),e[a]=p),d.push(e[a]),this.addTransformToStyleList(e[a])):"sh"===t[a].ty||"rc"===t[a].ty||"el"===t[a].ty||"sr"===t[a].ty?h||(e[a]=this.createShapeElement(t[a])):"tm"===t[a].ty||"rd"===t[a].ty||"pb"===t[a].ty||"zz"===t[a].ty||"op"===t[a].ty?(h?(l=e[a]).closed=!1:((l=ShapeModifiers.getModifier(t[a].ty)).init(this,t[a]),e[a]=l,this.shapeModifiers.push(l)),m.push(l)):"rp"===t[a].ty&&(h?(l=e[a]).closed=!0:(l=ShapeModifiers.getModifier(t[a].ty),e[a]=l,l.init(this,t,a,e),this.shapeModifiers.push(l),r=!1),m.push(l));this.addProcessedElement(t[a],a+1)}for(this.removeTransformFromStyleList(),this.closeStyles(c),f=m.length,a=0;a<f;a+=1)m[a].closed=!0},CVShapeElement.prototype.renderInnerContent=function(){this.transformHelper.opacity=1,this.transformHelper._opMdf=!1,this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame),this.renderShape(this.transformHelper,this.shapesData,this.itemsData,!0)},CVShapeElement.prototype.renderShapeTransform=function(t,e){(t._opMdf||e.op._mdf||this._isFirstFrame)&&(e.opacity=t.opacity,e.opacity*=e.op.v,e._opMdf=!0)},CVShapeElement.prototype.drawLayer=function(){var t,e,i,r,s,a,n,o,h,l=this.stylesList.length,p=this.globalData.renderer,f=this.globalData.canvasContext;for(t=0;t<l;t+=1)if(("st"!==(o=(h=this.stylesList[t]).type)&&"gs"!==o||0!==h.wi)&&h.data._shouldRender&&0!==h.coOp&&0!==this.globalData.currentGlobalAlpha){for(p.save(),a=h.elements,"st"===o||"gs"===o?(p.ctxStrokeStyle("st"===o?h.co:h.grd),p.ctxLineWidth(h.wi),p.ctxLineCap(h.lc),p.ctxLineJoin(h.lj),p.ctxMiterLimit(h.ml||0)):p.ctxFillStyle("fl"===o?h.co:h.grd),p.ctxOpacity(h.coOp),"st"!==o&&"gs"!==o&&f.beginPath(),p.ctxTransform(h.preTransforms.finalTransform.props),i=a.length,e=0;e<i;e+=1){for("st"!==o&&"gs"!==o||(f.beginPath(),h.da&&(f.setLineDash(h.da),f.lineDashOffset=h.do)),s=(n=a[e].trNodes).length,r=0;r<s;r+=1)"m"===n[r].t?f.moveTo(n[r].p[0],n[r].p[1]):"c"===n[r].t?f.bezierCurveTo(n[r].pts[0],n[r].pts[1],n[r].pts[2],n[r].pts[3],n[r].pts[4],n[r].pts[5]):f.closePath();"st"!==o&&"gs"!==o||(p.ctxStroke(),h.da&&f.setLineDash(this.dashResetter))}"st"!==o&&"gs"!==o&&this.globalData.renderer.ctxFill(h.r),p.restore()}},CVShapeElement.prototype.renderShape=function(t,e,i,r){var s,a;for(a=t,s=e.length-1;s>=0;s-=1)"tr"===e[s].ty?(a=i[s].transform,this.renderShapeTransform(t,a)):"sh"===e[s].ty||"el"===e[s].ty||"rc"===e[s].ty||"sr"===e[s].ty?this.renderPath(e[s],i[s]):"fl"===e[s].ty?this.renderFill(e[s],i[s],a):"st"===e[s].ty?this.renderStroke(e[s],i[s],a):"gf"===e[s].ty||"gs"===e[s].ty?this.renderGradientFill(e[s],i[s],a):"gr"===e[s].ty?this.renderShape(a,e[s].it,i[s].it):e[s].ty;r&&this.drawLayer()},CVShapeElement.prototype.renderStyledShape=function(t,e){if(this._isFirstFrame||e._mdf||t.transforms._mdf){var i,r,s,a=t.trNodes,n=e.paths,o=n._length;a.length=0;var h=t.transforms.finalTransform;for(s=0;s<o;s+=1){var l=n.shapes[s];if(l&&l.v){for(r=l._length,i=1;i<r;i+=1)1===i&&a.push({t:"m",p:h.applyToPointArray(l.v[0][0],l.v[0][1],0)}),a.push({t:"c",pts:h.applyToTriplePoints(l.o[i-1],l.i[i],l.v[i])});1===r&&a.push({t:"m",p:h.applyToPointArray(l.v[0][0],l.v[0][1],0)}),l.c&&r&&(a.push({t:"c",pts:h.applyToTriplePoints(l.o[i-1],l.i[0],l.v[0])}),a.push({t:"z"}))}}t.trNodes=a}},CVShapeElement.prototype.renderPath=function(t,e){if(!0!==t.hd&&t._shouldRender){var i,r=e.styledShapes.length;for(i=0;i<r;i+=1)this.renderStyledShape(e.styledShapes[i],e.sh)}},CVShapeElement.prototype.renderFill=function(t,e,i){var r=e.style;(e.c._mdf||this._isFirstFrame)&&(r.co="rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i._opMdf||this._isFirstFrame)&&(r.coOp=e.o.v*i.opacity)},CVShapeElement.prototype.renderGradientFill=function(t,e,i){var r,s=e.style;if(!s.grd||e.g._mdf||e.s._mdf||e.e._mdf||1!==t.t&&(e.h._mdf||e.a._mdf)){var a,n=this.globalData.canvasContext,o=e.s.v,h=e.e.v;if(1===t.t)r=n.createLinearGradient(o[0],o[1],h[0],h[1]);else{var l=Math.sqrt(Math.pow(o[0]-h[0],2)+Math.pow(o[1]-h[1],2)),p=Math.atan2(h[1]-o[1],h[0]-o[0]),f=e.h.v;f>=1?f=.99:f<=-1&&(f=-.99);var c=l*f,m=Math.cos(p+e.a.v)*c+o[0],d=Math.sin(p+e.a.v)*c+o[1];r=n.createRadialGradient(m,d,0,o[0],o[1],l)}var u=t.g.p,y=e.g.c,g=1;for(a=0;a<u;a+=1)e.g._hasOpacity&&e.g._collapsable&&(g=e.g.o[2*a+1]),r.addColorStop(y[4*a]/100,"rgba("+y[4*a+1]+","+y[4*a+2]+","+y[4*a+3]+","+g+")");s.grd=r}s.coOp=e.o.v*i.opacity},CVShapeElement.prototype.renderStroke=function(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||this._isFirstFrame)&&(r.da=s.dashArray,r.do=s.dashoffset[0]),(e.c._mdf||this._isFirstFrame)&&(r.co="rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i._opMdf||this._isFirstFrame)&&(r.coOp=e.o.v*i.opacity),(e.w._mdf||this._isFirstFrame)&&(r.wi=e.w.v)},CVShapeElement.prototype.destroy=function(){this.shapesData=null,this.globalData=null,this.canvasContext=null,this.stylesList.length=0,this.itemsData.length=0},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement,ITextElement],CVTextElement),CVTextElement.prototype.tHelper=createTag("canvas").getContext("2d"),CVTextElement.prototype.buildNewText=function(){var t=this.textProperty.currentData;this.renderedLetters=createSizedArray(t.l?t.l.length:0);var e=!1;t.fc?(e=!0,this.values.fill=this.buildColor(t.fc)):this.values.fill="rgba(0,0,0,0)",this.fill=e;var i=!1;t.sc&&(i=!0,this.values.stroke=this.buildColor(t.sc),this.values.sWidth=t.sw);var r,s,a,n,o,h,l,p,f,c,m,d,u=this.globalData.fontManager.getFontByName(t.f),y=t.l,g=this.mHelper;this.stroke=i,this.values.fValue=t.finalSize+"px "+this.globalData.fontManager.getFontByName(t.f).fFamily,s=t.finalText.length;var v=this.data.singleShape,P=.001*t.tr*t.finalSize,b=0,x=0,S=!0,C=0;for(r=0;r<s;r+=1){n=(a=this.globalData.fontManager.getCharData(t.finalText[r],u.fStyle,this.globalData.fontManager.getFontByName(t.f).fFamily))&&a.data||{},g.reset(),v&&y[r].n&&(b=-P,x+=t.yOffset,x+=S?1:0,S=!1),f=(l=n.shapes?n.shapes[0].it:[]).length,g.scale(t.finalSize/100,t.finalSize/100),v&&this.applyTextPropertiesToMatrix(t,g,y[r].line,b,x),m=createSizedArray(f-1);var E=0;for(p=0;p<f;p+=1)if("sh"===l[p].ty){for(h=l[p].ks.k.i.length,c=l[p].ks.k,d=[],o=1;o<h;o+=1)1===o&&d.push(g.applyToX(c.v[0][0],c.v[0][1],0),g.applyToY(c.v[0][0],c.v[0][1],0)),d.push(g.applyToX(c.o[o-1][0],c.o[o-1][1],0),g.applyToY(c.o[o-1][0],c.o[o-1][1],0),g.applyToX(c.i[o][0],c.i[o][1],0),g.applyToY(c.i[o][0],c.i[o][1],0),g.applyToX(c.v[o][0],c.v[o][1],0),g.applyToY(c.v[o][0],c.v[o][1],0));d.push(g.applyToX(c.o[o-1][0],c.o[o-1][1],0),g.applyToY(c.o[o-1][0],c.o[o-1][1],0),g.applyToX(c.i[0][0],c.i[0][1],0),g.applyToY(c.i[0][0],c.i[0][1],0),g.applyToX(c.v[0][0],c.v[0][1],0),g.applyToY(c.v[0][0],c.v[0][1],0)),m[E]=d,E+=1}v&&(b+=y[r].l,b+=P),this.textSpans[C]?this.textSpans[C].elem=m:this.textSpans[C]={elem:m},C+=1}},CVTextElement.prototype.renderInnerContent=function(){var t,e,i,r,s,a;this.validateText(),this.canvasContext.font=this.values.fValue,this.globalData.renderer.ctxLineCap("butt"),this.globalData.renderer.ctxLineJoin("miter"),this.globalData.renderer.ctxMiterLimit(4),this.data.singleShape||this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag);var n,o=this.textAnimator.renderedLetters,h=this.textProperty.currentData.l;e=h.length;var l,p,f=null,c=null,m=null,d=this.globalData.renderer;for(t=0;t<e;t+=1)if(!h[t].n){if((n=o[t])&&(d.save(),d.ctxTransform(n.p),d.ctxOpacity(n.o)),this.fill){for(n&&n.fc?f!==n.fc&&(d.ctxFillStyle(n.fc),f=n.fc):f!==this.values.fill&&(f=this.values.fill,d.ctxFillStyle(this.values.fill)),r=(l=this.textSpans[t].elem).length,this.globalData.canvasContext.beginPath(),i=0;i<r;i+=1)for(a=(p=l[i]).length,this.globalData.canvasContext.moveTo(p[0],p[1]),s=2;s<a;s+=6)this.globalData.canvasContext.bezierCurveTo(p[s],p[s+1],p[s+2],p[s+3],p[s+4],p[s+5]);this.globalData.canvasContext.closePath(),d.ctxFill()}if(this.stroke){for(n&&n.sw?m!==n.sw&&(m=n.sw,d.ctxLineWidth(n.sw)):m!==this.values.sWidth&&(m=this.values.sWidth,d.ctxLineWidth(this.values.sWidth)),n&&n.sc?c!==n.sc&&(c=n.sc,d.ctxStrokeStyle(n.sc)):c!==this.values.stroke&&(c=this.values.stroke,d.ctxStrokeStyle(this.values.stroke)),r=(l=this.textSpans[t].elem).length,this.globalData.canvasContext.beginPath(),i=0;i<r;i+=1)for(a=(p=l[i]).length,this.globalData.canvasContext.moveTo(p[0],p[1]),s=2;s<a;s+=6)this.globalData.canvasContext.bezierCurveTo(p[s],p[s+1],p[s+2],p[s+3],p[s+4],p[s+5]);this.globalData.canvasContext.closePath(),d.ctxStroke()}n&&this.globalData.renderer.restore()}},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVImageElement),CVImageElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVImageElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVImageElement.prototype.createContent=function(){if(this.img.width&&(this.assetData.w!==this.img.width||this.assetData.h!==this.img.height)){var t=createTag("canvas");t.width=this.assetData.w,t.height=this.assetData.h;var e,i,r=t.getContext("2d"),s=this.img.width,a=this.img.height,n=s/a,o=this.assetData.w/this.assetData.h,h=this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio;n>o&&"xMidYMid slice"===h||n<o&&"xMidYMid slice"!==h?e=(i=a)*o:i=(e=s)/o,r.drawImage(this.img,(s-e)/2,(a-i)/2,e,i,0,0,this.assetData.w,this.assetData.h),this.img=t}},CVImageElement.prototype.renderInnerContent=function(){this.canvasContext.drawImage(this.img,0,0)},CVImageElement.prototype.destroy=function(){this.img=null},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVSolidElement),CVSolidElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVSolidElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVSolidElement.prototype.renderInnerContent=function(){this.globalData.renderer.ctxFillStyle(this.data.sc),this.globalData.renderer.ctxFillRect(0,0,this.data.sw,this.data.sh)},extendPrototype([BaseRenderer],CanvasRendererBase),CanvasRendererBase.prototype.createShape=function(t){return new CVShapeElement(t,this.globalData,this)},CanvasRendererBase.prototype.createText=function(t){return new CVTextElement(t,this.globalData,this)},CanvasRendererBase.prototype.createImage=function(t){return new CVImageElement(t,this.globalData,this)},CanvasRendererBase.prototype.createSolid=function(t){return new CVSolidElement(t,this.globalData,this)},CanvasRendererBase.prototype.createNull=SVGRenderer.prototype.createNull,CanvasRendererBase.prototype.ctxTransform=function(t){1===t[0]&&0===t[1]&&0===t[4]&&1===t[5]&&0===t[12]&&0===t[13]||this.canvasContext.transform(t[0],t[1],t[4],t[5],t[12],t[13])},CanvasRendererBase.prototype.ctxOpacity=function(t){this.canvasContext.globalAlpha*=t<0?0:t},CanvasRendererBase.prototype.ctxFillStyle=function(t){this.canvasContext.fillStyle=t},CanvasRendererBase.prototype.ctxStrokeStyle=function(t){this.canvasContext.strokeStyle=t},CanvasRendererBase.prototype.ctxLineWidth=function(t){this.canvasContext.lineWidth=t},CanvasRendererBase.prototype.ctxLineCap=function(t){this.canvasContext.lineCap=t},CanvasRendererBase.prototype.ctxLineJoin=function(t){this.canvasContext.lineJoin=t},CanvasRendererBase.prototype.ctxMiterLimit=function(t){this.canvasContext.miterLimit=t},CanvasRendererBase.prototype.ctxFill=function(t){this.canvasContext.fill(t)},CanvasRendererBase.prototype.ctxFillRect=function(t,e,i,r){this.canvasContext.fillRect(t,e,i,r)},CanvasRendererBase.prototype.ctxStroke=function(){this.canvasContext.stroke()},CanvasRendererBase.prototype.reset=function(){this.renderConfig.clearCanvas?this.contextData.reset():this.canvasContext.restore()},CanvasRendererBase.prototype.save=function(){this.canvasContext.save()},CanvasRendererBase.prototype.restore=function(t){this.renderConfig.clearCanvas?(t&&(this.globalData.blendMode="source-over"),this.contextData.restore(t)):this.canvasContext.restore()},CanvasRendererBase.prototype.configAnimation=function(t){if(this.animationItem.wrapper){this.animationItem.container=createTag("canvas");var e=this.animationItem.container.style;e.width="100%",e.height="100%";var i="0px 0px 0px";e.transformOrigin=i,e.mozTransformOrigin=i,e.webkitTransformOrigin=i,e["-webkit-transform"]=i,e.contentVisibility=this.renderConfig.contentVisibility,this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.animationItem.container.setAttribute("id",this.renderConfig.id)}else this.canvasContext=this.renderConfig.context;this.contextData.setContext(this.canvasContext),this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.setupGlobalData(t,document.body),this.globalData.canvasContext=this.canvasContext,this.globalData.renderer=this,this.globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=createSizedArray(t.layers.length),this.updateContainerSize()},CanvasRendererBase.prototype.updateContainerSize=function(t,e){var i,r,s,a;if(this.reset(),t?(i=t,r=e,this.canvasContext.canvas.width=i,this.canvasContext.canvas.height=r):(this.animationItem.wrapper&&this.animationItem.container?(i=this.animationItem.wrapper.offsetWidth,r=this.animationItem.wrapper.offsetHeight):(i=this.canvasContext.canvas.width,r=this.canvasContext.canvas.height),this.canvasContext.canvas.width=i*this.renderConfig.dpr,this.canvasContext.canvas.height=r*this.renderConfig.dpr),-1!==this.renderConfig.preserveAspectRatio.indexOf("meet")||-1!==this.renderConfig.preserveAspectRatio.indexOf("slice")){var n=this.renderConfig.preserveAspectRatio.split(" "),o=n[1]||"meet",h=n[0]||"xMidYMid",l=h.substr(0,4),p=h.substr(4);s=i/r,(a=this.transformCanvas.w/this.transformCanvas.h)>s&&"meet"===o||a<s&&"slice"===o?(this.transformCanvas.sx=i/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=i/(this.transformCanvas.w/this.renderConfig.dpr)):(this.transformCanvas.sx=r/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.sy=r/(this.transformCanvas.h/this.renderConfig.dpr)),this.transformCanvas.tx="xMid"===l&&(a<s&&"meet"===o||a>s&&"slice"===o)?(i-this.transformCanvas.w*(r/this.transformCanvas.h))/2*this.renderConfig.dpr:"xMax"===l&&(a<s&&"meet"===o||a>s&&"slice"===o)?(i-this.transformCanvas.w*(r/this.transformCanvas.h))*this.renderConfig.dpr:0,this.transformCanvas.ty="YMid"===p&&(a>s&&"meet"===o||a<s&&"slice"===o)?(r-this.transformCanvas.h*(i/this.transformCanvas.w))/2*this.renderConfig.dpr:"YMax"===p&&(a>s&&"meet"===o||a<s&&"slice"===o)?(r-this.transformCanvas.h*(i/this.transformCanvas.w))*this.renderConfig.dpr:0}else"none"===this.renderConfig.preserveAspectRatio?(this.transformCanvas.sx=i/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=r/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.tx=0,this.transformCanvas.ty=0):(this.transformCanvas.sx=this.renderConfig.dpr,this.transformCanvas.sy=this.renderConfig.dpr,this.transformCanvas.tx=0,this.transformCanvas.ty=0);this.transformCanvas.props=[this.transformCanvas.sx,0,0,0,0,this.transformCanvas.sy,0,0,0,0,1,0,this.transformCanvas.tx,this.transformCanvas.ty,0,1],this.ctxTransform(this.transformCanvas.props),this.canvasContext.beginPath(),this.canvasContext.rect(0,0,this.transformCanvas.w,this.transformCanvas.h),this.canvasContext.closePath(),this.canvasContext.clip(),this.renderFrame(this.renderedFrame,!0)},CanvasRendererBase.prototype.destroy=function(){var t;for(this.renderConfig.clearCanvas&&this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),t=(this.layers?this.layers.length:0)-1;t>=0;t-=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.globalData.canvasContext=null,this.animationItem.container=null,this.destroyed=!0},CanvasRendererBase.prototype.renderFrame=function(t,e){if((this.renderedFrame!==t||!0!==this.renderConfig.clearCanvas||e)&&!this.destroyed&&-1!==t){var i;this.renderedFrame=t,this.globalData.frameNum=t-this.animationItem._isFirstFrame,this.globalData.frameId+=1,this.globalData._mdf=!this.renderConfig.clearCanvas||e,this.globalData.projectInterface.currentFrame=t;var r=this.layers.length;for(this.completeLayers||this.checkLayers(t),i=r-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&this.elements[i].prepareFrame(t-this.layers[i].st);if(this.globalData._mdf){for(!0===this.renderConfig.clearCanvas?this.canvasContext.clearRect(0,0,this.transformCanvas.w,this.transformCanvas.h):this.save(),i=r-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&this.elements[i].renderFrame();!0!==this.renderConfig.clearCanvas&&this.restore()}}},CanvasRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){var i=this.createItem(this.layers[t],this,this.globalData);e[t]=i,i.initExpressions()}},CanvasRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},CanvasRendererBase.prototype.hide=function(){this.animationItem.container.style.display="none"},CanvasRendererBase.prototype.show=function(){this.animationItem.container.style.display="block"},CVContextData.prototype.duplicate=function(){var t=2*this._length,e=0;for(e=this._length;e<t;e+=1)this.stack[e]=new CanvasContext;this._length=t},CVContextData.prototype.reset=function(){this.cArrPos=0,this.cTr.reset(),this.stack[this.cArrPos].opacity=1},CVContextData.prototype.restore=function(t){this.cArrPos-=1;var e,i=this.stack[this.cArrPos],r=i.transform,s=this.cTr.props;for(e=0;e<16;e+=1)s[e]=r[e];if(t){this.nativeContext.restore();var a=this.stack[this.cArrPos+1];this.appliedFillStyle=a.fillStyle,this.appliedStrokeStyle=a.strokeStyle,this.appliedLineWidth=a.lineWidth,this.appliedLineCap=a.lineCap,this.appliedLineJoin=a.lineJoin,this.appliedMiterLimit=a.miterLimit}this.nativeContext.setTransform(r[0],r[1],r[4],r[5],r[12],r[13]),(t||-1!==i.opacity&&this.currentOpacity!==i.opacity)&&(this.nativeContext.globalAlpha=i.opacity,this.currentOpacity=i.opacity),this.currentFillStyle=i.fillStyle,this.currentStrokeStyle=i.strokeStyle,this.currentLineWidth=i.lineWidth,this.currentLineCap=i.lineCap,this.currentLineJoin=i.lineJoin,this.currentMiterLimit=i.miterLimit},CVContextData.prototype.save=function(t){t&&this.nativeContext.save();var e=this.cTr.props;this._length<=this.cArrPos&&this.duplicate();var i,r=this.stack[this.cArrPos];for(i=0;i<16;i+=1)r.transform[i]=e[i];this.cArrPos+=1;var s=this.stack[this.cArrPos];s.opacity=r.opacity,s.fillStyle=r.fillStyle,s.strokeStyle=r.strokeStyle,s.lineWidth=r.lineWidth,s.lineCap=r.lineCap,s.lineJoin=r.lineJoin,s.miterLimit=r.miterLimit},CVContextData.prototype.setOpacity=function(t){this.stack[this.cArrPos].opacity=t},CVContextData.prototype.setContext=function(t){this.nativeContext=t},CVContextData.prototype.fillStyle=function(t){this.stack[this.cArrPos].fillStyle!==t&&(this.currentFillStyle=t,this.stack[this.cArrPos].fillStyle=t)},CVContextData.prototype.strokeStyle=function(t){this.stack[this.cArrPos].strokeStyle!==t&&(this.currentStrokeStyle=t,this.stack[this.cArrPos].strokeStyle=t)},CVContextData.prototype.lineWidth=function(t){this.stack[this.cArrPos].lineWidth!==t&&(this.currentLineWidth=t,this.stack[this.cArrPos].lineWidth=t)},CVContextData.prototype.lineCap=function(t){this.stack[this.cArrPos].lineCap!==t&&(this.currentLineCap=t,this.stack[this.cArrPos].lineCap=t)},CVContextData.prototype.lineJoin=function(t){this.stack[this.cArrPos].lineJoin!==t&&(this.currentLineJoin=t,this.stack[this.cArrPos].lineJoin=t)},CVContextData.prototype.miterLimit=function(t){this.stack[this.cArrPos].miterLimit!==t&&(this.currentMiterLimit=t,this.stack[this.cArrPos].miterLimit=t)},CVContextData.prototype.transform=function(t){this.transformMat.cloneFromProps(t);var e=this.cTr;this.transformMat.multiply(e),e.cloneFromProps(this.transformMat.props);var i=e.props;this.nativeContext.setTransform(i[0],i[1],i[4],i[5],i[12],i[13])},CVContextData.prototype.opacity=function(t){var e=this.stack[this.cArrPos].opacity;e*=t<0?0:t,this.stack[this.cArrPos].opacity!==e&&(this.currentOpacity!==t&&(this.nativeContext.globalAlpha=t,this.currentOpacity=t),this.stack[this.cArrPos].opacity=e)},CVContextData.prototype.fill=function(t){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fill(t)},CVContextData.prototype.fillRect=function(t,e,i,r){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fillRect(t,e,i,r)},CVContextData.prototype.stroke=function(){this.appliedStrokeStyle!==this.currentStrokeStyle&&(this.appliedStrokeStyle=this.currentStrokeStyle,this.nativeContext.strokeStyle=this.appliedStrokeStyle),this.appliedLineWidth!==this.currentLineWidth&&(this.appliedLineWidth=this.currentLineWidth,this.nativeContext.lineWidth=this.appliedLineWidth),this.appliedLineCap!==this.currentLineCap&&(this.appliedLineCap=this.currentLineCap,this.nativeContext.lineCap=this.appliedLineCap),this.appliedLineJoin!==this.currentLineJoin&&(this.appliedLineJoin=this.currentLineJoin,this.nativeContext.lineJoin=this.appliedLineJoin),this.appliedMiterLimit!==this.currentMiterLimit&&(this.appliedMiterLimit=this.currentMiterLimit,this.nativeContext.miterLimit=this.appliedMiterLimit),this.nativeContext.stroke()},extendPrototype([CanvasRendererBase,ICompElement,CVBaseElement],CVCompElement),CVCompElement.prototype.renderInnerContent=function(){var t,e=this.canvasContext;for(e.beginPath(),e.moveTo(0,0),e.lineTo(this.data.w,0),e.lineTo(this.data.w,this.data.h),e.lineTo(0,this.data.h),e.lineTo(0,0),e.clip(),t=this.layers.length-1;t>=0;t-=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},CVCompElement.prototype.destroy=function(){var t;for(t=this.layers.length-1;t>=0;t-=1)this.elements[t]&&this.elements[t].destroy();this.layers=null,this.elements=null},CVCompElement.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},extendPrototype([CanvasRendererBase],CanvasRenderer),CanvasRenderer.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},registerRenderer("canvas",CanvasRenderer),ShapeModifiers.registerModifier("tm",TrimModifier),ShapeModifiers.registerModifier("pb",PuckerAndBloatModifier),ShapeModifiers.registerModifier("rp",RepeaterModifier),ShapeModifiers.registerModifier("rd",RoundCornersModifier),ShapeModifiers.registerModifier("zz",ZigZagModifier),ShapeModifiers.registerModifier("op",OffsetPathModifier);var CompExpressionInterface=function(t){function e(e){for(var i=0,r=t.layers.length;i<r;){if(t.layers[i].nm===e||t.layers[i].ind===e)return t.elements[i].layerInterface;i+=1}return null}return Object.defineProperty(e,"_name",{value:t.data.nm}),e.layer=e,e.pixelAspect=1,e.height=t.data.h||t.globalData.compSize.h,e.width=t.data.w||t.globalData.compSize.w,e.pixelAspect=1,e.frameDuration=1/t.globalData.frameRate,e.displayStartTime=0,e.numLayers=t.layers.length,e};function _typeof$2(t){return _typeof$2="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$2(t)}function seedRandom(t,e){var i,r=this,s=256,a="random",n=e.pow(s,6),o=e.pow(2,52),h=2*o,l=255;function p(t){var e,i=t.length,r=this,a=0,n=r.i=r.j=0,o=r.S=[];for(i||(t=[i++]);a<s;)o[a]=a++;for(a=0;a<s;a++)o[a]=o[n=l&n+t[a%i]+(e=o[a])],o[n]=e;r.g=function(t){for(var e,i=0,a=r.i,n=r.j,o=r.S;t--;)e=o[a=l&a+1],i=i*s+o[l&(o[a]=o[n=l&n+e])+(o[n]=e)];return r.i=a,r.j=n,i}}function f(t,e){return e.i=t.i,e.j=t.j,e.S=t.S.slice(),e}function c(t,e){var i,r=[],s=_typeof$2(t);if(e&&"object"==s)for(i in t)try{r.push(c(t[i],e-1))}catch(t){}return r.length?r:"string"==s?t:t+"\0"}function m(t,e){for(var i,r=t+"",s=0;s<r.length;)e[l&s]=l&(i^=19*e[l&s])+r.charCodeAt(s++);return d(e)}function d(t){return String.fromCharCode.apply(0,t)}e["seed"+a]=function(l,u,y){var g=[],v=m(c((u=!0===u?{entropy:!0}:u||{}).entropy?[l,d(t)]:null===l?function(){try{i;var e=new Uint8Array(s);return(r.crypto||r.msCrypto).getRandomValues(e),d(e)}catch(e){var a=r.navigator,n=a&&a.plugins;return[+new Date,r,n,r.screen,d(t)]}}():l,3),g),P=new p(g),b=function(){for(var t=P.g(6),e=n,i=0;t<o;)t=(t+i)*s,e*=s,i=P.g(1);for(;t>=h;)t/=2,e/=2,i>>>=1;return(t+i)/e};return b.int32=function(){return 0|P.g(4)},b.quick=function(){return P.g(4)/4294967296},b.double=b,m(d(P.S),t),(u.pass||y||function(t,i,r,s){return s&&(s.S&&f(s,P),t.state=function(){return f(P,{})}),r?(e[a]=t,i):t})(b,v,"global"in u?u.global:this==e,u.state)},m(e.random(),t)}function initialize$2(t){seedRandom([],t)}var propTypes={SHAPE:"shape"};function _typeof$1(t){return _typeof$1="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$1(t)}var ExpressionManager=function(){var ob={},Math=BMMath,window=null,document=null,XMLHttpRequest=null,fetch=null,frames=null,_lottieGlobal={};function resetFrame(){_lottieGlobal={}}function $bm_isInstanceOfArray(t){return t.constructor===Array||t.constructor===Float32Array}function isNumerable(t,e){return"number"===t||e instanceof Number||"boolean"===t||"string"===t}function $bm_neg(t){var e=_typeof$1(t);if("number"===e||t instanceof Number||"boolean"===e)return-t;if($bm_isInstanceOfArray(t)){var i,r=t.length,s=[];for(i=0;i<r;i+=1)s[i]=-t[i];return s}return t.propType?t.v:-t}initialize$2(BMMath);var easeInBez=BezierFactory.getBezierEasing(.333,0,.833,.833,"easeIn").get,easeOutBez=BezierFactory.getBezierEasing(.167,.167,.667,1,"easeOut").get,easeInOutBez=BezierFactory.getBezierEasing(.33,0,.667,1,"easeInOut").get;function sum(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e)||"string"===i||"string"===r)return t+e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]+=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t+e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]+e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}var add=sum;function sub(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e))return"string"===i&&(t=parseInt(t,10)),"string"===r&&(e=parseInt(e,10)),t-e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]-=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t-e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]-e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}function mul(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t*e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]*e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t*e[r];return i}return 0}function div(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t/e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]/e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t/e[r];return i}return 0}function mod(t,e){return"string"==typeof t&&(t=parseInt(t,10)),"string"==typeof e&&(e=parseInt(e,10)),t%e}var $bm_sum=sum,$bm_sub=sub,$bm_mul=mul,$bm_div=div,$bm_mod=mod;function clamp(t,e,i){if(e>i){var r=i;i=e,e=r}return Math.min(Math.max(t,e),i)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return e=e||0,Math.abs(t-e);var i;e||(e=helperLengthArray);var r=Math.min(t.length,e.length),s=0;for(i=0;i<r;i+=1)s+=Math.pow(e[i]-t[i],2);return Math.sqrt(s)}function normalize(t){return div(t,length(t))}function rgbToHsl(t){var e,i,r=t[0],s=t[1],a=t[2],n=Math.max(r,s,a),o=Math.min(r,s,a),h=(n+o)/2;if(n===o)e=0,i=0;else{var l=n-o;switch(i=h>.5?l/(2-n-o):l/(n+o),n){case r:e=(s-a)/l+(s<a?6:0);break;case s:e=(a-r)/l+2;break;case a:e=(r-s)/l+4}e/=6}return[e,i,h,t[3]]}function hue2rgb(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}function hslToRgb(t){var e,i,r,s=t[0],a=t[1],n=t[2];if(0===a)e=n,r=n,i=n;else{var o=n<.5?n*(1+a):n+a-n*a,h=2*n-o;e=hue2rgb(h,o,s+1/3),i=hue2rgb(h,o,s),r=hue2rgb(h,o,s-1/3)}return[e,i,r,t[3]]}function linear(t,e,i,r,s){if(void 0!==r&&void 0!==s||(r=e,s=i,e=0,i=1),i<e){var a=i;i=e,e=a}if(t<=e)return r;if(t>=i)return s;var n,o=i===e?0:(t-e)/(i-e);if(!r.length)return r+(s-r)*o;var h=r.length,l=createTypedArray("float32",h);for(n=0;n<h;n+=1)l[n]=r[n]+(s[n]-r[n])*o;return l}function random(t,e){if(void 0===e&&(void 0===t?(t=0,e=1):(e=t,t=void 0)),e.length){var i,r=e.length;t||(t=createTypedArray("float32",r));var s=createTypedArray("float32",r),a=BMMath.random();for(i=0;i<r;i+=1)s[i]=t[i]+a*(e[i]-t[i]);return s}return void 0===t&&(t=0),t+BMMath.random()*(e-t)}function createPath(t,e,i,r){var s,a=t.length,n=shapePool.newElement();n.setPathData(!!r,a);var o,h,l=[0,0];for(s=0;s<a;s+=1)o=e&&e[s]?e[s]:l,h=i&&i[s]?i[s]:l,n.setTripleAt(t[s][0],t[s][1],h[0]+t[s][0],h[1]+t[s][1],o[0]+t[s][0],o[1]+t[s][1],s,!0);return n}function initiateExpression(elem,data,property){function noOp(t){return t}if(!elem.globalData.renderConfig.runExpressions)return noOp;var val=data.x,needsVelocity=/velocity(?![\w\d])/.test(val),_needsRandom=-1!==val.indexOf("random"),elemType=elem.data.ty,transform,$bm_transform,content,effect,thisProperty=property;thisProperty._name=elem.data.nm,thisProperty.valueAtTime=thisProperty.getValueAtTime,Object.defineProperty(thisProperty,"value",{get:function(){return thisProperty.v}}),elem.comp.frameDuration=1/elem.comp.globalData.frameRate,elem.comp.displayStartTime=0;var inPoint=elem.data.ip/elem.comp.globalData.frameRate,outPoint=elem.data.op/elem.comp.globalData.frameRate,width=elem.data.sw?elem.data.sw:0,height=elem.data.sh?elem.data.sh:0,name=elem.data.nm,loopIn,loop_in,loopOut,loop_out,smooth,toWorld,fromWorld,fromComp,toComp,fromCompToSurface,position,rotation,anchorPoint,scale,thisLayer,thisComp,mask,valueAtTime,velocityAtTime,scoped_bm_rt,expression_function=eval("[function _expression_function(){"+val+";scoped_bm_rt=$bm_rt}]")[0],numKeys=property.kf?data.k.length:0,active=!this.data||!0!==this.data.hd,wiggle=function(t,e){var i,r,s=this.pv.length?this.pv.length:1,a=createTypedArray("float32",s);var n=Math.floor(5*time);for(i=0,r=0;i<n;){for(r=0;r<s;r+=1)a[r]+=-e+2*e*BMMath.random();i+=1}var o=5*time,h=o-Math.floor(o),l=createTypedArray("float32",s);if(s>1){for(r=0;r<s;r+=1)l[r]=this.pv[r]+a[r]+(-e+2*e*BMMath.random())*h;return l}return this.pv+a[0]+(-e+2*e*BMMath.random())*h}.bind(this);function loopInDuration(t,e){return loopIn(t,e,!0)}function loopOutDuration(t,e){return loopOut(t,e,!0)}thisProperty.loopIn&&(loopIn=thisProperty.loopIn.bind(thisProperty),loop_in=loopIn),thisProperty.loopOut&&(loopOut=thisProperty.loopOut.bind(thisProperty),loop_out=loopOut),thisProperty.smooth&&(smooth=thisProperty.smooth.bind(thisProperty)),this.getValueAtTime&&(valueAtTime=this.getValueAtTime.bind(this)),this.getVelocityAtTime&&(velocityAtTime=this.getVelocityAtTime.bind(this));var comp=elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface),time,velocity,value,text,textIndex,textTotal,selectorValue;function lookAt(t,e){var i=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],r=Math.atan2(i[0],Math.sqrt(i[1]*i[1]+i[2]*i[2]))/degToRads;return[-Math.atan2(i[1],i[2])/degToRads,r,0]}function easeOut(t,e,i,r,s){return applyEase(easeOutBez,t,e,i,r,s)}function easeIn(t,e,i,r,s){return applyEase(easeInBez,t,e,i,r,s)}function ease(t,e,i,r,s){return applyEase(easeInOutBez,t,e,i,r,s)}function applyEase(t,e,i,r,s,a){void 0===s?(s=i,a=r):e=(e-i)/(r-i),e>1?e=1:e<0&&(e=0);var n=t(e);if($bm_isInstanceOfArray(s)){var o,h=s.length,l=createTypedArray("float32",h);for(o=0;o<h;o+=1)l[o]=(a[o]-s[o])*n+s[o];return l}return(a-s)*n+s}function nearestKey(t){var e,i,r,s=data.k.length;if(data.k.length&&"number"!=typeof data.k[0])if(i=-1,(t*=elem.comp.globalData.frameRate)<data.k[0].t)i=1,r=data.k[0].t;else{for(e=0;e<s-1;e+=1){if(t===data.k[e].t){i=e+1,r=data.k[e].t;break}if(t>data.k[e].t&&t<data.k[e+1].t){t-data.k[e].t>data.k[e+1].t-t?(i=e+2,r=data.k[e+1].t):(i=e+1,r=data.k[e].t);break}}-1===i&&(i=e+1,r=data.k[e].t)}else i=0,r=0;var a={};return a.index=i,a.time=r/elem.comp.globalData.frameRate,a}function key(t){var e,i,r;if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]};var s=Object.prototype.hasOwnProperty.call(data.k[t],"s")?data.k[t].s:data.k[t-1].e;for(r=s.length,i=0;i<r;i+=1)e[i]=s[i],e.value[i]=s[i];return e}function framesToTime(t,e){return e||(e=elem.comp.globalData.frameRate),t/e}function timeToFrames(t,e){return t||0===t||(t=time),e||(e=elem.comp.globalData.frameRate),t*e}function seedRandom(t){BMMath.seedrandom(randSeed+t)}function sourceRectAtTime(){return elem.sourceRectAtTime()}function substring(t,e){return"string"==typeof value?void 0===e?value.substring(t):value.substring(t,e):""}function substr(t,e){return"string"==typeof value?void 0===e?value.substr(t):value.substr(t,e):""}function posterizeTime(t){time=0===t?0:Math.floor(time*t)/t,value=valueAtTime(time)}var index=elem.data.ind,hasParent=!(!elem.hierarchy||!elem.hierarchy.length),parent,randSeed=Math.floor(1e6*Math.random()),globalData=elem.globalData;function executeExpression(t){return value=t,this.frameExpressionId===elem.globalData.frameId&&"textSelector"!==this.propType?value:("textSelector"===this.propType&&(textIndex=this.textIndex,textTotal=this.textTotal,selectorValue=this.selectorValue),thisLayer||(text=elem.layerInterface.text,thisLayer=elem.layerInterface,thisComp=elem.comp.compInterface,toWorld=thisLayer.toWorld.bind(thisLayer),fromWorld=thisLayer.fromWorld.bind(thisLayer),fromComp=thisLayer.fromComp.bind(thisLayer),toComp=thisLayer.toComp.bind(thisLayer),mask=thisLayer.mask?thisLayer.mask.bind(thisLayer):null,fromCompToSurface=fromComp),transform||(transform=elem.layerInterface("ADBE Transform Group"),$bm_transform=transform,transform&&(anchorPoint=transform.anchorPoint)),4!==elemType||content||(content=thisLayer("ADBE Root Vectors Group")),effect||(effect=thisLayer(4)),(hasParent=!(!elem.hierarchy||!elem.hierarchy.length))&&!parent&&(parent=elem.hierarchy[0].layerInterface),time=this.comp.renderedFrame/this.comp.globalData.frameRate,_needsRandom&&seedRandom(randSeed+time),needsVelocity&&(velocity=velocityAtTime(time)),expression_function(),this.frameExpressionId=elem.globalData.frameId,scoped_bm_rt=scoped_bm_rt.propType===propTypes.SHAPE?scoped_bm_rt.v:scoped_bm_rt)}return executeExpression.__preventDeadCodeRemoval=[$bm_transform,anchorPoint,time,velocity,inPoint,outPoint,width,height,name,loop_in,loop_out,smooth,toComp,fromCompToSurface,toWorld,fromWorld,mask,position,rotation,scale,thisComp,numKeys,active,wiggle,loopInDuration,loopOutDuration,comp,lookAt,easeOut,easeIn,ease,nearestKey,key,text,textIndex,textTotal,selectorValue,framesToTime,timeToFrames,sourceRectAtTime,substring,substr,posterizeTime,index,globalData],executeExpression}return ob.initiateExpression=initiateExpression,ob.__preventDeadCodeRemoval=[window,document,XMLHttpRequest,fetch,frames,$bm_neg,add,$bm_sum,$bm_sub,$bm_mul,$bm_div,$bm_mod,clamp,radians_to_degrees,degreesToRadians,degrees_to_radians,normalize,rgbToHsl,hslToRgb,linear,random,createPath,_lottieGlobal],ob.resetFrame=resetFrame,ob}(),Expressions=function(){var t={};return t.initExpressions=function(t){var e=0,i=[];t.renderer.compInterface=CompExpressionInterface(t.renderer),t.renderer.globalData.projectInterface.registerComposition(t.renderer),t.renderer.globalData.pushExpression=function(){e+=1},t.renderer.globalData.popExpression=function(){0==(e-=1)&&function(){var t,e=i.length;for(t=0;t<e;t+=1)i[t].release();i.length=0}()},t.renderer.globalData.registerExpressionProperty=function(t){-1===i.indexOf(t)&&i.push(t)}},t.resetFrame=ExpressionManager.resetFrame,t}(),MaskManagerInterface=function(){function t(t,e){this._mask=t,this._data=e}Object.defineProperty(t.prototype,"maskPath",{get:function(){return this._mask.prop.k&&this._mask.prop.getValue(),this._mask.prop}}),Object.defineProperty(t.prototype,"maskOpacity",{get:function(){return this._mask.op.k&&this._mask.op.getValue(),100*this._mask.op.v}});return function(e){var i,r=createSizedArray(e.viewData.length),s=e.viewData.length;for(i=0;i<s;i+=1)r[i]=new t(e.viewData[i],e.masksProperties[i]);return function(t){for(i=0;i<s;){if(e.masksProperties[i].nm===t)return r[i];i+=1}return null}}}(),ExpressionPropertyInterface=function(){var t={pv:0,v:0,mult:1},e={pv:[0,0,0],v:[0,0,0],mult:1};function i(t,e,i){Object.defineProperty(t,"velocity",{get:function(){return e.getVelocityAtTime(e.comp.currentFrame)}}),t.numKeys=e.keyframes?e.keyframes.length:0,t.key=function(r){if(!t.numKeys)return 0;var s="";s="s"in e.keyframes[r-1]?e.keyframes[r-1].s:"e"in e.keyframes[r-2]?e.keyframes[r-2].e:e.keyframes[r-2].s;var a="unidimensional"===i?new Number(s):Object.assign({},s);return a.time=e.keyframes[r-1].t/e.elem.comp.globalData.frameRate,a.value="unidimensional"===i?s[0]:s,a},t.valueAtTime=e.getValueAtTime,t.speedAtTime=e.getSpeedAtTime,t.velocityAtTime=e.getVelocityAtTime,t.propertyGroup=e.propertyGroup}function r(){return t}return function(s){return s?"unidimensional"===s.propType?function(e){e&&"pv"in e||(e=t);var r=1/e.mult,s=e.pv*r,a=new Number(s);return a.value=s,i(a,e,"unidimensional"),function(){return e.k&&e.getValue(),s=e.v*r,a.value!==s&&((a=new Number(s)).value=s,a[0]=s,i(a,e,"unidimensional")),a}}(s):function(t){t&&"pv"in t||(t=e);var r=1/t.mult,s=t.data&&t.data.l||t.pv.length,a=createTypedArray("float32",s),n=createTypedArray("float32",s);return a.value=n,i(a,t,"multidimensional"),function(){t.k&&t.getValue();for(var e=0;e<s;e+=1)n[e]=t.v[e]*r,a[e]=n[e];return a}}(s):r}}(),TransformExpressionInterface=function(t){function e(t){switch(t){case"scale":case"Scale":case"ADBE Scale":case 6:return e.scale;case"rotation":case"Rotation":case"ADBE Rotation":case"ADBE Rotate Z":case 10:return e.rotation;case"ADBE Rotate X":return e.xRotation;case"ADBE Rotate Y":return e.yRotation;case"position":case"Position":case"ADBE Position":case 2:return e.position;case"ADBE Position_0":return e.xPosition;case"ADBE Position_1":return e.yPosition;case"ADBE Position_2":return e.zPosition;case"anchorPoint":case"AnchorPoint":case"Anchor Point":case"ADBE AnchorPoint":case 1:return e.anchorPoint;case"opacity":case"Opacity":case 11:return e.opacity;default:return null}}var i,r,s,a;return Object.defineProperty(e,"rotation",{get:ExpressionPropertyInterface(t.r||t.rz)}),Object.defineProperty(e,"zRotation",{get:ExpressionPropertyInterface(t.rz||t.r)}),Object.defineProperty(e,"xRotation",{get:ExpressionPropertyInterface(t.rx)}),Object.defineProperty(e,"yRotation",{get:ExpressionPropertyInterface(t.ry)}),Object.defineProperty(e,"scale",{get:ExpressionPropertyInterface(t.s)}),t.p?a=ExpressionPropertyInterface(t.p):(i=ExpressionPropertyInterface(t.px),r=ExpressionPropertyInterface(t.py),t.pz&&(s=ExpressionPropertyInterface(t.pz))),Object.defineProperty(e,"position",{get:function(){return t.p?a():[i(),r(),s?s():0]}}),Object.defineProperty(e,"xPosition",{get:ExpressionPropertyInterface(t.px)}),Object.defineProperty(e,"yPosition",{get:ExpressionPropertyInterface(t.py)}),Object.defineProperty(e,"zPosition",{get:ExpressionPropertyInterface(t.pz)}),Object.defineProperty(e,"anchorPoint",{get:ExpressionPropertyInterface(t.a)}),Object.defineProperty(e,"opacity",{get:ExpressionPropertyInterface(t.o)}),Object.defineProperty(e,"skew",{get:ExpressionPropertyInterface(t.sk)}),Object.defineProperty(e,"skewAxis",{get:ExpressionPropertyInterface(t.sa)}),Object.defineProperty(e,"orientation",{get:ExpressionPropertyInterface(t.or)}),e},LayerExpressionInterface=function(){function t(t){var e=new Matrix;void 0!==t?this._elem.finalTransform.mProp.getValueAtTime(t).clone(e):this._elem.finalTransform.mProp.applyToMatrix(e);return e}function e(t,e){var i=this.getMatrix(e);return i.props[12]=0,i.props[13]=0,i.props[14]=0,this.applyPoint(i,t)}function i(t,e){var i=this.getMatrix(e);return this.applyPoint(i,t)}function r(t,e){var i=this.getMatrix(e);return i.props[12]=0,i.props[13]=0,i.props[14]=0,this.invertPoint(i,t)}function s(t,e){var i=this.getMatrix(e);return this.invertPoint(i,t)}function a(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(t)}return t.applyToPointArray(e[0],e[1],e[2]||0)}function n(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(t)}return t.inversePoint(e)}function o(t){var e=new Matrix;if(e.reset(),this._elem.finalTransform.mProp.applyToMatrix(e),this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(e);return e.inversePoint(t)}return e.inversePoint(t)}function h(){return[1,1,1,1]}return function(l){var p;function f(t){switch(t){case"ADBE Root Vectors Group":case"Contents":case 2:return f.shapeInterface;case 1:case 6:case"Transform":case"transform":case"ADBE Transform Group":return p;case 4:case"ADBE Effect Parade":case"effects":case"Effects":return f.effect;case"ADBE Text Properties":return f.textInterface;default:return null}}f.getMatrix=t,f.invertPoint=n,f.applyPoint=a,f.toWorld=i,f.toWorldVec=e,f.fromWorld=s,f.fromWorldVec=r,f.toComp=i,f.fromComp=o,f.sampleImage=h,f.sourceRectAtTime=l.sourceRectAtTime.bind(l),f._elem=l;var c=getDescriptor(p=TransformExpressionInterface(l.finalTransform.mProp),"anchorPoint");return Object.defineProperties(f,{hasParent:{get:function(){return l.hierarchy.length}},parent:{get:function(){return l.hierarchy[0].layerInterface}},rotation:getDescriptor(p,"rotation"),scale:getDescriptor(p,"scale"),position:getDescriptor(p,"position"),opacity:getDescriptor(p,"opacity"),anchorPoint:c,anchor_point:c,transform:{get:function(){return p}},active:{get:function(){return l.isInRange}}}),f.startTime=l.data.st,f.index=l.data.ind,f.source=l.data.refId,f.height=0===l.data.ty?l.data.h:100,f.width=0===l.data.ty?l.data.w:100,f.inPoint=l.data.ip/l.comp.globalData.frameRate,f.outPoint=l.data.op/l.comp.globalData.frameRate,f._name=l.data.nm,f.registerMaskInterface=function(t){f.mask=new MaskManagerInterface(t,l)},f.registerEffectsInterface=function(t){f.effect=t},f}}(),propertyGroupFactory=function(t,e){return function(i){return(i=void 0===i?1:i)<=0?t:e(i-1)}},PropertyInterface=function(t,e){var i={_name:t};return function(t){return(t=void 0===t?1:t)<=0?i:e(t-1)}},EffectsExpressionInterface=function(){function t(i,r,s,a){function n(t){for(var e=i.ef,r=0,s=e.length;r<s;){if(t===e[r].nm||t===e[r].mn||t===e[r].ix)return 5===e[r].ty?l[r]:l[r]();r+=1}throw new Error}var o,h=propertyGroupFactory(n,s),l=[],p=i.ef.length;for(o=0;o<p;o+=1)5===i.ef[o].ty?l.push(t(i.ef[o],r.effectElements[o],r.effectElements[o].propertyGroup,a)):l.push(e(r.effectElements[o],i.ef[o].ty,a,h));return"ADBE Color Control"===i.mn&&Object.defineProperty(n,"color",{get:function(){return l[0]()}}),Object.defineProperties(n,{numProperties:{get:function(){return i.np}},_name:{value:i.nm},propertyGroup:{value:h}}),n.enabled=0!==i.en,n.active=n.enabled,n}function e(t,e,i,r){var s=ExpressionPropertyInterface(t.p);return t.p.setGroupProperty&&t.p.setGroupProperty(PropertyInterface("",r)),function(){return 10===e?i.comp.compInterface(t.p.v):s()}}return{createEffectsInterface:function(e,i){if(e.effectsManager){var r,s=[],a=e.data.ef,n=e.effectsManager.effectElements.length;for(r=0;r<n;r+=1)s.push(t(a[r],e.effectsManager.effectElements[r],i,e));var o=e.data.ef||[],h=function(t){for(r=0,n=o.length;r<n;){if(t===o[r].nm||t===o[r].mn||t===o[r].ix)return s[r];r+=1}return null};return Object.defineProperty(h,"numProperties",{get:function(){return o.length}}),h}return null}}}(),ShapePathInterface=function(t,e,i){var r=e.sh;function s(t){return"Shape"===t||"shape"===t||"Path"===t||"path"===t||"ADBE Vector Shape"===t||2===t?s.path:null}var a=propertyGroupFactory(s,i);return r.setGroupProperty(PropertyInterface("Path",a)),Object.defineProperties(s,{path:{get:function(){return r.k&&r.getValue(),r}},shape:{get:function(){return r.k&&r.getValue(),r}},_name:{value:t.nm},ix:{value:t.ix},propertyIndex:{value:t.ix},mn:{value:t.mn},propertyGroup:{value:i}}),s},ShapeExpressionInterface=function(){function t(t,o,m){var d,u=[],y=t?t.length:0;for(d=0;d<y;d+=1)"gr"===t[d].ty?u.push(e(t[d],o[d],m)):"fl"===t[d].ty?u.push(i(t[d],o[d],m)):"st"===t[d].ty?u.push(a(t[d],o[d],m)):"tm"===t[d].ty?u.push(n(t[d],o[d],m)):"tr"===t[d].ty||("el"===t[d].ty?u.push(h(t[d],o[d],m)):"sr"===t[d].ty?u.push(l(t[d],o[d],m)):"sh"===t[d].ty?u.push(ShapePathInterface(t[d],o[d],m)):"rc"===t[d].ty?u.push(p(t[d],o[d],m)):"rd"===t[d].ty?u.push(f(t[d],o[d],m)):"rp"===t[d].ty?u.push(c(t[d],o[d],m)):"gf"===t[d].ty?u.push(r(t[d],o[d],m)):u.push(s(t[d],o[d])));return u}function e(e,i,r){var s=function(t){switch(t){case"ADBE Vectors Group":case"Contents":case 2:return s.content;default:return s.transform}};s.propertyGroup=propertyGroupFactory(s,r);var a=function(e,i,r){var s,a=function(t){for(var e=0,i=s.length;e<i;){if(s[e]._name===t||s[e].mn===t||s[e].propertyIndex===t||s[e].ix===t||s[e].ind===t)return s[e];e+=1}return"number"==typeof t?s[t-1]:null};a.propertyGroup=propertyGroupFactory(a,r),s=t(e.it,i.it,a.propertyGroup),a.numProperties=s.length;var n=o(e.it[e.it.length-1],i.it[i.it.length-1],a.propertyGroup);return a.transform=n,a.propertyIndex=e.cix,a._name=e.nm,a}(e,i,s.propertyGroup),n=o(e.it[e.it.length-1],i.it[i.it.length-1],s.propertyGroup);return s.content=a,s.transform=n,Object.defineProperty(s,"_name",{get:function(){return e.nm}}),s.numProperties=e.np,s.propertyIndex=e.ix,s.nm=e.nm,s.mn=e.mn,s}function i(t,e,i){function r(t){return"Color"===t||"color"===t?r.color:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r}function r(t,e,i){function r(t){return"Start Point"===t||"start point"===t?r.startPoint:"End Point"===t||"end point"===t?r.endPoint:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{startPoint:{get:ExpressionPropertyInterface(e.s)},endPoint:{get:ExpressionPropertyInterface(e.e)},opacity:{get:ExpressionPropertyInterface(e.o)},type:{get:function(){return"a"}},_name:{value:t.nm},mn:{value:t.mn}}),e.s.setGroupProperty(PropertyInterface("Start Point",i)),e.e.setGroupProperty(PropertyInterface("End Point",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r}function s(){return function(){return null}}function a(t,e,i){var r,s=propertyGroupFactory(l,i),a=propertyGroupFactory(h,s);function n(i){Object.defineProperty(h,t.d[i].nm,{get:ExpressionPropertyInterface(e.d.dataProps[i].p)})}var o=t.d?t.d.length:0,h={};for(r=0;r<o;r+=1)n(r),e.d.dataProps[r].p.setGroupProperty(a);function l(t){return"Color"===t||"color"===t?l.color:"Opacity"===t||"opacity"===t?l.opacity:"Stroke Width"===t||"stroke width"===t?l.strokeWidth:null}return Object.defineProperties(l,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},strokeWidth:{get:ExpressionPropertyInterface(e.w)},dash:{get:function(){return h}},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",s)),e.o.setGroupProperty(PropertyInterface("Opacity",s)),e.w.setGroupProperty(PropertyInterface("Stroke Width",s)),l}function n(t,e,i){function r(e){return e===t.e.ix||"End"===e||"end"===e?r.end:e===t.s.ix?r.start:e===t.o.ix?r.offset:null}var s=propertyGroupFactory(r,i);return r.propertyIndex=t.ix,e.s.setGroupProperty(PropertyInterface("Start",s)),e.e.setGroupProperty(PropertyInterface("End",s)),e.o.setGroupProperty(PropertyInterface("Offset",s)),r.propertyIndex=t.ix,r.propertyGroup=i,Object.defineProperties(r,{start:{get:ExpressionPropertyInterface(e.s)},end:{get:ExpressionPropertyInterface(e.e)},offset:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm}}),r.mn=t.mn,r}function o(t,e,i){function r(e){return t.a.ix===e||"Anchor Point"===e?r.anchorPoint:t.o.ix===e||"Opacity"===e?r.opacity:t.p.ix===e||"Position"===e?r.position:t.r.ix===e||"Rotation"===e||"ADBE Vector Rotation"===e?r.rotation:t.s.ix===e||"Scale"===e?r.scale:t.sk&&t.sk.ix===e||"Skew"===e?r.skew:t.sa&&t.sa.ix===e||"Skew Axis"===e?r.skewAxis:null}var s=propertyGroupFactory(r,i);return e.transform.mProps.o.setGroupProperty(PropertyInterface("Opacity",s)),e.transform.mProps.p.setGroupProperty(PropertyInterface("Position",s)),e.transform.mProps.a.setGroupProperty(PropertyInterface("Anchor Point",s)),e.transform.mProps.s.setGroupProperty(PropertyInterface("Scale",s)),e.transform.mProps.r.setGroupProperty(PropertyInterface("Rotation",s)),e.transform.mProps.sk&&(e.transform.mProps.sk.setGroupProperty(PropertyInterface("Skew",s)),e.transform.mProps.sa.setGroupProperty(PropertyInterface("Skew Angle",s))),e.transform.op.setGroupProperty(PropertyInterface("Opacity",s)),Object.defineProperties(r,{opacity:{get:ExpressionPropertyInterface(e.transform.mProps.o)},position:{get:ExpressionPropertyInterface(e.transform.mProps.p)},anchorPoint:{get:ExpressionPropertyInterface(e.transform.mProps.a)},scale:{get:ExpressionPropertyInterface(e.transform.mProps.s)},rotation:{get:ExpressionPropertyInterface(e.transform.mProps.r)},skew:{get:ExpressionPropertyInterface(e.transform.mProps.sk)},skewAxis:{get:ExpressionPropertyInterface(e.transform.mProps.sa)},_name:{value:t.nm}}),r.ty="tr",r.mn=t.mn,r.propertyGroup=i,r}function h(t,e,i){function r(e){return t.p.ix===e?r.position:t.s.ix===e?r.size:null}var s=propertyGroupFactory(r,i);r.propertyIndex=t.ix;var a="tm"===e.sh.ty?e.sh.prop:e.sh;return a.s.setGroupProperty(PropertyInterface("Size",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),Object.defineProperties(r,{size:{get:ExpressionPropertyInterface(a.s)},position:{get:ExpressionPropertyInterface(a.p)},_name:{value:t.nm}}),r.mn=t.mn,r}function l(t,e,i){function r(e){return t.p.ix===e?r.position:t.r.ix===e?r.rotation:t.pt.ix===e?r.points:t.or.ix===e||"ADBE Vector Star Outer Radius"===e?r.outerRadius:t.os.ix===e?r.outerRoundness:!t.ir||t.ir.ix!==e&&"ADBE Vector Star Inner Radius"!==e?t.is&&t.is.ix===e?r.innerRoundness:null:r.innerRadius}var s=propertyGroupFactory(r,i),a="tm"===e.sh.ty?e.sh.prop:e.sh;return r.propertyIndex=t.ix,a.or.setGroupProperty(PropertyInterface("Outer Radius",s)),a.os.setGroupProperty(PropertyInterface("Outer Roundness",s)),a.pt.setGroupProperty(PropertyInterface("Points",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),t.ir&&(a.ir.setGroupProperty(PropertyInterface("Inner Radius",s)),a.is.setGroupProperty(PropertyInterface("Inner Roundness",s))),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(a.p)},rotation:{get:ExpressionPropertyInterface(a.r)},points:{get:ExpressionPropertyInterface(a.pt)},outerRadius:{get:ExpressionPropertyInterface(a.or)},outerRoundness:{get:ExpressionPropertyInterface(a.os)},innerRadius:{get:ExpressionPropertyInterface(a.ir)},innerRoundness:{get:ExpressionPropertyInterface(a.is)},_name:{value:t.nm}}),r.mn=t.mn,r}function p(t,e,i){function r(e){return t.p.ix===e?r.position:t.r.ix===e?r.roundness:t.s.ix===e||"Size"===e||"ADBE Vector Rect Size"===e?r.size:null}var s=propertyGroupFactory(r,i),a="tm"===e.sh.ty?e.sh.prop:e.sh;return r.propertyIndex=t.ix,a.p.setGroupProperty(PropertyInterface("Position",s)),a.s.setGroupProperty(PropertyInterface("Size",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(a.p)},roundness:{get:ExpressionPropertyInterface(a.r)},size:{get:ExpressionPropertyInterface(a.s)},_name:{value:t.nm}}),r.mn=t.mn,r}function f(t,e,i){function r(e){return t.r.ix===e||"Round Corners 1"===e?r.radius:null}var s=propertyGroupFactory(r,i),a=e;return r.propertyIndex=t.ix,a.rd.setGroupProperty(PropertyInterface("Radius",s)),Object.defineProperties(r,{radius:{get:ExpressionPropertyInterface(a.rd)},_name:{value:t.nm}}),r.mn=t.mn,r}function c(t,e,i){function r(e){return t.c.ix===e||"Copies"===e?r.copies:t.o.ix===e||"Offset"===e?r.offset:null}var s=propertyGroupFactory(r,i),a=e;return r.propertyIndex=t.ix,a.c.setGroupProperty(PropertyInterface("Copies",s)),a.o.setGroupProperty(PropertyInterface("Offset",s)),Object.defineProperties(r,{copies:{get:ExpressionPropertyInterface(a.c)},offset:{get:ExpressionPropertyInterface(a.o)},_name:{value:t.nm}}),r.mn=t.mn,r}return function(e,i,r){var s;function a(t){if("number"==typeof t)return 0===(t=void 0===t?1:t)?r:s[t-1];for(var e=0,i=s.length;e<i;){if(s[e]._name===t)return s[e];e+=1}return null}return a.propertyGroup=propertyGroupFactory(a,(function(){return r})),s=t(e,i,a.propertyGroup),a.numProperties=s.length,a._name="Contents",a}}(),TextExpressionInterface=function(t){var e;function i(t){return"ADBE Text Document"===t?i.sourceText:null}return Object.defineProperty(i,"sourceText",{get:function(){t.textProperty.getValue();var i=t.textProperty.currentData.t;return e&&i===e.value||((e=new String(i)).value=i||new String(i),Object.defineProperty(e,"style",{get:function(){return{fillColor:t.textProperty.currentData.fc}}})),e}}),i};function _typeof(t){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof(t)}var FootageInterface=(dataInterfaceFactory=function(t){function e(t){return"Outline"===t?e.outlineInterface():null}return e._name="Outline",e.outlineInterface=function(t){var e="",i=t.getFootageData();function r(t){if(i[t])return e=t,"object"===_typeof(i=i[t])?r:i;var s=t.indexOf(e);if(-1!==s){var a=parseInt(t.substr(s+e.length),10);return"object"===_typeof(i=i[a])?r:i}return""}return function(){return e="",i=t.getFootageData(),r}}(t),e},function(t){function e(t){return"Data"===t?e.dataInterface:null}return e._name="Data",e.dataInterface=dataInterfaceFactory(t),e}),dataInterfaceFactory,interfaces={layer:LayerExpressionInterface,effects:EffectsExpressionInterface,comp:CompExpressionInterface,shape:ShapeExpressionInterface,text:TextExpressionInterface,footage:FootageInterface};function getInterface(t){return interfaces[t]||null}var expressionHelpers={searchExpressions:function(t,e,i){e.x&&(i.k=!0,i.x=!0,i.initiateExpression=ExpressionManager.initiateExpression,i.effectsSequence.push(i.initiateExpression(t,e,i).bind(i)))},getSpeedAtTime:function(t){var e=this.getValueAtTime(t),i=this.getValueAtTime(t+-.01),r=0;if(e.length){var s;for(s=0;s<e.length;s+=1)r+=Math.pow(i[s]-e[s],2);r=100*Math.sqrt(r)}else r=0;return r},getVelocityAtTime:function(t){if(void 0!==this.vel)return this.vel;var e,i,r=-.001,s=this.getValueAtTime(t),a=this.getValueAtTime(t+r);if(s.length)for(e=createTypedArray("float32",s.length),i=0;i<s.length;i+=1)e[i]=(a[i]-s[i])/r;else e=(a-s)/r;return e},getValueAtTime:function(t){return t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastFrame&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastFrame<t?this._cachingAtTime.lastIndex:0,this._cachingAtTime.value=this.interpolateValue(t,this._cachingAtTime),this._cachingAtTime.lastFrame=t),this._cachingAtTime.value},getStaticValueAtTime:function(){return this.pv},setGroupProperty:function(t){this.propertyGroup=t}};function addPropertyDecorator(){function t(t,e,i){if(!this.k||!this.keyframes)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[l.length-1].t;if(h<=p)return this.pv;if(i?s=p-(r=e?Math.abs(p-this.elem.comp.globalData.frameRate*e):Math.max(0,p-this.elem.data.ip)):((!e||e>l.length-1)&&(e=l.length-1),r=p-(s=l[l.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/r)%2!=0)return this.getValueAtTime((r-(h-s)%r+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime(p/this.comp.globalData.frameRate,0),m=this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0),d=Math.floor((h-s)/r);if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=(c[a]-f[a])*d+m[a];return o}return(c-f)*d+m}if("continue"===t){var u=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p-.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*((h-p)/this.comp.globalData.frameRate)/5e-4;return o}return u+(h-p)/.001*(u-y)}}return this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0)}function e(t,e,i){if(!this.k)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[0].t;if(h>=p)return this.pv;if(i?s=p+(r=e?Math.abs(this.elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-p)):((!e||e>l.length-1)&&(e=l.length-1),r=(s=l[e].t)-p),"pingpong"===t){if(Math.floor((p-h)/r)%2==0)return this.getValueAtTime(((p-h)%r+p)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(p/this.comp.globalData.frameRate,0),c=this.getValueAtTime(s/this.comp.globalData.frameRate,0),m=this.getValueAtTime((r-(p-h)%r+p)/this.comp.globalData.frameRate,0),d=Math.floor((p-h)/r)+1;if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=m[a]-(c[a]-f[a])*d;return o}return m-(c-f)*d}if("continue"===t){var u=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p+.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*(p-h)/.001;return o}return u+(u-y)*(p-h)/.001}}return this.getValueAtTime((r-((p-h)%r+p))/this.comp.globalData.frameRate,0)}function i(t,e){if(!this.k)return this.pv;if(t=.5*(t||.4),(e=Math.floor(e||5))<=1)return this.pv;var i,r,s=this.comp.renderedFrame/this.comp.globalData.frameRate,a=s-t,n=e>1?(s+t-a)/(e-1):1,o=0,h=0;for(i=this.pv.length?createTypedArray("float32",this.pv.length):0;o<e;){if(r=this.getValueAtTime(a+o*n),this.pv.length)for(h=0;h<this.pv.length;h+=1)i[h]+=r[h];else i+=r;o+=1}if(this.pv.length)for(h=0;h<this.pv.length;h+=1)i[h]/=e;else i/=e;return i}function r(t){this._transformCachingAtTime||(this._transformCachingAtTime={v:new Matrix});var e=this._transformCachingAtTime.v;if(e.cloneFromProps(this.pre.props),this.appliedTransformations<1){var i=this.a.getValueAtTime(t);e.translate(-i[0]*this.a.mult,-i[1]*this.a.mult,i[2]*this.a.mult)}if(this.appliedTransformations<2){var r=this.s.getValueAtTime(t);e.scale(r[0]*this.s.mult,r[1]*this.s.mult,r[2]*this.s.mult)}if(this.sk&&this.appliedTransformations<3){var s=this.sk.getValueAtTime(t),a=this.sa.getValueAtTime(t);e.skewFromAxis(-s*this.sk.mult,a*this.sa.mult)}if(this.r&&this.appliedTransformations<4){var n=this.r.getValueAtTime(t);e.rotate(-n*this.r.mult)}else if(!this.r&&this.appliedTransformations<4){var o=this.rz.getValueAtTime(t),h=this.ry.getValueAtTime(t),l=this.rx.getValueAtTime(t),p=this.or.getValueAtTime(t);e.rotateZ(-o*this.rz.mult).rotateY(h*this.ry.mult).rotateX(l*this.rx.mult).rotateZ(-p[2]*this.or.mult).rotateY(p[1]*this.or.mult).rotateX(p[0]*this.or.mult)}if(this.data.p&&this.data.p.s){var f=this.px.getValueAtTime(t),c=this.py.getValueAtTime(t);if(this.data.p.z){var m=this.pz.getValueAtTime(t);e.translate(f*this.px.mult,c*this.py.mult,-m*this.pz.mult)}else e.translate(f*this.px.mult,c*this.py.mult,0)}else{var d=this.p.getValueAtTime(t);e.translate(d[0]*this.p.mult,d[1]*this.p.mult,-d[2]*this.p.mult)}return e}function s(){return this.v.clone(new Matrix)}var a=TransformPropertyFactory.getTransformProperty;TransformPropertyFactory.getTransformProperty=function(t,e,i){var n=a(t,e,i);return n.dynamicProperties.length?n.getValueAtTime=r.bind(n):n.getValueAtTime=s.bind(n),n.setGroupProperty=expressionHelpers.setGroupProperty,n};var n=PropertyFactory.getProp;PropertyFactory.getProp=function(r,s,a,o,h){var l=n(r,s,a,o,h);l.kf?l.getValueAtTime=expressionHelpers.getValueAtTime.bind(l):l.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(l),l.setGroupProperty=expressionHelpers.setGroupProperty,l.loopOut=t,l.loopIn=e,l.smooth=i,l.getVelocityAtTime=expressionHelpers.getVelocityAtTime.bind(l),l.getSpeedAtTime=expressionHelpers.getSpeedAtTime.bind(l),l.numKeys=1===s.a?s.k.length:0,l.propertyIndex=s.ix;var p=0;return 0!==a&&(p=createTypedArray("float32",1===s.a?s.k[0].s.length:s.k.length)),l._cachingAtTime={lastFrame:initialDefaultFrame,lastIndex:0,value:p},expressionHelpers.searchExpressions(r,s,l),l.k&&h.addDynamicProperty(l),l};var o=ShapePropertyFactory.getConstructorFunction(),h=ShapePropertyFactory.getKeyframedConstructorFunction();function l(){}l.prototype={vertices:function(t,e){this.k&&this.getValue();var i,r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0));var s=r._length,a=r[t],n=r.v,o=createSizedArray(s);for(i=0;i<s;i+=1)o[i]="i"===t||"o"===t?[a[i][0]-n[i][0],a[i][1]-n[i][1]]:[a[i][0],a[i][1]];return o},points:function(t){return this.vertices("v",t)},inTangents:function(t){return this.vertices("i",t)},outTangents:function(t){return this.vertices("o",t)},isClosed:function(){return this.v.c},pointOnPath:function(t,e){var i=this.v;void 0!==e&&(i=this.getValueAtTime(e,0)),this._segmentsLength||(this._segmentsLength=bez.getSegmentsLength(i));for(var r,s=this._segmentsLength,a=s.lengths,n=s.totalLength*t,o=0,h=a.length,l=0;o<h;){if(l+a[o].addedLength>n){var p=o,f=i.c&&o===h-1?0:o+1,c=(n-l)/a[o].addedLength;r=bez.getPointInSegment(i.v[p],i.v[f],i.o[p],i.i[f],c,a[o]);break}l+=a[o].addedLength,o+=1}return r||(r=i.c?[i.v[0][0],i.v[0][1]]:[i.v[i._length-1][0],i.v[i._length-1][1]]),r},vectorOnPath:function(t,e,i){1==t?t=this.v.c:0==t&&(t=.999);var r=this.pointOnPath(t,e),s=this.pointOnPath(t+.001,e),a=s[0]-r[0],n=s[1]-r[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return 0===o?[0,0]:"tangent"===i?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([l],o),extendPrototype([l],h),h.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shapePool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime<t?this._caching.lastIndex:0,this._cachingAtTime.lastTime=t,this.interpolateShape(t,this._cachingAtTime.shapeValue,this._cachingAtTime)),this._cachingAtTime.shapeValue},h.prototype.initiateExpression=ExpressionManager.initiateExpression;var p=ShapePropertyFactory.getShapeProp;ShapePropertyFactory.getShapeProp=function(t,e,i,r,s){var a=p(t,e,i,r,s);return a.propertyIndex=e.ix,a.lock=!1,3===i?expressionHelpers.searchExpressions(t,e.pt,a):4===i&&expressionHelpers.searchExpressions(t,e.ks,a),a.k&&t.addDynamicProperty(a),a}}function initialize$1(){addPropertyDecorator()}function addDecorator(){TextProperty.prototype.getExpressionValue=function(t,e){var i=this.calculateExpression(e);if(t.t!==i){var r={};return this.copyData(r,t),r.t=i.toString(),r.__complete=!1,r}return t},TextProperty.prototype.searchProperty=function(){var t=this.searchKeyframes(),e=this.searchExpressions();return this.kf=t||e,this.kf},TextProperty.prototype.searchExpressions=function(){return this.data.d.x?(this.calculateExpression=ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this),this.addEffect(this.getExpressionValue.bind(this)),!0):null}}function initialize(){addDecorator()}function TransformEffect(){}function CVTransformEffect(t){this.init(t)}return TransformEffect.prototype.init=function(t){this.effectsManager=t,this.type=effectTypes.TRANSFORM_EFFECT,this.matrix=new Matrix,this.opacity=-1,this._mdf=!1,this._opMdf=!1},TransformEffect.prototype.renderFrame=function(t){if(this._opMdf=!1,this._mdf=!1,t||this.effectsManager._mdf){var e=this.effectsManager.effectElements,i=e[0].p.v,r=e[1].p.v,s=1===e[2].p.v,a=e[3].p.v,n=s?a:e[4].p.v,o=e[5].p.v,h=e[6].p.v,l=e[7].p.v;this.matrix.reset(),this.matrix.translate(-i[0],-i[1],i[2]),this.matrix.scale(.01*n,.01*a,1),this.matrix.rotate(-l*degToRads),this.matrix.skewFromAxis(-o*degToRads,(h+90)*degToRads),this.matrix.translate(r[0],r[1],0),this._mdf=!0,this.opacity!==e[8].p.v&&(this.opacity=e[8].p.v,this._opMdf=!0)}},extendPrototype([TransformEffect],CVTransformEffect),setExpressionsPlugin(Expressions),setExpressionInterfaces(getInterface),initialize$1(),initialize(),registerEffect(35,CVTransformEffect),lottie}));
diff --git a/build/player/lottie_canvas_worker.js b/build/player/lottie_canvas_worker.js
index 0b19a37..1311700 100644
--- a/build/player/lottie_canvas_worker.js
+++ b/build/player/lottie_canvas_worker.js
@@ -294,7 +294,7 @@
   var lottieInternal = (function () {
     'use strict';
 
-    (typeof navigator !== "undefined") && (function (global, factory) {
+    (typeof document !== "undefined") && (typeof navigator !== "undefined") && (function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
   typeof define === 'function' && define.amd ? define(factory) :
   (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lottie = factory());
@@ -304,19 +304,15 @@
   var locationHref = '';
   var _useWebWorker = false;
   var initialDefaultFrame = -999999;
-
   var setWebWorker = function setWebWorker(flag) {
     _useWebWorker = !!flag;
   };
-
   var getWebWorker = function getWebWorker() {
     return _useWebWorker;
   };
-
   var setLocationHref = function setLocationHref(value) {
     locationHref = value;
   };
-
   var getLocationHref = function getLocationHref() {
     return locationHref;
   };
@@ -330,28 +326,24 @@
     var i;
     var len = sources.length;
     var sourcePrototype;
-
     for (i = 0; i < len; i += 1) {
       sourcePrototype = sources[i].prototype;
-
       for (var attr in sourcePrototype) {
         if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
       }
     }
   }
-
   function getDescriptor(object, prop) {
     return Object.getOwnPropertyDescriptor(object, prop);
   }
-
   function createProxyFunction(prototype) {
     function ProxyFunction() {}
-
     ProxyFunction.prototype = prototype;
     return ProxyFunction;
   }
 
   // import Howl from '../../3rd_party/howler';
+
   var audioControllerFactory = function () {
     function AudioController(audioFactory) {
       this.audios = [];
@@ -359,7 +351,6 @@
       this._volume = 1;
       this._isMuted = false;
     }
-
     AudioController.prototype = {
       addAudio: function addAudio(audio) {
         this.audios.push(audio);
@@ -367,7 +358,6 @@
       pause: function pause() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].pause();
         }
@@ -375,7 +365,6 @@
       resume: function resume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].resume();
         }
@@ -383,7 +372,6 @@
       setRate: function setRate(rateValue) {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].setRate(rateValue);
         }
@@ -392,13 +380,11 @@
         if (this.audioFactory) {
           return this.audioFactory(assetPath);
         }
-
         if (window.Howl) {
           return new window.Howl({
             src: [assetPath]
           });
         }
-
         return {
           isPlaying: false,
           play: function play() {
@@ -417,17 +403,14 @@
       },
       setVolume: function setVolume(value) {
         this._volume = value;
-
         this._updateVolume();
       },
       mute: function mute() {
         this._isMuted = true;
-
         this._updateVolume();
       },
       unmute: function unmute() {
         this._isMuted = false;
-
         this._updateVolume();
       },
       getVolume: function getVolume() {
@@ -436,7 +419,6 @@
       _updateVolume: function _updateVolume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
         }
@@ -452,55 +434,44 @@
       var i = 0;
       var arr = [];
       var value;
-
       switch (type) {
         case 'int16':
         case 'uint8c':
           value = 1;
           break;
-
         default:
           value = 1.1;
           break;
       }
-
       for (i = 0; i < len; i += 1) {
         arr.push(value);
       }
-
       return arr;
     }
-
     function createTypedArrayFactory(type, len) {
       if (type === 'float32') {
         return new Float32Array(len);
       }
-
       if (type === 'int16') {
         return new Int16Array(len);
       }
-
       if (type === 'uint8c') {
         return new Uint8ClampedArray(len);
       }
-
       return createRegularArray(type, len);
     }
-
     if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
       return createTypedArrayFactory;
     }
-
     return createRegularArray;
   }();
-
   function createSizedArray(len) {
     return Array.apply(null, {
       length: len
     });
   }
 
-  function _typeof$6(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$6 = function _typeof(obj) { return typeof obj; }; } else { _typeof$6 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$6(obj); }
+  function _typeof$6(o) { "@babel/helpers - typeof"; return _typeof$6 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$6(o); }
   var subframeEnabled = true;
   var expressionsPlugin = null;
   var expressionsInterfaces = null;
@@ -513,57 +484,43 @@
   var bmMax = Math.max;
   var bmMin = Math.min;
   var BMMath = {};
-
   (function () {
     var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
     var i;
     var len = propertyNames.length;
-
     for (i = 0; i < len; i += 1) {
       BMMath[propertyNames[i]] = Math[propertyNames[i]];
     }
   })();
-
   function ProjectInterface$1() {
     return {};
   }
-
   BMMath.random = Math.random;
-
   BMMath.abs = function (val) {
     var tOfVal = _typeof$6(val);
-
     if (tOfVal === 'object' && val.length) {
       var absArr = createSizedArray(val.length);
       var i;
       var len = val.length;
-
       for (i = 0; i < len; i += 1) {
         absArr[i] = Math.abs(val[i]);
       }
-
       return absArr;
     }
-
     return Math.abs(val);
   };
-
   var defaultCurveSegments = 150;
   var degToRads = Math.PI / 180;
   var roundCorner = 0.5519;
-
   function roundValues(flag) {
     _shouldRoundValues = !!flag;
   }
-
   function bmRnd(value) {
     if (_shouldRoundValues) {
       return Math.round(value);
     }
-
     return value;
   }
-
   function styleDiv(element) {
     element.style.position = 'absolute';
     element.style.top = 0;
@@ -577,53 +534,44 @@
     element.style.webkitTransformStyle = 'preserve-3d';
     element.style.mozTransformStyle = 'preserve-3d';
   }
-
   function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
     this.type = type;
     this.currentTime = currentTime;
     this.totalTime = totalTime;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteEvent(type, frameMultiplier) {
     this.type = type;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
     this.type = type;
     this.currentLoop = currentLoop;
     this.totalLoops = totalLoops;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMSegmentStartEvent(type, firstFrame, totalFrames) {
     this.type = type;
     this.firstFrame = firstFrame;
     this.totalFrames = totalFrames;
   }
-
   function BMDestroyEvent(type, target) {
     this.type = type;
     this.target = target;
   }
-
   function BMRenderFrameErrorEvent(nativeError, currentTime) {
     this.type = 'renderFrameError';
     this.nativeError = nativeError;
     this.currentTime = currentTime;
   }
-
   function BMConfigErrorEvent(nativeError) {
     this.type = 'configError';
     this.nativeError = nativeError;
   }
-
   function BMAnimationConfigErrorEvent(type, nativeError) {
     this.type = type;
     this.nativeError = nativeError;
   }
-
   var createElementID = function () {
     var _count = 0;
     return function createID() {
@@ -631,7 +579,6 @@
       return idPrefix$1 + '__lottie_element_' + _count;
     };
   }();
-
   function HSVtoRGB(h, s, v) {
     var r;
     var g;
@@ -646,51 +593,42 @@
     p = v * (1 - s);
     q = v * (1 - f * s);
     t = v * (1 - (1 - f) * s);
-
     switch (i % 6) {
       case 0:
         r = v;
         g = t;
         b = p;
         break;
-
       case 1:
         r = q;
         g = v;
         b = p;
         break;
-
       case 2:
         r = p;
         g = v;
         b = t;
         break;
-
       case 3:
         r = p;
         g = q;
         b = v;
         break;
-
       case 4:
         r = t;
         g = p;
         b = v;
         break;
-
       case 5:
         r = v;
         g = p;
         b = q;
         break;
-
       default:
         break;
     }
-
     return [r, g, b];
   }
-
   function RGBtoHSV(r, g, b) {
     var max = Math.max(r, g, b);
     var min = Math.min(r, g, b);
@@ -698,136 +636,105 @@
     var h;
     var s = max === 0 ? 0 : d / max;
     var v = max / 255;
-
     switch (max) {
       case min:
         h = 0;
         break;
-
       case r:
         h = g - b + d * (g < b ? 6 : 0);
         h /= 6 * d;
         break;
-
       case g:
         h = b - r + d * 2;
         h /= 6 * d;
         break;
-
       case b:
         h = r - g + d * 4;
         h /= 6 * d;
         break;
-
       default:
         break;
     }
-
     return [h, s, v];
   }
-
   function addSaturationToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[1] += offset;
-
     if (hsv[1] > 1) {
       hsv[1] = 1;
     } else if (hsv[1] <= 0) {
       hsv[1] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addBrightnessToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[2] += offset;
-
     if (hsv[2] > 1) {
       hsv[2] = 1;
     } else if (hsv[2] < 0) {
       hsv[2] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addHueToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[0] += offset / 360;
-
     if (hsv[0] > 1) {
       hsv[0] -= 1;
     } else if (hsv[0] < 0) {
       hsv[0] += 1;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   var rgbToHex = function () {
     var colorMap = [];
     var i;
     var hex;
-
     for (i = 0; i < 256; i += 1) {
       hex = i.toString(16);
       colorMap[i] = hex.length === 1 ? '0' + hex : hex;
     }
-
     return function (r, g, b) {
       if (r < 0) {
         r = 0;
       }
-
       if (g < 0) {
         g = 0;
       }
-
       if (b < 0) {
         b = 0;
       }
-
       return '#' + colorMap[r] + colorMap[g] + colorMap[b];
     };
   }();
-
   var setSubframeEnabled = function setSubframeEnabled(flag) {
     subframeEnabled = !!flag;
   };
-
   var getSubframeEnabled = function getSubframeEnabled() {
     return subframeEnabled;
   };
-
   var setExpressionsPlugin = function setExpressionsPlugin(value) {
     expressionsPlugin = value;
   };
-
   var getExpressionsPlugin = function getExpressionsPlugin() {
     return expressionsPlugin;
   };
-
   var setExpressionInterfaces = function setExpressionInterfaces(value) {
     expressionsInterfaces = value;
   };
-
   var getExpressionInterfaces = function getExpressionInterfaces() {
     return expressionsInterfaces;
   };
-
   var setDefaultCurveSegments = function setDefaultCurveSegments(value) {
     defaultCurveSegments = value;
   };
-
   var getDefaultCurveSegments = function getDefaultCurveSegments() {
     return defaultCurveSegments;
   };
-
   var setIdPrefix = function setIdPrefix(value) {
     idPrefix$1 = value;
   };
-
   var getIdPrefix = function getIdPrefix() {
     return idPrefix$1;
   };
@@ -837,8 +744,7 @@
     return document.createElementNS(svgNS, type);
   }
 
-  function _typeof$5(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$5 = function _typeof(obj) { return typeof obj; }; } else { _typeof$5 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$5(obj); }
-
+  function _typeof$5(o) { "@babel/helpers - typeof"; return _typeof$5 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$5(o); }
   var dataManager = function () {
     var _counterId = 1;
     var processes = [];
@@ -859,21 +765,18 @@
         });
       }
     };
-
     function createWorker(fn) {
       if (window.Worker && window.Blob && getWebWorker()) {
         var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], {
           type: 'text/javascript'
-        }); // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
-
+        });
+        // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
         var url = URL.createObjectURL(blob);
         return new Worker(url);
       }
-
       workerFn = fn;
       return workerProxy;
     }
-
     function setupWorker() {
       if (!workerInstance) {
         workerInstance = createWorker(function workerStart(e) {
@@ -886,28 +789,22 @@
               var jLen;
               var k;
               var kLen;
-
               for (i = 0; i < len; i += 1) {
                 layerData = layers[i];
-
                 if ('ks' in layerData && !layerData.completed) {
                   layerData.completed = true;
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         convertPathsToAbsoluteValues(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) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
                           }
@@ -915,7 +812,6 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 0) {
                     layerData.layers = findCompLayers(layerData.refId, comps);
                     completeLayers(layerData.layers, comps);
@@ -927,16 +823,15 @@
                 }
               }
             }
-
             function completeChars(chars, assets) {
               if (chars) {
                 var i = 0;
                 var len = chars.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (chars[i].t === 1) {
                     // var compData = findComp(chars[i].data.refId, assets);
-                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets); // chars[i].data.ip = 0;
+                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                    // chars[i].data.ip = 0;
                     // chars[i].data.op = 99999;
                     // chars[i].data.st = 0;
                     // chars[i].data.sr = 1;
@@ -948,61 +843,48 @@
                     //   s: { k: [100, 100], a: 0 },
                     //   o: { k: 100, a: 0 },
                     // };
-
                     completeLayers(chars[i].data.layers, assets);
                   }
                 }
               }
             }
-
             function findComp(id, comps) {
               var i = 0;
               var len = comps.length;
-
               while (i < len) {
                 if (comps[i].id === id) {
                   return comps[i];
                 }
-
                 i += 1;
               }
-
               return null;
             }
-
             function findCompLayers(id, comps) {
               var comp = findComp(id, comps);
-
               if (comp) {
                 if (!comp.layers.__used) {
                   comp.layers.__used = true;
                   return comp.layers;
                 }
-
                 return JSON.parse(JSON.stringify(comp.layers));
               }
-
               return null;
             }
-
             function completeShapes(arr) {
               var i;
               var len = arr.length;
               var j;
               var jLen;
-
               for (i = len - 1; i >= 0; i -= 1) {
                 if (arr[i].ty === 'sh') {
                   if (arr[i].ks.k.i) {
                     convertPathsToAbsoluteValues(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) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
                       }
-
                       if (arr[i].ks.k[j].e) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
                       }
@@ -1013,11 +895,9 @@
                 }
               }
             }
-
             function convertPathsToAbsoluteValues(path) {
               var i;
               var len = path.i.length;
-
               for (i = 0; i < len; i += 1) {
                 path.i[i][0] += path.v[i][0];
                 path.i[i][1] += path.v[i][1];
@@ -1025,40 +905,30 @@
                 path.o[i][1] += path.v[i][1];
               }
             }
-
             function checkVersion(minimum, animVersionString) {
               var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
-
               if (minimum[0] > animVersion[0]) {
                 return true;
               }
-
               if (animVersion[0] > minimum[0]) {
                 return false;
               }
-
               if (minimum[1] > animVersion[1]) {
                 return true;
               }
-
               if (animVersion[1] > minimum[1]) {
                 return false;
               }
-
               if (minimum[2] > animVersion[2]) {
                 return true;
               }
-
               if (animVersion[2] > minimum[2]) {
                 return false;
               }
-
               return null;
             }
-
             var checkText = function () {
               var minimumVersion = [4, 4, 14];
-
               function updateTextLayer(textLayer) {
                 var documentData = textLayer.t.d;
                 textLayer.t.d = {
@@ -1068,26 +938,21 @@
                   }]
                 };
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1097,17 +962,14 @@
                 }
               };
             }();
-
             var checkChars = function () {
               var minimumVersion = [4, 7, 99];
               return function (animationData) {
                 if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
                   var i;
                   var len = animationData.chars.length;
-
                   for (i = 0; i < len; i += 1) {
                     var charData = animationData.chars[i];
-
                     if (charData.data && charData.data.shapes) {
                       completeShapes(charData.data.shapes);
                       charData.data.ip = 0;
@@ -1136,7 +998,6 @@
                           a: 0
                         }
                       };
-
                       if (!animationData.chars[i].t) {
                         charData.data.shapes.push({
                           ty: 'no'
@@ -1178,27 +1039,22 @@
                 }
               };
             }();
-
             var checkPathProperties = function () {
               var minimumVersion = [5, 7, 15];
-
               function updateTextLayer(textLayer) {
                 var pathData = textLayer.t.p;
-
                 if (typeof pathData.a === 'number') {
                   pathData.a = {
                     a: 0,
                     k: pathData.a
                   };
                 }
-
                 if (typeof pathData.p === 'number') {
                   pathData.p = {
                     a: 0,
                     k: pathData.p
                   };
                 }
-
                 if (typeof pathData.r === 'number') {
                   pathData.r = {
                     a: 0,
@@ -1206,26 +1062,21 @@
                   };
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1235,23 +1086,19 @@
                 }
               };
             }();
-
             var checkColors = function () {
               var minimumVersion = [4, 1, 9];
-
               function iterateShapes(shapes) {
                 var i;
                 var len = shapes.length;
                 var j;
                 var jLen;
-
                 for (i = 0; i < len; i += 1) {
                   if (shapes[i].ty === 'gr') {
                     iterateShapes(shapes[i].it);
                   } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
                     if (shapes[i].c.k && shapes[i].c.k[0].i) {
                       jLen = shapes[i].c.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (shapes[i].c.k[j].s) {
                           shapes[i].c.k[j].s[0] /= 255;
@@ -1259,7 +1106,6 @@
                           shapes[i].c.k[j].s[2] /= 255;
                           shapes[i].c.k[j].s[3] /= 255;
                         }
-
                         if (shapes[i].c.k[j].e) {
                           shapes[i].c.k[j].e[0] /= 255;
                           shapes[i].c.k[j].e[1] /= 255;
@@ -1276,26 +1122,21 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 4) {
                     iterateShapes(layers[i].shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1305,28 +1146,23 @@
                 }
               };
             }();
-
             var checkShapes = function () {
               var minimumVersion = [4, 4, 18];
-
               function completeClosingShapes(arr) {
                 var i;
                 var len = arr.length;
                 var j;
                 var jLen;
-
                 for (i = len - 1; i >= 0; i -= 1) {
                   if (arr[i].ty === 'sh') {
                     if (arr[i].ks.k.i) {
                       arr[i].ks.k.c = arr[i].closed;
                     } else {
                       jLen = arr[i].ks.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (arr[i].ks.k[j].s) {
                           arr[i].ks.k[j].s[0].c = arr[i].closed;
                         }
-
                         if (arr[i].ks.k[j].e) {
                           arr[i].ks.k[j].e[0].c = arr[i].closed;
                         }
@@ -1337,7 +1173,6 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var layerData;
                 var i;
@@ -1346,25 +1181,20 @@
                 var jLen;
                 var k;
                 var kLen;
-
                 for (i = 0; i < len; i += 1) {
                   layerData = layers[i];
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         maskProps[j].pt.k.c = maskProps[j].cl;
                       } else {
                         kLen = maskProps[j].pt.k.length;
-
                         for (k = 0; k < kLen; k += 1) {
                           if (maskProps[j].pt.k[k].s) {
                             maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
                           }
@@ -1372,21 +1202,17 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 4) {
                     completeClosingShapes(layerData.shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1396,12 +1222,10 @@
                 }
               };
             }();
-
             function completeData(animationData) {
               if (animationData.__complete) {
                 return;
               }
-
               checkColors(animationData);
               checkText(animationData);
               checkChars(animationData);
@@ -1411,12 +1235,11 @@
               completeChars(animationData.chars, animationData.assets);
               animationData.__complete = true;
             }
-
             function completeText(data) {
-              if (data.t.a.length === 0 && !('m' in data.t.p)) {// data.singleShape = true;
+              if (data.t.a.length === 0 && !('m' in data.t.p)) {
+                // data.singleShape = true;
               }
             }
-
             var moduleOb = {};
             moduleOb.completeData = completeData;
             moduleOb.checkColors = checkColors;
@@ -1426,47 +1249,37 @@
             moduleOb.completeLayers = completeLayers;
             return moduleOb;
           }
-
           if (!_workerSelf.dataManager) {
             _workerSelf.dataManager = dataFunctionManager();
           }
-
           if (!_workerSelf.assetLoader) {
             _workerSelf.assetLoader = function () {
               function formatResponse(xhr) {
                 // using typeof doubles the time of execution of this method,
                 // so if available, it's better to use the header to validate the type
                 var contentTypeHeader = xhr.getResponseHeader('content-type');
-
                 if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
                   return xhr.response;
                 }
-
                 if (xhr.response && _typeof$5(xhr.response) === 'object') {
                   return xhr.response;
                 }
-
                 if (xhr.response && typeof xhr.response === 'string') {
                   return JSON.parse(xhr.response);
                 }
-
                 if (xhr.responseText) {
                   return JSON.parse(xhr.responseText);
                 }
-
                 return null;
               }
-
               function loadAsset(path, fullPath, callback, errorCallback) {
                 var response;
-                var xhr = new XMLHttpRequest(); // set responseType after calling open or IE will break.
-
+                var xhr = new XMLHttpRequest();
+                // set responseType after calling open or IE will break.
                 try {
                   // This crashes on Android WebView prior to KitKat
                   xhr.responseType = 'json';
                 } catch (err) {} // eslint-disable-line no-empty
-
-
                 xhr.onreadystatechange = function () {
                   if (xhr.readyState === 4) {
                     if (xhr.status === 200) {
@@ -1484,7 +1297,6 @@
                     }
                   }
                 };
-
                 try {
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), path, true);
@@ -1492,20 +1304,16 @@
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
                 }
-
                 xhr.send();
               }
-
               return {
                 load: loadAsset
               };
             }();
           }
-
           if (e.data.type === 'loadAnimation') {
             _workerSelf.assetLoader.load(e.data.path, e.data.fullPath, function (data) {
               _workerSelf.dataManager.completeData(data);
-
               _workerSelf.postMessage({
                 id: e.data.id,
                 payload: data,
@@ -1519,9 +1327,7 @@
             });
           } else if (e.data.type === 'complete') {
             var animation = e.data.animation;
-
             _workerSelf.dataManager.completeData(animation);
-
             _workerSelf.postMessage({
               id: e.data.id,
               payload: animation,
@@ -1542,13 +1348,11 @@
             });
           }
         });
-
         workerInstance.onmessage = function (event) {
           var data = event.data;
           var id = data.id;
           var process = processes[id];
           processes[id] = null;
-
           if (data.status === 'success') {
             process.onComplete(data.payload);
           } else if (process.onError) {
@@ -1557,7 +1361,6 @@
         };
       }
     }
-
     function createProcess(onComplete, onError) {
       _counterId += 1;
       var id = 'processId_' + _counterId;
@@ -1567,7 +1370,6 @@
       };
       return id;
     }
-
     function loadAnimation(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1578,7 +1380,6 @@
         id: processId
       });
     }
-
     function loadData(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1589,7 +1390,6 @@
         id: processId
       });
     }
-
     function completeAnimation(anim, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1599,7 +1399,6 @@
         id: processId
       });
     }
-
     return {
       loadAnimation: loadAnimation,
       loadData: loadData,
@@ -1617,94 +1416,74 @@
       ctx.fillRect(0, 0, 1, 1);
       return canvas;
     }();
-
     function imageLoaded() {
       this.loadedAssets += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function footageLoaded() {
       this.loadedFootagesCount += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function getAssetsPath(assetData, assetsPath, originalPath) {
       var path = '';
-
       if (assetData.e) {
         path = assetData.p;
       } else if (assetsPath) {
         var imagePath = assetData.p;
-
         if (imagePath.indexOf('images/') !== -1) {
           imagePath = imagePath.split('/')[1];
         }
-
         path = assetsPath + imagePath;
       } else {
         path = originalPath;
         path += assetData.u ? assetData.u : '';
         path += assetData.p;
       }
-
       return path;
     }
-
     function testImageLoaded(img) {
       var _count = 0;
       var intervalId = setInterval(function () {
         var box = img.getBBox();
-
         if (box.width || _count > 500) {
           this._imageLoaded();
-
           clearInterval(intervalId);
         }
-
         _count += 1;
       }.bind(this), 50);
     }
-
     function createImageData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createNS('image');
-
       if (isSafari) {
         this.testImageLoaded(img);
       } else {
         img.addEventListener('load', this._imageLoaded, false);
       }
-
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
-
       if (this._elementHelper.append) {
         this._elementHelper.append(img);
       } else {
         this._elementHelper.appendChild(img);
       }
-
       var ob = {
         img: img,
         assetData: assetData
       };
       return ob;
     }
-
     function createImgData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createTag('img');
@@ -1712,7 +1491,6 @@
       img.addEventListener('load', this._imageLoaded, false);
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.src = path;
@@ -1722,7 +1500,6 @@
       };
       return ob;
     }
-
     function createFootageData(data) {
       var ob = {
         assetData: data
@@ -1730,21 +1507,17 @@
       var path = getAssetsPath(data, this.assetsPath, this.path);
       dataManager.loadData(path, function (footageData) {
         ob.img = footageData;
-
         this._footageLoaded();
       }.bind(this), function () {
         ob.img = {};
-
         this._footageLoaded();
       }.bind(this));
       return ob;
     }
-
     function loadAssets(assets, cb) {
       this.imagesLoadedCb = cb;
       var i;
       var len = assets.length;
-
       for (i = 0; i < len; i += 1) {
         if (!assets[i].layers) {
           if (!assets[i].t || assets[i].t === 'seq') {
@@ -1757,43 +1530,33 @@
         }
       }
     }
-
     function setPath(path) {
       this.path = path || '';
     }
-
     function setAssetsPath(path) {
       this.assetsPath = path || '';
     }
-
     function getAsset(assetData) {
       var i = 0;
       var len = this.images.length;
-
       while (i < len) {
         if (this.images[i].assetData === assetData) {
           return this.images[i].img;
         }
-
         i += 1;
       }
-
       return null;
     }
-
     function destroy() {
       this.imagesLoadedCb = null;
       this.images.length = 0;
     }
-
     function loadedImages() {
       return this.totalImages === this.loadedAssets;
     }
-
     function loadedFootages() {
       return this.totalFootages === this.loadedFootagesCount;
     }
-
     function setCacheType(type, elementHelper) {
       if (type === 'svg') {
         this._elementHelper = elementHelper;
@@ -1802,7 +1565,6 @@
         this._createImageData = this.createImgData.bind(this);
       }
     }
-
     function ImagePreloaderFactory() {
       this._imageLoaded = imageLoaded.bind(this);
       this._footageLoaded = footageLoaded.bind(this);
@@ -1817,7 +1579,6 @@
       this.imagesLoadedCb = null;
       this.images = [];
     }
-
     ImagePreloaderFactory.prototype = {
       loadAssets: loadAssets,
       setAssetsPath: setAssetsPath,
@@ -1836,12 +1597,10 @@
   }();
 
   function BaseEvent() {}
-
   BaseEvent.prototype = {
     triggerEvent: function triggerEvent(eventName, args) {
       if (this._cbs[eventName]) {
         var callbacks = this._cbs[eventName];
-
         for (var i = 0; i < callbacks.length; i += 1) {
           callbacks[i](args);
         }
@@ -1851,9 +1610,7 @@
       if (!this._cbs[eventName]) {
         this._cbs[eventName] = [];
       }
-
       this._cbs[eventName].push(callback);
-
       return function () {
         this.removeEventListener(eventName, callback);
       }.bind(this);
@@ -1864,18 +1621,14 @@
       } else if (this._cbs[eventName]) {
         var i = 0;
         var len = this._cbs[eventName].length;
-
         while (i < len) {
           if (this._cbs[eventName][i] === callback) {
             this._cbs[eventName].splice(i, 1);
-
             i -= 1;
             len -= 1;
           }
-
           i += 1;
         }
-
         if (!this._cbs[eventName].length) {
           this._cbs[eventName] = null;
         }
@@ -1889,33 +1642,26 @@
       var keys = {};
       var line;
       var keysCount = 0;
-
       for (var i = 0; i < lines.length; i += 1) {
         line = lines[i].split(':');
-
         if (line.length === 2) {
           keys[line[0]] = line[1].trim();
           keysCount += 1;
         }
       }
-
       if (keysCount === 0) {
         throw new Error();
       }
-
       return keys;
     }
-
     return function (_markers) {
       var markers = [];
-
       for (var i = 0; i < _markers.length; i += 1) {
         var _marker = _markers[i];
         var markerData = {
           time: _marker.tm,
           duration: _marker.dr
         };
-
         try {
           markerData.payload = JSON.parse(_markers[i].cm);
         } catch (_) {
@@ -1927,10 +1673,8 @@
             };
           }
         }
-
         markers.push(markerData);
       }
-
       return markers;
     };
   }();
@@ -1939,27 +1683,21 @@
     function registerComposition(comp) {
       this.compositions.push(comp);
     }
-
     return function () {
       function _thisProjectFunction(name) {
         var i = 0;
         var len = this.compositions.length;
-
         while (i < len) {
           if (this.compositions[i].data && this.compositions[i].data.nm === name) {
             if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
               this.compositions[i].prepareFrame(this.currentFrame);
             }
-
             return this.compositions[i].compInterface;
           }
-
           i += 1;
         }
-
         return null;
       }
-
       _thisProjectFunction.compositions = [];
       _thisProjectFunction.currentFrame = 0;
       _thisProjectFunction.registerComposition = registerComposition;
@@ -1968,33 +1706,27 @@
   }();
 
   var renderers = {};
-
   var registerRenderer = function registerRenderer(key, value) {
     renderers[key] = value;
   };
-
   function getRenderer(key) {
     return renderers[key];
   }
-
   function getRegisteredRenderer() {
     // Returns canvas by default for compatibility
     if (renderers.canvas) {
       return 'canvas';
-    } // Returns any renderer that is registered
-
-
+    }
+    // Returns any renderer that is registered
     for (var key in renderers) {
       if (renderers[key]) {
         return key;
       }
     }
-
     return '';
   }
 
-  function _typeof$4(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$4 = function _typeof(obj) { return typeof obj; }; } else { _typeof$4 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$4(obj); }
-
+  function _typeof$4(o) { "@babel/helpers - typeof"; return _typeof$4 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$4(o); }
   var AnimationItem = function AnimationItem() {
     this._cbs = [];
     this.name = '';
@@ -2033,28 +1765,22 @@
     this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
     this.expressionsPlugin = getExpressionsPlugin();
   };
-
   extendPrototype([BaseEvent], AnimationItem);
-
   AnimationItem.prototype.setParams = function (params) {
     if (params.wrapper || params.container) {
       this.wrapper = params.wrapper || params.container;
     }
-
     var animType = 'svg';
-
     if (params.animType) {
       animType = params.animType;
     } else if (params.renderer) {
       animType = params.renderer;
     }
-
     var RendererClass = getRenderer(animType);
     this.renderer = new RendererClass(this, params.rendererSettings);
     this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
     this.renderer.setProjectInterface(this.projectInterface);
     this.animType = animType;
-
     if (params.loop === '' || params.loop === null || params.loop === undefined || params.loop === true) {
       this.loop = true;
     } else if (params.loop === false) {
@@ -2062,17 +1788,14 @@
     } else {
       this.loop = parseInt(params.loop, 10);
     }
-
     this.autoplay = 'autoplay' in params ? params.autoplay : true;
     this.name = params.name ? params.name : '';
     this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
     this.assetsPath = params.assetsPath;
     this.initialSegment = params.initialSegment;
-
     if (params.audioFactory) {
       this.audioController.setAudioFactory(params.audioFactory);
     }
-
     if (params.animationData) {
       this.setupAnimation(params.animationData);
     } else if (params.path) {
@@ -2081,28 +1804,23 @@
       } else {
         this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
       }
-
       this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
       this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
       dataManager.loadAnimation(params.path, this.configAnimation, this.onSetupError);
     }
   };
-
   AnimationItem.prototype.onSetupError = function () {
     this.trigger('data_failed');
   };
-
   AnimationItem.prototype.setupAnimation = function (data) {
     dataManager.completeAnimation(data, this.configAnimation);
   };
-
   AnimationItem.prototype.setData = function (wrapper, animationData) {
     if (animationData) {
       if (_typeof$4(animationData) !== 'object') {
         animationData = JSON.parse(animationData);
       }
     }
-
     var params = {
       wrapper: wrapper,
       animationData: animationData
@@ -2119,7 +1837,6 @@
     var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-loop').value : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-loop').value : wrapperAttributes.getNamedItem('bm-loop') ? wrapperAttributes.getNamedItem('bm-loop').value : '';
-
     if (loop === 'false') {
       params.loop = false;
     } else if (loop === 'true') {
@@ -2127,7 +1844,6 @@
     } else if (loop !== '') {
       params.loop = parseInt(loop, 10);
     }
-
     var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-autoplay').value : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-autoplay').value : wrapperAttributes.getNamedItem('bm-autoplay') ? wrapperAttributes.getNamedItem('bm-autoplay').value : true;
@@ -2138,81 +1854,64 @@
     var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-prerender').value : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-prerender').value : wrapperAttributes.getNamedItem('bm-prerender') ? wrapperAttributes.getNamedItem('bm-prerender').value : '';
-
     if (prerender === 'false') {
       params.prerender = false;
     }
-
     if (!params.path) {
       this.trigger('destroy');
     } else {
       this.setParams(params);
     }
   };
-
   AnimationItem.prototype.includeLayers = function (data) {
     if (data.op > this.animationData.op) {
       this.animationData.op = data.op;
       this.totalFrames = Math.floor(data.op - this.animationData.ip);
     }
-
     var layers = this.animationData.layers;
     var i;
     var len = layers.length;
     var newLayers = data.layers;
     var j;
     var jLen = newLayers.length;
-
     for (j = 0; j < jLen; j += 1) {
       i = 0;
-
       while (i < len) {
         if (layers[i].id === newLayers[j].id) {
           layers[i] = newLayers[j];
           break;
         }
-
         i += 1;
       }
     }
-
     if (data.chars || data.fonts) {
       this.renderer.globalData.fontManager.addChars(data.chars);
       this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
     }
-
     if (data.assets) {
       len = data.assets.length;
-
       for (i = 0; i < len; i += 1) {
         this.animationData.assets.push(data.assets[i]);
       }
     }
-
     this.animationData.__complete = false;
     dataManager.completeAnimation(this.animationData, this.onSegmentComplete);
   };
-
   AnimationItem.prototype.onSegmentComplete = function (data) {
     this.animationData = data;
     var expressionsPlugin = getExpressionsPlugin();
-
     if (expressionsPlugin) {
       expressionsPlugin.initExpressions(this);
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.loadNextSegment = function () {
     var segments = this.animationData.segments;
-
     if (!segments || segments.length === 0 || !this.autoloadSegments) {
       this.trigger('data_ready');
       this.timeCompleted = this.totalFrames;
       return;
     }
-
     var segment = segments.shift();
     this.timeCompleted = segment.time * this.frameRate;
     var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
@@ -2221,36 +1920,28 @@
       this.trigger('data_failed');
     }.bind(this));
   };
-
   AnimationItem.prototype.loadSegments = function () {
     var segments = this.animationData.segments;
-
     if (!segments) {
       this.timeCompleted = this.totalFrames;
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.imagesLoaded = function () {
     this.trigger('loaded_images');
     this.checkLoaded();
   };
-
   AnimationItem.prototype.preloadImages = function () {
     this.imagePreloader.setAssetsPath(this.assetsPath);
     this.imagePreloader.setPath(this.path);
     this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
   };
-
   AnimationItem.prototype.configAnimation = function (animData) {
     if (!this.renderer) {
       return;
     }
-
     try {
       this.animationData = animData;
-
       if (this.initialSegment) {
         this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
         this.firstFrame = Math.round(this.initialSegment[0]);
@@ -2258,13 +1949,10 @@
         this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
         this.firstFrame = Math.round(this.animationData.ip);
       }
-
       this.renderer.configAnimation(animData);
-
       if (!animData.assets) {
         animData.assets = [];
       }
-
       this.assets = this.animationData.assets;
       this.frameRate = this.animationData.fr;
       this.frameMult = this.animationData.fr / 1000;
@@ -2275,7 +1963,6 @@
       this.loadSegments();
       this.updaFrameModifier();
       this.waitForFontsLoaded();
-
       if (this.isPaused) {
         this.audioController.pause();
       }
@@ -2283,103 +1970,83 @@
       this.triggerConfigError(error);
     }
   };
-
   AnimationItem.prototype.waitForFontsLoaded = function () {
     if (!this.renderer) {
       return;
     }
-
     if (this.renderer.globalData.fontManager.isLoaded) {
       this.checkLoaded();
     } else {
       setTimeout(this.waitForFontsLoaded.bind(this), 20);
     }
   };
-
   AnimationItem.prototype.checkLoaded = function () {
     if (!this.isLoaded && this.renderer.globalData.fontManager.isLoaded && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas') && this.imagePreloader.loadedFootages()) {
       this.isLoaded = true;
       var expressionsPlugin = getExpressionsPlugin();
-
       if (expressionsPlugin) {
         expressionsPlugin.initExpressions(this);
       }
-
       this.renderer.initItems();
       setTimeout(function () {
         this.trigger('DOMLoaded');
       }.bind(this), 0);
       this.gotoFrame();
-
       if (this.autoplay) {
         this.play();
       }
     }
   };
-
   AnimationItem.prototype.resize = function (width, height) {
     // Adding this validation for backwards compatibility in case an event object was being passed down
     var _width = typeof width === 'number' ? width : undefined;
-
     var _height = typeof height === 'number' ? height : undefined;
-
     this.renderer.updateContainerSize(_width, _height);
   };
-
   AnimationItem.prototype.setSubframe = function (flag) {
     this.isSubframeEnabled = !!flag;
   };
-
   AnimationItem.prototype.gotoFrame = function () {
     this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
 
     if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
       this.currentFrame = this.timeCompleted;
     }
-
     this.trigger('enterFrame');
     this.renderFrame();
     this.trigger('drawnFrame');
   };
-
   AnimationItem.prototype.renderFrame = function () {
     if (this.isLoaded === false || !this.renderer) {
       return;
     }
-
     try {
       if (this.expressionsPlugin) {
         this.expressionsPlugin.resetFrame();
       }
-
       this.renderer.renderFrame(this.currentFrame + this.firstFrame);
     } catch (error) {
       this.triggerRenderFrameError(error);
     }
   };
-
   AnimationItem.prototype.play = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.isPaused = false;
       this.trigger('_play');
       this.audioController.resume();
-
       if (this._idle) {
         this._idle = false;
         this.trigger('_active');
       }
     }
   };
-
   AnimationItem.prototype.pause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === false) {
       this.isPaused = true;
       this.trigger('_pause');
@@ -2388,54 +2055,42 @@
       this.audioController.pause();
     }
   };
-
   AnimationItem.prototype.togglePause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.play();
     } else {
       this.pause();
     }
   };
-
   AnimationItem.prototype.stop = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.pause();
     this.playCount = 0;
     this._completedLoop = false;
     this.setCurrentRawFrameValue(0);
   };
-
   AnimationItem.prototype.getMarkerData = function (markerName) {
     var marker;
-
     for (var i = 0; i < this.markers.length; i += 1) {
       marker = this.markers[i];
-
       if (marker.payload && marker.payload.name === markerName) {
         return marker;
       }
     }
-
     return null;
   };
-
   AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         this.goToAndStop(marker.time, true);
       }
@@ -2444,20 +2099,15 @@
     } else {
       this.setCurrentRawFrameValue(value * this.frameModifier);
     }
-
     this.pause();
   };
-
   AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         if (!marker.duration) {
           this.goToAndStop(marker.time, true);
@@ -2468,19 +2118,16 @@
     } else {
       this.goToAndStop(numValue, isFrame, name);
     }
-
     this.play();
   };
-
   AnimationItem.prototype.advanceTime = function (value) {
     if (this.isPaused === true || this.isLoaded === false) {
       return;
     }
-
     var nextValue = this.currentRawFrame + value * this.frameModifier;
-    var _isComplete = false; // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+    var _isComplete = false;
+    // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
     // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
-
     if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
       if (!this.loop || this.playCount === this.loop) {
         if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
@@ -2489,7 +2136,6 @@
         }
       } else if (nextValue >= this.totalFrames) {
         this.playCount += 1;
-
         if (!this.checkSegments(nextValue % this.totalFrames)) {
           this.setCurrentRawFrameValue(nextValue % this.totalFrames);
           this._completedLoop = true;
@@ -2503,7 +2149,6 @@
         if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) {
           // eslint-disable-line no-plusplus
           this.setCurrentRawFrameValue(this.totalFrames + nextValue % this.totalFrames);
-
           if (!this._completedLoop) {
             this._completedLoop = true;
           } else {
@@ -2517,17 +2162,14 @@
     } else {
       this.setCurrentRawFrameValue(nextValue);
     }
-
     if (_isComplete) {
       this.setCurrentRawFrameValue(nextValue);
       this.pause();
       this.trigger('complete');
     }
   };
-
   AnimationItem.prototype.adjustSegment = function (arr, offset) {
     this.playCount = 0;
-
     if (arr[1] < arr[0]) {
       if (this.frameModifier > 0) {
         if (this.playSpeed < 0) {
@@ -2536,7 +2178,6 @@
           this.setDirection(-1);
         }
       }
-
       this.totalFrames = arr[0] - arr[1];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[1];
@@ -2549,19 +2190,15 @@
           this.setDirection(1);
         }
       }
-
       this.totalFrames = arr[1] - arr[0];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[0];
       this.setCurrentRawFrameValue(0.001 + offset);
     }
-
     this.trigger('segmentStart');
   };
-
   AnimationItem.prototype.setSegment = function (init, end) {
     var pendingFrame = -1;
-
     if (this.isPaused) {
       if (this.currentRawFrame + this.firstFrame < init) {
         pendingFrame = init;
@@ -2569,64 +2206,51 @@
         pendingFrame = end - init;
       }
     }
-
     this.firstFrame = init;
     this.totalFrames = end - init;
     this.timeCompleted = this.totalFrames;
-
     if (pendingFrame !== -1) {
       this.goToAndStop(pendingFrame, true);
     }
   };
-
   AnimationItem.prototype.playSegments = function (arr, forceFlag) {
     if (forceFlag) {
       this.segments.length = 0;
     }
-
     if (_typeof$4(arr[0]) === 'object') {
       var i;
       var len = arr.length;
-
       for (i = 0; i < len; i += 1) {
         this.segments.push(arr[i]);
       }
     } else {
       this.segments.push(arr);
     }
-
     if (this.segments.length && forceFlag) {
       this.adjustSegment(this.segments.shift(), 0);
     }
-
     if (this.isPaused) {
       this.play();
     }
   };
-
   AnimationItem.prototype.resetSegments = function (forceFlag) {
     this.segments.length = 0;
     this.segments.push([this.animationData.ip, this.animationData.op]);
-
     if (forceFlag) {
       this.checkSegments(0);
     }
   };
-
   AnimationItem.prototype.checkSegments = function (offset) {
     if (this.segments.length) {
       this.adjustSegment(this.segments.shift(), offset);
       return true;
     }
-
     return false;
   };
-
   AnimationItem.prototype.destroy = function (name) {
     if (name && this.name !== name || !this.renderer) {
       return;
     }
-
     this.renderer.destroy();
     this.imagePreloader.destroy();
     this.trigger('destroy');
@@ -2641,189 +2265,148 @@
     this.imagePreloader = null;
     this.projectInterface = null;
   };
-
   AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
     this.currentRawFrame = value;
     this.gotoFrame();
   };
-
   AnimationItem.prototype.setSpeed = function (val) {
     this.playSpeed = val;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setDirection = function (val) {
     this.playDirection = val < 0 ? -1 : 1;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setLoop = function (isLooping) {
     this.loop = isLooping;
   };
-
   AnimationItem.prototype.setVolume = function (val, name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.setVolume(val);
   };
-
   AnimationItem.prototype.getVolume = function () {
     return this.audioController.getVolume();
   };
-
   AnimationItem.prototype.mute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.mute();
   };
-
   AnimationItem.prototype.unmute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.unmute();
   };
-
   AnimationItem.prototype.updaFrameModifier = function () {
     this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
     this.audioController.setRate(this.playSpeed * this.playDirection);
   };
-
   AnimationItem.prototype.getPath = function () {
     return this.path;
   };
-
   AnimationItem.prototype.getAssetsPath = function (assetData) {
     var path = '';
-
     if (assetData.e) {
       path = assetData.p;
     } else if (this.assetsPath) {
       var imagePath = assetData.p;
-
       if (imagePath.indexOf('images/') !== -1) {
         imagePath = imagePath.split('/')[1];
       }
-
       path = this.assetsPath + imagePath;
     } else {
       path = this.path;
       path += assetData.u ? assetData.u : '';
       path += assetData.p;
     }
-
     return path;
   };
-
   AnimationItem.prototype.getAssetData = function (id) {
     var i = 0;
     var len = this.assets.length;
-
     while (i < len) {
       if (id === this.assets[i].id) {
         return this.assets[i];
       }
-
       i += 1;
     }
-
     return null;
   };
-
   AnimationItem.prototype.hide = function () {
     this.renderer.hide();
   };
-
   AnimationItem.prototype.show = function () {
     this.renderer.show();
   };
-
   AnimationItem.prototype.getDuration = function (isFrame) {
     return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
   };
-
   AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
     try {
       var element = this.renderer.getElementByPath(path);
       element.updateDocumentData(documentData, index);
-    } catch (error) {// TODO: decide how to handle catch case
+    } catch (error) {
+      // TODO: decide how to handle catch case
     }
   };
-
   AnimationItem.prototype.trigger = function (name) {
     if (this._cbs && this._cbs[name]) {
       switch (name) {
         case 'enterFrame':
           this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
           break;
-
         case 'drawnFrame':
           this.drawnFrameEvent.currentTime = this.currentFrame;
           this.drawnFrameEvent.totalTime = this.totalFrames;
           this.drawnFrameEvent.direction = this.frameModifier;
           this.triggerEvent(name, this.drawnFrameEvent);
           break;
-
         case 'loopComplete':
           this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
           break;
-
         case 'complete':
           this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
           break;
-
         case 'segmentStart':
           this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
           break;
-
         case 'destroy':
           this.triggerEvent(name, new BMDestroyEvent(name, this));
           break;
-
         default:
           this.triggerEvent(name);
       }
     }
-
     if (name === 'enterFrame' && this.onEnterFrame) {
       this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
     }
-
     if (name === 'loopComplete' && this.onLoopComplete) {
       this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
     }
-
     if (name === 'complete' && this.onComplete) {
       this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
     }
-
     if (name === 'segmentStart' && this.onSegmentStart) {
       this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
     }
-
     if (name === 'destroy' && this.onDestroy) {
       this.onDestroy.call(this, new BMDestroyEvent(name, this));
     }
   };
-
   AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
     var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
   };
-
   AnimationItem.prototype.triggerConfigError = function (nativeError) {
     var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
@@ -2837,68 +2420,53 @@
     var playingAnimationsNum = 0;
     var _stopped = true;
     var _isFrozen = false;
-
     function removeElement(ev) {
       var i = 0;
       var animItem = ev.target;
-
       while (i < len) {
         if (registeredAnimations[i].animation === animItem) {
           registeredAnimations.splice(i, 1);
           i -= 1;
           len -= 1;
-
           if (!animItem.isPaused) {
             subtractPlayingCount();
           }
         }
-
         i += 1;
       }
     }
-
     function registerAnimation(element, animationData) {
       if (!element) {
         return null;
       }
-
       var i = 0;
-
       while (i < len) {
         if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
           return registeredAnimations[i].animation;
         }
-
         i += 1;
       }
-
       var animItem = new AnimationItem();
       setupAnimation(animItem, element);
       animItem.setData(element, animationData);
       return animItem;
     }
-
     function getRegisteredAnimations() {
       var i;
       var lenAnims = registeredAnimations.length;
       var animations = [];
-
       for (i = 0; i < lenAnims; i += 1) {
         animations.push(registeredAnimations[i].animation);
       }
-
       return animations;
     }
-
     function addPlayingCount() {
       playingAnimationsNum += 1;
       activate();
     }
-
     function subtractPlayingCount() {
       playingAnimationsNum -= 1;
     }
-
     function setupAnimation(animItem, element) {
       animItem.addEventListener('destroy', removeElement);
       animItem.addEventListener('_active', addPlayingCount);
@@ -2909,118 +2477,91 @@
       });
       len += 1;
     }
-
     function loadAnimation(params) {
       var animItem = new AnimationItem();
       setupAnimation(animItem, null);
       animItem.setParams(params);
       return animItem;
     }
-
     function setSpeed(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setSpeed(val, animation);
       }
     }
-
     function setDirection(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setDirection(val, animation);
       }
     }
-
     function play(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.play(animation);
       }
     }
-
     function resume(nowTime) {
       var elapsedTime = nowTime - initTime;
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.advanceTime(elapsedTime);
       }
-
       initTime = nowTime;
-
       if (playingAnimationsNum && !_isFrozen) {
         window.requestAnimationFrame(resume);
       } else {
         _stopped = true;
       }
     }
-
     function first(nowTime) {
       initTime = nowTime;
       window.requestAnimationFrame(resume);
     }
-
     function pause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.pause(animation);
       }
     }
-
     function goToAndStop(value, isFrame, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
       }
     }
-
     function stop(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.stop(animation);
       }
     }
-
     function togglePause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.togglePause(animation);
       }
     }
-
     function destroy(animation) {
       var i;
-
       for (i = len - 1; i >= 0; i -= 1) {
         registeredAnimations[i].animation.destroy(animation);
       }
     }
-
     function searchAnimations(animationData, standalone, renderer) {
       var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')), [].slice.call(document.getElementsByClassName('bodymovin')));
       var i;
       var lenAnims = animElements.length;
-
       for (i = 0; i < lenAnims; i += 1) {
         if (renderer) {
           animElements[i].setAttribute('data-bm-type', renderer);
         }
-
         registerAnimation(animElements[i], animationData);
       }
-
       if (standalone && lenAnims === 0) {
         if (!renderer) {
           renderer = 'svg';
         }
-
         var body = document.getElementsByTagName('body')[0];
         body.innerText = '';
         var div = createTag('div');
@@ -3031,15 +2572,12 @@
         registerAnimation(div, animationData);
       }
     }
-
     function resize() {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.resize();
       }
     }
-
     function activate() {
       if (!_isFrozen && playingAnimationsNum) {
         if (_stopped) {
@@ -3048,40 +2586,31 @@
         }
       }
     }
-
     function freeze() {
       _isFrozen = true;
     }
-
     function unfreeze() {
       _isFrozen = false;
       activate();
     }
-
     function setVolume(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setVolume(val, animation);
       }
     }
-
     function mute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.mute(animation);
       }
     }
-
     function unmute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.unmute(animation);
       }
     }
-
     moduleOb.registerAnimation = registerAnimation;
     moduleOb.loadAnimation = loadAnimation;
     moduleOb.setSpeed = setSpeed;
@@ -3091,8 +2620,8 @@
     moduleOb.stop = stop;
     moduleOb.togglePause = togglePause;
     moduleOb.searchAnimations = searchAnimations;
-    moduleOb.resize = resize; // moduleOb.start = start;
-
+    moduleOb.resize = resize;
+    // moduleOb.start = start;
     moduleOb.goToAndStop = goToAndStop;
     moduleOb.destroy = destroy;
     moduleOb.freeze = freeze;
@@ -3116,23 +2645,21 @@
        * spline.get(x) => returns the easing value | x must be in [0, 1] range
        *
        */
+
     var ob = {};
     ob.getBezierEasing = getBezierEasing;
     var beziers = {};
-
     function getBezierEasing(a, b, c, d, nm) {
       var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
-
       if (beziers[str]) {
         return beziers[str];
       }
-
       var bezEasing = new BezierEasing([a, b, c, d]);
       beziers[str] = bezEasing;
       return bezEasing;
-    } // These values are established by empiricism with tests (tradeoff: performance VS precision)
+    }
 
-
+    // These values are established by empiricism with tests (tradeoff: performance VS precision)
     var NEWTON_ITERATIONS = 4;
     var NEWTON_MIN_SLOPE = 0.001;
     var SUBDIVISION_PRECISION = 0.0000001;
@@ -3140,48 +2667,40 @@
     var kSplineTableSize = 11;
     var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
     var float32ArraySupported = typeof Float32Array === 'function';
-
     function A(aA1, aA2) {
       return 1.0 - 3.0 * aA2 + 3.0 * aA1;
     }
-
     function B(aA1, aA2) {
       return 3.0 * aA2 - 6.0 * aA1;
     }
-
     function C(aA1) {
       return 3.0 * aA1;
-    } // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+    }
 
-
+    // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
     function calcBezier(aT, aA1, aA2) {
       return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
-    } // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+    }
 
-
+    // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
     function getSlope(aT, aA1, aA2) {
       return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
     }
-
     function binarySubdivide(aX, aA, aB, mX1, mX2) {
       var currentX,
-          currentT,
-          i = 0;
-
+        currentT,
+        i = 0;
       do {
         currentT = aA + (aB - aA) / 2.0;
         currentX = calcBezier(currentT, mX1, mX2) - aX;
-
         if (currentX > 0.0) {
           aB = currentT;
         } else {
           aA = currentT;
         }
       } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
-
       return currentT;
     }
-
     function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
       for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
         var currentSlope = getSlope(aGuessT, mX1, mX2);
@@ -3189,85 +2708,75 @@
         var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
         aGuessT -= currentX / currentSlope;
       }
-
       return aGuessT;
     }
+
     /**
        * points is an array of [ mX1, mY1, mX2, mY2 ]
        */
-
-
     function BezierEasing(points) {
       this._p = points;
       this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
       this._precomputed = false;
       this.get = this.get.bind(this);
     }
-
     BezierEasing.prototype = {
       get: function get(x) {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         if (!this._precomputed) this._precompute();
         if (mX1 === mY1 && mX2 === mY2) return x; // linear
         // Because JavaScript number are imprecise, we should guarantee the extremes are right.
-
         if (x === 0) return 0;
         if (x === 1) return 1;
         return calcBezier(this._getTForX(x), mY1, mY2);
       },
       // Private part
+
       _precompute: function _precompute() {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         this._precomputed = true;
-
         if (mX1 !== mY1 || mX2 !== mY2) {
           this._calcSampleValues();
         }
       },
       _calcSampleValues: function _calcSampleValues() {
         var mX1 = this._p[0],
-            mX2 = this._p[2];
-
+          mX2 = this._p[2];
         for (var i = 0; i < kSplineTableSize; ++i) {
           this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
         }
       },
-
       /**
            * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
            */
       _getTForX: function _getTForX(aX) {
         var mX1 = this._p[0],
-            mX2 = this._p[2],
-            mSampleValues = this._mSampleValues;
+          mX2 = this._p[2],
+          mSampleValues = this._mSampleValues;
         var intervalStart = 0.0;
         var currentSample = 1;
         var lastSample = kSplineTableSize - 1;
-
         for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
           intervalStart += kSampleStepSize;
         }
+        --currentSample;
 
-        --currentSample; // Interpolate to provide an initial guess for t
-
+        // Interpolate to provide an initial guess for t
         var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
         var guessForT = intervalStart + dist * kSampleStepSize;
         var initialSlope = getSlope(guessForT, mX1, mX2);
-
         if (initialSlope >= NEWTON_MIN_SLOPE) {
           return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
         }
-
         if (initialSlope === 0.0) {
           return guessForT;
         }
-
         return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
       }
     };
@@ -3278,7 +2787,6 @@
     function _double(arr) {
       return arr.concat(createSizedArray(arr.length));
     }
-
     return {
       "double": _double
     };
@@ -3293,34 +2801,27 @@
         newElement: newElement,
         release: release
       };
-
       function newElement() {
         var element;
-
         if (_length) {
           _length -= 1;
           element = pool[_length];
         } else {
           element = _create();
         }
-
         return element;
       }
-
       function release(element) {
         if (_length === _maxLength) {
           pool = pooling["double"](pool);
           _maxLength *= 2;
         }
-
         if (_release) {
           _release(element);
         }
-
         pool[_length] = element;
         _length += 1;
       }
-
       return ob;
     };
   }();
@@ -3333,7 +2834,6 @@
         lengths: createTypedArray('float32', getDefaultCurveSegments())
       };
     }
-
     return poolFactory(8, create);
   }();
 
@@ -3344,39 +2844,31 @@
         totalLength: 0
       };
     }
-
     function release(element) {
       var i;
       var len = element.lengths.length;
-
       for (i = 0; i < len; i += 1) {
         bezierLengthPool.release(element.lengths[i]);
       }
-
       element.lengths.length = 0;
     }
-
     return poolFactory(8, create, release);
   }();
 
   function bezFunction() {
     var math = Math;
-
     function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
       var det1 = x1 * y2 + y1 * x3 + x2 * y3 - x3 * y2 - y3 * x1 - x2 * y1;
       return det1 > -0.001 && det1 < 0.001;
     }
-
     function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
       if (z1 === 0 && z2 === 0 && z3 === 0) {
         return pointOnLine2D(x1, y1, x2, y2, x3, y3);
       }
-
       var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
       var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
       var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
       var diffDist;
-
       if (dist1 > dist2) {
         if (dist1 > dist3) {
           diffDist = dist1 - dist2 - dist3;
@@ -3388,10 +2880,8 @@
       } else {
         diffDist = dist2 - dist1 - dist3;
       }
-
       return diffDist > -0.0001 && diffDist < 0.0001;
     }
-
     var getBezierLength = function () {
       return function (pt1, pt2, pt3, pt4) {
         var curveSegments = getDefaultCurveSegments();
@@ -3406,36 +2896,28 @@
         var lastPoint = [];
         var lengthData = bezierLengthPool.newElement();
         len = pt3.length;
-
         for (k = 0; k < curveSegments; k += 1) {
           perc = k / (curveSegments - 1);
           ptDistance = 0;
-
           for (i = 0; i < len; i += 1) {
             ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
             point[i] = ptCoord;
-
             if (lastPoint[i] !== null) {
               ptDistance += bmPow(point[i] - lastPoint[i], 2);
             }
-
             lastPoint[i] = point[i];
           }
-
           if (ptDistance) {
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
           }
-
           lengthData.percents[k] = perc;
           lengthData.lengths[k] = addedLength;
         }
-
         lengthData.addedLength = addedLength;
         return lengthData;
       };
     }();
-
     function getSegmentsLength(shapeData) {
       var segmentsLength = segmentsLengthPool.newElement();
       var closed = shapeData.c;
@@ -3446,36 +2928,29 @@
       var len = shapeData._length;
       var lengths = segmentsLength.lengths;
       var totalLength = 0;
-
       for (i = 0; i < len - 1; i += 1) {
         lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
         totalLength += lengths[i].addedLength;
       }
-
       if (closed && len) {
         lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
         totalLength += lengths[i].addedLength;
       }
-
       segmentsLength.totalLength = totalLength;
       return segmentsLength;
     }
-
     function BezierData(length) {
       this.segmentLength = 0;
       this.points = new Array(length);
     }
-
     function PointData(partial, point) {
       this.partialLength = partial;
       this.point = point;
     }
-
     var buildBezierData = function () {
       var storedData = {};
       return function (pt1, pt2, pt3, pt4) {
         var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
-
         if (!storedData[bezierName]) {
           var curveSegments = getDefaultCurveSegments();
           var k;
@@ -3487,42 +2962,33 @@
           var ptDistance;
           var point;
           var lastPoint = null;
-
           if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
             curveSegments = 2;
           }
-
           var bezierData = new BezierData(curveSegments);
           len = pt3.length;
-
           for (k = 0; k < curveSegments; k += 1) {
             point = createSizedArray(len);
             perc = k / (curveSegments - 1);
             ptDistance = 0;
-
             for (i = 0; i < len; i += 1) {
               ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
               point[i] = ptCoord;
-
               if (lastPoint !== null) {
                 ptDistance += bmPow(point[i] - lastPoint[i], 2);
               }
             }
-
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
             bezierData.points[k] = new PointData(ptDistance, point);
             lastPoint = point;
           }
-
           bezierData.segmentLength = addedLength;
           storedData[bezierName] = bezierData;
         }
-
         return storedData[bezierName];
       };
     }();
-
     function getDistancePerc(perc, bezierData) {
       var percents = bezierData.percents;
       var lengths = bezierData.lengths;
@@ -3530,14 +2996,11 @@
       var initPos = bmFloor((len - 1) * perc);
       var lengthPos = perc * bezierData.addedLength;
       var lPerc = 0;
-
       if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
         return percents[initPos];
       }
-
       var dir = lengths[initPos] > lengthPos ? -1 : 1;
       var flag = true;
-
       while (flag) {
         if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
           lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
@@ -3545,20 +3008,16 @@
         } else {
           initPos += dir;
         }
-
         if (initPos < 0 || initPos >= len - 1) {
           // FIX for TypedArrays that don't store floating point values with enough accuracy
           if (initPos === len - 1) {
             return percents[initPos];
           }
-
           flag = false;
         }
       }
-
       return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
     }
-
     function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
       var t1 = getDistancePerc(percent, bezierData);
       var u1 = 1 - t1;
@@ -3566,16 +3025,13 @@
       var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
       return [ptX, ptY];
     }
-
     var bezierSegmentPoints = createTypedArray('float32', 8);
-
     function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
       if (startPerc < 0) {
         startPerc = 0;
       } else if (startPerc > 1) {
         startPerc = 1;
       }
-
       var t0 = getDistancePerc(startPerc, bezierData);
       endPerc = endPerc > 1 ? 1 : endPerc;
       var t1 = getDistancePerc(endPerc, bezierData);
@@ -3585,45 +3041,31 @@
       var u1 = 1 - t1;
       var u0u0u0 = u0 * u0 * u0;
       var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
-
       var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
-
-      var t0t0t0 = t0 * t0 * t0; //
-
+      var t0t0t0 = t0 * t0 * t0;
+      //
       var u0u0u1 = u0 * u0 * u1;
       var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
-
       var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
-
-      var t0t0t1 = t0 * t0 * t1; //
-
+      var t0t0t1 = t0 * t0 * t1;
+      //
       var u0u1u1 = u0 * u1 * u1;
       var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
-
       var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
-
-      var t0t1t1 = t0 * t1 * t1; //
-
+      var t0t1t1 = t0 * t1 * t1;
+      //
       var u1u1u1 = u1 * u1 * u1;
       var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1t1 = t1 * t1 * t1;
-
       for (i = 0; i < len; i += 1) {
         bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
       }
-
       return bezierSegmentPoints;
     }
-
     return {
       getSegmentsLength: getSegmentsLength,
       getNewSegment: getNewSegment,
@@ -3633,20 +3075,16 @@
       pointOnLine3D: pointOnLine3D
     };
   }
-
   var bez = bezFunction();
 
   var initFrame = initialDefaultFrame;
   var mathAbs = Math.abs;
-
   function interpolateValue(frameNum, caching) {
     var offsetTime = this.offsetTime;
     var newValue;
-
     if (this.propType === 'multidimensional') {
       newValue = createTypedArray('float32', this.pv.length);
     }
-
     var iterationIndex = caching.lastIndex;
     var i = iterationIndex;
     var len = this.keyframes.length - 1;
@@ -3654,25 +3092,20 @@
     var keyData;
     var nextKeyData;
     var keyframeMetadata;
-
     while (flag) {
       keyData = this.keyframes[i];
       nextKeyData = this.keyframes[i + 1];
-
       if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
         if (keyData.h) {
           keyData = nextKeyData;
         }
-
         iterationIndex = 0;
         break;
       }
-
       if (nextKeyData.t - offsetTime > frameNum) {
         iterationIndex = i;
         break;
       }
-
       if (i < len - 1) {
         i += 1;
       } else {
@@ -3680,7 +3113,6 @@
         flag = false;
       }
     }
-
     keyframeMetadata = this.keyframesMetadata[i] || {};
     var k;
     var kLen;
@@ -3691,22 +3123,18 @@
     var nextKeyTime = nextKeyData.t - offsetTime;
     var keyTime = keyData.t - offsetTime;
     var endValue;
-
     if (keyData.to) {
       if (!keyframeMetadata.bezierData) {
         keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
       }
-
       var bezierData = keyframeMetadata.bezierData;
-
       if (frameNum >= nextKeyTime || frameNum < keyTime) {
         var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
         kLen = bezierData.points[ind].point.length;
-
         for (k = 0; k < kLen; k += 1) {
           newValue[k] = bezierData.points[ind].point[k];
-        } // caching._lastKeyframeIndex = -1;
-
+        }
+        // caching._lastKeyframeIndex = -1;
       } else {
         if (keyframeMetadata.__fnct) {
           fnc = keyframeMetadata.__fnct;
@@ -3714,7 +3142,6 @@
           fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
           keyframeMetadata.__fnct = fnc;
         }
-
         perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
         var distanceInLine = bezierData.segmentLength * perc;
         var segmentPerc;
@@ -3722,36 +3149,28 @@
         j = caching.lastFrame < frameNum && caching._lastKeyframeIndex === i ? caching._lastPoint : 0;
         flag = true;
         jLen = bezierData.points.length;
-
         while (flag) {
           addedLength += bezierData.points[j].partialLength;
-
           if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k];
             }
-
             break;
           } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
             segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
             }
-
             break;
           }
-
           if (j < jLen - 1) {
             j += 1;
           } else {
             flag = false;
           }
         }
-
         caching._lastPoint = j;
         caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
         caching._lastKeyframeIndex = i;
@@ -3764,7 +3183,6 @@
       var keyValue;
       len = keyData.s.length;
       endValue = nextKeyData.s || keyData.e;
-
       if (this.sh && keyData.h !== 1) {
         if (frameNum >= nextKeyTime) {
           newValue[0] = endValue[0];
@@ -3792,7 +3210,6 @@
                 if (!keyframeMetadata.__fnct) {
                   keyframeMetadata.__fnct = [];
                 }
-
                 if (!keyframeMetadata.__fnct[i]) {
                   outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
                   outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
@@ -3813,14 +3230,11 @@
               } else {
                 fnc = keyframeMetadata.__fnct;
               }
-
               perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
             }
           }
-
           endValue = nextKeyData.s || keyData.e;
           keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
-
           if (this.propType === 'multidimensional') {
             newValue[i] = keyValue;
           } else {
@@ -3829,12 +3243,11 @@
         }
       }
     }
-
     caching.lastIndex = iterationIndex;
     return newValue;
-  } // based on @Toji's https://github.com/toji/gl-matrix/
+  }
 
-
+  // based on @Toji's https://github.com/toji/gl-matrix/
   function slerp(a, b, t) {
     var out = [];
     var ax = a[0];
@@ -3851,7 +3264,6 @@
     var scale0;
     var scale1;
     cosom = ax * bx + ay * by + az * bz + aw * bw;
-
     if (cosom < 0.0) {
       cosom = -cosom;
       bx = -bx;
@@ -3859,7 +3271,6 @@
       bz = -bz;
       bw = -bw;
     }
-
     if (1.0 - cosom > 0.000001) {
       omega = Math.acos(cosom);
       sinom = Math.sin(omega);
@@ -3869,14 +3280,12 @@
       scale0 = 1.0 - t;
       scale1 = t;
     }
-
     out[0] = scale0 * ax + scale1 * bx;
     out[1] = scale0 * ay + scale1 * by;
     out[2] = scale0 * az + scale1 * bz;
     out[3] = scale0 * aw + scale1 * bw;
     return out;
   }
-
   function quaternionToEuler(out, quat) {
     var qx = quat[0];
     var qy = quat[1];
@@ -3889,7 +3298,6 @@
     out[1] = attitude / degToRads;
     out[2] = bank / degToRads;
   }
-
   function createQuaternion(values) {
     var heading = values[0] * degToRads;
     var attitude = values[1] * degToRads;
@@ -3906,32 +3314,25 @@
     var z = c1 * s2 * c3 - s1 * c2 * s3;
     return [x, y, z, w];
   }
-
   function getValueAtCurrentTime() {
     var frameNum = this.comp.renderedFrame - this.offsetTime;
     var initTime = this.keyframes[0].t - this.offsetTime;
     var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
-
     if (!(frameNum === this._caching.lastFrame || this._caching.lastFrame !== initFrame && (this._caching.lastFrame >= endTime && frameNum >= endTime || this._caching.lastFrame < initTime && frameNum < initTime))) {
       if (this._caching.lastFrame >= frameNum) {
         this._caching._lastKeyframeIndex = -1;
         this._caching.lastIndex = 0;
       }
-
       var renderResult = this.interpolateValue(frameNum, this._caching);
       this.pv = renderResult;
     }
-
     this._caching.lastFrame = frameNum;
     return this.pv;
   }
-
   function setVValue(val) {
     var multipliedValue;
-
     if (this.propType === 'unidimensional') {
       multipliedValue = val * this.mult;
-
       if (mathAbs(this.v - multipliedValue) > 0.00001) {
         this.v = multipliedValue;
         this._mdf = true;
@@ -3939,51 +3340,41 @@
     } else {
       var i = 0;
       var len = this.v.length;
-
       while (i < len) {
         multipliedValue = val[i] * this.mult;
-
         if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
           this.v[i] = multipliedValue;
           this._mdf = true;
         }
-
         i += 1;
       }
     }
   }
-
   function processEffectsSequence() {
     if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
       return;
     }
-
     if (this.lock) {
       this.setVValue(this.pv);
       return;
     }
-
     this.lock = true;
     this._mdf = this._isFirstFrame;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = this.kf ? this.pv : this.data.k;
-
     for (i = 0; i < len; i += 1) {
       finalValue = this.effectsSequence[i](finalValue);
     }
-
     this.setVValue(finalValue);
     this._isFirstFrame = false;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   }
-
   function addEffect(effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.container.addDynamicProperty(this);
   }
-
   function ValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.mult = mult || 1;
@@ -4003,7 +3394,6 @@
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function MultiDimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     this.mult = mult || 1;
@@ -4020,19 +3410,16 @@
     this.v = createTypedArray('float32', len);
     this.pv = createTypedArray('float32', len);
     this.vel = createTypedArray('float32', len);
-
     for (i = 0; i < len; i += 1) {
       this.v[i] = data.k[i] * this.mult;
       this.pv[i] = data.k[i];
     }
-
     this._isFirstFrame = true;
     this.effectsSequence = [];
     this.getValue = processEffectsSequence;
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function KeyframedValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.keyframes = data.k;
@@ -4061,7 +3448,6 @@
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.addEffect = addEffect;
   }
-
   function KeyframedMultidimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     var i;
@@ -4070,19 +3456,16 @@
     var e;
     var to;
     var ti;
-
     for (i = 0; i < len - 1; i += 1) {
       if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
         s = data.k[i].s;
         e = data.k[i + 1].s;
         to = data.k[i].to;
         ti = data.k[i].ti;
-
         if (s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1]) || s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2])) {
           data.k[i].to = null;
           data.k[i].ti = null;
         }
-
         if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
           if (s.length === 2 || s[2] === e[2] && to[2] === 0 && ti[2] === 0) {
             data.k[i].to = null;
@@ -4091,7 +3474,6 @@
         }
       }
     }
-
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.data = data;
     this.keyframes = data.k;
@@ -4111,12 +3493,10 @@
     var arrLen = data.k[0].s.length;
     this.v = createTypedArray('float32', arrLen);
     this.pv = createTypedArray('float32', arrLen);
-
     for (i = 0; i < arrLen; i += 1) {
       this.v[i] = initFrame;
       this.pv[i] = initFrame;
     }
-
     this._caching = {
       lastFrame: initFrame,
       lastIndex: 0,
@@ -4124,15 +3504,12 @@
     };
     this.addEffect = addEffect;
   }
-
   var PropertyFactory = function () {
     function getProp(elem, data, type, mult, container) {
       if (data.sid) {
         data = elem.globalData.slotManager.getProp(data);
       }
-
       var p;
-
       if (!data.k.length) {
         p = new ValueProperty(elem, data, mult, container);
       } else if (typeof data.k[0] === 'number') {
@@ -4142,23 +3519,18 @@
           case 0:
             p = new KeyframedValueProperty(elem, data, mult, container);
             break;
-
           case 1:
             p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
             break;
-
           default:
             break;
         }
       }
-
       if (p.effectsSequence.length) {
         container.addDynamicProperty(p);
       }
-
       return p;
     }
-
     var ob = {
       getProp: getProp
     };
@@ -4166,7 +3538,6 @@
   }();
 
   function DynamicPropertyContainer() {}
-
   DynamicPropertyContainer.prototype = {
     addDynamicProperty: function addDynamicProperty(prop) {
       if (this.dynamicProperties.indexOf(prop) === -1) {
@@ -4179,10 +3550,8 @@
       this._mdf = false;
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         this.dynamicProperties[i].getValue();
-
         if (this.dynamicProperties[i]._mdf) {
           this._mdf = true;
         }
@@ -4200,7 +3569,6 @@
     function create() {
       return createTypedArray('float32', 2);
     }
-
     return poolFactory(8, create);
   }();
 
@@ -4212,12 +3580,10 @@
     this.o = createSizedArray(this._maxLength);
     this.i = createSizedArray(this._maxLength);
   }
-
   ShapePath.prototype.setPathData = function (closed, len) {
     this.c = closed;
     this.setLength(len);
     var i = 0;
-
     while (i < len) {
       this.v[i] = pointPool.newElement();
       this.o[i] = pointPool.newElement();
@@ -4225,62 +3591,49 @@
       i += 1;
     }
   };
-
   ShapePath.prototype.setLength = function (len) {
     while (this._maxLength < len) {
       this.doubleArrayLength();
     }
-
     this._length = len;
   };
-
   ShapePath.prototype.doubleArrayLength = function () {
     this.v = this.v.concat(createSizedArray(this._maxLength));
     this.i = this.i.concat(createSizedArray(this._maxLength));
     this.o = this.o.concat(createSizedArray(this._maxLength));
     this._maxLength *= 2;
   };
-
   ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
     var arr;
     this._length = Math.max(this._length, pos + 1);
-
     if (this._length >= this._maxLength) {
       this.doubleArrayLength();
     }
-
     switch (type) {
       case 'v':
         arr = this.v;
         break;
-
       case 'i':
         arr = this.i;
         break;
-
       case 'o':
         arr = this.o;
         break;
-
       default:
         arr = [];
         break;
     }
-
     if (!arr[pos] || arr[pos] && !replace) {
       arr[pos] = pointPool.newElement();
     }
-
     arr[pos][0] = x;
     arr[pos][1] = y;
   };
-
   ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
     this.setXYAt(vX, vY, 'v', pos, replace);
     this.setXYAt(oX, oY, 'o', pos, replace);
     this.setXYAt(iX, iY, 'i', pos, replace);
   };
-
   ShapePath.prototype.reverse = function () {
     var newPath = new ShapePath();
     newPath.setPathData(this.c, this._length);
@@ -4288,24 +3641,19 @@
     var outPoints = this.o;
     var inPoints = this.i;
     var init = 0;
-
     if (this.c) {
       newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
       init = 1;
     }
-
     var cnt = this._length - 1;
     var len = this._length;
     var i;
-
     for (i = init; i < len; i += 1) {
       newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
       cnt -= 1;
     }
-
     return newPath;
   };
-
   ShapePath.prototype.length = function () {
     return this._length;
   };
@@ -4314,11 +3662,9 @@
     function create() {
       return new ShapePath();
     }
-
     function release(shapePath) {
       var len = shapePath._length;
       var i;
-
       for (i = 0; i < len; i += 1) {
         pointPool.release(shapePath.v[i]);
         pointPool.release(shapePath.i[i]);
@@ -4327,25 +3673,20 @@
         shapePath.i[i] = null;
         shapePath.o[i] = null;
       }
-
       shapePath._length = 0;
       shapePath.c = false;
     }
-
     function clone(shape) {
       var cloned = factory.newElement();
       var i;
       var len = shape._length === undefined ? shape.v.length : shape._length;
       cloned.setLength(len);
       cloned.c = shape.c;
-
       for (i = 0; i < len; i += 1) {
         cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
       }
-
       return cloned;
     }
-
     var factory = poolFactory(4, create, release);
     factory.clone = clone;
     return factory;
@@ -4356,24 +3697,19 @@
     this._maxLength = 4;
     this.shapes = createSizedArray(this._maxLength);
   }
-
   ShapeCollection.prototype.addShape = function (shapeData) {
     if (this._length === this._maxLength) {
       this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
       this._maxLength *= 2;
     }
-
     this.shapes[this._length] = shapeData;
     this._length += 1;
   };
-
   ShapeCollection.prototype.releaseShapes = function () {
     var i;
-
     for (i = 0; i < this._length; i += 1) {
       shapePool.release(this.shapes[i]);
     }
-
     this._length = 0;
   };
 
@@ -4385,45 +3721,35 @@
     var _length = 0;
     var _maxLength = 4;
     var pool = createSizedArray(_maxLength);
-
     function newShapeCollection() {
       var shapeCollection;
-
       if (_length) {
         _length -= 1;
         shapeCollection = pool[_length];
       } else {
         shapeCollection = new ShapeCollection();
       }
-
       return shapeCollection;
     }
-
     function release(shapeCollection) {
       var i;
       var len = shapeCollection._length;
-
       for (i = 0; i < len; i += 1) {
         shapePool.release(shapeCollection.shapes[i]);
       }
-
       shapeCollection._length = 0;
-
       if (_length === _maxLength) {
         pool = pooling["double"](pool);
         _maxLength *= 2;
       }
-
       pool[_length] = shapeCollection;
       _length += 1;
     }
-
     return ob;
   }();
 
   var ShapePropertyFactory = function () {
     var initFrame = -999999;
-
     function interpolateShape(frameNum, previousValue, caching) {
       var iterationIndex = caching.lastIndex;
       var keyPropS;
@@ -4436,7 +3762,6 @@
       var perc;
       var vertexValue;
       var kf = this.keyframes;
-
       if (frameNum < kf[0].t - this.offsetTime) {
         keyPropS = kf[0].s[0];
         isHold = true;
@@ -4448,7 +3773,6 @@
               }else{
                   keyPropS = kf[kf.length - 2].e[0];
               } */
-
         isHold = true;
       } else {
         var i = iterationIndex;
@@ -4457,26 +3781,21 @@
         var keyData;
         var nextKeyData;
         var keyframeMetadata;
-
         while (flag) {
           keyData = kf[i];
           nextKeyData = kf[i + 1];
-
           if (nextKeyData.t - this.offsetTime > frameNum) {
             break;
           }
-
           if (i < len - 1) {
             i += 1;
           } else {
             flag = false;
           }
         }
-
         keyframeMetadata = this.keyframesMetadata[i] || {};
         isHold = keyData.h === 1;
         iterationIndex = i;
-
         if (!isHold) {
           if (frameNum >= nextKeyData.t - this.offsetTime) {
             perc = 1;
@@ -4484,27 +3803,21 @@
             perc = 0;
           } else {
             var fnc;
-
             if (keyframeMetadata.__fnct) {
               fnc = keyframeMetadata.__fnct;
             } else {
               fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
               keyframeMetadata.__fnct = fnc;
             }
-
             perc = fnc((frameNum - (keyData.t - this.offsetTime)) / (nextKeyData.t - this.offsetTime - (keyData.t - this.offsetTime)));
           }
-
           keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
         }
-
         keyPropS = keyData.s[0];
       }
-
       jLen = previousValue._length;
       kLen = keyPropS.i[0].length;
       caching.lastIndex = iterationIndex;
-
       for (j = 0; j < jLen; j += 1) {
         for (k = 0; k < kLen; k += 1) {
           vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
@@ -4516,44 +3829,36 @@
         }
       }
     }
-
     function interpolateShapeCurrentTime() {
       var frameNum = this.comp.renderedFrame - this.offsetTime;
       var initTime = this.keyframes[0].t - this.offsetTime;
       var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
       var lastFrame = this._caching.lastFrame;
-
       if (!(lastFrame !== initFrame && (lastFrame < initTime && frameNum < initTime || lastFrame > endTime && frameNum > endTime))) {
         /// /
         this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
-        this.interpolateShape(frameNum, this.pv, this._caching); /// /
+        this.interpolateShape(frameNum, this.pv, this._caching);
+        /// /
       }
-
       this._caching.lastFrame = frameNum;
       return this.pv;
     }
-
     function resetShape() {
       this.paths = this.localShapeCollection;
     }
-
     function shapesEqual(shape1, shape2) {
       if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
         return false;
       }
-
       var i;
       var len = shape1._length;
-
       for (i = 0; i < len; i += 1) {
         if (shape1.v[i][0] !== shape2.v[i][0] || shape1.v[i][1] !== shape2.v[i][1] || shape1.o[i][0] !== shape2.o[i][0] || shape1.o[i][1] !== shape2.o[i][1] || shape1.i[i][0] !== shape2.i[i][0] || shape1.i[i][1] !== shape2.i[i][1]) {
           return false;
         }
       }
-
       return true;
     }
-
     function setVValue(newPath) {
       if (!shapesEqual(this.v, newPath)) {
         this.v = shapePool.clone(newPath);
@@ -4563,26 +3868,21 @@
         this.paths = this.localShapeCollection;
       }
     }
-
     function processEffectsSequence() {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (!this.effectsSequence.length) {
         this._mdf = false;
         return;
       }
-
       if (this.lock) {
         this.setVValue(this.pv);
         return;
       }
-
       this.lock = true;
       this._mdf = false;
       var finalValue;
-
       if (this.kf) {
         finalValue = this.pv;
       } else if (this.data.ks) {
@@ -4590,19 +3890,15 @@
       } else {
         finalValue = this.data.pt.k;
       }
-
       var i;
       var len = this.effectsSequence.length;
-
       for (i = 0; i < len; i += 1) {
         finalValue = this.effectsSequence[i](finalValue);
       }
-
       this.setVValue(finalValue);
       this.lock = false;
       this.frameId = this.elem.globalData.frameId;
     }
-
     function ShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4621,17 +3917,14 @@
       this.reset = resetShape;
       this.effectsSequence = [];
     }
-
     function addEffect(effectFunction) {
       this.effectsSequence.push(effectFunction);
       this.container.addDynamicProperty(this);
     }
-
     ShapeProperty.prototype.interpolateShape = interpolateShape;
     ShapeProperty.prototype.getValue = processEffectsSequence;
     ShapeProperty.prototype.setVValue = setVValue;
     ShapeProperty.prototype.addEffect = addEffect;
-
     function KeyframedShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4657,15 +3950,12 @@
       };
       this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
     }
-
     KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
     KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
     KeyframedShapeProperty.prototype.setVValue = setVValue;
     KeyframedShapeProperty.prototype.addEffect = addEffect;
-
     var EllShapeProperty = function () {
       var cPoint = roundCorner;
-
       function EllShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
         this.v.setPathData(true, 4);
@@ -4679,7 +3969,6 @@
         this.initDynamicPropertyContainer(elem);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4687,17 +3976,14 @@
           this.convertEllToPath();
         }
       }
-
       EllShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertEllToPath();
           }
@@ -4707,9 +3993,7 @@
           var p1 = this.p.v[1];
           var s0 = this.s.v[0] / 2;
           var s1 = this.s.v[1] / 2;
-
           var _cw = this.d !== 3;
-
           var _v = this.v;
           _v.v[0][0] = p0;
           _v.v[0][1] = p1 - s1;
@@ -4740,7 +4024,6 @@
       extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
       return EllShapePropertyFactory;
     }();
-
     var StarShapeProperty = function () {
       function StarShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4751,7 +4034,6 @@
         this.frameId = -1;
         this.d = data.d;
         this.initDynamicPropertyContainer(elem);
-
         if (data.sy === 1) {
           this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
           this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
@@ -4759,7 +4041,6 @@
         } else {
           this.convertToPath = this.convertPolygonToPath;
         }
-
         this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
@@ -4768,7 +4049,6 @@
         this.localShapeCollection = shapeCollectionPool.newShapeCollection();
         this.localShapeCollection.addShape(this.v);
         this.paths = this.localShapeCollection;
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4776,17 +4056,14 @@
           this.convertToPath();
         }
       }
-
       StarShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertToPath();
           }
@@ -4797,7 +4074,6 @@
           /* this.v.v.length = numPts;
                   this.v.i.length = numPts;
                   this.v.o.length = numPts; */
-
           var longFlag = true;
           var longRad = this.or.v;
           var shortRad = this.ir.v;
@@ -4813,7 +4089,6 @@
           currentAng += this.r.v;
           var dir = this.data.d === 3 ? -1 : 1;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             rad = longFlag ? longRad : shortRad;
             roundness = longFlag ? longRound : shortRound;
@@ -4825,11 +4100,11 @@
             x += +this.p.v[0];
             y += +this.p.v[1];
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
             /* this.v.v[i] = [x,y];
                       this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
                       this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
                       this.v._length = numPts; */
-
             longFlag = !longFlag;
             currentAng += angle * dir;
           }
@@ -4845,7 +4120,6 @@
           var dir = this.data.d === 3 ? -1 : 1;
           currentAng += this.r.v;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             var x = rad * Math.cos(currentAng);
             var y = rad * Math.sin(currentAng);
@@ -4856,7 +4130,6 @@
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
             currentAng += angle * dir;
           }
-
           this.paths.length = 0;
           this.paths[0] = this.v;
         }
@@ -4864,7 +4137,6 @@
       extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
       return StarShapePropertyFactory;
     }();
-
     var RectShapeProperty = function () {
       function RectShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4880,7 +4152,6 @@
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4888,7 +4159,6 @@
           this.convertRectToPath();
         }
       }
-
       RectShapePropertyFactory.prototype = {
         convertRectToPath: function convertRectToPath() {
           var p0 = this.p.v[0];
@@ -4898,11 +4168,9 @@
           var round = bmMin(v0, v1, this.r.v);
           var cPoint = round * (1 - roundCorner);
           this.v._length = 0;
-
           if (this.d === 2 || this.d === 1) {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
             this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
               this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
@@ -4916,7 +4184,6 @@
             }
           } else {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
               this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
@@ -4936,10 +4203,8 @@
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertRectToPath();
           }
@@ -4949,14 +4214,11 @@
       extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
       return RectShapePropertyFactory;
     }();
-
     function getShapeProp(elem, data, type) {
       var prop;
-
       if (type === 3 || type === 4) {
         var dataProp = type === 3 ? data.pt : data.ks;
         var keys = dataProp.k;
-
         if (keys.length) {
           prop = new KeyframedShapeProperty(elem, data, type);
         } else {
@@ -4969,22 +4231,17 @@
       } else if (type === 7) {
         prop = new StarShapeProperty(elem, data);
       }
-
       if (prop.k) {
         elem.addDynamicProperty(prop);
       }
-
       return prop;
     }
-
     function getConstructorFunction() {
       return ShapeProperty;
     }
-
     function getKeyframedConstructorFunction() {
       return KeyframedShapeProperty;
     }
-
     var ob = {};
     ob.getShapeProp = getShapeProp;
     ob.getConstructorFunction = getConstructorFunction;
@@ -5026,7 +4283,6 @@
     var _sin = Math.sin;
     var _tan = Math.tan;
     var _rnd = Math.round;
-
     function reset() {
       this.props[0] = 1;
       this.props[1] = 0;
@@ -5046,83 +4302,59 @@
       this.props[15] = 1;
       return this;
     }
-
     function rotate(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function rotateX(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateY(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateZ(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function shear(sx, sy) {
       return this._t(1, sy, sx, 1, 0, 0);
     }
-
     function skew(ax, ay) {
       return this.shear(_tan(ax), _tan(ay));
     }
-
     function skewFromAxis(ax, angle) {
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
-      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+      // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
     }
-
     function scale(sx, sy, sz) {
       if (!sz && sz !== 0) {
         sz = 1;
       }
-
       if (sx === 1 && sy === 1 && sz === 1) {
         return this;
       }
-
       return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
     }
-
     function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
       this.props[0] = a;
       this.props[1] = b;
@@ -5142,32 +4374,26 @@
       this.props[15] = p;
       return this;
     }
-
     function translate(tx, ty, tz) {
       tz = tz || 0;
-
       if (tx !== 0 || ty !== 0 || tz !== 0) {
         return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
       }
-
       return this;
     }
-
     function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
       var _p = this.props;
-
       if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
         // NOTE: commenting this condition because TurboFan deoptimizes code when present
         // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
         _p[12] = _p[12] * a2 + _p[15] * m2;
         _p[13] = _p[13] * f2 + _p[15] * n2;
         _p[14] = _p[14] * k2 + _p[15] * o2;
-        _p[15] *= p2; // }
-
+        _p[15] *= p2;
+        // }
         this._identityCalculated = false;
         return this;
       }
-
       var a1 = _p[0];
       var b1 = _p[1];
       var c1 = _p[2];
@@ -5184,12 +4410,12 @@
       var n1 = _p[13];
       var o1 = _p[14];
       var p1 = _p[15];
+
       /* matrix order (canvas compatible):
            * ace
            * bdf
            * 001
            */
-
       _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
       _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
       _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
@@ -5209,53 +4435,40 @@
       this._identityCalculated = false;
       return this;
     }
-
     function multiply(matrix) {
       var matrixProps = matrix.props;
       return this.transform(matrixProps[0], matrixProps[1], matrixProps[2], matrixProps[3], matrixProps[4], matrixProps[5], matrixProps[6], matrixProps[7], matrixProps[8], matrixProps[9], matrixProps[10], matrixProps[11], matrixProps[12], matrixProps[13], matrixProps[14], matrixProps[15]);
     }
-
     function isIdentity() {
       if (!this._identityCalculated) {
         this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
         this._identityCalculated = true;
       }
-
       return this._identity;
     }
-
     function equals(matr) {
       var i = 0;
-
       while (i < 16) {
         if (matr.props[i] !== this.props[i]) {
           return false;
         }
-
         i += 1;
       }
-
       return true;
     }
-
     function clone(matr) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         matr.props[i] = this.props[i];
       }
-
       return matr;
     }
-
     function cloneFromProps(props) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         this.props[i] = props[i];
       }
     }
-
     function applyToPoint(x, y, z) {
       return {
         x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
@@ -5267,19 +4480,15 @@
            y: x * me.b + y * me.d + me.f
            }; */
     }
-
     function applyToX(x, y, z) {
       return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
     }
-
     function applyToY(x, y, z) {
       return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
     }
-
     function applyToZ(x, y, z) {
       return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
     }
-
     function getInverseMatrix() {
       var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
       var a = this.props[5] / determinant;
@@ -5297,27 +4506,21 @@
       inverseMatrix.props[13] = f;
       return inverseMatrix;
     }
-
     function inversePoint(pt) {
       var inverseMatrix = this.getInverseMatrix();
       return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
     }
-
     function inversePoints(pts) {
       var i;
       var len = pts.length;
       var retPts = [];
-
       for (i = 0; i < len; i += 1) {
         retPts[i] = inversePoint(pts[i]);
       }
-
       return retPts;
     }
-
     function applyToTriplePoints(pt1, pt2, pt3) {
       var arr = createTypedArray('float32', 6);
-
       if (this.isIdentity()) {
         arr[0] = pt1[0];
         arr[1] = pt1[1];
@@ -5339,34 +4542,26 @@
         arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
         arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
       }
-
       return arr;
     }
-
     function applyToPointArray(x, y, z) {
       var arr;
-
       if (this.isIdentity()) {
         arr = [x, y, z];
       } else {
         arr = [x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12], x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13], x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14]];
       }
-
       return arr;
     }
-
     function applyToPointStringified(x, y) {
       if (this.isIdentity()) {
         return x + ',' + y;
       }
-
       var _p = this.props;
       return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
     }
-
     function toCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
@@ -5374,49 +4569,34 @@
       var props = this.props;
       var cssValue = 'matrix3d(';
       var v = 10000;
-
       while (i < 16) {
         cssValue += _rnd(props[i] * v) / v;
         cssValue += i === 15 ? ')' : ',';
         i += 1;
       }
-
       return cssValue;
     }
-
     function roundMatrixProperty(val) {
       var v = 10000;
-
       if (val < 0.000001 && val > 0 || val > -0.000001 && val < 0) {
         return _rnd(val * v) / v;
       }
-
       return val;
     }
-
     function to2dCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
       var props = this.props;
-
       var _a = roundMatrixProperty(props[0]);
-
       var _b = roundMatrixProperty(props[1]);
-
       var _c = roundMatrixProperty(props[4]);
-
       var _d = roundMatrixProperty(props[5]);
-
       var _e = roundMatrixProperty(props[12]);
-
       var _f = roundMatrixProperty(props[13]);
-
       return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
     }
-
     return function () {
       this.reset = reset;
       this.rotate = rotate;
@@ -5455,16 +4635,14 @@
     };
   }();
 
-  function _typeof$3(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$3 = function _typeof(obj) { return typeof obj; }; } else { _typeof$3 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$3(obj); }
+  function _typeof$3(o) { "@babel/helpers - typeof"; return _typeof$3 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$3(o); }
   var lottie = {};
   var standalone = '__[STANDALONE]__';
   var animationData = '__[ANIMATIONDATA]__';
   var renderer = '';
-
   function setLocation(href) {
     setLocationHref(href);
   }
-
   function searchAnimations() {
     if (standalone === true) {
       animationManager.searchAnimations(animationData, standalone, renderer);
@@ -5472,35 +4650,28 @@
       animationManager.searchAnimations();
     }
   }
-
   function setSubframeRendering(flag) {
     setSubframeEnabled(flag);
   }
-
   function setPrefix(prefix) {
     setIdPrefix(prefix);
   }
-
   function loadAnimation(params) {
     if (standalone === true) {
       params.animationData = JSON.parse(animationData);
     }
-
     return animationManager.loadAnimation(params);
   }
-
   function setQuality(value) {
     if (typeof value === 'string') {
       switch (value) {
         case 'high':
           setDefaultCurveSegments(200);
           break;
-
         default:
         case 'medium':
           setDefaultCurveSegments(50);
           break;
-
         case 'low':
           setDefaultCurveSegments(10);
           break;
@@ -5508,40 +4679,32 @@
     } else if (!isNaN(value) && value > 1) {
       setDefaultCurveSegments(value);
     }
-
     if (getDefaultCurveSegments() >= 50) {
       roundValues(false);
     } else {
       roundValues(true);
     }
   }
-
   function inBrowser() {
     return typeof navigator !== 'undefined';
   }
-
   function installPlugin(type, plugin) {
     if (type === 'expressions') {
       setExpressionsPlugin(plugin);
     }
   }
-
   function getFactory(name) {
     switch (name) {
       case 'propertyFactory':
         return PropertyFactory;
-
       case 'shapePropertyFactory':
         return ShapePropertyFactory;
-
       case 'matrix':
         return Matrix;
-
       default:
         return null;
     }
   }
-
   lottie.play = animationManager.play;
   lottie.pause = animationManager.pause;
   lottie.setLocationHref = setLocation;
@@ -5553,8 +4716,8 @@
   lottie.registerAnimation = animationManager.registerAnimation;
   lottie.loadAnimation = loadAnimation;
   lottie.setSubframeRendering = setSubframeRendering;
-  lottie.resize = animationManager.resize; // lottie.start = start;
-
+  lottie.resize = animationManager.resize;
+  // lottie.start = start;
   lottie.goToAndStop = animationManager.goToAndStop;
   lottie.destroy = animationManager.destroy;
   lottie.setQuality = setQuality;
@@ -5569,32 +4732,25 @@
   lottie.useWebWorker = setWebWorker;
   lottie.setIDPrefix = setPrefix;
   lottie.__getFactory = getFactory;
-  lottie.version = '5.12.2';
-
+  lottie.version = '5.13.0';
   function checkReady() {
     if (document.readyState === 'complete') {
       clearInterval(readyStateCheckInterval);
       searchAnimations();
     }
   }
-
   function getQueryVariable(variable) {
     var vars = queryString.split('&');
-
     for (var i = 0; i < vars.length; i += 1) {
       var pair = vars[i].split('=');
-
       if (decodeURIComponent(pair[0]) == variable) {
         // eslint-disable-line eqeqeq
         return decodeURIComponent(pair[1]);
       }
     }
-
     return null;
   }
-
   var queryString = '';
-
   if (standalone) {
     var scripts = document.getElementsByTagName('script');
     var index = scripts.length - 1;
@@ -5602,18 +4758,18 @@
       src: ''
     };
     queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
-
     renderer = getQueryVariable('renderer');
   }
+  var readyStateCheckInterval = setInterval(checkReady, 100);
 
-  var readyStateCheckInterval = setInterval(checkReady, 100); // this adds bodymovin to the window object for backwards compatibility
-
+  // this adds bodymovin to the window object for backwards compatibility
   try {
     if (!((typeof exports === "undefined" ? "undefined" : _typeof$3(exports)) === 'object' && typeof module !== 'undefined') && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
     ) {
       window.bodymovin = lottie;
     }
-  } catch (err) {//
+  } catch (err) {
+    //
   }
 
   var ShapeModifiers = function () {
@@ -5621,26 +4777,19 @@
     var modifiers = {};
     ob.registerModifier = registerModifier;
     ob.getModifier = getModifier;
-
     function registerModifier(nm, factory) {
       if (!modifiers[nm]) {
         modifiers[nm] = factory;
       }
     }
-
     function getModifier(nm, elem, data) {
       return new modifiers[nm](elem, data);
     }
-
     return ob;
   }();
-
   function ShapeModifier() {}
-
   ShapeModifier.prototype.initModifierProperties = function () {};
-
   ShapeModifier.prototype.addShapeToModifier = function () {};
-
   ShapeModifier.prototype.addShape = function (data) {
     if (!this.closed) {
       // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
@@ -5652,13 +4801,11 @@
       };
       this.shapes.push(shapeData);
       this.addShapeToModifier(shapeData);
-
       if (this._isAnimated) {
         data.setAsAnimated();
       }
     }
   };
-
   ShapeModifier.prototype.init = function (elem, data) {
     this.shapes = [];
     this.elem = elem;
@@ -5667,29 +4814,23 @@
     this.frameId = initialDefaultFrame;
     this.closed = false;
     this.k = false;
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   ShapeModifier.prototype.processKeys = function () {
     if (this.elem.globalData.frameId === this.frameId) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   extendPrototype([DynamicPropertyContainer], ShapeModifier);
 
   function TrimModifier() {}
-
   extendPrototype([ShapeModifier], TrimModifier);
-
   TrimModifier.prototype.initModifierProperties = function (elem, data) {
     this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
     this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
@@ -5700,14 +4841,11 @@
     this.m = data.m;
     this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
   };
-
   TrimModifier.prototype.addShapeToModifier = function (shapeData) {
     shapeData.pathsData = [];
   };
-
   TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
     var segments = [];
-
     if (e <= 1) {
       segments.push({
         s: s,
@@ -5728,65 +4866,50 @@
         e: e - 1
       });
     }
-
     var shapeSegments = [];
     var i;
     var len = segments.length;
     var segmentOb;
-
     for (i = 0; i < len; i += 1) {
       segmentOb = segments[i];
-
       if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
         var shapeS;
         var shapeE;
-
         if (segmentOb.s * totalModifierLength <= addedLength) {
           shapeS = 0;
         } else {
           shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
         }
-
         if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
           shapeE = 1;
         } else {
           shapeE = (segmentOb.e * totalModifierLength - addedLength) / shapeLength;
         }
-
         shapeSegments.push([shapeS, shapeE]);
       }
     }
-
     if (!shapeSegments.length) {
       shapeSegments.push([0, 0]);
     }
-
     return shapeSegments;
   };
-
   TrimModifier.prototype.releasePathsData = function (pathsData) {
     var i;
     var len = pathsData.length;
-
     for (i = 0; i < len; i += 1) {
       segmentsLengthPool.release(pathsData[i]);
     }
-
     pathsData.length = 0;
     return pathsData;
   };
-
   TrimModifier.prototype.processShapes = function (_isFirstFrame) {
     var s;
     var e;
-
     if (this._mdf || _isFirstFrame) {
       var o = this.o.v % 360 / 360;
-
       if (o < 0) {
         o += 1;
       }
-
       if (this.s.v > 1) {
         s = 1 + o;
       } else if (this.s.v < 0) {
@@ -5794,7 +4917,6 @@
       } else {
         s = this.s.v + o;
       }
-
       if (this.e.v > 1) {
         e = 1 + o;
       } else if (this.e.v < 0) {
@@ -5802,13 +4924,11 @@
       } else {
         e = this.e.v + o;
       }
-
       if (s > e) {
         var _s = s;
         s = e;
         e = _s;
       }
-
       s = Math.round(s * 10000) * 0.0001;
       e = Math.round(e * 10000) * 0.0001;
       this.sValue = s;
@@ -5817,7 +4937,6 @@
       s = this.sValue;
       e = this.eValue;
     }
-
     var shapePaths;
     var i;
     var len = this.shapes.length;
@@ -5827,13 +4946,11 @@
     var pathData;
     var totalShapeLength;
     var totalModifierLength = 0;
-
     if (e === s) {
       for (i = 0; i < len; i += 1) {
         this.shapes[i].localShapeCollection.releaseShapes();
         this.shapes[i].shape._mdf = true;
         this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
-
         if (this._mdf) {
           this.shapes[i].pathsData.length = 0;
         }
@@ -5842,63 +4959,52 @@
       var segments = [];
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
-        shapeData = this.shapes[i]; // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
-
+        shapeData = this.shapes[i];
+        // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
         if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
           shapeData.shape.paths = shapeData.localShapeCollection;
         } else {
           shapePaths = shapeData.shape.paths;
           jLen = shapePaths._length;
           totalShapeLength = 0;
-
           if (!shapeData.shape._mdf && shapeData.pathsData.length) {
             totalShapeLength = shapeData.totalShapeLength;
           } else {
             pathsData = this.releasePathsData(shapeData.pathsData);
-
             for (j = 0; j < jLen; j += 1) {
               pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
               pathsData.push(pathData);
               totalShapeLength += pathData.totalLength;
             }
-
             shapeData.totalShapeLength = totalShapeLength;
             shapeData.pathsData = pathsData;
           }
-
           totalModifierLength += totalShapeLength;
           shapeData.shape._mdf = true;
         }
       }
-
       var shapeS = s;
       var shapeE = e;
       var addedLength = 0;
       var edges;
-
       for (i = len - 1; i >= 0; i -= 1) {
         shapeData = this.shapes[i];
-
         if (shapeData.shape._mdf) {
           localShapeCollection = shapeData.localShapeCollection;
-          localShapeCollection.releaseShapes(); // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
-
+          localShapeCollection.releaseShapes();
+          // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
           if (this.m === 2 && len > 1) {
             edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
             addedLength += shapeData.totalShapeLength;
           } else {
             edges = [[shapeS, shapeE]];
           }
-
           jLen = edges.length;
-
           for (j = 0; j < jLen; j += 1) {
             shapeS = edges[j][0];
             shapeE = edges[j][1];
             segments.length = 0;
-
             if (shapeE <= 1) {
               segments.push({
                 s: shapeData.totalShapeLength * shapeS,
@@ -5919,13 +5025,10 @@
                 e: shapeData.totalShapeLength * (shapeE - 1)
               });
             }
-
             var newShapesData = this.addShapes(shapeData, segments[0]);
-
             if (segments[0].s !== segments[0].e) {
               if (segments.length > 1) {
                 var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
-
                 if (lastShapeInCollection.c) {
                   var lastShape = newShapesData.pop();
                   this.addPaths(newShapesData, localShapeCollection);
@@ -5935,11 +5038,9 @@
                   newShapesData = this.addShapes(shapeData, segments[1]);
                 }
               }
-
               this.addPaths(newShapesData, localShapeCollection);
             }
           }
-
           shapeData.shape.paths = localShapeCollection;
         }
       }
@@ -5952,38 +5053,29 @@
       }
     }
   };
-
   TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
     var i;
     var len = newPaths.length;
-
     for (i = 0; i < len; i += 1) {
       localShapeCollection.addShape(newPaths[i]);
     }
   };
-
   TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
     shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
     shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
     }
-
     shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
     shapePath.setXYAt(points[1], points[5], 'o', pos);
     shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(points[0], points[4], 'v', pos);
     }
-
     shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
     var pathsData = shapeData.pathsData;
     var shapePaths = shapeData.shape.paths.shapes;
@@ -5999,7 +5091,6 @@
     var shapes = [];
     var initPos;
     var newShape = true;
-
     if (!shapePath) {
       shapePath = shapePool.newElement();
       segmentCount = 0;
@@ -6008,17 +5099,13 @@
       segmentCount = shapePath._length;
       initPos = shapePath._length;
     }
-
     shapes.push(shapePath);
-
     for (i = 0; i < len; i += 1) {
       lengths = pathsData[i].lengths;
       shapePath.c = shapePaths[i].c;
       jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
-
       for (j = 1; j < jLen; j += 1) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
           addedLength += currentLengthData.addedLength;
           shapePath.c = false;
@@ -6031,50 +5118,42 @@
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
-
           addedLength += currentLengthData.addedLength;
           segmentCount += 1;
         }
       }
-
       if (shapePaths[i].c && lengths.length) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength <= shapeSegment.e) {
           var segmentLength = lengths[j - 1].addedLength;
-
           if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
             this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
         } else {
           shapePath.c = false;
         }
-
         addedLength += currentLengthData.addedLength;
         segmentCount += 1;
       }
-
       if (shapePath._length) {
         shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
         shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
       }
-
       if (addedLength > shapeSegment.e) {
         break;
       }
-
       if (i < len - 1) {
         shapePath = shapePool.newElement();
         newShape = true;
@@ -6082,31 +5161,25 @@
         segmentCount = 0;
       }
     }
-
     return shapes;
   };
 
   function PuckerAndBloatModifier() {}
-
   extendPrototype([ShapeModifier], PuckerAndBloatModifier);
-
   PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
     this._isAnimated = !!this.amount.effectsSequence.length;
   };
-
   PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
     var percent = amount / 100;
     var centerPoint = [0, 0];
     var pathLength = path._length;
     var i = 0;
-
     for (i = 0; i < pathLength; i += 1) {
       centerPoint[0] += path.v[i][0];
       centerPoint[1] += path.v[i][1];
     }
-
     centerPoint[0] /= pathLength;
     centerPoint[1] /= pathLength;
     var clonedPath = shapePool.newElement();
@@ -6117,7 +5190,6 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < pathLength; i += 1) {
       vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
       vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
@@ -6127,10 +5199,8 @@
       iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
       clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
     }
-
     return clonedPath;
   };
-
   PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6138,30 +5208,24 @@
     var j;
     var jLen;
     var amount = this.amount.v;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6169,30 +5233,24 @@
 
   var TransformPropertyFactory = function () {
     var defaultVector = [0, 0];
-
     function applyToMatrix(mat) {
       var _mdf = this._mdf;
       this.iterateDynamicProperties();
       this._mdf = this._mdf || _mdf;
-
       if (this.a) {
         mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
       }
-
       if (this.s) {
         mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
       }
-
       if (this.sk) {
         mat.skewFromAxis(-this.sk.v, this.sa.v);
       }
-
       if (this.r) {
         mat.rotate(-this.r.v);
       } else {
         mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
       }
-
       if (this.data.p.s) {
         if (this.data.p.z) {
           mat.translate(this.px.v, this.py.v, -this.pz.v);
@@ -6203,46 +5261,36 @@
         mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
       }
     }
-
     function processKeys(forceRender) {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (this._isDirty) {
         this.precalculateMatrix();
         this._isDirty = false;
       }
-
       this.iterateDynamicProperties();
-
       if (this._mdf || forceRender) {
         var frameRate;
         this.v.cloneFromProps(this.pre.props);
-
         if (this.appliedTransformations < 1) {
           this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         }
-
         if (this.appliedTransformations < 2) {
           this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         }
-
         if (this.sk && this.appliedTransformations < 3) {
           this.v.skewFromAxis(-this.sk.v, this.sa.v);
         }
-
         if (this.r && this.appliedTransformations < 4) {
           this.v.rotate(-this.r.v);
         } else if (!this.r && this.appliedTransformations < 4) {
           this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
         }
-
         if (this.autoOriented) {
           var v1;
           var v2;
           frameRate = this.elem.globalData.frameRate;
-
           if (this.p && this.p.keyframes && this.p.getValueAtTime) {
             if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
               v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
@@ -6259,7 +5307,6 @@
             v2 = [];
             var px = this.px;
             var py = this.py;
-
             if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
               v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
               v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
@@ -6279,10 +5326,8 @@
             v2 = defaultVector;
             v1 = v2;
           }
-
           this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
         }
-
         if (this.data.p && this.data.p.s) {
           if (this.data.p.z) {
             this.v.translate(this.px.v, this.py.v, -this.pz.v);
@@ -6293,28 +5338,23 @@
           this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
         }
       }
-
       this.frameId = this.elem.globalData.frameId;
     }
-
     function precalculateMatrix() {
       this.appliedTransformations = 0;
       this.pre.reset();
-
       if (!this.a.effectsSequence.length) {
         this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         this.appliedTransformations = 1;
       } else {
         return;
       }
-
       if (!this.s.effectsSequence.length) {
         this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         this.appliedTransformations = 2;
       } else {
         return;
       }
-
       if (this.sk) {
         if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
           this.pre.skewFromAxis(-this.sk.v, this.sa.v);
@@ -6323,7 +5363,6 @@
           return;
         }
       }
-
       if (this.r) {
         if (!this.r.effectsSequence.length) {
           this.pre.rotate(-this.r.v);
@@ -6334,33 +5373,28 @@
         this.appliedTransformations = 4;
       }
     }
-
-    function autoOrient() {//
+    function autoOrient() {
+      //
       // var prevP = this.getValueAtTime();
     }
-
     function addDynamicProperty(prop) {
       this._addDynamicProperty(prop);
-
       this.elem.addDynamicProperty(prop);
       this._isDirty = true;
     }
-
     function TransformProperty(elem, data, container) {
       this.elem = elem;
       this.frameId = -1;
       this.propType = 'transform';
       this.data = data;
-      this.v = new Matrix(); // Precalculated matrix with non animated properties
-
+      this.v = new Matrix();
+      // Precalculated matrix with non animated properties
       this.pre = new Matrix();
       this.appliedTransformations = 0;
       this.initDynamicPropertyContainer(container || elem);
-
       if (data.p && data.p.s) {
         this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
         this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
-
         if (data.p.z) {
           this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
         }
@@ -6369,43 +5403,37 @@
           k: [0, 0, 0]
         }, 1, 0, this);
       }
-
       if (data.rx) {
         this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
         this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
         this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
-
         if (data.or.k[0].ti) {
           var i;
           var len = data.or.k.length;
-
           for (i = 0; i < len; i += 1) {
             data.or.k[i].to = null;
             data.or.k[i].ti = null;
           }
         }
-
-        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this); // sh Indicates it needs to be capped between -180 and 180
-
+        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+        // sh Indicates it needs to be capped between -180 and 180
         this.or.sh = true;
       } else {
         this.r = PropertyFactory.getProp(elem, data.r || {
           k: 0
         }, 0, degToRads, this);
       }
-
       if (data.sk) {
         this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
         this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
       }
-
       this.a = PropertyFactory.getProp(elem, data.a || {
         k: [0, 0, 0]
       }, 1, 0, this);
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: [100, 100, 100]
-      }, 1, 0.01, this); // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
-
+      }, 1, 0.01, this);
+      // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
       if (data.o) {
         this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
       } else {
@@ -6414,14 +5442,11 @@
           v: 1
         };
       }
-
       this._isDirty = true;
-
       if (!this.dynamicProperties.length) {
         this.getValue(true);
       }
     }
-
     TransformProperty.prototype = {
       applyToMatrix: applyToMatrix,
       getValue: processKeys,
@@ -6431,20 +5456,16 @@
     extendPrototype([DynamicPropertyContainer], TransformProperty);
     TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
     TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
-
     function getTransformProperty(elem, data, container) {
       return new TransformProperty(elem, data, container);
     }
-
     return {
       getTransformProperty: getTransformProperty
     };
   }();
 
   function RepeaterModifier() {}
-
   extendPrototype([ShapeModifier], RepeaterModifier);
-
   RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
@@ -6453,11 +5474,9 @@
     this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
     this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
     this.data = data;
-
     if (!this.dynamicProperties.length) {
       this.getValue(true);
     }
-
     this._isAnimated = !!this.dynamicProperties.length;
     this.pMatrix = new Matrix();
     this.rMatrix = new Matrix();
@@ -6465,7 +5484,6 @@
     this.tMatrix = new Matrix();
     this.matrix = new Matrix();
   };
-
   RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
     var dir = inv ? -1 : 1;
     var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
@@ -6478,7 +5496,6 @@
     sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
     sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
   };
-
   RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
     this.elem = elem;
     this.arr = arr;
@@ -6490,52 +5507,42 @@
     this.frameId = -1;
     this.initDynamicPropertyContainer(elem);
     this.initModifierProperties(elem, arr[pos]);
-
     while (pos > 0) {
-      pos -= 1; // this._elements.unshift(arr.splice(pos,1)[0]);
-
+      pos -= 1;
+      // this._elements.unshift(arr.splice(pos,1)[0]);
       this._elements.unshift(arr[pos]);
     }
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   RepeaterModifier.prototype.resetElements = function (elements) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._processed = false;
-
       if (elements[i].ty === 'gr') {
         this.resetElements(elements[i].it);
       }
     }
   };
-
   RepeaterModifier.prototype.cloneElements = function (elements) {
     var newElements = JSON.parse(JSON.stringify(elements));
     this.resetElements(newElements);
     return newElements;
   };
-
   RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._render = renderFlag;
-
       if (elements[i].ty === 'gr') {
         this.changeGroupRender(elements[i].it, renderFlag);
       }
     }
   };
-
   RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
     var items;
     var itemsTransform;
@@ -6543,10 +5550,8 @@
     var dir;
     var cont;
     var hasReloaded = false;
-
     if (this._mdf || _isFirstFrame) {
       var copies = Math.ceil(this.c.v);
-
       if (this._groups.length < copies) {
         while (this._groups.length < copies) {
           var group = {
@@ -6601,28 +5606,21 @@
             ty: 'tr'
           });
           this.arr.splice(0, 0, group);
-
           this._groups.splice(0, 0, group);
-
           this._currentCopies += 1;
         }
-
         this.elem.reloadShapes();
         hasReloaded = true;
       }
-
       cont = 0;
       var renderFlag;
-
       for (i = 0; i <= this._groups.length - 1; i += 1) {
         renderFlag = cont < copies;
         this._groups[i]._render = renderFlag;
         this.changeGroupRender(this._groups[i].it, renderFlag);
-
         if (!renderFlag) {
           var elems = this.elemsData[i].it;
           var transformData = elems[elems.length - 1];
-
           if (transformData.transform.op.v !== 0) {
             transformData.transform.op._mdf = true;
             transformData.transform.op.v = 0;
@@ -6630,11 +5628,10 @@
             transformData.transform.op._mdf = false;
           }
         }
-
         cont += 1;
       }
-
-      this._currentCopies = copies; /// /
+      this._currentCopies = copies;
+      /// /
 
       var offset = this.o.v;
       var offsetModulo = offset % 1;
@@ -6648,13 +5645,11 @@
       this.tMatrix.reset();
       this.matrix.reset();
       var iteration = 0;
-
       if (offset > 0) {
         while (iteration < roundOffset) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           iteration += 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
           iteration += offsetModulo;
@@ -6664,19 +5659,16 @@
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
           iteration -= 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
           iteration -= offsetModulo;
         }
       }
-
       i = this.data.m === 1 ? 0 : this._currentCopies - 1;
       dir = this.data.m === 1 ? 1 : -1;
       cont = this._currentCopies;
       var j;
       var jLen;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6684,29 +5676,23 @@
         items[items.length - 1].transform.mProps._mdf = true;
         items[items.length - 1].transform.op._mdf = true;
         items[items.length - 1].transform.op.v = this._currentCopies === 1 ? this.so.v : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
-
         if (iteration !== 0) {
           if (i !== 0 && dir === 1 || i !== this._currentCopies - 1 && dir === -1) {
             this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           }
-
           this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
           this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
           this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
-
           this.matrix.reset();
         } else {
           this.matrix.reset();
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
         }
-
         iteration += 1;
         cont -= 1;
         i += dir;
@@ -6715,7 +5701,6 @@
       cont = this._currentCopies;
       i = 0;
       dir = 1;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6725,22 +5710,17 @@
         i += dir;
       }
     }
-
     return hasReloaded;
   };
-
   RepeaterModifier.prototype.addShape = function () {};
 
   function RoundCornersModifier() {}
-
   extendPrototype([ShapeModifier], RoundCornersModifier);
-
   RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
     this._isAnimated = !!this.rd.effectsSequence.length;
   };
-
   RoundCornersModifier.prototype.processPath = function (path, round) {
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
@@ -6759,19 +5739,16 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < len; i += 1) {
       currentV = path.v[i];
       currentO = path.o[i];
       currentI = path.i[i];
-
       if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
         if ((i === 0 || i === len - 1) && !path.c) {
           clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
           /* clonedPath.v[index] = currentV;
                   clonedPath.o[index] = currentO;
                   clonedPath.i[index] = currentI; */
-
           index += 1;
         } else {
           if (i === 0) {
@@ -6779,7 +5756,6 @@
           } else {
             closerV = path.v[i - 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6790,13 +5766,11 @@
           oY = vY - (vY - currentV[1]) * roundCorner;
           clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
           index += 1;
-
           if (i === len - 1) {
             closerV = path.v[0];
           } else {
             closerV = path.v[i + 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6813,10 +5787,8 @@
         index += 1;
       }
     }
-
     return clonedPath;
   };
-
   RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6824,30 +5796,24 @@
     var j;
     var jLen;
     var rd = this.rd.v;
-
     if (rd !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6856,50 +5822,41 @@
   function floatEqual(a, b) {
     return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
   }
-
   function floatZero(f) {
     return Math.abs(f) <= 0.00001;
   }
-
   function lerp(p0, p1, amount) {
     return p0 * (1 - amount) + p1 * amount;
   }
-
   function lerpPoint(p0, p1, amount) {
     return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
   }
-
   function quadRoots(a, b, c) {
     // no root
     if (a === 0) return [];
-    var s = b * b - 4 * a * c; // Complex roots
-
+    var s = b * b - 4 * a * c;
+    // Complex roots
     if (s < 0) return [];
-    var singleRoot = -b / (2 * a); // 1 root
-
+    var singleRoot = -b / (2 * a);
+    // 1 root
     if (s === 0) return [singleRoot];
-    var delta = Math.sqrt(s) / (2 * a); // 2 roots
-
+    var delta = Math.sqrt(s) / (2 * a);
+    // 2 roots
     return [singleRoot - delta, singleRoot + delta];
   }
-
   function polynomialCoefficients(p0, p1, p2, p3) {
     return [-p0 + 3 * p1 - 3 * p2 + p3, 3 * p0 - 6 * p1 + 3 * p2, -3 * p0 + 3 * p1, p0];
   }
-
   function singlePoint(p) {
     return new PolynomialBezier(p, p, p, p, false);
   }
-
   function PolynomialBezier(p0, p1, p2, p3, linearize) {
     if (linearize && pointEqual(p0, p1)) {
       p1 = lerpPoint(p0, p3, 1 / 3);
     }
-
     if (linearize && pointEqual(p2, p3)) {
       p2 = lerpPoint(p0, p3, 2 / 3);
     }
-
     var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
     var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
     this.a = [coeffx[0], coeffy[0]];
@@ -6908,25 +5865,20 @@
     this.d = [coeffx[3], coeffy[3]];
     this.points = [p0, p1, p2, p3];
   }
-
   PolynomialBezier.prototype.point = function (t) {
     return [((this.a[0] * t + this.b[0]) * t + this.c[0]) * t + this.d[0], ((this.a[1] * t + this.b[1]) * t + this.c[1]) * t + this.d[1]];
   };
-
   PolynomialBezier.prototype.derivative = function (t) {
     return [(3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0], (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1]];
   };
-
   PolynomialBezier.prototype.tangentAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[1], p[0]);
   };
-
   PolynomialBezier.prototype.normalAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[0], p[1]);
   };
-
   PolynomialBezier.prototype.inflectionPoints = function () {
     var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
     if (floatZero(denom)) return [];
@@ -6934,17 +5886,14 @@
     var square = tcusp * tcusp - 1 / 3 * (this.b[1] * this.c[0] - this.b[0] * this.c[1]) / denom;
     if (square < 0) return [];
     var root = Math.sqrt(square);
-
     if (floatZero(root)) {
       if (root > 0 && root < 1) return [tcusp];
       return [];
     }
-
     return [tcusp - root, tcusp + root].filter(function (r) {
       return r > 0 && r < 1;
     });
   };
-
   PolynomialBezier.prototype.split = function (t) {
     if (t <= 0) return [singlePoint(this.points[0]), this];
     if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
@@ -6956,40 +5905,33 @@
     var p3 = lerpPoint(p20, p21, t);
     return [new PolynomialBezier(this.points[0], p10, p20, p3, true), new PolynomialBezier(p3, p21, p12, this.points[3], true)];
   };
-
   function extrema(bez, comp) {
     var min = bez.points[0][comp];
     var max = bez.points[bez.points.length - 1][comp];
-
     if (min > max) {
       var e = max;
       max = min;
       min = e;
-    } // Derivative roots to find min/max
-
-
+    }
+    // Derivative roots to find min/max
     var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
-
     for (var i = 0; i < f.length; i += 1) {
       if (f[i] > 0 && f[i] < 1) {
         var val = bez.point(f[i])[comp];
         if (val < min) min = val;else if (val > max) max = val;
       }
     }
-
     return {
       min: min,
       max: max
     };
   }
-
   PolynomialBezier.prototype.bounds = function () {
     return {
       x: extrema(this, 0),
       y: extrema(this, 1)
     };
   };
-
   PolynomialBezier.prototype.boundingBox = function () {
     var bounds = this.bounds();
     return {
@@ -7003,7 +5945,6 @@
       cy: (bounds.y.max + bounds.y.min) / 2
     };
   };
-
   function intersectData(bez, t1, t2) {
     var box = bez.boundingBox();
     return {
@@ -7017,24 +5958,19 @@
       t2: t2
     };
   }
-
   function splitData(data) {
     var split = data.bez.split(0.5);
     return [intersectData(split[0], data.t1, data.t), intersectData(split[1], data.t, data.t2)];
   }
-
   function boxIntersect(b1, b2) {
     return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
   }
-
   function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
     if (!boxIntersect(d1, d2)) return;
-
     if (depth >= maxRecursion || d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance) {
       intersections.push([d1.t, d2.t]);
       return;
     }
-
     var d1s = splitData(d1);
     var d2s = splitData(d2);
     intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
@@ -7042,7 +5978,6 @@
     intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
     intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
   }
-
   PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
     if (tolerance === undefined) tolerance = 2;
     if (maxRecursion === undefined) maxRecursion = 7;
@@ -7050,21 +5985,17 @@
     intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
     return intersections;
   };
-
   PolynomialBezier.shapeSegment = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
   };
-
   PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
   };
-
   function crossProduct(a, b) {
     return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
   }
-
   function lineIntersection(start1, end1, start2, end2) {
     var v1 = [start1[0], start1[1], 1];
     var v2 = [end1[0], end1[1], 1];
@@ -7074,23 +6005,18 @@
     if (floatZero(r[2])) return null;
     return [r[0] / r[2], r[1] / r[2]];
   }
-
   function polarOffset(p, angle, length) {
     return [p[0] + Math.cos(angle) * length, p[1] - Math.sin(angle) * length];
   }
-
   function pointDistance(p1, p2) {
     return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
   }
-
   function pointEqual(p1, p2) {
     return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
   }
 
   function ZigZagModifier() {}
-
   extendPrototype([ShapeModifier], ZigZagModifier);
-
   ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
@@ -7098,7 +6024,6 @@
     this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
     this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
   };
-
   function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
     var angO = angle - Math.PI / 2;
     var angI = angle + Math.PI / 2;
@@ -7106,14 +6031,12 @@
     var py = point[1] - Math.sin(angle) * direction * amplitude;
     outputBezier.setTripleAt(px, py, px + Math.cos(angO) * outAmplitude, py - Math.sin(angO) * outAmplitude, px + Math.cos(angI) * inAmplitude, py - Math.sin(angI) * inAmplitude, outputBezier.length());
   }
-
   function getPerpendicularVector(pt1, pt2) {
     var vector = [pt2[0] - pt1[0], pt2[1] - pt1[1]];
     var rot = -Math.PI * 0.5;
     var rotatedVector = [Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1], Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1]];
     return rotatedVector;
   }
-
   function getProjectingAngle(path, cur) {
     var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
     var nextIndex = (cur + 1) % path.length();
@@ -7122,7 +6045,6 @@
     var pVector = getPerpendicularVector(prevPoint, nextPoint);
     return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
   }
-
   function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
     var angle = getProjectingAngle(path, cur);
     var point = path.v[cur % path._length];
@@ -7132,7 +6054,6 @@
     var nextDist = pointType === 2 ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2)) : 0;
     setPoint(outputBezier, path.v[cur % path._length], angle, direction, amplitude, nextDist / ((frequency + 1) * 2), prevDist / ((frequency + 1) * 2), pointType);
   }
-
   function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
     for (var i = 0; i < frequency; i += 1) {
       var t = (i + 1) / (frequency + 1);
@@ -7142,39 +6063,30 @@
       setPoint(outputBezier, point, angle, direction, amplitude, dist / ((frequency + 1) * 2), dist / ((frequency + 1) * 2), pointType);
       direction = -direction;
     }
-
     return direction;
   }
-
   ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
     var count = path._length;
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
-
     if (!path.c) {
       count -= 1;
     }
-
     if (count === 0) return clonedPath;
     var direction = -1;
     var segment = PolynomialBezier.shapeSegment(path, 0);
     zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
-
     for (var i = 0; i < count; i += 1) {
       direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
-
       if (i === count - 1 && !path.c) {
         segment = null;
       } else {
         segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
       }
-
       zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
     }
-
     return clonedPath;
   };
-
   ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -7184,30 +6096,24 @@
     var amplitude = this.amplitude.v;
     var frequency = Math.max(0, Math.round(this.frequency.v));
     var pointType = this.pointsType.v;
-
     if (amplitude !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -7217,7 +6123,6 @@
     var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
     return [polarOffset(p1, angle, amount), polarOffset(p2, angle, amount)];
   }
-
   function offsetSegment(segment, amount) {
     var p0;
     var p1a;
@@ -7241,15 +6146,17 @@
     if (p2 === null) p2 = p2a;
     return new PolynomialBezier(p0, p1, p2, p3);
   }
-
   function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
     var p0 = seg1.points[3];
-    var p1 = seg2.points[0]; // Bevel
+    var p1 = seg2.points[0];
 
-    if (lineJoin === 3) return p0; // Connected, they don't need a joint
+    // Bevel
+    if (lineJoin === 3) return p0;
 
-    if (pointEqual(p0, p1)) return p0; // Round
+    // Connected, they don't need a joint
+    if (pointEqual(p0, p1)) return p0;
 
+    // Round
     if (lineJoin === 2) {
       var angleOut = -seg1.tangentAngle(1);
       var angleIn = -seg2.tangentAngle(0) + Math.PI;
@@ -7260,91 +6167,75 @@
       tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
       outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
       return p1;
-    } // Miter
+    }
 
-
+    // Miter
     var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
     var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
     var intersection = lineIntersection(t0, p0, p1, t1);
-
     if (intersection && pointDistance(intersection, p0) < miterLimit) {
       outputBezier.setTripleAt(intersection[0], intersection[1], intersection[0], intersection[1], intersection[0], intersection[1], outputBezier.length());
       return intersection;
     }
-
     return p0;
   }
-
   function getIntersection(a, b) {
     var intersect = a.intersections(b);
     if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
     if (intersect.length) return intersect[0];
     return null;
   }
-
   function pruneSegmentIntersection(a, b) {
     var outa = a.slice();
     var outb = b.slice();
     var intersect = getIntersection(a[a.length - 1], b[0]);
-
     if (intersect) {
       outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
       outb[0] = b[0].split(intersect[1])[1];
     }
-
     if (a.length > 1 && b.length > 1) {
       intersect = getIntersection(a[0], b[b.length - 1]);
-
       if (intersect) {
         return [[a[0].split(intersect[0])[0]], [b[b.length - 1].split(intersect[1])[1]]];
       }
     }
-
     return [outa, outb];
   }
-
   function pruneIntersections(segments) {
     var e;
-
     for (var i = 1; i < segments.length; i += 1) {
       e = pruneSegmentIntersection(segments[i - 1], segments[i]);
       segments[i - 1] = e[0];
       segments[i] = e[1];
     }
-
     if (segments.length > 1) {
       e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
       segments[segments.length - 1] = e[0];
       segments[0] = e[1];
     }
-
     return segments;
   }
-
   function offsetSegmentSplit(segment, amount) {
     /*
       We split each bezier segment into smaller pieces based
       on inflection points, this ensures the control point
       polygon is convex.
-        (A cubic bezier can have none, one, or two inflection points)
+       (A cubic bezier can have none, one, or two inflection points)
     */
     var flex = segment.inflectionPoints();
     var left;
     var right;
     var split;
     var mid;
-
     if (flex.length === 0) {
       return [offsetSegment(segment, amount)];
     }
-
     if (flex.length === 1 || floatEqual(flex[1], 1)) {
       split = segment.split(flex[0]);
       left = split[0];
       right = split[1];
       return [offsetSegment(left, amount), offsetSegment(right, amount)];
     }
-
     split = segment.split(flex[0]);
     left = split[0];
     var t = (flex[1] - flex[0]) / (1 - flex[0]);
@@ -7353,11 +6244,8 @@
     right = split[1];
     return [offsetSegment(left, amount), offsetSegment(mid, amount), offsetSegment(right, amount)];
   }
-
   function OffsetPathModifier() {}
-
   extendPrototype([ShapeModifier], OffsetPathModifier);
-
   OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
@@ -7365,61 +6253,50 @@
     this.lineJoin = data.lj;
     this._isAnimated = this.amount.effectsSequence.length !== 0;
   };
-
   OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
     var outputBezier = shapePool.newElement();
     outputBezier.c = inputBezier.c;
     var count = inputBezier.length();
-
     if (!inputBezier.c) {
       count -= 1;
     }
-
     var i;
     var j;
     var segment;
     var multiSegments = [];
-
     for (i = 0; i < count; i += 1) {
       segment = PolynomialBezier.shapeSegment(inputBezier, i);
       multiSegments.push(offsetSegmentSplit(segment, amount));
     }
-
     if (!inputBezier.c) {
       for (i = count - 1; i >= 0; i -= 1) {
         segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
         multiSegments.push(offsetSegmentSplit(segment, amount));
       }
     }
+    multiSegments = pruneIntersections(multiSegments);
 
-    multiSegments = pruneIntersections(multiSegments); // Add bezier segments to the output and apply line joints
-
+    // Add bezier segments to the output and apply line joints
     var lastPoint = null;
     var lastSeg = null;
-
     for (i = 0; i < multiSegments.length; i += 1) {
       var multiSegment = multiSegments[i];
       if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
       lastSeg = multiSegment[multiSegment.length - 1];
-
       for (j = 0; j < multiSegment.length; j += 1) {
         segment = multiSegment[j];
-
         if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
           outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
         } else {
           outputBezier.setTripleAt(segment.points[0][0], segment.points[0][1], segment.points[1][0], segment.points[1][1], segment.points[0][0], segment.points[0][1], outputBezier.length());
         }
-
         outputBezier.setTripleAt(segment.points[3][0], segment.points[3][1], segment.points[3][0], segment.points[3][1], segment.points[2][0], segment.points[2][1], outputBezier.length());
         lastPoint = segment.points[3];
       }
     }
-
     if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
     return outputBezier;
   };
-
   OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -7429,30 +6306,24 @@
     var amount = this.amount.v;
     var miterLimit = this.miterLimit.v;
     var lineJoin = this.lineJoin;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -7464,42 +6335,33 @@
     var fStyle = 'normal';
     var len = styles.length;
     var styleName;
-
     for (var i = 0; i < len; i += 1) {
       styleName = styles[i].toLowerCase();
-
       switch (styleName) {
         case 'italic':
           fStyle = 'italic';
           break;
-
         case 'bold':
           fWeight = '700';
           break;
-
         case 'black':
           fWeight = '900';
           break;
-
         case 'medium':
           fWeight = '500';
           break;
-
         case 'regular':
         case 'normal':
           fWeight = '400';
           break;
-
         case 'light':
         case 'thin':
           fWeight = '200';
           break;
-
         default:
           break;
       }
     }
-
     return {
       style: fStyle,
       weight: fontData.fWeight || fWeight
@@ -7516,8 +6378,8 @@
         shapes: []
       }
     };
-    var combinedCharacters = []; // Hindi characters
-
+    var combinedCharacters = [];
+    // Hindi characters
     combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
     var BLACK_FLAG_CODE_POINT = 127988;
     var CANCEL_TAG_CODE_POINT = 917631;
@@ -7528,44 +6390,41 @@
     var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
     var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
     var surrogateModifiers = ['d83cdffb', 'd83cdffc', 'd83cdffd', 'd83cdffe', 'd83cdfff'];
-
     function trimFontOptions(font) {
       var familyArray = font.split(',');
       var i;
       var len = familyArray.length;
       var enabledFamilies = [];
-
       for (i = 0; i < len; i += 1) {
         if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
           enabledFamilies.push(familyArray[i]);
         }
       }
-
       return enabledFamilies.join(',');
     }
-
     function setUpNode(font, family) {
-      var parentNode = createTag('span'); // Node is invisible to screen readers.
-
+      var parentNode = createTag('span');
+      // Node is invisible to screen readers.
       parentNode.setAttribute('aria-hidden', true);
       parentNode.style.fontFamily = family;
-      var node = createTag('span'); // Characters that vary significantly among different fonts
-
-      node.innerText = 'giItT1WQy@!-/#'; // Visible - so we can measure it - but not on the screen
-
+      var node = createTag('span');
+      // Characters that vary significantly among different fonts
+      node.innerText = 'giItT1WQy@!-/#';
+      // Visible - so we can measure it - but not on the screen
       parentNode.style.position = 'absolute';
       parentNode.style.left = '-10000px';
-      parentNode.style.top = '-10000px'; // Large font size makes even subtle changes obvious
-
-      parentNode.style.fontSize = '300px'; // Reset any font properties
-
+      parentNode.style.top = '-10000px';
+      // Large font size makes even subtle changes obvious
+      parentNode.style.fontSize = '300px';
+      // Reset any font properties
       parentNode.style.fontVariant = 'normal';
       parentNode.style.fontStyle = 'normal';
       parentNode.style.fontWeight = 'normal';
       parentNode.style.letterSpacing = '0';
       parentNode.appendChild(node);
-      document.body.appendChild(parentNode); // Remember width with no applied web font
+      document.body.appendChild(parentNode);
 
+      // Remember width with no applied web font
       var width = node.offsetWidth;
       node.style.fontFamily = trimFontOptions(font) + ', ' + family;
       return {
@@ -7574,14 +6433,12 @@
         parent: parentNode
       };
     }
-
     function checkLoadedFonts() {
       var i;
       var len = this.fonts.length;
       var node;
       var w;
       var loadedCount = len;
-
       for (i = 0; i < len; i += 1) {
         if (this.fonts[i].loaded) {
           loadedCount -= 1;
@@ -7590,55 +6447,47 @@
         } else {
           node = this.fonts[i].monoCase.node;
           w = this.fonts[i].monoCase.w;
-
           if (node.offsetWidth !== w) {
             loadedCount -= 1;
             this.fonts[i].loaded = true;
           } else {
             node = this.fonts[i].sansCase.node;
             w = this.fonts[i].sansCase.w;
-
             if (node.offsetWidth !== w) {
               loadedCount -= 1;
               this.fonts[i].loaded = true;
             }
           }
-
           if (this.fonts[i].loaded) {
             this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
             this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
           }
         }
       }
-
       if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
         setTimeout(this.checkLoadedFontsBinded, 20);
       } else {
         setTimeout(this.setIsLoadedBinded, 10);
       }
     }
-
     function createHelper(fontData, def) {
       var engine = document.body && def ? 'svg' : 'canvas';
       var helper;
       var fontProps = getFontProperties(fontData);
-
       if (engine === 'svg') {
         var tHelper = createNS('text');
-        tHelper.style.fontSize = '100px'; // tHelper.style.fontFamily = fontData.fFamily;
-
+        tHelper.style.fontSize = '100px';
+        // tHelper.style.fontFamily = fontData.fFamily;
         tHelper.setAttribute('font-family', fontData.fFamily);
         tHelper.setAttribute('font-style', fontProps.style);
         tHelper.setAttribute('font-weight', fontProps.weight);
         tHelper.textContent = '1';
-
         if (fontData.fClass) {
           tHelper.style.fontFamily = 'inherit';
           tHelper.setAttribute('class', fontData.fClass);
         } else {
           tHelper.style.fontFamily = fontData.fFamily;
         }
-
         def.appendChild(tHelper);
         helper = tHelper;
       } else {
@@ -7646,33 +6495,27 @@
         tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
         helper = tCanvasHelper;
       }
-
       function measure(text) {
         if (engine === 'svg') {
           helper.textContent = text;
           return helper.getComputedTextLength();
         }
-
         return helper.measureText(text).width;
       }
-
       return {
         measureText: measure
       };
     }
-
     function addFonts(fontData, defs) {
       if (!fontData) {
         this.isLoaded = true;
         return;
       }
-
       if (this.chars) {
         this.isLoaded = true;
         this.fonts = fontData.list;
         return;
       }
-
       if (!document.body) {
         this.isLoaded = true;
         fontData.list.forEach(function (data) {
@@ -7682,12 +6525,10 @@
         this.fonts = fontData.list;
         return;
       }
-
       var fontArr = fontData.list;
       var i;
       var len = fontArr.length;
       var _pendingFonts = len;
-
       for (i = 0; i < len; i += 1) {
         var shouldLoadFont = true;
         var loadedSelector;
@@ -7695,17 +6536,14 @@
         fontArr[i].loaded = false;
         fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
         fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
-
         if (!fontArr[i].fPath) {
           fontArr[i].loaded = true;
           _pendingFonts -= 1;
         } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
           loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
-
           if (loadedSelector.length > 0) {
             shouldLoadFont = false;
           }
-
           if (shouldLoadFont) {
             var s = createTag('style');
             s.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7717,14 +6555,12 @@
           }
         } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
           loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var l = createTag('link');
             l.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7736,14 +6572,12 @@
           }
         } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
           loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (fontArr[i].fPath === loadedSelector[j].src) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var sc = createTag('link');
             sc.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7753,12 +6587,10 @@
             defs.appendChild(sc);
           }
         }
-
         fontArr[i].helper = createHelper(fontArr[i], defs);
         fontArr[i].cache = {};
         this.fonts.push(fontArr[i]);
       }
-
       if (_pendingFonts === 0) {
         this.isLoaded = true;
       } else {
@@ -7767,71 +6599,56 @@
         setTimeout(this.checkLoadedFonts.bind(this), 100);
       }
     }
-
     function addChars(chars) {
       if (!chars) {
         return;
       }
-
       if (!this.chars) {
         this.chars = [];
       }
-
       var i;
       var len = chars.length;
       var j;
       var jLen = this.chars.length;
       var found;
-
       for (i = 0; i < len; i += 1) {
         j = 0;
         found = false;
-
         while (j < jLen) {
           if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
             found = true;
           }
-
           j += 1;
         }
-
         if (!found) {
           this.chars.push(chars[i]);
           jLen += 1;
         }
       }
     }
-
     function getCharData(_char, style, font) {
       var i = 0;
       var len = this.chars.length;
-
       while (i < len) {
         if (this.chars[i].ch === _char && this.chars[i].style === style && this.chars[i].fFamily === font) {
           return this.chars[i];
         }
-
         i += 1;
       }
-
       if ((typeof _char === 'string' && _char.charCodeAt(0) !== 13 || !_char) && console && console.warn // eslint-disable-line no-console
       && !this._warned) {
         this._warned = true;
         console.warn('Missing character from exported characters list: ', _char, style, font); // eslint-disable-line no-console
       }
-
       return emptyChar;
     }
-
     function measureText(_char2, fontName, size) {
-      var fontData = this.getFontByName(fontName); // Using the char instead of char.charCodeAt(0)
+      var fontData = this.getFontByName(fontName);
+      // Using the char instead of char.charCodeAt(0)
       // to avoid collisions between equal chars
-
       var index = _char2;
-
       if (!fontData.cache[index]) {
         var tHelper = fontData.helper;
-
         if (_char2 === ' ') {
           var doubleSize = tHelper.measureText('|' + _char2 + '|');
           var singleSize = tHelper.measureText('||');
@@ -7840,111 +6657,90 @@
           fontData.cache[index] = tHelper.measureText(_char2) / 100;
         }
       }
-
       return fontData.cache[index] * size;
     }
-
     function getFontByName(name) {
       var i = 0;
       var len = this.fonts.length;
-
       while (i < len) {
         if (this.fonts[i].fName === name) {
           return this.fonts[i];
         }
-
         i += 1;
       }
-
       return this.fonts[0];
     }
-
     function getCodePoint(string) {
       var codePoint = 0;
       var first = string.charCodeAt(0);
-
       if (first >= 0xD800 && first <= 0xDBFF) {
         var second = string.charCodeAt(1);
-
         if (second >= 0xDC00 && second <= 0xDFFF) {
           codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
         }
       }
-
       return codePoint;
-    } // Skin tone modifiers
+    }
 
-
+    // Skin tone modifiers
     function isModifier(firstCharCode, secondCharCode) {
       var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
       return surrogateModifiers.indexOf(sum) !== -1;
     }
-
     function isZeroWidthJoiner(charCode) {
       return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
-    } // This codepoint may change the appearance of the preceding character.
+    }
+
+    // This codepoint may change the appearance of the preceding character.
     // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
     // as a colorful image as compared to a monochrome text variant.
-
-
     function isVariationSelector(charCode) {
       return charCode === VARIATION_SELECTOR_16_CODE_POINT;
-    } // The regional indicator symbols are a set of 26 alphabetic Unicode
+    }
+
+    // The regional indicator symbols are a set of 26 alphabetic Unicode
     /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
     // two-letter country codes in a way that allows optional special treatment.
-
-
     function isRegionalCode(string) {
       var codePoint = getCodePoint(string);
-
       if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
         return true;
       }
-
       return false;
-    } // Some Emoji implementations represent combinations of
+    }
+
+    // Some Emoji implementations represent combinations of
     // two “regional indicator” letters as a single flag symbol.
-
-
     function isFlagEmoji(string) {
       return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
     }
-
     function isCombinedCharacter(_char3) {
       return combinedCharacters.indexOf(_char3) !== -1;
-    } // Regional flags start with a BLACK_FLAG_CODE_POINT
+    }
+
+    // Regional flags start with a BLACK_FLAG_CODE_POINT
     // folowed by 5 chars in the TAG range
     // and end with a CANCEL_TAG_CODE_POINT
-
-
     function isRegionalFlag(text, index) {
       var codePoint = getCodePoint(text.substr(index, 2));
-
       if (codePoint !== BLACK_FLAG_CODE_POINT) {
         return false;
       }
-
       var count = 0;
       index += 2;
-
       while (count < 5) {
         codePoint = getCodePoint(text.substr(index, 2));
-
         if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
           return false;
         }
-
         count += 1;
         index += 2;
       }
-
       return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
     }
-
     function setIsLoaded() {
       this.isLoaded = true;
     }
-
     var Font = function Font() {
       this.fonts = [];
       this.chars = null;
@@ -7955,7 +6751,6 @@
       this.setIsLoadedBinded = this.setIsLoaded.bind(this);
       this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
     };
-
     Font.isModifier = isModifier;
     Font.isZeroWidthJoiner = isZeroWidthJoiner;
     Font.isFlagEmoji = isFlagEmoji;
@@ -7980,30 +6775,26 @@
   function SlotManager(animationData) {
     this.animationData = animationData;
   }
-
   SlotManager.prototype.getProp = function (data) {
     if (this.animationData.slots && this.animationData.slots[data.sid]) {
       return Object.assign(data, this.animationData.slots[data.sid].p);
     }
-
     return data;
   };
-
   function slotFactory(animationData) {
     return new SlotManager(animationData);
   }
 
   function RenderableElement() {}
-
   RenderableElement.prototype = {
     initRenderable: function initRenderable() {
       // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
-      this.isInRange = false; // layer's display state
-
-      this.hidden = false; // If layer's transparency equals 0, it can be hidden
-
-      this.isTransparent = false; // list of animated components
-
+      this.isInRange = false;
+      // layer's display state
+      this.hidden = false;
+      // If layer's transparency equals 0, it can be hidden
+      this.isTransparent = false;
+      // list of animated components
       this.renderableComponents = [];
     },
     addRenderableComponent: function addRenderableComponent(component) {
@@ -8030,7 +6821,6 @@
         this.show();
       }
     },
-
     /**
        * @function
        * Initializes frame related properties.
@@ -8056,13 +6846,11 @@
     renderRenderable: function renderRenderable() {
       var i;
       var len = this.renderableComponents.length;
-
       for (i = 0; i < len; i += 1) {
         this.renderableComponents[i].renderFrame(this._isFirstFrame);
       }
       /* this.maskManager.renderFrame(this.finalTransform.mat);
           this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
-
     },
     sourceRectAtTime: function sourceRectAtTime() {
       return {
@@ -8079,7 +6867,6 @@
           h: this.data.textData.height
         };
       }
-
       return {
         w: this.data.width,
         h: this.data.height
@@ -8114,31 +6901,24 @@
   function SliderEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function AngleEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function ColorEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function PointEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function LayerIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function MaskIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function CheckboxEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function NoValueEffect() {
     this.p = {};
   }
@@ -8149,20 +6929,16 @@
     var i;
     var len = effects.length;
     var effectItem;
-
     for (i = 0; i < len; i += 1) {
       effectItem = new GroupEffect(effects[i], element);
       this.effectElements.push(effectItem);
     }
   }
-
   function GroupEffect(data, element) {
     this.init(data, element);
   }
-
   extendPrototype([DynamicPropertyContainer], GroupEffect);
   GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
-
   GroupEffect.prototype.init = function (data, element) {
     this.data = data;
     this.effectElements = [];
@@ -8171,50 +6947,39 @@
     var len = this.data.ef.length;
     var eff;
     var effects = this.data.ef;
-
     for (i = 0; i < len; i += 1) {
       eff = null;
-
       switch (effects[i].ty) {
         case 0:
           eff = new SliderEffect(effects[i], element, this);
           break;
-
         case 1:
           eff = new AngleEffect(effects[i], element, this);
           break;
-
         case 2:
           eff = new ColorEffect(effects[i], element, this);
           break;
-
         case 3:
           eff = new PointEffect(effects[i], element, this);
           break;
-
         case 4:
         case 7:
           eff = new CheckboxEffect(effects[i], element, this);
           break;
-
         case 10:
           eff = new LayerIndexEffect(effects[i], element, this);
           break;
-
         case 11:
           eff = new MaskIndexEffect(effects[i], element, this);
           break;
-
         case 5:
           eff = new EffectsManager(effects[i], element, this);
           break;
         // case 6:
-
         default:
           eff = new NoValueEffect(effects[i], element, this);
           break;
       }
-
       if (eff) {
         this.effectElements.push(eff);
       }
@@ -8222,47 +6987,37 @@
   };
 
   function BaseElement() {}
-
   BaseElement.prototype = {
     checkMasks: function checkMasks() {
       if (!this.data.hasMask) {
         return false;
       }
-
       var i = 0;
       var len = this.data.masksProperties.length;
-
       while (i < len) {
         if (this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false) {
           return true;
         }
-
         i += 1;
       }
-
       return false;
     },
     initExpressions: function initExpressions() {
       var expressionsInterfaces = getExpressionInterfaces();
-
       if (!expressionsInterfaces) {
         return;
       }
-
       var LayerExpressionInterface = expressionsInterfaces('layer');
       var EffectsExpressionInterface = expressionsInterfaces('effects');
       var ShapeExpressionInterface = expressionsInterfaces('shape');
       var TextExpressionInterface = expressionsInterfaces('text');
       var CompExpressionInterface = expressionsInterfaces('comp');
       this.layerInterface = LayerExpressionInterface(this);
-
       if (this.data.hasMask && this.maskManager) {
         this.layerInterface.registerMaskInterface(this.maskManager);
       }
-
       var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
       this.layerInterface.registerEffectsInterface(effectsInterface);
-
       if (this.data.ty === 0 || this.data.xt) {
         this.compInterface = CompExpressionInterface(this);
       } else if (this.data.ty === 4) {
@@ -8282,13 +7037,13 @@
       this.globalData = globalData;
       this.comp = comp;
       this.data = data;
-      this.layerId = createElementID(); // Stretch factor for old animations missing this property.
+      this.layerId = createElementID();
 
+      // Stretch factor for old animations missing this property.
       if (!this.data.sr) {
         this.data.sr = 1;
-      } // effects manager
-
-
+      }
+      // effects manager
       this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
     },
     getType: function getType() {
@@ -8303,8 +7058,8 @@
    * Checks layer in point and out point
    *
    */
-  function FrameElement() {}
 
+  function FrameElement() {}
   FrameElement.prototype = {
     /**
        * @function
@@ -8313,13 +7068,12 @@
        */
     initFrame: function initFrame() {
       // set to true when inpoint is rendered
-      this._isFirstFrame = false; // list of animated properties
-
-      this.dynamicProperties = []; // If layer has been modified in current tick this will be true
-
+      this._isFirstFrame = false;
+      // list of animated properties
+      this.dynamicProperties = [];
+      // If layer has been modified in current tick this will be true
       this._mdf = false;
     },
-
     /**
        * @function
        * Calculates all dynamic values
@@ -8333,11 +7087,9 @@
     prepareProperties: function prepareProperties(num, isVisible) {
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         if (isVisible || this._isParent && this.dynamicProperties[i].propType === 'transform') {
           this.dynamicProperties[i].getValue();
-
           if (this.dynamicProperties[i]._mdf) {
             this.globalData._mdf = true;
             this._mdf = true;
@@ -8359,30 +7111,21 @@
     this.footageData = globalData.imageLoader.getAsset(this.assetData);
     this.initBaseData(data, globalData, comp);
   }
-
   FootageElement.prototype.prepareFrame = function () {};
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
-
   FootageElement.prototype.getBaseElement = function () {
     return null;
   };
-
   FootageElement.prototype.renderFrame = function () {};
-
   FootageElement.prototype.destroy = function () {};
-
   FootageElement.prototype.initExpressions = function () {
     var expressionsInterfaces = getExpressionInterfaces();
-
     if (!expressionsInterfaces) {
       return;
     }
-
     var FootageInterface = expressionsInterfaces('footage');
     this.layerInterface = FootageInterface(this);
   };
-
   FootageElement.prototype.getFootageData = function () {
     return this.footageData;
   };
@@ -8408,29 +7151,23 @@
       k: [100]
     }, 1, 0.01, this);
   }
-
   AudioElement.prototype.prepareFrame = function (num) {
     this.prepareRenderableFrame(num, true);
     this.prepareProperties(num, true);
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
       this._currentTime = timeRemapped;
     } else {
       this._currentTime = num / this.data.sr;
     }
-
     this._volume = this.lv.v[0];
     var totalVolume = this._volume * this._volumeMultiplier;
-
     if (this._previousVolume !== totalVolume) {
       this._previousVolume = totalVolume;
       this.audio.volume(totalVolume);
     }
   };
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
-
   AudioElement.prototype.renderFrame = function () {
     if (this.isInRange && this._canPlay) {
       if (!this._isPlaying) {
@@ -8442,162 +7179,124 @@
       }
     }
   };
-
-  AudioElement.prototype.show = function () {// this.audio.play()
+  AudioElement.prototype.show = function () {
+    // this.audio.play()
   };
-
   AudioElement.prototype.hide = function () {
     this.audio.pause();
     this._isPlaying = false;
   };
-
   AudioElement.prototype.pause = function () {
     this.audio.pause();
     this._isPlaying = false;
     this._canPlay = false;
   };
-
   AudioElement.prototype.resume = function () {
     this._canPlay = true;
   };
-
   AudioElement.prototype.setRate = function (rateValue) {
     this.audio.rate(rateValue);
   };
-
   AudioElement.prototype.volume = function (volumeValue) {
     this._volumeMultiplier = volumeValue;
     this._previousVolume = volumeValue * this._volume;
     this.audio.volume(this._previousVolume);
   };
-
   AudioElement.prototype.getBaseElement = function () {
     return null;
   };
-
   AudioElement.prototype.destroy = function () {};
-
   AudioElement.prototype.sourceRectAtTime = function () {};
-
   AudioElement.prototype.initExpressions = function () {};
 
   function BaseRenderer() {}
-
   BaseRenderer.prototype.checkLayers = function (num) {
     var i;
     var len = this.layers.length;
     var data;
     this.completeLayers = true;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (!this.elements[i]) {
         data = this.layers[i];
-
         if (data.ip - data.st <= num - this.layers[i].st && data.op - data.st > num - this.layers[i].st) {
           this.buildItem(i);
         }
       }
-
       this.completeLayers = this.elements[i] ? this.completeLayers : false;
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.createItem = function (layer) {
     switch (layer.ty) {
       case 2:
         return this.createImage(layer);
-
       case 0:
         return this.createComp(layer);
-
       case 1:
         return this.createSolid(layer);
-
       case 3:
         return this.createNull(layer);
-
       case 4:
         return this.createShape(layer);
-
       case 5:
         return this.createText(layer);
-
       case 6:
         return this.createAudio(layer);
-
       case 13:
         return this.createCamera(layer);
-
       case 15:
         return this.createFootage(layer);
-
       default:
         return this.createNull(layer);
     }
   };
-
   BaseRenderer.prototype.createCamera = function () {
     throw new Error('You\'re using a 3d camera. Try the html renderer.');
   };
-
   BaseRenderer.prototype.createAudio = function (data) {
     return new AudioElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.createFootage = function (data) {
     return new FootageElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.buildAllItems = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       this.buildItem(i);
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.includeLayers = function (newLayers) {
     this.completeLayers = false;
     var i;
     var len = newLayers.length;
     var j;
     var jLen = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       j = 0;
-
       while (j < jLen) {
         if (this.layers[j].id === newLayers[i].id) {
           this.layers[j] = newLayers[i];
           break;
         }
-
         j += 1;
       }
     }
   };
-
   BaseRenderer.prototype.setProjectInterface = function (pInterface) {
     this.globalData.projectInterface = pInterface;
   };
-
   BaseRenderer.prototype.initItems = function () {
     if (!this.globalData.progressiveLoad) {
       this.buildAllItems();
     }
   };
-
   BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
     var elements = this.elements;
     var layers = this.layers;
     var i = 0;
     var len = layers.length;
-
     while (i < len) {
       if (layers[i].ind == parentName) {
         // eslint-disable-line eqeqeq
@@ -8607,7 +7306,6 @@
         } else {
           hierarchy.push(elements[i]);
           elements[i].setAsParent();
-
           if (layers[i].parent !== undefined) {
             this.buildElementParenting(element, layers[i].parent, hierarchy);
           } else {
@@ -8615,19 +7313,15 @@
           }
         }
       }
-
       i += 1;
     }
   };
-
   BaseRenderer.prototype.addPendingElement = function (element) {
     this.pendingElements.push(element);
   };
-
   BaseRenderer.prototype.searchExtraCompositions = function (assets) {
     var i;
     var len = assets.length;
-
     for (i = 0; i < len; i += 1) {
       if (assets[i].xt) {
         var comp = this.createComp(assets[i]);
@@ -8636,30 +7330,24 @@
       }
     }
   };
-
   BaseRenderer.prototype.getElementById = function (ind) {
     var i;
     var len = this.elements.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i].data.ind === ind) {
         return this.elements[i];
       }
     }
-
     return null;
   };
-
   BaseRenderer.prototype.getElementByPath = function (path) {
     var pathValue = path.shift();
     var element;
-
     if (typeof pathValue === 'number') {
       element = this.elements[pathValue];
     } else {
       var i;
       var len = this.elements.length;
-
       for (i = 0; i < len; i += 1) {
         if (this.elements[i].data.nm === pathValue) {
           element = this.elements[i];
@@ -8667,14 +7355,11 @@
         }
       }
     }
-
     if (path.length === 0) {
       return element;
     }
-
     return element.getElementByPath(path);
   };
-
   BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
     this.globalData.fontManager = new FontManager();
     this.globalData.slotManager = slotFactory(animData);
@@ -8698,7 +7383,6 @@
   };
 
   function TransformElement() {}
-
   TransformElement.prototype = {
     initTransform: function initTransform() {
       var mat = new Matrix();
@@ -8713,50 +7397,44 @@
         localMat: mat,
         localOpacity: 1
       };
-
       if (this.data.ao) {
         this.finalTransform.mProp.autoOriented = true;
-      } // TODO: check TYPE 11: Guided elements
+      }
 
-
-      if (this.data.ty !== 11) {// this.createElements();
+      // TODO: check TYPE 11: Guided elements
+      if (this.data.ty !== 11) {
+        // this.createElements();
       }
     },
     renderTransform: function renderTransform() {
       this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
       this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
-
       if (this.hierarchy) {
         var mat;
         var finalMat = this.finalTransform.mat;
         var i = 0;
-        var len = this.hierarchy.length; // Checking if any of the transformation matrices in the hierarchy chain has changed.
-
+        var len = this.hierarchy.length;
+        // Checking if any of the transformation matrices in the hierarchy chain has changed.
         if (!this.finalTransform._matMdf) {
           while (i < len) {
             if (this.hierarchy[i].finalTransform.mProp._mdf) {
               this.finalTransform._matMdf = true;
               break;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._matMdf) {
           mat = this.finalTransform.mProp.v.props;
           finalMat.cloneFromProps(mat);
-
           for (i = 0; i < len; i += 1) {
             finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
           }
         }
       }
-
-      if (this.finalTransform._matMdf) {
+      if (!this.localTransforms || this.finalTransform._matMdf) {
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
       }
-
       if (this.finalTransform._opMdf) {
         this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
       }
@@ -8766,41 +7444,32 @@
         var i = 0;
         var len = this.localTransforms.length;
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
-
         if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
           while (i < len) {
             if (this.localTransforms[i]._mdf) {
               this.finalTransform._localMatMdf = true;
             }
-
             if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
               this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
               this.finalTransform._opMdf = true;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._localMatMdf) {
           var localMat = this.finalTransform.localMat;
           this.localTransforms[0].matrix.clone(localMat);
-
           for (i = 1; i < len; i += 1) {
             var lmat = this.localTransforms[i].matrix;
             localMat.multiply(lmat);
           }
-
           localMat.multiply(this.finalTransform.mat);
         }
-
         if (this.finalTransform._opMdf) {
           var localOp = this.finalTransform.localOpacity;
-
           for (i = 0; i < len; i += 1) {
             localOp *= this.localTransforms[i].opacity * 0.01;
           }
-
           this.finalTransform.localOpacity = localOp;
         }
       }
@@ -8808,13 +7477,11 @@
     searchEffectTransforms: function searchEffectTransforms() {
       if (this.renderableEffectsManager) {
         var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
-
         if (transformEffects.length) {
           this.localTransforms = [];
           this.finalTransform.localMat = new Matrix();
           var i = 0;
           var len = transformEffects.length;
-
           for (i = 0; i < len; i += 1) {
             this.localTransforms.push(transformEffects[i]);
           }
@@ -8826,29 +7493,24 @@
       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;
       var len = transforms.length;
       var 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]);
-
+        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;
     },
     mHelper: new Matrix()
@@ -8879,13 +7541,11 @@
     var x;
     var maskType = 'clipPath';
     var maskRef = 'clip-path';
-
     for (i = 0; i < len; i += 1) {
       if (properties[i].mode !== 'a' && properties[i].mode !== 'n' || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
         maskType = 'mask';
         maskRef = 'mask';
       }
-
       if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
         rect = createNS('rect');
         rect.setAttribute('fill', '#ffffff');
@@ -8895,9 +7555,7 @@
       } else {
         rect = null;
       }
-
       path = createNS('path');
-
       if (properties[i].mode === 'n') {
         // TODO move this to a factory or to a constructor
         this.viewData[i] = {
@@ -8912,7 +7570,6 @@
         path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
         path.setAttribute('clip-rule', 'nonzero');
         var filterID;
-
         if (properties[i].x.k !== 0) {
           maskType = 'mask';
           maskRef = 'mask';
@@ -8930,9 +7587,9 @@
         } else {
           feMorph = null;
           x = null;
-        } // TODO move this to a factory or to a constructor
+        }
 
-
+        // TODO move this to a factory or to a constructor
         this.storedData[i] = {
           elem: path,
           x: x,
@@ -8942,15 +7599,12 @@
           filterId: filterID,
           lastRadius: 0
         };
-
         if (properties[i].mode === 'i') {
           jLen = currentMasks.length;
           var g = createNS('g');
-
           for (j = 0; j < jLen; j += 1) {
             g.appendChild(currentMasks[j]);
           }
-
           var mask = createNS('mask');
           mask.setAttribute('mask-type', 'alpha');
           mask.setAttribute('id', layerId + '_' + count);
@@ -8962,12 +7616,10 @@
         } else {
           currentMasks.push(path);
         }
-
         if (properties[i].inv && !this.solidPath) {
           this.solidPath = this.createLayerSolidPath();
-        } // TODO move this to a factory or to a constructor
-
-
+        }
+        // TODO move this to a factory or to a constructor
         this.viewData[i] = {
           elem: path,
           lastPath: '',
@@ -8975,81 +7627,65 @@
           prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
           invRect: rect
         };
-
         if (!this.viewData[i].prop.k) {
           this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
         }
       }
     }
-
     this.maskElement = createNS(maskType);
     len = currentMasks.length;
-
     for (i = 0; i < len; i += 1) {
       this.maskElement.appendChild(currentMasks[i]);
     }
-
     if (count > 0) {
       this.maskElement.setAttribute('id', layerId);
       this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
       defs.appendChild(this.maskElement);
     }
-
     if (this.viewData.length) {
       this.element.addRenderableComponent(this);
     }
   }
-
   MaskElement.prototype.getMaskProperty = function (pos) {
     return this.viewData[pos].prop;
   };
-
   MaskElement.prototype.renderFrame = function (isFirstFrame) {
     var finalMat = this.element.finalTransform.mat;
     var i;
     var len = this.masksProperties.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.viewData[i].prop._mdf || isFirstFrame) {
         this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
       }
-
       if (this.viewData[i].op._mdf || isFirstFrame) {
         this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
       }
-
       if (this.masksProperties[i].mode !== 'n') {
         if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
           this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
         }
-
         if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
           var feMorph = this.storedData[i].expan;
-
           if (this.storedData[i].x.v < 0) {
             if (this.storedData[i].lastOperator !== 'erode') {
               this.storedData[i].lastOperator = 'erode';
               this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
             }
-
             feMorph.setAttribute('radius', -this.storedData[i].x.v);
           } else {
             if (this.storedData[i].lastOperator !== 'dilate') {
               this.storedData[i].lastOperator = 'dilate';
               this.storedData[i].elem.setAttribute('filter', null);
             }
-
             this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
           }
         }
       }
     }
   };
-
   MaskElement.prototype.getMaskelement = function () {
     return this.maskElement;
   };
-
   MaskElement.prototype.createLayerSolidPath = function () {
     var path = 'M0,0 ';
     path += ' h' + this.globalData.compSize.w;
@@ -9058,39 +7694,32 @@
     path += ' v-' + this.globalData.compSize.h + ' ';
     return path;
   };
-
   MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
     var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
     var i;
     var len;
     len = pathNodes._length;
-
     for (i = 1; i < len; i += 1) {
       // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
-    } // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
-
-
+    }
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
     if (pathNodes.c && len > 1) {
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
-    } // pathNodes.__renderedString = pathString;
-
+    }
+    // pathNodes.__renderedString = pathString;
 
     if (viewData.lastPath !== pathString) {
       var pathShapeValue = '';
-
       if (viewData.elem) {
         if (pathNodes.c) {
           pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
         }
-
         viewData.elem.setAttribute('d', pathShapeValue);
       }
-
       viewData.lastPath = pathString;
     }
   };
-
   MaskElement.prototype.destroy = function () {
     this.element = null;
     this.globalData = null;
@@ -9103,11 +7732,9 @@
     var ob = {};
     ob.createFilter = createFilter;
     ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
-
     function createFilter(filId, skipCoordinates) {
       var fil = createNS('filter');
       fil.setAttribute('id', filId);
-
       if (skipCoordinates !== true) {
         fil.setAttribute('filterUnits', 'objectBoundingBox');
         fil.setAttribute('x', '0%');
@@ -9115,10 +7742,8 @@
         fil.setAttribute('width', '100%');
         fil.setAttribute('height', '100%');
       }
-
       return fil;
     }
-
     function createAlphaToLuminanceFilter() {
       var feColorMatrix = createNS('feColorMatrix');
       feColorMatrix.setAttribute('type', 'matrix');
@@ -9126,7 +7751,6 @@
       feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
       return feColorMatrix;
     }
-
     return ob;
   }();
 
@@ -9136,21 +7760,17 @@
       svgLumaHidden: true,
       offscreenCanvas: typeof OffscreenCanvas !== 'undefined'
     };
-
     if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
       ob.maskType = false;
     }
-
     if (/firefox/i.test(navigator.userAgent)) {
       ob.svgLumaHidden = false;
     }
-
     return ob;
   }();
 
   var registeredEffects$1 = {};
   var idPrefix = 'filter_result_';
-
   function SVGEffects(elem) {
     var i;
     var source = 'SourceGraphic';
@@ -9160,59 +7780,47 @@
     var count = 0;
     this.filters = [];
     var filterManager;
-
     for (i = 0; i < len; i += 1) {
       filterManager = null;
       var type = elem.data.ef[i].ty;
-
       if (registeredEffects$1[type]) {
         var Effect = registeredEffects$1[type].effect;
         filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
         source = idPrefix + count;
-
         if (registeredEffects$1[type].countsAsEffect) {
           count += 1;
         }
       }
-
       if (filterManager) {
         this.filters.push(filterManager);
       }
     }
-
     if (count) {
       elem.globalData.defs.appendChild(fil);
       elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
     }
-
     if (this.filters.length) {
       elem.addRenderableComponent(this);
     }
   }
-
   SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
     var i;
     var len = this.filters.length;
-
     for (i = 0; i < len; i += 1) {
       this.filters[i].renderFrame(_isFirstFrame);
     }
   };
-
   SVGEffects.prototype.getEffects = function (type) {
     var i;
     var len = this.filters.length;
     var effects = [];
-
     for (i = 0; i < len; i += 1) {
       if (this.filters[i].type === type) {
         effects.push(this.filters[i]);
       }
     }
-
     return effects;
   };
-
   function registerEffect$1(id, effect, countsAsEffect) {
     registeredEffects$1[id] = {
       effect: effect,
@@ -9221,7 +7829,6 @@
   }
 
   function SVGBaseElement() {}
-
   SVGBaseElement.prototype = {
     initRendererElement: function initRendererElement() {
       this.layerElement = createNS('g');
@@ -9231,8 +7838,8 @@
       this.transformedElement = this.layerElement;
       this.maskedElement = this.layerElement;
       this._sizeChanged = false;
-      var layerElementParent = null; // If this layer acts as a mask for the following layer
-
+      var layerElementParent = null;
+      // If this layer acts as a mask for the following layer
       if (this.data.td) {
         this.matteMasks = {};
         var gg = createNS('g');
@@ -9247,16 +7854,13 @@
       } else {
         this.baseElement = this.layerElement;
       }
-
       if (this.data.ln) {
         this.layerElement.setAttribute('id', this.data.ln);
       }
-
       if (this.data.cl) {
         this.layerElement.setAttribute('class', this.data.cl);
-      } // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
-
-
+      }
+      // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
       if (this.data.ty === 0 && !this.data.hd) {
         var cp = createNS('clipPath');
         var pt = createNS('path');
@@ -9265,13 +7869,11 @@
         cp.setAttribute('id', clipId);
         cp.appendChild(pt);
         this.globalData.defs.appendChild(cp);
-
         if (this.checkMasks()) {
           var cpGroup = createNS('g');
           cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
           cpGroup.appendChild(this.layerElement);
           this.transformedElement = cpGroup;
-
           if (layerElementParent) {
             layerElementParent.appendChild(this.transformedElement);
           } else {
@@ -9281,7 +7883,6 @@
           this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
         }
       }
-
       if (this.data.bm !== 0) {
         this.setBlendMode();
       }
@@ -9290,7 +7891,6 @@
       if (this.finalTransform._localMatMdf) {
         this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
       }
-
       if (this.finalTransform._opMdf) {
         this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
       }
@@ -9304,7 +7904,6 @@
       if (this.data.hd) {
         return null;
       }
-
       return this.baseElement;
     },
     createRenderableComponents: function createRenderableComponents() {
@@ -9319,14 +7918,12 @@
       if (!this.matteMasks) {
         this.matteMasks = {};
       }
-
       if (!this.matteMasks[matteType]) {
         var id = this.layerId + '_' + matteType;
         var filId;
         var fil;
         var useElement;
         var gg;
-
         if (matteType === 1 || matteType === 3) {
           var masker = createNS('mask');
           masker.setAttribute('id', id);
@@ -9335,7 +7932,6 @@
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           masker.appendChild(useElement);
           this.globalData.defs.appendChild(masker);
-
           if (!featureSupport.maskType && matteType === 1) {
             masker.setAttribute('mask-type', 'luminance');
             filId = createElementID();
@@ -9354,16 +7950,16 @@
           var maskGrouper = createNS('g');
           maskGroup.appendChild(maskGrouper);
           filId = createElementID();
-          fil = filtersFactory.createFilter(filId); /// /
-
+          fil = filtersFactory.createFilter(filId);
+          /// /
           var feCTr = createNS('feComponentTransfer');
           feCTr.setAttribute('in', 'SourceGraphic');
           fil.appendChild(feCTr);
           var feFunc = createNS('feFuncA');
           feFunc.setAttribute('type', 'table');
           feFunc.setAttribute('tableValues', '1.0 0.0');
-          feCTr.appendChild(feFunc); /// /
-
+          feCTr.appendChild(feFunc);
+          /// /
           this.globalData.defs.appendChild(fil);
           var alphaRect = createNS('rect');
           alphaRect.setAttribute('width', this.comp.data.w);
@@ -9377,7 +7973,6 @@
           useElement = createNS('use');
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           maskGrouper.appendChild(useElement);
-
           if (!featureSupport.maskType) {
             maskGroup.setAttribute('mask-type', 'luminance');
             fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
@@ -9386,20 +7981,16 @@
             gg.appendChild(this.layerElement);
             maskGrouper.appendChild(gg);
           }
-
           this.globalData.defs.appendChild(maskGroup);
         }
-
         this.matteMasks[matteType] = id;
       }
-
       return this.matteMasks[matteType];
     },
     setMatte: function setMatte(id) {
       if (!this.matteElement) {
         return;
       }
-
       this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
     }
   };
@@ -9409,8 +8000,8 @@
    * Handles AE's layer parenting property.
    *
    */
-  function HierarchyElement() {}
 
+  function HierarchyElement() {}
   HierarchyElement.prototype = {
     /**
        * @function
@@ -9419,12 +8010,11 @@
        */
     initHierarchy: function initHierarchy() {
       // element's parent list
-      this.hierarchy = []; // if element is parent of another layer _isParent will be true
-
+      this.hierarchy = [];
+      // if element is parent of another layer _isParent will be true
       this._isParent = false;
       this.checkParenting();
     },
-
     /**
        * @function
        * Sets layer's hierarchy.
@@ -9435,7 +8025,6 @@
     setHierarchy: function setHierarchy(hierarchy) {
       this.hierarchy = hierarchy;
     },
-
     /**
        * @function
        * Sets layer as parent.
@@ -9444,7 +8033,6 @@
     setAsParent: function setAsParent() {
       this._isParent = true;
     },
-
     /**
        * @function
        * Searches layer's parenting chain
@@ -9458,7 +8046,6 @@
   };
 
   function RenderableDOMElement() {}
-
   (function () {
     var _prototype = {
       initElement: function initElement(data, globalData, comp) {
@@ -9488,7 +8075,6 @@
             var elem = this.baseElement || this.layerElement;
             elem.style.display = 'block';
           }
-
           this.hidden = false;
           this._isFirstFrame = true;
         }
@@ -9499,13 +8085,11 @@
         if (this.data.hd || this.hidden) {
           return;
         }
-
         this.renderTransform();
         this.renderRenderable();
         this.renderLocalTransform();
         this.renderElement();
         this.renderInnerContent();
-
         if (this._isFirstFrame) {
           this._isFirstFrame = false;
         }
@@ -9527,11 +8111,9 @@
 
   function IImageElement(data, globalData, comp) {
     this.assetData = globalData.getAssetData(data.refId);
-
     if (this.assetData && this.assetData.sid) {
       this.assetData = globalData.slotManager.getProp(this.assetData);
     }
-
     this.initElement(data, globalData, comp);
     this.sourceRect = {
       top: 0,
@@ -9540,9 +8122,7 @@
       height: this.assetData.h
     };
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
-
   IImageElement.prototype.createContent = function () {
     var assetPath = this.globalData.getAssetsPath(this.assetData);
     this.innerElem = createNS('image');
@@ -9552,7 +8132,6 @@
     this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
     this.layerElement.appendChild(this.innerElem);
   };
-
   IImageElement.prototype.sourceRectAtTime = function () {
     return this.sourceRect;
   };
@@ -9563,12 +8142,10 @@
   }
 
   function IShapeElement() {}
-
   IShapeElement.prototype = {
     addShapeToModifiers: function addShapeToModifiers(data) {
       var i;
       var len = this.shapeModifiers.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapeModifiers[i].addShape(data);
       }
@@ -9576,34 +8153,28 @@
     isShapeInAnimatedModifiers: function isShapeInAnimatedModifiers(data) {
       var i = 0;
       var len = this.shapeModifiers.length;
-
       while (i < len) {
         if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
           return true;
         }
       }
-
       return false;
     },
     renderModifiers: function renderModifiers() {
       if (!this.shapeModifiers.length) {
         return;
       }
-
       var i;
       var len = this.shapes.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapes[i].sh.reset();
       }
-
       len = this.shapeModifiers.length;
       var shouldBreakProcess;
-
       for (i = len - 1; i >= 0; i -= 1) {
-        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame); // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+        // workaround to fix cases where a repeater resets the shape so the following processes get called twice
         // TODO: find a better solution for this
-
         if (shouldBreakProcess) {
           break;
         }
@@ -9613,30 +8184,24 @@
       var elements = this.processedElements;
       var i = 0;
       var len = elements.length;
-
       while (i < len) {
         if (elements[i].elem === elem) {
           return elements[i].pos;
         }
-
         i += 1;
       }
-
       return 0;
     },
     addProcessedElement: function addProcessedElement(elem, pos) {
       var elements = this.processedElements;
       var i = elements.length;
-
       while (i) {
         i -= 1;
-
         if (elements[i].elem === elem) {
           elements[i].pos = pos;
           return;
         }
       }
-
       elements.push(new ProcessedElement(elem, pos));
     },
     prepareFrame: function prepareFrame(num) {
@@ -9662,25 +8227,22 @@
     this.transformers = transformers;
     this.lStr = '';
     this.sh = shape;
-    this.lvl = level; // TODO find if there are some cases where _isAnimated can be false.
+    this.lvl = level;
+    // TODO find if there are some cases where _isAnimated can be false.
     // For now, since shapes add up with other shapes. They have to be calculated every time.
     // One way of finding out is checking if all styles associated to this shape depend only of this shape
-
-    this._isAnimated = !!shape.k; // TODO: commenting this for now since all shapes are animated
-
+    this._isAnimated = !!shape.k;
+    // TODO: commenting this for now since all shapes are animated
     var i = 0;
     var len = transformers.length;
-
     while (i < len) {
       if (transformers[i].mProps.dynamicProperties.length) {
         this._isAnimated = true;
         break;
       }
-
       i += 1;
     }
   }
-
   SVGShapeData.prototype.setAsAnimated = function () {
     this._isAnimated = true;
   };
@@ -9695,7 +8257,6 @@
     this.pElem = createNS('path');
     this.msElem = null;
   }
-
   SVGStyleData.prototype.reset = function () {
     this.d = '';
     this._mdf = false;
@@ -9714,7 +8275,6 @@
     var i;
     var len = data.length || 0;
     var prop;
-
     for (i = 0; i < len; i += 1) {
       prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
       this.k = prop.k || this.k;
@@ -9723,31 +8283,24 @@
         p: prop
       };
     }
-
     if (!this.k) {
       this.getValue(true);
     }
-
     this._isAnimated = this.k;
   }
-
   DashProperty.prototype.getValue = function (forceRender) {
     if (this.elem.globalData.frameId === this.frameId && !forceRender) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
     this._mdf = this._mdf || forceRender;
-
     if (this._mdf) {
       var i = 0;
       var len = this.dataProps.length;
-
       if (this.renderer === 'svg') {
         this.dashStr = '';
       }
-
       for (i = 0; i < len; i += 1) {
         if (this.dataProps[i].n !== 'o') {
           if (this.renderer === 'svg') {
@@ -9761,7 +8314,6 @@
       }
     }
   };
-
   extendPrototype([DynamicPropertyContainer], DashProperty);
 
   function SVGStrokeStyleData(elem, data, styleOb) {
@@ -9774,7 +8326,6 @@
     this.style = styleOb;
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
 
   function SVGFillStyleData(elem, data, styleOb) {
@@ -9784,7 +8335,6 @@
     this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
 
   function SVGNoStyleData(elem, data, styleOb) {
@@ -9792,7 +8342,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
 
   function GradientProperty(elem, data, container) {
@@ -9809,88 +8358,69 @@
     this.k = this.prop.k;
     this.getValue(true);
   }
-
   GradientProperty.prototype.comparePoints = function (values, points) {
     var i = 0;
     var len = this.o.length / 2;
     var diff;
-
     while (i < len) {
       diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
-
       if (diff > 0.01) {
         return false;
       }
-
       i += 1;
     }
-
     return true;
   };
-
   GradientProperty.prototype.checkCollapsable = function () {
     if (this.o.length / 2 !== this.c.length / 4) {
       return false;
     }
-
     if (this.data.k.k[0].s) {
       var i = 0;
       var len = this.data.k.k.length;
-
       while (i < len) {
         if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
           return false;
         }
-
         i += 1;
       }
     } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
       return false;
     }
-
     return true;
   };
-
   GradientProperty.prototype.getValue = function (forceRender) {
     this.prop.getValue();
     this._mdf = false;
     this._cmdf = false;
     this._omdf = false;
-
     if (this.prop._mdf || forceRender) {
       var i;
       var len = this.data.p * 4;
       var mult;
       var val;
-
       for (i = 0; i < len; i += 1) {
         mult = i % 4 === 0 ? 100 : 255;
         val = Math.round(this.prop.v[i] * mult);
-
         if (this.c[i] !== val) {
           this.c[i] = val;
           this._cmdf = !forceRender;
         }
       }
-
       if (this.o.length) {
         len = this.prop.v.length;
-
         for (i = this.data.p * 4; i < len; i += 1) {
           mult = i % 2 === 0 ? 100 : 1;
           val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
-
           if (this.o[i - this.data.p * 4] !== val) {
             this.o[i - this.data.p * 4] = val;
             this._omdf = !forceRender;
           }
         }
       }
-
       this._mdf = !forceRender;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], GradientProperty);
 
   function SVGGradientFillStyleData(elem, data, styleOb) {
@@ -9898,7 +8428,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.initGradientData(elem, data, styleOb);
   }
-
   SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
     this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
     this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
@@ -9916,7 +8445,6 @@
     this.setGradientOpacity(data, styleOb);
     this._isAnimated = !!this._isAnimated;
   };
-
   SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
     var gradientId = createElementID();
     var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
@@ -9928,18 +8456,15 @@
     var j;
     var jLen;
     jLen = data.g.p * 4;
-
     for (j = 0; j < jLen; j += 4) {
       stop = createNS('stop');
       gfill.appendChild(stop);
       stops.push(stop);
     }
-
     pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
     this.gf = gfill;
     this.cst = stops;
   };
-
   SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
     if (this.g._hasOpacity && !this.g._collapsable) {
       var stop;
@@ -9957,25 +8482,20 @@
       opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
       jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
       var stops = this.stops;
-
       for (j = data.g.p * 4; j < jLen; j += 2) {
         stop = createNS('stop');
         stop.setAttribute('stop-color', 'rgb(255,255,255)');
         opFill.appendChild(stop);
         stops.push(stop);
       }
-
       maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
@@ -9983,7 +8503,6 @@
       styleOb.msElem = maskElement;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
 
   function SVGGradientStrokeStyleData(elem, data, styleOb) {
@@ -9994,7 +8513,6 @@
     this.initGradientData(elem, data, styleOb);
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
 
   function ShapeGroupData() {
@@ -10017,77 +8535,59 @@
     if (length === 0) {
       return '';
     }
-
     var _o = pathNodes.o;
     var _i = pathNodes.i;
     var _v = pathNodes.v;
     var i;
     var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
-
     for (i = 1; i < length; i += 1) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
     }
-
     if (closed && length) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
       shapeString += 'z';
     }
-
     return shapeString;
   };
 
   var SVGElementsRenderer = function () {
     var _identityMatrix = new Matrix();
-
     var _matrixHelper = new Matrix();
-
     var ob = {
       createRenderFunction: createRenderFunction
     };
-
     function createRenderFunction(data) {
       switch (data.ty) {
         case 'fl':
           return renderFill;
-
         case 'gf':
           return renderGradient;
-
         case 'gs':
           return renderGradientStroke;
-
         case 'st':
           return renderStroke;
-
         case 'sh':
         case 'el':
         case 'rc':
         case 'sr':
           return renderPath;
-
         case 'tr':
           return renderContentTransform;
-
         case 'no':
           return renderNoop;
-
         default:
           return null;
       }
     }
-
     function renderContentTransform(styleData, itemData, isFirstFrame) {
       if (isFirstFrame || itemData.transform.op._mdf) {
         itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
       }
-
       if (isFirstFrame || itemData.transform.mProps._mdf) {
         itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
       }
     }
-
     function renderNoop() {}
-
     function renderPath(styleData, itemData, isFirstFrame) {
       var j;
       var jLen;
@@ -10101,25 +8601,20 @@
       var mat;
       var iterations;
       var k;
-
       for (l = 0; l < lLen; l += 1) {
         redraw = itemData.sh._mdf || isFirstFrame;
-
         if (itemData.styles[l].lvl < lvl) {
           mat = _matrixHelper.reset();
           iterations = lvl - itemData.styles[l].lvl;
           k = itemData.transformers.length - 1;
-
           while (!redraw && iterations > 0) {
             redraw = itemData.transformers[k].mProps._mdf || redraw;
             iterations -= 1;
             k -= 1;
           }
-
           if (redraw) {
             iterations = lvl - itemData.styles[l].lvl;
             k = itemData.transformers.length - 1;
-
             while (iterations > 0) {
               mat.multiply(itemData.transformers[k].mProps.v);
               iterations -= 1;
@@ -10129,115 +8624,90 @@
         } else {
           mat = _identityMatrix;
         }
-
         paths = itemData.sh.paths;
         jLen = paths._length;
-
         if (redraw) {
           pathStringTransformed = '';
-
           for (j = 0; j < jLen; j += 1) {
             pathNodes = paths.shapes[j];
-
             if (pathNodes && pathNodes._length) {
               pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
             }
           }
-
           itemData.caches[l] = pathStringTransformed;
         } else {
           pathStringTransformed = itemData.caches[l];
         }
-
         itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
         itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
       }
     }
-
     function renderFill(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
-
       if (itemData.c._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
       }
     }
-
     function renderGradientStroke(styleData, itemData, isFirstFrame) {
       renderGradient(styleData, itemData, isFirstFrame);
       renderStroke(styleData, itemData, isFirstFrame);
     }
-
     function renderGradient(styleData, itemData, isFirstFrame) {
       var gfill = itemData.gf;
       var hasOpacity = itemData.g._hasOpacity;
       var pt1 = itemData.s.v;
       var pt2 = itemData.e.v;
-
       if (itemData.o._mdf || isFirstFrame) {
         var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
         itemData.style.pElem.setAttribute(attr, itemData.o.v);
       }
-
       if (itemData.s._mdf || isFirstFrame) {
         var attr1 = styleData.t === 1 ? 'x1' : 'cx';
         var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
         gfill.setAttribute(attr1, pt1[0]);
         gfill.setAttribute(attr2, pt1[1]);
-
         if (hasOpacity && !itemData.g._collapsable) {
           itemData.of.setAttribute(attr1, pt1[0]);
           itemData.of.setAttribute(attr2, pt1[1]);
         }
       }
-
       var stops;
       var i;
       var len;
       var stop;
-
       if (itemData.g._cmdf || isFirstFrame) {
         stops = itemData.cst;
         var cValues = itemData.g.c;
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
           stop.setAttribute('offset', cValues[i * 4] + '%');
           stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
         }
       }
-
       if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
         var oValues = itemData.g.o;
-
         if (itemData.g._collapsable) {
           stops = itemData.cst;
         } else {
           stops = itemData.ost;
         }
-
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
-
           if (!itemData.g._collapsable) {
             stop.setAttribute('offset', oValues[i * 2] + '%');
           }
-
           stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
         }
       }
-
       if (styleData.t === 1) {
         if (itemData.e._mdf || isFirstFrame) {
           gfill.setAttribute('x2', pt2[0]);
           gfill.setAttribute('y2', pt2[1]);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('x2', pt2[0]);
             itemData.of.setAttribute('y2', pt2[1]);
@@ -10245,112 +8715,93 @@
         }
       } else {
         var rad;
-
         if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
           rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           gfill.setAttribute('r', rad);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('r', rad);
           }
         }
-
-        if (itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
           if (!rad) {
             rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           }
-
           var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
           var percent = itemData.h.v;
-
           if (percent >= 1) {
             percent = 0.99;
           } else if (percent <= -1) {
             percent = -0.99;
           }
-
           var dist = rad * percent;
           var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
           var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
           gfill.setAttribute('fx', x);
           gfill.setAttribute('fy', y);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('fx', x);
             itemData.of.setAttribute('fy', y);
           }
-        } // gfill.setAttribute('fy','200');
-
+        }
+        // gfill.setAttribute('fy','200');
       }
     }
-
     function renderStroke(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
       var d = itemData.d;
-
       if (d && (d._mdf || isFirstFrame) && d.dashStr) {
         styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
         styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
       }
-
       if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
         styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
       }
-
       if (itemData.w._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
-
         if (styleElem.msElem) {
           styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
         }
       }
     }
-
     return ob;
   }();
 
   function SVGShapeElement(data, globalData, comp) {
     // List of drawable elements
-    this.shapes = []; // Full shape data
-
-    this.shapesData = data.shapes; // List of styles that will be applied to shapes
-
-    this.stylesList = []; // List of modifiers that will be applied to shapes
-
-    this.shapeModifiers = []; // List of items in shape tree
-
-    this.itemsData = []; // List of items in previous shape tree
-
-    this.processedElements = []; // List of animated components
-
+    this.shapes = [];
+    // Full shape data
+    this.shapesData = data.shapes;
+    // List of styles that will be applied to shapes
+    this.stylesList = [];
+    // List of modifiers that will be applied to shapes
+    this.shapeModifiers = [];
+    // List of items in shape tree
+    this.itemsData = [];
+    // List of items in previous shape tree
+    this.processedElements = [];
+    // List of animated components
     this.animatedContents = [];
-    this.initElement(data, globalData, comp); // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.initElement(data, globalData, comp);
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
     // List of elements that have been created
-
-    this.prevViewData = []; // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.prevViewData = [];
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
-
   SVGShapeElement.prototype.initSecondaryElement = function () {};
-
   SVGShapeElement.prototype.identityMatrix = new Matrix();
-
   SVGShapeElement.prototype.buildExpressionInterface = function () {};
-
   SVGShapeElement.prototype.createContent = function () {
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
   };
+
   /*
   This method searches for multiple shapes that affect a single element and one of them is animated
   */
-
-
   SVGShapeElement.prototype.filterUniqueShapes = function () {
     var i;
     var len = this.shapes.length;
@@ -10360,42 +8811,34 @@
     var style;
     var tempShapes = [];
     var areAnimated = false;
-
     for (j = 0; j < jLen; j += 1) {
       style = this.stylesList[j];
       areAnimated = false;
       tempShapes.length = 0;
-
       for (i = 0; i < len; i += 1) {
         shape = this.shapes[i];
-
         if (shape.styles.indexOf(style) !== -1) {
           tempShapes.push(shape);
           areAnimated = shape._isAnimated || areAnimated;
         }
       }
-
       if (tempShapes.length > 1 && areAnimated) {
         this.setShapesAsAnimated(tempShapes);
       }
     }
   };
-
   SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
     var i;
     var len = shapes.length;
-
     for (i = 0; i < len; i += 1) {
       shapes[i].setAsAnimated();
     }
   };
-
   SVGShapeElement.prototype.createStyleElement = function (data, level) {
     // TODO: prevent drawing of hidden styles
     var elementData;
     var styleOb = new SVGStyleData(data, level);
     var pathElement = styleOb.pElem;
-
     if (data.ty === 'st') {
       elementData = new SVGStrokeStyleData(this, data, styleOb);
     } else if (data.ty === 'fl') {
@@ -10404,7 +8847,6 @@
       var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
       elementData = new GradientConstructor(this, data, styleOb);
       this.globalData.defs.appendChild(elementData.gf);
-
       if (elementData.maskId) {
         this.globalData.defs.appendChild(elementData.ms);
         this.globalData.defs.appendChild(elementData.of);
@@ -10413,66 +8855,51 @@
     } else if (data.ty === 'no') {
       elementData = new SVGNoStyleData(this, data, styleOb);
     }
-
     if (data.ty === 'st' || data.ty === 'gs') {
       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);
       }
     }
-
     if (data.r === 2) {
       pathElement.setAttribute('fill-rule', 'evenodd');
     }
-
     if (data.ln) {
       pathElement.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       pathElement.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     this.stylesList.push(styleOb);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createGroupElement = function (data) {
     var elementData = new ShapeGroupData();
-
     if (data.ln) {
       elementData.gr.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       elementData.gr.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     return elementData;
   };
-
   SVGShapeElement.prototype.createTransformElement = function (data, container) {
     var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
     var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
     var ty = 4;
-
     if (data.ty === 'rc') {
       ty = 5;
     } else if (data.ty === 'el') {
@@ -10480,7 +8907,6 @@
     } else if (data.ty === 'sr') {
       ty = 7;
     }
-
     var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
     var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
     this.shapes.push(elementData);
@@ -10488,58 +8914,46 @@
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
     var i = 0;
     var len = this.animatedContents.length;
-
     while (i < len) {
       if (this.animatedContents[i].element === element) {
         return;
       }
-
       i += 1;
     }
-
     this.animatedContents.push({
       fn: SVGElementsRenderer.createRenderFunction(data),
       element: element,
       data: data
     });
   };
-
   SVGShapeElement.prototype.setElementStyles = function (elementData) {
     var arr = elementData.styles;
     var j;
     var jLen = this.stylesList.length;
-
     for (j = 0; j < jLen; j += 1) {
-      if (!this.stylesList[j].closed) {
+      if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
         arr.push(this.stylesList[j]);
       }
     }
   };
-
   SVGShapeElement.prototype.reloadShapes = function () {
     this._isFirstFrame = true;
     var i;
     var len = this.itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       this.prevViewData[i] = this.itemsData[i];
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
     len = this.dynamicProperties.length;
-
     for (i = 0; i < len; i += 1) {
       this.dynamicProperties[i].getValue();
     }
-
     this.renderModifiers();
   };
-
   SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
     var ownTransformers = [].concat(transformers);
     var i;
@@ -10551,43 +8965,35 @@
     var currentTransform;
     var modifier;
     var processedPos;
-
     for (i = len; i >= 0; i -= 1) {
       processedPos = this.searchProcessedElement(arr[i]);
-
       if (!processedPos) {
         arr[i]._render = render;
       } else {
         itemsData[i] = prevViewData[processedPos - 1];
       }
-
       if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
         if (!processedPos) {
           itemsData[i] = this.createStyleElement(arr[i], level);
         } else {
-          itemsData[i].style.closed = false;
+          itemsData[i].style.closed = arr[i].hd;
         }
-
         if (arr[i]._render) {
           if (itemsData[i].style.pElem.parentNode !== container) {
             container.appendChild(itemsData[i].style.pElem);
           }
         }
-
         ownStyles.push(itemsData[i].style);
       } else if (arr[i].ty === 'gr') {
         if (!processedPos) {
           itemsData[i] = this.createGroupElement(arr[i]);
         } else {
           jLen = itemsData[i].it.length;
-
           for (j = 0; j < jLen; j += 1) {
             itemsData[i].prevViewData[j] = itemsData[i].it[j];
           }
         }
-
         this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
-
         if (arr[i]._render) {
           if (itemsData[i].gr.parentNode !== container) {
             container.appendChild(itemsData[i].gr);
@@ -10597,14 +9003,12 @@
         if (!processedPos) {
           itemsData[i] = this.createTransformElement(arr[i], container);
         }
-
         currentTransform = itemsData[i].transform;
         ownTransformers.push(currentTransform);
       } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
         if (!processedPos) {
           itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
         }
-
         this.setElementStyles(itemsData[i]);
       } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
         if (!processedPos) {
@@ -10616,7 +9020,6 @@
           modifier = itemsData[i];
           modifier.closed = false;
         }
-
         ownModifiers.push(modifier);
       } else if (arr[i].ty === 'rp') {
         if (!processedPos) {
@@ -10629,64 +9032,49 @@
           modifier = itemsData[i];
           modifier.closed = true;
         }
-
         ownModifiers.push(modifier);
       }
-
       this.addProcessedElement(arr[i], i + 1);
     }
-
     len = ownStyles.length;
-
     for (i = 0; i < len; i += 1) {
       ownStyles[i].closed = true;
     }
-
     len = ownModifiers.length;
-
     for (i = 0; i < len; i += 1) {
       ownModifiers[i].closed = true;
     }
   };
-
   SVGShapeElement.prototype.renderInnerContent = function () {
     this.renderModifiers();
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       this.stylesList[i].reset();
     }
-
     this.renderShape();
-
     for (i = 0; i < len; i += 1) {
       if (this.stylesList[i]._mdf || this._isFirstFrame) {
         if (this.stylesList[i].msElem) {
-          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d); // Adding M0 0 fixes same mask bug on all browsers
-
+          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+          // Adding M0 0 fixes same mask bug on all browsers
           this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
         }
-
         this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
       }
     }
   };
-
   SVGShapeElement.prototype.renderShape = function () {
     var i;
     var len = this.animatedContents.length;
     var animatedContent;
-
     for (i = 0; i < len; i += 1) {
       animatedContent = this.animatedContents[i];
-
       if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
         animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
       }
     }
   };
-
   SVGShapeElement.prototype.destroy = function () {
     this.destroyBaseElement();
     this.shapesData = null;
@@ -10709,7 +9097,6 @@
       p: true
     };
   }
-
   LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
     this._mdf.o = false;
     this._mdf.sw = false;
@@ -10718,43 +9105,36 @@
     this._mdf.m = false;
     this._mdf.p = false;
     var updated = false;
-
     if (this.o !== o) {
       this.o = o;
       this._mdf.o = true;
       updated = true;
     }
-
     if (this.sw !== sw) {
       this.sw = sw;
       this._mdf.sw = true;
       updated = true;
     }
-
     if (this.sc !== sc) {
       this.sc = sc;
       this._mdf.sc = true;
       updated = true;
     }
-
     if (this.fc !== fc) {
       this.fc = fc;
       this._mdf.fc = true;
       updated = true;
     }
-
     if (this.m !== m) {
       this.m = m;
       this._mdf.m = true;
       updated = true;
     }
-
     if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
       this.p = p;
       this._mdf.p = true;
       updated = true;
     }
-
     return updated;
   };
 
@@ -10765,11 +9145,9 @@
     this.kf = false;
     this._isFirstFrame = true;
     this._mdf = false;
-
     if (data.d && data.d.sid) {
       data.d = elem.globalData.slotManager.getProp(data.d);
     }
-
     this.data = data;
     this.elem = elem;
     this.comp = this.elem.comp;
@@ -10808,73 +9186,57 @@
       __complete: false
     };
     this.copyData(this.currentData, this.data.d.k[0].s);
-
     if (!this.searchProperty()) {
       this.completeTextData(this.currentData);
     }
   }
-
   TextProperty.prototype.defaultBoxWidth = [0, 0];
-
   TextProperty.prototype.copyData = function (obj, data) {
     for (var s in data) {
       if (Object.prototype.hasOwnProperty.call(data, s)) {
         obj[s] = data[s];
       }
     }
-
     return obj;
   };
-
   TextProperty.prototype.setCurrentData = function (data) {
     if (!data.__complete) {
       this.completeTextData(data);
     }
-
     this.currentData = data;
     this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
     this._mdf = true;
   };
-
   TextProperty.prototype.searchProperty = function () {
     return this.searchKeyframes();
   };
-
   TextProperty.prototype.searchKeyframes = function () {
     this.kf = this.data.d.k.length > 1;
-
     if (this.kf) {
       this.addEffect(this.getKeyframeValue.bind(this));
     }
-
     return this.kf;
   };
-
   TextProperty.prototype.addEffect = function (effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.getValue = function (_finalValue) {
     if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
       return;
     }
-
     this.currentData.t = this.data.d.k[this.keysIndex].s.t;
     var currentValue = this.currentData;
     var currentIndex = this.keysIndex;
-
     if (this.lock) {
       this.setCurrentData(this.currentData);
       return;
     }
-
     this.lock = true;
     this._mdf = false;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
-
     for (i = 0; i < len; i += 1) {
       // Checking if index changed to prevent creating a new object every time the expression updates.
       if (currentIndex !== this.keysIndex) {
@@ -10883,38 +9245,30 @@
         finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
       }
     }
-
     if (currentValue !== finalValue) {
       this.setCurrentData(finalValue);
     }
-
     this.v = this.currentData;
     this.pv = this.v;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   };
-
   TextProperty.prototype.getKeyframeValue = function () {
     var textKeys = this.data.d.k;
     var frameNum = this.elem.comp.renderedFrame;
     var i = 0;
     var len = textKeys.length;
-
     while (i <= len - 1) {
       if (i === len - 1 || textKeys[i + 1].t > frameNum) {
         break;
       }
-
       i += 1;
     }
-
     if (this.keysIndex !== i) {
       this.keysIndex = i;
     }
-
     return this.data.d.k[this.keysIndex].s;
   };
-
   TextProperty.prototype.buildFinalText = function (text) {
     var charactersArray = [];
     var i = 0;
@@ -10924,21 +9278,20 @@
     var shouldCombine = false;
     var shouldCombineNext = false;
     var currentChars = '';
-
     while (i < len) {
       shouldCombine = shouldCombineNext;
       shouldCombineNext = false;
       charCode = text.charCodeAt(i);
       currentChars = text.charAt(i);
-
       if (FontManager.isCombinedCharacter(charCode)) {
-        shouldCombine = true; // It's a potential surrogate pair (this is the High surrogate)
+        shouldCombine = true;
+        // It's a potential surrogate pair (this is the High surrogate)
       } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
         if (FontManager.isRegionalFlag(text, i)) {
           currentChars = text.substr(i, 14);
         } else {
-          secondCharCode = text.charCodeAt(i + 1); // It's a surrogate pair (this is the Low surrogate)
-
+          secondCharCode = text.charCodeAt(i + 1);
+          // It's a surrogate pair (this is the Low surrogate)
           if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
             if (FontManager.isModifier(charCode, secondCharCode)) {
               currentChars = text.substr(i, 2);
@@ -10952,7 +9305,6 @@
         }
       } else if (charCode > 0xDBFF) {
         secondCharCode = text.charCodeAt(i + 1);
-
         if (FontManager.isVariationSelector(charCode)) {
           shouldCombine = true;
         }
@@ -10960,20 +9312,16 @@
         shouldCombine = true;
         shouldCombineNext = true;
       }
-
       if (shouldCombine) {
         charactersArray[charactersArray.length - 1] += currentChars;
         shouldCombine = false;
       } else {
         charactersArray.push(currentChars);
       }
-
       i += currentChars.length;
     }
-
     return charactersArray;
   };
-
   TextProperty.prototype.completeTextData = function (documentData) {
     documentData.__complete = true;
     var fontManager = this.elem.globalData.fontManager;
@@ -11005,14 +9353,12 @@
     documentData.finalLineHeight = documentData.lh;
     var trackingOffset = documentData.tr / 1000 * documentData.finalSize;
     var charCode;
-
     if (documentData.sz) {
       var flag = true;
       var boxWidth = documentData.sz[0];
       var boxHeight = documentData.sz[1];
       var currentHeight;
       var finalText;
-
       while (flag) {
         finalText = this.buildFinalText(documentData.t);
         currentHeight = 0;
@@ -11020,11 +9366,9 @@
         len = finalText.length;
         trackingOffset = documentData.tr / 1000 * documentData.finalSize;
         var lastSpaceIndex = -1;
-
         for (i = 0; i < len; i += 1) {
           charCode = finalText[i].charCodeAt(0);
           newLineFlag = false;
-
           if (finalText[i] === ' ') {
             lastSpaceIndex = i;
           } else if (charCode === 13 || charCode === 3) {
@@ -11032,7 +9376,6 @@
             newLineFlag = true;
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
           }
-
           if (fontManager.chars) {
             charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
             cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -11040,17 +9383,15 @@
             // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
             cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
           }
-
           if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
             if (lastSpaceIndex === -1) {
               len += 1;
             } else {
               i = lastSpaceIndex;
             }
-
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
-            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r'); // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
-
+            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+            // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
             lastSpaceIndex = -1;
             lineWidth = 0;
           } else {
@@ -11058,9 +9399,7 @@
             lineWidth += trackingOffset;
           }
         }
-
         currentHeight += fontData.ascent * documentData.finalSize / 100;
-
         if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
           documentData.finalSize -= 1;
           documentData.finalLineHeight = documentData.finalSize * documentData.lh / documentData.s;
@@ -11071,17 +9410,14 @@
         }
       }
     }
-
     lineWidth = -trackingOffset;
     cLength = 0;
     var uncollapsedSpaces = 0;
     var currentChar;
-
     for (i = 0; i < len; i += 1) {
       newLineFlag = false;
       currentChar = documentData.finalText[i];
       charCode = currentChar.charCodeAt(0);
-
       if (charCode === 13 || charCode === 3) {
         uncollapsedSpaces = 0;
         lineWidths.push(lineWidth);
@@ -11093,7 +9429,6 @@
       } else {
         val = currentChar;
       }
-
       if (fontManager.chars) {
         charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
         cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -11101,16 +9436,15 @@
         // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
         // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
         cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
-      } //
+      }
 
-
+      //
       if (currentChar === ' ') {
         uncollapsedSpaces += cLength + trackingOffset;
       } else {
         lineWidth += cLength + trackingOffset + uncollapsedSpaces;
         uncollapsedSpaces = 0;
       }
-
       letters.push({
         l: cLength,
         an: cLength,
@@ -11121,42 +9455,35 @@
         line: currentLine,
         animatorJustifyOffset: 0
       });
-
       if (anchorGrouping == 2) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || val === ' ' || i === len - 1) {
           if (val === '' || val === ' ') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           index += 1;
           currentSize = 0;
         }
       } else if (anchorGrouping == 3) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || i === len - 1) {
           if (val === '') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           currentSize = 0;
           index += 1;
         }
@@ -11166,31 +9493,25 @@
         index += 1;
       }
     }
-
     documentData.l = letters;
     maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
     lineWidths.push(lineWidth);
-
     if (documentData.sz) {
       documentData.boxWidth = documentData.sz[0];
       documentData.justifyOffset = 0;
     } else {
       documentData.boxWidth = maxLineWidth;
-
       switch (documentData.j) {
         case 1:
           documentData.justifyOffset = -documentData.boxWidth;
           break;
-
         case 2:
           documentData.justifyOffset = -documentData.boxWidth / 2;
           break;
-
         default:
           documentData.justifyOffset = 0;
       }
     }
-
     documentData.lineWidths = lineWidths;
     var animators = data.a;
     var animatorData;
@@ -11199,63 +9520,49 @@
     var based;
     var ind;
     var indexes = [];
-
     for (j = 0; j < jLen; j += 1) {
       animatorData = animators[j];
-
       if (animatorData.a.sc) {
         documentData.strokeColorAnim = true;
       }
-
       if (animatorData.a.sw) {
         documentData.strokeWidthAnim = true;
       }
-
       if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
         documentData.fillColorAnim = true;
       }
-
       ind = 0;
       based = animatorData.s.b;
-
       for (i = 0; i < len; i += 1) {
         letterData = letters[i];
         letterData.anIndexes[j] = ind;
-
         if (based == 1 && letterData.val !== '' || based == 2 && letterData.val !== '' && letterData.val !== ' ' || based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1) || based == 4 && (letterData.n || i == len - 1)) {
           // eslint-disable-line eqeqeq
           if (animatorData.s.rn === 1) {
             indexes.push(ind);
           }
-
           ind += 1;
         }
       }
-
       data.a[j].s.totalChars = ind;
       var currentInd = -1;
       var newInd;
-
       if (animatorData.s.rn === 1) {
         for (i = 0; i < len; i += 1) {
           letterData = letters[i];
-
           if (currentInd != letterData.anIndexes[j]) {
             // eslint-disable-line eqeqeq
             currentInd = letterData.anIndexes[j];
             newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
           }
-
           letterData.anIndexes[j] = newInd;
         }
       }
     }
-
     documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
     documentData.ls = documentData.ls || 0;
     documentData.ascent = fontData.ascent * documentData.finalSize / 100;
   };
-
   TextProperty.prototype.updateDocumentData = function (newData, index) {
     index = index === undefined ? this.keysIndex : index;
     var dData = this.copyData({}, this.data.d.k[index].s);
@@ -11265,7 +9572,6 @@
     this.setCurrentData(dData);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.recalculate = function (index) {
     var dData = this.data.d.k[index].s;
     dData.__complete = false;
@@ -11273,13 +9579,11 @@
     this._isFirstFrame = true;
     this.getValue(dData);
   };
-
   TextProperty.prototype.canResizeFont = function (_canResize) {
     this.canResize = _canResize;
     this.recalculate(this.keysIndex);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
     this.minimumFontSize = Math.floor(_fontValue) || 1;
     this.recalculate(this.keysIndex);
@@ -11290,7 +9594,6 @@
     var max = Math.max;
     var min = Math.min;
     var floor = Math.floor;
-
     function TextSelectorPropFactory(elem, data) {
       this._currentTextLength = -1;
       this.k = false;
@@ -11303,7 +9606,6 @@
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: 0
       }, 0, 0, this);
-
       if ('e' in data) {
         this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
       } else {
@@ -11311,7 +9613,6 @@
           v: 100
         };
       }
-
       this.o = PropertyFactory.getProp(elem, data.o || {
         k: 0
       }, 0, 0, this);
@@ -11325,48 +9626,40 @@
         k: 100
       }, 0, 0, this);
       this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
-
       if (!this.dynamicProperties.length) {
         this.getValue();
       }
     }
-
     TextSelectorPropFactory.prototype = {
       getMult: function getMult(ind) {
         if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
           this.getValue();
         }
-
         var x1 = 0;
         var y1 = 0;
         var x2 = 1;
         var y2 = 1;
-
         if (this.ne.v > 0) {
           x1 = this.ne.v / 100.0;
         } else {
           y1 = -this.ne.v / 100.0;
         }
-
         if (this.xe.v > 0) {
           x2 = 1.0 - this.xe.v / 100.0;
         } else {
           y2 = 1.0 + this.xe.v / 100.0;
         }
-
         var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
         var mult = 0;
         var s = this.finalS;
         var e = this.finalE;
         var type = this.data.sh;
-
         if (type === 2) {
           if (e === s) {
             mult = ind >= e ? 1 : 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 3) {
           if (e === s) {
@@ -11374,21 +9667,18 @@
           } else {
             mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 4) {
           if (e === s) {
             mult = 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
-
             if (mult < 0.5) {
               mult *= 2;
             } else {
               mult = 1 - 2 * (mult - 0.5);
             }
           }
-
           mult = easer(mult);
         } else if (type === 5) {
           if (e === s) {
@@ -11397,13 +9687,11 @@
             var tot = e - s;
             /* ind += 0.5;
                       mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
-
             ind = min(max(0, ind + 0.5 - s), e - s);
             var x = -tot / 2 + ind;
             var a = tot / 2;
             mult = Math.sqrt(1 - x * x / (a * a));
           }
-
           mult = easer(mult);
         } else if (type === 6) {
           if (e === s) {
@@ -11412,7 +9700,6 @@
             ind = min(max(0, ind + 0.5 - s), e - s);
             mult = (1 + Math.cos(Math.PI + Math.PI * 2 * ind / (e - s))) / 2; // eslint-disable-line
           }
-
           mult = easer(mult);
         } else {
           if (ind >= floor(s)) {
@@ -11422,9 +9709,9 @@
               mult = max(0, min(e - ind, 1));
             }
           }
-
           mult = easer(mult);
-        } // Smoothness implementation.
+        }
+        // Smoothness implementation.
         // The smoothness represents a reduced range of the original [0; 1] range.
         // if smoothness is 25%, the new range will be [0.375; 0.625]
         // Steps are:
@@ -11434,60 +9721,47 @@
         //     - subtract the threshold
         //     - divide it by the smoothness (this will return the range to [0; 1])
         // Note: If it doesn't work on some scenarios, consider applying it before the easer.
-
-
         if (this.sm.v !== 100) {
           var smoothness = this.sm.v * 0.01;
-
           if (smoothness === 0) {
             smoothness = 0.00000001;
           }
-
           var threshold = 0.5 - smoothness * 0.5;
-
           if (mult < threshold) {
             mult = 0;
           } else {
             mult = (mult - threshold) / smoothness;
-
             if (mult > 1) {
               mult = 1;
             }
           }
         }
-
         return mult * this.a.v;
       },
       getValue: function getValue(newCharsFlag) {
         this.iterateDynamicProperties();
         this._mdf = newCharsFlag || this._mdf;
         this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
-
         if (newCharsFlag && this.data.r === 2) {
           this.e.v = this._currentTextLength;
         }
-
         var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
         var o = this.o.v / divisor;
         var s = this.s.v / divisor + o;
         var e = this.e.v / divisor + o;
-
         if (s > e) {
           var _s = s;
           s = e;
           e = _s;
         }
-
         this.finalS = s;
         this.finalE = e;
       }
     };
     extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
-
     function getTextSelectorProp(elem, data, arr) {
       return new TextSelectorPropFactory(elem, data, arr);
     }
-
     return {
       getTextSelectorProp: getTextSelectorProp
     };
@@ -11537,18 +9811,15 @@
     this.lettersChangedFlag = false;
     this.initDynamicPropertyContainer(elem);
   }
-
   TextAnimatorProperty.prototype.searchProperties = function () {
     var i;
     var len = this._textData.a.length;
     var animatorProps;
     var getProp = PropertyFactory.getProp;
-
     for (i = 0; i < len; i += 1) {
       animatorProps = this._textData.a[i];
       this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
     }
-
     if (this._textData.p && 'm' in this._textData.p) {
       this._pathData = {
         a: getProp(this._elem, this._textData.p.a, 0, 0, this),
@@ -11562,17 +9833,13 @@
     } else {
       this._hasMaskedPath = false;
     }
-
     this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
   };
-
   TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
     this.lettersChangedFlag = lettersChangedFlag;
-
     if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
       return;
     }
-
     this._isFirstFrame = false;
     var alignment = this._moreOptions.alignment.v;
     var animators = this._animatorsData;
@@ -11600,18 +9867,14 @@
     var perc;
     var tanAngle;
     var mask;
-
     if (this._hasMaskedPath) {
       mask = this._pathData.m;
-
       if (!this._pathData.n || this._pathData._mdf) {
         var paths = mask.v;
-
         if (this._pathData.r.v) {
           paths = paths.reverse();
-        } // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
-
-
+        }
+        // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
         pathInfo = {
           tLength: 0,
           segments: []
@@ -11619,26 +9882,21 @@
         len = paths._length - 1;
         var bezierData;
         totalLength = 0;
-
         for (i = 0; i < len; i += 1) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[i + 1], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         i = len;
-
         if (mask.v.c) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[0], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         this._pathData.pi = pathInfo;
       }
-
       pathInfo = this._pathData.pi;
       currentLength = this._pathData.f.v;
       segmentInd = 0;
@@ -11646,20 +9904,16 @@
       segmentLength = 0;
       flag = true;
       segments = pathInfo.segments;
-
       if (currentLength < 0 && mask.v.c) {
         if (pathInfo.tLength < Math.abs(currentLength)) {
           currentLength = -Math.abs(currentLength) % pathInfo.tLength;
         }
-
         segmentInd = segments.length - 1;
         points = segments[segmentInd].points;
         pointInd = points.length - 1;
-
         while (currentLength < 0) {
           currentLength += points[pointInd].partialLength;
           pointInd -= 1;
-
           if (pointInd < 0) {
             segmentInd -= 1;
             points = segments[segmentInd].points;
@@ -11667,13 +9921,11 @@
           }
         }
       }
-
       points = segments[segmentInd].points;
       prevPoint = points[pointInd - 1];
       currentPoint = points[pointInd];
       partialLength = currentPoint.partialLength;
     }
-
     len = letters.length;
     xPos = 0;
     yPos = 0;
@@ -11704,40 +9956,35 @@
     var letterFc;
     var letterM = '';
     var letterP = this.defaultPropsArray;
-    var letterO; //
+    var letterO;
 
+    //
     if (documentData.j === 2 || documentData.j === 1) {
       var animatorJustifyOffset = 0;
       var animatorFirstCharOffset = 0;
       var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
       var lastIndex = 0;
       var isNewLine = true;
-
       for (i = 0; i < len; i += 1) {
         if (letters[i].n) {
           if (animatorJustifyOffset) {
             animatorJustifyOffset += animatorFirstCharOffset;
           }
-
           while (lastIndex < i) {
             letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
             lastIndex += 1;
           }
-
           animatorJustifyOffset = 0;
           isNewLine = true;
         } else {
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.t.propType) {
               if (isNewLine && documentData.j === 2) {
                 animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
               }
-
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
               } else {
@@ -11745,33 +9992,28 @@
               }
             }
           }
-
           isNewLine = false;
         }
       }
-
       if (animatorJustifyOffset) {
         animatorJustifyOffset += animatorFirstCharOffset;
       }
-
       while (lastIndex < i) {
         letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
         lastIndex += 1;
       }
-    } //
-
+    }
+    //
 
     for (i = 0; i < len; i += 1) {
       matrixHelper.reset();
       elemOpacity = 1;
-
       if (letters[i].n) {
         xPos = 0;
         yPos += documentData.yOffset;
         yPos += firstLine ? 1 : 0;
         currentLength = initPathPos;
         firstLine = false;
-
         if (this._hasMaskedPath) {
           segmentInd = initSegmentInd;
           pointInd = initPointInd;
@@ -11781,7 +10023,6 @@
           partialLength = currentPoint.partialLength;
           segmentLength = 0;
         }
-
         letterM = '';
         letterFc = '';
         letterSw = '';
@@ -11794,48 +10035,37 @@
               case 1:
                 currentLength += totalLength - documentData.lineWidths[letters[i].line];
                 break;
-
               case 2:
                 currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
                 break;
-
               default:
                 break;
             }
-
             currentLine = letters[i].line;
           }
-
           if (ind !== letters[i].ind) {
             if (letters[ind]) {
               currentLength += letters[ind].extra;
             }
-
             currentLength += letters[i].an / 2;
             ind = letters[i].ind;
           }
-
           currentLength += alignment[0] * letters[i].an * 0.005;
           var animatorOffset = 0;
-
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.p.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.p.v[0] * mult[0];
               } else {
                 animatorOffset += animatorProps.p.v[0] * mult;
               }
             }
-
             if (animatorProps.a.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.a.v[0] * mult[0];
               } else {
@@ -11843,14 +10073,12 @@
               }
             }
           }
-
-          flag = true; // Force alignment only works with a single line for now
-
+          flag = true;
+          // Force alignment only works with a single line for now
           if (this._pathData.a.v) {
             currentLength = letters[0].an * 0.5 + (totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind / (len - 1);
             currentLength += this._pathData.f.v;
           }
-
           while (flag) {
             if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
               perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
@@ -11861,11 +10089,9 @@
             } else if (points) {
               segmentLength += currentPoint.partialLength;
               pointInd += 1;
-
               if (pointInd >= points.length) {
                 pointInd = 0;
                 segmentInd += 1;
-
                 if (!segments[segmentInd]) {
                   if (mask.v.c) {
                     pointInd = 0;
@@ -11879,7 +10105,6 @@
                   points = segments[segmentInd].points;
                 }
               }
-
               if (points) {
                 prevPoint = currentPoint;
                 currentPoint = points[pointInd];
@@ -11887,23 +10112,21 @@
               }
             }
           }
-
           offf = letters[i].an / 2 - letters[i].add;
           matrixHelper.translate(-offf, 0, 0);
         } else {
           offf = letters[i].an / 2 - letters[i].add;
-          matrixHelper.translate(-offf, 0, 0); // Grouping alignment
+          matrixHelper.translate(-offf, 0, 0);
 
+          // Grouping alignment
           matrixHelper.translate(-alignment[0] * letters[i].an * 0.005, -alignment[1] * yOff * 0.01, 0);
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.t.propType) {
             animatorSelector = animators[j].s;
-            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars); // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
-
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
             if (xPos !== 0 || documentData.j !== 0) {
               if (this._hasMaskedPath) {
                 if (mult.length) {
@@ -11919,11 +10142,9 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           sw = documentData.sw || 0;
         }
-
         if (documentData.strokeColorAnim) {
           if (documentData.sc) {
             sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
@@ -11931,18 +10152,14 @@
             sc = [0, 0, 0];
           }
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.a.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
             } else {
@@ -11950,14 +10167,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.s.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.scale(1 + (animatorProps.s.v[0] - 1) * mult[0], 1 + (animatorProps.s.v[1] - 1) * mult[1], 1);
             } else {
@@ -11965,12 +10179,10 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
           animatorSelector = animators[j].s;
           mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
           if (animatorProps.sk.propType) {
             if (mult.length) {
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
@@ -11978,7 +10190,6 @@
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
             }
           }
-
           if (animatorProps.r.propType) {
             if (mult.length) {
               matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
@@ -11986,7 +10197,6 @@
               matrixHelper.rotateZ(-animatorProps.r.v * mult);
             }
           }
-
           if (animatorProps.ry.propType) {
             if (mult.length) {
               matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
@@ -11994,7 +10204,6 @@
               matrixHelper.rotateY(animatorProps.ry.v * mult);
             }
           }
-
           if (animatorProps.rx.propType) {
             if (mult.length) {
               matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
@@ -12002,7 +10211,6 @@
               matrixHelper.rotateX(animatorProps.rx.v * mult);
             }
           }
-
           if (animatorProps.o.propType) {
             if (mult.length) {
               elemOpacity += (animatorProps.o.v * mult[0] - elemOpacity) * mult[0];
@@ -12010,7 +10218,6 @@
               elemOpacity += (animatorProps.o.v * mult - elemOpacity) * mult;
             }
           }
-
           if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
             if (mult.length) {
               sw += animatorProps.sw.v * mult[0];
@@ -12018,7 +10225,6 @@
               sw += animatorProps.sw.v * mult;
             }
           }
-
           if (documentData.strokeColorAnim && animatorProps.sc.propType) {
             for (k = 0; k < 3; k += 1) {
               if (mult.length) {
@@ -12028,7 +10234,6 @@
               }
             }
           }
-
           if (documentData.fillColorAnim && documentData.fc) {
             if (animatorProps.fc.propType) {
               for (k = 0; k < 3; k += 1) {
@@ -12039,7 +10244,6 @@
                 }
               }
             }
-
             if (animatorProps.fh.propType) {
               if (mult.length) {
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
@@ -12047,7 +10251,6 @@
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult);
               }
             }
-
             if (animatorProps.fs.propType) {
               if (mult.length) {
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
@@ -12055,7 +10258,6 @@
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
               }
             }
-
             if (animatorProps.fb.propType) {
               if (mult.length) {
                 fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
@@ -12065,14 +10267,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.p.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (this._hasMaskedPath) {
               if (mult.length) {
                 matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
@@ -12086,68 +10285,53 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           letterSw = sw < 0 ? 0 : sw;
         }
-
         if (documentData.strokeColorAnim) {
           letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
         }
-
         if (this._hasMaskedPath) {
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(0, alignment[1] * yOff * 0.01 + yPos, 0);
-
           if (this._pathData.p.v) {
             tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
             var rot = Math.atan(tanAngle) * 180 / Math.PI;
-
             if (currentPoint.point[0] < prevPoint.point[0]) {
               rot += 180;
             }
-
             matrixHelper.rotate(-rot * Math.PI / 180);
           }
-
           matrixHelper.translate(xPathPos, yPathPos, 0);
           currentLength -= alignment[0] * letters[i].an * 0.005;
-
           if (letters[i + 1] && ind !== letters[i + 1].ind) {
             currentLength += letters[i].an / 2;
             currentLength += documentData.tr * 0.001 * documentData.finalSize;
           }
         } else {
           matrixHelper.translate(xPos, yPos, 0);
-
           if (documentData.ps) {
             // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
             matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
           }
-
           switch (documentData.j) {
             case 1:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
               break;
-
             case 2:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
               break;
-
             default:
               break;
           }
-
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(offf, 0, 0);
           matrixHelper.translate(alignment[0] * letters[i].an * 0.005, alignment[1] * yOff * 0.01, 0);
           xPos += letters[i].l + documentData.tr * 0.001 * documentData.finalSize;
         }
-
         if (renderType === 'html') {
           letterM = matrixHelper.toCSS();
         } else if (renderType === 'svg') {
@@ -12155,10 +10339,8 @@
         } else {
           letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
         }
-
         letterO = elemOpacity;
       }
-
       if (renderedLettersCount <= i) {
         letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
         this.renderedLetters.push(letterValue);
@@ -12170,22 +10352,18 @@
       }
     }
   };
-
   TextAnimatorProperty.prototype.getValue = function () {
     if (this._elem.globalData.frameId === this._frameId) {
       return;
     }
-
     this._frameId = this._elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   TextAnimatorProperty.prototype.mHelper = new Matrix();
   TextAnimatorProperty.prototype.defaultPropsArray = [];
   extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
 
   function ITextElement() {}
-
   ITextElement.prototype.initElement = function (data, globalData, comp) {
     this.lettersChangedFlag = true;
     this.initFrame();
@@ -12202,72 +10380,55 @@
     this.hide();
     this.textAnimator.searchProperties(this.dynamicProperties);
   };
-
   ITextElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
   };
-
   ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
     var j;
     var jLen = shapes.length;
     var pathNodes;
     var shapeStr = '';
-
     for (j = 0; j < jLen; j += 1) {
       if (shapes[j].ty === 'sh') {
         pathNodes = shapes[j].ks.k;
         shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
       }
     }
-
     return shapeStr;
   };
-
   ITextElement.prototype.updateDocumentData = function (newData, index) {
     this.textProperty.updateDocumentData(newData, index);
   };
-
   ITextElement.prototype.canResizeFont = function (_canResize) {
     this.textProperty.canResizeFont(_canResize);
   };
-
   ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
     this.textProperty.setMinimumFontSize(_fontSize);
   };
-
   ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
     if (documentData.ps) {
       matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
     }
-
     matrixHelper.translate(0, -documentData.ls, 0);
-
     switch (documentData.j) {
       case 1:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
         break;
-
       case 2:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
         break;
-
       default:
         break;
     }
-
     matrixHelper.translate(xPos, yPos, 0);
   };
-
   ITextElement.prototype.buildColor = function (colorData) {
     return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
   };
-
   ITextElement.prototype.emptyProp = new LetterProps();
-
   ITextElement.prototype.destroy = function () {};
-
   ITextElement.prototype.validateText = function () {
     if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
       this.buildNewText();
@@ -12279,27 +10440,22 @@
   var emptyShapeData = {
     shapes: []
   };
-
   function SVGTextLottieElement(data, globalData, comp) {
     this.textSpans = [];
     this.renderType = 'svg';
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
-
   SVGTextLottieElement.prototype.createContent = function () {
     if (this.data.singleShape && !this.globalData.fontManager.chars) {
       this.textContainer = createNS('text');
     }
   };
-
   SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
     var i = 0;
     var len = textArray.length;
     var textContents = [];
     var currentTextContent = '';
-
     while (i < len) {
       if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
         textContents.push(currentTextContent);
@@ -12307,14 +10463,11 @@
       } else {
         currentTextContent += textArray[i];
       }
-
       i += 1;
     }
-
     textContents.push(currentTextContent);
     return textContents;
   };
-
   SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
     // data should probably be cloned to apply scale separately to each instance of a text on different layers
     // but since text internal content gets only rendered once and then it's never rerendered,
@@ -12322,41 +10475,33 @@
     // Avoiding cloning is preferred since cloning each character shape data is expensive
     if (data.shapes && data.shapes.length) {
       var shape = data.shapes[0];
-
       if (shape.it) {
         var shapeItem = shape.it[shape.it.length - 1];
-
         if (shapeItem.s) {
           shapeItem.s.k[0] = scale;
           shapeItem.s.k[1] = scale;
         }
       }
     }
-
     return data;
   };
-
   SVGTextLottieElement.prototype.buildNewText = function () {
     this.addDynamicProperty(this);
     var i;
     var len;
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
-
     if (documentData.fc) {
       this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
     } else {
       this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
     }
-
     if (documentData.sc) {
       this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
       this.layerElement.setAttribute('stroke-width', documentData.sw);
     }
-
     this.layerElement.setAttribute('font-size', documentData.finalSize);
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
-
     if (fontData.fClass) {
       this.layerElement.setAttribute('class', fontData.fClass);
     } else {
@@ -12366,7 +10511,6 @@
       this.layerElement.setAttribute('font-style', fStyle);
       this.layerElement.setAttribute('font-weight', fWeight);
     }
-
     this.layerElement.setAttribute('aria-label', documentData.t);
     var letters = documentData.l || [];
     var usesGlyphs = !!this.globalData.fontManager.chars;
@@ -12379,31 +10523,25 @@
     var yPos = 0;
     var firstLine = true;
     var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
-
     if (singleShape && !usesGlyphs && !documentData.sz) {
       var tElement = this.textContainer;
       var justify = 'start';
-
       switch (documentData.j) {
         case 1:
           justify = 'end';
           break;
-
         case 2:
           justify = 'middle';
           break;
-
         default:
           justify = 'start';
           break;
       }
-
       tElement.setAttribute('text-anchor', justify);
       tElement.setAttribute('letter-spacing', trackingOffset);
       var textContent = this.buildTextContents(documentData.finalText);
       len = textContent.length;
       yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
-
       for (i = 0; i < len; i += 1) {
         tSpan = this.textSpans[i].span || createNS('tspan');
         tSpan.textContent = textContent[i];
@@ -12411,23 +10549,19 @@
         tSpan.setAttribute('y', yPos);
         tSpan.style.display = 'inherit';
         tElement.appendChild(tSpan);
-
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
             span: null,
             glyph: null
           };
         }
-
         this.textSpans[i].span = tSpan;
         yPos += documentData.finalLineHeight;
       }
-
       this.layerElement.appendChild(tElement);
     } else {
       var cachedSpansLength = this.textSpans.length;
       var charData;
-
       for (i = 0; i < len; i += 1) {
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
@@ -12436,31 +10570,24 @@
             glyph: null
           };
         }
-
         if (!usesGlyphs || !singleShape || i === 0) {
           tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
-
           if (cachedSpansLength <= i) {
             tSpan.setAttribute('stroke-linecap', 'butt');
             tSpan.setAttribute('stroke-linejoin', 'round');
             tSpan.setAttribute('stroke-miterlimit', '4');
             this.textSpans[i].span = tSpan;
-
             if (usesGlyphs) {
               var childSpan = createNS('g');
               tSpan.appendChild(childSpan);
               this.textSpans[i].childSpan = childSpan;
             }
-
             this.textSpans[i].span = tSpan;
             this.layerElement.appendChild(tSpan);
           }
-
           tSpan.style.display = 'inherit';
         }
-
         matrixHelper.reset();
-
         if (singleShape) {
           if (letters[i].n) {
             xPos = -trackingOffset;
@@ -12468,42 +10595,36 @@
             yPos += firstLine ? 1 : 0;
             firstLine = false;
           }
-
           this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
-          xPos += letters[i].l || 0; // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
-
+          xPos += letters[i].l || 0;
+          // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
           xPos += trackingOffset;
         }
-
         if (usesGlyphs) {
           charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
-          var glyphElement; // t === 1 means the character has been replaced with an animated shaped
-
+          var glyphElement;
+          // t === 1 means the character has been replaced with an animated shaped
           if (charData.t === 1) {
             glyphElement = new SVGCompElement(charData.data, this.globalData, this);
           } else {
             var data = emptyShapeData;
-
             if (charData.data && charData.data.shapes) {
               data = this.buildShapeData(charData.data, documentData.finalSize);
             }
-
             glyphElement = new SVGShapeElement(data, this.globalData, this);
           }
-
           if (this.textSpans[i].glyph) {
             var glyph = this.textSpans[i].glyph;
             this.textSpans[i].childSpan.removeChild(glyph.layerElement);
             glyph.destroy();
           }
-
           this.textSpans[i].glyph = glyphElement;
           glyphElement._debug = true;
           glyphElement.prepareFrame(0);
           glyphElement.renderFrame();
-          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement); // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+          // when using animated shapes, the layer will be scaled instead of replacing the internal scale
           // this might have issues with strokes and might need a different solution
-
           if (charData.t === 1) {
             this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
           }
@@ -12511,30 +10632,24 @@
           if (singleShape) {
             tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
           }
-
           tSpan.textContent = letters[i].val;
           tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
-        } //
-
+        }
+        //
       }
-
       if (singleShape && tSpan) {
         tSpan.setAttribute('d', shapeStr);
       }
     }
-
     while (i < this.textSpans.length) {
       this.textSpans[i].span.style.display = 'none';
       i += 1;
     }
-
     this._sizeChanged = true;
   };
-
   SVGTextLottieElement.prototype.sourceRectAtTime = function () {
     this.prepareFrame(this.comp.renderedFrame - this.data.st);
     this.renderInnerContent();
-
     if (this._sizeChanged) {
       this._sizeChanged = false;
       var textBox = this.layerElement.getBBox();
@@ -12545,35 +10660,27 @@
         height: textBox.height
       };
     }
-
     return this.bbox;
   };
-
   SVGTextLottieElement.prototype.getValue = function () {
     var i;
     var len = this.textSpans.length;
     var glyphElement;
     this.renderedFrame = this.comp.renderedFrame;
-
     for (i = 0; i < len; i += 1) {
       glyphElement = this.textSpans[i].glyph;
-
       if (glyphElement) {
         glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
-
         if (glyphElement._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   SVGTextLottieElement.prototype.renderInnerContent = function () {
     this.validateText();
-
     if (!this.data.singleShape || this._mdf) {
       this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
-
       if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
         this._sizeChanged = true;
         var i;
@@ -12584,33 +10691,26 @@
         var renderedLetter;
         var textSpan;
         var glyphElement;
-
         for (i = 0; i < len; i += 1) {
           if (!letters[i].n) {
             renderedLetter = renderedLetters[i];
             textSpan = this.textSpans[i].span;
             glyphElement = this.textSpans[i].glyph;
-
             if (glyphElement) {
               glyphElement.renderFrame();
             }
-
             if (renderedLetter._mdf.m) {
               textSpan.setAttribute('transform', renderedLetter.m);
             }
-
             if (renderedLetter._mdf.o) {
               textSpan.setAttribute('opacity', renderedLetter.o);
             }
-
             if (renderedLetter._mdf.sw) {
               textSpan.setAttribute('stroke-width', renderedLetter.sw);
             }
-
             if (renderedLetter._mdf.sc) {
               textSpan.setAttribute('stroke', renderedLetter.sc);
             }
-
             if (renderedLetter._mdf.fc) {
               textSpan.setAttribute('fill', renderedLetter.fc);
             }
@@ -12623,14 +10723,12 @@
   function ISolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([IImageElement], ISolidElement);
-
   ISolidElement.prototype.createContent = function () {
-    var rect = createNS('rect'); /// /rect.style.width = this.data.sw;
+    var rect = createNS('rect');
+    /// /rect.style.width = this.data.sw;
     /// /rect.style.height = this.data.sh;
     /// /rect.style.fill = this.data.sc;
-
     rect.setAttribute('width', this.data.sw);
     rect.setAttribute('height', this.data.sh);
     rect.setAttribute('fill', this.data.sc);
@@ -12644,59 +10742,43 @@
     this.initTransform(data, globalData, comp);
     this.initHierarchy();
   }
-
   NullElement.prototype.prepareFrame = function (num) {
     this.prepareProperties(num, true);
   };
-
   NullElement.prototype.renderFrame = function () {};
-
   NullElement.prototype.getBaseElement = function () {
     return null;
   };
-
   NullElement.prototype.destroy = function () {};
-
   NullElement.prototype.sourceRectAtTime = function () {};
-
   NullElement.prototype.hide = function () {};
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
 
   function SVGRendererBase() {}
-
   extendPrototype([BaseRenderer], SVGRendererBase);
-
   SVGRendererBase.prototype.createNull = function (data) {
     return new NullElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createShape = function (data) {
     return new SVGShapeElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createText = function (data) {
     return new SVGTextLottieElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createImage = function (data) {
     return new IImageElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createSolid = function (data) {
     return new ISolidElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.configAnimation = function (animData) {
     this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
     this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
-
     if (this.renderConfig.viewBoxSize) {
       this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
     } else {
       this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
     }
-
     if (!this.renderConfig.viewBoxOnly) {
       this.svgElement.setAttribute('width', animData.w);
       this.svgElement.setAttribute('height', animData.h);
@@ -12705,32 +10787,26 @@
       this.svgElement.style.transform = 'translate3d(0,0,0)';
       this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
     }
-
     if (this.renderConfig.width) {
       this.svgElement.setAttribute('width', this.renderConfig.width);
     }
-
     if (this.renderConfig.height) {
       this.svgElement.setAttribute('height', this.renderConfig.height);
     }
-
     if (this.renderConfig.className) {
       this.svgElement.setAttribute('class', this.renderConfig.className);
     }
-
     if (this.renderConfig.id) {
       this.svgElement.setAttribute('id', this.renderConfig.id);
     }
-
     if (this.renderConfig.focusable !== undefined) {
       this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
     }
-
-    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio); // this.layerElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+    // this.layerElement.style.transform = 'translate3d(0,0,0)';
     // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
-
-    this.animationItem.wrapper.appendChild(this.svgElement); // Mask animation
-
+    this.animationItem.wrapper.appendChild(this.svgElement);
+    // Mask animation
     var defs = this.globalData.defs;
     this.setupGlobalData(animData, defs);
     this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
@@ -12749,71 +10825,54 @@
     this.layers = animData.layers;
     this.elements = createSizedArray(animData.layers.length);
   };
-
   SVGRendererBase.prototype.destroy = function () {
     if (this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     this.layerElement = null;
     this.globalData.defs = null;
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.destroyed = true;
     this.animationItem = null;
   };
-
   SVGRendererBase.prototype.updateContainerSize = function () {};
-
   SVGRendererBase.prototype.findIndexByInd = function (ind) {
     var i = 0;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.layers[i].ind === ind) {
         return i;
       }
     }
-
     return -1;
   };
-
   SVGRendererBase.prototype.buildItem = function (pos) {
     var elements = this.elements;
-
     if (elements[pos] || this.layers[pos].ty === 99) {
       return;
     }
-
     elements[pos] = true;
     var element = this.createItem(this.layers[pos]);
     elements[pos] = element;
-
     if (getExpressionsPlugin()) {
       if (this.layers[pos].ty === 0) {
         this.globalData.projectInterface.registerComposition(element);
       }
-
       element.initExpressions();
     }
-
     this.appendElementInPos(element, pos);
-
     if (this.layers[pos].tt) {
       var elementIndex = 'tp' in this.layers[pos] ? this.findIndexByInd(this.layers[pos].tp) : pos - 1;
-
       if (elementIndex === -1) {
         return;
       }
-
       if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
         this.buildItem(elementIndex);
         this.addPendingElement(element);
@@ -12824,16 +10883,13 @@
       }
     }
   };
-
   SVGRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
-
       if (element.data.tt) {
         var i = 0;
         var len = this.elements.length;
-
         while (i < len) {
           if (this.elements[i] === element) {
             var elementIndex = 'tp' in element.data ? this.findIndexByInd(element.data.tp) : i - 1;
@@ -12842,43 +10898,36 @@
             element.setMatte(matteMask);
             break;
           }
-
           i += 1;
         }
       }
     }
   };
-
   SVGRendererBase.prototype.renderFrame = function (num) {
     if (this.renderedFrame === num || this.destroyed) {
       return;
     }
-
     if (num === null) {
       num = this.renderedFrame;
     } else {
       this.renderedFrame = num;
-    } // console.log('-------');
+    }
+    // console.log('-------');
     // console.log('FRAME ',num);
-
-
     this.globalData.frameNum = num;
     this.globalData.frameId += 1;
     this.globalData.projectInterface.currentFrame = num;
     this.globalData._mdf = false;
     var i;
     var len = this.layers.length;
-
     if (!this.completeLayers) {
       this.checkLayers(num);
     }
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(num - this.layers[i].st);
       }
     }
-
     if (this.globalData._mdf) {
       for (i = 0; i < len; i += 1) {
         if (this.completeLayers || this.elements[i]) {
@@ -12887,44 +10936,34 @@
       }
     }
   };
-
   SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
     var newElement = element.getBaseElement();
-
     if (!newElement) {
       return;
     }
-
     var i = 0;
     var nextElement;
-
     while (i < pos) {
       if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
         nextElement = this.elements[i].getBaseElement();
       }
-
       i += 1;
     }
-
     if (nextElement) {
       this.layerElement.insertBefore(newElement, nextElement);
     } else {
       this.layerElement.appendChild(newElement);
     }
   };
-
   SVGRendererBase.prototype.hide = function () {
     this.layerElement.style.display = 'none';
   };
-
   SVGRendererBase.prototype.show = function () {
     this.layerElement.style.display = 'block';
   };
 
   function ICompElement() {}
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
-
   ICompElement.prototype.initElement = function (data, globalData, comp) {
     this.initFrame();
     this.initBaseData(data, globalData, comp);
@@ -12934,13 +10973,12 @@
     this.initRendererElement();
     this.createContainerElements();
     this.createRenderableComponents();
-
     if (this.data.xt || !globalData.progressiveLoad) {
       this.buildAllItems();
     }
-
     this.hide();
   };
+
   /* ICompElement.prototype.hide = function(){
       if(!this.hidden){
           this.hideElement();
@@ -12953,77 +10991,61 @@
       }
   }; */
 
-
   ICompElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
-
     if (!this.isInRange && !this.data.xt) {
       return;
     }
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
-
       if (timeRemapped === this.data.op) {
         timeRemapped = this.data.op - 1;
       }
-
       this.renderedFrame = timeRemapped;
     } else {
       this.renderedFrame = num / this.data.sr;
     }
-
     var i;
     var len = this.elements.length;
-
     if (!this.completeLayers) {
       this.checkLayers(this.renderedFrame);
-    } // This iteration needs to be backwards because of how expressions connect between each other
-
-
+    }
+    // This iteration needs to be backwards because of how expressions connect between each other
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
-
         if (this.elements[i]._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   ICompElement.prototype.renderInnerContent = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].renderFrame();
       }
     }
   };
-
   ICompElement.prototype.setElements = function (elems) {
     this.elements = elems;
   };
-
   ICompElement.prototype.getElements = function () {
     return this.elements;
   };
-
   ICompElement.prototype.destroyElements = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i]) {
         this.elements[i].destroy();
       }
     }
   };
-
   ICompElement.prototype.destroy = function () {
     this.destroyElements();
     this.destroyBaseElement();
@@ -13040,9 +11062,7 @@
       _placeholder: true
     };
   }
-
   extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
-
   SVGCompElement.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
@@ -13053,7 +11073,6 @@
     this.renderedFrame = -1;
     this.svgElement = createNS('svg');
     var ariaLabel = '';
-
     if (config && config.title) {
       var titleElement = createNS('title');
       var titleId = createElementID();
@@ -13062,7 +11081,6 @@
       this.svgElement.appendChild(titleElement);
       ariaLabel += titleId;
     }
-
     if (config && config.description) {
       var descElement = createNS('desc');
       var descId = createElementID();
@@ -13071,11 +11089,9 @@
       this.svgElement.appendChild(descElement);
       ariaLabel += ' ' + descId;
     }
-
     if (ariaLabel) {
       this.svgElement.setAttribute('aria-labelledby', ariaLabel);
     }
-
     var defs = createNS('defs');
     this.svgElement.appendChild(defs);
     var maskElement = createNS('g');
@@ -13113,9 +11129,7 @@
     this.destroyed = false;
     this.rendererType = 'svg';
   }
-
   extendPrototype([SVGRendererBase], SVGRenderer);
-
   SVGRenderer.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
@@ -13125,19 +11139,15 @@
     this.sequenceList = [];
     this.transform_key_count = 0;
   }
-
   ShapeTransformManager.prototype = {
     addTransformSequence: function addTransformSequence(transforms) {
       var i;
       var len = transforms.length;
       var key = '_';
-
       for (i = 0; i < len; i += 1) {
         key += transforms[i].transform.key + '_';
       }
-
       var sequence = this.sequences[key];
-
       if (!sequence) {
         sequence = {
           transforms: [].concat(transforms),
@@ -13147,37 +11157,30 @@
         this.sequences[key] = sequence;
         this.sequenceList.push(sequence);
       }
-
       return sequence;
     },
     processSequence: function processSequence(sequence, isFirstFrame) {
       var i = 0;
       var len = sequence.transforms.length;
       var _mdf = isFirstFrame;
-
       while (i < len && !isFirstFrame) {
         if (sequence.transforms[i].transform.mProps._mdf) {
           _mdf = true;
           break;
         }
-
         i += 1;
       }
-
       if (_mdf) {
         sequence.finalTransform.reset();
-
         for (i = len - 1; i >= 0; i -= 1) {
           sequence.finalTransform.multiply(sequence.transforms[i].transform.mProps.v);
         }
       }
-
       sequence._mdf = _mdf;
     },
     processSequences: function processSequences(isFirstFrame) {
       var i;
       var len = this.sequenceList.length;
-
       for (i = 0; i < len; i += 1) {
         this.processSequence(this.sequenceList[i], isFirstFrame);
       }
@@ -13192,11 +11195,12 @@
     var id = '__lottie_element_luma_buffer';
     var lumaBuffer = null;
     var lumaBufferCtx = null;
-    var svg = null; // This alternate solution has a slight delay before the filter is applied, resulting in a flicker on the first frame.
+    var svg = null;
+
+    // This alternate solution has a slight delay before the filter is applied, resulting in a flicker on the first frame.
     // Keeping this here for reference, and in the future, if offscreen canvas supports url filters, this can be used.
     // For now, neither of them work for offscreen canvas, so canvas workers can't support the luma track matte mask.
     // Naming it solution 2 to mark the extra comment lines.
-
     /*
     var svgString = [
       '<svg xmlns="http://www.w3.org/2000/svg">',
@@ -13216,7 +11220,6 @@
 
     function createLumaSvgFilter() {
       var _svg = createNS('svg');
-
       var fil = createNS('filter');
       var matrix = createNS('feColorMatrix');
       fil.setAttribute('id', id);
@@ -13224,60 +11227,49 @@
       matrix.setAttribute('color-interpolation-filters', 'sRGB');
       matrix.setAttribute('values', '0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0');
       fil.appendChild(matrix);
-
       _svg.appendChild(fil);
-
       _svg.setAttribute('id', id + '_svg');
-
       if (featureSupport.svgLumaHidden) {
         _svg.style.display = 'none';
       }
-
       return _svg;
     }
-
     function loadLuma() {
       if (!lumaBuffer) {
         svg = createLumaSvgFilter();
         document.body.appendChild(svg);
         lumaBuffer = createTag('canvas');
-        lumaBufferCtx = lumaBuffer.getContext('2d'); // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
-
+        lumaBufferCtx = lumaBuffer.getContext('2d');
+        // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
         lumaBufferCtx.filter = 'url(#' + id + ')';
         lumaBufferCtx.fillStyle = 'rgba(0,0,0,0)';
         lumaBufferCtx.fillRect(0, 0, 1, 1);
       }
     }
-
     function getLuma(canvas) {
       if (!lumaBuffer) {
         loadLuma();
       }
-
       lumaBuffer.width = canvas.width;
-      lumaBuffer.height = canvas.height; // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
-
+      lumaBuffer.height = canvas.height;
+      // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
       lumaBufferCtx.filter = 'url(#' + id + ')';
       return lumaBuffer;
     }
-
     return {
       load: loadLuma,
       get: getLuma
     };
   };
-
   function createCanvas(width, height) {
     if (featureSupport.offscreenCanvas) {
       return new OffscreenCanvas(width, height);
     }
-
     var canvas = createTag('canvas');
     canvas.width = width;
     canvas.height = height;
     return canvas;
   }
-
   var assetLoader = function () {
     return {
       loadLumaCanvas: lumaLoader.load,
@@ -13287,55 +11279,44 @@
   }();
 
   var registeredEffects = {};
-
   function CVEffects(elem) {
     var i;
     var len = elem.data.ef ? elem.data.ef.length : 0;
     this.filters = [];
     var filterManager;
-
     for (i = 0; i < len; i += 1) {
       filterManager = null;
       var type = elem.data.ef[i].ty;
-
       if (registeredEffects[type]) {
         var Effect = registeredEffects[type].effect;
         filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
       }
-
       if (filterManager) {
         this.filters.push(filterManager);
       }
     }
-
     if (this.filters.length) {
       elem.addRenderableComponent(this);
     }
   }
-
   CVEffects.prototype.renderFrame = function (_isFirstFrame) {
     var i;
     var len = this.filters.length;
-
     for (i = 0; i < len; i += 1) {
       this.filters[i].renderFrame(_isFirstFrame);
     }
   };
-
   CVEffects.prototype.getEffects = function (type) {
     var i;
     var len = this.filters.length;
     var effects = [];
-
     for (i = 0; i < len; i += 1) {
       if (this.filters[i].type === type) {
         effects.push(this.filters[i]);
       }
     }
-
     return effects;
   };
-
   function registerEffect(id, effect) {
     registeredEffects[id] = {
       effect: effect
@@ -13350,27 +11331,21 @@
     var i;
     var len = this.masksProperties.length;
     var hasMasks = false;
-
     for (i = 0; i < len; i += 1) {
       if (this.masksProperties[i].mode !== 'n') {
         hasMasks = true;
       }
-
       this.viewData[i] = ShapePropertyFactory.getShapeProp(this.element, this.masksProperties[i], 3);
     }
-
     this.hasMasks = hasMasks;
-
     if (hasMasks) {
       this.element.addRenderableComponent(this);
     }
   }
-
   CVMaskElement.prototype.renderFrame = function () {
     if (!this.hasMasks) {
       return;
     }
-
     var transform = this.element.finalTransform.mat;
     var ctx = this.element.canvasContext;
     var i;
@@ -13379,7 +11354,6 @@
     var pts;
     var data;
     ctx.beginPath();
-
     for (i = 0; i < len; i += 1) {
       if (this.masksProperties[i].mode !== 'n') {
         if (this.masksProperties[i].inv) {
@@ -13389,35 +11363,28 @@
           ctx.lineTo(0, this.element.globalData.compSize.h);
           ctx.lineTo(0, 0);
         }
-
         data = this.viewData[i].v;
         pt = transform.applyToPointArray(data.v[0][0], data.v[0][1], 0);
         ctx.moveTo(pt[0], pt[1]);
         var j;
         var jLen = data._length;
-
         for (j = 1; j < jLen; j += 1) {
           pts = transform.applyToTriplePoints(data.o[j - 1], data.i[j], data.v[j]);
           ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
         }
-
         pts = transform.applyToTriplePoints(data.o[j - 1], data.i[0], data.v[0]);
         ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
       }
     }
-
     this.element.globalData.renderer.save(true);
     ctx.clip();
   };
-
   CVMaskElement.prototype.getMaskProperty = MaskElement.prototype.getMaskProperty;
-
   CVMaskElement.prototype.destroy = function () {
     this.element = null;
   };
 
   function CVBaseElement() {}
-
   var operationsMap = {
     1: 'source-in',
     2: 'source-out',
@@ -13440,12 +11407,10 @@
         this.buffers.push(bufferCanvas);
         var bufferCanvas2 = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
         this.buffers.push(bufferCanvas2);
-
         if (this.data.tt >= 3 && !document._isProxy) {
           assetLoader.loadLumaCanvas();
         }
       }
-
       this.canvasContext = this.globalData.canvasContext;
       this.transformCanvas = this.globalData.transformCanvas;
       this.renderableEffectsManager = new CVEffects(this);
@@ -13454,7 +11419,6 @@
     createContent: function createContent() {},
     setBlendMode: function setBlendMode() {
       var globalData = this.globalData;
-
       if (globalData.blendMode !== this.data.bm) {
         globalData.blendMode = this.data.bm;
         var blendModeValue = getBlendMode(this.data.bm);
@@ -13484,11 +11448,11 @@
       if (this.data.tt >= 1) {
         var buffer = this.buffers[0];
         var bufferCtx = buffer.getContext('2d');
-        this.clearCanvas(bufferCtx); // on the first buffer we store the current state of the global drawing
-
-        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0); // The next four lines are to clear the canvas
+        this.clearCanvas(bufferCtx);
+        // on the first buffer we store the current state of the global drawing
+        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+        // The next four lines are to clear the canvas
         // TODO: Check if there is a way to clear the canvas without resetting the transform
-
         this.currentTransform = this.canvasContext.getTransform();
         this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
         this.clearCanvas(this.canvasContext);
@@ -13497,43 +11461,43 @@
     },
     exitLayer: function exitLayer() {
       if (this.data.tt >= 1) {
-        var buffer = this.buffers[1]; // On the second buffer we store the current state of the global drawing
+        var buffer = this.buffers[1];
+        // On the second buffer we store the current state of the global drawing
         // that only contains the content of this layer
         // (if it is a composition, it also includes the nested layers)
-
         var bufferCtx = buffer.getContext('2d');
         this.clearCanvas(bufferCtx);
-        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0); // We clear the canvas again
-
+        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+        // We clear the canvas again
         this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
         this.clearCanvas(this.canvasContext);
-        this.canvasContext.setTransform(this.currentTransform); // We draw the mask
-
+        this.canvasContext.setTransform(this.currentTransform);
+        // We draw the mask
         var mask = this.comp.getElementById('tp' in this.data ? this.data.tp : this.data.ind - 1);
-        mask.renderFrame(true); // We draw the second buffer (that contains the content of this layer)
+        mask.renderFrame(true);
+        // We draw the second buffer (that contains the content of this layer)
+        this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
 
-        this.canvasContext.setTransform(1, 0, 0, 1, 0, 0); // If the mask is a Luma matte, we need to do two extra painting operations
+        // If the mask is a Luma matte, we need to do two extra painting operations
         // the _isProxy check is to avoid drawing a fake canvas in workers that will throw an error
-
         if (this.data.tt >= 3 && !document._isProxy) {
           // We copy the painted mask to a buffer that has a color matrix filter applied to it
           // that applies the rgb values to the alpha channel
           var lumaBuffer = assetLoader.getLumaCanvas(this.canvasContext.canvas);
           var lumaBufferCtx = lumaBuffer.getContext('2d');
           lumaBufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
-          this.clearCanvas(this.canvasContext); // we repaint the context with the mask applied to it
-
+          this.clearCanvas(this.canvasContext);
+          // we repaint the context with the mask applied to it
           this.canvasContext.drawImage(lumaBuffer, 0, 0);
         }
-
         this.canvasContext.globalCompositeOperation = operationsMap[this.data.tt];
-        this.canvasContext.drawImage(buffer, 0, 0); // We finally draw the first buffer (that contains the content of the global drawing)
+        this.canvasContext.drawImage(buffer, 0, 0);
+        // We finally draw the first buffer (that contains the content of the global drawing)
         // We use destination-over to draw the global drawing below the current layer
-
         this.canvasContext.globalCompositeOperation = 'destination-over';
         this.canvasContext.drawImage(this.buffers[0], 0, 0);
-        this.canvasContext.setTransform(this.currentTransform); // We reset the globalCompositeOperation to source-over, the standard type of operation
-
+        this.canvasContext.setTransform(this.currentTransform);
+        // We reset the globalCompositeOperation to source-over, the standard type of operation
         this.canvasContext.globalCompositeOperation = 'source-over';
       }
     },
@@ -13541,11 +11505,9 @@
       if (this.hidden || this.data.hd) {
         return;
       }
-
       if (this.data.td === 1 && !forceRender) {
         return;
       }
-
       this.renderTransform();
       this.renderRenderable();
       this.renderLocalTransform();
@@ -13558,11 +11520,9 @@
       this.renderInnerContent();
       this.globalData.renderer.restore(forceRealStack);
       this.exitLayer();
-
       if (this.maskManager.hasMasks) {
         this.globalData.renderer.restore(true);
       }
-
       if (this._isFirstFrame) {
         this._isFirstFrame = false;
       }
@@ -13582,7 +11542,6 @@
     this.styledShapes = [];
     this.tr = [0, 0, 0, 0, 0, 0];
     var ty = 4;
-
     if (data.ty === 'rc') {
       ty = 5;
     } else if (data.ty === 'el') {
@@ -13590,12 +11549,10 @@
     } else if (data.ty === 'sr') {
       ty = 7;
     }
-
     this.sh = ShapePropertyFactory.getShapeProp(element, data, ty, element);
     var i;
     var len = styles.length;
     var styledShape;
-
     for (i = 0; i < len; i += 1) {
       if (!styles[i].closed) {
         styledShape = {
@@ -13607,7 +11564,6 @@
       }
     }
   }
-
   CVShapeData.prototype.setAsAnimated = SVGShapeData.prototype.setAsAnimated;
 
   function CVShapeElement(data, globalData, comp) {
@@ -13621,7 +11577,6 @@
     this.transformsManager = new ShapeTransformManager();
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableElement], CVShapeElement);
   CVShapeElement.prototype.initElement = RenderableDOMElement.prototype.initElement;
   CVShapeElement.prototype.transformHelper = {
@@ -13629,11 +11584,9 @@
     _opMdf: false
   };
   CVShapeElement.prototype.dashResetter = [];
-
   CVShapeElement.prototype.createContent = function () {
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
   };
-
   CVShapeElement.prototype.createStyleElement = function (data, transforms) {
     var styleElem = {
       data: data,
@@ -13644,10 +11597,8 @@
       closed: data.hd === true
     };
     var elementData = {};
-
     if (data.ty === 'fl' || data.ty === 'st') {
       elementData.c = PropertyFactory.getProp(this, data.c, 1, 255, this);
-
       if (!elementData.c.k) {
         styleElem.co = 'rgb(' + bmFloor(elementData.c.v[0]) + ',' + bmFloor(elementData.c.v[1]) + ',' + bmFloor(elementData.c.v[2]) + ')';
       }
@@ -13662,28 +11613,21 @@
       }, 0, degToRads, this);
       elementData.g = new GradientProperty(this, data.g, this);
     }
-
     elementData.o = PropertyFactory.getProp(this, data.o, 0, 0.01, this);
-
     if (data.ty === 'st' || data.ty === 'gs') {
       styleElem.lc = lineCapEnum[data.lc || 2];
       styleElem.lj = lineJoinEnum[data.lj || 2];
-
       if (data.lj == 1) {
         // eslint-disable-line eqeqeq
         styleElem.ml = data.ml;
       }
-
       elementData.w = PropertyFactory.getProp(this, data.w, 0, null, this);
-
       if (!elementData.w.k) {
         styleElem.wi = elementData.w.v;
       }
-
       if (data.d) {
         var d = new DashProperty(this, data.d, 'canvas', this);
         elementData.d = d;
-
         if (!elementData.d.k) {
           styleElem.da = elementData.d.dashArray;
           styleElem["do"] = elementData.d.dashoffset[0];
@@ -13692,12 +11636,10 @@
     } else {
       styleElem.r = data.r === 2 ? 'evenodd' : 'nonzero';
     }
-
     this.stylesList.push(styleElem);
     elementData.style = styleElem;
     return elementData;
   };
-
   CVShapeElement.prototype.createGroupElement = function () {
     var elementData = {
       it: [],
@@ -13705,7 +11647,6 @@
     };
     return elementData;
   };
-
   CVShapeElement.prototype.createTransformElement = function (data) {
     var elementData = {
       transform: {
@@ -13718,65 +11659,52 @@
     };
     return elementData;
   };
-
   CVShapeElement.prototype.createShapeElement = function (data) {
     var elementData = new CVShapeData(this, data, this.stylesList, this.transformsManager);
     this.shapes.push(elementData);
     this.addShapeToModifiers(elementData);
     return elementData;
   };
-
   CVShapeElement.prototype.reloadShapes = function () {
     this._isFirstFrame = true;
     var i;
     var len = this.itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       this.prevViewData[i] = this.itemsData[i];
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
     len = this.dynamicProperties.length;
-
     for (i = 0; i < len; i += 1) {
       this.dynamicProperties[i].getValue();
     }
-
     this.renderModifiers();
     this.transformsManager.processSequences(this._isFirstFrame);
   };
-
   CVShapeElement.prototype.addTransformToStyleList = function (transform) {
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       if (!this.stylesList[i].closed) {
         this.stylesList[i].transforms.push(transform);
       }
     }
   };
-
   CVShapeElement.prototype.removeTransformFromStyleList = function () {
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       if (!this.stylesList[i].closed) {
         this.stylesList[i].transforms.pop();
       }
     }
   };
-
   CVShapeElement.prototype.closeStyles = function (styles) {
     var i;
     var len = styles.length;
-
     for (i = 0; i < len; i += 1) {
       styles[i].closed = true;
     }
   };
-
   CVShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, shouldRender, transforms) {
     var i;
     var len = arr.length - 1;
@@ -13788,42 +11716,35 @@
     var modifier;
     var currentTransform;
     var ownTransforms = [].concat(transforms);
-
     for (i = len; i >= 0; i -= 1) {
       processedPos = this.searchProcessedElement(arr[i]);
-
       if (!processedPos) {
         arr[i]._shouldRender = shouldRender;
       } else {
         itemsData[i] = prevViewData[processedPos - 1];
       }
-
       if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs') {
         if (!processedPos) {
           itemsData[i] = this.createStyleElement(arr[i], ownTransforms);
         } else {
           itemsData[i].style.closed = false;
         }
-
         ownStyles.push(itemsData[i].style);
       } else if (arr[i].ty === 'gr') {
         if (!processedPos) {
           itemsData[i] = this.createGroupElement(arr[i]);
         } else {
           jLen = itemsData[i].it.length;
-
           for (j = 0; j < jLen; j += 1) {
             itemsData[i].prevViewData[j] = itemsData[i].it[j];
           }
         }
-
         this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, shouldRender, ownTransforms);
       } else if (arr[i].ty === 'tr') {
         if (!processedPos) {
           currentTransform = this.createTransformElement(arr[i]);
           itemsData[i] = currentTransform;
         }
-
         ownTransforms.push(itemsData[i]);
         this.addTransformToStyleList(itemsData[i]);
       } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
@@ -13840,7 +11761,6 @@
           modifier = itemsData[i];
           modifier.closed = false;
         }
-
         ownModifiers.push(modifier);
       } else if (arr[i].ty === 'rp') {
         if (!processedPos) {
@@ -13853,22 +11773,17 @@
           modifier = itemsData[i];
           modifier.closed = true;
         }
-
         ownModifiers.push(modifier);
       }
-
       this.addProcessedElement(arr[i], i + 1);
     }
-
     this.removeTransformFromStyleList();
     this.closeStyles(ownStyles);
     len = ownModifiers.length;
-
     for (i = 0; i < len; i += 1) {
       ownModifiers[i].closed = true;
     }
   };
-
   CVShapeElement.prototype.renderInnerContent = function () {
     this.transformHelper.opacity = 1;
     this.transformHelper._opMdf = false;
@@ -13876,7 +11791,6 @@
     this.transformsManager.processSequences(this._isFirstFrame);
     this.renderShape(this.transformHelper, this.shapesData, this.itemsData, true);
   };
-
   CVShapeElement.prototype.renderShapeTransform = function (parentTransform, groupTransform) {
     if (parentTransform._opMdf || groupTransform.op._mdf || this._isFirstFrame) {
       groupTransform.opacity = parentTransform.opacity;
@@ -13884,7 +11798,6 @@
       groupTransform._opMdf = true;
     }
   };
-
   CVShapeElement.prototype.drawLayer = function () {
     var i;
     var len = this.stylesList.length;
@@ -13898,55 +11811,49 @@
     var ctx = this.globalData.canvasContext;
     var type;
     var currentStyle;
-
     for (i = 0; i < len; i += 1) {
       currentStyle = this.stylesList[i];
-      type = currentStyle.type; // Skipping style when
+      type = currentStyle.type;
+
+      // Skipping style when
       // Stroke width equals 0
       // style should not be rendered (extra unused repeaters)
       // current opacity equals 0
       // global opacity equals 0
-
       if (!((type === 'st' || type === 'gs') && currentStyle.wi === 0 || !currentStyle.data._shouldRender || currentStyle.coOp === 0 || this.globalData.currentGlobalAlpha === 0)) {
         renderer.save();
         elems = currentStyle.elements;
-
         if (type === 'st' || type === 'gs') {
-          renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd); // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
-
-          renderer.ctxLineWidth(currentStyle.wi); // ctx.lineWidth = currentStyle.wi;
-
-          renderer.ctxLineCap(currentStyle.lc); // ctx.lineCap = currentStyle.lc;
-
-          renderer.ctxLineJoin(currentStyle.lj); // ctx.lineJoin = currentStyle.lj;
-
-          renderer.ctxMiterLimit(currentStyle.ml || 0); // ctx.miterLimit = currentStyle.ml || 0;
+          renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd);
+          // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
+          renderer.ctxLineWidth(currentStyle.wi);
+          // ctx.lineWidth = currentStyle.wi;
+          renderer.ctxLineCap(currentStyle.lc);
+          // ctx.lineCap = currentStyle.lc;
+          renderer.ctxLineJoin(currentStyle.lj);
+          // ctx.lineJoin = currentStyle.lj;
+          renderer.ctxMiterLimit(currentStyle.ml || 0);
+          // ctx.miterLimit = currentStyle.ml || 0;
         } else {
-          renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd); // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
+          renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd);
+          // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
         }
-
         renderer.ctxOpacity(currentStyle.coOp);
-
         if (type !== 'st' && type !== 'gs') {
           ctx.beginPath();
         }
-
         renderer.ctxTransform(currentStyle.preTransforms.finalTransform.props);
         jLen = elems.length;
-
         for (j = 0; j < jLen; j += 1) {
           if (type === 'st' || type === 'gs') {
             ctx.beginPath();
-
             if (currentStyle.da) {
               ctx.setLineDash(currentStyle.da);
               ctx.lineDashOffset = currentStyle["do"];
             }
           }
-
           nodes = elems[j].trNodes;
           kLen = nodes.length;
-
           for (k = 0; k < kLen; k += 1) {
             if (nodes[k].t === 'm') {
               ctx.moveTo(nodes[k].p[0], nodes[k].p[1]);
@@ -13956,33 +11863,27 @@
               ctx.closePath();
             }
           }
-
           if (type === 'st' || type === 'gs') {
             // ctx.stroke();
             renderer.ctxStroke();
-
             if (currentStyle.da) {
               ctx.setLineDash(this.dashResetter);
             }
           }
         }
-
         if (type !== 'st' && type !== 'gs') {
           // ctx.fill(currentStyle.r);
           this.globalData.renderer.ctxFill(currentStyle.r);
         }
-
         renderer.restore();
       }
     }
   };
-
   CVShapeElement.prototype.renderShape = function (parentTransform, items, data, isMain) {
     var i;
     var len = items.length - 1;
     var groupTransform;
     groupTransform = parentTransform;
-
     for (i = len; i >= 0; i -= 1) {
       if (items[i].ty === 'tr') {
         groupTransform = data[i].transform;
@@ -13997,15 +11898,14 @@
         this.renderGradientFill(items[i], data[i], groupTransform);
       } else if (items[i].ty === 'gr') {
         this.renderShape(groupTransform, items[i].it, data[i].it);
-      } else if (items[i].ty === 'tm') {//
+      } else if (items[i].ty === 'tm') {
+        //
       }
     }
-
     if (isMain) {
       this.drawLayer();
     }
   };
-
   CVShapeElement.prototype.renderStyledShape = function (styledShape, shape) {
     if (this._isFirstFrame || shape._mdf || styledShape.transforms._mdf) {
       var shapeNodes = styledShape.trNodes;
@@ -14016,13 +11916,10 @@
       var jLen = paths._length;
       shapeNodes.length = 0;
       var groupTransformMat = styledShape.transforms.finalTransform;
-
       for (j = 0; j < jLen; j += 1) {
         var pathNodes = paths.shapes[j];
-
         if (pathNodes && pathNodes.v) {
           len = pathNodes._length;
-
           for (i = 1; i < len; i += 1) {
             if (i === 1) {
               shapeNodes.push({
@@ -14030,20 +11927,17 @@
                 p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0)
               });
             }
-
             shapeNodes.push({
               t: 'c',
               pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[i], pathNodes.v[i])
             });
           }
-
           if (len === 1) {
             shapeNodes.push({
               t: 'm',
               p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0)
             });
           }
-
           if (pathNodes.c && len) {
             shapeNodes.push({
               t: 'c',
@@ -14055,103 +11949,81 @@
           }
         }
       }
-
       styledShape.trNodes = shapeNodes;
     }
   };
-
   CVShapeElement.prototype.renderPath = function (pathData, itemData) {
     if (pathData.hd !== true && pathData._shouldRender) {
       var i;
       var len = itemData.styledShapes.length;
-
       for (i = 0; i < len; i += 1) {
         this.renderStyledShape(itemData.styledShapes[i], itemData.sh);
       }
     }
   };
-
   CVShapeElement.prototype.renderFill = function (styleData, itemData, groupTransform) {
     var styleElem = itemData.style;
-
     if (itemData.c._mdf || this._isFirstFrame) {
       styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
     }
-
     if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
       styleElem.coOp = itemData.o.v * groupTransform.opacity;
     }
   };
-
   CVShapeElement.prototype.renderGradientFill = function (styleData, itemData, groupTransform) {
     var styleElem = itemData.style;
     var grd;
-
     if (!styleElem.grd || itemData.g._mdf || itemData.s._mdf || itemData.e._mdf || styleData.t !== 1 && (itemData.h._mdf || itemData.a._mdf)) {
       var ctx = this.globalData.canvasContext;
       var pt1 = itemData.s.v;
       var pt2 = itemData.e.v;
-
       if (styleData.t === 1) {
         grd = ctx.createLinearGradient(pt1[0], pt1[1], pt2[0], pt2[1]);
       } else {
         var rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
         var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
         var percent = itemData.h.v;
-
         if (percent >= 1) {
           percent = 0.99;
         } else if (percent <= -1) {
           percent = -0.99;
         }
-
         var dist = rad * percent;
         var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
         var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
         grd = ctx.createRadialGradient(x, y, 0, pt1[0], pt1[1], rad);
       }
-
       var i;
       var len = styleData.g.p;
       var cValues = itemData.g.c;
       var opacity = 1;
-
       for (i = 0; i < len; i += 1) {
         if (itemData.g._hasOpacity && itemData.g._collapsable) {
           opacity = itemData.g.o[i * 2 + 1];
         }
-
         grd.addColorStop(cValues[i * 4] / 100, 'rgba(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ',' + opacity + ')');
       }
-
       styleElem.grd = grd;
     }
-
     styleElem.coOp = itemData.o.v * groupTransform.opacity;
   };
-
   CVShapeElement.prototype.renderStroke = function (styleData, itemData, groupTransform) {
     var styleElem = itemData.style;
     var d = itemData.d;
-
     if (d && (d._mdf || this._isFirstFrame)) {
       styleElem.da = d.dashArray;
       styleElem["do"] = d.dashoffset[0];
     }
-
     if (itemData.c._mdf || this._isFirstFrame) {
       styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
     }
-
     if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
       styleElem.coOp = itemData.o.v * groupTransform.opacity;
     }
-
     if (itemData.w._mdf || this._isFirstFrame) {
       styleElem.wi = itemData.w.v;
     }
   };
-
   CVShapeElement.prototype.destroy = function () {
     this.shapesData = null;
     this.globalData = null;
@@ -14179,31 +12051,25 @@
     };
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement, ITextElement], CVTextElement);
   CVTextElement.prototype.tHelper = createTag('canvas').getContext('2d');
-
   CVTextElement.prototype.buildNewText = function () {
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
     var hasFill = false;
-
     if (documentData.fc) {
       hasFill = true;
       this.values.fill = this.buildColor(documentData.fc);
     } else {
       this.values.fill = 'rgba(0,0,0,0)';
     }
-
     this.fill = hasFill;
     var hasStroke = false;
-
     if (documentData.sc) {
       hasStroke = true;
       this.values.stroke = this.buildColor(documentData.sc);
       this.values.sWidth = documentData.sw;
     }
-
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
     var i;
     var len;
@@ -14211,8 +12077,8 @@
     var matrixHelper = this.mHelper;
     this.stroke = hasStroke;
     this.values.fValue = documentData.finalSize + 'px ' + this.globalData.fontManager.getFontByName(documentData.f).fFamily;
-    len = documentData.finalText.length; // this.tHelper.font = this.values.fValue;
-
+    len = documentData.finalText.length;
+    // this.tHelper.font = this.values.fValue;
     var charData;
     var shapeData;
     var k;
@@ -14229,55 +12095,44 @@
     var yPos = 0;
     var firstLine = true;
     var cnt = 0;
-
     for (i = 0; i < len; i += 1) {
       charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
       shapeData = charData && charData.data || {};
       matrixHelper.reset();
-
       if (singleShape && letters[i].n) {
         xPos = -trackingOffset;
         yPos += documentData.yOffset;
         yPos += firstLine ? 1 : 0;
         firstLine = false;
       }
-
       shapes = shapeData.shapes ? shapeData.shapes[0].it : [];
       jLen = shapes.length;
       matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
-
       if (singleShape) {
         this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
       }
-
       commands = createSizedArray(jLen - 1);
       var commandsCounter = 0;
-
       for (j = 0; j < jLen; j += 1) {
         if (shapes[j].ty === 'sh') {
           kLen = shapes[j].ks.k.i.length;
           pathNodes = shapes[j].ks.k;
           pathArr = [];
-
           for (k = 1; k < kLen; k += 1) {
             if (k === 1) {
               pathArr.push(matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
             }
-
             pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToY(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToX(pathNodes.v[k][0], pathNodes.v[k][1], 0), matrixHelper.applyToY(pathNodes.v[k][0], pathNodes.v[k][1], 0));
           }
-
           pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToY(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
           commands[commandsCounter] = pathArr;
           commandsCounter += 1;
         }
       }
-
       if (singleShape) {
         xPos += letters[i].l;
         xPos += trackingOffset;
       }
-
       if (this.textSpans[cnt]) {
         this.textSpans[cnt].elem = commands;
       } else {
@@ -14285,25 +12140,23 @@
           elem: commands
         };
       }
-
       cnt += 1;
     }
   };
-
   CVTextElement.prototype.renderInnerContent = function () {
     this.validateText();
     var ctx = this.canvasContext;
     ctx.font = this.values.fValue;
-    this.globalData.renderer.ctxLineCap('butt'); // ctx.lineCap = 'butt';
-
-    this.globalData.renderer.ctxLineJoin('miter'); // ctx.lineJoin = 'miter';
-
-    this.globalData.renderer.ctxMiterLimit(4); // ctx.miterLimit = 4;
+    this.globalData.renderer.ctxLineCap('butt');
+    // ctx.lineCap = 'butt';
+    this.globalData.renderer.ctxLineJoin('miter');
+    // ctx.lineJoin = 'miter';
+    this.globalData.renderer.ctxMiterLimit(4);
+    // ctx.miterLimit = 4;
 
     if (!this.data.singleShape) {
       this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
     }
-
     var i;
     var len;
     var j;
@@ -14320,87 +12173,81 @@
     var commands;
     var pathArr;
     var renderer = this.globalData.renderer;
-
     for (i = 0; i < len; i += 1) {
       if (!letters[i].n) {
         renderedLetter = renderedLetters[i];
-
         if (renderedLetter) {
           renderer.save();
           renderer.ctxTransform(renderedLetter.p);
           renderer.ctxOpacity(renderedLetter.o);
         }
-
         if (this.fill) {
           if (renderedLetter && renderedLetter.fc) {
             if (lastFill !== renderedLetter.fc) {
               renderer.ctxFillStyle(renderedLetter.fc);
-              lastFill = renderedLetter.fc; // ctx.fillStyle = renderedLetter.fc;
+              lastFill = renderedLetter.fc;
+              // ctx.fillStyle = renderedLetter.fc;
             }
           } else if (lastFill !== this.values.fill) {
             lastFill = this.values.fill;
-            renderer.ctxFillStyle(this.values.fill); // ctx.fillStyle = this.values.fill;
+            renderer.ctxFillStyle(this.values.fill);
+            // ctx.fillStyle = this.values.fill;
           }
-
           commands = this.textSpans[i].elem;
           jLen = commands.length;
           this.globalData.canvasContext.beginPath();
-
           for (j = 0; j < jLen; j += 1) {
             pathArr = commands[j];
             kLen = pathArr.length;
             this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
-
             for (k = 2; k < kLen; k += 6) {
               this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
             }
           }
-
           this.globalData.canvasContext.closePath();
-          renderer.ctxFill(); // this.globalData.canvasContext.fill();
+          renderer.ctxFill();
+          // this.globalData.canvasContext.fill();
           /// ctx.fillText(this.textSpans[i].val,0,0);
         }
-
         if (this.stroke) {
           if (renderedLetter && renderedLetter.sw) {
             if (lastStrokeW !== renderedLetter.sw) {
               lastStrokeW = renderedLetter.sw;
-              renderer.ctxLineWidth(renderedLetter.sw); // ctx.lineWidth = renderedLetter.sw;
+              renderer.ctxLineWidth(renderedLetter.sw);
+              // ctx.lineWidth = renderedLetter.sw;
             }
           } else if (lastStrokeW !== this.values.sWidth) {
             lastStrokeW = this.values.sWidth;
-            renderer.ctxLineWidth(this.values.sWidth); // ctx.lineWidth = this.values.sWidth;
+            renderer.ctxLineWidth(this.values.sWidth);
+            // ctx.lineWidth = this.values.sWidth;
           }
-
           if (renderedLetter && renderedLetter.sc) {
             if (lastStroke !== renderedLetter.sc) {
               lastStroke = renderedLetter.sc;
-              renderer.ctxStrokeStyle(renderedLetter.sc); // ctx.strokeStyle = renderedLetter.sc;
+              renderer.ctxStrokeStyle(renderedLetter.sc);
+              // ctx.strokeStyle = renderedLetter.sc;
             }
           } else if (lastStroke !== this.values.stroke) {
             lastStroke = this.values.stroke;
-            renderer.ctxStrokeStyle(this.values.stroke); // ctx.strokeStyle = this.values.stroke;
+            renderer.ctxStrokeStyle(this.values.stroke);
+            // ctx.strokeStyle = this.values.stroke;
           }
-
           commands = this.textSpans[i].elem;
           jLen = commands.length;
           this.globalData.canvasContext.beginPath();
-
           for (j = 0; j < jLen; j += 1) {
             pathArr = commands[j];
             kLen = pathArr.length;
             this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
-
             for (k = 2; k < kLen; k += 6) {
               this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
             }
           }
-
           this.globalData.canvasContext.closePath();
-          renderer.ctxStroke(); // this.globalData.canvasContext.stroke();
+          renderer.ctxStroke();
+          // this.globalData.canvasContext.stroke();
           /// ctx.strokeText(letters[i].val,0,0);
         }
-
         if (renderedLetter) {
           this.globalData.renderer.restore();
         }
@@ -14413,11 +12260,9 @@
     this.img = globalData.imageLoader.getAsset(this.assetData);
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVImageElement);
   CVImageElement.prototype.initElement = SVGShapeElement.prototype.initElement;
   CVImageElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
-
   CVImageElement.prototype.createContent = function () {
     if (this.img.width && (this.assetData.w !== this.img.width || this.assetData.h !== this.img.height)) {
       var canvas = createTag('canvas');
@@ -14431,7 +12276,6 @@
       var widthCrop;
       var heightCrop;
       var par = this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio;
-
       if (imgRel > canvasRel && par === 'xMidYMid slice' || imgRel < canvasRel && par !== 'xMidYMid slice') {
         heightCrop = imgH;
         widthCrop = heightCrop * canvasRel;
@@ -14439,16 +12283,13 @@
         widthCrop = imgW;
         heightCrop = widthCrop / canvasRel;
       }
-
       ctx.drawImage(this.img, (imgW - widthCrop) / 2, (imgH - heightCrop) / 2, widthCrop, heightCrop, 0, 0, this.assetData.w, this.assetData.h);
       this.img = canvas;
     }
   };
-
   CVImageElement.prototype.renderInnerContent = function () {
     this.canvasContext.drawImage(this.img, 0, 0);
   };
-
   CVImageElement.prototype.destroy = function () {
     this.img = null;
   };
@@ -14456,115 +12297,89 @@
   function CVSolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVSolidElement);
   CVSolidElement.prototype.initElement = SVGShapeElement.prototype.initElement;
   CVSolidElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
-
   CVSolidElement.prototype.renderInnerContent = function () {
     // var ctx = this.canvasContext;
-    this.globalData.renderer.ctxFillStyle(this.data.sc); // ctx.fillStyle = this.data.sc;
-
-    this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh); // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
+    this.globalData.renderer.ctxFillStyle(this.data.sc);
+    // ctx.fillStyle = this.data.sc;
+    this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh);
+    // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
     //
   };
 
   function CanvasRendererBase() {}
-
   extendPrototype([BaseRenderer], CanvasRendererBase);
-
   CanvasRendererBase.prototype.createShape = function (data) {
     return new CVShapeElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createText = function (data) {
     return new CVTextElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createImage = function (data) {
     return new CVImageElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createSolid = function (data) {
     return new CVSolidElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
-
   CanvasRendererBase.prototype.ctxTransform = function (props) {
     if (props[0] === 1 && props[1] === 0 && props[4] === 0 && props[5] === 1 && props[12] === 0 && props[13] === 0) {
       return;
     }
-
     this.canvasContext.transform(props[0], props[1], props[4], props[5], props[12], props[13]);
   };
-
   CanvasRendererBase.prototype.ctxOpacity = function (op) {
     this.canvasContext.globalAlpha *= op < 0 ? 0 : op;
   };
-
   CanvasRendererBase.prototype.ctxFillStyle = function (value) {
     this.canvasContext.fillStyle = value;
   };
-
   CanvasRendererBase.prototype.ctxStrokeStyle = function (value) {
     this.canvasContext.strokeStyle = value;
   };
-
   CanvasRendererBase.prototype.ctxLineWidth = function (value) {
     this.canvasContext.lineWidth = value;
   };
-
   CanvasRendererBase.prototype.ctxLineCap = function (value) {
     this.canvasContext.lineCap = value;
   };
-
   CanvasRendererBase.prototype.ctxLineJoin = function (value) {
     this.canvasContext.lineJoin = value;
   };
-
   CanvasRendererBase.prototype.ctxMiterLimit = function (value) {
     this.canvasContext.miterLimit = value;
   };
-
   CanvasRendererBase.prototype.ctxFill = function (rule) {
     this.canvasContext.fill(rule);
   };
-
   CanvasRendererBase.prototype.ctxFillRect = function (x, y, w, h) {
     this.canvasContext.fillRect(x, y, w, h);
   };
-
   CanvasRendererBase.prototype.ctxStroke = function () {
     this.canvasContext.stroke();
   };
-
   CanvasRendererBase.prototype.reset = function () {
     if (!this.renderConfig.clearCanvas) {
       this.canvasContext.restore();
       return;
     }
-
     this.contextData.reset();
   };
-
   CanvasRendererBase.prototype.save = function () {
     this.canvasContext.save();
   };
-
   CanvasRendererBase.prototype.restore = function (actionFlag) {
     if (!this.renderConfig.clearCanvas) {
       this.canvasContext.restore();
       return;
     }
-
     if (actionFlag) {
       this.globalData.blendMode = 'source-over';
     }
-
     this.contextData.restore(actionFlag);
   };
-
   CanvasRendererBase.prototype.configAnimation = function (animData) {
     if (this.animationItem.wrapper) {
       this.animationItem.container = createTag('canvas');
@@ -14579,18 +12394,15 @@
       containerStyle.contentVisibility = this.renderConfig.contentVisibility;
       this.animationItem.wrapper.appendChild(this.animationItem.container);
       this.canvasContext = this.animationItem.container.getContext('2d');
-
       if (this.renderConfig.className) {
         this.animationItem.container.setAttribute('class', this.renderConfig.className);
       }
-
       if (this.renderConfig.id) {
         this.animationItem.container.setAttribute('id', this.renderConfig.id);
       }
     } else {
       this.canvasContext = this.renderConfig.context;
     }
-
     this.contextData.setContext(this.canvasContext);
     this.data = animData;
     this.layers = animData.layers;
@@ -14611,12 +12423,10 @@
     this.elements = createSizedArray(animData.layers.length);
     this.updateContainerSize();
   };
-
   CanvasRendererBase.prototype.updateContainerSize = function (width, height) {
     this.reset();
     var elementWidth;
     var elementHeight;
-
     if (width) {
       elementWidth = width;
       elementHeight = height;
@@ -14630,14 +12440,11 @@
         elementWidth = this.canvasContext.canvas.width;
         elementHeight = this.canvasContext.canvas.height;
       }
-
       this.canvasContext.canvas.width = elementWidth * this.renderConfig.dpr;
       this.canvasContext.canvas.height = elementHeight * this.renderConfig.dpr;
     }
-
     var elementRel;
     var animationRel;
-
     if (this.renderConfig.preserveAspectRatio.indexOf('meet') !== -1 || this.renderConfig.preserveAspectRatio.indexOf('slice') !== -1) {
       var par = this.renderConfig.preserveAspectRatio.split(' ');
       var fillType = par[1] || 'meet';
@@ -14646,7 +12453,6 @@
       var yPos = pos.substr(4);
       elementRel = elementWidth / elementHeight;
       animationRel = this.transformCanvas.w / this.transformCanvas.h;
-
       if (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice') {
         this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
         this.transformCanvas.sy = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
@@ -14654,7 +12460,6 @@
         this.transformCanvas.sx = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
         this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
       }
-
       if (xPos === 'xMid' && (animationRel < elementRel && fillType === 'meet' || animationRel > elementRel && fillType === 'slice')) {
         this.transformCanvas.tx = (elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) / 2 * this.renderConfig.dpr;
       } else if (xPos === 'xMax' && (animationRel < elementRel && fillType === 'meet' || animationRel > elementRel && fillType === 'slice')) {
@@ -14662,7 +12467,6 @@
       } else {
         this.transformCanvas.tx = 0;
       }
-
       if (yPos === 'YMid' && (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice')) {
         this.transformCanvas.ty = (elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w)) / 2 * this.renderConfig.dpr;
       } else if (yPos === 'YMax' && (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice')) {
@@ -14681,7 +12485,6 @@
       this.transformCanvas.tx = 0;
       this.transformCanvas.ty = 0;
     }
-
     this.transformCanvas.props = [this.transformCanvas.sx, 0, 0, 0, 0, this.transformCanvas.sy, 0, 0, 0, 0, 1, 0, this.transformCanvas.tx, this.transformCanvas.ty, 0, 1];
     /* var i, len = this.elements.length;
       for(i=0;i<len;i+=1){
@@ -14689,7 +12492,6 @@
               this.elements[i].resize(this.globalData.transformCanvas);
           }
       } */
-
     this.ctxTransform(this.transformCanvas.props);
     this.canvasContext.beginPath();
     this.canvasContext.rect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
@@ -14697,78 +12499,65 @@
     this.canvasContext.clip();
     this.renderFrame(this.renderedFrame, true);
   };
-
   CanvasRendererBase.prototype.destroy = function () {
     if (this.renderConfig.clearCanvas && this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.globalData.canvasContext = null;
     this.animationItem.container = null;
     this.destroyed = true;
   };
-
   CanvasRendererBase.prototype.renderFrame = function (num, forceRender) {
     if (this.renderedFrame === num && this.renderConfig.clearCanvas === true && !forceRender || this.destroyed || num === -1) {
       return;
     }
-
     this.renderedFrame = num;
     this.globalData.frameNum = num - this.animationItem._isFirstFrame;
     this.globalData.frameId += 1;
     this.globalData._mdf = !this.renderConfig.clearCanvas || forceRender;
-    this.globalData.projectInterface.currentFrame = num; // console.log('--------');
-    // console.log('NEW: ',num);
+    this.globalData.projectInterface.currentFrame = num;
 
+    // console.log('--------');
+    // console.log('NEW: ',num);
     var i;
     var len = this.layers.length;
-
     if (!this.completeLayers) {
       this.checkLayers(num);
     }
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(num - this.layers[i].st);
       }
     }
-
     if (this.globalData._mdf) {
       if (this.renderConfig.clearCanvas === true) {
         this.canvasContext.clearRect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
       } else {
         this.save();
       }
-
       for (i = len - 1; i >= 0; i -= 1) {
         if (this.completeLayers || this.elements[i]) {
           this.elements[i].renderFrame();
         }
       }
-
       if (this.renderConfig.clearCanvas !== true) {
         this.restore();
       }
     }
   };
-
   CanvasRendererBase.prototype.buildItem = function (pos) {
     var elements = this.elements;
-
     if (elements[pos] || this.layers[pos].ty === 99) {
       return;
     }
-
     var element = this.createItem(this.layers[pos], this, this.globalData);
     elements[pos] = element;
     element.initExpressions();
@@ -14776,18 +12565,15 @@
           element.resize(this.globalData.transformCanvas);
       } */
   };
-
   CanvasRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
     }
   };
-
   CanvasRendererBase.prototype.hide = function () {
     this.animationItem.container.style.display = 'none';
   };
-
   CanvasRendererBase.prototype.show = function () {
     this.animationItem.container.style.display = 'block';
   };
@@ -14803,71 +12589,61 @@
     this.miterLimit = '';
     this.id = Math.random();
   }
-
   function CVContextData() {
     this.stack = [];
     this.cArrPos = 0;
     this.cTr = new Matrix();
     var i;
     var len = 15;
-
     for (i = 0; i < len; i += 1) {
       var canvasContext = new CanvasContext();
       this.stack[i] = canvasContext;
     }
-
     this._length = len;
     this.nativeContext = null;
     this.transformMat = new Matrix();
-    this.currentOpacity = 1; //
-
+    this.currentOpacity = 1;
+    //
     this.currentFillStyle = '';
-    this.appliedFillStyle = ''; //
-
+    this.appliedFillStyle = '';
+    //
     this.currentStrokeStyle = '';
-    this.appliedStrokeStyle = ''; //
-
+    this.appliedStrokeStyle = '';
+    //
     this.currentLineWidth = '';
-    this.appliedLineWidth = ''; //
-
+    this.appliedLineWidth = '';
+    //
     this.currentLineCap = '';
-    this.appliedLineCap = ''; //
-
+    this.appliedLineCap = '';
+    //
     this.currentLineJoin = '';
-    this.appliedLineJoin = ''; //
-
+    this.appliedLineJoin = '';
+    //
     this.appliedMiterLimit = '';
     this.currentMiterLimit = '';
   }
-
   CVContextData.prototype.duplicate = function () {
     var newLength = this._length * 2;
     var i = 0;
-
     for (i = this._length; i < newLength; i += 1) {
       this.stack[i] = new CanvasContext();
     }
-
     this._length = newLength;
   };
-
   CVContextData.prototype.reset = function () {
     this.cArrPos = 0;
     this.cTr.reset();
     this.stack[this.cArrPos].opacity = 1;
   };
-
   CVContextData.prototype.restore = function (forceRestore) {
     this.cArrPos -= 1;
     var currentContext = this.stack[this.cArrPos];
     var transform = currentContext.transform;
     var i;
     var arr = this.cTr.props;
-
     for (i = 0; i < 16; i += 1) {
       arr[i] = transform[i];
     }
-
     if (forceRestore) {
       this.nativeContext.restore();
       var prevStack = this.stack[this.cArrPos + 1];
@@ -14878,14 +12654,11 @@
       this.appliedLineJoin = prevStack.lineJoin;
       this.appliedMiterLimit = prevStack.miterLimit;
     }
-
     this.nativeContext.setTransform(transform[0], transform[1], transform[4], transform[5], transform[12], transform[13]);
-
     if (forceRestore || currentContext.opacity !== -1 && this.currentOpacity !== currentContext.opacity) {
       this.nativeContext.globalAlpha = currentContext.opacity;
       this.currentOpacity = currentContext.opacity;
     }
-
     this.currentFillStyle = currentContext.fillStyle;
     this.currentStrokeStyle = currentContext.strokeStyle;
     this.currentLineWidth = currentContext.lineWidth;
@@ -14893,25 +12666,19 @@
     this.currentLineJoin = currentContext.lineJoin;
     this.currentMiterLimit = currentContext.miterLimit;
   };
-
   CVContextData.prototype.save = function (saveOnNativeFlag) {
     if (saveOnNativeFlag) {
       this.nativeContext.save();
     }
-
     var props = this.cTr.props;
-
     if (this._length <= this.cArrPos) {
       this.duplicate();
     }
-
     var currentStack = this.stack[this.cArrPos];
     var i;
-
     for (i = 0; i < 16; i += 1) {
       currentStack.transform[i] = props[i];
     }
-
     this.cArrPos += 1;
     var newStack = this.stack[this.cArrPos];
     newStack.opacity = currentStack.opacity;
@@ -14922,128 +12689,106 @@
     newStack.lineJoin = currentStack.lineJoin;
     newStack.miterLimit = currentStack.miterLimit;
   };
-
   CVContextData.prototype.setOpacity = function (value) {
     this.stack[this.cArrPos].opacity = value;
   };
-
   CVContextData.prototype.setContext = function (value) {
     this.nativeContext = value;
   };
-
   CVContextData.prototype.fillStyle = function (value) {
     if (this.stack[this.cArrPos].fillStyle !== value) {
       this.currentFillStyle = value;
       this.stack[this.cArrPos].fillStyle = value;
     }
   };
-
   CVContextData.prototype.strokeStyle = function (value) {
     if (this.stack[this.cArrPos].strokeStyle !== value) {
       this.currentStrokeStyle = value;
       this.stack[this.cArrPos].strokeStyle = value;
     }
   };
-
   CVContextData.prototype.lineWidth = function (value) {
     if (this.stack[this.cArrPos].lineWidth !== value) {
       this.currentLineWidth = value;
       this.stack[this.cArrPos].lineWidth = value;
     }
   };
-
   CVContextData.prototype.lineCap = function (value) {
     if (this.stack[this.cArrPos].lineCap !== value) {
       this.currentLineCap = value;
       this.stack[this.cArrPos].lineCap = value;
     }
   };
-
   CVContextData.prototype.lineJoin = function (value) {
     if (this.stack[this.cArrPos].lineJoin !== value) {
       this.currentLineJoin = value;
       this.stack[this.cArrPos].lineJoin = value;
     }
   };
-
   CVContextData.prototype.miterLimit = function (value) {
     if (this.stack[this.cArrPos].miterLimit !== value) {
       this.currentMiterLimit = value;
       this.stack[this.cArrPos].miterLimit = value;
     }
   };
-
   CVContextData.prototype.transform = function (props) {
-    this.transformMat.cloneFromProps(props); // Taking the last transform value from the stored stack of transforms
-
-    var currentTransform = this.cTr; // Applying the last transform value after the new transform to respect the order of transformations
-
-    this.transformMat.multiply(currentTransform); // Storing the new transformed value in the stored transform
-
+    this.transformMat.cloneFromProps(props);
+    // Taking the last transform value from the stored stack of transforms
+    var currentTransform = this.cTr;
+    // Applying the last transform value after the new transform to respect the order of transformations
+    this.transformMat.multiply(currentTransform);
+    // Storing the new transformed value in the stored transform
     currentTransform.cloneFromProps(this.transformMat.props);
-    var trProps = currentTransform.props; // Applying the new transform to the canvas
-
+    var trProps = currentTransform.props;
+    // Applying the new transform to the canvas
     this.nativeContext.setTransform(trProps[0], trProps[1], trProps[4], trProps[5], trProps[12], trProps[13]);
   };
-
   CVContextData.prototype.opacity = function (op) {
     var currentOpacity = this.stack[this.cArrPos].opacity;
     currentOpacity *= op < 0 ? 0 : op;
-
     if (this.stack[this.cArrPos].opacity !== currentOpacity) {
       if (this.currentOpacity !== op) {
         this.nativeContext.globalAlpha = op;
         this.currentOpacity = op;
       }
-
       this.stack[this.cArrPos].opacity = currentOpacity;
     }
   };
-
   CVContextData.prototype.fill = function (rule) {
     if (this.appliedFillStyle !== this.currentFillStyle) {
       this.appliedFillStyle = this.currentFillStyle;
       this.nativeContext.fillStyle = this.appliedFillStyle;
     }
-
     this.nativeContext.fill(rule);
   };
-
   CVContextData.prototype.fillRect = function (x, y, w, h) {
     if (this.appliedFillStyle !== this.currentFillStyle) {
       this.appliedFillStyle = this.currentFillStyle;
       this.nativeContext.fillStyle = this.appliedFillStyle;
     }
-
     this.nativeContext.fillRect(x, y, w, h);
   };
-
   CVContextData.prototype.stroke = function () {
     if (this.appliedStrokeStyle !== this.currentStrokeStyle) {
       this.appliedStrokeStyle = this.currentStrokeStyle;
       this.nativeContext.strokeStyle = this.appliedStrokeStyle;
     }
-
     if (this.appliedLineWidth !== this.currentLineWidth) {
       this.appliedLineWidth = this.currentLineWidth;
       this.nativeContext.lineWidth = this.appliedLineWidth;
     }
-
     if (this.appliedLineCap !== this.currentLineCap) {
       this.appliedLineCap = this.currentLineCap;
       this.nativeContext.lineCap = this.appliedLineCap;
     }
-
     if (this.appliedLineJoin !== this.currentLineJoin) {
       this.appliedLineJoin = this.currentLineJoin;
       this.nativeContext.lineJoin = this.appliedLineJoin;
     }
-
     if (this.appliedMiterLimit !== this.currentMiterLimit) {
       this.appliedMiterLimit = this.currentMiterLimit;
       this.nativeContext.miterLimit = this.appliedMiterLimit;
     }
-
     this.nativeContext.stroke();
   };
 
@@ -15057,9 +12802,7 @@
       _placeholder: true
     };
   }
-
   extendPrototype([CanvasRendererBase, ICompElement, CVBaseElement], CVCompElement);
-
   CVCompElement.prototype.renderInnerContent = function () {
     var ctx = this.canvasContext;
     ctx.beginPath();
@@ -15071,28 +12814,23 @@
     ctx.clip();
     var i;
     var len = this.layers.length;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].renderFrame();
       }
     }
   };
-
   CVCompElement.prototype.destroy = function () {
     var i;
     var len = this.layers.length;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.elements[i]) {
         this.elements[i].destroy();
       }
     }
-
     this.layers = null;
     this.elements = null;
   };
-
   CVCompElement.prototype.createComp = function (data) {
     return new CVCompElement(data, this.globalData, this);
   };
@@ -15111,11 +12849,9 @@
       runExpressions: !config || config.runExpressions === undefined || config.runExpressions
     };
     this.renderConfig.dpr = config && config.dpr || 1;
-
     if (this.animationItem.wrapper) {
       this.renderConfig.dpr = config && config.dpr || window.devicePixelRatio || 1;
     }
-
     this.renderedFrame = -1;
     this.globalData = {
       frameNum: -1,
@@ -15129,7 +12865,6 @@
     this.transformMat = new Matrix();
     this.completeLayers = false;
     this.rendererType = 'canvas';
-
     if (this.renderConfig.clearCanvas) {
       this.ctxTransform = this.contextData.transform.bind(this.contextData);
       this.ctxOpacity = this.contextData.opacity.bind(this.contextData);
@@ -15145,20 +12880,16 @@
       this.save = this.contextData.save.bind(this.contextData);
     }
   }
-
   extendPrototype([CanvasRendererBase], CanvasRenderer);
-
   CanvasRenderer.prototype.createComp = function (data) {
     return new CVCompElement(data, this.globalData, this);
   };
 
   function HBaseElement() {}
-
   HBaseElement.prototype = {
     checkBlendMode: function checkBlendMode() {},
     initRendererElement: function initRendererElement() {
       this.baseElement = createTag(this.data.tg || 'div');
-
       if (this.data.hasMask) {
         this.svgElement = createNS('svg');
         this.layerElement = createNS('g');
@@ -15168,35 +12899,29 @@
       } else {
         this.layerElement = this.baseElement;
       }
-
       styleDiv(this.baseElement);
     },
     createContainerElements: function createContainerElements() {
       this.renderableEffectsManager = new CVEffects(this);
       this.transformedElement = this.baseElement;
       this.maskedElement = this.layerElement;
-
       if (this.data.ln) {
         this.layerElement.setAttribute('id', this.data.ln);
       }
-
       if (this.data.cl) {
         this.layerElement.setAttribute('class', this.data.cl);
       }
-
       if (this.data.bm !== 0) {
         this.setBlendMode();
       }
     },
     renderElement: function renderElement() {
       var transformedElementStyle = this.transformedElement ? this.transformedElement.style : {};
-
       if (this.finalTransform._matMdf) {
         var matrixValue = this.finalTransform.mat.toCSS();
         transformedElementStyle.transform = matrixValue;
         transformedElementStyle.webkitTransform = matrixValue;
       }
-
       if (this.finalTransform._opMdf) {
         transformedElementStyle.opacity = this.finalTransform.mProp.o.v;
       }
@@ -15207,12 +12932,10 @@
       if (this.data.hd || this.hidden) {
         return;
       }
-
       this.renderTransform();
       this.renderRenderable();
       this.renderElement();
       this.renderInnerContent();
-
       if (this._isFirstFrame) {
         this._isFirstFrame = false;
       }
@@ -15220,11 +12943,9 @@
     destroy: function destroy() {
       this.layerElement = null;
       this.transformedElement = null;
-
       if (this.matteElement) {
         this.matteElement = null;
       }
-
       if (this.maskManager) {
         this.maskManager.destroy();
         this.maskManager = null;
@@ -15243,12 +12964,9 @@
   function HSolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], HSolidElement);
-
   HSolidElement.prototype.createContent = function () {
     var rect;
-
     if (this.data.hasMask) {
       rect = createNS('rect');
       rect.setAttribute('width', this.data.sw);
@@ -15262,29 +12980,28 @@
       rect.style.height = this.data.sh + 'px';
       rect.style.backgroundColor = this.data.sc;
     }
-
     this.layerElement.appendChild(rect);
   };
 
   function HShapeElement(data, globalData, comp) {
     // List of drawable elements
-    this.shapes = []; // Full shape data
-
-    this.shapesData = data.shapes; // List of styles that will be applied to shapes
-
-    this.stylesList = []; // List of modifiers that will be applied to shapes
-
-    this.shapeModifiers = []; // List of items in shape tree
-
-    this.itemsData = []; // List of items in previous shape tree
-
-    this.processedElements = []; // List of animated components
-
+    this.shapes = [];
+    // Full shape data
+    this.shapesData = data.shapes;
+    // List of styles that will be applied to shapes
+    this.stylesList = [];
+    // List of modifiers that will be applied to shapes
+    this.shapeModifiers = [];
+    // List of items in shape tree
+    this.itemsData = [];
+    // List of items in previous shape tree
+    this.processedElements = [];
+    // List of animated components
     this.animatedContents = [];
     this.shapesContainer = createNS('g');
-    this.initElement(data, globalData, comp); // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.initElement(data, globalData, comp);
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
     // List of elements that have been created
-
     this.prevViewData = [];
     this.currentBBox = {
       x: 999999,
@@ -15293,14 +13010,11 @@
       w: 0
     };
   }
-
   extendPrototype([BaseElement, TransformElement, HSolidElement, SVGShapeElement, HBaseElement, HierarchyElement, FrameElement, RenderableElement], HShapeElement);
   HShapeElement.prototype._renderShapeFrame = HShapeElement.prototype.renderInnerContent;
-
   HShapeElement.prototype.createContent = function () {
     var cont;
     this.baseElement.style.fontSize = 0;
-
     if (this.data.hasMask) {
       this.layerElement.appendChild(this.shapesContainer);
       cont = this.svgElement;
@@ -15312,23 +13026,18 @@
       cont.appendChild(this.shapesContainer);
       this.layerElement.appendChild(cont);
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.shapesContainer, 0, [], true);
     this.filterUniqueShapes();
     this.shapeCont = cont;
   };
-
   HShapeElement.prototype.getTransformedPoint = function (transformers, point) {
     var i;
     var len = transformers.length;
-
     for (i = 0; i < len; i += 1) {
       point = transformers[i].mProps.v.applyToPointArray(point[0], point[1], 0);
     }
-
     return point;
   };
-
   HShapeElement.prototype.calculateShapeBoundingBox = function (item, boundingBox) {
     var shape = item.sh.v;
     var transformers = item.transformers;
@@ -15338,11 +13047,9 @@
     var oPoint;
     var nextIPoint;
     var nextVPoint;
-
     if (len <= 1) {
       return;
     }
-
     for (i = 0; i < len - 1; i += 1) {
       vPoint = this.getTransformedPoint(transformers, shape.v[i]);
       oPoint = this.getTransformedPoint(transformers, shape.o[i]);
@@ -15350,7 +13057,6 @@
       nextVPoint = this.getTransformedPoint(transformers, shape.v[i + 1]);
       this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
     }
-
     if (shape.c) {
       vPoint = this.getTransformedPoint(transformers, shape.v[i]);
       oPoint = this.getTransformedPoint(transformers, shape.o[i]);
@@ -15359,7 +13065,6 @@
       this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
     }
   };
-
   HShapeElement.prototype.checkBounds = function (vPoint, oPoint, nextIPoint, nextVPoint, boundingBox) {
     this.getBoundsOfCurve(vPoint, oPoint, nextIPoint, nextVPoint);
     var bounds = this.shapeBoundingBox;
@@ -15368,7 +13073,6 @@
     boundingBox.y = bmMin(bounds.top, boundingBox.y);
     boundingBox.yMax = bmMax(bounds.bottom, boundingBox.yMax);
   };
-
   HShapeElement.prototype.shapeBoundingBox = {
     left: 0,
     right: 0,
@@ -15383,31 +13087,26 @@
     width: 0,
     height: 0
   };
-
   HShapeElement.prototype.getBoundsOfCurve = function (p0, p1, p2, p3) {
     var bounds = [[p0[0], p3[0]], [p0[1], p3[1]]];
-
     for (var a, b, c, t, b2ac, t1, t2, i = 0; i < 2; ++i) {
       // eslint-disable-line no-plusplus
       b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];
       a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];
       c = 3 * p1[i] - 3 * p0[i];
       b |= 0; // eslint-disable-line no-bitwise
-
       a |= 0; // eslint-disable-line no-bitwise
-
       c |= 0; // eslint-disable-line no-bitwise
 
-      if (a === 0 && b === 0) {//
+      if (a === 0 && b === 0) {
+        //
       } else if (a === 0) {
         t = -c / b;
-
         if (t > 0 && t < 1) {
           bounds[i].push(this.calculateF(t, p0, p1, p2, p3, i));
         }
       } else {
         b2ac = b * b - 4 * c * a;
-
         if (b2ac >= 0) {
           t1 = (-b + bmSqrt(b2ac)) / (2 * a);
           if (t1 > 0 && t1 < 1) bounds[i].push(this.calculateF(t1, p0, p1, p2, p3, i));
@@ -15416,21 +13115,17 @@
         }
       }
     }
-
     this.shapeBoundingBox.left = bmMin.apply(null, bounds[0]);
     this.shapeBoundingBox.top = bmMin.apply(null, bounds[1]);
     this.shapeBoundingBox.right = bmMax.apply(null, bounds[0]);
     this.shapeBoundingBox.bottom = bmMax.apply(null, bounds[1]);
   };
-
   HShapeElement.prototype.calculateF = function (t, p0, p1, p2, p3, i) {
     return bmPow(1 - t, 3) * p0[i] + 3 * bmPow(1 - t, 2) * t * p1[i] + 3 * (1 - t) * bmPow(t, 2) * p2[i] + bmPow(t, 3) * p3[i];
   };
-
   HShapeElement.prototype.calculateBoundingBox = function (itemsData, boundingBox) {
     var i;
     var len = itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       if (itemsData[i] && itemsData[i].sh) {
         this.calculateShapeBoundingBox(itemsData[i], boundingBox);
@@ -15441,37 +13136,29 @@
       }
     }
   };
-
   HShapeElement.prototype.expandStrokeBoundingBox = function (widthProperty, boundingBox) {
     var width = 0;
-
     if (widthProperty.keyframes) {
       for (var i = 0; i < widthProperty.keyframes.length; i += 1) {
         var kfw = widthProperty.keyframes[i].s;
-
         if (kfw > width) {
           width = kfw;
         }
       }
-
       width *= widthProperty.mult;
     } else {
       width = widthProperty.v * widthProperty.mult;
     }
-
     boundingBox.x -= width;
     boundingBox.xMax += width;
     boundingBox.y -= width;
     boundingBox.yMax += width;
   };
-
   HShapeElement.prototype.currentBoxContains = function (box) {
     return this.currentBBox.x <= box.x && this.currentBBox.y <= box.y && this.currentBBox.width + this.currentBBox.x >= box.x + box.width && this.currentBBox.height + this.currentBBox.y >= box.y + box.height;
   };
-
   HShapeElement.prototype.renderInnerContent = function () {
     this._renderShapeFrame();
-
     if (!this.hidden && (this._isFirstFrame || this._mdf)) {
       var tempBoundingBox = this.tempBoundingBox;
       var max = 999999;
@@ -15481,26 +13168,22 @@
       tempBoundingBox.yMax = -max;
       this.calculateBoundingBox(this.itemsData, tempBoundingBox);
       tempBoundingBox.width = tempBoundingBox.xMax < tempBoundingBox.x ? 0 : tempBoundingBox.xMax - tempBoundingBox.x;
-      tempBoundingBox.height = tempBoundingBox.yMax < tempBoundingBox.y ? 0 : tempBoundingBox.yMax - tempBoundingBox.y; // var tempBoundingBox = this.shapeCont.getBBox();
-
+      tempBoundingBox.height = tempBoundingBox.yMax < tempBoundingBox.y ? 0 : tempBoundingBox.yMax - tempBoundingBox.y;
+      // var tempBoundingBox = this.shapeCont.getBBox();
       if (this.currentBoxContains(tempBoundingBox)) {
         return;
       }
-
       var changed = false;
-
       if (this.currentBBox.w !== tempBoundingBox.width) {
         this.currentBBox.w = tempBoundingBox.width;
         this.shapeCont.setAttribute('width', tempBoundingBox.width);
         changed = true;
       }
-
       if (this.currentBBox.h !== tempBoundingBox.height) {
         this.currentBBox.h = tempBoundingBox.height;
         this.shapeCont.setAttribute('height', tempBoundingBox.height);
         changed = true;
       }
-
       if (changed || this.currentBBox.x !== tempBoundingBox.x || this.currentBBox.y !== tempBoundingBox.y) {
         this.currentBBox.w = tempBoundingBox.width;
         this.currentBBox.h = tempBoundingBox.height;
@@ -15528,12 +13211,9 @@
     this.isMasked = false;
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], HTextElement);
-
   HTextElement.prototype.createContent = function () {
     this.isMasked = this.checkMasks();
-
     if (this.isMasked) {
       this.renderType = 'svg';
       this.compW = this.comp.data.w;
@@ -15547,10 +13227,8 @@
       this.renderType = 'html';
       this.innerElem = this.layerElement;
     }
-
     this.checkParenting();
   };
-
   HTextElement.prototype.buildNewText = function () {
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
@@ -15558,18 +13236,14 @@
     var textColor = documentData.fc ? this.buildColor(documentData.fc) : 'rgba(0,0,0,0)';
     innerElemStyle.fill = textColor;
     innerElemStyle.color = textColor;
-
     if (documentData.sc) {
       innerElemStyle.stroke = this.buildColor(documentData.sc);
       innerElemStyle.strokeWidth = documentData.sw + 'px';
     }
-
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
-
     if (!this.globalData.fontManager.chars) {
       innerElemStyle.fontSize = documentData.finalSize + 'px';
       innerElemStyle.lineHeight = documentData.finalSize + 'px';
-
       if (fontData.fClass) {
         this.innerElem.className = fontData.fClass;
       } else {
@@ -15580,7 +13254,6 @@
         innerElemStyle.fontWeight = fWeight;
       }
     }
-
     var i;
     var len;
     var letters = documentData.l;
@@ -15592,7 +13265,6 @@
     var shapes;
     var shapeStr = '';
     var cnt = 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.globalData.fontManager.chars) {
         if (!this.textPaths[cnt]) {
@@ -15603,7 +13275,6 @@
         } else {
           tSpan = this.textPaths[cnt];
         }
-
         if (!this.isMasked) {
           if (this.textSpans[cnt]) {
             tParent = this.textSpans[cnt];
@@ -15629,31 +13300,25 @@
         }
       } else {
         tSpan = this.textPaths[cnt] ? this.textPaths[cnt] : createNS('text');
-      } // tSpan.setAttribute('visibility', 'hidden');
-
-
+      }
+      // tSpan.setAttribute('visibility', 'hidden');
       if (this.globalData.fontManager.chars) {
         var charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
         var shapeData;
-
         if (charData) {
           shapeData = charData.data;
         } else {
           shapeData = null;
         }
-
         matrixHelper.reset();
-
         if (shapeData && shapeData.shapes && shapeData.shapes.length) {
           shapes = shapeData.shapes[0].it;
           matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
           shapeStr = this.createPathShape(matrixHelper, shapes);
           tSpan.setAttribute('d', shapeStr);
         }
-
         if (!this.isMasked) {
           this.innerElem.appendChild(tParent);
-
           if (shapeData && shapeData.shapes) {
             // document.body.appendChild is needed to get exact measure of shape
             document.body.appendChild(tCont);
@@ -15670,7 +13335,6 @@
             tCont.setAttribute('width', 1);
             tCont.setAttribute('height', 1);
           }
-
           tParent.appendChild(tCont);
         } else {
           this.innerElem.appendChild(tSpan);
@@ -15678,10 +13342,9 @@
       } else {
         tSpan.textContent = letters[i].val;
         tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
-
         if (!this.isMasked) {
-          this.innerElem.appendChild(tParent); //
-
+          this.innerElem.appendChild(tParent);
+          //
           var tStyle = tSpan.style;
           var tSpanTranslation = 'translate3d(0,' + -documentData.finalSize / 1.2 + 'px,0)';
           tStyle.transform = tSpanTranslation;
@@ -15689,35 +13352,29 @@
         } else {
           this.innerElem.appendChild(tSpan);
         }
-      } //
-
-
+      }
+      //
       if (!this.isMasked) {
         this.textSpans[cnt] = tParent;
       } else {
         this.textSpans[cnt] = tSpan;
       }
-
       this.textSpans[cnt].style.display = 'block';
       this.textPaths[cnt] = tSpan;
       cnt += 1;
     }
-
     while (cnt < this.textSpans.length) {
       this.textSpans[cnt].style.display = 'none';
       cnt += 1;
     }
   };
-
   HTextElement.prototype.renderInnerContent = function () {
     this.validateText();
     var svgStyle;
-
     if (this.data.singleShape) {
       if (!this._isFirstFrame && !this.lettersChangedFlag) {
         return;
       }
-
       if (this.isMasked && this.finalTransform._matMdf) {
         // Todo Benchmark if using this is better than getBBox
         this.svgElement.setAttribute('viewBox', -this.finalTransform.mProp.p.v[0] + ' ' + -this.finalTransform.mProp.p.v[1] + ' ' + this.compW + ' ' + this.compH);
@@ -15727,13 +13384,10 @@
         svgStyle.webkitTransform = translation;
       }
     }
-
     this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
-
     if (!this.lettersChangedFlag && !this.textAnimator.lettersChangedFlag) {
       return;
     }
-
     var i;
     var len;
     var count = 0;
@@ -15743,7 +13397,6 @@
     var renderedLetter;
     var textSpan;
     var textPath;
-
     for (i = 0; i < len; i += 1) {
       if (letters[i].n) {
         count += 1;
@@ -15752,7 +13405,6 @@
         textPath = this.textPaths[i];
         renderedLetter = renderedLetters[count];
         count += 1;
-
         if (renderedLetter._mdf.m) {
           if (!this.isMasked) {
             textSpan.style.webkitTransform = renderedLetter.m;
@@ -15760,41 +13412,32 @@
           } else {
             textSpan.setAttribute('transform', renderedLetter.m);
           }
-        } /// /textSpan.setAttribute('opacity',renderedLetter.o);
-
-
+        }
+        /// /textSpan.setAttribute('opacity',renderedLetter.o);
         textSpan.style.opacity = renderedLetter.o;
-
         if (renderedLetter.sw && renderedLetter._mdf.sw) {
           textPath.setAttribute('stroke-width', renderedLetter.sw);
         }
-
         if (renderedLetter.sc && renderedLetter._mdf.sc) {
           textPath.setAttribute('stroke', renderedLetter.sc);
         }
-
         if (renderedLetter.fc && renderedLetter._mdf.fc) {
           textPath.setAttribute('fill', renderedLetter.fc);
           textPath.style.color = renderedLetter.fc;
         }
       }
     }
-
     if (this.innerElem.getBBox && !this.hidden && (this._isFirstFrame || this._mdf)) {
       var boundingBox = this.innerElem.getBBox();
-
       if (this.currentBBox.w !== boundingBox.width) {
         this.currentBBox.w = boundingBox.width;
         this.svgElement.setAttribute('width', boundingBox.width);
       }
-
       if (this.currentBBox.h !== boundingBox.height) {
         this.currentBBox.h = boundingBox.height;
         this.svgElement.setAttribute('height', boundingBox.height);
       }
-
       var margin = 1;
-
       if (this.currentBBox.w !== boundingBox.width + margin * 2 || this.currentBBox.h !== boundingBox.height + margin * 2 || this.currentBBox.x !== boundingBox.x - margin || this.currentBBox.y !== boundingBox.y - margin) {
         this.currentBBox.w = boundingBox.width + margin * 2;
         this.currentBBox.h = boundingBox.height + margin * 2;
@@ -15815,7 +13458,6 @@
     this.initHierarchy();
     var getProp = PropertyFactory.getProp;
     this.pe = getProp(this, data.pe, 0, 0, this);
-
     if (data.ks.p.s) {
       this.px = getProp(this, data.ks.p.x, 1, 0, this);
       this.py = getProp(this, data.ks.p.y, 1, 0, this);
@@ -15823,21 +13465,17 @@
     } else {
       this.p = getProp(this, data.ks.p, 1, 0, this);
     }
-
     if (data.ks.a) {
       this.a = getProp(this, data.ks.a, 1, 0, this);
     }
-
     if (data.ks.or.k.length && data.ks.or.k[0].to) {
       var i;
       var len = data.ks.or.k.length;
-
       for (i = 0; i < len; i += 1) {
         data.ks.or.k[i].to = null;
         data.ks.or.k[i].ti = null;
       }
     }
-
     this.or = getProp(this, data.ks.or, 1, degToRads, this);
     this.or.sh = true;
     this.rx = getProp(this, data.ks.rx, 0, degToRads, this);
@@ -15845,26 +13483,23 @@
     this.rz = getProp(this, data.ks.rz, 0, degToRads, this);
     this.mat = new Matrix();
     this._prevMat = new Matrix();
-    this._isFirstFrame = true; // TODO: find a better way to make the HCamera element to be compatible with the LayerInterface and TransformInterface.
+    this._isFirstFrame = true;
 
+    // TODO: find a better way to make the HCamera element to be compatible with the LayerInterface and TransformInterface.
     this.finalTransform = {
       mProp: this
     };
   }
-
   extendPrototype([BaseElement, FrameElement, HierarchyElement], HCameraElement);
-
   HCameraElement.prototype.setup = function () {
     var i;
     var len = this.comp.threeDElements.length;
     var comp;
     var perspectiveStyle;
     var containerStyle;
-
     for (i = 0; i < len; i += 1) {
       // [perspectiveElem,container]
       comp = this.comp.threeDElements[i];
-
       if (comp.type === '3d') {
         perspectiveStyle = comp.perspectiveElem.style;
         containerStyle = comp.container.style;
@@ -15881,30 +13516,22 @@
       }
     }
   };
-
   HCameraElement.prototype.createElements = function () {};
-
   HCameraElement.prototype.hide = function () {};
-
   HCameraElement.prototype.renderFrame = function () {
     var _mdf = this._isFirstFrame;
     var i;
     var len;
-
     if (this.hierarchy) {
       len = this.hierarchy.length;
-
       for (i = 0; i < len; i += 1) {
         _mdf = this.hierarchy[i].finalTransform.mProp._mdf || _mdf;
       }
     }
-
     if (_mdf || this.pe._mdf || this.p && this.p._mdf || this.px && (this.px._mdf || this.py._mdf || this.pz._mdf) || this.rx._mdf || this.ry._mdf || this.rz._mdf || this.or._mdf || this.a && this.a._mdf) {
       this.mat.reset();
-
       if (this.hierarchy) {
         len = this.hierarchy.length - 1;
-
         for (i = len; i >= 0; i -= 1) {
           var mTransf = this.hierarchy[i].finalTransform.mProp;
           this.mat.translate(-mTransf.p.v[0], -mTransf.p.v[1], mTransf.p.v[2]);
@@ -15914,46 +13541,38 @@
           this.mat.translate(mTransf.a.v[0], mTransf.a.v[1], mTransf.a.v[2]);
         }
       }
-
       if (this.p) {
         this.mat.translate(-this.p.v[0], -this.p.v[1], this.p.v[2]);
       } else {
         this.mat.translate(-this.px.v, -this.py.v, this.pz.v);
       }
-
       if (this.a) {
         var diffVector;
-
         if (this.p) {
           diffVector = [this.p.v[0] - this.a.v[0], this.p.v[1] - this.a.v[1], this.p.v[2] - this.a.v[2]];
         } else {
           diffVector = [this.px.v - this.a.v[0], this.py.v - this.a.v[1], this.pz.v - this.a.v[2]];
         }
-
-        var mag = Math.sqrt(Math.pow(diffVector[0], 2) + Math.pow(diffVector[1], 2) + Math.pow(diffVector[2], 2)); // var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
-
+        var mag = Math.sqrt(Math.pow(diffVector[0], 2) + Math.pow(diffVector[1], 2) + Math.pow(diffVector[2], 2));
+        // var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
         var lookDir = [diffVector[0] / mag, diffVector[1] / mag, diffVector[2] / mag];
         var lookLengthOnXZ = Math.sqrt(lookDir[2] * lookDir[2] + lookDir[0] * lookDir[0]);
         var mRotationX = Math.atan2(lookDir[1], lookLengthOnXZ);
         var mRotationY = Math.atan2(lookDir[0], -lookDir[2]);
         this.mat.rotateY(mRotationY).rotateX(-mRotationX);
       }
-
       this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v);
       this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]);
       this.mat.translate(this.globalData.compSize.w / 2, this.globalData.compSize.h / 2, 0);
       this.mat.translate(0, 0, this.pe.v);
       var hasMatrixChanged = !this._prevMat.equals(this.mat);
-
       if ((hasMatrixChanged || this.pe._mdf) && this.comp.threeDElements) {
         len = this.comp.threeDElements.length;
         var comp;
         var perspectiveStyle;
         var containerStyle;
-
         for (i = 0; i < len; i += 1) {
           comp = this.comp.threeDElements[i];
-
           if (comp.type === '3d') {
             if (hasMatrixChanged) {
               var matValue = this.mat.toCSS();
@@ -15961,7 +13580,6 @@
               containerStyle.transform = matValue;
               containerStyle.webkitTransform = matValue;
             }
-
             if (this.pe._mdf) {
               perspectiveStyle = comp.perspectiveElem.style;
               perspectiveStyle.perspective = this.pe.v + 'px';
@@ -15969,20 +13587,15 @@
             }
           }
         }
-
         this.mat.clone(this._prevMat);
       }
     }
-
     this._isFirstFrame = false;
   };
-
   HCameraElement.prototype.prepareFrame = function (num) {
     this.prepareProperties(num, true);
   };
-
   HCameraElement.prototype.destroy = function () {};
-
   HCameraElement.prototype.getBaseElement = function () {
     return null;
   };
@@ -15991,13 +13604,10 @@
     this.assetData = globalData.getAssetData(data.refId);
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, HBaseElement, HSolidElement, HierarchyElement, FrameElement, RenderableElement], HImageElement);
-
   HImageElement.prototype.createContent = function () {
     var assetPath = this.globalData.getAssetsPath(this.assetData);
     var img = new Image();
-
     if (this.data.hasMask) {
       this.imageElem = createNS('image');
       this.imageElem.setAttribute('width', this.assetData.w + 'px');
@@ -16009,10 +13619,8 @@
     } else {
       this.layerElement.appendChild(img);
     }
-
     img.crossOrigin = 'anonymous';
     img.src = assetPath;
-
     if (this.data.ln) {
       this.baseElement.setAttribute('id', this.data.ln);
     }
@@ -16046,26 +13654,20 @@
     this.supports3d = true;
     this.rendererType = 'html';
   }
-
   extendPrototype([BaseRenderer], HybridRendererBase);
   HybridRendererBase.prototype.buildItem = SVGRenderer.prototype.buildItem;
-
   HybridRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
     }
   };
-
   HybridRendererBase.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);
@@ -16074,17 +13676,14 @@
         var nextDOMElement;
         var nextLayer;
         var 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);
@@ -16097,61 +13696,46 @@
       this.addTo3dContainer(newDOMElement, pos);
     }
   };
-
   HybridRendererBase.prototype.createShape = function (data) {
     if (!this.supports3d) {
       return new SVGShapeElement(data, this.globalData, this);
     }
-
     return new HShapeElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createText = function (data) {
     if (!this.supports3d) {
       return new SVGTextLottieElement(data, this.globalData, this);
     }
-
     return new HTextElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createCamera = function (data) {
     this.camera = new HCameraElement(data, this.globalData, this);
     return this.camera;
   };
-
   HybridRendererBase.prototype.createImage = function (data) {
     if (!this.supports3d) {
       return new IImageElement(data, this.globalData, this);
     }
-
     return new HImageElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createSolid = function (data) {
     if (!this.supports3d) {
       return new ISolidElement(data, this.globalData, this);
     }
-
     return new HSolidElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
-
   HybridRendererBase.prototype.getThreeDContainerByPos = function (pos) {
     var i = 0;
     var 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;
     }
-
     return null;
   };
-
   HybridRendererBase.prototype.createThreeDContainer = function (pos, type) {
     var perspectiveElem = createTag('div');
     var style;
@@ -16159,7 +13743,6 @@
     styleDiv(perspectiveElem);
     var container = createTag('div');
     styleDiv(container);
-
     if (type === '3d') {
       style = perspectiveElem.style;
       style.width = this.globalData.compSize.w + 'px';
@@ -16173,9 +13756,8 @@
       containerStyle.transform = matrix;
       containerStyle.webkitTransform = matrix;
     }
-
-    perspectiveElem.appendChild(container); // this.resizerElem.appendChild(perspectiveElem);
-
+    perspectiveElem.appendChild(container);
+    // this.resizerElem.appendChild(perspectiveElem);
     var threeDContainerData = {
       container: container,
       perspectiveElem: perspectiveElem,
@@ -16186,68 +13768,54 @@
     this.threeDElements.push(threeDContainerData);
     return threeDContainerData;
   };
-
   HybridRendererBase.prototype.build3dContainers = function () {
     var i;
     var 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 -= 1) {
       this.resizerElem.appendChild(this.threeDElements[i].perspectiveElem);
     }
   };
-
   HybridRendererBase.prototype.addTo3dContainer = function (elem, pos) {
     var i = 0;
     var 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;
     }
   };
-
   HybridRendererBase.prototype.configAnimation = function (animData) {
     var resizerElem = createTag('div');
     var wrapper = this.animationItem.wrapper;
@@ -16259,11 +13827,9 @@
     style.transformStyle = 'flat';
     style.mozTransformStyle = 'flat';
     style.webkitTransformStyle = 'flat';
-
     if (this.renderConfig.className) {
       resizerElem.setAttribute('class', this.renderConfig.className);
     }
-
     wrapper.appendChild(resizerElem);
     style.overflow = 'hidden';
     var svg = createNS('svg');
@@ -16273,8 +13839,8 @@
     this.resizerElem.appendChild(svg);
     var defs = createNS('defs');
     svg.appendChild(defs);
-    this.data = animData; // Mask animation
-
+    this.data = animData;
+    // Mask animation
     this.setupGlobalData(animData, svg);
     this.globalData.defs = defs;
     this.layers = animData.layers;
@@ -16282,28 +13848,23 @@
     this.build3dContainers();
     this.updateContainerSize();
   };
-
   HybridRendererBase.prototype.destroy = function () {
     if (this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     this.animationItem.container = null;
     this.globalData.defs = null;
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.destroyed = true;
     this.animationItem = null;
   };
-
   HybridRendererBase.prototype.updateContainerSize = function () {
     var elementWidth = this.animationItem.wrapper.offsetWidth;
     var elementHeight = this.animationItem.wrapper.offsetHeight;
@@ -16313,7 +13874,6 @@
     var sy;
     var tx;
     var ty;
-
     if (animationRel > elementRel) {
       sx = elementWidth / this.globalData.compSize.w;
       sy = elementWidth / this.globalData.compSize.w;
@@ -16325,25 +13885,19 @@
       tx = (elementWidth - this.globalData.compSize.w * (elementHeight / this.globalData.compSize.h)) / 2;
       ty = 0;
     }
-
     var style = this.resizerElem.style;
     style.webkitTransform = 'matrix3d(' + sx + ',0,0,0,0,' + sy + ',0,0,0,0,1,0,' + tx + ',' + ty + ',0,1)';
     style.transform = style.webkitTransform;
   };
-
   HybridRendererBase.prototype.renderFrame = SVGRenderer.prototype.renderFrame;
-
   HybridRendererBase.prototype.hide = function () {
     this.resizerElem.style.display = 'none';
   };
-
   HybridRendererBase.prototype.show = function () {
     this.resizerElem.style.display = 'block';
   };
-
   HybridRendererBase.prototype.initItems = function () {
     this.buildAllItems();
-
     if (this.camera) {
       this.camera.setup();
     } else {
@@ -16351,7 +13905,6 @@
       var cHeight = this.globalData.compSize.h;
       var i;
       var len = this.threeDElements.length;
-
       for (i = 0; i < len; i += 1) {
         var style = this.threeDElements[i].perspectiveElem.style;
         style.webkitPerspective = Math.sqrt(Math.pow(cWidth, 2) + Math.pow(cHeight, 2)) + 'px';
@@ -16359,12 +13912,10 @@
       }
     }
   };
-
   HybridRendererBase.prototype.searchExtraCompositions = function (assets) {
     var i;
     var 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);
@@ -16385,14 +13936,11 @@
       _placeholder: true
     };
   }
-
   extendPrototype([HybridRendererBase, ICompElement, HBaseElement], HCompElement);
   HCompElement.prototype._createBaseContainerElements = HCompElement.prototype.createContainerElements;
-
   HCompElement.prototype.createContainerElements = function () {
-    this._createBaseContainerElements(); // divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
-
-
+    this._createBaseContainerElements();
+    // divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
     if (this.data.hasMask) {
       this.svgElement.setAttribute('width', this.data.w);
       this.svgElement.setAttribute('height', this.data.h);
@@ -16401,31 +13949,25 @@
       this.transformedElement = this.layerElement;
     }
   };
-
   HCompElement.prototype.addTo3dContainer = function (elem, pos) {
     var j = 0;
     var nextElement;
-
     while (j < pos) {
       if (this.elements[j] && this.elements[j].getBaseElement) {
         nextElement = this.elements[j].getBaseElement();
       }
-
       j += 1;
     }
-
     if (nextElement) {
       this.layerElement.insertBefore(elem, nextElement);
     } else {
       this.layerElement.appendChild(elem);
     }
   };
-
   HCompElement.prototype.createComp = function (data) {
     if (!this.supports3d) {
       return new SVGCompElement(data, this.globalData, this);
     }
-
     return new HCompElement(data, this.globalData, this);
   };
 
@@ -16458,14 +14000,11 @@
     this.supports3d = true;
     this.rendererType = 'html';
   }
-
   extendPrototype([HybridRendererBase], HybridRenderer);
-
   HybridRenderer.prototype.createComp = function (data) {
     if (!this.supports3d) {
       return new SVGCompElement(data, this.globalData, this);
     }
-
     return new HCompElement(data, this.globalData, this);
   };
 
@@ -16474,18 +14013,15 @@
       function _thisLayerFunction(name) {
         var i = 0;
         var len = comp.layers.length;
-
         while (i < len) {
           if (comp.layers[i].nm === name || comp.layers[i].ind === name) {
             return comp.elements[i].layerInterface;
           }
-
           i += 1;
         }
-
-        return null; // return {active:false};
+        return null;
+        // return {active:false};
       }
-
       Object.defineProperty(_thisLayerFunction, '_name', {
         value: comp.data.nm
       });
@@ -16501,10 +14037,8 @@
     };
   }();
 
-  function _typeof$2(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$2 = function _typeof(obj) { return typeof obj; }; } else { _typeof$2 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$2(obj); }
-
+  function _typeof$2(o) { "@babel/helpers - typeof"; return _typeof$2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$2(o); }
   /* eslint-disable */
-
   /*
    Copyright 2014 David Bau.
 
@@ -16528,105 +14062,103 @@
    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
    */
+
   function seedRandom(pool, math) {
     //
     // The following constants are related to IEEE 754 limits.
     //
     var global = this,
-        width = 256,
-        // each RC4 output is 0 <= x < 256
-    chunks = 6,
-        // at least six RC4 outputs for each double
-    digits = 52,
-        // there are 52 significant digits in a double
-    rngname = 'random',
-        // rngname: name for Math.random and Math.seedrandom
-    startdenom = math.pow(width, chunks),
-        significance = math.pow(2, digits),
-        overflow = significance * 2,
-        mask = width - 1,
-        nodecrypto; // node.js crypto module, initialized at the bottom.
+      width = 256,
+      // each RC4 output is 0 <= x < 256
+      chunks = 6,
+      // at least six RC4 outputs for each double
+      digits = 52,
+      // there are 52 significant digits in a double
+      rngname = 'random',
+      // rngname: name for Math.random and Math.seedrandom
+      startdenom = math.pow(width, chunks),
+      significance = math.pow(2, digits),
+      overflow = significance * 2,
+      mask = width - 1,
+      nodecrypto; // node.js crypto module, initialized at the bottom.
+
     //
     // seedrandom()
     // This is the seedrandom function described above.
     //
-
     function seedrandom(seed, options, callback) {
       var key = [];
       options = options === true ? {
         entropy: true
-      } : options || {}; // Flatten the seed string or build one from local entropy if needed.
+      } : options || {};
 
-      var shortseed = mixkey(flatten(options.entropy ? [seed, tostring(pool)] : seed === null ? autoseed() : seed, 3), key); // Use the seed to initialize an ARC4 generator.
+      // Flatten the seed string or build one from local entropy if needed.
+      var shortseed = mixkey(flatten(options.entropy ? [seed, tostring(pool)] : seed === null ? autoseed() : seed, 3), key);
 
-      var arc4 = new ARC4(key); // This function returns a random double in [0, 1) that contains
+      // Use the seed to initialize an ARC4 generator.
+      var arc4 = new ARC4(key);
+
+      // This function returns a random double in [0, 1) that contains
       // randomness in every bit of the mantissa of the IEEE 754 value.
-
       var prng = function prng() {
         var n = arc4.g(chunks),
-            // Start with a numerator n < 2 ^ 48
-        d = startdenom,
-            //   and denominator d = 2 ^ 48.
-        x = 0; //   and no 'extra last byte'.
-
+          // Start with a numerator n < 2 ^ 48
+          d = startdenom,
+          //   and denominator d = 2 ^ 48.
+          x = 0; //   and no 'extra last byte'.
         while (n < significance) {
           // Fill up all significant digits by
           n = (n + x) * width; //   shifting numerator and
-
           d *= width; //   denominator and generating a
-
           x = arc4.g(1); //   new least-significant-byte.
         }
-
         while (n >= overflow) {
           // To avoid rounding up, before adding
           n /= 2; //   last byte, shift everything
-
           d /= 2; //   right using integer math until
-
           x >>>= 1; //   we have exactly the desired bits.
         }
-
         return (n + x) / d; // Form the number within [0, 1).
       };
-
       prng.int32 = function () {
         return arc4.g(4) | 0;
       };
-
       prng.quick = function () {
         return arc4.g(4) / 0x100000000;
       };
+      prng["double"] = prng;
 
-      prng["double"] = prng; // Mix the randomness into accumulated entropy.
+      // Mix the randomness into accumulated entropy.
+      mixkey(tostring(arc4.S), pool);
 
-      mixkey(tostring(arc4.S), pool); // Calling convention: what to return as a function of prng, seed, is_math.
-
+      // Calling convention: what to return as a function of prng, seed, is_math.
       return (options.pass || callback || function (prng, seed, is_math_call, state) {
         if (state) {
           // Load the arc4 state from the given state if it has an S array.
           if (state.S) {
             copy(state, arc4);
-          } // Only provide the .state method if requested via options.state.
-
-
+          }
+          // Only provide the .state method if requested via options.state.
           prng.state = function () {
             return copy(arc4, {});
           };
-        } // If called as a method of Math (Math.seedrandom()), mutate
+        }
+
+        // If called as a method of Math (Math.seedrandom()), mutate
         // Math.random because that is how seedrandom.js has worked since v1.0.
-
-
         if (is_math_call) {
           math[rngname] = prng;
           return seed;
-        } // Otherwise, it is a newer calling convention, so return the
+        }
+
+        // Otherwise, it is a newer calling convention, so return the
         // prng directly.
         else return prng;
       })(prng, shortseed, 'global' in options ? options.global : this == math, options.state);
     }
+    math['seed' + rngname] = seedrandom;
 
-    math['seed' + rngname] = seedrandom; //
+    //
     // ARC4
     //
     // An ARC4 implementation.  The constructor takes a key in the form of
@@ -16636,71 +14168,68 @@
     // the next (count) outputs from ARC4.  Its return value is a number x
     // that is in the range 0 <= x < (width ^ count).
     //
-
     function ARC4(key) {
       var t,
-          keylen = key.length,
-          me = this,
-          i = 0,
-          j = me.i = me.j = 0,
-          s = me.S = []; // The empty key [] is treated as [0].
+        keylen = key.length,
+        me = this,
+        i = 0,
+        j = me.i = me.j = 0,
+        s = me.S = [];
 
+      // The empty key [] is treated as [0].
       if (!keylen) {
         key = [keylen++];
-      } // Set up S using the standard key scheduling algorithm.
+      }
 
-
+      // Set up S using the standard key scheduling algorithm.
       while (i < width) {
         s[i] = i++;
       }
-
       for (i = 0; i < width; i++) {
         s[i] = s[j = mask & j + key[i % keylen] + (t = s[i])];
         s[j] = t;
-      } // The "g" method returns the next (count) outputs as one number.
+      }
 
-
+      // The "g" method returns the next (count) outputs as one number.
       me.g = function (count) {
         // Using instance members instead of closure state nearly doubles speed.
         var t,
-            r = 0,
-            i = me.i,
-            j = me.j,
-            s = me.S;
-
+          r = 0,
+          i = me.i,
+          j = me.j,
+          s = me.S;
         while (count--) {
           t = s[i = mask & i + 1];
           r = r * width + s[mask & (s[i] = s[j = mask & j + t]) + (s[j] = t)];
         }
-
         me.i = i;
         me.j = j;
-        return r; // For robust unpredictability, the function call below automatically
+        return r;
+        // For robust unpredictability, the function call below automatically
         // discards an initial batch of values.  This is called RC4-drop[256].
         // See http://google.com/search?q=rsa+fluhrer+response&btnI
       };
-    } //
+    }
+
+    //
     // copy()
     // Copies internal state of ARC4 to or from a plain object.
     //
-
-
     function copy(f, t) {
       t.i = f.i;
       t.j = f.j;
       t.S = f.S.slice();
       return t;
-    } //
+    }
+
+    //
     // flatten()
     // Converts an object tree to nested arrays of strings.
     //
-
-
     function flatten(obj, depth) {
       var result = [],
-          typ = _typeof$2(obj),
-          prop;
-
+        typ = _typeof$2(obj),
+        prop;
       if (depth && typ == 'object') {
         for (prop in obj) {
           try {
@@ -16708,72 +14237,69 @@
           } catch (e) {}
         }
       }
-
       return result.length ? result : typ == 'string' ? obj : obj + '\0';
-    } //
+    }
+
+    //
     // mixkey()
     // Mixes a string seed into a key that is an array of integers, and
     // returns a shortened string seed that is equivalent to the result key.
     //
-
-
     function mixkey(seed, key) {
       var stringseed = seed + '',
-          smear,
-          j = 0;
-
+        smear,
+        j = 0;
       while (j < stringseed.length) {
         key[mask & j] = mask & (smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++);
       }
-
       return tostring(key);
-    } //
+    }
+
+    //
     // autoseed()
     // Returns an object for autoseeding, using window.crypto and Node crypto
     // module if available.
     //
-
-
     function autoseed() {
       try {
         if (nodecrypto) {
           return tostring(nodecrypto.randomBytes(width));
         }
-
         var out = new Uint8Array(width);
         (global.crypto || global.msCrypto).getRandomValues(out);
         return tostring(out);
       } catch (e) {
         var browser = global.navigator,
-            plugins = browser && browser.plugins;
+          plugins = browser && browser.plugins;
         return [+new Date(), global, plugins, global.screen, tostring(pool)];
       }
-    } //
+    }
+
+    //
     // tostring()
     // Converts an array of charcodes to a string
     //
-
-
     function tostring(a) {
       return String.fromCharCode.apply(0, a);
-    } //
+    }
+
+    //
     // When seedrandom.js is loaded, we immediately mix a few bits
     // from the built-in RNG into the entropy pool.  Because we do
     // not want to interfere with deterministic PRNG state later,
     // seedrandom will not call math.random on its own again after
     // initialization.
     //
+    mixkey(math.random(), pool);
 
-
-    mixkey(math.random(), pool); //
+    //
     // Nodejs and AMD support: export the implementation as a module using
     // either convention.
     //
+
     // End anonymous scope, and pass initial values.
   }
-
   ;
-
   function initialize$2(BMMath) {
     seedRandom([], BMMath);
   }
@@ -16782,8 +14308,7 @@
     SHAPE: 'shape'
   };
 
-  function _typeof$1(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$1 = function _typeof(obj) { return typeof obj; }; } else { _typeof$1 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$1(obj); }
-
+  function _typeof$1(o) { "@babel/helpers - typeof"; return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$1(o); }
   var ExpressionManager = function () {
     'use strict';
 
@@ -16796,289 +14321,214 @@
     var frames = null;
     var _lottieGlobal = {};
     initialize$2(BMMath);
-
     function resetFrame() {
       _lottieGlobal = {};
     }
-
     function $bm_isInstanceOfArray(arr) {
       return arr.constructor === Array || arr.constructor === Float32Array;
     }
-
     function isNumerable(tOfV, v) {
       return tOfV === 'number' || v instanceof Number || tOfV === 'boolean' || tOfV === 'string';
     }
-
     function $bm_neg(a) {
       var tOfA = _typeof$1(a);
-
       if (tOfA === 'number' || a instanceof Number || tOfA === 'boolean') {
         return -a;
       }
-
       if ($bm_isInstanceOfArray(a)) {
         var i;
         var lenA = a.length;
         var retArr = [];
-
         for (i = 0; i < lenA; i += 1) {
           retArr[i] = -a[i];
         }
-
         return retArr;
       }
-
       if (a.propType) {
         return a.v;
       }
-
       return -a;
     }
-
     var easeInBez = BezierFactory.getBezierEasing(0.333, 0, 0.833, 0.833, 'easeIn').get;
     var easeOutBez = BezierFactory.getBezierEasing(0.167, 0.167, 0.667, 1, 'easeOut').get;
     var easeInOutBez = BezierFactory.getBezierEasing(0.33, 0, 0.667, 1, 'easeInOut').get;
-
     function sum(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b) || tOfA === 'string' || tOfB === 'string') {
         return a + b;
       }
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         a = a.slice(0);
         a[0] += b;
         return a;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         b = b.slice(0);
         b[0] = a + b[0];
         return b;
       }
-
       if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
         var i = 0;
         var lenA = a.length;
         var lenB = b.length;
         var retArr = [];
-
         while (i < lenA || i < lenB) {
           if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
             retArr[i] = a[i] + b[i];
           } else {
             retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
           }
-
           i += 1;
         }
-
         return retArr;
       }
-
       return 0;
     }
-
     var add = sum;
-
     function sub(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         if (tOfA === 'string') {
           a = parseInt(a, 10);
         }
-
         if (tOfB === 'string') {
           b = parseInt(b, 10);
         }
-
         return a - b;
       }
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         a = a.slice(0);
         a[0] -= b;
         return a;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         b = b.slice(0);
         b[0] = a - b[0];
         return b;
       }
-
       if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
         var i = 0;
         var lenA = a.length;
         var lenB = b.length;
         var retArr = [];
-
         while (i < lenA || i < lenB) {
           if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
             retArr[i] = a[i] - b[i];
           } else {
             retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
           }
-
           i += 1;
         }
-
         return retArr;
       }
-
       return 0;
     }
-
     function mul(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       var arr;
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         return a * b;
       }
-
       var i;
       var len;
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         len = a.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a[i] * b;
         }
-
         return arr;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         len = b.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a * b[i];
         }
-
         return arr;
       }
-
       return 0;
     }
-
     function div(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       var arr;
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         return a / b;
       }
-
       var i;
       var len;
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         len = a.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a[i] / b;
         }
-
         return arr;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         len = b.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a / b[i];
         }
-
         return arr;
       }
-
       return 0;
     }
-
     function mod(a, b) {
       if (typeof a === 'string') {
         a = parseInt(a, 10);
       }
-
       if (typeof b === 'string') {
         b = parseInt(b, 10);
       }
-
       return a % b;
     }
-
     var $bm_sum = sum;
     var $bm_sub = sub;
     var $bm_mul = mul;
     var $bm_div = div;
     var $bm_mod = mod;
-
     function clamp(num, min, max) {
       if (min > max) {
         var mm = max;
         max = min;
         min = mm;
       }
-
       return Math.min(Math.max(num, min), max);
     }
-
     function radiansToDegrees(val) {
       return val / degToRads;
     }
-
     var radians_to_degrees = radiansToDegrees;
-
     function degreesToRadians(val) {
       return val * degToRads;
     }
-
     var degrees_to_radians = radiansToDegrees;
     var helperLengthArray = [0, 0, 0, 0, 0, 0];
-
     function length(arr1, arr2) {
       if (typeof arr1 === 'number' || arr1 instanceof Number) {
         arr2 = arr2 || 0;
         return Math.abs(arr1 - arr2);
       }
-
       if (!arr2) {
         arr2 = helperLengthArray;
       }
-
       var i;
       var len = Math.min(arr1.length, arr2.length);
       var addedLength = 0;
-
       for (i = 0; i < len; i += 1) {
         addedLength += Math.pow(arr2[i] - arr1[i], 2);
       }
-
       return Math.sqrt(addedLength);
     }
-
     function normalize(vec) {
       return div(vec, length(vec));
     }
-
     function rgbToHsl(val) {
       var r = val[0];
       var g = val[1];
@@ -17088,38 +14538,29 @@
       var h;
       var s;
       var l = (max + min) / 2;
-
       if (max === min) {
         h = 0; // achromatic
-
         s = 0; // achromatic
       } else {
         var d = max - min;
         s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
-
         switch (max) {
           case r:
             h = (g - b) / d + (g < b ? 6 : 0);
             break;
-
           case g:
             h = (b - r) / d + 2;
             break;
-
           case b:
             h = (r - g) / d + 4;
             break;
-
           default:
             break;
         }
-
         h /= 6;
       }
-
       return [h, s, l, val[3]];
     }
-
     function hue2rgb(p, q, t) {
       if (t < 0) t += 1;
       if (t > 1) t -= 1;
@@ -17128,7 +14569,6 @@
       if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
       return p;
     }
-
     function hslToRgb(val) {
       var h = val[0];
       var s = val[1];
@@ -17136,12 +14576,9 @@
       var r;
       var g;
       var b;
-
       if (s === 0) {
         r = l; // achromatic
-
         b = l; // achromatic
-
         g = l; // achromatic
       } else {
         var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
@@ -17150,10 +14587,8 @@
         g = hue2rgb(p, q, h);
         b = hue2rgb(p, q, h - 1 / 3);
       }
-
       return [r, g, b, val[3]];
     }
-
     function linear(t, tMin, tMax, value1, value2) {
       if (value1 === undefined || value2 === undefined) {
         value1 = tMin;
@@ -17161,38 +14596,29 @@
         tMin = 0;
         tMax = 1;
       }
-
       if (tMax < tMin) {
         var _tMin = tMax;
         tMax = tMin;
         tMin = _tMin;
       }
-
       if (t <= tMin) {
         return value1;
       }
-
       if (t >= tMax) {
         return value2;
       }
-
       var perc = tMax === tMin ? 0 : (t - tMin) / (tMax - tMin);
-
       if (!value1.length) {
         return value1 + (value2 - value1) * perc;
       }
-
       var i;
       var len = value1.length;
       var arr = createTypedArray('float32', len);
-
       for (i = 0; i < len; i += 1) {
         arr[i] = value1[i] + (value2[i] - value1[i]) * perc;
       }
-
       return arr;
     }
-
     function random(min, max) {
       if (max === undefined) {
         if (min === undefined) {
@@ -17203,33 +14629,25 @@
           min = undefined;
         }
       }
-
       if (max.length) {
         var i;
         var len = max.length;
-
         if (!min) {
           min = createTypedArray('float32', len);
         }
-
         var arr = createTypedArray('float32', len);
         var rnd = BMMath.random();
-
         for (i = 0; i < len; i += 1) {
           arr[i] = min[i] + rnd * (max[i] - min[i]);
         }
-
         return arr;
       }
-
       if (min === undefined) {
         min = 0;
       }
-
       var rndm = BMMath.random();
       return min + rndm * (max - min);
     }
-
     function createPath(points, inTangents, outTangents, closed) {
       var i;
       var len = points.length;
@@ -17238,37 +14656,31 @@
       var arrPlaceholder = [0, 0];
       var inVertexPoint;
       var outVertexPoint;
-
       for (i = 0; i < len; i += 1) {
         inVertexPoint = inTangents && inTangents[i] ? inTangents[i] : arrPlaceholder;
         outVertexPoint = outTangents && outTangents[i] ? outTangents[i] : arrPlaceholder;
         path.setTripleAt(points[i][0], points[i][1], outVertexPoint[0] + points[i][0], outVertexPoint[1] + points[i][1], inVertexPoint[0] + points[i][0], inVertexPoint[1] + points[i][1], i, true);
       }
-
       return path;
     }
-
     function initiateExpression(elem, data, property) {
       // Bail out if we don't want expressions
       function noOp(_value) {
         return _value;
       }
-
       if (!elem.globalData.renderConfig.runExpressions) {
         return noOp;
       }
-
       var val = data.x;
       var needsVelocity = /velocity(?![\w\d])/.test(val);
-
       var _needsRandom = val.indexOf('random') !== -1;
-
       var elemType = elem.data.ty;
       var transform;
       var $bm_transform;
       var content;
       var effect;
       var thisProperty = property;
+      thisProperty._name = elem.data.nm;
       thisProperty.valueAtTime = thisProperty.getValueAtTime;
       Object.defineProperty(thisProperty, 'value', {
         get: function get() {
@@ -17301,13 +14713,11 @@
       var mask;
       var valueAtTime;
       var velocityAtTime;
-      var scoped_bm_rt; // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
-
+      var scoped_bm_rt;
+      // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
       var expression_function = eval('[function _expression_function(){' + val + ';scoped_bm_rt=$bm_rt}]')[0]; // eslint-disable-line no-eval
-
       var numKeys = property.kf ? data.k.length : 0;
       var active = !this.data || this.data.hd !== true;
-
       var wiggle = function wiggle(freq, amp) {
         var iWiggle;
         var j;
@@ -17317,84 +14727,67 @@
         var iterations = Math.floor(time * freq);
         iWiggle = 0;
         j = 0;
-
         while (iWiggle < iterations) {
           // var rnd = BMMath.random();
           for (j = 0; j < lenWiggle; j += 1) {
-            addedAmps[j] += -amp + amp * 2 * BMMath.random(); // addedAmps[j] += -amp + amp*2*rnd;
+            addedAmps[j] += -amp + amp * 2 * BMMath.random();
+            // addedAmps[j] += -amp + amp*2*rnd;
           }
-
           iWiggle += 1;
-        } // var rnd2 = BMMath.random();
-
-
+        }
+        // var rnd2 = BMMath.random();
         var periods = time * freq;
         var perc = periods - Math.floor(periods);
         var arr = createTypedArray('float32', lenWiggle);
-
         if (lenWiggle > 1) {
           for (j = 0; j < lenWiggle; j += 1) {
-            arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc; // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
+            arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc;
+            // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
             // arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc);
           }
-
           return arr;
         }
-
         return this.pv + addedAmps[0] + (-amp + amp * 2 * BMMath.random()) * perc;
       }.bind(this);
-
       if (thisProperty.loopIn) {
         loopIn = thisProperty.loopIn.bind(thisProperty);
         loop_in = loopIn;
       }
-
       if (thisProperty.loopOut) {
         loopOut = thisProperty.loopOut.bind(thisProperty);
         loop_out = loopOut;
       }
-
       if (thisProperty.smooth) {
         smooth = thisProperty.smooth.bind(thisProperty);
       }
-
       function loopInDuration(type, duration) {
         return loopIn(type, duration, true);
       }
-
       function loopOutDuration(type, duration) {
         return loopOut(type, duration, true);
       }
-
       if (this.getValueAtTime) {
         valueAtTime = this.getValueAtTime.bind(this);
       }
-
       if (this.getVelocityAtTime) {
         velocityAtTime = this.getVelocityAtTime.bind(this);
       }
-
       var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface);
-
       function lookAt(elem1, elem2) {
         var fVec = [elem2[0] - elem1[0], elem2[1] - elem1[1], elem2[2] - elem1[2]];
         var pitch = Math.atan2(fVec[0], Math.sqrt(fVec[1] * fVec[1] + fVec[2] * fVec[2])) / degToRads;
         var yaw = -Math.atan2(fVec[1], fVec[2]) / degToRads;
         return [yaw, pitch, 0];
       }
-
       function easeOut(t, tMin, tMax, val1, val2) {
         return applyEase(easeOutBez, t, tMin, tMax, val1, val2);
       }
-
       function easeIn(t, tMin, tMax, val1, val2) {
         return applyEase(easeInBez, t, tMin, tMax, val1, val2);
       }
-
       function ease(t, tMin, tMax, val1, val2) {
         return applyEase(easeInOutBez, t, tMin, tMax, val1, val2);
       }
-
       function applyEase(fn, t, tMin, tMax, val1, val2) {
         if (val1 === undefined) {
           val1 = tMin;
@@ -17402,43 +14795,34 @@
         } else {
           t = (t - tMin) / (tMax - tMin);
         }
-
         if (t > 1) {
           t = 1;
         } else if (t < 0) {
           t = 0;
         }
-
         var mult = fn(t);
-
         if ($bm_isInstanceOfArray(val1)) {
           var iKey;
           var lenKey = val1.length;
           var arr = createTypedArray('float32', lenKey);
-
           for (iKey = 0; iKey < lenKey; iKey += 1) {
             arr[iKey] = (val2[iKey] - val1[iKey]) * mult + val1[iKey];
           }
-
           return arr;
         }
-
         return (val2 - val1) * mult + val1;
       }
-
       function nearestKey(time) {
         var iKey;
         var lenKey = data.k.length;
         var index;
         var keyTime;
-
         if (!data.k.length || typeof data.k[0] === 'number') {
           index = 0;
           keyTime = 0;
         } else {
           index = -1;
           time *= elem.comp.globalData.frameRate;
-
           if (time < data.k[0].t) {
             index = 1;
             keyTime = data.k[0].t;
@@ -17456,33 +14840,27 @@
                   index = iKey + 1;
                   keyTime = data.k[iKey].t;
                 }
-
                 break;
               }
             }
-
             if (index === -1) {
               index = iKey + 1;
               keyTime = data.k[iKey].t;
             }
           }
         }
-
         var obKey = {};
         obKey.index = index;
         obKey.time = keyTime / elem.comp.globalData.frameRate;
         return obKey;
       }
-
       function key(ind) {
         var obKey;
         var iKey;
         var lenKey;
-
         if (!data.k.length || typeof data.k[0] === 'number') {
           throw new Error('The property has no keyframe at index ' + ind);
         }
-
         ind -= 1;
         obKey = {
           time: data.k[ind].t / elem.comp.globalData.frameRate,
@@ -17490,72 +14868,55 @@
         };
         var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e;
         lenKey = arr.length;
-
         for (iKey = 0; iKey < lenKey; iKey += 1) {
           obKey[iKey] = arr[iKey];
           obKey.value[iKey] = arr[iKey];
         }
-
         return obKey;
       }
-
       function framesToTime(fr, fps) {
         if (!fps) {
           fps = elem.comp.globalData.frameRate;
         }
-
         return fr / fps;
       }
-
       function timeToFrames(t, fps) {
         if (!t && t !== 0) {
           t = time;
         }
-
         if (!fps) {
           fps = elem.comp.globalData.frameRate;
         }
-
         return t * fps;
       }
-
       function seedRandom(seed) {
         BMMath.seedrandom(randSeed + seed);
       }
-
       function sourceRectAtTime() {
         return elem.sourceRectAtTime();
       }
-
       function substring(init, end) {
         if (typeof value === 'string') {
           if (end === undefined) {
             return value.substring(init);
           }
-
           return value.substring(init, end);
         }
-
         return '';
       }
-
       function substr(init, end) {
         if (typeof value === 'string') {
           if (end === undefined) {
             return value.substr(init);
           }
-
           return value.substr(init, end);
         }
-
         return '';
       }
-
       function posterizeTime(framesPerSecond) {
         time = framesPerSecond === 0 ? 0 : Math.floor(time * framesPerSecond) / framesPerSecond;
         value = valueAtTime(time);
       }
-
       var time;
       var velocity;
       var value;
@@ -17568,21 +14929,17 @@
       var parent;
       var randSeed = Math.floor(Math.random() * 1000000);
       var globalData = elem.globalData;
-
       function executeExpression(_value) {
         // globalData.pushExpression();
         value = _value;
-
         if (this.frameExpressionId === elem.globalData.frameId && this.propType !== 'textSelector') {
           return value;
         }
-
         if (this.propType === 'textSelector') {
           textIndex = this.textIndex;
           textTotal = this.textTotal;
           selectorValue = this.selectorValue;
         }
-
         if (!thisLayer) {
           text = elem.layerInterface.text;
           thisLayer = elem.layerInterface;
@@ -17594,11 +14951,9 @@
           mask = thisLayer.mask ? thisLayer.mask.bind(thisLayer) : null;
           fromCompToSurface = fromComp;
         }
-
         if (!transform) {
           transform = elem.layerInterface('ADBE Transform Group');
           $bm_transform = transform;
-
           if (transform) {
             anchorPoint = transform.anchorPoint;
             /* position = transform.position;
@@ -17606,44 +14961,35 @@
                       scale = transform.scale; */
           }
         }
-
         if (elemType === 4 && !content) {
           content = thisLayer('ADBE Root Vectors Group');
         }
-
         if (!effect) {
           effect = thisLayer(4);
         }
-
         hasParent = !!(elem.hierarchy && elem.hierarchy.length);
-
         if (hasParent && !parent) {
           parent = elem.hierarchy[0].layerInterface;
         }
-
         time = this.comp.renderedFrame / this.comp.globalData.frameRate;
-
         if (_needsRandom) {
           seedRandom(randSeed + time);
         }
-
         if (needsVelocity) {
           velocity = velocityAtTime(time);
         }
-
         expression_function();
-        this.frameExpressionId = elem.globalData.frameId; // TODO: Check if it's possible to return on ShapeInterface the .v value
-        // Changed this to a ternary operation because Rollup failed compiling it correctly
+        this.frameExpressionId = elem.globalData.frameId;
 
+        // TODO: Check if it's possible to return on ShapeInterface the .v value
+        // Changed this to a ternary operation because Rollup failed compiling it correctly
         scoped_bm_rt = scoped_bm_rt.propType === propTypes.SHAPE ? scoped_bm_rt.v : scoped_bm_rt;
         return scoped_bm_rt;
-      } // Bundlers will see these as dead code and unless we reference them
-
-
+      }
+      // Bundlers will see these as dead code and unless we reference them
       executeExpression.__preventDeadCodeRemoval = [$bm_transform, anchorPoint, time, velocity, inPoint, outPoint, width, height, name, loop_in, loop_out, smooth, toComp, fromCompToSurface, toWorld, fromWorld, mask, position, rotation, scale, thisComp, numKeys, active, wiggle, loopInDuration, loopOutDuration, comp, lookAt, easeOut, easeIn, ease, nearestKey, key, text, textIndex, textTotal, selectorValue, framesToTime, timeToFrames, sourceRectAtTime, substring, substr, posterizeTime, index, globalData];
       return executeExpression;
     }
-
     ob.initiateExpression = initiateExpression;
     ob.__preventDeadCodeRemoval = [window, document, XMLHttpRequest, fetch, frames, $bm_neg, add, $bm_sum, $bm_sub, $bm_mul, $bm_div, $bm_mod, clamp, radians_to_degrees, degreesToRadians, degrees_to_radians, normalize, rgbToHsl, hslToRgb, linear, random, createPath, _lottieGlobal];
     ob.resetFrame = resetFrame;
@@ -17654,47 +15000,37 @@
     var ob = {};
     ob.initExpressions = initExpressions;
     ob.resetFrame = ExpressionManager.resetFrame;
-
     function initExpressions(animation) {
       var stackCount = 0;
       var registers = [];
-
       function pushExpression() {
         stackCount += 1;
       }
-
       function popExpression() {
         stackCount -= 1;
-
         if (stackCount === 0) {
           releaseInstances();
         }
       }
-
       function registerExpressionProperty(expression) {
         if (registers.indexOf(expression) === -1) {
           registers.push(expression);
         }
       }
-
       function releaseInstances() {
         var i;
         var len = registers.length;
-
         for (i = 0; i < len; i += 1) {
           registers[i].release();
         }
-
         registers.length = 0;
       }
-
       animation.renderer.compInterface = CompExpressionInterface(animation.renderer);
       animation.renderer.globalData.projectInterface.registerComposition(animation.renderer);
       animation.renderer.globalData.pushExpression = pushExpression;
       animation.renderer.globalData.popExpression = popExpression;
       animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty;
     }
-
     return ob;
   }();
 
@@ -17703,13 +15039,11 @@
       this._mask = mask;
       this._data = data;
     }
-
     Object.defineProperty(MaskInterface.prototype, 'maskPath', {
       get: function get() {
         if (this._mask.prop.k) {
           this._mask.prop.getValue();
         }
-
         return this._mask.prop;
       }
     });
@@ -17718,38 +15052,28 @@
         if (this._mask.op.k) {
           this._mask.op.getValue();
         }
-
         return this._mask.op.v * 100;
       }
     });
-
     var MaskManager = function MaskManager(maskManager) {
       var _masksInterfaces = createSizedArray(maskManager.viewData.length);
-
       var i;
       var len = maskManager.viewData.length;
-
       for (i = 0; i < len; i += 1) {
         _masksInterfaces[i] = new MaskInterface(maskManager.viewData[i], maskManager.masksProperties[i]);
       }
-
       var maskFunction = function maskFunction(name) {
         i = 0;
-
         while (i < len) {
           if (maskManager.masksProperties[i].nm === name) {
             return _masksInterfaces[i];
           }
-
           i += 1;
         }
-
         return null;
       };
-
       return maskFunction;
     };
-
     return MaskManager;
   }();
 
@@ -17764,7 +15088,6 @@
       v: [0, 0, 0],
       mult: 1
     };
-
     function completeProperty(expressionValue, property, type) {
       Object.defineProperty(expressionValue, 'velocity', {
         get: function get() {
@@ -17772,14 +15095,11 @@
         }
       });
       expressionValue.numKeys = property.keyframes ? property.keyframes.length : 0;
-
       expressionValue.key = function (pos) {
         if (!expressionValue.numKeys) {
           return 0;
         }
-
         var value = '';
-
         if ('s' in property.keyframes[pos - 1]) {
           value = property.keyframes[pos - 1].s;
         } else if ('e' in property.keyframes[pos - 2]) {
@@ -17787,54 +15107,43 @@
         } else {
           value = property.keyframes[pos - 2].s;
         }
-
         var valueProp = type === 'unidimensional' ? new Number(value) : Object.assign({}, value); // eslint-disable-line no-new-wrappers
-
         valueProp.time = property.keyframes[pos - 1].t / property.elem.comp.globalData.frameRate;
         valueProp.value = type === 'unidimensional' ? value[0] : value;
         return valueProp;
       };
-
       expressionValue.valueAtTime = property.getValueAtTime;
       expressionValue.speedAtTime = property.getSpeedAtTime;
       expressionValue.velocityAtTime = property.getVelocityAtTime;
       expressionValue.propertyGroup = property.propertyGroup;
     }
-
     function UnidimensionalPropertyInterface(property) {
       if (!property || !('pv' in property)) {
         property = defaultUnidimensionalValue;
       }
-
       var mult = 1 / property.mult;
       var val = property.pv * mult;
       var expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
-
       expressionValue.value = val;
       completeProperty(expressionValue, property, 'unidimensional');
       return function () {
         if (property.k) {
           property.getValue();
         }
-
         val = property.v * mult;
-
         if (expressionValue.value !== val) {
           expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
-
           expressionValue.value = val;
+          expressionValue[0] = val;
           completeProperty(expressionValue, property, 'unidimensional');
         }
-
         return expressionValue;
       };
     }
-
     function MultidimensionalPropertyInterface(property) {
       if (!property || !('pv' in property)) {
         property = defaultMultidimensionalValue;
       }
-
       var mult = 1 / property.mult;
       var len = property.data && property.data.l || property.pv.length;
       var expressionValue = createTypedArray('float32', len);
@@ -17845,30 +15154,25 @@
         if (property.k) {
           property.getValue();
         }
-
         for (var i = 0; i < len; i += 1) {
           arrValue[i] = property.v[i] * mult;
           expressionValue[i] = arrValue[i];
         }
-
         return expressionValue;
       };
-    } // TODO: try to avoid using this getter
+    }
 
-
+    // TODO: try to avoid using this getter
     function defaultGetter() {
       return defaultUnidimensionalValue;
     }
-
     return function (property) {
       if (!property) {
         return defaultGetter;
       }
-
       if (property.propType === 'unidimensional') {
         return UnidimensionalPropertyInterface(property);
       }
-
       return MultidimensionalPropertyInterface(property);
     };
   }();
@@ -17882,52 +15186,41 @@
           case 'ADBE Scale':
           case 6:
             return _thisFunction.scale;
-
           case 'rotation':
           case 'Rotation':
           case 'ADBE Rotation':
           case 'ADBE Rotate Z':
           case 10:
             return _thisFunction.rotation;
-
           case 'ADBE Rotate X':
             return _thisFunction.xRotation;
-
           case 'ADBE Rotate Y':
             return _thisFunction.yRotation;
-
           case 'position':
           case 'Position':
           case 'ADBE Position':
           case 2:
             return _thisFunction.position;
-
           case 'ADBE Position_0':
             return _thisFunction.xPosition;
-
           case 'ADBE Position_1':
             return _thisFunction.yPosition;
-
           case 'ADBE Position_2':
             return _thisFunction.zPosition;
-
           case 'anchorPoint':
           case 'AnchorPoint':
           case 'Anchor Point':
           case 'ADBE AnchorPoint':
           case 1:
             return _thisFunction.anchorPoint;
-
           case 'opacity':
           case 'Opacity':
           case 11:
             return _thisFunction.opacity;
-
           default:
             return null;
         }
       }
-
       Object.defineProperty(_thisFunction, 'rotation', {
         get: ExpressionPropertyInterface(transform.r || transform.rz)
       });
@@ -17943,32 +15236,24 @@
       Object.defineProperty(_thisFunction, 'scale', {
         get: ExpressionPropertyInterface(transform.s)
       });
-
       var _px;
-
       var _py;
-
       var _pz;
-
       var _transformFactory;
-
       if (transform.p) {
         _transformFactory = ExpressionPropertyInterface(transform.p);
       } else {
         _px = ExpressionPropertyInterface(transform.px);
         _py = ExpressionPropertyInterface(transform.py);
-
         if (transform.pz) {
           _pz = ExpressionPropertyInterface(transform.pz);
         }
       }
-
       Object.defineProperty(_thisFunction, 'position', {
         get: function get() {
           if (transform.p) {
             return _transformFactory();
           }
-
           return [_px(), _py(), _pz ? _pz() : 0];
         }
       });
@@ -18003,19 +15288,15 @@
   var LayerExpressionInterface = function () {
     function getMatrix(time) {
       var toWorldMat = new Matrix();
-
       if (time !== undefined) {
         var propMatrix = this._elem.finalTransform.mProp.getValueAtTime(time);
-
         propMatrix.clone(toWorldMat);
       } else {
         var transformMat = this._elem.finalTransform.mProp;
         transformMat.applyToMatrix(toWorldMat);
       }
-
       return toWorldMat;
     }
-
     function toWorldVec(arr, time) {
       var toWorldMat = this.getMatrix(time);
       toWorldMat.props[12] = 0;
@@ -18023,12 +15304,10 @@
       toWorldMat.props[14] = 0;
       return this.applyPoint(toWorldMat, arr);
     }
-
     function toWorld(arr, time) {
       var toWorldMat = this.getMatrix(time);
       return this.applyPoint(toWorldMat, arr);
     }
-
     function fromWorldVec(arr, time) {
       var toWorldMat = this.getMatrix(time);
       toWorldMat.props[12] = 0;
@@ -18036,101 +15315,78 @@
       toWorldMat.props[14] = 0;
       return this.invertPoint(toWorldMat, arr);
     }
-
     function fromWorld(arr, time) {
       var toWorldMat = this.getMatrix(time);
       return this.invertPoint(toWorldMat, arr);
     }
-
     function applyPoint(matrix, arr) {
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
         }
       }
-
       return matrix.applyToPointArray(arr[0], arr[1], arr[2] || 0);
     }
-
     function invertPoint(matrix, arr) {
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
         }
       }
-
       return matrix.inversePoint(arr);
     }
-
     function fromComp(arr) {
       var toWorldMat = new Matrix();
       toWorldMat.reset();
-
       this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
-
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
         }
-
         return toWorldMat.inversePoint(arr);
       }
-
       return toWorldMat.inversePoint(arr);
     }
-
     function sampleImage() {
       return [1, 1, 1, 1];
     }
-
     return function (elem) {
       var transformInterface;
-
       function _registerMaskInterface(maskManager) {
         _thisLayerFunction.mask = new MaskManagerInterface(maskManager, elem);
       }
-
       function _registerEffectsInterface(effects) {
         _thisLayerFunction.effect = effects;
       }
-
       function _thisLayerFunction(name) {
         switch (name) {
           case 'ADBE Root Vectors Group':
           case 'Contents':
           case 2:
             return _thisLayerFunction.shapeInterface;
-
           case 1:
           case 6:
           case 'Transform':
           case 'transform':
           case 'ADBE Transform Group':
             return transformInterface;
-
           case 4:
           case 'ADBE Effect Parade':
           case 'effects':
           case 'Effects':
             return _thisLayerFunction.effect;
-
           case 'ADBE Text Properties':
             return _thisLayerFunction.textInterface;
-
           default:
             return null;
         }
       }
-
       _thisLayerFunction.getMatrix = getMatrix;
       _thisLayerFunction.invertPoint = invertPoint;
       _thisLayerFunction.applyPoint = applyPoint;
@@ -18191,11 +15447,9 @@
     return function (interfaceFunction, parentPropertyGroup) {
       return function (val) {
         val = val === undefined ? 1 : val;
-
         if (val <= 0) {
           return interfaceFunction;
         }
-
         return parentPropertyGroup(val - 1);
       };
     };
@@ -18206,17 +15460,13 @@
       var interfaceFunction = {
         _name: propertyName
       };
-
       function _propertyGroup(val) {
         val = val === undefined ? 1 : val;
-
         if (val <= 0) {
           return interfaceFunction;
         }
-
         return propertyGroup(val - 1);
       }
-
       return _propertyGroup;
     };
   }();
@@ -18225,35 +15475,27 @@
     var ob = {
       createEffectsInterface: createEffectsInterface
     };
-
     function createEffectsInterface(elem, propertyGroup) {
       if (elem.effectsManager) {
         var effectElements = [];
         var effectsData = elem.data.ef;
         var i;
         var len = elem.effectsManager.effectElements.length;
-
         for (i = 0; i < len; i += 1) {
           effectElements.push(createGroupInterface(effectsData[i], elem.effectsManager.effectElements[i], propertyGroup, elem));
         }
-
         var effects = elem.data.ef || [];
-
         var groupInterface = function groupInterface(name) {
           i = 0;
           len = effects.length;
-
           while (i < len) {
             if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
               return effectElements[i];
             }
-
             i += 1;
           }
-
           return null;
         };
-
         Object.defineProperty(groupInterface, 'numProperties', {
           get: function get() {
             return effects.length;
@@ -18261,37 +15503,28 @@
         });
         return groupInterface;
       }
-
       return null;
     }
-
     function createGroupInterface(data, elements, propertyGroup, elem) {
       function groupInterface(name) {
         var effects = data.ef;
         var i = 0;
         var len = effects.length;
-
         while (i < len) {
           if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
             if (effects[i].ty === 5) {
               return effectElements[i];
             }
-
             return effectElements[i]();
           }
-
           i += 1;
         }
-
         throw new Error();
       }
-
       var _propertyGroup = propertyGroupFactory(groupInterface, propertyGroup);
-
       var effectElements = [];
       var i;
       var len = data.ef.length;
-
       for (i = 0; i < len; i += 1) {
         if (data.ef[i].ty === 5) {
           effectElements.push(createGroupInterface(data.ef[i], elements.effectElements[i], elements.effectElements[i].propertyGroup, elem));
@@ -18299,7 +15532,6 @@
           effectElements.push(createValueInterface(elements.effectElements[i], data.ef[i].ty, elem, _propertyGroup));
         }
       }
-
       if (data.mn === 'ADBE Color Control') {
         Object.defineProperty(groupInterface, 'color', {
           get: function get() {
@@ -18307,7 +15539,6 @@
           }
         });
       }
-
       Object.defineProperties(groupInterface, {
         numProperties: {
           get: function get() {
@@ -18325,42 +15556,32 @@
       groupInterface.active = groupInterface.enabled;
       return groupInterface;
     }
-
     function createValueInterface(element, type, elem, propertyGroup) {
       var expressionProperty = ExpressionPropertyInterface(element.p);
-
       function interfaceFunction() {
         if (type === 10) {
           return elem.comp.compInterface(element.p.v);
         }
-
         return expressionProperty();
       }
-
       if (element.p.setGroupProperty) {
         element.p.setGroupProperty(PropertyInterface('', propertyGroup));
       }
-
       return interfaceFunction;
     }
-
     return ob;
   }();
 
   var ShapePathInterface = function () {
     return function pathInterfaceFactory(shape, view, propertyGroup) {
       var prop = view.sh;
-
       function interfaceFunction(val) {
         if (val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2) {
           return interfaceFunction.path;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       prop.setGroupProperty(PropertyInterface('Path', _propertyGroup));
       Object.defineProperties(interfaceFunction, {
         path: {
@@ -18368,7 +15589,6 @@
             if (prop.k) {
               prop.getValue();
             }
-
             return prop;
           }
         },
@@ -18377,7 +15597,6 @@
             if (prop.k) {
               prop.getValue();
             }
-
             return prop;
           }
         },
@@ -18406,7 +15625,6 @@
       var arr = [];
       var i;
       var len = shapes ? shapes.length : 0;
-
       for (i = 0; i < len; i += 1) {
         if (shapes[i].ty === 'gr') {
           arr.push(groupInterfaceFactory(shapes[i], view[i], propertyGroup));
@@ -18416,7 +15634,8 @@
           arr.push(strokeInterfaceFactory(shapes[i], view[i], propertyGroup));
         } else if (shapes[i].ty === 'tm') {
           arr.push(trimInterfaceFactory(shapes[i], view[i], propertyGroup));
-        } else if (shapes[i].ty === 'tr') {// arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
+        } else if (shapes[i].ty === 'tr') {
+          // arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
         } else if (shapes[i].ty === 'el') {
           arr.push(ellipseInterfaceFactory(shapes[i], view[i], propertyGroup));
         } else if (shapes[i].ty === 'sr') {
@@ -18435,32 +15654,24 @@
           arr.push(defaultInterfaceFactory(shapes[i], view[i], propertyGroup));
         }
       }
-
       return arr;
     }
-
     function contentsInterfaceFactory(shape, view, propertyGroup) {
       var interfaces;
-
       var interfaceFunction = function _interfaceFunction(value) {
         var i = 0;
         var len = interfaces.length;
-
         while (i < len) {
           if (interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value) {
             return interfaces[i];
           }
-
           i += 1;
         }
-
         if (typeof value === 'number') {
           return interfaces[value - 1];
         }
-
         return null;
       };
-
       interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
       interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup);
       interfaceFunction.numProperties = interfaces.length;
@@ -18470,7 +15681,6 @@
       interfaceFunction._name = shape.nm;
       return interfaceFunction;
     }
-
     function groupInterfaceFactory(shape, view, propertyGroup) {
       var interfaceFunction = function _interfaceFunction(value) {
         switch (value) {
@@ -18481,12 +15691,10 @@
           // Not necessary for now. Keeping them here in case a new case appears
           // case 'ADBE Vector Transform Group':
           // case 3:
-
           default:
             return interfaceFunction.transform;
         }
       };
-
       interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
       var content = contentsInterfaceFactory(shape, view, interfaceFunction.propertyGroup);
       var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
@@ -18496,28 +15704,24 @@
         get: function get() {
           return shape.nm;
         }
-      }); // interfaceFunction.content = interfaceFunction;
-
+      });
+      // interfaceFunction.content = interfaceFunction;
       interfaceFunction.numProperties = shape.np;
       interfaceFunction.propertyIndex = shape.ix;
       interfaceFunction.nm = shape.nm;
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function fillInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(val) {
         if (val === 'Color' || val === 'color') {
           return interfaceFunction.color;
         }
-
         if (val === 'Opacity' || val === 'opacity') {
           return interfaceFunction.opacity;
         }
-
         return null;
       }
-
       Object.defineProperties(interfaceFunction, {
         color: {
           get: ExpressionPropertyInterface(view.c)
@@ -18536,24 +15740,19 @@
       view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
       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)
@@ -18581,51 +15780,39 @@
       view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
       return interfaceFunction;
     }
-
     function defaultInterfaceFactory() {
       function interfaceFunction() {
         return null;
       }
-
       return interfaceFunction;
     }
-
     function strokeInterfaceFactory(shape, view, propertyGroup) {
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup);
-
       function addPropertyToDashOb(i) {
         Object.defineProperty(dashOb, shape.d[i].nm, {
           get: ExpressionPropertyInterface(view.d.dataProps[i].p)
         });
       }
-
       var i;
       var len = shape.d ? shape.d.length : 0;
       var dashOb = {};
-
       for (i = 0; i < len; i += 1) {
         addPropertyToDashOb(i);
         view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup);
       }
-
       function interfaceFunction(val) {
         if (val === 'Color' || val === 'color') {
           return interfaceFunction.color;
         }
-
         if (val === 'Opacity' || val === 'opacity') {
           return interfaceFunction.opacity;
         }
-
         if (val === 'Stroke Width' || val === 'stroke width') {
           return interfaceFunction.strokeWidth;
         }
-
         return null;
       }
-
       Object.defineProperties(interfaceFunction, {
         color: {
           get: ExpressionPropertyInterface(view.c)
@@ -18653,26 +15840,20 @@
       view.w.setGroupProperty(PropertyInterface('Stroke Width', _propertyGroup));
       return interfaceFunction;
     }
-
     function trimInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(val) {
         if (val === shape.e.ix || val === 'End' || val === 'end') {
           return interfaceFunction.end;
         }
-
         if (val === shape.s.ix) {
           return interfaceFunction.start;
         }
-
         if (val === shape.o.ix) {
           return interfaceFunction.offset;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       interfaceFunction.propertyIndex = shape.ix;
       view.s.setGroupProperty(PropertyInterface('Start', _propertyGroup));
       view.e.setGroupProperty(PropertyInterface('End', _propertyGroup));
@@ -18696,53 +15877,41 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function transformInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.a.ix === value || value === 'Anchor Point') {
           return interfaceFunction.anchorPoint;
         }
-
         if (shape.o.ix === value || value === 'Opacity') {
           return interfaceFunction.opacity;
         }
-
         if (shape.p.ix === value || value === 'Position') {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value || value === 'Rotation' || value === 'ADBE Vector Rotation') {
           return interfaceFunction.rotation;
         }
-
         if (shape.s.ix === value || value === 'Scale') {
           return interfaceFunction.scale;
         }
-
         if (shape.sk && shape.sk.ix === value || value === 'Skew') {
           return interfaceFunction.skew;
         }
-
         if (shape.sa && shape.sa.ix === value || value === 'Skew Axis') {
           return interfaceFunction.skewAxis;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
       view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
       view.transform.mProps.a.setGroupProperty(PropertyInterface('Anchor Point', _propertyGroup));
       view.transform.mProps.s.setGroupProperty(PropertyInterface('Scale', _propertyGroup));
       view.transform.mProps.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
-
       if (view.transform.mProps.sk) {
         view.transform.mProps.sk.setGroupProperty(PropertyInterface('Skew', _propertyGroup));
         view.transform.mProps.sa.setGroupProperty(PropertyInterface('Skew Angle', _propertyGroup));
       }
-
       view.transform.op.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
       Object.defineProperties(interfaceFunction, {
         opacity: {
@@ -18775,22 +15944,17 @@
       interfaceFunction.propertyGroup = propertyGroup;
       return interfaceFunction;
     }
-
     function ellipseInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.s.ix === value) {
           return interfaceFunction.size;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       interfaceFunction.propertyIndex = shape.ix;
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
@@ -18809,42 +15973,32 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function starInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value) {
           return interfaceFunction.rotation;
         }
-
         if (shape.pt.ix === value) {
           return interfaceFunction.points;
         }
-
         if (shape.or.ix === value || value === 'ADBE Vector Star Outer Radius') {
           return interfaceFunction.outerRadius;
         }
-
         if (shape.os.ix === value) {
           return interfaceFunction.outerRoundness;
         }
-
         if (shape.ir && (shape.ir.ix === value || value === 'ADBE Vector Star Inner Radius')) {
           return interfaceFunction.innerRadius;
         }
-
         if (shape.is && shape.is.ix === value) {
           return interfaceFunction.innerRoundness;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       interfaceFunction.propertyIndex = shape.ix;
       prop.or.setGroupProperty(PropertyInterface('Outer Radius', _propertyGroup));
@@ -18852,12 +16006,10 @@
       prop.pt.setGroupProperty(PropertyInterface('Points', _propertyGroup));
       prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
       prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
-
       if (shape.ir) {
         prop.ir.setGroupProperty(PropertyInterface('Inner Radius', _propertyGroup));
         prop.is.setGroupProperty(PropertyInterface('Inner Roundness', _propertyGroup));
       }
-
       Object.defineProperties(interfaceFunction, {
         position: {
           get: ExpressionPropertyInterface(prop.p)
@@ -18887,26 +16039,20 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function rectInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value) {
           return interfaceFunction.roundness;
         }
-
         if (shape.s.ix === value || value === 'Size' || value === 'ADBE Vector Rect Size') {
           return interfaceFunction.size;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       interfaceFunction.propertyIndex = shape.ix;
       prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
@@ -18929,18 +16075,14 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function roundedInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.r.ix === value || value === 'Round Corners 1') {
           return interfaceFunction.radius;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view;
       interfaceFunction.propertyIndex = shape.ix;
       prop.rd.setGroupProperty(PropertyInterface('Radius', _propertyGroup));
@@ -18955,22 +16097,17 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function repeaterInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.c.ix === value || value === 'Copies') {
           return interfaceFunction.copies;
         }
-
         if (shape.o.ix === value || value === 'Offset') {
           return interfaceFunction.offset;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view;
       interfaceFunction.propertyIndex = shape.ix;
       prop.c.setGroupProperty(PropertyInterface('Copies', _propertyGroup));
@@ -18989,39 +16126,29 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     return function (shapes, view, propertyGroup) {
       var interfaces;
-
       function _interfaceFunction(value) {
         if (typeof value === 'number') {
           value = value === undefined ? 1 : value;
-
           if (value === 0) {
             return propertyGroup;
           }
-
           return interfaces[value - 1];
         }
-
         var i = 0;
         var len = interfaces.length;
-
         while (i < len) {
           if (interfaces[i]._name === value) {
             return interfaces[i];
           }
-
           i += 1;
         }
-
         return null;
       }
-
       function parentGroupWrapper() {
         return propertyGroup;
       }
-
       _interfaceFunction.propertyGroup = propertyGroupFactory(_interfaceFunction, parentGroupWrapper);
       interfaces = iterateElements(shapes, view, _interfaceFunction.propertyGroup);
       _interfaceFunction.numProperties = interfaces.length;
@@ -19033,28 +16160,22 @@
   var TextExpressionInterface = function () {
     return function (elem) {
       var _sourceText;
-
       function _thisLayerFunction(name) {
         switch (name) {
           case 'ADBE Text Document':
             return _thisLayerFunction.sourceText;
-
           default:
             return null;
         }
       }
-
       Object.defineProperty(_thisLayerFunction, 'sourceText', {
         get: function get() {
           elem.textProperty.getValue();
           var stringValue = elem.textProperty.currentData.t;
-
           if (!_sourceText || stringValue !== _sourceText.value) {
             _sourceText = new String(stringValue); // eslint-disable-line no-new-wrappers
             // If stringValue is an empty string, eval returns undefined, so it has to be returned as a String primitive
-
             _sourceText.value = stringValue || new String(stringValue); // eslint-disable-line no-new-wrappers
-
             Object.defineProperty(_sourceText, 'style', {
               get: function get() {
                 return {
@@ -19063,7 +16184,6 @@
               }
             });
           }
-
           return _sourceText;
         }
       });
@@ -19071,73 +16191,56 @@
     };
   }();
 
-  function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
-
+  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
   var FootageInterface = function () {
     var outlineInterfaceFactory = function outlineInterfaceFactory(elem) {
       var currentPropertyName = '';
       var currentProperty = elem.getFootageData();
-
       function init() {
         currentPropertyName = '';
         currentProperty = elem.getFootageData();
         return searchProperty;
       }
-
       function searchProperty(value) {
         if (currentProperty[value]) {
           currentPropertyName = value;
           currentProperty = currentProperty[value];
-
           if (_typeof(currentProperty) === 'object') {
             return searchProperty;
           }
-
           return currentProperty;
         }
-
         var propertyNameIndex = value.indexOf(currentPropertyName);
-
         if (propertyNameIndex !== -1) {
           var index = parseInt(value.substr(propertyNameIndex + currentPropertyName.length), 10);
           currentProperty = currentProperty[index];
-
           if (_typeof(currentProperty) === 'object') {
             return searchProperty;
           }
-
           return currentProperty;
         }
-
         return '';
       }
-
       return init;
     };
-
     var dataInterfaceFactory = function dataInterfaceFactory(elem) {
       function interfaceFunction(value) {
         if (value === 'Outline') {
           return interfaceFunction.outlineInterface();
         }
-
         return null;
       }
-
       interfaceFunction._name = 'Outline';
       interfaceFunction.outlineInterface = outlineInterfaceFactory(elem);
       return interfaceFunction;
     };
-
     return function (elem) {
       function _interfaceFunction(value) {
         if (value === 'Data') {
           return _interfaceFunction.dataInterface;
         }
-
         return null;
       }
-
       _interfaceFunction._name = 'Data';
       _interfaceFunction.dataInterface = dataInterfaceFactory(elem);
       return _interfaceFunction;
@@ -19152,7 +16255,6 @@
     text: TextExpressionInterface,
     footage: FootageInterface
   };
-
   function getInterface(type) {
     return interfaces[type] || null;
   }
@@ -19166,56 +16268,44 @@
         prop.effectsSequence.push(prop.initiateExpression(elem, data, prop).bind(prop));
       }
     }
-
     function getValueAtTime(frameNum) {
       frameNum *= this.elem.globalData.frameRate;
       frameNum -= this.offsetTime;
-
       if (frameNum !== this._cachingAtTime.lastFrame) {
         this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0;
         this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime);
         this._cachingAtTime.lastFrame = frameNum;
       }
-
       return this._cachingAtTime.value;
     }
-
     function getSpeedAtTime(frameNum) {
       var delta = -0.01;
       var v1 = this.getValueAtTime(frameNum);
       var v2 = this.getValueAtTime(frameNum + delta);
       var speed = 0;
-
       if (v1.length) {
         var i;
-
         for (i = 0; i < v1.length; i += 1) {
           speed += Math.pow(v2[i] - v1[i], 2);
         }
-
         speed = Math.sqrt(speed) * 100;
       } else {
         speed = 0;
       }
-
       return speed;
     }
-
     function getVelocityAtTime(frameNum) {
       if (this.vel !== undefined) {
         return this.vel;
       }
-
-      var delta = -0.001; // frameNum += this.elem.data.st;
-
+      var delta = -0.001;
+      // frameNum += this.elem.data.st;
       var v1 = this.getValueAtTime(frameNum);
       var v2 = this.getValueAtTime(frameNum + delta);
       var velocity;
-
       if (v1.length) {
         velocity = createTypedArray('float32', v1.length);
         var i;
-
         for (i = 0; i < v1.length; i += 1) {
           // removing frameRate
           // if needed, don't add it here
@@ -19225,18 +16315,14 @@
       } else {
         velocity = (v2 - v1) / delta;
       }
-
       return velocity;
     }
-
     function getStaticValueAtTime() {
       return this.pv;
     }
-
     function setGroupProperty(propertyGroup) {
       this.propertyGroup = propertyGroup;
     }
-
     return {
       searchExpressions: searchExpressions,
       getSpeedAtTime: getSpeedAtTime,
@@ -19252,24 +16338,19 @@
       if (!this.k || !this.keyframes) {
         return this.pv;
       }
-
       type = type ? type.toLowerCase() : '';
       var currentFrame = this.comp.renderedFrame;
       var keyframes = this.keyframes;
       var lastKeyFrame = keyframes[keyframes.length - 1].t;
-
       if (currentFrame <= lastKeyFrame) {
         return this.pv;
       }
-
       var cycleDuration;
       var firstKeyFrame;
-
       if (!durationFlag) {
         if (!duration || duration > keyframes.length - 1) {
           duration = keyframes.length - 1;
         }
-
         firstKeyFrame = keyframes[keyframes.length - 1 - duration].t;
         cycleDuration = lastKeyFrame - firstKeyFrame;
       } else {
@@ -19278,17 +16359,13 @@
         } else {
           cycleDuration = Math.abs(lastKeyFrame - this.elem.comp.globalData.frameRate * duration);
         }
-
         firstKeyFrame = lastKeyFrame - cycleDuration;
       }
-
       var i;
       var len;
       var ret;
-
       if (type === 'pingpong') {
         var iterations = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
-
         if (iterations % 2 !== 0) {
           return this.getValueAtTime((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
         }
@@ -19296,64 +16373,48 @@
         var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
         var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
-
         var repeats = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
-
         if (this.pv.length) {
           ret = new Array(initV.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = (endV[i] - initV[i]) * repeats + current[i];
           }
-
           return ret;
         }
-
         return (endV - initV) * repeats + current;
       } else if (type === 'continue') {
         var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0);
-
         if (this.pv.length) {
           ret = new Array(lastValue.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = lastValue[i] + (lastValue[i] - nextLastValue[i]) * ((currentFrame - lastKeyFrame) / this.comp.globalData.frameRate) / 0.0005; // eslint-disable-line
           }
-
           return ret;
         }
-
         return lastValue + (lastValue - nextLastValue) * ((currentFrame - lastKeyFrame) / 0.001);
       }
-
       return this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
     }
-
     function loopIn(type, duration, durationFlag) {
       if (!this.k) {
         return this.pv;
       }
-
       type = type ? type.toLowerCase() : '';
       var currentFrame = this.comp.renderedFrame;
       var keyframes = this.keyframes;
       var firstKeyFrame = keyframes[0].t;
-
       if (currentFrame >= firstKeyFrame) {
         return this.pv;
       }
-
       var cycleDuration;
       var lastKeyFrame;
-
       if (!durationFlag) {
         if (!duration || duration > keyframes.length - 1) {
           duration = keyframes.length - 1;
         }
-
         lastKeyFrame = keyframes[duration].t;
         cycleDuration = lastKeyFrame - firstKeyFrame;
       } else {
@@ -19362,17 +16423,13 @@
         } else {
           cycleDuration = Math.abs(this.elem.comp.globalData.frameRate * duration);
         }
-
         lastKeyFrame = firstKeyFrame + cycleDuration;
       }
-
       var i;
       var len;
       var ret;
-
       if (type === 'pingpong') {
         var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration);
-
         if (iterations % 2 === 0) {
           return this.getValueAtTime(((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
         }
@@ -19381,52 +16438,39 @@
         var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var current = this.getValueAtTime((cycleDuration - (firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0);
         var repeats = Math.floor((firstKeyFrame - currentFrame) / cycleDuration) + 1;
-
         if (this.pv.length) {
           ret = new Array(initV.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = current[i] - (endV[i] - initV[i]) * repeats;
           }
-
           return ret;
         }
-
         return current - (endV - initV) * repeats;
       } else if (type === 'continue') {
         var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
         var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0);
-
         if (this.pv.length) {
           ret = new Array(firstValue.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = firstValue[i] + (firstValue[i] - nextFirstValue[i]) * (firstKeyFrame - currentFrame) / 0.001;
           }
-
           return ret;
         }
-
         return firstValue + (firstValue - nextFirstValue) * (firstKeyFrame - currentFrame) / 0.001;
       }
-
       return this.getValueAtTime((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
     }
-
     function smooth(width, samples) {
       if (!this.k) {
         return this.pv;
       }
-
       width = (width || 0.4) * 0.5;
       samples = Math.floor(samples || 5);
-
       if (samples <= 1) {
         return this.pv;
       }
-
       var currentTime = this.comp.renderedFrame / this.comp.globalData.frameRate;
       var initFrame = currentTime - width;
       var endFrame = currentTime + width;
@@ -19434,18 +16478,14 @@
       var i = 0;
       var j = 0;
       var value;
-
       if (this.pv.length) {
         value = createTypedArray('float32', this.pv.length);
       } else {
         value = 0;
       }
-
       var sampleValue;
-
       while (i < samples) {
         sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency);
-
         if (this.pv.length) {
           for (j = 0; j < this.pv.length; j += 1) {
             value[j] += sampleValue[j];
@@ -19453,10 +16493,8 @@
         } else {
           value += sampleValue;
         }
-
         i += 1;
       }
-
       if (this.pv.length) {
         for (j = 0; j < this.pv.length; j += 1) {
           value[j] /= samples;
@@ -19464,37 +16502,30 @@
       } else {
         value /= samples;
       }
-
       return value;
     }
-
     function getTransformValueAtTime(time) {
       if (!this._transformCachingAtTime) {
         this._transformCachingAtTime = {
           v: new Matrix()
         };
-      } /// /
-
-
+      }
+      /// /
       var matrix = this._transformCachingAtTime.v;
       matrix.cloneFromProps(this.pre.props);
-
       if (this.appliedTransformations < 1) {
         var anchor = this.a.getValueAtTime(time);
         matrix.translate(-anchor[0] * this.a.mult, -anchor[1] * this.a.mult, anchor[2] * this.a.mult);
       }
-
       if (this.appliedTransformations < 2) {
         var scale = this.s.getValueAtTime(time);
         matrix.scale(scale[0] * this.s.mult, scale[1] * this.s.mult, scale[2] * this.s.mult);
       }
-
       if (this.sk && this.appliedTransformations < 3) {
         var skew = this.sk.getValueAtTime(time);
         var skewAxis = this.sa.getValueAtTime(time);
         matrix.skewFromAxis(-skew * this.sk.mult, skewAxis * this.sa.mult);
       }
-
       if (this.r && this.appliedTransformations < 4) {
         var rotation = this.r.getValueAtTime(time);
         matrix.rotate(-rotation * this.r.mult);
@@ -19505,11 +16536,9 @@
         var orientation = this.or.getValueAtTime(time);
         matrix.rotateZ(-rotationZ * this.rz.mult).rotateY(rotationY * this.ry.mult).rotateX(rotationX * this.rx.mult).rotateZ(-orientation[2] * this.or.mult).rotateY(orientation[1] * this.or.mult).rotateX(orientation[0] * this.or.mult);
       }
-
       if (this.data.p && this.data.p.s) {
         var positionX = this.px.getValueAtTime(time);
         var positionY = this.py.getValueAtTime(time);
-
         if (this.data.p.z) {
           var positionZ = this.pz.getValueAtTime(time);
           matrix.translate(positionX * this.px.mult, positionY * this.py.mult, -positionZ * this.pz.mult);
@@ -19520,42 +16549,34 @@
         var position = this.p.getValueAtTime(time);
         matrix.translate(position[0] * this.p.mult, position[1] * this.p.mult, -position[2] * this.p.mult);
       }
-
-      return matrix; /// /
+      return matrix;
+      /// /
     }
-
     function getTransformStaticValueAtTime() {
       return this.v.clone(new Matrix());
     }
-
     var getTransformProperty = TransformPropertyFactory.getTransformProperty;
-
     TransformPropertyFactory.getTransformProperty = function (elem, data, container) {
       var prop = getTransformProperty(elem, data, container);
-
       if (prop.dynamicProperties.length) {
         prop.getValueAtTime = getTransformValueAtTime.bind(prop);
       } else {
         prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop);
       }
-
       prop.setGroupProperty = expressionHelpers.setGroupProperty;
       return prop;
     };
-
     var propertyGetProp = PropertyFactory.getProp;
-
     PropertyFactory.getProp = function (elem, data, type, mult, container) {
-      var prop = propertyGetProp(elem, data, type, mult, container); // prop.getVelocityAtTime = getVelocityAtTime;
+      var prop = propertyGetProp(elem, data, type, mult, container);
+      // prop.getVelocityAtTime = getVelocityAtTime;
       // prop.loopOut = loopOut;
       // prop.loopIn = loopIn;
-
       if (prop.kf) {
         prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop);
       } else {
         prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop);
       }
-
       prop.setGroupProperty = expressionHelpers.setGroupProperty;
       prop.loopOut = loopOut;
       prop.loopIn = loopIn;
@@ -19565,25 +16586,20 @@
       prop.numKeys = data.a === 1 ? data.k.length : 0;
       prop.propertyIndex = data.ix;
       var value = 0;
-
       if (type !== 0) {
         value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length);
       }
-
       prop._cachingAtTime = {
         lastFrame: initialDefaultFrame,
         lastIndex: 0,
         value: value
       };
       expressionHelpers.searchExpressions(elem, data, prop);
-
       if (prop.k) {
         container.addDynamicProperty(prop);
       }
-
       return prop;
     };
-
     function getShapeValueAtTime(frameNum) {
       // For now this caching object is created only when needed instead of creating it when the shape is initialized.
       if (!this._cachingAtTime) {
@@ -19593,42 +16609,32 @@
           lastTime: initialDefaultFrame
         };
       }
-
       frameNum *= this.elem.globalData.frameRate;
       frameNum -= this.offsetTime;
-
       if (frameNum !== this._cachingAtTime.lastTime) {
         this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0;
         this._cachingAtTime.lastTime = frameNum;
         this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime);
       }
-
       return this._cachingAtTime.shapeValue;
     }
-
     var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction();
     var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction();
-
     function ShapeExpressions() {}
-
     ShapeExpressions.prototype = {
       vertices: function vertices(prop, time) {
         if (this.k) {
           this.getValue();
         }
-
         var shapePath = this.v;
-
         if (time !== undefined) {
           shapePath = this.getValueAtTime(time, 0);
         }
-
         var i;
         var len = shapePath._length;
         var vertices = shapePath[prop];
         var points = shapePath.v;
         var arr = createSizedArray(len);
-
         for (i = 0; i < len; i += 1) {
           if (prop === 'i' || prop === 'o') {
             arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]];
@@ -19636,7 +16642,6 @@
             arr[i] = [vertices[i][0], vertices[i][1]];
           }
         }
-
         return arr;
       },
       points: function points(time) {
@@ -19653,15 +16658,12 @@
       },
       pointOnPath: function pointOnPath(perc, time) {
         var shapePath = this.v;
-
         if (time !== undefined) {
           shapePath = this.getValueAtTime(time, 0);
         }
-
         if (!this._segmentsLength) {
           this._segmentsLength = bez.getSegmentsLength(shapePath);
         }
-
         var segmentsLength = this._segmentsLength;
         var lengths = segmentsLength.lengths;
         var lengthPos = segmentsLength.totalLength * perc;
@@ -19669,7 +16671,6 @@
         var len = lengths.length;
         var accumulatedLength = 0;
         var pt;
-
         while (i < len) {
           if (accumulatedLength + lengths[i].addedLength > lengthPos) {
             var initIndex = i;
@@ -19680,14 +16681,11 @@
           } else {
             accumulatedLength += lengths[i].addedLength;
           }
-
           i += 1;
         }
-
         if (!pt) {
           pt = shapePath.c ? [shapePath.v[0][0], shapePath.v[0][1]] : [shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1]];
         }
-
         return pt;
       },
       vectorOnPath: function vectorOnPath(perc, time, vectorType) {
@@ -19699,17 +16697,14 @@
           // eslint-disable-line eqeqeq
           perc = 0.999;
         }
-
         var pt1 = this.pointOnPath(perc, time);
         var pt2 = this.pointOnPath(perc + 0.001, time);
         var xLength = pt2[0] - pt1[0];
         var yLength = pt2[1] - pt1[1];
         var magnitude = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2));
-
         if (magnitude === 0) {
           return [0, 0];
         }
-
         var unitVector = vectorType === 'tangent' ? [xLength / magnitude, yLength / magnitude] : [-yLength / magnitude, xLength / magnitude];
         return unitVector;
       },
@@ -19727,26 +16722,21 @@
     KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime;
     KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression;
     var propertyGetShapeProp = ShapePropertyFactory.getShapeProp;
-
     ShapePropertyFactory.getShapeProp = function (elem, data, type, arr, trims) {
       var prop = propertyGetShapeProp(elem, data, type, arr, trims);
       prop.propertyIndex = data.ix;
       prop.lock = false;
-
       if (type === 3) {
         expressionHelpers.searchExpressions(elem, data.pt, prop);
       } else if (type === 4) {
         expressionHelpers.searchExpressions(elem, data.ks, prop);
       }
-
       if (prop.k) {
         elem.addDynamicProperty(prop);
       }
-
       return prop;
     };
   }
-
   function initialize$1() {
     addPropertyDecorator();
   }
@@ -19758,13 +16748,10 @@
         this.addEffect(this.getExpressionValue.bind(this));
         return true;
       }
-
       return null;
     }
-
     TextProperty.prototype.getExpressionValue = function (currentValue, text) {
       var newValue = this.calculateExpression(text);
-
       if (currentValue.t !== newValue) {
         var newData = {};
         this.copyData(newData, currentValue);
@@ -19772,46 +16759,38 @@
         newData.__complete = false;
         return newData;
       }
-
       return currentValue;
     };
-
     TextProperty.prototype.searchProperty = function () {
       var isKeyframed = this.searchKeyframes();
       var hasExpressions = this.searchExpressions();
       this.kf = isKeyframed || hasExpressions;
       return this.kf;
     };
-
     TextProperty.prototype.searchExpressions = searchExpressions;
   }
-
   function initialize() {
     addDecorator();
   }
 
   function SVGComposableEffect() {}
-
   SVGComposableEffect.prototype = {
     createMergeNode: function createMergeNode(resultId, ins) {
       var feMerge = createNS('feMerge');
       feMerge.setAttribute('result', resultId);
       var feMergeNode;
       var i;
-
       for (i = 0; i < ins.length; i += 1) {
         feMergeNode = createNS('feMergeNode');
         feMergeNode.setAttribute('in', ins[i]);
         feMerge.appendChild(feMergeNode);
         feMerge.appendChild(feMergeNode);
       }
-
       return feMerge;
     }
   };
 
   var linearFilterValue = '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0';
-
   function SVGTintFilter(filter, filterManager, elem, id, source) {
     this.filterManager = filterManager;
     var feColorMatrix = createNS('feColorMatrix');
@@ -19831,9 +16810,7 @@
     var feMerge = this.createMergeNode(id, [source, id + '_tint_1', id + '_tint_2']);
     filter.appendChild(feMerge);
   }
-
   extendPrototype([SVGComposableEffect], SVGTintFilter);
-
   SVGTintFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var colorBlack = this.filterManager.effectElements[0].p.v;
@@ -19854,7 +16831,6 @@
     filter.appendChild(feColorMatrix);
     this.matrixFilter = feColorMatrix;
   }
-
   SVGFillFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var color = this.filterManager.effectElements[2].p.v;
@@ -19869,14 +16845,12 @@
     this.elem = elem;
     this.paths = [];
   }
-
   SVGStrokeEffect.prototype.initialize = function () {
     var elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
     var path;
     var groupPath;
     var i;
     var len;
-
     if (this.filterManager.effectElements[1].p.v === 1) {
       len = this.elem.maskManager.masksProperties.length;
       i = 0;
@@ -19884,12 +16858,10 @@
       i = this.filterManager.effectElements[0].p.v - 1;
       len = i + 1;
     }
-
     groupPath = createNS('g');
     groupPath.setAttribute('fill', 'none');
     groupPath.setAttribute('stroke-linecap', 'round');
     groupPath.setAttribute('stroke-dashoffset', 1);
-
     for (i; i < len; i += 1) {
       path = createNS('path');
       groupPath.appendChild(path);
@@ -19898,7 +16870,6 @@
         m: i
       });
     }
-
     if (this.filterManager.effectElements[10].p.v === 3) {
       var mask = createNS('mask');
       var id = createElementID();
@@ -19908,54 +16879,43 @@
       this.elem.globalData.defs.appendChild(mask);
       var g = createNS('g');
       g.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
-
       while (elemChildren[0]) {
         g.appendChild(elemChildren[0]);
       }
-
       this.elem.layerElement.appendChild(g);
       this.masker = mask;
       groupPath.setAttribute('stroke', '#fff');
     } else if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
       if (this.filterManager.effectElements[10].p.v === 2) {
         elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
-
         while (elemChildren.length) {
           this.elem.layerElement.removeChild(elemChildren[0]);
         }
       }
-
       this.elem.layerElement.appendChild(groupPath);
       this.elem.layerElement.removeAttribute('mask');
       groupPath.setAttribute('stroke', '#fff');
     }
-
     this.initialized = true;
     this.pathMasker = groupPath;
   };
-
   SVGStrokeEffect.prototype.renderFrame = function (forceRender) {
     if (!this.initialized) {
       this.initialize();
     }
-
     var i;
     var len = this.paths.length;
     var mask;
     var path;
-
     for (i = 0; i < len; i += 1) {
       if (this.paths[i].m !== -1) {
         mask = this.elem.maskManager.viewData[this.paths[i].m];
         path = this.paths[i].p;
-
         if (forceRender || this.filterManager._mdf || mask.prop._mdf) {
           path.setAttribute('d', mask.lastPath);
         }
-
         if (forceRender || this.filterManager.effectElements[9].p._mdf || this.filterManager.effectElements[4].p._mdf || this.filterManager.effectElements[7].p._mdf || this.filterManager.effectElements[8].p._mdf || mask.prop._mdf) {
           var dasharrayValue;
-
           if (this.filterManager.effectElements[7].p.v !== 0 || this.filterManager.effectElements[8].p.v !== 100) {
             var s = Math.min(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
             var e = Math.max(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
@@ -19965,29 +16925,23 @@
             var segment = 1 + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
             var units = Math.floor(lineLength / segment);
             var j;
-
             for (j = 0; j < units; j += 1) {
               dasharrayValue += '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01 + ' ';
             }
-
             dasharrayValue += '0 ' + l * 10 + ' 0 0';
           } else {
             dasharrayValue = '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
           }
-
           path.setAttribute('stroke-dasharray', dasharrayValue);
         }
       }
     }
-
     if (forceRender || this.filterManager.effectElements[4].p._mdf) {
       this.pathMasker.setAttribute('stroke-width', this.filterManager.effectElements[4].p.v * 2);
     }
-
     if (forceRender || this.filterManager.effectElements[6].p._mdf) {
       this.pathMasker.setAttribute('opacity', this.filterManager.effectElements[6].p.v);
     }
-
     if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
       if (forceRender || this.filterManager.effectElements[3].p._mdf) {
         var color = this.filterManager.effectElements[3].p.v;
@@ -20021,7 +16975,6 @@
     this.feFuncB = feFuncB;
     filter.appendChild(feComponentTransfer);
   }
-
   SVGTritoneFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var color1 = this.filterManager.effectElements[0].p.v;
@@ -20039,33 +16992,29 @@
   function SVGProLevelsFilter(filter, filterManager, elem, id) {
     this.filterManager = filterManager;
     var effectElements = this.filterManager.effectElements;
-    var feComponentTransfer = createNS('feComponentTransfer'); // Red
+    var feComponentTransfer = createNS('feComponentTransfer');
 
+    // Red
     if (effectElements[10].p.k || effectElements[10].p.v !== 0 || effectElements[11].p.k || effectElements[11].p.v !== 1 || effectElements[12].p.k || effectElements[12].p.v !== 1 || effectElements[13].p.k || effectElements[13].p.v !== 0 || effectElements[14].p.k || effectElements[14].p.v !== 1) {
       this.feFuncR = this.createFeFunc('feFuncR', feComponentTransfer);
-    } // Green
-
-
+    }
+    // Green
     if (effectElements[17].p.k || effectElements[17].p.v !== 0 || effectElements[18].p.k || effectElements[18].p.v !== 1 || effectElements[19].p.k || effectElements[19].p.v !== 1 || effectElements[20].p.k || effectElements[20].p.v !== 0 || effectElements[21].p.k || effectElements[21].p.v !== 1) {
       this.feFuncG = this.createFeFunc('feFuncG', feComponentTransfer);
-    } // Blue
-
-
+    }
+    // Blue
     if (effectElements[24].p.k || effectElements[24].p.v !== 0 || effectElements[25].p.k || effectElements[25].p.v !== 1 || effectElements[26].p.k || effectElements[26].p.v !== 1 || effectElements[27].p.k || effectElements[27].p.v !== 0 || effectElements[28].p.k || effectElements[28].p.v !== 1) {
       this.feFuncB = this.createFeFunc('feFuncB', feComponentTransfer);
-    } // Alpha
-
-
+    }
+    // Alpha
     if (effectElements[31].p.k || effectElements[31].p.v !== 0 || effectElements[32].p.k || effectElements[32].p.v !== 1 || effectElements[33].p.k || effectElements[33].p.v !== 1 || effectElements[34].p.k || effectElements[34].p.v !== 0 || effectElements[35].p.k || effectElements[35].p.v !== 1) {
       this.feFuncA = this.createFeFunc('feFuncA', feComponentTransfer);
-    } // RGB
-
-
+    }
+    // RGB
     if (this.feFuncR || this.feFuncG || this.feFuncB || this.feFuncA) {
       feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
       filter.appendChild(feComponentTransfer);
     }
-
     if (effectElements[3].p.k || effectElements[3].p.v !== 0 || effectElements[4].p.k || effectElements[4].p.v !== 1 || effectElements[5].p.k || effectElements[5].p.v !== 1 || effectElements[6].p.k || effectElements[6].p.v !== 0 || effectElements[7].p.k || effectElements[7].p.v !== 1) {
       feComponentTransfer = createNS('feComponentTransfer');
       feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
@@ -20076,14 +17025,12 @@
       this.feFuncBComposed = this.createFeFunc('feFuncB', feComponentTransfer);
     }
   }
-
   SVGProLevelsFilter.prototype.createFeFunc = function (type, feComponentTransfer) {
     var feFunc = createNS(type);
     feFunc.setAttribute('type', 'table');
     feComponentTransfer.appendChild(feFunc);
     return feFunc;
   };
-
   SVGProLevelsFilter.prototype.getTableValue = function (inputBlack, inputWhite, gamma, outputBlack, outputWhite) {
     var cnt = 0;
     var segments = 256;
@@ -20097,10 +17044,8 @@
     var pos = 0;
     var outputDelta = outputWhite - outputBlack;
     var inputDelta = inputWhite - inputBlack;
-
     while (cnt <= 256) {
       perc = cnt / 256;
-
       if (perc <= min) {
         colorValue = inputDelta < 0 ? outputWhite : outputBlack;
       } else if (perc >= max) {
@@ -20108,42 +17053,34 @@
       } else {
         colorValue = outputBlack + outputDelta * Math.pow((perc - inputBlack) / inputDelta, 1 / gamma);
       }
-
       table[pos] = colorValue;
       pos += 1;
       cnt += 256 / (segments - 1);
     }
-
     return table.join(' ');
   };
-
   SVGProLevelsFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var val;
       var effectElements = this.filterManager.effectElements;
-
       if (this.feFuncRComposed && (forceRender || effectElements[3].p._mdf || effectElements[4].p._mdf || effectElements[5].p._mdf || effectElements[6].p._mdf || effectElements[7].p._mdf)) {
         val = this.getTableValue(effectElements[3].p.v, effectElements[4].p.v, effectElements[5].p.v, effectElements[6].p.v, effectElements[7].p.v);
         this.feFuncRComposed.setAttribute('tableValues', val);
         this.feFuncGComposed.setAttribute('tableValues', val);
         this.feFuncBComposed.setAttribute('tableValues', val);
       }
-
       if (this.feFuncR && (forceRender || effectElements[10].p._mdf || effectElements[11].p._mdf || effectElements[12].p._mdf || effectElements[13].p._mdf || effectElements[14].p._mdf)) {
         val = this.getTableValue(effectElements[10].p.v, effectElements[11].p.v, effectElements[12].p.v, effectElements[13].p.v, effectElements[14].p.v);
         this.feFuncR.setAttribute('tableValues', val);
       }
-
       if (this.feFuncG && (forceRender || effectElements[17].p._mdf || effectElements[18].p._mdf || effectElements[19].p._mdf || effectElements[20].p._mdf || effectElements[21].p._mdf)) {
         val = this.getTableValue(effectElements[17].p.v, effectElements[18].p.v, effectElements[19].p.v, effectElements[20].p.v, effectElements[21].p.v);
         this.feFuncG.setAttribute('tableValues', val);
       }
-
       if (this.feFuncB && (forceRender || effectElements[24].p._mdf || effectElements[25].p._mdf || effectElements[26].p._mdf || effectElements[27].p._mdf || effectElements[28].p._mdf)) {
         val = this.getTableValue(effectElements[24].p.v, effectElements[25].p.v, effectElements[26].p.v, effectElements[27].p.v, effectElements[28].p.v);
         this.feFuncB.setAttribute('tableValues', val);
       }
-
       if (this.feFuncA && (forceRender || effectElements[31].p._mdf || effectElements[32].p._mdf || effectElements[33].p._mdf || effectElements[34].p._mdf || effectElements[35].p._mdf)) {
         val = this.getTableValue(effectElements[31].p.v, effectElements[32].p.v, effectElements[33].p.v, effectElements[34].p.v, effectElements[35].p.v);
         this.feFuncA.setAttribute('tableValues', val);
@@ -20185,26 +17122,22 @@
     feComposite.setAttribute('result', id + '_drop_shadow_4');
     filter.appendChild(feComposite);
     var feMerge = this.createMergeNode(id, [id + '_drop_shadow_4', source]);
-    filter.appendChild(feMerge); //
+    filter.appendChild(feMerge);
+    //
   }
-
   extendPrototype([SVGComposableEffect], SVGDropShadowEffect);
-
   SVGDropShadowEffect.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       if (forceRender || this.filterManager.effectElements[4].p._mdf) {
         this.feGaussianBlur.setAttribute('stdDeviation', this.filterManager.effectElements[4].p.v / 4);
       }
-
       if (forceRender || this.filterManager.effectElements[0].p._mdf) {
         var col = this.filterManager.effectElements[0].p.v;
         this.feFlood.setAttribute('flood-color', rgbToHex(Math.round(col[0] * 255), Math.round(col[1] * 255), Math.round(col[2] * 255)));
       }
-
       if (forceRender || this.filterManager.effectElements[1].p._mdf) {
         this.feFlood.setAttribute('flood-opacity', this.filterManager.effectElements[1].p.v / 255);
       }
-
       if (forceRender || this.filterManager.effectElements[2].p._mdf || this.filterManager.effectElements[3].p._mdf) {
         var distance = this.filterManager.effectElements[3].p.v;
         var angle = (this.filterManager.effectElements[2].p.v - 90) * degToRads;
@@ -20217,7 +17150,6 @@
   };
 
   var _svgMatteSymbols = [];
-
   function SVGMatte3Effect(filterElem, filterManager, elem) {
     this.initialized = false;
     this.filterManager = filterManager;
@@ -20228,66 +17160,50 @@
     elem.matteElement.appendChild(elem.transformedElement);
     elem.baseElement = elem.matteElement;
   }
-
   SVGMatte3Effect.prototype.findSymbol = function (mask) {
     var i = 0;
     var len = _svgMatteSymbols.length;
-
     while (i < len) {
       if (_svgMatteSymbols[i] === mask) {
         return _svgMatteSymbols[i];
       }
-
       i += 1;
     }
-
     return null;
   };
-
   SVGMatte3Effect.prototype.replaceInParent = function (mask, symbolId) {
     var parentNode = mask.layerElement.parentNode;
-
     if (!parentNode) {
       return;
     }
-
     var children = parentNode.children;
     var i = 0;
     var len = children.length;
-
     while (i < len) {
       if (children[i] === mask.layerElement) {
         break;
       }
-
       i += 1;
     }
-
     var nextChild;
-
     if (i <= len - 2) {
       nextChild = children[i + 1];
     }
-
     var useElem = createNS('use');
     useElem.setAttribute('href', '#' + symbolId);
-
     if (nextChild) {
       parentNode.insertBefore(useElem, nextChild);
     } else {
       parentNode.appendChild(useElem);
     }
   };
-
   SVGMatte3Effect.prototype.setElementAsMask = function (elem, mask) {
     if (!this.findSymbol(mask)) {
       var symbolId = createElementID();
       var masker = createNS('mask');
       masker.setAttribute('id', mask.layerId);
       masker.setAttribute('mask-type', 'alpha');
-
       _svgMatteSymbols.push(mask);
-
       var defs = elem.globalData.defs;
       defs.appendChild(masker);
       var symbol = createNS('symbol');
@@ -20301,27 +17217,21 @@
       mask.data.hd = false;
       mask.show();
     }
-
     elem.setMatte(mask.layerId);
   };
-
   SVGMatte3Effect.prototype.initialize = function () {
     var ind = this.filterManager.effectElements[0].p.v;
     var elements = this.elem.comp.elements;
     var i = 0;
     var len = elements.length;
-
     while (i < len) {
       if (elements[i] && elements[i].data.ind === ind) {
         this.setElementAsMask(this.elem, elements[i]);
       }
-
       i += 1;
     }
-
     this.initialized = true;
   };
-
   SVGMatte3Effect.prototype.renderFrame = function () {
     if (!this.initialized) {
       this.initialize();
@@ -20340,36 +17250,34 @@
     filter.appendChild(feGaussianBlur);
     this.feGaussianBlur = feGaussianBlur;
   }
-
   SVGGaussianBlurEffect.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       // Empirical value, matching AE's blur appearance.
       var kBlurrinessToSigma = 0.3;
-      var sigma = this.filterManager.effectElements[0].p.v * kBlurrinessToSigma; // Dimensions mapping:
+      var sigma = this.filterManager.effectElements[0].p.v * kBlurrinessToSigma;
+
+      // Dimensions mapping:
       //
       //   1 -> horizontal & vertical
       //   2 -> horizontal only
       //   3 -> vertical only
       //
-
       var dimensions = this.filterManager.effectElements[1].p.v;
       var sigmaX = dimensions == 3 ? 0 : sigma; // eslint-disable-line eqeqeq
-
       var sigmaY = dimensions == 2 ? 0 : sigma; // eslint-disable-line eqeqeq
 
-      this.feGaussianBlur.setAttribute('stdDeviation', sigmaX + ' ' + sigmaY); // Repeat edges mapping:
+      this.feGaussianBlur.setAttribute('stdDeviation', sigmaX + ' ' + sigmaY);
+
+      // Repeat edges mapping:
       //
       //   0 -> off -> duplicate
       //   1 -> on  -> wrap
-
       var edgeMode = this.filterManager.effectElements[2].p.v == 1 ? 'wrap' : 'duplicate'; // eslint-disable-line eqeqeq
-
       this.feGaussianBlur.setAttribute('edgeMode', edgeMode);
     }
   };
 
   function TransformEffect() {}
-
   TransformEffect.prototype.init = function (effectsManager) {
     this.effectsManager = effectsManager;
     this.type = effectTypes.TRANSFORM_EFFECT;
@@ -20378,11 +17286,9 @@
     this._mdf = false;
     this._opMdf = false;
   };
-
   TransformEffect.prototype.renderFrame = function (forceFrame) {
     this._opMdf = false;
     this._mdf = false;
-
     if (forceFrame || this.effectsManager._mdf) {
       var effectElements = this.effectsManager.effectElements;
       var anchor = effectElements[0].p.v;
@@ -20400,7 +17306,6 @@
       this.matrix.skewFromAxis(-skew * degToRads, (skewAxis + 90) * degToRads);
       this.matrix.translate(position[0], position[1], 0);
       this._mdf = true;
-
       if (this.opacity !== effectElements[8].p.v) {
         this.opacity = effectElements[8].p.v;
         this._opMdf = true;
@@ -20411,31 +17316,33 @@
   function SVGTransformEffect(_, filterManager) {
     this.init(filterManager);
   }
-
   extendPrototype([TransformEffect], SVGTransformEffect);
 
   function CVTransformEffect(effectsManager) {
     this.init(effectsManager);
   }
-
   extendPrototype([TransformEffect], CVTransformEffect);
 
+  // Registering renderers
   registerRenderer('canvas', CanvasRenderer);
   registerRenderer('html', HybridRenderer);
-  registerRenderer('svg', SVGRenderer); // Registering shape modifiers
+  registerRenderer('svg', SVGRenderer);
 
+  // Registering shape modifiers
   ShapeModifiers.registerModifier('tm', TrimModifier);
   ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
   ShapeModifiers.registerModifier('rp', RepeaterModifier);
   ShapeModifiers.registerModifier('rd', RoundCornersModifier);
   ShapeModifiers.registerModifier('zz', ZigZagModifier);
-  ShapeModifiers.registerModifier('op', OffsetPathModifier); // Registering expression plugin
+  ShapeModifiers.registerModifier('op', OffsetPathModifier);
 
+  // Registering expression plugin
   setExpressionsPlugin(Expressions);
   setExpressionInterfaces(getInterface);
   initialize$1();
-  initialize(); // Registering svg effects
+  initialize();
 
+  // Registering svg effects
   registerEffect$1(20, SVGTintFilter, true);
   registerEffect$1(21, SVGFillFilter, true);
   registerEffect$1(22, SVGStrokeEffect, false);
@@ -20450,7 +17357,7 @@
   return lottie;
 
 }));
-
+
 
 
     function addElementToList(element, list) {
@@ -20699,6 +17606,10 @@
       if (animations[payload.id]) {
         animations[payload.id].animation.playSegments(payload.arr, payload.forceFlag);
       }
+    } else if (type === 'resetSegments') {
+      if (animations[payload.id]) {
+        animations[payload.id].animation.resetSegments(payload.forceFlag);
+      }
     } else if (type === 'updateDocumentData') {
       animations[payload.id].animation.updateDocumentData(payload.path, payload.documentData, payload.index);
     }
diff --git a/build/player/lottie_canvas_worker.min.js b/build/player/lottie_canvas_worker.min.js
index 7ad99b4..03cb66c 100644
--- a/build/player/lottie_canvas_worker.min.js
+++ b/build/player/lottie_canvas_worker.min.js
@@ -10,6 +10,6 @@
         root.bodymovin = root.lottie;
     }
 }((self || {}), function(window) {
-	function workerContent(){function extendPrototype(t,e){var i,r,s=t.length;for(i=0;i<s;i+=1)for(var a in r=t[i].prototype)Object.prototype.hasOwnProperty.call(r,a)&&(e.prototype[a]=r[a])}function ProxyElement(t,e){this._state="init",this._isDirty=!1,this._isProxy=!0,this._changedStyles=[],this._changedAttributes=[],this._changedElements=[],this._textContent=null,this.type=t,this.namespace=e,this.children=[],localIdCounter+=1,this.attributes={id:"l_d_"+localIdCounter},this.style=new Style(this)}ProxyElement.prototype={appendChild:function(t){(t.parentNode=this).children.push(t),this._isDirty=!0,this._changedElements.push([t,this.attributes.id])},insertBefore:function(t,e){for(var i=this.children,r=0;r<i.length;r+=1)if(i[r]===e)return i.splice(r,0,t),this._isDirty=!0,void this._changedElements.push([t,this.attributes.id,e.attributes.id]);i.push(e)},setAttribute:function(t,e){this.attributes[t]=e,this._isDirty||(this._isDirty=!0),this._changedAttributes.push(t)},serialize:function(){return{type:this.type,namespace:this.namespace,style:this.style.serialize(),attributes:this.attributes,children:this.children.map(function(t){return t.serialize()}),textContent:this._textContent}},addEventListener:function(t,e){setTimeout(e,1)},setAttributeNS:function(t,e,i){this.attributes[e]=i,this._isDirty||(this._isDirty=!0),this._changedAttributes.push(e)}},Object.defineProperty(ProxyElement.prototype,"textContent",{set:function(t){this._isDirty=!0,this._textContent=t}});var localIdCounter=0,animations={},styleProperties=["width","height","display","transform","opacity","contentVisibility","mix-blend-mode"];function convertArguments(t){var e,i=[],r=t.length;for(e=0;e<r;e+=1)i.push(t[e]);return i}function Style(t){this.element=t}function CanvasContext(t){this.element=t}Style.prototype={serialize:function(){for(var t={},e=0;e<styleProperties.length;e+=1){var i=styleProperties[e],r="_"+i;r in this&&(t[i]=this[r])}return t}},styleProperties.forEach(function(e){Object.defineProperty(Style.prototype,e,{set:function(t){this.element._isDirty||(this.element._isDirty=!0),this.element._changedStyles.push(e),this["_"+e]=t},get:function(){return this["_"+e]}})}),CanvasContext.prototype={createRadialGradient:function(){var t={t:"rGradient",a:convertArguments(arguments),stops:[]};return this.element.instructions.push(t),{addColorStop:function(){t.stops.push(convertArguments(arguments))}}},createLinearGradient:function(){var t={t:"lGradient",a:convertArguments(arguments),stops:[]};return this.element.instructions.push(t),{addColorStop:function(){t.stops.push(convertArguments(arguments))}}}},Object.defineProperties(CanvasContext.prototype,{canvas:{enumerable:!0,get:function(){return this.element}}});var canvasContextMethods=["fillRect","setTransform","drawImage","beginPath","moveTo","save","restore","fillText","setLineDash","clearRect","clip","rect","stroke","fill","closePath","bezierCurveTo","lineTo"];canvasContextMethods.forEach(function(t){CanvasContext.prototype[t]=function(){this.element.instructions.push({t:t,a:convertArguments(arguments)})}});var canvasContextProperties=["globalAlpha","strokeStyle","fillStyle","lineCap","lineJoin","lineWidth","miterLimit","lineDashOffset","globalCompositeOperation"];function CanvasElement(t,e){ProxyElement.call(this,t,e),this.instructions=[],this.width=0,this.height=0,this.context=new CanvasContext(this)}function createElement(t,e){return"canvas"===e?new CanvasElement(e,t):new ProxyElement(e,t)}canvasContextProperties.forEach(function(e){Object.defineProperty(CanvasContext.prototype,e,{set:function(t){this.element.instructions.push({t:e,a:t})}})}),CanvasElement.prototype={getContext:function(){return this.context},resetInstructions:function(){this.instructions.length=0}},extendPrototype([ProxyElement],CanvasElement);var window=self,document={createElementNS:function(t,e){return createElement(t,e)},createElement:function(t){return createElement("",t)},getElementsByTagName:function(){return[]},body:createElement("","body"),_isProxy:!0},lottieInternal=function(){"use strict";var Y,Z;function addElementToList(t,e){e.push(t),t._isDirty=!1,t._changedStyles.length=0,t._changedAttributes.length=0,t._changedElements.length=0,t._textContent=null,t.children.forEach(function(t){addElementToList(t,e)})}function addChangedAttributes(t){for(var e,i=t._changedAttributes,r=[],s=0;s<i.length;s+=1)e=i[s],r.push([e,t.attributes[e]]);return r}function addChangedStyles(t){for(var e,i=t._changedStyles,r=[],s=0;s<i.length;s+=1)e=i[s],r.push([e,t.style[e]]);return r}function addChangedElements(t,e){for(var i,r=t._changedElements,s=[],a=0;a<r.length;a+=1)i=r[a],s.push([i[0].serialize(),i[1],i[2]]),addElementToList(i[0],e);return s}function loadAnimation(a){var e,t,i,r=a.params,n=[];if("svg"===r.renderer)e=document.createElement("div"),r.container=e;else{(i=r.rendererSettings.canvas)||((i=document.createElement("canvas")).width=r.animationData.w,i.height=r.animationData.h);var s=i.getContext("2d");r.rendererSettings.context=s}(t=lottie.loadAnimation(r)).addEventListener("error",function(t){console.log(t)}),t.onError=function(t){console.log("ERRORO",t)},t.addEventListener("_play",function(){self.postMessage({type:"playing",payload:{id:a.id}})}),t.addEventListener("_pause",function(){self.postMessage({type:"paused",payload:{id:a.id}})}),"svg"===r.renderer?(t.addEventListener("DOMLoaded",function(){var t=e.serialize();addElementToList(e,n),self.postMessage({type:"SVGloaded",payload:{id:a.id,tree:t.children[0]}})}),t.addEventListener("drawnFrame",function(t){for(var e,i=[],r=0;r<n.length;r+=1)if((e=n[r])._isDirty){var s={id:e.attributes.id,styles:addChangedStyles(e),attributes:addChangedAttributes(e),elements:addChangedElements(e,n),textContent:e._textContent||void 0};i.push(s),e._isDirty=!1,e._changedAttributes.length=0,e._changedStyles.length=0,e._changedElements.length=0,e._textContent=null}self.postMessage({type:"SVGupdated",payload:{elements:i,id:a.id,currentTime:t.currentTime}})})):i._isProxy&&t.addEventListener("drawnFrame",function(t){self.postMessage({type:"CanvasUpdated",payload:{instructions:i.instructions,id:a.id,currentTime:t.currentTime}}),i.resetInstructions()}),t.addEventListener("DOMLoaded",function(){self.postMessage({type:"DOMLoaded",payload:{id:a.id,totalFrames:t.totalFrames,frameRate:t.frameRate,firstFrame:t.firstFrame,currentFrame:t.currentFrame,playDirection:t.playDirection,isSubframeEnabled:t.isSubframeEnabled,currentRawFrame:t.currentRawFrame,timeCompleted:t.timeCompleted}})}),animations[a.id]={animation:t,events:{}}}return"undefined"!=typeof navigator&&(Y=this,Z=function(){var svgNS="http://www.w3.org/2000/svg",locationHref="",_useWebWorker=!1,initialDefaultFrame=-999999,setWebWorker=function(t){_useWebWorker=!!t},getWebWorker=function(){return _useWebWorker},setLocationHref=function(t){locationHref=t},getLocationHref=function(){return locationHref};function createTag(t){return document.createElement(t)}function extendPrototype(t,e){var i,r,s=t.length;for(i=0;i<s;i+=1)for(var a in r=t[i].prototype)Object.prototype.hasOwnProperty.call(r,a)&&(e.prototype[a]=r[a])}function getDescriptor(t,e){return Object.getOwnPropertyDescriptor(t,e)}function createProxyFunction(t){function e(){}return e.prototype=t,e}var audioControllerFactory=function(){function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].pause()},resume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].resume()},setRate:function(t){var e,i=this.audios.length;for(e=0;e<i;e+=1)this.audios[e].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}}(),createTypedArray=function(){function i(t,e){var i,r=0,s=[];switch(t){case"int16":case"uint8c":i=1;break;default:i=1.1}for(r=0;r<e;r+=1)s.push(i);return s}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(t,e){return"float32"===t?new Float32Array(e):"int16"===t?new Int16Array(e):"uint8c"===t?new Uint8ClampedArray(e):i(t,e)}:i}();function createSizedArray(t){return Array.apply(null,{length:t})}function _typeof$6(t){return(_typeof$6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var subframeEnabled=!0,expressionsPlugin=null,expressionsInterfaces=null,idPrefix$1="",isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),_shouldRoundValues=!1,bmPow=Math.pow,bmSqrt=Math.sqrt,bmFloor=Math.floor,bmMax=Math.max,bmMin=Math.min,BMMath={};function ProjectInterface$1(){return{}}!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],i=e.length;for(t=0;t<i;t+=1)BMMath[e[t]]=Math[e[t]]}(),BMMath.random=Math.random,BMMath.abs=function(t){if("object"===_typeof$6(t)&&t.length){var e,i=createSizedArray(t.length),r=t.length;for(e=0;e<r;e+=1)i[e]=Math.abs(t[e]);return i}return Math.abs(t)};var defaultCurveSegments=150,degToRads=Math.PI/180,roundCorner=.5519;function roundValues(t){_shouldRoundValues=!!t}function bmRnd(t){return _shouldRoundValues?Math.round(t):t}function styleDiv(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin="0 0",t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility="visible",t.style.webkitBackfaceVisibility="visible",t.style.transformStyle="preserve-3d",t.style.webkitTransformStyle="preserve-3d",t.style.mozTransformStyle="preserve-3d"}function BMEnterFrameEvent(t,e,i,r){this.type=t,this.currentTime=e,this.totalTime=i,this.direction=r<0?-1:1}function BMCompleteEvent(t,e){this.type=t,this.direction=e<0?-1:1}function BMCompleteLoopEvent(t,e,i,r){this.type=t,this.currentLoop=i,this.totalLoops=e,this.direction=r<0?-1:1}function BMSegmentStartEvent(t,e,i){this.type=t,this.firstFrame=e,this.totalFrames=i}function BMDestroyEvent(t,e){this.type=t,this.target=e}function BMRenderFrameErrorEvent(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function BMConfigErrorEvent(t){this.type="configError",this.nativeError=t}function BMAnimationConfigErrorEvent(t,e){this.type=t,this.nativeError=e}var createElementID=(Nb=0,function(){return idPrefix$1+"__lottie_element_"+(Nb+=1)}),Nb;function HSVtoRGB(t,e,i){var r,s,a,n,o,h,l,p;switch(h=i*(1-e),l=i*(1-(o=6*t-(n=Math.floor(6*t)))*e),p=i*(1-(1-o)*e),n%6){case 0:r=i,s=p,a=h;break;case 1:r=l,s=i,a=h;break;case 2:r=h,s=i,a=p;break;case 3:r=h,s=l,a=i;break;case 4:r=p,s=h,a=i;break;case 5:r=i,s=h,a=l}return[r,s,a]}function RGBtoHSV(t,e,i){var r,s=Math.max(t,e,i),a=Math.min(t,e,i),n=s-a,o=0===s?0:n/s,h=s/255;switch(s){case a:r=0;break;case t:r=e-i+n*(e<i?6:0),r/=6*n;break;case e:r=i-t+2*n,r/=6*n;break;case i:r=t-e+4*n,r/=6*n}return[r,o,h]}function addSaturationToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[1]+=e,1<i[1]?i[1]=1:i[1]<=0&&(i[1]=0),HSVtoRGB(i[0],i[1],i[2])}function addBrightnessToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[2]+=e,1<i[2]?i[2]=1:i[2]<0&&(i[2]=0),HSVtoRGB(i[0],i[1],i[2])}function addHueToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[0]+=e/360,1<i[0]?i[0]-=1:i[0]<0&&(i[0]+=1),HSVtoRGB(i[0],i[1],i[2])}var rgbToHex=function(){var t,e,r=[];for(t=0;t<256;t+=1)e=t.toString(16),r[t]=1===e.length?"0"+e:e;return function(t,e,i){return t<0&&(t=0),e<0&&(e=0),i<0&&(i=0),"#"+r[t]+r[e]+r[i]}}(),setSubframeEnabled=function(t){subframeEnabled=!!t},getSubframeEnabled=function(){return subframeEnabled},setExpressionsPlugin=function(t){expressionsPlugin=t},getExpressionsPlugin=function(){return expressionsPlugin},setExpressionInterfaces=function(t){expressionsInterfaces=t},getExpressionInterfaces=function(){return expressionsInterfaces},setDefaultCurveSegments=function(t){defaultCurveSegments=t},getDefaultCurveSegments=function(){return defaultCurveSegments},setIdPrefix=function(t){idPrefix$1=t},getIdPrefix=function(){return idPrefix$1};function createNS(t){return document.createElementNS(svgNS,t)}function _typeof$5(t){return(_typeof$5="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var dataManager=function(){var r,s,a=1,n=[],o={onmessage:function(){},postMessage:function(t){r({data:t})}},i={postMessage:function(t){o.onmessage({data:t})}};function h(){s||((s=function(t){if(window.Worker&&window.Blob&&getWebWorker()){var e=new Blob(["var _workerSelf = self; self.onmessage = ",t.toString()],{type:"text/javascript"}),i=URL.createObjectURL(e);return new Worker(i)}return r=t,o}(function(e){if(i.dataManager||(i.dataManager=function(){function f(t,e){var i,r,s,a,n,o,h,l=t.length;for(r=0;r<l;r+=1)if("ks"in(i=t[r])&&!i.completed){if(i.completed=!0,i.hasMask){var p=i.masksProperties;for(a=p.length,s=0;s<a;s+=1)if(p[s].pt.k.i)d(p[s].pt.k);else for(o=p[s].pt.k.length,n=0;n<o;n+=1)p[s].pt.k[n].s&&d(p[s].pt.k[n].s[0]),p[s].pt.k[n].e&&d(p[s].pt.k[n].e[0])}0===i.ty?(i.layers=m(i.refId,e),f(i.layers,e)):4===i.ty?c(i.shapes):5===i.ty&&(0===(h=i).t.a.length&&h.t.p)}}function m(t,e){var i=function(t,e){for(var i=0,r=e.length;i<r;){if(e[i].id===t)return e[i];i+=1}return null}(t,e);return i?i.layers.__used?JSON.parse(JSON.stringify(i.layers)):(i.layers.__used=!0,i.layers):null}function c(t){var e,i,r;for(e=t.length-1;0<=e;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)d(t[e].ks.k);else for(r=t[e].ks.k.length,i=0;i<r;i+=1)t[e].ks.k[i].s&&d(t[e].ks.k[i].s[0]),t[e].ks.k[i].e&&d(t[e].ks.k[i].e[0]);else"gr"===t[e].ty&&c(t[e].it)}function d(t){var e,i=t.i.length;for(e=0;e<i;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function n(t,e){var i=e?e.split("."):[100,100,100];return t[0]>i[0]||!(i[0]>t[0])&&(t[1]>i[1]||!(i[1]>t[1])&&(t[2]>i[2]||!(i[2]>t[2])&&null))}var s,e=function(){var r=[4,4,14];function s(t){var e,i,r,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(i=t[e],r=i.t.d,i.t.d={k:[{s:r,t:0}]})}return function(t){if(n(r,t.v)&&(s(t.layers),t.assets)){var e,i=t.assets.length;for(e=0;e<i;e+=1)t.assets[e].layers&&s(t.assets[e].layers)}}}(),i=(s=[4,7,99],function(t){if(t.chars&&!n(s,t.v)){var e,i=t.chars.length;for(e=0;e<i;e+=1){var r=t.chars[e];r.data&&r.data.shapes&&(c(r.data.shapes),r.data.ip=0,r.data.op=99999,r.data.st=0,r.data.sr=1,r.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[e].t||(r.data.shapes.push({ty:"no"}),r.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}}}),r=function(){var r=[5,7,15];function s(t){var e,i,r,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(i=t[e],r=void 0,"number"==typeof(r=i.t.p).a&&(r.a={a:0,k:r.a}),"number"==typeof r.p&&(r.p={a:0,k:r.p}),"number"==typeof r.r&&(r.r={a:0,k:r.r}))}return function(t){if(n(r,t.v)&&(s(t.layers),t.assets)){var e,i=t.assets.length;for(e=0;e<i;e+=1)t.assets[e].layers&&s(t.assets[e].layers)}}}(),a=function(){var r=[4,1,9];function a(t){var e,i,r,s=t.length;for(e=0;e<s;e+=1)if("gr"===t[e].ty)a(t[e].it);else if("fl"===t[e].ty||"st"===t[e].ty)if(t[e].c.k&&t[e].c.k[0].i)for(r=t[e].c.k.length,i=0;i<r;i+=1)t[e].c.k[i].s&&(t[e].c.k[i].s[0]/=255,t[e].c.k[i].s[1]/=255,t[e].c.k[i].s[2]/=255,t[e].c.k[i].s[3]/=255),t[e].c.k[i].e&&(t[e].c.k[i].e[0]/=255,t[e].c.k[i].e[1]/=255,t[e].c.k[i].e[2]/=255,t[e].c.k[i].e[3]/=255);else t[e].c.k[0]/=255,t[e].c.k[1]/=255,t[e].c.k[2]/=255,t[e].c.k[3]/=255}function s(t){var e,i=t.length;for(e=0;e<i;e+=1)4===t[e].ty&&a(t[e].shapes)}return function(t){if(n(r,t.v)&&(s(t.layers),t.assets)){var e,i=t.assets.length;for(e=0;e<i;e+=1)t.assets[e].layers&&s(t.assets[e].layers)}}}(),o=function(){var r=[4,4,18];function l(t){var e,i,r;for(e=t.length-1;0<=e;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)t[e].ks.k.c=t[e].closed;else for(r=t[e].ks.k.length,i=0;i<r;i+=1)t[e].ks.k[i].s&&(t[e].ks.k[i].s[0].c=t[e].closed),t[e].ks.k[i].e&&(t[e].ks.k[i].e[0].c=t[e].closed);else"gr"===t[e].ty&&l(t[e].it)}function s(t){var e,i,r,s,a,n,o=t.length;for(i=0;i<o;i+=1){if((e=t[i]).hasMask){var h=e.masksProperties;for(s=h.length,r=0;r<s;r+=1)if(h[r].pt.k.i)h[r].pt.k.c=h[r].cl;else for(n=h[r].pt.k.length,a=0;a<n;a+=1)h[r].pt.k[a].s&&(h[r].pt.k[a].s[0].c=h[r].cl),h[r].pt.k[a].e&&(h[r].pt.k[a].e[0].c=h[r].cl)}4===e.ty&&l(e.shapes)}}return function(t){if(n(r,t.v)&&(s(t.layers),t.assets)){var e,i=t.assets.length;for(e=0;e<i;e+=1)t.assets[e].layers&&s(t.assets[e].layers)}}}();var t={};return t.completeData=function(t){t.__complete||(a(t),e(t),i(t),r(t),o(t),f(t.layers,t.assets),function(t,e){if(t){var i=0,r=t.length;for(i=0;i<r;i+=1)1===t[i].t&&(t[i].data.layers=m(t[i].data.refId,e),f(t[i].data.layers,e))}}(t.chars,t.assets),t.__complete=!0)},t.checkColors=a,t.checkChars=i,t.checkPathProperties=r,t.checkShapes=o,t.completeLayers=f,t}()),i.assetLoader||(i.assetLoader=function(){function n(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")?t.response:t.response&&"object"===_typeof$5(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}return{load:function(e,i,t,r){var s,a=new XMLHttpRequest;try{a.responseType="json"}catch(t){}a.onreadystatechange=function(){if(4===a.readyState)if(200===a.status)s=n(a),t(s);else try{s=n(a),t(s)}catch(t){r&&r(t)}};try{a.open(["G","E","T"].join(""),e,!0)}catch(t){a.open(["G","E","T"].join(""),i+"/"+e,!0)}a.send()}}}()),"loadAnimation"===e.data.type)i.assetLoader.load(e.data.path,e.data.fullPath,function(t){i.dataManager.completeData(t),i.postMessage({id:e.data.id,payload:t,status:"success"})},function(){i.postMessage({id:e.data.id,status:"error"})});else if("complete"===e.data.type){var t=e.data.animation;i.dataManager.completeData(t),i.postMessage({id:e.data.id,payload:t,status:"success"})}else"loadData"===e.data.type&&i.assetLoader.load(e.data.path,e.data.fullPath,function(t){i.postMessage({id:e.data.id,payload:t,status:"success"})},function(){i.postMessage({id:e.data.id,status:"error"})})})).onmessage=function(t){var e=t.data,i=e.id,r=n[i];n[i]=null,"success"===e.status?r.onComplete(e.payload):r.onError&&r.onError()})}function l(t,e){var i="processId_"+(a+=1);return n[i]={onComplete:t,onError:e},i}return{loadAnimation:function(t,e,i){h();var r=l(e,i);s.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:r})},loadData:function(t,e,i){h();var r=l(e,i);s.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:r})},completeAnimation:function(t,e,i){h();var r=l(e,i);s.postMessage({type:"complete",animation:t,id:r})}}}(),ImagePreloader=function(){var s=function(){var t=createTag("canvas");t.width=1,t.height=1;var e=t.getContext("2d");return e.fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1),t}();function t(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function e(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function a(t,e,i){var r="";if(t.e)r=t.p;else if(e){var s=t.p;-1!==s.indexOf("images/")&&(s=s.split("/")[1]),r=e+s}else r=i,r+=t.u?t.u:"",r+=t.p;return r}function i(){this._imageLoaded=t.bind(this),this._footageLoaded=e.bind(this),this.testImageLoaded=function(t){var e=0,i=setInterval(function(){(t.getBBox().width||500<e)&&(this._imageLoaded(),clearInterval(i)),e+=1}.bind(this),50)}.bind(this),this.createFootageData=function(t){var e={assetData:t},i=a(t,this.assetsPath,this.path);return dataManager.loadData(i,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return i.prototype={loadAssets:function(t,e){var i;this.imagesLoadedCb=e;var r=t.length;for(i=0;i<r;i+=1)t[i].layers||(t[i].t&&"seq"!==t[i].t?3===t[i].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[i]))):(this.totalImages+=1,this.images.push(this._createImageData(t[i]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,i=this.images.length;e<i;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(t){var e=a(t,this.assetsPath,this.path),i=createTag("img");i.crossOrigin="anonymous",i.addEventListener("load",this._imageLoaded,!1),i.addEventListener("error",function(){r.img=s,this._imageLoaded()}.bind(this),!1),i.src=e;var r={img:i,assetData:t};return r},createImageData:function(t){var e=a(t,this.assetsPath,this.path),i=createNS("image");isSafari?this.testImageLoaded(i):i.addEventListener("load",this._imageLoaded,!1),i.addEventListener("error",function(){r.img=s,this._imageLoaded()}.bind(this),!1),i.setAttributeNS("http://www.w3.org/1999/xlink","href",e),this._elementHelper.append?this._elementHelper.append(i):this._elementHelper.appendChild(i);var r={img:i,assetData:t};return r},imageLoaded:t,footageLoaded:e,setCacheType:function(t,e){this._createImageData="svg"===t?(this._elementHelper=e,this.createImageData.bind(this)):this.createImgData.bind(this)}},i}();function BaseEvent(){}BaseEvent.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var i=this._cbs[t],r=0;r<i.length;r+=1)i[r](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var i=0,r=this._cbs[t].length;i<r;)this._cbs[t][i]===e&&(this._cbs[t].splice(i,1),i-=1,r-=1),i+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var markerParser=function(){function a(t){for(var e,i=t.split("\r\n"),r={},s=0,a=0;a<i.length;a+=1)2===(e=i[a].split(":")).length&&(r[e[0]]=e[1].trim(),s+=1);if(0===s)throw new Error;return r}return function(e){for(var t=[],i=0;i<e.length;i+=1){var r=e[i],s={time:r.tm,duration:r.dr};try{s.payload=JSON.parse(e[i].cm)}catch(t){try{s.payload=a(e[i].cm)}catch(t){s.payload={name:e[i].cm}}}t.push(s)}return t}}(),ProjectInterface=function(){function e(t){this.compositions.push(t)}return function(){function t(t){for(var e=0,i=this.compositions.length;e<i;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return t.compositions=[],t.currentFrame=0,t.registerComposition=e,t}}(),renderers={},registerRenderer=function(t,e){renderers[t]=e};function getRenderer(t){return renderers[t]}function getRegisteredRenderer(){if(renderers.canvas)return"canvas";for(var t in renderers)if(renderers[t])return t;return""}function _typeof$4(t){return(_typeof$4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var AnimationItem=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=createElementID(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=getSubframeEnabled(),this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=ProjectInterface(),this.imagePreloader=new ImagePreloader,this.audioController=audioControllerFactory(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new BMEnterFrameEvent("drawnFrame",0,0,0),this.expressionsPlugin=getExpressionsPlugin()};extendPrototype([BaseEvent],AnimationItem),AnimationItem.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg";t.animType?e=t.animType:t.renderer&&(e=t.renderer);var i=getRenderer(e);this.renderer=new i(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||void 0===t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),dataManager.loadAnimation(t.path,this.configAnimation,this.onSetupError))},AnimationItem.prototype.onSetupError=function(){this.trigger("data_failed")},AnimationItem.prototype.setupAnimation=function(t){dataManager.completeAnimation(t,this.configAnimation)},AnimationItem.prototype.setData=function(t,e){e&&"object"!==_typeof$4(e)&&(e=JSON.parse(e));var i={wrapper:t,animationData:e},r=t.attributes;i.path=r.getNamedItem("data-animation-path")?r.getNamedItem("data-animation-path").value:r.getNamedItem("data-bm-path")?r.getNamedItem("data-bm-path").value:r.getNamedItem("bm-path")?r.getNamedItem("bm-path").value:"",i.animType=r.getNamedItem("data-anim-type")?r.getNamedItem("data-anim-type").value:r.getNamedItem("data-bm-type")?r.getNamedItem("data-bm-type").value:r.getNamedItem("bm-type")?r.getNamedItem("bm-type").value:r.getNamedItem("data-bm-renderer")?r.getNamedItem("data-bm-renderer").value:r.getNamedItem("bm-renderer")?r.getNamedItem("bm-renderer").value:getRegisteredRenderer()||"canvas";var s=r.getNamedItem("data-anim-loop")?r.getNamedItem("data-anim-loop").value:r.getNamedItem("data-bm-loop")?r.getNamedItem("data-bm-loop").value:r.getNamedItem("bm-loop")?r.getNamedItem("bm-loop").value:"";"false"===s?i.loop=!1:"true"===s?i.loop=!0:""!==s&&(i.loop=parseInt(s,10));var a=r.getNamedItem("data-anim-autoplay")?r.getNamedItem("data-anim-autoplay").value:r.getNamedItem("data-bm-autoplay")?r.getNamedItem("data-bm-autoplay").value:!r.getNamedItem("bm-autoplay")||r.getNamedItem("bm-autoplay").value;i.autoplay="false"!==a,i.name=r.getNamedItem("data-name")?r.getNamedItem("data-name").value:r.getNamedItem("data-bm-name")?r.getNamedItem("data-bm-name").value:r.getNamedItem("bm-name")?r.getNamedItem("bm-name").value:"","false"===(r.getNamedItem("data-anim-prerender")?r.getNamedItem("data-anim-prerender").value:r.getNamedItem("data-bm-prerender")?r.getNamedItem("data-bm-prerender").value:r.getNamedItem("bm-prerender")?r.getNamedItem("bm-prerender").value:"")&&(i.prerender=!1),i.path?this.setParams(i):this.trigger("destroy")},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,i,r=this.animationData.layers,s=r.length,a=t.layers,n=a.length;for(i=0;i<n;i+=1)for(e=0;e<s;){if(r[e].id===a[i].id){r[e]=a[i];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(s=t.assets.length,e=0;e<s;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,dataManager.completeAnimation(this.animationData,this.onSegmentComplete)},AnimationItem.prototype.onSegmentComplete=function(t){this.animationData=t;var e=getExpressionsPlugin();e&&e.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var i=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,dataManager.loadData(i,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},AnimationItem.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},AnimationItem.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=markerParser(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},AnimationItem.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},AnimationItem.prototype.checkLoaded=function(){if(!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()){this.isLoaded=!0;var t=getExpressionsPlugin();t&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play()}},AnimationItem.prototype.resize=function(t,e){var i="number"==typeof t?t:void 0,r="number"==typeof e?e:void 0;this.renderer.updateContainerSize(i,r)},AnimationItem.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},AnimationItem.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},AnimationItem.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},AnimationItem.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},AnimationItem.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.getMarkerData=function(t){for(var e,i=0;i<this.markers.length;i+=1)if((e=this.markers[i]).payload&&e.payload.name===t)return e;return null},AnimationItem.prototype.goToAndStop=function(t,e,i){if(!i||this.name===i){var r=Number(t);if(isNaN(r)){var s=this.getMarkerData(t);s&&this.goToAndStop(s.time,!0)}else e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier);this.pause()}},AnimationItem.prototype.goToAndPlay=function(t,e,i){if(!i||this.name===i){var r=Number(t);if(isNaN(r)){var s=this.getMarkerData(t);s&&(s.duration?this.playSegments([s.time,s.time+s.duration],!0):this.goToAndStop(s.time,!0))}else this.goToAndStop(r,e,i);this.play()}},AnimationItem.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,i=!1;e>=this.totalFrames-1&&0<this.frameModifier?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(i=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(i=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),i&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(0<this.frameModifier&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var i=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?i=t:this.currentRawFrame+this.firstFrame>e&&(i=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==i&&this.goToAndStop(i,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===_typeof$4(t[0])){var i,r=t.length;for(i=0;i<r;i+=1)this.segments.push(t[i])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},AnimationItem.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},AnimationItem.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},AnimationItem.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},AnimationItem.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},AnimationItem.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},AnimationItem.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},AnimationItem.prototype.setLoop=function(t){this.loop=t},AnimationItem.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},AnimationItem.prototype.getVolume=function(){return this.audioController.getVolume()},AnimationItem.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},AnimationItem.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},AnimationItem.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},AnimationItem.prototype.getPath=function(){return this.path},AnimationItem.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var i=t.p;-1!==i.indexOf("images/")&&(i=i.split("/")[1]),e=this.assetsPath+i}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},AnimationItem.prototype.getAssetData=function(t){for(var e=0,i=this.assets.length;e<i;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},AnimationItem.prototype.hide=function(){this.renderer.hide()},AnimationItem.prototype.show=function(){this.renderer.show()},AnimationItem.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},AnimationItem.prototype.updateDocumentData=function(t,e,i){try{this.renderer.getElementByPath(t).updateDocumentData(e,i)}catch(t){}},AnimationItem.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new BMCompleteEvent(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new BMDestroyEvent(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new BMCompleteEvent(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new BMDestroyEvent(t,this))},AnimationItem.prototype.triggerRenderFrameError=function(t){var e=new BMRenderFrameErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)},AnimationItem.prototype.triggerConfigError=function(t){var e=new BMConfigErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)};var animationManager=function(){var t={},s=[],r=0,a=0,n=0,o=!0,h=!1;function i(t){for(var e=0,i=t.target;e<a;)s[e].animation===i&&(s.splice(e,1),e-=1,a-=1,i.isPaused||f()),e+=1}function l(t,e){if(!t)return null;for(var i=0;i<a;){if(s[i].elem===t&&null!==s[i].elem)return s[i].animation;i+=1}var r=new AnimationItem;return m(r,t),r.setData(t,e),r}function p(){n+=1,d()}function f(){n-=1}function m(t,e){t.addEventListener("destroy",i),t.addEventListener("_active",p),t.addEventListener("_idle",f),s.push({elem:e,animation:t}),a+=1}function c(t){var e,i=t-r;for(e=0;e<a;e+=1)s[e].animation.advanceTime(i);r=t,n&&!h?window.requestAnimationFrame(c):o=!0}function e(t){r=t,window.requestAnimationFrame(c)}function d(){!h&&n&&o&&(window.requestAnimationFrame(e),o=!1)}return t.registerAnimation=l,t.loadAnimation=function(t){var e=new AnimationItem;return m(e,null),e.setParams(t),e},t.setSpeed=function(t,e){var i;for(i=0;i<a;i+=1)s[i].animation.setSpeed(t,e)},t.setDirection=function(t,e){var i;for(i=0;i<a;i+=1)s[i].animation.setDirection(t,e)},t.play=function(t){var e;for(e=0;e<a;e+=1)s[e].animation.play(t)},t.pause=function(t){var e;for(e=0;e<a;e+=1)s[e].animation.pause(t)},t.stop=function(t){var e;for(e=0;e<a;e+=1)s[e].animation.stop(t)},t.togglePause=function(t){var e;for(e=0;e<a;e+=1)s[e].animation.togglePause(t)},t.searchAnimations=function(t,e,i){var r,s=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),a=s.length;for(r=0;r<a;r+=1)i&&s[r].setAttribute("data-bm-type",i),l(s[r],t);if(e&&0===a){i||(i="svg");var n=document.getElementsByTagName("body")[0];n.innerText="";var o=createTag("div");o.style.width="100%",o.style.height="100%",o.setAttribute("data-bm-type",i),n.appendChild(o),l(o,t)}},t.resize=function(){var t;for(t=0;t<a;t+=1)s[t].animation.resize()},t.goToAndStop=function(t,e,i){var r;for(r=0;r<a;r+=1)s[r].animation.goToAndStop(t,e,i)},t.destroy=function(t){var e;for(e=a-1;0<=e;e-=1)s[e].animation.destroy(t)},t.freeze=function(){h=!0},t.unfreeze=function(){h=!1,d()},t.setVolume=function(t,e){var i;for(i=0;i<a;i+=1)s[i].animation.setVolume(t,e)},t.mute=function(t){var e;for(e=0;e<a;e+=1)s[e].animation.mute(t)},t.unmute=function(t){var e;for(e=0;e<a;e+=1)s[e].animation.unmute(t)},t.getRegisteredAnimations=function(){var t,e=s.length,i=[];for(t=0;t<e;t+=1)i.push(s[t].animation);return i},t}(),BezierFactory=function(){var t={getBezierEasing:function(t,e,i,r,s){var a=s||("bez_"+t+"_"+e+"_"+i+"_"+r).replace(/\./g,"p");if(o[a])return o[a];var n=new h([t,e,i,r]);return o[a]=n}},o={};var l=11,p=1/(l-1),e="function"==typeof Float32Array;function r(t,e){return 1-3*e+3*t}function s(t,e){return 3*e-6*t}function a(t){return 3*t}function f(t,e,i){return((r(e,i)*t+s(e,i))*t+a(e))*t}function m(t,e,i){return 3*r(e,i)*t*t+2*s(e,i)*t+a(e)}function h(t){this._p=t,this._mSampleValues=e?new Float32Array(l):new Array(l),this._precomputed=!1,this.get=this.get.bind(this)}return h.prototype={get:function(t){var e=this._p[0],i=this._p[1],r=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===i&&r===s?t:0===t?0:1===t?1:f(this._getTForX(t),i,s)},_precompute:function(){var t=this._p[0],e=this._p[1],i=this._p[2],r=this._p[3];this._precomputed=!0,t===e&&i===r||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],i=0;i<l;++i)this._mSampleValues[i]=f(i*p,t,e)},_getTForX:function(t){for(var e=this._p[0],i=this._p[2],r=this._mSampleValues,s=0,a=1,n=l-1;a!==n&&r[a]<=t;++a)s+=p;var o=s+(t-r[--a])/(r[a+1]-r[a])*p,h=m(o,e,i);return.001<=h?function(t,e,i,r){for(var s=0;s<4;++s){var a=m(e,i,r);if(0===a)return e;e-=(f(e,i,r)-t)/a}return e}(t,o,e,i):0===h?o:function(t,e,i,r,s){for(var a,n,o=0;0<(a=f(n=e+(i-e)/2,r,s)-t)?i=n:e=n,1e-7<Math.abs(a)&&++o<10;);return n}(t,s,s+p,e,i)}},t}(),pooling={double:function(t){return t.concat(createSizedArray(t.length))}},poolFactory=function(t,e,i){var r=0,s=t,a=createSizedArray(s);return{newElement:function(){return r?a[r-=1]:e()},release:function(t){r===s&&(a=pooling.double(a),s*=2),i&&i(t),a[r]=t,r+=1}}},bezierLengthPool=poolFactory(8,function(){return{addedLength:0,percents:createTypedArray("float32",getDefaultCurveSegments()),lengths:createTypedArray("float32",getDefaultCurveSegments())}}),segmentsLengthPool=poolFactory(8,function(){return{lengths:[],totalLength:0}},function(t){var e,i=t.lengths.length;for(e=0;e<i;e+=1)bezierLengthPool.release(t.lengths[e]);t.lengths.length=0});function bezFunction(){var k=Math;function y(t,e,i,r,s,a){var n=t*r+e*s+i*a-s*r-a*t-i*e;return-.001<n&&n<.001}var p=function(t,e,i,r){var s,a,n,o,h,l,p=getDefaultCurveSegments(),f=0,m=[],c=[],d=bezierLengthPool.newElement();for(n=i.length,s=0;s<p;s+=1){for(h=s/(p-1),a=l=0;a<n;a+=1)o=bmPow(1-h,3)*t[a]+3*bmPow(1-h,2)*h*i[a]+3*(1-h)*bmPow(h,2)*r[a]+bmPow(h,3)*e[a],m[a]=o,null!==c[a]&&(l+=bmPow(m[a]-c[a],2)),c[a]=m[a];l&&(f+=l=bmSqrt(l)),d.percents[s]=h,d.lengths[s]=f}return d.addedLength=f,d};function g(t){this.segmentLength=0,this.points=new Array(t)}function v(t,e){this.partialLength=t,this.point=e}var b,t=(b={},function(t,e,i,r){var s=(t[0]+"_"+t[1]+"_"+e[0]+"_"+e[1]+"_"+i[0]+"_"+i[1]+"_"+r[0]+"_"+r[1]).replace(/\./g,"p");if(!b[s]){var a,n,o,h,l,p,f,m=getDefaultCurveSegments(),c=0,d=null;2===t.length&&(t[0]!==e[0]||t[1]!==e[1])&&y(t[0],t[1],e[0],e[1],t[0]+i[0],t[1]+i[1])&&y(t[0],t[1],e[0],e[1],e[0]+r[0],e[1]+r[1])&&(m=2);var u=new g(m);for(o=i.length,a=0;a<m;a+=1){for(f=createSizedArray(o),l=a/(m-1),n=p=0;n<o;n+=1)h=bmPow(1-l,3)*t[n]+3*bmPow(1-l,2)*l*(t[n]+i[n])+3*(1-l)*bmPow(l,2)*(e[n]+r[n])+bmPow(l,3)*e[n],f[n]=h,null!==d&&(p+=bmPow(f[n]-d[n],2));c+=p=bmSqrt(p),u.points[a]=new v(p,f),d=f}u.segmentLength=c,b[s]=u}return b[s]});function D(t,e){var i=e.percents,r=e.lengths,s=i.length,a=bmFloor((s-1)*t),n=t*e.addedLength,o=0;if(a===s-1||0===a||n===r[a])return i[a];for(var h=r[a]>n?-1:1,l=!0;l;)if(r[a]<=n&&r[a+1]>n?(o=(n-r[a])/(r[a+1]-r[a]),l=!1):a+=h,a<0||s-1<=a){if(a===s-1)return i[a];l=!1}return i[a]+(i[a+1]-i[a])*o}var F=createTypedArray("float32",8);return{getSegmentsLength:function(t){var e,i=segmentsLengthPool.newElement(),r=t.c,s=t.v,a=t.o,n=t.i,o=t._length,h=i.lengths,l=0;for(e=0;e<o-1;e+=1)h[e]=p(s[e],s[e+1],a[e],n[e+1]),l+=h[e].addedLength;return r&&o&&(h[e]=p(s[e],s[0],a[e],n[0]),l+=h[e].addedLength),i.totalLength=l,i},getNewSegment:function(t,e,i,r,s,a,n){s<0?s=0:1<s&&(s=1);var o,h=D(s,n),l=D(a=1<a?1:a,n),p=t.length,f=1-h,m=1-l,c=f*f*f,d=h*f*f*3,u=h*h*f*3,y=h*h*h,g=f*f*m,v=h*f*m+f*h*m+f*f*l,b=h*h*m+f*h*l+h*f*l,x=h*h*l,P=f*m*m,E=h*m*m+f*l*m+f*m*l,S=h*l*m+f*l*l+h*m*l,C=h*l*l,_=m*m*m,A=l*m*m+m*l*m+m*m*l,T=l*l*m+m*l*l+l*m*l,M=l*l*l;for(o=0;o<p;o+=1)F[4*o]=k.round(1e3*(c*t[o]+d*i[o]+u*r[o]+y*e[o]))/1e3,F[4*o+1]=k.round(1e3*(g*t[o]+v*i[o]+b*r[o]+x*e[o]))/1e3,F[4*o+2]=k.round(1e3*(P*t[o]+E*i[o]+S*r[o]+C*e[o]))/1e3,F[4*o+3]=k.round(1e3*(_*t[o]+A*i[o]+T*r[o]+M*e[o]))/1e3;return F},getPointInSegment:function(t,e,i,r,s,a){var n=D(s,a),o=1-n;return[k.round(1e3*(o*o*o*t[0]+(n*o*o+o*n*o+o*o*n)*i[0]+(n*n*o+o*n*n+n*o*n)*r[0]+n*n*n*e[0]))/1e3,k.round(1e3*(o*o*o*t[1]+(n*o*o+o*n*o+o*o*n)*i[1]+(n*n*o+o*n*n+n*o*n)*r[1]+n*n*n*e[1]))/1e3]},buildBezierData:t,pointOnLine2D:y,pointOnLine3D:function(t,e,i,r,s,a,n,o,h){if(0===i&&0===a&&0===h)return y(t,e,r,s,n,o);var l,p=k.sqrt(k.pow(r-t,2)+k.pow(s-e,2)+k.pow(a-i,2)),f=k.sqrt(k.pow(n-t,2)+k.pow(o-e,2)+k.pow(h-i,2)),m=k.sqrt(k.pow(n-r,2)+k.pow(o-s,2)+k.pow(h-a,2));return-1e-4<(l=f<p?m<p?p-f-m:m-f-p:f<m?m-f-p:f-p-m)&&l<1e-4}}}var bez=bezFunction(),initFrame=initialDefaultFrame,mathAbs=Math.abs;function interpolateValue(t,e){var i,r=this.offsetTime;"multidimensional"===this.propType&&(i=createTypedArray("float32",this.pv.length));for(var s,a,n,o,h,l,p,f,m,c=e.lastIndex,d=c,u=this.keyframes.length-1,y=!0;y;){if(s=this.keyframes[d],a=this.keyframes[d+1],d===u-1&&t>=a.t-r){s.h&&(s=a),c=0;break}if(a.t-r>t){c=d;break}d<u-1?d+=1:(c=0,y=!1)}n=this.keyframesMetadata[d]||{};var g,v=a.t-r,b=s.t-r;if(s.to){n.bezierData||(n.bezierData=bez.buildBezierData(s.s,a.s||s.e,s.to,s.ti));var x=n.bezierData;if(v<=t||t<b){var P=v<=t?x.points.length-1:0;for(h=x.points[P].point.length,o=0;o<h;o+=1)i[o]=x.points[P].point[o]}else{n.__fnct?m=n.__fnct:(m=BezierFactory.getBezierEasing(s.o.x,s.o.y,s.i.x,s.i.y,s.n).get,n.__fnct=m),l=m((t-b)/(v-b));var E,S=x.segmentLength*l,C=e.lastFrame<t&&e._lastKeyframeIndex===d?e._lastAddedLength:0;for(f=e.lastFrame<t&&e._lastKeyframeIndex===d?e._lastPoint:0,y=!0,p=x.points.length;y;){if(C+=x.points[f].partialLength,0===S||0===l||f===x.points.length-1){for(h=x.points[f].point.length,o=0;o<h;o+=1)i[o]=x.points[f].point[o];break}if(C<=S&&S<C+x.points[f+1].partialLength){for(E=(S-C)/x.points[f+1].partialLength,h=x.points[f].point.length,o=0;o<h;o+=1)i[o]=x.points[f].point[o]+(x.points[f+1].point[o]-x.points[f].point[o])*E;break}f<p-1?f+=1:y=!1}e._lastPoint=f,e._lastAddedLength=C-x.points[f].partialLength,e._lastKeyframeIndex=d}}else{var _,A,T,M,k;if(u=s.s.length,g=a.s||s.e,this.sh&&1!==s.h)if(v<=t)i[0]=g[0],i[1]=g[1],i[2]=g[2];else if(t<=b)i[0]=s.s[0],i[1]=s.s[1],i[2]=s.s[2];else{quaternionToEuler(i,slerp(createQuaternion(s.s),createQuaternion(g),(t-b)/(v-b)))}else for(d=0;d<u;d+=1)1!==s.h&&(l=v<=t?1:t<b?0:(s.o.x.constructor===Array?(n.__fnct||(n.__fnct=[]),n.__fnct[d]?m=n.__fnct[d]:(_=void 0===s.o.x[d]?s.o.x[0]:s.o.x[d],A=void 0===s.o.y[d]?s.o.y[0]:s.o.y[d],T=void 0===s.i.x[d]?s.i.x[0]:s.i.x[d],M=void 0===s.i.y[d]?s.i.y[0]:s.i.y[d],m=BezierFactory.getBezierEasing(_,A,T,M).get,n.__fnct[d]=m)):n.__fnct?m=n.__fnct:(_=s.o.x,A=s.o.y,T=s.i.x,M=s.i.y,m=BezierFactory.getBezierEasing(_,A,T,M).get,s.keyframeMetadata=m),m((t-b)/(v-b)))),g=a.s||s.e,k=1===s.h?s.s[d]:s.s[d]+(g[d]-s.s[d])*l,"multidimensional"===this.propType?i[d]=k:i=k}return e.lastIndex=c,i}function slerp(t,e,i){var r,s,a,n,o,h=[],l=t[0],p=t[1],f=t[2],m=t[3],c=e[0],d=e[1],u=e[2],y=e[3];return(s=l*c+p*d+f*u+m*y)<0&&(s=-s,c=-c,d=-d,u=-u,y=-y),o=1e-6<1-s?(r=Math.acos(s),a=Math.sin(r),n=Math.sin((1-i)*r)/a,Math.sin(i*r)/a):(n=1-i,i),h[0]=n*l+o*c,h[1]=n*p+o*d,h[2]=n*f+o*u,h[3]=n*m+o*y,h}function quaternionToEuler(t,e){var i=e[0],r=e[1],s=e[2],a=e[3],n=Math.atan2(2*r*a-2*i*s,1-2*r*r-2*s*s),o=Math.asin(2*i*r+2*s*a),h=Math.atan2(2*i*a-2*r*s,1-2*i*i-2*s*s);t[0]=n/degToRads,t[1]=o/degToRads,t[2]=h/degToRads}function createQuaternion(t){var e=t[0]*degToRads,i=t[1]*degToRads,r=t[2]*degToRads,s=Math.cos(e/2),a=Math.cos(i/2),n=Math.cos(r/2),o=Math.sin(e/2),h=Math.sin(i/2),l=Math.sin(r/2);return[o*h*n+s*a*l,o*a*n+s*h*l,s*h*n-o*a*l,s*a*n-o*h*l]}function getValueAtCurrentTime(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==initFrame&&(this._caching.lastFrame>=i&&i<=t||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var r=this.interpolateValue(t,this._caching);this.pv=r}return this._caching.lastFrame=t,this.pv}function setVValue(t){var e;if("unidimensional"===this.propType)e=t*this.mult,1e-5<mathAbs(this.v-e)&&(this.v=e,this._mdf=!0);else for(var i=0,r=this.v.length;i<r;)e=t[i]*this.mult,1e-5<mathAbs(this.v[i]-e)&&(this.v[i]=e,this._mdf=!0),i+=1}function processEffectsSequence(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t;this.lock=!0,this._mdf=this._isFirstFrame;var e=this.effectsSequence.length,i=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)i=this.effectsSequence[t](i);this.setVValue(i),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function addEffect(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function ValueProperty(t,e,i,r){this.propType="unidimensional",this.mult=i||1,this.data=e,this.v=i?e.k*i:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function MultiDimensionalProperty(t,e,i,r){var s;this.propType="multidimensional",this.mult=i||1,this.data=e,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var a=e.k.length;for(this.v=createTypedArray("float32",a),this.pv=createTypedArray("float32",a),this.vel=createTypedArray("float32",a),s=0;s<a;s+=1)this.v[s]=e.k[s]*this.mult,this.pv[s]=e.k[s];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function KeyframedValueProperty(t,e,i,r){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:initFrame,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.v=initFrame,this.pv=initFrame,this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.addEffect=addEffect}function KeyframedMultidimensionalProperty(t,e,i,r){var s;this.propType="multidimensional";var a,n,o,h,l=e.k.length;for(s=0;s<l-1;s+=1)e.k[s].to&&e.k[s].s&&e.k[s+1]&&e.k[s+1].s&&(a=e.k[s].s,n=e.k[s+1].s,o=e.k[s].to,h=e.k[s].ti,(2===a.length&&(a[0]!==n[0]||a[1]!==n[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],a[0]+o[0],a[1]+o[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],n[0]+h[0],n[1]+h[1])||3===a.length&&(a[0]!==n[0]||a[1]!==n[1]||a[2]!==n[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],a[0]+o[0],a[1]+o[1],a[2]+o[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],n[0]+h[0],n[1]+h[1],n[2]+h[2]))&&(e.k[s].to=null,e.k[s].ti=null),a[0]===n[0]&&a[1]===n[1]&&0===o[0]&&0===o[1]&&0===h[0]&&0===h[1]&&(2===a.length||a[2]===n[2]&&0===o[2]&&0===h[2])&&(e.k[s].to=null,e.k[s].ti=null));this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.frameId=-1;var p=e.k[0].s.length;for(this.v=createTypedArray("float32",p),this.pv=createTypedArray("float32",p),s=0;s<p;s+=1)this.v[s]=initFrame,this.pv[s]=initFrame;this._caching={lastFrame:initFrame,lastIndex:0,value:createTypedArray("float32",p)},this.addEffect=addEffect}var PropertyFactory={getProp:function(t,e,i,r,s){var a;if(e.sid&&(e=t.globalData.slotManager.getProp(e)),e.k.length)if("number"==typeof e.k[0])a=new MultiDimensionalProperty(t,e,r,s);else switch(i){case 0:a=new KeyframedValueProperty(t,e,r,s);break;case 1:a=new KeyframedMultidimensionalProperty(t,e,r,s)}else a=new ValueProperty(t,e,r,s);return a.effectsSequence.length&&s.addDynamicProperty(a),a}};function DynamicPropertyContainer(){}DynamicPropertyContainer.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){var t;this._mdf=!1;var e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var pointPool=poolFactory(8,function(){return createTypedArray("float32",2)});function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var i=0;i<e;)this.v[i]=pointPool.newElement(),this.o[i]=pointPool.newElement(),this.i[i]=pointPool.newElement(),i+=1},ShapePath.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},ShapePath.prototype.doubleArrayLength=function(){this.v=this.v.concat(createSizedArray(this._maxLength)),this.i=this.i.concat(createSizedArray(this._maxLength)),this.o=this.o.concat(createSizedArray(this._maxLength)),this._maxLength*=2},ShapePath.prototype.setXYAt=function(t,e,i,r,s){var a;switch(this._length=Math.max(this._length,r+1),this._length>=this._maxLength&&this.doubleArrayLength(),i){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o;break;default:a=[]}(!a[r]||a[r]&&!s)&&(a[r]=pointPool.newElement()),a[r][0]=t,a[r][1]=e},ShapePath.prototype.setTripleAt=function(t,e,i,r,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(i,r,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t=new ShapePath;t.setPathData(this.c,this._length);var e=this.v,i=this.o,r=this.i,s=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],r[0][0],r[0][1],i[0][0],i[0][1],0,!1),s=1);var a,n=this._length-1,o=this._length;for(a=s;a<o;a+=1)t.setTripleAt(e[n][0],e[n][1],r[n][0],r[n][1],i[n][0],i[n][1],a,!1),n-=1;return t},ShapePath.prototype.length=function(){return this._length};var shapePool=(_r=poolFactory(4,function(){return new ShapePath},function(t){var e,i=t._length;for(e=0;e<i;e+=1)pointPool.release(t.v[e]),pointPool.release(t.i[e]),pointPool.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1}),_r.clone=function(t){var e,i=_r.newElement(),r=void 0===t._length?t.v.length:t._length;for(i.setLength(r),i.c=t.c,e=0;e<r;e+=1)i.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return i},_r),_r;function ShapeCollection(){this._length=0,this._maxLength=4,this.shapes=createSizedArray(this._maxLength)}ShapeCollection.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(createSizedArray(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},ShapeCollection.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)shapePool.release(this.shapes[t]);this._length=0};var shapeCollectionPool=(js={newShapeCollection:function(){var t;t=ks?ms[ks-=1]:new ShapeCollection;return t},release:function(t){var e,i=t._length;for(e=0;e<i;e+=1)shapePool.release(t.shapes[e]);t._length=0,ks===ls&&(ms=pooling.double(ms),ls*=2);ms[ks]=t,ks+=1}},ks=0,ls=4,ms=createSizedArray(ls),js),js,ks,ls,ms,ShapePropertyFactory=function(){var s=-999999;function t(t,e,i){var r,s,a,n,o,h,l,p,f,m=i.lastIndex,c=this.keyframes;if(t<c[0].t-this.offsetTime)r=c[0].s[0],a=!0,m=0;else if(t>=c[c.length-1].t-this.offsetTime)r=c[c.length-1].s?c[c.length-1].s[0]:c[c.length-2].e[0],a=!0;else{for(var d,u,y,g=m,v=c.length-1,b=!0;b&&(d=c[g],!((u=c[g+1]).t-this.offsetTime>t));)g<v-1?g+=1:b=!1;if(y=this.keyframesMetadata[g]||{},m=g,!(a=1===d.h)){if(t>=u.t-this.offsetTime)p=1;else if(t<d.t-this.offsetTime)p=0;else{var x;y.__fnct?x=y.__fnct:(x=BezierFactory.getBezierEasing(d.o.x,d.o.y,d.i.x,d.i.y).get,y.__fnct=x),p=x((t-(d.t-this.offsetTime))/(u.t-this.offsetTime-(d.t-this.offsetTime)))}s=u.s?u.s[0]:d.e[0]}r=d.s[0]}for(h=e._length,l=r.i[0].length,i.lastIndex=m,n=0;n<h;n+=1)for(o=0;o<l;o+=1)f=a?r.i[n][o]:r.i[n][o]+(s.i[n][o]-r.i[n][o])*p,e.i[n][o]=f,f=a?r.o[n][o]:r.o[n][o]+(s.o[n][o]-r.o[n][o])*p,e.o[n][o]=f,f=a?r.v[n][o]:r.v[n][o]+(s.v[n][o]-r.v[n][o])*p,e.v[n][o]=f}function a(){this.paths=this.localShapeCollection}function e(t){(function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var i,r=t._length;for(i=0;i<r;i+=1)if(t.v[i][0]!==e.v[i][0]||t.v[i][1]!==e.v[i][1]||t.o[i][0]!==e.o[i][0]||t.o[i][1]!==e.o[i][1]||t.i[i][0]!==e.i[i][0]||t.i[i][1]!==e.i[i][1])return!1;return!0})(this.v,t)||(this.v=shapePool.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function i(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t,e;this.lock=!0,this._mdf=!1,t=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k;var i=this.effectsSequence.length;for(e=0;e<i;e+=1)t=this.effectsSequence[e](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function n(t,e,i){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var r=3===i?e.pt.k:e.ks.k;this.v=shapePool.clone(r),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=a,this.effectsSequence=[]}function r(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function o(t,e,i){this.propType="shape",this.comp=t.comp,this.elem=t,this.container=t,this.offsetTime=t.data.st,this.keyframes=3===i?e.pt.k:e.ks.k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;var r=this.keyframes[0].s[0].i.length;this.v=shapePool.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,r),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=s,this.reset=a,this._caching={lastFrame:s,lastIndex:0},this.effectsSequence=[function(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime,r=this._caching.lastFrame;return r!==s&&(r<e&&t<e||i<r&&i<t)||(this._caching.lastIndex=r<t?this._caching.lastIndex:0,this.interpolateShape(t,this.pv,this._caching)),this._caching.lastFrame=t,this.pv}.bind(this)]}n.prototype.interpolateShape=t,n.prototype.getValue=i,n.prototype.setVValue=e,n.prototype.addEffect=r,o.prototype.getValue=i,o.prototype.interpolateShape=t,o.prototype.setVValue=e,o.prototype.addEffect=r;var h=function(){var n=roundCorner;function t(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}return t.prototype={reset:a,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,r=this.s.v[1]/2,s=3!==this.d,a=this.v;a.v[0][0]=t,a.v[0][1]=e-r,a.v[1][0]=s?t+i:t-i,a.v[1][1]=e,a.v[2][0]=t,a.v[2][1]=e+r,a.v[3][0]=s?t-i:t+i,a.v[3][1]=e,a.i[0][0]=s?t-i*n:t+i*n,a.i[0][1]=e-r,a.i[1][0]=s?t+i:t-i,a.i[1][1]=e-r*n,a.i[2][0]=s?t+i*n:t-i*n,a.i[2][1]=e+r,a.i[3][0]=s?t-i:t+i,a.i[3][1]=e+r*n,a.o[0][0]=s?t+i*n:t-i*n,a.o[0][1]=e-r,a.o[1][0]=s?t+i:t-i,a.o[1][1]=e+r*n,a.o[2][0]=s?t-i*n:t+i*n,a.o[2][1]=e+r,a.o[3][0]=s?t-i:t+i,a.o[3][1]=e-r*n}},extendPrototype([DynamicPropertyContainer],t),t}(),l=function(){function t(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=PropertyFactory.getProp(t,e.ir,0,0,this),this.is=PropertyFactory.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=PropertyFactory.getProp(t,e.pt,0,0,this),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,degToRads,this),this.or=PropertyFactory.getProp(t,e.or,0,0,this),this.os=PropertyFactory.getProp(t,e.os,0,.01,this),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}return t.prototype={reset:a,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,i,r,s=2*Math.floor(this.pt.v),a=2*Math.PI/s,n=!0,o=this.or.v,h=this.ir.v,l=this.os.v,p=this.is.v,f=2*Math.PI*o/(2*s),m=2*Math.PI*h/(2*s),c=-Math.PI/2;c+=this.r.v;var d=3===this.data.d?-1:1;for(t=this.v._length=0;t<s;t+=1){i=n?l:p,r=n?f:m;var u=(e=n?o:h)*Math.cos(c),y=e*Math.sin(c),g=0===u&&0===y?0:y/Math.sqrt(u*u+y*y),v=0===u&&0===y?0:-u/Math.sqrt(u*u+y*y);u+=+this.p.v[0],y+=+this.p.v[1],this.v.setTripleAt(u,y,u-g*r*i*d,y-v*r*i*d,u+g*r*i*d,y+v*r*i*d,t,!0),n=!n,c+=a*d}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),i=2*Math.PI/e,r=this.or.v,s=this.os.v,a=2*Math.PI*r/(4*e),n=.5*-Math.PI,o=3===this.data.d?-1:1;for(n+=this.r.v,t=this.v._length=0;t<e;t+=1){var h=r*Math.cos(n),l=r*Math.sin(n),p=0===h&&0===l?0:l/Math.sqrt(h*h+l*l),f=0===h&&0===l?0:-h/Math.sqrt(h*h+l*l);h+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(h,l,h-p*a*s*o,l-f*a*s*o,h+p*a*s*o,l+f*a*s*o,t,!0),n+=i*o}this.paths.length=0,this.paths[0]=this.v}},extendPrototype([DynamicPropertyContainer],t),t}(),p=function(){function t(t,e){this.v=shapePool.newElement(),this.v.c=!0,this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}return t.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,r=this.s.v[1]/2,s=bmMin(i,r,this.r.v),a=s*(1-roundCorner);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+s,t+i,e-r+a,0,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-a,t+i,e+r-s,1,!0),0!==s?(this.v.setTripleAt(t+i-s,e+r,t+i-s,e+r,t+i-a,e+r,2,!0),this.v.setTripleAt(t-i+s,e+r,t-i+a,e+r,t-i+s,e+r,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-s,t-i,e+r-a,4,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+a,t-i,e-r+s,5,!0),this.v.setTripleAt(t-i+s,e-r,t-i+s,e-r,t-i+a,e-r,6,!0),this.v.setTripleAt(t+i-s,e-r,t+i-a,e-r,t+i-s,e-r,7,!0)):(this.v.setTripleAt(t-i,e+r,t-i+a,e+r,t-i,e+r,2),this.v.setTripleAt(t-i,e-r,t-i,e-r+a,t-i,e-r,3))):(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+a,t+i,e-r+s,0,!0),0!==s?(this.v.setTripleAt(t+i-s,e-r,t+i-s,e-r,t+i-a,e-r,1,!0),this.v.setTripleAt(t-i+s,e-r,t-i+a,e-r,t-i+s,e-r,2,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+s,t-i,e-r+a,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-a,t-i,e+r-s,4,!0),this.v.setTripleAt(t-i+s,e+r,t-i+s,e+r,t-i+a,e+r,5,!0),this.v.setTripleAt(t+i-s,e+r,t+i-a,e+r,t+i-s,e+r,6,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-s,t+i,e+r-a,7,!0)):(this.v.setTripleAt(t-i,e-r,t-i+a,e-r,t-i,e-r,1,!0),this.v.setTripleAt(t-i,e+r,t-i,e+r-a,t-i,e+r,2,!0),this.v.setTripleAt(t+i,e+r,t+i-a,e+r,t+i,e+r,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:a},extendPrototype([DynamicPropertyContainer],t),t}();var f={getShapeProp:function(t,e,i){var r;return 3===i||4===i?r=(3===i?e.pt:e.ks).k.length?new o(t,e,i):new n(t,e,i):5===i?r=new p(t,e):6===i?r=new h(t,e):7===i&&(r=new l(t,e)),r.k&&t.addDynamicProperty(r),r},getConstructorFunction:function(){return n},getKeyframedConstructorFunction:function(){return o}};return f}(),Matrix=function(){var s=Math.cos,a=Math.sin,n=Math.tan,r=Math.round;function t(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function e(t){if(0===t)return this;var e=s(t),i=a(t);return this._t(e,-i,0,0,i,e,0,0,0,0,1,0,0,0,0,1)}function i(t){if(0===t)return this;var e=s(t),i=a(t);return this._t(1,0,0,0,0,e,-i,0,0,i,e,0,0,0,0,1)}function o(t){if(0===t)return this;var e=s(t),i=a(t);return this._t(e,0,i,0,0,1,0,0,-i,0,e,0,0,0,0,1)}function h(t){if(0===t)return this;var e=s(t),i=a(t);return this._t(e,-i,0,0,i,e,0,0,0,0,1,0,0,0,0,1)}function l(t,e){return this._t(1,e,t,1,0,0)}function p(t,e){return this.shear(n(t),n(e))}function f(t,e){var i=s(e),r=a(e);return this._t(i,r,0,0,-r,i,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,n(t),1,0,0,0,0,1,0,0,0,0,1)._t(i,-r,0,0,r,i,0,0,0,0,1,0,0,0,0,1)}function m(t,e,i){return i||0===i||(i=1),1===t&&1===e&&1===i?this:this._t(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1)}function c(t,e,i,r,s,a,n,o,h,l,p,f,m,c,d,u){return this.props[0]=t,this.props[1]=e,this.props[2]=i,this.props[3]=r,this.props[4]=s,this.props[5]=a,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=l,this.props[10]=p,this.props[11]=f,this.props[12]=m,this.props[13]=c,this.props[14]=d,this.props[15]=u,this}function d(t,e,i){return i=i||0,0!==t||0!==e||0!==i?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,i,1):this}function u(t,e,i,r,s,a,n,o,h,l,p,f,m,c,d,u){var y=this.props;if(1===t&&0===e&&0===i&&0===r&&0===s&&1===a&&0===n&&0===o&&0===h&&0===l&&1===p&&0===f)return y[12]=y[12]*t+y[15]*m,y[13]=y[13]*a+y[15]*c,y[14]=y[14]*p+y[15]*d,y[15]*=u,this._identityCalculated=!1,this;var g=y[0],v=y[1],b=y[2],x=y[3],P=y[4],E=y[5],S=y[6],C=y[7],_=y[8],A=y[9],T=y[10],M=y[11],k=y[12],D=y[13],F=y[14],w=y[15];return y[0]=g*t+v*s+b*h+x*m,y[1]=g*e+v*a+b*l+x*c,y[2]=g*i+v*n+b*p+x*d,y[3]=g*r+v*o+b*f+x*u,y[4]=P*t+E*s+S*h+C*m,y[5]=P*e+E*a+S*l+C*c,y[6]=P*i+E*n+S*p+C*d,y[7]=P*r+E*o+S*f+C*u,y[8]=_*t+A*s+T*h+M*m,y[9]=_*e+A*a+T*l+M*c,y[10]=_*i+A*n+T*p+M*d,y[11]=_*r+A*o+T*f+M*u,y[12]=k*t+D*s+F*h+w*m,y[13]=k*e+D*a+F*l+w*c,y[14]=k*i+D*n+F*p+w*d,y[15]=k*r+D*o+F*f+w*u,this._identityCalculated=!1,this}function y(t){var e=t.props;return this.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}function g(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function v(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function b(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function x(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function P(t,e,i){return{x:t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}}function E(t,e,i){return t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12]}function S(t,e,i){return t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13]}function C(t,e,i){return t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}function _(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,i=-this.props[1]/t,r=-this.props[4]/t,s=this.props[0]/t,a=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,n=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,o=new Matrix;return o.props[0]=e,o.props[1]=i,o.props[4]=r,o.props[5]=s,o.props[12]=a,o.props[13]=n,o}function A(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function T(t){var e,i=t.length,r=[];for(e=0;e<i;e+=1)r[e]=A(t[e]);return r}function M(t,e,i){var r=createTypedArray("float32",6);if(this.isIdentity())r[0]=t[0],r[1]=t[1],r[2]=e[0],r[3]=e[1],r[4]=i[0],r[5]=i[1];else{var s=this.props[0],a=this.props[1],n=this.props[4],o=this.props[5],h=this.props[12],l=this.props[13];r[0]=t[0]*s+t[1]*n+h,r[1]=t[0]*a+t[1]*o+l,r[2]=e[0]*s+e[1]*n+h,r[3]=e[0]*a+e[1]*o+l,r[4]=i[0]*s+i[1]*n+h,r[5]=i[0]*a+i[1]*o+l}return r}function k(t,e,i){return this.isIdentity()?[t,e,i]:[t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]]}function D(t,e){if(this.isIdentity())return t+","+e;var i=this.props;return Math.round(100*(t*i[0]+e*i[4]+i[12]))/100+","+Math.round(100*(t*i[1]+e*i[5]+i[13]))/100}function F(){for(var t=0,e=this.props,i="matrix3d(";t<16;)i+=r(1e4*e[t])/1e4,i+=15===t?")":",",t+=1;return i}function w(t){return t<1e-6&&0<t||-1e-6<t&&t<0?r(1e4*t)/1e4:t}function I(){var t=this.props;return"matrix("+w(t[0])+","+w(t[1])+","+w(t[4])+","+w(t[5])+","+w(t[12])+","+w(t[13])+")"}return function(){this.reset=t,this.rotate=e,this.rotateX=i,this.rotateY=o,this.rotateZ=h,this.skew=p,this.skewFromAxis=f,this.shear=l,this.scale=m,this.setTransform=c,this.translate=d,this.transform=u,this.multiply=y,this.applyToPoint=P,this.applyToX=E,this.applyToY=S,this.applyToZ=C,this.applyToPointArray=k,this.applyToTriplePoints=M,this.applyToPointStringified=D,this.toCSS=F,this.to2dCSS=I,this.clone=b,this.cloneFromProps=x,this.equals=v,this.inversePoints=T,this.inversePoint=A,this.getInverseMatrix=_,this._t=this.transform,this.isIdentity=g,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}}();function _typeof$3(t){return(_typeof$3="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var lottie={},standalone="__[STANDALONE]__",animationData="__[ANIMATIONDATA]__",renderer="";function setLocation(t){setLocationHref(t)}function searchAnimations(){!0===standalone?animationManager.searchAnimations(animationData,standalone,renderer):animationManager.searchAnimations()}function setSubframeRendering(t){setSubframeEnabled(t)}function setPrefix(t){setIdPrefix(t)}function loadAnimation(t){return!0===standalone&&(t.animationData=JSON.parse(animationData)),animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":setDefaultCurveSegments(200);break;default:case"medium":setDefaultCurveSegments(50);break;case"low":setDefaultCurveSegments(10)}else!isNaN(t)&&1<t&&setDefaultCurveSegments(t);50<=getDefaultCurveSegments()?roundValues(!1):roundValues(!0)}function inBrowser(){return"undefined"!=typeof navigator}function installPlugin(t,e){"expressions"===t&&setExpressionsPlugin(e)}function getFactory(t){switch(t){case"propertyFactory":return PropertyFactory;case"shapePropertyFactory":return ShapePropertyFactory;case"matrix":return Matrix;default:return null}}function checkReady(){"complete"===document.readyState&&(clearInterval(readyStateCheckInterval),searchAnimations())}function getQueryVariable(t){for(var e=queryString.split("&"),i=0;i<e.length;i+=1){var r=e[i].split("=");if(decodeURIComponent(r[0])==t)return decodeURIComponent(r[1])}return null}lottie.play=animationManager.play,lottie.pause=animationManager.pause,lottie.setLocationHref=setLocation,lottie.togglePause=animationManager.togglePause,lottie.setSpeed=animationManager.setSpeed,lottie.setDirection=animationManager.setDirection,lottie.stop=animationManager.stop,lottie.searchAnimations=searchAnimations,lottie.registerAnimation=animationManager.registerAnimation,lottie.loadAnimation=loadAnimation,lottie.setSubframeRendering=setSubframeRendering,lottie.resize=animationManager.resize,lottie.goToAndStop=animationManager.goToAndStop,lottie.destroy=animationManager.destroy,lottie.setQuality=setQuality,lottie.inBrowser=inBrowser,lottie.installPlugin=installPlugin,lottie.freeze=animationManager.freeze,lottie.unfreeze=animationManager.unfreeze,lottie.setVolume=animationManager.setVolume,lottie.mute=animationManager.mute,lottie.unmute=animationManager.unmute,lottie.getRegisteredAnimations=animationManager.getRegisteredAnimations,lottie.useWebWorker=setWebWorker,lottie.setIDPrefix=setPrefix,lottie.__getFactory=getFactory,lottie.version="5.12.2";var queryString="";if(standalone){var scripts=document.getElementsByTagName("script"),index=scripts.length-1,myScript=scripts[index]||{src:""};queryString=myScript.src?myScript.src.replace(/^[^\?]+\??/,""):"",renderer=getQueryVariable("renderer")}var readyStateCheckInterval=setInterval(checkReady,100);try{"object"===("undefined"==typeof exports?"undefined":_typeof$3(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=lottie)}catch(t){}var ShapeModifiers=(ly={},my={},ly.registerModifier=function(t,e){my[t]||(my[t]=e)},ly.getModifier=function(t,e,i){return new my[t](e,i)},ly),ly,my;function ShapeModifier(){}function TrimModifier(){}function PuckerAndBloatModifier(){}ShapeModifier.prototype.initModifierProperties=function(){},ShapeModifier.prototype.addShapeToModifier=function(){},ShapeModifier.prototype.addShape=function(t){if(!this.closed){t.sh.container.addDynamicProperty(t.sh);var e={shape:t.sh,data:t,localShapeCollection:shapeCollectionPool.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},ShapeModifier.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=initialDefaultFrame,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},ShapeModifier.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},extendPrototype([DynamicPropertyContainer],ShapeModifier),extendPrototype([ShapeModifier],TrimModifier),TrimModifier.prototype.initModifierProperties=function(t,e){this.s=PropertyFactory.getProp(t,e.s,0,.01,this),this.e=PropertyFactory.getProp(t,e.e,0,.01,this),this.o=PropertyFactory.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},TrimModifier.prototype.addShapeToModifier=function(t){t.pathsData=[]},TrimModifier.prototype.calculateShapeEdges=function(t,e,i,r,s){var a=[];e<=1?a.push({s:t,e:e}):1<=t?a.push({s:t-1,e:e-1}):(a.push({s:t,e:1}),a.push({s:0,e:e-1}));var n,o,h=[],l=a.length;for(n=0;n<l;n+=1){var p,f;if(!((o=a[n]).e*s<r||o.s*s>r+i))p=o.s*s<=r?0:(o.s*s-r)/i,f=o.e*s>=r+i?1:(o.e*s-r)/i,h.push([p,f])}return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){var e,i=t.length;for(e=0;e<i;e+=1)segmentsLengthPool.release(t[e]);return t.length=0,t},TrimModifier.prototype.processShapes=function(t){var e,i,r,s;if(this._mdf||t){var a=this.o.v%360/360;if(a<0&&(a+=1),e=1<this.s.v?1+a:this.s.v<0?0+a:this.s.v+a,(i=1<this.e.v?1+a:this.e.v<0?0+a:this.e.v+a)<e){var n=e;e=i,i=n}e=1e-4*Math.round(1e4*e),i=1e-4*Math.round(1e4*i),this.sValue=e,this.eValue=i}else e=this.sValue,i=this.eValue;var o,h,l,p,f,m=this.shapes.length,c=0;if(i===e)for(s=0;s<m;s+=1)this.shapes[s].localShapeCollection.releaseShapes(),this.shapes[s].shape._mdf=!0,this.shapes[s].shape.paths=this.shapes[s].localShapeCollection,this._mdf&&(this.shapes[s].pathsData.length=0);else if(1===i&&0===e||0===i&&1===e){if(this._mdf)for(s=0;s<m;s+=1)this.shapes[s].pathsData.length=0,this.shapes[s].shape._mdf=!0}else{var d,u,y=[];for(s=0;s<m;s+=1)if((d=this.shapes[s]).shape._mdf||this._mdf||t||2===this.m){if(h=(r=d.shape.paths)._length,f=0,!d.shape._mdf&&d.pathsData.length)f=d.totalShapeLength;else{for(l=this.releasePathsData(d.pathsData),o=0;o<h;o+=1)p=bez.getSegmentsLength(r.shapes[o]),l.push(p),f+=p.totalLength;d.totalShapeLength=f,d.pathsData=l}c+=f,d.shape._mdf=!0}else d.shape.paths=d.localShapeCollection;var g,v=e,b=i,x=0;for(s=m-1;0<=s;s-=1)if((d=this.shapes[s]).shape._mdf){for((u=d.localShapeCollection).releaseShapes(),2===this.m&&1<m?(g=this.calculateShapeEdges(e,i,d.totalShapeLength,x,c),x+=d.totalShapeLength):g=[[v,b]],h=g.length,o=0;o<h;o+=1){v=g[o][0],b=g[o][1],y.length=0,b<=1?y.push({s:d.totalShapeLength*v,e:d.totalShapeLength*b}):1<=v?y.push({s:d.totalShapeLength*(v-1),e:d.totalShapeLength*(b-1)}):(y.push({s:d.totalShapeLength*v,e:d.totalShapeLength}),y.push({s:0,e:d.totalShapeLength*(b-1)}));var P=this.addShapes(d,y[0]);if(y[0].s!==y[0].e){if(1<y.length)if(d.shape.paths.shapes[d.shape.paths._length-1].c){var E=P.pop();this.addPaths(P,u),P=this.addShapes(d,y[1],E)}else this.addPaths(P,u),P=this.addShapes(d,y[1]);this.addPaths(P,u)}}d.shape.paths=u}}},TrimModifier.prototype.addPaths=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)e.addShape(t[i])},TrimModifier.prototype.addSegment=function(t,e,i,r,s,a,n){s.setXYAt(e[0],e[1],"o",a),s.setXYAt(i[0],i[1],"i",a+1),n&&s.setXYAt(t[0],t[1],"v",a),s.setXYAt(r[0],r[1],"v",a+1)},TrimModifier.prototype.addSegmentFromArray=function(t,e,i,r){e.setXYAt(t[1],t[5],"o",i),e.setXYAt(t[2],t[6],"i",i+1),r&&e.setXYAt(t[0],t[4],"v",i),e.setXYAt(t[3],t[7],"v",i+1)},TrimModifier.prototype.addShapes=function(t,e,i){var r,s,a,n,o,h,l,p,f=t.pathsData,m=t.shape.paths.shapes,c=t.shape.paths._length,d=0,u=[],y=!0;for(p=i?(o=i._length,i._length):(i=shapePool.newElement(),o=0),u.push(i),r=0;r<c;r+=1){for(h=f[r].lengths,i.c=m[r].c,a=m[r].c?h.length:h.length+1,s=1;s<a;s+=1)if(d+(n=h[s-1]).addedLength<e.s)d+=n.addedLength,i.c=!1;else{if(d>e.e){i.c=!1;break}e.s<=d&&e.e>=d+n.addedLength?(this.addSegment(m[r].v[s-1],m[r].o[s-1],m[r].i[s],m[r].v[s],i,o,y),y=!1):(l=bez.getNewSegment(m[r].v[s-1],m[r].v[s],m[r].o[s-1],m[r].i[s],(e.s-d)/n.addedLength,(e.e-d)/n.addedLength,h[s-1]),this.addSegmentFromArray(l,i,o,y),y=!1,i.c=!1),d+=n.addedLength,o+=1}if(m[r].c&&h.length){if(n=h[s-1],d<=e.e){var g=h[s-1].addedLength;e.s<=d&&e.e>=d+g?(this.addSegment(m[r].v[s-1],m[r].o[s-1],m[r].i[0],m[r].v[0],i,o,y),y=!1):(l=bez.getNewSegment(m[r].v[s-1],m[r].v[0],m[r].o[s-1],m[r].i[0],(e.s-d)/g,(e.e-d)/g,h[s-1]),this.addSegmentFromArray(l,i,o,y),y=!1,i.c=!1)}else i.c=!1;d+=n.addedLength,o+=1}if(i._length&&(i.setXYAt(i.v[p][0],i.v[p][1],"i",p),i.setXYAt(i.v[i._length-1][0],i.v[i._length-1][1],"o",i._length-1)),d>e.e)break;r<c-1&&(i=shapePool.newElement(),y=!0,u.push(i),o=0)}return u},extendPrototype([ShapeModifier],PuckerAndBloatModifier),PuckerAndBloatModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},PuckerAndBloatModifier.prototype.processPath=function(t,e){var i=e/100,r=[0,0],s=t._length,a=0;for(a=0;a<s;a+=1)r[0]+=t.v[a][0],r[1]+=t.v[a][1];r[0]/=s,r[1]/=s;var n,o,h,l,p,f,m=shapePool.newElement();for(m.c=t.c,a=0;a<s;a+=1)n=t.v[a][0]+(r[0]-t.v[a][0])*i,o=t.v[a][1]+(r[1]-t.v[a][1])*i,h=t.o[a][0]+(r[0]-t.o[a][0])*-i,l=t.o[a][1]+(r[1]-t.o[a][1])*-i,p=t.i[a][0]+(r[0]-t.i[a][0])*-i,f=t.i[a][1]+(r[1]-t.i[a][1])*-i,m.setTripleAt(n,o,h,l,p,f,a);return m},PuckerAndBloatModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amount.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var TransformPropertyFactory=function(){var n=[0,0];function r(t,e,i){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Matrix,this.pre=new Matrix,this.appliedTransformations=0,this.initDynamicPropertyContainer(i||t),e.p&&e.p.s?(this.px=PropertyFactory.getProp(t,e.p.x,0,0,this),this.py=PropertyFactory.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=PropertyFactory.getProp(t,e.p.z,0,0,this))):this.p=PropertyFactory.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=PropertyFactory.getProp(t,e.rx,0,degToRads,this),this.ry=PropertyFactory.getProp(t,e.ry,0,degToRads,this),this.rz=PropertyFactory.getProp(t,e.rz,0,degToRads,this),e.or.k[0].ti){var r,s=e.or.k.length;for(r=0;r<s;r+=1)e.or.k[r].to=null,e.or.k[r].ti=null}this.or=PropertyFactory.getProp(t,e.or,1,degToRads,this),this.or.sh=!0}else this.r=PropertyFactory.getProp(t,e.r||{k:0},0,degToRads,this);e.sk&&(this.sk=PropertyFactory.getProp(t,e.sk,0,degToRads,this),this.sa=PropertyFactory.getProp(t,e.sa,0,degToRads,this)),this.a=PropertyFactory.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=PropertyFactory.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=PropertyFactory.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return r.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(t){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||t){var e;if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var i,r;if(e=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime)r=this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(i=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/e,0),this.p.getValueAtTime(this.p.keyframes[0].t/e,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(i=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/e,0),this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/e,0)):(i=this.p.pv,this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/e,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){i=[],r=[];var s=this.px,a=this.py;s._caching.lastFrame+s.offsetTime<=s.keyframes[0].t?(i[0]=s.getValueAtTime((s.keyframes[0].t+.01)/e,0),i[1]=a.getValueAtTime((a.keyframes[0].t+.01)/e,0),r[0]=s.getValueAtTime(s.keyframes[0].t/e,0),r[1]=a.getValueAtTime(a.keyframes[0].t/e,0)):s._caching.lastFrame+s.offsetTime>=s.keyframes[s.keyframes.length-1].t?(i[0]=s.getValueAtTime(s.keyframes[s.keyframes.length-1].t/e,0),i[1]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/e,0),r[0]=s.getValueAtTime((s.keyframes[s.keyframes.length-1].t-.01)/e,0),r[1]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/e,0)):(i=[s.pv,a.pv],r[0]=s.getValueAtTime((s._caching.lastFrame+s.offsetTime-.01)/e,s.offsetTime),r[1]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/e,a.offsetTime))}else i=r=n;this.v.rotate(-Math.atan2(i[1]-r[1],i[0]-r[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],r),r.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},r.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,e,i){return new r(t,e,i)}}}();function RepeaterModifier(){}function RoundCornersModifier(){}function floatEqual(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function floatZero(t){return Math.abs(t)<=1e-5}function lerp(t,e,i){return t*(1-i)+e*i}function lerpPoint(t,e,i){return[lerp(t[0],e[0],i),lerp(t[1],e[1],i)]}function quadRoots(t,e,i){if(0===t)return[];var r=e*e-4*t*i;if(r<0)return[];var s=-e/(2*t);if(0===r)return[s];var a=Math.sqrt(r)/(2*t);return[s-a,s+a]}function polynomialCoefficients(t,e,i,r){return[3*e-t-3*i+r,3*t-6*e+3*i,-3*t+3*e,t]}function singlePoint(t){return new PolynomialBezier(t,t,t,t,!1)}function PolynomialBezier(t,e,i,r,s){s&&pointEqual(t,e)&&(e=lerpPoint(t,r,1/3)),s&&pointEqual(i,r)&&(i=lerpPoint(t,r,2/3));var a=polynomialCoefficients(t[0],e[0],i[0],r[0]),n=polynomialCoefficients(t[1],e[1],i[1],r[1]);this.a=[a[0],n[0]],this.b=[a[1],n[1]],this.c=[a[2],n[2]],this.d=[a[3],n[3]],this.points=[t,e,i,r]}function extrema(t,e){var i=t.points[0][e],r=t.points[t.points.length-1][e];if(r<i){var s=r;r=i,i=s}for(var a=quadRoots(3*t.a[e],2*t.b[e],t.c[e]),n=0;n<a.length;n+=1)if(0<a[n]&&a[n]<1){var o=t.point(a[n])[e];o<i?i=o:r<o&&(r=o)}return{min:i,max:r}}function intersectData(t,e,i){var r=t.boundingBox();return{cx:r.cx,cy:r.cy,width:r.width,height:r.height,bez:t,t:(e+i)/2,t1:e,t2:i}}function splitData(t){var e=t.bez.split(.5);return[intersectData(e[0],t.t1,t.t),intersectData(e[1],t.t,t.t2)]}function boxIntersect(t,e){return 2*Math.abs(t.cx-e.cx)<t.width+e.width&&2*Math.abs(t.cy-e.cy)<t.height+e.height}function intersectsImpl(t,e,i,r,s,a){if(boxIntersect(t,e))if(a<=i||t.width<=r&&t.height<=r&&e.width<=r&&e.height<=r)s.push([t.t,e.t]);else{var n=splitData(t),o=splitData(e);intersectsImpl(n[0],o[0],i+1,r,s,a),intersectsImpl(n[0],o[1],i+1,r,s,a),intersectsImpl(n[1],o[0],i+1,r,s,a),intersectsImpl(n[1],o[1],i+1,r,s,a)}}function crossProduct(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function lineIntersection(t,e,i,r){var s=[t[0],t[1],1],a=[e[0],e[1],1],n=[i[0],i[1],1],o=[r[0],r[1],1],h=crossProduct(crossProduct(s,a),crossProduct(n,o));return floatZero(h[2])?null:[h[0]/h[2],h[1]/h[2]]}function polarOffset(t,e,i){return[t[0]+Math.cos(e)*i,t[1]-Math.sin(e)*i]}function pointDistance(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function pointEqual(t,e){return floatEqual(t[0],e[0])&&floatEqual(t[1],e[1])}function ZigZagModifier(){}function setPoint(t,e,i,r,s,a,n){var o=i-Math.PI/2,h=i+Math.PI/2,l=e[0]+Math.cos(i)*r*s,p=e[1]-Math.sin(i)*r*s;t.setTripleAt(l,p,l+Math.cos(o)*a,p-Math.sin(o)*a,l+Math.cos(h)*n,p-Math.sin(h)*n,t.length())}function getPerpendicularVector(t,e){var i=[e[0]-t[0],e[1]-t[1]],r=.5*-Math.PI;return[Math.cos(r)*i[0]-Math.sin(r)*i[1],Math.sin(r)*i[0]+Math.cos(r)*i[1]]}function getProjectingAngle(t,e){var i=0===e?t.length()-1:e-1,r=(e+1)%t.length(),s=getPerpendicularVector(t.v[i],t.v[r]);return Math.atan2(0,1)-Math.atan2(s[1],s[0])}function zigZagCorner(t,e,i,r,s,a,n){var o=getProjectingAngle(e,i),h=e.v[i%e._length],l=e.v[0===i?e._length-1:i-1],p=e.v[(i+1)%e._length],f=2===a?Math.sqrt(Math.pow(h[0]-l[0],2)+Math.pow(h[1]-l[1],2)):0,m=2===a?Math.sqrt(Math.pow(h[0]-p[0],2)+Math.pow(h[1]-p[1],2)):0;setPoint(t,e.v[i%e._length],o,n,r,m/(2*(s+1)),f/(2*(s+1)),a)}function zigZagSegment(t,e,i,r,s,a){for(var n=0;n<r;n+=1){var o=(n+1)/(r+1),h=2===s?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(o);setPoint(t,e.point(o),l,a,i,h/(2*(r+1)),h/(2*(r+1)),s),a=-a}return a}function linearOffset(t,e,i){var r=Math.atan2(e[0]-t[0],e[1]-t[1]);return[polarOffset(t,r,i),polarOffset(e,r,i)]}function offsetSegment(t,e){var i,r,s,a,n,o,h;i=(h=linearOffset(t.points[0],t.points[1],e))[0],r=h[1],s=(h=linearOffset(t.points[1],t.points[2],e))[0],a=h[1],n=(h=linearOffset(t.points[2],t.points[3],e))[0],o=h[1];var l=lineIntersection(i,r,s,a);null===l&&(l=r);var p=lineIntersection(n,o,s,a);return null===p&&(p=n),new PolynomialBezier(i,l,p,o)}function joinLines(t,e,i,r,s){var a=e.points[3],n=i.points[0];if(3===r)return a;if(pointEqual(a,n))return a;if(2===r){var o=-e.tangentAngle(1),h=-i.tangentAngle(0)+Math.PI,l=lineIntersection(a,polarOffset(a,o+Math.PI/2,100),n,polarOffset(n,o+Math.PI/2,100)),p=l?pointDistance(l,a):pointDistance(a,n)/2,f=polarOffset(a,o,2*p*roundCorner);return t.setXYAt(f[0],f[1],"o",t.length()-1),f=polarOffset(n,h,2*p*roundCorner),t.setTripleAt(n[0],n[1],n[0],n[1],f[0],f[1],t.length()),n}var m=lineIntersection(pointEqual(a,e.points[2])?e.points[0]:e.points[2],a,n,pointEqual(n,i.points[1])?i.points[3]:i.points[1]);return m&&pointDistance(m,a)<s?(t.setTripleAt(m[0],m[1],m[0],m[1],m[0],m[1],t.length()),m):a}function getIntersection(t,e){var i=t.intersections(e);return i.length&&floatEqual(i[0][0],1)&&i.shift(),i.length?i[0]:null}function pruneSegmentIntersection(t,e){var i=t.slice(),r=e.slice(),s=getIntersection(t[t.length-1],e[0]);return s&&(i[t.length-1]=t[t.length-1].split(s[0])[0],r[0]=e[0].split(s[1])[1]),1<t.length&&1<e.length&&(s=getIntersection(t[0],e[e.length-1]))?[[t[0].split(s[0])[0]],[e[e.length-1].split(s[1])[1]]]:[i,r]}function pruneIntersections(t){for(var e,i=1;i<t.length;i+=1)e=pruneSegmentIntersection(t[i-1],t[i]),t[i-1]=e[0],t[i]=e[1];return 1<t.length&&(e=pruneSegmentIntersection(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}function offsetSegmentSplit(t,e){var i,r,s,a,n=t.inflectionPoints();if(0===n.length)return[offsetSegment(t,e)];if(1===n.length||floatEqual(n[1],1))return i=(s=t.split(n[0]))[0],r=s[1],[offsetSegment(i,e),offsetSegment(r,e)];i=(s=t.split(n[0]))[0];var o=(n[1]-n[0])/(1-n[0]);return a=(s=s[1].split(o))[0],r=s[1],[offsetSegment(i,e),offsetSegment(a,e),offsetSegment(r,e)]}function OffsetPathModifier(){}function getFontProperties(t){for(var e=t.fStyle?t.fStyle.split(" "):[],i="normal",r="normal",s=e.length,a=0;a<s;a+=1)switch(e[a].toLowerCase()){case"italic":r="italic";break;case"bold":i="700";break;case"black":i="900";break;case"medium":i="500";break;case"regular":case"normal":i="400";break;case"light":case"thin":i="200"}return{style:r,weight:t.fWeight||i}}extendPrototype([ShapeModifier],RepeaterModifier),RepeaterModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=PropertyFactory.getProp(t,e.c,0,null,this),this.o=PropertyFactory.getProp(t,e.o,0,null,this),this.tr=TransformPropertyFactory.getTransformProperty(t,e.tr,this),this.so=PropertyFactory.getProp(t,e.tr.so,0,.01,this),this.eo=PropertyFactory.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Matrix,this.rMatrix=new Matrix,this.sMatrix=new Matrix,this.tMatrix=new Matrix,this.matrix=new Matrix},RepeaterModifier.prototype.applyTransforms=function(t,e,i,r,s,a){var n=a?-1:1,o=r.s.v[0]+(1-r.s.v[0])*(1-s),h=r.s.v[1]+(1-r.s.v[1])*(1-s);t.translate(r.p.v[0]*n*s,r.p.v[1]*n*s,r.p.v[2]),e.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),e.rotate(-r.r.v*n*s),e.translate(r.a.v[0],r.a.v[1],r.a.v[2]),i.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),i.scale(a?1/o:o,a?1/h:h),i.translate(r.a.v[0],r.a.v[1],r.a.v[2])},RepeaterModifier.prototype.init=function(t,e,i,r){for(this.elem=t,this.arr=e,this.pos=i,this.elemsData=r,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[i]);0<i;)i-=1,this._elements.unshift(e[i]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},RepeaterModifier.prototype.cloneElements=function(t){var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},RepeaterModifier.prototype.changeGroupRender=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)t[i]._render=e,"gr"===t[i].ty&&this.changeGroupRender(t[i].it,e)},RepeaterModifier.prototype.processShapes=function(t){var e,i,r,s,a,n=!1;if(this._mdf||t){var o,h=Math.ceil(this.c.v);if(this._groups.length<h){for(;this._groups.length<h;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(r=a=0;r<=this._groups.length-1;r+=1){if(o=a<h,this._groups[r]._render=o,this.changeGroupRender(this._groups[r].it,o),!o){var p=this.elemsData[r].it,f=p[p.length-1];0!==f.transform.op.v?(f.transform.op._mdf=!0,f.transform.op.v=0):f.transform.op._mdf=!1}a+=1}this._currentCopies=h;var m=this.o.v,c=m%1,d=0<m?Math.floor(m):Math.ceil(m),u=this.pMatrix.props,y=this.rMatrix.props,g=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var v,b,x=0;if(0<m){for(;x<d;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),x+=1;c&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,c,!1),x+=c)}else if(m<0){for(;d<x;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),x-=1;c&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-c,!0),x-=c)}for(r=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(b=(i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(r/(this._currentCopies-1)),0!==x){for((0!==r&&1===s||r!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]),this.matrix.transform(u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]),v=0;v<b;v+=1)i[v]=this.matrix.props[v];this.matrix.reset()}else for(this.matrix.reset(),v=0;v<b;v+=1)i[v]=this.matrix.props[v];x+=1,a-=1,r+=s}}else for(a=this._currentCopies,r=0,s=1;a;)i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,a-=1,r+=s;return n},RepeaterModifier.prototype.addShape=function(){},extendPrototype([ShapeModifier],RoundCornersModifier),RoundCornersModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=PropertyFactory.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},RoundCornersModifier.prototype.processPath=function(t,e){var i,r=shapePool.newElement();r.c=t.c;var s,a,n,o,h,l,p,f,m,c,d,u,y=t._length,g=0;for(i=0;i<y;i+=1)s=t.v[i],n=t.o[i],a=t.i[i],s[0]===n[0]&&s[1]===n[1]&&s[0]===a[0]&&s[1]===a[1]?0!==i&&i!==y-1||t.c?(o=0===i?t.v[y-1]:t.v[i-1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=d=s[0]+(o[0]-s[0])*l,f=u=s[1]-(s[1]-o[1])*l,m=p-(p-s[0])*roundCorner,c=f-(f-s[1])*roundCorner,r.setTripleAt(p,f,m,c,d,u,g),g+=1,o=i===y-1?t.v[0]:t.v[i+1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=m=s[0]+(o[0]-s[0])*l,f=c=s[1]+(o[1]-s[1])*l,d=p-(p-s[0])*roundCorner,u=f-(f-s[1])*roundCorner,r.setTripleAt(p,f,m,c,d,u,g)):r.setTripleAt(s[0],s[1],n[0],n[1],a[0],a[1],g):r.setTripleAt(t.v[i][0],t.v[i][1],t.o[i][0],t.o[i][1],t.i[i][0],t.i[i][1],g),g+=1;return r},RoundCornersModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},PolynomialBezier.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},PolynomialBezier.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},PolynomialBezier.prototype.tangentAngle=function(t){var e=this.derivative(t);return Math.atan2(e[1],e[0])},PolynomialBezier.prototype.normalAngle=function(t){var e=this.derivative(t);return Math.atan2(e[0],e[1])},PolynomialBezier.prototype.inflectionPoints=function(){var t=this.a[1]*this.b[0]-this.a[0]*this.b[1];if(floatZero(t))return[];var e=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/t,i=e*e-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/t;if(i<0)return[];var r=Math.sqrt(i);return floatZero(r)?0<r&&r<1?[e]:[]:[e-r,e+r].filter(function(t){return 0<t&&t<1})},PolynomialBezier.prototype.split=function(t){if(t<=0)return[singlePoint(this.points[0]),this];if(1<=t)return[this,singlePoint(this.points[this.points.length-1])];var e=lerpPoint(this.points[0],this.points[1],t),i=lerpPoint(this.points[1],this.points[2],t),r=lerpPoint(this.points[2],this.points[3],t),s=lerpPoint(e,i,t),a=lerpPoint(i,r,t),n=lerpPoint(s,a,t);return[new PolynomialBezier(this.points[0],e,s,n,!0),new PolynomialBezier(n,a,r,this.points[3],!0)]},PolynomialBezier.prototype.bounds=function(){return{x:extrema(this,0),y:extrema(this,1)}},PolynomialBezier.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},PolynomialBezier.prototype.intersections=function(t,e,i){void 0===e&&(e=2),void 0===i&&(i=7);var r=[];return intersectsImpl(intersectData(this,0,1),intersectData(t,0,1),0,e,r,i),r},PolynomialBezier.shapeSegment=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[e],t.o[e],t.i[i],t.v[i],!0)},PolynomialBezier.shapeSegmentInverted=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[i],t.i[i],t.o[e],t.v[e],!0)},extendPrototype([ShapeModifier],ZigZagModifier),ZigZagModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=PropertyFactory.getProp(t,e.s,0,null,this),this.frequency=PropertyFactory.getProp(t,e.r,0,null,this),this.pointsType=PropertyFactory.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},ZigZagModifier.prototype.processPath=function(t,e,i,r){var s=t._length,a=shapePool.newElement();if(a.c=t.c,t.c||(s-=1),0===s)return a;var n=-1,o=PolynomialBezier.shapeSegment(t,0);zigZagCorner(a,t,0,e,i,r,n);for(var h=0;h<s;h+=1)n=zigZagSegment(a,o,e,i,r,-n),o=h!==s-1||t.c?PolynomialBezier.shapeSegment(t,(h+1)%s):null,zigZagCorner(a,t,h+1,e,i,r,n);return a},ZigZagModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amplitude.v,l=Math.max(0,Math.round(this.frequency.v)),p=this.pointsType.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h,l,p));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},extendPrototype([ShapeModifier],OffsetPathModifier),OffsetPathModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this.miterLimit=PropertyFactory.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},OffsetPathModifier.prototype.processPath=function(t,e,i,r){var s=shapePool.newElement();s.c=t.c;var a,n,o,h=t.length();t.c||(h-=1);var l=[];for(a=0;a<h;a+=1)o=PolynomialBezier.shapeSegment(t,a),l.push(offsetSegmentSplit(o,e));if(!t.c)for(a=h-1;0<=a;a-=1)o=PolynomialBezier.shapeSegmentInverted(t,a),l.push(offsetSegmentSplit(o,e));l=pruneIntersections(l);var p=null,f=null;for(a=0;a<l.length;a+=1){var m=l[a];for(f&&(p=joinLines(s,f,m[0],i,r)),f=m[m.length-1],n=0;n<m.length;n+=1)o=m[n],p&&pointEqual(o.points[0],p)?s.setXYAt(o.points[1][0],o.points[1][1],"o",s.length()-1):s.setTripleAt(o.points[0][0],o.points[0][1],o.points[1][0],o.points[1][1],o.points[0][0],o.points[0][1],s.length()),s.setTripleAt(o.points[3][0],o.points[3][1],o.points[3][0],o.points[3][1],o.points[2][0],o.points[2][1],s.length()),p=o.points[3]}return l.length&&joinLines(s,f,l[0][0],i,r),s},OffsetPathModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amount.v,l=this.miterLimit.v,p=this.lineJoin;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h,p,l));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var FontManager=function(){var a={w:0,size:0,shapes:[],data:{shapes:[]}},e=[];e=e.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);var i=127462,r=127487,s=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function m(t,e){var i=createTag("span");i.setAttribute("aria-hidden",!0),i.style.fontFamily=e;var r=createTag("span");r.innerText="giItT1WQy@!-/#",i.style.position="absolute",i.style.left="-10000px",i.style.top="-10000px",i.style.fontSize="300px",i.style.fontVariant="normal",i.style.fontStyle="normal",i.style.fontWeight="normal",i.style.letterSpacing="0",i.appendChild(r),document.body.appendChild(i);var s=r.offsetWidth;return r.style.fontFamily=function(t){var e,i=t.split(","),r=i.length,s=[];for(e=0;e<r;e+=1)"sans-serif"!==i[e]&&"monospace"!==i[e]&&s.push(i[e]);return s.join(",")}(t)+", "+e,{node:r,w:s,parent:i}}function c(t,e){var i,r=document.body&&e?"svg":"canvas",s=getFontProperties(t);if("svg"===r){var a=createNS("text");a.style.fontSize="100px",a.setAttribute("font-family",t.fFamily),a.setAttribute("font-style",s.style),a.setAttribute("font-weight",s.weight),a.textContent="1",t.fClass?(a.style.fontFamily="inherit",a.setAttribute("class",t.fClass)):a.style.fontFamily=t.fFamily,e.appendChild(a),i=a}else{var n=new OffscreenCanvas(500,500).getContext("2d");n.font=s.style+" "+s.weight+" 100px "+t.fFamily,i=n}return{measureText:function(t){return"svg"===r?(i.textContent=t,i.getComputedTextLength()):i.measureText(t).width}}}function n(t){var e=0,i=t.charCodeAt(0);if(55296<=i&&i<=56319){var r=t.charCodeAt(1);56320<=r&&r<=57343&&(e=1024*(i-55296)+r-56320+65536)}return e}function o(t){var e=n(t);return i<=e&&e<=r}var t=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)};return t.isModifier=function(t,e){var i=t.toString(16)+e.toString(16);return-1!==s.indexOf(i)},t.isZeroWidthJoiner=function(t){return 8205===t},t.isFlagEmoji=function(t){return o(t.substr(0,2))&&o(t.substr(2,2))},t.isRegionalCode=o,t.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},t.isRegionalFlag=function(t,e){var i=n(t.substr(e,2));if(127988!==i)return!1;var r=0;for(e+=2;r<5;){if((i=n(t.substr(e,2)))<917601||917626<i)return!1;r+=1,e+=2}return 917631===n(t.substr(e,2))},t.isVariationSelector=function(t){return 65039===t},t.BLACK_FLAG_CODE_POINT=127988,t.prototype={addChars:function(t){if(t){var e;this.chars||(this.chars=[]);var i,r,s=t.length,a=this.chars.length;for(e=0;e<s;e+=1){for(i=0,r=!1;i<a;)this.chars[i].style===t[e].style&&this.chars[i].fFamily===t[e].fFamily&&this.chars[i].ch===t[e].ch&&(r=!0),i+=1;r||(this.chars.push(t[e]),a+=1)}}},addFonts:function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);if(!document.body)return this.isLoaded=!0,t.list.forEach(function(t){t.helper=c(t),t.cache={}}),void(this.fonts=t.list);var i,r=t.list,s=r.length,a=s;for(i=0;i<s;i+=1){var n,o,h=!0;if(r[i].loaded=!1,r[i].monoCase=m(r[i].fFamily,"monospace"),r[i].sansCase=m(r[i].fFamily,"sans-serif"),r[i].fPath){if("p"===r[i].fOrigin||3===r[i].origin){if(0<(n=document.querySelectorAll('style[f-forigin="p"][f-family="'+r[i].fFamily+'"], style[f-origin="3"][f-family="'+r[i].fFamily+'"]')).length&&(h=!1),h){var l=createTag("style");l.setAttribute("f-forigin",r[i].fOrigin),l.setAttribute("f-origin",r[i].origin),l.setAttribute("f-family",r[i].fFamily),l.type="text/css",l.innerText="@font-face {font-family: "+r[i].fFamily+"; font-style: normal; src: url('"+r[i].fPath+"');}",e.appendChild(l)}}else if("g"===r[i].fOrigin||1===r[i].origin){for(n=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),o=0;o<n.length;o+=1)-1!==n[o].href.indexOf(r[i].fPath)&&(h=!1);if(h){var p=createTag("link");p.setAttribute("f-forigin",r[i].fOrigin),p.setAttribute("f-origin",r[i].origin),p.type="text/css",p.rel="stylesheet",p.href=r[i].fPath,document.body.appendChild(p)}}else if("t"===r[i].fOrigin||2===r[i].origin){for(n=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),o=0;o<n.length;o+=1)r[i].fPath===n[o].src&&(h=!1);if(h){var f=createTag("link");f.setAttribute("f-forigin",r[i].fOrigin),f.setAttribute("f-origin",r[i].origin),f.setAttribute("rel","stylesheet"),f.setAttribute("href",r[i].fPath),e.appendChild(f)}}}else r[i].loaded=!0,a-=1;r[i].helper=c(r[i],e),r[i].cache={},this.fonts.push(r[i])}0===a?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},getCharData:function(t,e,i){for(var r=0,s=this.chars.length;r<s;){if(this.chars[r].ch===t&&this.chars[r].style===e&&this.chars[r].fFamily===i)return this.chars[r];r+=1}return("string"==typeof t&&13!==t.charCodeAt(0)||!t)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",t,e,i)),a},getFontByName:function(t){for(var e=0,i=this.fonts.length;e<i;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,i){var r=this.getFontByName(e),s=t;if(!r.cache[s]){var a=r.helper;if(" "===t){var n=a.measureText("|"+t+"|"),o=a.measureText("||");r.cache[s]=(n-o)/100}else r.cache[s]=a.measureText(t)/100}return r.cache[s]*i},checkLoadedFonts:function(){var t,e,i,r=this.fonts.length,s=r;for(t=0;t<r;t+=1)this.fonts[t].loaded?s-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,i=this.fonts[t].monoCase.w,e.offsetWidth!==i?(s-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,i=this.fonts[t].sansCase.w,e.offsetWidth!==i&&(s-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==s&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}},t}();function SlotManager(t){this.animationData=t}function slotFactory(t){return new SlotManager(t)}function RenderableElement(){}SlotManager.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},RenderableElement.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var getBlendMode=(eJ={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return eJ[t]||""}),eJ;function SliderEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function AngleEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function ColorEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function PointEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function LayerIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function MaskIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function CheckboxEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function NoValueEffect(){this.p={}}function EffectsManager(t,e){var i,r=t.ef||[];this.effectElements=[];var s,a=r.length;for(i=0;i<a;i+=1)s=new GroupEffect(r[i],e),this.effectElements.push(s)}function GroupEffect(t,e){this.init(t,e)}function BaseElement(){}function FrameElement(){}function FootageElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,i)}function AudioElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,i),this._isPlaying=!1,this._canPlay=!1;var r=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(r),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=PropertyFactory.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function BaseRenderer(){}extendPrototype([DynamicPropertyContainer],GroupEffect),GroupEffect.prototype.getValue=GroupEffect.prototype.iterateDynamicProperties,GroupEffect.prototype.init=function(t,e){var i;this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var r,s=this.data.ef.length,a=this.data.ef;for(i=0;i<s;i+=1){switch(r=null,a[i].ty){case 0:r=new SliderEffect(a[i],e,this);break;case 1:r=new AngleEffect(a[i],e,this);break;case 2:r=new ColorEffect(a[i],e,this);break;case 3:r=new PointEffect(a[i],e,this);break;case 4:case 7:r=new CheckboxEffect(a[i],e,this);break;case 10:r=new LayerIndexEffect(a[i],e,this);break;case 11:r=new MaskIndexEffect(a[i],e,this);break;case 5:r=new EffectsManager(a[i],e,this);break;default:r=new NoValueEffect(a[i],e,this)}r&&this.effectElements.push(r)}},BaseElement.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t=getExpressionInterfaces();if(t){var e=t("layer"),i=t("effects"),r=t("shape"),s=t("text"),a=t("comp");this.layerInterface=e(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var n=i.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(n),0===this.data.ty||this.data.xt?this.compInterface=a(this):4===this.data.ty?(this.layerInterface.shapeInterface=r(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=s(this),this.layerInterface.text=this.layerInterface.textInterface)}},setBlendMode:function(){var t=getBlendMode(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,i){this.globalData=e,this.comp=i,this.data=t,this.layerId=createElementID(),this.data.sr||(this.data.sr=1),this.effectsManager=new EffectsManager(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},FrameElement.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var i,r=this.dynamicProperties.length;for(i=0;i<r;i+=1)(e||this._isParent&&"transform"===this.dynamicProperties[i].propType)&&(this.dynamicProperties[i].getValue(),this.dynamicProperties[i]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},FootageElement.prototype.prepareFrame=function(){},extendPrototype([RenderableElement,BaseElement,FrameElement],FootageElement),FootageElement.prototype.getBaseElement=function(){return null},FootageElement.prototype.renderFrame=function(){},FootageElement.prototype.destroy=function(){},FootageElement.prototype.initExpressions=function(){var t=getExpressionInterfaces();if(t){var e=t("footage");this.layerInterface=e(this)}},FootageElement.prototype.getFootageData=function(){return this.footageData},AudioElement.prototype.prepareFrame=function(t){if(this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder)this._currentTime=t/this.data.sr;else{var e=this.tm.v;this._currentTime=e}this._volume=this.lv.v[0];var i=this._volume*this._volumeMultiplier;this._previousVolume!==i&&(this._previousVolume=i,this.audio.volume(i))},extendPrototype([RenderableElement,BaseElement,FrameElement],AudioElement),AudioElement.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||.1<Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek()))&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},AudioElement.prototype.show=function(){},AudioElement.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},AudioElement.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},AudioElement.prototype.resume=function(){this._canPlay=!0},AudioElement.prototype.setRate=function(t){this.audio.rate(t)},AudioElement.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},AudioElement.prototype.getBaseElement=function(){return null},AudioElement.prototype.destroy=function(){},AudioElement.prototype.sourceRectAtTime=function(){},AudioElement.prototype.initExpressions=function(){},BaseRenderer.prototype.checkLayers=function(t){var e,i,r=this.layers.length;for(this.completeLayers=!0,e=r-1;0<=e;e-=1)this.elements[e]||(i=this.layers[e]).ip-i.st<=t-this.layers[e].st&&i.op-i.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t);default:return this.createNull(t)}},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.createAudio=function(t){return new AudioElement(t,this.globalData,this)},BaseRenderer.prototype.createFootage=function(t){return new FootageElement(t,this.globalData,this)},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},BaseRenderer.prototype.includeLayers=function(t){var e;this.completeLayers=!1;var i,r=t.length,s=this.layers.length;for(e=0;e<r;e+=1)for(i=0;i<s;){if(this.layers[i].id===t[e].id){this.layers[i]=t[e];break}i+=1}},BaseRenderer.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},BaseRenderer.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},BaseRenderer.prototype.buildElementParenting=function(t,e,i){for(var r=this.elements,s=this.layers,a=0,n=s.length;a<n;)s[a].ind==e&&(r[a]&&!0!==r[a]?(i.push(r[a]),r[a].setAsParent(),void 0!==s[a].parent?this.buildElementParenting(t,s[a].parent,i):t.setHierarchy(i)):(this.buildItem(a),this.addPendingElement(t))),a+=1},BaseRenderer.prototype.addPendingElement=function(t){this.pendingElements.push(t)},BaseRenderer.prototype.searchExtraCompositions=function(t){var e,i=t.length;for(e=0;e<i;e+=1)if(t[e].xt){var r=this.createComp(t[e]);r.initExpressions(),this.globalData.projectInterface.registerComposition(r)}},BaseRenderer.prototype.getElementById=function(t){var e,i=this.elements.length;for(e=0;e<i;e+=1)if(this.elements[e].data.ind===t)return this.elements[e];return null},BaseRenderer.prototype.getElementByPath=function(t){var e,i=t.shift();if("number"==typeof i)e=this.elements[i];else{var r,s=this.elements.length;for(r=0;r<s;r+=1)if(this.elements[r].data.nm===i){e=this.elements[r];break}}return 0===t.length?e:e.getElementByPath(t)},BaseRenderer.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new FontManager,this.globalData.slotManager=slotFactory(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var effectTypes={TRANSFORM_EFFECT:"transformEFfect"};function TransformElement(){}function MaskElement(t,e,i){this.data=t,this.element=e,this.globalData=i,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var r,s,a=this.globalData.defs,n=this.masksProperties?this.masksProperties.length:0;this.viewData=createSizedArray(n),this.solidPath="";var o,h,l,p,f,m,c=this.masksProperties,d=0,u=[],y=createElementID(),g="clipPath",v="clip-path";for(r=0;r<n;r+=1)if(("a"!==c[r].mode&&"n"!==c[r].mode||c[r].inv||100!==c[r].o.k||c[r].o.x)&&(v=g="mask"),"s"!==c[r].mode&&"i"!==c[r].mode||0!==d?l=null:((l=createNS("rect")).setAttribute("fill","#ffffff"),l.setAttribute("width",this.element.comp.data.w||0),l.setAttribute("height",this.element.comp.data.h||0),u.push(l)),s=createNS("path"),"n"===c[r].mode)this.viewData[r]={op:PropertyFactory.getProp(this.element,c[r].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[r],3),elem:s,lastPath:""},a.appendChild(s);else{var b;if(d+=1,s.setAttribute("fill","s"===c[r].mode?"#000000":"#ffffff"),s.setAttribute("clip-rule","nonzero"),0!==c[r].x.k?(v=g="mask",m=PropertyFactory.getProp(this.element,c[r].x,0,null,this.element),b=createElementID(),(p=createNS("filter")).setAttribute("id",b),(f=createNS("feMorphology")).setAttribute("operator","erode"),f.setAttribute("in","SourceGraphic"),f.setAttribute("radius","0"),p.appendChild(f),a.appendChild(p),s.setAttribute("stroke","s"===c[r].mode?"#000000":"#ffffff")):m=f=null,this.storedData[r]={elem:s,x:m,expan:f,lastPath:"",lastOperator:"",filterId:b,lastRadius:0},"i"===c[r].mode){h=u.length;var x=createNS("g");for(o=0;o<h;o+=1)x.appendChild(u[o]);var P=createNS("mask");P.setAttribute("mask-type","alpha"),P.setAttribute("id",y+"_"+d),P.appendChild(s),a.appendChild(P),x.setAttribute("mask","url("+getLocationHref()+"#"+y+"_"+d+")"),u.length=0,u.push(x)}else u.push(s);c[r].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[r]={elem:s,lastPath:"",op:PropertyFactory.getProp(this.element,c[r].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[r],3),invRect:l},this.viewData[r].prop.k||this.drawPath(c[r],this.viewData[r].prop.v,this.viewData[r])}for(this.maskElement=createNS(g),n=u.length,r=0;r<n;r+=1)this.maskElement.appendChild(u[r]);0<d&&(this.maskElement.setAttribute("id",y),this.element.maskedElement.setAttribute(v,"url("+getLocationHref()+"#"+y+")"),a.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}TransformElement.prototype={initTransform:function(){var t=new Matrix;this.finalTransform={mProp:this.data.ks?TransformPropertyFactory.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,i=0,r=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;i<r;){if(this.hierarchy[i].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}i+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),i=0;i<r;i+=1)e.multiply(this.hierarchy[i].finalTransform.mProp.v)}this.finalTransform._matMdf&&(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var i=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(i),t=1;t<e;t+=1){var r=this.localTransforms[t].matrix;i.multiply(r)}i.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){var s=this.finalTransform.localOpacity;for(t=0;t<e;t+=1)s*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=s}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new Matrix;var e=0,i=t.length;for(e=0;e<i;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var i,r=!0,s=this.comp;r;)s.finalTransform?(s.data.hasMask&&e.splice(0,0,s.finalTransform),s=s.comp):r=!1;var a,n=e.length;for(i=0;i<n;i+=1)a=e[i].mat.applyToPointArray(0,0,0),t=[t[0]-a[0],t[1]-a[1],0];return t},mHelper:new Matrix},MaskElement.prototype.getMaskProperty=function(t){return this.viewData[t].prop},MaskElement.prototype.renderFrame=function(t){var e,i=this.element.finalTransform.mat,r=this.masksProperties.length;for(e=0;e<r;e+=1)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[e].invRect.setAttribute("transform",i.getInverseMatrix().to2dCSS()),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var s=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+getLocationHref()+"#"+this.storedData[e].filterId+")")),s.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},MaskElement.prototype.getMaskelement=function(){return this.maskElement},MaskElement.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},MaskElement.prototype.drawPath=function(t,e,i){var r,s,a=" M"+e.v[0][0]+","+e.v[0][1];for(s=e._length,r=1;r<s;r+=1)a+=" C"+e.o[r-1][0]+","+e.o[r-1][1]+" "+e.i[r][0]+","+e.i[r][1]+" "+e.v[r][0]+","+e.v[r][1];if(e.c&&1<s&&(a+=" C"+e.o[r-1][0]+","+e.o[r-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),i.lastPath!==a){var n="";i.elem&&(e.c&&(n=t.inv?this.solidPath+a:a),i.elem.setAttribute("d",n)),i.lastPath=a}},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var filtersFactory=(tM={},tM.createFilter=function(t,e){var i=createNS("filter");return i.setAttribute("id",t),!0!==e&&(i.setAttribute("filterUnits","objectBoundingBox"),i.setAttribute("x","0%"),i.setAttribute("y","0%"),i.setAttribute("width","100%"),i.setAttribute("height","100%")),i},tM.createAlphaToLuminanceFilter=function(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},tM),tM,featureSupport=(AM={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas},(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(AM.maskType=!1),/firefox/i.test(navigator.userAgent)&&(AM.svgLumaHidden=!1),AM),AM,registeredEffects$1={},idPrefix="filter_result_";function SVGEffects(t){var e,i,r="SourceGraphic",s=t.data.ef?t.data.ef.length:0,a=createElementID(),n=filtersFactory.createFilter(a,!0),o=0;for(this.filters=[],e=0;e<s;e+=1){i=null;var h=t.data.ef[e].ty;if(registeredEffects$1[h])i=new registeredEffects$1[h].effect(n,t.effectsManager.effectElements[e],t,idPrefix+o,r),r=idPrefix+o,registeredEffects$1[h].countsAsEffect&&(o+=1);i&&this.filters.push(i)}o&&(t.globalData.defs.appendChild(n),t.layerElement.setAttribute("filter","url("+getLocationHref()+"#"+a+")")),this.filters.length&&t.addRenderableComponent(this)}function registerEffect$1(t,e,i){registeredEffects$1[t]={effect:e,countsAsEffect:i}}function SVGBaseElement(){}function HierarchyElement(){}function RenderableDOMElement(){}function IImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,i),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ProcessedElement(t,e){this.elem=t,this.pos=e}function IShapeElement(){}SVGEffects.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},SVGEffects.prototype.getEffects=function(t){var e,i=this.filters.length,r=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&r.push(this.filters[e]);return r},SVGBaseElement.prototype={initRendererElement:function(){this.layerElement=createNS("g")},createContainerElements:function(){this.matteElement=createNS("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t=null;if(this.data.td){this.matteMasks={};var e=createNS("g");e.setAttribute("id",this.layerId),e.appendChild(this.layerElement),t=e,this.globalData.defs.appendChild(e)}else this.data.tt?(this.matteElement.appendChild(this.layerElement),t=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var i=createNS("clipPath"),r=createNS("path");r.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var s=createElementID();if(i.setAttribute("id",s),i.appendChild(r),this.globalData.defs.appendChild(i),this.checkMasks()){var a=createNS("g");a.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),a.appendChild(this.layerElement),this.transformedElement=a,t?t.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData),this.renderableEffectsManager=new SVGEffects(this),this.searchEffectTransforms()},getMatte:function(t){if(this.matteMasks||(this.matteMasks={}),!this.matteMasks[t]){var e,i,r,s,a=this.layerId+"_"+t;if(1===t||3===t){var n=createNS("mask");n.setAttribute("id",a),n.setAttribute("mask-type",3===t?"luminance":"alpha"),(r=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),n.appendChild(r),this.globalData.defs.appendChild(n),featureSupport.maskType||1!==t||(n.setAttribute("mask-type","luminance"),e=createElementID(),i=filtersFactory.createFilter(e),this.globalData.defs.appendChild(i),i.appendChild(filtersFactory.createAlphaToLuminanceFilter()),(s=createNS("g")).appendChild(r),n.appendChild(s),s.setAttribute("filter","url("+getLocationHref()+"#"+e+")"))}else if(2===t){var o=createNS("mask");o.setAttribute("id",a),o.setAttribute("mask-type","alpha");var h=createNS("g");o.appendChild(h),e=createElementID(),i=filtersFactory.createFilter(e);var l=createNS("feComponentTransfer");l.setAttribute("in","SourceGraphic"),i.appendChild(l);var p=createNS("feFuncA");p.setAttribute("type","table"),p.setAttribute("tableValues","1.0 0.0"),l.appendChild(p),this.globalData.defs.appendChild(i);var f=createNS("rect");f.setAttribute("width",this.comp.data.w),f.setAttribute("height",this.comp.data.h),f.setAttribute("x","0"),f.setAttribute("y","0"),f.setAttribute("fill","#ffffff"),f.setAttribute("opacity","0"),h.setAttribute("filter","url("+getLocationHref()+"#"+e+")"),h.appendChild(f),(r=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),h.appendChild(r),featureSupport.maskType||(o.setAttribute("mask-type","luminance"),i.appendChild(filtersFactory.createAlphaToLuminanceFilter()),s=createNS("g"),h.appendChild(f),s.appendChild(this.layerElement),h.appendChild(s)),this.globalData.defs.appendChild(o)}this.matteMasks[t]=a}return this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+getLocationHref()+"#"+t+")")}},HierarchyElement.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},extendPrototype([RenderableElement,createProxyFunction({initElement:function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],RenderableDOMElement),extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],IImageElement),IImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=createNS("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},IImageElement.prototype.sourceRectAtTime=function(){return this.sourceRect},IShapeElement.prototype={addShapeToModifiers:function(t){var e,i=this.shapeModifiers.length;for(e=0;e<i;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;0<=t&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,i=0,r=e.length;i<r;){if(e[i].elem===t)return e[i].pos;i+=1}return 0},addProcessedElement:function(t,e){for(var i=this.processedElements,r=i.length;r;)if(i[r-=1].elem===t)return void(i[r].pos=e);i.push(new ProcessedElement(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var lineCapEnum={1:"butt",2:"round",3:"square"},lineJoinEnum={1:"miter",2:"round",3:"bevel"};function SVGShapeData(t,e,i){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=i,this.lvl=e,this._isAnimated=!!i.k;for(var r=0,s=t.length;r<s;){if(t[r].mProps.dynamicProperties.length){this._isAnimated=!0;break}r+=1}}function SVGStyleData(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=createNS("path"),this.msElem=null}function DashProperty(t,e,i,r){var s;this.elem=t,this.frameId=-1,this.dataProps=createSizedArray(e.length),this.renderer=i,this.k=!1,this.dashStr="",this.dashArray=createTypedArray("float32",e.length?e.length-1:0),this.dashoffset=createTypedArray("float32",1),this.initDynamicPropertyContainer(r);var a,n=e.length||0;for(s=0;s<n;s+=1)a=PropertyFactory.getProp(t,e[s].v,0,0,this),this.k=a.k||this.k,this.dataProps[s]={n:e[s].n,p:a};this.k||this.getValue(!0),this._isAnimated=this.k}function SVGStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i,this._isAnimated=!!this._isAnimated}function SVGFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i}function SVGNoStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=i}function GradientProperty(t,e,i){this.data=e,this.c=createTypedArray("uint8c",4*e.p);var r=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=createTypedArray("float32",r),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=r,this.initDynamicPropertyContainer(i),this.prop=PropertyFactory.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function SVGGradientFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,i)}function SVGGradientStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.initGradientData(t,e,i),this._isAnimated=!!this._isAnimated}function ShapeGroupData(){this.it=[],this.prevViewData=[],this.gr=createNS("g")}function SVGTransformData(t,e,i){this.transform={mProps:t,op:e,container:i},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}SVGShapeData.prototype.setAsAnimated=function(){this._isAnimated=!0},SVGStyleData.prototype.reset=function(){this.d="",this._mdf=!1},DashProperty.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,i=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<i;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},extendPrototype([DynamicPropertyContainer],DashProperty),extendPrototype([DynamicPropertyContainer],SVGStrokeStyleData),extendPrototype([DynamicPropertyContainer],SVGFillStyleData),extendPrototype([DynamicPropertyContainer],SVGNoStyleData),GradientProperty.prototype.comparePoints=function(t,e){for(var i=0,r=this.o.length/2;i<r;){if(.01<Math.abs(t[4*i]-t[4*e+2*i]))return!1;i+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},GradientProperty.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,i,r,s=4*this.data.p;for(e=0;e<s;e+=1)i=e%4==0?100:255,r=Math.round(this.prop.v[e]*i),this.c[e]!==r&&(this.c[e]=r,this._cmdf=!t);if(this.o.length)for(s=this.prop.v.length,e=4*this.data.p;e<s;e+=1)i=e%2==0?100:1,r=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==r&&(this.o[e-4*this.data.p]=r,this._omdf=!t);this._mdf=!t}},extendPrototype([DynamicPropertyContainer],GradientProperty),SVGGradientFillStyleData.prototype.initGradientData=function(t,e,i){this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.s=PropertyFactory.getProp(t,e.s,1,null,this),this.e=PropertyFactory.getProp(t,e.e,1,null,this),this.h=PropertyFactory.getProp(t,e.h||{k:0},0,.01,this),this.a=PropertyFactory.getProp(t,e.a||{k:0},0,degToRads,this),this.g=new GradientProperty(t,e.g,this),this.style=i,this.stops=[],this.setGradientData(i.pElem,e),this.setGradientOpacity(e,i),this._isAnimated=!!this._isAnimated},SVGGradientFillStyleData.prototype.setGradientData=function(t,e){var i=createElementID(),r=createNS(1===e.t?"linearGradient":"radialGradient");r.setAttribute("id",i),r.setAttribute("spreadMethod","pad"),r.setAttribute("gradientUnits","userSpaceOnUse");var s,a,n,o=[];for(n=4*e.g.p,a=0;a<n;a+=4)s=createNS("stop"),r.appendChild(s),o.push(s);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+getLocationHref()+"#"+i+")"),this.gf=r,this.cst=o},SVGGradientFillStyleData.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){var i,r,s,a=createNS("mask"),n=createNS("path");a.appendChild(n);var o=createElementID(),h=createElementID();a.setAttribute("id",h);var l=createNS(1===t.t?"linearGradient":"radialGradient");l.setAttribute("id",o),l.setAttribute("spreadMethod","pad"),l.setAttribute("gradientUnits","userSpaceOnUse"),s=t.g.k.k[0].s?t.g.k.k[0].s.length:t.g.k.k.length;var p=this.stops;for(r=4*t.g.p;r<s;r+=2)(i=createNS("stop")).setAttribute("stop-color","rgb(255,255,255)"),l.appendChild(i),p.push(i);n.setAttribute("gf"===t.ty?"fill":"stroke","url("+getLocationHref()+"#"+o+")"),"gs"===t.ty&&(n.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),n.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),1===t.lj&&n.setAttribute("stroke-miterlimit",t.ml)),this.of=l,this.ms=a,this.ost=p,this.maskId=h,e.msElem=n}},extendPrototype([DynamicPropertyContainer],SVGGradientFillStyleData),extendPrototype([SVGGradientFillStyleData,DynamicPropertyContainer],SVGGradientStrokeStyleData);var buildShapeString=function(t,e,i,r){if(0===e)return"";var s,a=t.o,n=t.i,o=t.v,h=" M"+r.applyToPointStringified(o[0][0],o[0][1]);for(s=1;s<e;s+=1)h+=" C"+r.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+r.applyToPointStringified(n[s][0],n[s][1])+" "+r.applyToPointStringified(o[s][0],o[s][1]);return i&&e&&(h+=" C"+r.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+r.applyToPointStringified(n[0][0],n[0][1])+" "+r.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},SVGElementsRenderer=function(){var u=new Matrix,y=new Matrix;function e(t,e,i){(i||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(i||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function i(){}function r(t,e,i){var r,s,a,n,o,h,l,p,f,m,c=e.styles.length,d=e.lvl;for(h=0;h<c;h+=1){if(n=e.sh._mdf||i,e.styles[h].lvl<d){for(p=y.reset(),f=d-e.styles[h].lvl,m=e.transformers.length-1;!n&&0<f;)n=e.transformers[m].mProps._mdf||n,f-=1,m-=1;if(n)for(f=d-e.styles[h].lvl,m=e.transformers.length-1;0<f;)p.multiply(e.transformers[m].mProps.v),f-=1,m-=1}else p=u;if(s=(l=e.sh.paths)._length,n){for(a="",r=0;r<s;r+=1)(o=l.shapes[r])&&o._length&&(a+=buildShapeString(o,o._length,o.c,p));e.caches[h]=a}else a=e.caches[h];e.styles[h].d+=!0===t.hd?"":a,e.styles[h]._mdf=n||e.styles[h]._mdf}}function s(t,e,i){var r=e.style;(e.c._mdf||i)&&r.pElem.setAttribute("fill","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("fill-opacity",e.o.v)}function a(t,e,i){n(t,e,i),o(t,e,i)}function n(t,e,i){var r,s,a,n,o,h=e.gf,l=e.g._hasOpacity,p=e.s.v,f=e.e.v;if(e.o._mdf||i){var m="gf"===t.ty?"fill-opacity":"stroke-opacity";e.style.pElem.setAttribute(m,e.o.v)}if(e.s._mdf||i){var c=1===t.t?"x1":"cx",d="x1"===c?"y1":"cy";h.setAttribute(c,p[0]),h.setAttribute(d,p[1]),l&&!e.g._collapsable&&(e.of.setAttribute(c,p[0]),e.of.setAttribute(d,p[1]))}if(e.g._cmdf||i){r=e.cst;var u=e.g.c;for(a=r.length,s=0;s<a;s+=1)(n=r[s]).setAttribute("offset",u[4*s]+"%"),n.setAttribute("stop-color","rgb("+u[4*s+1]+","+u[4*s+2]+","+u[4*s+3]+")")}if(l&&(e.g._omdf||i)){var y=e.g.o;for(a=(r=e.g._collapsable?e.cst:e.ost).length,s=0;s<a;s+=1)n=r[s],e.g._collapsable||n.setAttribute("offset",y[2*s]+"%"),n.setAttribute("stop-opacity",y[2*s+1])}if(1===t.t)(e.e._mdf||i)&&(h.setAttribute("x2",f[0]),h.setAttribute("y2",f[1]),l&&!e.g._collapsable&&(e.of.setAttribute("x2",f[0]),e.of.setAttribute("y2",f[1])));else if((e.s._mdf||e.e._mdf||i)&&(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)),h.setAttribute("r",o),l&&!e.g._collapsable&&e.of.setAttribute("r",o)),e.e._mdf||e.h._mdf||e.a._mdf||i){o||(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)));var g=Math.atan2(f[1]-p[1],f[0]-p[0]),v=e.h.v;1<=v?v=.99:v<=-1&&(v=-.99);var b=o*v,x=Math.cos(g+e.a.v)*b+p[0],P=Math.sin(g+e.a.v)*b+p[1];h.setAttribute("fx",x),h.setAttribute("fy",P),l&&!e.g._collapsable&&(e.of.setAttribute("fx",x),e.of.setAttribute("fy",P))}}function o(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||i)&&s.dashStr&&(r.pElem.setAttribute("stroke-dasharray",s.dashStr),r.pElem.setAttribute("stroke-dashoffset",s.dashoffset[0])),e.c&&(e.c._mdf||i)&&r.pElem.setAttribute("stroke","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||i)&&(r.pElem.setAttribute("stroke-width",e.w.v),r.msElem&&r.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function(t){switch(t.ty){case"fl":return s;case"gf":return n;case"gs":return a;case"st":return o;case"sh":case"el":case"rc":case"sr":return r;case"tr":return e;case"no":return i;default:return null}}}}();function SVGShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,i),this.prevViewData=[]}function LetterProps(t,e,i,r,s,a){this.o=t,this.sw=e,this.sc=i,this.fc=r,this.m=s,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!i,fc:!!r,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){var t,e,i,r,s=this.shapes.length,a=this.stylesList.length,n=[],o=!1;for(i=0;i<a;i+=1){for(r=this.stylesList[i],o=!1,t=n.length=0;t<s;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(r)&&(n.push(e),o=e._isAnimated||o);1<n.length&&o&&this.setShapesAsAnimated(n)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].setAsAnimated()},SVGShapeElement.prototype.createStyleElement=function(t,e){var i,r=new SVGStyleData(t,e),s=r.pElem;if("st"===t.ty)i=new SVGStrokeStyleData(this,t,r);else if("fl"===t.ty)i=new SVGFillStyleData(this,t,r);else if("gf"===t.ty||"gs"===t.ty){i=new("gf"===t.ty?SVGGradientFillStyleData:SVGGradientStrokeStyleData)(this,t,r),this.globalData.defs.appendChild(i.gf),i.maskId&&(this.globalData.defs.appendChild(i.ms),this.globalData.defs.appendChild(i.of),s.setAttribute("mask","url("+getLocationHref()+"#"+i.maskId+")"))}else"no"===t.ty&&(i=new SVGNoStyleData(this,t,r));return"st"!==t.ty&&"gs"!==t.ty||(s.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),s.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),s.setAttribute("fill-opacity","0"),1===t.lj&&s.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&s.setAttribute("fill-rule","evenodd"),t.ln&&s.setAttribute("id",t.ln),t.cl&&s.setAttribute("class",t.cl),t.bm&&(s.style["mix-blend-mode"]=getBlendMode(t.bm)),this.stylesList.push(r),this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createGroupElement=function(t){var e=new ShapeGroupData;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=getBlendMode(t.bm)),e},SVGShapeElement.prototype.createTransformElement=function(t,e){var i=TransformPropertyFactory.getTransformProperty(this,t,this),r=new SVGTransformData(i,i.o,e);return this.addToAnimatedContents(t,r),r},SVGShapeElement.prototype.createShapeElement=function(t,e,i){var r=4;"rc"===t.ty?r=5:"el"===t.ty?r=6:"sr"===t.ty&&(r=7);var s=new SVGShapeData(e,i,ShapePropertyFactory.getShapeProp(this,t,r,this));return this.shapes.push(s),this.addShapeToModifiers(s),this.addToAnimatedContents(t,s),s},SVGShapeElement.prototype.addToAnimatedContents=function(t,e){for(var i=0,r=this.animatedContents.length;i<r;){if(this.animatedContents[i].element===e)return;i+=1}this.animatedContents.push({fn:SVGElementsRenderer.createRenderFunction(t),element:e,data:t})},SVGShapeElement.prototype.setElementStyles=function(t){var e,i=t.styles,r=this.stylesList.length;for(e=0;e<r;e+=1)this.stylesList[e].closed||i.push(this.stylesList[e])},SVGShapeElement.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},SVGShapeElement.prototype.searchShapes=function(t,e,i,r,s,a,n){var o,h,l,p,f,m,c=[].concat(a),d=t.length-1,u=[],y=[];for(o=d;0<=o;o-=1){if((m=this.searchProcessedElement(t[o]))?e[o]=i[m-1]:t[o]._render=n,"fl"===t[o].ty||"st"===t[o].ty||"gf"===t[o].ty||"gs"===t[o].ty||"no"===t[o].ty)m?e[o].style.closed=!1:e[o]=this.createStyleElement(t[o],s),t[o]._render&&e[o].style.pElem.parentNode!==r&&r.appendChild(e[o].style.pElem),u.push(e[o].style);else if("gr"===t[o].ty){if(m)for(l=e[o].it.length,h=0;h<l;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,s+1,c,n),t[o]._render&&e[o].gr.parentNode!==r&&r.appendChild(e[o].gr)}else"tr"===t[o].ty?(m||(e[o]=this.createTransformElement(t[o],r)),p=e[o].transform,c.push(p)):"sh"===t[o].ty||"rc"===t[o].ty||"el"===t[o].ty||"sr"===t[o].ty?(m||(e[o]=this.createShapeElement(t[o],c,s)),this.setElementStyles(e[o])):"tm"===t[o].ty||"rd"===t[o].ty||"ms"===t[o].ty||"pb"===t[o].ty||"zz"===t[o].ty||"op"===t[o].ty?(m?(f=e[o]).closed=!1:((f=ShapeModifiers.getModifier(t[o].ty)).init(this,t[o]),e[o]=f,this.shapeModifiers.push(f)),y.push(f)):"rp"===t[o].ty&&(m?(f=e[o]).closed=!0:(f=ShapeModifiers.getModifier(t[o].ty),(e[o]=f).init(this,t,o,e),this.shapeModifiers.push(f),n=!1),y.push(f));this.addProcessedElement(t[o],o+1)}for(d=u.length,o=0;o<d;o+=1)u[o].closed=!0;for(d=y.length,o=0;o<d;o+=1)y[o].closed=!0},SVGShapeElement.prototype.renderInnerContent=function(){var t;this.renderModifiers();var e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},SVGShapeElement.prototype.renderShape=function(){var t,e,i=this.animatedContents.length;for(t=0;t<i;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},SVGShapeElement.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},LetterProps.prototype.update=function(t,e,i,r,s,a){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1;var n=this._mdf.p=!1;return this.o!==t&&(this.o=t,n=this._mdf.o=!0),this.sw!==e&&(this.sw=e,n=this._mdf.sw=!0),this.sc!==i&&(this.sc=i,n=this._mdf.sc=!0),this.fc!==r&&(this.fc=r,n=this._mdf.fc=!0),this.m!==s&&(this.m=s,n=this._mdf.m=!0),!a.length||this.p[0]===a[0]&&this.p[1]===a[1]&&this.p[4]===a[4]&&this.p[5]===a[5]&&this.p[12]===a[12]&&this.p[13]===a[13]||(this.p=a,n=this._mdf.p=!0),n},TextProperty.prototype.defaultBoxWidth=[0,0],TextProperty.prototype.copyData=function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},TextProperty.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},TextProperty.prototype.searchProperty=function(){return this.searchKeyframes()},TextProperty.prototype.searchKeyframes=function(){return this.kf=1<this.data.d.k.length,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,i=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{var r;this.lock=!0,this._mdf=!1;var s=this.effectsSequence.length,a=t||this.data.d.k[this.keysIndex].s;for(r=0;r<s;r+=1)a=i!==this.keysIndex?this.effectsSequence[r](a,a.t):this.effectsSequence[r](this.currentData,a.t);e!==a&&this.setCurrentData(a),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},TextProperty.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,i=0,r=t.length;i<=r-1&&!(i===r-1||t[i+1].t>e);)i+=1;return this.keysIndex!==i&&(this.keysIndex=i),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e,i,r=[],s=0,a=t.length,n=!1,o=!1,h="";s<a;)n=o,o=!1,e=t.charCodeAt(s),h=t.charAt(s),FontManager.isCombinedCharacter(e)?n=!0:55296<=e&&e<=56319?FontManager.isRegionalFlag(t,s)?h=t.substr(s,14):56320<=(i=t.charCodeAt(s+1))&&i<=57343&&(FontManager.isModifier(e,i)?(h=t.substr(s,2),n=!0):h=FontManager.isFlagEmoji(t.substr(s,4))?t.substr(s,4):t.substr(s,2)):56319<e?(i=t.charCodeAt(s+1),FontManager.isVariationSelector(e)&&(n=!0)):FontManager.isZeroWidthJoiner(e)&&(o=n=!0),n?(r[r.length-1]+=h,n=!1):r.push(h),s+=h.length;return r},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,i,r,s,a,n,o,h=this.elem.globalData.fontManager,l=this.data,p=[],f=0,m=l.m.g,c=0,d=0,u=0,y=[],g=0,v=0,b=h.getFontByName(t.f),x=0,P=getFontProperties(b);t.fWeight=P.weight,t.fStyle=P.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),i=t.finalText.length,t.finalLineHeight=t.lh;var E,S=t.tr/1e3*t.finalSize;if(t.sz)for(var C,_,A=!0,T=t.sz[0],M=t.sz[1];A;){g=C=0,i=(_=this.buildFinalText(t.t)).length,S=t.tr/1e3*t.finalSize;var k=-1;for(e=0;e<i;e+=1)E=_[e].charCodeAt(0),r=!1," "===_[e]?k=e:13!==E&&3!==E||(r=!(g=0),C+=t.finalLineHeight||1.2*t.finalSize),T<g+(x=h.chars?(o=h.getCharData(_[e],b.fStyle,b.fFamily),r?0:o.w*t.finalSize/100):h.measureText(_[e],t.f,t.finalSize))&&" "!==_[e]?(-1===k?i+=1:e=k,C+=t.finalLineHeight||1.2*t.finalSize,_.splice(e,k===e?1:0,"\r"),k=-1,g=0):(g+=x,g+=S);C+=b.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&M<C?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=_,i=t.finalText.length,A=!1)}g=-S;var D,F=x=0;for(e=0;e<i;e+=1)if(r=!1,13===(E=(D=t.finalText[e]).charCodeAt(0))||3===E?(F=0,y.push(g),v=v<g?g:v,g=-2*S,r=!(s=""),u+=1):s=D,x=h.chars?(o=h.getCharData(D,b.fStyle,h.getFontByName(t.f).fFamily),r?0:o.w*t.finalSize/100):h.measureText(s,t.f,t.finalSize)," "===D?F+=x+S:(g+=x+S+F,F=0),p.push({l:x,an:x,add:c,n:r,anIndexes:[],val:s,line:u,animatorJustifyOffset:0}),2==m){if(c+=x,""===s||" "===s||e===i-1){for(""!==s&&" "!==s||(c-=x);d<=e;)p[d].an=c,p[d].ind=f,p[d].extra=x,d+=1;f+=1,c=0}}else if(3==m){if(c+=x,""===s||e===i-1){for(""===s&&(c-=x);d<=e;)p[d].an=c,p[d].ind=f,p[d].extra=x,d+=1;c=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=v<g?g:v,y.push(g),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=y;var w,I,V,B,R=l.a;n=R.length;var L=[];for(a=0;a<n;a+=1){for((w=R[a]).a.sc&&(t.strokeColorAnim=!0),w.a.sw&&(t.strokeWidthAnim=!0),(w.a.fc||w.a.fh||w.a.fs||w.a.fb)&&(t.fillColorAnim=!0),B=0,V=w.s.b,e=0;e<i;e+=1)(I=p[e]).anIndexes[a]=B,(1==V&&""!==I.val||2==V&&""!==I.val&&" "!==I.val||3==V&&(I.n||" "==I.val||e==i-1)||4==V&&(I.n||e==i-1))&&(1===w.s.rn&&L.push(B),B+=1);l.a[a].s.totalChars=B;var z,G=-1;if(1===w.s.rn)for(e=0;e<i;e+=1)G!=(I=p[e]).anIndexes[a]&&(G=I.anIndexes[a],z=L.splice(Math.floor(Math.random()*L.length),1)[0]),I.anIndexes[a]=z}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=b.ascent*t.finalSize/100},TextProperty.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var i=this.copyData({},this.data.d.k[e].s);i=this.copyData(i,t),this.data.d.k[e].s=i,this.recalculate(e),this.setCurrentData(i),this.elem.addDynamicProperty(this)},TextProperty.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},TextProperty.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},TextProperty.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var TextSelectorProp=function(){var u=Math.max,y=Math.min,g=Math.floor;function r(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=PropertyFactory.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?PropertyFactory.getProp(t,e.e,0,0,this):{v:100},this.o=PropertyFactory.getProp(t,e.o||{k:0},0,0,this),this.xe=PropertyFactory.getProp(t,e.xe||{k:0},0,0,this),this.ne=PropertyFactory.getProp(t,e.ne||{k:0},0,0,this),this.sm=PropertyFactory.getProp(t,e.sm||{k:100},0,0,this),this.a=PropertyFactory.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return r.prototype={getMult:function(t){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var e=0,i=0,r=1,s=1;0<this.ne.v?e=this.ne.v/100:i=-this.ne.v/100,0<this.xe.v?r=1-this.xe.v/100:s=1+this.xe.v/100;var a=BezierFactory.getBezierEasing(e,i,r,s).get,n=0,o=this.finalS,h=this.finalE,l=this.data.sh;if(2===l)n=a(n=h===o?h<=t?1:0:u(0,y(.5/(h-o)+(t-o)/(h-o),1)));else if(3===l)n=a(n=h===o?h<=t?0:1:1-u(0,y(.5/(h-o)+(t-o)/(h-o),1)));else if(4===l)h===o?n=0:(n=u(0,y(.5/(h-o)+(t-o)/(h-o),1)))<.5?n*=2:n=1-2*(n-.5),n=a(n);else if(5===l){if(h===o)n=0;else{var p=h-o,f=-p/2+(t=y(u(0,t+.5-o),h-o)),m=p/2;n=Math.sqrt(1-f*f/(m*m))}n=a(n)}else n=6===l?a(n=h===o?0:(t=y(u(0,t+.5-o),h-o),(1+Math.cos(Math.PI+2*Math.PI*t/(h-o)))/2)):(t>=g(o)&&(n=u(0,y(t-o<0?y(h,1)-(o-t):h-t,1))),a(n));if(100!==this.sm.v){var c=.01*this.sm.v;0===c&&(c=1e-8);var d=.5-.5*c;n<d?n=0:1<(n=(n-d)/c)&&(n=1)}return n*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,i=this.o.v/e,r=this.s.v/e+i,s=this.e.v/e+i;if(s<r){var a=r;r=s,s=a}this.finalS=r,this.finalE=s}},extendPrototype([DynamicPropertyContainer],r),{getTextSelectorProp:function(t,e,i){return new r(t,e,i)}}}();function TextAnimatorDataProperty(t,e,i){var r={propType:!1},s=PropertyFactory.getProp,a=e.a;this.a={r:a.r?s(t,a.r,0,degToRads,i):r,rx:a.rx?s(t,a.rx,0,degToRads,i):r,ry:a.ry?s(t,a.ry,0,degToRads,i):r,sk:a.sk?s(t,a.sk,0,degToRads,i):r,sa:a.sa?s(t,a.sa,0,degToRads,i):r,s:a.s?s(t,a.s,1,.01,i):r,a:a.a?s(t,a.a,1,0,i):r,o:a.o?s(t,a.o,0,.01,i):r,p:a.p?s(t,a.p,1,0,i):r,sw:a.sw?s(t,a.sw,0,0,i):r,sc:a.sc?s(t,a.sc,1,0,i):r,fc:a.fc?s(t,a.fc,1,0,i):r,fh:a.fh?s(t,a.fh,0,0,i):r,fs:a.fs?s(t,a.fs,0,.01,i):r,fb:a.fb?s(t,a.fb,0,.01,i):r,t:a.t?s(t,a.t,0,0,i):r},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,i),this.s.t=e.s.t}function TextAnimatorProperty(t,e,i){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=i,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(i)}function ITextElement(){}TextAnimatorProperty.prototype.searchProperties=function(){var t,e,i=this._textData.a.length,r=PropertyFactory.getProp;for(t=0;t<i;t+=1)e=this._textData.a[t],this._animatorsData[t]=new TextAnimatorDataProperty(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:r(this._elem,this._textData.p.a,0,0,this),f:r(this._elem,this._textData.p.f,0,0,this),l:r(this._elem,this._textData.p.l,0,0,this),r:r(this._elem,this._textData.p.r,0,0,this),p:r(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=r(this._elem,this._textData.m.a,1,0,this)},TextAnimatorProperty.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var i,r,s,a,n,o,h,l,p,f,m,c,d,u,y,g,v,b,x,P=this._moreOptions.alignment.v,E=this._animatorsData,S=this._textData,C=this.mHelper,_=this._renderType,A=this.renderedLetters.length,T=t.l;if(this._hasMaskedPath){if(x=this._pathData.m,!this._pathData.n||this._pathData._mdf){var M,k=x.v;for(this._pathData.r.v&&(k=k.reverse()),n={tLength:0,segments:[]},a=k._length-1,s=g=0;s<a;s+=1)M=bez.buildBezierData(k.v[s],k.v[s+1],[k.o[s][0]-k.v[s][0],k.o[s][1]-k.v[s][1]],[k.i[s+1][0]-k.v[s+1][0],k.i[s+1][1]-k.v[s+1][1]]),n.tLength+=M.segmentLength,n.segments.push(M),g+=M.segmentLength;s=a,x.v.c&&(M=bez.buildBezierData(k.v[s],k.v[0],[k.o[s][0]-k.v[s][0],k.o[s][1]-k.v[s][1]],[k.i[0][0]-k.v[0][0],k.i[0][1]-k.v[0][1]]),n.tLength+=M.segmentLength,n.segments.push(M),g+=M.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,f=1,p=!(l=m=0),u=n.segments,o<0&&x.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),f=(d=u[m=u.length-1].points).length-1;o<0;)o+=d[f].partialLength,(f-=1)<0&&(f=(d=u[m-=1].points).length-1);c=(d=u[m].points)[f-1],y=(h=d[f]).partialLength}a=T.length,r=i=0;var D,F,w,I,V,B=1.2*t.finalSize*.714,R=!0;w=E.length;var L,z,G,O,N,H,j,q,W,$,Y,J,X=-1,Z=o,K=m,U=f,Q=-1,tt="",et=this.defaultPropsArray;if(2===t.j||1===t.j){var it=0,rt=0,st=2===t.j?-.5:-1,at=0,nt=!0;for(s=0;s<a;s+=1)if(T[s].n){for(it&&(it+=rt);at<s;)T[at].animatorJustifyOffset=it,at+=1;nt=!(it=0)}else{for(F=0;F<w;F+=1)(D=E[F].a).t.propType&&(nt&&2===t.j&&(rt+=D.t.v*st),(V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?it+=D.t.v*V[0]*st:it+=D.t.v*V*st);nt=!1}for(it&&(it+=rt);at<s;)T[at].animatorJustifyOffset=it,at+=1}for(s=0;s<a;s+=1){if(C.reset(),O=1,T[s].n)i=0,r+=t.yOffset,r+=R?1:0,o=Z,R=!1,this._hasMaskedPath&&(f=U,c=(d=u[m=K].points)[f-1],y=(h=d[f]).partialLength,l=0),J=W=Y=tt="",et=this.defaultPropsArray;else{if(this._hasMaskedPath){if(Q!==T[s].line){switch(t.j){case 1:o+=g-t.lineWidths[T[s].line];break;case 2:o+=(g-t.lineWidths[T[s].line])/2}Q=T[s].line}X!==T[s].ind&&(T[X]&&(o+=T[X].extra),o+=T[s].an/2,X=T[s].ind),o+=P[0]*T[s].an*.005;var ot=0;for(F=0;F<w;F+=1)(D=E[F].a).p.propType&&((V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?ot+=D.p.v[0]*V[0]:ot+=D.p.v[0]*V),D.a.propType&&((V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?ot+=D.a.v[0]*V[0]:ot+=D.a.v[0]*V);for(p=!0,this._pathData.a.v&&(o=.5*T[0].an+(g-this._pathData.f.v-.5*T[0].an-.5*T[T.length-1].an)*X/(a-1),o+=this._pathData.f.v);p;)o+ot<=l+y||!d?(v=(o+ot-l)/h.partialLength,z=c.point[0]+(h.point[0]-c.point[0])*v,G=c.point[1]+(h.point[1]-c.point[1])*v,C.translate(-P[0]*T[s].an*.005,-P[1]*B*.01),p=!1):d&&(l+=h.partialLength,(f+=1)>=d.length&&(f=0,d=u[m+=1]?u[m].points:x.v.c?u[m=f=0].points:(l-=h.partialLength,null)),d&&(c=h,y=(h=d[f]).partialLength));L=T[s].an/2-T[s].add,C.translate(-L,0,0)}else L=T[s].an/2-T[s].add,C.translate(-L,0,0),C.translate(-P[0]*T[s].an*.005,-P[1]*B*.01,0);for(F=0;F<w;F+=1)(D=E[F].a).t.propType&&(V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars),0===i&&0===t.j||(this._hasMaskedPath?V.length?o+=D.t.v*V[0]:o+=D.t.v*V:V.length?i+=D.t.v*V[0]:i+=D.t.v*V));for(t.strokeWidthAnim&&(H=t.sw||0),t.strokeColorAnim&&(N=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(j=[t.fc[0],t.fc[1],t.fc[2]]),F=0;F<w;F+=1)(D=E[F].a).a.propType&&((V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?C.translate(-D.a.v[0]*V[0],-D.a.v[1]*V[1],D.a.v[2]*V[2]):C.translate(-D.a.v[0]*V,-D.a.v[1]*V,D.a.v[2]*V));for(F=0;F<w;F+=1)(D=E[F].a).s.propType&&((V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?C.scale(1+(D.s.v[0]-1)*V[0],1+(D.s.v[1]-1)*V[1],1):C.scale(1+(D.s.v[0]-1)*V,1+(D.s.v[1]-1)*V,1));for(F=0;F<w;F+=1){if(D=E[F].a,V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars),D.sk.propType&&(V.length?C.skewFromAxis(-D.sk.v*V[0],D.sa.v*V[1]):C.skewFromAxis(-D.sk.v*V,D.sa.v*V)),D.r.propType&&(V.length?C.rotateZ(-D.r.v*V[2]):C.rotateZ(-D.r.v*V)),D.ry.propType&&(V.length?C.rotateY(D.ry.v*V[1]):C.rotateY(D.ry.v*V)),D.rx.propType&&(V.length?C.rotateX(D.rx.v*V[0]):C.rotateX(D.rx.v*V)),D.o.propType&&(V.length?O+=(D.o.v*V[0]-O)*V[0]:O+=(D.o.v*V-O)*V),t.strokeWidthAnim&&D.sw.propType&&(V.length?H+=D.sw.v*V[0]:H+=D.sw.v*V),t.strokeColorAnim&&D.sc.propType)for(q=0;q<3;q+=1)V.length?N[q]+=(D.sc.v[q]-N[q])*V[0]:N[q]+=(D.sc.v[q]-N[q])*V;if(t.fillColorAnim&&t.fc){if(D.fc.propType)for(q=0;q<3;q+=1)V.length?j[q]+=(D.fc.v[q]-j[q])*V[0]:j[q]+=(D.fc.v[q]-j[q])*V;D.fh.propType&&(j=V.length?addHueToRGB(j,D.fh.v*V[0]):addHueToRGB(j,D.fh.v*V)),D.fs.propType&&(j=V.length?addSaturationToRGB(j,D.fs.v*V[0]):addSaturationToRGB(j,D.fs.v*V)),D.fb.propType&&(j=V.length?addBrightnessToRGB(j,D.fb.v*V[0]):addBrightnessToRGB(j,D.fb.v*V))}}for(F=0;F<w;F+=1)(D=E[F].a).p.propType&&(V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars),this._hasMaskedPath?V.length?C.translate(0,D.p.v[1]*V[0],-D.p.v[2]*V[1]):C.translate(0,D.p.v[1]*V,-D.p.v[2]*V):V.length?C.translate(D.p.v[0]*V[0],D.p.v[1]*V[1],-D.p.v[2]*V[2]):C.translate(D.p.v[0]*V,D.p.v[1]*V,-D.p.v[2]*V));if(t.strokeWidthAnim&&(W=H<0?0:H),t.strokeColorAnim&&($="rgb("+Math.round(255*N[0])+","+Math.round(255*N[1])+","+Math.round(255*N[2])+")"),t.fillColorAnim&&t.fc&&(Y="rgb("+Math.round(255*j[0])+","+Math.round(255*j[1])+","+Math.round(255*j[2])+")"),this._hasMaskedPath){if(C.translate(0,-t.ls),C.translate(0,P[1]*B*.01+r,0),this._pathData.p.v){b=(h.point[1]-c.point[1])/(h.point[0]-c.point[0]);var ht=180*Math.atan(b)/Math.PI;h.point[0]<c.point[0]&&(ht+=180),C.rotate(-ht*Math.PI/180)}C.translate(z,G,0),o-=P[0]*T[s].an*.005,T[s+1]&&X!==T[s+1].ind&&(o+=T[s].an/2,o+=.001*t.tr*t.finalSize)}else{switch(C.translate(i,r,0),t.ps&&C.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:C.translate(T[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[T[s].line]),0,0);break;case 2:C.translate(T[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[T[s].line])/2,0,0)}C.translate(0,-t.ls),C.translate(L,0,0),C.translate(P[0]*T[s].an*.005,P[1]*B*.01,0),i+=T[s].l+.001*t.tr*t.finalSize}"html"===_?tt=C.toCSS():"svg"===_?tt=C.to2dCSS():et=[C.props[0],C.props[1],C.props[2],C.props[3],C.props[4],C.props[5],C.props[6],C.props[7],C.props[8],C.props[9],C.props[10],C.props[11],C.props[12],C.props[13],C.props[14],C.props[15]],J=O}this.lettersChangedFlag=A<=s?(I=new LetterProps(J,W,$,Y,tt,et),this.renderedLetters.push(I),A+=1,!0):(I=this.renderedLetters[s]).update(J,W,$,Y,tt,et)||this.lettersChangedFlag}}},TextAnimatorProperty.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},TextAnimatorProperty.prototype.mHelper=new Matrix,TextAnimatorProperty.prototype.defaultPropsArray=[],extendPrototype([DynamicPropertyContainer],TextAnimatorProperty),ITextElement.prototype.initElement=function(t,e,i){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,i),this.textProperty=new TextProperty(this,t.t,this.dynamicProperties),this.textAnimator=new TextAnimatorProperty(t.t,this.renderType,this),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},ITextElement.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},ITextElement.prototype.createPathShape=function(t,e){var i,r,s=e.length,a="";for(i=0;i<s;i+=1)"sh"===e[i].ty&&(r=e[i].ks.k,a+=buildShapeString(r,r.i.length,!0,t));return a},ITextElement.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},ITextElement.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},ITextElement.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},ITextElement.prototype.applyTextPropertiesToMatrix=function(t,e,i,r,s){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i])/2,0,0)}e.translate(r,s,0)},ITextElement.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},ITextElement.prototype.emptyProp=new LetterProps,ITextElement.prototype.destroy=function(){},ITextElement.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var emptyShapeData={shapes:[]};function SVGTextLottieElement(t,e,i){this.textSpans=[],this.renderType="svg",this.initElement(t,e,i)}function ISolidElement(t,e,i){this.initElement(t,e,i)}function NullElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initFrame(),this.initTransform(t,e,i),this.initHierarchy()}function SVGRendererBase(){}function ICompElement(){}function SVGCompElement(t,e,i){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function SVGRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=createNS("svg");var i="";if(e&&e.title){var r=createNS("title"),s=createElementID();r.setAttribute("id",s),r.textContent=e.title,this.svgElement.appendChild(r),i+=s}if(e&&e.description){var a=createNS("desc"),n=createElementID();a.setAttribute("id",n),a.textContent=e.description,this.svgElement.appendChild(a),i+=" "+n}i&&this.svgElement.setAttribute("aria-labelledby",i);var o=createNS("defs");this.svgElement.appendChild(o);var h=createNS("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}function ShapeTransformManager(){this.sequences={},this.sequenceList=[],this.transform_key_count=0}extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],SVGTextLottieElement),SVGTextLottieElement.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=createNS("text"))},SVGTextLottieElement.prototype.buildTextContents=function(t){for(var e=0,i=t.length,r=[],s="";e<i;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(r.push(s),s=""):s+=t[e],e+=1;return r.push(s),r},SVGTextLottieElement.prototype.buildShapeData=function(t,e){if(t.shapes&&t.shapes.length){var i=t.shapes[0];if(i.it){var r=i.it[i.it.length-1];r.s&&(r.s.k[0]=e,r.s.k[1]=e)}}return t},SVGTextLottieElement.prototype.buildNewText=function(){var t,e;this.addDynamicProperty(this);var i=this.textProperty.currentData;this.renderedLetters=createSizedArray(i?i.l.length:0),i.fc?this.layerElement.setAttribute("fill",this.buildColor(i.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),i.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(i.sc)),this.layerElement.setAttribute("stroke-width",i.sw)),this.layerElement.setAttribute("font-size",i.finalSize);var r=this.globalData.fontManager.getFontByName(i.f);if(r.fClass)this.layerElement.setAttribute("class",r.fClass);else{this.layerElement.setAttribute("font-family",r.fFamily);var s=i.fWeight,a=i.fStyle;this.layerElement.setAttribute("font-style",a),this.layerElement.setAttribute("font-weight",s)}this.layerElement.setAttribute("aria-label",i.t);var n,o=i.l||[],h=!!this.globalData.fontManager.chars;e=o.length;var l=this.mHelper,p=this.data.singleShape,f=0,m=0,c=!0,d=.001*i.tr*i.finalSize;if(!p||h||i.sz){var u,y=this.textSpans.length;for(t=0;t<e;t+=1){if(this.textSpans[t]||(this.textSpans[t]={span:null,childSpan:null,glyph:null}),!h||!p||0===t){if(n=t<y?this.textSpans[t].span:createNS(h?"g":"text"),y<=t){if(n.setAttribute("stroke-linecap","butt"),n.setAttribute("stroke-linejoin","round"),n.setAttribute("stroke-miterlimit","4"),this.textSpans[t].span=n,h){var g=createNS("g");n.appendChild(g),this.textSpans[t].childSpan=g}this.textSpans[t].span=n,this.layerElement.appendChild(n)}n.style.display="inherit"}if(l.reset(),p&&(o[t].n&&(f=-d,m+=i.yOffset,m+=c?1:0,c=!1),this.applyTextPropertiesToMatrix(i,l,o[t].line,f,m),f+=o[t].l||0,f+=d),h){var v;if(1===(u=this.globalData.fontManager.getCharData(i.finalText[t],r.fStyle,this.globalData.fontManager.getFontByName(i.f).fFamily)).t)v=new SVGCompElement(u.data,this.globalData,this);else{var b=emptyShapeData;u.data&&u.data.shapes&&(b=this.buildShapeData(u.data,i.finalSize)),v=new SVGShapeElement(b,this.globalData,this)}if(this.textSpans[t].glyph){var x=this.textSpans[t].glyph;this.textSpans[t].childSpan.removeChild(x.layerElement),x.destroy()}(this.textSpans[t].glyph=v)._debug=!0,v.prepareFrame(0),v.renderFrame(),this.textSpans[t].childSpan.appendChild(v.layerElement),1===u.t&&this.textSpans[t].childSpan.setAttribute("transform","scale("+i.finalSize/100+","+i.finalSize/100+")")}else p&&n.setAttribute("transform","translate("+l.props[12]+","+l.props[13]+")"),n.textContent=o[t].val,n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}p&&n&&n.setAttribute("d","")}else{var P=this.textContainer,E="start";switch(i.j){case 1:E="end";break;case 2:E="middle";break;default:E="start"}P.setAttribute("text-anchor",E),P.setAttribute("letter-spacing",d);var S=this.buildTextContents(i.finalText);for(e=S.length,m=i.ps?i.ps[1]+i.ascent:0,t=0;t<e;t+=1)(n=this.textSpans[t].span||createNS("tspan")).textContent=S[t],n.setAttribute("x",0),n.setAttribute("y",m),n.style.display="inherit",P.appendChild(n),this.textSpans[t]||(this.textSpans[t]={span:null,glyph:null}),this.textSpans[t].span=n,m+=i.finalLineHeight;this.layerElement.appendChild(P)}for(;t<this.textSpans.length;)this.textSpans[t].span.style.display="none",t+=1;this._sizeChanged=!0},SVGTextLottieElement.prototype.sourceRectAtTime=function(){if(this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged){this._sizeChanged=!1;var t=this.layerElement.getBBox();this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}}return this.bbox},SVGTextLottieElement.prototype.getValue=function(){var t,e,i=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<i;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf&&(this._mdf=!0))},SVGTextLottieElement.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){var t,e;this._sizeChanged=!0;var i,r,s,a=this.textAnimator.renderedLetters,n=this.textProperty.currentData.l;for(e=n.length,t=0;t<e;t+=1)n[t].n||(i=a[t],r=this.textSpans[t].span,(s=this.textSpans[t].glyph)&&s.renderFrame(),i._mdf.m&&r.setAttribute("transform",i.m),i._mdf.o&&r.setAttribute("opacity",i.o),i._mdf.sw&&r.setAttribute("stroke-width",i.sw),i._mdf.sc&&r.setAttribute("stroke",i.sc),i._mdf.fc&&r.setAttribute("fill",i.fc))}},extendPrototype([IImageElement],ISolidElement),ISolidElement.prototype.createContent=function(){var t=createNS("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},NullElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},NullElement.prototype.renderFrame=function(){},NullElement.prototype.getBaseElement=function(){return null},NullElement.prototype.destroy=function(){},NullElement.prototype.sourceRectAtTime=function(){},NullElement.prototype.hide=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement],NullElement),extendPrototype([BaseRenderer],SVGRendererBase),SVGRendererBase.prototype.createNull=function(t){return new NullElement(t,this.globalData,this)},SVGRendererBase.prototype.createShape=function(t){return new SVGShapeElement(t,this.globalData,this)},SVGRendererBase.prototype.createText=function(t){return new SVGTextLottieElement(t,this.globalData,this)},SVGRendererBase.prototype.createImage=function(t){return new IImageElement(t,this.globalData,this)},SVGRendererBase.prototype.createSolid=function(t){return new ISolidElement(t,this.globalData,this)},SVGRendererBase.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var i=createNS("clipPath"),r=createNS("rect");r.setAttribute("width",t.w),r.setAttribute("height",t.h),r.setAttribute("x",0),r.setAttribute("y",0);var s=createElementID();i.setAttribute("id",s),i.appendChild(r),this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),e.appendChild(i),this.layers=t.layers,this.elements=createSizedArray(t.layers.length)},SVGRendererBase.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},SVGRendererBase.prototype.updateContainerSize=function(){},SVGRendererBase.prototype.findIndexByInd=function(t){var e=0,i=this.layers.length;for(e=0;e<i;e+=1)if(this.layers[e].ind===t)return e;return-1},SVGRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){e[t]=!0;var i=this.createItem(this.layers[t]);if(e[t]=i,getExpressionsPlugin()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(i),i.initExpressions()),this.appendElementInPos(i,t),this.layers[t].tt){var r="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1;if(-1===r)return;if(this.elements[r]&&!0!==this.elements[r]){var s=e[r].getMatte(this.layers[t].tt);i.setMatte(s)}else this.buildItem(r),this.addPendingElement(i)}}},SVGRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,i=this.elements.length;e<i;){if(this.elements[e]===t){var r="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,s=this.elements[r].getMatte(this.layers[e].tt);t.setMatte(s);break}e+=1}}},SVGRendererBase.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){var e;null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var i=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=i-1;0<=e;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<i;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},SVGRendererBase.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){for(var r,s=0;s<e;)this.elements[s]&&!0!==this.elements[s]&&this.elements[s].getBaseElement()&&(r=this.elements[s].getBaseElement()),s+=1;r?this.layerElement.insertBefore(i,r):this.layerElement.appendChild(i)}},SVGRendererBase.prototype.hide=function(){this.layerElement.style.display="none"},SVGRendererBase.prototype.show=function(){this.layerElement.style.display="block"},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement,RenderableDOMElement],ICompElement),ICompElement.prototype.initElement=function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},ICompElement.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var i,r=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),i=r-1;0<=i;i-=1)(this.completeLayers||this.elements[i])&&(this.elements[i].prepareFrame(this.renderedFrame-this.layers[i].st),this.elements[i]._mdf&&(this._mdf=!0))}},ICompElement.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},ICompElement.prototype.setElements=function(t){this.elements=t},ICompElement.prototype.getElements=function(){return this.elements},ICompElement.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},ICompElement.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},extendPrototype([SVGRendererBase,ICompElement,SVGBaseElement],SVGCompElement),SVGCompElement.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},extendPrototype([SVGRendererBase],SVGRenderer),SVGRenderer.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},ShapeTransformManager.prototype={addTransformSequence:function(t){var e,i=t.length,r="_";for(e=0;e<i;e+=1)r+=t[e].transform.key+"_";var s=this.sequences[r];return s||(s={transforms:[].concat(t),finalTransform:new Matrix,_mdf:!1},this.sequences[r]=s,this.sequenceList.push(s)),s},processSequence:function(t,e){for(var i=0,r=t.transforms.length,s=e;i<r&&!e;){if(t.transforms[i].transform.mProps._mdf){s=!0;break}i+=1}if(s)for(t.finalTransform.reset(),i=r-1;0<=i;i-=1)t.finalTransform.multiply(t.transforms[i].transform.mProps.v);t._mdf=s},processSequences:function(t){var e,i=this.sequenceList.length;for(e=0;e<i;e+=1)this.processSequence(this.sequenceList[e],t)},getNewKey:function(){return this.transform_key_count+=1,"_"+this.transform_key_count}};var lumaLoader=function(){var r="__lottie_element_luma_buffer",s=null,a=null,n=null;function e(){var t,e,i;s||(t=createNS("svg"),e=createNS("filter"),i=createNS("feColorMatrix"),e.setAttribute("id",r),i.setAttribute("type","matrix"),i.setAttribute("color-interpolation-filters","sRGB"),i.setAttribute("values","0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0"),e.appendChild(i),t.appendChild(e),t.setAttribute("id",r+"_svg"),featureSupport.svgLumaHidden&&(t.style.display="none"),n=t,document.body.appendChild(n),s=createTag("canvas"),(a=s.getContext("2d")).filter="url(#"+r+")",a.fillStyle="rgba(0,0,0,0)",a.fillRect(0,0,1,1))}return{load:e,get:function(t){return s||e(),s.width=t.width,s.height=t.height,a.filter="url(#"+r+")",s}}};function createCanvas(t,e){if(featureSupport.offscreenCanvas)return new OffscreenCanvas(t,e);var i=createTag("canvas");return i.width=t,i.height=e,i}var assetLoader={loadLumaCanvas:lumaLoader.load,getLumaCanvas:lumaLoader.get,createCanvas:createCanvas},registeredEffects={};function CVEffects(t){var e,i,r=t.data.ef?t.data.ef.length:0;for(this.filters=[],e=0;e<r;e+=1){i=null;var s=t.data.ef[e].ty;if(registeredEffects[s])i=new registeredEffects[s].effect(t.effectsManager.effectElements[e],t);i&&this.filters.push(i)}this.filters.length&&t.addRenderableComponent(this)}function registerEffect(t,e){registeredEffects[t]={effect:e}}function CVMaskElement(t,e){var i;this.data=t,this.element=e,this.masksProperties=this.data.masksProperties||[],this.viewData=createSizedArray(this.masksProperties.length);var r=this.masksProperties.length,s=!1;for(i=0;i<r;i+=1)"n"!==this.masksProperties[i].mode&&(s=!0),this.viewData[i]=ShapePropertyFactory.getShapeProp(this.element,this.masksProperties[i],3);(this.hasMasks=s)&&this.element.addRenderableComponent(this)}function CVBaseElement(){}CVEffects.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},CVEffects.prototype.getEffects=function(t){var e,i=this.filters.length,r=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&r.push(this.filters[e]);return r},CVMaskElement.prototype.renderFrame=function(){if(this.hasMasks){var t,e,i,r,s=this.element.finalTransform.mat,a=this.element.canvasContext,n=this.masksProperties.length;for(a.beginPath(),t=0;t<n;t+=1)if("n"!==this.masksProperties[t].mode){var o;this.masksProperties[t].inv&&(a.moveTo(0,0),a.lineTo(this.element.globalData.compSize.w,0),a.lineTo(this.element.globalData.compSize.w,this.element.globalData.compSize.h),a.lineTo(0,this.element.globalData.compSize.h),a.lineTo(0,0)),r=this.viewData[t].v,e=s.applyToPointArray(r.v[0][0],r.v[0][1],0),a.moveTo(e[0],e[1]);var h=r._length;for(o=1;o<h;o+=1)i=s.applyToTriplePoints(r.o[o-1],r.i[o],r.v[o]),a.bezierCurveTo(i[0],i[1],i[2],i[3],i[4],i[5]);i=s.applyToTriplePoints(r.o[o-1],r.i[0],r.v[0]),a.bezierCurveTo(i[0],i[1],i[2],i[3],i[4],i[5])}this.element.globalData.renderer.save(!0),a.clip()}},CVMaskElement.prototype.getMaskProperty=MaskElement.prototype.getMaskProperty,CVMaskElement.prototype.destroy=function(){this.element=null};var operationsMap={1:"source-in",2:"source-out",3:"source-in",4:"source-out"};function CVShapeData(t,e,i,r){this.styledShapes=[],this.tr=[0,0,0,0,0,0];var s,a=4;"rc"===e.ty?a=5:"el"===e.ty?a=6:"sr"===e.ty&&(a=7),this.sh=ShapePropertyFactory.getShapeProp(t,e,a,t);var n,o=i.length;for(s=0;s<o;s+=1)i[s].closed||(n={transforms:r.addTransformSequence(i[s].transforms),trNodes:[]},this.styledShapes.push(n),i[s].elements.push(n))}function CVShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.itemsData=[],this.prevViewData=[],this.shapeModifiers=[],this.processedElements=[],this.transformsManager=new ShapeTransformManager,this.initElement(t,e,i)}function CVTextElement(t,e,i){this.textSpans=[],this.yOffset=0,this.fillColorAnim=!1,this.strokeColorAnim=!1,this.strokeWidthAnim=!1,this.stroke=!1,this.fill=!1,this.justifyOffset=0,this.currentRender=null,this.renderType="canvas",this.values={fill:"rgba(0,0,0,0)",stroke:"rgba(0,0,0,0)",sWidth:0,fValue:""},this.initElement(t,e,i)}function CVImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.img=e.imageLoader.getAsset(this.assetData),this.initElement(t,e,i)}function CVSolidElement(t,e,i){this.initElement(t,e,i)}function CanvasRendererBase(){}function CanvasContext(){this.opacity=-1,this.transform=createTypedArray("float32",16),this.fillStyle="",this.strokeStyle="",this.lineWidth="",this.lineCap="",this.lineJoin="",this.miterLimit="",this.id=Math.random()}function CVContextData(){var t;this.stack=[],this.cArrPos=0,this.cTr=new Matrix;for(t=0;t<15;t+=1){var e=new CanvasContext;this.stack[t]=e}this._length=15,this.nativeContext=null,this.transformMat=new Matrix,this.currentOpacity=1,this.currentFillStyle="",this.appliedFillStyle="",this.currentStrokeStyle="",this.appliedStrokeStyle="",this.currentLineWidth="",this.appliedLineWidth="",this.currentLineCap="",this.appliedLineCap="",this.currentLineJoin="",this.appliedLineJoin="",this.appliedMiterLimit="",this.currentMiterLimit=""}function CVCompElement(t,e,i){this.completeLayers=!1,this.layers=t.layers,this.pendingElements=[],this.elements=createSizedArray(this.layers.length),this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function CanvasRenderer(t,e){this.animationItem=t,this.renderConfig={clearCanvas:!e||void 0===e.clearCanvas||e.clearCanvas,context:e&&e.context||null,progressiveLoad:e&&e.progressiveLoad||!1,preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",className:e&&e.className||"",id:e&&e.id||"",runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.renderConfig.dpr=e&&e.dpr||1,this.animationItem.wrapper&&(this.renderConfig.dpr=e&&e.dpr||window.devicePixelRatio||1),this.renderedFrame=-1,this.globalData={frameNum:-1,_mdf:!1,renderConfig:this.renderConfig,currentGlobalAlpha:-1},this.contextData=new CVContextData,this.elements=[],this.pendingElements=[],this.transformMat=new Matrix,this.completeLayers=!1,this.rendererType="canvas",this.renderConfig.clearCanvas&&(this.ctxTransform=this.contextData.transform.bind(this.contextData),this.ctxOpacity=this.contextData.opacity.bind(this.contextData),this.ctxFillStyle=this.contextData.fillStyle.bind(this.contextData),this.ctxStrokeStyle=this.contextData.strokeStyle.bind(this.contextData),this.ctxLineWidth=this.contextData.lineWidth.bind(this.contextData),this.ctxLineCap=this.contextData.lineCap.bind(this.contextData),this.ctxLineJoin=this.contextData.lineJoin.bind(this.contextData),this.ctxMiterLimit=this.contextData.miterLimit.bind(this.contextData),this.ctxFill=this.contextData.fill.bind(this.contextData),this.ctxFillRect=this.contextData.fillRect.bind(this.contextData),this.ctxStroke=this.contextData.stroke.bind(this.contextData),this.save=this.contextData.save.bind(this.contextData))}function HBaseElement(){}function HSolidElement(t,e,i){this.initElement(t,e,i)}function HShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.shapesContainer=createNS("g"),this.initElement(t,e,i),this.prevViewData=[],this.currentBBox={x:999999,y:-999999,h:0,w:0}}function HTextElement(t,e,i){this.textSpans=[],this.textPaths=[],this.currentBBox={x:999999,y:-999999,h:0,w:0},this.renderType="svg",this.isMasked=!1,this.initElement(t,e,i)}function HCameraElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initHierarchy();var r=PropertyFactory.getProp;if(this.pe=r(this,t.pe,0,0,this),t.ks.p.s?(this.px=r(this,t.ks.p.x,1,0,this),this.py=r(this,t.ks.p.y,1,0,this),this.pz=r(this,t.ks.p.z,1,0,this)):this.p=r(this,t.ks.p,1,0,this),t.ks.a&&(this.a=r(this,t.ks.a,1,0,this)),t.ks.or.k.length&&t.ks.or.k[0].to){var s,a=t.ks.or.k.length;for(s=0;s<a;s+=1)t.ks.or.k[s].to=null,t.ks.or.k[s].ti=null}this.or=r(this,t.ks.or,1,degToRads,this),this.or.sh=!0,this.rx=r(this,t.ks.rx,0,degToRads,this),this.ry=r(this,t.ks.ry,0,degToRads,this),this.rz=r(this,t.ks.rz,0,degToRads,this),this.mat=new Matrix,this._prevMat=new Matrix,this._isFirstFrame=!0,this.finalTransform={mProp:this}}function HImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.initElement(t,e,i)}function HybridRendererBase(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"}},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}function HCompElement(t,e,i){this.layers=t.layers,this.supports3d=!t.hasMask,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function HybridRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"},runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}CVBaseElement.prototype={createElements:function(){},initRendererElement:function(){},createContainerElements:function(){if(1<=this.data.tt){this.buffers=[];var t=this.globalData.canvasContext,e=assetLoader.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(e);var i=assetLoader.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(i),3<=this.data.tt&&!document._isProxy&&assetLoader.loadLumaCanvas()}this.canvasContext=this.globalData.canvasContext,this.transformCanvas=this.globalData.transformCanvas,this.renderableEffectsManager=new CVEffects(this),this.searchEffectTransforms()},createContent:function(){},setBlendMode:function(){var t=this.globalData;if(t.blendMode!==this.data.bm){t.blendMode=this.data.bm;var e=getBlendMode(this.data.bm);t.canvasContext.globalCompositeOperation=e}},createRenderableComponents:function(){this.maskManager=new CVMaskElement(this.data,this),this.transformEffects=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT)},hideElement:function(){this.hidden||this.isInRange&&!this.isTransparent||(this.hidden=!0)},showElement:function(){this.isInRange&&!this.isTransparent&&(this.hidden=!1,this._isFirstFrame=!0,this.maskManager._isFirstFrame=!0)},clearCanvas:function(t){t.clearRect(this.transformCanvas.tx,this.transformCanvas.ty,this.transformCanvas.w*this.transformCanvas.sx,this.transformCanvas.h*this.transformCanvas.sy)},prepareLayer:function(){if(1<=this.data.tt){var t=this.buffers[0].getContext("2d");this.clearCanvas(t),t.drawImage(this.canvasContext.canvas,0,0),this.currentTransform=this.canvasContext.getTransform(),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform)}},exitLayer:function(){if(1<=this.data.tt){var t=this.buffers[1],e=t.getContext("2d");if(this.clearCanvas(e),e.drawImage(this.canvasContext.canvas,0,0),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform),this.comp.getElementById("tp"in this.data?this.data.tp:this.data.ind-1).renderFrame(!0),this.canvasContext.setTransform(1,0,0,1,0,0),3<=this.data.tt&&!document._isProxy){var i=assetLoader.getLumaCanvas(this.canvasContext.canvas);i.getContext("2d").drawImage(this.canvasContext.canvas,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.drawImage(i,0,0)}this.canvasContext.globalCompositeOperation=operationsMap[this.data.tt],this.canvasContext.drawImage(t,0,0),this.canvasContext.globalCompositeOperation="destination-over",this.canvasContext.drawImage(this.buffers[0],0,0),this.canvasContext.setTransform(this.currentTransform),this.canvasContext.globalCompositeOperation="source-over"}},renderFrame:function(t){if(!this.hidden&&!this.data.hd&&(1!==this.data.td||t)){this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.setBlendMode();var e=0===this.data.ty;this.prepareLayer(),this.globalData.renderer.save(e),this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props),this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity),this.renderInnerContent(),this.globalData.renderer.restore(e),this.exitLayer(),this.maskManager.hasMasks&&this.globalData.renderer.restore(!0),this._isFirstFrame&&(this._isFirstFrame=!1)}},destroy:function(){this.canvasContext=null,this.data=null,this.globalData=null,this.maskManager.destroy()},mHelper:new Matrix},CVBaseElement.prototype.hide=CVBaseElement.prototype.hideElement,CVBaseElement.prototype.show=CVBaseElement.prototype.showElement,CVShapeData.prototype.setAsAnimated=SVGShapeData.prototype.setAsAnimated,extendPrototype([BaseElement,TransformElement,CVBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableElement],CVShapeElement),CVShapeElement.prototype.initElement=RenderableDOMElement.prototype.initElement,CVShapeElement.prototype.transformHelper={opacity:1,_opMdf:!1},CVShapeElement.prototype.dashResetter=[],CVShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[])},CVShapeElement.prototype.createStyleElement=function(t,e){var i={data:t,type:t.ty,preTransforms:this.transformsManager.addTransformSequence(e),transforms:[],elements:[],closed:!0===t.hd},r={};if("fl"===t.ty||"st"===t.ty?(r.c=PropertyFactory.getProp(this,t.c,1,255,this),r.c.k||(i.co="rgb("+bmFloor(r.c.v[0])+","+bmFloor(r.c.v[1])+","+bmFloor(r.c.v[2])+")")):"gf"!==t.ty&&"gs"!==t.ty||(r.s=PropertyFactory.getProp(this,t.s,1,null,this),r.e=PropertyFactory.getProp(this,t.e,1,null,this),r.h=PropertyFactory.getProp(this,t.h||{k:0},0,.01,this),r.a=PropertyFactory.getProp(this,t.a||{k:0},0,degToRads,this),r.g=new GradientProperty(this,t.g,this)),r.o=PropertyFactory.getProp(this,t.o,0,.01,this),"st"===t.ty||"gs"===t.ty){if(i.lc=lineCapEnum[t.lc||2],i.lj=lineJoinEnum[t.lj||2],1==t.lj&&(i.ml=t.ml),r.w=PropertyFactory.getProp(this,t.w,0,null,this),r.w.k||(i.wi=r.w.v),t.d){var s=new DashProperty(this,t.d,"canvas",this);r.d=s,r.d.k||(i.da=r.d.dashArray,i.do=r.d.dashoffset[0])}}else i.r=2===t.r?"evenodd":"nonzero";return this.stylesList.push(i),r.style=i,r},CVShapeElement.prototype.createGroupElement=function(){return{it:[],prevViewData:[]}},CVShapeElement.prototype.createTransformElement=function(t){return{transform:{opacity:1,_opMdf:!1,key:this.transformsManager.getNewKey(),op:PropertyFactory.getProp(this,t.o,0,.01,this),mProps:TransformPropertyFactory.getTransformProperty(this,t,this)}}},CVShapeElement.prototype.createShapeElement=function(t){var e=new CVShapeData(this,t,this.stylesList,this.transformsManager);return this.shapes.push(e),this.addShapeToModifiers(e),e},CVShapeElement.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[]),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame)},CVShapeElement.prototype.addTransformToStyleList=function(t){var e,i=this.stylesList.length;for(e=0;e<i;e+=1)this.stylesList[e].closed||this.stylesList[e].transforms.push(t)},CVShapeElement.prototype.removeTransformFromStyleList=function(){var t,e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].closed||this.stylesList[t].transforms.pop()},CVShapeElement.prototype.closeStyles=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].closed=!0},CVShapeElement.prototype.searchShapes=function(t,e,i,r,s){var a,n,o,h,l,p,f=t.length-1,m=[],c=[],d=[].concat(s);for(a=f;0<=a;a-=1){if((h=this.searchProcessedElement(t[a]))?e[a]=i[h-1]:t[a]._shouldRender=r,"fl"===t[a].ty||"st"===t[a].ty||"gf"===t[a].ty||"gs"===t[a].ty)h?e[a].style.closed=!1:e[a]=this.createStyleElement(t[a],d),m.push(e[a].style);else if("gr"===t[a].ty){if(h)for(o=e[a].it.length,n=0;n<o;n+=1)e[a].prevViewData[n]=e[a].it[n];else e[a]=this.createGroupElement(t[a]);this.searchShapes(t[a].it,e[a].it,e[a].prevViewData,r,d)}else"tr"===t[a].ty?(h||(p=this.createTransformElement(t[a]),e[a]=p),d.push(e[a]),this.addTransformToStyleList(e[a])):"sh"===t[a].ty||"rc"===t[a].ty||"el"===t[a].ty||"sr"===t[a].ty?h||(e[a]=this.createShapeElement(t[a])):"tm"===t[a].ty||"rd"===t[a].ty||"pb"===t[a].ty||"zz"===t[a].ty||"op"===t[a].ty?(h?(l=e[a]).closed=!1:((l=ShapeModifiers.getModifier(t[a].ty)).init(this,t[a]),e[a]=l,this.shapeModifiers.push(l)),c.push(l)):"rp"===t[a].ty&&(h?(l=e[a]).closed=!0:(l=ShapeModifiers.getModifier(t[a].ty),(e[a]=l).init(this,t,a,e),this.shapeModifiers.push(l),r=!1),c.push(l));this.addProcessedElement(t[a],a+1)}for(this.removeTransformFromStyleList(),this.closeStyles(m),f=c.length,a=0;a<f;a+=1)c[a].closed=!0},CVShapeElement.prototype.renderInnerContent=function(){this.transformHelper.opacity=1,this.transformHelper._opMdf=!1,this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame),this.renderShape(this.transformHelper,this.shapesData,this.itemsData,!0)},CVShapeElement.prototype.renderShapeTransform=function(t,e){(t._opMdf||e.op._mdf||this._isFirstFrame)&&(e.opacity=t.opacity,e.opacity*=e.op.v,e._opMdf=!0)},CVShapeElement.prototype.drawLayer=function(){var t,e,i,r,s,a,n,o,h,l=this.stylesList.length,p=this.globalData.renderer,f=this.globalData.canvasContext;for(t=0;t<l;t+=1)if(("st"!==(o=(h=this.stylesList[t]).type)&&"gs"!==o||0!==h.wi)&&h.data._shouldRender&&0!==h.coOp&&0!==this.globalData.currentGlobalAlpha){for(p.save(),a=h.elements,"st"===o||"gs"===o?(p.ctxStrokeStyle("st"===o?h.co:h.grd),p.ctxLineWidth(h.wi),p.ctxLineCap(h.lc),p.ctxLineJoin(h.lj),p.ctxMiterLimit(h.ml||0)):p.ctxFillStyle("fl"===o?h.co:h.grd),p.ctxOpacity(h.coOp),"st"!==o&&"gs"!==o&&f.beginPath(),p.ctxTransform(h.preTransforms.finalTransform.props),i=a.length,e=0;e<i;e+=1){for("st"!==o&&"gs"!==o||(f.beginPath(),h.da&&(f.setLineDash(h.da),f.lineDashOffset=h.do)),s=(n=a[e].trNodes).length,r=0;r<s;r+=1)"m"===n[r].t?f.moveTo(n[r].p[0],n[r].p[1]):"c"===n[r].t?f.bezierCurveTo(n[r].pts[0],n[r].pts[1],n[r].pts[2],n[r].pts[3],n[r].pts[4],n[r].pts[5]):f.closePath();"st"!==o&&"gs"!==o||(p.ctxStroke(),h.da&&f.setLineDash(this.dashResetter))}"st"!==o&&"gs"!==o&&this.globalData.renderer.ctxFill(h.r),p.restore()}},CVShapeElement.prototype.renderShape=function(t,e,i,r){var s,a;for(a=t,s=e.length-1;0<=s;s-=1)"tr"===e[s].ty?(a=i[s].transform,this.renderShapeTransform(t,a)):"sh"===e[s].ty||"el"===e[s].ty||"rc"===e[s].ty||"sr"===e[s].ty?this.renderPath(e[s],i[s]):"fl"===e[s].ty?this.renderFill(e[s],i[s],a):"st"===e[s].ty?this.renderStroke(e[s],i[s],a):"gf"===e[s].ty||"gs"===e[s].ty?this.renderGradientFill(e[s],i[s],a):"gr"===e[s].ty?this.renderShape(a,e[s].it,i[s].it):e[s].ty;r&&this.drawLayer()},CVShapeElement.prototype.renderStyledShape=function(t,e){if(this._isFirstFrame||e._mdf||t.transforms._mdf){var i,r,s,a=t.trNodes,n=e.paths,o=n._length;a.length=0;var h=t.transforms.finalTransform;for(s=0;s<o;s+=1){var l=n.shapes[s];if(l&&l.v){for(r=l._length,i=1;i<r;i+=1)1===i&&a.push({t:"m",p:h.applyToPointArray(l.v[0][0],l.v[0][1],0)}),a.push({t:"c",pts:h.applyToTriplePoints(l.o[i-1],l.i[i],l.v[i])});1===r&&a.push({t:"m",p:h.applyToPointArray(l.v[0][0],l.v[0][1],0)}),l.c&&r&&(a.push({t:"c",pts:h.applyToTriplePoints(l.o[i-1],l.i[0],l.v[0])}),a.push({t:"z"}))}}t.trNodes=a}},CVShapeElement.prototype.renderPath=function(t,e){if(!0!==t.hd&&t._shouldRender){var i,r=e.styledShapes.length;for(i=0;i<r;i+=1)this.renderStyledShape(e.styledShapes[i],e.sh)}},CVShapeElement.prototype.renderFill=function(t,e,i){var r=e.style;(e.c._mdf||this._isFirstFrame)&&(r.co="rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i._opMdf||this._isFirstFrame)&&(r.coOp=e.o.v*i.opacity)},CVShapeElement.prototype.renderGradientFill=function(t,e,i){var r,s=e.style;if(!s.grd||e.g._mdf||e.s._mdf||e.e._mdf||1!==t.t&&(e.h._mdf||e.a._mdf)){var a,n=this.globalData.canvasContext,o=e.s.v,h=e.e.v;if(1===t.t)r=n.createLinearGradient(o[0],o[1],h[0],h[1]);else{var l=Math.sqrt(Math.pow(o[0]-h[0],2)+Math.pow(o[1]-h[1],2)),p=Math.atan2(h[1]-o[1],h[0]-o[0]),f=e.h.v;1<=f?f=.99:f<=-1&&(f=-.99);var m=l*f,c=Math.cos(p+e.a.v)*m+o[0],d=Math.sin(p+e.a.v)*m+o[1];r=n.createRadialGradient(c,d,0,o[0],o[1],l)}var u=t.g.p,y=e.g.c,g=1;for(a=0;a<u;a+=1)e.g._hasOpacity&&e.g._collapsable&&(g=e.g.o[2*a+1]),r.addColorStop(y[4*a]/100,"rgba("+y[4*a+1]+","+y[4*a+2]+","+y[4*a+3]+","+g+")");s.grd=r}s.coOp=e.o.v*i.opacity},CVShapeElement.prototype.renderStroke=function(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||this._isFirstFrame)&&(r.da=s.dashArray,r.do=s.dashoffset[0]),(e.c._mdf||this._isFirstFrame)&&(r.co="rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i._opMdf||this._isFirstFrame)&&(r.coOp=e.o.v*i.opacity),(e.w._mdf||this._isFirstFrame)&&(r.wi=e.w.v)},CVShapeElement.prototype.destroy=function(){this.shapesData=null,this.globalData=null,this.canvasContext=null,this.stylesList.length=0,this.itemsData.length=0},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement,ITextElement],CVTextElement),CVTextElement.prototype.tHelper=createTag("canvas").getContext("2d"),CVTextElement.prototype.buildNewText=function(){var t=this.textProperty.currentData;this.renderedLetters=createSizedArray(t.l?t.l.length:0);var e=!1;t.fc?(e=!0,this.values.fill=this.buildColor(t.fc)):this.values.fill="rgba(0,0,0,0)",this.fill=e;var i=!1;t.sc&&(i=!0,this.values.stroke=this.buildColor(t.sc),this.values.sWidth=t.sw);var r,s,a,n,o,h,l,p,f,m,c,d,u=this.globalData.fontManager.getFontByName(t.f),y=t.l,g=this.mHelper;this.stroke=i,this.values.fValue=t.finalSize+"px "+this.globalData.fontManager.getFontByName(t.f).fFamily,s=t.finalText.length;var v=this.data.singleShape,b=.001*t.tr*t.finalSize,x=0,P=0,E=!0,S=0;for(r=0;r<s;r+=1){n=(a=this.globalData.fontManager.getCharData(t.finalText[r],u.fStyle,this.globalData.fontManager.getFontByName(t.f).fFamily))&&a.data||{},g.reset(),v&&y[r].n&&(x=-b,P+=t.yOffset,P+=E?1:0,E=!1),f=(l=n.shapes?n.shapes[0].it:[]).length,g.scale(t.finalSize/100,t.finalSize/100),v&&this.applyTextPropertiesToMatrix(t,g,y[r].line,x,P),c=createSizedArray(f-1);var C=0;for(p=0;p<f;p+=1)if("sh"===l[p].ty){for(h=l[p].ks.k.i.length,m=l[p].ks.k,d=[],o=1;o<h;o+=1)1===o&&d.push(g.applyToX(m.v[0][0],m.v[0][1],0),g.applyToY(m.v[0][0],m.v[0][1],0)),d.push(g.applyToX(m.o[o-1][0],m.o[o-1][1],0),g.applyToY(m.o[o-1][0],m.o[o-1][1],0),g.applyToX(m.i[o][0],m.i[o][1],0),g.applyToY(m.i[o][0],m.i[o][1],0),g.applyToX(m.v[o][0],m.v[o][1],0),g.applyToY(m.v[o][0],m.v[o][1],0));d.push(g.applyToX(m.o[o-1][0],m.o[o-1][1],0),g.applyToY(m.o[o-1][0],m.o[o-1][1],0),g.applyToX(m.i[0][0],m.i[0][1],0),g.applyToY(m.i[0][0],m.i[0][1],0),g.applyToX(m.v[0][0],m.v[0][1],0),g.applyToY(m.v[0][0],m.v[0][1],0)),c[C]=d,C+=1}v&&(x+=y[r].l,x+=b),this.textSpans[S]?this.textSpans[S].elem=c:this.textSpans[S]={elem:c},S+=1}},CVTextElement.prototype.renderInnerContent=function(){var t,e,i,r,s,a;this.validateText(),this.canvasContext.font=this.values.fValue,this.globalData.renderer.ctxLineCap("butt"),this.globalData.renderer.ctxLineJoin("miter"),this.globalData.renderer.ctxMiterLimit(4),this.data.singleShape||this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag);var n,o=this.textAnimator.renderedLetters,h=this.textProperty.currentData.l;e=h.length;var l,p,f=null,m=null,c=null,d=this.globalData.renderer;for(t=0;t<e;t+=1)if(!h[t].n){if((n=o[t])&&(d.save(),d.ctxTransform(n.p),d.ctxOpacity(n.o)),this.fill){for(n&&n.fc?f!==n.fc&&(d.ctxFillStyle(n.fc),f=n.fc):f!==this.values.fill&&(f=this.values.fill,d.ctxFillStyle(this.values.fill)),r=(l=this.textSpans[t].elem).length,this.globalData.canvasContext.beginPath(),i=0;i<r;i+=1)for(a=(p=l[i]).length,this.globalData.canvasContext.moveTo(p[0],p[1]),s=2;s<a;s+=6)this.globalData.canvasContext.bezierCurveTo(p[s],p[s+1],p[s+2],p[s+3],p[s+4],p[s+5]);this.globalData.canvasContext.closePath(),d.ctxFill()}if(this.stroke){for(n&&n.sw?c!==n.sw&&(c=n.sw,d.ctxLineWidth(n.sw)):c!==this.values.sWidth&&(c=this.values.sWidth,d.ctxLineWidth(this.values.sWidth)),n&&n.sc?m!==n.sc&&(m=n.sc,d.ctxStrokeStyle(n.sc)):m!==this.values.stroke&&(m=this.values.stroke,d.ctxStrokeStyle(this.values.stroke)),r=(l=this.textSpans[t].elem).length,this.globalData.canvasContext.beginPath(),i=0;i<r;i+=1)for(a=(p=l[i]).length,this.globalData.canvasContext.moveTo(p[0],p[1]),s=2;s<a;s+=6)this.globalData.canvasContext.bezierCurveTo(p[s],p[s+1],p[s+2],p[s+3],p[s+4],p[s+5]);this.globalData.canvasContext.closePath(),d.ctxStroke()}n&&this.globalData.renderer.restore()}},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVImageElement),CVImageElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVImageElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVImageElement.prototype.createContent=function(){if(this.img.width&&(this.assetData.w!==this.img.width||this.assetData.h!==this.img.height)){var t=createTag("canvas");t.width=this.assetData.w,t.height=this.assetData.h;var e,i,r=t.getContext("2d"),s=this.img.width,a=this.img.height,n=s/a,o=this.assetData.w/this.assetData.h,h=this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio;o<n&&"xMidYMid slice"===h||n<o&&"xMidYMid slice"!==h?e=(i=a)*o:i=(e=s)/o,r.drawImage(this.img,(s-e)/2,(a-i)/2,e,i,0,0,this.assetData.w,this.assetData.h),this.img=t}},CVImageElement.prototype.renderInnerContent=function(){this.canvasContext.drawImage(this.img,0,0)},CVImageElement.prototype.destroy=function(){this.img=null},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVSolidElement),CVSolidElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVSolidElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVSolidElement.prototype.renderInnerContent=function(){this.globalData.renderer.ctxFillStyle(this.data.sc),this.globalData.renderer.ctxFillRect(0,0,this.data.sw,this.data.sh)},extendPrototype([BaseRenderer],CanvasRendererBase),CanvasRendererBase.prototype.createShape=function(t){return new CVShapeElement(t,this.globalData,this)},CanvasRendererBase.prototype.createText=function(t){return new CVTextElement(t,this.globalData,this)},CanvasRendererBase.prototype.createImage=function(t){return new CVImageElement(t,this.globalData,this)},CanvasRendererBase.prototype.createSolid=function(t){return new CVSolidElement(t,this.globalData,this)},CanvasRendererBase.prototype.createNull=SVGRenderer.prototype.createNull,CanvasRendererBase.prototype.ctxTransform=function(t){1===t[0]&&0===t[1]&&0===t[4]&&1===t[5]&&0===t[12]&&0===t[13]||this.canvasContext.transform(t[0],t[1],t[4],t[5],t[12],t[13])},CanvasRendererBase.prototype.ctxOpacity=function(t){this.canvasContext.globalAlpha*=t<0?0:t},CanvasRendererBase.prototype.ctxFillStyle=function(t){this.canvasContext.fillStyle=t},CanvasRendererBase.prototype.ctxStrokeStyle=function(t){this.canvasContext.strokeStyle=t},CanvasRendererBase.prototype.ctxLineWidth=function(t){this.canvasContext.lineWidth=t},CanvasRendererBase.prototype.ctxLineCap=function(t){this.canvasContext.lineCap=t},CanvasRendererBase.prototype.ctxLineJoin=function(t){this.canvasContext.lineJoin=t},CanvasRendererBase.prototype.ctxMiterLimit=function(t){this.canvasContext.miterLimit=t},CanvasRendererBase.prototype.ctxFill=function(t){this.canvasContext.fill(t)},CanvasRendererBase.prototype.ctxFillRect=function(t,e,i,r){this.canvasContext.fillRect(t,e,i,r)},CanvasRendererBase.prototype.ctxStroke=function(){this.canvasContext.stroke()},CanvasRendererBase.prototype.reset=function(){this.renderConfig.clearCanvas?this.contextData.reset():this.canvasContext.restore()},CanvasRendererBase.prototype.save=function(){this.canvasContext.save()},CanvasRendererBase.prototype.restore=function(t){this.renderConfig.clearCanvas?(t&&(this.globalData.blendMode="source-over"),this.contextData.restore(t)):this.canvasContext.restore()},CanvasRendererBase.prototype.configAnimation=function(t){if(this.animationItem.wrapper){this.animationItem.container=createTag("canvas");var e=this.animationItem.container.style;e.width="100%",e.height="100%";var i="0px 0px 0px";e.transformOrigin=i,e.mozTransformOrigin=i,e.webkitTransformOrigin=i,e["-webkit-transform"]=i,e.contentVisibility=this.renderConfig.contentVisibility,this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.animationItem.container.setAttribute("id",this.renderConfig.id)}else this.canvasContext=this.renderConfig.context;this.contextData.setContext(this.canvasContext),this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.setupGlobalData(t,document.body),this.globalData.canvasContext=this.canvasContext,(this.globalData.renderer=this).globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=createSizedArray(t.layers.length),this.updateContainerSize()},CanvasRendererBase.prototype.updateContainerSize=function(t,e){var i,r,s,a;if(this.reset(),this.canvasContext.canvas.height=t?(i=t,r=e,this.canvasContext.canvas.width=i,r):(r=this.animationItem.wrapper&&this.animationItem.container?(i=this.animationItem.wrapper.offsetWidth,this.animationItem.wrapper.offsetHeight):(i=this.canvasContext.canvas.width,this.canvasContext.canvas.height),this.canvasContext.canvas.width=i*this.renderConfig.dpr,r*this.renderConfig.dpr),-1!==this.renderConfig.preserveAspectRatio.indexOf("meet")||-1!==this.renderConfig.preserveAspectRatio.indexOf("slice")){var n=this.renderConfig.preserveAspectRatio.split(" "),o=n[1]||"meet",h=n[0]||"xMidYMid",l=h.substr(0,4),p=h.substr(4);s=i/r,a=this.transformCanvas.w/this.transformCanvas.h,this.transformCanvas.sy=s<a&&"meet"===o||a<s&&"slice"===o?(this.transformCanvas.sx=i/(this.transformCanvas.w/this.renderConfig.dpr),i/(this.transformCanvas.w/this.renderConfig.dpr)):(this.transformCanvas.sx=r/(this.transformCanvas.h/this.renderConfig.dpr),r/(this.transformCanvas.h/this.renderConfig.dpr)),this.transformCanvas.tx="xMid"===l&&(a<s&&"meet"===o||s<a&&"slice"===o)?(i-this.transformCanvas.w*(r/this.transformCanvas.h))/2*this.renderConfig.dpr:"xMax"===l&&(a<s&&"meet"===o||s<a&&"slice"===o)?(i-this.transformCanvas.w*(r/this.transformCanvas.h))*this.renderConfig.dpr:0,this.transformCanvas.ty="YMid"===p&&(s<a&&"meet"===o||a<s&&"slice"===o)?(r-this.transformCanvas.h*(i/this.transformCanvas.w))/2*this.renderConfig.dpr:"YMax"===p&&(s<a&&"meet"===o||a<s&&"slice"===o)?(r-this.transformCanvas.h*(i/this.transformCanvas.w))*this.renderConfig.dpr:0}else"none"===this.renderConfig.preserveAspectRatio?(this.transformCanvas.sx=i/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=r/(this.transformCanvas.h/this.renderConfig.dpr)):(this.transformCanvas.sx=this.renderConfig.dpr,this.transformCanvas.sy=this.renderConfig.dpr),this.transformCanvas.tx=0,this.transformCanvas.ty=0;this.transformCanvas.props=[this.transformCanvas.sx,0,0,0,0,this.transformCanvas.sy,0,0,0,0,1,0,this.transformCanvas.tx,this.transformCanvas.ty,0,1],this.ctxTransform(this.transformCanvas.props),this.canvasContext.beginPath(),this.canvasContext.rect(0,0,this.transformCanvas.w,this.transformCanvas.h),this.canvasContext.closePath(),this.canvasContext.clip(),this.renderFrame(this.renderedFrame,!0)},CanvasRendererBase.prototype.destroy=function(){var t;for(this.renderConfig.clearCanvas&&this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),t=(this.layers?this.layers.length:0)-1;0<=t;t-=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.globalData.canvasContext=null,this.animationItem.container=null,this.destroyed=!0},CanvasRendererBase.prototype.renderFrame=function(t,e){if((this.renderedFrame!==t||!0!==this.renderConfig.clearCanvas||e)&&!this.destroyed&&-1!==t){var i;this.renderedFrame=t,this.globalData.frameNum=t-this.animationItem._isFirstFrame,this.globalData.frameId+=1,this.globalData._mdf=!this.renderConfig.clearCanvas||e,this.globalData.projectInterface.currentFrame=t;var r=this.layers.length;for(this.completeLayers||this.checkLayers(t),i=r-1;0<=i;i-=1)(this.completeLayers||this.elements[i])&&this.elements[i].prepareFrame(t-this.layers[i].st);if(this.globalData._mdf){for(!0===this.renderConfig.clearCanvas?this.canvasContext.clearRect(0,0,this.transformCanvas.w,this.transformCanvas.h):this.save(),i=r-1;0<=i;i-=1)(this.completeLayers||this.elements[i])&&this.elements[i].renderFrame();!0!==this.renderConfig.clearCanvas&&this.restore()}}},CanvasRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){var i=this.createItem(this.layers[t],this,this.globalData);(e[t]=i).initExpressions()}},CanvasRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},CanvasRendererBase.prototype.hide=function(){this.animationItem.container.style.display="none"},CanvasRendererBase.prototype.show=function(){this.animationItem.container.style.display="block"},CVContextData.prototype.duplicate=function(){var t=2*this._length,e=0;for(e=this._length;e<t;e+=1)this.stack[e]=new CanvasContext;this._length=t},CVContextData.prototype.reset=function(){this.cArrPos=0,this.cTr.reset(),this.stack[this.cArrPos].opacity=1},CVContextData.prototype.restore=function(t){this.cArrPos-=1;var e,i=this.stack[this.cArrPos],r=i.transform,s=this.cTr.props;for(e=0;e<16;e+=1)s[e]=r[e];if(t){this.nativeContext.restore();var a=this.stack[this.cArrPos+1];this.appliedFillStyle=a.fillStyle,this.appliedStrokeStyle=a.strokeStyle,this.appliedLineWidth=a.lineWidth,this.appliedLineCap=a.lineCap,this.appliedLineJoin=a.lineJoin,this.appliedMiterLimit=a.miterLimit}this.nativeContext.setTransform(r[0],r[1],r[4],r[5],r[12],r[13]),(t||-1!==i.opacity&&this.currentOpacity!==i.opacity)&&(this.nativeContext.globalAlpha=i.opacity,this.currentOpacity=i.opacity),this.currentFillStyle=i.fillStyle,this.currentStrokeStyle=i.strokeStyle,this.currentLineWidth=i.lineWidth,this.currentLineCap=i.lineCap,this.currentLineJoin=i.lineJoin,this.currentMiterLimit=i.miterLimit},CVContextData.prototype.save=function(t){t&&this.nativeContext.save();var e=this.cTr.props;this._length<=this.cArrPos&&this.duplicate();var i,r=this.stack[this.cArrPos];for(i=0;i<16;i+=1)r.transform[i]=e[i];this.cArrPos+=1;var s=this.stack[this.cArrPos];s.opacity=r.opacity,s.fillStyle=r.fillStyle,s.strokeStyle=r.strokeStyle,s.lineWidth=r.lineWidth,s.lineCap=r.lineCap,s.lineJoin=r.lineJoin,s.miterLimit=r.miterLimit},CVContextData.prototype.setOpacity=function(t){this.stack[this.cArrPos].opacity=t},CVContextData.prototype.setContext=function(t){this.nativeContext=t},CVContextData.prototype.fillStyle=function(t){this.stack[this.cArrPos].fillStyle!==t&&(this.currentFillStyle=t,this.stack[this.cArrPos].fillStyle=t)},CVContextData.prototype.strokeStyle=function(t){this.stack[this.cArrPos].strokeStyle!==t&&(this.currentStrokeStyle=t,this.stack[this.cArrPos].strokeStyle=t)},CVContextData.prototype.lineWidth=function(t){this.stack[this.cArrPos].lineWidth!==t&&(this.currentLineWidth=t,this.stack[this.cArrPos].lineWidth=t)},CVContextData.prototype.lineCap=function(t){this.stack[this.cArrPos].lineCap!==t&&(this.currentLineCap=t,this.stack[this.cArrPos].lineCap=t)},CVContextData.prototype.lineJoin=function(t){this.stack[this.cArrPos].lineJoin!==t&&(this.currentLineJoin=t,this.stack[this.cArrPos].lineJoin=t)},CVContextData.prototype.miterLimit=function(t){this.stack[this.cArrPos].miterLimit!==t&&(this.currentMiterLimit=t,this.stack[this.cArrPos].miterLimit=t)},CVContextData.prototype.transform=function(t){this.transformMat.cloneFromProps(t);var e=this.cTr;this.transformMat.multiply(e),e.cloneFromProps(this.transformMat.props);var i=e.props;this.nativeContext.setTransform(i[0],i[1],i[4],i[5],i[12],i[13])},CVContextData.prototype.opacity=function(t){var e=this.stack[this.cArrPos].opacity;e*=t<0?0:t,this.stack[this.cArrPos].opacity!==e&&(this.currentOpacity!==t&&(this.nativeContext.globalAlpha=t,this.currentOpacity=t),this.stack[this.cArrPos].opacity=e)},CVContextData.prototype.fill=function(t){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fill(t)},CVContextData.prototype.fillRect=function(t,e,i,r){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fillRect(t,e,i,r)},CVContextData.prototype.stroke=function(){this.appliedStrokeStyle!==this.currentStrokeStyle&&(this.appliedStrokeStyle=this.currentStrokeStyle,this.nativeContext.strokeStyle=this.appliedStrokeStyle),this.appliedLineWidth!==this.currentLineWidth&&(this.appliedLineWidth=this.currentLineWidth,this.nativeContext.lineWidth=this.appliedLineWidth),this.appliedLineCap!==this.currentLineCap&&(this.appliedLineCap=this.currentLineCap,this.nativeContext.lineCap=this.appliedLineCap),this.appliedLineJoin!==this.currentLineJoin&&(this.appliedLineJoin=this.currentLineJoin,this.nativeContext.lineJoin=this.appliedLineJoin),this.appliedMiterLimit!==this.currentMiterLimit&&(this.appliedMiterLimit=this.currentMiterLimit,this.nativeContext.miterLimit=this.appliedMiterLimit),this.nativeContext.stroke()},extendPrototype([CanvasRendererBase,ICompElement,CVBaseElement],CVCompElement),CVCompElement.prototype.renderInnerContent=function(){var t,e=this.canvasContext;for(e.beginPath(),e.moveTo(0,0),e.lineTo(this.data.w,0),e.lineTo(this.data.w,this.data.h),e.lineTo(0,this.data.h),e.lineTo(0,0),e.clip(),t=this.layers.length-1;0<=t;t-=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},CVCompElement.prototype.destroy=function(){var t;for(t=this.layers.length-1;0<=t;t-=1)this.elements[t]&&this.elements[t].destroy();this.layers=null,this.elements=null},CVCompElement.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},extendPrototype([CanvasRendererBase],CanvasRenderer),CanvasRenderer.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},HBaseElement.prototype={checkBlendMode:function(){},initRendererElement:function(){this.baseElement=createTag(this.data.tg||"div"),this.data.hasMask?(this.svgElement=createNS("svg"),this.layerElement=createNS("g"),this.maskedElement=this.layerElement,this.svgElement.appendChild(this.layerElement),this.baseElement.appendChild(this.svgElement)):this.layerElement=this.baseElement,styleDiv(this.baseElement)},createContainerElements:function(){this.renderableEffectsManager=new CVEffects(this),this.transformedElement=this.baseElement,this.maskedElement=this.layerElement,this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0!==this.data.bm&&this.setBlendMode()},renderElement:function(){var t=this.transformedElement?this.transformedElement.style:{};if(this.finalTransform._matMdf){var e=this.finalTransform.mat.toCSS();t.transform=e,t.webkitTransform=e}this.finalTransform._opMdf&&(t.opacity=this.finalTransform.mProp.o.v)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},destroy:function(){this.layerElement=null,this.transformedElement=null,this.matteElement&&(this.matteElement=null),this.maskManager&&(this.maskManager.destroy(),this.maskManager=null)},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData)},addEffects:function(){},setMatte:function(){}},HBaseElement.prototype.getBaseElement=SVGBaseElement.prototype.getBaseElement,HBaseElement.prototype.destroyBaseElement=HBaseElement.prototype.destroy,HBaseElement.prototype.buildElementParenting=BaseRenderer.prototype.buildElementParenting,extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],HSolidElement),HSolidElement.prototype.createContent=function(){var t;this.data.hasMask?((t=createNS("rect")).setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.svgElement.setAttribute("width",this.data.sw),this.svgElement.setAttribute("height",this.data.sh)):((t=createTag("div")).style.width=this.data.sw+"px",t.style.height=this.data.sh+"px",t.style.backgroundColor=this.data.sc),this.layerElement.appendChild(t)},extendPrototype([BaseElement,TransformElement,HSolidElement,SVGShapeElement,HBaseElement,HierarchyElement,FrameElement,RenderableElement],HShapeElement),HShapeElement.prototype._renderShapeFrame=HShapeElement.prototype.renderInnerContent,HShapeElement.prototype.createContent=function(){var t;if(this.baseElement.style.fontSize=0,this.data.hasMask)this.layerElement.appendChild(this.shapesContainer),t=this.svgElement;else{t=createNS("svg");var e=this.comp.data?this.comp.data:this.globalData.compSize;t.setAttribute("width",e.w),t.setAttribute("height",e.h),t.appendChild(this.shapesContainer),this.layerElement.appendChild(t)}this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.shapesContainer,0,[],!0),this.filterUniqueShapes(),this.shapeCont=t},HShapeElement.prototype.getTransformedPoint=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)e=t[i].mProps.v.applyToPointArray(e[0],e[1],0);return e},HShapeElement.prototype.calculateShapeBoundingBox=function(t,e){var i,r,s,a,n,o=t.sh.v,h=t.transformers,l=o._length;if(!(l<=1)){for(i=0;i<l-1;i+=1)r=this.getTransformedPoint(h,o.v[i]),s=this.getTransformedPoint(h,o.o[i]),a=this.getTransformedPoint(h,o.i[i+1]),n=this.getTransformedPoint(h,o.v[i+1]),this.checkBounds(r,s,a,n,e);o.c&&(r=this.getTransformedPoint(h,o.v[i]),s=this.getTransformedPoint(h,o.o[i]),a=this.getTransformedPoint(h,o.i[0]),n=this.getTransformedPoint(h,o.v[0]),this.checkBounds(r,s,a,n,e))}},HShapeElement.prototype.checkBounds=function(t,e,i,r,s){this.getBoundsOfCurve(t,e,i,r);var a=this.shapeBoundingBox;s.x=bmMin(a.left,s.x),s.xMax=bmMax(a.right,s.xMax),s.y=bmMin(a.top,s.y),s.yMax=bmMax(a.bottom,s.yMax)},HShapeElement.prototype.shapeBoundingBox={left:0,right:0,top:0,bottom:0},HShapeElement.prototype.tempBoundingBox={x:0,xMax:0,y:0,yMax:0,width:0,height:0},HShapeElement.prototype.getBoundsOfCurve=function(t,e,i,r){for(var s,a,n,o,h,l,p,f=[[t[0],r[0]],[t[1],r[1]]],m=0;m<2;++m)a=6*t[m]-12*e[m]+6*i[m],s=-3*t[m]+9*e[m]-9*i[m]+3*r[m],n=3*e[m]-3*t[m],a|=0,n|=0,0===(s|=0)&&0===a||(0===s?0<(o=-n/a)&&o<1&&f[m].push(this.calculateF(o,t,e,i,r,m)):0<=(h=a*a-4*n*s)&&(0<(l=(-a+bmSqrt(h))/(2*s))&&l<1&&f[m].push(this.calculateF(l,t,e,i,r,m)),0<(p=(-a-bmSqrt(h))/(2*s))&&p<1&&f[m].push(this.calculateF(p,t,e,i,r,m))));this.shapeBoundingBox.left=bmMin.apply(null,f[0]),this.shapeBoundingBox.top=bmMin.apply(null,f[1]),this.shapeBoundingBox.right=bmMax.apply(null,f[0]),this.shapeBoundingBox.bottom=bmMax.apply(null,f[1])},HShapeElement.prototype.calculateF=function(t,e,i,r,s,a){return bmPow(1-t,3)*e[a]+3*bmPow(1-t,2)*t*i[a]+3*(1-t)*bmPow(t,2)*r[a]+bmPow(t,3)*s[a]},HShapeElement.prototype.calculateBoundingBox=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)t[i]&&t[i].sh?this.calculateShapeBoundingBox(t[i],e):t[i]&&t[i].it?this.calculateBoundingBox(t[i].it,e):t[i]&&t[i].style&&t[i].w&&this.expandStrokeBoundingBox(t[i].w,e)},HShapeElement.prototype.expandStrokeBoundingBox=function(t,e){var i=0;if(t.keyframes){for(var r=0;r<t.keyframes.length;r+=1){var s=t.keyframes[r].s;i<s&&(i=s)}i*=t.mult}else i=t.v*t.mult;e.x-=i,e.xMax+=i,e.y-=i,e.yMax+=i},HShapeElement.prototype.currentBoxContains=function(t){return this.currentBBox.x<=t.x&&this.currentBBox.y<=t.y&&this.currentBBox.width+this.currentBBox.x>=t.x+t.width&&this.currentBBox.height+this.currentBBox.y>=t.y+t.height},HShapeElement.prototype.renderInnerContent=function(){if(this._renderShapeFrame(),!this.hidden&&(this._isFirstFrame||this._mdf)){var t=this.tempBoundingBox,e=999999;if(t.x=e,t.xMax=-e,t.y=e,t.yMax=-e,this.calculateBoundingBox(this.itemsData,t),t.width=t.xMax<t.x?0:t.xMax-t.x,t.height=t.yMax<t.y?0:t.yMax-t.y,this.currentBoxContains(t))return;var i=!1;if(this.currentBBox.w!==t.width&&(this.currentBBox.w=t.width,this.shapeCont.setAttribute("width",t.width),i=!0),this.currentBBox.h!==t.height&&(this.currentBBox.h=t.height,this.shapeCont.setAttribute("height",t.height),i=!0),i||this.currentBBox.x!==t.x||this.currentBBox.y!==t.y){this.currentBBox.w=t.width,this.currentBBox.h=t.height,this.currentBBox.x=t.x,this.currentBBox.y=t.y,this.shapeCont.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h);var r=this.shapeCont.style,s="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)";r.transform=s,r.webkitTransform=s}}},extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],HTextElement),HTextElement.prototype.createContent=function(){if(this.isMasked=this.checkMasks(),this.isMasked){this.renderType="svg",this.compW=this.comp.data.w,this.compH=this.comp.data.h,this.svgElement.setAttribute("width",this.compW),this.svgElement.setAttribute("height",this.compH);var t=createNS("g");this.maskedElement.appendChild(t),this.innerElem=t}else this.renderType="html",this.innerElem=this.layerElement;this.checkParenting()},HTextElement.prototype.buildNewText=function(){var t=this.textProperty.currentData;this.renderedLetters=createSizedArray(t.l?t.l.length:0);var e=this.innerElem.style,i=t.fc?this.buildColor(t.fc):"rgba(0,0,0,0)";e.fill=i,e.color=i,t.sc&&(e.stroke=this.buildColor(t.sc),e.strokeWidth=t.sw+"px");var r,s,a=this.globalData.fontManager.getFontByName(t.f);if(!this.globalData.fontManager.chars)if(e.fontSize=t.finalSize+"px",e.lineHeight=t.finalSize+"px",a.fClass)this.innerElem.className=a.fClass;else{e.fontFamily=a.fFamily;var n=t.fWeight,o=t.fStyle;e.fontStyle=o,e.fontWeight=n}var h,l,p,f=t.l;s=f.length;var m,c=this.mHelper,d="",u=0;for(r=0;r<s;r+=1){if(this.globalData.fontManager.chars?(this.textPaths[u]?h=this.textPaths[u]:((h=createNS("path")).setAttribute("stroke-linecap",lineCapEnum[1]),h.setAttribute("stroke-linejoin",lineJoinEnum[2]),h.setAttribute("stroke-miterlimit","4")),this.isMasked||(this.textSpans[u]?p=(l=this.textSpans[u]).children[0]:((l=createTag("div")).style.lineHeight=0,(p=createNS("svg")).appendChild(h),styleDiv(l)))):this.isMasked?h=this.textPaths[u]?this.textPaths[u]:createNS("text"):this.textSpans[u]?(l=this.textSpans[u],h=this.textPaths[u]):(styleDiv(l=createTag("span")),styleDiv(h=createTag("span")),l.appendChild(h)),this.globalData.fontManager.chars){var y,g=this.globalData.fontManager.getCharData(t.finalText[r],a.fStyle,this.globalData.fontManager.getFontByName(t.f).fFamily);if(y=g?g.data:null,c.reset(),y&&y.shapes&&y.shapes.length&&(m=y.shapes[0].it,c.scale(t.finalSize/100,t.finalSize/100),d=this.createPathShape(c,m),h.setAttribute("d",d)),this.isMasked)this.innerElem.appendChild(h);else{if(this.innerElem.appendChild(l),y&&y.shapes){document.body.appendChild(p);var v=p.getBBox();p.setAttribute("width",v.width+2),p.setAttribute("height",v.height+2),p.setAttribute("viewBox",v.x-1+" "+(v.y-1)+" "+(v.width+2)+" "+(v.height+2));var b=p.style,x="translate("+(v.x-1)+"px,"+(v.y-1)+"px)";b.transform=x,b.webkitTransform=x,f[r].yOffset=v.y-1}else p.setAttribute("width",1),p.setAttribute("height",1);l.appendChild(p)}}else if(h.textContent=f[r].val,h.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),this.isMasked)this.innerElem.appendChild(h);else{this.innerElem.appendChild(l);var P=h.style,E="translate3d(0,"+-t.finalSize/1.2+"px,0)";P.transform=E,P.webkitTransform=E}this.isMasked?this.textSpans[u]=h:this.textSpans[u]=l,this.textSpans[u].style.display="block",this.textPaths[u]=h,u+=1}for(;u<this.textSpans.length;)this.textSpans[u].style.display="none",u+=1},HTextElement.prototype.renderInnerContent=function(){var t;if(this.validateText(),this.data.singleShape){if(!this._isFirstFrame&&!this.lettersChangedFlag)return;if(this.isMasked&&this.finalTransform._matMdf){this.svgElement.setAttribute("viewBox",-this.finalTransform.mProp.p.v[0]+" "+-this.finalTransform.mProp.p.v[1]+" "+this.compW+" "+this.compH),t=this.svgElement.style;var e="translate("+-this.finalTransform.mProp.p.v[0]+"px,"+-this.finalTransform.mProp.p.v[1]+"px)";t.transform=e,t.webkitTransform=e}}if(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag){var i,r,s,a,n,o=0,h=this.textAnimator.renderedLetters,l=this.textProperty.currentData.l;for(r=l.length,i=0;i<r;i+=1)l[i].n?o+=1:(a=this.textSpans[i],n=this.textPaths[i],s=h[o],o+=1,s._mdf.m&&(this.isMasked?a.setAttribute("transform",s.m):(a.style.webkitTransform=s.m,a.style.transform=s.m)),a.style.opacity=s.o,s.sw&&s._mdf.sw&&n.setAttribute("stroke-width",s.sw),s.sc&&s._mdf.sc&&n.setAttribute("stroke",s.sc),s.fc&&s._mdf.fc&&(n.setAttribute("fill",s.fc),n.style.color=s.fc));if(this.innerElem.getBBox&&!this.hidden&&(this._isFirstFrame||this._mdf)){var p=this.innerElem.getBBox();this.currentBBox.w!==p.width&&(this.currentBBox.w=p.width,this.svgElement.setAttribute("width",p.width)),this.currentBBox.h!==p.height&&(this.currentBBox.h=p.height,this.svgElement.setAttribute("height",p.height));if(this.currentBBox.w!==p.width+2||this.currentBBox.h!==p.height+2||this.currentBBox.x!==p.x-1||this.currentBBox.y!==p.y-1){this.currentBBox.w=p.width+2,this.currentBBox.h=p.height+2,this.currentBBox.x=p.x-1,this.currentBBox.y=p.y-1,this.svgElement.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h),t=this.svgElement.style;var f="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)";t.transform=f,t.webkitTransform=f}}}},extendPrototype([BaseElement,FrameElement,HierarchyElement],HCameraElement),HCameraElement.prototype.setup=function(){var t,e,i,r,s=this.comp.threeDElements.length;for(t=0;t<s;t+=1)if("3d"===(e=this.comp.threeDElements[t]).type){i=e.perspectiveElem.style,r=e.container.style;var a=this.pe.v+"px",n="0px 0px 0px",o="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";i.perspective=a,i.webkitPerspective=a,r.transformOrigin=n,r.mozTransformOrigin=n,r.webkitTransformOrigin=n,i.transform=o,i.webkitTransform=o}},HCameraElement.prototype.createElements=function(){},HCameraElement.prototype.hide=function(){},HCameraElement.prototype.renderFrame=function(){var t,e,i=this._isFirstFrame;if(this.hierarchy)for(e=this.hierarchy.length,t=0;t<e;t+=1)i=this.hierarchy[t].finalTransform.mProp._mdf||i;if(i||this.pe._mdf||this.p&&this.p._mdf||this.px&&(this.px._mdf||this.py._mdf||this.pz._mdf)||this.rx._mdf||this.ry._mdf||this.rz._mdf||this.or._mdf||this.a&&this.a._mdf){if(this.mat.reset(),this.hierarchy)for(t=e=this.hierarchy.length-1;0<=t;t-=1){var r=this.hierarchy[t].finalTransform.mProp;this.mat.translate(-r.p.v[0],-r.p.v[1],r.p.v[2]),this.mat.rotateX(-r.or.v[0]).rotateY(-r.or.v[1]).rotateZ(r.or.v[2]),this.mat.rotateX(-r.rx.v).rotateY(-r.ry.v).rotateZ(r.rz.v),this.mat.scale(1/r.s.v[0],1/r.s.v[1],1/r.s.v[2]),this.mat.translate(r.a.v[0],r.a.v[1],r.a.v[2])}if(this.p?this.mat.translate(-this.p.v[0],-this.p.v[1],this.p.v[2]):this.mat.translate(-this.px.v,-this.py.v,this.pz.v),this.a){var s;s=this.p?[this.p.v[0]-this.a.v[0],this.p.v[1]-this.a.v[1],this.p.v[2]-this.a.v[2]]:[this.px.v-this.a.v[0],this.py.v-this.a.v[1],this.pz.v-this.a.v[2]];var a=Math.sqrt(Math.pow(s[0],2)+Math.pow(s[1],2)+Math.pow(s[2],2)),n=[s[0]/a,s[1]/a,s[2]/a],o=Math.sqrt(n[2]*n[2]+n[0]*n[0]),h=Math.atan2(n[1],o),l=Math.atan2(n[0],-n[2]);this.mat.rotateY(l).rotateX(-h)}this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v),this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]),this.mat.translate(this.globalData.compSize.w/2,this.globalData.compSize.h/2,0),this.mat.translate(0,0,this.pe.v);var p=!this._prevMat.equals(this.mat);if((p||this.pe._mdf)&&this.comp.threeDElements){var f,m,c;for(e=this.comp.threeDElements.length,t=0;t<e;t+=1)if("3d"===(f=this.comp.threeDElements[t]).type){if(p){var d=this.mat.toCSS();(c=f.container.style).transform=d,c.webkitTransform=d}this.pe._mdf&&((m=f.perspectiveElem.style).perspective=this.pe.v+"px",m.webkitPerspective=this.pe.v+"px")}this.mat.clone(this._prevMat)}}this._isFirstFrame=!1},HCameraElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},HCameraElement.prototype.destroy=function(){},HCameraElement.prototype.getBaseElement=function(){return null},extendPrototype([BaseElement,TransformElement,HBaseElement,HSolidElement,HierarchyElement,FrameElement,RenderableElement],HImageElement),HImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData),e=new Image;this.data.hasMask?(this.imageElem=createNS("image"),this.imageElem.setAttribute("width",this.assetData.w+"px"),this.imageElem.setAttribute("height",this.assetData.h+"px"),this.imageElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.imageElem),this.baseElement.setAttribute("width",this.assetData.w),this.baseElement.setAttribute("height",this.assetData.h)):this.layerElement.appendChild(e),e.crossOrigin="anonymous",e.src=t,this.data.ln&&this.baseElement.setAttribute("id",this.data.ln)},extendPrototype([BaseRenderer],HybridRendererBase),HybridRendererBase.prototype.buildItem=SVGRenderer.prototype.buildItem,HybridRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},HybridRendererBase.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){var r=this.layers[e];if(r.ddd&&this.supports3d)this.addTo3dContainer(i,e);else if(this.threeDElements)this.addTo3dContainer(i,e);else{for(var s,a,n=0;n<e;)this.elements[n]&&!0!==this.elements[n]&&this.elements[n].getBaseElement&&(a=this.elements[n],s=(this.layers[n].ddd?this.getThreeDContainerByPos(n):a.getBaseElement())||s),n+=1;s?r.ddd&&this.supports3d||this.layerElement.insertBefore(i,s):r.ddd&&this.supports3d||this.layerElement.appendChild(i)}}},HybridRendererBase.prototype.createShape=function(t){return this.supports3d?new HShapeElement(t,this.globalData,this):new SVGShapeElement(t,this.globalData,this)},HybridRendererBase.prototype.createText=function(t){return this.supports3d?new HTextElement(t,this.globalData,this):new SVGTextLottieElement(t,this.globalData,this)},HybridRendererBase.prototype.createCamera=function(t){return this.camera=new HCameraElement(t,this.globalData,this),this.camera},HybridRendererBase.prototype.createImage=function(t){return this.supports3d?new HImageElement(t,this.globalData,this):new IImageElement(t,this.globalData,this)},HybridRendererBase.prototype.createSolid=function(t){return this.supports3d?new HSolidElement(t,this.globalData,this):new ISolidElement(t,this.globalData,this)},HybridRendererBase.prototype.createNull=SVGRenderer.prototype.createNull,HybridRendererBase.prototype.getThreeDContainerByPos=function(t){for(var e=0,i=this.threeDElements.length;e<i;){if(this.threeDElements[e].startPos<=t&&this.threeDElements[e].endPos>=t)return this.threeDElements[e].perspectiveElem;e+=1}return null},HybridRendererBase.prototype.createThreeDContainer=function(t,e){var i,r,s=createTag("div");styleDiv(s);var a=createTag("div");if(styleDiv(a),"3d"===e){(i=s.style).width=this.globalData.compSize.w+"px",i.height=this.globalData.compSize.h+"px";var n="50% 50%";i.webkitTransformOrigin=n,i.mozTransformOrigin=n,i.transformOrigin=n;var o="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";(r=a.style).transform=o,r.webkitTransform=o}s.appendChild(a);var h={container:a,perspectiveElem:s,startPos:t,endPos:t,type:e};return this.threeDElements.push(h),h},HybridRendererBase.prototype.build3dContainers=function(){var t,e,i=this.layers.length,r="";for(t=0;t<i;t+=1)this.layers[t].ddd&&3!==this.layers[t].ty?"3d"!==r&&(r="3d",e=this.createThreeDContainer(t,"3d")):"2d"!==r&&(r="2d",e=this.createThreeDContainer(t,"2d")),e.endPos=Math.max(e.endPos,t);for(t=(i=this.threeDElements.length)-1;0<=t;t-=1)this.resizerElem.appendChild(this.threeDElements[t].perspectiveElem)},HybridRendererBase.prototype.addTo3dContainer=function(t,e){for(var i=0,r=this.threeDElements.length;i<r;){if(e<=this.threeDElements[i].endPos){for(var s,a=this.threeDElements[i].startPos;a<e;)this.elements[a]&&this.elements[a].getBaseElement&&(s=this.elements[a].getBaseElement()),a+=1;s?this.threeDElements[i].container.insertBefore(t,s):this.threeDElements[i].container.appendChild(t);break}i+=1}},HybridRendererBase.prototype.configAnimation=function(t){var e=createTag("div"),i=this.animationItem.wrapper,r=e.style;r.width=t.w+"px",r.height=t.h+"px",styleDiv(this.resizerElem=e),r.transformStyle="flat",r.mozTransformStyle="flat",r.webkitTransformStyle="flat",this.renderConfig.className&&e.setAttribute("class",this.renderConfig.className),i.appendChild(e),r.overflow="hidden";var s=createNS("svg");s.setAttribute("width","1"),s.setAttribute("height","1"),styleDiv(s),this.resizerElem.appendChild(s);var a=createNS("defs");s.appendChild(a),this.data=t,this.setupGlobalData(t,s),this.globalData.defs=a,this.layers=t.layers,this.layerElement=this.resizerElem,this.build3dContainers(),this.updateContainerSize()},HybridRendererBase.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.animationItem.container=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},HybridRendererBase.prototype.updateContainerSize=function(){var t,e,i,r,s=this.animationItem.wrapper.offsetWidth,a=this.animationItem.wrapper.offsetHeight;r=s/a<this.globalData.compSize.w/this.globalData.compSize.h?(t=s/this.globalData.compSize.w,e=s/this.globalData.compSize.w,i=0,(a-this.globalData.compSize.h*(s/this.globalData.compSize.w))/2):(t=a/this.globalData.compSize.h,e=a/this.globalData.compSize.h,i=(s-this.globalData.compSize.w*(a/this.globalData.compSize.h))/2,0);var n=this.resizerElem.style;n.webkitTransform="matrix3d("+t+",0,0,0,0,"+e+",0,0,0,0,1,0,"+i+","+r+",0,1)",n.transform=n.webkitTransform},HybridRendererBase.prototype.renderFrame=SVGRenderer.prototype.renderFrame,HybridRendererBase.prototype.hide=function(){this.resizerElem.style.display="none"},HybridRendererBase.prototype.show=function(){this.resizerElem.style.display="block"},HybridRendererBase.prototype.initItems=function(){if(this.buildAllItems(),this.camera)this.camera.setup();else{var t,e=this.globalData.compSize.w,i=this.globalData.compSize.h,r=this.threeDElements.length;for(t=0;t<r;t+=1){var s=this.threeDElements[t].perspectiveElem.style;s.webkitPerspective=Math.sqrt(Math.pow(e,2)+Math.pow(i,2))+"px",s.perspective=s.webkitPerspective}}},HybridRendererBase.prototype.searchExtraCompositions=function(t){var e,i=t.length,r=createTag("div");for(e=0;e<i;e+=1)if(t[e].xt){var s=this.createComp(t[e],r,this.globalData.comp,null);s.initExpressions(),this.globalData.projectInterface.registerComposition(s)}},extendPrototype([HybridRendererBase,ICompElement,HBaseElement],HCompElement),HCompElement.prototype._createBaseContainerElements=HCompElement.prototype.createContainerElements,HCompElement.prototype.createContainerElements=function(){this._createBaseContainerElements(),this.data.hasMask?(this.svgElement.setAttribute("width",this.data.w),this.svgElement.setAttribute("height",this.data.h),this.transformedElement=this.baseElement):this.transformedElement=this.layerElement},HCompElement.prototype.addTo3dContainer=function(t,e){for(var i,r=0;r<e;)this.elements[r]&&this.elements[r].getBaseElement&&(i=this.elements[r].getBaseElement()),r+=1;i?this.layerElement.insertBefore(t,i):this.layerElement.appendChild(t)},HCompElement.prototype.createComp=function(t){return this.supports3d?new HCompElement(t,this.globalData,this):new SVGCompElement(t,this.globalData,this)},extendPrototype([HybridRendererBase],HybridRenderer),HybridRenderer.prototype.createComp=function(t){return this.supports3d?new HCompElement(t,this.globalData,this):new SVGCompElement(t,this.globalData,this)};var CompExpressionInterface=function(r){function t(t){for(var e=0,i=r.layers.length;e<i;){if(r.layers[e].nm===t||r.layers[e].ind===t)return r.elements[e].layerInterface;e+=1}return null}return Object.defineProperty(t,"_name",{value:r.data.nm}),(t.layer=t).pixelAspect=1,t.height=r.data.h||r.globalData.compSize.h,t.width=r.data.w||r.globalData.compSize.w,t.pixelAspect=1,t.frameDuration=1/r.globalData.frameRate,t.displayStartTime=0,t.numLayers=r.layers.length,t};function _typeof$2(t){return(_typeof$2="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function seedRandom(o,h){var l,p=this,f=256,m=6,c="random",d=h.pow(f,m),u=h.pow(2,52),y=2*u,g=f-1;function v(t){var e,i=t.length,n=this,r=0,s=n.i=n.j=0,a=n.S=[];for(i||(t=[i++]);r<f;)a[r]=r++;for(r=0;r<f;r++)a[r]=a[s=g&s+t[r%i]+(e=a[r])],a[s]=e;n.g=function(t){for(var e,i=0,r=n.i,s=n.j,a=n.S;t--;)e=a[r=g&r+1],i=i*f+a[g&(a[r]=a[s=g&s+e])+(a[s]=e)];return n.i=r,n.j=s,i}}function b(t,e){return e.i=t.i,e.j=t.j,e.S=t.S.slice(),e}function x(t,e){for(var i,r=t+"",s=0;s<r.length;)e[g&s]=g&(i^=19*e[g&s])+r.charCodeAt(s++);return P(e)}function P(t){return String.fromCharCode.apply(0,t)}h["seed"+c]=function(t,e,i){var r=[],s=x(function t(e,i){var r,s=[],a=_typeof$2(e);if(i&&"object"==a)for(r in e)try{s.push(t(e[r],i-1))}catch(t){}return s.length?s:"string"==a?e:e+"\0"}((e=!0===e?{entropy:!0}:e||{}).entropy?[t,P(o)]:null===t?function(){try{if(l)return P(l.randomBytes(f));var t=new Uint8Array(f);return(p.crypto||p.msCrypto).getRandomValues(t),P(t)}catch(t){var e=p.navigator,i=e&&e.plugins;return[+new Date,p,i,p.screen,P(o)]}}():t,3),r),a=new v(r),n=function(){for(var t=a.g(m),e=d,i=0;t<u;)t=(t+i)*f,e*=f,i=a.g(1);for(;y<=t;)t/=2,e/=2,i>>>=1;return(t+i)/e};return n.int32=function(){return 0|a.g(4)},n.quick=function(){return a.g(4)/4294967296},n.double=n,x(P(a.S),o),(e.pass||i||function(t,e,i,r){return r&&(r.S&&b(r,a),t.state=function(){return b(a,{})}),i?(h[c]=t,e):t})(n,s,"global"in e?e.global:this==h,e.state)},x(h.random(),o)}function initialize$2(t){seedRandom([],t)}var propTypes={SHAPE:"shape"};function _typeof$1(t){return(_typeof$1="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var ExpressionManager=function(){var ob={},Math=BMMath,window=null,document=null,XMLHttpRequest=null,fetch=null,frames=null,_lottieGlobal={};function resetFrame(){_lottieGlobal={}}function $bm_isInstanceOfArray(t){return t.constructor===Array||t.constructor===Float32Array}function isNumerable(t,e){return"number"===t||e instanceof Number||"boolean"===t||"string"===t}function $bm_neg(t){var e=_typeof$1(t);if("number"===e||t instanceof Number||"boolean"===e)return-t;if($bm_isInstanceOfArray(t)){var i,r=t.length,s=[];for(i=0;i<r;i+=1)s[i]=-t[i];return s}return t.propType?t.v:-t}initialize$2(BMMath);var easeInBez=BezierFactory.getBezierEasing(.333,0,.833,.833,"easeIn").get,easeOutBez=BezierFactory.getBezierEasing(.167,.167,.667,1,"easeOut").get,easeInOutBez=BezierFactory.getBezierEasing(.33,0,.667,1,"easeInOut").get;function sum(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e)||"string"===i||"string"===r)return t+e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]+=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t+e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]+e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}var add=sum;function sub(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e))return"string"===i&&(t=parseInt(t,10)),"string"===r&&(e=parseInt(e,10)),t-e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]-=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t-e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]-e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}function mul(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t*e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]*e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t*e[r];return i}return 0}function div(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t/e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]/e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t/e[r];return i}return 0}function mod(t,e){return"string"==typeof t&&(t=parseInt(t,10)),"string"==typeof e&&(e=parseInt(e,10)),t%e}var $bm_sum=sum,$bm_sub=sub,$bm_mul=mul,$bm_div=div,$bm_mod=mod;function clamp(t,e,i){if(i<e){var r=i;i=e,e=r}return Math.min(Math.max(t,e),i)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return e=e||0,Math.abs(t-e);var i;e||(e=helperLengthArray);var r=Math.min(t.length,e.length),s=0;for(i=0;i<r;i+=1)s+=Math.pow(e[i]-t[i],2);return Math.sqrt(s)}function normalize(t){return div(t,length(t))}function rgbToHsl(t){var e,i,r=t[0],s=t[1],a=t[2],n=Math.max(r,s,a),o=Math.min(r,s,a),h=(n+o)/2;if(n===o)i=e=0;else{var l=n-o;switch(i=.5<h?l/(2-n-o):l/(n+o),n){case r:e=(s-a)/l+(s<a?6:0);break;case s:e=(a-r)/l+2;break;case a:e=(r-s)/l+4}e/=6}return[e,i,h,t[3]]}function hue2rgb(t,e,i){return i<0&&(i+=1),1<i&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}function hslToRgb(t){var e,i,r,s=t[0],a=t[1],n=t[2];if(0===a)i=r=e=n;else{var o=n<.5?n*(1+a):n+a-n*a,h=2*n-o;e=hue2rgb(h,o,s+1/3),i=hue2rgb(h,o,s),r=hue2rgb(h,o,s-1/3)}return[e,i,r,t[3]]}function linear(t,e,i,r,s){if(void 0!==r&&void 0!==s||(r=e,s=i,e=0,i=1),i<e){var a=i;i=e,e=a}if(t<=e)return r;if(i<=t)return s;var n,o=i===e?0:(t-e)/(i-e);if(!r.length)return r+(s-r)*o;var h=r.length,l=createTypedArray("float32",h);for(n=0;n<h;n+=1)l[n]=r[n]+(s[n]-r[n])*o;return l}function random(t,e){if(void 0===e&&(void 0===t?(t=0,e=1):(e=t,t=void 0)),e.length){var i,r=e.length;t||(t=createTypedArray("float32",r));var s=createTypedArray("float32",r),a=BMMath.random();for(i=0;i<r;i+=1)s[i]=t[i]+a*(e[i]-t[i]);return s}return void 0===t&&(t=0),t+BMMath.random()*(e-t)}function createPath(t,e,i,r){var s,a=t.length,n=shapePool.newElement();n.setPathData(!!r,a);var o,h,l=[0,0];for(s=0;s<a;s+=1)o=e&&e[s]?e[s]:l,h=i&&i[s]?i[s]:l,n.setTripleAt(t[s][0],t[s][1],h[0]+t[s][0],h[1]+t[s][1],o[0]+t[s][0],o[1]+t[s][1],s,!0);return n}function initiateExpression(elem,data,property){function noOp(t){return t}if(!elem.globalData.renderConfig.runExpressions)return noOp;var val=data.x,needsVelocity=/velocity(?![\w\d])/.test(val),_needsRandom=-1!==val.indexOf("random"),elemType=elem.data.ty,transform,$bm_transform,content,effect,thisProperty=property;thisProperty.valueAtTime=thisProperty.getValueAtTime,Object.defineProperty(thisProperty,"value",{get:function(){return thisProperty.v}}),elem.comp.frameDuration=1/elem.comp.globalData.frameRate,elem.comp.displayStartTime=0;var inPoint=elem.data.ip/elem.comp.globalData.frameRate,outPoint=elem.data.op/elem.comp.globalData.frameRate,width=elem.data.sw?elem.data.sw:0,height=elem.data.sh?elem.data.sh:0,name=elem.data.nm,loopIn,loop_in,loopOut,loop_out,smooth,toWorld,fromWorld,fromComp,toComp,fromCompToSurface,position,rotation,anchorPoint,scale,thisLayer,thisComp,mask,valueAtTime,velocityAtTime,scoped_bm_rt,expression_function=eval("[function _expression_function(){"+val+";scoped_bm_rt=$bm_rt}]")[0],numKeys=property.kf?data.k.length:0,active=!this.data||!0!==this.data.hd,wiggle=function(t,e){var i,r,s=this.pv.length?this.pv.length:1,a=createTypedArray("float32",s);var n=Math.floor(5*time);for(r=i=0;i<n;){for(r=0;r<s;r+=1)a[r]+=-e+2*e*BMMath.random();i+=1}var o=5*time,h=o-Math.floor(o),l=createTypedArray("float32",s);if(1<s){for(r=0;r<s;r+=1)l[r]=this.pv[r]+a[r]+(-e+2*e*BMMath.random())*h;return l}return this.pv+a[0]+(-e+2*e*BMMath.random())*h}.bind(this);function loopInDuration(t,e){return loopIn(t,e,!0)}function loopOutDuration(t,e){return loopOut(t,e,!0)}thisProperty.loopIn&&(loopIn=thisProperty.loopIn.bind(thisProperty),loop_in=loopIn),thisProperty.loopOut&&(loopOut=thisProperty.loopOut.bind(thisProperty),loop_out=loopOut),thisProperty.smooth&&(smooth=thisProperty.smooth.bind(thisProperty)),this.getValueAtTime&&(valueAtTime=this.getValueAtTime.bind(this)),this.getVelocityAtTime&&(velocityAtTime=this.getVelocityAtTime.bind(this));var comp=elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface),time,velocity,value,text,textIndex,textTotal,selectorValue;function lookAt(t,e){var i=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],r=Math.atan2(i[0],Math.sqrt(i[1]*i[1]+i[2]*i[2]))/degToRads;return[-Math.atan2(i[1],i[2])/degToRads,r,0]}function easeOut(t,e,i,r,s){return applyEase(easeOutBez,t,e,i,r,s)}function easeIn(t,e,i,r,s){return applyEase(easeInBez,t,e,i,r,s)}function ease(t,e,i,r,s){return applyEase(easeInOutBez,t,e,i,r,s)}function applyEase(t,e,i,r,s,a){void 0===s?(s=i,a=r):e=(e-i)/(r-i),1<e?e=1:e<0&&(e=0);var n=t(e);if($bm_isInstanceOfArray(s)){var o,h=s.length,l=createTypedArray("float32",h);for(o=0;o<h;o+=1)l[o]=(a[o]-s[o])*n+s[o];return l}return(a-s)*n+s}function nearestKey(t){var e,i,r,s=data.k.length;if(data.k.length&&"number"!=typeof data.k[0])if(i=-1,(t*=elem.comp.globalData.frameRate)<data.k[0].t)i=1,r=data.k[0].t;else{for(e=0;e<s-1;e+=1){if(t===data.k[e].t){i=e+1,r=data.k[e].t;break}if(t>data.k[e].t&&t<data.k[e+1].t){r=t-data.k[e].t>data.k[e+1].t-t?(i=e+2,data.k[e+1].t):(i=e+1,data.k[e].t);break}}-1===i&&(i=e+1,r=data.k[e].t)}else r=i=0;var a={};return a.index=i,a.time=r/elem.comp.globalData.frameRate,a}function key(t){var e,i,r;if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]};var s=Object.prototype.hasOwnProperty.call(data.k[t],"s")?data.k[t].s:data.k[t-1].e;for(r=s.length,i=0;i<r;i+=1)e[i]=s[i],e.value[i]=s[i];return e}function framesToTime(t,e){return e||(e=elem.comp.globalData.frameRate),t/e}function timeToFrames(t,e){return t||0===t||(t=time),e||(e=elem.comp.globalData.frameRate),t*e}function seedRandom(t){BMMath.seedrandom(randSeed+t)}function sourceRectAtTime(){return elem.sourceRectAtTime()}function substring(t,e){return"string"==typeof value?void 0===e?value.substring(t):value.substring(t,e):""}function substr(t,e){return"string"==typeof value?void 0===e?value.substr(t):value.substr(t,e):""}function posterizeTime(t){time=0===t?0:Math.floor(time*t)/t,value=valueAtTime(time)}var index=elem.data.ind,hasParent=!(!elem.hierarchy||!elem.hierarchy.length),parent,randSeed=Math.floor(1e6*Math.random()),globalData=elem.globalData;function executeExpression(t){return value=t,this.frameExpressionId===elem.globalData.frameId&&"textSelector"!==this.propType?value:("textSelector"===this.propType&&(textIndex=this.textIndex,textTotal=this.textTotal,selectorValue=this.selectorValue),thisLayer||(text=elem.layerInterface.text,thisLayer=elem.layerInterface,thisComp=elem.comp.compInterface,toWorld=thisLayer.toWorld.bind(thisLayer),fromWorld=thisLayer.fromWorld.bind(thisLayer),fromComp=thisLayer.fromComp.bind(thisLayer),toComp=thisLayer.toComp.bind(thisLayer),mask=thisLayer.mask?thisLayer.mask.bind(thisLayer):null,fromCompToSurface=fromComp),transform||(transform=elem.layerInterface("ADBE Transform Group"),($bm_transform=transform)&&(anchorPoint=transform.anchorPoint)),4!==elemType||content||(content=thisLayer("ADBE Root Vectors Group")),effect||(effect=thisLayer(4)),(hasParent=!(!elem.hierarchy||!elem.hierarchy.length))&&!parent&&(parent=elem.hierarchy[0].layerInterface),time=this.comp.renderedFrame/this.comp.globalData.frameRate,_needsRandom&&seedRandom(randSeed+time),needsVelocity&&(velocity=velocityAtTime(time)),expression_function(),this.frameExpressionId=elem.globalData.frameId,scoped_bm_rt=scoped_bm_rt.propType===propTypes.SHAPE?scoped_bm_rt.v:scoped_bm_rt)}return executeExpression.__preventDeadCodeRemoval=[$bm_transform,anchorPoint,time,velocity,inPoint,outPoint,width,height,name,loop_in,loop_out,smooth,toComp,fromCompToSurface,toWorld,fromWorld,mask,position,rotation,scale,thisComp,numKeys,active,wiggle,loopInDuration,loopOutDuration,comp,lookAt,easeOut,easeIn,ease,nearestKey,key,text,textIndex,textTotal,selectorValue,framesToTime,timeToFrames,sourceRectAtTime,substring,substr,posterizeTime,index,globalData],executeExpression}return ob.initiateExpression=initiateExpression,ob.__preventDeadCodeRemoval=[window,document,XMLHttpRequest,fetch,frames,$bm_neg,add,$bm_sum,$bm_sub,$bm_mul,$bm_div,$bm_mod,clamp,radians_to_degrees,degreesToRadians,degrees_to_radians,normalize,rgbToHsl,hslToRgb,linear,random,createPath,_lottieGlobal],ob.resetFrame=resetFrame,ob}(),Expressions=(Dba={},Dba.initExpressions=function(t){var e=0,i=[];function r(){var t,e=i.length;for(t=0;t<e;t+=1)i[t].release();i.length=0}t.renderer.compInterface=CompExpressionInterface(t.renderer),t.renderer.globalData.projectInterface.registerComposition(t.renderer),t.renderer.globalData.pushExpression=function(){e+=1},t.renderer.globalData.popExpression=function(){0==(e-=1)&&r()},t.renderer.globalData.registerExpressionProperty=function(t){-1===i.indexOf(t)&&i.push(t)}},Dba.resetFrame=ExpressionManager.resetFrame,Dba),Dba,MaskManagerInterface=function(){function t(t,e){this._mask=t,this._data=e}Object.defineProperty(t.prototype,"maskPath",{get:function(){return this._mask.prop.k&&this._mask.prop.getValue(),this._mask.prop}}),Object.defineProperty(t.prototype,"maskOpacity",{get:function(){return this._mask.op.k&&this._mask.op.getValue(),100*this._mask.op.v}});return function(e){var i,r=createSizedArray(e.viewData.length),s=e.viewData.length;for(i=0;i<s;i+=1)r[i]=new t(e.viewData[i],e.masksProperties[i]);return function(t){for(i=0;i<s;){if(e.masksProperties[i].nm===t)return r[i];i+=1}return null}}}(),ExpressionPropertyInterface=function(){var s={pv:0,v:0,mult:1},n={pv:[0,0,0],v:[0,0,0],mult:1};function o(r,s,a){Object.defineProperty(r,"velocity",{get:function(){return s.getVelocityAtTime(s.comp.currentFrame)}}),r.numKeys=s.keyframes?s.keyframes.length:0,r.key=function(t){if(!r.numKeys)return 0;var e="";e="s"in s.keyframes[t-1]?s.keyframes[t-1].s:"e"in s.keyframes[t-2]?s.keyframes[t-2].e:s.keyframes[t-2].s;var i="unidimensional"===a?new Number(e):Object.assign({},e);return i.time=s.keyframes[t-1].t/s.elem.comp.globalData.frameRate,i.value="unidimensional"===a?e[0]:e,i},r.valueAtTime=s.getValueAtTime,r.speedAtTime=s.getSpeedAtTime,r.velocityAtTime=s.getVelocityAtTime,r.propertyGroup=s.propertyGroup}function e(){return s}return function(t){return t?"unidimensional"===t.propType?function(t){t&&"pv"in t||(t=s);var e=1/t.mult,i=t.pv*e,r=new Number(i);return r.value=i,o(r,t,"unidimensional"),function(){return t.k&&t.getValue(),i=t.v*e,r.value!==i&&((r=new Number(i)).value=i,o(r,t,"unidimensional")),r}}(t):function(e){e&&"pv"in e||(e=n);var i=1/e.mult,r=e.data&&e.data.l||e.pv.length,s=createTypedArray("float32",r),a=createTypedArray("float32",r);return s.value=a,o(s,e,"multidimensional"),function(){e.k&&e.getValue();for(var t=0;t<r;t+=1)a[t]=e.v[t]*i,s[t]=a[t];return s}}(t):e}}(),TransformExpressionInterface=function(t){function e(t){switch(t){case"scale":case"Scale":case"ADBE Scale":case 6:return e.scale;case"rotation":case"Rotation":case"ADBE Rotation":case"ADBE Rotate Z":case 10:return e.rotation;case"ADBE Rotate X":return e.xRotation;case"ADBE Rotate Y":return e.yRotation;case"position":case"Position":case"ADBE Position":case 2:return e.position;case"ADBE Position_0":return e.xPosition;case"ADBE Position_1":return e.yPosition;case"ADBE Position_2":return e.zPosition;case"anchorPoint":case"AnchorPoint":case"Anchor Point":case"ADBE AnchorPoint":case 1:return e.anchorPoint;case"opacity":case"Opacity":case 11:return e.opacity;default:return null}}var i,r,s,a;return Object.defineProperty(e,"rotation",{get:ExpressionPropertyInterface(t.r||t.rz)}),Object.defineProperty(e,"zRotation",{get:ExpressionPropertyInterface(t.rz||t.r)}),Object.defineProperty(e,"xRotation",{get:ExpressionPropertyInterface(t.rx)}),Object.defineProperty(e,"yRotation",{get:ExpressionPropertyInterface(t.ry)}),Object.defineProperty(e,"scale",{get:ExpressionPropertyInterface(t.s)}),t.p?a=ExpressionPropertyInterface(t.p):(i=ExpressionPropertyInterface(t.px),r=ExpressionPropertyInterface(t.py),t.pz&&(s=ExpressionPropertyInterface(t.pz))),Object.defineProperty(e,"position",{get:function(){return t.p?a():[i(),r(),s?s():0]}}),Object.defineProperty(e,"xPosition",{get:ExpressionPropertyInterface(t.px)}),Object.defineProperty(e,"yPosition",{get:ExpressionPropertyInterface(t.py)}),Object.defineProperty(e,"zPosition",{get:ExpressionPropertyInterface(t.pz)}),Object.defineProperty(e,"anchorPoint",{get:ExpressionPropertyInterface(t.a)}),Object.defineProperty(e,"opacity",{get:ExpressionPropertyInterface(t.o)}),Object.defineProperty(e,"skew",{get:ExpressionPropertyInterface(t.sk)}),Object.defineProperty(e,"skewAxis",{get:ExpressionPropertyInterface(t.sa)}),Object.defineProperty(e,"orientation",{get:ExpressionPropertyInterface(t.or)}),e},LayerExpressionInterface=function(){function s(t){var e=new Matrix;void 0!==t?this._elem.finalTransform.mProp.getValueAtTime(t).clone(e):this._elem.finalTransform.mProp.applyToMatrix(e);return e}function a(t,e){var i=this.getMatrix(e);return i.props[12]=0,i.props[13]=0,i.props[14]=0,this.applyPoint(i,t)}function n(t,e){var i=this.getMatrix(e);return this.applyPoint(i,t)}function o(t,e){var i=this.getMatrix(e);return i.props[12]=0,i.props[13]=0,i.props[14]=0,this.invertPoint(i,t)}function h(t,e){var i=this.getMatrix(e);return this.invertPoint(i,t)}function l(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(t)}return t.applyToPointArray(e[0],e[1],e[2]||0)}function p(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(t)}return t.inversePoint(e)}function f(t){var e=new Matrix;if(e.reset(),this._elem.finalTransform.mProp.applyToMatrix(e),this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(e);return e.inversePoint(t)}return e.inversePoint(t)}function m(){return[1,1,1,1]}return function(e){var i;function r(t){switch(t){case"ADBE Root Vectors Group":case"Contents":case 2:return r.shapeInterface;case 1:case 6:case"Transform":case"transform":case"ADBE Transform Group":return i;case 4:case"ADBE Effect Parade":case"effects":case"Effects":return r.effect;case"ADBE Text Properties":return r.textInterface;default:return null}}r.getMatrix=s,r.invertPoint=p,r.applyPoint=l,r.toWorld=n,r.toWorldVec=a,r.fromWorld=h,r.fromWorldVec=o,r.toComp=n,r.fromComp=f,r.sampleImage=m,r.sourceRectAtTime=e.sourceRectAtTime.bind(e);var t=getDescriptor(i=TransformExpressionInterface((r._elem=e).finalTransform.mProp),"anchorPoint");return Object.defineProperties(r,{hasParent:{get:function(){return e.hierarchy.length}},parent:{get:function(){return e.hierarchy[0].layerInterface}},rotation:getDescriptor(i,"rotation"),scale:getDescriptor(i,"scale"),position:getDescriptor(i,"position"),opacity:getDescriptor(i,"opacity"),anchorPoint:t,anchor_point:t,transform:{get:function(){return i}},active:{get:function(){return e.isInRange}}}),r.startTime=e.data.st,r.index=e.data.ind,r.source=e.data.refId,r.height=0===e.data.ty?e.data.h:100,r.width=0===e.data.ty?e.data.w:100,r.inPoint=e.data.ip/e.comp.globalData.frameRate,r.outPoint=e.data.op/e.comp.globalData.frameRate,r._name=e.data.nm,r.registerMaskInterface=function(t){r.mask=new MaskManagerInterface(t,e)},r.registerEffectsInterface=function(t){r.effect=t},r}}(),propertyGroupFactory=function(e,i){return function(t){return(t=void 0===t?1:t)<=0?e:i(t-1)}},PropertyInterface=function(t,e){var i={_name:t};return function(t){return(t=void 0===t?1:t)<=0?i:e(t-1)}},EffectsExpressionInterface=function(){function l(s,t,e,i){function r(t){for(var e=s.ef,i=0,r=e.length;i<r;){if(t===e[i].nm||t===e[i].mn||t===e[i].ix)return 5===e[i].ty?o[i]:o[i]();i+=1}throw new Error}var a,n=propertyGroupFactory(r,e),o=[],h=s.ef.length;for(a=0;a<h;a+=1)5===s.ef[a].ty?o.push(l(s.ef[a],t.effectElements[a],t.effectElements[a].propertyGroup,i)):o.push(p(t.effectElements[a],s.ef[a].ty,i,n));return"ADBE Color Control"===s.mn&&Object.defineProperty(r,"color",{get:function(){return o[0]()}}),Object.defineProperties(r,{numProperties:{get:function(){return s.np}},_name:{value:s.nm},propertyGroup:{value:n}}),r.enabled=0!==s.en,r.active=r.enabled,r}function p(t,e,i,r){var s=ExpressionPropertyInterface(t.p);return t.p.setGroupProperty&&t.p.setGroupProperty(PropertyInterface("",r)),function(){return 10===e?i.comp.compInterface(t.p.v):s()}}return{createEffectsInterface:function(t,e){if(t.effectsManager){var i,r=[],s=t.data.ef,a=t.effectsManager.effectElements.length;for(i=0;i<a;i+=1)r.push(l(s[i],t.effectsManager.effectElements[i],e,t));var n=t.data.ef||[],o=function(t){for(i=0,a=n.length;i<a;){if(t===n[i].nm||t===n[i].mn||t===n[i].ix)return r[i];i+=1}return null};return Object.defineProperty(o,"numProperties",{get:function(){return n.length}}),o}return null}}}(),ShapePathInterface=function(t,e,i){var r=e.sh;function s(t){return"Shape"===t||"shape"===t||"Path"===t||"path"===t||"ADBE Vector Shape"===t||2===t?s.path:null}var a=propertyGroupFactory(s,i);return r.setGroupProperty(PropertyInterface("Path",a)),Object.defineProperties(s,{path:{get:function(){return r.k&&r.getValue(),r}},shape:{get:function(){return r.k&&r.getValue(),r}},_name:{value:t.nm},ix:{value:t.ix},propertyIndex:{value:t.ix},mn:{value:t.mn},propertyGroup:{value:i}}),s},ShapeExpressionInterface=function(){function n(t,e,i){var r,s=[],a=t?t.length:0;for(r=0;r<a;r+=1)"gr"===t[r].ty?s.push(o(t[r],e[r],i)):"fl"===t[r].ty?s.push(h(t[r],e[r],i)):"st"===t[r].ty?s.push(f(t[r],e[r],i)):"tm"===t[r].ty?s.push(m(t[r],e[r],i)):"tr"===t[r].ty||("el"===t[r].ty?s.push(d(t[r],e[r],i)):"sr"===t[r].ty?s.push(u(t[r],e[r],i)):"sh"===t[r].ty?s.push(ShapePathInterface(t[r],e[r],i)):"rc"===t[r].ty?s.push(y(t[r],e[r],i)):"rd"===t[r].ty?s.push(g(t[r],e[r],i)):"rp"===t[r].ty?s.push(v(t[r],e[r],i)):"gf"===t[r].ty?s.push(l(t[r],e[r],i)):s.push(p(t[r],e[r])));return s}function o(t,e,i){var r=function(t){switch(t){case"ADBE Vectors Group":case"Contents":case 2:return r.content;default:return r.transform}};r.propertyGroup=propertyGroupFactory(r,i);var s=function(t,e,i){var r,s=function(t){for(var e=0,i=r.length;e<i;){if(r[e]._name===t||r[e].mn===t||r[e].propertyIndex===t||r[e].ix===t||r[e].ind===t)return r[e];e+=1}return"number"==typeof t?r[t-1]:null};s.propertyGroup=propertyGroupFactory(s,i),r=n(t.it,e.it,s.propertyGroup),s.numProperties=r.length;var a=c(t.it[t.it.length-1],e.it[e.it.length-1],s.propertyGroup);return s.transform=a,s.propertyIndex=t.cix,s._name=t.nm,s}(t,e,r.propertyGroup),a=c(t.it[t.it.length-1],e.it[e.it.length-1],r.propertyGroup);return r.content=s,r.transform=a,Object.defineProperty(r,"_name",{get:function(){return t.nm}}),r.numProperties=t.np,r.propertyIndex=t.ix,r.nm=t.nm,r.mn=t.mn,r}function h(t,e,i){function r(t){return"Color"===t||"color"===t?r.color:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r}function l(t,e,i){function r(t){return"Start Point"===t||"start point"===t?r.startPoint:"End Point"===t||"end point"===t?r.endPoint:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{startPoint:{get:ExpressionPropertyInterface(e.s)},endPoint:{get:ExpressionPropertyInterface(e.e)},opacity:{get:ExpressionPropertyInterface(e.o)},type:{get:function(){return"a"}},_name:{value:t.nm},mn:{value:t.mn}}),e.s.setGroupProperty(PropertyInterface("Start Point",i)),e.e.setGroupProperty(PropertyInterface("End Point",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r}function p(){return function(){return null}}function f(t,e,i){var r,s=propertyGroupFactory(l,i),a=propertyGroupFactory(h,s);var n,o=t.d?t.d.length:0,h={};for(r=0;r<o;r+=1)n=r,Object.defineProperty(h,t.d[n].nm,{get:ExpressionPropertyInterface(e.d.dataProps[n].p)}),e.d.dataProps[r].p.setGroupProperty(a);function l(t){return"Color"===t||"color"===t?l.color:"Opacity"===t||"opacity"===t?l.opacity:"Stroke Width"===t||"stroke width"===t?l.strokeWidth:null}return Object.defineProperties(l,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},strokeWidth:{get:ExpressionPropertyInterface(e.w)},dash:{get:function(){return h}},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",s)),e.o.setGroupProperty(PropertyInterface("Opacity",s)),e.w.setGroupProperty(PropertyInterface("Stroke Width",s)),l}function m(e,t,i){function r(t){return t===e.e.ix||"End"===t||"end"===t?r.end:t===e.s.ix?r.start:t===e.o.ix?r.offset:null}var s=propertyGroupFactory(r,i);return r.propertyIndex=e.ix,t.s.setGroupProperty(PropertyInterface("Start",s)),t.e.setGroupProperty(PropertyInterface("End",s)),t.o.setGroupProperty(PropertyInterface("Offset",s)),r.propertyIndex=e.ix,r.propertyGroup=i,Object.defineProperties(r,{start:{get:ExpressionPropertyInterface(t.s)},end:{get:ExpressionPropertyInterface(t.e)},offset:{get:ExpressionPropertyInterface(t.o)},_name:{value:e.nm}}),r.mn=e.mn,r}function c(e,t,i){function r(t){return e.a.ix===t||"Anchor Point"===t?r.anchorPoint:e.o.ix===t||"Opacity"===t?r.opacity:e.p.ix===t||"Position"===t?r.position:e.r.ix===t||"Rotation"===t||"ADBE Vector Rotation"===t?r.rotation:e.s.ix===t||"Scale"===t?r.scale:e.sk&&e.sk.ix===t||"Skew"===t?r.skew:e.sa&&e.sa.ix===t||"Skew Axis"===t?r.skewAxis:null}var s=propertyGroupFactory(r,i);return t.transform.mProps.o.setGroupProperty(PropertyInterface("Opacity",s)),t.transform.mProps.p.setGroupProperty(PropertyInterface("Position",s)),t.transform.mProps.a.setGroupProperty(PropertyInterface("Anchor Point",s)),t.transform.mProps.s.setGroupProperty(PropertyInterface("Scale",s)),t.transform.mProps.r.setGroupProperty(PropertyInterface("Rotation",s)),t.transform.mProps.sk&&(t.transform.mProps.sk.setGroupProperty(PropertyInterface("Skew",s)),t.transform.mProps.sa.setGroupProperty(PropertyInterface("Skew Angle",s))),t.transform.op.setGroupProperty(PropertyInterface("Opacity",s)),Object.defineProperties(r,{opacity:{get:ExpressionPropertyInterface(t.transform.mProps.o)},position:{get:ExpressionPropertyInterface(t.transform.mProps.p)},anchorPoint:{get:ExpressionPropertyInterface(t.transform.mProps.a)},scale:{get:ExpressionPropertyInterface(t.transform.mProps.s)},rotation:{get:ExpressionPropertyInterface(t.transform.mProps.r)},skew:{get:ExpressionPropertyInterface(t.transform.mProps.sk)},skewAxis:{get:ExpressionPropertyInterface(t.transform.mProps.sa)},_name:{value:e.nm}}),r.ty="tr",r.mn=e.mn,r.propertyGroup=i,r}function d(e,t,i){function r(t){return e.p.ix===t?r.position:e.s.ix===t?r.size:null}var s=propertyGroupFactory(r,i);r.propertyIndex=e.ix;var a="tm"===t.sh.ty?t.sh.prop:t.sh;return a.s.setGroupProperty(PropertyInterface("Size",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),Object.defineProperties(r,{size:{get:ExpressionPropertyInterface(a.s)},position:{get:ExpressionPropertyInterface(a.p)},_name:{value:e.nm}}),r.mn=e.mn,r}function u(e,t,i){function r(t){return e.p.ix===t?r.position:e.r.ix===t?r.rotation:e.pt.ix===t?r.points:e.or.ix===t||"ADBE Vector Star Outer Radius"===t?r.outerRadius:e.os.ix===t?r.outerRoundness:!e.ir||e.ir.ix!==t&&"ADBE Vector Star Inner Radius"!==t?e.is&&e.is.ix===t?r.innerRoundness:null:r.innerRadius}var s=propertyGroupFactory(r,i),a="tm"===t.sh.ty?t.sh.prop:t.sh;return r.propertyIndex=e.ix,a.or.setGroupProperty(PropertyInterface("Outer Radius",s)),a.os.setGroupProperty(PropertyInterface("Outer Roundness",s)),a.pt.setGroupProperty(PropertyInterface("Points",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),e.ir&&(a.ir.setGroupProperty(PropertyInterface("Inner Radius",s)),a.is.setGroupProperty(PropertyInterface("Inner Roundness",s))),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(a.p)},rotation:{get:ExpressionPropertyInterface(a.r)},points:{get:ExpressionPropertyInterface(a.pt)},outerRadius:{get:ExpressionPropertyInterface(a.or)},outerRoundness:{get:ExpressionPropertyInterface(a.os)},innerRadius:{get:ExpressionPropertyInterface(a.ir)},innerRoundness:{get:ExpressionPropertyInterface(a.is)},_name:{value:e.nm}}),r.mn=e.mn,r}function y(e,t,i){function r(t){return e.p.ix===t?r.position:e.r.ix===t?r.roundness:e.s.ix===t||"Size"===t||"ADBE Vector Rect Size"===t?r.size:null}var s=propertyGroupFactory(r,i),a="tm"===t.sh.ty?t.sh.prop:t.sh;return r.propertyIndex=e.ix,a.p.setGroupProperty(PropertyInterface("Position",s)),a.s.setGroupProperty(PropertyInterface("Size",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(a.p)},roundness:{get:ExpressionPropertyInterface(a.r)},size:{get:ExpressionPropertyInterface(a.s)},_name:{value:e.nm}}),r.mn=e.mn,r}function g(e,t,i){function r(t){return e.r.ix===t||"Round Corners 1"===t?r.radius:null}var s=propertyGroupFactory(r,i),a=t;return r.propertyIndex=e.ix,a.rd.setGroupProperty(PropertyInterface("Radius",s)),Object.defineProperties(r,{radius:{get:ExpressionPropertyInterface(a.rd)},_name:{value:e.nm}}),r.mn=e.mn,r}function v(e,t,i){function r(t){return e.c.ix===t||"Copies"===t?r.copies:e.o.ix===t||"Offset"===t?r.offset:null}var s=propertyGroupFactory(r,i),a=t;return r.propertyIndex=e.ix,a.c.setGroupProperty(PropertyInterface("Copies",s)),a.o.setGroupProperty(PropertyInterface("Offset",s)),Object.defineProperties(r,{copies:{get:ExpressionPropertyInterface(a.c)},offset:{get:ExpressionPropertyInterface(a.o)},_name:{value:e.nm}}),r.mn=e.mn,r}return function(t,e,r){var s;function i(t){if("number"==typeof t)return 0===(t=void 0===t?1:t)?r:s[t-1];for(var e=0,i=s.length;e<i;){if(s[e]._name===t)return s[e];e+=1}return null}return i.propertyGroup=propertyGroupFactory(i,function(){return r}),s=n(t,e,i.propertyGroup),i.numProperties=s.length,i._name="Contents",i}}(),TextExpressionInterface=function(e){var i;function r(t){switch(t){case"ADBE Text Document":return r.sourceText;default:return null}}return Object.defineProperty(r,"sourceText",{get:function(){e.textProperty.getValue();var t=e.textProperty.currentData.t;return i&&t===i.value||((i=new String(t)).value=t||new String(t),Object.defineProperty(i,"style",{get:function(){return{fillColor:e.textProperty.currentData.fc}}})),i}}),r};function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var FootageInterface=(aha=function(t){function e(t){return"Outline"===t?e.outlineInterface():null}return e._name="Outline",e.outlineInterface=function(t){var r="",s=t.getFootageData();function a(t){if(s[t])return"object"===_typeof(s=s[r=t])?a:s;var e=t.indexOf(r);if(-1===e)return"";var i=parseInt(t.substr(e+r.length),10);return"object"===_typeof(s=s[i])?a:s}return function(){return r="",s=t.getFootageData(),a}}(t),e},function(t){function e(t){return"Data"===t?e.dataInterface:null}return e._name="Data",e.dataInterface=aha(t),e}),aha,interfaces={layer:LayerExpressionInterface,effects:EffectsExpressionInterface,comp:CompExpressionInterface,shape:ShapeExpressionInterface,text:TextExpressionInterface,footage:FootageInterface};function getInterface(t){return interfaces[t]||null}var expressionHelpers={searchExpressions:function(t,e,i){e.x&&(i.k=!0,i.x=!0,i.initiateExpression=ExpressionManager.initiateExpression,i.effectsSequence.push(i.initiateExpression(t,e,i).bind(i)))},getSpeedAtTime:function(t){var e=this.getValueAtTime(t),i=this.getValueAtTime(t+-.01),r=0;if(e.length){var s;for(s=0;s<e.length;s+=1)r+=Math.pow(i[s]-e[s],2);r=100*Math.sqrt(r)}else r=0;return r},getVelocityAtTime:function(t){if(void 0!==this.vel)return this.vel;var e,i,r=this.getValueAtTime(t),s=this.getValueAtTime(t+-.001);if(r.length)for(e=createTypedArray("float32",r.length),i=0;i<r.length;i+=1)e[i]=(s[i]-r[i])/-.001;else e=(s-r)/-.001;return e},getValueAtTime:function(t){return t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastFrame&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastFrame<t?this._cachingAtTime.lastIndex:0,this._cachingAtTime.value=this.interpolateValue(t,this._cachingAtTime),this._cachingAtTime.lastFrame=t),this._cachingAtTime.value},getStaticValueAtTime:function(){return this.pv},setGroupProperty:function(t){this.propertyGroup=t}};function addPropertyDecorator(){function o(t,e,i){if(!this.k||!this.keyframes)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[l.length-1].t;if(h<=p)return this.pv;if(i?s=p-(r=e?Math.abs(p-this.elem.comp.globalData.frameRate*e):Math.max(0,p-this.elem.data.ip)):((!e||e>l.length-1)&&(e=l.length-1),r=p-(s=l[l.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/r)%2!=0)return this.getValueAtTime((r-(h-s)%r+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),m=this.getValueAtTime(p/this.comp.globalData.frameRate,0),c=this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0),d=Math.floor((h-s)/r);if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=(m[a]-f[a])*d+c[a];return o}return(m-f)*d+c}if("continue"===t){var u=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p-.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*((h-p)/this.comp.globalData.frameRate)/5e-4;return o}return u+(h-p)/.001*(u-y)}}return this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0)}function h(t,e,i){if(!this.k)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[0].t;if(p<=h)return this.pv;if(i?s=p+(r=e?Math.abs(this.elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-p)):((!e||e>l.length-1)&&(e=l.length-1),r=(s=l[e].t)-p),"pingpong"===t){if(Math.floor((p-h)/r)%2==0)return this.getValueAtTime(((p-h)%r+p)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(p/this.comp.globalData.frameRate,0),m=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime((r-(p-h)%r+p)/this.comp.globalData.frameRate,0),d=Math.floor((p-h)/r)+1;if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=c[a]-(m[a]-f[a])*d;return o}return c-(m-f)*d}if("continue"===t){var u=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p+.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*(p-h)/.001;return o}return u+(u-y)*(p-h)/.001}}return this.getValueAtTime((r-((p-h)%r+p))/this.comp.globalData.frameRate,0)}function l(t,e){if(!this.k)return this.pv;if(t=.5*(t||.4),(e=Math.floor(e||5))<=1)return this.pv;var i,r,s=this.comp.renderedFrame/this.comp.globalData.frameRate,a=s-t,n=1<e?(s+t-a)/(e-1):1,o=0,h=0;for(i=this.pv.length?createTypedArray("float32",this.pv.length):0;o<e;){if(r=this.getValueAtTime(a+o*n),this.pv.length)for(h=0;h<this.pv.length;h+=1)i[h]+=r[h];else i+=r;o+=1}if(this.pv.length)for(h=0;h<this.pv.length;h+=1)i[h]/=e;else i/=e;return i}var s=TransformPropertyFactory.getTransformProperty;TransformPropertyFactory.getTransformProperty=function(t,e,i){var r=s(t,e,i);return r.dynamicProperties.length?r.getValueAtTime=function(t){this._transformCachingAtTime||(this._transformCachingAtTime={v:new Matrix});var e=this._transformCachingAtTime.v;if(e.cloneFromProps(this.pre.props),this.appliedTransformations<1){var i=this.a.getValueAtTime(t);e.translate(-i[0]*this.a.mult,-i[1]*this.a.mult,i[2]*this.a.mult)}if(this.appliedTransformations<2){var r=this.s.getValueAtTime(t);e.scale(r[0]*this.s.mult,r[1]*this.s.mult,r[2]*this.s.mult)}if(this.sk&&this.appliedTransformations<3){var s=this.sk.getValueAtTime(t),a=this.sa.getValueAtTime(t);e.skewFromAxis(-s*this.sk.mult,a*this.sa.mult)}if(this.r&&this.appliedTransformations<4){var n=this.r.getValueAtTime(t);e.rotate(-n*this.r.mult)}else if(!this.r&&this.appliedTransformations<4){var o=this.rz.getValueAtTime(t),h=this.ry.getValueAtTime(t),l=this.rx.getValueAtTime(t),p=this.or.getValueAtTime(t);e.rotateZ(-o*this.rz.mult).rotateY(h*this.ry.mult).rotateX(l*this.rx.mult).rotateZ(-p[2]*this.or.mult).rotateY(p[1]*this.or.mult).rotateX(p[0]*this.or.mult)}if(this.data.p&&this.data.p.s){var f=this.px.getValueAtTime(t),m=this.py.getValueAtTime(t);if(this.data.p.z){var c=this.pz.getValueAtTime(t);e.translate(f*this.px.mult,m*this.py.mult,-c*this.pz.mult)}else e.translate(f*this.px.mult,m*this.py.mult,0)}else{var d=this.p.getValueAtTime(t);e.translate(d[0]*this.p.mult,d[1]*this.p.mult,-d[2]*this.p.mult)}return e}.bind(r):r.getValueAtTime=function(){return this.v.clone(new Matrix)}.bind(r),r.setGroupProperty=expressionHelpers.setGroupProperty,r};var p=PropertyFactory.getProp;PropertyFactory.getProp=function(t,e,i,r,s){var a=p(t,e,i,r,s);a.kf?a.getValueAtTime=expressionHelpers.getValueAtTime.bind(a):a.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(a),a.setGroupProperty=expressionHelpers.setGroupProperty,a.loopOut=o,a.loopIn=h,a.smooth=l,a.getVelocityAtTime=expressionHelpers.getVelocityAtTime.bind(a),a.getSpeedAtTime=expressionHelpers.getSpeedAtTime.bind(a),a.numKeys=1===e.a?e.k.length:0,a.propertyIndex=e.ix;var n=0;return 0!==i&&(n=createTypedArray("float32",1===e.a?e.k[0].s.length:e.k.length)),a._cachingAtTime={lastFrame:initialDefaultFrame,lastIndex:0,value:n},expressionHelpers.searchExpressions(t,e,a),a.k&&s.addDynamicProperty(a),a};var t=ShapePropertyFactory.getConstructorFunction(),e=ShapePropertyFactory.getKeyframedConstructorFunction();function i(){}i.prototype={vertices:function(t,e){this.k&&this.getValue();var i,r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0));var s=r._length,a=r[t],n=r.v,o=createSizedArray(s);for(i=0;i<s;i+=1)o[i]="i"===t||"o"===t?[a[i][0]-n[i][0],a[i][1]-n[i][1]]:[a[i][0],a[i][1]];return o},points:function(t){return this.vertices("v",t)},inTangents:function(t){return this.vertices("i",t)},outTangents:function(t){return this.vertices("o",t)},isClosed:function(){return this.v.c},pointOnPath:function(t,e){var i=this.v;void 0!==e&&(i=this.getValueAtTime(e,0)),this._segmentsLength||(this._segmentsLength=bez.getSegmentsLength(i));for(var r,s=this._segmentsLength,a=s.lengths,n=s.totalLength*t,o=0,h=a.length,l=0;o<h;){if(l+a[o].addedLength>n){var p=o,f=i.c&&o===h-1?0:o+1,m=(n-l)/a[o].addedLength;r=bez.getPointInSegment(i.v[p],i.v[f],i.o[p],i.i[f],m,a[o]);break}l+=a[o].addedLength,o+=1}return r||(r=i.c?[i.v[0][0],i.v[0][1]]:[i.v[i._length-1][0],i.v[i._length-1][1]]),r},vectorOnPath:function(t,e,i){1==t?t=this.v.c:0==t&&(t=.999);var r=this.pointOnPath(t,e),s=this.pointOnPath(t+.001,e),a=s[0]-r[0],n=s[1]-r[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return 0===o?[0,0]:"tangent"===i?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([i],t),extendPrototype([i],e),e.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shapePool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime<t?this._caching.lastIndex:0,this._cachingAtTime.lastTime=t,this.interpolateShape(t,this._cachingAtTime.shapeValue,this._cachingAtTime)),this._cachingAtTime.shapeValue},e.prototype.initiateExpression=ExpressionManager.initiateExpression;var n=ShapePropertyFactory.getShapeProp;ShapePropertyFactory.getShapeProp=function(t,e,i,r,s){var a=n(t,e,i,r,s);return a.propertyIndex=e.ix,a.lock=!1,3===i?expressionHelpers.searchExpressions(t,e.pt,a):4===i&&expressionHelpers.searchExpressions(t,e.ks,a),a.k&&t.addDynamicProperty(a),a}}function initialize$1(){addPropertyDecorator()}function addDecorator(){TextProperty.prototype.getExpressionValue=function(t,e){var i=this.calculateExpression(e);if(t.t===i)return t;var r={};return this.copyData(r,t),r.t=i.toString(),r.__complete=!1,r},TextProperty.prototype.searchProperty=function(){var t=this.searchKeyframes(),e=this.searchExpressions();return this.kf=t||e,this.kf},TextProperty.prototype.searchExpressions=function(){return this.data.d.x?(this.calculateExpression=ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this),this.addEffect(this.getExpressionValue.bind(this)),!0):null}}function initialize(){addDecorator()}function SVGComposableEffect(){}SVGComposableEffect.prototype={createMergeNode:function(t,e){var i,r,s=createNS("feMerge");for(s.setAttribute("result",t),r=0;r<e.length;r+=1)(i=createNS("feMergeNode")).setAttribute("in",e[r]),s.appendChild(i),s.appendChild(i);return s}};var linearFilterValue="0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0";function SVGTintFilter(t,e,i,r,s){this.filterManager=e;var a=createNS("feColorMatrix");a.setAttribute("type","matrix"),a.setAttribute("color-interpolation-filters","linearRGB"),a.setAttribute("values",linearFilterValue+" 1 0"),(this.linearFilter=a).setAttribute("result",r+"_tint_1"),t.appendChild(a),(a=createNS("feColorMatrix")).setAttribute("type","matrix"),a.setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),a.setAttribute("result",r+"_tint_2"),t.appendChild(a),this.matrixFilter=a;var n=this.createMergeNode(r,[s,r+"_tint_1",r+"_tint_2"]);t.appendChild(n)}function SVGFillFilter(t,e,i,r){this.filterManager=e;var s=createNS("feColorMatrix");s.setAttribute("type","matrix"),s.setAttribute("color-interpolation-filters","sRGB"),s.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),s.setAttribute("result",r),t.appendChild(s),this.matrixFilter=s}function SVGStrokeEffect(t,e,i){this.initialized=!1,this.filterManager=e,this.elem=i,this.paths=[]}function SVGTritoneFilter(t,e,i,r){this.filterManager=e;var s=createNS("feColorMatrix");s.setAttribute("type","matrix"),s.setAttribute("color-interpolation-filters","linearRGB"),s.setAttribute("values","0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0"),t.appendChild(s);var a=createNS("feComponentTransfer");a.setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("result",r),this.matrixFilter=a;var n=createNS("feFuncR");n.setAttribute("type","table"),a.appendChild(n),this.feFuncR=n;var o=createNS("feFuncG");o.setAttribute("type","table"),a.appendChild(o),this.feFuncG=o;var h=createNS("feFuncB");h.setAttribute("type","table"),a.appendChild(h),this.feFuncB=h,t.appendChild(a)}function SVGProLevelsFilter(t,e,i,r){this.filterManager=e;var s=this.filterManager.effectElements,a=createNS("feComponentTransfer");(s[10].p.k||0!==s[10].p.v||s[11].p.k||1!==s[11].p.v||s[12].p.k||1!==s[12].p.v||s[13].p.k||0!==s[13].p.v||s[14].p.k||1!==s[14].p.v)&&(this.feFuncR=this.createFeFunc("feFuncR",a)),(s[17].p.k||0!==s[17].p.v||s[18].p.k||1!==s[18].p.v||s[19].p.k||1!==s[19].p.v||s[20].p.k||0!==s[20].p.v||s[21].p.k||1!==s[21].p.v)&&(this.feFuncG=this.createFeFunc("feFuncG",a)),(s[24].p.k||0!==s[24].p.v||s[25].p.k||1!==s[25].p.v||s[26].p.k||1!==s[26].p.v||s[27].p.k||0!==s[27].p.v||s[28].p.k||1!==s[28].p.v)&&(this.feFuncB=this.createFeFunc("feFuncB",a)),(s[31].p.k||0!==s[31].p.v||s[32].p.k||1!==s[32].p.v||s[33].p.k||1!==s[33].p.v||s[34].p.k||0!==s[34].p.v||s[35].p.k||1!==s[35].p.v)&&(this.feFuncA=this.createFeFunc("feFuncA",a)),(this.feFuncR||this.feFuncG||this.feFuncB||this.feFuncA)&&(a.setAttribute("color-interpolation-filters","sRGB"),t.appendChild(a)),(s[3].p.k||0!==s[3].p.v||s[4].p.k||1!==s[4].p.v||s[5].p.k||1!==s[5].p.v||s[6].p.k||0!==s[6].p.v||s[7].p.k||1!==s[7].p.v)&&((a=createNS("feComponentTransfer")).setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("result",r),t.appendChild(a),this.feFuncRComposed=this.createFeFunc("feFuncR",a),this.feFuncGComposed=this.createFeFunc("feFuncG",a),this.feFuncBComposed=this.createFeFunc("feFuncB",a))}function SVGDropShadowEffect(t,e,i,r,s){var a=e.container.globalData.renderConfig.filterSize,n=e.data.fs||a;t.setAttribute("x",n.x||a.x),t.setAttribute("y",n.y||a.y),t.setAttribute("width",n.width||a.width),t.setAttribute("height",n.height||a.height),this.filterManager=e;var o=createNS("feGaussianBlur");o.setAttribute("in","SourceAlpha"),o.setAttribute("result",r+"_drop_shadow_1"),o.setAttribute("stdDeviation","0"),this.feGaussianBlur=o,t.appendChild(o);var h=createNS("feOffset");h.setAttribute("dx","25"),h.setAttribute("dy","0"),h.setAttribute("in",r+"_drop_shadow_1"),h.setAttribute("result",r+"_drop_shadow_2"),this.feOffset=h,t.appendChild(h);var l=createNS("feFlood");l.setAttribute("flood-color","#00ff00"),l.setAttribute("flood-opacity","1"),l.setAttribute("result",r+"_drop_shadow_3"),this.feFlood=l,t.appendChild(l);var p=createNS("feComposite");p.setAttribute("in",r+"_drop_shadow_3"),p.setAttribute("in2",r+"_drop_shadow_2"),p.setAttribute("operator","in"),p.setAttribute("result",r+"_drop_shadow_4"),t.appendChild(p);var f=this.createMergeNode(r,[r+"_drop_shadow_4",s]);t.appendChild(f)}extendPrototype([SVGComposableEffect],SVGTintFilter),SVGTintFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=this.filterManager.effectElements[2].p.v/100;this.linearFilter.setAttribute("values",linearFilterValue+" "+r+" 0"),this.matrixFilter.setAttribute("values",i[0]-e[0]+" 0 0 0 "+e[0]+" "+(i[1]-e[1])+" 0 0 0 "+e[1]+" "+(i[2]-e[2])+" 0 0 0 "+e[2]+" 0 0 0 1 0")}},SVGFillFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[2].p.v,i=this.filterManager.effectElements[6].p.v;this.matrixFilter.setAttribute("values","0 0 0 0 "+e[0]+" 0 0 0 0 "+e[1]+" 0 0 0 0 "+e[2]+" 0 0 0 "+i+" 0")}},SVGStrokeEffect.prototype.initialize=function(){var t,e,i,r,s=this.elem.layerElement.children||this.elem.layerElement.childNodes;for(1===this.filterManager.effectElements[1].p.v?(r=this.elem.maskManager.masksProperties.length,i=0):r=(i=this.filterManager.effectElements[0].p.v-1)+1,(e=createNS("g")).setAttribute("fill","none"),e.setAttribute("stroke-linecap","round"),e.setAttribute("stroke-dashoffset",1);i<r;i+=1)t=createNS("path"),e.appendChild(t),this.paths.push({p:t,m:i});if(3===this.filterManager.effectElements[10].p.v){var a=createNS("mask"),n=createElementID();a.setAttribute("id",n),a.setAttribute("mask-type","alpha"),a.appendChild(e),this.elem.globalData.defs.appendChild(a);var o=createNS("g");for(o.setAttribute("mask","url("+getLocationHref()+"#"+n+")");s[0];)o.appendChild(s[0]);this.elem.layerElement.appendChild(o),this.masker=a,e.setAttribute("stroke","#fff")}else if(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v){if(2===this.filterManager.effectElements[10].p.v)for(s=this.elem.layerElement.children||this.elem.layerElement.childNodes;s.length;)this.elem.layerElement.removeChild(s[0]);this.elem.layerElement.appendChild(e),this.elem.layerElement.removeAttribute("mask"),e.setAttribute("stroke","#fff")}this.initialized=!0,this.pathMasker=e},SVGStrokeEffect.prototype.renderFrame=function(t){var e;this.initialized||this.initialize();var i,r,s=this.paths.length;for(e=0;e<s;e+=1)if(-1!==this.paths[e].m&&(i=this.elem.maskManager.viewData[this.paths[e].m],r=this.paths[e].p,(t||this.filterManager._mdf||i.prop._mdf)&&r.setAttribute("d",i.lastPath),t||this.filterManager.effectElements[9].p._mdf||this.filterManager.effectElements[4].p._mdf||this.filterManager.effectElements[7].p._mdf||this.filterManager.effectElements[8].p._mdf||i.prop._mdf)){var a;if(0!==this.filterManager.effectElements[7].p.v||100!==this.filterManager.effectElements[8].p.v){var n=.01*Math.min(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),o=.01*Math.max(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),h=r.getTotalLength();a="0 0 0 "+h*n+" ";var l,p=h*(o-n),f=1+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01,m=Math.floor(p/f);for(l=0;l<m;l+=1)a+="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01+" ";a+="0 "+10*h+" 0 0"}else a="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01;r.setAttribute("stroke-dasharray",a)}if((t||this.filterManager.effectElements[4].p._mdf)&&this.pathMasker.setAttribute("stroke-width",2*this.filterManager.effectElements[4].p.v),(t||this.filterManager.effectElements[6].p._mdf)&&this.pathMasker.setAttribute("opacity",this.filterManager.effectElements[6].p.v),(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v)&&(t||this.filterManager.effectElements[3].p._mdf)){var c=this.filterManager.effectElements[3].p.v;this.pathMasker.setAttribute("stroke","rgb("+bmFloor(255*c[0])+","+bmFloor(255*c[1])+","+bmFloor(255*c[2])+")")}},SVGTritoneFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=this.filterManager.effectElements[2].p.v,s=r[0]+" "+i[0]+" "+e[0],a=r[1]+" "+i[1]+" "+e[1],n=r[2]+" "+i[2]+" "+e[2];this.feFuncR.setAttribute("tableValues",s),this.feFuncG.setAttribute("tableValues",a),this.feFuncB.setAttribute("tableValues",n)}},SVGProLevelsFilter.prototype.createFeFunc=function(t,e){var i=createNS(t);return i.setAttribute("type","table"),e.appendChild(i),i},SVGProLevelsFilter.prototype.getTableValue=function(t,e,i,r,s){for(var a,n,o=0,h=Math.min(t,e),l=Math.max(t,e),p=Array.call(null,{length:256}),f=0,m=s-r,c=e-t;o<=256;)n=(a=o/256)<=h?c<0?s:r:l<=a?c<0?r:s:r+m*Math.pow((a-t)/c,1/i),p[f]=n,f+=1,o+=256/255;return p.join(" ")},SVGProLevelsFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e,i=this.filterManager.effectElements;this.feFuncRComposed&&(t||i[3].p._mdf||i[4].p._mdf||i[5].p._mdf||i[6].p._mdf||i[7].p._mdf)&&(e=this.getTableValue(i[3].p.v,i[4].p.v,i[5].p.v,i[6].p.v,i[7].p.v),this.feFuncRComposed.setAttribute("tableValues",e),this.feFuncGComposed.setAttribute("tableValues",e),this.feFuncBComposed.setAttribute("tableValues",e)),this.feFuncR&&(t||i[10].p._mdf||i[11].p._mdf||i[12].p._mdf||i[13].p._mdf||i[14].p._mdf)&&(e=this.getTableValue(i[10].p.v,i[11].p.v,i[12].p.v,i[13].p.v,i[14].p.v),this.feFuncR.setAttribute("tableValues",e)),this.feFuncG&&(t||i[17].p._mdf||i[18].p._mdf||i[19].p._mdf||i[20].p._mdf||i[21].p._mdf)&&(e=this.getTableValue(i[17].p.v,i[18].p.v,i[19].p.v,i[20].p.v,i[21].p.v),this.feFuncG.setAttribute("tableValues",e)),this.feFuncB&&(t||i[24].p._mdf||i[25].p._mdf||i[26].p._mdf||i[27].p._mdf||i[28].p._mdf)&&(e=this.getTableValue(i[24].p.v,i[25].p.v,i[26].p.v,i[27].p.v,i[28].p.v),this.feFuncB.setAttribute("tableValues",e)),this.feFuncA&&(t||i[31].p._mdf||i[32].p._mdf||i[33].p._mdf||i[34].p._mdf||i[35].p._mdf)&&(e=this.getTableValue(i[31].p.v,i[32].p.v,i[33].p.v,i[34].p.v,i[35].p.v),this.feFuncA.setAttribute("tableValues",e))}},extendPrototype([SVGComposableEffect],SVGDropShadowEffect),SVGDropShadowEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){if((t||this.filterManager.effectElements[4].p._mdf)&&this.feGaussianBlur.setAttribute("stdDeviation",this.filterManager.effectElements[4].p.v/4),t||this.filterManager.effectElements[0].p._mdf){var e=this.filterManager.effectElements[0].p.v;this.feFlood.setAttribute("flood-color",rgbToHex(Math.round(255*e[0]),Math.round(255*e[1]),Math.round(255*e[2])))}if((t||this.filterManager.effectElements[1].p._mdf)&&this.feFlood.setAttribute("flood-opacity",this.filterManager.effectElements[1].p.v/255),t||this.filterManager.effectElements[2].p._mdf||this.filterManager.effectElements[3].p._mdf){var i=this.filterManager.effectElements[3].p.v,r=(this.filterManager.effectElements[2].p.v-90)*degToRads,s=i*Math.cos(r),a=i*Math.sin(r);this.feOffset.setAttribute("dx",s),this.feOffset.setAttribute("dy",a)}}};var _svgMatteSymbols=[];function SVGMatte3Effect(t,e,i){this.initialized=!1,this.filterManager=e,this.filterElem=t,(this.elem=i).matteElement=createNS("g"),i.matteElement.appendChild(i.layerElement),i.matteElement.appendChild(i.transformedElement),i.baseElement=i.matteElement}function SVGGaussianBlurEffect(t,e,i,r){t.setAttribute("x","-100%"),t.setAttribute("y","-100%"),t.setAttribute("width","300%"),t.setAttribute("height","300%"),this.filterManager=e;var s=createNS("feGaussianBlur");s.setAttribute("result",r),t.appendChild(s),this.feGaussianBlur=s}function TransformEffect(){}function SVGTransformEffect(t,e){this.init(e)}function CVTransformEffect(t){this.init(t)}return SVGMatte3Effect.prototype.findSymbol=function(t){for(var e=0,i=_svgMatteSymbols.length;e<i;){if(_svgMatteSymbols[e]===t)return _svgMatteSymbols[e];e+=1}return null},SVGMatte3Effect.prototype.replaceInParent=function(t,e){var i=t.layerElement.parentNode;if(i){for(var r,s=i.children,a=0,n=s.length;a<n&&s[a]!==t.layerElement;)a+=1;a<=n-2&&(r=s[a+1]);var o=createNS("use");o.setAttribute("href","#"+e),r?i.insertBefore(o,r):i.appendChild(o)}},SVGMatte3Effect.prototype.setElementAsMask=function(t,e){if(!this.findSymbol(e)){var i=createElementID(),r=createNS("mask");r.setAttribute("id",e.layerId),r.setAttribute("mask-type","alpha"),_svgMatteSymbols.push(e);var s=t.globalData.defs;s.appendChild(r);var a=createNS("symbol");a.setAttribute("id",i),this.replaceInParent(e,i),a.appendChild(e.layerElement),s.appendChild(a);var n=createNS("use");n.setAttribute("href","#"+i),r.appendChild(n),e.data.hd=!1,e.show()}t.setMatte(e.layerId)},SVGMatte3Effect.prototype.initialize=function(){for(var t=this.filterManager.effectElements[0].p.v,e=this.elem.comp.elements,i=0,r=e.length;i<r;)e[i]&&e[i].data.ind===t&&this.setElementAsMask(this.elem,e[i]),i+=1;this.initialized=!0},SVGMatte3Effect.prototype.renderFrame=function(){this.initialized||this.initialize()},SVGGaussianBlurEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=.3*this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=3==i?0:e,s=2==i?0:e;this.feGaussianBlur.setAttribute("stdDeviation",r+" "+s);var a=1==this.filterManager.effectElements[2].p.v?"wrap":"duplicate";this.feGaussianBlur.setAttribute("edgeMode",a)}},TransformEffect.prototype.init=function(t){this.effectsManager=t,this.type=effectTypes.TRANSFORM_EFFECT,this.matrix=new Matrix,this.opacity=-1,this._mdf=!1,this._opMdf=!1},TransformEffect.prototype.renderFrame=function(t){if(this._opMdf=!1,this._mdf=!1,t||this.effectsManager._mdf){var e=this.effectsManager.effectElements,i=e[0].p.v,r=e[1].p.v,s=1===e[2].p.v,a=e[3].p.v,n=s?a:e[4].p.v,o=e[5].p.v,h=e[6].p.v,l=e[7].p.v;this.matrix.reset(),this.matrix.translate(-i[0],-i[1],i[2]),this.matrix.scale(.01*n,.01*a,1),this.matrix.rotate(-l*degToRads),this.matrix.skewFromAxis(-o*degToRads,(h+90)*degToRads),this.matrix.translate(r[0],r[1],0),this._mdf=!0,this.opacity!==e[8].p.v&&(this.opacity=e[8].p.v,this._opMdf=!0)}},extendPrototype([TransformEffect],SVGTransformEffect),extendPrototype([TransformEffect],CVTransformEffect),registerRenderer("canvas",CanvasRenderer),registerRenderer("html",HybridRenderer),registerRenderer("svg",SVGRenderer),ShapeModifiers.registerModifier("tm",TrimModifier),ShapeModifiers.registerModifier("pb",PuckerAndBloatModifier),ShapeModifiers.registerModifier("rp",RepeaterModifier),ShapeModifiers.registerModifier("rd",RoundCornersModifier),ShapeModifiers.registerModifier("zz",ZigZagModifier),ShapeModifiers.registerModifier("op",OffsetPathModifier),setExpressionsPlugin(Expressions),setExpressionInterfaces(getInterface),initialize$1(),initialize(),registerEffect$1(20,SVGTintFilter,!0),registerEffect$1(21,SVGFillFilter,!0),registerEffect$1(22,SVGStrokeEffect,!1),registerEffect$1(23,SVGTritoneFilter,!0),registerEffect$1(24,SVGProLevelsFilter,!0),registerEffect$1(25,SVGDropShadowEffect,!0),registerEffect$1(28,SVGMatte3Effect,!1),registerEffect$1(29,SVGGaussianBlurEffect,!0),registerEffect$1(35,SVGTransformEffect,!1),registerEffect(35,CVTransformEffect),lottie},"object"==typeof exports&&"undefined"!=typeof module?module.exports=Z():"function"==typeof define&&define.amd?define(Z):(Y="undefined"!=typeof globalThis?globalThis:Y||self).lottie=Z()),{loadAnimation:loadAnimation}}({});onmessage=function(t){var e=t.data,i=e.type,r=e.payload;if("load"===i)lottieInternal.loadAnimation(r);else if("pause"===i)animations[r.id]&&animations[r.id].animation.pause();else if("play"===i)animations[r.id]&&animations[r.id].animation.play();else if("stop"===i)animations[r.id]&&animations[r.id].animation.stop();else if("setSpeed"===i)animations[r.id]&&animations[r.id].animation.setSpeed(r.value);else if("setDirection"===i)animations[r.id]&&animations[r.id].animation.setDirection(r.value);else if("setLoop"===i)animations[r.id]&&animations[r.id].animation.setLoop(r.value);else if("goToAndPlay"===i)animations[r.id]&&animations[r.id].animation.goToAndPlay(r.value,r.isFrame);else if("goToAndStop"===i)animations[r.id]&&animations[r.id].animation.goToAndStop(r.value,r.isFrame);else if("setSubframe"===i)animations[r.id]&&animations[r.id].animation.setSubframe(r.value);else if("addEventListener"===i){if(animations[r.id]){var s=function(){self.postMessage({type:"event",payload:{id:r.id,callbackId:r.callbackId,argument:arguments[0]}})};animations[r.id].events[r.callbackId]={callback:s},animations[r.id].animation.addEventListener(r.eventName,s)}}else if("removeEventListener"===i){if(animations[r.id]){var a=animations[r.id].events[r.callbackId];animations[r.id].animation.removeEventListener(r.eventName,a)}}else"destroy"===i?animations[r.id]&&(animations[r.id].animation.destroy(),animations[r.id]=null):"resize"===i?animations[r.id]&&animations[r.id].animation.resize(r.width,r.height):"playSegments"===i?animations[r.id]&&animations[r.id].animation.playSegments(r.arr,r.forceFlag):"updateDocumentData"===i&&animations[r.id].animation.updateDocumentData(r.path,r.documentData,r.index)}}function createWorker(t){var e=new Blob(["("+t.toString()+"())"],{type:"text/javascript"}),i=URL.createObjectURL(e);return new Worker(i)}var lottie=function(){"use strict";var l=createWorker(workerContent),i=0,s=0,p={},a={rendererSettings:{}};function o(t,e,i,r){var s;for(var a in s="div"===t.type?document.createElement("div"):document.createElementNS(t.namespace,t.type),t.textContent&&(s.textContent=t.textContent),t.attributes)Object.prototype.hasOwnProperty.call(t.attributes,a)&&("href"===a?s.setAttributeNS("http://www.w3.org/1999/xlink",a,t.attributes[a]):s.setAttribute(a,t.attributes[a]),"id"===a&&(i[t.attributes[a]]=s));for(var n in t.style)Object.prototype.hasOwnProperty.call(t.style,n)&&(s.style[n]=t.style[n]);t.children.forEach(function(t){o(t,s,i)}),r?e.insertBefore(s,r):e.appendChild(s)}function f(t,e){for(var i,r=0;r<t.length;r+=1){var s,a=e[(i=t[r])[1]];if(a)i[2]&&(s=e[i[2]]),o(i[0],a,e,s),t.splice(r,1),r-=1}}function m(t,e){for(var i,r=0;r<e.length;r+=1)i=e[r],t.style[i[0]]=i[1]}function c(t,e){for(var i,r=0;r<e.length;r+=1)i=e[r],t.setAttribute(i[0],i[1])}var e={DOMLoaded:function(t){var e=p[t.id];e._loaded=!0,e.pendingCallbacks.forEach(function(t){e.animInstance.addEventListener(t.eventName,t.callback),"DOMLoaded"===t.eventName&&t.callback()}),e.animInstance.totalFrames=t.totalFrames,e.animInstance.frameRate=t.frameRate,e.animInstance.firstFrame=t.firstFrame,e.animInstance.playDirection=t.playDirection,e.animInstance.currentFrame=t.isSubframeEnabled?t.currentRawFrame:~~t.currentRawFrame,t.timeCompleted!==t.totalFrames&&t.currentFrame>t.timeCompleted&&(e.animInstance.currentFrame=t.timeCompleted)},SVGloaded:function(t){var e=p[t.id],i=e.container,r=e.elements;o(t.tree,i,r)},SVGupdated:function(t){var e,i,r=t.elements,s=p[t.id];if(s){for(var a,n=s.elements,o=0;o<r.length;o+=1){var h=n[(a=r[o]).id];f(a.elements,n),m(h,a.styles),c(h,a.attributes),e=h,(i=a.textContent)&&(e.textContent=i)}s.animInstance.currentFrame=t.currentTime}},CanvasUpdated:function(t){p[t.id].instructionsHandler(t.instructions)},event:function(t){var e=p[t.id];if(e){var i=e.callbacks;i[t.callbackId]&&i[t.callbackId].callback(t.argument)}},playing:function(t){var e=p[t.id];e&&(e.animInstance.isPaused=!1)},paused:function(t){var e=p[t.id];e&&(e.animInstance.isPaused=!0)}};return l.onmessage=function(t){e[t.data.type]&&e[t.data.type](t.data.payload)},{loadAnimation:function(t){var r,o="lottie_animationId_"+(i+=1),h={elements:{},callbacks:{},pendingCallbacks:[],status:"init"},e={id:o,isPaused:!0,pause:function(){l.postMessage({type:"pause",payload:{id:o}})},play:function(){l.postMessage({type:"play",payload:{id:o}})},stop:function(){l.postMessage({type:"stop",payload:{id:o}})},setSpeed:function(t){l.postMessage({type:"setSpeed",payload:{id:o,value:t}})},setDirection:function(t){l.postMessage({type:"setDirection",payload:{id:o,value:t}})},setLoop:function(t){l.postMessage({type:"setLoop",payload:{id:o,value:t}})},goToAndStop:function(t,e){l.postMessage({type:"goToAndStop",payload:{id:o,value:t,isFrame:e}})},goToAndPlay:function(t,e){l.postMessage({type:"goToAndPlay",payload:{id:o,value:t,isFrame:e}})},playSegments:function(t,e){l.postMessage({type:"playSegments",payload:{id:o,arr:t,forceFlag:e}})},setSubframe:function(t){l.postMessage({type:"setSubframe",payload:{id:o,value:t}})},addEventListener:function(t,e){if(h._loaded){var i="callback_"+(s+=1);h.callbacks[i]={eventName:t,callback:e},l.postMessage({type:"addEventListener",payload:{id:o,callbackId:i,eventName:t}})}else h.pendingCallbacks.push({eventName:t,callback:e})},removeEventListener:function(e,i){Object.keys(h.callbacks).forEach(function(t){h.callbacks[t].eventName!==e||h.callbacks[t].callback!==i&&i||(delete h.callbacks[t],l.postMessage({type:"removeEventListener",payload:{id:o,callbackId:t,eventName:e}}))})},destroy:function(){"init"===h.status?h.status="destroyable":(h.status="destroyed",p[o]=null,h.container&&(h.container.innerHTML=""),l.postMessage({type:"destroy",payload:{id:o}}))},resize:function(t,e){var i=window.devicePixelRatio||1;l.postMessage({type:"resize",payload:{id:o,width:t||(h.container?h.container.offsetWidth*i:0),height:e||(h.container?h.container.offsetHeight*i:0)}})},updateDocumentData:function(t,e,i){l.postMessage({type:"updateDocumentData",payload:{id:o,path:t,documentData:e,index:i}})}};return h.animInstance=e,(r=t,new Promise(function(e,t){var i=Object.assign({},a,r);i.animType&&!i.renderer&&(i.renderer=i.animType),i.wrapper&&(i.container||(i.container=i.wrapper),delete i.wrapper),i.animationData?e(i):i.path?fetch(i.path).then(function(t){return t.json()}).then(function(t){i.animationData=t,delete i.path,e(i)}):t()})).then(function(t){if("destroyable"!==h.status){h.status="loaded";var s,a,e=[];if(t.container&&(h.container=t.container,delete t.container),"canvas"===t.renderer){var i=t.rendererSettings.canvas;if(!i){var r=window.devicePixelRatio||1;i=document.createElement("canvas"),h.container.appendChild(i),i.width=(h.container?h.container.offsetWidth:t.animationData.w)*r,i.height=(h.container?h.container.offsetHeight:t.animationData.h)*r,i.style.width="100%",i.style.height="100%"}var n=i;"undefined"==typeof OffscreenCanvas?(h.canvas=i,h.instructionsHandler=(s=i.getContext("2d"),a={beginPath:s.beginPath,closePath:s.closePath,rect:s.rect,clip:s.clip,clearRect:s.clearRect,setTransform:s.setTransform,moveTo:s.moveTo,bezierCurveTo:s.bezierCurveTo,lineTo:s.lineTo,fill:s.fill,save:s.save,restore:s.restore},function(t){for(var e=0;e<t.length;e+=1){var i=t[e],r=a[i.t];r?r.apply(s,i.a):s[i.t]=i.a}})):(i instanceof OffscreenCanvas||(n=i.transferControlToOffscreen(),t.rendererSettings.canvas=n),e.push(n))}p[o]=h,l.postMessage({type:"load",payload:{params:t,id:o}},e)}else h.animInstance.destroy()}),e}}}();
+	function workerContent(){function extendPrototype(t,e){for(var i,r=t.length,s=0;s<r;s+=1)for(var a in i=t[s].prototype)Object.prototype.hasOwnProperty.call(i,a)&&(e.prototype[a]=i[a])}function ProxyElement(t,e){this._state="init",this._isDirty=!1,this._isProxy=!0,this._changedStyles=[],this._changedAttributes=[],this._changedElements=[],this._textContent=null,this.type=t,this.namespace=e,this.children=[],localIdCounter+=1,this.attributes={id:"l_d_"+localIdCounter},this.style=new Style(this)}ProxyElement.prototype={appendChild:function(t){(t.parentNode=this).children.push(t),this._isDirty=!0,this._changedElements.push([t,this.attributes.id])},insertBefore:function(t,e){for(var i=this.children,r=0;r<i.length;r+=1)if(i[r]===e)return i.splice(r,0,t),this._isDirty=!0,void this._changedElements.push([t,this.attributes.id,e.attributes.id]);i.push(e)},setAttribute:function(t,e){this.attributes[t]=e,this._isDirty||(this._isDirty=!0),this._changedAttributes.push(t)},serialize:function(){return{type:this.type,namespace:this.namespace,style:this.style.serialize(),attributes:this.attributes,children:this.children.map(function(t){return t.serialize()}),textContent:this._textContent}},addEventListener:function(t,e){setTimeout(e,1)},setAttributeNS:function(t,e,i){this.attributes[e]=i,this._isDirty||(this._isDirty=!0),this._changedAttributes.push(e)}},Object.defineProperty(ProxyElement.prototype,"textContent",{set:function(t){this._isDirty=!0,this._textContent=t}});var localIdCounter=0,animations={},styleProperties=["width","height","display","transform","opacity","contentVisibility","mix-blend-mode"];function convertArguments(t){for(var e=[],i=t.length,r=0;r<i;r+=1)e.push(t[r]);return e}function Style(t){this.element=t}function CanvasContext(t){this.element=t}Style.prototype={serialize:function(){for(var t={},e=0;e<styleProperties.length;e+=1){var i=styleProperties[e],r="_"+i;r in this&&(t[i]=this[r])}return t}},styleProperties.forEach(function(e){Object.defineProperty(Style.prototype,e,{set:function(t){this.element._isDirty||(this.element._isDirty=!0),this.element._changedStyles.push(e),this["_"+e]=t},get:function(){return this["_"+e]}})}),CanvasContext.prototype={createRadialGradient:function(){var t={t:"rGradient",a:convertArguments(arguments),stops:[]};return this.element.instructions.push(t),{addColorStop:function(){t.stops.push(convertArguments(arguments))}}},createLinearGradient:function(){var t={t:"lGradient",a:convertArguments(arguments),stops:[]};return this.element.instructions.push(t),{addColorStop:function(){t.stops.push(convertArguments(arguments))}}}},Object.defineProperties(CanvasContext.prototype,{canvas:{enumerable:!0,get:function(){return this.element}}});var canvasContextMethods=["fillRect","setTransform","drawImage","beginPath","moveTo","save","restore","fillText","setLineDash","clearRect","clip","rect","stroke","fill","closePath","bezierCurveTo","lineTo"],canvasContextProperties=(canvasContextMethods.forEach(function(t){CanvasContext.prototype[t]=function(){this.element.instructions.push({t:t,a:convertArguments(arguments)})}}),["globalAlpha","strokeStyle","fillStyle","lineCap","lineJoin","lineWidth","miterLimit","lineDashOffset","globalCompositeOperation"]);function CanvasElement(t,e){ProxyElement.call(this,t,e),this.instructions=[],this.width=0,this.height=0,this.context=new CanvasContext(this)}function createElement(t,e){return new("canvas"===e?CanvasElement:ProxyElement)(e,t)}canvasContextProperties.forEach(function(e){Object.defineProperty(CanvasContext.prototype,e,{set:function(t){this.element.instructions.push({t:e,a:t})}})}),CanvasElement.prototype={getContext:function(){return this.context},resetInstructions:function(){this.instructions.length=0}},extendPrototype([ProxyElement],CanvasElement);var window=self,document={createElementNS:function(t,e){return createElement(t,e)},createElement:function(t){return createElement("",t)},getElementsByTagName:function(){return[]},body:createElement("","body"),_isProxy:!0},lottieInternal=function(){function addElementToList(t,e){e.push(t),t._isDirty=!1,t._changedStyles.length=0,t._changedAttributes.length=0,t._changedElements.length=0,t._textContent=null,t.children.forEach(function(t){addElementToList(t,e)})}function addChangedAttributes(t){for(var e,i=t._changedAttributes,r=[],s=0;s<i.length;s+=1)e=i[s],r.push([e,t.attributes[e]]);return r}function addChangedStyles(t){for(var e,i=t._changedStyles,r=[],s=0;s<i.length;s+=1)e=i[s],r.push([e,t.style[e]]);return r}function addChangedElements(t,e){for(var i,r=t._changedElements,s=[],a=0;a<r.length;a+=1)i=r[a],s.push([i[0].serialize(),i[1],i[2]]),addElementToList(i[0],e);return s}function loadAnimation(a){var e,t,i,r,s=a.params,n=[];"svg"===s.renderer?(e=document.createElement("div"),s.container=e):((i=s.rendererSettings.canvas)||((i=document.createElement("canvas")).width=s.animationData.w,i.height=s.animationData.h),r=i.getContext("2d"),s.rendererSettings.context=r),(t=lottie.loadAnimation(s)).addEventListener("error",function(t){console.log(t)}),t.onError=function(t){console.log("ERRORO",t)},t.addEventListener("_play",function(){self.postMessage({type:"playing",payload:{id:a.id}})}),t.addEventListener("_pause",function(){self.postMessage({type:"paused",payload:{id:a.id}})}),"svg"===s.renderer?(t.addEventListener("DOMLoaded",function(){var t=e.serialize();addElementToList(e,n),self.postMessage({type:"SVGloaded",payload:{id:a.id,tree:t.children[0]}})}),t.addEventListener("drawnFrame",function(t){for(var e,i,r=[],s=0;s<n.length;s+=1)(i=n[s])._isDirty&&(e={id:i.attributes.id,styles:addChangedStyles(i),attributes:addChangedAttributes(i),elements:addChangedElements(i,n),textContent:i._textContent||void 0},r.push(e),i._isDirty=!1,i._changedAttributes.length=0,i._changedStyles.length=0,i._changedElements.length=0,i._textContent=null);self.postMessage({type:"SVGupdated",payload:{elements:r,id:a.id,currentTime:t.currentTime}})})):i._isProxy&&t.addEventListener("drawnFrame",function(t){self.postMessage({type:"CanvasUpdated",payload:{instructions:i.instructions,id:a.id,currentTime:t.currentTime}}),i.resetInstructions()}),t.addEventListener("DOMLoaded",function(){self.postMessage({type:"DOMLoaded",payload:{id:a.id,totalFrames:t.totalFrames,frameRate:t.frameRate,firstFrame:t.firstFrame,currentFrame:t.currentFrame,playDirection:t.playDirection,isSubframeEnabled:t.isSubframeEnabled,currentRawFrame:t.currentRawFrame,timeCompleted:t.timeCompleted}})}),animations[a.id]={animation:t,events:{}}}return void 0!==document&&"undefined"!=typeof navigator&&((t,e)=>{"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lottie=e()})(this,function(){var svgNS="http://www.w3.org/2000/svg",locationHref="",_useWebWorker=!1,initialDefaultFrame=-999999,setWebWorker=function(t){_useWebWorker=!!t},getWebWorker=function(){return _useWebWorker},setLocationHref=function(t){locationHref=t},getLocationHref=function(){return locationHref};function createTag(t){return document.createElement(t)}function extendPrototype(t,e){for(var i,r=t.length,s=0;s<r;s+=1)for(var a in i=t[s].prototype)Object.prototype.hasOwnProperty.call(i,a)&&(e.prototype[a]=i[a])}function getDescriptor(t,e){return Object.getOwnPropertyDescriptor(t,e)}function createProxyFunction(t){function e(){}return e.prototype=t,e}var audioControllerFactory=(()=>{function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){for(var t=this.audios.length,e=0;e<t;e+=1)this.audios[e].pause()},resume:function(){for(var t=this.audios.length,e=0;e<t;e+=1)this.audios[e].resume()},setRate:function(t){for(var e=this.audios.length,i=0;i<e;i+=1)this.audios[i].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){for(var t=this.audios.length,e=0;e<t;e+=1)this.audios[e].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}})(),createTypedArray=(()=>{function i(t,e){var i,r=0,s=[];switch(t){case"int16":case"uint8c":i=1;break;default:i=1.1}for(r=0;r<e;r+=1)s.push(i);return s}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(t,e){return"float32"===t?new Float32Array(e):"int16"===t?new Int16Array(e):"uint8c"===t?new Uint8ClampedArray(e):i(t,e)}:i})();function createSizedArray(t){return Array.apply(null,{length:t})}function _typeof$6(t){return(_typeof$6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var subframeEnabled=!0,expressionsPlugin=null,expressionsInterfaces=null,idPrefix$1="",isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),_shouldRoundValues=!1,bmPow=Math.pow,bmSqrt=Math.sqrt,bmFloor=Math.floor,bmMax=Math.max,bmMin=Math.min,BMMath={};function ProjectInterface$1(){}(()=>{for(var t=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],e=t.length,i=0;i<e;i+=1)BMMath[t[i]]=Math[t[i]]})(),BMMath.random=Math.random,BMMath.abs=function(t){if("object"===_typeof$6(t)&&t.length){for(var e=createSizedArray(t.length),i=t.length,r=0;r<i;r+=1)e[r]=Math.abs(t[r]);return e}return Math.abs(t)};var defaultCurveSegments=150,degToRads=Math.PI/180,roundCorner=.5519;function roundValues(t){_shouldRoundValues=!!t}function bmRnd(t){if(_shouldRoundValues)return Math.round(t)}function styleDiv(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin="0 0",t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility="visible",t.style.webkitBackfaceVisibility="visible",t.style.transformStyle="preserve-3d",t.style.webkitTransformStyle="preserve-3d",t.style.mozTransformStyle="preserve-3d"}function BMEnterFrameEvent(t,e,i,r){this.type=t,this.currentTime=e,this.totalTime=i,this.direction=r<0?-1:1}function BMCompleteEvent(t,e){this.type=t,this.direction=e<0?-1:1}function BMCompleteLoopEvent(t,e,i,r){this.type=t,this.currentLoop=i,this.totalLoops=e,this.direction=r<0?-1:1}function BMSegmentStartEvent(t,e,i){this.type=t,this.firstFrame=e,this.totalFrames=i}function BMDestroyEvent(t,e){this.type=t,this.target=e}function BMRenderFrameErrorEvent(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function BMConfigErrorEvent(t){this.type="configError",this.nativeError=t}function BMAnimationConfigErrorEvent(t,e){this.type=t,this.nativeError=e}var createElementID=(()=>{var t=0;return function(){return idPrefix$1+"__lottie_element_"+(t+=1)}})();function HSVtoRGB(t,e,i){var r,s,a,n=Math.floor(6*t),t=6*t-n,o=i*(1-e),h=i*(1-t*e),l=i*(1-(1-t)*e);switch(n%6){case 0:r=i,s=l,a=o;break;case 1:r=h,s=i,a=o;break;case 2:r=o,s=i,a=l;break;case 3:r=o,s=h,a=i;break;case 4:r=l,s=o,a=i;break;case 5:r=i,s=o,a=h}return[r,s,a]}function RGBtoHSV(t,e,i){var r,s=Math.max(t,e,i),a=Math.min(t,e,i),n=s-a,o=0===s?0:n/s,h=s/255;switch(s){case a:r=0;break;case t:r=e-i+n*(e<i?6:0),r/=6*n;break;case e:r=i-t+2*n,r/=6*n;break;case i:r=t-e+4*n,r/=6*n}return[r,o,h]}function addSaturationToRGB(t,e){t=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return t[1]+=e,1<t[1]?t[1]=1:t[1]<=0&&(t[1]=0),HSVtoRGB(t[0],t[1],t[2])}function addBrightnessToRGB(t,e){t=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return t[2]+=e,1<t[2]?t[2]=1:t[2]<0&&(t[2]=0),HSVtoRGB(t[0],t[1],t[2])}function addHueToRGB(t,e){t=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return t[0]+=e/360,1<t[0]?--t[0]:t[0]<0&&(t[0]+=1),HSVtoRGB(t[0],t[1],t[2])}var rgbToHex=(()=>{for(var t,r=[],e=0;e<256;e+=1)t=e.toString(16),r[e]=1===t.length?"0"+t:t;return function(t,e,i){return"#"+r[t=t<0?0:t]+r[e=e<0?0:e]+r[i=i<0?0:i]}})(),setSubframeEnabled=function(t){subframeEnabled=!!t},getSubframeEnabled=function(){return subframeEnabled},setExpressionsPlugin=function(t){expressionsPlugin=t},getExpressionsPlugin=function(){return expressionsPlugin},setExpressionInterfaces=function(t){expressionsInterfaces=t},getExpressionInterfaces=function(){return expressionsInterfaces},setDefaultCurveSegments=function(t){defaultCurveSegments=t},getDefaultCurveSegments=function(){return defaultCurveSegments},setIdPrefix=function(t){idPrefix$1=t},getIdPrefix=function(){return idPrefix$1};function createNS(t){return document.createElementNS(svgNS,t)}function _typeof$5(t){return(_typeof$5="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var dataManager=(()=>{var i,r,s=1,a=[],n={onmessage:function(){},postMessage:function(t){i({data:t})}},o={postMessage:function(t){n.onmessage({data:t})}};function h(){var t,e;r||(t=function(e){function t(){function p(t,e){for(var i,r,s,a=t.length,n=0;n<a;n+=1)if("ks"in(s=t[n])&&!s.completed){if(s.completed=!0,s.hasMask)for(var o=s.masksProperties,h=o.length,l=0;l<h;l+=1)if(o[l].pt.k.i)c(o[l].pt.k);else for(r=o[l].pt.k.length,i=0;i<r;i+=1)o[l].pt.k[i].s&&c(o[l].pt.k[i].s[0]),o[l].pt.k[i].e&&c(o[l].pt.k[i].e[0]);0===s.ty?(s.layers=m(s.refId,e),p(s.layers,e)):4===s.ty?f(s.shapes):5===s.ty&&0===(s=s).t.a.length&&0 in s.t.p}}function m(t,e){t=((t,e)=>{for(var i=0,r=e.length;i<r;){if(e[i].id===t)return e[i];i+=1}return null})(t,e);return t?t.layers.__used?JSON.parse(JSON.stringify(t.layers)):(t.layers.__used=!0,t.layers):null}function f(t){for(var e,i,r=t.length-1;0<=r;--r)if("sh"===t[r].ty)if(t[r].ks.k.i)c(t[r].ks.k);else for(i=t[r].ks.k.length,e=0;e<i;e+=1)t[r].ks.k[e].s&&c(t[r].ks.k[e].s[0]),t[r].ks.k[e].e&&c(t[r].ks.k[e].e[0]);else"gr"===t[r].ty&&f(t[r].it)}function c(t){for(var e=t.i.length,i=0;i<e;i+=1)t.i[i][0]+=t.v[i][0],t.i[i][1]+=t.v[i][1],t.o[i][0]+=t.v[i][0],t.o[i][1]+=t.v[i][1]}function s(t,e){e=e?e.split("."):[100,100,100];return t[0]>e[0]||!(t[0]<e[0])&&(e[1]<t[1]||!(t[1]<e[1])&&e[2]<t[2])}r=[4,4,14];var r,a=function(t){if(s(r,t.v)&&(n(t.layers),t.assets))for(var e=t.assets.length,i=0;i<e;i+=1)t.assets[i].layers&&n(t.assets[i].layers)};function n(t){for(var e,i,r=t.length,s=0;s<r;s+=1)5===t[s].ty&&(e=t[s],i=void 0,i=e.t.d,e.t.d={k:[{s:i,t:0}]})}o=[4,7,99];var o,h,l=function(t){if(t.chars&&!s(o,t.v))for(var e=t.chars.length,i=0;i<e;i+=1){var r=t.chars[i];r.data&&r.data.shapes&&(f(r.data.shapes),r.data.ip=0,r.data.op=99999,r.data.st=0,r.data.sr=1,r.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[i].t||(r.data.shapes.push({ty:"no"}),r.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}},d=(h=[5,7,15],function(t){if(s(h,t.v)&&(u(t.layers),t.assets))for(var e=t.assets.length,i=0;i<e;i+=1)t.assets[i].layers&&u(t.assets[i].layers)});function u(t){for(var e,i=t.length,r=0;r<i;r+=1)5===t[r].ty&&("number"==typeof(e=(e=t[r]).t.p).a&&(e.a={a:0,k:e.a}),"number"==typeof e.p&&(e.p={a:0,k:e.p}),"number"==typeof e.r)&&(e.r={a:0,k:e.r})}y=[4,1,9];var y,g=function(t){if(s(y,t.v)&&(v(t.layers),t.assets))for(var e=t.assets.length,i=0;i<e;i+=1)t.assets[i].layers&&v(t.assets[i].layers)};function v(t){for(var e=t.length,i=0;i<e;i+=1)4===t[i].ty&&!function t(e){for(var i,r,s=e.length,a=0;a<s;a+=1)if("gr"===e[a].ty)t(e[a].it);else if("fl"===e[a].ty||"st"===e[a].ty)if(e[a].c.k&&e[a].c.k[0].i)for(r=e[a].c.k.length,i=0;i<r;i+=1)e[a].c.k[i].s&&(e[a].c.k[i].s[0]/=255,e[a].c.k[i].s[1]/=255,e[a].c.k[i].s[2]/=255,e[a].c.k[i].s[3]/=255),e[a].c.k[i].e&&(e[a].c.k[i].e[0]/=255,e[a].c.k[i].e[1]/=255,e[a].c.k[i].e[2]/=255,e[a].c.k[i].e[3]/=255);else e[a].c.k[0]/=255,e[a].c.k[1]/=255,e[a].c.k[2]/=255,e[a].c.k[3]/=255}(t[i].shapes)}b=[4,4,18];var b,x=function(t){if(s(b,t.v)&&(P(t.layers),t.assets))for(var e=t.assets.length,i=0;i<e;i+=1)t.assets[i].layers&&P(t.assets[i].layers)};function P(t){for(var e,i,r,s=t.length,a=0;a<s;a+=1){if((e=t[a]).hasMask)for(var n=e.masksProperties,o=n.length,h=0;h<o;h+=1)if(n[h].pt.k.i)n[h].pt.k.c=n[h].cl;else for(r=n[h].pt.k.length,i=0;i<r;i+=1)n[h].pt.k[i].s&&(n[h].pt.k[i].s[0].c=n[h].cl),n[h].pt.k[i].e&&(n[h].pt.k[i].e[0].c=n[h].cl);4===e.ty&&!function t(e){for(var i,r,s=e.length-1;0<=s;--s)if("sh"===e[s].ty)if(e[s].ks.k.i)e[s].ks.k.c=e[s].closed;else for(r=e[s].ks.k.length,i=0;i<r;i+=1)e[s].ks.k[i].s&&(e[s].ks.k[i].s[0].c=e[s].closed),e[s].ks.k[i].e&&(e[s].ks.k[i].e[0].c=e[s].closed);else"gr"===e[s].ty&&t(e[s].it)}(e.shapes)}}var t={};return t.completeData=function(t){if(!t.__complete){g(t),a(t),l(t),d(t),x(t),p(t.layers,t.assets);var e=t.chars,i=t.assets;if(e)for(var r=0,s=e.length,r=0;r<s;r+=1)1===e[r].t&&(e[r].data.layers=m(e[r].data.refId,i),p(e[r].data.layers,i));t.__complete=!0}},t.checkColors=g,t.checkChars=l,t.checkPathProperties=d,t.checkShapes=x,t.completeLayers=p,t}function n(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")||t.response&&"object"===_typeof$5(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}var i;o.dataManager||(o.dataManager=t()),o.assetLoader||(o.assetLoader={load:function(e,i,t,r){var s,a=new XMLHttpRequest;try{a.responseType="json"}catch(t){}a.onreadystatechange=function(){if(4===a.readyState)if(200===a.status)s=n(a),t(s);else try{s=n(a),t(s)}catch(t){r&&r(t)}};try{a.open(["G","E","T"].join(""),e,!0)}catch(t){a.open(["G","E","T"].join(""),i+"/"+e,!0)}a.send()}}),"loadAnimation"===e.data.type?o.assetLoader.load(e.data.path,e.data.fullPath,function(t){o.dataManager.completeData(t),o.postMessage({id:e.data.id,payload:t,status:"success"})},function(){o.postMessage({id:e.data.id,status:"error"})}):"complete"===e.data.type?(i=e.data.animation,o.dataManager.completeData(i),o.postMessage({id:e.data.id,payload:i,status:"success"})):"loadData"===e.data.type&&o.assetLoader.load(e.data.path,e.data.fullPath,function(t){o.postMessage({id:e.data.id,payload:t,status:"success"})},function(){o.postMessage({id:e.data.id,status:"error"})})},(r=window.Worker&&window.Blob&&getWebWorker()?(e=new Blob(["var _workerSelf = self; self.onmessage = ",t.toString()],{type:"text/javascript"}),e=URL.createObjectURL(e),new Worker(e)):(i=t,n)).onmessage=function(t){var t=t.data,e=t.id,i=a[e];a[e]=null,"success"===t.status?i.onComplete(t.payload):i.onError&&i.onError()})}function l(t,e){var i="processId_"+(s+=1);return a[i]={onComplete:t,onError:e},i}return{loadAnimation:function(t,e,i){h(),e=l(e,i),r.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:e})},loadData:function(t,e,i){h(),e=l(e,i),r.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:e})},completeAnimation:function(t,e,i){h(),e=l(e,i),r.postMessage({type:"complete",animation:t,id:e})}}})(),ImagePreloader=(()=>{(t=createTag("canvas")).width=1,t.height=1,(e=t.getContext("2d")).fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1);var t,e,s=t;function i(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function r(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function a(t,e,i){var r="";return r=t.e?t.p:e?e+(e=-1!==(e=t.p).indexOf("images/")?e.split("/")[1]:e):(r=i,(r+=t.u||"")+t.p)}function n(){this._imageLoaded=i.bind(this),this._footageLoaded=r.bind(this),this.testImageLoaded=function(t){var e=0,i=setInterval(function(){(t.getBBox().width||500<e)&&(this._imageLoaded(),clearInterval(i)),e+=1}.bind(this),50)}.bind(this),this.createFootageData=function(t){var e={assetData:t},t=a(t,this.assetsPath,this.path);return dataManager.loadData(t,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return n.prototype={loadAssets:function(t,e){this.imagesLoadedCb=e;for(var i=t.length,r=0;r<i;r+=1)t[r].layers||(t[r].t&&"seq"!==t[r].t?3===t[r].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[r]))):(this.totalImages+=1,this.images.push(this._createImageData(t[r]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,i=this.images.length;e<i;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(t){var e=a(t,this.assetsPath,this.path),i=createTag("img"),r=(i.crossOrigin="anonymous",i.addEventListener("load",this._imageLoaded,!1),i.addEventListener("error",function(){r.img=s,this._imageLoaded()}.bind(this),!1),i.src=e,{img:i,assetData:t});return r},createImageData:function(t){var e=a(t,this.assetsPath,this.path),i=createNS("image"),r=(isSafari?this.testImageLoaded(i):i.addEventListener("load",this._imageLoaded,!1),i.addEventListener("error",function(){r.img=s,this._imageLoaded()}.bind(this),!1),i.setAttributeNS("http://www.w3.org/1999/xlink","href",e),this._elementHelper.append?this._elementHelper.append(i):this._elementHelper.appendChild(i),{img:i,assetData:t});return r},imageLoaded:i,footageLoaded:r,setCacheType:function(t,e){"svg"===t?(this._elementHelper=e,this._createImageData=this.createImageData.bind(this)):this._createImageData=this.createImgData.bind(this)}},n})();function BaseEvent(){}BaseEvent.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var i=this._cbs[t],r=0;r<i.length;r+=1)i[r](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var i=0,r=this._cbs[t].length;i<r;)this._cbs[t][i]===e&&(this._cbs[t].splice(i,1),--i,--r),i+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var markerParser=function(e){for(var t=[],i=0;i<e.length;i+=1){var r=e[i],r={time:r.tm,duration:r.dr};try{r.payload=JSON.parse(e[i].cm)}catch(t){try{r.payload=(t=>{for(var e,i=t.split("\r\n"),r={},s=0,a=0;a<i.length;a+=1)2===(e=i[a].split(":")).length&&(r[e[0]]=e[1].trim(),s+=1);if(0===s)throw new Error;return r})(e[i].cm)}catch(t){r.payload={name:e[i].cm}}}t.push(r)}return t},ProjectInterface=(()=>{function e(t){this.compositions.push(t)}return function(){function t(t){for(var e=0,i=this.compositions.length;e<i;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return t.compositions=[],t.currentFrame=0,t.registerComposition=e,t}})(),renderers={},registerRenderer=function(t,e){renderers[t]=e};function getRenderer(t){return renderers[t]}function getRegisteredRenderer(){if(renderers.canvas)return"canvas";for(var t in renderers)if(renderers[t])return t;return""}function _typeof$4(t){return(_typeof$4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var AnimationItem=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=createElementID(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=getSubframeEnabled(),this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=ProjectInterface(),this.imagePreloader=new ImagePreloader,this.audioController=audioControllerFactory(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new BMEnterFrameEvent("drawnFrame",0,0,0),this.expressionsPlugin=getExpressionsPlugin()},animationManager=(extendPrototype([BaseEvent],AnimationItem),AnimationItem.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg",i=(t.animType?e=t.animType:t.renderer&&(e=t.renderer),getRenderer(e));this.renderer=new i(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null==t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name||"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),dataManager.loadAnimation(t.path,this.configAnimation,this.onSetupError))},AnimationItem.prototype.onSetupError=function(){this.trigger("data_failed")},AnimationItem.prototype.setupAnimation=function(t){dataManager.completeAnimation(t,this.configAnimation)},AnimationItem.prototype.setData=function(t,e){var e={wrapper:t,animationData:e=e&&"object"!==_typeof$4(e)?JSON.parse(e):e},t=t.attributes,i=(e.path=t.getNamedItem("data-animation-path")?t.getNamedItem("data-animation-path").value:t.getNamedItem("data-bm-path")?t.getNamedItem("data-bm-path").value:t.getNamedItem("bm-path")?t.getNamedItem("bm-path").value:"",e.animType=t.getNamedItem("data-anim-type")?t.getNamedItem("data-anim-type").value:t.getNamedItem("data-bm-type")?t.getNamedItem("data-bm-type").value:t.getNamedItem("bm-type")?t.getNamedItem("bm-type").value:t.getNamedItem("data-bm-renderer")?t.getNamedItem("data-bm-renderer").value:t.getNamedItem("bm-renderer")?t.getNamedItem("bm-renderer").value:getRegisteredRenderer()||"canvas",t.getNamedItem("data-anim-loop")?t.getNamedItem("data-anim-loop").value:t.getNamedItem("data-bm-loop")?t.getNamedItem("data-bm-loop").value:t.getNamedItem("bm-loop")?t.getNamedItem("bm-loop").value:""),i=("false"===i?e.loop=!1:"true"===i?e.loop=!0:""!==i&&(e.loop=parseInt(i,10)),t.getNamedItem("data-anim-autoplay")?t.getNamedItem("data-anim-autoplay").value:t.getNamedItem("data-bm-autoplay")?t.getNamedItem("data-bm-autoplay").value:!t.getNamedItem("bm-autoplay")||t.getNamedItem("bm-autoplay").value);e.autoplay="false"!==i,e.name=t.getNamedItem("data-name")?t.getNamedItem("data-name").value:t.getNamedItem("data-bm-name")?t.getNamedItem("data-bm-name").value:t.getNamedItem("bm-name")?t.getNamedItem("bm-name").value:"","false"===(t.getNamedItem("data-anim-prerender")?t.getNamedItem("data-anim-prerender").value:t.getNamedItem("data-bm-prerender")?t.getNamedItem("data-bm-prerender").value:t.getNamedItem("bm-prerender")?t.getNamedItem("bm-prerender").value:"")&&(e.prerender=!1),e.path?this.setParams(e):this.trigger("destroy")},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));for(var e,i=this.animationData.layers,r=i.length,s=t.layers,a=s.length,n=0;n<a;n+=1)for(e=0;e<r;){if(i[e].id===s[n].id){i[e]=s[n];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(r=t.assets.length,e=0;e<r;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,dataManager.completeAnimation(this.animationData,this.onSegmentComplete)},AnimationItem.prototype.onSegmentComplete=function(t){this.animationData=t;t=getExpressionsPlugin();t&&t.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;t&&0!==t.length&&this.autoloadSegments?(t=t.shift(),this.timeCompleted=t.time*this.frameRate,t=this.path+this.fileName+"_"+this.segmentPos+".json",this.segmentPos+=1,dataManager.loadData(t,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))):(this.trigger("data_ready"),this.timeCompleted=this.totalFrames)},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},AnimationItem.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},AnimationItem.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=markerParser(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},AnimationItem.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},AnimationItem.prototype.checkLoaded=function(){var t;!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()&&(this.isLoaded=!0,(t=getExpressionsPlugin())&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay)&&this.play()},AnimationItem.prototype.resize=function(t,e){this.renderer.updateContainerSize("number"==typeof t?t:void 0,"number"==typeof e?e:void 0)},AnimationItem.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},AnimationItem.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},AnimationItem.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},AnimationItem.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle)&&(this._idle=!1,this.trigger("_active"))},AnimationItem.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},AnimationItem.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.getMarkerData=function(t){for(var e,i=0;i<this.markers.length;i+=1)if((e=this.markers[i]).payload&&e.payload.name===t)return e;return null},AnimationItem.prototype.goToAndStop=function(t,e,i){i&&this.name!==i||(i=Number(t),isNaN(i)?(i=this.getMarkerData(t))&&this.goToAndStop(i.time,!0):e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier),this.pause())},AnimationItem.prototype.goToAndPlay=function(t,e,i){var r;i&&this.name!==i||(r=Number(t),isNaN(r)?(t=this.getMarkerData(t))&&(t.duration?this.playSegments([t.time,t.time+t.duration],!0):this.goToAndStop(t.time,!0)):this.goToAndStop(r,e,i),this.play())},AnimationItem.prototype.advanceTime=function(t){var e;!0!==this.isPaused&&!1!==this.isLoaded&&(e=!1,(t=this.currentRawFrame+t*this.frameModifier)>=this.totalFrames-1&&0<this.frameModifier?this.loop&&this.playCount!==this.loop?t>=this.totalFrames?(this.playCount+=1,this.checkSegments(t%this.totalFrames)||(this.setCurrentRawFrameValue(t%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(t):this.checkSegments(t>this.totalFrames?t%this.totalFrames:0)||(e=!0,t=this.totalFrames-1):t<0?this.checkSegments(t%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(e=!0,t=0):(this.setCurrentRawFrameValue(this.totalFrames+t%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(t),e)&&(this.setCurrentRawFrameValue(t),this.pause(),this.trigger("complete"))},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(0<this.frameModifier&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var i=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?i=t:this.currentRawFrame+this.firstFrame>e&&(i=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==i&&this.goToAndStop(i,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===_typeof$4(t[0]))for(var i=t.length,r=0;r<i;r+=1)this.segments.push(t[r]);else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},AnimationItem.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},AnimationItem.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},AnimationItem.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},AnimationItem.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},AnimationItem.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},AnimationItem.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},AnimationItem.prototype.setLoop=function(t){this.loop=t},AnimationItem.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},AnimationItem.prototype.getVolume=function(){return this.audioController.getVolume()},AnimationItem.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},AnimationItem.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},AnimationItem.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},AnimationItem.prototype.getPath=function(){return this.path},AnimationItem.prototype.getAssetsPath=function(t){var e,i="";return i=t.e?t.p:this.assetsPath?(-1!==(e=t.p).indexOf("images/")&&(e=e.split("/")[1]),this.assetsPath+e):(i=this.path,(i+=t.u||"")+t.p)},AnimationItem.prototype.getAssetData=function(t){for(var e=0,i=this.assets.length;e<i;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},AnimationItem.prototype.hide=function(){this.renderer.hide()},AnimationItem.prototype.show=function(){this.renderer.show()},AnimationItem.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},AnimationItem.prototype.updateDocumentData=function(t,e,i){try{this.renderer.getElementByPath(t).updateDocumentData(e,i)}catch(t){}},AnimationItem.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new BMCompleteEvent(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new BMDestroyEvent(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new BMCompleteEvent(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new BMDestroyEvent(t,this))},AnimationItem.prototype.triggerRenderFrameError=function(t){t=new BMRenderFrameErrorEvent(t,this.currentFrame);this.triggerEvent("error",t),this.onError&&this.onError.call(this,t)},AnimationItem.prototype.triggerConfigError=function(t){t=new BMConfigErrorEvent(t,this.currentFrame);this.triggerEvent("error",t),this.onError&&this.onError.call(this,t)},(()=>{var t={},s=[],r=0,a=0,n=0,o=!0,h=!1;function i(t){for(var e=0,i=t.target;e<a;)s[e].animation===i&&(s.splice(e,1),--e,--a,i.isPaused||m()),e+=1}function l(t,e){if(!t)return null;for(var i=0;i<a;){if(s[i].elem===t&&null!==s[i].elem)return s[i].animation;i+=1}var r=new AnimationItem;return f(r,t),r.setData(t,e),r}function p(){n+=1,d()}function m(){--n}function f(t,e){t.addEventListener("destroy",i),t.addEventListener("_active",p),t.addEventListener("_idle",m),s.push({elem:e,animation:t}),a+=1}function c(t){for(var e=t-r,i=0;i<a;i+=1)s[i].animation.advanceTime(e);r=t,n&&!h?window.requestAnimationFrame(c):o=!0}function e(t){r=t,window.requestAnimationFrame(c)}function d(){!h&&n&&o&&(window.requestAnimationFrame(e),o=!1)}return t.registerAnimation=l,t.loadAnimation=function(t){var e=new AnimationItem;return f(e,null),e.setParams(t),e},t.setSpeed=function(t,e){for(var i=0;i<a;i+=1)s[i].animation.setSpeed(t,e)},t.setDirection=function(t,e){for(var i=0;i<a;i+=1)s[i].animation.setDirection(t,e)},t.play=function(t){for(var e=0;e<a;e+=1)s[e].animation.play(t)},t.pause=function(t){for(var e=0;e<a;e+=1)s[e].animation.pause(t)},t.stop=function(t){for(var e=0;e<a;e+=1)s[e].animation.stop(t)},t.togglePause=function(t){for(var e=0;e<a;e+=1)s[e].animation.togglePause(t)},t.searchAnimations=function(t,e,i){for(var r,s=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),a=s.length,n=0;n<a;n+=1)i&&s[n].setAttribute("data-bm-type",i),l(s[n],t);e&&0===a&&(i=i||"svg",(e=document.getElementsByTagName("body")[0]).innerText="",(r=createTag("div")).style.width="100%",r.style.height="100%",r.setAttribute("data-bm-type",i),e.appendChild(r),l(r,t))},t.resize=function(){for(var t=0;t<a;t+=1)s[t].animation.resize()},t.goToAndStop=function(t,e,i){for(var r=0;r<a;r+=1)s[r].animation.goToAndStop(t,e,i)},t.destroy=function(t){for(var e=a-1;0<=e;--e)s[e].animation.destroy(t)},t.freeze=function(){h=!0},t.unfreeze=function(){h=!1,d()},t.setVolume=function(t,e){for(var i=0;i<a;i+=1)s[i].animation.setVolume(t,e)},t.mute=function(t){for(var e=0;e<a;e+=1)s[e].animation.mute(t)},t.unmute=function(t){for(var e=0;e<a;e+=1)s[e].animation.unmute(t)},t.getRegisteredAnimations=function(){for(var t=s.length,e=[],i=0;i<t;i+=1)e.push(s[i].animation);return e},t})()),BezierFactory=(()=>{var t={getBezierEasing:function(t,e,i,r,s){s=s||("bez_"+t+"_"+e+"_"+i+"_"+r).replace(/\./g,"p");if(a[s])return a[s];t=new n([t,e,i,r]);return a[s]=t}},a={},S=4,C=1e-7,_=10,A=11,T=1/(A-1),e="function"==typeof Float32Array;function r(t,e){return 1-3*e+3*t}function M(t,e,i){return((r(e,i)*t+(3*i-6*e))*t+3*e)*t}function k(t,e,i){return 3*r(e,i)*t*t+2*(3*i-6*e)*t+3*e}function n(t){this._p=t,this._mSampleValues=new(e?Float32Array:Array)(A),this._precomputed=!1,this.get=this.get.bind(this)}return n.prototype={get:function(t){var e=this._p[0],i=this._p[1],r=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===i&&r===s?t:0===t?0:1===t?1:M(this._getTForX(t),i,s)},_precompute:function(){var t=this._p[0],e=this._p[1],i=this._p[2],r=this._p[3];this._precomputed=!0,t===e&&i===r||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],i=0;i<A;++i)this._mSampleValues[i]=M(i*T,t,e)},_getTForX:function(t){for(var e=this._p[0],i=this._p[2],r=this._mSampleValues,s=0,a=1,n=A-1;a!==n&&r[a]<=t;++a)s+=T;var o=s+(t-r[--a])/(r[a+1]-r[a])*T,h=k(o,e,i);if(.001<=h){for(var l=t,p=o,m=e,f=i,c=0;c<S;++c){var d=k(p,m,f);if(0===d)return p;p-=(M(p,m,f)-l)/d}return p}if(0===h)return o;for(var u,y,g=t,v=s,b=s+T,x=e,P=i,E=0;0<(u=M(y=v+(b-v)/2,x,P)-g)?b=y:v=y,Math.abs(u)>C&&++E<_;);return y}},t})(),pooling={double:function(t){return t.concat(createSizedArray(t.length))}},poolFactory=function(t,e,i){var r=0,s=t,a=createSizedArray(s);return{newElement:function(){var t;t=r?a[--r]:e();return t},release:function(t){r===s&&(a=pooling.double(a),s*=2);i&&i(t);a[r]=t,r+=1}}},bezierLengthPool=poolFactory(8,function(){return{addedLength:0,percents:createTypedArray("float32",getDefaultCurveSegments()),lengths:createTypedArray("float32",getDefaultCurveSegments())}}),segmentsLengthPool=poolFactory(8,function(){return{lengths:[],totalLength:0}},function(t){for(var e=t.lengths.length,i=0;i<e;i+=1)bezierLengthPool.release(t.lengths[i]);t.lengths.length=0});function bezFunction(){var A=Math;function y(t,e,i,r,s,a){s=t*r+e*s+i*a-s*r-a*t-i*e;return-.001<s&&s<.001}var p=function(t,e,i,r){for(var s,a,n,o,h=getDefaultCurveSegments(),l=0,p=[],m=[],f=bezierLengthPool.newElement(),c=i.length,d=0;d<h;d+=1){for(n=d/(h-1),s=o=0;s<c;s+=1)a=bmPow(1-n,3)*t[s]+3*bmPow(1-n,2)*n*i[s]+3*(1-n)*bmPow(n,2)*r[s]+bmPow(n,3)*e[s],p[s]=a,null!==m[s]&&(o+=bmPow(p[s]-m[s],2)),m[s]=p[s];o&&(l+=o=bmSqrt(o)),f.percents[d]=n,f.lengths[d]=l}return f.addedLength=l,f};function g(t){this.segmentLength=0,this.points=new Array(t)}function v(t,e){this.partialLength=t,this.point=e}function t(t,e,i,r){var s=(t[0]+"_"+t[1]+"_"+e[0]+"_"+e[1]+"_"+i[0]+"_"+i[1]+"_"+r[0]+"_"+r[1]).replace(/\./g,"p");if(!b[s]){for(var a,n,o,h,l,p=getDefaultCurveSegments(),m=0,f=null,c=new g(p=2===t.length&&(t[0]!==e[0]||t[1]!==e[1])&&y(t[0],t[1],e[0],e[1],t[0]+i[0],t[1]+i[1])&&y(t[0],t[1],e[0],e[1],e[0]+r[0],e[1]+r[1])?2:p),d=i.length,u=0;u<p;u+=1){for(l=createSizedArray(d),o=u/(p-1),a=h=0;a<d;a+=1)n=bmPow(1-o,3)*t[a]+3*bmPow(1-o,2)*o*(t[a]+i[a])+3*(1-o)*bmPow(o,2)*(e[a]+r[a])+bmPow(o,3)*e[a],l[a]=n,null!==f&&(h+=bmPow(l[a]-f[a],2));m+=h=bmSqrt(h),c.points[u]=new v(h,l),f=l}c.segmentLength=m,b[s]=c}return b[s]}var b;b={};function T(t,e){var i=e.percents,r=e.lengths,s=i.length,a=bmFloor((s-1)*t),n=t*e.addedLength,o=0;if(a===s-1||0===a||n===r[a])return i[a];for(var h=r[a]>n?-1:1,l=!0;l;)if(r[a]<=n&&r[a+1]>n?(o=(n-r[a])/(r[a+1]-r[a]),l=!1):a+=h,a<0||s-1<=a){if(a===s-1)return i[a];l=!1}return i[a]+(i[a+1]-i[a])*o}var M=createTypedArray("float32",8);return{getSegmentsLength:function(t){for(var e=segmentsLengthPool.newElement(),i=t.c,r=t.v,s=t.o,a=t.i,n=t._length,o=e.lengths,h=0,l=0;l<n-1;l+=1)o[l]=p(r[l],r[l+1],s[l],a[l+1]),h+=o[l].addedLength;return i&&n&&(o[l]=p(r[l],r[0],s[l],a[0]),h+=o[l].addedLength),e.totalLength=h,e},getNewSegment:function(t,e,i,r,s,a,n){s<0?s=0:1<s&&(s=1);for(var s=T(s,n),a=T(a=1<a?1:a,n),o=t.length,h=1-a,l=(n=1-s)*n*n,p=s*n*n*3,m=s*s*n*3,f=s*s*s,c=n*n*h,d=s*n*h+n*s*h+n*n*a,u=s*s*h+n*s*a+s*n*a,y=s*s*a,g=n*h*h,v=s*h*h+n*a*h+n*h*a,b=s*a*h+n*a*a+s*h*a,x=s*a*a,P=h*h*h,E=a*h*h+h*a*h+h*h*a,S=a*a*h+h*a*a+a*h*a,C=a*a*a,_=0;_<o;_+=1)M[4*_]=A.round(1e3*(l*t[_]+p*i[_]+m*r[_]+f*e[_]))/1e3,M[4*_+1]=A.round(1e3*(c*t[_]+d*i[_]+u*r[_]+y*e[_]))/1e3,M[4*_+2]=A.round(1e3*(g*t[_]+v*i[_]+b*r[_]+x*e[_]))/1e3,M[4*_+3]=A.round(1e3*(P*t[_]+E*i[_]+S*r[_]+C*e[_]))/1e3;return M},getPointInSegment:function(t,e,i,r,s,a){return s=T(s,a),a=1-s,[A.round(1e3*(a*a*a*t[0]+(s*a*a+a*s*a+a*a*s)*i[0]+(s*s*a+a*s*s+s*a*s)*r[0]+s*s*s*e[0]))/1e3,A.round(1e3*(a*a*a*t[1]+(s*a*a+a*s*a+a*a*s)*i[1]+(s*s*a+a*s*s+s*a*s)*r[1]+s*s*s*e[1]))/1e3]},buildBezierData:t,pointOnLine2D:y,pointOnLine3D:function(t,e,i,r,s,a,n,o,h){var l;return 0===i&&0===a&&0===h?y(t,e,r,s,n,o):(l=A.sqrt(A.pow(r-t,2)+A.pow(s-e,2)+A.pow(a-i,2)),t=A.sqrt(A.pow(n-t,2)+A.pow(o-e,2)+A.pow(h-i,2)),e=A.sqrt(A.pow(n-r,2)+A.pow(o-s,2)+A.pow(h-a,2)),-1e-4<(i=t<l?e<l?l-t-e:e-t-l:t<e?e-t-l:t-l-e)&&i<1e-4)}}}var bez=bezFunction(),initFrame=initialDefaultFrame,mathAbs=Math.abs;function interpolateValue(t,e){for(var i,r,s,a,n=this.offsetTime,o=("multidimensional"===this.propType&&(i=createTypedArray("float32",this.pv.length)),e.lastIndex),h=o,l=this.keyframes.length-1,p=!0;p;){if(r=this.keyframes[h],s=this.keyframes[h+1],h===l-1&&t>=s.t-n){r.h&&(r=s),o=0;break}if(s.t-n>t){o=h;break}h<l-1?h+=1:(o=0,p=!1)}var m=this.keyframesMetadata[h]||{},f=s.t-n,c=r.t-n;if(r.to){m.bezierData||(m.bezierData=bez.buildBezierData(r.s,s.s||r.e,r.to,r.ti));var d=m.bezierData;if(f<=t||t<c)for(var u=f<=t?d.points.length-1:0,y=d.points[u].point.length,g=0;g<y;g+=1)i[g]=d.points[u].point[g];else{m.__fnct?a=m.__fnct:(a=BezierFactory.getBezierEasing(r.o.x,r.o.y,r.i.x,r.i.y,r.n).get,m.__fnct=a);for(var v,b=a((t-c)/(f-c)),x=d.segmentLength*b,P=e.lastFrame<t&&e._lastKeyframeIndex===h?e._lastAddedLength:0,E=e.lastFrame<t&&e._lastKeyframeIndex===h?e._lastPoint:0,p=!0,S=d.points.length;p;){if(P+=d.points[E].partialLength,0==x||0===b||E===d.points.length-1){for(y=d.points[E].point.length,g=0;g<y;g+=1)i[g]=d.points[E].point[g];break}if(P<=x&&x<P+d.points[E+1].partialLength){for(v=(x-P)/d.points[E+1].partialLength,y=d.points[E].point.length,g=0;g<y;g+=1)i[g]=d.points[E].point[g]+(d.points[E+1].point[g]-d.points[E].point[g])*v;break}E<S-1?E+=1:p=!1}e._lastPoint=E,e._lastAddedLength=P-d.points[E].partialLength,e._lastKeyframeIndex=h}}else{var C,_,A,T,M,l=r.s.length,k=s.s||r.e;if(this.sh&&1!==r.h)f<=t?(i[0]=k[0],i[1]=k[1],i[2]=k[2]):t<=c?(i[0]=r.s[0],i[1]=r.s[1],i[2]=r.s[2]):quaternionToEuler(i,slerp(createQuaternion(r.s),createQuaternion(k),(t-c)/(f-c)));else for(h=0;h<l;h+=1)1!==r.h&&(b=f<=t?1:t<c?0:(r.o.x.constructor===Array?(m.__fnct||(m.__fnct=[]),m.__fnct[h]?a=m.__fnct[h]:(C=void 0===r.o.x[h]?r.o.x[0]:r.o.x[h],_=void 0===r.o.y[h]?r.o.y[0]:r.o.y[h],A=void 0===r.i.x[h]?r.i.x[0]:r.i.x[h],T=void 0===r.i.y[h]?r.i.y[0]:r.i.y[h],a=BezierFactory.getBezierEasing(C,_,A,T).get,m.__fnct[h]=a)):m.__fnct?a=m.__fnct:(C=r.o.x,_=r.o.y,A=r.i.x,T=r.i.y,a=BezierFactory.getBezierEasing(C,_,A,T).get,r.keyframeMetadata=a),a((t-c)/(f-c)))),k=s.s||r.e,M=1===r.h?r.s[h]:r.s[h]+(k[h]-r.s[h])*b,"multidimensional"===this.propType?i[h]=M:i=M}return e.lastIndex=o,i}function slerp(t,e,i){var r,s,a=[],n=t[0],o=t[1],h=t[2],t=t[3],l=e[0],p=e[1],m=e[2],e=e[3],f=n*l+o*p+h*m+t*e;return f<0&&(f=-f,l=-l,p=-p,m=-m,e=-e),f=1e-6<1-f?(f=Math.acos(f),r=Math.sin(f),s=Math.sin((1-i)*f)/r,Math.sin(i*f)/r):(s=1-i,i),a[0]=s*n+f*l,a[1]=s*o+f*p,a[2]=s*h+f*m,a[3]=s*t+f*e,a}function quaternionToEuler(t,e){var i=e[0],r=e[1],s=e[2],e=e[3],a=Math.atan2(2*r*e-2*i*s,1-2*r*r-2*s*s),n=Math.asin(2*i*r+2*s*e),e=Math.atan2(2*i*e-2*r*s,1-2*i*i-2*s*s);t[0]=a/degToRads,t[1]=n/degToRads,t[2]=e/degToRads}function createQuaternion(t){var e=t[0]*degToRads,i=t[1]*degToRads,t=t[2]*degToRads,r=Math.cos(e/2),s=Math.cos(i/2),a=Math.cos(t/2),e=Math.sin(e/2),i=Math.sin(i/2),t=Math.sin(t/2);return[e*i*a+r*s*t,e*s*a+r*i*t,r*i*a-e*s*t,r*s*a-e*i*t]}function getValueAtCurrentTime(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime;return t===this._caching.lastFrame||this._caching.lastFrame!==initFrame&&(this._caching.lastFrame>=i&&i<=t||this._caching.lastFrame<e&&t<e)||(this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0),i=this.interpolateValue(t,this._caching),this.pv=i),this._caching.lastFrame=t,this.pv}function setVValue(t){var e;if("unidimensional"===this.propType)e=t*this.mult,1e-5<mathAbs(this.v-e)&&(this.v=e,this._mdf=!0);else for(var i=0,r=this.v.length;i<r;)e=t[i]*this.mult,1e-5<mathAbs(this.v[i]-e)&&(this.v[i]=e,this._mdf=!0),i+=1}function processEffectsSequence(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{this.lock=!0,this._mdf=this._isFirstFrame;for(var t=this.effectsSequence.length,e=this.kf?this.pv:this.data.k,i=0;i<t;i+=1)e=this.effectsSequence[i](e);this.setVValue(e),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function addEffect(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function ValueProperty(t,e,i,r){this.propType="unidimensional",this.mult=i||1,this.data=e,this.v=i?e.k*i:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function MultiDimensionalProperty(t,e,i,r){this.propType="multidimensional",this.mult=i||1,this.data=e,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var s,a=e.k.length;for(this.v=createTypedArray("float32",a),this.pv=createTypedArray("float32",a),this.vel=createTypedArray("float32",a),s=0;s<a;s+=1)this.v[s]=e.k[s]*this.mult,this.pv[s]=e.k[s];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function KeyframedValueProperty(t,e,i,r){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:initFrame,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.v=initFrame,this.pv=initFrame,this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.addEffect=addEffect}function KeyframedMultidimensionalProperty(t,e,i,r){this.propType="multidimensional";for(var s,a,n,o,h=e.k.length,l=0;l<h-1;l+=1)e.k[l].to&&e.k[l].s&&e.k[l+1]&&e.k[l+1].s&&(s=e.k[l].s,a=e.k[l+1].s,n=e.k[l].to,o=e.k[l].ti,(2===s.length&&(s[0]!==a[0]||s[1]!==a[1])&&bez.pointOnLine2D(s[0],s[1],a[0],a[1],s[0]+n[0],s[1]+n[1])&&bez.pointOnLine2D(s[0],s[1],a[0],a[1],a[0]+o[0],a[1]+o[1])||3===s.length&&(s[0]!==a[0]||s[1]!==a[1]||s[2]!==a[2])&&bez.pointOnLine3D(s[0],s[1],s[2],a[0],a[1],a[2],s[0]+n[0],s[1]+n[1],s[2]+n[2])&&bez.pointOnLine3D(s[0],s[1],s[2],a[0],a[1],a[2],a[0]+o[0],a[1]+o[1],a[2]+o[2]))&&(e.k[l].to=null,e.k[l].ti=null),s[0]===a[0])&&s[1]===a[1]&&0===n[0]&&0===n[1]&&0===o[0]&&0===o[1]&&(2===s.length||s[2]===a[2]&&0===n[2]&&0===o[2])&&(e.k[l].to=null,e.k[l].ti=null);this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.frameId=-1;var p=e.k[0].s.length;for(this.v=createTypedArray("float32",p),this.pv=createTypedArray("float32",p),l=0;l<p;l+=1)this.v[l]=initFrame,this.pv[l]=initFrame;this._caching={lastFrame:initFrame,lastIndex:0,value:createTypedArray("float32",p)},this.addEffect=addEffect}var PropertyFactory={getProp:function(t,e,i,r,s){var a;if((e=e.sid?t.globalData.slotManager.getProp(e):e).k.length)if("number"==typeof e.k[0])a=new MultiDimensionalProperty(t,e,r,s);else switch(i){case 0:a=new KeyframedValueProperty(t,e,r,s);break;case 1:a=new KeyframedMultidimensionalProperty(t,e,r,s)}else a=new ValueProperty(t,e,r,s);return a.effectsSequence.length&&s.addDynamicProperty(a),a}};function DynamicPropertyContainer(){}DynamicPropertyContainer.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){this._mdf=!1;for(var t=this.dynamicProperties.length,e=0;e<t;e+=1)this.dynamicProperties[e].getValue(),this.dynamicProperties[e]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var pointPool=poolFactory(8,function(){return createTypedArray("float32",2)});function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var i=0;i<e;)this.v[i]=pointPool.newElement(),this.o[i]=pointPool.newElement(),this.i[i]=pointPool.newElement(),i+=1},ShapePath.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},ShapePath.prototype.doubleArrayLength=function(){this.v=this.v.concat(createSizedArray(this._maxLength)),this.i=this.i.concat(createSizedArray(this._maxLength)),this.o=this.o.concat(createSizedArray(this._maxLength)),this._maxLength*=2},ShapePath.prototype.setXYAt=function(t,e,i,r,s){var a;switch(this._length=Math.max(this._length,r+1),this._length>=this._maxLength&&this.doubleArrayLength(),i){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o;break;default:a=[]}a[r]&&(a[r],s)||(a[r]=pointPool.newElement()),a[r][0]=t,a[r][1]=e},ShapePath.prototype.setTripleAt=function(t,e,i,r,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(i,r,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){for(var t=new ShapePath,e=(t.setPathData(this.c,this._length),this.v),i=this.o,r=this.i,s=0,a=(this.c&&(t.setTripleAt(e[0][0],e[0][1],r[0][0],r[0][1],i[0][0],i[0][1],0,!1),s=1),this._length-1),n=this._length,o=s;o<n;o+=1)t.setTripleAt(e[a][0],e[a][1],r[a][0],r[a][1],i[a][0],i[a][1],o,!1),--a;return t},ShapePath.prototype.length=function(){return this._length};var shapePool=(()=>{var s=poolFactory(4,function(){return new ShapePath},function(t){for(var e=t._length,i=0;i<e;i+=1)pointPool.release(t.v[i]),pointPool.release(t.i[i]),pointPool.release(t.o[i]),t.v[i]=null,t.i[i]=null,t.o[i]=null;t._length=0,t.c=!1});return s.clone=function(t){var e,i=s.newElement(),r=void 0===t._length?t.v.length:t._length;for(i.setLength(r),i.c=t.c,e=0;e<r;e+=1)i.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return i},s})();function ShapeCollection(){this._length=0,this._maxLength=4,this.shapes=createSizedArray(this._maxLength)}ShapeCollection.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(createSizedArray(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},ShapeCollection.prototype.releaseShapes=function(){for(var t=0;t<this._length;t+=1)shapePool.release(this.shapes[t]);this._length=0};var shapeCollectionPool=(()=>{var t={newShapeCollection:function(){var t;t=r?a[--r]:new ShapeCollection;return t},release:function(t){var e,i=t._length;for(e=0;e<i;e+=1)shapePool.release(t.shapes[e]);t._length=0,r===s&&(a=pooling.double(a),s*=2);a[r]=t,r+=1}},r=0,s=4,a=createSizedArray(s);return t})(),ShapePropertyFactory=(()=>{var s=-999999;function t(t,e,i){var r,s,a,n,o,h,l,p=i.lastIndex,m=this.keyframes;if(t<m[0].t-this.offsetTime)r=m[0].s[0],s=!0,p=0;else if(t>=m[m.length-1].t-this.offsetTime)r=(m[m.length-1].s?m[m.length-1].s:m[m.length-2].e)[0],s=!0;else{for(var f,c,d,u,y,g,v=p,b=m.length-1,x=!0;x&&(f=m[v],!((c=m[v+1]).t-this.offsetTime>t));)v<b-1?v+=1:x=!1;d=this.keyframesMetadata[v]||{},p=v,(s=1===f.h)||(y=t>=c.t-this.offsetTime?1:t<f.t-this.offsetTime?0:(d.__fnct?u=d.__fnct:(u=BezierFactory.getBezierEasing(f.o.x,f.o.y,f.i.x,f.i.y).get,d.__fnct=u),u((t-(f.t-this.offsetTime))/(c.t-this.offsetTime-(f.t-this.offsetTime)))),g=(c.s||f.e)[0]),r=f.s[0]}for(o=e._length,h=r.i[0].length,i.lastIndex=p,a=0;a<o;a+=1)for(n=0;n<h;n+=1)l=s?r.i[a][n]:r.i[a][n]+(g.i[a][n]-r.i[a][n])*y,e.i[a][n]=l,l=s?r.o[a][n]:r.o[a][n]+(g.o[a][n]-r.o[a][n])*y,e.o[a][n]=l,l=s?r.v[a][n]:r.v[a][n]+(g.v[a][n]-r.v[a][n])*y,e.v[a][n]=l}function r(){this.paths=this.localShapeCollection}function e(t){((t,e)=>{if(t._length===e._length&&t.c===e.c){for(var i=t._length,r=0;r<i;r+=1)if(t.v[r][0]!==e.v[r][0]||t.v[r][1]!==e.v[r][1]||t.o[r][0]!==e.o[r][0]||t.o[r][1]!==e.o[r][1]||t.i[r][0]!==e.i[r][0]||t.i[r][1]!==e.i[r][1])return;return 1}})(this.v,t)||(this.v=shapePool.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function i(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{this.lock=!0,this._mdf=!1,t=this.kf?this.pv:(this.data.ks||this.data.pt).k;for(var t,e=this.effectsSequence.length,i=0;i<e;i+=1)t=this.effectsSequence[i](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function a(t,e,i){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;t=(3===i?e.pt:e.ks).k;this.v=shapePool.clone(t),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=r,this.effectsSequence=[]}function n(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function o(t,e,i){this.propType="shape",this.comp=t.comp,this.elem=t,this.container=t,this.offsetTime=t.data.st,this.keyframes=(3===i?e.pt:e.ks).k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;t=this.keyframes[0].s[0].i.length;this.v=shapePool.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,t),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=s,this.reset=r,this._caching={lastFrame:s,lastIndex:0},this.effectsSequence=[function(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime,r=this._caching.lastFrame;return r!==s&&(r<e&&t<e||i<r&&i<t)||(this._caching.lastIndex=r<t?this._caching.lastIndex:0,this.interpolateShape(t,this.pv,this._caching)),this._caching.lastFrame=t,this.pv}.bind(this)]}a.prototype.interpolateShape=t,a.prototype.getValue=i,a.prototype.setVValue=e,a.prototype.addEffect=n,o.prototype.getValue=i,o.prototype.interpolateShape=t,o.prototype.setVValue=e,o.prototype.addEffect=n,h=roundCorner,p.prototype={reset:r,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf)&&this.convertEllToPath()},convertEllToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,r=this.s.v[1]/2,s=3!==this.d,a=this.v;a.v[0][0]=t,a.v[0][1]=e-r,a.v[1][0]=s?t+i:t-i,a.v[1][1]=e,a.v[2][0]=t,a.v[2][1]=e+r,a.v[3][0]=s?t-i:t+i,a.v[3][1]=e,a.i[0][0]=s?t-i*h:t+i*h,a.i[0][1]=e-r,a.i[1][0]=s?t+i:t-i,a.i[1][1]=e-r*h,a.i[2][0]=s?t+i*h:t-i*h,a.i[2][1]=e+r,a.i[3][0]=s?t-i:t+i,a.i[3][1]=e+r*h,a.o[0][0]=s?t+i*h:t-i*h,a.o[0][1]=e-r,a.o[1][0]=s?t+i:t-i,a.o[1][1]=e+r*h,a.o[2][0]=s?t-i*h:t+i*h,a.o[2][1]=e+r,a.o[3][0]=s?t-i:t+i,a.o[3][1]=e-r*h}},extendPrototype([DynamicPropertyContainer],p);var h,l=p;function p(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}f.prototype={reset:r,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf)&&this.convertToPath()},convertStarToPath:function(){for(var t=2*Math.floor(this.pt.v),e=2*Math.PI/t,i=!0,r=this.or.v,s=this.ir.v,a=this.os.v,n=this.is.v,o=2*Math.PI*r/(2*t),h=2*Math.PI*s/(2*t),l=-Math.PI/2,p=(l+=this.r.v,3===this.data.d?-1:1),m=this.v._length=0;m<t;m+=1){var f=i?a:n,c=i?o:h,d=(u=i?r:s)*Math.cos(l),u=u*Math.sin(l),y=0==d&&0==u?0:u/Math.sqrt(d*d+u*u),g=0==d&&0==u?0:-d/Math.sqrt(d*d+u*u);d+=+this.p.v[0],u+=+this.p.v[1],this.v.setTripleAt(d,u,d-y*c*f*p,u-g*c*f*p,d+y*c*f*p,u+g*c*f*p,m,!0),i=!i,l+=e*p}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),i=2*Math.PI/e,r=this.or.v,s=this.os.v,a=2*Math.PI*r/(4*e),n=.5*-Math.PI,o=3===this.data.d?-1:1;for(n+=this.r.v,t=this.v._length=0;t<e;t+=1){var h=r*Math.cos(n),l=r*Math.sin(n),p=0==h&&0==l?0:l/Math.sqrt(h*h+l*l),m=0==h&&0==l?0:-h/Math.sqrt(h*h+l*l);h+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(h,l,h-p*a*s*o,l-m*a*s*o,h+p*a*s*o,l+m*a*s*o,t,!0),n+=i*o}this.paths.length=0,this.paths[0]=this.v}},extendPrototype([DynamicPropertyContainer],f);var m=f;function f(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=PropertyFactory.getProp(t,e.ir,0,0,this),this.is=PropertyFactory.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=PropertyFactory.getProp(t,e.pt,0,0,this),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,degToRads,this),this.or=PropertyFactory.getProp(t,e.or,0,0,this),this.os=PropertyFactory.getProp(t,e.os,0,.01,this),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}d.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,r=this.s.v[1]/2,s=bmMin(i,r,this.r.v),a=s*(1-roundCorner);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+s,t+i,e-r+a,0,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-a,t+i,e+r-s,1,!0),0!==s?(this.v.setTripleAt(t+i-s,e+r,t+i-s,e+r,t+i-a,e+r,2,!0),this.v.setTripleAt(t-i+s,e+r,t-i+a,e+r,t-i+s,e+r,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-s,t-i,e+r-a,4,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+a,t-i,e-r+s,5,!0),this.v.setTripleAt(t-i+s,e-r,t-i+s,e-r,t-i+a,e-r,6,!0),this.v.setTripleAt(t+i-s,e-r,t+i-a,e-r,t+i-s,e-r,7,!0)):(this.v.setTripleAt(t-i,e+r,t-i+a,e+r,t-i,e+r,2),this.v.setTripleAt(t-i,e-r,t-i,e-r+a,t-i,e-r,3))):(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+a,t+i,e-r+s,0,!0),0!==s?(this.v.setTripleAt(t+i-s,e-r,t+i-s,e-r,t+i-a,e-r,1,!0),this.v.setTripleAt(t-i+s,e-r,t-i+a,e-r,t-i+s,e-r,2,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+s,t-i,e-r+a,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-a,t-i,e+r-s,4,!0),this.v.setTripleAt(t-i+s,e+r,t-i+s,e+r,t-i+a,e+r,5,!0),this.v.setTripleAt(t+i-s,e+r,t+i-a,e+r,t+i-s,e+r,6,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-s,t+i,e+r-a,7,!0)):(this.v.setTripleAt(t-i,e-r,t-i+a,e-r,t-i,e-r,1,!0),this.v.setTripleAt(t-i,e+r,t-i,e+r-a,t-i,e+r,2,!0),this.v.setTripleAt(t+i,e+r,t+i-a,e+r,t+i,e+r,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf)&&this.convertRectToPath()},reset:r},extendPrototype([DynamicPropertyContainer],d);var c=d;function d(t,e){this.v=shapePool.newElement(),this.v.c=!0,this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}var u={getShapeProp:function(t,e,i){var r;return 3===i||4===i?r=new((3===i?e.pt:e.ks).k.length?o:a)(t,e,i):5===i?r=new c(t,e):6===i?r=new l(t,e):7===i&&(r=new m(t,e)),r.k&&t.addDynamicProperty(r),r},getConstructorFunction:function(){return a},getKeyframedConstructorFunction:function(){return o}};return u})(),Matrix=(()=>{var r=Math.cos,s=Math.sin,a=Math.tan,n=Math.round;function t(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function e(t){var e;return 0===t?this:(e=r(t),t=s(t),this._t(e,-t,0,0,t,e,0,0,0,0,1,0,0,0,0,1))}function i(t){var e;return 0===t?this:(e=r(t),t=s(t),this._t(1,0,0,0,0,e,-t,0,0,t,e,0,0,0,0,1))}function o(t){var e;return 0===t?this:(e=r(t),t=s(t),this._t(e,0,t,0,0,1,0,0,-t,0,e,0,0,0,0,1))}function h(t){var e;return 0===t?this:(e=r(t),t=s(t),this._t(e,-t,0,0,t,e,0,0,0,0,1,0,0,0,0,1))}function l(t,e){return this._t(1,e,t,1,0,0)}function p(t,e){return this.shear(a(t),a(e))}function m(t,e){var i=r(e),e=s(e);return this._t(i,e,0,0,-e,i,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,a(t),1,0,0,0,0,1,0,0,0,0,1)._t(i,-e,0,0,e,i,0,0,0,0,1,0,0,0,0,1)}function f(t,e,i){return i||0===i||(i=1),1===t&&1===e&&1===i?this:this._t(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1)}function c(t,e,i,r,s,a,n,o,h,l,p,m,f,c,d,u){return this.props[0]=t,this.props[1]=e,this.props[2]=i,this.props[3]=r,this.props[4]=s,this.props[5]=a,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=l,this.props[10]=p,this.props[11]=m,this.props[12]=f,this.props[13]=c,this.props[14]=d,this.props[15]=u,this}function d(t,e,i){return i=i||0,0!==t||0!==e||0!==i?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,i,1):this}function u(t,e,i,r,s,a,n,o,h,l,p,m,f,c,d,u){var y,g,v,b,x,P,E,S,C,_,A,T,M,k,D,F,w=this.props;return 1===t&&0===e&&0===i&&0===r&&0===s&&1===a&&0===n&&0===o&&0===h&&0===l&&1===p&&0===m?(w[12]=w[12]*t+w[15]*f,w[13]=w[13]*a+w[15]*c,w[14]=w[14]*p+w[15]*d,w[15]*=u,this._identityCalculated=!1):(y=w[0],x=w[4],P=w[5],E=w[6],S=w[7],C=w[8],_=w[9],A=w[10],T=w[11],M=w[12],k=w[13],D=w[14],F=w[15],w[0]=y*t+(g=w[1])*s+(v=w[2])*h+(b=w[3])*f,w[1]=y*e+g*a+v*l+b*c,w[2]=y*i+g*n+v*p+b*d,w[3]=y*r+g*o+v*m+b*u,w[4]=x*t+P*s+E*h+S*f,w[5]=x*e+P*a+E*l+S*c,w[6]=x*i+P*n+E*p+S*d,w[7]=x*r+P*o+E*m+S*u,w[8]=C*t+_*s+A*h+T*f,w[9]=C*e+_*a+A*l+T*c,w[10]=C*i+_*n+A*p+T*d,w[11]=C*r+_*o+A*m+T*u,w[12]=M*t+k*s+D*h+F*f,w[13]=M*e+k*a+D*l+F*c,w[14]=M*i+k*n+D*p+F*d,w[15]=M*r+k*o+D*m+F*u,this._identityCalculated=!1),this}function y(t){t=t.props;return this.transform(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])}function g(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function v(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function b(t){for(var e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function x(t){for(var e=0;e<16;e+=1)this.props[e]=t[e]}function P(t,e,i){return{x:t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}}function E(t,e,i){return t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12]}function S(t,e,i){return t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13]}function C(t,e,i){return t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}function _(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,i=-this.props[1]/t,r=-this.props[4]/t,s=this.props[0]/t,a=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,t=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,n=new Matrix;return n.props[0]=e,n.props[1]=i,n.props[4]=r,n.props[5]=s,n.props[12]=a,n.props[13]=t,n}function A(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function T(t){for(var e=t.length,i=[],r=0;r<e;r+=1)i[r]=A(t[r]);return i}function M(t,e,i){var r,s,a,n,o,h,l=createTypedArray("float32",6);return this.isIdentity()?(l[0]=t[0],l[1]=t[1],l[2]=e[0],l[3]=e[1],l[4]=i[0],l[5]=i[1]):(r=this.props[0],s=this.props[1],a=this.props[4],n=this.props[5],o=this.props[12],h=this.props[13],l[0]=t[0]*r+t[1]*a+o,l[1]=t[0]*s+t[1]*n+h,l[2]=e[0]*r+e[1]*a+o,l[3]=e[0]*s+e[1]*n+h,l[4]=i[0]*r+i[1]*a+o,l[5]=i[0]*s+i[1]*n+h),l}function k(t,e,i){t=this.isIdentity()?[t,e,i]:[t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]];return t}function D(t,e){var i;return this.isIdentity()?t+","+e:(i=this.props,Math.round(100*(t*i[0]+e*i[4]+i[12]))/100+","+Math.round(100*(t*i[1]+e*i[5]+i[13]))/100)}function F(){for(var t=0,e=this.props,i="matrix3d(";t<16;)i=i+n(1e4*e[t])/1e4+(15===t?")":","),t+=1;return i}function w(t){return t<1e-6&&0<t||-1e-6<t&&t<0?n(1e4*t)/1e4:t}function I(){var t=this.props;return"matrix("+w(t[0])+","+w(t[1])+","+w(t[4])+","+w(t[5])+","+w(t[12])+","+w(t[13])+")"}return function(){this.reset=t,this.rotate=e,this.rotateX=i,this.rotateY=o,this.rotateZ=h,this.skew=p,this.skewFromAxis=m,this.shear=l,this.scale=f,this.setTransform=c,this.translate=d,this.transform=u,this.multiply=y,this.applyToPoint=P,this.applyToX=E,this.applyToY=S,this.applyToZ=C,this.applyToPointArray=k,this.applyToTriplePoints=M,this.applyToPointStringified=D,this.toCSS=F,this.to2dCSS=I,this.clone=b,this.cloneFromProps=x,this.equals=v,this.inversePoints=T,this.inversePoint=A,this.getInverseMatrix=_,this._t=this.transform,this.isIdentity=g,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}})();function _typeof$3(t){return(_typeof$3="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var lottie={},standalone="__[STANDALONE]__",animationData="__[ANIMATIONDATA]__",renderer="";function setLocation(t){setLocationHref(t)}function searchAnimations(){!0===standalone?animationManager.searchAnimations(animationData,standalone,renderer):animationManager.searchAnimations()}function setSubframeRendering(t){setSubframeEnabled(t)}function setPrefix(t){setIdPrefix(t)}function loadAnimation(t){return!0===standalone&&(t.animationData=JSON.parse(animationData)),animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":setDefaultCurveSegments(200);break;default:case"medium":setDefaultCurveSegments(50);break;case"low":setDefaultCurveSegments(10)}else!isNaN(t)&&1<t&&setDefaultCurveSegments(t);50<=getDefaultCurveSegments()?roundValues(!1):roundValues(!0)}function inBrowser(){return"undefined"!=typeof navigator}function installPlugin(t,e){"expressions"===t&&setExpressionsPlugin(e)}function getFactory(t){switch(t){case"propertyFactory":return PropertyFactory;case"shapePropertyFactory":return ShapePropertyFactory;case"matrix":return Matrix;default:return null}}function checkReady(){"complete"===document.readyState&&(clearInterval(readyStateCheckInterval),searchAnimations())}function getQueryVariable(t){for(var e=queryString.split("&"),i=0;i<e.length;i+=1){var r=e[i].split("=");if(decodeURIComponent(r[0])==t)return decodeURIComponent(r[1])}return null}lottie.play=animationManager.play,lottie.pause=animationManager.pause,lottie.setLocationHref=setLocation,lottie.togglePause=animationManager.togglePause,lottie.setSpeed=animationManager.setSpeed,lottie.setDirection=animationManager.setDirection,lottie.stop=animationManager.stop,lottie.searchAnimations=searchAnimations,lottie.registerAnimation=animationManager.registerAnimation,lottie.loadAnimation=loadAnimation,lottie.setSubframeRendering=setSubframeRendering,lottie.resize=animationManager.resize,lottie.goToAndStop=animationManager.goToAndStop,lottie.destroy=animationManager.destroy,lottie.setQuality=setQuality,lottie.inBrowser=inBrowser,lottie.installPlugin=installPlugin,lottie.freeze=animationManager.freeze,lottie.unfreeze=animationManager.unfreeze,lottie.setVolume=animationManager.setVolume,lottie.mute=animationManager.mute,lottie.unmute=animationManager.unmute,lottie.getRegisteredAnimations=animationManager.getRegisteredAnimations,lottie.useWebWorker=setWebWorker,lottie.setIDPrefix=setPrefix,lottie.__getFactory=getFactory,lottie.version="5.13.0";var queryString="",scripts,index,myScript,queryString,renderer,readyStateCheckInterval=(standalone&&(scripts=document.getElementsByTagName("script"),index=scripts.length-1,myScript=scripts[index]||{src:""},queryString=myScript.src?myScript.src.replace(/^[^\?]+\??/,""):"",renderer=getQueryVariable("renderer")),setInterval(checkReady,100));try{"object"===("undefined"==typeof exports?"undefined":_typeof$3(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=lottie)}catch(err){}var ShapeModifiers=(()=>{var t={},r={};return t.registerModifier=function(t,e){r[t]||(r[t]=e)},t.getModifier=function(t,e,i){return new r[t](e,i)},t})();function ShapeModifier(){}function TrimModifier(){}function PuckerAndBloatModifier(){}ShapeModifier.prototype.initModifierProperties=function(){},ShapeModifier.prototype.addShapeToModifier=function(){},ShapeModifier.prototype.addShape=function(t){var e;this.closed||(t.sh.container.addDynamicProperty(t.sh),e={shape:t.sh,data:t,localShapeCollection:shapeCollectionPool.newShapeCollection()},this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated())},ShapeModifier.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=initialDefaultFrame,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},ShapeModifier.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},extendPrototype([DynamicPropertyContainer],ShapeModifier),extendPrototype([ShapeModifier],TrimModifier),TrimModifier.prototype.initModifierProperties=function(t,e){this.s=PropertyFactory.getProp(t,e.s,0,.01,this),this.e=PropertyFactory.getProp(t,e.e,0,.01,this),this.o=PropertyFactory.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},TrimModifier.prototype.addShapeToModifier=function(t){t.pathsData=[]},TrimModifier.prototype.calculateShapeEdges=function(t,e,i,r,s){for(var a,n,o=[],h=(e<=1?o.push({s:t,e:e}):1<=t?o.push({s:t-1,e:e-1}):(o.push({s:t,e:1}),o.push({s:0,e:e-1})),[]),l=o.length,p=0;p<l;p+=1)(n=o[p]).e*s<r||n.s*s>r+i||(a=n.s*s<=r?0:(n.s*s-r)/i,n=n.e*s>=r+i?1:(n.e*s-r)/i,h.push([a,n]));return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){for(var e=t.length,i=0;i<e;i+=1)segmentsLengthPool.release(t[i]);return t.length=0,t},TrimModifier.prototype.processShapes=function(t){this._mdf||t?((e=this.o.v%360/360)<0&&(e+=1),i=1<this.s.v?1+e:this.s.v<0?0+e:this.s.v+e,(r=1<this.e.v?1+e:this.e.v<0?0+e:this.e.v+e)<i&&(e=i,i=r,r=e),i=1e-4*Math.round(1e4*i),r=1e-4*Math.round(1e4*r),this.sValue=i,this.eValue=r):(i=this.sValue,r=this.eValue);var e,i,r,s,a,n,o,h,l,p=this.shapes.length,m=0;if(r===i)for(u=0;u<p;u+=1)this.shapes[u].localShapeCollection.releaseShapes(),this.shapes[u].shape._mdf=!0,this.shapes[u].shape.paths=this.shapes[u].localShapeCollection,this._mdf&&(this.shapes[u].pathsData.length=0);else if(1===r&&0===i||0===r&&1===i){if(this._mdf)for(u=0;u<p;u+=1)this.shapes[u].pathsData.length=0,this.shapes[u].shape._mdf=!0}else{for(var f,c,d=[],u=0;u<p;u+=1)if((f=this.shapes[u]).shape._mdf||this._mdf||t||2===this.m){if(n=(s=f.shape.paths)._length,l=0,!f.shape._mdf&&f.pathsData.length)l=f.totalShapeLength;else{for(o=this.releasePathsData(f.pathsData),a=0;a<n;a+=1)h=bez.getSegmentsLength(s.shapes[a]),o.push(h),l+=h.totalLength;f.totalShapeLength=l,f.pathsData=o}m+=l,f.shape._mdf=!0}else f.shape.paths=f.localShapeCollection;var y,g=i,v=r,b=0;for(u=p-1;0<=u;--u)if((f=this.shapes[u]).shape._mdf){for((c=f.localShapeCollection).releaseShapes(),2===this.m&&1<p?(y=this.calculateShapeEdges(i,r,f.totalShapeLength,b,m),b+=f.totalShapeLength):y=[[g,v]],n=y.length,a=0;a<n;a+=1){g=y[a][0],v=y[a][1],d.length=0,v<=1?d.push({s:f.totalShapeLength*g,e:f.totalShapeLength*v}):1<=g?d.push({s:f.totalShapeLength*(g-1),e:f.totalShapeLength*(v-1)}):(d.push({s:f.totalShapeLength*g,e:f.totalShapeLength}),d.push({s:0,e:f.totalShapeLength*(v-1)}));var x,P=this.addShapes(f,d[0]);d[0].s!==d[0].e&&(1<d.length&&(P=f.shape.paths.shapes[f.shape.paths._length-1].c?(x=P.pop(),this.addPaths(P,c),this.addShapes(f,d[1],x)):(this.addPaths(P,c),this.addShapes(f,d[1]))),this.addPaths(P,c))}f.shape.paths=c}}},TrimModifier.prototype.addPaths=function(t,e){for(var i=t.length,r=0;r<i;r+=1)e.addShape(t[r])},TrimModifier.prototype.addSegment=function(t,e,i,r,s,a,n){s.setXYAt(e[0],e[1],"o",a),s.setXYAt(i[0],i[1],"i",a+1),n&&s.setXYAt(t[0],t[1],"v",a),s.setXYAt(r[0],r[1],"v",a+1)},TrimModifier.prototype.addSegmentFromArray=function(t,e,i,r){e.setXYAt(t[1],t[5],"o",i),e.setXYAt(t[2],t[6],"i",i+1),r&&e.setXYAt(t[0],t[4],"v",i),e.setXYAt(t[3],t[7],"v",i+1)},TrimModifier.prototype.addShapes=function(t,e,i){var r,s,a,n,o,h,l,p,m=t.pathsData,f=t.shape.paths.shapes,c=t.shape.paths._length,d=0,u=[],y=!0,g=i?(n=i._length,i._length):(i=shapePool.newElement(),n=0);for(u.push(i),r=0;r<c;r+=1){for(o=m[r].lengths,i.c=f[r].c,a=f[r].c?o.length:o.length+1,s=1;s<a;s+=1)if(d+(p=o[s-1]).addedLength<e.s)d+=p.addedLength,i.c=!1;else{if(d>e.e){i.c=!1;break}e.s<=d&&e.e>=d+p.addedLength?(this.addSegment(f[r].v[s-1],f[r].o[s-1],f[r].i[s],f[r].v[s],i,n,y),y=!1):(h=bez.getNewSegment(f[r].v[s-1],f[r].v[s],f[r].o[s-1],f[r].i[s],(e.s-d)/p.addedLength,(e.e-d)/p.addedLength,o[s-1]),this.addSegmentFromArray(h,i,n,y),i.c=y=!1),d+=p.addedLength,n+=1}if(f[r].c&&o.length&&(p=o[s-1],d<=e.e?(l=o[s-1].addedLength,e.s<=d&&e.e>=d+l?(this.addSegment(f[r].v[s-1],f[r].o[s-1],f[r].i[0],f[r].v[0],i,n,y),y=!1):(h=bez.getNewSegment(f[r].v[s-1],f[r].v[0],f[r].o[s-1],f[r].i[0],(e.s-d)/l,(e.e-d)/l,o[s-1]),this.addSegmentFromArray(h,i,n,y),i.c=y=!1)):i.c=!1,d+=p.addedLength,n+=1),i._length&&(i.setXYAt(i.v[g][0],i.v[g][1],"i",g),i.setXYAt(i.v[i._length-1][0],i.v[i._length-1][1],"o",i._length-1)),d>e.e)break;r<c-1&&(i=shapePool.newElement(),y=!0,u.push(i),n=0)}return u},extendPrototype([ShapeModifier],PuckerAndBloatModifier),PuckerAndBloatModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},PuckerAndBloatModifier.prototype.processPath=function(t,e){for(var i=e/100,r=[0,0],s=t._length,a=0,a=0;a<s;a+=1)r[0]+=t.v[a][0],r[1]+=t.v[a][1];r[0]/=s,r[1]/=s;var n,o,h,l,p,m,f=shapePool.newElement();for(f.c=t.c,a=0;a<s;a+=1)n=t.v[a][0]+(r[0]-t.v[a][0])*i,o=t.v[a][1]+(r[1]-t.v[a][1])*i,h=t.o[a][0]+(r[0]-t.o[a][0])*-i,l=t.o[a][1]+(r[1]-t.o[a][1])*-i,p=t.i[a][0]+(r[0]-t.i[a][0])*-i,m=t.i[a][1]+(r[1]-t.i[a][1])*-i,f.setTripleAt(n,o,h,l,p,m,a);return f},PuckerAndBloatModifier.prototype.processShapes=function(t){var e,i,r,s=this.shapes.length,a=this.amount.v;if(0!==a)for(var n,o,h=0;h<s;h+=1){if(o=(n=this.shapes[h]).localShapeCollection,n.shape._mdf||this._mdf||t)for(o.releaseShapes(),n.shape._mdf=!0,e=n.shape.paths.shapes,r=n.shape.paths._length,i=0;i<r;i+=1)o.addShape(this.processPath(e[i],a));n.shape.paths=n.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var TransformPropertyFactory=(()=>{var a=[0,0];function r(t,e,i){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Matrix,this.pre=new Matrix,this.appliedTransformations=0,this.initDynamicPropertyContainer(i||t),e.p&&e.p.s?(this.px=PropertyFactory.getProp(t,e.p.x,0,0,this),this.py=PropertyFactory.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=PropertyFactory.getProp(t,e.p.z,0,0,this))):this.p=PropertyFactory.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=PropertyFactory.getProp(t,e.rx,0,degToRads,this),this.ry=PropertyFactory.getProp(t,e.ry,0,degToRads,this),this.rz=PropertyFactory.getProp(t,e.rz,0,degToRads,this),e.or.k[0].ti)for(var r=e.or.k.length,s=0;s<r;s+=1)e.or.k[s].to=null,e.or.k[s].ti=null;this.or=PropertyFactory.getProp(t,e.or,1,degToRads,this),this.or.sh=!0}else this.r=PropertyFactory.getProp(t,e.r||{k:0},0,degToRads,this);e.sk&&(this.sk=PropertyFactory.getProp(t,e.sk,0,degToRads,this),this.sa=PropertyFactory.getProp(t,e.sa,0,degToRads,this)),this.a=PropertyFactory.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=PropertyFactory.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=PropertyFactory.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return r.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(t){var e,i,r,s;this.elem.globalData.frameId!==this.frameId&&(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),(this._mdf||t)&&(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented&&(t=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime?i=this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(e=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/t,0),this.p.getValueAtTime(this.p.keyframes[0].t/t,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(e=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/t,0),this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/t,0)):(e=this.p.pv,this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/t,this.p.offsetTime)):this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime?(e=[],i=[],r=this.px,s=this.py,r._caching.lastFrame+r.offsetTime<=r.keyframes[0].t?(e[0]=r.getValueAtTime((r.keyframes[0].t+.01)/t,0),e[1]=s.getValueAtTime((s.keyframes[0].t+.01)/t,0),i[0]=r.getValueAtTime(r.keyframes[0].t/t,0),i[1]=s.getValueAtTime(s.keyframes[0].t/t,0)):r._caching.lastFrame+r.offsetTime>=r.keyframes[r.keyframes.length-1].t?(e[0]=r.getValueAtTime(r.keyframes[r.keyframes.length-1].t/t,0),e[1]=s.getValueAtTime(s.keyframes[s.keyframes.length-1].t/t,0),i[0]=r.getValueAtTime((r.keyframes[r.keyframes.length-1].t-.01)/t,0),i[1]=s.getValueAtTime((s.keyframes[s.keyframes.length-1].t-.01)/t,0)):(e=[r.pv,s.pv],i[0]=r.getValueAtTime((r._caching.lastFrame+r.offsetTime-.01)/t,r.offsetTime),i[1]=s.getValueAtTime((s._caching.lastFrame+s.offsetTime-.01)/t,s.offsetTime))):e=i=a,this.v.rotate(-Math.atan2(e[1]-i[1],e[0]-i[0]))),this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])),this.frameId=this.elem.globalData.frameId)},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],r),r.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},r.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,e,i){return new r(t,e,i)}}})();function RepeaterModifier(){}function RoundCornersModifier(){}function floatEqual(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function floatZero(t){return Math.abs(t)<=1e-5}function lerp(t,e,i){return t*(1-i)+e*i}function lerpPoint(t,e,i){return[lerp(t[0],e[0],i),lerp(t[1],e[1],i)]}function quadRoots(t,e,i){return 0===t||(i=e*e-4*t*i)<0?[]:(e=-e/(2*t),0==i?[e]:[e-(i=Math.sqrt(i)/(2*t)),e+i])}function polynomialCoefficients(t,e,i,r){return[3*e-t-3*i+r,3*t-6*e+3*i,-3*t+3*e,t]}function singlePoint(t){return new PolynomialBezier(t,t,t,t,!1)}function PolynomialBezier(t,e,i,r,s){s&&pointEqual(t,e)&&(e=lerpPoint(t,r,1/3)),s&&pointEqual(i,r)&&(i=lerpPoint(t,r,2/3));var s=polynomialCoefficients(t[0],e[0],i[0],r[0]),a=polynomialCoefficients(t[1],e[1],i[1],r[1]);this.a=[s[0],a[0]],this.b=[s[1],a[1]],this.c=[s[2],a[2]],this.d=[s[3],a[3]],this.points=[t,e,i,r]}function extrema(t,e){for(var i,r,s=t.points[0][e],a=t.points[t.points.length-1][e],n=(a<s&&(i=a,a=s,s=i),quadRoots(3*t.a[e],2*t.b[e],t.c[e])),o=0;o<n.length;o+=1)0<n[o]&&n[o]<1&&((r=t.point(n[o])[e])<s?s=r:a<r&&(a=r));return{min:s,max:a}}function intersectData(t,e,i){var r=t.boundingBox();return{cx:r.cx,cy:r.cy,width:r.width,height:r.height,bez:t,t:(e+i)/2,t1:e,t2:i}}function splitData(t){var e=t.bez.split(.5);return[intersectData(e[0],t.t1,t.t),intersectData(e[1],t.t,t.t2)]}function boxIntersect(t,e){return 2*Math.abs(t.cx-e.cx)<t.width+e.width&&2*Math.abs(t.cy-e.cy)<t.height+e.height}function intersectsImpl(t,e,i,r,s,a){boxIntersect(t,e)&&(a<=i||t.width<=r&&t.height<=r&&e.width<=r&&e.height<=r?s.push([t.t,e.t]):(t=splitData(t),e=splitData(e),intersectsImpl(t[0],e[0],i+1,r,s,a),intersectsImpl(t[0],e[1],i+1,r,s,a),intersectsImpl(t[1],e[0],i+1,r,s,a),intersectsImpl(t[1],e[1],i+1,r,s,a)))}function crossProduct(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function lineIntersection(t,e,i,r){t=[t[0],t[1],1],e=[e[0],e[1],1],i=[i[0],i[1],1],r=[r[0],r[1],1],t=crossProduct(crossProduct(t,e),crossProduct(i,r));return floatZero(t[2])?null:[t[0]/t[2],t[1]/t[2]]}function polarOffset(t,e,i){return[t[0]+Math.cos(e)*i,t[1]-Math.sin(e)*i]}function pointDistance(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function pointEqual(t,e){return floatEqual(t[0],e[0])&&floatEqual(t[1],e[1])}function ZigZagModifier(){}function setPoint(t,e,i,r,s,a,n){var o=i-Math.PI/2,h=i+Math.PI/2,l=e[0]+Math.cos(i)*r*s,e=e[1]-Math.sin(i)*r*s;t.setTripleAt(l,e,l+Math.cos(o)*a,e-Math.sin(o)*a,l+Math.cos(h)*n,e-Math.sin(h)*n,t.length())}function getPerpendicularVector(t,e){e=[e[0]-t[0],e[1]-t[1]],t=.5*-Math.PI;return[Math.cos(t)*e[0]-Math.sin(t)*e[1],Math.sin(t)*e[0]+Math.cos(t)*e[1]]}function getProjectingAngle(t,e){var i=0===e?t.length()-1:e-1,e=(e+1)%t.length(),i=getPerpendicularVector(t.v[i],t.v[e]);return Math.atan2(0,1)-Math.atan2(i[1],i[0])}function zigZagCorner(t,e,i,r,s,a,n){var o=getProjectingAngle(e,i),h=e.v[i%e._length],l=e.v[0===i?e._length-1:i-1],p=e.v[(i+1)%e._length],l=2===a?Math.sqrt(Math.pow(h[0]-l[0],2)+Math.pow(h[1]-l[1],2)):0,h=2===a?Math.sqrt(Math.pow(h[0]-p[0],2)+Math.pow(h[1]-p[1],2)):0;setPoint(t,e.v[i%e._length],o,n,r,h/(2*(s+1)),l/(2*(s+1)),a)}function zigZagSegment(t,e,i,r,s,a){for(var n=0;n<r;n+=1){var o=(n+1)/(r+1),h=2===s?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(o);setPoint(t,e.point(o),l,a,i,h/(2*(r+1)),h/(2*(r+1)),s),a=-a}return a}function linearOffset(t,e,i){var r=Math.atan2(e[0]-t[0],e[1]-t[1]);return[polarOffset(t,r,i),polarOffset(e,r,i)]}function offsetSegment(t,e){var i=linearOffset(t.points[0],t.points[1],e),r=i[0],s=i[1],a=(i=linearOffset(t.points[1],t.points[2],e))[0],n=i[1],t=(i=linearOffset(t.points[2],t.points[3],e))[0],e=i[1],i=lineIntersection(r,s,a,n),s=(null===i&&(i=s),lineIntersection(t,e,a,n));return new PolynomialBezier(r,i,s=null===s?t:s,e)}function joinLines(t,e,i,r,s){var a,n,o=e.points[3],h=i.points[0];return 3===r||pointEqual(o,h)?o:2===r?(r=-e.tangentAngle(1),n=-i.tangentAngle(0)+Math.PI,a=lineIntersection(o,polarOffset(o,r+Math.PI/2,100),h,polarOffset(h,r+Math.PI/2,100)),a=polarOffset(o,r,2*(r=a?pointDistance(a,o):pointDistance(o,h)/2)*roundCorner),t.setXYAt(a[0],a[1],"o",t.length()-1),a=polarOffset(h,n,2*r*roundCorner),t.setTripleAt(h[0],h[1],h[0],h[1],a[0],a[1],t.length()),h):(n=lineIntersection(pointEqual(o,e.points[2])?e.points[0]:e.points[2],o,h,pointEqual(h,i.points[1])?i.points[3]:i.points[1]))&&pointDistance(n,o)<s?(t.setTripleAt(n[0],n[1],n[0],n[1],n[0],n[1],t.length()),n):o}function getIntersection(t,e){t=t.intersections(e);return t.length&&floatEqual(t[0][0],1)&&t.shift(),t.length?t[0]:null}function pruneSegmentIntersection(t,e){var i=t.slice(),r=e.slice(),s=getIntersection(t[t.length-1],e[0]);return s&&(i[t.length-1]=t[t.length-1].split(s[0])[0],r[0]=e[0].split(s[1])[1]),1<t.length&&1<e.length&&(s=getIntersection(t[0],e[e.length-1]))?[[t[0].split(s[0])[0]],[e[e.length-1].split(s[1])[1]]]:[i,r]}function pruneIntersections(t){for(var e,i=1;i<t.length;i+=1)e=pruneSegmentIntersection(t[i-1],t[i]),t[i-1]=e[0],t[i]=e[1];return 1<t.length&&(e=pruneSegmentIntersection(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}function offsetSegmentSplit(t,e){var i,r,s,a=t.inflectionPoints();return 0===a.length?[offsetSegment(t,e)]:1===a.length||floatEqual(a[1],1)?(r=(i=t.split(a[0]))[0],s=i[1],[offsetSegment(r,e),offsetSegment(s,e)]):(r=(i=t.split(a[0]))[0],t=(a[1]-a[0])/(1-a[0]),a=(i=i[1].split(t))[0],s=i[1],[offsetSegment(r,e),offsetSegment(a,e),offsetSegment(s,e)])}function OffsetPathModifier(){}function getFontProperties(t){for(var e=t.fStyle?t.fStyle.split(" "):[],i="normal",r="normal",s=e.length,a=0;a<s;a+=1)switch(e[a].toLowerCase()){case"italic":r="italic";break;case"bold":i="700";break;case"black":i="900";break;case"medium":i="500";break;case"regular":case"normal":i="400";break;case"light":case"thin":i="200"}return{style:r,weight:t.fWeight||i}}extendPrototype([ShapeModifier],RepeaterModifier),RepeaterModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=PropertyFactory.getProp(t,e.c,0,null,this),this.o=PropertyFactory.getProp(t,e.o,0,null,this),this.tr=TransformPropertyFactory.getTransformProperty(t,e.tr,this),this.so=PropertyFactory.getProp(t,e.tr.so,0,.01,this),this.eo=PropertyFactory.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Matrix,this.rMatrix=new Matrix,this.sMatrix=new Matrix,this.tMatrix=new Matrix,this.matrix=new Matrix},RepeaterModifier.prototype.applyTransforms=function(t,e,i,r,s,a){var n=a?-1:1,o=r.s.v[0]+(1-r.s.v[0])*(1-s),h=r.s.v[1]+(1-r.s.v[1])*(1-s);t.translate(r.p.v[0]*n*s,r.p.v[1]*n*s,r.p.v[2]),e.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),e.rotate(-r.r.v*n*s),e.translate(r.a.v[0],r.a.v[1],r.a.v[2]),i.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),i.scale(a?1/o:o,a?1/h:h),i.translate(r.a.v[0],r.a.v[1],r.a.v[2])},RepeaterModifier.prototype.init=function(t,e,i,r){for(this.elem=t,this.arr=e,this.pos=i,this.elemsData=r,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[i]);0<i;)this._elements.unshift(e[--i]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){for(var e=t.length,i=0;i<e;i+=1)t[i]._processed=!1,"gr"===t[i].ty&&this.resetElements(t[i].it)},RepeaterModifier.prototype.cloneElements=function(t){t=JSON.parse(JSON.stringify(t));return this.resetElements(t),t},RepeaterModifier.prototype.changeGroupRender=function(t,e){for(var i=t.length,r=0;r<i;r+=1)t[r]._render=e,"gr"===t[r].ty&&this.changeGroupRender(t[r].it,e)},RepeaterModifier.prototype.processShapes=function(t){var e,i,r,s,a,n=!1;if(this._mdf||t){var o,h=Math.ceil(this.c.v);if(this._groups.length<h){for(;this._groups.length<h;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(r=a=0;r<=this._groups.length-1;r+=1)this._groups[r]._render=o=a<h,this.changeGroupRender(this._groups[r].it,o),o||(0!==(o=(o=this.elemsData[r].it)[o.length-1]).transform.op.v?(o.transform.op._mdf=!0,o.transform.op.v=0):o.transform.op._mdf=!1),a+=1;this._currentCopies=h;var p,m,t=this.o.v,f=t%1,c=0<t?Math.floor(t):Math.ceil(t),d=this.pMatrix.props,u=this.rMatrix.props,y=this.sMatrix.props,g=(this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset(),0);if(0<t){for(;g<c;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),g+=1;f&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,f,!1),g+=f)}else if(t<0){for(;c<g;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),--g;f&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-f,!0),g-=f)}for(r=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(m=(i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(r/(this._currentCopies-1)),0!==g){for((0!==r&&1===s||r!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9],d[10],d[11],d[12],d[13],d[14],d[15]),p=0;p<m;p+=1)i[p]=this.matrix.props[p];this.matrix.reset()}else for(this.matrix.reset(),p=0;p<m;p+=1)i[p]=this.matrix.props[p];g+=1,--a,r+=s}}else for(a=this._currentCopies,r=0,s=1;a;)i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,--a,r+=s;return n},RepeaterModifier.prototype.addShape=function(){},extendPrototype([ShapeModifier],RoundCornersModifier),RoundCornersModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=PropertyFactory.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},RoundCornersModifier.prototype.processPath=function(t,e){for(var i,r,s,a,n,o,h,l,p,m,f=shapePool.newElement(),c=(f.c=t.c,t._length),d=0,u=0;u<c;u+=1)i=t.v[u],s=t.o[u],r=t.i[u],i[0]===s[0]&&i[1]===s[1]&&i[0]===r[0]&&i[1]===r[1]?0!==u&&u!==c-1||t.c?(a=0===u?t.v[c-1]:t.v[u-1],o=(n=Math.sqrt(Math.pow(i[0]-a[0],2)+Math.pow(i[1]-a[1],2)))?Math.min(n/2,e)/n:0,p=i[0]+(a[0]-i[0])*o,m=i[1]-(i[1]-a[1])*o,h=p-(p-i[0])*roundCorner,l=m-(m-i[1])*roundCorner,f.setTripleAt(p,m,h,l,p,m,d),d+=1,a=u===c-1?t.v[0]:t.v[u+1],o=(n=Math.sqrt(Math.pow(i[0]-a[0],2)+Math.pow(i[1]-a[1],2)))?Math.min(n/2,e)/n:0,h=i[0]+(a[0]-i[0])*o,l=i[1]+(a[1]-i[1])*o,p=h-(h-i[0])*roundCorner,m=l-(l-i[1])*roundCorner,f.setTripleAt(h,l,h,l,p,m,d)):f.setTripleAt(i[0],i[1],s[0],s[1],r[0],r[1],d):f.setTripleAt(t.v[u][0],t.v[u][1],t.o[u][0],t.o[u][1],t.i[u][0],t.i[u][1],d),d+=1;return f},RoundCornersModifier.prototype.processShapes=function(t){var e,i,r,s=this.shapes.length,a=this.rd.v;if(0!==a)for(var n,o,h=0;h<s;h+=1){if(o=(n=this.shapes[h]).localShapeCollection,n.shape._mdf||this._mdf||t)for(o.releaseShapes(),n.shape._mdf=!0,e=n.shape.paths.shapes,r=n.shape.paths._length,i=0;i<r;i+=1)o.addShape(this.processPath(e[i],a));n.shape.paths=n.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},PolynomialBezier.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},PolynomialBezier.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},PolynomialBezier.prototype.tangentAngle=function(t){t=this.derivative(t);return Math.atan2(t[1],t[0])},PolynomialBezier.prototype.normalAngle=function(t){t=this.derivative(t);return Math.atan2(t[0],t[1])},PolynomialBezier.prototype.inflectionPoints=function(){var t,e=this.a[1]*this.b[0]-this.a[0]*this.b[1];return floatZero(e)||(e=(t=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/e)*t-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/e)<0?[]:floatZero(e=Math.sqrt(e))?0<e&&e<1?[t]:[]:[t-e,t+e].filter(function(t){return 0<t&&t<1})},PolynomialBezier.prototype.split=function(t){var e,i,r,s;return t<=0?[singlePoint(this.points[0]),this]:1<=t?[this,singlePoint(this.points[this.points.length-1])]:(e=lerpPoint(this.points[0],this.points[1],t),s=lerpPoint(this.points[1],this.points[2],t),i=lerpPoint(this.points[2],this.points[3],t),r=lerpPoint(e,s,t),s=lerpPoint(s,i,t),t=lerpPoint(r,s,t),[new PolynomialBezier(this.points[0],e,r,t,!0),new PolynomialBezier(t,s,i,this.points[3],!0)])},PolynomialBezier.prototype.bounds=function(){return{x:extrema(this,0),y:extrema(this,1)}},PolynomialBezier.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},PolynomialBezier.prototype.intersections=function(t,e,i){void 0===e&&(e=2),void 0===i&&(i=7);var r=[];return intersectsImpl(intersectData(this,0,1),intersectData(t,0,1),0,e,r,i),r},PolynomialBezier.shapeSegment=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[e],t.o[e],t.i[i],t.v[i],!0)},PolynomialBezier.shapeSegmentInverted=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[i],t.i[i],t.o[e],t.v[e],!0)},extendPrototype([ShapeModifier],ZigZagModifier),ZigZagModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=PropertyFactory.getProp(t,e.s,0,null,this),this.frequency=PropertyFactory.getProp(t,e.r,0,null,this),this.pointsType=PropertyFactory.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},ZigZagModifier.prototype.processPath=function(t,e,i,r){var s=t._length,a=shapePool.newElement();if(a.c=t.c,t.c||--s,0!==s){var n=-1,o=PolynomialBezier.shapeSegment(t,0);zigZagCorner(a,t,0,e,i,r,n);for(var h=0;h<s;h+=1)n=zigZagSegment(a,o,e,i,r,-n),o=h!==s-1||t.c?PolynomialBezier.shapeSegment(t,(h+1)%s):null,zigZagCorner(a,t,h+1,e,i,r,n)}return a},ZigZagModifier.prototype.processShapes=function(t){var e,i,r,s=this.shapes.length,a=this.amplitude.v,n=Math.max(0,Math.round(this.frequency.v)),o=this.pointsType.v;if(0!==a)for(var h,l,p=0;p<s;p+=1){if(l=(h=this.shapes[p]).localShapeCollection,h.shape._mdf||this._mdf||t)for(l.releaseShapes(),h.shape._mdf=!0,e=h.shape.paths.shapes,r=h.shape.paths._length,i=0;i<r;i+=1)l.addShape(this.processPath(e[i],a,n,o));h.shape.paths=h.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},extendPrototype([ShapeModifier],OffsetPathModifier),OffsetPathModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this.miterLimit=PropertyFactory.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},OffsetPathModifier.prototype.processPath=function(t,e,i,r){for(var s,a,n=shapePool.newElement(),o=(n.c=t.c,t.length()),h=(t.c||--o,[]),l=0;l<o;l+=1)a=PolynomialBezier.shapeSegment(t,l),h.push(offsetSegmentSplit(a,e));if(!t.c)for(l=o-1;0<=l;--l)a=PolynomialBezier.shapeSegmentInverted(t,l),h.push(offsetSegmentSplit(a,e));var h=pruneIntersections(h),p=null,m=null;for(l=0;l<h.length;l+=1){var f=h[l];for(m&&(p=joinLines(n,m,f[0],i,r)),m=f[f.length-1],s=0;s<f.length;s+=1)a=f[s],p&&pointEqual(a.points[0],p)?n.setXYAt(a.points[1][0],a.points[1][1],"o",n.length()-1):n.setTripleAt(a.points[0][0],a.points[0][1],a.points[1][0],a.points[1][1],a.points[0][0],a.points[0][1],n.length()),n.setTripleAt(a.points[3][0],a.points[3][1],a.points[3][0],a.points[3][1],a.points[2][0],a.points[2][1],n.length()),p=a.points[3]}return h.length&&joinLines(n,m,h[0][0],i,r),n},OffsetPathModifier.prototype.processShapes=function(t){var e,i,r,s=this.shapes.length,a=this.amount.v,n=this.miterLimit.v,o=this.lineJoin;if(0!==a)for(var h,l,p=0;p<s;p+=1){if(l=(h=this.shapes[p]).localShapeCollection,h.shape._mdf||this._mdf||t)for(l.releaseShapes(),h.shape._mdf=!0,e=h.shape.paths.shapes,r=h.shape.paths._length,i=0;i<r;i+=1)l.addShape(this.processPath(e[i],a,o,n));h.shape.paths=h.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var FontManager=(()=>{var a=5e3,n={w:0,size:0,shapes:[],data:{shapes:[]}},e=(e=[]).concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]),s=127988,o=917631,h=917601,l=917626,i=65039,r=8205,p=127462,m=127487,f=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function c(t,e){var i=createTag("span"),r=(i.setAttribute("aria-hidden",!0),i.style.fontFamily=e,createTag("span")),s=(r.innerText="giItT1WQy@!-/#",i.style.position="absolute",i.style.left="-10000px",i.style.top="-10000px",i.style.fontSize="300px",i.style.fontVariant="normal",i.style.fontStyle="normal",i.style.fontWeight="normal",i.style.letterSpacing="0",i.appendChild(r),document.body.appendChild(i),r.offsetWidth);return r.style.fontFamily=(t=>{for(var e=t.split(","),i=e.length,r=[],s=0;s<i;s+=1)"sans-serif"!==e[s]&&"monospace"!==e[s]&&r.push(e[s]);return r.join(",")})(t)+", "+e,{node:r,w:s,parent:i}}function d(t,e){var i,r,s=document.body&&e?"svg":"canvas",a=getFontProperties(t);return i="svg"==s?((r=createNS("text")).style.fontSize="100px",r.setAttribute("font-family",t.fFamily),r.setAttribute("font-style",a.style),r.setAttribute("font-weight",a.weight),r.textContent="1",t.fClass?(r.style.fontFamily="inherit",r.setAttribute("class",t.fClass)):r.style.fontFamily=t.fFamily,e.appendChild(r),r):((e=new OffscreenCanvas(500,500).getContext("2d")).font=a.style+" "+a.weight+" 100px "+t.fFamily,e),{measureText:function(t){return"svg"==s?(i.textContent=t,i.getComputedTextLength()):i.measureText(t).width}}}function u(t){var e=0,i=t.charCodeAt(0);return e=55296<=i&&i<=56319&&56320<=(t=t.charCodeAt(1))&&t<=57343?1024*(i-55296)+t-56320+65536:e}function y(t){t=u(t);return p<=t&&t<=m}function t(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)}return t.isModifier=function(t,e){return t=t.toString(16)+e.toString(16),-1!==f.indexOf(t)},t.isZeroWidthJoiner=function(t){return t===r},t.isFlagEmoji=function(t){return y(t.substr(0,2))&&y(t.substr(2,2))},t.isRegionalCode=y,t.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},t.isRegionalFlag=function(t,e){var i;if(u(t.substr(e,2))!==s)return!1;var r=0;for(e+=2;r<5;){if((i=u(t.substr(e,2)))<h||l<i)return!1;r+=1,e+=2}return u(t.substr(e,2))===o},t.isVariationSelector=function(t){return t===i},t.BLACK_FLAG_CODE_POINT=s,t.prototype={addChars:function(t){if(t){this.chars||(this.chars=[]);for(var e,i,r=t.length,s=this.chars.length,a=0;a<r;a+=1){for(e=0,i=!1;e<s;)this.chars[e].style===t[a].style&&this.chars[e].fFamily===t[a].fFamily&&this.chars[e].ch===t[a].ch&&(i=!0),e+=1;i||(this.chars.push(t[a]),s+=1)}}},addFonts:function(t,e){if(t)if(this.chars)this.isLoaded=!0,this.fonts=t.list;else if(document.body){for(var i=t.list,r=i.length,s=r,a=0;a<r;a+=1){var n,o,h,l,p=!0;if(i[a].loaded=!1,i[a].monoCase=c(i[a].fFamily,"monospace"),i[a].sansCase=c(i[a].fFamily,"sans-serif"),i[a].fPath){if("p"===i[a].fOrigin||3===i[a].origin)(p=0<(o=document.querySelectorAll('style[f-forigin="p"][f-family="'+i[a].fFamily+'"], style[f-origin="3"][f-family="'+i[a].fFamily+'"]')).length?!1:p)&&((h=createTag("style")).setAttribute("f-forigin",i[a].fOrigin),h.setAttribute("f-origin",i[a].origin),h.setAttribute("f-family",i[a].fFamily),h.type="text/css",h.innerText="@font-face {font-family: "+i[a].fFamily+"; font-style: normal; src: url('"+i[a].fPath+"');}",e.appendChild(h));else if("g"===i[a].fOrigin||1===i[a].origin){for(o=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),n=0;n<o.length;n+=1)-1!==o[n].href.indexOf(i[a].fPath)&&(p=!1);p&&((h=createTag("link")).setAttribute("f-forigin",i[a].fOrigin),h.setAttribute("f-origin",i[a].origin),h.type="text/css",h.rel="stylesheet",h.href=i[a].fPath,document.body.appendChild(h))}else if("t"===i[a].fOrigin||2===i[a].origin){for(o=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),n=0;n<o.length;n+=1)i[a].fPath===o[n].src&&(p=!1);p&&((l=createTag("link")).setAttribute("f-forigin",i[a].fOrigin),l.setAttribute("f-origin",i[a].origin),l.setAttribute("rel","stylesheet"),l.setAttribute("href",i[a].fPath),e.appendChild(l))}}else i[a].loaded=!0,--s;i[a].helper=d(i[a],e),i[a].cache={},this.fonts.push(i[a])}0===s?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0,t.list.forEach(function(t){t.helper=d(t),t.cache={}}),this.fonts=t.list;else this.isLoaded=!0},getCharData:function(t,e,i){for(var r=0,s=this.chars.length;r<s;){if(this.chars[r].ch===t&&this.chars[r].style===e&&this.chars[r].fFamily===i)return this.chars[r];r+=1}return("string"==typeof t&&13!==t.charCodeAt(0)||!t)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",t,e,i)),n},getFontByName:function(t){for(var e=0,i=this.fonts.length;e<i;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,i){var r,s,a,e=this.getFontByName(e),n=t;return e.cache[n]||(r=e.helper," "===t?(s=r.measureText("|"+t+"|"),a=r.measureText("||"),e.cache[n]=(s-a)/100):e.cache[n]=r.measureText(t)/100),e.cache[n]*i},checkLoadedFonts:function(){for(var t,e,i=this.fonts.length,r=i,s=0;s<i;s+=1)this.fonts[s].loaded?--r:"n"===this.fonts[s].fOrigin||0===this.fonts[s].origin?this.fonts[s].loaded=!0:(t=this.fonts[s].monoCase.node,e=this.fonts[s].monoCase.w,t.offsetWidth===e&&(t=this.fonts[s].sansCase.node,e=this.fonts[s].sansCase.w,t.offsetWidth===e)||(--r,this.fonts[s].loaded=!0),this.fonts[s].loaded&&(this.fonts[s].sansCase.parent.parentNode.removeChild(this.fonts[s].sansCase.parent),this.fonts[s].monoCase.parent.parentNode.removeChild(this.fonts[s].monoCase.parent)));0!==r&&Date.now()-this.initTime<a?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}},t})();function SlotManager(t){this.animationData=t}function slotFactory(t){return new SlotManager(t)}function RenderableElement(){}SlotManager.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},RenderableElement.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){for(var t=this.renderableComponents.length,e=0;e<t;e+=1)this.renderableComponents[e].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var getBlendMode=(()=>{var e={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"};return function(t){return e[t]||""}})();function SliderEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function AngleEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function ColorEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function PointEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function LayerIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function MaskIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function CheckboxEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function NoValueEffect(){this.p={}}function EffectsManager(t,e){for(var i,r=t.ef||[],s=(this.effectElements=[],r.length),a=0;a<s;a+=1)i=new GroupEffect(r[a],e),this.effectElements.push(i)}function GroupEffect(t,e){this.init(t,e)}function BaseElement(){}function FrameElement(){}function FootageElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,i)}function AudioElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,i),this._isPlaying=!1,this._canPlay=!1;i=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(i),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=PropertyFactory.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function BaseRenderer(){}extendPrototype([DynamicPropertyContainer],GroupEffect),GroupEffect.prototype.getValue=GroupEffect.prototype.iterateDynamicProperties,GroupEffect.prototype.init=function(t,e){this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);for(var i,r=this.data.ef.length,s=this.data.ef,a=0;a<r;a+=1){switch(i=null,s[a].ty){case 0:i=new SliderEffect(s[a],e,this);break;case 1:i=new AngleEffect(s[a],e,this);break;case 2:i=new ColorEffect(s[a],e,this);break;case 3:i=new PointEffect(s[a],e,this);break;case 4:case 7:i=new CheckboxEffect(s[a],e,this);break;case 10:i=new LayerIndexEffect(s[a],e,this);break;case 11:i=new MaskIndexEffect(s[a],e,this);break;case 5:i=new EffectsManager(s[a],e,this);break;default:i=new NoValueEffect(s[a],e,this)}i&&this.effectElements.push(i)}},BaseElement.prototype={checkMasks:function(){if(this.data.hasMask)for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t,e,i,r,s=getExpressionInterfaces();s&&(r=s("layer"),t=s("effects"),e=s("shape"),i=s("text"),s=s("comp"),this.layerInterface=r(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager),r=t.createEffectsInterface(this,this.layerInterface),this.layerInterface.registerEffectsInterface(r),0===this.data.ty||this.data.xt?this.compInterface=s(this):4===this.data.ty?(this.layerInterface.shapeInterface=e(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=i(this),this.layerInterface.text=this.layerInterface.textInterface))},setBlendMode:function(){var t=getBlendMode(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,i){this.globalData=e,this.comp=i,this.data=t,this.layerId=createElementID(),this.data.sr||(this.data.sr=1),this.effectsManager=new EffectsManager(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},FrameElement.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){for(var i=this.dynamicProperties.length,r=0;r<i;r+=1)(e||this._isParent&&"transform"===this.dynamicProperties[r].propType)&&(this.dynamicProperties[r].getValue(),this.dynamicProperties[r]._mdf)&&(this.globalData._mdf=!0,this._mdf=!0)},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},FootageElement.prototype.prepareFrame=function(){},extendPrototype([RenderableElement,BaseElement,FrameElement],FootageElement),FootageElement.prototype.getBaseElement=function(){return null},FootageElement.prototype.renderFrame=function(){},FootageElement.prototype.destroy=function(){},FootageElement.prototype.initExpressions=function(){var t=getExpressionInterfaces();t&&(t=t("footage"),this.layerInterface=t(this))},FootageElement.prototype.getFootageData=function(){return this.footageData},AudioElement.prototype.prepareFrame=function(t){this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder?this._currentTime=t/this.data.sr:(t=this.tm.v,this._currentTime=t),this._volume=this.lv.v[0];t=this._volume*this._volumeMultiplier;this._previousVolume!==t&&(this._previousVolume=t,this.audio.volume(t))},extendPrototype([RenderableElement,BaseElement,FrameElement],AudioElement),AudioElement.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||.1<Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek()))&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},AudioElement.prototype.show=function(){},AudioElement.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},AudioElement.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},AudioElement.prototype.resume=function(){this._canPlay=!0},AudioElement.prototype.setRate=function(t){this.audio.rate(t)},AudioElement.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},AudioElement.prototype.getBaseElement=function(){return null},AudioElement.prototype.destroy=function(){},AudioElement.prototype.sourceRectAtTime=function(){},AudioElement.prototype.initExpressions=function(){},BaseRenderer.prototype.checkLayers=function(t){var e,i,r=this.layers.length;for(this.completeLayers=!0,e=r-1;0<=e;--e)this.elements[e]||(i=this.layers[e]).ip-i.st<=t-this.layers[e].st&&i.op-i.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t);default:return this.createNull(t)}},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.createAudio=function(t){return new AudioElement(t,this.globalData,this)},BaseRenderer.prototype.createFootage=function(t){return new FootageElement(t,this.globalData,this)},BaseRenderer.prototype.buildAllItems=function(){for(var t=this.layers.length,e=0;e<t;e+=1)this.buildItem(e);this.checkPendingElements()},BaseRenderer.prototype.includeLayers=function(t){this.completeLayers=!1;for(var e,i=t.length,r=this.layers.length,s=0;s<i;s+=1)for(e=0;e<r;){if(this.layers[e].id===t[s].id){this.layers[e]=t[s];break}e+=1}},BaseRenderer.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},BaseRenderer.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},BaseRenderer.prototype.buildElementParenting=function(t,e,i){for(var r=this.elements,s=this.layers,a=0,n=s.length;a<n;)s[a].ind==e&&(r[a]&&!0!==r[a]?(i.push(r[a]),r[a].setAsParent(),void 0!==s[a].parent?this.buildElementParenting(t,s[a].parent,i):t.setHierarchy(i)):(this.buildItem(a),this.addPendingElement(t))),a+=1},BaseRenderer.prototype.addPendingElement=function(t){this.pendingElements.push(t)},BaseRenderer.prototype.searchExtraCompositions=function(t){for(var e,i=t.length,r=0;r<i;r+=1)t[r].xt&&((e=this.createComp(t[r])).initExpressions(),this.globalData.projectInterface.registerComposition(e))},BaseRenderer.prototype.getElementById=function(t){for(var e=this.elements.length,i=0;i<e;i+=1)if(this.elements[i].data.ind===t)return this.elements[i];return null},BaseRenderer.prototype.getElementByPath=function(t){var e,i=t.shift();if("number"==typeof i)e=this.elements[i];else for(var r=this.elements.length,s=0;s<r;s+=1)if(this.elements[s].data.nm===i){e=this.elements[s];break}return 0===t.length?e:e.getElementByPath(t)},BaseRenderer.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new FontManager,this.globalData.slotManager=slotFactory(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var effectTypes={TRANSFORM_EFFECT:"transformEFfect"};function TransformElement(){}function MaskElement(t,e,i){this.data=t,this.element=e,this.globalData=i,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;for(var r,s,a,n,o,h=this.globalData.defs,l=this.masksProperties?this.masksProperties.length:0,p=(this.viewData=createSizedArray(l),this.solidPath="",this.masksProperties),m=0,f=[],c=createElementID(),d="clipPath",u="clip-path",y=0;y<l;y+=1)if(("a"!==p[y].mode&&"n"!==p[y].mode||p[y].inv||100!==p[y].o.k||p[y].o.x)&&(u=d="mask"),"s"!==p[y].mode&&"i"!==p[y].mode||0!==m?s=null:((s=createNS("rect")).setAttribute("fill","#ffffff"),s.setAttribute("width",this.element.comp.data.w||0),s.setAttribute("height",this.element.comp.data.h||0),f.push(s)),r=createNS("path"),"n"===p[y].mode)this.viewData[y]={op:PropertyFactory.getProp(this.element,p[y].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,p[y],3),elem:r,lastPath:""},h.appendChild(r);else{if(m+=1,r.setAttribute("fill","s"===p[y].mode?"#000000":"#ffffff"),r.setAttribute("clip-rule","nonzero"),0!==p[y].x.k?(u=d="mask",n=PropertyFactory.getProp(this.element,p[y].x,0,null,this.element),o=createElementID(),(x=createNS("filter")).setAttribute("id",o),(a=createNS("feMorphology")).setAttribute("operator","erode"),a.setAttribute("in","SourceGraphic"),a.setAttribute("radius","0"),x.appendChild(a),h.appendChild(x),r.setAttribute("stroke","s"===p[y].mode?"#000000":"#ffffff")):n=a=null,this.storedData[y]={elem:r,x:n,expan:a,lastPath:"",lastOperator:"",filterId:o,lastRadius:0},"i"===p[y].mode){for(var g=f.length,v=createNS("g"),b=0;b<g;b+=1)v.appendChild(f[b]);var x=createNS("mask");x.setAttribute("mask-type","alpha"),x.setAttribute("id",c+"_"+m),x.appendChild(r),h.appendChild(x),v.setAttribute("mask","url("+getLocationHref()+"#"+c+"_"+m+")"),f.length=0,f.push(v)}else f.push(r);p[y].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[y]={elem:r,lastPath:"",op:PropertyFactory.getProp(this.element,p[y].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,p[y],3),invRect:s},this.viewData[y].prop.k||this.drawPath(p[y],this.viewData[y].prop.v,this.viewData[y])}for(this.maskElement=createNS(d),l=f.length,y=0;y<l;y+=1)this.maskElement.appendChild(f[y]);0<m&&(this.maskElement.setAttribute("id",c),this.element.maskedElement.setAttribute(u,"url("+getLocationHref()+"#"+c+")"),h.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}TransformElement.prototype={initTransform:function(){var t=new Matrix;this.finalTransform={mProp:this.data.ks?TransformPropertyFactory.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,i=0,r=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;i<r;){if(this.hierarchy[i].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}i+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),i=0;i<r;i+=1)e.multiply(this.hierarchy[i].finalTransform.mProp.v)}this.localTransforms&&!this.finalTransform._matMdf||(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var i=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(i),t=1;t<e;t+=1){var r=this.localTransforms[t].matrix;i.multiply(r)}i.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){for(var s=this.finalTransform.localOpacity,t=0;t<e;t+=1)s*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=s}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new Matrix;for(var e=0,i=t.length,e=0;e<i;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){for(var e=[],i=(e.push(this.finalTransform),!0),r=this.comp;i;)r.finalTransform?(r.data.hasMask&&e.splice(0,0,r.finalTransform),r=r.comp):i=!1;for(var s,a=e.length,n=0;n<a;n+=1)s=e[n].mat.applyToPointArray(0,0,0),t=[t[0]-s[0],t[1]-s[1],0];return t},mHelper:new Matrix},MaskElement.prototype.getMaskProperty=function(t){return this.viewData[t].prop},MaskElement.prototype.renderFrame=function(t){for(var e,i=this.element.finalTransform.mat,r=this.masksProperties.length,s=0;s<r;s+=1)(this.viewData[s].prop._mdf||t)&&this.drawPath(this.masksProperties[s],this.viewData[s].prop.v,this.viewData[s]),(this.viewData[s].op._mdf||t)&&this.viewData[s].elem.setAttribute("fill-opacity",this.viewData[s].op.v),"n"!==this.masksProperties[s].mode&&(this.viewData[s].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[s].invRect.setAttribute("transform",i.getInverseMatrix().to2dCSS()),this.storedData[s].x)&&(this.storedData[s].x._mdf||t)&&(e=this.storedData[s].expan,this.storedData[s].x.v<0?("erode"!==this.storedData[s].lastOperator&&(this.storedData[s].lastOperator="erode",this.storedData[s].elem.setAttribute("filter","url("+getLocationHref()+"#"+this.storedData[s].filterId+")")),e.setAttribute("radius",-this.storedData[s].x.v)):("dilate"!==this.storedData[s].lastOperator&&(this.storedData[s].lastOperator="dilate",this.storedData[s].elem.setAttribute("filter",null)),this.storedData[s].elem.setAttribute("stroke-width",2*this.storedData[s].x.v)))},MaskElement.prototype.getMaskelement=function(){return this.maskElement},MaskElement.prototype.createLayerSolidPath=function(){var t="M0,0 ";return(t+=" h"+this.globalData.compSize.w)+(" v"+this.globalData.compSize.h)+(" h-"+this.globalData.compSize.w)+(" v-"+this.globalData.compSize.h+" ")},MaskElement.prototype.drawPath=function(t,e,i){for(var r,s=" M"+e.v[0][0]+","+e.v[0][1],a=e._length,n=1;n<a;n+=1)s+=" C"+e.o[n-1][0]+","+e.o[n-1][1]+" "+e.i[n][0]+","+e.i[n][1]+" "+e.v[n][0]+","+e.v[n][1];e.c&&1<a&&(s+=" C"+e.o[n-1][0]+","+e.o[n-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),i.lastPath!==s&&(r="",i.elem&&(e.c&&(r=t.inv?this.solidPath+s:s),i.elem.setAttribute("d",r)),i.lastPath=s)},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var filtersFactory=(()=>{var t={createFilter:function(t,e){var i=createNS("filter");i.setAttribute("id",t),!0!==e&&(i.setAttribute("filterUnits","objectBoundingBox"),i.setAttribute("x","0%"),i.setAttribute("y","0%"),i.setAttribute("width","100%"),i.setAttribute("height","100%"));return i},createAlphaToLuminanceFilter:function(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t}};return t})(),featureSupport=(()=>{var t={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),/firefox/i.test(navigator.userAgent)&&(t.svgLumaHidden=!1),t})(),registeredEffects$1={},idPrefix="filter_result_";function SVGEffects(t){var e,i="SourceGraphic",r=t.data.ef?t.data.ef.length:0,s=createElementID(),a=filtersFactory.createFilter(s,!0),n=0;for(this.filters=[],e=0;e<r;e+=1){o=null;var o,h=t.data.ef[e].ty;registeredEffects$1[h]&&(o=new registeredEffects$1[h].effect(a,t.effectsManager.effectElements[e],t,idPrefix+n,i),i=idPrefix+n,registeredEffects$1[h].countsAsEffect)&&(n+=1),o&&this.filters.push(o)}n&&(t.globalData.defs.appendChild(a),t.layerElement.setAttribute("filter","url("+getLocationHref()+"#"+s+")")),this.filters.length&&t.addRenderableComponent(this)}function registerEffect$1(t,e,i){registeredEffects$1[t]={effect:e,countsAsEffect:i}}function SVGBaseElement(){}function HierarchyElement(){}function RenderableDOMElement(){}function IImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,i),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ProcessedElement(t,e){this.elem=t,this.pos=e}function IShapeElement(){}SVGEffects.prototype.renderFrame=function(t){for(var e=this.filters.length,i=0;i<e;i+=1)this.filters[i].renderFrame(t)},SVGEffects.prototype.getEffects=function(t){for(var e=this.filters.length,i=[],r=0;r<e;r+=1)this.filters[r].type===t&&i.push(this.filters[r]);return i},SVGBaseElement.prototype={initRendererElement:function(){this.layerElement=createNS("g")},createContainerElements:function(){this.matteElement=createNS("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t,e,i,r=null;this.data.td?(this.matteMasks={},(t=createNS("g")).setAttribute("id",this.layerId),t.appendChild(this.layerElement),this.globalData.defs.appendChild(r=t)):this.data.tt?(this.matteElement.appendChild(this.layerElement),r=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement,this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0!==this.data.ty||this.data.hd||(t=createNS("clipPath"),(i=createNS("path")).setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z"),e=createElementID(),t.setAttribute("id",e),t.appendChild(i),this.globalData.defs.appendChild(t),this.checkMasks()?((i=createNS("g")).setAttribute("clip-path","url("+getLocationHref()+"#"+e+")"),i.appendChild(this.layerElement),this.transformedElement=i,r?r.appendChild(this.transformedElement):this.baseElement=this.transformedElement):this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+e+")")),0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData),this.renderableEffectsManager=new SVGEffects(this),this.searchEffectTransforms()},getMatte:function(t){var e,i,r,s,a,n,o,h,l;return this.matteMasks||(this.matteMasks={}),this.matteMasks[t]||(e=this.layerId+"_"+t,1===t||3===t?((n=createNS("mask")).setAttribute("id",e),n.setAttribute("mask-type",3===t?"luminance":"alpha"),(s=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),n.appendChild(s),this.globalData.defs.appendChild(n),featureSupport.maskType||1!==t||(n.setAttribute("mask-type","luminance"),i=createElementID(),r=filtersFactory.createFilter(i),this.globalData.defs.appendChild(r),r.appendChild(filtersFactory.createAlphaToLuminanceFilter()),(a=createNS("g")).appendChild(s),n.appendChild(a),a.setAttribute("filter","url("+getLocationHref()+"#"+i+")"))):2===t&&((n=createNS("mask")).setAttribute("id",e),n.setAttribute("mask-type","alpha"),o=createNS("g"),n.appendChild(o),i=createElementID(),r=filtersFactory.createFilter(i),(l=createNS("feComponentTransfer")).setAttribute("in","SourceGraphic"),r.appendChild(l),(h=createNS("feFuncA")).setAttribute("type","table"),h.setAttribute("tableValues","1.0 0.0"),l.appendChild(h),this.globalData.defs.appendChild(r),(l=createNS("rect")).setAttribute("width",this.comp.data.w),l.setAttribute("height",this.comp.data.h),l.setAttribute("x","0"),l.setAttribute("y","0"),l.setAttribute("fill","#ffffff"),l.setAttribute("opacity","0"),o.setAttribute("filter","url("+getLocationHref()+"#"+i+")"),o.appendChild(l),(s=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),o.appendChild(s),featureSupport.maskType||(n.setAttribute("mask-type","luminance"),r.appendChild(filtersFactory.createAlphaToLuminanceFilter()),a=createNS("g"),o.appendChild(l),a.appendChild(this.layerElement),o.appendChild(a)),this.globalData.defs.appendChild(n)),this.matteMasks[t]=e),this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+getLocationHref()+"#"+t+")")}},HierarchyElement.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},extendPrototype([RenderableElement,createProxyFunction({initElement:function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],RenderableDOMElement),extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],IImageElement),IImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=createNS("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},IImageElement.prototype.sourceRectAtTime=function(){return this.sourceRect},IShapeElement.prototype={addShapeToModifiers:function(t){for(var e=this.shapeModifiers.length,i=0;i<e;i+=1)this.shapeModifiers[i].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){for(var t=this.shapes.length,e=0;e<t;e+=1)this.shapes[e].sh.reset();for(e=(t=this.shapeModifiers.length)-1;0<=e&&!this.shapeModifiers[e].processShapes(this._isFirstFrame);--e);}},searchProcessedElement:function(t){for(var e=this.processedElements,i=0,r=e.length;i<r;){if(e[i].elem===t)return e[i].pos;i+=1}return 0},addProcessedElement:function(t,e){for(var i=this.processedElements,r=i.length;r;)if(i[--r].elem===t)return void(i[r].pos=e);i.push(new ProcessedElement(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var lineCapEnum={1:"butt",2:"round",3:"square"},lineJoinEnum={1:"miter",2:"round",3:"bevel"};function SVGShapeData(t,e,i){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=i,this.lvl=e,this._isAnimated=!!i.k;for(var r=0,s=t.length;r<s;){if(t[r].mProps.dynamicProperties.length){this._isAnimated=!0;break}r+=1}}function SVGStyleData(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=createNS("path"),this.msElem=null}function DashProperty(t,e,i,r){this.elem=t,this.frameId=-1,this.dataProps=createSizedArray(e.length),this.renderer=i,this.k=!1,this.dashStr="",this.dashArray=createTypedArray("float32",e.length?e.length-1:0),this.dashoffset=createTypedArray("float32",1),this.initDynamicPropertyContainer(r);for(var s,a=e.length||0,n=0;n<a;n+=1)s=PropertyFactory.getProp(t,e[n].v,0,0,this),this.k=s.k||this.k,this.dataProps[n]={n:e[n].n,p:s};this.k||this.getValue(!0),this._isAnimated=this.k}function SVGStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i,this._isAnimated=!!this._isAnimated}function SVGFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i}function SVGNoStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=i}function GradientProperty(t,e,i){this.data=e,this.c=createTypedArray("uint8c",4*e.p);var r=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=createTypedArray("float32",r),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=r,this.initDynamicPropertyContainer(i),this.prop=PropertyFactory.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function SVGGradientFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,i)}function SVGGradientStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.initGradientData(t,e,i),this._isAnimated=!!this._isAnimated}function ShapeGroupData(){this.it=[],this.prevViewData=[],this.gr=createNS("g")}function SVGTransformData(t,e,i){this.transform={mProps:t,op:e,container:i},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}SVGShapeData.prototype.setAsAnimated=function(){this._isAnimated=!0},SVGStyleData.prototype.reset=function(){this.d="",this._mdf=!1},DashProperty.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,i=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<i;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},extendPrototype([DynamicPropertyContainer],DashProperty),extendPrototype([DynamicPropertyContainer],SVGStrokeStyleData),extendPrototype([DynamicPropertyContainer],SVGFillStyleData),extendPrototype([DynamicPropertyContainer],SVGNoStyleData),GradientProperty.prototype.comparePoints=function(t,e){for(var i=0,r=this.o.length/2;i<r;){if(.01<Math.abs(t[4*i]-t[4*e+2*i]))return!1;i+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},GradientProperty.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){for(var e,i,r=4*this.data.p,s=0;s<r;s+=1)e=s%4==0?100:255,i=Math.round(this.prop.v[s]*e),this.c[s]!==i&&(this.c[s]=i,this._cmdf=!t);if(this.o.length)for(r=this.prop.v.length,s=4*this.data.p;s<r;s+=1)e=s%2==0?100:1,i=s%2==0?Math.round(100*this.prop.v[s]):this.prop.v[s],this.o[s-4*this.data.p]!==i&&(this.o[s-4*this.data.p]=i,this._omdf=!t);this._mdf=!t}},extendPrototype([DynamicPropertyContainer],GradientProperty),SVGGradientFillStyleData.prototype.initGradientData=function(t,e,i){this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.s=PropertyFactory.getProp(t,e.s,1,null,this),this.e=PropertyFactory.getProp(t,e.e,1,null,this),this.h=PropertyFactory.getProp(t,e.h||{k:0},0,.01,this),this.a=PropertyFactory.getProp(t,e.a||{k:0},0,degToRads,this),this.g=new GradientProperty(t,e.g,this),this.style=i,this.stops=[],this.setGradientData(i.pElem,e),this.setGradientOpacity(e,i),this._isAnimated=!!this._isAnimated},SVGGradientFillStyleData.prototype.setGradientData=function(t,e){for(var i,r=createElementID(),s=createNS(1===e.t?"linearGradient":"radialGradient"),a=(s.setAttribute("id",r),s.setAttribute("spreadMethod","pad"),s.setAttribute("gradientUnits","userSpaceOnUse"),[]),n=4*e.g.p,o=0;o<n;o+=4)i=createNS("stop"),s.appendChild(i),a.push(i);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+getLocationHref()+"#"+r+")"),this.gf=s,this.cst=a},SVGGradientFillStyleData.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){for(var i,r,s=createNS("mask"),a=createNS("path"),n=(s.appendChild(a),createElementID()),o=createElementID(),h=(s.setAttribute("id",o),createNS(1===t.t?"linearGradient":"radialGradient")),l=(h.setAttribute("id",n),h.setAttribute("spreadMethod","pad"),h.setAttribute("gradientUnits","userSpaceOnUse"),r=(t.g.k.k[0].s||t.g.k.k).length,this.stops),p=4*t.g.p;p<r;p+=2)(i=createNS("stop")).setAttribute("stop-color","rgb(255,255,255)"),h.appendChild(i),l.push(i);a.setAttribute("gf"===t.ty?"fill":"stroke","url("+getLocationHref()+"#"+n+")"),"gs"===t.ty&&(a.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),a.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),1===t.lj)&&a.setAttribute("stroke-miterlimit",t.ml),this.of=h,this.ms=s,this.ost=l,this.maskId=o,e.msElem=a}},extendPrototype([DynamicPropertyContainer],SVGGradientFillStyleData),extendPrototype([SVGGradientFillStyleData,DynamicPropertyContainer],SVGGradientStrokeStyleData);var buildShapeString=function(t,e,i,r){if(0===e)return"";for(var s=t.o,a=t.i,n=t.v,o=" M"+r.applyToPointStringified(n[0][0],n[0][1]),h=1;h<e;h+=1)o+=" C"+r.applyToPointStringified(s[h-1][0],s[h-1][1])+" "+r.applyToPointStringified(a[h][0],a[h][1])+" "+r.applyToPointStringified(n[h][0],n[h][1]);return o=i&&e?o+(" C"+r.applyToPointStringified(s[h-1][0],s[h-1][1])+" "+r.applyToPointStringified(a[0][0],a[0][1])+" "+r.applyToPointStringified(n[0][0],n[0][1]))+"z":o},SVGElementsRenderer=(()=>{var u=new Matrix,y=new Matrix;function e(t,e,i){(i||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(i||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function i(){}function r(t,e,i){for(var r,s,a,n,o,h,l,p,m,f=e.styles.length,c=e.lvl,d=0;d<f;d+=1){if(n=e.sh._mdf||i,e.styles[d].lvl<c){for(l=y.reset(),p=c-e.styles[d].lvl,m=e.transformers.length-1;!n&&0<p;)n=e.transformers[m].mProps._mdf||n,--p,--m;if(n)for(p=c-e.styles[d].lvl,m=e.transformers.length-1;0<p;)l.multiply(e.transformers[m].mProps.v),--p,--m}else l=u;if(s=(h=e.sh.paths)._length,n){for(a="",r=0;r<s;r+=1)(o=h.shapes[r])&&o._length&&(a+=buildShapeString(o,o._length,o.c,l));e.caches[d]=a}else a=e.caches[d];e.styles[d].d+=!0===t.hd?"":a,e.styles[d]._mdf=n||e.styles[d]._mdf}}function s(t,e,i){var r=e.style;(e.c._mdf||i)&&r.pElem.setAttribute("fill","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("fill-opacity",e.o.v)}function a(t,e,i){n(t,e,i),o(0,e,i)}function n(t,e,i){var r,s,a,n,o=e.gf,h=e.g._hasOpacity,l=e.s.v,p=e.e.v;if((e.o._mdf||i)&&(a="gf"===t.ty?"fill-opacity":"stroke-opacity",e.style.pElem.setAttribute(a,e.o.v)),(e.s._mdf||i)&&(n="x1"==(a=1===t.t?"x1":"cx")?"y1":"cy",o.setAttribute(a,l[0]),o.setAttribute(n,l[1]),h)&&!e.g._collapsable&&(e.of.setAttribute(a,l[0]),e.of.setAttribute(n,l[1])),e.g._cmdf||i)for(var m=e.cst,f=e.g.c,c=m.length,d=0;d<c;d+=1)(r=m[d]).setAttribute("offset",f[4*d]+"%"),r.setAttribute("stop-color","rgb("+f[4*d+1]+","+f[4*d+2]+","+f[4*d+3]+")");if(h&&(e.g._omdf||i)){var u=e.g.o;for(c=(m=e.g._collapsable?e.cst:e.ost).length,d=0;d<c;d+=1)r=m[d],e.g._collapsable||r.setAttribute("offset",u[2*d]+"%"),r.setAttribute("stop-opacity",u[2*d+1])}1===t.t?(e.e._mdf||i)&&(o.setAttribute("x2",p[0]),o.setAttribute("y2",p[1]),h)&&!e.g._collapsable&&(e.of.setAttribute("x2",p[0]),e.of.setAttribute("y2",p[1])):((e.s._mdf||e.e._mdf||i)&&(s=Math.sqrt(Math.pow(l[0]-p[0],2)+Math.pow(l[1]-p[1],2)),o.setAttribute("r",s),h)&&!e.g._collapsable&&e.of.setAttribute("r",s),(e.s._mdf||e.e._mdf||e.h._mdf||e.a._mdf||i)&&(s=s||Math.sqrt(Math.pow(l[0]-p[0],2)+Math.pow(l[1]-p[1],2)),a=Math.atan2(p[1]-l[1],p[0]-l[0]),1<=(n=e.h.v)?n=.99:n<=-1&&(n=-.99),t=s*n,i=Math.cos(a+e.a.v)*t+l[0],p=Math.sin(a+e.a.v)*t+l[1],o.setAttribute("fx",i),o.setAttribute("fy",p),h)&&!e.g._collapsable&&(e.of.setAttribute("fx",i),e.of.setAttribute("fy",p)))}function o(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||i)&&s.dashStr&&(r.pElem.setAttribute("stroke-dasharray",s.dashStr),r.pElem.setAttribute("stroke-dashoffset",s.dashoffset[0])),e.c&&(e.c._mdf||i)&&r.pElem.setAttribute("stroke","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||i)&&(r.pElem.setAttribute("stroke-width",e.w.v),r.msElem)&&r.msElem.setAttribute("stroke-width",e.w.v)}return{createRenderFunction:function(t){switch(t.ty){case"fl":return s;case"gf":return n;case"gs":return a;case"st":return o;case"sh":case"el":case"rc":case"sr":return r;case"tr":return e;case"no":return i;default:return null}}}})();function SVGShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,i),this.prevViewData=[]}function LetterProps(t,e,i,r,s,a){this.o=t,this.sw=e,this.sc=i,this.fc=r,this.m=s,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!i,fc:!!r,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){for(var t,e,i,r=this.shapes.length,s=this.stylesList.length,a=[],n=!1,o=0;o<s;o+=1){for(i=this.stylesList[o],n=!1,t=a.length=0;t<r;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(i)&&(a.push(e),n=e._isAnimated||n);1<a.length&&n&&this.setShapesAsAnimated(a)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){for(var e=t.length,i=0;i<e;i+=1)t[i].setAsAnimated()},SVGShapeElement.prototype.createStyleElement=function(t,e){var i,e=new SVGStyleData(t,e),r=e.pElem;return"st"===t.ty?i=new SVGStrokeStyleData(this,t,e):"fl"===t.ty?i=new SVGFillStyleData(this,t,e):"gf"===t.ty||"gs"===t.ty?(i=new("gf"===t.ty?SVGGradientFillStyleData:SVGGradientStrokeStyleData)(this,t,e),this.globalData.defs.appendChild(i.gf),i.maskId&&(this.globalData.defs.appendChild(i.ms),this.globalData.defs.appendChild(i.of),r.setAttribute("mask","url("+getLocationHref()+"#"+i.maskId+")"))):"no"===t.ty&&(i=new SVGNoStyleData(this,t,e)),"st"!==t.ty&&"gs"!==t.ty||(r.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),r.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),r.setAttribute("fill-opacity","0"),1===t.lj&&r.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&r.setAttribute("fill-rule","evenodd"),t.ln&&r.setAttribute("id",t.ln),t.cl&&r.setAttribute("class",t.cl),t.bm&&(r.style["mix-blend-mode"]=getBlendMode(t.bm)),this.stylesList.push(e),this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createGroupElement=function(t){var e=new ShapeGroupData;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=getBlendMode(t.bm)),e},SVGShapeElement.prototype.createTransformElement=function(t,e){var i=TransformPropertyFactory.getTransformProperty(this,t,this),i=new SVGTransformData(i,i.o,e);return this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createShapeElement=function(t,e,i){var r=4;"rc"===t.ty?r=5:"el"===t.ty?r=6:"sr"===t.ty&&(r=7);e=new SVGShapeData(e,i,ShapePropertyFactory.getShapeProp(this,t,r,this));return this.shapes.push(e),this.addShapeToModifiers(e),this.addToAnimatedContents(t,e),e},SVGShapeElement.prototype.addToAnimatedContents=function(t,e){for(var i=0,r=this.animatedContents.length;i<r;){if(this.animatedContents[i].element===e)return;i+=1}this.animatedContents.push({fn:SVGElementsRenderer.createRenderFunction(t),element:e,data:t})},SVGShapeElement.prototype.setElementStyles=function(t){for(var e=t.styles,i=this.stylesList.length,r=0;r<i;r+=1)-1!==e.indexOf(this.stylesList[r])||this.stylesList[r].closed||e.push(this.stylesList[r])},SVGShapeElement.prototype.reloadShapes=function(){this._isFirstFrame=!0;for(var t=this.itemsData.length,e=0;e<t;e+=1)this.prevViewData[e]=this.itemsData[e];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),t=this.dynamicProperties.length,e=0;e<t;e+=1)this.dynamicProperties[e].getValue();this.renderModifiers()},SVGShapeElement.prototype.searchShapes=function(t,e,i,r,s,a,n){for(var o,h,l,p,m,f=[].concat(a),c=t.length-1,d=[],u=[],y=c;0<=y;--y){if((m=this.searchProcessedElement(t[y]))?e[y]=i[m-1]:t[y]._render=n,"fl"===t[y].ty||"st"===t[y].ty||"gf"===t[y].ty||"gs"===t[y].ty||"no"===t[y].ty)m?e[y].style.closed=t[y].hd:e[y]=this.createStyleElement(t[y],s),t[y]._render&&e[y].style.pElem.parentNode!==r&&r.appendChild(e[y].style.pElem),d.push(e[y].style);else if("gr"===t[y].ty){if(m)for(h=e[y].it.length,o=0;o<h;o+=1)e[y].prevViewData[o]=e[y].it[o];else e[y]=this.createGroupElement(t[y]);this.searchShapes(t[y].it,e[y].it,e[y].prevViewData,e[y].gr,s+1,f,n),t[y]._render&&e[y].gr.parentNode!==r&&r.appendChild(e[y].gr)}else"tr"===t[y].ty?(m||(e[y]=this.createTransformElement(t[y],r)),l=e[y].transform,f.push(l)):"sh"===t[y].ty||"rc"===t[y].ty||"el"===t[y].ty||"sr"===t[y].ty?(m||(e[y]=this.createShapeElement(t[y],f,s)),this.setElementStyles(e[y])):"tm"===t[y].ty||"rd"===t[y].ty||"ms"===t[y].ty||"pb"===t[y].ty||"zz"===t[y].ty||"op"===t[y].ty?(m?(p=e[y]).closed=!1:((p=ShapeModifiers.getModifier(t[y].ty)).init(this,t[y]),e[y]=p,this.shapeModifiers.push(p)),u.push(p)):"rp"===t[y].ty&&(m?(p=e[y]).closed=!0:(p=ShapeModifiers.getModifier(t[y].ty),(e[y]=p).init(this,t,y,e),this.shapeModifiers.push(p),n=!1),u.push(p));this.addProcessedElement(t[y],y+1)}for(c=d.length,y=0;y<c;y+=1)d[y].closed=!0;for(c=u.length,y=0;y<c;y+=1)u[y].closed=!0},SVGShapeElement.prototype.renderInnerContent=function(){this.renderModifiers();for(var t=this.stylesList.length,e=0;e<t;e+=1)this.stylesList[e].reset();for(this.renderShape(),e=0;e<t;e+=1)(this.stylesList[e]._mdf||this._isFirstFrame)&&(this.stylesList[e].msElem&&(this.stylesList[e].msElem.setAttribute("d",this.stylesList[e].d),this.stylesList[e].d="M0 0"+this.stylesList[e].d),this.stylesList[e].pElem.setAttribute("d",this.stylesList[e].d||"M0 0"))},SVGShapeElement.prototype.renderShape=function(){for(var t,e=this.animatedContents.length,i=0;i<e;i+=1)t=this.animatedContents[i],(this._isFirstFrame||t.element._isAnimated)&&!0!==t.data&&t.fn(t.data,t.element,this._isFirstFrame)},SVGShapeElement.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},LetterProps.prototype.update=function(t,e,i,r,s,a){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1;var n=this._mdf.p=!1;return this.o!==t&&(this.o=t,n=this._mdf.o=!0),this.sw!==e&&(this.sw=e,n=this._mdf.sw=!0),this.sc!==i&&(this.sc=i,n=this._mdf.sc=!0),this.fc!==r&&(this.fc=r,n=this._mdf.fc=!0),this.m!==s&&(this.m=s,n=this._mdf.m=!0),!a.length||this.p[0]===a[0]&&this.p[1]===a[1]&&this.p[4]===a[4]&&this.p[5]===a[5]&&this.p[12]===a[12]&&this.p[13]===a[13]||(this.p=a,n=this._mdf.p=!0),n},TextProperty.prototype.defaultBoxWidth=[0,0],TextProperty.prototype.copyData=function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},TextProperty.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},TextProperty.prototype.searchProperty=function(){return this.searchKeyframes()},TextProperty.prototype.searchKeyframes=function(){return this.kf=1<this.data.d.k.length,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,i=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{this.lock=!0,this._mdf=!1;for(var r=this.effectsSequence.length,s=t||this.data.d.k[this.keysIndex].s,a=0;a<r;a+=1)s=i!==this.keysIndex?this.effectsSequence[a](s,s.t):this.effectsSequence[a](this.currentData,s.t);e!==s&&this.setCurrentData(s),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},TextProperty.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,i=0,r=t.length;i<=r-1&&!(i===r-1||t[i+1].t>e);)i+=1;return this.keysIndex!==i&&(this.keysIndex=i),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e,i,r=[],s=0,a=t.length,n=!1,o=!1,h="";s<a;)n=o,o=!1,e=t.charCodeAt(s),h=t.charAt(s),FontManager.isCombinedCharacter(e)?n=!0:55296<=e&&e<=56319?FontManager.isRegionalFlag(t,s)?h=t.substr(s,14):56320<=(i=t.charCodeAt(s+1))&&i<=57343&&(FontManager.isModifier(e,i)?(h=t.substr(s,2),n=!0):h=FontManager.isFlagEmoji(t.substr(s,4))?t.substr(s,4):t.substr(s,2)):56319<e?(i=t.charCodeAt(s+1),FontManager.isVariationSelector(e)&&(n=!0)):FontManager.isZeroWidthJoiner(e)&&(o=n=!0),n?(r[r.length-1]+=h,n=!1):r.push(h),s+=h.length;return r},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,i,r,s,a=this.elem.globalData.fontManager,n=this.data,o=[],h=0,l=n.m.g,p=0,m=0,f=0,c=[],d=0,u=0,y=a.getFontByName(t.f),g=0,v=getFontProperties(y),b=(t.fWeight=v.weight,t.fStyle=v.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),S=t.finalText.length,t.finalLineHeight=t.lh,t.tr/1e3*t.finalSize);if(t.sz)for(var x=!0,R=t.sz[0],L=t.sz[1];x;){for(var P,E=0,d=0,S=(P=this.buildFinalText(t.t)).length,b=t.tr/1e3*t.finalSize,C=-1,_=0;_<S;_+=1)s=P[_].charCodeAt(0),e=!1," "===P[_]?C=_:13!==s&&3!==s||(e=!(d=0),E+=t.finalLineHeight||1.2*t.finalSize),d=R<d+(g=a.chars?(r=a.getCharData(P[_],y.fStyle,y.fFamily),e?0:r.w*t.finalSize/100):a.measureText(P[_],t.f,t.finalSize))&&" "!==P[_]?(-1===C?S+=1:_=C,E+=t.finalLineHeight||1.2*t.finalSize,P.splice(_,C===_?1:0,"\r"),C=-1,0):d+g+b;E+=y.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&L<E?(--t.finalSize,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=P,S=t.finalText.length,x=!1)}d=-b;var A,g=0,T=0;for(_=0;_<S;_+=1)if(e=!1,13===(s=(A=t.finalText[_]).charCodeAt(0))||3===s?(T=0,c.push(d),u=u<d?d:u,d=-2*b,e=!(i=""),f+=1):i=A,g=a.chars?(r=a.getCharData(A,y.fStyle,a.getFontByName(t.f).fFamily),e?0:r.w*t.finalSize/100):a.measureText(i,t.f,t.finalSize)," "===A?T+=g+b:(d+=g+b+T,T=0),o.push({l:g,an:g,add:p,n:e,anIndexes:[],val:i,line:f,animatorJustifyOffset:0}),2==l){if(p+=g,""===i||" "===i||_===S-1){for(""!==i&&" "!==i||(p-=g);m<=_;)o[m].an=p,o[m].ind=h,o[m].extra=g,m+=1;h+=1,p=0}}else if(3==l){if(p+=g,""===i||_===S-1){for(""===i&&(p-=g);m<=_;)o[m].an=p,o[m].ind=h,o[m].extra=g,m+=1;p=0,h+=1}}else o[h].ind=h,o[h].extra=0,h+=1;if(t.l=o,u=u<d?d:u,c.push(d),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=u,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=c;for(var M,k,D,F,w=n.a,z=w.length,I=[],V=0;V<z;V+=1){for((M=w[V]).a.sc&&(t.strokeColorAnim=!0),M.a.sw&&(t.strokeWidthAnim=!0),(M.a.fc||M.a.fh||M.a.fs||M.a.fb)&&(t.fillColorAnim=!0),D=M.s.b,_=F=0;_<S;_+=1)(k=o[_]).anIndexes[V]=F,(1==D&&""!==k.val||2==D&&""!==k.val&&" "!==k.val||3==D&&(k.n||" "==k.val||_==S-1)||4==D&&(k.n||_==S-1))&&(1===M.s.rn&&I.push(F),F+=1);n.a[V].s.totalChars=F;var B,G=-1;if(1===M.s.rn)for(_=0;_<S;_+=1)G!=(k=o[_]).anIndexes[V]&&(G=k.anIndexes[V],B=I.splice(Math.floor(Math.random()*I.length),1)[0]),k.anIndexes[V]=B}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=y.ascent*t.finalSize/100},TextProperty.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var i=this.copyData({},this.data.d.k[e].s),i=this.copyData(i,t);this.data.d.k[e].s=i,this.recalculate(e),this.setCurrentData(i),this.elem.addDynamicProperty(this)},TextProperty.prototype.recalculate=function(t){t=this.data.d.k[t].s;t.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(t)},TextProperty.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},TextProperty.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var TextSelectorProp=(()=>{var o=Math.max,h=Math.min,l=Math.floor;function r(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=PropertyFactory.getProp(t,e.s||{k:0},0,0,this),"e"in e?this.e=PropertyFactory.getProp(t,e.e,0,0,this):this.e={v:100},this.o=PropertyFactory.getProp(t,e.o||{k:0},0,0,this),this.xe=PropertyFactory.getProp(t,e.xe||{k:0},0,0,this),this.ne=PropertyFactory.getProp(t,e.ne||{k:0},0,0,this),this.sm=PropertyFactory.getProp(t,e.sm||{k:100},0,0,this),this.a=PropertyFactory.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return r.prototype={getMult:function(t){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var e,i=0,r=0,s=1,a=1,i=(0<this.ne.v?i=this.ne.v/100:r=-this.ne.v/100,0<this.xe.v?s=1-this.xe.v/100:a=1+this.xe.v/100,BezierFactory.getBezierEasing(i,r,s,a).get),r=0,s=this.finalS,a=this.finalE,n=this.data.sh;return r=2===n?i(r=a===s?a<=t?1:0:o(0,h(.5/(a-s)+(t-s)/(a-s),1))):3===n?i(r=a===s?a<=t?0:1:1-o(0,h(.5/(a-s)+(t-s)/(a-s),1))):4===n?(a===s?r=0:(r=o(0,h(.5/(a-s)+(t-s)/(a-s),1)))<.5?r*=2:r=1-2*(r-.5),i(r)):i(r=5===n?a===s?0:(e=-(i=a-s)/2+(t=h(o(0,t+.5-s),a-s)),i=i/2,Math.sqrt(1-e*e/(i*i))):6===n?a===s?0:(t=h(o(0,t+.5-s),a-s),(1+Math.cos(Math.PI+2*Math.PI*t/(a-s)))/2):t>=l(s)?o(0,h(t-s<0?h(a,1)-(s-t):a-t,1)):r),100!==this.sm.v&&(r<(i=.5-.5*(e=0===(e=.01*this.sm.v)?1e-8:e))?r=0:1<(r=(r-i)/e)&&(r=1)),r*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var t=2===this.data.r?1:100/this.data.totalChars,e=this.o.v/t,i=this.s.v/t+e,t=this.e.v/t+e;t<i&&(e=i,i=t,t=e),this.finalS=i,this.finalE=t}},extendPrototype([DynamicPropertyContainer],r),{getTextSelectorProp:function(t,e,i){return new r(t,e)}}})();function TextAnimatorDataProperty(t,e,i){var r={propType:!1},s=PropertyFactory.getProp,a=e.a;this.a={r:a.r?s(t,a.r,0,degToRads,i):r,rx:a.rx?s(t,a.rx,0,degToRads,i):r,ry:a.ry?s(t,a.ry,0,degToRads,i):r,sk:a.sk?s(t,a.sk,0,degToRads,i):r,sa:a.sa?s(t,a.sa,0,degToRads,i):r,s:a.s?s(t,a.s,1,.01,i):r,a:a.a?s(t,a.a,1,0,i):r,o:a.o?s(t,a.o,0,.01,i):r,p:a.p?s(t,a.p,1,0,i):r,sw:a.sw?s(t,a.sw,0,0,i):r,sc:a.sc?s(t,a.sc,1,0,i):r,fc:a.fc?s(t,a.fc,1,0,i):r,fh:a.fh?s(t,a.fh,0,0,i):r,fs:a.fs?s(t,a.fs,0,.01,i):r,fb:a.fb?s(t,a.fb,0,.01,i):r,t:a.t?s(t,a.t,0,0,i):r},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,i),this.s.t=e.s.t}function TextAnimatorProperty(t,e,i){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=i,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(i)}function ITextElement(){}TextAnimatorProperty.prototype.searchProperties=function(){for(var t,e=this._textData.a.length,i=PropertyFactory.getProp,r=0;r<e;r+=1)t=this._textData.a[r],this._animatorsData[r]=new TextAnimatorDataProperty(this._elem,t,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:i(this._elem,this._textData.p.a,0,0,this),f:i(this._elem,this._textData.p.f,0,0,this),l:i(this._elem,this._textData.p.l,0,0,this),r:i(this._elem,this._textData.p.r,0,0,this),p:i(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=i(this._elem,this._textData.m.a,1,0,this)},TextAnimatorProperty.prototype.getMeasures=function(t,R){if(this.lettersChangedFlag=R,this._mdf||this._isFirstFrame||R||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var e,i,r,L,s,a,n,o,h,z,l,G,p,m=this._moreOptions.alignment.v,f=this._animatorsData,c=this._textData,d=this.mHelper,O=this._renderType,N=this.renderedLetters.length,u=t.l;if(this._hasMaskedPath){if(p=this._pathData.m,!this._pathData.n||this._pathData._mdf){for(var y,g=p.v,v={tLength:0,segments:[]},b=(g=this._pathData.r.v?g.reverse():g)._length-1,x=l=0;x<b;x+=1)y=bez.buildBezierData(g.v[x],g.v[x+1],[g.o[x][0]-g.v[x][0],g.o[x][1]-g.v[x][1]],[g.i[x+1][0]-g.v[x+1][0],g.i[x+1][1]-g.v[x+1][1]]),v.tLength+=y.segmentLength,v.segments.push(y),l+=y.segmentLength;x=b,p.v.c&&(y=bez.buildBezierData(g.v[x],g.v[0],[g.o[x][0]-g.v[x][0],g.o[x][1]-g.v[x][1]],[g.i[0][0]-g.v[0][0],g.i[0][1]-g.v[0][1]]),v.tLength+=y.segmentLength,v.segments.push(y),l+=y.segmentLength),this._pathData.pi=v}if(v=this._pathData.pi,e=this._pathData.f.v,s=1,L=!(r=a=0),h=v.segments,e<0&&p.v.c)for(v.tLength<Math.abs(e)&&(e=-Math.abs(e)%v.tLength),s=(o=h[a=h.length-1].points).length-1;e<0;)e+=o[s].partialLength,--s<0&&(s=(o=h[--a].points).length-1);n=(o=h[a].points)[s-1],z=(i=o[s]).partialLength}b=u.length;var P,H,E,S,j,q,C,_,A,T,M,W,$,Y,J,X,k=0,Z=0,K=1.2*t.finalSize*.714,U=!0,D=f.length,F=-1,Q=e,tt=a,et=s,it=-1,rt="",st=this.defaultPropsArray;if(2===t.j||1===t.j){var w=0,at=0,nt=2===t.j?-.5:-1,I=0,ot=!0;for(x=0;x<b;x+=1)if(u[x].n){for(w&&(w+=at);I<x;)u[I].animatorJustifyOffset=w,I+=1;ot=!(w=0)}else{for(B=0;B<D;B+=1)(P=f[B].a).t.propType&&(ot&&2===t.j&&(at+=P.t.v*nt),(E=f[B].s.getMult(u[x].anIndexes[B],c.a[B].s.totalChars)).length?w+=P.t.v*E[0]*nt:w+=P.t.v*E*nt);ot=!1}for(w&&(w+=at);I<x;)u[I].animatorJustifyOffset=w,I+=1}for(x=0;x<b;x+=1){if(d.reset(),C=1,u[x].n)k=0,Z=Z+t.yOffset+(U?1:0),e=Q,U=!1,this._hasMaskedPath&&(n=(o=h[a=tt].points)[(s=et)-1],z=(i=o[s]).partialLength,r=0),J=W=Y=rt="",st=this.defaultPropsArray;else{if(this._hasMaskedPath){if(it!==u[x].line){switch(t.j){case 1:e+=l-t.lineWidths[u[x].line];break;case 2:e+=(l-t.lineWidths[u[x].line])/2}it=u[x].line}F!==u[x].ind&&(u[F]&&(e+=u[F].extra),e+=u[x].an/2,F=u[x].ind),e+=m[0]*u[x].an*.005;for(var V=0,B=0;B<D;B+=1)(P=f[B].a).p.propType&&((E=f[B].s.getMult(u[x].anIndexes[B],c.a[B].s.totalChars)).length?V+=P.p.v[0]*E[0]:V+=P.p.v[0]*E),P.a.propType&&((E=f[B].s.getMult(u[x].anIndexes[B],c.a[B].s.totalChars)).length?V+=P.a.v[0]*E[0]:V+=P.a.v[0]*E);for(L=!0,this._pathData.a.v&&(e=.5*u[0].an+(l-this._pathData.f.v-.5*u[0].an-.5*u[u.length-1].an)*F/(b-1),e+=this._pathData.f.v);L;)e+V<=r+z||!o?(G=(e+V-r)/i.partialLength,j=n.point[0]+(i.point[0]-n.point[0])*G,q=n.point[1]+(i.point[1]-n.point[1])*G,d.translate(-m[0]*u[x].an*.005,-m[1]*K*.01),L=!1):o&&(r+=i.partialLength,(s+=1)>=o.length&&(s=0,o=h[a+=1]?h[a].points:p.v.c?h[a=s=0].points:(r-=i.partialLength,null)),o)&&(n=i,z=(i=o[s]).partialLength);S=u[x].an/2-u[x].add,d.translate(-S,0,0)}else S=u[x].an/2-u[x].add,d.translate(-S,0,0),d.translate(-m[0]*u[x].an*.005,-m[1]*K*.01,0);for(B=0;B<D;B+=1)(P=f[B].a).t.propType&&(E=f[B].s.getMult(u[x].anIndexes[B],c.a[B].s.totalChars),0===k&&0===t.j||(this._hasMaskedPath?E.length?e+=P.t.v*E[0]:e+=P.t.v*E:E.length?k+=P.t.v*E[0]:k+=P.t.v*E));for(t.strokeWidthAnim&&(A=t.sw||0),t.strokeColorAnim&&(_=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(T=[t.fc[0],t.fc[1],t.fc[2]]),B=0;B<D;B+=1)(P=f[B].a).a.propType&&((E=f[B].s.getMult(u[x].anIndexes[B],c.a[B].s.totalChars)).length?d.translate(-P.a.v[0]*E[0],-P.a.v[1]*E[1],P.a.v[2]*E[2]):d.translate(-P.a.v[0]*E,-P.a.v[1]*E,P.a.v[2]*E));for(B=0;B<D;B+=1)(P=f[B].a).s.propType&&((E=f[B].s.getMult(u[x].anIndexes[B],c.a[B].s.totalChars)).length?d.scale(1+(P.s.v[0]-1)*E[0],1+(P.s.v[1]-1)*E[1],1):d.scale(1+(P.s.v[0]-1)*E,1+(P.s.v[1]-1)*E,1));for(B=0;B<D;B+=1){if(P=f[B].a,E=f[B].s.getMult(u[x].anIndexes[B],c.a[B].s.totalChars),P.sk.propType&&(E.length?d.skewFromAxis(-P.sk.v*E[0],P.sa.v*E[1]):d.skewFromAxis(-P.sk.v*E,P.sa.v*E)),P.r.propType&&(E.length?d.rotateZ(-P.r.v*E[2]):d.rotateZ(-P.r.v*E)),P.ry.propType&&(E.length?d.rotateY(P.ry.v*E[1]):d.rotateY(P.ry.v*E)),P.rx.propType&&(E.length?d.rotateX(P.rx.v*E[0]):d.rotateX(P.rx.v*E)),P.o.propType&&(E.length?C+=(P.o.v*E[0]-C)*E[0]:C+=(P.o.v*E-C)*E),t.strokeWidthAnim&&P.sw.propType&&(E.length?A+=P.sw.v*E[0]:A+=P.sw.v*E),t.strokeColorAnim&&P.sc.propType)for(M=0;M<3;M+=1)E.length?_[M]+=(P.sc.v[M]-_[M])*E[0]:_[M]+=(P.sc.v[M]-_[M])*E;if(t.fillColorAnim&&t.fc){if(P.fc.propType)for(M=0;M<3;M+=1)E.length?T[M]+=(P.fc.v[M]-T[M])*E[0]:T[M]+=(P.fc.v[M]-T[M])*E;P.fh.propType&&(T=E.length?addHueToRGB(T,P.fh.v*E[0]):addHueToRGB(T,P.fh.v*E)),P.fs.propType&&(T=E.length?addSaturationToRGB(T,P.fs.v*E[0]):addSaturationToRGB(T,P.fs.v*E)),P.fb.propType&&(T=E.length?addBrightnessToRGB(T,P.fb.v*E[0]):addBrightnessToRGB(T,P.fb.v*E))}}for(B=0;B<D;B+=1)(P=f[B].a).p.propType&&(E=f[B].s.getMult(u[x].anIndexes[B],c.a[B].s.totalChars),this._hasMaskedPath?E.length?d.translate(0,P.p.v[1]*E[0],-P.p.v[2]*E[1]):d.translate(0,P.p.v[1]*E,-P.p.v[2]*E):E.length?d.translate(P.p.v[0]*E[0],P.p.v[1]*E[1],-P.p.v[2]*E[2]):d.translate(P.p.v[0]*E,P.p.v[1]*E,-P.p.v[2]*E));if(t.strokeWidthAnim&&(W=A<0?0:A),t.strokeColorAnim&&($="rgb("+Math.round(255*_[0])+","+Math.round(255*_[1])+","+Math.round(255*_[2])+")"),t.fillColorAnim&&t.fc&&(Y="rgb("+Math.round(255*T[0])+","+Math.round(255*T[1])+","+Math.round(255*T[2])+")"),this._hasMaskedPath)d.translate(0,-t.ls),d.translate(0,m[1]*K*.01+Z,0),this._pathData.p.v&&(X=(i.point[1]-n.point[1])/(i.point[0]-n.point[0]),X=180*Math.atan(X)/Math.PI,i.point[0]<n.point[0]&&(X+=180),d.rotate(-X*Math.PI/180)),d.translate(j,q,0),e-=m[0]*u[x].an*.005,u[x+1]&&F!==u[x+1].ind&&(e=(e+=u[x].an/2)+.001*t.tr*t.finalSize);else{switch(d.translate(k,Z,0),t.ps&&d.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:d.translate(u[x].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[u[x].line]),0,0);break;case 2:d.translate(u[x].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[u[x].line])/2,0,0)}d.translate(0,-t.ls),d.translate(S,0,0),d.translate(m[0]*u[x].an*.005,m[1]*K*.01,0),k+=u[x].l+.001*t.tr*t.finalSize}"html"===O?rt=d.toCSS():"svg"===O?rt=d.to2dCSS():st=[d.props[0],d.props[1],d.props[2],d.props[3],d.props[4],d.props[5],d.props[6],d.props[7],d.props[8],d.props[9],d.props[10],d.props[11],d.props[12],d.props[13],d.props[14],d.props[15]],J=C}N<=x?(H=new LetterProps(J,W,$,Y,rt,st),this.renderedLetters.push(H),N+=1,this.lettersChangedFlag=!0):(H=this.renderedLetters[x],this.lettersChangedFlag=H.update(J,W,$,Y,rt,st)||this.lettersChangedFlag)}}},TextAnimatorProperty.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},TextAnimatorProperty.prototype.mHelper=new Matrix,TextAnimatorProperty.prototype.defaultPropsArray=[],extendPrototype([DynamicPropertyContainer],TextAnimatorProperty),ITextElement.prototype.initElement=function(t,e,i){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,i),this.textProperty=new TextProperty(this,t.t,this.dynamicProperties),this.textAnimator=new TextAnimatorProperty(t.t,this.renderType,this),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},ITextElement.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},ITextElement.prototype.createPathShape=function(t,e){for(var i,r=e.length,s="",a=0;a<r;a+=1)"sh"===e[a].ty&&(i=e[a].ks.k,s+=buildShapeString(i,i.i.length,!0,t));return s},ITextElement.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},ITextElement.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},ITextElement.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},ITextElement.prototype.applyTextPropertiesToMatrix=function(t,e,i,r,s){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i])/2,0,0)}e.translate(r,s,0)},ITextElement.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},ITextElement.prototype.emptyProp=new LetterProps,ITextElement.prototype.destroy=function(){},ITextElement.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var emptyShapeData={shapes:[]};function SVGTextLottieElement(t,e,i){this.textSpans=[],this.renderType="svg",this.initElement(t,e,i)}function ISolidElement(t,e,i){this.initElement(t,e,i)}function NullElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initFrame(),this.initTransform(t,e,i),this.initHierarchy()}function SVGRendererBase(){}function ICompElement(){}function SVGCompElement(t,e,i){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function SVGRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=createNS("svg");var t="",i=(e&&e.title&&(i=createNS("title"),r=createElementID(),i.setAttribute("id",r),i.textContent=e.title,this.svgElement.appendChild(i),t+=r),e&&e.description&&(i=createNS("desc"),r=createElementID(),i.setAttribute("id",r),i.textContent=e.description,this.svgElement.appendChild(i),t+=" "+r),t&&this.svgElement.setAttribute("aria-labelledby",t),createNS("defs")),r=(this.svgElement.appendChild(i),createNS("g"));this.svgElement.appendChild(r),this.layerElement=r,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:i,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}function ShapeTransformManager(){this.sequences={},this.sequenceList=[],this.transform_key_count=0}extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],SVGTextLottieElement),SVGTextLottieElement.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=createNS("text"))},SVGTextLottieElement.prototype.buildTextContents=function(t){for(var e=0,i=t.length,r=[],s="";e<i;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(r.push(s),s=""):s+=t[e],e+=1;return r.push(s),r},SVGTextLottieElement.prototype.buildShapeData=function(t,e){var i;return t.shapes&&t.shapes.length&&(i=t.shapes[0]).it&&(i=i.it[i.it.length-1]).s&&(i.s.k[0]=e,i.s.k[1]=e),t},SVGTextLottieElement.prototype.buildNewText=function(){this.addDynamicProperty(this);var t,e,i=this.textProperty.currentData,r=(this.renderedLetters=createSizedArray(i?i.l.length:0),i.fc?this.layerElement.setAttribute("fill",this.buildColor(i.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),i.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(i.sc)),this.layerElement.setAttribute("stroke-width",i.sw)),this.layerElement.setAttribute("font-size",i.finalSize),this.globalData.fontManager.getFontByName(i.f)),s=(r.fClass?this.layerElement.setAttribute("class",r.fClass):(this.layerElement.setAttribute("font-family",r.fFamily),t=i.fWeight,e=i.fStyle,this.layerElement.setAttribute("font-style",e),this.layerElement.setAttribute("font-weight",t)),this.layerElement.setAttribute("aria-label",i.t),i.l||[]),a=!!this.globalData.fontManager.chars,n=(x=s.length,this.mHelper),o=this.data.singleShape,h=0,l=0,p=!0,m=.001*i.tr*i.finalSize;if(!o||a||i.sz){var f,c,d,u,y=this.textSpans.length;for(P=0;P<x;P+=1)this.textSpans[P]||(this.textSpans[P]={span:null,childSpan:null,glyph:null}),a&&o&&0!==P||(f=P<y?this.textSpans[P].span:createNS(a?"g":"text"),y<=P&&(f.setAttribute("stroke-linecap","butt"),f.setAttribute("stroke-linejoin","round"),f.setAttribute("stroke-miterlimit","4"),this.textSpans[P].span=f,a&&(u=createNS("g"),f.appendChild(u),this.textSpans[P].childSpan=u),this.textSpans[P].span=f,this.layerElement.appendChild(f)),f.style.display="inherit"),n.reset(),o&&(s[P].n&&(h=-m,l=l+i.yOffset+(p?1:0),p=!1),this.applyTextPropertiesToMatrix(i,n,s[P].line,h,l),h=h+(s[P].l||0)+m),a?(c=1===(u=this.globalData.fontManager.getCharData(i.finalText[P],r.fStyle,this.globalData.fontManager.getFontByName(i.f).fFamily)).t?new SVGCompElement(u.data,this.globalData,this):(c=emptyShapeData,new SVGShapeElement(c=u.data&&u.data.shapes?this.buildShapeData(u.data,i.finalSize):c,this.globalData,this)),this.textSpans[P].glyph&&(d=this.textSpans[P].glyph,this.textSpans[P].childSpan.removeChild(d.layerElement),d.destroy()),(this.textSpans[P].glyph=c)._debug=!0,c.prepareFrame(0),c.renderFrame(),this.textSpans[P].childSpan.appendChild(c.layerElement),1===u.t&&this.textSpans[P].childSpan.setAttribute("transform","scale("+i.finalSize/100+","+i.finalSize/100+")")):(o&&f.setAttribute("transform","translate("+n.props[12]+","+n.props[13]+")"),f.textContent=s[P].val,f.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"));o&&f&&f.setAttribute("d","")}else{var g=this.textContainer,v="start";switch(i.j){case 1:v="end";break;case 2:v="middle";break;default:v="start"}g.setAttribute("text-anchor",v),g.setAttribute("letter-spacing",m);for(var b=this.buildTextContents(i.finalText),x=b.length,l=i.ps?i.ps[1]+i.ascent:0,P=0;P<x;P+=1)(f=this.textSpans[P].span||createNS("tspan")).textContent=b[P],f.setAttribute("x",0),f.setAttribute("y",l),f.style.display="inherit",g.appendChild(f),this.textSpans[P]||(this.textSpans[P]={span:null,glyph:null}),this.textSpans[P].span=f,l+=i.finalLineHeight;this.layerElement.appendChild(g)}for(;P<this.textSpans.length;)this.textSpans[P].span.style.display="none",P+=1;this._sizeChanged=!0},SVGTextLottieElement.prototype.sourceRectAtTime=function(){var t;return this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged&&(this._sizeChanged=!1,t=this.layerElement.getBBox(),this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}),this.bbox},SVGTextLottieElement.prototype.getValue=function(){var t,e,i=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<i;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf)&&(this._mdf=!0)},SVGTextLottieElement.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){this._sizeChanged=!0;for(var t,e,i,r=this.textAnimator.renderedLetters,s=this.textProperty.currentData.l,a=s.length,n=0;n<a;n+=1)s[n].n||(t=r[n],e=this.textSpans[n].span,(i=this.textSpans[n].glyph)&&i.renderFrame(),t._mdf.m&&e.setAttribute("transform",t.m),t._mdf.o&&e.setAttribute("opacity",t.o),t._mdf.sw&&e.setAttribute("stroke-width",t.sw),t._mdf.sc&&e.setAttribute("stroke",t.sc),t._mdf.fc&&e.setAttribute("fill",t.fc))}},extendPrototype([IImageElement],ISolidElement),ISolidElement.prototype.createContent=function(){var t=createNS("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},NullElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},NullElement.prototype.renderFrame=function(){},NullElement.prototype.getBaseElement=function(){return null},NullElement.prototype.destroy=function(){},NullElement.prototype.sourceRectAtTime=function(){},NullElement.prototype.hide=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement],NullElement),extendPrototype([BaseRenderer],SVGRendererBase),SVGRendererBase.prototype.createNull=function(t){return new NullElement(t,this.globalData,this)},SVGRendererBase.prototype.createShape=function(t){return new SVGShapeElement(t,this.globalData,this)},SVGRendererBase.prototype.createText=function(t){return new SVGTextLottieElement(t,this.globalData,this)},SVGRendererBase.prototype.createImage=function(t){return new IImageElement(t,this.globalData,this)},SVGRendererBase.prototype.createSolid=function(t){return new ISolidElement(t,this.globalData,this)},SVGRendererBase.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs,i=(this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t,createNS("clipPath")),r=createNS("rect"),s=(r.setAttribute("width",t.w),r.setAttribute("height",t.h),r.setAttribute("x",0),r.setAttribute("y",0),createElementID());i.setAttribute("id",s),i.appendChild(r),this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),e.appendChild(i),this.layers=t.layers,this.elements=createSizedArray(t.layers.length)},SVGRendererBase.prototype.destroy=function(){this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;for(var t=this.layers?this.layers.length:0,e=0;e<t;e+=1)this.elements[e]&&this.elements[e].destroy&&this.elements[e].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},SVGRendererBase.prototype.updateContainerSize=function(){},SVGRendererBase.prototype.findIndexByInd=function(t){for(var e=0,i=this.layers.length,e=0;e<i;e+=1)if(this.layers[e].ind===t)return e;return-1},SVGRendererBase.prototype.buildItem=function(t){var e,i,r=this.elements;r[t]||99===this.layers[t].ty||(r[t]=!0,e=this.createItem(this.layers[t]),r[t]=e,getExpressionsPlugin()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(e),e.initExpressions()),this.appendElementInPos(e,t),this.layers[t].tt&&-1!==(i="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1)&&(this.elements[i]&&!0!==this.elements[i]?(r=r[i].getMatte(this.layers[t].tt),e.setMatte(r)):(this.buildItem(i),this.addPendingElement(e))))},SVGRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,i=this.elements.length;e<i;){if(this.elements[e]===t){var r="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,r=this.elements[r].getMatte(this.layers[e].tt);t.setMatte(r);break}e+=1}}},SVGRendererBase.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var e,i=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=i-1;0<=e;--e)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<i;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},SVGRendererBase.prototype.appendElementInPos=function(t,e){t=t.getBaseElement();if(t){for(var i,r=0;r<e;)this.elements[r]&&!0!==this.elements[r]&&this.elements[r].getBaseElement()&&(i=this.elements[r].getBaseElement()),r+=1;i?this.layerElement.insertBefore(t,i):this.layerElement.appendChild(t)}},SVGRendererBase.prototype.hide=function(){this.layerElement.style.display="none"},SVGRendererBase.prototype.show=function(){this.layerElement.style.display="block"},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement,RenderableDOMElement],ICompElement),ICompElement.prototype.initElement=function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},ICompElement.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){this.tm._placeholder?this.renderedFrame=t/this.data.sr:((t=this.tm.v)===this.data.op&&(t=this.data.op-1),this.renderedFrame=t);var e,t=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),e=t-1;0<=e;--e)(this.completeLayers||this.elements[e])&&(this.elements[e].prepareFrame(this.renderedFrame-this.layers[e].st),this.elements[e]._mdf)&&(this._mdf=!0)}},ICompElement.prototype.renderInnerContent=function(){for(var t=this.layers.length,e=0;e<t;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()},ICompElement.prototype.setElements=function(t){this.elements=t},ICompElement.prototype.getElements=function(){return this.elements},ICompElement.prototype.destroyElements=function(){for(var t=this.layers.length,e=0;e<t;e+=1)this.elements[e]&&this.elements[e].destroy()},ICompElement.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},extendPrototype([SVGRendererBase,ICompElement,SVGBaseElement],SVGCompElement),SVGCompElement.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},extendPrototype([SVGRendererBase],SVGRenderer),SVGRenderer.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},ShapeTransformManager.prototype={addTransformSequence:function(t){for(var e=t.length,i="_",r=0;r<e;r+=1)i+=t[r].transform.key+"_";var s=this.sequences[i];return s||(s={transforms:[].concat(t),finalTransform:new Matrix,_mdf:!1},this.sequences[i]=s,this.sequenceList.push(s)),s},processSequence:function(t,e){for(var i=0,r=t.transforms.length,s=e;i<r&&!e;){if(t.transforms[i].transform.mProps._mdf){s=!0;break}i+=1}if(s)for(t.finalTransform.reset(),i=r-1;0<=i;--i)t.finalTransform.multiply(t.transforms[i].transform.mProps.v);t._mdf=s},processSequences:function(t){for(var e=this.sequenceList.length,i=0;i<e;i+=1)this.processSequence(this.sequenceList[i],t)},getNewKey:function(){return this.transform_key_count+=1,"_"+this.transform_key_count}};var lumaLoader=function(){var r="__lottie_element_luma_buffer",s=null,a=null,n=null;function e(){var t,e,i;s||(t=createNS("svg"),e=createNS("filter"),i=createNS("feColorMatrix"),e.setAttribute("id",r),i.setAttribute("type","matrix"),i.setAttribute("color-interpolation-filters","sRGB"),i.setAttribute("values","0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0"),e.appendChild(i),t.appendChild(e),t.setAttribute("id",r+"_svg"),featureSupport.svgLumaHidden&&(t.style.display="none"),n=t,document.body.appendChild(n),s=createTag("canvas"),(a=s.getContext("2d")).filter="url(#"+r+")",a.fillStyle="rgba(0,0,0,0)",a.fillRect(0,0,1,1))}return{load:e,get:function(t){return s||e(),s.width=t.width,s.height=t.height,a.filter="url(#"+r+")",s}}};function createCanvas(t,e){var i;return featureSupport.offscreenCanvas?new OffscreenCanvas(t,e):((i=createTag("canvas")).width=t,i.height=e,i)}var assetLoader={loadLumaCanvas:lumaLoader.load,getLumaCanvas:lumaLoader.get,createCanvas:createCanvas},registeredEffects={};function CVEffects(t){var e,i=t.data.ef?t.data.ef.length:0;for(this.filters=[],e=0;e<i;e+=1){r=null;var r,s=t.data.ef[e].ty;(r=registeredEffects[s]?new registeredEffects[s].effect(t.effectsManager.effectElements[e],t):r)&&this.filters.push(r)}this.filters.length&&t.addRenderableComponent(this)}function registerEffect(t,e){registeredEffects[t]={effect:e}}function CVMaskElement(t,e){this.data=t,this.element=e,this.masksProperties=this.data.masksProperties||[],this.viewData=createSizedArray(this.masksProperties.length);for(var i=this.masksProperties.length,r=!1,s=0;s<i;s+=1)"n"!==this.masksProperties[s].mode&&(r=!0),this.viewData[s]=ShapePropertyFactory.getShapeProp(this.element,this.masksProperties[s],3);(this.hasMasks=r)&&this.element.addRenderableComponent(this)}function CVBaseElement(){}CVEffects.prototype.renderFrame=function(t){for(var e=this.filters.length,i=0;i<e;i+=1)this.filters[i].renderFrame(t)},CVEffects.prototype.getEffects=function(t){for(var e=this.filters.length,i=[],r=0;r<e;r+=1)this.filters[r].type===t&&i.push(this.filters[r]);return i},CVMaskElement.prototype.renderFrame=function(){if(this.hasMasks){var t,e,i,r,s=this.element.finalTransform.mat,a=this.element.canvasContext,n=this.masksProperties.length;for(a.beginPath(),t=0;t<n;t+=1)if("n"!==this.masksProperties[t].mode){this.masksProperties[t].inv&&(a.moveTo(0,0),a.lineTo(this.element.globalData.compSize.w,0),a.lineTo(this.element.globalData.compSize.w,this.element.globalData.compSize.h),a.lineTo(0,this.element.globalData.compSize.h),a.lineTo(0,0)),r=this.viewData[t].v,e=s.applyToPointArray(r.v[0][0],r.v[0][1],0),a.moveTo(e[0],e[1]);for(var o=r._length,h=1;h<o;h+=1)i=s.applyToTriplePoints(r.o[h-1],r.i[h],r.v[h]),a.bezierCurveTo(i[0],i[1],i[2],i[3],i[4],i[5]);i=s.applyToTriplePoints(r.o[h-1],r.i[0],r.v[0]),a.bezierCurveTo(i[0],i[1],i[2],i[3],i[4],i[5])}this.element.globalData.renderer.save(!0),a.clip()}},CVMaskElement.prototype.getMaskProperty=MaskElement.prototype.getMaskProperty,CVMaskElement.prototype.destroy=function(){this.element=null};var operationsMap={1:"source-in",2:"source-out",3:"source-in",4:"source-out"};function CVShapeData(t,e,i,r){this.styledShapes=[],this.tr=[0,0,0,0,0,0];for(var s,a=4,n=("rc"===e.ty?a=5:"el"===e.ty?a=6:"sr"===e.ty&&(a=7),this.sh=ShapePropertyFactory.getShapeProp(t,e,a,t),i.length),o=0;o<n;o+=1)i[o].closed||(s={transforms:r.addTransformSequence(i[o].transforms),trNodes:[]},this.styledShapes.push(s),i[o].elements.push(s))}function CVShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.itemsData=[],this.prevViewData=[],this.shapeModifiers=[],this.processedElements=[],this.transformsManager=new ShapeTransformManager,this.initElement(t,e,i)}function CVTextElement(t,e,i){this.textSpans=[],this.yOffset=0,this.fillColorAnim=!1,this.strokeColorAnim=!1,this.strokeWidthAnim=!1,this.stroke=!1,this.fill=!1,this.justifyOffset=0,this.currentRender=null,this.renderType="canvas",this.values={fill:"rgba(0,0,0,0)",stroke:"rgba(0,0,0,0)",sWidth:0,fValue:""},this.initElement(t,e,i)}function CVImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.img=e.imageLoader.getAsset(this.assetData),this.initElement(t,e,i)}function CVSolidElement(t,e,i){this.initElement(t,e,i)}function CanvasRendererBase(){}function CanvasContext(){this.opacity=-1,this.transform=createTypedArray("float32",16),this.fillStyle="",this.strokeStyle="",this.lineWidth="",this.lineCap="",this.lineJoin="",this.miterLimit="",this.id=Math.random()}function CVContextData(){this.stack=[],this.cArrPos=0,this.cTr=new Matrix;for(var t=0;t<15;t+=1){var e=new CanvasContext;this.stack[t]=e}this._length=15,this.nativeContext=null,this.transformMat=new Matrix,this.currentOpacity=1,this.currentFillStyle="",this.appliedFillStyle="",this.currentStrokeStyle="",this.appliedStrokeStyle="",this.currentLineWidth="",this.appliedLineWidth="",this.currentLineCap="",this.appliedLineCap="",this.currentLineJoin="",this.appliedLineJoin="",this.appliedMiterLimit="",this.currentMiterLimit=""}function CVCompElement(t,e,i){this.completeLayers=!1,this.layers=t.layers,this.pendingElements=[],this.elements=createSizedArray(this.layers.length),this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function CanvasRenderer(t,e){this.animationItem=t,this.renderConfig={clearCanvas:!e||void 0===e.clearCanvas||e.clearCanvas,context:e&&e.context||null,progressiveLoad:e&&e.progressiveLoad||!1,preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",className:e&&e.className||"",id:e&&e.id||"",runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.renderConfig.dpr=e&&e.dpr||1,this.animationItem.wrapper&&(this.renderConfig.dpr=e&&e.dpr||window.devicePixelRatio||1),this.renderedFrame=-1,this.globalData={frameNum:-1,_mdf:!1,renderConfig:this.renderConfig,currentGlobalAlpha:-1},this.contextData=new CVContextData,this.elements=[],this.pendingElements=[],this.transformMat=new Matrix,this.completeLayers=!1,this.rendererType="canvas",this.renderConfig.clearCanvas&&(this.ctxTransform=this.contextData.transform.bind(this.contextData),this.ctxOpacity=this.contextData.opacity.bind(this.contextData),this.ctxFillStyle=this.contextData.fillStyle.bind(this.contextData),this.ctxStrokeStyle=this.contextData.strokeStyle.bind(this.contextData),this.ctxLineWidth=this.contextData.lineWidth.bind(this.contextData),this.ctxLineCap=this.contextData.lineCap.bind(this.contextData),this.ctxLineJoin=this.contextData.lineJoin.bind(this.contextData),this.ctxMiterLimit=this.contextData.miterLimit.bind(this.contextData),this.ctxFill=this.contextData.fill.bind(this.contextData),this.ctxFillRect=this.contextData.fillRect.bind(this.contextData),this.ctxStroke=this.contextData.stroke.bind(this.contextData),this.save=this.contextData.save.bind(this.contextData))}function HBaseElement(){}function HSolidElement(t,e,i){this.initElement(t,e,i)}function HShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.shapesContainer=createNS("g"),this.initElement(t,e,i),this.prevViewData=[],this.currentBBox={x:999999,y:-999999,h:0,w:0}}function HTextElement(t,e,i){this.textSpans=[],this.textPaths=[],this.currentBBox={x:999999,y:-999999,h:0,w:0},this.renderType="svg",this.isMasked=!1,this.initElement(t,e,i)}function HCameraElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initHierarchy();e=PropertyFactory.getProp;if(this.pe=e(this,t.pe,0,0,this),t.ks.p.s?(this.px=e(this,t.ks.p.x,1,0,this),this.py=e(this,t.ks.p.y,1,0,this),this.pz=e(this,t.ks.p.z,1,0,this)):this.p=e(this,t.ks.p,1,0,this),t.ks.a&&(this.a=e(this,t.ks.a,1,0,this)),t.ks.or.k.length&&t.ks.or.k[0].to)for(var r=t.ks.or.k.length,s=0;s<r;s+=1)t.ks.or.k[s].to=null,t.ks.or.k[s].ti=null;this.or=e(this,t.ks.or,1,degToRads,this),this.or.sh=!0,this.rx=e(this,t.ks.rx,0,degToRads,this),this.ry=e(this,t.ks.ry,0,degToRads,this),this.rz=e(this,t.ks.rz,0,degToRads,this),this.mat=new Matrix,this._prevMat=new Matrix,this._isFirstFrame=!0,this.finalTransform={mProp:this}}function HImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.initElement(t,e,i)}function HybridRendererBase(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"}},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}function HCompElement(t,e,i){this.layers=t.layers,this.supports3d=!t.hasMask,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function HybridRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"},runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}CVBaseElement.prototype={createElements:function(){},initRendererElement:function(){},createContainerElements:function(){var t,e;1<=this.data.tt&&(this.buffers=[],t=this.globalData.canvasContext,e=assetLoader.createCanvas(t.canvas.width,t.canvas.height),this.buffers.push(e),e=assetLoader.createCanvas(t.canvas.width,t.canvas.height),this.buffers.push(e),3<=this.data.tt)&&!document._isProxy&&assetLoader.loadLumaCanvas(),this.canvasContext=this.globalData.canvasContext,this.transformCanvas=this.globalData.transformCanvas,this.renderableEffectsManager=new CVEffects(this),this.searchEffectTransforms()},createContent:function(){},setBlendMode:function(){var t,e=this.globalData;e.blendMode!==this.data.bm&&(e.blendMode=this.data.bm,t=getBlendMode(this.data.bm),e.canvasContext.globalCompositeOperation=t)},createRenderableComponents:function(){this.maskManager=new CVMaskElement(this.data,this),this.transformEffects=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT)},hideElement:function(){this.hidden||this.isInRange&&!this.isTransparent||(this.hidden=!0)},showElement:function(){this.isInRange&&!this.isTransparent&&(this.hidden=!1,this._isFirstFrame=!0,this.maskManager._isFirstFrame=!0)},clearCanvas:function(t){t.clearRect(this.transformCanvas.tx,this.transformCanvas.ty,this.transformCanvas.w*this.transformCanvas.sx,this.transformCanvas.h*this.transformCanvas.sy)},prepareLayer:function(){var t;1<=this.data.tt&&(t=this.buffers[0].getContext("2d"),this.clearCanvas(t),t.drawImage(this.canvasContext.canvas,0,0),this.currentTransform=this.canvasContext.getTransform(),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform))},exitLayer:function(){var t,e;1<=this.data.tt&&(e=(t=this.buffers[1]).getContext("2d"),this.clearCanvas(e),e.drawImage(this.canvasContext.canvas,0,0),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform),this.comp.getElementById("tp"in this.data?this.data.tp:this.data.ind-1).renderFrame(!0),this.canvasContext.setTransform(1,0,0,1,0,0),3<=this.data.tt&&!document._isProxy&&((e=assetLoader.getLumaCanvas(this.canvasContext.canvas)).getContext("2d").drawImage(this.canvasContext.canvas,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.drawImage(e,0,0)),this.canvasContext.globalCompositeOperation=operationsMap[this.data.tt],this.canvasContext.drawImage(t,0,0),this.canvasContext.globalCompositeOperation="destination-over",this.canvasContext.drawImage(this.buffers[0],0,0),this.canvasContext.setTransform(this.currentTransform),this.canvasContext.globalCompositeOperation="source-over")},renderFrame:function(t){this.hidden||this.data.hd||(1!==this.data.td||t)&&(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.setBlendMode(),t=0===this.data.ty,this.prepareLayer(),this.globalData.renderer.save(t),this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props),this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity),this.renderInnerContent(),this.globalData.renderer.restore(t),this.exitLayer(),this.maskManager.hasMasks&&this.globalData.renderer.restore(!0),this._isFirstFrame)&&(this._isFirstFrame=!1)},destroy:function(){this.canvasContext=null,this.data=null,this.globalData=null,this.maskManager.destroy()},mHelper:new Matrix},CVBaseElement.prototype.hide=CVBaseElement.prototype.hideElement,CVBaseElement.prototype.show=CVBaseElement.prototype.showElement,CVShapeData.prototype.setAsAnimated=SVGShapeData.prototype.setAsAnimated,extendPrototype([BaseElement,TransformElement,CVBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableElement],CVShapeElement),CVShapeElement.prototype.initElement=RenderableDOMElement.prototype.initElement,CVShapeElement.prototype.transformHelper={opacity:1,_opMdf:!1},CVShapeElement.prototype.dashResetter=[],CVShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[])},CVShapeElement.prototype.createStyleElement=function(t,e){var i,e={data:t,type:t.ty,preTransforms:this.transformsManager.addTransformSequence(e),transforms:[],elements:[],closed:!0===t.hd},r={};return"fl"===t.ty||"st"===t.ty?(r.c=PropertyFactory.getProp(this,t.c,1,255,this),r.c.k||(e.co="rgb("+bmFloor(r.c.v[0])+","+bmFloor(r.c.v[1])+","+bmFloor(r.c.v[2])+")")):"gf"!==t.ty&&"gs"!==t.ty||(r.s=PropertyFactory.getProp(this,t.s,1,null,this),r.e=PropertyFactory.getProp(this,t.e,1,null,this),r.h=PropertyFactory.getProp(this,t.h||{k:0},0,.01,this),r.a=PropertyFactory.getProp(this,t.a||{k:0},0,degToRads,this),r.g=new GradientProperty(this,t.g,this)),r.o=PropertyFactory.getProp(this,t.o,0,.01,this),"st"===t.ty||"gs"===t.ty?(e.lc=lineCapEnum[t.lc||2],e.lj=lineJoinEnum[t.lj||2],1==t.lj&&(e.ml=t.ml),r.w=PropertyFactory.getProp(this,t.w,0,null,this),r.w.k||(e.wi=r.w.v),t.d&&(i=new DashProperty(this,t.d,"canvas",this),r.d=i,r.d.k||(e.da=r.d.dashArray,e.do=r.d.dashoffset[0]))):e.r=2===t.r?"evenodd":"nonzero",this.stylesList.push(e),r.style=e,r},CVShapeElement.prototype.createGroupElement=function(){return{it:[],prevViewData:[]}},CVShapeElement.prototype.createTransformElement=function(t){return{transform:{opacity:1,_opMdf:!1,key:this.transformsManager.getNewKey(),op:PropertyFactory.getProp(this,t.o,0,.01,this),mProps:TransformPropertyFactory.getTransformProperty(this,t,this)}}},CVShapeElement.prototype.createShapeElement=function(t){t=new CVShapeData(this,t,this.stylesList,this.transformsManager);return this.shapes.push(t),this.addShapeToModifiers(t),t},CVShapeElement.prototype.reloadShapes=function(){this._isFirstFrame=!0;for(var t=this.itemsData.length,e=0;e<t;e+=1)this.prevViewData[e]=this.itemsData[e];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[]),t=this.dynamicProperties.length,e=0;e<t;e+=1)this.dynamicProperties[e].getValue();this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame)},CVShapeElement.prototype.addTransformToStyleList=function(t){for(var e=this.stylesList.length,i=0;i<e;i+=1)this.stylesList[i].closed||this.stylesList[i].transforms.push(t)},CVShapeElement.prototype.removeTransformFromStyleList=function(){for(var t=this.stylesList.length,e=0;e<t;e+=1)this.stylesList[e].closed||this.stylesList[e].transforms.pop()},CVShapeElement.prototype.closeStyles=function(t){for(var e=t.length,i=0;i<e;i+=1)t[i].closed=!0},CVShapeElement.prototype.searchShapes=function(t,e,i,r,s){for(var a,n,o,h,l,p=t.length-1,m=[],f=[],c=[].concat(s),d=p;0<=d;--d){if((o=this.searchProcessedElement(t[d]))?e[d]=i[o-1]:t[d]._shouldRender=r,"fl"===t[d].ty||"st"===t[d].ty||"gf"===t[d].ty||"gs"===t[d].ty)o?e[d].style.closed=!1:e[d]=this.createStyleElement(t[d],c),m.push(e[d].style);else if("gr"===t[d].ty){if(o)for(n=e[d].it.length,a=0;a<n;a+=1)e[d].prevViewData[a]=e[d].it[a];else e[d]=this.createGroupElement(t[d]);this.searchShapes(t[d].it,e[d].it,e[d].prevViewData,r,c)}else"tr"===t[d].ty?(o||(l=this.createTransformElement(t[d]),e[d]=l),c.push(e[d]),this.addTransformToStyleList(e[d])):"sh"===t[d].ty||"rc"===t[d].ty||"el"===t[d].ty||"sr"===t[d].ty?o||(e[d]=this.createShapeElement(t[d])):"tm"===t[d].ty||"rd"===t[d].ty||"pb"===t[d].ty||"zz"===t[d].ty||"op"===t[d].ty?(o?(h=e[d]).closed=!1:((h=ShapeModifiers.getModifier(t[d].ty)).init(this,t[d]),e[d]=h,this.shapeModifiers.push(h)),f.push(h)):"rp"===t[d].ty&&(o?(h=e[d]).closed=!0:(h=ShapeModifiers.getModifier(t[d].ty),(e[d]=h).init(this,t,d,e),this.shapeModifiers.push(h),r=!1),f.push(h));this.addProcessedElement(t[d],d+1)}for(this.removeTransformFromStyleList(),this.closeStyles(m),p=f.length,d=0;d<p;d+=1)f[d].closed=!0},CVShapeElement.prototype.renderInnerContent=function(){this.transformHelper.opacity=1,this.transformHelper._opMdf=!1,this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame),this.renderShape(this.transformHelper,this.shapesData,this.itemsData,!0)},CVShapeElement.prototype.renderShapeTransform=function(t,e){(t._opMdf||e.op._mdf||this._isFirstFrame)&&(e.opacity=t.opacity,e.opacity*=e.op.v,e._opMdf=!0)},CVShapeElement.prototype.drawLayer=function(){for(var t,e,i,r,s,a,n,o,h=this.stylesList.length,l=this.globalData.renderer,p=this.globalData.canvasContext,m=0;m<h;m+=1)if(("st"!==(n=(o=this.stylesList[m]).type)&&"gs"!==n||0!==o.wi)&&o.data._shouldRender&&0!==o.coOp&&0!==this.globalData.currentGlobalAlpha){for(l.save(),s=o.elements,"st"===n||"gs"===n?(l.ctxStrokeStyle("st"===n?o.co:o.grd),l.ctxLineWidth(o.wi),l.ctxLineCap(o.lc),l.ctxLineJoin(o.lj),l.ctxMiterLimit(o.ml||0)):l.ctxFillStyle("fl"===n?o.co:o.grd),l.ctxOpacity(o.coOp),"st"!==n&&"gs"!==n&&p.beginPath(),l.ctxTransform(o.preTransforms.finalTransform.props),e=s.length,t=0;t<e;t+=1){for("st"!==n&&"gs"!==n||(p.beginPath(),o.da&&(p.setLineDash(o.da),p.lineDashOffset=o.do)),r=(a=s[t].trNodes).length,i=0;i<r;i+=1)"m"===a[i].t?p.moveTo(a[i].p[0],a[i].p[1]):"c"===a[i].t?p.bezierCurveTo(a[i].pts[0],a[i].pts[1],a[i].pts[2],a[i].pts[3],a[i].pts[4],a[i].pts[5]):p.closePath();"st"!==n&&"gs"!==n||(l.ctxStroke(),o.da&&p.setLineDash(this.dashResetter))}"st"!==n&&"gs"!==n&&this.globalData.renderer.ctxFill(o.r),l.restore()}},CVShapeElement.prototype.renderShape=function(t,e,i,r){for(var s=t,a=e.length-1;0<=a;--a)"tr"===e[a].ty?(s=i[a].transform,this.renderShapeTransform(t,s)):"sh"===e[a].ty||"el"===e[a].ty||"rc"===e[a].ty||"sr"===e[a].ty?this.renderPath(e[a],i[a]):"fl"===e[a].ty?this.renderFill(e[a],i[a],s):"st"===e[a].ty?this.renderStroke(e[a],i[a],s):"gf"===e[a].ty||"gs"===e[a].ty?this.renderGradientFill(e[a],i[a],s):"gr"===e[a].ty?this.renderShape(s,e[a].it,i[a].it):e[a].ty;r&&this.drawLayer()},CVShapeElement.prototype.renderStyledShape=function(t,e){if(this._isFirstFrame||e._mdf||t.transforms._mdf){for(var i,r,s=t.trNodes,a=e.paths,n=a._length,o=(s.length=0,t.transforms.finalTransform),h=0;h<n;h+=1){var l=a.shapes[h];if(l&&l.v){for(r=l._length,i=1;i<r;i+=1)1===i&&s.push({t:"m",p:o.applyToPointArray(l.v[0][0],l.v[0][1],0)}),s.push({t:"c",pts:o.applyToTriplePoints(l.o[i-1],l.i[i],l.v[i])});1===r&&s.push({t:"m",p:o.applyToPointArray(l.v[0][0],l.v[0][1],0)}),l.c&&r&&(s.push({t:"c",pts:o.applyToTriplePoints(l.o[i-1],l.i[0],l.v[0])}),s.push({t:"z"}))}}t.trNodes=s}},CVShapeElement.prototype.renderPath=function(t,e){if(!0!==t.hd&&t._shouldRender)for(var i=e.styledShapes.length,r=0;r<i;r+=1)this.renderStyledShape(e.styledShapes[r],e.sh)},CVShapeElement.prototype.renderFill=function(t,e,i){var r=e.style;(e.c._mdf||this._isFirstFrame)&&(r.co="rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i._opMdf||this._isFirstFrame)&&(r.coOp=e.o.v*i.opacity)},CVShapeElement.prototype.renderGradientFill=function(t,e,i){var r=e.style;if(!r.grd||e.g._mdf||e.s._mdf||e.e._mdf||1!==t.t&&(e.h._mdf||e.a._mdf)){for(var s,a,n,o,h=this.globalData.canvasContext,l=e.s.v,p=e.e.v,m=(o=1===t.t?h.createLinearGradient(l[0],l[1],p[0],p[1]):(s=Math.sqrt(Math.pow(l[0]-p[0],2)+Math.pow(l[1]-p[1],2)),p=Math.atan2(p[1]-l[1],p[0]-l[0]),1<=(a=e.h.v)?a=.99:a<=-1&&(a=-.99),a=s*a,n=Math.cos(p+e.a.v)*a+l[0],p=Math.sin(p+e.a.v)*a+l[1],h.createRadialGradient(n,p,0,l[0],l[1],s)),t.g.p),f=e.g.c,c=1,d=0;d<m;d+=1)e.g._hasOpacity&&e.g._collapsable&&(c=e.g.o[2*d+1]),o.addColorStop(f[4*d]/100,"rgba("+f[4*d+1]+","+f[4*d+2]+","+f[4*d+3]+","+c+")");r.grd=o}r.coOp=e.o.v*i.opacity},CVShapeElement.prototype.renderStroke=function(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||this._isFirstFrame)&&(r.da=s.dashArray,r.do=s.dashoffset[0]),(e.c._mdf||this._isFirstFrame)&&(r.co="rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i._opMdf||this._isFirstFrame)&&(r.coOp=e.o.v*i.opacity),(e.w._mdf||this._isFirstFrame)&&(r.wi=e.w.v)},CVShapeElement.prototype.destroy=function(){this.shapesData=null,this.globalData=null,this.canvasContext=null,this.stylesList.length=0,this.itemsData.length=0},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement,ITextElement],CVTextElement),CVTextElement.prototype.tHelper=createTag("canvas").getContext("2d"),CVTextElement.prototype.buildNewText=function(){for(var t,e,i,r,s,a,n,o,h=this.textProperty.currentData,l=(this.renderedLetters=createSizedArray(h.l?h.l.length:0),!1),l=(h.fc?(l=!0,this.values.fill=this.buildColor(h.fc)):this.values.fill="rgba(0,0,0,0)",this.fill=l,!1),p=(h.sc&&(l=!0,this.values.stroke=this.buildColor(h.sc),this.values.sWidth=h.sw),this.globalData.fontManager.getFontByName(h.f)),m=h.l,f=this.mHelper,c=(this.stroke=l,this.values.fValue=h.finalSize+"px "+this.globalData.fontManager.getFontByName(h.f).fFamily,t=h.finalText.length,this.data.singleShape),d=.001*h.tr*h.finalSize,u=0,y=0,g=!0,v=0,b=0;b<t;b+=1){e=(e=this.globalData.fontManager.getCharData(h.finalText[b],p.fStyle,this.globalData.fontManager.getFontByName(h.f).fFamily))&&e.data||{},f.reset(),c&&m[b].n&&(u=-d,y=y+h.yOffset+(g?1:0),g=!1),a=(s=e.shapes?e.shapes[0].it:[]).length,f.scale(h.finalSize/100,h.finalSize/100),c&&this.applyTextPropertiesToMatrix(h,f,m[b].line,u,y);for(var x=createSizedArray(a-1),P=0,E=0;E<a;E+=1)if("sh"===s[E].ty){for(r=s[E].ks.k.i.length,n=s[E].ks.k,o=[],i=1;i<r;i+=1)1===i&&o.push(f.applyToX(n.v[0][0],n.v[0][1],0),f.applyToY(n.v[0][0],n.v[0][1],0)),o.push(f.applyToX(n.o[i-1][0],n.o[i-1][1],0),f.applyToY(n.o[i-1][0],n.o[i-1][1],0),f.applyToX(n.i[i][0],n.i[i][1],0),f.applyToY(n.i[i][0],n.i[i][1],0),f.applyToX(n.v[i][0],n.v[i][1],0),f.applyToY(n.v[i][0],n.v[i][1],0));o.push(f.applyToX(n.o[i-1][0],n.o[i-1][1],0),f.applyToY(n.o[i-1][0],n.o[i-1][1],0),f.applyToX(n.i[0][0],n.i[0][1],0),f.applyToY(n.i[0][0],n.i[0][1],0),f.applyToX(n.v[0][0],n.v[0][1],0),f.applyToY(n.v[0][0],n.v[0][1],0)),x[P]=o,P+=1}c&&(u=u+m[b].l+d),this.textSpans[v]?this.textSpans[v].elem=x:this.textSpans[v]={elem:x},v+=1}},CVTextElement.prototype.renderInnerContent=function(){this.validateText();this.canvasContext.font=this.values.fValue,this.globalData.renderer.ctxLineCap("butt"),this.globalData.renderer.ctxLineJoin("miter"),this.globalData.renderer.ctxMiterLimit(4),this.data.singleShape||this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag);for(var t,e,i,r,s,a,n,o=this.textAnimator.renderedLetters,h=this.textProperty.currentData.l,l=h.length,p=null,m=null,f=null,c=this.globalData.renderer,d=0;d<l;d+=1)if(!h[d].n){if((s=o[d])&&(c.save(),c.ctxTransform(s.p),c.ctxOpacity(s.o)),this.fill){for(s&&s.fc?p!==s.fc&&(c.ctxFillStyle(s.fc),p=s.fc):p!==this.values.fill&&(p=this.values.fill,c.ctxFillStyle(this.values.fill)),e=(a=this.textSpans[d].elem).length,this.globalData.canvasContext.beginPath(),t=0;t<e;t+=1)for(r=(n=a[t]).length,this.globalData.canvasContext.moveTo(n[0],n[1]),i=2;i<r;i+=6)this.globalData.canvasContext.bezierCurveTo(n[i],n[i+1],n[i+2],n[i+3],n[i+4],n[i+5]);this.globalData.canvasContext.closePath(),c.ctxFill()}if(this.stroke){for(s&&s.sw?f!==s.sw&&(f=s.sw,c.ctxLineWidth(s.sw)):f!==this.values.sWidth&&(f=this.values.sWidth,c.ctxLineWidth(this.values.sWidth)),s&&s.sc?m!==s.sc&&(m=s.sc,c.ctxStrokeStyle(s.sc)):m!==this.values.stroke&&(m=this.values.stroke,c.ctxStrokeStyle(this.values.stroke)),e=(a=this.textSpans[d].elem).length,this.globalData.canvasContext.beginPath(),t=0;t<e;t+=1)for(r=(n=a[t]).length,this.globalData.canvasContext.moveTo(n[0],n[1]),i=2;i<r;i+=6)this.globalData.canvasContext.bezierCurveTo(n[i],n[i+1],n[i+2],n[i+3],n[i+4],n[i+5]);this.globalData.canvasContext.closePath(),c.ctxStroke()}s&&this.globalData.renderer.restore()}},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVImageElement),CVImageElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVImageElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVImageElement.prototype.createContent=function(){var t,e,i,r,s,a,n,o,h;!this.img.width||this.assetData.w===this.img.width&&this.assetData.h===this.img.height||((t=createTag("canvas")).width=this.assetData.w,t.height=this.assetData.h,e=t.getContext("2d"),i=this.img.width,r=this.img.height,a=this.assetData.w/this.assetData.h,h=this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio,a<(s=i/r)&&"xMidYMid slice"===h||s<a&&"xMidYMid slice"!==h?n=(o=r)*a:o=(n=i)/a,e.drawImage(this.img,(i-n)/2,(r-o)/2,n,o,0,0,this.assetData.w,this.assetData.h),this.img=t)},CVImageElement.prototype.renderInnerContent=function(){this.canvasContext.drawImage(this.img,0,0)},CVImageElement.prototype.destroy=function(){this.img=null},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVSolidElement),CVSolidElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVSolidElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVSolidElement.prototype.renderInnerContent=function(){this.globalData.renderer.ctxFillStyle(this.data.sc),this.globalData.renderer.ctxFillRect(0,0,this.data.sw,this.data.sh)},extendPrototype([BaseRenderer],CanvasRendererBase),CanvasRendererBase.prototype.createShape=function(t){return new CVShapeElement(t,this.globalData,this)},CanvasRendererBase.prototype.createText=function(t){return new CVTextElement(t,this.globalData,this)},CanvasRendererBase.prototype.createImage=function(t){return new CVImageElement(t,this.globalData,this)},CanvasRendererBase.prototype.createSolid=function(t){return new CVSolidElement(t,this.globalData,this)},CanvasRendererBase.prototype.createNull=SVGRenderer.prototype.createNull,CanvasRendererBase.prototype.ctxTransform=function(t){1===t[0]&&0===t[1]&&0===t[4]&&1===t[5]&&0===t[12]&&0===t[13]||this.canvasContext.transform(t[0],t[1],t[4],t[5],t[12],t[13])},CanvasRendererBase.prototype.ctxOpacity=function(t){this.canvasContext.globalAlpha*=t<0?0:t},CanvasRendererBase.prototype.ctxFillStyle=function(t){this.canvasContext.fillStyle=t},CanvasRendererBase.prototype.ctxStrokeStyle=function(t){this.canvasContext.strokeStyle=t},CanvasRendererBase.prototype.ctxLineWidth=function(t){this.canvasContext.lineWidth=t},CanvasRendererBase.prototype.ctxLineCap=function(t){this.canvasContext.lineCap=t},CanvasRendererBase.prototype.ctxLineJoin=function(t){this.canvasContext.lineJoin=t},CanvasRendererBase.prototype.ctxMiterLimit=function(t){this.canvasContext.miterLimit=t},CanvasRendererBase.prototype.ctxFill=function(t){this.canvasContext.fill(t)},CanvasRendererBase.prototype.ctxFillRect=function(t,e,i,r){this.canvasContext.fillRect(t,e,i,r)},CanvasRendererBase.prototype.ctxStroke=function(){this.canvasContext.stroke()},CanvasRendererBase.prototype.reset=function(){this.renderConfig.clearCanvas?this.contextData.reset():this.canvasContext.restore()},CanvasRendererBase.prototype.save=function(){this.canvasContext.save()},CanvasRendererBase.prototype.restore=function(t){this.renderConfig.clearCanvas?(t&&(this.globalData.blendMode="source-over"),this.contextData.restore(t)):this.canvasContext.restore()},CanvasRendererBase.prototype.configAnimation=function(t){var e,i;this.animationItem.wrapper?(this.animationItem.container=createTag("canvas"),(e=this.animationItem.container.style).width="100%",e.height="100%",e.transformOrigin=i="0px 0px 0px",e.mozTransformOrigin=i,e.webkitTransformOrigin=i,e["-webkit-transform"]=i,e.contentVisibility=this.renderConfig.contentVisibility,this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.animationItem.container.setAttribute("id",this.renderConfig.id)):this.canvasContext=this.renderConfig.context,this.contextData.setContext(this.canvasContext),this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.setupGlobalData(t,document.body),this.globalData.canvasContext=this.canvasContext,(this.globalData.renderer=this).globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=createSizedArray(t.layers.length),this.updateContainerSize()},CanvasRendererBase.prototype.updateContainerSize=function(t,e){var i,r,s,a,n;this.reset(),t?(r=e,this.canvasContext.canvas.width=i=t,this.canvasContext.canvas.height=r):(r=this.animationItem.wrapper&&this.animationItem.container?(i=this.animationItem.wrapper.offsetWidth,this.animationItem.wrapper.offsetHeight):(i=this.canvasContext.canvas.width,this.canvasContext.canvas.height),this.canvasContext.canvas.width=i*this.renderConfig.dpr,this.canvasContext.canvas.height=r*this.renderConfig.dpr),-1!==this.renderConfig.preserveAspectRatio.indexOf("meet")||-1!==this.renderConfig.preserveAspectRatio.indexOf("slice")?(t=(e=this.renderConfig.preserveAspectRatio.split(" "))[1]||"meet",s=(e=e[0]||"xMidYMid").substr(0,4),e=e.substr(4),(a=i/r)<(n=this.transformCanvas.w/this.transformCanvas.h)&&"meet"===t||n<a&&"slice"===t?(this.transformCanvas.sx=i/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=i/(this.transformCanvas.w/this.renderConfig.dpr)):(this.transformCanvas.sx=r/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.sy=r/(this.transformCanvas.h/this.renderConfig.dpr)),this.transformCanvas.tx="xMid"===s&&(n<a&&"meet"===t||a<n&&"slice"===t)?(i-this.transformCanvas.w*(r/this.transformCanvas.h))/2*this.renderConfig.dpr:"xMax"===s&&(n<a&&"meet"===t||a<n&&"slice"===t)?(i-this.transformCanvas.w*(r/this.transformCanvas.h))*this.renderConfig.dpr:0,this.transformCanvas.ty="YMid"===e&&(a<n&&"meet"===t||n<a&&"slice"===t)?(r-this.transformCanvas.h*(i/this.transformCanvas.w))/2*this.renderConfig.dpr:"YMax"===e&&(a<n&&"meet"===t||n<a&&"slice"===t)?(r-this.transformCanvas.h*(i/this.transformCanvas.w))*this.renderConfig.dpr:0):("none"===this.renderConfig.preserveAspectRatio?(this.transformCanvas.sx=i/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=r/(this.transformCanvas.h/this.renderConfig.dpr)):(this.transformCanvas.sx=this.renderConfig.dpr,this.transformCanvas.sy=this.renderConfig.dpr),this.transformCanvas.tx=0,this.transformCanvas.ty=0),this.transformCanvas.props=[this.transformCanvas.sx,0,0,0,0,this.transformCanvas.sy,0,0,0,0,1,0,this.transformCanvas.tx,this.transformCanvas.ty,0,1],this.ctxTransform(this.transformCanvas.props),this.canvasContext.beginPath(),this.canvasContext.rect(0,0,this.transformCanvas.w,this.transformCanvas.h),this.canvasContext.closePath(),this.canvasContext.clip(),this.renderFrame(this.renderedFrame,!0)},CanvasRendererBase.prototype.destroy=function(){this.renderConfig.clearCanvas&&this.animationItem.wrapper&&(this.animationItem.wrapper.innerText="");for(var t=(this.layers?this.layers.length:0)-1;0<=t;--t)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.globalData.canvasContext=null,this.animationItem.container=null,this.destroyed=!0},CanvasRendererBase.prototype.renderFrame=function(t,e){if((this.renderedFrame!==t||!0!==this.renderConfig.clearCanvas||e)&&!this.destroyed&&-1!==t){this.renderedFrame=t,this.globalData.frameNum=t-this.animationItem._isFirstFrame,this.globalData.frameId+=1,this.globalData._mdf=!this.renderConfig.clearCanvas||e,this.globalData.projectInterface.currentFrame=t;var i,e=this.layers.length;for(this.completeLayers||this.checkLayers(t),i=e-1;0<=i;--i)(this.completeLayers||this.elements[i])&&this.elements[i].prepareFrame(t-this.layers[i].st);if(this.globalData._mdf){for(!0===this.renderConfig.clearCanvas?this.canvasContext.clearRect(0,0,this.transformCanvas.w,this.transformCanvas.h):this.save(),i=e-1;0<=i;--i)(this.completeLayers||this.elements[i])&&this.elements[i].renderFrame();!0!==this.renderConfig.clearCanvas&&this.restore()}}},CanvasRendererBase.prototype.buildItem=function(t){var e,i=this.elements;i[t]||99===this.layers[t].ty||(e=this.createItem(this.layers[t],this,this.globalData),(i[t]=e).initExpressions())},CanvasRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;)this.pendingElements.pop().checkParenting()},CanvasRendererBase.prototype.hide=function(){this.animationItem.container.style.display="none"},CanvasRendererBase.prototype.show=function(){this.animationItem.container.style.display="block"},CVContextData.prototype.duplicate=function(){for(var t=2*this._length,e=0,e=this._length;e<t;e+=1)this.stack[e]=new CanvasContext;this._length=t},CVContextData.prototype.reset=function(){this.cArrPos=0,this.cTr.reset(),this.stack[this.cArrPos].opacity=1},CVContextData.prototype.restore=function(t){--this.cArrPos;for(var e,i=this.stack[this.cArrPos],r=i.transform,s=this.cTr.props,a=0;a<16;a+=1)s[a]=r[a];t&&(this.nativeContext.restore(),e=this.stack[this.cArrPos+1],this.appliedFillStyle=e.fillStyle,this.appliedStrokeStyle=e.strokeStyle,this.appliedLineWidth=e.lineWidth,this.appliedLineCap=e.lineCap,this.appliedLineJoin=e.lineJoin,this.appliedMiterLimit=e.miterLimit),this.nativeContext.setTransform(r[0],r[1],r[4],r[5],r[12],r[13]),(t||-1!==i.opacity&&this.currentOpacity!==i.opacity)&&(this.nativeContext.globalAlpha=i.opacity,this.currentOpacity=i.opacity),this.currentFillStyle=i.fillStyle,this.currentStrokeStyle=i.strokeStyle,this.currentLineWidth=i.lineWidth,this.currentLineCap=i.lineCap,this.currentLineJoin=i.lineJoin,this.currentMiterLimit=i.miterLimit},CVContextData.prototype.save=function(t){t&&this.nativeContext.save();for(var e=this.cTr.props,i=(this._length<=this.cArrPos&&this.duplicate(),this.stack[this.cArrPos]),r=0;r<16;r+=1)i.transform[r]=e[r];this.cArrPos+=1;t=this.stack[this.cArrPos];t.opacity=i.opacity,t.fillStyle=i.fillStyle,t.strokeStyle=i.strokeStyle,t.lineWidth=i.lineWidth,t.lineCap=i.lineCap,t.lineJoin=i.lineJoin,t.miterLimit=i.miterLimit},CVContextData.prototype.setOpacity=function(t){this.stack[this.cArrPos].opacity=t},CVContextData.prototype.setContext=function(t){this.nativeContext=t},CVContextData.prototype.fillStyle=function(t){this.stack[this.cArrPos].fillStyle!==t&&(this.currentFillStyle=t,this.stack[this.cArrPos].fillStyle=t)},CVContextData.prototype.strokeStyle=function(t){this.stack[this.cArrPos].strokeStyle!==t&&(this.currentStrokeStyle=t,this.stack[this.cArrPos].strokeStyle=t)},CVContextData.prototype.lineWidth=function(t){this.stack[this.cArrPos].lineWidth!==t&&(this.currentLineWidth=t,this.stack[this.cArrPos].lineWidth=t)},CVContextData.prototype.lineCap=function(t){this.stack[this.cArrPos].lineCap!==t&&(this.currentLineCap=t,this.stack[this.cArrPos].lineCap=t)},CVContextData.prototype.lineJoin=function(t){this.stack[this.cArrPos].lineJoin!==t&&(this.currentLineJoin=t,this.stack[this.cArrPos].lineJoin=t)},CVContextData.prototype.miterLimit=function(t){this.stack[this.cArrPos].miterLimit!==t&&(this.currentMiterLimit=t,this.stack[this.cArrPos].miterLimit=t)},CVContextData.prototype.transform=function(t){this.transformMat.cloneFromProps(t);t=this.cTr,this.transformMat.multiply(t),t.cloneFromProps(this.transformMat.props),t=t.props;this.nativeContext.setTransform(t[0],t[1],t[4],t[5],t[12],t[13])},CVContextData.prototype.opacity=function(t){var e=this.stack[this.cArrPos].opacity;this.stack[this.cArrPos].opacity!==(e*=t<0?0:t)&&(this.currentOpacity!==t&&(this.nativeContext.globalAlpha=t,this.currentOpacity=t),this.stack[this.cArrPos].opacity=e)},CVContextData.prototype.fill=function(t){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fill(t)},CVContextData.prototype.fillRect=function(t,e,i,r){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fillRect(t,e,i,r)},CVContextData.prototype.stroke=function(){this.appliedStrokeStyle!==this.currentStrokeStyle&&(this.appliedStrokeStyle=this.currentStrokeStyle,this.nativeContext.strokeStyle=this.appliedStrokeStyle),this.appliedLineWidth!==this.currentLineWidth&&(this.appliedLineWidth=this.currentLineWidth,this.nativeContext.lineWidth=this.appliedLineWidth),this.appliedLineCap!==this.currentLineCap&&(this.appliedLineCap=this.currentLineCap,this.nativeContext.lineCap=this.appliedLineCap),this.appliedLineJoin!==this.currentLineJoin&&(this.appliedLineJoin=this.currentLineJoin,this.nativeContext.lineJoin=this.appliedLineJoin),this.appliedMiterLimit!==this.currentMiterLimit&&(this.appliedMiterLimit=this.currentMiterLimit,this.nativeContext.miterLimit=this.appliedMiterLimit),this.nativeContext.stroke()},extendPrototype([CanvasRendererBase,ICompElement,CVBaseElement],CVCompElement),CVCompElement.prototype.renderInnerContent=function(){var t=this.canvasContext;t.beginPath(),t.moveTo(0,0),t.lineTo(this.data.w,0),t.lineTo(this.data.w,this.data.h),t.lineTo(0,this.data.h),t.lineTo(0,0),t.clip();for(var e=this.layers.length-1;0<=e;--e)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()},CVCompElement.prototype.destroy=function(){for(var t=this.layers.length-1;0<=t;--t)this.elements[t]&&this.elements[t].destroy();this.layers=null,this.elements=null},CVCompElement.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},extendPrototype([CanvasRendererBase],CanvasRenderer),CanvasRenderer.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},HBaseElement.prototype={checkBlendMode:function(){},initRendererElement:function(){this.baseElement=createTag(this.data.tg||"div"),this.data.hasMask?(this.svgElement=createNS("svg"),this.layerElement=createNS("g"),this.maskedElement=this.layerElement,this.svgElement.appendChild(this.layerElement),this.baseElement.appendChild(this.svgElement)):this.layerElement=this.baseElement,styleDiv(this.baseElement)},createContainerElements:function(){this.renderableEffectsManager=new CVEffects(this),this.transformedElement=this.baseElement,this.maskedElement=this.layerElement,this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0!==this.data.bm&&this.setBlendMode()},renderElement:function(){var t,e=this.transformedElement?this.transformedElement.style:{};this.finalTransform._matMdf&&(t=this.finalTransform.mat.toCSS(),e.transform=t,e.webkitTransform=t),this.finalTransform._opMdf&&(e.opacity=this.finalTransform.mProp.o.v)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},destroy:function(){this.layerElement=null,this.transformedElement=null,this.matteElement&&(this.matteElement=null),this.maskManager&&(this.maskManager.destroy(),this.maskManager=null)},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData)},addEffects:function(){},setMatte:function(){}},HBaseElement.prototype.getBaseElement=SVGBaseElement.prototype.getBaseElement,HBaseElement.prototype.destroyBaseElement=HBaseElement.prototype.destroy,HBaseElement.prototype.buildElementParenting=BaseRenderer.prototype.buildElementParenting,extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],HSolidElement),HSolidElement.prototype.createContent=function(){var t;this.data.hasMask?((t=createNS("rect")).setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.svgElement.setAttribute("width",this.data.sw),this.svgElement.setAttribute("height",this.data.sh)):((t=createTag("div")).style.width=this.data.sw+"px",t.style.height=this.data.sh+"px",t.style.backgroundColor=this.data.sc),this.layerElement.appendChild(t)},extendPrototype([BaseElement,TransformElement,HSolidElement,SVGShapeElement,HBaseElement,HierarchyElement,FrameElement,RenderableElement],HShapeElement),HShapeElement.prototype._renderShapeFrame=HShapeElement.prototype.renderInnerContent,HShapeElement.prototype.createContent=function(){var t,e;this.baseElement.style.fontSize=0,this.data.hasMask?(this.layerElement.appendChild(this.shapesContainer),t=this.svgElement):(t=createNS("svg"),e=this.comp.data||this.globalData.compSize,t.setAttribute("width",e.w),t.setAttribute("height",e.h),t.appendChild(this.shapesContainer),this.layerElement.appendChild(t)),this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.shapesContainer,0,[],!0),this.filterUniqueShapes(),this.shapeCont=t},HShapeElement.prototype.getTransformedPoint=function(t,e){for(var i=t.length,r=0;r<i;r+=1)e=t[r].mProps.v.applyToPointArray(e[0],e[1],0);return e},HShapeElement.prototype.calculateShapeBoundingBox=function(t,e){var i,r,s,a,n,o=t.sh.v,h=t.transformers,l=o._length;if(!(l<=1)){for(i=0;i<l-1;i+=1)r=this.getTransformedPoint(h,o.v[i]),s=this.getTransformedPoint(h,o.o[i]),a=this.getTransformedPoint(h,o.i[i+1]),n=this.getTransformedPoint(h,o.v[i+1]),this.checkBounds(r,s,a,n,e);o.c&&(r=this.getTransformedPoint(h,o.v[i]),s=this.getTransformedPoint(h,o.o[i]),a=this.getTransformedPoint(h,o.i[0]),n=this.getTransformedPoint(h,o.v[0]),this.checkBounds(r,s,a,n,e))}},HShapeElement.prototype.checkBounds=function(t,e,i,r,s){this.getBoundsOfCurve(t,e,i,r);t=this.shapeBoundingBox;s.x=bmMin(t.left,s.x),s.xMax=bmMax(t.right,s.xMax),s.y=bmMin(t.top,s.y),s.yMax=bmMax(t.bottom,s.yMax)},HShapeElement.prototype.shapeBoundingBox={left:0,right:0,top:0,bottom:0},HShapeElement.prototype.tempBoundingBox={x:0,xMax:0,y:0,yMax:0,width:0,height:0},HShapeElement.prototype.getBoundsOfCurve=function(t,e,i,r){for(var s,a,n,o,h=[[t[0],r[0]],[t[1],r[1]]],l=0;l<2;++l)a=6*t[l]-12*e[l]+6*i[l],s=-3*t[l]+9*e[l]-9*i[l]+3*r[l],o=3*e[l]-3*t[l],a|=0,o|=0,0==(s|=0)&&0==a||(0==s?0<(n=-o/a)&&n<1&&h[l].push(this.calculateF(n,t,e,i,r,l)):0<=(n=a*a-4*o*s)&&(0<(o=(-a+bmSqrt(n))/(2*s))&&o<1&&h[l].push(this.calculateF(o,t,e,i,r,l)),0<(o=(-a-bmSqrt(n))/(2*s)))&&o<1&&h[l].push(this.calculateF(o,t,e,i,r,l)));this.shapeBoundingBox.left=bmMin.apply(null,h[0]),this.shapeBoundingBox.top=bmMin.apply(null,h[1]),this.shapeBoundingBox.right=bmMax.apply(null,h[0]),this.shapeBoundingBox.bottom=bmMax.apply(null,h[1])},HShapeElement.prototype.calculateF=function(t,e,i,r,s,a){return bmPow(1-t,3)*e[a]+3*bmPow(1-t,2)*t*i[a]+3*(1-t)*bmPow(t,2)*r[a]+bmPow(t,3)*s[a]},HShapeElement.prototype.calculateBoundingBox=function(t,e){for(var i=t.length,r=0;r<i;r+=1)t[r]&&t[r].sh?this.calculateShapeBoundingBox(t[r],e):t[r]&&t[r].it?this.calculateBoundingBox(t[r].it,e):t[r]&&t[r].style&&t[r].w&&this.expandStrokeBoundingBox(t[r].w,e)},HShapeElement.prototype.expandStrokeBoundingBox=function(t,e){var i=0;if(t.keyframes){for(var r=0;r<t.keyframes.length;r+=1){var s=t.keyframes[r].s;i<s&&(i=s)}i*=t.mult}else i=t.v*t.mult;e.x-=i,e.xMax+=i,e.y-=i,e.yMax+=i},HShapeElement.prototype.currentBoxContains=function(t){return this.currentBBox.x<=t.x&&this.currentBBox.y<=t.y&&this.currentBBox.width+this.currentBBox.x>=t.x+t.width&&this.currentBBox.height+this.currentBBox.y>=t.y+t.height},HShapeElement.prototype.renderInnerContent=function(){var t,e;this._renderShapeFrame(),this.hidden||!this._isFirstFrame&&!this._mdf||((e=this.tempBoundingBox).x=t=999999,e.xMax=-t,e.y=t,e.yMax=-t,this.calculateBoundingBox(this.itemsData,e),e.width=e.xMax<e.x?0:e.xMax-e.x,e.height=e.yMax<e.y?0:e.yMax-e.y,!this.currentBoxContains(e)&&(t=!1,this.currentBBox.w!==e.width&&(this.currentBBox.w=e.width,this.shapeCont.setAttribute("width",e.width),t=!0),this.currentBBox.h!==e.height&&(this.currentBBox.h=e.height,this.shapeCont.setAttribute("height",e.height),t=!0),t||this.currentBBox.x!==e.x||this.currentBBox.y!==e.y)&&(this.currentBBox.w=e.width,this.currentBBox.h=e.height,this.currentBBox.x=e.x,this.currentBBox.y=e.y,this.shapeCont.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h),t=this.shapeCont.style,e="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)",t.transform=e,t.webkitTransform=e))},extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],HTextElement),HTextElement.prototype.createContent=function(){var t;this.isMasked=this.checkMasks(),this.isMasked?(this.renderType="svg",this.compW=this.comp.data.w,this.compH=this.comp.data.h,this.svgElement.setAttribute("width",this.compW),this.svgElement.setAttribute("height",this.compH),t=createNS("g"),this.maskedElement.appendChild(t),this.innerElem=t):(this.renderType="html",this.innerElem=this.layerElement),this.checkParenting()},HTextElement.prototype.buildNewText=function(){for(var t,e,i,r,s,a,n,o=this.textProperty.currentData,h=(this.renderedLetters=createSizedArray(o.l?o.l.length:0),this.innerElem.style),l=o.fc?this.buildColor(o.fc):"rgba(0,0,0,0)",p=(h.fill=l,h.color=l,o.sc&&(h.stroke=this.buildColor(o.sc),h.strokeWidth=o.sw+"px"),this.globalData.fontManager.getFontByName(o.f)),m=(this.globalData.fontManager.chars||(h.fontSize=o.finalSize+"px",h.lineHeight=o.finalSize+"px",p.fClass?this.innerElem.className=p.fClass:(h.fontFamily=p.fFamily,l=o.fWeight,t=o.fStyle,h.fontStyle=t,h.fontWeight=l)),o.l),f=m.length,c=this.mHelper,d=0,u=0;u<f;u+=1)this.globalData.fontManager.chars?(this.textPaths[d]?e=this.textPaths[d]:((e=createNS("path")).setAttribute("stroke-linecap",lineCapEnum[1]),e.setAttribute("stroke-linejoin",lineJoinEnum[2]),e.setAttribute("stroke-miterlimit","4")),this.isMasked||(this.textSpans[d]?r=(i=this.textSpans[d]).children[0]:((i=createTag("div")).style.lineHeight=0,(r=createNS("svg")).appendChild(e),styleDiv(i)))):this.isMasked?e=this.textPaths[d]||createNS("text"):this.textSpans[d]?(i=this.textSpans[d],e=this.textPaths[d]):(styleDiv(i=createTag("span")),styleDiv(e=createTag("span")),i.appendChild(e)),this.globalData.fontManager.chars?(a=(a=this.globalData.fontManager.getCharData(o.finalText[u],p.fStyle,this.globalData.fontManager.getFontByName(o.f).fFamily))?a.data:null,c.reset(),a&&a.shapes&&a.shapes.length&&(s=a.shapes[0].it,c.scale(o.finalSize/100,o.finalSize/100),s=this.createPathShape(c,s),e.setAttribute("d",s)),this.isMasked?this.innerElem.appendChild(e):(this.innerElem.appendChild(i),a&&a.shapes?(document.body.appendChild(r),s=r.getBBox(),r.setAttribute("width",s.width+2),r.setAttribute("height",s.height+2),r.setAttribute("viewBox",s.x-1+" "+(s.y-1)+" "+(s.width+2)+" "+(s.height+2)),a=r.style,n="translate("+(s.x-1)+"px,"+(s.y-1)+"px)",a.transform=n,a.webkitTransform=n,m[u].yOffset=s.y-1):(r.setAttribute("width",1),r.setAttribute("height",1)),i.appendChild(r))):(e.textContent=m[u].val,e.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),this.isMasked?this.innerElem.appendChild(e):(this.innerElem.appendChild(i),a=e.style,n="translate3d(0,"+-o.finalSize/1.2+"px,0)",a.transform=n,a.webkitTransform=n)),this.isMasked?this.textSpans[d]=e:this.textSpans[d]=i,this.textSpans[d].style.display="block",this.textPaths[d]=e,d+=1;for(;d<this.textSpans.length;)this.textSpans[d].style.display="none",d+=1},HTextElement.prototype.renderInnerContent=function(){var t;if(this.validateText(),this.data.singleShape){if(!this._isFirstFrame&&!this.lettersChangedFlag)return;this.isMasked&&this.finalTransform._matMdf&&(this.svgElement.setAttribute("viewBox",-this.finalTransform.mProp.p.v[0]+" "+-this.finalTransform.mProp.p.v[1]+" "+this.compW+" "+this.compH),t=this.svgElement.style,s="translate("+-this.finalTransform.mProp.p.v[0]+"px,"+-this.finalTransform.mProp.p.v[1]+"px)",t.transform=s,t.webkitTransform=s)}if(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag){for(var e,i,r,s,a=0,n=this.textAnimator.renderedLetters,o=this.textProperty.currentData.l,h=o.length,l=0;l<h;l+=1)o[l].n?a+=1:(i=this.textSpans[l],r=this.textPaths[l],e=n[a],a+=1,e._mdf.m&&(this.isMasked?i.setAttribute("transform",e.m):(i.style.webkitTransform=e.m,i.style.transform=e.m)),i.style.opacity=e.o,e.sw&&e._mdf.sw&&r.setAttribute("stroke-width",e.sw),e.sc&&e._mdf.sc&&r.setAttribute("stroke",e.sc),e.fc&&e._mdf.fc&&(r.setAttribute("fill",e.fc),r.style.color=e.fc));this.innerElem.getBBox&&!this.hidden&&(this._isFirstFrame||this._mdf)&&(s=this.innerElem.getBBox(),this.currentBBox.w!==s.width&&(this.currentBBox.w=s.width,this.svgElement.setAttribute("width",s.width)),this.currentBBox.h!==s.height&&(this.currentBBox.h=s.height,this.svgElement.setAttribute("height",s.height)),this.currentBBox.w===s.width+2&&this.currentBBox.h===s.height+2&&this.currentBBox.x===s.x-1&&this.currentBBox.y===s.y-1||(this.currentBBox.w=s.width+2,this.currentBBox.h=s.height+2,this.currentBBox.x=s.x-1,this.currentBBox.y=s.y-1,this.svgElement.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h),t=this.svgElement.style,s="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)",t.transform=s,t.webkitTransform=s))}},extendPrototype([BaseElement,FrameElement,HierarchyElement],HCameraElement),HCameraElement.prototype.setup=function(){for(var t,e,i,r,s,a=this.comp.threeDElements.length,n=0;n<a;n+=1)"3d"===(s=this.comp.threeDElements[n]).type&&(t=s.perspectiveElem.style,s=s.container.style,e=this.pe.v+"px",i="0px 0px 0px",r="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)",t.perspective=e,t.webkitPerspective=e,s.transformOrigin=i,s.mozTransformOrigin=i,s.webkitTransformOrigin=i,t.transform=r,t.webkitTransform=r)},HCameraElement.prototype.createElements=function(){},HCameraElement.prototype.hide=function(){},HCameraElement.prototype.renderFrame=function(){var t=this._isFirstFrame;if(this.hierarchy)for(h=this.hierarchy.length,l=0;l<h;l+=1)t=this.hierarchy[l].finalTransform.mProp._mdf||t;if(t||this.pe._mdf||this.p&&this.p._mdf||this.px&&(this.px._mdf||this.py._mdf||this.pz._mdf)||this.rx._mdf||this.ry._mdf||this.rz._mdf||this.or._mdf||this.a&&this.a._mdf){if(this.mat.reset(),this.hierarchy)for(l=h=this.hierarchy.length-1;0<=l;--l){var e=this.hierarchy[l].finalTransform.mProp;this.mat.translate(-e.p.v[0],-e.p.v[1],e.p.v[2]),this.mat.rotateX(-e.or.v[0]).rotateY(-e.or.v[1]).rotateZ(e.or.v[2]),this.mat.rotateX(-e.rx.v).rotateY(-e.ry.v).rotateZ(e.rz.v),this.mat.scale(1/e.s.v[0],1/e.s.v[1],1/e.s.v[2]),this.mat.translate(e.a.v[0],e.a.v[1],e.a.v[2])}this.p?this.mat.translate(-this.p.v[0],-this.p.v[1],this.p.v[2]):this.mat.translate(-this.px.v,-this.py.v,this.pz.v),this.a&&(r=this.p?[this.p.v[0]-this.a.v[0],this.p.v[1]-this.a.v[1],this.p.v[2]-this.a.v[2]]:[this.px.v-this.a.v[0],this.py.v-this.a.v[1],this.pz.v-this.a.v[2]],i=Math.sqrt(Math.pow(r[0],2)+Math.pow(r[1],2)+Math.pow(r[2],2)),r=[r[0]/i,r[1]/i,r[2]/i],i=Math.sqrt(r[2]*r[2]+r[0]*r[0]),i=Math.atan2(r[1],i),r=Math.atan2(r[0],-r[2]),this.mat.rotateY(r).rotateX(-i)),this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v),this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]),this.mat.translate(this.globalData.compSize.w/2,this.globalData.compSize.h/2,0),this.mat.translate(0,0,this.pe.v);var i,r,s=!this._prevMat.equals(this.mat);if((s||this.pe._mdf)&&this.comp.threeDElements){for(var a,n,o,h=this.comp.threeDElements.length,l=0;l<h;l+=1)"3d"===(o=this.comp.threeDElements[l]).type&&(s&&(a=this.mat.toCSS(),(n=o.container.style).transform=a,n.webkitTransform=a),this.pe._mdf)&&((n=o.perspectiveElem.style).perspective=this.pe.v+"px",n.webkitPerspective=this.pe.v+"px");this.mat.clone(this._prevMat)}}this._isFirstFrame=!1},HCameraElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},HCameraElement.prototype.destroy=function(){},HCameraElement.prototype.getBaseElement=function(){return null},extendPrototype([BaseElement,TransformElement,HBaseElement,HSolidElement,HierarchyElement,FrameElement,RenderableElement],HImageElement),HImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData),e=new Image;this.data.hasMask?(this.imageElem=createNS("image"),this.imageElem.setAttribute("width",this.assetData.w+"px"),this.imageElem.setAttribute("height",this.assetData.h+"px"),this.imageElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.imageElem),this.baseElement.setAttribute("width",this.assetData.w),this.baseElement.setAttribute("height",this.assetData.h)):this.layerElement.appendChild(e),e.crossOrigin="anonymous",e.src=t,this.data.ln&&this.baseElement.setAttribute("id",this.data.ln)},extendPrototype([BaseRenderer],HybridRendererBase),HybridRendererBase.prototype.buildItem=SVGRenderer.prototype.buildItem,HybridRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;)this.pendingElements.pop().checkParenting()},HybridRendererBase.prototype.appendElementInPos=function(t,e){t=t.getBaseElement();if(t){var i=this.layers[e];if(i.ddd&&this.supports3d)this.addTo3dContainer(t,e);else if(this.threeDElements)this.addTo3dContainer(t,e);else{for(var r,s,a=0;a<e;)this.elements[a]&&!0!==this.elements[a]&&this.elements[a].getBaseElement&&(s=this.elements[a],r=(this.layers[a].ddd?this.getThreeDContainerByPos(a):s.getBaseElement())||r),a+=1;r?i.ddd&&this.supports3d||this.layerElement.insertBefore(t,r):i.ddd&&this.supports3d||this.layerElement.appendChild(t)}}},HybridRendererBase.prototype.createShape=function(t){return new(this.supports3d?HShapeElement:SVGShapeElement)(t,this.globalData,this)},HybridRendererBase.prototype.createText=function(t){return new(this.supports3d?HTextElement:SVGTextLottieElement)(t,this.globalData,this)},HybridRendererBase.prototype.createCamera=function(t){return this.camera=new HCameraElement(t,this.globalData,this),this.camera},HybridRendererBase.prototype.createImage=function(t){return new(this.supports3d?HImageElement:IImageElement)(t,this.globalData,this)},HybridRendererBase.prototype.createSolid=function(t){return new(this.supports3d?HSolidElement:ISolidElement)(t,this.globalData,this)},HybridRendererBase.prototype.createNull=SVGRenderer.prototype.createNull,HybridRendererBase.prototype.getThreeDContainerByPos=function(t){for(var e=0,i=this.threeDElements.length;e<i;){if(this.threeDElements[e].startPos<=t&&this.threeDElements[e].endPos>=t)return this.threeDElements[e].perspectiveElem;e+=1}return null},HybridRendererBase.prototype.createThreeDContainer=function(t,e){var i,r=createTag("div"),s=(styleDiv(r),createTag("div")),a=(styleDiv(s),"3d"===e&&((a=r.style).width=this.globalData.compSize.w+"px",a.height=this.globalData.compSize.h+"px",a.webkitTransformOrigin=i="50% 50%",a.mozTransformOrigin=i,a.transformOrigin=i,(a=s.style).transform=i="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)",a.webkitTransform=i),r.appendChild(s),{container:s,perspectiveElem:r,startPos:t,endPos:t,type:e});return this.threeDElements.push(a),a},HybridRendererBase.prototype.build3dContainers=function(){for(var t,e=this.layers.length,i="",r=0;r<e;r+=1)this.layers[r].ddd&&3!==this.layers[r].ty?(t="3d"!==i?this.createThreeDContainer(r,i="3d"):t).endPos=Math.max(t.endPos,r):(t="2d"!==i?this.createThreeDContainer(r,i="2d"):t).endPos=Math.max(t.endPos,r);for(r=(e=this.threeDElements.length)-1;0<=r;--r)this.resizerElem.appendChild(this.threeDElements[r].perspectiveElem)},HybridRendererBase.prototype.addTo3dContainer=function(t,e){for(var i=0,r=this.threeDElements.length;i<r;){if(e<=this.threeDElements[i].endPos){for(var s,a=this.threeDElements[i].startPos;a<e;)this.elements[a]&&this.elements[a].getBaseElement&&(s=this.elements[a].getBaseElement()),a+=1;s?this.threeDElements[i].container.insertBefore(t,s):this.threeDElements[i].container.appendChild(t);break}i+=1}},HybridRendererBase.prototype.configAnimation=function(t){var e=createTag("div"),i=this.animationItem.wrapper,r=e.style,i=(r.width=t.w+"px",r.height=t.h+"px",styleDiv(this.resizerElem=e),r.transformStyle="flat",r.mozTransformStyle="flat",r.webkitTransformStyle="flat",this.renderConfig.className&&e.setAttribute("class",this.renderConfig.className),i.appendChild(e),r.overflow="hidden",createNS("svg")),e=(i.setAttribute("width","1"),i.setAttribute("height","1"),styleDiv(i),this.resizerElem.appendChild(i),createNS("defs"));i.appendChild(e),this.data=t,this.setupGlobalData(t,i),this.globalData.defs=e,this.layers=t.layers,this.layerElement=this.resizerElem,this.build3dContainers(),this.updateContainerSize()},HybridRendererBase.prototype.destroy=function(){this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.animationItem.container=null,this.globalData.defs=null;for(var t=this.layers?this.layers.length:0,e=0;e<t;e+=1)this.elements[e]&&this.elements[e].destroy&&this.elements[e].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},HybridRendererBase.prototype.updateContainerSize=function(){var t,e,i,r=this.animationItem.wrapper.offsetWidth,s=this.animationItem.wrapper.offsetHeight,r=r/s<this.globalData.compSize.w/this.globalData.compSize.h?(t=r/this.globalData.compSize.w,e=r/this.globalData.compSize.w,i=0,(s-this.globalData.compSize.h*(r/this.globalData.compSize.w))/2):(t=s/this.globalData.compSize.h,e=s/this.globalData.compSize.h,i=(r-this.globalData.compSize.w*(s/this.globalData.compSize.h))/2,0),s=this.resizerElem.style;s.webkitTransform="matrix3d("+t+",0,0,0,0,"+e+",0,0,0,0,1,0,"+i+","+r+",0,1)",s.transform=s.webkitTransform},HybridRendererBase.prototype.renderFrame=SVGRenderer.prototype.renderFrame,HybridRendererBase.prototype.hide=function(){this.resizerElem.style.display="none"},HybridRendererBase.prototype.show=function(){this.resizerElem.style.display="block"},HybridRendererBase.prototype.initItems=function(){if(this.buildAllItems(),this.camera)this.camera.setup();else for(var t=this.globalData.compSize.w,e=this.globalData.compSize.h,i=this.threeDElements.length,r=0;r<i;r+=1){var s=this.threeDElements[r].perspectiveElem.style;s.webkitPerspective=Math.sqrt(Math.pow(t,2)+Math.pow(e,2))+"px",s.perspective=s.webkitPerspective}},HybridRendererBase.prototype.searchExtraCompositions=function(t){for(var e,i=t.length,r=createTag("div"),s=0;s<i;s+=1)t[s].xt&&((e=this.createComp(t[s],r,this.globalData.comp,null)).initExpressions(),this.globalData.projectInterface.registerComposition(e))},extendPrototype([HybridRendererBase,ICompElement,HBaseElement],HCompElement),HCompElement.prototype._createBaseContainerElements=HCompElement.prototype.createContainerElements,HCompElement.prototype.createContainerElements=function(){this._createBaseContainerElements(),this.data.hasMask?(this.svgElement.setAttribute("width",this.data.w),this.svgElement.setAttribute("height",this.data.h),this.transformedElement=this.baseElement):this.transformedElement=this.layerElement},HCompElement.prototype.addTo3dContainer=function(t,e){for(var i,r=0;r<e;)this.elements[r]&&this.elements[r].getBaseElement&&(i=this.elements[r].getBaseElement()),r+=1;i?this.layerElement.insertBefore(t,i):this.layerElement.appendChild(t)},HCompElement.prototype.createComp=function(t){return new(this.supports3d?HCompElement:SVGCompElement)(t,this.globalData,this)},extendPrototype([HybridRendererBase],HybridRenderer),HybridRenderer.prototype.createComp=function(t){return new(this.supports3d?HCompElement:SVGCompElement)(t,this.globalData,this)};var CompExpressionInterface=function(r){function t(t){for(var e=0,i=r.layers.length;e<i;){if(r.layers[e].nm===t||r.layers[e].ind===t)return r.elements[e].layerInterface;e+=1}return null}return Object.defineProperty(t,"_name",{value:r.data.nm}),(t.layer=t).pixelAspect=1,t.height=r.data.h||r.globalData.compSize.h,t.width=r.data.w||r.globalData.compSize.w,t.pixelAspect=1,t.frameDuration=1/r.globalData.frameRate,t.displayStartTime=0,t.numLayers=r.layers.length,t};function _typeof$2(t){return(_typeof$2="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function seedRandom(n,o){var h,l=this,p=256,m=6,f="random",c=o.pow(p,m),d=o.pow(2,52),u=2*d,y=p-1;function g(t){var e,i=t.length,n=this,r=0,s=n.i=n.j=0,a=n.S=[];for(i||(t=[i++]);r<p;)a[r]=r++;for(r=0;r<p;r++)a[r]=a[s=y&s+t[r%i]+(e=a[r])],a[s]=e;n.g=function(t){for(var e,i=0,r=n.i,s=n.j,a=n.S;t--;)e=a[r=y&r+1],i=i*p+a[y&(a[r]=a[s=y&s+e])+(a[s]=e)];return n.i=r,n.j=s,i}}function v(t,e){return e.i=t.i,e.j=t.j,e.S=t.S.slice(),e}function b(t,e){for(var i,r=t+"",s=0;s<r.length;)e[y&s]=y&(i^=19*e[y&s])+r.charCodeAt(s++);return x(e)}function x(t){return String.fromCharCode.apply(0,t)}o["seed"+f]=function(t,e,i){function r(){for(var t=a.g(m),e=c,i=0;t<d;)t=(t+i)*p,e*=p,i=a.g(1);for(;u<=t;)t/=2,e/=2,i>>>=1;return(t+i)/e}var s=[],t=b(function t(e,i){var r,s=[],a=_typeof$2(e);if(i&&"object"==a)for(r in e)try{s.push(t(e[r],i-1))}catch(t){}return s.length?s:"string"==a?e:e+"\0"}((e=!0===e?{entropy:!0}:e||{}).entropy?[t,x(n)]:null===t?(()=>{try{return h?x(h.randomBytes(p)):(e=new Uint8Array(p),(l.crypto||l.msCrypto).getRandomValues(e),x(e))}catch(t){var e=l.navigator,e=e&&e.plugins;return[+new Date,l,e,l.screen,x(n)]}})():t,3),s),a=new g(s);return r.int32=function(){return 0|a.g(4)},r.quick=function(){return a.g(4)/4294967296},r.double=r,b(x(a.S),n),(e.pass||i||function(t,e,i,r){return r&&(r.S&&v(r,a),t.state=function(){return v(a,{})}),i?(o[f]=t,e):t})(r,t,"global"in e?e.global:this==o,e.state)},b(o.random(),n)}function initialize$2(t){seedRandom([],t)}var propTypes={SHAPE:"shape"};function _typeof$1(t){return(_typeof$1="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var ExpressionManager=function(){var ob={},Math=BMMath,window=null,document=null,XMLHttpRequest=null,fetch=null,frames=null,_lottieGlobal={};function resetFrame(){_lottieGlobal={}}function $bm_isInstanceOfArray(t){return t.constructor===Array||t.constructor===Float32Array}function isNumerable(t,e){return"number"===t||e instanceof Number||"boolean"===t||"string"===t}function $bm_neg(t){var e=_typeof$1(t);if("number"===e||t instanceof Number||"boolean"===e)return-t;if($bm_isInstanceOfArray(t)){for(var i=t.length,r=[],s=0;s<i;s+=1)r[s]=-t[s];return r}return t.propType?t.v:-t}initialize$2(BMMath);var easeInBez=BezierFactory.getBezierEasing(.333,0,.833,.833,"easeIn").get,easeOutBez=BezierFactory.getBezierEasing(.167,.167,.667,1,"easeOut").get,easeInOutBez=BezierFactory.getBezierEasing(.33,0,.667,1,"easeInOut").get;function sum(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e)||"string"===i||"string"===r)return t+e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]+=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t+e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]+e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}var add=sum;function sub(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e))return(t="string"===i?parseInt(t,10):t)-(e="string"===r?parseInt(e,10):e);if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]-=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t-e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]-e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}function mul(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t*e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]*e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t*e[r];return i}return 0}function div(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t/e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]/e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t/e[r];return i}return 0}function mod(t,e){return(t="string"==typeof t?parseInt(t,10):t)%(e="string"==typeof e?parseInt(e,10):e)}var $bm_sum=sum,$bm_sub=sub,$bm_mul=mul,$bm_div=div,$bm_mod=mod;function clamp(t,e,i){var r;return i<e&&(r=i,i=e,e=r),Math.min(Math.max(t,e),i)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return Math.abs(t-(e=e||0));for(var i=Math.min(t.length,(e=e||helperLengthArray).length),r=0,s=0;s<i;s+=1)r+=Math.pow(e[s]-t[s],2);return Math.sqrt(r)}function normalize(t){return div(t,length(t))}function rgbToHsl(t){var e,i=t[0],r=t[1],s=t[2],a=Math.max(i,r,s),n=Math.min(i,r,s),o=(a+n)/2;if(a===n)l=e=0;else{var h=a-n,l=.5<o?h/(2-a-n):h/(a+n);switch(a){case i:e=(r-s)/h+(r<s?6:0);break;case r:e=(s-i)/h+2;break;case s:e=(i-r)/h+4}e/=6}return[e,l,o,t[3]]}function hue2rgb(t,e,i){return i<0&&(i+=1),1<i&&--i,i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}function hslToRgb(t){var e,i,r,s=t[0],a=t[1],n=t[2];return 0===a?i=r=e=n:(e=hue2rgb(a=2*n-(n=n<.5?n*(1+a):n+a-n*a),n,s+1/3),i=hue2rgb(a,n,s),r=hue2rgb(a,n,s-1/3)),[e,i,r,t[3]]}function linear(t,e,i,r,s){var a;if(void 0!==r&&void 0!==s||(r=e,s=i,e=0,i=1),i<e&&(a=i,i=e,e=a),t<=e)return r;if(i<=t)return s;var n=i===e?0:(t-e)/(i-e);if(!r.length)return r+(s-r)*n;for(var o=r.length,h=createTypedArray("float32",o),l=0;l<o;l+=1)h[l]=r[l]+(s[l]-r[l])*n;return h}function random(t,e){if(void 0===e&&(void 0===t?(t=0,e=1):(e=t,t=void 0)),e.length){for(var i=e.length,r=(t=t||createTypedArray("float32",i),createTypedArray("float32",i)),s=BMMath.random(),a=0;a<i;a+=1)r[a]=t[a]+s*(e[a]-t[a]);return r}return(t=void 0===t?0:t)+BMMath.random()*(e-t)}function createPath(t,e,i,r){for(var s,a,n=t.length,o=shapePool.newElement(),h=(o.setPathData(!!r,n),[0,0]),l=0;l<n;l+=1)s=e&&e[l]?e[l]:h,a=i&&i[l]?i[l]:h,o.setTripleAt(t[l][0],t[l][1],a[0]+t[l][0],a[1]+t[l][1],s[0]+t[l][0],s[1]+t[l][1],l,!0);return o}function initiateExpression(elem,data,property){function noOp(t){return t}if(!elem.globalData.renderConfig.runExpressions)return noOp;var val=data.x,needsVelocity=/velocity(?![\w\d])/.test(val),_needsRandom=-1!==val.indexOf("random"),elemType=elem.data.ty,transform,$bm_transform,content,effect,thisProperty=property,inPoint=(thisProperty._name=elem.data.nm,thisProperty.valueAtTime=thisProperty.getValueAtTime,Object.defineProperty(thisProperty,"value",{get:function(){return thisProperty.v}}),elem.comp.frameDuration=1/elem.comp.globalData.frameRate,elem.comp.displayStartTime=0,elem.data.ip/elem.comp.globalData.frameRate),outPoint=elem.data.op/elem.comp.globalData.frameRate,width=elem.data.sw||0,height=elem.data.sh||0,name=elem.data.nm,loopIn,loop_in,loopOut,loop_out,smooth,toWorld,fromWorld,fromComp,toComp,fromCompToSurface,position,rotation,anchorPoint,scale,thisLayer,thisComp,mask,valueAtTime,velocityAtTime,scoped_bm_rt,expression_function=eval("[function _expression_function(){"+val+";scoped_bm_rt=$bm_rt}]")[0],numKeys=property.kf?data.k.length:0,active=!this.data||!0!==this.data.hd,wiggle=function(t,e){for(var i=this.pv.length||1,r=createTypedArray("float32",i),s=Math.floor(5*time),a=0,n=0;a<s;){for(n=0;n<i;n+=1)r[n]+=-e+2*e*BMMath.random();a+=1}var o=5*time,h=o-Math.floor(o),l=createTypedArray("float32",i);if(1<i){for(n=0;n<i;n+=1)l[n]=this.pv[n]+r[n]+(-e+2*e*BMMath.random())*h;return l}return this.pv+r[0]+(-e+2*e*BMMath.random())*h}.bind(this);function loopInDuration(t,e){return loopIn(t,e,!0)}function loopOutDuration(t,e){return loopOut(t,e,!0)}thisProperty.loopIn&&(loopIn=thisProperty.loopIn.bind(thisProperty),loop_in=loopIn),thisProperty.loopOut&&(loopOut=thisProperty.loopOut.bind(thisProperty),loop_out=loopOut),thisProperty.smooth&&(smooth=thisProperty.smooth.bind(thisProperty)),this.getValueAtTime&&(valueAtTime=this.getValueAtTime.bind(this)),this.getVelocityAtTime&&(velocityAtTime=this.getVelocityAtTime.bind(this));var comp=elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface),time,velocity,value,text,textIndex,textTotal,selectorValue;function lookAt(t,e){e=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],t=Math.atan2(e[0],Math.sqrt(e[1]*e[1]+e[2]*e[2]))/degToRads;return[-Math.atan2(e[1],e[2])/degToRads,t,0]}function easeOut(t,e,i,r,s){return applyEase(easeOutBez,t,e,i,r,s)}function easeIn(t,e,i,r,s){return applyEase(easeInBez,t,e,i,r,s)}function ease(t,e,i,r,s){return applyEase(easeInOutBez,t,e,i,r,s)}function applyEase(t,e,i,r,s,a){void 0===s?(s=i,a=r):e=(e-i)/(r-i),1<e?e=1:e<0&&(e=0);var n=t(e);if($bm_isInstanceOfArray(s)){for(var o=s.length,h=createTypedArray("float32",o),l=0;l<o;l+=1)h[l]=(a[l]-s[l])*n+s[l];return h}return(a-s)*n+s}function nearestKey(t){var e,i,r,s=data.k.length;if(data.k.length&&"number"!=typeof data.k[0])if(i=-1,(t*=elem.comp.globalData.frameRate)<data.k[0].t)i=1,r=data.k[0].t;else{for(e=0;e<s-1;e+=1){if(t===data.k[e].t){i=e+1,r=data.k[e].t;break}if(t>data.k[e].t&&t<data.k[e+1].t){r=(t-data.k[e].t>data.k[e+1].t-t?(i=e+2,data.k[e+1]):(i=e+1,data.k[e])).t;break}}-1===i&&(i=e+1,r=data.k[e].t)}else r=i=0;var a={};return a.index=i,a.time=r/elem.comp.globalData.frameRate,a}function key(t){if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);for(var e={time:data.k[--t].t/elem.comp.globalData.frameRate,value:[]},i=Object.prototype.hasOwnProperty.call(data.k[t],"s")?data.k[t].s:data.k[t-1].e,r=i.length,s=0;s<r;s+=1)e[s]=i[s],e.value[s]=i[s];return e}function framesToTime(t,e){return t/(e=e||elem.comp.globalData.frameRate)}function timeToFrames(t,e){return(t=t||0===t?t:time)*(e=e||elem.comp.globalData.frameRate)}function seedRandom(t){BMMath.seedrandom(randSeed+t)}function sourceRectAtTime(){return elem.sourceRectAtTime()}function substring(t,e){return"string"==typeof value?void 0===e?value.substring(t):value.substring(t,e):""}function substr(t,e){return"string"==typeof value?void 0===e?value.substr(t):value.substr(t,e):""}function posterizeTime(t){time=0===t?0:Math.floor(time*t)/t,value=valueAtTime(time)}var index=elem.data.ind,hasParent=!(!elem.hierarchy||!elem.hierarchy.length),parent,randSeed=Math.floor(1e6*Math.random()),globalData=elem.globalData;function executeExpression(t){return value=t,this.frameExpressionId===elem.globalData.frameId&&"textSelector"!==this.propType?value:("textSelector"===this.propType&&(textIndex=this.textIndex,textTotal=this.textTotal,selectorValue=this.selectorValue),thisLayer||(text=elem.layerInterface.text,thisLayer=elem.layerInterface,thisComp=elem.comp.compInterface,toWorld=thisLayer.toWorld.bind(thisLayer),fromWorld=thisLayer.fromWorld.bind(thisLayer),fromComp=thisLayer.fromComp.bind(thisLayer),toComp=thisLayer.toComp.bind(thisLayer),mask=thisLayer.mask?thisLayer.mask.bind(thisLayer):null,fromCompToSurface=fromComp),!transform&&(transform=elem.layerInterface("ADBE Transform Group"),$bm_transform=transform)&&(anchorPoint=transform.anchorPoint),4===elemType&&(content=content||thisLayer("ADBE Root Vectors Group")),effect=effect||thisLayer(4),(hasParent=!(!elem.hierarchy||!elem.hierarchy.length))&&!parent&&(parent=elem.hierarchy[0].layerInterface),time=this.comp.renderedFrame/this.comp.globalData.frameRate,_needsRandom&&seedRandom(randSeed+time),needsVelocity&&(velocity=velocityAtTime(time)),expression_function(),this.frameExpressionId=elem.globalData.frameId,scoped_bm_rt=scoped_bm_rt.propType===propTypes.SHAPE?scoped_bm_rt.v:scoped_bm_rt)}return executeExpression.__preventDeadCodeRemoval=[$bm_transform,anchorPoint,time,velocity,inPoint,outPoint,width,height,name,loop_in,loop_out,smooth,toComp,fromCompToSurface,toWorld,fromWorld,mask,position,rotation,scale,thisComp,numKeys,active,wiggle,loopInDuration,loopOutDuration,comp,lookAt,easeOut,easeIn,ease,nearestKey,key,text,textIndex,textTotal,selectorValue,framesToTime,timeToFrames,sourceRectAtTime,substring,substr,posterizeTime,index,globalData],executeExpression}return ob.initiateExpression=initiateExpression,ob.__preventDeadCodeRemoval=[window,document,XMLHttpRequest,fetch,frames,$bm_neg,add,$bm_sum,$bm_sub,$bm_mul,$bm_div,$bm_mod,clamp,radians_to_degrees,degreesToRadians,degrees_to_radians,normalize,rgbToHsl,hslToRgb,linear,random,createPath,_lottieGlobal],ob.resetFrame=resetFrame,ob}(),Expressions=(()=>{var t={};return t.initExpressions=function(t){var i=0,r=[];t.renderer.compInterface=CompExpressionInterface(t.renderer),t.renderer.globalData.projectInterface.registerComposition(t.renderer),t.renderer.globalData.pushExpression=function(){i+=1},t.renderer.globalData.popExpression=function(){if(0===--i){var t,e=r.length;for(t=0;t<e;t+=1)r[t].release();r.length=0}},t.renderer.globalData.registerExpressionProperty=function(t){-1===r.indexOf(t)&&r.push(t)}},t.resetFrame=ExpressionManager.resetFrame,t})(),MaskManagerInterface=(()=>{function t(t,e){this._mask=t,this._data=e}return Object.defineProperty(t.prototype,"maskPath",{get:function(){return this._mask.prop.k&&this._mask.prop.getValue(),this._mask.prop}}),Object.defineProperty(t.prototype,"maskOpacity",{get:function(){return this._mask.op.k&&this._mask.op.getValue(),100*this._mask.op.v}}),function(e){for(var i=createSizedArray(e.viewData.length),r=e.viewData.length,s=0;s<r;s+=1)i[s]=new t(e.viewData[s],e.masksProperties[s]);return function(t){for(s=0;s<r;){if(e.masksProperties[s].nm===t)return i[s];s+=1}return null}}})(),ExpressionPropertyInterface=(()=>{var p={pv:0,v:0,mult:1},m={pv:[0,0,0],v:[0,0,0],mult:1};function f(r,s,a){Object.defineProperty(r,"velocity",{get:function(){return s.getVelocityAtTime(s.comp.currentFrame)}}),r.numKeys=s.keyframes?s.keyframes.length:0,r.key=function(t){var e,i;return r.numKeys?(e="",e="s"in s.keyframes[t-1]?s.keyframes[t-1].s:"e"in s.keyframes[t-2]?s.keyframes[t-2].e:s.keyframes[t-2].s,(i="unidimensional"===a?new Number(e):Object.assign({},e)).time=s.keyframes[t-1].t/s.elem.comp.globalData.frameRate,i.value="unidimensional"===a?e[0]:e,i):0},r.valueAtTime=s.getValueAtTime,r.speedAtTime=s.getSpeedAtTime,r.velocityAtTime=s.getVelocityAtTime,r.propertyGroup=s.propertyGroup}function c(){return p}return function(t){var e,i,r,s,a,n,o,h,l;return t?"unidimensional"===t.propType?(i=1/(e=(e=t)&&"pv"in e?e:p).mult,r=e.pv*i,(s=new Number(r)).value=r,f(s,e,"unidimensional"),function(){return e.k&&e.getValue(),r=e.v*i,s.value!==r&&((s=new Number(r)).value=r,s[0]=r,f(s,e,"unidimensional")),s}):(n=1/(a=(a=t)&&"pv"in a?a:m).mult,o=a.data&&a.data.l||a.pv.length,h=createTypedArray("float32",o),l=createTypedArray("float32",o),h.value=l,f(h,a,"multidimensional"),function(){a.k&&a.getValue();for(var t=0;t<o;t+=1)l[t]=a.v[t]*n,h[t]=l[t];return h}):c}})(),TransformExpressionInterface=function(t){function e(t){switch(t){case"scale":case"Scale":case"ADBE Scale":case 6:return e.scale;case"rotation":case"Rotation":case"ADBE Rotation":case"ADBE Rotate Z":case 10:return e.rotation;case"ADBE Rotate X":return e.xRotation;case"ADBE Rotate Y":return e.yRotation;case"position":case"Position":case"ADBE Position":case 2:return e.position;case"ADBE Position_0":return e.xPosition;case"ADBE Position_1":return e.yPosition;case"ADBE Position_2":return e.zPosition;case"anchorPoint":case"AnchorPoint":case"Anchor Point":case"ADBE AnchorPoint":case 1:return e.anchorPoint;case"opacity":case"Opacity":case 11:return e.opacity;default:return null}}var i,r,s,a;return Object.defineProperty(e,"rotation",{get:ExpressionPropertyInterface(t.r||t.rz)}),Object.defineProperty(e,"zRotation",{get:ExpressionPropertyInterface(t.rz||t.r)}),Object.defineProperty(e,"xRotation",{get:ExpressionPropertyInterface(t.rx)}),Object.defineProperty(e,"yRotation",{get:ExpressionPropertyInterface(t.ry)}),Object.defineProperty(e,"scale",{get:ExpressionPropertyInterface(t.s)}),t.p?a=ExpressionPropertyInterface(t.p):(i=ExpressionPropertyInterface(t.px),r=ExpressionPropertyInterface(t.py),t.pz&&(s=ExpressionPropertyInterface(t.pz))),Object.defineProperty(e,"position",{get:function(){return t.p?a():[i(),r(),s?s():0]}}),Object.defineProperty(e,"xPosition",{get:ExpressionPropertyInterface(t.px)}),Object.defineProperty(e,"yPosition",{get:ExpressionPropertyInterface(t.py)}),Object.defineProperty(e,"zPosition",{get:ExpressionPropertyInterface(t.pz)}),Object.defineProperty(e,"anchorPoint",{get:ExpressionPropertyInterface(t.a)}),Object.defineProperty(e,"opacity",{get:ExpressionPropertyInterface(t.o)}),Object.defineProperty(e,"skew",{get:ExpressionPropertyInterface(t.sk)}),Object.defineProperty(e,"skewAxis",{get:ExpressionPropertyInterface(t.sa)}),Object.defineProperty(e,"orientation",{get:ExpressionPropertyInterface(t.or)}),e},LayerExpressionInterface=(()=>{function s(t){var e=new Matrix;return void 0!==t?this._elem.finalTransform.mProp.getValueAtTime(t).clone(e):this._elem.finalTransform.mProp.applyToMatrix(e),e}function a(t,e){e=this.getMatrix(e);return e.props[12]=0,e.props[13]=0,e.props[14]=0,this.applyPoint(e,t)}function n(t,e){e=this.getMatrix(e);return this.applyPoint(e,t)}function o(t,e){e=this.getMatrix(e);return e.props[12]=0,e.props[13]=0,e.props[14]=0,this.invertPoint(e,t)}function h(t,e){e=this.getMatrix(e);return this.invertPoint(e,t)}function l(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length)for(var i=this._elem.hierarchy.length,r=0;r<i;r+=1)this._elem.hierarchy[r].finalTransform.mProp.applyToMatrix(t);return t.applyToPointArray(e[0],e[1],e[2]||0)}function p(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length)for(var i=this._elem.hierarchy.length,r=0;r<i;r+=1)this._elem.hierarchy[r].finalTransform.mProp.applyToMatrix(t);return t.inversePoint(e)}function m(t){var e=new Matrix;if(e.reset(),this._elem.finalTransform.mProp.applyToMatrix(e),this._elem.hierarchy&&this._elem.hierarchy.length)for(var i=this._elem.hierarchy.length,r=0;r<i;r+=1)this._elem.hierarchy[r].finalTransform.mProp.applyToMatrix(e);return e.inversePoint(t)}function f(){return[1,1,1,1]}return function(e){function i(t){switch(t){case"ADBE Root Vectors Group":case"Contents":case 2:return i.shapeInterface;case 1:case 6:case"Transform":case"transform":case"ADBE Transform Group":return r;case 4:case"ADBE Effect Parade":case"effects":case"Effects":return i.effect;case"ADBE Text Properties":return i.textInterface;default:return null}}i.getMatrix=s,i.invertPoint=p,i.applyPoint=l,i.toWorld=n,i.toWorldVec=a,i.fromWorld=h,i.fromWorldVec=o,i.toComp=n,i.fromComp=m,i.sampleImage=f,i.sourceRectAtTime=e.sourceRectAtTime.bind(e);var r,t=getDescriptor(r=TransformExpressionInterface((i._elem=e).finalTransform.mProp),"anchorPoint");return Object.defineProperties(i,{hasParent:{get:function(){return e.hierarchy.length}},parent:{get:function(){return e.hierarchy[0].layerInterface}},rotation:getDescriptor(r,"rotation"),scale:getDescriptor(r,"scale"),position:getDescriptor(r,"position"),opacity:getDescriptor(r,"opacity"),anchorPoint:t,anchor_point:t,transform:{get:function(){return r}},active:{get:function(){return e.isInRange}}}),i.startTime=e.data.st,i.index=e.data.ind,i.source=e.data.refId,i.height=0===e.data.ty?e.data.h:100,i.width=0===e.data.ty?e.data.w:100,i.inPoint=e.data.ip/e.comp.globalData.frameRate,i.outPoint=e.data.op/e.comp.globalData.frameRate,i._name=e.data.nm,i.registerMaskInterface=function(t){i.mask=new MaskManagerInterface(t,e)},i.registerEffectsInterface=function(t){i.effect=t},i}})(),propertyGroupFactory=function(e,i){return function(t){return(t=void 0===t?1:t)<=0?e:i(t-1)}},PropertyInterface=function(t,e){var i={_name:t};return function(t){return(t=void 0===t?1:t)<=0?i:e(t-1)}},EffectsExpressionInterface=(()=>{function p(t,e,i,r){var s=ExpressionPropertyInterface(t.p);return t.p.setGroupProperty&&t.p.setGroupProperty(PropertyInterface("",r)),function(){return 10===e?i.comp.compInterface(t.p.v):s()}}return{createEffectsInterface:function(t,e){if(t.effectsManager){var i,r=[],s=t.data.ef,a=t.effectsManager.effectElements.length;for(i=0;i<a;i+=1)r.push(function t(s,e,i,r){function a(t){for(var e=s.ef,i=0,r=e.length;i<r;){if(t===e[i].nm||t===e[i].mn||t===e[i].ix)return 5===e[i].ty?o[i]:o[i]();i+=1}throw new Error}var n=propertyGroupFactory(a,i);var o=[];var h;var l=s.ef.length;for(h=0;h<l;h+=1)5===s.ef[h].ty?o.push(t(s.ef[h],e.effectElements[h],e.effectElements[h].propertyGroup,r)):o.push(p(e.effectElements[h],s.ef[h].ty,r,n));"ADBE Color Control"===s.mn&&Object.defineProperty(a,"color",{get:function(){return o[0]()}});Object.defineProperties(a,{numProperties:{get:function(){return s.np}},_name:{value:s.nm},propertyGroup:{value:n}});a.enabled=0!==s.en;a.active=a.enabled;return a}(s[i],t.effectsManager.effectElements[i],e,t));var n=t.data.ef||[],o=function(t){for(i=0,a=n.length;i<a;){if(t===n[i].nm||t===n[i].mn||t===n[i].ix)return r[i];i+=1}return null};return Object.defineProperty(o,"numProperties",{get:function(){return n.length}}),o}return null}}})(),ShapePathInterface=function(t,e,i){var r=e.sh;function s(t){return"Shape"===t||"shape"===t||"Path"===t||"path"===t||"ADBE Vector Shape"===t||2===t?s.path:null}e=propertyGroupFactory(s,i);return r.setGroupProperty(PropertyInterface("Path",e)),Object.defineProperties(s,{path:{get:function(){return r.k&&r.getValue(),r}},shape:{get:function(){return r.k&&r.getValue(),r}},_name:{value:t.nm},ix:{value:t.ix},propertyIndex:{value:t.ix},mn:{value:t.mn},propertyGroup:{value:i}}),s},ShapeExpressionInterface=(()=>{function n(t,e,i){for(var r=[],s=t?t.length:0,a=0;a<s;a+=1)"gr"===t[a].ty?r.push(((t,e,i)=>{function r(t){switch(t){case"ADBE Vectors Group":case"Contents":case 2:return r.content;default:return r.transform}}return r.propertyGroup=propertyGroupFactory(r,i),i=((t,e,i)=>{function r(t){for(var e=0,i=s.length;e<i;){if(s[e]._name===t||s[e].mn===t||s[e].propertyIndex===t||s[e].ix===t||s[e].ind===t)return s[e];e+=1}return"number"==typeof t?s[t-1]:null}r.propertyGroup=propertyGroupFactory(r,i),s=n(t.it,e.it,r.propertyGroup),r.numProperties=s.length;var s,i=o(t.it[t.it.length-1],e.it[e.it.length-1],r.propertyGroup);return r.transform=i,r.propertyIndex=t.cix,r._name=t.nm,r})(t,e,r.propertyGroup),e=o(t.it[t.it.length-1],e.it[e.it.length-1],r.propertyGroup),r.content=i,r.transform=e,Object.defineProperty(r,"_name",{get:function(){return t.nm}}),r.numProperties=t.np,r.propertyIndex=t.ix,r.nm=t.nm,r.mn=t.mn,r})(t[a],e[a],i)):"fl"===t[a].ty?r.push(((t,e,i)=>{function r(t){return"Color"===t||"color"===t?r.color:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r})(t[a],e[a],i)):"st"===t[a].ty?r.push(((t,e,i)=>{var r,i=propertyGroupFactory(h,i),s=propertyGroupFactory(void 0,i),a=t.d?t.d.length:0,n={};for(r=0;r<a;r+=1){{o=void 0;var o=r;Object.defineProperty(n,t.d[o].nm,{get:ExpressionPropertyInterface(e.d.dataProps[o].p)})}e.d.dataProps[r].p.setGroupProperty(s)}function h(t){return"Color"===t||"color"===t?h.color:"Opacity"===t||"opacity"===t?h.opacity:"Stroke Width"===t||"stroke width"===t?h.strokeWidth:null}return Object.defineProperties(h,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},strokeWidth:{get:ExpressionPropertyInterface(e.w)},dash:{get:function(){return n}},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),e.w.setGroupProperty(PropertyInterface("Stroke Width",i)),h})(t[a],e[a],i)):"tm"===t[a].ty?r.push(((e,t,i)=>{function r(t){return t===e.e.ix||"End"===t||"end"===t?r.end:t===e.s.ix?r.start:t===e.o.ix?r.offset:null}var s=propertyGroupFactory(r,i);return r.propertyIndex=e.ix,t.s.setGroupProperty(PropertyInterface("Start",s)),t.e.setGroupProperty(PropertyInterface("End",s)),t.o.setGroupProperty(PropertyInterface("Offset",s)),r.propertyIndex=e.ix,r.propertyGroup=i,Object.defineProperties(r,{start:{get:ExpressionPropertyInterface(t.s)},end:{get:ExpressionPropertyInterface(t.e)},offset:{get:ExpressionPropertyInterface(t.o)},_name:{value:e.nm}}),r.mn=e.mn,r})(t[a],e[a],i)):"tr"!==t[a].ty&&("el"===t[a].ty?r.push(((e,t,i)=>{function r(t){return e.p.ix===t?r.position:e.s.ix===t?r.size:null}return i=propertyGroupFactory(r,i),r.propertyIndex=e.ix,(t="tm"===t.sh.ty?t.sh.prop:t.sh).s.setGroupProperty(PropertyInterface("Size",i)),t.p.setGroupProperty(PropertyInterface("Position",i)),Object.defineProperties(r,{size:{get:ExpressionPropertyInterface(t.s)},position:{get:ExpressionPropertyInterface(t.p)},_name:{value:e.nm}}),r.mn=e.mn,r})(t[a],e[a],i)):"sr"===t[a].ty?r.push(((e,t,i)=>{function r(t){return e.p.ix===t?r.position:e.r.ix===t?r.rotation:e.pt.ix===t?r.points:e.or.ix===t||"ADBE Vector Star Outer Radius"===t?r.outerRadius:e.os.ix===t?r.outerRoundness:!e.ir||e.ir.ix!==t&&"ADBE Vector Star Inner Radius"!==t?e.is&&e.is.ix===t?r.innerRoundness:null:r.innerRadius}return i=propertyGroupFactory(r,i),t="tm"===t.sh.ty?t.sh.prop:t.sh,r.propertyIndex=e.ix,t.or.setGroupProperty(PropertyInterface("Outer Radius",i)),t.os.setGroupProperty(PropertyInterface("Outer Roundness",i)),t.pt.setGroupProperty(PropertyInterface("Points",i)),t.p.setGroupProperty(PropertyInterface("Position",i)),t.r.setGroupProperty(PropertyInterface("Rotation",i)),e.ir&&(t.ir.setGroupProperty(PropertyInterface("Inner Radius",i)),t.is.setGroupProperty(PropertyInterface("Inner Roundness",i))),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(t.p)},rotation:{get:ExpressionPropertyInterface(t.r)},points:{get:ExpressionPropertyInterface(t.pt)},outerRadius:{get:ExpressionPropertyInterface(t.or)},outerRoundness:{get:ExpressionPropertyInterface(t.os)},innerRadius:{get:ExpressionPropertyInterface(t.ir)},innerRoundness:{get:ExpressionPropertyInterface(t.is)},_name:{value:e.nm}}),r.mn=e.mn,r})(t[a],e[a],i)):"sh"===t[a].ty?r.push(ShapePathInterface(t[a],e[a],i)):"rc"===t[a].ty?r.push(((e,t,i)=>{function r(t){return e.p.ix===t?r.position:e.r.ix===t?r.roundness:e.s.ix===t||"Size"===t||"ADBE Vector Rect Size"===t?r.size:null}return i=propertyGroupFactory(r,i),t="tm"===t.sh.ty?t.sh.prop:t.sh,r.propertyIndex=e.ix,t.p.setGroupProperty(PropertyInterface("Position",i)),t.s.setGroupProperty(PropertyInterface("Size",i)),t.r.setGroupProperty(PropertyInterface("Rotation",i)),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(t.p)},roundness:{get:ExpressionPropertyInterface(t.r)},size:{get:ExpressionPropertyInterface(t.s)},_name:{value:e.nm}}),r.mn=e.mn,r})(t[a],e[a],i)):"rd"===t[a].ty?r.push(((e,t,i)=>{function r(t){return e.r.ix===t||"Round Corners 1"===t?r.radius:null}return i=propertyGroupFactory(r,i),r.propertyIndex=e.ix,t.rd.setGroupProperty(PropertyInterface("Radius",i)),Object.defineProperties(r,{radius:{get:ExpressionPropertyInterface(t.rd)},_name:{value:e.nm}}),r.mn=e.mn,r})(t[a],e[a],i)):"rp"===t[a].ty?r.push(((e,t,i)=>{function r(t){return e.c.ix===t||"Copies"===t?r.copies:e.o.ix===t||"Offset"===t?r.offset:null}return i=propertyGroupFactory(r,i),r.propertyIndex=e.ix,t.c.setGroupProperty(PropertyInterface("Copies",i)),t.o.setGroupProperty(PropertyInterface("Offset",i)),Object.defineProperties(r,{copies:{get:ExpressionPropertyInterface(t.c)},offset:{get:ExpressionPropertyInterface(t.o)},_name:{value:e.nm}}),r.mn=e.mn,r})(t[a],e[a],i)):"gf"===t[a].ty?r.push(((t,e,i)=>{function r(t){return"Start Point"===t||"start point"===t?r.startPoint:"End Point"===t||"end point"===t?r.endPoint:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{startPoint:{get:ExpressionPropertyInterface(e.s)},endPoint:{get:ExpressionPropertyInterface(e.e)},opacity:{get:ExpressionPropertyInterface(e.o)},type:{get:function(){return"a"}},_name:{value:t.nm},mn:{value:t.mn}}),e.s.setGroupProperty(PropertyInterface("Start Point",i)),e.e.setGroupProperty(PropertyInterface("End Point",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r})(t[a],e[a],i)):r.push((t[a],e[a],function(){return null})));return r}function o(e,t,i){function r(t){return e.a.ix===t||"Anchor Point"===t?r.anchorPoint:e.o.ix===t||"Opacity"===t?r.opacity:e.p.ix===t||"Position"===t?r.position:e.r.ix===t||"Rotation"===t||"ADBE Vector Rotation"===t?r.rotation:e.s.ix===t||"Scale"===t?r.scale:e.sk&&e.sk.ix===t||"Skew"===t?r.skew:e.sa&&e.sa.ix===t||"Skew Axis"===t?r.skewAxis:null}var s=propertyGroupFactory(r,i);return t.transform.mProps.o.setGroupProperty(PropertyInterface("Opacity",s)),t.transform.mProps.p.setGroupProperty(PropertyInterface("Position",s)),t.transform.mProps.a.setGroupProperty(PropertyInterface("Anchor Point",s)),t.transform.mProps.s.setGroupProperty(PropertyInterface("Scale",s)),t.transform.mProps.r.setGroupProperty(PropertyInterface("Rotation",s)),t.transform.mProps.sk&&(t.transform.mProps.sk.setGroupProperty(PropertyInterface("Skew",s)),t.transform.mProps.sa.setGroupProperty(PropertyInterface("Skew Angle",s))),t.transform.op.setGroupProperty(PropertyInterface("Opacity",s)),Object.defineProperties(r,{opacity:{get:ExpressionPropertyInterface(t.transform.mProps.o)},position:{get:ExpressionPropertyInterface(t.transform.mProps.p)},anchorPoint:{get:ExpressionPropertyInterface(t.transform.mProps.a)},scale:{get:ExpressionPropertyInterface(t.transform.mProps.s)},rotation:{get:ExpressionPropertyInterface(t.transform.mProps.r)},skew:{get:ExpressionPropertyInterface(t.transform.mProps.sk)},skewAxis:{get:ExpressionPropertyInterface(t.transform.mProps.sa)},_name:{value:e.nm}}),r.ty="tr",r.mn=e.mn,r.propertyGroup=i,r}return function(t,e,r){var s;function i(t){if("number"==typeof t)return 0===(t=void 0===t?1:t)?r:s[t-1];for(var e=0,i=s.length;e<i;){if(s[e]._name===t)return s[e];e+=1}return null}return i.propertyGroup=propertyGroupFactory(i,function(){return r}),s=n(t,e,i.propertyGroup),i.numProperties=s.length,i._name="Contents",i}})(),TextExpressionInterface=function(e){var i;function r(t){return"ADBE Text Document"!==t?null:r.sourceText}return Object.defineProperty(r,"sourceText",{get:function(){e.textProperty.getValue();var t=e.textProperty.currentData.t;return i&&t===i.value||((i=new String(t)).value=t||new String(t),Object.defineProperty(i,"style",{get:function(){return{fillColor:e.textProperty.currentData.fc}}})),i}}),r};function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var FootageInterface=(()=>{var r=function(t){var i="",r=t.getFootageData();function s(t){var e;return r[t]?"object"===_typeof(r=r[i=t])?s:r:-1!==(e=t.indexOf(i))?(t=parseInt(t.substr(e+i.length),10),"object"===_typeof(r=r[t])?s:r):""}return function(){return i="",r=t.getFootageData(),s}};return function(t){function e(t){return"Data"===t?e.dataInterface:null}function i(t){return"Outline"===t?i.outlineInterface():null}return e._name="Data",e.dataInterface=(t=t,i._name="Outline",i.outlineInterface=r(t),i),e}})(),interfaces={layer:LayerExpressionInterface,effects:EffectsExpressionInterface,comp:CompExpressionInterface,shape:ShapeExpressionInterface,text:TextExpressionInterface,footage:FootageInterface};function getInterface(t){return interfaces[t]||null}var expressionHelpers={searchExpressions:function(t,e,i){e.x&&(i.k=!0,i.x=!0,i.initiateExpression=ExpressionManager.initiateExpression,i.effectsSequence.push(i.initiateExpression(t,e,i).bind(i)))},getSpeedAtTime:function(t){var e=this.getValueAtTime(t),i=this.getValueAtTime(t+-.01),r=0;if(e.length){for(var s=0;s<e.length;s+=1)r+=Math.pow(i[s]-e[s],2);r=100*Math.sqrt(r)}else r=0;return r},getVelocityAtTime:function(t){if(void 0!==this.vel)return this.vel;var e=this.getValueAtTime(t),i=this.getValueAtTime(t+-.001);if(e.length)for(var r=createTypedArray("float32",e.length),s=0;s<e.length;s+=1)r[s]=(i[s]-e[s])/-.001;else r=(i-e)/-.001;return r},getValueAtTime:function(t){return(t=(t*=this.elem.globalData.frameRate)-this.offsetTime)!==this._cachingAtTime.lastFrame&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastFrame<t?this._cachingAtTime.lastIndex:0,this._cachingAtTime.value=this.interpolateValue(t,this._cachingAtTime),this._cachingAtTime.lastFrame=t),this._cachingAtTime.value},getStaticValueAtTime:function(){return this.pv},setGroupProperty:function(t){this.propertyGroup=t}};function addPropertyDecorator(){function n(t,e,i){if(!this.k||!this.keyframes)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[l.length-1].t;if(h<=p)return this.pv;if(i?s=p-(r=e?Math.abs(p-this.elem.comp.globalData.frameRate*e):Math.max(0,p-this.elem.data.ip)):((!e||e>l.length-1)&&(e=l.length-1),r=p-(s=l[l.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/r)%2!=0)return this.getValueAtTime((r-(h-s)%r+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var m=this.getValueAtTime(s/this.comp.globalData.frameRate,0),f=this.getValueAtTime(p/this.comp.globalData.frameRate,0),c=this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0),d=Math.floor((h-s)/r);if(this.pv.length){for(n=(o=new Array(m.length)).length,a=0;a<n;a+=1)o[a]=(f[a]-m[a])*d+c[a];return o}return(f-m)*d+c}if("continue"===t){var u=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p-.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*((h-p)/this.comp.globalData.frameRate)/5e-4;return o}return u+(h-p)/.001*(u-y)}}return this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0)}function o(t,e,i){if(!this.k)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[0].t;if(p<=h)return this.pv;if(i?s=p+(r=e?Math.abs(this.elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-p)):r=(s=l[e=!e||e>l.length-1?l.length-1:e].t)-p,"pingpong"===t){if(Math.floor((p-h)/r)%2==0)return this.getValueAtTime(((p-h)%r+p)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var m=this.getValueAtTime(p/this.comp.globalData.frameRate,0),f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime((r-(p-h)%r+p)/this.comp.globalData.frameRate,0),d=Math.floor((p-h)/r)+1;if(this.pv.length){for(n=(o=new Array(m.length)).length,a=0;a<n;a+=1)o[a]=c[a]-(f[a]-m[a])*d;return o}return c-(f-m)*d}if("continue"===t){var u=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p+.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*(p-h)/.001;return o}return u+(u-y)*(p-h)/.001}}return this.getValueAtTime((r-((p-h)%r+p))/this.comp.globalData.frameRate,0)}function h(t,e){if(!this.k)return this.pv;if(t=.5*(t||.4),(e=Math.floor(e||5))<=1)return this.pv;for(var i,r=this.comp.renderedFrame/this.comp.globalData.frameRate,s=r-t,a=1<e?(r+t-s)/(e-1):1,n=0,o=0,h=this.pv.length?createTypedArray("float32",this.pv.length):0;n<e;){if(i=this.getValueAtTime(s+n*a),this.pv.length)for(o=0;o<this.pv.length;o+=1)h[o]+=i[o];else h+=i;n+=1}if(this.pv.length)for(o=0;o<this.pv.length;o+=1)h[o]/=e;else h/=e;return h}var r=TransformPropertyFactory.getTransformProperty,l=(TransformPropertyFactory.getTransformProperty=function(t,e,i){t=r(t,e,i);return t.dynamicProperties.length?t.getValueAtTime=function(t){this._transformCachingAtTime||(this._transformCachingAtTime={v:new Matrix});var e,i,r,s,a=this._transformCachingAtTime.v;return a.cloneFromProps(this.pre.props),this.appliedTransformations<1&&(i=this.a.getValueAtTime(t),a.translate(-i[0]*this.a.mult,-i[1]*this.a.mult,i[2]*this.a.mult)),this.appliedTransformations<2&&(i=this.s.getValueAtTime(t),a.scale(i[0]*this.s.mult,i[1]*this.s.mult,i[2]*this.s.mult)),this.sk&&this.appliedTransformations<3&&(i=this.sk.getValueAtTime(t),e=this.sa.getValueAtTime(t),a.skewFromAxis(-i*this.sk.mult,e*this.sa.mult)),this.r&&this.appliedTransformations<4?(i=this.r.getValueAtTime(t),a.rotate(-i*this.r.mult)):!this.r&&this.appliedTransformations<4&&(e=this.rz.getValueAtTime(t),i=this.ry.getValueAtTime(t),r=this.rx.getValueAtTime(t),s=this.or.getValueAtTime(t),a.rotateZ(-e*this.rz.mult).rotateY(i*this.ry.mult).rotateX(r*this.rx.mult).rotateZ(-s[2]*this.or.mult).rotateY(s[1]*this.or.mult).rotateX(s[0]*this.or.mult)),this.data.p&&this.data.p.s?(e=this.px.getValueAtTime(t),i=this.py.getValueAtTime(t),this.data.p.z?(r=this.pz.getValueAtTime(t),a.translate(e*this.px.mult,i*this.py.mult,-r*this.pz.mult)):a.translate(e*this.px.mult,i*this.py.mult,0)):(s=this.p.getValueAtTime(t),a.translate(s[0]*this.p.mult,s[1]*this.p.mult,-s[2]*this.p.mult)),a}.bind(t):t.getValueAtTime=function(){return this.v.clone(new Matrix)}.bind(t),t.setGroupProperty=expressionHelpers.setGroupProperty,t},PropertyFactory.getProp);PropertyFactory.getProp=function(t,e,i,r,s){var r=l(t,e,i,r,s),a=(r.kf?r.getValueAtTime=expressionHelpers.getValueAtTime.bind(r):r.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(r),r.setGroupProperty=expressionHelpers.setGroupProperty,r.loopOut=n,r.loopIn=o,r.smooth=h,r.getVelocityAtTime=expressionHelpers.getVelocityAtTime.bind(r),r.getSpeedAtTime=expressionHelpers.getSpeedAtTime.bind(r),r.numKeys=1===e.a?e.k.length:0,r.propertyIndex=e.ix,0);return 0!==i&&(a=createTypedArray("float32",(1===e.a?e.k[0].s:e.k).length)),r._cachingAtTime={lastFrame:initialDefaultFrame,lastIndex:0,value:a},expressionHelpers.searchExpressions(t,e,r),r.k&&s.addDynamicProperty(r),r};var t=ShapePropertyFactory.getConstructorFunction(),e=ShapePropertyFactory.getKeyframedConstructorFunction();function i(){}i.prototype={vertices:function(t,e){this.k&&this.getValue();for(var i=this.v,r=(i=void 0!==e?this.getValueAtTime(e,0):i)._length,s=i[t],a=i.v,n=createSizedArray(r),o=0;o<r;o+=1)n[o]="i"===t||"o"===t?[s[o][0]-a[o][0],s[o][1]-a[o][1]]:[s[o][0],s[o][1]];return n},points:function(t){return this.vertices("v",t)},inTangents:function(t){return this.vertices("i",t)},outTangents:function(t){return this.vertices("o",t)},isClosed:function(){return this.v.c},pointOnPath:function(t,e){for(var i=this.v,e=(void 0!==e&&(i=this.getValueAtTime(e,0)),this._segmentsLength||(this._segmentsLength=bez.getSegmentsLength(i)),this._segmentsLength),r=e.lengths,s=e.totalLength*t,a=0,n=r.length,o=0;a<n;){if(o+r[a].addedLength>s){var h=a,l=i.c&&a===n-1?0:a+1,p=(s-o)/r[a].addedLength,m=bez.getPointInSegment(i.v[h],i.v[l],i.o[h],i.i[l],p,r[a]);break}o+=r[a].addedLength,a+=1}return m=m||(i.c?[i.v[0][0],i.v[0][1]]:[i.v[i._length-1][0],i.v[i._length-1][1]])},vectorOnPath:function(t,e,i){1==t?t=this.v.c:0==t&&(t=.999);var r=this.pointOnPath(t,e),t=this.pointOnPath(t+.001,e),e=t[0]-r[0],t=t[1]-r[1],r=Math.sqrt(Math.pow(e,2)+Math.pow(t,2));return 0===r?[0,0]:"tangent"===i?[e/r,t/r]:[-t/r,e/r]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([i],t),extendPrototype([i],e),e.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shapePool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),(t=(t*=this.elem.globalData.frameRate)-this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime<t?this._caching.lastIndex:0,this._cachingAtTime.lastTime=t,this.interpolateShape(t,this._cachingAtTime.shapeValue,this._cachingAtTime)),this._cachingAtTime.shapeValue},e.prototype.initiateExpression=ExpressionManager.initiateExpression;var a=ShapePropertyFactory.getShapeProp;ShapePropertyFactory.getShapeProp=function(t,e,i,r,s){r=a(t,e,i,r,s);return r.propertyIndex=e.ix,r.lock=!1,3===i?expressionHelpers.searchExpressions(t,e.pt,r):4===i&&expressionHelpers.searchExpressions(t,e.ks,r),r.k&&t.addDynamicProperty(r),r}}function initialize$1(){addPropertyDecorator()}function addDecorator(){TextProperty.prototype.getExpressionValue=function(t,e){var i,e=this.calculateExpression(e);return t.t!==e?(this.copyData(i={},t),i.t=e.toString(),i.__complete=!1,i):t},TextProperty.prototype.searchProperty=function(){var t=this.searchKeyframes(),e=this.searchExpressions();return this.kf=t||e,this.kf},TextProperty.prototype.searchExpressions=function(){return this.data.d.x?(this.calculateExpression=ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this),this.addEffect(this.getExpressionValue.bind(this)),!0):null}}function initialize(){addDecorator()}function SVGComposableEffect(){}SVGComposableEffect.prototype={createMergeNode:function(t,e){var i,r,s=createNS("feMerge");for(s.setAttribute("result",t),r=0;r<e.length;r+=1)(i=createNS("feMergeNode")).setAttribute("in",e[r]),s.appendChild(i),s.appendChild(i);return s}};var linearFilterValue="0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0";function SVGTintFilter(t,e,i,r,s){this.filterManager=e;e=createNS("feColorMatrix"),e.setAttribute("type","matrix"),e.setAttribute("color-interpolation-filters","linearRGB"),e.setAttribute("values",linearFilterValue+" 1 0"),(this.linearFilter=e).setAttribute("result",r+"_tint_1"),t.appendChild(e),(e=createNS("feColorMatrix")).setAttribute("type","matrix"),e.setAttribute("color-interpolation-filters","sRGB"),e.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),e.setAttribute("result",r+"_tint_2"),t.appendChild(e),this.matrixFilter=e,e=this.createMergeNode(r,[s,r+"_tint_1",r+"_tint_2"]);t.appendChild(e)}function SVGFillFilter(t,e,i,r){this.filterManager=e;e=createNS("feColorMatrix");e.setAttribute("type","matrix"),e.setAttribute("color-interpolation-filters","sRGB"),e.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),e.setAttribute("result",r),t.appendChild(e),this.matrixFilter=e}function SVGStrokeEffect(t,e,i){this.initialized=!1,this.filterManager=e,this.elem=i,this.paths=[]}function SVGTritoneFilter(t,e,i,r){this.filterManager=e;e=createNS("feColorMatrix"),e.setAttribute("type","matrix"),e.setAttribute("color-interpolation-filters","linearRGB"),e.setAttribute("values","0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0"),t.appendChild(e),e=createNS("feComponentTransfer"),e.setAttribute("color-interpolation-filters","sRGB"),e.setAttribute("result",r),this.matrixFilter=e,r=createNS("feFuncR"),r.setAttribute("type","table"),e.appendChild(r),this.feFuncR=r,r=createNS("feFuncG"),r.setAttribute("type","table"),e.appendChild(r),this.feFuncG=r,r=createNS("feFuncB");r.setAttribute("type","table"),e.appendChild(r),this.feFuncB=r,t.appendChild(e)}function SVGProLevelsFilter(t,e,i,r){this.filterManager=e;var e=this.filterManager.effectElements,s=createNS("feComponentTransfer");(e[10].p.k||0!==e[10].p.v||e[11].p.k||1!==e[11].p.v||e[12].p.k||1!==e[12].p.v||e[13].p.k||0!==e[13].p.v||e[14].p.k||1!==e[14].p.v)&&(this.feFuncR=this.createFeFunc("feFuncR",s)),(e[17].p.k||0!==e[17].p.v||e[18].p.k||1!==e[18].p.v||e[19].p.k||1!==e[19].p.v||e[20].p.k||0!==e[20].p.v||e[21].p.k||1!==e[21].p.v)&&(this.feFuncG=this.createFeFunc("feFuncG",s)),(e[24].p.k||0!==e[24].p.v||e[25].p.k||1!==e[25].p.v||e[26].p.k||1!==e[26].p.v||e[27].p.k||0!==e[27].p.v||e[28].p.k||1!==e[28].p.v)&&(this.feFuncB=this.createFeFunc("feFuncB",s)),(e[31].p.k||0!==e[31].p.v||e[32].p.k||1!==e[32].p.v||e[33].p.k||1!==e[33].p.v||e[34].p.k||0!==e[34].p.v||e[35].p.k||1!==e[35].p.v)&&(this.feFuncA=this.createFeFunc("feFuncA",s)),(this.feFuncR||this.feFuncG||this.feFuncB||this.feFuncA)&&(s.setAttribute("color-interpolation-filters","sRGB"),t.appendChild(s)),(e[3].p.k||0!==e[3].p.v||e[4].p.k||1!==e[4].p.v||e[5].p.k||1!==e[5].p.v||e[6].p.k||0!==e[6].p.v||e[7].p.k||1!==e[7].p.v)&&((s=createNS("feComponentTransfer")).setAttribute("color-interpolation-filters","sRGB"),s.setAttribute("result",r),t.appendChild(s),this.feFuncRComposed=this.createFeFunc("feFuncR",s),this.feFuncGComposed=this.createFeFunc("feFuncG",s),this.feFuncBComposed=this.createFeFunc("feFuncB",s))}function SVGDropShadowEffect(t,e,i,r,s){var a=e.container.globalData.renderConfig.filterSize,n=e.data.fs||a,n=(t.setAttribute("x",n.x||a.x),t.setAttribute("y",n.y||a.y),t.setAttribute("width",n.width||a.width),t.setAttribute("height",n.height||a.height),this.filterManager=e,createNS("feGaussianBlur")),a=(n.setAttribute("in","SourceAlpha"),n.setAttribute("result",r+"_drop_shadow_1"),n.setAttribute("stdDeviation","0"),this.feGaussianBlur=n,t.appendChild(n),createNS("feOffset")),e=(a.setAttribute("dx","25"),a.setAttribute("dy","0"),a.setAttribute("in",r+"_drop_shadow_1"),a.setAttribute("result",r+"_drop_shadow_2"),this.feOffset=a,t.appendChild(a),createNS("feFlood")),n=(e.setAttribute("flood-color","#00ff00"),e.setAttribute("flood-opacity","1"),e.setAttribute("result",r+"_drop_shadow_3"),this.feFlood=e,t.appendChild(e),createNS("feComposite")),a=(n.setAttribute("in",r+"_drop_shadow_3"),n.setAttribute("in2",r+"_drop_shadow_2"),n.setAttribute("operator","in"),n.setAttribute("result",r+"_drop_shadow_4"),t.appendChild(n),this.createMergeNode(r,[r+"_drop_shadow_4",s]));t.appendChild(a)}extendPrototype([SVGComposableEffect],SVGTintFilter),SVGTintFilter.prototype.renderFrame=function(t){var e,i;(t||this.filterManager._mdf)&&(t=this.filterManager.effectElements[0].p.v,e=this.filterManager.effectElements[1].p.v,i=this.filterManager.effectElements[2].p.v/100,this.linearFilter.setAttribute("values",linearFilterValue+" "+i+" 0"),this.matrixFilter.setAttribute("values",e[0]-t[0]+" 0 0 0 "+t[0]+" "+(e[1]-t[1])+" 0 0 0 "+t[1]+" "+(e[2]-t[2])+" 0 0 0 "+t[2]+" 0 0 0 1 0"))},SVGFillFilter.prototype.renderFrame=function(t){var e;(t||this.filterManager._mdf)&&(t=this.filterManager.effectElements[2].p.v,e=this.filterManager.effectElements[6].p.v,this.matrixFilter.setAttribute("values","0 0 0 0 "+t[0]+" 0 0 0 0 "+t[1]+" 0 0 0 0 "+t[2]+" 0 0 0 "+e+" 0"))},SVGStrokeEffect.prototype.initialize=function(){var t,e,i,r,s=this.elem.layerElement.children||this.elem.layerElement.childNodes;for(1===this.filterManager.effectElements[1].p.v?(r=this.elem.maskManager.masksProperties.length,i=0):r=(i=this.filterManager.effectElements[0].p.v-1)+1,(e=createNS("g")).setAttribute("fill","none"),e.setAttribute("stroke-linecap","round"),e.setAttribute("stroke-dashoffset",1);i<r;i+=1)t=createNS("path"),e.appendChild(t),this.paths.push({p:t,m:i});if(3===this.filterManager.effectElements[10].p.v){var a=createNS("mask"),n=createElementID(),o=(a.setAttribute("id",n),a.setAttribute("mask-type","alpha"),a.appendChild(e),this.elem.globalData.defs.appendChild(a),createNS("g"));for(o.setAttribute("mask","url("+getLocationHref()+"#"+n+")");s[0];)o.appendChild(s[0]);this.elem.layerElement.appendChild(o),this.masker=a,e.setAttribute("stroke","#fff")}else if(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v){if(2===this.filterManager.effectElements[10].p.v)for(s=this.elem.layerElement.children||this.elem.layerElement.childNodes;s.length;)this.elem.layerElement.removeChild(s[0]);this.elem.layerElement.appendChild(e),this.elem.layerElement.removeAttribute("mask"),e.setAttribute("stroke","#fff")}this.initialized=!0,this.pathMasker=e},SVGStrokeEffect.prototype.renderFrame=function(t){this.initialized||this.initialize();for(var e,i,r=this.paths.length,s=0;s<r;s+=1)if(-1!==this.paths[s].m&&(a=this.elem.maskManager.viewData[this.paths[s].m],e=this.paths[s].p,(t||this.filterManager._mdf||a.prop._mdf)&&e.setAttribute("d",a.lastPath),t||this.filterManager.effectElements[9].p._mdf||this.filterManager.effectElements[4].p._mdf||this.filterManager.effectElements[7].p._mdf||this.filterManager.effectElements[8].p._mdf||a.prop._mdf)){if(0!==this.filterManager.effectElements[7].p.v||100!==this.filterManager.effectElements[8].p.v){for(var a=.01*Math.min(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),n=.01*Math.max(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),o=e.getTotalLength(),h="0 0 0 "+o*a+" ",l=1+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01,p=Math.floor(o*(n-a)/l),m=0;m<p;m+=1)h+="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01+" ";h+="0 "+10*o+" 0 0"}else h="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01;e.setAttribute("stroke-dasharray",h)}(t||this.filterManager.effectElements[4].p._mdf)&&this.pathMasker.setAttribute("stroke-width",2*this.filterManager.effectElements[4].p.v),(t||this.filterManager.effectElements[6].p._mdf)&&this.pathMasker.setAttribute("opacity",this.filterManager.effectElements[6].p.v),1!==this.filterManager.effectElements[10].p.v&&2!==this.filterManager.effectElements[10].p.v||(t||this.filterManager.effectElements[3].p._mdf)&&(i=this.filterManager.effectElements[3].p.v,this.pathMasker.setAttribute("stroke","rgb("+bmFloor(255*i[0])+","+bmFloor(255*i[1])+","+bmFloor(255*i[2])+")"))},SVGTritoneFilter.prototype.renderFrame=function(t){var e,i,r,s;(t||this.filterManager._mdf)&&(t=this.filterManager.effectElements[0].p.v,e=this.filterManager.effectElements[1].p.v,i=(s=this.filterManager.effectElements[2].p.v)[0]+" "+e[0]+" "+t[0],r=s[1]+" "+e[1]+" "+t[1],s=s[2]+" "+e[2]+" "+t[2],this.feFuncR.setAttribute("tableValues",i),this.feFuncG.setAttribute("tableValues",r),this.feFuncB.setAttribute("tableValues",s))},SVGProLevelsFilter.prototype.createFeFunc=function(t,e){t=createNS(t);return t.setAttribute("type","table"),e.appendChild(t),t},SVGProLevelsFilter.prototype.getTableValue=function(t,e,i,r,s){for(var a,n=0,o=Math.min(t,e),h=Math.max(t,e),l=Array.call(null,{length:256}),p=0,m=s-r,f=e-t;n<=256;)a=(a=n/256)<=o?f<0?s:r:h<=a?f<0?r:s:r+m*Math.pow((a-t)/f,1/i),l[p]=a,p+=1,n+=256/255;return l.join(" ")},SVGProLevelsFilter.prototype.renderFrame=function(t){var e,i;(t||this.filterManager._mdf)&&(i=this.filterManager.effectElements,this.feFuncRComposed&&(t||i[3].p._mdf||i[4].p._mdf||i[5].p._mdf||i[6].p._mdf||i[7].p._mdf)&&(e=this.getTableValue(i[3].p.v,i[4].p.v,i[5].p.v,i[6].p.v,i[7].p.v),this.feFuncRComposed.setAttribute("tableValues",e),this.feFuncGComposed.setAttribute("tableValues",e),this.feFuncBComposed.setAttribute("tableValues",e)),this.feFuncR&&(t||i[10].p._mdf||i[11].p._mdf||i[12].p._mdf||i[13].p._mdf||i[14].p._mdf)&&(e=this.getTableValue(i[10].p.v,i[11].p.v,i[12].p.v,i[13].p.v,i[14].p.v),this.feFuncR.setAttribute("tableValues",e)),this.feFuncG&&(t||i[17].p._mdf||i[18].p._mdf||i[19].p._mdf||i[20].p._mdf||i[21].p._mdf)&&(e=this.getTableValue(i[17].p.v,i[18].p.v,i[19].p.v,i[20].p.v,i[21].p.v),this.feFuncG.setAttribute("tableValues",e)),this.feFuncB&&(t||i[24].p._mdf||i[25].p._mdf||i[26].p._mdf||i[27].p._mdf||i[28].p._mdf)&&(e=this.getTableValue(i[24].p.v,i[25].p.v,i[26].p.v,i[27].p.v,i[28].p.v),this.feFuncB.setAttribute("tableValues",e)),this.feFuncA)&&(t||i[31].p._mdf||i[32].p._mdf||i[33].p._mdf||i[34].p._mdf||i[35].p._mdf)&&(e=this.getTableValue(i[31].p.v,i[32].p.v,i[33].p.v,i[34].p.v,i[35].p.v),this.feFuncA.setAttribute("tableValues",e))},extendPrototype([SVGComposableEffect],SVGDropShadowEffect),SVGDropShadowEffect.prototype.renderFrame=function(t){var e,i;(t||this.filterManager._mdf)&&((t||this.filterManager.effectElements[4].p._mdf)&&this.feGaussianBlur.setAttribute("stdDeviation",this.filterManager.effectElements[4].p.v/4),(t||this.filterManager.effectElements[0].p._mdf)&&(i=this.filterManager.effectElements[0].p.v,this.feFlood.setAttribute("flood-color",rgbToHex(Math.round(255*i[0]),Math.round(255*i[1]),Math.round(255*i[2])))),(t||this.filterManager.effectElements[1].p._mdf)&&this.feFlood.setAttribute("flood-opacity",this.filterManager.effectElements[1].p.v/255),t||this.filterManager.effectElements[2].p._mdf||this.filterManager.effectElements[3].p._mdf)&&(i=this.filterManager.effectElements[3].p.v,t=(this.filterManager.effectElements[2].p.v-90)*degToRads,e=i*Math.cos(t),i=i*Math.sin(t),this.feOffset.setAttribute("dx",e),this.feOffset.setAttribute("dy",i))};var _svgMatteSymbols=[];function SVGMatte3Effect(t,e,i){this.initialized=!1,this.filterManager=e,this.filterElem=t,(this.elem=i).matteElement=createNS("g"),i.matteElement.appendChild(i.layerElement),i.matteElement.appendChild(i.transformedElement),i.baseElement=i.matteElement}function SVGGaussianBlurEffect(t,e,i,r){t.setAttribute("x","-100%"),t.setAttribute("y","-100%"),t.setAttribute("width","300%"),t.setAttribute("height","300%"),this.filterManager=e;e=createNS("feGaussianBlur");e.setAttribute("result",r),t.appendChild(e),this.feGaussianBlur=e}function TransformEffect(){}function SVGTransformEffect(t,e){this.init(e)}function CVTransformEffect(t){this.init(t)}return SVGMatte3Effect.prototype.findSymbol=function(t){for(var e=0,i=_svgMatteSymbols.length;e<i;){if(_svgMatteSymbols[e]===t)return _svgMatteSymbols[e];e+=1}return null},SVGMatte3Effect.prototype.replaceInParent=function(t,e){var i=t.layerElement.parentNode;if(i){for(var r,s=i.children,a=0,n=s.length;a<n&&s[a]!==t.layerElement;)a+=1;a<=n-2&&(r=s[a+1]);var o=createNS("use");o.setAttribute("href","#"+e),r?i.insertBefore(o,r):i.appendChild(o)}},SVGMatte3Effect.prototype.setElementAsMask=function(t,e){var i,r,s,a;this.findSymbol(e)||(i=createElementID(),(r=createNS("mask")).setAttribute("id",e.layerId),r.setAttribute("mask-type","alpha"),_svgMatteSymbols.push(e),(a=t.globalData.defs).appendChild(r),(s=createNS("symbol")).setAttribute("id",i),this.replaceInParent(e,i),s.appendChild(e.layerElement),a.appendChild(s),(a=createNS("use")).setAttribute("href","#"+i),r.appendChild(a),e.data.hd=!1,e.show()),t.setMatte(e.layerId)},SVGMatte3Effect.prototype.initialize=function(){for(var t=this.filterManager.effectElements[0].p.v,e=this.elem.comp.elements,i=0,r=e.length;i<r;)e[i]&&e[i].data.ind===t&&this.setElementAsMask(this.elem,e[i]),i+=1;this.initialized=!0},SVGMatte3Effect.prototype.renderFrame=function(){this.initialized||this.initialize()},SVGGaussianBlurEffect.prototype.renderFrame=function(t){var e;(t||this.filterManager._mdf)&&(t=.3*this.filterManager.effectElements[0].p.v,e=this.filterManager.effectElements[1].p.v,this.feGaussianBlur.setAttribute("stdDeviation",(3==e?0:t)+" "+(2==e?0:t)),e=1==this.filterManager.effectElements[2].p.v?"wrap":"duplicate",this.feGaussianBlur.setAttribute("edgeMode",e))},TransformEffect.prototype.init=function(t){this.effectsManager=t,this.type=effectTypes.TRANSFORM_EFFECT,this.matrix=new Matrix,this.opacity=-1,this._mdf=!1,this._opMdf=!1},TransformEffect.prototype.renderFrame=function(t){var e,i,r,s,a,n,o;this._opMdf=!1,this._mdf=!1,(t||this.effectsManager._mdf)&&(e=(t=this.effectsManager.effectElements)[0].p.v,i=t[1].p.v,s=1===t[2].p.v,r=t[3].p.v,s=s?r:t[4].p.v,a=t[5].p.v,n=t[6].p.v,o=t[7].p.v,this.matrix.reset(),this.matrix.translate(-e[0],-e[1],e[2]),this.matrix.scale(.01*s,.01*r,1),this.matrix.rotate(-o*degToRads),this.matrix.skewFromAxis(-a*degToRads,(n+90)*degToRads),this.matrix.translate(i[0],i[1],0),this._mdf=!0,this.opacity!==t[8].p.v)&&(this.opacity=t[8].p.v,this._opMdf=!0)},extendPrototype([TransformEffect],SVGTransformEffect),extendPrototype([TransformEffect],CVTransformEffect),registerRenderer("canvas",CanvasRenderer),registerRenderer("html",HybridRenderer),registerRenderer("svg",SVGRenderer),ShapeModifiers.registerModifier("tm",TrimModifier),ShapeModifiers.registerModifier("pb",PuckerAndBloatModifier),ShapeModifiers.registerModifier("rp",RepeaterModifier),ShapeModifiers.registerModifier("rd",RoundCornersModifier),ShapeModifiers.registerModifier("zz",ZigZagModifier),ShapeModifiers.registerModifier("op",OffsetPathModifier),setExpressionsPlugin(Expressions),setExpressionInterfaces(getInterface),initialize$1(),initialize(),registerEffect$1(20,SVGTintFilter,!0),registerEffect$1(21,SVGFillFilter,!0),registerEffect$1(22,SVGStrokeEffect,!1),registerEffect$1(23,SVGTritoneFilter,!0),registerEffect$1(24,SVGProLevelsFilter,!0),registerEffect$1(25,SVGDropShadowEffect,!0),registerEffect$1(28,SVGMatte3Effect,!1),registerEffect$1(29,SVGGaussianBlurEffect,!0),registerEffect$1(35,SVGTransformEffect,!1),registerEffect(35,CVTransformEffect),lottie}),{loadAnimation:loadAnimation}}({});onmessage=function(t){var t=t.data,e=t.type,i=t.payload;"load"===e?lottieInternal.loadAnimation(i):"pause"===e?animations[i.id]&&animations[i.id].animation.pause():"play"===e?animations[i.id]&&animations[i.id].animation.play():"stop"===e?animations[i.id]&&animations[i.id].animation.stop():"setSpeed"===e?animations[i.id]&&animations[i.id].animation.setSpeed(i.value):"setDirection"===e?animations[i.id]&&animations[i.id].animation.setDirection(i.value):"setLoop"===e?animations[i.id]&&animations[i.id].animation.setLoop(i.value):"goToAndPlay"===e?animations[i.id]&&animations[i.id].animation.goToAndPlay(i.value,i.isFrame):"goToAndStop"===e?animations[i.id]&&animations[i.id].animation.goToAndStop(i.value,i.isFrame):"setSubframe"===e?animations[i.id]&&animations[i.id].animation.setSubframe(i.value):"addEventListener"===e?animations[i.id]&&(animations[i.id].events[i.callbackId]={callback:t=function(){self.postMessage({type:"event",payload:{id:i.id,callbackId:i.callbackId,argument:arguments[0]}})}},animations[i.id].animation.addEventListener(i.eventName,t)):"removeEventListener"===e?animations[i.id]&&(t=animations[i.id].events[i.callbackId],animations[i.id].animation.removeEventListener(i.eventName,t)):"destroy"===e?animations[i.id]&&(animations[i.id].animation.destroy(),animations[i.id]=null):"resize"===e?animations[i.id]&&animations[i.id].animation.resize(i.width,i.height):"playSegments"===e?animations[i.id]&&animations[i.id].animation.playSegments(i.arr,i.forceFlag):"resetSegments"===e?animations[i.id]&&animations[i.id].animation.resetSegments(i.forceFlag):"updateDocumentData"===e&&animations[i.id].animation.updateDocumentData(i.path,i.documentData,i.index)}}function createWorker(t){t=new Blob(["("+t.toString()+"())"],{type:"text/javascript"}),t=URL.createObjectURL(t);return new Worker(t)}var lottie=(()=>{var h=createWorker(workerContent),i=0,s=0,P={},a={rendererSettings:{}};function E(t,e,i,r){var s,a,n="div"===t.type?document.createElement("div"):document.createElementNS(t.namespace,t.type);for(s in t.textContent&&(n.textContent=t.textContent),t.attributes)Object.prototype.hasOwnProperty.call(t.attributes,s)&&("href"===s?n.setAttributeNS("http://www.w3.org/1999/xlink",s,t.attributes[s]):n.setAttribute(s,t.attributes[s]),"id"===s)&&(i[t.attributes[s]]=n);for(a in t.style)Object.prototype.hasOwnProperty.call(t.style,a)&&(n.style[a]=t.style[a]);t.children.forEach(function(t){E(t,n,i)}),r?e.insertBefore(n,r):e.appendChild(n)}var e={DOMLoaded:function(t){var e=P[t.id];e._loaded=!0,e.pendingCallbacks.forEach(function(t){e.animInstance.addEventListener(t.eventName,t.callback),"DOMLoaded"===t.eventName&&t.callback()}),e.animInstance.totalFrames=t.totalFrames,e.animInstance.frameRate=t.frameRate,e.animInstance.firstFrame=t.firstFrame,e.animInstance.playDirection=t.playDirection,e.animInstance.currentFrame=t.isSubframeEnabled?t.currentRawFrame:~~t.currentRawFrame,t.timeCompleted!==t.totalFrames&&t.currentFrame>t.timeCompleted&&(e.animInstance.currentFrame=t.timeCompleted)},SVGloaded:function(t){var e=P[t.id],i=e.container;E(t.tree,i,e.elements)},SVGupdated:function(t){var e=t.elements,i=P[t.id];if(i){for(var r=i.elements,s=0;s<e.length;s+=1){for(var a,n=r[(a=e[s]).id],o=(m=f=l=p=h=o=void 0,a.elements),h=r,l=0;l<o.length;l+=1){var p,m,f=h[(p=o[l])[1]];f&&(p[2]&&(m=h[p[2]]),E(p[0],f,h,m),o.splice(l,1),--l)}y=c=u=d=void 0;for(var c,d=n,u=a.styles,y=0;y<u.length;y+=1)d.style[(c=u[y])[0]]=c[1];x=g=b=v=void 0;for(var g,v=n,b=a.attributes,x=0;x<b.length;x+=1)v.setAttribute((g=b[x])[0],g[1]);n=n,(a=a.textContent)&&(n.textContent=a)}i.animInstance.currentFrame=t.currentTime}},CanvasUpdated:function(t){P[t.id].instructionsHandler(t.instructions)},event:function(t){var e=P[t.id];e&&(e=e.callbacks)[t.callbackId]&&e[t.callbackId].callback(t.argument)},playing:function(t){(t=P[t.id])&&(t.animInstance.isPaused=!1)},paused:function(t){(t=P[t.id])&&(t.animInstance.isPaused=!0)}};return h.onmessage=function(t){e[t.data.type]&&e[t.data.type](t.data.payload)},{loadAnimation:function(t){var r,n="lottie_animationId_"+(i+=1),o={elements:{},callbacks:{},pendingCallbacks:[],status:"init"},e={id:n,isPaused:!0,pause:function(){h.postMessage({type:"pause",payload:{id:n}})},play:function(){h.postMessage({type:"play",payload:{id:n}})},stop:function(){h.postMessage({type:"stop",payload:{id:n}})},setSpeed:function(t){h.postMessage({type:"setSpeed",payload:{id:n,value:t}})},setDirection:function(t){h.postMessage({type:"setDirection",payload:{id:n,value:t}})},setLoop:function(t){h.postMessage({type:"setLoop",payload:{id:n,value:t}})},goToAndStop:function(t,e){h.postMessage({type:"goToAndStop",payload:{id:n,value:t,isFrame:e}})},goToAndPlay:function(t,e){h.postMessage({type:"goToAndPlay",payload:{id:n,value:t,isFrame:e}})},playSegments:function(t,e){h.postMessage({type:"playSegments",payload:{id:n,arr:t,forceFlag:e}})},setSubframe:function(t){h.postMessage({type:"setSubframe",payload:{id:n,value:t}})},addEventListener:function(t,e){var i;o._loaded?(i="callback_"+(s+=1),o.callbacks[i]={eventName:t,callback:e},h.postMessage({type:"addEventListener",payload:{id:n,callbackId:i,eventName:t}})):o.pendingCallbacks.push({eventName:t,callback:e})},removeEventListener:function(e,i){Object.keys(o.callbacks).forEach(function(t){o.callbacks[t].eventName!==e||o.callbacks[t].callback!==i&&i||(delete o.callbacks[t],h.postMessage({type:"removeEventListener",payload:{id:n,callbackId:t,eventName:e}}))})},destroy:function(){"init"===o.status?o.status="destroyable":(o.status="destroyed",P[n]=null,o.container&&(o.container.innerHTML=""),h.postMessage({type:"destroy",payload:{id:n}}))},resize:function(t,e){var i=window.devicePixelRatio||1;h.postMessage({type:"resize",payload:{id:n,width:t||(o.container?o.container.offsetWidth*i:0),height:e||(o.container?o.container.offsetHeight*i:0)}})},updateDocumentData:function(t,e,i){h.postMessage({type:"updateDocumentData",payload:{id:n,path:t,documentData:e,index:i}})}};return o.animInstance=e,r=t,new Promise(function(e,t){var i=Object.assign({},a,r);i.animType&&!i.renderer&&(i.renderer=i.animType),i.wrapper&&(i.container||(i.container=i.wrapper),delete i.wrapper),i.animationData?e(i):i.path?fetch(i.path).then(function(t){return t.json()}).then(function(t){i.animationData=t,delete i.path,e(i)}):t()}).then(function(t){var e,i,r,s,a;"destroyable"===o.status?o.animInstance.destroy():(o.status="loaded",e=[],t.container&&(o.container=t.container,delete t.container),"canvas"===t.renderer&&((i=t.rendererSettings.canvas)||(r=window.devicePixelRatio||1,i=document.createElement("canvas"),o.container.appendChild(i),i.width=(o.container?o.container.offsetWidth:t.animationData.w)*r,i.height=(o.container?o.container.offsetHeight:t.animationData.h)*r,i.style.width="100%",i.style.height="100%"),r=i,"undefined"==typeof OffscreenCanvas?(o.canvas=i,o.instructionsHandler=(s=i.getContext("2d"),a={beginPath:s.beginPath,closePath:s.closePath,rect:s.rect,clip:s.clip,clearRect:s.clearRect,setTransform:s.setTransform,moveTo:s.moveTo,bezierCurveTo:s.bezierCurveTo,lineTo:s.lineTo,fill:s.fill,save:s.save,restore:s.restore},function(t){for(var e=0;e<t.length;e+=1){var i=t[e],r=a[i.t];r?r.apply(s,i.a):s[i.t]=i.a}})):(i instanceof OffscreenCanvas||(r=i.transferControlToOffscreen(),t.rendererSettings.canvas=r),e.push(r))),P[n]=o,h.postMessage({type:"load",payload:{params:t,id:n}},e))}),e}}})();
 return lottie;
 }));
\ No newline at end of file
diff --git a/build/player/lottie_html.js b/build/player/lottie_html.js
index c05821d..90afaf2 100644
--- a/build/player/lottie_html.js
+++ b/build/player/lottie_html.js
@@ -1,4 +1,4 @@
-(typeof navigator !== "undefined") && (function (global, factory) {
+(typeof document !== "undefined") && (typeof navigator !== "undefined") && (function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
   typeof define === 'function' && define.amd ? define(factory) :
   (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lottie = factory());
@@ -8,19 +8,15 @@
   var locationHref = '';
   var _useWebWorker = false;
   var initialDefaultFrame = -999999;
-
   var setWebWorker = function setWebWorker(flag) {
     _useWebWorker = !!flag;
   };
-
   var getWebWorker = function getWebWorker() {
     return _useWebWorker;
   };
-
   var setLocationHref = function setLocationHref(value) {
     locationHref = value;
   };
-
   var getLocationHref = function getLocationHref() {
     return locationHref;
   };
@@ -34,28 +30,24 @@
     var i;
     var len = sources.length;
     var sourcePrototype;
-
     for (i = 0; i < len; i += 1) {
       sourcePrototype = sources[i].prototype;
-
       for (var attr in sourcePrototype) {
         if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
       }
     }
   }
-
   function getDescriptor(object, prop) {
     return Object.getOwnPropertyDescriptor(object, prop);
   }
-
   function createProxyFunction(prototype) {
     function ProxyFunction() {}
-
     ProxyFunction.prototype = prototype;
     return ProxyFunction;
   }
 
   // import Howl from '../../3rd_party/howler';
+
   var audioControllerFactory = function () {
     function AudioController(audioFactory) {
       this.audios = [];
@@ -63,7 +55,6 @@
       this._volume = 1;
       this._isMuted = false;
     }
-
     AudioController.prototype = {
       addAudio: function addAudio(audio) {
         this.audios.push(audio);
@@ -71,7 +62,6 @@
       pause: function pause() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].pause();
         }
@@ -79,7 +69,6 @@
       resume: function resume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].resume();
         }
@@ -87,7 +76,6 @@
       setRate: function setRate(rateValue) {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].setRate(rateValue);
         }
@@ -96,13 +84,11 @@
         if (this.audioFactory) {
           return this.audioFactory(assetPath);
         }
-
         if (window.Howl) {
           return new window.Howl({
             src: [assetPath]
           });
         }
-
         return {
           isPlaying: false,
           play: function play() {
@@ -121,17 +107,14 @@
       },
       setVolume: function setVolume(value) {
         this._volume = value;
-
         this._updateVolume();
       },
       mute: function mute() {
         this._isMuted = true;
-
         this._updateVolume();
       },
       unmute: function unmute() {
         this._isMuted = false;
-
         this._updateVolume();
       },
       getVolume: function getVolume() {
@@ -140,7 +123,6 @@
       _updateVolume: function _updateVolume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
         }
@@ -156,55 +138,44 @@
       var i = 0;
       var arr = [];
       var value;
-
       switch (type) {
         case 'int16':
         case 'uint8c':
           value = 1;
           break;
-
         default:
           value = 1.1;
           break;
       }
-
       for (i = 0; i < len; i += 1) {
         arr.push(value);
       }
-
       return arr;
     }
-
     function createTypedArrayFactory(type, len) {
       if (type === 'float32') {
         return new Float32Array(len);
       }
-
       if (type === 'int16') {
         return new Int16Array(len);
       }
-
       if (type === 'uint8c') {
         return new Uint8ClampedArray(len);
       }
-
       return createRegularArray(type, len);
     }
-
     if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
       return createTypedArrayFactory;
     }
-
     return createRegularArray;
   }();
-
   function createSizedArray(len) {
     return Array.apply(null, {
       length: len
     });
   }
 
-  function _typeof$6(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$6 = function _typeof(obj) { return typeof obj; }; } else { _typeof$6 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$6(obj); }
+  function _typeof$6(o) { "@babel/helpers - typeof"; return _typeof$6 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$6(o); }
   var subframeEnabled = true;
   var expressionsPlugin = null;
   var expressionsInterfaces = null;
@@ -217,57 +188,43 @@
   var bmMax = Math.max;
   var bmMin = Math.min;
   var BMMath = {};
-
   (function () {
     var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
     var i;
     var len = propertyNames.length;
-
     for (i = 0; i < len; i += 1) {
       BMMath[propertyNames[i]] = Math[propertyNames[i]];
     }
   })();
-
   function ProjectInterface$1() {
     return {};
   }
-
   BMMath.random = Math.random;
-
   BMMath.abs = function (val) {
     var tOfVal = _typeof$6(val);
-
     if (tOfVal === 'object' && val.length) {
       var absArr = createSizedArray(val.length);
       var i;
       var len = val.length;
-
       for (i = 0; i < len; i += 1) {
         absArr[i] = Math.abs(val[i]);
       }
-
       return absArr;
     }
-
     return Math.abs(val);
   };
-
   var defaultCurveSegments = 150;
   var degToRads = Math.PI / 180;
   var roundCorner = 0.5519;
-
   function roundValues(flag) {
     _shouldRoundValues = !!flag;
   }
-
   function bmRnd(value) {
     if (_shouldRoundValues) {
       return Math.round(value);
     }
-
     return value;
   }
-
   function styleDiv(element) {
     element.style.position = 'absolute';
     element.style.top = 0;
@@ -281,53 +238,44 @@
     element.style.webkitTransformStyle = 'preserve-3d';
     element.style.mozTransformStyle = 'preserve-3d';
   }
-
   function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
     this.type = type;
     this.currentTime = currentTime;
     this.totalTime = totalTime;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteEvent(type, frameMultiplier) {
     this.type = type;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
     this.type = type;
     this.currentLoop = currentLoop;
     this.totalLoops = totalLoops;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMSegmentStartEvent(type, firstFrame, totalFrames) {
     this.type = type;
     this.firstFrame = firstFrame;
     this.totalFrames = totalFrames;
   }
-
   function BMDestroyEvent(type, target) {
     this.type = type;
     this.target = target;
   }
-
   function BMRenderFrameErrorEvent(nativeError, currentTime) {
     this.type = 'renderFrameError';
     this.nativeError = nativeError;
     this.currentTime = currentTime;
   }
-
   function BMConfigErrorEvent(nativeError) {
     this.type = 'configError';
     this.nativeError = nativeError;
   }
-
   function BMAnimationConfigErrorEvent(type, nativeError) {
     this.type = type;
     this.nativeError = nativeError;
   }
-
   var createElementID = function () {
     var _count = 0;
     return function createID() {
@@ -335,7 +283,6 @@
       return idPrefix$1 + '__lottie_element_' + _count;
     };
   }();
-
   function HSVtoRGB(h, s, v) {
     var r;
     var g;
@@ -350,51 +297,42 @@
     p = v * (1 - s);
     q = v * (1 - f * s);
     t = v * (1 - (1 - f) * s);
-
     switch (i % 6) {
       case 0:
         r = v;
         g = t;
         b = p;
         break;
-
       case 1:
         r = q;
         g = v;
         b = p;
         break;
-
       case 2:
         r = p;
         g = v;
         b = t;
         break;
-
       case 3:
         r = p;
         g = q;
         b = v;
         break;
-
       case 4:
         r = t;
         g = p;
         b = v;
         break;
-
       case 5:
         r = v;
         g = p;
         b = q;
         break;
-
       default:
         break;
     }
-
     return [r, g, b];
   }
-
   function RGBtoHSV(r, g, b) {
     var max = Math.max(r, g, b);
     var min = Math.min(r, g, b);
@@ -402,136 +340,105 @@
     var h;
     var s = max === 0 ? 0 : d / max;
     var v = max / 255;
-
     switch (max) {
       case min:
         h = 0;
         break;
-
       case r:
         h = g - b + d * (g < b ? 6 : 0);
         h /= 6 * d;
         break;
-
       case g:
         h = b - r + d * 2;
         h /= 6 * d;
         break;
-
       case b:
         h = r - g + d * 4;
         h /= 6 * d;
         break;
-
       default:
         break;
     }
-
     return [h, s, v];
   }
-
   function addSaturationToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[1] += offset;
-
     if (hsv[1] > 1) {
       hsv[1] = 1;
     } else if (hsv[1] <= 0) {
       hsv[1] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addBrightnessToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[2] += offset;
-
     if (hsv[2] > 1) {
       hsv[2] = 1;
     } else if (hsv[2] < 0) {
       hsv[2] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addHueToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[0] += offset / 360;
-
     if (hsv[0] > 1) {
       hsv[0] -= 1;
     } else if (hsv[0] < 0) {
       hsv[0] += 1;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   var rgbToHex = function () {
     var colorMap = [];
     var i;
     var hex;
-
     for (i = 0; i < 256; i += 1) {
       hex = i.toString(16);
       colorMap[i] = hex.length === 1 ? '0' + hex : hex;
     }
-
     return function (r, g, b) {
       if (r < 0) {
         r = 0;
       }
-
       if (g < 0) {
         g = 0;
       }
-
       if (b < 0) {
         b = 0;
       }
-
       return '#' + colorMap[r] + colorMap[g] + colorMap[b];
     };
   }();
-
   var setSubframeEnabled = function setSubframeEnabled(flag) {
     subframeEnabled = !!flag;
   };
-
   var getSubframeEnabled = function getSubframeEnabled() {
     return subframeEnabled;
   };
-
   var setExpressionsPlugin = function setExpressionsPlugin(value) {
     expressionsPlugin = value;
   };
-
   var getExpressionsPlugin = function getExpressionsPlugin() {
     return expressionsPlugin;
   };
-
   var setExpressionInterfaces = function setExpressionInterfaces(value) {
     expressionsInterfaces = value;
   };
-
   var getExpressionInterfaces = function getExpressionInterfaces() {
     return expressionsInterfaces;
   };
-
   var setDefaultCurveSegments = function setDefaultCurveSegments(value) {
     defaultCurveSegments = value;
   };
-
   var getDefaultCurveSegments = function getDefaultCurveSegments() {
     return defaultCurveSegments;
   };
-
   var setIdPrefix = function setIdPrefix(value) {
     idPrefix$1 = value;
   };
-
   var getIdPrefix = function getIdPrefix() {
     return idPrefix$1;
   };
@@ -541,8 +448,7 @@
     return document.createElementNS(svgNS, type);
   }
 
-  function _typeof$5(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$5 = function _typeof(obj) { return typeof obj; }; } else { _typeof$5 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$5(obj); }
-
+  function _typeof$5(o) { "@babel/helpers - typeof"; return _typeof$5 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$5(o); }
   var dataManager = function () {
     var _counterId = 1;
     var processes = [];
@@ -563,21 +469,18 @@
         });
       }
     };
-
     function createWorker(fn) {
       if (window.Worker && window.Blob && getWebWorker()) {
         var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], {
           type: 'text/javascript'
-        }); // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
-
+        });
+        // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
         var url = URL.createObjectURL(blob);
         return new Worker(url);
       }
-
       workerFn = fn;
       return workerProxy;
     }
-
     function setupWorker() {
       if (!workerInstance) {
         workerInstance = createWorker(function workerStart(e) {
@@ -590,28 +493,22 @@
               var jLen;
               var k;
               var kLen;
-
               for (i = 0; i < len; i += 1) {
                 layerData = layers[i];
-
                 if ('ks' in layerData && !layerData.completed) {
                   layerData.completed = true;
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         convertPathsToAbsoluteValues(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) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
                           }
@@ -619,7 +516,6 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 0) {
                     layerData.layers = findCompLayers(layerData.refId, comps);
                     completeLayers(layerData.layers, comps);
@@ -631,16 +527,15 @@
                 }
               }
             }
-
             function completeChars(chars, assets) {
               if (chars) {
                 var i = 0;
                 var len = chars.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (chars[i].t === 1) {
                     // var compData = findComp(chars[i].data.refId, assets);
-                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets); // chars[i].data.ip = 0;
+                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                    // chars[i].data.ip = 0;
                     // chars[i].data.op = 99999;
                     // chars[i].data.st = 0;
                     // chars[i].data.sr = 1;
@@ -652,61 +547,48 @@
                     //   s: { k: [100, 100], a: 0 },
                     //   o: { k: 100, a: 0 },
                     // };
-
                     completeLayers(chars[i].data.layers, assets);
                   }
                 }
               }
             }
-
             function findComp(id, comps) {
               var i = 0;
               var len = comps.length;
-
               while (i < len) {
                 if (comps[i].id === id) {
                   return comps[i];
                 }
-
                 i += 1;
               }
-
               return null;
             }
-
             function findCompLayers(id, comps) {
               var comp = findComp(id, comps);
-
               if (comp) {
                 if (!comp.layers.__used) {
                   comp.layers.__used = true;
                   return comp.layers;
                 }
-
                 return JSON.parse(JSON.stringify(comp.layers));
               }
-
               return null;
             }
-
             function completeShapes(arr) {
               var i;
               var len = arr.length;
               var j;
               var jLen;
-
               for (i = len - 1; i >= 0; i -= 1) {
                 if (arr[i].ty === 'sh') {
                   if (arr[i].ks.k.i) {
                     convertPathsToAbsoluteValues(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) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
                       }
-
                       if (arr[i].ks.k[j].e) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
                       }
@@ -717,11 +599,9 @@
                 }
               }
             }
-
             function convertPathsToAbsoluteValues(path) {
               var i;
               var len = path.i.length;
-
               for (i = 0; i < len; i += 1) {
                 path.i[i][0] += path.v[i][0];
                 path.i[i][1] += path.v[i][1];
@@ -729,40 +609,30 @@
                 path.o[i][1] += path.v[i][1];
               }
             }
-
             function checkVersion(minimum, animVersionString) {
               var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
-
               if (minimum[0] > animVersion[0]) {
                 return true;
               }
-
               if (animVersion[0] > minimum[0]) {
                 return false;
               }
-
               if (minimum[1] > animVersion[1]) {
                 return true;
               }
-
               if (animVersion[1] > minimum[1]) {
                 return false;
               }
-
               if (minimum[2] > animVersion[2]) {
                 return true;
               }
-
               if (animVersion[2] > minimum[2]) {
                 return false;
               }
-
               return null;
             }
-
             var checkText = function () {
               var minimumVersion = [4, 4, 14];
-
               function updateTextLayer(textLayer) {
                 var documentData = textLayer.t.d;
                 textLayer.t.d = {
@@ -772,26 +642,21 @@
                   }]
                 };
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -801,17 +666,14 @@
                 }
               };
             }();
-
             var checkChars = function () {
               var minimumVersion = [4, 7, 99];
               return function (animationData) {
                 if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
                   var i;
                   var len = animationData.chars.length;
-
                   for (i = 0; i < len; i += 1) {
                     var charData = animationData.chars[i];
-
                     if (charData.data && charData.data.shapes) {
                       completeShapes(charData.data.shapes);
                       charData.data.ip = 0;
@@ -840,7 +702,6 @@
                           a: 0
                         }
                       };
-
                       if (!animationData.chars[i].t) {
                         charData.data.shapes.push({
                           ty: 'no'
@@ -882,27 +743,22 @@
                 }
               };
             }();
-
             var checkPathProperties = function () {
               var minimumVersion = [5, 7, 15];
-
               function updateTextLayer(textLayer) {
                 var pathData = textLayer.t.p;
-
                 if (typeof pathData.a === 'number') {
                   pathData.a = {
                     a: 0,
                     k: pathData.a
                   };
                 }
-
                 if (typeof pathData.p === 'number') {
                   pathData.p = {
                     a: 0,
                     k: pathData.p
                   };
                 }
-
                 if (typeof pathData.r === 'number') {
                   pathData.r = {
                     a: 0,
@@ -910,26 +766,21 @@
                   };
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -939,23 +790,19 @@
                 }
               };
             }();
-
             var checkColors = function () {
               var minimumVersion = [4, 1, 9];
-
               function iterateShapes(shapes) {
                 var i;
                 var len = shapes.length;
                 var j;
                 var jLen;
-
                 for (i = 0; i < len; i += 1) {
                   if (shapes[i].ty === 'gr') {
                     iterateShapes(shapes[i].it);
                   } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
                     if (shapes[i].c.k && shapes[i].c.k[0].i) {
                       jLen = shapes[i].c.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (shapes[i].c.k[j].s) {
                           shapes[i].c.k[j].s[0] /= 255;
@@ -963,7 +810,6 @@
                           shapes[i].c.k[j].s[2] /= 255;
                           shapes[i].c.k[j].s[3] /= 255;
                         }
-
                         if (shapes[i].c.k[j].e) {
                           shapes[i].c.k[j].e[0] /= 255;
                           shapes[i].c.k[j].e[1] /= 255;
@@ -980,26 +826,21 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 4) {
                     iterateShapes(layers[i].shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1009,28 +850,23 @@
                 }
               };
             }();
-
             var checkShapes = function () {
               var minimumVersion = [4, 4, 18];
-
               function completeClosingShapes(arr) {
                 var i;
                 var len = arr.length;
                 var j;
                 var jLen;
-
                 for (i = len - 1; i >= 0; i -= 1) {
                   if (arr[i].ty === 'sh') {
                     if (arr[i].ks.k.i) {
                       arr[i].ks.k.c = arr[i].closed;
                     } else {
                       jLen = arr[i].ks.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (arr[i].ks.k[j].s) {
                           arr[i].ks.k[j].s[0].c = arr[i].closed;
                         }
-
                         if (arr[i].ks.k[j].e) {
                           arr[i].ks.k[j].e[0].c = arr[i].closed;
                         }
@@ -1041,7 +877,6 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var layerData;
                 var i;
@@ -1050,25 +885,20 @@
                 var jLen;
                 var k;
                 var kLen;
-
                 for (i = 0; i < len; i += 1) {
                   layerData = layers[i];
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         maskProps[j].pt.k.c = maskProps[j].cl;
                       } else {
                         kLen = maskProps[j].pt.k.length;
-
                         for (k = 0; k < kLen; k += 1) {
                           if (maskProps[j].pt.k[k].s) {
                             maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
                           }
@@ -1076,21 +906,17 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 4) {
                     completeClosingShapes(layerData.shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1100,12 +926,10 @@
                 }
               };
             }();
-
             function completeData(animationData) {
               if (animationData.__complete) {
                 return;
               }
-
               checkColors(animationData);
               checkText(animationData);
               checkChars(animationData);
@@ -1115,12 +939,11 @@
               completeChars(animationData.chars, animationData.assets);
               animationData.__complete = true;
             }
-
             function completeText(data) {
-              if (data.t.a.length === 0 && !('m' in data.t.p)) {// data.singleShape = true;
+              if (data.t.a.length === 0 && !('m' in data.t.p)) {
+                // data.singleShape = true;
               }
             }
-
             var moduleOb = {};
             moduleOb.completeData = completeData;
             moduleOb.checkColors = checkColors;
@@ -1130,47 +953,37 @@
             moduleOb.completeLayers = completeLayers;
             return moduleOb;
           }
-
           if (!_workerSelf.dataManager) {
             _workerSelf.dataManager = dataFunctionManager();
           }
-
           if (!_workerSelf.assetLoader) {
             _workerSelf.assetLoader = function () {
               function formatResponse(xhr) {
                 // using typeof doubles the time of execution of this method,
                 // so if available, it's better to use the header to validate the type
                 var contentTypeHeader = xhr.getResponseHeader('content-type');
-
                 if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
                   return xhr.response;
                 }
-
                 if (xhr.response && _typeof$5(xhr.response) === 'object') {
                   return xhr.response;
                 }
-
                 if (xhr.response && typeof xhr.response === 'string') {
                   return JSON.parse(xhr.response);
                 }
-
                 if (xhr.responseText) {
                   return JSON.parse(xhr.responseText);
                 }
-
                 return null;
               }
-
               function loadAsset(path, fullPath, callback, errorCallback) {
                 var response;
-                var xhr = new XMLHttpRequest(); // set responseType after calling open or IE will break.
-
+                var xhr = new XMLHttpRequest();
+                // set responseType after calling open or IE will break.
                 try {
                   // This crashes on Android WebView prior to KitKat
                   xhr.responseType = 'json';
                 } catch (err) {} // eslint-disable-line no-empty
-
-
                 xhr.onreadystatechange = function () {
                   if (xhr.readyState === 4) {
                     if (xhr.status === 200) {
@@ -1188,7 +1001,6 @@
                     }
                   }
                 };
-
                 try {
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), path, true);
@@ -1196,20 +1008,16 @@
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
                 }
-
                 xhr.send();
               }
-
               return {
                 load: loadAsset
               };
             }();
           }
-
           if (e.data.type === 'loadAnimation') {
             _workerSelf.assetLoader.load(e.data.path, e.data.fullPath, function (data) {
               _workerSelf.dataManager.completeData(data);
-
               _workerSelf.postMessage({
                 id: e.data.id,
                 payload: data,
@@ -1223,9 +1031,7 @@
             });
           } else if (e.data.type === 'complete') {
             var animation = e.data.animation;
-
             _workerSelf.dataManager.completeData(animation);
-
             _workerSelf.postMessage({
               id: e.data.id,
               payload: animation,
@@ -1246,13 +1052,11 @@
             });
           }
         });
-
         workerInstance.onmessage = function (event) {
           var data = event.data;
           var id = data.id;
           var process = processes[id];
           processes[id] = null;
-
           if (data.status === 'success') {
             process.onComplete(data.payload);
           } else if (process.onError) {
@@ -1261,7 +1065,6 @@
         };
       }
     }
-
     function createProcess(onComplete, onError) {
       _counterId += 1;
       var id = 'processId_' + _counterId;
@@ -1271,7 +1074,6 @@
       };
       return id;
     }
-
     function loadAnimation(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1282,7 +1084,6 @@
         id: processId
       });
     }
-
     function loadData(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1293,7 +1094,6 @@
         id: processId
       });
     }
-
     function completeAnimation(anim, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1303,7 +1103,6 @@
         id: processId
       });
     }
-
     return {
       loadAnimation: loadAnimation,
       loadData: loadData,
@@ -1321,94 +1120,74 @@
       ctx.fillRect(0, 0, 1, 1);
       return canvas;
     }();
-
     function imageLoaded() {
       this.loadedAssets += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function footageLoaded() {
       this.loadedFootagesCount += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function getAssetsPath(assetData, assetsPath, originalPath) {
       var path = '';
-
       if (assetData.e) {
         path = assetData.p;
       } else if (assetsPath) {
         var imagePath = assetData.p;
-
         if (imagePath.indexOf('images/') !== -1) {
           imagePath = imagePath.split('/')[1];
         }
-
         path = assetsPath + imagePath;
       } else {
         path = originalPath;
         path += assetData.u ? assetData.u : '';
         path += assetData.p;
       }
-
       return path;
     }
-
     function testImageLoaded(img) {
       var _count = 0;
       var intervalId = setInterval(function () {
         var box = img.getBBox();
-
         if (box.width || _count > 500) {
           this._imageLoaded();
-
           clearInterval(intervalId);
         }
-
         _count += 1;
       }.bind(this), 50);
     }
-
     function createImageData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createNS('image');
-
       if (isSafari) {
         this.testImageLoaded(img);
       } else {
         img.addEventListener('load', this._imageLoaded, false);
       }
-
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
-
       if (this._elementHelper.append) {
         this._elementHelper.append(img);
       } else {
         this._elementHelper.appendChild(img);
       }
-
       var ob = {
         img: img,
         assetData: assetData
       };
       return ob;
     }
-
     function createImgData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createTag('img');
@@ -1416,7 +1195,6 @@
       img.addEventListener('load', this._imageLoaded, false);
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.src = path;
@@ -1426,7 +1204,6 @@
       };
       return ob;
     }
-
     function createFootageData(data) {
       var ob = {
         assetData: data
@@ -1434,21 +1211,17 @@
       var path = getAssetsPath(data, this.assetsPath, this.path);
       dataManager.loadData(path, function (footageData) {
         ob.img = footageData;
-
         this._footageLoaded();
       }.bind(this), function () {
         ob.img = {};
-
         this._footageLoaded();
       }.bind(this));
       return ob;
     }
-
     function loadAssets(assets, cb) {
       this.imagesLoadedCb = cb;
       var i;
       var len = assets.length;
-
       for (i = 0; i < len; i += 1) {
         if (!assets[i].layers) {
           if (!assets[i].t || assets[i].t === 'seq') {
@@ -1461,43 +1234,33 @@
         }
       }
     }
-
     function setPath(path) {
       this.path = path || '';
     }
-
     function setAssetsPath(path) {
       this.assetsPath = path || '';
     }
-
     function getAsset(assetData) {
       var i = 0;
       var len = this.images.length;
-
       while (i < len) {
         if (this.images[i].assetData === assetData) {
           return this.images[i].img;
         }
-
         i += 1;
       }
-
       return null;
     }
-
     function destroy() {
       this.imagesLoadedCb = null;
       this.images.length = 0;
     }
-
     function loadedImages() {
       return this.totalImages === this.loadedAssets;
     }
-
     function loadedFootages() {
       return this.totalFootages === this.loadedFootagesCount;
     }
-
     function setCacheType(type, elementHelper) {
       if (type === 'svg') {
         this._elementHelper = elementHelper;
@@ -1506,7 +1269,6 @@
         this._createImageData = this.createImgData.bind(this);
       }
     }
-
     function ImagePreloaderFactory() {
       this._imageLoaded = imageLoaded.bind(this);
       this._footageLoaded = footageLoaded.bind(this);
@@ -1521,7 +1283,6 @@
       this.imagesLoadedCb = null;
       this.images = [];
     }
-
     ImagePreloaderFactory.prototype = {
       loadAssets: loadAssets,
       setAssetsPath: setAssetsPath,
@@ -1540,12 +1301,10 @@
   }();
 
   function BaseEvent() {}
-
   BaseEvent.prototype = {
     triggerEvent: function triggerEvent(eventName, args) {
       if (this._cbs[eventName]) {
         var callbacks = this._cbs[eventName];
-
         for (var i = 0; i < callbacks.length; i += 1) {
           callbacks[i](args);
         }
@@ -1555,9 +1314,7 @@
       if (!this._cbs[eventName]) {
         this._cbs[eventName] = [];
       }
-
       this._cbs[eventName].push(callback);
-
       return function () {
         this.removeEventListener(eventName, callback);
       }.bind(this);
@@ -1568,18 +1325,14 @@
       } else if (this._cbs[eventName]) {
         var i = 0;
         var len = this._cbs[eventName].length;
-
         while (i < len) {
           if (this._cbs[eventName][i] === callback) {
             this._cbs[eventName].splice(i, 1);
-
             i -= 1;
             len -= 1;
           }
-
           i += 1;
         }
-
         if (!this._cbs[eventName].length) {
           this._cbs[eventName] = null;
         }
@@ -1593,33 +1346,26 @@
       var keys = {};
       var line;
       var keysCount = 0;
-
       for (var i = 0; i < lines.length; i += 1) {
         line = lines[i].split(':');
-
         if (line.length === 2) {
           keys[line[0]] = line[1].trim();
           keysCount += 1;
         }
       }
-
       if (keysCount === 0) {
         throw new Error();
       }
-
       return keys;
     }
-
     return function (_markers) {
       var markers = [];
-
       for (var i = 0; i < _markers.length; i += 1) {
         var _marker = _markers[i];
         var markerData = {
           time: _marker.tm,
           duration: _marker.dr
         };
-
         try {
           markerData.payload = JSON.parse(_markers[i].cm);
         } catch (_) {
@@ -1631,10 +1377,8 @@
             };
           }
         }
-
         markers.push(markerData);
       }
-
       return markers;
     };
   }();
@@ -1643,27 +1387,21 @@
     function registerComposition(comp) {
       this.compositions.push(comp);
     }
-
     return function () {
       function _thisProjectFunction(name) {
         var i = 0;
         var len = this.compositions.length;
-
         while (i < len) {
           if (this.compositions[i].data && this.compositions[i].data.nm === name) {
             if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
               this.compositions[i].prepareFrame(this.currentFrame);
             }
-
             return this.compositions[i].compInterface;
           }
-
           i += 1;
         }
-
         return null;
       }
-
       _thisProjectFunction.compositions = [];
       _thisProjectFunction.currentFrame = 0;
       _thisProjectFunction.registerComposition = registerComposition;
@@ -1672,33 +1410,27 @@
   }();
 
   var renderers = {};
-
   var registerRenderer = function registerRenderer(key, value) {
     renderers[key] = value;
   };
-
   function getRenderer(key) {
     return renderers[key];
   }
-
   function getRegisteredRenderer() {
     // Returns canvas by default for compatibility
     if (renderers.canvas) {
       return 'canvas';
-    } // Returns any renderer that is registered
-
-
+    }
+    // Returns any renderer that is registered
     for (var key in renderers) {
       if (renderers[key]) {
         return key;
       }
     }
-
     return '';
   }
 
-  function _typeof$4(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$4 = function _typeof(obj) { return typeof obj; }; } else { _typeof$4 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$4(obj); }
-
+  function _typeof$4(o) { "@babel/helpers - typeof"; return _typeof$4 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$4(o); }
   var AnimationItem = function AnimationItem() {
     this._cbs = [];
     this.name = '';
@@ -1737,28 +1469,22 @@
     this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
     this.expressionsPlugin = getExpressionsPlugin();
   };
-
   extendPrototype([BaseEvent], AnimationItem);
-
   AnimationItem.prototype.setParams = function (params) {
     if (params.wrapper || params.container) {
       this.wrapper = params.wrapper || params.container;
     }
-
     var animType = 'svg';
-
     if (params.animType) {
       animType = params.animType;
     } else if (params.renderer) {
       animType = params.renderer;
     }
-
     var RendererClass = getRenderer(animType);
     this.renderer = new RendererClass(this, params.rendererSettings);
     this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
     this.renderer.setProjectInterface(this.projectInterface);
     this.animType = animType;
-
     if (params.loop === '' || params.loop === null || params.loop === undefined || params.loop === true) {
       this.loop = true;
     } else if (params.loop === false) {
@@ -1766,17 +1492,14 @@
     } else {
       this.loop = parseInt(params.loop, 10);
     }
-
     this.autoplay = 'autoplay' in params ? params.autoplay : true;
     this.name = params.name ? params.name : '';
     this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
     this.assetsPath = params.assetsPath;
     this.initialSegment = params.initialSegment;
-
     if (params.audioFactory) {
       this.audioController.setAudioFactory(params.audioFactory);
     }
-
     if (params.animationData) {
       this.setupAnimation(params.animationData);
     } else if (params.path) {
@@ -1785,28 +1508,23 @@
       } else {
         this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
       }
-
       this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
       this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
       dataManager.loadAnimation(params.path, this.configAnimation, this.onSetupError);
     }
   };
-
   AnimationItem.prototype.onSetupError = function () {
     this.trigger('data_failed');
   };
-
   AnimationItem.prototype.setupAnimation = function (data) {
     dataManager.completeAnimation(data, this.configAnimation);
   };
-
   AnimationItem.prototype.setData = function (wrapper, animationData) {
     if (animationData) {
       if (_typeof$4(animationData) !== 'object') {
         animationData = JSON.parse(animationData);
       }
     }
-
     var params = {
       wrapper: wrapper,
       animationData: animationData
@@ -1823,7 +1541,6 @@
     var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-loop').value : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-loop').value : wrapperAttributes.getNamedItem('bm-loop') ? wrapperAttributes.getNamedItem('bm-loop').value : '';
-
     if (loop === 'false') {
       params.loop = false;
     } else if (loop === 'true') {
@@ -1831,7 +1548,6 @@
     } else if (loop !== '') {
       params.loop = parseInt(loop, 10);
     }
-
     var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-autoplay').value : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-autoplay').value : wrapperAttributes.getNamedItem('bm-autoplay') ? wrapperAttributes.getNamedItem('bm-autoplay').value : true;
@@ -1842,81 +1558,64 @@
     var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-prerender').value : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-prerender').value : wrapperAttributes.getNamedItem('bm-prerender') ? wrapperAttributes.getNamedItem('bm-prerender').value : '';
-
     if (prerender === 'false') {
       params.prerender = false;
     }
-
     if (!params.path) {
       this.trigger('destroy');
     } else {
       this.setParams(params);
     }
   };
-
   AnimationItem.prototype.includeLayers = function (data) {
     if (data.op > this.animationData.op) {
       this.animationData.op = data.op;
       this.totalFrames = Math.floor(data.op - this.animationData.ip);
     }
-
     var layers = this.animationData.layers;
     var i;
     var len = layers.length;
     var newLayers = data.layers;
     var j;
     var jLen = newLayers.length;
-
     for (j = 0; j < jLen; j += 1) {
       i = 0;
-
       while (i < len) {
         if (layers[i].id === newLayers[j].id) {
           layers[i] = newLayers[j];
           break;
         }
-
         i += 1;
       }
     }
-
     if (data.chars || data.fonts) {
       this.renderer.globalData.fontManager.addChars(data.chars);
       this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
     }
-
     if (data.assets) {
       len = data.assets.length;
-
       for (i = 0; i < len; i += 1) {
         this.animationData.assets.push(data.assets[i]);
       }
     }
-
     this.animationData.__complete = false;
     dataManager.completeAnimation(this.animationData, this.onSegmentComplete);
   };
-
   AnimationItem.prototype.onSegmentComplete = function (data) {
     this.animationData = data;
     var expressionsPlugin = getExpressionsPlugin();
-
     if (expressionsPlugin) {
       expressionsPlugin.initExpressions(this);
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.loadNextSegment = function () {
     var segments = this.animationData.segments;
-
     if (!segments || segments.length === 0 || !this.autoloadSegments) {
       this.trigger('data_ready');
       this.timeCompleted = this.totalFrames;
       return;
     }
-
     var segment = segments.shift();
     this.timeCompleted = segment.time * this.frameRate;
     var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
@@ -1925,36 +1624,28 @@
       this.trigger('data_failed');
     }.bind(this));
   };
-
   AnimationItem.prototype.loadSegments = function () {
     var segments = this.animationData.segments;
-
     if (!segments) {
       this.timeCompleted = this.totalFrames;
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.imagesLoaded = function () {
     this.trigger('loaded_images');
     this.checkLoaded();
   };
-
   AnimationItem.prototype.preloadImages = function () {
     this.imagePreloader.setAssetsPath(this.assetsPath);
     this.imagePreloader.setPath(this.path);
     this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
   };
-
   AnimationItem.prototype.configAnimation = function (animData) {
     if (!this.renderer) {
       return;
     }
-
     try {
       this.animationData = animData;
-
       if (this.initialSegment) {
         this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
         this.firstFrame = Math.round(this.initialSegment[0]);
@@ -1962,13 +1653,10 @@
         this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
         this.firstFrame = Math.round(this.animationData.ip);
       }
-
       this.renderer.configAnimation(animData);
-
       if (!animData.assets) {
         animData.assets = [];
       }
-
       this.assets = this.animationData.assets;
       this.frameRate = this.animationData.fr;
       this.frameMult = this.animationData.fr / 1000;
@@ -1979,7 +1667,6 @@
       this.loadSegments();
       this.updaFrameModifier();
       this.waitForFontsLoaded();
-
       if (this.isPaused) {
         this.audioController.pause();
       }
@@ -1987,103 +1674,83 @@
       this.triggerConfigError(error);
     }
   };
-
   AnimationItem.prototype.waitForFontsLoaded = function () {
     if (!this.renderer) {
       return;
     }
-
     if (this.renderer.globalData.fontManager.isLoaded) {
       this.checkLoaded();
     } else {
       setTimeout(this.waitForFontsLoaded.bind(this), 20);
     }
   };
-
   AnimationItem.prototype.checkLoaded = function () {
     if (!this.isLoaded && this.renderer.globalData.fontManager.isLoaded && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas') && this.imagePreloader.loadedFootages()) {
       this.isLoaded = true;
       var expressionsPlugin = getExpressionsPlugin();
-
       if (expressionsPlugin) {
         expressionsPlugin.initExpressions(this);
       }
-
       this.renderer.initItems();
       setTimeout(function () {
         this.trigger('DOMLoaded');
       }.bind(this), 0);
       this.gotoFrame();
-
       if (this.autoplay) {
         this.play();
       }
     }
   };
-
   AnimationItem.prototype.resize = function (width, height) {
     // Adding this validation for backwards compatibility in case an event object was being passed down
     var _width = typeof width === 'number' ? width : undefined;
-
     var _height = typeof height === 'number' ? height : undefined;
-
     this.renderer.updateContainerSize(_width, _height);
   };
-
   AnimationItem.prototype.setSubframe = function (flag) {
     this.isSubframeEnabled = !!flag;
   };
-
   AnimationItem.prototype.gotoFrame = function () {
     this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
 
     if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
       this.currentFrame = this.timeCompleted;
     }
-
     this.trigger('enterFrame');
     this.renderFrame();
     this.trigger('drawnFrame');
   };
-
   AnimationItem.prototype.renderFrame = function () {
     if (this.isLoaded === false || !this.renderer) {
       return;
     }
-
     try {
       if (this.expressionsPlugin) {
         this.expressionsPlugin.resetFrame();
       }
-
       this.renderer.renderFrame(this.currentFrame + this.firstFrame);
     } catch (error) {
       this.triggerRenderFrameError(error);
     }
   };
-
   AnimationItem.prototype.play = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.isPaused = false;
       this.trigger('_play');
       this.audioController.resume();
-
       if (this._idle) {
         this._idle = false;
         this.trigger('_active');
       }
     }
   };
-
   AnimationItem.prototype.pause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === false) {
       this.isPaused = true;
       this.trigger('_pause');
@@ -2092,54 +1759,42 @@
       this.audioController.pause();
     }
   };
-
   AnimationItem.prototype.togglePause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.play();
     } else {
       this.pause();
     }
   };
-
   AnimationItem.prototype.stop = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.pause();
     this.playCount = 0;
     this._completedLoop = false;
     this.setCurrentRawFrameValue(0);
   };
-
   AnimationItem.prototype.getMarkerData = function (markerName) {
     var marker;
-
     for (var i = 0; i < this.markers.length; i += 1) {
       marker = this.markers[i];
-
       if (marker.payload && marker.payload.name === markerName) {
         return marker;
       }
     }
-
     return null;
   };
-
   AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         this.goToAndStop(marker.time, true);
       }
@@ -2148,20 +1803,15 @@
     } else {
       this.setCurrentRawFrameValue(value * this.frameModifier);
     }
-
     this.pause();
   };
-
   AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         if (!marker.duration) {
           this.goToAndStop(marker.time, true);
@@ -2172,19 +1822,16 @@
     } else {
       this.goToAndStop(numValue, isFrame, name);
     }
-
     this.play();
   };
-
   AnimationItem.prototype.advanceTime = function (value) {
     if (this.isPaused === true || this.isLoaded === false) {
       return;
     }
-
     var nextValue = this.currentRawFrame + value * this.frameModifier;
-    var _isComplete = false; // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+    var _isComplete = false;
+    // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
     // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
-
     if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
       if (!this.loop || this.playCount === this.loop) {
         if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
@@ -2193,7 +1840,6 @@
         }
       } else if (nextValue >= this.totalFrames) {
         this.playCount += 1;
-
         if (!this.checkSegments(nextValue % this.totalFrames)) {
           this.setCurrentRawFrameValue(nextValue % this.totalFrames);
           this._completedLoop = true;
@@ -2207,7 +1853,6 @@
         if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) {
           // eslint-disable-line no-plusplus
           this.setCurrentRawFrameValue(this.totalFrames + nextValue % this.totalFrames);
-
           if (!this._completedLoop) {
             this._completedLoop = true;
           } else {
@@ -2221,17 +1866,14 @@
     } else {
       this.setCurrentRawFrameValue(nextValue);
     }
-
     if (_isComplete) {
       this.setCurrentRawFrameValue(nextValue);
       this.pause();
       this.trigger('complete');
     }
   };
-
   AnimationItem.prototype.adjustSegment = function (arr, offset) {
     this.playCount = 0;
-
     if (arr[1] < arr[0]) {
       if (this.frameModifier > 0) {
         if (this.playSpeed < 0) {
@@ -2240,7 +1882,6 @@
           this.setDirection(-1);
         }
       }
-
       this.totalFrames = arr[0] - arr[1];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[1];
@@ -2253,19 +1894,15 @@
           this.setDirection(1);
         }
       }
-
       this.totalFrames = arr[1] - arr[0];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[0];
       this.setCurrentRawFrameValue(0.001 + offset);
     }
-
     this.trigger('segmentStart');
   };
-
   AnimationItem.prototype.setSegment = function (init, end) {
     var pendingFrame = -1;
-
     if (this.isPaused) {
       if (this.currentRawFrame + this.firstFrame < init) {
         pendingFrame = init;
@@ -2273,64 +1910,51 @@
         pendingFrame = end - init;
       }
     }
-
     this.firstFrame = init;
     this.totalFrames = end - init;
     this.timeCompleted = this.totalFrames;
-
     if (pendingFrame !== -1) {
       this.goToAndStop(pendingFrame, true);
     }
   };
-
   AnimationItem.prototype.playSegments = function (arr, forceFlag) {
     if (forceFlag) {
       this.segments.length = 0;
     }
-
     if (_typeof$4(arr[0]) === 'object') {
       var i;
       var len = arr.length;
-
       for (i = 0; i < len; i += 1) {
         this.segments.push(arr[i]);
       }
     } else {
       this.segments.push(arr);
     }
-
     if (this.segments.length && forceFlag) {
       this.adjustSegment(this.segments.shift(), 0);
     }
-
     if (this.isPaused) {
       this.play();
     }
   };
-
   AnimationItem.prototype.resetSegments = function (forceFlag) {
     this.segments.length = 0;
     this.segments.push([this.animationData.ip, this.animationData.op]);
-
     if (forceFlag) {
       this.checkSegments(0);
     }
   };
-
   AnimationItem.prototype.checkSegments = function (offset) {
     if (this.segments.length) {
       this.adjustSegment(this.segments.shift(), offset);
       return true;
     }
-
     return false;
   };
-
   AnimationItem.prototype.destroy = function (name) {
     if (name && this.name !== name || !this.renderer) {
       return;
     }
-
     this.renderer.destroy();
     this.imagePreloader.destroy();
     this.trigger('destroy');
@@ -2345,189 +1969,148 @@
     this.imagePreloader = null;
     this.projectInterface = null;
   };
-
   AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
     this.currentRawFrame = value;
     this.gotoFrame();
   };
-
   AnimationItem.prototype.setSpeed = function (val) {
     this.playSpeed = val;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setDirection = function (val) {
     this.playDirection = val < 0 ? -1 : 1;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setLoop = function (isLooping) {
     this.loop = isLooping;
   };
-
   AnimationItem.prototype.setVolume = function (val, name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.setVolume(val);
   };
-
   AnimationItem.prototype.getVolume = function () {
     return this.audioController.getVolume();
   };
-
   AnimationItem.prototype.mute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.mute();
   };
-
   AnimationItem.prototype.unmute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.unmute();
   };
-
   AnimationItem.prototype.updaFrameModifier = function () {
     this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
     this.audioController.setRate(this.playSpeed * this.playDirection);
   };
-
   AnimationItem.prototype.getPath = function () {
     return this.path;
   };
-
   AnimationItem.prototype.getAssetsPath = function (assetData) {
     var path = '';
-
     if (assetData.e) {
       path = assetData.p;
     } else if (this.assetsPath) {
       var imagePath = assetData.p;
-
       if (imagePath.indexOf('images/') !== -1) {
         imagePath = imagePath.split('/')[1];
       }
-
       path = this.assetsPath + imagePath;
     } else {
       path = this.path;
       path += assetData.u ? assetData.u : '';
       path += assetData.p;
     }
-
     return path;
   };
-
   AnimationItem.prototype.getAssetData = function (id) {
     var i = 0;
     var len = this.assets.length;
-
     while (i < len) {
       if (id === this.assets[i].id) {
         return this.assets[i];
       }
-
       i += 1;
     }
-
     return null;
   };
-
   AnimationItem.prototype.hide = function () {
     this.renderer.hide();
   };
-
   AnimationItem.prototype.show = function () {
     this.renderer.show();
   };
-
   AnimationItem.prototype.getDuration = function (isFrame) {
     return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
   };
-
   AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
     try {
       var element = this.renderer.getElementByPath(path);
       element.updateDocumentData(documentData, index);
-    } catch (error) {// TODO: decide how to handle catch case
+    } catch (error) {
+      // TODO: decide how to handle catch case
     }
   };
-
   AnimationItem.prototype.trigger = function (name) {
     if (this._cbs && this._cbs[name]) {
       switch (name) {
         case 'enterFrame':
           this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
           break;
-
         case 'drawnFrame':
           this.drawnFrameEvent.currentTime = this.currentFrame;
           this.drawnFrameEvent.totalTime = this.totalFrames;
           this.drawnFrameEvent.direction = this.frameModifier;
           this.triggerEvent(name, this.drawnFrameEvent);
           break;
-
         case 'loopComplete':
           this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
           break;
-
         case 'complete':
           this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
           break;
-
         case 'segmentStart':
           this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
           break;
-
         case 'destroy':
           this.triggerEvent(name, new BMDestroyEvent(name, this));
           break;
-
         default:
           this.triggerEvent(name);
       }
     }
-
     if (name === 'enterFrame' && this.onEnterFrame) {
       this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
     }
-
     if (name === 'loopComplete' && this.onLoopComplete) {
       this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
     }
-
     if (name === 'complete' && this.onComplete) {
       this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
     }
-
     if (name === 'segmentStart' && this.onSegmentStart) {
       this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
     }
-
     if (name === 'destroy' && this.onDestroy) {
       this.onDestroy.call(this, new BMDestroyEvent(name, this));
     }
   };
-
   AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
     var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
   };
-
   AnimationItem.prototype.triggerConfigError = function (nativeError) {
     var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
@@ -2541,68 +2124,53 @@
     var playingAnimationsNum = 0;
     var _stopped = true;
     var _isFrozen = false;
-
     function removeElement(ev) {
       var i = 0;
       var animItem = ev.target;
-
       while (i < len) {
         if (registeredAnimations[i].animation === animItem) {
           registeredAnimations.splice(i, 1);
           i -= 1;
           len -= 1;
-
           if (!animItem.isPaused) {
             subtractPlayingCount();
           }
         }
-
         i += 1;
       }
     }
-
     function registerAnimation(element, animationData) {
       if (!element) {
         return null;
       }
-
       var i = 0;
-
       while (i < len) {
         if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
           return registeredAnimations[i].animation;
         }
-
         i += 1;
       }
-
       var animItem = new AnimationItem();
       setupAnimation(animItem, element);
       animItem.setData(element, animationData);
       return animItem;
     }
-
     function getRegisteredAnimations() {
       var i;
       var lenAnims = registeredAnimations.length;
       var animations = [];
-
       for (i = 0; i < lenAnims; i += 1) {
         animations.push(registeredAnimations[i].animation);
       }
-
       return animations;
     }
-
     function addPlayingCount() {
       playingAnimationsNum += 1;
       activate();
     }
-
     function subtractPlayingCount() {
       playingAnimationsNum -= 1;
     }
-
     function setupAnimation(animItem, element) {
       animItem.addEventListener('destroy', removeElement);
       animItem.addEventListener('_active', addPlayingCount);
@@ -2613,118 +2181,91 @@
       });
       len += 1;
     }
-
     function loadAnimation(params) {
       var animItem = new AnimationItem();
       setupAnimation(animItem, null);
       animItem.setParams(params);
       return animItem;
     }
-
     function setSpeed(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setSpeed(val, animation);
       }
     }
-
     function setDirection(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setDirection(val, animation);
       }
     }
-
     function play(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.play(animation);
       }
     }
-
     function resume(nowTime) {
       var elapsedTime = nowTime - initTime;
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.advanceTime(elapsedTime);
       }
-
       initTime = nowTime;
-
       if (playingAnimationsNum && !_isFrozen) {
         window.requestAnimationFrame(resume);
       } else {
         _stopped = true;
       }
     }
-
     function first(nowTime) {
       initTime = nowTime;
       window.requestAnimationFrame(resume);
     }
-
     function pause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.pause(animation);
       }
     }
-
     function goToAndStop(value, isFrame, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
       }
     }
-
     function stop(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.stop(animation);
       }
     }
-
     function togglePause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.togglePause(animation);
       }
     }
-
     function destroy(animation) {
       var i;
-
       for (i = len - 1; i >= 0; i -= 1) {
         registeredAnimations[i].animation.destroy(animation);
       }
     }
-
     function searchAnimations(animationData, standalone, renderer) {
       var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')), [].slice.call(document.getElementsByClassName('bodymovin')));
       var i;
       var lenAnims = animElements.length;
-
       for (i = 0; i < lenAnims; i += 1) {
         if (renderer) {
           animElements[i].setAttribute('data-bm-type', renderer);
         }
-
         registerAnimation(animElements[i], animationData);
       }
-
       if (standalone && lenAnims === 0) {
         if (!renderer) {
           renderer = 'svg';
         }
-
         var body = document.getElementsByTagName('body')[0];
         body.innerText = '';
         var div = createTag('div');
@@ -2735,15 +2276,12 @@
         registerAnimation(div, animationData);
       }
     }
-
     function resize() {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.resize();
       }
     }
-
     function activate() {
       if (!_isFrozen && playingAnimationsNum) {
         if (_stopped) {
@@ -2752,40 +2290,31 @@
         }
       }
     }
-
     function freeze() {
       _isFrozen = true;
     }
-
     function unfreeze() {
       _isFrozen = false;
       activate();
     }
-
     function setVolume(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setVolume(val, animation);
       }
     }
-
     function mute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.mute(animation);
       }
     }
-
     function unmute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.unmute(animation);
       }
     }
-
     moduleOb.registerAnimation = registerAnimation;
     moduleOb.loadAnimation = loadAnimation;
     moduleOb.setSpeed = setSpeed;
@@ -2795,8 +2324,8 @@
     moduleOb.stop = stop;
     moduleOb.togglePause = togglePause;
     moduleOb.searchAnimations = searchAnimations;
-    moduleOb.resize = resize; // moduleOb.start = start;
-
+    moduleOb.resize = resize;
+    // moduleOb.start = start;
     moduleOb.goToAndStop = goToAndStop;
     moduleOb.destroy = destroy;
     moduleOb.freeze = freeze;
@@ -2820,23 +2349,21 @@
        * spline.get(x) => returns the easing value | x must be in [0, 1] range
        *
        */
+
     var ob = {};
     ob.getBezierEasing = getBezierEasing;
     var beziers = {};
-
     function getBezierEasing(a, b, c, d, nm) {
       var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
-
       if (beziers[str]) {
         return beziers[str];
       }
-
       var bezEasing = new BezierEasing([a, b, c, d]);
       beziers[str] = bezEasing;
       return bezEasing;
-    } // These values are established by empiricism with tests (tradeoff: performance VS precision)
+    }
 
-
+    // These values are established by empiricism with tests (tradeoff: performance VS precision)
     var NEWTON_ITERATIONS = 4;
     var NEWTON_MIN_SLOPE = 0.001;
     var SUBDIVISION_PRECISION = 0.0000001;
@@ -2844,48 +2371,40 @@
     var kSplineTableSize = 11;
     var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
     var float32ArraySupported = typeof Float32Array === 'function';
-
     function A(aA1, aA2) {
       return 1.0 - 3.0 * aA2 + 3.0 * aA1;
     }
-
     function B(aA1, aA2) {
       return 3.0 * aA2 - 6.0 * aA1;
     }
-
     function C(aA1) {
       return 3.0 * aA1;
-    } // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+    }
 
-
+    // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
     function calcBezier(aT, aA1, aA2) {
       return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
-    } // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+    }
 
-
+    // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
     function getSlope(aT, aA1, aA2) {
       return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
     }
-
     function binarySubdivide(aX, aA, aB, mX1, mX2) {
       var currentX,
-          currentT,
-          i = 0;
-
+        currentT,
+        i = 0;
       do {
         currentT = aA + (aB - aA) / 2.0;
         currentX = calcBezier(currentT, mX1, mX2) - aX;
-
         if (currentX > 0.0) {
           aB = currentT;
         } else {
           aA = currentT;
         }
       } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
-
       return currentT;
     }
-
     function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
       for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
         var currentSlope = getSlope(aGuessT, mX1, mX2);
@@ -2893,85 +2412,75 @@
         var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
         aGuessT -= currentX / currentSlope;
       }
-
       return aGuessT;
     }
+
     /**
        * points is an array of [ mX1, mY1, mX2, mY2 ]
        */
-
-
     function BezierEasing(points) {
       this._p = points;
       this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
       this._precomputed = false;
       this.get = this.get.bind(this);
     }
-
     BezierEasing.prototype = {
       get: function get(x) {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         if (!this._precomputed) this._precompute();
         if (mX1 === mY1 && mX2 === mY2) return x; // linear
         // Because JavaScript number are imprecise, we should guarantee the extremes are right.
-
         if (x === 0) return 0;
         if (x === 1) return 1;
         return calcBezier(this._getTForX(x), mY1, mY2);
       },
       // Private part
+
       _precompute: function _precompute() {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         this._precomputed = true;
-
         if (mX1 !== mY1 || mX2 !== mY2) {
           this._calcSampleValues();
         }
       },
       _calcSampleValues: function _calcSampleValues() {
         var mX1 = this._p[0],
-            mX2 = this._p[2];
-
+          mX2 = this._p[2];
         for (var i = 0; i < kSplineTableSize; ++i) {
           this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
         }
       },
-
       /**
            * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
            */
       _getTForX: function _getTForX(aX) {
         var mX1 = this._p[0],
-            mX2 = this._p[2],
-            mSampleValues = this._mSampleValues;
+          mX2 = this._p[2],
+          mSampleValues = this._mSampleValues;
         var intervalStart = 0.0;
         var currentSample = 1;
         var lastSample = kSplineTableSize - 1;
-
         for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
           intervalStart += kSampleStepSize;
         }
+        --currentSample;
 
-        --currentSample; // Interpolate to provide an initial guess for t
-
+        // Interpolate to provide an initial guess for t
         var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
         var guessForT = intervalStart + dist * kSampleStepSize;
         var initialSlope = getSlope(guessForT, mX1, mX2);
-
         if (initialSlope >= NEWTON_MIN_SLOPE) {
           return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
         }
-
         if (initialSlope === 0.0) {
           return guessForT;
         }
-
         return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
       }
     };
@@ -2982,7 +2491,6 @@
     function _double(arr) {
       return arr.concat(createSizedArray(arr.length));
     }
-
     return {
       "double": _double
     };
@@ -2997,34 +2505,27 @@
         newElement: newElement,
         release: release
       };
-
       function newElement() {
         var element;
-
         if (_length) {
           _length -= 1;
           element = pool[_length];
         } else {
           element = _create();
         }
-
         return element;
       }
-
       function release(element) {
         if (_length === _maxLength) {
           pool = pooling["double"](pool);
           _maxLength *= 2;
         }
-
         if (_release) {
           _release(element);
         }
-
         pool[_length] = element;
         _length += 1;
       }
-
       return ob;
     };
   }();
@@ -3037,7 +2538,6 @@
         lengths: createTypedArray('float32', getDefaultCurveSegments())
       };
     }
-
     return poolFactory(8, create);
   }();
 
@@ -3048,39 +2548,31 @@
         totalLength: 0
       };
     }
-
     function release(element) {
       var i;
       var len = element.lengths.length;
-
       for (i = 0; i < len; i += 1) {
         bezierLengthPool.release(element.lengths[i]);
       }
-
       element.lengths.length = 0;
     }
-
     return poolFactory(8, create, release);
   }();
 
   function bezFunction() {
     var math = Math;
-
     function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
       var det1 = x1 * y2 + y1 * x3 + x2 * y3 - x3 * y2 - y3 * x1 - x2 * y1;
       return det1 > -0.001 && det1 < 0.001;
     }
-
     function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
       if (z1 === 0 && z2 === 0 && z3 === 0) {
         return pointOnLine2D(x1, y1, x2, y2, x3, y3);
       }
-
       var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
       var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
       var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
       var diffDist;
-
       if (dist1 > dist2) {
         if (dist1 > dist3) {
           diffDist = dist1 - dist2 - dist3;
@@ -3092,10 +2584,8 @@
       } else {
         diffDist = dist2 - dist1 - dist3;
       }
-
       return diffDist > -0.0001 && diffDist < 0.0001;
     }
-
     var getBezierLength = function () {
       return function (pt1, pt2, pt3, pt4) {
         var curveSegments = getDefaultCurveSegments();
@@ -3110,36 +2600,28 @@
         var lastPoint = [];
         var lengthData = bezierLengthPool.newElement();
         len = pt3.length;
-
         for (k = 0; k < curveSegments; k += 1) {
           perc = k / (curveSegments - 1);
           ptDistance = 0;
-
           for (i = 0; i < len; i += 1) {
             ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
             point[i] = ptCoord;
-
             if (lastPoint[i] !== null) {
               ptDistance += bmPow(point[i] - lastPoint[i], 2);
             }
-
             lastPoint[i] = point[i];
           }
-
           if (ptDistance) {
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
           }
-
           lengthData.percents[k] = perc;
           lengthData.lengths[k] = addedLength;
         }
-
         lengthData.addedLength = addedLength;
         return lengthData;
       };
     }();
-
     function getSegmentsLength(shapeData) {
       var segmentsLength = segmentsLengthPool.newElement();
       var closed = shapeData.c;
@@ -3150,36 +2632,29 @@
       var len = shapeData._length;
       var lengths = segmentsLength.lengths;
       var totalLength = 0;
-
       for (i = 0; i < len - 1; i += 1) {
         lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
         totalLength += lengths[i].addedLength;
       }
-
       if (closed && len) {
         lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
         totalLength += lengths[i].addedLength;
       }
-
       segmentsLength.totalLength = totalLength;
       return segmentsLength;
     }
-
     function BezierData(length) {
       this.segmentLength = 0;
       this.points = new Array(length);
     }
-
     function PointData(partial, point) {
       this.partialLength = partial;
       this.point = point;
     }
-
     var buildBezierData = function () {
       var storedData = {};
       return function (pt1, pt2, pt3, pt4) {
         var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
-
         if (!storedData[bezierName]) {
           var curveSegments = getDefaultCurveSegments();
           var k;
@@ -3191,42 +2666,33 @@
           var ptDistance;
           var point;
           var lastPoint = null;
-
           if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
             curveSegments = 2;
           }
-
           var bezierData = new BezierData(curveSegments);
           len = pt3.length;
-
           for (k = 0; k < curveSegments; k += 1) {
             point = createSizedArray(len);
             perc = k / (curveSegments - 1);
             ptDistance = 0;
-
             for (i = 0; i < len; i += 1) {
               ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
               point[i] = ptCoord;
-
               if (lastPoint !== null) {
                 ptDistance += bmPow(point[i] - lastPoint[i], 2);
               }
             }
-
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
             bezierData.points[k] = new PointData(ptDistance, point);
             lastPoint = point;
           }
-
           bezierData.segmentLength = addedLength;
           storedData[bezierName] = bezierData;
         }
-
         return storedData[bezierName];
       };
     }();
-
     function getDistancePerc(perc, bezierData) {
       var percents = bezierData.percents;
       var lengths = bezierData.lengths;
@@ -3234,14 +2700,11 @@
       var initPos = bmFloor((len - 1) * perc);
       var lengthPos = perc * bezierData.addedLength;
       var lPerc = 0;
-
       if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
         return percents[initPos];
       }
-
       var dir = lengths[initPos] > lengthPos ? -1 : 1;
       var flag = true;
-
       while (flag) {
         if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
           lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
@@ -3249,20 +2712,16 @@
         } else {
           initPos += dir;
         }
-
         if (initPos < 0 || initPos >= len - 1) {
           // FIX for TypedArrays that don't store floating point values with enough accuracy
           if (initPos === len - 1) {
             return percents[initPos];
           }
-
           flag = false;
         }
       }
-
       return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
     }
-
     function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
       var t1 = getDistancePerc(percent, bezierData);
       var u1 = 1 - t1;
@@ -3270,16 +2729,13 @@
       var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
       return [ptX, ptY];
     }
-
     var bezierSegmentPoints = createTypedArray('float32', 8);
-
     function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
       if (startPerc < 0) {
         startPerc = 0;
       } else if (startPerc > 1) {
         startPerc = 1;
       }
-
       var t0 = getDistancePerc(startPerc, bezierData);
       endPerc = endPerc > 1 ? 1 : endPerc;
       var t1 = getDistancePerc(endPerc, bezierData);
@@ -3289,45 +2745,31 @@
       var u1 = 1 - t1;
       var u0u0u0 = u0 * u0 * u0;
       var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
-
       var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
-
-      var t0t0t0 = t0 * t0 * t0; //
-
+      var t0t0t0 = t0 * t0 * t0;
+      //
       var u0u0u1 = u0 * u0 * u1;
       var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
-
       var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
-
-      var t0t0t1 = t0 * t0 * t1; //
-
+      var t0t0t1 = t0 * t0 * t1;
+      //
       var u0u1u1 = u0 * u1 * u1;
       var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
-
       var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
-
-      var t0t1t1 = t0 * t1 * t1; //
-
+      var t0t1t1 = t0 * t1 * t1;
+      //
       var u1u1u1 = u1 * u1 * u1;
       var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1t1 = t1 * t1 * t1;
-
       for (i = 0; i < len; i += 1) {
         bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
       }
-
       return bezierSegmentPoints;
     }
-
     return {
       getSegmentsLength: getSegmentsLength,
       getNewSegment: getNewSegment,
@@ -3337,20 +2779,16 @@
       pointOnLine3D: pointOnLine3D
     };
   }
-
   var bez = bezFunction();
 
   var initFrame = initialDefaultFrame;
   var mathAbs = Math.abs;
-
   function interpolateValue(frameNum, caching) {
     var offsetTime = this.offsetTime;
     var newValue;
-
     if (this.propType === 'multidimensional') {
       newValue = createTypedArray('float32', this.pv.length);
     }
-
     var iterationIndex = caching.lastIndex;
     var i = iterationIndex;
     var len = this.keyframes.length - 1;
@@ -3358,25 +2796,20 @@
     var keyData;
     var nextKeyData;
     var keyframeMetadata;
-
     while (flag) {
       keyData = this.keyframes[i];
       nextKeyData = this.keyframes[i + 1];
-
       if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
         if (keyData.h) {
           keyData = nextKeyData;
         }
-
         iterationIndex = 0;
         break;
       }
-
       if (nextKeyData.t - offsetTime > frameNum) {
         iterationIndex = i;
         break;
       }
-
       if (i < len - 1) {
         i += 1;
       } else {
@@ -3384,7 +2817,6 @@
         flag = false;
       }
     }
-
     keyframeMetadata = this.keyframesMetadata[i] || {};
     var k;
     var kLen;
@@ -3395,22 +2827,18 @@
     var nextKeyTime = nextKeyData.t - offsetTime;
     var keyTime = keyData.t - offsetTime;
     var endValue;
-
     if (keyData.to) {
       if (!keyframeMetadata.bezierData) {
         keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
       }
-
       var bezierData = keyframeMetadata.bezierData;
-
       if (frameNum >= nextKeyTime || frameNum < keyTime) {
         var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
         kLen = bezierData.points[ind].point.length;
-
         for (k = 0; k < kLen; k += 1) {
           newValue[k] = bezierData.points[ind].point[k];
-        } // caching._lastKeyframeIndex = -1;
-
+        }
+        // caching._lastKeyframeIndex = -1;
       } else {
         if (keyframeMetadata.__fnct) {
           fnc = keyframeMetadata.__fnct;
@@ -3418,7 +2846,6 @@
           fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
           keyframeMetadata.__fnct = fnc;
         }
-
         perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
         var distanceInLine = bezierData.segmentLength * perc;
         var segmentPerc;
@@ -3426,36 +2853,28 @@
         j = caching.lastFrame < frameNum && caching._lastKeyframeIndex === i ? caching._lastPoint : 0;
         flag = true;
         jLen = bezierData.points.length;
-
         while (flag) {
           addedLength += bezierData.points[j].partialLength;
-
           if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k];
             }
-
             break;
           } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
             segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
             }
-
             break;
           }
-
           if (j < jLen - 1) {
             j += 1;
           } else {
             flag = false;
           }
         }
-
         caching._lastPoint = j;
         caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
         caching._lastKeyframeIndex = i;
@@ -3468,7 +2887,6 @@
       var keyValue;
       len = keyData.s.length;
       endValue = nextKeyData.s || keyData.e;
-
       if (this.sh && keyData.h !== 1) {
         if (frameNum >= nextKeyTime) {
           newValue[0] = endValue[0];
@@ -3496,7 +2914,6 @@
                 if (!keyframeMetadata.__fnct) {
                   keyframeMetadata.__fnct = [];
                 }
-
                 if (!keyframeMetadata.__fnct[i]) {
                   outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
                   outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
@@ -3517,14 +2934,11 @@
               } else {
                 fnc = keyframeMetadata.__fnct;
               }
-
               perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
             }
           }
-
           endValue = nextKeyData.s || keyData.e;
           keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
-
           if (this.propType === 'multidimensional') {
             newValue[i] = keyValue;
           } else {
@@ -3533,12 +2947,11 @@
         }
       }
     }
-
     caching.lastIndex = iterationIndex;
     return newValue;
-  } // based on @Toji's https://github.com/toji/gl-matrix/
+  }
 
-
+  // based on @Toji's https://github.com/toji/gl-matrix/
   function slerp(a, b, t) {
     var out = [];
     var ax = a[0];
@@ -3555,7 +2968,6 @@
     var scale0;
     var scale1;
     cosom = ax * bx + ay * by + az * bz + aw * bw;
-
     if (cosom < 0.0) {
       cosom = -cosom;
       bx = -bx;
@@ -3563,7 +2975,6 @@
       bz = -bz;
       bw = -bw;
     }
-
     if (1.0 - cosom > 0.000001) {
       omega = Math.acos(cosom);
       sinom = Math.sin(omega);
@@ -3573,14 +2984,12 @@
       scale0 = 1.0 - t;
       scale1 = t;
     }
-
     out[0] = scale0 * ax + scale1 * bx;
     out[1] = scale0 * ay + scale1 * by;
     out[2] = scale0 * az + scale1 * bz;
     out[3] = scale0 * aw + scale1 * bw;
     return out;
   }
-
   function quaternionToEuler(out, quat) {
     var qx = quat[0];
     var qy = quat[1];
@@ -3593,7 +3002,6 @@
     out[1] = attitude / degToRads;
     out[2] = bank / degToRads;
   }
-
   function createQuaternion(values) {
     var heading = values[0] * degToRads;
     var attitude = values[1] * degToRads;
@@ -3610,32 +3018,25 @@
     var z = c1 * s2 * c3 - s1 * c2 * s3;
     return [x, y, z, w];
   }
-
   function getValueAtCurrentTime() {
     var frameNum = this.comp.renderedFrame - this.offsetTime;
     var initTime = this.keyframes[0].t - this.offsetTime;
     var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
-
     if (!(frameNum === this._caching.lastFrame || this._caching.lastFrame !== initFrame && (this._caching.lastFrame >= endTime && frameNum >= endTime || this._caching.lastFrame < initTime && frameNum < initTime))) {
       if (this._caching.lastFrame >= frameNum) {
         this._caching._lastKeyframeIndex = -1;
         this._caching.lastIndex = 0;
       }
-
       var renderResult = this.interpolateValue(frameNum, this._caching);
       this.pv = renderResult;
     }
-
     this._caching.lastFrame = frameNum;
     return this.pv;
   }
-
   function setVValue(val) {
     var multipliedValue;
-
     if (this.propType === 'unidimensional') {
       multipliedValue = val * this.mult;
-
       if (mathAbs(this.v - multipliedValue) > 0.00001) {
         this.v = multipliedValue;
         this._mdf = true;
@@ -3643,51 +3044,41 @@
     } else {
       var i = 0;
       var len = this.v.length;
-
       while (i < len) {
         multipliedValue = val[i] * this.mult;
-
         if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
           this.v[i] = multipliedValue;
           this._mdf = true;
         }
-
         i += 1;
       }
     }
   }
-
   function processEffectsSequence() {
     if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
       return;
     }
-
     if (this.lock) {
       this.setVValue(this.pv);
       return;
     }
-
     this.lock = true;
     this._mdf = this._isFirstFrame;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = this.kf ? this.pv : this.data.k;
-
     for (i = 0; i < len; i += 1) {
       finalValue = this.effectsSequence[i](finalValue);
     }
-
     this.setVValue(finalValue);
     this._isFirstFrame = false;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   }
-
   function addEffect(effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.container.addDynamicProperty(this);
   }
-
   function ValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.mult = mult || 1;
@@ -3707,7 +3098,6 @@
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function MultiDimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     this.mult = mult || 1;
@@ -3724,19 +3114,16 @@
     this.v = createTypedArray('float32', len);
     this.pv = createTypedArray('float32', len);
     this.vel = createTypedArray('float32', len);
-
     for (i = 0; i < len; i += 1) {
       this.v[i] = data.k[i] * this.mult;
       this.pv[i] = data.k[i];
     }
-
     this._isFirstFrame = true;
     this.effectsSequence = [];
     this.getValue = processEffectsSequence;
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function KeyframedValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.keyframes = data.k;
@@ -3765,7 +3152,6 @@
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.addEffect = addEffect;
   }
-
   function KeyframedMultidimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     var i;
@@ -3774,19 +3160,16 @@
     var e;
     var to;
     var ti;
-
     for (i = 0; i < len - 1; i += 1) {
       if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
         s = data.k[i].s;
         e = data.k[i + 1].s;
         to = data.k[i].to;
         ti = data.k[i].ti;
-
         if (s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1]) || s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2])) {
           data.k[i].to = null;
           data.k[i].ti = null;
         }
-
         if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
           if (s.length === 2 || s[2] === e[2] && to[2] === 0 && ti[2] === 0) {
             data.k[i].to = null;
@@ -3795,7 +3178,6 @@
         }
       }
     }
-
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.data = data;
     this.keyframes = data.k;
@@ -3815,12 +3197,10 @@
     var arrLen = data.k[0].s.length;
     this.v = createTypedArray('float32', arrLen);
     this.pv = createTypedArray('float32', arrLen);
-
     for (i = 0; i < arrLen; i += 1) {
       this.v[i] = initFrame;
       this.pv[i] = initFrame;
     }
-
     this._caching = {
       lastFrame: initFrame,
       lastIndex: 0,
@@ -3828,15 +3208,12 @@
     };
     this.addEffect = addEffect;
   }
-
   var PropertyFactory = function () {
     function getProp(elem, data, type, mult, container) {
       if (data.sid) {
         data = elem.globalData.slotManager.getProp(data);
       }
-
       var p;
-
       if (!data.k.length) {
         p = new ValueProperty(elem, data, mult, container);
       } else if (typeof data.k[0] === 'number') {
@@ -3846,23 +3223,18 @@
           case 0:
             p = new KeyframedValueProperty(elem, data, mult, container);
             break;
-
           case 1:
             p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
             break;
-
           default:
             break;
         }
       }
-
       if (p.effectsSequence.length) {
         container.addDynamicProperty(p);
       }
-
       return p;
     }
-
     var ob = {
       getProp: getProp
     };
@@ -3870,7 +3242,6 @@
   }();
 
   function DynamicPropertyContainer() {}
-
   DynamicPropertyContainer.prototype = {
     addDynamicProperty: function addDynamicProperty(prop) {
       if (this.dynamicProperties.indexOf(prop) === -1) {
@@ -3883,10 +3254,8 @@
       this._mdf = false;
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         this.dynamicProperties[i].getValue();
-
         if (this.dynamicProperties[i]._mdf) {
           this._mdf = true;
         }
@@ -3904,7 +3273,6 @@
     function create() {
       return createTypedArray('float32', 2);
     }
-
     return poolFactory(8, create);
   }();
 
@@ -3916,12 +3284,10 @@
     this.o = createSizedArray(this._maxLength);
     this.i = createSizedArray(this._maxLength);
   }
-
   ShapePath.prototype.setPathData = function (closed, len) {
     this.c = closed;
     this.setLength(len);
     var i = 0;
-
     while (i < len) {
       this.v[i] = pointPool.newElement();
       this.o[i] = pointPool.newElement();
@@ -3929,62 +3295,49 @@
       i += 1;
     }
   };
-
   ShapePath.prototype.setLength = function (len) {
     while (this._maxLength < len) {
       this.doubleArrayLength();
     }
-
     this._length = len;
   };
-
   ShapePath.prototype.doubleArrayLength = function () {
     this.v = this.v.concat(createSizedArray(this._maxLength));
     this.i = this.i.concat(createSizedArray(this._maxLength));
     this.o = this.o.concat(createSizedArray(this._maxLength));
     this._maxLength *= 2;
   };
-
   ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
     var arr;
     this._length = Math.max(this._length, pos + 1);
-
     if (this._length >= this._maxLength) {
       this.doubleArrayLength();
     }
-
     switch (type) {
       case 'v':
         arr = this.v;
         break;
-
       case 'i':
         arr = this.i;
         break;
-
       case 'o':
         arr = this.o;
         break;
-
       default:
         arr = [];
         break;
     }
-
     if (!arr[pos] || arr[pos] && !replace) {
       arr[pos] = pointPool.newElement();
     }
-
     arr[pos][0] = x;
     arr[pos][1] = y;
   };
-
   ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
     this.setXYAt(vX, vY, 'v', pos, replace);
     this.setXYAt(oX, oY, 'o', pos, replace);
     this.setXYAt(iX, iY, 'i', pos, replace);
   };
-
   ShapePath.prototype.reverse = function () {
     var newPath = new ShapePath();
     newPath.setPathData(this.c, this._length);
@@ -3992,24 +3345,19 @@
     var outPoints = this.o;
     var inPoints = this.i;
     var init = 0;
-
     if (this.c) {
       newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
       init = 1;
     }
-
     var cnt = this._length - 1;
     var len = this._length;
     var i;
-
     for (i = init; i < len; i += 1) {
       newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
       cnt -= 1;
     }
-
     return newPath;
   };
-
   ShapePath.prototype.length = function () {
     return this._length;
   };
@@ -4018,11 +3366,9 @@
     function create() {
       return new ShapePath();
     }
-
     function release(shapePath) {
       var len = shapePath._length;
       var i;
-
       for (i = 0; i < len; i += 1) {
         pointPool.release(shapePath.v[i]);
         pointPool.release(shapePath.i[i]);
@@ -4031,25 +3377,20 @@
         shapePath.i[i] = null;
         shapePath.o[i] = null;
       }
-
       shapePath._length = 0;
       shapePath.c = false;
     }
-
     function clone(shape) {
       var cloned = factory.newElement();
       var i;
       var len = shape._length === undefined ? shape.v.length : shape._length;
       cloned.setLength(len);
       cloned.c = shape.c;
-
       for (i = 0; i < len; i += 1) {
         cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
       }
-
       return cloned;
     }
-
     var factory = poolFactory(4, create, release);
     factory.clone = clone;
     return factory;
@@ -4060,24 +3401,19 @@
     this._maxLength = 4;
     this.shapes = createSizedArray(this._maxLength);
   }
-
   ShapeCollection.prototype.addShape = function (shapeData) {
     if (this._length === this._maxLength) {
       this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
       this._maxLength *= 2;
     }
-
     this.shapes[this._length] = shapeData;
     this._length += 1;
   };
-
   ShapeCollection.prototype.releaseShapes = function () {
     var i;
-
     for (i = 0; i < this._length; i += 1) {
       shapePool.release(this.shapes[i]);
     }
-
     this._length = 0;
   };
 
@@ -4089,45 +3425,35 @@
     var _length = 0;
     var _maxLength = 4;
     var pool = createSizedArray(_maxLength);
-
     function newShapeCollection() {
       var shapeCollection;
-
       if (_length) {
         _length -= 1;
         shapeCollection = pool[_length];
       } else {
         shapeCollection = new ShapeCollection();
       }
-
       return shapeCollection;
     }
-
     function release(shapeCollection) {
       var i;
       var len = shapeCollection._length;
-
       for (i = 0; i < len; i += 1) {
         shapePool.release(shapeCollection.shapes[i]);
       }
-
       shapeCollection._length = 0;
-
       if (_length === _maxLength) {
         pool = pooling["double"](pool);
         _maxLength *= 2;
       }
-
       pool[_length] = shapeCollection;
       _length += 1;
     }
-
     return ob;
   }();
 
   var ShapePropertyFactory = function () {
     var initFrame = -999999;
-
     function interpolateShape(frameNum, previousValue, caching) {
       var iterationIndex = caching.lastIndex;
       var keyPropS;
@@ -4140,7 +3466,6 @@
       var perc;
       var vertexValue;
       var kf = this.keyframes;
-
       if (frameNum < kf[0].t - this.offsetTime) {
         keyPropS = kf[0].s[0];
         isHold = true;
@@ -4152,7 +3477,6 @@
               }else{
                   keyPropS = kf[kf.length - 2].e[0];
               } */
-
         isHold = true;
       } else {
         var i = iterationIndex;
@@ -4161,26 +3485,21 @@
         var keyData;
         var nextKeyData;
         var keyframeMetadata;
-
         while (flag) {
           keyData = kf[i];
           nextKeyData = kf[i + 1];
-
           if (nextKeyData.t - this.offsetTime > frameNum) {
             break;
           }
-
           if (i < len - 1) {
             i += 1;
           } else {
             flag = false;
           }
         }
-
         keyframeMetadata = this.keyframesMetadata[i] || {};
         isHold = keyData.h === 1;
         iterationIndex = i;
-
         if (!isHold) {
           if (frameNum >= nextKeyData.t - this.offsetTime) {
             perc = 1;
@@ -4188,27 +3507,21 @@
             perc = 0;
           } else {
             var fnc;
-
             if (keyframeMetadata.__fnct) {
               fnc = keyframeMetadata.__fnct;
             } else {
               fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
               keyframeMetadata.__fnct = fnc;
             }
-
             perc = fnc((frameNum - (keyData.t - this.offsetTime)) / (nextKeyData.t - this.offsetTime - (keyData.t - this.offsetTime)));
           }
-
           keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
         }
-
         keyPropS = keyData.s[0];
       }
-
       jLen = previousValue._length;
       kLen = keyPropS.i[0].length;
       caching.lastIndex = iterationIndex;
-
       for (j = 0; j < jLen; j += 1) {
         for (k = 0; k < kLen; k += 1) {
           vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
@@ -4220,44 +3533,36 @@
         }
       }
     }
-
     function interpolateShapeCurrentTime() {
       var frameNum = this.comp.renderedFrame - this.offsetTime;
       var initTime = this.keyframes[0].t - this.offsetTime;
       var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
       var lastFrame = this._caching.lastFrame;
-
       if (!(lastFrame !== initFrame && (lastFrame < initTime && frameNum < initTime || lastFrame > endTime && frameNum > endTime))) {
         /// /
         this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
-        this.interpolateShape(frameNum, this.pv, this._caching); /// /
+        this.interpolateShape(frameNum, this.pv, this._caching);
+        /// /
       }
-
       this._caching.lastFrame = frameNum;
       return this.pv;
     }
-
     function resetShape() {
       this.paths = this.localShapeCollection;
     }
-
     function shapesEqual(shape1, shape2) {
       if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
         return false;
       }
-
       var i;
       var len = shape1._length;
-
       for (i = 0; i < len; i += 1) {
         if (shape1.v[i][0] !== shape2.v[i][0] || shape1.v[i][1] !== shape2.v[i][1] || shape1.o[i][0] !== shape2.o[i][0] || shape1.o[i][1] !== shape2.o[i][1] || shape1.i[i][0] !== shape2.i[i][0] || shape1.i[i][1] !== shape2.i[i][1]) {
           return false;
         }
       }
-
       return true;
     }
-
     function setVValue(newPath) {
       if (!shapesEqual(this.v, newPath)) {
         this.v = shapePool.clone(newPath);
@@ -4267,26 +3572,21 @@
         this.paths = this.localShapeCollection;
       }
     }
-
     function processEffectsSequence() {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (!this.effectsSequence.length) {
         this._mdf = false;
         return;
       }
-
       if (this.lock) {
         this.setVValue(this.pv);
         return;
       }
-
       this.lock = true;
       this._mdf = false;
       var finalValue;
-
       if (this.kf) {
         finalValue = this.pv;
       } else if (this.data.ks) {
@@ -4294,19 +3594,15 @@
       } else {
         finalValue = this.data.pt.k;
       }
-
       var i;
       var len = this.effectsSequence.length;
-
       for (i = 0; i < len; i += 1) {
         finalValue = this.effectsSequence[i](finalValue);
       }
-
       this.setVValue(finalValue);
       this.lock = false;
       this.frameId = this.elem.globalData.frameId;
     }
-
     function ShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4325,17 +3621,14 @@
       this.reset = resetShape;
       this.effectsSequence = [];
     }
-
     function addEffect(effectFunction) {
       this.effectsSequence.push(effectFunction);
       this.container.addDynamicProperty(this);
     }
-
     ShapeProperty.prototype.interpolateShape = interpolateShape;
     ShapeProperty.prototype.getValue = processEffectsSequence;
     ShapeProperty.prototype.setVValue = setVValue;
     ShapeProperty.prototype.addEffect = addEffect;
-
     function KeyframedShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4361,15 +3654,12 @@
       };
       this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
     }
-
     KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
     KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
     KeyframedShapeProperty.prototype.setVValue = setVValue;
     KeyframedShapeProperty.prototype.addEffect = addEffect;
-
     var EllShapeProperty = function () {
       var cPoint = roundCorner;
-
       function EllShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
         this.v.setPathData(true, 4);
@@ -4383,7 +3673,6 @@
         this.initDynamicPropertyContainer(elem);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4391,17 +3680,14 @@
           this.convertEllToPath();
         }
       }
-
       EllShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertEllToPath();
           }
@@ -4411,9 +3697,7 @@
           var p1 = this.p.v[1];
           var s0 = this.s.v[0] / 2;
           var s1 = this.s.v[1] / 2;
-
           var _cw = this.d !== 3;
-
           var _v = this.v;
           _v.v[0][0] = p0;
           _v.v[0][1] = p1 - s1;
@@ -4444,7 +3728,6 @@
       extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
       return EllShapePropertyFactory;
     }();
-
     var StarShapeProperty = function () {
       function StarShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4455,7 +3738,6 @@
         this.frameId = -1;
         this.d = data.d;
         this.initDynamicPropertyContainer(elem);
-
         if (data.sy === 1) {
           this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
           this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
@@ -4463,7 +3745,6 @@
         } else {
           this.convertToPath = this.convertPolygonToPath;
         }
-
         this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
@@ -4472,7 +3753,6 @@
         this.localShapeCollection = shapeCollectionPool.newShapeCollection();
         this.localShapeCollection.addShape(this.v);
         this.paths = this.localShapeCollection;
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4480,17 +3760,14 @@
           this.convertToPath();
         }
       }
-
       StarShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertToPath();
           }
@@ -4501,7 +3778,6 @@
           /* this.v.v.length = numPts;
                   this.v.i.length = numPts;
                   this.v.o.length = numPts; */
-
           var longFlag = true;
           var longRad = this.or.v;
           var shortRad = this.ir.v;
@@ -4517,7 +3793,6 @@
           currentAng += this.r.v;
           var dir = this.data.d === 3 ? -1 : 1;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             rad = longFlag ? longRad : shortRad;
             roundness = longFlag ? longRound : shortRound;
@@ -4529,11 +3804,11 @@
             x += +this.p.v[0];
             y += +this.p.v[1];
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
             /* this.v.v[i] = [x,y];
                       this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
                       this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
                       this.v._length = numPts; */
-
             longFlag = !longFlag;
             currentAng += angle * dir;
           }
@@ -4549,7 +3824,6 @@
           var dir = this.data.d === 3 ? -1 : 1;
           currentAng += this.r.v;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             var x = rad * Math.cos(currentAng);
             var y = rad * Math.sin(currentAng);
@@ -4560,7 +3834,6 @@
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
             currentAng += angle * dir;
           }
-
           this.paths.length = 0;
           this.paths[0] = this.v;
         }
@@ -4568,7 +3841,6 @@
       extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
       return StarShapePropertyFactory;
     }();
-
     var RectShapeProperty = function () {
       function RectShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4584,7 +3856,6 @@
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4592,7 +3863,6 @@
           this.convertRectToPath();
         }
       }
-
       RectShapePropertyFactory.prototype = {
         convertRectToPath: function convertRectToPath() {
           var p0 = this.p.v[0];
@@ -4602,11 +3872,9 @@
           var round = bmMin(v0, v1, this.r.v);
           var cPoint = round * (1 - roundCorner);
           this.v._length = 0;
-
           if (this.d === 2 || this.d === 1) {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
             this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
               this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
@@ -4620,7 +3888,6 @@
             }
           } else {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
               this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
@@ -4640,10 +3907,8 @@
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertRectToPath();
           }
@@ -4653,14 +3918,11 @@
       extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
       return RectShapePropertyFactory;
     }();
-
     function getShapeProp(elem, data, type) {
       var prop;
-
       if (type === 3 || type === 4) {
         var dataProp = type === 3 ? data.pt : data.ks;
         var keys = dataProp.k;
-
         if (keys.length) {
           prop = new KeyframedShapeProperty(elem, data, type);
         } else {
@@ -4673,22 +3935,17 @@
       } else if (type === 7) {
         prop = new StarShapeProperty(elem, data);
       }
-
       if (prop.k) {
         elem.addDynamicProperty(prop);
       }
-
       return prop;
     }
-
     function getConstructorFunction() {
       return ShapeProperty;
     }
-
     function getKeyframedConstructorFunction() {
       return KeyframedShapeProperty;
     }
-
     var ob = {};
     ob.getShapeProp = getShapeProp;
     ob.getConstructorFunction = getConstructorFunction;
@@ -4730,7 +3987,6 @@
     var _sin = Math.sin;
     var _tan = Math.tan;
     var _rnd = Math.round;
-
     function reset() {
       this.props[0] = 1;
       this.props[1] = 0;
@@ -4750,83 +4006,59 @@
       this.props[15] = 1;
       return this;
     }
-
     function rotate(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function rotateX(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateY(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateZ(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function shear(sx, sy) {
       return this._t(1, sy, sx, 1, 0, 0);
     }
-
     function skew(ax, ay) {
       return this.shear(_tan(ax), _tan(ay));
     }
-
     function skewFromAxis(ax, angle) {
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
-      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+      // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
     }
-
     function scale(sx, sy, sz) {
       if (!sz && sz !== 0) {
         sz = 1;
       }
-
       if (sx === 1 && sy === 1 && sz === 1) {
         return this;
       }
-
       return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
     }
-
     function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
       this.props[0] = a;
       this.props[1] = b;
@@ -4846,32 +4078,26 @@
       this.props[15] = p;
       return this;
     }
-
     function translate(tx, ty, tz) {
       tz = tz || 0;
-
       if (tx !== 0 || ty !== 0 || tz !== 0) {
         return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
       }
-
       return this;
     }
-
     function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
       var _p = this.props;
-
       if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
         // NOTE: commenting this condition because TurboFan deoptimizes code when present
         // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
         _p[12] = _p[12] * a2 + _p[15] * m2;
         _p[13] = _p[13] * f2 + _p[15] * n2;
         _p[14] = _p[14] * k2 + _p[15] * o2;
-        _p[15] *= p2; // }
-
+        _p[15] *= p2;
+        // }
         this._identityCalculated = false;
         return this;
       }
-
       var a1 = _p[0];
       var b1 = _p[1];
       var c1 = _p[2];
@@ -4888,12 +4114,12 @@
       var n1 = _p[13];
       var o1 = _p[14];
       var p1 = _p[15];
+
       /* matrix order (canvas compatible):
            * ace
            * bdf
            * 001
            */
-
       _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
       _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
       _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
@@ -4913,53 +4139,40 @@
       this._identityCalculated = false;
       return this;
     }
-
     function multiply(matrix) {
       var matrixProps = matrix.props;
       return this.transform(matrixProps[0], matrixProps[1], matrixProps[2], matrixProps[3], matrixProps[4], matrixProps[5], matrixProps[6], matrixProps[7], matrixProps[8], matrixProps[9], matrixProps[10], matrixProps[11], matrixProps[12], matrixProps[13], matrixProps[14], matrixProps[15]);
     }
-
     function isIdentity() {
       if (!this._identityCalculated) {
         this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
         this._identityCalculated = true;
       }
-
       return this._identity;
     }
-
     function equals(matr) {
       var i = 0;
-
       while (i < 16) {
         if (matr.props[i] !== this.props[i]) {
           return false;
         }
-
         i += 1;
       }
-
       return true;
     }
-
     function clone(matr) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         matr.props[i] = this.props[i];
       }
-
       return matr;
     }
-
     function cloneFromProps(props) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         this.props[i] = props[i];
       }
     }
-
     function applyToPoint(x, y, z) {
       return {
         x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
@@ -4971,19 +4184,15 @@
            y: x * me.b + y * me.d + me.f
            }; */
     }
-
     function applyToX(x, y, z) {
       return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
     }
-
     function applyToY(x, y, z) {
       return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
     }
-
     function applyToZ(x, y, z) {
       return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
     }
-
     function getInverseMatrix() {
       var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
       var a = this.props[5] / determinant;
@@ -5001,27 +4210,21 @@
       inverseMatrix.props[13] = f;
       return inverseMatrix;
     }
-
     function inversePoint(pt) {
       var inverseMatrix = this.getInverseMatrix();
       return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
     }
-
     function inversePoints(pts) {
       var i;
       var len = pts.length;
       var retPts = [];
-
       for (i = 0; i < len; i += 1) {
         retPts[i] = inversePoint(pts[i]);
       }
-
       return retPts;
     }
-
     function applyToTriplePoints(pt1, pt2, pt3) {
       var arr = createTypedArray('float32', 6);
-
       if (this.isIdentity()) {
         arr[0] = pt1[0];
         arr[1] = pt1[1];
@@ -5043,34 +4246,26 @@
         arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
         arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
       }
-
       return arr;
     }
-
     function applyToPointArray(x, y, z) {
       var arr;
-
       if (this.isIdentity()) {
         arr = [x, y, z];
       } else {
         arr = [x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12], x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13], x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14]];
       }
-
       return arr;
     }
-
     function applyToPointStringified(x, y) {
       if (this.isIdentity()) {
         return x + ',' + y;
       }
-
       var _p = this.props;
       return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
     }
-
     function toCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
@@ -5078,49 +4273,34 @@
       var props = this.props;
       var cssValue = 'matrix3d(';
       var v = 10000;
-
       while (i < 16) {
         cssValue += _rnd(props[i] * v) / v;
         cssValue += i === 15 ? ')' : ',';
         i += 1;
       }
-
       return cssValue;
     }
-
     function roundMatrixProperty(val) {
       var v = 10000;
-
       if (val < 0.000001 && val > 0 || val > -0.000001 && val < 0) {
         return _rnd(val * v) / v;
       }
-
       return val;
     }
-
     function to2dCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
       var props = this.props;
-
       var _a = roundMatrixProperty(props[0]);
-
       var _b = roundMatrixProperty(props[1]);
-
       var _c = roundMatrixProperty(props[4]);
-
       var _d = roundMatrixProperty(props[5]);
-
       var _e = roundMatrixProperty(props[12]);
-
       var _f = roundMatrixProperty(props[13]);
-
       return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
     }
-
     return function () {
       this.reset = reset;
       this.rotate = rotate;
@@ -5159,16 +4339,14 @@
     };
   }();
 
-  function _typeof$3(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$3 = function _typeof(obj) { return typeof obj; }; } else { _typeof$3 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$3(obj); }
+  function _typeof$3(o) { "@babel/helpers - typeof"; return _typeof$3 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$3(o); }
   var lottie = {};
   var standalone = '__[STANDALONE]__';
   var animationData = '__[ANIMATIONDATA]__';
   var renderer = '';
-
   function setLocation(href) {
     setLocationHref(href);
   }
-
   function searchAnimations() {
     if (standalone === true) {
       animationManager.searchAnimations(animationData, standalone, renderer);
@@ -5176,35 +4354,28 @@
       animationManager.searchAnimations();
     }
   }
-
   function setSubframeRendering(flag) {
     setSubframeEnabled(flag);
   }
-
   function setPrefix(prefix) {
     setIdPrefix(prefix);
   }
-
   function loadAnimation(params) {
     if (standalone === true) {
       params.animationData = JSON.parse(animationData);
     }
-
     return animationManager.loadAnimation(params);
   }
-
   function setQuality(value) {
     if (typeof value === 'string') {
       switch (value) {
         case 'high':
           setDefaultCurveSegments(200);
           break;
-
         default:
         case 'medium':
           setDefaultCurveSegments(50);
           break;
-
         case 'low':
           setDefaultCurveSegments(10);
           break;
@@ -5212,40 +4383,32 @@
     } else if (!isNaN(value) && value > 1) {
       setDefaultCurveSegments(value);
     }
-
     if (getDefaultCurveSegments() >= 50) {
       roundValues(false);
     } else {
       roundValues(true);
     }
   }
-
   function inBrowser() {
     return typeof navigator !== 'undefined';
   }
-
   function installPlugin(type, plugin) {
     if (type === 'expressions') {
       setExpressionsPlugin(plugin);
     }
   }
-
   function getFactory(name) {
     switch (name) {
       case 'propertyFactory':
         return PropertyFactory;
-
       case 'shapePropertyFactory':
         return ShapePropertyFactory;
-
       case 'matrix':
         return Matrix;
-
       default:
         return null;
     }
   }
-
   lottie.play = animationManager.play;
   lottie.pause = animationManager.pause;
   lottie.setLocationHref = setLocation;
@@ -5257,8 +4420,8 @@
   lottie.registerAnimation = animationManager.registerAnimation;
   lottie.loadAnimation = loadAnimation;
   lottie.setSubframeRendering = setSubframeRendering;
-  lottie.resize = animationManager.resize; // lottie.start = start;
-
+  lottie.resize = animationManager.resize;
+  // lottie.start = start;
   lottie.goToAndStop = animationManager.goToAndStop;
   lottie.destroy = animationManager.destroy;
   lottie.setQuality = setQuality;
@@ -5273,32 +4436,25 @@
   lottie.useWebWorker = setWebWorker;
   lottie.setIDPrefix = setPrefix;
   lottie.__getFactory = getFactory;
-  lottie.version = '5.12.2';
-
+  lottie.version = '5.13.0';
   function checkReady() {
     if (document.readyState === 'complete') {
       clearInterval(readyStateCheckInterval);
       searchAnimations();
     }
   }
-
   function getQueryVariable(variable) {
     var vars = queryString.split('&');
-
     for (var i = 0; i < vars.length; i += 1) {
       var pair = vars[i].split('=');
-
       if (decodeURIComponent(pair[0]) == variable) {
         // eslint-disable-line eqeqeq
         return decodeURIComponent(pair[1]);
       }
     }
-
     return null;
   }
-
   var queryString = '';
-
   if (standalone) {
     var scripts = document.getElementsByTagName('script');
     var index = scripts.length - 1;
@@ -5306,18 +4462,18 @@
       src: ''
     };
     queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
-
     renderer = getQueryVariable('renderer');
   }
+  var readyStateCheckInterval = setInterval(checkReady, 100);
 
-  var readyStateCheckInterval = setInterval(checkReady, 100); // this adds bodymovin to the window object for backwards compatibility
-
+  // this adds bodymovin to the window object for backwards compatibility
   try {
     if (!((typeof exports === "undefined" ? "undefined" : _typeof$3(exports)) === 'object' && typeof module !== 'undefined') && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
     ) {
       window.bodymovin = lottie;
     }
-  } catch (err) {//
+  } catch (err) {
+    //
   }
 
   var ShapeModifiers = function () {
@@ -5325,26 +4481,19 @@
     var modifiers = {};
     ob.registerModifier = registerModifier;
     ob.getModifier = getModifier;
-
     function registerModifier(nm, factory) {
       if (!modifiers[nm]) {
         modifiers[nm] = factory;
       }
     }
-
     function getModifier(nm, elem, data) {
       return new modifiers[nm](elem, data);
     }
-
     return ob;
   }();
-
   function ShapeModifier() {}
-
   ShapeModifier.prototype.initModifierProperties = function () {};
-
   ShapeModifier.prototype.addShapeToModifier = function () {};
-
   ShapeModifier.prototype.addShape = function (data) {
     if (!this.closed) {
       // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
@@ -5356,13 +4505,11 @@
       };
       this.shapes.push(shapeData);
       this.addShapeToModifier(shapeData);
-
       if (this._isAnimated) {
         data.setAsAnimated();
       }
     }
   };
-
   ShapeModifier.prototype.init = function (elem, data) {
     this.shapes = [];
     this.elem = elem;
@@ -5371,29 +4518,23 @@
     this.frameId = initialDefaultFrame;
     this.closed = false;
     this.k = false;
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   ShapeModifier.prototype.processKeys = function () {
     if (this.elem.globalData.frameId === this.frameId) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   extendPrototype([DynamicPropertyContainer], ShapeModifier);
 
   function TrimModifier() {}
-
   extendPrototype([ShapeModifier], TrimModifier);
-
   TrimModifier.prototype.initModifierProperties = function (elem, data) {
     this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
     this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
@@ -5404,14 +4545,11 @@
     this.m = data.m;
     this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
   };
-
   TrimModifier.prototype.addShapeToModifier = function (shapeData) {
     shapeData.pathsData = [];
   };
-
   TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
     var segments = [];
-
     if (e <= 1) {
       segments.push({
         s: s,
@@ -5432,65 +4570,50 @@
         e: e - 1
       });
     }
-
     var shapeSegments = [];
     var i;
     var len = segments.length;
     var segmentOb;
-
     for (i = 0; i < len; i += 1) {
       segmentOb = segments[i];
-
       if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
         var shapeS;
         var shapeE;
-
         if (segmentOb.s * totalModifierLength <= addedLength) {
           shapeS = 0;
         } else {
           shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
         }
-
         if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
           shapeE = 1;
         } else {
           shapeE = (segmentOb.e * totalModifierLength - addedLength) / shapeLength;
         }
-
         shapeSegments.push([shapeS, shapeE]);
       }
     }
-
     if (!shapeSegments.length) {
       shapeSegments.push([0, 0]);
     }
-
     return shapeSegments;
   };
-
   TrimModifier.prototype.releasePathsData = function (pathsData) {
     var i;
     var len = pathsData.length;
-
     for (i = 0; i < len; i += 1) {
       segmentsLengthPool.release(pathsData[i]);
     }
-
     pathsData.length = 0;
     return pathsData;
   };
-
   TrimModifier.prototype.processShapes = function (_isFirstFrame) {
     var s;
     var e;
-
     if (this._mdf || _isFirstFrame) {
       var o = this.o.v % 360 / 360;
-
       if (o < 0) {
         o += 1;
       }
-
       if (this.s.v > 1) {
         s = 1 + o;
       } else if (this.s.v < 0) {
@@ -5498,7 +4621,6 @@
       } else {
         s = this.s.v + o;
       }
-
       if (this.e.v > 1) {
         e = 1 + o;
       } else if (this.e.v < 0) {
@@ -5506,13 +4628,11 @@
       } else {
         e = this.e.v + o;
       }
-
       if (s > e) {
         var _s = s;
         s = e;
         e = _s;
       }
-
       s = Math.round(s * 10000) * 0.0001;
       e = Math.round(e * 10000) * 0.0001;
       this.sValue = s;
@@ -5521,7 +4641,6 @@
       s = this.sValue;
       e = this.eValue;
     }
-
     var shapePaths;
     var i;
     var len = this.shapes.length;
@@ -5531,13 +4650,11 @@
     var pathData;
     var totalShapeLength;
     var totalModifierLength = 0;
-
     if (e === s) {
       for (i = 0; i < len; i += 1) {
         this.shapes[i].localShapeCollection.releaseShapes();
         this.shapes[i].shape._mdf = true;
         this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
-
         if (this._mdf) {
           this.shapes[i].pathsData.length = 0;
         }
@@ -5546,63 +4663,52 @@
       var segments = [];
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
-        shapeData = this.shapes[i]; // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
-
+        shapeData = this.shapes[i];
+        // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
         if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
           shapeData.shape.paths = shapeData.localShapeCollection;
         } else {
           shapePaths = shapeData.shape.paths;
           jLen = shapePaths._length;
           totalShapeLength = 0;
-
           if (!shapeData.shape._mdf && shapeData.pathsData.length) {
             totalShapeLength = shapeData.totalShapeLength;
           } else {
             pathsData = this.releasePathsData(shapeData.pathsData);
-
             for (j = 0; j < jLen; j += 1) {
               pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
               pathsData.push(pathData);
               totalShapeLength += pathData.totalLength;
             }
-
             shapeData.totalShapeLength = totalShapeLength;
             shapeData.pathsData = pathsData;
           }
-
           totalModifierLength += totalShapeLength;
           shapeData.shape._mdf = true;
         }
       }
-
       var shapeS = s;
       var shapeE = e;
       var addedLength = 0;
       var edges;
-
       for (i = len - 1; i >= 0; i -= 1) {
         shapeData = this.shapes[i];
-
         if (shapeData.shape._mdf) {
           localShapeCollection = shapeData.localShapeCollection;
-          localShapeCollection.releaseShapes(); // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
-
+          localShapeCollection.releaseShapes();
+          // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
           if (this.m === 2 && len > 1) {
             edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
             addedLength += shapeData.totalShapeLength;
           } else {
             edges = [[shapeS, shapeE]];
           }
-
           jLen = edges.length;
-
           for (j = 0; j < jLen; j += 1) {
             shapeS = edges[j][0];
             shapeE = edges[j][1];
             segments.length = 0;
-
             if (shapeE <= 1) {
               segments.push({
                 s: shapeData.totalShapeLength * shapeS,
@@ -5623,13 +4729,10 @@
                 e: shapeData.totalShapeLength * (shapeE - 1)
               });
             }
-
             var newShapesData = this.addShapes(shapeData, segments[0]);
-
             if (segments[0].s !== segments[0].e) {
               if (segments.length > 1) {
                 var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
-
                 if (lastShapeInCollection.c) {
                   var lastShape = newShapesData.pop();
                   this.addPaths(newShapesData, localShapeCollection);
@@ -5639,11 +4742,9 @@
                   newShapesData = this.addShapes(shapeData, segments[1]);
                 }
               }
-
               this.addPaths(newShapesData, localShapeCollection);
             }
           }
-
           shapeData.shape.paths = localShapeCollection;
         }
       }
@@ -5656,38 +4757,29 @@
       }
     }
   };
-
   TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
     var i;
     var len = newPaths.length;
-
     for (i = 0; i < len; i += 1) {
       localShapeCollection.addShape(newPaths[i]);
     }
   };
-
   TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
     shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
     shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
     }
-
     shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
     shapePath.setXYAt(points[1], points[5], 'o', pos);
     shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(points[0], points[4], 'v', pos);
     }
-
     shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
     var pathsData = shapeData.pathsData;
     var shapePaths = shapeData.shape.paths.shapes;
@@ -5703,7 +4795,6 @@
     var shapes = [];
     var initPos;
     var newShape = true;
-
     if (!shapePath) {
       shapePath = shapePool.newElement();
       segmentCount = 0;
@@ -5712,17 +4803,13 @@
       segmentCount = shapePath._length;
       initPos = shapePath._length;
     }
-
     shapes.push(shapePath);
-
     for (i = 0; i < len; i += 1) {
       lengths = pathsData[i].lengths;
       shapePath.c = shapePaths[i].c;
       jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
-
       for (j = 1; j < jLen; j += 1) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
           addedLength += currentLengthData.addedLength;
           shapePath.c = false;
@@ -5735,50 +4822,42 @@
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
-
           addedLength += currentLengthData.addedLength;
           segmentCount += 1;
         }
       }
-
       if (shapePaths[i].c && lengths.length) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength <= shapeSegment.e) {
           var segmentLength = lengths[j - 1].addedLength;
-
           if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
             this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
         } else {
           shapePath.c = false;
         }
-
         addedLength += currentLengthData.addedLength;
         segmentCount += 1;
       }
-
       if (shapePath._length) {
         shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
         shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
       }
-
       if (addedLength > shapeSegment.e) {
         break;
       }
-
       if (i < len - 1) {
         shapePath = shapePool.newElement();
         newShape = true;
@@ -5786,31 +4865,25 @@
         segmentCount = 0;
       }
     }
-
     return shapes;
   };
 
   function PuckerAndBloatModifier() {}
-
   extendPrototype([ShapeModifier], PuckerAndBloatModifier);
-
   PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
     this._isAnimated = !!this.amount.effectsSequence.length;
   };
-
   PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
     var percent = amount / 100;
     var centerPoint = [0, 0];
     var pathLength = path._length;
     var i = 0;
-
     for (i = 0; i < pathLength; i += 1) {
       centerPoint[0] += path.v[i][0];
       centerPoint[1] += path.v[i][1];
     }
-
     centerPoint[0] /= pathLength;
     centerPoint[1] /= pathLength;
     var clonedPath = shapePool.newElement();
@@ -5821,7 +4894,6 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < pathLength; i += 1) {
       vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
       vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
@@ -5831,10 +4903,8 @@
       iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
       clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
     }
-
     return clonedPath;
   };
-
   PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -5842,30 +4912,24 @@
     var j;
     var jLen;
     var amount = this.amount.v;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -5873,30 +4937,24 @@
 
   var TransformPropertyFactory = function () {
     var defaultVector = [0, 0];
-
     function applyToMatrix(mat) {
       var _mdf = this._mdf;
       this.iterateDynamicProperties();
       this._mdf = this._mdf || _mdf;
-
       if (this.a) {
         mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
       }
-
       if (this.s) {
         mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
       }
-
       if (this.sk) {
         mat.skewFromAxis(-this.sk.v, this.sa.v);
       }
-
       if (this.r) {
         mat.rotate(-this.r.v);
       } else {
         mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
       }
-
       if (this.data.p.s) {
         if (this.data.p.z) {
           mat.translate(this.px.v, this.py.v, -this.pz.v);
@@ -5907,46 +4965,36 @@
         mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
       }
     }
-
     function processKeys(forceRender) {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (this._isDirty) {
         this.precalculateMatrix();
         this._isDirty = false;
       }
-
       this.iterateDynamicProperties();
-
       if (this._mdf || forceRender) {
         var frameRate;
         this.v.cloneFromProps(this.pre.props);
-
         if (this.appliedTransformations < 1) {
           this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         }
-
         if (this.appliedTransformations < 2) {
           this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         }
-
         if (this.sk && this.appliedTransformations < 3) {
           this.v.skewFromAxis(-this.sk.v, this.sa.v);
         }
-
         if (this.r && this.appliedTransformations < 4) {
           this.v.rotate(-this.r.v);
         } else if (!this.r && this.appliedTransformations < 4) {
           this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
         }
-
         if (this.autoOriented) {
           var v1;
           var v2;
           frameRate = this.elem.globalData.frameRate;
-
           if (this.p && this.p.keyframes && this.p.getValueAtTime) {
             if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
               v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
@@ -5963,7 +5011,6 @@
             v2 = [];
             var px = this.px;
             var py = this.py;
-
             if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
               v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
               v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
@@ -5983,10 +5030,8 @@
             v2 = defaultVector;
             v1 = v2;
           }
-
           this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
         }
-
         if (this.data.p && this.data.p.s) {
           if (this.data.p.z) {
             this.v.translate(this.px.v, this.py.v, -this.pz.v);
@@ -5997,28 +5042,23 @@
           this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
         }
       }
-
       this.frameId = this.elem.globalData.frameId;
     }
-
     function precalculateMatrix() {
       this.appliedTransformations = 0;
       this.pre.reset();
-
       if (!this.a.effectsSequence.length) {
         this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         this.appliedTransformations = 1;
       } else {
         return;
       }
-
       if (!this.s.effectsSequence.length) {
         this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         this.appliedTransformations = 2;
       } else {
         return;
       }
-
       if (this.sk) {
         if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
           this.pre.skewFromAxis(-this.sk.v, this.sa.v);
@@ -6027,7 +5067,6 @@
           return;
         }
       }
-
       if (this.r) {
         if (!this.r.effectsSequence.length) {
           this.pre.rotate(-this.r.v);
@@ -6038,33 +5077,28 @@
         this.appliedTransformations = 4;
       }
     }
-
-    function autoOrient() {//
+    function autoOrient() {
+      //
       // var prevP = this.getValueAtTime();
     }
-
     function addDynamicProperty(prop) {
       this._addDynamicProperty(prop);
-
       this.elem.addDynamicProperty(prop);
       this._isDirty = true;
     }
-
     function TransformProperty(elem, data, container) {
       this.elem = elem;
       this.frameId = -1;
       this.propType = 'transform';
       this.data = data;
-      this.v = new Matrix(); // Precalculated matrix with non animated properties
-
+      this.v = new Matrix();
+      // Precalculated matrix with non animated properties
       this.pre = new Matrix();
       this.appliedTransformations = 0;
       this.initDynamicPropertyContainer(container || elem);
-
       if (data.p && data.p.s) {
         this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
         this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
-
         if (data.p.z) {
           this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
         }
@@ -6073,43 +5107,37 @@
           k: [0, 0, 0]
         }, 1, 0, this);
       }
-
       if (data.rx) {
         this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
         this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
         this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
-
         if (data.or.k[0].ti) {
           var i;
           var len = data.or.k.length;
-
           for (i = 0; i < len; i += 1) {
             data.or.k[i].to = null;
             data.or.k[i].ti = null;
           }
         }
-
-        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this); // sh Indicates it needs to be capped between -180 and 180
-
+        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+        // sh Indicates it needs to be capped between -180 and 180
         this.or.sh = true;
       } else {
         this.r = PropertyFactory.getProp(elem, data.r || {
           k: 0
         }, 0, degToRads, this);
       }
-
       if (data.sk) {
         this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
         this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
       }
-
       this.a = PropertyFactory.getProp(elem, data.a || {
         k: [0, 0, 0]
       }, 1, 0, this);
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: [100, 100, 100]
-      }, 1, 0.01, this); // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
-
+      }, 1, 0.01, this);
+      // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
       if (data.o) {
         this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
       } else {
@@ -6118,14 +5146,11 @@
           v: 1
         };
       }
-
       this._isDirty = true;
-
       if (!this.dynamicProperties.length) {
         this.getValue(true);
       }
     }
-
     TransformProperty.prototype = {
       applyToMatrix: applyToMatrix,
       getValue: processKeys,
@@ -6135,20 +5160,16 @@
     extendPrototype([DynamicPropertyContainer], TransformProperty);
     TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
     TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
-
     function getTransformProperty(elem, data, container) {
       return new TransformProperty(elem, data, container);
     }
-
     return {
       getTransformProperty: getTransformProperty
     };
   }();
 
   function RepeaterModifier() {}
-
   extendPrototype([ShapeModifier], RepeaterModifier);
-
   RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
@@ -6157,11 +5178,9 @@
     this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
     this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
     this.data = data;
-
     if (!this.dynamicProperties.length) {
       this.getValue(true);
     }
-
     this._isAnimated = !!this.dynamicProperties.length;
     this.pMatrix = new Matrix();
     this.rMatrix = new Matrix();
@@ -6169,7 +5188,6 @@
     this.tMatrix = new Matrix();
     this.matrix = new Matrix();
   };
-
   RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
     var dir = inv ? -1 : 1;
     var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
@@ -6182,7 +5200,6 @@
     sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
     sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
   };
-
   RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
     this.elem = elem;
     this.arr = arr;
@@ -6194,52 +5211,42 @@
     this.frameId = -1;
     this.initDynamicPropertyContainer(elem);
     this.initModifierProperties(elem, arr[pos]);
-
     while (pos > 0) {
-      pos -= 1; // this._elements.unshift(arr.splice(pos,1)[0]);
-
+      pos -= 1;
+      // this._elements.unshift(arr.splice(pos,1)[0]);
       this._elements.unshift(arr[pos]);
     }
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   RepeaterModifier.prototype.resetElements = function (elements) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._processed = false;
-
       if (elements[i].ty === 'gr') {
         this.resetElements(elements[i].it);
       }
     }
   };
-
   RepeaterModifier.prototype.cloneElements = function (elements) {
     var newElements = JSON.parse(JSON.stringify(elements));
     this.resetElements(newElements);
     return newElements;
   };
-
   RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._render = renderFlag;
-
       if (elements[i].ty === 'gr') {
         this.changeGroupRender(elements[i].it, renderFlag);
       }
     }
   };
-
   RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
     var items;
     var itemsTransform;
@@ -6247,10 +5254,8 @@
     var dir;
     var cont;
     var hasReloaded = false;
-
     if (this._mdf || _isFirstFrame) {
       var copies = Math.ceil(this.c.v);
-
       if (this._groups.length < copies) {
         while (this._groups.length < copies) {
           var group = {
@@ -6305,28 +5310,21 @@
             ty: 'tr'
           });
           this.arr.splice(0, 0, group);
-
           this._groups.splice(0, 0, group);
-
           this._currentCopies += 1;
         }
-
         this.elem.reloadShapes();
         hasReloaded = true;
       }
-
       cont = 0;
       var renderFlag;
-
       for (i = 0; i <= this._groups.length - 1; i += 1) {
         renderFlag = cont < copies;
         this._groups[i]._render = renderFlag;
         this.changeGroupRender(this._groups[i].it, renderFlag);
-
         if (!renderFlag) {
           var elems = this.elemsData[i].it;
           var transformData = elems[elems.length - 1];
-
           if (transformData.transform.op.v !== 0) {
             transformData.transform.op._mdf = true;
             transformData.transform.op.v = 0;
@@ -6334,11 +5332,10 @@
             transformData.transform.op._mdf = false;
           }
         }
-
         cont += 1;
       }
-
-      this._currentCopies = copies; /// /
+      this._currentCopies = copies;
+      /// /
 
       var offset = this.o.v;
       var offsetModulo = offset % 1;
@@ -6352,13 +5349,11 @@
       this.tMatrix.reset();
       this.matrix.reset();
       var iteration = 0;
-
       if (offset > 0) {
         while (iteration < roundOffset) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           iteration += 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
           iteration += offsetModulo;
@@ -6368,19 +5363,16 @@
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
           iteration -= 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
           iteration -= offsetModulo;
         }
       }
-
       i = this.data.m === 1 ? 0 : this._currentCopies - 1;
       dir = this.data.m === 1 ? 1 : -1;
       cont = this._currentCopies;
       var j;
       var jLen;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6388,29 +5380,23 @@
         items[items.length - 1].transform.mProps._mdf = true;
         items[items.length - 1].transform.op._mdf = true;
         items[items.length - 1].transform.op.v = this._currentCopies === 1 ? this.so.v : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
-
         if (iteration !== 0) {
           if (i !== 0 && dir === 1 || i !== this._currentCopies - 1 && dir === -1) {
             this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           }
-
           this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
           this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
           this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
-
           this.matrix.reset();
         } else {
           this.matrix.reset();
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
         }
-
         iteration += 1;
         cont -= 1;
         i += dir;
@@ -6419,7 +5405,6 @@
       cont = this._currentCopies;
       i = 0;
       dir = 1;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6429,22 +5414,17 @@
         i += dir;
       }
     }
-
     return hasReloaded;
   };
-
   RepeaterModifier.prototype.addShape = function () {};
 
   function RoundCornersModifier() {}
-
   extendPrototype([ShapeModifier], RoundCornersModifier);
-
   RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
     this._isAnimated = !!this.rd.effectsSequence.length;
   };
-
   RoundCornersModifier.prototype.processPath = function (path, round) {
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
@@ -6463,19 +5443,16 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < len; i += 1) {
       currentV = path.v[i];
       currentO = path.o[i];
       currentI = path.i[i];
-
       if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
         if ((i === 0 || i === len - 1) && !path.c) {
           clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
           /* clonedPath.v[index] = currentV;
                   clonedPath.o[index] = currentO;
                   clonedPath.i[index] = currentI; */
-
           index += 1;
         } else {
           if (i === 0) {
@@ -6483,7 +5460,6 @@
           } else {
             closerV = path.v[i - 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6494,13 +5470,11 @@
           oY = vY - (vY - currentV[1]) * roundCorner;
           clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
           index += 1;
-
           if (i === len - 1) {
             closerV = path.v[0];
           } else {
             closerV = path.v[i + 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6517,10 +5491,8 @@
         index += 1;
       }
     }
-
     return clonedPath;
   };
-
   RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6528,30 +5500,24 @@
     var j;
     var jLen;
     var rd = this.rd.v;
-
     if (rd !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6560,50 +5526,41 @@
   function floatEqual(a, b) {
     return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
   }
-
   function floatZero(f) {
     return Math.abs(f) <= 0.00001;
   }
-
   function lerp(p0, p1, amount) {
     return p0 * (1 - amount) + p1 * amount;
   }
-
   function lerpPoint(p0, p1, amount) {
     return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
   }
-
   function quadRoots(a, b, c) {
     // no root
     if (a === 0) return [];
-    var s = b * b - 4 * a * c; // Complex roots
-
+    var s = b * b - 4 * a * c;
+    // Complex roots
     if (s < 0) return [];
-    var singleRoot = -b / (2 * a); // 1 root
-
+    var singleRoot = -b / (2 * a);
+    // 1 root
     if (s === 0) return [singleRoot];
-    var delta = Math.sqrt(s) / (2 * a); // 2 roots
-
+    var delta = Math.sqrt(s) / (2 * a);
+    // 2 roots
     return [singleRoot - delta, singleRoot + delta];
   }
-
   function polynomialCoefficients(p0, p1, p2, p3) {
     return [-p0 + 3 * p1 - 3 * p2 + p3, 3 * p0 - 6 * p1 + 3 * p2, -3 * p0 + 3 * p1, p0];
   }
-
   function singlePoint(p) {
     return new PolynomialBezier(p, p, p, p, false);
   }
-
   function PolynomialBezier(p0, p1, p2, p3, linearize) {
     if (linearize && pointEqual(p0, p1)) {
       p1 = lerpPoint(p0, p3, 1 / 3);
     }
-
     if (linearize && pointEqual(p2, p3)) {
       p2 = lerpPoint(p0, p3, 2 / 3);
     }
-
     var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
     var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
     this.a = [coeffx[0], coeffy[0]];
@@ -6612,25 +5569,20 @@
     this.d = [coeffx[3], coeffy[3]];
     this.points = [p0, p1, p2, p3];
   }
-
   PolynomialBezier.prototype.point = function (t) {
     return [((this.a[0] * t + this.b[0]) * t + this.c[0]) * t + this.d[0], ((this.a[1] * t + this.b[1]) * t + this.c[1]) * t + this.d[1]];
   };
-
   PolynomialBezier.prototype.derivative = function (t) {
     return [(3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0], (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1]];
   };
-
   PolynomialBezier.prototype.tangentAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[1], p[0]);
   };
-
   PolynomialBezier.prototype.normalAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[0], p[1]);
   };
-
   PolynomialBezier.prototype.inflectionPoints = function () {
     var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
     if (floatZero(denom)) return [];
@@ -6638,17 +5590,14 @@
     var square = tcusp * tcusp - 1 / 3 * (this.b[1] * this.c[0] - this.b[0] * this.c[1]) / denom;
     if (square < 0) return [];
     var root = Math.sqrt(square);
-
     if (floatZero(root)) {
       if (root > 0 && root < 1) return [tcusp];
       return [];
     }
-
     return [tcusp - root, tcusp + root].filter(function (r) {
       return r > 0 && r < 1;
     });
   };
-
   PolynomialBezier.prototype.split = function (t) {
     if (t <= 0) return [singlePoint(this.points[0]), this];
     if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
@@ -6660,40 +5609,33 @@
     var p3 = lerpPoint(p20, p21, t);
     return [new PolynomialBezier(this.points[0], p10, p20, p3, true), new PolynomialBezier(p3, p21, p12, this.points[3], true)];
   };
-
   function extrema(bez, comp) {
     var min = bez.points[0][comp];
     var max = bez.points[bez.points.length - 1][comp];
-
     if (min > max) {
       var e = max;
       max = min;
       min = e;
-    } // Derivative roots to find min/max
-
-
+    }
+    // Derivative roots to find min/max
     var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
-
     for (var i = 0; i < f.length; i += 1) {
       if (f[i] > 0 && f[i] < 1) {
         var val = bez.point(f[i])[comp];
         if (val < min) min = val;else if (val > max) max = val;
       }
     }
-
     return {
       min: min,
       max: max
     };
   }
-
   PolynomialBezier.prototype.bounds = function () {
     return {
       x: extrema(this, 0),
       y: extrema(this, 1)
     };
   };
-
   PolynomialBezier.prototype.boundingBox = function () {
     var bounds = this.bounds();
     return {
@@ -6707,7 +5649,6 @@
       cy: (bounds.y.max + bounds.y.min) / 2
     };
   };
-
   function intersectData(bez, t1, t2) {
     var box = bez.boundingBox();
     return {
@@ -6721,24 +5662,19 @@
       t2: t2
     };
   }
-
   function splitData(data) {
     var split = data.bez.split(0.5);
     return [intersectData(split[0], data.t1, data.t), intersectData(split[1], data.t, data.t2)];
   }
-
   function boxIntersect(b1, b2) {
     return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
   }
-
   function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
     if (!boxIntersect(d1, d2)) return;
-
     if (depth >= maxRecursion || d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance) {
       intersections.push([d1.t, d2.t]);
       return;
     }
-
     var d1s = splitData(d1);
     var d2s = splitData(d2);
     intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
@@ -6746,7 +5682,6 @@
     intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
     intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
   }
-
   PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
     if (tolerance === undefined) tolerance = 2;
     if (maxRecursion === undefined) maxRecursion = 7;
@@ -6754,21 +5689,17 @@
     intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
     return intersections;
   };
-
   PolynomialBezier.shapeSegment = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
   };
-
   PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
   };
-
   function crossProduct(a, b) {
     return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
   }
-
   function lineIntersection(start1, end1, start2, end2) {
     var v1 = [start1[0], start1[1], 1];
     var v2 = [end1[0], end1[1], 1];
@@ -6778,23 +5709,18 @@
     if (floatZero(r[2])) return null;
     return [r[0] / r[2], r[1] / r[2]];
   }
-
   function polarOffset(p, angle, length) {
     return [p[0] + Math.cos(angle) * length, p[1] - Math.sin(angle) * length];
   }
-
   function pointDistance(p1, p2) {
     return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
   }
-
   function pointEqual(p1, p2) {
     return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
   }
 
   function ZigZagModifier() {}
-
   extendPrototype([ShapeModifier], ZigZagModifier);
-
   ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
@@ -6802,7 +5728,6 @@
     this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
     this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
   };
-
   function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
     var angO = angle - Math.PI / 2;
     var angI = angle + Math.PI / 2;
@@ -6810,14 +5735,12 @@
     var py = point[1] - Math.sin(angle) * direction * amplitude;
     outputBezier.setTripleAt(px, py, px + Math.cos(angO) * outAmplitude, py - Math.sin(angO) * outAmplitude, px + Math.cos(angI) * inAmplitude, py - Math.sin(angI) * inAmplitude, outputBezier.length());
   }
-
   function getPerpendicularVector(pt1, pt2) {
     var vector = [pt2[0] - pt1[0], pt2[1] - pt1[1]];
     var rot = -Math.PI * 0.5;
     var rotatedVector = [Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1], Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1]];
     return rotatedVector;
   }
-
   function getProjectingAngle(path, cur) {
     var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
     var nextIndex = (cur + 1) % path.length();
@@ -6826,7 +5749,6 @@
     var pVector = getPerpendicularVector(prevPoint, nextPoint);
     return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
   }
-
   function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
     var angle = getProjectingAngle(path, cur);
     var point = path.v[cur % path._length];
@@ -6836,7 +5758,6 @@
     var nextDist = pointType === 2 ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2)) : 0;
     setPoint(outputBezier, path.v[cur % path._length], angle, direction, amplitude, nextDist / ((frequency + 1) * 2), prevDist / ((frequency + 1) * 2), pointType);
   }
-
   function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
     for (var i = 0; i < frequency; i += 1) {
       var t = (i + 1) / (frequency + 1);
@@ -6846,39 +5767,30 @@
       setPoint(outputBezier, point, angle, direction, amplitude, dist / ((frequency + 1) * 2), dist / ((frequency + 1) * 2), pointType);
       direction = -direction;
     }
-
     return direction;
   }
-
   ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
     var count = path._length;
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
-
     if (!path.c) {
       count -= 1;
     }
-
     if (count === 0) return clonedPath;
     var direction = -1;
     var segment = PolynomialBezier.shapeSegment(path, 0);
     zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
-
     for (var i = 0; i < count; i += 1) {
       direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
-
       if (i === count - 1 && !path.c) {
         segment = null;
       } else {
         segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
       }
-
       zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
     }
-
     return clonedPath;
   };
-
   ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6888,30 +5800,24 @@
     var amplitude = this.amplitude.v;
     var frequency = Math.max(0, Math.round(this.frequency.v));
     var pointType = this.pointsType.v;
-
     if (amplitude !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6921,7 +5827,6 @@
     var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
     return [polarOffset(p1, angle, amount), polarOffset(p2, angle, amount)];
   }
-
   function offsetSegment(segment, amount) {
     var p0;
     var p1a;
@@ -6945,15 +5850,17 @@
     if (p2 === null) p2 = p2a;
     return new PolynomialBezier(p0, p1, p2, p3);
   }
-
   function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
     var p0 = seg1.points[3];
-    var p1 = seg2.points[0]; // Bevel
+    var p1 = seg2.points[0];
 
-    if (lineJoin === 3) return p0; // Connected, they don't need a joint
+    // Bevel
+    if (lineJoin === 3) return p0;
 
-    if (pointEqual(p0, p1)) return p0; // Round
+    // Connected, they don't need a joint
+    if (pointEqual(p0, p1)) return p0;
 
+    // Round
     if (lineJoin === 2) {
       var angleOut = -seg1.tangentAngle(1);
       var angleIn = -seg2.tangentAngle(0) + Math.PI;
@@ -6964,91 +5871,75 @@
       tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
       outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
       return p1;
-    } // Miter
+    }
 
-
+    // Miter
     var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
     var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
     var intersection = lineIntersection(t0, p0, p1, t1);
-
     if (intersection && pointDistance(intersection, p0) < miterLimit) {
       outputBezier.setTripleAt(intersection[0], intersection[1], intersection[0], intersection[1], intersection[0], intersection[1], outputBezier.length());
       return intersection;
     }
-
     return p0;
   }
-
   function getIntersection(a, b) {
     var intersect = a.intersections(b);
     if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
     if (intersect.length) return intersect[0];
     return null;
   }
-
   function pruneSegmentIntersection(a, b) {
     var outa = a.slice();
     var outb = b.slice();
     var intersect = getIntersection(a[a.length - 1], b[0]);
-
     if (intersect) {
       outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
       outb[0] = b[0].split(intersect[1])[1];
     }
-
     if (a.length > 1 && b.length > 1) {
       intersect = getIntersection(a[0], b[b.length - 1]);
-
       if (intersect) {
         return [[a[0].split(intersect[0])[0]], [b[b.length - 1].split(intersect[1])[1]]];
       }
     }
-
     return [outa, outb];
   }
-
   function pruneIntersections(segments) {
     var e;
-
     for (var i = 1; i < segments.length; i += 1) {
       e = pruneSegmentIntersection(segments[i - 1], segments[i]);
       segments[i - 1] = e[0];
       segments[i] = e[1];
     }
-
     if (segments.length > 1) {
       e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
       segments[segments.length - 1] = e[0];
       segments[0] = e[1];
     }
-
     return segments;
   }
-
   function offsetSegmentSplit(segment, amount) {
     /*
       We split each bezier segment into smaller pieces based
       on inflection points, this ensures the control point
       polygon is convex.
-        (A cubic bezier can have none, one, or two inflection points)
+       (A cubic bezier can have none, one, or two inflection points)
     */
     var flex = segment.inflectionPoints();
     var left;
     var right;
     var split;
     var mid;
-
     if (flex.length === 0) {
       return [offsetSegment(segment, amount)];
     }
-
     if (flex.length === 1 || floatEqual(flex[1], 1)) {
       split = segment.split(flex[0]);
       left = split[0];
       right = split[1];
       return [offsetSegment(left, amount), offsetSegment(right, amount)];
     }
-
     split = segment.split(flex[0]);
     left = split[0];
     var t = (flex[1] - flex[0]) / (1 - flex[0]);
@@ -7057,11 +5948,8 @@
     right = split[1];
     return [offsetSegment(left, amount), offsetSegment(mid, amount), offsetSegment(right, amount)];
   }
-
   function OffsetPathModifier() {}
-
   extendPrototype([ShapeModifier], OffsetPathModifier);
-
   OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
@@ -7069,61 +5957,50 @@
     this.lineJoin = data.lj;
     this._isAnimated = this.amount.effectsSequence.length !== 0;
   };
-
   OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
     var outputBezier = shapePool.newElement();
     outputBezier.c = inputBezier.c;
     var count = inputBezier.length();
-
     if (!inputBezier.c) {
       count -= 1;
     }
-
     var i;
     var j;
     var segment;
     var multiSegments = [];
-
     for (i = 0; i < count; i += 1) {
       segment = PolynomialBezier.shapeSegment(inputBezier, i);
       multiSegments.push(offsetSegmentSplit(segment, amount));
     }
-
     if (!inputBezier.c) {
       for (i = count - 1; i >= 0; i -= 1) {
         segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
         multiSegments.push(offsetSegmentSplit(segment, amount));
       }
     }
+    multiSegments = pruneIntersections(multiSegments);
 
-    multiSegments = pruneIntersections(multiSegments); // Add bezier segments to the output and apply line joints
-
+    // Add bezier segments to the output and apply line joints
     var lastPoint = null;
     var lastSeg = null;
-
     for (i = 0; i < multiSegments.length; i += 1) {
       var multiSegment = multiSegments[i];
       if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
       lastSeg = multiSegment[multiSegment.length - 1];
-
       for (j = 0; j < multiSegment.length; j += 1) {
         segment = multiSegment[j];
-
         if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
           outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
         } else {
           outputBezier.setTripleAt(segment.points[0][0], segment.points[0][1], segment.points[1][0], segment.points[1][1], segment.points[0][0], segment.points[0][1], outputBezier.length());
         }
-
         outputBezier.setTripleAt(segment.points[3][0], segment.points[3][1], segment.points[3][0], segment.points[3][1], segment.points[2][0], segment.points[2][1], outputBezier.length());
         lastPoint = segment.points[3];
       }
     }
-
     if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
     return outputBezier;
   };
-
   OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -7133,30 +6010,24 @@
     var amount = this.amount.v;
     var miterLimit = this.miterLimit.v;
     var lineJoin = this.lineJoin;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -7168,42 +6039,33 @@
     var fStyle = 'normal';
     var len = styles.length;
     var styleName;
-
     for (var i = 0; i < len; i += 1) {
       styleName = styles[i].toLowerCase();
-
       switch (styleName) {
         case 'italic':
           fStyle = 'italic';
           break;
-
         case 'bold':
           fWeight = '700';
           break;
-
         case 'black':
           fWeight = '900';
           break;
-
         case 'medium':
           fWeight = '500';
           break;
-
         case 'regular':
         case 'normal':
           fWeight = '400';
           break;
-
         case 'light':
         case 'thin':
           fWeight = '200';
           break;
-
         default:
           break;
       }
     }
-
     return {
       style: fStyle,
       weight: fontData.fWeight || fWeight
@@ -7220,8 +6082,8 @@
         shapes: []
       }
     };
-    var combinedCharacters = []; // Hindi characters
-
+    var combinedCharacters = [];
+    // Hindi characters
     combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
     var BLACK_FLAG_CODE_POINT = 127988;
     var CANCEL_TAG_CODE_POINT = 917631;
@@ -7232,44 +6094,41 @@
     var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
     var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
     var surrogateModifiers = ['d83cdffb', 'd83cdffc', 'd83cdffd', 'd83cdffe', 'd83cdfff'];
-
     function trimFontOptions(font) {
       var familyArray = font.split(',');
       var i;
       var len = familyArray.length;
       var enabledFamilies = [];
-
       for (i = 0; i < len; i += 1) {
         if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
           enabledFamilies.push(familyArray[i]);
         }
       }
-
       return enabledFamilies.join(',');
     }
-
     function setUpNode(font, family) {
-      var parentNode = createTag('span'); // Node is invisible to screen readers.
-
+      var parentNode = createTag('span');
+      // Node is invisible to screen readers.
       parentNode.setAttribute('aria-hidden', true);
       parentNode.style.fontFamily = family;
-      var node = createTag('span'); // Characters that vary significantly among different fonts
-
-      node.innerText = 'giItT1WQy@!-/#'; // Visible - so we can measure it - but not on the screen
-
+      var node = createTag('span');
+      // Characters that vary significantly among different fonts
+      node.innerText = 'giItT1WQy@!-/#';
+      // Visible - so we can measure it - but not on the screen
       parentNode.style.position = 'absolute';
       parentNode.style.left = '-10000px';
-      parentNode.style.top = '-10000px'; // Large font size makes even subtle changes obvious
-
-      parentNode.style.fontSize = '300px'; // Reset any font properties
-
+      parentNode.style.top = '-10000px';
+      // Large font size makes even subtle changes obvious
+      parentNode.style.fontSize = '300px';
+      // Reset any font properties
       parentNode.style.fontVariant = 'normal';
       parentNode.style.fontStyle = 'normal';
       parentNode.style.fontWeight = 'normal';
       parentNode.style.letterSpacing = '0';
       parentNode.appendChild(node);
-      document.body.appendChild(parentNode); // Remember width with no applied web font
+      document.body.appendChild(parentNode);
 
+      // Remember width with no applied web font
       var width = node.offsetWidth;
       node.style.fontFamily = trimFontOptions(font) + ', ' + family;
       return {
@@ -7278,14 +6137,12 @@
         parent: parentNode
       };
     }
-
     function checkLoadedFonts() {
       var i;
       var len = this.fonts.length;
       var node;
       var w;
       var loadedCount = len;
-
       for (i = 0; i < len; i += 1) {
         if (this.fonts[i].loaded) {
           loadedCount -= 1;
@@ -7294,55 +6151,47 @@
         } else {
           node = this.fonts[i].monoCase.node;
           w = this.fonts[i].monoCase.w;
-
           if (node.offsetWidth !== w) {
             loadedCount -= 1;
             this.fonts[i].loaded = true;
           } else {
             node = this.fonts[i].sansCase.node;
             w = this.fonts[i].sansCase.w;
-
             if (node.offsetWidth !== w) {
               loadedCount -= 1;
               this.fonts[i].loaded = true;
             }
           }
-
           if (this.fonts[i].loaded) {
             this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
             this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
           }
         }
       }
-
       if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
         setTimeout(this.checkLoadedFontsBinded, 20);
       } else {
         setTimeout(this.setIsLoadedBinded, 10);
       }
     }
-
     function createHelper(fontData, def) {
       var engine = document.body && def ? 'svg' : 'canvas';
       var helper;
       var fontProps = getFontProperties(fontData);
-
       if (engine === 'svg') {
         var tHelper = createNS('text');
-        tHelper.style.fontSize = '100px'; // tHelper.style.fontFamily = fontData.fFamily;
-
+        tHelper.style.fontSize = '100px';
+        // tHelper.style.fontFamily = fontData.fFamily;
         tHelper.setAttribute('font-family', fontData.fFamily);
         tHelper.setAttribute('font-style', fontProps.style);
         tHelper.setAttribute('font-weight', fontProps.weight);
         tHelper.textContent = '1';
-
         if (fontData.fClass) {
           tHelper.style.fontFamily = 'inherit';
           tHelper.setAttribute('class', fontData.fClass);
         } else {
           tHelper.style.fontFamily = fontData.fFamily;
         }
-
         def.appendChild(tHelper);
         helper = tHelper;
       } else {
@@ -7350,33 +6199,27 @@
         tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
         helper = tCanvasHelper;
       }
-
       function measure(text) {
         if (engine === 'svg') {
           helper.textContent = text;
           return helper.getComputedTextLength();
         }
-
         return helper.measureText(text).width;
       }
-
       return {
         measureText: measure
       };
     }
-
     function addFonts(fontData, defs) {
       if (!fontData) {
         this.isLoaded = true;
         return;
       }
-
       if (this.chars) {
         this.isLoaded = true;
         this.fonts = fontData.list;
         return;
       }
-
       if (!document.body) {
         this.isLoaded = true;
         fontData.list.forEach(function (data) {
@@ -7386,12 +6229,10 @@
         this.fonts = fontData.list;
         return;
       }
-
       var fontArr = fontData.list;
       var i;
       var len = fontArr.length;
       var _pendingFonts = len;
-
       for (i = 0; i < len; i += 1) {
         var shouldLoadFont = true;
         var loadedSelector;
@@ -7399,17 +6240,14 @@
         fontArr[i].loaded = false;
         fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
         fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
-
         if (!fontArr[i].fPath) {
           fontArr[i].loaded = true;
           _pendingFonts -= 1;
         } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
           loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
-
           if (loadedSelector.length > 0) {
             shouldLoadFont = false;
           }
-
           if (shouldLoadFont) {
             var s = createTag('style');
             s.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7421,14 +6259,12 @@
           }
         } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
           loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var l = createTag('link');
             l.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7440,14 +6276,12 @@
           }
         } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
           loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (fontArr[i].fPath === loadedSelector[j].src) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var sc = createTag('link');
             sc.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7457,12 +6291,10 @@
             defs.appendChild(sc);
           }
         }
-
         fontArr[i].helper = createHelper(fontArr[i], defs);
         fontArr[i].cache = {};
         this.fonts.push(fontArr[i]);
       }
-
       if (_pendingFonts === 0) {
         this.isLoaded = true;
       } else {
@@ -7471,71 +6303,56 @@
         setTimeout(this.checkLoadedFonts.bind(this), 100);
       }
     }
-
     function addChars(chars) {
       if (!chars) {
         return;
       }
-
       if (!this.chars) {
         this.chars = [];
       }
-
       var i;
       var len = chars.length;
       var j;
       var jLen = this.chars.length;
       var found;
-
       for (i = 0; i < len; i += 1) {
         j = 0;
         found = false;
-
         while (j < jLen) {
           if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
             found = true;
           }
-
           j += 1;
         }
-
         if (!found) {
           this.chars.push(chars[i]);
           jLen += 1;
         }
       }
     }
-
     function getCharData(_char, style, font) {
       var i = 0;
       var len = this.chars.length;
-
       while (i < len) {
         if (this.chars[i].ch === _char && this.chars[i].style === style && this.chars[i].fFamily === font) {
           return this.chars[i];
         }
-
         i += 1;
       }
-
       if ((typeof _char === 'string' && _char.charCodeAt(0) !== 13 || !_char) && console && console.warn // eslint-disable-line no-console
       && !this._warned) {
         this._warned = true;
         console.warn('Missing character from exported characters list: ', _char, style, font); // eslint-disable-line no-console
       }
-
       return emptyChar;
     }
-
     function measureText(_char2, fontName, size) {
-      var fontData = this.getFontByName(fontName); // Using the char instead of char.charCodeAt(0)
+      var fontData = this.getFontByName(fontName);
+      // Using the char instead of char.charCodeAt(0)
       // to avoid collisions between equal chars
-
       var index = _char2;
-
       if (!fontData.cache[index]) {
         var tHelper = fontData.helper;
-
         if (_char2 === ' ') {
           var doubleSize = tHelper.measureText('|' + _char2 + '|');
           var singleSize = tHelper.measureText('||');
@@ -7544,111 +6361,90 @@
           fontData.cache[index] = tHelper.measureText(_char2) / 100;
         }
       }
-
       return fontData.cache[index] * size;
     }
-
     function getFontByName(name) {
       var i = 0;
       var len = this.fonts.length;
-
       while (i < len) {
         if (this.fonts[i].fName === name) {
           return this.fonts[i];
         }
-
         i += 1;
       }
-
       return this.fonts[0];
     }
-
     function getCodePoint(string) {
       var codePoint = 0;
       var first = string.charCodeAt(0);
-
       if (first >= 0xD800 && first <= 0xDBFF) {
         var second = string.charCodeAt(1);
-
         if (second >= 0xDC00 && second <= 0xDFFF) {
           codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
         }
       }
-
       return codePoint;
-    } // Skin tone modifiers
+    }
 
-
+    // Skin tone modifiers
     function isModifier(firstCharCode, secondCharCode) {
       var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
       return surrogateModifiers.indexOf(sum) !== -1;
     }
-
     function isZeroWidthJoiner(charCode) {
       return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
-    } // This codepoint may change the appearance of the preceding character.
+    }
+
+    // This codepoint may change the appearance of the preceding character.
     // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
     // as a colorful image as compared to a monochrome text variant.
-
-
     function isVariationSelector(charCode) {
       return charCode === VARIATION_SELECTOR_16_CODE_POINT;
-    } // The regional indicator symbols are a set of 26 alphabetic Unicode
+    }
+
+    // The regional indicator symbols are a set of 26 alphabetic Unicode
     /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
     // two-letter country codes in a way that allows optional special treatment.
-
-
     function isRegionalCode(string) {
       var codePoint = getCodePoint(string);
-
       if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
         return true;
       }
-
       return false;
-    } // Some Emoji implementations represent combinations of
+    }
+
+    // Some Emoji implementations represent combinations of
     // two “regional indicator” letters as a single flag symbol.
-
-
     function isFlagEmoji(string) {
       return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
     }
-
     function isCombinedCharacter(_char3) {
       return combinedCharacters.indexOf(_char3) !== -1;
-    } // Regional flags start with a BLACK_FLAG_CODE_POINT
+    }
+
+    // Regional flags start with a BLACK_FLAG_CODE_POINT
     // folowed by 5 chars in the TAG range
     // and end with a CANCEL_TAG_CODE_POINT
-
-
     function isRegionalFlag(text, index) {
       var codePoint = getCodePoint(text.substr(index, 2));
-
       if (codePoint !== BLACK_FLAG_CODE_POINT) {
         return false;
       }
-
       var count = 0;
       index += 2;
-
       while (count < 5) {
         codePoint = getCodePoint(text.substr(index, 2));
-
         if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
           return false;
         }
-
         count += 1;
         index += 2;
       }
-
       return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
     }
-
     function setIsLoaded() {
       this.isLoaded = true;
     }
-
     var Font = function Font() {
       this.fonts = [];
       this.chars = null;
@@ -7659,7 +6455,6 @@
       this.setIsLoadedBinded = this.setIsLoaded.bind(this);
       this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
     };
-
     Font.isModifier = isModifier;
     Font.isZeroWidthJoiner = isZeroWidthJoiner;
     Font.isFlagEmoji = isFlagEmoji;
@@ -7684,30 +6479,26 @@
   function SlotManager(animationData) {
     this.animationData = animationData;
   }
-
   SlotManager.prototype.getProp = function (data) {
     if (this.animationData.slots && this.animationData.slots[data.sid]) {
       return Object.assign(data, this.animationData.slots[data.sid].p);
     }
-
     return data;
   };
-
   function slotFactory(animationData) {
     return new SlotManager(animationData);
   }
 
   function RenderableElement() {}
-
   RenderableElement.prototype = {
     initRenderable: function initRenderable() {
       // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
-      this.isInRange = false; // layer's display state
-
-      this.hidden = false; // If layer's transparency equals 0, it can be hidden
-
-      this.isTransparent = false; // list of animated components
-
+      this.isInRange = false;
+      // layer's display state
+      this.hidden = false;
+      // If layer's transparency equals 0, it can be hidden
+      this.isTransparent = false;
+      // list of animated components
       this.renderableComponents = [];
     },
     addRenderableComponent: function addRenderableComponent(component) {
@@ -7734,7 +6525,6 @@
         this.show();
       }
     },
-
     /**
        * @function
        * Initializes frame related properties.
@@ -7760,13 +6550,11 @@
     renderRenderable: function renderRenderable() {
       var i;
       var len = this.renderableComponents.length;
-
       for (i = 0; i < len; i += 1) {
         this.renderableComponents[i].renderFrame(this._isFirstFrame);
       }
       /* this.maskManager.renderFrame(this.finalTransform.mat);
           this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
-
     },
     sourceRectAtTime: function sourceRectAtTime() {
       return {
@@ -7783,7 +6571,6 @@
           h: this.data.textData.height
         };
       }
-
       return {
         w: this.data.width,
         h: this.data.height
@@ -7818,31 +6605,24 @@
   function SliderEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function AngleEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function ColorEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function PointEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function LayerIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function MaskIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function CheckboxEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function NoValueEffect() {
     this.p = {};
   }
@@ -7853,20 +6633,16 @@
     var i;
     var len = effects.length;
     var effectItem;
-
     for (i = 0; i < len; i += 1) {
       effectItem = new GroupEffect(effects[i], element);
       this.effectElements.push(effectItem);
     }
   }
-
   function GroupEffect(data, element) {
     this.init(data, element);
   }
-
   extendPrototype([DynamicPropertyContainer], GroupEffect);
   GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
-
   GroupEffect.prototype.init = function (data, element) {
     this.data = data;
     this.effectElements = [];
@@ -7875,50 +6651,39 @@
     var len = this.data.ef.length;
     var eff;
     var effects = this.data.ef;
-
     for (i = 0; i < len; i += 1) {
       eff = null;
-
       switch (effects[i].ty) {
         case 0:
           eff = new SliderEffect(effects[i], element, this);
           break;
-
         case 1:
           eff = new AngleEffect(effects[i], element, this);
           break;
-
         case 2:
           eff = new ColorEffect(effects[i], element, this);
           break;
-
         case 3:
           eff = new PointEffect(effects[i], element, this);
           break;
-
         case 4:
         case 7:
           eff = new CheckboxEffect(effects[i], element, this);
           break;
-
         case 10:
           eff = new LayerIndexEffect(effects[i], element, this);
           break;
-
         case 11:
           eff = new MaskIndexEffect(effects[i], element, this);
           break;
-
         case 5:
           eff = new EffectsManager(effects[i], element, this);
           break;
         // case 6:
-
         default:
           eff = new NoValueEffect(effects[i], element, this);
           break;
       }
-
       if (eff) {
         this.effectElements.push(eff);
       }
@@ -7926,47 +6691,37 @@
   };
 
   function BaseElement() {}
-
   BaseElement.prototype = {
     checkMasks: function checkMasks() {
       if (!this.data.hasMask) {
         return false;
       }
-
       var i = 0;
       var len = this.data.masksProperties.length;
-
       while (i < len) {
         if (this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false) {
           return true;
         }
-
         i += 1;
       }
-
       return false;
     },
     initExpressions: function initExpressions() {
       var expressionsInterfaces = getExpressionInterfaces();
-
       if (!expressionsInterfaces) {
         return;
       }
-
       var LayerExpressionInterface = expressionsInterfaces('layer');
       var EffectsExpressionInterface = expressionsInterfaces('effects');
       var ShapeExpressionInterface = expressionsInterfaces('shape');
       var TextExpressionInterface = expressionsInterfaces('text');
       var CompExpressionInterface = expressionsInterfaces('comp');
       this.layerInterface = LayerExpressionInterface(this);
-
       if (this.data.hasMask && this.maskManager) {
         this.layerInterface.registerMaskInterface(this.maskManager);
       }
-
       var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
       this.layerInterface.registerEffectsInterface(effectsInterface);
-
       if (this.data.ty === 0 || this.data.xt) {
         this.compInterface = CompExpressionInterface(this);
       } else if (this.data.ty === 4) {
@@ -7986,13 +6741,13 @@
       this.globalData = globalData;
       this.comp = comp;
       this.data = data;
-      this.layerId = createElementID(); // Stretch factor for old animations missing this property.
+      this.layerId = createElementID();
 
+      // Stretch factor for old animations missing this property.
       if (!this.data.sr) {
         this.data.sr = 1;
-      } // effects manager
-
-
+      }
+      // effects manager
       this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
     },
     getType: function getType() {
@@ -8007,8 +6762,8 @@
    * Checks layer in point and out point
    *
    */
-  function FrameElement() {}
 
+  function FrameElement() {}
   FrameElement.prototype = {
     /**
        * @function
@@ -8017,13 +6772,12 @@
        */
     initFrame: function initFrame() {
       // set to true when inpoint is rendered
-      this._isFirstFrame = false; // list of animated properties
-
-      this.dynamicProperties = []; // If layer has been modified in current tick this will be true
-
+      this._isFirstFrame = false;
+      // list of animated properties
+      this.dynamicProperties = [];
+      // If layer has been modified in current tick this will be true
       this._mdf = false;
     },
-
     /**
        * @function
        * Calculates all dynamic values
@@ -8037,11 +6791,9 @@
     prepareProperties: function prepareProperties(num, isVisible) {
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         if (isVisible || this._isParent && this.dynamicProperties[i].propType === 'transform') {
           this.dynamicProperties[i].getValue();
-
           if (this.dynamicProperties[i]._mdf) {
             this.globalData._mdf = true;
             this._mdf = true;
@@ -8063,30 +6815,21 @@
     this.footageData = globalData.imageLoader.getAsset(this.assetData);
     this.initBaseData(data, globalData, comp);
   }
-
   FootageElement.prototype.prepareFrame = function () {};
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
-
   FootageElement.prototype.getBaseElement = function () {
     return null;
   };
-
   FootageElement.prototype.renderFrame = function () {};
-
   FootageElement.prototype.destroy = function () {};
-
   FootageElement.prototype.initExpressions = function () {
     var expressionsInterfaces = getExpressionInterfaces();
-
     if (!expressionsInterfaces) {
       return;
     }
-
     var FootageInterface = expressionsInterfaces('footage');
     this.layerInterface = FootageInterface(this);
   };
-
   FootageElement.prototype.getFootageData = function () {
     return this.footageData;
   };
@@ -8112,29 +6855,23 @@
       k: [100]
     }, 1, 0.01, this);
   }
-
   AudioElement.prototype.prepareFrame = function (num) {
     this.prepareRenderableFrame(num, true);
     this.prepareProperties(num, true);
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
       this._currentTime = timeRemapped;
     } else {
       this._currentTime = num / this.data.sr;
     }
-
     this._volume = this.lv.v[0];
     var totalVolume = this._volume * this._volumeMultiplier;
-
     if (this._previousVolume !== totalVolume) {
       this._previousVolume = totalVolume;
       this.audio.volume(totalVolume);
     }
   };
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
-
   AudioElement.prototype.renderFrame = function () {
     if (this.isInRange && this._canPlay) {
       if (!this._isPlaying) {
@@ -8146,162 +6883,124 @@
       }
     }
   };
-
-  AudioElement.prototype.show = function () {// this.audio.play()
+  AudioElement.prototype.show = function () {
+    // this.audio.play()
   };
-
   AudioElement.prototype.hide = function () {
     this.audio.pause();
     this._isPlaying = false;
   };
-
   AudioElement.prototype.pause = function () {
     this.audio.pause();
     this._isPlaying = false;
     this._canPlay = false;
   };
-
   AudioElement.prototype.resume = function () {
     this._canPlay = true;
   };
-
   AudioElement.prototype.setRate = function (rateValue) {
     this.audio.rate(rateValue);
   };
-
   AudioElement.prototype.volume = function (volumeValue) {
     this._volumeMultiplier = volumeValue;
     this._previousVolume = volumeValue * this._volume;
     this.audio.volume(this._previousVolume);
   };
-
   AudioElement.prototype.getBaseElement = function () {
     return null;
   };
-
   AudioElement.prototype.destroy = function () {};
-
   AudioElement.prototype.sourceRectAtTime = function () {};
-
   AudioElement.prototype.initExpressions = function () {};
 
   function BaseRenderer() {}
-
   BaseRenderer.prototype.checkLayers = function (num) {
     var i;
     var len = this.layers.length;
     var data;
     this.completeLayers = true;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (!this.elements[i]) {
         data = this.layers[i];
-
         if (data.ip - data.st <= num - this.layers[i].st && data.op - data.st > num - this.layers[i].st) {
           this.buildItem(i);
         }
       }
-
       this.completeLayers = this.elements[i] ? this.completeLayers : false;
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.createItem = function (layer) {
     switch (layer.ty) {
       case 2:
         return this.createImage(layer);
-
       case 0:
         return this.createComp(layer);
-
       case 1:
         return this.createSolid(layer);
-
       case 3:
         return this.createNull(layer);
-
       case 4:
         return this.createShape(layer);
-
       case 5:
         return this.createText(layer);
-
       case 6:
         return this.createAudio(layer);
-
       case 13:
         return this.createCamera(layer);
-
       case 15:
         return this.createFootage(layer);
-
       default:
         return this.createNull(layer);
     }
   };
-
   BaseRenderer.prototype.createCamera = function () {
     throw new Error('You\'re using a 3d camera. Try the html renderer.');
   };
-
   BaseRenderer.prototype.createAudio = function (data) {
     return new AudioElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.createFootage = function (data) {
     return new FootageElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.buildAllItems = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       this.buildItem(i);
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.includeLayers = function (newLayers) {
     this.completeLayers = false;
     var i;
     var len = newLayers.length;
     var j;
     var jLen = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       j = 0;
-
       while (j < jLen) {
         if (this.layers[j].id === newLayers[i].id) {
           this.layers[j] = newLayers[i];
           break;
         }
-
         j += 1;
       }
     }
   };
-
   BaseRenderer.prototype.setProjectInterface = function (pInterface) {
     this.globalData.projectInterface = pInterface;
   };
-
   BaseRenderer.prototype.initItems = function () {
     if (!this.globalData.progressiveLoad) {
       this.buildAllItems();
     }
   };
-
   BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
     var elements = this.elements;
     var layers = this.layers;
     var i = 0;
     var len = layers.length;
-
     while (i < len) {
       if (layers[i].ind == parentName) {
         // eslint-disable-line eqeqeq
@@ -8311,7 +7010,6 @@
         } else {
           hierarchy.push(elements[i]);
           elements[i].setAsParent();
-
           if (layers[i].parent !== undefined) {
             this.buildElementParenting(element, layers[i].parent, hierarchy);
           } else {
@@ -8319,19 +7017,15 @@
           }
         }
       }
-
       i += 1;
     }
   };
-
   BaseRenderer.prototype.addPendingElement = function (element) {
     this.pendingElements.push(element);
   };
-
   BaseRenderer.prototype.searchExtraCompositions = function (assets) {
     var i;
     var len = assets.length;
-
     for (i = 0; i < len; i += 1) {
       if (assets[i].xt) {
         var comp = this.createComp(assets[i]);
@@ -8340,30 +7034,24 @@
       }
     }
   };
-
   BaseRenderer.prototype.getElementById = function (ind) {
     var i;
     var len = this.elements.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i].data.ind === ind) {
         return this.elements[i];
       }
     }
-
     return null;
   };
-
   BaseRenderer.prototype.getElementByPath = function (path) {
     var pathValue = path.shift();
     var element;
-
     if (typeof pathValue === 'number') {
       element = this.elements[pathValue];
     } else {
       var i;
       var len = this.elements.length;
-
       for (i = 0; i < len; i += 1) {
         if (this.elements[i].data.nm === pathValue) {
           element = this.elements[i];
@@ -8371,14 +7059,11 @@
         }
       }
     }
-
     if (path.length === 0) {
       return element;
     }
-
     return element.getElementByPath(path);
   };
-
   BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
     this.globalData.fontManager = new FontManager();
     this.globalData.slotManager = slotFactory(animData);
@@ -8402,7 +7087,6 @@
   };
 
   function TransformElement() {}
-
   TransformElement.prototype = {
     initTransform: function initTransform() {
       var mat = new Matrix();
@@ -8417,50 +7101,44 @@
         localMat: mat,
         localOpacity: 1
       };
-
       if (this.data.ao) {
         this.finalTransform.mProp.autoOriented = true;
-      } // TODO: check TYPE 11: Guided elements
+      }
 
-
-      if (this.data.ty !== 11) {// this.createElements();
+      // TODO: check TYPE 11: Guided elements
+      if (this.data.ty !== 11) {
+        // this.createElements();
       }
     },
     renderTransform: function renderTransform() {
       this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
       this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
-
       if (this.hierarchy) {
         var mat;
         var finalMat = this.finalTransform.mat;
         var i = 0;
-        var len = this.hierarchy.length; // Checking if any of the transformation matrices in the hierarchy chain has changed.
-
+        var len = this.hierarchy.length;
+        // Checking if any of the transformation matrices in the hierarchy chain has changed.
         if (!this.finalTransform._matMdf) {
           while (i < len) {
             if (this.hierarchy[i].finalTransform.mProp._mdf) {
               this.finalTransform._matMdf = true;
               break;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._matMdf) {
           mat = this.finalTransform.mProp.v.props;
           finalMat.cloneFromProps(mat);
-
           for (i = 0; i < len; i += 1) {
             finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
           }
         }
       }
-
-      if (this.finalTransform._matMdf) {
+      if (!this.localTransforms || this.finalTransform._matMdf) {
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
       }
-
       if (this.finalTransform._opMdf) {
         this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
       }
@@ -8470,41 +7148,32 @@
         var i = 0;
         var len = this.localTransforms.length;
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
-
         if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
           while (i < len) {
             if (this.localTransforms[i]._mdf) {
               this.finalTransform._localMatMdf = true;
             }
-
             if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
               this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
               this.finalTransform._opMdf = true;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._localMatMdf) {
           var localMat = this.finalTransform.localMat;
           this.localTransforms[0].matrix.clone(localMat);
-
           for (i = 1; i < len; i += 1) {
             var lmat = this.localTransforms[i].matrix;
             localMat.multiply(lmat);
           }
-
           localMat.multiply(this.finalTransform.mat);
         }
-
         if (this.finalTransform._opMdf) {
           var localOp = this.finalTransform.localOpacity;
-
           for (i = 0; i < len; i += 1) {
             localOp *= this.localTransforms[i].opacity * 0.01;
           }
-
           this.finalTransform.localOpacity = localOp;
         }
       }
@@ -8512,13 +7181,11 @@
     searchEffectTransforms: function searchEffectTransforms() {
       if (this.renderableEffectsManager) {
         var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
-
         if (transformEffects.length) {
           this.localTransforms = [];
           this.finalTransform.localMat = new Matrix();
           var i = 0;
           var len = transformEffects.length;
-
           for (i = 0; i < len; i += 1) {
             this.localTransforms.push(transformEffects[i]);
           }
@@ -8530,29 +7197,24 @@
       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;
       var len = transforms.length;
       var 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]);
-
+        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;
     },
     mHelper: new Matrix()
@@ -8583,13 +7245,11 @@
     var x;
     var maskType = 'clipPath';
     var maskRef = 'clip-path';
-
     for (i = 0; i < len; i += 1) {
       if (properties[i].mode !== 'a' && properties[i].mode !== 'n' || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
         maskType = 'mask';
         maskRef = 'mask';
       }
-
       if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
         rect = createNS('rect');
         rect.setAttribute('fill', '#ffffff');
@@ -8599,9 +7259,7 @@
       } else {
         rect = null;
       }
-
       path = createNS('path');
-
       if (properties[i].mode === 'n') {
         // TODO move this to a factory or to a constructor
         this.viewData[i] = {
@@ -8616,7 +7274,6 @@
         path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
         path.setAttribute('clip-rule', 'nonzero');
         var filterID;
-
         if (properties[i].x.k !== 0) {
           maskType = 'mask';
           maskRef = 'mask';
@@ -8634,9 +7291,9 @@
         } else {
           feMorph = null;
           x = null;
-        } // TODO move this to a factory or to a constructor
+        }
 
-
+        // TODO move this to a factory or to a constructor
         this.storedData[i] = {
           elem: path,
           x: x,
@@ -8646,15 +7303,12 @@
           filterId: filterID,
           lastRadius: 0
         };
-
         if (properties[i].mode === 'i') {
           jLen = currentMasks.length;
           var g = createNS('g');
-
           for (j = 0; j < jLen; j += 1) {
             g.appendChild(currentMasks[j]);
           }
-
           var mask = createNS('mask');
           mask.setAttribute('mask-type', 'alpha');
           mask.setAttribute('id', layerId + '_' + count);
@@ -8666,12 +7320,10 @@
         } else {
           currentMasks.push(path);
         }
-
         if (properties[i].inv && !this.solidPath) {
           this.solidPath = this.createLayerSolidPath();
-        } // TODO move this to a factory or to a constructor
-
-
+        }
+        // TODO move this to a factory or to a constructor
         this.viewData[i] = {
           elem: path,
           lastPath: '',
@@ -8679,81 +7331,65 @@
           prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
           invRect: rect
         };
-
         if (!this.viewData[i].prop.k) {
           this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
         }
       }
     }
-
     this.maskElement = createNS(maskType);
     len = currentMasks.length;
-
     for (i = 0; i < len; i += 1) {
       this.maskElement.appendChild(currentMasks[i]);
     }
-
     if (count > 0) {
       this.maskElement.setAttribute('id', layerId);
       this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
       defs.appendChild(this.maskElement);
     }
-
     if (this.viewData.length) {
       this.element.addRenderableComponent(this);
     }
   }
-
   MaskElement.prototype.getMaskProperty = function (pos) {
     return this.viewData[pos].prop;
   };
-
   MaskElement.prototype.renderFrame = function (isFirstFrame) {
     var finalMat = this.element.finalTransform.mat;
     var i;
     var len = this.masksProperties.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.viewData[i].prop._mdf || isFirstFrame) {
         this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
       }
-
       if (this.viewData[i].op._mdf || isFirstFrame) {
         this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
       }
-
       if (this.masksProperties[i].mode !== 'n') {
         if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
           this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
         }
-
         if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
           var feMorph = this.storedData[i].expan;
-
           if (this.storedData[i].x.v < 0) {
             if (this.storedData[i].lastOperator !== 'erode') {
               this.storedData[i].lastOperator = 'erode';
               this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
             }
-
             feMorph.setAttribute('radius', -this.storedData[i].x.v);
           } else {
             if (this.storedData[i].lastOperator !== 'dilate') {
               this.storedData[i].lastOperator = 'dilate';
               this.storedData[i].elem.setAttribute('filter', null);
             }
-
             this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
           }
         }
       }
     }
   };
-
   MaskElement.prototype.getMaskelement = function () {
     return this.maskElement;
   };
-
   MaskElement.prototype.createLayerSolidPath = function () {
     var path = 'M0,0 ';
     path += ' h' + this.globalData.compSize.w;
@@ -8762,39 +7398,32 @@
     path += ' v-' + this.globalData.compSize.h + ' ';
     return path;
   };
-
   MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
     var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
     var i;
     var len;
     len = pathNodes._length;
-
     for (i = 1; i < len; i += 1) {
       // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
-    } // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
-
-
+    }
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
     if (pathNodes.c && len > 1) {
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
-    } // pathNodes.__renderedString = pathString;
-
+    }
+    // pathNodes.__renderedString = pathString;
 
     if (viewData.lastPath !== pathString) {
       var pathShapeValue = '';
-
       if (viewData.elem) {
         if (pathNodes.c) {
           pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
         }
-
         viewData.elem.setAttribute('d', pathShapeValue);
       }
-
       viewData.lastPath = pathString;
     }
   };
-
   MaskElement.prototype.destroy = function () {
     this.element = null;
     this.globalData = null;
@@ -8807,11 +7436,9 @@
     var ob = {};
     ob.createFilter = createFilter;
     ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
-
     function createFilter(filId, skipCoordinates) {
       var fil = createNS('filter');
       fil.setAttribute('id', filId);
-
       if (skipCoordinates !== true) {
         fil.setAttribute('filterUnits', 'objectBoundingBox');
         fil.setAttribute('x', '0%');
@@ -8819,10 +7446,8 @@
         fil.setAttribute('width', '100%');
         fil.setAttribute('height', '100%');
       }
-
       return fil;
     }
-
     function createAlphaToLuminanceFilter() {
       var feColorMatrix = createNS('feColorMatrix');
       feColorMatrix.setAttribute('type', 'matrix');
@@ -8830,7 +7455,6 @@
       feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
       return feColorMatrix;
     }
-
     return ob;
   }();
 
@@ -8840,21 +7464,17 @@
       svgLumaHidden: true,
       offscreenCanvas: typeof OffscreenCanvas !== 'undefined'
     };
-
     if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
       ob.maskType = false;
     }
-
     if (/firefox/i.test(navigator.userAgent)) {
       ob.svgLumaHidden = false;
     }
-
     return ob;
   }();
 
   var registeredEffects$1 = {};
   var idPrefix = 'filter_result_';
-
   function SVGEffects(elem) {
     var i;
     var source = 'SourceGraphic';
@@ -8864,59 +7484,47 @@
     var count = 0;
     this.filters = [];
     var filterManager;
-
     for (i = 0; i < len; i += 1) {
       filterManager = null;
       var type = elem.data.ef[i].ty;
-
       if (registeredEffects$1[type]) {
         var Effect = registeredEffects$1[type].effect;
         filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
         source = idPrefix + count;
-
         if (registeredEffects$1[type].countsAsEffect) {
           count += 1;
         }
       }
-
       if (filterManager) {
         this.filters.push(filterManager);
       }
     }
-
     if (count) {
       elem.globalData.defs.appendChild(fil);
       elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
     }
-
     if (this.filters.length) {
       elem.addRenderableComponent(this);
     }
   }
-
   SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
     var i;
     var len = this.filters.length;
-
     for (i = 0; i < len; i += 1) {
       this.filters[i].renderFrame(_isFirstFrame);
     }
   };
-
   SVGEffects.prototype.getEffects = function (type) {
     var i;
     var len = this.filters.length;
     var effects = [];
-
     for (i = 0; i < len; i += 1) {
       if (this.filters[i].type === type) {
         effects.push(this.filters[i]);
       }
     }
-
     return effects;
   };
-
   function registerEffect$1(id, effect, countsAsEffect) {
     registeredEffects$1[id] = {
       effect: effect,
@@ -8925,7 +7533,6 @@
   }
 
   function SVGBaseElement() {}
-
   SVGBaseElement.prototype = {
     initRendererElement: function initRendererElement() {
       this.layerElement = createNS('g');
@@ -8935,8 +7542,8 @@
       this.transformedElement = this.layerElement;
       this.maskedElement = this.layerElement;
       this._sizeChanged = false;
-      var layerElementParent = null; // If this layer acts as a mask for the following layer
-
+      var layerElementParent = null;
+      // If this layer acts as a mask for the following layer
       if (this.data.td) {
         this.matteMasks = {};
         var gg = createNS('g');
@@ -8951,16 +7558,13 @@
       } else {
         this.baseElement = this.layerElement;
       }
-
       if (this.data.ln) {
         this.layerElement.setAttribute('id', this.data.ln);
       }
-
       if (this.data.cl) {
         this.layerElement.setAttribute('class', this.data.cl);
-      } // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
-
-
+      }
+      // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
       if (this.data.ty === 0 && !this.data.hd) {
         var cp = createNS('clipPath');
         var pt = createNS('path');
@@ -8969,13 +7573,11 @@
         cp.setAttribute('id', clipId);
         cp.appendChild(pt);
         this.globalData.defs.appendChild(cp);
-
         if (this.checkMasks()) {
           var cpGroup = createNS('g');
           cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
           cpGroup.appendChild(this.layerElement);
           this.transformedElement = cpGroup;
-
           if (layerElementParent) {
             layerElementParent.appendChild(this.transformedElement);
           } else {
@@ -8985,7 +7587,6 @@
           this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
         }
       }
-
       if (this.data.bm !== 0) {
         this.setBlendMode();
       }
@@ -8994,7 +7595,6 @@
       if (this.finalTransform._localMatMdf) {
         this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
       }
-
       if (this.finalTransform._opMdf) {
         this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
       }
@@ -9008,7 +7608,6 @@
       if (this.data.hd) {
         return null;
       }
-
       return this.baseElement;
     },
     createRenderableComponents: function createRenderableComponents() {
@@ -9023,14 +7622,12 @@
       if (!this.matteMasks) {
         this.matteMasks = {};
       }
-
       if (!this.matteMasks[matteType]) {
         var id = this.layerId + '_' + matteType;
         var filId;
         var fil;
         var useElement;
         var gg;
-
         if (matteType === 1 || matteType === 3) {
           var masker = createNS('mask');
           masker.setAttribute('id', id);
@@ -9039,7 +7636,6 @@
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           masker.appendChild(useElement);
           this.globalData.defs.appendChild(masker);
-
           if (!featureSupport.maskType && matteType === 1) {
             masker.setAttribute('mask-type', 'luminance');
             filId = createElementID();
@@ -9058,16 +7654,16 @@
           var maskGrouper = createNS('g');
           maskGroup.appendChild(maskGrouper);
           filId = createElementID();
-          fil = filtersFactory.createFilter(filId); /// /
-
+          fil = filtersFactory.createFilter(filId);
+          /// /
           var feCTr = createNS('feComponentTransfer');
           feCTr.setAttribute('in', 'SourceGraphic');
           fil.appendChild(feCTr);
           var feFunc = createNS('feFuncA');
           feFunc.setAttribute('type', 'table');
           feFunc.setAttribute('tableValues', '1.0 0.0');
-          feCTr.appendChild(feFunc); /// /
-
+          feCTr.appendChild(feFunc);
+          /// /
           this.globalData.defs.appendChild(fil);
           var alphaRect = createNS('rect');
           alphaRect.setAttribute('width', this.comp.data.w);
@@ -9081,7 +7677,6 @@
           useElement = createNS('use');
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           maskGrouper.appendChild(useElement);
-
           if (!featureSupport.maskType) {
             maskGroup.setAttribute('mask-type', 'luminance');
             fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
@@ -9090,20 +7685,16 @@
             gg.appendChild(this.layerElement);
             maskGrouper.appendChild(gg);
           }
-
           this.globalData.defs.appendChild(maskGroup);
         }
-
         this.matteMasks[matteType] = id;
       }
-
       return this.matteMasks[matteType];
     },
     setMatte: function setMatte(id) {
       if (!this.matteElement) {
         return;
       }
-
       this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
     }
   };
@@ -9113,8 +7704,8 @@
    * Handles AE's layer parenting property.
    *
    */
-  function HierarchyElement() {}
 
+  function HierarchyElement() {}
   HierarchyElement.prototype = {
     /**
        * @function
@@ -9123,12 +7714,11 @@
        */
     initHierarchy: function initHierarchy() {
       // element's parent list
-      this.hierarchy = []; // if element is parent of another layer _isParent will be true
-
+      this.hierarchy = [];
+      // if element is parent of another layer _isParent will be true
       this._isParent = false;
       this.checkParenting();
     },
-
     /**
        * @function
        * Sets layer's hierarchy.
@@ -9139,7 +7729,6 @@
     setHierarchy: function setHierarchy(hierarchy) {
       this.hierarchy = hierarchy;
     },
-
     /**
        * @function
        * Sets layer as parent.
@@ -9148,7 +7737,6 @@
     setAsParent: function setAsParent() {
       this._isParent = true;
     },
-
     /**
        * @function
        * Searches layer's parenting chain
@@ -9162,7 +7750,6 @@
   };
 
   function RenderableDOMElement() {}
-
   (function () {
     var _prototype = {
       initElement: function initElement(data, globalData, comp) {
@@ -9192,7 +7779,6 @@
             var elem = this.baseElement || this.layerElement;
             elem.style.display = 'block';
           }
-
           this.hidden = false;
           this._isFirstFrame = true;
         }
@@ -9203,13 +7789,11 @@
         if (this.data.hd || this.hidden) {
           return;
         }
-
         this.renderTransform();
         this.renderRenderable();
         this.renderLocalTransform();
         this.renderElement();
         this.renderInnerContent();
-
         if (this._isFirstFrame) {
           this._isFirstFrame = false;
         }
@@ -9231,11 +7815,9 @@
 
   function IImageElement(data, globalData, comp) {
     this.assetData = globalData.getAssetData(data.refId);
-
     if (this.assetData && this.assetData.sid) {
       this.assetData = globalData.slotManager.getProp(this.assetData);
     }
-
     this.initElement(data, globalData, comp);
     this.sourceRect = {
       top: 0,
@@ -9244,9 +7826,7 @@
       height: this.assetData.h
     };
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
-
   IImageElement.prototype.createContent = function () {
     var assetPath = this.globalData.getAssetsPath(this.assetData);
     this.innerElem = createNS('image');
@@ -9256,7 +7836,6 @@
     this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
     this.layerElement.appendChild(this.innerElem);
   };
-
   IImageElement.prototype.sourceRectAtTime = function () {
     return this.sourceRect;
   };
@@ -9267,12 +7846,10 @@
   }
 
   function IShapeElement() {}
-
   IShapeElement.prototype = {
     addShapeToModifiers: function addShapeToModifiers(data) {
       var i;
       var len = this.shapeModifiers.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapeModifiers[i].addShape(data);
       }
@@ -9280,34 +7857,28 @@
     isShapeInAnimatedModifiers: function isShapeInAnimatedModifiers(data) {
       var i = 0;
       var len = this.shapeModifiers.length;
-
       while (i < len) {
         if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
           return true;
         }
       }
-
       return false;
     },
     renderModifiers: function renderModifiers() {
       if (!this.shapeModifiers.length) {
         return;
       }
-
       var i;
       var len = this.shapes.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapes[i].sh.reset();
       }
-
       len = this.shapeModifiers.length;
       var shouldBreakProcess;
-
       for (i = len - 1; i >= 0; i -= 1) {
-        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame); // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+        // workaround to fix cases where a repeater resets the shape so the following processes get called twice
         // TODO: find a better solution for this
-
         if (shouldBreakProcess) {
           break;
         }
@@ -9317,30 +7888,24 @@
       var elements = this.processedElements;
       var i = 0;
       var len = elements.length;
-
       while (i < len) {
         if (elements[i].elem === elem) {
           return elements[i].pos;
         }
-
         i += 1;
       }
-
       return 0;
     },
     addProcessedElement: function addProcessedElement(elem, pos) {
       var elements = this.processedElements;
       var i = elements.length;
-
       while (i) {
         i -= 1;
-
         if (elements[i].elem === elem) {
           elements[i].pos = pos;
           return;
         }
       }
-
       elements.push(new ProcessedElement(elem, pos));
     },
     prepareFrame: function prepareFrame(num) {
@@ -9366,25 +7931,22 @@
     this.transformers = transformers;
     this.lStr = '';
     this.sh = shape;
-    this.lvl = level; // TODO find if there are some cases where _isAnimated can be false.
+    this.lvl = level;
+    // TODO find if there are some cases where _isAnimated can be false.
     // For now, since shapes add up with other shapes. They have to be calculated every time.
     // One way of finding out is checking if all styles associated to this shape depend only of this shape
-
-    this._isAnimated = !!shape.k; // TODO: commenting this for now since all shapes are animated
-
+    this._isAnimated = !!shape.k;
+    // TODO: commenting this for now since all shapes are animated
     var i = 0;
     var len = transformers.length;
-
     while (i < len) {
       if (transformers[i].mProps.dynamicProperties.length) {
         this._isAnimated = true;
         break;
       }
-
       i += 1;
     }
   }
-
   SVGShapeData.prototype.setAsAnimated = function () {
     this._isAnimated = true;
   };
@@ -9399,7 +7961,6 @@
     this.pElem = createNS('path');
     this.msElem = null;
   }
-
   SVGStyleData.prototype.reset = function () {
     this.d = '';
     this._mdf = false;
@@ -9418,7 +7979,6 @@
     var i;
     var len = data.length || 0;
     var prop;
-
     for (i = 0; i < len; i += 1) {
       prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
       this.k = prop.k || this.k;
@@ -9427,31 +7987,24 @@
         p: prop
       };
     }
-
     if (!this.k) {
       this.getValue(true);
     }
-
     this._isAnimated = this.k;
   }
-
   DashProperty.prototype.getValue = function (forceRender) {
     if (this.elem.globalData.frameId === this.frameId && !forceRender) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
     this._mdf = this._mdf || forceRender;
-
     if (this._mdf) {
       var i = 0;
       var len = this.dataProps.length;
-
       if (this.renderer === 'svg') {
         this.dashStr = '';
       }
-
       for (i = 0; i < len; i += 1) {
         if (this.dataProps[i].n !== 'o') {
           if (this.renderer === 'svg') {
@@ -9465,7 +8018,6 @@
       }
     }
   };
-
   extendPrototype([DynamicPropertyContainer], DashProperty);
 
   function SVGStrokeStyleData(elem, data, styleOb) {
@@ -9478,7 +8030,6 @@
     this.style = styleOb;
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
 
   function SVGFillStyleData(elem, data, styleOb) {
@@ -9488,7 +8039,6 @@
     this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
 
   function SVGNoStyleData(elem, data, styleOb) {
@@ -9496,7 +8046,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
 
   function GradientProperty(elem, data, container) {
@@ -9513,88 +8062,69 @@
     this.k = this.prop.k;
     this.getValue(true);
   }
-
   GradientProperty.prototype.comparePoints = function (values, points) {
     var i = 0;
     var len = this.o.length / 2;
     var diff;
-
     while (i < len) {
       diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
-
       if (diff > 0.01) {
         return false;
       }
-
       i += 1;
     }
-
     return true;
   };
-
   GradientProperty.prototype.checkCollapsable = function () {
     if (this.o.length / 2 !== this.c.length / 4) {
       return false;
     }
-
     if (this.data.k.k[0].s) {
       var i = 0;
       var len = this.data.k.k.length;
-
       while (i < len) {
         if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
           return false;
         }
-
         i += 1;
       }
     } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
       return false;
     }
-
     return true;
   };
-
   GradientProperty.prototype.getValue = function (forceRender) {
     this.prop.getValue();
     this._mdf = false;
     this._cmdf = false;
     this._omdf = false;
-
     if (this.prop._mdf || forceRender) {
       var i;
       var len = this.data.p * 4;
       var mult;
       var val;
-
       for (i = 0; i < len; i += 1) {
         mult = i % 4 === 0 ? 100 : 255;
         val = Math.round(this.prop.v[i] * mult);
-
         if (this.c[i] !== val) {
           this.c[i] = val;
           this._cmdf = !forceRender;
         }
       }
-
       if (this.o.length) {
         len = this.prop.v.length;
-
         for (i = this.data.p * 4; i < len; i += 1) {
           mult = i % 2 === 0 ? 100 : 1;
           val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
-
           if (this.o[i - this.data.p * 4] !== val) {
             this.o[i - this.data.p * 4] = val;
             this._omdf = !forceRender;
           }
         }
       }
-
       this._mdf = !forceRender;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], GradientProperty);
 
   function SVGGradientFillStyleData(elem, data, styleOb) {
@@ -9602,7 +8132,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.initGradientData(elem, data, styleOb);
   }
-
   SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
     this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
     this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
@@ -9620,7 +8149,6 @@
     this.setGradientOpacity(data, styleOb);
     this._isAnimated = !!this._isAnimated;
   };
-
   SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
     var gradientId = createElementID();
     var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
@@ -9632,18 +8160,15 @@
     var j;
     var jLen;
     jLen = data.g.p * 4;
-
     for (j = 0; j < jLen; j += 4) {
       stop = createNS('stop');
       gfill.appendChild(stop);
       stops.push(stop);
     }
-
     pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
     this.gf = gfill;
     this.cst = stops;
   };
-
   SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
     if (this.g._hasOpacity && !this.g._collapsable) {
       var stop;
@@ -9661,25 +8186,20 @@
       opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
       jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
       var stops = this.stops;
-
       for (j = data.g.p * 4; j < jLen; j += 2) {
         stop = createNS('stop');
         stop.setAttribute('stop-color', 'rgb(255,255,255)');
         opFill.appendChild(stop);
         stops.push(stop);
       }
-
       maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
@@ -9687,7 +8207,6 @@
       styleOb.msElem = maskElement;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
 
   function SVGGradientStrokeStyleData(elem, data, styleOb) {
@@ -9698,7 +8217,6 @@
     this.initGradientData(elem, data, styleOb);
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
 
   function ShapeGroupData() {
@@ -9721,77 +8239,59 @@
     if (length === 0) {
       return '';
     }
-
     var _o = pathNodes.o;
     var _i = pathNodes.i;
     var _v = pathNodes.v;
     var i;
     var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
-
     for (i = 1; i < length; i += 1) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
     }
-
     if (closed && length) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
       shapeString += 'z';
     }
-
     return shapeString;
   };
 
   var SVGElementsRenderer = function () {
     var _identityMatrix = new Matrix();
-
     var _matrixHelper = new Matrix();
-
     var ob = {
       createRenderFunction: createRenderFunction
     };
-
     function createRenderFunction(data) {
       switch (data.ty) {
         case 'fl':
           return renderFill;
-
         case 'gf':
           return renderGradient;
-
         case 'gs':
           return renderGradientStroke;
-
         case 'st':
           return renderStroke;
-
         case 'sh':
         case 'el':
         case 'rc':
         case 'sr':
           return renderPath;
-
         case 'tr':
           return renderContentTransform;
-
         case 'no':
           return renderNoop;
-
         default:
           return null;
       }
     }
-
     function renderContentTransform(styleData, itemData, isFirstFrame) {
       if (isFirstFrame || itemData.transform.op._mdf) {
         itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
       }
-
       if (isFirstFrame || itemData.transform.mProps._mdf) {
         itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
       }
     }
-
     function renderNoop() {}
-
     function renderPath(styleData, itemData, isFirstFrame) {
       var j;
       var jLen;
@@ -9805,25 +8305,20 @@
       var mat;
       var iterations;
       var k;
-
       for (l = 0; l < lLen; l += 1) {
         redraw = itemData.sh._mdf || isFirstFrame;
-
         if (itemData.styles[l].lvl < lvl) {
           mat = _matrixHelper.reset();
           iterations = lvl - itemData.styles[l].lvl;
           k = itemData.transformers.length - 1;
-
           while (!redraw && iterations > 0) {
             redraw = itemData.transformers[k].mProps._mdf || redraw;
             iterations -= 1;
             k -= 1;
           }
-
           if (redraw) {
             iterations = lvl - itemData.styles[l].lvl;
             k = itemData.transformers.length - 1;
-
             while (iterations > 0) {
               mat.multiply(itemData.transformers[k].mProps.v);
               iterations -= 1;
@@ -9833,115 +8328,90 @@
         } else {
           mat = _identityMatrix;
         }
-
         paths = itemData.sh.paths;
         jLen = paths._length;
-
         if (redraw) {
           pathStringTransformed = '';
-
           for (j = 0; j < jLen; j += 1) {
             pathNodes = paths.shapes[j];
-
             if (pathNodes && pathNodes._length) {
               pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
             }
           }
-
           itemData.caches[l] = pathStringTransformed;
         } else {
           pathStringTransformed = itemData.caches[l];
         }
-
         itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
         itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
       }
     }
-
     function renderFill(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
-
       if (itemData.c._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
       }
     }
-
     function renderGradientStroke(styleData, itemData, isFirstFrame) {
       renderGradient(styleData, itemData, isFirstFrame);
       renderStroke(styleData, itemData, isFirstFrame);
     }
-
     function renderGradient(styleData, itemData, isFirstFrame) {
       var gfill = itemData.gf;
       var hasOpacity = itemData.g._hasOpacity;
       var pt1 = itemData.s.v;
       var pt2 = itemData.e.v;
-
       if (itemData.o._mdf || isFirstFrame) {
         var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
         itemData.style.pElem.setAttribute(attr, itemData.o.v);
       }
-
       if (itemData.s._mdf || isFirstFrame) {
         var attr1 = styleData.t === 1 ? 'x1' : 'cx';
         var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
         gfill.setAttribute(attr1, pt1[0]);
         gfill.setAttribute(attr2, pt1[1]);
-
         if (hasOpacity && !itemData.g._collapsable) {
           itemData.of.setAttribute(attr1, pt1[0]);
           itemData.of.setAttribute(attr2, pt1[1]);
         }
       }
-
       var stops;
       var i;
       var len;
       var stop;
-
       if (itemData.g._cmdf || isFirstFrame) {
         stops = itemData.cst;
         var cValues = itemData.g.c;
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
           stop.setAttribute('offset', cValues[i * 4] + '%');
           stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
         }
       }
-
       if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
         var oValues = itemData.g.o;
-
         if (itemData.g._collapsable) {
           stops = itemData.cst;
         } else {
           stops = itemData.ost;
         }
-
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
-
           if (!itemData.g._collapsable) {
             stop.setAttribute('offset', oValues[i * 2] + '%');
           }
-
           stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
         }
       }
-
       if (styleData.t === 1) {
         if (itemData.e._mdf || isFirstFrame) {
           gfill.setAttribute('x2', pt2[0]);
           gfill.setAttribute('y2', pt2[1]);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('x2', pt2[0]);
             itemData.of.setAttribute('y2', pt2[1]);
@@ -9949,112 +8419,93 @@
         }
       } else {
         var rad;
-
         if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
           rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           gfill.setAttribute('r', rad);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('r', rad);
           }
         }
-
-        if (itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
           if (!rad) {
             rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           }
-
           var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
           var percent = itemData.h.v;
-
           if (percent >= 1) {
             percent = 0.99;
           } else if (percent <= -1) {
             percent = -0.99;
           }
-
           var dist = rad * percent;
           var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
           var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
           gfill.setAttribute('fx', x);
           gfill.setAttribute('fy', y);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('fx', x);
             itemData.of.setAttribute('fy', y);
           }
-        } // gfill.setAttribute('fy','200');
-
+        }
+        // gfill.setAttribute('fy','200');
       }
     }
-
     function renderStroke(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
       var d = itemData.d;
-
       if (d && (d._mdf || isFirstFrame) && d.dashStr) {
         styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
         styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
       }
-
       if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
         styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
       }
-
       if (itemData.w._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
-
         if (styleElem.msElem) {
           styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
         }
       }
     }
-
     return ob;
   }();
 
   function SVGShapeElement(data, globalData, comp) {
     // List of drawable elements
-    this.shapes = []; // Full shape data
-
-    this.shapesData = data.shapes; // List of styles that will be applied to shapes
-
-    this.stylesList = []; // List of modifiers that will be applied to shapes
-
-    this.shapeModifiers = []; // List of items in shape tree
-
-    this.itemsData = []; // List of items in previous shape tree
-
-    this.processedElements = []; // List of animated components
-
+    this.shapes = [];
+    // Full shape data
+    this.shapesData = data.shapes;
+    // List of styles that will be applied to shapes
+    this.stylesList = [];
+    // List of modifiers that will be applied to shapes
+    this.shapeModifiers = [];
+    // List of items in shape tree
+    this.itemsData = [];
+    // List of items in previous shape tree
+    this.processedElements = [];
+    // List of animated components
     this.animatedContents = [];
-    this.initElement(data, globalData, comp); // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.initElement(data, globalData, comp);
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
     // List of elements that have been created
-
-    this.prevViewData = []; // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.prevViewData = [];
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
-
   SVGShapeElement.prototype.initSecondaryElement = function () {};
-
   SVGShapeElement.prototype.identityMatrix = new Matrix();
-
   SVGShapeElement.prototype.buildExpressionInterface = function () {};
-
   SVGShapeElement.prototype.createContent = function () {
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
   };
+
   /*
   This method searches for multiple shapes that affect a single element and one of them is animated
   */
-
-
   SVGShapeElement.prototype.filterUniqueShapes = function () {
     var i;
     var len = this.shapes.length;
@@ -10064,42 +8515,34 @@
     var style;
     var tempShapes = [];
     var areAnimated = false;
-
     for (j = 0; j < jLen; j += 1) {
       style = this.stylesList[j];
       areAnimated = false;
       tempShapes.length = 0;
-
       for (i = 0; i < len; i += 1) {
         shape = this.shapes[i];
-
         if (shape.styles.indexOf(style) !== -1) {
           tempShapes.push(shape);
           areAnimated = shape._isAnimated || areAnimated;
         }
       }
-
       if (tempShapes.length > 1 && areAnimated) {
         this.setShapesAsAnimated(tempShapes);
       }
     }
   };
-
   SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
     var i;
     var len = shapes.length;
-
     for (i = 0; i < len; i += 1) {
       shapes[i].setAsAnimated();
     }
   };
-
   SVGShapeElement.prototype.createStyleElement = function (data, level) {
     // TODO: prevent drawing of hidden styles
     var elementData;
     var styleOb = new SVGStyleData(data, level);
     var pathElement = styleOb.pElem;
-
     if (data.ty === 'st') {
       elementData = new SVGStrokeStyleData(this, data, styleOb);
     } else if (data.ty === 'fl') {
@@ -10108,7 +8551,6 @@
       var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
       elementData = new GradientConstructor(this, data, styleOb);
       this.globalData.defs.appendChild(elementData.gf);
-
       if (elementData.maskId) {
         this.globalData.defs.appendChild(elementData.ms);
         this.globalData.defs.appendChild(elementData.of);
@@ -10117,66 +8559,51 @@
     } else if (data.ty === 'no') {
       elementData = new SVGNoStyleData(this, data, styleOb);
     }
-
     if (data.ty === 'st' || data.ty === 'gs') {
       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);
       }
     }
-
     if (data.r === 2) {
       pathElement.setAttribute('fill-rule', 'evenodd');
     }
-
     if (data.ln) {
       pathElement.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       pathElement.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     this.stylesList.push(styleOb);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createGroupElement = function (data) {
     var elementData = new ShapeGroupData();
-
     if (data.ln) {
       elementData.gr.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       elementData.gr.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     return elementData;
   };
-
   SVGShapeElement.prototype.createTransformElement = function (data, container) {
     var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
     var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
     var ty = 4;
-
     if (data.ty === 'rc') {
       ty = 5;
     } else if (data.ty === 'el') {
@@ -10184,7 +8611,6 @@
     } else if (data.ty === 'sr') {
       ty = 7;
     }
-
     var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
     var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
     this.shapes.push(elementData);
@@ -10192,58 +8618,46 @@
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
     var i = 0;
     var len = this.animatedContents.length;
-
     while (i < len) {
       if (this.animatedContents[i].element === element) {
         return;
       }
-
       i += 1;
     }
-
     this.animatedContents.push({
       fn: SVGElementsRenderer.createRenderFunction(data),
       element: element,
       data: data
     });
   };
-
   SVGShapeElement.prototype.setElementStyles = function (elementData) {
     var arr = elementData.styles;
     var j;
     var jLen = this.stylesList.length;
-
     for (j = 0; j < jLen; j += 1) {
-      if (!this.stylesList[j].closed) {
+      if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
         arr.push(this.stylesList[j]);
       }
     }
   };
-
   SVGShapeElement.prototype.reloadShapes = function () {
     this._isFirstFrame = true;
     var i;
     var len = this.itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       this.prevViewData[i] = this.itemsData[i];
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
     len = this.dynamicProperties.length;
-
     for (i = 0; i < len; i += 1) {
       this.dynamicProperties[i].getValue();
     }
-
     this.renderModifiers();
   };
-
   SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
     var ownTransformers = [].concat(transformers);
     var i;
@@ -10255,43 +8669,35 @@
     var currentTransform;
     var modifier;
     var processedPos;
-
     for (i = len; i >= 0; i -= 1) {
       processedPos = this.searchProcessedElement(arr[i]);
-
       if (!processedPos) {
         arr[i]._render = render;
       } else {
         itemsData[i] = prevViewData[processedPos - 1];
       }
-
       if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
         if (!processedPos) {
           itemsData[i] = this.createStyleElement(arr[i], level);
         } else {
-          itemsData[i].style.closed = false;
+          itemsData[i].style.closed = arr[i].hd;
         }
-
         if (arr[i]._render) {
           if (itemsData[i].style.pElem.parentNode !== container) {
             container.appendChild(itemsData[i].style.pElem);
           }
         }
-
         ownStyles.push(itemsData[i].style);
       } else if (arr[i].ty === 'gr') {
         if (!processedPos) {
           itemsData[i] = this.createGroupElement(arr[i]);
         } else {
           jLen = itemsData[i].it.length;
-
           for (j = 0; j < jLen; j += 1) {
             itemsData[i].prevViewData[j] = itemsData[i].it[j];
           }
         }
-
         this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
-
         if (arr[i]._render) {
           if (itemsData[i].gr.parentNode !== container) {
             container.appendChild(itemsData[i].gr);
@@ -10301,14 +8707,12 @@
         if (!processedPos) {
           itemsData[i] = this.createTransformElement(arr[i], container);
         }
-
         currentTransform = itemsData[i].transform;
         ownTransformers.push(currentTransform);
       } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
         if (!processedPos) {
           itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
         }
-
         this.setElementStyles(itemsData[i]);
       } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
         if (!processedPos) {
@@ -10320,7 +8724,6 @@
           modifier = itemsData[i];
           modifier.closed = false;
         }
-
         ownModifiers.push(modifier);
       } else if (arr[i].ty === 'rp') {
         if (!processedPos) {
@@ -10333,64 +8736,49 @@
           modifier = itemsData[i];
           modifier.closed = true;
         }
-
         ownModifiers.push(modifier);
       }
-
       this.addProcessedElement(arr[i], i + 1);
     }
-
     len = ownStyles.length;
-
     for (i = 0; i < len; i += 1) {
       ownStyles[i].closed = true;
     }
-
     len = ownModifiers.length;
-
     for (i = 0; i < len; i += 1) {
       ownModifiers[i].closed = true;
     }
   };
-
   SVGShapeElement.prototype.renderInnerContent = function () {
     this.renderModifiers();
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       this.stylesList[i].reset();
     }
-
     this.renderShape();
-
     for (i = 0; i < len; i += 1) {
       if (this.stylesList[i]._mdf || this._isFirstFrame) {
         if (this.stylesList[i].msElem) {
-          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d); // Adding M0 0 fixes same mask bug on all browsers
-
+          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+          // Adding M0 0 fixes same mask bug on all browsers
           this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
         }
-
         this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
       }
     }
   };
-
   SVGShapeElement.prototype.renderShape = function () {
     var i;
     var len = this.animatedContents.length;
     var animatedContent;
-
     for (i = 0; i < len; i += 1) {
       animatedContent = this.animatedContents[i];
-
       if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
         animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
       }
     }
   };
-
   SVGShapeElement.prototype.destroy = function () {
     this.destroyBaseElement();
     this.shapesData = null;
@@ -10413,7 +8801,6 @@
       p: true
     };
   }
-
   LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
     this._mdf.o = false;
     this._mdf.sw = false;
@@ -10422,43 +8809,36 @@
     this._mdf.m = false;
     this._mdf.p = false;
     var updated = false;
-
     if (this.o !== o) {
       this.o = o;
       this._mdf.o = true;
       updated = true;
     }
-
     if (this.sw !== sw) {
       this.sw = sw;
       this._mdf.sw = true;
       updated = true;
     }
-
     if (this.sc !== sc) {
       this.sc = sc;
       this._mdf.sc = true;
       updated = true;
     }
-
     if (this.fc !== fc) {
       this.fc = fc;
       this._mdf.fc = true;
       updated = true;
     }
-
     if (this.m !== m) {
       this.m = m;
       this._mdf.m = true;
       updated = true;
     }
-
     if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
       this.p = p;
       this._mdf.p = true;
       updated = true;
     }
-
     return updated;
   };
 
@@ -10469,11 +8849,9 @@
     this.kf = false;
     this._isFirstFrame = true;
     this._mdf = false;
-
     if (data.d && data.d.sid) {
       data.d = elem.globalData.slotManager.getProp(data.d);
     }
-
     this.data = data;
     this.elem = elem;
     this.comp = this.elem.comp;
@@ -10512,73 +8890,57 @@
       __complete: false
     };
     this.copyData(this.currentData, this.data.d.k[0].s);
-
     if (!this.searchProperty()) {
       this.completeTextData(this.currentData);
     }
   }
-
   TextProperty.prototype.defaultBoxWidth = [0, 0];
-
   TextProperty.prototype.copyData = function (obj, data) {
     for (var s in data) {
       if (Object.prototype.hasOwnProperty.call(data, s)) {
         obj[s] = data[s];
       }
     }
-
     return obj;
   };
-
   TextProperty.prototype.setCurrentData = function (data) {
     if (!data.__complete) {
       this.completeTextData(data);
     }
-
     this.currentData = data;
     this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
     this._mdf = true;
   };
-
   TextProperty.prototype.searchProperty = function () {
     return this.searchKeyframes();
   };
-
   TextProperty.prototype.searchKeyframes = function () {
     this.kf = this.data.d.k.length > 1;
-
     if (this.kf) {
       this.addEffect(this.getKeyframeValue.bind(this));
     }
-
     return this.kf;
   };
-
   TextProperty.prototype.addEffect = function (effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.getValue = function (_finalValue) {
     if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
       return;
     }
-
     this.currentData.t = this.data.d.k[this.keysIndex].s.t;
     var currentValue = this.currentData;
     var currentIndex = this.keysIndex;
-
     if (this.lock) {
       this.setCurrentData(this.currentData);
       return;
     }
-
     this.lock = true;
     this._mdf = false;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
-
     for (i = 0; i < len; i += 1) {
       // Checking if index changed to prevent creating a new object every time the expression updates.
       if (currentIndex !== this.keysIndex) {
@@ -10587,38 +8949,30 @@
         finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
       }
     }
-
     if (currentValue !== finalValue) {
       this.setCurrentData(finalValue);
     }
-
     this.v = this.currentData;
     this.pv = this.v;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   };
-
   TextProperty.prototype.getKeyframeValue = function () {
     var textKeys = this.data.d.k;
     var frameNum = this.elem.comp.renderedFrame;
     var i = 0;
     var len = textKeys.length;
-
     while (i <= len - 1) {
       if (i === len - 1 || textKeys[i + 1].t > frameNum) {
         break;
       }
-
       i += 1;
     }
-
     if (this.keysIndex !== i) {
       this.keysIndex = i;
     }
-
     return this.data.d.k[this.keysIndex].s;
   };
-
   TextProperty.prototype.buildFinalText = function (text) {
     var charactersArray = [];
     var i = 0;
@@ -10628,21 +8982,20 @@
     var shouldCombine = false;
     var shouldCombineNext = false;
     var currentChars = '';
-
     while (i < len) {
       shouldCombine = shouldCombineNext;
       shouldCombineNext = false;
       charCode = text.charCodeAt(i);
       currentChars = text.charAt(i);
-
       if (FontManager.isCombinedCharacter(charCode)) {
-        shouldCombine = true; // It's a potential surrogate pair (this is the High surrogate)
+        shouldCombine = true;
+        // It's a potential surrogate pair (this is the High surrogate)
       } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
         if (FontManager.isRegionalFlag(text, i)) {
           currentChars = text.substr(i, 14);
         } else {
-          secondCharCode = text.charCodeAt(i + 1); // It's a surrogate pair (this is the Low surrogate)
-
+          secondCharCode = text.charCodeAt(i + 1);
+          // It's a surrogate pair (this is the Low surrogate)
           if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
             if (FontManager.isModifier(charCode, secondCharCode)) {
               currentChars = text.substr(i, 2);
@@ -10656,7 +9009,6 @@
         }
       } else if (charCode > 0xDBFF) {
         secondCharCode = text.charCodeAt(i + 1);
-
         if (FontManager.isVariationSelector(charCode)) {
           shouldCombine = true;
         }
@@ -10664,20 +9016,16 @@
         shouldCombine = true;
         shouldCombineNext = true;
       }
-
       if (shouldCombine) {
         charactersArray[charactersArray.length - 1] += currentChars;
         shouldCombine = false;
       } else {
         charactersArray.push(currentChars);
       }
-
       i += currentChars.length;
     }
-
     return charactersArray;
   };
-
   TextProperty.prototype.completeTextData = function (documentData) {
     documentData.__complete = true;
     var fontManager = this.elem.globalData.fontManager;
@@ -10709,14 +9057,12 @@
     documentData.finalLineHeight = documentData.lh;
     var trackingOffset = documentData.tr / 1000 * documentData.finalSize;
     var charCode;
-
     if (documentData.sz) {
       var flag = true;
       var boxWidth = documentData.sz[0];
       var boxHeight = documentData.sz[1];
       var currentHeight;
       var finalText;
-
       while (flag) {
         finalText = this.buildFinalText(documentData.t);
         currentHeight = 0;
@@ -10724,11 +9070,9 @@
         len = finalText.length;
         trackingOffset = documentData.tr / 1000 * documentData.finalSize;
         var lastSpaceIndex = -1;
-
         for (i = 0; i < len; i += 1) {
           charCode = finalText[i].charCodeAt(0);
           newLineFlag = false;
-
           if (finalText[i] === ' ') {
             lastSpaceIndex = i;
           } else if (charCode === 13 || charCode === 3) {
@@ -10736,7 +9080,6 @@
             newLineFlag = true;
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
           }
-
           if (fontManager.chars) {
             charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
             cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -10744,17 +9087,15 @@
             // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
             cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
           }
-
           if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
             if (lastSpaceIndex === -1) {
               len += 1;
             } else {
               i = lastSpaceIndex;
             }
-
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
-            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r'); // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
-
+            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+            // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
             lastSpaceIndex = -1;
             lineWidth = 0;
           } else {
@@ -10762,9 +9103,7 @@
             lineWidth += trackingOffset;
           }
         }
-
         currentHeight += fontData.ascent * documentData.finalSize / 100;
-
         if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
           documentData.finalSize -= 1;
           documentData.finalLineHeight = documentData.finalSize * documentData.lh / documentData.s;
@@ -10775,17 +9114,14 @@
         }
       }
     }
-
     lineWidth = -trackingOffset;
     cLength = 0;
     var uncollapsedSpaces = 0;
     var currentChar;
-
     for (i = 0; i < len; i += 1) {
       newLineFlag = false;
       currentChar = documentData.finalText[i];
       charCode = currentChar.charCodeAt(0);
-
       if (charCode === 13 || charCode === 3) {
         uncollapsedSpaces = 0;
         lineWidths.push(lineWidth);
@@ -10797,7 +9133,6 @@
       } else {
         val = currentChar;
       }
-
       if (fontManager.chars) {
         charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
         cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -10805,16 +9140,15 @@
         // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
         // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
         cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
-      } //
+      }
 
-
+      //
       if (currentChar === ' ') {
         uncollapsedSpaces += cLength + trackingOffset;
       } else {
         lineWidth += cLength + trackingOffset + uncollapsedSpaces;
         uncollapsedSpaces = 0;
       }
-
       letters.push({
         l: cLength,
         an: cLength,
@@ -10825,42 +9159,35 @@
         line: currentLine,
         animatorJustifyOffset: 0
       });
-
       if (anchorGrouping == 2) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || val === ' ' || i === len - 1) {
           if (val === '' || val === ' ') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           index += 1;
           currentSize = 0;
         }
       } else if (anchorGrouping == 3) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || i === len - 1) {
           if (val === '') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           currentSize = 0;
           index += 1;
         }
@@ -10870,31 +9197,25 @@
         index += 1;
       }
     }
-
     documentData.l = letters;
     maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
     lineWidths.push(lineWidth);
-
     if (documentData.sz) {
       documentData.boxWidth = documentData.sz[0];
       documentData.justifyOffset = 0;
     } else {
       documentData.boxWidth = maxLineWidth;
-
       switch (documentData.j) {
         case 1:
           documentData.justifyOffset = -documentData.boxWidth;
           break;
-
         case 2:
           documentData.justifyOffset = -documentData.boxWidth / 2;
           break;
-
         default:
           documentData.justifyOffset = 0;
       }
     }
-
     documentData.lineWidths = lineWidths;
     var animators = data.a;
     var animatorData;
@@ -10903,63 +9224,49 @@
     var based;
     var ind;
     var indexes = [];
-
     for (j = 0; j < jLen; j += 1) {
       animatorData = animators[j];
-
       if (animatorData.a.sc) {
         documentData.strokeColorAnim = true;
       }
-
       if (animatorData.a.sw) {
         documentData.strokeWidthAnim = true;
       }
-
       if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
         documentData.fillColorAnim = true;
       }
-
       ind = 0;
       based = animatorData.s.b;
-
       for (i = 0; i < len; i += 1) {
         letterData = letters[i];
         letterData.anIndexes[j] = ind;
-
         if (based == 1 && letterData.val !== '' || based == 2 && letterData.val !== '' && letterData.val !== ' ' || based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1) || based == 4 && (letterData.n || i == len - 1)) {
           // eslint-disable-line eqeqeq
           if (animatorData.s.rn === 1) {
             indexes.push(ind);
           }
-
           ind += 1;
         }
       }
-
       data.a[j].s.totalChars = ind;
       var currentInd = -1;
       var newInd;
-
       if (animatorData.s.rn === 1) {
         for (i = 0; i < len; i += 1) {
           letterData = letters[i];
-
           if (currentInd != letterData.anIndexes[j]) {
             // eslint-disable-line eqeqeq
             currentInd = letterData.anIndexes[j];
             newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
           }
-
           letterData.anIndexes[j] = newInd;
         }
       }
     }
-
     documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
     documentData.ls = documentData.ls || 0;
     documentData.ascent = fontData.ascent * documentData.finalSize / 100;
   };
-
   TextProperty.prototype.updateDocumentData = function (newData, index) {
     index = index === undefined ? this.keysIndex : index;
     var dData = this.copyData({}, this.data.d.k[index].s);
@@ -10969,7 +9276,6 @@
     this.setCurrentData(dData);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.recalculate = function (index) {
     var dData = this.data.d.k[index].s;
     dData.__complete = false;
@@ -10977,13 +9283,11 @@
     this._isFirstFrame = true;
     this.getValue(dData);
   };
-
   TextProperty.prototype.canResizeFont = function (_canResize) {
     this.canResize = _canResize;
     this.recalculate(this.keysIndex);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
     this.minimumFontSize = Math.floor(_fontValue) || 1;
     this.recalculate(this.keysIndex);
@@ -10994,7 +9298,6 @@
     var max = Math.max;
     var min = Math.min;
     var floor = Math.floor;
-
     function TextSelectorPropFactory(elem, data) {
       this._currentTextLength = -1;
       this.k = false;
@@ -11007,7 +9310,6 @@
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: 0
       }, 0, 0, this);
-
       if ('e' in data) {
         this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
       } else {
@@ -11015,7 +9317,6 @@
           v: 100
         };
       }
-
       this.o = PropertyFactory.getProp(elem, data.o || {
         k: 0
       }, 0, 0, this);
@@ -11029,48 +9330,40 @@
         k: 100
       }, 0, 0, this);
       this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
-
       if (!this.dynamicProperties.length) {
         this.getValue();
       }
     }
-
     TextSelectorPropFactory.prototype = {
       getMult: function getMult(ind) {
         if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
           this.getValue();
         }
-
         var x1 = 0;
         var y1 = 0;
         var x2 = 1;
         var y2 = 1;
-
         if (this.ne.v > 0) {
           x1 = this.ne.v / 100.0;
         } else {
           y1 = -this.ne.v / 100.0;
         }
-
         if (this.xe.v > 0) {
           x2 = 1.0 - this.xe.v / 100.0;
         } else {
           y2 = 1.0 + this.xe.v / 100.0;
         }
-
         var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
         var mult = 0;
         var s = this.finalS;
         var e = this.finalE;
         var type = this.data.sh;
-
         if (type === 2) {
           if (e === s) {
             mult = ind >= e ? 1 : 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 3) {
           if (e === s) {
@@ -11078,21 +9371,18 @@
           } else {
             mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 4) {
           if (e === s) {
             mult = 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
-
             if (mult < 0.5) {
               mult *= 2;
             } else {
               mult = 1 - 2 * (mult - 0.5);
             }
           }
-
           mult = easer(mult);
         } else if (type === 5) {
           if (e === s) {
@@ -11101,13 +9391,11 @@
             var tot = e - s;
             /* ind += 0.5;
                       mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
-
             ind = min(max(0, ind + 0.5 - s), e - s);
             var x = -tot / 2 + ind;
             var a = tot / 2;
             mult = Math.sqrt(1 - x * x / (a * a));
           }
-
           mult = easer(mult);
         } else if (type === 6) {
           if (e === s) {
@@ -11116,7 +9404,6 @@
             ind = min(max(0, ind + 0.5 - s), e - s);
             mult = (1 + Math.cos(Math.PI + Math.PI * 2 * ind / (e - s))) / 2; // eslint-disable-line
           }
-
           mult = easer(mult);
         } else {
           if (ind >= floor(s)) {
@@ -11126,9 +9413,9 @@
               mult = max(0, min(e - ind, 1));
             }
           }
-
           mult = easer(mult);
-        } // Smoothness implementation.
+        }
+        // Smoothness implementation.
         // The smoothness represents a reduced range of the original [0; 1] range.
         // if smoothness is 25%, the new range will be [0.375; 0.625]
         // Steps are:
@@ -11138,60 +9425,47 @@
         //     - subtract the threshold
         //     - divide it by the smoothness (this will return the range to [0; 1])
         // Note: If it doesn't work on some scenarios, consider applying it before the easer.
-
-
         if (this.sm.v !== 100) {
           var smoothness = this.sm.v * 0.01;
-
           if (smoothness === 0) {
             smoothness = 0.00000001;
           }
-
           var threshold = 0.5 - smoothness * 0.5;
-
           if (mult < threshold) {
             mult = 0;
           } else {
             mult = (mult - threshold) / smoothness;
-
             if (mult > 1) {
               mult = 1;
             }
           }
         }
-
         return mult * this.a.v;
       },
       getValue: function getValue(newCharsFlag) {
         this.iterateDynamicProperties();
         this._mdf = newCharsFlag || this._mdf;
         this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
-
         if (newCharsFlag && this.data.r === 2) {
           this.e.v = this._currentTextLength;
         }
-
         var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
         var o = this.o.v / divisor;
         var s = this.s.v / divisor + o;
         var e = this.e.v / divisor + o;
-
         if (s > e) {
           var _s = s;
           s = e;
           e = _s;
         }
-
         this.finalS = s;
         this.finalE = e;
       }
     };
     extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
-
     function getTextSelectorProp(elem, data, arr) {
       return new TextSelectorPropFactory(elem, data, arr);
     }
-
     return {
       getTextSelectorProp: getTextSelectorProp
     };
@@ -11241,18 +9515,15 @@
     this.lettersChangedFlag = false;
     this.initDynamicPropertyContainer(elem);
   }
-
   TextAnimatorProperty.prototype.searchProperties = function () {
     var i;
     var len = this._textData.a.length;
     var animatorProps;
     var getProp = PropertyFactory.getProp;
-
     for (i = 0; i < len; i += 1) {
       animatorProps = this._textData.a[i];
       this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
     }
-
     if (this._textData.p && 'm' in this._textData.p) {
       this._pathData = {
         a: getProp(this._elem, this._textData.p.a, 0, 0, this),
@@ -11266,17 +9537,13 @@
     } else {
       this._hasMaskedPath = false;
     }
-
     this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
   };
-
   TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
     this.lettersChangedFlag = lettersChangedFlag;
-
     if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
       return;
     }
-
     this._isFirstFrame = false;
     var alignment = this._moreOptions.alignment.v;
     var animators = this._animatorsData;
@@ -11304,18 +9571,14 @@
     var perc;
     var tanAngle;
     var mask;
-
     if (this._hasMaskedPath) {
       mask = this._pathData.m;
-
       if (!this._pathData.n || this._pathData._mdf) {
         var paths = mask.v;
-
         if (this._pathData.r.v) {
           paths = paths.reverse();
-        } // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
-
-
+        }
+        // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
         pathInfo = {
           tLength: 0,
           segments: []
@@ -11323,26 +9586,21 @@
         len = paths._length - 1;
         var bezierData;
         totalLength = 0;
-
         for (i = 0; i < len; i += 1) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[i + 1], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         i = len;
-
         if (mask.v.c) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[0], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         this._pathData.pi = pathInfo;
       }
-
       pathInfo = this._pathData.pi;
       currentLength = this._pathData.f.v;
       segmentInd = 0;
@@ -11350,20 +9608,16 @@
       segmentLength = 0;
       flag = true;
       segments = pathInfo.segments;
-
       if (currentLength < 0 && mask.v.c) {
         if (pathInfo.tLength < Math.abs(currentLength)) {
           currentLength = -Math.abs(currentLength) % pathInfo.tLength;
         }
-
         segmentInd = segments.length - 1;
         points = segments[segmentInd].points;
         pointInd = points.length - 1;
-
         while (currentLength < 0) {
           currentLength += points[pointInd].partialLength;
           pointInd -= 1;
-
           if (pointInd < 0) {
             segmentInd -= 1;
             points = segments[segmentInd].points;
@@ -11371,13 +9625,11 @@
           }
         }
       }
-
       points = segments[segmentInd].points;
       prevPoint = points[pointInd - 1];
       currentPoint = points[pointInd];
       partialLength = currentPoint.partialLength;
     }
-
     len = letters.length;
     xPos = 0;
     yPos = 0;
@@ -11408,40 +9660,35 @@
     var letterFc;
     var letterM = '';
     var letterP = this.defaultPropsArray;
-    var letterO; //
+    var letterO;
 
+    //
     if (documentData.j === 2 || documentData.j === 1) {
       var animatorJustifyOffset = 0;
       var animatorFirstCharOffset = 0;
       var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
       var lastIndex = 0;
       var isNewLine = true;
-
       for (i = 0; i < len; i += 1) {
         if (letters[i].n) {
           if (animatorJustifyOffset) {
             animatorJustifyOffset += animatorFirstCharOffset;
           }
-
           while (lastIndex < i) {
             letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
             lastIndex += 1;
           }
-
           animatorJustifyOffset = 0;
           isNewLine = true;
         } else {
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.t.propType) {
               if (isNewLine && documentData.j === 2) {
                 animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
               }
-
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
               } else {
@@ -11449,33 +9696,28 @@
               }
             }
           }
-
           isNewLine = false;
         }
       }
-
       if (animatorJustifyOffset) {
         animatorJustifyOffset += animatorFirstCharOffset;
       }
-
       while (lastIndex < i) {
         letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
         lastIndex += 1;
       }
-    } //
-
+    }
+    //
 
     for (i = 0; i < len; i += 1) {
       matrixHelper.reset();
       elemOpacity = 1;
-
       if (letters[i].n) {
         xPos = 0;
         yPos += documentData.yOffset;
         yPos += firstLine ? 1 : 0;
         currentLength = initPathPos;
         firstLine = false;
-
         if (this._hasMaskedPath) {
           segmentInd = initSegmentInd;
           pointInd = initPointInd;
@@ -11485,7 +9727,6 @@
           partialLength = currentPoint.partialLength;
           segmentLength = 0;
         }
-
         letterM = '';
         letterFc = '';
         letterSw = '';
@@ -11498,48 +9739,37 @@
               case 1:
                 currentLength += totalLength - documentData.lineWidths[letters[i].line];
                 break;
-
               case 2:
                 currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
                 break;
-
               default:
                 break;
             }
-
             currentLine = letters[i].line;
           }
-
           if (ind !== letters[i].ind) {
             if (letters[ind]) {
               currentLength += letters[ind].extra;
             }
-
             currentLength += letters[i].an / 2;
             ind = letters[i].ind;
           }
-
           currentLength += alignment[0] * letters[i].an * 0.005;
           var animatorOffset = 0;
-
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.p.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.p.v[0] * mult[0];
               } else {
                 animatorOffset += animatorProps.p.v[0] * mult;
               }
             }
-
             if (animatorProps.a.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.a.v[0] * mult[0];
               } else {
@@ -11547,14 +9777,12 @@
               }
             }
           }
-
-          flag = true; // Force alignment only works with a single line for now
-
+          flag = true;
+          // Force alignment only works with a single line for now
           if (this._pathData.a.v) {
             currentLength = letters[0].an * 0.5 + (totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind / (len - 1);
             currentLength += this._pathData.f.v;
           }
-
           while (flag) {
             if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
               perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
@@ -11565,11 +9793,9 @@
             } else if (points) {
               segmentLength += currentPoint.partialLength;
               pointInd += 1;
-
               if (pointInd >= points.length) {
                 pointInd = 0;
                 segmentInd += 1;
-
                 if (!segments[segmentInd]) {
                   if (mask.v.c) {
                     pointInd = 0;
@@ -11583,7 +9809,6 @@
                   points = segments[segmentInd].points;
                 }
               }
-
               if (points) {
                 prevPoint = currentPoint;
                 currentPoint = points[pointInd];
@@ -11591,23 +9816,21 @@
               }
             }
           }
-
           offf = letters[i].an / 2 - letters[i].add;
           matrixHelper.translate(-offf, 0, 0);
         } else {
           offf = letters[i].an / 2 - letters[i].add;
-          matrixHelper.translate(-offf, 0, 0); // Grouping alignment
+          matrixHelper.translate(-offf, 0, 0);
 
+          // Grouping alignment
           matrixHelper.translate(-alignment[0] * letters[i].an * 0.005, -alignment[1] * yOff * 0.01, 0);
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.t.propType) {
             animatorSelector = animators[j].s;
-            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars); // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
-
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
             if (xPos !== 0 || documentData.j !== 0) {
               if (this._hasMaskedPath) {
                 if (mult.length) {
@@ -11623,11 +9846,9 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           sw = documentData.sw || 0;
         }
-
         if (documentData.strokeColorAnim) {
           if (documentData.sc) {
             sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
@@ -11635,18 +9856,14 @@
             sc = [0, 0, 0];
           }
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.a.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
             } else {
@@ -11654,14 +9871,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.s.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.scale(1 + (animatorProps.s.v[0] - 1) * mult[0], 1 + (animatorProps.s.v[1] - 1) * mult[1], 1);
             } else {
@@ -11669,12 +9883,10 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
           animatorSelector = animators[j].s;
           mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
           if (animatorProps.sk.propType) {
             if (mult.length) {
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
@@ -11682,7 +9894,6 @@
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
             }
           }
-
           if (animatorProps.r.propType) {
             if (mult.length) {
               matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
@@ -11690,7 +9901,6 @@
               matrixHelper.rotateZ(-animatorProps.r.v * mult);
             }
           }
-
           if (animatorProps.ry.propType) {
             if (mult.length) {
               matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
@@ -11698,7 +9908,6 @@
               matrixHelper.rotateY(animatorProps.ry.v * mult);
             }
           }
-
           if (animatorProps.rx.propType) {
             if (mult.length) {
               matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
@@ -11706,7 +9915,6 @@
               matrixHelper.rotateX(animatorProps.rx.v * mult);
             }
           }
-
           if (animatorProps.o.propType) {
             if (mult.length) {
               elemOpacity += (animatorProps.o.v * mult[0] - elemOpacity) * mult[0];
@@ -11714,7 +9922,6 @@
               elemOpacity += (animatorProps.o.v * mult - elemOpacity) * mult;
             }
           }
-
           if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
             if (mult.length) {
               sw += animatorProps.sw.v * mult[0];
@@ -11722,7 +9929,6 @@
               sw += animatorProps.sw.v * mult;
             }
           }
-
           if (documentData.strokeColorAnim && animatorProps.sc.propType) {
             for (k = 0; k < 3; k += 1) {
               if (mult.length) {
@@ -11732,7 +9938,6 @@
               }
             }
           }
-
           if (documentData.fillColorAnim && documentData.fc) {
             if (animatorProps.fc.propType) {
               for (k = 0; k < 3; k += 1) {
@@ -11743,7 +9948,6 @@
                 }
               }
             }
-
             if (animatorProps.fh.propType) {
               if (mult.length) {
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
@@ -11751,7 +9955,6 @@
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult);
               }
             }
-
             if (animatorProps.fs.propType) {
               if (mult.length) {
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
@@ -11759,7 +9962,6 @@
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
               }
             }
-
             if (animatorProps.fb.propType) {
               if (mult.length) {
                 fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
@@ -11769,14 +9971,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.p.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (this._hasMaskedPath) {
               if (mult.length) {
                 matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
@@ -11790,68 +9989,53 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           letterSw = sw < 0 ? 0 : sw;
         }
-
         if (documentData.strokeColorAnim) {
           letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
         }
-
         if (this._hasMaskedPath) {
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(0, alignment[1] * yOff * 0.01 + yPos, 0);
-
           if (this._pathData.p.v) {
             tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
             var rot = Math.atan(tanAngle) * 180 / Math.PI;
-
             if (currentPoint.point[0] < prevPoint.point[0]) {
               rot += 180;
             }
-
             matrixHelper.rotate(-rot * Math.PI / 180);
           }
-
           matrixHelper.translate(xPathPos, yPathPos, 0);
           currentLength -= alignment[0] * letters[i].an * 0.005;
-
           if (letters[i + 1] && ind !== letters[i + 1].ind) {
             currentLength += letters[i].an / 2;
             currentLength += documentData.tr * 0.001 * documentData.finalSize;
           }
         } else {
           matrixHelper.translate(xPos, yPos, 0);
-
           if (documentData.ps) {
             // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
             matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
           }
-
           switch (documentData.j) {
             case 1:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
               break;
-
             case 2:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
               break;
-
             default:
               break;
           }
-
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(offf, 0, 0);
           matrixHelper.translate(alignment[0] * letters[i].an * 0.005, alignment[1] * yOff * 0.01, 0);
           xPos += letters[i].l + documentData.tr * 0.001 * documentData.finalSize;
         }
-
         if (renderType === 'html') {
           letterM = matrixHelper.toCSS();
         } else if (renderType === 'svg') {
@@ -11859,10 +10043,8 @@
         } else {
           letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
         }
-
         letterO = elemOpacity;
       }
-
       if (renderedLettersCount <= i) {
         letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
         this.renderedLetters.push(letterValue);
@@ -11874,22 +10056,18 @@
       }
     }
   };
-
   TextAnimatorProperty.prototype.getValue = function () {
     if (this._elem.globalData.frameId === this._frameId) {
       return;
     }
-
     this._frameId = this._elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   TextAnimatorProperty.prototype.mHelper = new Matrix();
   TextAnimatorProperty.prototype.defaultPropsArray = [];
   extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
 
   function ITextElement() {}
-
   ITextElement.prototype.initElement = function (data, globalData, comp) {
     this.lettersChangedFlag = true;
     this.initFrame();
@@ -11906,72 +10084,55 @@
     this.hide();
     this.textAnimator.searchProperties(this.dynamicProperties);
   };
-
   ITextElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
   };
-
   ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
     var j;
     var jLen = shapes.length;
     var pathNodes;
     var shapeStr = '';
-
     for (j = 0; j < jLen; j += 1) {
       if (shapes[j].ty === 'sh') {
         pathNodes = shapes[j].ks.k;
         shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
       }
     }
-
     return shapeStr;
   };
-
   ITextElement.prototype.updateDocumentData = function (newData, index) {
     this.textProperty.updateDocumentData(newData, index);
   };
-
   ITextElement.prototype.canResizeFont = function (_canResize) {
     this.textProperty.canResizeFont(_canResize);
   };
-
   ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
     this.textProperty.setMinimumFontSize(_fontSize);
   };
-
   ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
     if (documentData.ps) {
       matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
     }
-
     matrixHelper.translate(0, -documentData.ls, 0);
-
     switch (documentData.j) {
       case 1:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
         break;
-
       case 2:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
         break;
-
       default:
         break;
     }
-
     matrixHelper.translate(xPos, yPos, 0);
   };
-
   ITextElement.prototype.buildColor = function (colorData) {
     return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
   };
-
   ITextElement.prototype.emptyProp = new LetterProps();
-
   ITextElement.prototype.destroy = function () {};
-
   ITextElement.prototype.validateText = function () {
     if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
       this.buildNewText();
@@ -11983,27 +10144,22 @@
   var emptyShapeData = {
     shapes: []
   };
-
   function SVGTextLottieElement(data, globalData, comp) {
     this.textSpans = [];
     this.renderType = 'svg';
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
-
   SVGTextLottieElement.prototype.createContent = function () {
     if (this.data.singleShape && !this.globalData.fontManager.chars) {
       this.textContainer = createNS('text');
     }
   };
-
   SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
     var i = 0;
     var len = textArray.length;
     var textContents = [];
     var currentTextContent = '';
-
     while (i < len) {
       if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
         textContents.push(currentTextContent);
@@ -12011,14 +10167,11 @@
       } else {
         currentTextContent += textArray[i];
       }
-
       i += 1;
     }
-
     textContents.push(currentTextContent);
     return textContents;
   };
-
   SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
     // data should probably be cloned to apply scale separately to each instance of a text on different layers
     // but since text internal content gets only rendered once and then it's never rerendered,
@@ -12026,41 +10179,33 @@
     // Avoiding cloning is preferred since cloning each character shape data is expensive
     if (data.shapes && data.shapes.length) {
       var shape = data.shapes[0];
-
       if (shape.it) {
         var shapeItem = shape.it[shape.it.length - 1];
-
         if (shapeItem.s) {
           shapeItem.s.k[0] = scale;
           shapeItem.s.k[1] = scale;
         }
       }
     }
-
     return data;
   };
-
   SVGTextLottieElement.prototype.buildNewText = function () {
     this.addDynamicProperty(this);
     var i;
     var len;
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
-
     if (documentData.fc) {
       this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
     } else {
       this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
     }
-
     if (documentData.sc) {
       this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
       this.layerElement.setAttribute('stroke-width', documentData.sw);
     }
-
     this.layerElement.setAttribute('font-size', documentData.finalSize);
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
-
     if (fontData.fClass) {
       this.layerElement.setAttribute('class', fontData.fClass);
     } else {
@@ -12070,7 +10215,6 @@
       this.layerElement.setAttribute('font-style', fStyle);
       this.layerElement.setAttribute('font-weight', fWeight);
     }
-
     this.layerElement.setAttribute('aria-label', documentData.t);
     var letters = documentData.l || [];
     var usesGlyphs = !!this.globalData.fontManager.chars;
@@ -12083,31 +10227,25 @@
     var yPos = 0;
     var firstLine = true;
     var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
-
     if (singleShape && !usesGlyphs && !documentData.sz) {
       var tElement = this.textContainer;
       var justify = 'start';
-
       switch (documentData.j) {
         case 1:
           justify = 'end';
           break;
-
         case 2:
           justify = 'middle';
           break;
-
         default:
           justify = 'start';
           break;
       }
-
       tElement.setAttribute('text-anchor', justify);
       tElement.setAttribute('letter-spacing', trackingOffset);
       var textContent = this.buildTextContents(documentData.finalText);
       len = textContent.length;
       yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
-
       for (i = 0; i < len; i += 1) {
         tSpan = this.textSpans[i].span || createNS('tspan');
         tSpan.textContent = textContent[i];
@@ -12115,23 +10253,19 @@
         tSpan.setAttribute('y', yPos);
         tSpan.style.display = 'inherit';
         tElement.appendChild(tSpan);
-
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
             span: null,
             glyph: null
           };
         }
-
         this.textSpans[i].span = tSpan;
         yPos += documentData.finalLineHeight;
       }
-
       this.layerElement.appendChild(tElement);
     } else {
       var cachedSpansLength = this.textSpans.length;
       var charData;
-
       for (i = 0; i < len; i += 1) {
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
@@ -12140,31 +10274,24 @@
             glyph: null
           };
         }
-
         if (!usesGlyphs || !singleShape || i === 0) {
           tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
-
           if (cachedSpansLength <= i) {
             tSpan.setAttribute('stroke-linecap', 'butt');
             tSpan.setAttribute('stroke-linejoin', 'round');
             tSpan.setAttribute('stroke-miterlimit', '4');
             this.textSpans[i].span = tSpan;
-
             if (usesGlyphs) {
               var childSpan = createNS('g');
               tSpan.appendChild(childSpan);
               this.textSpans[i].childSpan = childSpan;
             }
-
             this.textSpans[i].span = tSpan;
             this.layerElement.appendChild(tSpan);
           }
-
           tSpan.style.display = 'inherit';
         }
-
         matrixHelper.reset();
-
         if (singleShape) {
           if (letters[i].n) {
             xPos = -trackingOffset;
@@ -12172,42 +10299,36 @@
             yPos += firstLine ? 1 : 0;
             firstLine = false;
           }
-
           this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
-          xPos += letters[i].l || 0; // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
-
+          xPos += letters[i].l || 0;
+          // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
           xPos += trackingOffset;
         }
-
         if (usesGlyphs) {
           charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
-          var glyphElement; // t === 1 means the character has been replaced with an animated shaped
-
+          var glyphElement;
+          // t === 1 means the character has been replaced with an animated shaped
           if (charData.t === 1) {
             glyphElement = new SVGCompElement(charData.data, this.globalData, this);
           } else {
             var data = emptyShapeData;
-
             if (charData.data && charData.data.shapes) {
               data = this.buildShapeData(charData.data, documentData.finalSize);
             }
-
             glyphElement = new SVGShapeElement(data, this.globalData, this);
           }
-
           if (this.textSpans[i].glyph) {
             var glyph = this.textSpans[i].glyph;
             this.textSpans[i].childSpan.removeChild(glyph.layerElement);
             glyph.destroy();
           }
-
           this.textSpans[i].glyph = glyphElement;
           glyphElement._debug = true;
           glyphElement.prepareFrame(0);
           glyphElement.renderFrame();
-          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement); // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+          // when using animated shapes, the layer will be scaled instead of replacing the internal scale
           // this might have issues with strokes and might need a different solution
-
           if (charData.t === 1) {
             this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
           }
@@ -12215,30 +10336,24 @@
           if (singleShape) {
             tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
           }
-
           tSpan.textContent = letters[i].val;
           tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
-        } //
-
+        }
+        //
       }
-
       if (singleShape && tSpan) {
         tSpan.setAttribute('d', shapeStr);
       }
     }
-
     while (i < this.textSpans.length) {
       this.textSpans[i].span.style.display = 'none';
       i += 1;
     }
-
     this._sizeChanged = true;
   };
-
   SVGTextLottieElement.prototype.sourceRectAtTime = function () {
     this.prepareFrame(this.comp.renderedFrame - this.data.st);
     this.renderInnerContent();
-
     if (this._sizeChanged) {
       this._sizeChanged = false;
       var textBox = this.layerElement.getBBox();
@@ -12249,35 +10364,27 @@
         height: textBox.height
       };
     }
-
     return this.bbox;
   };
-
   SVGTextLottieElement.prototype.getValue = function () {
     var i;
     var len = this.textSpans.length;
     var glyphElement;
     this.renderedFrame = this.comp.renderedFrame;
-
     for (i = 0; i < len; i += 1) {
       glyphElement = this.textSpans[i].glyph;
-
       if (glyphElement) {
         glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
-
         if (glyphElement._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   SVGTextLottieElement.prototype.renderInnerContent = function () {
     this.validateText();
-
     if (!this.data.singleShape || this._mdf) {
       this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
-
       if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
         this._sizeChanged = true;
         var i;
@@ -12288,33 +10395,26 @@
         var renderedLetter;
         var textSpan;
         var glyphElement;
-
         for (i = 0; i < len; i += 1) {
           if (!letters[i].n) {
             renderedLetter = renderedLetters[i];
             textSpan = this.textSpans[i].span;
             glyphElement = this.textSpans[i].glyph;
-
             if (glyphElement) {
               glyphElement.renderFrame();
             }
-
             if (renderedLetter._mdf.m) {
               textSpan.setAttribute('transform', renderedLetter.m);
             }
-
             if (renderedLetter._mdf.o) {
               textSpan.setAttribute('opacity', renderedLetter.o);
             }
-
             if (renderedLetter._mdf.sw) {
               textSpan.setAttribute('stroke-width', renderedLetter.sw);
             }
-
             if (renderedLetter._mdf.sc) {
               textSpan.setAttribute('stroke', renderedLetter.sc);
             }
-
             if (renderedLetter._mdf.fc) {
               textSpan.setAttribute('fill', renderedLetter.fc);
             }
@@ -12327,14 +10427,12 @@
   function ISolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([IImageElement], ISolidElement);
-
   ISolidElement.prototype.createContent = function () {
-    var rect = createNS('rect'); /// /rect.style.width = this.data.sw;
+    var rect = createNS('rect');
+    /// /rect.style.width = this.data.sw;
     /// /rect.style.height = this.data.sh;
     /// /rect.style.fill = this.data.sc;
-
     rect.setAttribute('width', this.data.sw);
     rect.setAttribute('height', this.data.sh);
     rect.setAttribute('fill', this.data.sc);
@@ -12348,59 +10446,43 @@
     this.initTransform(data, globalData, comp);
     this.initHierarchy();
   }
-
   NullElement.prototype.prepareFrame = function (num) {
     this.prepareProperties(num, true);
   };
-
   NullElement.prototype.renderFrame = function () {};
-
   NullElement.prototype.getBaseElement = function () {
     return null;
   };
-
   NullElement.prototype.destroy = function () {};
-
   NullElement.prototype.sourceRectAtTime = function () {};
-
   NullElement.prototype.hide = function () {};
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
 
   function SVGRendererBase() {}
-
   extendPrototype([BaseRenderer], SVGRendererBase);
-
   SVGRendererBase.prototype.createNull = function (data) {
     return new NullElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createShape = function (data) {
     return new SVGShapeElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createText = function (data) {
     return new SVGTextLottieElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createImage = function (data) {
     return new IImageElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createSolid = function (data) {
     return new ISolidElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.configAnimation = function (animData) {
     this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
     this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
-
     if (this.renderConfig.viewBoxSize) {
       this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
     } else {
       this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
     }
-
     if (!this.renderConfig.viewBoxOnly) {
       this.svgElement.setAttribute('width', animData.w);
       this.svgElement.setAttribute('height', animData.h);
@@ -12409,32 +10491,26 @@
       this.svgElement.style.transform = 'translate3d(0,0,0)';
       this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
     }
-
     if (this.renderConfig.width) {
       this.svgElement.setAttribute('width', this.renderConfig.width);
     }
-
     if (this.renderConfig.height) {
       this.svgElement.setAttribute('height', this.renderConfig.height);
     }
-
     if (this.renderConfig.className) {
       this.svgElement.setAttribute('class', this.renderConfig.className);
     }
-
     if (this.renderConfig.id) {
       this.svgElement.setAttribute('id', this.renderConfig.id);
     }
-
     if (this.renderConfig.focusable !== undefined) {
       this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
     }
-
-    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio); // this.layerElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+    // this.layerElement.style.transform = 'translate3d(0,0,0)';
     // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
-
-    this.animationItem.wrapper.appendChild(this.svgElement); // Mask animation
-
+    this.animationItem.wrapper.appendChild(this.svgElement);
+    // Mask animation
     var defs = this.globalData.defs;
     this.setupGlobalData(animData, defs);
     this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
@@ -12453,71 +10529,54 @@
     this.layers = animData.layers;
     this.elements = createSizedArray(animData.layers.length);
   };
-
   SVGRendererBase.prototype.destroy = function () {
     if (this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     this.layerElement = null;
     this.globalData.defs = null;
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.destroyed = true;
     this.animationItem = null;
   };
-
   SVGRendererBase.prototype.updateContainerSize = function () {};
-
   SVGRendererBase.prototype.findIndexByInd = function (ind) {
     var i = 0;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.layers[i].ind === ind) {
         return i;
       }
     }
-
     return -1;
   };
-
   SVGRendererBase.prototype.buildItem = function (pos) {
     var elements = this.elements;
-
     if (elements[pos] || this.layers[pos].ty === 99) {
       return;
     }
-
     elements[pos] = true;
     var element = this.createItem(this.layers[pos]);
     elements[pos] = element;
-
     if (getExpressionsPlugin()) {
       if (this.layers[pos].ty === 0) {
         this.globalData.projectInterface.registerComposition(element);
       }
-
       element.initExpressions();
     }
-
     this.appendElementInPos(element, pos);
-
     if (this.layers[pos].tt) {
       var elementIndex = 'tp' in this.layers[pos] ? this.findIndexByInd(this.layers[pos].tp) : pos - 1;
-
       if (elementIndex === -1) {
         return;
       }
-
       if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
         this.buildItem(elementIndex);
         this.addPendingElement(element);
@@ -12528,16 +10587,13 @@
       }
     }
   };
-
   SVGRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
-
       if (element.data.tt) {
         var i = 0;
         var len = this.elements.length;
-
         while (i < len) {
           if (this.elements[i] === element) {
             var elementIndex = 'tp' in element.data ? this.findIndexByInd(element.data.tp) : i - 1;
@@ -12546,43 +10602,36 @@
             element.setMatte(matteMask);
             break;
           }
-
           i += 1;
         }
       }
     }
   };
-
   SVGRendererBase.prototype.renderFrame = function (num) {
     if (this.renderedFrame === num || this.destroyed) {
       return;
     }
-
     if (num === null) {
       num = this.renderedFrame;
     } else {
       this.renderedFrame = num;
-    } // console.log('-------');
+    }
+    // console.log('-------');
     // console.log('FRAME ',num);
-
-
     this.globalData.frameNum = num;
     this.globalData.frameId += 1;
     this.globalData.projectInterface.currentFrame = num;
     this.globalData._mdf = false;
     var i;
     var len = this.layers.length;
-
     if (!this.completeLayers) {
       this.checkLayers(num);
     }
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(num - this.layers[i].st);
       }
     }
-
     if (this.globalData._mdf) {
       for (i = 0; i < len; i += 1) {
         if (this.completeLayers || this.elements[i]) {
@@ -12591,44 +10640,34 @@
       }
     }
   };
-
   SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
     var newElement = element.getBaseElement();
-
     if (!newElement) {
       return;
     }
-
     var i = 0;
     var nextElement;
-
     while (i < pos) {
       if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
         nextElement = this.elements[i].getBaseElement();
       }
-
       i += 1;
     }
-
     if (nextElement) {
       this.layerElement.insertBefore(newElement, nextElement);
     } else {
       this.layerElement.appendChild(newElement);
     }
   };
-
   SVGRendererBase.prototype.hide = function () {
     this.layerElement.style.display = 'none';
   };
-
   SVGRendererBase.prototype.show = function () {
     this.layerElement.style.display = 'block';
   };
 
   function ICompElement() {}
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
-
   ICompElement.prototype.initElement = function (data, globalData, comp) {
     this.initFrame();
     this.initBaseData(data, globalData, comp);
@@ -12638,13 +10677,12 @@
     this.initRendererElement();
     this.createContainerElements();
     this.createRenderableComponents();
-
     if (this.data.xt || !globalData.progressiveLoad) {
       this.buildAllItems();
     }
-
     this.hide();
   };
+
   /* ICompElement.prototype.hide = function(){
       if(!this.hidden){
           this.hideElement();
@@ -12657,77 +10695,61 @@
       }
   }; */
 
-
   ICompElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
-
     if (!this.isInRange && !this.data.xt) {
       return;
     }
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
-
       if (timeRemapped === this.data.op) {
         timeRemapped = this.data.op - 1;
       }
-
       this.renderedFrame = timeRemapped;
     } else {
       this.renderedFrame = num / this.data.sr;
     }
-
     var i;
     var len = this.elements.length;
-
     if (!this.completeLayers) {
       this.checkLayers(this.renderedFrame);
-    } // This iteration needs to be backwards because of how expressions connect between each other
-
-
+    }
+    // This iteration needs to be backwards because of how expressions connect between each other
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
-
         if (this.elements[i]._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   ICompElement.prototype.renderInnerContent = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].renderFrame();
       }
     }
   };
-
   ICompElement.prototype.setElements = function (elems) {
     this.elements = elems;
   };
-
   ICompElement.prototype.getElements = function () {
     return this.elements;
   };
-
   ICompElement.prototype.destroyElements = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i]) {
         this.elements[i].destroy();
       }
     }
   };
-
   ICompElement.prototype.destroy = function () {
     this.destroyElements();
     this.destroyBaseElement();
@@ -12744,9 +10766,7 @@
       _placeholder: true
     };
   }
-
   extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
-
   SVGCompElement.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
@@ -12757,7 +10777,6 @@
     this.renderedFrame = -1;
     this.svgElement = createNS('svg');
     var ariaLabel = '';
-
     if (config && config.title) {
       var titleElement = createNS('title');
       var titleId = createElementID();
@@ -12766,7 +10785,6 @@
       this.svgElement.appendChild(titleElement);
       ariaLabel += titleId;
     }
-
     if (config && config.description) {
       var descElement = createNS('desc');
       var descId = createElementID();
@@ -12775,11 +10793,9 @@
       this.svgElement.appendChild(descElement);
       ariaLabel += ' ' + descId;
     }
-
     if (ariaLabel) {
       this.svgElement.setAttribute('aria-labelledby', ariaLabel);
     }
-
     var defs = createNS('defs');
     this.svgElement.appendChild(defs);
     var maskElement = createNS('g');
@@ -12817,63 +10833,50 @@
     this.destroyed = false;
     this.rendererType = 'svg';
   }
-
   extendPrototype([SVGRendererBase], SVGRenderer);
-
   SVGRenderer.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
 
   var registeredEffects = {};
-
   function CVEffects(elem) {
     var i;
     var len = elem.data.ef ? elem.data.ef.length : 0;
     this.filters = [];
     var filterManager;
-
     for (i = 0; i < len; i += 1) {
       filterManager = null;
       var type = elem.data.ef[i].ty;
-
       if (registeredEffects[type]) {
         var Effect = registeredEffects[type].effect;
         filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
       }
-
       if (filterManager) {
         this.filters.push(filterManager);
       }
     }
-
     if (this.filters.length) {
       elem.addRenderableComponent(this);
     }
   }
-
   CVEffects.prototype.renderFrame = function (_isFirstFrame) {
     var i;
     var len = this.filters.length;
-
     for (i = 0; i < len; i += 1) {
       this.filters[i].renderFrame(_isFirstFrame);
     }
   };
-
   CVEffects.prototype.getEffects = function (type) {
     var i;
     var len = this.filters.length;
     var effects = [];
-
     for (i = 0; i < len; i += 1) {
       if (this.filters[i].type === type) {
         effects.push(this.filters[i]);
       }
     }
-
     return effects;
   };
-
   function registerEffect(id, effect) {
     registeredEffects[id] = {
       effect: effect
@@ -12881,12 +10884,10 @@
   }
 
   function HBaseElement() {}
-
   HBaseElement.prototype = {
     checkBlendMode: function checkBlendMode() {},
     initRendererElement: function initRendererElement() {
       this.baseElement = createTag(this.data.tg || 'div');
-
       if (this.data.hasMask) {
         this.svgElement = createNS('svg');
         this.layerElement = createNS('g');
@@ -12896,35 +10897,29 @@
       } else {
         this.layerElement = this.baseElement;
       }
-
       styleDiv(this.baseElement);
     },
     createContainerElements: function createContainerElements() {
       this.renderableEffectsManager = new CVEffects(this);
       this.transformedElement = this.baseElement;
       this.maskedElement = this.layerElement;
-
       if (this.data.ln) {
         this.layerElement.setAttribute('id', this.data.ln);
       }
-
       if (this.data.cl) {
         this.layerElement.setAttribute('class', this.data.cl);
       }
-
       if (this.data.bm !== 0) {
         this.setBlendMode();
       }
     },
     renderElement: function renderElement() {
       var transformedElementStyle = this.transformedElement ? this.transformedElement.style : {};
-
       if (this.finalTransform._matMdf) {
         var matrixValue = this.finalTransform.mat.toCSS();
         transformedElementStyle.transform = matrixValue;
         transformedElementStyle.webkitTransform = matrixValue;
       }
-
       if (this.finalTransform._opMdf) {
         transformedElementStyle.opacity = this.finalTransform.mProp.o.v;
       }
@@ -12935,12 +10930,10 @@
       if (this.data.hd || this.hidden) {
         return;
       }
-
       this.renderTransform();
       this.renderRenderable();
       this.renderElement();
       this.renderInnerContent();
-
       if (this._isFirstFrame) {
         this._isFirstFrame = false;
       }
@@ -12948,11 +10941,9 @@
     destroy: function destroy() {
       this.layerElement = null;
       this.transformedElement = null;
-
       if (this.matteElement) {
         this.matteElement = null;
       }
-
       if (this.maskManager) {
         this.maskManager.destroy();
         this.maskManager = null;
@@ -12971,12 +10962,9 @@
   function HSolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], HSolidElement);
-
   HSolidElement.prototype.createContent = function () {
     var rect;
-
     if (this.data.hasMask) {
       rect = createNS('rect');
       rect.setAttribute('width', this.data.sw);
@@ -12990,29 +10978,28 @@
       rect.style.height = this.data.sh + 'px';
       rect.style.backgroundColor = this.data.sc;
     }
-
     this.layerElement.appendChild(rect);
   };
 
   function HShapeElement(data, globalData, comp) {
     // List of drawable elements
-    this.shapes = []; // Full shape data
-
-    this.shapesData = data.shapes; // List of styles that will be applied to shapes
-
-    this.stylesList = []; // List of modifiers that will be applied to shapes
-
-    this.shapeModifiers = []; // List of items in shape tree
-
-    this.itemsData = []; // List of items in previous shape tree
-
-    this.processedElements = []; // List of animated components
-
+    this.shapes = [];
+    // Full shape data
+    this.shapesData = data.shapes;
+    // List of styles that will be applied to shapes
+    this.stylesList = [];
+    // List of modifiers that will be applied to shapes
+    this.shapeModifiers = [];
+    // List of items in shape tree
+    this.itemsData = [];
+    // List of items in previous shape tree
+    this.processedElements = [];
+    // List of animated components
     this.animatedContents = [];
     this.shapesContainer = createNS('g');
-    this.initElement(data, globalData, comp); // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.initElement(data, globalData, comp);
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
     // List of elements that have been created
-
     this.prevViewData = [];
     this.currentBBox = {
       x: 999999,
@@ -13021,14 +11008,11 @@
       w: 0
     };
   }
-
   extendPrototype([BaseElement, TransformElement, HSolidElement, SVGShapeElement, HBaseElement, HierarchyElement, FrameElement, RenderableElement], HShapeElement);
   HShapeElement.prototype._renderShapeFrame = HShapeElement.prototype.renderInnerContent;
-
   HShapeElement.prototype.createContent = function () {
     var cont;
     this.baseElement.style.fontSize = 0;
-
     if (this.data.hasMask) {
       this.layerElement.appendChild(this.shapesContainer);
       cont = this.svgElement;
@@ -13040,23 +11024,18 @@
       cont.appendChild(this.shapesContainer);
       this.layerElement.appendChild(cont);
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.shapesContainer, 0, [], true);
     this.filterUniqueShapes();
     this.shapeCont = cont;
   };
-
   HShapeElement.prototype.getTransformedPoint = function (transformers, point) {
     var i;
     var len = transformers.length;
-
     for (i = 0; i < len; i += 1) {
       point = transformers[i].mProps.v.applyToPointArray(point[0], point[1], 0);
     }
-
     return point;
   };
-
   HShapeElement.prototype.calculateShapeBoundingBox = function (item, boundingBox) {
     var shape = item.sh.v;
     var transformers = item.transformers;
@@ -13066,11 +11045,9 @@
     var oPoint;
     var nextIPoint;
     var nextVPoint;
-
     if (len <= 1) {
       return;
     }
-
     for (i = 0; i < len - 1; i += 1) {
       vPoint = this.getTransformedPoint(transformers, shape.v[i]);
       oPoint = this.getTransformedPoint(transformers, shape.o[i]);
@@ -13078,7 +11055,6 @@
       nextVPoint = this.getTransformedPoint(transformers, shape.v[i + 1]);
       this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
     }
-
     if (shape.c) {
       vPoint = this.getTransformedPoint(transformers, shape.v[i]);
       oPoint = this.getTransformedPoint(transformers, shape.o[i]);
@@ -13087,7 +11063,6 @@
       this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
     }
   };
-
   HShapeElement.prototype.checkBounds = function (vPoint, oPoint, nextIPoint, nextVPoint, boundingBox) {
     this.getBoundsOfCurve(vPoint, oPoint, nextIPoint, nextVPoint);
     var bounds = this.shapeBoundingBox;
@@ -13096,7 +11071,6 @@
     boundingBox.y = bmMin(bounds.top, boundingBox.y);
     boundingBox.yMax = bmMax(bounds.bottom, boundingBox.yMax);
   };
-
   HShapeElement.prototype.shapeBoundingBox = {
     left: 0,
     right: 0,
@@ -13111,31 +11085,26 @@
     width: 0,
     height: 0
   };
-
   HShapeElement.prototype.getBoundsOfCurve = function (p0, p1, p2, p3) {
     var bounds = [[p0[0], p3[0]], [p0[1], p3[1]]];
-
     for (var a, b, c, t, b2ac, t1, t2, i = 0; i < 2; ++i) {
       // eslint-disable-line no-plusplus
       b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];
       a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];
       c = 3 * p1[i] - 3 * p0[i];
       b |= 0; // eslint-disable-line no-bitwise
-
       a |= 0; // eslint-disable-line no-bitwise
-
       c |= 0; // eslint-disable-line no-bitwise
 
-      if (a === 0 && b === 0) {//
+      if (a === 0 && b === 0) {
+        //
       } else if (a === 0) {
         t = -c / b;
-
         if (t > 0 && t < 1) {
           bounds[i].push(this.calculateF(t, p0, p1, p2, p3, i));
         }
       } else {
         b2ac = b * b - 4 * c * a;
-
         if (b2ac >= 0) {
           t1 = (-b + bmSqrt(b2ac)) / (2 * a);
           if (t1 > 0 && t1 < 1) bounds[i].push(this.calculateF(t1, p0, p1, p2, p3, i));
@@ -13144,21 +11113,17 @@
         }
       }
     }
-
     this.shapeBoundingBox.left = bmMin.apply(null, bounds[0]);
     this.shapeBoundingBox.top = bmMin.apply(null, bounds[1]);
     this.shapeBoundingBox.right = bmMax.apply(null, bounds[0]);
     this.shapeBoundingBox.bottom = bmMax.apply(null, bounds[1]);
   };
-
   HShapeElement.prototype.calculateF = function (t, p0, p1, p2, p3, i) {
     return bmPow(1 - t, 3) * p0[i] + 3 * bmPow(1 - t, 2) * t * p1[i] + 3 * (1 - t) * bmPow(t, 2) * p2[i] + bmPow(t, 3) * p3[i];
   };
-
   HShapeElement.prototype.calculateBoundingBox = function (itemsData, boundingBox) {
     var i;
     var len = itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       if (itemsData[i] && itemsData[i].sh) {
         this.calculateShapeBoundingBox(itemsData[i], boundingBox);
@@ -13169,37 +11134,29 @@
       }
     }
   };
-
   HShapeElement.prototype.expandStrokeBoundingBox = function (widthProperty, boundingBox) {
     var width = 0;
-
     if (widthProperty.keyframes) {
       for (var i = 0; i < widthProperty.keyframes.length; i += 1) {
         var kfw = widthProperty.keyframes[i].s;
-
         if (kfw > width) {
           width = kfw;
         }
       }
-
       width *= widthProperty.mult;
     } else {
       width = widthProperty.v * widthProperty.mult;
     }
-
     boundingBox.x -= width;
     boundingBox.xMax += width;
     boundingBox.y -= width;
     boundingBox.yMax += width;
   };
-
   HShapeElement.prototype.currentBoxContains = function (box) {
     return this.currentBBox.x <= box.x && this.currentBBox.y <= box.y && this.currentBBox.width + this.currentBBox.x >= box.x + box.width && this.currentBBox.height + this.currentBBox.y >= box.y + box.height;
   };
-
   HShapeElement.prototype.renderInnerContent = function () {
     this._renderShapeFrame();
-
     if (!this.hidden && (this._isFirstFrame || this._mdf)) {
       var tempBoundingBox = this.tempBoundingBox;
       var max = 999999;
@@ -13209,26 +11166,22 @@
       tempBoundingBox.yMax = -max;
       this.calculateBoundingBox(this.itemsData, tempBoundingBox);
       tempBoundingBox.width = tempBoundingBox.xMax < tempBoundingBox.x ? 0 : tempBoundingBox.xMax - tempBoundingBox.x;
-      tempBoundingBox.height = tempBoundingBox.yMax < tempBoundingBox.y ? 0 : tempBoundingBox.yMax - tempBoundingBox.y; // var tempBoundingBox = this.shapeCont.getBBox();
-
+      tempBoundingBox.height = tempBoundingBox.yMax < tempBoundingBox.y ? 0 : tempBoundingBox.yMax - tempBoundingBox.y;
+      // var tempBoundingBox = this.shapeCont.getBBox();
       if (this.currentBoxContains(tempBoundingBox)) {
         return;
       }
-
       var changed = false;
-
       if (this.currentBBox.w !== tempBoundingBox.width) {
         this.currentBBox.w = tempBoundingBox.width;
         this.shapeCont.setAttribute('width', tempBoundingBox.width);
         changed = true;
       }
-
       if (this.currentBBox.h !== tempBoundingBox.height) {
         this.currentBBox.h = tempBoundingBox.height;
         this.shapeCont.setAttribute('height', tempBoundingBox.height);
         changed = true;
       }
-
       if (changed || this.currentBBox.x !== tempBoundingBox.x || this.currentBBox.y !== tempBoundingBox.y) {
         this.currentBBox.w = tempBoundingBox.width;
         this.currentBBox.h = tempBoundingBox.height;
@@ -13256,12 +11209,9 @@
     this.isMasked = false;
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], HTextElement);
-
   HTextElement.prototype.createContent = function () {
     this.isMasked = this.checkMasks();
-
     if (this.isMasked) {
       this.renderType = 'svg';
       this.compW = this.comp.data.w;
@@ -13275,10 +11225,8 @@
       this.renderType = 'html';
       this.innerElem = this.layerElement;
     }
-
     this.checkParenting();
   };
-
   HTextElement.prototype.buildNewText = function () {
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
@@ -13286,18 +11234,14 @@
     var textColor = documentData.fc ? this.buildColor(documentData.fc) : 'rgba(0,0,0,0)';
     innerElemStyle.fill = textColor;
     innerElemStyle.color = textColor;
-
     if (documentData.sc) {
       innerElemStyle.stroke = this.buildColor(documentData.sc);
       innerElemStyle.strokeWidth = documentData.sw + 'px';
     }
-
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
-
     if (!this.globalData.fontManager.chars) {
       innerElemStyle.fontSize = documentData.finalSize + 'px';
       innerElemStyle.lineHeight = documentData.finalSize + 'px';
-
       if (fontData.fClass) {
         this.innerElem.className = fontData.fClass;
       } else {
@@ -13308,7 +11252,6 @@
         innerElemStyle.fontWeight = fWeight;
       }
     }
-
     var i;
     var len;
     var letters = documentData.l;
@@ -13320,7 +11263,6 @@
     var shapes;
     var shapeStr = '';
     var cnt = 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.globalData.fontManager.chars) {
         if (!this.textPaths[cnt]) {
@@ -13331,7 +11273,6 @@
         } else {
           tSpan = this.textPaths[cnt];
         }
-
         if (!this.isMasked) {
           if (this.textSpans[cnt]) {
             tParent = this.textSpans[cnt];
@@ -13357,31 +11298,25 @@
         }
       } else {
         tSpan = this.textPaths[cnt] ? this.textPaths[cnt] : createNS('text');
-      } // tSpan.setAttribute('visibility', 'hidden');
-
-
+      }
+      // tSpan.setAttribute('visibility', 'hidden');
       if (this.globalData.fontManager.chars) {
         var charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
         var shapeData;
-
         if (charData) {
           shapeData = charData.data;
         } else {
           shapeData = null;
         }
-
         matrixHelper.reset();
-
         if (shapeData && shapeData.shapes && shapeData.shapes.length) {
           shapes = shapeData.shapes[0].it;
           matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
           shapeStr = this.createPathShape(matrixHelper, shapes);
           tSpan.setAttribute('d', shapeStr);
         }
-
         if (!this.isMasked) {
           this.innerElem.appendChild(tParent);
-
           if (shapeData && shapeData.shapes) {
             // document.body.appendChild is needed to get exact measure of shape
             document.body.appendChild(tCont);
@@ -13398,7 +11333,6 @@
             tCont.setAttribute('width', 1);
             tCont.setAttribute('height', 1);
           }
-
           tParent.appendChild(tCont);
         } else {
           this.innerElem.appendChild(tSpan);
@@ -13406,10 +11340,9 @@
       } else {
         tSpan.textContent = letters[i].val;
         tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
-
         if (!this.isMasked) {
-          this.innerElem.appendChild(tParent); //
-
+          this.innerElem.appendChild(tParent);
+          //
           var tStyle = tSpan.style;
           var tSpanTranslation = 'translate3d(0,' + -documentData.finalSize / 1.2 + 'px,0)';
           tStyle.transform = tSpanTranslation;
@@ -13417,35 +11350,29 @@
         } else {
           this.innerElem.appendChild(tSpan);
         }
-      } //
-
-
+      }
+      //
       if (!this.isMasked) {
         this.textSpans[cnt] = tParent;
       } else {
         this.textSpans[cnt] = tSpan;
       }
-
       this.textSpans[cnt].style.display = 'block';
       this.textPaths[cnt] = tSpan;
       cnt += 1;
     }
-
     while (cnt < this.textSpans.length) {
       this.textSpans[cnt].style.display = 'none';
       cnt += 1;
     }
   };
-
   HTextElement.prototype.renderInnerContent = function () {
     this.validateText();
     var svgStyle;
-
     if (this.data.singleShape) {
       if (!this._isFirstFrame && !this.lettersChangedFlag) {
         return;
       }
-
       if (this.isMasked && this.finalTransform._matMdf) {
         // Todo Benchmark if using this is better than getBBox
         this.svgElement.setAttribute('viewBox', -this.finalTransform.mProp.p.v[0] + ' ' + -this.finalTransform.mProp.p.v[1] + ' ' + this.compW + ' ' + this.compH);
@@ -13455,13 +11382,10 @@
         svgStyle.webkitTransform = translation;
       }
     }
-
     this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
-
     if (!this.lettersChangedFlag && !this.textAnimator.lettersChangedFlag) {
       return;
     }
-
     var i;
     var len;
     var count = 0;
@@ -13471,7 +11395,6 @@
     var renderedLetter;
     var textSpan;
     var textPath;
-
     for (i = 0; i < len; i += 1) {
       if (letters[i].n) {
         count += 1;
@@ -13480,7 +11403,6 @@
         textPath = this.textPaths[i];
         renderedLetter = renderedLetters[count];
         count += 1;
-
         if (renderedLetter._mdf.m) {
           if (!this.isMasked) {
             textSpan.style.webkitTransform = renderedLetter.m;
@@ -13488,41 +11410,32 @@
           } else {
             textSpan.setAttribute('transform', renderedLetter.m);
           }
-        } /// /textSpan.setAttribute('opacity',renderedLetter.o);
-
-
+        }
+        /// /textSpan.setAttribute('opacity',renderedLetter.o);
         textSpan.style.opacity = renderedLetter.o;
-
         if (renderedLetter.sw && renderedLetter._mdf.sw) {
           textPath.setAttribute('stroke-width', renderedLetter.sw);
         }
-
         if (renderedLetter.sc && renderedLetter._mdf.sc) {
           textPath.setAttribute('stroke', renderedLetter.sc);
         }
-
         if (renderedLetter.fc && renderedLetter._mdf.fc) {
           textPath.setAttribute('fill', renderedLetter.fc);
           textPath.style.color = renderedLetter.fc;
         }
       }
     }
-
     if (this.innerElem.getBBox && !this.hidden && (this._isFirstFrame || this._mdf)) {
       var boundingBox = this.innerElem.getBBox();
-
       if (this.currentBBox.w !== boundingBox.width) {
         this.currentBBox.w = boundingBox.width;
         this.svgElement.setAttribute('width', boundingBox.width);
       }
-
       if (this.currentBBox.h !== boundingBox.height) {
         this.currentBBox.h = boundingBox.height;
         this.svgElement.setAttribute('height', boundingBox.height);
       }
-
       var margin = 1;
-
       if (this.currentBBox.w !== boundingBox.width + margin * 2 || this.currentBBox.h !== boundingBox.height + margin * 2 || this.currentBBox.x !== boundingBox.x - margin || this.currentBBox.y !== boundingBox.y - margin) {
         this.currentBBox.w = boundingBox.width + margin * 2;
         this.currentBBox.h = boundingBox.height + margin * 2;
@@ -13543,7 +11456,6 @@
     this.initHierarchy();
     var getProp = PropertyFactory.getProp;
     this.pe = getProp(this, data.pe, 0, 0, this);
-
     if (data.ks.p.s) {
       this.px = getProp(this, data.ks.p.x, 1, 0, this);
       this.py = getProp(this, data.ks.p.y, 1, 0, this);
@@ -13551,21 +11463,17 @@
     } else {
       this.p = getProp(this, data.ks.p, 1, 0, this);
     }
-
     if (data.ks.a) {
       this.a = getProp(this, data.ks.a, 1, 0, this);
     }
-
     if (data.ks.or.k.length && data.ks.or.k[0].to) {
       var i;
       var len = data.ks.or.k.length;
-
       for (i = 0; i < len; i += 1) {
         data.ks.or.k[i].to = null;
         data.ks.or.k[i].ti = null;
       }
     }
-
     this.or = getProp(this, data.ks.or, 1, degToRads, this);
     this.or.sh = true;
     this.rx = getProp(this, data.ks.rx, 0, degToRads, this);
@@ -13573,26 +11481,23 @@
     this.rz = getProp(this, data.ks.rz, 0, degToRads, this);
     this.mat = new Matrix();
     this._prevMat = new Matrix();
-    this._isFirstFrame = true; // TODO: find a better way to make the HCamera element to be compatible with the LayerInterface and TransformInterface.
+    this._isFirstFrame = true;
 
+    // TODO: find a better way to make the HCamera element to be compatible with the LayerInterface and TransformInterface.
     this.finalTransform = {
       mProp: this
     };
   }
-
   extendPrototype([BaseElement, FrameElement, HierarchyElement], HCameraElement);
-
   HCameraElement.prototype.setup = function () {
     var i;
     var len = this.comp.threeDElements.length;
     var comp;
     var perspectiveStyle;
     var containerStyle;
-
     for (i = 0; i < len; i += 1) {
       // [perspectiveElem,container]
       comp = this.comp.threeDElements[i];
-
       if (comp.type === '3d') {
         perspectiveStyle = comp.perspectiveElem.style;
         containerStyle = comp.container.style;
@@ -13609,30 +11514,22 @@
       }
     }
   };
-
   HCameraElement.prototype.createElements = function () {};
-
   HCameraElement.prototype.hide = function () {};
-
   HCameraElement.prototype.renderFrame = function () {
     var _mdf = this._isFirstFrame;
     var i;
     var len;
-
     if (this.hierarchy) {
       len = this.hierarchy.length;
-
       for (i = 0; i < len; i += 1) {
         _mdf = this.hierarchy[i].finalTransform.mProp._mdf || _mdf;
       }
     }
-
     if (_mdf || this.pe._mdf || this.p && this.p._mdf || this.px && (this.px._mdf || this.py._mdf || this.pz._mdf) || this.rx._mdf || this.ry._mdf || this.rz._mdf || this.or._mdf || this.a && this.a._mdf) {
       this.mat.reset();
-
       if (this.hierarchy) {
         len = this.hierarchy.length - 1;
-
         for (i = len; i >= 0; i -= 1) {
           var mTransf = this.hierarchy[i].finalTransform.mProp;
           this.mat.translate(-mTransf.p.v[0], -mTransf.p.v[1], mTransf.p.v[2]);
@@ -13642,46 +11539,38 @@
           this.mat.translate(mTransf.a.v[0], mTransf.a.v[1], mTransf.a.v[2]);
         }
       }
-
       if (this.p) {
         this.mat.translate(-this.p.v[0], -this.p.v[1], this.p.v[2]);
       } else {
         this.mat.translate(-this.px.v, -this.py.v, this.pz.v);
       }
-
       if (this.a) {
         var diffVector;
-
         if (this.p) {
           diffVector = [this.p.v[0] - this.a.v[0], this.p.v[1] - this.a.v[1], this.p.v[2] - this.a.v[2]];
         } else {
           diffVector = [this.px.v - this.a.v[0], this.py.v - this.a.v[1], this.pz.v - this.a.v[2]];
         }
-
-        var mag = Math.sqrt(Math.pow(diffVector[0], 2) + Math.pow(diffVector[1], 2) + Math.pow(diffVector[2], 2)); // var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
-
+        var mag = Math.sqrt(Math.pow(diffVector[0], 2) + Math.pow(diffVector[1], 2) + Math.pow(diffVector[2], 2));
+        // var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
         var lookDir = [diffVector[0] / mag, diffVector[1] / mag, diffVector[2] / mag];
         var lookLengthOnXZ = Math.sqrt(lookDir[2] * lookDir[2] + lookDir[0] * lookDir[0]);
         var mRotationX = Math.atan2(lookDir[1], lookLengthOnXZ);
         var mRotationY = Math.atan2(lookDir[0], -lookDir[2]);
         this.mat.rotateY(mRotationY).rotateX(-mRotationX);
       }
-
       this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v);
       this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]);
       this.mat.translate(this.globalData.compSize.w / 2, this.globalData.compSize.h / 2, 0);
       this.mat.translate(0, 0, this.pe.v);
       var hasMatrixChanged = !this._prevMat.equals(this.mat);
-
       if ((hasMatrixChanged || this.pe._mdf) && this.comp.threeDElements) {
         len = this.comp.threeDElements.length;
         var comp;
         var perspectiveStyle;
         var containerStyle;
-
         for (i = 0; i < len; i += 1) {
           comp = this.comp.threeDElements[i];
-
           if (comp.type === '3d') {
             if (hasMatrixChanged) {
               var matValue = this.mat.toCSS();
@@ -13689,7 +11578,6 @@
               containerStyle.transform = matValue;
               containerStyle.webkitTransform = matValue;
             }
-
             if (this.pe._mdf) {
               perspectiveStyle = comp.perspectiveElem.style;
               perspectiveStyle.perspective = this.pe.v + 'px';
@@ -13697,20 +11585,15 @@
             }
           }
         }
-
         this.mat.clone(this._prevMat);
       }
     }
-
     this._isFirstFrame = false;
   };
-
   HCameraElement.prototype.prepareFrame = function (num) {
     this.prepareProperties(num, true);
   };
-
   HCameraElement.prototype.destroy = function () {};
-
   HCameraElement.prototype.getBaseElement = function () {
     return null;
   };
@@ -13719,13 +11602,10 @@
     this.assetData = globalData.getAssetData(data.refId);
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, HBaseElement, HSolidElement, HierarchyElement, FrameElement, RenderableElement], HImageElement);
-
   HImageElement.prototype.createContent = function () {
     var assetPath = this.globalData.getAssetsPath(this.assetData);
     var img = new Image();
-
     if (this.data.hasMask) {
       this.imageElem = createNS('image');
       this.imageElem.setAttribute('width', this.assetData.w + 'px');
@@ -13737,10 +11617,8 @@
     } else {
       this.layerElement.appendChild(img);
     }
-
     img.crossOrigin = 'anonymous';
     img.src = assetPath;
-
     if (this.data.ln) {
       this.baseElement.setAttribute('id', this.data.ln);
     }
@@ -13774,26 +11652,20 @@
     this.supports3d = true;
     this.rendererType = 'html';
   }
-
   extendPrototype([BaseRenderer], HybridRendererBase);
   HybridRendererBase.prototype.buildItem = SVGRenderer.prototype.buildItem;
-
   HybridRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
     }
   };
-
   HybridRendererBase.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);
@@ -13802,17 +11674,14 @@
         var nextDOMElement;
         var nextLayer;
         var 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);
@@ -13825,61 +11694,46 @@
       this.addTo3dContainer(newDOMElement, pos);
     }
   };
-
   HybridRendererBase.prototype.createShape = function (data) {
     if (!this.supports3d) {
       return new SVGShapeElement(data, this.globalData, this);
     }
-
     return new HShapeElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createText = function (data) {
     if (!this.supports3d) {
       return new SVGTextLottieElement(data, this.globalData, this);
     }
-
     return new HTextElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createCamera = function (data) {
     this.camera = new HCameraElement(data, this.globalData, this);
     return this.camera;
   };
-
   HybridRendererBase.prototype.createImage = function (data) {
     if (!this.supports3d) {
       return new IImageElement(data, this.globalData, this);
     }
-
     return new HImageElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createSolid = function (data) {
     if (!this.supports3d) {
       return new ISolidElement(data, this.globalData, this);
     }
-
     return new HSolidElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
-
   HybridRendererBase.prototype.getThreeDContainerByPos = function (pos) {
     var i = 0;
     var 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;
     }
-
     return null;
   };
-
   HybridRendererBase.prototype.createThreeDContainer = function (pos, type) {
     var perspectiveElem = createTag('div');
     var style;
@@ -13887,7 +11741,6 @@
     styleDiv(perspectiveElem);
     var container = createTag('div');
     styleDiv(container);
-
     if (type === '3d') {
       style = perspectiveElem.style;
       style.width = this.globalData.compSize.w + 'px';
@@ -13901,9 +11754,8 @@
       containerStyle.transform = matrix;
       containerStyle.webkitTransform = matrix;
     }
-
-    perspectiveElem.appendChild(container); // this.resizerElem.appendChild(perspectiveElem);
-
+    perspectiveElem.appendChild(container);
+    // this.resizerElem.appendChild(perspectiveElem);
     var threeDContainerData = {
       container: container,
       perspectiveElem: perspectiveElem,
@@ -13914,68 +11766,54 @@
     this.threeDElements.push(threeDContainerData);
     return threeDContainerData;
   };
-
   HybridRendererBase.prototype.build3dContainers = function () {
     var i;
     var 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 -= 1) {
       this.resizerElem.appendChild(this.threeDElements[i].perspectiveElem);
     }
   };
-
   HybridRendererBase.prototype.addTo3dContainer = function (elem, pos) {
     var i = 0;
     var 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;
     }
   };
-
   HybridRendererBase.prototype.configAnimation = function (animData) {
     var resizerElem = createTag('div');
     var wrapper = this.animationItem.wrapper;
@@ -13987,11 +11825,9 @@
     style.transformStyle = 'flat';
     style.mozTransformStyle = 'flat';
     style.webkitTransformStyle = 'flat';
-
     if (this.renderConfig.className) {
       resizerElem.setAttribute('class', this.renderConfig.className);
     }
-
     wrapper.appendChild(resizerElem);
     style.overflow = 'hidden';
     var svg = createNS('svg');
@@ -14001,8 +11837,8 @@
     this.resizerElem.appendChild(svg);
     var defs = createNS('defs');
     svg.appendChild(defs);
-    this.data = animData; // Mask animation
-
+    this.data = animData;
+    // Mask animation
     this.setupGlobalData(animData, svg);
     this.globalData.defs = defs;
     this.layers = animData.layers;
@@ -14010,28 +11846,23 @@
     this.build3dContainers();
     this.updateContainerSize();
   };
-
   HybridRendererBase.prototype.destroy = function () {
     if (this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     this.animationItem.container = null;
     this.globalData.defs = null;
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.destroyed = true;
     this.animationItem = null;
   };
-
   HybridRendererBase.prototype.updateContainerSize = function () {
     var elementWidth = this.animationItem.wrapper.offsetWidth;
     var elementHeight = this.animationItem.wrapper.offsetHeight;
@@ -14041,7 +11872,6 @@
     var sy;
     var tx;
     var ty;
-
     if (animationRel > elementRel) {
       sx = elementWidth / this.globalData.compSize.w;
       sy = elementWidth / this.globalData.compSize.w;
@@ -14053,25 +11883,19 @@
       tx = (elementWidth - this.globalData.compSize.w * (elementHeight / this.globalData.compSize.h)) / 2;
       ty = 0;
     }
-
     var style = this.resizerElem.style;
     style.webkitTransform = 'matrix3d(' + sx + ',0,0,0,0,' + sy + ',0,0,0,0,1,0,' + tx + ',' + ty + ',0,1)';
     style.transform = style.webkitTransform;
   };
-
   HybridRendererBase.prototype.renderFrame = SVGRenderer.prototype.renderFrame;
-
   HybridRendererBase.prototype.hide = function () {
     this.resizerElem.style.display = 'none';
   };
-
   HybridRendererBase.prototype.show = function () {
     this.resizerElem.style.display = 'block';
   };
-
   HybridRendererBase.prototype.initItems = function () {
     this.buildAllItems();
-
     if (this.camera) {
       this.camera.setup();
     } else {
@@ -14079,7 +11903,6 @@
       var cHeight = this.globalData.compSize.h;
       var i;
       var len = this.threeDElements.length;
-
       for (i = 0; i < len; i += 1) {
         var style = this.threeDElements[i].perspectiveElem.style;
         style.webkitPerspective = Math.sqrt(Math.pow(cWidth, 2) + Math.pow(cHeight, 2)) + 'px';
@@ -14087,12 +11910,10 @@
       }
     }
   };
-
   HybridRendererBase.prototype.searchExtraCompositions = function (assets) {
     var i;
     var 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);
@@ -14113,14 +11934,11 @@
       _placeholder: true
     };
   }
-
   extendPrototype([HybridRendererBase, ICompElement, HBaseElement], HCompElement);
   HCompElement.prototype._createBaseContainerElements = HCompElement.prototype.createContainerElements;
-
   HCompElement.prototype.createContainerElements = function () {
-    this._createBaseContainerElements(); // divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
-
-
+    this._createBaseContainerElements();
+    // divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
     if (this.data.hasMask) {
       this.svgElement.setAttribute('width', this.data.w);
       this.svgElement.setAttribute('height', this.data.h);
@@ -14129,31 +11947,25 @@
       this.transformedElement = this.layerElement;
     }
   };
-
   HCompElement.prototype.addTo3dContainer = function (elem, pos) {
     var j = 0;
     var nextElement;
-
     while (j < pos) {
       if (this.elements[j] && this.elements[j].getBaseElement) {
         nextElement = this.elements[j].getBaseElement();
       }
-
       j += 1;
     }
-
     if (nextElement) {
       this.layerElement.insertBefore(elem, nextElement);
     } else {
       this.layerElement.appendChild(elem);
     }
   };
-
   HCompElement.prototype.createComp = function (data) {
     if (!this.supports3d) {
       return new SVGCompElement(data, this.globalData, this);
     }
-
     return new HCompElement(data, this.globalData, this);
   };
 
@@ -14186,19 +11998,18 @@
     this.supports3d = true;
     this.rendererType = 'html';
   }
-
   extendPrototype([HybridRendererBase], HybridRenderer);
-
   HybridRenderer.prototype.createComp = function (data) {
     if (!this.supports3d) {
       return new SVGCompElement(data, this.globalData, this);
     }
-
     return new HCompElement(data, this.globalData, this);
   };
 
-  registerRenderer('html', HybridRenderer); // Registering shape modifiers
+  // Registering renderers
+  registerRenderer('html', HybridRenderer);
 
+  // Registering shape modifiers
   ShapeModifiers.registerModifier('tm', TrimModifier);
   ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
   ShapeModifiers.registerModifier('rp', RepeaterModifier);
@@ -14211,18 +12022,15 @@
       function _thisLayerFunction(name) {
         var i = 0;
         var len = comp.layers.length;
-
         while (i < len) {
           if (comp.layers[i].nm === name || comp.layers[i].ind === name) {
             return comp.elements[i].layerInterface;
           }
-
           i += 1;
         }
-
-        return null; // return {active:false};
+        return null;
+        // return {active:false};
       }
-
       Object.defineProperty(_thisLayerFunction, '_name', {
         value: comp.data.nm
       });
@@ -14238,10 +12046,8 @@
     };
   }();
 
-  function _typeof$2(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$2 = function _typeof(obj) { return typeof obj; }; } else { _typeof$2 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$2(obj); }
-
+  function _typeof$2(o) { "@babel/helpers - typeof"; return _typeof$2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$2(o); }
   /* eslint-disable */
-
   /*
    Copyright 2014 David Bau.
 
@@ -14265,105 +12071,103 @@
    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
    */
+
   function seedRandom(pool, math) {
     //
     // The following constants are related to IEEE 754 limits.
     //
     var global = this,
-        width = 256,
-        // each RC4 output is 0 <= x < 256
-    chunks = 6,
-        // at least six RC4 outputs for each double
-    digits = 52,
-        // there are 52 significant digits in a double
-    rngname = 'random',
-        // rngname: name for Math.random and Math.seedrandom
-    startdenom = math.pow(width, chunks),
-        significance = math.pow(2, digits),
-        overflow = significance * 2,
-        mask = width - 1,
-        nodecrypto; // node.js crypto module, initialized at the bottom.
+      width = 256,
+      // each RC4 output is 0 <= x < 256
+      chunks = 6,
+      // at least six RC4 outputs for each double
+      digits = 52,
+      // there are 52 significant digits in a double
+      rngname = 'random',
+      // rngname: name for Math.random and Math.seedrandom
+      startdenom = math.pow(width, chunks),
+      significance = math.pow(2, digits),
+      overflow = significance * 2,
+      mask = width - 1,
+      nodecrypto; // node.js crypto module, initialized at the bottom.
+
     //
     // seedrandom()
     // This is the seedrandom function described above.
     //
-
     function seedrandom(seed, options, callback) {
       var key = [];
       options = options === true ? {
         entropy: true
-      } : options || {}; // Flatten the seed string or build one from local entropy if needed.
+      } : options || {};
 
-      var shortseed = mixkey(flatten(options.entropy ? [seed, tostring(pool)] : seed === null ? autoseed() : seed, 3), key); // Use the seed to initialize an ARC4 generator.
+      // Flatten the seed string or build one from local entropy if needed.
+      var shortseed = mixkey(flatten(options.entropy ? [seed, tostring(pool)] : seed === null ? autoseed() : seed, 3), key);
 
-      var arc4 = new ARC4(key); // This function returns a random double in [0, 1) that contains
+      // Use the seed to initialize an ARC4 generator.
+      var arc4 = new ARC4(key);
+
+      // This function returns a random double in [0, 1) that contains
       // randomness in every bit of the mantissa of the IEEE 754 value.
-
       var prng = function prng() {
         var n = arc4.g(chunks),
-            // Start with a numerator n < 2 ^ 48
-        d = startdenom,
-            //   and denominator d = 2 ^ 48.
-        x = 0; //   and no 'extra last byte'.
-
+          // Start with a numerator n < 2 ^ 48
+          d = startdenom,
+          //   and denominator d = 2 ^ 48.
+          x = 0; //   and no 'extra last byte'.
         while (n < significance) {
           // Fill up all significant digits by
           n = (n + x) * width; //   shifting numerator and
-
           d *= width; //   denominator and generating a
-
           x = arc4.g(1); //   new least-significant-byte.
         }
-
         while (n >= overflow) {
           // To avoid rounding up, before adding
           n /= 2; //   last byte, shift everything
-
           d /= 2; //   right using integer math until
-
           x >>>= 1; //   we have exactly the desired bits.
         }
-
         return (n + x) / d; // Form the number within [0, 1).
       };
-
       prng.int32 = function () {
         return arc4.g(4) | 0;
       };
-
       prng.quick = function () {
         return arc4.g(4) / 0x100000000;
       };
+      prng["double"] = prng;
 
-      prng["double"] = prng; // Mix the randomness into accumulated entropy.
+      // Mix the randomness into accumulated entropy.
+      mixkey(tostring(arc4.S), pool);
 
-      mixkey(tostring(arc4.S), pool); // Calling convention: what to return as a function of prng, seed, is_math.
-
+      // Calling convention: what to return as a function of prng, seed, is_math.
       return (options.pass || callback || function (prng, seed, is_math_call, state) {
         if (state) {
           // Load the arc4 state from the given state if it has an S array.
           if (state.S) {
             copy(state, arc4);
-          } // Only provide the .state method if requested via options.state.
-
-
+          }
+          // Only provide the .state method if requested via options.state.
           prng.state = function () {
             return copy(arc4, {});
           };
-        } // If called as a method of Math (Math.seedrandom()), mutate
+        }
+
+        // If called as a method of Math (Math.seedrandom()), mutate
         // Math.random because that is how seedrandom.js has worked since v1.0.
-
-
         if (is_math_call) {
           math[rngname] = prng;
           return seed;
-        } // Otherwise, it is a newer calling convention, so return the
+        }
+
+        // Otherwise, it is a newer calling convention, so return the
         // prng directly.
         else return prng;
       })(prng, shortseed, 'global' in options ? options.global : this == math, options.state);
     }
+    math['seed' + rngname] = seedrandom;
 
-    math['seed' + rngname] = seedrandom; //
+    //
     // ARC4
     //
     // An ARC4 implementation.  The constructor takes a key in the form of
@@ -14373,71 +12177,68 @@
     // the next (count) outputs from ARC4.  Its return value is a number x
     // that is in the range 0 <= x < (width ^ count).
     //
-
     function ARC4(key) {
       var t,
-          keylen = key.length,
-          me = this,
-          i = 0,
-          j = me.i = me.j = 0,
-          s = me.S = []; // The empty key [] is treated as [0].
+        keylen = key.length,
+        me = this,
+        i = 0,
+        j = me.i = me.j = 0,
+        s = me.S = [];
 
+      // The empty key [] is treated as [0].
       if (!keylen) {
         key = [keylen++];
-      } // Set up S using the standard key scheduling algorithm.
+      }
 
-
+      // Set up S using the standard key scheduling algorithm.
       while (i < width) {
         s[i] = i++;
       }
-
       for (i = 0; i < width; i++) {
         s[i] = s[j = mask & j + key[i % keylen] + (t = s[i])];
         s[j] = t;
-      } // The "g" method returns the next (count) outputs as one number.
+      }
 
-
+      // The "g" method returns the next (count) outputs as one number.
       me.g = function (count) {
         // Using instance members instead of closure state nearly doubles speed.
         var t,
-            r = 0,
-            i = me.i,
-            j = me.j,
-            s = me.S;
-
+          r = 0,
+          i = me.i,
+          j = me.j,
+          s = me.S;
         while (count--) {
           t = s[i = mask & i + 1];
           r = r * width + s[mask & (s[i] = s[j = mask & j + t]) + (s[j] = t)];
         }
-
         me.i = i;
         me.j = j;
-        return r; // For robust unpredictability, the function call below automatically
+        return r;
+        // For robust unpredictability, the function call below automatically
         // discards an initial batch of values.  This is called RC4-drop[256].
         // See http://google.com/search?q=rsa+fluhrer+response&btnI
       };
-    } //
+    }
+
+    //
     // copy()
     // Copies internal state of ARC4 to or from a plain object.
     //
-
-
     function copy(f, t) {
       t.i = f.i;
       t.j = f.j;
       t.S = f.S.slice();
       return t;
-    } //
+    }
+
+    //
     // flatten()
     // Converts an object tree to nested arrays of strings.
     //
-
-
     function flatten(obj, depth) {
       var result = [],
-          typ = _typeof$2(obj),
-          prop;
-
+        typ = _typeof$2(obj),
+        prop;
       if (depth && typ == 'object') {
         for (prop in obj) {
           try {
@@ -14445,72 +12246,69 @@
           } catch (e) {}
         }
       }
-
       return result.length ? result : typ == 'string' ? obj : obj + '\0';
-    } //
+    }
+
+    //
     // mixkey()
     // Mixes a string seed into a key that is an array of integers, and
     // returns a shortened string seed that is equivalent to the result key.
     //
-
-
     function mixkey(seed, key) {
       var stringseed = seed + '',
-          smear,
-          j = 0;
-
+        smear,
+        j = 0;
       while (j < stringseed.length) {
         key[mask & j] = mask & (smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++);
       }
-
       return tostring(key);
-    } //
+    }
+
+    //
     // autoseed()
     // Returns an object for autoseeding, using window.crypto and Node crypto
     // module if available.
     //
-
-
     function autoseed() {
       try {
         if (nodecrypto) {
           return tostring(nodecrypto.randomBytes(width));
         }
-
         var out = new Uint8Array(width);
         (global.crypto || global.msCrypto).getRandomValues(out);
         return tostring(out);
       } catch (e) {
         var browser = global.navigator,
-            plugins = browser && browser.plugins;
+          plugins = browser && browser.plugins;
         return [+new Date(), global, plugins, global.screen, tostring(pool)];
       }
-    } //
+    }
+
+    //
     // tostring()
     // Converts an array of charcodes to a string
     //
-
-
     function tostring(a) {
       return String.fromCharCode.apply(0, a);
-    } //
+    }
+
+    //
     // When seedrandom.js is loaded, we immediately mix a few bits
     // from the built-in RNG into the entropy pool.  Because we do
     // not want to interfere with deterministic PRNG state later,
     // seedrandom will not call math.random on its own again after
     // initialization.
     //
+    mixkey(math.random(), pool);
 
-
-    mixkey(math.random(), pool); //
+    //
     // Nodejs and AMD support: export the implementation as a module using
     // either convention.
     //
+
     // End anonymous scope, and pass initial values.
   }
-
   ;
-
   function initialize$2(BMMath) {
     seedRandom([], BMMath);
   }
@@ -14519,8 +12317,7 @@
     SHAPE: 'shape'
   };
 
-  function _typeof$1(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$1 = function _typeof(obj) { return typeof obj; }; } else { _typeof$1 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$1(obj); }
-
+  function _typeof$1(o) { "@babel/helpers - typeof"; return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$1(o); }
   var ExpressionManager = function () {
     'use strict';
 
@@ -14533,289 +12330,214 @@
     var frames = null;
     var _lottieGlobal = {};
     initialize$2(BMMath);
-
     function resetFrame() {
       _lottieGlobal = {};
     }
-
     function $bm_isInstanceOfArray(arr) {
       return arr.constructor === Array || arr.constructor === Float32Array;
     }
-
     function isNumerable(tOfV, v) {
       return tOfV === 'number' || v instanceof Number || tOfV === 'boolean' || tOfV === 'string';
     }
-
     function $bm_neg(a) {
       var tOfA = _typeof$1(a);
-
       if (tOfA === 'number' || a instanceof Number || tOfA === 'boolean') {
         return -a;
       }
-
       if ($bm_isInstanceOfArray(a)) {
         var i;
         var lenA = a.length;
         var retArr = [];
-
         for (i = 0; i < lenA; i += 1) {
           retArr[i] = -a[i];
         }
-
         return retArr;
       }
-
       if (a.propType) {
         return a.v;
       }
-
       return -a;
     }
-
     var easeInBez = BezierFactory.getBezierEasing(0.333, 0, 0.833, 0.833, 'easeIn').get;
     var easeOutBez = BezierFactory.getBezierEasing(0.167, 0.167, 0.667, 1, 'easeOut').get;
     var easeInOutBez = BezierFactory.getBezierEasing(0.33, 0, 0.667, 1, 'easeInOut').get;
-
     function sum(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b) || tOfA === 'string' || tOfB === 'string') {
         return a + b;
       }
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         a = a.slice(0);
         a[0] += b;
         return a;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         b = b.slice(0);
         b[0] = a + b[0];
         return b;
       }
-
       if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
         var i = 0;
         var lenA = a.length;
         var lenB = b.length;
         var retArr = [];
-
         while (i < lenA || i < lenB) {
           if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
             retArr[i] = a[i] + b[i];
           } else {
             retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
           }
-
           i += 1;
         }
-
         return retArr;
       }
-
       return 0;
     }
-
     var add = sum;
-
     function sub(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         if (tOfA === 'string') {
           a = parseInt(a, 10);
         }
-
         if (tOfB === 'string') {
           b = parseInt(b, 10);
         }
-
         return a - b;
       }
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         a = a.slice(0);
         a[0] -= b;
         return a;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         b = b.slice(0);
         b[0] = a - b[0];
         return b;
       }
-
       if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
         var i = 0;
         var lenA = a.length;
         var lenB = b.length;
         var retArr = [];
-
         while (i < lenA || i < lenB) {
           if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
             retArr[i] = a[i] - b[i];
           } else {
             retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
           }
-
           i += 1;
         }
-
         return retArr;
       }
-
       return 0;
     }
-
     function mul(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       var arr;
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         return a * b;
       }
-
       var i;
       var len;
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         len = a.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a[i] * b;
         }
-
         return arr;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         len = b.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a * b[i];
         }
-
         return arr;
       }
-
       return 0;
     }
-
     function div(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       var arr;
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         return a / b;
       }
-
       var i;
       var len;
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         len = a.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a[i] / b;
         }
-
         return arr;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         len = b.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a / b[i];
         }
-
         return arr;
       }
-
       return 0;
     }
-
     function mod(a, b) {
       if (typeof a === 'string') {
         a = parseInt(a, 10);
       }
-
       if (typeof b === 'string') {
         b = parseInt(b, 10);
       }
-
       return a % b;
     }
-
     var $bm_sum = sum;
     var $bm_sub = sub;
     var $bm_mul = mul;
     var $bm_div = div;
     var $bm_mod = mod;
-
     function clamp(num, min, max) {
       if (min > max) {
         var mm = max;
         max = min;
         min = mm;
       }
-
       return Math.min(Math.max(num, min), max);
     }
-
     function radiansToDegrees(val) {
       return val / degToRads;
     }
-
     var radians_to_degrees = radiansToDegrees;
-
     function degreesToRadians(val) {
       return val * degToRads;
     }
-
     var degrees_to_radians = radiansToDegrees;
     var helperLengthArray = [0, 0, 0, 0, 0, 0];
-
     function length(arr1, arr2) {
       if (typeof arr1 === 'number' || arr1 instanceof Number) {
         arr2 = arr2 || 0;
         return Math.abs(arr1 - arr2);
       }
-
       if (!arr2) {
         arr2 = helperLengthArray;
       }
-
       var i;
       var len = Math.min(arr1.length, arr2.length);
       var addedLength = 0;
-
       for (i = 0; i < len; i += 1) {
         addedLength += Math.pow(arr2[i] - arr1[i], 2);
       }
-
       return Math.sqrt(addedLength);
     }
-
     function normalize(vec) {
       return div(vec, length(vec));
     }
-
     function rgbToHsl(val) {
       var r = val[0];
       var g = val[1];
@@ -14825,38 +12547,29 @@
       var h;
       var s;
       var l = (max + min) / 2;
-
       if (max === min) {
         h = 0; // achromatic
-
         s = 0; // achromatic
       } else {
         var d = max - min;
         s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
-
         switch (max) {
           case r:
             h = (g - b) / d + (g < b ? 6 : 0);
             break;
-
           case g:
             h = (b - r) / d + 2;
             break;
-
           case b:
             h = (r - g) / d + 4;
             break;
-
           default:
             break;
         }
-
         h /= 6;
       }
-
       return [h, s, l, val[3]];
     }
-
     function hue2rgb(p, q, t) {
       if (t < 0) t += 1;
       if (t > 1) t -= 1;
@@ -14865,7 +12578,6 @@
       if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
       return p;
     }
-
     function hslToRgb(val) {
       var h = val[0];
       var s = val[1];
@@ -14873,12 +12585,9 @@
       var r;
       var g;
       var b;
-
       if (s === 0) {
         r = l; // achromatic
-
         b = l; // achromatic
-
         g = l; // achromatic
       } else {
         var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
@@ -14887,10 +12596,8 @@
         g = hue2rgb(p, q, h);
         b = hue2rgb(p, q, h - 1 / 3);
       }
-
       return [r, g, b, val[3]];
     }
-
     function linear(t, tMin, tMax, value1, value2) {
       if (value1 === undefined || value2 === undefined) {
         value1 = tMin;
@@ -14898,38 +12605,29 @@
         tMin = 0;
         tMax = 1;
       }
-
       if (tMax < tMin) {
         var _tMin = tMax;
         tMax = tMin;
         tMin = _tMin;
       }
-
       if (t <= tMin) {
         return value1;
       }
-
       if (t >= tMax) {
         return value2;
       }
-
       var perc = tMax === tMin ? 0 : (t - tMin) / (tMax - tMin);
-
       if (!value1.length) {
         return value1 + (value2 - value1) * perc;
       }
-
       var i;
       var len = value1.length;
       var arr = createTypedArray('float32', len);
-
       for (i = 0; i < len; i += 1) {
         arr[i] = value1[i] + (value2[i] - value1[i]) * perc;
       }
-
       return arr;
     }
-
     function random(min, max) {
       if (max === undefined) {
         if (min === undefined) {
@@ -14940,33 +12638,25 @@
           min = undefined;
         }
       }
-
       if (max.length) {
         var i;
         var len = max.length;
-
         if (!min) {
           min = createTypedArray('float32', len);
         }
-
         var arr = createTypedArray('float32', len);
         var rnd = BMMath.random();
-
         for (i = 0; i < len; i += 1) {
           arr[i] = min[i] + rnd * (max[i] - min[i]);
         }
-
         return arr;
       }
-
       if (min === undefined) {
         min = 0;
       }
-
       var rndm = BMMath.random();
       return min + rndm * (max - min);
     }
-
     function createPath(points, inTangents, outTangents, closed) {
       var i;
       var len = points.length;
@@ -14975,37 +12665,31 @@
       var arrPlaceholder = [0, 0];
       var inVertexPoint;
       var outVertexPoint;
-
       for (i = 0; i < len; i += 1) {
         inVertexPoint = inTangents && inTangents[i] ? inTangents[i] : arrPlaceholder;
         outVertexPoint = outTangents && outTangents[i] ? outTangents[i] : arrPlaceholder;
         path.setTripleAt(points[i][0], points[i][1], outVertexPoint[0] + points[i][0], outVertexPoint[1] + points[i][1], inVertexPoint[0] + points[i][0], inVertexPoint[1] + points[i][1], i, true);
       }
-
       return path;
     }
-
     function initiateExpression(elem, data, property) {
       // Bail out if we don't want expressions
       function noOp(_value) {
         return _value;
       }
-
       if (!elem.globalData.renderConfig.runExpressions) {
         return noOp;
       }
-
       var val = data.x;
       var needsVelocity = /velocity(?![\w\d])/.test(val);
-
       var _needsRandom = val.indexOf('random') !== -1;
-
       var elemType = elem.data.ty;
       var transform;
       var $bm_transform;
       var content;
       var effect;
       var thisProperty = property;
+      thisProperty._name = elem.data.nm;
       thisProperty.valueAtTime = thisProperty.getValueAtTime;
       Object.defineProperty(thisProperty, 'value', {
         get: function get() {
@@ -15038,13 +12722,11 @@
       var mask;
       var valueAtTime;
       var velocityAtTime;
-      var scoped_bm_rt; // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
-
+      var scoped_bm_rt;
+      // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
       var expression_function = eval('[function _expression_function(){' + val + ';scoped_bm_rt=$bm_rt}]')[0]; // eslint-disable-line no-eval
-
       var numKeys = property.kf ? data.k.length : 0;
       var active = !this.data || this.data.hd !== true;
-
       var wiggle = function wiggle(freq, amp) {
         var iWiggle;
         var j;
@@ -15054,84 +12736,67 @@
         var iterations = Math.floor(time * freq);
         iWiggle = 0;
         j = 0;
-
         while (iWiggle < iterations) {
           // var rnd = BMMath.random();
           for (j = 0; j < lenWiggle; j += 1) {
-            addedAmps[j] += -amp + amp * 2 * BMMath.random(); // addedAmps[j] += -amp + amp*2*rnd;
+            addedAmps[j] += -amp + amp * 2 * BMMath.random();
+            // addedAmps[j] += -amp + amp*2*rnd;
           }
-
           iWiggle += 1;
-        } // var rnd2 = BMMath.random();
-
-
+        }
+        // var rnd2 = BMMath.random();
         var periods = time * freq;
         var perc = periods - Math.floor(periods);
         var arr = createTypedArray('float32', lenWiggle);
-
         if (lenWiggle > 1) {
           for (j = 0; j < lenWiggle; j += 1) {
-            arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc; // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
+            arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc;
+            // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
             // arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc);
           }
-
           return arr;
         }
-
         return this.pv + addedAmps[0] + (-amp + amp * 2 * BMMath.random()) * perc;
       }.bind(this);
-
       if (thisProperty.loopIn) {
         loopIn = thisProperty.loopIn.bind(thisProperty);
         loop_in = loopIn;
       }
-
       if (thisProperty.loopOut) {
         loopOut = thisProperty.loopOut.bind(thisProperty);
         loop_out = loopOut;
       }
-
       if (thisProperty.smooth) {
         smooth = thisProperty.smooth.bind(thisProperty);
       }
-
       function loopInDuration(type, duration) {
         return loopIn(type, duration, true);
       }
-
       function loopOutDuration(type, duration) {
         return loopOut(type, duration, true);
       }
-
       if (this.getValueAtTime) {
         valueAtTime = this.getValueAtTime.bind(this);
       }
-
       if (this.getVelocityAtTime) {
         velocityAtTime = this.getVelocityAtTime.bind(this);
       }
-
       var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface);
-
       function lookAt(elem1, elem2) {
         var fVec = [elem2[0] - elem1[0], elem2[1] - elem1[1], elem2[2] - elem1[2]];
         var pitch = Math.atan2(fVec[0], Math.sqrt(fVec[1] * fVec[1] + fVec[2] * fVec[2])) / degToRads;
         var yaw = -Math.atan2(fVec[1], fVec[2]) / degToRads;
         return [yaw, pitch, 0];
       }
-
       function easeOut(t, tMin, tMax, val1, val2) {
         return applyEase(easeOutBez, t, tMin, tMax, val1, val2);
       }
-
       function easeIn(t, tMin, tMax, val1, val2) {
         return applyEase(easeInBez, t, tMin, tMax, val1, val2);
       }
-
       function ease(t, tMin, tMax, val1, val2) {
         return applyEase(easeInOutBez, t, tMin, tMax, val1, val2);
       }
-
       function applyEase(fn, t, tMin, tMax, val1, val2) {
         if (val1 === undefined) {
           val1 = tMin;
@@ -15139,43 +12804,34 @@
         } else {
           t = (t - tMin) / (tMax - tMin);
         }
-
         if (t > 1) {
           t = 1;
         } else if (t < 0) {
           t = 0;
         }
-
         var mult = fn(t);
-
         if ($bm_isInstanceOfArray(val1)) {
           var iKey;
           var lenKey = val1.length;
           var arr = createTypedArray('float32', lenKey);
-
           for (iKey = 0; iKey < lenKey; iKey += 1) {
             arr[iKey] = (val2[iKey] - val1[iKey]) * mult + val1[iKey];
           }
-
           return arr;
         }
-
         return (val2 - val1) * mult + val1;
       }
-
       function nearestKey(time) {
         var iKey;
         var lenKey = data.k.length;
         var index;
         var keyTime;
-
         if (!data.k.length || typeof data.k[0] === 'number') {
           index = 0;
           keyTime = 0;
         } else {
           index = -1;
           time *= elem.comp.globalData.frameRate;
-
           if (time < data.k[0].t) {
             index = 1;
             keyTime = data.k[0].t;
@@ -15193,33 +12849,27 @@
                   index = iKey + 1;
                   keyTime = data.k[iKey].t;
                 }
-
                 break;
               }
             }
-
             if (index === -1) {
               index = iKey + 1;
               keyTime = data.k[iKey].t;
             }
           }
         }
-
         var obKey = {};
         obKey.index = index;
         obKey.time = keyTime / elem.comp.globalData.frameRate;
         return obKey;
       }
-
       function key(ind) {
         var obKey;
         var iKey;
         var lenKey;
-
         if (!data.k.length || typeof data.k[0] === 'number') {
           throw new Error('The property has no keyframe at index ' + ind);
         }
-
         ind -= 1;
         obKey = {
           time: data.k[ind].t / elem.comp.globalData.frameRate,
@@ -15227,72 +12877,55 @@
         };
         var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e;
         lenKey = arr.length;
-
         for (iKey = 0; iKey < lenKey; iKey += 1) {
           obKey[iKey] = arr[iKey];
           obKey.value[iKey] = arr[iKey];
         }
-
         return obKey;
       }
-
       function framesToTime(fr, fps) {
         if (!fps) {
           fps = elem.comp.globalData.frameRate;
         }
-
         return fr / fps;
       }
-
       function timeToFrames(t, fps) {
         if (!t && t !== 0) {
           t = time;
         }
-
         if (!fps) {
           fps = elem.comp.globalData.frameRate;
         }
-
         return t * fps;
       }
-
       function seedRandom(seed) {
         BMMath.seedrandom(randSeed + seed);
       }
-
       function sourceRectAtTime() {
         return elem.sourceRectAtTime();
       }
-
       function substring(init, end) {
         if (typeof value === 'string') {
           if (end === undefined) {
             return value.substring(init);
           }
-
           return value.substring(init, end);
         }
-
         return '';
       }
-
       function substr(init, end) {
         if (typeof value === 'string') {
           if (end === undefined) {
             return value.substr(init);
           }
-
           return value.substr(init, end);
         }
-
         return '';
       }
-
       function posterizeTime(framesPerSecond) {
         time = framesPerSecond === 0 ? 0 : Math.floor(time * framesPerSecond) / framesPerSecond;
         value = valueAtTime(time);
       }
-
       var time;
       var velocity;
       var value;
@@ -15305,21 +12938,17 @@
       var parent;
       var randSeed = Math.floor(Math.random() * 1000000);
       var globalData = elem.globalData;
-
       function executeExpression(_value) {
         // globalData.pushExpression();
         value = _value;
-
         if (this.frameExpressionId === elem.globalData.frameId && this.propType !== 'textSelector') {
           return value;
         }
-
         if (this.propType === 'textSelector') {
           textIndex = this.textIndex;
           textTotal = this.textTotal;
           selectorValue = this.selectorValue;
         }
-
         if (!thisLayer) {
           text = elem.layerInterface.text;
           thisLayer = elem.layerInterface;
@@ -15331,11 +12960,9 @@
           mask = thisLayer.mask ? thisLayer.mask.bind(thisLayer) : null;
           fromCompToSurface = fromComp;
         }
-
         if (!transform) {
           transform = elem.layerInterface('ADBE Transform Group');
           $bm_transform = transform;
-
           if (transform) {
             anchorPoint = transform.anchorPoint;
             /* position = transform.position;
@@ -15343,44 +12970,35 @@
                       scale = transform.scale; */
           }
         }
-
         if (elemType === 4 && !content) {
           content = thisLayer('ADBE Root Vectors Group');
         }
-
         if (!effect) {
           effect = thisLayer(4);
         }
-
         hasParent = !!(elem.hierarchy && elem.hierarchy.length);
-
         if (hasParent && !parent) {
           parent = elem.hierarchy[0].layerInterface;
         }
-
         time = this.comp.renderedFrame / this.comp.globalData.frameRate;
-
         if (_needsRandom) {
           seedRandom(randSeed + time);
         }
-
         if (needsVelocity) {
           velocity = velocityAtTime(time);
         }
-
         expression_function();
-        this.frameExpressionId = elem.globalData.frameId; // TODO: Check if it's possible to return on ShapeInterface the .v value
-        // Changed this to a ternary operation because Rollup failed compiling it correctly
+        this.frameExpressionId = elem.globalData.frameId;
 
+        // TODO: Check if it's possible to return on ShapeInterface the .v value
+        // Changed this to a ternary operation because Rollup failed compiling it correctly
         scoped_bm_rt = scoped_bm_rt.propType === propTypes.SHAPE ? scoped_bm_rt.v : scoped_bm_rt;
         return scoped_bm_rt;
-      } // Bundlers will see these as dead code and unless we reference them
-
-
+      }
+      // Bundlers will see these as dead code and unless we reference them
       executeExpression.__preventDeadCodeRemoval = [$bm_transform, anchorPoint, time, velocity, inPoint, outPoint, width, height, name, loop_in, loop_out, smooth, toComp, fromCompToSurface, toWorld, fromWorld, mask, position, rotation, scale, thisComp, numKeys, active, wiggle, loopInDuration, loopOutDuration, comp, lookAt, easeOut, easeIn, ease, nearestKey, key, text, textIndex, textTotal, selectorValue, framesToTime, timeToFrames, sourceRectAtTime, substring, substr, posterizeTime, index, globalData];
       return executeExpression;
     }
-
     ob.initiateExpression = initiateExpression;
     ob.__preventDeadCodeRemoval = [window, document, XMLHttpRequest, fetch, frames, $bm_neg, add, $bm_sum, $bm_sub, $bm_mul, $bm_div, $bm_mod, clamp, radians_to_degrees, degreesToRadians, degrees_to_radians, normalize, rgbToHsl, hslToRgb, linear, random, createPath, _lottieGlobal];
     ob.resetFrame = resetFrame;
@@ -15391,47 +13009,37 @@
     var ob = {};
     ob.initExpressions = initExpressions;
     ob.resetFrame = ExpressionManager.resetFrame;
-
     function initExpressions(animation) {
       var stackCount = 0;
       var registers = [];
-
       function pushExpression() {
         stackCount += 1;
       }
-
       function popExpression() {
         stackCount -= 1;
-
         if (stackCount === 0) {
           releaseInstances();
         }
       }
-
       function registerExpressionProperty(expression) {
         if (registers.indexOf(expression) === -1) {
           registers.push(expression);
         }
       }
-
       function releaseInstances() {
         var i;
         var len = registers.length;
-
         for (i = 0; i < len; i += 1) {
           registers[i].release();
         }
-
         registers.length = 0;
       }
-
       animation.renderer.compInterface = CompExpressionInterface(animation.renderer);
       animation.renderer.globalData.projectInterface.registerComposition(animation.renderer);
       animation.renderer.globalData.pushExpression = pushExpression;
       animation.renderer.globalData.popExpression = popExpression;
       animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty;
     }
-
     return ob;
   }();
 
@@ -15440,13 +13048,11 @@
       this._mask = mask;
       this._data = data;
     }
-
     Object.defineProperty(MaskInterface.prototype, 'maskPath', {
       get: function get() {
         if (this._mask.prop.k) {
           this._mask.prop.getValue();
         }
-
         return this._mask.prop;
       }
     });
@@ -15455,38 +13061,28 @@
         if (this._mask.op.k) {
           this._mask.op.getValue();
         }
-
         return this._mask.op.v * 100;
       }
     });
-
     var MaskManager = function MaskManager(maskManager) {
       var _masksInterfaces = createSizedArray(maskManager.viewData.length);
-
       var i;
       var len = maskManager.viewData.length;
-
       for (i = 0; i < len; i += 1) {
         _masksInterfaces[i] = new MaskInterface(maskManager.viewData[i], maskManager.masksProperties[i]);
       }
-
       var maskFunction = function maskFunction(name) {
         i = 0;
-
         while (i < len) {
           if (maskManager.masksProperties[i].nm === name) {
             return _masksInterfaces[i];
           }
-
           i += 1;
         }
-
         return null;
       };
-
       return maskFunction;
     };
-
     return MaskManager;
   }();
 
@@ -15501,7 +13097,6 @@
       v: [0, 0, 0],
       mult: 1
     };
-
     function completeProperty(expressionValue, property, type) {
       Object.defineProperty(expressionValue, 'velocity', {
         get: function get() {
@@ -15509,14 +13104,11 @@
         }
       });
       expressionValue.numKeys = property.keyframes ? property.keyframes.length : 0;
-
       expressionValue.key = function (pos) {
         if (!expressionValue.numKeys) {
           return 0;
         }
-
         var value = '';
-
         if ('s' in property.keyframes[pos - 1]) {
           value = property.keyframes[pos - 1].s;
         } else if ('e' in property.keyframes[pos - 2]) {
@@ -15524,54 +13116,43 @@
         } else {
           value = property.keyframes[pos - 2].s;
         }
-
         var valueProp = type === 'unidimensional' ? new Number(value) : Object.assign({}, value); // eslint-disable-line no-new-wrappers
-
         valueProp.time = property.keyframes[pos - 1].t / property.elem.comp.globalData.frameRate;
         valueProp.value = type === 'unidimensional' ? value[0] : value;
         return valueProp;
       };
-
       expressionValue.valueAtTime = property.getValueAtTime;
       expressionValue.speedAtTime = property.getSpeedAtTime;
       expressionValue.velocityAtTime = property.getVelocityAtTime;
       expressionValue.propertyGroup = property.propertyGroup;
     }
-
     function UnidimensionalPropertyInterface(property) {
       if (!property || !('pv' in property)) {
         property = defaultUnidimensionalValue;
       }
-
       var mult = 1 / property.mult;
       var val = property.pv * mult;
       var expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
-
       expressionValue.value = val;
       completeProperty(expressionValue, property, 'unidimensional');
       return function () {
         if (property.k) {
           property.getValue();
         }
-
         val = property.v * mult;
-
         if (expressionValue.value !== val) {
           expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
-
           expressionValue.value = val;
+          expressionValue[0] = val;
           completeProperty(expressionValue, property, 'unidimensional');
         }
-
         return expressionValue;
       };
     }
-
     function MultidimensionalPropertyInterface(property) {
       if (!property || !('pv' in property)) {
         property = defaultMultidimensionalValue;
       }
-
       var mult = 1 / property.mult;
       var len = property.data && property.data.l || property.pv.length;
       var expressionValue = createTypedArray('float32', len);
@@ -15582,30 +13163,25 @@
         if (property.k) {
           property.getValue();
         }
-
         for (var i = 0; i < len; i += 1) {
           arrValue[i] = property.v[i] * mult;
           expressionValue[i] = arrValue[i];
         }
-
         return expressionValue;
       };
-    } // TODO: try to avoid using this getter
+    }
 
-
+    // TODO: try to avoid using this getter
     function defaultGetter() {
       return defaultUnidimensionalValue;
     }
-
     return function (property) {
       if (!property) {
         return defaultGetter;
       }
-
       if (property.propType === 'unidimensional') {
         return UnidimensionalPropertyInterface(property);
       }
-
       return MultidimensionalPropertyInterface(property);
     };
   }();
@@ -15619,52 +13195,41 @@
           case 'ADBE Scale':
           case 6:
             return _thisFunction.scale;
-
           case 'rotation':
           case 'Rotation':
           case 'ADBE Rotation':
           case 'ADBE Rotate Z':
           case 10:
             return _thisFunction.rotation;
-
           case 'ADBE Rotate X':
             return _thisFunction.xRotation;
-
           case 'ADBE Rotate Y':
             return _thisFunction.yRotation;
-
           case 'position':
           case 'Position':
           case 'ADBE Position':
           case 2:
             return _thisFunction.position;
-
           case 'ADBE Position_0':
             return _thisFunction.xPosition;
-
           case 'ADBE Position_1':
             return _thisFunction.yPosition;
-
           case 'ADBE Position_2':
             return _thisFunction.zPosition;
-
           case 'anchorPoint':
           case 'AnchorPoint':
           case 'Anchor Point':
           case 'ADBE AnchorPoint':
           case 1:
             return _thisFunction.anchorPoint;
-
           case 'opacity':
           case 'Opacity':
           case 11:
             return _thisFunction.opacity;
-
           default:
             return null;
         }
       }
-
       Object.defineProperty(_thisFunction, 'rotation', {
         get: ExpressionPropertyInterface(transform.r || transform.rz)
       });
@@ -15680,32 +13245,24 @@
       Object.defineProperty(_thisFunction, 'scale', {
         get: ExpressionPropertyInterface(transform.s)
       });
-
       var _px;
-
       var _py;
-
       var _pz;
-
       var _transformFactory;
-
       if (transform.p) {
         _transformFactory = ExpressionPropertyInterface(transform.p);
       } else {
         _px = ExpressionPropertyInterface(transform.px);
         _py = ExpressionPropertyInterface(transform.py);
-
         if (transform.pz) {
           _pz = ExpressionPropertyInterface(transform.pz);
         }
       }
-
       Object.defineProperty(_thisFunction, 'position', {
         get: function get() {
           if (transform.p) {
             return _transformFactory();
           }
-
           return [_px(), _py(), _pz ? _pz() : 0];
         }
       });
@@ -15740,19 +13297,15 @@
   var LayerExpressionInterface = function () {
     function getMatrix(time) {
       var toWorldMat = new Matrix();
-
       if (time !== undefined) {
         var propMatrix = this._elem.finalTransform.mProp.getValueAtTime(time);
-
         propMatrix.clone(toWorldMat);
       } else {
         var transformMat = this._elem.finalTransform.mProp;
         transformMat.applyToMatrix(toWorldMat);
       }
-
       return toWorldMat;
     }
-
     function toWorldVec(arr, time) {
       var toWorldMat = this.getMatrix(time);
       toWorldMat.props[12] = 0;
@@ -15760,12 +13313,10 @@
       toWorldMat.props[14] = 0;
       return this.applyPoint(toWorldMat, arr);
     }
-
     function toWorld(arr, time) {
       var toWorldMat = this.getMatrix(time);
       return this.applyPoint(toWorldMat, arr);
     }
-
     function fromWorldVec(arr, time) {
       var toWorldMat = this.getMatrix(time);
       toWorldMat.props[12] = 0;
@@ -15773,101 +13324,78 @@
       toWorldMat.props[14] = 0;
       return this.invertPoint(toWorldMat, arr);
     }
-
     function fromWorld(arr, time) {
       var toWorldMat = this.getMatrix(time);
       return this.invertPoint(toWorldMat, arr);
     }
-
     function applyPoint(matrix, arr) {
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
         }
       }
-
       return matrix.applyToPointArray(arr[0], arr[1], arr[2] || 0);
     }
-
     function invertPoint(matrix, arr) {
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
         }
       }
-
       return matrix.inversePoint(arr);
     }
-
     function fromComp(arr) {
       var toWorldMat = new Matrix();
       toWorldMat.reset();
-
       this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
-
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
         }
-
         return toWorldMat.inversePoint(arr);
       }
-
       return toWorldMat.inversePoint(arr);
     }
-
     function sampleImage() {
       return [1, 1, 1, 1];
     }
-
     return function (elem) {
       var transformInterface;
-
       function _registerMaskInterface(maskManager) {
         _thisLayerFunction.mask = new MaskManagerInterface(maskManager, elem);
       }
-
       function _registerEffectsInterface(effects) {
         _thisLayerFunction.effect = effects;
       }
-
       function _thisLayerFunction(name) {
         switch (name) {
           case 'ADBE Root Vectors Group':
           case 'Contents':
           case 2:
             return _thisLayerFunction.shapeInterface;
-
           case 1:
           case 6:
           case 'Transform':
           case 'transform':
           case 'ADBE Transform Group':
             return transformInterface;
-
           case 4:
           case 'ADBE Effect Parade':
           case 'effects':
           case 'Effects':
             return _thisLayerFunction.effect;
-
           case 'ADBE Text Properties':
             return _thisLayerFunction.textInterface;
-
           default:
             return null;
         }
       }
-
       _thisLayerFunction.getMatrix = getMatrix;
       _thisLayerFunction.invertPoint = invertPoint;
       _thisLayerFunction.applyPoint = applyPoint;
@@ -15928,11 +13456,9 @@
     return function (interfaceFunction, parentPropertyGroup) {
       return function (val) {
         val = val === undefined ? 1 : val;
-
         if (val <= 0) {
           return interfaceFunction;
         }
-
         return parentPropertyGroup(val - 1);
       };
     };
@@ -15943,17 +13469,13 @@
       var interfaceFunction = {
         _name: propertyName
       };
-
       function _propertyGroup(val) {
         val = val === undefined ? 1 : val;
-
         if (val <= 0) {
           return interfaceFunction;
         }
-
         return propertyGroup(val - 1);
       }
-
       return _propertyGroup;
     };
   }();
@@ -15962,35 +13484,27 @@
     var ob = {
       createEffectsInterface: createEffectsInterface
     };
-
     function createEffectsInterface(elem, propertyGroup) {
       if (elem.effectsManager) {
         var effectElements = [];
         var effectsData = elem.data.ef;
         var i;
         var len = elem.effectsManager.effectElements.length;
-
         for (i = 0; i < len; i += 1) {
           effectElements.push(createGroupInterface(effectsData[i], elem.effectsManager.effectElements[i], propertyGroup, elem));
         }
-
         var effects = elem.data.ef || [];
-
         var groupInterface = function groupInterface(name) {
           i = 0;
           len = effects.length;
-
           while (i < len) {
             if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
               return effectElements[i];
             }
-
             i += 1;
           }
-
           return null;
         };
-
         Object.defineProperty(groupInterface, 'numProperties', {
           get: function get() {
             return effects.length;
@@ -15998,37 +13512,28 @@
         });
         return groupInterface;
       }
-
       return null;
     }
-
     function createGroupInterface(data, elements, propertyGroup, elem) {
       function groupInterface(name) {
         var effects = data.ef;
         var i = 0;
         var len = effects.length;
-
         while (i < len) {
           if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
             if (effects[i].ty === 5) {
               return effectElements[i];
             }
-
             return effectElements[i]();
           }
-
           i += 1;
         }
-
         throw new Error();
       }
-
       var _propertyGroup = propertyGroupFactory(groupInterface, propertyGroup);
-
       var effectElements = [];
       var i;
       var len = data.ef.length;
-
       for (i = 0; i < len; i += 1) {
         if (data.ef[i].ty === 5) {
           effectElements.push(createGroupInterface(data.ef[i], elements.effectElements[i], elements.effectElements[i].propertyGroup, elem));
@@ -16036,7 +13541,6 @@
           effectElements.push(createValueInterface(elements.effectElements[i], data.ef[i].ty, elem, _propertyGroup));
         }
       }
-
       if (data.mn === 'ADBE Color Control') {
         Object.defineProperty(groupInterface, 'color', {
           get: function get() {
@@ -16044,7 +13548,6 @@
           }
         });
       }
-
       Object.defineProperties(groupInterface, {
         numProperties: {
           get: function get() {
@@ -16062,42 +13565,32 @@
       groupInterface.active = groupInterface.enabled;
       return groupInterface;
     }
-
     function createValueInterface(element, type, elem, propertyGroup) {
       var expressionProperty = ExpressionPropertyInterface(element.p);
-
       function interfaceFunction() {
         if (type === 10) {
           return elem.comp.compInterface(element.p.v);
         }
-
         return expressionProperty();
       }
-
       if (element.p.setGroupProperty) {
         element.p.setGroupProperty(PropertyInterface('', propertyGroup));
       }
-
       return interfaceFunction;
     }
-
     return ob;
   }();
 
   var ShapePathInterface = function () {
     return function pathInterfaceFactory(shape, view, propertyGroup) {
       var prop = view.sh;
-
       function interfaceFunction(val) {
         if (val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2) {
           return interfaceFunction.path;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       prop.setGroupProperty(PropertyInterface('Path', _propertyGroup));
       Object.defineProperties(interfaceFunction, {
         path: {
@@ -16105,7 +13598,6 @@
             if (prop.k) {
               prop.getValue();
             }
-
             return prop;
           }
         },
@@ -16114,7 +13606,6 @@
             if (prop.k) {
               prop.getValue();
             }
-
             return prop;
           }
         },
@@ -16143,7 +13634,6 @@
       var arr = [];
       var i;
       var len = shapes ? shapes.length : 0;
-
       for (i = 0; i < len; i += 1) {
         if (shapes[i].ty === 'gr') {
           arr.push(groupInterfaceFactory(shapes[i], view[i], propertyGroup));
@@ -16153,7 +13643,8 @@
           arr.push(strokeInterfaceFactory(shapes[i], view[i], propertyGroup));
         } else if (shapes[i].ty === 'tm') {
           arr.push(trimInterfaceFactory(shapes[i], view[i], propertyGroup));
-        } else if (shapes[i].ty === 'tr') {// arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
+        } else if (shapes[i].ty === 'tr') {
+          // arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
         } else if (shapes[i].ty === 'el') {
           arr.push(ellipseInterfaceFactory(shapes[i], view[i], propertyGroup));
         } else if (shapes[i].ty === 'sr') {
@@ -16172,32 +13663,24 @@
           arr.push(defaultInterfaceFactory(shapes[i], view[i], propertyGroup));
         }
       }
-
       return arr;
     }
-
     function contentsInterfaceFactory(shape, view, propertyGroup) {
       var interfaces;
-
       var interfaceFunction = function _interfaceFunction(value) {
         var i = 0;
         var len = interfaces.length;
-
         while (i < len) {
           if (interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value) {
             return interfaces[i];
           }
-
           i += 1;
         }
-
         if (typeof value === 'number') {
           return interfaces[value - 1];
         }
-
         return null;
       };
-
       interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
       interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup);
       interfaceFunction.numProperties = interfaces.length;
@@ -16207,7 +13690,6 @@
       interfaceFunction._name = shape.nm;
       return interfaceFunction;
     }
-
     function groupInterfaceFactory(shape, view, propertyGroup) {
       var interfaceFunction = function _interfaceFunction(value) {
         switch (value) {
@@ -16218,12 +13700,10 @@
           // Not necessary for now. Keeping them here in case a new case appears
           // case 'ADBE Vector Transform Group':
           // case 3:
-
           default:
             return interfaceFunction.transform;
         }
       };
-
       interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
       var content = contentsInterfaceFactory(shape, view, interfaceFunction.propertyGroup);
       var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
@@ -16233,28 +13713,24 @@
         get: function get() {
           return shape.nm;
         }
-      }); // interfaceFunction.content = interfaceFunction;
-
+      });
+      // interfaceFunction.content = interfaceFunction;
       interfaceFunction.numProperties = shape.np;
       interfaceFunction.propertyIndex = shape.ix;
       interfaceFunction.nm = shape.nm;
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function fillInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(val) {
         if (val === 'Color' || val === 'color') {
           return interfaceFunction.color;
         }
-
         if (val === 'Opacity' || val === 'opacity') {
           return interfaceFunction.opacity;
         }
-
         return null;
       }
-
       Object.defineProperties(interfaceFunction, {
         color: {
           get: ExpressionPropertyInterface(view.c)
@@ -16273,24 +13749,19 @@
       view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
       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)
@@ -16318,51 +13789,39 @@
       view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
       return interfaceFunction;
     }
-
     function defaultInterfaceFactory() {
       function interfaceFunction() {
         return null;
       }
-
       return interfaceFunction;
     }
-
     function strokeInterfaceFactory(shape, view, propertyGroup) {
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup);
-
       function addPropertyToDashOb(i) {
         Object.defineProperty(dashOb, shape.d[i].nm, {
           get: ExpressionPropertyInterface(view.d.dataProps[i].p)
         });
       }
-
       var i;
       var len = shape.d ? shape.d.length : 0;
       var dashOb = {};
-
       for (i = 0; i < len; i += 1) {
         addPropertyToDashOb(i);
         view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup);
       }
-
       function interfaceFunction(val) {
         if (val === 'Color' || val === 'color') {
           return interfaceFunction.color;
         }
-
         if (val === 'Opacity' || val === 'opacity') {
           return interfaceFunction.opacity;
         }
-
         if (val === 'Stroke Width' || val === 'stroke width') {
           return interfaceFunction.strokeWidth;
         }
-
         return null;
       }
-
       Object.defineProperties(interfaceFunction, {
         color: {
           get: ExpressionPropertyInterface(view.c)
@@ -16390,26 +13849,20 @@
       view.w.setGroupProperty(PropertyInterface('Stroke Width', _propertyGroup));
       return interfaceFunction;
     }
-
     function trimInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(val) {
         if (val === shape.e.ix || val === 'End' || val === 'end') {
           return interfaceFunction.end;
         }
-
         if (val === shape.s.ix) {
           return interfaceFunction.start;
         }
-
         if (val === shape.o.ix) {
           return interfaceFunction.offset;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       interfaceFunction.propertyIndex = shape.ix;
       view.s.setGroupProperty(PropertyInterface('Start', _propertyGroup));
       view.e.setGroupProperty(PropertyInterface('End', _propertyGroup));
@@ -16433,53 +13886,41 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function transformInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.a.ix === value || value === 'Anchor Point') {
           return interfaceFunction.anchorPoint;
         }
-
         if (shape.o.ix === value || value === 'Opacity') {
           return interfaceFunction.opacity;
         }
-
         if (shape.p.ix === value || value === 'Position') {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value || value === 'Rotation' || value === 'ADBE Vector Rotation') {
           return interfaceFunction.rotation;
         }
-
         if (shape.s.ix === value || value === 'Scale') {
           return interfaceFunction.scale;
         }
-
         if (shape.sk && shape.sk.ix === value || value === 'Skew') {
           return interfaceFunction.skew;
         }
-
         if (shape.sa && shape.sa.ix === value || value === 'Skew Axis') {
           return interfaceFunction.skewAxis;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
       view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
       view.transform.mProps.a.setGroupProperty(PropertyInterface('Anchor Point', _propertyGroup));
       view.transform.mProps.s.setGroupProperty(PropertyInterface('Scale', _propertyGroup));
       view.transform.mProps.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
-
       if (view.transform.mProps.sk) {
         view.transform.mProps.sk.setGroupProperty(PropertyInterface('Skew', _propertyGroup));
         view.transform.mProps.sa.setGroupProperty(PropertyInterface('Skew Angle', _propertyGroup));
       }
-
       view.transform.op.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
       Object.defineProperties(interfaceFunction, {
         opacity: {
@@ -16512,22 +13953,17 @@
       interfaceFunction.propertyGroup = propertyGroup;
       return interfaceFunction;
     }
-
     function ellipseInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.s.ix === value) {
           return interfaceFunction.size;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       interfaceFunction.propertyIndex = shape.ix;
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
@@ -16546,42 +13982,32 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function starInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value) {
           return interfaceFunction.rotation;
         }
-
         if (shape.pt.ix === value) {
           return interfaceFunction.points;
         }
-
         if (shape.or.ix === value || value === 'ADBE Vector Star Outer Radius') {
           return interfaceFunction.outerRadius;
         }
-
         if (shape.os.ix === value) {
           return interfaceFunction.outerRoundness;
         }
-
         if (shape.ir && (shape.ir.ix === value || value === 'ADBE Vector Star Inner Radius')) {
           return interfaceFunction.innerRadius;
         }
-
         if (shape.is && shape.is.ix === value) {
           return interfaceFunction.innerRoundness;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       interfaceFunction.propertyIndex = shape.ix;
       prop.or.setGroupProperty(PropertyInterface('Outer Radius', _propertyGroup));
@@ -16589,12 +14015,10 @@
       prop.pt.setGroupProperty(PropertyInterface('Points', _propertyGroup));
       prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
       prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
-
       if (shape.ir) {
         prop.ir.setGroupProperty(PropertyInterface('Inner Radius', _propertyGroup));
         prop.is.setGroupProperty(PropertyInterface('Inner Roundness', _propertyGroup));
       }
-
       Object.defineProperties(interfaceFunction, {
         position: {
           get: ExpressionPropertyInterface(prop.p)
@@ -16624,26 +14048,20 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function rectInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value) {
           return interfaceFunction.roundness;
         }
-
         if (shape.s.ix === value || value === 'Size' || value === 'ADBE Vector Rect Size') {
           return interfaceFunction.size;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       interfaceFunction.propertyIndex = shape.ix;
       prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
@@ -16666,18 +14084,14 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function roundedInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.r.ix === value || value === 'Round Corners 1') {
           return interfaceFunction.radius;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view;
       interfaceFunction.propertyIndex = shape.ix;
       prop.rd.setGroupProperty(PropertyInterface('Radius', _propertyGroup));
@@ -16692,22 +14106,17 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function repeaterInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.c.ix === value || value === 'Copies') {
           return interfaceFunction.copies;
         }
-
         if (shape.o.ix === value || value === 'Offset') {
           return interfaceFunction.offset;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view;
       interfaceFunction.propertyIndex = shape.ix;
       prop.c.setGroupProperty(PropertyInterface('Copies', _propertyGroup));
@@ -16726,39 +14135,29 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     return function (shapes, view, propertyGroup) {
       var interfaces;
-
       function _interfaceFunction(value) {
         if (typeof value === 'number') {
           value = value === undefined ? 1 : value;
-
           if (value === 0) {
             return propertyGroup;
           }
-
           return interfaces[value - 1];
         }
-
         var i = 0;
         var len = interfaces.length;
-
         while (i < len) {
           if (interfaces[i]._name === value) {
             return interfaces[i];
           }
-
           i += 1;
         }
-
         return null;
       }
-
       function parentGroupWrapper() {
         return propertyGroup;
       }
-
       _interfaceFunction.propertyGroup = propertyGroupFactory(_interfaceFunction, parentGroupWrapper);
       interfaces = iterateElements(shapes, view, _interfaceFunction.propertyGroup);
       _interfaceFunction.numProperties = interfaces.length;
@@ -16770,28 +14169,22 @@
   var TextExpressionInterface = function () {
     return function (elem) {
       var _sourceText;
-
       function _thisLayerFunction(name) {
         switch (name) {
           case 'ADBE Text Document':
             return _thisLayerFunction.sourceText;
-
           default:
             return null;
         }
       }
-
       Object.defineProperty(_thisLayerFunction, 'sourceText', {
         get: function get() {
           elem.textProperty.getValue();
           var stringValue = elem.textProperty.currentData.t;
-
           if (!_sourceText || stringValue !== _sourceText.value) {
             _sourceText = new String(stringValue); // eslint-disable-line no-new-wrappers
             // If stringValue is an empty string, eval returns undefined, so it has to be returned as a String primitive
-
             _sourceText.value = stringValue || new String(stringValue); // eslint-disable-line no-new-wrappers
-
             Object.defineProperty(_sourceText, 'style', {
               get: function get() {
                 return {
@@ -16800,7 +14193,6 @@
               }
             });
           }
-
           return _sourceText;
         }
       });
@@ -16808,73 +14200,56 @@
     };
   }();
 
-  function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
-
+  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
   var FootageInterface = function () {
     var outlineInterfaceFactory = function outlineInterfaceFactory(elem) {
       var currentPropertyName = '';
       var currentProperty = elem.getFootageData();
-
       function init() {
         currentPropertyName = '';
         currentProperty = elem.getFootageData();
         return searchProperty;
       }
-
       function searchProperty(value) {
         if (currentProperty[value]) {
           currentPropertyName = value;
           currentProperty = currentProperty[value];
-
           if (_typeof(currentProperty) === 'object') {
             return searchProperty;
           }
-
           return currentProperty;
         }
-
         var propertyNameIndex = value.indexOf(currentPropertyName);
-
         if (propertyNameIndex !== -1) {
           var index = parseInt(value.substr(propertyNameIndex + currentPropertyName.length), 10);
           currentProperty = currentProperty[index];
-
           if (_typeof(currentProperty) === 'object') {
             return searchProperty;
           }
-
           return currentProperty;
         }
-
         return '';
       }
-
       return init;
     };
-
     var dataInterfaceFactory = function dataInterfaceFactory(elem) {
       function interfaceFunction(value) {
         if (value === 'Outline') {
           return interfaceFunction.outlineInterface();
         }
-
         return null;
       }
-
       interfaceFunction._name = 'Outline';
       interfaceFunction.outlineInterface = outlineInterfaceFactory(elem);
       return interfaceFunction;
     };
-
     return function (elem) {
       function _interfaceFunction(value) {
         if (value === 'Data') {
           return _interfaceFunction.dataInterface;
         }
-
         return null;
       }
-
       _interfaceFunction._name = 'Data';
       _interfaceFunction.dataInterface = dataInterfaceFactory(elem);
       return _interfaceFunction;
@@ -16889,7 +14264,6 @@
     text: TextExpressionInterface,
     footage: FootageInterface
   };
-
   function getInterface(type) {
     return interfaces[type] || null;
   }
@@ -16903,56 +14277,44 @@
         prop.effectsSequence.push(prop.initiateExpression(elem, data, prop).bind(prop));
       }
     }
-
     function getValueAtTime(frameNum) {
       frameNum *= this.elem.globalData.frameRate;
       frameNum -= this.offsetTime;
-
       if (frameNum !== this._cachingAtTime.lastFrame) {
         this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0;
         this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime);
         this._cachingAtTime.lastFrame = frameNum;
       }
-
       return this._cachingAtTime.value;
     }
-
     function getSpeedAtTime(frameNum) {
       var delta = -0.01;
       var v1 = this.getValueAtTime(frameNum);
       var v2 = this.getValueAtTime(frameNum + delta);
       var speed = 0;
-
       if (v1.length) {
         var i;
-
         for (i = 0; i < v1.length; i += 1) {
           speed += Math.pow(v2[i] - v1[i], 2);
         }
-
         speed = Math.sqrt(speed) * 100;
       } else {
         speed = 0;
       }
-
       return speed;
     }
-
     function getVelocityAtTime(frameNum) {
       if (this.vel !== undefined) {
         return this.vel;
       }
-
-      var delta = -0.001; // frameNum += this.elem.data.st;
-
+      var delta = -0.001;
+      // frameNum += this.elem.data.st;
       var v1 = this.getValueAtTime(frameNum);
       var v2 = this.getValueAtTime(frameNum + delta);
       var velocity;
-
       if (v1.length) {
         velocity = createTypedArray('float32', v1.length);
         var i;
-
         for (i = 0; i < v1.length; i += 1) {
           // removing frameRate
           // if needed, don't add it here
@@ -16962,18 +14324,14 @@
       } else {
         velocity = (v2 - v1) / delta;
       }
-
       return velocity;
     }
-
     function getStaticValueAtTime() {
       return this.pv;
     }
-
     function setGroupProperty(propertyGroup) {
       this.propertyGroup = propertyGroup;
     }
-
     return {
       searchExpressions: searchExpressions,
       getSpeedAtTime: getSpeedAtTime,
@@ -16989,24 +14347,19 @@
       if (!this.k || !this.keyframes) {
         return this.pv;
       }
-
       type = type ? type.toLowerCase() : '';
       var currentFrame = this.comp.renderedFrame;
       var keyframes = this.keyframes;
       var lastKeyFrame = keyframes[keyframes.length - 1].t;
-
       if (currentFrame <= lastKeyFrame) {
         return this.pv;
       }
-
       var cycleDuration;
       var firstKeyFrame;
-
       if (!durationFlag) {
         if (!duration || duration > keyframes.length - 1) {
           duration = keyframes.length - 1;
         }
-
         firstKeyFrame = keyframes[keyframes.length - 1 - duration].t;
         cycleDuration = lastKeyFrame - firstKeyFrame;
       } else {
@@ -17015,17 +14368,13 @@
         } else {
           cycleDuration = Math.abs(lastKeyFrame - this.elem.comp.globalData.frameRate * duration);
         }
-
         firstKeyFrame = lastKeyFrame - cycleDuration;
       }
-
       var i;
       var len;
       var ret;
-
       if (type === 'pingpong') {
         var iterations = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
-
         if (iterations % 2 !== 0) {
           return this.getValueAtTime((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
         }
@@ -17033,64 +14382,48 @@
         var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
         var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
-
         var repeats = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
-
         if (this.pv.length) {
           ret = new Array(initV.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = (endV[i] - initV[i]) * repeats + current[i];
           }
-
           return ret;
         }
-
         return (endV - initV) * repeats + current;
       } else if (type === 'continue') {
         var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0);
-
         if (this.pv.length) {
           ret = new Array(lastValue.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = lastValue[i] + (lastValue[i] - nextLastValue[i]) * ((currentFrame - lastKeyFrame) / this.comp.globalData.frameRate) / 0.0005; // eslint-disable-line
           }
-
           return ret;
         }
-
         return lastValue + (lastValue - nextLastValue) * ((currentFrame - lastKeyFrame) / 0.001);
       }
-
       return this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
     }
-
     function loopIn(type, duration, durationFlag) {
       if (!this.k) {
         return this.pv;
       }
-
       type = type ? type.toLowerCase() : '';
       var currentFrame = this.comp.renderedFrame;
       var keyframes = this.keyframes;
       var firstKeyFrame = keyframes[0].t;
-
       if (currentFrame >= firstKeyFrame) {
         return this.pv;
       }
-
       var cycleDuration;
       var lastKeyFrame;
-
       if (!durationFlag) {
         if (!duration || duration > keyframes.length - 1) {
           duration = keyframes.length - 1;
         }
-
         lastKeyFrame = keyframes[duration].t;
         cycleDuration = lastKeyFrame - firstKeyFrame;
       } else {
@@ -17099,17 +14432,13 @@
         } else {
           cycleDuration = Math.abs(this.elem.comp.globalData.frameRate * duration);
         }
-
         lastKeyFrame = firstKeyFrame + cycleDuration;
       }
-
       var i;
       var len;
       var ret;
-
       if (type === 'pingpong') {
         var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration);
-
         if (iterations % 2 === 0) {
           return this.getValueAtTime(((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
         }
@@ -17118,52 +14447,39 @@
         var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var current = this.getValueAtTime((cycleDuration - (firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0);
         var repeats = Math.floor((firstKeyFrame - currentFrame) / cycleDuration) + 1;
-
         if (this.pv.length) {
           ret = new Array(initV.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = current[i] - (endV[i] - initV[i]) * repeats;
           }
-
           return ret;
         }
-
         return current - (endV - initV) * repeats;
       } else if (type === 'continue') {
         var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
         var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0);
-
         if (this.pv.length) {
           ret = new Array(firstValue.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = firstValue[i] + (firstValue[i] - nextFirstValue[i]) * (firstKeyFrame - currentFrame) / 0.001;
           }
-
           return ret;
         }
-
         return firstValue + (firstValue - nextFirstValue) * (firstKeyFrame - currentFrame) / 0.001;
       }
-
       return this.getValueAtTime((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
     }
-
     function smooth(width, samples) {
       if (!this.k) {
         return this.pv;
       }
-
       width = (width || 0.4) * 0.5;
       samples = Math.floor(samples || 5);
-
       if (samples <= 1) {
         return this.pv;
       }
-
       var currentTime = this.comp.renderedFrame / this.comp.globalData.frameRate;
       var initFrame = currentTime - width;
       var endFrame = currentTime + width;
@@ -17171,18 +14487,14 @@
       var i = 0;
       var j = 0;
       var value;
-
       if (this.pv.length) {
         value = createTypedArray('float32', this.pv.length);
       } else {
         value = 0;
       }
-
       var sampleValue;
-
       while (i < samples) {
         sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency);
-
         if (this.pv.length) {
           for (j = 0; j < this.pv.length; j += 1) {
             value[j] += sampleValue[j];
@@ -17190,10 +14502,8 @@
         } else {
           value += sampleValue;
         }
-
         i += 1;
       }
-
       if (this.pv.length) {
         for (j = 0; j < this.pv.length; j += 1) {
           value[j] /= samples;
@@ -17201,37 +14511,30 @@
       } else {
         value /= samples;
       }
-
       return value;
     }
-
     function getTransformValueAtTime(time) {
       if (!this._transformCachingAtTime) {
         this._transformCachingAtTime = {
           v: new Matrix()
         };
-      } /// /
-
-
+      }
+      /// /
       var matrix = this._transformCachingAtTime.v;
       matrix.cloneFromProps(this.pre.props);
-
       if (this.appliedTransformations < 1) {
         var anchor = this.a.getValueAtTime(time);
         matrix.translate(-anchor[0] * this.a.mult, -anchor[1] * this.a.mult, anchor[2] * this.a.mult);
       }
-
       if (this.appliedTransformations < 2) {
         var scale = this.s.getValueAtTime(time);
         matrix.scale(scale[0] * this.s.mult, scale[1] * this.s.mult, scale[2] * this.s.mult);
       }
-
       if (this.sk && this.appliedTransformations < 3) {
         var skew = this.sk.getValueAtTime(time);
         var skewAxis = this.sa.getValueAtTime(time);
         matrix.skewFromAxis(-skew * this.sk.mult, skewAxis * this.sa.mult);
       }
-
       if (this.r && this.appliedTransformations < 4) {
         var rotation = this.r.getValueAtTime(time);
         matrix.rotate(-rotation * this.r.mult);
@@ -17242,11 +14545,9 @@
         var orientation = this.or.getValueAtTime(time);
         matrix.rotateZ(-rotationZ * this.rz.mult).rotateY(rotationY * this.ry.mult).rotateX(rotationX * this.rx.mult).rotateZ(-orientation[2] * this.or.mult).rotateY(orientation[1] * this.or.mult).rotateX(orientation[0] * this.or.mult);
       }
-
       if (this.data.p && this.data.p.s) {
         var positionX = this.px.getValueAtTime(time);
         var positionY = this.py.getValueAtTime(time);
-
         if (this.data.p.z) {
           var positionZ = this.pz.getValueAtTime(time);
           matrix.translate(positionX * this.px.mult, positionY * this.py.mult, -positionZ * this.pz.mult);
@@ -17257,42 +14558,34 @@
         var position = this.p.getValueAtTime(time);
         matrix.translate(position[0] * this.p.mult, position[1] * this.p.mult, -position[2] * this.p.mult);
       }
-
-      return matrix; /// /
+      return matrix;
+      /// /
     }
-
     function getTransformStaticValueAtTime() {
       return this.v.clone(new Matrix());
     }
-
     var getTransformProperty = TransformPropertyFactory.getTransformProperty;
-
     TransformPropertyFactory.getTransformProperty = function (elem, data, container) {
       var prop = getTransformProperty(elem, data, container);
-
       if (prop.dynamicProperties.length) {
         prop.getValueAtTime = getTransformValueAtTime.bind(prop);
       } else {
         prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop);
       }
-
       prop.setGroupProperty = expressionHelpers.setGroupProperty;
       return prop;
     };
-
     var propertyGetProp = PropertyFactory.getProp;
-
     PropertyFactory.getProp = function (elem, data, type, mult, container) {
-      var prop = propertyGetProp(elem, data, type, mult, container); // prop.getVelocityAtTime = getVelocityAtTime;
+      var prop = propertyGetProp(elem, data, type, mult, container);
+      // prop.getVelocityAtTime = getVelocityAtTime;
       // prop.loopOut = loopOut;
       // prop.loopIn = loopIn;
-
       if (prop.kf) {
         prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop);
       } else {
         prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop);
       }
-
       prop.setGroupProperty = expressionHelpers.setGroupProperty;
       prop.loopOut = loopOut;
       prop.loopIn = loopIn;
@@ -17302,25 +14595,20 @@
       prop.numKeys = data.a === 1 ? data.k.length : 0;
       prop.propertyIndex = data.ix;
       var value = 0;
-
       if (type !== 0) {
         value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length);
       }
-
       prop._cachingAtTime = {
         lastFrame: initialDefaultFrame,
         lastIndex: 0,
         value: value
       };
       expressionHelpers.searchExpressions(elem, data, prop);
-
       if (prop.k) {
         container.addDynamicProperty(prop);
       }
-
       return prop;
     };
-
     function getShapeValueAtTime(frameNum) {
       // For now this caching object is created only when needed instead of creating it when the shape is initialized.
       if (!this._cachingAtTime) {
@@ -17330,42 +14618,32 @@
           lastTime: initialDefaultFrame
         };
       }
-
       frameNum *= this.elem.globalData.frameRate;
       frameNum -= this.offsetTime;
-
       if (frameNum !== this._cachingAtTime.lastTime) {
         this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0;
         this._cachingAtTime.lastTime = frameNum;
         this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime);
       }
-
       return this._cachingAtTime.shapeValue;
     }
-
     var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction();
     var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction();
-
     function ShapeExpressions() {}
-
     ShapeExpressions.prototype = {
       vertices: function vertices(prop, time) {
         if (this.k) {
           this.getValue();
         }
-
         var shapePath = this.v;
-
         if (time !== undefined) {
           shapePath = this.getValueAtTime(time, 0);
         }
-
         var i;
         var len = shapePath._length;
         var vertices = shapePath[prop];
         var points = shapePath.v;
         var arr = createSizedArray(len);
-
         for (i = 0; i < len; i += 1) {
           if (prop === 'i' || prop === 'o') {
             arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]];
@@ -17373,7 +14651,6 @@
             arr[i] = [vertices[i][0], vertices[i][1]];
           }
         }
-
         return arr;
       },
       points: function points(time) {
@@ -17390,15 +14667,12 @@
       },
       pointOnPath: function pointOnPath(perc, time) {
         var shapePath = this.v;
-
         if (time !== undefined) {
           shapePath = this.getValueAtTime(time, 0);
         }
-
         if (!this._segmentsLength) {
           this._segmentsLength = bez.getSegmentsLength(shapePath);
         }
-
         var segmentsLength = this._segmentsLength;
         var lengths = segmentsLength.lengths;
         var lengthPos = segmentsLength.totalLength * perc;
@@ -17406,7 +14680,6 @@
         var len = lengths.length;
         var accumulatedLength = 0;
         var pt;
-
         while (i < len) {
           if (accumulatedLength + lengths[i].addedLength > lengthPos) {
             var initIndex = i;
@@ -17417,14 +14690,11 @@
           } else {
             accumulatedLength += lengths[i].addedLength;
           }
-
           i += 1;
         }
-
         if (!pt) {
           pt = shapePath.c ? [shapePath.v[0][0], shapePath.v[0][1]] : [shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1]];
         }
-
         return pt;
       },
       vectorOnPath: function vectorOnPath(perc, time, vectorType) {
@@ -17436,17 +14706,14 @@
           // eslint-disable-line eqeqeq
           perc = 0.999;
         }
-
         var pt1 = this.pointOnPath(perc, time);
         var pt2 = this.pointOnPath(perc + 0.001, time);
         var xLength = pt2[0] - pt1[0];
         var yLength = pt2[1] - pt1[1];
         var magnitude = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2));
-
         if (magnitude === 0) {
           return [0, 0];
         }
-
         var unitVector = vectorType === 'tangent' ? [xLength / magnitude, yLength / magnitude] : [-yLength / magnitude, xLength / magnitude];
         return unitVector;
       },
@@ -17464,26 +14731,21 @@
     KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime;
     KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression;
     var propertyGetShapeProp = ShapePropertyFactory.getShapeProp;
-
     ShapePropertyFactory.getShapeProp = function (elem, data, type, arr, trims) {
       var prop = propertyGetShapeProp(elem, data, type, arr, trims);
       prop.propertyIndex = data.ix;
       prop.lock = false;
-
       if (type === 3) {
         expressionHelpers.searchExpressions(elem, data.pt, prop);
       } else if (type === 4) {
         expressionHelpers.searchExpressions(elem, data.ks, prop);
       }
-
       if (prop.k) {
         elem.addDynamicProperty(prop);
       }
-
       return prop;
     };
   }
-
   function initialize$1() {
     addPropertyDecorator();
   }
@@ -17495,13 +14757,10 @@
         this.addEffect(this.getExpressionValue.bind(this));
         return true;
       }
-
       return null;
     }
-
     TextProperty.prototype.getExpressionValue = function (currentValue, text) {
       var newValue = this.calculateExpression(text);
-
       if (currentValue.t !== newValue) {
         var newData = {};
         this.copyData(newData, currentValue);
@@ -17509,46 +14768,38 @@
         newData.__complete = false;
         return newData;
       }
-
       return currentValue;
     };
-
     TextProperty.prototype.searchProperty = function () {
       var isKeyframed = this.searchKeyframes();
       var hasExpressions = this.searchExpressions();
       this.kf = isKeyframed || hasExpressions;
       return this.kf;
     };
-
     TextProperty.prototype.searchExpressions = searchExpressions;
   }
-
   function initialize() {
     addDecorator();
   }
 
   function SVGComposableEffect() {}
-
   SVGComposableEffect.prototype = {
     createMergeNode: function createMergeNode(resultId, ins) {
       var feMerge = createNS('feMerge');
       feMerge.setAttribute('result', resultId);
       var feMergeNode;
       var i;
-
       for (i = 0; i < ins.length; i += 1) {
         feMergeNode = createNS('feMergeNode');
         feMergeNode.setAttribute('in', ins[i]);
         feMerge.appendChild(feMergeNode);
         feMerge.appendChild(feMergeNode);
       }
-
       return feMerge;
     }
   };
 
   var linearFilterValue = '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0';
-
   function SVGTintFilter(filter, filterManager, elem, id, source) {
     this.filterManager = filterManager;
     var feColorMatrix = createNS('feColorMatrix');
@@ -17568,9 +14819,7 @@
     var feMerge = this.createMergeNode(id, [source, id + '_tint_1', id + '_tint_2']);
     filter.appendChild(feMerge);
   }
-
   extendPrototype([SVGComposableEffect], SVGTintFilter);
-
   SVGTintFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var colorBlack = this.filterManager.effectElements[0].p.v;
@@ -17591,7 +14840,6 @@
     filter.appendChild(feColorMatrix);
     this.matrixFilter = feColorMatrix;
   }
-
   SVGFillFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var color = this.filterManager.effectElements[2].p.v;
@@ -17606,14 +14854,12 @@
     this.elem = elem;
     this.paths = [];
   }
-
   SVGStrokeEffect.prototype.initialize = function () {
     var elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
     var path;
     var groupPath;
     var i;
     var len;
-
     if (this.filterManager.effectElements[1].p.v === 1) {
       len = this.elem.maskManager.masksProperties.length;
       i = 0;
@@ -17621,12 +14867,10 @@
       i = this.filterManager.effectElements[0].p.v - 1;
       len = i + 1;
     }
-
     groupPath = createNS('g');
     groupPath.setAttribute('fill', 'none');
     groupPath.setAttribute('stroke-linecap', 'round');
     groupPath.setAttribute('stroke-dashoffset', 1);
-
     for (i; i < len; i += 1) {
       path = createNS('path');
       groupPath.appendChild(path);
@@ -17635,7 +14879,6 @@
         m: i
       });
     }
-
     if (this.filterManager.effectElements[10].p.v === 3) {
       var mask = createNS('mask');
       var id = createElementID();
@@ -17645,54 +14888,43 @@
       this.elem.globalData.defs.appendChild(mask);
       var g = createNS('g');
       g.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
-
       while (elemChildren[0]) {
         g.appendChild(elemChildren[0]);
       }
-
       this.elem.layerElement.appendChild(g);
       this.masker = mask;
       groupPath.setAttribute('stroke', '#fff');
     } else if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
       if (this.filterManager.effectElements[10].p.v === 2) {
         elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
-
         while (elemChildren.length) {
           this.elem.layerElement.removeChild(elemChildren[0]);
         }
       }
-
       this.elem.layerElement.appendChild(groupPath);
       this.elem.layerElement.removeAttribute('mask');
       groupPath.setAttribute('stroke', '#fff');
     }
-
     this.initialized = true;
     this.pathMasker = groupPath;
   };
-
   SVGStrokeEffect.prototype.renderFrame = function (forceRender) {
     if (!this.initialized) {
       this.initialize();
     }
-
     var i;
     var len = this.paths.length;
     var mask;
     var path;
-
     for (i = 0; i < len; i += 1) {
       if (this.paths[i].m !== -1) {
         mask = this.elem.maskManager.viewData[this.paths[i].m];
         path = this.paths[i].p;
-
         if (forceRender || this.filterManager._mdf || mask.prop._mdf) {
           path.setAttribute('d', mask.lastPath);
         }
-
         if (forceRender || this.filterManager.effectElements[9].p._mdf || this.filterManager.effectElements[4].p._mdf || this.filterManager.effectElements[7].p._mdf || this.filterManager.effectElements[8].p._mdf || mask.prop._mdf) {
           var dasharrayValue;
-
           if (this.filterManager.effectElements[7].p.v !== 0 || this.filterManager.effectElements[8].p.v !== 100) {
             var s = Math.min(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
             var e = Math.max(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
@@ -17702,29 +14934,23 @@
             var segment = 1 + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
             var units = Math.floor(lineLength / segment);
             var j;
-
             for (j = 0; j < units; j += 1) {
               dasharrayValue += '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01 + ' ';
             }
-
             dasharrayValue += '0 ' + l * 10 + ' 0 0';
           } else {
             dasharrayValue = '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
           }
-
           path.setAttribute('stroke-dasharray', dasharrayValue);
         }
       }
     }
-
     if (forceRender || this.filterManager.effectElements[4].p._mdf) {
       this.pathMasker.setAttribute('stroke-width', this.filterManager.effectElements[4].p.v * 2);
     }
-
     if (forceRender || this.filterManager.effectElements[6].p._mdf) {
       this.pathMasker.setAttribute('opacity', this.filterManager.effectElements[6].p.v);
     }
-
     if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
       if (forceRender || this.filterManager.effectElements[3].p._mdf) {
         var color = this.filterManager.effectElements[3].p.v;
@@ -17758,7 +14984,6 @@
     this.feFuncB = feFuncB;
     filter.appendChild(feComponentTransfer);
   }
-
   SVGTritoneFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var color1 = this.filterManager.effectElements[0].p.v;
@@ -17776,33 +15001,29 @@
   function SVGProLevelsFilter(filter, filterManager, elem, id) {
     this.filterManager = filterManager;
     var effectElements = this.filterManager.effectElements;
-    var feComponentTransfer = createNS('feComponentTransfer'); // Red
+    var feComponentTransfer = createNS('feComponentTransfer');
 
+    // Red
     if (effectElements[10].p.k || effectElements[10].p.v !== 0 || effectElements[11].p.k || effectElements[11].p.v !== 1 || effectElements[12].p.k || effectElements[12].p.v !== 1 || effectElements[13].p.k || effectElements[13].p.v !== 0 || effectElements[14].p.k || effectElements[14].p.v !== 1) {
       this.feFuncR = this.createFeFunc('feFuncR', feComponentTransfer);
-    } // Green
-
-
+    }
+    // Green
     if (effectElements[17].p.k || effectElements[17].p.v !== 0 || effectElements[18].p.k || effectElements[18].p.v !== 1 || effectElements[19].p.k || effectElements[19].p.v !== 1 || effectElements[20].p.k || effectElements[20].p.v !== 0 || effectElements[21].p.k || effectElements[21].p.v !== 1) {
       this.feFuncG = this.createFeFunc('feFuncG', feComponentTransfer);
-    } // Blue
-
-
+    }
+    // Blue
     if (effectElements[24].p.k || effectElements[24].p.v !== 0 || effectElements[25].p.k || effectElements[25].p.v !== 1 || effectElements[26].p.k || effectElements[26].p.v !== 1 || effectElements[27].p.k || effectElements[27].p.v !== 0 || effectElements[28].p.k || effectElements[28].p.v !== 1) {
       this.feFuncB = this.createFeFunc('feFuncB', feComponentTransfer);
-    } // Alpha
-
-
+    }
+    // Alpha
     if (effectElements[31].p.k || effectElements[31].p.v !== 0 || effectElements[32].p.k || effectElements[32].p.v !== 1 || effectElements[33].p.k || effectElements[33].p.v !== 1 || effectElements[34].p.k || effectElements[34].p.v !== 0 || effectElements[35].p.k || effectElements[35].p.v !== 1) {
       this.feFuncA = this.createFeFunc('feFuncA', feComponentTransfer);
-    } // RGB
-
-
+    }
+    // RGB
     if (this.feFuncR || this.feFuncG || this.feFuncB || this.feFuncA) {
       feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
       filter.appendChild(feComponentTransfer);
     }
-
     if (effectElements[3].p.k || effectElements[3].p.v !== 0 || effectElements[4].p.k || effectElements[4].p.v !== 1 || effectElements[5].p.k || effectElements[5].p.v !== 1 || effectElements[6].p.k || effectElements[6].p.v !== 0 || effectElements[7].p.k || effectElements[7].p.v !== 1) {
       feComponentTransfer = createNS('feComponentTransfer');
       feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
@@ -17813,14 +15034,12 @@
       this.feFuncBComposed = this.createFeFunc('feFuncB', feComponentTransfer);
     }
   }
-
   SVGProLevelsFilter.prototype.createFeFunc = function (type, feComponentTransfer) {
     var feFunc = createNS(type);
     feFunc.setAttribute('type', 'table');
     feComponentTransfer.appendChild(feFunc);
     return feFunc;
   };
-
   SVGProLevelsFilter.prototype.getTableValue = function (inputBlack, inputWhite, gamma, outputBlack, outputWhite) {
     var cnt = 0;
     var segments = 256;
@@ -17834,10 +15053,8 @@
     var pos = 0;
     var outputDelta = outputWhite - outputBlack;
     var inputDelta = inputWhite - inputBlack;
-
     while (cnt <= 256) {
       perc = cnt / 256;
-
       if (perc <= min) {
         colorValue = inputDelta < 0 ? outputWhite : outputBlack;
       } else if (perc >= max) {
@@ -17845,42 +15062,34 @@
       } else {
         colorValue = outputBlack + outputDelta * Math.pow((perc - inputBlack) / inputDelta, 1 / gamma);
       }
-
       table[pos] = colorValue;
       pos += 1;
       cnt += 256 / (segments - 1);
     }
-
     return table.join(' ');
   };
-
   SVGProLevelsFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var val;
       var effectElements = this.filterManager.effectElements;
-
       if (this.feFuncRComposed && (forceRender || effectElements[3].p._mdf || effectElements[4].p._mdf || effectElements[5].p._mdf || effectElements[6].p._mdf || effectElements[7].p._mdf)) {
         val = this.getTableValue(effectElements[3].p.v, effectElements[4].p.v, effectElements[5].p.v, effectElements[6].p.v, effectElements[7].p.v);
         this.feFuncRComposed.setAttribute('tableValues', val);
         this.feFuncGComposed.setAttribute('tableValues', val);
         this.feFuncBComposed.setAttribute('tableValues', val);
       }
-
       if (this.feFuncR && (forceRender || effectElements[10].p._mdf || effectElements[11].p._mdf || effectElements[12].p._mdf || effectElements[13].p._mdf || effectElements[14].p._mdf)) {
         val = this.getTableValue(effectElements[10].p.v, effectElements[11].p.v, effectElements[12].p.v, effectElements[13].p.v, effectElements[14].p.v);
         this.feFuncR.setAttribute('tableValues', val);
       }
-
       if (this.feFuncG && (forceRender || effectElements[17].p._mdf || effectElements[18].p._mdf || effectElements[19].p._mdf || effectElements[20].p._mdf || effectElements[21].p._mdf)) {
         val = this.getTableValue(effectElements[17].p.v, effectElements[18].p.v, effectElements[19].p.v, effectElements[20].p.v, effectElements[21].p.v);
         this.feFuncG.setAttribute('tableValues', val);
       }
-
       if (this.feFuncB && (forceRender || effectElements[24].p._mdf || effectElements[25].p._mdf || effectElements[26].p._mdf || effectElements[27].p._mdf || effectElements[28].p._mdf)) {
         val = this.getTableValue(effectElements[24].p.v, effectElements[25].p.v, effectElements[26].p.v, effectElements[27].p.v, effectElements[28].p.v);
         this.feFuncB.setAttribute('tableValues', val);
       }
-
       if (this.feFuncA && (forceRender || effectElements[31].p._mdf || effectElements[32].p._mdf || effectElements[33].p._mdf || effectElements[34].p._mdf || effectElements[35].p._mdf)) {
         val = this.getTableValue(effectElements[31].p.v, effectElements[32].p.v, effectElements[33].p.v, effectElements[34].p.v, effectElements[35].p.v);
         this.feFuncA.setAttribute('tableValues', val);
@@ -17922,26 +15131,22 @@
     feComposite.setAttribute('result', id + '_drop_shadow_4');
     filter.appendChild(feComposite);
     var feMerge = this.createMergeNode(id, [id + '_drop_shadow_4', source]);
-    filter.appendChild(feMerge); //
+    filter.appendChild(feMerge);
+    //
   }
-
   extendPrototype([SVGComposableEffect], SVGDropShadowEffect);
-
   SVGDropShadowEffect.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       if (forceRender || this.filterManager.effectElements[4].p._mdf) {
         this.feGaussianBlur.setAttribute('stdDeviation', this.filterManager.effectElements[4].p.v / 4);
       }
-
       if (forceRender || this.filterManager.effectElements[0].p._mdf) {
         var col = this.filterManager.effectElements[0].p.v;
         this.feFlood.setAttribute('flood-color', rgbToHex(Math.round(col[0] * 255), Math.round(col[1] * 255), Math.round(col[2] * 255)));
       }
-
       if (forceRender || this.filterManager.effectElements[1].p._mdf) {
         this.feFlood.setAttribute('flood-opacity', this.filterManager.effectElements[1].p.v / 255);
       }
-
       if (forceRender || this.filterManager.effectElements[2].p._mdf || this.filterManager.effectElements[3].p._mdf) {
         var distance = this.filterManager.effectElements[3].p.v;
         var angle = (this.filterManager.effectElements[2].p.v - 90) * degToRads;
@@ -17954,7 +15159,6 @@
   };
 
   var _svgMatteSymbols = [];
-
   function SVGMatte3Effect(filterElem, filterManager, elem) {
     this.initialized = false;
     this.filterManager = filterManager;
@@ -17965,66 +15169,50 @@
     elem.matteElement.appendChild(elem.transformedElement);
     elem.baseElement = elem.matteElement;
   }
-
   SVGMatte3Effect.prototype.findSymbol = function (mask) {
     var i = 0;
     var len = _svgMatteSymbols.length;
-
     while (i < len) {
       if (_svgMatteSymbols[i] === mask) {
         return _svgMatteSymbols[i];
       }
-
       i += 1;
     }
-
     return null;
   };
-
   SVGMatte3Effect.prototype.replaceInParent = function (mask, symbolId) {
     var parentNode = mask.layerElement.parentNode;
-
     if (!parentNode) {
       return;
     }
-
     var children = parentNode.children;
     var i = 0;
     var len = children.length;
-
     while (i < len) {
       if (children[i] === mask.layerElement) {
         break;
       }
-
       i += 1;
     }
-
     var nextChild;
-
     if (i <= len - 2) {
       nextChild = children[i + 1];
     }
-
     var useElem = createNS('use');
     useElem.setAttribute('href', '#' + symbolId);
-
     if (nextChild) {
       parentNode.insertBefore(useElem, nextChild);
     } else {
       parentNode.appendChild(useElem);
     }
   };
-
   SVGMatte3Effect.prototype.setElementAsMask = function (elem, mask) {
     if (!this.findSymbol(mask)) {
       var symbolId = createElementID();
       var masker = createNS('mask');
       masker.setAttribute('id', mask.layerId);
       masker.setAttribute('mask-type', 'alpha');
-
       _svgMatteSymbols.push(mask);
-
       var defs = elem.globalData.defs;
       defs.appendChild(masker);
       var symbol = createNS('symbol');
@@ -18038,27 +15226,21 @@
       mask.data.hd = false;
       mask.show();
     }
-
     elem.setMatte(mask.layerId);
   };
-
   SVGMatte3Effect.prototype.initialize = function () {
     var ind = this.filterManager.effectElements[0].p.v;
     var elements = this.elem.comp.elements;
     var i = 0;
     var len = elements.length;
-
     while (i < len) {
       if (elements[i] && elements[i].data.ind === ind) {
         this.setElementAsMask(this.elem, elements[i]);
       }
-
       i += 1;
     }
-
     this.initialized = true;
   };
-
   SVGMatte3Effect.prototype.renderFrame = function () {
     if (!this.initialized) {
       this.initialize();
@@ -18077,36 +15259,34 @@
     filter.appendChild(feGaussianBlur);
     this.feGaussianBlur = feGaussianBlur;
   }
-
   SVGGaussianBlurEffect.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       // Empirical value, matching AE's blur appearance.
       var kBlurrinessToSigma = 0.3;
-      var sigma = this.filterManager.effectElements[0].p.v * kBlurrinessToSigma; // Dimensions mapping:
+      var sigma = this.filterManager.effectElements[0].p.v * kBlurrinessToSigma;
+
+      // Dimensions mapping:
       //
       //   1 -> horizontal & vertical
       //   2 -> horizontal only
       //   3 -> vertical only
       //
-
       var dimensions = this.filterManager.effectElements[1].p.v;
       var sigmaX = dimensions == 3 ? 0 : sigma; // eslint-disable-line eqeqeq
-
       var sigmaY = dimensions == 2 ? 0 : sigma; // eslint-disable-line eqeqeq
 
-      this.feGaussianBlur.setAttribute('stdDeviation', sigmaX + ' ' + sigmaY); // Repeat edges mapping:
+      this.feGaussianBlur.setAttribute('stdDeviation', sigmaX + ' ' + sigmaY);
+
+      // Repeat edges mapping:
       //
       //   0 -> off -> duplicate
       //   1 -> on  -> wrap
-
       var edgeMode = this.filterManager.effectElements[2].p.v == 1 ? 'wrap' : 'duplicate'; // eslint-disable-line eqeqeq
-
       this.feGaussianBlur.setAttribute('edgeMode', edgeMode);
     }
   };
 
   function TransformEffect() {}
-
   TransformEffect.prototype.init = function (effectsManager) {
     this.effectsManager = effectsManager;
     this.type = effectTypes.TRANSFORM_EFFECT;
@@ -18115,11 +15295,9 @@
     this._mdf = false;
     this._opMdf = false;
   };
-
   TransformEffect.prototype.renderFrame = function (forceFrame) {
     this._opMdf = false;
     this._mdf = false;
-
     if (forceFrame || this.effectsManager._mdf) {
       var effectElements = this.effectsManager.effectElements;
       var anchor = effectElements[0].p.v;
@@ -18137,7 +15315,6 @@
       this.matrix.skewFromAxis(-skew * degToRads, (skewAxis + 90) * degToRads);
       this.matrix.translate(position[0], position[1], 0);
       this._mdf = true;
-
       if (this.opacity !== effectElements[8].p.v) {
         this.opacity = effectElements[8].p.v;
         this._opMdf = true;
@@ -18148,9 +15325,9 @@
   function SVGTransformEffect(_, filterManager) {
     this.init(filterManager);
   }
-
   extendPrototype([TransformEffect], SVGTransformEffect);
 
+  // Registering expression plugin
   setExpressionsPlugin(Expressions);
   setExpressionInterfaces(getInterface);
   initialize$1();
diff --git a/build/player/lottie_html.min.js b/build/player/lottie_html.min.js
index 62c951d..c7aec6b 100644
--- a/build/player/lottie_html.min.js
+++ b/build/player/lottie_html.min.js
@@ -1 +1 @@
-"undefined"!=typeof navigator&&function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lottie=e()}(this,(function(){"use strict";var svgNS="http://www.w3.org/2000/svg",locationHref="",_useWebWorker=!1,initialDefaultFrame=-999999,setWebWorker=function(t){_useWebWorker=!!t},getWebWorker=function(){return _useWebWorker},setLocationHref=function(t){locationHref=t},getLocationHref=function(){return locationHref};function createTag(t){return document.createElement(t)}function extendPrototype(t,e){var i,r,s=t.length;for(i=0;i<s;i+=1)for(var a in r=t[i].prototype)Object.prototype.hasOwnProperty.call(r,a)&&(e.prototype[a]=r[a])}function getDescriptor(t,e){return Object.getOwnPropertyDescriptor(t,e)}function createProxyFunction(t){function e(){}return e.prototype=t,e}var audioControllerFactory=function(){function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].pause()},resume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].resume()},setRate:function(t){var e,i=this.audios.length;for(e=0;e<i;e+=1)this.audios[e].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}}(),createTypedArray=function(){function t(t,e){var i,r=0,s=[];switch(t){case"int16":case"uint8c":i=1;break;default:i=1.1}for(r=0;r<e;r+=1)s.push(i);return s}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(e,i){return"float32"===e?new Float32Array(i):"int16"===e?new Int16Array(i):"uint8c"===e?new Uint8ClampedArray(i):t(e,i)}:t}();function createSizedArray(t){return Array.apply(null,{length:t})}function _typeof$6(t){return _typeof$6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$6(t)}var subframeEnabled=!0,expressionsPlugin=null,expressionsInterfaces=null,idPrefix$1="",isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),_shouldRoundValues=!1,bmPow=Math.pow,bmSqrt=Math.sqrt,bmFloor=Math.floor,bmMax=Math.max,bmMin=Math.min,BMMath={};function ProjectInterface$1(){return{}}!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],i=e.length;for(t=0;t<i;t+=1)BMMath[e[t]]=Math[e[t]]}(),BMMath.random=Math.random,BMMath.abs=function(t){if("object"===_typeof$6(t)&&t.length){var e,i=createSizedArray(t.length),r=t.length;for(e=0;e<r;e+=1)i[e]=Math.abs(t[e]);return i}return Math.abs(t)};var defaultCurveSegments=150,degToRads=Math.PI/180,roundCorner=.5519;function roundValues(t){_shouldRoundValues=!!t}function bmRnd(t){return _shouldRoundValues?Math.round(t):t}function styleDiv(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin="0 0",t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility="visible",t.style.webkitBackfaceVisibility="visible",t.style.transformStyle="preserve-3d",t.style.webkitTransformStyle="preserve-3d",t.style.mozTransformStyle="preserve-3d"}function BMEnterFrameEvent(t,e,i,r){this.type=t,this.currentTime=e,this.totalTime=i,this.direction=r<0?-1:1}function BMCompleteEvent(t,e){this.type=t,this.direction=e<0?-1:1}function BMCompleteLoopEvent(t,e,i,r){this.type=t,this.currentLoop=i,this.totalLoops=e,this.direction=r<0?-1:1}function BMSegmentStartEvent(t,e,i){this.type=t,this.firstFrame=e,this.totalFrames=i}function BMDestroyEvent(t,e){this.type=t,this.target=e}function BMRenderFrameErrorEvent(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function BMConfigErrorEvent(t){this.type="configError",this.nativeError=t}function BMAnimationConfigErrorEvent(t,e){this.type=t,this.nativeError=e}var createElementID=(_count=0,function(){return idPrefix$1+"__lottie_element_"+(_count+=1)}),_count;function HSVtoRGB(t,e,i){var r,s,a,n,o,h,l,p;switch(h=i*(1-e),l=i*(1-(o=6*t-(n=Math.floor(6*t)))*e),p=i*(1-(1-o)*e),n%6){case 0:r=i,s=p,a=h;break;case 1:r=l,s=i,a=h;break;case 2:r=h,s=i,a=p;break;case 3:r=h,s=l,a=i;break;case 4:r=p,s=h,a=i;break;case 5:r=i,s=h,a=l}return[r,s,a]}function RGBtoHSV(t,e,i){var r,s=Math.max(t,e,i),a=Math.min(t,e,i),n=s-a,o=0===s?0:n/s,h=s/255;switch(s){case a:r=0;break;case t:r=e-i+n*(e<i?6:0),r/=6*n;break;case e:r=i-t+2*n,r/=6*n;break;case i:r=t-e+4*n,r/=6*n}return[r,o,h]}function addSaturationToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[1]+=e,i[1]>1?i[1]=1:i[1]<=0&&(i[1]=0),HSVtoRGB(i[0],i[1],i[2])}function addBrightnessToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[2]+=e,i[2]>1?i[2]=1:i[2]<0&&(i[2]=0),HSVtoRGB(i[0],i[1],i[2])}function addHueToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[0]+=e/360,i[0]>1?i[0]-=1:i[0]<0&&(i[0]+=1),HSVtoRGB(i[0],i[1],i[2])}var rgbToHex=function(){var t,e,i=[];for(t=0;t<256;t+=1)e=t.toString(16),i[t]=1===e.length?"0"+e:e;return function(t,e,r){return t<0&&(t=0),e<0&&(e=0),r<0&&(r=0),"#"+i[t]+i[e]+i[r]}}(),setSubframeEnabled=function(t){subframeEnabled=!!t},getSubframeEnabled=function(){return subframeEnabled},setExpressionsPlugin=function(t){expressionsPlugin=t},getExpressionsPlugin=function(){return expressionsPlugin},setExpressionInterfaces=function(t){expressionsInterfaces=t},getExpressionInterfaces=function(){return expressionsInterfaces},setDefaultCurveSegments=function(t){defaultCurveSegments=t},getDefaultCurveSegments=function(){return defaultCurveSegments},setIdPrefix=function(t){idPrefix$1=t},getIdPrefix=function(){return idPrefix$1};function createNS(t){return document.createElementNS(svgNS,t)}function _typeof$5(t){return _typeof$5="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$5(t)}var dataManager=function(){var t,e,i=1,r=[],s={onmessage:function(){},postMessage:function(e){t({data:e})}},a={postMessage:function(t){s.onmessage({data:t})}};function n(){e||(e=function(e){if(window.Worker&&window.Blob&&getWebWorker()){var i=new Blob(["var _workerSelf = self; self.onmessage = ",e.toString()],{type:"text/javascript"}),r=URL.createObjectURL(i);return new Worker(r)}return t=e,s}((function(t){if(a.dataManager||(a.dataManager=function(){function t(s,a){var n,o,h,l,p,m,c=s.length;for(o=0;o<c;o+=1)if("ks"in(n=s[o])&&!n.completed){if(n.completed=!0,n.hasMask){var u=n.masksProperties;for(l=u.length,h=0;h<l;h+=1)if(u[h].pt.k.i)r(u[h].pt.k);else for(m=u[h].pt.k.length,p=0;p<m;p+=1)u[h].pt.k[p].s&&r(u[h].pt.k[p].s[0]),u[h].pt.k[p].e&&r(u[h].pt.k[p].e[0])}0===n.ty?(n.layers=e(n.refId,a),t(n.layers,a)):4===n.ty?i(n.shapes):5===n.ty&&f(n)}}function e(t,e){var i=function(t,e){for(var i=0,r=e.length;i<r;){if(e[i].id===t)return e[i];i+=1}return null}(t,e);return i?i.layers.__used?JSON.parse(JSON.stringify(i.layers)):(i.layers.__used=!0,i.layers):null}function i(t){var e,s,a;for(e=t.length-1;e>=0;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)r(t[e].ks.k);else for(a=t[e].ks.k.length,s=0;s<a;s+=1)t[e].ks.k[s].s&&r(t[e].ks.k[s].s[0]),t[e].ks.k[s].e&&r(t[e].ks.k[s].e[0]);else"gr"===t[e].ty&&i(t[e].it)}function r(t){var e,i=t.i.length;for(e=0;e<i;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function s(t,e){var i=e?e.split("."):[100,100,100];return t[0]>i[0]||!(i[0]>t[0])&&(t[1]>i[1]||!(i[1]>t[1])&&(t[2]>i[2]||!(i[2]>t[2])&&null))}var a,n=function(){var t=[4,4,14];function e(t){var e,i,r,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(r=void 0,r=(i=t[e]).t.d,i.t.d={k:[{s:r,t:0}]})}return function(i){if(s(t,i.v)&&(e(i.layers),i.assets)){var r,a=i.assets.length;for(r=0;r<a;r+=1)i.assets[r].layers&&e(i.assets[r].layers)}}}(),o=(a=[4,7,99],function(t){if(t.chars&&!s(a,t.v)){var e,r=t.chars.length;for(e=0;e<r;e+=1){var n=t.chars[e];n.data&&n.data.shapes&&(i(n.data.shapes),n.data.ip=0,n.data.op=99999,n.data.st=0,n.data.sr=1,n.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[e].t||(n.data.shapes.push({ty:"no"}),n.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}}}),h=function(){var t=[5,7,15];function e(t){var e,i,r=t.length;for(e=0;e<r;e+=1)5===t[e].ty&&(i=void 0,"number"==typeof(i=t[e].t.p).a&&(i.a={a:0,k:i.a}),"number"==typeof i.p&&(i.p={a:0,k:i.p}),"number"==typeof i.r&&(i.r={a:0,k:i.r}))}return function(i){if(s(t,i.v)&&(e(i.layers),i.assets)){var r,a=i.assets.length;for(r=0;r<a;r+=1)i.assets[r].layers&&e(i.assets[r].layers)}}}(),l=function(){var t=[4,1,9];function e(t){var i,r,s,a=t.length;for(i=0;i<a;i+=1)if("gr"===t[i].ty)e(t[i].it);else if("fl"===t[i].ty||"st"===t[i].ty)if(t[i].c.k&&t[i].c.k[0].i)for(s=t[i].c.k.length,r=0;r<s;r+=1)t[i].c.k[r].s&&(t[i].c.k[r].s[0]/=255,t[i].c.k[r].s[1]/=255,t[i].c.k[r].s[2]/=255,t[i].c.k[r].s[3]/=255),t[i].c.k[r].e&&(t[i].c.k[r].e[0]/=255,t[i].c.k[r].e[1]/=255,t[i].c.k[r].e[2]/=255,t[i].c.k[r].e[3]/=255);else t[i].c.k[0]/=255,t[i].c.k[1]/=255,t[i].c.k[2]/=255,t[i].c.k[3]/=255}function i(t){var i,r=t.length;for(i=0;i<r;i+=1)4===t[i].ty&&e(t[i].shapes)}return function(e){if(s(t,e.v)&&(i(e.layers),e.assets)){var r,a=e.assets.length;for(r=0;r<a;r+=1)e.assets[r].layers&&i(e.assets[r].layers)}}}(),p=function(){var t=[4,4,18];function e(t){var i,r,s;for(i=t.length-1;i>=0;i-=1)if("sh"===t[i].ty)if(t[i].ks.k.i)t[i].ks.k.c=t[i].closed;else for(s=t[i].ks.k.length,r=0;r<s;r+=1)t[i].ks.k[r].s&&(t[i].ks.k[r].s[0].c=t[i].closed),t[i].ks.k[r].e&&(t[i].ks.k[r].e[0].c=t[i].closed);else"gr"===t[i].ty&&e(t[i].it)}function i(t){var i,r,s,a,n,o,h=t.length;for(r=0;r<h;r+=1){if((i=t[r]).hasMask){var l=i.masksProperties;for(a=l.length,s=0;s<a;s+=1)if(l[s].pt.k.i)l[s].pt.k.c=l[s].cl;else for(o=l[s].pt.k.length,n=0;n<o;n+=1)l[s].pt.k[n].s&&(l[s].pt.k[n].s[0].c=l[s].cl),l[s].pt.k[n].e&&(l[s].pt.k[n].e[0].c=l[s].cl)}4===i.ty&&e(i.shapes)}}return function(e){if(s(t,e.v)&&(i(e.layers),e.assets)){var r,a=e.assets.length;for(r=0;r<a;r+=1)e.assets[r].layers&&i(e.assets[r].layers)}}}();function f(t){0===t.t.a.length&&t.t.p}var m={completeData:function(i){i.__complete||(l(i),n(i),o(i),h(i),p(i),t(i.layers,i.assets),function(i,r){if(i){var s=0,a=i.length;for(s=0;s<a;s+=1)1===i[s].t&&(i[s].data.layers=e(i[s].data.refId,r),t(i[s].data.layers,r))}}(i.chars,i.assets),i.__complete=!0)}};return m.checkColors=l,m.checkChars=o,m.checkPathProperties=h,m.checkShapes=p,m.completeLayers=t,m}()),a.assetLoader||(a.assetLoader=function(){function t(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")||t.response&&"object"===_typeof$5(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}return{load:function(e,i,r,s){var a,n=new XMLHttpRequest;try{n.responseType="json"}catch(t){}n.onreadystatechange=function(){if(4===n.readyState)if(200===n.status)a=t(n),r(a);else try{a=t(n),r(a)}catch(t){s&&s(t)}};try{n.open(["G","E","T"].join(""),e,!0)}catch(t){n.open(["G","E","T"].join(""),i+"/"+e,!0)}n.send()}}}()),"loadAnimation"===t.data.type)a.assetLoader.load(t.data.path,t.data.fullPath,(function(e){a.dataManager.completeData(e),a.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){a.postMessage({id:t.data.id,status:"error"})}));else if("complete"===t.data.type){var e=t.data.animation;a.dataManager.completeData(e),a.postMessage({id:t.data.id,payload:e,status:"success"})}else"loadData"===t.data.type&&a.assetLoader.load(t.data.path,t.data.fullPath,(function(e){a.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){a.postMessage({id:t.data.id,status:"error"})}))})),e.onmessage=function(t){var e=t.data,i=e.id,s=r[i];r[i]=null,"success"===e.status?s.onComplete(e.payload):s.onError&&s.onError()})}function o(t,e){var s="processId_"+(i+=1);return r[s]={onComplete:t,onError:e},s}return{loadAnimation:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:s})},loadData:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:s})},completeAnimation:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"complete",animation:t,id:s})}}}(),ImagePreloader=function(){var t=function(){var t=createTag("canvas");t.width=1,t.height=1;var e=t.getContext("2d");return e.fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1),t}();function e(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function i(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function r(t,e,i){var r="";if(t.e)r=t.p;else if(e){var s=t.p;-1!==s.indexOf("images/")&&(s=s.split("/")[1]),r=e+s}else r=i,r+=t.u?t.u:"",r+=t.p;return r}function s(t){var e=0,i=setInterval(function(){(t.getBBox().width||e>500)&&(this._imageLoaded(),clearInterval(i)),e+=1}.bind(this),50)}function a(t){var e={assetData:t},i=r(t,this.assetsPath,this.path);return dataManager.loadData(i,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}function n(){this._imageLoaded=e.bind(this),this._footageLoaded=i.bind(this),this.testImageLoaded=s.bind(this),this.createFootageData=a.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return n.prototype={loadAssets:function(t,e){var i;this.imagesLoadedCb=e;var r=t.length;for(i=0;i<r;i+=1)t[i].layers||(t[i].t&&"seq"!==t[i].t?3===t[i].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[i]))):(this.totalImages+=1,this.images.push(this._createImageData(t[i]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,i=this.images.length;e<i;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(e){var i=r(e,this.assetsPath,this.path),s=createTag("img");s.crossOrigin="anonymous",s.addEventListener("load",this._imageLoaded,!1),s.addEventListener("error",function(){a.img=t,this._imageLoaded()}.bind(this),!1),s.src=i;var a={img:s,assetData:e};return a},createImageData:function(e){var i=r(e,this.assetsPath,this.path),s=createNS("image");isSafari?this.testImageLoaded(s):s.addEventListener("load",this._imageLoaded,!1),s.addEventListener("error",function(){a.img=t,this._imageLoaded()}.bind(this),!1),s.setAttributeNS("http://www.w3.org/1999/xlink","href",i),this._elementHelper.append?this._elementHelper.append(s):this._elementHelper.appendChild(s);var a={img:s,assetData:e};return a},imageLoaded:e,footageLoaded:i,setCacheType:function(t,e){"svg"===t?(this._elementHelper=e,this._createImageData=this.createImageData.bind(this)):this._createImageData=this.createImgData.bind(this)}},n}();function BaseEvent(){}BaseEvent.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var i=this._cbs[t],r=0;r<i.length;r+=1)i[r](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var i=0,r=this._cbs[t].length;i<r;)this._cbs[t][i]===e&&(this._cbs[t].splice(i,1),i-=1,r-=1),i+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var markerParser=function(){function t(t){for(var e,i=t.split("\r\n"),r={},s=0,a=0;a<i.length;a+=1)2===(e=i[a].split(":")).length&&(r[e[0]]=e[1].trim(),s+=1);if(0===s)throw new Error;return r}return function(e){for(var i=[],r=0;r<e.length;r+=1){var s=e[r],a={time:s.tm,duration:s.dr};try{a.payload=JSON.parse(e[r].cm)}catch(i){try{a.payload=t(e[r].cm)}catch(t){a.payload={name:e[r].cm}}}i.push(a)}return i}}(),ProjectInterface=function(){function t(t){this.compositions.push(t)}return function(){function e(t){for(var e=0,i=this.compositions.length;e<i;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return e.compositions=[],e.currentFrame=0,e.registerComposition=t,e}}(),renderers={},registerRenderer=function(t,e){renderers[t]=e};function getRenderer(t){return renderers[t]}function getRegisteredRenderer(){if(renderers.canvas)return"canvas";for(var t in renderers)if(renderers[t])return t;return""}function _typeof$4(t){return _typeof$4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$4(t)}var AnimationItem=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=createElementID(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=getSubframeEnabled(),this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=ProjectInterface(),this.imagePreloader=new ImagePreloader,this.audioController=audioControllerFactory(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new BMEnterFrameEvent("drawnFrame",0,0,0),this.expressionsPlugin=getExpressionsPlugin()};extendPrototype([BaseEvent],AnimationItem),AnimationItem.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg";t.animType?e=t.animType:t.renderer&&(e=t.renderer);var i=getRenderer(e);this.renderer=new i(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||void 0===t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),dataManager.loadAnimation(t.path,this.configAnimation,this.onSetupError))},AnimationItem.prototype.onSetupError=function(){this.trigger("data_failed")},AnimationItem.prototype.setupAnimation=function(t){dataManager.completeAnimation(t,this.configAnimation)},AnimationItem.prototype.setData=function(t,e){e&&"object"!==_typeof$4(e)&&(e=JSON.parse(e));var i={wrapper:t,animationData:e},r=t.attributes;i.path=r.getNamedItem("data-animation-path")?r.getNamedItem("data-animation-path").value:r.getNamedItem("data-bm-path")?r.getNamedItem("data-bm-path").value:r.getNamedItem("bm-path")?r.getNamedItem("bm-path").value:"",i.animType=r.getNamedItem("data-anim-type")?r.getNamedItem("data-anim-type").value:r.getNamedItem("data-bm-type")?r.getNamedItem("data-bm-type").value:r.getNamedItem("bm-type")?r.getNamedItem("bm-type").value:r.getNamedItem("data-bm-renderer")?r.getNamedItem("data-bm-renderer").value:r.getNamedItem("bm-renderer")?r.getNamedItem("bm-renderer").value:getRegisteredRenderer()||"canvas";var s=r.getNamedItem("data-anim-loop")?r.getNamedItem("data-anim-loop").value:r.getNamedItem("data-bm-loop")?r.getNamedItem("data-bm-loop").value:r.getNamedItem("bm-loop")?r.getNamedItem("bm-loop").value:"";"false"===s?i.loop=!1:"true"===s?i.loop=!0:""!==s&&(i.loop=parseInt(s,10));var a=r.getNamedItem("data-anim-autoplay")?r.getNamedItem("data-anim-autoplay").value:r.getNamedItem("data-bm-autoplay")?r.getNamedItem("data-bm-autoplay").value:!r.getNamedItem("bm-autoplay")||r.getNamedItem("bm-autoplay").value;i.autoplay="false"!==a,i.name=r.getNamedItem("data-name")?r.getNamedItem("data-name").value:r.getNamedItem("data-bm-name")?r.getNamedItem("data-bm-name").value:r.getNamedItem("bm-name")?r.getNamedItem("bm-name").value:"","false"===(r.getNamedItem("data-anim-prerender")?r.getNamedItem("data-anim-prerender").value:r.getNamedItem("data-bm-prerender")?r.getNamedItem("data-bm-prerender").value:r.getNamedItem("bm-prerender")?r.getNamedItem("bm-prerender").value:"")&&(i.prerender=!1),i.path?this.setParams(i):this.trigger("destroy")},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,i,r=this.animationData.layers,s=r.length,a=t.layers,n=a.length;for(i=0;i<n;i+=1)for(e=0;e<s;){if(r[e].id===a[i].id){r[e]=a[i];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(s=t.assets.length,e=0;e<s;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,dataManager.completeAnimation(this.animationData,this.onSegmentComplete)},AnimationItem.prototype.onSegmentComplete=function(t){this.animationData=t;var e=getExpressionsPlugin();e&&e.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var i=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,dataManager.loadData(i,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},AnimationItem.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},AnimationItem.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=markerParser(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},AnimationItem.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},AnimationItem.prototype.checkLoaded=function(){if(!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()){this.isLoaded=!0;var t=getExpressionsPlugin();t&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play()}},AnimationItem.prototype.resize=function(t,e){var i="number"==typeof t?t:void 0,r="number"==typeof e?e:void 0;this.renderer.updateContainerSize(i,r)},AnimationItem.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},AnimationItem.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},AnimationItem.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},AnimationItem.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},AnimationItem.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.getMarkerData=function(t){for(var e,i=0;i<this.markers.length;i+=1)if((e=this.markers[i]).payload&&e.payload.name===t)return e;return null},AnimationItem.prototype.goToAndStop=function(t,e,i){if(!i||this.name===i){var r=Number(t);if(isNaN(r)){var s=this.getMarkerData(t);s&&this.goToAndStop(s.time,!0)}else e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier);this.pause()}},AnimationItem.prototype.goToAndPlay=function(t,e,i){if(!i||this.name===i){var r=Number(t);if(isNaN(r)){var s=this.getMarkerData(t);s&&(s.duration?this.playSegments([s.time,s.time+s.duration],!0):this.goToAndStop(s.time,!0))}else this.goToAndStop(r,e,i);this.play()}},AnimationItem.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,i=!1;e>=this.totalFrames-1&&this.frameModifier>0?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(i=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(i=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),i&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(this.frameModifier>0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var i=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?i=t:this.currentRawFrame+this.firstFrame>e&&(i=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==i&&this.goToAndStop(i,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===_typeof$4(t[0])){var i,r=t.length;for(i=0;i<r;i+=1)this.segments.push(t[i])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},AnimationItem.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},AnimationItem.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},AnimationItem.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},AnimationItem.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},AnimationItem.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},AnimationItem.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},AnimationItem.prototype.setLoop=function(t){this.loop=t},AnimationItem.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},AnimationItem.prototype.getVolume=function(){return this.audioController.getVolume()},AnimationItem.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},AnimationItem.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},AnimationItem.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},AnimationItem.prototype.getPath=function(){return this.path},AnimationItem.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var i=t.p;-1!==i.indexOf("images/")&&(i=i.split("/")[1]),e=this.assetsPath+i}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},AnimationItem.prototype.getAssetData=function(t){for(var e=0,i=this.assets.length;e<i;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},AnimationItem.prototype.hide=function(){this.renderer.hide()},AnimationItem.prototype.show=function(){this.renderer.show()},AnimationItem.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},AnimationItem.prototype.updateDocumentData=function(t,e,i){try{this.renderer.getElementByPath(t).updateDocumentData(e,i)}catch(t){}},AnimationItem.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new BMCompleteEvent(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new BMDestroyEvent(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new BMCompleteEvent(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new BMDestroyEvent(t,this))},AnimationItem.prototype.triggerRenderFrameError=function(t){var e=new BMRenderFrameErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)},AnimationItem.prototype.triggerConfigError=function(t){var e=new BMConfigErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)};var animationManager=function(){var t={},e=[],i=0,r=0,s=0,a=!0,n=!1;function o(t){for(var i=0,s=t.target;i<r;)e[i].animation===s&&(e.splice(i,1),i-=1,r-=1,s.isPaused||p()),i+=1}function h(t,i){if(!t)return null;for(var s=0;s<r;){if(e[s].elem===t&&null!==e[s].elem)return e[s].animation;s+=1}var a=new AnimationItem;return f(a,t),a.setData(t,i),a}function l(){s+=1,u()}function p(){s-=1}function f(t,i){t.addEventListener("destroy",o),t.addEventListener("_active",l),t.addEventListener("_idle",p),e.push({elem:i,animation:t}),r+=1}function m(t){var o,h=t-i;for(o=0;o<r;o+=1)e[o].animation.advanceTime(h);i=t,s&&!n?window.requestAnimationFrame(m):a=!0}function c(t){i=t,window.requestAnimationFrame(m)}function u(){!n&&s&&a&&(window.requestAnimationFrame(c),a=!1)}return t.registerAnimation=h,t.loadAnimation=function(t){var e=new AnimationItem;return f(e,null),e.setParams(t),e},t.setSpeed=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setSpeed(t,i)},t.setDirection=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setDirection(t,i)},t.play=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.play(t)},t.pause=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.pause(t)},t.stop=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.stop(t)},t.togglePause=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.togglePause(t)},t.searchAnimations=function(t,e,i){var r,s=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),a=s.length;for(r=0;r<a;r+=1)i&&s[r].setAttribute("data-bm-type",i),h(s[r],t);if(e&&0===a){i||(i="svg");var n=document.getElementsByTagName("body")[0];n.innerText="";var o=createTag("div");o.style.width="100%",o.style.height="100%",o.setAttribute("data-bm-type",i),n.appendChild(o),h(o,t)}},t.resize=function(){var t;for(t=0;t<r;t+=1)e[t].animation.resize()},t.goToAndStop=function(t,i,s){var a;for(a=0;a<r;a+=1)e[a].animation.goToAndStop(t,i,s)},t.destroy=function(t){var i;for(i=r-1;i>=0;i-=1)e[i].animation.destroy(t)},t.freeze=function(){n=!0},t.unfreeze=function(){n=!1,u()},t.setVolume=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setVolume(t,i)},t.mute=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.mute(t)},t.unmute=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.unmute(t)},t.getRegisteredAnimations=function(){var t,i=e.length,r=[];for(t=0;t<i;t+=1)r.push(e[t].animation);return r},t}(),BezierFactory=function(){var t={getBezierEasing:function(t,i,r,s,a){var n=a||("bez_"+t+"_"+i+"_"+r+"_"+s).replace(/\./g,"p");if(e[n])return e[n];var o=new l([t,i,r,s]);return e[n]=o,o}},e={};var i=.1,r="function"==typeof Float32Array;function s(t,e){return 1-3*e+3*t}function a(t,e){return 3*e-6*t}function n(t){return 3*t}function o(t,e,i){return((s(e,i)*t+a(e,i))*t+n(e))*t}function h(t,e,i){return 3*s(e,i)*t*t+2*a(e,i)*t+n(e)}function l(t){this._p=t,this._mSampleValues=r?new Float32Array(11):new Array(11),this._precomputed=!1,this.get=this.get.bind(this)}return l.prototype={get:function(t){var e=this._p[0],i=this._p[1],r=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===i&&r===s?t:0===t?0:1===t?1:o(this._getTForX(t),i,s)},_precompute:function(){var t=this._p[0],e=this._p[1],i=this._p[2],r=this._p[3];this._precomputed=!0,t===e&&i===r||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],r=0;r<11;++r)this._mSampleValues[r]=o(r*i,t,e)},_getTForX:function(t){for(var e=this._p[0],r=this._p[2],s=this._mSampleValues,a=0,n=1;10!==n&&s[n]<=t;++n)a+=i;var l=a+(t-s[--n])/(s[n+1]-s[n])*i,p=h(l,e,r);return p>=.001?function(t,e,i,r){for(var s=0;s<4;++s){var a=h(e,i,r);if(0===a)return e;e-=(o(e,i,r)-t)/a}return e}(t,l,e,r):0===p?l:function(t,e,i,r,s){var a,n,h=0;do{(a=o(n=e+(i-e)/2,r,s)-t)>0?i=n:e=n}while(Math.abs(a)>1e-7&&++h<10);return n}(t,a,a+i,e,r)}},t}(),pooling={double:function(t){return t.concat(createSizedArray(t.length))}},poolFactory=function(t,e,i){var r=0,s=t,a=createSizedArray(s);return{newElement:function(){return r?a[r-=1]:e()},release:function(t){r===s&&(a=pooling.double(a),s*=2),i&&i(t),a[r]=t,r+=1}}},bezierLengthPool=poolFactory(8,(function(){return{addedLength:0,percents:createTypedArray("float32",getDefaultCurveSegments()),lengths:createTypedArray("float32",getDefaultCurveSegments())}})),segmentsLengthPool=poolFactory(8,(function(){return{lengths:[],totalLength:0}}),(function(t){var e,i=t.lengths.length;for(e=0;e<i;e+=1)bezierLengthPool.release(t.lengths[e]);t.lengths.length=0}));function bezFunction(){var t=Math;function e(t,e,i,r,s,a){var n=t*r+e*s+i*a-s*r-a*t-i*e;return n>-.001&&n<.001}var i=function(t,e,i,r){var s,a,n,o,h,l,p=getDefaultCurveSegments(),f=0,m=[],c=[],u=bezierLengthPool.newElement();for(n=i.length,s=0;s<p;s+=1){for(h=s/(p-1),l=0,a=0;a<n;a+=1)o=bmPow(1-h,3)*t[a]+3*bmPow(1-h,2)*h*i[a]+3*(1-h)*bmPow(h,2)*r[a]+bmPow(h,3)*e[a],m[a]=o,null!==c[a]&&(l+=bmPow(m[a]-c[a],2)),c[a]=m[a];l&&(f+=l=bmSqrt(l)),u.percents[s]=h,u.lengths[s]=f}return u.addedLength=f,u};function r(t){this.segmentLength=0,this.points=new Array(t)}function s(t,e){this.partialLength=t,this.point=e}var a,n=(a={},function(t,i,n,o){var h=(t[0]+"_"+t[1]+"_"+i[0]+"_"+i[1]+"_"+n[0]+"_"+n[1]+"_"+o[0]+"_"+o[1]).replace(/\./g,"p");if(!a[h]){var l,p,f,m,c,u,d,y=getDefaultCurveSegments(),g=0,v=null;2===t.length&&(t[0]!==i[0]||t[1]!==i[1])&&e(t[0],t[1],i[0],i[1],t[0]+n[0],t[1]+n[1])&&e(t[0],t[1],i[0],i[1],i[0]+o[0],i[1]+o[1])&&(y=2);var b=new r(y);for(f=n.length,l=0;l<y;l+=1){for(d=createSizedArray(f),c=l/(y-1),u=0,p=0;p<f;p+=1)m=bmPow(1-c,3)*t[p]+3*bmPow(1-c,2)*c*(t[p]+n[p])+3*(1-c)*bmPow(c,2)*(i[p]+o[p])+bmPow(c,3)*i[p],d[p]=m,null!==v&&(u+=bmPow(d[p]-v[p],2));g+=u=bmSqrt(u),b.points[l]=new s(u,d),v=d}b.segmentLength=g,a[h]=b}return a[h]});function o(t,e){var i=e.percents,r=e.lengths,s=i.length,a=bmFloor((s-1)*t),n=t*e.addedLength,o=0;if(a===s-1||0===a||n===r[a])return i[a];for(var h=r[a]>n?-1:1,l=!0;l;)if(r[a]<=n&&r[a+1]>n?(o=(n-r[a])/(r[a+1]-r[a]),l=!1):a+=h,a<0||a>=s-1){if(a===s-1)return i[a];l=!1}return i[a]+(i[a+1]-i[a])*o}var h=createTypedArray("float32",8);return{getSegmentsLength:function(t){var e,r=segmentsLengthPool.newElement(),s=t.c,a=t.v,n=t.o,o=t.i,h=t._length,l=r.lengths,p=0;for(e=0;e<h-1;e+=1)l[e]=i(a[e],a[e+1],n[e],o[e+1]),p+=l[e].addedLength;return s&&h&&(l[e]=i(a[e],a[0],n[e],o[0]),p+=l[e].addedLength),r.totalLength=p,r},getNewSegment:function(e,i,r,s,a,n,l){a<0?a=0:a>1&&(a=1);var p,f=o(a,l),m=o(n=n>1?1:n,l),c=e.length,u=1-f,d=1-m,y=u*u*u,g=f*u*u*3,v=f*f*u*3,b=f*f*f,P=u*u*d,E=f*u*d+u*f*d+u*u*m,x=f*f*d+u*f*m+f*u*m,S=f*f*m,_=u*d*d,A=f*d*d+u*m*d+u*d*m,M=f*m*d+u*m*m+f*d*m,T=f*m*m,k=d*d*d,D=m*d*d+d*m*d+d*d*m,F=m*m*d+d*m*m+m*d*m,C=m*m*m;for(p=0;p<c;p+=1)h[4*p]=t.round(1e3*(y*e[p]+g*r[p]+v*s[p]+b*i[p]))/1e3,h[4*p+1]=t.round(1e3*(P*e[p]+E*r[p]+x*s[p]+S*i[p]))/1e3,h[4*p+2]=t.round(1e3*(_*e[p]+A*r[p]+M*s[p]+T*i[p]))/1e3,h[4*p+3]=t.round(1e3*(k*e[p]+D*r[p]+F*s[p]+C*i[p]))/1e3;return h},getPointInSegment:function(e,i,r,s,a,n){var h=o(a,n),l=1-h;return[t.round(1e3*(l*l*l*e[0]+(h*l*l+l*h*l+l*l*h)*r[0]+(h*h*l+l*h*h+h*l*h)*s[0]+h*h*h*i[0]))/1e3,t.round(1e3*(l*l*l*e[1]+(h*l*l+l*h*l+l*l*h)*r[1]+(h*h*l+l*h*h+h*l*h)*s[1]+h*h*h*i[1]))/1e3]},buildBezierData:n,pointOnLine2D:e,pointOnLine3D:function(i,r,s,a,n,o,h,l,p){if(0===s&&0===o&&0===p)return e(i,r,a,n,h,l);var f,m=t.sqrt(t.pow(a-i,2)+t.pow(n-r,2)+t.pow(o-s,2)),c=t.sqrt(t.pow(h-i,2)+t.pow(l-r,2)+t.pow(p-s,2)),u=t.sqrt(t.pow(h-a,2)+t.pow(l-n,2)+t.pow(p-o,2));return(f=m>c?m>u?m-c-u:u-c-m:u>c?u-c-m:c-m-u)>-1e-4&&f<1e-4}}}var bez=bezFunction(),initFrame=initialDefaultFrame,mathAbs=Math.abs;function interpolateValue(t,e){var i,r=this.offsetTime;"multidimensional"===this.propType&&(i=createTypedArray("float32",this.pv.length));for(var s,a,n,o,h,l,p,f,m,c=e.lastIndex,u=c,d=this.keyframes.length-1,y=!0;y;){if(s=this.keyframes[u],a=this.keyframes[u+1],u===d-1&&t>=a.t-r){s.h&&(s=a),c=0;break}if(a.t-r>t){c=u;break}u<d-1?u+=1:(c=0,y=!1)}n=this.keyframesMetadata[u]||{};var g,v=a.t-r,b=s.t-r;if(s.to){n.bezierData||(n.bezierData=bez.buildBezierData(s.s,a.s||s.e,s.to,s.ti));var P=n.bezierData;if(t>=v||t<b){var E=t>=v?P.points.length-1:0;for(h=P.points[E].point.length,o=0;o<h;o+=1)i[o]=P.points[E].point[o]}else{n.__fnct?m=n.__fnct:(m=BezierFactory.getBezierEasing(s.o.x,s.o.y,s.i.x,s.i.y,s.n).get,n.__fnct=m),l=m((t-b)/(v-b));var x,S=P.segmentLength*l,_=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastAddedLength:0;for(f=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastPoint:0,y=!0,p=P.points.length;y;){if(_+=P.points[f].partialLength,0===S||0===l||f===P.points.length-1){for(h=P.points[f].point.length,o=0;o<h;o+=1)i[o]=P.points[f].point[o];break}if(S>=_&&S<_+P.points[f+1].partialLength){for(x=(S-_)/P.points[f+1].partialLength,h=P.points[f].point.length,o=0;o<h;o+=1)i[o]=P.points[f].point[o]+(P.points[f+1].point[o]-P.points[f].point[o])*x;break}f<p-1?f+=1:y=!1}e._lastPoint=f,e._lastAddedLength=_-P.points[f].partialLength,e._lastKeyframeIndex=u}}else{var A,M,T,k,D;if(d=s.s.length,g=a.s||s.e,this.sh&&1!==s.h)if(t>=v)i[0]=g[0],i[1]=g[1],i[2]=g[2];else if(t<=b)i[0]=s.s[0],i[1]=s.s[1],i[2]=s.s[2];else{quaternionToEuler(i,slerp(createQuaternion(s.s),createQuaternion(g),(t-b)/(v-b)))}else for(u=0;u<d;u+=1)1!==s.h&&(t>=v?l=1:t<b?l=0:(s.o.x.constructor===Array?(n.__fnct||(n.__fnct=[]),n.__fnct[u]?m=n.__fnct[u]:(A=void 0===s.o.x[u]?s.o.x[0]:s.o.x[u],M=void 0===s.o.y[u]?s.o.y[0]:s.o.y[u],T=void 0===s.i.x[u]?s.i.x[0]:s.i.x[u],k=void 0===s.i.y[u]?s.i.y[0]:s.i.y[u],m=BezierFactory.getBezierEasing(A,M,T,k).get,n.__fnct[u]=m)):n.__fnct?m=n.__fnct:(A=s.o.x,M=s.o.y,T=s.i.x,k=s.i.y,m=BezierFactory.getBezierEasing(A,M,T,k).get,s.keyframeMetadata=m),l=m((t-b)/(v-b)))),g=a.s||s.e,D=1===s.h?s.s[u]:s.s[u]+(g[u]-s.s[u])*l,"multidimensional"===this.propType?i[u]=D:i=D}return e.lastIndex=c,i}function slerp(t,e,i){var r,s,a,n,o,h=[],l=t[0],p=t[1],f=t[2],m=t[3],c=e[0],u=e[1],d=e[2],y=e[3];return(s=l*c+p*u+f*d+m*y)<0&&(s=-s,c=-c,u=-u,d=-d,y=-y),1-s>1e-6?(r=Math.acos(s),a=Math.sin(r),n=Math.sin((1-i)*r)/a,o=Math.sin(i*r)/a):(n=1-i,o=i),h[0]=n*l+o*c,h[1]=n*p+o*u,h[2]=n*f+o*d,h[3]=n*m+o*y,h}function quaternionToEuler(t,e){var i=e[0],r=e[1],s=e[2],a=e[3],n=Math.atan2(2*r*a-2*i*s,1-2*r*r-2*s*s),o=Math.asin(2*i*r+2*s*a),h=Math.atan2(2*i*a-2*r*s,1-2*i*i-2*s*s);t[0]=n/degToRads,t[1]=o/degToRads,t[2]=h/degToRads}function createQuaternion(t){var e=t[0]*degToRads,i=t[1]*degToRads,r=t[2]*degToRads,s=Math.cos(e/2),a=Math.cos(i/2),n=Math.cos(r/2),o=Math.sin(e/2),h=Math.sin(i/2),l=Math.sin(r/2);return[o*h*n+s*a*l,o*a*n+s*h*l,s*h*n-o*a*l,s*a*n-o*h*l]}function getValueAtCurrentTime(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==initFrame&&(this._caching.lastFrame>=i&&t>=i||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var r=this.interpolateValue(t,this._caching);this.pv=r}return this._caching.lastFrame=t,this.pv}function setVValue(t){var e;if("unidimensional"===this.propType)e=t*this.mult,mathAbs(this.v-e)>1e-5&&(this.v=e,this._mdf=!0);else for(var i=0,r=this.v.length;i<r;)e=t[i]*this.mult,mathAbs(this.v[i]-e)>1e-5&&(this.v[i]=e,this._mdf=!0),i+=1}function processEffectsSequence(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t;this.lock=!0,this._mdf=this._isFirstFrame;var e=this.effectsSequence.length,i=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)i=this.effectsSequence[t](i);this.setVValue(i),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function addEffect(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function ValueProperty(t,e,i,r){this.propType="unidimensional",this.mult=i||1,this.data=e,this.v=i?e.k*i:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function MultiDimensionalProperty(t,e,i,r){var s;this.propType="multidimensional",this.mult=i||1,this.data=e,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var a=e.k.length;for(this.v=createTypedArray("float32",a),this.pv=createTypedArray("float32",a),this.vel=createTypedArray("float32",a),s=0;s<a;s+=1)this.v[s]=e.k[s]*this.mult,this.pv[s]=e.k[s];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function KeyframedValueProperty(t,e,i,r){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:initFrame,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.v=initFrame,this.pv=initFrame,this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.addEffect=addEffect}function KeyframedMultidimensionalProperty(t,e,i,r){var s;this.propType="multidimensional";var a,n,o,h,l=e.k.length;for(s=0;s<l-1;s+=1)e.k[s].to&&e.k[s].s&&e.k[s+1]&&e.k[s+1].s&&(a=e.k[s].s,n=e.k[s+1].s,o=e.k[s].to,h=e.k[s].ti,(2===a.length&&(a[0]!==n[0]||a[1]!==n[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],a[0]+o[0],a[1]+o[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],n[0]+h[0],n[1]+h[1])||3===a.length&&(a[0]!==n[0]||a[1]!==n[1]||a[2]!==n[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],a[0]+o[0],a[1]+o[1],a[2]+o[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],n[0]+h[0],n[1]+h[1],n[2]+h[2]))&&(e.k[s].to=null,e.k[s].ti=null),a[0]===n[0]&&a[1]===n[1]&&0===o[0]&&0===o[1]&&0===h[0]&&0===h[1]&&(2===a.length||a[2]===n[2]&&0===o[2]&&0===h[2])&&(e.k[s].to=null,e.k[s].ti=null));this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.frameId=-1;var p=e.k[0].s.length;for(this.v=createTypedArray("float32",p),this.pv=createTypedArray("float32",p),s=0;s<p;s+=1)this.v[s]=initFrame,this.pv[s]=initFrame;this._caching={lastFrame:initFrame,lastIndex:0,value:createTypedArray("float32",p)},this.addEffect=addEffect}var PropertyFactory={getProp:function(t,e,i,r,s){var a;if(e.sid&&(e=t.globalData.slotManager.getProp(e)),e.k.length)if("number"==typeof e.k[0])a=new MultiDimensionalProperty(t,e,r,s);else switch(i){case 0:a=new KeyframedValueProperty(t,e,r,s);break;case 1:a=new KeyframedMultidimensionalProperty(t,e,r,s)}else a=new ValueProperty(t,e,r,s);return a.effectsSequence.length&&s.addDynamicProperty(a),a}};function DynamicPropertyContainer(){}DynamicPropertyContainer.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){var t;this._mdf=!1;var e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var pointPool=poolFactory(8,(function(){return createTypedArray("float32",2)}));function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var i=0;i<e;)this.v[i]=pointPool.newElement(),this.o[i]=pointPool.newElement(),this.i[i]=pointPool.newElement(),i+=1},ShapePath.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},ShapePath.prototype.doubleArrayLength=function(){this.v=this.v.concat(createSizedArray(this._maxLength)),this.i=this.i.concat(createSizedArray(this._maxLength)),this.o=this.o.concat(createSizedArray(this._maxLength)),this._maxLength*=2},ShapePath.prototype.setXYAt=function(t,e,i,r,s){var a;switch(this._length=Math.max(this._length,r+1),this._length>=this._maxLength&&this.doubleArrayLength(),i){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o;break;default:a=[]}(!a[r]||a[r]&&!s)&&(a[r]=pointPool.newElement()),a[r][0]=t,a[r][1]=e},ShapePath.prototype.setTripleAt=function(t,e,i,r,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(i,r,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t=new ShapePath;t.setPathData(this.c,this._length);var e=this.v,i=this.o,r=this.i,s=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],r[0][0],r[0][1],i[0][0],i[0][1],0,!1),s=1);var a,n=this._length-1,o=this._length;for(a=s;a<o;a+=1)t.setTripleAt(e[n][0],e[n][1],r[n][0],r[n][1],i[n][0],i[n][1],a,!1),n-=1;return t},ShapePath.prototype.length=function(){return this._length};var shapePool=(factory=poolFactory(4,(function(){return new ShapePath}),(function(t){var e,i=t._length;for(e=0;e<i;e+=1)pointPool.release(t.v[e]),pointPool.release(t.i[e]),pointPool.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1})),factory.clone=function(t){var e,i=factory.newElement(),r=void 0===t._length?t.v.length:t._length;for(i.setLength(r),i.c=t.c,e=0;e<r;e+=1)i.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return i},factory),factory;function ShapeCollection(){this._length=0,this._maxLength=4,this.shapes=createSizedArray(this._maxLength)}ShapeCollection.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(createSizedArray(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},ShapeCollection.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)shapePool.release(this.shapes[t]);this._length=0};var shapeCollectionPool=(ob={newShapeCollection:function(){return _length?pool[_length-=1]:new ShapeCollection},release:function(t){var e,i=t._length;for(e=0;e<i;e+=1)shapePool.release(t.shapes[e]);t._length=0,_length===_maxLength&&(pool=pooling.double(pool),_maxLength*=2),pool[_length]=t,_length+=1}},_length=0,_maxLength=4,pool=createSizedArray(_maxLength),ob),ob,_length,_maxLength,pool,ShapePropertyFactory=function(){var t=-999999;function e(t,e,i){var r,s,a,n,o,h,l,p,f,m=i.lastIndex,c=this.keyframes;if(t<c[0].t-this.offsetTime)r=c[0].s[0],a=!0,m=0;else if(t>=c[c.length-1].t-this.offsetTime)r=c[c.length-1].s?c[c.length-1].s[0]:c[c.length-2].e[0],a=!0;else{for(var u,d,y,g=m,v=c.length-1,b=!0;b&&(u=c[g],!((d=c[g+1]).t-this.offsetTime>t));)g<v-1?g+=1:b=!1;if(y=this.keyframesMetadata[g]||{},m=g,!(a=1===u.h)){if(t>=d.t-this.offsetTime)p=1;else if(t<u.t-this.offsetTime)p=0;else{var P;y.__fnct?P=y.__fnct:(P=BezierFactory.getBezierEasing(u.o.x,u.o.y,u.i.x,u.i.y).get,y.__fnct=P),p=P((t-(u.t-this.offsetTime))/(d.t-this.offsetTime-(u.t-this.offsetTime)))}s=d.s?d.s[0]:u.e[0]}r=u.s[0]}for(h=e._length,l=r.i[0].length,i.lastIndex=m,n=0;n<h;n+=1)for(o=0;o<l;o+=1)f=a?r.i[n][o]:r.i[n][o]+(s.i[n][o]-r.i[n][o])*p,e.i[n][o]=f,f=a?r.o[n][o]:r.o[n][o]+(s.o[n][o]-r.o[n][o])*p,e.o[n][o]=f,f=a?r.v[n][o]:r.v[n][o]+(s.v[n][o]-r.v[n][o])*p,e.v[n][o]=f}function i(){var e=this.comp.renderedFrame-this.offsetTime,i=this.keyframes[0].t-this.offsetTime,r=this.keyframes[this.keyframes.length-1].t-this.offsetTime,s=this._caching.lastFrame;return s!==t&&(s<i&&e<i||s>r&&e>r)||(this._caching.lastIndex=s<e?this._caching.lastIndex:0,this.interpolateShape(e,this.pv,this._caching)),this._caching.lastFrame=e,this.pv}function r(){this.paths=this.localShapeCollection}function s(t){(function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var i,r=t._length;for(i=0;i<r;i+=1)if(t.v[i][0]!==e.v[i][0]||t.v[i][1]!==e.v[i][1]||t.o[i][0]!==e.o[i][0]||t.o[i][1]!==e.o[i][1]||t.i[i][0]!==e.i[i][0]||t.i[i][1]!==e.i[i][1])return!1;return!0})(this.v,t)||(this.v=shapePool.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function a(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t,e;this.lock=!0,this._mdf=!1,t=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k;var i=this.effectsSequence.length;for(e=0;e<i;e+=1)t=this.effectsSequence[e](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function n(t,e,i){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var s=3===i?e.pt.k:e.ks.k;this.v=shapePool.clone(s),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=r,this.effectsSequence=[]}function o(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function h(e,s,a){this.propType="shape",this.comp=e.comp,this.elem=e,this.container=e,this.offsetTime=e.data.st,this.keyframes=3===a?s.pt.k:s.ks.k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;var n=this.keyframes[0].s[0].i.length;this.v=shapePool.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,n),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=t,this.reset=r,this._caching={lastFrame:t,lastIndex:0},this.effectsSequence=[i.bind(this)]}n.prototype.interpolateShape=e,n.prototype.getValue=a,n.prototype.setVValue=s,n.prototype.addEffect=o,h.prototype.getValue=a,h.prototype.interpolateShape=e,h.prototype.setVValue=s,h.prototype.addEffect=o;var l=function(){var t=roundCorner;function e(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}return e.prototype={reset:r,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var e=this.p.v[0],i=this.p.v[1],r=this.s.v[0]/2,s=this.s.v[1]/2,a=3!==this.d,n=this.v;n.v[0][0]=e,n.v[0][1]=i-s,n.v[1][0]=a?e+r:e-r,n.v[1][1]=i,n.v[2][0]=e,n.v[2][1]=i+s,n.v[3][0]=a?e-r:e+r,n.v[3][1]=i,n.i[0][0]=a?e-r*t:e+r*t,n.i[0][1]=i-s,n.i[1][0]=a?e+r:e-r,n.i[1][1]=i-s*t,n.i[2][0]=a?e+r*t:e-r*t,n.i[2][1]=i+s,n.i[3][0]=a?e-r:e+r,n.i[3][1]=i+s*t,n.o[0][0]=a?e+r*t:e-r*t,n.o[0][1]=i-s,n.o[1][0]=a?e+r:e-r,n.o[1][1]=i+s*t,n.o[2][0]=a?e-r*t:e+r*t,n.o[2][1]=i+s,n.o[3][0]=a?e-r:e+r,n.o[3][1]=i-s*t}},extendPrototype([DynamicPropertyContainer],e),e}(),p=function(){function t(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=PropertyFactory.getProp(t,e.ir,0,0,this),this.is=PropertyFactory.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=PropertyFactory.getProp(t,e.pt,0,0,this),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,degToRads,this),this.or=PropertyFactory.getProp(t,e.or,0,0,this),this.os=PropertyFactory.getProp(t,e.os,0,.01,this),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}return t.prototype={reset:r,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,i,r,s=2*Math.floor(this.pt.v),a=2*Math.PI/s,n=!0,o=this.or.v,h=this.ir.v,l=this.os.v,p=this.is.v,f=2*Math.PI*o/(2*s),m=2*Math.PI*h/(2*s),c=-Math.PI/2;c+=this.r.v;var u=3===this.data.d?-1:1;for(this.v._length=0,t=0;t<s;t+=1){i=n?l:p,r=n?f:m;var d=(e=n?o:h)*Math.cos(c),y=e*Math.sin(c),g=0===d&&0===y?0:y/Math.sqrt(d*d+y*y),v=0===d&&0===y?0:-d/Math.sqrt(d*d+y*y);d+=+this.p.v[0],y+=+this.p.v[1],this.v.setTripleAt(d,y,d-g*r*i*u,y-v*r*i*u,d+g*r*i*u,y+v*r*i*u,t,!0),n=!n,c+=a*u}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),i=2*Math.PI/e,r=this.or.v,s=this.os.v,a=2*Math.PI*r/(4*e),n=.5*-Math.PI,o=3===this.data.d?-1:1;for(n+=this.r.v,this.v._length=0,t=0;t<e;t+=1){var h=r*Math.cos(n),l=r*Math.sin(n),p=0===h&&0===l?0:l/Math.sqrt(h*h+l*l),f=0===h&&0===l?0:-h/Math.sqrt(h*h+l*l);h+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(h,l,h-p*a*s*o,l-f*a*s*o,h+p*a*s*o,l+f*a*s*o,t,!0),n+=i*o}this.paths.length=0,this.paths[0]=this.v}},extendPrototype([DynamicPropertyContainer],t),t}(),f=function(){function t(t,e){this.v=shapePool.newElement(),this.v.c=!0,this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}return t.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,r=this.s.v[1]/2,s=bmMin(i,r,this.r.v),a=s*(1-roundCorner);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+s,t+i,e-r+a,0,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-a,t+i,e+r-s,1,!0),0!==s?(this.v.setTripleAt(t+i-s,e+r,t+i-s,e+r,t+i-a,e+r,2,!0),this.v.setTripleAt(t-i+s,e+r,t-i+a,e+r,t-i+s,e+r,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-s,t-i,e+r-a,4,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+a,t-i,e-r+s,5,!0),this.v.setTripleAt(t-i+s,e-r,t-i+s,e-r,t-i+a,e-r,6,!0),this.v.setTripleAt(t+i-s,e-r,t+i-a,e-r,t+i-s,e-r,7,!0)):(this.v.setTripleAt(t-i,e+r,t-i+a,e+r,t-i,e+r,2),this.v.setTripleAt(t-i,e-r,t-i,e-r+a,t-i,e-r,3))):(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+a,t+i,e-r+s,0,!0),0!==s?(this.v.setTripleAt(t+i-s,e-r,t+i-s,e-r,t+i-a,e-r,1,!0),this.v.setTripleAt(t-i+s,e-r,t-i+a,e-r,t-i+s,e-r,2,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+s,t-i,e-r+a,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-a,t-i,e+r-s,4,!0),this.v.setTripleAt(t-i+s,e+r,t-i+s,e+r,t-i+a,e+r,5,!0),this.v.setTripleAt(t+i-s,e+r,t+i-a,e+r,t+i-s,e+r,6,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-s,t+i,e+r-a,7,!0)):(this.v.setTripleAt(t-i,e-r,t-i+a,e-r,t-i,e-r,1,!0),this.v.setTripleAt(t-i,e+r,t-i,e+r-a,t-i,e+r,2,!0),this.v.setTripleAt(t+i,e+r,t+i-a,e+r,t+i,e+r,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:r},extendPrototype([DynamicPropertyContainer],t),t}();var m={getShapeProp:function(t,e,i){var r;return 3===i||4===i?r=(3===i?e.pt:e.ks).k.length?new h(t,e,i):new n(t,e,i):5===i?r=new f(t,e):6===i?r=new l(t,e):7===i&&(r=new p(t,e)),r.k&&t.addDynamicProperty(r),r},getConstructorFunction:function(){return n},getKeyframedConstructorFunction:function(){return h}};return m}(),Matrix=function(){var t=Math.cos,e=Math.sin,i=Math.tan,r=Math.round;function s(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function a(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,-s,0,0,s,r,0,0,0,0,1,0,0,0,0,1)}function n(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(1,0,0,0,0,r,-s,0,0,s,r,0,0,0,0,1)}function o(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,0,s,0,0,1,0,0,-s,0,r,0,0,0,0,1)}function h(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,-s,0,0,s,r,0,0,0,0,1,0,0,0,0,1)}function l(t,e){return this._t(1,e,t,1,0,0)}function p(t,e){return this.shear(i(t),i(e))}function f(r,s){var a=t(s),n=e(s);return this._t(a,n,0,0,-n,a,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,i(r),1,0,0,0,0,1,0,0,0,0,1)._t(a,-n,0,0,n,a,0,0,0,0,1,0,0,0,0,1)}function m(t,e,i){return i||0===i||(i=1),1===t&&1===e&&1===i?this:this._t(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1)}function c(t,e,i,r,s,a,n,o,h,l,p,f,m,c,u,d){return this.props[0]=t,this.props[1]=e,this.props[2]=i,this.props[3]=r,this.props[4]=s,this.props[5]=a,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=l,this.props[10]=p,this.props[11]=f,this.props[12]=m,this.props[13]=c,this.props[14]=u,this.props[15]=d,this}function u(t,e,i){return i=i||0,0!==t||0!==e||0!==i?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,i,1):this}function d(t,e,i,r,s,a,n,o,h,l,p,f,m,c,u,d){var y=this.props;if(1===t&&0===e&&0===i&&0===r&&0===s&&1===a&&0===n&&0===o&&0===h&&0===l&&1===p&&0===f)return y[12]=y[12]*t+y[15]*m,y[13]=y[13]*a+y[15]*c,y[14]=y[14]*p+y[15]*u,y[15]*=d,this._identityCalculated=!1,this;var g=y[0],v=y[1],b=y[2],P=y[3],E=y[4],x=y[5],S=y[6],_=y[7],A=y[8],M=y[9],T=y[10],k=y[11],D=y[12],F=y[13],C=y[14],I=y[15];return y[0]=g*t+v*s+b*h+P*m,y[1]=g*e+v*a+b*l+P*c,y[2]=g*i+v*n+b*p+P*u,y[3]=g*r+v*o+b*f+P*d,y[4]=E*t+x*s+S*h+_*m,y[5]=E*e+x*a+S*l+_*c,y[6]=E*i+x*n+S*p+_*u,y[7]=E*r+x*o+S*f+_*d,y[8]=A*t+M*s+T*h+k*m,y[9]=A*e+M*a+T*l+k*c,y[10]=A*i+M*n+T*p+k*u,y[11]=A*r+M*o+T*f+k*d,y[12]=D*t+F*s+C*h+I*m,y[13]=D*e+F*a+C*l+I*c,y[14]=D*i+F*n+C*p+I*u,y[15]=D*r+F*o+C*f+I*d,this._identityCalculated=!1,this}function y(t){var e=t.props;return this.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}function g(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function v(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function b(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function P(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function E(t,e,i){return{x:t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}}function x(t,e,i){return t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12]}function S(t,e,i){return t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13]}function _(t,e,i){return t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}function A(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,i=-this.props[1]/t,r=-this.props[4]/t,s=this.props[0]/t,a=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,n=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,o=new Matrix;return o.props[0]=e,o.props[1]=i,o.props[4]=r,o.props[5]=s,o.props[12]=a,o.props[13]=n,o}function M(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function T(t){var e,i=t.length,r=[];for(e=0;e<i;e+=1)r[e]=M(t[e]);return r}function k(t,e,i){var r=createTypedArray("float32",6);if(this.isIdentity())r[0]=t[0],r[1]=t[1],r[2]=e[0],r[3]=e[1],r[4]=i[0],r[5]=i[1];else{var s=this.props[0],a=this.props[1],n=this.props[4],o=this.props[5],h=this.props[12],l=this.props[13];r[0]=t[0]*s+t[1]*n+h,r[1]=t[0]*a+t[1]*o+l,r[2]=e[0]*s+e[1]*n+h,r[3]=e[0]*a+e[1]*o+l,r[4]=i[0]*s+i[1]*n+h,r[5]=i[0]*a+i[1]*o+l}return r}function D(t,e,i){return this.isIdentity()?[t,e,i]:[t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]]}function F(t,e){if(this.isIdentity())return t+","+e;var i=this.props;return Math.round(100*(t*i[0]+e*i[4]+i[12]))/100+","+Math.round(100*(t*i[1]+e*i[5]+i[13]))/100}function C(){for(var t=0,e=this.props,i="matrix3d(";t<16;)i+=r(1e4*e[t])/1e4,i+=15===t?")":",",t+=1;return i}function I(t){return t<1e-6&&t>0||t>-1e-6&&t<0?r(1e4*t)/1e4:t}function w(){var t=this.props;return"matrix("+I(t[0])+","+I(t[1])+","+I(t[4])+","+I(t[5])+","+I(t[12])+","+I(t[13])+")"}return function(){this.reset=s,this.rotate=a,this.rotateX=n,this.rotateY=o,this.rotateZ=h,this.skew=p,this.skewFromAxis=f,this.shear=l,this.scale=m,this.setTransform=c,this.translate=u,this.transform=d,this.multiply=y,this.applyToPoint=E,this.applyToX=x,this.applyToY=S,this.applyToZ=_,this.applyToPointArray=D,this.applyToTriplePoints=k,this.applyToPointStringified=F,this.toCSS=C,this.to2dCSS=w,this.clone=b,this.cloneFromProps=P,this.equals=v,this.inversePoints=T,this.inversePoint=M,this.getInverseMatrix=A,this._t=this.transform,this.isIdentity=g,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}}();function _typeof$3(t){return _typeof$3="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$3(t)}var lottie={},standalone="__[STANDALONE]__",animationData="__[ANIMATIONDATA]__",renderer="";function setLocation(t){setLocationHref(t)}function searchAnimations(){!0===standalone?animationManager.searchAnimations(animationData,standalone,renderer):animationManager.searchAnimations()}function setSubframeRendering(t){setSubframeEnabled(t)}function setPrefix(t){setIdPrefix(t)}function loadAnimation(t){return!0===standalone&&(t.animationData=JSON.parse(animationData)),animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":setDefaultCurveSegments(200);break;default:case"medium":setDefaultCurveSegments(50);break;case"low":setDefaultCurveSegments(10)}else!isNaN(t)&&t>1&&setDefaultCurveSegments(t);getDefaultCurveSegments()>=50?roundValues(!1):roundValues(!0)}function inBrowser(){return"undefined"!=typeof navigator}function installPlugin(t,e){"expressions"===t&&setExpressionsPlugin(e)}function getFactory(t){switch(t){case"propertyFactory":return PropertyFactory;case"shapePropertyFactory":return ShapePropertyFactory;case"matrix":return Matrix;default:return null}}function checkReady(){"complete"===document.readyState&&(clearInterval(readyStateCheckInterval),searchAnimations())}function getQueryVariable(t){for(var e=queryString.split("&"),i=0;i<e.length;i+=1){var r=e[i].split("=");if(decodeURIComponent(r[0])==t)return decodeURIComponent(r[1])}return null}lottie.play=animationManager.play,lottie.pause=animationManager.pause,lottie.setLocationHref=setLocation,lottie.togglePause=animationManager.togglePause,lottie.setSpeed=animationManager.setSpeed,lottie.setDirection=animationManager.setDirection,lottie.stop=animationManager.stop,lottie.searchAnimations=searchAnimations,lottie.registerAnimation=animationManager.registerAnimation,lottie.loadAnimation=loadAnimation,lottie.setSubframeRendering=setSubframeRendering,lottie.resize=animationManager.resize,lottie.goToAndStop=animationManager.goToAndStop,lottie.destroy=animationManager.destroy,lottie.setQuality=setQuality,lottie.inBrowser=inBrowser,lottie.installPlugin=installPlugin,lottie.freeze=animationManager.freeze,lottie.unfreeze=animationManager.unfreeze,lottie.setVolume=animationManager.setVolume,lottie.mute=animationManager.mute,lottie.unmute=animationManager.unmute,lottie.getRegisteredAnimations=animationManager.getRegisteredAnimations,lottie.useWebWorker=setWebWorker,lottie.setIDPrefix=setPrefix,lottie.__getFactory=getFactory,lottie.version="5.12.2";var queryString="";if(standalone){var scripts=document.getElementsByTagName("script"),index=scripts.length-1,myScript=scripts[index]||{src:""};queryString=myScript.src?myScript.src.replace(/^[^\?]+\??/,""):"",renderer=getQueryVariable("renderer")}var readyStateCheckInterval=setInterval(checkReady,100);try{"object"===("undefined"==typeof exports?"undefined":_typeof$3(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=lottie)}catch(t){}var ShapeModifiers=function(){var t={},e={};return t.registerModifier=function(t,i){e[t]||(e[t]=i)},t.getModifier=function(t,i,r){return new e[t](i,r)},t}();function ShapeModifier(){}function TrimModifier(){}function PuckerAndBloatModifier(){}ShapeModifier.prototype.initModifierProperties=function(){},ShapeModifier.prototype.addShapeToModifier=function(){},ShapeModifier.prototype.addShape=function(t){if(!this.closed){t.sh.container.addDynamicProperty(t.sh);var e={shape:t.sh,data:t,localShapeCollection:shapeCollectionPool.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},ShapeModifier.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=initialDefaultFrame,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},ShapeModifier.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},extendPrototype([DynamicPropertyContainer],ShapeModifier),extendPrototype([ShapeModifier],TrimModifier),TrimModifier.prototype.initModifierProperties=function(t,e){this.s=PropertyFactory.getProp(t,e.s,0,.01,this),this.e=PropertyFactory.getProp(t,e.e,0,.01,this),this.o=PropertyFactory.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},TrimModifier.prototype.addShapeToModifier=function(t){t.pathsData=[]},TrimModifier.prototype.calculateShapeEdges=function(t,e,i,r,s){var a=[];e<=1?a.push({s:t,e:e}):t>=1?a.push({s:t-1,e:e-1}):(a.push({s:t,e:1}),a.push({s:0,e:e-1}));var n,o,h=[],l=a.length;for(n=0;n<l;n+=1){var p,f;if(!((o=a[n]).e*s<r||o.s*s>r+i))p=o.s*s<=r?0:(o.s*s-r)/i,f=o.e*s>=r+i?1:(o.e*s-r)/i,h.push([p,f])}return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){var e,i=t.length;for(e=0;e<i;e+=1)segmentsLengthPool.release(t[e]);return t.length=0,t},TrimModifier.prototype.processShapes=function(t){var e,i,r,s;if(this._mdf||t){var a=this.o.v%360/360;if(a<0&&(a+=1),(e=this.s.v>1?1+a:this.s.v<0?0+a:this.s.v+a)>(i=this.e.v>1?1+a:this.e.v<0?0+a:this.e.v+a)){var n=e;e=i,i=n}e=1e-4*Math.round(1e4*e),i=1e-4*Math.round(1e4*i),this.sValue=e,this.eValue=i}else e=this.sValue,i=this.eValue;var o,h,l,p,f,m=this.shapes.length,c=0;if(i===e)for(s=0;s<m;s+=1)this.shapes[s].localShapeCollection.releaseShapes(),this.shapes[s].shape._mdf=!0,this.shapes[s].shape.paths=this.shapes[s].localShapeCollection,this._mdf&&(this.shapes[s].pathsData.length=0);else if(1===i&&0===e||0===i&&1===e){if(this._mdf)for(s=0;s<m;s+=1)this.shapes[s].pathsData.length=0,this.shapes[s].shape._mdf=!0}else{var u,d,y=[];for(s=0;s<m;s+=1)if((u=this.shapes[s]).shape._mdf||this._mdf||t||2===this.m){if(h=(r=u.shape.paths)._length,f=0,!u.shape._mdf&&u.pathsData.length)f=u.totalShapeLength;else{for(l=this.releasePathsData(u.pathsData),o=0;o<h;o+=1)p=bez.getSegmentsLength(r.shapes[o]),l.push(p),f+=p.totalLength;u.totalShapeLength=f,u.pathsData=l}c+=f,u.shape._mdf=!0}else u.shape.paths=u.localShapeCollection;var g,v=e,b=i,P=0;for(s=m-1;s>=0;s-=1)if((u=this.shapes[s]).shape._mdf){for((d=u.localShapeCollection).releaseShapes(),2===this.m&&m>1?(g=this.calculateShapeEdges(e,i,u.totalShapeLength,P,c),P+=u.totalShapeLength):g=[[v,b]],h=g.length,o=0;o<h;o+=1){v=g[o][0],b=g[o][1],y.length=0,b<=1?y.push({s:u.totalShapeLength*v,e:u.totalShapeLength*b}):v>=1?y.push({s:u.totalShapeLength*(v-1),e:u.totalShapeLength*(b-1)}):(y.push({s:u.totalShapeLength*v,e:u.totalShapeLength}),y.push({s:0,e:u.totalShapeLength*(b-1)}));var E=this.addShapes(u,y[0]);if(y[0].s!==y[0].e){if(y.length>1)if(u.shape.paths.shapes[u.shape.paths._length-1].c){var x=E.pop();this.addPaths(E,d),E=this.addShapes(u,y[1],x)}else this.addPaths(E,d),E=this.addShapes(u,y[1]);this.addPaths(E,d)}}u.shape.paths=d}}},TrimModifier.prototype.addPaths=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)e.addShape(t[i])},TrimModifier.prototype.addSegment=function(t,e,i,r,s,a,n){s.setXYAt(e[0],e[1],"o",a),s.setXYAt(i[0],i[1],"i",a+1),n&&s.setXYAt(t[0],t[1],"v",a),s.setXYAt(r[0],r[1],"v",a+1)},TrimModifier.prototype.addSegmentFromArray=function(t,e,i,r){e.setXYAt(t[1],t[5],"o",i),e.setXYAt(t[2],t[6],"i",i+1),r&&e.setXYAt(t[0],t[4],"v",i),e.setXYAt(t[3],t[7],"v",i+1)},TrimModifier.prototype.addShapes=function(t,e,i){var r,s,a,n,o,h,l,p,f=t.pathsData,m=t.shape.paths.shapes,c=t.shape.paths._length,u=0,d=[],y=!0;for(i?(o=i._length,p=i._length):(i=shapePool.newElement(),o=0,p=0),d.push(i),r=0;r<c;r+=1){for(h=f[r].lengths,i.c=m[r].c,a=m[r].c?h.length:h.length+1,s=1;s<a;s+=1)if(u+(n=h[s-1]).addedLength<e.s)u+=n.addedLength,i.c=!1;else{if(u>e.e){i.c=!1;break}e.s<=u&&e.e>=u+n.addedLength?(this.addSegment(m[r].v[s-1],m[r].o[s-1],m[r].i[s],m[r].v[s],i,o,y),y=!1):(l=bez.getNewSegment(m[r].v[s-1],m[r].v[s],m[r].o[s-1],m[r].i[s],(e.s-u)/n.addedLength,(e.e-u)/n.addedLength,h[s-1]),this.addSegmentFromArray(l,i,o,y),y=!1,i.c=!1),u+=n.addedLength,o+=1}if(m[r].c&&h.length){if(n=h[s-1],u<=e.e){var g=h[s-1].addedLength;e.s<=u&&e.e>=u+g?(this.addSegment(m[r].v[s-1],m[r].o[s-1],m[r].i[0],m[r].v[0],i,o,y),y=!1):(l=bez.getNewSegment(m[r].v[s-1],m[r].v[0],m[r].o[s-1],m[r].i[0],(e.s-u)/g,(e.e-u)/g,h[s-1]),this.addSegmentFromArray(l,i,o,y),y=!1,i.c=!1)}else i.c=!1;u+=n.addedLength,o+=1}if(i._length&&(i.setXYAt(i.v[p][0],i.v[p][1],"i",p),i.setXYAt(i.v[i._length-1][0],i.v[i._length-1][1],"o",i._length-1)),u>e.e)break;r<c-1&&(i=shapePool.newElement(),y=!0,d.push(i),o=0)}return d},extendPrototype([ShapeModifier],PuckerAndBloatModifier),PuckerAndBloatModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},PuckerAndBloatModifier.prototype.processPath=function(t,e){var i=e/100,r=[0,0],s=t._length,a=0;for(a=0;a<s;a+=1)r[0]+=t.v[a][0],r[1]+=t.v[a][1];r[0]/=s,r[1]/=s;var n,o,h,l,p,f,m=shapePool.newElement();for(m.c=t.c,a=0;a<s;a+=1)n=t.v[a][0]+(r[0]-t.v[a][0])*i,o=t.v[a][1]+(r[1]-t.v[a][1])*i,h=t.o[a][0]+(r[0]-t.o[a][0])*-i,l=t.o[a][1]+(r[1]-t.o[a][1])*-i,p=t.i[a][0]+(r[0]-t.i[a][0])*-i,f=t.i[a][1]+(r[1]-t.i[a][1])*-i,m.setTripleAt(n,o,h,l,p,f,a);return m},PuckerAndBloatModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amount.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var TransformPropertyFactory=function(){var t=[0,0];function e(t,e,i){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Matrix,this.pre=new Matrix,this.appliedTransformations=0,this.initDynamicPropertyContainer(i||t),e.p&&e.p.s?(this.px=PropertyFactory.getProp(t,e.p.x,0,0,this),this.py=PropertyFactory.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=PropertyFactory.getProp(t,e.p.z,0,0,this))):this.p=PropertyFactory.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=PropertyFactory.getProp(t,e.rx,0,degToRads,this),this.ry=PropertyFactory.getProp(t,e.ry,0,degToRads,this),this.rz=PropertyFactory.getProp(t,e.rz,0,degToRads,this),e.or.k[0].ti){var r,s=e.or.k.length;for(r=0;r<s;r+=1)e.or.k[r].to=null,e.or.k[r].ti=null}this.or=PropertyFactory.getProp(t,e.or,1,degToRads,this),this.or.sh=!0}else this.r=PropertyFactory.getProp(t,e.r||{k:0},0,degToRads,this);e.sk&&(this.sk=PropertyFactory.getProp(t,e.sk,0,degToRads,this),this.sa=PropertyFactory.getProp(t,e.sa,0,degToRads,this)),this.a=PropertyFactory.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=PropertyFactory.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=PropertyFactory.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return e.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(e){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||e){var i;if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var r,s;if(i=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime)this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(r=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/i,0),s=this.p.getValueAtTime(this.p.keyframes[0].t/i,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(r=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/i,0),s=this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/i,0)):(r=this.p.pv,s=this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/i,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){r=[],s=[];var a=this.px,n=this.py;a._caching.lastFrame+a.offsetTime<=a.keyframes[0].t?(r[0]=a.getValueAtTime((a.keyframes[0].t+.01)/i,0),r[1]=n.getValueAtTime((n.keyframes[0].t+.01)/i,0),s[0]=a.getValueAtTime(a.keyframes[0].t/i,0),s[1]=n.getValueAtTime(n.keyframes[0].t/i,0)):a._caching.lastFrame+a.offsetTime>=a.keyframes[a.keyframes.length-1].t?(r[0]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/i,0),r[1]=n.getValueAtTime(n.keyframes[n.keyframes.length-1].t/i,0),s[0]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/i,0),s[1]=n.getValueAtTime((n.keyframes[n.keyframes.length-1].t-.01)/i,0)):(r=[a.pv,n.pv],s[0]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/i,a.offsetTime),s[1]=n.getValueAtTime((n._caching.lastFrame+n.offsetTime-.01)/i,n.offsetTime))}else r=s=t;this.v.rotate(-Math.atan2(r[1]-s[1],r[0]-s[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],e),e.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},e.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,i,r){return new e(t,i,r)}}}();function RepeaterModifier(){}function RoundCornersModifier(){}function floatEqual(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function floatZero(t){return Math.abs(t)<=1e-5}function lerp(t,e,i){return t*(1-i)+e*i}function lerpPoint(t,e,i){return[lerp(t[0],e[0],i),lerp(t[1],e[1],i)]}function quadRoots(t,e,i){if(0===t)return[];var r=e*e-4*t*i;if(r<0)return[];var s=-e/(2*t);if(0===r)return[s];var a=Math.sqrt(r)/(2*t);return[s-a,s+a]}function polynomialCoefficients(t,e,i,r){return[3*e-t-3*i+r,3*t-6*e+3*i,-3*t+3*e,t]}function singlePoint(t){return new PolynomialBezier(t,t,t,t,!1)}function PolynomialBezier(t,e,i,r,s){s&&pointEqual(t,e)&&(e=lerpPoint(t,r,1/3)),s&&pointEqual(i,r)&&(i=lerpPoint(t,r,2/3));var a=polynomialCoefficients(t[0],e[0],i[0],r[0]),n=polynomialCoefficients(t[1],e[1],i[1],r[1]);this.a=[a[0],n[0]],this.b=[a[1],n[1]],this.c=[a[2],n[2]],this.d=[a[3],n[3]],this.points=[t,e,i,r]}function extrema(t,e){var i=t.points[0][e],r=t.points[t.points.length-1][e];if(i>r){var s=r;r=i,i=s}for(var a=quadRoots(3*t.a[e],2*t.b[e],t.c[e]),n=0;n<a.length;n+=1)if(a[n]>0&&a[n]<1){var o=t.point(a[n])[e];o<i?i=o:o>r&&(r=o)}return{min:i,max:r}}function intersectData(t,e,i){var r=t.boundingBox();return{cx:r.cx,cy:r.cy,width:r.width,height:r.height,bez:t,t:(e+i)/2,t1:e,t2:i}}function splitData(t){var e=t.bez.split(.5);return[intersectData(e[0],t.t1,t.t),intersectData(e[1],t.t,t.t2)]}function boxIntersect(t,e){return 2*Math.abs(t.cx-e.cx)<t.width+e.width&&2*Math.abs(t.cy-e.cy)<t.height+e.height}function intersectsImpl(t,e,i,r,s,a){if(boxIntersect(t,e))if(i>=a||t.width<=r&&t.height<=r&&e.width<=r&&e.height<=r)s.push([t.t,e.t]);else{var n=splitData(t),o=splitData(e);intersectsImpl(n[0],o[0],i+1,r,s,a),intersectsImpl(n[0],o[1],i+1,r,s,a),intersectsImpl(n[1],o[0],i+1,r,s,a),intersectsImpl(n[1],o[1],i+1,r,s,a)}}function crossProduct(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function lineIntersection(t,e,i,r){var s=[t[0],t[1],1],a=[e[0],e[1],1],n=[i[0],i[1],1],o=[r[0],r[1],1],h=crossProduct(crossProduct(s,a),crossProduct(n,o));return floatZero(h[2])?null:[h[0]/h[2],h[1]/h[2]]}function polarOffset(t,e,i){return[t[0]+Math.cos(e)*i,t[1]-Math.sin(e)*i]}function pointDistance(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function pointEqual(t,e){return floatEqual(t[0],e[0])&&floatEqual(t[1],e[1])}function ZigZagModifier(){}function setPoint(t,e,i,r,s,a,n){var o=i-Math.PI/2,h=i+Math.PI/2,l=e[0]+Math.cos(i)*r*s,p=e[1]-Math.sin(i)*r*s;t.setTripleAt(l,p,l+Math.cos(o)*a,p-Math.sin(o)*a,l+Math.cos(h)*n,p-Math.sin(h)*n,t.length())}function getPerpendicularVector(t,e){var i=[e[0]-t[0],e[1]-t[1]],r=.5*-Math.PI;return[Math.cos(r)*i[0]-Math.sin(r)*i[1],Math.sin(r)*i[0]+Math.cos(r)*i[1]]}function getProjectingAngle(t,e){var i=0===e?t.length()-1:e-1,r=(e+1)%t.length(),s=getPerpendicularVector(t.v[i],t.v[r]);return Math.atan2(0,1)-Math.atan2(s[1],s[0])}function zigZagCorner(t,e,i,r,s,a,n){var o=getProjectingAngle(e,i),h=e.v[i%e._length],l=e.v[0===i?e._length-1:i-1],p=e.v[(i+1)%e._length],f=2===a?Math.sqrt(Math.pow(h[0]-l[0],2)+Math.pow(h[1]-l[1],2)):0,m=2===a?Math.sqrt(Math.pow(h[0]-p[0],2)+Math.pow(h[1]-p[1],2)):0;setPoint(t,e.v[i%e._length],o,n,r,m/(2*(s+1)),f/(2*(s+1)),a)}function zigZagSegment(t,e,i,r,s,a){for(var n=0;n<r;n+=1){var o=(n+1)/(r+1),h=2===s?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(o);setPoint(t,e.point(o),l,a,i,h/(2*(r+1)),h/(2*(r+1)),s),a=-a}return a}function linearOffset(t,e,i){var r=Math.atan2(e[0]-t[0],e[1]-t[1]);return[polarOffset(t,r,i),polarOffset(e,r,i)]}function offsetSegment(t,e){var i,r,s,a,n,o,h;i=(h=linearOffset(t.points[0],t.points[1],e))[0],r=h[1],s=(h=linearOffset(t.points[1],t.points[2],e))[0],a=h[1],n=(h=linearOffset(t.points[2],t.points[3],e))[0],o=h[1];var l=lineIntersection(i,r,s,a);null===l&&(l=r);var p=lineIntersection(n,o,s,a);return null===p&&(p=n),new PolynomialBezier(i,l,p,o)}function joinLines(t,e,i,r,s){var a=e.points[3],n=i.points[0];if(3===r)return a;if(pointEqual(a,n))return a;if(2===r){var o=-e.tangentAngle(1),h=-i.tangentAngle(0)+Math.PI,l=lineIntersection(a,polarOffset(a,o+Math.PI/2,100),n,polarOffset(n,o+Math.PI/2,100)),p=l?pointDistance(l,a):pointDistance(a,n)/2,f=polarOffset(a,o,2*p*roundCorner);return t.setXYAt(f[0],f[1],"o",t.length()-1),f=polarOffset(n,h,2*p*roundCorner),t.setTripleAt(n[0],n[1],n[0],n[1],f[0],f[1],t.length()),n}var m=lineIntersection(pointEqual(a,e.points[2])?e.points[0]:e.points[2],a,n,pointEqual(n,i.points[1])?i.points[3]:i.points[1]);return m&&pointDistance(m,a)<s?(t.setTripleAt(m[0],m[1],m[0],m[1],m[0],m[1],t.length()),m):a}function getIntersection(t,e){var i=t.intersections(e);return i.length&&floatEqual(i[0][0],1)&&i.shift(),i.length?i[0]:null}function pruneSegmentIntersection(t,e){var i=t.slice(),r=e.slice(),s=getIntersection(t[t.length-1],e[0]);return s&&(i[t.length-1]=t[t.length-1].split(s[0])[0],r[0]=e[0].split(s[1])[1]),t.length>1&&e.length>1&&(s=getIntersection(t[0],e[e.length-1]))?[[t[0].split(s[0])[0]],[e[e.length-1].split(s[1])[1]]]:[i,r]}function pruneIntersections(t){for(var e,i=1;i<t.length;i+=1)e=pruneSegmentIntersection(t[i-1],t[i]),t[i-1]=e[0],t[i]=e[1];return t.length>1&&(e=pruneSegmentIntersection(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}function offsetSegmentSplit(t,e){var i,r,s,a,n=t.inflectionPoints();if(0===n.length)return[offsetSegment(t,e)];if(1===n.length||floatEqual(n[1],1))return i=(s=t.split(n[0]))[0],r=s[1],[offsetSegment(i,e),offsetSegment(r,e)];i=(s=t.split(n[0]))[0];var o=(n[1]-n[0])/(1-n[0]);return a=(s=s[1].split(o))[0],r=s[1],[offsetSegment(i,e),offsetSegment(a,e),offsetSegment(r,e)]}function OffsetPathModifier(){}function getFontProperties(t){for(var e=t.fStyle?t.fStyle.split(" "):[],i="normal",r="normal",s=e.length,a=0;a<s;a+=1)switch(e[a].toLowerCase()){case"italic":r="italic";break;case"bold":i="700";break;case"black":i="900";break;case"medium":i="500";break;case"regular":case"normal":i="400";break;case"light":case"thin":i="200"}return{style:r,weight:t.fWeight||i}}extendPrototype([ShapeModifier],RepeaterModifier),RepeaterModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=PropertyFactory.getProp(t,e.c,0,null,this),this.o=PropertyFactory.getProp(t,e.o,0,null,this),this.tr=TransformPropertyFactory.getTransformProperty(t,e.tr,this),this.so=PropertyFactory.getProp(t,e.tr.so,0,.01,this),this.eo=PropertyFactory.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Matrix,this.rMatrix=new Matrix,this.sMatrix=new Matrix,this.tMatrix=new Matrix,this.matrix=new Matrix},RepeaterModifier.prototype.applyTransforms=function(t,e,i,r,s,a){var n=a?-1:1,o=r.s.v[0]+(1-r.s.v[0])*(1-s),h=r.s.v[1]+(1-r.s.v[1])*(1-s);t.translate(r.p.v[0]*n*s,r.p.v[1]*n*s,r.p.v[2]),e.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),e.rotate(-r.r.v*n*s),e.translate(r.a.v[0],r.a.v[1],r.a.v[2]),i.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),i.scale(a?1/o:o,a?1/h:h),i.translate(r.a.v[0],r.a.v[1],r.a.v[2])},RepeaterModifier.prototype.init=function(t,e,i,r){for(this.elem=t,this.arr=e,this.pos=i,this.elemsData=r,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[i]);i>0;)i-=1,this._elements.unshift(e[i]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},RepeaterModifier.prototype.cloneElements=function(t){var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},RepeaterModifier.prototype.changeGroupRender=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)t[i]._render=e,"gr"===t[i].ty&&this.changeGroupRender(t[i].it,e)},RepeaterModifier.prototype.processShapes=function(t){var e,i,r,s,a,n=!1;if(this._mdf||t){var o,h=Math.ceil(this.c.v);if(this._groups.length<h){for(;this._groups.length<h;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(a=0,r=0;r<=this._groups.length-1;r+=1){if(o=a<h,this._groups[r]._render=o,this.changeGroupRender(this._groups[r].it,o),!o){var p=this.elemsData[r].it,f=p[p.length-1];0!==f.transform.op.v?(f.transform.op._mdf=!0,f.transform.op.v=0):f.transform.op._mdf=!1}a+=1}this._currentCopies=h;var m=this.o.v,c=m%1,u=m>0?Math.floor(m):Math.ceil(m),d=this.pMatrix.props,y=this.rMatrix.props,g=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var v,b,P=0;if(m>0){for(;P<u;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),P+=1;c&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,c,!1),P+=c)}else if(m<0){for(;P>u;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),P-=1;c&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-c,!0),P-=c)}for(r=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(b=(i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(r/(this._currentCopies-1)),0!==P){for((0!==r&&1===s||r!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]),this.matrix.transform(d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9],d[10],d[11],d[12],d[13],d[14],d[15]),v=0;v<b;v+=1)i[v]=this.matrix.props[v];this.matrix.reset()}else for(this.matrix.reset(),v=0;v<b;v+=1)i[v]=this.matrix.props[v];P+=1,a-=1,r+=s}}else for(a=this._currentCopies,r=0,s=1;a;)i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,a-=1,r+=s;return n},RepeaterModifier.prototype.addShape=function(){},extendPrototype([ShapeModifier],RoundCornersModifier),RoundCornersModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=PropertyFactory.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},RoundCornersModifier.prototype.processPath=function(t,e){var i,r=shapePool.newElement();r.c=t.c;var s,a,n,o,h,l,p,f,m,c,u,d,y=t._length,g=0;for(i=0;i<y;i+=1)s=t.v[i],n=t.o[i],a=t.i[i],s[0]===n[0]&&s[1]===n[1]&&s[0]===a[0]&&s[1]===a[1]?0!==i&&i!==y-1||t.c?(o=0===i?t.v[y-1]:t.v[i-1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=u=s[0]+(o[0]-s[0])*l,f=d=s[1]-(s[1]-o[1])*l,m=p-(p-s[0])*roundCorner,c=f-(f-s[1])*roundCorner,r.setTripleAt(p,f,m,c,u,d,g),g+=1,o=i===y-1?t.v[0]:t.v[i+1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=m=s[0]+(o[0]-s[0])*l,f=c=s[1]+(o[1]-s[1])*l,u=p-(p-s[0])*roundCorner,d=f-(f-s[1])*roundCorner,r.setTripleAt(p,f,m,c,u,d,g),g+=1):(r.setTripleAt(s[0],s[1],n[0],n[1],a[0],a[1],g),g+=1):(r.setTripleAt(t.v[i][0],t.v[i][1],t.o[i][0],t.o[i][1],t.i[i][0],t.i[i][1],g),g+=1);return r},RoundCornersModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},PolynomialBezier.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},PolynomialBezier.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},PolynomialBezier.prototype.tangentAngle=function(t){var e=this.derivative(t);return Math.atan2(e[1],e[0])},PolynomialBezier.prototype.normalAngle=function(t){var e=this.derivative(t);return Math.atan2(e[0],e[1])},PolynomialBezier.prototype.inflectionPoints=function(){var t=this.a[1]*this.b[0]-this.a[0]*this.b[1];if(floatZero(t))return[];var e=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/t,i=e*e-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/t;if(i<0)return[];var r=Math.sqrt(i);return floatZero(r)?r>0&&r<1?[e]:[]:[e-r,e+r].filter((function(t){return t>0&&t<1}))},PolynomialBezier.prototype.split=function(t){if(t<=0)return[singlePoint(this.points[0]),this];if(t>=1)return[this,singlePoint(this.points[this.points.length-1])];var e=lerpPoint(this.points[0],this.points[1],t),i=lerpPoint(this.points[1],this.points[2],t),r=lerpPoint(this.points[2],this.points[3],t),s=lerpPoint(e,i,t),a=lerpPoint(i,r,t),n=lerpPoint(s,a,t);return[new PolynomialBezier(this.points[0],e,s,n,!0),new PolynomialBezier(n,a,r,this.points[3],!0)]},PolynomialBezier.prototype.bounds=function(){return{x:extrema(this,0),y:extrema(this,1)}},PolynomialBezier.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},PolynomialBezier.prototype.intersections=function(t,e,i){void 0===e&&(e=2),void 0===i&&(i=7);var r=[];return intersectsImpl(intersectData(this,0,1),intersectData(t,0,1),0,e,r,i),r},PolynomialBezier.shapeSegment=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[e],t.o[e],t.i[i],t.v[i],!0)},PolynomialBezier.shapeSegmentInverted=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[i],t.i[i],t.o[e],t.v[e],!0)},extendPrototype([ShapeModifier],ZigZagModifier),ZigZagModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=PropertyFactory.getProp(t,e.s,0,null,this),this.frequency=PropertyFactory.getProp(t,e.r,0,null,this),this.pointsType=PropertyFactory.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},ZigZagModifier.prototype.processPath=function(t,e,i,r){var s=t._length,a=shapePool.newElement();if(a.c=t.c,t.c||(s-=1),0===s)return a;var n=-1,o=PolynomialBezier.shapeSegment(t,0);zigZagCorner(a,t,0,e,i,r,n);for(var h=0;h<s;h+=1)n=zigZagSegment(a,o,e,i,r,-n),o=h!==s-1||t.c?PolynomialBezier.shapeSegment(t,(h+1)%s):null,zigZagCorner(a,t,h+1,e,i,r,n);return a},ZigZagModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amplitude.v,l=Math.max(0,Math.round(this.frequency.v)),p=this.pointsType.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h,l,p));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},extendPrototype([ShapeModifier],OffsetPathModifier),OffsetPathModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this.miterLimit=PropertyFactory.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},OffsetPathModifier.prototype.processPath=function(t,e,i,r){var s=shapePool.newElement();s.c=t.c;var a,n,o,h=t.length();t.c||(h-=1);var l=[];for(a=0;a<h;a+=1)o=PolynomialBezier.shapeSegment(t,a),l.push(offsetSegmentSplit(o,e));if(!t.c)for(a=h-1;a>=0;a-=1)o=PolynomialBezier.shapeSegmentInverted(t,a),l.push(offsetSegmentSplit(o,e));l=pruneIntersections(l);var p=null,f=null;for(a=0;a<l.length;a+=1){var m=l[a];for(f&&(p=joinLines(s,f,m[0],i,r)),f=m[m.length-1],n=0;n<m.length;n+=1)o=m[n],p&&pointEqual(o.points[0],p)?s.setXYAt(o.points[1][0],o.points[1][1],"o",s.length()-1):s.setTripleAt(o.points[0][0],o.points[0][1],o.points[1][0],o.points[1][1],o.points[0][0],o.points[0][1],s.length()),s.setTripleAt(o.points[3][0],o.points[3][1],o.points[3][0],o.points[3][1],o.points[2][0],o.points[2][1],s.length()),p=o.points[3]}return l.length&&joinLines(s,f,l[0][0],i,r),s},OffsetPathModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amount.v,l=this.miterLimit.v,p=this.lineJoin;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h,p,l));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var FontManager=function(){var t={w:0,size:0,shapes:[],data:{shapes:[]}},e=[];e=e.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);var i=127988,r=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function s(t,e){var i=createTag("span");i.setAttribute("aria-hidden",!0),i.style.fontFamily=e;var r=createTag("span");r.innerText="giItT1WQy@!-/#",i.style.position="absolute",i.style.left="-10000px",i.style.top="-10000px",i.style.fontSize="300px",i.style.fontVariant="normal",i.style.fontStyle="normal",i.style.fontWeight="normal",i.style.letterSpacing="0",i.appendChild(r),document.body.appendChild(i);var s=r.offsetWidth;return r.style.fontFamily=function(t){var e,i=t.split(","),r=i.length,s=[];for(e=0;e<r;e+=1)"sans-serif"!==i[e]&&"monospace"!==i[e]&&s.push(i[e]);return s.join(",")}(t)+", "+e,{node:r,w:s,parent:i}}function a(t,e){var i,r=document.body&&e?"svg":"canvas",s=getFontProperties(t);if("svg"===r){var a=createNS("text");a.style.fontSize="100px",a.setAttribute("font-family",t.fFamily),a.setAttribute("font-style",s.style),a.setAttribute("font-weight",s.weight),a.textContent="1",t.fClass?(a.style.fontFamily="inherit",a.setAttribute("class",t.fClass)):a.style.fontFamily=t.fFamily,e.appendChild(a),i=a}else{var n=new OffscreenCanvas(500,500).getContext("2d");n.font=s.style+" "+s.weight+" 100px "+t.fFamily,i=n}return{measureText:function(t){return"svg"===r?(i.textContent=t,i.getComputedTextLength()):i.measureText(t).width}}}function n(t){var e=0,i=t.charCodeAt(0);if(i>=55296&&i<=56319){var r=t.charCodeAt(1);r>=56320&&r<=57343&&(e=1024*(i-55296)+r-56320+65536)}return e}function o(t){var e=n(t);return e>=127462&&e<=127487}var h=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)};h.isModifier=function(t,e){var i=t.toString(16)+e.toString(16);return-1!==r.indexOf(i)},h.isZeroWidthJoiner=function(t){return 8205===t},h.isFlagEmoji=function(t){return o(t.substr(0,2))&&o(t.substr(2,2))},h.isRegionalCode=o,h.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},h.isRegionalFlag=function(t,e){var r=n(t.substr(e,2));if(r!==i)return!1;var s=0;for(e+=2;s<5;){if((r=n(t.substr(e,2)))<917601||r>917626)return!1;s+=1,e+=2}return 917631===n(t.substr(e,2))},h.isVariationSelector=function(t){return 65039===t},h.BLACK_FLAG_CODE_POINT=i;var l={addChars:function(t){if(t){var e;this.chars||(this.chars=[]);var i,r,s=t.length,a=this.chars.length;for(e=0;e<s;e+=1){for(i=0,r=!1;i<a;)this.chars[i].style===t[e].style&&this.chars[i].fFamily===t[e].fFamily&&this.chars[i].ch===t[e].ch&&(r=!0),i+=1;r||(this.chars.push(t[e]),a+=1)}}},addFonts:function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);if(!document.body)return this.isLoaded=!0,t.list.forEach((function(t){t.helper=a(t),t.cache={}})),void(this.fonts=t.list);var i,r=t.list,n=r.length,o=n;for(i=0;i<n;i+=1){var h,l,p=!0;if(r[i].loaded=!1,r[i].monoCase=s(r[i].fFamily,"monospace"),r[i].sansCase=s(r[i].fFamily,"sans-serif"),r[i].fPath){if("p"===r[i].fOrigin||3===r[i].origin){if((h=document.querySelectorAll('style[f-forigin="p"][f-family="'+r[i].fFamily+'"], style[f-origin="3"][f-family="'+r[i].fFamily+'"]')).length>0&&(p=!1),p){var f=createTag("style");f.setAttribute("f-forigin",r[i].fOrigin),f.setAttribute("f-origin",r[i].origin),f.setAttribute("f-family",r[i].fFamily),f.type="text/css",f.innerText="@font-face {font-family: "+r[i].fFamily+"; font-style: normal; src: url('"+r[i].fPath+"');}",e.appendChild(f)}}else if("g"===r[i].fOrigin||1===r[i].origin){for(h=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),l=0;l<h.length;l+=1)-1!==h[l].href.indexOf(r[i].fPath)&&(p=!1);if(p){var m=createTag("link");m.setAttribute("f-forigin",r[i].fOrigin),m.setAttribute("f-origin",r[i].origin),m.type="text/css",m.rel="stylesheet",m.href=r[i].fPath,document.body.appendChild(m)}}else if("t"===r[i].fOrigin||2===r[i].origin){for(h=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),l=0;l<h.length;l+=1)r[i].fPath===h[l].src&&(p=!1);if(p){var c=createTag("link");c.setAttribute("f-forigin",r[i].fOrigin),c.setAttribute("f-origin",r[i].origin),c.setAttribute("rel","stylesheet"),c.setAttribute("href",r[i].fPath),e.appendChild(c)}}}else r[i].loaded=!0,o-=1;r[i].helper=a(r[i],e),r[i].cache={},this.fonts.push(r[i])}0===o?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},getCharData:function(e,i,r){for(var s=0,a=this.chars.length;s<a;){if(this.chars[s].ch===e&&this.chars[s].style===i&&this.chars[s].fFamily===r)return this.chars[s];s+=1}return("string"==typeof e&&13!==e.charCodeAt(0)||!e)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",e,i,r)),t},getFontByName:function(t){for(var e=0,i=this.fonts.length;e<i;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,i){var r=this.getFontByName(e),s=t;if(!r.cache[s]){var a=r.helper;if(" "===t){var n=a.measureText("|"+t+"|"),o=a.measureText("||");r.cache[s]=(n-o)/100}else r.cache[s]=a.measureText(t)/100}return r.cache[s]*i},checkLoadedFonts:function(){var t,e,i,r=this.fonts.length,s=r;for(t=0;t<r;t+=1)this.fonts[t].loaded?s-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,i=this.fonts[t].monoCase.w,e.offsetWidth!==i?(s-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,i=this.fonts[t].sansCase.w,e.offsetWidth!==i&&(s-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==s&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}};return h.prototype=l,h}();function SlotManager(t){this.animationData=t}function slotFactory(t){return new SlotManager(t)}function RenderableElement(){}SlotManager.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},RenderableElement.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var getBlendMode=(blendModeEnums={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return blendModeEnums[t]||""}),blendModeEnums;function SliderEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function AngleEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function ColorEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function PointEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function LayerIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function MaskIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function CheckboxEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function NoValueEffect(){this.p={}}function EffectsManager(t,e){var i,r=t.ef||[];this.effectElements=[];var s,a=r.length;for(i=0;i<a;i+=1)s=new GroupEffect(r[i],e),this.effectElements.push(s)}function GroupEffect(t,e){this.init(t,e)}function BaseElement(){}function FrameElement(){}function FootageElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,i)}function AudioElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,i),this._isPlaying=!1,this._canPlay=!1;var r=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(r),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=PropertyFactory.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function BaseRenderer(){}extendPrototype([DynamicPropertyContainer],GroupEffect),GroupEffect.prototype.getValue=GroupEffect.prototype.iterateDynamicProperties,GroupEffect.prototype.init=function(t,e){var i;this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var r,s=this.data.ef.length,a=this.data.ef;for(i=0;i<s;i+=1){switch(r=null,a[i].ty){case 0:r=new SliderEffect(a[i],e,this);break;case 1:r=new AngleEffect(a[i],e,this);break;case 2:r=new ColorEffect(a[i],e,this);break;case 3:r=new PointEffect(a[i],e,this);break;case 4:case 7:r=new CheckboxEffect(a[i],e,this);break;case 10:r=new LayerIndexEffect(a[i],e,this);break;case 11:r=new MaskIndexEffect(a[i],e,this);break;case 5:r=new EffectsManager(a[i],e,this);break;default:r=new NoValueEffect(a[i],e,this)}r&&this.effectElements.push(r)}},BaseElement.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t=getExpressionInterfaces();if(t){var e=t("layer"),i=t("effects"),r=t("shape"),s=t("text"),a=t("comp");this.layerInterface=e(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var n=i.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(n),0===this.data.ty||this.data.xt?this.compInterface=a(this):4===this.data.ty?(this.layerInterface.shapeInterface=r(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=s(this),this.layerInterface.text=this.layerInterface.textInterface)}},setBlendMode:function(){var t=getBlendMode(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,i){this.globalData=e,this.comp=i,this.data=t,this.layerId=createElementID(),this.data.sr||(this.data.sr=1),this.effectsManager=new EffectsManager(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},FrameElement.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var i,r=this.dynamicProperties.length;for(i=0;i<r;i+=1)(e||this._isParent&&"transform"===this.dynamicProperties[i].propType)&&(this.dynamicProperties[i].getValue(),this.dynamicProperties[i]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},FootageElement.prototype.prepareFrame=function(){},extendPrototype([RenderableElement,BaseElement,FrameElement],FootageElement),FootageElement.prototype.getBaseElement=function(){return null},FootageElement.prototype.renderFrame=function(){},FootageElement.prototype.destroy=function(){},FootageElement.prototype.initExpressions=function(){var t=getExpressionInterfaces();if(t){var e=t("footage");this.layerInterface=e(this)}},FootageElement.prototype.getFootageData=function(){return this.footageData},AudioElement.prototype.prepareFrame=function(t){if(this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder)this._currentTime=t/this.data.sr;else{var e=this.tm.v;this._currentTime=e}this._volume=this.lv.v[0];var i=this._volume*this._volumeMultiplier;this._previousVolume!==i&&(this._previousVolume=i,this.audio.volume(i))},extendPrototype([RenderableElement,BaseElement,FrameElement],AudioElement),AudioElement.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek())>.1)&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},AudioElement.prototype.show=function(){},AudioElement.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},AudioElement.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},AudioElement.prototype.resume=function(){this._canPlay=!0},AudioElement.prototype.setRate=function(t){this.audio.rate(t)},AudioElement.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},AudioElement.prototype.getBaseElement=function(){return null},AudioElement.prototype.destroy=function(){},AudioElement.prototype.sourceRectAtTime=function(){},AudioElement.prototype.initExpressions=function(){},BaseRenderer.prototype.checkLayers=function(t){var e,i,r=this.layers.length;for(this.completeLayers=!0,e=r-1;e>=0;e-=1)this.elements[e]||(i=this.layers[e]).ip-i.st<=t-this.layers[e].st&&i.op-i.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:default:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t)}},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.createAudio=function(t){return new AudioElement(t,this.globalData,this)},BaseRenderer.prototype.createFootage=function(t){return new FootageElement(t,this.globalData,this)},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},BaseRenderer.prototype.includeLayers=function(t){var e;this.completeLayers=!1;var i,r=t.length,s=this.layers.length;for(e=0;e<r;e+=1)for(i=0;i<s;){if(this.layers[i].id===t[e].id){this.layers[i]=t[e];break}i+=1}},BaseRenderer.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},BaseRenderer.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},BaseRenderer.prototype.buildElementParenting=function(t,e,i){for(var r=this.elements,s=this.layers,a=0,n=s.length;a<n;)s[a].ind==e&&(r[a]&&!0!==r[a]?(i.push(r[a]),r[a].setAsParent(),void 0!==s[a].parent?this.buildElementParenting(t,s[a].parent,i):t.setHierarchy(i)):(this.buildItem(a),this.addPendingElement(t))),a+=1},BaseRenderer.prototype.addPendingElement=function(t){this.pendingElements.push(t)},BaseRenderer.prototype.searchExtraCompositions=function(t){var e,i=t.length;for(e=0;e<i;e+=1)if(t[e].xt){var r=this.createComp(t[e]);r.initExpressions(),this.globalData.projectInterface.registerComposition(r)}},BaseRenderer.prototype.getElementById=function(t){var e,i=this.elements.length;for(e=0;e<i;e+=1)if(this.elements[e].data.ind===t)return this.elements[e];return null},BaseRenderer.prototype.getElementByPath=function(t){var e,i=t.shift();if("number"==typeof i)e=this.elements[i];else{var r,s=this.elements.length;for(r=0;r<s;r+=1)if(this.elements[r].data.nm===i){e=this.elements[r];break}}return 0===t.length?e:e.getElementByPath(t)},BaseRenderer.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new FontManager,this.globalData.slotManager=slotFactory(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var effectTypes={TRANSFORM_EFFECT:"transformEFfect"};function TransformElement(){}function MaskElement(t,e,i){this.data=t,this.element=e,this.globalData=i,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var r,s,a=this.globalData.defs,n=this.masksProperties?this.masksProperties.length:0;this.viewData=createSizedArray(n),this.solidPath="";var o,h,l,p,f,m,c=this.masksProperties,u=0,d=[],y=createElementID(),g="clipPath",v="clip-path";for(r=0;r<n;r+=1)if(("a"!==c[r].mode&&"n"!==c[r].mode||c[r].inv||100!==c[r].o.k||c[r].o.x)&&(g="mask",v="mask"),"s"!==c[r].mode&&"i"!==c[r].mode||0!==u?l=null:((l=createNS("rect")).setAttribute("fill","#ffffff"),l.setAttribute("width",this.element.comp.data.w||0),l.setAttribute("height",this.element.comp.data.h||0),d.push(l)),s=createNS("path"),"n"===c[r].mode)this.viewData[r]={op:PropertyFactory.getProp(this.element,c[r].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[r],3),elem:s,lastPath:""},a.appendChild(s);else{var b;if(u+=1,s.setAttribute("fill","s"===c[r].mode?"#000000":"#ffffff"),s.setAttribute("clip-rule","nonzero"),0!==c[r].x.k?(g="mask",v="mask",m=PropertyFactory.getProp(this.element,c[r].x,0,null,this.element),b=createElementID(),(p=createNS("filter")).setAttribute("id",b),(f=createNS("feMorphology")).setAttribute("operator","erode"),f.setAttribute("in","SourceGraphic"),f.setAttribute("radius","0"),p.appendChild(f),a.appendChild(p),s.setAttribute("stroke","s"===c[r].mode?"#000000":"#ffffff")):(f=null,m=null),this.storedData[r]={elem:s,x:m,expan:f,lastPath:"",lastOperator:"",filterId:b,lastRadius:0},"i"===c[r].mode){h=d.length;var P=createNS("g");for(o=0;o<h;o+=1)P.appendChild(d[o]);var E=createNS("mask");E.setAttribute("mask-type","alpha"),E.setAttribute("id",y+"_"+u),E.appendChild(s),a.appendChild(E),P.setAttribute("mask","url("+getLocationHref()+"#"+y+"_"+u+")"),d.length=0,d.push(P)}else d.push(s);c[r].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[r]={elem:s,lastPath:"",op:PropertyFactory.getProp(this.element,c[r].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[r],3),invRect:l},this.viewData[r].prop.k||this.drawPath(c[r],this.viewData[r].prop.v,this.viewData[r])}for(this.maskElement=createNS(g),n=d.length,r=0;r<n;r+=1)this.maskElement.appendChild(d[r]);u>0&&(this.maskElement.setAttribute("id",y),this.element.maskedElement.setAttribute(v,"url("+getLocationHref()+"#"+y+")"),a.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}TransformElement.prototype={initTransform:function(){var t=new Matrix;this.finalTransform={mProp:this.data.ks?TransformPropertyFactory.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,i=0,r=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;i<r;){if(this.hierarchy[i].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}i+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),i=0;i<r;i+=1)e.multiply(this.hierarchy[i].finalTransform.mProp.v)}this.finalTransform._matMdf&&(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var i=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(i),t=1;t<e;t+=1){var r=this.localTransforms[t].matrix;i.multiply(r)}i.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){var s=this.finalTransform.localOpacity;for(t=0;t<e;t+=1)s*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=s}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new Matrix;var e=0,i=t.length;for(e=0;e<i;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var i,r=!0,s=this.comp;r;)s.finalTransform?(s.data.hasMask&&e.splice(0,0,s.finalTransform),s=s.comp):r=!1;var a,n=e.length;for(i=0;i<n;i+=1)a=e[i].mat.applyToPointArray(0,0,0),t=[t[0]-a[0],t[1]-a[1],0];return t},mHelper:new Matrix},MaskElement.prototype.getMaskProperty=function(t){return this.viewData[t].prop},MaskElement.prototype.renderFrame=function(t){var e,i=this.element.finalTransform.mat,r=this.masksProperties.length;for(e=0;e<r;e+=1)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[e].invRect.setAttribute("transform",i.getInverseMatrix().to2dCSS()),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var s=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+getLocationHref()+"#"+this.storedData[e].filterId+")")),s.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},MaskElement.prototype.getMaskelement=function(){return this.maskElement},MaskElement.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},MaskElement.prototype.drawPath=function(t,e,i){var r,s,a=" M"+e.v[0][0]+","+e.v[0][1];for(s=e._length,r=1;r<s;r+=1)a+=" C"+e.o[r-1][0]+","+e.o[r-1][1]+" "+e.i[r][0]+","+e.i[r][1]+" "+e.v[r][0]+","+e.v[r][1];if(e.c&&s>1&&(a+=" C"+e.o[r-1][0]+","+e.o[r-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),i.lastPath!==a){var n="";i.elem&&(e.c&&(n=t.inv?this.solidPath+a:a),i.elem.setAttribute("d",n)),i.lastPath=a}},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var filtersFactory=function(){var t={};return t.createFilter=function(t,e){var i=createNS("filter");i.setAttribute("id",t),!0!==e&&(i.setAttribute("filterUnits","objectBoundingBox"),i.setAttribute("x","0%"),i.setAttribute("y","0%"),i.setAttribute("width","100%"),i.setAttribute("height","100%"));return i},t.createAlphaToLuminanceFilter=function(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},t}(),featureSupport=function(){var t={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),/firefox/i.test(navigator.userAgent)&&(t.svgLumaHidden=!1),t}(),registeredEffects$1={},idPrefix="filter_result_";function SVGEffects(t){var e,i,r="SourceGraphic",s=t.data.ef?t.data.ef.length:0,a=createElementID(),n=filtersFactory.createFilter(a,!0),o=0;for(this.filters=[],e=0;e<s;e+=1){i=null;var h=t.data.ef[e].ty;if(registeredEffects$1[h])i=new(0,registeredEffects$1[h].effect)(n,t.effectsManager.effectElements[e],t,idPrefix+o,r),r=idPrefix+o,registeredEffects$1[h].countsAsEffect&&(o+=1);i&&this.filters.push(i)}o&&(t.globalData.defs.appendChild(n),t.layerElement.setAttribute("filter","url("+getLocationHref()+"#"+a+")")),this.filters.length&&t.addRenderableComponent(this)}function registerEffect$1(t,e,i){registeredEffects$1[t]={effect:e,countsAsEffect:i}}function SVGBaseElement(){}function HierarchyElement(){}function RenderableDOMElement(){}function IImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,i),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ProcessedElement(t,e){this.elem=t,this.pos=e}function IShapeElement(){}SVGEffects.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},SVGEffects.prototype.getEffects=function(t){var e,i=this.filters.length,r=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&r.push(this.filters[e]);return r},SVGBaseElement.prototype={initRendererElement:function(){this.layerElement=createNS("g")},createContainerElements:function(){this.matteElement=createNS("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t=null;if(this.data.td){this.matteMasks={};var e=createNS("g");e.setAttribute("id",this.layerId),e.appendChild(this.layerElement),t=e,this.globalData.defs.appendChild(e)}else this.data.tt?(this.matteElement.appendChild(this.layerElement),t=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var i=createNS("clipPath"),r=createNS("path");r.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var s=createElementID();if(i.setAttribute("id",s),i.appendChild(r),this.globalData.defs.appendChild(i),this.checkMasks()){var a=createNS("g");a.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),a.appendChild(this.layerElement),this.transformedElement=a,t?t.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData),this.renderableEffectsManager=new SVGEffects(this),this.searchEffectTransforms()},getMatte:function(t){if(this.matteMasks||(this.matteMasks={}),!this.matteMasks[t]){var e,i,r,s,a=this.layerId+"_"+t;if(1===t||3===t){var n=createNS("mask");n.setAttribute("id",a),n.setAttribute("mask-type",3===t?"luminance":"alpha"),(r=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),n.appendChild(r),this.globalData.defs.appendChild(n),featureSupport.maskType||1!==t||(n.setAttribute("mask-type","luminance"),e=createElementID(),i=filtersFactory.createFilter(e),this.globalData.defs.appendChild(i),i.appendChild(filtersFactory.createAlphaToLuminanceFilter()),(s=createNS("g")).appendChild(r),n.appendChild(s),s.setAttribute("filter","url("+getLocationHref()+"#"+e+")"))}else if(2===t){var o=createNS("mask");o.setAttribute("id",a),o.setAttribute("mask-type","alpha");var h=createNS("g");o.appendChild(h),e=createElementID(),i=filtersFactory.createFilter(e);var l=createNS("feComponentTransfer");l.setAttribute("in","SourceGraphic"),i.appendChild(l);var p=createNS("feFuncA");p.setAttribute("type","table"),p.setAttribute("tableValues","1.0 0.0"),l.appendChild(p),this.globalData.defs.appendChild(i);var f=createNS("rect");f.setAttribute("width",this.comp.data.w),f.setAttribute("height",this.comp.data.h),f.setAttribute("x","0"),f.setAttribute("y","0"),f.setAttribute("fill","#ffffff"),f.setAttribute("opacity","0"),h.setAttribute("filter","url("+getLocationHref()+"#"+e+")"),h.appendChild(f),(r=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),h.appendChild(r),featureSupport.maskType||(o.setAttribute("mask-type","luminance"),i.appendChild(filtersFactory.createAlphaToLuminanceFilter()),s=createNS("g"),h.appendChild(f),s.appendChild(this.layerElement),h.appendChild(s)),this.globalData.defs.appendChild(o)}this.matteMasks[t]=a}return this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+getLocationHref()+"#"+t+")")}},HierarchyElement.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},extendPrototype([RenderableElement,createProxyFunction({initElement:function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],RenderableDOMElement),extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],IImageElement),IImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=createNS("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},IImageElement.prototype.sourceRectAtTime=function(){return this.sourceRect},IShapeElement.prototype={addShapeToModifiers:function(t){var e,i=this.shapeModifiers.length;for(e=0;e<i;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;t>=0&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,i=0,r=e.length;i<r;){if(e[i].elem===t)return e[i].pos;i+=1}return 0},addProcessedElement:function(t,e){for(var i=this.processedElements,r=i.length;r;)if(i[r-=1].elem===t)return void(i[r].pos=e);i.push(new ProcessedElement(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var lineCapEnum={1:"butt",2:"round",3:"square"},lineJoinEnum={1:"miter",2:"round",3:"bevel"};function SVGShapeData(t,e,i){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=i,this.lvl=e,this._isAnimated=!!i.k;for(var r=0,s=t.length;r<s;){if(t[r].mProps.dynamicProperties.length){this._isAnimated=!0;break}r+=1}}function SVGStyleData(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=createNS("path"),this.msElem=null}function DashProperty(t,e,i,r){var s;this.elem=t,this.frameId=-1,this.dataProps=createSizedArray(e.length),this.renderer=i,this.k=!1,this.dashStr="",this.dashArray=createTypedArray("float32",e.length?e.length-1:0),this.dashoffset=createTypedArray("float32",1),this.initDynamicPropertyContainer(r);var a,n=e.length||0;for(s=0;s<n;s+=1)a=PropertyFactory.getProp(t,e[s].v,0,0,this),this.k=a.k||this.k,this.dataProps[s]={n:e[s].n,p:a};this.k||this.getValue(!0),this._isAnimated=this.k}function SVGStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i,this._isAnimated=!!this._isAnimated}function SVGFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i}function SVGNoStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=i}function GradientProperty(t,e,i){this.data=e,this.c=createTypedArray("uint8c",4*e.p);var r=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=createTypedArray("float32",r),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=r,this.initDynamicPropertyContainer(i),this.prop=PropertyFactory.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function SVGGradientFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,i)}function SVGGradientStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.initGradientData(t,e,i),this._isAnimated=!!this._isAnimated}function ShapeGroupData(){this.it=[],this.prevViewData=[],this.gr=createNS("g")}function SVGTransformData(t,e,i){this.transform={mProps:t,op:e,container:i},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}SVGShapeData.prototype.setAsAnimated=function(){this._isAnimated=!0},SVGStyleData.prototype.reset=function(){this.d="",this._mdf=!1},DashProperty.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,i=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<i;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},extendPrototype([DynamicPropertyContainer],DashProperty),extendPrototype([DynamicPropertyContainer],SVGStrokeStyleData),extendPrototype([DynamicPropertyContainer],SVGFillStyleData),extendPrototype([DynamicPropertyContainer],SVGNoStyleData),GradientProperty.prototype.comparePoints=function(t,e){for(var i=0,r=this.o.length/2;i<r;){if(Math.abs(t[4*i]-t[4*e+2*i])>.01)return!1;i+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},GradientProperty.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,i,r,s=4*this.data.p;for(e=0;e<s;e+=1)i=e%4==0?100:255,r=Math.round(this.prop.v[e]*i),this.c[e]!==r&&(this.c[e]=r,this._cmdf=!t);if(this.o.length)for(s=this.prop.v.length,e=4*this.data.p;e<s;e+=1)i=e%2==0?100:1,r=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==r&&(this.o[e-4*this.data.p]=r,this._omdf=!t);this._mdf=!t}},extendPrototype([DynamicPropertyContainer],GradientProperty),SVGGradientFillStyleData.prototype.initGradientData=function(t,e,i){this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.s=PropertyFactory.getProp(t,e.s,1,null,this),this.e=PropertyFactory.getProp(t,e.e,1,null,this),this.h=PropertyFactory.getProp(t,e.h||{k:0},0,.01,this),this.a=PropertyFactory.getProp(t,e.a||{k:0},0,degToRads,this),this.g=new GradientProperty(t,e.g,this),this.style=i,this.stops=[],this.setGradientData(i.pElem,e),this.setGradientOpacity(e,i),this._isAnimated=!!this._isAnimated},SVGGradientFillStyleData.prototype.setGradientData=function(t,e){var i=createElementID(),r=createNS(1===e.t?"linearGradient":"radialGradient");r.setAttribute("id",i),r.setAttribute("spreadMethod","pad"),r.setAttribute("gradientUnits","userSpaceOnUse");var s,a,n,o=[];for(n=4*e.g.p,a=0;a<n;a+=4)s=createNS("stop"),r.appendChild(s),o.push(s);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+getLocationHref()+"#"+i+")"),this.gf=r,this.cst=o},SVGGradientFillStyleData.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){var i,r,s,a=createNS("mask"),n=createNS("path");a.appendChild(n);var o=createElementID(),h=createElementID();a.setAttribute("id",h);var l=createNS(1===t.t?"linearGradient":"radialGradient");l.setAttribute("id",o),l.setAttribute("spreadMethod","pad"),l.setAttribute("gradientUnits","userSpaceOnUse"),s=t.g.k.k[0].s?t.g.k.k[0].s.length:t.g.k.k.length;var p=this.stops;for(r=4*t.g.p;r<s;r+=2)(i=createNS("stop")).setAttribute("stop-color","rgb(255,255,255)"),l.appendChild(i),p.push(i);n.setAttribute("gf"===t.ty?"fill":"stroke","url("+getLocationHref()+"#"+o+")"),"gs"===t.ty&&(n.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),n.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),1===t.lj&&n.setAttribute("stroke-miterlimit",t.ml)),this.of=l,this.ms=a,this.ost=p,this.maskId=h,e.msElem=n}},extendPrototype([DynamicPropertyContainer],SVGGradientFillStyleData),extendPrototype([SVGGradientFillStyleData,DynamicPropertyContainer],SVGGradientStrokeStyleData);var buildShapeString=function(t,e,i,r){if(0===e)return"";var s,a=t.o,n=t.i,o=t.v,h=" M"+r.applyToPointStringified(o[0][0],o[0][1]);for(s=1;s<e;s+=1)h+=" C"+r.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+r.applyToPointStringified(n[s][0],n[s][1])+" "+r.applyToPointStringified(o[s][0],o[s][1]);return i&&e&&(h+=" C"+r.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+r.applyToPointStringified(n[0][0],n[0][1])+" "+r.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},SVGElementsRenderer=function(){var t=new Matrix,e=new Matrix;function i(t,e,i){(i||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(i||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function r(){}function s(i,r,s){var a,n,o,h,l,p,f,m,c,u,d=r.styles.length,y=r.lvl;for(p=0;p<d;p+=1){if(h=r.sh._mdf||s,r.styles[p].lvl<y){for(m=e.reset(),c=y-r.styles[p].lvl,u=r.transformers.length-1;!h&&c>0;)h=r.transformers[u].mProps._mdf||h,c-=1,u-=1;if(h)for(c=y-r.styles[p].lvl,u=r.transformers.length-1;c>0;)m.multiply(r.transformers[u].mProps.v),c-=1,u-=1}else m=t;if(n=(f=r.sh.paths)._length,h){for(o="",a=0;a<n;a+=1)(l=f.shapes[a])&&l._length&&(o+=buildShapeString(l,l._length,l.c,m));r.caches[p]=o}else o=r.caches[p];r.styles[p].d+=!0===i.hd?"":o,r.styles[p]._mdf=h||r.styles[p]._mdf}}function a(t,e,i){var r=e.style;(e.c._mdf||i)&&r.pElem.setAttribute("fill","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("fill-opacity",e.o.v)}function n(t,e,i){o(t,e,i),h(t,e,i)}function o(t,e,i){var r,s,a,n,o,h=e.gf,l=e.g._hasOpacity,p=e.s.v,f=e.e.v;if(e.o._mdf||i){var m="gf"===t.ty?"fill-opacity":"stroke-opacity";e.style.pElem.setAttribute(m,e.o.v)}if(e.s._mdf||i){var c=1===t.t?"x1":"cx",u="x1"===c?"y1":"cy";h.setAttribute(c,p[0]),h.setAttribute(u,p[1]),l&&!e.g._collapsable&&(e.of.setAttribute(c,p[0]),e.of.setAttribute(u,p[1]))}if(e.g._cmdf||i){r=e.cst;var d=e.g.c;for(a=r.length,s=0;s<a;s+=1)(n=r[s]).setAttribute("offset",d[4*s]+"%"),n.setAttribute("stop-color","rgb("+d[4*s+1]+","+d[4*s+2]+","+d[4*s+3]+")")}if(l&&(e.g._omdf||i)){var y=e.g.o;for(a=(r=e.g._collapsable?e.cst:e.ost).length,s=0;s<a;s+=1)n=r[s],e.g._collapsable||n.setAttribute("offset",y[2*s]+"%"),n.setAttribute("stop-opacity",y[2*s+1])}if(1===t.t)(e.e._mdf||i)&&(h.setAttribute("x2",f[0]),h.setAttribute("y2",f[1]),l&&!e.g._collapsable&&(e.of.setAttribute("x2",f[0]),e.of.setAttribute("y2",f[1])));else if((e.s._mdf||e.e._mdf||i)&&(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)),h.setAttribute("r",o),l&&!e.g._collapsable&&e.of.setAttribute("r",o)),e.e._mdf||e.h._mdf||e.a._mdf||i){o||(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)));var g=Math.atan2(f[1]-p[1],f[0]-p[0]),v=e.h.v;v>=1?v=.99:v<=-1&&(v=-.99);var b=o*v,P=Math.cos(g+e.a.v)*b+p[0],E=Math.sin(g+e.a.v)*b+p[1];h.setAttribute("fx",P),h.setAttribute("fy",E),l&&!e.g._collapsable&&(e.of.setAttribute("fx",P),e.of.setAttribute("fy",E))}}function h(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||i)&&s.dashStr&&(r.pElem.setAttribute("stroke-dasharray",s.dashStr),r.pElem.setAttribute("stroke-dashoffset",s.dashoffset[0])),e.c&&(e.c._mdf||i)&&r.pElem.setAttribute("stroke","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||i)&&(r.pElem.setAttribute("stroke-width",e.w.v),r.msElem&&r.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function(t){switch(t.ty){case"fl":return a;case"gf":return o;case"gs":return n;case"st":return h;case"sh":case"el":case"rc":case"sr":return s;case"tr":return i;case"no":return r;default:return null}}}}();function SVGShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,i),this.prevViewData=[]}function LetterProps(t,e,i,r,s,a){this.o=t,this.sw=e,this.sc=i,this.fc=r,this.m=s,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!i,fc:!!r,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){var t,e,i,r,s=this.shapes.length,a=this.stylesList.length,n=[],o=!1;for(i=0;i<a;i+=1){for(r=this.stylesList[i],o=!1,n.length=0,t=0;t<s;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(r)&&(n.push(e),o=e._isAnimated||o);n.length>1&&o&&this.setShapesAsAnimated(n)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].setAsAnimated()},SVGShapeElement.prototype.createStyleElement=function(t,e){var i,r=new SVGStyleData(t,e),s=r.pElem;if("st"===t.ty)i=new SVGStrokeStyleData(this,t,r);else if("fl"===t.ty)i=new SVGFillStyleData(this,t,r);else if("gf"===t.ty||"gs"===t.ty){i=new("gf"===t.ty?SVGGradientFillStyleData:SVGGradientStrokeStyleData)(this,t,r),this.globalData.defs.appendChild(i.gf),i.maskId&&(this.globalData.defs.appendChild(i.ms),this.globalData.defs.appendChild(i.of),s.setAttribute("mask","url("+getLocationHref()+"#"+i.maskId+")"))}else"no"===t.ty&&(i=new SVGNoStyleData(this,t,r));return"st"!==t.ty&&"gs"!==t.ty||(s.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),s.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),s.setAttribute("fill-opacity","0"),1===t.lj&&s.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&s.setAttribute("fill-rule","evenodd"),t.ln&&s.setAttribute("id",t.ln),t.cl&&s.setAttribute("class",t.cl),t.bm&&(s.style["mix-blend-mode"]=getBlendMode(t.bm)),this.stylesList.push(r),this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createGroupElement=function(t){var e=new ShapeGroupData;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=getBlendMode(t.bm)),e},SVGShapeElement.prototype.createTransformElement=function(t,e){var i=TransformPropertyFactory.getTransformProperty(this,t,this),r=new SVGTransformData(i,i.o,e);return this.addToAnimatedContents(t,r),r},SVGShapeElement.prototype.createShapeElement=function(t,e,i){var r=4;"rc"===t.ty?r=5:"el"===t.ty?r=6:"sr"===t.ty&&(r=7);var s=new SVGShapeData(e,i,ShapePropertyFactory.getShapeProp(this,t,r,this));return this.shapes.push(s),this.addShapeToModifiers(s),this.addToAnimatedContents(t,s),s},SVGShapeElement.prototype.addToAnimatedContents=function(t,e){for(var i=0,r=this.animatedContents.length;i<r;){if(this.animatedContents[i].element===e)return;i+=1}this.animatedContents.push({fn:SVGElementsRenderer.createRenderFunction(t),element:e,data:t})},SVGShapeElement.prototype.setElementStyles=function(t){var e,i=t.styles,r=this.stylesList.length;for(e=0;e<r;e+=1)this.stylesList[e].closed||i.push(this.stylesList[e])},SVGShapeElement.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},SVGShapeElement.prototype.searchShapes=function(t,e,i,r,s,a,n){var o,h,l,p,f,m,c=[].concat(a),u=t.length-1,d=[],y=[];for(o=u;o>=0;o-=1){if((m=this.searchProcessedElement(t[o]))?e[o]=i[m-1]:t[o]._render=n,"fl"===t[o].ty||"st"===t[o].ty||"gf"===t[o].ty||"gs"===t[o].ty||"no"===t[o].ty)m?e[o].style.closed=!1:e[o]=this.createStyleElement(t[o],s),t[o]._render&&e[o].style.pElem.parentNode!==r&&r.appendChild(e[o].style.pElem),d.push(e[o].style);else if("gr"===t[o].ty){if(m)for(l=e[o].it.length,h=0;h<l;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,s+1,c,n),t[o]._render&&e[o].gr.parentNode!==r&&r.appendChild(e[o].gr)}else"tr"===t[o].ty?(m||(e[o]=this.createTransformElement(t[o],r)),p=e[o].transform,c.push(p)):"sh"===t[o].ty||"rc"===t[o].ty||"el"===t[o].ty||"sr"===t[o].ty?(m||(e[o]=this.createShapeElement(t[o],c,s)),this.setElementStyles(e[o])):"tm"===t[o].ty||"rd"===t[o].ty||"ms"===t[o].ty||"pb"===t[o].ty||"zz"===t[o].ty||"op"===t[o].ty?(m?(f=e[o]).closed=!1:((f=ShapeModifiers.getModifier(t[o].ty)).init(this,t[o]),e[o]=f,this.shapeModifiers.push(f)),y.push(f)):"rp"===t[o].ty&&(m?(f=e[o]).closed=!0:(f=ShapeModifiers.getModifier(t[o].ty),e[o]=f,f.init(this,t,o,e),this.shapeModifiers.push(f),n=!1),y.push(f));this.addProcessedElement(t[o],o+1)}for(u=d.length,o=0;o<u;o+=1)d[o].closed=!0;for(u=y.length,o=0;o<u;o+=1)y[o].closed=!0},SVGShapeElement.prototype.renderInnerContent=function(){var t;this.renderModifiers();var e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},SVGShapeElement.prototype.renderShape=function(){var t,e,i=this.animatedContents.length;for(t=0;t<i;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},SVGShapeElement.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},LetterProps.prototype.update=function(t,e,i,r,s,a){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1,this._mdf.p=!1;var n=!1;return this.o!==t&&(this.o=t,this._mdf.o=!0,n=!0),this.sw!==e&&(this.sw=e,this._mdf.sw=!0,n=!0),this.sc!==i&&(this.sc=i,this._mdf.sc=!0,n=!0),this.fc!==r&&(this.fc=r,this._mdf.fc=!0,n=!0),this.m!==s&&(this.m=s,this._mdf.m=!0,n=!0),!a.length||this.p[0]===a[0]&&this.p[1]===a[1]&&this.p[4]===a[4]&&this.p[5]===a[5]&&this.p[12]===a[12]&&this.p[13]===a[13]||(this.p=a,this._mdf.p=!0,n=!0),n},TextProperty.prototype.defaultBoxWidth=[0,0],TextProperty.prototype.copyData=function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},TextProperty.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},TextProperty.prototype.searchProperty=function(){return this.searchKeyframes()},TextProperty.prototype.searchKeyframes=function(){return this.kf=this.data.d.k.length>1,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,i=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{var r;this.lock=!0,this._mdf=!1;var s=this.effectsSequence.length,a=t||this.data.d.k[this.keysIndex].s;for(r=0;r<s;r+=1)a=i!==this.keysIndex?this.effectsSequence[r](a,a.t):this.effectsSequence[r](this.currentData,a.t);e!==a&&this.setCurrentData(a),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},TextProperty.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,i=0,r=t.length;i<=r-1&&!(i===r-1||t[i+1].t>e);)i+=1;return this.keysIndex!==i&&(this.keysIndex=i),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e,i,r=[],s=0,a=t.length,n=!1,o=!1,h="";s<a;)n=o,o=!1,e=t.charCodeAt(s),h=t.charAt(s),FontManager.isCombinedCharacter(e)?n=!0:e>=55296&&e<=56319?FontManager.isRegionalFlag(t,s)?h=t.substr(s,14):(i=t.charCodeAt(s+1))>=56320&&i<=57343&&(FontManager.isModifier(e,i)?(h=t.substr(s,2),n=!0):h=FontManager.isFlagEmoji(t.substr(s,4))?t.substr(s,4):t.substr(s,2)):e>56319?(i=t.charCodeAt(s+1),FontManager.isVariationSelector(e)&&(n=!0)):FontManager.isZeroWidthJoiner(e)&&(n=!0,o=!0),n?(r[r.length-1]+=h,n=!1):r.push(h),s+=h.length;return r},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,i,r,s,a,n,o,h=this.elem.globalData.fontManager,l=this.data,p=[],f=0,m=l.m.g,c=0,u=0,d=0,y=[],g=0,v=0,b=h.getFontByName(t.f),P=0,E=getFontProperties(b);t.fWeight=E.weight,t.fStyle=E.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),i=t.finalText.length,t.finalLineHeight=t.lh;var x,S=t.tr/1e3*t.finalSize;if(t.sz)for(var _,A,M=!0,T=t.sz[0],k=t.sz[1];M;){_=0,g=0,i=(A=this.buildFinalText(t.t)).length,S=t.tr/1e3*t.finalSize;var D=-1;for(e=0;e<i;e+=1)x=A[e].charCodeAt(0),r=!1," "===A[e]?D=e:13!==x&&3!==x||(g=0,r=!0,_+=t.finalLineHeight||1.2*t.finalSize),h.chars?(o=h.getCharData(A[e],b.fStyle,b.fFamily),P=r?0:o.w*t.finalSize/100):P=h.measureText(A[e],t.f,t.finalSize),g+P>T&&" "!==A[e]?(-1===D?i+=1:e=D,_+=t.finalLineHeight||1.2*t.finalSize,A.splice(e,D===e?1:0,"\r"),D=-1,g=0):(g+=P,g+=S);_+=b.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&k<_?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=A,i=t.finalText.length,M=!1)}g=-S,P=0;var F,C=0;for(e=0;e<i;e+=1)if(r=!1,13===(x=(F=t.finalText[e]).charCodeAt(0))||3===x?(C=0,y.push(g),v=g>v?g:v,g=-2*S,s="",r=!0,d+=1):s=F,h.chars?(o=h.getCharData(F,b.fStyle,h.getFontByName(t.f).fFamily),P=r?0:o.w*t.finalSize/100):P=h.measureText(s,t.f,t.finalSize)," "===F?C+=P+S:(g+=P+S+C,C=0),p.push({l:P,an:P,add:c,n:r,anIndexes:[],val:s,line:d,animatorJustifyOffset:0}),2==m){if(c+=P,""===s||" "===s||e===i-1){for(""!==s&&" "!==s||(c-=P);u<=e;)p[u].an=c,p[u].ind=f,p[u].extra=P,u+=1;f+=1,c=0}}else if(3==m){if(c+=P,""===s||e===i-1){for(""===s&&(c-=P);u<=e;)p[u].an=c,p[u].ind=f,p[u].extra=P,u+=1;c=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=g>v?g:v,y.push(g),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=y;var I,w,B,V,R=l.a;n=R.length;var L=[];for(a=0;a<n;a+=1){for((I=R[a]).a.sc&&(t.strokeColorAnim=!0),I.a.sw&&(t.strokeWidthAnim=!0),(I.a.fc||I.a.fh||I.a.fs||I.a.fb)&&(t.fillColorAnim=!0),V=0,B=I.s.b,e=0;e<i;e+=1)(w=p[e]).anIndexes[a]=V,(1==B&&""!==w.val||2==B&&""!==w.val&&" "!==w.val||3==B&&(w.n||" "==w.val||e==i-1)||4==B&&(w.n||e==i-1))&&(1===I.s.rn&&L.push(V),V+=1);l.a[a].s.totalChars=V;var G,z=-1;if(1===I.s.rn)for(e=0;e<i;e+=1)z!=(w=p[e]).anIndexes[a]&&(z=w.anIndexes[a],G=L.splice(Math.floor(Math.random()*L.length),1)[0]),w.anIndexes[a]=G}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=b.ascent*t.finalSize/100},TextProperty.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var i=this.copyData({},this.data.d.k[e].s);i=this.copyData(i,t),this.data.d.k[e].s=i,this.recalculate(e),this.setCurrentData(i),this.elem.addDynamicProperty(this)},TextProperty.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},TextProperty.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},TextProperty.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var TextSelectorProp=function(){var t=Math.max,e=Math.min,i=Math.floor;function r(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=PropertyFactory.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?PropertyFactory.getProp(t,e.e,0,0,this):{v:100},this.o=PropertyFactory.getProp(t,e.o||{k:0},0,0,this),this.xe=PropertyFactory.getProp(t,e.xe||{k:0},0,0,this),this.ne=PropertyFactory.getProp(t,e.ne||{k:0},0,0,this),this.sm=PropertyFactory.getProp(t,e.sm||{k:100},0,0,this),this.a=PropertyFactory.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return r.prototype={getMult:function(r){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var s=0,a=0,n=1,o=1;this.ne.v>0?s=this.ne.v/100:a=-this.ne.v/100,this.xe.v>0?n=1-this.xe.v/100:o=1+this.xe.v/100;var h=BezierFactory.getBezierEasing(s,a,n,o).get,l=0,p=this.finalS,f=this.finalE,m=this.data.sh;if(2===m)l=h(l=f===p?r>=f?1:0:t(0,e(.5/(f-p)+(r-p)/(f-p),1)));else if(3===m)l=h(l=f===p?r>=f?0:1:1-t(0,e(.5/(f-p)+(r-p)/(f-p),1)));else if(4===m)f===p?l=0:(l=t(0,e(.5/(f-p)+(r-p)/(f-p),1)))<.5?l*=2:l=1-2*(l-.5),l=h(l);else if(5===m){if(f===p)l=0;else{var c=f-p,u=-c/2+(r=e(t(0,r+.5-p),f-p)),d=c/2;l=Math.sqrt(1-u*u/(d*d))}l=h(l)}else 6===m?(f===p?l=0:(r=e(t(0,r+.5-p),f-p),l=(1+Math.cos(Math.PI+2*Math.PI*r/(f-p)))/2),l=h(l)):(r>=i(p)&&(l=t(0,e(r-p<0?e(f,1)-(p-r):f-r,1))),l=h(l));if(100!==this.sm.v){var y=.01*this.sm.v;0===y&&(y=1e-8);var g=.5-.5*y;l<g?l=0:(l=(l-g)/y)>1&&(l=1)}return l*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,i=this.o.v/e,r=this.s.v/e+i,s=this.e.v/e+i;if(r>s){var a=r;r=s,s=a}this.finalS=r,this.finalE=s}},extendPrototype([DynamicPropertyContainer],r),{getTextSelectorProp:function(t,e,i){return new r(t,e,i)}}}();function TextAnimatorDataProperty(t,e,i){var r={propType:!1},s=PropertyFactory.getProp,a=e.a;this.a={r:a.r?s(t,a.r,0,degToRads,i):r,rx:a.rx?s(t,a.rx,0,degToRads,i):r,ry:a.ry?s(t,a.ry,0,degToRads,i):r,sk:a.sk?s(t,a.sk,0,degToRads,i):r,sa:a.sa?s(t,a.sa,0,degToRads,i):r,s:a.s?s(t,a.s,1,.01,i):r,a:a.a?s(t,a.a,1,0,i):r,o:a.o?s(t,a.o,0,.01,i):r,p:a.p?s(t,a.p,1,0,i):r,sw:a.sw?s(t,a.sw,0,0,i):r,sc:a.sc?s(t,a.sc,1,0,i):r,fc:a.fc?s(t,a.fc,1,0,i):r,fh:a.fh?s(t,a.fh,0,0,i):r,fs:a.fs?s(t,a.fs,0,.01,i):r,fb:a.fb?s(t,a.fb,0,.01,i):r,t:a.t?s(t,a.t,0,0,i):r},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,i),this.s.t=e.s.t}function TextAnimatorProperty(t,e,i){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=i,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(i)}function ITextElement(){}TextAnimatorProperty.prototype.searchProperties=function(){var t,e,i=this._textData.a.length,r=PropertyFactory.getProp;for(t=0;t<i;t+=1)e=this._textData.a[t],this._animatorsData[t]=new TextAnimatorDataProperty(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:r(this._elem,this._textData.p.a,0,0,this),f:r(this._elem,this._textData.p.f,0,0,this),l:r(this._elem,this._textData.p.l,0,0,this),r:r(this._elem,this._textData.p.r,0,0,this),p:r(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=r(this._elem,this._textData.m.a,1,0,this)},TextAnimatorProperty.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var i,r,s,a,n,o,h,l,p,f,m,c,u,d,y,g,v,b,P,E=this._moreOptions.alignment.v,x=this._animatorsData,S=this._textData,_=this.mHelper,A=this._renderType,M=this.renderedLetters.length,T=t.l;if(this._hasMaskedPath){if(P=this._pathData.m,!this._pathData.n||this._pathData._mdf){var k,D=P.v;for(this._pathData.r.v&&(D=D.reverse()),n={tLength:0,segments:[]},a=D._length-1,g=0,s=0;s<a;s+=1)k=bez.buildBezierData(D.v[s],D.v[s+1],[D.o[s][0]-D.v[s][0],D.o[s][1]-D.v[s][1]],[D.i[s+1][0]-D.v[s+1][0],D.i[s+1][1]-D.v[s+1][1]]),n.tLength+=k.segmentLength,n.segments.push(k),g+=k.segmentLength;s=a,P.v.c&&(k=bez.buildBezierData(D.v[s],D.v[0],[D.o[s][0]-D.v[s][0],D.o[s][1]-D.v[s][1]],[D.i[0][0]-D.v[0][0],D.i[0][1]-D.v[0][1]]),n.tLength+=k.segmentLength,n.segments.push(k),g+=k.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,m=0,f=1,l=0,p=!0,d=n.segments,o<0&&P.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),f=(u=d[m=d.length-1].points).length-1;o<0;)o+=u[f].partialLength,(f-=1)<0&&(f=(u=d[m-=1].points).length-1);c=(u=d[m].points)[f-1],y=(h=u[f]).partialLength}a=T.length,i=0,r=0;var F,C,I,w,B,V=1.2*t.finalSize*.714,R=!0;I=x.length;var L,G,z,N,O,H,j,q,$,W,X,Z,Y=-1,K=o,J=m,U=f,Q=-1,tt="",et=this.defaultPropsArray;if(2===t.j||1===t.j){var it=0,rt=0,st=2===t.j?-.5:-1,at=0,nt=!0;for(s=0;s<a;s+=1)if(T[s].n){for(it&&(it+=rt);at<s;)T[at].animatorJustifyOffset=it,at+=1;it=0,nt=!0}else{for(C=0;C<I;C+=1)(F=x[C].a).t.propType&&(nt&&2===t.j&&(rt+=F.t.v*st),(B=x[C].s.getMult(T[s].anIndexes[C],S.a[C].s.totalChars)).length?it+=F.t.v*B[0]*st:it+=F.t.v*B*st);nt=!1}for(it&&(it+=rt);at<s;)T[at].animatorJustifyOffset=it,at+=1}for(s=0;s<a;s+=1){if(_.reset(),N=1,T[s].n)i=0,r+=t.yOffset,r+=R?1:0,o=K,R=!1,this._hasMaskedPath&&(f=U,c=(u=d[m=J].points)[f-1],y=(h=u[f]).partialLength,l=0),tt="",X="",$="",Z="",et=this.defaultPropsArray;else{if(this._hasMaskedPath){if(Q!==T[s].line){switch(t.j){case 1:o+=g-t.lineWidths[T[s].line];break;case 2:o+=(g-t.lineWidths[T[s].line])/2}Q=T[s].line}Y!==T[s].ind&&(T[Y]&&(o+=T[Y].extra),o+=T[s].an/2,Y=T[s].ind),o+=E[0]*T[s].an*.005;var ot=0;for(C=0;C<I;C+=1)(F=x[C].a).p.propType&&((B=x[C].s.getMult(T[s].anIndexes[C],S.a[C].s.totalChars)).length?ot+=F.p.v[0]*B[0]:ot+=F.p.v[0]*B),F.a.propType&&((B=x[C].s.getMult(T[s].anIndexes[C],S.a[C].s.totalChars)).length?ot+=F.a.v[0]*B[0]:ot+=F.a.v[0]*B);for(p=!0,this._pathData.a.v&&(o=.5*T[0].an+(g-this._pathData.f.v-.5*T[0].an-.5*T[T.length-1].an)*Y/(a-1),o+=this._pathData.f.v);p;)l+y>=o+ot||!u?(v=(o+ot-l)/h.partialLength,G=c.point[0]+(h.point[0]-c.point[0])*v,z=c.point[1]+(h.point[1]-c.point[1])*v,_.translate(-E[0]*T[s].an*.005,-E[1]*V*.01),p=!1):u&&(l+=h.partialLength,(f+=1)>=u.length&&(f=0,d[m+=1]?u=d[m].points:P.v.c?(f=0,u=d[m=0].points):(l-=h.partialLength,u=null)),u&&(c=h,y=(h=u[f]).partialLength));L=T[s].an/2-T[s].add,_.translate(-L,0,0)}else L=T[s].an/2-T[s].add,_.translate(-L,0,0),_.translate(-E[0]*T[s].an*.005,-E[1]*V*.01,0);for(C=0;C<I;C+=1)(F=x[C].a).t.propType&&(B=x[C].s.getMult(T[s].anIndexes[C],S.a[C].s.totalChars),0===i&&0===t.j||(this._hasMaskedPath?B.length?o+=F.t.v*B[0]:o+=F.t.v*B:B.length?i+=F.t.v*B[0]:i+=F.t.v*B));for(t.strokeWidthAnim&&(H=t.sw||0),t.strokeColorAnim&&(O=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(j=[t.fc[0],t.fc[1],t.fc[2]]),C=0;C<I;C+=1)(F=x[C].a).a.propType&&((B=x[C].s.getMult(T[s].anIndexes[C],S.a[C].s.totalChars)).length?_.translate(-F.a.v[0]*B[0],-F.a.v[1]*B[1],F.a.v[2]*B[2]):_.translate(-F.a.v[0]*B,-F.a.v[1]*B,F.a.v[2]*B));for(C=0;C<I;C+=1)(F=x[C].a).s.propType&&((B=x[C].s.getMult(T[s].anIndexes[C],S.a[C].s.totalChars)).length?_.scale(1+(F.s.v[0]-1)*B[0],1+(F.s.v[1]-1)*B[1],1):_.scale(1+(F.s.v[0]-1)*B,1+(F.s.v[1]-1)*B,1));for(C=0;C<I;C+=1){if(F=x[C].a,B=x[C].s.getMult(T[s].anIndexes[C],S.a[C].s.totalChars),F.sk.propType&&(B.length?_.skewFromAxis(-F.sk.v*B[0],F.sa.v*B[1]):_.skewFromAxis(-F.sk.v*B,F.sa.v*B)),F.r.propType&&(B.length?_.rotateZ(-F.r.v*B[2]):_.rotateZ(-F.r.v*B)),F.ry.propType&&(B.length?_.rotateY(F.ry.v*B[1]):_.rotateY(F.ry.v*B)),F.rx.propType&&(B.length?_.rotateX(F.rx.v*B[0]):_.rotateX(F.rx.v*B)),F.o.propType&&(B.length?N+=(F.o.v*B[0]-N)*B[0]:N+=(F.o.v*B-N)*B),t.strokeWidthAnim&&F.sw.propType&&(B.length?H+=F.sw.v*B[0]:H+=F.sw.v*B),t.strokeColorAnim&&F.sc.propType)for(q=0;q<3;q+=1)B.length?O[q]+=(F.sc.v[q]-O[q])*B[0]:O[q]+=(F.sc.v[q]-O[q])*B;if(t.fillColorAnim&&t.fc){if(F.fc.propType)for(q=0;q<3;q+=1)B.length?j[q]+=(F.fc.v[q]-j[q])*B[0]:j[q]+=(F.fc.v[q]-j[q])*B;F.fh.propType&&(j=B.length?addHueToRGB(j,F.fh.v*B[0]):addHueToRGB(j,F.fh.v*B)),F.fs.propType&&(j=B.length?addSaturationToRGB(j,F.fs.v*B[0]):addSaturationToRGB(j,F.fs.v*B)),F.fb.propType&&(j=B.length?addBrightnessToRGB(j,F.fb.v*B[0]):addBrightnessToRGB(j,F.fb.v*B))}}for(C=0;C<I;C+=1)(F=x[C].a).p.propType&&(B=x[C].s.getMult(T[s].anIndexes[C],S.a[C].s.totalChars),this._hasMaskedPath?B.length?_.translate(0,F.p.v[1]*B[0],-F.p.v[2]*B[1]):_.translate(0,F.p.v[1]*B,-F.p.v[2]*B):B.length?_.translate(F.p.v[0]*B[0],F.p.v[1]*B[1],-F.p.v[2]*B[2]):_.translate(F.p.v[0]*B,F.p.v[1]*B,-F.p.v[2]*B));if(t.strokeWidthAnim&&($=H<0?0:H),t.strokeColorAnim&&(W="rgb("+Math.round(255*O[0])+","+Math.round(255*O[1])+","+Math.round(255*O[2])+")"),t.fillColorAnim&&t.fc&&(X="rgb("+Math.round(255*j[0])+","+Math.round(255*j[1])+","+Math.round(255*j[2])+")"),this._hasMaskedPath){if(_.translate(0,-t.ls),_.translate(0,E[1]*V*.01+r,0),this._pathData.p.v){b=(h.point[1]-c.point[1])/(h.point[0]-c.point[0]);var ht=180*Math.atan(b)/Math.PI;h.point[0]<c.point[0]&&(ht+=180),_.rotate(-ht*Math.PI/180)}_.translate(G,z,0),o-=E[0]*T[s].an*.005,T[s+1]&&Y!==T[s+1].ind&&(o+=T[s].an/2,o+=.001*t.tr*t.finalSize)}else{switch(_.translate(i,r,0),t.ps&&_.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:_.translate(T[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[T[s].line]),0,0);break;case 2:_.translate(T[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[T[s].line])/2,0,0)}_.translate(0,-t.ls),_.translate(L,0,0),_.translate(E[0]*T[s].an*.005,E[1]*V*.01,0),i+=T[s].l+.001*t.tr*t.finalSize}"html"===A?tt=_.toCSS():"svg"===A?tt=_.to2dCSS():et=[_.props[0],_.props[1],_.props[2],_.props[3],_.props[4],_.props[5],_.props[6],_.props[7],_.props[8],_.props[9],_.props[10],_.props[11],_.props[12],_.props[13],_.props[14],_.props[15]],Z=N}M<=s?(w=new LetterProps(Z,$,W,X,tt,et),this.renderedLetters.push(w),M+=1,this.lettersChangedFlag=!0):(w=this.renderedLetters[s],this.lettersChangedFlag=w.update(Z,$,W,X,tt,et)||this.lettersChangedFlag)}}},TextAnimatorProperty.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},TextAnimatorProperty.prototype.mHelper=new Matrix,TextAnimatorProperty.prototype.defaultPropsArray=[],extendPrototype([DynamicPropertyContainer],TextAnimatorProperty),ITextElement.prototype.initElement=function(t,e,i){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,i),this.textProperty=new TextProperty(this,t.t,this.dynamicProperties),this.textAnimator=new TextAnimatorProperty(t.t,this.renderType,this),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},ITextElement.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},ITextElement.prototype.createPathShape=function(t,e){var i,r,s=e.length,a="";for(i=0;i<s;i+=1)"sh"===e[i].ty&&(r=e[i].ks.k,a+=buildShapeString(r,r.i.length,!0,t));return a},ITextElement.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},ITextElement.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},ITextElement.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},ITextElement.prototype.applyTextPropertiesToMatrix=function(t,e,i,r,s){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i])/2,0,0)}e.translate(r,s,0)},ITextElement.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},ITextElement.prototype.emptyProp=new LetterProps,ITextElement.prototype.destroy=function(){},ITextElement.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var emptyShapeData={shapes:[]};function SVGTextLottieElement(t,e,i){this.textSpans=[],this.renderType="svg",this.initElement(t,e,i)}function ISolidElement(t,e,i){this.initElement(t,e,i)}function NullElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initFrame(),this.initTransform(t,e,i),this.initHierarchy()}function SVGRendererBase(){}function ICompElement(){}function SVGCompElement(t,e,i){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function SVGRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=createNS("svg");var i="";if(e&&e.title){var r=createNS("title"),s=createElementID();r.setAttribute("id",s),r.textContent=e.title,this.svgElement.appendChild(r),i+=s}if(e&&e.description){var a=createNS("desc"),n=createElementID();a.setAttribute("id",n),a.textContent=e.description,this.svgElement.appendChild(a),i+=" "+n}i&&this.svgElement.setAttribute("aria-labelledby",i);var o=createNS("defs");this.svgElement.appendChild(o);var h=createNS("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],SVGTextLottieElement),SVGTextLottieElement.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=createNS("text"))},SVGTextLottieElement.prototype.buildTextContents=function(t){for(var e=0,i=t.length,r=[],s="";e<i;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(r.push(s),s=""):s+=t[e],e+=1;return r.push(s),r},SVGTextLottieElement.prototype.buildShapeData=function(t,e){if(t.shapes&&t.shapes.length){var i=t.shapes[0];if(i.it){var r=i.it[i.it.length-1];r.s&&(r.s.k[0]=e,r.s.k[1]=e)}}return t},SVGTextLottieElement.prototype.buildNewText=function(){var t,e;this.addDynamicProperty(this);var i=this.textProperty.currentData;this.renderedLetters=createSizedArray(i?i.l.length:0),i.fc?this.layerElement.setAttribute("fill",this.buildColor(i.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),i.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(i.sc)),this.layerElement.setAttribute("stroke-width",i.sw)),this.layerElement.setAttribute("font-size",i.finalSize);var r=this.globalData.fontManager.getFontByName(i.f);if(r.fClass)this.layerElement.setAttribute("class",r.fClass);else{this.layerElement.setAttribute("font-family",r.fFamily);var s=i.fWeight,a=i.fStyle;this.layerElement.setAttribute("font-style",a),this.layerElement.setAttribute("font-weight",s)}this.layerElement.setAttribute("aria-label",i.t);var n,o=i.l||[],h=!!this.globalData.fontManager.chars;e=o.length;var l=this.mHelper,p=this.data.singleShape,f=0,m=0,c=!0,u=.001*i.tr*i.finalSize;if(!p||h||i.sz){var d,y=this.textSpans.length;for(t=0;t<e;t+=1){if(this.textSpans[t]||(this.textSpans[t]={span:null,childSpan:null,glyph:null}),!h||!p||0===t){if(n=y>t?this.textSpans[t].span:createNS(h?"g":"text"),y<=t){if(n.setAttribute("stroke-linecap","butt"),n.setAttribute("stroke-linejoin","round"),n.setAttribute("stroke-miterlimit","4"),this.textSpans[t].span=n,h){var g=createNS("g");n.appendChild(g),this.textSpans[t].childSpan=g}this.textSpans[t].span=n,this.layerElement.appendChild(n)}n.style.display="inherit"}if(l.reset(),p&&(o[t].n&&(f=-u,m+=i.yOffset,m+=c?1:0,c=!1),this.applyTextPropertiesToMatrix(i,l,o[t].line,f,m),f+=o[t].l||0,f+=u),h){var v;if(1===(d=this.globalData.fontManager.getCharData(i.finalText[t],r.fStyle,this.globalData.fontManager.getFontByName(i.f).fFamily)).t)v=new SVGCompElement(d.data,this.globalData,this);else{var b=emptyShapeData;d.data&&d.data.shapes&&(b=this.buildShapeData(d.data,i.finalSize)),v=new SVGShapeElement(b,this.globalData,this)}if(this.textSpans[t].glyph){var P=this.textSpans[t].glyph;this.textSpans[t].childSpan.removeChild(P.layerElement),P.destroy()}this.textSpans[t].glyph=v,v._debug=!0,v.prepareFrame(0),v.renderFrame(),this.textSpans[t].childSpan.appendChild(v.layerElement),1===d.t&&this.textSpans[t].childSpan.setAttribute("transform","scale("+i.finalSize/100+","+i.finalSize/100+")")}else p&&n.setAttribute("transform","translate("+l.props[12]+","+l.props[13]+")"),n.textContent=o[t].val,n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}p&&n&&n.setAttribute("d","")}else{var E=this.textContainer,x="start";switch(i.j){case 1:x="end";break;case 2:x="middle";break;default:x="start"}E.setAttribute("text-anchor",x),E.setAttribute("letter-spacing",u);var S=this.buildTextContents(i.finalText);for(e=S.length,m=i.ps?i.ps[1]+i.ascent:0,t=0;t<e;t+=1)(n=this.textSpans[t].span||createNS("tspan")).textContent=S[t],n.setAttribute("x",0),n.setAttribute("y",m),n.style.display="inherit",E.appendChild(n),this.textSpans[t]||(this.textSpans[t]={span:null,glyph:null}),this.textSpans[t].span=n,m+=i.finalLineHeight;this.layerElement.appendChild(E)}for(;t<this.textSpans.length;)this.textSpans[t].span.style.display="none",t+=1;this._sizeChanged=!0},SVGTextLottieElement.prototype.sourceRectAtTime=function(){if(this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged){this._sizeChanged=!1;var t=this.layerElement.getBBox();this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}}return this.bbox},SVGTextLottieElement.prototype.getValue=function(){var t,e,i=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<i;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf&&(this._mdf=!0))},SVGTextLottieElement.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){var t,e;this._sizeChanged=!0;var i,r,s,a=this.textAnimator.renderedLetters,n=this.textProperty.currentData.l;for(e=n.length,t=0;t<e;t+=1)n[t].n||(i=a[t],r=this.textSpans[t].span,(s=this.textSpans[t].glyph)&&s.renderFrame(),i._mdf.m&&r.setAttribute("transform",i.m),i._mdf.o&&r.setAttribute("opacity",i.o),i._mdf.sw&&r.setAttribute("stroke-width",i.sw),i._mdf.sc&&r.setAttribute("stroke",i.sc),i._mdf.fc&&r.setAttribute("fill",i.fc))}},extendPrototype([IImageElement],ISolidElement),ISolidElement.prototype.createContent=function(){var t=createNS("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},NullElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},NullElement.prototype.renderFrame=function(){},NullElement.prototype.getBaseElement=function(){return null},NullElement.prototype.destroy=function(){},NullElement.prototype.sourceRectAtTime=function(){},NullElement.prototype.hide=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement],NullElement),extendPrototype([BaseRenderer],SVGRendererBase),SVGRendererBase.prototype.createNull=function(t){return new NullElement(t,this.globalData,this)},SVGRendererBase.prototype.createShape=function(t){return new SVGShapeElement(t,this.globalData,this)},SVGRendererBase.prototype.createText=function(t){return new SVGTextLottieElement(t,this.globalData,this)},SVGRendererBase.prototype.createImage=function(t){return new IImageElement(t,this.globalData,this)},SVGRendererBase.prototype.createSolid=function(t){return new ISolidElement(t,this.globalData,this)},SVGRendererBase.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var i=createNS("clipPath"),r=createNS("rect");r.setAttribute("width",t.w),r.setAttribute("height",t.h),r.setAttribute("x",0),r.setAttribute("y",0);var s=createElementID();i.setAttribute("id",s),i.appendChild(r),this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),e.appendChild(i),this.layers=t.layers,this.elements=createSizedArray(t.layers.length)},SVGRendererBase.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},SVGRendererBase.prototype.updateContainerSize=function(){},SVGRendererBase.prototype.findIndexByInd=function(t){var e=0,i=this.layers.length;for(e=0;e<i;e+=1)if(this.layers[e].ind===t)return e;return-1},SVGRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){e[t]=!0;var i=this.createItem(this.layers[t]);if(e[t]=i,getExpressionsPlugin()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(i),i.initExpressions()),this.appendElementInPos(i,t),this.layers[t].tt){var r="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1;if(-1===r)return;if(this.elements[r]&&!0!==this.elements[r]){var s=e[r].getMatte(this.layers[t].tt);i.setMatte(s)}else this.buildItem(r),this.addPendingElement(i)}}},SVGRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,i=this.elements.length;e<i;){if(this.elements[e]===t){var r="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,s=this.elements[r].getMatte(this.layers[e].tt);t.setMatte(s);break}e+=1}}},SVGRendererBase.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){var e;null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var i=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=i-1;e>=0;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<i;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},SVGRendererBase.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){for(var r,s=0;s<e;)this.elements[s]&&!0!==this.elements[s]&&this.elements[s].getBaseElement()&&(r=this.elements[s].getBaseElement()),s+=1;r?this.layerElement.insertBefore(i,r):this.layerElement.appendChild(i)}},SVGRendererBase.prototype.hide=function(){this.layerElement.style.display="none"},SVGRendererBase.prototype.show=function(){this.layerElement.style.display="block"},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement,RenderableDOMElement],ICompElement),ICompElement.prototype.initElement=function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},ICompElement.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var i,r=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),i=r-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&(this.elements[i].prepareFrame(this.renderedFrame-this.layers[i].st),this.elements[i]._mdf&&(this._mdf=!0))}},ICompElement.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},ICompElement.prototype.setElements=function(t){this.elements=t},ICompElement.prototype.getElements=function(){return this.elements},ICompElement.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},ICompElement.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},extendPrototype([SVGRendererBase,ICompElement,SVGBaseElement],SVGCompElement),SVGCompElement.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},extendPrototype([SVGRendererBase],SVGRenderer),SVGRenderer.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)};var registeredEffects={};function CVEffects(t){var e,i,r=t.data.ef?t.data.ef.length:0;for(this.filters=[],e=0;e<r;e+=1){i=null;var s=t.data.ef[e].ty;if(registeredEffects[s])i=new(0,registeredEffects[s].effect)(t.effectsManager.effectElements[e],t);i&&this.filters.push(i)}this.filters.length&&t.addRenderableComponent(this)}function registerEffect(t,e){registeredEffects[t]={effect:e}}function HBaseElement(){}function HSolidElement(t,e,i){this.initElement(t,e,i)}function HShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.shapesContainer=createNS("g"),this.initElement(t,e,i),this.prevViewData=[],this.currentBBox={x:999999,y:-999999,h:0,w:0}}function HTextElement(t,e,i){this.textSpans=[],this.textPaths=[],this.currentBBox={x:999999,y:-999999,h:0,w:0},this.renderType="svg",this.isMasked=!1,this.initElement(t,e,i)}function HCameraElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initHierarchy();var r=PropertyFactory.getProp;if(this.pe=r(this,t.pe,0,0,this),t.ks.p.s?(this.px=r(this,t.ks.p.x,1,0,this),this.py=r(this,t.ks.p.y,1,0,this),this.pz=r(this,t.ks.p.z,1,0,this)):this.p=r(this,t.ks.p,1,0,this),t.ks.a&&(this.a=r(this,t.ks.a,1,0,this)),t.ks.or.k.length&&t.ks.or.k[0].to){var s,a=t.ks.or.k.length;for(s=0;s<a;s+=1)t.ks.or.k[s].to=null,t.ks.or.k[s].ti=null}this.or=r(this,t.ks.or,1,degToRads,this),this.or.sh=!0,this.rx=r(this,t.ks.rx,0,degToRads,this),this.ry=r(this,t.ks.ry,0,degToRads,this),this.rz=r(this,t.ks.rz,0,degToRads,this),this.mat=new Matrix,this._prevMat=new Matrix,this._isFirstFrame=!0,this.finalTransform={mProp:this}}function HImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.initElement(t,e,i)}function HybridRendererBase(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"}},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}function HCompElement(t,e,i){this.layers=t.layers,this.supports3d=!t.hasMask,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function HybridRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"},runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}CVEffects.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},CVEffects.prototype.getEffects=function(t){var e,i=this.filters.length,r=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&r.push(this.filters[e]);return r},HBaseElement.prototype={checkBlendMode:function(){},initRendererElement:function(){this.baseElement=createTag(this.data.tg||"div"),this.data.hasMask?(this.svgElement=createNS("svg"),this.layerElement=createNS("g"),this.maskedElement=this.layerElement,this.svgElement.appendChild(this.layerElement),this.baseElement.appendChild(this.svgElement)):this.layerElement=this.baseElement,styleDiv(this.baseElement)},createContainerElements:function(){this.renderableEffectsManager=new CVEffects(this),this.transformedElement=this.baseElement,this.maskedElement=this.layerElement,this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0!==this.data.bm&&this.setBlendMode()},renderElement:function(){var t=this.transformedElement?this.transformedElement.style:{};if(this.finalTransform._matMdf){var e=this.finalTransform.mat.toCSS();t.transform=e,t.webkitTransform=e}this.finalTransform._opMdf&&(t.opacity=this.finalTransform.mProp.o.v)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},destroy:function(){this.layerElement=null,this.transformedElement=null,this.matteElement&&(this.matteElement=null),this.maskManager&&(this.maskManager.destroy(),this.maskManager=null)},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData)},addEffects:function(){},setMatte:function(){}},HBaseElement.prototype.getBaseElement=SVGBaseElement.prototype.getBaseElement,HBaseElement.prototype.destroyBaseElement=HBaseElement.prototype.destroy,HBaseElement.prototype.buildElementParenting=BaseRenderer.prototype.buildElementParenting,extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],HSolidElement),HSolidElement.prototype.createContent=function(){var t;this.data.hasMask?((t=createNS("rect")).setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.svgElement.setAttribute("width",this.data.sw),this.svgElement.setAttribute("height",this.data.sh)):((t=createTag("div")).style.width=this.data.sw+"px",t.style.height=this.data.sh+"px",t.style.backgroundColor=this.data.sc),this.layerElement.appendChild(t)},extendPrototype([BaseElement,TransformElement,HSolidElement,SVGShapeElement,HBaseElement,HierarchyElement,FrameElement,RenderableElement],HShapeElement),HShapeElement.prototype._renderShapeFrame=HShapeElement.prototype.renderInnerContent,HShapeElement.prototype.createContent=function(){var t;if(this.baseElement.style.fontSize=0,this.data.hasMask)this.layerElement.appendChild(this.shapesContainer),t=this.svgElement;else{t=createNS("svg");var e=this.comp.data?this.comp.data:this.globalData.compSize;t.setAttribute("width",e.w),t.setAttribute("height",e.h),t.appendChild(this.shapesContainer),this.layerElement.appendChild(t)}this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.shapesContainer,0,[],!0),this.filterUniqueShapes(),this.shapeCont=t},HShapeElement.prototype.getTransformedPoint=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)e=t[i].mProps.v.applyToPointArray(e[0],e[1],0);return e},HShapeElement.prototype.calculateShapeBoundingBox=function(t,e){var i,r,s,a,n,o=t.sh.v,h=t.transformers,l=o._length;if(!(l<=1)){for(i=0;i<l-1;i+=1)r=this.getTransformedPoint(h,o.v[i]),s=this.getTransformedPoint(h,o.o[i]),a=this.getTransformedPoint(h,o.i[i+1]),n=this.getTransformedPoint(h,o.v[i+1]),this.checkBounds(r,s,a,n,e);o.c&&(r=this.getTransformedPoint(h,o.v[i]),s=this.getTransformedPoint(h,o.o[i]),a=this.getTransformedPoint(h,o.i[0]),n=this.getTransformedPoint(h,o.v[0]),this.checkBounds(r,s,a,n,e))}},HShapeElement.prototype.checkBounds=function(t,e,i,r,s){this.getBoundsOfCurve(t,e,i,r);var a=this.shapeBoundingBox;s.x=bmMin(a.left,s.x),s.xMax=bmMax(a.right,s.xMax),s.y=bmMin(a.top,s.y),s.yMax=bmMax(a.bottom,s.yMax)},HShapeElement.prototype.shapeBoundingBox={left:0,right:0,top:0,bottom:0},HShapeElement.prototype.tempBoundingBox={x:0,xMax:0,y:0,yMax:0,width:0,height:0},HShapeElement.prototype.getBoundsOfCurve=function(t,e,i,r){for(var s,a,n,o,h,l,p,f=[[t[0],r[0]],[t[1],r[1]]],m=0;m<2;++m)a=6*t[m]-12*e[m]+6*i[m],s=-3*t[m]+9*e[m]-9*i[m]+3*r[m],n=3*e[m]-3*t[m],a|=0,n|=0,0===(s|=0)&&0===a||(0===s?(o=-n/a)>0&&o<1&&f[m].push(this.calculateF(o,t,e,i,r,m)):(h=a*a-4*n*s)>=0&&((l=(-a+bmSqrt(h))/(2*s))>0&&l<1&&f[m].push(this.calculateF(l,t,e,i,r,m)),(p=(-a-bmSqrt(h))/(2*s))>0&&p<1&&f[m].push(this.calculateF(p,t,e,i,r,m))));this.shapeBoundingBox.left=bmMin.apply(null,f[0]),this.shapeBoundingBox.top=bmMin.apply(null,f[1]),this.shapeBoundingBox.right=bmMax.apply(null,f[0]),this.shapeBoundingBox.bottom=bmMax.apply(null,f[1])},HShapeElement.prototype.calculateF=function(t,e,i,r,s,a){return bmPow(1-t,3)*e[a]+3*bmPow(1-t,2)*t*i[a]+3*(1-t)*bmPow(t,2)*r[a]+bmPow(t,3)*s[a]},HShapeElement.prototype.calculateBoundingBox=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)t[i]&&t[i].sh?this.calculateShapeBoundingBox(t[i],e):t[i]&&t[i].it?this.calculateBoundingBox(t[i].it,e):t[i]&&t[i].style&&t[i].w&&this.expandStrokeBoundingBox(t[i].w,e)},HShapeElement.prototype.expandStrokeBoundingBox=function(t,e){var i=0;if(t.keyframes){for(var r=0;r<t.keyframes.length;r+=1){var s=t.keyframes[r].s;s>i&&(i=s)}i*=t.mult}else i=t.v*t.mult;e.x-=i,e.xMax+=i,e.y-=i,e.yMax+=i},HShapeElement.prototype.currentBoxContains=function(t){return this.currentBBox.x<=t.x&&this.currentBBox.y<=t.y&&this.currentBBox.width+this.currentBBox.x>=t.x+t.width&&this.currentBBox.height+this.currentBBox.y>=t.y+t.height},HShapeElement.prototype.renderInnerContent=function(){if(this._renderShapeFrame(),!this.hidden&&(this._isFirstFrame||this._mdf)){var t=this.tempBoundingBox,e=999999;if(t.x=e,t.xMax=-e,t.y=e,t.yMax=-e,this.calculateBoundingBox(this.itemsData,t),t.width=t.xMax<t.x?0:t.xMax-t.x,t.height=t.yMax<t.y?0:t.yMax-t.y,this.currentBoxContains(t))return;var i=!1;if(this.currentBBox.w!==t.width&&(this.currentBBox.w=t.width,this.shapeCont.setAttribute("width",t.width),i=!0),this.currentBBox.h!==t.height&&(this.currentBBox.h=t.height,this.shapeCont.setAttribute("height",t.height),i=!0),i||this.currentBBox.x!==t.x||this.currentBBox.y!==t.y){this.currentBBox.w=t.width,this.currentBBox.h=t.height,this.currentBBox.x=t.x,this.currentBBox.y=t.y,this.shapeCont.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h);var r=this.shapeCont.style,s="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)";r.transform=s,r.webkitTransform=s}}},extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],HTextElement),HTextElement.prototype.createContent=function(){if(this.isMasked=this.checkMasks(),this.isMasked){this.renderType="svg",this.compW=this.comp.data.w,this.compH=this.comp.data.h,this.svgElement.setAttribute("width",this.compW),this.svgElement.setAttribute("height",this.compH);var t=createNS("g");this.maskedElement.appendChild(t),this.innerElem=t}else this.renderType="html",this.innerElem=this.layerElement;this.checkParenting()},HTextElement.prototype.buildNewText=function(){var t=this.textProperty.currentData;this.renderedLetters=createSizedArray(t.l?t.l.length:0);var e=this.innerElem.style,i=t.fc?this.buildColor(t.fc):"rgba(0,0,0,0)";e.fill=i,e.color=i,t.sc&&(e.stroke=this.buildColor(t.sc),e.strokeWidth=t.sw+"px");var r,s,a=this.globalData.fontManager.getFontByName(t.f);if(!this.globalData.fontManager.chars)if(e.fontSize=t.finalSize+"px",e.lineHeight=t.finalSize+"px",a.fClass)this.innerElem.className=a.fClass;else{e.fontFamily=a.fFamily;var n=t.fWeight,o=t.fStyle;e.fontStyle=o,e.fontWeight=n}var h,l,p,f=t.l;s=f.length;var m,c=this.mHelper,u="",d=0;for(r=0;r<s;r+=1){if(this.globalData.fontManager.chars?(this.textPaths[d]?h=this.textPaths[d]:((h=createNS("path")).setAttribute("stroke-linecap",lineCapEnum[1]),h.setAttribute("stroke-linejoin",lineJoinEnum[2]),h.setAttribute("stroke-miterlimit","4")),this.isMasked||(this.textSpans[d]?p=(l=this.textSpans[d]).children[0]:((l=createTag("div")).style.lineHeight=0,(p=createNS("svg")).appendChild(h),styleDiv(l)))):this.isMasked?h=this.textPaths[d]?this.textPaths[d]:createNS("text"):this.textSpans[d]?(l=this.textSpans[d],h=this.textPaths[d]):(styleDiv(l=createTag("span")),styleDiv(h=createTag("span")),l.appendChild(h)),this.globalData.fontManager.chars){var y,g=this.globalData.fontManager.getCharData(t.finalText[r],a.fStyle,this.globalData.fontManager.getFontByName(t.f).fFamily);if(y=g?g.data:null,c.reset(),y&&y.shapes&&y.shapes.length&&(m=y.shapes[0].it,c.scale(t.finalSize/100,t.finalSize/100),u=this.createPathShape(c,m),h.setAttribute("d",u)),this.isMasked)this.innerElem.appendChild(h);else{if(this.innerElem.appendChild(l),y&&y.shapes){document.body.appendChild(p);var v=p.getBBox();p.setAttribute("width",v.width+2),p.setAttribute("height",v.height+2),p.setAttribute("viewBox",v.x-1+" "+(v.y-1)+" "+(v.width+2)+" "+(v.height+2));var b=p.style,P="translate("+(v.x-1)+"px,"+(v.y-1)+"px)";b.transform=P,b.webkitTransform=P,f[r].yOffset=v.y-1}else p.setAttribute("width",1),p.setAttribute("height",1);l.appendChild(p)}}else if(h.textContent=f[r].val,h.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),this.isMasked)this.innerElem.appendChild(h);else{this.innerElem.appendChild(l);var E=h.style,x="translate3d(0,"+-t.finalSize/1.2+"px,0)";E.transform=x,E.webkitTransform=x}this.isMasked?this.textSpans[d]=h:this.textSpans[d]=l,this.textSpans[d].style.display="block",this.textPaths[d]=h,d+=1}for(;d<this.textSpans.length;)this.textSpans[d].style.display="none",d+=1},HTextElement.prototype.renderInnerContent=function(){var t;if(this.validateText(),this.data.singleShape){if(!this._isFirstFrame&&!this.lettersChangedFlag)return;if(this.isMasked&&this.finalTransform._matMdf){this.svgElement.setAttribute("viewBox",-this.finalTransform.mProp.p.v[0]+" "+-this.finalTransform.mProp.p.v[1]+" "+this.compW+" "+this.compH),t=this.svgElement.style;var e="translate("+-this.finalTransform.mProp.p.v[0]+"px,"+-this.finalTransform.mProp.p.v[1]+"px)";t.transform=e,t.webkitTransform=e}}if(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag){var i,r,s,a,n,o=0,h=this.textAnimator.renderedLetters,l=this.textProperty.currentData.l;for(r=l.length,i=0;i<r;i+=1)l[i].n?o+=1:(a=this.textSpans[i],n=this.textPaths[i],s=h[o],o+=1,s._mdf.m&&(this.isMasked?a.setAttribute("transform",s.m):(a.style.webkitTransform=s.m,a.style.transform=s.m)),a.style.opacity=s.o,s.sw&&s._mdf.sw&&n.setAttribute("stroke-width",s.sw),s.sc&&s._mdf.sc&&n.setAttribute("stroke",s.sc),s.fc&&s._mdf.fc&&(n.setAttribute("fill",s.fc),n.style.color=s.fc));if(this.innerElem.getBBox&&!this.hidden&&(this._isFirstFrame||this._mdf)){var p=this.innerElem.getBBox();this.currentBBox.w!==p.width&&(this.currentBBox.w=p.width,this.svgElement.setAttribute("width",p.width)),this.currentBBox.h!==p.height&&(this.currentBBox.h=p.height,this.svgElement.setAttribute("height",p.height));if(this.currentBBox.w!==p.width+2||this.currentBBox.h!==p.height+2||this.currentBBox.x!==p.x-1||this.currentBBox.y!==p.y-1){this.currentBBox.w=p.width+2,this.currentBBox.h=p.height+2,this.currentBBox.x=p.x-1,this.currentBBox.y=p.y-1,this.svgElement.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h),t=this.svgElement.style;var f="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)";t.transform=f,t.webkitTransform=f}}}},extendPrototype([BaseElement,FrameElement,HierarchyElement],HCameraElement),HCameraElement.prototype.setup=function(){var t,e,i,r,s=this.comp.threeDElements.length;for(t=0;t<s;t+=1)if("3d"===(e=this.comp.threeDElements[t]).type){i=e.perspectiveElem.style,r=e.container.style;var a=this.pe.v+"px",n="0px 0px 0px",o="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";i.perspective=a,i.webkitPerspective=a,r.transformOrigin=n,r.mozTransformOrigin=n,r.webkitTransformOrigin=n,i.transform=o,i.webkitTransform=o}},HCameraElement.prototype.createElements=function(){},HCameraElement.prototype.hide=function(){},HCameraElement.prototype.renderFrame=function(){var t,e,i=this._isFirstFrame;if(this.hierarchy)for(e=this.hierarchy.length,t=0;t<e;t+=1)i=this.hierarchy[t].finalTransform.mProp._mdf||i;if(i||this.pe._mdf||this.p&&this.p._mdf||this.px&&(this.px._mdf||this.py._mdf||this.pz._mdf)||this.rx._mdf||this.ry._mdf||this.rz._mdf||this.or._mdf||this.a&&this.a._mdf){if(this.mat.reset(),this.hierarchy)for(t=e=this.hierarchy.length-1;t>=0;t-=1){var r=this.hierarchy[t].finalTransform.mProp;this.mat.translate(-r.p.v[0],-r.p.v[1],r.p.v[2]),this.mat.rotateX(-r.or.v[0]).rotateY(-r.or.v[1]).rotateZ(r.or.v[2]),this.mat.rotateX(-r.rx.v).rotateY(-r.ry.v).rotateZ(r.rz.v),this.mat.scale(1/r.s.v[0],1/r.s.v[1],1/r.s.v[2]),this.mat.translate(r.a.v[0],r.a.v[1],r.a.v[2])}if(this.p?this.mat.translate(-this.p.v[0],-this.p.v[1],this.p.v[2]):this.mat.translate(-this.px.v,-this.py.v,this.pz.v),this.a){var s;s=this.p?[this.p.v[0]-this.a.v[0],this.p.v[1]-this.a.v[1],this.p.v[2]-this.a.v[2]]:[this.px.v-this.a.v[0],this.py.v-this.a.v[1],this.pz.v-this.a.v[2]];var a=Math.sqrt(Math.pow(s[0],2)+Math.pow(s[1],2)+Math.pow(s[2],2)),n=[s[0]/a,s[1]/a,s[2]/a],o=Math.sqrt(n[2]*n[2]+n[0]*n[0]),h=Math.atan2(n[1],o),l=Math.atan2(n[0],-n[2]);this.mat.rotateY(l).rotateX(-h)}this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v),this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]),this.mat.translate(this.globalData.compSize.w/2,this.globalData.compSize.h/2,0),this.mat.translate(0,0,this.pe.v);var p=!this._prevMat.equals(this.mat);if((p||this.pe._mdf)&&this.comp.threeDElements){var f,m,c;for(e=this.comp.threeDElements.length,t=0;t<e;t+=1)if("3d"===(f=this.comp.threeDElements[t]).type){if(p){var u=this.mat.toCSS();(c=f.container.style).transform=u,c.webkitTransform=u}this.pe._mdf&&((m=f.perspectiveElem.style).perspective=this.pe.v+"px",m.webkitPerspective=this.pe.v+"px")}this.mat.clone(this._prevMat)}}this._isFirstFrame=!1},HCameraElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},HCameraElement.prototype.destroy=function(){},HCameraElement.prototype.getBaseElement=function(){return null},extendPrototype([BaseElement,TransformElement,HBaseElement,HSolidElement,HierarchyElement,FrameElement,RenderableElement],HImageElement),HImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData),e=new Image;this.data.hasMask?(this.imageElem=createNS("image"),this.imageElem.setAttribute("width",this.assetData.w+"px"),this.imageElem.setAttribute("height",this.assetData.h+"px"),this.imageElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.imageElem),this.baseElement.setAttribute("width",this.assetData.w),this.baseElement.setAttribute("height",this.assetData.h)):this.layerElement.appendChild(e),e.crossOrigin="anonymous",e.src=t,this.data.ln&&this.baseElement.setAttribute("id",this.data.ln)},extendPrototype([BaseRenderer],HybridRendererBase),HybridRendererBase.prototype.buildItem=SVGRenderer.prototype.buildItem,HybridRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},HybridRendererBase.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){var r=this.layers[e];if(r.ddd&&this.supports3d)this.addTo3dContainer(i,e);else if(this.threeDElements)this.addTo3dContainer(i,e);else{for(var s,a,n=0;n<e;)this.elements[n]&&!0!==this.elements[n]&&this.elements[n].getBaseElement&&(a=this.elements[n],s=(this.layers[n].ddd?this.getThreeDContainerByPos(n):a.getBaseElement())||s),n+=1;s?r.ddd&&this.supports3d||this.layerElement.insertBefore(i,s):r.ddd&&this.supports3d||this.layerElement.appendChild(i)}}},HybridRendererBase.prototype.createShape=function(t){return this.supports3d?new HShapeElement(t,this.globalData,this):new SVGShapeElement(t,this.globalData,this)},HybridRendererBase.prototype.createText=function(t){return this.supports3d?new HTextElement(t,this.globalData,this):new SVGTextLottieElement(t,this.globalData,this)},HybridRendererBase.prototype.createCamera=function(t){return this.camera=new HCameraElement(t,this.globalData,this),this.camera},HybridRendererBase.prototype.createImage=function(t){return this.supports3d?new HImageElement(t,this.globalData,this):new IImageElement(t,this.globalData,this)},HybridRendererBase.prototype.createSolid=function(t){return this.supports3d?new HSolidElement(t,this.globalData,this):new ISolidElement(t,this.globalData,this)},HybridRendererBase.prototype.createNull=SVGRenderer.prototype.createNull,HybridRendererBase.prototype.getThreeDContainerByPos=function(t){for(var e=0,i=this.threeDElements.length;e<i;){if(this.threeDElements[e].startPos<=t&&this.threeDElements[e].endPos>=t)return this.threeDElements[e].perspectiveElem;e+=1}return null},HybridRendererBase.prototype.createThreeDContainer=function(t,e){var i,r,s=createTag("div");styleDiv(s);var a=createTag("div");if(styleDiv(a),"3d"===e){(i=s.style).width=this.globalData.compSize.w+"px",i.height=this.globalData.compSize.h+"px";var n="50% 50%";i.webkitTransformOrigin=n,i.mozTransformOrigin=n,i.transformOrigin=n;var o="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";(r=a.style).transform=o,r.webkitTransform=o}s.appendChild(a);var h={container:a,perspectiveElem:s,startPos:t,endPos:t,type:e};return this.threeDElements.push(h),h},HybridRendererBase.prototype.build3dContainers=function(){var t,e,i=this.layers.length,r="";for(t=0;t<i;t+=1)this.layers[t].ddd&&3!==this.layers[t].ty?("3d"!==r&&(r="3d",e=this.createThreeDContainer(t,"3d")),e.endPos=Math.max(e.endPos,t)):("2d"!==r&&(r="2d",e=this.createThreeDContainer(t,"2d")),e.endPos=Math.max(e.endPos,t));for(t=(i=this.threeDElements.length)-1;t>=0;t-=1)this.resizerElem.appendChild(this.threeDElements[t].perspectiveElem)},HybridRendererBase.prototype.addTo3dContainer=function(t,e){for(var i=0,r=this.threeDElements.length;i<r;){if(e<=this.threeDElements[i].endPos){for(var s,a=this.threeDElements[i].startPos;a<e;)this.elements[a]&&this.elements[a].getBaseElement&&(s=this.elements[a].getBaseElement()),a+=1;s?this.threeDElements[i].container.insertBefore(t,s):this.threeDElements[i].container.appendChild(t);break}i+=1}},HybridRendererBase.prototype.configAnimation=function(t){var e=createTag("div"),i=this.animationItem.wrapper,r=e.style;r.width=t.w+"px",r.height=t.h+"px",this.resizerElem=e,styleDiv(e),r.transformStyle="flat",r.mozTransformStyle="flat",r.webkitTransformStyle="flat",this.renderConfig.className&&e.setAttribute("class",this.renderConfig.className),i.appendChild(e),r.overflow="hidden";var s=createNS("svg");s.setAttribute("width","1"),s.setAttribute("height","1"),styleDiv(s),this.resizerElem.appendChild(s);var a=createNS("defs");s.appendChild(a),this.data=t,this.setupGlobalData(t,s),this.globalData.defs=a,this.layers=t.layers,this.layerElement=this.resizerElem,this.build3dContainers(),this.updateContainerSize()},HybridRendererBase.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.animationItem.container=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},HybridRendererBase.prototype.updateContainerSize=function(){var t,e,i,r,s=this.animationItem.wrapper.offsetWidth,a=this.animationItem.wrapper.offsetHeight,n=s/a;this.globalData.compSize.w/this.globalData.compSize.h>n?(t=s/this.globalData.compSize.w,e=s/this.globalData.compSize.w,i=0,r=(a-this.globalData.compSize.h*(s/this.globalData.compSize.w))/2):(t=a/this.globalData.compSize.h,e=a/this.globalData.compSize.h,i=(s-this.globalData.compSize.w*(a/this.globalData.compSize.h))/2,r=0);var o=this.resizerElem.style;o.webkitTransform="matrix3d("+t+",0,0,0,0,"+e+",0,0,0,0,1,0,"+i+","+r+",0,1)",o.transform=o.webkitTransform},HybridRendererBase.prototype.renderFrame=SVGRenderer.prototype.renderFrame,HybridRendererBase.prototype.hide=function(){this.resizerElem.style.display="none"},HybridRendererBase.prototype.show=function(){this.resizerElem.style.display="block"},HybridRendererBase.prototype.initItems=function(){if(this.buildAllItems(),this.camera)this.camera.setup();else{var t,e=this.globalData.compSize.w,i=this.globalData.compSize.h,r=this.threeDElements.length;for(t=0;t<r;t+=1){var s=this.threeDElements[t].perspectiveElem.style;s.webkitPerspective=Math.sqrt(Math.pow(e,2)+Math.pow(i,2))+"px",s.perspective=s.webkitPerspective}}},HybridRendererBase.prototype.searchExtraCompositions=function(t){var e,i=t.length,r=createTag("div");for(e=0;e<i;e+=1)if(t[e].xt){var s=this.createComp(t[e],r,this.globalData.comp,null);s.initExpressions(),this.globalData.projectInterface.registerComposition(s)}},extendPrototype([HybridRendererBase,ICompElement,HBaseElement],HCompElement),HCompElement.prototype._createBaseContainerElements=HCompElement.prototype.createContainerElements,HCompElement.prototype.createContainerElements=function(){this._createBaseContainerElements(),this.data.hasMask?(this.svgElement.setAttribute("width",this.data.w),this.svgElement.setAttribute("height",this.data.h),this.transformedElement=this.baseElement):this.transformedElement=this.layerElement},HCompElement.prototype.addTo3dContainer=function(t,e){for(var i,r=0;r<e;)this.elements[r]&&this.elements[r].getBaseElement&&(i=this.elements[r].getBaseElement()),r+=1;i?this.layerElement.insertBefore(t,i):this.layerElement.appendChild(t)},HCompElement.prototype.createComp=function(t){return this.supports3d?new HCompElement(t,this.globalData,this):new SVGCompElement(t,this.globalData,this)},extendPrototype([HybridRendererBase],HybridRenderer),HybridRenderer.prototype.createComp=function(t){return this.supports3d?new HCompElement(t,this.globalData,this):new SVGCompElement(t,this.globalData,this)},registerRenderer("html",HybridRenderer),ShapeModifiers.registerModifier("tm",TrimModifier),ShapeModifiers.registerModifier("pb",PuckerAndBloatModifier),ShapeModifiers.registerModifier("rp",RepeaterModifier),ShapeModifiers.registerModifier("rd",RoundCornersModifier),ShapeModifiers.registerModifier("zz",ZigZagModifier),ShapeModifiers.registerModifier("op",OffsetPathModifier);var CompExpressionInterface=function(t){function e(e){for(var i=0,r=t.layers.length;i<r;){if(t.layers[i].nm===e||t.layers[i].ind===e)return t.elements[i].layerInterface;i+=1}return null}return Object.defineProperty(e,"_name",{value:t.data.nm}),e.layer=e,e.pixelAspect=1,e.height=t.data.h||t.globalData.compSize.h,e.width=t.data.w||t.globalData.compSize.w,e.pixelAspect=1,e.frameDuration=1/t.globalData.frameRate,e.displayStartTime=0,e.numLayers=t.layers.length,e};function _typeof$2(t){return _typeof$2="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$2(t)}function seedRandom(t,e){var i,r=this,s=256,a=e.pow(s,6),n=e.pow(2,52),o=2*n,h=255;function l(t){var e,i=t.length,r=this,a=0,n=r.i=r.j=0,o=r.S=[];for(i||(t=[i++]);a<s;)o[a]=a++;for(a=0;a<s;a++)o[a]=o[n=h&n+t[a%i]+(e=o[a])],o[n]=e;r.g=function(t){for(var e,i=0,a=r.i,n=r.j,o=r.S;t--;)e=o[a=h&a+1],i=i*s+o[h&(o[a]=o[n=h&n+e])+(o[n]=e)];return r.i=a,r.j=n,i}}function p(t,e){return e.i=t.i,e.j=t.j,e.S=t.S.slice(),e}function f(t,e){var i,r=[],s=_typeof$2(t);if(e&&"object"==s)for(i in t)try{r.push(f(t[i],e-1))}catch(t){}return r.length?r:"string"==s?t:t+"\0"}function m(t,e){for(var i,r=t+"",s=0;s<r.length;)e[h&s]=h&(i^=19*e[h&s])+r.charCodeAt(s++);return c(e)}function c(t){return String.fromCharCode.apply(0,t)}e.seedrandom=function(h,u,d){var y=[],g=m(f((u=!0===u?{entropy:!0}:u||{}).entropy?[h,c(t)]:null===h?function(){try{i;var e=new Uint8Array(s);return(r.crypto||r.msCrypto).getRandomValues(e),c(e)}catch(e){var a=r.navigator,n=a&&a.plugins;return[+new Date,r,n,r.screen,c(t)]}}():h,3),y),v=new l(y),b=function(){for(var t=v.g(6),e=a,i=0;t<n;)t=(t+i)*s,e*=s,i=v.g(1);for(;t>=o;)t/=2,e/=2,i>>>=1;return(t+i)/e};return b.int32=function(){return 0|v.g(4)},b.quick=function(){return v.g(4)/4294967296},b.double=b,m(c(v.S),t),(u.pass||d||function(t,i,r,s){return s&&(s.S&&p(s,v),t.state=function(){return p(v,{})}),r?(e.random=t,i):t})(b,g,"global"in u?u.global:this==e,u.state)},m(e.random(),t)}function initialize$2(t){seedRandom([],t)}var propTypes={SHAPE:"shape"};function _typeof$1(t){return _typeof$1="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$1(t)}var ExpressionManager=function(){var ob={},Math=BMMath,window=null,document=null,XMLHttpRequest=null,fetch=null,frames=null,_lottieGlobal={};function resetFrame(){_lottieGlobal={}}function $bm_isInstanceOfArray(t){return t.constructor===Array||t.constructor===Float32Array}function isNumerable(t,e){return"number"===t||e instanceof Number||"boolean"===t||"string"===t}function $bm_neg(t){var e=_typeof$1(t);if("number"===e||t instanceof Number||"boolean"===e)return-t;if($bm_isInstanceOfArray(t)){var i,r=t.length,s=[];for(i=0;i<r;i+=1)s[i]=-t[i];return s}return t.propType?t.v:-t}initialize$2(BMMath);var easeInBez=BezierFactory.getBezierEasing(.333,0,.833,.833,"easeIn").get,easeOutBez=BezierFactory.getBezierEasing(.167,.167,.667,1,"easeOut").get,easeInOutBez=BezierFactory.getBezierEasing(.33,0,.667,1,"easeInOut").get;function sum(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e)||"string"===i||"string"===r)return t+e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]+=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t+e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]+e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}var add=sum;function sub(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e))return"string"===i&&(t=parseInt(t,10)),"string"===r&&(e=parseInt(e,10)),t-e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]-=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t-e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]-e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}function mul(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t*e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]*e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t*e[r];return i}return 0}function div(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t/e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]/e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t/e[r];return i}return 0}function mod(t,e){return"string"==typeof t&&(t=parseInt(t,10)),"string"==typeof e&&(e=parseInt(e,10)),t%e}var $bm_sum=sum,$bm_sub=sub,$bm_mul=mul,$bm_div=div,$bm_mod=mod;function clamp(t,e,i){if(e>i){var r=i;i=e,e=r}return Math.min(Math.max(t,e),i)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return e=e||0,Math.abs(t-e);var i;e||(e=helperLengthArray);var r=Math.min(t.length,e.length),s=0;for(i=0;i<r;i+=1)s+=Math.pow(e[i]-t[i],2);return Math.sqrt(s)}function normalize(t){return div(t,length(t))}function rgbToHsl(t){var e,i,r=t[0],s=t[1],a=t[2],n=Math.max(r,s,a),o=Math.min(r,s,a),h=(n+o)/2;if(n===o)e=0,i=0;else{var l=n-o;switch(i=h>.5?l/(2-n-o):l/(n+o),n){case r:e=(s-a)/l+(s<a?6:0);break;case s:e=(a-r)/l+2;break;case a:e=(r-s)/l+4}e/=6}return[e,i,h,t[3]]}function hue2rgb(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}function hslToRgb(t){var e,i,r,s=t[0],a=t[1],n=t[2];if(0===a)e=n,r=n,i=n;else{var o=n<.5?n*(1+a):n+a-n*a,h=2*n-o;e=hue2rgb(h,o,s+1/3),i=hue2rgb(h,o,s),r=hue2rgb(h,o,s-1/3)}return[e,i,r,t[3]]}function linear(t,e,i,r,s){if(void 0!==r&&void 0!==s||(r=e,s=i,e=0,i=1),i<e){var a=i;i=e,e=a}if(t<=e)return r;if(t>=i)return s;var n,o=i===e?0:(t-e)/(i-e);if(!r.length)return r+(s-r)*o;var h=r.length,l=createTypedArray("float32",h);for(n=0;n<h;n+=1)l[n]=r[n]+(s[n]-r[n])*o;return l}function random(t,e){if(void 0===e&&(void 0===t?(t=0,e=1):(e=t,t=void 0)),e.length){var i,r=e.length;t||(t=createTypedArray("float32",r));var s=createTypedArray("float32",r),a=BMMath.random();for(i=0;i<r;i+=1)s[i]=t[i]+a*(e[i]-t[i]);return s}return void 0===t&&(t=0),t+BMMath.random()*(e-t)}function createPath(t,e,i,r){var s,a=t.length,n=shapePool.newElement();n.setPathData(!!r,a);var o,h,l=[0,0];for(s=0;s<a;s+=1)o=e&&e[s]?e[s]:l,h=i&&i[s]?i[s]:l,n.setTripleAt(t[s][0],t[s][1],h[0]+t[s][0],h[1]+t[s][1],o[0]+t[s][0],o[1]+t[s][1],s,!0);return n}function initiateExpression(elem,data,property){function noOp(t){return t}if(!elem.globalData.renderConfig.runExpressions)return noOp;var val=data.x,needsVelocity=/velocity(?![\w\d])/.test(val),_needsRandom=-1!==val.indexOf("random"),elemType=elem.data.ty,transform,$bm_transform,content,effect,thisProperty=property;thisProperty.valueAtTime=thisProperty.getValueAtTime,Object.defineProperty(thisProperty,"value",{get:function(){return thisProperty.v}}),elem.comp.frameDuration=1/elem.comp.globalData.frameRate,elem.comp.displayStartTime=0;var inPoint=elem.data.ip/elem.comp.globalData.frameRate,outPoint=elem.data.op/elem.comp.globalData.frameRate,width=elem.data.sw?elem.data.sw:0,height=elem.data.sh?elem.data.sh:0,name=elem.data.nm,loopIn,loop_in,loopOut,loop_out,smooth,toWorld,fromWorld,fromComp,toComp,fromCompToSurface,position,rotation,anchorPoint,scale,thisLayer,thisComp,mask,valueAtTime,velocityAtTime,scoped_bm_rt,expression_function=eval("[function _expression_function(){"+val+";scoped_bm_rt=$bm_rt}]")[0],numKeys=property.kf?data.k.length:0,active=!this.data||!0!==this.data.hd,wiggle=function(t,e){var i,r,s=this.pv.length?this.pv.length:1,a=createTypedArray("float32",s);var n=Math.floor(5*time);for(i=0,r=0;i<n;){for(r=0;r<s;r+=1)a[r]+=-e+2*e*BMMath.random();i+=1}var o=5*time,h=o-Math.floor(o),l=createTypedArray("float32",s);if(s>1){for(r=0;r<s;r+=1)l[r]=this.pv[r]+a[r]+(-e+2*e*BMMath.random())*h;return l}return this.pv+a[0]+(-e+2*e*BMMath.random())*h}.bind(this);function loopInDuration(t,e){return loopIn(t,e,!0)}function loopOutDuration(t,e){return loopOut(t,e,!0)}thisProperty.loopIn&&(loopIn=thisProperty.loopIn.bind(thisProperty),loop_in=loopIn),thisProperty.loopOut&&(loopOut=thisProperty.loopOut.bind(thisProperty),loop_out=loopOut),thisProperty.smooth&&(smooth=thisProperty.smooth.bind(thisProperty)),this.getValueAtTime&&(valueAtTime=this.getValueAtTime.bind(this)),this.getVelocityAtTime&&(velocityAtTime=this.getVelocityAtTime.bind(this));var comp=elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface),time,velocity,value,text,textIndex,textTotal,selectorValue;function lookAt(t,e){var i=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],r=Math.atan2(i[0],Math.sqrt(i[1]*i[1]+i[2]*i[2]))/degToRads;return[-Math.atan2(i[1],i[2])/degToRads,r,0]}function easeOut(t,e,i,r,s){return applyEase(easeOutBez,t,e,i,r,s)}function easeIn(t,e,i,r,s){return applyEase(easeInBez,t,e,i,r,s)}function ease(t,e,i,r,s){return applyEase(easeInOutBez,t,e,i,r,s)}function applyEase(t,e,i,r,s,a){void 0===s?(s=i,a=r):e=(e-i)/(r-i),e>1?e=1:e<0&&(e=0);var n=t(e);if($bm_isInstanceOfArray(s)){var o,h=s.length,l=createTypedArray("float32",h);for(o=0;o<h;o+=1)l[o]=(a[o]-s[o])*n+s[o];return l}return(a-s)*n+s}function nearestKey(t){var e,i,r,s=data.k.length;if(data.k.length&&"number"!=typeof data.k[0])if(i=-1,(t*=elem.comp.globalData.frameRate)<data.k[0].t)i=1,r=data.k[0].t;else{for(e=0;e<s-1;e+=1){if(t===data.k[e].t){i=e+1,r=data.k[e].t;break}if(t>data.k[e].t&&t<data.k[e+1].t){t-data.k[e].t>data.k[e+1].t-t?(i=e+2,r=data.k[e+1].t):(i=e+1,r=data.k[e].t);break}}-1===i&&(i=e+1,r=data.k[e].t)}else i=0,r=0;var a={};return a.index=i,a.time=r/elem.comp.globalData.frameRate,a}function key(t){var e,i,r;if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]};var s=Object.prototype.hasOwnProperty.call(data.k[t],"s")?data.k[t].s:data.k[t-1].e;for(r=s.length,i=0;i<r;i+=1)e[i]=s[i],e.value[i]=s[i];return e}function framesToTime(t,e){return e||(e=elem.comp.globalData.frameRate),t/e}function timeToFrames(t,e){return t||0===t||(t=time),e||(e=elem.comp.globalData.frameRate),t*e}function seedRandom(t){BMMath.seedrandom(randSeed+t)}function sourceRectAtTime(){return elem.sourceRectAtTime()}function substring(t,e){return"string"==typeof value?void 0===e?value.substring(t):value.substring(t,e):""}function substr(t,e){return"string"==typeof value?void 0===e?value.substr(t):value.substr(t,e):""}function posterizeTime(t){time=0===t?0:Math.floor(time*t)/t,value=valueAtTime(time)}var index=elem.data.ind,hasParent=!(!elem.hierarchy||!elem.hierarchy.length),parent,randSeed=Math.floor(1e6*Math.random()),globalData=elem.globalData;function executeExpression(t){return value=t,this.frameExpressionId===elem.globalData.frameId&&"textSelector"!==this.propType?value:("textSelector"===this.propType&&(textIndex=this.textIndex,textTotal=this.textTotal,selectorValue=this.selectorValue),thisLayer||(text=elem.layerInterface.text,thisLayer=elem.layerInterface,thisComp=elem.comp.compInterface,toWorld=thisLayer.toWorld.bind(thisLayer),fromWorld=thisLayer.fromWorld.bind(thisLayer),fromComp=thisLayer.fromComp.bind(thisLayer),toComp=thisLayer.toComp.bind(thisLayer),mask=thisLayer.mask?thisLayer.mask.bind(thisLayer):null,fromCompToSurface=fromComp),transform||(transform=elem.layerInterface("ADBE Transform Group"),$bm_transform=transform,transform&&(anchorPoint=transform.anchorPoint)),4!==elemType||content||(content=thisLayer("ADBE Root Vectors Group")),effect||(effect=thisLayer(4)),(hasParent=!(!elem.hierarchy||!elem.hierarchy.length))&&!parent&&(parent=elem.hierarchy[0].layerInterface),time=this.comp.renderedFrame/this.comp.globalData.frameRate,_needsRandom&&seedRandom(randSeed+time),needsVelocity&&(velocity=velocityAtTime(time)),expression_function(),this.frameExpressionId=elem.globalData.frameId,scoped_bm_rt=scoped_bm_rt.propType===propTypes.SHAPE?scoped_bm_rt.v:scoped_bm_rt)}return executeExpression.__preventDeadCodeRemoval=[$bm_transform,anchorPoint,time,velocity,inPoint,outPoint,width,height,name,loop_in,loop_out,smooth,toComp,fromCompToSurface,toWorld,fromWorld,mask,position,rotation,scale,thisComp,numKeys,active,wiggle,loopInDuration,loopOutDuration,comp,lookAt,easeOut,easeIn,ease,nearestKey,key,text,textIndex,textTotal,selectorValue,framesToTime,timeToFrames,sourceRectAtTime,substring,substr,posterizeTime,index,globalData],executeExpression}return ob.initiateExpression=initiateExpression,ob.__preventDeadCodeRemoval=[window,document,XMLHttpRequest,fetch,frames,$bm_neg,add,$bm_sum,$bm_sub,$bm_mul,$bm_div,$bm_mod,clamp,radians_to_degrees,degreesToRadians,degrees_to_radians,normalize,rgbToHsl,hslToRgb,linear,random,createPath,_lottieGlobal],ob.resetFrame=resetFrame,ob}(),Expressions=function(){var t={};return t.initExpressions=function(t){var e=0,i=[];t.renderer.compInterface=CompExpressionInterface(t.renderer),t.renderer.globalData.projectInterface.registerComposition(t.renderer),t.renderer.globalData.pushExpression=function(){e+=1},t.renderer.globalData.popExpression=function(){0==(e-=1)&&function(){var t,e=i.length;for(t=0;t<e;t+=1)i[t].release();i.length=0}()},t.renderer.globalData.registerExpressionProperty=function(t){-1===i.indexOf(t)&&i.push(t)}},t.resetFrame=ExpressionManager.resetFrame,t}(),MaskManagerInterface=function(){function t(t,e){this._mask=t,this._data=e}Object.defineProperty(t.prototype,"maskPath",{get:function(){return this._mask.prop.k&&this._mask.prop.getValue(),this._mask.prop}}),Object.defineProperty(t.prototype,"maskOpacity",{get:function(){return this._mask.op.k&&this._mask.op.getValue(),100*this._mask.op.v}});return function(e){var i,r=createSizedArray(e.viewData.length),s=e.viewData.length;for(i=0;i<s;i+=1)r[i]=new t(e.viewData[i],e.masksProperties[i]);return function(t){for(i=0;i<s;){if(e.masksProperties[i].nm===t)return r[i];i+=1}return null}}}(),ExpressionPropertyInterface=function(){var t={pv:0,v:0,mult:1},e={pv:[0,0,0],v:[0,0,0],mult:1};function i(t,e,i){Object.defineProperty(t,"velocity",{get:function(){return e.getVelocityAtTime(e.comp.currentFrame)}}),t.numKeys=e.keyframes?e.keyframes.length:0,t.key=function(r){if(!t.numKeys)return 0;var s="";s="s"in e.keyframes[r-1]?e.keyframes[r-1].s:"e"in e.keyframes[r-2]?e.keyframes[r-2].e:e.keyframes[r-2].s;var a="unidimensional"===i?new Number(s):Object.assign({},s);return a.time=e.keyframes[r-1].t/e.elem.comp.globalData.frameRate,a.value="unidimensional"===i?s[0]:s,a},t.valueAtTime=e.getValueAtTime,t.speedAtTime=e.getSpeedAtTime,t.velocityAtTime=e.getVelocityAtTime,t.propertyGroup=e.propertyGroup}function r(){return t}return function(s){return s?"unidimensional"===s.propType?function(e){e&&"pv"in e||(e=t);var r=1/e.mult,s=e.pv*r,a=new Number(s);return a.value=s,i(a,e,"unidimensional"),function(){return e.k&&e.getValue(),s=e.v*r,a.value!==s&&((a=new Number(s)).value=s,i(a,e,"unidimensional")),a}}(s):function(t){t&&"pv"in t||(t=e);var r=1/t.mult,s=t.data&&t.data.l||t.pv.length,a=createTypedArray("float32",s),n=createTypedArray("float32",s);return a.value=n,i(a,t,"multidimensional"),function(){t.k&&t.getValue();for(var e=0;e<s;e+=1)n[e]=t.v[e]*r,a[e]=n[e];return a}}(s):r}}(),TransformExpressionInterface=function(t){function e(t){switch(t){case"scale":case"Scale":case"ADBE Scale":case 6:return e.scale;case"rotation":case"Rotation":case"ADBE Rotation":case"ADBE Rotate Z":case 10:return e.rotation;case"ADBE Rotate X":return e.xRotation;case"ADBE Rotate Y":return e.yRotation;case"position":case"Position":case"ADBE Position":case 2:return e.position;case"ADBE Position_0":return e.xPosition;case"ADBE Position_1":return e.yPosition;case"ADBE Position_2":return e.zPosition;case"anchorPoint":case"AnchorPoint":case"Anchor Point":case"ADBE AnchorPoint":case 1:return e.anchorPoint;case"opacity":case"Opacity":case 11:return e.opacity;default:return null}}var i,r,s,a;return Object.defineProperty(e,"rotation",{get:ExpressionPropertyInterface(t.r||t.rz)}),Object.defineProperty(e,"zRotation",{get:ExpressionPropertyInterface(t.rz||t.r)}),Object.defineProperty(e,"xRotation",{get:ExpressionPropertyInterface(t.rx)}),Object.defineProperty(e,"yRotation",{get:ExpressionPropertyInterface(t.ry)}),Object.defineProperty(e,"scale",{get:ExpressionPropertyInterface(t.s)}),t.p?a=ExpressionPropertyInterface(t.p):(i=ExpressionPropertyInterface(t.px),r=ExpressionPropertyInterface(t.py),t.pz&&(s=ExpressionPropertyInterface(t.pz))),Object.defineProperty(e,"position",{get:function(){return t.p?a():[i(),r(),s?s():0]}}),Object.defineProperty(e,"xPosition",{get:ExpressionPropertyInterface(t.px)}),Object.defineProperty(e,"yPosition",{get:ExpressionPropertyInterface(t.py)}),Object.defineProperty(e,"zPosition",{get:ExpressionPropertyInterface(t.pz)}),Object.defineProperty(e,"anchorPoint",{get:ExpressionPropertyInterface(t.a)}),Object.defineProperty(e,"opacity",{get:ExpressionPropertyInterface(t.o)}),Object.defineProperty(e,"skew",{get:ExpressionPropertyInterface(t.sk)}),Object.defineProperty(e,"skewAxis",{get:ExpressionPropertyInterface(t.sa)}),Object.defineProperty(e,"orientation",{get:ExpressionPropertyInterface(t.or)}),e},LayerExpressionInterface=function(){function t(t){var e=new Matrix;void 0!==t?this._elem.finalTransform.mProp.getValueAtTime(t).clone(e):this._elem.finalTransform.mProp.applyToMatrix(e);return e}function e(t,e){var i=this.getMatrix(e);return i.props[12]=0,i.props[13]=0,i.props[14]=0,this.applyPoint(i,t)}function i(t,e){var i=this.getMatrix(e);return this.applyPoint(i,t)}function r(t,e){var i=this.getMatrix(e);return i.props[12]=0,i.props[13]=0,i.props[14]=0,this.invertPoint(i,t)}function s(t,e){var i=this.getMatrix(e);return this.invertPoint(i,t)}function a(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(t)}return t.applyToPointArray(e[0],e[1],e[2]||0)}function n(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(t)}return t.inversePoint(e)}function o(t){var e=new Matrix;if(e.reset(),this._elem.finalTransform.mProp.applyToMatrix(e),this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(e);return e.inversePoint(t)}return e.inversePoint(t)}function h(){return[1,1,1,1]}return function(l){var p;function f(t){switch(t){case"ADBE Root Vectors Group":case"Contents":case 2:return f.shapeInterface;case 1:case 6:case"Transform":case"transform":case"ADBE Transform Group":return p;case 4:case"ADBE Effect Parade":case"effects":case"Effects":return f.effect;case"ADBE Text Properties":return f.textInterface;default:return null}}f.getMatrix=t,f.invertPoint=n,f.applyPoint=a,f.toWorld=i,f.toWorldVec=e,f.fromWorld=s,f.fromWorldVec=r,f.toComp=i,f.fromComp=o,f.sampleImage=h,f.sourceRectAtTime=l.sourceRectAtTime.bind(l),f._elem=l;var m=getDescriptor(p=TransformExpressionInterface(l.finalTransform.mProp),"anchorPoint");return Object.defineProperties(f,{hasParent:{get:function(){return l.hierarchy.length}},parent:{get:function(){return l.hierarchy[0].layerInterface}},rotation:getDescriptor(p,"rotation"),scale:getDescriptor(p,"scale"),position:getDescriptor(p,"position"),opacity:getDescriptor(p,"opacity"),anchorPoint:m,anchor_point:m,transform:{get:function(){return p}},active:{get:function(){return l.isInRange}}}),f.startTime=l.data.st,f.index=l.data.ind,f.source=l.data.refId,f.height=0===l.data.ty?l.data.h:100,f.width=0===l.data.ty?l.data.w:100,f.inPoint=l.data.ip/l.comp.globalData.frameRate,f.outPoint=l.data.op/l.comp.globalData.frameRate,f._name=l.data.nm,f.registerMaskInterface=function(t){f.mask=new MaskManagerInterface(t,l)},f.registerEffectsInterface=function(t){f.effect=t},f}}(),propertyGroupFactory=function(t,e){return function(i){return(i=void 0===i?1:i)<=0?t:e(i-1)}},PropertyInterface=function(t,e){var i={_name:t};return function(t){return(t=void 0===t?1:t)<=0?i:e(t-1)}},EffectsExpressionInterface=function(){function t(i,r,s,a){function n(t){for(var e=i.ef,r=0,s=e.length;r<s;){if(t===e[r].nm||t===e[r].mn||t===e[r].ix)return 5===e[r].ty?l[r]:l[r]();r+=1}throw new Error}var o,h=propertyGroupFactory(n,s),l=[],p=i.ef.length;for(o=0;o<p;o+=1)5===i.ef[o].ty?l.push(t(i.ef[o],r.effectElements[o],r.effectElements[o].propertyGroup,a)):l.push(e(r.effectElements[o],i.ef[o].ty,a,h));return"ADBE Color Control"===i.mn&&Object.defineProperty(n,"color",{get:function(){return l[0]()}}),Object.defineProperties(n,{numProperties:{get:function(){return i.np}},_name:{value:i.nm},propertyGroup:{value:h}}),n.enabled=0!==i.en,n.active=n.enabled,n}function e(t,e,i,r){var s=ExpressionPropertyInterface(t.p);return t.p.setGroupProperty&&t.p.setGroupProperty(PropertyInterface("",r)),function(){return 10===e?i.comp.compInterface(t.p.v):s()}}return{createEffectsInterface:function(e,i){if(e.effectsManager){var r,s=[],a=e.data.ef,n=e.effectsManager.effectElements.length;for(r=0;r<n;r+=1)s.push(t(a[r],e.effectsManager.effectElements[r],i,e));var o=e.data.ef||[],h=function(t){for(r=0,n=o.length;r<n;){if(t===o[r].nm||t===o[r].mn||t===o[r].ix)return s[r];r+=1}return null};return Object.defineProperty(h,"numProperties",{get:function(){return o.length}}),h}return null}}}(),ShapePathInterface=function(t,e,i){var r=e.sh;function s(t){return"Shape"===t||"shape"===t||"Path"===t||"path"===t||"ADBE Vector Shape"===t||2===t?s.path:null}var a=propertyGroupFactory(s,i);return r.setGroupProperty(PropertyInterface("Path",a)),Object.defineProperties(s,{path:{get:function(){return r.k&&r.getValue(),r}},shape:{get:function(){return r.k&&r.getValue(),r}},_name:{value:t.nm},ix:{value:t.ix},propertyIndex:{value:t.ix},mn:{value:t.mn},propertyGroup:{value:i}}),s},ShapeExpressionInterface=function(){function t(t,o,c){var u,d=[],y=t?t.length:0;for(u=0;u<y;u+=1)"gr"===t[u].ty?d.push(e(t[u],o[u],c)):"fl"===t[u].ty?d.push(i(t[u],o[u],c)):"st"===t[u].ty?d.push(a(t[u],o[u],c)):"tm"===t[u].ty?d.push(n(t[u],o[u],c)):"tr"===t[u].ty||("el"===t[u].ty?d.push(h(t[u],o[u],c)):"sr"===t[u].ty?d.push(l(t[u],o[u],c)):"sh"===t[u].ty?d.push(ShapePathInterface(t[u],o[u],c)):"rc"===t[u].ty?d.push(p(t[u],o[u],c)):"rd"===t[u].ty?d.push(f(t[u],o[u],c)):"rp"===t[u].ty?d.push(m(t[u],o[u],c)):"gf"===t[u].ty?d.push(r(t[u],o[u],c)):d.push(s(t[u],o[u])));return d}function e(e,i,r){var s=function(t){switch(t){case"ADBE Vectors Group":case"Contents":case 2:return s.content;default:return s.transform}};s.propertyGroup=propertyGroupFactory(s,r);var a=function(e,i,r){var s,a=function(t){for(var e=0,i=s.length;e<i;){if(s[e]._name===t||s[e].mn===t||s[e].propertyIndex===t||s[e].ix===t||s[e].ind===t)return s[e];e+=1}return"number"==typeof t?s[t-1]:null};a.propertyGroup=propertyGroupFactory(a,r),s=t(e.it,i.it,a.propertyGroup),a.numProperties=s.length;var n=o(e.it[e.it.length-1],i.it[i.it.length-1],a.propertyGroup);return a.transform=n,a.propertyIndex=e.cix,a._name=e.nm,a}(e,i,s.propertyGroup),n=o(e.it[e.it.length-1],i.it[i.it.length-1],s.propertyGroup);return s.content=a,s.transform=n,Object.defineProperty(s,"_name",{get:function(){return e.nm}}),s.numProperties=e.np,s.propertyIndex=e.ix,s.nm=e.nm,s.mn=e.mn,s}function i(t,e,i){function r(t){return"Color"===t||"color"===t?r.color:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r}function r(t,e,i){function r(t){return"Start Point"===t||"start point"===t?r.startPoint:"End Point"===t||"end point"===t?r.endPoint:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{startPoint:{get:ExpressionPropertyInterface(e.s)},endPoint:{get:ExpressionPropertyInterface(e.e)},opacity:{get:ExpressionPropertyInterface(e.o)},type:{get:function(){return"a"}},_name:{value:t.nm},mn:{value:t.mn}}),e.s.setGroupProperty(PropertyInterface("Start Point",i)),e.e.setGroupProperty(PropertyInterface("End Point",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r}function s(){return function(){return null}}function a(t,e,i){var r,s=propertyGroupFactory(l,i),a=propertyGroupFactory(h,s);function n(i){Object.defineProperty(h,t.d[i].nm,{get:ExpressionPropertyInterface(e.d.dataProps[i].p)})}var o=t.d?t.d.length:0,h={};for(r=0;r<o;r+=1)n(r),e.d.dataProps[r].p.setGroupProperty(a);function l(t){return"Color"===t||"color"===t?l.color:"Opacity"===t||"opacity"===t?l.opacity:"Stroke Width"===t||"stroke width"===t?l.strokeWidth:null}return Object.defineProperties(l,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},strokeWidth:{get:ExpressionPropertyInterface(e.w)},dash:{get:function(){return h}},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",s)),e.o.setGroupProperty(PropertyInterface("Opacity",s)),e.w.setGroupProperty(PropertyInterface("Stroke Width",s)),l}function n(t,e,i){function r(e){return e===t.e.ix||"End"===e||"end"===e?r.end:e===t.s.ix?r.start:e===t.o.ix?r.offset:null}var s=propertyGroupFactory(r,i);return r.propertyIndex=t.ix,e.s.setGroupProperty(PropertyInterface("Start",s)),e.e.setGroupProperty(PropertyInterface("End",s)),e.o.setGroupProperty(PropertyInterface("Offset",s)),r.propertyIndex=t.ix,r.propertyGroup=i,Object.defineProperties(r,{start:{get:ExpressionPropertyInterface(e.s)},end:{get:ExpressionPropertyInterface(e.e)},offset:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm}}),r.mn=t.mn,r}function o(t,e,i){function r(e){return t.a.ix===e||"Anchor Point"===e?r.anchorPoint:t.o.ix===e||"Opacity"===e?r.opacity:t.p.ix===e||"Position"===e?r.position:t.r.ix===e||"Rotation"===e||"ADBE Vector Rotation"===e?r.rotation:t.s.ix===e||"Scale"===e?r.scale:t.sk&&t.sk.ix===e||"Skew"===e?r.skew:t.sa&&t.sa.ix===e||"Skew Axis"===e?r.skewAxis:null}var s=propertyGroupFactory(r,i);return e.transform.mProps.o.setGroupProperty(PropertyInterface("Opacity",s)),e.transform.mProps.p.setGroupProperty(PropertyInterface("Position",s)),e.transform.mProps.a.setGroupProperty(PropertyInterface("Anchor Point",s)),e.transform.mProps.s.setGroupProperty(PropertyInterface("Scale",s)),e.transform.mProps.r.setGroupProperty(PropertyInterface("Rotation",s)),e.transform.mProps.sk&&(e.transform.mProps.sk.setGroupProperty(PropertyInterface("Skew",s)),e.transform.mProps.sa.setGroupProperty(PropertyInterface("Skew Angle",s))),e.transform.op.setGroupProperty(PropertyInterface("Opacity",s)),Object.defineProperties(r,{opacity:{get:ExpressionPropertyInterface(e.transform.mProps.o)},position:{get:ExpressionPropertyInterface(e.transform.mProps.p)},anchorPoint:{get:ExpressionPropertyInterface(e.transform.mProps.a)},scale:{get:ExpressionPropertyInterface(e.transform.mProps.s)},rotation:{get:ExpressionPropertyInterface(e.transform.mProps.r)},skew:{get:ExpressionPropertyInterface(e.transform.mProps.sk)},skewAxis:{get:ExpressionPropertyInterface(e.transform.mProps.sa)},_name:{value:t.nm}}),r.ty="tr",r.mn=t.mn,r.propertyGroup=i,r}function h(t,e,i){function r(e){return t.p.ix===e?r.position:t.s.ix===e?r.size:null}var s=propertyGroupFactory(r,i);r.propertyIndex=t.ix;var a="tm"===e.sh.ty?e.sh.prop:e.sh;return a.s.setGroupProperty(PropertyInterface("Size",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),Object.defineProperties(r,{size:{get:ExpressionPropertyInterface(a.s)},position:{get:ExpressionPropertyInterface(a.p)},_name:{value:t.nm}}),r.mn=t.mn,r}function l(t,e,i){function r(e){return t.p.ix===e?r.position:t.r.ix===e?r.rotation:t.pt.ix===e?r.points:t.or.ix===e||"ADBE Vector Star Outer Radius"===e?r.outerRadius:t.os.ix===e?r.outerRoundness:!t.ir||t.ir.ix!==e&&"ADBE Vector Star Inner Radius"!==e?t.is&&t.is.ix===e?r.innerRoundness:null:r.innerRadius}var s=propertyGroupFactory(r,i),a="tm"===e.sh.ty?e.sh.prop:e.sh;return r.propertyIndex=t.ix,a.or.setGroupProperty(PropertyInterface("Outer Radius",s)),a.os.setGroupProperty(PropertyInterface("Outer Roundness",s)),a.pt.setGroupProperty(PropertyInterface("Points",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),t.ir&&(a.ir.setGroupProperty(PropertyInterface("Inner Radius",s)),a.is.setGroupProperty(PropertyInterface("Inner Roundness",s))),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(a.p)},rotation:{get:ExpressionPropertyInterface(a.r)},points:{get:ExpressionPropertyInterface(a.pt)},outerRadius:{get:ExpressionPropertyInterface(a.or)},outerRoundness:{get:ExpressionPropertyInterface(a.os)},innerRadius:{get:ExpressionPropertyInterface(a.ir)},innerRoundness:{get:ExpressionPropertyInterface(a.is)},_name:{value:t.nm}}),r.mn=t.mn,r}function p(t,e,i){function r(e){return t.p.ix===e?r.position:t.r.ix===e?r.roundness:t.s.ix===e||"Size"===e||"ADBE Vector Rect Size"===e?r.size:null}var s=propertyGroupFactory(r,i),a="tm"===e.sh.ty?e.sh.prop:e.sh;return r.propertyIndex=t.ix,a.p.setGroupProperty(PropertyInterface("Position",s)),a.s.setGroupProperty(PropertyInterface("Size",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(a.p)},roundness:{get:ExpressionPropertyInterface(a.r)},size:{get:ExpressionPropertyInterface(a.s)},_name:{value:t.nm}}),r.mn=t.mn,r}function f(t,e,i){function r(e){return t.r.ix===e||"Round Corners 1"===e?r.radius:null}var s=propertyGroupFactory(r,i),a=e;return r.propertyIndex=t.ix,a.rd.setGroupProperty(PropertyInterface("Radius",s)),Object.defineProperties(r,{radius:{get:ExpressionPropertyInterface(a.rd)},_name:{value:t.nm}}),r.mn=t.mn,r}function m(t,e,i){function r(e){return t.c.ix===e||"Copies"===e?r.copies:t.o.ix===e||"Offset"===e?r.offset:null}var s=propertyGroupFactory(r,i),a=e;return r.propertyIndex=t.ix,a.c.setGroupProperty(PropertyInterface("Copies",s)),a.o.setGroupProperty(PropertyInterface("Offset",s)),Object.defineProperties(r,{copies:{get:ExpressionPropertyInterface(a.c)},offset:{get:ExpressionPropertyInterface(a.o)},_name:{value:t.nm}}),r.mn=t.mn,r}return function(e,i,r){var s;function a(t){if("number"==typeof t)return 0===(t=void 0===t?1:t)?r:s[t-1];for(var e=0,i=s.length;e<i;){if(s[e]._name===t)return s[e];e+=1}return null}return a.propertyGroup=propertyGroupFactory(a,(function(){return r})),s=t(e,i,a.propertyGroup),a.numProperties=s.length,a._name="Contents",a}}(),TextExpressionInterface=function(t){var e;function i(t){return"ADBE Text Document"===t?i.sourceText:null}return Object.defineProperty(i,"sourceText",{get:function(){t.textProperty.getValue();var i=t.textProperty.currentData.t;return e&&i===e.value||((e=new String(i)).value=i||new String(i),Object.defineProperty(e,"style",{get:function(){return{fillColor:t.textProperty.currentData.fc}}})),e}}),i};function _typeof(t){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof(t)}var FootageInterface=(dataInterfaceFactory=function(t){function e(t){return"Outline"===t?e.outlineInterface():null}return e._name="Outline",e.outlineInterface=function(t){var e="",i=t.getFootageData();function r(t){if(i[t])return e=t,"object"===_typeof(i=i[t])?r:i;var s=t.indexOf(e);if(-1!==s){var a=parseInt(t.substr(s+e.length),10);return"object"===_typeof(i=i[a])?r:i}return""}return function(){return e="",i=t.getFootageData(),r}}(t),e},function(t){function e(t){return"Data"===t?e.dataInterface:null}return e._name="Data",e.dataInterface=dataInterfaceFactory(t),e}),dataInterfaceFactory,interfaces={layer:LayerExpressionInterface,effects:EffectsExpressionInterface,comp:CompExpressionInterface,shape:ShapeExpressionInterface,text:TextExpressionInterface,footage:FootageInterface};function getInterface(t){return interfaces[t]||null}var expressionHelpers={searchExpressions:function(t,e,i){e.x&&(i.k=!0,i.x=!0,i.initiateExpression=ExpressionManager.initiateExpression,i.effectsSequence.push(i.initiateExpression(t,e,i).bind(i)))},getSpeedAtTime:function(t){var e=this.getValueAtTime(t),i=this.getValueAtTime(t+-.01),r=0;if(e.length){var s;for(s=0;s<e.length;s+=1)r+=Math.pow(i[s]-e[s],2);r=100*Math.sqrt(r)}else r=0;return r},getVelocityAtTime:function(t){if(void 0!==this.vel)return this.vel;var e,i,r=-.001,s=this.getValueAtTime(t),a=this.getValueAtTime(t+r);if(s.length)for(e=createTypedArray("float32",s.length),i=0;i<s.length;i+=1)e[i]=(a[i]-s[i])/r;else e=(a-s)/r;return e},getValueAtTime:function(t){return t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastFrame&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastFrame<t?this._cachingAtTime.lastIndex:0,this._cachingAtTime.value=this.interpolateValue(t,this._cachingAtTime),this._cachingAtTime.lastFrame=t),this._cachingAtTime.value},getStaticValueAtTime:function(){return this.pv},setGroupProperty:function(t){this.propertyGroup=t}};function addPropertyDecorator(){function t(t,e,i){if(!this.k||!this.keyframes)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[l.length-1].t;if(h<=p)return this.pv;if(i?s=p-(r=e?Math.abs(p-this.elem.comp.globalData.frameRate*e):Math.max(0,p-this.elem.data.ip)):((!e||e>l.length-1)&&(e=l.length-1),r=p-(s=l[l.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/r)%2!=0)return this.getValueAtTime((r-(h-s)%r+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),m=this.getValueAtTime(p/this.comp.globalData.frameRate,0),c=this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0),u=Math.floor((h-s)/r);if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=(m[a]-f[a])*u+c[a];return o}return(m-f)*u+c}if("continue"===t){var d=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p-.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(d.length)).length,a=0;a<n;a+=1)o[a]=d[a]+(d[a]-y[a])*((h-p)/this.comp.globalData.frameRate)/5e-4;return o}return d+(h-p)/.001*(d-y)}}return this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0)}function e(t,e,i){if(!this.k)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[0].t;if(h>=p)return this.pv;if(i?s=p+(r=e?Math.abs(this.elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-p)):((!e||e>l.length-1)&&(e=l.length-1),r=(s=l[e].t)-p),"pingpong"===t){if(Math.floor((p-h)/r)%2==0)return this.getValueAtTime(((p-h)%r+p)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(p/this.comp.globalData.frameRate,0),m=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime((r-(p-h)%r+p)/this.comp.globalData.frameRate,0),u=Math.floor((p-h)/r)+1;if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=c[a]-(m[a]-f[a])*u;return o}return c-(m-f)*u}if("continue"===t){var d=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p+.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(d.length)).length,a=0;a<n;a+=1)o[a]=d[a]+(d[a]-y[a])*(p-h)/.001;return o}return d+(d-y)*(p-h)/.001}}return this.getValueAtTime((r-((p-h)%r+p))/this.comp.globalData.frameRate,0)}function i(t,e){if(!this.k)return this.pv;if(t=.5*(t||.4),(e=Math.floor(e||5))<=1)return this.pv;var i,r,s=this.comp.renderedFrame/this.comp.globalData.frameRate,a=s-t,n=e>1?(s+t-a)/(e-1):1,o=0,h=0;for(i=this.pv.length?createTypedArray("float32",this.pv.length):0;o<e;){if(r=this.getValueAtTime(a+o*n),this.pv.length)for(h=0;h<this.pv.length;h+=1)i[h]+=r[h];else i+=r;o+=1}if(this.pv.length)for(h=0;h<this.pv.length;h+=1)i[h]/=e;else i/=e;return i}function r(t){this._transformCachingAtTime||(this._transformCachingAtTime={v:new Matrix});var e=this._transformCachingAtTime.v;if(e.cloneFromProps(this.pre.props),this.appliedTransformations<1){var i=this.a.getValueAtTime(t);e.translate(-i[0]*this.a.mult,-i[1]*this.a.mult,i[2]*this.a.mult)}if(this.appliedTransformations<2){var r=this.s.getValueAtTime(t);e.scale(r[0]*this.s.mult,r[1]*this.s.mult,r[2]*this.s.mult)}if(this.sk&&this.appliedTransformations<3){var s=this.sk.getValueAtTime(t),a=this.sa.getValueAtTime(t);e.skewFromAxis(-s*this.sk.mult,a*this.sa.mult)}if(this.r&&this.appliedTransformations<4){var n=this.r.getValueAtTime(t);e.rotate(-n*this.r.mult)}else if(!this.r&&this.appliedTransformations<4){var o=this.rz.getValueAtTime(t),h=this.ry.getValueAtTime(t),l=this.rx.getValueAtTime(t),p=this.or.getValueAtTime(t);e.rotateZ(-o*this.rz.mult).rotateY(h*this.ry.mult).rotateX(l*this.rx.mult).rotateZ(-p[2]*this.or.mult).rotateY(p[1]*this.or.mult).rotateX(p[0]*this.or.mult)}if(this.data.p&&this.data.p.s){var f=this.px.getValueAtTime(t),m=this.py.getValueAtTime(t);if(this.data.p.z){var c=this.pz.getValueAtTime(t);e.translate(f*this.px.mult,m*this.py.mult,-c*this.pz.mult)}else e.translate(f*this.px.mult,m*this.py.mult,0)}else{var u=this.p.getValueAtTime(t);e.translate(u[0]*this.p.mult,u[1]*this.p.mult,-u[2]*this.p.mult)}return e}function s(){return this.v.clone(new Matrix)}var a=TransformPropertyFactory.getTransformProperty;TransformPropertyFactory.getTransformProperty=function(t,e,i){var n=a(t,e,i);return n.dynamicProperties.length?n.getValueAtTime=r.bind(n):n.getValueAtTime=s.bind(n),n.setGroupProperty=expressionHelpers.setGroupProperty,n};var n=PropertyFactory.getProp;PropertyFactory.getProp=function(r,s,a,o,h){var l=n(r,s,a,o,h);l.kf?l.getValueAtTime=expressionHelpers.getValueAtTime.bind(l):l.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(l),l.setGroupProperty=expressionHelpers.setGroupProperty,l.loopOut=t,l.loopIn=e,l.smooth=i,l.getVelocityAtTime=expressionHelpers.getVelocityAtTime.bind(l),l.getSpeedAtTime=expressionHelpers.getSpeedAtTime.bind(l),l.numKeys=1===s.a?s.k.length:0,l.propertyIndex=s.ix;var p=0;return 0!==a&&(p=createTypedArray("float32",1===s.a?s.k[0].s.length:s.k.length)),l._cachingAtTime={lastFrame:initialDefaultFrame,lastIndex:0,value:p},expressionHelpers.searchExpressions(r,s,l),l.k&&h.addDynamicProperty(l),l};var o=ShapePropertyFactory.getConstructorFunction(),h=ShapePropertyFactory.getKeyframedConstructorFunction();function l(){}l.prototype={vertices:function(t,e){this.k&&this.getValue();var i,r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0));var s=r._length,a=r[t],n=r.v,o=createSizedArray(s);for(i=0;i<s;i+=1)o[i]="i"===t||"o"===t?[a[i][0]-n[i][0],a[i][1]-n[i][1]]:[a[i][0],a[i][1]];return o},points:function(t){return this.vertices("v",t)},inTangents:function(t){return this.vertices("i",t)},outTangents:function(t){return this.vertices("o",t)},isClosed:function(){return this.v.c},pointOnPath:function(t,e){var i=this.v;void 0!==e&&(i=this.getValueAtTime(e,0)),this._segmentsLength||(this._segmentsLength=bez.getSegmentsLength(i));for(var r,s=this._segmentsLength,a=s.lengths,n=s.totalLength*t,o=0,h=a.length,l=0;o<h;){if(l+a[o].addedLength>n){var p=o,f=i.c&&o===h-1?0:o+1,m=(n-l)/a[o].addedLength;r=bez.getPointInSegment(i.v[p],i.v[f],i.o[p],i.i[f],m,a[o]);break}l+=a[o].addedLength,o+=1}return r||(r=i.c?[i.v[0][0],i.v[0][1]]:[i.v[i._length-1][0],i.v[i._length-1][1]]),r},vectorOnPath:function(t,e,i){1==t?t=this.v.c:0==t&&(t=.999);var r=this.pointOnPath(t,e),s=this.pointOnPath(t+.001,e),a=s[0]-r[0],n=s[1]-r[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return 0===o?[0,0]:"tangent"===i?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([l],o),extendPrototype([l],h),h.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shapePool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime<t?this._caching.lastIndex:0,this._cachingAtTime.lastTime=t,this.interpolateShape(t,this._cachingAtTime.shapeValue,this._cachingAtTime)),this._cachingAtTime.shapeValue},h.prototype.initiateExpression=ExpressionManager.initiateExpression;var p=ShapePropertyFactory.getShapeProp;ShapePropertyFactory.getShapeProp=function(t,e,i,r,s){var a=p(t,e,i,r,s);return a.propertyIndex=e.ix,a.lock=!1,3===i?expressionHelpers.searchExpressions(t,e.pt,a):4===i&&expressionHelpers.searchExpressions(t,e.ks,a),a.k&&t.addDynamicProperty(a),a}}function initialize$1(){addPropertyDecorator()}function addDecorator(){TextProperty.prototype.getExpressionValue=function(t,e){var i=this.calculateExpression(e);if(t.t!==i){var r={};return this.copyData(r,t),r.t=i.toString(),r.__complete=!1,r}return t},TextProperty.prototype.searchProperty=function(){var t=this.searchKeyframes(),e=this.searchExpressions();return this.kf=t||e,this.kf},TextProperty.prototype.searchExpressions=function(){return this.data.d.x?(this.calculateExpression=ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this),this.addEffect(this.getExpressionValue.bind(this)),!0):null}}function initialize(){addDecorator()}function SVGComposableEffect(){}SVGComposableEffect.prototype={createMergeNode:function(t,e){var i,r,s=createNS("feMerge");for(s.setAttribute("result",t),r=0;r<e.length;r+=1)(i=createNS("feMergeNode")).setAttribute("in",e[r]),s.appendChild(i),s.appendChild(i);return s}};var linearFilterValue="0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0";function SVGTintFilter(t,e,i,r,s){this.filterManager=e;var a=createNS("feColorMatrix");a.setAttribute("type","matrix"),a.setAttribute("color-interpolation-filters","linearRGB"),a.setAttribute("values",linearFilterValue+" 1 0"),this.linearFilter=a,a.setAttribute("result",r+"_tint_1"),t.appendChild(a),(a=createNS("feColorMatrix")).setAttribute("type","matrix"),a.setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),a.setAttribute("result",r+"_tint_2"),t.appendChild(a),this.matrixFilter=a;var n=this.createMergeNode(r,[s,r+"_tint_1",r+"_tint_2"]);t.appendChild(n)}function SVGFillFilter(t,e,i,r){this.filterManager=e;var s=createNS("feColorMatrix");s.setAttribute("type","matrix"),s.setAttribute("color-interpolation-filters","sRGB"),s.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),s.setAttribute("result",r),t.appendChild(s),this.matrixFilter=s}function SVGStrokeEffect(t,e,i){this.initialized=!1,this.filterManager=e,this.elem=i,this.paths=[]}function SVGTritoneFilter(t,e,i,r){this.filterManager=e;var s=createNS("feColorMatrix");s.setAttribute("type","matrix"),s.setAttribute("color-interpolation-filters","linearRGB"),s.setAttribute("values","0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0"),t.appendChild(s);var a=createNS("feComponentTransfer");a.setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("result",r),this.matrixFilter=a;var n=createNS("feFuncR");n.setAttribute("type","table"),a.appendChild(n),this.feFuncR=n;var o=createNS("feFuncG");o.setAttribute("type","table"),a.appendChild(o),this.feFuncG=o;var h=createNS("feFuncB");h.setAttribute("type","table"),a.appendChild(h),this.feFuncB=h,t.appendChild(a)}function SVGProLevelsFilter(t,e,i,r){this.filterManager=e;var s=this.filterManager.effectElements,a=createNS("feComponentTransfer");(s[10].p.k||0!==s[10].p.v||s[11].p.k||1!==s[11].p.v||s[12].p.k||1!==s[12].p.v||s[13].p.k||0!==s[13].p.v||s[14].p.k||1!==s[14].p.v)&&(this.feFuncR=this.createFeFunc("feFuncR",a)),(s[17].p.k||0!==s[17].p.v||s[18].p.k||1!==s[18].p.v||s[19].p.k||1!==s[19].p.v||s[20].p.k||0!==s[20].p.v||s[21].p.k||1!==s[21].p.v)&&(this.feFuncG=this.createFeFunc("feFuncG",a)),(s[24].p.k||0!==s[24].p.v||s[25].p.k||1!==s[25].p.v||s[26].p.k||1!==s[26].p.v||s[27].p.k||0!==s[27].p.v||s[28].p.k||1!==s[28].p.v)&&(this.feFuncB=this.createFeFunc("feFuncB",a)),(s[31].p.k||0!==s[31].p.v||s[32].p.k||1!==s[32].p.v||s[33].p.k||1!==s[33].p.v||s[34].p.k||0!==s[34].p.v||s[35].p.k||1!==s[35].p.v)&&(this.feFuncA=this.createFeFunc("feFuncA",a)),(this.feFuncR||this.feFuncG||this.feFuncB||this.feFuncA)&&(a.setAttribute("color-interpolation-filters","sRGB"),t.appendChild(a)),(s[3].p.k||0!==s[3].p.v||s[4].p.k||1!==s[4].p.v||s[5].p.k||1!==s[5].p.v||s[6].p.k||0!==s[6].p.v||s[7].p.k||1!==s[7].p.v)&&((a=createNS("feComponentTransfer")).setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("result",r),t.appendChild(a),this.feFuncRComposed=this.createFeFunc("feFuncR",a),this.feFuncGComposed=this.createFeFunc("feFuncG",a),this.feFuncBComposed=this.createFeFunc("feFuncB",a))}function SVGDropShadowEffect(t,e,i,r,s){var a=e.container.globalData.renderConfig.filterSize,n=e.data.fs||a;t.setAttribute("x",n.x||a.x),t.setAttribute("y",n.y||a.y),t.setAttribute("width",n.width||a.width),t.setAttribute("height",n.height||a.height),this.filterManager=e;var o=createNS("feGaussianBlur");o.setAttribute("in","SourceAlpha"),o.setAttribute("result",r+"_drop_shadow_1"),o.setAttribute("stdDeviation","0"),this.feGaussianBlur=o,t.appendChild(o);var h=createNS("feOffset");h.setAttribute("dx","25"),h.setAttribute("dy","0"),h.setAttribute("in",r+"_drop_shadow_1"),h.setAttribute("result",r+"_drop_shadow_2"),this.feOffset=h,t.appendChild(h);var l=createNS("feFlood");l.setAttribute("flood-color","#00ff00"),l.setAttribute("flood-opacity","1"),l.setAttribute("result",r+"_drop_shadow_3"),this.feFlood=l,t.appendChild(l);var p=createNS("feComposite");p.setAttribute("in",r+"_drop_shadow_3"),p.setAttribute("in2",r+"_drop_shadow_2"),p.setAttribute("operator","in"),p.setAttribute("result",r+"_drop_shadow_4"),t.appendChild(p);var f=this.createMergeNode(r,[r+"_drop_shadow_4",s]);t.appendChild(f)}extendPrototype([SVGComposableEffect],SVGTintFilter),SVGTintFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=this.filterManager.effectElements[2].p.v/100;this.linearFilter.setAttribute("values",linearFilterValue+" "+r+" 0"),this.matrixFilter.setAttribute("values",i[0]-e[0]+" 0 0 0 "+e[0]+" "+(i[1]-e[1])+" 0 0 0 "+e[1]+" "+(i[2]-e[2])+" 0 0 0 "+e[2]+" 0 0 0 1 0")}},SVGFillFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[2].p.v,i=this.filterManager.effectElements[6].p.v;this.matrixFilter.setAttribute("values","0 0 0 0 "+e[0]+" 0 0 0 0 "+e[1]+" 0 0 0 0 "+e[2]+" 0 0 0 "+i+" 0")}},SVGStrokeEffect.prototype.initialize=function(){var t,e,i,r,s=this.elem.layerElement.children||this.elem.layerElement.childNodes;for(1===this.filterManager.effectElements[1].p.v?(r=this.elem.maskManager.masksProperties.length,i=0):r=(i=this.filterManager.effectElements[0].p.v-1)+1,(e=createNS("g")).setAttribute("fill","none"),e.setAttribute("stroke-linecap","round"),e.setAttribute("stroke-dashoffset",1);i<r;i+=1)t=createNS("path"),e.appendChild(t),this.paths.push({p:t,m:i});if(3===this.filterManager.effectElements[10].p.v){var a=createNS("mask"),n=createElementID();a.setAttribute("id",n),a.setAttribute("mask-type","alpha"),a.appendChild(e),this.elem.globalData.defs.appendChild(a);var o=createNS("g");for(o.setAttribute("mask","url("+getLocationHref()+"#"+n+")");s[0];)o.appendChild(s[0]);this.elem.layerElement.appendChild(o),this.masker=a,e.setAttribute("stroke","#fff")}else if(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v){if(2===this.filterManager.effectElements[10].p.v)for(s=this.elem.layerElement.children||this.elem.layerElement.childNodes;s.length;)this.elem.layerElement.removeChild(s[0]);this.elem.layerElement.appendChild(e),this.elem.layerElement.removeAttribute("mask"),e.setAttribute("stroke","#fff")}this.initialized=!0,this.pathMasker=e},SVGStrokeEffect.prototype.renderFrame=function(t){var e;this.initialized||this.initialize();var i,r,s=this.paths.length;for(e=0;e<s;e+=1)if(-1!==this.paths[e].m&&(i=this.elem.maskManager.viewData[this.paths[e].m],r=this.paths[e].p,(t||this.filterManager._mdf||i.prop._mdf)&&r.setAttribute("d",i.lastPath),t||this.filterManager.effectElements[9].p._mdf||this.filterManager.effectElements[4].p._mdf||this.filterManager.effectElements[7].p._mdf||this.filterManager.effectElements[8].p._mdf||i.prop._mdf)){var a;if(0!==this.filterManager.effectElements[7].p.v||100!==this.filterManager.effectElements[8].p.v){var n=.01*Math.min(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),o=.01*Math.max(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),h=r.getTotalLength();a="0 0 0 "+h*n+" ";var l,p=h*(o-n),f=1+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01,m=Math.floor(p/f);for(l=0;l<m;l+=1)a+="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01+" ";a+="0 "+10*h+" 0 0"}else a="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01;r.setAttribute("stroke-dasharray",a)}if((t||this.filterManager.effectElements[4].p._mdf)&&this.pathMasker.setAttribute("stroke-width",2*this.filterManager.effectElements[4].p.v),(t||this.filterManager.effectElements[6].p._mdf)&&this.pathMasker.setAttribute("opacity",this.filterManager.effectElements[6].p.v),(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v)&&(t||this.filterManager.effectElements[3].p._mdf)){var c=this.filterManager.effectElements[3].p.v;this.pathMasker.setAttribute("stroke","rgb("+bmFloor(255*c[0])+","+bmFloor(255*c[1])+","+bmFloor(255*c[2])+")")}},SVGTritoneFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=this.filterManager.effectElements[2].p.v,s=r[0]+" "+i[0]+" "+e[0],a=r[1]+" "+i[1]+" "+e[1],n=r[2]+" "+i[2]+" "+e[2];this.feFuncR.setAttribute("tableValues",s),this.feFuncG.setAttribute("tableValues",a),this.feFuncB.setAttribute("tableValues",n)}},SVGProLevelsFilter.prototype.createFeFunc=function(t,e){var i=createNS(t);return i.setAttribute("type","table"),e.appendChild(i),i},SVGProLevelsFilter.prototype.getTableValue=function(t,e,i,r,s){for(var a,n,o=0,h=Math.min(t,e),l=Math.max(t,e),p=Array.call(null,{length:256}),f=0,m=s-r,c=e-t;o<=256;)n=(a=o/256)<=h?c<0?s:r:a>=l?c<0?r:s:r+m*Math.pow((a-t)/c,1/i),p[f]=n,f+=1,o+=256/255;return p.join(" ")},SVGProLevelsFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e,i=this.filterManager.effectElements;this.feFuncRComposed&&(t||i[3].p._mdf||i[4].p._mdf||i[5].p._mdf||i[6].p._mdf||i[7].p._mdf)&&(e=this.getTableValue(i[3].p.v,i[4].p.v,i[5].p.v,i[6].p.v,i[7].p.v),this.feFuncRComposed.setAttribute("tableValues",e),this.feFuncGComposed.setAttribute("tableValues",e),this.feFuncBComposed.setAttribute("tableValues",e)),this.feFuncR&&(t||i[10].p._mdf||i[11].p._mdf||i[12].p._mdf||i[13].p._mdf||i[14].p._mdf)&&(e=this.getTableValue(i[10].p.v,i[11].p.v,i[12].p.v,i[13].p.v,i[14].p.v),this.feFuncR.setAttribute("tableValues",e)),this.feFuncG&&(t||i[17].p._mdf||i[18].p._mdf||i[19].p._mdf||i[20].p._mdf||i[21].p._mdf)&&(e=this.getTableValue(i[17].p.v,i[18].p.v,i[19].p.v,i[20].p.v,i[21].p.v),this.feFuncG.setAttribute("tableValues",e)),this.feFuncB&&(t||i[24].p._mdf||i[25].p._mdf||i[26].p._mdf||i[27].p._mdf||i[28].p._mdf)&&(e=this.getTableValue(i[24].p.v,i[25].p.v,i[26].p.v,i[27].p.v,i[28].p.v),this.feFuncB.setAttribute("tableValues",e)),this.feFuncA&&(t||i[31].p._mdf||i[32].p._mdf||i[33].p._mdf||i[34].p._mdf||i[35].p._mdf)&&(e=this.getTableValue(i[31].p.v,i[32].p.v,i[33].p.v,i[34].p.v,i[35].p.v),this.feFuncA.setAttribute("tableValues",e))}},extendPrototype([SVGComposableEffect],SVGDropShadowEffect),SVGDropShadowEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){if((t||this.filterManager.effectElements[4].p._mdf)&&this.feGaussianBlur.setAttribute("stdDeviation",this.filterManager.effectElements[4].p.v/4),t||this.filterManager.effectElements[0].p._mdf){var e=this.filterManager.effectElements[0].p.v;this.feFlood.setAttribute("flood-color",rgbToHex(Math.round(255*e[0]),Math.round(255*e[1]),Math.round(255*e[2])))}if((t||this.filterManager.effectElements[1].p._mdf)&&this.feFlood.setAttribute("flood-opacity",this.filterManager.effectElements[1].p.v/255),t||this.filterManager.effectElements[2].p._mdf||this.filterManager.effectElements[3].p._mdf){var i=this.filterManager.effectElements[3].p.v,r=(this.filterManager.effectElements[2].p.v-90)*degToRads,s=i*Math.cos(r),a=i*Math.sin(r);this.feOffset.setAttribute("dx",s),this.feOffset.setAttribute("dy",a)}}};var _svgMatteSymbols=[];function SVGMatte3Effect(t,e,i){this.initialized=!1,this.filterManager=e,this.filterElem=t,this.elem=i,i.matteElement=createNS("g"),i.matteElement.appendChild(i.layerElement),i.matteElement.appendChild(i.transformedElement),i.baseElement=i.matteElement}function SVGGaussianBlurEffect(t,e,i,r){t.setAttribute("x","-100%"),t.setAttribute("y","-100%"),t.setAttribute("width","300%"),t.setAttribute("height","300%"),this.filterManager=e;var s=createNS("feGaussianBlur");s.setAttribute("result",r),t.appendChild(s),this.feGaussianBlur=s}function TransformEffect(){}function SVGTransformEffect(t,e){this.init(e)}return SVGMatte3Effect.prototype.findSymbol=function(t){for(var e=0,i=_svgMatteSymbols.length;e<i;){if(_svgMatteSymbols[e]===t)return _svgMatteSymbols[e];e+=1}return null},SVGMatte3Effect.prototype.replaceInParent=function(t,e){var i=t.layerElement.parentNode;if(i){for(var r,s=i.children,a=0,n=s.length;a<n&&s[a]!==t.layerElement;)a+=1;a<=n-2&&(r=s[a+1]);var o=createNS("use");o.setAttribute("href","#"+e),r?i.insertBefore(o,r):i.appendChild(o)}},SVGMatte3Effect.prototype.setElementAsMask=function(t,e){if(!this.findSymbol(e)){var i=createElementID(),r=createNS("mask");r.setAttribute("id",e.layerId),r.setAttribute("mask-type","alpha"),_svgMatteSymbols.push(e);var s=t.globalData.defs;s.appendChild(r);var a=createNS("symbol");a.setAttribute("id",i),this.replaceInParent(e,i),a.appendChild(e.layerElement),s.appendChild(a);var n=createNS("use");n.setAttribute("href","#"+i),r.appendChild(n),e.data.hd=!1,e.show()}t.setMatte(e.layerId)},SVGMatte3Effect.prototype.initialize=function(){for(var t=this.filterManager.effectElements[0].p.v,e=this.elem.comp.elements,i=0,r=e.length;i<r;)e[i]&&e[i].data.ind===t&&this.setElementAsMask(this.elem,e[i]),i+=1;this.initialized=!0},SVGMatte3Effect.prototype.renderFrame=function(){this.initialized||this.initialize()},SVGGaussianBlurEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=.3*this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=3==i?0:e,s=2==i?0:e;this.feGaussianBlur.setAttribute("stdDeviation",r+" "+s);var a=1==this.filterManager.effectElements[2].p.v?"wrap":"duplicate";this.feGaussianBlur.setAttribute("edgeMode",a)}},TransformEffect.prototype.init=function(t){this.effectsManager=t,this.type=effectTypes.TRANSFORM_EFFECT,this.matrix=new Matrix,this.opacity=-1,this._mdf=!1,this._opMdf=!1},TransformEffect.prototype.renderFrame=function(t){if(this._opMdf=!1,this._mdf=!1,t||this.effectsManager._mdf){var e=this.effectsManager.effectElements,i=e[0].p.v,r=e[1].p.v,s=1===e[2].p.v,a=e[3].p.v,n=s?a:e[4].p.v,o=e[5].p.v,h=e[6].p.v,l=e[7].p.v;this.matrix.reset(),this.matrix.translate(-i[0],-i[1],i[2]),this.matrix.scale(.01*n,.01*a,1),this.matrix.rotate(-l*degToRads),this.matrix.skewFromAxis(-o*degToRads,(h+90)*degToRads),this.matrix.translate(r[0],r[1],0),this._mdf=!0,this.opacity!==e[8].p.v&&(this.opacity=e[8].p.v,this._opMdf=!0)}},extendPrototype([TransformEffect],SVGTransformEffect),setExpressionsPlugin(Expressions),setExpressionInterfaces(getInterface),initialize$1(),initialize(),registerEffect$1(20,SVGTintFilter,!0),registerEffect$1(21,SVGFillFilter,!0),registerEffect$1(22,SVGStrokeEffect,!1),registerEffect$1(23,SVGTritoneFilter,!0),registerEffect$1(24,SVGProLevelsFilter,!0),registerEffect$1(25,SVGDropShadowEffect,!0),registerEffect$1(28,SVGMatte3Effect,!1),registerEffect$1(29,SVGGaussianBlurEffect,!0),registerEffect$1(35,SVGTransformEffect,!1),lottie}));
+"undefined"!=typeof document&&"undefined"!=typeof navigator&&function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lottie=e()}(this,(function(){"use strict";var svgNS="http://www.w3.org/2000/svg",locationHref="",_useWebWorker=!1,initialDefaultFrame=-999999,setWebWorker=function(t){_useWebWorker=!!t},getWebWorker=function(){return _useWebWorker},setLocationHref=function(t){locationHref=t},getLocationHref=function(){return locationHref};function createTag(t){return document.createElement(t)}function extendPrototype(t,e){var i,r,s=t.length;for(i=0;i<s;i+=1)for(var a in r=t[i].prototype)Object.prototype.hasOwnProperty.call(r,a)&&(e.prototype[a]=r[a])}function getDescriptor(t,e){return Object.getOwnPropertyDescriptor(t,e)}function createProxyFunction(t){function e(){}return e.prototype=t,e}var audioControllerFactory=function(){function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].pause()},resume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].resume()},setRate:function(t){var e,i=this.audios.length;for(e=0;e<i;e+=1)this.audios[e].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}}(),createTypedArray=function(){function t(t,e){var i,r=0,s=[];switch(t){case"int16":case"uint8c":i=1;break;default:i=1.1}for(r=0;r<e;r+=1)s.push(i);return s}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(e,i){return"float32"===e?new Float32Array(i):"int16"===e?new Int16Array(i):"uint8c"===e?new Uint8ClampedArray(i):t(e,i)}:t}();function createSizedArray(t){return Array.apply(null,{length:t})}function _typeof$6(t){return _typeof$6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$6(t)}var subframeEnabled=!0,expressionsPlugin=null,expressionsInterfaces=null,idPrefix$1="",isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),_shouldRoundValues=!1,bmPow=Math.pow,bmSqrt=Math.sqrt,bmFloor=Math.floor,bmMax=Math.max,bmMin=Math.min,BMMath={};function ProjectInterface$1(){return{}}!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],i=e.length;for(t=0;t<i;t+=1)BMMath[e[t]]=Math[e[t]]}(),BMMath.random=Math.random,BMMath.abs=function(t){if("object"===_typeof$6(t)&&t.length){var e,i=createSizedArray(t.length),r=t.length;for(e=0;e<r;e+=1)i[e]=Math.abs(t[e]);return i}return Math.abs(t)};var defaultCurveSegments=150,degToRads=Math.PI/180,roundCorner=.5519;function roundValues(t){_shouldRoundValues=!!t}function bmRnd(t){return _shouldRoundValues?Math.round(t):t}function styleDiv(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin="0 0",t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility="visible",t.style.webkitBackfaceVisibility="visible",t.style.transformStyle="preserve-3d",t.style.webkitTransformStyle="preserve-3d",t.style.mozTransformStyle="preserve-3d"}function BMEnterFrameEvent(t,e,i,r){this.type=t,this.currentTime=e,this.totalTime=i,this.direction=r<0?-1:1}function BMCompleteEvent(t,e){this.type=t,this.direction=e<0?-1:1}function BMCompleteLoopEvent(t,e,i,r){this.type=t,this.currentLoop=i,this.totalLoops=e,this.direction=r<0?-1:1}function BMSegmentStartEvent(t,e,i){this.type=t,this.firstFrame=e,this.totalFrames=i}function BMDestroyEvent(t,e){this.type=t,this.target=e}function BMRenderFrameErrorEvent(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function BMConfigErrorEvent(t){this.type="configError",this.nativeError=t}function BMAnimationConfigErrorEvent(t,e){this.type=t,this.nativeError=e}var createElementID=(_count=0,function(){return idPrefix$1+"__lottie_element_"+(_count+=1)}),_count;function HSVtoRGB(t,e,i){var r,s,a,n,o,h,l,p;switch(h=i*(1-e),l=i*(1-(o=6*t-(n=Math.floor(6*t)))*e),p=i*(1-(1-o)*e),n%6){case 0:r=i,s=p,a=h;break;case 1:r=l,s=i,a=h;break;case 2:r=h,s=i,a=p;break;case 3:r=h,s=l,a=i;break;case 4:r=p,s=h,a=i;break;case 5:r=i,s=h,a=l}return[r,s,a]}function RGBtoHSV(t,e,i){var r,s=Math.max(t,e,i),a=Math.min(t,e,i),n=s-a,o=0===s?0:n/s,h=s/255;switch(s){case a:r=0;break;case t:r=e-i+n*(e<i?6:0),r/=6*n;break;case e:r=i-t+2*n,r/=6*n;break;case i:r=t-e+4*n,r/=6*n}return[r,o,h]}function addSaturationToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[1]+=e,i[1]>1?i[1]=1:i[1]<=0&&(i[1]=0),HSVtoRGB(i[0],i[1],i[2])}function addBrightnessToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[2]+=e,i[2]>1?i[2]=1:i[2]<0&&(i[2]=0),HSVtoRGB(i[0],i[1],i[2])}function addHueToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[0]+=e/360,i[0]>1?i[0]-=1:i[0]<0&&(i[0]+=1),HSVtoRGB(i[0],i[1],i[2])}var rgbToHex=function(){var t,e,i=[];for(t=0;t<256;t+=1)e=t.toString(16),i[t]=1===e.length?"0"+e:e;return function(t,e,r){return t<0&&(t=0),e<0&&(e=0),r<0&&(r=0),"#"+i[t]+i[e]+i[r]}}(),setSubframeEnabled=function(t){subframeEnabled=!!t},getSubframeEnabled=function(){return subframeEnabled},setExpressionsPlugin=function(t){expressionsPlugin=t},getExpressionsPlugin=function(){return expressionsPlugin},setExpressionInterfaces=function(t){expressionsInterfaces=t},getExpressionInterfaces=function(){return expressionsInterfaces},setDefaultCurveSegments=function(t){defaultCurveSegments=t},getDefaultCurveSegments=function(){return defaultCurveSegments},setIdPrefix=function(t){idPrefix$1=t},getIdPrefix=function(){return idPrefix$1};function createNS(t){return document.createElementNS(svgNS,t)}function _typeof$5(t){return _typeof$5="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$5(t)}var dataManager=function(){var t,e,i=1,r=[],s={onmessage:function(){},postMessage:function(e){t({data:e})}},a={postMessage:function(t){s.onmessage({data:t})}};function n(){e||(e=function(e){if(window.Worker&&window.Blob&&getWebWorker()){var i=new Blob(["var _workerSelf = self; self.onmessage = ",e.toString()],{type:"text/javascript"}),r=URL.createObjectURL(i);return new Worker(r)}return t=e,s}((function(t){if(a.dataManager||(a.dataManager=function(){function t(s,a){var n,o,h,l,p,m,c=s.length;for(o=0;o<c;o+=1)if("ks"in(n=s[o])&&!n.completed){if(n.completed=!0,n.hasMask){var u=n.masksProperties;for(l=u.length,h=0;h<l;h+=1)if(u[h].pt.k.i)r(u[h].pt.k);else for(m=u[h].pt.k.length,p=0;p<m;p+=1)u[h].pt.k[p].s&&r(u[h].pt.k[p].s[0]),u[h].pt.k[p].e&&r(u[h].pt.k[p].e[0])}0===n.ty?(n.layers=e(n.refId,a),t(n.layers,a)):4===n.ty?i(n.shapes):5===n.ty&&f(n)}}function e(t,e){var i=function(t,e){for(var i=0,r=e.length;i<r;){if(e[i].id===t)return e[i];i+=1}return null}(t,e);return i?i.layers.__used?JSON.parse(JSON.stringify(i.layers)):(i.layers.__used=!0,i.layers):null}function i(t){var e,s,a;for(e=t.length-1;e>=0;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)r(t[e].ks.k);else for(a=t[e].ks.k.length,s=0;s<a;s+=1)t[e].ks.k[s].s&&r(t[e].ks.k[s].s[0]),t[e].ks.k[s].e&&r(t[e].ks.k[s].e[0]);else"gr"===t[e].ty&&i(t[e].it)}function r(t){var e,i=t.i.length;for(e=0;e<i;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function s(t,e){var i=e?e.split("."):[100,100,100];return t[0]>i[0]||!(i[0]>t[0])&&(t[1]>i[1]||!(i[1]>t[1])&&(t[2]>i[2]||!(i[2]>t[2])&&null))}var a,n=function(){var t=[4,4,14];function e(t){var e,i,r,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(r=void 0,r=(i=t[e]).t.d,i.t.d={k:[{s:r,t:0}]})}return function(i){if(s(t,i.v)&&(e(i.layers),i.assets)){var r,a=i.assets.length;for(r=0;r<a;r+=1)i.assets[r].layers&&e(i.assets[r].layers)}}}(),o=(a=[4,7,99],function(t){if(t.chars&&!s(a,t.v)){var e,r=t.chars.length;for(e=0;e<r;e+=1){var n=t.chars[e];n.data&&n.data.shapes&&(i(n.data.shapes),n.data.ip=0,n.data.op=99999,n.data.st=0,n.data.sr=1,n.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[e].t||(n.data.shapes.push({ty:"no"}),n.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}}}),h=function(){var t=[5,7,15];function e(t){var e,i,r=t.length;for(e=0;e<r;e+=1)5===t[e].ty&&(i=void 0,"number"==typeof(i=t[e].t.p).a&&(i.a={a:0,k:i.a}),"number"==typeof i.p&&(i.p={a:0,k:i.p}),"number"==typeof i.r&&(i.r={a:0,k:i.r}))}return function(i){if(s(t,i.v)&&(e(i.layers),i.assets)){var r,a=i.assets.length;for(r=0;r<a;r+=1)i.assets[r].layers&&e(i.assets[r].layers)}}}(),l=function(){var t=[4,1,9];function e(t){var i,r,s,a=t.length;for(i=0;i<a;i+=1)if("gr"===t[i].ty)e(t[i].it);else if("fl"===t[i].ty||"st"===t[i].ty)if(t[i].c.k&&t[i].c.k[0].i)for(s=t[i].c.k.length,r=0;r<s;r+=1)t[i].c.k[r].s&&(t[i].c.k[r].s[0]/=255,t[i].c.k[r].s[1]/=255,t[i].c.k[r].s[2]/=255,t[i].c.k[r].s[3]/=255),t[i].c.k[r].e&&(t[i].c.k[r].e[0]/=255,t[i].c.k[r].e[1]/=255,t[i].c.k[r].e[2]/=255,t[i].c.k[r].e[3]/=255);else t[i].c.k[0]/=255,t[i].c.k[1]/=255,t[i].c.k[2]/=255,t[i].c.k[3]/=255}function i(t){var i,r=t.length;for(i=0;i<r;i+=1)4===t[i].ty&&e(t[i].shapes)}return function(e){if(s(t,e.v)&&(i(e.layers),e.assets)){var r,a=e.assets.length;for(r=0;r<a;r+=1)e.assets[r].layers&&i(e.assets[r].layers)}}}(),p=function(){var t=[4,4,18];function e(t){var i,r,s;for(i=t.length-1;i>=0;i-=1)if("sh"===t[i].ty)if(t[i].ks.k.i)t[i].ks.k.c=t[i].closed;else for(s=t[i].ks.k.length,r=0;r<s;r+=1)t[i].ks.k[r].s&&(t[i].ks.k[r].s[0].c=t[i].closed),t[i].ks.k[r].e&&(t[i].ks.k[r].e[0].c=t[i].closed);else"gr"===t[i].ty&&e(t[i].it)}function i(t){var i,r,s,a,n,o,h=t.length;for(r=0;r<h;r+=1){if((i=t[r]).hasMask){var l=i.masksProperties;for(a=l.length,s=0;s<a;s+=1)if(l[s].pt.k.i)l[s].pt.k.c=l[s].cl;else for(o=l[s].pt.k.length,n=0;n<o;n+=1)l[s].pt.k[n].s&&(l[s].pt.k[n].s[0].c=l[s].cl),l[s].pt.k[n].e&&(l[s].pt.k[n].e[0].c=l[s].cl)}4===i.ty&&e(i.shapes)}}return function(e){if(s(t,e.v)&&(i(e.layers),e.assets)){var r,a=e.assets.length;for(r=0;r<a;r+=1)e.assets[r].layers&&i(e.assets[r].layers)}}}();function f(t){0===t.t.a.length&&t.t.p}var m={completeData:function(i){i.__complete||(l(i),n(i),o(i),h(i),p(i),t(i.layers,i.assets),function(i,r){if(i){var s=0,a=i.length;for(s=0;s<a;s+=1)1===i[s].t&&(i[s].data.layers=e(i[s].data.refId,r),t(i[s].data.layers,r))}}(i.chars,i.assets),i.__complete=!0)}};return m.checkColors=l,m.checkChars=o,m.checkPathProperties=h,m.checkShapes=p,m.completeLayers=t,m}()),a.assetLoader||(a.assetLoader=function(){function t(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")||t.response&&"object"===_typeof$5(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}return{load:function(e,i,r,s){var a,n=new XMLHttpRequest;try{n.responseType="json"}catch(t){}n.onreadystatechange=function(){if(4===n.readyState)if(200===n.status)a=t(n),r(a);else try{a=t(n),r(a)}catch(t){s&&s(t)}};try{n.open(["G","E","T"].join(""),e,!0)}catch(t){n.open(["G","E","T"].join(""),i+"/"+e,!0)}n.send()}}}()),"loadAnimation"===t.data.type)a.assetLoader.load(t.data.path,t.data.fullPath,(function(e){a.dataManager.completeData(e),a.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){a.postMessage({id:t.data.id,status:"error"})}));else if("complete"===t.data.type){var e=t.data.animation;a.dataManager.completeData(e),a.postMessage({id:t.data.id,payload:e,status:"success"})}else"loadData"===t.data.type&&a.assetLoader.load(t.data.path,t.data.fullPath,(function(e){a.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){a.postMessage({id:t.data.id,status:"error"})}))})),e.onmessage=function(t){var e=t.data,i=e.id,s=r[i];r[i]=null,"success"===e.status?s.onComplete(e.payload):s.onError&&s.onError()})}function o(t,e){var s="processId_"+(i+=1);return r[s]={onComplete:t,onError:e},s}return{loadAnimation:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:s})},loadData:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:s})},completeAnimation:function(t,i,r){n();var s=o(i,r);e.postMessage({type:"complete",animation:t,id:s})}}}(),ImagePreloader=function(){var t=function(){var t=createTag("canvas");t.width=1,t.height=1;var e=t.getContext("2d");return e.fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1),t}();function e(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function i(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function r(t,e,i){var r="";if(t.e)r=t.p;else if(e){var s=t.p;-1!==s.indexOf("images/")&&(s=s.split("/")[1]),r=e+s}else r=i,r+=t.u?t.u:"",r+=t.p;return r}function s(t){var e=0,i=setInterval(function(){(t.getBBox().width||e>500)&&(this._imageLoaded(),clearInterval(i)),e+=1}.bind(this),50)}function a(t){var e={assetData:t},i=r(t,this.assetsPath,this.path);return dataManager.loadData(i,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}function n(){this._imageLoaded=e.bind(this),this._footageLoaded=i.bind(this),this.testImageLoaded=s.bind(this),this.createFootageData=a.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return n.prototype={loadAssets:function(t,e){var i;this.imagesLoadedCb=e;var r=t.length;for(i=0;i<r;i+=1)t[i].layers||(t[i].t&&"seq"!==t[i].t?3===t[i].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[i]))):(this.totalImages+=1,this.images.push(this._createImageData(t[i]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,i=this.images.length;e<i;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(e){var i=r(e,this.assetsPath,this.path),s=createTag("img");s.crossOrigin="anonymous",s.addEventListener("load",this._imageLoaded,!1),s.addEventListener("error",function(){a.img=t,this._imageLoaded()}.bind(this),!1),s.src=i;var a={img:s,assetData:e};return a},createImageData:function(e){var i=r(e,this.assetsPath,this.path),s=createNS("image");isSafari?this.testImageLoaded(s):s.addEventListener("load",this._imageLoaded,!1),s.addEventListener("error",function(){a.img=t,this._imageLoaded()}.bind(this),!1),s.setAttributeNS("http://www.w3.org/1999/xlink","href",i),this._elementHelper.append?this._elementHelper.append(s):this._elementHelper.appendChild(s);var a={img:s,assetData:e};return a},imageLoaded:e,footageLoaded:i,setCacheType:function(t,e){"svg"===t?(this._elementHelper=e,this._createImageData=this.createImageData.bind(this)):this._createImageData=this.createImgData.bind(this)}},n}();function BaseEvent(){}BaseEvent.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var i=this._cbs[t],r=0;r<i.length;r+=1)i[r](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var i=0,r=this._cbs[t].length;i<r;)this._cbs[t][i]===e&&(this._cbs[t].splice(i,1),i-=1,r-=1),i+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var markerParser=function(){function t(t){for(var e,i=t.split("\r\n"),r={},s=0,a=0;a<i.length;a+=1)2===(e=i[a].split(":")).length&&(r[e[0]]=e[1].trim(),s+=1);if(0===s)throw new Error;return r}return function(e){for(var i=[],r=0;r<e.length;r+=1){var s=e[r],a={time:s.tm,duration:s.dr};try{a.payload=JSON.parse(e[r].cm)}catch(i){try{a.payload=t(e[r].cm)}catch(t){a.payload={name:e[r].cm}}}i.push(a)}return i}}(),ProjectInterface=function(){function t(t){this.compositions.push(t)}return function(){function e(t){for(var e=0,i=this.compositions.length;e<i;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return e.compositions=[],e.currentFrame=0,e.registerComposition=t,e}}(),renderers={},registerRenderer=function(t,e){renderers[t]=e};function getRenderer(t){return renderers[t]}function getRegisteredRenderer(){if(renderers.canvas)return"canvas";for(var t in renderers)if(renderers[t])return t;return""}function _typeof$4(t){return _typeof$4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$4(t)}var AnimationItem=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=createElementID(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=getSubframeEnabled(),this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=ProjectInterface(),this.imagePreloader=new ImagePreloader,this.audioController=audioControllerFactory(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new BMEnterFrameEvent("drawnFrame",0,0,0),this.expressionsPlugin=getExpressionsPlugin()};extendPrototype([BaseEvent],AnimationItem),AnimationItem.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg";t.animType?e=t.animType:t.renderer&&(e=t.renderer);var i=getRenderer(e);this.renderer=new i(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||void 0===t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),dataManager.loadAnimation(t.path,this.configAnimation,this.onSetupError))},AnimationItem.prototype.onSetupError=function(){this.trigger("data_failed")},AnimationItem.prototype.setupAnimation=function(t){dataManager.completeAnimation(t,this.configAnimation)},AnimationItem.prototype.setData=function(t,e){e&&"object"!==_typeof$4(e)&&(e=JSON.parse(e));var i={wrapper:t,animationData:e},r=t.attributes;i.path=r.getNamedItem("data-animation-path")?r.getNamedItem("data-animation-path").value:r.getNamedItem("data-bm-path")?r.getNamedItem("data-bm-path").value:r.getNamedItem("bm-path")?r.getNamedItem("bm-path").value:"",i.animType=r.getNamedItem("data-anim-type")?r.getNamedItem("data-anim-type").value:r.getNamedItem("data-bm-type")?r.getNamedItem("data-bm-type").value:r.getNamedItem("bm-type")?r.getNamedItem("bm-type").value:r.getNamedItem("data-bm-renderer")?r.getNamedItem("data-bm-renderer").value:r.getNamedItem("bm-renderer")?r.getNamedItem("bm-renderer").value:getRegisteredRenderer()||"canvas";var s=r.getNamedItem("data-anim-loop")?r.getNamedItem("data-anim-loop").value:r.getNamedItem("data-bm-loop")?r.getNamedItem("data-bm-loop").value:r.getNamedItem("bm-loop")?r.getNamedItem("bm-loop").value:"";"false"===s?i.loop=!1:"true"===s?i.loop=!0:""!==s&&(i.loop=parseInt(s,10));var a=r.getNamedItem("data-anim-autoplay")?r.getNamedItem("data-anim-autoplay").value:r.getNamedItem("data-bm-autoplay")?r.getNamedItem("data-bm-autoplay").value:!r.getNamedItem("bm-autoplay")||r.getNamedItem("bm-autoplay").value;i.autoplay="false"!==a,i.name=r.getNamedItem("data-name")?r.getNamedItem("data-name").value:r.getNamedItem("data-bm-name")?r.getNamedItem("data-bm-name").value:r.getNamedItem("bm-name")?r.getNamedItem("bm-name").value:"","false"===(r.getNamedItem("data-anim-prerender")?r.getNamedItem("data-anim-prerender").value:r.getNamedItem("data-bm-prerender")?r.getNamedItem("data-bm-prerender").value:r.getNamedItem("bm-prerender")?r.getNamedItem("bm-prerender").value:"")&&(i.prerender=!1),i.path?this.setParams(i):this.trigger("destroy")},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,i,r=this.animationData.layers,s=r.length,a=t.layers,n=a.length;for(i=0;i<n;i+=1)for(e=0;e<s;){if(r[e].id===a[i].id){r[e]=a[i];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(s=t.assets.length,e=0;e<s;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,dataManager.completeAnimation(this.animationData,this.onSegmentComplete)},AnimationItem.prototype.onSegmentComplete=function(t){this.animationData=t;var e=getExpressionsPlugin();e&&e.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var i=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,dataManager.loadData(i,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},AnimationItem.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},AnimationItem.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=markerParser(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},AnimationItem.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},AnimationItem.prototype.checkLoaded=function(){if(!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()){this.isLoaded=!0;var t=getExpressionsPlugin();t&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play()}},AnimationItem.prototype.resize=function(t,e){var i="number"==typeof t?t:void 0,r="number"==typeof e?e:void 0;this.renderer.updateContainerSize(i,r)},AnimationItem.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},AnimationItem.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},AnimationItem.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},AnimationItem.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},AnimationItem.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.getMarkerData=function(t){for(var e,i=0;i<this.markers.length;i+=1)if((e=this.markers[i]).payload&&e.payload.name===t)return e;return null},AnimationItem.prototype.goToAndStop=function(t,e,i){if(!i||this.name===i){var r=Number(t);if(isNaN(r)){var s=this.getMarkerData(t);s&&this.goToAndStop(s.time,!0)}else e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier);this.pause()}},AnimationItem.prototype.goToAndPlay=function(t,e,i){if(!i||this.name===i){var r=Number(t);if(isNaN(r)){var s=this.getMarkerData(t);s&&(s.duration?this.playSegments([s.time,s.time+s.duration],!0):this.goToAndStop(s.time,!0))}else this.goToAndStop(r,e,i);this.play()}},AnimationItem.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,i=!1;e>=this.totalFrames-1&&this.frameModifier>0?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(i=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(i=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),i&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(this.frameModifier>0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var i=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?i=t:this.currentRawFrame+this.firstFrame>e&&(i=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==i&&this.goToAndStop(i,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===_typeof$4(t[0])){var i,r=t.length;for(i=0;i<r;i+=1)this.segments.push(t[i])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},AnimationItem.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},AnimationItem.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},AnimationItem.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},AnimationItem.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},AnimationItem.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},AnimationItem.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},AnimationItem.prototype.setLoop=function(t){this.loop=t},AnimationItem.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},AnimationItem.prototype.getVolume=function(){return this.audioController.getVolume()},AnimationItem.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},AnimationItem.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},AnimationItem.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},AnimationItem.prototype.getPath=function(){return this.path},AnimationItem.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var i=t.p;-1!==i.indexOf("images/")&&(i=i.split("/")[1]),e=this.assetsPath+i}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},AnimationItem.prototype.getAssetData=function(t){for(var e=0,i=this.assets.length;e<i;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},AnimationItem.prototype.hide=function(){this.renderer.hide()},AnimationItem.prototype.show=function(){this.renderer.show()},AnimationItem.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},AnimationItem.prototype.updateDocumentData=function(t,e,i){try{this.renderer.getElementByPath(t).updateDocumentData(e,i)}catch(t){}},AnimationItem.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new BMCompleteEvent(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new BMDestroyEvent(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new BMCompleteEvent(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new BMDestroyEvent(t,this))},AnimationItem.prototype.triggerRenderFrameError=function(t){var e=new BMRenderFrameErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)},AnimationItem.prototype.triggerConfigError=function(t){var e=new BMConfigErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)};var animationManager=function(){var t={},e=[],i=0,r=0,s=0,a=!0,n=!1;function o(t){for(var i=0,s=t.target;i<r;)e[i].animation===s&&(e.splice(i,1),i-=1,r-=1,s.isPaused||p()),i+=1}function h(t,i){if(!t)return null;for(var s=0;s<r;){if(e[s].elem===t&&null!==e[s].elem)return e[s].animation;s+=1}var a=new AnimationItem;return f(a,t),a.setData(t,i),a}function l(){s+=1,u()}function p(){s-=1}function f(t,i){t.addEventListener("destroy",o),t.addEventListener("_active",l),t.addEventListener("_idle",p),e.push({elem:i,animation:t}),r+=1}function m(t){var o,h=t-i;for(o=0;o<r;o+=1)e[o].animation.advanceTime(h);i=t,s&&!n?window.requestAnimationFrame(m):a=!0}function c(t){i=t,window.requestAnimationFrame(m)}function u(){!n&&s&&a&&(window.requestAnimationFrame(c),a=!1)}return t.registerAnimation=h,t.loadAnimation=function(t){var e=new AnimationItem;return f(e,null),e.setParams(t),e},t.setSpeed=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setSpeed(t,i)},t.setDirection=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setDirection(t,i)},t.play=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.play(t)},t.pause=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.pause(t)},t.stop=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.stop(t)},t.togglePause=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.togglePause(t)},t.searchAnimations=function(t,e,i){var r,s=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),a=s.length;for(r=0;r<a;r+=1)i&&s[r].setAttribute("data-bm-type",i),h(s[r],t);if(e&&0===a){i||(i="svg");var n=document.getElementsByTagName("body")[0];n.innerText="";var o=createTag("div");o.style.width="100%",o.style.height="100%",o.setAttribute("data-bm-type",i),n.appendChild(o),h(o,t)}},t.resize=function(){var t;for(t=0;t<r;t+=1)e[t].animation.resize()},t.goToAndStop=function(t,i,s){var a;for(a=0;a<r;a+=1)e[a].animation.goToAndStop(t,i,s)},t.destroy=function(t){var i;for(i=r-1;i>=0;i-=1)e[i].animation.destroy(t)},t.freeze=function(){n=!0},t.unfreeze=function(){n=!1,u()},t.setVolume=function(t,i){var s;for(s=0;s<r;s+=1)e[s].animation.setVolume(t,i)},t.mute=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.mute(t)},t.unmute=function(t){var i;for(i=0;i<r;i+=1)e[i].animation.unmute(t)},t.getRegisteredAnimations=function(){var t,i=e.length,r=[];for(t=0;t<i;t+=1)r.push(e[t].animation);return r},t}(),BezierFactory=function(){var t={getBezierEasing:function(t,i,r,s,a){var n=a||("bez_"+t+"_"+i+"_"+r+"_"+s).replace(/\./g,"p");if(e[n])return e[n];var o=new p([t,i,r,s]);return e[n]=o,o}},e={};var i=11,r=1/(i-1),s="function"==typeof Float32Array;function a(t,e){return 1-3*e+3*t}function n(t,e){return 3*e-6*t}function o(t){return 3*t}function h(t,e,i){return((a(e,i)*t+n(e,i))*t+o(e))*t}function l(t,e,i){return 3*a(e,i)*t*t+2*n(e,i)*t+o(e)}function p(t){this._p=t,this._mSampleValues=s?new Float32Array(i):new Array(i),this._precomputed=!1,this.get=this.get.bind(this)}return p.prototype={get:function(t){var e=this._p[0],i=this._p[1],r=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===i&&r===s?t:0===t?0:1===t?1:h(this._getTForX(t),i,s)},_precompute:function(){var t=this._p[0],e=this._p[1],i=this._p[2],r=this._p[3];this._precomputed=!0,t===e&&i===r||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],s=0;s<i;++s)this._mSampleValues[s]=h(s*r,t,e)},_getTForX:function(t){for(var e=this._p[0],s=this._p[2],a=this._mSampleValues,n=0,o=1,p=i-1;o!==p&&a[o]<=t;++o)n+=r;var f=n+(t-a[--o])/(a[o+1]-a[o])*r,m=l(f,e,s);return m>=.001?function(t,e,i,r){for(var s=0;s<4;++s){var a=l(e,i,r);if(0===a)return e;e-=(h(e,i,r)-t)/a}return e}(t,f,e,s):0===m?f:function(t,e,i,r,s){var a,n,o=0;do{(a=h(n=e+(i-e)/2,r,s)-t)>0?i=n:e=n}while(Math.abs(a)>1e-7&&++o<10);return n}(t,n,n+r,e,s)}},t}(),pooling={double:function(t){return t.concat(createSizedArray(t.length))}},poolFactory=function(t,e,i){var r=0,s=t,a=createSizedArray(s);return{newElement:function(){return r?a[r-=1]:e()},release:function(t){r===s&&(a=pooling.double(a),s*=2),i&&i(t),a[r]=t,r+=1}}},bezierLengthPool=poolFactory(8,(function(){return{addedLength:0,percents:createTypedArray("float32",getDefaultCurveSegments()),lengths:createTypedArray("float32",getDefaultCurveSegments())}})),segmentsLengthPool=poolFactory(8,(function(){return{lengths:[],totalLength:0}}),(function(t){var e,i=t.lengths.length;for(e=0;e<i;e+=1)bezierLengthPool.release(t.lengths[e]);t.lengths.length=0}));function bezFunction(){var t=Math;function e(t,e,i,r,s,a){var n=t*r+e*s+i*a-s*r-a*t-i*e;return n>-.001&&n<.001}var i=function(t,e,i,r){var s,a,n,o,h,l,p=getDefaultCurveSegments(),f=0,m=[],c=[],u=bezierLengthPool.newElement();for(n=i.length,s=0;s<p;s+=1){for(h=s/(p-1),l=0,a=0;a<n;a+=1)o=bmPow(1-h,3)*t[a]+3*bmPow(1-h,2)*h*i[a]+3*(1-h)*bmPow(h,2)*r[a]+bmPow(h,3)*e[a],m[a]=o,null!==c[a]&&(l+=bmPow(m[a]-c[a],2)),c[a]=m[a];l&&(f+=l=bmSqrt(l)),u.percents[s]=h,u.lengths[s]=f}return u.addedLength=f,u};function r(t){this.segmentLength=0,this.points=new Array(t)}function s(t,e){this.partialLength=t,this.point=e}var a,n=(a={},function(t,i,n,o){var h=(t[0]+"_"+t[1]+"_"+i[0]+"_"+i[1]+"_"+n[0]+"_"+n[1]+"_"+o[0]+"_"+o[1]).replace(/\./g,"p");if(!a[h]){var l,p,f,m,c,u,d,y=getDefaultCurveSegments(),g=0,v=null;2===t.length&&(t[0]!==i[0]||t[1]!==i[1])&&e(t[0],t[1],i[0],i[1],t[0]+n[0],t[1]+n[1])&&e(t[0],t[1],i[0],i[1],i[0]+o[0],i[1]+o[1])&&(y=2);var b=new r(y);for(f=n.length,l=0;l<y;l+=1){for(d=createSizedArray(f),c=l/(y-1),u=0,p=0;p<f;p+=1)m=bmPow(1-c,3)*t[p]+3*bmPow(1-c,2)*c*(t[p]+n[p])+3*(1-c)*bmPow(c,2)*(i[p]+o[p])+bmPow(c,3)*i[p],d[p]=m,null!==v&&(u+=bmPow(d[p]-v[p],2));g+=u=bmSqrt(u),b.points[l]=new s(u,d),v=d}b.segmentLength=g,a[h]=b}return a[h]});function o(t,e){var i=e.percents,r=e.lengths,s=i.length,a=bmFloor((s-1)*t),n=t*e.addedLength,o=0;if(a===s-1||0===a||n===r[a])return i[a];for(var h=r[a]>n?-1:1,l=!0;l;)if(r[a]<=n&&r[a+1]>n?(o=(n-r[a])/(r[a+1]-r[a]),l=!1):a+=h,a<0||a>=s-1){if(a===s-1)return i[a];l=!1}return i[a]+(i[a+1]-i[a])*o}var h=createTypedArray("float32",8);return{getSegmentsLength:function(t){var e,r=segmentsLengthPool.newElement(),s=t.c,a=t.v,n=t.o,o=t.i,h=t._length,l=r.lengths,p=0;for(e=0;e<h-1;e+=1)l[e]=i(a[e],a[e+1],n[e],o[e+1]),p+=l[e].addedLength;return s&&h&&(l[e]=i(a[e],a[0],n[e],o[0]),p+=l[e].addedLength),r.totalLength=p,r},getNewSegment:function(e,i,r,s,a,n,l){a<0?a=0:a>1&&(a=1);var p,f=o(a,l),m=o(n=n>1?1:n,l),c=e.length,u=1-f,d=1-m,y=u*u*u,g=f*u*u*3,v=f*f*u*3,b=f*f*f,P=u*u*d,E=f*u*d+u*f*d+u*u*m,x=f*f*d+u*f*m+f*u*m,S=f*f*m,_=u*d*d,A=f*d*d+u*m*d+u*d*m,M=f*m*d+u*m*m+f*d*m,T=f*m*m,k=d*d*d,D=m*d*d+d*m*d+d*d*m,F=m*m*d+d*m*m+m*d*m,C=m*m*m;for(p=0;p<c;p+=1)h[4*p]=t.round(1e3*(y*e[p]+g*r[p]+v*s[p]+b*i[p]))/1e3,h[4*p+1]=t.round(1e3*(P*e[p]+E*r[p]+x*s[p]+S*i[p]))/1e3,h[4*p+2]=t.round(1e3*(_*e[p]+A*r[p]+M*s[p]+T*i[p]))/1e3,h[4*p+3]=t.round(1e3*(k*e[p]+D*r[p]+F*s[p]+C*i[p]))/1e3;return h},getPointInSegment:function(e,i,r,s,a,n){var h=o(a,n),l=1-h;return[t.round(1e3*(l*l*l*e[0]+(h*l*l+l*h*l+l*l*h)*r[0]+(h*h*l+l*h*h+h*l*h)*s[0]+h*h*h*i[0]))/1e3,t.round(1e3*(l*l*l*e[1]+(h*l*l+l*h*l+l*l*h)*r[1]+(h*h*l+l*h*h+h*l*h)*s[1]+h*h*h*i[1]))/1e3]},buildBezierData:n,pointOnLine2D:e,pointOnLine3D:function(i,r,s,a,n,o,h,l,p){if(0===s&&0===o&&0===p)return e(i,r,a,n,h,l);var f,m=t.sqrt(t.pow(a-i,2)+t.pow(n-r,2)+t.pow(o-s,2)),c=t.sqrt(t.pow(h-i,2)+t.pow(l-r,2)+t.pow(p-s,2)),u=t.sqrt(t.pow(h-a,2)+t.pow(l-n,2)+t.pow(p-o,2));return(f=m>c?m>u?m-c-u:u-c-m:u>c?u-c-m:c-m-u)>-1e-4&&f<1e-4}}}var bez=bezFunction(),initFrame=initialDefaultFrame,mathAbs=Math.abs;function interpolateValue(t,e){var i,r=this.offsetTime;"multidimensional"===this.propType&&(i=createTypedArray("float32",this.pv.length));for(var s,a,n,o,h,l,p,f,m,c=e.lastIndex,u=c,d=this.keyframes.length-1,y=!0;y;){if(s=this.keyframes[u],a=this.keyframes[u+1],u===d-1&&t>=a.t-r){s.h&&(s=a),c=0;break}if(a.t-r>t){c=u;break}u<d-1?u+=1:(c=0,y=!1)}n=this.keyframesMetadata[u]||{};var g,v=a.t-r,b=s.t-r;if(s.to){n.bezierData||(n.bezierData=bez.buildBezierData(s.s,a.s||s.e,s.to,s.ti));var P=n.bezierData;if(t>=v||t<b){var E=t>=v?P.points.length-1:0;for(h=P.points[E].point.length,o=0;o<h;o+=1)i[o]=P.points[E].point[o]}else{n.__fnct?m=n.__fnct:(m=BezierFactory.getBezierEasing(s.o.x,s.o.y,s.i.x,s.i.y,s.n).get,n.__fnct=m),l=m((t-b)/(v-b));var x,S=P.segmentLength*l,_=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastAddedLength:0;for(f=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastPoint:0,y=!0,p=P.points.length;y;){if(_+=P.points[f].partialLength,0===S||0===l||f===P.points.length-1){for(h=P.points[f].point.length,o=0;o<h;o+=1)i[o]=P.points[f].point[o];break}if(S>=_&&S<_+P.points[f+1].partialLength){for(x=(S-_)/P.points[f+1].partialLength,h=P.points[f].point.length,o=0;o<h;o+=1)i[o]=P.points[f].point[o]+(P.points[f+1].point[o]-P.points[f].point[o])*x;break}f<p-1?f+=1:y=!1}e._lastPoint=f,e._lastAddedLength=_-P.points[f].partialLength,e._lastKeyframeIndex=u}}else{var A,M,T,k,D;if(d=s.s.length,g=a.s||s.e,this.sh&&1!==s.h)if(t>=v)i[0]=g[0],i[1]=g[1],i[2]=g[2];else if(t<=b)i[0]=s.s[0],i[1]=s.s[1],i[2]=s.s[2];else{quaternionToEuler(i,slerp(createQuaternion(s.s),createQuaternion(g),(t-b)/(v-b)))}else for(u=0;u<d;u+=1)1!==s.h&&(t>=v?l=1:t<b?l=0:(s.o.x.constructor===Array?(n.__fnct||(n.__fnct=[]),n.__fnct[u]?m=n.__fnct[u]:(A=void 0===s.o.x[u]?s.o.x[0]:s.o.x[u],M=void 0===s.o.y[u]?s.o.y[0]:s.o.y[u],T=void 0===s.i.x[u]?s.i.x[0]:s.i.x[u],k=void 0===s.i.y[u]?s.i.y[0]:s.i.y[u],m=BezierFactory.getBezierEasing(A,M,T,k).get,n.__fnct[u]=m)):n.__fnct?m=n.__fnct:(A=s.o.x,M=s.o.y,T=s.i.x,k=s.i.y,m=BezierFactory.getBezierEasing(A,M,T,k).get,s.keyframeMetadata=m),l=m((t-b)/(v-b)))),g=a.s||s.e,D=1===s.h?s.s[u]:s.s[u]+(g[u]-s.s[u])*l,"multidimensional"===this.propType?i[u]=D:i=D}return e.lastIndex=c,i}function slerp(t,e,i){var r,s,a,n,o,h=[],l=t[0],p=t[1],f=t[2],m=t[3],c=e[0],u=e[1],d=e[2],y=e[3];return(s=l*c+p*u+f*d+m*y)<0&&(s=-s,c=-c,u=-u,d=-d,y=-y),1-s>1e-6?(r=Math.acos(s),a=Math.sin(r),n=Math.sin((1-i)*r)/a,o=Math.sin(i*r)/a):(n=1-i,o=i),h[0]=n*l+o*c,h[1]=n*p+o*u,h[2]=n*f+o*d,h[3]=n*m+o*y,h}function quaternionToEuler(t,e){var i=e[0],r=e[1],s=e[2],a=e[3],n=Math.atan2(2*r*a-2*i*s,1-2*r*r-2*s*s),o=Math.asin(2*i*r+2*s*a),h=Math.atan2(2*i*a-2*r*s,1-2*i*i-2*s*s);t[0]=n/degToRads,t[1]=o/degToRads,t[2]=h/degToRads}function createQuaternion(t){var e=t[0]*degToRads,i=t[1]*degToRads,r=t[2]*degToRads,s=Math.cos(e/2),a=Math.cos(i/2),n=Math.cos(r/2),o=Math.sin(e/2),h=Math.sin(i/2),l=Math.sin(r/2);return[o*h*n+s*a*l,o*a*n+s*h*l,s*h*n-o*a*l,s*a*n-o*h*l]}function getValueAtCurrentTime(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==initFrame&&(this._caching.lastFrame>=i&&t>=i||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var r=this.interpolateValue(t,this._caching);this.pv=r}return this._caching.lastFrame=t,this.pv}function setVValue(t){var e;if("unidimensional"===this.propType)e=t*this.mult,mathAbs(this.v-e)>1e-5&&(this.v=e,this._mdf=!0);else for(var i=0,r=this.v.length;i<r;)e=t[i]*this.mult,mathAbs(this.v[i]-e)>1e-5&&(this.v[i]=e,this._mdf=!0),i+=1}function processEffectsSequence(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t;this.lock=!0,this._mdf=this._isFirstFrame;var e=this.effectsSequence.length,i=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)i=this.effectsSequence[t](i);this.setVValue(i),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function addEffect(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function ValueProperty(t,e,i,r){this.propType="unidimensional",this.mult=i||1,this.data=e,this.v=i?e.k*i:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function MultiDimensionalProperty(t,e,i,r){var s;this.propType="multidimensional",this.mult=i||1,this.data=e,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var a=e.k.length;for(this.v=createTypedArray("float32",a),this.pv=createTypedArray("float32",a),this.vel=createTypedArray("float32",a),s=0;s<a;s+=1)this.v[s]=e.k[s]*this.mult,this.pv[s]=e.k[s];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function KeyframedValueProperty(t,e,i,r){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:initFrame,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.v=initFrame,this.pv=initFrame,this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.addEffect=addEffect}function KeyframedMultidimensionalProperty(t,e,i,r){var s;this.propType="multidimensional";var a,n,o,h,l=e.k.length;for(s=0;s<l-1;s+=1)e.k[s].to&&e.k[s].s&&e.k[s+1]&&e.k[s+1].s&&(a=e.k[s].s,n=e.k[s+1].s,o=e.k[s].to,h=e.k[s].ti,(2===a.length&&(a[0]!==n[0]||a[1]!==n[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],a[0]+o[0],a[1]+o[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],n[0]+h[0],n[1]+h[1])||3===a.length&&(a[0]!==n[0]||a[1]!==n[1]||a[2]!==n[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],a[0]+o[0],a[1]+o[1],a[2]+o[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],n[0]+h[0],n[1]+h[1],n[2]+h[2]))&&(e.k[s].to=null,e.k[s].ti=null),a[0]===n[0]&&a[1]===n[1]&&0===o[0]&&0===o[1]&&0===h[0]&&0===h[1]&&(2===a.length||a[2]===n[2]&&0===o[2]&&0===h[2])&&(e.k[s].to=null,e.k[s].ti=null));this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.frameId=-1;var p=e.k[0].s.length;for(this.v=createTypedArray("float32",p),this.pv=createTypedArray("float32",p),s=0;s<p;s+=1)this.v[s]=initFrame,this.pv[s]=initFrame;this._caching={lastFrame:initFrame,lastIndex:0,value:createTypedArray("float32",p)},this.addEffect=addEffect}var PropertyFactory={getProp:function(t,e,i,r,s){var a;if(e.sid&&(e=t.globalData.slotManager.getProp(e)),e.k.length)if("number"==typeof e.k[0])a=new MultiDimensionalProperty(t,e,r,s);else switch(i){case 0:a=new KeyframedValueProperty(t,e,r,s);break;case 1:a=new KeyframedMultidimensionalProperty(t,e,r,s)}else a=new ValueProperty(t,e,r,s);return a.effectsSequence.length&&s.addDynamicProperty(a),a}};function DynamicPropertyContainer(){}DynamicPropertyContainer.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){var t;this._mdf=!1;var e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var pointPool=poolFactory(8,(function(){return createTypedArray("float32",2)}));function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var i=0;i<e;)this.v[i]=pointPool.newElement(),this.o[i]=pointPool.newElement(),this.i[i]=pointPool.newElement(),i+=1},ShapePath.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},ShapePath.prototype.doubleArrayLength=function(){this.v=this.v.concat(createSizedArray(this._maxLength)),this.i=this.i.concat(createSizedArray(this._maxLength)),this.o=this.o.concat(createSizedArray(this._maxLength)),this._maxLength*=2},ShapePath.prototype.setXYAt=function(t,e,i,r,s){var a;switch(this._length=Math.max(this._length,r+1),this._length>=this._maxLength&&this.doubleArrayLength(),i){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o;break;default:a=[]}(!a[r]||a[r]&&!s)&&(a[r]=pointPool.newElement()),a[r][0]=t,a[r][1]=e},ShapePath.prototype.setTripleAt=function(t,e,i,r,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(i,r,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t=new ShapePath;t.setPathData(this.c,this._length);var e=this.v,i=this.o,r=this.i,s=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],r[0][0],r[0][1],i[0][0],i[0][1],0,!1),s=1);var a,n=this._length-1,o=this._length;for(a=s;a<o;a+=1)t.setTripleAt(e[n][0],e[n][1],r[n][0],r[n][1],i[n][0],i[n][1],a,!1),n-=1;return t},ShapePath.prototype.length=function(){return this._length};var shapePool=(factory=poolFactory(4,(function(){return new ShapePath}),(function(t){var e,i=t._length;for(e=0;e<i;e+=1)pointPool.release(t.v[e]),pointPool.release(t.i[e]),pointPool.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1})),factory.clone=function(t){var e,i=factory.newElement(),r=void 0===t._length?t.v.length:t._length;for(i.setLength(r),i.c=t.c,e=0;e<r;e+=1)i.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return i},factory),factory;function ShapeCollection(){this._length=0,this._maxLength=4,this.shapes=createSizedArray(this._maxLength)}ShapeCollection.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(createSizedArray(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},ShapeCollection.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)shapePool.release(this.shapes[t]);this._length=0};var shapeCollectionPool=(ob={newShapeCollection:function(){return _length?pool[_length-=1]:new ShapeCollection},release:function(t){var e,i=t._length;for(e=0;e<i;e+=1)shapePool.release(t.shapes[e]);t._length=0,_length===_maxLength&&(pool=pooling.double(pool),_maxLength*=2),pool[_length]=t,_length+=1}},_length=0,_maxLength=4,pool=createSizedArray(_maxLength),ob),ob,_length,_maxLength,pool,ShapePropertyFactory=function(){var t=-999999;function e(t,e,i){var r,s,a,n,o,h,l,p,f,m=i.lastIndex,c=this.keyframes;if(t<c[0].t-this.offsetTime)r=c[0].s[0],a=!0,m=0;else if(t>=c[c.length-1].t-this.offsetTime)r=c[c.length-1].s?c[c.length-1].s[0]:c[c.length-2].e[0],a=!0;else{for(var u,d,y,g=m,v=c.length-1,b=!0;b&&(u=c[g],!((d=c[g+1]).t-this.offsetTime>t));)g<v-1?g+=1:b=!1;if(y=this.keyframesMetadata[g]||{},m=g,!(a=1===u.h)){if(t>=d.t-this.offsetTime)p=1;else if(t<u.t-this.offsetTime)p=0;else{var P;y.__fnct?P=y.__fnct:(P=BezierFactory.getBezierEasing(u.o.x,u.o.y,u.i.x,u.i.y).get,y.__fnct=P),p=P((t-(u.t-this.offsetTime))/(d.t-this.offsetTime-(u.t-this.offsetTime)))}s=d.s?d.s[0]:u.e[0]}r=u.s[0]}for(h=e._length,l=r.i[0].length,i.lastIndex=m,n=0;n<h;n+=1)for(o=0;o<l;o+=1)f=a?r.i[n][o]:r.i[n][o]+(s.i[n][o]-r.i[n][o])*p,e.i[n][o]=f,f=a?r.o[n][o]:r.o[n][o]+(s.o[n][o]-r.o[n][o])*p,e.o[n][o]=f,f=a?r.v[n][o]:r.v[n][o]+(s.v[n][o]-r.v[n][o])*p,e.v[n][o]=f}function i(){var e=this.comp.renderedFrame-this.offsetTime,i=this.keyframes[0].t-this.offsetTime,r=this.keyframes[this.keyframes.length-1].t-this.offsetTime,s=this._caching.lastFrame;return s!==t&&(s<i&&e<i||s>r&&e>r)||(this._caching.lastIndex=s<e?this._caching.lastIndex:0,this.interpolateShape(e,this.pv,this._caching)),this._caching.lastFrame=e,this.pv}function r(){this.paths=this.localShapeCollection}function s(t){(function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var i,r=t._length;for(i=0;i<r;i+=1)if(t.v[i][0]!==e.v[i][0]||t.v[i][1]!==e.v[i][1]||t.o[i][0]!==e.o[i][0]||t.o[i][1]!==e.o[i][1]||t.i[i][0]!==e.i[i][0]||t.i[i][1]!==e.i[i][1])return!1;return!0})(this.v,t)||(this.v=shapePool.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function a(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t,e;this.lock=!0,this._mdf=!1,t=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k;var i=this.effectsSequence.length;for(e=0;e<i;e+=1)t=this.effectsSequence[e](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function n(t,e,i){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var s=3===i?e.pt.k:e.ks.k;this.v=shapePool.clone(s),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=r,this.effectsSequence=[]}function o(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function h(e,s,a){this.propType="shape",this.comp=e.comp,this.elem=e,this.container=e,this.offsetTime=e.data.st,this.keyframes=3===a?s.pt.k:s.ks.k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;var n=this.keyframes[0].s[0].i.length;this.v=shapePool.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,n),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=t,this.reset=r,this._caching={lastFrame:t,lastIndex:0},this.effectsSequence=[i.bind(this)]}n.prototype.interpolateShape=e,n.prototype.getValue=a,n.prototype.setVValue=s,n.prototype.addEffect=o,h.prototype.getValue=a,h.prototype.interpolateShape=e,h.prototype.setVValue=s,h.prototype.addEffect=o;var l=function(){var t=roundCorner;function e(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}return e.prototype={reset:r,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var e=this.p.v[0],i=this.p.v[1],r=this.s.v[0]/2,s=this.s.v[1]/2,a=3!==this.d,n=this.v;n.v[0][0]=e,n.v[0][1]=i-s,n.v[1][0]=a?e+r:e-r,n.v[1][1]=i,n.v[2][0]=e,n.v[2][1]=i+s,n.v[3][0]=a?e-r:e+r,n.v[3][1]=i,n.i[0][0]=a?e-r*t:e+r*t,n.i[0][1]=i-s,n.i[1][0]=a?e+r:e-r,n.i[1][1]=i-s*t,n.i[2][0]=a?e+r*t:e-r*t,n.i[2][1]=i+s,n.i[3][0]=a?e-r:e+r,n.i[3][1]=i+s*t,n.o[0][0]=a?e+r*t:e-r*t,n.o[0][1]=i-s,n.o[1][0]=a?e+r:e-r,n.o[1][1]=i+s*t,n.o[2][0]=a?e-r*t:e+r*t,n.o[2][1]=i+s,n.o[3][0]=a?e-r:e+r,n.o[3][1]=i-s*t}},extendPrototype([DynamicPropertyContainer],e),e}(),p=function(){function t(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=PropertyFactory.getProp(t,e.ir,0,0,this),this.is=PropertyFactory.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=PropertyFactory.getProp(t,e.pt,0,0,this),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,degToRads,this),this.or=PropertyFactory.getProp(t,e.or,0,0,this),this.os=PropertyFactory.getProp(t,e.os,0,.01,this),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}return t.prototype={reset:r,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,i,r,s=2*Math.floor(this.pt.v),a=2*Math.PI/s,n=!0,o=this.or.v,h=this.ir.v,l=this.os.v,p=this.is.v,f=2*Math.PI*o/(2*s),m=2*Math.PI*h/(2*s),c=-Math.PI/2;c+=this.r.v;var u=3===this.data.d?-1:1;for(this.v._length=0,t=0;t<s;t+=1){i=n?l:p,r=n?f:m;var d=(e=n?o:h)*Math.cos(c),y=e*Math.sin(c),g=0===d&&0===y?0:y/Math.sqrt(d*d+y*y),v=0===d&&0===y?0:-d/Math.sqrt(d*d+y*y);d+=+this.p.v[0],y+=+this.p.v[1],this.v.setTripleAt(d,y,d-g*r*i*u,y-v*r*i*u,d+g*r*i*u,y+v*r*i*u,t,!0),n=!n,c+=a*u}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),i=2*Math.PI/e,r=this.or.v,s=this.os.v,a=2*Math.PI*r/(4*e),n=.5*-Math.PI,o=3===this.data.d?-1:1;for(n+=this.r.v,this.v._length=0,t=0;t<e;t+=1){var h=r*Math.cos(n),l=r*Math.sin(n),p=0===h&&0===l?0:l/Math.sqrt(h*h+l*l),f=0===h&&0===l?0:-h/Math.sqrt(h*h+l*l);h+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(h,l,h-p*a*s*o,l-f*a*s*o,h+p*a*s*o,l+f*a*s*o,t,!0),n+=i*o}this.paths.length=0,this.paths[0]=this.v}},extendPrototype([DynamicPropertyContainer],t),t}(),f=function(){function t(t,e){this.v=shapePool.newElement(),this.v.c=!0,this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}return t.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,r=this.s.v[1]/2,s=bmMin(i,r,this.r.v),a=s*(1-roundCorner);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+s,t+i,e-r+a,0,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-a,t+i,e+r-s,1,!0),0!==s?(this.v.setTripleAt(t+i-s,e+r,t+i-s,e+r,t+i-a,e+r,2,!0),this.v.setTripleAt(t-i+s,e+r,t-i+a,e+r,t-i+s,e+r,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-s,t-i,e+r-a,4,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+a,t-i,e-r+s,5,!0),this.v.setTripleAt(t-i+s,e-r,t-i+s,e-r,t-i+a,e-r,6,!0),this.v.setTripleAt(t+i-s,e-r,t+i-a,e-r,t+i-s,e-r,7,!0)):(this.v.setTripleAt(t-i,e+r,t-i+a,e+r,t-i,e+r,2),this.v.setTripleAt(t-i,e-r,t-i,e-r+a,t-i,e-r,3))):(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+a,t+i,e-r+s,0,!0),0!==s?(this.v.setTripleAt(t+i-s,e-r,t+i-s,e-r,t+i-a,e-r,1,!0),this.v.setTripleAt(t-i+s,e-r,t-i+a,e-r,t-i+s,e-r,2,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+s,t-i,e-r+a,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-a,t-i,e+r-s,4,!0),this.v.setTripleAt(t-i+s,e+r,t-i+s,e+r,t-i+a,e+r,5,!0),this.v.setTripleAt(t+i-s,e+r,t+i-a,e+r,t+i-s,e+r,6,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-s,t+i,e+r-a,7,!0)):(this.v.setTripleAt(t-i,e-r,t-i+a,e-r,t-i,e-r,1,!0),this.v.setTripleAt(t-i,e+r,t-i,e+r-a,t-i,e+r,2,!0),this.v.setTripleAt(t+i,e+r,t+i-a,e+r,t+i,e+r,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:r},extendPrototype([DynamicPropertyContainer],t),t}();var m={getShapeProp:function(t,e,i){var r;return 3===i||4===i?r=(3===i?e.pt:e.ks).k.length?new h(t,e,i):new n(t,e,i):5===i?r=new f(t,e):6===i?r=new l(t,e):7===i&&(r=new p(t,e)),r.k&&t.addDynamicProperty(r),r},getConstructorFunction:function(){return n},getKeyframedConstructorFunction:function(){return h}};return m}(),Matrix=function(){var t=Math.cos,e=Math.sin,i=Math.tan,r=Math.round;function s(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function a(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,-s,0,0,s,r,0,0,0,0,1,0,0,0,0,1)}function n(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(1,0,0,0,0,r,-s,0,0,s,r,0,0,0,0,1)}function o(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,0,s,0,0,1,0,0,-s,0,r,0,0,0,0,1)}function h(i){if(0===i)return this;var r=t(i),s=e(i);return this._t(r,-s,0,0,s,r,0,0,0,0,1,0,0,0,0,1)}function l(t,e){return this._t(1,e,t,1,0,0)}function p(t,e){return this.shear(i(t),i(e))}function f(r,s){var a=t(s),n=e(s);return this._t(a,n,0,0,-n,a,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,i(r),1,0,0,0,0,1,0,0,0,0,1)._t(a,-n,0,0,n,a,0,0,0,0,1,0,0,0,0,1)}function m(t,e,i){return i||0===i||(i=1),1===t&&1===e&&1===i?this:this._t(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1)}function c(t,e,i,r,s,a,n,o,h,l,p,f,m,c,u,d){return this.props[0]=t,this.props[1]=e,this.props[2]=i,this.props[3]=r,this.props[4]=s,this.props[5]=a,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=l,this.props[10]=p,this.props[11]=f,this.props[12]=m,this.props[13]=c,this.props[14]=u,this.props[15]=d,this}function u(t,e,i){return i=i||0,0!==t||0!==e||0!==i?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,i,1):this}function d(t,e,i,r,s,a,n,o,h,l,p,f,m,c,u,d){var y=this.props;if(1===t&&0===e&&0===i&&0===r&&0===s&&1===a&&0===n&&0===o&&0===h&&0===l&&1===p&&0===f)return y[12]=y[12]*t+y[15]*m,y[13]=y[13]*a+y[15]*c,y[14]=y[14]*p+y[15]*u,y[15]*=d,this._identityCalculated=!1,this;var g=y[0],v=y[1],b=y[2],P=y[3],E=y[4],x=y[5],S=y[6],_=y[7],A=y[8],M=y[9],T=y[10],k=y[11],D=y[12],F=y[13],C=y[14],I=y[15];return y[0]=g*t+v*s+b*h+P*m,y[1]=g*e+v*a+b*l+P*c,y[2]=g*i+v*n+b*p+P*u,y[3]=g*r+v*o+b*f+P*d,y[4]=E*t+x*s+S*h+_*m,y[5]=E*e+x*a+S*l+_*c,y[6]=E*i+x*n+S*p+_*u,y[7]=E*r+x*o+S*f+_*d,y[8]=A*t+M*s+T*h+k*m,y[9]=A*e+M*a+T*l+k*c,y[10]=A*i+M*n+T*p+k*u,y[11]=A*r+M*o+T*f+k*d,y[12]=D*t+F*s+C*h+I*m,y[13]=D*e+F*a+C*l+I*c,y[14]=D*i+F*n+C*p+I*u,y[15]=D*r+F*o+C*f+I*d,this._identityCalculated=!1,this}function y(t){var e=t.props;return this.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}function g(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function v(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function b(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function P(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function E(t,e,i){return{x:t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}}function x(t,e,i){return t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12]}function S(t,e,i){return t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13]}function _(t,e,i){return t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}function A(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,i=-this.props[1]/t,r=-this.props[4]/t,s=this.props[0]/t,a=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,n=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,o=new Matrix;return o.props[0]=e,o.props[1]=i,o.props[4]=r,o.props[5]=s,o.props[12]=a,o.props[13]=n,o}function M(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function T(t){var e,i=t.length,r=[];for(e=0;e<i;e+=1)r[e]=M(t[e]);return r}function k(t,e,i){var r=createTypedArray("float32",6);if(this.isIdentity())r[0]=t[0],r[1]=t[1],r[2]=e[0],r[3]=e[1],r[4]=i[0],r[5]=i[1];else{var s=this.props[0],a=this.props[1],n=this.props[4],o=this.props[5],h=this.props[12],l=this.props[13];r[0]=t[0]*s+t[1]*n+h,r[1]=t[0]*a+t[1]*o+l,r[2]=e[0]*s+e[1]*n+h,r[3]=e[0]*a+e[1]*o+l,r[4]=i[0]*s+i[1]*n+h,r[5]=i[0]*a+i[1]*o+l}return r}function D(t,e,i){return this.isIdentity()?[t,e,i]:[t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]]}function F(t,e){if(this.isIdentity())return t+","+e;var i=this.props;return Math.round(100*(t*i[0]+e*i[4]+i[12]))/100+","+Math.round(100*(t*i[1]+e*i[5]+i[13]))/100}function C(){for(var t=0,e=this.props,i="matrix3d(";t<16;)i+=r(1e4*e[t])/1e4,i+=15===t?")":",",t+=1;return i}function I(t){return t<1e-6&&t>0||t>-1e-6&&t<0?r(1e4*t)/1e4:t}function w(){var t=this.props;return"matrix("+I(t[0])+","+I(t[1])+","+I(t[4])+","+I(t[5])+","+I(t[12])+","+I(t[13])+")"}return function(){this.reset=s,this.rotate=a,this.rotateX=n,this.rotateY=o,this.rotateZ=h,this.skew=p,this.skewFromAxis=f,this.shear=l,this.scale=m,this.setTransform=c,this.translate=u,this.transform=d,this.multiply=y,this.applyToPoint=E,this.applyToX=x,this.applyToY=S,this.applyToZ=_,this.applyToPointArray=D,this.applyToTriplePoints=k,this.applyToPointStringified=F,this.toCSS=C,this.to2dCSS=w,this.clone=b,this.cloneFromProps=P,this.equals=v,this.inversePoints=T,this.inversePoint=M,this.getInverseMatrix=A,this._t=this.transform,this.isIdentity=g,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}}();function _typeof$3(t){return _typeof$3="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$3(t)}var lottie={},standalone="__[STANDALONE]__",animationData="__[ANIMATIONDATA]__",renderer="";function setLocation(t){setLocationHref(t)}function searchAnimations(){!0===standalone?animationManager.searchAnimations(animationData,standalone,renderer):animationManager.searchAnimations()}function setSubframeRendering(t){setSubframeEnabled(t)}function setPrefix(t){setIdPrefix(t)}function loadAnimation(t){return!0===standalone&&(t.animationData=JSON.parse(animationData)),animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":setDefaultCurveSegments(200);break;default:case"medium":setDefaultCurveSegments(50);break;case"low":setDefaultCurveSegments(10)}else!isNaN(t)&&t>1&&setDefaultCurveSegments(t);getDefaultCurveSegments()>=50?roundValues(!1):roundValues(!0)}function inBrowser(){return"undefined"!=typeof navigator}function installPlugin(t,e){"expressions"===t&&setExpressionsPlugin(e)}function getFactory(t){switch(t){case"propertyFactory":return PropertyFactory;case"shapePropertyFactory":return ShapePropertyFactory;case"matrix":return Matrix;default:return null}}function checkReady(){"complete"===document.readyState&&(clearInterval(readyStateCheckInterval),searchAnimations())}function getQueryVariable(t){for(var e=queryString.split("&"),i=0;i<e.length;i+=1){var r=e[i].split("=");if(decodeURIComponent(r[0])==t)return decodeURIComponent(r[1])}return null}lottie.play=animationManager.play,lottie.pause=animationManager.pause,lottie.setLocationHref=setLocation,lottie.togglePause=animationManager.togglePause,lottie.setSpeed=animationManager.setSpeed,lottie.setDirection=animationManager.setDirection,lottie.stop=animationManager.stop,lottie.searchAnimations=searchAnimations,lottie.registerAnimation=animationManager.registerAnimation,lottie.loadAnimation=loadAnimation,lottie.setSubframeRendering=setSubframeRendering,lottie.resize=animationManager.resize,lottie.goToAndStop=animationManager.goToAndStop,lottie.destroy=animationManager.destroy,lottie.setQuality=setQuality,lottie.inBrowser=inBrowser,lottie.installPlugin=installPlugin,lottie.freeze=animationManager.freeze,lottie.unfreeze=animationManager.unfreeze,lottie.setVolume=animationManager.setVolume,lottie.mute=animationManager.mute,lottie.unmute=animationManager.unmute,lottie.getRegisteredAnimations=animationManager.getRegisteredAnimations,lottie.useWebWorker=setWebWorker,lottie.setIDPrefix=setPrefix,lottie.__getFactory=getFactory,lottie.version="5.13.0";var queryString="";if(standalone){var scripts=document.getElementsByTagName("script"),index=scripts.length-1,myScript=scripts[index]||{src:""};queryString=myScript.src?myScript.src.replace(/^[^\?]+\??/,""):"",renderer=getQueryVariable("renderer")}var readyStateCheckInterval=setInterval(checkReady,100);try{"object"===("undefined"==typeof exports?"undefined":_typeof$3(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=lottie)}catch(t){}var ShapeModifiers=function(){var t={},e={};return t.registerModifier=function(t,i){e[t]||(e[t]=i)},t.getModifier=function(t,i,r){return new e[t](i,r)},t}();function ShapeModifier(){}function TrimModifier(){}function PuckerAndBloatModifier(){}ShapeModifier.prototype.initModifierProperties=function(){},ShapeModifier.prototype.addShapeToModifier=function(){},ShapeModifier.prototype.addShape=function(t){if(!this.closed){t.sh.container.addDynamicProperty(t.sh);var e={shape:t.sh,data:t,localShapeCollection:shapeCollectionPool.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},ShapeModifier.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=initialDefaultFrame,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},ShapeModifier.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},extendPrototype([DynamicPropertyContainer],ShapeModifier),extendPrototype([ShapeModifier],TrimModifier),TrimModifier.prototype.initModifierProperties=function(t,e){this.s=PropertyFactory.getProp(t,e.s,0,.01,this),this.e=PropertyFactory.getProp(t,e.e,0,.01,this),this.o=PropertyFactory.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},TrimModifier.prototype.addShapeToModifier=function(t){t.pathsData=[]},TrimModifier.prototype.calculateShapeEdges=function(t,e,i,r,s){var a=[];e<=1?a.push({s:t,e:e}):t>=1?a.push({s:t-1,e:e-1}):(a.push({s:t,e:1}),a.push({s:0,e:e-1}));var n,o,h=[],l=a.length;for(n=0;n<l;n+=1){var p,f;if(!((o=a[n]).e*s<r||o.s*s>r+i))p=o.s*s<=r?0:(o.s*s-r)/i,f=o.e*s>=r+i?1:(o.e*s-r)/i,h.push([p,f])}return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){var e,i=t.length;for(e=0;e<i;e+=1)segmentsLengthPool.release(t[e]);return t.length=0,t},TrimModifier.prototype.processShapes=function(t){var e,i,r,s;if(this._mdf||t){var a=this.o.v%360/360;if(a<0&&(a+=1),(e=this.s.v>1?1+a:this.s.v<0?0+a:this.s.v+a)>(i=this.e.v>1?1+a:this.e.v<0?0+a:this.e.v+a)){var n=e;e=i,i=n}e=1e-4*Math.round(1e4*e),i=1e-4*Math.round(1e4*i),this.sValue=e,this.eValue=i}else e=this.sValue,i=this.eValue;var o,h,l,p,f,m=this.shapes.length,c=0;if(i===e)for(s=0;s<m;s+=1)this.shapes[s].localShapeCollection.releaseShapes(),this.shapes[s].shape._mdf=!0,this.shapes[s].shape.paths=this.shapes[s].localShapeCollection,this._mdf&&(this.shapes[s].pathsData.length=0);else if(1===i&&0===e||0===i&&1===e){if(this._mdf)for(s=0;s<m;s+=1)this.shapes[s].pathsData.length=0,this.shapes[s].shape._mdf=!0}else{var u,d,y=[];for(s=0;s<m;s+=1)if((u=this.shapes[s]).shape._mdf||this._mdf||t||2===this.m){if(h=(r=u.shape.paths)._length,f=0,!u.shape._mdf&&u.pathsData.length)f=u.totalShapeLength;else{for(l=this.releasePathsData(u.pathsData),o=0;o<h;o+=1)p=bez.getSegmentsLength(r.shapes[o]),l.push(p),f+=p.totalLength;u.totalShapeLength=f,u.pathsData=l}c+=f,u.shape._mdf=!0}else u.shape.paths=u.localShapeCollection;var g,v=e,b=i,P=0;for(s=m-1;s>=0;s-=1)if((u=this.shapes[s]).shape._mdf){for((d=u.localShapeCollection).releaseShapes(),2===this.m&&m>1?(g=this.calculateShapeEdges(e,i,u.totalShapeLength,P,c),P+=u.totalShapeLength):g=[[v,b]],h=g.length,o=0;o<h;o+=1){v=g[o][0],b=g[o][1],y.length=0,b<=1?y.push({s:u.totalShapeLength*v,e:u.totalShapeLength*b}):v>=1?y.push({s:u.totalShapeLength*(v-1),e:u.totalShapeLength*(b-1)}):(y.push({s:u.totalShapeLength*v,e:u.totalShapeLength}),y.push({s:0,e:u.totalShapeLength*(b-1)}));var E=this.addShapes(u,y[0]);if(y[0].s!==y[0].e){if(y.length>1)if(u.shape.paths.shapes[u.shape.paths._length-1].c){var x=E.pop();this.addPaths(E,d),E=this.addShapes(u,y[1],x)}else this.addPaths(E,d),E=this.addShapes(u,y[1]);this.addPaths(E,d)}}u.shape.paths=d}}},TrimModifier.prototype.addPaths=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)e.addShape(t[i])},TrimModifier.prototype.addSegment=function(t,e,i,r,s,a,n){s.setXYAt(e[0],e[1],"o",a),s.setXYAt(i[0],i[1],"i",a+1),n&&s.setXYAt(t[0],t[1],"v",a),s.setXYAt(r[0],r[1],"v",a+1)},TrimModifier.prototype.addSegmentFromArray=function(t,e,i,r){e.setXYAt(t[1],t[5],"o",i),e.setXYAt(t[2],t[6],"i",i+1),r&&e.setXYAt(t[0],t[4],"v",i),e.setXYAt(t[3],t[7],"v",i+1)},TrimModifier.prototype.addShapes=function(t,e,i){var r,s,a,n,o,h,l,p,f=t.pathsData,m=t.shape.paths.shapes,c=t.shape.paths._length,u=0,d=[],y=!0;for(i?(o=i._length,p=i._length):(i=shapePool.newElement(),o=0,p=0),d.push(i),r=0;r<c;r+=1){for(h=f[r].lengths,i.c=m[r].c,a=m[r].c?h.length:h.length+1,s=1;s<a;s+=1)if(u+(n=h[s-1]).addedLength<e.s)u+=n.addedLength,i.c=!1;else{if(u>e.e){i.c=!1;break}e.s<=u&&e.e>=u+n.addedLength?(this.addSegment(m[r].v[s-1],m[r].o[s-1],m[r].i[s],m[r].v[s],i,o,y),y=!1):(l=bez.getNewSegment(m[r].v[s-1],m[r].v[s],m[r].o[s-1],m[r].i[s],(e.s-u)/n.addedLength,(e.e-u)/n.addedLength,h[s-1]),this.addSegmentFromArray(l,i,o,y),y=!1,i.c=!1),u+=n.addedLength,o+=1}if(m[r].c&&h.length){if(n=h[s-1],u<=e.e){var g=h[s-1].addedLength;e.s<=u&&e.e>=u+g?(this.addSegment(m[r].v[s-1],m[r].o[s-1],m[r].i[0],m[r].v[0],i,o,y),y=!1):(l=bez.getNewSegment(m[r].v[s-1],m[r].v[0],m[r].o[s-1],m[r].i[0],(e.s-u)/g,(e.e-u)/g,h[s-1]),this.addSegmentFromArray(l,i,o,y),y=!1,i.c=!1)}else i.c=!1;u+=n.addedLength,o+=1}if(i._length&&(i.setXYAt(i.v[p][0],i.v[p][1],"i",p),i.setXYAt(i.v[i._length-1][0],i.v[i._length-1][1],"o",i._length-1)),u>e.e)break;r<c-1&&(i=shapePool.newElement(),y=!0,d.push(i),o=0)}return d},extendPrototype([ShapeModifier],PuckerAndBloatModifier),PuckerAndBloatModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},PuckerAndBloatModifier.prototype.processPath=function(t,e){var i=e/100,r=[0,0],s=t._length,a=0;for(a=0;a<s;a+=1)r[0]+=t.v[a][0],r[1]+=t.v[a][1];r[0]/=s,r[1]/=s;var n,o,h,l,p,f,m=shapePool.newElement();for(m.c=t.c,a=0;a<s;a+=1)n=t.v[a][0]+(r[0]-t.v[a][0])*i,o=t.v[a][1]+(r[1]-t.v[a][1])*i,h=t.o[a][0]+(r[0]-t.o[a][0])*-i,l=t.o[a][1]+(r[1]-t.o[a][1])*-i,p=t.i[a][0]+(r[0]-t.i[a][0])*-i,f=t.i[a][1]+(r[1]-t.i[a][1])*-i,m.setTripleAt(n,o,h,l,p,f,a);return m},PuckerAndBloatModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amount.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var TransformPropertyFactory=function(){var t=[0,0];function e(t,e,i){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Matrix,this.pre=new Matrix,this.appliedTransformations=0,this.initDynamicPropertyContainer(i||t),e.p&&e.p.s?(this.px=PropertyFactory.getProp(t,e.p.x,0,0,this),this.py=PropertyFactory.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=PropertyFactory.getProp(t,e.p.z,0,0,this))):this.p=PropertyFactory.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=PropertyFactory.getProp(t,e.rx,0,degToRads,this),this.ry=PropertyFactory.getProp(t,e.ry,0,degToRads,this),this.rz=PropertyFactory.getProp(t,e.rz,0,degToRads,this),e.or.k[0].ti){var r,s=e.or.k.length;for(r=0;r<s;r+=1)e.or.k[r].to=null,e.or.k[r].ti=null}this.or=PropertyFactory.getProp(t,e.or,1,degToRads,this),this.or.sh=!0}else this.r=PropertyFactory.getProp(t,e.r||{k:0},0,degToRads,this);e.sk&&(this.sk=PropertyFactory.getProp(t,e.sk,0,degToRads,this),this.sa=PropertyFactory.getProp(t,e.sa,0,degToRads,this)),this.a=PropertyFactory.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=PropertyFactory.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=PropertyFactory.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return e.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(e){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||e){var i;if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var r,s;if(i=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime)this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(r=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/i,0),s=this.p.getValueAtTime(this.p.keyframes[0].t/i,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(r=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/i,0),s=this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/i,0)):(r=this.p.pv,s=this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/i,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){r=[],s=[];var a=this.px,n=this.py;a._caching.lastFrame+a.offsetTime<=a.keyframes[0].t?(r[0]=a.getValueAtTime((a.keyframes[0].t+.01)/i,0),r[1]=n.getValueAtTime((n.keyframes[0].t+.01)/i,0),s[0]=a.getValueAtTime(a.keyframes[0].t/i,0),s[1]=n.getValueAtTime(n.keyframes[0].t/i,0)):a._caching.lastFrame+a.offsetTime>=a.keyframes[a.keyframes.length-1].t?(r[0]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/i,0),r[1]=n.getValueAtTime(n.keyframes[n.keyframes.length-1].t/i,0),s[0]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/i,0),s[1]=n.getValueAtTime((n.keyframes[n.keyframes.length-1].t-.01)/i,0)):(r=[a.pv,n.pv],s[0]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/i,a.offsetTime),s[1]=n.getValueAtTime((n._caching.lastFrame+n.offsetTime-.01)/i,n.offsetTime))}else r=s=t;this.v.rotate(-Math.atan2(r[1]-s[1],r[0]-s[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],e),e.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},e.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,i,r){return new e(t,i,r)}}}();function RepeaterModifier(){}function RoundCornersModifier(){}function floatEqual(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function floatZero(t){return Math.abs(t)<=1e-5}function lerp(t,e,i){return t*(1-i)+e*i}function lerpPoint(t,e,i){return[lerp(t[0],e[0],i),lerp(t[1],e[1],i)]}function quadRoots(t,e,i){if(0===t)return[];var r=e*e-4*t*i;if(r<0)return[];var s=-e/(2*t);if(0===r)return[s];var a=Math.sqrt(r)/(2*t);return[s-a,s+a]}function polynomialCoefficients(t,e,i,r){return[3*e-t-3*i+r,3*t-6*e+3*i,-3*t+3*e,t]}function singlePoint(t){return new PolynomialBezier(t,t,t,t,!1)}function PolynomialBezier(t,e,i,r,s){s&&pointEqual(t,e)&&(e=lerpPoint(t,r,1/3)),s&&pointEqual(i,r)&&(i=lerpPoint(t,r,2/3));var a=polynomialCoefficients(t[0],e[0],i[0],r[0]),n=polynomialCoefficients(t[1],e[1],i[1],r[1]);this.a=[a[0],n[0]],this.b=[a[1],n[1]],this.c=[a[2],n[2]],this.d=[a[3],n[3]],this.points=[t,e,i,r]}function extrema(t,e){var i=t.points[0][e],r=t.points[t.points.length-1][e];if(i>r){var s=r;r=i,i=s}for(var a=quadRoots(3*t.a[e],2*t.b[e],t.c[e]),n=0;n<a.length;n+=1)if(a[n]>0&&a[n]<1){var o=t.point(a[n])[e];o<i?i=o:o>r&&(r=o)}return{min:i,max:r}}function intersectData(t,e,i){var r=t.boundingBox();return{cx:r.cx,cy:r.cy,width:r.width,height:r.height,bez:t,t:(e+i)/2,t1:e,t2:i}}function splitData(t){var e=t.bez.split(.5);return[intersectData(e[0],t.t1,t.t),intersectData(e[1],t.t,t.t2)]}function boxIntersect(t,e){return 2*Math.abs(t.cx-e.cx)<t.width+e.width&&2*Math.abs(t.cy-e.cy)<t.height+e.height}function intersectsImpl(t,e,i,r,s,a){if(boxIntersect(t,e))if(i>=a||t.width<=r&&t.height<=r&&e.width<=r&&e.height<=r)s.push([t.t,e.t]);else{var n=splitData(t),o=splitData(e);intersectsImpl(n[0],o[0],i+1,r,s,a),intersectsImpl(n[0],o[1],i+1,r,s,a),intersectsImpl(n[1],o[0],i+1,r,s,a),intersectsImpl(n[1],o[1],i+1,r,s,a)}}function crossProduct(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function lineIntersection(t,e,i,r){var s=[t[0],t[1],1],a=[e[0],e[1],1],n=[i[0],i[1],1],o=[r[0],r[1],1],h=crossProduct(crossProduct(s,a),crossProduct(n,o));return floatZero(h[2])?null:[h[0]/h[2],h[1]/h[2]]}function polarOffset(t,e,i){return[t[0]+Math.cos(e)*i,t[1]-Math.sin(e)*i]}function pointDistance(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function pointEqual(t,e){return floatEqual(t[0],e[0])&&floatEqual(t[1],e[1])}function ZigZagModifier(){}function setPoint(t,e,i,r,s,a,n){var o=i-Math.PI/2,h=i+Math.PI/2,l=e[0]+Math.cos(i)*r*s,p=e[1]-Math.sin(i)*r*s;t.setTripleAt(l,p,l+Math.cos(o)*a,p-Math.sin(o)*a,l+Math.cos(h)*n,p-Math.sin(h)*n,t.length())}function getPerpendicularVector(t,e){var i=[e[0]-t[0],e[1]-t[1]],r=.5*-Math.PI;return[Math.cos(r)*i[0]-Math.sin(r)*i[1],Math.sin(r)*i[0]+Math.cos(r)*i[1]]}function getProjectingAngle(t,e){var i=0===e?t.length()-1:e-1,r=(e+1)%t.length(),s=getPerpendicularVector(t.v[i],t.v[r]);return Math.atan2(0,1)-Math.atan2(s[1],s[0])}function zigZagCorner(t,e,i,r,s,a,n){var o=getProjectingAngle(e,i),h=e.v[i%e._length],l=e.v[0===i?e._length-1:i-1],p=e.v[(i+1)%e._length],f=2===a?Math.sqrt(Math.pow(h[0]-l[0],2)+Math.pow(h[1]-l[1],2)):0,m=2===a?Math.sqrt(Math.pow(h[0]-p[0],2)+Math.pow(h[1]-p[1],2)):0;setPoint(t,e.v[i%e._length],o,n,r,m/(2*(s+1)),f/(2*(s+1)),a)}function zigZagSegment(t,e,i,r,s,a){for(var n=0;n<r;n+=1){var o=(n+1)/(r+1),h=2===s?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(o);setPoint(t,e.point(o),l,a,i,h/(2*(r+1)),h/(2*(r+1)),s),a=-a}return a}function linearOffset(t,e,i){var r=Math.atan2(e[0]-t[0],e[1]-t[1]);return[polarOffset(t,r,i),polarOffset(e,r,i)]}function offsetSegment(t,e){var i,r,s,a,n,o,h;i=(h=linearOffset(t.points[0],t.points[1],e))[0],r=h[1],s=(h=linearOffset(t.points[1],t.points[2],e))[0],a=h[1],n=(h=linearOffset(t.points[2],t.points[3],e))[0],o=h[1];var l=lineIntersection(i,r,s,a);null===l&&(l=r);var p=lineIntersection(n,o,s,a);return null===p&&(p=n),new PolynomialBezier(i,l,p,o)}function joinLines(t,e,i,r,s){var a=e.points[3],n=i.points[0];if(3===r)return a;if(pointEqual(a,n))return a;if(2===r){var o=-e.tangentAngle(1),h=-i.tangentAngle(0)+Math.PI,l=lineIntersection(a,polarOffset(a,o+Math.PI/2,100),n,polarOffset(n,o+Math.PI/2,100)),p=l?pointDistance(l,a):pointDistance(a,n)/2,f=polarOffset(a,o,2*p*roundCorner);return t.setXYAt(f[0],f[1],"o",t.length()-1),f=polarOffset(n,h,2*p*roundCorner),t.setTripleAt(n[0],n[1],n[0],n[1],f[0],f[1],t.length()),n}var m=lineIntersection(pointEqual(a,e.points[2])?e.points[0]:e.points[2],a,n,pointEqual(n,i.points[1])?i.points[3]:i.points[1]);return m&&pointDistance(m,a)<s?(t.setTripleAt(m[0],m[1],m[0],m[1],m[0],m[1],t.length()),m):a}function getIntersection(t,e){var i=t.intersections(e);return i.length&&floatEqual(i[0][0],1)&&i.shift(),i.length?i[0]:null}function pruneSegmentIntersection(t,e){var i=t.slice(),r=e.slice(),s=getIntersection(t[t.length-1],e[0]);return s&&(i[t.length-1]=t[t.length-1].split(s[0])[0],r[0]=e[0].split(s[1])[1]),t.length>1&&e.length>1&&(s=getIntersection(t[0],e[e.length-1]))?[[t[0].split(s[0])[0]],[e[e.length-1].split(s[1])[1]]]:[i,r]}function pruneIntersections(t){for(var e,i=1;i<t.length;i+=1)e=pruneSegmentIntersection(t[i-1],t[i]),t[i-1]=e[0],t[i]=e[1];return t.length>1&&(e=pruneSegmentIntersection(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}function offsetSegmentSplit(t,e){var i,r,s,a,n=t.inflectionPoints();if(0===n.length)return[offsetSegment(t,e)];if(1===n.length||floatEqual(n[1],1))return i=(s=t.split(n[0]))[0],r=s[1],[offsetSegment(i,e),offsetSegment(r,e)];i=(s=t.split(n[0]))[0];var o=(n[1]-n[0])/(1-n[0]);return a=(s=s[1].split(o))[0],r=s[1],[offsetSegment(i,e),offsetSegment(a,e),offsetSegment(r,e)]}function OffsetPathModifier(){}function getFontProperties(t){for(var e=t.fStyle?t.fStyle.split(" "):[],i="normal",r="normal",s=e.length,a=0;a<s;a+=1)switch(e[a].toLowerCase()){case"italic":r="italic";break;case"bold":i="700";break;case"black":i="900";break;case"medium":i="500";break;case"regular":case"normal":i="400";break;case"light":case"thin":i="200"}return{style:r,weight:t.fWeight||i}}extendPrototype([ShapeModifier],RepeaterModifier),RepeaterModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=PropertyFactory.getProp(t,e.c,0,null,this),this.o=PropertyFactory.getProp(t,e.o,0,null,this),this.tr=TransformPropertyFactory.getTransformProperty(t,e.tr,this),this.so=PropertyFactory.getProp(t,e.tr.so,0,.01,this),this.eo=PropertyFactory.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Matrix,this.rMatrix=new Matrix,this.sMatrix=new Matrix,this.tMatrix=new Matrix,this.matrix=new Matrix},RepeaterModifier.prototype.applyTransforms=function(t,e,i,r,s,a){var n=a?-1:1,o=r.s.v[0]+(1-r.s.v[0])*(1-s),h=r.s.v[1]+(1-r.s.v[1])*(1-s);t.translate(r.p.v[0]*n*s,r.p.v[1]*n*s,r.p.v[2]),e.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),e.rotate(-r.r.v*n*s),e.translate(r.a.v[0],r.a.v[1],r.a.v[2]),i.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),i.scale(a?1/o:o,a?1/h:h),i.translate(r.a.v[0],r.a.v[1],r.a.v[2])},RepeaterModifier.prototype.init=function(t,e,i,r){for(this.elem=t,this.arr=e,this.pos=i,this.elemsData=r,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[i]);i>0;)i-=1,this._elements.unshift(e[i]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},RepeaterModifier.prototype.cloneElements=function(t){var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},RepeaterModifier.prototype.changeGroupRender=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)t[i]._render=e,"gr"===t[i].ty&&this.changeGroupRender(t[i].it,e)},RepeaterModifier.prototype.processShapes=function(t){var e,i,r,s,a,n=!1;if(this._mdf||t){var o,h=Math.ceil(this.c.v);if(this._groups.length<h){for(;this._groups.length<h;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(a=0,r=0;r<=this._groups.length-1;r+=1){if(o=a<h,this._groups[r]._render=o,this.changeGroupRender(this._groups[r].it,o),!o){var p=this.elemsData[r].it,f=p[p.length-1];0!==f.transform.op.v?(f.transform.op._mdf=!0,f.transform.op.v=0):f.transform.op._mdf=!1}a+=1}this._currentCopies=h;var m=this.o.v,c=m%1,u=m>0?Math.floor(m):Math.ceil(m),d=this.pMatrix.props,y=this.rMatrix.props,g=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var v,b,P=0;if(m>0){for(;P<u;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),P+=1;c&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,c,!1),P+=c)}else if(m<0){for(;P>u;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),P-=1;c&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-c,!0),P-=c)}for(r=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(b=(i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(r/(this._currentCopies-1)),0!==P){for((0!==r&&1===s||r!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]),this.matrix.transform(d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9],d[10],d[11],d[12],d[13],d[14],d[15]),v=0;v<b;v+=1)i[v]=this.matrix.props[v];this.matrix.reset()}else for(this.matrix.reset(),v=0;v<b;v+=1)i[v]=this.matrix.props[v];P+=1,a-=1,r+=s}}else for(a=this._currentCopies,r=0,s=1;a;)i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,a-=1,r+=s;return n},RepeaterModifier.prototype.addShape=function(){},extendPrototype([ShapeModifier],RoundCornersModifier),RoundCornersModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=PropertyFactory.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},RoundCornersModifier.prototype.processPath=function(t,e){var i,r=shapePool.newElement();r.c=t.c;var s,a,n,o,h,l,p,f,m,c,u,d,y=t._length,g=0;for(i=0;i<y;i+=1)s=t.v[i],n=t.o[i],a=t.i[i],s[0]===n[0]&&s[1]===n[1]&&s[0]===a[0]&&s[1]===a[1]?0!==i&&i!==y-1||t.c?(o=0===i?t.v[y-1]:t.v[i-1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=u=s[0]+(o[0]-s[0])*l,f=d=s[1]-(s[1]-o[1])*l,m=p-(p-s[0])*roundCorner,c=f-(f-s[1])*roundCorner,r.setTripleAt(p,f,m,c,u,d,g),g+=1,o=i===y-1?t.v[0]:t.v[i+1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=m=s[0]+(o[0]-s[0])*l,f=c=s[1]+(o[1]-s[1])*l,u=p-(p-s[0])*roundCorner,d=f-(f-s[1])*roundCorner,r.setTripleAt(p,f,m,c,u,d,g),g+=1):(r.setTripleAt(s[0],s[1],n[0],n[1],a[0],a[1],g),g+=1):(r.setTripleAt(t.v[i][0],t.v[i][1],t.o[i][0],t.o[i][1],t.i[i][0],t.i[i][1],g),g+=1);return r},RoundCornersModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},PolynomialBezier.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},PolynomialBezier.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},PolynomialBezier.prototype.tangentAngle=function(t){var e=this.derivative(t);return Math.atan2(e[1],e[0])},PolynomialBezier.prototype.normalAngle=function(t){var e=this.derivative(t);return Math.atan2(e[0],e[1])},PolynomialBezier.prototype.inflectionPoints=function(){var t=this.a[1]*this.b[0]-this.a[0]*this.b[1];if(floatZero(t))return[];var e=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/t,i=e*e-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/t;if(i<0)return[];var r=Math.sqrt(i);return floatZero(r)?r>0&&r<1?[e]:[]:[e-r,e+r].filter((function(t){return t>0&&t<1}))},PolynomialBezier.prototype.split=function(t){if(t<=0)return[singlePoint(this.points[0]),this];if(t>=1)return[this,singlePoint(this.points[this.points.length-1])];var e=lerpPoint(this.points[0],this.points[1],t),i=lerpPoint(this.points[1],this.points[2],t),r=lerpPoint(this.points[2],this.points[3],t),s=lerpPoint(e,i,t),a=lerpPoint(i,r,t),n=lerpPoint(s,a,t);return[new PolynomialBezier(this.points[0],e,s,n,!0),new PolynomialBezier(n,a,r,this.points[3],!0)]},PolynomialBezier.prototype.bounds=function(){return{x:extrema(this,0),y:extrema(this,1)}},PolynomialBezier.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},PolynomialBezier.prototype.intersections=function(t,e,i){void 0===e&&(e=2),void 0===i&&(i=7);var r=[];return intersectsImpl(intersectData(this,0,1),intersectData(t,0,1),0,e,r,i),r},PolynomialBezier.shapeSegment=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[e],t.o[e],t.i[i],t.v[i],!0)},PolynomialBezier.shapeSegmentInverted=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[i],t.i[i],t.o[e],t.v[e],!0)},extendPrototype([ShapeModifier],ZigZagModifier),ZigZagModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=PropertyFactory.getProp(t,e.s,0,null,this),this.frequency=PropertyFactory.getProp(t,e.r,0,null,this),this.pointsType=PropertyFactory.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},ZigZagModifier.prototype.processPath=function(t,e,i,r){var s=t._length,a=shapePool.newElement();if(a.c=t.c,t.c||(s-=1),0===s)return a;var n=-1,o=PolynomialBezier.shapeSegment(t,0);zigZagCorner(a,t,0,e,i,r,n);for(var h=0;h<s;h+=1)n=zigZagSegment(a,o,e,i,r,-n),o=h!==s-1||t.c?PolynomialBezier.shapeSegment(t,(h+1)%s):null,zigZagCorner(a,t,h+1,e,i,r,n);return a},ZigZagModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amplitude.v,l=Math.max(0,Math.round(this.frequency.v)),p=this.pointsType.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h,l,p));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},extendPrototype([ShapeModifier],OffsetPathModifier),OffsetPathModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this.miterLimit=PropertyFactory.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},OffsetPathModifier.prototype.processPath=function(t,e,i,r){var s=shapePool.newElement();s.c=t.c;var a,n,o,h=t.length();t.c||(h-=1);var l=[];for(a=0;a<h;a+=1)o=PolynomialBezier.shapeSegment(t,a),l.push(offsetSegmentSplit(o,e));if(!t.c)for(a=h-1;a>=0;a-=1)o=PolynomialBezier.shapeSegmentInverted(t,a),l.push(offsetSegmentSplit(o,e));l=pruneIntersections(l);var p=null,f=null;for(a=0;a<l.length;a+=1){var m=l[a];for(f&&(p=joinLines(s,f,m[0],i,r)),f=m[m.length-1],n=0;n<m.length;n+=1)o=m[n],p&&pointEqual(o.points[0],p)?s.setXYAt(o.points[1][0],o.points[1][1],"o",s.length()-1):s.setTripleAt(o.points[0][0],o.points[0][1],o.points[1][0],o.points[1][1],o.points[0][0],o.points[0][1],s.length()),s.setTripleAt(o.points[3][0],o.points[3][1],o.points[3][0],o.points[3][1],o.points[2][0],o.points[2][1],s.length()),p=o.points[3]}return l.length&&joinLines(s,f,l[0][0],i,r),s},OffsetPathModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amount.v,l=this.miterLimit.v,p=this.lineJoin;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h,p,l));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var FontManager=function(){var t={w:0,size:0,shapes:[],data:{shapes:[]}},e=[];e=e.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);var i=127988,r=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function s(t,e){var i=createTag("span");i.setAttribute("aria-hidden",!0),i.style.fontFamily=e;var r=createTag("span");r.innerText="giItT1WQy@!-/#",i.style.position="absolute",i.style.left="-10000px",i.style.top="-10000px",i.style.fontSize="300px",i.style.fontVariant="normal",i.style.fontStyle="normal",i.style.fontWeight="normal",i.style.letterSpacing="0",i.appendChild(r),document.body.appendChild(i);var s=r.offsetWidth;return r.style.fontFamily=function(t){var e,i=t.split(","),r=i.length,s=[];for(e=0;e<r;e+=1)"sans-serif"!==i[e]&&"monospace"!==i[e]&&s.push(i[e]);return s.join(",")}(t)+", "+e,{node:r,w:s,parent:i}}function a(t,e){var i,r=document.body&&e?"svg":"canvas",s=getFontProperties(t);if("svg"===r){var a=createNS("text");a.style.fontSize="100px",a.setAttribute("font-family",t.fFamily),a.setAttribute("font-style",s.style),a.setAttribute("font-weight",s.weight),a.textContent="1",t.fClass?(a.style.fontFamily="inherit",a.setAttribute("class",t.fClass)):a.style.fontFamily=t.fFamily,e.appendChild(a),i=a}else{var n=new OffscreenCanvas(500,500).getContext("2d");n.font=s.style+" "+s.weight+" 100px "+t.fFamily,i=n}return{measureText:function(t){return"svg"===r?(i.textContent=t,i.getComputedTextLength()):i.measureText(t).width}}}function n(t){var e=0,i=t.charCodeAt(0);if(i>=55296&&i<=56319){var r=t.charCodeAt(1);r>=56320&&r<=57343&&(e=1024*(i-55296)+r-56320+65536)}return e}function o(t){var e=n(t);return e>=127462&&e<=127487}var h=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)};h.isModifier=function(t,e){var i=t.toString(16)+e.toString(16);return-1!==r.indexOf(i)},h.isZeroWidthJoiner=function(t){return 8205===t},h.isFlagEmoji=function(t){return o(t.substr(0,2))&&o(t.substr(2,2))},h.isRegionalCode=o,h.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},h.isRegionalFlag=function(t,e){var r=n(t.substr(e,2));if(r!==i)return!1;var s=0;for(e+=2;s<5;){if((r=n(t.substr(e,2)))<917601||r>917626)return!1;s+=1,e+=2}return 917631===n(t.substr(e,2))},h.isVariationSelector=function(t){return 65039===t},h.BLACK_FLAG_CODE_POINT=i;var l={addChars:function(t){if(t){var e;this.chars||(this.chars=[]);var i,r,s=t.length,a=this.chars.length;for(e=0;e<s;e+=1){for(i=0,r=!1;i<a;)this.chars[i].style===t[e].style&&this.chars[i].fFamily===t[e].fFamily&&this.chars[i].ch===t[e].ch&&(r=!0),i+=1;r||(this.chars.push(t[e]),a+=1)}}},addFonts:function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);if(!document.body)return this.isLoaded=!0,t.list.forEach((function(t){t.helper=a(t),t.cache={}})),void(this.fonts=t.list);var i,r=t.list,n=r.length,o=n;for(i=0;i<n;i+=1){var h,l,p=!0;if(r[i].loaded=!1,r[i].monoCase=s(r[i].fFamily,"monospace"),r[i].sansCase=s(r[i].fFamily,"sans-serif"),r[i].fPath){if("p"===r[i].fOrigin||3===r[i].origin){if((h=document.querySelectorAll('style[f-forigin="p"][f-family="'+r[i].fFamily+'"], style[f-origin="3"][f-family="'+r[i].fFamily+'"]')).length>0&&(p=!1),p){var f=createTag("style");f.setAttribute("f-forigin",r[i].fOrigin),f.setAttribute("f-origin",r[i].origin),f.setAttribute("f-family",r[i].fFamily),f.type="text/css",f.innerText="@font-face {font-family: "+r[i].fFamily+"; font-style: normal; src: url('"+r[i].fPath+"');}",e.appendChild(f)}}else if("g"===r[i].fOrigin||1===r[i].origin){for(h=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),l=0;l<h.length;l+=1)-1!==h[l].href.indexOf(r[i].fPath)&&(p=!1);if(p){var m=createTag("link");m.setAttribute("f-forigin",r[i].fOrigin),m.setAttribute("f-origin",r[i].origin),m.type="text/css",m.rel="stylesheet",m.href=r[i].fPath,document.body.appendChild(m)}}else if("t"===r[i].fOrigin||2===r[i].origin){for(h=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),l=0;l<h.length;l+=1)r[i].fPath===h[l].src&&(p=!1);if(p){var c=createTag("link");c.setAttribute("f-forigin",r[i].fOrigin),c.setAttribute("f-origin",r[i].origin),c.setAttribute("rel","stylesheet"),c.setAttribute("href",r[i].fPath),e.appendChild(c)}}}else r[i].loaded=!0,o-=1;r[i].helper=a(r[i],e),r[i].cache={},this.fonts.push(r[i])}0===o?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},getCharData:function(e,i,r){for(var s=0,a=this.chars.length;s<a;){if(this.chars[s].ch===e&&this.chars[s].style===i&&this.chars[s].fFamily===r)return this.chars[s];s+=1}return("string"==typeof e&&13!==e.charCodeAt(0)||!e)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",e,i,r)),t},getFontByName:function(t){for(var e=0,i=this.fonts.length;e<i;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,i){var r=this.getFontByName(e),s=t;if(!r.cache[s]){var a=r.helper;if(" "===t){var n=a.measureText("|"+t+"|"),o=a.measureText("||");r.cache[s]=(n-o)/100}else r.cache[s]=a.measureText(t)/100}return r.cache[s]*i},checkLoadedFonts:function(){var t,e,i,r=this.fonts.length,s=r;for(t=0;t<r;t+=1)this.fonts[t].loaded?s-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,i=this.fonts[t].monoCase.w,e.offsetWidth!==i?(s-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,i=this.fonts[t].sansCase.w,e.offsetWidth!==i&&(s-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==s&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}};return h.prototype=l,h}();function SlotManager(t){this.animationData=t}function slotFactory(t){return new SlotManager(t)}function RenderableElement(){}SlotManager.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},RenderableElement.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var getBlendMode=(blendModeEnums={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return blendModeEnums[t]||""}),blendModeEnums;function SliderEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function AngleEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function ColorEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function PointEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function LayerIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function MaskIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function CheckboxEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function NoValueEffect(){this.p={}}function EffectsManager(t,e){var i,r=t.ef||[];this.effectElements=[];var s,a=r.length;for(i=0;i<a;i+=1)s=new GroupEffect(r[i],e),this.effectElements.push(s)}function GroupEffect(t,e){this.init(t,e)}function BaseElement(){}function FrameElement(){}function FootageElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,i)}function AudioElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,i),this._isPlaying=!1,this._canPlay=!1;var r=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(r),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=PropertyFactory.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function BaseRenderer(){}extendPrototype([DynamicPropertyContainer],GroupEffect),GroupEffect.prototype.getValue=GroupEffect.prototype.iterateDynamicProperties,GroupEffect.prototype.init=function(t,e){var i;this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var r,s=this.data.ef.length,a=this.data.ef;for(i=0;i<s;i+=1){switch(r=null,a[i].ty){case 0:r=new SliderEffect(a[i],e,this);break;case 1:r=new AngleEffect(a[i],e,this);break;case 2:r=new ColorEffect(a[i],e,this);break;case 3:r=new PointEffect(a[i],e,this);break;case 4:case 7:r=new CheckboxEffect(a[i],e,this);break;case 10:r=new LayerIndexEffect(a[i],e,this);break;case 11:r=new MaskIndexEffect(a[i],e,this);break;case 5:r=new EffectsManager(a[i],e,this);break;default:r=new NoValueEffect(a[i],e,this)}r&&this.effectElements.push(r)}},BaseElement.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t=getExpressionInterfaces();if(t){var e=t("layer"),i=t("effects"),r=t("shape"),s=t("text"),a=t("comp");this.layerInterface=e(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var n=i.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(n),0===this.data.ty||this.data.xt?this.compInterface=a(this):4===this.data.ty?(this.layerInterface.shapeInterface=r(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=s(this),this.layerInterface.text=this.layerInterface.textInterface)}},setBlendMode:function(){var t=getBlendMode(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,i){this.globalData=e,this.comp=i,this.data=t,this.layerId=createElementID(),this.data.sr||(this.data.sr=1),this.effectsManager=new EffectsManager(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},FrameElement.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var i,r=this.dynamicProperties.length;for(i=0;i<r;i+=1)(e||this._isParent&&"transform"===this.dynamicProperties[i].propType)&&(this.dynamicProperties[i].getValue(),this.dynamicProperties[i]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},FootageElement.prototype.prepareFrame=function(){},extendPrototype([RenderableElement,BaseElement,FrameElement],FootageElement),FootageElement.prototype.getBaseElement=function(){return null},FootageElement.prototype.renderFrame=function(){},FootageElement.prototype.destroy=function(){},FootageElement.prototype.initExpressions=function(){var t=getExpressionInterfaces();if(t){var e=t("footage");this.layerInterface=e(this)}},FootageElement.prototype.getFootageData=function(){return this.footageData},AudioElement.prototype.prepareFrame=function(t){if(this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder)this._currentTime=t/this.data.sr;else{var e=this.tm.v;this._currentTime=e}this._volume=this.lv.v[0];var i=this._volume*this._volumeMultiplier;this._previousVolume!==i&&(this._previousVolume=i,this.audio.volume(i))},extendPrototype([RenderableElement,BaseElement,FrameElement],AudioElement),AudioElement.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek())>.1)&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},AudioElement.prototype.show=function(){},AudioElement.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},AudioElement.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},AudioElement.prototype.resume=function(){this._canPlay=!0},AudioElement.prototype.setRate=function(t){this.audio.rate(t)},AudioElement.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},AudioElement.prototype.getBaseElement=function(){return null},AudioElement.prototype.destroy=function(){},AudioElement.prototype.sourceRectAtTime=function(){},AudioElement.prototype.initExpressions=function(){},BaseRenderer.prototype.checkLayers=function(t){var e,i,r=this.layers.length;for(this.completeLayers=!0,e=r-1;e>=0;e-=1)this.elements[e]||(i=this.layers[e]).ip-i.st<=t-this.layers[e].st&&i.op-i.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:default:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t)}},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.createAudio=function(t){return new AudioElement(t,this.globalData,this)},BaseRenderer.prototype.createFootage=function(t){return new FootageElement(t,this.globalData,this)},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},BaseRenderer.prototype.includeLayers=function(t){var e;this.completeLayers=!1;var i,r=t.length,s=this.layers.length;for(e=0;e<r;e+=1)for(i=0;i<s;){if(this.layers[i].id===t[e].id){this.layers[i]=t[e];break}i+=1}},BaseRenderer.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},BaseRenderer.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},BaseRenderer.prototype.buildElementParenting=function(t,e,i){for(var r=this.elements,s=this.layers,a=0,n=s.length;a<n;)s[a].ind==e&&(r[a]&&!0!==r[a]?(i.push(r[a]),r[a].setAsParent(),void 0!==s[a].parent?this.buildElementParenting(t,s[a].parent,i):t.setHierarchy(i)):(this.buildItem(a),this.addPendingElement(t))),a+=1},BaseRenderer.prototype.addPendingElement=function(t){this.pendingElements.push(t)},BaseRenderer.prototype.searchExtraCompositions=function(t){var e,i=t.length;for(e=0;e<i;e+=1)if(t[e].xt){var r=this.createComp(t[e]);r.initExpressions(),this.globalData.projectInterface.registerComposition(r)}},BaseRenderer.prototype.getElementById=function(t){var e,i=this.elements.length;for(e=0;e<i;e+=1)if(this.elements[e].data.ind===t)return this.elements[e];return null},BaseRenderer.prototype.getElementByPath=function(t){var e,i=t.shift();if("number"==typeof i)e=this.elements[i];else{var r,s=this.elements.length;for(r=0;r<s;r+=1)if(this.elements[r].data.nm===i){e=this.elements[r];break}}return 0===t.length?e:e.getElementByPath(t)},BaseRenderer.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new FontManager,this.globalData.slotManager=slotFactory(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var effectTypes={TRANSFORM_EFFECT:"transformEFfect"};function TransformElement(){}function MaskElement(t,e,i){this.data=t,this.element=e,this.globalData=i,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var r,s,a=this.globalData.defs,n=this.masksProperties?this.masksProperties.length:0;this.viewData=createSizedArray(n),this.solidPath="";var o,h,l,p,f,m,c=this.masksProperties,u=0,d=[],y=createElementID(),g="clipPath",v="clip-path";for(r=0;r<n;r+=1)if(("a"!==c[r].mode&&"n"!==c[r].mode||c[r].inv||100!==c[r].o.k||c[r].o.x)&&(g="mask",v="mask"),"s"!==c[r].mode&&"i"!==c[r].mode||0!==u?l=null:((l=createNS("rect")).setAttribute("fill","#ffffff"),l.setAttribute("width",this.element.comp.data.w||0),l.setAttribute("height",this.element.comp.data.h||0),d.push(l)),s=createNS("path"),"n"===c[r].mode)this.viewData[r]={op:PropertyFactory.getProp(this.element,c[r].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[r],3),elem:s,lastPath:""},a.appendChild(s);else{var b;if(u+=1,s.setAttribute("fill","s"===c[r].mode?"#000000":"#ffffff"),s.setAttribute("clip-rule","nonzero"),0!==c[r].x.k?(g="mask",v="mask",m=PropertyFactory.getProp(this.element,c[r].x,0,null,this.element),b=createElementID(),(p=createNS("filter")).setAttribute("id",b),(f=createNS("feMorphology")).setAttribute("operator","erode"),f.setAttribute("in","SourceGraphic"),f.setAttribute("radius","0"),p.appendChild(f),a.appendChild(p),s.setAttribute("stroke","s"===c[r].mode?"#000000":"#ffffff")):(f=null,m=null),this.storedData[r]={elem:s,x:m,expan:f,lastPath:"",lastOperator:"",filterId:b,lastRadius:0},"i"===c[r].mode){h=d.length;var P=createNS("g");for(o=0;o<h;o+=1)P.appendChild(d[o]);var E=createNS("mask");E.setAttribute("mask-type","alpha"),E.setAttribute("id",y+"_"+u),E.appendChild(s),a.appendChild(E),P.setAttribute("mask","url("+getLocationHref()+"#"+y+"_"+u+")"),d.length=0,d.push(P)}else d.push(s);c[r].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[r]={elem:s,lastPath:"",op:PropertyFactory.getProp(this.element,c[r].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[r],3),invRect:l},this.viewData[r].prop.k||this.drawPath(c[r],this.viewData[r].prop.v,this.viewData[r])}for(this.maskElement=createNS(g),n=d.length,r=0;r<n;r+=1)this.maskElement.appendChild(d[r]);u>0&&(this.maskElement.setAttribute("id",y),this.element.maskedElement.setAttribute(v,"url("+getLocationHref()+"#"+y+")"),a.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}TransformElement.prototype={initTransform:function(){var t=new Matrix;this.finalTransform={mProp:this.data.ks?TransformPropertyFactory.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,i=0,r=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;i<r;){if(this.hierarchy[i].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}i+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),i=0;i<r;i+=1)e.multiply(this.hierarchy[i].finalTransform.mProp.v)}this.localTransforms&&!this.finalTransform._matMdf||(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var i=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(i),t=1;t<e;t+=1){var r=this.localTransforms[t].matrix;i.multiply(r)}i.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){var s=this.finalTransform.localOpacity;for(t=0;t<e;t+=1)s*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=s}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new Matrix;var e=0,i=t.length;for(e=0;e<i;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var i,r=!0,s=this.comp;r;)s.finalTransform?(s.data.hasMask&&e.splice(0,0,s.finalTransform),s=s.comp):r=!1;var a,n=e.length;for(i=0;i<n;i+=1)a=e[i].mat.applyToPointArray(0,0,0),t=[t[0]-a[0],t[1]-a[1],0];return t},mHelper:new Matrix},MaskElement.prototype.getMaskProperty=function(t){return this.viewData[t].prop},MaskElement.prototype.renderFrame=function(t){var e,i=this.element.finalTransform.mat,r=this.masksProperties.length;for(e=0;e<r;e+=1)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[e].invRect.setAttribute("transform",i.getInverseMatrix().to2dCSS()),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var s=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+getLocationHref()+"#"+this.storedData[e].filterId+")")),s.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},MaskElement.prototype.getMaskelement=function(){return this.maskElement},MaskElement.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},MaskElement.prototype.drawPath=function(t,e,i){var r,s,a=" M"+e.v[0][0]+","+e.v[0][1];for(s=e._length,r=1;r<s;r+=1)a+=" C"+e.o[r-1][0]+","+e.o[r-1][1]+" "+e.i[r][0]+","+e.i[r][1]+" "+e.v[r][0]+","+e.v[r][1];if(e.c&&s>1&&(a+=" C"+e.o[r-1][0]+","+e.o[r-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),i.lastPath!==a){var n="";i.elem&&(e.c&&(n=t.inv?this.solidPath+a:a),i.elem.setAttribute("d",n)),i.lastPath=a}},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var filtersFactory=function(){var t={};return t.createFilter=function(t,e){var i=createNS("filter");i.setAttribute("id",t),!0!==e&&(i.setAttribute("filterUnits","objectBoundingBox"),i.setAttribute("x","0%"),i.setAttribute("y","0%"),i.setAttribute("width","100%"),i.setAttribute("height","100%"));return i},t.createAlphaToLuminanceFilter=function(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},t}(),featureSupport=function(){var t={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),/firefox/i.test(navigator.userAgent)&&(t.svgLumaHidden=!1),t}(),registeredEffects$1={},idPrefix="filter_result_";function SVGEffects(t){var e,i,r="SourceGraphic",s=t.data.ef?t.data.ef.length:0,a=createElementID(),n=filtersFactory.createFilter(a,!0),o=0;for(this.filters=[],e=0;e<s;e+=1){i=null;var h=t.data.ef[e].ty;if(registeredEffects$1[h])i=new(0,registeredEffects$1[h].effect)(n,t.effectsManager.effectElements[e],t,idPrefix+o,r),r=idPrefix+o,registeredEffects$1[h].countsAsEffect&&(o+=1);i&&this.filters.push(i)}o&&(t.globalData.defs.appendChild(n),t.layerElement.setAttribute("filter","url("+getLocationHref()+"#"+a+")")),this.filters.length&&t.addRenderableComponent(this)}function registerEffect$1(t,e,i){registeredEffects$1[t]={effect:e,countsAsEffect:i}}function SVGBaseElement(){}function HierarchyElement(){}function RenderableDOMElement(){}function IImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,i),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ProcessedElement(t,e){this.elem=t,this.pos=e}function IShapeElement(){}SVGEffects.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},SVGEffects.prototype.getEffects=function(t){var e,i=this.filters.length,r=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&r.push(this.filters[e]);return r},SVGBaseElement.prototype={initRendererElement:function(){this.layerElement=createNS("g")},createContainerElements:function(){this.matteElement=createNS("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t=null;if(this.data.td){this.matteMasks={};var e=createNS("g");e.setAttribute("id",this.layerId),e.appendChild(this.layerElement),t=e,this.globalData.defs.appendChild(e)}else this.data.tt?(this.matteElement.appendChild(this.layerElement),t=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var i=createNS("clipPath"),r=createNS("path");r.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var s=createElementID();if(i.setAttribute("id",s),i.appendChild(r),this.globalData.defs.appendChild(i),this.checkMasks()){var a=createNS("g");a.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),a.appendChild(this.layerElement),this.transformedElement=a,t?t.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData),this.renderableEffectsManager=new SVGEffects(this),this.searchEffectTransforms()},getMatte:function(t){if(this.matteMasks||(this.matteMasks={}),!this.matteMasks[t]){var e,i,r,s,a=this.layerId+"_"+t;if(1===t||3===t){var n=createNS("mask");n.setAttribute("id",a),n.setAttribute("mask-type",3===t?"luminance":"alpha"),(r=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),n.appendChild(r),this.globalData.defs.appendChild(n),featureSupport.maskType||1!==t||(n.setAttribute("mask-type","luminance"),e=createElementID(),i=filtersFactory.createFilter(e),this.globalData.defs.appendChild(i),i.appendChild(filtersFactory.createAlphaToLuminanceFilter()),(s=createNS("g")).appendChild(r),n.appendChild(s),s.setAttribute("filter","url("+getLocationHref()+"#"+e+")"))}else if(2===t){var o=createNS("mask");o.setAttribute("id",a),o.setAttribute("mask-type","alpha");var h=createNS("g");o.appendChild(h),e=createElementID(),i=filtersFactory.createFilter(e);var l=createNS("feComponentTransfer");l.setAttribute("in","SourceGraphic"),i.appendChild(l);var p=createNS("feFuncA");p.setAttribute("type","table"),p.setAttribute("tableValues","1.0 0.0"),l.appendChild(p),this.globalData.defs.appendChild(i);var f=createNS("rect");f.setAttribute("width",this.comp.data.w),f.setAttribute("height",this.comp.data.h),f.setAttribute("x","0"),f.setAttribute("y","0"),f.setAttribute("fill","#ffffff"),f.setAttribute("opacity","0"),h.setAttribute("filter","url("+getLocationHref()+"#"+e+")"),h.appendChild(f),(r=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),h.appendChild(r),featureSupport.maskType||(o.setAttribute("mask-type","luminance"),i.appendChild(filtersFactory.createAlphaToLuminanceFilter()),s=createNS("g"),h.appendChild(f),s.appendChild(this.layerElement),h.appendChild(s)),this.globalData.defs.appendChild(o)}this.matteMasks[t]=a}return this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+getLocationHref()+"#"+t+")")}},HierarchyElement.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},extendPrototype([RenderableElement,createProxyFunction({initElement:function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],RenderableDOMElement),extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],IImageElement),IImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=createNS("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},IImageElement.prototype.sourceRectAtTime=function(){return this.sourceRect},IShapeElement.prototype={addShapeToModifiers:function(t){var e,i=this.shapeModifiers.length;for(e=0;e<i;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;t>=0&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,i=0,r=e.length;i<r;){if(e[i].elem===t)return e[i].pos;i+=1}return 0},addProcessedElement:function(t,e){for(var i=this.processedElements,r=i.length;r;)if(i[r-=1].elem===t)return void(i[r].pos=e);i.push(new ProcessedElement(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var lineCapEnum={1:"butt",2:"round",3:"square"},lineJoinEnum={1:"miter",2:"round",3:"bevel"};function SVGShapeData(t,e,i){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=i,this.lvl=e,this._isAnimated=!!i.k;for(var r=0,s=t.length;r<s;){if(t[r].mProps.dynamicProperties.length){this._isAnimated=!0;break}r+=1}}function SVGStyleData(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=createNS("path"),this.msElem=null}function DashProperty(t,e,i,r){var s;this.elem=t,this.frameId=-1,this.dataProps=createSizedArray(e.length),this.renderer=i,this.k=!1,this.dashStr="",this.dashArray=createTypedArray("float32",e.length?e.length-1:0),this.dashoffset=createTypedArray("float32",1),this.initDynamicPropertyContainer(r);var a,n=e.length||0;for(s=0;s<n;s+=1)a=PropertyFactory.getProp(t,e[s].v,0,0,this),this.k=a.k||this.k,this.dataProps[s]={n:e[s].n,p:a};this.k||this.getValue(!0),this._isAnimated=this.k}function SVGStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i,this._isAnimated=!!this._isAnimated}function SVGFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i}function SVGNoStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=i}function GradientProperty(t,e,i){this.data=e,this.c=createTypedArray("uint8c",4*e.p);var r=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=createTypedArray("float32",r),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=r,this.initDynamicPropertyContainer(i),this.prop=PropertyFactory.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function SVGGradientFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,i)}function SVGGradientStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.initGradientData(t,e,i),this._isAnimated=!!this._isAnimated}function ShapeGroupData(){this.it=[],this.prevViewData=[],this.gr=createNS("g")}function SVGTransformData(t,e,i){this.transform={mProps:t,op:e,container:i},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}SVGShapeData.prototype.setAsAnimated=function(){this._isAnimated=!0},SVGStyleData.prototype.reset=function(){this.d="",this._mdf=!1},DashProperty.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,i=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<i;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},extendPrototype([DynamicPropertyContainer],DashProperty),extendPrototype([DynamicPropertyContainer],SVGStrokeStyleData),extendPrototype([DynamicPropertyContainer],SVGFillStyleData),extendPrototype([DynamicPropertyContainer],SVGNoStyleData),GradientProperty.prototype.comparePoints=function(t,e){for(var i=0,r=this.o.length/2;i<r;){if(Math.abs(t[4*i]-t[4*e+2*i])>.01)return!1;i+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},GradientProperty.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,i,r,s=4*this.data.p;for(e=0;e<s;e+=1)i=e%4==0?100:255,r=Math.round(this.prop.v[e]*i),this.c[e]!==r&&(this.c[e]=r,this._cmdf=!t);if(this.o.length)for(s=this.prop.v.length,e=4*this.data.p;e<s;e+=1)i=e%2==0?100:1,r=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==r&&(this.o[e-4*this.data.p]=r,this._omdf=!t);this._mdf=!t}},extendPrototype([DynamicPropertyContainer],GradientProperty),SVGGradientFillStyleData.prototype.initGradientData=function(t,e,i){this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.s=PropertyFactory.getProp(t,e.s,1,null,this),this.e=PropertyFactory.getProp(t,e.e,1,null,this),this.h=PropertyFactory.getProp(t,e.h||{k:0},0,.01,this),this.a=PropertyFactory.getProp(t,e.a||{k:0},0,degToRads,this),this.g=new GradientProperty(t,e.g,this),this.style=i,this.stops=[],this.setGradientData(i.pElem,e),this.setGradientOpacity(e,i),this._isAnimated=!!this._isAnimated},SVGGradientFillStyleData.prototype.setGradientData=function(t,e){var i=createElementID(),r=createNS(1===e.t?"linearGradient":"radialGradient");r.setAttribute("id",i),r.setAttribute("spreadMethod","pad"),r.setAttribute("gradientUnits","userSpaceOnUse");var s,a,n,o=[];for(n=4*e.g.p,a=0;a<n;a+=4)s=createNS("stop"),r.appendChild(s),o.push(s);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+getLocationHref()+"#"+i+")"),this.gf=r,this.cst=o},SVGGradientFillStyleData.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){var i,r,s,a=createNS("mask"),n=createNS("path");a.appendChild(n);var o=createElementID(),h=createElementID();a.setAttribute("id",h);var l=createNS(1===t.t?"linearGradient":"radialGradient");l.setAttribute("id",o),l.setAttribute("spreadMethod","pad"),l.setAttribute("gradientUnits","userSpaceOnUse"),s=t.g.k.k[0].s?t.g.k.k[0].s.length:t.g.k.k.length;var p=this.stops;for(r=4*t.g.p;r<s;r+=2)(i=createNS("stop")).setAttribute("stop-color","rgb(255,255,255)"),l.appendChild(i),p.push(i);n.setAttribute("gf"===t.ty?"fill":"stroke","url("+getLocationHref()+"#"+o+")"),"gs"===t.ty&&(n.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),n.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),1===t.lj&&n.setAttribute("stroke-miterlimit",t.ml)),this.of=l,this.ms=a,this.ost=p,this.maskId=h,e.msElem=n}},extendPrototype([DynamicPropertyContainer],SVGGradientFillStyleData),extendPrototype([SVGGradientFillStyleData,DynamicPropertyContainer],SVGGradientStrokeStyleData);var buildShapeString=function(t,e,i,r){if(0===e)return"";var s,a=t.o,n=t.i,o=t.v,h=" M"+r.applyToPointStringified(o[0][0],o[0][1]);for(s=1;s<e;s+=1)h+=" C"+r.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+r.applyToPointStringified(n[s][0],n[s][1])+" "+r.applyToPointStringified(o[s][0],o[s][1]);return i&&e&&(h+=" C"+r.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+r.applyToPointStringified(n[0][0],n[0][1])+" "+r.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},SVGElementsRenderer=function(){var t=new Matrix,e=new Matrix;function i(t,e,i){(i||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(i||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function r(){}function s(i,r,s){var a,n,o,h,l,p,f,m,c,u,d=r.styles.length,y=r.lvl;for(p=0;p<d;p+=1){if(h=r.sh._mdf||s,r.styles[p].lvl<y){for(m=e.reset(),c=y-r.styles[p].lvl,u=r.transformers.length-1;!h&&c>0;)h=r.transformers[u].mProps._mdf||h,c-=1,u-=1;if(h)for(c=y-r.styles[p].lvl,u=r.transformers.length-1;c>0;)m.multiply(r.transformers[u].mProps.v),c-=1,u-=1}else m=t;if(n=(f=r.sh.paths)._length,h){for(o="",a=0;a<n;a+=1)(l=f.shapes[a])&&l._length&&(o+=buildShapeString(l,l._length,l.c,m));r.caches[p]=o}else o=r.caches[p];r.styles[p].d+=!0===i.hd?"":o,r.styles[p]._mdf=h||r.styles[p]._mdf}}function a(t,e,i){var r=e.style;(e.c._mdf||i)&&r.pElem.setAttribute("fill","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("fill-opacity",e.o.v)}function n(t,e,i){o(t,e,i),h(t,e,i)}function o(t,e,i){var r,s,a,n,o,h=e.gf,l=e.g._hasOpacity,p=e.s.v,f=e.e.v;if(e.o._mdf||i){var m="gf"===t.ty?"fill-opacity":"stroke-opacity";e.style.pElem.setAttribute(m,e.o.v)}if(e.s._mdf||i){var c=1===t.t?"x1":"cx",u="x1"===c?"y1":"cy";h.setAttribute(c,p[0]),h.setAttribute(u,p[1]),l&&!e.g._collapsable&&(e.of.setAttribute(c,p[0]),e.of.setAttribute(u,p[1]))}if(e.g._cmdf||i){r=e.cst;var d=e.g.c;for(a=r.length,s=0;s<a;s+=1)(n=r[s]).setAttribute("offset",d[4*s]+"%"),n.setAttribute("stop-color","rgb("+d[4*s+1]+","+d[4*s+2]+","+d[4*s+3]+")")}if(l&&(e.g._omdf||i)){var y=e.g.o;for(a=(r=e.g._collapsable?e.cst:e.ost).length,s=0;s<a;s+=1)n=r[s],e.g._collapsable||n.setAttribute("offset",y[2*s]+"%"),n.setAttribute("stop-opacity",y[2*s+1])}if(1===t.t)(e.e._mdf||i)&&(h.setAttribute("x2",f[0]),h.setAttribute("y2",f[1]),l&&!e.g._collapsable&&(e.of.setAttribute("x2",f[0]),e.of.setAttribute("y2",f[1])));else if((e.s._mdf||e.e._mdf||i)&&(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)),h.setAttribute("r",o),l&&!e.g._collapsable&&e.of.setAttribute("r",o)),e.s._mdf||e.e._mdf||e.h._mdf||e.a._mdf||i){o||(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)));var g=Math.atan2(f[1]-p[1],f[0]-p[0]),v=e.h.v;v>=1?v=.99:v<=-1&&(v=-.99);var b=o*v,P=Math.cos(g+e.a.v)*b+p[0],E=Math.sin(g+e.a.v)*b+p[1];h.setAttribute("fx",P),h.setAttribute("fy",E),l&&!e.g._collapsable&&(e.of.setAttribute("fx",P),e.of.setAttribute("fy",E))}}function h(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||i)&&s.dashStr&&(r.pElem.setAttribute("stroke-dasharray",s.dashStr),r.pElem.setAttribute("stroke-dashoffset",s.dashoffset[0])),e.c&&(e.c._mdf||i)&&r.pElem.setAttribute("stroke","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||i)&&(r.pElem.setAttribute("stroke-width",e.w.v),r.msElem&&r.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function(t){switch(t.ty){case"fl":return a;case"gf":return o;case"gs":return n;case"st":return h;case"sh":case"el":case"rc":case"sr":return s;case"tr":return i;case"no":return r;default:return null}}}}();function SVGShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,i),this.prevViewData=[]}function LetterProps(t,e,i,r,s,a){this.o=t,this.sw=e,this.sc=i,this.fc=r,this.m=s,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!i,fc:!!r,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){var t,e,i,r,s=this.shapes.length,a=this.stylesList.length,n=[],o=!1;for(i=0;i<a;i+=1){for(r=this.stylesList[i],o=!1,n.length=0,t=0;t<s;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(r)&&(n.push(e),o=e._isAnimated||o);n.length>1&&o&&this.setShapesAsAnimated(n)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].setAsAnimated()},SVGShapeElement.prototype.createStyleElement=function(t,e){var i,r=new SVGStyleData(t,e),s=r.pElem;if("st"===t.ty)i=new SVGStrokeStyleData(this,t,r);else if("fl"===t.ty)i=new SVGFillStyleData(this,t,r);else if("gf"===t.ty||"gs"===t.ty){i=new("gf"===t.ty?SVGGradientFillStyleData:SVGGradientStrokeStyleData)(this,t,r),this.globalData.defs.appendChild(i.gf),i.maskId&&(this.globalData.defs.appendChild(i.ms),this.globalData.defs.appendChild(i.of),s.setAttribute("mask","url("+getLocationHref()+"#"+i.maskId+")"))}else"no"===t.ty&&(i=new SVGNoStyleData(this,t,r));return"st"!==t.ty&&"gs"!==t.ty||(s.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),s.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),s.setAttribute("fill-opacity","0"),1===t.lj&&s.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&s.setAttribute("fill-rule","evenodd"),t.ln&&s.setAttribute("id",t.ln),t.cl&&s.setAttribute("class",t.cl),t.bm&&(s.style["mix-blend-mode"]=getBlendMode(t.bm)),this.stylesList.push(r),this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createGroupElement=function(t){var e=new ShapeGroupData;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=getBlendMode(t.bm)),e},SVGShapeElement.prototype.createTransformElement=function(t,e){var i=TransformPropertyFactory.getTransformProperty(this,t,this),r=new SVGTransformData(i,i.o,e);return this.addToAnimatedContents(t,r),r},SVGShapeElement.prototype.createShapeElement=function(t,e,i){var r=4;"rc"===t.ty?r=5:"el"===t.ty?r=6:"sr"===t.ty&&(r=7);var s=new SVGShapeData(e,i,ShapePropertyFactory.getShapeProp(this,t,r,this));return this.shapes.push(s),this.addShapeToModifiers(s),this.addToAnimatedContents(t,s),s},SVGShapeElement.prototype.addToAnimatedContents=function(t,e){for(var i=0,r=this.animatedContents.length;i<r;){if(this.animatedContents[i].element===e)return;i+=1}this.animatedContents.push({fn:SVGElementsRenderer.createRenderFunction(t),element:e,data:t})},SVGShapeElement.prototype.setElementStyles=function(t){var e,i=t.styles,r=this.stylesList.length;for(e=0;e<r;e+=1)-1!==i.indexOf(this.stylesList[e])||this.stylesList[e].closed||i.push(this.stylesList[e])},SVGShapeElement.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},SVGShapeElement.prototype.searchShapes=function(t,e,i,r,s,a,n){var o,h,l,p,f,m,c=[].concat(a),u=t.length-1,d=[],y=[];for(o=u;o>=0;o-=1){if((m=this.searchProcessedElement(t[o]))?e[o]=i[m-1]:t[o]._render=n,"fl"===t[o].ty||"st"===t[o].ty||"gf"===t[o].ty||"gs"===t[o].ty||"no"===t[o].ty)m?e[o].style.closed=t[o].hd:e[o]=this.createStyleElement(t[o],s),t[o]._render&&e[o].style.pElem.parentNode!==r&&r.appendChild(e[o].style.pElem),d.push(e[o].style);else if("gr"===t[o].ty){if(m)for(l=e[o].it.length,h=0;h<l;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,s+1,c,n),t[o]._render&&e[o].gr.parentNode!==r&&r.appendChild(e[o].gr)}else"tr"===t[o].ty?(m||(e[o]=this.createTransformElement(t[o],r)),p=e[o].transform,c.push(p)):"sh"===t[o].ty||"rc"===t[o].ty||"el"===t[o].ty||"sr"===t[o].ty?(m||(e[o]=this.createShapeElement(t[o],c,s)),this.setElementStyles(e[o])):"tm"===t[o].ty||"rd"===t[o].ty||"ms"===t[o].ty||"pb"===t[o].ty||"zz"===t[o].ty||"op"===t[o].ty?(m?(f=e[o]).closed=!1:((f=ShapeModifiers.getModifier(t[o].ty)).init(this,t[o]),e[o]=f,this.shapeModifiers.push(f)),y.push(f)):"rp"===t[o].ty&&(m?(f=e[o]).closed=!0:(f=ShapeModifiers.getModifier(t[o].ty),e[o]=f,f.init(this,t,o,e),this.shapeModifiers.push(f),n=!1),y.push(f));this.addProcessedElement(t[o],o+1)}for(u=d.length,o=0;o<u;o+=1)d[o].closed=!0;for(u=y.length,o=0;o<u;o+=1)y[o].closed=!0},SVGShapeElement.prototype.renderInnerContent=function(){var t;this.renderModifiers();var e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},SVGShapeElement.prototype.renderShape=function(){var t,e,i=this.animatedContents.length;for(t=0;t<i;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},SVGShapeElement.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},LetterProps.prototype.update=function(t,e,i,r,s,a){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1,this._mdf.p=!1;var n=!1;return this.o!==t&&(this.o=t,this._mdf.o=!0,n=!0),this.sw!==e&&(this.sw=e,this._mdf.sw=!0,n=!0),this.sc!==i&&(this.sc=i,this._mdf.sc=!0,n=!0),this.fc!==r&&(this.fc=r,this._mdf.fc=!0,n=!0),this.m!==s&&(this.m=s,this._mdf.m=!0,n=!0),!a.length||this.p[0]===a[0]&&this.p[1]===a[1]&&this.p[4]===a[4]&&this.p[5]===a[5]&&this.p[12]===a[12]&&this.p[13]===a[13]||(this.p=a,this._mdf.p=!0,n=!0),n},TextProperty.prototype.defaultBoxWidth=[0,0],TextProperty.prototype.copyData=function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},TextProperty.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},TextProperty.prototype.searchProperty=function(){return this.searchKeyframes()},TextProperty.prototype.searchKeyframes=function(){return this.kf=this.data.d.k.length>1,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,i=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{var r;this.lock=!0,this._mdf=!1;var s=this.effectsSequence.length,a=t||this.data.d.k[this.keysIndex].s;for(r=0;r<s;r+=1)a=i!==this.keysIndex?this.effectsSequence[r](a,a.t):this.effectsSequence[r](this.currentData,a.t);e!==a&&this.setCurrentData(a),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},TextProperty.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,i=0,r=t.length;i<=r-1&&!(i===r-1||t[i+1].t>e);)i+=1;return this.keysIndex!==i&&(this.keysIndex=i),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e,i,r=[],s=0,a=t.length,n=!1,o=!1,h="";s<a;)n=o,o=!1,e=t.charCodeAt(s),h=t.charAt(s),FontManager.isCombinedCharacter(e)?n=!0:e>=55296&&e<=56319?FontManager.isRegionalFlag(t,s)?h=t.substr(s,14):(i=t.charCodeAt(s+1))>=56320&&i<=57343&&(FontManager.isModifier(e,i)?(h=t.substr(s,2),n=!0):h=FontManager.isFlagEmoji(t.substr(s,4))?t.substr(s,4):t.substr(s,2)):e>56319?(i=t.charCodeAt(s+1),FontManager.isVariationSelector(e)&&(n=!0)):FontManager.isZeroWidthJoiner(e)&&(n=!0,o=!0),n?(r[r.length-1]+=h,n=!1):r.push(h),s+=h.length;return r},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,i,r,s,a,n,o,h=this.elem.globalData.fontManager,l=this.data,p=[],f=0,m=l.m.g,c=0,u=0,d=0,y=[],g=0,v=0,b=h.getFontByName(t.f),P=0,E=getFontProperties(b);t.fWeight=E.weight,t.fStyle=E.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),i=t.finalText.length,t.finalLineHeight=t.lh;var x,S=t.tr/1e3*t.finalSize;if(t.sz)for(var _,A,M=!0,T=t.sz[0],k=t.sz[1];M;){_=0,g=0,i=(A=this.buildFinalText(t.t)).length,S=t.tr/1e3*t.finalSize;var D=-1;for(e=0;e<i;e+=1)x=A[e].charCodeAt(0),r=!1," "===A[e]?D=e:13!==x&&3!==x||(g=0,r=!0,_+=t.finalLineHeight||1.2*t.finalSize),h.chars?(o=h.getCharData(A[e],b.fStyle,b.fFamily),P=r?0:o.w*t.finalSize/100):P=h.measureText(A[e],t.f,t.finalSize),g+P>T&&" "!==A[e]?(-1===D?i+=1:e=D,_+=t.finalLineHeight||1.2*t.finalSize,A.splice(e,D===e?1:0,"\r"),D=-1,g=0):(g+=P,g+=S);_+=b.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&k<_?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=A,i=t.finalText.length,M=!1)}g=-S,P=0;var F,C=0;for(e=0;e<i;e+=1)if(r=!1,13===(x=(F=t.finalText[e]).charCodeAt(0))||3===x?(C=0,y.push(g),v=g>v?g:v,g=-2*S,s="",r=!0,d+=1):s=F,h.chars?(o=h.getCharData(F,b.fStyle,h.getFontByName(t.f).fFamily),P=r?0:o.w*t.finalSize/100):P=h.measureText(s,t.f,t.finalSize)," "===F?C+=P+S:(g+=P+S+C,C=0),p.push({l:P,an:P,add:c,n:r,anIndexes:[],val:s,line:d,animatorJustifyOffset:0}),2==m){if(c+=P,""===s||" "===s||e===i-1){for(""!==s&&" "!==s||(c-=P);u<=e;)p[u].an=c,p[u].ind=f,p[u].extra=P,u+=1;f+=1,c=0}}else if(3==m){if(c+=P,""===s||e===i-1){for(""===s&&(c-=P);u<=e;)p[u].an=c,p[u].ind=f,p[u].extra=P,u+=1;c=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=g>v?g:v,y.push(g),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=y;var I,w,B,V,R=l.a;n=R.length;var L=[];for(a=0;a<n;a+=1){for((I=R[a]).a.sc&&(t.strokeColorAnim=!0),I.a.sw&&(t.strokeWidthAnim=!0),(I.a.fc||I.a.fh||I.a.fs||I.a.fb)&&(t.fillColorAnim=!0),V=0,B=I.s.b,e=0;e<i;e+=1)(w=p[e]).anIndexes[a]=V,(1==B&&""!==w.val||2==B&&""!==w.val&&" "!==w.val||3==B&&(w.n||" "==w.val||e==i-1)||4==B&&(w.n||e==i-1))&&(1===I.s.rn&&L.push(V),V+=1);l.a[a].s.totalChars=V;var G,z=-1;if(1===I.s.rn)for(e=0;e<i;e+=1)z!=(w=p[e]).anIndexes[a]&&(z=w.anIndexes[a],G=L.splice(Math.floor(Math.random()*L.length),1)[0]),w.anIndexes[a]=G}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=b.ascent*t.finalSize/100},TextProperty.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var i=this.copyData({},this.data.d.k[e].s);i=this.copyData(i,t),this.data.d.k[e].s=i,this.recalculate(e),this.setCurrentData(i),this.elem.addDynamicProperty(this)},TextProperty.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},TextProperty.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},TextProperty.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var TextSelectorProp=function(){var t=Math.max,e=Math.min,i=Math.floor;function r(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=PropertyFactory.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?PropertyFactory.getProp(t,e.e,0,0,this):{v:100},this.o=PropertyFactory.getProp(t,e.o||{k:0},0,0,this),this.xe=PropertyFactory.getProp(t,e.xe||{k:0},0,0,this),this.ne=PropertyFactory.getProp(t,e.ne||{k:0},0,0,this),this.sm=PropertyFactory.getProp(t,e.sm||{k:100},0,0,this),this.a=PropertyFactory.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return r.prototype={getMult:function(r){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var s=0,a=0,n=1,o=1;this.ne.v>0?s=this.ne.v/100:a=-this.ne.v/100,this.xe.v>0?n=1-this.xe.v/100:o=1+this.xe.v/100;var h=BezierFactory.getBezierEasing(s,a,n,o).get,l=0,p=this.finalS,f=this.finalE,m=this.data.sh;if(2===m)l=h(l=f===p?r>=f?1:0:t(0,e(.5/(f-p)+(r-p)/(f-p),1)));else if(3===m)l=h(l=f===p?r>=f?0:1:1-t(0,e(.5/(f-p)+(r-p)/(f-p),1)));else if(4===m)f===p?l=0:(l=t(0,e(.5/(f-p)+(r-p)/(f-p),1)))<.5?l*=2:l=1-2*(l-.5),l=h(l);else if(5===m){if(f===p)l=0;else{var c=f-p,u=-c/2+(r=e(t(0,r+.5-p),f-p)),d=c/2;l=Math.sqrt(1-u*u/(d*d))}l=h(l)}else 6===m?(f===p?l=0:(r=e(t(0,r+.5-p),f-p),l=(1+Math.cos(Math.PI+2*Math.PI*r/(f-p)))/2),l=h(l)):(r>=i(p)&&(l=t(0,e(r-p<0?e(f,1)-(p-r):f-r,1))),l=h(l));if(100!==this.sm.v){var y=.01*this.sm.v;0===y&&(y=1e-8);var g=.5-.5*y;l<g?l=0:(l=(l-g)/y)>1&&(l=1)}return l*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,i=this.o.v/e,r=this.s.v/e+i,s=this.e.v/e+i;if(r>s){var a=r;r=s,s=a}this.finalS=r,this.finalE=s}},extendPrototype([DynamicPropertyContainer],r),{getTextSelectorProp:function(t,e,i){return new r(t,e,i)}}}();function TextAnimatorDataProperty(t,e,i){var r={propType:!1},s=PropertyFactory.getProp,a=e.a;this.a={r:a.r?s(t,a.r,0,degToRads,i):r,rx:a.rx?s(t,a.rx,0,degToRads,i):r,ry:a.ry?s(t,a.ry,0,degToRads,i):r,sk:a.sk?s(t,a.sk,0,degToRads,i):r,sa:a.sa?s(t,a.sa,0,degToRads,i):r,s:a.s?s(t,a.s,1,.01,i):r,a:a.a?s(t,a.a,1,0,i):r,o:a.o?s(t,a.o,0,.01,i):r,p:a.p?s(t,a.p,1,0,i):r,sw:a.sw?s(t,a.sw,0,0,i):r,sc:a.sc?s(t,a.sc,1,0,i):r,fc:a.fc?s(t,a.fc,1,0,i):r,fh:a.fh?s(t,a.fh,0,0,i):r,fs:a.fs?s(t,a.fs,0,.01,i):r,fb:a.fb?s(t,a.fb,0,.01,i):r,t:a.t?s(t,a.t,0,0,i):r},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,i),this.s.t=e.s.t}function TextAnimatorProperty(t,e,i){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=i,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(i)}function ITextElement(){}TextAnimatorProperty.prototype.searchProperties=function(){var t,e,i=this._textData.a.length,r=PropertyFactory.getProp;for(t=0;t<i;t+=1)e=this._textData.a[t],this._animatorsData[t]=new TextAnimatorDataProperty(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:r(this._elem,this._textData.p.a,0,0,this),f:r(this._elem,this._textData.p.f,0,0,this),l:r(this._elem,this._textData.p.l,0,0,this),r:r(this._elem,this._textData.p.r,0,0,this),p:r(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=r(this._elem,this._textData.m.a,1,0,this)},TextAnimatorProperty.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var i,r,s,a,n,o,h,l,p,f,m,c,u,d,y,g,v,b,P,E=this._moreOptions.alignment.v,x=this._animatorsData,S=this._textData,_=this.mHelper,A=this._renderType,M=this.renderedLetters.length,T=t.l;if(this._hasMaskedPath){if(P=this._pathData.m,!this._pathData.n||this._pathData._mdf){var k,D=P.v;for(this._pathData.r.v&&(D=D.reverse()),n={tLength:0,segments:[]},a=D._length-1,g=0,s=0;s<a;s+=1)k=bez.buildBezierData(D.v[s],D.v[s+1],[D.o[s][0]-D.v[s][0],D.o[s][1]-D.v[s][1]],[D.i[s+1][0]-D.v[s+1][0],D.i[s+1][1]-D.v[s+1][1]]),n.tLength+=k.segmentLength,n.segments.push(k),g+=k.segmentLength;s=a,P.v.c&&(k=bez.buildBezierData(D.v[s],D.v[0],[D.o[s][0]-D.v[s][0],D.o[s][1]-D.v[s][1]],[D.i[0][0]-D.v[0][0],D.i[0][1]-D.v[0][1]]),n.tLength+=k.segmentLength,n.segments.push(k),g+=k.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,m=0,f=1,l=0,p=!0,d=n.segments,o<0&&P.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),f=(u=d[m=d.length-1].points).length-1;o<0;)o+=u[f].partialLength,(f-=1)<0&&(f=(u=d[m-=1].points).length-1);c=(u=d[m].points)[f-1],y=(h=u[f]).partialLength}a=T.length,i=0,r=0;var F,C,I,w,B,V=1.2*t.finalSize*.714,R=!0;I=x.length;var L,G,z,N,O,H,j,q,$,W,X,Z,Y=-1,K=o,J=m,U=f,Q=-1,tt="",et=this.defaultPropsArray;if(2===t.j||1===t.j){var it=0,rt=0,st=2===t.j?-.5:-1,at=0,nt=!0;for(s=0;s<a;s+=1)if(T[s].n){for(it&&(it+=rt);at<s;)T[at].animatorJustifyOffset=it,at+=1;it=0,nt=!0}else{for(C=0;C<I;C+=1)(F=x[C].a).t.propType&&(nt&&2===t.j&&(rt+=F.t.v*st),(B=x[C].s.getMult(T[s].anIndexes[C],S.a[C].s.totalChars)).length?it+=F.t.v*B[0]*st:it+=F.t.v*B*st);nt=!1}for(it&&(it+=rt);at<s;)T[at].animatorJustifyOffset=it,at+=1}for(s=0;s<a;s+=1){if(_.reset(),N=1,T[s].n)i=0,r+=t.yOffset,r+=R?1:0,o=K,R=!1,this._hasMaskedPath&&(f=U,c=(u=d[m=J].points)[f-1],y=(h=u[f]).partialLength,l=0),tt="",X="",$="",Z="",et=this.defaultPropsArray;else{if(this._hasMaskedPath){if(Q!==T[s].line){switch(t.j){case 1:o+=g-t.lineWidths[T[s].line];break;case 2:o+=(g-t.lineWidths[T[s].line])/2}Q=T[s].line}Y!==T[s].ind&&(T[Y]&&(o+=T[Y].extra),o+=T[s].an/2,Y=T[s].ind),o+=E[0]*T[s].an*.005;var ot=0;for(C=0;C<I;C+=1)(F=x[C].a).p.propType&&((B=x[C].s.getMult(T[s].anIndexes[C],S.a[C].s.totalChars)).length?ot+=F.p.v[0]*B[0]:ot+=F.p.v[0]*B),F.a.propType&&((B=x[C].s.getMult(T[s].anIndexes[C],S.a[C].s.totalChars)).length?ot+=F.a.v[0]*B[0]:ot+=F.a.v[0]*B);for(p=!0,this._pathData.a.v&&(o=.5*T[0].an+(g-this._pathData.f.v-.5*T[0].an-.5*T[T.length-1].an)*Y/(a-1),o+=this._pathData.f.v);p;)l+y>=o+ot||!u?(v=(o+ot-l)/h.partialLength,G=c.point[0]+(h.point[0]-c.point[0])*v,z=c.point[1]+(h.point[1]-c.point[1])*v,_.translate(-E[0]*T[s].an*.005,-E[1]*V*.01),p=!1):u&&(l+=h.partialLength,(f+=1)>=u.length&&(f=0,d[m+=1]?u=d[m].points:P.v.c?(f=0,u=d[m=0].points):(l-=h.partialLength,u=null)),u&&(c=h,y=(h=u[f]).partialLength));L=T[s].an/2-T[s].add,_.translate(-L,0,0)}else L=T[s].an/2-T[s].add,_.translate(-L,0,0),_.translate(-E[0]*T[s].an*.005,-E[1]*V*.01,0);for(C=0;C<I;C+=1)(F=x[C].a).t.propType&&(B=x[C].s.getMult(T[s].anIndexes[C],S.a[C].s.totalChars),0===i&&0===t.j||(this._hasMaskedPath?B.length?o+=F.t.v*B[0]:o+=F.t.v*B:B.length?i+=F.t.v*B[0]:i+=F.t.v*B));for(t.strokeWidthAnim&&(H=t.sw||0),t.strokeColorAnim&&(O=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(j=[t.fc[0],t.fc[1],t.fc[2]]),C=0;C<I;C+=1)(F=x[C].a).a.propType&&((B=x[C].s.getMult(T[s].anIndexes[C],S.a[C].s.totalChars)).length?_.translate(-F.a.v[0]*B[0],-F.a.v[1]*B[1],F.a.v[2]*B[2]):_.translate(-F.a.v[0]*B,-F.a.v[1]*B,F.a.v[2]*B));for(C=0;C<I;C+=1)(F=x[C].a).s.propType&&((B=x[C].s.getMult(T[s].anIndexes[C],S.a[C].s.totalChars)).length?_.scale(1+(F.s.v[0]-1)*B[0],1+(F.s.v[1]-1)*B[1],1):_.scale(1+(F.s.v[0]-1)*B,1+(F.s.v[1]-1)*B,1));for(C=0;C<I;C+=1){if(F=x[C].a,B=x[C].s.getMult(T[s].anIndexes[C],S.a[C].s.totalChars),F.sk.propType&&(B.length?_.skewFromAxis(-F.sk.v*B[0],F.sa.v*B[1]):_.skewFromAxis(-F.sk.v*B,F.sa.v*B)),F.r.propType&&(B.length?_.rotateZ(-F.r.v*B[2]):_.rotateZ(-F.r.v*B)),F.ry.propType&&(B.length?_.rotateY(F.ry.v*B[1]):_.rotateY(F.ry.v*B)),F.rx.propType&&(B.length?_.rotateX(F.rx.v*B[0]):_.rotateX(F.rx.v*B)),F.o.propType&&(B.length?N+=(F.o.v*B[0]-N)*B[0]:N+=(F.o.v*B-N)*B),t.strokeWidthAnim&&F.sw.propType&&(B.length?H+=F.sw.v*B[0]:H+=F.sw.v*B),t.strokeColorAnim&&F.sc.propType)for(q=0;q<3;q+=1)B.length?O[q]+=(F.sc.v[q]-O[q])*B[0]:O[q]+=(F.sc.v[q]-O[q])*B;if(t.fillColorAnim&&t.fc){if(F.fc.propType)for(q=0;q<3;q+=1)B.length?j[q]+=(F.fc.v[q]-j[q])*B[0]:j[q]+=(F.fc.v[q]-j[q])*B;F.fh.propType&&(j=B.length?addHueToRGB(j,F.fh.v*B[0]):addHueToRGB(j,F.fh.v*B)),F.fs.propType&&(j=B.length?addSaturationToRGB(j,F.fs.v*B[0]):addSaturationToRGB(j,F.fs.v*B)),F.fb.propType&&(j=B.length?addBrightnessToRGB(j,F.fb.v*B[0]):addBrightnessToRGB(j,F.fb.v*B))}}for(C=0;C<I;C+=1)(F=x[C].a).p.propType&&(B=x[C].s.getMult(T[s].anIndexes[C],S.a[C].s.totalChars),this._hasMaskedPath?B.length?_.translate(0,F.p.v[1]*B[0],-F.p.v[2]*B[1]):_.translate(0,F.p.v[1]*B,-F.p.v[2]*B):B.length?_.translate(F.p.v[0]*B[0],F.p.v[1]*B[1],-F.p.v[2]*B[2]):_.translate(F.p.v[0]*B,F.p.v[1]*B,-F.p.v[2]*B));if(t.strokeWidthAnim&&($=H<0?0:H),t.strokeColorAnim&&(W="rgb("+Math.round(255*O[0])+","+Math.round(255*O[1])+","+Math.round(255*O[2])+")"),t.fillColorAnim&&t.fc&&(X="rgb("+Math.round(255*j[0])+","+Math.round(255*j[1])+","+Math.round(255*j[2])+")"),this._hasMaskedPath){if(_.translate(0,-t.ls),_.translate(0,E[1]*V*.01+r,0),this._pathData.p.v){b=(h.point[1]-c.point[1])/(h.point[0]-c.point[0]);var ht=180*Math.atan(b)/Math.PI;h.point[0]<c.point[0]&&(ht+=180),_.rotate(-ht*Math.PI/180)}_.translate(G,z,0),o-=E[0]*T[s].an*.005,T[s+1]&&Y!==T[s+1].ind&&(o+=T[s].an/2,o+=.001*t.tr*t.finalSize)}else{switch(_.translate(i,r,0),t.ps&&_.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:_.translate(T[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[T[s].line]),0,0);break;case 2:_.translate(T[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[T[s].line])/2,0,0)}_.translate(0,-t.ls),_.translate(L,0,0),_.translate(E[0]*T[s].an*.005,E[1]*V*.01,0),i+=T[s].l+.001*t.tr*t.finalSize}"html"===A?tt=_.toCSS():"svg"===A?tt=_.to2dCSS():et=[_.props[0],_.props[1],_.props[2],_.props[3],_.props[4],_.props[5],_.props[6],_.props[7],_.props[8],_.props[9],_.props[10],_.props[11],_.props[12],_.props[13],_.props[14],_.props[15]],Z=N}M<=s?(w=new LetterProps(Z,$,W,X,tt,et),this.renderedLetters.push(w),M+=1,this.lettersChangedFlag=!0):(w=this.renderedLetters[s],this.lettersChangedFlag=w.update(Z,$,W,X,tt,et)||this.lettersChangedFlag)}}},TextAnimatorProperty.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},TextAnimatorProperty.prototype.mHelper=new Matrix,TextAnimatorProperty.prototype.defaultPropsArray=[],extendPrototype([DynamicPropertyContainer],TextAnimatorProperty),ITextElement.prototype.initElement=function(t,e,i){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,i),this.textProperty=new TextProperty(this,t.t,this.dynamicProperties),this.textAnimator=new TextAnimatorProperty(t.t,this.renderType,this),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},ITextElement.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},ITextElement.prototype.createPathShape=function(t,e){var i,r,s=e.length,a="";for(i=0;i<s;i+=1)"sh"===e[i].ty&&(r=e[i].ks.k,a+=buildShapeString(r,r.i.length,!0,t));return a},ITextElement.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},ITextElement.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},ITextElement.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},ITextElement.prototype.applyTextPropertiesToMatrix=function(t,e,i,r,s){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i])/2,0,0)}e.translate(r,s,0)},ITextElement.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},ITextElement.prototype.emptyProp=new LetterProps,ITextElement.prototype.destroy=function(){},ITextElement.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var emptyShapeData={shapes:[]};function SVGTextLottieElement(t,e,i){this.textSpans=[],this.renderType="svg",this.initElement(t,e,i)}function ISolidElement(t,e,i){this.initElement(t,e,i)}function NullElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initFrame(),this.initTransform(t,e,i),this.initHierarchy()}function SVGRendererBase(){}function ICompElement(){}function SVGCompElement(t,e,i){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function SVGRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=createNS("svg");var i="";if(e&&e.title){var r=createNS("title"),s=createElementID();r.setAttribute("id",s),r.textContent=e.title,this.svgElement.appendChild(r),i+=s}if(e&&e.description){var a=createNS("desc"),n=createElementID();a.setAttribute("id",n),a.textContent=e.description,this.svgElement.appendChild(a),i+=" "+n}i&&this.svgElement.setAttribute("aria-labelledby",i);var o=createNS("defs");this.svgElement.appendChild(o);var h=createNS("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],SVGTextLottieElement),SVGTextLottieElement.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=createNS("text"))},SVGTextLottieElement.prototype.buildTextContents=function(t){for(var e=0,i=t.length,r=[],s="";e<i;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(r.push(s),s=""):s+=t[e],e+=1;return r.push(s),r},SVGTextLottieElement.prototype.buildShapeData=function(t,e){if(t.shapes&&t.shapes.length){var i=t.shapes[0];if(i.it){var r=i.it[i.it.length-1];r.s&&(r.s.k[0]=e,r.s.k[1]=e)}}return t},SVGTextLottieElement.prototype.buildNewText=function(){var t,e;this.addDynamicProperty(this);var i=this.textProperty.currentData;this.renderedLetters=createSizedArray(i?i.l.length:0),i.fc?this.layerElement.setAttribute("fill",this.buildColor(i.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),i.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(i.sc)),this.layerElement.setAttribute("stroke-width",i.sw)),this.layerElement.setAttribute("font-size",i.finalSize);var r=this.globalData.fontManager.getFontByName(i.f);if(r.fClass)this.layerElement.setAttribute("class",r.fClass);else{this.layerElement.setAttribute("font-family",r.fFamily);var s=i.fWeight,a=i.fStyle;this.layerElement.setAttribute("font-style",a),this.layerElement.setAttribute("font-weight",s)}this.layerElement.setAttribute("aria-label",i.t);var n,o=i.l||[],h=!!this.globalData.fontManager.chars;e=o.length;var l=this.mHelper,p=this.data.singleShape,f=0,m=0,c=!0,u=.001*i.tr*i.finalSize;if(!p||h||i.sz){var d,y=this.textSpans.length;for(t=0;t<e;t+=1){if(this.textSpans[t]||(this.textSpans[t]={span:null,childSpan:null,glyph:null}),!h||!p||0===t){if(n=y>t?this.textSpans[t].span:createNS(h?"g":"text"),y<=t){if(n.setAttribute("stroke-linecap","butt"),n.setAttribute("stroke-linejoin","round"),n.setAttribute("stroke-miterlimit","4"),this.textSpans[t].span=n,h){var g=createNS("g");n.appendChild(g),this.textSpans[t].childSpan=g}this.textSpans[t].span=n,this.layerElement.appendChild(n)}n.style.display="inherit"}if(l.reset(),p&&(o[t].n&&(f=-u,m+=i.yOffset,m+=c?1:0,c=!1),this.applyTextPropertiesToMatrix(i,l,o[t].line,f,m),f+=o[t].l||0,f+=u),h){var v;if(1===(d=this.globalData.fontManager.getCharData(i.finalText[t],r.fStyle,this.globalData.fontManager.getFontByName(i.f).fFamily)).t)v=new SVGCompElement(d.data,this.globalData,this);else{var b=emptyShapeData;d.data&&d.data.shapes&&(b=this.buildShapeData(d.data,i.finalSize)),v=new SVGShapeElement(b,this.globalData,this)}if(this.textSpans[t].glyph){var P=this.textSpans[t].glyph;this.textSpans[t].childSpan.removeChild(P.layerElement),P.destroy()}this.textSpans[t].glyph=v,v._debug=!0,v.prepareFrame(0),v.renderFrame(),this.textSpans[t].childSpan.appendChild(v.layerElement),1===d.t&&this.textSpans[t].childSpan.setAttribute("transform","scale("+i.finalSize/100+","+i.finalSize/100+")")}else p&&n.setAttribute("transform","translate("+l.props[12]+","+l.props[13]+")"),n.textContent=o[t].val,n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}p&&n&&n.setAttribute("d","")}else{var E=this.textContainer,x="start";switch(i.j){case 1:x="end";break;case 2:x="middle";break;default:x="start"}E.setAttribute("text-anchor",x),E.setAttribute("letter-spacing",u);var S=this.buildTextContents(i.finalText);for(e=S.length,m=i.ps?i.ps[1]+i.ascent:0,t=0;t<e;t+=1)(n=this.textSpans[t].span||createNS("tspan")).textContent=S[t],n.setAttribute("x",0),n.setAttribute("y",m),n.style.display="inherit",E.appendChild(n),this.textSpans[t]||(this.textSpans[t]={span:null,glyph:null}),this.textSpans[t].span=n,m+=i.finalLineHeight;this.layerElement.appendChild(E)}for(;t<this.textSpans.length;)this.textSpans[t].span.style.display="none",t+=1;this._sizeChanged=!0},SVGTextLottieElement.prototype.sourceRectAtTime=function(){if(this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged){this._sizeChanged=!1;var t=this.layerElement.getBBox();this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}}return this.bbox},SVGTextLottieElement.prototype.getValue=function(){var t,e,i=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<i;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf&&(this._mdf=!0))},SVGTextLottieElement.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){var t,e;this._sizeChanged=!0;var i,r,s,a=this.textAnimator.renderedLetters,n=this.textProperty.currentData.l;for(e=n.length,t=0;t<e;t+=1)n[t].n||(i=a[t],r=this.textSpans[t].span,(s=this.textSpans[t].glyph)&&s.renderFrame(),i._mdf.m&&r.setAttribute("transform",i.m),i._mdf.o&&r.setAttribute("opacity",i.o),i._mdf.sw&&r.setAttribute("stroke-width",i.sw),i._mdf.sc&&r.setAttribute("stroke",i.sc),i._mdf.fc&&r.setAttribute("fill",i.fc))}},extendPrototype([IImageElement],ISolidElement),ISolidElement.prototype.createContent=function(){var t=createNS("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},NullElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},NullElement.prototype.renderFrame=function(){},NullElement.prototype.getBaseElement=function(){return null},NullElement.prototype.destroy=function(){},NullElement.prototype.sourceRectAtTime=function(){},NullElement.prototype.hide=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement],NullElement),extendPrototype([BaseRenderer],SVGRendererBase),SVGRendererBase.prototype.createNull=function(t){return new NullElement(t,this.globalData,this)},SVGRendererBase.prototype.createShape=function(t){return new SVGShapeElement(t,this.globalData,this)},SVGRendererBase.prototype.createText=function(t){return new SVGTextLottieElement(t,this.globalData,this)},SVGRendererBase.prototype.createImage=function(t){return new IImageElement(t,this.globalData,this)},SVGRendererBase.prototype.createSolid=function(t){return new ISolidElement(t,this.globalData,this)},SVGRendererBase.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var i=createNS("clipPath"),r=createNS("rect");r.setAttribute("width",t.w),r.setAttribute("height",t.h),r.setAttribute("x",0),r.setAttribute("y",0);var s=createElementID();i.setAttribute("id",s),i.appendChild(r),this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),e.appendChild(i),this.layers=t.layers,this.elements=createSizedArray(t.layers.length)},SVGRendererBase.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},SVGRendererBase.prototype.updateContainerSize=function(){},SVGRendererBase.prototype.findIndexByInd=function(t){var e=0,i=this.layers.length;for(e=0;e<i;e+=1)if(this.layers[e].ind===t)return e;return-1},SVGRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){e[t]=!0;var i=this.createItem(this.layers[t]);if(e[t]=i,getExpressionsPlugin()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(i),i.initExpressions()),this.appendElementInPos(i,t),this.layers[t].tt){var r="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1;if(-1===r)return;if(this.elements[r]&&!0!==this.elements[r]){var s=e[r].getMatte(this.layers[t].tt);i.setMatte(s)}else this.buildItem(r),this.addPendingElement(i)}}},SVGRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,i=this.elements.length;e<i;){if(this.elements[e]===t){var r="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,s=this.elements[r].getMatte(this.layers[e].tt);t.setMatte(s);break}e+=1}}},SVGRendererBase.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){var e;null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var i=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=i-1;e>=0;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<i;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},SVGRendererBase.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){for(var r,s=0;s<e;)this.elements[s]&&!0!==this.elements[s]&&this.elements[s].getBaseElement()&&(r=this.elements[s].getBaseElement()),s+=1;r?this.layerElement.insertBefore(i,r):this.layerElement.appendChild(i)}},SVGRendererBase.prototype.hide=function(){this.layerElement.style.display="none"},SVGRendererBase.prototype.show=function(){this.layerElement.style.display="block"},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement,RenderableDOMElement],ICompElement),ICompElement.prototype.initElement=function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},ICompElement.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var i,r=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),i=r-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&(this.elements[i].prepareFrame(this.renderedFrame-this.layers[i].st),this.elements[i]._mdf&&(this._mdf=!0))}},ICompElement.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},ICompElement.prototype.setElements=function(t){this.elements=t},ICompElement.prototype.getElements=function(){return this.elements},ICompElement.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},ICompElement.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},extendPrototype([SVGRendererBase,ICompElement,SVGBaseElement],SVGCompElement),SVGCompElement.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},extendPrototype([SVGRendererBase],SVGRenderer),SVGRenderer.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)};var registeredEffects={};function CVEffects(t){var e,i,r=t.data.ef?t.data.ef.length:0;for(this.filters=[],e=0;e<r;e+=1){i=null;var s=t.data.ef[e].ty;if(registeredEffects[s])i=new(0,registeredEffects[s].effect)(t.effectsManager.effectElements[e],t);i&&this.filters.push(i)}this.filters.length&&t.addRenderableComponent(this)}function registerEffect(t,e){registeredEffects[t]={effect:e}}function HBaseElement(){}function HSolidElement(t,e,i){this.initElement(t,e,i)}function HShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.shapesContainer=createNS("g"),this.initElement(t,e,i),this.prevViewData=[],this.currentBBox={x:999999,y:-999999,h:0,w:0}}function HTextElement(t,e,i){this.textSpans=[],this.textPaths=[],this.currentBBox={x:999999,y:-999999,h:0,w:0},this.renderType="svg",this.isMasked=!1,this.initElement(t,e,i)}function HCameraElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initHierarchy();var r=PropertyFactory.getProp;if(this.pe=r(this,t.pe,0,0,this),t.ks.p.s?(this.px=r(this,t.ks.p.x,1,0,this),this.py=r(this,t.ks.p.y,1,0,this),this.pz=r(this,t.ks.p.z,1,0,this)):this.p=r(this,t.ks.p,1,0,this),t.ks.a&&(this.a=r(this,t.ks.a,1,0,this)),t.ks.or.k.length&&t.ks.or.k[0].to){var s,a=t.ks.or.k.length;for(s=0;s<a;s+=1)t.ks.or.k[s].to=null,t.ks.or.k[s].ti=null}this.or=r(this,t.ks.or,1,degToRads,this),this.or.sh=!0,this.rx=r(this,t.ks.rx,0,degToRads,this),this.ry=r(this,t.ks.ry,0,degToRads,this),this.rz=r(this,t.ks.rz,0,degToRads,this),this.mat=new Matrix,this._prevMat=new Matrix,this._isFirstFrame=!0,this.finalTransform={mProp:this}}function HImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.initElement(t,e,i)}function HybridRendererBase(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"}},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}function HCompElement(t,e,i){this.layers=t.layers,this.supports3d=!t.hasMask,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function HybridRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"},runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}CVEffects.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},CVEffects.prototype.getEffects=function(t){var e,i=this.filters.length,r=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&r.push(this.filters[e]);return r},HBaseElement.prototype={checkBlendMode:function(){},initRendererElement:function(){this.baseElement=createTag(this.data.tg||"div"),this.data.hasMask?(this.svgElement=createNS("svg"),this.layerElement=createNS("g"),this.maskedElement=this.layerElement,this.svgElement.appendChild(this.layerElement),this.baseElement.appendChild(this.svgElement)):this.layerElement=this.baseElement,styleDiv(this.baseElement)},createContainerElements:function(){this.renderableEffectsManager=new CVEffects(this),this.transformedElement=this.baseElement,this.maskedElement=this.layerElement,this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0!==this.data.bm&&this.setBlendMode()},renderElement:function(){var t=this.transformedElement?this.transformedElement.style:{};if(this.finalTransform._matMdf){var e=this.finalTransform.mat.toCSS();t.transform=e,t.webkitTransform=e}this.finalTransform._opMdf&&(t.opacity=this.finalTransform.mProp.o.v)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},destroy:function(){this.layerElement=null,this.transformedElement=null,this.matteElement&&(this.matteElement=null),this.maskManager&&(this.maskManager.destroy(),this.maskManager=null)},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData)},addEffects:function(){},setMatte:function(){}},HBaseElement.prototype.getBaseElement=SVGBaseElement.prototype.getBaseElement,HBaseElement.prototype.destroyBaseElement=HBaseElement.prototype.destroy,HBaseElement.prototype.buildElementParenting=BaseRenderer.prototype.buildElementParenting,extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],HSolidElement),HSolidElement.prototype.createContent=function(){var t;this.data.hasMask?((t=createNS("rect")).setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.svgElement.setAttribute("width",this.data.sw),this.svgElement.setAttribute("height",this.data.sh)):((t=createTag("div")).style.width=this.data.sw+"px",t.style.height=this.data.sh+"px",t.style.backgroundColor=this.data.sc),this.layerElement.appendChild(t)},extendPrototype([BaseElement,TransformElement,HSolidElement,SVGShapeElement,HBaseElement,HierarchyElement,FrameElement,RenderableElement],HShapeElement),HShapeElement.prototype._renderShapeFrame=HShapeElement.prototype.renderInnerContent,HShapeElement.prototype.createContent=function(){var t;if(this.baseElement.style.fontSize=0,this.data.hasMask)this.layerElement.appendChild(this.shapesContainer),t=this.svgElement;else{t=createNS("svg");var e=this.comp.data?this.comp.data:this.globalData.compSize;t.setAttribute("width",e.w),t.setAttribute("height",e.h),t.appendChild(this.shapesContainer),this.layerElement.appendChild(t)}this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.shapesContainer,0,[],!0),this.filterUniqueShapes(),this.shapeCont=t},HShapeElement.prototype.getTransformedPoint=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)e=t[i].mProps.v.applyToPointArray(e[0],e[1],0);return e},HShapeElement.prototype.calculateShapeBoundingBox=function(t,e){var i,r,s,a,n,o=t.sh.v,h=t.transformers,l=o._length;if(!(l<=1)){for(i=0;i<l-1;i+=1)r=this.getTransformedPoint(h,o.v[i]),s=this.getTransformedPoint(h,o.o[i]),a=this.getTransformedPoint(h,o.i[i+1]),n=this.getTransformedPoint(h,o.v[i+1]),this.checkBounds(r,s,a,n,e);o.c&&(r=this.getTransformedPoint(h,o.v[i]),s=this.getTransformedPoint(h,o.o[i]),a=this.getTransformedPoint(h,o.i[0]),n=this.getTransformedPoint(h,o.v[0]),this.checkBounds(r,s,a,n,e))}},HShapeElement.prototype.checkBounds=function(t,e,i,r,s){this.getBoundsOfCurve(t,e,i,r);var a=this.shapeBoundingBox;s.x=bmMin(a.left,s.x),s.xMax=bmMax(a.right,s.xMax),s.y=bmMin(a.top,s.y),s.yMax=bmMax(a.bottom,s.yMax)},HShapeElement.prototype.shapeBoundingBox={left:0,right:0,top:0,bottom:0},HShapeElement.prototype.tempBoundingBox={x:0,xMax:0,y:0,yMax:0,width:0,height:0},HShapeElement.prototype.getBoundsOfCurve=function(t,e,i,r){for(var s,a,n,o,h,l,p,f=[[t[0],r[0]],[t[1],r[1]]],m=0;m<2;++m)a=6*t[m]-12*e[m]+6*i[m],s=-3*t[m]+9*e[m]-9*i[m]+3*r[m],n=3*e[m]-3*t[m],a|=0,n|=0,0===(s|=0)&&0===a||(0===s?(o=-n/a)>0&&o<1&&f[m].push(this.calculateF(o,t,e,i,r,m)):(h=a*a-4*n*s)>=0&&((l=(-a+bmSqrt(h))/(2*s))>0&&l<1&&f[m].push(this.calculateF(l,t,e,i,r,m)),(p=(-a-bmSqrt(h))/(2*s))>0&&p<1&&f[m].push(this.calculateF(p,t,e,i,r,m))));this.shapeBoundingBox.left=bmMin.apply(null,f[0]),this.shapeBoundingBox.top=bmMin.apply(null,f[1]),this.shapeBoundingBox.right=bmMax.apply(null,f[0]),this.shapeBoundingBox.bottom=bmMax.apply(null,f[1])},HShapeElement.prototype.calculateF=function(t,e,i,r,s,a){return bmPow(1-t,3)*e[a]+3*bmPow(1-t,2)*t*i[a]+3*(1-t)*bmPow(t,2)*r[a]+bmPow(t,3)*s[a]},HShapeElement.prototype.calculateBoundingBox=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)t[i]&&t[i].sh?this.calculateShapeBoundingBox(t[i],e):t[i]&&t[i].it?this.calculateBoundingBox(t[i].it,e):t[i]&&t[i].style&&t[i].w&&this.expandStrokeBoundingBox(t[i].w,e)},HShapeElement.prototype.expandStrokeBoundingBox=function(t,e){var i=0;if(t.keyframes){for(var r=0;r<t.keyframes.length;r+=1){var s=t.keyframes[r].s;s>i&&(i=s)}i*=t.mult}else i=t.v*t.mult;e.x-=i,e.xMax+=i,e.y-=i,e.yMax+=i},HShapeElement.prototype.currentBoxContains=function(t){return this.currentBBox.x<=t.x&&this.currentBBox.y<=t.y&&this.currentBBox.width+this.currentBBox.x>=t.x+t.width&&this.currentBBox.height+this.currentBBox.y>=t.y+t.height},HShapeElement.prototype.renderInnerContent=function(){if(this._renderShapeFrame(),!this.hidden&&(this._isFirstFrame||this._mdf)){var t=this.tempBoundingBox,e=999999;if(t.x=e,t.xMax=-e,t.y=e,t.yMax=-e,this.calculateBoundingBox(this.itemsData,t),t.width=t.xMax<t.x?0:t.xMax-t.x,t.height=t.yMax<t.y?0:t.yMax-t.y,this.currentBoxContains(t))return;var i=!1;if(this.currentBBox.w!==t.width&&(this.currentBBox.w=t.width,this.shapeCont.setAttribute("width",t.width),i=!0),this.currentBBox.h!==t.height&&(this.currentBBox.h=t.height,this.shapeCont.setAttribute("height",t.height),i=!0),i||this.currentBBox.x!==t.x||this.currentBBox.y!==t.y){this.currentBBox.w=t.width,this.currentBBox.h=t.height,this.currentBBox.x=t.x,this.currentBBox.y=t.y,this.shapeCont.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h);var r=this.shapeCont.style,s="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)";r.transform=s,r.webkitTransform=s}}},extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],HTextElement),HTextElement.prototype.createContent=function(){if(this.isMasked=this.checkMasks(),this.isMasked){this.renderType="svg",this.compW=this.comp.data.w,this.compH=this.comp.data.h,this.svgElement.setAttribute("width",this.compW),this.svgElement.setAttribute("height",this.compH);var t=createNS("g");this.maskedElement.appendChild(t),this.innerElem=t}else this.renderType="html",this.innerElem=this.layerElement;this.checkParenting()},HTextElement.prototype.buildNewText=function(){var t=this.textProperty.currentData;this.renderedLetters=createSizedArray(t.l?t.l.length:0);var e=this.innerElem.style,i=t.fc?this.buildColor(t.fc):"rgba(0,0,0,0)";e.fill=i,e.color=i,t.sc&&(e.stroke=this.buildColor(t.sc),e.strokeWidth=t.sw+"px");var r,s,a=this.globalData.fontManager.getFontByName(t.f);if(!this.globalData.fontManager.chars)if(e.fontSize=t.finalSize+"px",e.lineHeight=t.finalSize+"px",a.fClass)this.innerElem.className=a.fClass;else{e.fontFamily=a.fFamily;var n=t.fWeight,o=t.fStyle;e.fontStyle=o,e.fontWeight=n}var h,l,p,f=t.l;s=f.length;var m,c=this.mHelper,u="",d=0;for(r=0;r<s;r+=1){if(this.globalData.fontManager.chars?(this.textPaths[d]?h=this.textPaths[d]:((h=createNS("path")).setAttribute("stroke-linecap",lineCapEnum[1]),h.setAttribute("stroke-linejoin",lineJoinEnum[2]),h.setAttribute("stroke-miterlimit","4")),this.isMasked||(this.textSpans[d]?p=(l=this.textSpans[d]).children[0]:((l=createTag("div")).style.lineHeight=0,(p=createNS("svg")).appendChild(h),styleDiv(l)))):this.isMasked?h=this.textPaths[d]?this.textPaths[d]:createNS("text"):this.textSpans[d]?(l=this.textSpans[d],h=this.textPaths[d]):(styleDiv(l=createTag("span")),styleDiv(h=createTag("span")),l.appendChild(h)),this.globalData.fontManager.chars){var y,g=this.globalData.fontManager.getCharData(t.finalText[r],a.fStyle,this.globalData.fontManager.getFontByName(t.f).fFamily);if(y=g?g.data:null,c.reset(),y&&y.shapes&&y.shapes.length&&(m=y.shapes[0].it,c.scale(t.finalSize/100,t.finalSize/100),u=this.createPathShape(c,m),h.setAttribute("d",u)),this.isMasked)this.innerElem.appendChild(h);else{if(this.innerElem.appendChild(l),y&&y.shapes){document.body.appendChild(p);var v=p.getBBox();p.setAttribute("width",v.width+2),p.setAttribute("height",v.height+2),p.setAttribute("viewBox",v.x-1+" "+(v.y-1)+" "+(v.width+2)+" "+(v.height+2));var b=p.style,P="translate("+(v.x-1)+"px,"+(v.y-1)+"px)";b.transform=P,b.webkitTransform=P,f[r].yOffset=v.y-1}else p.setAttribute("width",1),p.setAttribute("height",1);l.appendChild(p)}}else if(h.textContent=f[r].val,h.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),this.isMasked)this.innerElem.appendChild(h);else{this.innerElem.appendChild(l);var E=h.style,x="translate3d(0,"+-t.finalSize/1.2+"px,0)";E.transform=x,E.webkitTransform=x}this.isMasked?this.textSpans[d]=h:this.textSpans[d]=l,this.textSpans[d].style.display="block",this.textPaths[d]=h,d+=1}for(;d<this.textSpans.length;)this.textSpans[d].style.display="none",d+=1},HTextElement.prototype.renderInnerContent=function(){var t;if(this.validateText(),this.data.singleShape){if(!this._isFirstFrame&&!this.lettersChangedFlag)return;if(this.isMasked&&this.finalTransform._matMdf){this.svgElement.setAttribute("viewBox",-this.finalTransform.mProp.p.v[0]+" "+-this.finalTransform.mProp.p.v[1]+" "+this.compW+" "+this.compH),t=this.svgElement.style;var e="translate("+-this.finalTransform.mProp.p.v[0]+"px,"+-this.finalTransform.mProp.p.v[1]+"px)";t.transform=e,t.webkitTransform=e}}if(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag){var i,r,s,a,n,o=0,h=this.textAnimator.renderedLetters,l=this.textProperty.currentData.l;for(r=l.length,i=0;i<r;i+=1)l[i].n?o+=1:(a=this.textSpans[i],n=this.textPaths[i],s=h[o],o+=1,s._mdf.m&&(this.isMasked?a.setAttribute("transform",s.m):(a.style.webkitTransform=s.m,a.style.transform=s.m)),a.style.opacity=s.o,s.sw&&s._mdf.sw&&n.setAttribute("stroke-width",s.sw),s.sc&&s._mdf.sc&&n.setAttribute("stroke",s.sc),s.fc&&s._mdf.fc&&(n.setAttribute("fill",s.fc),n.style.color=s.fc));if(this.innerElem.getBBox&&!this.hidden&&(this._isFirstFrame||this._mdf)){var p=this.innerElem.getBBox();this.currentBBox.w!==p.width&&(this.currentBBox.w=p.width,this.svgElement.setAttribute("width",p.width)),this.currentBBox.h!==p.height&&(this.currentBBox.h=p.height,this.svgElement.setAttribute("height",p.height));if(this.currentBBox.w!==p.width+2||this.currentBBox.h!==p.height+2||this.currentBBox.x!==p.x-1||this.currentBBox.y!==p.y-1){this.currentBBox.w=p.width+2,this.currentBBox.h=p.height+2,this.currentBBox.x=p.x-1,this.currentBBox.y=p.y-1,this.svgElement.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h),t=this.svgElement.style;var f="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)";t.transform=f,t.webkitTransform=f}}}},extendPrototype([BaseElement,FrameElement,HierarchyElement],HCameraElement),HCameraElement.prototype.setup=function(){var t,e,i,r,s=this.comp.threeDElements.length;for(t=0;t<s;t+=1)if("3d"===(e=this.comp.threeDElements[t]).type){i=e.perspectiveElem.style,r=e.container.style;var a=this.pe.v+"px",n="0px 0px 0px",o="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";i.perspective=a,i.webkitPerspective=a,r.transformOrigin=n,r.mozTransformOrigin=n,r.webkitTransformOrigin=n,i.transform=o,i.webkitTransform=o}},HCameraElement.prototype.createElements=function(){},HCameraElement.prototype.hide=function(){},HCameraElement.prototype.renderFrame=function(){var t,e,i=this._isFirstFrame;if(this.hierarchy)for(e=this.hierarchy.length,t=0;t<e;t+=1)i=this.hierarchy[t].finalTransform.mProp._mdf||i;if(i||this.pe._mdf||this.p&&this.p._mdf||this.px&&(this.px._mdf||this.py._mdf||this.pz._mdf)||this.rx._mdf||this.ry._mdf||this.rz._mdf||this.or._mdf||this.a&&this.a._mdf){if(this.mat.reset(),this.hierarchy)for(t=e=this.hierarchy.length-1;t>=0;t-=1){var r=this.hierarchy[t].finalTransform.mProp;this.mat.translate(-r.p.v[0],-r.p.v[1],r.p.v[2]),this.mat.rotateX(-r.or.v[0]).rotateY(-r.or.v[1]).rotateZ(r.or.v[2]),this.mat.rotateX(-r.rx.v).rotateY(-r.ry.v).rotateZ(r.rz.v),this.mat.scale(1/r.s.v[0],1/r.s.v[1],1/r.s.v[2]),this.mat.translate(r.a.v[0],r.a.v[1],r.a.v[2])}if(this.p?this.mat.translate(-this.p.v[0],-this.p.v[1],this.p.v[2]):this.mat.translate(-this.px.v,-this.py.v,this.pz.v),this.a){var s;s=this.p?[this.p.v[0]-this.a.v[0],this.p.v[1]-this.a.v[1],this.p.v[2]-this.a.v[2]]:[this.px.v-this.a.v[0],this.py.v-this.a.v[1],this.pz.v-this.a.v[2]];var a=Math.sqrt(Math.pow(s[0],2)+Math.pow(s[1],2)+Math.pow(s[2],2)),n=[s[0]/a,s[1]/a,s[2]/a],o=Math.sqrt(n[2]*n[2]+n[0]*n[0]),h=Math.atan2(n[1],o),l=Math.atan2(n[0],-n[2]);this.mat.rotateY(l).rotateX(-h)}this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v),this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]),this.mat.translate(this.globalData.compSize.w/2,this.globalData.compSize.h/2,0),this.mat.translate(0,0,this.pe.v);var p=!this._prevMat.equals(this.mat);if((p||this.pe._mdf)&&this.comp.threeDElements){var f,m,c;for(e=this.comp.threeDElements.length,t=0;t<e;t+=1)if("3d"===(f=this.comp.threeDElements[t]).type){if(p){var u=this.mat.toCSS();(c=f.container.style).transform=u,c.webkitTransform=u}this.pe._mdf&&((m=f.perspectiveElem.style).perspective=this.pe.v+"px",m.webkitPerspective=this.pe.v+"px")}this.mat.clone(this._prevMat)}}this._isFirstFrame=!1},HCameraElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},HCameraElement.prototype.destroy=function(){},HCameraElement.prototype.getBaseElement=function(){return null},extendPrototype([BaseElement,TransformElement,HBaseElement,HSolidElement,HierarchyElement,FrameElement,RenderableElement],HImageElement),HImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData),e=new Image;this.data.hasMask?(this.imageElem=createNS("image"),this.imageElem.setAttribute("width",this.assetData.w+"px"),this.imageElem.setAttribute("height",this.assetData.h+"px"),this.imageElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.imageElem),this.baseElement.setAttribute("width",this.assetData.w),this.baseElement.setAttribute("height",this.assetData.h)):this.layerElement.appendChild(e),e.crossOrigin="anonymous",e.src=t,this.data.ln&&this.baseElement.setAttribute("id",this.data.ln)},extendPrototype([BaseRenderer],HybridRendererBase),HybridRendererBase.prototype.buildItem=SVGRenderer.prototype.buildItem,HybridRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},HybridRendererBase.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){var r=this.layers[e];if(r.ddd&&this.supports3d)this.addTo3dContainer(i,e);else if(this.threeDElements)this.addTo3dContainer(i,e);else{for(var s,a,n=0;n<e;)this.elements[n]&&!0!==this.elements[n]&&this.elements[n].getBaseElement&&(a=this.elements[n],s=(this.layers[n].ddd?this.getThreeDContainerByPos(n):a.getBaseElement())||s),n+=1;s?r.ddd&&this.supports3d||this.layerElement.insertBefore(i,s):r.ddd&&this.supports3d||this.layerElement.appendChild(i)}}},HybridRendererBase.prototype.createShape=function(t){return this.supports3d?new HShapeElement(t,this.globalData,this):new SVGShapeElement(t,this.globalData,this)},HybridRendererBase.prototype.createText=function(t){return this.supports3d?new HTextElement(t,this.globalData,this):new SVGTextLottieElement(t,this.globalData,this)},HybridRendererBase.prototype.createCamera=function(t){return this.camera=new HCameraElement(t,this.globalData,this),this.camera},HybridRendererBase.prototype.createImage=function(t){return this.supports3d?new HImageElement(t,this.globalData,this):new IImageElement(t,this.globalData,this)},HybridRendererBase.prototype.createSolid=function(t){return this.supports3d?new HSolidElement(t,this.globalData,this):new ISolidElement(t,this.globalData,this)},HybridRendererBase.prototype.createNull=SVGRenderer.prototype.createNull,HybridRendererBase.prototype.getThreeDContainerByPos=function(t){for(var e=0,i=this.threeDElements.length;e<i;){if(this.threeDElements[e].startPos<=t&&this.threeDElements[e].endPos>=t)return this.threeDElements[e].perspectiveElem;e+=1}return null},HybridRendererBase.prototype.createThreeDContainer=function(t,e){var i,r,s=createTag("div");styleDiv(s);var a=createTag("div");if(styleDiv(a),"3d"===e){(i=s.style).width=this.globalData.compSize.w+"px",i.height=this.globalData.compSize.h+"px";var n="50% 50%";i.webkitTransformOrigin=n,i.mozTransformOrigin=n,i.transformOrigin=n;var o="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";(r=a.style).transform=o,r.webkitTransform=o}s.appendChild(a);var h={container:a,perspectiveElem:s,startPos:t,endPos:t,type:e};return this.threeDElements.push(h),h},HybridRendererBase.prototype.build3dContainers=function(){var t,e,i=this.layers.length,r="";for(t=0;t<i;t+=1)this.layers[t].ddd&&3!==this.layers[t].ty?("3d"!==r&&(r="3d",e=this.createThreeDContainer(t,"3d")),e.endPos=Math.max(e.endPos,t)):("2d"!==r&&(r="2d",e=this.createThreeDContainer(t,"2d")),e.endPos=Math.max(e.endPos,t));for(t=(i=this.threeDElements.length)-1;t>=0;t-=1)this.resizerElem.appendChild(this.threeDElements[t].perspectiveElem)},HybridRendererBase.prototype.addTo3dContainer=function(t,e){for(var i=0,r=this.threeDElements.length;i<r;){if(e<=this.threeDElements[i].endPos){for(var s,a=this.threeDElements[i].startPos;a<e;)this.elements[a]&&this.elements[a].getBaseElement&&(s=this.elements[a].getBaseElement()),a+=1;s?this.threeDElements[i].container.insertBefore(t,s):this.threeDElements[i].container.appendChild(t);break}i+=1}},HybridRendererBase.prototype.configAnimation=function(t){var e=createTag("div"),i=this.animationItem.wrapper,r=e.style;r.width=t.w+"px",r.height=t.h+"px",this.resizerElem=e,styleDiv(e),r.transformStyle="flat",r.mozTransformStyle="flat",r.webkitTransformStyle="flat",this.renderConfig.className&&e.setAttribute("class",this.renderConfig.className),i.appendChild(e),r.overflow="hidden";var s=createNS("svg");s.setAttribute("width","1"),s.setAttribute("height","1"),styleDiv(s),this.resizerElem.appendChild(s);var a=createNS("defs");s.appendChild(a),this.data=t,this.setupGlobalData(t,s),this.globalData.defs=a,this.layers=t.layers,this.layerElement=this.resizerElem,this.build3dContainers(),this.updateContainerSize()},HybridRendererBase.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.animationItem.container=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},HybridRendererBase.prototype.updateContainerSize=function(){var t,e,i,r,s=this.animationItem.wrapper.offsetWidth,a=this.animationItem.wrapper.offsetHeight,n=s/a;this.globalData.compSize.w/this.globalData.compSize.h>n?(t=s/this.globalData.compSize.w,e=s/this.globalData.compSize.w,i=0,r=(a-this.globalData.compSize.h*(s/this.globalData.compSize.w))/2):(t=a/this.globalData.compSize.h,e=a/this.globalData.compSize.h,i=(s-this.globalData.compSize.w*(a/this.globalData.compSize.h))/2,r=0);var o=this.resizerElem.style;o.webkitTransform="matrix3d("+t+",0,0,0,0,"+e+",0,0,0,0,1,0,"+i+","+r+",0,1)",o.transform=o.webkitTransform},HybridRendererBase.prototype.renderFrame=SVGRenderer.prototype.renderFrame,HybridRendererBase.prototype.hide=function(){this.resizerElem.style.display="none"},HybridRendererBase.prototype.show=function(){this.resizerElem.style.display="block"},HybridRendererBase.prototype.initItems=function(){if(this.buildAllItems(),this.camera)this.camera.setup();else{var t,e=this.globalData.compSize.w,i=this.globalData.compSize.h,r=this.threeDElements.length;for(t=0;t<r;t+=1){var s=this.threeDElements[t].perspectiveElem.style;s.webkitPerspective=Math.sqrt(Math.pow(e,2)+Math.pow(i,2))+"px",s.perspective=s.webkitPerspective}}},HybridRendererBase.prototype.searchExtraCompositions=function(t){var e,i=t.length,r=createTag("div");for(e=0;e<i;e+=1)if(t[e].xt){var s=this.createComp(t[e],r,this.globalData.comp,null);s.initExpressions(),this.globalData.projectInterface.registerComposition(s)}},extendPrototype([HybridRendererBase,ICompElement,HBaseElement],HCompElement),HCompElement.prototype._createBaseContainerElements=HCompElement.prototype.createContainerElements,HCompElement.prototype.createContainerElements=function(){this._createBaseContainerElements(),this.data.hasMask?(this.svgElement.setAttribute("width",this.data.w),this.svgElement.setAttribute("height",this.data.h),this.transformedElement=this.baseElement):this.transformedElement=this.layerElement},HCompElement.prototype.addTo3dContainer=function(t,e){for(var i,r=0;r<e;)this.elements[r]&&this.elements[r].getBaseElement&&(i=this.elements[r].getBaseElement()),r+=1;i?this.layerElement.insertBefore(t,i):this.layerElement.appendChild(t)},HCompElement.prototype.createComp=function(t){return this.supports3d?new HCompElement(t,this.globalData,this):new SVGCompElement(t,this.globalData,this)},extendPrototype([HybridRendererBase],HybridRenderer),HybridRenderer.prototype.createComp=function(t){return this.supports3d?new HCompElement(t,this.globalData,this):new SVGCompElement(t,this.globalData,this)},registerRenderer("html",HybridRenderer),ShapeModifiers.registerModifier("tm",TrimModifier),ShapeModifiers.registerModifier("pb",PuckerAndBloatModifier),ShapeModifiers.registerModifier("rp",RepeaterModifier),ShapeModifiers.registerModifier("rd",RoundCornersModifier),ShapeModifiers.registerModifier("zz",ZigZagModifier),ShapeModifiers.registerModifier("op",OffsetPathModifier);var CompExpressionInterface=function(t){function e(e){for(var i=0,r=t.layers.length;i<r;){if(t.layers[i].nm===e||t.layers[i].ind===e)return t.elements[i].layerInterface;i+=1}return null}return Object.defineProperty(e,"_name",{value:t.data.nm}),e.layer=e,e.pixelAspect=1,e.height=t.data.h||t.globalData.compSize.h,e.width=t.data.w||t.globalData.compSize.w,e.pixelAspect=1,e.frameDuration=1/t.globalData.frameRate,e.displayStartTime=0,e.numLayers=t.layers.length,e};function _typeof$2(t){return _typeof$2="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$2(t)}function seedRandom(t,e){var i,r=this,s=256,a="random",n=e.pow(s,6),o=e.pow(2,52),h=2*o,l=255;function p(t){var e,i=t.length,r=this,a=0,n=r.i=r.j=0,o=r.S=[];for(i||(t=[i++]);a<s;)o[a]=a++;for(a=0;a<s;a++)o[a]=o[n=l&n+t[a%i]+(e=o[a])],o[n]=e;r.g=function(t){for(var e,i=0,a=r.i,n=r.j,o=r.S;t--;)e=o[a=l&a+1],i=i*s+o[l&(o[a]=o[n=l&n+e])+(o[n]=e)];return r.i=a,r.j=n,i}}function f(t,e){return e.i=t.i,e.j=t.j,e.S=t.S.slice(),e}function m(t,e){var i,r=[],s=_typeof$2(t);if(e&&"object"==s)for(i in t)try{r.push(m(t[i],e-1))}catch(t){}return r.length?r:"string"==s?t:t+"\0"}function c(t,e){for(var i,r=t+"",s=0;s<r.length;)e[l&s]=l&(i^=19*e[l&s])+r.charCodeAt(s++);return u(e)}function u(t){return String.fromCharCode.apply(0,t)}e["seed"+a]=function(l,d,y){var g=[],v=c(m((d=!0===d?{entropy:!0}:d||{}).entropy?[l,u(t)]:null===l?function(){try{i;var e=new Uint8Array(s);return(r.crypto||r.msCrypto).getRandomValues(e),u(e)}catch(e){var a=r.navigator,n=a&&a.plugins;return[+new Date,r,n,r.screen,u(t)]}}():l,3),g),b=new p(g),P=function(){for(var t=b.g(6),e=n,i=0;t<o;)t=(t+i)*s,e*=s,i=b.g(1);for(;t>=h;)t/=2,e/=2,i>>>=1;return(t+i)/e};return P.int32=function(){return 0|b.g(4)},P.quick=function(){return b.g(4)/4294967296},P.double=P,c(u(b.S),t),(d.pass||y||function(t,i,r,s){return s&&(s.S&&f(s,b),t.state=function(){return f(b,{})}),r?(e[a]=t,i):t})(P,v,"global"in d?d.global:this==e,d.state)},c(e.random(),t)}function initialize$2(t){seedRandom([],t)}var propTypes={SHAPE:"shape"};function _typeof$1(t){return _typeof$1="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$1(t)}var ExpressionManager=function(){var ob={},Math=BMMath,window=null,document=null,XMLHttpRequest=null,fetch=null,frames=null,_lottieGlobal={};function resetFrame(){_lottieGlobal={}}function $bm_isInstanceOfArray(t){return t.constructor===Array||t.constructor===Float32Array}function isNumerable(t,e){return"number"===t||e instanceof Number||"boolean"===t||"string"===t}function $bm_neg(t){var e=_typeof$1(t);if("number"===e||t instanceof Number||"boolean"===e)return-t;if($bm_isInstanceOfArray(t)){var i,r=t.length,s=[];for(i=0;i<r;i+=1)s[i]=-t[i];return s}return t.propType?t.v:-t}initialize$2(BMMath);var easeInBez=BezierFactory.getBezierEasing(.333,0,.833,.833,"easeIn").get,easeOutBez=BezierFactory.getBezierEasing(.167,.167,.667,1,"easeOut").get,easeInOutBez=BezierFactory.getBezierEasing(.33,0,.667,1,"easeInOut").get;function sum(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e)||"string"===i||"string"===r)return t+e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]+=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t+e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]+e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}var add=sum;function sub(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e))return"string"===i&&(t=parseInt(t,10)),"string"===r&&(e=parseInt(e,10)),t-e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]-=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t-e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]-e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}function mul(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t*e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]*e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t*e[r];return i}return 0}function div(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t/e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]/e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t/e[r];return i}return 0}function mod(t,e){return"string"==typeof t&&(t=parseInt(t,10)),"string"==typeof e&&(e=parseInt(e,10)),t%e}var $bm_sum=sum,$bm_sub=sub,$bm_mul=mul,$bm_div=div,$bm_mod=mod;function clamp(t,e,i){if(e>i){var r=i;i=e,e=r}return Math.min(Math.max(t,e),i)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return e=e||0,Math.abs(t-e);var i;e||(e=helperLengthArray);var r=Math.min(t.length,e.length),s=0;for(i=0;i<r;i+=1)s+=Math.pow(e[i]-t[i],2);return Math.sqrt(s)}function normalize(t){return div(t,length(t))}function rgbToHsl(t){var e,i,r=t[0],s=t[1],a=t[2],n=Math.max(r,s,a),o=Math.min(r,s,a),h=(n+o)/2;if(n===o)e=0,i=0;else{var l=n-o;switch(i=h>.5?l/(2-n-o):l/(n+o),n){case r:e=(s-a)/l+(s<a?6:0);break;case s:e=(a-r)/l+2;break;case a:e=(r-s)/l+4}e/=6}return[e,i,h,t[3]]}function hue2rgb(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}function hslToRgb(t){var e,i,r,s=t[0],a=t[1],n=t[2];if(0===a)e=n,r=n,i=n;else{var o=n<.5?n*(1+a):n+a-n*a,h=2*n-o;e=hue2rgb(h,o,s+1/3),i=hue2rgb(h,o,s),r=hue2rgb(h,o,s-1/3)}return[e,i,r,t[3]]}function linear(t,e,i,r,s){if(void 0!==r&&void 0!==s||(r=e,s=i,e=0,i=1),i<e){var a=i;i=e,e=a}if(t<=e)return r;if(t>=i)return s;var n,o=i===e?0:(t-e)/(i-e);if(!r.length)return r+(s-r)*o;var h=r.length,l=createTypedArray("float32",h);for(n=0;n<h;n+=1)l[n]=r[n]+(s[n]-r[n])*o;return l}function random(t,e){if(void 0===e&&(void 0===t?(t=0,e=1):(e=t,t=void 0)),e.length){var i,r=e.length;t||(t=createTypedArray("float32",r));var s=createTypedArray("float32",r),a=BMMath.random();for(i=0;i<r;i+=1)s[i]=t[i]+a*(e[i]-t[i]);return s}return void 0===t&&(t=0),t+BMMath.random()*(e-t)}function createPath(t,e,i,r){var s,a=t.length,n=shapePool.newElement();n.setPathData(!!r,a);var o,h,l=[0,0];for(s=0;s<a;s+=1)o=e&&e[s]?e[s]:l,h=i&&i[s]?i[s]:l,n.setTripleAt(t[s][0],t[s][1],h[0]+t[s][0],h[1]+t[s][1],o[0]+t[s][0],o[1]+t[s][1],s,!0);return n}function initiateExpression(elem,data,property){function noOp(t){return t}if(!elem.globalData.renderConfig.runExpressions)return noOp;var val=data.x,needsVelocity=/velocity(?![\w\d])/.test(val),_needsRandom=-1!==val.indexOf("random"),elemType=elem.data.ty,transform,$bm_transform,content,effect,thisProperty=property;thisProperty._name=elem.data.nm,thisProperty.valueAtTime=thisProperty.getValueAtTime,Object.defineProperty(thisProperty,"value",{get:function(){return thisProperty.v}}),elem.comp.frameDuration=1/elem.comp.globalData.frameRate,elem.comp.displayStartTime=0;var inPoint=elem.data.ip/elem.comp.globalData.frameRate,outPoint=elem.data.op/elem.comp.globalData.frameRate,width=elem.data.sw?elem.data.sw:0,height=elem.data.sh?elem.data.sh:0,name=elem.data.nm,loopIn,loop_in,loopOut,loop_out,smooth,toWorld,fromWorld,fromComp,toComp,fromCompToSurface,position,rotation,anchorPoint,scale,thisLayer,thisComp,mask,valueAtTime,velocityAtTime,scoped_bm_rt,expression_function=eval("[function _expression_function(){"+val+";scoped_bm_rt=$bm_rt}]")[0],numKeys=property.kf?data.k.length:0,active=!this.data||!0!==this.data.hd,wiggle=function(t,e){var i,r,s=this.pv.length?this.pv.length:1,a=createTypedArray("float32",s);var n=Math.floor(5*time);for(i=0,r=0;i<n;){for(r=0;r<s;r+=1)a[r]+=-e+2*e*BMMath.random();i+=1}var o=5*time,h=o-Math.floor(o),l=createTypedArray("float32",s);if(s>1){for(r=0;r<s;r+=1)l[r]=this.pv[r]+a[r]+(-e+2*e*BMMath.random())*h;return l}return this.pv+a[0]+(-e+2*e*BMMath.random())*h}.bind(this);function loopInDuration(t,e){return loopIn(t,e,!0)}function loopOutDuration(t,e){return loopOut(t,e,!0)}thisProperty.loopIn&&(loopIn=thisProperty.loopIn.bind(thisProperty),loop_in=loopIn),thisProperty.loopOut&&(loopOut=thisProperty.loopOut.bind(thisProperty),loop_out=loopOut),thisProperty.smooth&&(smooth=thisProperty.smooth.bind(thisProperty)),this.getValueAtTime&&(valueAtTime=this.getValueAtTime.bind(this)),this.getVelocityAtTime&&(velocityAtTime=this.getVelocityAtTime.bind(this));var comp=elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface),time,velocity,value,text,textIndex,textTotal,selectorValue;function lookAt(t,e){var i=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],r=Math.atan2(i[0],Math.sqrt(i[1]*i[1]+i[2]*i[2]))/degToRads;return[-Math.atan2(i[1],i[2])/degToRads,r,0]}function easeOut(t,e,i,r,s){return applyEase(easeOutBez,t,e,i,r,s)}function easeIn(t,e,i,r,s){return applyEase(easeInBez,t,e,i,r,s)}function ease(t,e,i,r,s){return applyEase(easeInOutBez,t,e,i,r,s)}function applyEase(t,e,i,r,s,a){void 0===s?(s=i,a=r):e=(e-i)/(r-i),e>1?e=1:e<0&&(e=0);var n=t(e);if($bm_isInstanceOfArray(s)){var o,h=s.length,l=createTypedArray("float32",h);for(o=0;o<h;o+=1)l[o]=(a[o]-s[o])*n+s[o];return l}return(a-s)*n+s}function nearestKey(t){var e,i,r,s=data.k.length;if(data.k.length&&"number"!=typeof data.k[0])if(i=-1,(t*=elem.comp.globalData.frameRate)<data.k[0].t)i=1,r=data.k[0].t;else{for(e=0;e<s-1;e+=1){if(t===data.k[e].t){i=e+1,r=data.k[e].t;break}if(t>data.k[e].t&&t<data.k[e+1].t){t-data.k[e].t>data.k[e+1].t-t?(i=e+2,r=data.k[e+1].t):(i=e+1,r=data.k[e].t);break}}-1===i&&(i=e+1,r=data.k[e].t)}else i=0,r=0;var a={};return a.index=i,a.time=r/elem.comp.globalData.frameRate,a}function key(t){var e,i,r;if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]};var s=Object.prototype.hasOwnProperty.call(data.k[t],"s")?data.k[t].s:data.k[t-1].e;for(r=s.length,i=0;i<r;i+=1)e[i]=s[i],e.value[i]=s[i];return e}function framesToTime(t,e){return e||(e=elem.comp.globalData.frameRate),t/e}function timeToFrames(t,e){return t||0===t||(t=time),e||(e=elem.comp.globalData.frameRate),t*e}function seedRandom(t){BMMath.seedrandom(randSeed+t)}function sourceRectAtTime(){return elem.sourceRectAtTime()}function substring(t,e){return"string"==typeof value?void 0===e?value.substring(t):value.substring(t,e):""}function substr(t,e){return"string"==typeof value?void 0===e?value.substr(t):value.substr(t,e):""}function posterizeTime(t){time=0===t?0:Math.floor(time*t)/t,value=valueAtTime(time)}var index=elem.data.ind,hasParent=!(!elem.hierarchy||!elem.hierarchy.length),parent,randSeed=Math.floor(1e6*Math.random()),globalData=elem.globalData;function executeExpression(t){return value=t,this.frameExpressionId===elem.globalData.frameId&&"textSelector"!==this.propType?value:("textSelector"===this.propType&&(textIndex=this.textIndex,textTotal=this.textTotal,selectorValue=this.selectorValue),thisLayer||(text=elem.layerInterface.text,thisLayer=elem.layerInterface,thisComp=elem.comp.compInterface,toWorld=thisLayer.toWorld.bind(thisLayer),fromWorld=thisLayer.fromWorld.bind(thisLayer),fromComp=thisLayer.fromComp.bind(thisLayer),toComp=thisLayer.toComp.bind(thisLayer),mask=thisLayer.mask?thisLayer.mask.bind(thisLayer):null,fromCompToSurface=fromComp),transform||(transform=elem.layerInterface("ADBE Transform Group"),$bm_transform=transform,transform&&(anchorPoint=transform.anchorPoint)),4!==elemType||content||(content=thisLayer("ADBE Root Vectors Group")),effect||(effect=thisLayer(4)),(hasParent=!(!elem.hierarchy||!elem.hierarchy.length))&&!parent&&(parent=elem.hierarchy[0].layerInterface),time=this.comp.renderedFrame/this.comp.globalData.frameRate,_needsRandom&&seedRandom(randSeed+time),needsVelocity&&(velocity=velocityAtTime(time)),expression_function(),this.frameExpressionId=elem.globalData.frameId,scoped_bm_rt=scoped_bm_rt.propType===propTypes.SHAPE?scoped_bm_rt.v:scoped_bm_rt)}return executeExpression.__preventDeadCodeRemoval=[$bm_transform,anchorPoint,time,velocity,inPoint,outPoint,width,height,name,loop_in,loop_out,smooth,toComp,fromCompToSurface,toWorld,fromWorld,mask,position,rotation,scale,thisComp,numKeys,active,wiggle,loopInDuration,loopOutDuration,comp,lookAt,easeOut,easeIn,ease,nearestKey,key,text,textIndex,textTotal,selectorValue,framesToTime,timeToFrames,sourceRectAtTime,substring,substr,posterizeTime,index,globalData],executeExpression}return ob.initiateExpression=initiateExpression,ob.__preventDeadCodeRemoval=[window,document,XMLHttpRequest,fetch,frames,$bm_neg,add,$bm_sum,$bm_sub,$bm_mul,$bm_div,$bm_mod,clamp,radians_to_degrees,degreesToRadians,degrees_to_radians,normalize,rgbToHsl,hslToRgb,linear,random,createPath,_lottieGlobal],ob.resetFrame=resetFrame,ob}(),Expressions=function(){var t={};return t.initExpressions=function(t){var e=0,i=[];t.renderer.compInterface=CompExpressionInterface(t.renderer),t.renderer.globalData.projectInterface.registerComposition(t.renderer),t.renderer.globalData.pushExpression=function(){e+=1},t.renderer.globalData.popExpression=function(){0==(e-=1)&&function(){var t,e=i.length;for(t=0;t<e;t+=1)i[t].release();i.length=0}()},t.renderer.globalData.registerExpressionProperty=function(t){-1===i.indexOf(t)&&i.push(t)}},t.resetFrame=ExpressionManager.resetFrame,t}(),MaskManagerInterface=function(){function t(t,e){this._mask=t,this._data=e}Object.defineProperty(t.prototype,"maskPath",{get:function(){return this._mask.prop.k&&this._mask.prop.getValue(),this._mask.prop}}),Object.defineProperty(t.prototype,"maskOpacity",{get:function(){return this._mask.op.k&&this._mask.op.getValue(),100*this._mask.op.v}});return function(e){var i,r=createSizedArray(e.viewData.length),s=e.viewData.length;for(i=0;i<s;i+=1)r[i]=new t(e.viewData[i],e.masksProperties[i]);return function(t){for(i=0;i<s;){if(e.masksProperties[i].nm===t)return r[i];i+=1}return null}}}(),ExpressionPropertyInterface=function(){var t={pv:0,v:0,mult:1},e={pv:[0,0,0],v:[0,0,0],mult:1};function i(t,e,i){Object.defineProperty(t,"velocity",{get:function(){return e.getVelocityAtTime(e.comp.currentFrame)}}),t.numKeys=e.keyframes?e.keyframes.length:0,t.key=function(r){if(!t.numKeys)return 0;var s="";s="s"in e.keyframes[r-1]?e.keyframes[r-1].s:"e"in e.keyframes[r-2]?e.keyframes[r-2].e:e.keyframes[r-2].s;var a="unidimensional"===i?new Number(s):Object.assign({},s);return a.time=e.keyframes[r-1].t/e.elem.comp.globalData.frameRate,a.value="unidimensional"===i?s[0]:s,a},t.valueAtTime=e.getValueAtTime,t.speedAtTime=e.getSpeedAtTime,t.velocityAtTime=e.getVelocityAtTime,t.propertyGroup=e.propertyGroup}function r(){return t}return function(s){return s?"unidimensional"===s.propType?function(e){e&&"pv"in e||(e=t);var r=1/e.mult,s=e.pv*r,a=new Number(s);return a.value=s,i(a,e,"unidimensional"),function(){return e.k&&e.getValue(),s=e.v*r,a.value!==s&&((a=new Number(s)).value=s,a[0]=s,i(a,e,"unidimensional")),a}}(s):function(t){t&&"pv"in t||(t=e);var r=1/t.mult,s=t.data&&t.data.l||t.pv.length,a=createTypedArray("float32",s),n=createTypedArray("float32",s);return a.value=n,i(a,t,"multidimensional"),function(){t.k&&t.getValue();for(var e=0;e<s;e+=1)n[e]=t.v[e]*r,a[e]=n[e];return a}}(s):r}}(),TransformExpressionInterface=function(t){function e(t){switch(t){case"scale":case"Scale":case"ADBE Scale":case 6:return e.scale;case"rotation":case"Rotation":case"ADBE Rotation":case"ADBE Rotate Z":case 10:return e.rotation;case"ADBE Rotate X":return e.xRotation;case"ADBE Rotate Y":return e.yRotation;case"position":case"Position":case"ADBE Position":case 2:return e.position;case"ADBE Position_0":return e.xPosition;case"ADBE Position_1":return e.yPosition;case"ADBE Position_2":return e.zPosition;case"anchorPoint":case"AnchorPoint":case"Anchor Point":case"ADBE AnchorPoint":case 1:return e.anchorPoint;case"opacity":case"Opacity":case 11:return e.opacity;default:return null}}var i,r,s,a;return Object.defineProperty(e,"rotation",{get:ExpressionPropertyInterface(t.r||t.rz)}),Object.defineProperty(e,"zRotation",{get:ExpressionPropertyInterface(t.rz||t.r)}),Object.defineProperty(e,"xRotation",{get:ExpressionPropertyInterface(t.rx)}),Object.defineProperty(e,"yRotation",{get:ExpressionPropertyInterface(t.ry)}),Object.defineProperty(e,"scale",{get:ExpressionPropertyInterface(t.s)}),t.p?a=ExpressionPropertyInterface(t.p):(i=ExpressionPropertyInterface(t.px),r=ExpressionPropertyInterface(t.py),t.pz&&(s=ExpressionPropertyInterface(t.pz))),Object.defineProperty(e,"position",{get:function(){return t.p?a():[i(),r(),s?s():0]}}),Object.defineProperty(e,"xPosition",{get:ExpressionPropertyInterface(t.px)}),Object.defineProperty(e,"yPosition",{get:ExpressionPropertyInterface(t.py)}),Object.defineProperty(e,"zPosition",{get:ExpressionPropertyInterface(t.pz)}),Object.defineProperty(e,"anchorPoint",{get:ExpressionPropertyInterface(t.a)}),Object.defineProperty(e,"opacity",{get:ExpressionPropertyInterface(t.o)}),Object.defineProperty(e,"skew",{get:ExpressionPropertyInterface(t.sk)}),Object.defineProperty(e,"skewAxis",{get:ExpressionPropertyInterface(t.sa)}),Object.defineProperty(e,"orientation",{get:ExpressionPropertyInterface(t.or)}),e},LayerExpressionInterface=function(){function t(t){var e=new Matrix;void 0!==t?this._elem.finalTransform.mProp.getValueAtTime(t).clone(e):this._elem.finalTransform.mProp.applyToMatrix(e);return e}function e(t,e){var i=this.getMatrix(e);return i.props[12]=0,i.props[13]=0,i.props[14]=0,this.applyPoint(i,t)}function i(t,e){var i=this.getMatrix(e);return this.applyPoint(i,t)}function r(t,e){var i=this.getMatrix(e);return i.props[12]=0,i.props[13]=0,i.props[14]=0,this.invertPoint(i,t)}function s(t,e){var i=this.getMatrix(e);return this.invertPoint(i,t)}function a(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(t)}return t.applyToPointArray(e[0],e[1],e[2]||0)}function n(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(t)}return t.inversePoint(e)}function o(t){var e=new Matrix;if(e.reset(),this._elem.finalTransform.mProp.applyToMatrix(e),this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(e);return e.inversePoint(t)}return e.inversePoint(t)}function h(){return[1,1,1,1]}return function(l){var p;function f(t){switch(t){case"ADBE Root Vectors Group":case"Contents":case 2:return f.shapeInterface;case 1:case 6:case"Transform":case"transform":case"ADBE Transform Group":return p;case 4:case"ADBE Effect Parade":case"effects":case"Effects":return f.effect;case"ADBE Text Properties":return f.textInterface;default:return null}}f.getMatrix=t,f.invertPoint=n,f.applyPoint=a,f.toWorld=i,f.toWorldVec=e,f.fromWorld=s,f.fromWorldVec=r,f.toComp=i,f.fromComp=o,f.sampleImage=h,f.sourceRectAtTime=l.sourceRectAtTime.bind(l),f._elem=l;var m=getDescriptor(p=TransformExpressionInterface(l.finalTransform.mProp),"anchorPoint");return Object.defineProperties(f,{hasParent:{get:function(){return l.hierarchy.length}},parent:{get:function(){return l.hierarchy[0].layerInterface}},rotation:getDescriptor(p,"rotation"),scale:getDescriptor(p,"scale"),position:getDescriptor(p,"position"),opacity:getDescriptor(p,"opacity"),anchorPoint:m,anchor_point:m,transform:{get:function(){return p}},active:{get:function(){return l.isInRange}}}),f.startTime=l.data.st,f.index=l.data.ind,f.source=l.data.refId,f.height=0===l.data.ty?l.data.h:100,f.width=0===l.data.ty?l.data.w:100,f.inPoint=l.data.ip/l.comp.globalData.frameRate,f.outPoint=l.data.op/l.comp.globalData.frameRate,f._name=l.data.nm,f.registerMaskInterface=function(t){f.mask=new MaskManagerInterface(t,l)},f.registerEffectsInterface=function(t){f.effect=t},f}}(),propertyGroupFactory=function(t,e){return function(i){return(i=void 0===i?1:i)<=0?t:e(i-1)}},PropertyInterface=function(t,e){var i={_name:t};return function(t){return(t=void 0===t?1:t)<=0?i:e(t-1)}},EffectsExpressionInterface=function(){function t(i,r,s,a){function n(t){for(var e=i.ef,r=0,s=e.length;r<s;){if(t===e[r].nm||t===e[r].mn||t===e[r].ix)return 5===e[r].ty?l[r]:l[r]();r+=1}throw new Error}var o,h=propertyGroupFactory(n,s),l=[],p=i.ef.length;for(o=0;o<p;o+=1)5===i.ef[o].ty?l.push(t(i.ef[o],r.effectElements[o],r.effectElements[o].propertyGroup,a)):l.push(e(r.effectElements[o],i.ef[o].ty,a,h));return"ADBE Color Control"===i.mn&&Object.defineProperty(n,"color",{get:function(){return l[0]()}}),Object.defineProperties(n,{numProperties:{get:function(){return i.np}},_name:{value:i.nm},propertyGroup:{value:h}}),n.enabled=0!==i.en,n.active=n.enabled,n}function e(t,e,i,r){var s=ExpressionPropertyInterface(t.p);return t.p.setGroupProperty&&t.p.setGroupProperty(PropertyInterface("",r)),function(){return 10===e?i.comp.compInterface(t.p.v):s()}}return{createEffectsInterface:function(e,i){if(e.effectsManager){var r,s=[],a=e.data.ef,n=e.effectsManager.effectElements.length;for(r=0;r<n;r+=1)s.push(t(a[r],e.effectsManager.effectElements[r],i,e));var o=e.data.ef||[],h=function(t){for(r=0,n=o.length;r<n;){if(t===o[r].nm||t===o[r].mn||t===o[r].ix)return s[r];r+=1}return null};return Object.defineProperty(h,"numProperties",{get:function(){return o.length}}),h}return null}}}(),ShapePathInterface=function(t,e,i){var r=e.sh;function s(t){return"Shape"===t||"shape"===t||"Path"===t||"path"===t||"ADBE Vector Shape"===t||2===t?s.path:null}var a=propertyGroupFactory(s,i);return r.setGroupProperty(PropertyInterface("Path",a)),Object.defineProperties(s,{path:{get:function(){return r.k&&r.getValue(),r}},shape:{get:function(){return r.k&&r.getValue(),r}},_name:{value:t.nm},ix:{value:t.ix},propertyIndex:{value:t.ix},mn:{value:t.mn},propertyGroup:{value:i}}),s},ShapeExpressionInterface=function(){function t(t,o,c){var u,d=[],y=t?t.length:0;for(u=0;u<y;u+=1)"gr"===t[u].ty?d.push(e(t[u],o[u],c)):"fl"===t[u].ty?d.push(i(t[u],o[u],c)):"st"===t[u].ty?d.push(a(t[u],o[u],c)):"tm"===t[u].ty?d.push(n(t[u],o[u],c)):"tr"===t[u].ty||("el"===t[u].ty?d.push(h(t[u],o[u],c)):"sr"===t[u].ty?d.push(l(t[u],o[u],c)):"sh"===t[u].ty?d.push(ShapePathInterface(t[u],o[u],c)):"rc"===t[u].ty?d.push(p(t[u],o[u],c)):"rd"===t[u].ty?d.push(f(t[u],o[u],c)):"rp"===t[u].ty?d.push(m(t[u],o[u],c)):"gf"===t[u].ty?d.push(r(t[u],o[u],c)):d.push(s(t[u],o[u])));return d}function e(e,i,r){var s=function(t){switch(t){case"ADBE Vectors Group":case"Contents":case 2:return s.content;default:return s.transform}};s.propertyGroup=propertyGroupFactory(s,r);var a=function(e,i,r){var s,a=function(t){for(var e=0,i=s.length;e<i;){if(s[e]._name===t||s[e].mn===t||s[e].propertyIndex===t||s[e].ix===t||s[e].ind===t)return s[e];e+=1}return"number"==typeof t?s[t-1]:null};a.propertyGroup=propertyGroupFactory(a,r),s=t(e.it,i.it,a.propertyGroup),a.numProperties=s.length;var n=o(e.it[e.it.length-1],i.it[i.it.length-1],a.propertyGroup);return a.transform=n,a.propertyIndex=e.cix,a._name=e.nm,a}(e,i,s.propertyGroup),n=o(e.it[e.it.length-1],i.it[i.it.length-1],s.propertyGroup);return s.content=a,s.transform=n,Object.defineProperty(s,"_name",{get:function(){return e.nm}}),s.numProperties=e.np,s.propertyIndex=e.ix,s.nm=e.nm,s.mn=e.mn,s}function i(t,e,i){function r(t){return"Color"===t||"color"===t?r.color:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r}function r(t,e,i){function r(t){return"Start Point"===t||"start point"===t?r.startPoint:"End Point"===t||"end point"===t?r.endPoint:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{startPoint:{get:ExpressionPropertyInterface(e.s)},endPoint:{get:ExpressionPropertyInterface(e.e)},opacity:{get:ExpressionPropertyInterface(e.o)},type:{get:function(){return"a"}},_name:{value:t.nm},mn:{value:t.mn}}),e.s.setGroupProperty(PropertyInterface("Start Point",i)),e.e.setGroupProperty(PropertyInterface("End Point",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r}function s(){return function(){return null}}function a(t,e,i){var r,s=propertyGroupFactory(l,i),a=propertyGroupFactory(h,s);function n(i){Object.defineProperty(h,t.d[i].nm,{get:ExpressionPropertyInterface(e.d.dataProps[i].p)})}var o=t.d?t.d.length:0,h={};for(r=0;r<o;r+=1)n(r),e.d.dataProps[r].p.setGroupProperty(a);function l(t){return"Color"===t||"color"===t?l.color:"Opacity"===t||"opacity"===t?l.opacity:"Stroke Width"===t||"stroke width"===t?l.strokeWidth:null}return Object.defineProperties(l,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},strokeWidth:{get:ExpressionPropertyInterface(e.w)},dash:{get:function(){return h}},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",s)),e.o.setGroupProperty(PropertyInterface("Opacity",s)),e.w.setGroupProperty(PropertyInterface("Stroke Width",s)),l}function n(t,e,i){function r(e){return e===t.e.ix||"End"===e||"end"===e?r.end:e===t.s.ix?r.start:e===t.o.ix?r.offset:null}var s=propertyGroupFactory(r,i);return r.propertyIndex=t.ix,e.s.setGroupProperty(PropertyInterface("Start",s)),e.e.setGroupProperty(PropertyInterface("End",s)),e.o.setGroupProperty(PropertyInterface("Offset",s)),r.propertyIndex=t.ix,r.propertyGroup=i,Object.defineProperties(r,{start:{get:ExpressionPropertyInterface(e.s)},end:{get:ExpressionPropertyInterface(e.e)},offset:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm}}),r.mn=t.mn,r}function o(t,e,i){function r(e){return t.a.ix===e||"Anchor Point"===e?r.anchorPoint:t.o.ix===e||"Opacity"===e?r.opacity:t.p.ix===e||"Position"===e?r.position:t.r.ix===e||"Rotation"===e||"ADBE Vector Rotation"===e?r.rotation:t.s.ix===e||"Scale"===e?r.scale:t.sk&&t.sk.ix===e||"Skew"===e?r.skew:t.sa&&t.sa.ix===e||"Skew Axis"===e?r.skewAxis:null}var s=propertyGroupFactory(r,i);return e.transform.mProps.o.setGroupProperty(PropertyInterface("Opacity",s)),e.transform.mProps.p.setGroupProperty(PropertyInterface("Position",s)),e.transform.mProps.a.setGroupProperty(PropertyInterface("Anchor Point",s)),e.transform.mProps.s.setGroupProperty(PropertyInterface("Scale",s)),e.transform.mProps.r.setGroupProperty(PropertyInterface("Rotation",s)),e.transform.mProps.sk&&(e.transform.mProps.sk.setGroupProperty(PropertyInterface("Skew",s)),e.transform.mProps.sa.setGroupProperty(PropertyInterface("Skew Angle",s))),e.transform.op.setGroupProperty(PropertyInterface("Opacity",s)),Object.defineProperties(r,{opacity:{get:ExpressionPropertyInterface(e.transform.mProps.o)},position:{get:ExpressionPropertyInterface(e.transform.mProps.p)},anchorPoint:{get:ExpressionPropertyInterface(e.transform.mProps.a)},scale:{get:ExpressionPropertyInterface(e.transform.mProps.s)},rotation:{get:ExpressionPropertyInterface(e.transform.mProps.r)},skew:{get:ExpressionPropertyInterface(e.transform.mProps.sk)},skewAxis:{get:ExpressionPropertyInterface(e.transform.mProps.sa)},_name:{value:t.nm}}),r.ty="tr",r.mn=t.mn,r.propertyGroup=i,r}function h(t,e,i){function r(e){return t.p.ix===e?r.position:t.s.ix===e?r.size:null}var s=propertyGroupFactory(r,i);r.propertyIndex=t.ix;var a="tm"===e.sh.ty?e.sh.prop:e.sh;return a.s.setGroupProperty(PropertyInterface("Size",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),Object.defineProperties(r,{size:{get:ExpressionPropertyInterface(a.s)},position:{get:ExpressionPropertyInterface(a.p)},_name:{value:t.nm}}),r.mn=t.mn,r}function l(t,e,i){function r(e){return t.p.ix===e?r.position:t.r.ix===e?r.rotation:t.pt.ix===e?r.points:t.or.ix===e||"ADBE Vector Star Outer Radius"===e?r.outerRadius:t.os.ix===e?r.outerRoundness:!t.ir||t.ir.ix!==e&&"ADBE Vector Star Inner Radius"!==e?t.is&&t.is.ix===e?r.innerRoundness:null:r.innerRadius}var s=propertyGroupFactory(r,i),a="tm"===e.sh.ty?e.sh.prop:e.sh;return r.propertyIndex=t.ix,a.or.setGroupProperty(PropertyInterface("Outer Radius",s)),a.os.setGroupProperty(PropertyInterface("Outer Roundness",s)),a.pt.setGroupProperty(PropertyInterface("Points",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),t.ir&&(a.ir.setGroupProperty(PropertyInterface("Inner Radius",s)),a.is.setGroupProperty(PropertyInterface("Inner Roundness",s))),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(a.p)},rotation:{get:ExpressionPropertyInterface(a.r)},points:{get:ExpressionPropertyInterface(a.pt)},outerRadius:{get:ExpressionPropertyInterface(a.or)},outerRoundness:{get:ExpressionPropertyInterface(a.os)},innerRadius:{get:ExpressionPropertyInterface(a.ir)},innerRoundness:{get:ExpressionPropertyInterface(a.is)},_name:{value:t.nm}}),r.mn=t.mn,r}function p(t,e,i){function r(e){return t.p.ix===e?r.position:t.r.ix===e?r.roundness:t.s.ix===e||"Size"===e||"ADBE Vector Rect Size"===e?r.size:null}var s=propertyGroupFactory(r,i),a="tm"===e.sh.ty?e.sh.prop:e.sh;return r.propertyIndex=t.ix,a.p.setGroupProperty(PropertyInterface("Position",s)),a.s.setGroupProperty(PropertyInterface("Size",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(a.p)},roundness:{get:ExpressionPropertyInterface(a.r)},size:{get:ExpressionPropertyInterface(a.s)},_name:{value:t.nm}}),r.mn=t.mn,r}function f(t,e,i){function r(e){return t.r.ix===e||"Round Corners 1"===e?r.radius:null}var s=propertyGroupFactory(r,i),a=e;return r.propertyIndex=t.ix,a.rd.setGroupProperty(PropertyInterface("Radius",s)),Object.defineProperties(r,{radius:{get:ExpressionPropertyInterface(a.rd)},_name:{value:t.nm}}),r.mn=t.mn,r}function m(t,e,i){function r(e){return t.c.ix===e||"Copies"===e?r.copies:t.o.ix===e||"Offset"===e?r.offset:null}var s=propertyGroupFactory(r,i),a=e;return r.propertyIndex=t.ix,a.c.setGroupProperty(PropertyInterface("Copies",s)),a.o.setGroupProperty(PropertyInterface("Offset",s)),Object.defineProperties(r,{copies:{get:ExpressionPropertyInterface(a.c)},offset:{get:ExpressionPropertyInterface(a.o)},_name:{value:t.nm}}),r.mn=t.mn,r}return function(e,i,r){var s;function a(t){if("number"==typeof t)return 0===(t=void 0===t?1:t)?r:s[t-1];for(var e=0,i=s.length;e<i;){if(s[e]._name===t)return s[e];e+=1}return null}return a.propertyGroup=propertyGroupFactory(a,(function(){return r})),s=t(e,i,a.propertyGroup),a.numProperties=s.length,a._name="Contents",a}}(),TextExpressionInterface=function(t){var e;function i(t){return"ADBE Text Document"===t?i.sourceText:null}return Object.defineProperty(i,"sourceText",{get:function(){t.textProperty.getValue();var i=t.textProperty.currentData.t;return e&&i===e.value||((e=new String(i)).value=i||new String(i),Object.defineProperty(e,"style",{get:function(){return{fillColor:t.textProperty.currentData.fc}}})),e}}),i};function _typeof(t){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof(t)}var FootageInterface=(dataInterfaceFactory=function(t){function e(t){return"Outline"===t?e.outlineInterface():null}return e._name="Outline",e.outlineInterface=function(t){var e="",i=t.getFootageData();function r(t){if(i[t])return e=t,"object"===_typeof(i=i[t])?r:i;var s=t.indexOf(e);if(-1!==s){var a=parseInt(t.substr(s+e.length),10);return"object"===_typeof(i=i[a])?r:i}return""}return function(){return e="",i=t.getFootageData(),r}}(t),e},function(t){function e(t){return"Data"===t?e.dataInterface:null}return e._name="Data",e.dataInterface=dataInterfaceFactory(t),e}),dataInterfaceFactory,interfaces={layer:LayerExpressionInterface,effects:EffectsExpressionInterface,comp:CompExpressionInterface,shape:ShapeExpressionInterface,text:TextExpressionInterface,footage:FootageInterface};function getInterface(t){return interfaces[t]||null}var expressionHelpers={searchExpressions:function(t,e,i){e.x&&(i.k=!0,i.x=!0,i.initiateExpression=ExpressionManager.initiateExpression,i.effectsSequence.push(i.initiateExpression(t,e,i).bind(i)))},getSpeedAtTime:function(t){var e=this.getValueAtTime(t),i=this.getValueAtTime(t+-.01),r=0;if(e.length){var s;for(s=0;s<e.length;s+=1)r+=Math.pow(i[s]-e[s],2);r=100*Math.sqrt(r)}else r=0;return r},getVelocityAtTime:function(t){if(void 0!==this.vel)return this.vel;var e,i,r=-.001,s=this.getValueAtTime(t),a=this.getValueAtTime(t+r);if(s.length)for(e=createTypedArray("float32",s.length),i=0;i<s.length;i+=1)e[i]=(a[i]-s[i])/r;else e=(a-s)/r;return e},getValueAtTime:function(t){return t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastFrame&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastFrame<t?this._cachingAtTime.lastIndex:0,this._cachingAtTime.value=this.interpolateValue(t,this._cachingAtTime),this._cachingAtTime.lastFrame=t),this._cachingAtTime.value},getStaticValueAtTime:function(){return this.pv},setGroupProperty:function(t){this.propertyGroup=t}};function addPropertyDecorator(){function t(t,e,i){if(!this.k||!this.keyframes)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[l.length-1].t;if(h<=p)return this.pv;if(i?s=p-(r=e?Math.abs(p-this.elem.comp.globalData.frameRate*e):Math.max(0,p-this.elem.data.ip)):((!e||e>l.length-1)&&(e=l.length-1),r=p-(s=l[l.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/r)%2!=0)return this.getValueAtTime((r-(h-s)%r+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),m=this.getValueAtTime(p/this.comp.globalData.frameRate,0),c=this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0),u=Math.floor((h-s)/r);if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=(m[a]-f[a])*u+c[a];return o}return(m-f)*u+c}if("continue"===t){var d=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p-.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(d.length)).length,a=0;a<n;a+=1)o[a]=d[a]+(d[a]-y[a])*((h-p)/this.comp.globalData.frameRate)/5e-4;return o}return d+(h-p)/.001*(d-y)}}return this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0)}function e(t,e,i){if(!this.k)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[0].t;if(h>=p)return this.pv;if(i?s=p+(r=e?Math.abs(this.elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-p)):((!e||e>l.length-1)&&(e=l.length-1),r=(s=l[e].t)-p),"pingpong"===t){if(Math.floor((p-h)/r)%2==0)return this.getValueAtTime(((p-h)%r+p)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(p/this.comp.globalData.frameRate,0),m=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime((r-(p-h)%r+p)/this.comp.globalData.frameRate,0),u=Math.floor((p-h)/r)+1;if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=c[a]-(m[a]-f[a])*u;return o}return c-(m-f)*u}if("continue"===t){var d=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p+.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(d.length)).length,a=0;a<n;a+=1)o[a]=d[a]+(d[a]-y[a])*(p-h)/.001;return o}return d+(d-y)*(p-h)/.001}}return this.getValueAtTime((r-((p-h)%r+p))/this.comp.globalData.frameRate,0)}function i(t,e){if(!this.k)return this.pv;if(t=.5*(t||.4),(e=Math.floor(e||5))<=1)return this.pv;var i,r,s=this.comp.renderedFrame/this.comp.globalData.frameRate,a=s-t,n=e>1?(s+t-a)/(e-1):1,o=0,h=0;for(i=this.pv.length?createTypedArray("float32",this.pv.length):0;o<e;){if(r=this.getValueAtTime(a+o*n),this.pv.length)for(h=0;h<this.pv.length;h+=1)i[h]+=r[h];else i+=r;o+=1}if(this.pv.length)for(h=0;h<this.pv.length;h+=1)i[h]/=e;else i/=e;return i}function r(t){this._transformCachingAtTime||(this._transformCachingAtTime={v:new Matrix});var e=this._transformCachingAtTime.v;if(e.cloneFromProps(this.pre.props),this.appliedTransformations<1){var i=this.a.getValueAtTime(t);e.translate(-i[0]*this.a.mult,-i[1]*this.a.mult,i[2]*this.a.mult)}if(this.appliedTransformations<2){var r=this.s.getValueAtTime(t);e.scale(r[0]*this.s.mult,r[1]*this.s.mult,r[2]*this.s.mult)}if(this.sk&&this.appliedTransformations<3){var s=this.sk.getValueAtTime(t),a=this.sa.getValueAtTime(t);e.skewFromAxis(-s*this.sk.mult,a*this.sa.mult)}if(this.r&&this.appliedTransformations<4){var n=this.r.getValueAtTime(t);e.rotate(-n*this.r.mult)}else if(!this.r&&this.appliedTransformations<4){var o=this.rz.getValueAtTime(t),h=this.ry.getValueAtTime(t),l=this.rx.getValueAtTime(t),p=this.or.getValueAtTime(t);e.rotateZ(-o*this.rz.mult).rotateY(h*this.ry.mult).rotateX(l*this.rx.mult).rotateZ(-p[2]*this.or.mult).rotateY(p[1]*this.or.mult).rotateX(p[0]*this.or.mult)}if(this.data.p&&this.data.p.s){var f=this.px.getValueAtTime(t),m=this.py.getValueAtTime(t);if(this.data.p.z){var c=this.pz.getValueAtTime(t);e.translate(f*this.px.mult,m*this.py.mult,-c*this.pz.mult)}else e.translate(f*this.px.mult,m*this.py.mult,0)}else{var u=this.p.getValueAtTime(t);e.translate(u[0]*this.p.mult,u[1]*this.p.mult,-u[2]*this.p.mult)}return e}function s(){return this.v.clone(new Matrix)}var a=TransformPropertyFactory.getTransformProperty;TransformPropertyFactory.getTransformProperty=function(t,e,i){var n=a(t,e,i);return n.dynamicProperties.length?n.getValueAtTime=r.bind(n):n.getValueAtTime=s.bind(n),n.setGroupProperty=expressionHelpers.setGroupProperty,n};var n=PropertyFactory.getProp;PropertyFactory.getProp=function(r,s,a,o,h){var l=n(r,s,a,o,h);l.kf?l.getValueAtTime=expressionHelpers.getValueAtTime.bind(l):l.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(l),l.setGroupProperty=expressionHelpers.setGroupProperty,l.loopOut=t,l.loopIn=e,l.smooth=i,l.getVelocityAtTime=expressionHelpers.getVelocityAtTime.bind(l),l.getSpeedAtTime=expressionHelpers.getSpeedAtTime.bind(l),l.numKeys=1===s.a?s.k.length:0,l.propertyIndex=s.ix;var p=0;return 0!==a&&(p=createTypedArray("float32",1===s.a?s.k[0].s.length:s.k.length)),l._cachingAtTime={lastFrame:initialDefaultFrame,lastIndex:0,value:p},expressionHelpers.searchExpressions(r,s,l),l.k&&h.addDynamicProperty(l),l};var o=ShapePropertyFactory.getConstructorFunction(),h=ShapePropertyFactory.getKeyframedConstructorFunction();function l(){}l.prototype={vertices:function(t,e){this.k&&this.getValue();var i,r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0));var s=r._length,a=r[t],n=r.v,o=createSizedArray(s);for(i=0;i<s;i+=1)o[i]="i"===t||"o"===t?[a[i][0]-n[i][0],a[i][1]-n[i][1]]:[a[i][0],a[i][1]];return o},points:function(t){return this.vertices("v",t)},inTangents:function(t){return this.vertices("i",t)},outTangents:function(t){return this.vertices("o",t)},isClosed:function(){return this.v.c},pointOnPath:function(t,e){var i=this.v;void 0!==e&&(i=this.getValueAtTime(e,0)),this._segmentsLength||(this._segmentsLength=bez.getSegmentsLength(i));for(var r,s=this._segmentsLength,a=s.lengths,n=s.totalLength*t,o=0,h=a.length,l=0;o<h;){if(l+a[o].addedLength>n){var p=o,f=i.c&&o===h-1?0:o+1,m=(n-l)/a[o].addedLength;r=bez.getPointInSegment(i.v[p],i.v[f],i.o[p],i.i[f],m,a[o]);break}l+=a[o].addedLength,o+=1}return r||(r=i.c?[i.v[0][0],i.v[0][1]]:[i.v[i._length-1][0],i.v[i._length-1][1]]),r},vectorOnPath:function(t,e,i){1==t?t=this.v.c:0==t&&(t=.999);var r=this.pointOnPath(t,e),s=this.pointOnPath(t+.001,e),a=s[0]-r[0],n=s[1]-r[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return 0===o?[0,0]:"tangent"===i?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([l],o),extendPrototype([l],h),h.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shapePool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime<t?this._caching.lastIndex:0,this._cachingAtTime.lastTime=t,this.interpolateShape(t,this._cachingAtTime.shapeValue,this._cachingAtTime)),this._cachingAtTime.shapeValue},h.prototype.initiateExpression=ExpressionManager.initiateExpression;var p=ShapePropertyFactory.getShapeProp;ShapePropertyFactory.getShapeProp=function(t,e,i,r,s){var a=p(t,e,i,r,s);return a.propertyIndex=e.ix,a.lock=!1,3===i?expressionHelpers.searchExpressions(t,e.pt,a):4===i&&expressionHelpers.searchExpressions(t,e.ks,a),a.k&&t.addDynamicProperty(a),a}}function initialize$1(){addPropertyDecorator()}function addDecorator(){TextProperty.prototype.getExpressionValue=function(t,e){var i=this.calculateExpression(e);if(t.t!==i){var r={};return this.copyData(r,t),r.t=i.toString(),r.__complete=!1,r}return t},TextProperty.prototype.searchProperty=function(){var t=this.searchKeyframes(),e=this.searchExpressions();return this.kf=t||e,this.kf},TextProperty.prototype.searchExpressions=function(){return this.data.d.x?(this.calculateExpression=ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this),this.addEffect(this.getExpressionValue.bind(this)),!0):null}}function initialize(){addDecorator()}function SVGComposableEffect(){}SVGComposableEffect.prototype={createMergeNode:function(t,e){var i,r,s=createNS("feMerge");for(s.setAttribute("result",t),r=0;r<e.length;r+=1)(i=createNS("feMergeNode")).setAttribute("in",e[r]),s.appendChild(i),s.appendChild(i);return s}};var linearFilterValue="0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0";function SVGTintFilter(t,e,i,r,s){this.filterManager=e;var a=createNS("feColorMatrix");a.setAttribute("type","matrix"),a.setAttribute("color-interpolation-filters","linearRGB"),a.setAttribute("values",linearFilterValue+" 1 0"),this.linearFilter=a,a.setAttribute("result",r+"_tint_1"),t.appendChild(a),(a=createNS("feColorMatrix")).setAttribute("type","matrix"),a.setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),a.setAttribute("result",r+"_tint_2"),t.appendChild(a),this.matrixFilter=a;var n=this.createMergeNode(r,[s,r+"_tint_1",r+"_tint_2"]);t.appendChild(n)}function SVGFillFilter(t,e,i,r){this.filterManager=e;var s=createNS("feColorMatrix");s.setAttribute("type","matrix"),s.setAttribute("color-interpolation-filters","sRGB"),s.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),s.setAttribute("result",r),t.appendChild(s),this.matrixFilter=s}function SVGStrokeEffect(t,e,i){this.initialized=!1,this.filterManager=e,this.elem=i,this.paths=[]}function SVGTritoneFilter(t,e,i,r){this.filterManager=e;var s=createNS("feColorMatrix");s.setAttribute("type","matrix"),s.setAttribute("color-interpolation-filters","linearRGB"),s.setAttribute("values","0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0"),t.appendChild(s);var a=createNS("feComponentTransfer");a.setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("result",r),this.matrixFilter=a;var n=createNS("feFuncR");n.setAttribute("type","table"),a.appendChild(n),this.feFuncR=n;var o=createNS("feFuncG");o.setAttribute("type","table"),a.appendChild(o),this.feFuncG=o;var h=createNS("feFuncB");h.setAttribute("type","table"),a.appendChild(h),this.feFuncB=h,t.appendChild(a)}function SVGProLevelsFilter(t,e,i,r){this.filterManager=e;var s=this.filterManager.effectElements,a=createNS("feComponentTransfer");(s[10].p.k||0!==s[10].p.v||s[11].p.k||1!==s[11].p.v||s[12].p.k||1!==s[12].p.v||s[13].p.k||0!==s[13].p.v||s[14].p.k||1!==s[14].p.v)&&(this.feFuncR=this.createFeFunc("feFuncR",a)),(s[17].p.k||0!==s[17].p.v||s[18].p.k||1!==s[18].p.v||s[19].p.k||1!==s[19].p.v||s[20].p.k||0!==s[20].p.v||s[21].p.k||1!==s[21].p.v)&&(this.feFuncG=this.createFeFunc("feFuncG",a)),(s[24].p.k||0!==s[24].p.v||s[25].p.k||1!==s[25].p.v||s[26].p.k||1!==s[26].p.v||s[27].p.k||0!==s[27].p.v||s[28].p.k||1!==s[28].p.v)&&(this.feFuncB=this.createFeFunc("feFuncB",a)),(s[31].p.k||0!==s[31].p.v||s[32].p.k||1!==s[32].p.v||s[33].p.k||1!==s[33].p.v||s[34].p.k||0!==s[34].p.v||s[35].p.k||1!==s[35].p.v)&&(this.feFuncA=this.createFeFunc("feFuncA",a)),(this.feFuncR||this.feFuncG||this.feFuncB||this.feFuncA)&&(a.setAttribute("color-interpolation-filters","sRGB"),t.appendChild(a)),(s[3].p.k||0!==s[3].p.v||s[4].p.k||1!==s[4].p.v||s[5].p.k||1!==s[5].p.v||s[6].p.k||0!==s[6].p.v||s[7].p.k||1!==s[7].p.v)&&((a=createNS("feComponentTransfer")).setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("result",r),t.appendChild(a),this.feFuncRComposed=this.createFeFunc("feFuncR",a),this.feFuncGComposed=this.createFeFunc("feFuncG",a),this.feFuncBComposed=this.createFeFunc("feFuncB",a))}function SVGDropShadowEffect(t,e,i,r,s){var a=e.container.globalData.renderConfig.filterSize,n=e.data.fs||a;t.setAttribute("x",n.x||a.x),t.setAttribute("y",n.y||a.y),t.setAttribute("width",n.width||a.width),t.setAttribute("height",n.height||a.height),this.filterManager=e;var o=createNS("feGaussianBlur");o.setAttribute("in","SourceAlpha"),o.setAttribute("result",r+"_drop_shadow_1"),o.setAttribute("stdDeviation","0"),this.feGaussianBlur=o,t.appendChild(o);var h=createNS("feOffset");h.setAttribute("dx","25"),h.setAttribute("dy","0"),h.setAttribute("in",r+"_drop_shadow_1"),h.setAttribute("result",r+"_drop_shadow_2"),this.feOffset=h,t.appendChild(h);var l=createNS("feFlood");l.setAttribute("flood-color","#00ff00"),l.setAttribute("flood-opacity","1"),l.setAttribute("result",r+"_drop_shadow_3"),this.feFlood=l,t.appendChild(l);var p=createNS("feComposite");p.setAttribute("in",r+"_drop_shadow_3"),p.setAttribute("in2",r+"_drop_shadow_2"),p.setAttribute("operator","in"),p.setAttribute("result",r+"_drop_shadow_4"),t.appendChild(p);var f=this.createMergeNode(r,[r+"_drop_shadow_4",s]);t.appendChild(f)}extendPrototype([SVGComposableEffect],SVGTintFilter),SVGTintFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=this.filterManager.effectElements[2].p.v/100;this.linearFilter.setAttribute("values",linearFilterValue+" "+r+" 0"),this.matrixFilter.setAttribute("values",i[0]-e[0]+" 0 0 0 "+e[0]+" "+(i[1]-e[1])+" 0 0 0 "+e[1]+" "+(i[2]-e[2])+" 0 0 0 "+e[2]+" 0 0 0 1 0")}},SVGFillFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[2].p.v,i=this.filterManager.effectElements[6].p.v;this.matrixFilter.setAttribute("values","0 0 0 0 "+e[0]+" 0 0 0 0 "+e[1]+" 0 0 0 0 "+e[2]+" 0 0 0 "+i+" 0")}},SVGStrokeEffect.prototype.initialize=function(){var t,e,i,r,s=this.elem.layerElement.children||this.elem.layerElement.childNodes;for(1===this.filterManager.effectElements[1].p.v?(r=this.elem.maskManager.masksProperties.length,i=0):r=(i=this.filterManager.effectElements[0].p.v-1)+1,(e=createNS("g")).setAttribute("fill","none"),e.setAttribute("stroke-linecap","round"),e.setAttribute("stroke-dashoffset",1);i<r;i+=1)t=createNS("path"),e.appendChild(t),this.paths.push({p:t,m:i});if(3===this.filterManager.effectElements[10].p.v){var a=createNS("mask"),n=createElementID();a.setAttribute("id",n),a.setAttribute("mask-type","alpha"),a.appendChild(e),this.elem.globalData.defs.appendChild(a);var o=createNS("g");for(o.setAttribute("mask","url("+getLocationHref()+"#"+n+")");s[0];)o.appendChild(s[0]);this.elem.layerElement.appendChild(o),this.masker=a,e.setAttribute("stroke","#fff")}else if(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v){if(2===this.filterManager.effectElements[10].p.v)for(s=this.elem.layerElement.children||this.elem.layerElement.childNodes;s.length;)this.elem.layerElement.removeChild(s[0]);this.elem.layerElement.appendChild(e),this.elem.layerElement.removeAttribute("mask"),e.setAttribute("stroke","#fff")}this.initialized=!0,this.pathMasker=e},SVGStrokeEffect.prototype.renderFrame=function(t){var e;this.initialized||this.initialize();var i,r,s=this.paths.length;for(e=0;e<s;e+=1)if(-1!==this.paths[e].m&&(i=this.elem.maskManager.viewData[this.paths[e].m],r=this.paths[e].p,(t||this.filterManager._mdf||i.prop._mdf)&&r.setAttribute("d",i.lastPath),t||this.filterManager.effectElements[9].p._mdf||this.filterManager.effectElements[4].p._mdf||this.filterManager.effectElements[7].p._mdf||this.filterManager.effectElements[8].p._mdf||i.prop._mdf)){var a;if(0!==this.filterManager.effectElements[7].p.v||100!==this.filterManager.effectElements[8].p.v){var n=.01*Math.min(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),o=.01*Math.max(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),h=r.getTotalLength();a="0 0 0 "+h*n+" ";var l,p=h*(o-n),f=1+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01,m=Math.floor(p/f);for(l=0;l<m;l+=1)a+="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01+" ";a+="0 "+10*h+" 0 0"}else a="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01;r.setAttribute("stroke-dasharray",a)}if((t||this.filterManager.effectElements[4].p._mdf)&&this.pathMasker.setAttribute("stroke-width",2*this.filterManager.effectElements[4].p.v),(t||this.filterManager.effectElements[6].p._mdf)&&this.pathMasker.setAttribute("opacity",this.filterManager.effectElements[6].p.v),(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v)&&(t||this.filterManager.effectElements[3].p._mdf)){var c=this.filterManager.effectElements[3].p.v;this.pathMasker.setAttribute("stroke","rgb("+bmFloor(255*c[0])+","+bmFloor(255*c[1])+","+bmFloor(255*c[2])+")")}},SVGTritoneFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=this.filterManager.effectElements[2].p.v,s=r[0]+" "+i[0]+" "+e[0],a=r[1]+" "+i[1]+" "+e[1],n=r[2]+" "+i[2]+" "+e[2];this.feFuncR.setAttribute("tableValues",s),this.feFuncG.setAttribute("tableValues",a),this.feFuncB.setAttribute("tableValues",n)}},SVGProLevelsFilter.prototype.createFeFunc=function(t,e){var i=createNS(t);return i.setAttribute("type","table"),e.appendChild(i),i},SVGProLevelsFilter.prototype.getTableValue=function(t,e,i,r,s){for(var a,n,o=0,h=Math.min(t,e),l=Math.max(t,e),p=Array.call(null,{length:256}),f=0,m=s-r,c=e-t;o<=256;)n=(a=o/256)<=h?c<0?s:r:a>=l?c<0?r:s:r+m*Math.pow((a-t)/c,1/i),p[f]=n,f+=1,o+=256/255;return p.join(" ")},SVGProLevelsFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e,i=this.filterManager.effectElements;this.feFuncRComposed&&(t||i[3].p._mdf||i[4].p._mdf||i[5].p._mdf||i[6].p._mdf||i[7].p._mdf)&&(e=this.getTableValue(i[3].p.v,i[4].p.v,i[5].p.v,i[6].p.v,i[7].p.v),this.feFuncRComposed.setAttribute("tableValues",e),this.feFuncGComposed.setAttribute("tableValues",e),this.feFuncBComposed.setAttribute("tableValues",e)),this.feFuncR&&(t||i[10].p._mdf||i[11].p._mdf||i[12].p._mdf||i[13].p._mdf||i[14].p._mdf)&&(e=this.getTableValue(i[10].p.v,i[11].p.v,i[12].p.v,i[13].p.v,i[14].p.v),this.feFuncR.setAttribute("tableValues",e)),this.feFuncG&&(t||i[17].p._mdf||i[18].p._mdf||i[19].p._mdf||i[20].p._mdf||i[21].p._mdf)&&(e=this.getTableValue(i[17].p.v,i[18].p.v,i[19].p.v,i[20].p.v,i[21].p.v),this.feFuncG.setAttribute("tableValues",e)),this.feFuncB&&(t||i[24].p._mdf||i[25].p._mdf||i[26].p._mdf||i[27].p._mdf||i[28].p._mdf)&&(e=this.getTableValue(i[24].p.v,i[25].p.v,i[26].p.v,i[27].p.v,i[28].p.v),this.feFuncB.setAttribute("tableValues",e)),this.feFuncA&&(t||i[31].p._mdf||i[32].p._mdf||i[33].p._mdf||i[34].p._mdf||i[35].p._mdf)&&(e=this.getTableValue(i[31].p.v,i[32].p.v,i[33].p.v,i[34].p.v,i[35].p.v),this.feFuncA.setAttribute("tableValues",e))}},extendPrototype([SVGComposableEffect],SVGDropShadowEffect),SVGDropShadowEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){if((t||this.filterManager.effectElements[4].p._mdf)&&this.feGaussianBlur.setAttribute("stdDeviation",this.filterManager.effectElements[4].p.v/4),t||this.filterManager.effectElements[0].p._mdf){var e=this.filterManager.effectElements[0].p.v;this.feFlood.setAttribute("flood-color",rgbToHex(Math.round(255*e[0]),Math.round(255*e[1]),Math.round(255*e[2])))}if((t||this.filterManager.effectElements[1].p._mdf)&&this.feFlood.setAttribute("flood-opacity",this.filterManager.effectElements[1].p.v/255),t||this.filterManager.effectElements[2].p._mdf||this.filterManager.effectElements[3].p._mdf){var i=this.filterManager.effectElements[3].p.v,r=(this.filterManager.effectElements[2].p.v-90)*degToRads,s=i*Math.cos(r),a=i*Math.sin(r);this.feOffset.setAttribute("dx",s),this.feOffset.setAttribute("dy",a)}}};var _svgMatteSymbols=[];function SVGMatte3Effect(t,e,i){this.initialized=!1,this.filterManager=e,this.filterElem=t,this.elem=i,i.matteElement=createNS("g"),i.matteElement.appendChild(i.layerElement),i.matteElement.appendChild(i.transformedElement),i.baseElement=i.matteElement}function SVGGaussianBlurEffect(t,e,i,r){t.setAttribute("x","-100%"),t.setAttribute("y","-100%"),t.setAttribute("width","300%"),t.setAttribute("height","300%"),this.filterManager=e;var s=createNS("feGaussianBlur");s.setAttribute("result",r),t.appendChild(s),this.feGaussianBlur=s}function TransformEffect(){}function SVGTransformEffect(t,e){this.init(e)}return SVGMatte3Effect.prototype.findSymbol=function(t){for(var e=0,i=_svgMatteSymbols.length;e<i;){if(_svgMatteSymbols[e]===t)return _svgMatteSymbols[e];e+=1}return null},SVGMatte3Effect.prototype.replaceInParent=function(t,e){var i=t.layerElement.parentNode;if(i){for(var r,s=i.children,a=0,n=s.length;a<n&&s[a]!==t.layerElement;)a+=1;a<=n-2&&(r=s[a+1]);var o=createNS("use");o.setAttribute("href","#"+e),r?i.insertBefore(o,r):i.appendChild(o)}},SVGMatte3Effect.prototype.setElementAsMask=function(t,e){if(!this.findSymbol(e)){var i=createElementID(),r=createNS("mask");r.setAttribute("id",e.layerId),r.setAttribute("mask-type","alpha"),_svgMatteSymbols.push(e);var s=t.globalData.defs;s.appendChild(r);var a=createNS("symbol");a.setAttribute("id",i),this.replaceInParent(e,i),a.appendChild(e.layerElement),s.appendChild(a);var n=createNS("use");n.setAttribute("href","#"+i),r.appendChild(n),e.data.hd=!1,e.show()}t.setMatte(e.layerId)},SVGMatte3Effect.prototype.initialize=function(){for(var t=this.filterManager.effectElements[0].p.v,e=this.elem.comp.elements,i=0,r=e.length;i<r;)e[i]&&e[i].data.ind===t&&this.setElementAsMask(this.elem,e[i]),i+=1;this.initialized=!0},SVGMatte3Effect.prototype.renderFrame=function(){this.initialized||this.initialize()},SVGGaussianBlurEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=.3*this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=3==i?0:e,s=2==i?0:e;this.feGaussianBlur.setAttribute("stdDeviation",r+" "+s);var a=1==this.filterManager.effectElements[2].p.v?"wrap":"duplicate";this.feGaussianBlur.setAttribute("edgeMode",a)}},TransformEffect.prototype.init=function(t){this.effectsManager=t,this.type=effectTypes.TRANSFORM_EFFECT,this.matrix=new Matrix,this.opacity=-1,this._mdf=!1,this._opMdf=!1},TransformEffect.prototype.renderFrame=function(t){if(this._opMdf=!1,this._mdf=!1,t||this.effectsManager._mdf){var e=this.effectsManager.effectElements,i=e[0].p.v,r=e[1].p.v,s=1===e[2].p.v,a=e[3].p.v,n=s?a:e[4].p.v,o=e[5].p.v,h=e[6].p.v,l=e[7].p.v;this.matrix.reset(),this.matrix.translate(-i[0],-i[1],i[2]),this.matrix.scale(.01*n,.01*a,1),this.matrix.rotate(-l*degToRads),this.matrix.skewFromAxis(-o*degToRads,(h+90)*degToRads),this.matrix.translate(r[0],r[1],0),this._mdf=!0,this.opacity!==e[8].p.v&&(this.opacity=e[8].p.v,this._opMdf=!0)}},extendPrototype([TransformEffect],SVGTransformEffect),setExpressionsPlugin(Expressions),setExpressionInterfaces(getInterface),initialize$1(),initialize(),registerEffect$1(20,SVGTintFilter,!0),registerEffect$1(21,SVGFillFilter,!0),registerEffect$1(22,SVGStrokeEffect,!1),registerEffect$1(23,SVGTritoneFilter,!0),registerEffect$1(24,SVGProLevelsFilter,!0),registerEffect$1(25,SVGDropShadowEffect,!0),registerEffect$1(28,SVGMatte3Effect,!1),registerEffect$1(29,SVGGaussianBlurEffect,!0),registerEffect$1(35,SVGTransformEffect,!1),lottie}));
diff --git a/build/player/lottie_light.js b/build/player/lottie_light.js
index 6b055b9..9db72ef 100644
--- a/build/player/lottie_light.js
+++ b/build/player/lottie_light.js
@@ -1,4 +1,4 @@
-(typeof navigator !== "undefined") && (function (global, factory) {
+(typeof document !== "undefined") && (typeof navigator !== "undefined") && (function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
   typeof define === 'function' && define.amd ? define(factory) :
   (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lottie = factory());
@@ -8,19 +8,15 @@
   var locationHref = '';
   var _useWebWorker = false;
   var initialDefaultFrame = -999999;
-
   var setWebWorker = function setWebWorker(flag) {
     _useWebWorker = !!flag;
   };
-
   var getWebWorker = function getWebWorker() {
     return _useWebWorker;
   };
-
   var setLocationHref = function setLocationHref(value) {
     locationHref = value;
   };
-
   var getLocationHref = function getLocationHref() {
     return locationHref;
   };
@@ -34,28 +30,24 @@
     var i;
     var len = sources.length;
     var sourcePrototype;
-
     for (i = 0; i < len; i += 1) {
       sourcePrototype = sources[i].prototype;
-
       for (var attr in sourcePrototype) {
         if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
       }
     }
   }
-
   function getDescriptor(object, prop) {
     return Object.getOwnPropertyDescriptor(object, prop);
   }
-
   function createProxyFunction(prototype) {
     function ProxyFunction() {}
-
     ProxyFunction.prototype = prototype;
     return ProxyFunction;
   }
 
   // import Howl from '../../3rd_party/howler';
+
   var audioControllerFactory = function () {
     function AudioController(audioFactory) {
       this.audios = [];
@@ -63,7 +55,6 @@
       this._volume = 1;
       this._isMuted = false;
     }
-
     AudioController.prototype = {
       addAudio: function addAudio(audio) {
         this.audios.push(audio);
@@ -71,7 +62,6 @@
       pause: function pause() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].pause();
         }
@@ -79,7 +69,6 @@
       resume: function resume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].resume();
         }
@@ -87,7 +76,6 @@
       setRate: function setRate(rateValue) {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].setRate(rateValue);
         }
@@ -96,13 +84,11 @@
         if (this.audioFactory) {
           return this.audioFactory(assetPath);
         }
-
         if (window.Howl) {
           return new window.Howl({
             src: [assetPath]
           });
         }
-
         return {
           isPlaying: false,
           play: function play() {
@@ -121,17 +107,14 @@
       },
       setVolume: function setVolume(value) {
         this._volume = value;
-
         this._updateVolume();
       },
       mute: function mute() {
         this._isMuted = true;
-
         this._updateVolume();
       },
       unmute: function unmute() {
         this._isMuted = false;
-
         this._updateVolume();
       },
       getVolume: function getVolume() {
@@ -140,7 +123,6 @@
       _updateVolume: function _updateVolume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
         }
@@ -156,55 +138,44 @@
       var i = 0;
       var arr = [];
       var value;
-
       switch (type) {
         case 'int16':
         case 'uint8c':
           value = 1;
           break;
-
         default:
           value = 1.1;
           break;
       }
-
       for (i = 0; i < len; i += 1) {
         arr.push(value);
       }
-
       return arr;
     }
-
     function createTypedArrayFactory(type, len) {
       if (type === 'float32') {
         return new Float32Array(len);
       }
-
       if (type === 'int16') {
         return new Int16Array(len);
       }
-
       if (type === 'uint8c') {
         return new Uint8ClampedArray(len);
       }
-
       return createRegularArray(type, len);
     }
-
     if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
       return createTypedArrayFactory;
     }
-
     return createRegularArray;
   }();
-
   function createSizedArray(len) {
     return Array.apply(null, {
       length: len
     });
   }
 
-  function _typeof$3(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$3 = function _typeof(obj) { return typeof obj; }; } else { _typeof$3 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$3(obj); }
+  function _typeof$3(o) { "@babel/helpers - typeof"; return _typeof$3 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$3(o); }
   var subframeEnabled = true;
   var expressionsPlugin = null;
   var expressionsInterfaces = null;
@@ -217,57 +188,43 @@
   var bmMax = Math.max;
   var bmMin = Math.min;
   var BMMath = {};
-
   (function () {
     var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
     var i;
     var len = propertyNames.length;
-
     for (i = 0; i < len; i += 1) {
       BMMath[propertyNames[i]] = Math[propertyNames[i]];
     }
   })();
-
   function ProjectInterface$1() {
     return {};
   }
-
   BMMath.random = Math.random;
-
   BMMath.abs = function (val) {
     var tOfVal = _typeof$3(val);
-
     if (tOfVal === 'object' && val.length) {
       var absArr = createSizedArray(val.length);
       var i;
       var len = val.length;
-
       for (i = 0; i < len; i += 1) {
         absArr[i] = Math.abs(val[i]);
       }
-
       return absArr;
     }
-
     return Math.abs(val);
   };
-
   var defaultCurveSegments = 150;
   var degToRads = Math.PI / 180;
   var roundCorner = 0.5519;
-
   function roundValues(flag) {
     _shouldRoundValues = !!flag;
   }
-
   function bmRnd(value) {
     if (_shouldRoundValues) {
       return Math.round(value);
     }
-
     return value;
   }
-
   function styleDiv(element) {
     element.style.position = 'absolute';
     element.style.top = 0;
@@ -281,53 +238,44 @@
     element.style.webkitTransformStyle = 'preserve-3d';
     element.style.mozTransformStyle = 'preserve-3d';
   }
-
   function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
     this.type = type;
     this.currentTime = currentTime;
     this.totalTime = totalTime;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteEvent(type, frameMultiplier) {
     this.type = type;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
     this.type = type;
     this.currentLoop = currentLoop;
     this.totalLoops = totalLoops;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMSegmentStartEvent(type, firstFrame, totalFrames) {
     this.type = type;
     this.firstFrame = firstFrame;
     this.totalFrames = totalFrames;
   }
-
   function BMDestroyEvent(type, target) {
     this.type = type;
     this.target = target;
   }
-
   function BMRenderFrameErrorEvent(nativeError, currentTime) {
     this.type = 'renderFrameError';
     this.nativeError = nativeError;
     this.currentTime = currentTime;
   }
-
   function BMConfigErrorEvent(nativeError) {
     this.type = 'configError';
     this.nativeError = nativeError;
   }
-
   function BMAnimationConfigErrorEvent(type, nativeError) {
     this.type = type;
     this.nativeError = nativeError;
   }
-
   var createElementID = function () {
     var _count = 0;
     return function createID() {
@@ -335,7 +283,6 @@
       return idPrefix$1 + '__lottie_element_' + _count;
     };
   }();
-
   function HSVtoRGB(h, s, v) {
     var r;
     var g;
@@ -350,51 +297,42 @@
     p = v * (1 - s);
     q = v * (1 - f * s);
     t = v * (1 - (1 - f) * s);
-
     switch (i % 6) {
       case 0:
         r = v;
         g = t;
         b = p;
         break;
-
       case 1:
         r = q;
         g = v;
         b = p;
         break;
-
       case 2:
         r = p;
         g = v;
         b = t;
         break;
-
       case 3:
         r = p;
         g = q;
         b = v;
         break;
-
       case 4:
         r = t;
         g = p;
         b = v;
         break;
-
       case 5:
         r = v;
         g = p;
         b = q;
         break;
-
       default:
         break;
     }
-
     return [r, g, b];
   }
-
   function RGBtoHSV(r, g, b) {
     var max = Math.max(r, g, b);
     var min = Math.min(r, g, b);
@@ -402,136 +340,105 @@
     var h;
     var s = max === 0 ? 0 : d / max;
     var v = max / 255;
-
     switch (max) {
       case min:
         h = 0;
         break;
-
       case r:
         h = g - b + d * (g < b ? 6 : 0);
         h /= 6 * d;
         break;
-
       case g:
         h = b - r + d * 2;
         h /= 6 * d;
         break;
-
       case b:
         h = r - g + d * 4;
         h /= 6 * d;
         break;
-
       default:
         break;
     }
-
     return [h, s, v];
   }
-
   function addSaturationToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[1] += offset;
-
     if (hsv[1] > 1) {
       hsv[1] = 1;
     } else if (hsv[1] <= 0) {
       hsv[1] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addBrightnessToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[2] += offset;
-
     if (hsv[2] > 1) {
       hsv[2] = 1;
     } else if (hsv[2] < 0) {
       hsv[2] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addHueToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[0] += offset / 360;
-
     if (hsv[0] > 1) {
       hsv[0] -= 1;
     } else if (hsv[0] < 0) {
       hsv[0] += 1;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   var rgbToHex = function () {
     var colorMap = [];
     var i;
     var hex;
-
     for (i = 0; i < 256; i += 1) {
       hex = i.toString(16);
       colorMap[i] = hex.length === 1 ? '0' + hex : hex;
     }
-
     return function (r, g, b) {
       if (r < 0) {
         r = 0;
       }
-
       if (g < 0) {
         g = 0;
       }
-
       if (b < 0) {
         b = 0;
       }
-
       return '#' + colorMap[r] + colorMap[g] + colorMap[b];
     };
   }();
-
   var setSubframeEnabled = function setSubframeEnabled(flag) {
     subframeEnabled = !!flag;
   };
-
   var getSubframeEnabled = function getSubframeEnabled() {
     return subframeEnabled;
   };
-
   var setExpressionsPlugin = function setExpressionsPlugin(value) {
     expressionsPlugin = value;
   };
-
   var getExpressionsPlugin = function getExpressionsPlugin() {
     return expressionsPlugin;
   };
-
   var setExpressionInterfaces = function setExpressionInterfaces(value) {
     expressionsInterfaces = value;
   };
-
   var getExpressionInterfaces = function getExpressionInterfaces() {
     return expressionsInterfaces;
   };
-
   var setDefaultCurveSegments = function setDefaultCurveSegments(value) {
     defaultCurveSegments = value;
   };
-
   var getDefaultCurveSegments = function getDefaultCurveSegments() {
     return defaultCurveSegments;
   };
-
   var setIdPrefix = function setIdPrefix(value) {
     idPrefix$1 = value;
   };
-
   var getIdPrefix = function getIdPrefix() {
     return idPrefix$1;
   };
@@ -541,8 +448,7 @@
     return document.createElementNS(svgNS, type);
   }
 
-  function _typeof$2(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$2 = function _typeof(obj) { return typeof obj; }; } else { _typeof$2 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$2(obj); }
-
+  function _typeof$2(o) { "@babel/helpers - typeof"; return _typeof$2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$2(o); }
   var dataManager = function () {
     var _counterId = 1;
     var processes = [];
@@ -563,21 +469,18 @@
         });
       }
     };
-
     function createWorker(fn) {
       if (window.Worker && window.Blob && getWebWorker()) {
         var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], {
           type: 'text/javascript'
-        }); // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
-
+        });
+        // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
         var url = URL.createObjectURL(blob);
         return new Worker(url);
       }
-
       workerFn = fn;
       return workerProxy;
     }
-
     function setupWorker() {
       if (!workerInstance) {
         workerInstance = createWorker(function workerStart(e) {
@@ -590,28 +493,22 @@
               var jLen;
               var k;
               var kLen;
-
               for (i = 0; i < len; i += 1) {
                 layerData = layers[i];
-
                 if ('ks' in layerData && !layerData.completed) {
                   layerData.completed = true;
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         convertPathsToAbsoluteValues(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) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
                           }
@@ -619,7 +516,6 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 0) {
                     layerData.layers = findCompLayers(layerData.refId, comps);
                     completeLayers(layerData.layers, comps);
@@ -631,16 +527,15 @@
                 }
               }
             }
-
             function completeChars(chars, assets) {
               if (chars) {
                 var i = 0;
                 var len = chars.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (chars[i].t === 1) {
                     // var compData = findComp(chars[i].data.refId, assets);
-                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets); // chars[i].data.ip = 0;
+                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                    // chars[i].data.ip = 0;
                     // chars[i].data.op = 99999;
                     // chars[i].data.st = 0;
                     // chars[i].data.sr = 1;
@@ -652,61 +547,48 @@
                     //   s: { k: [100, 100], a: 0 },
                     //   o: { k: 100, a: 0 },
                     // };
-
                     completeLayers(chars[i].data.layers, assets);
                   }
                 }
               }
             }
-
             function findComp(id, comps) {
               var i = 0;
               var len = comps.length;
-
               while (i < len) {
                 if (comps[i].id === id) {
                   return comps[i];
                 }
-
                 i += 1;
               }
-
               return null;
             }
-
             function findCompLayers(id, comps) {
               var comp = findComp(id, comps);
-
               if (comp) {
                 if (!comp.layers.__used) {
                   comp.layers.__used = true;
                   return comp.layers;
                 }
-
                 return JSON.parse(JSON.stringify(comp.layers));
               }
-
               return null;
             }
-
             function completeShapes(arr) {
               var i;
               var len = arr.length;
               var j;
               var jLen;
-
               for (i = len - 1; i >= 0; i -= 1) {
                 if (arr[i].ty === 'sh') {
                   if (arr[i].ks.k.i) {
                     convertPathsToAbsoluteValues(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) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
                       }
-
                       if (arr[i].ks.k[j].e) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
                       }
@@ -717,11 +599,9 @@
                 }
               }
             }
-
             function convertPathsToAbsoluteValues(path) {
               var i;
               var len = path.i.length;
-
               for (i = 0; i < len; i += 1) {
                 path.i[i][0] += path.v[i][0];
                 path.i[i][1] += path.v[i][1];
@@ -729,40 +609,30 @@
                 path.o[i][1] += path.v[i][1];
               }
             }
-
             function checkVersion(minimum, animVersionString) {
               var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
-
               if (minimum[0] > animVersion[0]) {
                 return true;
               }
-
               if (animVersion[0] > minimum[0]) {
                 return false;
               }
-
               if (minimum[1] > animVersion[1]) {
                 return true;
               }
-
               if (animVersion[1] > minimum[1]) {
                 return false;
               }
-
               if (minimum[2] > animVersion[2]) {
                 return true;
               }
-
               if (animVersion[2] > minimum[2]) {
                 return false;
               }
-
               return null;
             }
-
             var checkText = function () {
               var minimumVersion = [4, 4, 14];
-
               function updateTextLayer(textLayer) {
                 var documentData = textLayer.t.d;
                 textLayer.t.d = {
@@ -772,26 +642,21 @@
                   }]
                 };
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -801,17 +666,14 @@
                 }
               };
             }();
-
             var checkChars = function () {
               var minimumVersion = [4, 7, 99];
               return function (animationData) {
                 if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
                   var i;
                   var len = animationData.chars.length;
-
                   for (i = 0; i < len; i += 1) {
                     var charData = animationData.chars[i];
-
                     if (charData.data && charData.data.shapes) {
                       completeShapes(charData.data.shapes);
                       charData.data.ip = 0;
@@ -840,7 +702,6 @@
                           a: 0
                         }
                       };
-
                       if (!animationData.chars[i].t) {
                         charData.data.shapes.push({
                           ty: 'no'
@@ -882,27 +743,22 @@
                 }
               };
             }();
-
             var checkPathProperties = function () {
               var minimumVersion = [5, 7, 15];
-
               function updateTextLayer(textLayer) {
                 var pathData = textLayer.t.p;
-
                 if (typeof pathData.a === 'number') {
                   pathData.a = {
                     a: 0,
                     k: pathData.a
                   };
                 }
-
                 if (typeof pathData.p === 'number') {
                   pathData.p = {
                     a: 0,
                     k: pathData.p
                   };
                 }
-
                 if (typeof pathData.r === 'number') {
                   pathData.r = {
                     a: 0,
@@ -910,26 +766,21 @@
                   };
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -939,23 +790,19 @@
                 }
               };
             }();
-
             var checkColors = function () {
               var minimumVersion = [4, 1, 9];
-
               function iterateShapes(shapes) {
                 var i;
                 var len = shapes.length;
                 var j;
                 var jLen;
-
                 for (i = 0; i < len; i += 1) {
                   if (shapes[i].ty === 'gr') {
                     iterateShapes(shapes[i].it);
                   } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
                     if (shapes[i].c.k && shapes[i].c.k[0].i) {
                       jLen = shapes[i].c.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (shapes[i].c.k[j].s) {
                           shapes[i].c.k[j].s[0] /= 255;
@@ -963,7 +810,6 @@
                           shapes[i].c.k[j].s[2] /= 255;
                           shapes[i].c.k[j].s[3] /= 255;
                         }
-
                         if (shapes[i].c.k[j].e) {
                           shapes[i].c.k[j].e[0] /= 255;
                           shapes[i].c.k[j].e[1] /= 255;
@@ -980,26 +826,21 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 4) {
                     iterateShapes(layers[i].shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1009,28 +850,23 @@
                 }
               };
             }();
-
             var checkShapes = function () {
               var minimumVersion = [4, 4, 18];
-
               function completeClosingShapes(arr) {
                 var i;
                 var len = arr.length;
                 var j;
                 var jLen;
-
                 for (i = len - 1; i >= 0; i -= 1) {
                   if (arr[i].ty === 'sh') {
                     if (arr[i].ks.k.i) {
                       arr[i].ks.k.c = arr[i].closed;
                     } else {
                       jLen = arr[i].ks.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (arr[i].ks.k[j].s) {
                           arr[i].ks.k[j].s[0].c = arr[i].closed;
                         }
-
                         if (arr[i].ks.k[j].e) {
                           arr[i].ks.k[j].e[0].c = arr[i].closed;
                         }
@@ -1041,7 +877,6 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var layerData;
                 var i;
@@ -1050,25 +885,20 @@
                 var jLen;
                 var k;
                 var kLen;
-
                 for (i = 0; i < len; i += 1) {
                   layerData = layers[i];
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         maskProps[j].pt.k.c = maskProps[j].cl;
                       } else {
                         kLen = maskProps[j].pt.k.length;
-
                         for (k = 0; k < kLen; k += 1) {
                           if (maskProps[j].pt.k[k].s) {
                             maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
                           }
@@ -1076,21 +906,17 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 4) {
                     completeClosingShapes(layerData.shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1100,12 +926,10 @@
                 }
               };
             }();
-
             function completeData(animationData) {
               if (animationData.__complete) {
                 return;
               }
-
               checkColors(animationData);
               checkText(animationData);
               checkChars(animationData);
@@ -1115,12 +939,11 @@
               completeChars(animationData.chars, animationData.assets);
               animationData.__complete = true;
             }
-
             function completeText(data) {
-              if (data.t.a.length === 0 && !('m' in data.t.p)) {// data.singleShape = true;
+              if (data.t.a.length === 0 && !('m' in data.t.p)) {
+                // data.singleShape = true;
               }
             }
-
             var moduleOb = {};
             moduleOb.completeData = completeData;
             moduleOb.checkColors = checkColors;
@@ -1130,47 +953,37 @@
             moduleOb.completeLayers = completeLayers;
             return moduleOb;
           }
-
           if (!_workerSelf.dataManager) {
             _workerSelf.dataManager = dataFunctionManager();
           }
-
           if (!_workerSelf.assetLoader) {
             _workerSelf.assetLoader = function () {
               function formatResponse(xhr) {
                 // using typeof doubles the time of execution of this method,
                 // so if available, it's better to use the header to validate the type
                 var contentTypeHeader = xhr.getResponseHeader('content-type');
-
                 if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
                   return xhr.response;
                 }
-
                 if (xhr.response && _typeof$2(xhr.response) === 'object') {
                   return xhr.response;
                 }
-
                 if (xhr.response && typeof xhr.response === 'string') {
                   return JSON.parse(xhr.response);
                 }
-
                 if (xhr.responseText) {
                   return JSON.parse(xhr.responseText);
                 }
-
                 return null;
               }
-
               function loadAsset(path, fullPath, callback, errorCallback) {
                 var response;
-                var xhr = new XMLHttpRequest(); // set responseType after calling open or IE will break.
-
+                var xhr = new XMLHttpRequest();
+                // set responseType after calling open or IE will break.
                 try {
                   // This crashes on Android WebView prior to KitKat
                   xhr.responseType = 'json';
                 } catch (err) {} // eslint-disable-line no-empty
-
-
                 xhr.onreadystatechange = function () {
                   if (xhr.readyState === 4) {
                     if (xhr.status === 200) {
@@ -1188,7 +1001,6 @@
                     }
                   }
                 };
-
                 try {
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), path, true);
@@ -1196,20 +1008,16 @@
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
                 }
-
                 xhr.send();
               }
-
               return {
                 load: loadAsset
               };
             }();
           }
-
           if (e.data.type === 'loadAnimation') {
             _workerSelf.assetLoader.load(e.data.path, e.data.fullPath, function (data) {
               _workerSelf.dataManager.completeData(data);
-
               _workerSelf.postMessage({
                 id: e.data.id,
                 payload: data,
@@ -1223,9 +1031,7 @@
             });
           } else if (e.data.type === 'complete') {
             var animation = e.data.animation;
-
             _workerSelf.dataManager.completeData(animation);
-
             _workerSelf.postMessage({
               id: e.data.id,
               payload: animation,
@@ -1246,13 +1052,11 @@
             });
           }
         });
-
         workerInstance.onmessage = function (event) {
           var data = event.data;
           var id = data.id;
           var process = processes[id];
           processes[id] = null;
-
           if (data.status === 'success') {
             process.onComplete(data.payload);
           } else if (process.onError) {
@@ -1261,7 +1065,6 @@
         };
       }
     }
-
     function createProcess(onComplete, onError) {
       _counterId += 1;
       var id = 'processId_' + _counterId;
@@ -1271,7 +1074,6 @@
       };
       return id;
     }
-
     function loadAnimation(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1282,7 +1084,6 @@
         id: processId
       });
     }
-
     function loadData(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1293,7 +1094,6 @@
         id: processId
       });
     }
-
     function completeAnimation(anim, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1303,7 +1103,6 @@
         id: processId
       });
     }
-
     return {
       loadAnimation: loadAnimation,
       loadData: loadData,
@@ -1321,94 +1120,74 @@
       ctx.fillRect(0, 0, 1, 1);
       return canvas;
     }();
-
     function imageLoaded() {
       this.loadedAssets += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function footageLoaded() {
       this.loadedFootagesCount += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function getAssetsPath(assetData, assetsPath, originalPath) {
       var path = '';
-
       if (assetData.e) {
         path = assetData.p;
       } else if (assetsPath) {
         var imagePath = assetData.p;
-
         if (imagePath.indexOf('images/') !== -1) {
           imagePath = imagePath.split('/')[1];
         }
-
         path = assetsPath + imagePath;
       } else {
         path = originalPath;
         path += assetData.u ? assetData.u : '';
         path += assetData.p;
       }
-
       return path;
     }
-
     function testImageLoaded(img) {
       var _count = 0;
       var intervalId = setInterval(function () {
         var box = img.getBBox();
-
         if (box.width || _count > 500) {
           this._imageLoaded();
-
           clearInterval(intervalId);
         }
-
         _count += 1;
       }.bind(this), 50);
     }
-
     function createImageData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createNS('image');
-
       if (isSafari) {
         this.testImageLoaded(img);
       } else {
         img.addEventListener('load', this._imageLoaded, false);
       }
-
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
-
       if (this._elementHelper.append) {
         this._elementHelper.append(img);
       } else {
         this._elementHelper.appendChild(img);
       }
-
       var ob = {
         img: img,
         assetData: assetData
       };
       return ob;
     }
-
     function createImgData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createTag('img');
@@ -1416,7 +1195,6 @@
       img.addEventListener('load', this._imageLoaded, false);
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.src = path;
@@ -1426,7 +1204,6 @@
       };
       return ob;
     }
-
     function createFootageData(data) {
       var ob = {
         assetData: data
@@ -1434,21 +1211,17 @@
       var path = getAssetsPath(data, this.assetsPath, this.path);
       dataManager.loadData(path, function (footageData) {
         ob.img = footageData;
-
         this._footageLoaded();
       }.bind(this), function () {
         ob.img = {};
-
         this._footageLoaded();
       }.bind(this));
       return ob;
     }
-
     function loadAssets(assets, cb) {
       this.imagesLoadedCb = cb;
       var i;
       var len = assets.length;
-
       for (i = 0; i < len; i += 1) {
         if (!assets[i].layers) {
           if (!assets[i].t || assets[i].t === 'seq') {
@@ -1461,43 +1234,33 @@
         }
       }
     }
-
     function setPath(path) {
       this.path = path || '';
     }
-
     function setAssetsPath(path) {
       this.assetsPath = path || '';
     }
-
     function getAsset(assetData) {
       var i = 0;
       var len = this.images.length;
-
       while (i < len) {
         if (this.images[i].assetData === assetData) {
           return this.images[i].img;
         }
-
         i += 1;
       }
-
       return null;
     }
-
     function destroy() {
       this.imagesLoadedCb = null;
       this.images.length = 0;
     }
-
     function loadedImages() {
       return this.totalImages === this.loadedAssets;
     }
-
     function loadedFootages() {
       return this.totalFootages === this.loadedFootagesCount;
     }
-
     function setCacheType(type, elementHelper) {
       if (type === 'svg') {
         this._elementHelper = elementHelper;
@@ -1506,7 +1269,6 @@
         this._createImageData = this.createImgData.bind(this);
       }
     }
-
     function ImagePreloaderFactory() {
       this._imageLoaded = imageLoaded.bind(this);
       this._footageLoaded = footageLoaded.bind(this);
@@ -1521,7 +1283,6 @@
       this.imagesLoadedCb = null;
       this.images = [];
     }
-
     ImagePreloaderFactory.prototype = {
       loadAssets: loadAssets,
       setAssetsPath: setAssetsPath,
@@ -1540,12 +1301,10 @@
   }();
 
   function BaseEvent() {}
-
   BaseEvent.prototype = {
     triggerEvent: function triggerEvent(eventName, args) {
       if (this._cbs[eventName]) {
         var callbacks = this._cbs[eventName];
-
         for (var i = 0; i < callbacks.length; i += 1) {
           callbacks[i](args);
         }
@@ -1555,9 +1314,7 @@
       if (!this._cbs[eventName]) {
         this._cbs[eventName] = [];
       }
-
       this._cbs[eventName].push(callback);
-
       return function () {
         this.removeEventListener(eventName, callback);
       }.bind(this);
@@ -1568,18 +1325,14 @@
       } else if (this._cbs[eventName]) {
         var i = 0;
         var len = this._cbs[eventName].length;
-
         while (i < len) {
           if (this._cbs[eventName][i] === callback) {
             this._cbs[eventName].splice(i, 1);
-
             i -= 1;
             len -= 1;
           }
-
           i += 1;
         }
-
         if (!this._cbs[eventName].length) {
           this._cbs[eventName] = null;
         }
@@ -1593,33 +1346,26 @@
       var keys = {};
       var line;
       var keysCount = 0;
-
       for (var i = 0; i < lines.length; i += 1) {
         line = lines[i].split(':');
-
         if (line.length === 2) {
           keys[line[0]] = line[1].trim();
           keysCount += 1;
         }
       }
-
       if (keysCount === 0) {
         throw new Error();
       }
-
       return keys;
     }
-
     return function (_markers) {
       var markers = [];
-
       for (var i = 0; i < _markers.length; i += 1) {
         var _marker = _markers[i];
         var markerData = {
           time: _marker.tm,
           duration: _marker.dr
         };
-
         try {
           markerData.payload = JSON.parse(_markers[i].cm);
         } catch (_) {
@@ -1631,10 +1377,8 @@
             };
           }
         }
-
         markers.push(markerData);
       }
-
       return markers;
     };
   }();
@@ -1643,27 +1387,21 @@
     function registerComposition(comp) {
       this.compositions.push(comp);
     }
-
     return function () {
       function _thisProjectFunction(name) {
         var i = 0;
         var len = this.compositions.length;
-
         while (i < len) {
           if (this.compositions[i].data && this.compositions[i].data.nm === name) {
             if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
               this.compositions[i].prepareFrame(this.currentFrame);
             }
-
             return this.compositions[i].compInterface;
           }
-
           i += 1;
         }
-
         return null;
       }
-
       _thisProjectFunction.compositions = [];
       _thisProjectFunction.currentFrame = 0;
       _thisProjectFunction.registerComposition = registerComposition;
@@ -1672,33 +1410,27 @@
   }();
 
   var renderers = {};
-
   var registerRenderer = function registerRenderer(key, value) {
     renderers[key] = value;
   };
-
   function getRenderer(key) {
     return renderers[key];
   }
-
   function getRegisteredRenderer() {
     // Returns canvas by default for compatibility
     if (renderers.canvas) {
       return 'canvas';
-    } // Returns any renderer that is registered
-
-
+    }
+    // Returns any renderer that is registered
     for (var key in renderers) {
       if (renderers[key]) {
         return key;
       }
     }
-
     return '';
   }
 
-  function _typeof$1(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$1 = function _typeof(obj) { return typeof obj; }; } else { _typeof$1 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$1(obj); }
-
+  function _typeof$1(o) { "@babel/helpers - typeof"; return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$1(o); }
   var AnimationItem = function AnimationItem() {
     this._cbs = [];
     this.name = '';
@@ -1737,28 +1469,22 @@
     this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
     this.expressionsPlugin = getExpressionsPlugin();
   };
-
   extendPrototype([BaseEvent], AnimationItem);
-
   AnimationItem.prototype.setParams = function (params) {
     if (params.wrapper || params.container) {
       this.wrapper = params.wrapper || params.container;
     }
-
     var animType = 'svg';
-
     if (params.animType) {
       animType = params.animType;
     } else if (params.renderer) {
       animType = params.renderer;
     }
-
     var RendererClass = getRenderer(animType);
     this.renderer = new RendererClass(this, params.rendererSettings);
     this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
     this.renderer.setProjectInterface(this.projectInterface);
     this.animType = animType;
-
     if (params.loop === '' || params.loop === null || params.loop === undefined || params.loop === true) {
       this.loop = true;
     } else if (params.loop === false) {
@@ -1766,17 +1492,14 @@
     } else {
       this.loop = parseInt(params.loop, 10);
     }
-
     this.autoplay = 'autoplay' in params ? params.autoplay : true;
     this.name = params.name ? params.name : '';
     this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
     this.assetsPath = params.assetsPath;
     this.initialSegment = params.initialSegment;
-
     if (params.audioFactory) {
       this.audioController.setAudioFactory(params.audioFactory);
     }
-
     if (params.animationData) {
       this.setupAnimation(params.animationData);
     } else if (params.path) {
@@ -1785,28 +1508,23 @@
       } else {
         this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
       }
-
       this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
       this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
       dataManager.loadAnimation(params.path, this.configAnimation, this.onSetupError);
     }
   };
-
   AnimationItem.prototype.onSetupError = function () {
     this.trigger('data_failed');
   };
-
   AnimationItem.prototype.setupAnimation = function (data) {
     dataManager.completeAnimation(data, this.configAnimation);
   };
-
   AnimationItem.prototype.setData = function (wrapper, animationData) {
     if (animationData) {
       if (_typeof$1(animationData) !== 'object') {
         animationData = JSON.parse(animationData);
       }
     }
-
     var params = {
       wrapper: wrapper,
       animationData: animationData
@@ -1823,7 +1541,6 @@
     var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-loop').value : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-loop').value : wrapperAttributes.getNamedItem('bm-loop') ? wrapperAttributes.getNamedItem('bm-loop').value : '';
-
     if (loop === 'false') {
       params.loop = false;
     } else if (loop === 'true') {
@@ -1831,7 +1548,6 @@
     } else if (loop !== '') {
       params.loop = parseInt(loop, 10);
     }
-
     var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-autoplay').value : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-autoplay').value : wrapperAttributes.getNamedItem('bm-autoplay') ? wrapperAttributes.getNamedItem('bm-autoplay').value : true;
@@ -1842,81 +1558,64 @@
     var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-prerender').value : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-prerender').value : wrapperAttributes.getNamedItem('bm-prerender') ? wrapperAttributes.getNamedItem('bm-prerender').value : '';
-
     if (prerender === 'false') {
       params.prerender = false;
     }
-
     if (!params.path) {
       this.trigger('destroy');
     } else {
       this.setParams(params);
     }
   };
-
   AnimationItem.prototype.includeLayers = function (data) {
     if (data.op > this.animationData.op) {
       this.animationData.op = data.op;
       this.totalFrames = Math.floor(data.op - this.animationData.ip);
     }
-
     var layers = this.animationData.layers;
     var i;
     var len = layers.length;
     var newLayers = data.layers;
     var j;
     var jLen = newLayers.length;
-
     for (j = 0; j < jLen; j += 1) {
       i = 0;
-
       while (i < len) {
         if (layers[i].id === newLayers[j].id) {
           layers[i] = newLayers[j];
           break;
         }
-
         i += 1;
       }
     }
-
     if (data.chars || data.fonts) {
       this.renderer.globalData.fontManager.addChars(data.chars);
       this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
     }
-
     if (data.assets) {
       len = data.assets.length;
-
       for (i = 0; i < len; i += 1) {
         this.animationData.assets.push(data.assets[i]);
       }
     }
-
     this.animationData.__complete = false;
     dataManager.completeAnimation(this.animationData, this.onSegmentComplete);
   };
-
   AnimationItem.prototype.onSegmentComplete = function (data) {
     this.animationData = data;
     var expressionsPlugin = getExpressionsPlugin();
-
     if (expressionsPlugin) {
       expressionsPlugin.initExpressions(this);
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.loadNextSegment = function () {
     var segments = this.animationData.segments;
-
     if (!segments || segments.length === 0 || !this.autoloadSegments) {
       this.trigger('data_ready');
       this.timeCompleted = this.totalFrames;
       return;
     }
-
     var segment = segments.shift();
     this.timeCompleted = segment.time * this.frameRate;
     var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
@@ -1925,36 +1624,28 @@
       this.trigger('data_failed');
     }.bind(this));
   };
-
   AnimationItem.prototype.loadSegments = function () {
     var segments = this.animationData.segments;
-
     if (!segments) {
       this.timeCompleted = this.totalFrames;
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.imagesLoaded = function () {
     this.trigger('loaded_images');
     this.checkLoaded();
   };
-
   AnimationItem.prototype.preloadImages = function () {
     this.imagePreloader.setAssetsPath(this.assetsPath);
     this.imagePreloader.setPath(this.path);
     this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
   };
-
   AnimationItem.prototype.configAnimation = function (animData) {
     if (!this.renderer) {
       return;
     }
-
     try {
       this.animationData = animData;
-
       if (this.initialSegment) {
         this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
         this.firstFrame = Math.round(this.initialSegment[0]);
@@ -1962,13 +1653,10 @@
         this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
         this.firstFrame = Math.round(this.animationData.ip);
       }
-
       this.renderer.configAnimation(animData);
-
       if (!animData.assets) {
         animData.assets = [];
       }
-
       this.assets = this.animationData.assets;
       this.frameRate = this.animationData.fr;
       this.frameMult = this.animationData.fr / 1000;
@@ -1979,7 +1667,6 @@
       this.loadSegments();
       this.updaFrameModifier();
       this.waitForFontsLoaded();
-
       if (this.isPaused) {
         this.audioController.pause();
       }
@@ -1987,103 +1674,83 @@
       this.triggerConfigError(error);
     }
   };
-
   AnimationItem.prototype.waitForFontsLoaded = function () {
     if (!this.renderer) {
       return;
     }
-
     if (this.renderer.globalData.fontManager.isLoaded) {
       this.checkLoaded();
     } else {
       setTimeout(this.waitForFontsLoaded.bind(this), 20);
     }
   };
-
   AnimationItem.prototype.checkLoaded = function () {
     if (!this.isLoaded && this.renderer.globalData.fontManager.isLoaded && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas') && this.imagePreloader.loadedFootages()) {
       this.isLoaded = true;
       var expressionsPlugin = getExpressionsPlugin();
-
       if (expressionsPlugin) {
         expressionsPlugin.initExpressions(this);
       }
-
       this.renderer.initItems();
       setTimeout(function () {
         this.trigger('DOMLoaded');
       }.bind(this), 0);
       this.gotoFrame();
-
       if (this.autoplay) {
         this.play();
       }
     }
   };
-
   AnimationItem.prototype.resize = function (width, height) {
     // Adding this validation for backwards compatibility in case an event object was being passed down
     var _width = typeof width === 'number' ? width : undefined;
-
     var _height = typeof height === 'number' ? height : undefined;
-
     this.renderer.updateContainerSize(_width, _height);
   };
-
   AnimationItem.prototype.setSubframe = function (flag) {
     this.isSubframeEnabled = !!flag;
   };
-
   AnimationItem.prototype.gotoFrame = function () {
     this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
 
     if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
       this.currentFrame = this.timeCompleted;
     }
-
     this.trigger('enterFrame');
     this.renderFrame();
     this.trigger('drawnFrame');
   };
-
   AnimationItem.prototype.renderFrame = function () {
     if (this.isLoaded === false || !this.renderer) {
       return;
     }
-
     try {
       if (this.expressionsPlugin) {
         this.expressionsPlugin.resetFrame();
       }
-
       this.renderer.renderFrame(this.currentFrame + this.firstFrame);
     } catch (error) {
       this.triggerRenderFrameError(error);
     }
   };
-
   AnimationItem.prototype.play = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.isPaused = false;
       this.trigger('_play');
       this.audioController.resume();
-
       if (this._idle) {
         this._idle = false;
         this.trigger('_active');
       }
     }
   };
-
   AnimationItem.prototype.pause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === false) {
       this.isPaused = true;
       this.trigger('_pause');
@@ -2092,54 +1759,42 @@
       this.audioController.pause();
     }
   };
-
   AnimationItem.prototype.togglePause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.play();
     } else {
       this.pause();
     }
   };
-
   AnimationItem.prototype.stop = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.pause();
     this.playCount = 0;
     this._completedLoop = false;
     this.setCurrentRawFrameValue(0);
   };
-
   AnimationItem.prototype.getMarkerData = function (markerName) {
     var marker;
-
     for (var i = 0; i < this.markers.length; i += 1) {
       marker = this.markers[i];
-
       if (marker.payload && marker.payload.name === markerName) {
         return marker;
       }
     }
-
     return null;
   };
-
   AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         this.goToAndStop(marker.time, true);
       }
@@ -2148,20 +1803,15 @@
     } else {
       this.setCurrentRawFrameValue(value * this.frameModifier);
     }
-
     this.pause();
   };
-
   AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         if (!marker.duration) {
           this.goToAndStop(marker.time, true);
@@ -2172,19 +1822,16 @@
     } else {
       this.goToAndStop(numValue, isFrame, name);
     }
-
     this.play();
   };
-
   AnimationItem.prototype.advanceTime = function (value) {
     if (this.isPaused === true || this.isLoaded === false) {
       return;
     }
-
     var nextValue = this.currentRawFrame + value * this.frameModifier;
-    var _isComplete = false; // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+    var _isComplete = false;
+    // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
     // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
-
     if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
       if (!this.loop || this.playCount === this.loop) {
         if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
@@ -2193,7 +1840,6 @@
         }
       } else if (nextValue >= this.totalFrames) {
         this.playCount += 1;
-
         if (!this.checkSegments(nextValue % this.totalFrames)) {
           this.setCurrentRawFrameValue(nextValue % this.totalFrames);
           this._completedLoop = true;
@@ -2207,7 +1853,6 @@
         if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) {
           // eslint-disable-line no-plusplus
           this.setCurrentRawFrameValue(this.totalFrames + nextValue % this.totalFrames);
-
           if (!this._completedLoop) {
             this._completedLoop = true;
           } else {
@@ -2221,17 +1866,14 @@
     } else {
       this.setCurrentRawFrameValue(nextValue);
     }
-
     if (_isComplete) {
       this.setCurrentRawFrameValue(nextValue);
       this.pause();
       this.trigger('complete');
     }
   };
-
   AnimationItem.prototype.adjustSegment = function (arr, offset) {
     this.playCount = 0;
-
     if (arr[1] < arr[0]) {
       if (this.frameModifier > 0) {
         if (this.playSpeed < 0) {
@@ -2240,7 +1882,6 @@
           this.setDirection(-1);
         }
       }
-
       this.totalFrames = arr[0] - arr[1];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[1];
@@ -2253,19 +1894,15 @@
           this.setDirection(1);
         }
       }
-
       this.totalFrames = arr[1] - arr[0];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[0];
       this.setCurrentRawFrameValue(0.001 + offset);
     }
-
     this.trigger('segmentStart');
   };
-
   AnimationItem.prototype.setSegment = function (init, end) {
     var pendingFrame = -1;
-
     if (this.isPaused) {
       if (this.currentRawFrame + this.firstFrame < init) {
         pendingFrame = init;
@@ -2273,64 +1910,51 @@
         pendingFrame = end - init;
       }
     }
-
     this.firstFrame = init;
     this.totalFrames = end - init;
     this.timeCompleted = this.totalFrames;
-
     if (pendingFrame !== -1) {
       this.goToAndStop(pendingFrame, true);
     }
   };
-
   AnimationItem.prototype.playSegments = function (arr, forceFlag) {
     if (forceFlag) {
       this.segments.length = 0;
     }
-
     if (_typeof$1(arr[0]) === 'object') {
       var i;
       var len = arr.length;
-
       for (i = 0; i < len; i += 1) {
         this.segments.push(arr[i]);
       }
     } else {
       this.segments.push(arr);
     }
-
     if (this.segments.length && forceFlag) {
       this.adjustSegment(this.segments.shift(), 0);
     }
-
     if (this.isPaused) {
       this.play();
     }
   };
-
   AnimationItem.prototype.resetSegments = function (forceFlag) {
     this.segments.length = 0;
     this.segments.push([this.animationData.ip, this.animationData.op]);
-
     if (forceFlag) {
       this.checkSegments(0);
     }
   };
-
   AnimationItem.prototype.checkSegments = function (offset) {
     if (this.segments.length) {
       this.adjustSegment(this.segments.shift(), offset);
       return true;
     }
-
     return false;
   };
-
   AnimationItem.prototype.destroy = function (name) {
     if (name && this.name !== name || !this.renderer) {
       return;
     }
-
     this.renderer.destroy();
     this.imagePreloader.destroy();
     this.trigger('destroy');
@@ -2345,189 +1969,148 @@
     this.imagePreloader = null;
     this.projectInterface = null;
   };
-
   AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
     this.currentRawFrame = value;
     this.gotoFrame();
   };
-
   AnimationItem.prototype.setSpeed = function (val) {
     this.playSpeed = val;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setDirection = function (val) {
     this.playDirection = val < 0 ? -1 : 1;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setLoop = function (isLooping) {
     this.loop = isLooping;
   };
-
   AnimationItem.prototype.setVolume = function (val, name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.setVolume(val);
   };
-
   AnimationItem.prototype.getVolume = function () {
     return this.audioController.getVolume();
   };
-
   AnimationItem.prototype.mute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.mute();
   };
-
   AnimationItem.prototype.unmute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.unmute();
   };
-
   AnimationItem.prototype.updaFrameModifier = function () {
     this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
     this.audioController.setRate(this.playSpeed * this.playDirection);
   };
-
   AnimationItem.prototype.getPath = function () {
     return this.path;
   };
-
   AnimationItem.prototype.getAssetsPath = function (assetData) {
     var path = '';
-
     if (assetData.e) {
       path = assetData.p;
     } else if (this.assetsPath) {
       var imagePath = assetData.p;
-
       if (imagePath.indexOf('images/') !== -1) {
         imagePath = imagePath.split('/')[1];
       }
-
       path = this.assetsPath + imagePath;
     } else {
       path = this.path;
       path += assetData.u ? assetData.u : '';
       path += assetData.p;
     }
-
     return path;
   };
-
   AnimationItem.prototype.getAssetData = function (id) {
     var i = 0;
     var len = this.assets.length;
-
     while (i < len) {
       if (id === this.assets[i].id) {
         return this.assets[i];
       }
-
       i += 1;
     }
-
     return null;
   };
-
   AnimationItem.prototype.hide = function () {
     this.renderer.hide();
   };
-
   AnimationItem.prototype.show = function () {
     this.renderer.show();
   };
-
   AnimationItem.prototype.getDuration = function (isFrame) {
     return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
   };
-
   AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
     try {
       var element = this.renderer.getElementByPath(path);
       element.updateDocumentData(documentData, index);
-    } catch (error) {// TODO: decide how to handle catch case
+    } catch (error) {
+      // TODO: decide how to handle catch case
     }
   };
-
   AnimationItem.prototype.trigger = function (name) {
     if (this._cbs && this._cbs[name]) {
       switch (name) {
         case 'enterFrame':
           this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
           break;
-
         case 'drawnFrame':
           this.drawnFrameEvent.currentTime = this.currentFrame;
           this.drawnFrameEvent.totalTime = this.totalFrames;
           this.drawnFrameEvent.direction = this.frameModifier;
           this.triggerEvent(name, this.drawnFrameEvent);
           break;
-
         case 'loopComplete':
           this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
           break;
-
         case 'complete':
           this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
           break;
-
         case 'segmentStart':
           this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
           break;
-
         case 'destroy':
           this.triggerEvent(name, new BMDestroyEvent(name, this));
           break;
-
         default:
           this.triggerEvent(name);
       }
     }
-
     if (name === 'enterFrame' && this.onEnterFrame) {
       this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
     }
-
     if (name === 'loopComplete' && this.onLoopComplete) {
       this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
     }
-
     if (name === 'complete' && this.onComplete) {
       this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
     }
-
     if (name === 'segmentStart' && this.onSegmentStart) {
       this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
     }
-
     if (name === 'destroy' && this.onDestroy) {
       this.onDestroy.call(this, new BMDestroyEvent(name, this));
     }
   };
-
   AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
     var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
   };
-
   AnimationItem.prototype.triggerConfigError = function (nativeError) {
     var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
@@ -2541,68 +2124,53 @@
     var playingAnimationsNum = 0;
     var _stopped = true;
     var _isFrozen = false;
-
     function removeElement(ev) {
       var i = 0;
       var animItem = ev.target;
-
       while (i < len) {
         if (registeredAnimations[i].animation === animItem) {
           registeredAnimations.splice(i, 1);
           i -= 1;
           len -= 1;
-
           if (!animItem.isPaused) {
             subtractPlayingCount();
           }
         }
-
         i += 1;
       }
     }
-
     function registerAnimation(element, animationData) {
       if (!element) {
         return null;
       }
-
       var i = 0;
-
       while (i < len) {
         if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
           return registeredAnimations[i].animation;
         }
-
         i += 1;
       }
-
       var animItem = new AnimationItem();
       setupAnimation(animItem, element);
       animItem.setData(element, animationData);
       return animItem;
     }
-
     function getRegisteredAnimations() {
       var i;
       var lenAnims = registeredAnimations.length;
       var animations = [];
-
       for (i = 0; i < lenAnims; i += 1) {
         animations.push(registeredAnimations[i].animation);
       }
-
       return animations;
     }
-
     function addPlayingCount() {
       playingAnimationsNum += 1;
       activate();
     }
-
     function subtractPlayingCount() {
       playingAnimationsNum -= 1;
     }
-
     function setupAnimation(animItem, element) {
       animItem.addEventListener('destroy', removeElement);
       animItem.addEventListener('_active', addPlayingCount);
@@ -2613,118 +2181,91 @@
       });
       len += 1;
     }
-
     function loadAnimation(params) {
       var animItem = new AnimationItem();
       setupAnimation(animItem, null);
       animItem.setParams(params);
       return animItem;
     }
-
     function setSpeed(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setSpeed(val, animation);
       }
     }
-
     function setDirection(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setDirection(val, animation);
       }
     }
-
     function play(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.play(animation);
       }
     }
-
     function resume(nowTime) {
       var elapsedTime = nowTime - initTime;
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.advanceTime(elapsedTime);
       }
-
       initTime = nowTime;
-
       if (playingAnimationsNum && !_isFrozen) {
         window.requestAnimationFrame(resume);
       } else {
         _stopped = true;
       }
     }
-
     function first(nowTime) {
       initTime = nowTime;
       window.requestAnimationFrame(resume);
     }
-
     function pause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.pause(animation);
       }
     }
-
     function goToAndStop(value, isFrame, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
       }
     }
-
     function stop(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.stop(animation);
       }
     }
-
     function togglePause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.togglePause(animation);
       }
     }
-
     function destroy(animation) {
       var i;
-
       for (i = len - 1; i >= 0; i -= 1) {
         registeredAnimations[i].animation.destroy(animation);
       }
     }
-
     function searchAnimations(animationData, standalone, renderer) {
       var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')), [].slice.call(document.getElementsByClassName('bodymovin')));
       var i;
       var lenAnims = animElements.length;
-
       for (i = 0; i < lenAnims; i += 1) {
         if (renderer) {
           animElements[i].setAttribute('data-bm-type', renderer);
         }
-
         registerAnimation(animElements[i], animationData);
       }
-
       if (standalone && lenAnims === 0) {
         if (!renderer) {
           renderer = 'svg';
         }
-
         var body = document.getElementsByTagName('body')[0];
         body.innerText = '';
         var div = createTag('div');
@@ -2735,15 +2276,12 @@
         registerAnimation(div, animationData);
       }
     }
-
     function resize() {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.resize();
       }
     }
-
     function activate() {
       if (!_isFrozen && playingAnimationsNum) {
         if (_stopped) {
@@ -2752,40 +2290,31 @@
         }
       }
     }
-
     function freeze() {
       _isFrozen = true;
     }
-
     function unfreeze() {
       _isFrozen = false;
       activate();
     }
-
     function setVolume(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setVolume(val, animation);
       }
     }
-
     function mute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.mute(animation);
       }
     }
-
     function unmute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.unmute(animation);
       }
     }
-
     moduleOb.registerAnimation = registerAnimation;
     moduleOb.loadAnimation = loadAnimation;
     moduleOb.setSpeed = setSpeed;
@@ -2795,8 +2324,8 @@
     moduleOb.stop = stop;
     moduleOb.togglePause = togglePause;
     moduleOb.searchAnimations = searchAnimations;
-    moduleOb.resize = resize; // moduleOb.start = start;
-
+    moduleOb.resize = resize;
+    // moduleOb.start = start;
     moduleOb.goToAndStop = goToAndStop;
     moduleOb.destroy = destroy;
     moduleOb.freeze = freeze;
@@ -2820,23 +2349,21 @@
        * spline.get(x) => returns the easing value | x must be in [0, 1] range
        *
        */
+
     var ob = {};
     ob.getBezierEasing = getBezierEasing;
     var beziers = {};
-
     function getBezierEasing(a, b, c, d, nm) {
       var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
-
       if (beziers[str]) {
         return beziers[str];
       }
-
       var bezEasing = new BezierEasing([a, b, c, d]);
       beziers[str] = bezEasing;
       return bezEasing;
-    } // These values are established by empiricism with tests (tradeoff: performance VS precision)
+    }
 
-
+    // These values are established by empiricism with tests (tradeoff: performance VS precision)
     var NEWTON_ITERATIONS = 4;
     var NEWTON_MIN_SLOPE = 0.001;
     var SUBDIVISION_PRECISION = 0.0000001;
@@ -2844,48 +2371,40 @@
     var kSplineTableSize = 11;
     var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
     var float32ArraySupported = typeof Float32Array === 'function';
-
     function A(aA1, aA2) {
       return 1.0 - 3.0 * aA2 + 3.0 * aA1;
     }
-
     function B(aA1, aA2) {
       return 3.0 * aA2 - 6.0 * aA1;
     }
-
     function C(aA1) {
       return 3.0 * aA1;
-    } // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+    }
 
-
+    // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
     function calcBezier(aT, aA1, aA2) {
       return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
-    } // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+    }
 
-
+    // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
     function getSlope(aT, aA1, aA2) {
       return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
     }
-
     function binarySubdivide(aX, aA, aB, mX1, mX2) {
       var currentX,
-          currentT,
-          i = 0;
-
+        currentT,
+        i = 0;
       do {
         currentT = aA + (aB - aA) / 2.0;
         currentX = calcBezier(currentT, mX1, mX2) - aX;
-
         if (currentX > 0.0) {
           aB = currentT;
         } else {
           aA = currentT;
         }
       } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
-
       return currentT;
     }
-
     function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
       for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
         var currentSlope = getSlope(aGuessT, mX1, mX2);
@@ -2893,85 +2412,75 @@
         var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
         aGuessT -= currentX / currentSlope;
       }
-
       return aGuessT;
     }
+
     /**
        * points is an array of [ mX1, mY1, mX2, mY2 ]
        */
-
-
     function BezierEasing(points) {
       this._p = points;
       this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
       this._precomputed = false;
       this.get = this.get.bind(this);
     }
-
     BezierEasing.prototype = {
       get: function get(x) {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         if (!this._precomputed) this._precompute();
         if (mX1 === mY1 && mX2 === mY2) return x; // linear
         // Because JavaScript number are imprecise, we should guarantee the extremes are right.
-
         if (x === 0) return 0;
         if (x === 1) return 1;
         return calcBezier(this._getTForX(x), mY1, mY2);
       },
       // Private part
+
       _precompute: function _precompute() {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         this._precomputed = true;
-
         if (mX1 !== mY1 || mX2 !== mY2) {
           this._calcSampleValues();
         }
       },
       _calcSampleValues: function _calcSampleValues() {
         var mX1 = this._p[0],
-            mX2 = this._p[2];
-
+          mX2 = this._p[2];
         for (var i = 0; i < kSplineTableSize; ++i) {
           this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
         }
       },
-
       /**
            * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
            */
       _getTForX: function _getTForX(aX) {
         var mX1 = this._p[0],
-            mX2 = this._p[2],
-            mSampleValues = this._mSampleValues;
+          mX2 = this._p[2],
+          mSampleValues = this._mSampleValues;
         var intervalStart = 0.0;
         var currentSample = 1;
         var lastSample = kSplineTableSize - 1;
-
         for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
           intervalStart += kSampleStepSize;
         }
+        --currentSample;
 
-        --currentSample; // Interpolate to provide an initial guess for t
-
+        // Interpolate to provide an initial guess for t
         var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
         var guessForT = intervalStart + dist * kSampleStepSize;
         var initialSlope = getSlope(guessForT, mX1, mX2);
-
         if (initialSlope >= NEWTON_MIN_SLOPE) {
           return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
         }
-
         if (initialSlope === 0.0) {
           return guessForT;
         }
-
         return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
       }
     };
@@ -2982,7 +2491,6 @@
     function _double(arr) {
       return arr.concat(createSizedArray(arr.length));
     }
-
     return {
       "double": _double
     };
@@ -2997,34 +2505,27 @@
         newElement: newElement,
         release: release
       };
-
       function newElement() {
         var element;
-
         if (_length) {
           _length -= 1;
           element = pool[_length];
         } else {
           element = _create();
         }
-
         return element;
       }
-
       function release(element) {
         if (_length === _maxLength) {
           pool = pooling["double"](pool);
           _maxLength *= 2;
         }
-
         if (_release) {
           _release(element);
         }
-
         pool[_length] = element;
         _length += 1;
       }
-
       return ob;
     };
   }();
@@ -3037,7 +2538,6 @@
         lengths: createTypedArray('float32', getDefaultCurveSegments())
       };
     }
-
     return poolFactory(8, create);
   }();
 
@@ -3048,39 +2548,31 @@
         totalLength: 0
       };
     }
-
     function release(element) {
       var i;
       var len = element.lengths.length;
-
       for (i = 0; i < len; i += 1) {
         bezierLengthPool.release(element.lengths[i]);
       }
-
       element.lengths.length = 0;
     }
-
     return poolFactory(8, create, release);
   }();
 
   function bezFunction() {
     var math = Math;
-
     function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
       var det1 = x1 * y2 + y1 * x3 + x2 * y3 - x3 * y2 - y3 * x1 - x2 * y1;
       return det1 > -0.001 && det1 < 0.001;
     }
-
     function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
       if (z1 === 0 && z2 === 0 && z3 === 0) {
         return pointOnLine2D(x1, y1, x2, y2, x3, y3);
       }
-
       var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
       var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
       var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
       var diffDist;
-
       if (dist1 > dist2) {
         if (dist1 > dist3) {
           diffDist = dist1 - dist2 - dist3;
@@ -3092,10 +2584,8 @@
       } else {
         diffDist = dist2 - dist1 - dist3;
       }
-
       return diffDist > -0.0001 && diffDist < 0.0001;
     }
-
     var getBezierLength = function () {
       return function (pt1, pt2, pt3, pt4) {
         var curveSegments = getDefaultCurveSegments();
@@ -3110,36 +2600,28 @@
         var lastPoint = [];
         var lengthData = bezierLengthPool.newElement();
         len = pt3.length;
-
         for (k = 0; k < curveSegments; k += 1) {
           perc = k / (curveSegments - 1);
           ptDistance = 0;
-
           for (i = 0; i < len; i += 1) {
             ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
             point[i] = ptCoord;
-
             if (lastPoint[i] !== null) {
               ptDistance += bmPow(point[i] - lastPoint[i], 2);
             }
-
             lastPoint[i] = point[i];
           }
-
           if (ptDistance) {
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
           }
-
           lengthData.percents[k] = perc;
           lengthData.lengths[k] = addedLength;
         }
-
         lengthData.addedLength = addedLength;
         return lengthData;
       };
     }();
-
     function getSegmentsLength(shapeData) {
       var segmentsLength = segmentsLengthPool.newElement();
       var closed = shapeData.c;
@@ -3150,36 +2632,29 @@
       var len = shapeData._length;
       var lengths = segmentsLength.lengths;
       var totalLength = 0;
-
       for (i = 0; i < len - 1; i += 1) {
         lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
         totalLength += lengths[i].addedLength;
       }
-
       if (closed && len) {
         lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
         totalLength += lengths[i].addedLength;
       }
-
       segmentsLength.totalLength = totalLength;
       return segmentsLength;
     }
-
     function BezierData(length) {
       this.segmentLength = 0;
       this.points = new Array(length);
     }
-
     function PointData(partial, point) {
       this.partialLength = partial;
       this.point = point;
     }
-
     var buildBezierData = function () {
       var storedData = {};
       return function (pt1, pt2, pt3, pt4) {
         var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
-
         if (!storedData[bezierName]) {
           var curveSegments = getDefaultCurveSegments();
           var k;
@@ -3191,42 +2666,33 @@
           var ptDistance;
           var point;
           var lastPoint = null;
-
           if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
             curveSegments = 2;
           }
-
           var bezierData = new BezierData(curveSegments);
           len = pt3.length;
-
           for (k = 0; k < curveSegments; k += 1) {
             point = createSizedArray(len);
             perc = k / (curveSegments - 1);
             ptDistance = 0;
-
             for (i = 0; i < len; i += 1) {
               ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
               point[i] = ptCoord;
-
               if (lastPoint !== null) {
                 ptDistance += bmPow(point[i] - lastPoint[i], 2);
               }
             }
-
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
             bezierData.points[k] = new PointData(ptDistance, point);
             lastPoint = point;
           }
-
           bezierData.segmentLength = addedLength;
           storedData[bezierName] = bezierData;
         }
-
         return storedData[bezierName];
       };
     }();
-
     function getDistancePerc(perc, bezierData) {
       var percents = bezierData.percents;
       var lengths = bezierData.lengths;
@@ -3234,14 +2700,11 @@
       var initPos = bmFloor((len - 1) * perc);
       var lengthPos = perc * bezierData.addedLength;
       var lPerc = 0;
-
       if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
         return percents[initPos];
       }
-
       var dir = lengths[initPos] > lengthPos ? -1 : 1;
       var flag = true;
-
       while (flag) {
         if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
           lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
@@ -3249,20 +2712,16 @@
         } else {
           initPos += dir;
         }
-
         if (initPos < 0 || initPos >= len - 1) {
           // FIX for TypedArrays that don't store floating point values with enough accuracy
           if (initPos === len - 1) {
             return percents[initPos];
           }
-
           flag = false;
         }
       }
-
       return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
     }
-
     function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
       var t1 = getDistancePerc(percent, bezierData);
       var u1 = 1 - t1;
@@ -3270,16 +2729,13 @@
       var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
       return [ptX, ptY];
     }
-
     var bezierSegmentPoints = createTypedArray('float32', 8);
-
     function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
       if (startPerc < 0) {
         startPerc = 0;
       } else if (startPerc > 1) {
         startPerc = 1;
       }
-
       var t0 = getDistancePerc(startPerc, bezierData);
       endPerc = endPerc > 1 ? 1 : endPerc;
       var t1 = getDistancePerc(endPerc, bezierData);
@@ -3289,45 +2745,31 @@
       var u1 = 1 - t1;
       var u0u0u0 = u0 * u0 * u0;
       var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
-
       var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
-
-      var t0t0t0 = t0 * t0 * t0; //
-
+      var t0t0t0 = t0 * t0 * t0;
+      //
       var u0u0u1 = u0 * u0 * u1;
       var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
-
       var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
-
-      var t0t0t1 = t0 * t0 * t1; //
-
+      var t0t0t1 = t0 * t0 * t1;
+      //
       var u0u1u1 = u0 * u1 * u1;
       var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
-
       var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
-
-      var t0t1t1 = t0 * t1 * t1; //
-
+      var t0t1t1 = t0 * t1 * t1;
+      //
       var u1u1u1 = u1 * u1 * u1;
       var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1t1 = t1 * t1 * t1;
-
       for (i = 0; i < len; i += 1) {
         bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
       }
-
       return bezierSegmentPoints;
     }
-
     return {
       getSegmentsLength: getSegmentsLength,
       getNewSegment: getNewSegment,
@@ -3337,20 +2779,16 @@
       pointOnLine3D: pointOnLine3D
     };
   }
-
   var bez = bezFunction();
 
   var initFrame = initialDefaultFrame;
   var mathAbs = Math.abs;
-
   function interpolateValue(frameNum, caching) {
     var offsetTime = this.offsetTime;
     var newValue;
-
     if (this.propType === 'multidimensional') {
       newValue = createTypedArray('float32', this.pv.length);
     }
-
     var iterationIndex = caching.lastIndex;
     var i = iterationIndex;
     var len = this.keyframes.length - 1;
@@ -3358,25 +2796,20 @@
     var keyData;
     var nextKeyData;
     var keyframeMetadata;
-
     while (flag) {
       keyData = this.keyframes[i];
       nextKeyData = this.keyframes[i + 1];
-
       if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
         if (keyData.h) {
           keyData = nextKeyData;
         }
-
         iterationIndex = 0;
         break;
       }
-
       if (nextKeyData.t - offsetTime > frameNum) {
         iterationIndex = i;
         break;
       }
-
       if (i < len - 1) {
         i += 1;
       } else {
@@ -3384,7 +2817,6 @@
         flag = false;
       }
     }
-
     keyframeMetadata = this.keyframesMetadata[i] || {};
     var k;
     var kLen;
@@ -3395,22 +2827,18 @@
     var nextKeyTime = nextKeyData.t - offsetTime;
     var keyTime = keyData.t - offsetTime;
     var endValue;
-
     if (keyData.to) {
       if (!keyframeMetadata.bezierData) {
         keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
       }
-
       var bezierData = keyframeMetadata.bezierData;
-
       if (frameNum >= nextKeyTime || frameNum < keyTime) {
         var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
         kLen = bezierData.points[ind].point.length;
-
         for (k = 0; k < kLen; k += 1) {
           newValue[k] = bezierData.points[ind].point[k];
-        } // caching._lastKeyframeIndex = -1;
-
+        }
+        // caching._lastKeyframeIndex = -1;
       } else {
         if (keyframeMetadata.__fnct) {
           fnc = keyframeMetadata.__fnct;
@@ -3418,7 +2846,6 @@
           fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
           keyframeMetadata.__fnct = fnc;
         }
-
         perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
         var distanceInLine = bezierData.segmentLength * perc;
         var segmentPerc;
@@ -3426,36 +2853,28 @@
         j = caching.lastFrame < frameNum && caching._lastKeyframeIndex === i ? caching._lastPoint : 0;
         flag = true;
         jLen = bezierData.points.length;
-
         while (flag) {
           addedLength += bezierData.points[j].partialLength;
-
           if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k];
             }
-
             break;
           } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
             segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
             }
-
             break;
           }
-
           if (j < jLen - 1) {
             j += 1;
           } else {
             flag = false;
           }
         }
-
         caching._lastPoint = j;
         caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
         caching._lastKeyframeIndex = i;
@@ -3468,7 +2887,6 @@
       var keyValue;
       len = keyData.s.length;
       endValue = nextKeyData.s || keyData.e;
-
       if (this.sh && keyData.h !== 1) {
         if (frameNum >= nextKeyTime) {
           newValue[0] = endValue[0];
@@ -3496,7 +2914,6 @@
                 if (!keyframeMetadata.__fnct) {
                   keyframeMetadata.__fnct = [];
                 }
-
                 if (!keyframeMetadata.__fnct[i]) {
                   outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
                   outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
@@ -3517,14 +2934,11 @@
               } else {
                 fnc = keyframeMetadata.__fnct;
               }
-
               perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
             }
           }
-
           endValue = nextKeyData.s || keyData.e;
           keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
-
           if (this.propType === 'multidimensional') {
             newValue[i] = keyValue;
           } else {
@@ -3533,12 +2947,11 @@
         }
       }
     }
-
     caching.lastIndex = iterationIndex;
     return newValue;
-  } // based on @Toji's https://github.com/toji/gl-matrix/
+  }
 
-
+  // based on @Toji's https://github.com/toji/gl-matrix/
   function slerp(a, b, t) {
     var out = [];
     var ax = a[0];
@@ -3555,7 +2968,6 @@
     var scale0;
     var scale1;
     cosom = ax * bx + ay * by + az * bz + aw * bw;
-
     if (cosom < 0.0) {
       cosom = -cosom;
       bx = -bx;
@@ -3563,7 +2975,6 @@
       bz = -bz;
       bw = -bw;
     }
-
     if (1.0 - cosom > 0.000001) {
       omega = Math.acos(cosom);
       sinom = Math.sin(omega);
@@ -3573,14 +2984,12 @@
       scale0 = 1.0 - t;
       scale1 = t;
     }
-
     out[0] = scale0 * ax + scale1 * bx;
     out[1] = scale0 * ay + scale1 * by;
     out[2] = scale0 * az + scale1 * bz;
     out[3] = scale0 * aw + scale1 * bw;
     return out;
   }
-
   function quaternionToEuler(out, quat) {
     var qx = quat[0];
     var qy = quat[1];
@@ -3593,7 +3002,6 @@
     out[1] = attitude / degToRads;
     out[2] = bank / degToRads;
   }
-
   function createQuaternion(values) {
     var heading = values[0] * degToRads;
     var attitude = values[1] * degToRads;
@@ -3610,32 +3018,25 @@
     var z = c1 * s2 * c3 - s1 * c2 * s3;
     return [x, y, z, w];
   }
-
   function getValueAtCurrentTime() {
     var frameNum = this.comp.renderedFrame - this.offsetTime;
     var initTime = this.keyframes[0].t - this.offsetTime;
     var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
-
     if (!(frameNum === this._caching.lastFrame || this._caching.lastFrame !== initFrame && (this._caching.lastFrame >= endTime && frameNum >= endTime || this._caching.lastFrame < initTime && frameNum < initTime))) {
       if (this._caching.lastFrame >= frameNum) {
         this._caching._lastKeyframeIndex = -1;
         this._caching.lastIndex = 0;
       }
-
       var renderResult = this.interpolateValue(frameNum, this._caching);
       this.pv = renderResult;
     }
-
     this._caching.lastFrame = frameNum;
     return this.pv;
   }
-
   function setVValue(val) {
     var multipliedValue;
-
     if (this.propType === 'unidimensional') {
       multipliedValue = val * this.mult;
-
       if (mathAbs(this.v - multipliedValue) > 0.00001) {
         this.v = multipliedValue;
         this._mdf = true;
@@ -3643,51 +3044,41 @@
     } else {
       var i = 0;
       var len = this.v.length;
-
       while (i < len) {
         multipliedValue = val[i] * this.mult;
-
         if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
           this.v[i] = multipliedValue;
           this._mdf = true;
         }
-
         i += 1;
       }
     }
   }
-
   function processEffectsSequence() {
     if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
       return;
     }
-
     if (this.lock) {
       this.setVValue(this.pv);
       return;
     }
-
     this.lock = true;
     this._mdf = this._isFirstFrame;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = this.kf ? this.pv : this.data.k;
-
     for (i = 0; i < len; i += 1) {
       finalValue = this.effectsSequence[i](finalValue);
     }
-
     this.setVValue(finalValue);
     this._isFirstFrame = false;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   }
-
   function addEffect(effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.container.addDynamicProperty(this);
   }
-
   function ValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.mult = mult || 1;
@@ -3707,7 +3098,6 @@
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function MultiDimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     this.mult = mult || 1;
@@ -3724,19 +3114,16 @@
     this.v = createTypedArray('float32', len);
     this.pv = createTypedArray('float32', len);
     this.vel = createTypedArray('float32', len);
-
     for (i = 0; i < len; i += 1) {
       this.v[i] = data.k[i] * this.mult;
       this.pv[i] = data.k[i];
     }
-
     this._isFirstFrame = true;
     this.effectsSequence = [];
     this.getValue = processEffectsSequence;
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function KeyframedValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.keyframes = data.k;
@@ -3765,7 +3152,6 @@
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.addEffect = addEffect;
   }
-
   function KeyframedMultidimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     var i;
@@ -3774,19 +3160,16 @@
     var e;
     var to;
     var ti;
-
     for (i = 0; i < len - 1; i += 1) {
       if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
         s = data.k[i].s;
         e = data.k[i + 1].s;
         to = data.k[i].to;
         ti = data.k[i].ti;
-
         if (s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1]) || s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2])) {
           data.k[i].to = null;
           data.k[i].ti = null;
         }
-
         if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
           if (s.length === 2 || s[2] === e[2] && to[2] === 0 && ti[2] === 0) {
             data.k[i].to = null;
@@ -3795,7 +3178,6 @@
         }
       }
     }
-
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.data = data;
     this.keyframes = data.k;
@@ -3815,12 +3197,10 @@
     var arrLen = data.k[0].s.length;
     this.v = createTypedArray('float32', arrLen);
     this.pv = createTypedArray('float32', arrLen);
-
     for (i = 0; i < arrLen; i += 1) {
       this.v[i] = initFrame;
       this.pv[i] = initFrame;
     }
-
     this._caching = {
       lastFrame: initFrame,
       lastIndex: 0,
@@ -3828,15 +3208,12 @@
     };
     this.addEffect = addEffect;
   }
-
   var PropertyFactory = function () {
     function getProp(elem, data, type, mult, container) {
       if (data.sid) {
         data = elem.globalData.slotManager.getProp(data);
       }
-
       var p;
-
       if (!data.k.length) {
         p = new ValueProperty(elem, data, mult, container);
       } else if (typeof data.k[0] === 'number') {
@@ -3846,23 +3223,18 @@
           case 0:
             p = new KeyframedValueProperty(elem, data, mult, container);
             break;
-
           case 1:
             p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
             break;
-
           default:
             break;
         }
       }
-
       if (p.effectsSequence.length) {
         container.addDynamicProperty(p);
       }
-
       return p;
     }
-
     var ob = {
       getProp: getProp
     };
@@ -3870,7 +3242,6 @@
   }();
 
   function DynamicPropertyContainer() {}
-
   DynamicPropertyContainer.prototype = {
     addDynamicProperty: function addDynamicProperty(prop) {
       if (this.dynamicProperties.indexOf(prop) === -1) {
@@ -3883,10 +3254,8 @@
       this._mdf = false;
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         this.dynamicProperties[i].getValue();
-
         if (this.dynamicProperties[i]._mdf) {
           this._mdf = true;
         }
@@ -3904,7 +3273,6 @@
     function create() {
       return createTypedArray('float32', 2);
     }
-
     return poolFactory(8, create);
   }();
 
@@ -3916,12 +3284,10 @@
     this.o = createSizedArray(this._maxLength);
     this.i = createSizedArray(this._maxLength);
   }
-
   ShapePath.prototype.setPathData = function (closed, len) {
     this.c = closed;
     this.setLength(len);
     var i = 0;
-
     while (i < len) {
       this.v[i] = pointPool.newElement();
       this.o[i] = pointPool.newElement();
@@ -3929,62 +3295,49 @@
       i += 1;
     }
   };
-
   ShapePath.prototype.setLength = function (len) {
     while (this._maxLength < len) {
       this.doubleArrayLength();
     }
-
     this._length = len;
   };
-
   ShapePath.prototype.doubleArrayLength = function () {
     this.v = this.v.concat(createSizedArray(this._maxLength));
     this.i = this.i.concat(createSizedArray(this._maxLength));
     this.o = this.o.concat(createSizedArray(this._maxLength));
     this._maxLength *= 2;
   };
-
   ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
     var arr;
     this._length = Math.max(this._length, pos + 1);
-
     if (this._length >= this._maxLength) {
       this.doubleArrayLength();
     }
-
     switch (type) {
       case 'v':
         arr = this.v;
         break;
-
       case 'i':
         arr = this.i;
         break;
-
       case 'o':
         arr = this.o;
         break;
-
       default:
         arr = [];
         break;
     }
-
     if (!arr[pos] || arr[pos] && !replace) {
       arr[pos] = pointPool.newElement();
     }
-
     arr[pos][0] = x;
     arr[pos][1] = y;
   };
-
   ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
     this.setXYAt(vX, vY, 'v', pos, replace);
     this.setXYAt(oX, oY, 'o', pos, replace);
     this.setXYAt(iX, iY, 'i', pos, replace);
   };
-
   ShapePath.prototype.reverse = function () {
     var newPath = new ShapePath();
     newPath.setPathData(this.c, this._length);
@@ -3992,24 +3345,19 @@
     var outPoints = this.o;
     var inPoints = this.i;
     var init = 0;
-
     if (this.c) {
       newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
       init = 1;
     }
-
     var cnt = this._length - 1;
     var len = this._length;
     var i;
-
     for (i = init; i < len; i += 1) {
       newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
       cnt -= 1;
     }
-
     return newPath;
   };
-
   ShapePath.prototype.length = function () {
     return this._length;
   };
@@ -4018,11 +3366,9 @@
     function create() {
       return new ShapePath();
     }
-
     function release(shapePath) {
       var len = shapePath._length;
       var i;
-
       for (i = 0; i < len; i += 1) {
         pointPool.release(shapePath.v[i]);
         pointPool.release(shapePath.i[i]);
@@ -4031,25 +3377,20 @@
         shapePath.i[i] = null;
         shapePath.o[i] = null;
       }
-
       shapePath._length = 0;
       shapePath.c = false;
     }
-
     function clone(shape) {
       var cloned = factory.newElement();
       var i;
       var len = shape._length === undefined ? shape.v.length : shape._length;
       cloned.setLength(len);
       cloned.c = shape.c;
-
       for (i = 0; i < len; i += 1) {
         cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
       }
-
       return cloned;
     }
-
     var factory = poolFactory(4, create, release);
     factory.clone = clone;
     return factory;
@@ -4060,24 +3401,19 @@
     this._maxLength = 4;
     this.shapes = createSizedArray(this._maxLength);
   }
-
   ShapeCollection.prototype.addShape = function (shapeData) {
     if (this._length === this._maxLength) {
       this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
       this._maxLength *= 2;
     }
-
     this.shapes[this._length] = shapeData;
     this._length += 1;
   };
-
   ShapeCollection.prototype.releaseShapes = function () {
     var i;
-
     for (i = 0; i < this._length; i += 1) {
       shapePool.release(this.shapes[i]);
     }
-
     this._length = 0;
   };
 
@@ -4089,45 +3425,35 @@
     var _length = 0;
     var _maxLength = 4;
     var pool = createSizedArray(_maxLength);
-
     function newShapeCollection() {
       var shapeCollection;
-
       if (_length) {
         _length -= 1;
         shapeCollection = pool[_length];
       } else {
         shapeCollection = new ShapeCollection();
       }
-
       return shapeCollection;
     }
-
     function release(shapeCollection) {
       var i;
       var len = shapeCollection._length;
-
       for (i = 0; i < len; i += 1) {
         shapePool.release(shapeCollection.shapes[i]);
       }
-
       shapeCollection._length = 0;
-
       if (_length === _maxLength) {
         pool = pooling["double"](pool);
         _maxLength *= 2;
       }
-
       pool[_length] = shapeCollection;
       _length += 1;
     }
-
     return ob;
   }();
 
   var ShapePropertyFactory = function () {
     var initFrame = -999999;
-
     function interpolateShape(frameNum, previousValue, caching) {
       var iterationIndex = caching.lastIndex;
       var keyPropS;
@@ -4140,7 +3466,6 @@
       var perc;
       var vertexValue;
       var kf = this.keyframes;
-
       if (frameNum < kf[0].t - this.offsetTime) {
         keyPropS = kf[0].s[0];
         isHold = true;
@@ -4152,7 +3477,6 @@
               }else{
                   keyPropS = kf[kf.length - 2].e[0];
               } */
-
         isHold = true;
       } else {
         var i = iterationIndex;
@@ -4161,26 +3485,21 @@
         var keyData;
         var nextKeyData;
         var keyframeMetadata;
-
         while (flag) {
           keyData = kf[i];
           nextKeyData = kf[i + 1];
-
           if (nextKeyData.t - this.offsetTime > frameNum) {
             break;
           }
-
           if (i < len - 1) {
             i += 1;
           } else {
             flag = false;
           }
         }
-
         keyframeMetadata = this.keyframesMetadata[i] || {};
         isHold = keyData.h === 1;
         iterationIndex = i;
-
         if (!isHold) {
           if (frameNum >= nextKeyData.t - this.offsetTime) {
             perc = 1;
@@ -4188,27 +3507,21 @@
             perc = 0;
           } else {
             var fnc;
-
             if (keyframeMetadata.__fnct) {
               fnc = keyframeMetadata.__fnct;
             } else {
               fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
               keyframeMetadata.__fnct = fnc;
             }
-
             perc = fnc((frameNum - (keyData.t - this.offsetTime)) / (nextKeyData.t - this.offsetTime - (keyData.t - this.offsetTime)));
           }
-
           keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
         }
-
         keyPropS = keyData.s[0];
       }
-
       jLen = previousValue._length;
       kLen = keyPropS.i[0].length;
       caching.lastIndex = iterationIndex;
-
       for (j = 0; j < jLen; j += 1) {
         for (k = 0; k < kLen; k += 1) {
           vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
@@ -4220,44 +3533,36 @@
         }
       }
     }
-
     function interpolateShapeCurrentTime() {
       var frameNum = this.comp.renderedFrame - this.offsetTime;
       var initTime = this.keyframes[0].t - this.offsetTime;
       var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
       var lastFrame = this._caching.lastFrame;
-
       if (!(lastFrame !== initFrame && (lastFrame < initTime && frameNum < initTime || lastFrame > endTime && frameNum > endTime))) {
         /// /
         this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
-        this.interpolateShape(frameNum, this.pv, this._caching); /// /
+        this.interpolateShape(frameNum, this.pv, this._caching);
+        /// /
       }
-
       this._caching.lastFrame = frameNum;
       return this.pv;
     }
-
     function resetShape() {
       this.paths = this.localShapeCollection;
     }
-
     function shapesEqual(shape1, shape2) {
       if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
         return false;
       }
-
       var i;
       var len = shape1._length;
-
       for (i = 0; i < len; i += 1) {
         if (shape1.v[i][0] !== shape2.v[i][0] || shape1.v[i][1] !== shape2.v[i][1] || shape1.o[i][0] !== shape2.o[i][0] || shape1.o[i][1] !== shape2.o[i][1] || shape1.i[i][0] !== shape2.i[i][0] || shape1.i[i][1] !== shape2.i[i][1]) {
           return false;
         }
       }
-
       return true;
     }
-
     function setVValue(newPath) {
       if (!shapesEqual(this.v, newPath)) {
         this.v = shapePool.clone(newPath);
@@ -4267,26 +3572,21 @@
         this.paths = this.localShapeCollection;
       }
     }
-
     function processEffectsSequence() {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (!this.effectsSequence.length) {
         this._mdf = false;
         return;
       }
-
       if (this.lock) {
         this.setVValue(this.pv);
         return;
       }
-
       this.lock = true;
       this._mdf = false;
       var finalValue;
-
       if (this.kf) {
         finalValue = this.pv;
       } else if (this.data.ks) {
@@ -4294,19 +3594,15 @@
       } else {
         finalValue = this.data.pt.k;
       }
-
       var i;
       var len = this.effectsSequence.length;
-
       for (i = 0; i < len; i += 1) {
         finalValue = this.effectsSequence[i](finalValue);
       }
-
       this.setVValue(finalValue);
       this.lock = false;
       this.frameId = this.elem.globalData.frameId;
     }
-
     function ShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4325,17 +3621,14 @@
       this.reset = resetShape;
       this.effectsSequence = [];
     }
-
     function addEffect(effectFunction) {
       this.effectsSequence.push(effectFunction);
       this.container.addDynamicProperty(this);
     }
-
     ShapeProperty.prototype.interpolateShape = interpolateShape;
     ShapeProperty.prototype.getValue = processEffectsSequence;
     ShapeProperty.prototype.setVValue = setVValue;
     ShapeProperty.prototype.addEffect = addEffect;
-
     function KeyframedShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4361,15 +3654,12 @@
       };
       this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
     }
-
     KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
     KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
     KeyframedShapeProperty.prototype.setVValue = setVValue;
     KeyframedShapeProperty.prototype.addEffect = addEffect;
-
     var EllShapeProperty = function () {
       var cPoint = roundCorner;
-
       function EllShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
         this.v.setPathData(true, 4);
@@ -4383,7 +3673,6 @@
         this.initDynamicPropertyContainer(elem);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4391,17 +3680,14 @@
           this.convertEllToPath();
         }
       }
-
       EllShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertEllToPath();
           }
@@ -4411,9 +3697,7 @@
           var p1 = this.p.v[1];
           var s0 = this.s.v[0] / 2;
           var s1 = this.s.v[1] / 2;
-
           var _cw = this.d !== 3;
-
           var _v = this.v;
           _v.v[0][0] = p0;
           _v.v[0][1] = p1 - s1;
@@ -4444,7 +3728,6 @@
       extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
       return EllShapePropertyFactory;
     }();
-
     var StarShapeProperty = function () {
       function StarShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4455,7 +3738,6 @@
         this.frameId = -1;
         this.d = data.d;
         this.initDynamicPropertyContainer(elem);
-
         if (data.sy === 1) {
           this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
           this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
@@ -4463,7 +3745,6 @@
         } else {
           this.convertToPath = this.convertPolygonToPath;
         }
-
         this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
@@ -4472,7 +3753,6 @@
         this.localShapeCollection = shapeCollectionPool.newShapeCollection();
         this.localShapeCollection.addShape(this.v);
         this.paths = this.localShapeCollection;
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4480,17 +3760,14 @@
           this.convertToPath();
         }
       }
-
       StarShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertToPath();
           }
@@ -4501,7 +3778,6 @@
           /* this.v.v.length = numPts;
                   this.v.i.length = numPts;
                   this.v.o.length = numPts; */
-
           var longFlag = true;
           var longRad = this.or.v;
           var shortRad = this.ir.v;
@@ -4517,7 +3793,6 @@
           currentAng += this.r.v;
           var dir = this.data.d === 3 ? -1 : 1;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             rad = longFlag ? longRad : shortRad;
             roundness = longFlag ? longRound : shortRound;
@@ -4529,11 +3804,11 @@
             x += +this.p.v[0];
             y += +this.p.v[1];
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
             /* this.v.v[i] = [x,y];
                       this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
                       this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
                       this.v._length = numPts; */
-
             longFlag = !longFlag;
             currentAng += angle * dir;
           }
@@ -4549,7 +3824,6 @@
           var dir = this.data.d === 3 ? -1 : 1;
           currentAng += this.r.v;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             var x = rad * Math.cos(currentAng);
             var y = rad * Math.sin(currentAng);
@@ -4560,7 +3834,6 @@
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
             currentAng += angle * dir;
           }
-
           this.paths.length = 0;
           this.paths[0] = this.v;
         }
@@ -4568,7 +3841,6 @@
       extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
       return StarShapePropertyFactory;
     }();
-
     var RectShapeProperty = function () {
       function RectShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4584,7 +3856,6 @@
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4592,7 +3863,6 @@
           this.convertRectToPath();
         }
       }
-
       RectShapePropertyFactory.prototype = {
         convertRectToPath: function convertRectToPath() {
           var p0 = this.p.v[0];
@@ -4602,11 +3872,9 @@
           var round = bmMin(v0, v1, this.r.v);
           var cPoint = round * (1 - roundCorner);
           this.v._length = 0;
-
           if (this.d === 2 || this.d === 1) {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
             this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
               this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
@@ -4620,7 +3888,6 @@
             }
           } else {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
               this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
@@ -4640,10 +3907,8 @@
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertRectToPath();
           }
@@ -4653,14 +3918,11 @@
       extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
       return RectShapePropertyFactory;
     }();
-
     function getShapeProp(elem, data, type) {
       var prop;
-
       if (type === 3 || type === 4) {
         var dataProp = type === 3 ? data.pt : data.ks;
         var keys = dataProp.k;
-
         if (keys.length) {
           prop = new KeyframedShapeProperty(elem, data, type);
         } else {
@@ -4673,22 +3935,17 @@
       } else if (type === 7) {
         prop = new StarShapeProperty(elem, data);
       }
-
       if (prop.k) {
         elem.addDynamicProperty(prop);
       }
-
       return prop;
     }
-
     function getConstructorFunction() {
       return ShapeProperty;
     }
-
     function getKeyframedConstructorFunction() {
       return KeyframedShapeProperty;
     }
-
     var ob = {};
     ob.getShapeProp = getShapeProp;
     ob.getConstructorFunction = getConstructorFunction;
@@ -4730,7 +3987,6 @@
     var _sin = Math.sin;
     var _tan = Math.tan;
     var _rnd = Math.round;
-
     function reset() {
       this.props[0] = 1;
       this.props[1] = 0;
@@ -4750,83 +4006,59 @@
       this.props[15] = 1;
       return this;
     }
-
     function rotate(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function rotateX(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateY(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateZ(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function shear(sx, sy) {
       return this._t(1, sy, sx, 1, 0, 0);
     }
-
     function skew(ax, ay) {
       return this.shear(_tan(ax), _tan(ay));
     }
-
     function skewFromAxis(ax, angle) {
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
-      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+      // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
     }
-
     function scale(sx, sy, sz) {
       if (!sz && sz !== 0) {
         sz = 1;
       }
-
       if (sx === 1 && sy === 1 && sz === 1) {
         return this;
       }
-
       return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
     }
-
     function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
       this.props[0] = a;
       this.props[1] = b;
@@ -4846,32 +4078,26 @@
       this.props[15] = p;
       return this;
     }
-
     function translate(tx, ty, tz) {
       tz = tz || 0;
-
       if (tx !== 0 || ty !== 0 || tz !== 0) {
         return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
       }
-
       return this;
     }
-
     function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
       var _p = this.props;
-
       if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
         // NOTE: commenting this condition because TurboFan deoptimizes code when present
         // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
         _p[12] = _p[12] * a2 + _p[15] * m2;
         _p[13] = _p[13] * f2 + _p[15] * n2;
         _p[14] = _p[14] * k2 + _p[15] * o2;
-        _p[15] *= p2; // }
-
+        _p[15] *= p2;
+        // }
         this._identityCalculated = false;
         return this;
       }
-
       var a1 = _p[0];
       var b1 = _p[1];
       var c1 = _p[2];
@@ -4888,12 +4114,12 @@
       var n1 = _p[13];
       var o1 = _p[14];
       var p1 = _p[15];
+
       /* matrix order (canvas compatible):
            * ace
            * bdf
            * 001
            */
-
       _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
       _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
       _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
@@ -4913,53 +4139,40 @@
       this._identityCalculated = false;
       return this;
     }
-
     function multiply(matrix) {
       var matrixProps = matrix.props;
       return this.transform(matrixProps[0], matrixProps[1], matrixProps[2], matrixProps[3], matrixProps[4], matrixProps[5], matrixProps[6], matrixProps[7], matrixProps[8], matrixProps[9], matrixProps[10], matrixProps[11], matrixProps[12], matrixProps[13], matrixProps[14], matrixProps[15]);
     }
-
     function isIdentity() {
       if (!this._identityCalculated) {
         this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
         this._identityCalculated = true;
       }
-
       return this._identity;
     }
-
     function equals(matr) {
       var i = 0;
-
       while (i < 16) {
         if (matr.props[i] !== this.props[i]) {
           return false;
         }
-
         i += 1;
       }
-
       return true;
     }
-
     function clone(matr) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         matr.props[i] = this.props[i];
       }
-
       return matr;
     }
-
     function cloneFromProps(props) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         this.props[i] = props[i];
       }
     }
-
     function applyToPoint(x, y, z) {
       return {
         x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
@@ -4971,19 +4184,15 @@
            y: x * me.b + y * me.d + me.f
            }; */
     }
-
     function applyToX(x, y, z) {
       return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
     }
-
     function applyToY(x, y, z) {
       return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
     }
-
     function applyToZ(x, y, z) {
       return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
     }
-
     function getInverseMatrix() {
       var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
       var a = this.props[5] / determinant;
@@ -5001,27 +4210,21 @@
       inverseMatrix.props[13] = f;
       return inverseMatrix;
     }
-
     function inversePoint(pt) {
       var inverseMatrix = this.getInverseMatrix();
       return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
     }
-
     function inversePoints(pts) {
       var i;
       var len = pts.length;
       var retPts = [];
-
       for (i = 0; i < len; i += 1) {
         retPts[i] = inversePoint(pts[i]);
       }
-
       return retPts;
     }
-
     function applyToTriplePoints(pt1, pt2, pt3) {
       var arr = createTypedArray('float32', 6);
-
       if (this.isIdentity()) {
         arr[0] = pt1[0];
         arr[1] = pt1[1];
@@ -5043,34 +4246,26 @@
         arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
         arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
       }
-
       return arr;
     }
-
     function applyToPointArray(x, y, z) {
       var arr;
-
       if (this.isIdentity()) {
         arr = [x, y, z];
       } else {
         arr = [x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12], x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13], x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14]];
       }
-
       return arr;
     }
-
     function applyToPointStringified(x, y) {
       if (this.isIdentity()) {
         return x + ',' + y;
       }
-
       var _p = this.props;
       return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
     }
-
     function toCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
@@ -5078,49 +4273,34 @@
       var props = this.props;
       var cssValue = 'matrix3d(';
       var v = 10000;
-
       while (i < 16) {
         cssValue += _rnd(props[i] * v) / v;
         cssValue += i === 15 ? ')' : ',';
         i += 1;
       }
-
       return cssValue;
     }
-
     function roundMatrixProperty(val) {
       var v = 10000;
-
       if (val < 0.000001 && val > 0 || val > -0.000001 && val < 0) {
         return _rnd(val * v) / v;
       }
-
       return val;
     }
-
     function to2dCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
       var props = this.props;
-
       var _a = roundMatrixProperty(props[0]);
-
       var _b = roundMatrixProperty(props[1]);
-
       var _c = roundMatrixProperty(props[4]);
-
       var _d = roundMatrixProperty(props[5]);
-
       var _e = roundMatrixProperty(props[12]);
-
       var _f = roundMatrixProperty(props[13]);
-
       return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
     }
-
     return function () {
       this.reset = reset;
       this.rotate = rotate;
@@ -5159,16 +4339,14 @@
     };
   }();
 
-  function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
   var lottie = {};
   var standalone = '__[STANDALONE]__';
   var animationData = '__[ANIMATIONDATA]__';
   var renderer = '';
-
   function setLocation(href) {
     setLocationHref(href);
   }
-
   function searchAnimations() {
     if (standalone === true) {
       animationManager.searchAnimations(animationData, standalone, renderer);
@@ -5176,35 +4354,28 @@
       animationManager.searchAnimations();
     }
   }
-
   function setSubframeRendering(flag) {
     setSubframeEnabled(flag);
   }
-
   function setPrefix(prefix) {
     setIdPrefix(prefix);
   }
-
   function loadAnimation(params) {
     if (standalone === true) {
       params.animationData = JSON.parse(animationData);
     }
-
     return animationManager.loadAnimation(params);
   }
-
   function setQuality(value) {
     if (typeof value === 'string') {
       switch (value) {
         case 'high':
           setDefaultCurveSegments(200);
           break;
-
         default:
         case 'medium':
           setDefaultCurveSegments(50);
           break;
-
         case 'low':
           setDefaultCurveSegments(10);
           break;
@@ -5212,40 +4383,32 @@
     } else if (!isNaN(value) && value > 1) {
       setDefaultCurveSegments(value);
     }
-
     if (getDefaultCurveSegments() >= 50) {
       roundValues(false);
     } else {
       roundValues(true);
     }
   }
-
   function inBrowser() {
     return typeof navigator !== 'undefined';
   }
-
   function installPlugin(type, plugin) {
     if (type === 'expressions') {
       setExpressionsPlugin(plugin);
     }
   }
-
   function getFactory(name) {
     switch (name) {
       case 'propertyFactory':
         return PropertyFactory;
-
       case 'shapePropertyFactory':
         return ShapePropertyFactory;
-
       case 'matrix':
         return Matrix;
-
       default:
         return null;
     }
   }
-
   lottie.play = animationManager.play;
   lottie.pause = animationManager.pause;
   lottie.setLocationHref = setLocation;
@@ -5257,8 +4420,8 @@
   lottie.registerAnimation = animationManager.registerAnimation;
   lottie.loadAnimation = loadAnimation;
   lottie.setSubframeRendering = setSubframeRendering;
-  lottie.resize = animationManager.resize; // lottie.start = start;
-
+  lottie.resize = animationManager.resize;
+  // lottie.start = start;
   lottie.goToAndStop = animationManager.goToAndStop;
   lottie.destroy = animationManager.destroy;
   lottie.setQuality = setQuality;
@@ -5273,32 +4436,25 @@
   lottie.useWebWorker = setWebWorker;
   lottie.setIDPrefix = setPrefix;
   lottie.__getFactory = getFactory;
-  lottie.version = '5.12.2';
-
+  lottie.version = '5.13.0';
   function checkReady() {
     if (document.readyState === 'complete') {
       clearInterval(readyStateCheckInterval);
       searchAnimations();
     }
   }
-
   function getQueryVariable(variable) {
     var vars = queryString.split('&');
-
     for (var i = 0; i < vars.length; i += 1) {
       var pair = vars[i].split('=');
-
       if (decodeURIComponent(pair[0]) == variable) {
         // eslint-disable-line eqeqeq
         return decodeURIComponent(pair[1]);
       }
     }
-
     return null;
   }
-
   var queryString = '';
-
   if (standalone) {
     var scripts = document.getElementsByTagName('script');
     var index = scripts.length - 1;
@@ -5306,18 +4462,18 @@
       src: ''
     };
     queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
-
     renderer = getQueryVariable('renderer');
   }
+  var readyStateCheckInterval = setInterval(checkReady, 100);
 
-  var readyStateCheckInterval = setInterval(checkReady, 100); // this adds bodymovin to the window object for backwards compatibility
-
+  // this adds bodymovin to the window object for backwards compatibility
   try {
     if (!((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === 'object' && typeof module !== 'undefined') && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
     ) {
       window.bodymovin = lottie;
     }
-  } catch (err) {//
+  } catch (err) {
+    //
   }
 
   var ShapeModifiers = function () {
@@ -5325,26 +4481,19 @@
     var modifiers = {};
     ob.registerModifier = registerModifier;
     ob.getModifier = getModifier;
-
     function registerModifier(nm, factory) {
       if (!modifiers[nm]) {
         modifiers[nm] = factory;
       }
     }
-
     function getModifier(nm, elem, data) {
       return new modifiers[nm](elem, data);
     }
-
     return ob;
   }();
-
   function ShapeModifier() {}
-
   ShapeModifier.prototype.initModifierProperties = function () {};
-
   ShapeModifier.prototype.addShapeToModifier = function () {};
-
   ShapeModifier.prototype.addShape = function (data) {
     if (!this.closed) {
       // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
@@ -5356,13 +4505,11 @@
       };
       this.shapes.push(shapeData);
       this.addShapeToModifier(shapeData);
-
       if (this._isAnimated) {
         data.setAsAnimated();
       }
     }
   };
-
   ShapeModifier.prototype.init = function (elem, data) {
     this.shapes = [];
     this.elem = elem;
@@ -5371,29 +4518,23 @@
     this.frameId = initialDefaultFrame;
     this.closed = false;
     this.k = false;
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   ShapeModifier.prototype.processKeys = function () {
     if (this.elem.globalData.frameId === this.frameId) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   extendPrototype([DynamicPropertyContainer], ShapeModifier);
 
   function TrimModifier() {}
-
   extendPrototype([ShapeModifier], TrimModifier);
-
   TrimModifier.prototype.initModifierProperties = function (elem, data) {
     this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
     this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
@@ -5404,14 +4545,11 @@
     this.m = data.m;
     this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
   };
-
   TrimModifier.prototype.addShapeToModifier = function (shapeData) {
     shapeData.pathsData = [];
   };
-
   TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
     var segments = [];
-
     if (e <= 1) {
       segments.push({
         s: s,
@@ -5432,65 +4570,50 @@
         e: e - 1
       });
     }
-
     var shapeSegments = [];
     var i;
     var len = segments.length;
     var segmentOb;
-
     for (i = 0; i < len; i += 1) {
       segmentOb = segments[i];
-
       if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
         var shapeS;
         var shapeE;
-
         if (segmentOb.s * totalModifierLength <= addedLength) {
           shapeS = 0;
         } else {
           shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
         }
-
         if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
           shapeE = 1;
         } else {
           shapeE = (segmentOb.e * totalModifierLength - addedLength) / shapeLength;
         }
-
         shapeSegments.push([shapeS, shapeE]);
       }
     }
-
     if (!shapeSegments.length) {
       shapeSegments.push([0, 0]);
     }
-
     return shapeSegments;
   };
-
   TrimModifier.prototype.releasePathsData = function (pathsData) {
     var i;
     var len = pathsData.length;
-
     for (i = 0; i < len; i += 1) {
       segmentsLengthPool.release(pathsData[i]);
     }
-
     pathsData.length = 0;
     return pathsData;
   };
-
   TrimModifier.prototype.processShapes = function (_isFirstFrame) {
     var s;
     var e;
-
     if (this._mdf || _isFirstFrame) {
       var o = this.o.v % 360 / 360;
-
       if (o < 0) {
         o += 1;
       }
-
       if (this.s.v > 1) {
         s = 1 + o;
       } else if (this.s.v < 0) {
@@ -5498,7 +4621,6 @@
       } else {
         s = this.s.v + o;
       }
-
       if (this.e.v > 1) {
         e = 1 + o;
       } else if (this.e.v < 0) {
@@ -5506,13 +4628,11 @@
       } else {
         e = this.e.v + o;
       }
-
       if (s > e) {
         var _s = s;
         s = e;
         e = _s;
       }
-
       s = Math.round(s * 10000) * 0.0001;
       e = Math.round(e * 10000) * 0.0001;
       this.sValue = s;
@@ -5521,7 +4641,6 @@
       s = this.sValue;
       e = this.eValue;
     }
-
     var shapePaths;
     var i;
     var len = this.shapes.length;
@@ -5531,13 +4650,11 @@
     var pathData;
     var totalShapeLength;
     var totalModifierLength = 0;
-
     if (e === s) {
       for (i = 0; i < len; i += 1) {
         this.shapes[i].localShapeCollection.releaseShapes();
         this.shapes[i].shape._mdf = true;
         this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
-
         if (this._mdf) {
           this.shapes[i].pathsData.length = 0;
         }
@@ -5546,63 +4663,52 @@
       var segments = [];
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
-        shapeData = this.shapes[i]; // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
-
+        shapeData = this.shapes[i];
+        // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
         if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
           shapeData.shape.paths = shapeData.localShapeCollection;
         } else {
           shapePaths = shapeData.shape.paths;
           jLen = shapePaths._length;
           totalShapeLength = 0;
-
           if (!shapeData.shape._mdf && shapeData.pathsData.length) {
             totalShapeLength = shapeData.totalShapeLength;
           } else {
             pathsData = this.releasePathsData(shapeData.pathsData);
-
             for (j = 0; j < jLen; j += 1) {
               pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
               pathsData.push(pathData);
               totalShapeLength += pathData.totalLength;
             }
-
             shapeData.totalShapeLength = totalShapeLength;
             shapeData.pathsData = pathsData;
           }
-
           totalModifierLength += totalShapeLength;
           shapeData.shape._mdf = true;
         }
       }
-
       var shapeS = s;
       var shapeE = e;
       var addedLength = 0;
       var edges;
-
       for (i = len - 1; i >= 0; i -= 1) {
         shapeData = this.shapes[i];
-
         if (shapeData.shape._mdf) {
           localShapeCollection = shapeData.localShapeCollection;
-          localShapeCollection.releaseShapes(); // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
-
+          localShapeCollection.releaseShapes();
+          // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
           if (this.m === 2 && len > 1) {
             edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
             addedLength += shapeData.totalShapeLength;
           } else {
             edges = [[shapeS, shapeE]];
           }
-
           jLen = edges.length;
-
           for (j = 0; j < jLen; j += 1) {
             shapeS = edges[j][0];
             shapeE = edges[j][1];
             segments.length = 0;
-
             if (shapeE <= 1) {
               segments.push({
                 s: shapeData.totalShapeLength * shapeS,
@@ -5623,13 +4729,10 @@
                 e: shapeData.totalShapeLength * (shapeE - 1)
               });
             }
-
             var newShapesData = this.addShapes(shapeData, segments[0]);
-
             if (segments[0].s !== segments[0].e) {
               if (segments.length > 1) {
                 var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
-
                 if (lastShapeInCollection.c) {
                   var lastShape = newShapesData.pop();
                   this.addPaths(newShapesData, localShapeCollection);
@@ -5639,11 +4742,9 @@
                   newShapesData = this.addShapes(shapeData, segments[1]);
                 }
               }
-
               this.addPaths(newShapesData, localShapeCollection);
             }
           }
-
           shapeData.shape.paths = localShapeCollection;
         }
       }
@@ -5656,38 +4757,29 @@
       }
     }
   };
-
   TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
     var i;
     var len = newPaths.length;
-
     for (i = 0; i < len; i += 1) {
       localShapeCollection.addShape(newPaths[i]);
     }
   };
-
   TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
     shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
     shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
     }
-
     shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
     shapePath.setXYAt(points[1], points[5], 'o', pos);
     shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(points[0], points[4], 'v', pos);
     }
-
     shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
     var pathsData = shapeData.pathsData;
     var shapePaths = shapeData.shape.paths.shapes;
@@ -5703,7 +4795,6 @@
     var shapes = [];
     var initPos;
     var newShape = true;
-
     if (!shapePath) {
       shapePath = shapePool.newElement();
       segmentCount = 0;
@@ -5712,17 +4803,13 @@
       segmentCount = shapePath._length;
       initPos = shapePath._length;
     }
-
     shapes.push(shapePath);
-
     for (i = 0; i < len; i += 1) {
       lengths = pathsData[i].lengths;
       shapePath.c = shapePaths[i].c;
       jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
-
       for (j = 1; j < jLen; j += 1) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
           addedLength += currentLengthData.addedLength;
           shapePath.c = false;
@@ -5735,50 +4822,42 @@
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
-
           addedLength += currentLengthData.addedLength;
           segmentCount += 1;
         }
       }
-
       if (shapePaths[i].c && lengths.length) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength <= shapeSegment.e) {
           var segmentLength = lengths[j - 1].addedLength;
-
           if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
             this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
         } else {
           shapePath.c = false;
         }
-
         addedLength += currentLengthData.addedLength;
         segmentCount += 1;
       }
-
       if (shapePath._length) {
         shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
         shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
       }
-
       if (addedLength > shapeSegment.e) {
         break;
       }
-
       if (i < len - 1) {
         shapePath = shapePool.newElement();
         newShape = true;
@@ -5786,31 +4865,25 @@
         segmentCount = 0;
       }
     }
-
     return shapes;
   };
 
   function PuckerAndBloatModifier() {}
-
   extendPrototype([ShapeModifier], PuckerAndBloatModifier);
-
   PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
     this._isAnimated = !!this.amount.effectsSequence.length;
   };
-
   PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
     var percent = amount / 100;
     var centerPoint = [0, 0];
     var pathLength = path._length;
     var i = 0;
-
     for (i = 0; i < pathLength; i += 1) {
       centerPoint[0] += path.v[i][0];
       centerPoint[1] += path.v[i][1];
     }
-
     centerPoint[0] /= pathLength;
     centerPoint[1] /= pathLength;
     var clonedPath = shapePool.newElement();
@@ -5821,7 +4894,6 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < pathLength; i += 1) {
       vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
       vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
@@ -5831,10 +4903,8 @@
       iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
       clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
     }
-
     return clonedPath;
   };
-
   PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -5842,30 +4912,24 @@
     var j;
     var jLen;
     var amount = this.amount.v;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -5873,30 +4937,24 @@
 
   var TransformPropertyFactory = function () {
     var defaultVector = [0, 0];
-
     function applyToMatrix(mat) {
       var _mdf = this._mdf;
       this.iterateDynamicProperties();
       this._mdf = this._mdf || _mdf;
-
       if (this.a) {
         mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
       }
-
       if (this.s) {
         mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
       }
-
       if (this.sk) {
         mat.skewFromAxis(-this.sk.v, this.sa.v);
       }
-
       if (this.r) {
         mat.rotate(-this.r.v);
       } else {
         mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
       }
-
       if (this.data.p.s) {
         if (this.data.p.z) {
           mat.translate(this.px.v, this.py.v, -this.pz.v);
@@ -5907,46 +4965,36 @@
         mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
       }
     }
-
     function processKeys(forceRender) {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (this._isDirty) {
         this.precalculateMatrix();
         this._isDirty = false;
       }
-
       this.iterateDynamicProperties();
-
       if (this._mdf || forceRender) {
         var frameRate;
         this.v.cloneFromProps(this.pre.props);
-
         if (this.appliedTransformations < 1) {
           this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         }
-
         if (this.appliedTransformations < 2) {
           this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         }
-
         if (this.sk && this.appliedTransformations < 3) {
           this.v.skewFromAxis(-this.sk.v, this.sa.v);
         }
-
         if (this.r && this.appliedTransformations < 4) {
           this.v.rotate(-this.r.v);
         } else if (!this.r && this.appliedTransformations < 4) {
           this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
         }
-
         if (this.autoOriented) {
           var v1;
           var v2;
           frameRate = this.elem.globalData.frameRate;
-
           if (this.p && this.p.keyframes && this.p.getValueAtTime) {
             if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
               v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
@@ -5963,7 +5011,6 @@
             v2 = [];
             var px = this.px;
             var py = this.py;
-
             if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
               v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
               v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
@@ -5983,10 +5030,8 @@
             v2 = defaultVector;
             v1 = v2;
           }
-
           this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
         }
-
         if (this.data.p && this.data.p.s) {
           if (this.data.p.z) {
             this.v.translate(this.px.v, this.py.v, -this.pz.v);
@@ -5997,28 +5042,23 @@
           this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
         }
       }
-
       this.frameId = this.elem.globalData.frameId;
     }
-
     function precalculateMatrix() {
       this.appliedTransformations = 0;
       this.pre.reset();
-
       if (!this.a.effectsSequence.length) {
         this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         this.appliedTransformations = 1;
       } else {
         return;
       }
-
       if (!this.s.effectsSequence.length) {
         this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         this.appliedTransformations = 2;
       } else {
         return;
       }
-
       if (this.sk) {
         if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
           this.pre.skewFromAxis(-this.sk.v, this.sa.v);
@@ -6027,7 +5067,6 @@
           return;
         }
       }
-
       if (this.r) {
         if (!this.r.effectsSequence.length) {
           this.pre.rotate(-this.r.v);
@@ -6038,33 +5077,28 @@
         this.appliedTransformations = 4;
       }
     }
-
-    function autoOrient() {//
+    function autoOrient() {
+      //
       // var prevP = this.getValueAtTime();
     }
-
     function addDynamicProperty(prop) {
       this._addDynamicProperty(prop);
-
       this.elem.addDynamicProperty(prop);
       this._isDirty = true;
     }
-
     function TransformProperty(elem, data, container) {
       this.elem = elem;
       this.frameId = -1;
       this.propType = 'transform';
       this.data = data;
-      this.v = new Matrix(); // Precalculated matrix with non animated properties
-
+      this.v = new Matrix();
+      // Precalculated matrix with non animated properties
       this.pre = new Matrix();
       this.appliedTransformations = 0;
       this.initDynamicPropertyContainer(container || elem);
-
       if (data.p && data.p.s) {
         this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
         this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
-
         if (data.p.z) {
           this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
         }
@@ -6073,43 +5107,37 @@
           k: [0, 0, 0]
         }, 1, 0, this);
       }
-
       if (data.rx) {
         this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
         this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
         this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
-
         if (data.or.k[0].ti) {
           var i;
           var len = data.or.k.length;
-
           for (i = 0; i < len; i += 1) {
             data.or.k[i].to = null;
             data.or.k[i].ti = null;
           }
         }
-
-        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this); // sh Indicates it needs to be capped between -180 and 180
-
+        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+        // sh Indicates it needs to be capped between -180 and 180
         this.or.sh = true;
       } else {
         this.r = PropertyFactory.getProp(elem, data.r || {
           k: 0
         }, 0, degToRads, this);
       }
-
       if (data.sk) {
         this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
         this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
       }
-
       this.a = PropertyFactory.getProp(elem, data.a || {
         k: [0, 0, 0]
       }, 1, 0, this);
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: [100, 100, 100]
-      }, 1, 0.01, this); // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
-
+      }, 1, 0.01, this);
+      // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
       if (data.o) {
         this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
       } else {
@@ -6118,14 +5146,11 @@
           v: 1
         };
       }
-
       this._isDirty = true;
-
       if (!this.dynamicProperties.length) {
         this.getValue(true);
       }
     }
-
     TransformProperty.prototype = {
       applyToMatrix: applyToMatrix,
       getValue: processKeys,
@@ -6135,20 +5160,16 @@
     extendPrototype([DynamicPropertyContainer], TransformProperty);
     TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
     TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
-
     function getTransformProperty(elem, data, container) {
       return new TransformProperty(elem, data, container);
     }
-
     return {
       getTransformProperty: getTransformProperty
     };
   }();
 
   function RepeaterModifier() {}
-
   extendPrototype([ShapeModifier], RepeaterModifier);
-
   RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
@@ -6157,11 +5178,9 @@
     this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
     this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
     this.data = data;
-
     if (!this.dynamicProperties.length) {
       this.getValue(true);
     }
-
     this._isAnimated = !!this.dynamicProperties.length;
     this.pMatrix = new Matrix();
     this.rMatrix = new Matrix();
@@ -6169,7 +5188,6 @@
     this.tMatrix = new Matrix();
     this.matrix = new Matrix();
   };
-
   RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
     var dir = inv ? -1 : 1;
     var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
@@ -6182,7 +5200,6 @@
     sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
     sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
   };
-
   RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
     this.elem = elem;
     this.arr = arr;
@@ -6194,52 +5211,42 @@
     this.frameId = -1;
     this.initDynamicPropertyContainer(elem);
     this.initModifierProperties(elem, arr[pos]);
-
     while (pos > 0) {
-      pos -= 1; // this._elements.unshift(arr.splice(pos,1)[0]);
-
+      pos -= 1;
+      // this._elements.unshift(arr.splice(pos,1)[0]);
       this._elements.unshift(arr[pos]);
     }
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   RepeaterModifier.prototype.resetElements = function (elements) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._processed = false;
-
       if (elements[i].ty === 'gr') {
         this.resetElements(elements[i].it);
       }
     }
   };
-
   RepeaterModifier.prototype.cloneElements = function (elements) {
     var newElements = JSON.parse(JSON.stringify(elements));
     this.resetElements(newElements);
     return newElements;
   };
-
   RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._render = renderFlag;
-
       if (elements[i].ty === 'gr') {
         this.changeGroupRender(elements[i].it, renderFlag);
       }
     }
   };
-
   RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
     var items;
     var itemsTransform;
@@ -6247,10 +5254,8 @@
     var dir;
     var cont;
     var hasReloaded = false;
-
     if (this._mdf || _isFirstFrame) {
       var copies = Math.ceil(this.c.v);
-
       if (this._groups.length < copies) {
         while (this._groups.length < copies) {
           var group = {
@@ -6305,28 +5310,21 @@
             ty: 'tr'
           });
           this.arr.splice(0, 0, group);
-
           this._groups.splice(0, 0, group);
-
           this._currentCopies += 1;
         }
-
         this.elem.reloadShapes();
         hasReloaded = true;
       }
-
       cont = 0;
       var renderFlag;
-
       for (i = 0; i <= this._groups.length - 1; i += 1) {
         renderFlag = cont < copies;
         this._groups[i]._render = renderFlag;
         this.changeGroupRender(this._groups[i].it, renderFlag);
-
         if (!renderFlag) {
           var elems = this.elemsData[i].it;
           var transformData = elems[elems.length - 1];
-
           if (transformData.transform.op.v !== 0) {
             transformData.transform.op._mdf = true;
             transformData.transform.op.v = 0;
@@ -6334,11 +5332,10 @@
             transformData.transform.op._mdf = false;
           }
         }
-
         cont += 1;
       }
-
-      this._currentCopies = copies; /// /
+      this._currentCopies = copies;
+      /// /
 
       var offset = this.o.v;
       var offsetModulo = offset % 1;
@@ -6352,13 +5349,11 @@
       this.tMatrix.reset();
       this.matrix.reset();
       var iteration = 0;
-
       if (offset > 0) {
         while (iteration < roundOffset) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           iteration += 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
           iteration += offsetModulo;
@@ -6368,19 +5363,16 @@
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
           iteration -= 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
           iteration -= offsetModulo;
         }
       }
-
       i = this.data.m === 1 ? 0 : this._currentCopies - 1;
       dir = this.data.m === 1 ? 1 : -1;
       cont = this._currentCopies;
       var j;
       var jLen;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6388,29 +5380,23 @@
         items[items.length - 1].transform.mProps._mdf = true;
         items[items.length - 1].transform.op._mdf = true;
         items[items.length - 1].transform.op.v = this._currentCopies === 1 ? this.so.v : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
-
         if (iteration !== 0) {
           if (i !== 0 && dir === 1 || i !== this._currentCopies - 1 && dir === -1) {
             this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           }
-
           this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
           this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
           this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
-
           this.matrix.reset();
         } else {
           this.matrix.reset();
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
         }
-
         iteration += 1;
         cont -= 1;
         i += dir;
@@ -6419,7 +5405,6 @@
       cont = this._currentCopies;
       i = 0;
       dir = 1;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6429,22 +5414,17 @@
         i += dir;
       }
     }
-
     return hasReloaded;
   };
-
   RepeaterModifier.prototype.addShape = function () {};
 
   function RoundCornersModifier() {}
-
   extendPrototype([ShapeModifier], RoundCornersModifier);
-
   RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
     this._isAnimated = !!this.rd.effectsSequence.length;
   };
-
   RoundCornersModifier.prototype.processPath = function (path, round) {
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
@@ -6463,19 +5443,16 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < len; i += 1) {
       currentV = path.v[i];
       currentO = path.o[i];
       currentI = path.i[i];
-
       if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
         if ((i === 0 || i === len - 1) && !path.c) {
           clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
           /* clonedPath.v[index] = currentV;
                   clonedPath.o[index] = currentO;
                   clonedPath.i[index] = currentI; */
-
           index += 1;
         } else {
           if (i === 0) {
@@ -6483,7 +5460,6 @@
           } else {
             closerV = path.v[i - 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6494,13 +5470,11 @@
           oY = vY - (vY - currentV[1]) * roundCorner;
           clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
           index += 1;
-
           if (i === len - 1) {
             closerV = path.v[0];
           } else {
             closerV = path.v[i + 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6517,10 +5491,8 @@
         index += 1;
       }
     }
-
     return clonedPath;
   };
-
   RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6528,30 +5500,24 @@
     var j;
     var jLen;
     var rd = this.rd.v;
-
     if (rd !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6560,50 +5526,41 @@
   function floatEqual(a, b) {
     return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
   }
-
   function floatZero(f) {
     return Math.abs(f) <= 0.00001;
   }
-
   function lerp(p0, p1, amount) {
     return p0 * (1 - amount) + p1 * amount;
   }
-
   function lerpPoint(p0, p1, amount) {
     return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
   }
-
   function quadRoots(a, b, c) {
     // no root
     if (a === 0) return [];
-    var s = b * b - 4 * a * c; // Complex roots
-
+    var s = b * b - 4 * a * c;
+    // Complex roots
     if (s < 0) return [];
-    var singleRoot = -b / (2 * a); // 1 root
-
+    var singleRoot = -b / (2 * a);
+    // 1 root
     if (s === 0) return [singleRoot];
-    var delta = Math.sqrt(s) / (2 * a); // 2 roots
-
+    var delta = Math.sqrt(s) / (2 * a);
+    // 2 roots
     return [singleRoot - delta, singleRoot + delta];
   }
-
   function polynomialCoefficients(p0, p1, p2, p3) {
     return [-p0 + 3 * p1 - 3 * p2 + p3, 3 * p0 - 6 * p1 + 3 * p2, -3 * p0 + 3 * p1, p0];
   }
-
   function singlePoint(p) {
     return new PolynomialBezier(p, p, p, p, false);
   }
-
   function PolynomialBezier(p0, p1, p2, p3, linearize) {
     if (linearize && pointEqual(p0, p1)) {
       p1 = lerpPoint(p0, p3, 1 / 3);
     }
-
     if (linearize && pointEqual(p2, p3)) {
       p2 = lerpPoint(p0, p3, 2 / 3);
     }
-
     var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
     var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
     this.a = [coeffx[0], coeffy[0]];
@@ -6612,25 +5569,20 @@
     this.d = [coeffx[3], coeffy[3]];
     this.points = [p0, p1, p2, p3];
   }
-
   PolynomialBezier.prototype.point = function (t) {
     return [((this.a[0] * t + this.b[0]) * t + this.c[0]) * t + this.d[0], ((this.a[1] * t + this.b[1]) * t + this.c[1]) * t + this.d[1]];
   };
-
   PolynomialBezier.prototype.derivative = function (t) {
     return [(3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0], (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1]];
   };
-
   PolynomialBezier.prototype.tangentAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[1], p[0]);
   };
-
   PolynomialBezier.prototype.normalAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[0], p[1]);
   };
-
   PolynomialBezier.prototype.inflectionPoints = function () {
     var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
     if (floatZero(denom)) return [];
@@ -6638,17 +5590,14 @@
     var square = tcusp * tcusp - 1 / 3 * (this.b[1] * this.c[0] - this.b[0] * this.c[1]) / denom;
     if (square < 0) return [];
     var root = Math.sqrt(square);
-
     if (floatZero(root)) {
       if (root > 0 && root < 1) return [tcusp];
       return [];
     }
-
     return [tcusp - root, tcusp + root].filter(function (r) {
       return r > 0 && r < 1;
     });
   };
-
   PolynomialBezier.prototype.split = function (t) {
     if (t <= 0) return [singlePoint(this.points[0]), this];
     if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
@@ -6660,40 +5609,33 @@
     var p3 = lerpPoint(p20, p21, t);
     return [new PolynomialBezier(this.points[0], p10, p20, p3, true), new PolynomialBezier(p3, p21, p12, this.points[3], true)];
   };
-
   function extrema(bez, comp) {
     var min = bez.points[0][comp];
     var max = bez.points[bez.points.length - 1][comp];
-
     if (min > max) {
       var e = max;
       max = min;
       min = e;
-    } // Derivative roots to find min/max
-
-
+    }
+    // Derivative roots to find min/max
     var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
-
     for (var i = 0; i < f.length; i += 1) {
       if (f[i] > 0 && f[i] < 1) {
         var val = bez.point(f[i])[comp];
         if (val < min) min = val;else if (val > max) max = val;
       }
     }
-
     return {
       min: min,
       max: max
     };
   }
-
   PolynomialBezier.prototype.bounds = function () {
     return {
       x: extrema(this, 0),
       y: extrema(this, 1)
     };
   };
-
   PolynomialBezier.prototype.boundingBox = function () {
     var bounds = this.bounds();
     return {
@@ -6707,7 +5649,6 @@
       cy: (bounds.y.max + bounds.y.min) / 2
     };
   };
-
   function intersectData(bez, t1, t2) {
     var box = bez.boundingBox();
     return {
@@ -6721,24 +5662,19 @@
       t2: t2
     };
   }
-
   function splitData(data) {
     var split = data.bez.split(0.5);
     return [intersectData(split[0], data.t1, data.t), intersectData(split[1], data.t, data.t2)];
   }
-
   function boxIntersect(b1, b2) {
     return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
   }
-
   function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
     if (!boxIntersect(d1, d2)) return;
-
     if (depth >= maxRecursion || d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance) {
       intersections.push([d1.t, d2.t]);
       return;
     }
-
     var d1s = splitData(d1);
     var d2s = splitData(d2);
     intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
@@ -6746,7 +5682,6 @@
     intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
     intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
   }
-
   PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
     if (tolerance === undefined) tolerance = 2;
     if (maxRecursion === undefined) maxRecursion = 7;
@@ -6754,21 +5689,17 @@
     intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
     return intersections;
   };
-
   PolynomialBezier.shapeSegment = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
   };
-
   PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
   };
-
   function crossProduct(a, b) {
     return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
   }
-
   function lineIntersection(start1, end1, start2, end2) {
     var v1 = [start1[0], start1[1], 1];
     var v2 = [end1[0], end1[1], 1];
@@ -6778,23 +5709,18 @@
     if (floatZero(r[2])) return null;
     return [r[0] / r[2], r[1] / r[2]];
   }
-
   function polarOffset(p, angle, length) {
     return [p[0] + Math.cos(angle) * length, p[1] - Math.sin(angle) * length];
   }
-
   function pointDistance(p1, p2) {
     return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
   }
-
   function pointEqual(p1, p2) {
     return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
   }
 
   function ZigZagModifier() {}
-
   extendPrototype([ShapeModifier], ZigZagModifier);
-
   ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
@@ -6802,7 +5728,6 @@
     this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
     this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
   };
-
   function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
     var angO = angle - Math.PI / 2;
     var angI = angle + Math.PI / 2;
@@ -6810,14 +5735,12 @@
     var py = point[1] - Math.sin(angle) * direction * amplitude;
     outputBezier.setTripleAt(px, py, px + Math.cos(angO) * outAmplitude, py - Math.sin(angO) * outAmplitude, px + Math.cos(angI) * inAmplitude, py - Math.sin(angI) * inAmplitude, outputBezier.length());
   }
-
   function getPerpendicularVector(pt1, pt2) {
     var vector = [pt2[0] - pt1[0], pt2[1] - pt1[1]];
     var rot = -Math.PI * 0.5;
     var rotatedVector = [Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1], Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1]];
     return rotatedVector;
   }
-
   function getProjectingAngle(path, cur) {
     var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
     var nextIndex = (cur + 1) % path.length();
@@ -6826,7 +5749,6 @@
     var pVector = getPerpendicularVector(prevPoint, nextPoint);
     return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
   }
-
   function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
     var angle = getProjectingAngle(path, cur);
     var point = path.v[cur % path._length];
@@ -6836,7 +5758,6 @@
     var nextDist = pointType === 2 ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2)) : 0;
     setPoint(outputBezier, path.v[cur % path._length], angle, direction, amplitude, nextDist / ((frequency + 1) * 2), prevDist / ((frequency + 1) * 2), pointType);
   }
-
   function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
     for (var i = 0; i < frequency; i += 1) {
       var t = (i + 1) / (frequency + 1);
@@ -6846,39 +5767,30 @@
       setPoint(outputBezier, point, angle, direction, amplitude, dist / ((frequency + 1) * 2), dist / ((frequency + 1) * 2), pointType);
       direction = -direction;
     }
-
     return direction;
   }
-
   ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
     var count = path._length;
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
-
     if (!path.c) {
       count -= 1;
     }
-
     if (count === 0) return clonedPath;
     var direction = -1;
     var segment = PolynomialBezier.shapeSegment(path, 0);
     zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
-
     for (var i = 0; i < count; i += 1) {
       direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
-
       if (i === count - 1 && !path.c) {
         segment = null;
       } else {
         segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
       }
-
       zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
     }
-
     return clonedPath;
   };
-
   ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6888,30 +5800,24 @@
     var amplitude = this.amplitude.v;
     var frequency = Math.max(0, Math.round(this.frequency.v));
     var pointType = this.pointsType.v;
-
     if (amplitude !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6921,7 +5827,6 @@
     var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
     return [polarOffset(p1, angle, amount), polarOffset(p2, angle, amount)];
   }
-
   function offsetSegment(segment, amount) {
     var p0;
     var p1a;
@@ -6945,15 +5850,17 @@
     if (p2 === null) p2 = p2a;
     return new PolynomialBezier(p0, p1, p2, p3);
   }
-
   function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
     var p0 = seg1.points[3];
-    var p1 = seg2.points[0]; // Bevel
+    var p1 = seg2.points[0];
 
-    if (lineJoin === 3) return p0; // Connected, they don't need a joint
+    // Bevel
+    if (lineJoin === 3) return p0;
 
-    if (pointEqual(p0, p1)) return p0; // Round
+    // Connected, they don't need a joint
+    if (pointEqual(p0, p1)) return p0;
 
+    // Round
     if (lineJoin === 2) {
       var angleOut = -seg1.tangentAngle(1);
       var angleIn = -seg2.tangentAngle(0) + Math.PI;
@@ -6964,91 +5871,75 @@
       tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
       outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
       return p1;
-    } // Miter
+    }
 
-
+    // Miter
     var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
     var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
     var intersection = lineIntersection(t0, p0, p1, t1);
-
     if (intersection && pointDistance(intersection, p0) < miterLimit) {
       outputBezier.setTripleAt(intersection[0], intersection[1], intersection[0], intersection[1], intersection[0], intersection[1], outputBezier.length());
       return intersection;
     }
-
     return p0;
   }
-
   function getIntersection(a, b) {
     var intersect = a.intersections(b);
     if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
     if (intersect.length) return intersect[0];
     return null;
   }
-
   function pruneSegmentIntersection(a, b) {
     var outa = a.slice();
     var outb = b.slice();
     var intersect = getIntersection(a[a.length - 1], b[0]);
-
     if (intersect) {
       outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
       outb[0] = b[0].split(intersect[1])[1];
     }
-
     if (a.length > 1 && b.length > 1) {
       intersect = getIntersection(a[0], b[b.length - 1]);
-
       if (intersect) {
         return [[a[0].split(intersect[0])[0]], [b[b.length - 1].split(intersect[1])[1]]];
       }
     }
-
     return [outa, outb];
   }
-
   function pruneIntersections(segments) {
     var e;
-
     for (var i = 1; i < segments.length; i += 1) {
       e = pruneSegmentIntersection(segments[i - 1], segments[i]);
       segments[i - 1] = e[0];
       segments[i] = e[1];
     }
-
     if (segments.length > 1) {
       e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
       segments[segments.length - 1] = e[0];
       segments[0] = e[1];
     }
-
     return segments;
   }
-
   function offsetSegmentSplit(segment, amount) {
     /*
       We split each bezier segment into smaller pieces based
       on inflection points, this ensures the control point
       polygon is convex.
-        (A cubic bezier can have none, one, or two inflection points)
+       (A cubic bezier can have none, one, or two inflection points)
     */
     var flex = segment.inflectionPoints();
     var left;
     var right;
     var split;
     var mid;
-
     if (flex.length === 0) {
       return [offsetSegment(segment, amount)];
     }
-
     if (flex.length === 1 || floatEqual(flex[1], 1)) {
       split = segment.split(flex[0]);
       left = split[0];
       right = split[1];
       return [offsetSegment(left, amount), offsetSegment(right, amount)];
     }
-
     split = segment.split(flex[0]);
     left = split[0];
     var t = (flex[1] - flex[0]) / (1 - flex[0]);
@@ -7057,11 +5948,8 @@
     right = split[1];
     return [offsetSegment(left, amount), offsetSegment(mid, amount), offsetSegment(right, amount)];
   }
-
   function OffsetPathModifier() {}
-
   extendPrototype([ShapeModifier], OffsetPathModifier);
-
   OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
@@ -7069,61 +5957,50 @@
     this.lineJoin = data.lj;
     this._isAnimated = this.amount.effectsSequence.length !== 0;
   };
-
   OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
     var outputBezier = shapePool.newElement();
     outputBezier.c = inputBezier.c;
     var count = inputBezier.length();
-
     if (!inputBezier.c) {
       count -= 1;
     }
-
     var i;
     var j;
     var segment;
     var multiSegments = [];
-
     for (i = 0; i < count; i += 1) {
       segment = PolynomialBezier.shapeSegment(inputBezier, i);
       multiSegments.push(offsetSegmentSplit(segment, amount));
     }
-
     if (!inputBezier.c) {
       for (i = count - 1; i >= 0; i -= 1) {
         segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
         multiSegments.push(offsetSegmentSplit(segment, amount));
       }
     }
+    multiSegments = pruneIntersections(multiSegments);
 
-    multiSegments = pruneIntersections(multiSegments); // Add bezier segments to the output and apply line joints
-
+    // Add bezier segments to the output and apply line joints
     var lastPoint = null;
     var lastSeg = null;
-
     for (i = 0; i < multiSegments.length; i += 1) {
       var multiSegment = multiSegments[i];
       if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
       lastSeg = multiSegment[multiSegment.length - 1];
-
       for (j = 0; j < multiSegment.length; j += 1) {
         segment = multiSegment[j];
-
         if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
           outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
         } else {
           outputBezier.setTripleAt(segment.points[0][0], segment.points[0][1], segment.points[1][0], segment.points[1][1], segment.points[0][0], segment.points[0][1], outputBezier.length());
         }
-
         outputBezier.setTripleAt(segment.points[3][0], segment.points[3][1], segment.points[3][0], segment.points[3][1], segment.points[2][0], segment.points[2][1], outputBezier.length());
         lastPoint = segment.points[3];
       }
     }
-
     if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
     return outputBezier;
   };
-
   OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -7133,30 +6010,24 @@
     var amount = this.amount.v;
     var miterLimit = this.miterLimit.v;
     var lineJoin = this.lineJoin;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -7168,42 +6039,33 @@
     var fStyle = 'normal';
     var len = styles.length;
     var styleName;
-
     for (var i = 0; i < len; i += 1) {
       styleName = styles[i].toLowerCase();
-
       switch (styleName) {
         case 'italic':
           fStyle = 'italic';
           break;
-
         case 'bold':
           fWeight = '700';
           break;
-
         case 'black':
           fWeight = '900';
           break;
-
         case 'medium':
           fWeight = '500';
           break;
-
         case 'regular':
         case 'normal':
           fWeight = '400';
           break;
-
         case 'light':
         case 'thin':
           fWeight = '200';
           break;
-
         default:
           break;
       }
     }
-
     return {
       style: fStyle,
       weight: fontData.fWeight || fWeight
@@ -7220,8 +6082,8 @@
         shapes: []
       }
     };
-    var combinedCharacters = []; // Hindi characters
-
+    var combinedCharacters = [];
+    // Hindi characters
     combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
     var BLACK_FLAG_CODE_POINT = 127988;
     var CANCEL_TAG_CODE_POINT = 917631;
@@ -7232,44 +6094,41 @@
     var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
     var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
     var surrogateModifiers = ['d83cdffb', 'd83cdffc', 'd83cdffd', 'd83cdffe', 'd83cdfff'];
-
     function trimFontOptions(font) {
       var familyArray = font.split(',');
       var i;
       var len = familyArray.length;
       var enabledFamilies = [];
-
       for (i = 0; i < len; i += 1) {
         if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
           enabledFamilies.push(familyArray[i]);
         }
       }
-
       return enabledFamilies.join(',');
     }
-
     function setUpNode(font, family) {
-      var parentNode = createTag('span'); // Node is invisible to screen readers.
-
+      var parentNode = createTag('span');
+      // Node is invisible to screen readers.
       parentNode.setAttribute('aria-hidden', true);
       parentNode.style.fontFamily = family;
-      var node = createTag('span'); // Characters that vary significantly among different fonts
-
-      node.innerText = 'giItT1WQy@!-/#'; // Visible - so we can measure it - but not on the screen
-
+      var node = createTag('span');
+      // Characters that vary significantly among different fonts
+      node.innerText = 'giItT1WQy@!-/#';
+      // Visible - so we can measure it - but not on the screen
       parentNode.style.position = 'absolute';
       parentNode.style.left = '-10000px';
-      parentNode.style.top = '-10000px'; // Large font size makes even subtle changes obvious
-
-      parentNode.style.fontSize = '300px'; // Reset any font properties
-
+      parentNode.style.top = '-10000px';
+      // Large font size makes even subtle changes obvious
+      parentNode.style.fontSize = '300px';
+      // Reset any font properties
       parentNode.style.fontVariant = 'normal';
       parentNode.style.fontStyle = 'normal';
       parentNode.style.fontWeight = 'normal';
       parentNode.style.letterSpacing = '0';
       parentNode.appendChild(node);
-      document.body.appendChild(parentNode); // Remember width with no applied web font
+      document.body.appendChild(parentNode);
 
+      // Remember width with no applied web font
       var width = node.offsetWidth;
       node.style.fontFamily = trimFontOptions(font) + ', ' + family;
       return {
@@ -7278,14 +6137,12 @@
         parent: parentNode
       };
     }
-
     function checkLoadedFonts() {
       var i;
       var len = this.fonts.length;
       var node;
       var w;
       var loadedCount = len;
-
       for (i = 0; i < len; i += 1) {
         if (this.fonts[i].loaded) {
           loadedCount -= 1;
@@ -7294,55 +6151,47 @@
         } else {
           node = this.fonts[i].monoCase.node;
           w = this.fonts[i].monoCase.w;
-
           if (node.offsetWidth !== w) {
             loadedCount -= 1;
             this.fonts[i].loaded = true;
           } else {
             node = this.fonts[i].sansCase.node;
             w = this.fonts[i].sansCase.w;
-
             if (node.offsetWidth !== w) {
               loadedCount -= 1;
               this.fonts[i].loaded = true;
             }
           }
-
           if (this.fonts[i].loaded) {
             this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
             this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
           }
         }
       }
-
       if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
         setTimeout(this.checkLoadedFontsBinded, 20);
       } else {
         setTimeout(this.setIsLoadedBinded, 10);
       }
     }
-
     function createHelper(fontData, def) {
       var engine = document.body && def ? 'svg' : 'canvas';
       var helper;
       var fontProps = getFontProperties(fontData);
-
       if (engine === 'svg') {
         var tHelper = createNS('text');
-        tHelper.style.fontSize = '100px'; // tHelper.style.fontFamily = fontData.fFamily;
-
+        tHelper.style.fontSize = '100px';
+        // tHelper.style.fontFamily = fontData.fFamily;
         tHelper.setAttribute('font-family', fontData.fFamily);
         tHelper.setAttribute('font-style', fontProps.style);
         tHelper.setAttribute('font-weight', fontProps.weight);
         tHelper.textContent = '1';
-
         if (fontData.fClass) {
           tHelper.style.fontFamily = 'inherit';
           tHelper.setAttribute('class', fontData.fClass);
         } else {
           tHelper.style.fontFamily = fontData.fFamily;
         }
-
         def.appendChild(tHelper);
         helper = tHelper;
       } else {
@@ -7350,33 +6199,27 @@
         tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
         helper = tCanvasHelper;
       }
-
       function measure(text) {
         if (engine === 'svg') {
           helper.textContent = text;
           return helper.getComputedTextLength();
         }
-
         return helper.measureText(text).width;
       }
-
       return {
         measureText: measure
       };
     }
-
     function addFonts(fontData, defs) {
       if (!fontData) {
         this.isLoaded = true;
         return;
       }
-
       if (this.chars) {
         this.isLoaded = true;
         this.fonts = fontData.list;
         return;
       }
-
       if (!document.body) {
         this.isLoaded = true;
         fontData.list.forEach(function (data) {
@@ -7386,12 +6229,10 @@
         this.fonts = fontData.list;
         return;
       }
-
       var fontArr = fontData.list;
       var i;
       var len = fontArr.length;
       var _pendingFonts = len;
-
       for (i = 0; i < len; i += 1) {
         var shouldLoadFont = true;
         var loadedSelector;
@@ -7399,17 +6240,14 @@
         fontArr[i].loaded = false;
         fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
         fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
-
         if (!fontArr[i].fPath) {
           fontArr[i].loaded = true;
           _pendingFonts -= 1;
         } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
           loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
-
           if (loadedSelector.length > 0) {
             shouldLoadFont = false;
           }
-
           if (shouldLoadFont) {
             var s = createTag('style');
             s.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7421,14 +6259,12 @@
           }
         } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
           loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var l = createTag('link');
             l.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7440,14 +6276,12 @@
           }
         } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
           loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (fontArr[i].fPath === loadedSelector[j].src) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var sc = createTag('link');
             sc.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7457,12 +6291,10 @@
             defs.appendChild(sc);
           }
         }
-
         fontArr[i].helper = createHelper(fontArr[i], defs);
         fontArr[i].cache = {};
         this.fonts.push(fontArr[i]);
       }
-
       if (_pendingFonts === 0) {
         this.isLoaded = true;
       } else {
@@ -7471,71 +6303,56 @@
         setTimeout(this.checkLoadedFonts.bind(this), 100);
       }
     }
-
     function addChars(chars) {
       if (!chars) {
         return;
       }
-
       if (!this.chars) {
         this.chars = [];
       }
-
       var i;
       var len = chars.length;
       var j;
       var jLen = this.chars.length;
       var found;
-
       for (i = 0; i < len; i += 1) {
         j = 0;
         found = false;
-
         while (j < jLen) {
           if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
             found = true;
           }
-
           j += 1;
         }
-
         if (!found) {
           this.chars.push(chars[i]);
           jLen += 1;
         }
       }
     }
-
     function getCharData(_char, style, font) {
       var i = 0;
       var len = this.chars.length;
-
       while (i < len) {
         if (this.chars[i].ch === _char && this.chars[i].style === style && this.chars[i].fFamily === font) {
           return this.chars[i];
         }
-
         i += 1;
       }
-
       if ((typeof _char === 'string' && _char.charCodeAt(0) !== 13 || !_char) && console && console.warn // eslint-disable-line no-console
       && !this._warned) {
         this._warned = true;
         console.warn('Missing character from exported characters list: ', _char, style, font); // eslint-disable-line no-console
       }
-
       return emptyChar;
     }
-
     function measureText(_char2, fontName, size) {
-      var fontData = this.getFontByName(fontName); // Using the char instead of char.charCodeAt(0)
+      var fontData = this.getFontByName(fontName);
+      // Using the char instead of char.charCodeAt(0)
       // to avoid collisions between equal chars
-
       var index = _char2;
-
       if (!fontData.cache[index]) {
         var tHelper = fontData.helper;
-
         if (_char2 === ' ') {
           var doubleSize = tHelper.measureText('|' + _char2 + '|');
           var singleSize = tHelper.measureText('||');
@@ -7544,111 +6361,90 @@
           fontData.cache[index] = tHelper.measureText(_char2) / 100;
         }
       }
-
       return fontData.cache[index] * size;
     }
-
     function getFontByName(name) {
       var i = 0;
       var len = this.fonts.length;
-
       while (i < len) {
         if (this.fonts[i].fName === name) {
           return this.fonts[i];
         }
-
         i += 1;
       }
-
       return this.fonts[0];
     }
-
     function getCodePoint(string) {
       var codePoint = 0;
       var first = string.charCodeAt(0);
-
       if (first >= 0xD800 && first <= 0xDBFF) {
         var second = string.charCodeAt(1);
-
         if (second >= 0xDC00 && second <= 0xDFFF) {
           codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
         }
       }
-
       return codePoint;
-    } // Skin tone modifiers
+    }
 
-
+    // Skin tone modifiers
     function isModifier(firstCharCode, secondCharCode) {
       var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
       return surrogateModifiers.indexOf(sum) !== -1;
     }
-
     function isZeroWidthJoiner(charCode) {
       return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
-    } // This codepoint may change the appearance of the preceding character.
+    }
+
+    // This codepoint may change the appearance of the preceding character.
     // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
     // as a colorful image as compared to a monochrome text variant.
-
-
     function isVariationSelector(charCode) {
       return charCode === VARIATION_SELECTOR_16_CODE_POINT;
-    } // The regional indicator symbols are a set of 26 alphabetic Unicode
+    }
+
+    // The regional indicator symbols are a set of 26 alphabetic Unicode
     /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
     // two-letter country codes in a way that allows optional special treatment.
-
-
     function isRegionalCode(string) {
       var codePoint = getCodePoint(string);
-
       if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
         return true;
       }
-
       return false;
-    } // Some Emoji implementations represent combinations of
+    }
+
+    // Some Emoji implementations represent combinations of
     // two “regional indicator” letters as a single flag symbol.
-
-
     function isFlagEmoji(string) {
       return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
     }
-
     function isCombinedCharacter(_char3) {
       return combinedCharacters.indexOf(_char3) !== -1;
-    } // Regional flags start with a BLACK_FLAG_CODE_POINT
+    }
+
+    // Regional flags start with a BLACK_FLAG_CODE_POINT
     // folowed by 5 chars in the TAG range
     // and end with a CANCEL_TAG_CODE_POINT
-
-
     function isRegionalFlag(text, index) {
       var codePoint = getCodePoint(text.substr(index, 2));
-
       if (codePoint !== BLACK_FLAG_CODE_POINT) {
         return false;
       }
-
       var count = 0;
       index += 2;
-
       while (count < 5) {
         codePoint = getCodePoint(text.substr(index, 2));
-
         if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
           return false;
         }
-
         count += 1;
         index += 2;
       }
-
       return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
     }
-
     function setIsLoaded() {
       this.isLoaded = true;
     }
-
     var Font = function Font() {
       this.fonts = [];
       this.chars = null;
@@ -7659,7 +6455,6 @@
       this.setIsLoadedBinded = this.setIsLoaded.bind(this);
       this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
     };
-
     Font.isModifier = isModifier;
     Font.isZeroWidthJoiner = isZeroWidthJoiner;
     Font.isFlagEmoji = isFlagEmoji;
@@ -7684,30 +6479,26 @@
   function SlotManager(animationData) {
     this.animationData = animationData;
   }
-
   SlotManager.prototype.getProp = function (data) {
     if (this.animationData.slots && this.animationData.slots[data.sid]) {
       return Object.assign(data, this.animationData.slots[data.sid].p);
     }
-
     return data;
   };
-
   function slotFactory(animationData) {
     return new SlotManager(animationData);
   }
 
   function RenderableElement() {}
-
   RenderableElement.prototype = {
     initRenderable: function initRenderable() {
       // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
-      this.isInRange = false; // layer's display state
-
-      this.hidden = false; // If layer's transparency equals 0, it can be hidden
-
-      this.isTransparent = false; // list of animated components
-
+      this.isInRange = false;
+      // layer's display state
+      this.hidden = false;
+      // If layer's transparency equals 0, it can be hidden
+      this.isTransparent = false;
+      // list of animated components
       this.renderableComponents = [];
     },
     addRenderableComponent: function addRenderableComponent(component) {
@@ -7734,7 +6525,6 @@
         this.show();
       }
     },
-
     /**
        * @function
        * Initializes frame related properties.
@@ -7760,13 +6550,11 @@
     renderRenderable: function renderRenderable() {
       var i;
       var len = this.renderableComponents.length;
-
       for (i = 0; i < len; i += 1) {
         this.renderableComponents[i].renderFrame(this._isFirstFrame);
       }
       /* this.maskManager.renderFrame(this.finalTransform.mat);
           this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
-
     },
     sourceRectAtTime: function sourceRectAtTime() {
       return {
@@ -7783,7 +6571,6 @@
           h: this.data.textData.height
         };
       }
-
       return {
         w: this.data.width,
         h: this.data.height
@@ -7818,31 +6605,24 @@
   function SliderEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function AngleEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function ColorEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function PointEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function LayerIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function MaskIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function CheckboxEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function NoValueEffect() {
     this.p = {};
   }
@@ -7853,20 +6633,16 @@
     var i;
     var len = effects.length;
     var effectItem;
-
     for (i = 0; i < len; i += 1) {
       effectItem = new GroupEffect(effects[i], element);
       this.effectElements.push(effectItem);
     }
   }
-
   function GroupEffect(data, element) {
     this.init(data, element);
   }
-
   extendPrototype([DynamicPropertyContainer], GroupEffect);
   GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
-
   GroupEffect.prototype.init = function (data, element) {
     this.data = data;
     this.effectElements = [];
@@ -7875,50 +6651,39 @@
     var len = this.data.ef.length;
     var eff;
     var effects = this.data.ef;
-
     for (i = 0; i < len; i += 1) {
       eff = null;
-
       switch (effects[i].ty) {
         case 0:
           eff = new SliderEffect(effects[i], element, this);
           break;
-
         case 1:
           eff = new AngleEffect(effects[i], element, this);
           break;
-
         case 2:
           eff = new ColorEffect(effects[i], element, this);
           break;
-
         case 3:
           eff = new PointEffect(effects[i], element, this);
           break;
-
         case 4:
         case 7:
           eff = new CheckboxEffect(effects[i], element, this);
           break;
-
         case 10:
           eff = new LayerIndexEffect(effects[i], element, this);
           break;
-
         case 11:
           eff = new MaskIndexEffect(effects[i], element, this);
           break;
-
         case 5:
           eff = new EffectsManager(effects[i], element, this);
           break;
         // case 6:
-
         default:
           eff = new NoValueEffect(effects[i], element, this);
           break;
       }
-
       if (eff) {
         this.effectElements.push(eff);
       }
@@ -7926,47 +6691,37 @@
   };
 
   function BaseElement() {}
-
   BaseElement.prototype = {
     checkMasks: function checkMasks() {
       if (!this.data.hasMask) {
         return false;
       }
-
       var i = 0;
       var len = this.data.masksProperties.length;
-
       while (i < len) {
         if (this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false) {
           return true;
         }
-
         i += 1;
       }
-
       return false;
     },
     initExpressions: function initExpressions() {
       var expressionsInterfaces = getExpressionInterfaces();
-
       if (!expressionsInterfaces) {
         return;
       }
-
       var LayerExpressionInterface = expressionsInterfaces('layer');
       var EffectsExpressionInterface = expressionsInterfaces('effects');
       var ShapeExpressionInterface = expressionsInterfaces('shape');
       var TextExpressionInterface = expressionsInterfaces('text');
       var CompExpressionInterface = expressionsInterfaces('comp');
       this.layerInterface = LayerExpressionInterface(this);
-
       if (this.data.hasMask && this.maskManager) {
         this.layerInterface.registerMaskInterface(this.maskManager);
       }
-
       var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
       this.layerInterface.registerEffectsInterface(effectsInterface);
-
       if (this.data.ty === 0 || this.data.xt) {
         this.compInterface = CompExpressionInterface(this);
       } else if (this.data.ty === 4) {
@@ -7986,13 +6741,13 @@
       this.globalData = globalData;
       this.comp = comp;
       this.data = data;
-      this.layerId = createElementID(); // Stretch factor for old animations missing this property.
+      this.layerId = createElementID();
 
+      // Stretch factor for old animations missing this property.
       if (!this.data.sr) {
         this.data.sr = 1;
-      } // effects manager
-
-
+      }
+      // effects manager
       this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
     },
     getType: function getType() {
@@ -8007,8 +6762,8 @@
    * Checks layer in point and out point
    *
    */
-  function FrameElement() {}
 
+  function FrameElement() {}
   FrameElement.prototype = {
     /**
        * @function
@@ -8017,13 +6772,12 @@
        */
     initFrame: function initFrame() {
       // set to true when inpoint is rendered
-      this._isFirstFrame = false; // list of animated properties
-
-      this.dynamicProperties = []; // If layer has been modified in current tick this will be true
-
+      this._isFirstFrame = false;
+      // list of animated properties
+      this.dynamicProperties = [];
+      // If layer has been modified in current tick this will be true
       this._mdf = false;
     },
-
     /**
        * @function
        * Calculates all dynamic values
@@ -8037,11 +6791,9 @@
     prepareProperties: function prepareProperties(num, isVisible) {
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         if (isVisible || this._isParent && this.dynamicProperties[i].propType === 'transform') {
           this.dynamicProperties[i].getValue();
-
           if (this.dynamicProperties[i]._mdf) {
             this.globalData._mdf = true;
             this._mdf = true;
@@ -8063,30 +6815,21 @@
     this.footageData = globalData.imageLoader.getAsset(this.assetData);
     this.initBaseData(data, globalData, comp);
   }
-
   FootageElement.prototype.prepareFrame = function () {};
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
-
   FootageElement.prototype.getBaseElement = function () {
     return null;
   };
-
   FootageElement.prototype.renderFrame = function () {};
-
   FootageElement.prototype.destroy = function () {};
-
   FootageElement.prototype.initExpressions = function () {
     var expressionsInterfaces = getExpressionInterfaces();
-
     if (!expressionsInterfaces) {
       return;
     }
-
     var FootageInterface = expressionsInterfaces('footage');
     this.layerInterface = FootageInterface(this);
   };
-
   FootageElement.prototype.getFootageData = function () {
     return this.footageData;
   };
@@ -8112,29 +6855,23 @@
       k: [100]
     }, 1, 0.01, this);
   }
-
   AudioElement.prototype.prepareFrame = function (num) {
     this.prepareRenderableFrame(num, true);
     this.prepareProperties(num, true);
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
       this._currentTime = timeRemapped;
     } else {
       this._currentTime = num / this.data.sr;
     }
-
     this._volume = this.lv.v[0];
     var totalVolume = this._volume * this._volumeMultiplier;
-
     if (this._previousVolume !== totalVolume) {
       this._previousVolume = totalVolume;
       this.audio.volume(totalVolume);
     }
   };
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
-
   AudioElement.prototype.renderFrame = function () {
     if (this.isInRange && this._canPlay) {
       if (!this._isPlaying) {
@@ -8146,162 +6883,124 @@
       }
     }
   };
-
-  AudioElement.prototype.show = function () {// this.audio.play()
+  AudioElement.prototype.show = function () {
+    // this.audio.play()
   };
-
   AudioElement.prototype.hide = function () {
     this.audio.pause();
     this._isPlaying = false;
   };
-
   AudioElement.prototype.pause = function () {
     this.audio.pause();
     this._isPlaying = false;
     this._canPlay = false;
   };
-
   AudioElement.prototype.resume = function () {
     this._canPlay = true;
   };
-
   AudioElement.prototype.setRate = function (rateValue) {
     this.audio.rate(rateValue);
   };
-
   AudioElement.prototype.volume = function (volumeValue) {
     this._volumeMultiplier = volumeValue;
     this._previousVolume = volumeValue * this._volume;
     this.audio.volume(this._previousVolume);
   };
-
   AudioElement.prototype.getBaseElement = function () {
     return null;
   };
-
   AudioElement.prototype.destroy = function () {};
-
   AudioElement.prototype.sourceRectAtTime = function () {};
-
   AudioElement.prototype.initExpressions = function () {};
 
   function BaseRenderer() {}
-
   BaseRenderer.prototype.checkLayers = function (num) {
     var i;
     var len = this.layers.length;
     var data;
     this.completeLayers = true;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (!this.elements[i]) {
         data = this.layers[i];
-
         if (data.ip - data.st <= num - this.layers[i].st && data.op - data.st > num - this.layers[i].st) {
           this.buildItem(i);
         }
       }
-
       this.completeLayers = this.elements[i] ? this.completeLayers : false;
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.createItem = function (layer) {
     switch (layer.ty) {
       case 2:
         return this.createImage(layer);
-
       case 0:
         return this.createComp(layer);
-
       case 1:
         return this.createSolid(layer);
-
       case 3:
         return this.createNull(layer);
-
       case 4:
         return this.createShape(layer);
-
       case 5:
         return this.createText(layer);
-
       case 6:
         return this.createAudio(layer);
-
       case 13:
         return this.createCamera(layer);
-
       case 15:
         return this.createFootage(layer);
-
       default:
         return this.createNull(layer);
     }
   };
-
   BaseRenderer.prototype.createCamera = function () {
     throw new Error('You\'re using a 3d camera. Try the html renderer.');
   };
-
   BaseRenderer.prototype.createAudio = function (data) {
     return new AudioElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.createFootage = function (data) {
     return new FootageElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.buildAllItems = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       this.buildItem(i);
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.includeLayers = function (newLayers) {
     this.completeLayers = false;
     var i;
     var len = newLayers.length;
     var j;
     var jLen = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       j = 0;
-
       while (j < jLen) {
         if (this.layers[j].id === newLayers[i].id) {
           this.layers[j] = newLayers[i];
           break;
         }
-
         j += 1;
       }
     }
   };
-
   BaseRenderer.prototype.setProjectInterface = function (pInterface) {
     this.globalData.projectInterface = pInterface;
   };
-
   BaseRenderer.prototype.initItems = function () {
     if (!this.globalData.progressiveLoad) {
       this.buildAllItems();
     }
   };
-
   BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
     var elements = this.elements;
     var layers = this.layers;
     var i = 0;
     var len = layers.length;
-
     while (i < len) {
       if (layers[i].ind == parentName) {
         // eslint-disable-line eqeqeq
@@ -8311,7 +7010,6 @@
         } else {
           hierarchy.push(elements[i]);
           elements[i].setAsParent();
-
           if (layers[i].parent !== undefined) {
             this.buildElementParenting(element, layers[i].parent, hierarchy);
           } else {
@@ -8319,19 +7017,15 @@
           }
         }
       }
-
       i += 1;
     }
   };
-
   BaseRenderer.prototype.addPendingElement = function (element) {
     this.pendingElements.push(element);
   };
-
   BaseRenderer.prototype.searchExtraCompositions = function (assets) {
     var i;
     var len = assets.length;
-
     for (i = 0; i < len; i += 1) {
       if (assets[i].xt) {
         var comp = this.createComp(assets[i]);
@@ -8340,30 +7034,24 @@
       }
     }
   };
-
   BaseRenderer.prototype.getElementById = function (ind) {
     var i;
     var len = this.elements.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i].data.ind === ind) {
         return this.elements[i];
       }
     }
-
     return null;
   };
-
   BaseRenderer.prototype.getElementByPath = function (path) {
     var pathValue = path.shift();
     var element;
-
     if (typeof pathValue === 'number') {
       element = this.elements[pathValue];
     } else {
       var i;
       var len = this.elements.length;
-
       for (i = 0; i < len; i += 1) {
         if (this.elements[i].data.nm === pathValue) {
           element = this.elements[i];
@@ -8371,14 +7059,11 @@
         }
       }
     }
-
     if (path.length === 0) {
       return element;
     }
-
     return element.getElementByPath(path);
   };
-
   BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
     this.globalData.fontManager = new FontManager();
     this.globalData.slotManager = slotFactory(animData);
@@ -8402,7 +7087,6 @@
   };
 
   function TransformElement() {}
-
   TransformElement.prototype = {
     initTransform: function initTransform() {
       var mat = new Matrix();
@@ -8417,50 +7101,44 @@
         localMat: mat,
         localOpacity: 1
       };
-
       if (this.data.ao) {
         this.finalTransform.mProp.autoOriented = true;
-      } // TODO: check TYPE 11: Guided elements
+      }
 
-
-      if (this.data.ty !== 11) {// this.createElements();
+      // TODO: check TYPE 11: Guided elements
+      if (this.data.ty !== 11) {
+        // this.createElements();
       }
     },
     renderTransform: function renderTransform() {
       this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
       this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
-
       if (this.hierarchy) {
         var mat;
         var finalMat = this.finalTransform.mat;
         var i = 0;
-        var len = this.hierarchy.length; // Checking if any of the transformation matrices in the hierarchy chain has changed.
-
+        var len = this.hierarchy.length;
+        // Checking if any of the transformation matrices in the hierarchy chain has changed.
         if (!this.finalTransform._matMdf) {
           while (i < len) {
             if (this.hierarchy[i].finalTransform.mProp._mdf) {
               this.finalTransform._matMdf = true;
               break;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._matMdf) {
           mat = this.finalTransform.mProp.v.props;
           finalMat.cloneFromProps(mat);
-
           for (i = 0; i < len; i += 1) {
             finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
           }
         }
       }
-
-      if (this.finalTransform._matMdf) {
+      if (!this.localTransforms || this.finalTransform._matMdf) {
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
       }
-
       if (this.finalTransform._opMdf) {
         this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
       }
@@ -8470,41 +7148,32 @@
         var i = 0;
         var len = this.localTransforms.length;
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
-
         if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
           while (i < len) {
             if (this.localTransforms[i]._mdf) {
               this.finalTransform._localMatMdf = true;
             }
-
             if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
               this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
               this.finalTransform._opMdf = true;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._localMatMdf) {
           var localMat = this.finalTransform.localMat;
           this.localTransforms[0].matrix.clone(localMat);
-
           for (i = 1; i < len; i += 1) {
             var lmat = this.localTransforms[i].matrix;
             localMat.multiply(lmat);
           }
-
           localMat.multiply(this.finalTransform.mat);
         }
-
         if (this.finalTransform._opMdf) {
           var localOp = this.finalTransform.localOpacity;
-
           for (i = 0; i < len; i += 1) {
             localOp *= this.localTransforms[i].opacity * 0.01;
           }
-
           this.finalTransform.localOpacity = localOp;
         }
       }
@@ -8512,13 +7181,11 @@
     searchEffectTransforms: function searchEffectTransforms() {
       if (this.renderableEffectsManager) {
         var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
-
         if (transformEffects.length) {
           this.localTransforms = [];
           this.finalTransform.localMat = new Matrix();
           var i = 0;
           var len = transformEffects.length;
-
           for (i = 0; i < len; i += 1) {
             this.localTransforms.push(transformEffects[i]);
           }
@@ -8530,29 +7197,24 @@
       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;
       var len = transforms.length;
       var 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]);
-
+        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;
     },
     mHelper: new Matrix()
@@ -8583,13 +7245,11 @@
     var x;
     var maskType = 'clipPath';
     var maskRef = 'clip-path';
-
     for (i = 0; i < len; i += 1) {
       if (properties[i].mode !== 'a' && properties[i].mode !== 'n' || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
         maskType = 'mask';
         maskRef = 'mask';
       }
-
       if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
         rect = createNS('rect');
         rect.setAttribute('fill', '#ffffff');
@@ -8599,9 +7259,7 @@
       } else {
         rect = null;
       }
-
       path = createNS('path');
-
       if (properties[i].mode === 'n') {
         // TODO move this to a factory or to a constructor
         this.viewData[i] = {
@@ -8616,7 +7274,6 @@
         path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
         path.setAttribute('clip-rule', 'nonzero');
         var filterID;
-
         if (properties[i].x.k !== 0) {
           maskType = 'mask';
           maskRef = 'mask';
@@ -8634,9 +7291,9 @@
         } else {
           feMorph = null;
           x = null;
-        } // TODO move this to a factory or to a constructor
+        }
 
-
+        // TODO move this to a factory or to a constructor
         this.storedData[i] = {
           elem: path,
           x: x,
@@ -8646,15 +7303,12 @@
           filterId: filterID,
           lastRadius: 0
         };
-
         if (properties[i].mode === 'i') {
           jLen = currentMasks.length;
           var g = createNS('g');
-
           for (j = 0; j < jLen; j += 1) {
             g.appendChild(currentMasks[j]);
           }
-
           var mask = createNS('mask');
           mask.setAttribute('mask-type', 'alpha');
           mask.setAttribute('id', layerId + '_' + count);
@@ -8666,12 +7320,10 @@
         } else {
           currentMasks.push(path);
         }
-
         if (properties[i].inv && !this.solidPath) {
           this.solidPath = this.createLayerSolidPath();
-        } // TODO move this to a factory or to a constructor
-
-
+        }
+        // TODO move this to a factory or to a constructor
         this.viewData[i] = {
           elem: path,
           lastPath: '',
@@ -8679,81 +7331,65 @@
           prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
           invRect: rect
         };
-
         if (!this.viewData[i].prop.k) {
           this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
         }
       }
     }
-
     this.maskElement = createNS(maskType);
     len = currentMasks.length;
-
     for (i = 0; i < len; i += 1) {
       this.maskElement.appendChild(currentMasks[i]);
     }
-
     if (count > 0) {
       this.maskElement.setAttribute('id', layerId);
       this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
       defs.appendChild(this.maskElement);
     }
-
     if (this.viewData.length) {
       this.element.addRenderableComponent(this);
     }
   }
-
   MaskElement.prototype.getMaskProperty = function (pos) {
     return this.viewData[pos].prop;
   };
-
   MaskElement.prototype.renderFrame = function (isFirstFrame) {
     var finalMat = this.element.finalTransform.mat;
     var i;
     var len = this.masksProperties.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.viewData[i].prop._mdf || isFirstFrame) {
         this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
       }
-
       if (this.viewData[i].op._mdf || isFirstFrame) {
         this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
       }
-
       if (this.masksProperties[i].mode !== 'n') {
         if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
           this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
         }
-
         if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
           var feMorph = this.storedData[i].expan;
-
           if (this.storedData[i].x.v < 0) {
             if (this.storedData[i].lastOperator !== 'erode') {
               this.storedData[i].lastOperator = 'erode';
               this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
             }
-
             feMorph.setAttribute('radius', -this.storedData[i].x.v);
           } else {
             if (this.storedData[i].lastOperator !== 'dilate') {
               this.storedData[i].lastOperator = 'dilate';
               this.storedData[i].elem.setAttribute('filter', null);
             }
-
             this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
           }
         }
       }
     }
   };
-
   MaskElement.prototype.getMaskelement = function () {
     return this.maskElement;
   };
-
   MaskElement.prototype.createLayerSolidPath = function () {
     var path = 'M0,0 ';
     path += ' h' + this.globalData.compSize.w;
@@ -8762,39 +7398,32 @@
     path += ' v-' + this.globalData.compSize.h + ' ';
     return path;
   };
-
   MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
     var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
     var i;
     var len;
     len = pathNodes._length;
-
     for (i = 1; i < len; i += 1) {
       // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
-    } // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
-
-
+    }
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
     if (pathNodes.c && len > 1) {
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
-    } // pathNodes.__renderedString = pathString;
-
+    }
+    // pathNodes.__renderedString = pathString;
 
     if (viewData.lastPath !== pathString) {
       var pathShapeValue = '';
-
       if (viewData.elem) {
         if (pathNodes.c) {
           pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
         }
-
         viewData.elem.setAttribute('d', pathShapeValue);
       }
-
       viewData.lastPath = pathString;
     }
   };
-
   MaskElement.prototype.destroy = function () {
     this.element = null;
     this.globalData = null;
@@ -8807,11 +7436,9 @@
     var ob = {};
     ob.createFilter = createFilter;
     ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
-
     function createFilter(filId, skipCoordinates) {
       var fil = createNS('filter');
       fil.setAttribute('id', filId);
-
       if (skipCoordinates !== true) {
         fil.setAttribute('filterUnits', 'objectBoundingBox');
         fil.setAttribute('x', '0%');
@@ -8819,10 +7446,8 @@
         fil.setAttribute('width', '100%');
         fil.setAttribute('height', '100%');
       }
-
       return fil;
     }
-
     function createAlphaToLuminanceFilter() {
       var feColorMatrix = createNS('feColorMatrix');
       feColorMatrix.setAttribute('type', 'matrix');
@@ -8830,7 +7455,6 @@
       feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
       return feColorMatrix;
     }
-
     return ob;
   }();
 
@@ -8840,21 +7464,17 @@
       svgLumaHidden: true,
       offscreenCanvas: typeof OffscreenCanvas !== 'undefined'
     };
-
     if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
       ob.maskType = false;
     }
-
     if (/firefox/i.test(navigator.userAgent)) {
       ob.svgLumaHidden = false;
     }
-
     return ob;
   }();
 
   var registeredEffects = {};
   var idPrefix = 'filter_result_';
-
   function SVGEffects(elem) {
     var i;
     var source = 'SourceGraphic';
@@ -8864,59 +7484,47 @@
     var count = 0;
     this.filters = [];
     var filterManager;
-
     for (i = 0; i < len; i += 1) {
       filterManager = null;
       var type = elem.data.ef[i].ty;
-
       if (registeredEffects[type]) {
         var Effect = registeredEffects[type].effect;
         filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
         source = idPrefix + count;
-
         if (registeredEffects[type].countsAsEffect) {
           count += 1;
         }
       }
-
       if (filterManager) {
         this.filters.push(filterManager);
       }
     }
-
     if (count) {
       elem.globalData.defs.appendChild(fil);
       elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
     }
-
     if (this.filters.length) {
       elem.addRenderableComponent(this);
     }
   }
-
   SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
     var i;
     var len = this.filters.length;
-
     for (i = 0; i < len; i += 1) {
       this.filters[i].renderFrame(_isFirstFrame);
     }
   };
-
   SVGEffects.prototype.getEffects = function (type) {
     var i;
     var len = this.filters.length;
     var effects = [];
-
     for (i = 0; i < len; i += 1) {
       if (this.filters[i].type === type) {
         effects.push(this.filters[i]);
       }
     }
-
     return effects;
   };
-
   function registerEffect(id, effect, countsAsEffect) {
     registeredEffects[id] = {
       effect: effect,
@@ -8925,7 +7533,6 @@
   }
 
   function SVGBaseElement() {}
-
   SVGBaseElement.prototype = {
     initRendererElement: function initRendererElement() {
       this.layerElement = createNS('g');
@@ -8935,8 +7542,8 @@
       this.transformedElement = this.layerElement;
       this.maskedElement = this.layerElement;
       this._sizeChanged = false;
-      var layerElementParent = null; // If this layer acts as a mask for the following layer
-
+      var layerElementParent = null;
+      // If this layer acts as a mask for the following layer
       if (this.data.td) {
         this.matteMasks = {};
         var gg = createNS('g');
@@ -8951,16 +7558,13 @@
       } else {
         this.baseElement = this.layerElement;
       }
-
       if (this.data.ln) {
         this.layerElement.setAttribute('id', this.data.ln);
       }
-
       if (this.data.cl) {
         this.layerElement.setAttribute('class', this.data.cl);
-      } // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
-
-
+      }
+      // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
       if (this.data.ty === 0 && !this.data.hd) {
         var cp = createNS('clipPath');
         var pt = createNS('path');
@@ -8969,13 +7573,11 @@
         cp.setAttribute('id', clipId);
         cp.appendChild(pt);
         this.globalData.defs.appendChild(cp);
-
         if (this.checkMasks()) {
           var cpGroup = createNS('g');
           cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
           cpGroup.appendChild(this.layerElement);
           this.transformedElement = cpGroup;
-
           if (layerElementParent) {
             layerElementParent.appendChild(this.transformedElement);
           } else {
@@ -8985,7 +7587,6 @@
           this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
         }
       }
-
       if (this.data.bm !== 0) {
         this.setBlendMode();
       }
@@ -8994,7 +7595,6 @@
       if (this.finalTransform._localMatMdf) {
         this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
       }
-
       if (this.finalTransform._opMdf) {
         this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
       }
@@ -9008,7 +7608,6 @@
       if (this.data.hd) {
         return null;
       }
-
       return this.baseElement;
     },
     createRenderableComponents: function createRenderableComponents() {
@@ -9023,14 +7622,12 @@
       if (!this.matteMasks) {
         this.matteMasks = {};
       }
-
       if (!this.matteMasks[matteType]) {
         var id = this.layerId + '_' + matteType;
         var filId;
         var fil;
         var useElement;
         var gg;
-
         if (matteType === 1 || matteType === 3) {
           var masker = createNS('mask');
           masker.setAttribute('id', id);
@@ -9039,7 +7636,6 @@
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           masker.appendChild(useElement);
           this.globalData.defs.appendChild(masker);
-
           if (!featureSupport.maskType && matteType === 1) {
             masker.setAttribute('mask-type', 'luminance');
             filId = createElementID();
@@ -9058,16 +7654,16 @@
           var maskGrouper = createNS('g');
           maskGroup.appendChild(maskGrouper);
           filId = createElementID();
-          fil = filtersFactory.createFilter(filId); /// /
-
+          fil = filtersFactory.createFilter(filId);
+          /// /
           var feCTr = createNS('feComponentTransfer');
           feCTr.setAttribute('in', 'SourceGraphic');
           fil.appendChild(feCTr);
           var feFunc = createNS('feFuncA');
           feFunc.setAttribute('type', 'table');
           feFunc.setAttribute('tableValues', '1.0 0.0');
-          feCTr.appendChild(feFunc); /// /
-
+          feCTr.appendChild(feFunc);
+          /// /
           this.globalData.defs.appendChild(fil);
           var alphaRect = createNS('rect');
           alphaRect.setAttribute('width', this.comp.data.w);
@@ -9081,7 +7677,6 @@
           useElement = createNS('use');
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           maskGrouper.appendChild(useElement);
-
           if (!featureSupport.maskType) {
             maskGroup.setAttribute('mask-type', 'luminance');
             fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
@@ -9090,20 +7685,16 @@
             gg.appendChild(this.layerElement);
             maskGrouper.appendChild(gg);
           }
-
           this.globalData.defs.appendChild(maskGroup);
         }
-
         this.matteMasks[matteType] = id;
       }
-
       return this.matteMasks[matteType];
     },
     setMatte: function setMatte(id) {
       if (!this.matteElement) {
         return;
       }
-
       this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
     }
   };
@@ -9113,8 +7704,8 @@
    * Handles AE's layer parenting property.
    *
    */
-  function HierarchyElement() {}
 
+  function HierarchyElement() {}
   HierarchyElement.prototype = {
     /**
        * @function
@@ -9123,12 +7714,11 @@
        */
     initHierarchy: function initHierarchy() {
       // element's parent list
-      this.hierarchy = []; // if element is parent of another layer _isParent will be true
-
+      this.hierarchy = [];
+      // if element is parent of another layer _isParent will be true
       this._isParent = false;
       this.checkParenting();
     },
-
     /**
        * @function
        * Sets layer's hierarchy.
@@ -9139,7 +7729,6 @@
     setHierarchy: function setHierarchy(hierarchy) {
       this.hierarchy = hierarchy;
     },
-
     /**
        * @function
        * Sets layer as parent.
@@ -9148,7 +7737,6 @@
     setAsParent: function setAsParent() {
       this._isParent = true;
     },
-
     /**
        * @function
        * Searches layer's parenting chain
@@ -9162,7 +7750,6 @@
   };
 
   function RenderableDOMElement() {}
-
   (function () {
     var _prototype = {
       initElement: function initElement(data, globalData, comp) {
@@ -9192,7 +7779,6 @@
             var elem = this.baseElement || this.layerElement;
             elem.style.display = 'block';
           }
-
           this.hidden = false;
           this._isFirstFrame = true;
         }
@@ -9203,13 +7789,11 @@
         if (this.data.hd || this.hidden) {
           return;
         }
-
         this.renderTransform();
         this.renderRenderable();
         this.renderLocalTransform();
         this.renderElement();
         this.renderInnerContent();
-
         if (this._isFirstFrame) {
           this._isFirstFrame = false;
         }
@@ -9231,11 +7815,9 @@
 
   function IImageElement(data, globalData, comp) {
     this.assetData = globalData.getAssetData(data.refId);
-
     if (this.assetData && this.assetData.sid) {
       this.assetData = globalData.slotManager.getProp(this.assetData);
     }
-
     this.initElement(data, globalData, comp);
     this.sourceRect = {
       top: 0,
@@ -9244,9 +7826,7 @@
       height: this.assetData.h
     };
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
-
   IImageElement.prototype.createContent = function () {
     var assetPath = this.globalData.getAssetsPath(this.assetData);
     this.innerElem = createNS('image');
@@ -9256,7 +7836,6 @@
     this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
     this.layerElement.appendChild(this.innerElem);
   };
-
   IImageElement.prototype.sourceRectAtTime = function () {
     return this.sourceRect;
   };
@@ -9267,12 +7846,10 @@
   }
 
   function IShapeElement() {}
-
   IShapeElement.prototype = {
     addShapeToModifiers: function addShapeToModifiers(data) {
       var i;
       var len = this.shapeModifiers.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapeModifiers[i].addShape(data);
       }
@@ -9280,34 +7857,28 @@
     isShapeInAnimatedModifiers: function isShapeInAnimatedModifiers(data) {
       var i = 0;
       var len = this.shapeModifiers.length;
-
       while (i < len) {
         if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
           return true;
         }
       }
-
       return false;
     },
     renderModifiers: function renderModifiers() {
       if (!this.shapeModifiers.length) {
         return;
       }
-
       var i;
       var len = this.shapes.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapes[i].sh.reset();
       }
-
       len = this.shapeModifiers.length;
       var shouldBreakProcess;
-
       for (i = len - 1; i >= 0; i -= 1) {
-        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame); // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+        // workaround to fix cases where a repeater resets the shape so the following processes get called twice
         // TODO: find a better solution for this
-
         if (shouldBreakProcess) {
           break;
         }
@@ -9317,30 +7888,24 @@
       var elements = this.processedElements;
       var i = 0;
       var len = elements.length;
-
       while (i < len) {
         if (elements[i].elem === elem) {
           return elements[i].pos;
         }
-
         i += 1;
       }
-
       return 0;
     },
     addProcessedElement: function addProcessedElement(elem, pos) {
       var elements = this.processedElements;
       var i = elements.length;
-
       while (i) {
         i -= 1;
-
         if (elements[i].elem === elem) {
           elements[i].pos = pos;
           return;
         }
       }
-
       elements.push(new ProcessedElement(elem, pos));
     },
     prepareFrame: function prepareFrame(num) {
@@ -9366,25 +7931,22 @@
     this.transformers = transformers;
     this.lStr = '';
     this.sh = shape;
-    this.lvl = level; // TODO find if there are some cases where _isAnimated can be false.
+    this.lvl = level;
+    // TODO find if there are some cases where _isAnimated can be false.
     // For now, since shapes add up with other shapes. They have to be calculated every time.
     // One way of finding out is checking if all styles associated to this shape depend only of this shape
-
-    this._isAnimated = !!shape.k; // TODO: commenting this for now since all shapes are animated
-
+    this._isAnimated = !!shape.k;
+    // TODO: commenting this for now since all shapes are animated
     var i = 0;
     var len = transformers.length;
-
     while (i < len) {
       if (transformers[i].mProps.dynamicProperties.length) {
         this._isAnimated = true;
         break;
       }
-
       i += 1;
     }
   }
-
   SVGShapeData.prototype.setAsAnimated = function () {
     this._isAnimated = true;
   };
@@ -9399,7 +7961,6 @@
     this.pElem = createNS('path');
     this.msElem = null;
   }
-
   SVGStyleData.prototype.reset = function () {
     this.d = '';
     this._mdf = false;
@@ -9418,7 +7979,6 @@
     var i;
     var len = data.length || 0;
     var prop;
-
     for (i = 0; i < len; i += 1) {
       prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
       this.k = prop.k || this.k;
@@ -9427,31 +7987,24 @@
         p: prop
       };
     }
-
     if (!this.k) {
       this.getValue(true);
     }
-
     this._isAnimated = this.k;
   }
-
   DashProperty.prototype.getValue = function (forceRender) {
     if (this.elem.globalData.frameId === this.frameId && !forceRender) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
     this._mdf = this._mdf || forceRender;
-
     if (this._mdf) {
       var i = 0;
       var len = this.dataProps.length;
-
       if (this.renderer === 'svg') {
         this.dashStr = '';
       }
-
       for (i = 0; i < len; i += 1) {
         if (this.dataProps[i].n !== 'o') {
           if (this.renderer === 'svg') {
@@ -9465,7 +8018,6 @@
       }
     }
   };
-
   extendPrototype([DynamicPropertyContainer], DashProperty);
 
   function SVGStrokeStyleData(elem, data, styleOb) {
@@ -9478,7 +8030,6 @@
     this.style = styleOb;
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
 
   function SVGFillStyleData(elem, data, styleOb) {
@@ -9488,7 +8039,6 @@
     this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
 
   function SVGNoStyleData(elem, data, styleOb) {
@@ -9496,7 +8046,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
 
   function GradientProperty(elem, data, container) {
@@ -9513,88 +8062,69 @@
     this.k = this.prop.k;
     this.getValue(true);
   }
-
   GradientProperty.prototype.comparePoints = function (values, points) {
     var i = 0;
     var len = this.o.length / 2;
     var diff;
-
     while (i < len) {
       diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
-
       if (diff > 0.01) {
         return false;
       }
-
       i += 1;
     }
-
     return true;
   };
-
   GradientProperty.prototype.checkCollapsable = function () {
     if (this.o.length / 2 !== this.c.length / 4) {
       return false;
     }
-
     if (this.data.k.k[0].s) {
       var i = 0;
       var len = this.data.k.k.length;
-
       while (i < len) {
         if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
           return false;
         }
-
         i += 1;
       }
     } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
       return false;
     }
-
     return true;
   };
-
   GradientProperty.prototype.getValue = function (forceRender) {
     this.prop.getValue();
     this._mdf = false;
     this._cmdf = false;
     this._omdf = false;
-
     if (this.prop._mdf || forceRender) {
       var i;
       var len = this.data.p * 4;
       var mult;
       var val;
-
       for (i = 0; i < len; i += 1) {
         mult = i % 4 === 0 ? 100 : 255;
         val = Math.round(this.prop.v[i] * mult);
-
         if (this.c[i] !== val) {
           this.c[i] = val;
           this._cmdf = !forceRender;
         }
       }
-
       if (this.o.length) {
         len = this.prop.v.length;
-
         for (i = this.data.p * 4; i < len; i += 1) {
           mult = i % 2 === 0 ? 100 : 1;
           val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
-
           if (this.o[i - this.data.p * 4] !== val) {
             this.o[i - this.data.p * 4] = val;
             this._omdf = !forceRender;
           }
         }
       }
-
       this._mdf = !forceRender;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], GradientProperty);
 
   function SVGGradientFillStyleData(elem, data, styleOb) {
@@ -9602,7 +8132,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.initGradientData(elem, data, styleOb);
   }
-
   SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
     this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
     this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
@@ -9620,7 +8149,6 @@
     this.setGradientOpacity(data, styleOb);
     this._isAnimated = !!this._isAnimated;
   };
-
   SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
     var gradientId = createElementID();
     var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
@@ -9632,18 +8160,15 @@
     var j;
     var jLen;
     jLen = data.g.p * 4;
-
     for (j = 0; j < jLen; j += 4) {
       stop = createNS('stop');
       gfill.appendChild(stop);
       stops.push(stop);
     }
-
     pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
     this.gf = gfill;
     this.cst = stops;
   };
-
   SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
     if (this.g._hasOpacity && !this.g._collapsable) {
       var stop;
@@ -9661,25 +8186,20 @@
       opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
       jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
       var stops = this.stops;
-
       for (j = data.g.p * 4; j < jLen; j += 2) {
         stop = createNS('stop');
         stop.setAttribute('stop-color', 'rgb(255,255,255)');
         opFill.appendChild(stop);
         stops.push(stop);
       }
-
       maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
@@ -9687,7 +8207,6 @@
       styleOb.msElem = maskElement;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
 
   function SVGGradientStrokeStyleData(elem, data, styleOb) {
@@ -9698,7 +8217,6 @@
     this.initGradientData(elem, data, styleOb);
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
 
   function ShapeGroupData() {
@@ -9721,77 +8239,59 @@
     if (length === 0) {
       return '';
     }
-
     var _o = pathNodes.o;
     var _i = pathNodes.i;
     var _v = pathNodes.v;
     var i;
     var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
-
     for (i = 1; i < length; i += 1) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
     }
-
     if (closed && length) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
       shapeString += 'z';
     }
-
     return shapeString;
   };
 
   var SVGElementsRenderer = function () {
     var _identityMatrix = new Matrix();
-
     var _matrixHelper = new Matrix();
-
     var ob = {
       createRenderFunction: createRenderFunction
     };
-
     function createRenderFunction(data) {
       switch (data.ty) {
         case 'fl':
           return renderFill;
-
         case 'gf':
           return renderGradient;
-
         case 'gs':
           return renderGradientStroke;
-
         case 'st':
           return renderStroke;
-
         case 'sh':
         case 'el':
         case 'rc':
         case 'sr':
           return renderPath;
-
         case 'tr':
           return renderContentTransform;
-
         case 'no':
           return renderNoop;
-
         default:
           return null;
       }
     }
-
     function renderContentTransform(styleData, itemData, isFirstFrame) {
       if (isFirstFrame || itemData.transform.op._mdf) {
         itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
       }
-
       if (isFirstFrame || itemData.transform.mProps._mdf) {
         itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
       }
     }
-
     function renderNoop() {}
-
     function renderPath(styleData, itemData, isFirstFrame) {
       var j;
       var jLen;
@@ -9805,25 +8305,20 @@
       var mat;
       var iterations;
       var k;
-
       for (l = 0; l < lLen; l += 1) {
         redraw = itemData.sh._mdf || isFirstFrame;
-
         if (itemData.styles[l].lvl < lvl) {
           mat = _matrixHelper.reset();
           iterations = lvl - itemData.styles[l].lvl;
           k = itemData.transformers.length - 1;
-
           while (!redraw && iterations > 0) {
             redraw = itemData.transformers[k].mProps._mdf || redraw;
             iterations -= 1;
             k -= 1;
           }
-
           if (redraw) {
             iterations = lvl - itemData.styles[l].lvl;
             k = itemData.transformers.length - 1;
-
             while (iterations > 0) {
               mat.multiply(itemData.transformers[k].mProps.v);
               iterations -= 1;
@@ -9833,115 +8328,90 @@
         } else {
           mat = _identityMatrix;
         }
-
         paths = itemData.sh.paths;
         jLen = paths._length;
-
         if (redraw) {
           pathStringTransformed = '';
-
           for (j = 0; j < jLen; j += 1) {
             pathNodes = paths.shapes[j];
-
             if (pathNodes && pathNodes._length) {
               pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
             }
           }
-
           itemData.caches[l] = pathStringTransformed;
         } else {
           pathStringTransformed = itemData.caches[l];
         }
-
         itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
         itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
       }
     }
-
     function renderFill(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
-
       if (itemData.c._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
       }
     }
-
     function renderGradientStroke(styleData, itemData, isFirstFrame) {
       renderGradient(styleData, itemData, isFirstFrame);
       renderStroke(styleData, itemData, isFirstFrame);
     }
-
     function renderGradient(styleData, itemData, isFirstFrame) {
       var gfill = itemData.gf;
       var hasOpacity = itemData.g._hasOpacity;
       var pt1 = itemData.s.v;
       var pt2 = itemData.e.v;
-
       if (itemData.o._mdf || isFirstFrame) {
         var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
         itemData.style.pElem.setAttribute(attr, itemData.o.v);
       }
-
       if (itemData.s._mdf || isFirstFrame) {
         var attr1 = styleData.t === 1 ? 'x1' : 'cx';
         var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
         gfill.setAttribute(attr1, pt1[0]);
         gfill.setAttribute(attr2, pt1[1]);
-
         if (hasOpacity && !itemData.g._collapsable) {
           itemData.of.setAttribute(attr1, pt1[0]);
           itemData.of.setAttribute(attr2, pt1[1]);
         }
       }
-
       var stops;
       var i;
       var len;
       var stop;
-
       if (itemData.g._cmdf || isFirstFrame) {
         stops = itemData.cst;
         var cValues = itemData.g.c;
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
           stop.setAttribute('offset', cValues[i * 4] + '%');
           stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
         }
       }
-
       if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
         var oValues = itemData.g.o;
-
         if (itemData.g._collapsable) {
           stops = itemData.cst;
         } else {
           stops = itemData.ost;
         }
-
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
-
           if (!itemData.g._collapsable) {
             stop.setAttribute('offset', oValues[i * 2] + '%');
           }
-
           stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
         }
       }
-
       if (styleData.t === 1) {
         if (itemData.e._mdf || isFirstFrame) {
           gfill.setAttribute('x2', pt2[0]);
           gfill.setAttribute('y2', pt2[1]);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('x2', pt2[0]);
             itemData.of.setAttribute('y2', pt2[1]);
@@ -9949,112 +8419,93 @@
         }
       } else {
         var rad;
-
         if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
           rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           gfill.setAttribute('r', rad);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('r', rad);
           }
         }
-
-        if (itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
           if (!rad) {
             rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           }
-
           var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
           var percent = itemData.h.v;
-
           if (percent >= 1) {
             percent = 0.99;
           } else if (percent <= -1) {
             percent = -0.99;
           }
-
           var dist = rad * percent;
           var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
           var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
           gfill.setAttribute('fx', x);
           gfill.setAttribute('fy', y);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('fx', x);
             itemData.of.setAttribute('fy', y);
           }
-        } // gfill.setAttribute('fy','200');
-
+        }
+        // gfill.setAttribute('fy','200');
       }
     }
-
     function renderStroke(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
       var d = itemData.d;
-
       if (d && (d._mdf || isFirstFrame) && d.dashStr) {
         styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
         styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
       }
-
       if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
         styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
       }
-
       if (itemData.w._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
-
         if (styleElem.msElem) {
           styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
         }
       }
     }
-
     return ob;
   }();
 
   function SVGShapeElement(data, globalData, comp) {
     // List of drawable elements
-    this.shapes = []; // Full shape data
-
-    this.shapesData = data.shapes; // List of styles that will be applied to shapes
-
-    this.stylesList = []; // List of modifiers that will be applied to shapes
-
-    this.shapeModifiers = []; // List of items in shape tree
-
-    this.itemsData = []; // List of items in previous shape tree
-
-    this.processedElements = []; // List of animated components
-
+    this.shapes = [];
+    // Full shape data
+    this.shapesData = data.shapes;
+    // List of styles that will be applied to shapes
+    this.stylesList = [];
+    // List of modifiers that will be applied to shapes
+    this.shapeModifiers = [];
+    // List of items in shape tree
+    this.itemsData = [];
+    // List of items in previous shape tree
+    this.processedElements = [];
+    // List of animated components
     this.animatedContents = [];
-    this.initElement(data, globalData, comp); // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.initElement(data, globalData, comp);
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
     // List of elements that have been created
-
-    this.prevViewData = []; // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.prevViewData = [];
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
-
   SVGShapeElement.prototype.initSecondaryElement = function () {};
-
   SVGShapeElement.prototype.identityMatrix = new Matrix();
-
   SVGShapeElement.prototype.buildExpressionInterface = function () {};
-
   SVGShapeElement.prototype.createContent = function () {
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
   };
+
   /*
   This method searches for multiple shapes that affect a single element and one of them is animated
   */
-
-
   SVGShapeElement.prototype.filterUniqueShapes = function () {
     var i;
     var len = this.shapes.length;
@@ -10064,42 +8515,34 @@
     var style;
     var tempShapes = [];
     var areAnimated = false;
-
     for (j = 0; j < jLen; j += 1) {
       style = this.stylesList[j];
       areAnimated = false;
       tempShapes.length = 0;
-
       for (i = 0; i < len; i += 1) {
         shape = this.shapes[i];
-
         if (shape.styles.indexOf(style) !== -1) {
           tempShapes.push(shape);
           areAnimated = shape._isAnimated || areAnimated;
         }
       }
-
       if (tempShapes.length > 1 && areAnimated) {
         this.setShapesAsAnimated(tempShapes);
       }
     }
   };
-
   SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
     var i;
     var len = shapes.length;
-
     for (i = 0; i < len; i += 1) {
       shapes[i].setAsAnimated();
     }
   };
-
   SVGShapeElement.prototype.createStyleElement = function (data, level) {
     // TODO: prevent drawing of hidden styles
     var elementData;
     var styleOb = new SVGStyleData(data, level);
     var pathElement = styleOb.pElem;
-
     if (data.ty === 'st') {
       elementData = new SVGStrokeStyleData(this, data, styleOb);
     } else if (data.ty === 'fl') {
@@ -10108,7 +8551,6 @@
       var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
       elementData = new GradientConstructor(this, data, styleOb);
       this.globalData.defs.appendChild(elementData.gf);
-
       if (elementData.maskId) {
         this.globalData.defs.appendChild(elementData.ms);
         this.globalData.defs.appendChild(elementData.of);
@@ -10117,66 +8559,51 @@
     } else if (data.ty === 'no') {
       elementData = new SVGNoStyleData(this, data, styleOb);
     }
-
     if (data.ty === 'st' || data.ty === 'gs') {
       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);
       }
     }
-
     if (data.r === 2) {
       pathElement.setAttribute('fill-rule', 'evenodd');
     }
-
     if (data.ln) {
       pathElement.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       pathElement.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     this.stylesList.push(styleOb);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createGroupElement = function (data) {
     var elementData = new ShapeGroupData();
-
     if (data.ln) {
       elementData.gr.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       elementData.gr.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     return elementData;
   };
-
   SVGShapeElement.prototype.createTransformElement = function (data, container) {
     var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
     var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
     var ty = 4;
-
     if (data.ty === 'rc') {
       ty = 5;
     } else if (data.ty === 'el') {
@@ -10184,7 +8611,6 @@
     } else if (data.ty === 'sr') {
       ty = 7;
     }
-
     var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
     var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
     this.shapes.push(elementData);
@@ -10192,58 +8618,46 @@
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
     var i = 0;
     var len = this.animatedContents.length;
-
     while (i < len) {
       if (this.animatedContents[i].element === element) {
         return;
       }
-
       i += 1;
     }
-
     this.animatedContents.push({
       fn: SVGElementsRenderer.createRenderFunction(data),
       element: element,
       data: data
     });
   };
-
   SVGShapeElement.prototype.setElementStyles = function (elementData) {
     var arr = elementData.styles;
     var j;
     var jLen = this.stylesList.length;
-
     for (j = 0; j < jLen; j += 1) {
-      if (!this.stylesList[j].closed) {
+      if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
         arr.push(this.stylesList[j]);
       }
     }
   };
-
   SVGShapeElement.prototype.reloadShapes = function () {
     this._isFirstFrame = true;
     var i;
     var len = this.itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       this.prevViewData[i] = this.itemsData[i];
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
     len = this.dynamicProperties.length;
-
     for (i = 0; i < len; i += 1) {
       this.dynamicProperties[i].getValue();
     }
-
     this.renderModifiers();
   };
-
   SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
     var ownTransformers = [].concat(transformers);
     var i;
@@ -10255,43 +8669,35 @@
     var currentTransform;
     var modifier;
     var processedPos;
-
     for (i = len; i >= 0; i -= 1) {
       processedPos = this.searchProcessedElement(arr[i]);
-
       if (!processedPos) {
         arr[i]._render = render;
       } else {
         itemsData[i] = prevViewData[processedPos - 1];
       }
-
       if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
         if (!processedPos) {
           itemsData[i] = this.createStyleElement(arr[i], level);
         } else {
-          itemsData[i].style.closed = false;
+          itemsData[i].style.closed = arr[i].hd;
         }
-
         if (arr[i]._render) {
           if (itemsData[i].style.pElem.parentNode !== container) {
             container.appendChild(itemsData[i].style.pElem);
           }
         }
-
         ownStyles.push(itemsData[i].style);
       } else if (arr[i].ty === 'gr') {
         if (!processedPos) {
           itemsData[i] = this.createGroupElement(arr[i]);
         } else {
           jLen = itemsData[i].it.length;
-
           for (j = 0; j < jLen; j += 1) {
             itemsData[i].prevViewData[j] = itemsData[i].it[j];
           }
         }
-
         this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
-
         if (arr[i]._render) {
           if (itemsData[i].gr.parentNode !== container) {
             container.appendChild(itemsData[i].gr);
@@ -10301,14 +8707,12 @@
         if (!processedPos) {
           itemsData[i] = this.createTransformElement(arr[i], container);
         }
-
         currentTransform = itemsData[i].transform;
         ownTransformers.push(currentTransform);
       } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
         if (!processedPos) {
           itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
         }
-
         this.setElementStyles(itemsData[i]);
       } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
         if (!processedPos) {
@@ -10320,7 +8724,6 @@
           modifier = itemsData[i];
           modifier.closed = false;
         }
-
         ownModifiers.push(modifier);
       } else if (arr[i].ty === 'rp') {
         if (!processedPos) {
@@ -10333,64 +8736,49 @@
           modifier = itemsData[i];
           modifier.closed = true;
         }
-
         ownModifiers.push(modifier);
       }
-
       this.addProcessedElement(arr[i], i + 1);
     }
-
     len = ownStyles.length;
-
     for (i = 0; i < len; i += 1) {
       ownStyles[i].closed = true;
     }
-
     len = ownModifiers.length;
-
     for (i = 0; i < len; i += 1) {
       ownModifiers[i].closed = true;
     }
   };
-
   SVGShapeElement.prototype.renderInnerContent = function () {
     this.renderModifiers();
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       this.stylesList[i].reset();
     }
-
     this.renderShape();
-
     for (i = 0; i < len; i += 1) {
       if (this.stylesList[i]._mdf || this._isFirstFrame) {
         if (this.stylesList[i].msElem) {
-          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d); // Adding M0 0 fixes same mask bug on all browsers
-
+          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+          // Adding M0 0 fixes same mask bug on all browsers
           this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
         }
-
         this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
       }
     }
   };
-
   SVGShapeElement.prototype.renderShape = function () {
     var i;
     var len = this.animatedContents.length;
     var animatedContent;
-
     for (i = 0; i < len; i += 1) {
       animatedContent = this.animatedContents[i];
-
       if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
         animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
       }
     }
   };
-
   SVGShapeElement.prototype.destroy = function () {
     this.destroyBaseElement();
     this.shapesData = null;
@@ -10413,7 +8801,6 @@
       p: true
     };
   }
-
   LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
     this._mdf.o = false;
     this._mdf.sw = false;
@@ -10422,43 +8809,36 @@
     this._mdf.m = false;
     this._mdf.p = false;
     var updated = false;
-
     if (this.o !== o) {
       this.o = o;
       this._mdf.o = true;
       updated = true;
     }
-
     if (this.sw !== sw) {
       this.sw = sw;
       this._mdf.sw = true;
       updated = true;
     }
-
     if (this.sc !== sc) {
       this.sc = sc;
       this._mdf.sc = true;
       updated = true;
     }
-
     if (this.fc !== fc) {
       this.fc = fc;
       this._mdf.fc = true;
       updated = true;
     }
-
     if (this.m !== m) {
       this.m = m;
       this._mdf.m = true;
       updated = true;
     }
-
     if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
       this.p = p;
       this._mdf.p = true;
       updated = true;
     }
-
     return updated;
   };
 
@@ -10469,11 +8849,9 @@
     this.kf = false;
     this._isFirstFrame = true;
     this._mdf = false;
-
     if (data.d && data.d.sid) {
       data.d = elem.globalData.slotManager.getProp(data.d);
     }
-
     this.data = data;
     this.elem = elem;
     this.comp = this.elem.comp;
@@ -10512,73 +8890,57 @@
       __complete: false
     };
     this.copyData(this.currentData, this.data.d.k[0].s);
-
     if (!this.searchProperty()) {
       this.completeTextData(this.currentData);
     }
   }
-
   TextProperty.prototype.defaultBoxWidth = [0, 0];
-
   TextProperty.prototype.copyData = function (obj, data) {
     for (var s in data) {
       if (Object.prototype.hasOwnProperty.call(data, s)) {
         obj[s] = data[s];
       }
     }
-
     return obj;
   };
-
   TextProperty.prototype.setCurrentData = function (data) {
     if (!data.__complete) {
       this.completeTextData(data);
     }
-
     this.currentData = data;
     this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
     this._mdf = true;
   };
-
   TextProperty.prototype.searchProperty = function () {
     return this.searchKeyframes();
   };
-
   TextProperty.prototype.searchKeyframes = function () {
     this.kf = this.data.d.k.length > 1;
-
     if (this.kf) {
       this.addEffect(this.getKeyframeValue.bind(this));
     }
-
     return this.kf;
   };
-
   TextProperty.prototype.addEffect = function (effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.getValue = function (_finalValue) {
     if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
       return;
     }
-
     this.currentData.t = this.data.d.k[this.keysIndex].s.t;
     var currentValue = this.currentData;
     var currentIndex = this.keysIndex;
-
     if (this.lock) {
       this.setCurrentData(this.currentData);
       return;
     }
-
     this.lock = true;
     this._mdf = false;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
-
     for (i = 0; i < len; i += 1) {
       // Checking if index changed to prevent creating a new object every time the expression updates.
       if (currentIndex !== this.keysIndex) {
@@ -10587,38 +8949,30 @@
         finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
       }
     }
-
     if (currentValue !== finalValue) {
       this.setCurrentData(finalValue);
     }
-
     this.v = this.currentData;
     this.pv = this.v;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   };
-
   TextProperty.prototype.getKeyframeValue = function () {
     var textKeys = this.data.d.k;
     var frameNum = this.elem.comp.renderedFrame;
     var i = 0;
     var len = textKeys.length;
-
     while (i <= len - 1) {
       if (i === len - 1 || textKeys[i + 1].t > frameNum) {
         break;
       }
-
       i += 1;
     }
-
     if (this.keysIndex !== i) {
       this.keysIndex = i;
     }
-
     return this.data.d.k[this.keysIndex].s;
   };
-
   TextProperty.prototype.buildFinalText = function (text) {
     var charactersArray = [];
     var i = 0;
@@ -10628,21 +8982,20 @@
     var shouldCombine = false;
     var shouldCombineNext = false;
     var currentChars = '';
-
     while (i < len) {
       shouldCombine = shouldCombineNext;
       shouldCombineNext = false;
       charCode = text.charCodeAt(i);
       currentChars = text.charAt(i);
-
       if (FontManager.isCombinedCharacter(charCode)) {
-        shouldCombine = true; // It's a potential surrogate pair (this is the High surrogate)
+        shouldCombine = true;
+        // It's a potential surrogate pair (this is the High surrogate)
       } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
         if (FontManager.isRegionalFlag(text, i)) {
           currentChars = text.substr(i, 14);
         } else {
-          secondCharCode = text.charCodeAt(i + 1); // It's a surrogate pair (this is the Low surrogate)
-
+          secondCharCode = text.charCodeAt(i + 1);
+          // It's a surrogate pair (this is the Low surrogate)
           if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
             if (FontManager.isModifier(charCode, secondCharCode)) {
               currentChars = text.substr(i, 2);
@@ -10656,7 +9009,6 @@
         }
       } else if (charCode > 0xDBFF) {
         secondCharCode = text.charCodeAt(i + 1);
-
         if (FontManager.isVariationSelector(charCode)) {
           shouldCombine = true;
         }
@@ -10664,20 +9016,16 @@
         shouldCombine = true;
         shouldCombineNext = true;
       }
-
       if (shouldCombine) {
         charactersArray[charactersArray.length - 1] += currentChars;
         shouldCombine = false;
       } else {
         charactersArray.push(currentChars);
       }
-
       i += currentChars.length;
     }
-
     return charactersArray;
   };
-
   TextProperty.prototype.completeTextData = function (documentData) {
     documentData.__complete = true;
     var fontManager = this.elem.globalData.fontManager;
@@ -10709,14 +9057,12 @@
     documentData.finalLineHeight = documentData.lh;
     var trackingOffset = documentData.tr / 1000 * documentData.finalSize;
     var charCode;
-
     if (documentData.sz) {
       var flag = true;
       var boxWidth = documentData.sz[0];
       var boxHeight = documentData.sz[1];
       var currentHeight;
       var finalText;
-
       while (flag) {
         finalText = this.buildFinalText(documentData.t);
         currentHeight = 0;
@@ -10724,11 +9070,9 @@
         len = finalText.length;
         trackingOffset = documentData.tr / 1000 * documentData.finalSize;
         var lastSpaceIndex = -1;
-
         for (i = 0; i < len; i += 1) {
           charCode = finalText[i].charCodeAt(0);
           newLineFlag = false;
-
           if (finalText[i] === ' ') {
             lastSpaceIndex = i;
           } else if (charCode === 13 || charCode === 3) {
@@ -10736,7 +9080,6 @@
             newLineFlag = true;
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
           }
-
           if (fontManager.chars) {
             charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
             cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -10744,17 +9087,15 @@
             // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
             cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
           }
-
           if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
             if (lastSpaceIndex === -1) {
               len += 1;
             } else {
               i = lastSpaceIndex;
             }
-
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
-            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r'); // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
-
+            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+            // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
             lastSpaceIndex = -1;
             lineWidth = 0;
           } else {
@@ -10762,9 +9103,7 @@
             lineWidth += trackingOffset;
           }
         }
-
         currentHeight += fontData.ascent * documentData.finalSize / 100;
-
         if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
           documentData.finalSize -= 1;
           documentData.finalLineHeight = documentData.finalSize * documentData.lh / documentData.s;
@@ -10775,17 +9114,14 @@
         }
       }
     }
-
     lineWidth = -trackingOffset;
     cLength = 0;
     var uncollapsedSpaces = 0;
     var currentChar;
-
     for (i = 0; i < len; i += 1) {
       newLineFlag = false;
       currentChar = documentData.finalText[i];
       charCode = currentChar.charCodeAt(0);
-
       if (charCode === 13 || charCode === 3) {
         uncollapsedSpaces = 0;
         lineWidths.push(lineWidth);
@@ -10797,7 +9133,6 @@
       } else {
         val = currentChar;
       }
-
       if (fontManager.chars) {
         charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
         cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -10805,16 +9140,15 @@
         // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
         // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
         cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
-      } //
+      }
 
-
+      //
       if (currentChar === ' ') {
         uncollapsedSpaces += cLength + trackingOffset;
       } else {
         lineWidth += cLength + trackingOffset + uncollapsedSpaces;
         uncollapsedSpaces = 0;
       }
-
       letters.push({
         l: cLength,
         an: cLength,
@@ -10825,42 +9159,35 @@
         line: currentLine,
         animatorJustifyOffset: 0
       });
-
       if (anchorGrouping == 2) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || val === ' ' || i === len - 1) {
           if (val === '' || val === ' ') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           index += 1;
           currentSize = 0;
         }
       } else if (anchorGrouping == 3) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || i === len - 1) {
           if (val === '') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           currentSize = 0;
           index += 1;
         }
@@ -10870,31 +9197,25 @@
         index += 1;
       }
     }
-
     documentData.l = letters;
     maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
     lineWidths.push(lineWidth);
-
     if (documentData.sz) {
       documentData.boxWidth = documentData.sz[0];
       documentData.justifyOffset = 0;
     } else {
       documentData.boxWidth = maxLineWidth;
-
       switch (documentData.j) {
         case 1:
           documentData.justifyOffset = -documentData.boxWidth;
           break;
-
         case 2:
           documentData.justifyOffset = -documentData.boxWidth / 2;
           break;
-
         default:
           documentData.justifyOffset = 0;
       }
     }
-
     documentData.lineWidths = lineWidths;
     var animators = data.a;
     var animatorData;
@@ -10903,63 +9224,49 @@
     var based;
     var ind;
     var indexes = [];
-
     for (j = 0; j < jLen; j += 1) {
       animatorData = animators[j];
-
       if (animatorData.a.sc) {
         documentData.strokeColorAnim = true;
       }
-
       if (animatorData.a.sw) {
         documentData.strokeWidthAnim = true;
       }
-
       if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
         documentData.fillColorAnim = true;
       }
-
       ind = 0;
       based = animatorData.s.b;
-
       for (i = 0; i < len; i += 1) {
         letterData = letters[i];
         letterData.anIndexes[j] = ind;
-
         if (based == 1 && letterData.val !== '' || based == 2 && letterData.val !== '' && letterData.val !== ' ' || based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1) || based == 4 && (letterData.n || i == len - 1)) {
           // eslint-disable-line eqeqeq
           if (animatorData.s.rn === 1) {
             indexes.push(ind);
           }
-
           ind += 1;
         }
       }
-
       data.a[j].s.totalChars = ind;
       var currentInd = -1;
       var newInd;
-
       if (animatorData.s.rn === 1) {
         for (i = 0; i < len; i += 1) {
           letterData = letters[i];
-
           if (currentInd != letterData.anIndexes[j]) {
             // eslint-disable-line eqeqeq
             currentInd = letterData.anIndexes[j];
             newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
           }
-
           letterData.anIndexes[j] = newInd;
         }
       }
     }
-
     documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
     documentData.ls = documentData.ls || 0;
     documentData.ascent = fontData.ascent * documentData.finalSize / 100;
   };
-
   TextProperty.prototype.updateDocumentData = function (newData, index) {
     index = index === undefined ? this.keysIndex : index;
     var dData = this.copyData({}, this.data.d.k[index].s);
@@ -10969,7 +9276,6 @@
     this.setCurrentData(dData);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.recalculate = function (index) {
     var dData = this.data.d.k[index].s;
     dData.__complete = false;
@@ -10977,13 +9283,11 @@
     this._isFirstFrame = true;
     this.getValue(dData);
   };
-
   TextProperty.prototype.canResizeFont = function (_canResize) {
     this.canResize = _canResize;
     this.recalculate(this.keysIndex);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
     this.minimumFontSize = Math.floor(_fontValue) || 1;
     this.recalculate(this.keysIndex);
@@ -10994,7 +9298,6 @@
     var max = Math.max;
     var min = Math.min;
     var floor = Math.floor;
-
     function TextSelectorPropFactory(elem, data) {
       this._currentTextLength = -1;
       this.k = false;
@@ -11007,7 +9310,6 @@
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: 0
       }, 0, 0, this);
-
       if ('e' in data) {
         this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
       } else {
@@ -11015,7 +9317,6 @@
           v: 100
         };
       }
-
       this.o = PropertyFactory.getProp(elem, data.o || {
         k: 0
       }, 0, 0, this);
@@ -11029,48 +9330,40 @@
         k: 100
       }, 0, 0, this);
       this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
-
       if (!this.dynamicProperties.length) {
         this.getValue();
       }
     }
-
     TextSelectorPropFactory.prototype = {
       getMult: function getMult(ind) {
         if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
           this.getValue();
         }
-
         var x1 = 0;
         var y1 = 0;
         var x2 = 1;
         var y2 = 1;
-
         if (this.ne.v > 0) {
           x1 = this.ne.v / 100.0;
         } else {
           y1 = -this.ne.v / 100.0;
         }
-
         if (this.xe.v > 0) {
           x2 = 1.0 - this.xe.v / 100.0;
         } else {
           y2 = 1.0 + this.xe.v / 100.0;
         }
-
         var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
         var mult = 0;
         var s = this.finalS;
         var e = this.finalE;
         var type = this.data.sh;
-
         if (type === 2) {
           if (e === s) {
             mult = ind >= e ? 1 : 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 3) {
           if (e === s) {
@@ -11078,21 +9371,18 @@
           } else {
             mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 4) {
           if (e === s) {
             mult = 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
-
             if (mult < 0.5) {
               mult *= 2;
             } else {
               mult = 1 - 2 * (mult - 0.5);
             }
           }
-
           mult = easer(mult);
         } else if (type === 5) {
           if (e === s) {
@@ -11101,13 +9391,11 @@
             var tot = e - s;
             /* ind += 0.5;
                       mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
-
             ind = min(max(0, ind + 0.5 - s), e - s);
             var x = -tot / 2 + ind;
             var a = tot / 2;
             mult = Math.sqrt(1 - x * x / (a * a));
           }
-
           mult = easer(mult);
         } else if (type === 6) {
           if (e === s) {
@@ -11116,7 +9404,6 @@
             ind = min(max(0, ind + 0.5 - s), e - s);
             mult = (1 + Math.cos(Math.PI + Math.PI * 2 * ind / (e - s))) / 2; // eslint-disable-line
           }
-
           mult = easer(mult);
         } else {
           if (ind >= floor(s)) {
@@ -11126,9 +9413,9 @@
               mult = max(0, min(e - ind, 1));
             }
           }
-
           mult = easer(mult);
-        } // Smoothness implementation.
+        }
+        // Smoothness implementation.
         // The smoothness represents a reduced range of the original [0; 1] range.
         // if smoothness is 25%, the new range will be [0.375; 0.625]
         // Steps are:
@@ -11138,60 +9425,47 @@
         //     - subtract the threshold
         //     - divide it by the smoothness (this will return the range to [0; 1])
         // Note: If it doesn't work on some scenarios, consider applying it before the easer.
-
-
         if (this.sm.v !== 100) {
           var smoothness = this.sm.v * 0.01;
-
           if (smoothness === 0) {
             smoothness = 0.00000001;
           }
-
           var threshold = 0.5 - smoothness * 0.5;
-
           if (mult < threshold) {
             mult = 0;
           } else {
             mult = (mult - threshold) / smoothness;
-
             if (mult > 1) {
               mult = 1;
             }
           }
         }
-
         return mult * this.a.v;
       },
       getValue: function getValue(newCharsFlag) {
         this.iterateDynamicProperties();
         this._mdf = newCharsFlag || this._mdf;
         this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
-
         if (newCharsFlag && this.data.r === 2) {
           this.e.v = this._currentTextLength;
         }
-
         var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
         var o = this.o.v / divisor;
         var s = this.s.v / divisor + o;
         var e = this.e.v / divisor + o;
-
         if (s > e) {
           var _s = s;
           s = e;
           e = _s;
         }
-
         this.finalS = s;
         this.finalE = e;
       }
     };
     extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
-
     function getTextSelectorProp(elem, data, arr) {
       return new TextSelectorPropFactory(elem, data, arr);
     }
-
     return {
       getTextSelectorProp: getTextSelectorProp
     };
@@ -11241,18 +9515,15 @@
     this.lettersChangedFlag = false;
     this.initDynamicPropertyContainer(elem);
   }
-
   TextAnimatorProperty.prototype.searchProperties = function () {
     var i;
     var len = this._textData.a.length;
     var animatorProps;
     var getProp = PropertyFactory.getProp;
-
     for (i = 0; i < len; i += 1) {
       animatorProps = this._textData.a[i];
       this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
     }
-
     if (this._textData.p && 'm' in this._textData.p) {
       this._pathData = {
         a: getProp(this._elem, this._textData.p.a, 0, 0, this),
@@ -11266,17 +9537,13 @@
     } else {
       this._hasMaskedPath = false;
     }
-
     this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
   };
-
   TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
     this.lettersChangedFlag = lettersChangedFlag;
-
     if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
       return;
     }
-
     this._isFirstFrame = false;
     var alignment = this._moreOptions.alignment.v;
     var animators = this._animatorsData;
@@ -11304,18 +9571,14 @@
     var perc;
     var tanAngle;
     var mask;
-
     if (this._hasMaskedPath) {
       mask = this._pathData.m;
-
       if (!this._pathData.n || this._pathData._mdf) {
         var paths = mask.v;
-
         if (this._pathData.r.v) {
           paths = paths.reverse();
-        } // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
-
-
+        }
+        // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
         pathInfo = {
           tLength: 0,
           segments: []
@@ -11323,26 +9586,21 @@
         len = paths._length - 1;
         var bezierData;
         totalLength = 0;
-
         for (i = 0; i < len; i += 1) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[i + 1], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         i = len;
-
         if (mask.v.c) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[0], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         this._pathData.pi = pathInfo;
       }
-
       pathInfo = this._pathData.pi;
       currentLength = this._pathData.f.v;
       segmentInd = 0;
@@ -11350,20 +9608,16 @@
       segmentLength = 0;
       flag = true;
       segments = pathInfo.segments;
-
       if (currentLength < 0 && mask.v.c) {
         if (pathInfo.tLength < Math.abs(currentLength)) {
           currentLength = -Math.abs(currentLength) % pathInfo.tLength;
         }
-
         segmentInd = segments.length - 1;
         points = segments[segmentInd].points;
         pointInd = points.length - 1;
-
         while (currentLength < 0) {
           currentLength += points[pointInd].partialLength;
           pointInd -= 1;
-
           if (pointInd < 0) {
             segmentInd -= 1;
             points = segments[segmentInd].points;
@@ -11371,13 +9625,11 @@
           }
         }
       }
-
       points = segments[segmentInd].points;
       prevPoint = points[pointInd - 1];
       currentPoint = points[pointInd];
       partialLength = currentPoint.partialLength;
     }
-
     len = letters.length;
     xPos = 0;
     yPos = 0;
@@ -11408,40 +9660,35 @@
     var letterFc;
     var letterM = '';
     var letterP = this.defaultPropsArray;
-    var letterO; //
+    var letterO;
 
+    //
     if (documentData.j === 2 || documentData.j === 1) {
       var animatorJustifyOffset = 0;
       var animatorFirstCharOffset = 0;
       var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
       var lastIndex = 0;
       var isNewLine = true;
-
       for (i = 0; i < len; i += 1) {
         if (letters[i].n) {
           if (animatorJustifyOffset) {
             animatorJustifyOffset += animatorFirstCharOffset;
           }
-
           while (lastIndex < i) {
             letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
             lastIndex += 1;
           }
-
           animatorJustifyOffset = 0;
           isNewLine = true;
         } else {
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.t.propType) {
               if (isNewLine && documentData.j === 2) {
                 animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
               }
-
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
               } else {
@@ -11449,33 +9696,28 @@
               }
             }
           }
-
           isNewLine = false;
         }
       }
-
       if (animatorJustifyOffset) {
         animatorJustifyOffset += animatorFirstCharOffset;
       }
-
       while (lastIndex < i) {
         letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
         lastIndex += 1;
       }
-    } //
-
+    }
+    //
 
     for (i = 0; i < len; i += 1) {
       matrixHelper.reset();
       elemOpacity = 1;
-
       if (letters[i].n) {
         xPos = 0;
         yPos += documentData.yOffset;
         yPos += firstLine ? 1 : 0;
         currentLength = initPathPos;
         firstLine = false;
-
         if (this._hasMaskedPath) {
           segmentInd = initSegmentInd;
           pointInd = initPointInd;
@@ -11485,7 +9727,6 @@
           partialLength = currentPoint.partialLength;
           segmentLength = 0;
         }
-
         letterM = '';
         letterFc = '';
         letterSw = '';
@@ -11498,48 +9739,37 @@
               case 1:
                 currentLength += totalLength - documentData.lineWidths[letters[i].line];
                 break;
-
               case 2:
                 currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
                 break;
-
               default:
                 break;
             }
-
             currentLine = letters[i].line;
           }
-
           if (ind !== letters[i].ind) {
             if (letters[ind]) {
               currentLength += letters[ind].extra;
             }
-
             currentLength += letters[i].an / 2;
             ind = letters[i].ind;
           }
-
           currentLength += alignment[0] * letters[i].an * 0.005;
           var animatorOffset = 0;
-
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.p.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.p.v[0] * mult[0];
               } else {
                 animatorOffset += animatorProps.p.v[0] * mult;
               }
             }
-
             if (animatorProps.a.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.a.v[0] * mult[0];
               } else {
@@ -11547,14 +9777,12 @@
               }
             }
           }
-
-          flag = true; // Force alignment only works with a single line for now
-
+          flag = true;
+          // Force alignment only works with a single line for now
           if (this._pathData.a.v) {
             currentLength = letters[0].an * 0.5 + (totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind / (len - 1);
             currentLength += this._pathData.f.v;
           }
-
           while (flag) {
             if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
               perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
@@ -11565,11 +9793,9 @@
             } else if (points) {
               segmentLength += currentPoint.partialLength;
               pointInd += 1;
-
               if (pointInd >= points.length) {
                 pointInd = 0;
                 segmentInd += 1;
-
                 if (!segments[segmentInd]) {
                   if (mask.v.c) {
                     pointInd = 0;
@@ -11583,7 +9809,6 @@
                   points = segments[segmentInd].points;
                 }
               }
-
               if (points) {
                 prevPoint = currentPoint;
                 currentPoint = points[pointInd];
@@ -11591,23 +9816,21 @@
               }
             }
           }
-
           offf = letters[i].an / 2 - letters[i].add;
           matrixHelper.translate(-offf, 0, 0);
         } else {
           offf = letters[i].an / 2 - letters[i].add;
-          matrixHelper.translate(-offf, 0, 0); // Grouping alignment
+          matrixHelper.translate(-offf, 0, 0);
 
+          // Grouping alignment
           matrixHelper.translate(-alignment[0] * letters[i].an * 0.005, -alignment[1] * yOff * 0.01, 0);
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.t.propType) {
             animatorSelector = animators[j].s;
-            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars); // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
-
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
             if (xPos !== 0 || documentData.j !== 0) {
               if (this._hasMaskedPath) {
                 if (mult.length) {
@@ -11623,11 +9846,9 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           sw = documentData.sw || 0;
         }
-
         if (documentData.strokeColorAnim) {
           if (documentData.sc) {
             sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
@@ -11635,18 +9856,14 @@
             sc = [0, 0, 0];
           }
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.a.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
             } else {
@@ -11654,14 +9871,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.s.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.scale(1 + (animatorProps.s.v[0] - 1) * mult[0], 1 + (animatorProps.s.v[1] - 1) * mult[1], 1);
             } else {
@@ -11669,12 +9883,10 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
           animatorSelector = animators[j].s;
           mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
           if (animatorProps.sk.propType) {
             if (mult.length) {
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
@@ -11682,7 +9894,6 @@
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
             }
           }
-
           if (animatorProps.r.propType) {
             if (mult.length) {
               matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
@@ -11690,7 +9901,6 @@
               matrixHelper.rotateZ(-animatorProps.r.v * mult);
             }
           }
-
           if (animatorProps.ry.propType) {
             if (mult.length) {
               matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
@@ -11698,7 +9908,6 @@
               matrixHelper.rotateY(animatorProps.ry.v * mult);
             }
           }
-
           if (animatorProps.rx.propType) {
             if (mult.length) {
               matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
@@ -11706,7 +9915,6 @@
               matrixHelper.rotateX(animatorProps.rx.v * mult);
             }
           }
-
           if (animatorProps.o.propType) {
             if (mult.length) {
               elemOpacity += (animatorProps.o.v * mult[0] - elemOpacity) * mult[0];
@@ -11714,7 +9922,6 @@
               elemOpacity += (animatorProps.o.v * mult - elemOpacity) * mult;
             }
           }
-
           if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
             if (mult.length) {
               sw += animatorProps.sw.v * mult[0];
@@ -11722,7 +9929,6 @@
               sw += animatorProps.sw.v * mult;
             }
           }
-
           if (documentData.strokeColorAnim && animatorProps.sc.propType) {
             for (k = 0; k < 3; k += 1) {
               if (mult.length) {
@@ -11732,7 +9938,6 @@
               }
             }
           }
-
           if (documentData.fillColorAnim && documentData.fc) {
             if (animatorProps.fc.propType) {
               for (k = 0; k < 3; k += 1) {
@@ -11743,7 +9948,6 @@
                 }
               }
             }
-
             if (animatorProps.fh.propType) {
               if (mult.length) {
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
@@ -11751,7 +9955,6 @@
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult);
               }
             }
-
             if (animatorProps.fs.propType) {
               if (mult.length) {
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
@@ -11759,7 +9962,6 @@
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
               }
             }
-
             if (animatorProps.fb.propType) {
               if (mult.length) {
                 fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
@@ -11769,14 +9971,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.p.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (this._hasMaskedPath) {
               if (mult.length) {
                 matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
@@ -11790,68 +9989,53 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           letterSw = sw < 0 ? 0 : sw;
         }
-
         if (documentData.strokeColorAnim) {
           letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
         }
-
         if (this._hasMaskedPath) {
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(0, alignment[1] * yOff * 0.01 + yPos, 0);
-
           if (this._pathData.p.v) {
             tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
             var rot = Math.atan(tanAngle) * 180 / Math.PI;
-
             if (currentPoint.point[0] < prevPoint.point[0]) {
               rot += 180;
             }
-
             matrixHelper.rotate(-rot * Math.PI / 180);
           }
-
           matrixHelper.translate(xPathPos, yPathPos, 0);
           currentLength -= alignment[0] * letters[i].an * 0.005;
-
           if (letters[i + 1] && ind !== letters[i + 1].ind) {
             currentLength += letters[i].an / 2;
             currentLength += documentData.tr * 0.001 * documentData.finalSize;
           }
         } else {
           matrixHelper.translate(xPos, yPos, 0);
-
           if (documentData.ps) {
             // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
             matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
           }
-
           switch (documentData.j) {
             case 1:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
               break;
-
             case 2:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
               break;
-
             default:
               break;
           }
-
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(offf, 0, 0);
           matrixHelper.translate(alignment[0] * letters[i].an * 0.005, alignment[1] * yOff * 0.01, 0);
           xPos += letters[i].l + documentData.tr * 0.001 * documentData.finalSize;
         }
-
         if (renderType === 'html') {
           letterM = matrixHelper.toCSS();
         } else if (renderType === 'svg') {
@@ -11859,10 +10043,8 @@
         } else {
           letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
         }
-
         letterO = elemOpacity;
       }
-
       if (renderedLettersCount <= i) {
         letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
         this.renderedLetters.push(letterValue);
@@ -11874,22 +10056,18 @@
       }
     }
   };
-
   TextAnimatorProperty.prototype.getValue = function () {
     if (this._elem.globalData.frameId === this._frameId) {
       return;
     }
-
     this._frameId = this._elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   TextAnimatorProperty.prototype.mHelper = new Matrix();
   TextAnimatorProperty.prototype.defaultPropsArray = [];
   extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
 
   function ITextElement() {}
-
   ITextElement.prototype.initElement = function (data, globalData, comp) {
     this.lettersChangedFlag = true;
     this.initFrame();
@@ -11906,72 +10084,55 @@
     this.hide();
     this.textAnimator.searchProperties(this.dynamicProperties);
   };
-
   ITextElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
   };
-
   ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
     var j;
     var jLen = shapes.length;
     var pathNodes;
     var shapeStr = '';
-
     for (j = 0; j < jLen; j += 1) {
       if (shapes[j].ty === 'sh') {
         pathNodes = shapes[j].ks.k;
         shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
       }
     }
-
     return shapeStr;
   };
-
   ITextElement.prototype.updateDocumentData = function (newData, index) {
     this.textProperty.updateDocumentData(newData, index);
   };
-
   ITextElement.prototype.canResizeFont = function (_canResize) {
     this.textProperty.canResizeFont(_canResize);
   };
-
   ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
     this.textProperty.setMinimumFontSize(_fontSize);
   };
-
   ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
     if (documentData.ps) {
       matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
     }
-
     matrixHelper.translate(0, -documentData.ls, 0);
-
     switch (documentData.j) {
       case 1:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
         break;
-
       case 2:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
         break;
-
       default:
         break;
     }
-
     matrixHelper.translate(xPos, yPos, 0);
   };
-
   ITextElement.prototype.buildColor = function (colorData) {
     return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
   };
-
   ITextElement.prototype.emptyProp = new LetterProps();
-
   ITextElement.prototype.destroy = function () {};
-
   ITextElement.prototype.validateText = function () {
     if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
       this.buildNewText();
@@ -11983,27 +10144,22 @@
   var emptyShapeData = {
     shapes: []
   };
-
   function SVGTextLottieElement(data, globalData, comp) {
     this.textSpans = [];
     this.renderType = 'svg';
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
-
   SVGTextLottieElement.prototype.createContent = function () {
     if (this.data.singleShape && !this.globalData.fontManager.chars) {
       this.textContainer = createNS('text');
     }
   };
-
   SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
     var i = 0;
     var len = textArray.length;
     var textContents = [];
     var currentTextContent = '';
-
     while (i < len) {
       if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
         textContents.push(currentTextContent);
@@ -12011,14 +10167,11 @@
       } else {
         currentTextContent += textArray[i];
       }
-
       i += 1;
     }
-
     textContents.push(currentTextContent);
     return textContents;
   };
-
   SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
     // data should probably be cloned to apply scale separately to each instance of a text on different layers
     // but since text internal content gets only rendered once and then it's never rerendered,
@@ -12026,41 +10179,33 @@
     // Avoiding cloning is preferred since cloning each character shape data is expensive
     if (data.shapes && data.shapes.length) {
       var shape = data.shapes[0];
-
       if (shape.it) {
         var shapeItem = shape.it[shape.it.length - 1];
-
         if (shapeItem.s) {
           shapeItem.s.k[0] = scale;
           shapeItem.s.k[1] = scale;
         }
       }
     }
-
     return data;
   };
-
   SVGTextLottieElement.prototype.buildNewText = function () {
     this.addDynamicProperty(this);
     var i;
     var len;
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
-
     if (documentData.fc) {
       this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
     } else {
       this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
     }
-
     if (documentData.sc) {
       this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
       this.layerElement.setAttribute('stroke-width', documentData.sw);
     }
-
     this.layerElement.setAttribute('font-size', documentData.finalSize);
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
-
     if (fontData.fClass) {
       this.layerElement.setAttribute('class', fontData.fClass);
     } else {
@@ -12070,7 +10215,6 @@
       this.layerElement.setAttribute('font-style', fStyle);
       this.layerElement.setAttribute('font-weight', fWeight);
     }
-
     this.layerElement.setAttribute('aria-label', documentData.t);
     var letters = documentData.l || [];
     var usesGlyphs = !!this.globalData.fontManager.chars;
@@ -12083,31 +10227,25 @@
     var yPos = 0;
     var firstLine = true;
     var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
-
     if (singleShape && !usesGlyphs && !documentData.sz) {
       var tElement = this.textContainer;
       var justify = 'start';
-
       switch (documentData.j) {
         case 1:
           justify = 'end';
           break;
-
         case 2:
           justify = 'middle';
           break;
-
         default:
           justify = 'start';
           break;
       }
-
       tElement.setAttribute('text-anchor', justify);
       tElement.setAttribute('letter-spacing', trackingOffset);
       var textContent = this.buildTextContents(documentData.finalText);
       len = textContent.length;
       yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
-
       for (i = 0; i < len; i += 1) {
         tSpan = this.textSpans[i].span || createNS('tspan');
         tSpan.textContent = textContent[i];
@@ -12115,23 +10253,19 @@
         tSpan.setAttribute('y', yPos);
         tSpan.style.display = 'inherit';
         tElement.appendChild(tSpan);
-
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
             span: null,
             glyph: null
           };
         }
-
         this.textSpans[i].span = tSpan;
         yPos += documentData.finalLineHeight;
       }
-
       this.layerElement.appendChild(tElement);
     } else {
       var cachedSpansLength = this.textSpans.length;
       var charData;
-
       for (i = 0; i < len; i += 1) {
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
@@ -12140,31 +10274,24 @@
             glyph: null
           };
         }
-
         if (!usesGlyphs || !singleShape || i === 0) {
           tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
-
           if (cachedSpansLength <= i) {
             tSpan.setAttribute('stroke-linecap', 'butt');
             tSpan.setAttribute('stroke-linejoin', 'round');
             tSpan.setAttribute('stroke-miterlimit', '4');
             this.textSpans[i].span = tSpan;
-
             if (usesGlyphs) {
               var childSpan = createNS('g');
               tSpan.appendChild(childSpan);
               this.textSpans[i].childSpan = childSpan;
             }
-
             this.textSpans[i].span = tSpan;
             this.layerElement.appendChild(tSpan);
           }
-
           tSpan.style.display = 'inherit';
         }
-
         matrixHelper.reset();
-
         if (singleShape) {
           if (letters[i].n) {
             xPos = -trackingOffset;
@@ -12172,42 +10299,36 @@
             yPos += firstLine ? 1 : 0;
             firstLine = false;
           }
-
           this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
-          xPos += letters[i].l || 0; // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
-
+          xPos += letters[i].l || 0;
+          // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
           xPos += trackingOffset;
         }
-
         if (usesGlyphs) {
           charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
-          var glyphElement; // t === 1 means the character has been replaced with an animated shaped
-
+          var glyphElement;
+          // t === 1 means the character has been replaced with an animated shaped
           if (charData.t === 1) {
             glyphElement = new SVGCompElement(charData.data, this.globalData, this);
           } else {
             var data = emptyShapeData;
-
             if (charData.data && charData.data.shapes) {
               data = this.buildShapeData(charData.data, documentData.finalSize);
             }
-
             glyphElement = new SVGShapeElement(data, this.globalData, this);
           }
-
           if (this.textSpans[i].glyph) {
             var glyph = this.textSpans[i].glyph;
             this.textSpans[i].childSpan.removeChild(glyph.layerElement);
             glyph.destroy();
           }
-
           this.textSpans[i].glyph = glyphElement;
           glyphElement._debug = true;
           glyphElement.prepareFrame(0);
           glyphElement.renderFrame();
-          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement); // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+          // when using animated shapes, the layer will be scaled instead of replacing the internal scale
           // this might have issues with strokes and might need a different solution
-
           if (charData.t === 1) {
             this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
           }
@@ -12215,30 +10336,24 @@
           if (singleShape) {
             tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
           }
-
           tSpan.textContent = letters[i].val;
           tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
-        } //
-
+        }
+        //
       }
-
       if (singleShape && tSpan) {
         tSpan.setAttribute('d', shapeStr);
       }
     }
-
     while (i < this.textSpans.length) {
       this.textSpans[i].span.style.display = 'none';
       i += 1;
     }
-
     this._sizeChanged = true;
   };
-
   SVGTextLottieElement.prototype.sourceRectAtTime = function () {
     this.prepareFrame(this.comp.renderedFrame - this.data.st);
     this.renderInnerContent();
-
     if (this._sizeChanged) {
       this._sizeChanged = false;
       var textBox = this.layerElement.getBBox();
@@ -12249,35 +10364,27 @@
         height: textBox.height
       };
     }
-
     return this.bbox;
   };
-
   SVGTextLottieElement.prototype.getValue = function () {
     var i;
     var len = this.textSpans.length;
     var glyphElement;
     this.renderedFrame = this.comp.renderedFrame;
-
     for (i = 0; i < len; i += 1) {
       glyphElement = this.textSpans[i].glyph;
-
       if (glyphElement) {
         glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
-
         if (glyphElement._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   SVGTextLottieElement.prototype.renderInnerContent = function () {
     this.validateText();
-
     if (!this.data.singleShape || this._mdf) {
       this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
-
       if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
         this._sizeChanged = true;
         var i;
@@ -12288,33 +10395,26 @@
         var renderedLetter;
         var textSpan;
         var glyphElement;
-
         for (i = 0; i < len; i += 1) {
           if (!letters[i].n) {
             renderedLetter = renderedLetters[i];
             textSpan = this.textSpans[i].span;
             glyphElement = this.textSpans[i].glyph;
-
             if (glyphElement) {
               glyphElement.renderFrame();
             }
-
             if (renderedLetter._mdf.m) {
               textSpan.setAttribute('transform', renderedLetter.m);
             }
-
             if (renderedLetter._mdf.o) {
               textSpan.setAttribute('opacity', renderedLetter.o);
             }
-
             if (renderedLetter._mdf.sw) {
               textSpan.setAttribute('stroke-width', renderedLetter.sw);
             }
-
             if (renderedLetter._mdf.sc) {
               textSpan.setAttribute('stroke', renderedLetter.sc);
             }
-
             if (renderedLetter._mdf.fc) {
               textSpan.setAttribute('fill', renderedLetter.fc);
             }
@@ -12327,14 +10427,12 @@
   function ISolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([IImageElement], ISolidElement);
-
   ISolidElement.prototype.createContent = function () {
-    var rect = createNS('rect'); /// /rect.style.width = this.data.sw;
+    var rect = createNS('rect');
+    /// /rect.style.width = this.data.sw;
     /// /rect.style.height = this.data.sh;
     /// /rect.style.fill = this.data.sc;
-
     rect.setAttribute('width', this.data.sw);
     rect.setAttribute('height', this.data.sh);
     rect.setAttribute('fill', this.data.sc);
@@ -12348,59 +10446,43 @@
     this.initTransform(data, globalData, comp);
     this.initHierarchy();
   }
-
   NullElement.prototype.prepareFrame = function (num) {
     this.prepareProperties(num, true);
   };
-
   NullElement.prototype.renderFrame = function () {};
-
   NullElement.prototype.getBaseElement = function () {
     return null;
   };
-
   NullElement.prototype.destroy = function () {};
-
   NullElement.prototype.sourceRectAtTime = function () {};
-
   NullElement.prototype.hide = function () {};
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
 
   function SVGRendererBase() {}
-
   extendPrototype([BaseRenderer], SVGRendererBase);
-
   SVGRendererBase.prototype.createNull = function (data) {
     return new NullElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createShape = function (data) {
     return new SVGShapeElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createText = function (data) {
     return new SVGTextLottieElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createImage = function (data) {
     return new IImageElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createSolid = function (data) {
     return new ISolidElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.configAnimation = function (animData) {
     this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
     this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
-
     if (this.renderConfig.viewBoxSize) {
       this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
     } else {
       this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
     }
-
     if (!this.renderConfig.viewBoxOnly) {
       this.svgElement.setAttribute('width', animData.w);
       this.svgElement.setAttribute('height', animData.h);
@@ -12409,32 +10491,26 @@
       this.svgElement.style.transform = 'translate3d(0,0,0)';
       this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
     }
-
     if (this.renderConfig.width) {
       this.svgElement.setAttribute('width', this.renderConfig.width);
     }
-
     if (this.renderConfig.height) {
       this.svgElement.setAttribute('height', this.renderConfig.height);
     }
-
     if (this.renderConfig.className) {
       this.svgElement.setAttribute('class', this.renderConfig.className);
     }
-
     if (this.renderConfig.id) {
       this.svgElement.setAttribute('id', this.renderConfig.id);
     }
-
     if (this.renderConfig.focusable !== undefined) {
       this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
     }
-
-    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio); // this.layerElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+    // this.layerElement.style.transform = 'translate3d(0,0,0)';
     // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
-
-    this.animationItem.wrapper.appendChild(this.svgElement); // Mask animation
-
+    this.animationItem.wrapper.appendChild(this.svgElement);
+    // Mask animation
     var defs = this.globalData.defs;
     this.setupGlobalData(animData, defs);
     this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
@@ -12453,71 +10529,54 @@
     this.layers = animData.layers;
     this.elements = createSizedArray(animData.layers.length);
   };
-
   SVGRendererBase.prototype.destroy = function () {
     if (this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     this.layerElement = null;
     this.globalData.defs = null;
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.destroyed = true;
     this.animationItem = null;
   };
-
   SVGRendererBase.prototype.updateContainerSize = function () {};
-
   SVGRendererBase.prototype.findIndexByInd = function (ind) {
     var i = 0;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.layers[i].ind === ind) {
         return i;
       }
     }
-
     return -1;
   };
-
   SVGRendererBase.prototype.buildItem = function (pos) {
     var elements = this.elements;
-
     if (elements[pos] || this.layers[pos].ty === 99) {
       return;
     }
-
     elements[pos] = true;
     var element = this.createItem(this.layers[pos]);
     elements[pos] = element;
-
     if (getExpressionsPlugin()) {
       if (this.layers[pos].ty === 0) {
         this.globalData.projectInterface.registerComposition(element);
       }
-
       element.initExpressions();
     }
-
     this.appendElementInPos(element, pos);
-
     if (this.layers[pos].tt) {
       var elementIndex = 'tp' in this.layers[pos] ? this.findIndexByInd(this.layers[pos].tp) : pos - 1;
-
       if (elementIndex === -1) {
         return;
       }
-
       if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
         this.buildItem(elementIndex);
         this.addPendingElement(element);
@@ -12528,16 +10587,13 @@
       }
     }
   };
-
   SVGRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
-
       if (element.data.tt) {
         var i = 0;
         var len = this.elements.length;
-
         while (i < len) {
           if (this.elements[i] === element) {
             var elementIndex = 'tp' in element.data ? this.findIndexByInd(element.data.tp) : i - 1;
@@ -12546,43 +10602,36 @@
             element.setMatte(matteMask);
             break;
           }
-
           i += 1;
         }
       }
     }
   };
-
   SVGRendererBase.prototype.renderFrame = function (num) {
     if (this.renderedFrame === num || this.destroyed) {
       return;
     }
-
     if (num === null) {
       num = this.renderedFrame;
     } else {
       this.renderedFrame = num;
-    } // console.log('-------');
+    }
+    // console.log('-------');
     // console.log('FRAME ',num);
-
-
     this.globalData.frameNum = num;
     this.globalData.frameId += 1;
     this.globalData.projectInterface.currentFrame = num;
     this.globalData._mdf = false;
     var i;
     var len = this.layers.length;
-
     if (!this.completeLayers) {
       this.checkLayers(num);
     }
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(num - this.layers[i].st);
       }
     }
-
     if (this.globalData._mdf) {
       for (i = 0; i < len; i += 1) {
         if (this.completeLayers || this.elements[i]) {
@@ -12591,44 +10640,34 @@
       }
     }
   };
-
   SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
     var newElement = element.getBaseElement();
-
     if (!newElement) {
       return;
     }
-
     var i = 0;
     var nextElement;
-
     while (i < pos) {
       if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
         nextElement = this.elements[i].getBaseElement();
       }
-
       i += 1;
     }
-
     if (nextElement) {
       this.layerElement.insertBefore(newElement, nextElement);
     } else {
       this.layerElement.appendChild(newElement);
     }
   };
-
   SVGRendererBase.prototype.hide = function () {
     this.layerElement.style.display = 'none';
   };
-
   SVGRendererBase.prototype.show = function () {
     this.layerElement.style.display = 'block';
   };
 
   function ICompElement() {}
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
-
   ICompElement.prototype.initElement = function (data, globalData, comp) {
     this.initFrame();
     this.initBaseData(data, globalData, comp);
@@ -12638,13 +10677,12 @@
     this.initRendererElement();
     this.createContainerElements();
     this.createRenderableComponents();
-
     if (this.data.xt || !globalData.progressiveLoad) {
       this.buildAllItems();
     }
-
     this.hide();
   };
+
   /* ICompElement.prototype.hide = function(){
       if(!this.hidden){
           this.hideElement();
@@ -12657,77 +10695,61 @@
       }
   }; */
 
-
   ICompElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
-
     if (!this.isInRange && !this.data.xt) {
       return;
     }
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
-
       if (timeRemapped === this.data.op) {
         timeRemapped = this.data.op - 1;
       }
-
       this.renderedFrame = timeRemapped;
     } else {
       this.renderedFrame = num / this.data.sr;
     }
-
     var i;
     var len = this.elements.length;
-
     if (!this.completeLayers) {
       this.checkLayers(this.renderedFrame);
-    } // This iteration needs to be backwards because of how expressions connect between each other
-
-
+    }
+    // This iteration needs to be backwards because of how expressions connect between each other
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
-
         if (this.elements[i]._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   ICompElement.prototype.renderInnerContent = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].renderFrame();
       }
     }
   };
-
   ICompElement.prototype.setElements = function (elems) {
     this.elements = elems;
   };
-
   ICompElement.prototype.getElements = function () {
     return this.elements;
   };
-
   ICompElement.prototype.destroyElements = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i]) {
         this.elements[i].destroy();
       }
     }
   };
-
   ICompElement.prototype.destroy = function () {
     this.destroyElements();
     this.destroyBaseElement();
@@ -12744,9 +10766,7 @@
       _placeholder: true
     };
   }
-
   extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
-
   SVGCompElement.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
@@ -12757,7 +10777,6 @@
     this.renderedFrame = -1;
     this.svgElement = createNS('svg');
     var ariaLabel = '';
-
     if (config && config.title) {
       var titleElement = createNS('title');
       var titleId = createElementID();
@@ -12766,7 +10785,6 @@
       this.svgElement.appendChild(titleElement);
       ariaLabel += titleId;
     }
-
     if (config && config.description) {
       var descElement = createNS('desc');
       var descId = createElementID();
@@ -12775,11 +10793,9 @@
       this.svgElement.appendChild(descElement);
       ariaLabel += ' ' + descId;
     }
-
     if (ariaLabel) {
       this.svgElement.setAttribute('aria-labelledby', ariaLabel);
     }
-
     var defs = createNS('defs');
     this.svgElement.appendChild(defs);
     var maskElement = createNS('g');
@@ -12817,15 +10833,15 @@
     this.destroyed = false;
     this.rendererType = 'svg';
   }
-
   extendPrototype([SVGRendererBase], SVGRenderer);
-
   SVGRenderer.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
 
-  registerRenderer('svg', SVGRenderer); // Registering shape modifiers
+  // Registering renderers
+  registerRenderer('svg', SVGRenderer);
 
+  // Registering shape modifiers
   ShapeModifiers.registerModifier('tm', TrimModifier);
   ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
   ShapeModifiers.registerModifier('rp', RepeaterModifier);
diff --git a/build/player/lottie_light.min.js b/build/player/lottie_light.min.js
index e83ba9c..0e5a569 100644
--- a/build/player/lottie_light.min.js
+++ b/build/player/lottie_light.min.js
@@ -1 +1 @@
-"undefined"!=typeof navigator&&function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lottie=e()}(this,(function(){"use strict";var t="",e=!1,i=-999999,s=function(){return t};function a(t){return document.createElement(t)}function r(t,e){var i,s,a=t.length;for(i=0;i<a;i+=1)for(var r in s=t[i].prototype)Object.prototype.hasOwnProperty.call(s,r)&&(e.prototype[r]=s[r])}function n(t){function e(){}return e.prototype=t,e}var o=function(){function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].pause()},resume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].resume()},setRate:function(t){var e,i=this.audios.length;for(e=0;e<i;e+=1)this.audios[e].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}}(),h=function(){function t(t,e){var i,s=0,a=[];switch(t){case"int16":case"uint8c":i=1;break;default:i=1.1}for(s=0;s<e;s+=1)a.push(i);return a}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(e,i){return"float32"===e?new Float32Array(i):"int16"===e?new Int16Array(i):"uint8c"===e?new Uint8ClampedArray(i):t(e,i)}:t}();function l(t){return Array.apply(null,{length:t})}function p(t){return p="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},p(t)}var f=!0,d=null,m=null,c="",u=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),g=Math.pow,y=Math.sqrt,v=Math.floor,b=(Math.max,Math.min),_={};!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],i=e.length;for(t=0;t<i;t+=1)_[e[t]]=Math[e[t]]}(),_.random=Math.random,_.abs=function(t){if("object"===p(t)&&t.length){var e,i=l(t.length),s=t.length;for(e=0;e<s;e+=1)i[e]=Math.abs(t[e]);return i}return Math.abs(t)};var k=150,P=Math.PI/180,A=.5519;function S(t){!!t}function x(t,e,i,s){this.type=t,this.currentTime=e,this.totalTime=i,this.direction=s<0?-1:1}function w(t,e){this.type=t,this.direction=e<0?-1:1}function D(t,e,i,s){this.type=t,this.currentLoop=i,this.totalLoops=e,this.direction=s<0?-1:1}function C(t,e,i){this.type=t,this.firstFrame=e,this.totalFrames=i}function M(t,e){this.type=t,this.target=e}function T(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function F(t){this.type="configError",this.nativeError=t}var E,I=(E=0,function(){return c+"__lottie_element_"+(E+=1)});function L(t,e,i){var s,a,r,n,o,h,l,p;switch(h=i*(1-e),l=i*(1-(o=6*t-(n=Math.floor(6*t)))*e),p=i*(1-(1-o)*e),n%6){case 0:s=i,a=p,r=h;break;case 1:s=l,a=i,r=h;break;case 2:s=h,a=i,r=p;break;case 3:s=h,a=l,r=i;break;case 4:s=p,a=h,r=i;break;case 5:s=i,a=h,r=l}return[s,a,r]}function V(t,e,i){var s,a=Math.max(t,e,i),r=Math.min(t,e,i),n=a-r,o=0===a?0:n/a,h=a/255;switch(a){case r:s=0;break;case t:s=e-i+n*(e<i?6:0),s/=6*n;break;case e:s=i-t+2*n,s/=6*n;break;case i:s=t-e+4*n,s/=6*n}return[s,o,h]}function R(t,e){var i=V(255*t[0],255*t[1],255*t[2]);return i[1]+=e,i[1]>1?i[1]=1:i[1]<=0&&(i[1]=0),L(i[0],i[1],i[2])}function z(t,e){var i=V(255*t[0],255*t[1],255*t[2]);return i[2]+=e,i[2]>1?i[2]=1:i[2]<0&&(i[2]=0),L(i[0],i[1],i[2])}function O(t,e){var i=V(255*t[0],255*t[1],255*t[2]);return i[0]+=e/360,i[0]>1?i[0]-=1:i[0]<0&&(i[0]+=1),L(i[0],i[1],i[2])}!function(){var t,e,i=[];for(t=0;t<256;t+=1)e=t.toString(16),i[t]=1===e.length?"0"+e:e}();var N=function(){return d},B=function(){return m},q=function(t){k=t},j=function(){return k};function W(t){return document.createElementNS("http://www.w3.org/2000/svg",t)}function X(t){return X="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},X(t)}var H=function(){var t,i,s=1,a=[],r={onmessage:function(){},postMessage:function(e){t({data:e})}},n={postMessage:function(t){r.onmessage({data:t})}};function o(i){if(window.Worker&&window.Blob&&e){var s=new Blob(["var _workerSelf = self; self.onmessage = ",i.toString()],{type:"text/javascript"}),a=URL.createObjectURL(s);return new Worker(a)}return t=i,r}function h(){i||(i=o((function(t){if(n.dataManager||(n.dataManager=function(){function t(a,r){var n,o,h,l,p,d,m=a.length;for(o=0;o<m;o+=1)if("ks"in(n=a[o])&&!n.completed){if(n.completed=!0,n.hasMask){var c=n.masksProperties;for(l=c.length,h=0;h<l;h+=1)if(c[h].pt.k.i)s(c[h].pt.k);else for(d=c[h].pt.k.length,p=0;p<d;p+=1)c[h].pt.k[p].s&&s(c[h].pt.k[p].s[0]),c[h].pt.k[p].e&&s(c[h].pt.k[p].e[0])}0===n.ty?(n.layers=e(n.refId,r),t(n.layers,r)):4===n.ty?i(n.shapes):5===n.ty&&f(n)}}function e(t,e){var i=function(t,e){for(var i=0,s=e.length;i<s;){if(e[i].id===t)return e[i];i+=1}return null}(t,e);return i?i.layers.__used?JSON.parse(JSON.stringify(i.layers)):(i.layers.__used=!0,i.layers):null}function i(t){var e,a,r;for(e=t.length-1;e>=0;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)s(t[e].ks.k);else for(r=t[e].ks.k.length,a=0;a<r;a+=1)t[e].ks.k[a].s&&s(t[e].ks.k[a].s[0]),t[e].ks.k[a].e&&s(t[e].ks.k[a].e[0]);else"gr"===t[e].ty&&i(t[e].it)}function s(t){var e,i=t.i.length;for(e=0;e<i;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function a(t,e){var i=e?e.split("."):[100,100,100];return t[0]>i[0]||!(i[0]>t[0])&&(t[1]>i[1]||!(i[1]>t[1])&&(t[2]>i[2]||!(i[2]>t[2])&&null))}var r,n=function(){var t=[4,4,14];function e(t){var e,i,s,a=t.length;for(e=0;e<a;e+=1)5===t[e].ty&&(s=void 0,s=(i=t[e]).t.d,i.t.d={k:[{s:s,t:0}]})}return function(i){if(a(t,i.v)&&(e(i.layers),i.assets)){var s,r=i.assets.length;for(s=0;s<r;s+=1)i.assets[s].layers&&e(i.assets[s].layers)}}}(),o=(r=[4,7,99],function(t){if(t.chars&&!a(r,t.v)){var e,s=t.chars.length;for(e=0;e<s;e+=1){var n=t.chars[e];n.data&&n.data.shapes&&(i(n.data.shapes),n.data.ip=0,n.data.op=99999,n.data.st=0,n.data.sr=1,n.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[e].t||(n.data.shapes.push({ty:"no"}),n.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}}}),h=function(){var t=[5,7,15];function e(t){var e,i,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(i=void 0,"number"==typeof(i=t[e].t.p).a&&(i.a={a:0,k:i.a}),"number"==typeof i.p&&(i.p={a:0,k:i.p}),"number"==typeof i.r&&(i.r={a:0,k:i.r}))}return function(i){if(a(t,i.v)&&(e(i.layers),i.assets)){var s,r=i.assets.length;for(s=0;s<r;s+=1)i.assets[s].layers&&e(i.assets[s].layers)}}}(),l=function(){var t=[4,1,9];function e(t){var i,s,a,r=t.length;for(i=0;i<r;i+=1)if("gr"===t[i].ty)e(t[i].it);else if("fl"===t[i].ty||"st"===t[i].ty)if(t[i].c.k&&t[i].c.k[0].i)for(a=t[i].c.k.length,s=0;s<a;s+=1)t[i].c.k[s].s&&(t[i].c.k[s].s[0]/=255,t[i].c.k[s].s[1]/=255,t[i].c.k[s].s[2]/=255,t[i].c.k[s].s[3]/=255),t[i].c.k[s].e&&(t[i].c.k[s].e[0]/=255,t[i].c.k[s].e[1]/=255,t[i].c.k[s].e[2]/=255,t[i].c.k[s].e[3]/=255);else t[i].c.k[0]/=255,t[i].c.k[1]/=255,t[i].c.k[2]/=255,t[i].c.k[3]/=255}function i(t){var i,s=t.length;for(i=0;i<s;i+=1)4===t[i].ty&&e(t[i].shapes)}return function(e){if(a(t,e.v)&&(i(e.layers),e.assets)){var s,r=e.assets.length;for(s=0;s<r;s+=1)e.assets[s].layers&&i(e.assets[s].layers)}}}(),p=function(){var t=[4,4,18];function e(t){var i,s,a;for(i=t.length-1;i>=0;i-=1)if("sh"===t[i].ty)if(t[i].ks.k.i)t[i].ks.k.c=t[i].closed;else for(a=t[i].ks.k.length,s=0;s<a;s+=1)t[i].ks.k[s].s&&(t[i].ks.k[s].s[0].c=t[i].closed),t[i].ks.k[s].e&&(t[i].ks.k[s].e[0].c=t[i].closed);else"gr"===t[i].ty&&e(t[i].it)}function i(t){var i,s,a,r,n,o,h=t.length;for(s=0;s<h;s+=1){if((i=t[s]).hasMask){var l=i.masksProperties;for(r=l.length,a=0;a<r;a+=1)if(l[a].pt.k.i)l[a].pt.k.c=l[a].cl;else for(o=l[a].pt.k.length,n=0;n<o;n+=1)l[a].pt.k[n].s&&(l[a].pt.k[n].s[0].c=l[a].cl),l[a].pt.k[n].e&&(l[a].pt.k[n].e[0].c=l[a].cl)}4===i.ty&&e(i.shapes)}}return function(e){if(a(t,e.v)&&(i(e.layers),e.assets)){var s,r=e.assets.length;for(s=0;s<r;s+=1)e.assets[s].layers&&i(e.assets[s].layers)}}}();function f(t){0===t.t.a.length&&t.t.p}var d={completeData:function(i){i.__complete||(l(i),n(i),o(i),h(i),p(i),t(i.layers,i.assets),function(i,s){if(i){var a=0,r=i.length;for(a=0;a<r;a+=1)1===i[a].t&&(i[a].data.layers=e(i[a].data.refId,s),t(i[a].data.layers,s))}}(i.chars,i.assets),i.__complete=!0)}};return d.checkColors=l,d.checkChars=o,d.checkPathProperties=h,d.checkShapes=p,d.completeLayers=t,d}()),n.assetLoader||(n.assetLoader=function(){function t(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")||t.response&&"object"===X(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}return{load:function(e,i,s,a){var r,n=new XMLHttpRequest;try{n.responseType="json"}catch(t){}n.onreadystatechange=function(){if(4===n.readyState)if(200===n.status)r=t(n),s(r);else try{r=t(n),s(r)}catch(t){a&&a(t)}};try{n.open(["G","E","T"].join(""),e,!0)}catch(t){n.open(["G","E","T"].join(""),i+"/"+e,!0)}n.send()}}}()),"loadAnimation"===t.data.type)n.assetLoader.load(t.data.path,t.data.fullPath,(function(e){n.dataManager.completeData(e),n.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){n.postMessage({id:t.data.id,status:"error"})}));else if("complete"===t.data.type){var e=t.data.animation;n.dataManager.completeData(e),n.postMessage({id:t.data.id,payload:e,status:"success"})}else"loadData"===t.data.type&&n.assetLoader.load(t.data.path,t.data.fullPath,(function(e){n.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){n.postMessage({id:t.data.id,status:"error"})}))})),i.onmessage=function(t){var e=t.data,i=e.id,s=a[i];a[i]=null,"success"===e.status?s.onComplete(e.payload):s.onError&&s.onError()})}function l(t,e){var i="processId_"+(s+=1);return a[i]={onComplete:t,onError:e},i}return{loadAnimation:function(t,e,s){h();var a=l(e,s);i.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:a})},loadData:function(t,e,s){h();var a=l(e,s);i.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:a})},completeAnimation:function(t,e,s){h();var a=l(e,s);i.postMessage({type:"complete",animation:t,id:a})}}}(),Y=function(){var t=function(){var t=a("canvas");t.width=1,t.height=1;var e=t.getContext("2d");return e.fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1),t}();function e(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function i(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function s(t,e,i){var s="";if(t.e)s=t.p;else if(e){var a=t.p;-1!==a.indexOf("images/")&&(a=a.split("/")[1]),s=e+a}else s=i,s+=t.u?t.u:"",s+=t.p;return s}function r(t){var e=0,i=setInterval(function(){(t.getBBox().width||e>500)&&(this._imageLoaded(),clearInterval(i)),e+=1}.bind(this),50)}function n(t){var e={assetData:t},i=s(t,this.assetsPath,this.path);return H.loadData(i,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}function o(){this._imageLoaded=e.bind(this),this._footageLoaded=i.bind(this),this.testImageLoaded=r.bind(this),this.createFootageData=n.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return o.prototype={loadAssets:function(t,e){var i;this.imagesLoadedCb=e;var s=t.length;for(i=0;i<s;i+=1)t[i].layers||(t[i].t&&"seq"!==t[i].t?3===t[i].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[i]))):(this.totalImages+=1,this.images.push(this._createImageData(t[i]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,i=this.images.length;e<i;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(e){var i=s(e,this.assetsPath,this.path),r=a("img");r.crossOrigin="anonymous",r.addEventListener("load",this._imageLoaded,!1),r.addEventListener("error",function(){n.img=t,this._imageLoaded()}.bind(this),!1),r.src=i;var n={img:r,assetData:e};return n},createImageData:function(e){var i=s(e,this.assetsPath,this.path),a=W("image");u?this.testImageLoaded(a):a.addEventListener("load",this._imageLoaded,!1),a.addEventListener("error",function(){r.img=t,this._imageLoaded()}.bind(this),!1),a.setAttributeNS("http://www.w3.org/1999/xlink","href",i),this._elementHelper.append?this._elementHelper.append(a):this._elementHelper.appendChild(a);var r={img:a,assetData:e};return r},imageLoaded:e,footageLoaded:i,setCacheType:function(t,e){"svg"===t?(this._elementHelper=e,this._createImageData=this.createImageData.bind(this)):this._createImageData=this.createImgData.bind(this)}},o}();function G(){}G.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var i=this._cbs[t],s=0;s<i.length;s+=1)i[s](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var i=0,s=this._cbs[t].length;i<s;)this._cbs[t][i]===e&&(this._cbs[t].splice(i,1),i-=1,s-=1),i+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var K=function(){function t(t){for(var e,i=t.split("\r\n"),s={},a=0,r=0;r<i.length;r+=1)2===(e=i[r].split(":")).length&&(s[e[0]]=e[1].trim(),a+=1);if(0===a)throw new Error;return s}return function(e){for(var i=[],s=0;s<e.length;s+=1){var a=e[s],r={time:a.tm,duration:a.dr};try{r.payload=JSON.parse(e[s].cm)}catch(i){try{r.payload=t(e[s].cm)}catch(t){r.payload={name:e[s].cm}}}i.push(r)}return i}}(),J=function(){function t(t){this.compositions.push(t)}return function(){function e(t){for(var e=0,i=this.compositions.length;e<i;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return e.compositions=[],e.currentFrame=0,e.registerComposition=t,e}}(),U={};function Z(t){return Z="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Z(t)}var Q=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=I(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=f,this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=J(),this.imagePreloader=new Y,this.audioController=o(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new x("drawnFrame",0,0,0),this.expressionsPlugin=N()};r([G],Q),Q.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg";t.animType?e=t.animType:t.renderer&&(e=t.renderer);var i=U[e];this.renderer=new i(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||void 0===t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),H.loadAnimation(t.path,this.configAnimation,this.onSetupError))},Q.prototype.onSetupError=function(){this.trigger("data_failed")},Q.prototype.setupAnimation=function(t){H.completeAnimation(t,this.configAnimation)},Q.prototype.setData=function(t,e){e&&"object"!==Z(e)&&(e=JSON.parse(e));var i={wrapper:t,animationData:e},s=t.attributes;i.path=s.getNamedItem("data-animation-path")?s.getNamedItem("data-animation-path").value:s.getNamedItem("data-bm-path")?s.getNamedItem("data-bm-path").value:s.getNamedItem("bm-path")?s.getNamedItem("bm-path").value:"",i.animType=s.getNamedItem("data-anim-type")?s.getNamedItem("data-anim-type").value:s.getNamedItem("data-bm-type")?s.getNamedItem("data-bm-type").value:s.getNamedItem("bm-type")?s.getNamedItem("bm-type").value:s.getNamedItem("data-bm-renderer")?s.getNamedItem("data-bm-renderer").value:s.getNamedItem("bm-renderer")?s.getNamedItem("bm-renderer").value:function(){if(U.canvas)return"canvas";for(var t in U)if(U[t])return t;return""}()||"canvas";var a=s.getNamedItem("data-anim-loop")?s.getNamedItem("data-anim-loop").value:s.getNamedItem("data-bm-loop")?s.getNamedItem("data-bm-loop").value:s.getNamedItem("bm-loop")?s.getNamedItem("bm-loop").value:"";"false"===a?i.loop=!1:"true"===a?i.loop=!0:""!==a&&(i.loop=parseInt(a,10));var r=s.getNamedItem("data-anim-autoplay")?s.getNamedItem("data-anim-autoplay").value:s.getNamedItem("data-bm-autoplay")?s.getNamedItem("data-bm-autoplay").value:!s.getNamedItem("bm-autoplay")||s.getNamedItem("bm-autoplay").value;i.autoplay="false"!==r,i.name=s.getNamedItem("data-name")?s.getNamedItem("data-name").value:s.getNamedItem("data-bm-name")?s.getNamedItem("data-bm-name").value:s.getNamedItem("bm-name")?s.getNamedItem("bm-name").value:"","false"===(s.getNamedItem("data-anim-prerender")?s.getNamedItem("data-anim-prerender").value:s.getNamedItem("data-bm-prerender")?s.getNamedItem("data-bm-prerender").value:s.getNamedItem("bm-prerender")?s.getNamedItem("bm-prerender").value:"")&&(i.prerender=!1),i.path?this.setParams(i):this.trigger("destroy")},Q.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,i,s=this.animationData.layers,a=s.length,r=t.layers,n=r.length;for(i=0;i<n;i+=1)for(e=0;e<a;){if(s[e].id===r[i].id){s[e]=r[i];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(a=t.assets.length,e=0;e<a;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,H.completeAnimation(this.animationData,this.onSegmentComplete)},Q.prototype.onSegmentComplete=function(t){this.animationData=t;var e=N();e&&e.initExpressions(this),this.loadNextSegment()},Q.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var i=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,H.loadData(i,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},Q.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},Q.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},Q.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},Q.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=K(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},Q.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},Q.prototype.checkLoaded=function(){if(!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()){this.isLoaded=!0;var t=N();t&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play()}},Q.prototype.resize=function(t,e){var i="number"==typeof t?t:void 0,s="number"==typeof e?e:void 0;this.renderer.updateContainerSize(i,s)},Q.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},Q.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},Q.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},Q.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},Q.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},Q.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},Q.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},Q.prototype.getMarkerData=function(t){for(var e,i=0;i<this.markers.length;i+=1)if((e=this.markers[i]).payload&&e.payload.name===t)return e;return null},Q.prototype.goToAndStop=function(t,e,i){if(!i||this.name===i){var s=Number(t);if(isNaN(s)){var a=this.getMarkerData(t);a&&this.goToAndStop(a.time,!0)}else e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier);this.pause()}},Q.prototype.goToAndPlay=function(t,e,i){if(!i||this.name===i){var s=Number(t);if(isNaN(s)){var a=this.getMarkerData(t);a&&(a.duration?this.playSegments([a.time,a.time+a.duration],!0):this.goToAndStop(a.time,!0))}else this.goToAndStop(s,e,i);this.play()}},Q.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,i=!1;e>=this.totalFrames-1&&this.frameModifier>0?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(i=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(i=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),i&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},Q.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(this.frameModifier>0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},Q.prototype.setSegment=function(t,e){var i=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?i=t:this.currentRawFrame+this.firstFrame>e&&(i=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==i&&this.goToAndStop(i,!0)},Q.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===Z(t[0])){var i,s=t.length;for(i=0;i<s;i+=1)this.segments.push(t[i])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},Q.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},Q.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},Q.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},Q.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},Q.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},Q.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},Q.prototype.setLoop=function(t){this.loop=t},Q.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},Q.prototype.getVolume=function(){return this.audioController.getVolume()},Q.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},Q.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},Q.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},Q.prototype.getPath=function(){return this.path},Q.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var i=t.p;-1!==i.indexOf("images/")&&(i=i.split("/")[1]),e=this.assetsPath+i}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},Q.prototype.getAssetData=function(t){for(var e=0,i=this.assets.length;e<i;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},Q.prototype.hide=function(){this.renderer.hide()},Q.prototype.show=function(){this.renderer.show()},Q.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},Q.prototype.updateDocumentData=function(t,e,i){try{this.renderer.getElementByPath(t).updateDocumentData(e,i)}catch(t){}},Q.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new x(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new D(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new w(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new C(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new M(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new x(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new D(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new w(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new C(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new M(t,this))},Q.prototype.triggerRenderFrameError=function(t){var e=new T(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)},Q.prototype.triggerConfigError=function(t){var e=new F(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)};var $=function(){var t={},e=[],i=0,s=0,r=0,n=!0,o=!1;function h(t){for(var i=0,a=t.target;i<s;)e[i].animation===a&&(e.splice(i,1),i-=1,s-=1,a.isPaused||f()),i+=1}function l(t,i){if(!t)return null;for(var a=0;a<s;){if(e[a].elem===t&&null!==e[a].elem)return e[a].animation;a+=1}var r=new Q;return d(r,t),r.setData(t,i),r}function p(){r+=1,u()}function f(){r-=1}function d(t,i){t.addEventListener("destroy",h),t.addEventListener("_active",p),t.addEventListener("_idle",f),e.push({elem:i,animation:t}),s+=1}function m(t){var a,h=t-i;for(a=0;a<s;a+=1)e[a].animation.advanceTime(h);i=t,r&&!o?window.requestAnimationFrame(m):n=!0}function c(t){i=t,window.requestAnimationFrame(m)}function u(){!o&&r&&n&&(window.requestAnimationFrame(c),n=!1)}return t.registerAnimation=l,t.loadAnimation=function(t){var e=new Q;return d(e,null),e.setParams(t),e},t.setSpeed=function(t,i){var a;for(a=0;a<s;a+=1)e[a].animation.setSpeed(t,i)},t.setDirection=function(t,i){var a;for(a=0;a<s;a+=1)e[a].animation.setDirection(t,i)},t.play=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.play(t)},t.pause=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.pause(t)},t.stop=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.stop(t)},t.togglePause=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.togglePause(t)},t.searchAnimations=function(t,e,i){var s,r=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),n=r.length;for(s=0;s<n;s+=1)i&&r[s].setAttribute("data-bm-type",i),l(r[s],t);if(e&&0===n){i||(i="svg");var o=document.getElementsByTagName("body")[0];o.innerText="";var h=a("div");h.style.width="100%",h.style.height="100%",h.setAttribute("data-bm-type",i),o.appendChild(h),l(h,t)}},t.resize=function(){var t;for(t=0;t<s;t+=1)e[t].animation.resize()},t.goToAndStop=function(t,i,a){var r;for(r=0;r<s;r+=1)e[r].animation.goToAndStop(t,i,a)},t.destroy=function(t){var i;for(i=s-1;i>=0;i-=1)e[i].animation.destroy(t)},t.freeze=function(){o=!0},t.unfreeze=function(){o=!1,u()},t.setVolume=function(t,i){var a;for(a=0;a<s;a+=1)e[a].animation.setVolume(t,i)},t.mute=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.mute(t)},t.unmute=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.unmute(t)},t.getRegisteredAnimations=function(){var t,i=e.length,s=[];for(t=0;t<i;t+=1)s.push(e[t].animation);return s},t}(),tt=function(){var t={getBezierEasing:function(t,i,s,a,r){var n=r||("bez_"+t+"_"+i+"_"+s+"_"+a).replace(/\./g,"p");if(e[n])return e[n];var o=new l([t,i,s,a]);return e[n]=o,o}},e={};var i=.1,s="function"==typeof Float32Array;function a(t,e){return 1-3*e+3*t}function r(t,e){return 3*e-6*t}function n(t){return 3*t}function o(t,e,i){return((a(e,i)*t+r(e,i))*t+n(e))*t}function h(t,e,i){return 3*a(e,i)*t*t+2*r(e,i)*t+n(e)}function l(t){this._p=t,this._mSampleValues=s?new Float32Array(11):new Array(11),this._precomputed=!1,this.get=this.get.bind(this)}return l.prototype={get:function(t){var e=this._p[0],i=this._p[1],s=this._p[2],a=this._p[3];return this._precomputed||this._precompute(),e===i&&s===a?t:0===t?0:1===t?1:o(this._getTForX(t),i,a)},_precompute:function(){var t=this._p[0],e=this._p[1],i=this._p[2],s=this._p[3];this._precomputed=!0,t===e&&i===s||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],s=0;s<11;++s)this._mSampleValues[s]=o(s*i,t,e)},_getTForX:function(t){for(var e=this._p[0],s=this._p[2],a=this._mSampleValues,r=0,n=1;10!==n&&a[n]<=t;++n)r+=i;var l=r+(t-a[--n])/(a[n+1]-a[n])*i,p=h(l,e,s);return p>=.001?function(t,e,i,s){for(var a=0;a<4;++a){var r=h(e,i,s);if(0===r)return e;e-=(o(e,i,s)-t)/r}return e}(t,l,e,s):0===p?l:function(t,e,i,s,a){var r,n,h=0;do{(r=o(n=e+(i-e)/2,s,a)-t)>0?i=n:e=n}while(Math.abs(r)>1e-7&&++h<10);return n}(t,r,r+i,e,s)}},t}(),et={double:function(t){return t.concat(l(t.length))}},it=function(t,e,i){var s=0,a=t,r=l(a);return{newElement:function(){return s?r[s-=1]:e()},release:function(t){s===a&&(r=et.double(r),a*=2),i&&i(t),r[s]=t,s+=1}}},st=it(8,(function(){return{addedLength:0,percents:h("float32",j()),lengths:h("float32",j())}})),at=it(8,(function(){return{lengths:[],totalLength:0}}),(function(t){var e,i=t.lengths.length;for(e=0;e<i;e+=1)st.release(t.lengths[e]);t.lengths.length=0}));var rt=function(){var t=Math;function e(t,e,i,s,a,r){var n=t*s+e*a+i*r-a*s-r*t-i*e;return n>-.001&&n<.001}var i=function(t,e,i,s){var a,r,n,o,h,l,p=j(),f=0,d=[],m=[],c=st.newElement();for(n=i.length,a=0;a<p;a+=1){for(h=a/(p-1),l=0,r=0;r<n;r+=1)o=g(1-h,3)*t[r]+3*g(1-h,2)*h*i[r]+3*(1-h)*g(h,2)*s[r]+g(h,3)*e[r],d[r]=o,null!==m[r]&&(l+=g(d[r]-m[r],2)),m[r]=d[r];l&&(f+=l=y(l)),c.percents[a]=h,c.lengths[a]=f}return c.addedLength=f,c};function s(t){this.segmentLength=0,this.points=new Array(t)}function a(t,e){this.partialLength=t,this.point=e}var r,n=(r={},function(t,i,n,o){var h=(t[0]+"_"+t[1]+"_"+i[0]+"_"+i[1]+"_"+n[0]+"_"+n[1]+"_"+o[0]+"_"+o[1]).replace(/\./g,"p");if(!r[h]){var p,f,d,m,c,u,v,b=j(),_=0,k=null;2===t.length&&(t[0]!==i[0]||t[1]!==i[1])&&e(t[0],t[1],i[0],i[1],t[0]+n[0],t[1]+n[1])&&e(t[0],t[1],i[0],i[1],i[0]+o[0],i[1]+o[1])&&(b=2);var P=new s(b);for(d=n.length,p=0;p<b;p+=1){for(v=l(d),c=p/(b-1),u=0,f=0;f<d;f+=1)m=g(1-c,3)*t[f]+3*g(1-c,2)*c*(t[f]+n[f])+3*(1-c)*g(c,2)*(i[f]+o[f])+g(c,3)*i[f],v[f]=m,null!==k&&(u+=g(v[f]-k[f],2));_+=u=y(u),P.points[p]=new a(u,v),k=v}P.segmentLength=_,r[h]=P}return r[h]});function o(t,e){var i=e.percents,s=e.lengths,a=i.length,r=v((a-1)*t),n=t*e.addedLength,o=0;if(r===a-1||0===r||n===s[r])return i[r];for(var h=s[r]>n?-1:1,l=!0;l;)if(s[r]<=n&&s[r+1]>n?(o=(n-s[r])/(s[r+1]-s[r]),l=!1):r+=h,r<0||r>=a-1){if(r===a-1)return i[r];l=!1}return i[r]+(i[r+1]-i[r])*o}var p=h("float32",8);return{getSegmentsLength:function(t){var e,s=at.newElement(),a=t.c,r=t.v,n=t.o,o=t.i,h=t._length,l=s.lengths,p=0;for(e=0;e<h-1;e+=1)l[e]=i(r[e],r[e+1],n[e],o[e+1]),p+=l[e].addedLength;return a&&h&&(l[e]=i(r[e],r[0],n[e],o[0]),p+=l[e].addedLength),s.totalLength=p,s},getNewSegment:function(e,i,s,a,r,n,h){r<0?r=0:r>1&&(r=1);var l,f=o(r,h),d=o(n=n>1?1:n,h),m=e.length,c=1-f,u=1-d,g=c*c*c,y=f*c*c*3,v=f*f*c*3,b=f*f*f,_=c*c*u,k=f*c*u+c*f*u+c*c*d,P=f*f*u+c*f*d+f*c*d,A=f*f*d,S=c*u*u,x=f*u*u+c*d*u+c*u*d,w=f*d*u+c*d*d+f*u*d,D=f*d*d,C=u*u*u,M=d*u*u+u*d*u+u*u*d,T=d*d*u+u*d*d+d*u*d,F=d*d*d;for(l=0;l<m;l+=1)p[4*l]=t.round(1e3*(g*e[l]+y*s[l]+v*a[l]+b*i[l]))/1e3,p[4*l+1]=t.round(1e3*(_*e[l]+k*s[l]+P*a[l]+A*i[l]))/1e3,p[4*l+2]=t.round(1e3*(S*e[l]+x*s[l]+w*a[l]+D*i[l]))/1e3,p[4*l+3]=t.round(1e3*(C*e[l]+M*s[l]+T*a[l]+F*i[l]))/1e3;return p},getPointInSegment:function(e,i,s,a,r,n){var h=o(r,n),l=1-h;return[t.round(1e3*(l*l*l*e[0]+(h*l*l+l*h*l+l*l*h)*s[0]+(h*h*l+l*h*h+h*l*h)*a[0]+h*h*h*i[0]))/1e3,t.round(1e3*(l*l*l*e[1]+(h*l*l+l*h*l+l*l*h)*s[1]+(h*h*l+l*h*h+h*l*h)*a[1]+h*h*h*i[1]))/1e3]},buildBezierData:n,pointOnLine2D:e,pointOnLine3D:function(i,s,a,r,n,o,h,l,p){if(0===a&&0===o&&0===p)return e(i,s,r,n,h,l);var f,d=t.sqrt(t.pow(r-i,2)+t.pow(n-s,2)+t.pow(o-a,2)),m=t.sqrt(t.pow(h-i,2)+t.pow(l-s,2)+t.pow(p-a,2)),c=t.sqrt(t.pow(h-r,2)+t.pow(l-n,2)+t.pow(p-o,2));return(f=d>m?d>c?d-m-c:c-m-d:c>m?c-m-d:m-d-c)>-1e-4&&f<1e-4}}}(),nt=i,ot=Math.abs;function ht(t,e){var i,s=this.offsetTime;"multidimensional"===this.propType&&(i=h("float32",this.pv.length));for(var a,r,n,o,l,p,f,d,m,c=e.lastIndex,u=c,g=this.keyframes.length-1,y=!0;y;){if(a=this.keyframes[u],r=this.keyframes[u+1],u===g-1&&t>=r.t-s){a.h&&(a=r),c=0;break}if(r.t-s>t){c=u;break}u<g-1?u+=1:(c=0,y=!1)}n=this.keyframesMetadata[u]||{};var v,b,_,k,A,S,x,w,D,C,M=r.t-s,T=a.t-s;if(a.to){n.bezierData||(n.bezierData=rt.buildBezierData(a.s,r.s||a.e,a.to,a.ti));var F=n.bezierData;if(t>=M||t<T){var E=t>=M?F.points.length-1:0;for(l=F.points[E].point.length,o=0;o<l;o+=1)i[o]=F.points[E].point[o]}else{n.__fnct?m=n.__fnct:(m=tt.getBezierEasing(a.o.x,a.o.y,a.i.x,a.i.y,a.n).get,n.__fnct=m),p=m((t-T)/(M-T));var I,L=F.segmentLength*p,V=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastAddedLength:0;for(d=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastPoint:0,y=!0,f=F.points.length;y;){if(V+=F.points[d].partialLength,0===L||0===p||d===F.points.length-1){for(l=F.points[d].point.length,o=0;o<l;o+=1)i[o]=F.points[d].point[o];break}if(L>=V&&L<V+F.points[d+1].partialLength){for(I=(L-V)/F.points[d+1].partialLength,l=F.points[d].point.length,o=0;o<l;o+=1)i[o]=F.points[d].point[o]+(F.points[d+1].point[o]-F.points[d].point[o])*I;break}d<f-1?d+=1:y=!1}e._lastPoint=d,e._lastAddedLength=V-F.points[d].partialLength,e._lastKeyframeIndex=u}}else{var R,z,O,N,B;if(g=a.s.length,v=r.s||a.e,this.sh&&1!==a.h)if(t>=M)i[0]=v[0],i[1]=v[1],i[2]=v[2];else if(t<=T)i[0]=a.s[0],i[1]=a.s[1],i[2]=a.s[2];else{var q=lt(a.s),j=lt(v);b=i,_=function(t,e,i){var s,a,r,n,o,h=[],l=t[0],p=t[1],f=t[2],d=t[3],m=e[0],c=e[1],u=e[2],g=e[3];return(a=l*m+p*c+f*u+d*g)<0&&(a=-a,m=-m,c=-c,u=-u,g=-g),1-a>1e-6?(s=Math.acos(a),r=Math.sin(s),n=Math.sin((1-i)*s)/r,o=Math.sin(i*s)/r):(n=1-i,o=i),h[0]=n*l+o*m,h[1]=n*p+o*c,h[2]=n*f+o*u,h[3]=n*d+o*g,h}(q,j,(t-T)/(M-T)),k=_[0],A=_[1],S=_[2],x=_[3],w=Math.atan2(2*A*x-2*k*S,1-2*A*A-2*S*S),D=Math.asin(2*k*A+2*S*x),C=Math.atan2(2*k*x-2*A*S,1-2*k*k-2*S*S),b[0]=w/P,b[1]=D/P,b[2]=C/P}else for(u=0;u<g;u+=1)1!==a.h&&(t>=M?p=1:t<T?p=0:(a.o.x.constructor===Array?(n.__fnct||(n.__fnct=[]),n.__fnct[u]?m=n.__fnct[u]:(R=void 0===a.o.x[u]?a.o.x[0]:a.o.x[u],z=void 0===a.o.y[u]?a.o.y[0]:a.o.y[u],O=void 0===a.i.x[u]?a.i.x[0]:a.i.x[u],N=void 0===a.i.y[u]?a.i.y[0]:a.i.y[u],m=tt.getBezierEasing(R,z,O,N).get,n.__fnct[u]=m)):n.__fnct?m=n.__fnct:(R=a.o.x,z=a.o.y,O=a.i.x,N=a.i.y,m=tt.getBezierEasing(R,z,O,N).get,a.keyframeMetadata=m),p=m((t-T)/(M-T)))),v=r.s||a.e,B=1===a.h?a.s[u]:a.s[u]+(v[u]-a.s[u])*p,"multidimensional"===this.propType?i[u]=B:i=B}return e.lastIndex=c,i}function lt(t){var e=t[0]*P,i=t[1]*P,s=t[2]*P,a=Math.cos(e/2),r=Math.cos(i/2),n=Math.cos(s/2),o=Math.sin(e/2),h=Math.sin(i/2),l=Math.sin(s/2);return[o*h*n+a*r*l,o*r*n+a*h*l,a*h*n-o*r*l,a*r*n-o*h*l]}function pt(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==nt&&(this._caching.lastFrame>=i&&t>=i||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var s=this.interpolateValue(t,this._caching);this.pv=s}return this._caching.lastFrame=t,this.pv}function ft(t){var e;if("unidimensional"===this.propType)e=t*this.mult,ot(this.v-e)>1e-5&&(this.v=e,this._mdf=!0);else for(var i=0,s=this.v.length;i<s;)e=t[i]*this.mult,ot(this.v[i]-e)>1e-5&&(this.v[i]=e,this._mdf=!0),i+=1}function dt(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t;this.lock=!0,this._mdf=this._isFirstFrame;var e=this.effectsSequence.length,i=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)i=this.effectsSequence[t](i);this.setVValue(i),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function mt(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function ct(t,e,i,s){this.propType="unidimensional",this.mult=i||1,this.data=e,this.v=i?e.k*i:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=s,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=dt,this.setVValue=ft,this.addEffect=mt}function ut(t,e,i,s){var a;this.propType="multidimensional",this.mult=i||1,this.data=e,this._mdf=!1,this.elem=t,this.container=s,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var r=e.k.length;for(this.v=h("float32",r),this.pv=h("float32",r),this.vel=h("float32",r),a=0;a<r;a+=1)this.v[a]=e.k[a]*this.mult,this.pv[a]=e.k[a];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=dt,this.setVValue=ft,this.addEffect=mt}function gt(t,e,i,s){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:nt,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=i||1,this.elem=t,this.container=s,this.comp=t.comp,this.v=nt,this.pv=nt,this._isFirstFrame=!0,this.getValue=dt,this.setVValue=ft,this.interpolateValue=ht,this.effectsSequence=[pt.bind(this)],this.addEffect=mt}function yt(t,e,i,s){var a;this.propType="multidimensional";var r,n,o,l,p=e.k.length;for(a=0;a<p-1;a+=1)e.k[a].to&&e.k[a].s&&e.k[a+1]&&e.k[a+1].s&&(r=e.k[a].s,n=e.k[a+1].s,o=e.k[a].to,l=e.k[a].ti,(2===r.length&&(r[0]!==n[0]||r[1]!==n[1])&&rt.pointOnLine2D(r[0],r[1],n[0],n[1],r[0]+o[0],r[1]+o[1])&&rt.pointOnLine2D(r[0],r[1],n[0],n[1],n[0]+l[0],n[1]+l[1])||3===r.length&&(r[0]!==n[0]||r[1]!==n[1]||r[2]!==n[2])&&rt.pointOnLine3D(r[0],r[1],r[2],n[0],n[1],n[2],r[0]+o[0],r[1]+o[1],r[2]+o[2])&&rt.pointOnLine3D(r[0],r[1],r[2],n[0],n[1],n[2],n[0]+l[0],n[1]+l[1],n[2]+l[2]))&&(e.k[a].to=null,e.k[a].ti=null),r[0]===n[0]&&r[1]===n[1]&&0===o[0]&&0===o[1]&&0===l[0]&&0===l[1]&&(2===r.length||r[2]===n[2]&&0===o[2]&&0===l[2])&&(e.k[a].to=null,e.k[a].ti=null));this.effectsSequence=[pt.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=i||1,this.elem=t,this.container=s,this.comp=t.comp,this.getValue=dt,this.setVValue=ft,this.interpolateValue=ht,this.frameId=-1;var f=e.k[0].s.length;for(this.v=h("float32",f),this.pv=h("float32",f),a=0;a<f;a+=1)this.v[a]=nt,this.pv[a]=nt;this._caching={lastFrame:nt,lastIndex:0,value:h("float32",f)},this.addEffect=mt}var vt={getProp:function(t,e,i,s,a){var r;if(e.sid&&(e=t.globalData.slotManager.getProp(e)),e.k.length)if("number"==typeof e.k[0])r=new ut(t,e,s,a);else switch(i){case 0:r=new gt(t,e,s,a);break;case 1:r=new yt(t,e,s,a)}else r=new ct(t,e,s,a);return r.effectsSequence.length&&a.addDynamicProperty(r),r}};function bt(){}bt.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){var t;this._mdf=!1;var e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var _t=it(8,(function(){return h("float32",2)}));function kt(){this.c=!1,this._length=0,this._maxLength=8,this.v=l(this._maxLength),this.o=l(this._maxLength),this.i=l(this._maxLength)}kt.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var i=0;i<e;)this.v[i]=_t.newElement(),this.o[i]=_t.newElement(),this.i[i]=_t.newElement(),i+=1},kt.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},kt.prototype.doubleArrayLength=function(){this.v=this.v.concat(l(this._maxLength)),this.i=this.i.concat(l(this._maxLength)),this.o=this.o.concat(l(this._maxLength)),this._maxLength*=2},kt.prototype.setXYAt=function(t,e,i,s,a){var r;switch(this._length=Math.max(this._length,s+1),this._length>=this._maxLength&&this.doubleArrayLength(),i){case"v":r=this.v;break;case"i":r=this.i;break;case"o":r=this.o;break;default:r=[]}(!r[s]||r[s]&&!a)&&(r[s]=_t.newElement()),r[s][0]=t,r[s][1]=e},kt.prototype.setTripleAt=function(t,e,i,s,a,r,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(i,s,"o",n,o),this.setXYAt(a,r,"i",n,o)},kt.prototype.reverse=function(){var t=new kt;t.setPathData(this.c,this._length);var e=this.v,i=this.o,s=this.i,a=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],s[0][0],s[0][1],i[0][0],i[0][1],0,!1),a=1);var r,n=this._length-1,o=this._length;for(r=a;r<o;r+=1)t.setTripleAt(e[n][0],e[n][1],s[n][0],s[n][1],i[n][0],i[n][1],r,!1),n-=1;return t},kt.prototype.length=function(){return this._length};var Pt,At=((Pt=it(4,(function(){return new kt}),(function(t){var e,i=t._length;for(e=0;e<i;e+=1)_t.release(t.v[e]),_t.release(t.i[e]),_t.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1}))).clone=function(t){var e,i=Pt.newElement(),s=void 0===t._length?t.v.length:t._length;for(i.setLength(s),i.c=t.c,e=0;e<s;e+=1)i.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return i},Pt);function St(){this._length=0,this._maxLength=4,this.shapes=l(this._maxLength)}St.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(l(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},St.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)At.release(this.shapes[t]);this._length=0};var xt,wt,Dt,Ct,Mt=(xt={newShapeCollection:function(){return wt?Ct[wt-=1]:new St},release:function(t){var e,i=t._length;for(e=0;e<i;e+=1)At.release(t.shapes[e]);t._length=0,wt===Dt&&(Ct=et.double(Ct),Dt*=2),Ct[wt]=t,wt+=1}},wt=0,Ct=l(Dt=4),xt),Tt=function(){var t=-999999;function e(t,e,i){var s,a,r,n,o,h,l,p,f,d=i.lastIndex,m=this.keyframes;if(t<m[0].t-this.offsetTime)s=m[0].s[0],r=!0,d=0;else if(t>=m[m.length-1].t-this.offsetTime)s=m[m.length-1].s?m[m.length-1].s[0]:m[m.length-2].e[0],r=!0;else{for(var c,u,g,y=d,v=m.length-1,b=!0;b&&(c=m[y],!((u=m[y+1]).t-this.offsetTime>t));)y<v-1?y+=1:b=!1;if(g=this.keyframesMetadata[y]||{},d=y,!(r=1===c.h)){if(t>=u.t-this.offsetTime)p=1;else if(t<c.t-this.offsetTime)p=0;else{var _;g.__fnct?_=g.__fnct:(_=tt.getBezierEasing(c.o.x,c.o.y,c.i.x,c.i.y).get,g.__fnct=_),p=_((t-(c.t-this.offsetTime))/(u.t-this.offsetTime-(c.t-this.offsetTime)))}a=u.s?u.s[0]:c.e[0]}s=c.s[0]}for(h=e._length,l=s.i[0].length,i.lastIndex=d,n=0;n<h;n+=1)for(o=0;o<l;o+=1)f=r?s.i[n][o]:s.i[n][o]+(a.i[n][o]-s.i[n][o])*p,e.i[n][o]=f,f=r?s.o[n][o]:s.o[n][o]+(a.o[n][o]-s.o[n][o])*p,e.o[n][o]=f,f=r?s.v[n][o]:s.v[n][o]+(a.v[n][o]-s.v[n][o])*p,e.v[n][o]=f}function i(){var e=this.comp.renderedFrame-this.offsetTime,i=this.keyframes[0].t-this.offsetTime,s=this.keyframes[this.keyframes.length-1].t-this.offsetTime,a=this._caching.lastFrame;return a!==t&&(a<i&&e<i||a>s&&e>s)||(this._caching.lastIndex=a<e?this._caching.lastIndex:0,this.interpolateShape(e,this.pv,this._caching)),this._caching.lastFrame=e,this.pv}function s(){this.paths=this.localShapeCollection}function a(t){(function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var i,s=t._length;for(i=0;i<s;i+=1)if(t.v[i][0]!==e.v[i][0]||t.v[i][1]!==e.v[i][1]||t.o[i][0]!==e.o[i][0]||t.o[i][1]!==e.o[i][1]||t.i[i][0]!==e.i[i][0]||t.i[i][1]!==e.i[i][1])return!1;return!0})(this.v,t)||(this.v=At.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function n(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t,e;this.lock=!0,this._mdf=!1,t=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k;var i=this.effectsSequence.length;for(e=0;e<i;e+=1)t=this.effectsSequence[e](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function o(t,e,i){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var a=3===i?e.pt.k:e.ks.k;this.v=At.clone(a),this.pv=At.clone(this.v),this.localShapeCollection=Mt.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=s,this.effectsSequence=[]}function h(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function l(e,a,r){this.propType="shape",this.comp=e.comp,this.elem=e,this.container=e,this.offsetTime=e.data.st,this.keyframes=3===r?a.pt.k:a.ks.k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;var n=this.keyframes[0].s[0].i.length;this.v=At.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,n),this.pv=At.clone(this.v),this.localShapeCollection=Mt.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=t,this.reset=s,this._caching={lastFrame:t,lastIndex:0},this.effectsSequence=[i.bind(this)]}o.prototype.interpolateShape=e,o.prototype.getValue=n,o.prototype.setVValue=a,o.prototype.addEffect=h,l.prototype.getValue=n,l.prototype.interpolateShape=e,l.prototype.setVValue=a,l.prototype.addEffect=h;var p=function(){var t=A;function e(t,e){this.v=At.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=Mt.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=vt.getProp(t,e.p,1,0,this),this.s=vt.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}return e.prototype={reset:s,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var e=this.p.v[0],i=this.p.v[1],s=this.s.v[0]/2,a=this.s.v[1]/2,r=3!==this.d,n=this.v;n.v[0][0]=e,n.v[0][1]=i-a,n.v[1][0]=r?e+s:e-s,n.v[1][1]=i,n.v[2][0]=e,n.v[2][1]=i+a,n.v[3][0]=r?e-s:e+s,n.v[3][1]=i,n.i[0][0]=r?e-s*t:e+s*t,n.i[0][1]=i-a,n.i[1][0]=r?e+s:e-s,n.i[1][1]=i-a*t,n.i[2][0]=r?e+s*t:e-s*t,n.i[2][1]=i+a,n.i[3][0]=r?e-s:e+s,n.i[3][1]=i+a*t,n.o[0][0]=r?e+s*t:e-s*t,n.o[0][1]=i-a,n.o[1][0]=r?e+s:e-s,n.o[1][1]=i+a*t,n.o[2][0]=r?e-s*t:e+s*t,n.o[2][1]=i+a,n.o[3][0]=r?e-s:e+s,n.o[3][1]=i-a*t}},r([bt],e),e}(),f=function(){function t(t,e){this.v=At.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=vt.getProp(t,e.ir,0,0,this),this.is=vt.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=vt.getProp(t,e.pt,0,0,this),this.p=vt.getProp(t,e.p,1,0,this),this.r=vt.getProp(t,e.r,0,P,this),this.or=vt.getProp(t,e.or,0,0,this),this.os=vt.getProp(t,e.os,0,.01,this),this.localShapeCollection=Mt.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}return t.prototype={reset:s,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,i,s,a=2*Math.floor(this.pt.v),r=2*Math.PI/a,n=!0,o=this.or.v,h=this.ir.v,l=this.os.v,p=this.is.v,f=2*Math.PI*o/(2*a),d=2*Math.PI*h/(2*a),m=-Math.PI/2;m+=this.r.v;var c=3===this.data.d?-1:1;for(this.v._length=0,t=0;t<a;t+=1){i=n?l:p,s=n?f:d;var u=(e=n?o:h)*Math.cos(m),g=e*Math.sin(m),y=0===u&&0===g?0:g/Math.sqrt(u*u+g*g),v=0===u&&0===g?0:-u/Math.sqrt(u*u+g*g);u+=+this.p.v[0],g+=+this.p.v[1],this.v.setTripleAt(u,g,u-y*s*i*c,g-v*s*i*c,u+y*s*i*c,g+v*s*i*c,t,!0),n=!n,m+=r*c}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),i=2*Math.PI/e,s=this.or.v,a=this.os.v,r=2*Math.PI*s/(4*e),n=.5*-Math.PI,o=3===this.data.d?-1:1;for(n+=this.r.v,this.v._length=0,t=0;t<e;t+=1){var h=s*Math.cos(n),l=s*Math.sin(n),p=0===h&&0===l?0:l/Math.sqrt(h*h+l*l),f=0===h&&0===l?0:-h/Math.sqrt(h*h+l*l);h+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(h,l,h-p*r*a*o,l-f*r*a*o,h+p*r*a*o,l+f*r*a*o,t,!0),n+=i*o}this.paths.length=0,this.paths[0]=this.v}},r([bt],t),t}(),d=function(){function t(t,e){this.v=At.newElement(),this.v.c=!0,this.localShapeCollection=Mt.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=vt.getProp(t,e.p,1,0,this),this.s=vt.getProp(t,e.s,1,0,this),this.r=vt.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}return t.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,s=this.s.v[1]/2,a=b(i,s,this.r.v),r=a*(1-A);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+i,e-s+a,t+i,e-s+a,t+i,e-s+r,0,!0),this.v.setTripleAt(t+i,e+s-a,t+i,e+s-r,t+i,e+s-a,1,!0),0!==a?(this.v.setTripleAt(t+i-a,e+s,t+i-a,e+s,t+i-r,e+s,2,!0),this.v.setTripleAt(t-i+a,e+s,t-i+r,e+s,t-i+a,e+s,3,!0),this.v.setTripleAt(t-i,e+s-a,t-i,e+s-a,t-i,e+s-r,4,!0),this.v.setTripleAt(t-i,e-s+a,t-i,e-s+r,t-i,e-s+a,5,!0),this.v.setTripleAt(t-i+a,e-s,t-i+a,e-s,t-i+r,e-s,6,!0),this.v.setTripleAt(t+i-a,e-s,t+i-r,e-s,t+i-a,e-s,7,!0)):(this.v.setTripleAt(t-i,e+s,t-i+r,e+s,t-i,e+s,2),this.v.setTripleAt(t-i,e-s,t-i,e-s+r,t-i,e-s,3))):(this.v.setTripleAt(t+i,e-s+a,t+i,e-s+r,t+i,e-s+a,0,!0),0!==a?(this.v.setTripleAt(t+i-a,e-s,t+i-a,e-s,t+i-r,e-s,1,!0),this.v.setTripleAt(t-i+a,e-s,t-i+r,e-s,t-i+a,e-s,2,!0),this.v.setTripleAt(t-i,e-s+a,t-i,e-s+a,t-i,e-s+r,3,!0),this.v.setTripleAt(t-i,e+s-a,t-i,e+s-r,t-i,e+s-a,4,!0),this.v.setTripleAt(t-i+a,e+s,t-i+a,e+s,t-i+r,e+s,5,!0),this.v.setTripleAt(t+i-a,e+s,t+i-r,e+s,t+i-a,e+s,6,!0),this.v.setTripleAt(t+i,e+s-a,t+i,e+s-a,t+i,e+s-r,7,!0)):(this.v.setTripleAt(t-i,e-s,t-i+r,e-s,t-i,e-s,1,!0),this.v.setTripleAt(t-i,e+s,t-i,e+s-r,t-i,e+s,2,!0),this.v.setTripleAt(t+i,e+s,t+i-r,e+s,t+i,e+s,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:s},r([bt],t),t}();var m={getShapeProp:function(t,e,i){var s;return 3===i||4===i?s=(3===i?e.pt:e.ks).k.length?new l(t,e,i):new o(t,e,i):5===i?s=new d(t,e):6===i?s=new p(t,e):7===i&&(s=new f(t,e)),s.k&&t.addDynamicProperty(s),s},getConstructorFunction:function(){return o},getKeyframedConstructorFunction:function(){return l}};return m}(),Ft=function(){var t=Math.cos,e=Math.sin,i=Math.tan,s=Math.round;function a(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function r(i){if(0===i)return this;var s=t(i),a=e(i);return this._t(s,-a,0,0,a,s,0,0,0,0,1,0,0,0,0,1)}function n(i){if(0===i)return this;var s=t(i),a=e(i);return this._t(1,0,0,0,0,s,-a,0,0,a,s,0,0,0,0,1)}function o(i){if(0===i)return this;var s=t(i),a=e(i);return this._t(s,0,a,0,0,1,0,0,-a,0,s,0,0,0,0,1)}function l(i){if(0===i)return this;var s=t(i),a=e(i);return this._t(s,-a,0,0,a,s,0,0,0,0,1,0,0,0,0,1)}function p(t,e){return this._t(1,e,t,1,0,0)}function f(t,e){return this.shear(i(t),i(e))}function d(s,a){var r=t(a),n=e(a);return this._t(r,n,0,0,-n,r,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,i(s),1,0,0,0,0,1,0,0,0,0,1)._t(r,-n,0,0,n,r,0,0,0,0,1,0,0,0,0,1)}function m(t,e,i){return i||0===i||(i=1),1===t&&1===e&&1===i?this:this._t(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1)}function c(t,e,i,s,a,r,n,o,h,l,p,f,d,m,c,u){return this.props[0]=t,this.props[1]=e,this.props[2]=i,this.props[3]=s,this.props[4]=a,this.props[5]=r,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=l,this.props[10]=p,this.props[11]=f,this.props[12]=d,this.props[13]=m,this.props[14]=c,this.props[15]=u,this}function u(t,e,i){return i=i||0,0!==t||0!==e||0!==i?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,i,1):this}function g(t,e,i,s,a,r,n,o,h,l,p,f,d,m,c,u){var g=this.props;if(1===t&&0===e&&0===i&&0===s&&0===a&&1===r&&0===n&&0===o&&0===h&&0===l&&1===p&&0===f)return g[12]=g[12]*t+g[15]*d,g[13]=g[13]*r+g[15]*m,g[14]=g[14]*p+g[15]*c,g[15]*=u,this._identityCalculated=!1,this;var y=g[0],v=g[1],b=g[2],_=g[3],k=g[4],P=g[5],A=g[6],S=g[7],x=g[8],w=g[9],D=g[10],C=g[11],M=g[12],T=g[13],F=g[14],E=g[15];return g[0]=y*t+v*a+b*h+_*d,g[1]=y*e+v*r+b*l+_*m,g[2]=y*i+v*n+b*p+_*c,g[3]=y*s+v*o+b*f+_*u,g[4]=k*t+P*a+A*h+S*d,g[5]=k*e+P*r+A*l+S*m,g[6]=k*i+P*n+A*p+S*c,g[7]=k*s+P*o+A*f+S*u,g[8]=x*t+w*a+D*h+C*d,g[9]=x*e+w*r+D*l+C*m,g[10]=x*i+w*n+D*p+C*c,g[11]=x*s+w*o+D*f+C*u,g[12]=M*t+T*a+F*h+E*d,g[13]=M*e+T*r+F*l+E*m,g[14]=M*i+T*n+F*p+E*c,g[15]=M*s+T*o+F*f+E*u,this._identityCalculated=!1,this}function y(t){var e=t.props;return this.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}function v(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function b(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function _(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function k(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function P(t,e,i){return{x:t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}}function A(t,e,i){return t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12]}function S(t,e,i){return t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13]}function x(t,e,i){return t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}function w(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,i=-this.props[1]/t,s=-this.props[4]/t,a=this.props[0]/t,r=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,n=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,o=new Ft;return o.props[0]=e,o.props[1]=i,o.props[4]=s,o.props[5]=a,o.props[12]=r,o.props[13]=n,o}function D(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function C(t){var e,i=t.length,s=[];for(e=0;e<i;e+=1)s[e]=D(t[e]);return s}function M(t,e,i){var s=h("float32",6);if(this.isIdentity())s[0]=t[0],s[1]=t[1],s[2]=e[0],s[3]=e[1],s[4]=i[0],s[5]=i[1];else{var a=this.props[0],r=this.props[1],n=this.props[4],o=this.props[5],l=this.props[12],p=this.props[13];s[0]=t[0]*a+t[1]*n+l,s[1]=t[0]*r+t[1]*o+p,s[2]=e[0]*a+e[1]*n+l,s[3]=e[0]*r+e[1]*o+p,s[4]=i[0]*a+i[1]*n+l,s[5]=i[0]*r+i[1]*o+p}return s}function T(t,e,i){return this.isIdentity()?[t,e,i]:[t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]]}function F(t,e){if(this.isIdentity())return t+","+e;var i=this.props;return Math.round(100*(t*i[0]+e*i[4]+i[12]))/100+","+Math.round(100*(t*i[1]+e*i[5]+i[13]))/100}function E(){for(var t=0,e=this.props,i="matrix3d(";t<16;)i+=s(1e4*e[t])/1e4,i+=15===t?")":",",t+=1;return i}function I(t){return t<1e-6&&t>0||t>-1e-6&&t<0?s(1e4*t)/1e4:t}function L(){var t=this.props;return"matrix("+I(t[0])+","+I(t[1])+","+I(t[4])+","+I(t[5])+","+I(t[12])+","+I(t[13])+")"}return function(){this.reset=a,this.rotate=r,this.rotateX=n,this.rotateY=o,this.rotateZ=l,this.skew=f,this.skewFromAxis=d,this.shear=p,this.scale=m,this.setTransform=c,this.translate=u,this.transform=g,this.multiply=y,this.applyToPoint=P,this.applyToX=A,this.applyToY=S,this.applyToZ=x,this.applyToPointArray=T,this.applyToTriplePoints=M,this.applyToPointStringified=F,this.toCSS=E,this.to2dCSS=L,this.clone=_,this.cloneFromProps=k,this.equals=b,this.inversePoints=C,this.inversePoint=D,this.getInverseMatrix=w,this._t=this.transform,this.isIdentity=v,this._identity=!0,this._identityCalculated=!1,this.props=h("float32",16),this.reset()}}();function Et(t){return Et="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Et(t)}var It={};function Lt(){$.searchAnimations()}It.play=$.play,It.pause=$.pause,It.setLocationHref=function(e){t=e},It.togglePause=$.togglePause,It.setSpeed=$.setSpeed,It.setDirection=$.setDirection,It.stop=$.stop,It.searchAnimations=Lt,It.registerAnimation=$.registerAnimation,It.loadAnimation=function(t){return $.loadAnimation(t)},It.setSubframeRendering=function(t){!function(t){f=!!t}(t)},It.resize=$.resize,It.goToAndStop=$.goToAndStop,It.destroy=$.destroy,It.setQuality=function(t){if("string"==typeof t)switch(t){case"high":q(200);break;default:case"medium":q(50);break;case"low":q(10)}else!isNaN(t)&&t>1&&q(t);j()>=50?S(!1):S(!0)},It.inBrowser=function(){return"undefined"!=typeof navigator},It.installPlugin=function(t,e){"expressions"===t&&(d=e)},It.freeze=$.freeze,It.unfreeze=$.unfreeze,It.setVolume=$.setVolume,It.mute=$.mute,It.unmute=$.unmute,It.getRegisteredAnimations=$.getRegisteredAnimations,It.useWebWorker=function(t){e=!!t},It.setIDPrefix=function(t){c=t},It.__getFactory=function(t){switch(t){case"propertyFactory":return vt;case"shapePropertyFactory":return Tt;case"matrix":return Ft;default:return null}},It.version="5.12.2";var Vt="",Rt=document.getElementsByTagName("script"),zt=Rt[Rt.length-1]||{src:""};Vt=zt.src?zt.src.replace(/^[^\?]+\??/,""):"",function(t){for(var e=Vt.split("&"),i=0;i<e.length;i+=1){var s=e[i].split("=");if(decodeURIComponent(s[0])==t)return decodeURIComponent(s[1])}}("renderer");var Ot=setInterval((function(){"complete"===document.readyState&&(clearInterval(Ot),Lt())}),100);try{"object"===("undefined"==typeof exports?"undefined":Et(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=It)}catch(t){}var Nt=function(){var t={},e={};return t.registerModifier=function(t,i){e[t]||(e[t]=i)},t.getModifier=function(t,i,s){return new e[t](i,s)},t}();function Bt(){}function qt(){}function jt(){}Bt.prototype.initModifierProperties=function(){},Bt.prototype.addShapeToModifier=function(){},Bt.prototype.addShape=function(t){if(!this.closed){t.sh.container.addDynamicProperty(t.sh);var e={shape:t.sh,data:t,localShapeCollection:Mt.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},Bt.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=i,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},Bt.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},r([bt],Bt),r([Bt],qt),qt.prototype.initModifierProperties=function(t,e){this.s=vt.getProp(t,e.s,0,.01,this),this.e=vt.getProp(t,e.e,0,.01,this),this.o=vt.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},qt.prototype.addShapeToModifier=function(t){t.pathsData=[]},qt.prototype.calculateShapeEdges=function(t,e,i,s,a){var r=[];e<=1?r.push({s:t,e:e}):t>=1?r.push({s:t-1,e:e-1}):(r.push({s:t,e:1}),r.push({s:0,e:e-1}));var n,o,h=[],l=r.length;for(n=0;n<l;n+=1){var p,f;if(!((o=r[n]).e*a<s||o.s*a>s+i))p=o.s*a<=s?0:(o.s*a-s)/i,f=o.e*a>=s+i?1:(o.e*a-s)/i,h.push([p,f])}return h.length||h.push([0,0]),h},qt.prototype.releasePathsData=function(t){var e,i=t.length;for(e=0;e<i;e+=1)at.release(t[e]);return t.length=0,t},qt.prototype.processShapes=function(t){var e,i,s,a;if(this._mdf||t){var r=this.o.v%360/360;if(r<0&&(r+=1),(e=this.s.v>1?1+r:this.s.v<0?0+r:this.s.v+r)>(i=this.e.v>1?1+r:this.e.v<0?0+r:this.e.v+r)){var n=e;e=i,i=n}e=1e-4*Math.round(1e4*e),i=1e-4*Math.round(1e4*i),this.sValue=e,this.eValue=i}else e=this.sValue,i=this.eValue;var o,h,l,p,f,d=this.shapes.length,m=0;if(i===e)for(a=0;a<d;a+=1)this.shapes[a].localShapeCollection.releaseShapes(),this.shapes[a].shape._mdf=!0,this.shapes[a].shape.paths=this.shapes[a].localShapeCollection,this._mdf&&(this.shapes[a].pathsData.length=0);else if(1===i&&0===e||0===i&&1===e){if(this._mdf)for(a=0;a<d;a+=1)this.shapes[a].pathsData.length=0,this.shapes[a].shape._mdf=!0}else{var c,u,g=[];for(a=0;a<d;a+=1)if((c=this.shapes[a]).shape._mdf||this._mdf||t||2===this.m){if(h=(s=c.shape.paths)._length,f=0,!c.shape._mdf&&c.pathsData.length)f=c.totalShapeLength;else{for(l=this.releasePathsData(c.pathsData),o=0;o<h;o+=1)p=rt.getSegmentsLength(s.shapes[o]),l.push(p),f+=p.totalLength;c.totalShapeLength=f,c.pathsData=l}m+=f,c.shape._mdf=!0}else c.shape.paths=c.localShapeCollection;var y,v=e,b=i,_=0;for(a=d-1;a>=0;a-=1)if((c=this.shapes[a]).shape._mdf){for((u=c.localShapeCollection).releaseShapes(),2===this.m&&d>1?(y=this.calculateShapeEdges(e,i,c.totalShapeLength,_,m),_+=c.totalShapeLength):y=[[v,b]],h=y.length,o=0;o<h;o+=1){v=y[o][0],b=y[o][1],g.length=0,b<=1?g.push({s:c.totalShapeLength*v,e:c.totalShapeLength*b}):v>=1?g.push({s:c.totalShapeLength*(v-1),e:c.totalShapeLength*(b-1)}):(g.push({s:c.totalShapeLength*v,e:c.totalShapeLength}),g.push({s:0,e:c.totalShapeLength*(b-1)}));var k=this.addShapes(c,g[0]);if(g[0].s!==g[0].e){if(g.length>1)if(c.shape.paths.shapes[c.shape.paths._length-1].c){var P=k.pop();this.addPaths(k,u),k=this.addShapes(c,g[1],P)}else this.addPaths(k,u),k=this.addShapes(c,g[1]);this.addPaths(k,u)}}c.shape.paths=u}}},qt.prototype.addPaths=function(t,e){var i,s=t.length;for(i=0;i<s;i+=1)e.addShape(t[i])},qt.prototype.addSegment=function(t,e,i,s,a,r,n){a.setXYAt(e[0],e[1],"o",r),a.setXYAt(i[0],i[1],"i",r+1),n&&a.setXYAt(t[0],t[1],"v",r),a.setXYAt(s[0],s[1],"v",r+1)},qt.prototype.addSegmentFromArray=function(t,e,i,s){e.setXYAt(t[1],t[5],"o",i),e.setXYAt(t[2],t[6],"i",i+1),s&&e.setXYAt(t[0],t[4],"v",i),e.setXYAt(t[3],t[7],"v",i+1)},qt.prototype.addShapes=function(t,e,i){var s,a,r,n,o,h,l,p,f=t.pathsData,d=t.shape.paths.shapes,m=t.shape.paths._length,c=0,u=[],g=!0;for(i?(o=i._length,p=i._length):(i=At.newElement(),o=0,p=0),u.push(i),s=0;s<m;s+=1){for(h=f[s].lengths,i.c=d[s].c,r=d[s].c?h.length:h.length+1,a=1;a<r;a+=1)if(c+(n=h[a-1]).addedLength<e.s)c+=n.addedLength,i.c=!1;else{if(c>e.e){i.c=!1;break}e.s<=c&&e.e>=c+n.addedLength?(this.addSegment(d[s].v[a-1],d[s].o[a-1],d[s].i[a],d[s].v[a],i,o,g),g=!1):(l=rt.getNewSegment(d[s].v[a-1],d[s].v[a],d[s].o[a-1],d[s].i[a],(e.s-c)/n.addedLength,(e.e-c)/n.addedLength,h[a-1]),this.addSegmentFromArray(l,i,o,g),g=!1,i.c=!1),c+=n.addedLength,o+=1}if(d[s].c&&h.length){if(n=h[a-1],c<=e.e){var y=h[a-1].addedLength;e.s<=c&&e.e>=c+y?(this.addSegment(d[s].v[a-1],d[s].o[a-1],d[s].i[0],d[s].v[0],i,o,g),g=!1):(l=rt.getNewSegment(d[s].v[a-1],d[s].v[0],d[s].o[a-1],d[s].i[0],(e.s-c)/y,(e.e-c)/y,h[a-1]),this.addSegmentFromArray(l,i,o,g),g=!1,i.c=!1)}else i.c=!1;c+=n.addedLength,o+=1}if(i._length&&(i.setXYAt(i.v[p][0],i.v[p][1],"i",p),i.setXYAt(i.v[i._length-1][0],i.v[i._length-1][1],"o",i._length-1)),c>e.e)break;s<m-1&&(i=At.newElement(),g=!0,u.push(i),o=0)}return u},r([Bt],jt),jt.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=vt.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},jt.prototype.processPath=function(t,e){var i=e/100,s=[0,0],a=t._length,r=0;for(r=0;r<a;r+=1)s[0]+=t.v[r][0],s[1]+=t.v[r][1];s[0]/=a,s[1]/=a;var n,o,h,l,p,f,d=At.newElement();for(d.c=t.c,r=0;r<a;r+=1)n=t.v[r][0]+(s[0]-t.v[r][0])*i,o=t.v[r][1]+(s[1]-t.v[r][1])*i,h=t.o[r][0]+(s[0]-t.o[r][0])*-i,l=t.o[r][1]+(s[1]-t.o[r][1])*-i,p=t.i[r][0]+(s[0]-t.i[r][0])*-i,f=t.i[r][1]+(s[1]-t.i[r][1])*-i,d.setTripleAt(n,o,h,l,p,f,r);return d},jt.prototype.processShapes=function(t){var e,i,s,a,r,n,o=this.shapes.length,h=this.amount.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(r=this.shapes[i]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,s=0;s<a;s+=1)n.addShape(this.processPath(e[s],h));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var Wt=function(){var t=[0,0];function e(t,e,i){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Ft,this.pre=new Ft,this.appliedTransformations=0,this.initDynamicPropertyContainer(i||t),e.p&&e.p.s?(this.px=vt.getProp(t,e.p.x,0,0,this),this.py=vt.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=vt.getProp(t,e.p.z,0,0,this))):this.p=vt.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=vt.getProp(t,e.rx,0,P,this),this.ry=vt.getProp(t,e.ry,0,P,this),this.rz=vt.getProp(t,e.rz,0,P,this),e.or.k[0].ti){var s,a=e.or.k.length;for(s=0;s<a;s+=1)e.or.k[s].to=null,e.or.k[s].ti=null}this.or=vt.getProp(t,e.or,1,P,this),this.or.sh=!0}else this.r=vt.getProp(t,e.r||{k:0},0,P,this);e.sk&&(this.sk=vt.getProp(t,e.sk,0,P,this),this.sa=vt.getProp(t,e.sa,0,P,this)),this.a=vt.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=vt.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=vt.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return e.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(e){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||e){var i;if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var s,a;if(i=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime)this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(s=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/i,0),a=this.p.getValueAtTime(this.p.keyframes[0].t/i,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(s=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/i,0),a=this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/i,0)):(s=this.p.pv,a=this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/i,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){s=[],a=[];var r=this.px,n=this.py;r._caching.lastFrame+r.offsetTime<=r.keyframes[0].t?(s[0]=r.getValueAtTime((r.keyframes[0].t+.01)/i,0),s[1]=n.getValueAtTime((n.keyframes[0].t+.01)/i,0),a[0]=r.getValueAtTime(r.keyframes[0].t/i,0),a[1]=n.getValueAtTime(n.keyframes[0].t/i,0)):r._caching.lastFrame+r.offsetTime>=r.keyframes[r.keyframes.length-1].t?(s[0]=r.getValueAtTime(r.keyframes[r.keyframes.length-1].t/i,0),s[1]=n.getValueAtTime(n.keyframes[n.keyframes.length-1].t/i,0),a[0]=r.getValueAtTime((r.keyframes[r.keyframes.length-1].t-.01)/i,0),a[1]=n.getValueAtTime((n.keyframes[n.keyframes.length-1].t-.01)/i,0)):(s=[r.pv,n.pv],a[0]=r.getValueAtTime((r._caching.lastFrame+r.offsetTime-.01)/i,r.offsetTime),a[1]=n.getValueAtTime((n._caching.lastFrame+n.offsetTime-.01)/i,n.offsetTime))}else s=a=t;this.v.rotate(-Math.atan2(s[1]-a[1],s[0]-a[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},r([bt],e),e.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},e.prototype._addDynamicProperty=bt.prototype.addDynamicProperty,{getTransformProperty:function(t,i,s){return new e(t,i,s)}}}();function Xt(){}function Ht(){}function Yt(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function Gt(t){return Math.abs(t)<=1e-5}function Kt(t,e,i){return t*(1-i)+e*i}function Jt(t,e,i){return[Kt(t[0],e[0],i),Kt(t[1],e[1],i)]}function Ut(t,e,i,s){return[3*e-t-3*i+s,3*t-6*e+3*i,-3*t+3*e,t]}function Zt(t){return new Qt(t,t,t,t,!1)}function Qt(t,e,i,s,a){a&&oe(t,e)&&(e=Jt(t,s,1/3)),a&&oe(i,s)&&(i=Jt(t,s,2/3));var r=Ut(t[0],e[0],i[0],s[0]),n=Ut(t[1],e[1],i[1],s[1]);this.a=[r[0],n[0]],this.b=[r[1],n[1]],this.c=[r[2],n[2]],this.d=[r[3],n[3]],this.points=[t,e,i,s]}function $t(t,e){var i=t.points[0][e],s=t.points[t.points.length-1][e];if(i>s){var a=s;s=i,i=a}for(var r=function(t,e,i){if(0===t)return[];var s=e*e-4*t*i;if(s<0)return[];var a=-e/(2*t);if(0===s)return[a];var r=Math.sqrt(s)/(2*t);return[a-r,a+r]}(3*t.a[e],2*t.b[e],t.c[e]),n=0;n<r.length;n+=1)if(r[n]>0&&r[n]<1){var o=t.point(r[n])[e];o<i?i=o:o>s&&(s=o)}return{min:i,max:s}}function te(t,e,i){var s=t.boundingBox();return{cx:s.cx,cy:s.cy,width:s.width,height:s.height,bez:t,t:(e+i)/2,t1:e,t2:i}}function ee(t){var e=t.bez.split(.5);return[te(e[0],t.t1,t.t),te(e[1],t.t,t.t2)]}function ie(t,e,i,s,a,r){var n,o;if(n=t,o=e,2*Math.abs(n.cx-o.cx)<n.width+o.width&&2*Math.abs(n.cy-o.cy)<n.height+o.height)if(i>=r||t.width<=s&&t.height<=s&&e.width<=s&&e.height<=s)a.push([t.t,e.t]);else{var h=ee(t),l=ee(e);ie(h[0],l[0],i+1,s,a,r),ie(h[0],l[1],i+1,s,a,r),ie(h[1],l[0],i+1,s,a,r),ie(h[1],l[1],i+1,s,a,r)}}function se(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function ae(t,e,i,s){var a=[t[0],t[1],1],r=[e[0],e[1],1],n=[i[0],i[1],1],o=[s[0],s[1],1],h=se(se(a,r),se(n,o));return Gt(h[2])?null:[h[0]/h[2],h[1]/h[2]]}function re(t,e,i){return[t[0]+Math.cos(e)*i,t[1]-Math.sin(e)*i]}function ne(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function oe(t,e){return Yt(t[0],e[0])&&Yt(t[1],e[1])}function he(){}function le(t,e,i,s,a,r,n){var o=i-Math.PI/2,h=i+Math.PI/2,l=e[0]+Math.cos(i)*s*a,p=e[1]-Math.sin(i)*s*a;t.setTripleAt(l,p,l+Math.cos(o)*r,p-Math.sin(o)*r,l+Math.cos(h)*n,p-Math.sin(h)*n,t.length())}function pe(t,e){var i,s,a,r,n=0===e?t.length()-1:e-1,o=(e+1)%t.length(),h=t.v[n],l=t.v[o],p=(i=h,a=[(s=l)[0]-i[0],s[1]-i[1]],r=.5*-Math.PI,[Math.cos(r)*a[0]-Math.sin(r)*a[1],Math.sin(r)*a[0]+Math.cos(r)*a[1]]);return Math.atan2(0,1)-Math.atan2(p[1],p[0])}function fe(t,e,i,s,a,r,n){var o=pe(e,i),h=e.v[i%e._length],l=e.v[0===i?e._length-1:i-1],p=e.v[(i+1)%e._length],f=2===r?Math.sqrt(Math.pow(h[0]-l[0],2)+Math.pow(h[1]-l[1],2)):0,d=2===r?Math.sqrt(Math.pow(h[0]-p[0],2)+Math.pow(h[1]-p[1],2)):0;le(t,e.v[i%e._length],o,n,s,d/(2*(a+1)),f/(2*(a+1)))}function de(t,e,i,s,a,r){for(var n=0;n<s;n+=1){var o=(n+1)/(s+1),h=2===a?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(o);le(t,e.point(o),l,r,i,h/(2*(s+1)),h/(2*(s+1))),r=-r}return r}function me(t,e,i){var s=Math.atan2(e[0]-t[0],e[1]-t[1]);return[re(t,s,i),re(e,s,i)]}function ce(t,e){var i,s,a,r,n,o,h;i=(h=me(t.points[0],t.points[1],e))[0],s=h[1],a=(h=me(t.points[1],t.points[2],e))[0],r=h[1],n=(h=me(t.points[2],t.points[3],e))[0],o=h[1];var l=ae(i,s,a,r);null===l&&(l=s);var p=ae(n,o,a,r);return null===p&&(p=n),new Qt(i,l,p,o)}function ue(t,e,i,s,a){var r=e.points[3],n=i.points[0];if(3===s)return r;if(oe(r,n))return r;if(2===s){var o=-e.tangentAngle(1),h=-i.tangentAngle(0)+Math.PI,l=ae(r,re(r,o+Math.PI/2,100),n,re(n,o+Math.PI/2,100)),p=l?ne(l,r):ne(r,n)/2,f=re(r,o,2*p*A);return t.setXYAt(f[0],f[1],"o",t.length()-1),f=re(n,h,2*p*A),t.setTripleAt(n[0],n[1],n[0],n[1],f[0],f[1],t.length()),n}var d=ae(oe(r,e.points[2])?e.points[0]:e.points[2],r,n,oe(n,i.points[1])?i.points[3]:i.points[1]);return d&&ne(d,r)<a?(t.setTripleAt(d[0],d[1],d[0],d[1],d[0],d[1],t.length()),d):r}function ge(t,e){var i=t.intersections(e);return i.length&&Yt(i[0][0],1)&&i.shift(),i.length?i[0]:null}function ye(t,e){var i=t.slice(),s=e.slice(),a=ge(t[t.length-1],e[0]);return a&&(i[t.length-1]=t[t.length-1].split(a[0])[0],s[0]=e[0].split(a[1])[1]),t.length>1&&e.length>1&&(a=ge(t[0],e[e.length-1]))?[[t[0].split(a[0])[0]],[e[e.length-1].split(a[1])[1]]]:[i,s]}function ve(t,e){var i,s,a,r,n=t.inflectionPoints();if(0===n.length)return[ce(t,e)];if(1===n.length||Yt(n[1],1))return i=(a=t.split(n[0]))[0],s=a[1],[ce(i,e),ce(s,e)];i=(a=t.split(n[0]))[0];var o=(n[1]-n[0])/(1-n[0]);return r=(a=a[1].split(o))[0],s=a[1],[ce(i,e),ce(r,e),ce(s,e)]}function be(){}function _e(t){for(var e=t.fStyle?t.fStyle.split(" "):[],i="normal",s="normal",a=e.length,r=0;r<a;r+=1)switch(e[r].toLowerCase()){case"italic":s="italic";break;case"bold":i="700";break;case"black":i="900";break;case"medium":i="500";break;case"regular":case"normal":i="400";break;case"light":case"thin":i="200"}return{style:s,weight:t.fWeight||i}}r([Bt],Xt),Xt.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=vt.getProp(t,e.c,0,null,this),this.o=vt.getProp(t,e.o,0,null,this),this.tr=Wt.getTransformProperty(t,e.tr,this),this.so=vt.getProp(t,e.tr.so,0,.01,this),this.eo=vt.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Ft,this.rMatrix=new Ft,this.sMatrix=new Ft,this.tMatrix=new Ft,this.matrix=new Ft},Xt.prototype.applyTransforms=function(t,e,i,s,a,r){var n=r?-1:1,o=s.s.v[0]+(1-s.s.v[0])*(1-a),h=s.s.v[1]+(1-s.s.v[1])*(1-a);t.translate(s.p.v[0]*n*a,s.p.v[1]*n*a,s.p.v[2]),e.translate(-s.a.v[0],-s.a.v[1],s.a.v[2]),e.rotate(-s.r.v*n*a),e.translate(s.a.v[0],s.a.v[1],s.a.v[2]),i.translate(-s.a.v[0],-s.a.v[1],s.a.v[2]),i.scale(r?1/o:o,r?1/h:h),i.translate(s.a.v[0],s.a.v[1],s.a.v[2])},Xt.prototype.init=function(t,e,i,s){for(this.elem=t,this.arr=e,this.pos=i,this.elemsData=s,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[i]);i>0;)i-=1,this._elements.unshift(e[i]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},Xt.prototype.resetElements=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},Xt.prototype.cloneElements=function(t){var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},Xt.prototype.changeGroupRender=function(t,e){var i,s=t.length;for(i=0;i<s;i+=1)t[i]._render=e,"gr"===t[i].ty&&this.changeGroupRender(t[i].it,e)},Xt.prototype.processShapes=function(t){var e,i,s,a,r,n=!1;if(this._mdf||t){var o,h=Math.ceil(this.c.v);if(this._groups.length<h){for(;this._groups.length<h;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(r=0,s=0;s<=this._groups.length-1;s+=1){if(o=r<h,this._groups[s]._render=o,this.changeGroupRender(this._groups[s].it,o),!o){var p=this.elemsData[s].it,f=p[p.length-1];0!==f.transform.op.v?(f.transform.op._mdf=!0,f.transform.op.v=0):f.transform.op._mdf=!1}r+=1}this._currentCopies=h;var d=this.o.v,m=d%1,c=d>0?Math.floor(d):Math.ceil(d),u=this.pMatrix.props,g=this.rMatrix.props,y=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var v,b,_=0;if(d>0){for(;_<c;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),_+=1;m&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,m,!1),_+=m)}else if(d<0){for(;_>c;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),_-=1;m&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-m,!0),_-=m)}for(s=1===this.data.m?0:this._currentCopies-1,a=1===this.data.m?1:-1,r=this._currentCopies;r;){if(b=(i=(e=this.elemsData[s].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(s/(this._currentCopies-1)),0!==_){for((0!==s&&1===a||s!==this._currentCopies-1&&-1===a)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]),v=0;v<b;v+=1)i[v]=this.matrix.props[v];this.matrix.reset()}else for(this.matrix.reset(),v=0;v<b;v+=1)i[v]=this.matrix.props[v];_+=1,r-=1,s+=a}}else for(r=this._currentCopies,s=0,a=1;r;)i=(e=this.elemsData[s].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,r-=1,s+=a;return n},Xt.prototype.addShape=function(){},r([Bt],Ht),Ht.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=vt.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},Ht.prototype.processPath=function(t,e){var i,s=At.newElement();s.c=t.c;var a,r,n,o,h,l,p,f,d,m,c,u,g=t._length,y=0;for(i=0;i<g;i+=1)a=t.v[i],n=t.o[i],r=t.i[i],a[0]===n[0]&&a[1]===n[1]&&a[0]===r[0]&&a[1]===r[1]?0!==i&&i!==g-1||t.c?(o=0===i?t.v[g-1]:t.v[i-1],l=(h=Math.sqrt(Math.pow(a[0]-o[0],2)+Math.pow(a[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=c=a[0]+(o[0]-a[0])*l,f=u=a[1]-(a[1]-o[1])*l,d=p-(p-a[0])*A,m=f-(f-a[1])*A,s.setTripleAt(p,f,d,m,c,u,y),y+=1,o=i===g-1?t.v[0]:t.v[i+1],l=(h=Math.sqrt(Math.pow(a[0]-o[0],2)+Math.pow(a[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=d=a[0]+(o[0]-a[0])*l,f=m=a[1]+(o[1]-a[1])*l,c=p-(p-a[0])*A,u=f-(f-a[1])*A,s.setTripleAt(p,f,d,m,c,u,y),y+=1):(s.setTripleAt(a[0],a[1],n[0],n[1],r[0],r[1],y),y+=1):(s.setTripleAt(t.v[i][0],t.v[i][1],t.o[i][0],t.o[i][1],t.i[i][0],t.i[i][1],y),y+=1);return s},Ht.prototype.processShapes=function(t){var e,i,s,a,r,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(r=this.shapes[i]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,s=0;s<a;s+=1)n.addShape(this.processPath(e[s],h));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},Qt.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},Qt.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},Qt.prototype.tangentAngle=function(t){var e=this.derivative(t);return Math.atan2(e[1],e[0])},Qt.prototype.normalAngle=function(t){var e=this.derivative(t);return Math.atan2(e[0],e[1])},Qt.prototype.inflectionPoints=function(){var t=this.a[1]*this.b[0]-this.a[0]*this.b[1];if(Gt(t))return[];var e=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/t,i=e*e-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/t;if(i<0)return[];var s=Math.sqrt(i);return Gt(s)?s>0&&s<1?[e]:[]:[e-s,e+s].filter((function(t){return t>0&&t<1}))},Qt.prototype.split=function(t){if(t<=0)return[Zt(this.points[0]),this];if(t>=1)return[this,Zt(this.points[this.points.length-1])];var e=Jt(this.points[0],this.points[1],t),i=Jt(this.points[1],this.points[2],t),s=Jt(this.points[2],this.points[3],t),a=Jt(e,i,t),r=Jt(i,s,t),n=Jt(a,r,t);return[new Qt(this.points[0],e,a,n,!0),new Qt(n,r,s,this.points[3],!0)]},Qt.prototype.bounds=function(){return{x:$t(this,0),y:$t(this,1)}},Qt.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},Qt.prototype.intersections=function(t,e,i){void 0===e&&(e=2),void 0===i&&(i=7);var s=[];return ie(te(this,0,1),te(t,0,1),0,e,s,i),s},Qt.shapeSegment=function(t,e){var i=(e+1)%t.length();return new Qt(t.v[e],t.o[e],t.i[i],t.v[i],!0)},Qt.shapeSegmentInverted=function(t,e){var i=(e+1)%t.length();return new Qt(t.v[i],t.i[i],t.o[e],t.v[e],!0)},r([Bt],he),he.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=vt.getProp(t,e.s,0,null,this),this.frequency=vt.getProp(t,e.r,0,null,this),this.pointsType=vt.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},he.prototype.processPath=function(t,e,i,s){var a=t._length,r=At.newElement();if(r.c=t.c,t.c||(a-=1),0===a)return r;var n=-1,o=Qt.shapeSegment(t,0);fe(r,t,0,e,i,s,n);for(var h=0;h<a;h+=1)n=de(r,o,e,i,s,-n),o=h!==a-1||t.c?Qt.shapeSegment(t,(h+1)%a):null,fe(r,t,h+1,e,i,s,n);return r},he.prototype.processShapes=function(t){var e,i,s,a,r,n,o=this.shapes.length,h=this.amplitude.v,l=Math.max(0,Math.round(this.frequency.v)),p=this.pointsType.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(r=this.shapes[i]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,s=0;s<a;s+=1)n.addShape(this.processPath(e[s],h,l,p));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},r([Bt],be),be.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=vt.getProp(t,e.a,0,null,this),this.miterLimit=vt.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},be.prototype.processPath=function(t,e,i,s){var a=At.newElement();a.c=t.c;var r,n,o,h=t.length();t.c||(h-=1);var l=[];for(r=0;r<h;r+=1)o=Qt.shapeSegment(t,r),l.push(ve(o,e));if(!t.c)for(r=h-1;r>=0;r-=1)o=Qt.shapeSegmentInverted(t,r),l.push(ve(o,e));l=function(t){for(var e,i=1;i<t.length;i+=1)e=ye(t[i-1],t[i]),t[i-1]=e[0],t[i]=e[1];return t.length>1&&(e=ye(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}(l);var p=null,f=null;for(r=0;r<l.length;r+=1){var d=l[r];for(f&&(p=ue(a,f,d[0],i,s)),f=d[d.length-1],n=0;n<d.length;n+=1)o=d[n],p&&oe(o.points[0],p)?a.setXYAt(o.points[1][0],o.points[1][1],"o",a.length()-1):a.setTripleAt(o.points[0][0],o.points[0][1],o.points[1][0],o.points[1][1],o.points[0][0],o.points[0][1],a.length()),a.setTripleAt(o.points[3][0],o.points[3][1],o.points[3][0],o.points[3][1],o.points[2][0],o.points[2][1],a.length()),p=o.points[3]}return l.length&&ue(a,f,l[0][0],i,s),a},be.prototype.processShapes=function(t){var e,i,s,a,r,n,o=this.shapes.length,h=this.amount.v,l=this.miterLimit.v,p=this.lineJoin;if(0!==h)for(i=0;i<o;i+=1){if(n=(r=this.shapes[i]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,s=0;s<a;s+=1)n.addShape(this.processPath(e[s],h,p,l));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var ke=function(){var t={w:0,size:0,shapes:[],data:{shapes:[]}},e=[];e=e.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);var i=127988,s=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function r(t,e){var i=a("span");i.setAttribute("aria-hidden",!0),i.style.fontFamily=e;var s=a("span");s.innerText="giItT1WQy@!-/#",i.style.position="absolute",i.style.left="-10000px",i.style.top="-10000px",i.style.fontSize="300px",i.style.fontVariant="normal",i.style.fontStyle="normal",i.style.fontWeight="normal",i.style.letterSpacing="0",i.appendChild(s),document.body.appendChild(i);var r=s.offsetWidth;return s.style.fontFamily=function(t){var e,i=t.split(","),s=i.length,a=[];for(e=0;e<s;e+=1)"sans-serif"!==i[e]&&"monospace"!==i[e]&&a.push(i[e]);return a.join(",")}(t)+", "+e,{node:s,w:r,parent:i}}function n(t,e){var i,s=document.body&&e?"svg":"canvas",a=_e(t);if("svg"===s){var r=W("text");r.style.fontSize="100px",r.setAttribute("font-family",t.fFamily),r.setAttribute("font-style",a.style),r.setAttribute("font-weight",a.weight),r.textContent="1",t.fClass?(r.style.fontFamily="inherit",r.setAttribute("class",t.fClass)):r.style.fontFamily=t.fFamily,e.appendChild(r),i=r}else{var n=new OffscreenCanvas(500,500).getContext("2d");n.font=a.style+" "+a.weight+" 100px "+t.fFamily,i=n}return{measureText:function(t){return"svg"===s?(i.textContent=t,i.getComputedTextLength()):i.measureText(t).width}}}function o(t){var e=0,i=t.charCodeAt(0);if(i>=55296&&i<=56319){var s=t.charCodeAt(1);s>=56320&&s<=57343&&(e=1024*(i-55296)+s-56320+65536)}return e}function h(t){var e=o(t);return e>=127462&&e<=127487}var l=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)};l.isModifier=function(t,e){var i=t.toString(16)+e.toString(16);return-1!==s.indexOf(i)},l.isZeroWidthJoiner=function(t){return 8205===t},l.isFlagEmoji=function(t){return h(t.substr(0,2))&&h(t.substr(2,2))},l.isRegionalCode=h,l.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},l.isRegionalFlag=function(t,e){var s=o(t.substr(e,2));if(s!==i)return!1;var a=0;for(e+=2;a<5;){if((s=o(t.substr(e,2)))<917601||s>917626)return!1;a+=1,e+=2}return 917631===o(t.substr(e,2))},l.isVariationSelector=function(t){return 65039===t},l.BLACK_FLAG_CODE_POINT=i;var p={addChars:function(t){if(t){var e;this.chars||(this.chars=[]);var i,s,a=t.length,r=this.chars.length;for(e=0;e<a;e+=1){for(i=0,s=!1;i<r;)this.chars[i].style===t[e].style&&this.chars[i].fFamily===t[e].fFamily&&this.chars[i].ch===t[e].ch&&(s=!0),i+=1;s||(this.chars.push(t[e]),r+=1)}}},addFonts:function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);if(!document.body)return this.isLoaded=!0,t.list.forEach((function(t){t.helper=n(t),t.cache={}})),void(this.fonts=t.list);var i,s=t.list,o=s.length,h=o;for(i=0;i<o;i+=1){var l,p,f=!0;if(s[i].loaded=!1,s[i].monoCase=r(s[i].fFamily,"monospace"),s[i].sansCase=r(s[i].fFamily,"sans-serif"),s[i].fPath){if("p"===s[i].fOrigin||3===s[i].origin){if((l=document.querySelectorAll('style[f-forigin="p"][f-family="'+s[i].fFamily+'"], style[f-origin="3"][f-family="'+s[i].fFamily+'"]')).length>0&&(f=!1),f){var d=a("style");d.setAttribute("f-forigin",s[i].fOrigin),d.setAttribute("f-origin",s[i].origin),d.setAttribute("f-family",s[i].fFamily),d.type="text/css",d.innerText="@font-face {font-family: "+s[i].fFamily+"; font-style: normal; src: url('"+s[i].fPath+"');}",e.appendChild(d)}}else if("g"===s[i].fOrigin||1===s[i].origin){for(l=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),p=0;p<l.length;p+=1)-1!==l[p].href.indexOf(s[i].fPath)&&(f=!1);if(f){var m=a("link");m.setAttribute("f-forigin",s[i].fOrigin),m.setAttribute("f-origin",s[i].origin),m.type="text/css",m.rel="stylesheet",m.href=s[i].fPath,document.body.appendChild(m)}}else if("t"===s[i].fOrigin||2===s[i].origin){for(l=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),p=0;p<l.length;p+=1)s[i].fPath===l[p].src&&(f=!1);if(f){var c=a("link");c.setAttribute("f-forigin",s[i].fOrigin),c.setAttribute("f-origin",s[i].origin),c.setAttribute("rel","stylesheet"),c.setAttribute("href",s[i].fPath),e.appendChild(c)}}}else s[i].loaded=!0,h-=1;s[i].helper=n(s[i],e),s[i].cache={},this.fonts.push(s[i])}0===h?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},getCharData:function(e,i,s){for(var a=0,r=this.chars.length;a<r;){if(this.chars[a].ch===e&&this.chars[a].style===i&&this.chars[a].fFamily===s)return this.chars[a];a+=1}return("string"==typeof e&&13!==e.charCodeAt(0)||!e)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",e,i,s)),t},getFontByName:function(t){for(var e=0,i=this.fonts.length;e<i;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,i){var s=this.getFontByName(e),a=t;if(!s.cache[a]){var r=s.helper;if(" "===t){var n=r.measureText("|"+t+"|"),o=r.measureText("||");s.cache[a]=(n-o)/100}else s.cache[a]=r.measureText(t)/100}return s.cache[a]*i},checkLoadedFonts:function(){var t,e,i,s=this.fonts.length,a=s;for(t=0;t<s;t+=1)this.fonts[t].loaded?a-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,i=this.fonts[t].monoCase.w,e.offsetWidth!==i?(a-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,i=this.fonts[t].sansCase.w,e.offsetWidth!==i&&(a-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==a&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}};return l.prototype=p,l}();function Pe(t){this.animationData=t}function Ae(){}Pe.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},Ae.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var Se,xe=(Se={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return Se[t]||""});function we(t,e,i){this.p=vt.getProp(e,t.v,0,0,i)}function De(t,e,i){this.p=vt.getProp(e,t.v,0,0,i)}function Ce(t,e,i){this.p=vt.getProp(e,t.v,1,0,i)}function Me(t,e,i){this.p=vt.getProp(e,t.v,1,0,i)}function Te(t,e,i){this.p=vt.getProp(e,t.v,0,0,i)}function Fe(t,e,i){this.p=vt.getProp(e,t.v,0,0,i)}function Ee(t,e,i){this.p=vt.getProp(e,t.v,0,0,i)}function Ie(){this.p={}}function Le(t,e){var i,s=t.ef||[];this.effectElements=[];var a,r=s.length;for(i=0;i<r;i+=1)a=new Ve(s[i],e),this.effectElements.push(a)}function Ve(t,e){this.init(t,e)}function Re(){}function ze(){}function Oe(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,i)}function Ne(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,i),this._isPlaying=!1,this._canPlay=!1;var s=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(s),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?vt.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=vt.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function Be(){}r([bt],Ve),Ve.prototype.getValue=Ve.prototype.iterateDynamicProperties,Ve.prototype.init=function(t,e){var i;this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var s,a=this.data.ef.length,r=this.data.ef;for(i=0;i<a;i+=1){switch(s=null,r[i].ty){case 0:s=new we(r[i],e,this);break;case 1:s=new De(r[i],e,this);break;case 2:s=new Ce(r[i],e,this);break;case 3:s=new Me(r[i],e,this);break;case 4:case 7:s=new Ee(r[i],e,this);break;case 10:s=new Te(r[i],e,this);break;case 11:s=new Fe(r[i],e,this);break;case 5:s=new Le(r[i],e,this);break;default:s=new Ie(r[i],e,this)}s&&this.effectElements.push(s)}},Re.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t=B();if(t){var e=t("layer"),i=t("effects"),s=t("shape"),a=t("text"),r=t("comp");this.layerInterface=e(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var n=i.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(n),0===this.data.ty||this.data.xt?this.compInterface=r(this):4===this.data.ty?(this.layerInterface.shapeInterface=s(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=a(this),this.layerInterface.text=this.layerInterface.textInterface)}},setBlendMode:function(){var t=xe(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,i){this.globalData=e,this.comp=i,this.data=t,this.layerId=I(),this.data.sr||(this.data.sr=1),this.effectsManager=new Le(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},ze.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var i,s=this.dynamicProperties.length;for(i=0;i<s;i+=1)(e||this._isParent&&"transform"===this.dynamicProperties[i].propType)&&(this.dynamicProperties[i].getValue(),this.dynamicProperties[i]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},Oe.prototype.prepareFrame=function(){},r([Ae,Re,ze],Oe),Oe.prototype.getBaseElement=function(){return null},Oe.prototype.renderFrame=function(){},Oe.prototype.destroy=function(){},Oe.prototype.initExpressions=function(){var t=B();if(t){var e=t("footage");this.layerInterface=e(this)}},Oe.prototype.getFootageData=function(){return this.footageData},Ne.prototype.prepareFrame=function(t){if(this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder)this._currentTime=t/this.data.sr;else{var e=this.tm.v;this._currentTime=e}this._volume=this.lv.v[0];var i=this._volume*this._volumeMultiplier;this._previousVolume!==i&&(this._previousVolume=i,this.audio.volume(i))},r([Ae,Re,ze],Ne),Ne.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek())>.1)&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},Ne.prototype.show=function(){},Ne.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},Ne.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},Ne.prototype.resume=function(){this._canPlay=!0},Ne.prototype.setRate=function(t){this.audio.rate(t)},Ne.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},Ne.prototype.getBaseElement=function(){return null},Ne.prototype.destroy=function(){},Ne.prototype.sourceRectAtTime=function(){},Ne.prototype.initExpressions=function(){},Be.prototype.checkLayers=function(t){var e,i,s=this.layers.length;for(this.completeLayers=!0,e=s-1;e>=0;e-=1)this.elements[e]||(i=this.layers[e]).ip-i.st<=t-this.layers[e].st&&i.op-i.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},Be.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:default:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t)}},Be.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},Be.prototype.createAudio=function(t){return new Ne(t,this.globalData,this)},Be.prototype.createFootage=function(t){return new Oe(t,this.globalData,this)},Be.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},Be.prototype.includeLayers=function(t){var e;this.completeLayers=!1;var i,s=t.length,a=this.layers.length;for(e=0;e<s;e+=1)for(i=0;i<a;){if(this.layers[i].id===t[e].id){this.layers[i]=t[e];break}i+=1}},Be.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},Be.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},Be.prototype.buildElementParenting=function(t,e,i){for(var s=this.elements,a=this.layers,r=0,n=a.length;r<n;)a[r].ind==e&&(s[r]&&!0!==s[r]?(i.push(s[r]),s[r].setAsParent(),void 0!==a[r].parent?this.buildElementParenting(t,a[r].parent,i):t.setHierarchy(i)):(this.buildItem(r),this.addPendingElement(t))),r+=1},Be.prototype.addPendingElement=function(t){this.pendingElements.push(t)},Be.prototype.searchExtraCompositions=function(t){var e,i=t.length;for(e=0;e<i;e+=1)if(t[e].xt){var s=this.createComp(t[e]);s.initExpressions(),this.globalData.projectInterface.registerComposition(s)}},Be.prototype.getElementById=function(t){var e,i=this.elements.length;for(e=0;e<i;e+=1)if(this.elements[e].data.ind===t)return this.elements[e];return null},Be.prototype.getElementByPath=function(t){var e,i=t.shift();if("number"==typeof i)e=this.elements[i];else{var s,a=this.elements.length;for(s=0;s<a;s+=1)if(this.elements[s].data.nm===i){e=this.elements[s];break}}return 0===t.length?e:e.getElementByPath(t)},Be.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new ke,this.globalData.slotManager=function(t){return new Pe(t)}(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var qe="transformEFfect";function je(){}function We(t,e,i){this.data=t,this.element=e,this.globalData=i,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var a,r,n=this.globalData.defs,o=this.masksProperties?this.masksProperties.length:0;this.viewData=l(o),this.solidPath="";var h,p,f,d,m,c,u=this.masksProperties,g=0,y=[],v=I(),b="clipPath",_="clip-path";for(a=0;a<o;a+=1)if(("a"!==u[a].mode&&"n"!==u[a].mode||u[a].inv||100!==u[a].o.k||u[a].o.x)&&(b="mask",_="mask"),"s"!==u[a].mode&&"i"!==u[a].mode||0!==g?f=null:((f=W("rect")).setAttribute("fill","#ffffff"),f.setAttribute("width",this.element.comp.data.w||0),f.setAttribute("height",this.element.comp.data.h||0),y.push(f)),r=W("path"),"n"===u[a].mode)this.viewData[a]={op:vt.getProp(this.element,u[a].o,0,.01,this.element),prop:Tt.getShapeProp(this.element,u[a],3),elem:r,lastPath:""},n.appendChild(r);else{var k;if(g+=1,r.setAttribute("fill","s"===u[a].mode?"#000000":"#ffffff"),r.setAttribute("clip-rule","nonzero"),0!==u[a].x.k?(b="mask",_="mask",c=vt.getProp(this.element,u[a].x,0,null,this.element),k=I(),(d=W("filter")).setAttribute("id",k),(m=W("feMorphology")).setAttribute("operator","erode"),m.setAttribute("in","SourceGraphic"),m.setAttribute("radius","0"),d.appendChild(m),n.appendChild(d),r.setAttribute("stroke","s"===u[a].mode?"#000000":"#ffffff")):(m=null,c=null),this.storedData[a]={elem:r,x:c,expan:m,lastPath:"",lastOperator:"",filterId:k,lastRadius:0},"i"===u[a].mode){p=y.length;var P=W("g");for(h=0;h<p;h+=1)P.appendChild(y[h]);var A=W("mask");A.setAttribute("mask-type","alpha"),A.setAttribute("id",v+"_"+g),A.appendChild(r),n.appendChild(A),P.setAttribute("mask","url("+s()+"#"+v+"_"+g+")"),y.length=0,y.push(P)}else y.push(r);u[a].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[a]={elem:r,lastPath:"",op:vt.getProp(this.element,u[a].o,0,.01,this.element),prop:Tt.getShapeProp(this.element,u[a],3),invRect:f},this.viewData[a].prop.k||this.drawPath(u[a],this.viewData[a].prop.v,this.viewData[a])}for(this.maskElement=W(b),o=y.length,a=0;a<o;a+=1)this.maskElement.appendChild(y[a]);g>0&&(this.maskElement.setAttribute("id",v),this.element.maskedElement.setAttribute(_,"url("+s()+"#"+v+")"),n.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}je.prototype={initTransform:function(){var t=new Ft;this.finalTransform={mProp:this.data.ks?Wt.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,i=0,s=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;i<s;){if(this.hierarchy[i].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}i+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),i=0;i<s;i+=1)e.multiply(this.hierarchy[i].finalTransform.mProp.v)}this.finalTransform._matMdf&&(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var i=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(i),t=1;t<e;t+=1){var s=this.localTransforms[t].matrix;i.multiply(s)}i.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){var a=this.finalTransform.localOpacity;for(t=0;t<e;t+=1)a*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=a}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(qe);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new Ft;var e=0,i=t.length;for(e=0;e<i;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var i,s=!0,a=this.comp;s;)a.finalTransform?(a.data.hasMask&&e.splice(0,0,a.finalTransform),a=a.comp):s=!1;var r,n=e.length;for(i=0;i<n;i+=1)r=e[i].mat.applyToPointArray(0,0,0),t=[t[0]-r[0],t[1]-r[1],0];return t},mHelper:new Ft},We.prototype.getMaskProperty=function(t){return this.viewData[t].prop},We.prototype.renderFrame=function(t){var e,i=this.element.finalTransform.mat,a=this.masksProperties.length;for(e=0;e<a;e+=1)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[e].invRect.setAttribute("transform",i.getInverseMatrix().to2dCSS()),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var r=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+s()+"#"+this.storedData[e].filterId+")")),r.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},We.prototype.getMaskelement=function(){return this.maskElement},We.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},We.prototype.drawPath=function(t,e,i){var s,a,r=" M"+e.v[0][0]+","+e.v[0][1];for(a=e._length,s=1;s<a;s+=1)r+=" C"+e.o[s-1][0]+","+e.o[s-1][1]+" "+e.i[s][0]+","+e.i[s][1]+" "+e.v[s][0]+","+e.v[s][1];if(e.c&&a>1&&(r+=" C"+e.o[s-1][0]+","+e.o[s-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),i.lastPath!==r){var n="";i.elem&&(e.c&&(n=t.inv?this.solidPath+r:r),i.elem.setAttribute("d",n)),i.lastPath=r}},We.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var Xe=function(){var t={};return t.createFilter=function(t,e){var i=W("filter");i.setAttribute("id",t),!0!==e&&(i.setAttribute("filterUnits","objectBoundingBox"),i.setAttribute("x","0%"),i.setAttribute("y","0%"),i.setAttribute("width","100%"),i.setAttribute("height","100%"));return i},t.createAlphaToLuminanceFilter=function(){var t=W("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},t}(),He=function(){var t={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),/firefox/i.test(navigator.userAgent)&&(t.svgLumaHidden=!1),t}(),Ye={},Ge="filter_result_";function Ke(t){var e,i,a="SourceGraphic",r=t.data.ef?t.data.ef.length:0,n=I(),o=Xe.createFilter(n,!0),h=0;for(this.filters=[],e=0;e<r;e+=1){i=null;var l=t.data.ef[e].ty;if(Ye[l])i=new(0,Ye[l].effect)(o,t.effectsManager.effectElements[e],t,Ge+h,a),a=Ge+h,Ye[l].countsAsEffect&&(h+=1);i&&this.filters.push(i)}h&&(t.globalData.defs.appendChild(o),t.layerElement.setAttribute("filter","url("+s()+"#"+n+")")),this.filters.length&&t.addRenderableComponent(this)}function Je(){}function Ue(){}function Ze(){}function Qe(t,e,i){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,i),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function $e(t,e){this.elem=t,this.pos=e}function ti(){}Ke.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},Ke.prototype.getEffects=function(t){var e,i=this.filters.length,s=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&s.push(this.filters[e]);return s},Je.prototype={initRendererElement:function(){this.layerElement=W("g")},createContainerElements:function(){this.matteElement=W("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t=null;if(this.data.td){this.matteMasks={};var e=W("g");e.setAttribute("id",this.layerId),e.appendChild(this.layerElement),t=e,this.globalData.defs.appendChild(e)}else this.data.tt?(this.matteElement.appendChild(this.layerElement),t=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var i=W("clipPath"),a=W("path");a.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var r=I();if(i.setAttribute("id",r),i.appendChild(a),this.globalData.defs.appendChild(i),this.checkMasks()){var n=W("g");n.setAttribute("clip-path","url("+s()+"#"+r+")"),n.appendChild(this.layerElement),this.transformedElement=n,t?t.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+s()+"#"+r+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new We(this.data,this,this.globalData),this.renderableEffectsManager=new Ke(this),this.searchEffectTransforms()},getMatte:function(t){if(this.matteMasks||(this.matteMasks={}),!this.matteMasks[t]){var e,i,a,r,n=this.layerId+"_"+t;if(1===t||3===t){var o=W("mask");o.setAttribute("id",n),o.setAttribute("mask-type",3===t?"luminance":"alpha"),(a=W("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),o.appendChild(a),this.globalData.defs.appendChild(o),He.maskType||1!==t||(o.setAttribute("mask-type","luminance"),e=I(),i=Xe.createFilter(e),this.globalData.defs.appendChild(i),i.appendChild(Xe.createAlphaToLuminanceFilter()),(r=W("g")).appendChild(a),o.appendChild(r),r.setAttribute("filter","url("+s()+"#"+e+")"))}else if(2===t){var h=W("mask");h.setAttribute("id",n),h.setAttribute("mask-type","alpha");var l=W("g");h.appendChild(l),e=I(),i=Xe.createFilter(e);var p=W("feComponentTransfer");p.setAttribute("in","SourceGraphic"),i.appendChild(p);var f=W("feFuncA");f.setAttribute("type","table"),f.setAttribute("tableValues","1.0 0.0"),p.appendChild(f),this.globalData.defs.appendChild(i);var d=W("rect");d.setAttribute("width",this.comp.data.w),d.setAttribute("height",this.comp.data.h),d.setAttribute("x","0"),d.setAttribute("y","0"),d.setAttribute("fill","#ffffff"),d.setAttribute("opacity","0"),l.setAttribute("filter","url("+s()+"#"+e+")"),l.appendChild(d),(a=W("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),l.appendChild(a),He.maskType||(h.setAttribute("mask-type","luminance"),i.appendChild(Xe.createAlphaToLuminanceFilter()),r=W("g"),l.appendChild(d),r.appendChild(this.layerElement),l.appendChild(r)),this.globalData.defs.appendChild(h)}this.matteMasks[t]=n}return this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+s()+"#"+t+")")}},Ue.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},r([Ae,n({initElement:function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],Ze),r([Re,je,Je,Ue,ze,Ze],Qe),Qe.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=W("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},Qe.prototype.sourceRectAtTime=function(){return this.sourceRect},ti.prototype={addShapeToModifiers:function(t){var e,i=this.shapeModifiers.length;for(e=0;e<i;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;t>=0&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,i=0,s=e.length;i<s;){if(e[i].elem===t)return e[i].pos;i+=1}return 0},addProcessedElement:function(t,e){for(var i=this.processedElements,s=i.length;s;)if(i[s-=1].elem===t)return void(i[s].pos=e);i.push(new $e(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var ei={1:"butt",2:"round",3:"square"},ii={1:"miter",2:"round",3:"bevel"};function si(t,e,i){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=i,this.lvl=e,this._isAnimated=!!i.k;for(var s=0,a=t.length;s<a;){if(t[s].mProps.dynamicProperties.length){this._isAnimated=!0;break}s+=1}}function ai(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=W("path"),this.msElem=null}function ri(t,e,i,s){var a;this.elem=t,this.frameId=-1,this.dataProps=l(e.length),this.renderer=i,this.k=!1,this.dashStr="",this.dashArray=h("float32",e.length?e.length-1:0),this.dashoffset=h("float32",1),this.initDynamicPropertyContainer(s);var r,n=e.length||0;for(a=0;a<n;a+=1)r=vt.getProp(t,e[a].v,0,0,this),this.k=r.k||this.k,this.dataProps[a]={n:e[a].n,p:r};this.k||this.getValue(!0),this._isAnimated=this.k}function ni(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=vt.getProp(t,e.o,0,.01,this),this.w=vt.getProp(t,e.w,0,null,this),this.d=new ri(t,e.d||{},"svg",this),this.c=vt.getProp(t,e.c,1,255,this),this.style=i,this._isAnimated=!!this._isAnimated}function oi(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=vt.getProp(t,e.o,0,.01,this),this.c=vt.getProp(t,e.c,1,255,this),this.style=i}function hi(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=i}function li(t,e,i){this.data=e,this.c=h("uint8c",4*e.p);var s=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=h("float32",s),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=s,this.initDynamicPropertyContainer(i),this.prop=vt.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function pi(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,i)}function fi(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=vt.getProp(t,e.w,0,null,this),this.d=new ri(t,e.d||{},"svg",this),this.initGradientData(t,e,i),this._isAnimated=!!this._isAnimated}function di(){this.it=[],this.prevViewData=[],this.gr=W("g")}function mi(t,e,i){this.transform={mProps:t,op:e,container:i},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}si.prototype.setAsAnimated=function(){this._isAnimated=!0},ai.prototype.reset=function(){this.d="",this._mdf=!1},ri.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,i=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<i;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},r([bt],ri),r([bt],ni),r([bt],oi),r([bt],hi),li.prototype.comparePoints=function(t,e){for(var i=0,s=this.o.length/2;i<s;){if(Math.abs(t[4*i]-t[4*e+2*i])>.01)return!1;i+=1}return!0},li.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},li.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,i,s,a=4*this.data.p;for(e=0;e<a;e+=1)i=e%4==0?100:255,s=Math.round(this.prop.v[e]*i),this.c[e]!==s&&(this.c[e]=s,this._cmdf=!t);if(this.o.length)for(a=this.prop.v.length,e=4*this.data.p;e<a;e+=1)i=e%2==0?100:1,s=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==s&&(this.o[e-4*this.data.p]=s,this._omdf=!t);this._mdf=!t}},r([bt],li),pi.prototype.initGradientData=function(t,e,i){this.o=vt.getProp(t,e.o,0,.01,this),this.s=vt.getProp(t,e.s,1,null,this),this.e=vt.getProp(t,e.e,1,null,this),this.h=vt.getProp(t,e.h||{k:0},0,.01,this),this.a=vt.getProp(t,e.a||{k:0},0,P,this),this.g=new li(t,e.g,this),this.style=i,this.stops=[],this.setGradientData(i.pElem,e),this.setGradientOpacity(e,i),this._isAnimated=!!this._isAnimated},pi.prototype.setGradientData=function(t,e){var i=I(),a=W(1===e.t?"linearGradient":"radialGradient");a.setAttribute("id",i),a.setAttribute("spreadMethod","pad"),a.setAttribute("gradientUnits","userSpaceOnUse");var r,n,o,h=[];for(o=4*e.g.p,n=0;n<o;n+=4)r=W("stop"),a.appendChild(r),h.push(r);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+s()+"#"+i+")"),this.gf=a,this.cst=h},pi.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){var i,a,r,n=W("mask"),o=W("path");n.appendChild(o);var h=I(),l=I();n.setAttribute("id",l);var p=W(1===t.t?"linearGradient":"radialGradient");p.setAttribute("id",h),p.setAttribute("spreadMethod","pad"),p.setAttribute("gradientUnits","userSpaceOnUse"),r=t.g.k.k[0].s?t.g.k.k[0].s.length:t.g.k.k.length;var f=this.stops;for(a=4*t.g.p;a<r;a+=2)(i=W("stop")).setAttribute("stop-color","rgb(255,255,255)"),p.appendChild(i),f.push(i);o.setAttribute("gf"===t.ty?"fill":"stroke","url("+s()+"#"+h+")"),"gs"===t.ty&&(o.setAttribute("stroke-linecap",ei[t.lc||2]),o.setAttribute("stroke-linejoin",ii[t.lj||2]),1===t.lj&&o.setAttribute("stroke-miterlimit",t.ml)),this.of=p,this.ms=n,this.ost=f,this.maskId=l,e.msElem=o}},r([bt],pi),r([pi,bt],fi);var ci=function(t,e,i,s){if(0===e)return"";var a,r=t.o,n=t.i,o=t.v,h=" M"+s.applyToPointStringified(o[0][0],o[0][1]);for(a=1;a<e;a+=1)h+=" C"+s.applyToPointStringified(r[a-1][0],r[a-1][1])+" "+s.applyToPointStringified(n[a][0],n[a][1])+" "+s.applyToPointStringified(o[a][0],o[a][1]);return i&&e&&(h+=" C"+s.applyToPointStringified(r[a-1][0],r[a-1][1])+" "+s.applyToPointStringified(n[0][0],n[0][1])+" "+s.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},ui=function(){var t=new Ft,e=new Ft;function i(t,e,i){(i||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(i||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function s(){}function a(i,s,a){var r,n,o,h,l,p,f,d,m,c,u=s.styles.length,g=s.lvl;for(p=0;p<u;p+=1){if(h=s.sh._mdf||a,s.styles[p].lvl<g){for(d=e.reset(),m=g-s.styles[p].lvl,c=s.transformers.length-1;!h&&m>0;)h=s.transformers[c].mProps._mdf||h,m-=1,c-=1;if(h)for(m=g-s.styles[p].lvl,c=s.transformers.length-1;m>0;)d.multiply(s.transformers[c].mProps.v),m-=1,c-=1}else d=t;if(n=(f=s.sh.paths)._length,h){for(o="",r=0;r<n;r+=1)(l=f.shapes[r])&&l._length&&(o+=ci(l,l._length,l.c,d));s.caches[p]=o}else o=s.caches[p];s.styles[p].d+=!0===i.hd?"":o,s.styles[p]._mdf=h||s.styles[p]._mdf}}function r(t,e,i){var s=e.style;(e.c._mdf||i)&&s.pElem.setAttribute("fill","rgb("+v(e.c.v[0])+","+v(e.c.v[1])+","+v(e.c.v[2])+")"),(e.o._mdf||i)&&s.pElem.setAttribute("fill-opacity",e.o.v)}function n(t,e,i){o(t,e,i),h(t,e,i)}function o(t,e,i){var s,a,r,n,o,h=e.gf,l=e.g._hasOpacity,p=e.s.v,f=e.e.v;if(e.o._mdf||i){var d="gf"===t.ty?"fill-opacity":"stroke-opacity";e.style.pElem.setAttribute(d,e.o.v)}if(e.s._mdf||i){var m=1===t.t?"x1":"cx",c="x1"===m?"y1":"cy";h.setAttribute(m,p[0]),h.setAttribute(c,p[1]),l&&!e.g._collapsable&&(e.of.setAttribute(m,p[0]),e.of.setAttribute(c,p[1]))}if(e.g._cmdf||i){s=e.cst;var u=e.g.c;for(r=s.length,a=0;a<r;a+=1)(n=s[a]).setAttribute("offset",u[4*a]+"%"),n.setAttribute("stop-color","rgb("+u[4*a+1]+","+u[4*a+2]+","+u[4*a+3]+")")}if(l&&(e.g._omdf||i)){var g=e.g.o;for(r=(s=e.g._collapsable?e.cst:e.ost).length,a=0;a<r;a+=1)n=s[a],e.g._collapsable||n.setAttribute("offset",g[2*a]+"%"),n.setAttribute("stop-opacity",g[2*a+1])}if(1===t.t)(e.e._mdf||i)&&(h.setAttribute("x2",f[0]),h.setAttribute("y2",f[1]),l&&!e.g._collapsable&&(e.of.setAttribute("x2",f[0]),e.of.setAttribute("y2",f[1])));else if((e.s._mdf||e.e._mdf||i)&&(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)),h.setAttribute("r",o),l&&!e.g._collapsable&&e.of.setAttribute("r",o)),e.e._mdf||e.h._mdf||e.a._mdf||i){o||(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)));var y=Math.atan2(f[1]-p[1],f[0]-p[0]),v=e.h.v;v>=1?v=.99:v<=-1&&(v=-.99);var b=o*v,_=Math.cos(y+e.a.v)*b+p[0],k=Math.sin(y+e.a.v)*b+p[1];h.setAttribute("fx",_),h.setAttribute("fy",k),l&&!e.g._collapsable&&(e.of.setAttribute("fx",_),e.of.setAttribute("fy",k))}}function h(t,e,i){var s=e.style,a=e.d;a&&(a._mdf||i)&&a.dashStr&&(s.pElem.setAttribute("stroke-dasharray",a.dashStr),s.pElem.setAttribute("stroke-dashoffset",a.dashoffset[0])),e.c&&(e.c._mdf||i)&&s.pElem.setAttribute("stroke","rgb("+v(e.c.v[0])+","+v(e.c.v[1])+","+v(e.c.v[2])+")"),(e.o._mdf||i)&&s.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||i)&&(s.pElem.setAttribute("stroke-width",e.w.v),s.msElem&&s.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function(t){switch(t.ty){case"fl":return r;case"gf":return o;case"gs":return n;case"st":return h;case"sh":case"el":case"rc":case"sr":return a;case"tr":return i;case"no":return s;default:return null}}}}();function gi(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,i),this.prevViewData=[]}function yi(t,e,i,s,a,r){this.o=t,this.sw=e,this.sc=i,this.fc=s,this.m=a,this.p=r,this._mdf={o:!0,sw:!!e,sc:!!i,fc:!!s,m:!0,p:!0}}function vi(t,e){this._frameId=i,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}r([Re,je,Je,ti,Ue,ze,Ze],gi),gi.prototype.initSecondaryElement=function(){},gi.prototype.identityMatrix=new Ft,gi.prototype.buildExpressionInterface=function(){},gi.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},gi.prototype.filterUniqueShapes=function(){var t,e,i,s,a=this.shapes.length,r=this.stylesList.length,n=[],o=!1;for(i=0;i<r;i+=1){for(s=this.stylesList[i],o=!1,n.length=0,t=0;t<a;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(s)&&(n.push(e),o=e._isAnimated||o);n.length>1&&o&&this.setShapesAsAnimated(n)}},gi.prototype.setShapesAsAnimated=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].setAsAnimated()},gi.prototype.createStyleElement=function(t,e){var i,a=new ai(t,e),r=a.pElem;if("st"===t.ty)i=new ni(this,t,a);else if("fl"===t.ty)i=new oi(this,t,a);else if("gf"===t.ty||"gs"===t.ty){i=new("gf"===t.ty?pi:fi)(this,t,a),this.globalData.defs.appendChild(i.gf),i.maskId&&(this.globalData.defs.appendChild(i.ms),this.globalData.defs.appendChild(i.of),r.setAttribute("mask","url("+s()+"#"+i.maskId+")"))}else"no"===t.ty&&(i=new hi(this,t,a));return"st"!==t.ty&&"gs"!==t.ty||(r.setAttribute("stroke-linecap",ei[t.lc||2]),r.setAttribute("stroke-linejoin",ii[t.lj||2]),r.setAttribute("fill-opacity","0"),1===t.lj&&r.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&r.setAttribute("fill-rule","evenodd"),t.ln&&r.setAttribute("id",t.ln),t.cl&&r.setAttribute("class",t.cl),t.bm&&(r.style["mix-blend-mode"]=xe(t.bm)),this.stylesList.push(a),this.addToAnimatedContents(t,i),i},gi.prototype.createGroupElement=function(t){var e=new di;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=xe(t.bm)),e},gi.prototype.createTransformElement=function(t,e){var i=Wt.getTransformProperty(this,t,this),s=new mi(i,i.o,e);return this.addToAnimatedContents(t,s),s},gi.prototype.createShapeElement=function(t,e,i){var s=4;"rc"===t.ty?s=5:"el"===t.ty?s=6:"sr"===t.ty&&(s=7);var a=new si(e,i,Tt.getShapeProp(this,t,s,this));return this.shapes.push(a),this.addShapeToModifiers(a),this.addToAnimatedContents(t,a),a},gi.prototype.addToAnimatedContents=function(t,e){for(var i=0,s=this.animatedContents.length;i<s;){if(this.animatedContents[i].element===e)return;i+=1}this.animatedContents.push({fn:ui.createRenderFunction(t),element:e,data:t})},gi.prototype.setElementStyles=function(t){var e,i=t.styles,s=this.stylesList.length;for(e=0;e<s;e+=1)this.stylesList[e].closed||i.push(this.stylesList[e])},gi.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},gi.prototype.searchShapes=function(t,e,i,s,a,r,n){var o,h,l,p,f,d,m=[].concat(r),c=t.length-1,u=[],g=[];for(o=c;o>=0;o-=1){if((d=this.searchProcessedElement(t[o]))?e[o]=i[d-1]:t[o]._render=n,"fl"===t[o].ty||"st"===t[o].ty||"gf"===t[o].ty||"gs"===t[o].ty||"no"===t[o].ty)d?e[o].style.closed=!1:e[o]=this.createStyleElement(t[o],a),t[o]._render&&e[o].style.pElem.parentNode!==s&&s.appendChild(e[o].style.pElem),u.push(e[o].style);else if("gr"===t[o].ty){if(d)for(l=e[o].it.length,h=0;h<l;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,a+1,m,n),t[o]._render&&e[o].gr.parentNode!==s&&s.appendChild(e[o].gr)}else"tr"===t[o].ty?(d||(e[o]=this.createTransformElement(t[o],s)),p=e[o].transform,m.push(p)):"sh"===t[o].ty||"rc"===t[o].ty||"el"===t[o].ty||"sr"===t[o].ty?(d||(e[o]=this.createShapeElement(t[o],m,a)),this.setElementStyles(e[o])):"tm"===t[o].ty||"rd"===t[o].ty||"ms"===t[o].ty||"pb"===t[o].ty||"zz"===t[o].ty||"op"===t[o].ty?(d?(f=e[o]).closed=!1:((f=Nt.getModifier(t[o].ty)).init(this,t[o]),e[o]=f,this.shapeModifiers.push(f)),g.push(f)):"rp"===t[o].ty&&(d?(f=e[o]).closed=!0:(f=Nt.getModifier(t[o].ty),e[o]=f,f.init(this,t,o,e),this.shapeModifiers.push(f),n=!1),g.push(f));this.addProcessedElement(t[o],o+1)}for(c=u.length,o=0;o<c;o+=1)u[o].closed=!0;for(c=g.length,o=0;o<c;o+=1)g[o].closed=!0},gi.prototype.renderInnerContent=function(){var t;this.renderModifiers();var e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},gi.prototype.renderShape=function(){var t,e,i=this.animatedContents.length;for(t=0;t<i;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},gi.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},yi.prototype.update=function(t,e,i,s,a,r){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1,this._mdf.p=!1;var n=!1;return this.o!==t&&(this.o=t,this._mdf.o=!0,n=!0),this.sw!==e&&(this.sw=e,this._mdf.sw=!0,n=!0),this.sc!==i&&(this.sc=i,this._mdf.sc=!0,n=!0),this.fc!==s&&(this.fc=s,this._mdf.fc=!0,n=!0),this.m!==a&&(this.m=a,this._mdf.m=!0,n=!0),!r.length||this.p[0]===r[0]&&this.p[1]===r[1]&&this.p[4]===r[4]&&this.p[5]===r[5]&&this.p[12]===r[12]&&this.p[13]===r[13]||(this.p=r,this._mdf.p=!0,n=!0),n},vi.prototype.defaultBoxWidth=[0,0],vi.prototype.copyData=function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},vi.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},vi.prototype.searchProperty=function(){return this.searchKeyframes()},vi.prototype.searchKeyframes=function(){return this.kf=this.data.d.k.length>1,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},vi.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},vi.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,i=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{var s;this.lock=!0,this._mdf=!1;var a=this.effectsSequence.length,r=t||this.data.d.k[this.keysIndex].s;for(s=0;s<a;s+=1)r=i!==this.keysIndex?this.effectsSequence[s](r,r.t):this.effectsSequence[s](this.currentData,r.t);e!==r&&this.setCurrentData(r),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},vi.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,i=0,s=t.length;i<=s-1&&!(i===s-1||t[i+1].t>e);)i+=1;return this.keysIndex!==i&&(this.keysIndex=i),this.data.d.k[this.keysIndex].s},vi.prototype.buildFinalText=function(t){for(var e,i,s=[],a=0,r=t.length,n=!1,o=!1,h="";a<r;)n=o,o=!1,e=t.charCodeAt(a),h=t.charAt(a),ke.isCombinedCharacter(e)?n=!0:e>=55296&&e<=56319?ke.isRegionalFlag(t,a)?h=t.substr(a,14):(i=t.charCodeAt(a+1))>=56320&&i<=57343&&(ke.isModifier(e,i)?(h=t.substr(a,2),n=!0):h=ke.isFlagEmoji(t.substr(a,4))?t.substr(a,4):t.substr(a,2)):e>56319?(i=t.charCodeAt(a+1),ke.isVariationSelector(e)&&(n=!0)):ke.isZeroWidthJoiner(e)&&(n=!0,o=!0),n?(s[s.length-1]+=h,n=!1):s.push(h),a+=h.length;return s},vi.prototype.completeTextData=function(t){t.__complete=!0;var e,i,s,a,r,n,o,h=this.elem.globalData.fontManager,l=this.data,p=[],f=0,d=l.m.g,m=0,c=0,u=0,g=[],y=0,v=0,b=h.getFontByName(t.f),_=0,k=_e(b);t.fWeight=k.weight,t.fStyle=k.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),i=t.finalText.length,t.finalLineHeight=t.lh;var P,A=t.tr/1e3*t.finalSize;if(t.sz)for(var S,x,w=!0,D=t.sz[0],C=t.sz[1];w;){S=0,y=0,i=(x=this.buildFinalText(t.t)).length,A=t.tr/1e3*t.finalSize;var M=-1;for(e=0;e<i;e+=1)P=x[e].charCodeAt(0),s=!1," "===x[e]?M=e:13!==P&&3!==P||(y=0,s=!0,S+=t.finalLineHeight||1.2*t.finalSize),h.chars?(o=h.getCharData(x[e],b.fStyle,b.fFamily),_=s?0:o.w*t.finalSize/100):_=h.measureText(x[e],t.f,t.finalSize),y+_>D&&" "!==x[e]?(-1===M?i+=1:e=M,S+=t.finalLineHeight||1.2*t.finalSize,x.splice(e,M===e?1:0,"\r"),M=-1,y=0):(y+=_,y+=A);S+=b.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&C<S?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=x,i=t.finalText.length,w=!1)}y=-A,_=0;var T,F=0;for(e=0;e<i;e+=1)if(s=!1,13===(P=(T=t.finalText[e]).charCodeAt(0))||3===P?(F=0,g.push(y),v=y>v?y:v,y=-2*A,a="",s=!0,u+=1):a=T,h.chars?(o=h.getCharData(T,b.fStyle,h.getFontByName(t.f).fFamily),_=s?0:o.w*t.finalSize/100):_=h.measureText(a,t.f,t.finalSize)," "===T?F+=_+A:(y+=_+A+F,F=0),p.push({l:_,an:_,add:m,n:s,anIndexes:[],val:a,line:u,animatorJustifyOffset:0}),2==d){if(m+=_,""===a||" "===a||e===i-1){for(""!==a&&" "!==a||(m-=_);c<=e;)p[c].an=m,p[c].ind=f,p[c].extra=_,c+=1;f+=1,m=0}}else if(3==d){if(m+=_,""===a||e===i-1){for(""===a&&(m-=_);c<=e;)p[c].an=m,p[c].ind=f,p[c].extra=_,c+=1;m=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=y>v?y:v,g.push(y),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=g;var E,I,L,V,R=l.a;n=R.length;var z=[];for(r=0;r<n;r+=1){for((E=R[r]).a.sc&&(t.strokeColorAnim=!0),E.a.sw&&(t.strokeWidthAnim=!0),(E.a.fc||E.a.fh||E.a.fs||E.a.fb)&&(t.fillColorAnim=!0),V=0,L=E.s.b,e=0;e<i;e+=1)(I=p[e]).anIndexes[r]=V,(1==L&&""!==I.val||2==L&&""!==I.val&&" "!==I.val||3==L&&(I.n||" "==I.val||e==i-1)||4==L&&(I.n||e==i-1))&&(1===E.s.rn&&z.push(V),V+=1);l.a[r].s.totalChars=V;var O,N=-1;if(1===E.s.rn)for(e=0;e<i;e+=1)N!=(I=p[e]).anIndexes[r]&&(N=I.anIndexes[r],O=z.splice(Math.floor(Math.random()*z.length),1)[0]),I.anIndexes[r]=O}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=b.ascent*t.finalSize/100},vi.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var i=this.copyData({},this.data.d.k[e].s);i=this.copyData(i,t),this.data.d.k[e].s=i,this.recalculate(e),this.setCurrentData(i),this.elem.addDynamicProperty(this)},vi.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},vi.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},vi.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var bi=function(){var t=Math.max,e=Math.min,i=Math.floor;function s(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=vt.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?vt.getProp(t,e.e,0,0,this):{v:100},this.o=vt.getProp(t,e.o||{k:0},0,0,this),this.xe=vt.getProp(t,e.xe||{k:0},0,0,this),this.ne=vt.getProp(t,e.ne||{k:0},0,0,this),this.sm=vt.getProp(t,e.sm||{k:100},0,0,this),this.a=vt.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return s.prototype={getMult:function(s){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var a=0,r=0,n=1,o=1;this.ne.v>0?a=this.ne.v/100:r=-this.ne.v/100,this.xe.v>0?n=1-this.xe.v/100:o=1+this.xe.v/100;var h=tt.getBezierEasing(a,r,n,o).get,l=0,p=this.finalS,f=this.finalE,d=this.data.sh;if(2===d)l=h(l=f===p?s>=f?1:0:t(0,e(.5/(f-p)+(s-p)/(f-p),1)));else if(3===d)l=h(l=f===p?s>=f?0:1:1-t(0,e(.5/(f-p)+(s-p)/(f-p),1)));else if(4===d)f===p?l=0:(l=t(0,e(.5/(f-p)+(s-p)/(f-p),1)))<.5?l*=2:l=1-2*(l-.5),l=h(l);else if(5===d){if(f===p)l=0;else{var m=f-p,c=-m/2+(s=e(t(0,s+.5-p),f-p)),u=m/2;l=Math.sqrt(1-c*c/(u*u))}l=h(l)}else 6===d?(f===p?l=0:(s=e(t(0,s+.5-p),f-p),l=(1+Math.cos(Math.PI+2*Math.PI*s/(f-p)))/2),l=h(l)):(s>=i(p)&&(l=t(0,e(s-p<0?e(f,1)-(p-s):f-s,1))),l=h(l));if(100!==this.sm.v){var g=.01*this.sm.v;0===g&&(g=1e-8);var y=.5-.5*g;l<y?l=0:(l=(l-y)/g)>1&&(l=1)}return l*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,i=this.o.v/e,s=this.s.v/e+i,a=this.e.v/e+i;if(s>a){var r=s;s=a,a=r}this.finalS=s,this.finalE=a}},r([bt],s),{getTextSelectorProp:function(t,e,i){return new s(t,e,i)}}}();function _i(t,e,i){var s={propType:!1},a=vt.getProp,r=e.a;this.a={r:r.r?a(t,r.r,0,P,i):s,rx:r.rx?a(t,r.rx,0,P,i):s,ry:r.ry?a(t,r.ry,0,P,i):s,sk:r.sk?a(t,r.sk,0,P,i):s,sa:r.sa?a(t,r.sa,0,P,i):s,s:r.s?a(t,r.s,1,.01,i):s,a:r.a?a(t,r.a,1,0,i):s,o:r.o?a(t,r.o,0,.01,i):s,p:r.p?a(t,r.p,1,0,i):s,sw:r.sw?a(t,r.sw,0,0,i):s,sc:r.sc?a(t,r.sc,1,0,i):s,fc:r.fc?a(t,r.fc,1,0,i):s,fh:r.fh?a(t,r.fh,0,0,i):s,fs:r.fs?a(t,r.fs,0,.01,i):s,fb:r.fb?a(t,r.fb,0,.01,i):s,t:r.t?a(t,r.t,0,0,i):s},this.s=bi.getTextSelectorProp(t,e.s,i),this.s.t=e.s.t}function ki(t,e,i){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=i,this._animatorsData=l(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(i)}function Pi(){}ki.prototype.searchProperties=function(){var t,e,i=this._textData.a.length,s=vt.getProp;for(t=0;t<i;t+=1)e=this._textData.a[t],this._animatorsData[t]=new _i(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:s(this._elem,this._textData.p.a,0,0,this),f:s(this._elem,this._textData.p.f,0,0,this),l:s(this._elem,this._textData.p.l,0,0,this),r:s(this._elem,this._textData.p.r,0,0,this),p:s(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=s(this._elem,this._textData.m.a,1,0,this)},ki.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var i,s,a,r,n,o,h,l,p,f,d,m,c,u,g,y,v,b,_,k=this._moreOptions.alignment.v,P=this._animatorsData,A=this._textData,S=this.mHelper,x=this._renderType,w=this.renderedLetters.length,D=t.l;if(this._hasMaskedPath){if(_=this._pathData.m,!this._pathData.n||this._pathData._mdf){var C,M=_.v;for(this._pathData.r.v&&(M=M.reverse()),n={tLength:0,segments:[]},r=M._length-1,y=0,a=0;a<r;a+=1)C=rt.buildBezierData(M.v[a],M.v[a+1],[M.o[a][0]-M.v[a][0],M.o[a][1]-M.v[a][1]],[M.i[a+1][0]-M.v[a+1][0],M.i[a+1][1]-M.v[a+1][1]]),n.tLength+=C.segmentLength,n.segments.push(C),y+=C.segmentLength;a=r,_.v.c&&(C=rt.buildBezierData(M.v[a],M.v[0],[M.o[a][0]-M.v[a][0],M.o[a][1]-M.v[a][1]],[M.i[0][0]-M.v[0][0],M.i[0][1]-M.v[0][1]]),n.tLength+=C.segmentLength,n.segments.push(C),y+=C.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,d=0,f=1,l=0,p=!0,u=n.segments,o<0&&_.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),f=(c=u[d=u.length-1].points).length-1;o<0;)o+=c[f].partialLength,(f-=1)<0&&(f=(c=u[d-=1].points).length-1);m=(c=u[d].points)[f-1],g=(h=c[f]).partialLength}r=D.length,i=0,s=0;var T,F,E,I,L,V=1.2*t.finalSize*.714,N=!0;E=P.length;var B,q,j,W,X,H,Y,G,K,J,U,Z,Q=-1,$=o,tt=d,et=f,it=-1,st="",at=this.defaultPropsArray;if(2===t.j||1===t.j){var nt=0,ot=0,ht=2===t.j?-.5:-1,lt=0,pt=!0;for(a=0;a<r;a+=1)if(D[a].n){for(nt&&(nt+=ot);lt<a;)D[lt].animatorJustifyOffset=nt,lt+=1;nt=0,pt=!0}else{for(F=0;F<E;F+=1)(T=P[F].a).t.propType&&(pt&&2===t.j&&(ot+=T.t.v*ht),(L=P[F].s.getMult(D[a].anIndexes[F],A.a[F].s.totalChars)).length?nt+=T.t.v*L[0]*ht:nt+=T.t.v*L*ht);pt=!1}for(nt&&(nt+=ot);lt<a;)D[lt].animatorJustifyOffset=nt,lt+=1}for(a=0;a<r;a+=1){if(S.reset(),W=1,D[a].n)i=0,s+=t.yOffset,s+=N?1:0,o=$,N=!1,this._hasMaskedPath&&(f=et,m=(c=u[d=tt].points)[f-1],g=(h=c[f]).partialLength,l=0),st="",U="",K="",Z="",at=this.defaultPropsArray;else{if(this._hasMaskedPath){if(it!==D[a].line){switch(t.j){case 1:o+=y-t.lineWidths[D[a].line];break;case 2:o+=(y-t.lineWidths[D[a].line])/2}it=D[a].line}Q!==D[a].ind&&(D[Q]&&(o+=D[Q].extra),o+=D[a].an/2,Q=D[a].ind),o+=k[0]*D[a].an*.005;var ft=0;for(F=0;F<E;F+=1)(T=P[F].a).p.propType&&((L=P[F].s.getMult(D[a].anIndexes[F],A.a[F].s.totalChars)).length?ft+=T.p.v[0]*L[0]:ft+=T.p.v[0]*L),T.a.propType&&((L=P[F].s.getMult(D[a].anIndexes[F],A.a[F].s.totalChars)).length?ft+=T.a.v[0]*L[0]:ft+=T.a.v[0]*L);for(p=!0,this._pathData.a.v&&(o=.5*D[0].an+(y-this._pathData.f.v-.5*D[0].an-.5*D[D.length-1].an)*Q/(r-1),o+=this._pathData.f.v);p;)l+g>=o+ft||!c?(v=(o+ft-l)/h.partialLength,q=m.point[0]+(h.point[0]-m.point[0])*v,j=m.point[1]+(h.point[1]-m.point[1])*v,S.translate(-k[0]*D[a].an*.005,-k[1]*V*.01),p=!1):c&&(l+=h.partialLength,(f+=1)>=c.length&&(f=0,u[d+=1]?c=u[d].points:_.v.c?(f=0,c=u[d=0].points):(l-=h.partialLength,c=null)),c&&(m=h,g=(h=c[f]).partialLength));B=D[a].an/2-D[a].add,S.translate(-B,0,0)}else B=D[a].an/2-D[a].add,S.translate(-B,0,0),S.translate(-k[0]*D[a].an*.005,-k[1]*V*.01,0);for(F=0;F<E;F+=1)(T=P[F].a).t.propType&&(L=P[F].s.getMult(D[a].anIndexes[F],A.a[F].s.totalChars),0===i&&0===t.j||(this._hasMaskedPath?L.length?o+=T.t.v*L[0]:o+=T.t.v*L:L.length?i+=T.t.v*L[0]:i+=T.t.v*L));for(t.strokeWidthAnim&&(H=t.sw||0),t.strokeColorAnim&&(X=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(Y=[t.fc[0],t.fc[1],t.fc[2]]),F=0;F<E;F+=1)(T=P[F].a).a.propType&&((L=P[F].s.getMult(D[a].anIndexes[F],A.a[F].s.totalChars)).length?S.translate(-T.a.v[0]*L[0],-T.a.v[1]*L[1],T.a.v[2]*L[2]):S.translate(-T.a.v[0]*L,-T.a.v[1]*L,T.a.v[2]*L));for(F=0;F<E;F+=1)(T=P[F].a).s.propType&&((L=P[F].s.getMult(D[a].anIndexes[F],A.a[F].s.totalChars)).length?S.scale(1+(T.s.v[0]-1)*L[0],1+(T.s.v[1]-1)*L[1],1):S.scale(1+(T.s.v[0]-1)*L,1+(T.s.v[1]-1)*L,1));for(F=0;F<E;F+=1){if(T=P[F].a,L=P[F].s.getMult(D[a].anIndexes[F],A.a[F].s.totalChars),T.sk.propType&&(L.length?S.skewFromAxis(-T.sk.v*L[0],T.sa.v*L[1]):S.skewFromAxis(-T.sk.v*L,T.sa.v*L)),T.r.propType&&(L.length?S.rotateZ(-T.r.v*L[2]):S.rotateZ(-T.r.v*L)),T.ry.propType&&(L.length?S.rotateY(T.ry.v*L[1]):S.rotateY(T.ry.v*L)),T.rx.propType&&(L.length?S.rotateX(T.rx.v*L[0]):S.rotateX(T.rx.v*L)),T.o.propType&&(L.length?W+=(T.o.v*L[0]-W)*L[0]:W+=(T.o.v*L-W)*L),t.strokeWidthAnim&&T.sw.propType&&(L.length?H+=T.sw.v*L[0]:H+=T.sw.v*L),t.strokeColorAnim&&T.sc.propType)for(G=0;G<3;G+=1)L.length?X[G]+=(T.sc.v[G]-X[G])*L[0]:X[G]+=(T.sc.v[G]-X[G])*L;if(t.fillColorAnim&&t.fc){if(T.fc.propType)for(G=0;G<3;G+=1)L.length?Y[G]+=(T.fc.v[G]-Y[G])*L[0]:Y[G]+=(T.fc.v[G]-Y[G])*L;T.fh.propType&&(Y=L.length?O(Y,T.fh.v*L[0]):O(Y,T.fh.v*L)),T.fs.propType&&(Y=L.length?R(Y,T.fs.v*L[0]):R(Y,T.fs.v*L)),T.fb.propType&&(Y=L.length?z(Y,T.fb.v*L[0]):z(Y,T.fb.v*L))}}for(F=0;F<E;F+=1)(T=P[F].a).p.propType&&(L=P[F].s.getMult(D[a].anIndexes[F],A.a[F].s.totalChars),this._hasMaskedPath?L.length?S.translate(0,T.p.v[1]*L[0],-T.p.v[2]*L[1]):S.translate(0,T.p.v[1]*L,-T.p.v[2]*L):L.length?S.translate(T.p.v[0]*L[0],T.p.v[1]*L[1],-T.p.v[2]*L[2]):S.translate(T.p.v[0]*L,T.p.v[1]*L,-T.p.v[2]*L));if(t.strokeWidthAnim&&(K=H<0?0:H),t.strokeColorAnim&&(J="rgb("+Math.round(255*X[0])+","+Math.round(255*X[1])+","+Math.round(255*X[2])+")"),t.fillColorAnim&&t.fc&&(U="rgb("+Math.round(255*Y[0])+","+Math.round(255*Y[1])+","+Math.round(255*Y[2])+")"),this._hasMaskedPath){if(S.translate(0,-t.ls),S.translate(0,k[1]*V*.01+s,0),this._pathData.p.v){b=(h.point[1]-m.point[1])/(h.point[0]-m.point[0]);var dt=180*Math.atan(b)/Math.PI;h.point[0]<m.point[0]&&(dt+=180),S.rotate(-dt*Math.PI/180)}S.translate(q,j,0),o-=k[0]*D[a].an*.005,D[a+1]&&Q!==D[a+1].ind&&(o+=D[a].an/2,o+=.001*t.tr*t.finalSize)}else{switch(S.translate(i,s,0),t.ps&&S.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:S.translate(D[a].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[D[a].line]),0,0);break;case 2:S.translate(D[a].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[D[a].line])/2,0,0)}S.translate(0,-t.ls),S.translate(B,0,0),S.translate(k[0]*D[a].an*.005,k[1]*V*.01,0),i+=D[a].l+.001*t.tr*t.finalSize}"html"===x?st=S.toCSS():"svg"===x?st=S.to2dCSS():at=[S.props[0],S.props[1],S.props[2],S.props[3],S.props[4],S.props[5],S.props[6],S.props[7],S.props[8],S.props[9],S.props[10],S.props[11],S.props[12],S.props[13],S.props[14],S.props[15]],Z=W}w<=a?(I=new yi(Z,K,J,U,st,at),this.renderedLetters.push(I),w+=1,this.lettersChangedFlag=!0):(I=this.renderedLetters[a],this.lettersChangedFlag=I.update(Z,K,J,U,st,at)||this.lettersChangedFlag)}}},ki.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},ki.prototype.mHelper=new Ft,ki.prototype.defaultPropsArray=[],r([bt],ki),Pi.prototype.initElement=function(t,e,i){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,i),this.textProperty=new vi(this,t.t,this.dynamicProperties),this.textAnimator=new ki(t.t,this.renderType,this),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},Pi.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},Pi.prototype.createPathShape=function(t,e){var i,s,a=e.length,r="";for(i=0;i<a;i+=1)"sh"===e[i].ty&&(s=e[i].ks.k,r+=ci(s,s.i.length,!0,t));return r},Pi.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},Pi.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},Pi.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},Pi.prototype.applyTextPropertiesToMatrix=function(t,e,i,s,a){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i])/2,0,0)}e.translate(s,a,0)},Pi.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},Pi.prototype.emptyProp=new yi,Pi.prototype.destroy=function(){},Pi.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var Ai,Si={shapes:[]};function xi(t,e,i){this.textSpans=[],this.renderType="svg",this.initElement(t,e,i)}function wi(t,e,i){this.initElement(t,e,i)}function Di(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initFrame(),this.initTransform(t,e,i),this.initHierarchy()}function Ci(){}function Mi(){}function Ti(t,e,i){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?l(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?vt.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function Fi(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=W("svg");var i="";if(e&&e.title){var s=W("title"),a=I();s.setAttribute("id",a),s.textContent=e.title,this.svgElement.appendChild(s),i+=a}if(e&&e.description){var r=W("desc"),n=I();r.setAttribute("id",n),r.textContent=e.description,this.svgElement.appendChild(r),i+=" "+n}i&&this.svgElement.setAttribute("aria-labelledby",i);var o=W("defs");this.svgElement.appendChild(o);var h=W("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}return r([Re,je,Je,Ue,ze,Ze,Pi],xi),xi.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=W("text"))},xi.prototype.buildTextContents=function(t){for(var e=0,i=t.length,s=[],a="";e<i;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(s.push(a),a=""):a+=t[e],e+=1;return s.push(a),s},xi.prototype.buildShapeData=function(t,e){if(t.shapes&&t.shapes.length){var i=t.shapes[0];if(i.it){var s=i.it[i.it.length-1];s.s&&(s.s.k[0]=e,s.s.k[1]=e)}}return t},xi.prototype.buildNewText=function(){var t,e;this.addDynamicProperty(this);var i=this.textProperty.currentData;this.renderedLetters=l(i?i.l.length:0),i.fc?this.layerElement.setAttribute("fill",this.buildColor(i.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),i.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(i.sc)),this.layerElement.setAttribute("stroke-width",i.sw)),this.layerElement.setAttribute("font-size",i.finalSize);var s=this.globalData.fontManager.getFontByName(i.f);if(s.fClass)this.layerElement.setAttribute("class",s.fClass);else{this.layerElement.setAttribute("font-family",s.fFamily);var a=i.fWeight,r=i.fStyle;this.layerElement.setAttribute("font-style",r),this.layerElement.setAttribute("font-weight",a)}this.layerElement.setAttribute("aria-label",i.t);var n,o=i.l||[],h=!!this.globalData.fontManager.chars;e=o.length;var p=this.mHelper,f=this.data.singleShape,d=0,m=0,c=!0,u=.001*i.tr*i.finalSize;if(!f||h||i.sz){var g,y=this.textSpans.length;for(t=0;t<e;t+=1){if(this.textSpans[t]||(this.textSpans[t]={span:null,childSpan:null,glyph:null}),!h||!f||0===t){if(n=y>t?this.textSpans[t].span:W(h?"g":"text"),y<=t){if(n.setAttribute("stroke-linecap","butt"),n.setAttribute("stroke-linejoin","round"),n.setAttribute("stroke-miterlimit","4"),this.textSpans[t].span=n,h){var v=W("g");n.appendChild(v),this.textSpans[t].childSpan=v}this.textSpans[t].span=n,this.layerElement.appendChild(n)}n.style.display="inherit"}if(p.reset(),f&&(o[t].n&&(d=-u,m+=i.yOffset,m+=c?1:0,c=!1),this.applyTextPropertiesToMatrix(i,p,o[t].line,d,m),d+=o[t].l||0,d+=u),h){var b;if(1===(g=this.globalData.fontManager.getCharData(i.finalText[t],s.fStyle,this.globalData.fontManager.getFontByName(i.f).fFamily)).t)b=new Ti(g.data,this.globalData,this);else{var _=Si;g.data&&g.data.shapes&&(_=this.buildShapeData(g.data,i.finalSize)),b=new gi(_,this.globalData,this)}if(this.textSpans[t].glyph){var k=this.textSpans[t].glyph;this.textSpans[t].childSpan.removeChild(k.layerElement),k.destroy()}this.textSpans[t].glyph=b,b._debug=!0,b.prepareFrame(0),b.renderFrame(),this.textSpans[t].childSpan.appendChild(b.layerElement),1===g.t&&this.textSpans[t].childSpan.setAttribute("transform","scale("+i.finalSize/100+","+i.finalSize/100+")")}else f&&n.setAttribute("transform","translate("+p.props[12]+","+p.props[13]+")"),n.textContent=o[t].val,n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}f&&n&&n.setAttribute("d","")}else{var P=this.textContainer,A="start";switch(i.j){case 1:A="end";break;case 2:A="middle";break;default:A="start"}P.setAttribute("text-anchor",A),P.setAttribute("letter-spacing",u);var S=this.buildTextContents(i.finalText);for(e=S.length,m=i.ps?i.ps[1]+i.ascent:0,t=0;t<e;t+=1)(n=this.textSpans[t].span||W("tspan")).textContent=S[t],n.setAttribute("x",0),n.setAttribute("y",m),n.style.display="inherit",P.appendChild(n),this.textSpans[t]||(this.textSpans[t]={span:null,glyph:null}),this.textSpans[t].span=n,m+=i.finalLineHeight;this.layerElement.appendChild(P)}for(;t<this.textSpans.length;)this.textSpans[t].span.style.display="none",t+=1;this._sizeChanged=!0},xi.prototype.sourceRectAtTime=function(){if(this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged){this._sizeChanged=!1;var t=this.layerElement.getBBox();this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}}return this.bbox},xi.prototype.getValue=function(){var t,e,i=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<i;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf&&(this._mdf=!0))},xi.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){var t,e;this._sizeChanged=!0;var i,s,a,r=this.textAnimator.renderedLetters,n=this.textProperty.currentData.l;for(e=n.length,t=0;t<e;t+=1)n[t].n||(i=r[t],s=this.textSpans[t].span,(a=this.textSpans[t].glyph)&&a.renderFrame(),i._mdf.m&&s.setAttribute("transform",i.m),i._mdf.o&&s.setAttribute("opacity",i.o),i._mdf.sw&&s.setAttribute("stroke-width",i.sw),i._mdf.sc&&s.setAttribute("stroke",i.sc),i._mdf.fc&&s.setAttribute("fill",i.fc))}},r([Qe],wi),wi.prototype.createContent=function(){var t=W("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},Di.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},Di.prototype.renderFrame=function(){},Di.prototype.getBaseElement=function(){return null},Di.prototype.destroy=function(){},Di.prototype.sourceRectAtTime=function(){},Di.prototype.hide=function(){},r([Re,je,Ue,ze],Di),r([Be],Ci),Ci.prototype.createNull=function(t){return new Di(t,this.globalData,this)},Ci.prototype.createShape=function(t){return new gi(t,this.globalData,this)},Ci.prototype.createText=function(t){return new xi(t,this.globalData,this)},Ci.prototype.createImage=function(t){return new Qe(t,this.globalData,this)},Ci.prototype.createSolid=function(t){return new wi(t,this.globalData,this)},Ci.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var i=W("clipPath"),a=W("rect");a.setAttribute("width",t.w),a.setAttribute("height",t.h),a.setAttribute("x",0),a.setAttribute("y",0);var r=I();i.setAttribute("id",r),i.appendChild(a),this.layerElement.setAttribute("clip-path","url("+s()+"#"+r+")"),e.appendChild(i),this.layers=t.layers,this.elements=l(t.layers.length)},Ci.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},Ci.prototype.updateContainerSize=function(){},Ci.prototype.findIndexByInd=function(t){var e=0,i=this.layers.length;for(e=0;e<i;e+=1)if(this.layers[e].ind===t)return e;return-1},Ci.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){e[t]=!0;var i=this.createItem(this.layers[t]);if(e[t]=i,N()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(i),i.initExpressions()),this.appendElementInPos(i,t),this.layers[t].tt){var s="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1;if(-1===s)return;if(this.elements[s]&&!0!==this.elements[s]){var a=e[s].getMatte(this.layers[t].tt);i.setMatte(a)}else this.buildItem(s),this.addPendingElement(i)}}},Ci.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,i=this.elements.length;e<i;){if(this.elements[e]===t){var s="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,a=this.elements[s].getMatte(this.layers[e].tt);t.setMatte(a);break}e+=1}}},Ci.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){var e;null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var i=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=i-1;e>=0;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<i;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},Ci.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){for(var s,a=0;a<e;)this.elements[a]&&!0!==this.elements[a]&&this.elements[a].getBaseElement()&&(s=this.elements[a].getBaseElement()),a+=1;s?this.layerElement.insertBefore(i,s):this.layerElement.appendChild(i)}},Ci.prototype.hide=function(){this.layerElement.style.display="none"},Ci.prototype.show=function(){this.layerElement.style.display="block"},r([Re,je,Ue,ze,Ze],Mi),Mi.prototype.initElement=function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},Mi.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var i,s=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),i=s-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&(this.elements[i].prepareFrame(this.renderedFrame-this.layers[i].st),this.elements[i]._mdf&&(this._mdf=!0))}},Mi.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},Mi.prototype.setElements=function(t){this.elements=t},Mi.prototype.getElements=function(){return this.elements},Mi.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},Mi.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},r([Ci,Mi,Je],Ti),Ti.prototype.createComp=function(t){return new Ti(t,this.globalData,this)},r([Ci],Fi),Fi.prototype.createComp=function(t){return new Ti(t,this.globalData,this)},Ai=Fi,U["svg"]=Ai,Nt.registerModifier("tm",qt),Nt.registerModifier("pb",jt),Nt.registerModifier("rp",Xt),Nt.registerModifier("rd",Ht),Nt.registerModifier("zz",he),Nt.registerModifier("op",be),It}));
+"undefined"!=typeof document&&"undefined"!=typeof navigator&&function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lottie=e()}(this,(function(){"use strict";var t="",e=!1,i=-999999,s=function(){return t};function a(t){return document.createElement(t)}function r(t,e){var i,s,a=t.length;for(i=0;i<a;i+=1)for(var r in s=t[i].prototype)Object.prototype.hasOwnProperty.call(s,r)&&(e.prototype[r]=s[r])}function n(t){function e(){}return e.prototype=t,e}var o=function(){function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].pause()},resume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].resume()},setRate:function(t){var e,i=this.audios.length;for(e=0;e<i;e+=1)this.audios[e].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}}(),h=function(){function t(t,e){var i,s=0,a=[];switch(t){case"int16":case"uint8c":i=1;break;default:i=1.1}for(s=0;s<e;s+=1)a.push(i);return a}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(e,i){return"float32"===e?new Float32Array(i):"int16"===e?new Int16Array(i):"uint8c"===e?new Uint8ClampedArray(i):t(e,i)}:t}();function l(t){return Array.apply(null,{length:t})}function p(t){return p="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},p(t)}var f=!0,d=null,m=null,c="",u=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),g=Math.pow,y=Math.sqrt,v=Math.floor,b=(Math.max,Math.min),_={};!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],i=e.length;for(t=0;t<i;t+=1)_[e[t]]=Math[e[t]]}(),_.random=Math.random,_.abs=function(t){if("object"===p(t)&&t.length){var e,i=l(t.length),s=t.length;for(e=0;e<s;e+=1)i[e]=Math.abs(t[e]);return i}return Math.abs(t)};var k=150,P=Math.PI/180,A=.5519;function S(t){0}function x(t,e,i,s){this.type=t,this.currentTime=e,this.totalTime=i,this.direction=s<0?-1:1}function w(t,e){this.type=t,this.direction=e<0?-1:1}function D(t,e,i,s){this.type=t,this.currentLoop=i,this.totalLoops=e,this.direction=s<0?-1:1}function C(t,e,i){this.type=t,this.firstFrame=e,this.totalFrames=i}function M(t,e){this.type=t,this.target=e}function T(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function F(t){this.type="configError",this.nativeError=t}var E,I=(E=0,function(){return c+"__lottie_element_"+(E+=1)});function L(t,e,i){var s,a,r,n,o,h,l,p;switch(h=i*(1-e),l=i*(1-(o=6*t-(n=Math.floor(6*t)))*e),p=i*(1-(1-o)*e),n%6){case 0:s=i,a=p,r=h;break;case 1:s=l,a=i,r=h;break;case 2:s=h,a=i,r=p;break;case 3:s=h,a=l,r=i;break;case 4:s=p,a=h,r=i;break;case 5:s=i,a=h,r=l}return[s,a,r]}function V(t,e,i){var s,a=Math.max(t,e,i),r=Math.min(t,e,i),n=a-r,o=0===a?0:n/a,h=a/255;switch(a){case r:s=0;break;case t:s=e-i+n*(e<i?6:0),s/=6*n;break;case e:s=i-t+2*n,s/=6*n;break;case i:s=t-e+4*n,s/=6*n}return[s,o,h]}function R(t,e){var i=V(255*t[0],255*t[1],255*t[2]);return i[1]+=e,i[1]>1?i[1]=1:i[1]<=0&&(i[1]=0),L(i[0],i[1],i[2])}function z(t,e){var i=V(255*t[0],255*t[1],255*t[2]);return i[2]+=e,i[2]>1?i[2]=1:i[2]<0&&(i[2]=0),L(i[0],i[1],i[2])}function O(t,e){var i=V(255*t[0],255*t[1],255*t[2]);return i[0]+=e/360,i[0]>1?i[0]-=1:i[0]<0&&(i[0]+=1),L(i[0],i[1],i[2])}!function(){var t,e,i=[];for(t=0;t<256;t+=1)e=t.toString(16),i[t]=1===e.length?"0"+e:e}();var N=function(){return d},B=function(){return m},q=function(t){k=t},j=function(){return k};function W(t){return document.createElementNS("http://www.w3.org/2000/svg",t)}function X(t){return X="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},X(t)}var H=function(){var t,i,s=1,a=[],r={onmessage:function(){},postMessage:function(e){t({data:e})}},n={postMessage:function(t){r.onmessage({data:t})}};function o(i){if(window.Worker&&window.Blob&&e){var s=new Blob(["var _workerSelf = self; self.onmessage = ",i.toString()],{type:"text/javascript"}),a=URL.createObjectURL(s);return new Worker(a)}return t=i,r}function h(){i||(i=o((function(t){if(n.dataManager||(n.dataManager=function(){function t(a,r){var n,o,h,l,p,d,m=a.length;for(o=0;o<m;o+=1)if("ks"in(n=a[o])&&!n.completed){if(n.completed=!0,n.hasMask){var c=n.masksProperties;for(l=c.length,h=0;h<l;h+=1)if(c[h].pt.k.i)s(c[h].pt.k);else for(d=c[h].pt.k.length,p=0;p<d;p+=1)c[h].pt.k[p].s&&s(c[h].pt.k[p].s[0]),c[h].pt.k[p].e&&s(c[h].pt.k[p].e[0])}0===n.ty?(n.layers=e(n.refId,r),t(n.layers,r)):4===n.ty?i(n.shapes):5===n.ty&&f(n)}}function e(t,e){var i=function(t,e){for(var i=0,s=e.length;i<s;){if(e[i].id===t)return e[i];i+=1}return null}(t,e);return i?i.layers.__used?JSON.parse(JSON.stringify(i.layers)):(i.layers.__used=!0,i.layers):null}function i(t){var e,a,r;for(e=t.length-1;e>=0;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)s(t[e].ks.k);else for(r=t[e].ks.k.length,a=0;a<r;a+=1)t[e].ks.k[a].s&&s(t[e].ks.k[a].s[0]),t[e].ks.k[a].e&&s(t[e].ks.k[a].e[0]);else"gr"===t[e].ty&&i(t[e].it)}function s(t){var e,i=t.i.length;for(e=0;e<i;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function a(t,e){var i=e?e.split("."):[100,100,100];return t[0]>i[0]||!(i[0]>t[0])&&(t[1]>i[1]||!(i[1]>t[1])&&(t[2]>i[2]||!(i[2]>t[2])&&null))}var r,n=function(){var t=[4,4,14];function e(t){var e,i,s,a=t.length;for(e=0;e<a;e+=1)5===t[e].ty&&(s=void 0,s=(i=t[e]).t.d,i.t.d={k:[{s:s,t:0}]})}return function(i){if(a(t,i.v)&&(e(i.layers),i.assets)){var s,r=i.assets.length;for(s=0;s<r;s+=1)i.assets[s].layers&&e(i.assets[s].layers)}}}(),o=(r=[4,7,99],function(t){if(t.chars&&!a(r,t.v)){var e,s=t.chars.length;for(e=0;e<s;e+=1){var n=t.chars[e];n.data&&n.data.shapes&&(i(n.data.shapes),n.data.ip=0,n.data.op=99999,n.data.st=0,n.data.sr=1,n.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[e].t||(n.data.shapes.push({ty:"no"}),n.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}}}),h=function(){var t=[5,7,15];function e(t){var e,i,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(i=void 0,"number"==typeof(i=t[e].t.p).a&&(i.a={a:0,k:i.a}),"number"==typeof i.p&&(i.p={a:0,k:i.p}),"number"==typeof i.r&&(i.r={a:0,k:i.r}))}return function(i){if(a(t,i.v)&&(e(i.layers),i.assets)){var s,r=i.assets.length;for(s=0;s<r;s+=1)i.assets[s].layers&&e(i.assets[s].layers)}}}(),l=function(){var t=[4,1,9];function e(t){var i,s,a,r=t.length;for(i=0;i<r;i+=1)if("gr"===t[i].ty)e(t[i].it);else if("fl"===t[i].ty||"st"===t[i].ty)if(t[i].c.k&&t[i].c.k[0].i)for(a=t[i].c.k.length,s=0;s<a;s+=1)t[i].c.k[s].s&&(t[i].c.k[s].s[0]/=255,t[i].c.k[s].s[1]/=255,t[i].c.k[s].s[2]/=255,t[i].c.k[s].s[3]/=255),t[i].c.k[s].e&&(t[i].c.k[s].e[0]/=255,t[i].c.k[s].e[1]/=255,t[i].c.k[s].e[2]/=255,t[i].c.k[s].e[3]/=255);else t[i].c.k[0]/=255,t[i].c.k[1]/=255,t[i].c.k[2]/=255,t[i].c.k[3]/=255}function i(t){var i,s=t.length;for(i=0;i<s;i+=1)4===t[i].ty&&e(t[i].shapes)}return function(e){if(a(t,e.v)&&(i(e.layers),e.assets)){var s,r=e.assets.length;for(s=0;s<r;s+=1)e.assets[s].layers&&i(e.assets[s].layers)}}}(),p=function(){var t=[4,4,18];function e(t){var i,s,a;for(i=t.length-1;i>=0;i-=1)if("sh"===t[i].ty)if(t[i].ks.k.i)t[i].ks.k.c=t[i].closed;else for(a=t[i].ks.k.length,s=0;s<a;s+=1)t[i].ks.k[s].s&&(t[i].ks.k[s].s[0].c=t[i].closed),t[i].ks.k[s].e&&(t[i].ks.k[s].e[0].c=t[i].closed);else"gr"===t[i].ty&&e(t[i].it)}function i(t){var i,s,a,r,n,o,h=t.length;for(s=0;s<h;s+=1){if((i=t[s]).hasMask){var l=i.masksProperties;for(r=l.length,a=0;a<r;a+=1)if(l[a].pt.k.i)l[a].pt.k.c=l[a].cl;else for(o=l[a].pt.k.length,n=0;n<o;n+=1)l[a].pt.k[n].s&&(l[a].pt.k[n].s[0].c=l[a].cl),l[a].pt.k[n].e&&(l[a].pt.k[n].e[0].c=l[a].cl)}4===i.ty&&e(i.shapes)}}return function(e){if(a(t,e.v)&&(i(e.layers),e.assets)){var s,r=e.assets.length;for(s=0;s<r;s+=1)e.assets[s].layers&&i(e.assets[s].layers)}}}();function f(t){0===t.t.a.length&&t.t.p}var d={completeData:function(i){i.__complete||(l(i),n(i),o(i),h(i),p(i),t(i.layers,i.assets),function(i,s){if(i){var a=0,r=i.length;for(a=0;a<r;a+=1)1===i[a].t&&(i[a].data.layers=e(i[a].data.refId,s),t(i[a].data.layers,s))}}(i.chars,i.assets),i.__complete=!0)}};return d.checkColors=l,d.checkChars=o,d.checkPathProperties=h,d.checkShapes=p,d.completeLayers=t,d}()),n.assetLoader||(n.assetLoader=function(){function t(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")||t.response&&"object"===X(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}return{load:function(e,i,s,a){var r,n=new XMLHttpRequest;try{n.responseType="json"}catch(t){}n.onreadystatechange=function(){if(4===n.readyState)if(200===n.status)r=t(n),s(r);else try{r=t(n),s(r)}catch(t){a&&a(t)}};try{n.open(["G","E","T"].join(""),e,!0)}catch(t){n.open(["G","E","T"].join(""),i+"/"+e,!0)}n.send()}}}()),"loadAnimation"===t.data.type)n.assetLoader.load(t.data.path,t.data.fullPath,(function(e){n.dataManager.completeData(e),n.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){n.postMessage({id:t.data.id,status:"error"})}));else if("complete"===t.data.type){var e=t.data.animation;n.dataManager.completeData(e),n.postMessage({id:t.data.id,payload:e,status:"success"})}else"loadData"===t.data.type&&n.assetLoader.load(t.data.path,t.data.fullPath,(function(e){n.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){n.postMessage({id:t.data.id,status:"error"})}))})),i.onmessage=function(t){var e=t.data,i=e.id,s=a[i];a[i]=null,"success"===e.status?s.onComplete(e.payload):s.onError&&s.onError()})}function l(t,e){var i="processId_"+(s+=1);return a[i]={onComplete:t,onError:e},i}return{loadAnimation:function(t,e,s){h();var a=l(e,s);i.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:a})},loadData:function(t,e,s){h();var a=l(e,s);i.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:a})},completeAnimation:function(t,e,s){h();var a=l(e,s);i.postMessage({type:"complete",animation:t,id:a})}}}(),Y=function(){var t=function(){var t=a("canvas");t.width=1,t.height=1;var e=t.getContext("2d");return e.fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1),t}();function e(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function i(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function s(t,e,i){var s="";if(t.e)s=t.p;else if(e){var a=t.p;-1!==a.indexOf("images/")&&(a=a.split("/")[1]),s=e+a}else s=i,s+=t.u?t.u:"",s+=t.p;return s}function r(t){var e=0,i=setInterval(function(){(t.getBBox().width||e>500)&&(this._imageLoaded(),clearInterval(i)),e+=1}.bind(this),50)}function n(t){var e={assetData:t},i=s(t,this.assetsPath,this.path);return H.loadData(i,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}function o(){this._imageLoaded=e.bind(this),this._footageLoaded=i.bind(this),this.testImageLoaded=r.bind(this),this.createFootageData=n.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return o.prototype={loadAssets:function(t,e){var i;this.imagesLoadedCb=e;var s=t.length;for(i=0;i<s;i+=1)t[i].layers||(t[i].t&&"seq"!==t[i].t?3===t[i].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[i]))):(this.totalImages+=1,this.images.push(this._createImageData(t[i]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,i=this.images.length;e<i;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(e){var i=s(e,this.assetsPath,this.path),r=a("img");r.crossOrigin="anonymous",r.addEventListener("load",this._imageLoaded,!1),r.addEventListener("error",function(){n.img=t,this._imageLoaded()}.bind(this),!1),r.src=i;var n={img:r,assetData:e};return n},createImageData:function(e){var i=s(e,this.assetsPath,this.path),a=W("image");u?this.testImageLoaded(a):a.addEventListener("load",this._imageLoaded,!1),a.addEventListener("error",function(){r.img=t,this._imageLoaded()}.bind(this),!1),a.setAttributeNS("http://www.w3.org/1999/xlink","href",i),this._elementHelper.append?this._elementHelper.append(a):this._elementHelper.appendChild(a);var r={img:a,assetData:e};return r},imageLoaded:e,footageLoaded:i,setCacheType:function(t,e){"svg"===t?(this._elementHelper=e,this._createImageData=this.createImageData.bind(this)):this._createImageData=this.createImgData.bind(this)}},o}();function G(){}G.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var i=this._cbs[t],s=0;s<i.length;s+=1)i[s](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var i=0,s=this._cbs[t].length;i<s;)this._cbs[t][i]===e&&(this._cbs[t].splice(i,1),i-=1,s-=1),i+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var K=function(){function t(t){for(var e,i=t.split("\r\n"),s={},a=0,r=0;r<i.length;r+=1)2===(e=i[r].split(":")).length&&(s[e[0]]=e[1].trim(),a+=1);if(0===a)throw new Error;return s}return function(e){for(var i=[],s=0;s<e.length;s+=1){var a=e[s],r={time:a.tm,duration:a.dr};try{r.payload=JSON.parse(e[s].cm)}catch(i){try{r.payload=t(e[s].cm)}catch(t){r.payload={name:e[s].cm}}}i.push(r)}return i}}(),J=function(){function t(t){this.compositions.push(t)}return function(){function e(t){for(var e=0,i=this.compositions.length;e<i;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return e.compositions=[],e.currentFrame=0,e.registerComposition=t,e}}(),U={};function Z(t){return Z="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Z(t)}var Q=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=I(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=f,this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=J(),this.imagePreloader=new Y,this.audioController=o(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new x("drawnFrame",0,0,0),this.expressionsPlugin=N()};r([G],Q),Q.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg";t.animType?e=t.animType:t.renderer&&(e=t.renderer);var i=U[e];this.renderer=new i(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||void 0===t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),H.loadAnimation(t.path,this.configAnimation,this.onSetupError))},Q.prototype.onSetupError=function(){this.trigger("data_failed")},Q.prototype.setupAnimation=function(t){H.completeAnimation(t,this.configAnimation)},Q.prototype.setData=function(t,e){e&&"object"!==Z(e)&&(e=JSON.parse(e));var i={wrapper:t,animationData:e},s=t.attributes;i.path=s.getNamedItem("data-animation-path")?s.getNamedItem("data-animation-path").value:s.getNamedItem("data-bm-path")?s.getNamedItem("data-bm-path").value:s.getNamedItem("bm-path")?s.getNamedItem("bm-path").value:"",i.animType=s.getNamedItem("data-anim-type")?s.getNamedItem("data-anim-type").value:s.getNamedItem("data-bm-type")?s.getNamedItem("data-bm-type").value:s.getNamedItem("bm-type")?s.getNamedItem("bm-type").value:s.getNamedItem("data-bm-renderer")?s.getNamedItem("data-bm-renderer").value:s.getNamedItem("bm-renderer")?s.getNamedItem("bm-renderer").value:function(){if(U.canvas)return"canvas";for(var t in U)if(U[t])return t;return""}()||"canvas";var a=s.getNamedItem("data-anim-loop")?s.getNamedItem("data-anim-loop").value:s.getNamedItem("data-bm-loop")?s.getNamedItem("data-bm-loop").value:s.getNamedItem("bm-loop")?s.getNamedItem("bm-loop").value:"";"false"===a?i.loop=!1:"true"===a?i.loop=!0:""!==a&&(i.loop=parseInt(a,10));var r=s.getNamedItem("data-anim-autoplay")?s.getNamedItem("data-anim-autoplay").value:s.getNamedItem("data-bm-autoplay")?s.getNamedItem("data-bm-autoplay").value:!s.getNamedItem("bm-autoplay")||s.getNamedItem("bm-autoplay").value;i.autoplay="false"!==r,i.name=s.getNamedItem("data-name")?s.getNamedItem("data-name").value:s.getNamedItem("data-bm-name")?s.getNamedItem("data-bm-name").value:s.getNamedItem("bm-name")?s.getNamedItem("bm-name").value:"","false"===(s.getNamedItem("data-anim-prerender")?s.getNamedItem("data-anim-prerender").value:s.getNamedItem("data-bm-prerender")?s.getNamedItem("data-bm-prerender").value:s.getNamedItem("bm-prerender")?s.getNamedItem("bm-prerender").value:"")&&(i.prerender=!1),i.path?this.setParams(i):this.trigger("destroy")},Q.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,i,s=this.animationData.layers,a=s.length,r=t.layers,n=r.length;for(i=0;i<n;i+=1)for(e=0;e<a;){if(s[e].id===r[i].id){s[e]=r[i];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(a=t.assets.length,e=0;e<a;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,H.completeAnimation(this.animationData,this.onSegmentComplete)},Q.prototype.onSegmentComplete=function(t){this.animationData=t;var e=N();e&&e.initExpressions(this),this.loadNextSegment()},Q.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var i=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,H.loadData(i,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},Q.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},Q.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},Q.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},Q.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=K(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},Q.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},Q.prototype.checkLoaded=function(){if(!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()){this.isLoaded=!0;var t=N();t&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play()}},Q.prototype.resize=function(t,e){var i="number"==typeof t?t:void 0,s="number"==typeof e?e:void 0;this.renderer.updateContainerSize(i,s)},Q.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},Q.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},Q.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},Q.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},Q.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},Q.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},Q.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},Q.prototype.getMarkerData=function(t){for(var e,i=0;i<this.markers.length;i+=1)if((e=this.markers[i]).payload&&e.payload.name===t)return e;return null},Q.prototype.goToAndStop=function(t,e,i){if(!i||this.name===i){var s=Number(t);if(isNaN(s)){var a=this.getMarkerData(t);a&&this.goToAndStop(a.time,!0)}else e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier);this.pause()}},Q.prototype.goToAndPlay=function(t,e,i){if(!i||this.name===i){var s=Number(t);if(isNaN(s)){var a=this.getMarkerData(t);a&&(a.duration?this.playSegments([a.time,a.time+a.duration],!0):this.goToAndStop(a.time,!0))}else this.goToAndStop(s,e,i);this.play()}},Q.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,i=!1;e>=this.totalFrames-1&&this.frameModifier>0?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(i=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(i=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),i&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},Q.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(this.frameModifier>0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},Q.prototype.setSegment=function(t,e){var i=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?i=t:this.currentRawFrame+this.firstFrame>e&&(i=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==i&&this.goToAndStop(i,!0)},Q.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===Z(t[0])){var i,s=t.length;for(i=0;i<s;i+=1)this.segments.push(t[i])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},Q.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},Q.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},Q.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},Q.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},Q.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},Q.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},Q.prototype.setLoop=function(t){this.loop=t},Q.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},Q.prototype.getVolume=function(){return this.audioController.getVolume()},Q.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},Q.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},Q.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},Q.prototype.getPath=function(){return this.path},Q.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var i=t.p;-1!==i.indexOf("images/")&&(i=i.split("/")[1]),e=this.assetsPath+i}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},Q.prototype.getAssetData=function(t){for(var e=0,i=this.assets.length;e<i;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},Q.prototype.hide=function(){this.renderer.hide()},Q.prototype.show=function(){this.renderer.show()},Q.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},Q.prototype.updateDocumentData=function(t,e,i){try{this.renderer.getElementByPath(t).updateDocumentData(e,i)}catch(t){}},Q.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new x(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new D(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new w(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new C(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new M(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new x(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new D(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new w(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new C(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new M(t,this))},Q.prototype.triggerRenderFrameError=function(t){var e=new T(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)},Q.prototype.triggerConfigError=function(t){var e=new F(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)};var $=function(){var t={},e=[],i=0,s=0,r=0,n=!0,o=!1;function h(t){for(var i=0,a=t.target;i<s;)e[i].animation===a&&(e.splice(i,1),i-=1,s-=1,a.isPaused||f()),i+=1}function l(t,i){if(!t)return null;for(var a=0;a<s;){if(e[a].elem===t&&null!==e[a].elem)return e[a].animation;a+=1}var r=new Q;return d(r,t),r.setData(t,i),r}function p(){r+=1,u()}function f(){r-=1}function d(t,i){t.addEventListener("destroy",h),t.addEventListener("_active",p),t.addEventListener("_idle",f),e.push({elem:i,animation:t}),s+=1}function m(t){var a,h=t-i;for(a=0;a<s;a+=1)e[a].animation.advanceTime(h);i=t,r&&!o?window.requestAnimationFrame(m):n=!0}function c(t){i=t,window.requestAnimationFrame(m)}function u(){!o&&r&&n&&(window.requestAnimationFrame(c),n=!1)}return t.registerAnimation=l,t.loadAnimation=function(t){var e=new Q;return d(e,null),e.setParams(t),e},t.setSpeed=function(t,i){var a;for(a=0;a<s;a+=1)e[a].animation.setSpeed(t,i)},t.setDirection=function(t,i){var a;for(a=0;a<s;a+=1)e[a].animation.setDirection(t,i)},t.play=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.play(t)},t.pause=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.pause(t)},t.stop=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.stop(t)},t.togglePause=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.togglePause(t)},t.searchAnimations=function(t,e,i){var s,r=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),n=r.length;for(s=0;s<n;s+=1)i&&r[s].setAttribute("data-bm-type",i),l(r[s],t);if(e&&0===n){i||(i="svg");var o=document.getElementsByTagName("body")[0];o.innerText="";var h=a("div");h.style.width="100%",h.style.height="100%",h.setAttribute("data-bm-type",i),o.appendChild(h),l(h,t)}},t.resize=function(){var t;for(t=0;t<s;t+=1)e[t].animation.resize()},t.goToAndStop=function(t,i,a){var r;for(r=0;r<s;r+=1)e[r].animation.goToAndStop(t,i,a)},t.destroy=function(t){var i;for(i=s-1;i>=0;i-=1)e[i].animation.destroy(t)},t.freeze=function(){o=!0},t.unfreeze=function(){o=!1,u()},t.setVolume=function(t,i){var a;for(a=0;a<s;a+=1)e[a].animation.setVolume(t,i)},t.mute=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.mute(t)},t.unmute=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.unmute(t)},t.getRegisteredAnimations=function(){var t,i=e.length,s=[];for(t=0;t<i;t+=1)s.push(e[t].animation);return s},t}(),tt=function(){var t={getBezierEasing:function(t,i,s,a,r){var n=r||("bez_"+t+"_"+i+"_"+s+"_"+a).replace(/\./g,"p");if(e[n])return e[n];var o=new p([t,i,s,a]);return e[n]=o,o}},e={};var i=11,s=1/(i-1),a="function"==typeof Float32Array;function r(t,e){return 1-3*e+3*t}function n(t,e){return 3*e-6*t}function o(t){return 3*t}function h(t,e,i){return((r(e,i)*t+n(e,i))*t+o(e))*t}function l(t,e,i){return 3*r(e,i)*t*t+2*n(e,i)*t+o(e)}function p(t){this._p=t,this._mSampleValues=a?new Float32Array(i):new Array(i),this._precomputed=!1,this.get=this.get.bind(this)}return p.prototype={get:function(t){var e=this._p[0],i=this._p[1],s=this._p[2],a=this._p[3];return this._precomputed||this._precompute(),e===i&&s===a?t:0===t?0:1===t?1:h(this._getTForX(t),i,a)},_precompute:function(){var t=this._p[0],e=this._p[1],i=this._p[2],s=this._p[3];this._precomputed=!0,t===e&&i===s||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],a=0;a<i;++a)this._mSampleValues[a]=h(a*s,t,e)},_getTForX:function(t){for(var e=this._p[0],a=this._p[2],r=this._mSampleValues,n=0,o=1,p=i-1;o!==p&&r[o]<=t;++o)n+=s;var f=n+(t-r[--o])/(r[o+1]-r[o])*s,d=l(f,e,a);return d>=.001?function(t,e,i,s){for(var a=0;a<4;++a){var r=l(e,i,s);if(0===r)return e;e-=(h(e,i,s)-t)/r}return e}(t,f,e,a):0===d?f:function(t,e,i,s,a){var r,n,o=0;do{(r=h(n=e+(i-e)/2,s,a)-t)>0?i=n:e=n}while(Math.abs(r)>1e-7&&++o<10);return n}(t,n,n+s,e,a)}},t}(),et={double:function(t){return t.concat(l(t.length))}},it=function(t,e,i){var s=0,a=t,r=l(a);return{newElement:function(){return s?r[s-=1]:e()},release:function(t){s===a&&(r=et.double(r),a*=2),i&&i(t),r[s]=t,s+=1}}},st=it(8,(function(){return{addedLength:0,percents:h("float32",j()),lengths:h("float32",j())}})),at=it(8,(function(){return{lengths:[],totalLength:0}}),(function(t){var e,i=t.lengths.length;for(e=0;e<i;e+=1)st.release(t.lengths[e]);t.lengths.length=0}));var rt=function(){var t=Math;function e(t,e,i,s,a,r){var n=t*s+e*a+i*r-a*s-r*t-i*e;return n>-.001&&n<.001}var i=function(t,e,i,s){var a,r,n,o,h,l,p=j(),f=0,d=[],m=[],c=st.newElement();for(n=i.length,a=0;a<p;a+=1){for(h=a/(p-1),l=0,r=0;r<n;r+=1)o=g(1-h,3)*t[r]+3*g(1-h,2)*h*i[r]+3*(1-h)*g(h,2)*s[r]+g(h,3)*e[r],d[r]=o,null!==m[r]&&(l+=g(d[r]-m[r],2)),m[r]=d[r];l&&(f+=l=y(l)),c.percents[a]=h,c.lengths[a]=f}return c.addedLength=f,c};function s(t){this.segmentLength=0,this.points=new Array(t)}function a(t,e){this.partialLength=t,this.point=e}var r,n=(r={},function(t,i,n,o){var h=(t[0]+"_"+t[1]+"_"+i[0]+"_"+i[1]+"_"+n[0]+"_"+n[1]+"_"+o[0]+"_"+o[1]).replace(/\./g,"p");if(!r[h]){var p,f,d,m,c,u,v,b=j(),_=0,k=null;2===t.length&&(t[0]!==i[0]||t[1]!==i[1])&&e(t[0],t[1],i[0],i[1],t[0]+n[0],t[1]+n[1])&&e(t[0],t[1],i[0],i[1],i[0]+o[0],i[1]+o[1])&&(b=2);var P=new s(b);for(d=n.length,p=0;p<b;p+=1){for(v=l(d),c=p/(b-1),u=0,f=0;f<d;f+=1)m=g(1-c,3)*t[f]+3*g(1-c,2)*c*(t[f]+n[f])+3*(1-c)*g(c,2)*(i[f]+o[f])+g(c,3)*i[f],v[f]=m,null!==k&&(u+=g(v[f]-k[f],2));_+=u=y(u),P.points[p]=new a(u,v),k=v}P.segmentLength=_,r[h]=P}return r[h]});function o(t,e){var i=e.percents,s=e.lengths,a=i.length,r=v((a-1)*t),n=t*e.addedLength,o=0;if(r===a-1||0===r||n===s[r])return i[r];for(var h=s[r]>n?-1:1,l=!0;l;)if(s[r]<=n&&s[r+1]>n?(o=(n-s[r])/(s[r+1]-s[r]),l=!1):r+=h,r<0||r>=a-1){if(r===a-1)return i[r];l=!1}return i[r]+(i[r+1]-i[r])*o}var p=h("float32",8);return{getSegmentsLength:function(t){var e,s=at.newElement(),a=t.c,r=t.v,n=t.o,o=t.i,h=t._length,l=s.lengths,p=0;for(e=0;e<h-1;e+=1)l[e]=i(r[e],r[e+1],n[e],o[e+1]),p+=l[e].addedLength;return a&&h&&(l[e]=i(r[e],r[0],n[e],o[0]),p+=l[e].addedLength),s.totalLength=p,s},getNewSegment:function(e,i,s,a,r,n,h){r<0?r=0:r>1&&(r=1);var l,f=o(r,h),d=o(n=n>1?1:n,h),m=e.length,c=1-f,u=1-d,g=c*c*c,y=f*c*c*3,v=f*f*c*3,b=f*f*f,_=c*c*u,k=f*c*u+c*f*u+c*c*d,P=f*f*u+c*f*d+f*c*d,A=f*f*d,S=c*u*u,x=f*u*u+c*d*u+c*u*d,w=f*d*u+c*d*d+f*u*d,D=f*d*d,C=u*u*u,M=d*u*u+u*d*u+u*u*d,T=d*d*u+u*d*d+d*u*d,F=d*d*d;for(l=0;l<m;l+=1)p[4*l]=t.round(1e3*(g*e[l]+y*s[l]+v*a[l]+b*i[l]))/1e3,p[4*l+1]=t.round(1e3*(_*e[l]+k*s[l]+P*a[l]+A*i[l]))/1e3,p[4*l+2]=t.round(1e3*(S*e[l]+x*s[l]+w*a[l]+D*i[l]))/1e3,p[4*l+3]=t.round(1e3*(C*e[l]+M*s[l]+T*a[l]+F*i[l]))/1e3;return p},getPointInSegment:function(e,i,s,a,r,n){var h=o(r,n),l=1-h;return[t.round(1e3*(l*l*l*e[0]+(h*l*l+l*h*l+l*l*h)*s[0]+(h*h*l+l*h*h+h*l*h)*a[0]+h*h*h*i[0]))/1e3,t.round(1e3*(l*l*l*e[1]+(h*l*l+l*h*l+l*l*h)*s[1]+(h*h*l+l*h*h+h*l*h)*a[1]+h*h*h*i[1]))/1e3]},buildBezierData:n,pointOnLine2D:e,pointOnLine3D:function(i,s,a,r,n,o,h,l,p){if(0===a&&0===o&&0===p)return e(i,s,r,n,h,l);var f,d=t.sqrt(t.pow(r-i,2)+t.pow(n-s,2)+t.pow(o-a,2)),m=t.sqrt(t.pow(h-i,2)+t.pow(l-s,2)+t.pow(p-a,2)),c=t.sqrt(t.pow(h-r,2)+t.pow(l-n,2)+t.pow(p-o,2));return(f=d>m?d>c?d-m-c:c-m-d:c>m?c-m-d:m-d-c)>-1e-4&&f<1e-4}}}(),nt=i,ot=Math.abs;function ht(t,e){var i,s=this.offsetTime;"multidimensional"===this.propType&&(i=h("float32",this.pv.length));for(var a,r,n,o,l,p,f,d,m,c=e.lastIndex,u=c,g=this.keyframes.length-1,y=!0;y;){if(a=this.keyframes[u],r=this.keyframes[u+1],u===g-1&&t>=r.t-s){a.h&&(a=r),c=0;break}if(r.t-s>t){c=u;break}u<g-1?u+=1:(c=0,y=!1)}n=this.keyframesMetadata[u]||{};var v,b,_,k,A,S,x,w,D,C,M=r.t-s,T=a.t-s;if(a.to){n.bezierData||(n.bezierData=rt.buildBezierData(a.s,r.s||a.e,a.to,a.ti));var F=n.bezierData;if(t>=M||t<T){var E=t>=M?F.points.length-1:0;for(l=F.points[E].point.length,o=0;o<l;o+=1)i[o]=F.points[E].point[o]}else{n.__fnct?m=n.__fnct:(m=tt.getBezierEasing(a.o.x,a.o.y,a.i.x,a.i.y,a.n).get,n.__fnct=m),p=m((t-T)/(M-T));var I,L=F.segmentLength*p,V=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastAddedLength:0;for(d=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastPoint:0,y=!0,f=F.points.length;y;){if(V+=F.points[d].partialLength,0===L||0===p||d===F.points.length-1){for(l=F.points[d].point.length,o=0;o<l;o+=1)i[o]=F.points[d].point[o];break}if(L>=V&&L<V+F.points[d+1].partialLength){for(I=(L-V)/F.points[d+1].partialLength,l=F.points[d].point.length,o=0;o<l;o+=1)i[o]=F.points[d].point[o]+(F.points[d+1].point[o]-F.points[d].point[o])*I;break}d<f-1?d+=1:y=!1}e._lastPoint=d,e._lastAddedLength=V-F.points[d].partialLength,e._lastKeyframeIndex=u}}else{var R,z,O,N,B;if(g=a.s.length,v=r.s||a.e,this.sh&&1!==a.h)if(t>=M)i[0]=v[0],i[1]=v[1],i[2]=v[2];else if(t<=T)i[0]=a.s[0],i[1]=a.s[1],i[2]=a.s[2];else{var q=lt(a.s),j=lt(v);b=i,_=function(t,e,i){var s,a,r,n,o,h=[],l=t[0],p=t[1],f=t[2],d=t[3],m=e[0],c=e[1],u=e[2],g=e[3];return(a=l*m+p*c+f*u+d*g)<0&&(a=-a,m=-m,c=-c,u=-u,g=-g),1-a>1e-6?(s=Math.acos(a),r=Math.sin(s),n=Math.sin((1-i)*s)/r,o=Math.sin(i*s)/r):(n=1-i,o=i),h[0]=n*l+o*m,h[1]=n*p+o*c,h[2]=n*f+o*u,h[3]=n*d+o*g,h}(q,j,(t-T)/(M-T)),k=_[0],A=_[1],S=_[2],x=_[3],w=Math.atan2(2*A*x-2*k*S,1-2*A*A-2*S*S),D=Math.asin(2*k*A+2*S*x),C=Math.atan2(2*k*x-2*A*S,1-2*k*k-2*S*S),b[0]=w/P,b[1]=D/P,b[2]=C/P}else for(u=0;u<g;u+=1)1!==a.h&&(t>=M?p=1:t<T?p=0:(a.o.x.constructor===Array?(n.__fnct||(n.__fnct=[]),n.__fnct[u]?m=n.__fnct[u]:(R=void 0===a.o.x[u]?a.o.x[0]:a.o.x[u],z=void 0===a.o.y[u]?a.o.y[0]:a.o.y[u],O=void 0===a.i.x[u]?a.i.x[0]:a.i.x[u],N=void 0===a.i.y[u]?a.i.y[0]:a.i.y[u],m=tt.getBezierEasing(R,z,O,N).get,n.__fnct[u]=m)):n.__fnct?m=n.__fnct:(R=a.o.x,z=a.o.y,O=a.i.x,N=a.i.y,m=tt.getBezierEasing(R,z,O,N).get,a.keyframeMetadata=m),p=m((t-T)/(M-T)))),v=r.s||a.e,B=1===a.h?a.s[u]:a.s[u]+(v[u]-a.s[u])*p,"multidimensional"===this.propType?i[u]=B:i=B}return e.lastIndex=c,i}function lt(t){var e=t[0]*P,i=t[1]*P,s=t[2]*P,a=Math.cos(e/2),r=Math.cos(i/2),n=Math.cos(s/2),o=Math.sin(e/2),h=Math.sin(i/2),l=Math.sin(s/2);return[o*h*n+a*r*l,o*r*n+a*h*l,a*h*n-o*r*l,a*r*n-o*h*l]}function pt(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==nt&&(this._caching.lastFrame>=i&&t>=i||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var s=this.interpolateValue(t,this._caching);this.pv=s}return this._caching.lastFrame=t,this.pv}function ft(t){var e;if("unidimensional"===this.propType)e=t*this.mult,ot(this.v-e)>1e-5&&(this.v=e,this._mdf=!0);else for(var i=0,s=this.v.length;i<s;)e=t[i]*this.mult,ot(this.v[i]-e)>1e-5&&(this.v[i]=e,this._mdf=!0),i+=1}function dt(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t;this.lock=!0,this._mdf=this._isFirstFrame;var e=this.effectsSequence.length,i=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)i=this.effectsSequence[t](i);this.setVValue(i),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function mt(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function ct(t,e,i,s){this.propType="unidimensional",this.mult=i||1,this.data=e,this.v=i?e.k*i:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=s,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=dt,this.setVValue=ft,this.addEffect=mt}function ut(t,e,i,s){var a;this.propType="multidimensional",this.mult=i||1,this.data=e,this._mdf=!1,this.elem=t,this.container=s,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var r=e.k.length;for(this.v=h("float32",r),this.pv=h("float32",r),this.vel=h("float32",r),a=0;a<r;a+=1)this.v[a]=e.k[a]*this.mult,this.pv[a]=e.k[a];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=dt,this.setVValue=ft,this.addEffect=mt}function gt(t,e,i,s){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:nt,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=i||1,this.elem=t,this.container=s,this.comp=t.comp,this.v=nt,this.pv=nt,this._isFirstFrame=!0,this.getValue=dt,this.setVValue=ft,this.interpolateValue=ht,this.effectsSequence=[pt.bind(this)],this.addEffect=mt}function yt(t,e,i,s){var a;this.propType="multidimensional";var r,n,o,l,p=e.k.length;for(a=0;a<p-1;a+=1)e.k[a].to&&e.k[a].s&&e.k[a+1]&&e.k[a+1].s&&(r=e.k[a].s,n=e.k[a+1].s,o=e.k[a].to,l=e.k[a].ti,(2===r.length&&(r[0]!==n[0]||r[1]!==n[1])&&rt.pointOnLine2D(r[0],r[1],n[0],n[1],r[0]+o[0],r[1]+o[1])&&rt.pointOnLine2D(r[0],r[1],n[0],n[1],n[0]+l[0],n[1]+l[1])||3===r.length&&(r[0]!==n[0]||r[1]!==n[1]||r[2]!==n[2])&&rt.pointOnLine3D(r[0],r[1],r[2],n[0],n[1],n[2],r[0]+o[0],r[1]+o[1],r[2]+o[2])&&rt.pointOnLine3D(r[0],r[1],r[2],n[0],n[1],n[2],n[0]+l[0],n[1]+l[1],n[2]+l[2]))&&(e.k[a].to=null,e.k[a].ti=null),r[0]===n[0]&&r[1]===n[1]&&0===o[0]&&0===o[1]&&0===l[0]&&0===l[1]&&(2===r.length||r[2]===n[2]&&0===o[2]&&0===l[2])&&(e.k[a].to=null,e.k[a].ti=null));this.effectsSequence=[pt.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=i||1,this.elem=t,this.container=s,this.comp=t.comp,this.getValue=dt,this.setVValue=ft,this.interpolateValue=ht,this.frameId=-1;var f=e.k[0].s.length;for(this.v=h("float32",f),this.pv=h("float32",f),a=0;a<f;a+=1)this.v[a]=nt,this.pv[a]=nt;this._caching={lastFrame:nt,lastIndex:0,value:h("float32",f)},this.addEffect=mt}var vt={getProp:function(t,e,i,s,a){var r;if(e.sid&&(e=t.globalData.slotManager.getProp(e)),e.k.length)if("number"==typeof e.k[0])r=new ut(t,e,s,a);else switch(i){case 0:r=new gt(t,e,s,a);break;case 1:r=new yt(t,e,s,a)}else r=new ct(t,e,s,a);return r.effectsSequence.length&&a.addDynamicProperty(r),r}};function bt(){}bt.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){var t;this._mdf=!1;var e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var _t=it(8,(function(){return h("float32",2)}));function kt(){this.c=!1,this._length=0,this._maxLength=8,this.v=l(this._maxLength),this.o=l(this._maxLength),this.i=l(this._maxLength)}kt.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var i=0;i<e;)this.v[i]=_t.newElement(),this.o[i]=_t.newElement(),this.i[i]=_t.newElement(),i+=1},kt.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},kt.prototype.doubleArrayLength=function(){this.v=this.v.concat(l(this._maxLength)),this.i=this.i.concat(l(this._maxLength)),this.o=this.o.concat(l(this._maxLength)),this._maxLength*=2},kt.prototype.setXYAt=function(t,e,i,s,a){var r;switch(this._length=Math.max(this._length,s+1),this._length>=this._maxLength&&this.doubleArrayLength(),i){case"v":r=this.v;break;case"i":r=this.i;break;case"o":r=this.o;break;default:r=[]}(!r[s]||r[s]&&!a)&&(r[s]=_t.newElement()),r[s][0]=t,r[s][1]=e},kt.prototype.setTripleAt=function(t,e,i,s,a,r,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(i,s,"o",n,o),this.setXYAt(a,r,"i",n,o)},kt.prototype.reverse=function(){var t=new kt;t.setPathData(this.c,this._length);var e=this.v,i=this.o,s=this.i,a=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],s[0][0],s[0][1],i[0][0],i[0][1],0,!1),a=1);var r,n=this._length-1,o=this._length;for(r=a;r<o;r+=1)t.setTripleAt(e[n][0],e[n][1],s[n][0],s[n][1],i[n][0],i[n][1],r,!1),n-=1;return t},kt.prototype.length=function(){return this._length};var Pt,At=((Pt=it(4,(function(){return new kt}),(function(t){var e,i=t._length;for(e=0;e<i;e+=1)_t.release(t.v[e]),_t.release(t.i[e]),_t.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1}))).clone=function(t){var e,i=Pt.newElement(),s=void 0===t._length?t.v.length:t._length;for(i.setLength(s),i.c=t.c,e=0;e<s;e+=1)i.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return i},Pt);function St(){this._length=0,this._maxLength=4,this.shapes=l(this._maxLength)}St.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(l(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},St.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)At.release(this.shapes[t]);this._length=0};var xt,wt,Dt,Ct,Mt=(xt={newShapeCollection:function(){return wt?Ct[wt-=1]:new St},release:function(t){var e,i=t._length;for(e=0;e<i;e+=1)At.release(t.shapes[e]);t._length=0,wt===Dt&&(Ct=et.double(Ct),Dt*=2),Ct[wt]=t,wt+=1}},wt=0,Ct=l(Dt=4),xt),Tt=function(){var t=-999999;function e(t,e,i){var s,a,r,n,o,h,l,p,f,d=i.lastIndex,m=this.keyframes;if(t<m[0].t-this.offsetTime)s=m[0].s[0],r=!0,d=0;else if(t>=m[m.length-1].t-this.offsetTime)s=m[m.length-1].s?m[m.length-1].s[0]:m[m.length-2].e[0],r=!0;else{for(var c,u,g,y=d,v=m.length-1,b=!0;b&&(c=m[y],!((u=m[y+1]).t-this.offsetTime>t));)y<v-1?y+=1:b=!1;if(g=this.keyframesMetadata[y]||{},d=y,!(r=1===c.h)){if(t>=u.t-this.offsetTime)p=1;else if(t<c.t-this.offsetTime)p=0;else{var _;g.__fnct?_=g.__fnct:(_=tt.getBezierEasing(c.o.x,c.o.y,c.i.x,c.i.y).get,g.__fnct=_),p=_((t-(c.t-this.offsetTime))/(u.t-this.offsetTime-(c.t-this.offsetTime)))}a=u.s?u.s[0]:c.e[0]}s=c.s[0]}for(h=e._length,l=s.i[0].length,i.lastIndex=d,n=0;n<h;n+=1)for(o=0;o<l;o+=1)f=r?s.i[n][o]:s.i[n][o]+(a.i[n][o]-s.i[n][o])*p,e.i[n][o]=f,f=r?s.o[n][o]:s.o[n][o]+(a.o[n][o]-s.o[n][o])*p,e.o[n][o]=f,f=r?s.v[n][o]:s.v[n][o]+(a.v[n][o]-s.v[n][o])*p,e.v[n][o]=f}function i(){var e=this.comp.renderedFrame-this.offsetTime,i=this.keyframes[0].t-this.offsetTime,s=this.keyframes[this.keyframes.length-1].t-this.offsetTime,a=this._caching.lastFrame;return a!==t&&(a<i&&e<i||a>s&&e>s)||(this._caching.lastIndex=a<e?this._caching.lastIndex:0,this.interpolateShape(e,this.pv,this._caching)),this._caching.lastFrame=e,this.pv}function s(){this.paths=this.localShapeCollection}function a(t){(function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var i,s=t._length;for(i=0;i<s;i+=1)if(t.v[i][0]!==e.v[i][0]||t.v[i][1]!==e.v[i][1]||t.o[i][0]!==e.o[i][0]||t.o[i][1]!==e.o[i][1]||t.i[i][0]!==e.i[i][0]||t.i[i][1]!==e.i[i][1])return!1;return!0})(this.v,t)||(this.v=At.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function n(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t,e;this.lock=!0,this._mdf=!1,t=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k;var i=this.effectsSequence.length;for(e=0;e<i;e+=1)t=this.effectsSequence[e](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function o(t,e,i){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var a=3===i?e.pt.k:e.ks.k;this.v=At.clone(a),this.pv=At.clone(this.v),this.localShapeCollection=Mt.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=s,this.effectsSequence=[]}function h(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function l(e,a,r){this.propType="shape",this.comp=e.comp,this.elem=e,this.container=e,this.offsetTime=e.data.st,this.keyframes=3===r?a.pt.k:a.ks.k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;var n=this.keyframes[0].s[0].i.length;this.v=At.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,n),this.pv=At.clone(this.v),this.localShapeCollection=Mt.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=t,this.reset=s,this._caching={lastFrame:t,lastIndex:0},this.effectsSequence=[i.bind(this)]}o.prototype.interpolateShape=e,o.prototype.getValue=n,o.prototype.setVValue=a,o.prototype.addEffect=h,l.prototype.getValue=n,l.prototype.interpolateShape=e,l.prototype.setVValue=a,l.prototype.addEffect=h;var p=function(){var t=A;function e(t,e){this.v=At.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=Mt.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=vt.getProp(t,e.p,1,0,this),this.s=vt.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}return e.prototype={reset:s,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var e=this.p.v[0],i=this.p.v[1],s=this.s.v[0]/2,a=this.s.v[1]/2,r=3!==this.d,n=this.v;n.v[0][0]=e,n.v[0][1]=i-a,n.v[1][0]=r?e+s:e-s,n.v[1][1]=i,n.v[2][0]=e,n.v[2][1]=i+a,n.v[3][0]=r?e-s:e+s,n.v[3][1]=i,n.i[0][0]=r?e-s*t:e+s*t,n.i[0][1]=i-a,n.i[1][0]=r?e+s:e-s,n.i[1][1]=i-a*t,n.i[2][0]=r?e+s*t:e-s*t,n.i[2][1]=i+a,n.i[3][0]=r?e-s:e+s,n.i[3][1]=i+a*t,n.o[0][0]=r?e+s*t:e-s*t,n.o[0][1]=i-a,n.o[1][0]=r?e+s:e-s,n.o[1][1]=i+a*t,n.o[2][0]=r?e-s*t:e+s*t,n.o[2][1]=i+a,n.o[3][0]=r?e-s:e+s,n.o[3][1]=i-a*t}},r([bt],e),e}(),f=function(){function t(t,e){this.v=At.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=vt.getProp(t,e.ir,0,0,this),this.is=vt.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=vt.getProp(t,e.pt,0,0,this),this.p=vt.getProp(t,e.p,1,0,this),this.r=vt.getProp(t,e.r,0,P,this),this.or=vt.getProp(t,e.or,0,0,this),this.os=vt.getProp(t,e.os,0,.01,this),this.localShapeCollection=Mt.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}return t.prototype={reset:s,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,i,s,a=2*Math.floor(this.pt.v),r=2*Math.PI/a,n=!0,o=this.or.v,h=this.ir.v,l=this.os.v,p=this.is.v,f=2*Math.PI*o/(2*a),d=2*Math.PI*h/(2*a),m=-Math.PI/2;m+=this.r.v;var c=3===this.data.d?-1:1;for(this.v._length=0,t=0;t<a;t+=1){i=n?l:p,s=n?f:d;var u=(e=n?o:h)*Math.cos(m),g=e*Math.sin(m),y=0===u&&0===g?0:g/Math.sqrt(u*u+g*g),v=0===u&&0===g?0:-u/Math.sqrt(u*u+g*g);u+=+this.p.v[0],g+=+this.p.v[1],this.v.setTripleAt(u,g,u-y*s*i*c,g-v*s*i*c,u+y*s*i*c,g+v*s*i*c,t,!0),n=!n,m+=r*c}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),i=2*Math.PI/e,s=this.or.v,a=this.os.v,r=2*Math.PI*s/(4*e),n=.5*-Math.PI,o=3===this.data.d?-1:1;for(n+=this.r.v,this.v._length=0,t=0;t<e;t+=1){var h=s*Math.cos(n),l=s*Math.sin(n),p=0===h&&0===l?0:l/Math.sqrt(h*h+l*l),f=0===h&&0===l?0:-h/Math.sqrt(h*h+l*l);h+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(h,l,h-p*r*a*o,l-f*r*a*o,h+p*r*a*o,l+f*r*a*o,t,!0),n+=i*o}this.paths.length=0,this.paths[0]=this.v}},r([bt],t),t}(),d=function(){function t(t,e){this.v=At.newElement(),this.v.c=!0,this.localShapeCollection=Mt.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=vt.getProp(t,e.p,1,0,this),this.s=vt.getProp(t,e.s,1,0,this),this.r=vt.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}return t.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,s=this.s.v[1]/2,a=b(i,s,this.r.v),r=a*(1-A);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+i,e-s+a,t+i,e-s+a,t+i,e-s+r,0,!0),this.v.setTripleAt(t+i,e+s-a,t+i,e+s-r,t+i,e+s-a,1,!0),0!==a?(this.v.setTripleAt(t+i-a,e+s,t+i-a,e+s,t+i-r,e+s,2,!0),this.v.setTripleAt(t-i+a,e+s,t-i+r,e+s,t-i+a,e+s,3,!0),this.v.setTripleAt(t-i,e+s-a,t-i,e+s-a,t-i,e+s-r,4,!0),this.v.setTripleAt(t-i,e-s+a,t-i,e-s+r,t-i,e-s+a,5,!0),this.v.setTripleAt(t-i+a,e-s,t-i+a,e-s,t-i+r,e-s,6,!0),this.v.setTripleAt(t+i-a,e-s,t+i-r,e-s,t+i-a,e-s,7,!0)):(this.v.setTripleAt(t-i,e+s,t-i+r,e+s,t-i,e+s,2),this.v.setTripleAt(t-i,e-s,t-i,e-s+r,t-i,e-s,3))):(this.v.setTripleAt(t+i,e-s+a,t+i,e-s+r,t+i,e-s+a,0,!0),0!==a?(this.v.setTripleAt(t+i-a,e-s,t+i-a,e-s,t+i-r,e-s,1,!0),this.v.setTripleAt(t-i+a,e-s,t-i+r,e-s,t-i+a,e-s,2,!0),this.v.setTripleAt(t-i,e-s+a,t-i,e-s+a,t-i,e-s+r,3,!0),this.v.setTripleAt(t-i,e+s-a,t-i,e+s-r,t-i,e+s-a,4,!0),this.v.setTripleAt(t-i+a,e+s,t-i+a,e+s,t-i+r,e+s,5,!0),this.v.setTripleAt(t+i-a,e+s,t+i-r,e+s,t+i-a,e+s,6,!0),this.v.setTripleAt(t+i,e+s-a,t+i,e+s-a,t+i,e+s-r,7,!0)):(this.v.setTripleAt(t-i,e-s,t-i+r,e-s,t-i,e-s,1,!0),this.v.setTripleAt(t-i,e+s,t-i,e+s-r,t-i,e+s,2,!0),this.v.setTripleAt(t+i,e+s,t+i-r,e+s,t+i,e+s,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:s},r([bt],t),t}();var m={getShapeProp:function(t,e,i){var s;return 3===i||4===i?s=(3===i?e.pt:e.ks).k.length?new l(t,e,i):new o(t,e,i):5===i?s=new d(t,e):6===i?s=new p(t,e):7===i&&(s=new f(t,e)),s.k&&t.addDynamicProperty(s),s},getConstructorFunction:function(){return o},getKeyframedConstructorFunction:function(){return l}};return m}(),Ft=function(){var t=Math.cos,e=Math.sin,i=Math.tan,s=Math.round;function a(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function r(i){if(0===i)return this;var s=t(i),a=e(i);return this._t(s,-a,0,0,a,s,0,0,0,0,1,0,0,0,0,1)}function n(i){if(0===i)return this;var s=t(i),a=e(i);return this._t(1,0,0,0,0,s,-a,0,0,a,s,0,0,0,0,1)}function o(i){if(0===i)return this;var s=t(i),a=e(i);return this._t(s,0,a,0,0,1,0,0,-a,0,s,0,0,0,0,1)}function l(i){if(0===i)return this;var s=t(i),a=e(i);return this._t(s,-a,0,0,a,s,0,0,0,0,1,0,0,0,0,1)}function p(t,e){return this._t(1,e,t,1,0,0)}function f(t,e){return this.shear(i(t),i(e))}function d(s,a){var r=t(a),n=e(a);return this._t(r,n,0,0,-n,r,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,i(s),1,0,0,0,0,1,0,0,0,0,1)._t(r,-n,0,0,n,r,0,0,0,0,1,0,0,0,0,1)}function m(t,e,i){return i||0===i||(i=1),1===t&&1===e&&1===i?this:this._t(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1)}function c(t,e,i,s,a,r,n,o,h,l,p,f,d,m,c,u){return this.props[0]=t,this.props[1]=e,this.props[2]=i,this.props[3]=s,this.props[4]=a,this.props[5]=r,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=l,this.props[10]=p,this.props[11]=f,this.props[12]=d,this.props[13]=m,this.props[14]=c,this.props[15]=u,this}function u(t,e,i){return i=i||0,0!==t||0!==e||0!==i?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,i,1):this}function g(t,e,i,s,a,r,n,o,h,l,p,f,d,m,c,u){var g=this.props;if(1===t&&0===e&&0===i&&0===s&&0===a&&1===r&&0===n&&0===o&&0===h&&0===l&&1===p&&0===f)return g[12]=g[12]*t+g[15]*d,g[13]=g[13]*r+g[15]*m,g[14]=g[14]*p+g[15]*c,g[15]*=u,this._identityCalculated=!1,this;var y=g[0],v=g[1],b=g[2],_=g[3],k=g[4],P=g[5],A=g[6],S=g[7],x=g[8],w=g[9],D=g[10],C=g[11],M=g[12],T=g[13],F=g[14],E=g[15];return g[0]=y*t+v*a+b*h+_*d,g[1]=y*e+v*r+b*l+_*m,g[2]=y*i+v*n+b*p+_*c,g[3]=y*s+v*o+b*f+_*u,g[4]=k*t+P*a+A*h+S*d,g[5]=k*e+P*r+A*l+S*m,g[6]=k*i+P*n+A*p+S*c,g[7]=k*s+P*o+A*f+S*u,g[8]=x*t+w*a+D*h+C*d,g[9]=x*e+w*r+D*l+C*m,g[10]=x*i+w*n+D*p+C*c,g[11]=x*s+w*o+D*f+C*u,g[12]=M*t+T*a+F*h+E*d,g[13]=M*e+T*r+F*l+E*m,g[14]=M*i+T*n+F*p+E*c,g[15]=M*s+T*o+F*f+E*u,this._identityCalculated=!1,this}function y(t){var e=t.props;return this.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}function v(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function b(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function _(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function k(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function P(t,e,i){return{x:t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}}function A(t,e,i){return t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12]}function S(t,e,i){return t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13]}function x(t,e,i){return t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}function w(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,i=-this.props[1]/t,s=-this.props[4]/t,a=this.props[0]/t,r=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,n=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,o=new Ft;return o.props[0]=e,o.props[1]=i,o.props[4]=s,o.props[5]=a,o.props[12]=r,o.props[13]=n,o}function D(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function C(t){var e,i=t.length,s=[];for(e=0;e<i;e+=1)s[e]=D(t[e]);return s}function M(t,e,i){var s=h("float32",6);if(this.isIdentity())s[0]=t[0],s[1]=t[1],s[2]=e[0],s[3]=e[1],s[4]=i[0],s[5]=i[1];else{var a=this.props[0],r=this.props[1],n=this.props[4],o=this.props[5],l=this.props[12],p=this.props[13];s[0]=t[0]*a+t[1]*n+l,s[1]=t[0]*r+t[1]*o+p,s[2]=e[0]*a+e[1]*n+l,s[3]=e[0]*r+e[1]*o+p,s[4]=i[0]*a+i[1]*n+l,s[5]=i[0]*r+i[1]*o+p}return s}function T(t,e,i){return this.isIdentity()?[t,e,i]:[t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]]}function F(t,e){if(this.isIdentity())return t+","+e;var i=this.props;return Math.round(100*(t*i[0]+e*i[4]+i[12]))/100+","+Math.round(100*(t*i[1]+e*i[5]+i[13]))/100}function E(){for(var t=0,e=this.props,i="matrix3d(";t<16;)i+=s(1e4*e[t])/1e4,i+=15===t?")":",",t+=1;return i}function I(t){return t<1e-6&&t>0||t>-1e-6&&t<0?s(1e4*t)/1e4:t}function L(){var t=this.props;return"matrix("+I(t[0])+","+I(t[1])+","+I(t[4])+","+I(t[5])+","+I(t[12])+","+I(t[13])+")"}return function(){this.reset=a,this.rotate=r,this.rotateX=n,this.rotateY=o,this.rotateZ=l,this.skew=f,this.skewFromAxis=d,this.shear=p,this.scale=m,this.setTransform=c,this.translate=u,this.transform=g,this.multiply=y,this.applyToPoint=P,this.applyToX=A,this.applyToY=S,this.applyToZ=x,this.applyToPointArray=T,this.applyToTriplePoints=M,this.applyToPointStringified=F,this.toCSS=E,this.to2dCSS=L,this.clone=_,this.cloneFromProps=k,this.equals=b,this.inversePoints=C,this.inversePoint=D,this.getInverseMatrix=w,this._t=this.transform,this.isIdentity=v,this._identity=!0,this._identityCalculated=!1,this.props=h("float32",16),this.reset()}}();function Et(t){return Et="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Et(t)}var It={},Lt="__[STANDALONE]__";function Vt(){$.searchAnimations()}It.play=$.play,It.pause=$.pause,It.setLocationHref=function(e){t=e},It.togglePause=$.togglePause,It.setSpeed=$.setSpeed,It.setDirection=$.setDirection,It.stop=$.stop,It.searchAnimations=Vt,It.registerAnimation=$.registerAnimation,It.loadAnimation=function(t){return $.loadAnimation(t)},It.setSubframeRendering=function(t){!function(t){f=!!t}(t)},It.resize=$.resize,It.goToAndStop=$.goToAndStop,It.destroy=$.destroy,It.setQuality=function(t){if("string"==typeof t)switch(t){case"high":q(200);break;default:case"medium":q(50);break;case"low":q(10)}else!isNaN(t)&&t>1&&q(t);j()>=50?S(!1):S(!0)},It.inBrowser=function(){return"undefined"!=typeof navigator},It.installPlugin=function(t,e){"expressions"===t&&(d=e)},It.freeze=$.freeze,It.unfreeze=$.unfreeze,It.setVolume=$.setVolume,It.mute=$.mute,It.unmute=$.unmute,It.getRegisteredAnimations=$.getRegisteredAnimations,It.useWebWorker=function(t){e=!!t},It.setIDPrefix=function(t){c=t},It.__getFactory=function(t){switch(t){case"propertyFactory":return vt;case"shapePropertyFactory":return Tt;case"matrix":return Ft;default:return null}},It.version="5.13.0";var Rt="";if(Lt){var zt=document.getElementsByTagName("script"),Ot=zt[zt.length-1]||{src:""};Rt=Ot.src?Ot.src.replace(/^[^\?]+\??/,""):"",function(t){for(var e=Rt.split("&"),i=0;i<e.length;i+=1){var s=e[i].split("=");if(decodeURIComponent(s[0])==t)return decodeURIComponent(s[1])}return null}("renderer")}var Nt=setInterval((function(){"complete"===document.readyState&&(clearInterval(Nt),Vt())}),100);try{"object"===("undefined"==typeof exports?"undefined":Et(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=It)}catch(t){}var Bt=function(){var t={},e={};return t.registerModifier=function(t,i){e[t]||(e[t]=i)},t.getModifier=function(t,i,s){return new e[t](i,s)},t}();function qt(){}function jt(){}function Wt(){}qt.prototype.initModifierProperties=function(){},qt.prototype.addShapeToModifier=function(){},qt.prototype.addShape=function(t){if(!this.closed){t.sh.container.addDynamicProperty(t.sh);var e={shape:t.sh,data:t,localShapeCollection:Mt.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},qt.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=i,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},qt.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},r([bt],qt),r([qt],jt),jt.prototype.initModifierProperties=function(t,e){this.s=vt.getProp(t,e.s,0,.01,this),this.e=vt.getProp(t,e.e,0,.01,this),this.o=vt.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},jt.prototype.addShapeToModifier=function(t){t.pathsData=[]},jt.prototype.calculateShapeEdges=function(t,e,i,s,a){var r=[];e<=1?r.push({s:t,e:e}):t>=1?r.push({s:t-1,e:e-1}):(r.push({s:t,e:1}),r.push({s:0,e:e-1}));var n,o,h=[],l=r.length;for(n=0;n<l;n+=1){var p,f;if(!((o=r[n]).e*a<s||o.s*a>s+i))p=o.s*a<=s?0:(o.s*a-s)/i,f=o.e*a>=s+i?1:(o.e*a-s)/i,h.push([p,f])}return h.length||h.push([0,0]),h},jt.prototype.releasePathsData=function(t){var e,i=t.length;for(e=0;e<i;e+=1)at.release(t[e]);return t.length=0,t},jt.prototype.processShapes=function(t){var e,i,s,a;if(this._mdf||t){var r=this.o.v%360/360;if(r<0&&(r+=1),(e=this.s.v>1?1+r:this.s.v<0?0+r:this.s.v+r)>(i=this.e.v>1?1+r:this.e.v<0?0+r:this.e.v+r)){var n=e;e=i,i=n}e=1e-4*Math.round(1e4*e),i=1e-4*Math.round(1e4*i),this.sValue=e,this.eValue=i}else e=this.sValue,i=this.eValue;var o,h,l,p,f,d=this.shapes.length,m=0;if(i===e)for(a=0;a<d;a+=1)this.shapes[a].localShapeCollection.releaseShapes(),this.shapes[a].shape._mdf=!0,this.shapes[a].shape.paths=this.shapes[a].localShapeCollection,this._mdf&&(this.shapes[a].pathsData.length=0);else if(1===i&&0===e||0===i&&1===e){if(this._mdf)for(a=0;a<d;a+=1)this.shapes[a].pathsData.length=0,this.shapes[a].shape._mdf=!0}else{var c,u,g=[];for(a=0;a<d;a+=1)if((c=this.shapes[a]).shape._mdf||this._mdf||t||2===this.m){if(h=(s=c.shape.paths)._length,f=0,!c.shape._mdf&&c.pathsData.length)f=c.totalShapeLength;else{for(l=this.releasePathsData(c.pathsData),o=0;o<h;o+=1)p=rt.getSegmentsLength(s.shapes[o]),l.push(p),f+=p.totalLength;c.totalShapeLength=f,c.pathsData=l}m+=f,c.shape._mdf=!0}else c.shape.paths=c.localShapeCollection;var y,v=e,b=i,_=0;for(a=d-1;a>=0;a-=1)if((c=this.shapes[a]).shape._mdf){for((u=c.localShapeCollection).releaseShapes(),2===this.m&&d>1?(y=this.calculateShapeEdges(e,i,c.totalShapeLength,_,m),_+=c.totalShapeLength):y=[[v,b]],h=y.length,o=0;o<h;o+=1){v=y[o][0],b=y[o][1],g.length=0,b<=1?g.push({s:c.totalShapeLength*v,e:c.totalShapeLength*b}):v>=1?g.push({s:c.totalShapeLength*(v-1),e:c.totalShapeLength*(b-1)}):(g.push({s:c.totalShapeLength*v,e:c.totalShapeLength}),g.push({s:0,e:c.totalShapeLength*(b-1)}));var k=this.addShapes(c,g[0]);if(g[0].s!==g[0].e){if(g.length>1)if(c.shape.paths.shapes[c.shape.paths._length-1].c){var P=k.pop();this.addPaths(k,u),k=this.addShapes(c,g[1],P)}else this.addPaths(k,u),k=this.addShapes(c,g[1]);this.addPaths(k,u)}}c.shape.paths=u}}},jt.prototype.addPaths=function(t,e){var i,s=t.length;for(i=0;i<s;i+=1)e.addShape(t[i])},jt.prototype.addSegment=function(t,e,i,s,a,r,n){a.setXYAt(e[0],e[1],"o",r),a.setXYAt(i[0],i[1],"i",r+1),n&&a.setXYAt(t[0],t[1],"v",r),a.setXYAt(s[0],s[1],"v",r+1)},jt.prototype.addSegmentFromArray=function(t,e,i,s){e.setXYAt(t[1],t[5],"o",i),e.setXYAt(t[2],t[6],"i",i+1),s&&e.setXYAt(t[0],t[4],"v",i),e.setXYAt(t[3],t[7],"v",i+1)},jt.prototype.addShapes=function(t,e,i){var s,a,r,n,o,h,l,p,f=t.pathsData,d=t.shape.paths.shapes,m=t.shape.paths._length,c=0,u=[],g=!0;for(i?(o=i._length,p=i._length):(i=At.newElement(),o=0,p=0),u.push(i),s=0;s<m;s+=1){for(h=f[s].lengths,i.c=d[s].c,r=d[s].c?h.length:h.length+1,a=1;a<r;a+=1)if(c+(n=h[a-1]).addedLength<e.s)c+=n.addedLength,i.c=!1;else{if(c>e.e){i.c=!1;break}e.s<=c&&e.e>=c+n.addedLength?(this.addSegment(d[s].v[a-1],d[s].o[a-1],d[s].i[a],d[s].v[a],i,o,g),g=!1):(l=rt.getNewSegment(d[s].v[a-1],d[s].v[a],d[s].o[a-1],d[s].i[a],(e.s-c)/n.addedLength,(e.e-c)/n.addedLength,h[a-1]),this.addSegmentFromArray(l,i,o,g),g=!1,i.c=!1),c+=n.addedLength,o+=1}if(d[s].c&&h.length){if(n=h[a-1],c<=e.e){var y=h[a-1].addedLength;e.s<=c&&e.e>=c+y?(this.addSegment(d[s].v[a-1],d[s].o[a-1],d[s].i[0],d[s].v[0],i,o,g),g=!1):(l=rt.getNewSegment(d[s].v[a-1],d[s].v[0],d[s].o[a-1],d[s].i[0],(e.s-c)/y,(e.e-c)/y,h[a-1]),this.addSegmentFromArray(l,i,o,g),g=!1,i.c=!1)}else i.c=!1;c+=n.addedLength,o+=1}if(i._length&&(i.setXYAt(i.v[p][0],i.v[p][1],"i",p),i.setXYAt(i.v[i._length-1][0],i.v[i._length-1][1],"o",i._length-1)),c>e.e)break;s<m-1&&(i=At.newElement(),g=!0,u.push(i),o=0)}return u},r([qt],Wt),Wt.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=vt.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},Wt.prototype.processPath=function(t,e){var i=e/100,s=[0,0],a=t._length,r=0;for(r=0;r<a;r+=1)s[0]+=t.v[r][0],s[1]+=t.v[r][1];s[0]/=a,s[1]/=a;var n,o,h,l,p,f,d=At.newElement();for(d.c=t.c,r=0;r<a;r+=1)n=t.v[r][0]+(s[0]-t.v[r][0])*i,o=t.v[r][1]+(s[1]-t.v[r][1])*i,h=t.o[r][0]+(s[0]-t.o[r][0])*-i,l=t.o[r][1]+(s[1]-t.o[r][1])*-i,p=t.i[r][0]+(s[0]-t.i[r][0])*-i,f=t.i[r][1]+(s[1]-t.i[r][1])*-i,d.setTripleAt(n,o,h,l,p,f,r);return d},Wt.prototype.processShapes=function(t){var e,i,s,a,r,n,o=this.shapes.length,h=this.amount.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(r=this.shapes[i]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,s=0;s<a;s+=1)n.addShape(this.processPath(e[s],h));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var Xt=function(){var t=[0,0];function e(t,e,i){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Ft,this.pre=new Ft,this.appliedTransformations=0,this.initDynamicPropertyContainer(i||t),e.p&&e.p.s?(this.px=vt.getProp(t,e.p.x,0,0,this),this.py=vt.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=vt.getProp(t,e.p.z,0,0,this))):this.p=vt.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=vt.getProp(t,e.rx,0,P,this),this.ry=vt.getProp(t,e.ry,0,P,this),this.rz=vt.getProp(t,e.rz,0,P,this),e.or.k[0].ti){var s,a=e.or.k.length;for(s=0;s<a;s+=1)e.or.k[s].to=null,e.or.k[s].ti=null}this.or=vt.getProp(t,e.or,1,P,this),this.or.sh=!0}else this.r=vt.getProp(t,e.r||{k:0},0,P,this);e.sk&&(this.sk=vt.getProp(t,e.sk,0,P,this),this.sa=vt.getProp(t,e.sa,0,P,this)),this.a=vt.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=vt.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=vt.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return e.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(e){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||e){var i;if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var s,a;if(i=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime)this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(s=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/i,0),a=this.p.getValueAtTime(this.p.keyframes[0].t/i,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(s=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/i,0),a=this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/i,0)):(s=this.p.pv,a=this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/i,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){s=[],a=[];var r=this.px,n=this.py;r._caching.lastFrame+r.offsetTime<=r.keyframes[0].t?(s[0]=r.getValueAtTime((r.keyframes[0].t+.01)/i,0),s[1]=n.getValueAtTime((n.keyframes[0].t+.01)/i,0),a[0]=r.getValueAtTime(r.keyframes[0].t/i,0),a[1]=n.getValueAtTime(n.keyframes[0].t/i,0)):r._caching.lastFrame+r.offsetTime>=r.keyframes[r.keyframes.length-1].t?(s[0]=r.getValueAtTime(r.keyframes[r.keyframes.length-1].t/i,0),s[1]=n.getValueAtTime(n.keyframes[n.keyframes.length-1].t/i,0),a[0]=r.getValueAtTime((r.keyframes[r.keyframes.length-1].t-.01)/i,0),a[1]=n.getValueAtTime((n.keyframes[n.keyframes.length-1].t-.01)/i,0)):(s=[r.pv,n.pv],a[0]=r.getValueAtTime((r._caching.lastFrame+r.offsetTime-.01)/i,r.offsetTime),a[1]=n.getValueAtTime((n._caching.lastFrame+n.offsetTime-.01)/i,n.offsetTime))}else s=a=t;this.v.rotate(-Math.atan2(s[1]-a[1],s[0]-a[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},r([bt],e),e.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},e.prototype._addDynamicProperty=bt.prototype.addDynamicProperty,{getTransformProperty:function(t,i,s){return new e(t,i,s)}}}();function Ht(){}function Yt(){}function Gt(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function Kt(t){return Math.abs(t)<=1e-5}function Jt(t,e,i){return t*(1-i)+e*i}function Ut(t,e,i){return[Jt(t[0],e[0],i),Jt(t[1],e[1],i)]}function Zt(t,e,i,s){return[3*e-t-3*i+s,3*t-6*e+3*i,-3*t+3*e,t]}function Qt(t){return new $t(t,t,t,t,!1)}function $t(t,e,i,s,a){a&&he(t,e)&&(e=Ut(t,s,1/3)),a&&he(i,s)&&(i=Ut(t,s,2/3));var r=Zt(t[0],e[0],i[0],s[0]),n=Zt(t[1],e[1],i[1],s[1]);this.a=[r[0],n[0]],this.b=[r[1],n[1]],this.c=[r[2],n[2]],this.d=[r[3],n[3]],this.points=[t,e,i,s]}function te(t,e){var i=t.points[0][e],s=t.points[t.points.length-1][e];if(i>s){var a=s;s=i,i=a}for(var r=function(t,e,i){if(0===t)return[];var s=e*e-4*t*i;if(s<0)return[];var a=-e/(2*t);if(0===s)return[a];var r=Math.sqrt(s)/(2*t);return[a-r,a+r]}(3*t.a[e],2*t.b[e],t.c[e]),n=0;n<r.length;n+=1)if(r[n]>0&&r[n]<1){var o=t.point(r[n])[e];o<i?i=o:o>s&&(s=o)}return{min:i,max:s}}function ee(t,e,i){var s=t.boundingBox();return{cx:s.cx,cy:s.cy,width:s.width,height:s.height,bez:t,t:(e+i)/2,t1:e,t2:i}}function ie(t){var e=t.bez.split(.5);return[ee(e[0],t.t1,t.t),ee(e[1],t.t,t.t2)]}function se(t,e,i,s,a,r){var n,o;if(n=t,o=e,2*Math.abs(n.cx-o.cx)<n.width+o.width&&2*Math.abs(n.cy-o.cy)<n.height+o.height)if(i>=r||t.width<=s&&t.height<=s&&e.width<=s&&e.height<=s)a.push([t.t,e.t]);else{var h=ie(t),l=ie(e);se(h[0],l[0],i+1,s,a,r),se(h[0],l[1],i+1,s,a,r),se(h[1],l[0],i+1,s,a,r),se(h[1],l[1],i+1,s,a,r)}}function ae(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function re(t,e,i,s){var a=[t[0],t[1],1],r=[e[0],e[1],1],n=[i[0],i[1],1],o=[s[0],s[1],1],h=ae(ae(a,r),ae(n,o));return Kt(h[2])?null:[h[0]/h[2],h[1]/h[2]]}function ne(t,e,i){return[t[0]+Math.cos(e)*i,t[1]-Math.sin(e)*i]}function oe(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function he(t,e){return Gt(t[0],e[0])&&Gt(t[1],e[1])}function le(){}function pe(t,e,i,s,a,r,n){var o=i-Math.PI/2,h=i+Math.PI/2,l=e[0]+Math.cos(i)*s*a,p=e[1]-Math.sin(i)*s*a;t.setTripleAt(l,p,l+Math.cos(o)*r,p-Math.sin(o)*r,l+Math.cos(h)*n,p-Math.sin(h)*n,t.length())}function fe(t,e){var i,s,a,r,n=0===e?t.length()-1:e-1,o=(e+1)%t.length(),h=t.v[n],l=t.v[o],p=(i=h,a=[(s=l)[0]-i[0],s[1]-i[1]],r=.5*-Math.PI,[Math.cos(r)*a[0]-Math.sin(r)*a[1],Math.sin(r)*a[0]+Math.cos(r)*a[1]]);return Math.atan2(0,1)-Math.atan2(p[1],p[0])}function de(t,e,i,s,a,r,n){var o=fe(e,i),h=e.v[i%e._length],l=e.v[0===i?e._length-1:i-1],p=e.v[(i+1)%e._length],f=2===r?Math.sqrt(Math.pow(h[0]-l[0],2)+Math.pow(h[1]-l[1],2)):0,d=2===r?Math.sqrt(Math.pow(h[0]-p[0],2)+Math.pow(h[1]-p[1],2)):0;pe(t,e.v[i%e._length],o,n,s,d/(2*(a+1)),f/(2*(a+1)))}function me(t,e,i,s,a,r){for(var n=0;n<s;n+=1){var o=(n+1)/(s+1),h=2===a?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(o);pe(t,e.point(o),l,r,i,h/(2*(s+1)),h/(2*(s+1))),r=-r}return r}function ce(t,e,i){var s=Math.atan2(e[0]-t[0],e[1]-t[1]);return[ne(t,s,i),ne(e,s,i)]}function ue(t,e){var i,s,a,r,n,o,h;i=(h=ce(t.points[0],t.points[1],e))[0],s=h[1],a=(h=ce(t.points[1],t.points[2],e))[0],r=h[1],n=(h=ce(t.points[2],t.points[3],e))[0],o=h[1];var l=re(i,s,a,r);null===l&&(l=s);var p=re(n,o,a,r);return null===p&&(p=n),new $t(i,l,p,o)}function ge(t,e,i,s,a){var r=e.points[3],n=i.points[0];if(3===s)return r;if(he(r,n))return r;if(2===s){var o=-e.tangentAngle(1),h=-i.tangentAngle(0)+Math.PI,l=re(r,ne(r,o+Math.PI/2,100),n,ne(n,o+Math.PI/2,100)),p=l?oe(l,r):oe(r,n)/2,f=ne(r,o,2*p*A);return t.setXYAt(f[0],f[1],"o",t.length()-1),f=ne(n,h,2*p*A),t.setTripleAt(n[0],n[1],n[0],n[1],f[0],f[1],t.length()),n}var d=re(he(r,e.points[2])?e.points[0]:e.points[2],r,n,he(n,i.points[1])?i.points[3]:i.points[1]);return d&&oe(d,r)<a?(t.setTripleAt(d[0],d[1],d[0],d[1],d[0],d[1],t.length()),d):r}function ye(t,e){var i=t.intersections(e);return i.length&&Gt(i[0][0],1)&&i.shift(),i.length?i[0]:null}function ve(t,e){var i=t.slice(),s=e.slice(),a=ye(t[t.length-1],e[0]);return a&&(i[t.length-1]=t[t.length-1].split(a[0])[0],s[0]=e[0].split(a[1])[1]),t.length>1&&e.length>1&&(a=ye(t[0],e[e.length-1]))?[[t[0].split(a[0])[0]],[e[e.length-1].split(a[1])[1]]]:[i,s]}function be(t,e){var i,s,a,r,n=t.inflectionPoints();if(0===n.length)return[ue(t,e)];if(1===n.length||Gt(n[1],1))return i=(a=t.split(n[0]))[0],s=a[1],[ue(i,e),ue(s,e)];i=(a=t.split(n[0]))[0];var o=(n[1]-n[0])/(1-n[0]);return r=(a=a[1].split(o))[0],s=a[1],[ue(i,e),ue(r,e),ue(s,e)]}function _e(){}function ke(t){for(var e=t.fStyle?t.fStyle.split(" "):[],i="normal",s="normal",a=e.length,r=0;r<a;r+=1)switch(e[r].toLowerCase()){case"italic":s="italic";break;case"bold":i="700";break;case"black":i="900";break;case"medium":i="500";break;case"regular":case"normal":i="400";break;case"light":case"thin":i="200"}return{style:s,weight:t.fWeight||i}}r([qt],Ht),Ht.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=vt.getProp(t,e.c,0,null,this),this.o=vt.getProp(t,e.o,0,null,this),this.tr=Xt.getTransformProperty(t,e.tr,this),this.so=vt.getProp(t,e.tr.so,0,.01,this),this.eo=vt.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Ft,this.rMatrix=new Ft,this.sMatrix=new Ft,this.tMatrix=new Ft,this.matrix=new Ft},Ht.prototype.applyTransforms=function(t,e,i,s,a,r){var n=r?-1:1,o=s.s.v[0]+(1-s.s.v[0])*(1-a),h=s.s.v[1]+(1-s.s.v[1])*(1-a);t.translate(s.p.v[0]*n*a,s.p.v[1]*n*a,s.p.v[2]),e.translate(-s.a.v[0],-s.a.v[1],s.a.v[2]),e.rotate(-s.r.v*n*a),e.translate(s.a.v[0],s.a.v[1],s.a.v[2]),i.translate(-s.a.v[0],-s.a.v[1],s.a.v[2]),i.scale(r?1/o:o,r?1/h:h),i.translate(s.a.v[0],s.a.v[1],s.a.v[2])},Ht.prototype.init=function(t,e,i,s){for(this.elem=t,this.arr=e,this.pos=i,this.elemsData=s,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[i]);i>0;)i-=1,this._elements.unshift(e[i]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},Ht.prototype.resetElements=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},Ht.prototype.cloneElements=function(t){var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},Ht.prototype.changeGroupRender=function(t,e){var i,s=t.length;for(i=0;i<s;i+=1)t[i]._render=e,"gr"===t[i].ty&&this.changeGroupRender(t[i].it,e)},Ht.prototype.processShapes=function(t){var e,i,s,a,r,n=!1;if(this._mdf||t){var o,h=Math.ceil(this.c.v);if(this._groups.length<h){for(;this._groups.length<h;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(r=0,s=0;s<=this._groups.length-1;s+=1){if(o=r<h,this._groups[s]._render=o,this.changeGroupRender(this._groups[s].it,o),!o){var p=this.elemsData[s].it,f=p[p.length-1];0!==f.transform.op.v?(f.transform.op._mdf=!0,f.transform.op.v=0):f.transform.op._mdf=!1}r+=1}this._currentCopies=h;var d=this.o.v,m=d%1,c=d>0?Math.floor(d):Math.ceil(d),u=this.pMatrix.props,g=this.rMatrix.props,y=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var v,b,_=0;if(d>0){for(;_<c;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),_+=1;m&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,m,!1),_+=m)}else if(d<0){for(;_>c;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),_-=1;m&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-m,!0),_-=m)}for(s=1===this.data.m?0:this._currentCopies-1,a=1===this.data.m?1:-1,r=this._currentCopies;r;){if(b=(i=(e=this.elemsData[s].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(s/(this._currentCopies-1)),0!==_){for((0!==s&&1===a||s!==this._currentCopies-1&&-1===a)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]),v=0;v<b;v+=1)i[v]=this.matrix.props[v];this.matrix.reset()}else for(this.matrix.reset(),v=0;v<b;v+=1)i[v]=this.matrix.props[v];_+=1,r-=1,s+=a}}else for(r=this._currentCopies,s=0,a=1;r;)i=(e=this.elemsData[s].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,r-=1,s+=a;return n},Ht.prototype.addShape=function(){},r([qt],Yt),Yt.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=vt.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},Yt.prototype.processPath=function(t,e){var i,s=At.newElement();s.c=t.c;var a,r,n,o,h,l,p,f,d,m,c,u,g=t._length,y=0;for(i=0;i<g;i+=1)a=t.v[i],n=t.o[i],r=t.i[i],a[0]===n[0]&&a[1]===n[1]&&a[0]===r[0]&&a[1]===r[1]?0!==i&&i!==g-1||t.c?(o=0===i?t.v[g-1]:t.v[i-1],l=(h=Math.sqrt(Math.pow(a[0]-o[0],2)+Math.pow(a[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=c=a[0]+(o[0]-a[0])*l,f=u=a[1]-(a[1]-o[1])*l,d=p-(p-a[0])*A,m=f-(f-a[1])*A,s.setTripleAt(p,f,d,m,c,u,y),y+=1,o=i===g-1?t.v[0]:t.v[i+1],l=(h=Math.sqrt(Math.pow(a[0]-o[0],2)+Math.pow(a[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=d=a[0]+(o[0]-a[0])*l,f=m=a[1]+(o[1]-a[1])*l,c=p-(p-a[0])*A,u=f-(f-a[1])*A,s.setTripleAt(p,f,d,m,c,u,y),y+=1):(s.setTripleAt(a[0],a[1],n[0],n[1],r[0],r[1],y),y+=1):(s.setTripleAt(t.v[i][0],t.v[i][1],t.o[i][0],t.o[i][1],t.i[i][0],t.i[i][1],y),y+=1);return s},Yt.prototype.processShapes=function(t){var e,i,s,a,r,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(r=this.shapes[i]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,s=0;s<a;s+=1)n.addShape(this.processPath(e[s],h));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},$t.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},$t.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},$t.prototype.tangentAngle=function(t){var e=this.derivative(t);return Math.atan2(e[1],e[0])},$t.prototype.normalAngle=function(t){var e=this.derivative(t);return Math.atan2(e[0],e[1])},$t.prototype.inflectionPoints=function(){var t=this.a[1]*this.b[0]-this.a[0]*this.b[1];if(Kt(t))return[];var e=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/t,i=e*e-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/t;if(i<0)return[];var s=Math.sqrt(i);return Kt(s)?s>0&&s<1?[e]:[]:[e-s,e+s].filter((function(t){return t>0&&t<1}))},$t.prototype.split=function(t){if(t<=0)return[Qt(this.points[0]),this];if(t>=1)return[this,Qt(this.points[this.points.length-1])];var e=Ut(this.points[0],this.points[1],t),i=Ut(this.points[1],this.points[2],t),s=Ut(this.points[2],this.points[3],t),a=Ut(e,i,t),r=Ut(i,s,t),n=Ut(a,r,t);return[new $t(this.points[0],e,a,n,!0),new $t(n,r,s,this.points[3],!0)]},$t.prototype.bounds=function(){return{x:te(this,0),y:te(this,1)}},$t.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},$t.prototype.intersections=function(t,e,i){void 0===e&&(e=2),void 0===i&&(i=7);var s=[];return se(ee(this,0,1),ee(t,0,1),0,e,s,i),s},$t.shapeSegment=function(t,e){var i=(e+1)%t.length();return new $t(t.v[e],t.o[e],t.i[i],t.v[i],!0)},$t.shapeSegmentInverted=function(t,e){var i=(e+1)%t.length();return new $t(t.v[i],t.i[i],t.o[e],t.v[e],!0)},r([qt],le),le.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=vt.getProp(t,e.s,0,null,this),this.frequency=vt.getProp(t,e.r,0,null,this),this.pointsType=vt.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},le.prototype.processPath=function(t,e,i,s){var a=t._length,r=At.newElement();if(r.c=t.c,t.c||(a-=1),0===a)return r;var n=-1,o=$t.shapeSegment(t,0);de(r,t,0,e,i,s,n);for(var h=0;h<a;h+=1)n=me(r,o,e,i,s,-n),o=h!==a-1||t.c?$t.shapeSegment(t,(h+1)%a):null,de(r,t,h+1,e,i,s,n);return r},le.prototype.processShapes=function(t){var e,i,s,a,r,n,o=this.shapes.length,h=this.amplitude.v,l=Math.max(0,Math.round(this.frequency.v)),p=this.pointsType.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(r=this.shapes[i]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,s=0;s<a;s+=1)n.addShape(this.processPath(e[s],h,l,p));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},r([qt],_e),_e.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=vt.getProp(t,e.a,0,null,this),this.miterLimit=vt.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},_e.prototype.processPath=function(t,e,i,s){var a=At.newElement();a.c=t.c;var r,n,o,h=t.length();t.c||(h-=1);var l=[];for(r=0;r<h;r+=1)o=$t.shapeSegment(t,r),l.push(be(o,e));if(!t.c)for(r=h-1;r>=0;r-=1)o=$t.shapeSegmentInverted(t,r),l.push(be(o,e));l=function(t){for(var e,i=1;i<t.length;i+=1)e=ve(t[i-1],t[i]),t[i-1]=e[0],t[i]=e[1];return t.length>1&&(e=ve(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}(l);var p=null,f=null;for(r=0;r<l.length;r+=1){var d=l[r];for(f&&(p=ge(a,f,d[0],i,s)),f=d[d.length-1],n=0;n<d.length;n+=1)o=d[n],p&&he(o.points[0],p)?a.setXYAt(o.points[1][0],o.points[1][1],"o",a.length()-1):a.setTripleAt(o.points[0][0],o.points[0][1],o.points[1][0],o.points[1][1],o.points[0][0],o.points[0][1],a.length()),a.setTripleAt(o.points[3][0],o.points[3][1],o.points[3][0],o.points[3][1],o.points[2][0],o.points[2][1],a.length()),p=o.points[3]}return l.length&&ge(a,f,l[0][0],i,s),a},_e.prototype.processShapes=function(t){var e,i,s,a,r,n,o=this.shapes.length,h=this.amount.v,l=this.miterLimit.v,p=this.lineJoin;if(0!==h)for(i=0;i<o;i+=1){if(n=(r=this.shapes[i]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,s=0;s<a;s+=1)n.addShape(this.processPath(e[s],h,p,l));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var Pe=function(){var t={w:0,size:0,shapes:[],data:{shapes:[]}},e=[];e=e.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);var i=127988,s=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function r(t,e){var i=a("span");i.setAttribute("aria-hidden",!0),i.style.fontFamily=e;var s=a("span");s.innerText="giItT1WQy@!-/#",i.style.position="absolute",i.style.left="-10000px",i.style.top="-10000px",i.style.fontSize="300px",i.style.fontVariant="normal",i.style.fontStyle="normal",i.style.fontWeight="normal",i.style.letterSpacing="0",i.appendChild(s),document.body.appendChild(i);var r=s.offsetWidth;return s.style.fontFamily=function(t){var e,i=t.split(","),s=i.length,a=[];for(e=0;e<s;e+=1)"sans-serif"!==i[e]&&"monospace"!==i[e]&&a.push(i[e]);return a.join(",")}(t)+", "+e,{node:s,w:r,parent:i}}function n(t,e){var i,s=document.body&&e?"svg":"canvas",a=ke(t);if("svg"===s){var r=W("text");r.style.fontSize="100px",r.setAttribute("font-family",t.fFamily),r.setAttribute("font-style",a.style),r.setAttribute("font-weight",a.weight),r.textContent="1",t.fClass?(r.style.fontFamily="inherit",r.setAttribute("class",t.fClass)):r.style.fontFamily=t.fFamily,e.appendChild(r),i=r}else{var n=new OffscreenCanvas(500,500).getContext("2d");n.font=a.style+" "+a.weight+" 100px "+t.fFamily,i=n}return{measureText:function(t){return"svg"===s?(i.textContent=t,i.getComputedTextLength()):i.measureText(t).width}}}function o(t){var e=0,i=t.charCodeAt(0);if(i>=55296&&i<=56319){var s=t.charCodeAt(1);s>=56320&&s<=57343&&(e=1024*(i-55296)+s-56320+65536)}return e}function h(t){var e=o(t);return e>=127462&&e<=127487}var l=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)};l.isModifier=function(t,e){var i=t.toString(16)+e.toString(16);return-1!==s.indexOf(i)},l.isZeroWidthJoiner=function(t){return 8205===t},l.isFlagEmoji=function(t){return h(t.substr(0,2))&&h(t.substr(2,2))},l.isRegionalCode=h,l.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},l.isRegionalFlag=function(t,e){var s=o(t.substr(e,2));if(s!==i)return!1;var a=0;for(e+=2;a<5;){if((s=o(t.substr(e,2)))<917601||s>917626)return!1;a+=1,e+=2}return 917631===o(t.substr(e,2))},l.isVariationSelector=function(t){return 65039===t},l.BLACK_FLAG_CODE_POINT=i;var p={addChars:function(t){if(t){var e;this.chars||(this.chars=[]);var i,s,a=t.length,r=this.chars.length;for(e=0;e<a;e+=1){for(i=0,s=!1;i<r;)this.chars[i].style===t[e].style&&this.chars[i].fFamily===t[e].fFamily&&this.chars[i].ch===t[e].ch&&(s=!0),i+=1;s||(this.chars.push(t[e]),r+=1)}}},addFonts:function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);if(!document.body)return this.isLoaded=!0,t.list.forEach((function(t){t.helper=n(t),t.cache={}})),void(this.fonts=t.list);var i,s=t.list,o=s.length,h=o;for(i=0;i<o;i+=1){var l,p,f=!0;if(s[i].loaded=!1,s[i].monoCase=r(s[i].fFamily,"monospace"),s[i].sansCase=r(s[i].fFamily,"sans-serif"),s[i].fPath){if("p"===s[i].fOrigin||3===s[i].origin){if((l=document.querySelectorAll('style[f-forigin="p"][f-family="'+s[i].fFamily+'"], style[f-origin="3"][f-family="'+s[i].fFamily+'"]')).length>0&&(f=!1),f){var d=a("style");d.setAttribute("f-forigin",s[i].fOrigin),d.setAttribute("f-origin",s[i].origin),d.setAttribute("f-family",s[i].fFamily),d.type="text/css",d.innerText="@font-face {font-family: "+s[i].fFamily+"; font-style: normal; src: url('"+s[i].fPath+"');}",e.appendChild(d)}}else if("g"===s[i].fOrigin||1===s[i].origin){for(l=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),p=0;p<l.length;p+=1)-1!==l[p].href.indexOf(s[i].fPath)&&(f=!1);if(f){var m=a("link");m.setAttribute("f-forigin",s[i].fOrigin),m.setAttribute("f-origin",s[i].origin),m.type="text/css",m.rel="stylesheet",m.href=s[i].fPath,document.body.appendChild(m)}}else if("t"===s[i].fOrigin||2===s[i].origin){for(l=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),p=0;p<l.length;p+=1)s[i].fPath===l[p].src&&(f=!1);if(f){var c=a("link");c.setAttribute("f-forigin",s[i].fOrigin),c.setAttribute("f-origin",s[i].origin),c.setAttribute("rel","stylesheet"),c.setAttribute("href",s[i].fPath),e.appendChild(c)}}}else s[i].loaded=!0,h-=1;s[i].helper=n(s[i],e),s[i].cache={},this.fonts.push(s[i])}0===h?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},getCharData:function(e,i,s){for(var a=0,r=this.chars.length;a<r;){if(this.chars[a].ch===e&&this.chars[a].style===i&&this.chars[a].fFamily===s)return this.chars[a];a+=1}return("string"==typeof e&&13!==e.charCodeAt(0)||!e)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",e,i,s)),t},getFontByName:function(t){for(var e=0,i=this.fonts.length;e<i;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,i){var s=this.getFontByName(e),a=t;if(!s.cache[a]){var r=s.helper;if(" "===t){var n=r.measureText("|"+t+"|"),o=r.measureText("||");s.cache[a]=(n-o)/100}else s.cache[a]=r.measureText(t)/100}return s.cache[a]*i},checkLoadedFonts:function(){var t,e,i,s=this.fonts.length,a=s;for(t=0;t<s;t+=1)this.fonts[t].loaded?a-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,i=this.fonts[t].monoCase.w,e.offsetWidth!==i?(a-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,i=this.fonts[t].sansCase.w,e.offsetWidth!==i&&(a-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==a&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}};return l.prototype=p,l}();function Ae(t){this.animationData=t}function Se(){}Ae.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},Se.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var xe,we=(xe={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return xe[t]||""});function De(t,e,i){this.p=vt.getProp(e,t.v,0,0,i)}function Ce(t,e,i){this.p=vt.getProp(e,t.v,0,0,i)}function Me(t,e,i){this.p=vt.getProp(e,t.v,1,0,i)}function Te(t,e,i){this.p=vt.getProp(e,t.v,1,0,i)}function Fe(t,e,i){this.p=vt.getProp(e,t.v,0,0,i)}function Ee(t,e,i){this.p=vt.getProp(e,t.v,0,0,i)}function Ie(t,e,i){this.p=vt.getProp(e,t.v,0,0,i)}function Le(){this.p={}}function Ve(t,e){var i,s=t.ef||[];this.effectElements=[];var a,r=s.length;for(i=0;i<r;i+=1)a=new Re(s[i],e),this.effectElements.push(a)}function Re(t,e){this.init(t,e)}function ze(){}function Oe(){}function Ne(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,i)}function Be(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,i),this._isPlaying=!1,this._canPlay=!1;var s=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(s),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?vt.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=vt.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function qe(){}r([bt],Re),Re.prototype.getValue=Re.prototype.iterateDynamicProperties,Re.prototype.init=function(t,e){var i;this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var s,a=this.data.ef.length,r=this.data.ef;for(i=0;i<a;i+=1){switch(s=null,r[i].ty){case 0:s=new De(r[i],e,this);break;case 1:s=new Ce(r[i],e,this);break;case 2:s=new Me(r[i],e,this);break;case 3:s=new Te(r[i],e,this);break;case 4:case 7:s=new Ie(r[i],e,this);break;case 10:s=new Fe(r[i],e,this);break;case 11:s=new Ee(r[i],e,this);break;case 5:s=new Ve(r[i],e,this);break;default:s=new Le(r[i],e,this)}s&&this.effectElements.push(s)}},ze.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t=B();if(t){var e=t("layer"),i=t("effects"),s=t("shape"),a=t("text"),r=t("comp");this.layerInterface=e(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var n=i.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(n),0===this.data.ty||this.data.xt?this.compInterface=r(this):4===this.data.ty?(this.layerInterface.shapeInterface=s(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=a(this),this.layerInterface.text=this.layerInterface.textInterface)}},setBlendMode:function(){var t=we(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,i){this.globalData=e,this.comp=i,this.data=t,this.layerId=I(),this.data.sr||(this.data.sr=1),this.effectsManager=new Ve(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},Oe.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var i,s=this.dynamicProperties.length;for(i=0;i<s;i+=1)(e||this._isParent&&"transform"===this.dynamicProperties[i].propType)&&(this.dynamicProperties[i].getValue(),this.dynamicProperties[i]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},Ne.prototype.prepareFrame=function(){},r([Se,ze,Oe],Ne),Ne.prototype.getBaseElement=function(){return null},Ne.prototype.renderFrame=function(){},Ne.prototype.destroy=function(){},Ne.prototype.initExpressions=function(){var t=B();if(t){var e=t("footage");this.layerInterface=e(this)}},Ne.prototype.getFootageData=function(){return this.footageData},Be.prototype.prepareFrame=function(t){if(this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder)this._currentTime=t/this.data.sr;else{var e=this.tm.v;this._currentTime=e}this._volume=this.lv.v[0];var i=this._volume*this._volumeMultiplier;this._previousVolume!==i&&(this._previousVolume=i,this.audio.volume(i))},r([Se,ze,Oe],Be),Be.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek())>.1)&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},Be.prototype.show=function(){},Be.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},Be.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},Be.prototype.resume=function(){this._canPlay=!0},Be.prototype.setRate=function(t){this.audio.rate(t)},Be.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},Be.prototype.getBaseElement=function(){return null},Be.prototype.destroy=function(){},Be.prototype.sourceRectAtTime=function(){},Be.prototype.initExpressions=function(){},qe.prototype.checkLayers=function(t){var e,i,s=this.layers.length;for(this.completeLayers=!0,e=s-1;e>=0;e-=1)this.elements[e]||(i=this.layers[e]).ip-i.st<=t-this.layers[e].st&&i.op-i.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},qe.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:default:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t)}},qe.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},qe.prototype.createAudio=function(t){return new Be(t,this.globalData,this)},qe.prototype.createFootage=function(t){return new Ne(t,this.globalData,this)},qe.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},qe.prototype.includeLayers=function(t){var e;this.completeLayers=!1;var i,s=t.length,a=this.layers.length;for(e=0;e<s;e+=1)for(i=0;i<a;){if(this.layers[i].id===t[e].id){this.layers[i]=t[e];break}i+=1}},qe.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},qe.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},qe.prototype.buildElementParenting=function(t,e,i){for(var s=this.elements,a=this.layers,r=0,n=a.length;r<n;)a[r].ind==e&&(s[r]&&!0!==s[r]?(i.push(s[r]),s[r].setAsParent(),void 0!==a[r].parent?this.buildElementParenting(t,a[r].parent,i):t.setHierarchy(i)):(this.buildItem(r),this.addPendingElement(t))),r+=1},qe.prototype.addPendingElement=function(t){this.pendingElements.push(t)},qe.prototype.searchExtraCompositions=function(t){var e,i=t.length;for(e=0;e<i;e+=1)if(t[e].xt){var s=this.createComp(t[e]);s.initExpressions(),this.globalData.projectInterface.registerComposition(s)}},qe.prototype.getElementById=function(t){var e,i=this.elements.length;for(e=0;e<i;e+=1)if(this.elements[e].data.ind===t)return this.elements[e];return null},qe.prototype.getElementByPath=function(t){var e,i=t.shift();if("number"==typeof i)e=this.elements[i];else{var s,a=this.elements.length;for(s=0;s<a;s+=1)if(this.elements[s].data.nm===i){e=this.elements[s];break}}return 0===t.length?e:e.getElementByPath(t)},qe.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new Pe,this.globalData.slotManager=function(t){return new Ae(t)}(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var je="transformEFfect";function We(){}function Xe(t,e,i){this.data=t,this.element=e,this.globalData=i,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var a,r,n=this.globalData.defs,o=this.masksProperties?this.masksProperties.length:0;this.viewData=l(o),this.solidPath="";var h,p,f,d,m,c,u=this.masksProperties,g=0,y=[],v=I(),b="clipPath",_="clip-path";for(a=0;a<o;a+=1)if(("a"!==u[a].mode&&"n"!==u[a].mode||u[a].inv||100!==u[a].o.k||u[a].o.x)&&(b="mask",_="mask"),"s"!==u[a].mode&&"i"!==u[a].mode||0!==g?f=null:((f=W("rect")).setAttribute("fill","#ffffff"),f.setAttribute("width",this.element.comp.data.w||0),f.setAttribute("height",this.element.comp.data.h||0),y.push(f)),r=W("path"),"n"===u[a].mode)this.viewData[a]={op:vt.getProp(this.element,u[a].o,0,.01,this.element),prop:Tt.getShapeProp(this.element,u[a],3),elem:r,lastPath:""},n.appendChild(r);else{var k;if(g+=1,r.setAttribute("fill","s"===u[a].mode?"#000000":"#ffffff"),r.setAttribute("clip-rule","nonzero"),0!==u[a].x.k?(b="mask",_="mask",c=vt.getProp(this.element,u[a].x,0,null,this.element),k=I(),(d=W("filter")).setAttribute("id",k),(m=W("feMorphology")).setAttribute("operator","erode"),m.setAttribute("in","SourceGraphic"),m.setAttribute("radius","0"),d.appendChild(m),n.appendChild(d),r.setAttribute("stroke","s"===u[a].mode?"#000000":"#ffffff")):(m=null,c=null),this.storedData[a]={elem:r,x:c,expan:m,lastPath:"",lastOperator:"",filterId:k,lastRadius:0},"i"===u[a].mode){p=y.length;var P=W("g");for(h=0;h<p;h+=1)P.appendChild(y[h]);var A=W("mask");A.setAttribute("mask-type","alpha"),A.setAttribute("id",v+"_"+g),A.appendChild(r),n.appendChild(A),P.setAttribute("mask","url("+s()+"#"+v+"_"+g+")"),y.length=0,y.push(P)}else y.push(r);u[a].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[a]={elem:r,lastPath:"",op:vt.getProp(this.element,u[a].o,0,.01,this.element),prop:Tt.getShapeProp(this.element,u[a],3),invRect:f},this.viewData[a].prop.k||this.drawPath(u[a],this.viewData[a].prop.v,this.viewData[a])}for(this.maskElement=W(b),o=y.length,a=0;a<o;a+=1)this.maskElement.appendChild(y[a]);g>0&&(this.maskElement.setAttribute("id",v),this.element.maskedElement.setAttribute(_,"url("+s()+"#"+v+")"),n.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}We.prototype={initTransform:function(){var t=new Ft;this.finalTransform={mProp:this.data.ks?Xt.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,i=0,s=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;i<s;){if(this.hierarchy[i].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}i+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),i=0;i<s;i+=1)e.multiply(this.hierarchy[i].finalTransform.mProp.v)}this.localTransforms&&!this.finalTransform._matMdf||(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var i=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(i),t=1;t<e;t+=1){var s=this.localTransforms[t].matrix;i.multiply(s)}i.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){var a=this.finalTransform.localOpacity;for(t=0;t<e;t+=1)a*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=a}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(je);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new Ft;var e=0,i=t.length;for(e=0;e<i;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var i,s=!0,a=this.comp;s;)a.finalTransform?(a.data.hasMask&&e.splice(0,0,a.finalTransform),a=a.comp):s=!1;var r,n=e.length;for(i=0;i<n;i+=1)r=e[i].mat.applyToPointArray(0,0,0),t=[t[0]-r[0],t[1]-r[1],0];return t},mHelper:new Ft},Xe.prototype.getMaskProperty=function(t){return this.viewData[t].prop},Xe.prototype.renderFrame=function(t){var e,i=this.element.finalTransform.mat,a=this.masksProperties.length;for(e=0;e<a;e+=1)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[e].invRect.setAttribute("transform",i.getInverseMatrix().to2dCSS()),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var r=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+s()+"#"+this.storedData[e].filterId+")")),r.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},Xe.prototype.getMaskelement=function(){return this.maskElement},Xe.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},Xe.prototype.drawPath=function(t,e,i){var s,a,r=" M"+e.v[0][0]+","+e.v[0][1];for(a=e._length,s=1;s<a;s+=1)r+=" C"+e.o[s-1][0]+","+e.o[s-1][1]+" "+e.i[s][0]+","+e.i[s][1]+" "+e.v[s][0]+","+e.v[s][1];if(e.c&&a>1&&(r+=" C"+e.o[s-1][0]+","+e.o[s-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),i.lastPath!==r){var n="";i.elem&&(e.c&&(n=t.inv?this.solidPath+r:r),i.elem.setAttribute("d",n)),i.lastPath=r}},Xe.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var He=function(){var t={};return t.createFilter=function(t,e){var i=W("filter");i.setAttribute("id",t),!0!==e&&(i.setAttribute("filterUnits","objectBoundingBox"),i.setAttribute("x","0%"),i.setAttribute("y","0%"),i.setAttribute("width","100%"),i.setAttribute("height","100%"));return i},t.createAlphaToLuminanceFilter=function(){var t=W("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},t}(),Ye=function(){var t={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),/firefox/i.test(navigator.userAgent)&&(t.svgLumaHidden=!1),t}(),Ge={},Ke="filter_result_";function Je(t){var e,i,a="SourceGraphic",r=t.data.ef?t.data.ef.length:0,n=I(),o=He.createFilter(n,!0),h=0;for(this.filters=[],e=0;e<r;e+=1){i=null;var l=t.data.ef[e].ty;if(Ge[l])i=new(0,Ge[l].effect)(o,t.effectsManager.effectElements[e],t,Ke+h,a),a=Ke+h,Ge[l].countsAsEffect&&(h+=1);i&&this.filters.push(i)}h&&(t.globalData.defs.appendChild(o),t.layerElement.setAttribute("filter","url("+s()+"#"+n+")")),this.filters.length&&t.addRenderableComponent(this)}function Ue(){}function Ze(){}function Qe(){}function $e(t,e,i){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,i),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ti(t,e){this.elem=t,this.pos=e}function ei(){}Je.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},Je.prototype.getEffects=function(t){var e,i=this.filters.length,s=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&s.push(this.filters[e]);return s},Ue.prototype={initRendererElement:function(){this.layerElement=W("g")},createContainerElements:function(){this.matteElement=W("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t=null;if(this.data.td){this.matteMasks={};var e=W("g");e.setAttribute("id",this.layerId),e.appendChild(this.layerElement),t=e,this.globalData.defs.appendChild(e)}else this.data.tt?(this.matteElement.appendChild(this.layerElement),t=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var i=W("clipPath"),a=W("path");a.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var r=I();if(i.setAttribute("id",r),i.appendChild(a),this.globalData.defs.appendChild(i),this.checkMasks()){var n=W("g");n.setAttribute("clip-path","url("+s()+"#"+r+")"),n.appendChild(this.layerElement),this.transformedElement=n,t?t.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+s()+"#"+r+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new Xe(this.data,this,this.globalData),this.renderableEffectsManager=new Je(this),this.searchEffectTransforms()},getMatte:function(t){if(this.matteMasks||(this.matteMasks={}),!this.matteMasks[t]){var e,i,a,r,n=this.layerId+"_"+t;if(1===t||3===t){var o=W("mask");o.setAttribute("id",n),o.setAttribute("mask-type",3===t?"luminance":"alpha"),(a=W("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),o.appendChild(a),this.globalData.defs.appendChild(o),Ye.maskType||1!==t||(o.setAttribute("mask-type","luminance"),e=I(),i=He.createFilter(e),this.globalData.defs.appendChild(i),i.appendChild(He.createAlphaToLuminanceFilter()),(r=W("g")).appendChild(a),o.appendChild(r),r.setAttribute("filter","url("+s()+"#"+e+")"))}else if(2===t){var h=W("mask");h.setAttribute("id",n),h.setAttribute("mask-type","alpha");var l=W("g");h.appendChild(l),e=I(),i=He.createFilter(e);var p=W("feComponentTransfer");p.setAttribute("in","SourceGraphic"),i.appendChild(p);var f=W("feFuncA");f.setAttribute("type","table"),f.setAttribute("tableValues","1.0 0.0"),p.appendChild(f),this.globalData.defs.appendChild(i);var d=W("rect");d.setAttribute("width",this.comp.data.w),d.setAttribute("height",this.comp.data.h),d.setAttribute("x","0"),d.setAttribute("y","0"),d.setAttribute("fill","#ffffff"),d.setAttribute("opacity","0"),l.setAttribute("filter","url("+s()+"#"+e+")"),l.appendChild(d),(a=W("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),l.appendChild(a),Ye.maskType||(h.setAttribute("mask-type","luminance"),i.appendChild(He.createAlphaToLuminanceFilter()),r=W("g"),l.appendChild(d),r.appendChild(this.layerElement),l.appendChild(r)),this.globalData.defs.appendChild(h)}this.matteMasks[t]=n}return this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+s()+"#"+t+")")}},Ze.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},r([Se,n({initElement:function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],Qe),r([ze,We,Ue,Ze,Oe,Qe],$e),$e.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=W("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},$e.prototype.sourceRectAtTime=function(){return this.sourceRect},ei.prototype={addShapeToModifiers:function(t){var e,i=this.shapeModifiers.length;for(e=0;e<i;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;t>=0&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,i=0,s=e.length;i<s;){if(e[i].elem===t)return e[i].pos;i+=1}return 0},addProcessedElement:function(t,e){for(var i=this.processedElements,s=i.length;s;)if(i[s-=1].elem===t)return void(i[s].pos=e);i.push(new ti(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var ii={1:"butt",2:"round",3:"square"},si={1:"miter",2:"round",3:"bevel"};function ai(t,e,i){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=i,this.lvl=e,this._isAnimated=!!i.k;for(var s=0,a=t.length;s<a;){if(t[s].mProps.dynamicProperties.length){this._isAnimated=!0;break}s+=1}}function ri(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=W("path"),this.msElem=null}function ni(t,e,i,s){var a;this.elem=t,this.frameId=-1,this.dataProps=l(e.length),this.renderer=i,this.k=!1,this.dashStr="",this.dashArray=h("float32",e.length?e.length-1:0),this.dashoffset=h("float32",1),this.initDynamicPropertyContainer(s);var r,n=e.length||0;for(a=0;a<n;a+=1)r=vt.getProp(t,e[a].v,0,0,this),this.k=r.k||this.k,this.dataProps[a]={n:e[a].n,p:r};this.k||this.getValue(!0),this._isAnimated=this.k}function oi(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=vt.getProp(t,e.o,0,.01,this),this.w=vt.getProp(t,e.w,0,null,this),this.d=new ni(t,e.d||{},"svg",this),this.c=vt.getProp(t,e.c,1,255,this),this.style=i,this._isAnimated=!!this._isAnimated}function hi(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=vt.getProp(t,e.o,0,.01,this),this.c=vt.getProp(t,e.c,1,255,this),this.style=i}function li(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=i}function pi(t,e,i){this.data=e,this.c=h("uint8c",4*e.p);var s=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=h("float32",s),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=s,this.initDynamicPropertyContainer(i),this.prop=vt.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function fi(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,i)}function di(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=vt.getProp(t,e.w,0,null,this),this.d=new ni(t,e.d||{},"svg",this),this.initGradientData(t,e,i),this._isAnimated=!!this._isAnimated}function mi(){this.it=[],this.prevViewData=[],this.gr=W("g")}function ci(t,e,i){this.transform={mProps:t,op:e,container:i},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}ai.prototype.setAsAnimated=function(){this._isAnimated=!0},ri.prototype.reset=function(){this.d="",this._mdf=!1},ni.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,i=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<i;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},r([bt],ni),r([bt],oi),r([bt],hi),r([bt],li),pi.prototype.comparePoints=function(t,e){for(var i=0,s=this.o.length/2;i<s;){if(Math.abs(t[4*i]-t[4*e+2*i])>.01)return!1;i+=1}return!0},pi.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},pi.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,i,s,a=4*this.data.p;for(e=0;e<a;e+=1)i=e%4==0?100:255,s=Math.round(this.prop.v[e]*i),this.c[e]!==s&&(this.c[e]=s,this._cmdf=!t);if(this.o.length)for(a=this.prop.v.length,e=4*this.data.p;e<a;e+=1)i=e%2==0?100:1,s=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==s&&(this.o[e-4*this.data.p]=s,this._omdf=!t);this._mdf=!t}},r([bt],pi),fi.prototype.initGradientData=function(t,e,i){this.o=vt.getProp(t,e.o,0,.01,this),this.s=vt.getProp(t,e.s,1,null,this),this.e=vt.getProp(t,e.e,1,null,this),this.h=vt.getProp(t,e.h||{k:0},0,.01,this),this.a=vt.getProp(t,e.a||{k:0},0,P,this),this.g=new pi(t,e.g,this),this.style=i,this.stops=[],this.setGradientData(i.pElem,e),this.setGradientOpacity(e,i),this._isAnimated=!!this._isAnimated},fi.prototype.setGradientData=function(t,e){var i=I(),a=W(1===e.t?"linearGradient":"radialGradient");a.setAttribute("id",i),a.setAttribute("spreadMethod","pad"),a.setAttribute("gradientUnits","userSpaceOnUse");var r,n,o,h=[];for(o=4*e.g.p,n=0;n<o;n+=4)r=W("stop"),a.appendChild(r),h.push(r);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+s()+"#"+i+")"),this.gf=a,this.cst=h},fi.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){var i,a,r,n=W("mask"),o=W("path");n.appendChild(o);var h=I(),l=I();n.setAttribute("id",l);var p=W(1===t.t?"linearGradient":"radialGradient");p.setAttribute("id",h),p.setAttribute("spreadMethod","pad"),p.setAttribute("gradientUnits","userSpaceOnUse"),r=t.g.k.k[0].s?t.g.k.k[0].s.length:t.g.k.k.length;var f=this.stops;for(a=4*t.g.p;a<r;a+=2)(i=W("stop")).setAttribute("stop-color","rgb(255,255,255)"),p.appendChild(i),f.push(i);o.setAttribute("gf"===t.ty?"fill":"stroke","url("+s()+"#"+h+")"),"gs"===t.ty&&(o.setAttribute("stroke-linecap",ii[t.lc||2]),o.setAttribute("stroke-linejoin",si[t.lj||2]),1===t.lj&&o.setAttribute("stroke-miterlimit",t.ml)),this.of=p,this.ms=n,this.ost=f,this.maskId=l,e.msElem=o}},r([bt],fi),r([fi,bt],di);var ui=function(t,e,i,s){if(0===e)return"";var a,r=t.o,n=t.i,o=t.v,h=" M"+s.applyToPointStringified(o[0][0],o[0][1]);for(a=1;a<e;a+=1)h+=" C"+s.applyToPointStringified(r[a-1][0],r[a-1][1])+" "+s.applyToPointStringified(n[a][0],n[a][1])+" "+s.applyToPointStringified(o[a][0],o[a][1]);return i&&e&&(h+=" C"+s.applyToPointStringified(r[a-1][0],r[a-1][1])+" "+s.applyToPointStringified(n[0][0],n[0][1])+" "+s.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},gi=function(){var t=new Ft,e=new Ft;function i(t,e,i){(i||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(i||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function s(){}function a(i,s,a){var r,n,o,h,l,p,f,d,m,c,u=s.styles.length,g=s.lvl;for(p=0;p<u;p+=1){if(h=s.sh._mdf||a,s.styles[p].lvl<g){for(d=e.reset(),m=g-s.styles[p].lvl,c=s.transformers.length-1;!h&&m>0;)h=s.transformers[c].mProps._mdf||h,m-=1,c-=1;if(h)for(m=g-s.styles[p].lvl,c=s.transformers.length-1;m>0;)d.multiply(s.transformers[c].mProps.v),m-=1,c-=1}else d=t;if(n=(f=s.sh.paths)._length,h){for(o="",r=0;r<n;r+=1)(l=f.shapes[r])&&l._length&&(o+=ui(l,l._length,l.c,d));s.caches[p]=o}else o=s.caches[p];s.styles[p].d+=!0===i.hd?"":o,s.styles[p]._mdf=h||s.styles[p]._mdf}}function r(t,e,i){var s=e.style;(e.c._mdf||i)&&s.pElem.setAttribute("fill","rgb("+v(e.c.v[0])+","+v(e.c.v[1])+","+v(e.c.v[2])+")"),(e.o._mdf||i)&&s.pElem.setAttribute("fill-opacity",e.o.v)}function n(t,e,i){o(t,e,i),h(t,e,i)}function o(t,e,i){var s,a,r,n,o,h=e.gf,l=e.g._hasOpacity,p=e.s.v,f=e.e.v;if(e.o._mdf||i){var d="gf"===t.ty?"fill-opacity":"stroke-opacity";e.style.pElem.setAttribute(d,e.o.v)}if(e.s._mdf||i){var m=1===t.t?"x1":"cx",c="x1"===m?"y1":"cy";h.setAttribute(m,p[0]),h.setAttribute(c,p[1]),l&&!e.g._collapsable&&(e.of.setAttribute(m,p[0]),e.of.setAttribute(c,p[1]))}if(e.g._cmdf||i){s=e.cst;var u=e.g.c;for(r=s.length,a=0;a<r;a+=1)(n=s[a]).setAttribute("offset",u[4*a]+"%"),n.setAttribute("stop-color","rgb("+u[4*a+1]+","+u[4*a+2]+","+u[4*a+3]+")")}if(l&&(e.g._omdf||i)){var g=e.g.o;for(r=(s=e.g._collapsable?e.cst:e.ost).length,a=0;a<r;a+=1)n=s[a],e.g._collapsable||n.setAttribute("offset",g[2*a]+"%"),n.setAttribute("stop-opacity",g[2*a+1])}if(1===t.t)(e.e._mdf||i)&&(h.setAttribute("x2",f[0]),h.setAttribute("y2",f[1]),l&&!e.g._collapsable&&(e.of.setAttribute("x2",f[0]),e.of.setAttribute("y2",f[1])));else if((e.s._mdf||e.e._mdf||i)&&(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)),h.setAttribute("r",o),l&&!e.g._collapsable&&e.of.setAttribute("r",o)),e.s._mdf||e.e._mdf||e.h._mdf||e.a._mdf||i){o||(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)));var y=Math.atan2(f[1]-p[1],f[0]-p[0]),v=e.h.v;v>=1?v=.99:v<=-1&&(v=-.99);var b=o*v,_=Math.cos(y+e.a.v)*b+p[0],k=Math.sin(y+e.a.v)*b+p[1];h.setAttribute("fx",_),h.setAttribute("fy",k),l&&!e.g._collapsable&&(e.of.setAttribute("fx",_),e.of.setAttribute("fy",k))}}function h(t,e,i){var s=e.style,a=e.d;a&&(a._mdf||i)&&a.dashStr&&(s.pElem.setAttribute("stroke-dasharray",a.dashStr),s.pElem.setAttribute("stroke-dashoffset",a.dashoffset[0])),e.c&&(e.c._mdf||i)&&s.pElem.setAttribute("stroke","rgb("+v(e.c.v[0])+","+v(e.c.v[1])+","+v(e.c.v[2])+")"),(e.o._mdf||i)&&s.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||i)&&(s.pElem.setAttribute("stroke-width",e.w.v),s.msElem&&s.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function(t){switch(t.ty){case"fl":return r;case"gf":return o;case"gs":return n;case"st":return h;case"sh":case"el":case"rc":case"sr":return a;case"tr":return i;case"no":return s;default:return null}}}}();function yi(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,i),this.prevViewData=[]}function vi(t,e,i,s,a,r){this.o=t,this.sw=e,this.sc=i,this.fc=s,this.m=a,this.p=r,this._mdf={o:!0,sw:!!e,sc:!!i,fc:!!s,m:!0,p:!0}}function bi(t,e){this._frameId=i,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}r([ze,We,Ue,ei,Ze,Oe,Qe],yi),yi.prototype.initSecondaryElement=function(){},yi.prototype.identityMatrix=new Ft,yi.prototype.buildExpressionInterface=function(){},yi.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},yi.prototype.filterUniqueShapes=function(){var t,e,i,s,a=this.shapes.length,r=this.stylesList.length,n=[],o=!1;for(i=0;i<r;i+=1){for(s=this.stylesList[i],o=!1,n.length=0,t=0;t<a;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(s)&&(n.push(e),o=e._isAnimated||o);n.length>1&&o&&this.setShapesAsAnimated(n)}},yi.prototype.setShapesAsAnimated=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].setAsAnimated()},yi.prototype.createStyleElement=function(t,e){var i,a=new ri(t,e),r=a.pElem;if("st"===t.ty)i=new oi(this,t,a);else if("fl"===t.ty)i=new hi(this,t,a);else if("gf"===t.ty||"gs"===t.ty){i=new("gf"===t.ty?fi:di)(this,t,a),this.globalData.defs.appendChild(i.gf),i.maskId&&(this.globalData.defs.appendChild(i.ms),this.globalData.defs.appendChild(i.of),r.setAttribute("mask","url("+s()+"#"+i.maskId+")"))}else"no"===t.ty&&(i=new li(this,t,a));return"st"!==t.ty&&"gs"!==t.ty||(r.setAttribute("stroke-linecap",ii[t.lc||2]),r.setAttribute("stroke-linejoin",si[t.lj||2]),r.setAttribute("fill-opacity","0"),1===t.lj&&r.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&r.setAttribute("fill-rule","evenodd"),t.ln&&r.setAttribute("id",t.ln),t.cl&&r.setAttribute("class",t.cl),t.bm&&(r.style["mix-blend-mode"]=we(t.bm)),this.stylesList.push(a),this.addToAnimatedContents(t,i),i},yi.prototype.createGroupElement=function(t){var e=new mi;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=we(t.bm)),e},yi.prototype.createTransformElement=function(t,e){var i=Xt.getTransformProperty(this,t,this),s=new ci(i,i.o,e);return this.addToAnimatedContents(t,s),s},yi.prototype.createShapeElement=function(t,e,i){var s=4;"rc"===t.ty?s=5:"el"===t.ty?s=6:"sr"===t.ty&&(s=7);var a=new ai(e,i,Tt.getShapeProp(this,t,s,this));return this.shapes.push(a),this.addShapeToModifiers(a),this.addToAnimatedContents(t,a),a},yi.prototype.addToAnimatedContents=function(t,e){for(var i=0,s=this.animatedContents.length;i<s;){if(this.animatedContents[i].element===e)return;i+=1}this.animatedContents.push({fn:gi.createRenderFunction(t),element:e,data:t})},yi.prototype.setElementStyles=function(t){var e,i=t.styles,s=this.stylesList.length;for(e=0;e<s;e+=1)-1!==i.indexOf(this.stylesList[e])||this.stylesList[e].closed||i.push(this.stylesList[e])},yi.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},yi.prototype.searchShapes=function(t,e,i,s,a,r,n){var o,h,l,p,f,d,m=[].concat(r),c=t.length-1,u=[],g=[];for(o=c;o>=0;o-=1){if((d=this.searchProcessedElement(t[o]))?e[o]=i[d-1]:t[o]._render=n,"fl"===t[o].ty||"st"===t[o].ty||"gf"===t[o].ty||"gs"===t[o].ty||"no"===t[o].ty)d?e[o].style.closed=t[o].hd:e[o]=this.createStyleElement(t[o],a),t[o]._render&&e[o].style.pElem.parentNode!==s&&s.appendChild(e[o].style.pElem),u.push(e[o].style);else if("gr"===t[o].ty){if(d)for(l=e[o].it.length,h=0;h<l;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,a+1,m,n),t[o]._render&&e[o].gr.parentNode!==s&&s.appendChild(e[o].gr)}else"tr"===t[o].ty?(d||(e[o]=this.createTransformElement(t[o],s)),p=e[o].transform,m.push(p)):"sh"===t[o].ty||"rc"===t[o].ty||"el"===t[o].ty||"sr"===t[o].ty?(d||(e[o]=this.createShapeElement(t[o],m,a)),this.setElementStyles(e[o])):"tm"===t[o].ty||"rd"===t[o].ty||"ms"===t[o].ty||"pb"===t[o].ty||"zz"===t[o].ty||"op"===t[o].ty?(d?(f=e[o]).closed=!1:((f=Bt.getModifier(t[o].ty)).init(this,t[o]),e[o]=f,this.shapeModifiers.push(f)),g.push(f)):"rp"===t[o].ty&&(d?(f=e[o]).closed=!0:(f=Bt.getModifier(t[o].ty),e[o]=f,f.init(this,t,o,e),this.shapeModifiers.push(f),n=!1),g.push(f));this.addProcessedElement(t[o],o+1)}for(c=u.length,o=0;o<c;o+=1)u[o].closed=!0;for(c=g.length,o=0;o<c;o+=1)g[o].closed=!0},yi.prototype.renderInnerContent=function(){var t;this.renderModifiers();var e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},yi.prototype.renderShape=function(){var t,e,i=this.animatedContents.length;for(t=0;t<i;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},yi.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},vi.prototype.update=function(t,e,i,s,a,r){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1,this._mdf.p=!1;var n=!1;return this.o!==t&&(this.o=t,this._mdf.o=!0,n=!0),this.sw!==e&&(this.sw=e,this._mdf.sw=!0,n=!0),this.sc!==i&&(this.sc=i,this._mdf.sc=!0,n=!0),this.fc!==s&&(this.fc=s,this._mdf.fc=!0,n=!0),this.m!==a&&(this.m=a,this._mdf.m=!0,n=!0),!r.length||this.p[0]===r[0]&&this.p[1]===r[1]&&this.p[4]===r[4]&&this.p[5]===r[5]&&this.p[12]===r[12]&&this.p[13]===r[13]||(this.p=r,this._mdf.p=!0,n=!0),n},bi.prototype.defaultBoxWidth=[0,0],bi.prototype.copyData=function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},bi.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},bi.prototype.searchProperty=function(){return this.searchKeyframes()},bi.prototype.searchKeyframes=function(){return this.kf=this.data.d.k.length>1,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},bi.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},bi.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,i=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{var s;this.lock=!0,this._mdf=!1;var a=this.effectsSequence.length,r=t||this.data.d.k[this.keysIndex].s;for(s=0;s<a;s+=1)r=i!==this.keysIndex?this.effectsSequence[s](r,r.t):this.effectsSequence[s](this.currentData,r.t);e!==r&&this.setCurrentData(r),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},bi.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,i=0,s=t.length;i<=s-1&&!(i===s-1||t[i+1].t>e);)i+=1;return this.keysIndex!==i&&(this.keysIndex=i),this.data.d.k[this.keysIndex].s},bi.prototype.buildFinalText=function(t){for(var e,i,s=[],a=0,r=t.length,n=!1,o=!1,h="";a<r;)n=o,o=!1,e=t.charCodeAt(a),h=t.charAt(a),Pe.isCombinedCharacter(e)?n=!0:e>=55296&&e<=56319?Pe.isRegionalFlag(t,a)?h=t.substr(a,14):(i=t.charCodeAt(a+1))>=56320&&i<=57343&&(Pe.isModifier(e,i)?(h=t.substr(a,2),n=!0):h=Pe.isFlagEmoji(t.substr(a,4))?t.substr(a,4):t.substr(a,2)):e>56319?(i=t.charCodeAt(a+1),Pe.isVariationSelector(e)&&(n=!0)):Pe.isZeroWidthJoiner(e)&&(n=!0,o=!0),n?(s[s.length-1]+=h,n=!1):s.push(h),a+=h.length;return s},bi.prototype.completeTextData=function(t){t.__complete=!0;var e,i,s,a,r,n,o,h=this.elem.globalData.fontManager,l=this.data,p=[],f=0,d=l.m.g,m=0,c=0,u=0,g=[],y=0,v=0,b=h.getFontByName(t.f),_=0,k=ke(b);t.fWeight=k.weight,t.fStyle=k.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),i=t.finalText.length,t.finalLineHeight=t.lh;var P,A=t.tr/1e3*t.finalSize;if(t.sz)for(var S,x,w=!0,D=t.sz[0],C=t.sz[1];w;){S=0,y=0,i=(x=this.buildFinalText(t.t)).length,A=t.tr/1e3*t.finalSize;var M=-1;for(e=0;e<i;e+=1)P=x[e].charCodeAt(0),s=!1," "===x[e]?M=e:13!==P&&3!==P||(y=0,s=!0,S+=t.finalLineHeight||1.2*t.finalSize),h.chars?(o=h.getCharData(x[e],b.fStyle,b.fFamily),_=s?0:o.w*t.finalSize/100):_=h.measureText(x[e],t.f,t.finalSize),y+_>D&&" "!==x[e]?(-1===M?i+=1:e=M,S+=t.finalLineHeight||1.2*t.finalSize,x.splice(e,M===e?1:0,"\r"),M=-1,y=0):(y+=_,y+=A);S+=b.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&C<S?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=x,i=t.finalText.length,w=!1)}y=-A,_=0;var T,F=0;for(e=0;e<i;e+=1)if(s=!1,13===(P=(T=t.finalText[e]).charCodeAt(0))||3===P?(F=0,g.push(y),v=y>v?y:v,y=-2*A,a="",s=!0,u+=1):a=T,h.chars?(o=h.getCharData(T,b.fStyle,h.getFontByName(t.f).fFamily),_=s?0:o.w*t.finalSize/100):_=h.measureText(a,t.f,t.finalSize)," "===T?F+=_+A:(y+=_+A+F,F=0),p.push({l:_,an:_,add:m,n:s,anIndexes:[],val:a,line:u,animatorJustifyOffset:0}),2==d){if(m+=_,""===a||" "===a||e===i-1){for(""!==a&&" "!==a||(m-=_);c<=e;)p[c].an=m,p[c].ind=f,p[c].extra=_,c+=1;f+=1,m=0}}else if(3==d){if(m+=_,""===a||e===i-1){for(""===a&&(m-=_);c<=e;)p[c].an=m,p[c].ind=f,p[c].extra=_,c+=1;m=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=y>v?y:v,g.push(y),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=g;var E,I,L,V,R=l.a;n=R.length;var z=[];for(r=0;r<n;r+=1){for((E=R[r]).a.sc&&(t.strokeColorAnim=!0),E.a.sw&&(t.strokeWidthAnim=!0),(E.a.fc||E.a.fh||E.a.fs||E.a.fb)&&(t.fillColorAnim=!0),V=0,L=E.s.b,e=0;e<i;e+=1)(I=p[e]).anIndexes[r]=V,(1==L&&""!==I.val||2==L&&""!==I.val&&" "!==I.val||3==L&&(I.n||" "==I.val||e==i-1)||4==L&&(I.n||e==i-1))&&(1===E.s.rn&&z.push(V),V+=1);l.a[r].s.totalChars=V;var O,N=-1;if(1===E.s.rn)for(e=0;e<i;e+=1)N!=(I=p[e]).anIndexes[r]&&(N=I.anIndexes[r],O=z.splice(Math.floor(Math.random()*z.length),1)[0]),I.anIndexes[r]=O}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=b.ascent*t.finalSize/100},bi.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var i=this.copyData({},this.data.d.k[e].s);i=this.copyData(i,t),this.data.d.k[e].s=i,this.recalculate(e),this.setCurrentData(i),this.elem.addDynamicProperty(this)},bi.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},bi.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},bi.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var _i=function(){var t=Math.max,e=Math.min,i=Math.floor;function s(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=vt.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?vt.getProp(t,e.e,0,0,this):{v:100},this.o=vt.getProp(t,e.o||{k:0},0,0,this),this.xe=vt.getProp(t,e.xe||{k:0},0,0,this),this.ne=vt.getProp(t,e.ne||{k:0},0,0,this),this.sm=vt.getProp(t,e.sm||{k:100},0,0,this),this.a=vt.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return s.prototype={getMult:function(s){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var a=0,r=0,n=1,o=1;this.ne.v>0?a=this.ne.v/100:r=-this.ne.v/100,this.xe.v>0?n=1-this.xe.v/100:o=1+this.xe.v/100;var h=tt.getBezierEasing(a,r,n,o).get,l=0,p=this.finalS,f=this.finalE,d=this.data.sh;if(2===d)l=h(l=f===p?s>=f?1:0:t(0,e(.5/(f-p)+(s-p)/(f-p),1)));else if(3===d)l=h(l=f===p?s>=f?0:1:1-t(0,e(.5/(f-p)+(s-p)/(f-p),1)));else if(4===d)f===p?l=0:(l=t(0,e(.5/(f-p)+(s-p)/(f-p),1)))<.5?l*=2:l=1-2*(l-.5),l=h(l);else if(5===d){if(f===p)l=0;else{var m=f-p,c=-m/2+(s=e(t(0,s+.5-p),f-p)),u=m/2;l=Math.sqrt(1-c*c/(u*u))}l=h(l)}else 6===d?(f===p?l=0:(s=e(t(0,s+.5-p),f-p),l=(1+Math.cos(Math.PI+2*Math.PI*s/(f-p)))/2),l=h(l)):(s>=i(p)&&(l=t(0,e(s-p<0?e(f,1)-(p-s):f-s,1))),l=h(l));if(100!==this.sm.v){var g=.01*this.sm.v;0===g&&(g=1e-8);var y=.5-.5*g;l<y?l=0:(l=(l-y)/g)>1&&(l=1)}return l*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,i=this.o.v/e,s=this.s.v/e+i,a=this.e.v/e+i;if(s>a){var r=s;s=a,a=r}this.finalS=s,this.finalE=a}},r([bt],s),{getTextSelectorProp:function(t,e,i){return new s(t,e,i)}}}();function ki(t,e,i){var s={propType:!1},a=vt.getProp,r=e.a;this.a={r:r.r?a(t,r.r,0,P,i):s,rx:r.rx?a(t,r.rx,0,P,i):s,ry:r.ry?a(t,r.ry,0,P,i):s,sk:r.sk?a(t,r.sk,0,P,i):s,sa:r.sa?a(t,r.sa,0,P,i):s,s:r.s?a(t,r.s,1,.01,i):s,a:r.a?a(t,r.a,1,0,i):s,o:r.o?a(t,r.o,0,.01,i):s,p:r.p?a(t,r.p,1,0,i):s,sw:r.sw?a(t,r.sw,0,0,i):s,sc:r.sc?a(t,r.sc,1,0,i):s,fc:r.fc?a(t,r.fc,1,0,i):s,fh:r.fh?a(t,r.fh,0,0,i):s,fs:r.fs?a(t,r.fs,0,.01,i):s,fb:r.fb?a(t,r.fb,0,.01,i):s,t:r.t?a(t,r.t,0,0,i):s},this.s=_i.getTextSelectorProp(t,e.s,i),this.s.t=e.s.t}function Pi(t,e,i){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=i,this._animatorsData=l(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(i)}function Ai(){}Pi.prototype.searchProperties=function(){var t,e,i=this._textData.a.length,s=vt.getProp;for(t=0;t<i;t+=1)e=this._textData.a[t],this._animatorsData[t]=new ki(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:s(this._elem,this._textData.p.a,0,0,this),f:s(this._elem,this._textData.p.f,0,0,this),l:s(this._elem,this._textData.p.l,0,0,this),r:s(this._elem,this._textData.p.r,0,0,this),p:s(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=s(this._elem,this._textData.m.a,1,0,this)},Pi.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var i,s,a,r,n,o,h,l,p,f,d,m,c,u,g,y,v,b,_,k=this._moreOptions.alignment.v,P=this._animatorsData,A=this._textData,S=this.mHelper,x=this._renderType,w=this.renderedLetters.length,D=t.l;if(this._hasMaskedPath){if(_=this._pathData.m,!this._pathData.n||this._pathData._mdf){var C,M=_.v;for(this._pathData.r.v&&(M=M.reverse()),n={tLength:0,segments:[]},r=M._length-1,y=0,a=0;a<r;a+=1)C=rt.buildBezierData(M.v[a],M.v[a+1],[M.o[a][0]-M.v[a][0],M.o[a][1]-M.v[a][1]],[M.i[a+1][0]-M.v[a+1][0],M.i[a+1][1]-M.v[a+1][1]]),n.tLength+=C.segmentLength,n.segments.push(C),y+=C.segmentLength;a=r,_.v.c&&(C=rt.buildBezierData(M.v[a],M.v[0],[M.o[a][0]-M.v[a][0],M.o[a][1]-M.v[a][1]],[M.i[0][0]-M.v[0][0],M.i[0][1]-M.v[0][1]]),n.tLength+=C.segmentLength,n.segments.push(C),y+=C.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,d=0,f=1,l=0,p=!0,u=n.segments,o<0&&_.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),f=(c=u[d=u.length-1].points).length-1;o<0;)o+=c[f].partialLength,(f-=1)<0&&(f=(c=u[d-=1].points).length-1);m=(c=u[d].points)[f-1],g=(h=c[f]).partialLength}r=D.length,i=0,s=0;var T,F,E,I,L,V=1.2*t.finalSize*.714,N=!0;E=P.length;var B,q,j,W,X,H,Y,G,K,J,U,Z,Q=-1,$=o,tt=d,et=f,it=-1,st="",at=this.defaultPropsArray;if(2===t.j||1===t.j){var nt=0,ot=0,ht=2===t.j?-.5:-1,lt=0,pt=!0;for(a=0;a<r;a+=1)if(D[a].n){for(nt&&(nt+=ot);lt<a;)D[lt].animatorJustifyOffset=nt,lt+=1;nt=0,pt=!0}else{for(F=0;F<E;F+=1)(T=P[F].a).t.propType&&(pt&&2===t.j&&(ot+=T.t.v*ht),(L=P[F].s.getMult(D[a].anIndexes[F],A.a[F].s.totalChars)).length?nt+=T.t.v*L[0]*ht:nt+=T.t.v*L*ht);pt=!1}for(nt&&(nt+=ot);lt<a;)D[lt].animatorJustifyOffset=nt,lt+=1}for(a=0;a<r;a+=1){if(S.reset(),W=1,D[a].n)i=0,s+=t.yOffset,s+=N?1:0,o=$,N=!1,this._hasMaskedPath&&(f=et,m=(c=u[d=tt].points)[f-1],g=(h=c[f]).partialLength,l=0),st="",U="",K="",Z="",at=this.defaultPropsArray;else{if(this._hasMaskedPath){if(it!==D[a].line){switch(t.j){case 1:o+=y-t.lineWidths[D[a].line];break;case 2:o+=(y-t.lineWidths[D[a].line])/2}it=D[a].line}Q!==D[a].ind&&(D[Q]&&(o+=D[Q].extra),o+=D[a].an/2,Q=D[a].ind),o+=k[0]*D[a].an*.005;var ft=0;for(F=0;F<E;F+=1)(T=P[F].a).p.propType&&((L=P[F].s.getMult(D[a].anIndexes[F],A.a[F].s.totalChars)).length?ft+=T.p.v[0]*L[0]:ft+=T.p.v[0]*L),T.a.propType&&((L=P[F].s.getMult(D[a].anIndexes[F],A.a[F].s.totalChars)).length?ft+=T.a.v[0]*L[0]:ft+=T.a.v[0]*L);for(p=!0,this._pathData.a.v&&(o=.5*D[0].an+(y-this._pathData.f.v-.5*D[0].an-.5*D[D.length-1].an)*Q/(r-1),o+=this._pathData.f.v);p;)l+g>=o+ft||!c?(v=(o+ft-l)/h.partialLength,q=m.point[0]+(h.point[0]-m.point[0])*v,j=m.point[1]+(h.point[1]-m.point[1])*v,S.translate(-k[0]*D[a].an*.005,-k[1]*V*.01),p=!1):c&&(l+=h.partialLength,(f+=1)>=c.length&&(f=0,u[d+=1]?c=u[d].points:_.v.c?(f=0,c=u[d=0].points):(l-=h.partialLength,c=null)),c&&(m=h,g=(h=c[f]).partialLength));B=D[a].an/2-D[a].add,S.translate(-B,0,0)}else B=D[a].an/2-D[a].add,S.translate(-B,0,0),S.translate(-k[0]*D[a].an*.005,-k[1]*V*.01,0);for(F=0;F<E;F+=1)(T=P[F].a).t.propType&&(L=P[F].s.getMult(D[a].anIndexes[F],A.a[F].s.totalChars),0===i&&0===t.j||(this._hasMaskedPath?L.length?o+=T.t.v*L[0]:o+=T.t.v*L:L.length?i+=T.t.v*L[0]:i+=T.t.v*L));for(t.strokeWidthAnim&&(H=t.sw||0),t.strokeColorAnim&&(X=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(Y=[t.fc[0],t.fc[1],t.fc[2]]),F=0;F<E;F+=1)(T=P[F].a).a.propType&&((L=P[F].s.getMult(D[a].anIndexes[F],A.a[F].s.totalChars)).length?S.translate(-T.a.v[0]*L[0],-T.a.v[1]*L[1],T.a.v[2]*L[2]):S.translate(-T.a.v[0]*L,-T.a.v[1]*L,T.a.v[2]*L));for(F=0;F<E;F+=1)(T=P[F].a).s.propType&&((L=P[F].s.getMult(D[a].anIndexes[F],A.a[F].s.totalChars)).length?S.scale(1+(T.s.v[0]-1)*L[0],1+(T.s.v[1]-1)*L[1],1):S.scale(1+(T.s.v[0]-1)*L,1+(T.s.v[1]-1)*L,1));for(F=0;F<E;F+=1){if(T=P[F].a,L=P[F].s.getMult(D[a].anIndexes[F],A.a[F].s.totalChars),T.sk.propType&&(L.length?S.skewFromAxis(-T.sk.v*L[0],T.sa.v*L[1]):S.skewFromAxis(-T.sk.v*L,T.sa.v*L)),T.r.propType&&(L.length?S.rotateZ(-T.r.v*L[2]):S.rotateZ(-T.r.v*L)),T.ry.propType&&(L.length?S.rotateY(T.ry.v*L[1]):S.rotateY(T.ry.v*L)),T.rx.propType&&(L.length?S.rotateX(T.rx.v*L[0]):S.rotateX(T.rx.v*L)),T.o.propType&&(L.length?W+=(T.o.v*L[0]-W)*L[0]:W+=(T.o.v*L-W)*L),t.strokeWidthAnim&&T.sw.propType&&(L.length?H+=T.sw.v*L[0]:H+=T.sw.v*L),t.strokeColorAnim&&T.sc.propType)for(G=0;G<3;G+=1)L.length?X[G]+=(T.sc.v[G]-X[G])*L[0]:X[G]+=(T.sc.v[G]-X[G])*L;if(t.fillColorAnim&&t.fc){if(T.fc.propType)for(G=0;G<3;G+=1)L.length?Y[G]+=(T.fc.v[G]-Y[G])*L[0]:Y[G]+=(T.fc.v[G]-Y[G])*L;T.fh.propType&&(Y=L.length?O(Y,T.fh.v*L[0]):O(Y,T.fh.v*L)),T.fs.propType&&(Y=L.length?R(Y,T.fs.v*L[0]):R(Y,T.fs.v*L)),T.fb.propType&&(Y=L.length?z(Y,T.fb.v*L[0]):z(Y,T.fb.v*L))}}for(F=0;F<E;F+=1)(T=P[F].a).p.propType&&(L=P[F].s.getMult(D[a].anIndexes[F],A.a[F].s.totalChars),this._hasMaskedPath?L.length?S.translate(0,T.p.v[1]*L[0],-T.p.v[2]*L[1]):S.translate(0,T.p.v[1]*L,-T.p.v[2]*L):L.length?S.translate(T.p.v[0]*L[0],T.p.v[1]*L[1],-T.p.v[2]*L[2]):S.translate(T.p.v[0]*L,T.p.v[1]*L,-T.p.v[2]*L));if(t.strokeWidthAnim&&(K=H<0?0:H),t.strokeColorAnim&&(J="rgb("+Math.round(255*X[0])+","+Math.round(255*X[1])+","+Math.round(255*X[2])+")"),t.fillColorAnim&&t.fc&&(U="rgb("+Math.round(255*Y[0])+","+Math.round(255*Y[1])+","+Math.round(255*Y[2])+")"),this._hasMaskedPath){if(S.translate(0,-t.ls),S.translate(0,k[1]*V*.01+s,0),this._pathData.p.v){b=(h.point[1]-m.point[1])/(h.point[0]-m.point[0]);var dt=180*Math.atan(b)/Math.PI;h.point[0]<m.point[0]&&(dt+=180),S.rotate(-dt*Math.PI/180)}S.translate(q,j,0),o-=k[0]*D[a].an*.005,D[a+1]&&Q!==D[a+1].ind&&(o+=D[a].an/2,o+=.001*t.tr*t.finalSize)}else{switch(S.translate(i,s,0),t.ps&&S.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:S.translate(D[a].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[D[a].line]),0,0);break;case 2:S.translate(D[a].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[D[a].line])/2,0,0)}S.translate(0,-t.ls),S.translate(B,0,0),S.translate(k[0]*D[a].an*.005,k[1]*V*.01,0),i+=D[a].l+.001*t.tr*t.finalSize}"html"===x?st=S.toCSS():"svg"===x?st=S.to2dCSS():at=[S.props[0],S.props[1],S.props[2],S.props[3],S.props[4],S.props[5],S.props[6],S.props[7],S.props[8],S.props[9],S.props[10],S.props[11],S.props[12],S.props[13],S.props[14],S.props[15]],Z=W}w<=a?(I=new vi(Z,K,J,U,st,at),this.renderedLetters.push(I),w+=1,this.lettersChangedFlag=!0):(I=this.renderedLetters[a],this.lettersChangedFlag=I.update(Z,K,J,U,st,at)||this.lettersChangedFlag)}}},Pi.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},Pi.prototype.mHelper=new Ft,Pi.prototype.defaultPropsArray=[],r([bt],Pi),Ai.prototype.initElement=function(t,e,i){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,i),this.textProperty=new bi(this,t.t,this.dynamicProperties),this.textAnimator=new Pi(t.t,this.renderType,this),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},Ai.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},Ai.prototype.createPathShape=function(t,e){var i,s,a=e.length,r="";for(i=0;i<a;i+=1)"sh"===e[i].ty&&(s=e[i].ks.k,r+=ui(s,s.i.length,!0,t));return r},Ai.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},Ai.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},Ai.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},Ai.prototype.applyTextPropertiesToMatrix=function(t,e,i,s,a){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i])/2,0,0)}e.translate(s,a,0)},Ai.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},Ai.prototype.emptyProp=new vi,Ai.prototype.destroy=function(){},Ai.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var Si,xi={shapes:[]};function wi(t,e,i){this.textSpans=[],this.renderType="svg",this.initElement(t,e,i)}function Di(t,e,i){this.initElement(t,e,i)}function Ci(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initFrame(),this.initTransform(t,e,i),this.initHierarchy()}function Mi(){}function Ti(){}function Fi(t,e,i){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?l(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?vt.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function Ei(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=W("svg");var i="";if(e&&e.title){var s=W("title"),a=I();s.setAttribute("id",a),s.textContent=e.title,this.svgElement.appendChild(s),i+=a}if(e&&e.description){var r=W("desc"),n=I();r.setAttribute("id",n),r.textContent=e.description,this.svgElement.appendChild(r),i+=" "+n}i&&this.svgElement.setAttribute("aria-labelledby",i);var o=W("defs");this.svgElement.appendChild(o);var h=W("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}return r([ze,We,Ue,Ze,Oe,Qe,Ai],wi),wi.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=W("text"))},wi.prototype.buildTextContents=function(t){for(var e=0,i=t.length,s=[],a="";e<i;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(s.push(a),a=""):a+=t[e],e+=1;return s.push(a),s},wi.prototype.buildShapeData=function(t,e){if(t.shapes&&t.shapes.length){var i=t.shapes[0];if(i.it){var s=i.it[i.it.length-1];s.s&&(s.s.k[0]=e,s.s.k[1]=e)}}return t},wi.prototype.buildNewText=function(){var t,e;this.addDynamicProperty(this);var i=this.textProperty.currentData;this.renderedLetters=l(i?i.l.length:0),i.fc?this.layerElement.setAttribute("fill",this.buildColor(i.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),i.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(i.sc)),this.layerElement.setAttribute("stroke-width",i.sw)),this.layerElement.setAttribute("font-size",i.finalSize);var s=this.globalData.fontManager.getFontByName(i.f);if(s.fClass)this.layerElement.setAttribute("class",s.fClass);else{this.layerElement.setAttribute("font-family",s.fFamily);var a=i.fWeight,r=i.fStyle;this.layerElement.setAttribute("font-style",r),this.layerElement.setAttribute("font-weight",a)}this.layerElement.setAttribute("aria-label",i.t);var n,o=i.l||[],h=!!this.globalData.fontManager.chars;e=o.length;var p=this.mHelper,f=this.data.singleShape,d=0,m=0,c=!0,u=.001*i.tr*i.finalSize;if(!f||h||i.sz){var g,y=this.textSpans.length;for(t=0;t<e;t+=1){if(this.textSpans[t]||(this.textSpans[t]={span:null,childSpan:null,glyph:null}),!h||!f||0===t){if(n=y>t?this.textSpans[t].span:W(h?"g":"text"),y<=t){if(n.setAttribute("stroke-linecap","butt"),n.setAttribute("stroke-linejoin","round"),n.setAttribute("stroke-miterlimit","4"),this.textSpans[t].span=n,h){var v=W("g");n.appendChild(v),this.textSpans[t].childSpan=v}this.textSpans[t].span=n,this.layerElement.appendChild(n)}n.style.display="inherit"}if(p.reset(),f&&(o[t].n&&(d=-u,m+=i.yOffset,m+=c?1:0,c=!1),this.applyTextPropertiesToMatrix(i,p,o[t].line,d,m),d+=o[t].l||0,d+=u),h){var b;if(1===(g=this.globalData.fontManager.getCharData(i.finalText[t],s.fStyle,this.globalData.fontManager.getFontByName(i.f).fFamily)).t)b=new Fi(g.data,this.globalData,this);else{var _=xi;g.data&&g.data.shapes&&(_=this.buildShapeData(g.data,i.finalSize)),b=new yi(_,this.globalData,this)}if(this.textSpans[t].glyph){var k=this.textSpans[t].glyph;this.textSpans[t].childSpan.removeChild(k.layerElement),k.destroy()}this.textSpans[t].glyph=b,b._debug=!0,b.prepareFrame(0),b.renderFrame(),this.textSpans[t].childSpan.appendChild(b.layerElement),1===g.t&&this.textSpans[t].childSpan.setAttribute("transform","scale("+i.finalSize/100+","+i.finalSize/100+")")}else f&&n.setAttribute("transform","translate("+p.props[12]+","+p.props[13]+")"),n.textContent=o[t].val,n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}f&&n&&n.setAttribute("d","")}else{var P=this.textContainer,A="start";switch(i.j){case 1:A="end";break;case 2:A="middle";break;default:A="start"}P.setAttribute("text-anchor",A),P.setAttribute("letter-spacing",u);var S=this.buildTextContents(i.finalText);for(e=S.length,m=i.ps?i.ps[1]+i.ascent:0,t=0;t<e;t+=1)(n=this.textSpans[t].span||W("tspan")).textContent=S[t],n.setAttribute("x",0),n.setAttribute("y",m),n.style.display="inherit",P.appendChild(n),this.textSpans[t]||(this.textSpans[t]={span:null,glyph:null}),this.textSpans[t].span=n,m+=i.finalLineHeight;this.layerElement.appendChild(P)}for(;t<this.textSpans.length;)this.textSpans[t].span.style.display="none",t+=1;this._sizeChanged=!0},wi.prototype.sourceRectAtTime=function(){if(this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged){this._sizeChanged=!1;var t=this.layerElement.getBBox();this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}}return this.bbox},wi.prototype.getValue=function(){var t,e,i=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<i;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf&&(this._mdf=!0))},wi.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){var t,e;this._sizeChanged=!0;var i,s,a,r=this.textAnimator.renderedLetters,n=this.textProperty.currentData.l;for(e=n.length,t=0;t<e;t+=1)n[t].n||(i=r[t],s=this.textSpans[t].span,(a=this.textSpans[t].glyph)&&a.renderFrame(),i._mdf.m&&s.setAttribute("transform",i.m),i._mdf.o&&s.setAttribute("opacity",i.o),i._mdf.sw&&s.setAttribute("stroke-width",i.sw),i._mdf.sc&&s.setAttribute("stroke",i.sc),i._mdf.fc&&s.setAttribute("fill",i.fc))}},r([$e],Di),Di.prototype.createContent=function(){var t=W("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},Ci.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},Ci.prototype.renderFrame=function(){},Ci.prototype.getBaseElement=function(){return null},Ci.prototype.destroy=function(){},Ci.prototype.sourceRectAtTime=function(){},Ci.prototype.hide=function(){},r([ze,We,Ze,Oe],Ci),r([qe],Mi),Mi.prototype.createNull=function(t){return new Ci(t,this.globalData,this)},Mi.prototype.createShape=function(t){return new yi(t,this.globalData,this)},Mi.prototype.createText=function(t){return new wi(t,this.globalData,this)},Mi.prototype.createImage=function(t){return new $e(t,this.globalData,this)},Mi.prototype.createSolid=function(t){return new Di(t,this.globalData,this)},Mi.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var i=W("clipPath"),a=W("rect");a.setAttribute("width",t.w),a.setAttribute("height",t.h),a.setAttribute("x",0),a.setAttribute("y",0);var r=I();i.setAttribute("id",r),i.appendChild(a),this.layerElement.setAttribute("clip-path","url("+s()+"#"+r+")"),e.appendChild(i),this.layers=t.layers,this.elements=l(t.layers.length)},Mi.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},Mi.prototype.updateContainerSize=function(){},Mi.prototype.findIndexByInd=function(t){var e=0,i=this.layers.length;for(e=0;e<i;e+=1)if(this.layers[e].ind===t)return e;return-1},Mi.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){e[t]=!0;var i=this.createItem(this.layers[t]);if(e[t]=i,N()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(i),i.initExpressions()),this.appendElementInPos(i,t),this.layers[t].tt){var s="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1;if(-1===s)return;if(this.elements[s]&&!0!==this.elements[s]){var a=e[s].getMatte(this.layers[t].tt);i.setMatte(a)}else this.buildItem(s),this.addPendingElement(i)}}},Mi.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,i=this.elements.length;e<i;){if(this.elements[e]===t){var s="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,a=this.elements[s].getMatte(this.layers[e].tt);t.setMatte(a);break}e+=1}}},Mi.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){var e;null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var i=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=i-1;e>=0;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<i;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},Mi.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){for(var s,a=0;a<e;)this.elements[a]&&!0!==this.elements[a]&&this.elements[a].getBaseElement()&&(s=this.elements[a].getBaseElement()),a+=1;s?this.layerElement.insertBefore(i,s):this.layerElement.appendChild(i)}},Mi.prototype.hide=function(){this.layerElement.style.display="none"},Mi.prototype.show=function(){this.layerElement.style.display="block"},r([ze,We,Ze,Oe,Qe],Ti),Ti.prototype.initElement=function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},Ti.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var i,s=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),i=s-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&(this.elements[i].prepareFrame(this.renderedFrame-this.layers[i].st),this.elements[i]._mdf&&(this._mdf=!0))}},Ti.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},Ti.prototype.setElements=function(t){this.elements=t},Ti.prototype.getElements=function(){return this.elements},Ti.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},Ti.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},r([Mi,Ti,Ue],Fi),Fi.prototype.createComp=function(t){return new Fi(t,this.globalData,this)},r([Mi],Ei),Ei.prototype.createComp=function(t){return new Fi(t,this.globalData,this)},Si=Ei,U["svg"]=Si,Bt.registerModifier("tm",jt),Bt.registerModifier("pb",Wt),Bt.registerModifier("rp",Ht),Bt.registerModifier("rd",Yt),Bt.registerModifier("zz",le),Bt.registerModifier("op",_e),It}));
diff --git a/build/player/lottie_light_canvas.js b/build/player/lottie_light_canvas.js
index 8f2b065..05fd133 100644
--- a/build/player/lottie_light_canvas.js
+++ b/build/player/lottie_light_canvas.js
@@ -1,4 +1,4 @@
-(typeof navigator !== "undefined") && (function (global, factory) {
+(typeof document !== "undefined") && (typeof navigator !== "undefined") && (function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
   typeof define === 'function' && define.amd ? define(factory) :
   (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lottie = factory());
@@ -8,19 +8,15 @@
   var locationHref = '';
   var _useWebWorker = false;
   var initialDefaultFrame = -999999;
-
   var setWebWorker = function setWebWorker(flag) {
     _useWebWorker = !!flag;
   };
-
   var getWebWorker = function getWebWorker() {
     return _useWebWorker;
   };
-
   var setLocationHref = function setLocationHref(value) {
     locationHref = value;
   };
-
   var getLocationHref = function getLocationHref() {
     return locationHref;
   };
@@ -34,28 +30,24 @@
     var i;
     var len = sources.length;
     var sourcePrototype;
-
     for (i = 0; i < len; i += 1) {
       sourcePrototype = sources[i].prototype;
-
       for (var attr in sourcePrototype) {
         if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
       }
     }
   }
-
   function getDescriptor(object, prop) {
     return Object.getOwnPropertyDescriptor(object, prop);
   }
-
   function createProxyFunction(prototype) {
     function ProxyFunction() {}
-
     ProxyFunction.prototype = prototype;
     return ProxyFunction;
   }
 
   // import Howl from '../../3rd_party/howler';
+
   var audioControllerFactory = function () {
     function AudioController(audioFactory) {
       this.audios = [];
@@ -63,7 +55,6 @@
       this._volume = 1;
       this._isMuted = false;
     }
-
     AudioController.prototype = {
       addAudio: function addAudio(audio) {
         this.audios.push(audio);
@@ -71,7 +62,6 @@
       pause: function pause() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].pause();
         }
@@ -79,7 +69,6 @@
       resume: function resume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].resume();
         }
@@ -87,7 +76,6 @@
       setRate: function setRate(rateValue) {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].setRate(rateValue);
         }
@@ -96,13 +84,11 @@
         if (this.audioFactory) {
           return this.audioFactory(assetPath);
         }
-
         if (window.Howl) {
           return new window.Howl({
             src: [assetPath]
           });
         }
-
         return {
           isPlaying: false,
           play: function play() {
@@ -121,17 +107,14 @@
       },
       setVolume: function setVolume(value) {
         this._volume = value;
-
         this._updateVolume();
       },
       mute: function mute() {
         this._isMuted = true;
-
         this._updateVolume();
       },
       unmute: function unmute() {
         this._isMuted = false;
-
         this._updateVolume();
       },
       getVolume: function getVolume() {
@@ -140,7 +123,6 @@
       _updateVolume: function _updateVolume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
         }
@@ -156,55 +138,44 @@
       var i = 0;
       var arr = [];
       var value;
-
       switch (type) {
         case 'int16':
         case 'uint8c':
           value = 1;
           break;
-
         default:
           value = 1.1;
           break;
       }
-
       for (i = 0; i < len; i += 1) {
         arr.push(value);
       }
-
       return arr;
     }
-
     function createTypedArrayFactory(type, len) {
       if (type === 'float32') {
         return new Float32Array(len);
       }
-
       if (type === 'int16') {
         return new Int16Array(len);
       }
-
       if (type === 'uint8c') {
         return new Uint8ClampedArray(len);
       }
-
       return createRegularArray(type, len);
     }
-
     if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
       return createTypedArrayFactory;
     }
-
     return createRegularArray;
   }();
-
   function createSizedArray(len) {
     return Array.apply(null, {
       length: len
     });
   }
 
-  function _typeof$3(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$3 = function _typeof(obj) { return typeof obj; }; } else { _typeof$3 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$3(obj); }
+  function _typeof$3(o) { "@babel/helpers - typeof"; return _typeof$3 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$3(o); }
   var subframeEnabled = true;
   var expressionsPlugin = null;
   var expressionsInterfaces = null;
@@ -217,57 +188,43 @@
   var bmMax = Math.max;
   var bmMin = Math.min;
   var BMMath = {};
-
   (function () {
     var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
     var i;
     var len = propertyNames.length;
-
     for (i = 0; i < len; i += 1) {
       BMMath[propertyNames[i]] = Math[propertyNames[i]];
     }
   })();
-
   function ProjectInterface$1() {
     return {};
   }
-
   BMMath.random = Math.random;
-
   BMMath.abs = function (val) {
     var tOfVal = _typeof$3(val);
-
     if (tOfVal === 'object' && val.length) {
       var absArr = createSizedArray(val.length);
       var i;
       var len = val.length;
-
       for (i = 0; i < len; i += 1) {
         absArr[i] = Math.abs(val[i]);
       }
-
       return absArr;
     }
-
     return Math.abs(val);
   };
-
   var defaultCurveSegments = 150;
   var degToRads = Math.PI / 180;
   var roundCorner = 0.5519;
-
   function roundValues(flag) {
     _shouldRoundValues = !!flag;
   }
-
   function bmRnd(value) {
     if (_shouldRoundValues) {
       return Math.round(value);
     }
-
     return value;
   }
-
   function styleDiv(element) {
     element.style.position = 'absolute';
     element.style.top = 0;
@@ -281,53 +238,44 @@
     element.style.webkitTransformStyle = 'preserve-3d';
     element.style.mozTransformStyle = 'preserve-3d';
   }
-
   function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
     this.type = type;
     this.currentTime = currentTime;
     this.totalTime = totalTime;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteEvent(type, frameMultiplier) {
     this.type = type;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
     this.type = type;
     this.currentLoop = currentLoop;
     this.totalLoops = totalLoops;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMSegmentStartEvent(type, firstFrame, totalFrames) {
     this.type = type;
     this.firstFrame = firstFrame;
     this.totalFrames = totalFrames;
   }
-
   function BMDestroyEvent(type, target) {
     this.type = type;
     this.target = target;
   }
-
   function BMRenderFrameErrorEvent(nativeError, currentTime) {
     this.type = 'renderFrameError';
     this.nativeError = nativeError;
     this.currentTime = currentTime;
   }
-
   function BMConfigErrorEvent(nativeError) {
     this.type = 'configError';
     this.nativeError = nativeError;
   }
-
   function BMAnimationConfigErrorEvent(type, nativeError) {
     this.type = type;
     this.nativeError = nativeError;
   }
-
   var createElementID = function () {
     var _count = 0;
     return function createID() {
@@ -335,7 +283,6 @@
       return idPrefix$1 + '__lottie_element_' + _count;
     };
   }();
-
   function HSVtoRGB(h, s, v) {
     var r;
     var g;
@@ -350,51 +297,42 @@
     p = v * (1 - s);
     q = v * (1 - f * s);
     t = v * (1 - (1 - f) * s);
-
     switch (i % 6) {
       case 0:
         r = v;
         g = t;
         b = p;
         break;
-
       case 1:
         r = q;
         g = v;
         b = p;
         break;
-
       case 2:
         r = p;
         g = v;
         b = t;
         break;
-
       case 3:
         r = p;
         g = q;
         b = v;
         break;
-
       case 4:
         r = t;
         g = p;
         b = v;
         break;
-
       case 5:
         r = v;
         g = p;
         b = q;
         break;
-
       default:
         break;
     }
-
     return [r, g, b];
   }
-
   function RGBtoHSV(r, g, b) {
     var max = Math.max(r, g, b);
     var min = Math.min(r, g, b);
@@ -402,136 +340,105 @@
     var h;
     var s = max === 0 ? 0 : d / max;
     var v = max / 255;
-
     switch (max) {
       case min:
         h = 0;
         break;
-
       case r:
         h = g - b + d * (g < b ? 6 : 0);
         h /= 6 * d;
         break;
-
       case g:
         h = b - r + d * 2;
         h /= 6 * d;
         break;
-
       case b:
         h = r - g + d * 4;
         h /= 6 * d;
         break;
-
       default:
         break;
     }
-
     return [h, s, v];
   }
-
   function addSaturationToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[1] += offset;
-
     if (hsv[1] > 1) {
       hsv[1] = 1;
     } else if (hsv[1] <= 0) {
       hsv[1] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addBrightnessToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[2] += offset;
-
     if (hsv[2] > 1) {
       hsv[2] = 1;
     } else if (hsv[2] < 0) {
       hsv[2] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addHueToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[0] += offset / 360;
-
     if (hsv[0] > 1) {
       hsv[0] -= 1;
     } else if (hsv[0] < 0) {
       hsv[0] += 1;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   var rgbToHex = function () {
     var colorMap = [];
     var i;
     var hex;
-
     for (i = 0; i < 256; i += 1) {
       hex = i.toString(16);
       colorMap[i] = hex.length === 1 ? '0' + hex : hex;
     }
-
     return function (r, g, b) {
       if (r < 0) {
         r = 0;
       }
-
       if (g < 0) {
         g = 0;
       }
-
       if (b < 0) {
         b = 0;
       }
-
       return '#' + colorMap[r] + colorMap[g] + colorMap[b];
     };
   }();
-
   var setSubframeEnabled = function setSubframeEnabled(flag) {
     subframeEnabled = !!flag;
   };
-
   var getSubframeEnabled = function getSubframeEnabled() {
     return subframeEnabled;
   };
-
   var setExpressionsPlugin = function setExpressionsPlugin(value) {
     expressionsPlugin = value;
   };
-
   var getExpressionsPlugin = function getExpressionsPlugin() {
     return expressionsPlugin;
   };
-
   var setExpressionInterfaces = function setExpressionInterfaces(value) {
     expressionsInterfaces = value;
   };
-
   var getExpressionInterfaces = function getExpressionInterfaces() {
     return expressionsInterfaces;
   };
-
   var setDefaultCurveSegments = function setDefaultCurveSegments(value) {
     defaultCurveSegments = value;
   };
-
   var getDefaultCurveSegments = function getDefaultCurveSegments() {
     return defaultCurveSegments;
   };
-
   var setIdPrefix = function setIdPrefix(value) {
     idPrefix$1 = value;
   };
-
   var getIdPrefix = function getIdPrefix() {
     return idPrefix$1;
   };
@@ -541,8 +448,7 @@
     return document.createElementNS(svgNS, type);
   }
 
-  function _typeof$2(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$2 = function _typeof(obj) { return typeof obj; }; } else { _typeof$2 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$2(obj); }
-
+  function _typeof$2(o) { "@babel/helpers - typeof"; return _typeof$2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$2(o); }
   var dataManager = function () {
     var _counterId = 1;
     var processes = [];
@@ -563,21 +469,18 @@
         });
       }
     };
-
     function createWorker(fn) {
       if (window.Worker && window.Blob && getWebWorker()) {
         var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], {
           type: 'text/javascript'
-        }); // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
-
+        });
+        // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
         var url = URL.createObjectURL(blob);
         return new Worker(url);
       }
-
       workerFn = fn;
       return workerProxy;
     }
-
     function setupWorker() {
       if (!workerInstance) {
         workerInstance = createWorker(function workerStart(e) {
@@ -590,28 +493,22 @@
               var jLen;
               var k;
               var kLen;
-
               for (i = 0; i < len; i += 1) {
                 layerData = layers[i];
-
                 if ('ks' in layerData && !layerData.completed) {
                   layerData.completed = true;
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         convertPathsToAbsoluteValues(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) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
                           }
@@ -619,7 +516,6 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 0) {
                     layerData.layers = findCompLayers(layerData.refId, comps);
                     completeLayers(layerData.layers, comps);
@@ -631,16 +527,15 @@
                 }
               }
             }
-
             function completeChars(chars, assets) {
               if (chars) {
                 var i = 0;
                 var len = chars.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (chars[i].t === 1) {
                     // var compData = findComp(chars[i].data.refId, assets);
-                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets); // chars[i].data.ip = 0;
+                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                    // chars[i].data.ip = 0;
                     // chars[i].data.op = 99999;
                     // chars[i].data.st = 0;
                     // chars[i].data.sr = 1;
@@ -652,61 +547,48 @@
                     //   s: { k: [100, 100], a: 0 },
                     //   o: { k: 100, a: 0 },
                     // };
-
                     completeLayers(chars[i].data.layers, assets);
                   }
                 }
               }
             }
-
             function findComp(id, comps) {
               var i = 0;
               var len = comps.length;
-
               while (i < len) {
                 if (comps[i].id === id) {
                   return comps[i];
                 }
-
                 i += 1;
               }
-
               return null;
             }
-
             function findCompLayers(id, comps) {
               var comp = findComp(id, comps);
-
               if (comp) {
                 if (!comp.layers.__used) {
                   comp.layers.__used = true;
                   return comp.layers;
                 }
-
                 return JSON.parse(JSON.stringify(comp.layers));
               }
-
               return null;
             }
-
             function completeShapes(arr) {
               var i;
               var len = arr.length;
               var j;
               var jLen;
-
               for (i = len - 1; i >= 0; i -= 1) {
                 if (arr[i].ty === 'sh') {
                   if (arr[i].ks.k.i) {
                     convertPathsToAbsoluteValues(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) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
                       }
-
                       if (arr[i].ks.k[j].e) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
                       }
@@ -717,11 +599,9 @@
                 }
               }
             }
-
             function convertPathsToAbsoluteValues(path) {
               var i;
               var len = path.i.length;
-
               for (i = 0; i < len; i += 1) {
                 path.i[i][0] += path.v[i][0];
                 path.i[i][1] += path.v[i][1];
@@ -729,40 +609,30 @@
                 path.o[i][1] += path.v[i][1];
               }
             }
-
             function checkVersion(minimum, animVersionString) {
               var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
-
               if (minimum[0] > animVersion[0]) {
                 return true;
               }
-
               if (animVersion[0] > minimum[0]) {
                 return false;
               }
-
               if (minimum[1] > animVersion[1]) {
                 return true;
               }
-
               if (animVersion[1] > minimum[1]) {
                 return false;
               }
-
               if (minimum[2] > animVersion[2]) {
                 return true;
               }
-
               if (animVersion[2] > minimum[2]) {
                 return false;
               }
-
               return null;
             }
-
             var checkText = function () {
               var minimumVersion = [4, 4, 14];
-
               function updateTextLayer(textLayer) {
                 var documentData = textLayer.t.d;
                 textLayer.t.d = {
@@ -772,26 +642,21 @@
                   }]
                 };
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -801,17 +666,14 @@
                 }
               };
             }();
-
             var checkChars = function () {
               var minimumVersion = [4, 7, 99];
               return function (animationData) {
                 if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
                   var i;
                   var len = animationData.chars.length;
-
                   for (i = 0; i < len; i += 1) {
                     var charData = animationData.chars[i];
-
                     if (charData.data && charData.data.shapes) {
                       completeShapes(charData.data.shapes);
                       charData.data.ip = 0;
@@ -840,7 +702,6 @@
                           a: 0
                         }
                       };
-
                       if (!animationData.chars[i].t) {
                         charData.data.shapes.push({
                           ty: 'no'
@@ -882,27 +743,22 @@
                 }
               };
             }();
-
             var checkPathProperties = function () {
               var minimumVersion = [5, 7, 15];
-
               function updateTextLayer(textLayer) {
                 var pathData = textLayer.t.p;
-
                 if (typeof pathData.a === 'number') {
                   pathData.a = {
                     a: 0,
                     k: pathData.a
                   };
                 }
-
                 if (typeof pathData.p === 'number') {
                   pathData.p = {
                     a: 0,
                     k: pathData.p
                   };
                 }
-
                 if (typeof pathData.r === 'number') {
                   pathData.r = {
                     a: 0,
@@ -910,26 +766,21 @@
                   };
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -939,23 +790,19 @@
                 }
               };
             }();
-
             var checkColors = function () {
               var minimumVersion = [4, 1, 9];
-
               function iterateShapes(shapes) {
                 var i;
                 var len = shapes.length;
                 var j;
                 var jLen;
-
                 for (i = 0; i < len; i += 1) {
                   if (shapes[i].ty === 'gr') {
                     iterateShapes(shapes[i].it);
                   } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
                     if (shapes[i].c.k && shapes[i].c.k[0].i) {
                       jLen = shapes[i].c.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (shapes[i].c.k[j].s) {
                           shapes[i].c.k[j].s[0] /= 255;
@@ -963,7 +810,6 @@
                           shapes[i].c.k[j].s[2] /= 255;
                           shapes[i].c.k[j].s[3] /= 255;
                         }
-
                         if (shapes[i].c.k[j].e) {
                           shapes[i].c.k[j].e[0] /= 255;
                           shapes[i].c.k[j].e[1] /= 255;
@@ -980,26 +826,21 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 4) {
                     iterateShapes(layers[i].shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1009,28 +850,23 @@
                 }
               };
             }();
-
             var checkShapes = function () {
               var minimumVersion = [4, 4, 18];
-
               function completeClosingShapes(arr) {
                 var i;
                 var len = arr.length;
                 var j;
                 var jLen;
-
                 for (i = len - 1; i >= 0; i -= 1) {
                   if (arr[i].ty === 'sh') {
                     if (arr[i].ks.k.i) {
                       arr[i].ks.k.c = arr[i].closed;
                     } else {
                       jLen = arr[i].ks.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (arr[i].ks.k[j].s) {
                           arr[i].ks.k[j].s[0].c = arr[i].closed;
                         }
-
                         if (arr[i].ks.k[j].e) {
                           arr[i].ks.k[j].e[0].c = arr[i].closed;
                         }
@@ -1041,7 +877,6 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var layerData;
                 var i;
@@ -1050,25 +885,20 @@
                 var jLen;
                 var k;
                 var kLen;
-
                 for (i = 0; i < len; i += 1) {
                   layerData = layers[i];
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         maskProps[j].pt.k.c = maskProps[j].cl;
                       } else {
                         kLen = maskProps[j].pt.k.length;
-
                         for (k = 0; k < kLen; k += 1) {
                           if (maskProps[j].pt.k[k].s) {
                             maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
                           }
@@ -1076,21 +906,17 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 4) {
                     completeClosingShapes(layerData.shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1100,12 +926,10 @@
                 }
               };
             }();
-
             function completeData(animationData) {
               if (animationData.__complete) {
                 return;
               }
-
               checkColors(animationData);
               checkText(animationData);
               checkChars(animationData);
@@ -1115,12 +939,11 @@
               completeChars(animationData.chars, animationData.assets);
               animationData.__complete = true;
             }
-
             function completeText(data) {
-              if (data.t.a.length === 0 && !('m' in data.t.p)) {// data.singleShape = true;
+              if (data.t.a.length === 0 && !('m' in data.t.p)) {
+                // data.singleShape = true;
               }
             }
-
             var moduleOb = {};
             moduleOb.completeData = completeData;
             moduleOb.checkColors = checkColors;
@@ -1130,47 +953,37 @@
             moduleOb.completeLayers = completeLayers;
             return moduleOb;
           }
-
           if (!_workerSelf.dataManager) {
             _workerSelf.dataManager = dataFunctionManager();
           }
-
           if (!_workerSelf.assetLoader) {
             _workerSelf.assetLoader = function () {
               function formatResponse(xhr) {
                 // using typeof doubles the time of execution of this method,
                 // so if available, it's better to use the header to validate the type
                 var contentTypeHeader = xhr.getResponseHeader('content-type');
-
                 if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
                   return xhr.response;
                 }
-
                 if (xhr.response && _typeof$2(xhr.response) === 'object') {
                   return xhr.response;
                 }
-
                 if (xhr.response && typeof xhr.response === 'string') {
                   return JSON.parse(xhr.response);
                 }
-
                 if (xhr.responseText) {
                   return JSON.parse(xhr.responseText);
                 }
-
                 return null;
               }
-
               function loadAsset(path, fullPath, callback, errorCallback) {
                 var response;
-                var xhr = new XMLHttpRequest(); // set responseType after calling open or IE will break.
-
+                var xhr = new XMLHttpRequest();
+                // set responseType after calling open or IE will break.
                 try {
                   // This crashes on Android WebView prior to KitKat
                   xhr.responseType = 'json';
                 } catch (err) {} // eslint-disable-line no-empty
-
-
                 xhr.onreadystatechange = function () {
                   if (xhr.readyState === 4) {
                     if (xhr.status === 200) {
@@ -1188,7 +1001,6 @@
                     }
                   }
                 };
-
                 try {
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), path, true);
@@ -1196,20 +1008,16 @@
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
                 }
-
                 xhr.send();
               }
-
               return {
                 load: loadAsset
               };
             }();
           }
-
           if (e.data.type === 'loadAnimation') {
             _workerSelf.assetLoader.load(e.data.path, e.data.fullPath, function (data) {
               _workerSelf.dataManager.completeData(data);
-
               _workerSelf.postMessage({
                 id: e.data.id,
                 payload: data,
@@ -1223,9 +1031,7 @@
             });
           } else if (e.data.type === 'complete') {
             var animation = e.data.animation;
-
             _workerSelf.dataManager.completeData(animation);
-
             _workerSelf.postMessage({
               id: e.data.id,
               payload: animation,
@@ -1246,13 +1052,11 @@
             });
           }
         });
-
         workerInstance.onmessage = function (event) {
           var data = event.data;
           var id = data.id;
           var process = processes[id];
           processes[id] = null;
-
           if (data.status === 'success') {
             process.onComplete(data.payload);
           } else if (process.onError) {
@@ -1261,7 +1065,6 @@
         };
       }
     }
-
     function createProcess(onComplete, onError) {
       _counterId += 1;
       var id = 'processId_' + _counterId;
@@ -1271,7 +1074,6 @@
       };
       return id;
     }
-
     function loadAnimation(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1282,7 +1084,6 @@
         id: processId
       });
     }
-
     function loadData(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1293,7 +1094,6 @@
         id: processId
       });
     }
-
     function completeAnimation(anim, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1303,7 +1103,6 @@
         id: processId
       });
     }
-
     return {
       loadAnimation: loadAnimation,
       loadData: loadData,
@@ -1321,94 +1120,74 @@
       ctx.fillRect(0, 0, 1, 1);
       return canvas;
     }();
-
     function imageLoaded() {
       this.loadedAssets += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function footageLoaded() {
       this.loadedFootagesCount += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function getAssetsPath(assetData, assetsPath, originalPath) {
       var path = '';
-
       if (assetData.e) {
         path = assetData.p;
       } else if (assetsPath) {
         var imagePath = assetData.p;
-
         if (imagePath.indexOf('images/') !== -1) {
           imagePath = imagePath.split('/')[1];
         }
-
         path = assetsPath + imagePath;
       } else {
         path = originalPath;
         path += assetData.u ? assetData.u : '';
         path += assetData.p;
       }
-
       return path;
     }
-
     function testImageLoaded(img) {
       var _count = 0;
       var intervalId = setInterval(function () {
         var box = img.getBBox();
-
         if (box.width || _count > 500) {
           this._imageLoaded();
-
           clearInterval(intervalId);
         }
-
         _count += 1;
       }.bind(this), 50);
     }
-
     function createImageData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createNS('image');
-
       if (isSafari) {
         this.testImageLoaded(img);
       } else {
         img.addEventListener('load', this._imageLoaded, false);
       }
-
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
-
       if (this._elementHelper.append) {
         this._elementHelper.append(img);
       } else {
         this._elementHelper.appendChild(img);
       }
-
       var ob = {
         img: img,
         assetData: assetData
       };
       return ob;
     }
-
     function createImgData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createTag('img');
@@ -1416,7 +1195,6 @@
       img.addEventListener('load', this._imageLoaded, false);
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.src = path;
@@ -1426,7 +1204,6 @@
       };
       return ob;
     }
-
     function createFootageData(data) {
       var ob = {
         assetData: data
@@ -1434,21 +1211,17 @@
       var path = getAssetsPath(data, this.assetsPath, this.path);
       dataManager.loadData(path, function (footageData) {
         ob.img = footageData;
-
         this._footageLoaded();
       }.bind(this), function () {
         ob.img = {};
-
         this._footageLoaded();
       }.bind(this));
       return ob;
     }
-
     function loadAssets(assets, cb) {
       this.imagesLoadedCb = cb;
       var i;
       var len = assets.length;
-
       for (i = 0; i < len; i += 1) {
         if (!assets[i].layers) {
           if (!assets[i].t || assets[i].t === 'seq') {
@@ -1461,43 +1234,33 @@
         }
       }
     }
-
     function setPath(path) {
       this.path = path || '';
     }
-
     function setAssetsPath(path) {
       this.assetsPath = path || '';
     }
-
     function getAsset(assetData) {
       var i = 0;
       var len = this.images.length;
-
       while (i < len) {
         if (this.images[i].assetData === assetData) {
           return this.images[i].img;
         }
-
         i += 1;
       }
-
       return null;
     }
-
     function destroy() {
       this.imagesLoadedCb = null;
       this.images.length = 0;
     }
-
     function loadedImages() {
       return this.totalImages === this.loadedAssets;
     }
-
     function loadedFootages() {
       return this.totalFootages === this.loadedFootagesCount;
     }
-
     function setCacheType(type, elementHelper) {
       if (type === 'svg') {
         this._elementHelper = elementHelper;
@@ -1506,7 +1269,6 @@
         this._createImageData = this.createImgData.bind(this);
       }
     }
-
     function ImagePreloaderFactory() {
       this._imageLoaded = imageLoaded.bind(this);
       this._footageLoaded = footageLoaded.bind(this);
@@ -1521,7 +1283,6 @@
       this.imagesLoadedCb = null;
       this.images = [];
     }
-
     ImagePreloaderFactory.prototype = {
       loadAssets: loadAssets,
       setAssetsPath: setAssetsPath,
@@ -1540,12 +1301,10 @@
   }();
 
   function BaseEvent() {}
-
   BaseEvent.prototype = {
     triggerEvent: function triggerEvent(eventName, args) {
       if (this._cbs[eventName]) {
         var callbacks = this._cbs[eventName];
-
         for (var i = 0; i < callbacks.length; i += 1) {
           callbacks[i](args);
         }
@@ -1555,9 +1314,7 @@
       if (!this._cbs[eventName]) {
         this._cbs[eventName] = [];
       }
-
       this._cbs[eventName].push(callback);
-
       return function () {
         this.removeEventListener(eventName, callback);
       }.bind(this);
@@ -1568,18 +1325,14 @@
       } else if (this._cbs[eventName]) {
         var i = 0;
         var len = this._cbs[eventName].length;
-
         while (i < len) {
           if (this._cbs[eventName][i] === callback) {
             this._cbs[eventName].splice(i, 1);
-
             i -= 1;
             len -= 1;
           }
-
           i += 1;
         }
-
         if (!this._cbs[eventName].length) {
           this._cbs[eventName] = null;
         }
@@ -1593,33 +1346,26 @@
       var keys = {};
       var line;
       var keysCount = 0;
-
       for (var i = 0; i < lines.length; i += 1) {
         line = lines[i].split(':');
-
         if (line.length === 2) {
           keys[line[0]] = line[1].trim();
           keysCount += 1;
         }
       }
-
       if (keysCount === 0) {
         throw new Error();
       }
-
       return keys;
     }
-
     return function (_markers) {
       var markers = [];
-
       for (var i = 0; i < _markers.length; i += 1) {
         var _marker = _markers[i];
         var markerData = {
           time: _marker.tm,
           duration: _marker.dr
         };
-
         try {
           markerData.payload = JSON.parse(_markers[i].cm);
         } catch (_) {
@@ -1631,10 +1377,8 @@
             };
           }
         }
-
         markers.push(markerData);
       }
-
       return markers;
     };
   }();
@@ -1643,27 +1387,21 @@
     function registerComposition(comp) {
       this.compositions.push(comp);
     }
-
     return function () {
       function _thisProjectFunction(name) {
         var i = 0;
         var len = this.compositions.length;
-
         while (i < len) {
           if (this.compositions[i].data && this.compositions[i].data.nm === name) {
             if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
               this.compositions[i].prepareFrame(this.currentFrame);
             }
-
             return this.compositions[i].compInterface;
           }
-
           i += 1;
         }
-
         return null;
       }
-
       _thisProjectFunction.compositions = [];
       _thisProjectFunction.currentFrame = 0;
       _thisProjectFunction.registerComposition = registerComposition;
@@ -1672,33 +1410,27 @@
   }();
 
   var renderers = {};
-
   var registerRenderer = function registerRenderer(key, value) {
     renderers[key] = value;
   };
-
   function getRenderer(key) {
     return renderers[key];
   }
-
   function getRegisteredRenderer() {
     // Returns canvas by default for compatibility
     if (renderers.canvas) {
       return 'canvas';
-    } // Returns any renderer that is registered
-
-
+    }
+    // Returns any renderer that is registered
     for (var key in renderers) {
       if (renderers[key]) {
         return key;
       }
     }
-
     return '';
   }
 
-  function _typeof$1(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$1 = function _typeof(obj) { return typeof obj; }; } else { _typeof$1 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$1(obj); }
-
+  function _typeof$1(o) { "@babel/helpers - typeof"; return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$1(o); }
   var AnimationItem = function AnimationItem() {
     this._cbs = [];
     this.name = '';
@@ -1737,28 +1469,22 @@
     this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
     this.expressionsPlugin = getExpressionsPlugin();
   };
-
   extendPrototype([BaseEvent], AnimationItem);
-
   AnimationItem.prototype.setParams = function (params) {
     if (params.wrapper || params.container) {
       this.wrapper = params.wrapper || params.container;
     }
-
     var animType = 'svg';
-
     if (params.animType) {
       animType = params.animType;
     } else if (params.renderer) {
       animType = params.renderer;
     }
-
     var RendererClass = getRenderer(animType);
     this.renderer = new RendererClass(this, params.rendererSettings);
     this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
     this.renderer.setProjectInterface(this.projectInterface);
     this.animType = animType;
-
     if (params.loop === '' || params.loop === null || params.loop === undefined || params.loop === true) {
       this.loop = true;
     } else if (params.loop === false) {
@@ -1766,17 +1492,14 @@
     } else {
       this.loop = parseInt(params.loop, 10);
     }
-
     this.autoplay = 'autoplay' in params ? params.autoplay : true;
     this.name = params.name ? params.name : '';
     this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
     this.assetsPath = params.assetsPath;
     this.initialSegment = params.initialSegment;
-
     if (params.audioFactory) {
       this.audioController.setAudioFactory(params.audioFactory);
     }
-
     if (params.animationData) {
       this.setupAnimation(params.animationData);
     } else if (params.path) {
@@ -1785,28 +1508,23 @@
       } else {
         this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
       }
-
       this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
       this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
       dataManager.loadAnimation(params.path, this.configAnimation, this.onSetupError);
     }
   };
-
   AnimationItem.prototype.onSetupError = function () {
     this.trigger('data_failed');
   };
-
   AnimationItem.prototype.setupAnimation = function (data) {
     dataManager.completeAnimation(data, this.configAnimation);
   };
-
   AnimationItem.prototype.setData = function (wrapper, animationData) {
     if (animationData) {
       if (_typeof$1(animationData) !== 'object') {
         animationData = JSON.parse(animationData);
       }
     }
-
     var params = {
       wrapper: wrapper,
       animationData: animationData
@@ -1823,7 +1541,6 @@
     var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-loop').value : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-loop').value : wrapperAttributes.getNamedItem('bm-loop') ? wrapperAttributes.getNamedItem('bm-loop').value : '';
-
     if (loop === 'false') {
       params.loop = false;
     } else if (loop === 'true') {
@@ -1831,7 +1548,6 @@
     } else if (loop !== '') {
       params.loop = parseInt(loop, 10);
     }
-
     var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-autoplay').value : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-autoplay').value : wrapperAttributes.getNamedItem('bm-autoplay') ? wrapperAttributes.getNamedItem('bm-autoplay').value : true;
@@ -1842,81 +1558,64 @@
     var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-prerender').value : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-prerender').value : wrapperAttributes.getNamedItem('bm-prerender') ? wrapperAttributes.getNamedItem('bm-prerender').value : '';
-
     if (prerender === 'false') {
       params.prerender = false;
     }
-
     if (!params.path) {
       this.trigger('destroy');
     } else {
       this.setParams(params);
     }
   };
-
   AnimationItem.prototype.includeLayers = function (data) {
     if (data.op > this.animationData.op) {
       this.animationData.op = data.op;
       this.totalFrames = Math.floor(data.op - this.animationData.ip);
     }
-
     var layers = this.animationData.layers;
     var i;
     var len = layers.length;
     var newLayers = data.layers;
     var j;
     var jLen = newLayers.length;
-
     for (j = 0; j < jLen; j += 1) {
       i = 0;
-
       while (i < len) {
         if (layers[i].id === newLayers[j].id) {
           layers[i] = newLayers[j];
           break;
         }
-
         i += 1;
       }
     }
-
     if (data.chars || data.fonts) {
       this.renderer.globalData.fontManager.addChars(data.chars);
       this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
     }
-
     if (data.assets) {
       len = data.assets.length;
-
       for (i = 0; i < len; i += 1) {
         this.animationData.assets.push(data.assets[i]);
       }
     }
-
     this.animationData.__complete = false;
     dataManager.completeAnimation(this.animationData, this.onSegmentComplete);
   };
-
   AnimationItem.prototype.onSegmentComplete = function (data) {
     this.animationData = data;
     var expressionsPlugin = getExpressionsPlugin();
-
     if (expressionsPlugin) {
       expressionsPlugin.initExpressions(this);
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.loadNextSegment = function () {
     var segments = this.animationData.segments;
-
     if (!segments || segments.length === 0 || !this.autoloadSegments) {
       this.trigger('data_ready');
       this.timeCompleted = this.totalFrames;
       return;
     }
-
     var segment = segments.shift();
     this.timeCompleted = segment.time * this.frameRate;
     var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
@@ -1925,36 +1624,28 @@
       this.trigger('data_failed');
     }.bind(this));
   };
-
   AnimationItem.prototype.loadSegments = function () {
     var segments = this.animationData.segments;
-
     if (!segments) {
       this.timeCompleted = this.totalFrames;
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.imagesLoaded = function () {
     this.trigger('loaded_images');
     this.checkLoaded();
   };
-
   AnimationItem.prototype.preloadImages = function () {
     this.imagePreloader.setAssetsPath(this.assetsPath);
     this.imagePreloader.setPath(this.path);
     this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
   };
-
   AnimationItem.prototype.configAnimation = function (animData) {
     if (!this.renderer) {
       return;
     }
-
     try {
       this.animationData = animData;
-
       if (this.initialSegment) {
         this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
         this.firstFrame = Math.round(this.initialSegment[0]);
@@ -1962,13 +1653,10 @@
         this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
         this.firstFrame = Math.round(this.animationData.ip);
       }
-
       this.renderer.configAnimation(animData);
-
       if (!animData.assets) {
         animData.assets = [];
       }
-
       this.assets = this.animationData.assets;
       this.frameRate = this.animationData.fr;
       this.frameMult = this.animationData.fr / 1000;
@@ -1979,7 +1667,6 @@
       this.loadSegments();
       this.updaFrameModifier();
       this.waitForFontsLoaded();
-
       if (this.isPaused) {
         this.audioController.pause();
       }
@@ -1987,103 +1674,83 @@
       this.triggerConfigError(error);
     }
   };
-
   AnimationItem.prototype.waitForFontsLoaded = function () {
     if (!this.renderer) {
       return;
     }
-
     if (this.renderer.globalData.fontManager.isLoaded) {
       this.checkLoaded();
     } else {
       setTimeout(this.waitForFontsLoaded.bind(this), 20);
     }
   };
-
   AnimationItem.prototype.checkLoaded = function () {
     if (!this.isLoaded && this.renderer.globalData.fontManager.isLoaded && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas') && this.imagePreloader.loadedFootages()) {
       this.isLoaded = true;
       var expressionsPlugin = getExpressionsPlugin();
-
       if (expressionsPlugin) {
         expressionsPlugin.initExpressions(this);
       }
-
       this.renderer.initItems();
       setTimeout(function () {
         this.trigger('DOMLoaded');
       }.bind(this), 0);
       this.gotoFrame();
-
       if (this.autoplay) {
         this.play();
       }
     }
   };
-
   AnimationItem.prototype.resize = function (width, height) {
     // Adding this validation for backwards compatibility in case an event object was being passed down
     var _width = typeof width === 'number' ? width : undefined;
-
     var _height = typeof height === 'number' ? height : undefined;
-
     this.renderer.updateContainerSize(_width, _height);
   };
-
   AnimationItem.prototype.setSubframe = function (flag) {
     this.isSubframeEnabled = !!flag;
   };
-
   AnimationItem.prototype.gotoFrame = function () {
     this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
 
     if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
       this.currentFrame = this.timeCompleted;
     }
-
     this.trigger('enterFrame');
     this.renderFrame();
     this.trigger('drawnFrame');
   };
-
   AnimationItem.prototype.renderFrame = function () {
     if (this.isLoaded === false || !this.renderer) {
       return;
     }
-
     try {
       if (this.expressionsPlugin) {
         this.expressionsPlugin.resetFrame();
       }
-
       this.renderer.renderFrame(this.currentFrame + this.firstFrame);
     } catch (error) {
       this.triggerRenderFrameError(error);
     }
   };
-
   AnimationItem.prototype.play = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.isPaused = false;
       this.trigger('_play');
       this.audioController.resume();
-
       if (this._idle) {
         this._idle = false;
         this.trigger('_active');
       }
     }
   };
-
   AnimationItem.prototype.pause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === false) {
       this.isPaused = true;
       this.trigger('_pause');
@@ -2092,54 +1759,42 @@
       this.audioController.pause();
     }
   };
-
   AnimationItem.prototype.togglePause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.play();
     } else {
       this.pause();
     }
   };
-
   AnimationItem.prototype.stop = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.pause();
     this.playCount = 0;
     this._completedLoop = false;
     this.setCurrentRawFrameValue(0);
   };
-
   AnimationItem.prototype.getMarkerData = function (markerName) {
     var marker;
-
     for (var i = 0; i < this.markers.length; i += 1) {
       marker = this.markers[i];
-
       if (marker.payload && marker.payload.name === markerName) {
         return marker;
       }
     }
-
     return null;
   };
-
   AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         this.goToAndStop(marker.time, true);
       }
@@ -2148,20 +1803,15 @@
     } else {
       this.setCurrentRawFrameValue(value * this.frameModifier);
     }
-
     this.pause();
   };
-
   AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         if (!marker.duration) {
           this.goToAndStop(marker.time, true);
@@ -2172,19 +1822,16 @@
     } else {
       this.goToAndStop(numValue, isFrame, name);
     }
-
     this.play();
   };
-
   AnimationItem.prototype.advanceTime = function (value) {
     if (this.isPaused === true || this.isLoaded === false) {
       return;
     }
-
     var nextValue = this.currentRawFrame + value * this.frameModifier;
-    var _isComplete = false; // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+    var _isComplete = false;
+    // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
     // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
-
     if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
       if (!this.loop || this.playCount === this.loop) {
         if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
@@ -2193,7 +1840,6 @@
         }
       } else if (nextValue >= this.totalFrames) {
         this.playCount += 1;
-
         if (!this.checkSegments(nextValue % this.totalFrames)) {
           this.setCurrentRawFrameValue(nextValue % this.totalFrames);
           this._completedLoop = true;
@@ -2207,7 +1853,6 @@
         if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) {
           // eslint-disable-line no-plusplus
           this.setCurrentRawFrameValue(this.totalFrames + nextValue % this.totalFrames);
-
           if (!this._completedLoop) {
             this._completedLoop = true;
           } else {
@@ -2221,17 +1866,14 @@
     } else {
       this.setCurrentRawFrameValue(nextValue);
     }
-
     if (_isComplete) {
       this.setCurrentRawFrameValue(nextValue);
       this.pause();
       this.trigger('complete');
     }
   };
-
   AnimationItem.prototype.adjustSegment = function (arr, offset) {
     this.playCount = 0;
-
     if (arr[1] < arr[0]) {
       if (this.frameModifier > 0) {
         if (this.playSpeed < 0) {
@@ -2240,7 +1882,6 @@
           this.setDirection(-1);
         }
       }
-
       this.totalFrames = arr[0] - arr[1];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[1];
@@ -2253,19 +1894,15 @@
           this.setDirection(1);
         }
       }
-
       this.totalFrames = arr[1] - arr[0];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[0];
       this.setCurrentRawFrameValue(0.001 + offset);
     }
-
     this.trigger('segmentStart');
   };
-
   AnimationItem.prototype.setSegment = function (init, end) {
     var pendingFrame = -1;
-
     if (this.isPaused) {
       if (this.currentRawFrame + this.firstFrame < init) {
         pendingFrame = init;
@@ -2273,64 +1910,51 @@
         pendingFrame = end - init;
       }
     }
-
     this.firstFrame = init;
     this.totalFrames = end - init;
     this.timeCompleted = this.totalFrames;
-
     if (pendingFrame !== -1) {
       this.goToAndStop(pendingFrame, true);
     }
   };
-
   AnimationItem.prototype.playSegments = function (arr, forceFlag) {
     if (forceFlag) {
       this.segments.length = 0;
     }
-
     if (_typeof$1(arr[0]) === 'object') {
       var i;
       var len = arr.length;
-
       for (i = 0; i < len; i += 1) {
         this.segments.push(arr[i]);
       }
     } else {
       this.segments.push(arr);
     }
-
     if (this.segments.length && forceFlag) {
       this.adjustSegment(this.segments.shift(), 0);
     }
-
     if (this.isPaused) {
       this.play();
     }
   };
-
   AnimationItem.prototype.resetSegments = function (forceFlag) {
     this.segments.length = 0;
     this.segments.push([this.animationData.ip, this.animationData.op]);
-
     if (forceFlag) {
       this.checkSegments(0);
     }
   };
-
   AnimationItem.prototype.checkSegments = function (offset) {
     if (this.segments.length) {
       this.adjustSegment(this.segments.shift(), offset);
       return true;
     }
-
     return false;
   };
-
   AnimationItem.prototype.destroy = function (name) {
     if (name && this.name !== name || !this.renderer) {
       return;
     }
-
     this.renderer.destroy();
     this.imagePreloader.destroy();
     this.trigger('destroy');
@@ -2345,189 +1969,148 @@
     this.imagePreloader = null;
     this.projectInterface = null;
   };
-
   AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
     this.currentRawFrame = value;
     this.gotoFrame();
   };
-
   AnimationItem.prototype.setSpeed = function (val) {
     this.playSpeed = val;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setDirection = function (val) {
     this.playDirection = val < 0 ? -1 : 1;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setLoop = function (isLooping) {
     this.loop = isLooping;
   };
-
   AnimationItem.prototype.setVolume = function (val, name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.setVolume(val);
   };
-
   AnimationItem.prototype.getVolume = function () {
     return this.audioController.getVolume();
   };
-
   AnimationItem.prototype.mute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.mute();
   };
-
   AnimationItem.prototype.unmute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.unmute();
   };
-
   AnimationItem.prototype.updaFrameModifier = function () {
     this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
     this.audioController.setRate(this.playSpeed * this.playDirection);
   };
-
   AnimationItem.prototype.getPath = function () {
     return this.path;
   };
-
   AnimationItem.prototype.getAssetsPath = function (assetData) {
     var path = '';
-
     if (assetData.e) {
       path = assetData.p;
     } else if (this.assetsPath) {
       var imagePath = assetData.p;
-
       if (imagePath.indexOf('images/') !== -1) {
         imagePath = imagePath.split('/')[1];
       }
-
       path = this.assetsPath + imagePath;
     } else {
       path = this.path;
       path += assetData.u ? assetData.u : '';
       path += assetData.p;
     }
-
     return path;
   };
-
   AnimationItem.prototype.getAssetData = function (id) {
     var i = 0;
     var len = this.assets.length;
-
     while (i < len) {
       if (id === this.assets[i].id) {
         return this.assets[i];
       }
-
       i += 1;
     }
-
     return null;
   };
-
   AnimationItem.prototype.hide = function () {
     this.renderer.hide();
   };
-
   AnimationItem.prototype.show = function () {
     this.renderer.show();
   };
-
   AnimationItem.prototype.getDuration = function (isFrame) {
     return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
   };
-
   AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
     try {
       var element = this.renderer.getElementByPath(path);
       element.updateDocumentData(documentData, index);
-    } catch (error) {// TODO: decide how to handle catch case
+    } catch (error) {
+      // TODO: decide how to handle catch case
     }
   };
-
   AnimationItem.prototype.trigger = function (name) {
     if (this._cbs && this._cbs[name]) {
       switch (name) {
         case 'enterFrame':
           this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
           break;
-
         case 'drawnFrame':
           this.drawnFrameEvent.currentTime = this.currentFrame;
           this.drawnFrameEvent.totalTime = this.totalFrames;
           this.drawnFrameEvent.direction = this.frameModifier;
           this.triggerEvent(name, this.drawnFrameEvent);
           break;
-
         case 'loopComplete':
           this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
           break;
-
         case 'complete':
           this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
           break;
-
         case 'segmentStart':
           this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
           break;
-
         case 'destroy':
           this.triggerEvent(name, new BMDestroyEvent(name, this));
           break;
-
         default:
           this.triggerEvent(name);
       }
     }
-
     if (name === 'enterFrame' && this.onEnterFrame) {
       this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
     }
-
     if (name === 'loopComplete' && this.onLoopComplete) {
       this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
     }
-
     if (name === 'complete' && this.onComplete) {
       this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
     }
-
     if (name === 'segmentStart' && this.onSegmentStart) {
       this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
     }
-
     if (name === 'destroy' && this.onDestroy) {
       this.onDestroy.call(this, new BMDestroyEvent(name, this));
     }
   };
-
   AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
     var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
   };
-
   AnimationItem.prototype.triggerConfigError = function (nativeError) {
     var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
@@ -2541,68 +2124,53 @@
     var playingAnimationsNum = 0;
     var _stopped = true;
     var _isFrozen = false;
-
     function removeElement(ev) {
       var i = 0;
       var animItem = ev.target;
-
       while (i < len) {
         if (registeredAnimations[i].animation === animItem) {
           registeredAnimations.splice(i, 1);
           i -= 1;
           len -= 1;
-
           if (!animItem.isPaused) {
             subtractPlayingCount();
           }
         }
-
         i += 1;
       }
     }
-
     function registerAnimation(element, animationData) {
       if (!element) {
         return null;
       }
-
       var i = 0;
-
       while (i < len) {
         if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
           return registeredAnimations[i].animation;
         }
-
         i += 1;
       }
-
       var animItem = new AnimationItem();
       setupAnimation(animItem, element);
       animItem.setData(element, animationData);
       return animItem;
     }
-
     function getRegisteredAnimations() {
       var i;
       var lenAnims = registeredAnimations.length;
       var animations = [];
-
       for (i = 0; i < lenAnims; i += 1) {
         animations.push(registeredAnimations[i].animation);
       }
-
       return animations;
     }
-
     function addPlayingCount() {
       playingAnimationsNum += 1;
       activate();
     }
-
     function subtractPlayingCount() {
       playingAnimationsNum -= 1;
     }
-
     function setupAnimation(animItem, element) {
       animItem.addEventListener('destroy', removeElement);
       animItem.addEventListener('_active', addPlayingCount);
@@ -2613,118 +2181,91 @@
       });
       len += 1;
     }
-
     function loadAnimation(params) {
       var animItem = new AnimationItem();
       setupAnimation(animItem, null);
       animItem.setParams(params);
       return animItem;
     }
-
     function setSpeed(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setSpeed(val, animation);
       }
     }
-
     function setDirection(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setDirection(val, animation);
       }
     }
-
     function play(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.play(animation);
       }
     }
-
     function resume(nowTime) {
       var elapsedTime = nowTime - initTime;
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.advanceTime(elapsedTime);
       }
-
       initTime = nowTime;
-
       if (playingAnimationsNum && !_isFrozen) {
         window.requestAnimationFrame(resume);
       } else {
         _stopped = true;
       }
     }
-
     function first(nowTime) {
       initTime = nowTime;
       window.requestAnimationFrame(resume);
     }
-
     function pause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.pause(animation);
       }
     }
-
     function goToAndStop(value, isFrame, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
       }
     }
-
     function stop(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.stop(animation);
       }
     }
-
     function togglePause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.togglePause(animation);
       }
     }
-
     function destroy(animation) {
       var i;
-
       for (i = len - 1; i >= 0; i -= 1) {
         registeredAnimations[i].animation.destroy(animation);
       }
     }
-
     function searchAnimations(animationData, standalone, renderer) {
       var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')), [].slice.call(document.getElementsByClassName('bodymovin')));
       var i;
       var lenAnims = animElements.length;
-
       for (i = 0; i < lenAnims; i += 1) {
         if (renderer) {
           animElements[i].setAttribute('data-bm-type', renderer);
         }
-
         registerAnimation(animElements[i], animationData);
       }
-
       if (standalone && lenAnims === 0) {
         if (!renderer) {
           renderer = 'svg';
         }
-
         var body = document.getElementsByTagName('body')[0];
         body.innerText = '';
         var div = createTag('div');
@@ -2735,15 +2276,12 @@
         registerAnimation(div, animationData);
       }
     }
-
     function resize() {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.resize();
       }
     }
-
     function activate() {
       if (!_isFrozen && playingAnimationsNum) {
         if (_stopped) {
@@ -2752,40 +2290,31 @@
         }
       }
     }
-
     function freeze() {
       _isFrozen = true;
     }
-
     function unfreeze() {
       _isFrozen = false;
       activate();
     }
-
     function setVolume(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setVolume(val, animation);
       }
     }
-
     function mute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.mute(animation);
       }
     }
-
     function unmute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.unmute(animation);
       }
     }
-
     moduleOb.registerAnimation = registerAnimation;
     moduleOb.loadAnimation = loadAnimation;
     moduleOb.setSpeed = setSpeed;
@@ -2795,8 +2324,8 @@
     moduleOb.stop = stop;
     moduleOb.togglePause = togglePause;
     moduleOb.searchAnimations = searchAnimations;
-    moduleOb.resize = resize; // moduleOb.start = start;
-
+    moduleOb.resize = resize;
+    // moduleOb.start = start;
     moduleOb.goToAndStop = goToAndStop;
     moduleOb.destroy = destroy;
     moduleOb.freeze = freeze;
@@ -2820,23 +2349,21 @@
        * spline.get(x) => returns the easing value | x must be in [0, 1] range
        *
        */
+
     var ob = {};
     ob.getBezierEasing = getBezierEasing;
     var beziers = {};
-
     function getBezierEasing(a, b, c, d, nm) {
       var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
-
       if (beziers[str]) {
         return beziers[str];
       }
-
       var bezEasing = new BezierEasing([a, b, c, d]);
       beziers[str] = bezEasing;
       return bezEasing;
-    } // These values are established by empiricism with tests (tradeoff: performance VS precision)
+    }
 
-
+    // These values are established by empiricism with tests (tradeoff: performance VS precision)
     var NEWTON_ITERATIONS = 4;
     var NEWTON_MIN_SLOPE = 0.001;
     var SUBDIVISION_PRECISION = 0.0000001;
@@ -2844,48 +2371,40 @@
     var kSplineTableSize = 11;
     var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
     var float32ArraySupported = typeof Float32Array === 'function';
-
     function A(aA1, aA2) {
       return 1.0 - 3.0 * aA2 + 3.0 * aA1;
     }
-
     function B(aA1, aA2) {
       return 3.0 * aA2 - 6.0 * aA1;
     }
-
     function C(aA1) {
       return 3.0 * aA1;
-    } // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+    }
 
-
+    // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
     function calcBezier(aT, aA1, aA2) {
       return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
-    } // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+    }
 
-
+    // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
     function getSlope(aT, aA1, aA2) {
       return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
     }
-
     function binarySubdivide(aX, aA, aB, mX1, mX2) {
       var currentX,
-          currentT,
-          i = 0;
-
+        currentT,
+        i = 0;
       do {
         currentT = aA + (aB - aA) / 2.0;
         currentX = calcBezier(currentT, mX1, mX2) - aX;
-
         if (currentX > 0.0) {
           aB = currentT;
         } else {
           aA = currentT;
         }
       } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
-
       return currentT;
     }
-
     function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
       for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
         var currentSlope = getSlope(aGuessT, mX1, mX2);
@@ -2893,85 +2412,75 @@
         var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
         aGuessT -= currentX / currentSlope;
       }
-
       return aGuessT;
     }
+
     /**
        * points is an array of [ mX1, mY1, mX2, mY2 ]
        */
-
-
     function BezierEasing(points) {
       this._p = points;
       this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
       this._precomputed = false;
       this.get = this.get.bind(this);
     }
-
     BezierEasing.prototype = {
       get: function get(x) {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         if (!this._precomputed) this._precompute();
         if (mX1 === mY1 && mX2 === mY2) return x; // linear
         // Because JavaScript number are imprecise, we should guarantee the extremes are right.
-
         if (x === 0) return 0;
         if (x === 1) return 1;
         return calcBezier(this._getTForX(x), mY1, mY2);
       },
       // Private part
+
       _precompute: function _precompute() {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         this._precomputed = true;
-
         if (mX1 !== mY1 || mX2 !== mY2) {
           this._calcSampleValues();
         }
       },
       _calcSampleValues: function _calcSampleValues() {
         var mX1 = this._p[0],
-            mX2 = this._p[2];
-
+          mX2 = this._p[2];
         for (var i = 0; i < kSplineTableSize; ++i) {
           this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
         }
       },
-
       /**
            * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
            */
       _getTForX: function _getTForX(aX) {
         var mX1 = this._p[0],
-            mX2 = this._p[2],
-            mSampleValues = this._mSampleValues;
+          mX2 = this._p[2],
+          mSampleValues = this._mSampleValues;
         var intervalStart = 0.0;
         var currentSample = 1;
         var lastSample = kSplineTableSize - 1;
-
         for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
           intervalStart += kSampleStepSize;
         }
+        --currentSample;
 
-        --currentSample; // Interpolate to provide an initial guess for t
-
+        // Interpolate to provide an initial guess for t
         var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
         var guessForT = intervalStart + dist * kSampleStepSize;
         var initialSlope = getSlope(guessForT, mX1, mX2);
-
         if (initialSlope >= NEWTON_MIN_SLOPE) {
           return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
         }
-
         if (initialSlope === 0.0) {
           return guessForT;
         }
-
         return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
       }
     };
@@ -2982,7 +2491,6 @@
     function _double(arr) {
       return arr.concat(createSizedArray(arr.length));
     }
-
     return {
       "double": _double
     };
@@ -2997,34 +2505,27 @@
         newElement: newElement,
         release: release
       };
-
       function newElement() {
         var element;
-
         if (_length) {
           _length -= 1;
           element = pool[_length];
         } else {
           element = _create();
         }
-
         return element;
       }
-
       function release(element) {
         if (_length === _maxLength) {
           pool = pooling["double"](pool);
           _maxLength *= 2;
         }
-
         if (_release) {
           _release(element);
         }
-
         pool[_length] = element;
         _length += 1;
       }
-
       return ob;
     };
   }();
@@ -3037,7 +2538,6 @@
         lengths: createTypedArray('float32', getDefaultCurveSegments())
       };
     }
-
     return poolFactory(8, create);
   }();
 
@@ -3048,39 +2548,31 @@
         totalLength: 0
       };
     }
-
     function release(element) {
       var i;
       var len = element.lengths.length;
-
       for (i = 0; i < len; i += 1) {
         bezierLengthPool.release(element.lengths[i]);
       }
-
       element.lengths.length = 0;
     }
-
     return poolFactory(8, create, release);
   }();
 
   function bezFunction() {
     var math = Math;
-
     function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
       var det1 = x1 * y2 + y1 * x3 + x2 * y3 - x3 * y2 - y3 * x1 - x2 * y1;
       return det1 > -0.001 && det1 < 0.001;
     }
-
     function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
       if (z1 === 0 && z2 === 0 && z3 === 0) {
         return pointOnLine2D(x1, y1, x2, y2, x3, y3);
       }
-
       var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
       var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
       var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
       var diffDist;
-
       if (dist1 > dist2) {
         if (dist1 > dist3) {
           diffDist = dist1 - dist2 - dist3;
@@ -3092,10 +2584,8 @@
       } else {
         diffDist = dist2 - dist1 - dist3;
       }
-
       return diffDist > -0.0001 && diffDist < 0.0001;
     }
-
     var getBezierLength = function () {
       return function (pt1, pt2, pt3, pt4) {
         var curveSegments = getDefaultCurveSegments();
@@ -3110,36 +2600,28 @@
         var lastPoint = [];
         var lengthData = bezierLengthPool.newElement();
         len = pt3.length;
-
         for (k = 0; k < curveSegments; k += 1) {
           perc = k / (curveSegments - 1);
           ptDistance = 0;
-
           for (i = 0; i < len; i += 1) {
             ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
             point[i] = ptCoord;
-
             if (lastPoint[i] !== null) {
               ptDistance += bmPow(point[i] - lastPoint[i], 2);
             }
-
             lastPoint[i] = point[i];
           }
-
           if (ptDistance) {
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
           }
-
           lengthData.percents[k] = perc;
           lengthData.lengths[k] = addedLength;
         }
-
         lengthData.addedLength = addedLength;
         return lengthData;
       };
     }();
-
     function getSegmentsLength(shapeData) {
       var segmentsLength = segmentsLengthPool.newElement();
       var closed = shapeData.c;
@@ -3150,36 +2632,29 @@
       var len = shapeData._length;
       var lengths = segmentsLength.lengths;
       var totalLength = 0;
-
       for (i = 0; i < len - 1; i += 1) {
         lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
         totalLength += lengths[i].addedLength;
       }
-
       if (closed && len) {
         lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
         totalLength += lengths[i].addedLength;
       }
-
       segmentsLength.totalLength = totalLength;
       return segmentsLength;
     }
-
     function BezierData(length) {
       this.segmentLength = 0;
       this.points = new Array(length);
     }
-
     function PointData(partial, point) {
       this.partialLength = partial;
       this.point = point;
     }
-
     var buildBezierData = function () {
       var storedData = {};
       return function (pt1, pt2, pt3, pt4) {
         var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
-
         if (!storedData[bezierName]) {
           var curveSegments = getDefaultCurveSegments();
           var k;
@@ -3191,42 +2666,33 @@
           var ptDistance;
           var point;
           var lastPoint = null;
-
           if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
             curveSegments = 2;
           }
-
           var bezierData = new BezierData(curveSegments);
           len = pt3.length;
-
           for (k = 0; k < curveSegments; k += 1) {
             point = createSizedArray(len);
             perc = k / (curveSegments - 1);
             ptDistance = 0;
-
             for (i = 0; i < len; i += 1) {
               ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
               point[i] = ptCoord;
-
               if (lastPoint !== null) {
                 ptDistance += bmPow(point[i] - lastPoint[i], 2);
               }
             }
-
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
             bezierData.points[k] = new PointData(ptDistance, point);
             lastPoint = point;
           }
-
           bezierData.segmentLength = addedLength;
           storedData[bezierName] = bezierData;
         }
-
         return storedData[bezierName];
       };
     }();
-
     function getDistancePerc(perc, bezierData) {
       var percents = bezierData.percents;
       var lengths = bezierData.lengths;
@@ -3234,14 +2700,11 @@
       var initPos = bmFloor((len - 1) * perc);
       var lengthPos = perc * bezierData.addedLength;
       var lPerc = 0;
-
       if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
         return percents[initPos];
       }
-
       var dir = lengths[initPos] > lengthPos ? -1 : 1;
       var flag = true;
-
       while (flag) {
         if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
           lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
@@ -3249,20 +2712,16 @@
         } else {
           initPos += dir;
         }
-
         if (initPos < 0 || initPos >= len - 1) {
           // FIX for TypedArrays that don't store floating point values with enough accuracy
           if (initPos === len - 1) {
             return percents[initPos];
           }
-
           flag = false;
         }
       }
-
       return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
     }
-
     function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
       var t1 = getDistancePerc(percent, bezierData);
       var u1 = 1 - t1;
@@ -3270,16 +2729,13 @@
       var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
       return [ptX, ptY];
     }
-
     var bezierSegmentPoints = createTypedArray('float32', 8);
-
     function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
       if (startPerc < 0) {
         startPerc = 0;
       } else if (startPerc > 1) {
         startPerc = 1;
       }
-
       var t0 = getDistancePerc(startPerc, bezierData);
       endPerc = endPerc > 1 ? 1 : endPerc;
       var t1 = getDistancePerc(endPerc, bezierData);
@@ -3289,45 +2745,31 @@
       var u1 = 1 - t1;
       var u0u0u0 = u0 * u0 * u0;
       var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
-
       var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
-
-      var t0t0t0 = t0 * t0 * t0; //
-
+      var t0t0t0 = t0 * t0 * t0;
+      //
       var u0u0u1 = u0 * u0 * u1;
       var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
-
       var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
-
-      var t0t0t1 = t0 * t0 * t1; //
-
+      var t0t0t1 = t0 * t0 * t1;
+      //
       var u0u1u1 = u0 * u1 * u1;
       var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
-
       var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
-
-      var t0t1t1 = t0 * t1 * t1; //
-
+      var t0t1t1 = t0 * t1 * t1;
+      //
       var u1u1u1 = u1 * u1 * u1;
       var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1t1 = t1 * t1 * t1;
-
       for (i = 0; i < len; i += 1) {
         bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
       }
-
       return bezierSegmentPoints;
     }
-
     return {
       getSegmentsLength: getSegmentsLength,
       getNewSegment: getNewSegment,
@@ -3337,20 +2779,16 @@
       pointOnLine3D: pointOnLine3D
     };
   }
-
   var bez = bezFunction();
 
   var initFrame = initialDefaultFrame;
   var mathAbs = Math.abs;
-
   function interpolateValue(frameNum, caching) {
     var offsetTime = this.offsetTime;
     var newValue;
-
     if (this.propType === 'multidimensional') {
       newValue = createTypedArray('float32', this.pv.length);
     }
-
     var iterationIndex = caching.lastIndex;
     var i = iterationIndex;
     var len = this.keyframes.length - 1;
@@ -3358,25 +2796,20 @@
     var keyData;
     var nextKeyData;
     var keyframeMetadata;
-
     while (flag) {
       keyData = this.keyframes[i];
       nextKeyData = this.keyframes[i + 1];
-
       if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
         if (keyData.h) {
           keyData = nextKeyData;
         }
-
         iterationIndex = 0;
         break;
       }
-
       if (nextKeyData.t - offsetTime > frameNum) {
         iterationIndex = i;
         break;
       }
-
       if (i < len - 1) {
         i += 1;
       } else {
@@ -3384,7 +2817,6 @@
         flag = false;
       }
     }
-
     keyframeMetadata = this.keyframesMetadata[i] || {};
     var k;
     var kLen;
@@ -3395,22 +2827,18 @@
     var nextKeyTime = nextKeyData.t - offsetTime;
     var keyTime = keyData.t - offsetTime;
     var endValue;
-
     if (keyData.to) {
       if (!keyframeMetadata.bezierData) {
         keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
       }
-
       var bezierData = keyframeMetadata.bezierData;
-
       if (frameNum >= nextKeyTime || frameNum < keyTime) {
         var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
         kLen = bezierData.points[ind].point.length;
-
         for (k = 0; k < kLen; k += 1) {
           newValue[k] = bezierData.points[ind].point[k];
-        } // caching._lastKeyframeIndex = -1;
-
+        }
+        // caching._lastKeyframeIndex = -1;
       } else {
         if (keyframeMetadata.__fnct) {
           fnc = keyframeMetadata.__fnct;
@@ -3418,7 +2846,6 @@
           fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
           keyframeMetadata.__fnct = fnc;
         }
-
         perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
         var distanceInLine = bezierData.segmentLength * perc;
         var segmentPerc;
@@ -3426,36 +2853,28 @@
         j = caching.lastFrame < frameNum && caching._lastKeyframeIndex === i ? caching._lastPoint : 0;
         flag = true;
         jLen = bezierData.points.length;
-
         while (flag) {
           addedLength += bezierData.points[j].partialLength;
-
           if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k];
             }
-
             break;
           } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
             segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
             }
-
             break;
           }
-
           if (j < jLen - 1) {
             j += 1;
           } else {
             flag = false;
           }
         }
-
         caching._lastPoint = j;
         caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
         caching._lastKeyframeIndex = i;
@@ -3468,7 +2887,6 @@
       var keyValue;
       len = keyData.s.length;
       endValue = nextKeyData.s || keyData.e;
-
       if (this.sh && keyData.h !== 1) {
         if (frameNum >= nextKeyTime) {
           newValue[0] = endValue[0];
@@ -3496,7 +2914,6 @@
                 if (!keyframeMetadata.__fnct) {
                   keyframeMetadata.__fnct = [];
                 }
-
                 if (!keyframeMetadata.__fnct[i]) {
                   outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
                   outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
@@ -3517,14 +2934,11 @@
               } else {
                 fnc = keyframeMetadata.__fnct;
               }
-
               perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
             }
           }
-
           endValue = nextKeyData.s || keyData.e;
           keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
-
           if (this.propType === 'multidimensional') {
             newValue[i] = keyValue;
           } else {
@@ -3533,12 +2947,11 @@
         }
       }
     }
-
     caching.lastIndex = iterationIndex;
     return newValue;
-  } // based on @Toji's https://github.com/toji/gl-matrix/
+  }
 
-
+  // based on @Toji's https://github.com/toji/gl-matrix/
   function slerp(a, b, t) {
     var out = [];
     var ax = a[0];
@@ -3555,7 +2968,6 @@
     var scale0;
     var scale1;
     cosom = ax * bx + ay * by + az * bz + aw * bw;
-
     if (cosom < 0.0) {
       cosom = -cosom;
       bx = -bx;
@@ -3563,7 +2975,6 @@
       bz = -bz;
       bw = -bw;
     }
-
     if (1.0 - cosom > 0.000001) {
       omega = Math.acos(cosom);
       sinom = Math.sin(omega);
@@ -3573,14 +2984,12 @@
       scale0 = 1.0 - t;
       scale1 = t;
     }
-
     out[0] = scale0 * ax + scale1 * bx;
     out[1] = scale0 * ay + scale1 * by;
     out[2] = scale0 * az + scale1 * bz;
     out[3] = scale0 * aw + scale1 * bw;
     return out;
   }
-
   function quaternionToEuler(out, quat) {
     var qx = quat[0];
     var qy = quat[1];
@@ -3593,7 +3002,6 @@
     out[1] = attitude / degToRads;
     out[2] = bank / degToRads;
   }
-
   function createQuaternion(values) {
     var heading = values[0] * degToRads;
     var attitude = values[1] * degToRads;
@@ -3610,32 +3018,25 @@
     var z = c1 * s2 * c3 - s1 * c2 * s3;
     return [x, y, z, w];
   }
-
   function getValueAtCurrentTime() {
     var frameNum = this.comp.renderedFrame - this.offsetTime;
     var initTime = this.keyframes[0].t - this.offsetTime;
     var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
-
     if (!(frameNum === this._caching.lastFrame || this._caching.lastFrame !== initFrame && (this._caching.lastFrame >= endTime && frameNum >= endTime || this._caching.lastFrame < initTime && frameNum < initTime))) {
       if (this._caching.lastFrame >= frameNum) {
         this._caching._lastKeyframeIndex = -1;
         this._caching.lastIndex = 0;
       }
-
       var renderResult = this.interpolateValue(frameNum, this._caching);
       this.pv = renderResult;
     }
-
     this._caching.lastFrame = frameNum;
     return this.pv;
   }
-
   function setVValue(val) {
     var multipliedValue;
-
     if (this.propType === 'unidimensional') {
       multipliedValue = val * this.mult;
-
       if (mathAbs(this.v - multipliedValue) > 0.00001) {
         this.v = multipliedValue;
         this._mdf = true;
@@ -3643,51 +3044,41 @@
     } else {
       var i = 0;
       var len = this.v.length;
-
       while (i < len) {
         multipliedValue = val[i] * this.mult;
-
         if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
           this.v[i] = multipliedValue;
           this._mdf = true;
         }
-
         i += 1;
       }
     }
   }
-
   function processEffectsSequence() {
     if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
       return;
     }
-
     if (this.lock) {
       this.setVValue(this.pv);
       return;
     }
-
     this.lock = true;
     this._mdf = this._isFirstFrame;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = this.kf ? this.pv : this.data.k;
-
     for (i = 0; i < len; i += 1) {
       finalValue = this.effectsSequence[i](finalValue);
     }
-
     this.setVValue(finalValue);
     this._isFirstFrame = false;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   }
-
   function addEffect(effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.container.addDynamicProperty(this);
   }
-
   function ValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.mult = mult || 1;
@@ -3707,7 +3098,6 @@
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function MultiDimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     this.mult = mult || 1;
@@ -3724,19 +3114,16 @@
     this.v = createTypedArray('float32', len);
     this.pv = createTypedArray('float32', len);
     this.vel = createTypedArray('float32', len);
-
     for (i = 0; i < len; i += 1) {
       this.v[i] = data.k[i] * this.mult;
       this.pv[i] = data.k[i];
     }
-
     this._isFirstFrame = true;
     this.effectsSequence = [];
     this.getValue = processEffectsSequence;
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function KeyframedValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.keyframes = data.k;
@@ -3765,7 +3152,6 @@
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.addEffect = addEffect;
   }
-
   function KeyframedMultidimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     var i;
@@ -3774,19 +3160,16 @@
     var e;
     var to;
     var ti;
-
     for (i = 0; i < len - 1; i += 1) {
       if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
         s = data.k[i].s;
         e = data.k[i + 1].s;
         to = data.k[i].to;
         ti = data.k[i].ti;
-
         if (s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1]) || s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2])) {
           data.k[i].to = null;
           data.k[i].ti = null;
         }
-
         if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
           if (s.length === 2 || s[2] === e[2] && to[2] === 0 && ti[2] === 0) {
             data.k[i].to = null;
@@ -3795,7 +3178,6 @@
         }
       }
     }
-
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.data = data;
     this.keyframes = data.k;
@@ -3815,12 +3197,10 @@
     var arrLen = data.k[0].s.length;
     this.v = createTypedArray('float32', arrLen);
     this.pv = createTypedArray('float32', arrLen);
-
     for (i = 0; i < arrLen; i += 1) {
       this.v[i] = initFrame;
       this.pv[i] = initFrame;
     }
-
     this._caching = {
       lastFrame: initFrame,
       lastIndex: 0,
@@ -3828,15 +3208,12 @@
     };
     this.addEffect = addEffect;
   }
-
   var PropertyFactory = function () {
     function getProp(elem, data, type, mult, container) {
       if (data.sid) {
         data = elem.globalData.slotManager.getProp(data);
       }
-
       var p;
-
       if (!data.k.length) {
         p = new ValueProperty(elem, data, mult, container);
       } else if (typeof data.k[0] === 'number') {
@@ -3846,23 +3223,18 @@
           case 0:
             p = new KeyframedValueProperty(elem, data, mult, container);
             break;
-
           case 1:
             p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
             break;
-
           default:
             break;
         }
       }
-
       if (p.effectsSequence.length) {
         container.addDynamicProperty(p);
       }
-
       return p;
     }
-
     var ob = {
       getProp: getProp
     };
@@ -3870,7 +3242,6 @@
   }();
 
   function DynamicPropertyContainer() {}
-
   DynamicPropertyContainer.prototype = {
     addDynamicProperty: function addDynamicProperty(prop) {
       if (this.dynamicProperties.indexOf(prop) === -1) {
@@ -3883,10 +3254,8 @@
       this._mdf = false;
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         this.dynamicProperties[i].getValue();
-
         if (this.dynamicProperties[i]._mdf) {
           this._mdf = true;
         }
@@ -3904,7 +3273,6 @@
     function create() {
       return createTypedArray('float32', 2);
     }
-
     return poolFactory(8, create);
   }();
 
@@ -3916,12 +3284,10 @@
     this.o = createSizedArray(this._maxLength);
     this.i = createSizedArray(this._maxLength);
   }
-
   ShapePath.prototype.setPathData = function (closed, len) {
     this.c = closed;
     this.setLength(len);
     var i = 0;
-
     while (i < len) {
       this.v[i] = pointPool.newElement();
       this.o[i] = pointPool.newElement();
@@ -3929,62 +3295,49 @@
       i += 1;
     }
   };
-
   ShapePath.prototype.setLength = function (len) {
     while (this._maxLength < len) {
       this.doubleArrayLength();
     }
-
     this._length = len;
   };
-
   ShapePath.prototype.doubleArrayLength = function () {
     this.v = this.v.concat(createSizedArray(this._maxLength));
     this.i = this.i.concat(createSizedArray(this._maxLength));
     this.o = this.o.concat(createSizedArray(this._maxLength));
     this._maxLength *= 2;
   };
-
   ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
     var arr;
     this._length = Math.max(this._length, pos + 1);
-
     if (this._length >= this._maxLength) {
       this.doubleArrayLength();
     }
-
     switch (type) {
       case 'v':
         arr = this.v;
         break;
-
       case 'i':
         arr = this.i;
         break;
-
       case 'o':
         arr = this.o;
         break;
-
       default:
         arr = [];
         break;
     }
-
     if (!arr[pos] || arr[pos] && !replace) {
       arr[pos] = pointPool.newElement();
     }
-
     arr[pos][0] = x;
     arr[pos][1] = y;
   };
-
   ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
     this.setXYAt(vX, vY, 'v', pos, replace);
     this.setXYAt(oX, oY, 'o', pos, replace);
     this.setXYAt(iX, iY, 'i', pos, replace);
   };
-
   ShapePath.prototype.reverse = function () {
     var newPath = new ShapePath();
     newPath.setPathData(this.c, this._length);
@@ -3992,24 +3345,19 @@
     var outPoints = this.o;
     var inPoints = this.i;
     var init = 0;
-
     if (this.c) {
       newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
       init = 1;
     }
-
     var cnt = this._length - 1;
     var len = this._length;
     var i;
-
     for (i = init; i < len; i += 1) {
       newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
       cnt -= 1;
     }
-
     return newPath;
   };
-
   ShapePath.prototype.length = function () {
     return this._length;
   };
@@ -4018,11 +3366,9 @@
     function create() {
       return new ShapePath();
     }
-
     function release(shapePath) {
       var len = shapePath._length;
       var i;
-
       for (i = 0; i < len; i += 1) {
         pointPool.release(shapePath.v[i]);
         pointPool.release(shapePath.i[i]);
@@ -4031,25 +3377,20 @@
         shapePath.i[i] = null;
         shapePath.o[i] = null;
       }
-
       shapePath._length = 0;
       shapePath.c = false;
     }
-
     function clone(shape) {
       var cloned = factory.newElement();
       var i;
       var len = shape._length === undefined ? shape.v.length : shape._length;
       cloned.setLength(len);
       cloned.c = shape.c;
-
       for (i = 0; i < len; i += 1) {
         cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
       }
-
       return cloned;
     }
-
     var factory = poolFactory(4, create, release);
     factory.clone = clone;
     return factory;
@@ -4060,24 +3401,19 @@
     this._maxLength = 4;
     this.shapes = createSizedArray(this._maxLength);
   }
-
   ShapeCollection.prototype.addShape = function (shapeData) {
     if (this._length === this._maxLength) {
       this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
       this._maxLength *= 2;
     }
-
     this.shapes[this._length] = shapeData;
     this._length += 1;
   };
-
   ShapeCollection.prototype.releaseShapes = function () {
     var i;
-
     for (i = 0; i < this._length; i += 1) {
       shapePool.release(this.shapes[i]);
     }
-
     this._length = 0;
   };
 
@@ -4089,45 +3425,35 @@
     var _length = 0;
     var _maxLength = 4;
     var pool = createSizedArray(_maxLength);
-
     function newShapeCollection() {
       var shapeCollection;
-
       if (_length) {
         _length -= 1;
         shapeCollection = pool[_length];
       } else {
         shapeCollection = new ShapeCollection();
       }
-
       return shapeCollection;
     }
-
     function release(shapeCollection) {
       var i;
       var len = shapeCollection._length;
-
       for (i = 0; i < len; i += 1) {
         shapePool.release(shapeCollection.shapes[i]);
       }
-
       shapeCollection._length = 0;
-
       if (_length === _maxLength) {
         pool = pooling["double"](pool);
         _maxLength *= 2;
       }
-
       pool[_length] = shapeCollection;
       _length += 1;
     }
-
     return ob;
   }();
 
   var ShapePropertyFactory = function () {
     var initFrame = -999999;
-
     function interpolateShape(frameNum, previousValue, caching) {
       var iterationIndex = caching.lastIndex;
       var keyPropS;
@@ -4140,7 +3466,6 @@
       var perc;
       var vertexValue;
       var kf = this.keyframes;
-
       if (frameNum < kf[0].t - this.offsetTime) {
         keyPropS = kf[0].s[0];
         isHold = true;
@@ -4152,7 +3477,6 @@
               }else{
                   keyPropS = kf[kf.length - 2].e[0];
               } */
-
         isHold = true;
       } else {
         var i = iterationIndex;
@@ -4161,26 +3485,21 @@
         var keyData;
         var nextKeyData;
         var keyframeMetadata;
-
         while (flag) {
           keyData = kf[i];
           nextKeyData = kf[i + 1];
-
           if (nextKeyData.t - this.offsetTime > frameNum) {
             break;
           }
-
           if (i < len - 1) {
             i += 1;
           } else {
             flag = false;
           }
         }
-
         keyframeMetadata = this.keyframesMetadata[i] || {};
         isHold = keyData.h === 1;
         iterationIndex = i;
-
         if (!isHold) {
           if (frameNum >= nextKeyData.t - this.offsetTime) {
             perc = 1;
@@ -4188,27 +3507,21 @@
             perc = 0;
           } else {
             var fnc;
-
             if (keyframeMetadata.__fnct) {
               fnc = keyframeMetadata.__fnct;
             } else {
               fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
               keyframeMetadata.__fnct = fnc;
             }
-
             perc = fnc((frameNum - (keyData.t - this.offsetTime)) / (nextKeyData.t - this.offsetTime - (keyData.t - this.offsetTime)));
           }
-
           keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
         }
-
         keyPropS = keyData.s[0];
       }
-
       jLen = previousValue._length;
       kLen = keyPropS.i[0].length;
       caching.lastIndex = iterationIndex;
-
       for (j = 0; j < jLen; j += 1) {
         for (k = 0; k < kLen; k += 1) {
           vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
@@ -4220,44 +3533,36 @@
         }
       }
     }
-
     function interpolateShapeCurrentTime() {
       var frameNum = this.comp.renderedFrame - this.offsetTime;
       var initTime = this.keyframes[0].t - this.offsetTime;
       var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
       var lastFrame = this._caching.lastFrame;
-
       if (!(lastFrame !== initFrame && (lastFrame < initTime && frameNum < initTime || lastFrame > endTime && frameNum > endTime))) {
         /// /
         this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
-        this.interpolateShape(frameNum, this.pv, this._caching); /// /
+        this.interpolateShape(frameNum, this.pv, this._caching);
+        /// /
       }
-
       this._caching.lastFrame = frameNum;
       return this.pv;
     }
-
     function resetShape() {
       this.paths = this.localShapeCollection;
     }
-
     function shapesEqual(shape1, shape2) {
       if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
         return false;
       }
-
       var i;
       var len = shape1._length;
-
       for (i = 0; i < len; i += 1) {
         if (shape1.v[i][0] !== shape2.v[i][0] || shape1.v[i][1] !== shape2.v[i][1] || shape1.o[i][0] !== shape2.o[i][0] || shape1.o[i][1] !== shape2.o[i][1] || shape1.i[i][0] !== shape2.i[i][0] || shape1.i[i][1] !== shape2.i[i][1]) {
           return false;
         }
       }
-
       return true;
     }
-
     function setVValue(newPath) {
       if (!shapesEqual(this.v, newPath)) {
         this.v = shapePool.clone(newPath);
@@ -4267,26 +3572,21 @@
         this.paths = this.localShapeCollection;
       }
     }
-
     function processEffectsSequence() {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (!this.effectsSequence.length) {
         this._mdf = false;
         return;
       }
-
       if (this.lock) {
         this.setVValue(this.pv);
         return;
       }
-
       this.lock = true;
       this._mdf = false;
       var finalValue;
-
       if (this.kf) {
         finalValue = this.pv;
       } else if (this.data.ks) {
@@ -4294,19 +3594,15 @@
       } else {
         finalValue = this.data.pt.k;
       }
-
       var i;
       var len = this.effectsSequence.length;
-
       for (i = 0; i < len; i += 1) {
         finalValue = this.effectsSequence[i](finalValue);
       }
-
       this.setVValue(finalValue);
       this.lock = false;
       this.frameId = this.elem.globalData.frameId;
     }
-
     function ShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4325,17 +3621,14 @@
       this.reset = resetShape;
       this.effectsSequence = [];
     }
-
     function addEffect(effectFunction) {
       this.effectsSequence.push(effectFunction);
       this.container.addDynamicProperty(this);
     }
-
     ShapeProperty.prototype.interpolateShape = interpolateShape;
     ShapeProperty.prototype.getValue = processEffectsSequence;
     ShapeProperty.prototype.setVValue = setVValue;
     ShapeProperty.prototype.addEffect = addEffect;
-
     function KeyframedShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4361,15 +3654,12 @@
       };
       this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
     }
-
     KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
     KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
     KeyframedShapeProperty.prototype.setVValue = setVValue;
     KeyframedShapeProperty.prototype.addEffect = addEffect;
-
     var EllShapeProperty = function () {
       var cPoint = roundCorner;
-
       function EllShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
         this.v.setPathData(true, 4);
@@ -4383,7 +3673,6 @@
         this.initDynamicPropertyContainer(elem);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4391,17 +3680,14 @@
           this.convertEllToPath();
         }
       }
-
       EllShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertEllToPath();
           }
@@ -4411,9 +3697,7 @@
           var p1 = this.p.v[1];
           var s0 = this.s.v[0] / 2;
           var s1 = this.s.v[1] / 2;
-
           var _cw = this.d !== 3;
-
           var _v = this.v;
           _v.v[0][0] = p0;
           _v.v[0][1] = p1 - s1;
@@ -4444,7 +3728,6 @@
       extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
       return EllShapePropertyFactory;
     }();
-
     var StarShapeProperty = function () {
       function StarShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4455,7 +3738,6 @@
         this.frameId = -1;
         this.d = data.d;
         this.initDynamicPropertyContainer(elem);
-
         if (data.sy === 1) {
           this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
           this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
@@ -4463,7 +3745,6 @@
         } else {
           this.convertToPath = this.convertPolygonToPath;
         }
-
         this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
@@ -4472,7 +3753,6 @@
         this.localShapeCollection = shapeCollectionPool.newShapeCollection();
         this.localShapeCollection.addShape(this.v);
         this.paths = this.localShapeCollection;
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4480,17 +3760,14 @@
           this.convertToPath();
         }
       }
-
       StarShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertToPath();
           }
@@ -4501,7 +3778,6 @@
           /* this.v.v.length = numPts;
                   this.v.i.length = numPts;
                   this.v.o.length = numPts; */
-
           var longFlag = true;
           var longRad = this.or.v;
           var shortRad = this.ir.v;
@@ -4517,7 +3793,6 @@
           currentAng += this.r.v;
           var dir = this.data.d === 3 ? -1 : 1;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             rad = longFlag ? longRad : shortRad;
             roundness = longFlag ? longRound : shortRound;
@@ -4529,11 +3804,11 @@
             x += +this.p.v[0];
             y += +this.p.v[1];
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
             /* this.v.v[i] = [x,y];
                       this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
                       this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
                       this.v._length = numPts; */
-
             longFlag = !longFlag;
             currentAng += angle * dir;
           }
@@ -4549,7 +3824,6 @@
           var dir = this.data.d === 3 ? -1 : 1;
           currentAng += this.r.v;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             var x = rad * Math.cos(currentAng);
             var y = rad * Math.sin(currentAng);
@@ -4560,7 +3834,6 @@
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
             currentAng += angle * dir;
           }
-
           this.paths.length = 0;
           this.paths[0] = this.v;
         }
@@ -4568,7 +3841,6 @@
       extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
       return StarShapePropertyFactory;
     }();
-
     var RectShapeProperty = function () {
       function RectShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4584,7 +3856,6 @@
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4592,7 +3863,6 @@
           this.convertRectToPath();
         }
       }
-
       RectShapePropertyFactory.prototype = {
         convertRectToPath: function convertRectToPath() {
           var p0 = this.p.v[0];
@@ -4602,11 +3872,9 @@
           var round = bmMin(v0, v1, this.r.v);
           var cPoint = round * (1 - roundCorner);
           this.v._length = 0;
-
           if (this.d === 2 || this.d === 1) {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
             this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
               this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
@@ -4620,7 +3888,6 @@
             }
           } else {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
               this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
@@ -4640,10 +3907,8 @@
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertRectToPath();
           }
@@ -4653,14 +3918,11 @@
       extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
       return RectShapePropertyFactory;
     }();
-
     function getShapeProp(elem, data, type) {
       var prop;
-
       if (type === 3 || type === 4) {
         var dataProp = type === 3 ? data.pt : data.ks;
         var keys = dataProp.k;
-
         if (keys.length) {
           prop = new KeyframedShapeProperty(elem, data, type);
         } else {
@@ -4673,22 +3935,17 @@
       } else if (type === 7) {
         prop = new StarShapeProperty(elem, data);
       }
-
       if (prop.k) {
         elem.addDynamicProperty(prop);
       }
-
       return prop;
     }
-
     function getConstructorFunction() {
       return ShapeProperty;
     }
-
     function getKeyframedConstructorFunction() {
       return KeyframedShapeProperty;
     }
-
     var ob = {};
     ob.getShapeProp = getShapeProp;
     ob.getConstructorFunction = getConstructorFunction;
@@ -4730,7 +3987,6 @@
     var _sin = Math.sin;
     var _tan = Math.tan;
     var _rnd = Math.round;
-
     function reset() {
       this.props[0] = 1;
       this.props[1] = 0;
@@ -4750,83 +4006,59 @@
       this.props[15] = 1;
       return this;
     }
-
     function rotate(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function rotateX(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateY(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateZ(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function shear(sx, sy) {
       return this._t(1, sy, sx, 1, 0, 0);
     }
-
     function skew(ax, ay) {
       return this.shear(_tan(ax), _tan(ay));
     }
-
     function skewFromAxis(ax, angle) {
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
-      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+      // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
     }
-
     function scale(sx, sy, sz) {
       if (!sz && sz !== 0) {
         sz = 1;
       }
-
       if (sx === 1 && sy === 1 && sz === 1) {
         return this;
       }
-
       return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
     }
-
     function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
       this.props[0] = a;
       this.props[1] = b;
@@ -4846,32 +4078,26 @@
       this.props[15] = p;
       return this;
     }
-
     function translate(tx, ty, tz) {
       tz = tz || 0;
-
       if (tx !== 0 || ty !== 0 || tz !== 0) {
         return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
       }
-
       return this;
     }
-
     function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
       var _p = this.props;
-
       if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
         // NOTE: commenting this condition because TurboFan deoptimizes code when present
         // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
         _p[12] = _p[12] * a2 + _p[15] * m2;
         _p[13] = _p[13] * f2 + _p[15] * n2;
         _p[14] = _p[14] * k2 + _p[15] * o2;
-        _p[15] *= p2; // }
-
+        _p[15] *= p2;
+        // }
         this._identityCalculated = false;
         return this;
       }
-
       var a1 = _p[0];
       var b1 = _p[1];
       var c1 = _p[2];
@@ -4888,12 +4114,12 @@
       var n1 = _p[13];
       var o1 = _p[14];
       var p1 = _p[15];
+
       /* matrix order (canvas compatible):
            * ace
            * bdf
            * 001
            */
-
       _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
       _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
       _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
@@ -4913,53 +4139,40 @@
       this._identityCalculated = false;
       return this;
     }
-
     function multiply(matrix) {
       var matrixProps = matrix.props;
       return this.transform(matrixProps[0], matrixProps[1], matrixProps[2], matrixProps[3], matrixProps[4], matrixProps[5], matrixProps[6], matrixProps[7], matrixProps[8], matrixProps[9], matrixProps[10], matrixProps[11], matrixProps[12], matrixProps[13], matrixProps[14], matrixProps[15]);
     }
-
     function isIdentity() {
       if (!this._identityCalculated) {
         this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
         this._identityCalculated = true;
       }
-
       return this._identity;
     }
-
     function equals(matr) {
       var i = 0;
-
       while (i < 16) {
         if (matr.props[i] !== this.props[i]) {
           return false;
         }
-
         i += 1;
       }
-
       return true;
     }
-
     function clone(matr) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         matr.props[i] = this.props[i];
       }
-
       return matr;
     }
-
     function cloneFromProps(props) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         this.props[i] = props[i];
       }
     }
-
     function applyToPoint(x, y, z) {
       return {
         x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
@@ -4971,19 +4184,15 @@
            y: x * me.b + y * me.d + me.f
            }; */
     }
-
     function applyToX(x, y, z) {
       return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
     }
-
     function applyToY(x, y, z) {
       return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
     }
-
     function applyToZ(x, y, z) {
       return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
     }
-
     function getInverseMatrix() {
       var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
       var a = this.props[5] / determinant;
@@ -5001,27 +4210,21 @@
       inverseMatrix.props[13] = f;
       return inverseMatrix;
     }
-
     function inversePoint(pt) {
       var inverseMatrix = this.getInverseMatrix();
       return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
     }
-
     function inversePoints(pts) {
       var i;
       var len = pts.length;
       var retPts = [];
-
       for (i = 0; i < len; i += 1) {
         retPts[i] = inversePoint(pts[i]);
       }
-
       return retPts;
     }
-
     function applyToTriplePoints(pt1, pt2, pt3) {
       var arr = createTypedArray('float32', 6);
-
       if (this.isIdentity()) {
         arr[0] = pt1[0];
         arr[1] = pt1[1];
@@ -5043,34 +4246,26 @@
         arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
         arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
       }
-
       return arr;
     }
-
     function applyToPointArray(x, y, z) {
       var arr;
-
       if (this.isIdentity()) {
         arr = [x, y, z];
       } else {
         arr = [x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12], x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13], x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14]];
       }
-
       return arr;
     }
-
     function applyToPointStringified(x, y) {
       if (this.isIdentity()) {
         return x + ',' + y;
       }
-
       var _p = this.props;
       return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
     }
-
     function toCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
@@ -5078,49 +4273,34 @@
       var props = this.props;
       var cssValue = 'matrix3d(';
       var v = 10000;
-
       while (i < 16) {
         cssValue += _rnd(props[i] * v) / v;
         cssValue += i === 15 ? ')' : ',';
         i += 1;
       }
-
       return cssValue;
     }
-
     function roundMatrixProperty(val) {
       var v = 10000;
-
       if (val < 0.000001 && val > 0 || val > -0.000001 && val < 0) {
         return _rnd(val * v) / v;
       }
-
       return val;
     }
-
     function to2dCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
       var props = this.props;
-
       var _a = roundMatrixProperty(props[0]);
-
       var _b = roundMatrixProperty(props[1]);
-
       var _c = roundMatrixProperty(props[4]);
-
       var _d = roundMatrixProperty(props[5]);
-
       var _e = roundMatrixProperty(props[12]);
-
       var _f = roundMatrixProperty(props[13]);
-
       return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
     }
-
     return function () {
       this.reset = reset;
       this.rotate = rotate;
@@ -5159,16 +4339,14 @@
     };
   }();
 
-  function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
   var lottie = {};
   var standalone = '__[STANDALONE]__';
   var animationData = '__[ANIMATIONDATA]__';
   var renderer = '';
-
   function setLocation(href) {
     setLocationHref(href);
   }
-
   function searchAnimations() {
     if (standalone === true) {
       animationManager.searchAnimations(animationData, standalone, renderer);
@@ -5176,35 +4354,28 @@
       animationManager.searchAnimations();
     }
   }
-
   function setSubframeRendering(flag) {
     setSubframeEnabled(flag);
   }
-
   function setPrefix(prefix) {
     setIdPrefix(prefix);
   }
-
   function loadAnimation(params) {
     if (standalone === true) {
       params.animationData = JSON.parse(animationData);
     }
-
     return animationManager.loadAnimation(params);
   }
-
   function setQuality(value) {
     if (typeof value === 'string') {
       switch (value) {
         case 'high':
           setDefaultCurveSegments(200);
           break;
-
         default:
         case 'medium':
           setDefaultCurveSegments(50);
           break;
-
         case 'low':
           setDefaultCurveSegments(10);
           break;
@@ -5212,40 +4383,32 @@
     } else if (!isNaN(value) && value > 1) {
       setDefaultCurveSegments(value);
     }
-
     if (getDefaultCurveSegments() >= 50) {
       roundValues(false);
     } else {
       roundValues(true);
     }
   }
-
   function inBrowser() {
     return typeof navigator !== 'undefined';
   }
-
   function installPlugin(type, plugin) {
     if (type === 'expressions') {
       setExpressionsPlugin(plugin);
     }
   }
-
   function getFactory(name) {
     switch (name) {
       case 'propertyFactory':
         return PropertyFactory;
-
       case 'shapePropertyFactory':
         return ShapePropertyFactory;
-
       case 'matrix':
         return Matrix;
-
       default:
         return null;
     }
   }
-
   lottie.play = animationManager.play;
   lottie.pause = animationManager.pause;
   lottie.setLocationHref = setLocation;
@@ -5257,8 +4420,8 @@
   lottie.registerAnimation = animationManager.registerAnimation;
   lottie.loadAnimation = loadAnimation;
   lottie.setSubframeRendering = setSubframeRendering;
-  lottie.resize = animationManager.resize; // lottie.start = start;
-
+  lottie.resize = animationManager.resize;
+  // lottie.start = start;
   lottie.goToAndStop = animationManager.goToAndStop;
   lottie.destroy = animationManager.destroy;
   lottie.setQuality = setQuality;
@@ -5273,32 +4436,25 @@
   lottie.useWebWorker = setWebWorker;
   lottie.setIDPrefix = setPrefix;
   lottie.__getFactory = getFactory;
-  lottie.version = '5.12.2';
-
+  lottie.version = '5.13.0';
   function checkReady() {
     if (document.readyState === 'complete') {
       clearInterval(readyStateCheckInterval);
       searchAnimations();
     }
   }
-
   function getQueryVariable(variable) {
     var vars = queryString.split('&');
-
     for (var i = 0; i < vars.length; i += 1) {
       var pair = vars[i].split('=');
-
       if (decodeURIComponent(pair[0]) == variable) {
         // eslint-disable-line eqeqeq
         return decodeURIComponent(pair[1]);
       }
     }
-
     return null;
   }
-
   var queryString = '';
-
   if (standalone) {
     var scripts = document.getElementsByTagName('script');
     var index = scripts.length - 1;
@@ -5306,18 +4462,18 @@
       src: ''
     };
     queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
-
     renderer = getQueryVariable('renderer');
   }
+  var readyStateCheckInterval = setInterval(checkReady, 100);
 
-  var readyStateCheckInterval = setInterval(checkReady, 100); // this adds bodymovin to the window object for backwards compatibility
-
+  // this adds bodymovin to the window object for backwards compatibility
   try {
     if (!((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === 'object' && typeof module !== 'undefined') && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
     ) {
       window.bodymovin = lottie;
     }
-  } catch (err) {//
+  } catch (err) {
+    //
   }
 
   var ShapeModifiers = function () {
@@ -5325,26 +4481,19 @@
     var modifiers = {};
     ob.registerModifier = registerModifier;
     ob.getModifier = getModifier;
-
     function registerModifier(nm, factory) {
       if (!modifiers[nm]) {
         modifiers[nm] = factory;
       }
     }
-
     function getModifier(nm, elem, data) {
       return new modifiers[nm](elem, data);
     }
-
     return ob;
   }();
-
   function ShapeModifier() {}
-
   ShapeModifier.prototype.initModifierProperties = function () {};
-
   ShapeModifier.prototype.addShapeToModifier = function () {};
-
   ShapeModifier.prototype.addShape = function (data) {
     if (!this.closed) {
       // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
@@ -5356,13 +4505,11 @@
       };
       this.shapes.push(shapeData);
       this.addShapeToModifier(shapeData);
-
       if (this._isAnimated) {
         data.setAsAnimated();
       }
     }
   };
-
   ShapeModifier.prototype.init = function (elem, data) {
     this.shapes = [];
     this.elem = elem;
@@ -5371,29 +4518,23 @@
     this.frameId = initialDefaultFrame;
     this.closed = false;
     this.k = false;
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   ShapeModifier.prototype.processKeys = function () {
     if (this.elem.globalData.frameId === this.frameId) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   extendPrototype([DynamicPropertyContainer], ShapeModifier);
 
   function TrimModifier() {}
-
   extendPrototype([ShapeModifier], TrimModifier);
-
   TrimModifier.prototype.initModifierProperties = function (elem, data) {
     this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
     this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
@@ -5404,14 +4545,11 @@
     this.m = data.m;
     this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
   };
-
   TrimModifier.prototype.addShapeToModifier = function (shapeData) {
     shapeData.pathsData = [];
   };
-
   TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
     var segments = [];
-
     if (e <= 1) {
       segments.push({
         s: s,
@@ -5432,65 +4570,50 @@
         e: e - 1
       });
     }
-
     var shapeSegments = [];
     var i;
     var len = segments.length;
     var segmentOb;
-
     for (i = 0; i < len; i += 1) {
       segmentOb = segments[i];
-
       if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
         var shapeS;
         var shapeE;
-
         if (segmentOb.s * totalModifierLength <= addedLength) {
           shapeS = 0;
         } else {
           shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
         }
-
         if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
           shapeE = 1;
         } else {
           shapeE = (segmentOb.e * totalModifierLength - addedLength) / shapeLength;
         }
-
         shapeSegments.push([shapeS, shapeE]);
       }
     }
-
     if (!shapeSegments.length) {
       shapeSegments.push([0, 0]);
     }
-
     return shapeSegments;
   };
-
   TrimModifier.prototype.releasePathsData = function (pathsData) {
     var i;
     var len = pathsData.length;
-
     for (i = 0; i < len; i += 1) {
       segmentsLengthPool.release(pathsData[i]);
     }
-
     pathsData.length = 0;
     return pathsData;
   };
-
   TrimModifier.prototype.processShapes = function (_isFirstFrame) {
     var s;
     var e;
-
     if (this._mdf || _isFirstFrame) {
       var o = this.o.v % 360 / 360;
-
       if (o < 0) {
         o += 1;
       }
-
       if (this.s.v > 1) {
         s = 1 + o;
       } else if (this.s.v < 0) {
@@ -5498,7 +4621,6 @@
       } else {
         s = this.s.v + o;
       }
-
       if (this.e.v > 1) {
         e = 1 + o;
       } else if (this.e.v < 0) {
@@ -5506,13 +4628,11 @@
       } else {
         e = this.e.v + o;
       }
-
       if (s > e) {
         var _s = s;
         s = e;
         e = _s;
       }
-
       s = Math.round(s * 10000) * 0.0001;
       e = Math.round(e * 10000) * 0.0001;
       this.sValue = s;
@@ -5521,7 +4641,6 @@
       s = this.sValue;
       e = this.eValue;
     }
-
     var shapePaths;
     var i;
     var len = this.shapes.length;
@@ -5531,13 +4650,11 @@
     var pathData;
     var totalShapeLength;
     var totalModifierLength = 0;
-
     if (e === s) {
       for (i = 0; i < len; i += 1) {
         this.shapes[i].localShapeCollection.releaseShapes();
         this.shapes[i].shape._mdf = true;
         this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
-
         if (this._mdf) {
           this.shapes[i].pathsData.length = 0;
         }
@@ -5546,63 +4663,52 @@
       var segments = [];
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
-        shapeData = this.shapes[i]; // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
-
+        shapeData = this.shapes[i];
+        // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
         if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
           shapeData.shape.paths = shapeData.localShapeCollection;
         } else {
           shapePaths = shapeData.shape.paths;
           jLen = shapePaths._length;
           totalShapeLength = 0;
-
           if (!shapeData.shape._mdf && shapeData.pathsData.length) {
             totalShapeLength = shapeData.totalShapeLength;
           } else {
             pathsData = this.releasePathsData(shapeData.pathsData);
-
             for (j = 0; j < jLen; j += 1) {
               pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
               pathsData.push(pathData);
               totalShapeLength += pathData.totalLength;
             }
-
             shapeData.totalShapeLength = totalShapeLength;
             shapeData.pathsData = pathsData;
           }
-
           totalModifierLength += totalShapeLength;
           shapeData.shape._mdf = true;
         }
       }
-
       var shapeS = s;
       var shapeE = e;
       var addedLength = 0;
       var edges;
-
       for (i = len - 1; i >= 0; i -= 1) {
         shapeData = this.shapes[i];
-
         if (shapeData.shape._mdf) {
           localShapeCollection = shapeData.localShapeCollection;
-          localShapeCollection.releaseShapes(); // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
-
+          localShapeCollection.releaseShapes();
+          // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
           if (this.m === 2 && len > 1) {
             edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
             addedLength += shapeData.totalShapeLength;
           } else {
             edges = [[shapeS, shapeE]];
           }
-
           jLen = edges.length;
-
           for (j = 0; j < jLen; j += 1) {
             shapeS = edges[j][0];
             shapeE = edges[j][1];
             segments.length = 0;
-
             if (shapeE <= 1) {
               segments.push({
                 s: shapeData.totalShapeLength * shapeS,
@@ -5623,13 +4729,10 @@
                 e: shapeData.totalShapeLength * (shapeE - 1)
               });
             }
-
             var newShapesData = this.addShapes(shapeData, segments[0]);
-
             if (segments[0].s !== segments[0].e) {
               if (segments.length > 1) {
                 var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
-
                 if (lastShapeInCollection.c) {
                   var lastShape = newShapesData.pop();
                   this.addPaths(newShapesData, localShapeCollection);
@@ -5639,11 +4742,9 @@
                   newShapesData = this.addShapes(shapeData, segments[1]);
                 }
               }
-
               this.addPaths(newShapesData, localShapeCollection);
             }
           }
-
           shapeData.shape.paths = localShapeCollection;
         }
       }
@@ -5656,38 +4757,29 @@
       }
     }
   };
-
   TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
     var i;
     var len = newPaths.length;
-
     for (i = 0; i < len; i += 1) {
       localShapeCollection.addShape(newPaths[i]);
     }
   };
-
   TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
     shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
     shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
     }
-
     shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
     shapePath.setXYAt(points[1], points[5], 'o', pos);
     shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(points[0], points[4], 'v', pos);
     }
-
     shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
     var pathsData = shapeData.pathsData;
     var shapePaths = shapeData.shape.paths.shapes;
@@ -5703,7 +4795,6 @@
     var shapes = [];
     var initPos;
     var newShape = true;
-
     if (!shapePath) {
       shapePath = shapePool.newElement();
       segmentCount = 0;
@@ -5712,17 +4803,13 @@
       segmentCount = shapePath._length;
       initPos = shapePath._length;
     }
-
     shapes.push(shapePath);
-
     for (i = 0; i < len; i += 1) {
       lengths = pathsData[i].lengths;
       shapePath.c = shapePaths[i].c;
       jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
-
       for (j = 1; j < jLen; j += 1) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
           addedLength += currentLengthData.addedLength;
           shapePath.c = false;
@@ -5735,50 +4822,42 @@
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
-
           addedLength += currentLengthData.addedLength;
           segmentCount += 1;
         }
       }
-
       if (shapePaths[i].c && lengths.length) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength <= shapeSegment.e) {
           var segmentLength = lengths[j - 1].addedLength;
-
           if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
             this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
         } else {
           shapePath.c = false;
         }
-
         addedLength += currentLengthData.addedLength;
         segmentCount += 1;
       }
-
       if (shapePath._length) {
         shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
         shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
       }
-
       if (addedLength > shapeSegment.e) {
         break;
       }
-
       if (i < len - 1) {
         shapePath = shapePool.newElement();
         newShape = true;
@@ -5786,31 +4865,25 @@
         segmentCount = 0;
       }
     }
-
     return shapes;
   };
 
   function PuckerAndBloatModifier() {}
-
   extendPrototype([ShapeModifier], PuckerAndBloatModifier);
-
   PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
     this._isAnimated = !!this.amount.effectsSequence.length;
   };
-
   PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
     var percent = amount / 100;
     var centerPoint = [0, 0];
     var pathLength = path._length;
     var i = 0;
-
     for (i = 0; i < pathLength; i += 1) {
       centerPoint[0] += path.v[i][0];
       centerPoint[1] += path.v[i][1];
     }
-
     centerPoint[0] /= pathLength;
     centerPoint[1] /= pathLength;
     var clonedPath = shapePool.newElement();
@@ -5821,7 +4894,6 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < pathLength; i += 1) {
       vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
       vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
@@ -5831,10 +4903,8 @@
       iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
       clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
     }
-
     return clonedPath;
   };
-
   PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -5842,30 +4912,24 @@
     var j;
     var jLen;
     var amount = this.amount.v;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -5873,30 +4937,24 @@
 
   var TransformPropertyFactory = function () {
     var defaultVector = [0, 0];
-
     function applyToMatrix(mat) {
       var _mdf = this._mdf;
       this.iterateDynamicProperties();
       this._mdf = this._mdf || _mdf;
-
       if (this.a) {
         mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
       }
-
       if (this.s) {
         mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
       }
-
       if (this.sk) {
         mat.skewFromAxis(-this.sk.v, this.sa.v);
       }
-
       if (this.r) {
         mat.rotate(-this.r.v);
       } else {
         mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
       }
-
       if (this.data.p.s) {
         if (this.data.p.z) {
           mat.translate(this.px.v, this.py.v, -this.pz.v);
@@ -5907,46 +4965,36 @@
         mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
       }
     }
-
     function processKeys(forceRender) {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (this._isDirty) {
         this.precalculateMatrix();
         this._isDirty = false;
       }
-
       this.iterateDynamicProperties();
-
       if (this._mdf || forceRender) {
         var frameRate;
         this.v.cloneFromProps(this.pre.props);
-
         if (this.appliedTransformations < 1) {
           this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         }
-
         if (this.appliedTransformations < 2) {
           this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         }
-
         if (this.sk && this.appliedTransformations < 3) {
           this.v.skewFromAxis(-this.sk.v, this.sa.v);
         }
-
         if (this.r && this.appliedTransformations < 4) {
           this.v.rotate(-this.r.v);
         } else if (!this.r && this.appliedTransformations < 4) {
           this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
         }
-
         if (this.autoOriented) {
           var v1;
           var v2;
           frameRate = this.elem.globalData.frameRate;
-
           if (this.p && this.p.keyframes && this.p.getValueAtTime) {
             if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
               v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
@@ -5963,7 +5011,6 @@
             v2 = [];
             var px = this.px;
             var py = this.py;
-
             if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
               v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
               v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
@@ -5983,10 +5030,8 @@
             v2 = defaultVector;
             v1 = v2;
           }
-
           this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
         }
-
         if (this.data.p && this.data.p.s) {
           if (this.data.p.z) {
             this.v.translate(this.px.v, this.py.v, -this.pz.v);
@@ -5997,28 +5042,23 @@
           this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
         }
       }
-
       this.frameId = this.elem.globalData.frameId;
     }
-
     function precalculateMatrix() {
       this.appliedTransformations = 0;
       this.pre.reset();
-
       if (!this.a.effectsSequence.length) {
         this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         this.appliedTransformations = 1;
       } else {
         return;
       }
-
       if (!this.s.effectsSequence.length) {
         this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         this.appliedTransformations = 2;
       } else {
         return;
       }
-
       if (this.sk) {
         if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
           this.pre.skewFromAxis(-this.sk.v, this.sa.v);
@@ -6027,7 +5067,6 @@
           return;
         }
       }
-
       if (this.r) {
         if (!this.r.effectsSequence.length) {
           this.pre.rotate(-this.r.v);
@@ -6038,33 +5077,28 @@
         this.appliedTransformations = 4;
       }
     }
-
-    function autoOrient() {//
+    function autoOrient() {
+      //
       // var prevP = this.getValueAtTime();
     }
-
     function addDynamicProperty(prop) {
       this._addDynamicProperty(prop);
-
       this.elem.addDynamicProperty(prop);
       this._isDirty = true;
     }
-
     function TransformProperty(elem, data, container) {
       this.elem = elem;
       this.frameId = -1;
       this.propType = 'transform';
       this.data = data;
-      this.v = new Matrix(); // Precalculated matrix with non animated properties
-
+      this.v = new Matrix();
+      // Precalculated matrix with non animated properties
       this.pre = new Matrix();
       this.appliedTransformations = 0;
       this.initDynamicPropertyContainer(container || elem);
-
       if (data.p && data.p.s) {
         this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
         this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
-
         if (data.p.z) {
           this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
         }
@@ -6073,43 +5107,37 @@
           k: [0, 0, 0]
         }, 1, 0, this);
       }
-
       if (data.rx) {
         this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
         this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
         this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
-
         if (data.or.k[0].ti) {
           var i;
           var len = data.or.k.length;
-
           for (i = 0; i < len; i += 1) {
             data.or.k[i].to = null;
             data.or.k[i].ti = null;
           }
         }
-
-        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this); // sh Indicates it needs to be capped between -180 and 180
-
+        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+        // sh Indicates it needs to be capped between -180 and 180
         this.or.sh = true;
       } else {
         this.r = PropertyFactory.getProp(elem, data.r || {
           k: 0
         }, 0, degToRads, this);
       }
-
       if (data.sk) {
         this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
         this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
       }
-
       this.a = PropertyFactory.getProp(elem, data.a || {
         k: [0, 0, 0]
       }, 1, 0, this);
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: [100, 100, 100]
-      }, 1, 0.01, this); // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
-
+      }, 1, 0.01, this);
+      // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
       if (data.o) {
         this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
       } else {
@@ -6118,14 +5146,11 @@
           v: 1
         };
       }
-
       this._isDirty = true;
-
       if (!this.dynamicProperties.length) {
         this.getValue(true);
       }
     }
-
     TransformProperty.prototype = {
       applyToMatrix: applyToMatrix,
       getValue: processKeys,
@@ -6135,20 +5160,16 @@
     extendPrototype([DynamicPropertyContainer], TransformProperty);
     TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
     TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
-
     function getTransformProperty(elem, data, container) {
       return new TransformProperty(elem, data, container);
     }
-
     return {
       getTransformProperty: getTransformProperty
     };
   }();
 
   function RepeaterModifier() {}
-
   extendPrototype([ShapeModifier], RepeaterModifier);
-
   RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
@@ -6157,11 +5178,9 @@
     this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
     this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
     this.data = data;
-
     if (!this.dynamicProperties.length) {
       this.getValue(true);
     }
-
     this._isAnimated = !!this.dynamicProperties.length;
     this.pMatrix = new Matrix();
     this.rMatrix = new Matrix();
@@ -6169,7 +5188,6 @@
     this.tMatrix = new Matrix();
     this.matrix = new Matrix();
   };
-
   RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
     var dir = inv ? -1 : 1;
     var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
@@ -6182,7 +5200,6 @@
     sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
     sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
   };
-
   RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
     this.elem = elem;
     this.arr = arr;
@@ -6194,52 +5211,42 @@
     this.frameId = -1;
     this.initDynamicPropertyContainer(elem);
     this.initModifierProperties(elem, arr[pos]);
-
     while (pos > 0) {
-      pos -= 1; // this._elements.unshift(arr.splice(pos,1)[0]);
-
+      pos -= 1;
+      // this._elements.unshift(arr.splice(pos,1)[0]);
       this._elements.unshift(arr[pos]);
     }
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   RepeaterModifier.prototype.resetElements = function (elements) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._processed = false;
-
       if (elements[i].ty === 'gr') {
         this.resetElements(elements[i].it);
       }
     }
   };
-
   RepeaterModifier.prototype.cloneElements = function (elements) {
     var newElements = JSON.parse(JSON.stringify(elements));
     this.resetElements(newElements);
     return newElements;
   };
-
   RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._render = renderFlag;
-
       if (elements[i].ty === 'gr') {
         this.changeGroupRender(elements[i].it, renderFlag);
       }
     }
   };
-
   RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
     var items;
     var itemsTransform;
@@ -6247,10 +5254,8 @@
     var dir;
     var cont;
     var hasReloaded = false;
-
     if (this._mdf || _isFirstFrame) {
       var copies = Math.ceil(this.c.v);
-
       if (this._groups.length < copies) {
         while (this._groups.length < copies) {
           var group = {
@@ -6305,28 +5310,21 @@
             ty: 'tr'
           });
           this.arr.splice(0, 0, group);
-
           this._groups.splice(0, 0, group);
-
           this._currentCopies += 1;
         }
-
         this.elem.reloadShapes();
         hasReloaded = true;
       }
-
       cont = 0;
       var renderFlag;
-
       for (i = 0; i <= this._groups.length - 1; i += 1) {
         renderFlag = cont < copies;
         this._groups[i]._render = renderFlag;
         this.changeGroupRender(this._groups[i].it, renderFlag);
-
         if (!renderFlag) {
           var elems = this.elemsData[i].it;
           var transformData = elems[elems.length - 1];
-
           if (transformData.transform.op.v !== 0) {
             transformData.transform.op._mdf = true;
             transformData.transform.op.v = 0;
@@ -6334,11 +5332,10 @@
             transformData.transform.op._mdf = false;
           }
         }
-
         cont += 1;
       }
-
-      this._currentCopies = copies; /// /
+      this._currentCopies = copies;
+      /// /
 
       var offset = this.o.v;
       var offsetModulo = offset % 1;
@@ -6352,13 +5349,11 @@
       this.tMatrix.reset();
       this.matrix.reset();
       var iteration = 0;
-
       if (offset > 0) {
         while (iteration < roundOffset) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           iteration += 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
           iteration += offsetModulo;
@@ -6368,19 +5363,16 @@
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
           iteration -= 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
           iteration -= offsetModulo;
         }
       }
-
       i = this.data.m === 1 ? 0 : this._currentCopies - 1;
       dir = this.data.m === 1 ? 1 : -1;
       cont = this._currentCopies;
       var j;
       var jLen;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6388,29 +5380,23 @@
         items[items.length - 1].transform.mProps._mdf = true;
         items[items.length - 1].transform.op._mdf = true;
         items[items.length - 1].transform.op.v = this._currentCopies === 1 ? this.so.v : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
-
         if (iteration !== 0) {
           if (i !== 0 && dir === 1 || i !== this._currentCopies - 1 && dir === -1) {
             this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           }
-
           this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
           this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
           this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
-
           this.matrix.reset();
         } else {
           this.matrix.reset();
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
         }
-
         iteration += 1;
         cont -= 1;
         i += dir;
@@ -6419,7 +5405,6 @@
       cont = this._currentCopies;
       i = 0;
       dir = 1;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6429,22 +5414,17 @@
         i += dir;
       }
     }
-
     return hasReloaded;
   };
-
   RepeaterModifier.prototype.addShape = function () {};
 
   function RoundCornersModifier() {}
-
   extendPrototype([ShapeModifier], RoundCornersModifier);
-
   RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
     this._isAnimated = !!this.rd.effectsSequence.length;
   };
-
   RoundCornersModifier.prototype.processPath = function (path, round) {
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
@@ -6463,19 +5443,16 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < len; i += 1) {
       currentV = path.v[i];
       currentO = path.o[i];
       currentI = path.i[i];
-
       if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
         if ((i === 0 || i === len - 1) && !path.c) {
           clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
           /* clonedPath.v[index] = currentV;
                   clonedPath.o[index] = currentO;
                   clonedPath.i[index] = currentI; */
-
           index += 1;
         } else {
           if (i === 0) {
@@ -6483,7 +5460,6 @@
           } else {
             closerV = path.v[i - 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6494,13 +5470,11 @@
           oY = vY - (vY - currentV[1]) * roundCorner;
           clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
           index += 1;
-
           if (i === len - 1) {
             closerV = path.v[0];
           } else {
             closerV = path.v[i + 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6517,10 +5491,8 @@
         index += 1;
       }
     }
-
     return clonedPath;
   };
-
   RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6528,30 +5500,24 @@
     var j;
     var jLen;
     var rd = this.rd.v;
-
     if (rd !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6560,50 +5526,41 @@
   function floatEqual(a, b) {
     return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
   }
-
   function floatZero(f) {
     return Math.abs(f) <= 0.00001;
   }
-
   function lerp(p0, p1, amount) {
     return p0 * (1 - amount) + p1 * amount;
   }
-
   function lerpPoint(p0, p1, amount) {
     return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
   }
-
   function quadRoots(a, b, c) {
     // no root
     if (a === 0) return [];
-    var s = b * b - 4 * a * c; // Complex roots
-
+    var s = b * b - 4 * a * c;
+    // Complex roots
     if (s < 0) return [];
-    var singleRoot = -b / (2 * a); // 1 root
-
+    var singleRoot = -b / (2 * a);
+    // 1 root
     if (s === 0) return [singleRoot];
-    var delta = Math.sqrt(s) / (2 * a); // 2 roots
-
+    var delta = Math.sqrt(s) / (2 * a);
+    // 2 roots
     return [singleRoot - delta, singleRoot + delta];
   }
-
   function polynomialCoefficients(p0, p1, p2, p3) {
     return [-p0 + 3 * p1 - 3 * p2 + p3, 3 * p0 - 6 * p1 + 3 * p2, -3 * p0 + 3 * p1, p0];
   }
-
   function singlePoint(p) {
     return new PolynomialBezier(p, p, p, p, false);
   }
-
   function PolynomialBezier(p0, p1, p2, p3, linearize) {
     if (linearize && pointEqual(p0, p1)) {
       p1 = lerpPoint(p0, p3, 1 / 3);
     }
-
     if (linearize && pointEqual(p2, p3)) {
       p2 = lerpPoint(p0, p3, 2 / 3);
     }
-
     var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
     var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
     this.a = [coeffx[0], coeffy[0]];
@@ -6612,25 +5569,20 @@
     this.d = [coeffx[3], coeffy[3]];
     this.points = [p0, p1, p2, p3];
   }
-
   PolynomialBezier.prototype.point = function (t) {
     return [((this.a[0] * t + this.b[0]) * t + this.c[0]) * t + this.d[0], ((this.a[1] * t + this.b[1]) * t + this.c[1]) * t + this.d[1]];
   };
-
   PolynomialBezier.prototype.derivative = function (t) {
     return [(3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0], (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1]];
   };
-
   PolynomialBezier.prototype.tangentAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[1], p[0]);
   };
-
   PolynomialBezier.prototype.normalAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[0], p[1]);
   };
-
   PolynomialBezier.prototype.inflectionPoints = function () {
     var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
     if (floatZero(denom)) return [];
@@ -6638,17 +5590,14 @@
     var square = tcusp * tcusp - 1 / 3 * (this.b[1] * this.c[0] - this.b[0] * this.c[1]) / denom;
     if (square < 0) return [];
     var root = Math.sqrt(square);
-
     if (floatZero(root)) {
       if (root > 0 && root < 1) return [tcusp];
       return [];
     }
-
     return [tcusp - root, tcusp + root].filter(function (r) {
       return r > 0 && r < 1;
     });
   };
-
   PolynomialBezier.prototype.split = function (t) {
     if (t <= 0) return [singlePoint(this.points[0]), this];
     if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
@@ -6660,40 +5609,33 @@
     var p3 = lerpPoint(p20, p21, t);
     return [new PolynomialBezier(this.points[0], p10, p20, p3, true), new PolynomialBezier(p3, p21, p12, this.points[3], true)];
   };
-
   function extrema(bez, comp) {
     var min = bez.points[0][comp];
     var max = bez.points[bez.points.length - 1][comp];
-
     if (min > max) {
       var e = max;
       max = min;
       min = e;
-    } // Derivative roots to find min/max
-
-
+    }
+    // Derivative roots to find min/max
     var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
-
     for (var i = 0; i < f.length; i += 1) {
       if (f[i] > 0 && f[i] < 1) {
         var val = bez.point(f[i])[comp];
         if (val < min) min = val;else if (val > max) max = val;
       }
     }
-
     return {
       min: min,
       max: max
     };
   }
-
   PolynomialBezier.prototype.bounds = function () {
     return {
       x: extrema(this, 0),
       y: extrema(this, 1)
     };
   };
-
   PolynomialBezier.prototype.boundingBox = function () {
     var bounds = this.bounds();
     return {
@@ -6707,7 +5649,6 @@
       cy: (bounds.y.max + bounds.y.min) / 2
     };
   };
-
   function intersectData(bez, t1, t2) {
     var box = bez.boundingBox();
     return {
@@ -6721,24 +5662,19 @@
       t2: t2
     };
   }
-
   function splitData(data) {
     var split = data.bez.split(0.5);
     return [intersectData(split[0], data.t1, data.t), intersectData(split[1], data.t, data.t2)];
   }
-
   function boxIntersect(b1, b2) {
     return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
   }
-
   function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
     if (!boxIntersect(d1, d2)) return;
-
     if (depth >= maxRecursion || d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance) {
       intersections.push([d1.t, d2.t]);
       return;
     }
-
     var d1s = splitData(d1);
     var d2s = splitData(d2);
     intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
@@ -6746,7 +5682,6 @@
     intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
     intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
   }
-
   PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
     if (tolerance === undefined) tolerance = 2;
     if (maxRecursion === undefined) maxRecursion = 7;
@@ -6754,21 +5689,17 @@
     intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
     return intersections;
   };
-
   PolynomialBezier.shapeSegment = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
   };
-
   PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
   };
-
   function crossProduct(a, b) {
     return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
   }
-
   function lineIntersection(start1, end1, start2, end2) {
     var v1 = [start1[0], start1[1], 1];
     var v2 = [end1[0], end1[1], 1];
@@ -6778,23 +5709,18 @@
     if (floatZero(r[2])) return null;
     return [r[0] / r[2], r[1] / r[2]];
   }
-
   function polarOffset(p, angle, length) {
     return [p[0] + Math.cos(angle) * length, p[1] - Math.sin(angle) * length];
   }
-
   function pointDistance(p1, p2) {
     return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
   }
-
   function pointEqual(p1, p2) {
     return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
   }
 
   function ZigZagModifier() {}
-
   extendPrototype([ShapeModifier], ZigZagModifier);
-
   ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
@@ -6802,7 +5728,6 @@
     this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
     this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
   };
-
   function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
     var angO = angle - Math.PI / 2;
     var angI = angle + Math.PI / 2;
@@ -6810,14 +5735,12 @@
     var py = point[1] - Math.sin(angle) * direction * amplitude;
     outputBezier.setTripleAt(px, py, px + Math.cos(angO) * outAmplitude, py - Math.sin(angO) * outAmplitude, px + Math.cos(angI) * inAmplitude, py - Math.sin(angI) * inAmplitude, outputBezier.length());
   }
-
   function getPerpendicularVector(pt1, pt2) {
     var vector = [pt2[0] - pt1[0], pt2[1] - pt1[1]];
     var rot = -Math.PI * 0.5;
     var rotatedVector = [Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1], Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1]];
     return rotatedVector;
   }
-
   function getProjectingAngle(path, cur) {
     var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
     var nextIndex = (cur + 1) % path.length();
@@ -6826,7 +5749,6 @@
     var pVector = getPerpendicularVector(prevPoint, nextPoint);
     return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
   }
-
   function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
     var angle = getProjectingAngle(path, cur);
     var point = path.v[cur % path._length];
@@ -6836,7 +5758,6 @@
     var nextDist = pointType === 2 ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2)) : 0;
     setPoint(outputBezier, path.v[cur % path._length], angle, direction, amplitude, nextDist / ((frequency + 1) * 2), prevDist / ((frequency + 1) * 2), pointType);
   }
-
   function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
     for (var i = 0; i < frequency; i += 1) {
       var t = (i + 1) / (frequency + 1);
@@ -6846,39 +5767,30 @@
       setPoint(outputBezier, point, angle, direction, amplitude, dist / ((frequency + 1) * 2), dist / ((frequency + 1) * 2), pointType);
       direction = -direction;
     }
-
     return direction;
   }
-
   ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
     var count = path._length;
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
-
     if (!path.c) {
       count -= 1;
     }
-
     if (count === 0) return clonedPath;
     var direction = -1;
     var segment = PolynomialBezier.shapeSegment(path, 0);
     zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
-
     for (var i = 0; i < count; i += 1) {
       direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
-
       if (i === count - 1 && !path.c) {
         segment = null;
       } else {
         segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
       }
-
       zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
     }
-
     return clonedPath;
   };
-
   ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6888,30 +5800,24 @@
     var amplitude = this.amplitude.v;
     var frequency = Math.max(0, Math.round(this.frequency.v));
     var pointType = this.pointsType.v;
-
     if (amplitude !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6921,7 +5827,6 @@
     var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
     return [polarOffset(p1, angle, amount), polarOffset(p2, angle, amount)];
   }
-
   function offsetSegment(segment, amount) {
     var p0;
     var p1a;
@@ -6945,15 +5850,17 @@
     if (p2 === null) p2 = p2a;
     return new PolynomialBezier(p0, p1, p2, p3);
   }
-
   function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
     var p0 = seg1.points[3];
-    var p1 = seg2.points[0]; // Bevel
+    var p1 = seg2.points[0];
 
-    if (lineJoin === 3) return p0; // Connected, they don't need a joint
+    // Bevel
+    if (lineJoin === 3) return p0;
 
-    if (pointEqual(p0, p1)) return p0; // Round
+    // Connected, they don't need a joint
+    if (pointEqual(p0, p1)) return p0;
 
+    // Round
     if (lineJoin === 2) {
       var angleOut = -seg1.tangentAngle(1);
       var angleIn = -seg2.tangentAngle(0) + Math.PI;
@@ -6964,91 +5871,75 @@
       tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
       outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
       return p1;
-    } // Miter
+    }
 
-
+    // Miter
     var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
     var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
     var intersection = lineIntersection(t0, p0, p1, t1);
-
     if (intersection && pointDistance(intersection, p0) < miterLimit) {
       outputBezier.setTripleAt(intersection[0], intersection[1], intersection[0], intersection[1], intersection[0], intersection[1], outputBezier.length());
       return intersection;
     }
-
     return p0;
   }
-
   function getIntersection(a, b) {
     var intersect = a.intersections(b);
     if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
     if (intersect.length) return intersect[0];
     return null;
   }
-
   function pruneSegmentIntersection(a, b) {
     var outa = a.slice();
     var outb = b.slice();
     var intersect = getIntersection(a[a.length - 1], b[0]);
-
     if (intersect) {
       outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
       outb[0] = b[0].split(intersect[1])[1];
     }
-
     if (a.length > 1 && b.length > 1) {
       intersect = getIntersection(a[0], b[b.length - 1]);
-
       if (intersect) {
         return [[a[0].split(intersect[0])[0]], [b[b.length - 1].split(intersect[1])[1]]];
       }
     }
-
     return [outa, outb];
   }
-
   function pruneIntersections(segments) {
     var e;
-
     for (var i = 1; i < segments.length; i += 1) {
       e = pruneSegmentIntersection(segments[i - 1], segments[i]);
       segments[i - 1] = e[0];
       segments[i] = e[1];
     }
-
     if (segments.length > 1) {
       e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
       segments[segments.length - 1] = e[0];
       segments[0] = e[1];
     }
-
     return segments;
   }
-
   function offsetSegmentSplit(segment, amount) {
     /*
       We split each bezier segment into smaller pieces based
       on inflection points, this ensures the control point
       polygon is convex.
-        (A cubic bezier can have none, one, or two inflection points)
+       (A cubic bezier can have none, one, or two inflection points)
     */
     var flex = segment.inflectionPoints();
     var left;
     var right;
     var split;
     var mid;
-
     if (flex.length === 0) {
       return [offsetSegment(segment, amount)];
     }
-
     if (flex.length === 1 || floatEqual(flex[1], 1)) {
       split = segment.split(flex[0]);
       left = split[0];
       right = split[1];
       return [offsetSegment(left, amount), offsetSegment(right, amount)];
     }
-
     split = segment.split(flex[0]);
     left = split[0];
     var t = (flex[1] - flex[0]) / (1 - flex[0]);
@@ -7057,11 +5948,8 @@
     right = split[1];
     return [offsetSegment(left, amount), offsetSegment(mid, amount), offsetSegment(right, amount)];
   }
-
   function OffsetPathModifier() {}
-
   extendPrototype([ShapeModifier], OffsetPathModifier);
-
   OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
@@ -7069,61 +5957,50 @@
     this.lineJoin = data.lj;
     this._isAnimated = this.amount.effectsSequence.length !== 0;
   };
-
   OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
     var outputBezier = shapePool.newElement();
     outputBezier.c = inputBezier.c;
     var count = inputBezier.length();
-
     if (!inputBezier.c) {
       count -= 1;
     }
-
     var i;
     var j;
     var segment;
     var multiSegments = [];
-
     for (i = 0; i < count; i += 1) {
       segment = PolynomialBezier.shapeSegment(inputBezier, i);
       multiSegments.push(offsetSegmentSplit(segment, amount));
     }
-
     if (!inputBezier.c) {
       for (i = count - 1; i >= 0; i -= 1) {
         segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
         multiSegments.push(offsetSegmentSplit(segment, amount));
       }
     }
+    multiSegments = pruneIntersections(multiSegments);
 
-    multiSegments = pruneIntersections(multiSegments); // Add bezier segments to the output and apply line joints
-
+    // Add bezier segments to the output and apply line joints
     var lastPoint = null;
     var lastSeg = null;
-
     for (i = 0; i < multiSegments.length; i += 1) {
       var multiSegment = multiSegments[i];
       if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
       lastSeg = multiSegment[multiSegment.length - 1];
-
       for (j = 0; j < multiSegment.length; j += 1) {
         segment = multiSegment[j];
-
         if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
           outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
         } else {
           outputBezier.setTripleAt(segment.points[0][0], segment.points[0][1], segment.points[1][0], segment.points[1][1], segment.points[0][0], segment.points[0][1], outputBezier.length());
         }
-
         outputBezier.setTripleAt(segment.points[3][0], segment.points[3][1], segment.points[3][0], segment.points[3][1], segment.points[2][0], segment.points[2][1], outputBezier.length());
         lastPoint = segment.points[3];
       }
     }
-
     if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
     return outputBezier;
   };
-
   OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -7133,30 +6010,24 @@
     var amount = this.amount.v;
     var miterLimit = this.miterLimit.v;
     var lineJoin = this.lineJoin;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -7168,42 +6039,33 @@
     var fStyle = 'normal';
     var len = styles.length;
     var styleName;
-
     for (var i = 0; i < len; i += 1) {
       styleName = styles[i].toLowerCase();
-
       switch (styleName) {
         case 'italic':
           fStyle = 'italic';
           break;
-
         case 'bold':
           fWeight = '700';
           break;
-
         case 'black':
           fWeight = '900';
           break;
-
         case 'medium':
           fWeight = '500';
           break;
-
         case 'regular':
         case 'normal':
           fWeight = '400';
           break;
-
         case 'light':
         case 'thin':
           fWeight = '200';
           break;
-
         default:
           break;
       }
     }
-
     return {
       style: fStyle,
       weight: fontData.fWeight || fWeight
@@ -7220,8 +6082,8 @@
         shapes: []
       }
     };
-    var combinedCharacters = []; // Hindi characters
-
+    var combinedCharacters = [];
+    // Hindi characters
     combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
     var BLACK_FLAG_CODE_POINT = 127988;
     var CANCEL_TAG_CODE_POINT = 917631;
@@ -7232,44 +6094,41 @@
     var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
     var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
     var surrogateModifiers = ['d83cdffb', 'd83cdffc', 'd83cdffd', 'd83cdffe', 'd83cdfff'];
-
     function trimFontOptions(font) {
       var familyArray = font.split(',');
       var i;
       var len = familyArray.length;
       var enabledFamilies = [];
-
       for (i = 0; i < len; i += 1) {
         if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
           enabledFamilies.push(familyArray[i]);
         }
       }
-
       return enabledFamilies.join(',');
     }
-
     function setUpNode(font, family) {
-      var parentNode = createTag('span'); // Node is invisible to screen readers.
-
+      var parentNode = createTag('span');
+      // Node is invisible to screen readers.
       parentNode.setAttribute('aria-hidden', true);
       parentNode.style.fontFamily = family;
-      var node = createTag('span'); // Characters that vary significantly among different fonts
-
-      node.innerText = 'giItT1WQy@!-/#'; // Visible - so we can measure it - but not on the screen
-
+      var node = createTag('span');
+      // Characters that vary significantly among different fonts
+      node.innerText = 'giItT1WQy@!-/#';
+      // Visible - so we can measure it - but not on the screen
       parentNode.style.position = 'absolute';
       parentNode.style.left = '-10000px';
-      parentNode.style.top = '-10000px'; // Large font size makes even subtle changes obvious
-
-      parentNode.style.fontSize = '300px'; // Reset any font properties
-
+      parentNode.style.top = '-10000px';
+      // Large font size makes even subtle changes obvious
+      parentNode.style.fontSize = '300px';
+      // Reset any font properties
       parentNode.style.fontVariant = 'normal';
       parentNode.style.fontStyle = 'normal';
       parentNode.style.fontWeight = 'normal';
       parentNode.style.letterSpacing = '0';
       parentNode.appendChild(node);
-      document.body.appendChild(parentNode); // Remember width with no applied web font
+      document.body.appendChild(parentNode);
 
+      // Remember width with no applied web font
       var width = node.offsetWidth;
       node.style.fontFamily = trimFontOptions(font) + ', ' + family;
       return {
@@ -7278,14 +6137,12 @@
         parent: parentNode
       };
     }
-
     function checkLoadedFonts() {
       var i;
       var len = this.fonts.length;
       var node;
       var w;
       var loadedCount = len;
-
       for (i = 0; i < len; i += 1) {
         if (this.fonts[i].loaded) {
           loadedCount -= 1;
@@ -7294,55 +6151,47 @@
         } else {
           node = this.fonts[i].monoCase.node;
           w = this.fonts[i].monoCase.w;
-
           if (node.offsetWidth !== w) {
             loadedCount -= 1;
             this.fonts[i].loaded = true;
           } else {
             node = this.fonts[i].sansCase.node;
             w = this.fonts[i].sansCase.w;
-
             if (node.offsetWidth !== w) {
               loadedCount -= 1;
               this.fonts[i].loaded = true;
             }
           }
-
           if (this.fonts[i].loaded) {
             this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
             this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
           }
         }
       }
-
       if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
         setTimeout(this.checkLoadedFontsBinded, 20);
       } else {
         setTimeout(this.setIsLoadedBinded, 10);
       }
     }
-
     function createHelper(fontData, def) {
       var engine = document.body && def ? 'svg' : 'canvas';
       var helper;
       var fontProps = getFontProperties(fontData);
-
       if (engine === 'svg') {
         var tHelper = createNS('text');
-        tHelper.style.fontSize = '100px'; // tHelper.style.fontFamily = fontData.fFamily;
-
+        tHelper.style.fontSize = '100px';
+        // tHelper.style.fontFamily = fontData.fFamily;
         tHelper.setAttribute('font-family', fontData.fFamily);
         tHelper.setAttribute('font-style', fontProps.style);
         tHelper.setAttribute('font-weight', fontProps.weight);
         tHelper.textContent = '1';
-
         if (fontData.fClass) {
           tHelper.style.fontFamily = 'inherit';
           tHelper.setAttribute('class', fontData.fClass);
         } else {
           tHelper.style.fontFamily = fontData.fFamily;
         }
-
         def.appendChild(tHelper);
         helper = tHelper;
       } else {
@@ -7350,33 +6199,27 @@
         tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
         helper = tCanvasHelper;
       }
-
       function measure(text) {
         if (engine === 'svg') {
           helper.textContent = text;
           return helper.getComputedTextLength();
         }
-
         return helper.measureText(text).width;
       }
-
       return {
         measureText: measure
       };
     }
-
     function addFonts(fontData, defs) {
       if (!fontData) {
         this.isLoaded = true;
         return;
       }
-
       if (this.chars) {
         this.isLoaded = true;
         this.fonts = fontData.list;
         return;
       }
-
       if (!document.body) {
         this.isLoaded = true;
         fontData.list.forEach(function (data) {
@@ -7386,12 +6229,10 @@
         this.fonts = fontData.list;
         return;
       }
-
       var fontArr = fontData.list;
       var i;
       var len = fontArr.length;
       var _pendingFonts = len;
-
       for (i = 0; i < len; i += 1) {
         var shouldLoadFont = true;
         var loadedSelector;
@@ -7399,17 +6240,14 @@
         fontArr[i].loaded = false;
         fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
         fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
-
         if (!fontArr[i].fPath) {
           fontArr[i].loaded = true;
           _pendingFonts -= 1;
         } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
           loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
-
           if (loadedSelector.length > 0) {
             shouldLoadFont = false;
           }
-
           if (shouldLoadFont) {
             var s = createTag('style');
             s.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7421,14 +6259,12 @@
           }
         } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
           loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var l = createTag('link');
             l.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7440,14 +6276,12 @@
           }
         } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
           loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (fontArr[i].fPath === loadedSelector[j].src) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var sc = createTag('link');
             sc.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7457,12 +6291,10 @@
             defs.appendChild(sc);
           }
         }
-
         fontArr[i].helper = createHelper(fontArr[i], defs);
         fontArr[i].cache = {};
         this.fonts.push(fontArr[i]);
       }
-
       if (_pendingFonts === 0) {
         this.isLoaded = true;
       } else {
@@ -7471,71 +6303,56 @@
         setTimeout(this.checkLoadedFonts.bind(this), 100);
       }
     }
-
     function addChars(chars) {
       if (!chars) {
         return;
       }
-
       if (!this.chars) {
         this.chars = [];
       }
-
       var i;
       var len = chars.length;
       var j;
       var jLen = this.chars.length;
       var found;
-
       for (i = 0; i < len; i += 1) {
         j = 0;
         found = false;
-
         while (j < jLen) {
           if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
             found = true;
           }
-
           j += 1;
         }
-
         if (!found) {
           this.chars.push(chars[i]);
           jLen += 1;
         }
       }
     }
-
     function getCharData(_char, style, font) {
       var i = 0;
       var len = this.chars.length;
-
       while (i < len) {
         if (this.chars[i].ch === _char && this.chars[i].style === style && this.chars[i].fFamily === font) {
           return this.chars[i];
         }
-
         i += 1;
       }
-
       if ((typeof _char === 'string' && _char.charCodeAt(0) !== 13 || !_char) && console && console.warn // eslint-disable-line no-console
       && !this._warned) {
         this._warned = true;
         console.warn('Missing character from exported characters list: ', _char, style, font); // eslint-disable-line no-console
       }
-
       return emptyChar;
     }
-
     function measureText(_char2, fontName, size) {
-      var fontData = this.getFontByName(fontName); // Using the char instead of char.charCodeAt(0)
+      var fontData = this.getFontByName(fontName);
+      // Using the char instead of char.charCodeAt(0)
       // to avoid collisions between equal chars
-
       var index = _char2;
-
       if (!fontData.cache[index]) {
         var tHelper = fontData.helper;
-
         if (_char2 === ' ') {
           var doubleSize = tHelper.measureText('|' + _char2 + '|');
           var singleSize = tHelper.measureText('||');
@@ -7544,111 +6361,90 @@
           fontData.cache[index] = tHelper.measureText(_char2) / 100;
         }
       }
-
       return fontData.cache[index] * size;
     }
-
     function getFontByName(name) {
       var i = 0;
       var len = this.fonts.length;
-
       while (i < len) {
         if (this.fonts[i].fName === name) {
           return this.fonts[i];
         }
-
         i += 1;
       }
-
       return this.fonts[0];
     }
-
     function getCodePoint(string) {
       var codePoint = 0;
       var first = string.charCodeAt(0);
-
       if (first >= 0xD800 && first <= 0xDBFF) {
         var second = string.charCodeAt(1);
-
         if (second >= 0xDC00 && second <= 0xDFFF) {
           codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
         }
       }
-
       return codePoint;
-    } // Skin tone modifiers
+    }
 
-
+    // Skin tone modifiers
     function isModifier(firstCharCode, secondCharCode) {
       var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
       return surrogateModifiers.indexOf(sum) !== -1;
     }
-
     function isZeroWidthJoiner(charCode) {
       return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
-    } // This codepoint may change the appearance of the preceding character.
+    }
+
+    // This codepoint may change the appearance of the preceding character.
     // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
     // as a colorful image as compared to a monochrome text variant.
-
-
     function isVariationSelector(charCode) {
       return charCode === VARIATION_SELECTOR_16_CODE_POINT;
-    } // The regional indicator symbols are a set of 26 alphabetic Unicode
+    }
+
+    // The regional indicator symbols are a set of 26 alphabetic Unicode
     /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
     // two-letter country codes in a way that allows optional special treatment.
-
-
     function isRegionalCode(string) {
       var codePoint = getCodePoint(string);
-
       if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
         return true;
       }
-
       return false;
-    } // Some Emoji implementations represent combinations of
+    }
+
+    // Some Emoji implementations represent combinations of
     // two “regional indicator” letters as a single flag symbol.
-
-
     function isFlagEmoji(string) {
       return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
     }
-
     function isCombinedCharacter(_char3) {
       return combinedCharacters.indexOf(_char3) !== -1;
-    } // Regional flags start with a BLACK_FLAG_CODE_POINT
+    }
+
+    // Regional flags start with a BLACK_FLAG_CODE_POINT
     // folowed by 5 chars in the TAG range
     // and end with a CANCEL_TAG_CODE_POINT
-
-
     function isRegionalFlag(text, index) {
       var codePoint = getCodePoint(text.substr(index, 2));
-
       if (codePoint !== BLACK_FLAG_CODE_POINT) {
         return false;
       }
-
       var count = 0;
       index += 2;
-
       while (count < 5) {
         codePoint = getCodePoint(text.substr(index, 2));
-
         if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
           return false;
         }
-
         count += 1;
         index += 2;
       }
-
       return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
     }
-
     function setIsLoaded() {
       this.isLoaded = true;
     }
-
     var Font = function Font() {
       this.fonts = [];
       this.chars = null;
@@ -7659,7 +6455,6 @@
       this.setIsLoadedBinded = this.setIsLoaded.bind(this);
       this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
     };
-
     Font.isModifier = isModifier;
     Font.isZeroWidthJoiner = isZeroWidthJoiner;
     Font.isFlagEmoji = isFlagEmoji;
@@ -7684,30 +6479,26 @@
   function SlotManager(animationData) {
     this.animationData = animationData;
   }
-
   SlotManager.prototype.getProp = function (data) {
     if (this.animationData.slots && this.animationData.slots[data.sid]) {
       return Object.assign(data, this.animationData.slots[data.sid].p);
     }
-
     return data;
   };
-
   function slotFactory(animationData) {
     return new SlotManager(animationData);
   }
 
   function RenderableElement() {}
-
   RenderableElement.prototype = {
     initRenderable: function initRenderable() {
       // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
-      this.isInRange = false; // layer's display state
-
-      this.hidden = false; // If layer's transparency equals 0, it can be hidden
-
-      this.isTransparent = false; // list of animated components
-
+      this.isInRange = false;
+      // layer's display state
+      this.hidden = false;
+      // If layer's transparency equals 0, it can be hidden
+      this.isTransparent = false;
+      // list of animated components
       this.renderableComponents = [];
     },
     addRenderableComponent: function addRenderableComponent(component) {
@@ -7734,7 +6525,6 @@
         this.show();
       }
     },
-
     /**
        * @function
        * Initializes frame related properties.
@@ -7760,13 +6550,11 @@
     renderRenderable: function renderRenderable() {
       var i;
       var len = this.renderableComponents.length;
-
       for (i = 0; i < len; i += 1) {
         this.renderableComponents[i].renderFrame(this._isFirstFrame);
       }
       /* this.maskManager.renderFrame(this.finalTransform.mat);
           this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
-
     },
     sourceRectAtTime: function sourceRectAtTime() {
       return {
@@ -7783,7 +6571,6 @@
           h: this.data.textData.height
         };
       }
-
       return {
         w: this.data.width,
         h: this.data.height
@@ -7818,31 +6605,24 @@
   function SliderEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function AngleEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function ColorEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function PointEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function LayerIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function MaskIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function CheckboxEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function NoValueEffect() {
     this.p = {};
   }
@@ -7853,20 +6633,16 @@
     var i;
     var len = effects.length;
     var effectItem;
-
     for (i = 0; i < len; i += 1) {
       effectItem = new GroupEffect(effects[i], element);
       this.effectElements.push(effectItem);
     }
   }
-
   function GroupEffect(data, element) {
     this.init(data, element);
   }
-
   extendPrototype([DynamicPropertyContainer], GroupEffect);
   GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
-
   GroupEffect.prototype.init = function (data, element) {
     this.data = data;
     this.effectElements = [];
@@ -7875,50 +6651,39 @@
     var len = this.data.ef.length;
     var eff;
     var effects = this.data.ef;
-
     for (i = 0; i < len; i += 1) {
       eff = null;
-
       switch (effects[i].ty) {
         case 0:
           eff = new SliderEffect(effects[i], element, this);
           break;
-
         case 1:
           eff = new AngleEffect(effects[i], element, this);
           break;
-
         case 2:
           eff = new ColorEffect(effects[i], element, this);
           break;
-
         case 3:
           eff = new PointEffect(effects[i], element, this);
           break;
-
         case 4:
         case 7:
           eff = new CheckboxEffect(effects[i], element, this);
           break;
-
         case 10:
           eff = new LayerIndexEffect(effects[i], element, this);
           break;
-
         case 11:
           eff = new MaskIndexEffect(effects[i], element, this);
           break;
-
         case 5:
           eff = new EffectsManager(effects[i], element, this);
           break;
         // case 6:
-
         default:
           eff = new NoValueEffect(effects[i], element, this);
           break;
       }
-
       if (eff) {
         this.effectElements.push(eff);
       }
@@ -7926,47 +6691,37 @@
   };
 
   function BaseElement() {}
-
   BaseElement.prototype = {
     checkMasks: function checkMasks() {
       if (!this.data.hasMask) {
         return false;
       }
-
       var i = 0;
       var len = this.data.masksProperties.length;
-
       while (i < len) {
         if (this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false) {
           return true;
         }
-
         i += 1;
       }
-
       return false;
     },
     initExpressions: function initExpressions() {
       var expressionsInterfaces = getExpressionInterfaces();
-
       if (!expressionsInterfaces) {
         return;
       }
-
       var LayerExpressionInterface = expressionsInterfaces('layer');
       var EffectsExpressionInterface = expressionsInterfaces('effects');
       var ShapeExpressionInterface = expressionsInterfaces('shape');
       var TextExpressionInterface = expressionsInterfaces('text');
       var CompExpressionInterface = expressionsInterfaces('comp');
       this.layerInterface = LayerExpressionInterface(this);
-
       if (this.data.hasMask && this.maskManager) {
         this.layerInterface.registerMaskInterface(this.maskManager);
       }
-
       var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
       this.layerInterface.registerEffectsInterface(effectsInterface);
-
       if (this.data.ty === 0 || this.data.xt) {
         this.compInterface = CompExpressionInterface(this);
       } else if (this.data.ty === 4) {
@@ -7986,13 +6741,13 @@
       this.globalData = globalData;
       this.comp = comp;
       this.data = data;
-      this.layerId = createElementID(); // Stretch factor for old animations missing this property.
+      this.layerId = createElementID();
 
+      // Stretch factor for old animations missing this property.
       if (!this.data.sr) {
         this.data.sr = 1;
-      } // effects manager
-
-
+      }
+      // effects manager
       this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
     },
     getType: function getType() {
@@ -8007,8 +6762,8 @@
    * Checks layer in point and out point
    *
    */
-  function FrameElement() {}
 
+  function FrameElement() {}
   FrameElement.prototype = {
     /**
        * @function
@@ -8017,13 +6772,12 @@
        */
     initFrame: function initFrame() {
       // set to true when inpoint is rendered
-      this._isFirstFrame = false; // list of animated properties
-
-      this.dynamicProperties = []; // If layer has been modified in current tick this will be true
-
+      this._isFirstFrame = false;
+      // list of animated properties
+      this.dynamicProperties = [];
+      // If layer has been modified in current tick this will be true
       this._mdf = false;
     },
-
     /**
        * @function
        * Calculates all dynamic values
@@ -8037,11 +6791,9 @@
     prepareProperties: function prepareProperties(num, isVisible) {
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         if (isVisible || this._isParent && this.dynamicProperties[i].propType === 'transform') {
           this.dynamicProperties[i].getValue();
-
           if (this.dynamicProperties[i]._mdf) {
             this.globalData._mdf = true;
             this._mdf = true;
@@ -8063,30 +6815,21 @@
     this.footageData = globalData.imageLoader.getAsset(this.assetData);
     this.initBaseData(data, globalData, comp);
   }
-
   FootageElement.prototype.prepareFrame = function () {};
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
-
   FootageElement.prototype.getBaseElement = function () {
     return null;
   };
-
   FootageElement.prototype.renderFrame = function () {};
-
   FootageElement.prototype.destroy = function () {};
-
   FootageElement.prototype.initExpressions = function () {
     var expressionsInterfaces = getExpressionInterfaces();
-
     if (!expressionsInterfaces) {
       return;
     }
-
     var FootageInterface = expressionsInterfaces('footage');
     this.layerInterface = FootageInterface(this);
   };
-
   FootageElement.prototype.getFootageData = function () {
     return this.footageData;
   };
@@ -8112,29 +6855,23 @@
       k: [100]
     }, 1, 0.01, this);
   }
-
   AudioElement.prototype.prepareFrame = function (num) {
     this.prepareRenderableFrame(num, true);
     this.prepareProperties(num, true);
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
       this._currentTime = timeRemapped;
     } else {
       this._currentTime = num / this.data.sr;
     }
-
     this._volume = this.lv.v[0];
     var totalVolume = this._volume * this._volumeMultiplier;
-
     if (this._previousVolume !== totalVolume) {
       this._previousVolume = totalVolume;
       this.audio.volume(totalVolume);
     }
   };
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
-
   AudioElement.prototype.renderFrame = function () {
     if (this.isInRange && this._canPlay) {
       if (!this._isPlaying) {
@@ -8146,162 +6883,124 @@
       }
     }
   };
-
-  AudioElement.prototype.show = function () {// this.audio.play()
+  AudioElement.prototype.show = function () {
+    // this.audio.play()
   };
-
   AudioElement.prototype.hide = function () {
     this.audio.pause();
     this._isPlaying = false;
   };
-
   AudioElement.prototype.pause = function () {
     this.audio.pause();
     this._isPlaying = false;
     this._canPlay = false;
   };
-
   AudioElement.prototype.resume = function () {
     this._canPlay = true;
   };
-
   AudioElement.prototype.setRate = function (rateValue) {
     this.audio.rate(rateValue);
   };
-
   AudioElement.prototype.volume = function (volumeValue) {
     this._volumeMultiplier = volumeValue;
     this._previousVolume = volumeValue * this._volume;
     this.audio.volume(this._previousVolume);
   };
-
   AudioElement.prototype.getBaseElement = function () {
     return null;
   };
-
   AudioElement.prototype.destroy = function () {};
-
   AudioElement.prototype.sourceRectAtTime = function () {};
-
   AudioElement.prototype.initExpressions = function () {};
 
   function BaseRenderer() {}
-
   BaseRenderer.prototype.checkLayers = function (num) {
     var i;
     var len = this.layers.length;
     var data;
     this.completeLayers = true;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (!this.elements[i]) {
         data = this.layers[i];
-
         if (data.ip - data.st <= num - this.layers[i].st && data.op - data.st > num - this.layers[i].st) {
           this.buildItem(i);
         }
       }
-
       this.completeLayers = this.elements[i] ? this.completeLayers : false;
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.createItem = function (layer) {
     switch (layer.ty) {
       case 2:
         return this.createImage(layer);
-
       case 0:
         return this.createComp(layer);
-
       case 1:
         return this.createSolid(layer);
-
       case 3:
         return this.createNull(layer);
-
       case 4:
         return this.createShape(layer);
-
       case 5:
         return this.createText(layer);
-
       case 6:
         return this.createAudio(layer);
-
       case 13:
         return this.createCamera(layer);
-
       case 15:
         return this.createFootage(layer);
-
       default:
         return this.createNull(layer);
     }
   };
-
   BaseRenderer.prototype.createCamera = function () {
     throw new Error('You\'re using a 3d camera. Try the html renderer.');
   };
-
   BaseRenderer.prototype.createAudio = function (data) {
     return new AudioElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.createFootage = function (data) {
     return new FootageElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.buildAllItems = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       this.buildItem(i);
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.includeLayers = function (newLayers) {
     this.completeLayers = false;
     var i;
     var len = newLayers.length;
     var j;
     var jLen = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       j = 0;
-
       while (j < jLen) {
         if (this.layers[j].id === newLayers[i].id) {
           this.layers[j] = newLayers[i];
           break;
         }
-
         j += 1;
       }
     }
   };
-
   BaseRenderer.prototype.setProjectInterface = function (pInterface) {
     this.globalData.projectInterface = pInterface;
   };
-
   BaseRenderer.prototype.initItems = function () {
     if (!this.globalData.progressiveLoad) {
       this.buildAllItems();
     }
   };
-
   BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
     var elements = this.elements;
     var layers = this.layers;
     var i = 0;
     var len = layers.length;
-
     while (i < len) {
       if (layers[i].ind == parentName) {
         // eslint-disable-line eqeqeq
@@ -8311,7 +7010,6 @@
         } else {
           hierarchy.push(elements[i]);
           elements[i].setAsParent();
-
           if (layers[i].parent !== undefined) {
             this.buildElementParenting(element, layers[i].parent, hierarchy);
           } else {
@@ -8319,19 +7017,15 @@
           }
         }
       }
-
       i += 1;
     }
   };
-
   BaseRenderer.prototype.addPendingElement = function (element) {
     this.pendingElements.push(element);
   };
-
   BaseRenderer.prototype.searchExtraCompositions = function (assets) {
     var i;
     var len = assets.length;
-
     for (i = 0; i < len; i += 1) {
       if (assets[i].xt) {
         var comp = this.createComp(assets[i]);
@@ -8340,30 +7034,24 @@
       }
     }
   };
-
   BaseRenderer.prototype.getElementById = function (ind) {
     var i;
     var len = this.elements.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i].data.ind === ind) {
         return this.elements[i];
       }
     }
-
     return null;
   };
-
   BaseRenderer.prototype.getElementByPath = function (path) {
     var pathValue = path.shift();
     var element;
-
     if (typeof pathValue === 'number') {
       element = this.elements[pathValue];
     } else {
       var i;
       var len = this.elements.length;
-
       for (i = 0; i < len; i += 1) {
         if (this.elements[i].data.nm === pathValue) {
           element = this.elements[i];
@@ -8371,14 +7059,11 @@
         }
       }
     }
-
     if (path.length === 0) {
       return element;
     }
-
     return element.getElementByPath(path);
   };
-
   BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
     this.globalData.fontManager = new FontManager();
     this.globalData.slotManager = slotFactory(animData);
@@ -8402,7 +7087,6 @@
   };
 
   function TransformElement() {}
-
   TransformElement.prototype = {
     initTransform: function initTransform() {
       var mat = new Matrix();
@@ -8417,50 +7101,44 @@
         localMat: mat,
         localOpacity: 1
       };
-
       if (this.data.ao) {
         this.finalTransform.mProp.autoOriented = true;
-      } // TODO: check TYPE 11: Guided elements
+      }
 
-
-      if (this.data.ty !== 11) {// this.createElements();
+      // TODO: check TYPE 11: Guided elements
+      if (this.data.ty !== 11) {
+        // this.createElements();
       }
     },
     renderTransform: function renderTransform() {
       this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
       this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
-
       if (this.hierarchy) {
         var mat;
         var finalMat = this.finalTransform.mat;
         var i = 0;
-        var len = this.hierarchy.length; // Checking if any of the transformation matrices in the hierarchy chain has changed.
-
+        var len = this.hierarchy.length;
+        // Checking if any of the transformation matrices in the hierarchy chain has changed.
         if (!this.finalTransform._matMdf) {
           while (i < len) {
             if (this.hierarchy[i].finalTransform.mProp._mdf) {
               this.finalTransform._matMdf = true;
               break;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._matMdf) {
           mat = this.finalTransform.mProp.v.props;
           finalMat.cloneFromProps(mat);
-
           for (i = 0; i < len; i += 1) {
             finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
           }
         }
       }
-
-      if (this.finalTransform._matMdf) {
+      if (!this.localTransforms || this.finalTransform._matMdf) {
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
       }
-
       if (this.finalTransform._opMdf) {
         this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
       }
@@ -8470,41 +7148,32 @@
         var i = 0;
         var len = this.localTransforms.length;
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
-
         if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
           while (i < len) {
             if (this.localTransforms[i]._mdf) {
               this.finalTransform._localMatMdf = true;
             }
-
             if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
               this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
               this.finalTransform._opMdf = true;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._localMatMdf) {
           var localMat = this.finalTransform.localMat;
           this.localTransforms[0].matrix.clone(localMat);
-
           for (i = 1; i < len; i += 1) {
             var lmat = this.localTransforms[i].matrix;
             localMat.multiply(lmat);
           }
-
           localMat.multiply(this.finalTransform.mat);
         }
-
         if (this.finalTransform._opMdf) {
           var localOp = this.finalTransform.localOpacity;
-
           for (i = 0; i < len; i += 1) {
             localOp *= this.localTransforms[i].opacity * 0.01;
           }
-
           this.finalTransform.localOpacity = localOp;
         }
       }
@@ -8512,13 +7181,11 @@
     searchEffectTransforms: function searchEffectTransforms() {
       if (this.renderableEffectsManager) {
         var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
-
         if (transformEffects.length) {
           this.localTransforms = [];
           this.finalTransform.localMat = new Matrix();
           var i = 0;
           var len = transformEffects.length;
-
           for (i = 0; i < len; i += 1) {
             this.localTransforms.push(transformEffects[i]);
           }
@@ -8530,29 +7197,24 @@
       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;
       var len = transforms.length;
       var 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]);
-
+        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;
     },
     mHelper: new Matrix()
@@ -8583,13 +7245,11 @@
     var x;
     var maskType = 'clipPath';
     var maskRef = 'clip-path';
-
     for (i = 0; i < len; i += 1) {
       if (properties[i].mode !== 'a' && properties[i].mode !== 'n' || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
         maskType = 'mask';
         maskRef = 'mask';
       }
-
       if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
         rect = createNS('rect');
         rect.setAttribute('fill', '#ffffff');
@@ -8599,9 +7259,7 @@
       } else {
         rect = null;
       }
-
       path = createNS('path');
-
       if (properties[i].mode === 'n') {
         // TODO move this to a factory or to a constructor
         this.viewData[i] = {
@@ -8616,7 +7274,6 @@
         path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
         path.setAttribute('clip-rule', 'nonzero');
         var filterID;
-
         if (properties[i].x.k !== 0) {
           maskType = 'mask';
           maskRef = 'mask';
@@ -8634,9 +7291,9 @@
         } else {
           feMorph = null;
           x = null;
-        } // TODO move this to a factory or to a constructor
+        }
 
-
+        // TODO move this to a factory or to a constructor
         this.storedData[i] = {
           elem: path,
           x: x,
@@ -8646,15 +7303,12 @@
           filterId: filterID,
           lastRadius: 0
         };
-
         if (properties[i].mode === 'i') {
           jLen = currentMasks.length;
           var g = createNS('g');
-
           for (j = 0; j < jLen; j += 1) {
             g.appendChild(currentMasks[j]);
           }
-
           var mask = createNS('mask');
           mask.setAttribute('mask-type', 'alpha');
           mask.setAttribute('id', layerId + '_' + count);
@@ -8666,12 +7320,10 @@
         } else {
           currentMasks.push(path);
         }
-
         if (properties[i].inv && !this.solidPath) {
           this.solidPath = this.createLayerSolidPath();
-        } // TODO move this to a factory or to a constructor
-
-
+        }
+        // TODO move this to a factory or to a constructor
         this.viewData[i] = {
           elem: path,
           lastPath: '',
@@ -8679,81 +7331,65 @@
           prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
           invRect: rect
         };
-
         if (!this.viewData[i].prop.k) {
           this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
         }
       }
     }
-
     this.maskElement = createNS(maskType);
     len = currentMasks.length;
-
     for (i = 0; i < len; i += 1) {
       this.maskElement.appendChild(currentMasks[i]);
     }
-
     if (count > 0) {
       this.maskElement.setAttribute('id', layerId);
       this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
       defs.appendChild(this.maskElement);
     }
-
     if (this.viewData.length) {
       this.element.addRenderableComponent(this);
     }
   }
-
   MaskElement.prototype.getMaskProperty = function (pos) {
     return this.viewData[pos].prop;
   };
-
   MaskElement.prototype.renderFrame = function (isFirstFrame) {
     var finalMat = this.element.finalTransform.mat;
     var i;
     var len = this.masksProperties.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.viewData[i].prop._mdf || isFirstFrame) {
         this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
       }
-
       if (this.viewData[i].op._mdf || isFirstFrame) {
         this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
       }
-
       if (this.masksProperties[i].mode !== 'n') {
         if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
           this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
         }
-
         if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
           var feMorph = this.storedData[i].expan;
-
           if (this.storedData[i].x.v < 0) {
             if (this.storedData[i].lastOperator !== 'erode') {
               this.storedData[i].lastOperator = 'erode';
               this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
             }
-
             feMorph.setAttribute('radius', -this.storedData[i].x.v);
           } else {
             if (this.storedData[i].lastOperator !== 'dilate') {
               this.storedData[i].lastOperator = 'dilate';
               this.storedData[i].elem.setAttribute('filter', null);
             }
-
             this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
           }
         }
       }
     }
   };
-
   MaskElement.prototype.getMaskelement = function () {
     return this.maskElement;
   };
-
   MaskElement.prototype.createLayerSolidPath = function () {
     var path = 'M0,0 ';
     path += ' h' + this.globalData.compSize.w;
@@ -8762,39 +7398,32 @@
     path += ' v-' + this.globalData.compSize.h + ' ';
     return path;
   };
-
   MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
     var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
     var i;
     var len;
     len = pathNodes._length;
-
     for (i = 1; i < len; i += 1) {
       // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
-    } // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
-
-
+    }
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
     if (pathNodes.c && len > 1) {
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
-    } // pathNodes.__renderedString = pathString;
-
+    }
+    // pathNodes.__renderedString = pathString;
 
     if (viewData.lastPath !== pathString) {
       var pathShapeValue = '';
-
       if (viewData.elem) {
         if (pathNodes.c) {
           pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
         }
-
         viewData.elem.setAttribute('d', pathShapeValue);
       }
-
       viewData.lastPath = pathString;
     }
   };
-
   MaskElement.prototype.destroy = function () {
     this.element = null;
     this.globalData = null;
@@ -8807,11 +7436,9 @@
     var ob = {};
     ob.createFilter = createFilter;
     ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
-
     function createFilter(filId, skipCoordinates) {
       var fil = createNS('filter');
       fil.setAttribute('id', filId);
-
       if (skipCoordinates !== true) {
         fil.setAttribute('filterUnits', 'objectBoundingBox');
         fil.setAttribute('x', '0%');
@@ -8819,10 +7446,8 @@
         fil.setAttribute('width', '100%');
         fil.setAttribute('height', '100%');
       }
-
       return fil;
     }
-
     function createAlphaToLuminanceFilter() {
       var feColorMatrix = createNS('feColorMatrix');
       feColorMatrix.setAttribute('type', 'matrix');
@@ -8830,7 +7455,6 @@
       feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
       return feColorMatrix;
     }
-
     return ob;
   }();
 
@@ -8840,21 +7464,17 @@
       svgLumaHidden: true,
       offscreenCanvas: typeof OffscreenCanvas !== 'undefined'
     };
-
     if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
       ob.maskType = false;
     }
-
     if (/firefox/i.test(navigator.userAgent)) {
       ob.svgLumaHidden = false;
     }
-
     return ob;
   }();
 
   var registeredEffects$1 = {};
   var idPrefix = 'filter_result_';
-
   function SVGEffects(elem) {
     var i;
     var source = 'SourceGraphic';
@@ -8864,59 +7484,47 @@
     var count = 0;
     this.filters = [];
     var filterManager;
-
     for (i = 0; i < len; i += 1) {
       filterManager = null;
       var type = elem.data.ef[i].ty;
-
       if (registeredEffects$1[type]) {
         var Effect = registeredEffects$1[type].effect;
         filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
         source = idPrefix + count;
-
         if (registeredEffects$1[type].countsAsEffect) {
           count += 1;
         }
       }
-
       if (filterManager) {
         this.filters.push(filterManager);
       }
     }
-
     if (count) {
       elem.globalData.defs.appendChild(fil);
       elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
     }
-
     if (this.filters.length) {
       elem.addRenderableComponent(this);
     }
   }
-
   SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
     var i;
     var len = this.filters.length;
-
     for (i = 0; i < len; i += 1) {
       this.filters[i].renderFrame(_isFirstFrame);
     }
   };
-
   SVGEffects.prototype.getEffects = function (type) {
     var i;
     var len = this.filters.length;
     var effects = [];
-
     for (i = 0; i < len; i += 1) {
       if (this.filters[i].type === type) {
         effects.push(this.filters[i]);
       }
     }
-
     return effects;
   };
-
   function registerEffect$1(id, effect, countsAsEffect) {
     registeredEffects$1[id] = {
       effect: effect,
@@ -8925,7 +7533,6 @@
   }
 
   function SVGBaseElement() {}
-
   SVGBaseElement.prototype = {
     initRendererElement: function initRendererElement() {
       this.layerElement = createNS('g');
@@ -8935,8 +7542,8 @@
       this.transformedElement = this.layerElement;
       this.maskedElement = this.layerElement;
       this._sizeChanged = false;
-      var layerElementParent = null; // If this layer acts as a mask for the following layer
-
+      var layerElementParent = null;
+      // If this layer acts as a mask for the following layer
       if (this.data.td) {
         this.matteMasks = {};
         var gg = createNS('g');
@@ -8951,16 +7558,13 @@
       } else {
         this.baseElement = this.layerElement;
       }
-
       if (this.data.ln) {
         this.layerElement.setAttribute('id', this.data.ln);
       }
-
       if (this.data.cl) {
         this.layerElement.setAttribute('class', this.data.cl);
-      } // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
-
-
+      }
+      // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
       if (this.data.ty === 0 && !this.data.hd) {
         var cp = createNS('clipPath');
         var pt = createNS('path');
@@ -8969,13 +7573,11 @@
         cp.setAttribute('id', clipId);
         cp.appendChild(pt);
         this.globalData.defs.appendChild(cp);
-
         if (this.checkMasks()) {
           var cpGroup = createNS('g');
           cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
           cpGroup.appendChild(this.layerElement);
           this.transformedElement = cpGroup;
-
           if (layerElementParent) {
             layerElementParent.appendChild(this.transformedElement);
           } else {
@@ -8985,7 +7587,6 @@
           this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
         }
       }
-
       if (this.data.bm !== 0) {
         this.setBlendMode();
       }
@@ -8994,7 +7595,6 @@
       if (this.finalTransform._localMatMdf) {
         this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
       }
-
       if (this.finalTransform._opMdf) {
         this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
       }
@@ -9008,7 +7608,6 @@
       if (this.data.hd) {
         return null;
       }
-
       return this.baseElement;
     },
     createRenderableComponents: function createRenderableComponents() {
@@ -9023,14 +7622,12 @@
       if (!this.matteMasks) {
         this.matteMasks = {};
       }
-
       if (!this.matteMasks[matteType]) {
         var id = this.layerId + '_' + matteType;
         var filId;
         var fil;
         var useElement;
         var gg;
-
         if (matteType === 1 || matteType === 3) {
           var masker = createNS('mask');
           masker.setAttribute('id', id);
@@ -9039,7 +7636,6 @@
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           masker.appendChild(useElement);
           this.globalData.defs.appendChild(masker);
-
           if (!featureSupport.maskType && matteType === 1) {
             masker.setAttribute('mask-type', 'luminance');
             filId = createElementID();
@@ -9058,16 +7654,16 @@
           var maskGrouper = createNS('g');
           maskGroup.appendChild(maskGrouper);
           filId = createElementID();
-          fil = filtersFactory.createFilter(filId); /// /
-
+          fil = filtersFactory.createFilter(filId);
+          /// /
           var feCTr = createNS('feComponentTransfer');
           feCTr.setAttribute('in', 'SourceGraphic');
           fil.appendChild(feCTr);
           var feFunc = createNS('feFuncA');
           feFunc.setAttribute('type', 'table');
           feFunc.setAttribute('tableValues', '1.0 0.0');
-          feCTr.appendChild(feFunc); /// /
-
+          feCTr.appendChild(feFunc);
+          /// /
           this.globalData.defs.appendChild(fil);
           var alphaRect = createNS('rect');
           alphaRect.setAttribute('width', this.comp.data.w);
@@ -9081,7 +7677,6 @@
           useElement = createNS('use');
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           maskGrouper.appendChild(useElement);
-
           if (!featureSupport.maskType) {
             maskGroup.setAttribute('mask-type', 'luminance');
             fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
@@ -9090,20 +7685,16 @@
             gg.appendChild(this.layerElement);
             maskGrouper.appendChild(gg);
           }
-
           this.globalData.defs.appendChild(maskGroup);
         }
-
         this.matteMasks[matteType] = id;
       }
-
       return this.matteMasks[matteType];
     },
     setMatte: function setMatte(id) {
       if (!this.matteElement) {
         return;
       }
-
       this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
     }
   };
@@ -9113,8 +7704,8 @@
    * Handles AE's layer parenting property.
    *
    */
-  function HierarchyElement() {}
 
+  function HierarchyElement() {}
   HierarchyElement.prototype = {
     /**
        * @function
@@ -9123,12 +7714,11 @@
        */
     initHierarchy: function initHierarchy() {
       // element's parent list
-      this.hierarchy = []; // if element is parent of another layer _isParent will be true
-
+      this.hierarchy = [];
+      // if element is parent of another layer _isParent will be true
       this._isParent = false;
       this.checkParenting();
     },
-
     /**
        * @function
        * Sets layer's hierarchy.
@@ -9139,7 +7729,6 @@
     setHierarchy: function setHierarchy(hierarchy) {
       this.hierarchy = hierarchy;
     },
-
     /**
        * @function
        * Sets layer as parent.
@@ -9148,7 +7737,6 @@
     setAsParent: function setAsParent() {
       this._isParent = true;
     },
-
     /**
        * @function
        * Searches layer's parenting chain
@@ -9162,7 +7750,6 @@
   };
 
   function RenderableDOMElement() {}
-
   (function () {
     var _prototype = {
       initElement: function initElement(data, globalData, comp) {
@@ -9192,7 +7779,6 @@
             var elem = this.baseElement || this.layerElement;
             elem.style.display = 'block';
           }
-
           this.hidden = false;
           this._isFirstFrame = true;
         }
@@ -9203,13 +7789,11 @@
         if (this.data.hd || this.hidden) {
           return;
         }
-
         this.renderTransform();
         this.renderRenderable();
         this.renderLocalTransform();
         this.renderElement();
         this.renderInnerContent();
-
         if (this._isFirstFrame) {
           this._isFirstFrame = false;
         }
@@ -9231,11 +7815,9 @@
 
   function IImageElement(data, globalData, comp) {
     this.assetData = globalData.getAssetData(data.refId);
-
     if (this.assetData && this.assetData.sid) {
       this.assetData = globalData.slotManager.getProp(this.assetData);
     }
-
     this.initElement(data, globalData, comp);
     this.sourceRect = {
       top: 0,
@@ -9244,9 +7826,7 @@
       height: this.assetData.h
     };
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
-
   IImageElement.prototype.createContent = function () {
     var assetPath = this.globalData.getAssetsPath(this.assetData);
     this.innerElem = createNS('image');
@@ -9256,7 +7836,6 @@
     this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
     this.layerElement.appendChild(this.innerElem);
   };
-
   IImageElement.prototype.sourceRectAtTime = function () {
     return this.sourceRect;
   };
@@ -9267,12 +7846,10 @@
   }
 
   function IShapeElement() {}
-
   IShapeElement.prototype = {
     addShapeToModifiers: function addShapeToModifiers(data) {
       var i;
       var len = this.shapeModifiers.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapeModifiers[i].addShape(data);
       }
@@ -9280,34 +7857,28 @@
     isShapeInAnimatedModifiers: function isShapeInAnimatedModifiers(data) {
       var i = 0;
       var len = this.shapeModifiers.length;
-
       while (i < len) {
         if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
           return true;
         }
       }
-
       return false;
     },
     renderModifiers: function renderModifiers() {
       if (!this.shapeModifiers.length) {
         return;
       }
-
       var i;
       var len = this.shapes.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapes[i].sh.reset();
       }
-
       len = this.shapeModifiers.length;
       var shouldBreakProcess;
-
       for (i = len - 1; i >= 0; i -= 1) {
-        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame); // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+        // workaround to fix cases where a repeater resets the shape so the following processes get called twice
         // TODO: find a better solution for this
-
         if (shouldBreakProcess) {
           break;
         }
@@ -9317,30 +7888,24 @@
       var elements = this.processedElements;
       var i = 0;
       var len = elements.length;
-
       while (i < len) {
         if (elements[i].elem === elem) {
           return elements[i].pos;
         }
-
         i += 1;
       }
-
       return 0;
     },
     addProcessedElement: function addProcessedElement(elem, pos) {
       var elements = this.processedElements;
       var i = elements.length;
-
       while (i) {
         i -= 1;
-
         if (elements[i].elem === elem) {
           elements[i].pos = pos;
           return;
         }
       }
-
       elements.push(new ProcessedElement(elem, pos));
     },
     prepareFrame: function prepareFrame(num) {
@@ -9366,25 +7931,22 @@
     this.transformers = transformers;
     this.lStr = '';
     this.sh = shape;
-    this.lvl = level; // TODO find if there are some cases where _isAnimated can be false.
+    this.lvl = level;
+    // TODO find if there are some cases where _isAnimated can be false.
     // For now, since shapes add up with other shapes. They have to be calculated every time.
     // One way of finding out is checking if all styles associated to this shape depend only of this shape
-
-    this._isAnimated = !!shape.k; // TODO: commenting this for now since all shapes are animated
-
+    this._isAnimated = !!shape.k;
+    // TODO: commenting this for now since all shapes are animated
     var i = 0;
     var len = transformers.length;
-
     while (i < len) {
       if (transformers[i].mProps.dynamicProperties.length) {
         this._isAnimated = true;
         break;
       }
-
       i += 1;
     }
   }
-
   SVGShapeData.prototype.setAsAnimated = function () {
     this._isAnimated = true;
   };
@@ -9399,7 +7961,6 @@
     this.pElem = createNS('path');
     this.msElem = null;
   }
-
   SVGStyleData.prototype.reset = function () {
     this.d = '';
     this._mdf = false;
@@ -9418,7 +7979,6 @@
     var i;
     var len = data.length || 0;
     var prop;
-
     for (i = 0; i < len; i += 1) {
       prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
       this.k = prop.k || this.k;
@@ -9427,31 +7987,24 @@
         p: prop
       };
     }
-
     if (!this.k) {
       this.getValue(true);
     }
-
     this._isAnimated = this.k;
   }
-
   DashProperty.prototype.getValue = function (forceRender) {
     if (this.elem.globalData.frameId === this.frameId && !forceRender) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
     this._mdf = this._mdf || forceRender;
-
     if (this._mdf) {
       var i = 0;
       var len = this.dataProps.length;
-
       if (this.renderer === 'svg') {
         this.dashStr = '';
       }
-
       for (i = 0; i < len; i += 1) {
         if (this.dataProps[i].n !== 'o') {
           if (this.renderer === 'svg') {
@@ -9465,7 +8018,6 @@
       }
     }
   };
-
   extendPrototype([DynamicPropertyContainer], DashProperty);
 
   function SVGStrokeStyleData(elem, data, styleOb) {
@@ -9478,7 +8030,6 @@
     this.style = styleOb;
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
 
   function SVGFillStyleData(elem, data, styleOb) {
@@ -9488,7 +8039,6 @@
     this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
 
   function SVGNoStyleData(elem, data, styleOb) {
@@ -9496,7 +8046,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
 
   function GradientProperty(elem, data, container) {
@@ -9513,88 +8062,69 @@
     this.k = this.prop.k;
     this.getValue(true);
   }
-
   GradientProperty.prototype.comparePoints = function (values, points) {
     var i = 0;
     var len = this.o.length / 2;
     var diff;
-
     while (i < len) {
       diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
-
       if (diff > 0.01) {
         return false;
       }
-
       i += 1;
     }
-
     return true;
   };
-
   GradientProperty.prototype.checkCollapsable = function () {
     if (this.o.length / 2 !== this.c.length / 4) {
       return false;
     }
-
     if (this.data.k.k[0].s) {
       var i = 0;
       var len = this.data.k.k.length;
-
       while (i < len) {
         if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
           return false;
         }
-
         i += 1;
       }
     } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
       return false;
     }
-
     return true;
   };
-
   GradientProperty.prototype.getValue = function (forceRender) {
     this.prop.getValue();
     this._mdf = false;
     this._cmdf = false;
     this._omdf = false;
-
     if (this.prop._mdf || forceRender) {
       var i;
       var len = this.data.p * 4;
       var mult;
       var val;
-
       for (i = 0; i < len; i += 1) {
         mult = i % 4 === 0 ? 100 : 255;
         val = Math.round(this.prop.v[i] * mult);
-
         if (this.c[i] !== val) {
           this.c[i] = val;
           this._cmdf = !forceRender;
         }
       }
-
       if (this.o.length) {
         len = this.prop.v.length;
-
         for (i = this.data.p * 4; i < len; i += 1) {
           mult = i % 2 === 0 ? 100 : 1;
           val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
-
           if (this.o[i - this.data.p * 4] !== val) {
             this.o[i - this.data.p * 4] = val;
             this._omdf = !forceRender;
           }
         }
       }
-
       this._mdf = !forceRender;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], GradientProperty);
 
   function SVGGradientFillStyleData(elem, data, styleOb) {
@@ -9602,7 +8132,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.initGradientData(elem, data, styleOb);
   }
-
   SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
     this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
     this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
@@ -9620,7 +8149,6 @@
     this.setGradientOpacity(data, styleOb);
     this._isAnimated = !!this._isAnimated;
   };
-
   SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
     var gradientId = createElementID();
     var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
@@ -9632,18 +8160,15 @@
     var j;
     var jLen;
     jLen = data.g.p * 4;
-
     for (j = 0; j < jLen; j += 4) {
       stop = createNS('stop');
       gfill.appendChild(stop);
       stops.push(stop);
     }
-
     pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
     this.gf = gfill;
     this.cst = stops;
   };
-
   SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
     if (this.g._hasOpacity && !this.g._collapsable) {
       var stop;
@@ -9661,25 +8186,20 @@
       opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
       jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
       var stops = this.stops;
-
       for (j = data.g.p * 4; j < jLen; j += 2) {
         stop = createNS('stop');
         stop.setAttribute('stop-color', 'rgb(255,255,255)');
         opFill.appendChild(stop);
         stops.push(stop);
       }
-
       maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
@@ -9687,7 +8207,6 @@
       styleOb.msElem = maskElement;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
 
   function SVGGradientStrokeStyleData(elem, data, styleOb) {
@@ -9698,7 +8217,6 @@
     this.initGradientData(elem, data, styleOb);
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
 
   function ShapeGroupData() {
@@ -9721,77 +8239,59 @@
     if (length === 0) {
       return '';
     }
-
     var _o = pathNodes.o;
     var _i = pathNodes.i;
     var _v = pathNodes.v;
     var i;
     var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
-
     for (i = 1; i < length; i += 1) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
     }
-
     if (closed && length) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
       shapeString += 'z';
     }
-
     return shapeString;
   };
 
   var SVGElementsRenderer = function () {
     var _identityMatrix = new Matrix();
-
     var _matrixHelper = new Matrix();
-
     var ob = {
       createRenderFunction: createRenderFunction
     };
-
     function createRenderFunction(data) {
       switch (data.ty) {
         case 'fl':
           return renderFill;
-
         case 'gf':
           return renderGradient;
-
         case 'gs':
           return renderGradientStroke;
-
         case 'st':
           return renderStroke;
-
         case 'sh':
         case 'el':
         case 'rc':
         case 'sr':
           return renderPath;
-
         case 'tr':
           return renderContentTransform;
-
         case 'no':
           return renderNoop;
-
         default:
           return null;
       }
     }
-
     function renderContentTransform(styleData, itemData, isFirstFrame) {
       if (isFirstFrame || itemData.transform.op._mdf) {
         itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
       }
-
       if (isFirstFrame || itemData.transform.mProps._mdf) {
         itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
       }
     }
-
     function renderNoop() {}
-
     function renderPath(styleData, itemData, isFirstFrame) {
       var j;
       var jLen;
@@ -9805,25 +8305,20 @@
       var mat;
       var iterations;
       var k;
-
       for (l = 0; l < lLen; l += 1) {
         redraw = itemData.sh._mdf || isFirstFrame;
-
         if (itemData.styles[l].lvl < lvl) {
           mat = _matrixHelper.reset();
           iterations = lvl - itemData.styles[l].lvl;
           k = itemData.transformers.length - 1;
-
           while (!redraw && iterations > 0) {
             redraw = itemData.transformers[k].mProps._mdf || redraw;
             iterations -= 1;
             k -= 1;
           }
-
           if (redraw) {
             iterations = lvl - itemData.styles[l].lvl;
             k = itemData.transformers.length - 1;
-
             while (iterations > 0) {
               mat.multiply(itemData.transformers[k].mProps.v);
               iterations -= 1;
@@ -9833,115 +8328,90 @@
         } else {
           mat = _identityMatrix;
         }
-
         paths = itemData.sh.paths;
         jLen = paths._length;
-
         if (redraw) {
           pathStringTransformed = '';
-
           for (j = 0; j < jLen; j += 1) {
             pathNodes = paths.shapes[j];
-
             if (pathNodes && pathNodes._length) {
               pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
             }
           }
-
           itemData.caches[l] = pathStringTransformed;
         } else {
           pathStringTransformed = itemData.caches[l];
         }
-
         itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
         itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
       }
     }
-
     function renderFill(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
-
       if (itemData.c._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
       }
     }
-
     function renderGradientStroke(styleData, itemData, isFirstFrame) {
       renderGradient(styleData, itemData, isFirstFrame);
       renderStroke(styleData, itemData, isFirstFrame);
     }
-
     function renderGradient(styleData, itemData, isFirstFrame) {
       var gfill = itemData.gf;
       var hasOpacity = itemData.g._hasOpacity;
       var pt1 = itemData.s.v;
       var pt2 = itemData.e.v;
-
       if (itemData.o._mdf || isFirstFrame) {
         var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
         itemData.style.pElem.setAttribute(attr, itemData.o.v);
       }
-
       if (itemData.s._mdf || isFirstFrame) {
         var attr1 = styleData.t === 1 ? 'x1' : 'cx';
         var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
         gfill.setAttribute(attr1, pt1[0]);
         gfill.setAttribute(attr2, pt1[1]);
-
         if (hasOpacity && !itemData.g._collapsable) {
           itemData.of.setAttribute(attr1, pt1[0]);
           itemData.of.setAttribute(attr2, pt1[1]);
         }
       }
-
       var stops;
       var i;
       var len;
       var stop;
-
       if (itemData.g._cmdf || isFirstFrame) {
         stops = itemData.cst;
         var cValues = itemData.g.c;
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
           stop.setAttribute('offset', cValues[i * 4] + '%');
           stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
         }
       }
-
       if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
         var oValues = itemData.g.o;
-
         if (itemData.g._collapsable) {
           stops = itemData.cst;
         } else {
           stops = itemData.ost;
         }
-
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
-
           if (!itemData.g._collapsable) {
             stop.setAttribute('offset', oValues[i * 2] + '%');
           }
-
           stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
         }
       }
-
       if (styleData.t === 1) {
         if (itemData.e._mdf || isFirstFrame) {
           gfill.setAttribute('x2', pt2[0]);
           gfill.setAttribute('y2', pt2[1]);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('x2', pt2[0]);
             itemData.of.setAttribute('y2', pt2[1]);
@@ -9949,112 +8419,93 @@
         }
       } else {
         var rad;
-
         if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
           rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           gfill.setAttribute('r', rad);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('r', rad);
           }
         }
-
-        if (itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
           if (!rad) {
             rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           }
-
           var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
           var percent = itemData.h.v;
-
           if (percent >= 1) {
             percent = 0.99;
           } else if (percent <= -1) {
             percent = -0.99;
           }
-
           var dist = rad * percent;
           var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
           var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
           gfill.setAttribute('fx', x);
           gfill.setAttribute('fy', y);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('fx', x);
             itemData.of.setAttribute('fy', y);
           }
-        } // gfill.setAttribute('fy','200');
-
+        }
+        // gfill.setAttribute('fy','200');
       }
     }
-
     function renderStroke(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
       var d = itemData.d;
-
       if (d && (d._mdf || isFirstFrame) && d.dashStr) {
         styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
         styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
       }
-
       if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
         styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
       }
-
       if (itemData.w._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
-
         if (styleElem.msElem) {
           styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
         }
       }
     }
-
     return ob;
   }();
 
   function SVGShapeElement(data, globalData, comp) {
     // List of drawable elements
-    this.shapes = []; // Full shape data
-
-    this.shapesData = data.shapes; // List of styles that will be applied to shapes
-
-    this.stylesList = []; // List of modifiers that will be applied to shapes
-
-    this.shapeModifiers = []; // List of items in shape tree
-
-    this.itemsData = []; // List of items in previous shape tree
-
-    this.processedElements = []; // List of animated components
-
+    this.shapes = [];
+    // Full shape data
+    this.shapesData = data.shapes;
+    // List of styles that will be applied to shapes
+    this.stylesList = [];
+    // List of modifiers that will be applied to shapes
+    this.shapeModifiers = [];
+    // List of items in shape tree
+    this.itemsData = [];
+    // List of items in previous shape tree
+    this.processedElements = [];
+    // List of animated components
     this.animatedContents = [];
-    this.initElement(data, globalData, comp); // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.initElement(data, globalData, comp);
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
     // List of elements that have been created
-
-    this.prevViewData = []; // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.prevViewData = [];
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
-
   SVGShapeElement.prototype.initSecondaryElement = function () {};
-
   SVGShapeElement.prototype.identityMatrix = new Matrix();
-
   SVGShapeElement.prototype.buildExpressionInterface = function () {};
-
   SVGShapeElement.prototype.createContent = function () {
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
   };
+
   /*
   This method searches for multiple shapes that affect a single element and one of them is animated
   */
-
-
   SVGShapeElement.prototype.filterUniqueShapes = function () {
     var i;
     var len = this.shapes.length;
@@ -10064,42 +8515,34 @@
     var style;
     var tempShapes = [];
     var areAnimated = false;
-
     for (j = 0; j < jLen; j += 1) {
       style = this.stylesList[j];
       areAnimated = false;
       tempShapes.length = 0;
-
       for (i = 0; i < len; i += 1) {
         shape = this.shapes[i];
-
         if (shape.styles.indexOf(style) !== -1) {
           tempShapes.push(shape);
           areAnimated = shape._isAnimated || areAnimated;
         }
       }
-
       if (tempShapes.length > 1 && areAnimated) {
         this.setShapesAsAnimated(tempShapes);
       }
     }
   };
-
   SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
     var i;
     var len = shapes.length;
-
     for (i = 0; i < len; i += 1) {
       shapes[i].setAsAnimated();
     }
   };
-
   SVGShapeElement.prototype.createStyleElement = function (data, level) {
     // TODO: prevent drawing of hidden styles
     var elementData;
     var styleOb = new SVGStyleData(data, level);
     var pathElement = styleOb.pElem;
-
     if (data.ty === 'st') {
       elementData = new SVGStrokeStyleData(this, data, styleOb);
     } else if (data.ty === 'fl') {
@@ -10108,7 +8551,6 @@
       var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
       elementData = new GradientConstructor(this, data, styleOb);
       this.globalData.defs.appendChild(elementData.gf);
-
       if (elementData.maskId) {
         this.globalData.defs.appendChild(elementData.ms);
         this.globalData.defs.appendChild(elementData.of);
@@ -10117,66 +8559,51 @@
     } else if (data.ty === 'no') {
       elementData = new SVGNoStyleData(this, data, styleOb);
     }
-
     if (data.ty === 'st' || data.ty === 'gs') {
       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);
       }
     }
-
     if (data.r === 2) {
       pathElement.setAttribute('fill-rule', 'evenodd');
     }
-
     if (data.ln) {
       pathElement.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       pathElement.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     this.stylesList.push(styleOb);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createGroupElement = function (data) {
     var elementData = new ShapeGroupData();
-
     if (data.ln) {
       elementData.gr.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       elementData.gr.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     return elementData;
   };
-
   SVGShapeElement.prototype.createTransformElement = function (data, container) {
     var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
     var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
     var ty = 4;
-
     if (data.ty === 'rc') {
       ty = 5;
     } else if (data.ty === 'el') {
@@ -10184,7 +8611,6 @@
     } else if (data.ty === 'sr') {
       ty = 7;
     }
-
     var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
     var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
     this.shapes.push(elementData);
@@ -10192,58 +8618,46 @@
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
     var i = 0;
     var len = this.animatedContents.length;
-
     while (i < len) {
       if (this.animatedContents[i].element === element) {
         return;
       }
-
       i += 1;
     }
-
     this.animatedContents.push({
       fn: SVGElementsRenderer.createRenderFunction(data),
       element: element,
       data: data
     });
   };
-
   SVGShapeElement.prototype.setElementStyles = function (elementData) {
     var arr = elementData.styles;
     var j;
     var jLen = this.stylesList.length;
-
     for (j = 0; j < jLen; j += 1) {
-      if (!this.stylesList[j].closed) {
+      if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
         arr.push(this.stylesList[j]);
       }
     }
   };
-
   SVGShapeElement.prototype.reloadShapes = function () {
     this._isFirstFrame = true;
     var i;
     var len = this.itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       this.prevViewData[i] = this.itemsData[i];
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
     len = this.dynamicProperties.length;
-
     for (i = 0; i < len; i += 1) {
       this.dynamicProperties[i].getValue();
     }
-
     this.renderModifiers();
   };
-
   SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
     var ownTransformers = [].concat(transformers);
     var i;
@@ -10255,43 +8669,35 @@
     var currentTransform;
     var modifier;
     var processedPos;
-
     for (i = len; i >= 0; i -= 1) {
       processedPos = this.searchProcessedElement(arr[i]);
-
       if (!processedPos) {
         arr[i]._render = render;
       } else {
         itemsData[i] = prevViewData[processedPos - 1];
       }
-
       if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
         if (!processedPos) {
           itemsData[i] = this.createStyleElement(arr[i], level);
         } else {
-          itemsData[i].style.closed = false;
+          itemsData[i].style.closed = arr[i].hd;
         }
-
         if (arr[i]._render) {
           if (itemsData[i].style.pElem.parentNode !== container) {
             container.appendChild(itemsData[i].style.pElem);
           }
         }
-
         ownStyles.push(itemsData[i].style);
       } else if (arr[i].ty === 'gr') {
         if (!processedPos) {
           itemsData[i] = this.createGroupElement(arr[i]);
         } else {
           jLen = itemsData[i].it.length;
-
           for (j = 0; j < jLen; j += 1) {
             itemsData[i].prevViewData[j] = itemsData[i].it[j];
           }
         }
-
         this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
-
         if (arr[i]._render) {
           if (itemsData[i].gr.parentNode !== container) {
             container.appendChild(itemsData[i].gr);
@@ -10301,14 +8707,12 @@
         if (!processedPos) {
           itemsData[i] = this.createTransformElement(arr[i], container);
         }
-
         currentTransform = itemsData[i].transform;
         ownTransformers.push(currentTransform);
       } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
         if (!processedPos) {
           itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
         }
-
         this.setElementStyles(itemsData[i]);
       } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
         if (!processedPos) {
@@ -10320,7 +8724,6 @@
           modifier = itemsData[i];
           modifier.closed = false;
         }
-
         ownModifiers.push(modifier);
       } else if (arr[i].ty === 'rp') {
         if (!processedPos) {
@@ -10333,64 +8736,49 @@
           modifier = itemsData[i];
           modifier.closed = true;
         }
-
         ownModifiers.push(modifier);
       }
-
       this.addProcessedElement(arr[i], i + 1);
     }
-
     len = ownStyles.length;
-
     for (i = 0; i < len; i += 1) {
       ownStyles[i].closed = true;
     }
-
     len = ownModifiers.length;
-
     for (i = 0; i < len; i += 1) {
       ownModifiers[i].closed = true;
     }
   };
-
   SVGShapeElement.prototype.renderInnerContent = function () {
     this.renderModifiers();
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       this.stylesList[i].reset();
     }
-
     this.renderShape();
-
     for (i = 0; i < len; i += 1) {
       if (this.stylesList[i]._mdf || this._isFirstFrame) {
         if (this.stylesList[i].msElem) {
-          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d); // Adding M0 0 fixes same mask bug on all browsers
-
+          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+          // Adding M0 0 fixes same mask bug on all browsers
           this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
         }
-
         this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
       }
     }
   };
-
   SVGShapeElement.prototype.renderShape = function () {
     var i;
     var len = this.animatedContents.length;
     var animatedContent;
-
     for (i = 0; i < len; i += 1) {
       animatedContent = this.animatedContents[i];
-
       if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
         animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
       }
     }
   };
-
   SVGShapeElement.prototype.destroy = function () {
     this.destroyBaseElement();
     this.shapesData = null;
@@ -10413,7 +8801,6 @@
       p: true
     };
   }
-
   LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
     this._mdf.o = false;
     this._mdf.sw = false;
@@ -10422,43 +8809,36 @@
     this._mdf.m = false;
     this._mdf.p = false;
     var updated = false;
-
     if (this.o !== o) {
       this.o = o;
       this._mdf.o = true;
       updated = true;
     }
-
     if (this.sw !== sw) {
       this.sw = sw;
       this._mdf.sw = true;
       updated = true;
     }
-
     if (this.sc !== sc) {
       this.sc = sc;
       this._mdf.sc = true;
       updated = true;
     }
-
     if (this.fc !== fc) {
       this.fc = fc;
       this._mdf.fc = true;
       updated = true;
     }
-
     if (this.m !== m) {
       this.m = m;
       this._mdf.m = true;
       updated = true;
     }
-
     if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
       this.p = p;
       this._mdf.p = true;
       updated = true;
     }
-
     return updated;
   };
 
@@ -10469,11 +8849,9 @@
     this.kf = false;
     this._isFirstFrame = true;
     this._mdf = false;
-
     if (data.d && data.d.sid) {
       data.d = elem.globalData.slotManager.getProp(data.d);
     }
-
     this.data = data;
     this.elem = elem;
     this.comp = this.elem.comp;
@@ -10512,73 +8890,57 @@
       __complete: false
     };
     this.copyData(this.currentData, this.data.d.k[0].s);
-
     if (!this.searchProperty()) {
       this.completeTextData(this.currentData);
     }
   }
-
   TextProperty.prototype.defaultBoxWidth = [0, 0];
-
   TextProperty.prototype.copyData = function (obj, data) {
     for (var s in data) {
       if (Object.prototype.hasOwnProperty.call(data, s)) {
         obj[s] = data[s];
       }
     }
-
     return obj;
   };
-
   TextProperty.prototype.setCurrentData = function (data) {
     if (!data.__complete) {
       this.completeTextData(data);
     }
-
     this.currentData = data;
     this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
     this._mdf = true;
   };
-
   TextProperty.prototype.searchProperty = function () {
     return this.searchKeyframes();
   };
-
   TextProperty.prototype.searchKeyframes = function () {
     this.kf = this.data.d.k.length > 1;
-
     if (this.kf) {
       this.addEffect(this.getKeyframeValue.bind(this));
     }
-
     return this.kf;
   };
-
   TextProperty.prototype.addEffect = function (effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.getValue = function (_finalValue) {
     if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
       return;
     }
-
     this.currentData.t = this.data.d.k[this.keysIndex].s.t;
     var currentValue = this.currentData;
     var currentIndex = this.keysIndex;
-
     if (this.lock) {
       this.setCurrentData(this.currentData);
       return;
     }
-
     this.lock = true;
     this._mdf = false;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
-
     for (i = 0; i < len; i += 1) {
       // Checking if index changed to prevent creating a new object every time the expression updates.
       if (currentIndex !== this.keysIndex) {
@@ -10587,38 +8949,30 @@
         finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
       }
     }
-
     if (currentValue !== finalValue) {
       this.setCurrentData(finalValue);
     }
-
     this.v = this.currentData;
     this.pv = this.v;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   };
-
   TextProperty.prototype.getKeyframeValue = function () {
     var textKeys = this.data.d.k;
     var frameNum = this.elem.comp.renderedFrame;
     var i = 0;
     var len = textKeys.length;
-
     while (i <= len - 1) {
       if (i === len - 1 || textKeys[i + 1].t > frameNum) {
         break;
       }
-
       i += 1;
     }
-
     if (this.keysIndex !== i) {
       this.keysIndex = i;
     }
-
     return this.data.d.k[this.keysIndex].s;
   };
-
   TextProperty.prototype.buildFinalText = function (text) {
     var charactersArray = [];
     var i = 0;
@@ -10628,21 +8982,20 @@
     var shouldCombine = false;
     var shouldCombineNext = false;
     var currentChars = '';
-
     while (i < len) {
       shouldCombine = shouldCombineNext;
       shouldCombineNext = false;
       charCode = text.charCodeAt(i);
       currentChars = text.charAt(i);
-
       if (FontManager.isCombinedCharacter(charCode)) {
-        shouldCombine = true; // It's a potential surrogate pair (this is the High surrogate)
+        shouldCombine = true;
+        // It's a potential surrogate pair (this is the High surrogate)
       } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
         if (FontManager.isRegionalFlag(text, i)) {
           currentChars = text.substr(i, 14);
         } else {
-          secondCharCode = text.charCodeAt(i + 1); // It's a surrogate pair (this is the Low surrogate)
-
+          secondCharCode = text.charCodeAt(i + 1);
+          // It's a surrogate pair (this is the Low surrogate)
           if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
             if (FontManager.isModifier(charCode, secondCharCode)) {
               currentChars = text.substr(i, 2);
@@ -10656,7 +9009,6 @@
         }
       } else if (charCode > 0xDBFF) {
         secondCharCode = text.charCodeAt(i + 1);
-
         if (FontManager.isVariationSelector(charCode)) {
           shouldCombine = true;
         }
@@ -10664,20 +9016,16 @@
         shouldCombine = true;
         shouldCombineNext = true;
       }
-
       if (shouldCombine) {
         charactersArray[charactersArray.length - 1] += currentChars;
         shouldCombine = false;
       } else {
         charactersArray.push(currentChars);
       }
-
       i += currentChars.length;
     }
-
     return charactersArray;
   };
-
   TextProperty.prototype.completeTextData = function (documentData) {
     documentData.__complete = true;
     var fontManager = this.elem.globalData.fontManager;
@@ -10709,14 +9057,12 @@
     documentData.finalLineHeight = documentData.lh;
     var trackingOffset = documentData.tr / 1000 * documentData.finalSize;
     var charCode;
-
     if (documentData.sz) {
       var flag = true;
       var boxWidth = documentData.sz[0];
       var boxHeight = documentData.sz[1];
       var currentHeight;
       var finalText;
-
       while (flag) {
         finalText = this.buildFinalText(documentData.t);
         currentHeight = 0;
@@ -10724,11 +9070,9 @@
         len = finalText.length;
         trackingOffset = documentData.tr / 1000 * documentData.finalSize;
         var lastSpaceIndex = -1;
-
         for (i = 0; i < len; i += 1) {
           charCode = finalText[i].charCodeAt(0);
           newLineFlag = false;
-
           if (finalText[i] === ' ') {
             lastSpaceIndex = i;
           } else if (charCode === 13 || charCode === 3) {
@@ -10736,7 +9080,6 @@
             newLineFlag = true;
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
           }
-
           if (fontManager.chars) {
             charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
             cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -10744,17 +9087,15 @@
             // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
             cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
           }
-
           if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
             if (lastSpaceIndex === -1) {
               len += 1;
             } else {
               i = lastSpaceIndex;
             }
-
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
-            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r'); // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
-
+            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+            // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
             lastSpaceIndex = -1;
             lineWidth = 0;
           } else {
@@ -10762,9 +9103,7 @@
             lineWidth += trackingOffset;
           }
         }
-
         currentHeight += fontData.ascent * documentData.finalSize / 100;
-
         if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
           documentData.finalSize -= 1;
           documentData.finalLineHeight = documentData.finalSize * documentData.lh / documentData.s;
@@ -10775,17 +9114,14 @@
         }
       }
     }
-
     lineWidth = -trackingOffset;
     cLength = 0;
     var uncollapsedSpaces = 0;
     var currentChar;
-
     for (i = 0; i < len; i += 1) {
       newLineFlag = false;
       currentChar = documentData.finalText[i];
       charCode = currentChar.charCodeAt(0);
-
       if (charCode === 13 || charCode === 3) {
         uncollapsedSpaces = 0;
         lineWidths.push(lineWidth);
@@ -10797,7 +9133,6 @@
       } else {
         val = currentChar;
       }
-
       if (fontManager.chars) {
         charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
         cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -10805,16 +9140,15 @@
         // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
         // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
         cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
-      } //
+      }
 
-
+      //
       if (currentChar === ' ') {
         uncollapsedSpaces += cLength + trackingOffset;
       } else {
         lineWidth += cLength + trackingOffset + uncollapsedSpaces;
         uncollapsedSpaces = 0;
       }
-
       letters.push({
         l: cLength,
         an: cLength,
@@ -10825,42 +9159,35 @@
         line: currentLine,
         animatorJustifyOffset: 0
       });
-
       if (anchorGrouping == 2) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || val === ' ' || i === len - 1) {
           if (val === '' || val === ' ') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           index += 1;
           currentSize = 0;
         }
       } else if (anchorGrouping == 3) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || i === len - 1) {
           if (val === '') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           currentSize = 0;
           index += 1;
         }
@@ -10870,31 +9197,25 @@
         index += 1;
       }
     }
-
     documentData.l = letters;
     maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
     lineWidths.push(lineWidth);
-
     if (documentData.sz) {
       documentData.boxWidth = documentData.sz[0];
       documentData.justifyOffset = 0;
     } else {
       documentData.boxWidth = maxLineWidth;
-
       switch (documentData.j) {
         case 1:
           documentData.justifyOffset = -documentData.boxWidth;
           break;
-
         case 2:
           documentData.justifyOffset = -documentData.boxWidth / 2;
           break;
-
         default:
           documentData.justifyOffset = 0;
       }
     }
-
     documentData.lineWidths = lineWidths;
     var animators = data.a;
     var animatorData;
@@ -10903,63 +9224,49 @@
     var based;
     var ind;
     var indexes = [];
-
     for (j = 0; j < jLen; j += 1) {
       animatorData = animators[j];
-
       if (animatorData.a.sc) {
         documentData.strokeColorAnim = true;
       }
-
       if (animatorData.a.sw) {
         documentData.strokeWidthAnim = true;
       }
-
       if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
         documentData.fillColorAnim = true;
       }
-
       ind = 0;
       based = animatorData.s.b;
-
       for (i = 0; i < len; i += 1) {
         letterData = letters[i];
         letterData.anIndexes[j] = ind;
-
         if (based == 1 && letterData.val !== '' || based == 2 && letterData.val !== '' && letterData.val !== ' ' || based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1) || based == 4 && (letterData.n || i == len - 1)) {
           // eslint-disable-line eqeqeq
           if (animatorData.s.rn === 1) {
             indexes.push(ind);
           }
-
           ind += 1;
         }
       }
-
       data.a[j].s.totalChars = ind;
       var currentInd = -1;
       var newInd;
-
       if (animatorData.s.rn === 1) {
         for (i = 0; i < len; i += 1) {
           letterData = letters[i];
-
           if (currentInd != letterData.anIndexes[j]) {
             // eslint-disable-line eqeqeq
             currentInd = letterData.anIndexes[j];
             newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
           }
-
           letterData.anIndexes[j] = newInd;
         }
       }
     }
-
     documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
     documentData.ls = documentData.ls || 0;
     documentData.ascent = fontData.ascent * documentData.finalSize / 100;
   };
-
   TextProperty.prototype.updateDocumentData = function (newData, index) {
     index = index === undefined ? this.keysIndex : index;
     var dData = this.copyData({}, this.data.d.k[index].s);
@@ -10969,7 +9276,6 @@
     this.setCurrentData(dData);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.recalculate = function (index) {
     var dData = this.data.d.k[index].s;
     dData.__complete = false;
@@ -10977,13 +9283,11 @@
     this._isFirstFrame = true;
     this.getValue(dData);
   };
-
   TextProperty.prototype.canResizeFont = function (_canResize) {
     this.canResize = _canResize;
     this.recalculate(this.keysIndex);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
     this.minimumFontSize = Math.floor(_fontValue) || 1;
     this.recalculate(this.keysIndex);
@@ -10994,7 +9298,6 @@
     var max = Math.max;
     var min = Math.min;
     var floor = Math.floor;
-
     function TextSelectorPropFactory(elem, data) {
       this._currentTextLength = -1;
       this.k = false;
@@ -11007,7 +9310,6 @@
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: 0
       }, 0, 0, this);
-
       if ('e' in data) {
         this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
       } else {
@@ -11015,7 +9317,6 @@
           v: 100
         };
       }
-
       this.o = PropertyFactory.getProp(elem, data.o || {
         k: 0
       }, 0, 0, this);
@@ -11029,48 +9330,40 @@
         k: 100
       }, 0, 0, this);
       this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
-
       if (!this.dynamicProperties.length) {
         this.getValue();
       }
     }
-
     TextSelectorPropFactory.prototype = {
       getMult: function getMult(ind) {
         if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
           this.getValue();
         }
-
         var x1 = 0;
         var y1 = 0;
         var x2 = 1;
         var y2 = 1;
-
         if (this.ne.v > 0) {
           x1 = this.ne.v / 100.0;
         } else {
           y1 = -this.ne.v / 100.0;
         }
-
         if (this.xe.v > 0) {
           x2 = 1.0 - this.xe.v / 100.0;
         } else {
           y2 = 1.0 + this.xe.v / 100.0;
         }
-
         var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
         var mult = 0;
         var s = this.finalS;
         var e = this.finalE;
         var type = this.data.sh;
-
         if (type === 2) {
           if (e === s) {
             mult = ind >= e ? 1 : 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 3) {
           if (e === s) {
@@ -11078,21 +9371,18 @@
           } else {
             mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 4) {
           if (e === s) {
             mult = 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
-
             if (mult < 0.5) {
               mult *= 2;
             } else {
               mult = 1 - 2 * (mult - 0.5);
             }
           }
-
           mult = easer(mult);
         } else if (type === 5) {
           if (e === s) {
@@ -11101,13 +9391,11 @@
             var tot = e - s;
             /* ind += 0.5;
                       mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
-
             ind = min(max(0, ind + 0.5 - s), e - s);
             var x = -tot / 2 + ind;
             var a = tot / 2;
             mult = Math.sqrt(1 - x * x / (a * a));
           }
-
           mult = easer(mult);
         } else if (type === 6) {
           if (e === s) {
@@ -11116,7 +9404,6 @@
             ind = min(max(0, ind + 0.5 - s), e - s);
             mult = (1 + Math.cos(Math.PI + Math.PI * 2 * ind / (e - s))) / 2; // eslint-disable-line
           }
-
           mult = easer(mult);
         } else {
           if (ind >= floor(s)) {
@@ -11126,9 +9413,9 @@
               mult = max(0, min(e - ind, 1));
             }
           }
-
           mult = easer(mult);
-        } // Smoothness implementation.
+        }
+        // Smoothness implementation.
         // The smoothness represents a reduced range of the original [0; 1] range.
         // if smoothness is 25%, the new range will be [0.375; 0.625]
         // Steps are:
@@ -11138,60 +9425,47 @@
         //     - subtract the threshold
         //     - divide it by the smoothness (this will return the range to [0; 1])
         // Note: If it doesn't work on some scenarios, consider applying it before the easer.
-
-
         if (this.sm.v !== 100) {
           var smoothness = this.sm.v * 0.01;
-
           if (smoothness === 0) {
             smoothness = 0.00000001;
           }
-
           var threshold = 0.5 - smoothness * 0.5;
-
           if (mult < threshold) {
             mult = 0;
           } else {
             mult = (mult - threshold) / smoothness;
-
             if (mult > 1) {
               mult = 1;
             }
           }
         }
-
         return mult * this.a.v;
       },
       getValue: function getValue(newCharsFlag) {
         this.iterateDynamicProperties();
         this._mdf = newCharsFlag || this._mdf;
         this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
-
         if (newCharsFlag && this.data.r === 2) {
           this.e.v = this._currentTextLength;
         }
-
         var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
         var o = this.o.v / divisor;
         var s = this.s.v / divisor + o;
         var e = this.e.v / divisor + o;
-
         if (s > e) {
           var _s = s;
           s = e;
           e = _s;
         }
-
         this.finalS = s;
         this.finalE = e;
       }
     };
     extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
-
     function getTextSelectorProp(elem, data, arr) {
       return new TextSelectorPropFactory(elem, data, arr);
     }
-
     return {
       getTextSelectorProp: getTextSelectorProp
     };
@@ -11241,18 +9515,15 @@
     this.lettersChangedFlag = false;
     this.initDynamicPropertyContainer(elem);
   }
-
   TextAnimatorProperty.prototype.searchProperties = function () {
     var i;
     var len = this._textData.a.length;
     var animatorProps;
     var getProp = PropertyFactory.getProp;
-
     for (i = 0; i < len; i += 1) {
       animatorProps = this._textData.a[i];
       this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
     }
-
     if (this._textData.p && 'm' in this._textData.p) {
       this._pathData = {
         a: getProp(this._elem, this._textData.p.a, 0, 0, this),
@@ -11266,17 +9537,13 @@
     } else {
       this._hasMaskedPath = false;
     }
-
     this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
   };
-
   TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
     this.lettersChangedFlag = lettersChangedFlag;
-
     if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
       return;
     }
-
     this._isFirstFrame = false;
     var alignment = this._moreOptions.alignment.v;
     var animators = this._animatorsData;
@@ -11304,18 +9571,14 @@
     var perc;
     var tanAngle;
     var mask;
-
     if (this._hasMaskedPath) {
       mask = this._pathData.m;
-
       if (!this._pathData.n || this._pathData._mdf) {
         var paths = mask.v;
-
         if (this._pathData.r.v) {
           paths = paths.reverse();
-        } // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
-
-
+        }
+        // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
         pathInfo = {
           tLength: 0,
           segments: []
@@ -11323,26 +9586,21 @@
         len = paths._length - 1;
         var bezierData;
         totalLength = 0;
-
         for (i = 0; i < len; i += 1) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[i + 1], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         i = len;
-
         if (mask.v.c) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[0], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         this._pathData.pi = pathInfo;
       }
-
       pathInfo = this._pathData.pi;
       currentLength = this._pathData.f.v;
       segmentInd = 0;
@@ -11350,20 +9608,16 @@
       segmentLength = 0;
       flag = true;
       segments = pathInfo.segments;
-
       if (currentLength < 0 && mask.v.c) {
         if (pathInfo.tLength < Math.abs(currentLength)) {
           currentLength = -Math.abs(currentLength) % pathInfo.tLength;
         }
-
         segmentInd = segments.length - 1;
         points = segments[segmentInd].points;
         pointInd = points.length - 1;
-
         while (currentLength < 0) {
           currentLength += points[pointInd].partialLength;
           pointInd -= 1;
-
           if (pointInd < 0) {
             segmentInd -= 1;
             points = segments[segmentInd].points;
@@ -11371,13 +9625,11 @@
           }
         }
       }
-
       points = segments[segmentInd].points;
       prevPoint = points[pointInd - 1];
       currentPoint = points[pointInd];
       partialLength = currentPoint.partialLength;
     }
-
     len = letters.length;
     xPos = 0;
     yPos = 0;
@@ -11408,40 +9660,35 @@
     var letterFc;
     var letterM = '';
     var letterP = this.defaultPropsArray;
-    var letterO; //
+    var letterO;
 
+    //
     if (documentData.j === 2 || documentData.j === 1) {
       var animatorJustifyOffset = 0;
       var animatorFirstCharOffset = 0;
       var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
       var lastIndex = 0;
       var isNewLine = true;
-
       for (i = 0; i < len; i += 1) {
         if (letters[i].n) {
           if (animatorJustifyOffset) {
             animatorJustifyOffset += animatorFirstCharOffset;
           }
-
           while (lastIndex < i) {
             letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
             lastIndex += 1;
           }
-
           animatorJustifyOffset = 0;
           isNewLine = true;
         } else {
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.t.propType) {
               if (isNewLine && documentData.j === 2) {
                 animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
               }
-
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
               } else {
@@ -11449,33 +9696,28 @@
               }
             }
           }
-
           isNewLine = false;
         }
       }
-
       if (animatorJustifyOffset) {
         animatorJustifyOffset += animatorFirstCharOffset;
       }
-
       while (lastIndex < i) {
         letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
         lastIndex += 1;
       }
-    } //
-
+    }
+    //
 
     for (i = 0; i < len; i += 1) {
       matrixHelper.reset();
       elemOpacity = 1;
-
       if (letters[i].n) {
         xPos = 0;
         yPos += documentData.yOffset;
         yPos += firstLine ? 1 : 0;
         currentLength = initPathPos;
         firstLine = false;
-
         if (this._hasMaskedPath) {
           segmentInd = initSegmentInd;
           pointInd = initPointInd;
@@ -11485,7 +9727,6 @@
           partialLength = currentPoint.partialLength;
           segmentLength = 0;
         }
-
         letterM = '';
         letterFc = '';
         letterSw = '';
@@ -11498,48 +9739,37 @@
               case 1:
                 currentLength += totalLength - documentData.lineWidths[letters[i].line];
                 break;
-
               case 2:
                 currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
                 break;
-
               default:
                 break;
             }
-
             currentLine = letters[i].line;
           }
-
           if (ind !== letters[i].ind) {
             if (letters[ind]) {
               currentLength += letters[ind].extra;
             }
-
             currentLength += letters[i].an / 2;
             ind = letters[i].ind;
           }
-
           currentLength += alignment[0] * letters[i].an * 0.005;
           var animatorOffset = 0;
-
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.p.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.p.v[0] * mult[0];
               } else {
                 animatorOffset += animatorProps.p.v[0] * mult;
               }
             }
-
             if (animatorProps.a.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.a.v[0] * mult[0];
               } else {
@@ -11547,14 +9777,12 @@
               }
             }
           }
-
-          flag = true; // Force alignment only works with a single line for now
-
+          flag = true;
+          // Force alignment only works with a single line for now
           if (this._pathData.a.v) {
             currentLength = letters[0].an * 0.5 + (totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind / (len - 1);
             currentLength += this._pathData.f.v;
           }
-
           while (flag) {
             if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
               perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
@@ -11565,11 +9793,9 @@
             } else if (points) {
               segmentLength += currentPoint.partialLength;
               pointInd += 1;
-
               if (pointInd >= points.length) {
                 pointInd = 0;
                 segmentInd += 1;
-
                 if (!segments[segmentInd]) {
                   if (mask.v.c) {
                     pointInd = 0;
@@ -11583,7 +9809,6 @@
                   points = segments[segmentInd].points;
                 }
               }
-
               if (points) {
                 prevPoint = currentPoint;
                 currentPoint = points[pointInd];
@@ -11591,23 +9816,21 @@
               }
             }
           }
-
           offf = letters[i].an / 2 - letters[i].add;
           matrixHelper.translate(-offf, 0, 0);
         } else {
           offf = letters[i].an / 2 - letters[i].add;
-          matrixHelper.translate(-offf, 0, 0); // Grouping alignment
+          matrixHelper.translate(-offf, 0, 0);
 
+          // Grouping alignment
           matrixHelper.translate(-alignment[0] * letters[i].an * 0.005, -alignment[1] * yOff * 0.01, 0);
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.t.propType) {
             animatorSelector = animators[j].s;
-            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars); // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
-
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
             if (xPos !== 0 || documentData.j !== 0) {
               if (this._hasMaskedPath) {
                 if (mult.length) {
@@ -11623,11 +9846,9 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           sw = documentData.sw || 0;
         }
-
         if (documentData.strokeColorAnim) {
           if (documentData.sc) {
             sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
@@ -11635,18 +9856,14 @@
             sc = [0, 0, 0];
           }
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.a.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
             } else {
@@ -11654,14 +9871,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.s.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.scale(1 + (animatorProps.s.v[0] - 1) * mult[0], 1 + (animatorProps.s.v[1] - 1) * mult[1], 1);
             } else {
@@ -11669,12 +9883,10 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
           animatorSelector = animators[j].s;
           mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
           if (animatorProps.sk.propType) {
             if (mult.length) {
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
@@ -11682,7 +9894,6 @@
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
             }
           }
-
           if (animatorProps.r.propType) {
             if (mult.length) {
               matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
@@ -11690,7 +9901,6 @@
               matrixHelper.rotateZ(-animatorProps.r.v * mult);
             }
           }
-
           if (animatorProps.ry.propType) {
             if (mult.length) {
               matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
@@ -11698,7 +9908,6 @@
               matrixHelper.rotateY(animatorProps.ry.v * mult);
             }
           }
-
           if (animatorProps.rx.propType) {
             if (mult.length) {
               matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
@@ -11706,7 +9915,6 @@
               matrixHelper.rotateX(animatorProps.rx.v * mult);
             }
           }
-
           if (animatorProps.o.propType) {
             if (mult.length) {
               elemOpacity += (animatorProps.o.v * mult[0] - elemOpacity) * mult[0];
@@ -11714,7 +9922,6 @@
               elemOpacity += (animatorProps.o.v * mult - elemOpacity) * mult;
             }
           }
-
           if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
             if (mult.length) {
               sw += animatorProps.sw.v * mult[0];
@@ -11722,7 +9929,6 @@
               sw += animatorProps.sw.v * mult;
             }
           }
-
           if (documentData.strokeColorAnim && animatorProps.sc.propType) {
             for (k = 0; k < 3; k += 1) {
               if (mult.length) {
@@ -11732,7 +9938,6 @@
               }
             }
           }
-
           if (documentData.fillColorAnim && documentData.fc) {
             if (animatorProps.fc.propType) {
               for (k = 0; k < 3; k += 1) {
@@ -11743,7 +9948,6 @@
                 }
               }
             }
-
             if (animatorProps.fh.propType) {
               if (mult.length) {
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
@@ -11751,7 +9955,6 @@
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult);
               }
             }
-
             if (animatorProps.fs.propType) {
               if (mult.length) {
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
@@ -11759,7 +9962,6 @@
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
               }
             }
-
             if (animatorProps.fb.propType) {
               if (mult.length) {
                 fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
@@ -11769,14 +9971,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.p.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (this._hasMaskedPath) {
               if (mult.length) {
                 matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
@@ -11790,68 +9989,53 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           letterSw = sw < 0 ? 0 : sw;
         }
-
         if (documentData.strokeColorAnim) {
           letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
         }
-
         if (this._hasMaskedPath) {
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(0, alignment[1] * yOff * 0.01 + yPos, 0);
-
           if (this._pathData.p.v) {
             tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
             var rot = Math.atan(tanAngle) * 180 / Math.PI;
-
             if (currentPoint.point[0] < prevPoint.point[0]) {
               rot += 180;
             }
-
             matrixHelper.rotate(-rot * Math.PI / 180);
           }
-
           matrixHelper.translate(xPathPos, yPathPos, 0);
           currentLength -= alignment[0] * letters[i].an * 0.005;
-
           if (letters[i + 1] && ind !== letters[i + 1].ind) {
             currentLength += letters[i].an / 2;
             currentLength += documentData.tr * 0.001 * documentData.finalSize;
           }
         } else {
           matrixHelper.translate(xPos, yPos, 0);
-
           if (documentData.ps) {
             // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
             matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
           }
-
           switch (documentData.j) {
             case 1:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
               break;
-
             case 2:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
               break;
-
             default:
               break;
           }
-
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(offf, 0, 0);
           matrixHelper.translate(alignment[0] * letters[i].an * 0.005, alignment[1] * yOff * 0.01, 0);
           xPos += letters[i].l + documentData.tr * 0.001 * documentData.finalSize;
         }
-
         if (renderType === 'html') {
           letterM = matrixHelper.toCSS();
         } else if (renderType === 'svg') {
@@ -11859,10 +10043,8 @@
         } else {
           letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
         }
-
         letterO = elemOpacity;
       }
-
       if (renderedLettersCount <= i) {
         letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
         this.renderedLetters.push(letterValue);
@@ -11874,22 +10056,18 @@
       }
     }
   };
-
   TextAnimatorProperty.prototype.getValue = function () {
     if (this._elem.globalData.frameId === this._frameId) {
       return;
     }
-
     this._frameId = this._elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   TextAnimatorProperty.prototype.mHelper = new Matrix();
   TextAnimatorProperty.prototype.defaultPropsArray = [];
   extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
 
   function ITextElement() {}
-
   ITextElement.prototype.initElement = function (data, globalData, comp) {
     this.lettersChangedFlag = true;
     this.initFrame();
@@ -11906,72 +10084,55 @@
     this.hide();
     this.textAnimator.searchProperties(this.dynamicProperties);
   };
-
   ITextElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
   };
-
   ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
     var j;
     var jLen = shapes.length;
     var pathNodes;
     var shapeStr = '';
-
     for (j = 0; j < jLen; j += 1) {
       if (shapes[j].ty === 'sh') {
         pathNodes = shapes[j].ks.k;
         shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
       }
     }
-
     return shapeStr;
   };
-
   ITextElement.prototype.updateDocumentData = function (newData, index) {
     this.textProperty.updateDocumentData(newData, index);
   };
-
   ITextElement.prototype.canResizeFont = function (_canResize) {
     this.textProperty.canResizeFont(_canResize);
   };
-
   ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
     this.textProperty.setMinimumFontSize(_fontSize);
   };
-
   ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
     if (documentData.ps) {
       matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
     }
-
     matrixHelper.translate(0, -documentData.ls, 0);
-
     switch (documentData.j) {
       case 1:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
         break;
-
       case 2:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
         break;
-
       default:
         break;
     }
-
     matrixHelper.translate(xPos, yPos, 0);
   };
-
   ITextElement.prototype.buildColor = function (colorData) {
     return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
   };
-
   ITextElement.prototype.emptyProp = new LetterProps();
-
   ITextElement.prototype.destroy = function () {};
-
   ITextElement.prototype.validateText = function () {
     if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
       this.buildNewText();
@@ -11983,27 +10144,22 @@
   var emptyShapeData = {
     shapes: []
   };
-
   function SVGTextLottieElement(data, globalData, comp) {
     this.textSpans = [];
     this.renderType = 'svg';
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
-
   SVGTextLottieElement.prototype.createContent = function () {
     if (this.data.singleShape && !this.globalData.fontManager.chars) {
       this.textContainer = createNS('text');
     }
   };
-
   SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
     var i = 0;
     var len = textArray.length;
     var textContents = [];
     var currentTextContent = '';
-
     while (i < len) {
       if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
         textContents.push(currentTextContent);
@@ -12011,14 +10167,11 @@
       } else {
         currentTextContent += textArray[i];
       }
-
       i += 1;
     }
-
     textContents.push(currentTextContent);
     return textContents;
   };
-
   SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
     // data should probably be cloned to apply scale separately to each instance of a text on different layers
     // but since text internal content gets only rendered once and then it's never rerendered,
@@ -12026,41 +10179,33 @@
     // Avoiding cloning is preferred since cloning each character shape data is expensive
     if (data.shapes && data.shapes.length) {
       var shape = data.shapes[0];
-
       if (shape.it) {
         var shapeItem = shape.it[shape.it.length - 1];
-
         if (shapeItem.s) {
           shapeItem.s.k[0] = scale;
           shapeItem.s.k[1] = scale;
         }
       }
     }
-
     return data;
   };
-
   SVGTextLottieElement.prototype.buildNewText = function () {
     this.addDynamicProperty(this);
     var i;
     var len;
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
-
     if (documentData.fc) {
       this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
     } else {
       this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
     }
-
     if (documentData.sc) {
       this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
       this.layerElement.setAttribute('stroke-width', documentData.sw);
     }
-
     this.layerElement.setAttribute('font-size', documentData.finalSize);
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
-
     if (fontData.fClass) {
       this.layerElement.setAttribute('class', fontData.fClass);
     } else {
@@ -12070,7 +10215,6 @@
       this.layerElement.setAttribute('font-style', fStyle);
       this.layerElement.setAttribute('font-weight', fWeight);
     }
-
     this.layerElement.setAttribute('aria-label', documentData.t);
     var letters = documentData.l || [];
     var usesGlyphs = !!this.globalData.fontManager.chars;
@@ -12083,31 +10227,25 @@
     var yPos = 0;
     var firstLine = true;
     var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
-
     if (singleShape && !usesGlyphs && !documentData.sz) {
       var tElement = this.textContainer;
       var justify = 'start';
-
       switch (documentData.j) {
         case 1:
           justify = 'end';
           break;
-
         case 2:
           justify = 'middle';
           break;
-
         default:
           justify = 'start';
           break;
       }
-
       tElement.setAttribute('text-anchor', justify);
       tElement.setAttribute('letter-spacing', trackingOffset);
       var textContent = this.buildTextContents(documentData.finalText);
       len = textContent.length;
       yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
-
       for (i = 0; i < len; i += 1) {
         tSpan = this.textSpans[i].span || createNS('tspan');
         tSpan.textContent = textContent[i];
@@ -12115,23 +10253,19 @@
         tSpan.setAttribute('y', yPos);
         tSpan.style.display = 'inherit';
         tElement.appendChild(tSpan);
-
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
             span: null,
             glyph: null
           };
         }
-
         this.textSpans[i].span = tSpan;
         yPos += documentData.finalLineHeight;
       }
-
       this.layerElement.appendChild(tElement);
     } else {
       var cachedSpansLength = this.textSpans.length;
       var charData;
-
       for (i = 0; i < len; i += 1) {
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
@@ -12140,31 +10274,24 @@
             glyph: null
           };
         }
-
         if (!usesGlyphs || !singleShape || i === 0) {
           tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
-
           if (cachedSpansLength <= i) {
             tSpan.setAttribute('stroke-linecap', 'butt');
             tSpan.setAttribute('stroke-linejoin', 'round');
             tSpan.setAttribute('stroke-miterlimit', '4');
             this.textSpans[i].span = tSpan;
-
             if (usesGlyphs) {
               var childSpan = createNS('g');
               tSpan.appendChild(childSpan);
               this.textSpans[i].childSpan = childSpan;
             }
-
             this.textSpans[i].span = tSpan;
             this.layerElement.appendChild(tSpan);
           }
-
           tSpan.style.display = 'inherit';
         }
-
         matrixHelper.reset();
-
         if (singleShape) {
           if (letters[i].n) {
             xPos = -trackingOffset;
@@ -12172,42 +10299,36 @@
             yPos += firstLine ? 1 : 0;
             firstLine = false;
           }
-
           this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
-          xPos += letters[i].l || 0; // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
-
+          xPos += letters[i].l || 0;
+          // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
           xPos += trackingOffset;
         }
-
         if (usesGlyphs) {
           charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
-          var glyphElement; // t === 1 means the character has been replaced with an animated shaped
-
+          var glyphElement;
+          // t === 1 means the character has been replaced with an animated shaped
           if (charData.t === 1) {
             glyphElement = new SVGCompElement(charData.data, this.globalData, this);
           } else {
             var data = emptyShapeData;
-
             if (charData.data && charData.data.shapes) {
               data = this.buildShapeData(charData.data, documentData.finalSize);
             }
-
             glyphElement = new SVGShapeElement(data, this.globalData, this);
           }
-
           if (this.textSpans[i].glyph) {
             var glyph = this.textSpans[i].glyph;
             this.textSpans[i].childSpan.removeChild(glyph.layerElement);
             glyph.destroy();
           }
-
           this.textSpans[i].glyph = glyphElement;
           glyphElement._debug = true;
           glyphElement.prepareFrame(0);
           glyphElement.renderFrame();
-          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement); // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+          // when using animated shapes, the layer will be scaled instead of replacing the internal scale
           // this might have issues with strokes and might need a different solution
-
           if (charData.t === 1) {
             this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
           }
@@ -12215,30 +10336,24 @@
           if (singleShape) {
             tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
           }
-
           tSpan.textContent = letters[i].val;
           tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
-        } //
-
+        }
+        //
       }
-
       if (singleShape && tSpan) {
         tSpan.setAttribute('d', shapeStr);
       }
     }
-
     while (i < this.textSpans.length) {
       this.textSpans[i].span.style.display = 'none';
       i += 1;
     }
-
     this._sizeChanged = true;
   };
-
   SVGTextLottieElement.prototype.sourceRectAtTime = function () {
     this.prepareFrame(this.comp.renderedFrame - this.data.st);
     this.renderInnerContent();
-
     if (this._sizeChanged) {
       this._sizeChanged = false;
       var textBox = this.layerElement.getBBox();
@@ -12249,35 +10364,27 @@
         height: textBox.height
       };
     }
-
     return this.bbox;
   };
-
   SVGTextLottieElement.prototype.getValue = function () {
     var i;
     var len = this.textSpans.length;
     var glyphElement;
     this.renderedFrame = this.comp.renderedFrame;
-
     for (i = 0; i < len; i += 1) {
       glyphElement = this.textSpans[i].glyph;
-
       if (glyphElement) {
         glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
-
         if (glyphElement._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   SVGTextLottieElement.prototype.renderInnerContent = function () {
     this.validateText();
-
     if (!this.data.singleShape || this._mdf) {
       this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
-
       if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
         this._sizeChanged = true;
         var i;
@@ -12288,33 +10395,26 @@
         var renderedLetter;
         var textSpan;
         var glyphElement;
-
         for (i = 0; i < len; i += 1) {
           if (!letters[i].n) {
             renderedLetter = renderedLetters[i];
             textSpan = this.textSpans[i].span;
             glyphElement = this.textSpans[i].glyph;
-
             if (glyphElement) {
               glyphElement.renderFrame();
             }
-
             if (renderedLetter._mdf.m) {
               textSpan.setAttribute('transform', renderedLetter.m);
             }
-
             if (renderedLetter._mdf.o) {
               textSpan.setAttribute('opacity', renderedLetter.o);
             }
-
             if (renderedLetter._mdf.sw) {
               textSpan.setAttribute('stroke-width', renderedLetter.sw);
             }
-
             if (renderedLetter._mdf.sc) {
               textSpan.setAttribute('stroke', renderedLetter.sc);
             }
-
             if (renderedLetter._mdf.fc) {
               textSpan.setAttribute('fill', renderedLetter.fc);
             }
@@ -12327,14 +10427,12 @@
   function ISolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([IImageElement], ISolidElement);
-
   ISolidElement.prototype.createContent = function () {
-    var rect = createNS('rect'); /// /rect.style.width = this.data.sw;
+    var rect = createNS('rect');
+    /// /rect.style.width = this.data.sw;
     /// /rect.style.height = this.data.sh;
     /// /rect.style.fill = this.data.sc;
-
     rect.setAttribute('width', this.data.sw);
     rect.setAttribute('height', this.data.sh);
     rect.setAttribute('fill', this.data.sc);
@@ -12348,59 +10446,43 @@
     this.initTransform(data, globalData, comp);
     this.initHierarchy();
   }
-
   NullElement.prototype.prepareFrame = function (num) {
     this.prepareProperties(num, true);
   };
-
   NullElement.prototype.renderFrame = function () {};
-
   NullElement.prototype.getBaseElement = function () {
     return null;
   };
-
   NullElement.prototype.destroy = function () {};
-
   NullElement.prototype.sourceRectAtTime = function () {};
-
   NullElement.prototype.hide = function () {};
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
 
   function SVGRendererBase() {}
-
   extendPrototype([BaseRenderer], SVGRendererBase);
-
   SVGRendererBase.prototype.createNull = function (data) {
     return new NullElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createShape = function (data) {
     return new SVGShapeElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createText = function (data) {
     return new SVGTextLottieElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createImage = function (data) {
     return new IImageElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createSolid = function (data) {
     return new ISolidElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.configAnimation = function (animData) {
     this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
     this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
-
     if (this.renderConfig.viewBoxSize) {
       this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
     } else {
       this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
     }
-
     if (!this.renderConfig.viewBoxOnly) {
       this.svgElement.setAttribute('width', animData.w);
       this.svgElement.setAttribute('height', animData.h);
@@ -12409,32 +10491,26 @@
       this.svgElement.style.transform = 'translate3d(0,0,0)';
       this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
     }
-
     if (this.renderConfig.width) {
       this.svgElement.setAttribute('width', this.renderConfig.width);
     }
-
     if (this.renderConfig.height) {
       this.svgElement.setAttribute('height', this.renderConfig.height);
     }
-
     if (this.renderConfig.className) {
       this.svgElement.setAttribute('class', this.renderConfig.className);
     }
-
     if (this.renderConfig.id) {
       this.svgElement.setAttribute('id', this.renderConfig.id);
     }
-
     if (this.renderConfig.focusable !== undefined) {
       this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
     }
-
-    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio); // this.layerElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+    // this.layerElement.style.transform = 'translate3d(0,0,0)';
     // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
-
-    this.animationItem.wrapper.appendChild(this.svgElement); // Mask animation
-
+    this.animationItem.wrapper.appendChild(this.svgElement);
+    // Mask animation
     var defs = this.globalData.defs;
     this.setupGlobalData(animData, defs);
     this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
@@ -12453,71 +10529,54 @@
     this.layers = animData.layers;
     this.elements = createSizedArray(animData.layers.length);
   };
-
   SVGRendererBase.prototype.destroy = function () {
     if (this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     this.layerElement = null;
     this.globalData.defs = null;
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.destroyed = true;
     this.animationItem = null;
   };
-
   SVGRendererBase.prototype.updateContainerSize = function () {};
-
   SVGRendererBase.prototype.findIndexByInd = function (ind) {
     var i = 0;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.layers[i].ind === ind) {
         return i;
       }
     }
-
     return -1;
   };
-
   SVGRendererBase.prototype.buildItem = function (pos) {
     var elements = this.elements;
-
     if (elements[pos] || this.layers[pos].ty === 99) {
       return;
     }
-
     elements[pos] = true;
     var element = this.createItem(this.layers[pos]);
     elements[pos] = element;
-
     if (getExpressionsPlugin()) {
       if (this.layers[pos].ty === 0) {
         this.globalData.projectInterface.registerComposition(element);
       }
-
       element.initExpressions();
     }
-
     this.appendElementInPos(element, pos);
-
     if (this.layers[pos].tt) {
       var elementIndex = 'tp' in this.layers[pos] ? this.findIndexByInd(this.layers[pos].tp) : pos - 1;
-
       if (elementIndex === -1) {
         return;
       }
-
       if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
         this.buildItem(elementIndex);
         this.addPendingElement(element);
@@ -12528,16 +10587,13 @@
       }
     }
   };
-
   SVGRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
-
       if (element.data.tt) {
         var i = 0;
         var len = this.elements.length;
-
         while (i < len) {
           if (this.elements[i] === element) {
             var elementIndex = 'tp' in element.data ? this.findIndexByInd(element.data.tp) : i - 1;
@@ -12546,43 +10602,36 @@
             element.setMatte(matteMask);
             break;
           }
-
           i += 1;
         }
       }
     }
   };
-
   SVGRendererBase.prototype.renderFrame = function (num) {
     if (this.renderedFrame === num || this.destroyed) {
       return;
     }
-
     if (num === null) {
       num = this.renderedFrame;
     } else {
       this.renderedFrame = num;
-    } // console.log('-------');
+    }
+    // console.log('-------');
     // console.log('FRAME ',num);
-
-
     this.globalData.frameNum = num;
     this.globalData.frameId += 1;
     this.globalData.projectInterface.currentFrame = num;
     this.globalData._mdf = false;
     var i;
     var len = this.layers.length;
-
     if (!this.completeLayers) {
       this.checkLayers(num);
     }
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(num - this.layers[i].st);
       }
     }
-
     if (this.globalData._mdf) {
       for (i = 0; i < len; i += 1) {
         if (this.completeLayers || this.elements[i]) {
@@ -12591,44 +10640,34 @@
       }
     }
   };
-
   SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
     var newElement = element.getBaseElement();
-
     if (!newElement) {
       return;
     }
-
     var i = 0;
     var nextElement;
-
     while (i < pos) {
       if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
         nextElement = this.elements[i].getBaseElement();
       }
-
       i += 1;
     }
-
     if (nextElement) {
       this.layerElement.insertBefore(newElement, nextElement);
     } else {
       this.layerElement.appendChild(newElement);
     }
   };
-
   SVGRendererBase.prototype.hide = function () {
     this.layerElement.style.display = 'none';
   };
-
   SVGRendererBase.prototype.show = function () {
     this.layerElement.style.display = 'block';
   };
 
   function ICompElement() {}
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
-
   ICompElement.prototype.initElement = function (data, globalData, comp) {
     this.initFrame();
     this.initBaseData(data, globalData, comp);
@@ -12638,13 +10677,12 @@
     this.initRendererElement();
     this.createContainerElements();
     this.createRenderableComponents();
-
     if (this.data.xt || !globalData.progressiveLoad) {
       this.buildAllItems();
     }
-
     this.hide();
   };
+
   /* ICompElement.prototype.hide = function(){
       if(!this.hidden){
           this.hideElement();
@@ -12657,77 +10695,61 @@
       }
   }; */
 
-
   ICompElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
-
     if (!this.isInRange && !this.data.xt) {
       return;
     }
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
-
       if (timeRemapped === this.data.op) {
         timeRemapped = this.data.op - 1;
       }
-
       this.renderedFrame = timeRemapped;
     } else {
       this.renderedFrame = num / this.data.sr;
     }
-
     var i;
     var len = this.elements.length;
-
     if (!this.completeLayers) {
       this.checkLayers(this.renderedFrame);
-    } // This iteration needs to be backwards because of how expressions connect between each other
-
-
+    }
+    // This iteration needs to be backwards because of how expressions connect between each other
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
-
         if (this.elements[i]._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   ICompElement.prototype.renderInnerContent = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].renderFrame();
       }
     }
   };
-
   ICompElement.prototype.setElements = function (elems) {
     this.elements = elems;
   };
-
   ICompElement.prototype.getElements = function () {
     return this.elements;
   };
-
   ICompElement.prototype.destroyElements = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i]) {
         this.elements[i].destroy();
       }
     }
   };
-
   ICompElement.prototype.destroy = function () {
     this.destroyElements();
     this.destroyBaseElement();
@@ -12744,9 +10766,7 @@
       _placeholder: true
     };
   }
-
   extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
-
   SVGCompElement.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
@@ -12757,7 +10777,6 @@
     this.renderedFrame = -1;
     this.svgElement = createNS('svg');
     var ariaLabel = '';
-
     if (config && config.title) {
       var titleElement = createNS('title');
       var titleId = createElementID();
@@ -12766,7 +10785,6 @@
       this.svgElement.appendChild(titleElement);
       ariaLabel += titleId;
     }
-
     if (config && config.description) {
       var descElement = createNS('desc');
       var descId = createElementID();
@@ -12775,11 +10793,9 @@
       this.svgElement.appendChild(descElement);
       ariaLabel += ' ' + descId;
     }
-
     if (ariaLabel) {
       this.svgElement.setAttribute('aria-labelledby', ariaLabel);
     }
-
     var defs = createNS('defs');
     this.svgElement.appendChild(defs);
     var maskElement = createNS('g');
@@ -12817,9 +10833,7 @@
     this.destroyed = false;
     this.rendererType = 'svg';
   }
-
   extendPrototype([SVGRendererBase], SVGRenderer);
-
   SVGRenderer.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
@@ -12829,19 +10843,15 @@
     this.sequenceList = [];
     this.transform_key_count = 0;
   }
-
   ShapeTransformManager.prototype = {
     addTransformSequence: function addTransformSequence(transforms) {
       var i;
       var len = transforms.length;
       var key = '_';
-
       for (i = 0; i < len; i += 1) {
         key += transforms[i].transform.key + '_';
       }
-
       var sequence = this.sequences[key];
-
       if (!sequence) {
         sequence = {
           transforms: [].concat(transforms),
@@ -12851,37 +10861,30 @@
         this.sequences[key] = sequence;
         this.sequenceList.push(sequence);
       }
-
       return sequence;
     },
     processSequence: function processSequence(sequence, isFirstFrame) {
       var i = 0;
       var len = sequence.transforms.length;
       var _mdf = isFirstFrame;
-
       while (i < len && !isFirstFrame) {
         if (sequence.transforms[i].transform.mProps._mdf) {
           _mdf = true;
           break;
         }
-
         i += 1;
       }
-
       if (_mdf) {
         sequence.finalTransform.reset();
-
         for (i = len - 1; i >= 0; i -= 1) {
           sequence.finalTransform.multiply(sequence.transforms[i].transform.mProps.v);
         }
       }
-
       sequence._mdf = _mdf;
     },
     processSequences: function processSequences(isFirstFrame) {
       var i;
       var len = this.sequenceList.length;
-
       for (i = 0; i < len; i += 1) {
         this.processSequence(this.sequenceList[i], isFirstFrame);
       }
@@ -12896,11 +10899,12 @@
     var id = '__lottie_element_luma_buffer';
     var lumaBuffer = null;
     var lumaBufferCtx = null;
-    var svg = null; // This alternate solution has a slight delay before the filter is applied, resulting in a flicker on the first frame.
+    var svg = null;
+
+    // This alternate solution has a slight delay before the filter is applied, resulting in a flicker on the first frame.
     // Keeping this here for reference, and in the future, if offscreen canvas supports url filters, this can be used.
     // For now, neither of them work for offscreen canvas, so canvas workers can't support the luma track matte mask.
     // Naming it solution 2 to mark the extra comment lines.
-
     /*
     var svgString = [
       '<svg xmlns="http://www.w3.org/2000/svg">',
@@ -12920,7 +10924,6 @@
 
     function createLumaSvgFilter() {
       var _svg = createNS('svg');
-
       var fil = createNS('filter');
       var matrix = createNS('feColorMatrix');
       fil.setAttribute('id', id);
@@ -12928,60 +10931,49 @@
       matrix.setAttribute('color-interpolation-filters', 'sRGB');
       matrix.setAttribute('values', '0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0');
       fil.appendChild(matrix);
-
       _svg.appendChild(fil);
-
       _svg.setAttribute('id', id + '_svg');
-
       if (featureSupport.svgLumaHidden) {
         _svg.style.display = 'none';
       }
-
       return _svg;
     }
-
     function loadLuma() {
       if (!lumaBuffer) {
         svg = createLumaSvgFilter();
         document.body.appendChild(svg);
         lumaBuffer = createTag('canvas');
-        lumaBufferCtx = lumaBuffer.getContext('2d'); // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
-
+        lumaBufferCtx = lumaBuffer.getContext('2d');
+        // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
         lumaBufferCtx.filter = 'url(#' + id + ')';
         lumaBufferCtx.fillStyle = 'rgba(0,0,0,0)';
         lumaBufferCtx.fillRect(0, 0, 1, 1);
       }
     }
-
     function getLuma(canvas) {
       if (!lumaBuffer) {
         loadLuma();
       }
-
       lumaBuffer.width = canvas.width;
-      lumaBuffer.height = canvas.height; // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
-
+      lumaBuffer.height = canvas.height;
+      // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
       lumaBufferCtx.filter = 'url(#' + id + ')';
       return lumaBuffer;
     }
-
     return {
       load: loadLuma,
       get: getLuma
     };
   };
-
   function createCanvas(width, height) {
     if (featureSupport.offscreenCanvas) {
       return new OffscreenCanvas(width, height);
     }
-
     var canvas = createTag('canvas');
     canvas.width = width;
     canvas.height = height;
     return canvas;
   }
-
   var assetLoader = function () {
     return {
       loadLumaCanvas: lumaLoader.load,
@@ -12991,55 +10983,44 @@
   }();
 
   var registeredEffects = {};
-
   function CVEffects(elem) {
     var i;
     var len = elem.data.ef ? elem.data.ef.length : 0;
     this.filters = [];
     var filterManager;
-
     for (i = 0; i < len; i += 1) {
       filterManager = null;
       var type = elem.data.ef[i].ty;
-
       if (registeredEffects[type]) {
         var Effect = registeredEffects[type].effect;
         filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
       }
-
       if (filterManager) {
         this.filters.push(filterManager);
       }
     }
-
     if (this.filters.length) {
       elem.addRenderableComponent(this);
     }
   }
-
   CVEffects.prototype.renderFrame = function (_isFirstFrame) {
     var i;
     var len = this.filters.length;
-
     for (i = 0; i < len; i += 1) {
       this.filters[i].renderFrame(_isFirstFrame);
     }
   };
-
   CVEffects.prototype.getEffects = function (type) {
     var i;
     var len = this.filters.length;
     var effects = [];
-
     for (i = 0; i < len; i += 1) {
       if (this.filters[i].type === type) {
         effects.push(this.filters[i]);
       }
     }
-
     return effects;
   };
-
   function registerEffect(id, effect) {
     registeredEffects[id] = {
       effect: effect
@@ -13054,27 +11035,21 @@
     var i;
     var len = this.masksProperties.length;
     var hasMasks = false;
-
     for (i = 0; i < len; i += 1) {
       if (this.masksProperties[i].mode !== 'n') {
         hasMasks = true;
       }
-
       this.viewData[i] = ShapePropertyFactory.getShapeProp(this.element, this.masksProperties[i], 3);
     }
-
     this.hasMasks = hasMasks;
-
     if (hasMasks) {
       this.element.addRenderableComponent(this);
     }
   }
-
   CVMaskElement.prototype.renderFrame = function () {
     if (!this.hasMasks) {
       return;
     }
-
     var transform = this.element.finalTransform.mat;
     var ctx = this.element.canvasContext;
     var i;
@@ -13083,7 +11058,6 @@
     var pts;
     var data;
     ctx.beginPath();
-
     for (i = 0; i < len; i += 1) {
       if (this.masksProperties[i].mode !== 'n') {
         if (this.masksProperties[i].inv) {
@@ -13093,35 +11067,28 @@
           ctx.lineTo(0, this.element.globalData.compSize.h);
           ctx.lineTo(0, 0);
         }
-
         data = this.viewData[i].v;
         pt = transform.applyToPointArray(data.v[0][0], data.v[0][1], 0);
         ctx.moveTo(pt[0], pt[1]);
         var j;
         var jLen = data._length;
-
         for (j = 1; j < jLen; j += 1) {
           pts = transform.applyToTriplePoints(data.o[j - 1], data.i[j], data.v[j]);
           ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
         }
-
         pts = transform.applyToTriplePoints(data.o[j - 1], data.i[0], data.v[0]);
         ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
       }
     }
-
     this.element.globalData.renderer.save(true);
     ctx.clip();
   };
-
   CVMaskElement.prototype.getMaskProperty = MaskElement.prototype.getMaskProperty;
-
   CVMaskElement.prototype.destroy = function () {
     this.element = null;
   };
 
   function CVBaseElement() {}
-
   var operationsMap = {
     1: 'source-in',
     2: 'source-out',
@@ -13144,12 +11111,10 @@
         this.buffers.push(bufferCanvas);
         var bufferCanvas2 = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
         this.buffers.push(bufferCanvas2);
-
         if (this.data.tt >= 3 && !document._isProxy) {
           assetLoader.loadLumaCanvas();
         }
       }
-
       this.canvasContext = this.globalData.canvasContext;
       this.transformCanvas = this.globalData.transformCanvas;
       this.renderableEffectsManager = new CVEffects(this);
@@ -13158,7 +11123,6 @@
     createContent: function createContent() {},
     setBlendMode: function setBlendMode() {
       var globalData = this.globalData;
-
       if (globalData.blendMode !== this.data.bm) {
         globalData.blendMode = this.data.bm;
         var blendModeValue = getBlendMode(this.data.bm);
@@ -13188,11 +11152,11 @@
       if (this.data.tt >= 1) {
         var buffer = this.buffers[0];
         var bufferCtx = buffer.getContext('2d');
-        this.clearCanvas(bufferCtx); // on the first buffer we store the current state of the global drawing
-
-        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0); // The next four lines are to clear the canvas
+        this.clearCanvas(bufferCtx);
+        // on the first buffer we store the current state of the global drawing
+        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+        // The next four lines are to clear the canvas
         // TODO: Check if there is a way to clear the canvas without resetting the transform
-
         this.currentTransform = this.canvasContext.getTransform();
         this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
         this.clearCanvas(this.canvasContext);
@@ -13201,43 +11165,43 @@
     },
     exitLayer: function exitLayer() {
       if (this.data.tt >= 1) {
-        var buffer = this.buffers[1]; // On the second buffer we store the current state of the global drawing
+        var buffer = this.buffers[1];
+        // On the second buffer we store the current state of the global drawing
         // that only contains the content of this layer
         // (if it is a composition, it also includes the nested layers)
-
         var bufferCtx = buffer.getContext('2d');
         this.clearCanvas(bufferCtx);
-        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0); // We clear the canvas again
-
+        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+        // We clear the canvas again
         this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
         this.clearCanvas(this.canvasContext);
-        this.canvasContext.setTransform(this.currentTransform); // We draw the mask
-
+        this.canvasContext.setTransform(this.currentTransform);
+        // We draw the mask
         var mask = this.comp.getElementById('tp' in this.data ? this.data.tp : this.data.ind - 1);
-        mask.renderFrame(true); // We draw the second buffer (that contains the content of this layer)
+        mask.renderFrame(true);
+        // We draw the second buffer (that contains the content of this layer)
+        this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
 
-        this.canvasContext.setTransform(1, 0, 0, 1, 0, 0); // If the mask is a Luma matte, we need to do two extra painting operations
+        // If the mask is a Luma matte, we need to do two extra painting operations
         // the _isProxy check is to avoid drawing a fake canvas in workers that will throw an error
-
         if (this.data.tt >= 3 && !document._isProxy) {
           // We copy the painted mask to a buffer that has a color matrix filter applied to it
           // that applies the rgb values to the alpha channel
           var lumaBuffer = assetLoader.getLumaCanvas(this.canvasContext.canvas);
           var lumaBufferCtx = lumaBuffer.getContext('2d');
           lumaBufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
-          this.clearCanvas(this.canvasContext); // we repaint the context with the mask applied to it
-
+          this.clearCanvas(this.canvasContext);
+          // we repaint the context with the mask applied to it
           this.canvasContext.drawImage(lumaBuffer, 0, 0);
         }
-
         this.canvasContext.globalCompositeOperation = operationsMap[this.data.tt];
-        this.canvasContext.drawImage(buffer, 0, 0); // We finally draw the first buffer (that contains the content of the global drawing)
+        this.canvasContext.drawImage(buffer, 0, 0);
+        // We finally draw the first buffer (that contains the content of the global drawing)
         // We use destination-over to draw the global drawing below the current layer
-
         this.canvasContext.globalCompositeOperation = 'destination-over';
         this.canvasContext.drawImage(this.buffers[0], 0, 0);
-        this.canvasContext.setTransform(this.currentTransform); // We reset the globalCompositeOperation to source-over, the standard type of operation
-
+        this.canvasContext.setTransform(this.currentTransform);
+        // We reset the globalCompositeOperation to source-over, the standard type of operation
         this.canvasContext.globalCompositeOperation = 'source-over';
       }
     },
@@ -13245,11 +11209,9 @@
       if (this.hidden || this.data.hd) {
         return;
       }
-
       if (this.data.td === 1 && !forceRender) {
         return;
       }
-
       this.renderTransform();
       this.renderRenderable();
       this.renderLocalTransform();
@@ -13262,11 +11224,9 @@
       this.renderInnerContent();
       this.globalData.renderer.restore(forceRealStack);
       this.exitLayer();
-
       if (this.maskManager.hasMasks) {
         this.globalData.renderer.restore(true);
       }
-
       if (this._isFirstFrame) {
         this._isFirstFrame = false;
       }
@@ -13286,7 +11246,6 @@
     this.styledShapes = [];
     this.tr = [0, 0, 0, 0, 0, 0];
     var ty = 4;
-
     if (data.ty === 'rc') {
       ty = 5;
     } else if (data.ty === 'el') {
@@ -13294,12 +11253,10 @@
     } else if (data.ty === 'sr') {
       ty = 7;
     }
-
     this.sh = ShapePropertyFactory.getShapeProp(element, data, ty, element);
     var i;
     var len = styles.length;
     var styledShape;
-
     for (i = 0; i < len; i += 1) {
       if (!styles[i].closed) {
         styledShape = {
@@ -13311,7 +11268,6 @@
       }
     }
   }
-
   CVShapeData.prototype.setAsAnimated = SVGShapeData.prototype.setAsAnimated;
 
   function CVShapeElement(data, globalData, comp) {
@@ -13325,7 +11281,6 @@
     this.transformsManager = new ShapeTransformManager();
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableElement], CVShapeElement);
   CVShapeElement.prototype.initElement = RenderableDOMElement.prototype.initElement;
   CVShapeElement.prototype.transformHelper = {
@@ -13333,11 +11288,9 @@
     _opMdf: false
   };
   CVShapeElement.prototype.dashResetter = [];
-
   CVShapeElement.prototype.createContent = function () {
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
   };
-
   CVShapeElement.prototype.createStyleElement = function (data, transforms) {
     var styleElem = {
       data: data,
@@ -13348,10 +11301,8 @@
       closed: data.hd === true
     };
     var elementData = {};
-
     if (data.ty === 'fl' || data.ty === 'st') {
       elementData.c = PropertyFactory.getProp(this, data.c, 1, 255, this);
-
       if (!elementData.c.k) {
         styleElem.co = 'rgb(' + bmFloor(elementData.c.v[0]) + ',' + bmFloor(elementData.c.v[1]) + ',' + bmFloor(elementData.c.v[2]) + ')';
       }
@@ -13366,28 +11317,21 @@
       }, 0, degToRads, this);
       elementData.g = new GradientProperty(this, data.g, this);
     }
-
     elementData.o = PropertyFactory.getProp(this, data.o, 0, 0.01, this);
-
     if (data.ty === 'st' || data.ty === 'gs') {
       styleElem.lc = lineCapEnum[data.lc || 2];
       styleElem.lj = lineJoinEnum[data.lj || 2];
-
       if (data.lj == 1) {
         // eslint-disable-line eqeqeq
         styleElem.ml = data.ml;
       }
-
       elementData.w = PropertyFactory.getProp(this, data.w, 0, null, this);
-
       if (!elementData.w.k) {
         styleElem.wi = elementData.w.v;
       }
-
       if (data.d) {
         var d = new DashProperty(this, data.d, 'canvas', this);
         elementData.d = d;
-
         if (!elementData.d.k) {
           styleElem.da = elementData.d.dashArray;
           styleElem["do"] = elementData.d.dashoffset[0];
@@ -13396,12 +11340,10 @@
     } else {
       styleElem.r = data.r === 2 ? 'evenodd' : 'nonzero';
     }
-
     this.stylesList.push(styleElem);
     elementData.style = styleElem;
     return elementData;
   };
-
   CVShapeElement.prototype.createGroupElement = function () {
     var elementData = {
       it: [],
@@ -13409,7 +11351,6 @@
     };
     return elementData;
   };
-
   CVShapeElement.prototype.createTransformElement = function (data) {
     var elementData = {
       transform: {
@@ -13422,65 +11363,52 @@
     };
     return elementData;
   };
-
   CVShapeElement.prototype.createShapeElement = function (data) {
     var elementData = new CVShapeData(this, data, this.stylesList, this.transformsManager);
     this.shapes.push(elementData);
     this.addShapeToModifiers(elementData);
     return elementData;
   };
-
   CVShapeElement.prototype.reloadShapes = function () {
     this._isFirstFrame = true;
     var i;
     var len = this.itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       this.prevViewData[i] = this.itemsData[i];
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
     len = this.dynamicProperties.length;
-
     for (i = 0; i < len; i += 1) {
       this.dynamicProperties[i].getValue();
     }
-
     this.renderModifiers();
     this.transformsManager.processSequences(this._isFirstFrame);
   };
-
   CVShapeElement.prototype.addTransformToStyleList = function (transform) {
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       if (!this.stylesList[i].closed) {
         this.stylesList[i].transforms.push(transform);
       }
     }
   };
-
   CVShapeElement.prototype.removeTransformFromStyleList = function () {
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       if (!this.stylesList[i].closed) {
         this.stylesList[i].transforms.pop();
       }
     }
   };
-
   CVShapeElement.prototype.closeStyles = function (styles) {
     var i;
     var len = styles.length;
-
     for (i = 0; i < len; i += 1) {
       styles[i].closed = true;
     }
   };
-
   CVShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, shouldRender, transforms) {
     var i;
     var len = arr.length - 1;
@@ -13492,42 +11420,35 @@
     var modifier;
     var currentTransform;
     var ownTransforms = [].concat(transforms);
-
     for (i = len; i >= 0; i -= 1) {
       processedPos = this.searchProcessedElement(arr[i]);
-
       if (!processedPos) {
         arr[i]._shouldRender = shouldRender;
       } else {
         itemsData[i] = prevViewData[processedPos - 1];
       }
-
       if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs') {
         if (!processedPos) {
           itemsData[i] = this.createStyleElement(arr[i], ownTransforms);
         } else {
           itemsData[i].style.closed = false;
         }
-
         ownStyles.push(itemsData[i].style);
       } else if (arr[i].ty === 'gr') {
         if (!processedPos) {
           itemsData[i] = this.createGroupElement(arr[i]);
         } else {
           jLen = itemsData[i].it.length;
-
           for (j = 0; j < jLen; j += 1) {
             itemsData[i].prevViewData[j] = itemsData[i].it[j];
           }
         }
-
         this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, shouldRender, ownTransforms);
       } else if (arr[i].ty === 'tr') {
         if (!processedPos) {
           currentTransform = this.createTransformElement(arr[i]);
           itemsData[i] = currentTransform;
         }
-
         ownTransforms.push(itemsData[i]);
         this.addTransformToStyleList(itemsData[i]);
       } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
@@ -13544,7 +11465,6 @@
           modifier = itemsData[i];
           modifier.closed = false;
         }
-
         ownModifiers.push(modifier);
       } else if (arr[i].ty === 'rp') {
         if (!processedPos) {
@@ -13557,22 +11477,17 @@
           modifier = itemsData[i];
           modifier.closed = true;
         }
-
         ownModifiers.push(modifier);
       }
-
       this.addProcessedElement(arr[i], i + 1);
     }
-
     this.removeTransformFromStyleList();
     this.closeStyles(ownStyles);
     len = ownModifiers.length;
-
     for (i = 0; i < len; i += 1) {
       ownModifiers[i].closed = true;
     }
   };
-
   CVShapeElement.prototype.renderInnerContent = function () {
     this.transformHelper.opacity = 1;
     this.transformHelper._opMdf = false;
@@ -13580,7 +11495,6 @@
     this.transformsManager.processSequences(this._isFirstFrame);
     this.renderShape(this.transformHelper, this.shapesData, this.itemsData, true);
   };
-
   CVShapeElement.prototype.renderShapeTransform = function (parentTransform, groupTransform) {
     if (parentTransform._opMdf || groupTransform.op._mdf || this._isFirstFrame) {
       groupTransform.opacity = parentTransform.opacity;
@@ -13588,7 +11502,6 @@
       groupTransform._opMdf = true;
     }
   };
-
   CVShapeElement.prototype.drawLayer = function () {
     var i;
     var len = this.stylesList.length;
@@ -13602,55 +11515,49 @@
     var ctx = this.globalData.canvasContext;
     var type;
     var currentStyle;
-
     for (i = 0; i < len; i += 1) {
       currentStyle = this.stylesList[i];
-      type = currentStyle.type; // Skipping style when
+      type = currentStyle.type;
+
+      // Skipping style when
       // Stroke width equals 0
       // style should not be rendered (extra unused repeaters)
       // current opacity equals 0
       // global opacity equals 0
-
       if (!((type === 'st' || type === 'gs') && currentStyle.wi === 0 || !currentStyle.data._shouldRender || currentStyle.coOp === 0 || this.globalData.currentGlobalAlpha === 0)) {
         renderer.save();
         elems = currentStyle.elements;
-
         if (type === 'st' || type === 'gs') {
-          renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd); // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
-
-          renderer.ctxLineWidth(currentStyle.wi); // ctx.lineWidth = currentStyle.wi;
-
-          renderer.ctxLineCap(currentStyle.lc); // ctx.lineCap = currentStyle.lc;
-
-          renderer.ctxLineJoin(currentStyle.lj); // ctx.lineJoin = currentStyle.lj;
-
-          renderer.ctxMiterLimit(currentStyle.ml || 0); // ctx.miterLimit = currentStyle.ml || 0;
+          renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd);
+          // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
+          renderer.ctxLineWidth(currentStyle.wi);
+          // ctx.lineWidth = currentStyle.wi;
+          renderer.ctxLineCap(currentStyle.lc);
+          // ctx.lineCap = currentStyle.lc;
+          renderer.ctxLineJoin(currentStyle.lj);
+          // ctx.lineJoin = currentStyle.lj;
+          renderer.ctxMiterLimit(currentStyle.ml || 0);
+          // ctx.miterLimit = currentStyle.ml || 0;
         } else {
-          renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd); // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
+          renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd);
+          // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
         }
-
         renderer.ctxOpacity(currentStyle.coOp);
-
         if (type !== 'st' && type !== 'gs') {
           ctx.beginPath();
         }
-
         renderer.ctxTransform(currentStyle.preTransforms.finalTransform.props);
         jLen = elems.length;
-
         for (j = 0; j < jLen; j += 1) {
           if (type === 'st' || type === 'gs') {
             ctx.beginPath();
-
             if (currentStyle.da) {
               ctx.setLineDash(currentStyle.da);
               ctx.lineDashOffset = currentStyle["do"];
             }
           }
-
           nodes = elems[j].trNodes;
           kLen = nodes.length;
-
           for (k = 0; k < kLen; k += 1) {
             if (nodes[k].t === 'm') {
               ctx.moveTo(nodes[k].p[0], nodes[k].p[1]);
@@ -13660,33 +11567,27 @@
               ctx.closePath();
             }
           }
-
           if (type === 'st' || type === 'gs') {
             // ctx.stroke();
             renderer.ctxStroke();
-
             if (currentStyle.da) {
               ctx.setLineDash(this.dashResetter);
             }
           }
         }
-
         if (type !== 'st' && type !== 'gs') {
           // ctx.fill(currentStyle.r);
           this.globalData.renderer.ctxFill(currentStyle.r);
         }
-
         renderer.restore();
       }
     }
   };
-
   CVShapeElement.prototype.renderShape = function (parentTransform, items, data, isMain) {
     var i;
     var len = items.length - 1;
     var groupTransform;
     groupTransform = parentTransform;
-
     for (i = len; i >= 0; i -= 1) {
       if (items[i].ty === 'tr') {
         groupTransform = data[i].transform;
@@ -13701,15 +11602,14 @@
         this.renderGradientFill(items[i], data[i], groupTransform);
       } else if (items[i].ty === 'gr') {
         this.renderShape(groupTransform, items[i].it, data[i].it);
-      } else if (items[i].ty === 'tm') {//
+      } else if (items[i].ty === 'tm') {
+        //
       }
     }
-
     if (isMain) {
       this.drawLayer();
     }
   };
-
   CVShapeElement.prototype.renderStyledShape = function (styledShape, shape) {
     if (this._isFirstFrame || shape._mdf || styledShape.transforms._mdf) {
       var shapeNodes = styledShape.trNodes;
@@ -13720,13 +11620,10 @@
       var jLen = paths._length;
       shapeNodes.length = 0;
       var groupTransformMat = styledShape.transforms.finalTransform;
-
       for (j = 0; j < jLen; j += 1) {
         var pathNodes = paths.shapes[j];
-
         if (pathNodes && pathNodes.v) {
           len = pathNodes._length;
-
           for (i = 1; i < len; i += 1) {
             if (i === 1) {
               shapeNodes.push({
@@ -13734,20 +11631,17 @@
                 p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0)
               });
             }
-
             shapeNodes.push({
               t: 'c',
               pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[i], pathNodes.v[i])
             });
           }
-
           if (len === 1) {
             shapeNodes.push({
               t: 'm',
               p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0)
             });
           }
-
           if (pathNodes.c && len) {
             shapeNodes.push({
               t: 'c',
@@ -13759,103 +11653,81 @@
           }
         }
       }
-
       styledShape.trNodes = shapeNodes;
     }
   };
-
   CVShapeElement.prototype.renderPath = function (pathData, itemData) {
     if (pathData.hd !== true && pathData._shouldRender) {
       var i;
       var len = itemData.styledShapes.length;
-
       for (i = 0; i < len; i += 1) {
         this.renderStyledShape(itemData.styledShapes[i], itemData.sh);
       }
     }
   };
-
   CVShapeElement.prototype.renderFill = function (styleData, itemData, groupTransform) {
     var styleElem = itemData.style;
-
     if (itemData.c._mdf || this._isFirstFrame) {
       styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
     }
-
     if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
       styleElem.coOp = itemData.o.v * groupTransform.opacity;
     }
   };
-
   CVShapeElement.prototype.renderGradientFill = function (styleData, itemData, groupTransform) {
     var styleElem = itemData.style;
     var grd;
-
     if (!styleElem.grd || itemData.g._mdf || itemData.s._mdf || itemData.e._mdf || styleData.t !== 1 && (itemData.h._mdf || itemData.a._mdf)) {
       var ctx = this.globalData.canvasContext;
       var pt1 = itemData.s.v;
       var pt2 = itemData.e.v;
-
       if (styleData.t === 1) {
         grd = ctx.createLinearGradient(pt1[0], pt1[1], pt2[0], pt2[1]);
       } else {
         var rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
         var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
         var percent = itemData.h.v;
-
         if (percent >= 1) {
           percent = 0.99;
         } else if (percent <= -1) {
           percent = -0.99;
         }
-
         var dist = rad * percent;
         var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
         var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
         grd = ctx.createRadialGradient(x, y, 0, pt1[0], pt1[1], rad);
       }
-
       var i;
       var len = styleData.g.p;
       var cValues = itemData.g.c;
       var opacity = 1;
-
       for (i = 0; i < len; i += 1) {
         if (itemData.g._hasOpacity && itemData.g._collapsable) {
           opacity = itemData.g.o[i * 2 + 1];
         }
-
         grd.addColorStop(cValues[i * 4] / 100, 'rgba(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ',' + opacity + ')');
       }
-
       styleElem.grd = grd;
     }
-
     styleElem.coOp = itemData.o.v * groupTransform.opacity;
   };
-
   CVShapeElement.prototype.renderStroke = function (styleData, itemData, groupTransform) {
     var styleElem = itemData.style;
     var d = itemData.d;
-
     if (d && (d._mdf || this._isFirstFrame)) {
       styleElem.da = d.dashArray;
       styleElem["do"] = d.dashoffset[0];
     }
-
     if (itemData.c._mdf || this._isFirstFrame) {
       styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
     }
-
     if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
       styleElem.coOp = itemData.o.v * groupTransform.opacity;
     }
-
     if (itemData.w._mdf || this._isFirstFrame) {
       styleElem.wi = itemData.w.v;
     }
   };
-
   CVShapeElement.prototype.destroy = function () {
     this.shapesData = null;
     this.globalData = null;
@@ -13883,31 +11755,25 @@
     };
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement, ITextElement], CVTextElement);
   CVTextElement.prototype.tHelper = createTag('canvas').getContext('2d');
-
   CVTextElement.prototype.buildNewText = function () {
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
     var hasFill = false;
-
     if (documentData.fc) {
       hasFill = true;
       this.values.fill = this.buildColor(documentData.fc);
     } else {
       this.values.fill = 'rgba(0,0,0,0)';
     }
-
     this.fill = hasFill;
     var hasStroke = false;
-
     if (documentData.sc) {
       hasStroke = true;
       this.values.stroke = this.buildColor(documentData.sc);
       this.values.sWidth = documentData.sw;
     }
-
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
     var i;
     var len;
@@ -13915,8 +11781,8 @@
     var matrixHelper = this.mHelper;
     this.stroke = hasStroke;
     this.values.fValue = documentData.finalSize + 'px ' + this.globalData.fontManager.getFontByName(documentData.f).fFamily;
-    len = documentData.finalText.length; // this.tHelper.font = this.values.fValue;
-
+    len = documentData.finalText.length;
+    // this.tHelper.font = this.values.fValue;
     var charData;
     var shapeData;
     var k;
@@ -13933,55 +11799,44 @@
     var yPos = 0;
     var firstLine = true;
     var cnt = 0;
-
     for (i = 0; i < len; i += 1) {
       charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
       shapeData = charData && charData.data || {};
       matrixHelper.reset();
-
       if (singleShape && letters[i].n) {
         xPos = -trackingOffset;
         yPos += documentData.yOffset;
         yPos += firstLine ? 1 : 0;
         firstLine = false;
       }
-
       shapes = shapeData.shapes ? shapeData.shapes[0].it : [];
       jLen = shapes.length;
       matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
-
       if (singleShape) {
         this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
       }
-
       commands = createSizedArray(jLen - 1);
       var commandsCounter = 0;
-
       for (j = 0; j < jLen; j += 1) {
         if (shapes[j].ty === 'sh') {
           kLen = shapes[j].ks.k.i.length;
           pathNodes = shapes[j].ks.k;
           pathArr = [];
-
           for (k = 1; k < kLen; k += 1) {
             if (k === 1) {
               pathArr.push(matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
             }
-
             pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToY(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToX(pathNodes.v[k][0], pathNodes.v[k][1], 0), matrixHelper.applyToY(pathNodes.v[k][0], pathNodes.v[k][1], 0));
           }
-
           pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToY(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
           commands[commandsCounter] = pathArr;
           commandsCounter += 1;
         }
       }
-
       if (singleShape) {
         xPos += letters[i].l;
         xPos += trackingOffset;
       }
-
       if (this.textSpans[cnt]) {
         this.textSpans[cnt].elem = commands;
       } else {
@@ -13989,25 +11844,23 @@
           elem: commands
         };
       }
-
       cnt += 1;
     }
   };
-
   CVTextElement.prototype.renderInnerContent = function () {
     this.validateText();
     var ctx = this.canvasContext;
     ctx.font = this.values.fValue;
-    this.globalData.renderer.ctxLineCap('butt'); // ctx.lineCap = 'butt';
-
-    this.globalData.renderer.ctxLineJoin('miter'); // ctx.lineJoin = 'miter';
-
-    this.globalData.renderer.ctxMiterLimit(4); // ctx.miterLimit = 4;
+    this.globalData.renderer.ctxLineCap('butt');
+    // ctx.lineCap = 'butt';
+    this.globalData.renderer.ctxLineJoin('miter');
+    // ctx.lineJoin = 'miter';
+    this.globalData.renderer.ctxMiterLimit(4);
+    // ctx.miterLimit = 4;
 
     if (!this.data.singleShape) {
       this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
     }
-
     var i;
     var len;
     var j;
@@ -14024,87 +11877,81 @@
     var commands;
     var pathArr;
     var renderer = this.globalData.renderer;
-
     for (i = 0; i < len; i += 1) {
       if (!letters[i].n) {
         renderedLetter = renderedLetters[i];
-
         if (renderedLetter) {
           renderer.save();
           renderer.ctxTransform(renderedLetter.p);
           renderer.ctxOpacity(renderedLetter.o);
         }
-
         if (this.fill) {
           if (renderedLetter && renderedLetter.fc) {
             if (lastFill !== renderedLetter.fc) {
               renderer.ctxFillStyle(renderedLetter.fc);
-              lastFill = renderedLetter.fc; // ctx.fillStyle = renderedLetter.fc;
+              lastFill = renderedLetter.fc;
+              // ctx.fillStyle = renderedLetter.fc;
             }
           } else if (lastFill !== this.values.fill) {
             lastFill = this.values.fill;
-            renderer.ctxFillStyle(this.values.fill); // ctx.fillStyle = this.values.fill;
+            renderer.ctxFillStyle(this.values.fill);
+            // ctx.fillStyle = this.values.fill;
           }
-
           commands = this.textSpans[i].elem;
           jLen = commands.length;
           this.globalData.canvasContext.beginPath();
-
           for (j = 0; j < jLen; j += 1) {
             pathArr = commands[j];
             kLen = pathArr.length;
             this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
-
             for (k = 2; k < kLen; k += 6) {
               this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
             }
           }
-
           this.globalData.canvasContext.closePath();
-          renderer.ctxFill(); // this.globalData.canvasContext.fill();
+          renderer.ctxFill();
+          // this.globalData.canvasContext.fill();
           /// ctx.fillText(this.textSpans[i].val,0,0);
         }
-
         if (this.stroke) {
           if (renderedLetter && renderedLetter.sw) {
             if (lastStrokeW !== renderedLetter.sw) {
               lastStrokeW = renderedLetter.sw;
-              renderer.ctxLineWidth(renderedLetter.sw); // ctx.lineWidth = renderedLetter.sw;
+              renderer.ctxLineWidth(renderedLetter.sw);
+              // ctx.lineWidth = renderedLetter.sw;
             }
           } else if (lastStrokeW !== this.values.sWidth) {
             lastStrokeW = this.values.sWidth;
-            renderer.ctxLineWidth(this.values.sWidth); // ctx.lineWidth = this.values.sWidth;
+            renderer.ctxLineWidth(this.values.sWidth);
+            // ctx.lineWidth = this.values.sWidth;
           }
-
           if (renderedLetter && renderedLetter.sc) {
             if (lastStroke !== renderedLetter.sc) {
               lastStroke = renderedLetter.sc;
-              renderer.ctxStrokeStyle(renderedLetter.sc); // ctx.strokeStyle = renderedLetter.sc;
+              renderer.ctxStrokeStyle(renderedLetter.sc);
+              // ctx.strokeStyle = renderedLetter.sc;
             }
           } else if (lastStroke !== this.values.stroke) {
             lastStroke = this.values.stroke;
-            renderer.ctxStrokeStyle(this.values.stroke); // ctx.strokeStyle = this.values.stroke;
+            renderer.ctxStrokeStyle(this.values.stroke);
+            // ctx.strokeStyle = this.values.stroke;
           }
-
           commands = this.textSpans[i].elem;
           jLen = commands.length;
           this.globalData.canvasContext.beginPath();
-
           for (j = 0; j < jLen; j += 1) {
             pathArr = commands[j];
             kLen = pathArr.length;
             this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
-
             for (k = 2; k < kLen; k += 6) {
               this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
             }
           }
-
           this.globalData.canvasContext.closePath();
-          renderer.ctxStroke(); // this.globalData.canvasContext.stroke();
+          renderer.ctxStroke();
+          // this.globalData.canvasContext.stroke();
           /// ctx.strokeText(letters[i].val,0,0);
         }
-
         if (renderedLetter) {
           this.globalData.renderer.restore();
         }
@@ -14117,11 +11964,9 @@
     this.img = globalData.imageLoader.getAsset(this.assetData);
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVImageElement);
   CVImageElement.prototype.initElement = SVGShapeElement.prototype.initElement;
   CVImageElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
-
   CVImageElement.prototype.createContent = function () {
     if (this.img.width && (this.assetData.w !== this.img.width || this.assetData.h !== this.img.height)) {
       var canvas = createTag('canvas');
@@ -14135,7 +11980,6 @@
       var widthCrop;
       var heightCrop;
       var par = this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio;
-
       if (imgRel > canvasRel && par === 'xMidYMid slice' || imgRel < canvasRel && par !== 'xMidYMid slice') {
         heightCrop = imgH;
         widthCrop = heightCrop * canvasRel;
@@ -14143,16 +11987,13 @@
         widthCrop = imgW;
         heightCrop = widthCrop / canvasRel;
       }
-
       ctx.drawImage(this.img, (imgW - widthCrop) / 2, (imgH - heightCrop) / 2, widthCrop, heightCrop, 0, 0, this.assetData.w, this.assetData.h);
       this.img = canvas;
     }
   };
-
   CVImageElement.prototype.renderInnerContent = function () {
     this.canvasContext.drawImage(this.img, 0, 0);
   };
-
   CVImageElement.prototype.destroy = function () {
     this.img = null;
   };
@@ -14160,115 +12001,89 @@
   function CVSolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVSolidElement);
   CVSolidElement.prototype.initElement = SVGShapeElement.prototype.initElement;
   CVSolidElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
-
   CVSolidElement.prototype.renderInnerContent = function () {
     // var ctx = this.canvasContext;
-    this.globalData.renderer.ctxFillStyle(this.data.sc); // ctx.fillStyle = this.data.sc;
-
-    this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh); // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
+    this.globalData.renderer.ctxFillStyle(this.data.sc);
+    // ctx.fillStyle = this.data.sc;
+    this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh);
+    // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
     //
   };
 
   function CanvasRendererBase() {}
-
   extendPrototype([BaseRenderer], CanvasRendererBase);
-
   CanvasRendererBase.prototype.createShape = function (data) {
     return new CVShapeElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createText = function (data) {
     return new CVTextElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createImage = function (data) {
     return new CVImageElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createSolid = function (data) {
     return new CVSolidElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
-
   CanvasRendererBase.prototype.ctxTransform = function (props) {
     if (props[0] === 1 && props[1] === 0 && props[4] === 0 && props[5] === 1 && props[12] === 0 && props[13] === 0) {
       return;
     }
-
     this.canvasContext.transform(props[0], props[1], props[4], props[5], props[12], props[13]);
   };
-
   CanvasRendererBase.prototype.ctxOpacity = function (op) {
     this.canvasContext.globalAlpha *= op < 0 ? 0 : op;
   };
-
   CanvasRendererBase.prototype.ctxFillStyle = function (value) {
     this.canvasContext.fillStyle = value;
   };
-
   CanvasRendererBase.prototype.ctxStrokeStyle = function (value) {
     this.canvasContext.strokeStyle = value;
   };
-
   CanvasRendererBase.prototype.ctxLineWidth = function (value) {
     this.canvasContext.lineWidth = value;
   };
-
   CanvasRendererBase.prototype.ctxLineCap = function (value) {
     this.canvasContext.lineCap = value;
   };
-
   CanvasRendererBase.prototype.ctxLineJoin = function (value) {
     this.canvasContext.lineJoin = value;
   };
-
   CanvasRendererBase.prototype.ctxMiterLimit = function (value) {
     this.canvasContext.miterLimit = value;
   };
-
   CanvasRendererBase.prototype.ctxFill = function (rule) {
     this.canvasContext.fill(rule);
   };
-
   CanvasRendererBase.prototype.ctxFillRect = function (x, y, w, h) {
     this.canvasContext.fillRect(x, y, w, h);
   };
-
   CanvasRendererBase.prototype.ctxStroke = function () {
     this.canvasContext.stroke();
   };
-
   CanvasRendererBase.prototype.reset = function () {
     if (!this.renderConfig.clearCanvas) {
       this.canvasContext.restore();
       return;
     }
-
     this.contextData.reset();
   };
-
   CanvasRendererBase.prototype.save = function () {
     this.canvasContext.save();
   };
-
   CanvasRendererBase.prototype.restore = function (actionFlag) {
     if (!this.renderConfig.clearCanvas) {
       this.canvasContext.restore();
       return;
     }
-
     if (actionFlag) {
       this.globalData.blendMode = 'source-over';
     }
-
     this.contextData.restore(actionFlag);
   };
-
   CanvasRendererBase.prototype.configAnimation = function (animData) {
     if (this.animationItem.wrapper) {
       this.animationItem.container = createTag('canvas');
@@ -14283,18 +12098,15 @@
       containerStyle.contentVisibility = this.renderConfig.contentVisibility;
       this.animationItem.wrapper.appendChild(this.animationItem.container);
       this.canvasContext = this.animationItem.container.getContext('2d');
-
       if (this.renderConfig.className) {
         this.animationItem.container.setAttribute('class', this.renderConfig.className);
       }
-
       if (this.renderConfig.id) {
         this.animationItem.container.setAttribute('id', this.renderConfig.id);
       }
     } else {
       this.canvasContext = this.renderConfig.context;
     }
-
     this.contextData.setContext(this.canvasContext);
     this.data = animData;
     this.layers = animData.layers;
@@ -14315,12 +12127,10 @@
     this.elements = createSizedArray(animData.layers.length);
     this.updateContainerSize();
   };
-
   CanvasRendererBase.prototype.updateContainerSize = function (width, height) {
     this.reset();
     var elementWidth;
     var elementHeight;
-
     if (width) {
       elementWidth = width;
       elementHeight = height;
@@ -14334,14 +12144,11 @@
         elementWidth = this.canvasContext.canvas.width;
         elementHeight = this.canvasContext.canvas.height;
       }
-
       this.canvasContext.canvas.width = elementWidth * this.renderConfig.dpr;
       this.canvasContext.canvas.height = elementHeight * this.renderConfig.dpr;
     }
-
     var elementRel;
     var animationRel;
-
     if (this.renderConfig.preserveAspectRatio.indexOf('meet') !== -1 || this.renderConfig.preserveAspectRatio.indexOf('slice') !== -1) {
       var par = this.renderConfig.preserveAspectRatio.split(' ');
       var fillType = par[1] || 'meet';
@@ -14350,7 +12157,6 @@
       var yPos = pos.substr(4);
       elementRel = elementWidth / elementHeight;
       animationRel = this.transformCanvas.w / this.transformCanvas.h;
-
       if (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice') {
         this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
         this.transformCanvas.sy = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
@@ -14358,7 +12164,6 @@
         this.transformCanvas.sx = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
         this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
       }
-
       if (xPos === 'xMid' && (animationRel < elementRel && fillType === 'meet' || animationRel > elementRel && fillType === 'slice')) {
         this.transformCanvas.tx = (elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) / 2 * this.renderConfig.dpr;
       } else if (xPos === 'xMax' && (animationRel < elementRel && fillType === 'meet' || animationRel > elementRel && fillType === 'slice')) {
@@ -14366,7 +12171,6 @@
       } else {
         this.transformCanvas.tx = 0;
       }
-
       if (yPos === 'YMid' && (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice')) {
         this.transformCanvas.ty = (elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w)) / 2 * this.renderConfig.dpr;
       } else if (yPos === 'YMax' && (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice')) {
@@ -14385,7 +12189,6 @@
       this.transformCanvas.tx = 0;
       this.transformCanvas.ty = 0;
     }
-
     this.transformCanvas.props = [this.transformCanvas.sx, 0, 0, 0, 0, this.transformCanvas.sy, 0, 0, 0, 0, 1, 0, this.transformCanvas.tx, this.transformCanvas.ty, 0, 1];
     /* var i, len = this.elements.length;
       for(i=0;i<len;i+=1){
@@ -14393,7 +12196,6 @@
               this.elements[i].resize(this.globalData.transformCanvas);
           }
       } */
-
     this.ctxTransform(this.transformCanvas.props);
     this.canvasContext.beginPath();
     this.canvasContext.rect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
@@ -14401,78 +12203,65 @@
     this.canvasContext.clip();
     this.renderFrame(this.renderedFrame, true);
   };
-
   CanvasRendererBase.prototype.destroy = function () {
     if (this.renderConfig.clearCanvas && this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.globalData.canvasContext = null;
     this.animationItem.container = null;
     this.destroyed = true;
   };
-
   CanvasRendererBase.prototype.renderFrame = function (num, forceRender) {
     if (this.renderedFrame === num && this.renderConfig.clearCanvas === true && !forceRender || this.destroyed || num === -1) {
       return;
     }
-
     this.renderedFrame = num;
     this.globalData.frameNum = num - this.animationItem._isFirstFrame;
     this.globalData.frameId += 1;
     this.globalData._mdf = !this.renderConfig.clearCanvas || forceRender;
-    this.globalData.projectInterface.currentFrame = num; // console.log('--------');
-    // console.log('NEW: ',num);
+    this.globalData.projectInterface.currentFrame = num;
 
+    // console.log('--------');
+    // console.log('NEW: ',num);
     var i;
     var len = this.layers.length;
-
     if (!this.completeLayers) {
       this.checkLayers(num);
     }
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(num - this.layers[i].st);
       }
     }
-
     if (this.globalData._mdf) {
       if (this.renderConfig.clearCanvas === true) {
         this.canvasContext.clearRect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
       } else {
         this.save();
       }
-
       for (i = len - 1; i >= 0; i -= 1) {
         if (this.completeLayers || this.elements[i]) {
           this.elements[i].renderFrame();
         }
       }
-
       if (this.renderConfig.clearCanvas !== true) {
         this.restore();
       }
     }
   };
-
   CanvasRendererBase.prototype.buildItem = function (pos) {
     var elements = this.elements;
-
     if (elements[pos] || this.layers[pos].ty === 99) {
       return;
     }
-
     var element = this.createItem(this.layers[pos], this, this.globalData);
     elements[pos] = element;
     element.initExpressions();
@@ -14480,18 +12269,15 @@
           element.resize(this.globalData.transformCanvas);
       } */
   };
-
   CanvasRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
     }
   };
-
   CanvasRendererBase.prototype.hide = function () {
     this.animationItem.container.style.display = 'none';
   };
-
   CanvasRendererBase.prototype.show = function () {
     this.animationItem.container.style.display = 'block';
   };
@@ -14507,71 +12293,61 @@
     this.miterLimit = '';
     this.id = Math.random();
   }
-
   function CVContextData() {
     this.stack = [];
     this.cArrPos = 0;
     this.cTr = new Matrix();
     var i;
     var len = 15;
-
     for (i = 0; i < len; i += 1) {
       var canvasContext = new CanvasContext();
       this.stack[i] = canvasContext;
     }
-
     this._length = len;
     this.nativeContext = null;
     this.transformMat = new Matrix();
-    this.currentOpacity = 1; //
-
+    this.currentOpacity = 1;
+    //
     this.currentFillStyle = '';
-    this.appliedFillStyle = ''; //
-
+    this.appliedFillStyle = '';
+    //
     this.currentStrokeStyle = '';
-    this.appliedStrokeStyle = ''; //
-
+    this.appliedStrokeStyle = '';
+    //
     this.currentLineWidth = '';
-    this.appliedLineWidth = ''; //
-
+    this.appliedLineWidth = '';
+    //
     this.currentLineCap = '';
-    this.appliedLineCap = ''; //
-
+    this.appliedLineCap = '';
+    //
     this.currentLineJoin = '';
-    this.appliedLineJoin = ''; //
-
+    this.appliedLineJoin = '';
+    //
     this.appliedMiterLimit = '';
     this.currentMiterLimit = '';
   }
-
   CVContextData.prototype.duplicate = function () {
     var newLength = this._length * 2;
     var i = 0;
-
     for (i = this._length; i < newLength; i += 1) {
       this.stack[i] = new CanvasContext();
     }
-
     this._length = newLength;
   };
-
   CVContextData.prototype.reset = function () {
     this.cArrPos = 0;
     this.cTr.reset();
     this.stack[this.cArrPos].opacity = 1;
   };
-
   CVContextData.prototype.restore = function (forceRestore) {
     this.cArrPos -= 1;
     var currentContext = this.stack[this.cArrPos];
     var transform = currentContext.transform;
     var i;
     var arr = this.cTr.props;
-
     for (i = 0; i < 16; i += 1) {
       arr[i] = transform[i];
     }
-
     if (forceRestore) {
       this.nativeContext.restore();
       var prevStack = this.stack[this.cArrPos + 1];
@@ -14582,14 +12358,11 @@
       this.appliedLineJoin = prevStack.lineJoin;
       this.appliedMiterLimit = prevStack.miterLimit;
     }
-
     this.nativeContext.setTransform(transform[0], transform[1], transform[4], transform[5], transform[12], transform[13]);
-
     if (forceRestore || currentContext.opacity !== -1 && this.currentOpacity !== currentContext.opacity) {
       this.nativeContext.globalAlpha = currentContext.opacity;
       this.currentOpacity = currentContext.opacity;
     }
-
     this.currentFillStyle = currentContext.fillStyle;
     this.currentStrokeStyle = currentContext.strokeStyle;
     this.currentLineWidth = currentContext.lineWidth;
@@ -14597,25 +12370,19 @@
     this.currentLineJoin = currentContext.lineJoin;
     this.currentMiterLimit = currentContext.miterLimit;
   };
-
   CVContextData.prototype.save = function (saveOnNativeFlag) {
     if (saveOnNativeFlag) {
       this.nativeContext.save();
     }
-
     var props = this.cTr.props;
-
     if (this._length <= this.cArrPos) {
       this.duplicate();
     }
-
     var currentStack = this.stack[this.cArrPos];
     var i;
-
     for (i = 0; i < 16; i += 1) {
       currentStack.transform[i] = props[i];
     }
-
     this.cArrPos += 1;
     var newStack = this.stack[this.cArrPos];
     newStack.opacity = currentStack.opacity;
@@ -14626,128 +12393,106 @@
     newStack.lineJoin = currentStack.lineJoin;
     newStack.miterLimit = currentStack.miterLimit;
   };
-
   CVContextData.prototype.setOpacity = function (value) {
     this.stack[this.cArrPos].opacity = value;
   };
-
   CVContextData.prototype.setContext = function (value) {
     this.nativeContext = value;
   };
-
   CVContextData.prototype.fillStyle = function (value) {
     if (this.stack[this.cArrPos].fillStyle !== value) {
       this.currentFillStyle = value;
       this.stack[this.cArrPos].fillStyle = value;
     }
   };
-
   CVContextData.prototype.strokeStyle = function (value) {
     if (this.stack[this.cArrPos].strokeStyle !== value) {
       this.currentStrokeStyle = value;
       this.stack[this.cArrPos].strokeStyle = value;
     }
   };
-
   CVContextData.prototype.lineWidth = function (value) {
     if (this.stack[this.cArrPos].lineWidth !== value) {
       this.currentLineWidth = value;
       this.stack[this.cArrPos].lineWidth = value;
     }
   };
-
   CVContextData.prototype.lineCap = function (value) {
     if (this.stack[this.cArrPos].lineCap !== value) {
       this.currentLineCap = value;
       this.stack[this.cArrPos].lineCap = value;
     }
   };
-
   CVContextData.prototype.lineJoin = function (value) {
     if (this.stack[this.cArrPos].lineJoin !== value) {
       this.currentLineJoin = value;
       this.stack[this.cArrPos].lineJoin = value;
     }
   };
-
   CVContextData.prototype.miterLimit = function (value) {
     if (this.stack[this.cArrPos].miterLimit !== value) {
       this.currentMiterLimit = value;
       this.stack[this.cArrPos].miterLimit = value;
     }
   };
-
   CVContextData.prototype.transform = function (props) {
-    this.transformMat.cloneFromProps(props); // Taking the last transform value from the stored stack of transforms
-
-    var currentTransform = this.cTr; // Applying the last transform value after the new transform to respect the order of transformations
-
-    this.transformMat.multiply(currentTransform); // Storing the new transformed value in the stored transform
-
+    this.transformMat.cloneFromProps(props);
+    // Taking the last transform value from the stored stack of transforms
+    var currentTransform = this.cTr;
+    // Applying the last transform value after the new transform to respect the order of transformations
+    this.transformMat.multiply(currentTransform);
+    // Storing the new transformed value in the stored transform
     currentTransform.cloneFromProps(this.transformMat.props);
-    var trProps = currentTransform.props; // Applying the new transform to the canvas
-
+    var trProps = currentTransform.props;
+    // Applying the new transform to the canvas
     this.nativeContext.setTransform(trProps[0], trProps[1], trProps[4], trProps[5], trProps[12], trProps[13]);
   };
-
   CVContextData.prototype.opacity = function (op) {
     var currentOpacity = this.stack[this.cArrPos].opacity;
     currentOpacity *= op < 0 ? 0 : op;
-
     if (this.stack[this.cArrPos].opacity !== currentOpacity) {
       if (this.currentOpacity !== op) {
         this.nativeContext.globalAlpha = op;
         this.currentOpacity = op;
       }
-
       this.stack[this.cArrPos].opacity = currentOpacity;
     }
   };
-
   CVContextData.prototype.fill = function (rule) {
     if (this.appliedFillStyle !== this.currentFillStyle) {
       this.appliedFillStyle = this.currentFillStyle;
       this.nativeContext.fillStyle = this.appliedFillStyle;
     }
-
     this.nativeContext.fill(rule);
   };
-
   CVContextData.prototype.fillRect = function (x, y, w, h) {
     if (this.appliedFillStyle !== this.currentFillStyle) {
       this.appliedFillStyle = this.currentFillStyle;
       this.nativeContext.fillStyle = this.appliedFillStyle;
     }
-
     this.nativeContext.fillRect(x, y, w, h);
   };
-
   CVContextData.prototype.stroke = function () {
     if (this.appliedStrokeStyle !== this.currentStrokeStyle) {
       this.appliedStrokeStyle = this.currentStrokeStyle;
       this.nativeContext.strokeStyle = this.appliedStrokeStyle;
     }
-
     if (this.appliedLineWidth !== this.currentLineWidth) {
       this.appliedLineWidth = this.currentLineWidth;
       this.nativeContext.lineWidth = this.appliedLineWidth;
     }
-
     if (this.appliedLineCap !== this.currentLineCap) {
       this.appliedLineCap = this.currentLineCap;
       this.nativeContext.lineCap = this.appliedLineCap;
     }
-
     if (this.appliedLineJoin !== this.currentLineJoin) {
       this.appliedLineJoin = this.currentLineJoin;
       this.nativeContext.lineJoin = this.appliedLineJoin;
     }
-
     if (this.appliedMiterLimit !== this.currentMiterLimit) {
       this.appliedMiterLimit = this.currentMiterLimit;
       this.nativeContext.miterLimit = this.appliedMiterLimit;
     }
-
     this.nativeContext.stroke();
   };
 
@@ -14761,9 +12506,7 @@
       _placeholder: true
     };
   }
-
   extendPrototype([CanvasRendererBase, ICompElement, CVBaseElement], CVCompElement);
-
   CVCompElement.prototype.renderInnerContent = function () {
     var ctx = this.canvasContext;
     ctx.beginPath();
@@ -14775,28 +12518,23 @@
     ctx.clip();
     var i;
     var len = this.layers.length;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].renderFrame();
       }
     }
   };
-
   CVCompElement.prototype.destroy = function () {
     var i;
     var len = this.layers.length;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.elements[i]) {
         this.elements[i].destroy();
       }
     }
-
     this.layers = null;
     this.elements = null;
   };
-
   CVCompElement.prototype.createComp = function (data) {
     return new CVCompElement(data, this.globalData, this);
   };
@@ -14815,11 +12553,9 @@
       runExpressions: !config || config.runExpressions === undefined || config.runExpressions
     };
     this.renderConfig.dpr = config && config.dpr || 1;
-
     if (this.animationItem.wrapper) {
       this.renderConfig.dpr = config && config.dpr || window.devicePixelRatio || 1;
     }
-
     this.renderedFrame = -1;
     this.globalData = {
       frameNum: -1,
@@ -14833,7 +12569,6 @@
     this.transformMat = new Matrix();
     this.completeLayers = false;
     this.rendererType = 'canvas';
-
     if (this.renderConfig.clearCanvas) {
       this.ctxTransform = this.contextData.transform.bind(this.contextData);
       this.ctxOpacity = this.contextData.opacity.bind(this.contextData);
@@ -14849,15 +12584,15 @@
       this.save = this.contextData.save.bind(this.contextData);
     }
   }
-
   extendPrototype([CanvasRendererBase], CanvasRenderer);
-
   CanvasRenderer.prototype.createComp = function (data) {
     return new CVCompElement(data, this.globalData, this);
   };
 
-  registerRenderer('canvas', CanvasRenderer); // Registering shape modifiers
+  // Registering renderers
+  registerRenderer('canvas', CanvasRenderer);
 
+  // Registering shape modifiers
   ShapeModifiers.registerModifier('tm', TrimModifier);
   ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
   ShapeModifiers.registerModifier('rp', RepeaterModifier);
diff --git a/build/player/lottie_light_canvas.min.js b/build/player/lottie_light_canvas.min.js
index 6932c7d..490e7b1 100644
--- a/build/player/lottie_light_canvas.min.js
+++ b/build/player/lottie_light_canvas.min.js
@@ -1 +1 @@
-"undefined"!=typeof navigator&&function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lottie=e()}(this,(function(){"use strict";var t="",e=!1,s=-999999,i=function(){return t};function a(t){return document.createElement(t)}function r(t,e){var s,i,a=t.length;for(s=0;s<a;s+=1)for(var r in i=t[s].prototype)Object.prototype.hasOwnProperty.call(i,r)&&(e.prototype[r]=i[r])}function n(t){function e(){}return e.prototype=t,e}var o=function(){function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].pause()},resume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].resume()},setRate:function(t){var e,s=this.audios.length;for(e=0;e<s;e+=1)this.audios[e].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}}(),h=function(){function t(t,e){var s,i=0,a=[];switch(t){case"int16":case"uint8c":s=1;break;default:s=1.1}for(i=0;i<e;i+=1)a.push(s);return a}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(e,s){return"float32"===e?new Float32Array(s):"int16"===e?new Int16Array(s):"uint8c"===e?new Uint8ClampedArray(s):t(e,s)}:t}();function l(t){return Array.apply(null,{length:t})}function p(t){return p="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},p(t)}var f=!0,c=null,d=null,m="",u=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),g=Math.pow,y=Math.sqrt,v=Math.floor,b=(Math.max,Math.min),_={};!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],s=e.length;for(t=0;t<s;t+=1)_[e[t]]=Math[e[t]]}(),_.random=Math.random,_.abs=function(t){if("object"===p(t)&&t.length){var e,s=l(t.length),i=t.length;for(e=0;e<i;e+=1)s[e]=Math.abs(t[e]);return s}return Math.abs(t)};var C=150,x=Math.PI/180,k=.5519;function S(t){!!t}function P(t,e,s,i){this.type=t,this.currentTime=e,this.totalTime=s,this.direction=i<0?-1:1}function D(t,e){this.type=t,this.direction=e<0?-1:1}function w(t,e,s,i){this.type=t,this.currentLoop=s,this.totalLoops=e,this.direction=i<0?-1:1}function A(t,e,s){this.type=t,this.firstFrame=e,this.totalFrames=s}function M(t,e){this.type=t,this.target=e}function T(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function F(t){this.type="configError",this.nativeError=t}var E,L=(E=0,function(){return m+"__lottie_element_"+(E+=1)});function I(t,e,s){var i,a,r,n,o,h,l,p;switch(h=s*(1-e),l=s*(1-(o=6*t-(n=Math.floor(6*t)))*e),p=s*(1-(1-o)*e),n%6){case 0:i=s,a=p,r=h;break;case 1:i=l,a=s,r=h;break;case 2:i=h,a=s,r=p;break;case 3:i=h,a=l,r=s;break;case 4:i=p,a=h,r=s;break;case 5:i=s,a=h,r=l}return[i,a,r]}function R(t,e,s){var i,a=Math.max(t,e,s),r=Math.min(t,e,s),n=a-r,o=0===a?0:n/a,h=a/255;switch(a){case r:i=0;break;case t:i=e-s+n*(e<s?6:0),i/=6*n;break;case e:i=s-t+2*n,i/=6*n;break;case s:i=t-e+4*n,i/=6*n}return[i,o,h]}function V(t,e){var s=R(255*t[0],255*t[1],255*t[2]);return s[1]+=e,s[1]>1?s[1]=1:s[1]<=0&&(s[1]=0),I(s[0],s[1],s[2])}function z(t,e){var s=R(255*t[0],255*t[1],255*t[2]);return s[2]+=e,s[2]>1?s[2]=1:s[2]<0&&(s[2]=0),I(s[0],s[1],s[2])}function O(t,e){var s=R(255*t[0],255*t[1],255*t[2]);return s[0]+=e/360,s[0]>1?s[0]-=1:s[0]<0&&(s[0]+=1),I(s[0],s[1],s[2])}!function(){var t,e,s=[];for(t=0;t<256;t+=1)e=t.toString(16),s[t]=1===e.length?"0"+e:e}();var N=function(){return c},q=function(){return d},B=function(t){C=t},W=function(){return C};function j(t){return document.createElementNS("http://www.w3.org/2000/svg",t)}function Y(t){return Y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Y(t)}var J=function(){var t,s,i=1,a=[],r={onmessage:function(){},postMessage:function(e){t({data:e})}},n={postMessage:function(t){r.onmessage({data:t})}};function o(s){if(window.Worker&&window.Blob&&e){var i=new Blob(["var _workerSelf = self; self.onmessage = ",s.toString()],{type:"text/javascript"}),a=URL.createObjectURL(i);return new Worker(a)}return t=s,r}function h(){s||(s=o((function(t){if(n.dataManager||(n.dataManager=function(){function t(a,r){var n,o,h,l,p,c,d=a.length;for(o=0;o<d;o+=1)if("ks"in(n=a[o])&&!n.completed){if(n.completed=!0,n.hasMask){var m=n.masksProperties;for(l=m.length,h=0;h<l;h+=1)if(m[h].pt.k.i)i(m[h].pt.k);else for(c=m[h].pt.k.length,p=0;p<c;p+=1)m[h].pt.k[p].s&&i(m[h].pt.k[p].s[0]),m[h].pt.k[p].e&&i(m[h].pt.k[p].e[0])}0===n.ty?(n.layers=e(n.refId,r),t(n.layers,r)):4===n.ty?s(n.shapes):5===n.ty&&f(n)}}function e(t,e){var s=function(t,e){for(var s=0,i=e.length;s<i;){if(e[s].id===t)return e[s];s+=1}return null}(t,e);return s?s.layers.__used?JSON.parse(JSON.stringify(s.layers)):(s.layers.__used=!0,s.layers):null}function s(t){var e,a,r;for(e=t.length-1;e>=0;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)i(t[e].ks.k);else for(r=t[e].ks.k.length,a=0;a<r;a+=1)t[e].ks.k[a].s&&i(t[e].ks.k[a].s[0]),t[e].ks.k[a].e&&i(t[e].ks.k[a].e[0]);else"gr"===t[e].ty&&s(t[e].it)}function i(t){var e,s=t.i.length;for(e=0;e<s;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function a(t,e){var s=e?e.split("."):[100,100,100];return t[0]>s[0]||!(s[0]>t[0])&&(t[1]>s[1]||!(s[1]>t[1])&&(t[2]>s[2]||!(s[2]>t[2])&&null))}var r,n=function(){var t=[4,4,14];function e(t){var e,s,i,a=t.length;for(e=0;e<a;e+=1)5===t[e].ty&&(i=void 0,i=(s=t[e]).t.d,s.t.d={k:[{s:i,t:0}]})}return function(s){if(a(t,s.v)&&(e(s.layers),s.assets)){var i,r=s.assets.length;for(i=0;i<r;i+=1)s.assets[i].layers&&e(s.assets[i].layers)}}}(),o=(r=[4,7,99],function(t){if(t.chars&&!a(r,t.v)){var e,i=t.chars.length;for(e=0;e<i;e+=1){var n=t.chars[e];n.data&&n.data.shapes&&(s(n.data.shapes),n.data.ip=0,n.data.op=99999,n.data.st=0,n.data.sr=1,n.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[e].t||(n.data.shapes.push({ty:"no"}),n.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}}}),h=function(){var t=[5,7,15];function e(t){var e,s,i=t.length;for(e=0;e<i;e+=1)5===t[e].ty&&(s=void 0,"number"==typeof(s=t[e].t.p).a&&(s.a={a:0,k:s.a}),"number"==typeof s.p&&(s.p={a:0,k:s.p}),"number"==typeof s.r&&(s.r={a:0,k:s.r}))}return function(s){if(a(t,s.v)&&(e(s.layers),s.assets)){var i,r=s.assets.length;for(i=0;i<r;i+=1)s.assets[i].layers&&e(s.assets[i].layers)}}}(),l=function(){var t=[4,1,9];function e(t){var s,i,a,r=t.length;for(s=0;s<r;s+=1)if("gr"===t[s].ty)e(t[s].it);else if("fl"===t[s].ty||"st"===t[s].ty)if(t[s].c.k&&t[s].c.k[0].i)for(a=t[s].c.k.length,i=0;i<a;i+=1)t[s].c.k[i].s&&(t[s].c.k[i].s[0]/=255,t[s].c.k[i].s[1]/=255,t[s].c.k[i].s[2]/=255,t[s].c.k[i].s[3]/=255),t[s].c.k[i].e&&(t[s].c.k[i].e[0]/=255,t[s].c.k[i].e[1]/=255,t[s].c.k[i].e[2]/=255,t[s].c.k[i].e[3]/=255);else t[s].c.k[0]/=255,t[s].c.k[1]/=255,t[s].c.k[2]/=255,t[s].c.k[3]/=255}function s(t){var s,i=t.length;for(s=0;s<i;s+=1)4===t[s].ty&&e(t[s].shapes)}return function(e){if(a(t,e.v)&&(s(e.layers),e.assets)){var i,r=e.assets.length;for(i=0;i<r;i+=1)e.assets[i].layers&&s(e.assets[i].layers)}}}(),p=function(){var t=[4,4,18];function e(t){var s,i,a;for(s=t.length-1;s>=0;s-=1)if("sh"===t[s].ty)if(t[s].ks.k.i)t[s].ks.k.c=t[s].closed;else for(a=t[s].ks.k.length,i=0;i<a;i+=1)t[s].ks.k[i].s&&(t[s].ks.k[i].s[0].c=t[s].closed),t[s].ks.k[i].e&&(t[s].ks.k[i].e[0].c=t[s].closed);else"gr"===t[s].ty&&e(t[s].it)}function s(t){var s,i,a,r,n,o,h=t.length;for(i=0;i<h;i+=1){if((s=t[i]).hasMask){var l=s.masksProperties;for(r=l.length,a=0;a<r;a+=1)if(l[a].pt.k.i)l[a].pt.k.c=l[a].cl;else for(o=l[a].pt.k.length,n=0;n<o;n+=1)l[a].pt.k[n].s&&(l[a].pt.k[n].s[0].c=l[a].cl),l[a].pt.k[n].e&&(l[a].pt.k[n].e[0].c=l[a].cl)}4===s.ty&&e(s.shapes)}}return function(e){if(a(t,e.v)&&(s(e.layers),e.assets)){var i,r=e.assets.length;for(i=0;i<r;i+=1)e.assets[i].layers&&s(e.assets[i].layers)}}}();function f(t){0===t.t.a.length&&t.t.p}var c={completeData:function(s){s.__complete||(l(s),n(s),o(s),h(s),p(s),t(s.layers,s.assets),function(s,i){if(s){var a=0,r=s.length;for(a=0;a<r;a+=1)1===s[a].t&&(s[a].data.layers=e(s[a].data.refId,i),t(s[a].data.layers,i))}}(s.chars,s.assets),s.__complete=!0)}};return c.checkColors=l,c.checkChars=o,c.checkPathProperties=h,c.checkShapes=p,c.completeLayers=t,c}()),n.assetLoader||(n.assetLoader=function(){function t(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")||t.response&&"object"===Y(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}return{load:function(e,s,i,a){var r,n=new XMLHttpRequest;try{n.responseType="json"}catch(t){}n.onreadystatechange=function(){if(4===n.readyState)if(200===n.status)r=t(n),i(r);else try{r=t(n),i(r)}catch(t){a&&a(t)}};try{n.open(["G","E","T"].join(""),e,!0)}catch(t){n.open(["G","E","T"].join(""),s+"/"+e,!0)}n.send()}}}()),"loadAnimation"===t.data.type)n.assetLoader.load(t.data.path,t.data.fullPath,(function(e){n.dataManager.completeData(e),n.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){n.postMessage({id:t.data.id,status:"error"})}));else if("complete"===t.data.type){var e=t.data.animation;n.dataManager.completeData(e),n.postMessage({id:t.data.id,payload:e,status:"success"})}else"loadData"===t.data.type&&n.assetLoader.load(t.data.path,t.data.fullPath,(function(e){n.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){n.postMessage({id:t.data.id,status:"error"})}))})),s.onmessage=function(t){var e=t.data,s=e.id,i=a[s];a[s]=null,"success"===e.status?i.onComplete(e.payload):i.onError&&i.onError()})}function l(t,e){var s="processId_"+(i+=1);return a[s]={onComplete:t,onError:e},s}return{loadAnimation:function(t,e,i){h();var a=l(e,i);s.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:a})},loadData:function(t,e,i){h();var a=l(e,i);s.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:a})},completeAnimation:function(t,e,i){h();var a=l(e,i);s.postMessage({type:"complete",animation:t,id:a})}}}(),H=function(){var t=function(){var t=a("canvas");t.width=1,t.height=1;var e=t.getContext("2d");return e.fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1),t}();function e(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function s(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function i(t,e,s){var i="";if(t.e)i=t.p;else if(e){var a=t.p;-1!==a.indexOf("images/")&&(a=a.split("/")[1]),i=e+a}else i=s,i+=t.u?t.u:"",i+=t.p;return i}function r(t){var e=0,s=setInterval(function(){(t.getBBox().width||e>500)&&(this._imageLoaded(),clearInterval(s)),e+=1}.bind(this),50)}function n(t){var e={assetData:t},s=i(t,this.assetsPath,this.path);return J.loadData(s,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}function o(){this._imageLoaded=e.bind(this),this._footageLoaded=s.bind(this),this.testImageLoaded=r.bind(this),this.createFootageData=n.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return o.prototype={loadAssets:function(t,e){var s;this.imagesLoadedCb=e;var i=t.length;for(s=0;s<i;s+=1)t[s].layers||(t[s].t&&"seq"!==t[s].t?3===t[s].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[s]))):(this.totalImages+=1,this.images.push(this._createImageData(t[s]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,s=this.images.length;e<s;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(e){var s=i(e,this.assetsPath,this.path),r=a("img");r.crossOrigin="anonymous",r.addEventListener("load",this._imageLoaded,!1),r.addEventListener("error",function(){n.img=t,this._imageLoaded()}.bind(this),!1),r.src=s;var n={img:r,assetData:e};return n},createImageData:function(e){var s=i(e,this.assetsPath,this.path),a=j("image");u?this.testImageLoaded(a):a.addEventListener("load",this._imageLoaded,!1),a.addEventListener("error",function(){r.img=t,this._imageLoaded()}.bind(this),!1),a.setAttributeNS("http://www.w3.org/1999/xlink","href",s),this._elementHelper.append?this._elementHelper.append(a):this._elementHelper.appendChild(a);var r={img:a,assetData:e};return r},imageLoaded:e,footageLoaded:s,setCacheType:function(t,e){"svg"===t?(this._elementHelper=e,this._createImageData=this.createImageData.bind(this)):this._createImageData=this.createImgData.bind(this)}},o}();function G(){}G.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var s=this._cbs[t],i=0;i<s.length;i+=1)s[i](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var s=0,i=this._cbs[t].length;s<i;)this._cbs[t][s]===e&&(this._cbs[t].splice(s,1),s-=1,i-=1),s+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var X=function(){function t(t){for(var e,s=t.split("\r\n"),i={},a=0,r=0;r<s.length;r+=1)2===(e=s[r].split(":")).length&&(i[e[0]]=e[1].trim(),a+=1);if(0===a)throw new Error;return i}return function(e){for(var s=[],i=0;i<e.length;i+=1){var a=e[i],r={time:a.tm,duration:a.dr};try{r.payload=JSON.parse(e[i].cm)}catch(s){try{r.payload=t(e[i].cm)}catch(t){r.payload={name:e[i].cm}}}s.push(r)}return s}}(),K=function(){function t(t){this.compositions.push(t)}return function(){function e(t){for(var e=0,s=this.compositions.length;e<s;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return e.compositions=[],e.currentFrame=0,e.registerComposition=t,e}}(),U={};function Z(t){return Z="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Z(t)}var Q=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=L(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=f,this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=K(),this.imagePreloader=new H,this.audioController=o(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new P("drawnFrame",0,0,0),this.expressionsPlugin=N()};r([G],Q),Q.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg";t.animType?e=t.animType:t.renderer&&(e=t.renderer);var s=U[e];this.renderer=new s(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||void 0===t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),J.loadAnimation(t.path,this.configAnimation,this.onSetupError))},Q.prototype.onSetupError=function(){this.trigger("data_failed")},Q.prototype.setupAnimation=function(t){J.completeAnimation(t,this.configAnimation)},Q.prototype.setData=function(t,e){e&&"object"!==Z(e)&&(e=JSON.parse(e));var s={wrapper:t,animationData:e},i=t.attributes;s.path=i.getNamedItem("data-animation-path")?i.getNamedItem("data-animation-path").value:i.getNamedItem("data-bm-path")?i.getNamedItem("data-bm-path").value:i.getNamedItem("bm-path")?i.getNamedItem("bm-path").value:"",s.animType=i.getNamedItem("data-anim-type")?i.getNamedItem("data-anim-type").value:i.getNamedItem("data-bm-type")?i.getNamedItem("data-bm-type").value:i.getNamedItem("bm-type")?i.getNamedItem("bm-type").value:i.getNamedItem("data-bm-renderer")?i.getNamedItem("data-bm-renderer").value:i.getNamedItem("bm-renderer")?i.getNamedItem("bm-renderer").value:function(){if(U.canvas)return"canvas";for(var t in U)if(U[t])return t;return""}()||"canvas";var a=i.getNamedItem("data-anim-loop")?i.getNamedItem("data-anim-loop").value:i.getNamedItem("data-bm-loop")?i.getNamedItem("data-bm-loop").value:i.getNamedItem("bm-loop")?i.getNamedItem("bm-loop").value:"";"false"===a?s.loop=!1:"true"===a?s.loop=!0:""!==a&&(s.loop=parseInt(a,10));var r=i.getNamedItem("data-anim-autoplay")?i.getNamedItem("data-anim-autoplay").value:i.getNamedItem("data-bm-autoplay")?i.getNamedItem("data-bm-autoplay").value:!i.getNamedItem("bm-autoplay")||i.getNamedItem("bm-autoplay").value;s.autoplay="false"!==r,s.name=i.getNamedItem("data-name")?i.getNamedItem("data-name").value:i.getNamedItem("data-bm-name")?i.getNamedItem("data-bm-name").value:i.getNamedItem("bm-name")?i.getNamedItem("bm-name").value:"","false"===(i.getNamedItem("data-anim-prerender")?i.getNamedItem("data-anim-prerender").value:i.getNamedItem("data-bm-prerender")?i.getNamedItem("data-bm-prerender").value:i.getNamedItem("bm-prerender")?i.getNamedItem("bm-prerender").value:"")&&(s.prerender=!1),s.path?this.setParams(s):this.trigger("destroy")},Q.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,s,i=this.animationData.layers,a=i.length,r=t.layers,n=r.length;for(s=0;s<n;s+=1)for(e=0;e<a;){if(i[e].id===r[s].id){i[e]=r[s];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(a=t.assets.length,e=0;e<a;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,J.completeAnimation(this.animationData,this.onSegmentComplete)},Q.prototype.onSegmentComplete=function(t){this.animationData=t;var e=N();e&&e.initExpressions(this),this.loadNextSegment()},Q.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var s=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,J.loadData(s,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},Q.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},Q.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},Q.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},Q.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=X(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},Q.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},Q.prototype.checkLoaded=function(){if(!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()){this.isLoaded=!0;var t=N();t&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play()}},Q.prototype.resize=function(t,e){var s="number"==typeof t?t:void 0,i="number"==typeof e?e:void 0;this.renderer.updateContainerSize(s,i)},Q.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},Q.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},Q.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},Q.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},Q.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},Q.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},Q.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},Q.prototype.getMarkerData=function(t){for(var e,s=0;s<this.markers.length;s+=1)if((e=this.markers[s]).payload&&e.payload.name===t)return e;return null},Q.prototype.goToAndStop=function(t,e,s){if(!s||this.name===s){var i=Number(t);if(isNaN(i)){var a=this.getMarkerData(t);a&&this.goToAndStop(a.time,!0)}else e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier);this.pause()}},Q.prototype.goToAndPlay=function(t,e,s){if(!s||this.name===s){var i=Number(t);if(isNaN(i)){var a=this.getMarkerData(t);a&&(a.duration?this.playSegments([a.time,a.time+a.duration],!0):this.goToAndStop(a.time,!0))}else this.goToAndStop(i,e,s);this.play()}},Q.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,s=!1;e>=this.totalFrames-1&&this.frameModifier>0?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(s=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(s=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),s&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},Q.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(this.frameModifier>0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},Q.prototype.setSegment=function(t,e){var s=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?s=t:this.currentRawFrame+this.firstFrame>e&&(s=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==s&&this.goToAndStop(s,!0)},Q.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===Z(t[0])){var s,i=t.length;for(s=0;s<i;s+=1)this.segments.push(t[s])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},Q.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},Q.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},Q.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},Q.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},Q.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},Q.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},Q.prototype.setLoop=function(t){this.loop=t},Q.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},Q.prototype.getVolume=function(){return this.audioController.getVolume()},Q.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},Q.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},Q.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},Q.prototype.getPath=function(){return this.path},Q.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var s=t.p;-1!==s.indexOf("images/")&&(s=s.split("/")[1]),e=this.assetsPath+s}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},Q.prototype.getAssetData=function(t){for(var e=0,s=this.assets.length;e<s;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},Q.prototype.hide=function(){this.renderer.hide()},Q.prototype.show=function(){this.renderer.show()},Q.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},Q.prototype.updateDocumentData=function(t,e,s){try{this.renderer.getElementByPath(t).updateDocumentData(e,s)}catch(t){}},Q.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new P(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new w(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new D(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new A(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new M(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new P(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new w(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new D(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new A(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new M(t,this))},Q.prototype.triggerRenderFrameError=function(t){var e=new T(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)},Q.prototype.triggerConfigError=function(t){var e=new F(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)};var $=function(){var t={},e=[],s=0,i=0,r=0,n=!0,o=!1;function h(t){for(var s=0,a=t.target;s<i;)e[s].animation===a&&(e.splice(s,1),s-=1,i-=1,a.isPaused||f()),s+=1}function l(t,s){if(!t)return null;for(var a=0;a<i;){if(e[a].elem===t&&null!==e[a].elem)return e[a].animation;a+=1}var r=new Q;return c(r,t),r.setData(t,s),r}function p(){r+=1,u()}function f(){r-=1}function c(t,s){t.addEventListener("destroy",h),t.addEventListener("_active",p),t.addEventListener("_idle",f),e.push({elem:s,animation:t}),i+=1}function d(t){var a,h=t-s;for(a=0;a<i;a+=1)e[a].animation.advanceTime(h);s=t,r&&!o?window.requestAnimationFrame(d):n=!0}function m(t){s=t,window.requestAnimationFrame(d)}function u(){!o&&r&&n&&(window.requestAnimationFrame(m),n=!1)}return t.registerAnimation=l,t.loadAnimation=function(t){var e=new Q;return c(e,null),e.setParams(t),e},t.setSpeed=function(t,s){var a;for(a=0;a<i;a+=1)e[a].animation.setSpeed(t,s)},t.setDirection=function(t,s){var a;for(a=0;a<i;a+=1)e[a].animation.setDirection(t,s)},t.play=function(t){var s;for(s=0;s<i;s+=1)e[s].animation.play(t)},t.pause=function(t){var s;for(s=0;s<i;s+=1)e[s].animation.pause(t)},t.stop=function(t){var s;for(s=0;s<i;s+=1)e[s].animation.stop(t)},t.togglePause=function(t){var s;for(s=0;s<i;s+=1)e[s].animation.togglePause(t)},t.searchAnimations=function(t,e,s){var i,r=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),n=r.length;for(i=0;i<n;i+=1)s&&r[i].setAttribute("data-bm-type",s),l(r[i],t);if(e&&0===n){s||(s="svg");var o=document.getElementsByTagName("body")[0];o.innerText="";var h=a("div");h.style.width="100%",h.style.height="100%",h.setAttribute("data-bm-type",s),o.appendChild(h),l(h,t)}},t.resize=function(){var t;for(t=0;t<i;t+=1)e[t].animation.resize()},t.goToAndStop=function(t,s,a){var r;for(r=0;r<i;r+=1)e[r].animation.goToAndStop(t,s,a)},t.destroy=function(t){var s;for(s=i-1;s>=0;s-=1)e[s].animation.destroy(t)},t.freeze=function(){o=!0},t.unfreeze=function(){o=!1,u()},t.setVolume=function(t,s){var a;for(a=0;a<i;a+=1)e[a].animation.setVolume(t,s)},t.mute=function(t){var s;for(s=0;s<i;s+=1)e[s].animation.mute(t)},t.unmute=function(t){var s;for(s=0;s<i;s+=1)e[s].animation.unmute(t)},t.getRegisteredAnimations=function(){var t,s=e.length,i=[];for(t=0;t<s;t+=1)i.push(e[t].animation);return i},t}(),tt=function(){var t={getBezierEasing:function(t,s,i,a,r){var n=r||("bez_"+t+"_"+s+"_"+i+"_"+a).replace(/\./g,"p");if(e[n])return e[n];var o=new l([t,s,i,a]);return e[n]=o,o}},e={};var s=.1,i="function"==typeof Float32Array;function a(t,e){return 1-3*e+3*t}function r(t,e){return 3*e-6*t}function n(t){return 3*t}function o(t,e,s){return((a(e,s)*t+r(e,s))*t+n(e))*t}function h(t,e,s){return 3*a(e,s)*t*t+2*r(e,s)*t+n(e)}function l(t){this._p=t,this._mSampleValues=i?new Float32Array(11):new Array(11),this._precomputed=!1,this.get=this.get.bind(this)}return l.prototype={get:function(t){var e=this._p[0],s=this._p[1],i=this._p[2],a=this._p[3];return this._precomputed||this._precompute(),e===s&&i===a?t:0===t?0:1===t?1:o(this._getTForX(t),s,a)},_precompute:function(){var t=this._p[0],e=this._p[1],s=this._p[2],i=this._p[3];this._precomputed=!0,t===e&&s===i||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],i=0;i<11;++i)this._mSampleValues[i]=o(i*s,t,e)},_getTForX:function(t){for(var e=this._p[0],i=this._p[2],a=this._mSampleValues,r=0,n=1;10!==n&&a[n]<=t;++n)r+=s;var l=r+(t-a[--n])/(a[n+1]-a[n])*s,p=h(l,e,i);return p>=.001?function(t,e,s,i){for(var a=0;a<4;++a){var r=h(e,s,i);if(0===r)return e;e-=(o(e,s,i)-t)/r}return e}(t,l,e,i):0===p?l:function(t,e,s,i,a){var r,n,h=0;do{(r=o(n=e+(s-e)/2,i,a)-t)>0?s=n:e=n}while(Math.abs(r)>1e-7&&++h<10);return n}(t,r,r+s,e,i)}},t}(),et={double:function(t){return t.concat(l(t.length))}},st=function(t,e,s){var i=0,a=t,r=l(a);return{newElement:function(){return i?r[i-=1]:e()},release:function(t){i===a&&(r=et.double(r),a*=2),s&&s(t),r[i]=t,i+=1}}},it=st(8,(function(){return{addedLength:0,percents:h("float32",W()),lengths:h("float32",W())}})),at=st(8,(function(){return{lengths:[],totalLength:0}}),(function(t){var e,s=t.lengths.length;for(e=0;e<s;e+=1)it.release(t.lengths[e]);t.lengths.length=0}));var rt=function(){var t=Math;function e(t,e,s,i,a,r){var n=t*i+e*a+s*r-a*i-r*t-s*e;return n>-.001&&n<.001}var s=function(t,e,s,i){var a,r,n,o,h,l,p=W(),f=0,c=[],d=[],m=it.newElement();for(n=s.length,a=0;a<p;a+=1){for(h=a/(p-1),l=0,r=0;r<n;r+=1)o=g(1-h,3)*t[r]+3*g(1-h,2)*h*s[r]+3*(1-h)*g(h,2)*i[r]+g(h,3)*e[r],c[r]=o,null!==d[r]&&(l+=g(c[r]-d[r],2)),d[r]=c[r];l&&(f+=l=y(l)),m.percents[a]=h,m.lengths[a]=f}return m.addedLength=f,m};function i(t){this.segmentLength=0,this.points=new Array(t)}function a(t,e){this.partialLength=t,this.point=e}var r,n=(r={},function(t,s,n,o){var h=(t[0]+"_"+t[1]+"_"+s[0]+"_"+s[1]+"_"+n[0]+"_"+n[1]+"_"+o[0]+"_"+o[1]).replace(/\./g,"p");if(!r[h]){var p,f,c,d,m,u,v,b=W(),_=0,C=null;2===t.length&&(t[0]!==s[0]||t[1]!==s[1])&&e(t[0],t[1],s[0],s[1],t[0]+n[0],t[1]+n[1])&&e(t[0],t[1],s[0],s[1],s[0]+o[0],s[1]+o[1])&&(b=2);var x=new i(b);for(c=n.length,p=0;p<b;p+=1){for(v=l(c),m=p/(b-1),u=0,f=0;f<c;f+=1)d=g(1-m,3)*t[f]+3*g(1-m,2)*m*(t[f]+n[f])+3*(1-m)*g(m,2)*(s[f]+o[f])+g(m,3)*s[f],v[f]=d,null!==C&&(u+=g(v[f]-C[f],2));_+=u=y(u),x.points[p]=new a(u,v),C=v}x.segmentLength=_,r[h]=x}return r[h]});function o(t,e){var s=e.percents,i=e.lengths,a=s.length,r=v((a-1)*t),n=t*e.addedLength,o=0;if(r===a-1||0===r||n===i[r])return s[r];for(var h=i[r]>n?-1:1,l=!0;l;)if(i[r]<=n&&i[r+1]>n?(o=(n-i[r])/(i[r+1]-i[r]),l=!1):r+=h,r<0||r>=a-1){if(r===a-1)return s[r];l=!1}return s[r]+(s[r+1]-s[r])*o}var p=h("float32",8);return{getSegmentsLength:function(t){var e,i=at.newElement(),a=t.c,r=t.v,n=t.o,o=t.i,h=t._length,l=i.lengths,p=0;for(e=0;e<h-1;e+=1)l[e]=s(r[e],r[e+1],n[e],o[e+1]),p+=l[e].addedLength;return a&&h&&(l[e]=s(r[e],r[0],n[e],o[0]),p+=l[e].addedLength),i.totalLength=p,i},getNewSegment:function(e,s,i,a,r,n,h){r<0?r=0:r>1&&(r=1);var l,f=o(r,h),c=o(n=n>1?1:n,h),d=e.length,m=1-f,u=1-c,g=m*m*m,y=f*m*m*3,v=f*f*m*3,b=f*f*f,_=m*m*u,C=f*m*u+m*f*u+m*m*c,x=f*f*u+m*f*c+f*m*c,k=f*f*c,S=m*u*u,P=f*u*u+m*c*u+m*u*c,D=f*c*u+m*c*c+f*u*c,w=f*c*c,A=u*u*u,M=c*u*u+u*c*u+u*u*c,T=c*c*u+u*c*c+c*u*c,F=c*c*c;for(l=0;l<d;l+=1)p[4*l]=t.round(1e3*(g*e[l]+y*i[l]+v*a[l]+b*s[l]))/1e3,p[4*l+1]=t.round(1e3*(_*e[l]+C*i[l]+x*a[l]+k*s[l]))/1e3,p[4*l+2]=t.round(1e3*(S*e[l]+P*i[l]+D*a[l]+w*s[l]))/1e3,p[4*l+3]=t.round(1e3*(A*e[l]+M*i[l]+T*a[l]+F*s[l]))/1e3;return p},getPointInSegment:function(e,s,i,a,r,n){var h=o(r,n),l=1-h;return[t.round(1e3*(l*l*l*e[0]+(h*l*l+l*h*l+l*l*h)*i[0]+(h*h*l+l*h*h+h*l*h)*a[0]+h*h*h*s[0]))/1e3,t.round(1e3*(l*l*l*e[1]+(h*l*l+l*h*l+l*l*h)*i[1]+(h*h*l+l*h*h+h*l*h)*a[1]+h*h*h*s[1]))/1e3]},buildBezierData:n,pointOnLine2D:e,pointOnLine3D:function(s,i,a,r,n,o,h,l,p){if(0===a&&0===o&&0===p)return e(s,i,r,n,h,l);var f,c=t.sqrt(t.pow(r-s,2)+t.pow(n-i,2)+t.pow(o-a,2)),d=t.sqrt(t.pow(h-s,2)+t.pow(l-i,2)+t.pow(p-a,2)),m=t.sqrt(t.pow(h-r,2)+t.pow(l-n,2)+t.pow(p-o,2));return(f=c>d?c>m?c-d-m:m-d-c:m>d?m-d-c:d-c-m)>-1e-4&&f<1e-4}}}(),nt=s,ot=Math.abs;function ht(t,e){var s,i=this.offsetTime;"multidimensional"===this.propType&&(s=h("float32",this.pv.length));for(var a,r,n,o,l,p,f,c,d,m=e.lastIndex,u=m,g=this.keyframes.length-1,y=!0;y;){if(a=this.keyframes[u],r=this.keyframes[u+1],u===g-1&&t>=r.t-i){a.h&&(a=r),m=0;break}if(r.t-i>t){m=u;break}u<g-1?u+=1:(m=0,y=!1)}n=this.keyframesMetadata[u]||{};var v,b,_,C,k,S,P,D,w,A,M=r.t-i,T=a.t-i;if(a.to){n.bezierData||(n.bezierData=rt.buildBezierData(a.s,r.s||a.e,a.to,a.ti));var F=n.bezierData;if(t>=M||t<T){var E=t>=M?F.points.length-1:0;for(l=F.points[E].point.length,o=0;o<l;o+=1)s[o]=F.points[E].point[o]}else{n.__fnct?d=n.__fnct:(d=tt.getBezierEasing(a.o.x,a.o.y,a.i.x,a.i.y,a.n).get,n.__fnct=d),p=d((t-T)/(M-T));var L,I=F.segmentLength*p,R=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastAddedLength:0;for(c=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastPoint:0,y=!0,f=F.points.length;y;){if(R+=F.points[c].partialLength,0===I||0===p||c===F.points.length-1){for(l=F.points[c].point.length,o=0;o<l;o+=1)s[o]=F.points[c].point[o];break}if(I>=R&&I<R+F.points[c+1].partialLength){for(L=(I-R)/F.points[c+1].partialLength,l=F.points[c].point.length,o=0;o<l;o+=1)s[o]=F.points[c].point[o]+(F.points[c+1].point[o]-F.points[c].point[o])*L;break}c<f-1?c+=1:y=!1}e._lastPoint=c,e._lastAddedLength=R-F.points[c].partialLength,e._lastKeyframeIndex=u}}else{var V,z,O,N,q;if(g=a.s.length,v=r.s||a.e,this.sh&&1!==a.h)if(t>=M)s[0]=v[0],s[1]=v[1],s[2]=v[2];else if(t<=T)s[0]=a.s[0],s[1]=a.s[1],s[2]=a.s[2];else{var B=lt(a.s),W=lt(v);b=s,_=function(t,e,s){var i,a,r,n,o,h=[],l=t[0],p=t[1],f=t[2],c=t[3],d=e[0],m=e[1],u=e[2],g=e[3];return(a=l*d+p*m+f*u+c*g)<0&&(a=-a,d=-d,m=-m,u=-u,g=-g),1-a>1e-6?(i=Math.acos(a),r=Math.sin(i),n=Math.sin((1-s)*i)/r,o=Math.sin(s*i)/r):(n=1-s,o=s),h[0]=n*l+o*d,h[1]=n*p+o*m,h[2]=n*f+o*u,h[3]=n*c+o*g,h}(B,W,(t-T)/(M-T)),C=_[0],k=_[1],S=_[2],P=_[3],D=Math.atan2(2*k*P-2*C*S,1-2*k*k-2*S*S),w=Math.asin(2*C*k+2*S*P),A=Math.atan2(2*C*P-2*k*S,1-2*C*C-2*S*S),b[0]=D/x,b[1]=w/x,b[2]=A/x}else for(u=0;u<g;u+=1)1!==a.h&&(t>=M?p=1:t<T?p=0:(a.o.x.constructor===Array?(n.__fnct||(n.__fnct=[]),n.__fnct[u]?d=n.__fnct[u]:(V=void 0===a.o.x[u]?a.o.x[0]:a.o.x[u],z=void 0===a.o.y[u]?a.o.y[0]:a.o.y[u],O=void 0===a.i.x[u]?a.i.x[0]:a.i.x[u],N=void 0===a.i.y[u]?a.i.y[0]:a.i.y[u],d=tt.getBezierEasing(V,z,O,N).get,n.__fnct[u]=d)):n.__fnct?d=n.__fnct:(V=a.o.x,z=a.o.y,O=a.i.x,N=a.i.y,d=tt.getBezierEasing(V,z,O,N).get,a.keyframeMetadata=d),p=d((t-T)/(M-T)))),v=r.s||a.e,q=1===a.h?a.s[u]:a.s[u]+(v[u]-a.s[u])*p,"multidimensional"===this.propType?s[u]=q:s=q}return e.lastIndex=m,s}function lt(t){var e=t[0]*x,s=t[1]*x,i=t[2]*x,a=Math.cos(e/2),r=Math.cos(s/2),n=Math.cos(i/2),o=Math.sin(e/2),h=Math.sin(s/2),l=Math.sin(i/2);return[o*h*n+a*r*l,o*r*n+a*h*l,a*h*n-o*r*l,a*r*n-o*h*l]}function pt(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,s=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==nt&&(this._caching.lastFrame>=s&&t>=s||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var i=this.interpolateValue(t,this._caching);this.pv=i}return this._caching.lastFrame=t,this.pv}function ft(t){var e;if("unidimensional"===this.propType)e=t*this.mult,ot(this.v-e)>1e-5&&(this.v=e,this._mdf=!0);else for(var s=0,i=this.v.length;s<i;)e=t[s]*this.mult,ot(this.v[s]-e)>1e-5&&(this.v[s]=e,this._mdf=!0),s+=1}function ct(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t;this.lock=!0,this._mdf=this._isFirstFrame;var e=this.effectsSequence.length,s=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)s=this.effectsSequence[t](s);this.setVValue(s),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function dt(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function mt(t,e,s,i){this.propType="unidimensional",this.mult=s||1,this.data=e,this.v=s?e.k*s:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=i,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=ct,this.setVValue=ft,this.addEffect=dt}function ut(t,e,s,i){var a;this.propType="multidimensional",this.mult=s||1,this.data=e,this._mdf=!1,this.elem=t,this.container=i,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var r=e.k.length;for(this.v=h("float32",r),this.pv=h("float32",r),this.vel=h("float32",r),a=0;a<r;a+=1)this.v[a]=e.k[a]*this.mult,this.pv[a]=e.k[a];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=ct,this.setVValue=ft,this.addEffect=dt}function gt(t,e,s,i){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:nt,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=s||1,this.elem=t,this.container=i,this.comp=t.comp,this.v=nt,this.pv=nt,this._isFirstFrame=!0,this.getValue=ct,this.setVValue=ft,this.interpolateValue=ht,this.effectsSequence=[pt.bind(this)],this.addEffect=dt}function yt(t,e,s,i){var a;this.propType="multidimensional";var r,n,o,l,p=e.k.length;for(a=0;a<p-1;a+=1)e.k[a].to&&e.k[a].s&&e.k[a+1]&&e.k[a+1].s&&(r=e.k[a].s,n=e.k[a+1].s,o=e.k[a].to,l=e.k[a].ti,(2===r.length&&(r[0]!==n[0]||r[1]!==n[1])&&rt.pointOnLine2D(r[0],r[1],n[0],n[1],r[0]+o[0],r[1]+o[1])&&rt.pointOnLine2D(r[0],r[1],n[0],n[1],n[0]+l[0],n[1]+l[1])||3===r.length&&(r[0]!==n[0]||r[1]!==n[1]||r[2]!==n[2])&&rt.pointOnLine3D(r[0],r[1],r[2],n[0],n[1],n[2],r[0]+o[0],r[1]+o[1],r[2]+o[2])&&rt.pointOnLine3D(r[0],r[1],r[2],n[0],n[1],n[2],n[0]+l[0],n[1]+l[1],n[2]+l[2]))&&(e.k[a].to=null,e.k[a].ti=null),r[0]===n[0]&&r[1]===n[1]&&0===o[0]&&0===o[1]&&0===l[0]&&0===l[1]&&(2===r.length||r[2]===n[2]&&0===o[2]&&0===l[2])&&(e.k[a].to=null,e.k[a].ti=null));this.effectsSequence=[pt.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=s||1,this.elem=t,this.container=i,this.comp=t.comp,this.getValue=ct,this.setVValue=ft,this.interpolateValue=ht,this.frameId=-1;var f=e.k[0].s.length;for(this.v=h("float32",f),this.pv=h("float32",f),a=0;a<f;a+=1)this.v[a]=nt,this.pv[a]=nt;this._caching={lastFrame:nt,lastIndex:0,value:h("float32",f)},this.addEffect=dt}var vt={getProp:function(t,e,s,i,a){var r;if(e.sid&&(e=t.globalData.slotManager.getProp(e)),e.k.length)if("number"==typeof e.k[0])r=new ut(t,e,i,a);else switch(s){case 0:r=new gt(t,e,i,a);break;case 1:r=new yt(t,e,i,a)}else r=new mt(t,e,i,a);return r.effectsSequence.length&&a.addDynamicProperty(r),r}};function bt(){}bt.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){var t;this._mdf=!1;var e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var _t=st(8,(function(){return h("float32",2)}));function Ct(){this.c=!1,this._length=0,this._maxLength=8,this.v=l(this._maxLength),this.o=l(this._maxLength),this.i=l(this._maxLength)}Ct.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var s=0;s<e;)this.v[s]=_t.newElement(),this.o[s]=_t.newElement(),this.i[s]=_t.newElement(),s+=1},Ct.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},Ct.prototype.doubleArrayLength=function(){this.v=this.v.concat(l(this._maxLength)),this.i=this.i.concat(l(this._maxLength)),this.o=this.o.concat(l(this._maxLength)),this._maxLength*=2},Ct.prototype.setXYAt=function(t,e,s,i,a){var r;switch(this._length=Math.max(this._length,i+1),this._length>=this._maxLength&&this.doubleArrayLength(),s){case"v":r=this.v;break;case"i":r=this.i;break;case"o":r=this.o;break;default:r=[]}(!r[i]||r[i]&&!a)&&(r[i]=_t.newElement()),r[i][0]=t,r[i][1]=e},Ct.prototype.setTripleAt=function(t,e,s,i,a,r,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(s,i,"o",n,o),this.setXYAt(a,r,"i",n,o)},Ct.prototype.reverse=function(){var t=new Ct;t.setPathData(this.c,this._length);var e=this.v,s=this.o,i=this.i,a=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],i[0][0],i[0][1],s[0][0],s[0][1],0,!1),a=1);var r,n=this._length-1,o=this._length;for(r=a;r<o;r+=1)t.setTripleAt(e[n][0],e[n][1],i[n][0],i[n][1],s[n][0],s[n][1],r,!1),n-=1;return t},Ct.prototype.length=function(){return this._length};var xt,kt=((xt=st(4,(function(){return new Ct}),(function(t){var e,s=t._length;for(e=0;e<s;e+=1)_t.release(t.v[e]),_t.release(t.i[e]),_t.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1}))).clone=function(t){var e,s=xt.newElement(),i=void 0===t._length?t.v.length:t._length;for(s.setLength(i),s.c=t.c,e=0;e<i;e+=1)s.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return s},xt);function St(){this._length=0,this._maxLength=4,this.shapes=l(this._maxLength)}St.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(l(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},St.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)kt.release(this.shapes[t]);this._length=0};var Pt,Dt,wt,At,Mt=(Pt={newShapeCollection:function(){return Dt?At[Dt-=1]:new St},release:function(t){var e,s=t._length;for(e=0;e<s;e+=1)kt.release(t.shapes[e]);t._length=0,Dt===wt&&(At=et.double(At),wt*=2),At[Dt]=t,Dt+=1}},Dt=0,At=l(wt=4),Pt),Tt=function(){var t=-999999;function e(t,e,s){var i,a,r,n,o,h,l,p,f,c=s.lastIndex,d=this.keyframes;if(t<d[0].t-this.offsetTime)i=d[0].s[0],r=!0,c=0;else if(t>=d[d.length-1].t-this.offsetTime)i=d[d.length-1].s?d[d.length-1].s[0]:d[d.length-2].e[0],r=!0;else{for(var m,u,g,y=c,v=d.length-1,b=!0;b&&(m=d[y],!((u=d[y+1]).t-this.offsetTime>t));)y<v-1?y+=1:b=!1;if(g=this.keyframesMetadata[y]||{},c=y,!(r=1===m.h)){if(t>=u.t-this.offsetTime)p=1;else if(t<m.t-this.offsetTime)p=0;else{var _;g.__fnct?_=g.__fnct:(_=tt.getBezierEasing(m.o.x,m.o.y,m.i.x,m.i.y).get,g.__fnct=_),p=_((t-(m.t-this.offsetTime))/(u.t-this.offsetTime-(m.t-this.offsetTime)))}a=u.s?u.s[0]:m.e[0]}i=m.s[0]}for(h=e._length,l=i.i[0].length,s.lastIndex=c,n=0;n<h;n+=1)for(o=0;o<l;o+=1)f=r?i.i[n][o]:i.i[n][o]+(a.i[n][o]-i.i[n][o])*p,e.i[n][o]=f,f=r?i.o[n][o]:i.o[n][o]+(a.o[n][o]-i.o[n][o])*p,e.o[n][o]=f,f=r?i.v[n][o]:i.v[n][o]+(a.v[n][o]-i.v[n][o])*p,e.v[n][o]=f}function s(){var e=this.comp.renderedFrame-this.offsetTime,s=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime,a=this._caching.lastFrame;return a!==t&&(a<s&&e<s||a>i&&e>i)||(this._caching.lastIndex=a<e?this._caching.lastIndex:0,this.interpolateShape(e,this.pv,this._caching)),this._caching.lastFrame=e,this.pv}function i(){this.paths=this.localShapeCollection}function a(t){(function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var s,i=t._length;for(s=0;s<i;s+=1)if(t.v[s][0]!==e.v[s][0]||t.v[s][1]!==e.v[s][1]||t.o[s][0]!==e.o[s][0]||t.o[s][1]!==e.o[s][1]||t.i[s][0]!==e.i[s][0]||t.i[s][1]!==e.i[s][1])return!1;return!0})(this.v,t)||(this.v=kt.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function n(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t,e;this.lock=!0,this._mdf=!1,t=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k;var s=this.effectsSequence.length;for(e=0;e<s;e+=1)t=this.effectsSequence[e](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function o(t,e,s){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var a=3===s?e.pt.k:e.ks.k;this.v=kt.clone(a),this.pv=kt.clone(this.v),this.localShapeCollection=Mt.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=i,this.effectsSequence=[]}function h(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function l(e,a,r){this.propType="shape",this.comp=e.comp,this.elem=e,this.container=e,this.offsetTime=e.data.st,this.keyframes=3===r?a.pt.k:a.ks.k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;var n=this.keyframes[0].s[0].i.length;this.v=kt.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,n),this.pv=kt.clone(this.v),this.localShapeCollection=Mt.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=t,this.reset=i,this._caching={lastFrame:t,lastIndex:0},this.effectsSequence=[s.bind(this)]}o.prototype.interpolateShape=e,o.prototype.getValue=n,o.prototype.setVValue=a,o.prototype.addEffect=h,l.prototype.getValue=n,l.prototype.interpolateShape=e,l.prototype.setVValue=a,l.prototype.addEffect=h;var p=function(){var t=k;function e(t,e){this.v=kt.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=Mt.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=vt.getProp(t,e.p,1,0,this),this.s=vt.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}return e.prototype={reset:i,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var e=this.p.v[0],s=this.p.v[1],i=this.s.v[0]/2,a=this.s.v[1]/2,r=3!==this.d,n=this.v;n.v[0][0]=e,n.v[0][1]=s-a,n.v[1][0]=r?e+i:e-i,n.v[1][1]=s,n.v[2][0]=e,n.v[2][1]=s+a,n.v[3][0]=r?e-i:e+i,n.v[3][1]=s,n.i[0][0]=r?e-i*t:e+i*t,n.i[0][1]=s-a,n.i[1][0]=r?e+i:e-i,n.i[1][1]=s-a*t,n.i[2][0]=r?e+i*t:e-i*t,n.i[2][1]=s+a,n.i[3][0]=r?e-i:e+i,n.i[3][1]=s+a*t,n.o[0][0]=r?e+i*t:e-i*t,n.o[0][1]=s-a,n.o[1][0]=r?e+i:e-i,n.o[1][1]=s+a*t,n.o[2][0]=r?e-i*t:e+i*t,n.o[2][1]=s+a,n.o[3][0]=r?e-i:e+i,n.o[3][1]=s-a*t}},r([bt],e),e}(),f=function(){function t(t,e){this.v=kt.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=vt.getProp(t,e.ir,0,0,this),this.is=vt.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=vt.getProp(t,e.pt,0,0,this),this.p=vt.getProp(t,e.p,1,0,this),this.r=vt.getProp(t,e.r,0,x,this),this.or=vt.getProp(t,e.or,0,0,this),this.os=vt.getProp(t,e.os,0,.01,this),this.localShapeCollection=Mt.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}return t.prototype={reset:i,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,s,i,a=2*Math.floor(this.pt.v),r=2*Math.PI/a,n=!0,o=this.or.v,h=this.ir.v,l=this.os.v,p=this.is.v,f=2*Math.PI*o/(2*a),c=2*Math.PI*h/(2*a),d=-Math.PI/2;d+=this.r.v;var m=3===this.data.d?-1:1;for(this.v._length=0,t=0;t<a;t+=1){s=n?l:p,i=n?f:c;var u=(e=n?o:h)*Math.cos(d),g=e*Math.sin(d),y=0===u&&0===g?0:g/Math.sqrt(u*u+g*g),v=0===u&&0===g?0:-u/Math.sqrt(u*u+g*g);u+=+this.p.v[0],g+=+this.p.v[1],this.v.setTripleAt(u,g,u-y*i*s*m,g-v*i*s*m,u+y*i*s*m,g+v*i*s*m,t,!0),n=!n,d+=r*m}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),s=2*Math.PI/e,i=this.or.v,a=this.os.v,r=2*Math.PI*i/(4*e),n=.5*-Math.PI,o=3===this.data.d?-1:1;for(n+=this.r.v,this.v._length=0,t=0;t<e;t+=1){var h=i*Math.cos(n),l=i*Math.sin(n),p=0===h&&0===l?0:l/Math.sqrt(h*h+l*l),f=0===h&&0===l?0:-h/Math.sqrt(h*h+l*l);h+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(h,l,h-p*r*a*o,l-f*r*a*o,h+p*r*a*o,l+f*r*a*o,t,!0),n+=s*o}this.paths.length=0,this.paths[0]=this.v}},r([bt],t),t}(),c=function(){function t(t,e){this.v=kt.newElement(),this.v.c=!0,this.localShapeCollection=Mt.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=vt.getProp(t,e.p,1,0,this),this.s=vt.getProp(t,e.s,1,0,this),this.r=vt.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}return t.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],s=this.s.v[0]/2,i=this.s.v[1]/2,a=b(s,i,this.r.v),r=a*(1-k);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+s,e-i+a,t+s,e-i+a,t+s,e-i+r,0,!0),this.v.setTripleAt(t+s,e+i-a,t+s,e+i-r,t+s,e+i-a,1,!0),0!==a?(this.v.setTripleAt(t+s-a,e+i,t+s-a,e+i,t+s-r,e+i,2,!0),this.v.setTripleAt(t-s+a,e+i,t-s+r,e+i,t-s+a,e+i,3,!0),this.v.setTripleAt(t-s,e+i-a,t-s,e+i-a,t-s,e+i-r,4,!0),this.v.setTripleAt(t-s,e-i+a,t-s,e-i+r,t-s,e-i+a,5,!0),this.v.setTripleAt(t-s+a,e-i,t-s+a,e-i,t-s+r,e-i,6,!0),this.v.setTripleAt(t+s-a,e-i,t+s-r,e-i,t+s-a,e-i,7,!0)):(this.v.setTripleAt(t-s,e+i,t-s+r,e+i,t-s,e+i,2),this.v.setTripleAt(t-s,e-i,t-s,e-i+r,t-s,e-i,3))):(this.v.setTripleAt(t+s,e-i+a,t+s,e-i+r,t+s,e-i+a,0,!0),0!==a?(this.v.setTripleAt(t+s-a,e-i,t+s-a,e-i,t+s-r,e-i,1,!0),this.v.setTripleAt(t-s+a,e-i,t-s+r,e-i,t-s+a,e-i,2,!0),this.v.setTripleAt(t-s,e-i+a,t-s,e-i+a,t-s,e-i+r,3,!0),this.v.setTripleAt(t-s,e+i-a,t-s,e+i-r,t-s,e+i-a,4,!0),this.v.setTripleAt(t-s+a,e+i,t-s+a,e+i,t-s+r,e+i,5,!0),this.v.setTripleAt(t+s-a,e+i,t+s-r,e+i,t+s-a,e+i,6,!0),this.v.setTripleAt(t+s,e+i-a,t+s,e+i-a,t+s,e+i-r,7,!0)):(this.v.setTripleAt(t-s,e-i,t-s+r,e-i,t-s,e-i,1,!0),this.v.setTripleAt(t-s,e+i,t-s,e+i-r,t-s,e+i,2,!0),this.v.setTripleAt(t+s,e+i,t+s-r,e+i,t+s,e+i,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:i},r([bt],t),t}();var d={getShapeProp:function(t,e,s){var i;return 3===s||4===s?i=(3===s?e.pt:e.ks).k.length?new l(t,e,s):new o(t,e,s):5===s?i=new c(t,e):6===s?i=new p(t,e):7===s&&(i=new f(t,e)),i.k&&t.addDynamicProperty(i),i},getConstructorFunction:function(){return o},getKeyframedConstructorFunction:function(){return l}};return d}(),Ft=function(){var t=Math.cos,e=Math.sin,s=Math.tan,i=Math.round;function a(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function r(s){if(0===s)return this;var i=t(s),a=e(s);return this._t(i,-a,0,0,a,i,0,0,0,0,1,0,0,0,0,1)}function n(s){if(0===s)return this;var i=t(s),a=e(s);return this._t(1,0,0,0,0,i,-a,0,0,a,i,0,0,0,0,1)}function o(s){if(0===s)return this;var i=t(s),a=e(s);return this._t(i,0,a,0,0,1,0,0,-a,0,i,0,0,0,0,1)}function l(s){if(0===s)return this;var i=t(s),a=e(s);return this._t(i,-a,0,0,a,i,0,0,0,0,1,0,0,0,0,1)}function p(t,e){return this._t(1,e,t,1,0,0)}function f(t,e){return this.shear(s(t),s(e))}function c(i,a){var r=t(a),n=e(a);return this._t(r,n,0,0,-n,r,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,s(i),1,0,0,0,0,1,0,0,0,0,1)._t(r,-n,0,0,n,r,0,0,0,0,1,0,0,0,0,1)}function d(t,e,s){return s||0===s||(s=1),1===t&&1===e&&1===s?this:this._t(t,0,0,0,0,e,0,0,0,0,s,0,0,0,0,1)}function m(t,e,s,i,a,r,n,o,h,l,p,f,c,d,m,u){return this.props[0]=t,this.props[1]=e,this.props[2]=s,this.props[3]=i,this.props[4]=a,this.props[5]=r,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=l,this.props[10]=p,this.props[11]=f,this.props[12]=c,this.props[13]=d,this.props[14]=m,this.props[15]=u,this}function u(t,e,s){return s=s||0,0!==t||0!==e||0!==s?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,s,1):this}function g(t,e,s,i,a,r,n,o,h,l,p,f,c,d,m,u){var g=this.props;if(1===t&&0===e&&0===s&&0===i&&0===a&&1===r&&0===n&&0===o&&0===h&&0===l&&1===p&&0===f)return g[12]=g[12]*t+g[15]*c,g[13]=g[13]*r+g[15]*d,g[14]=g[14]*p+g[15]*m,g[15]*=u,this._identityCalculated=!1,this;var y=g[0],v=g[1],b=g[2],_=g[3],C=g[4],x=g[5],k=g[6],S=g[7],P=g[8],D=g[9],w=g[10],A=g[11],M=g[12],T=g[13],F=g[14],E=g[15];return g[0]=y*t+v*a+b*h+_*c,g[1]=y*e+v*r+b*l+_*d,g[2]=y*s+v*n+b*p+_*m,g[3]=y*i+v*o+b*f+_*u,g[4]=C*t+x*a+k*h+S*c,g[5]=C*e+x*r+k*l+S*d,g[6]=C*s+x*n+k*p+S*m,g[7]=C*i+x*o+k*f+S*u,g[8]=P*t+D*a+w*h+A*c,g[9]=P*e+D*r+w*l+A*d,g[10]=P*s+D*n+w*p+A*m,g[11]=P*i+D*o+w*f+A*u,g[12]=M*t+T*a+F*h+E*c,g[13]=M*e+T*r+F*l+E*d,g[14]=M*s+T*n+F*p+E*m,g[15]=M*i+T*o+F*f+E*u,this._identityCalculated=!1,this}function y(t){var e=t.props;return this.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}function v(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function b(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function _(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function C(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function x(t,e,s){return{x:t*this.props[0]+e*this.props[4]+s*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+s*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+s*this.props[10]+this.props[14]}}function k(t,e,s){return t*this.props[0]+e*this.props[4]+s*this.props[8]+this.props[12]}function S(t,e,s){return t*this.props[1]+e*this.props[5]+s*this.props[9]+this.props[13]}function P(t,e,s){return t*this.props[2]+e*this.props[6]+s*this.props[10]+this.props[14]}function D(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,s=-this.props[1]/t,i=-this.props[4]/t,a=this.props[0]/t,r=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,n=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,o=new Ft;return o.props[0]=e,o.props[1]=s,o.props[4]=i,o.props[5]=a,o.props[12]=r,o.props[13]=n,o}function w(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function A(t){var e,s=t.length,i=[];for(e=0;e<s;e+=1)i[e]=w(t[e]);return i}function M(t,e,s){var i=h("float32",6);if(this.isIdentity())i[0]=t[0],i[1]=t[1],i[2]=e[0],i[3]=e[1],i[4]=s[0],i[5]=s[1];else{var a=this.props[0],r=this.props[1],n=this.props[4],o=this.props[5],l=this.props[12],p=this.props[13];i[0]=t[0]*a+t[1]*n+l,i[1]=t[0]*r+t[1]*o+p,i[2]=e[0]*a+e[1]*n+l,i[3]=e[0]*r+e[1]*o+p,i[4]=s[0]*a+s[1]*n+l,i[5]=s[0]*r+s[1]*o+p}return i}function T(t,e,s){return this.isIdentity()?[t,e,s]:[t*this.props[0]+e*this.props[4]+s*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+s*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+s*this.props[10]+this.props[14]]}function F(t,e){if(this.isIdentity())return t+","+e;var s=this.props;return Math.round(100*(t*s[0]+e*s[4]+s[12]))/100+","+Math.round(100*(t*s[1]+e*s[5]+s[13]))/100}function E(){for(var t=0,e=this.props,s="matrix3d(";t<16;)s+=i(1e4*e[t])/1e4,s+=15===t?")":",",t+=1;return s}function L(t){return t<1e-6&&t>0||t>-1e-6&&t<0?i(1e4*t)/1e4:t}function I(){var t=this.props;return"matrix("+L(t[0])+","+L(t[1])+","+L(t[4])+","+L(t[5])+","+L(t[12])+","+L(t[13])+")"}return function(){this.reset=a,this.rotate=r,this.rotateX=n,this.rotateY=o,this.rotateZ=l,this.skew=f,this.skewFromAxis=c,this.shear=p,this.scale=d,this.setTransform=m,this.translate=u,this.transform=g,this.multiply=y,this.applyToPoint=x,this.applyToX=k,this.applyToY=S,this.applyToZ=P,this.applyToPointArray=T,this.applyToTriplePoints=M,this.applyToPointStringified=F,this.toCSS=E,this.to2dCSS=I,this.clone=_,this.cloneFromProps=C,this.equals=b,this.inversePoints=A,this.inversePoint=w,this.getInverseMatrix=D,this._t=this.transform,this.isIdentity=v,this._identity=!0,this._identityCalculated=!1,this.props=h("float32",16),this.reset()}}();function Et(t){return Et="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Et(t)}var Lt={};function It(){$.searchAnimations()}Lt.play=$.play,Lt.pause=$.pause,Lt.setLocationHref=function(e){t=e},Lt.togglePause=$.togglePause,Lt.setSpeed=$.setSpeed,Lt.setDirection=$.setDirection,Lt.stop=$.stop,Lt.searchAnimations=It,Lt.registerAnimation=$.registerAnimation,Lt.loadAnimation=function(t){return $.loadAnimation(t)},Lt.setSubframeRendering=function(t){!function(t){f=!!t}(t)},Lt.resize=$.resize,Lt.goToAndStop=$.goToAndStop,Lt.destroy=$.destroy,Lt.setQuality=function(t){if("string"==typeof t)switch(t){case"high":B(200);break;default:case"medium":B(50);break;case"low":B(10)}else!isNaN(t)&&t>1&&B(t);W()>=50?S(!1):S(!0)},Lt.inBrowser=function(){return"undefined"!=typeof navigator},Lt.installPlugin=function(t,e){"expressions"===t&&(c=e)},Lt.freeze=$.freeze,Lt.unfreeze=$.unfreeze,Lt.setVolume=$.setVolume,Lt.mute=$.mute,Lt.unmute=$.unmute,Lt.getRegisteredAnimations=$.getRegisteredAnimations,Lt.useWebWorker=function(t){e=!!t},Lt.setIDPrefix=function(t){m=t},Lt.__getFactory=function(t){switch(t){case"propertyFactory":return vt;case"shapePropertyFactory":return Tt;case"matrix":return Ft;default:return null}},Lt.version="5.12.2";var Rt="",Vt=document.getElementsByTagName("script"),zt=Vt[Vt.length-1]||{src:""};Rt=zt.src?zt.src.replace(/^[^\?]+\??/,""):"",function(t){for(var e=Rt.split("&"),s=0;s<e.length;s+=1){var i=e[s].split("=");if(decodeURIComponent(i[0])==t)return decodeURIComponent(i[1])}}("renderer");var Ot=setInterval((function(){"complete"===document.readyState&&(clearInterval(Ot),It())}),100);try{"object"===("undefined"==typeof exports?"undefined":Et(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=Lt)}catch(t){}var Nt=function(){var t={},e={};return t.registerModifier=function(t,s){e[t]||(e[t]=s)},t.getModifier=function(t,s,i){return new e[t](s,i)},t}();function qt(){}function Bt(){}function Wt(){}qt.prototype.initModifierProperties=function(){},qt.prototype.addShapeToModifier=function(){},qt.prototype.addShape=function(t){if(!this.closed){t.sh.container.addDynamicProperty(t.sh);var e={shape:t.sh,data:t,localShapeCollection:Mt.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},qt.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=s,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},qt.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},r([bt],qt),r([qt],Bt),Bt.prototype.initModifierProperties=function(t,e){this.s=vt.getProp(t,e.s,0,.01,this),this.e=vt.getProp(t,e.e,0,.01,this),this.o=vt.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},Bt.prototype.addShapeToModifier=function(t){t.pathsData=[]},Bt.prototype.calculateShapeEdges=function(t,e,s,i,a){var r=[];e<=1?r.push({s:t,e:e}):t>=1?r.push({s:t-1,e:e-1}):(r.push({s:t,e:1}),r.push({s:0,e:e-1}));var n,o,h=[],l=r.length;for(n=0;n<l;n+=1){var p,f;if(!((o=r[n]).e*a<i||o.s*a>i+s))p=o.s*a<=i?0:(o.s*a-i)/s,f=o.e*a>=i+s?1:(o.e*a-i)/s,h.push([p,f])}return h.length||h.push([0,0]),h},Bt.prototype.releasePathsData=function(t){var e,s=t.length;for(e=0;e<s;e+=1)at.release(t[e]);return t.length=0,t},Bt.prototype.processShapes=function(t){var e,s,i,a;if(this._mdf||t){var r=this.o.v%360/360;if(r<0&&(r+=1),(e=this.s.v>1?1+r:this.s.v<0?0+r:this.s.v+r)>(s=this.e.v>1?1+r:this.e.v<0?0+r:this.e.v+r)){var n=e;e=s,s=n}e=1e-4*Math.round(1e4*e),s=1e-4*Math.round(1e4*s),this.sValue=e,this.eValue=s}else e=this.sValue,s=this.eValue;var o,h,l,p,f,c=this.shapes.length,d=0;if(s===e)for(a=0;a<c;a+=1)this.shapes[a].localShapeCollection.releaseShapes(),this.shapes[a].shape._mdf=!0,this.shapes[a].shape.paths=this.shapes[a].localShapeCollection,this._mdf&&(this.shapes[a].pathsData.length=0);else if(1===s&&0===e||0===s&&1===e){if(this._mdf)for(a=0;a<c;a+=1)this.shapes[a].pathsData.length=0,this.shapes[a].shape._mdf=!0}else{var m,u,g=[];for(a=0;a<c;a+=1)if((m=this.shapes[a]).shape._mdf||this._mdf||t||2===this.m){if(h=(i=m.shape.paths)._length,f=0,!m.shape._mdf&&m.pathsData.length)f=m.totalShapeLength;else{for(l=this.releasePathsData(m.pathsData),o=0;o<h;o+=1)p=rt.getSegmentsLength(i.shapes[o]),l.push(p),f+=p.totalLength;m.totalShapeLength=f,m.pathsData=l}d+=f,m.shape._mdf=!0}else m.shape.paths=m.localShapeCollection;var y,v=e,b=s,_=0;for(a=c-1;a>=0;a-=1)if((m=this.shapes[a]).shape._mdf){for((u=m.localShapeCollection).releaseShapes(),2===this.m&&c>1?(y=this.calculateShapeEdges(e,s,m.totalShapeLength,_,d),_+=m.totalShapeLength):y=[[v,b]],h=y.length,o=0;o<h;o+=1){v=y[o][0],b=y[o][1],g.length=0,b<=1?g.push({s:m.totalShapeLength*v,e:m.totalShapeLength*b}):v>=1?g.push({s:m.totalShapeLength*(v-1),e:m.totalShapeLength*(b-1)}):(g.push({s:m.totalShapeLength*v,e:m.totalShapeLength}),g.push({s:0,e:m.totalShapeLength*(b-1)}));var C=this.addShapes(m,g[0]);if(g[0].s!==g[0].e){if(g.length>1)if(m.shape.paths.shapes[m.shape.paths._length-1].c){var x=C.pop();this.addPaths(C,u),C=this.addShapes(m,g[1],x)}else this.addPaths(C,u),C=this.addShapes(m,g[1]);this.addPaths(C,u)}}m.shape.paths=u}}},Bt.prototype.addPaths=function(t,e){var s,i=t.length;for(s=0;s<i;s+=1)e.addShape(t[s])},Bt.prototype.addSegment=function(t,e,s,i,a,r,n){a.setXYAt(e[0],e[1],"o",r),a.setXYAt(s[0],s[1],"i",r+1),n&&a.setXYAt(t[0],t[1],"v",r),a.setXYAt(i[0],i[1],"v",r+1)},Bt.prototype.addSegmentFromArray=function(t,e,s,i){e.setXYAt(t[1],t[5],"o",s),e.setXYAt(t[2],t[6],"i",s+1),i&&e.setXYAt(t[0],t[4],"v",s),e.setXYAt(t[3],t[7],"v",s+1)},Bt.prototype.addShapes=function(t,e,s){var i,a,r,n,o,h,l,p,f=t.pathsData,c=t.shape.paths.shapes,d=t.shape.paths._length,m=0,u=[],g=!0;for(s?(o=s._length,p=s._length):(s=kt.newElement(),o=0,p=0),u.push(s),i=0;i<d;i+=1){for(h=f[i].lengths,s.c=c[i].c,r=c[i].c?h.length:h.length+1,a=1;a<r;a+=1)if(m+(n=h[a-1]).addedLength<e.s)m+=n.addedLength,s.c=!1;else{if(m>e.e){s.c=!1;break}e.s<=m&&e.e>=m+n.addedLength?(this.addSegment(c[i].v[a-1],c[i].o[a-1],c[i].i[a],c[i].v[a],s,o,g),g=!1):(l=rt.getNewSegment(c[i].v[a-1],c[i].v[a],c[i].o[a-1],c[i].i[a],(e.s-m)/n.addedLength,(e.e-m)/n.addedLength,h[a-1]),this.addSegmentFromArray(l,s,o,g),g=!1,s.c=!1),m+=n.addedLength,o+=1}if(c[i].c&&h.length){if(n=h[a-1],m<=e.e){var y=h[a-1].addedLength;e.s<=m&&e.e>=m+y?(this.addSegment(c[i].v[a-1],c[i].o[a-1],c[i].i[0],c[i].v[0],s,o,g),g=!1):(l=rt.getNewSegment(c[i].v[a-1],c[i].v[0],c[i].o[a-1],c[i].i[0],(e.s-m)/y,(e.e-m)/y,h[a-1]),this.addSegmentFromArray(l,s,o,g),g=!1,s.c=!1)}else s.c=!1;m+=n.addedLength,o+=1}if(s._length&&(s.setXYAt(s.v[p][0],s.v[p][1],"i",p),s.setXYAt(s.v[s._length-1][0],s.v[s._length-1][1],"o",s._length-1)),m>e.e)break;i<d-1&&(s=kt.newElement(),g=!0,u.push(s),o=0)}return u},r([qt],Wt),Wt.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=vt.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},Wt.prototype.processPath=function(t,e){var s=e/100,i=[0,0],a=t._length,r=0;for(r=0;r<a;r+=1)i[0]+=t.v[r][0],i[1]+=t.v[r][1];i[0]/=a,i[1]/=a;var n,o,h,l,p,f,c=kt.newElement();for(c.c=t.c,r=0;r<a;r+=1)n=t.v[r][0]+(i[0]-t.v[r][0])*s,o=t.v[r][1]+(i[1]-t.v[r][1])*s,h=t.o[r][0]+(i[0]-t.o[r][0])*-s,l=t.o[r][1]+(i[1]-t.o[r][1])*-s,p=t.i[r][0]+(i[0]-t.i[r][0])*-s,f=t.i[r][1]+(i[1]-t.i[r][1])*-s,c.setTripleAt(n,o,h,l,p,f,r);return c},Wt.prototype.processShapes=function(t){var e,s,i,a,r,n,o=this.shapes.length,h=this.amount.v;if(0!==h)for(s=0;s<o;s+=1){if(n=(r=this.shapes[s]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,i=0;i<a;i+=1)n.addShape(this.processPath(e[i],h));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var jt=function(){var t=[0,0];function e(t,e,s){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Ft,this.pre=new Ft,this.appliedTransformations=0,this.initDynamicPropertyContainer(s||t),e.p&&e.p.s?(this.px=vt.getProp(t,e.p.x,0,0,this),this.py=vt.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=vt.getProp(t,e.p.z,0,0,this))):this.p=vt.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=vt.getProp(t,e.rx,0,x,this),this.ry=vt.getProp(t,e.ry,0,x,this),this.rz=vt.getProp(t,e.rz,0,x,this),e.or.k[0].ti){var i,a=e.or.k.length;for(i=0;i<a;i+=1)e.or.k[i].to=null,e.or.k[i].ti=null}this.or=vt.getProp(t,e.or,1,x,this),this.or.sh=!0}else this.r=vt.getProp(t,e.r||{k:0},0,x,this);e.sk&&(this.sk=vt.getProp(t,e.sk,0,x,this),this.sa=vt.getProp(t,e.sa,0,x,this)),this.a=vt.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=vt.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=vt.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return e.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(e){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||e){var s;if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var i,a;if(s=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime)this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(i=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/s,0),a=this.p.getValueAtTime(this.p.keyframes[0].t/s,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(i=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/s,0),a=this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/s,0)):(i=this.p.pv,a=this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/s,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){i=[],a=[];var r=this.px,n=this.py;r._caching.lastFrame+r.offsetTime<=r.keyframes[0].t?(i[0]=r.getValueAtTime((r.keyframes[0].t+.01)/s,0),i[1]=n.getValueAtTime((n.keyframes[0].t+.01)/s,0),a[0]=r.getValueAtTime(r.keyframes[0].t/s,0),a[1]=n.getValueAtTime(n.keyframes[0].t/s,0)):r._caching.lastFrame+r.offsetTime>=r.keyframes[r.keyframes.length-1].t?(i[0]=r.getValueAtTime(r.keyframes[r.keyframes.length-1].t/s,0),i[1]=n.getValueAtTime(n.keyframes[n.keyframes.length-1].t/s,0),a[0]=r.getValueAtTime((r.keyframes[r.keyframes.length-1].t-.01)/s,0),a[1]=n.getValueAtTime((n.keyframes[n.keyframes.length-1].t-.01)/s,0)):(i=[r.pv,n.pv],a[0]=r.getValueAtTime((r._caching.lastFrame+r.offsetTime-.01)/s,r.offsetTime),a[1]=n.getValueAtTime((n._caching.lastFrame+n.offsetTime-.01)/s,n.offsetTime))}else i=a=t;this.v.rotate(-Math.atan2(i[1]-a[1],i[0]-a[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},r([bt],e),e.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},e.prototype._addDynamicProperty=bt.prototype.addDynamicProperty,{getTransformProperty:function(t,s,i){return new e(t,s,i)}}}();function Yt(){}function Jt(){}function Ht(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function Gt(t){return Math.abs(t)<=1e-5}function Xt(t,e,s){return t*(1-s)+e*s}function Kt(t,e,s){return[Xt(t[0],e[0],s),Xt(t[1],e[1],s)]}function Ut(t,e,s,i){return[3*e-t-3*s+i,3*t-6*e+3*s,-3*t+3*e,t]}function Zt(t){return new Qt(t,t,t,t,!1)}function Qt(t,e,s,i,a){a&&oe(t,e)&&(e=Kt(t,i,1/3)),a&&oe(s,i)&&(s=Kt(t,i,2/3));var r=Ut(t[0],e[0],s[0],i[0]),n=Ut(t[1],e[1],s[1],i[1]);this.a=[r[0],n[0]],this.b=[r[1],n[1]],this.c=[r[2],n[2]],this.d=[r[3],n[3]],this.points=[t,e,s,i]}function $t(t,e){var s=t.points[0][e],i=t.points[t.points.length-1][e];if(s>i){var a=i;i=s,s=a}for(var r=function(t,e,s){if(0===t)return[];var i=e*e-4*t*s;if(i<0)return[];var a=-e/(2*t);if(0===i)return[a];var r=Math.sqrt(i)/(2*t);return[a-r,a+r]}(3*t.a[e],2*t.b[e],t.c[e]),n=0;n<r.length;n+=1)if(r[n]>0&&r[n]<1){var o=t.point(r[n])[e];o<s?s=o:o>i&&(i=o)}return{min:s,max:i}}function te(t,e,s){var i=t.boundingBox();return{cx:i.cx,cy:i.cy,width:i.width,height:i.height,bez:t,t:(e+s)/2,t1:e,t2:s}}function ee(t){var e=t.bez.split(.5);return[te(e[0],t.t1,t.t),te(e[1],t.t,t.t2)]}function se(t,e,s,i,a,r){var n,o;if(n=t,o=e,2*Math.abs(n.cx-o.cx)<n.width+o.width&&2*Math.abs(n.cy-o.cy)<n.height+o.height)if(s>=r||t.width<=i&&t.height<=i&&e.width<=i&&e.height<=i)a.push([t.t,e.t]);else{var h=ee(t),l=ee(e);se(h[0],l[0],s+1,i,a,r),se(h[0],l[1],s+1,i,a,r),se(h[1],l[0],s+1,i,a,r),se(h[1],l[1],s+1,i,a,r)}}function ie(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function ae(t,e,s,i){var a=[t[0],t[1],1],r=[e[0],e[1],1],n=[s[0],s[1],1],o=[i[0],i[1],1],h=ie(ie(a,r),ie(n,o));return Gt(h[2])?null:[h[0]/h[2],h[1]/h[2]]}function re(t,e,s){return[t[0]+Math.cos(e)*s,t[1]-Math.sin(e)*s]}function ne(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function oe(t,e){return Ht(t[0],e[0])&&Ht(t[1],e[1])}function he(){}function le(t,e,s,i,a,r,n){var o=s-Math.PI/2,h=s+Math.PI/2,l=e[0]+Math.cos(s)*i*a,p=e[1]-Math.sin(s)*i*a;t.setTripleAt(l,p,l+Math.cos(o)*r,p-Math.sin(o)*r,l+Math.cos(h)*n,p-Math.sin(h)*n,t.length())}function pe(t,e){var s,i,a,r,n=0===e?t.length()-1:e-1,o=(e+1)%t.length(),h=t.v[n],l=t.v[o],p=(s=h,a=[(i=l)[0]-s[0],i[1]-s[1]],r=.5*-Math.PI,[Math.cos(r)*a[0]-Math.sin(r)*a[1],Math.sin(r)*a[0]+Math.cos(r)*a[1]]);return Math.atan2(0,1)-Math.atan2(p[1],p[0])}function fe(t,e,s,i,a,r,n){var o=pe(e,s),h=e.v[s%e._length],l=e.v[0===s?e._length-1:s-1],p=e.v[(s+1)%e._length],f=2===r?Math.sqrt(Math.pow(h[0]-l[0],2)+Math.pow(h[1]-l[1],2)):0,c=2===r?Math.sqrt(Math.pow(h[0]-p[0],2)+Math.pow(h[1]-p[1],2)):0;le(t,e.v[s%e._length],o,n,i,c/(2*(a+1)),f/(2*(a+1)))}function ce(t,e,s,i,a,r){for(var n=0;n<i;n+=1){var o=(n+1)/(i+1),h=2===a?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(o);le(t,e.point(o),l,r,s,h/(2*(i+1)),h/(2*(i+1))),r=-r}return r}function de(t,e,s){var i=Math.atan2(e[0]-t[0],e[1]-t[1]);return[re(t,i,s),re(e,i,s)]}function me(t,e){var s,i,a,r,n,o,h;s=(h=de(t.points[0],t.points[1],e))[0],i=h[1],a=(h=de(t.points[1],t.points[2],e))[0],r=h[1],n=(h=de(t.points[2],t.points[3],e))[0],o=h[1];var l=ae(s,i,a,r);null===l&&(l=i);var p=ae(n,o,a,r);return null===p&&(p=n),new Qt(s,l,p,o)}function ue(t,e,s,i,a){var r=e.points[3],n=s.points[0];if(3===i)return r;if(oe(r,n))return r;if(2===i){var o=-e.tangentAngle(1),h=-s.tangentAngle(0)+Math.PI,l=ae(r,re(r,o+Math.PI/2,100),n,re(n,o+Math.PI/2,100)),p=l?ne(l,r):ne(r,n)/2,f=re(r,o,2*p*k);return t.setXYAt(f[0],f[1],"o",t.length()-1),f=re(n,h,2*p*k),t.setTripleAt(n[0],n[1],n[0],n[1],f[0],f[1],t.length()),n}var c=ae(oe(r,e.points[2])?e.points[0]:e.points[2],r,n,oe(n,s.points[1])?s.points[3]:s.points[1]);return c&&ne(c,r)<a?(t.setTripleAt(c[0],c[1],c[0],c[1],c[0],c[1],t.length()),c):r}function ge(t,e){var s=t.intersections(e);return s.length&&Ht(s[0][0],1)&&s.shift(),s.length?s[0]:null}function ye(t,e){var s=t.slice(),i=e.slice(),a=ge(t[t.length-1],e[0]);return a&&(s[t.length-1]=t[t.length-1].split(a[0])[0],i[0]=e[0].split(a[1])[1]),t.length>1&&e.length>1&&(a=ge(t[0],e[e.length-1]))?[[t[0].split(a[0])[0]],[e[e.length-1].split(a[1])[1]]]:[s,i]}function ve(t,e){var s,i,a,r,n=t.inflectionPoints();if(0===n.length)return[me(t,e)];if(1===n.length||Ht(n[1],1))return s=(a=t.split(n[0]))[0],i=a[1],[me(s,e),me(i,e)];s=(a=t.split(n[0]))[0];var o=(n[1]-n[0])/(1-n[0]);return r=(a=a[1].split(o))[0],i=a[1],[me(s,e),me(r,e),me(i,e)]}function be(){}function _e(t){for(var e=t.fStyle?t.fStyle.split(" "):[],s="normal",i="normal",a=e.length,r=0;r<a;r+=1)switch(e[r].toLowerCase()){case"italic":i="italic";break;case"bold":s="700";break;case"black":s="900";break;case"medium":s="500";break;case"regular":case"normal":s="400";break;case"light":case"thin":s="200"}return{style:i,weight:t.fWeight||s}}r([qt],Yt),Yt.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=vt.getProp(t,e.c,0,null,this),this.o=vt.getProp(t,e.o,0,null,this),this.tr=jt.getTransformProperty(t,e.tr,this),this.so=vt.getProp(t,e.tr.so,0,.01,this),this.eo=vt.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Ft,this.rMatrix=new Ft,this.sMatrix=new Ft,this.tMatrix=new Ft,this.matrix=new Ft},Yt.prototype.applyTransforms=function(t,e,s,i,a,r){var n=r?-1:1,o=i.s.v[0]+(1-i.s.v[0])*(1-a),h=i.s.v[1]+(1-i.s.v[1])*(1-a);t.translate(i.p.v[0]*n*a,i.p.v[1]*n*a,i.p.v[2]),e.translate(-i.a.v[0],-i.a.v[1],i.a.v[2]),e.rotate(-i.r.v*n*a),e.translate(i.a.v[0],i.a.v[1],i.a.v[2]),s.translate(-i.a.v[0],-i.a.v[1],i.a.v[2]),s.scale(r?1/o:o,r?1/h:h),s.translate(i.a.v[0],i.a.v[1],i.a.v[2])},Yt.prototype.init=function(t,e,s,i){for(this.elem=t,this.arr=e,this.pos=s,this.elemsData=i,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[s]);s>0;)s-=1,this._elements.unshift(e[s]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},Yt.prototype.resetElements=function(t){var e,s=t.length;for(e=0;e<s;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},Yt.prototype.cloneElements=function(t){var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},Yt.prototype.changeGroupRender=function(t,e){var s,i=t.length;for(s=0;s<i;s+=1)t[s]._render=e,"gr"===t[s].ty&&this.changeGroupRender(t[s].it,e)},Yt.prototype.processShapes=function(t){var e,s,i,a,r,n=!1;if(this._mdf||t){var o,h=Math.ceil(this.c.v);if(this._groups.length<h){for(;this._groups.length<h;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(r=0,i=0;i<=this._groups.length-1;i+=1){if(o=r<h,this._groups[i]._render=o,this.changeGroupRender(this._groups[i].it,o),!o){var p=this.elemsData[i].it,f=p[p.length-1];0!==f.transform.op.v?(f.transform.op._mdf=!0,f.transform.op.v=0):f.transform.op._mdf=!1}r+=1}this._currentCopies=h;var c=this.o.v,d=c%1,m=c>0?Math.floor(c):Math.ceil(c),u=this.pMatrix.props,g=this.rMatrix.props,y=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var v,b,_=0;if(c>0){for(;_<m;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),_+=1;d&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,d,!1),_+=d)}else if(c<0){for(;_>m;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),_-=1;d&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-d,!0),_-=d)}for(i=1===this.data.m?0:this._currentCopies-1,a=1===this.data.m?1:-1,r=this._currentCopies;r;){if(b=(s=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(i/(this._currentCopies-1)),0!==_){for((0!==i&&1===a||i!==this._currentCopies-1&&-1===a)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]),v=0;v<b;v+=1)s[v]=this.matrix.props[v];this.matrix.reset()}else for(this.matrix.reset(),v=0;v<b;v+=1)s[v]=this.matrix.props[v];_+=1,r-=1,i+=a}}else for(r=this._currentCopies,i=0,a=1;r;)s=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,r-=1,i+=a;return n},Yt.prototype.addShape=function(){},r([qt],Jt),Jt.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=vt.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},Jt.prototype.processPath=function(t,e){var s,i=kt.newElement();i.c=t.c;var a,r,n,o,h,l,p,f,c,d,m,u,g=t._length,y=0;for(s=0;s<g;s+=1)a=t.v[s],n=t.o[s],r=t.i[s],a[0]===n[0]&&a[1]===n[1]&&a[0]===r[0]&&a[1]===r[1]?0!==s&&s!==g-1||t.c?(o=0===s?t.v[g-1]:t.v[s-1],l=(h=Math.sqrt(Math.pow(a[0]-o[0],2)+Math.pow(a[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=m=a[0]+(o[0]-a[0])*l,f=u=a[1]-(a[1]-o[1])*l,c=p-(p-a[0])*k,d=f-(f-a[1])*k,i.setTripleAt(p,f,c,d,m,u,y),y+=1,o=s===g-1?t.v[0]:t.v[s+1],l=(h=Math.sqrt(Math.pow(a[0]-o[0],2)+Math.pow(a[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=c=a[0]+(o[0]-a[0])*l,f=d=a[1]+(o[1]-a[1])*l,m=p-(p-a[0])*k,u=f-(f-a[1])*k,i.setTripleAt(p,f,c,d,m,u,y),y+=1):(i.setTripleAt(a[0],a[1],n[0],n[1],r[0],r[1],y),y+=1):(i.setTripleAt(t.v[s][0],t.v[s][1],t.o[s][0],t.o[s][1],t.i[s][0],t.i[s][1],y),y+=1);return i},Jt.prototype.processShapes=function(t){var e,s,i,a,r,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(s=0;s<o;s+=1){if(n=(r=this.shapes[s]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,i=0;i<a;i+=1)n.addShape(this.processPath(e[i],h));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},Qt.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},Qt.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},Qt.prototype.tangentAngle=function(t){var e=this.derivative(t);return Math.atan2(e[1],e[0])},Qt.prototype.normalAngle=function(t){var e=this.derivative(t);return Math.atan2(e[0],e[1])},Qt.prototype.inflectionPoints=function(){var t=this.a[1]*this.b[0]-this.a[0]*this.b[1];if(Gt(t))return[];var e=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/t,s=e*e-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/t;if(s<0)return[];var i=Math.sqrt(s);return Gt(i)?i>0&&i<1?[e]:[]:[e-i,e+i].filter((function(t){return t>0&&t<1}))},Qt.prototype.split=function(t){if(t<=0)return[Zt(this.points[0]),this];if(t>=1)return[this,Zt(this.points[this.points.length-1])];var e=Kt(this.points[0],this.points[1],t),s=Kt(this.points[1],this.points[2],t),i=Kt(this.points[2],this.points[3],t),a=Kt(e,s,t),r=Kt(s,i,t),n=Kt(a,r,t);return[new Qt(this.points[0],e,a,n,!0),new Qt(n,r,i,this.points[3],!0)]},Qt.prototype.bounds=function(){return{x:$t(this,0),y:$t(this,1)}},Qt.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},Qt.prototype.intersections=function(t,e,s){void 0===e&&(e=2),void 0===s&&(s=7);var i=[];return se(te(this,0,1),te(t,0,1),0,e,i,s),i},Qt.shapeSegment=function(t,e){var s=(e+1)%t.length();return new Qt(t.v[e],t.o[e],t.i[s],t.v[s],!0)},Qt.shapeSegmentInverted=function(t,e){var s=(e+1)%t.length();return new Qt(t.v[s],t.i[s],t.o[e],t.v[e],!0)},r([qt],he),he.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=vt.getProp(t,e.s,0,null,this),this.frequency=vt.getProp(t,e.r,0,null,this),this.pointsType=vt.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},he.prototype.processPath=function(t,e,s,i){var a=t._length,r=kt.newElement();if(r.c=t.c,t.c||(a-=1),0===a)return r;var n=-1,o=Qt.shapeSegment(t,0);fe(r,t,0,e,s,i,n);for(var h=0;h<a;h+=1)n=ce(r,o,e,s,i,-n),o=h!==a-1||t.c?Qt.shapeSegment(t,(h+1)%a):null,fe(r,t,h+1,e,s,i,n);return r},he.prototype.processShapes=function(t){var e,s,i,a,r,n,o=this.shapes.length,h=this.amplitude.v,l=Math.max(0,Math.round(this.frequency.v)),p=this.pointsType.v;if(0!==h)for(s=0;s<o;s+=1){if(n=(r=this.shapes[s]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,i=0;i<a;i+=1)n.addShape(this.processPath(e[i],h,l,p));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},r([qt],be),be.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=vt.getProp(t,e.a,0,null,this),this.miterLimit=vt.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},be.prototype.processPath=function(t,e,s,i){var a=kt.newElement();a.c=t.c;var r,n,o,h=t.length();t.c||(h-=1);var l=[];for(r=0;r<h;r+=1)o=Qt.shapeSegment(t,r),l.push(ve(o,e));if(!t.c)for(r=h-1;r>=0;r-=1)o=Qt.shapeSegmentInverted(t,r),l.push(ve(o,e));l=function(t){for(var e,s=1;s<t.length;s+=1)e=ye(t[s-1],t[s]),t[s-1]=e[0],t[s]=e[1];return t.length>1&&(e=ye(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}(l);var p=null,f=null;for(r=0;r<l.length;r+=1){var c=l[r];for(f&&(p=ue(a,f,c[0],s,i)),f=c[c.length-1],n=0;n<c.length;n+=1)o=c[n],p&&oe(o.points[0],p)?a.setXYAt(o.points[1][0],o.points[1][1],"o",a.length()-1):a.setTripleAt(o.points[0][0],o.points[0][1],o.points[1][0],o.points[1][1],o.points[0][0],o.points[0][1],a.length()),a.setTripleAt(o.points[3][0],o.points[3][1],o.points[3][0],o.points[3][1],o.points[2][0],o.points[2][1],a.length()),p=o.points[3]}return l.length&&ue(a,f,l[0][0],s,i),a},be.prototype.processShapes=function(t){var e,s,i,a,r,n,o=this.shapes.length,h=this.amount.v,l=this.miterLimit.v,p=this.lineJoin;if(0!==h)for(s=0;s<o;s+=1){if(n=(r=this.shapes[s]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,i=0;i<a;i+=1)n.addShape(this.processPath(e[i],h,p,l));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var Ce=function(){var t={w:0,size:0,shapes:[],data:{shapes:[]}},e=[];e=e.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);var s=127988,i=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function r(t,e){var s=a("span");s.setAttribute("aria-hidden",!0),s.style.fontFamily=e;var i=a("span");i.innerText="giItT1WQy@!-/#",s.style.position="absolute",s.style.left="-10000px",s.style.top="-10000px",s.style.fontSize="300px",s.style.fontVariant="normal",s.style.fontStyle="normal",s.style.fontWeight="normal",s.style.letterSpacing="0",s.appendChild(i),document.body.appendChild(s);var r=i.offsetWidth;return i.style.fontFamily=function(t){var e,s=t.split(","),i=s.length,a=[];for(e=0;e<i;e+=1)"sans-serif"!==s[e]&&"monospace"!==s[e]&&a.push(s[e]);return a.join(",")}(t)+", "+e,{node:i,w:r,parent:s}}function n(t,e){var s,i=document.body&&e?"svg":"canvas",a=_e(t);if("svg"===i){var r=j("text");r.style.fontSize="100px",r.setAttribute("font-family",t.fFamily),r.setAttribute("font-style",a.style),r.setAttribute("font-weight",a.weight),r.textContent="1",t.fClass?(r.style.fontFamily="inherit",r.setAttribute("class",t.fClass)):r.style.fontFamily=t.fFamily,e.appendChild(r),s=r}else{var n=new OffscreenCanvas(500,500).getContext("2d");n.font=a.style+" "+a.weight+" 100px "+t.fFamily,s=n}return{measureText:function(t){return"svg"===i?(s.textContent=t,s.getComputedTextLength()):s.measureText(t).width}}}function o(t){var e=0,s=t.charCodeAt(0);if(s>=55296&&s<=56319){var i=t.charCodeAt(1);i>=56320&&i<=57343&&(e=1024*(s-55296)+i-56320+65536)}return e}function h(t){var e=o(t);return e>=127462&&e<=127487}var l=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)};l.isModifier=function(t,e){var s=t.toString(16)+e.toString(16);return-1!==i.indexOf(s)},l.isZeroWidthJoiner=function(t){return 8205===t},l.isFlagEmoji=function(t){return h(t.substr(0,2))&&h(t.substr(2,2))},l.isRegionalCode=h,l.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},l.isRegionalFlag=function(t,e){var i=o(t.substr(e,2));if(i!==s)return!1;var a=0;for(e+=2;a<5;){if((i=o(t.substr(e,2)))<917601||i>917626)return!1;a+=1,e+=2}return 917631===o(t.substr(e,2))},l.isVariationSelector=function(t){return 65039===t},l.BLACK_FLAG_CODE_POINT=s;var p={addChars:function(t){if(t){var e;this.chars||(this.chars=[]);var s,i,a=t.length,r=this.chars.length;for(e=0;e<a;e+=1){for(s=0,i=!1;s<r;)this.chars[s].style===t[e].style&&this.chars[s].fFamily===t[e].fFamily&&this.chars[s].ch===t[e].ch&&(i=!0),s+=1;i||(this.chars.push(t[e]),r+=1)}}},addFonts:function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);if(!document.body)return this.isLoaded=!0,t.list.forEach((function(t){t.helper=n(t),t.cache={}})),void(this.fonts=t.list);var s,i=t.list,o=i.length,h=o;for(s=0;s<o;s+=1){var l,p,f=!0;if(i[s].loaded=!1,i[s].monoCase=r(i[s].fFamily,"monospace"),i[s].sansCase=r(i[s].fFamily,"sans-serif"),i[s].fPath){if("p"===i[s].fOrigin||3===i[s].origin){if((l=document.querySelectorAll('style[f-forigin="p"][f-family="'+i[s].fFamily+'"], style[f-origin="3"][f-family="'+i[s].fFamily+'"]')).length>0&&(f=!1),f){var c=a("style");c.setAttribute("f-forigin",i[s].fOrigin),c.setAttribute("f-origin",i[s].origin),c.setAttribute("f-family",i[s].fFamily),c.type="text/css",c.innerText="@font-face {font-family: "+i[s].fFamily+"; font-style: normal; src: url('"+i[s].fPath+"');}",e.appendChild(c)}}else if("g"===i[s].fOrigin||1===i[s].origin){for(l=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),p=0;p<l.length;p+=1)-1!==l[p].href.indexOf(i[s].fPath)&&(f=!1);if(f){var d=a("link");d.setAttribute("f-forigin",i[s].fOrigin),d.setAttribute("f-origin",i[s].origin),d.type="text/css",d.rel="stylesheet",d.href=i[s].fPath,document.body.appendChild(d)}}else if("t"===i[s].fOrigin||2===i[s].origin){for(l=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),p=0;p<l.length;p+=1)i[s].fPath===l[p].src&&(f=!1);if(f){var m=a("link");m.setAttribute("f-forigin",i[s].fOrigin),m.setAttribute("f-origin",i[s].origin),m.setAttribute("rel","stylesheet"),m.setAttribute("href",i[s].fPath),e.appendChild(m)}}}else i[s].loaded=!0,h-=1;i[s].helper=n(i[s],e),i[s].cache={},this.fonts.push(i[s])}0===h?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},getCharData:function(e,s,i){for(var a=0,r=this.chars.length;a<r;){if(this.chars[a].ch===e&&this.chars[a].style===s&&this.chars[a].fFamily===i)return this.chars[a];a+=1}return("string"==typeof e&&13!==e.charCodeAt(0)||!e)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",e,s,i)),t},getFontByName:function(t){for(var e=0,s=this.fonts.length;e<s;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,s){var i=this.getFontByName(e),a=t;if(!i.cache[a]){var r=i.helper;if(" "===t){var n=r.measureText("|"+t+"|"),o=r.measureText("||");i.cache[a]=(n-o)/100}else i.cache[a]=r.measureText(t)/100}return i.cache[a]*s},checkLoadedFonts:function(){var t,e,s,i=this.fonts.length,a=i;for(t=0;t<i;t+=1)this.fonts[t].loaded?a-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,s=this.fonts[t].monoCase.w,e.offsetWidth!==s?(a-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,s=this.fonts[t].sansCase.w,e.offsetWidth!==s&&(a-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==a&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}};return l.prototype=p,l}();function xe(t){this.animationData=t}function ke(){}xe.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},ke.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var Se,Pe=(Se={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return Se[t]||""});function De(t,e,s){this.p=vt.getProp(e,t.v,0,0,s)}function we(t,e,s){this.p=vt.getProp(e,t.v,0,0,s)}function Ae(t,e,s){this.p=vt.getProp(e,t.v,1,0,s)}function Me(t,e,s){this.p=vt.getProp(e,t.v,1,0,s)}function Te(t,e,s){this.p=vt.getProp(e,t.v,0,0,s)}function Fe(t,e,s){this.p=vt.getProp(e,t.v,0,0,s)}function Ee(t,e,s){this.p=vt.getProp(e,t.v,0,0,s)}function Le(){this.p={}}function Ie(t,e){var s,i=t.ef||[];this.effectElements=[];var a,r=i.length;for(s=0;s<r;s+=1)a=new Re(i[s],e),this.effectElements.push(a)}function Re(t,e){this.init(t,e)}function Ve(){}function ze(){}function Oe(t,e,s){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,s)}function Ne(t,e,s){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,s),this._isPlaying=!1,this._canPlay=!1;var i=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(i),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?vt.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=vt.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function qe(){}r([bt],Re),Re.prototype.getValue=Re.prototype.iterateDynamicProperties,Re.prototype.init=function(t,e){var s;this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var i,a=this.data.ef.length,r=this.data.ef;for(s=0;s<a;s+=1){switch(i=null,r[s].ty){case 0:i=new De(r[s],e,this);break;case 1:i=new we(r[s],e,this);break;case 2:i=new Ae(r[s],e,this);break;case 3:i=new Me(r[s],e,this);break;case 4:case 7:i=new Ee(r[s],e,this);break;case 10:i=new Te(r[s],e,this);break;case 11:i=new Fe(r[s],e,this);break;case 5:i=new Ie(r[s],e,this);break;default:i=new Le(r[s],e,this)}i&&this.effectElements.push(i)}},Ve.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t=q();if(t){var e=t("layer"),s=t("effects"),i=t("shape"),a=t("text"),r=t("comp");this.layerInterface=e(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var n=s.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(n),0===this.data.ty||this.data.xt?this.compInterface=r(this):4===this.data.ty?(this.layerInterface.shapeInterface=i(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=a(this),this.layerInterface.text=this.layerInterface.textInterface)}},setBlendMode:function(){var t=Pe(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,s){this.globalData=e,this.comp=s,this.data=t,this.layerId=L(),this.data.sr||(this.data.sr=1),this.effectsManager=new Ie(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},ze.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var s,i=this.dynamicProperties.length;for(s=0;s<i;s+=1)(e||this._isParent&&"transform"===this.dynamicProperties[s].propType)&&(this.dynamicProperties[s].getValue(),this.dynamicProperties[s]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},Oe.prototype.prepareFrame=function(){},r([ke,Ve,ze],Oe),Oe.prototype.getBaseElement=function(){return null},Oe.prototype.renderFrame=function(){},Oe.prototype.destroy=function(){},Oe.prototype.initExpressions=function(){var t=q();if(t){var e=t("footage");this.layerInterface=e(this)}},Oe.prototype.getFootageData=function(){return this.footageData},Ne.prototype.prepareFrame=function(t){if(this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder)this._currentTime=t/this.data.sr;else{var e=this.tm.v;this._currentTime=e}this._volume=this.lv.v[0];var s=this._volume*this._volumeMultiplier;this._previousVolume!==s&&(this._previousVolume=s,this.audio.volume(s))},r([ke,Ve,ze],Ne),Ne.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek())>.1)&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},Ne.prototype.show=function(){},Ne.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},Ne.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},Ne.prototype.resume=function(){this._canPlay=!0},Ne.prototype.setRate=function(t){this.audio.rate(t)},Ne.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},Ne.prototype.getBaseElement=function(){return null},Ne.prototype.destroy=function(){},Ne.prototype.sourceRectAtTime=function(){},Ne.prototype.initExpressions=function(){},qe.prototype.checkLayers=function(t){var e,s,i=this.layers.length;for(this.completeLayers=!0,e=i-1;e>=0;e-=1)this.elements[e]||(s=this.layers[e]).ip-s.st<=t-this.layers[e].st&&s.op-s.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},qe.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:default:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t)}},qe.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},qe.prototype.createAudio=function(t){return new Ne(t,this.globalData,this)},qe.prototype.createFootage=function(t){return new Oe(t,this.globalData,this)},qe.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},qe.prototype.includeLayers=function(t){var e;this.completeLayers=!1;var s,i=t.length,a=this.layers.length;for(e=0;e<i;e+=1)for(s=0;s<a;){if(this.layers[s].id===t[e].id){this.layers[s]=t[e];break}s+=1}},qe.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},qe.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},qe.prototype.buildElementParenting=function(t,e,s){for(var i=this.elements,a=this.layers,r=0,n=a.length;r<n;)a[r].ind==e&&(i[r]&&!0!==i[r]?(s.push(i[r]),i[r].setAsParent(),void 0!==a[r].parent?this.buildElementParenting(t,a[r].parent,s):t.setHierarchy(s)):(this.buildItem(r),this.addPendingElement(t))),r+=1},qe.prototype.addPendingElement=function(t){this.pendingElements.push(t)},qe.prototype.searchExtraCompositions=function(t){var e,s=t.length;for(e=0;e<s;e+=1)if(t[e].xt){var i=this.createComp(t[e]);i.initExpressions(),this.globalData.projectInterface.registerComposition(i)}},qe.prototype.getElementById=function(t){var e,s=this.elements.length;for(e=0;e<s;e+=1)if(this.elements[e].data.ind===t)return this.elements[e];return null},qe.prototype.getElementByPath=function(t){var e,s=t.shift();if("number"==typeof s)e=this.elements[s];else{var i,a=this.elements.length;for(i=0;i<a;i+=1)if(this.elements[i].data.nm===s){e=this.elements[i];break}}return 0===t.length?e:e.getElementByPath(t)},qe.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new Ce,this.globalData.slotManager=function(t){return new xe(t)}(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var Be="transformEFfect";function We(){}function je(t,e,s){this.data=t,this.element=e,this.globalData=s,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var a,r,n=this.globalData.defs,o=this.masksProperties?this.masksProperties.length:0;this.viewData=l(o),this.solidPath="";var h,p,f,c,d,m,u=this.masksProperties,g=0,y=[],v=L(),b="clipPath",_="clip-path";for(a=0;a<o;a+=1)if(("a"!==u[a].mode&&"n"!==u[a].mode||u[a].inv||100!==u[a].o.k||u[a].o.x)&&(b="mask",_="mask"),"s"!==u[a].mode&&"i"!==u[a].mode||0!==g?f=null:((f=j("rect")).setAttribute("fill","#ffffff"),f.setAttribute("width",this.element.comp.data.w||0),f.setAttribute("height",this.element.comp.data.h||0),y.push(f)),r=j("path"),"n"===u[a].mode)this.viewData[a]={op:vt.getProp(this.element,u[a].o,0,.01,this.element),prop:Tt.getShapeProp(this.element,u[a],3),elem:r,lastPath:""},n.appendChild(r);else{var C;if(g+=1,r.setAttribute("fill","s"===u[a].mode?"#000000":"#ffffff"),r.setAttribute("clip-rule","nonzero"),0!==u[a].x.k?(b="mask",_="mask",m=vt.getProp(this.element,u[a].x,0,null,this.element),C=L(),(c=j("filter")).setAttribute("id",C),(d=j("feMorphology")).setAttribute("operator","erode"),d.setAttribute("in","SourceGraphic"),d.setAttribute("radius","0"),c.appendChild(d),n.appendChild(c),r.setAttribute("stroke","s"===u[a].mode?"#000000":"#ffffff")):(d=null,m=null),this.storedData[a]={elem:r,x:m,expan:d,lastPath:"",lastOperator:"",filterId:C,lastRadius:0},"i"===u[a].mode){p=y.length;var x=j("g");for(h=0;h<p;h+=1)x.appendChild(y[h]);var k=j("mask");k.setAttribute("mask-type","alpha"),k.setAttribute("id",v+"_"+g),k.appendChild(r),n.appendChild(k),x.setAttribute("mask","url("+i()+"#"+v+"_"+g+")"),y.length=0,y.push(x)}else y.push(r);u[a].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[a]={elem:r,lastPath:"",op:vt.getProp(this.element,u[a].o,0,.01,this.element),prop:Tt.getShapeProp(this.element,u[a],3),invRect:f},this.viewData[a].prop.k||this.drawPath(u[a],this.viewData[a].prop.v,this.viewData[a])}for(this.maskElement=j(b),o=y.length,a=0;a<o;a+=1)this.maskElement.appendChild(y[a]);g>0&&(this.maskElement.setAttribute("id",v),this.element.maskedElement.setAttribute(_,"url("+i()+"#"+v+")"),n.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}We.prototype={initTransform:function(){var t=new Ft;this.finalTransform={mProp:this.data.ks?jt.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,s=0,i=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;s<i;){if(this.hierarchy[s].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}s+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),s=0;s<i;s+=1)e.multiply(this.hierarchy[s].finalTransform.mProp.v)}this.finalTransform._matMdf&&(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var s=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(s),t=1;t<e;t+=1){var i=this.localTransforms[t].matrix;s.multiply(i)}s.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){var a=this.finalTransform.localOpacity;for(t=0;t<e;t+=1)a*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=a}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(Be);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new Ft;var e=0,s=t.length;for(e=0;e<s;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var s,i=!0,a=this.comp;i;)a.finalTransform?(a.data.hasMask&&e.splice(0,0,a.finalTransform),a=a.comp):i=!1;var r,n=e.length;for(s=0;s<n;s+=1)r=e[s].mat.applyToPointArray(0,0,0),t=[t[0]-r[0],t[1]-r[1],0];return t},mHelper:new Ft},je.prototype.getMaskProperty=function(t){return this.viewData[t].prop},je.prototype.renderFrame=function(t){var e,s=this.element.finalTransform.mat,a=this.masksProperties.length;for(e=0;e<a;e+=1)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[e].invRect.setAttribute("transform",s.getInverseMatrix().to2dCSS()),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var r=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+i()+"#"+this.storedData[e].filterId+")")),r.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},je.prototype.getMaskelement=function(){return this.maskElement},je.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},je.prototype.drawPath=function(t,e,s){var i,a,r=" M"+e.v[0][0]+","+e.v[0][1];for(a=e._length,i=1;i<a;i+=1)r+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[i][0]+","+e.i[i][1]+" "+e.v[i][0]+","+e.v[i][1];if(e.c&&a>1&&(r+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),s.lastPath!==r){var n="";s.elem&&(e.c&&(n=t.inv?this.solidPath+r:r),s.elem.setAttribute("d",n)),s.lastPath=r}},je.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var Ye=function(){var t={};return t.createFilter=function(t,e){var s=j("filter");s.setAttribute("id",t),!0!==e&&(s.setAttribute("filterUnits","objectBoundingBox"),s.setAttribute("x","0%"),s.setAttribute("y","0%"),s.setAttribute("width","100%"),s.setAttribute("height","100%"));return s},t.createAlphaToLuminanceFilter=function(){var t=j("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},t}(),Je=function(){var t={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),/firefox/i.test(navigator.userAgent)&&(t.svgLumaHidden=!1),t}(),He={},Ge="filter_result_";function Xe(t){var e,s,a="SourceGraphic",r=t.data.ef?t.data.ef.length:0,n=L(),o=Ye.createFilter(n,!0),h=0;for(this.filters=[],e=0;e<r;e+=1){s=null;var l=t.data.ef[e].ty;if(He[l])s=new(0,He[l].effect)(o,t.effectsManager.effectElements[e],t,Ge+h,a),a=Ge+h,He[l].countsAsEffect&&(h+=1);s&&this.filters.push(s)}h&&(t.globalData.defs.appendChild(o),t.layerElement.setAttribute("filter","url("+i()+"#"+n+")")),this.filters.length&&t.addRenderableComponent(this)}function Ke(){}function Ue(){}function Ze(){}function Qe(t,e,s){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,s),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function $e(t,e){this.elem=t,this.pos=e}function ts(){}Xe.prototype.renderFrame=function(t){var e,s=this.filters.length;for(e=0;e<s;e+=1)this.filters[e].renderFrame(t)},Xe.prototype.getEffects=function(t){var e,s=this.filters.length,i=[];for(e=0;e<s;e+=1)this.filters[e].type===t&&i.push(this.filters[e]);return i},Ke.prototype={initRendererElement:function(){this.layerElement=j("g")},createContainerElements:function(){this.matteElement=j("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t=null;if(this.data.td){this.matteMasks={};var e=j("g");e.setAttribute("id",this.layerId),e.appendChild(this.layerElement),t=e,this.globalData.defs.appendChild(e)}else this.data.tt?(this.matteElement.appendChild(this.layerElement),t=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var s=j("clipPath"),a=j("path");a.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var r=L();if(s.setAttribute("id",r),s.appendChild(a),this.globalData.defs.appendChild(s),this.checkMasks()){var n=j("g");n.setAttribute("clip-path","url("+i()+"#"+r+")"),n.appendChild(this.layerElement),this.transformedElement=n,t?t.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+i()+"#"+r+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new je(this.data,this,this.globalData),this.renderableEffectsManager=new Xe(this),this.searchEffectTransforms()},getMatte:function(t){if(this.matteMasks||(this.matteMasks={}),!this.matteMasks[t]){var e,s,a,r,n=this.layerId+"_"+t;if(1===t||3===t){var o=j("mask");o.setAttribute("id",n),o.setAttribute("mask-type",3===t?"luminance":"alpha"),(a=j("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),o.appendChild(a),this.globalData.defs.appendChild(o),Je.maskType||1!==t||(o.setAttribute("mask-type","luminance"),e=L(),s=Ye.createFilter(e),this.globalData.defs.appendChild(s),s.appendChild(Ye.createAlphaToLuminanceFilter()),(r=j("g")).appendChild(a),o.appendChild(r),r.setAttribute("filter","url("+i()+"#"+e+")"))}else if(2===t){var h=j("mask");h.setAttribute("id",n),h.setAttribute("mask-type","alpha");var l=j("g");h.appendChild(l),e=L(),s=Ye.createFilter(e);var p=j("feComponentTransfer");p.setAttribute("in","SourceGraphic"),s.appendChild(p);var f=j("feFuncA");f.setAttribute("type","table"),f.setAttribute("tableValues","1.0 0.0"),p.appendChild(f),this.globalData.defs.appendChild(s);var c=j("rect");c.setAttribute("width",this.comp.data.w),c.setAttribute("height",this.comp.data.h),c.setAttribute("x","0"),c.setAttribute("y","0"),c.setAttribute("fill","#ffffff"),c.setAttribute("opacity","0"),l.setAttribute("filter","url("+i()+"#"+e+")"),l.appendChild(c),(a=j("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),l.appendChild(a),Je.maskType||(h.setAttribute("mask-type","luminance"),s.appendChild(Ye.createAlphaToLuminanceFilter()),r=j("g"),l.appendChild(c),r.appendChild(this.layerElement),l.appendChild(r)),this.globalData.defs.appendChild(h)}this.matteMasks[t]=n}return this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+i()+"#"+t+")")}},Ue.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},r([ke,n({initElement:function(t,e,s){this.initFrame(),this.initBaseData(t,e,s),this.initTransform(t,e,s),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],Ze),r([Ve,We,Ke,Ue,ze,Ze],Qe),Qe.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=j("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},Qe.prototype.sourceRectAtTime=function(){return this.sourceRect},ts.prototype={addShapeToModifiers:function(t){var e,s=this.shapeModifiers.length;for(e=0;e<s;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;t>=0&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,s=0,i=e.length;s<i;){if(e[s].elem===t)return e[s].pos;s+=1}return 0},addProcessedElement:function(t,e){for(var s=this.processedElements,i=s.length;i;)if(s[i-=1].elem===t)return void(s[i].pos=e);s.push(new $e(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var es={1:"butt",2:"round",3:"square"},ss={1:"miter",2:"round",3:"bevel"};function is(t,e,s){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=s,this.lvl=e,this._isAnimated=!!s.k;for(var i=0,a=t.length;i<a;){if(t[i].mProps.dynamicProperties.length){this._isAnimated=!0;break}i+=1}}function as(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=j("path"),this.msElem=null}function rs(t,e,s,i){var a;this.elem=t,this.frameId=-1,this.dataProps=l(e.length),this.renderer=s,this.k=!1,this.dashStr="",this.dashArray=h("float32",e.length?e.length-1:0),this.dashoffset=h("float32",1),this.initDynamicPropertyContainer(i);var r,n=e.length||0;for(a=0;a<n;a+=1)r=vt.getProp(t,e[a].v,0,0,this),this.k=r.k||this.k,this.dataProps[a]={n:e[a].n,p:r};this.k||this.getValue(!0),this._isAnimated=this.k}function ns(t,e,s){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=vt.getProp(t,e.o,0,.01,this),this.w=vt.getProp(t,e.w,0,null,this),this.d=new rs(t,e.d||{},"svg",this),this.c=vt.getProp(t,e.c,1,255,this),this.style=s,this._isAnimated=!!this._isAnimated}function os(t,e,s){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=vt.getProp(t,e.o,0,.01,this),this.c=vt.getProp(t,e.c,1,255,this),this.style=s}function hs(t,e,s){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=s}function ls(t,e,s){this.data=e,this.c=h("uint8c",4*e.p);var i=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=h("float32",i),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=i,this.initDynamicPropertyContainer(s),this.prop=vt.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function ps(t,e,s){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,s)}function fs(t,e,s){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=vt.getProp(t,e.w,0,null,this),this.d=new rs(t,e.d||{},"svg",this),this.initGradientData(t,e,s),this._isAnimated=!!this._isAnimated}function cs(){this.it=[],this.prevViewData=[],this.gr=j("g")}function ds(t,e,s){this.transform={mProps:t,op:e,container:s},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}is.prototype.setAsAnimated=function(){this._isAnimated=!0},as.prototype.reset=function(){this.d="",this._mdf=!1},rs.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,s=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<s;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},r([bt],rs),r([bt],ns),r([bt],os),r([bt],hs),ls.prototype.comparePoints=function(t,e){for(var s=0,i=this.o.length/2;s<i;){if(Math.abs(t[4*s]-t[4*e+2*s])>.01)return!1;s+=1}return!0},ls.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},ls.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,s,i,a=4*this.data.p;for(e=0;e<a;e+=1)s=e%4==0?100:255,i=Math.round(this.prop.v[e]*s),this.c[e]!==i&&(this.c[e]=i,this._cmdf=!t);if(this.o.length)for(a=this.prop.v.length,e=4*this.data.p;e<a;e+=1)s=e%2==0?100:1,i=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==i&&(this.o[e-4*this.data.p]=i,this._omdf=!t);this._mdf=!t}},r([bt],ls),ps.prototype.initGradientData=function(t,e,s){this.o=vt.getProp(t,e.o,0,.01,this),this.s=vt.getProp(t,e.s,1,null,this),this.e=vt.getProp(t,e.e,1,null,this),this.h=vt.getProp(t,e.h||{k:0},0,.01,this),this.a=vt.getProp(t,e.a||{k:0},0,x,this),this.g=new ls(t,e.g,this),this.style=s,this.stops=[],this.setGradientData(s.pElem,e),this.setGradientOpacity(e,s),this._isAnimated=!!this._isAnimated},ps.prototype.setGradientData=function(t,e){var s=L(),a=j(1===e.t?"linearGradient":"radialGradient");a.setAttribute("id",s),a.setAttribute("spreadMethod","pad"),a.setAttribute("gradientUnits","userSpaceOnUse");var r,n,o,h=[];for(o=4*e.g.p,n=0;n<o;n+=4)r=j("stop"),a.appendChild(r),h.push(r);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+i()+"#"+s+")"),this.gf=a,this.cst=h},ps.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){var s,a,r,n=j("mask"),o=j("path");n.appendChild(o);var h=L(),l=L();n.setAttribute("id",l);var p=j(1===t.t?"linearGradient":"radialGradient");p.setAttribute("id",h),p.setAttribute("spreadMethod","pad"),p.setAttribute("gradientUnits","userSpaceOnUse"),r=t.g.k.k[0].s?t.g.k.k[0].s.length:t.g.k.k.length;var f=this.stops;for(a=4*t.g.p;a<r;a+=2)(s=j("stop")).setAttribute("stop-color","rgb(255,255,255)"),p.appendChild(s),f.push(s);o.setAttribute("gf"===t.ty?"fill":"stroke","url("+i()+"#"+h+")"),"gs"===t.ty&&(o.setAttribute("stroke-linecap",es[t.lc||2]),o.setAttribute("stroke-linejoin",ss[t.lj||2]),1===t.lj&&o.setAttribute("stroke-miterlimit",t.ml)),this.of=p,this.ms=n,this.ost=f,this.maskId=l,e.msElem=o}},r([bt],ps),r([ps,bt],fs);var ms=function(t,e,s,i){if(0===e)return"";var a,r=t.o,n=t.i,o=t.v,h=" M"+i.applyToPointStringified(o[0][0],o[0][1]);for(a=1;a<e;a+=1)h+=" C"+i.applyToPointStringified(r[a-1][0],r[a-1][1])+" "+i.applyToPointStringified(n[a][0],n[a][1])+" "+i.applyToPointStringified(o[a][0],o[a][1]);return s&&e&&(h+=" C"+i.applyToPointStringified(r[a-1][0],r[a-1][1])+" "+i.applyToPointStringified(n[0][0],n[0][1])+" "+i.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},us=function(){var t=new Ft,e=new Ft;function s(t,e,s){(s||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(s||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function i(){}function a(s,i,a){var r,n,o,h,l,p,f,c,d,m,u=i.styles.length,g=i.lvl;for(p=0;p<u;p+=1){if(h=i.sh._mdf||a,i.styles[p].lvl<g){for(c=e.reset(),d=g-i.styles[p].lvl,m=i.transformers.length-1;!h&&d>0;)h=i.transformers[m].mProps._mdf||h,d-=1,m-=1;if(h)for(d=g-i.styles[p].lvl,m=i.transformers.length-1;d>0;)c.multiply(i.transformers[m].mProps.v),d-=1,m-=1}else c=t;if(n=(f=i.sh.paths)._length,h){for(o="",r=0;r<n;r+=1)(l=f.shapes[r])&&l._length&&(o+=ms(l,l._length,l.c,c));i.caches[p]=o}else o=i.caches[p];i.styles[p].d+=!0===s.hd?"":o,i.styles[p]._mdf=h||i.styles[p]._mdf}}function r(t,e,s){var i=e.style;(e.c._mdf||s)&&i.pElem.setAttribute("fill","rgb("+v(e.c.v[0])+","+v(e.c.v[1])+","+v(e.c.v[2])+")"),(e.o._mdf||s)&&i.pElem.setAttribute("fill-opacity",e.o.v)}function n(t,e,s){o(t,e,s),h(t,e,s)}function o(t,e,s){var i,a,r,n,o,h=e.gf,l=e.g._hasOpacity,p=e.s.v,f=e.e.v;if(e.o._mdf||s){var c="gf"===t.ty?"fill-opacity":"stroke-opacity";e.style.pElem.setAttribute(c,e.o.v)}if(e.s._mdf||s){var d=1===t.t?"x1":"cx",m="x1"===d?"y1":"cy";h.setAttribute(d,p[0]),h.setAttribute(m,p[1]),l&&!e.g._collapsable&&(e.of.setAttribute(d,p[0]),e.of.setAttribute(m,p[1]))}if(e.g._cmdf||s){i=e.cst;var u=e.g.c;for(r=i.length,a=0;a<r;a+=1)(n=i[a]).setAttribute("offset",u[4*a]+"%"),n.setAttribute("stop-color","rgb("+u[4*a+1]+","+u[4*a+2]+","+u[4*a+3]+")")}if(l&&(e.g._omdf||s)){var g=e.g.o;for(r=(i=e.g._collapsable?e.cst:e.ost).length,a=0;a<r;a+=1)n=i[a],e.g._collapsable||n.setAttribute("offset",g[2*a]+"%"),n.setAttribute("stop-opacity",g[2*a+1])}if(1===t.t)(e.e._mdf||s)&&(h.setAttribute("x2",f[0]),h.setAttribute("y2",f[1]),l&&!e.g._collapsable&&(e.of.setAttribute("x2",f[0]),e.of.setAttribute("y2",f[1])));else if((e.s._mdf||e.e._mdf||s)&&(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)),h.setAttribute("r",o),l&&!e.g._collapsable&&e.of.setAttribute("r",o)),e.e._mdf||e.h._mdf||e.a._mdf||s){o||(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)));var y=Math.atan2(f[1]-p[1],f[0]-p[0]),v=e.h.v;v>=1?v=.99:v<=-1&&(v=-.99);var b=o*v,_=Math.cos(y+e.a.v)*b+p[0],C=Math.sin(y+e.a.v)*b+p[1];h.setAttribute("fx",_),h.setAttribute("fy",C),l&&!e.g._collapsable&&(e.of.setAttribute("fx",_),e.of.setAttribute("fy",C))}}function h(t,e,s){var i=e.style,a=e.d;a&&(a._mdf||s)&&a.dashStr&&(i.pElem.setAttribute("stroke-dasharray",a.dashStr),i.pElem.setAttribute("stroke-dashoffset",a.dashoffset[0])),e.c&&(e.c._mdf||s)&&i.pElem.setAttribute("stroke","rgb("+v(e.c.v[0])+","+v(e.c.v[1])+","+v(e.c.v[2])+")"),(e.o._mdf||s)&&i.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||s)&&(i.pElem.setAttribute("stroke-width",e.w.v),i.msElem&&i.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function(t){switch(t.ty){case"fl":return r;case"gf":return o;case"gs":return n;case"st":return h;case"sh":case"el":case"rc":case"sr":return a;case"tr":return s;case"no":return i;default:return null}}}}();function gs(t,e,s){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,s),this.prevViewData=[]}function ys(t,e,s,i,a,r){this.o=t,this.sw=e,this.sc=s,this.fc=i,this.m=a,this.p=r,this._mdf={o:!0,sw:!!e,sc:!!s,fc:!!i,m:!0,p:!0}}function vs(t,e){this._frameId=s,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}r([Ve,We,Ke,ts,Ue,ze,Ze],gs),gs.prototype.initSecondaryElement=function(){},gs.prototype.identityMatrix=new Ft,gs.prototype.buildExpressionInterface=function(){},gs.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},gs.prototype.filterUniqueShapes=function(){var t,e,s,i,a=this.shapes.length,r=this.stylesList.length,n=[],o=!1;for(s=0;s<r;s+=1){for(i=this.stylesList[s],o=!1,n.length=0,t=0;t<a;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(i)&&(n.push(e),o=e._isAnimated||o);n.length>1&&o&&this.setShapesAsAnimated(n)}},gs.prototype.setShapesAsAnimated=function(t){var e,s=t.length;for(e=0;e<s;e+=1)t[e].setAsAnimated()},gs.prototype.createStyleElement=function(t,e){var s,a=new as(t,e),r=a.pElem;if("st"===t.ty)s=new ns(this,t,a);else if("fl"===t.ty)s=new os(this,t,a);else if("gf"===t.ty||"gs"===t.ty){s=new("gf"===t.ty?ps:fs)(this,t,a),this.globalData.defs.appendChild(s.gf),s.maskId&&(this.globalData.defs.appendChild(s.ms),this.globalData.defs.appendChild(s.of),r.setAttribute("mask","url("+i()+"#"+s.maskId+")"))}else"no"===t.ty&&(s=new hs(this,t,a));return"st"!==t.ty&&"gs"!==t.ty||(r.setAttribute("stroke-linecap",es[t.lc||2]),r.setAttribute("stroke-linejoin",ss[t.lj||2]),r.setAttribute("fill-opacity","0"),1===t.lj&&r.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&r.setAttribute("fill-rule","evenodd"),t.ln&&r.setAttribute("id",t.ln),t.cl&&r.setAttribute("class",t.cl),t.bm&&(r.style["mix-blend-mode"]=Pe(t.bm)),this.stylesList.push(a),this.addToAnimatedContents(t,s),s},gs.prototype.createGroupElement=function(t){var e=new cs;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=Pe(t.bm)),e},gs.prototype.createTransformElement=function(t,e){var s=jt.getTransformProperty(this,t,this),i=new ds(s,s.o,e);return this.addToAnimatedContents(t,i),i},gs.prototype.createShapeElement=function(t,e,s){var i=4;"rc"===t.ty?i=5:"el"===t.ty?i=6:"sr"===t.ty&&(i=7);var a=new is(e,s,Tt.getShapeProp(this,t,i,this));return this.shapes.push(a),this.addShapeToModifiers(a),this.addToAnimatedContents(t,a),a},gs.prototype.addToAnimatedContents=function(t,e){for(var s=0,i=this.animatedContents.length;s<i;){if(this.animatedContents[s].element===e)return;s+=1}this.animatedContents.push({fn:us.createRenderFunction(t),element:e,data:t})},gs.prototype.setElementStyles=function(t){var e,s=t.styles,i=this.stylesList.length;for(e=0;e<i;e+=1)this.stylesList[e].closed||s.push(this.stylesList[e])},gs.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},gs.prototype.searchShapes=function(t,e,s,i,a,r,n){var o,h,l,p,f,c,d=[].concat(r),m=t.length-1,u=[],g=[];for(o=m;o>=0;o-=1){if((c=this.searchProcessedElement(t[o]))?e[o]=s[c-1]:t[o]._render=n,"fl"===t[o].ty||"st"===t[o].ty||"gf"===t[o].ty||"gs"===t[o].ty||"no"===t[o].ty)c?e[o].style.closed=!1:e[o]=this.createStyleElement(t[o],a),t[o]._render&&e[o].style.pElem.parentNode!==i&&i.appendChild(e[o].style.pElem),u.push(e[o].style);else if("gr"===t[o].ty){if(c)for(l=e[o].it.length,h=0;h<l;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,a+1,d,n),t[o]._render&&e[o].gr.parentNode!==i&&i.appendChild(e[o].gr)}else"tr"===t[o].ty?(c||(e[o]=this.createTransformElement(t[o],i)),p=e[o].transform,d.push(p)):"sh"===t[o].ty||"rc"===t[o].ty||"el"===t[o].ty||"sr"===t[o].ty?(c||(e[o]=this.createShapeElement(t[o],d,a)),this.setElementStyles(e[o])):"tm"===t[o].ty||"rd"===t[o].ty||"ms"===t[o].ty||"pb"===t[o].ty||"zz"===t[o].ty||"op"===t[o].ty?(c?(f=e[o]).closed=!1:((f=Nt.getModifier(t[o].ty)).init(this,t[o]),e[o]=f,this.shapeModifiers.push(f)),g.push(f)):"rp"===t[o].ty&&(c?(f=e[o]).closed=!0:(f=Nt.getModifier(t[o].ty),e[o]=f,f.init(this,t,o,e),this.shapeModifiers.push(f),n=!1),g.push(f));this.addProcessedElement(t[o],o+1)}for(m=u.length,o=0;o<m;o+=1)u[o].closed=!0;for(m=g.length,o=0;o<m;o+=1)g[o].closed=!0},gs.prototype.renderInnerContent=function(){var t;this.renderModifiers();var e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},gs.prototype.renderShape=function(){var t,e,s=this.animatedContents.length;for(t=0;t<s;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},gs.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},ys.prototype.update=function(t,e,s,i,a,r){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1,this._mdf.p=!1;var n=!1;return this.o!==t&&(this.o=t,this._mdf.o=!0,n=!0),this.sw!==e&&(this.sw=e,this._mdf.sw=!0,n=!0),this.sc!==s&&(this.sc=s,this._mdf.sc=!0,n=!0),this.fc!==i&&(this.fc=i,this._mdf.fc=!0,n=!0),this.m!==a&&(this.m=a,this._mdf.m=!0,n=!0),!r.length||this.p[0]===r[0]&&this.p[1]===r[1]&&this.p[4]===r[4]&&this.p[5]===r[5]&&this.p[12]===r[12]&&this.p[13]===r[13]||(this.p=r,this._mdf.p=!0,n=!0),n},vs.prototype.defaultBoxWidth=[0,0],vs.prototype.copyData=function(t,e){for(var s in e)Object.prototype.hasOwnProperty.call(e,s)&&(t[s]=e[s]);return t},vs.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},vs.prototype.searchProperty=function(){return this.searchKeyframes()},vs.prototype.searchKeyframes=function(){return this.kf=this.data.d.k.length>1,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},vs.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},vs.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,s=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{var i;this.lock=!0,this._mdf=!1;var a=this.effectsSequence.length,r=t||this.data.d.k[this.keysIndex].s;for(i=0;i<a;i+=1)r=s!==this.keysIndex?this.effectsSequence[i](r,r.t):this.effectsSequence[i](this.currentData,r.t);e!==r&&this.setCurrentData(r),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},vs.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,s=0,i=t.length;s<=i-1&&!(s===i-1||t[s+1].t>e);)s+=1;return this.keysIndex!==s&&(this.keysIndex=s),this.data.d.k[this.keysIndex].s},vs.prototype.buildFinalText=function(t){for(var e,s,i=[],a=0,r=t.length,n=!1,o=!1,h="";a<r;)n=o,o=!1,e=t.charCodeAt(a),h=t.charAt(a),Ce.isCombinedCharacter(e)?n=!0:e>=55296&&e<=56319?Ce.isRegionalFlag(t,a)?h=t.substr(a,14):(s=t.charCodeAt(a+1))>=56320&&s<=57343&&(Ce.isModifier(e,s)?(h=t.substr(a,2),n=!0):h=Ce.isFlagEmoji(t.substr(a,4))?t.substr(a,4):t.substr(a,2)):e>56319?(s=t.charCodeAt(a+1),Ce.isVariationSelector(e)&&(n=!0)):Ce.isZeroWidthJoiner(e)&&(n=!0,o=!0),n?(i[i.length-1]+=h,n=!1):i.push(h),a+=h.length;return i},vs.prototype.completeTextData=function(t){t.__complete=!0;var e,s,i,a,r,n,o,h=this.elem.globalData.fontManager,l=this.data,p=[],f=0,c=l.m.g,d=0,m=0,u=0,g=[],y=0,v=0,b=h.getFontByName(t.f),_=0,C=_e(b);t.fWeight=C.weight,t.fStyle=C.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),s=t.finalText.length,t.finalLineHeight=t.lh;var x,k=t.tr/1e3*t.finalSize;if(t.sz)for(var S,P,D=!0,w=t.sz[0],A=t.sz[1];D;){S=0,y=0,s=(P=this.buildFinalText(t.t)).length,k=t.tr/1e3*t.finalSize;var M=-1;for(e=0;e<s;e+=1)x=P[e].charCodeAt(0),i=!1," "===P[e]?M=e:13!==x&&3!==x||(y=0,i=!0,S+=t.finalLineHeight||1.2*t.finalSize),h.chars?(o=h.getCharData(P[e],b.fStyle,b.fFamily),_=i?0:o.w*t.finalSize/100):_=h.measureText(P[e],t.f,t.finalSize),y+_>w&&" "!==P[e]?(-1===M?s+=1:e=M,S+=t.finalLineHeight||1.2*t.finalSize,P.splice(e,M===e?1:0,"\r"),M=-1,y=0):(y+=_,y+=k);S+=b.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&A<S?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=P,s=t.finalText.length,D=!1)}y=-k,_=0;var T,F=0;for(e=0;e<s;e+=1)if(i=!1,13===(x=(T=t.finalText[e]).charCodeAt(0))||3===x?(F=0,g.push(y),v=y>v?y:v,y=-2*k,a="",i=!0,u+=1):a=T,h.chars?(o=h.getCharData(T,b.fStyle,h.getFontByName(t.f).fFamily),_=i?0:o.w*t.finalSize/100):_=h.measureText(a,t.f,t.finalSize)," "===T?F+=_+k:(y+=_+k+F,F=0),p.push({l:_,an:_,add:d,n:i,anIndexes:[],val:a,line:u,animatorJustifyOffset:0}),2==c){if(d+=_,""===a||" "===a||e===s-1){for(""!==a&&" "!==a||(d-=_);m<=e;)p[m].an=d,p[m].ind=f,p[m].extra=_,m+=1;f+=1,d=0}}else if(3==c){if(d+=_,""===a||e===s-1){for(""===a&&(d-=_);m<=e;)p[m].an=d,p[m].ind=f,p[m].extra=_,m+=1;d=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=y>v?y:v,g.push(y),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=g;var E,L,I,R,V=l.a;n=V.length;var z=[];for(r=0;r<n;r+=1){for((E=V[r]).a.sc&&(t.strokeColorAnim=!0),E.a.sw&&(t.strokeWidthAnim=!0),(E.a.fc||E.a.fh||E.a.fs||E.a.fb)&&(t.fillColorAnim=!0),R=0,I=E.s.b,e=0;e<s;e+=1)(L=p[e]).anIndexes[r]=R,(1==I&&""!==L.val||2==I&&""!==L.val&&" "!==L.val||3==I&&(L.n||" "==L.val||e==s-1)||4==I&&(L.n||e==s-1))&&(1===E.s.rn&&z.push(R),R+=1);l.a[r].s.totalChars=R;var O,N=-1;if(1===E.s.rn)for(e=0;e<s;e+=1)N!=(L=p[e]).anIndexes[r]&&(N=L.anIndexes[r],O=z.splice(Math.floor(Math.random()*z.length),1)[0]),L.anIndexes[r]=O}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=b.ascent*t.finalSize/100},vs.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var s=this.copyData({},this.data.d.k[e].s);s=this.copyData(s,t),this.data.d.k[e].s=s,this.recalculate(e),this.setCurrentData(s),this.elem.addDynamicProperty(this)},vs.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},vs.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},vs.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var bs=function(){var t=Math.max,e=Math.min,s=Math.floor;function i(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=vt.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?vt.getProp(t,e.e,0,0,this):{v:100},this.o=vt.getProp(t,e.o||{k:0},0,0,this),this.xe=vt.getProp(t,e.xe||{k:0},0,0,this),this.ne=vt.getProp(t,e.ne||{k:0},0,0,this),this.sm=vt.getProp(t,e.sm||{k:100},0,0,this),this.a=vt.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return i.prototype={getMult:function(i){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var a=0,r=0,n=1,o=1;this.ne.v>0?a=this.ne.v/100:r=-this.ne.v/100,this.xe.v>0?n=1-this.xe.v/100:o=1+this.xe.v/100;var h=tt.getBezierEasing(a,r,n,o).get,l=0,p=this.finalS,f=this.finalE,c=this.data.sh;if(2===c)l=h(l=f===p?i>=f?1:0:t(0,e(.5/(f-p)+(i-p)/(f-p),1)));else if(3===c)l=h(l=f===p?i>=f?0:1:1-t(0,e(.5/(f-p)+(i-p)/(f-p),1)));else if(4===c)f===p?l=0:(l=t(0,e(.5/(f-p)+(i-p)/(f-p),1)))<.5?l*=2:l=1-2*(l-.5),l=h(l);else if(5===c){if(f===p)l=0;else{var d=f-p,m=-d/2+(i=e(t(0,i+.5-p),f-p)),u=d/2;l=Math.sqrt(1-m*m/(u*u))}l=h(l)}else 6===c?(f===p?l=0:(i=e(t(0,i+.5-p),f-p),l=(1+Math.cos(Math.PI+2*Math.PI*i/(f-p)))/2),l=h(l)):(i>=s(p)&&(l=t(0,e(i-p<0?e(f,1)-(p-i):f-i,1))),l=h(l));if(100!==this.sm.v){var g=.01*this.sm.v;0===g&&(g=1e-8);var y=.5-.5*g;l<y?l=0:(l=(l-y)/g)>1&&(l=1)}return l*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,s=this.o.v/e,i=this.s.v/e+s,a=this.e.v/e+s;if(i>a){var r=i;i=a,a=r}this.finalS=i,this.finalE=a}},r([bt],i),{getTextSelectorProp:function(t,e,s){return new i(t,e,s)}}}();function _s(t,e,s){var i={propType:!1},a=vt.getProp,r=e.a;this.a={r:r.r?a(t,r.r,0,x,s):i,rx:r.rx?a(t,r.rx,0,x,s):i,ry:r.ry?a(t,r.ry,0,x,s):i,sk:r.sk?a(t,r.sk,0,x,s):i,sa:r.sa?a(t,r.sa,0,x,s):i,s:r.s?a(t,r.s,1,.01,s):i,a:r.a?a(t,r.a,1,0,s):i,o:r.o?a(t,r.o,0,.01,s):i,p:r.p?a(t,r.p,1,0,s):i,sw:r.sw?a(t,r.sw,0,0,s):i,sc:r.sc?a(t,r.sc,1,0,s):i,fc:r.fc?a(t,r.fc,1,0,s):i,fh:r.fh?a(t,r.fh,0,0,s):i,fs:r.fs?a(t,r.fs,0,.01,s):i,fb:r.fb?a(t,r.fb,0,.01,s):i,t:r.t?a(t,r.t,0,0,s):i},this.s=bs.getTextSelectorProp(t,e.s,s),this.s.t=e.s.t}function Cs(t,e,s){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=s,this._animatorsData=l(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(s)}function xs(){}Cs.prototype.searchProperties=function(){var t,e,s=this._textData.a.length,i=vt.getProp;for(t=0;t<s;t+=1)e=this._textData.a[t],this._animatorsData[t]=new _s(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:i(this._elem,this._textData.p.a,0,0,this),f:i(this._elem,this._textData.p.f,0,0,this),l:i(this._elem,this._textData.p.l,0,0,this),r:i(this._elem,this._textData.p.r,0,0,this),p:i(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=i(this._elem,this._textData.m.a,1,0,this)},Cs.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var s,i,a,r,n,o,h,l,p,f,c,d,m,u,g,y,v,b,_,C=this._moreOptions.alignment.v,x=this._animatorsData,k=this._textData,S=this.mHelper,P=this._renderType,D=this.renderedLetters.length,w=t.l;if(this._hasMaskedPath){if(_=this._pathData.m,!this._pathData.n||this._pathData._mdf){var A,M=_.v;for(this._pathData.r.v&&(M=M.reverse()),n={tLength:0,segments:[]},r=M._length-1,y=0,a=0;a<r;a+=1)A=rt.buildBezierData(M.v[a],M.v[a+1],[M.o[a][0]-M.v[a][0],M.o[a][1]-M.v[a][1]],[M.i[a+1][0]-M.v[a+1][0],M.i[a+1][1]-M.v[a+1][1]]),n.tLength+=A.segmentLength,n.segments.push(A),y+=A.segmentLength;a=r,_.v.c&&(A=rt.buildBezierData(M.v[a],M.v[0],[M.o[a][0]-M.v[a][0],M.o[a][1]-M.v[a][1]],[M.i[0][0]-M.v[0][0],M.i[0][1]-M.v[0][1]]),n.tLength+=A.segmentLength,n.segments.push(A),y+=A.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,c=0,f=1,l=0,p=!0,u=n.segments,o<0&&_.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),f=(m=u[c=u.length-1].points).length-1;o<0;)o+=m[f].partialLength,(f-=1)<0&&(f=(m=u[c-=1].points).length-1);d=(m=u[c].points)[f-1],g=(h=m[f]).partialLength}r=w.length,s=0,i=0;var T,F,E,L,I,R=1.2*t.finalSize*.714,N=!0;E=x.length;var q,B,W,j,Y,J,H,G,X,K,U,Z,Q=-1,$=o,tt=c,et=f,st=-1,it="",at=this.defaultPropsArray;if(2===t.j||1===t.j){var nt=0,ot=0,ht=2===t.j?-.5:-1,lt=0,pt=!0;for(a=0;a<r;a+=1)if(w[a].n){for(nt&&(nt+=ot);lt<a;)w[lt].animatorJustifyOffset=nt,lt+=1;nt=0,pt=!0}else{for(F=0;F<E;F+=1)(T=x[F].a).t.propType&&(pt&&2===t.j&&(ot+=T.t.v*ht),(I=x[F].s.getMult(w[a].anIndexes[F],k.a[F].s.totalChars)).length?nt+=T.t.v*I[0]*ht:nt+=T.t.v*I*ht);pt=!1}for(nt&&(nt+=ot);lt<a;)w[lt].animatorJustifyOffset=nt,lt+=1}for(a=0;a<r;a+=1){if(S.reset(),j=1,w[a].n)s=0,i+=t.yOffset,i+=N?1:0,o=$,N=!1,this._hasMaskedPath&&(f=et,d=(m=u[c=tt].points)[f-1],g=(h=m[f]).partialLength,l=0),it="",U="",X="",Z="",at=this.defaultPropsArray;else{if(this._hasMaskedPath){if(st!==w[a].line){switch(t.j){case 1:o+=y-t.lineWidths[w[a].line];break;case 2:o+=(y-t.lineWidths[w[a].line])/2}st=w[a].line}Q!==w[a].ind&&(w[Q]&&(o+=w[Q].extra),o+=w[a].an/2,Q=w[a].ind),o+=C[0]*w[a].an*.005;var ft=0;for(F=0;F<E;F+=1)(T=x[F].a).p.propType&&((I=x[F].s.getMult(w[a].anIndexes[F],k.a[F].s.totalChars)).length?ft+=T.p.v[0]*I[0]:ft+=T.p.v[0]*I),T.a.propType&&((I=x[F].s.getMult(w[a].anIndexes[F],k.a[F].s.totalChars)).length?ft+=T.a.v[0]*I[0]:ft+=T.a.v[0]*I);for(p=!0,this._pathData.a.v&&(o=.5*w[0].an+(y-this._pathData.f.v-.5*w[0].an-.5*w[w.length-1].an)*Q/(r-1),o+=this._pathData.f.v);p;)l+g>=o+ft||!m?(v=(o+ft-l)/h.partialLength,B=d.point[0]+(h.point[0]-d.point[0])*v,W=d.point[1]+(h.point[1]-d.point[1])*v,S.translate(-C[0]*w[a].an*.005,-C[1]*R*.01),p=!1):m&&(l+=h.partialLength,(f+=1)>=m.length&&(f=0,u[c+=1]?m=u[c].points:_.v.c?(f=0,m=u[c=0].points):(l-=h.partialLength,m=null)),m&&(d=h,g=(h=m[f]).partialLength));q=w[a].an/2-w[a].add,S.translate(-q,0,0)}else q=w[a].an/2-w[a].add,S.translate(-q,0,0),S.translate(-C[0]*w[a].an*.005,-C[1]*R*.01,0);for(F=0;F<E;F+=1)(T=x[F].a).t.propType&&(I=x[F].s.getMult(w[a].anIndexes[F],k.a[F].s.totalChars),0===s&&0===t.j||(this._hasMaskedPath?I.length?o+=T.t.v*I[0]:o+=T.t.v*I:I.length?s+=T.t.v*I[0]:s+=T.t.v*I));for(t.strokeWidthAnim&&(J=t.sw||0),t.strokeColorAnim&&(Y=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(H=[t.fc[0],t.fc[1],t.fc[2]]),F=0;F<E;F+=1)(T=x[F].a).a.propType&&((I=x[F].s.getMult(w[a].anIndexes[F],k.a[F].s.totalChars)).length?S.translate(-T.a.v[0]*I[0],-T.a.v[1]*I[1],T.a.v[2]*I[2]):S.translate(-T.a.v[0]*I,-T.a.v[1]*I,T.a.v[2]*I));for(F=0;F<E;F+=1)(T=x[F].a).s.propType&&((I=x[F].s.getMult(w[a].anIndexes[F],k.a[F].s.totalChars)).length?S.scale(1+(T.s.v[0]-1)*I[0],1+(T.s.v[1]-1)*I[1],1):S.scale(1+(T.s.v[0]-1)*I,1+(T.s.v[1]-1)*I,1));for(F=0;F<E;F+=1){if(T=x[F].a,I=x[F].s.getMult(w[a].anIndexes[F],k.a[F].s.totalChars),T.sk.propType&&(I.length?S.skewFromAxis(-T.sk.v*I[0],T.sa.v*I[1]):S.skewFromAxis(-T.sk.v*I,T.sa.v*I)),T.r.propType&&(I.length?S.rotateZ(-T.r.v*I[2]):S.rotateZ(-T.r.v*I)),T.ry.propType&&(I.length?S.rotateY(T.ry.v*I[1]):S.rotateY(T.ry.v*I)),T.rx.propType&&(I.length?S.rotateX(T.rx.v*I[0]):S.rotateX(T.rx.v*I)),T.o.propType&&(I.length?j+=(T.o.v*I[0]-j)*I[0]:j+=(T.o.v*I-j)*I),t.strokeWidthAnim&&T.sw.propType&&(I.length?J+=T.sw.v*I[0]:J+=T.sw.v*I),t.strokeColorAnim&&T.sc.propType)for(G=0;G<3;G+=1)I.length?Y[G]+=(T.sc.v[G]-Y[G])*I[0]:Y[G]+=(T.sc.v[G]-Y[G])*I;if(t.fillColorAnim&&t.fc){if(T.fc.propType)for(G=0;G<3;G+=1)I.length?H[G]+=(T.fc.v[G]-H[G])*I[0]:H[G]+=(T.fc.v[G]-H[G])*I;T.fh.propType&&(H=I.length?O(H,T.fh.v*I[0]):O(H,T.fh.v*I)),T.fs.propType&&(H=I.length?V(H,T.fs.v*I[0]):V(H,T.fs.v*I)),T.fb.propType&&(H=I.length?z(H,T.fb.v*I[0]):z(H,T.fb.v*I))}}for(F=0;F<E;F+=1)(T=x[F].a).p.propType&&(I=x[F].s.getMult(w[a].anIndexes[F],k.a[F].s.totalChars),this._hasMaskedPath?I.length?S.translate(0,T.p.v[1]*I[0],-T.p.v[2]*I[1]):S.translate(0,T.p.v[1]*I,-T.p.v[2]*I):I.length?S.translate(T.p.v[0]*I[0],T.p.v[1]*I[1],-T.p.v[2]*I[2]):S.translate(T.p.v[0]*I,T.p.v[1]*I,-T.p.v[2]*I));if(t.strokeWidthAnim&&(X=J<0?0:J),t.strokeColorAnim&&(K="rgb("+Math.round(255*Y[0])+","+Math.round(255*Y[1])+","+Math.round(255*Y[2])+")"),t.fillColorAnim&&t.fc&&(U="rgb("+Math.round(255*H[0])+","+Math.round(255*H[1])+","+Math.round(255*H[2])+")"),this._hasMaskedPath){if(S.translate(0,-t.ls),S.translate(0,C[1]*R*.01+i,0),this._pathData.p.v){b=(h.point[1]-d.point[1])/(h.point[0]-d.point[0]);var ct=180*Math.atan(b)/Math.PI;h.point[0]<d.point[0]&&(ct+=180),S.rotate(-ct*Math.PI/180)}S.translate(B,W,0),o-=C[0]*w[a].an*.005,w[a+1]&&Q!==w[a+1].ind&&(o+=w[a].an/2,o+=.001*t.tr*t.finalSize)}else{switch(S.translate(s,i,0),t.ps&&S.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:S.translate(w[a].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[w[a].line]),0,0);break;case 2:S.translate(w[a].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[w[a].line])/2,0,0)}S.translate(0,-t.ls),S.translate(q,0,0),S.translate(C[0]*w[a].an*.005,C[1]*R*.01,0),s+=w[a].l+.001*t.tr*t.finalSize}"html"===P?it=S.toCSS():"svg"===P?it=S.to2dCSS():at=[S.props[0],S.props[1],S.props[2],S.props[3],S.props[4],S.props[5],S.props[6],S.props[7],S.props[8],S.props[9],S.props[10],S.props[11],S.props[12],S.props[13],S.props[14],S.props[15]],Z=j}D<=a?(L=new ys(Z,X,K,U,it,at),this.renderedLetters.push(L),D+=1,this.lettersChangedFlag=!0):(L=this.renderedLetters[a],this.lettersChangedFlag=L.update(Z,X,K,U,it,at)||this.lettersChangedFlag)}}},Cs.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},Cs.prototype.mHelper=new Ft,Cs.prototype.defaultPropsArray=[],r([bt],Cs),xs.prototype.initElement=function(t,e,s){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,s),this.textProperty=new vs(this,t.t,this.dynamicProperties),this.textAnimator=new Cs(t.t,this.renderType,this),this.initTransform(t,e,s),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},xs.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},xs.prototype.createPathShape=function(t,e){var s,i,a=e.length,r="";for(s=0;s<a;s+=1)"sh"===e[s].ty&&(i=e[s].ks.k,r+=ms(i,i.i.length,!0,t));return r},xs.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},xs.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},xs.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},xs.prototype.applyTextPropertiesToMatrix=function(t,e,s,i,a){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[s]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[s])/2,0,0)}e.translate(i,a,0)},xs.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},xs.prototype.emptyProp=new ys,xs.prototype.destroy=function(){},xs.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var ks={shapes:[]};function Ss(t,e,s){this.textSpans=[],this.renderType="svg",this.initElement(t,e,s)}function Ps(t,e,s){this.initElement(t,e,s)}function Ds(t,e,s){this.initFrame(),this.initBaseData(t,e,s),this.initFrame(),this.initTransform(t,e,s),this.initHierarchy()}function ws(){}function As(){}function Ms(t,e,s){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?l(this.layers.length):[],this.initElement(t,e,s),this.tm=t.tm?vt.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function Ts(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=j("svg");var s="";if(e&&e.title){var i=j("title"),a=L();i.setAttribute("id",a),i.textContent=e.title,this.svgElement.appendChild(i),s+=a}if(e&&e.description){var r=j("desc"),n=L();r.setAttribute("id",n),r.textContent=e.description,this.svgElement.appendChild(r),s+=" "+n}s&&this.svgElement.setAttribute("aria-labelledby",s);var o=j("defs");this.svgElement.appendChild(o);var h=j("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}function Fs(){this.sequences={},this.sequenceList=[],this.transform_key_count=0}r([Ve,We,Ke,Ue,ze,Ze,xs],Ss),Ss.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=j("text"))},Ss.prototype.buildTextContents=function(t){for(var e=0,s=t.length,i=[],a="";e<s;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(i.push(a),a=""):a+=t[e],e+=1;return i.push(a),i},Ss.prototype.buildShapeData=function(t,e){if(t.shapes&&t.shapes.length){var s=t.shapes[0];if(s.it){var i=s.it[s.it.length-1];i.s&&(i.s.k[0]=e,i.s.k[1]=e)}}return t},Ss.prototype.buildNewText=function(){var t,e;this.addDynamicProperty(this);var s=this.textProperty.currentData;this.renderedLetters=l(s?s.l.length:0),s.fc?this.layerElement.setAttribute("fill",this.buildColor(s.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),s.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(s.sc)),this.layerElement.setAttribute("stroke-width",s.sw)),this.layerElement.setAttribute("font-size",s.finalSize);var i=this.globalData.fontManager.getFontByName(s.f);if(i.fClass)this.layerElement.setAttribute("class",i.fClass);else{this.layerElement.setAttribute("font-family",i.fFamily);var a=s.fWeight,r=s.fStyle;this.layerElement.setAttribute("font-style",r),this.layerElement.setAttribute("font-weight",a)}this.layerElement.setAttribute("aria-label",s.t);var n,o=s.l||[],h=!!this.globalData.fontManager.chars;e=o.length;var p=this.mHelper,f=this.data.singleShape,c=0,d=0,m=!0,u=.001*s.tr*s.finalSize;if(!f||h||s.sz){var g,y=this.textSpans.length;for(t=0;t<e;t+=1){if(this.textSpans[t]||(this.textSpans[t]={span:null,childSpan:null,glyph:null}),!h||!f||0===t){if(n=y>t?this.textSpans[t].span:j(h?"g":"text"),y<=t){if(n.setAttribute("stroke-linecap","butt"),n.setAttribute("stroke-linejoin","round"),n.setAttribute("stroke-miterlimit","4"),this.textSpans[t].span=n,h){var v=j("g");n.appendChild(v),this.textSpans[t].childSpan=v}this.textSpans[t].span=n,this.layerElement.appendChild(n)}n.style.display="inherit"}if(p.reset(),f&&(o[t].n&&(c=-u,d+=s.yOffset,d+=m?1:0,m=!1),this.applyTextPropertiesToMatrix(s,p,o[t].line,c,d),c+=o[t].l||0,c+=u),h){var b;if(1===(g=this.globalData.fontManager.getCharData(s.finalText[t],i.fStyle,this.globalData.fontManager.getFontByName(s.f).fFamily)).t)b=new Ms(g.data,this.globalData,this);else{var _=ks;g.data&&g.data.shapes&&(_=this.buildShapeData(g.data,s.finalSize)),b=new gs(_,this.globalData,this)}if(this.textSpans[t].glyph){var C=this.textSpans[t].glyph;this.textSpans[t].childSpan.removeChild(C.layerElement),C.destroy()}this.textSpans[t].glyph=b,b._debug=!0,b.prepareFrame(0),b.renderFrame(),this.textSpans[t].childSpan.appendChild(b.layerElement),1===g.t&&this.textSpans[t].childSpan.setAttribute("transform","scale("+s.finalSize/100+","+s.finalSize/100+")")}else f&&n.setAttribute("transform","translate("+p.props[12]+","+p.props[13]+")"),n.textContent=o[t].val,n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}f&&n&&n.setAttribute("d","")}else{var x=this.textContainer,k="start";switch(s.j){case 1:k="end";break;case 2:k="middle";break;default:k="start"}x.setAttribute("text-anchor",k),x.setAttribute("letter-spacing",u);var S=this.buildTextContents(s.finalText);for(e=S.length,d=s.ps?s.ps[1]+s.ascent:0,t=0;t<e;t+=1)(n=this.textSpans[t].span||j("tspan")).textContent=S[t],n.setAttribute("x",0),n.setAttribute("y",d),n.style.display="inherit",x.appendChild(n),this.textSpans[t]||(this.textSpans[t]={span:null,glyph:null}),this.textSpans[t].span=n,d+=s.finalLineHeight;this.layerElement.appendChild(x)}for(;t<this.textSpans.length;)this.textSpans[t].span.style.display="none",t+=1;this._sizeChanged=!0},Ss.prototype.sourceRectAtTime=function(){if(this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged){this._sizeChanged=!1;var t=this.layerElement.getBBox();this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}}return this.bbox},Ss.prototype.getValue=function(){var t,e,s=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<s;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf&&(this._mdf=!0))},Ss.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){var t,e;this._sizeChanged=!0;var s,i,a,r=this.textAnimator.renderedLetters,n=this.textProperty.currentData.l;for(e=n.length,t=0;t<e;t+=1)n[t].n||(s=r[t],i=this.textSpans[t].span,(a=this.textSpans[t].glyph)&&a.renderFrame(),s._mdf.m&&i.setAttribute("transform",s.m),s._mdf.o&&i.setAttribute("opacity",s.o),s._mdf.sw&&i.setAttribute("stroke-width",s.sw),s._mdf.sc&&i.setAttribute("stroke",s.sc),s._mdf.fc&&i.setAttribute("fill",s.fc))}},r([Qe],Ps),Ps.prototype.createContent=function(){var t=j("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},Ds.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},Ds.prototype.renderFrame=function(){},Ds.prototype.getBaseElement=function(){return null},Ds.prototype.destroy=function(){},Ds.prototype.sourceRectAtTime=function(){},Ds.prototype.hide=function(){},r([Ve,We,Ue,ze],Ds),r([qe],ws),ws.prototype.createNull=function(t){return new Ds(t,this.globalData,this)},ws.prototype.createShape=function(t){return new gs(t,this.globalData,this)},ws.prototype.createText=function(t){return new Ss(t,this.globalData,this)},ws.prototype.createImage=function(t){return new Qe(t,this.globalData,this)},ws.prototype.createSolid=function(t){return new Ps(t,this.globalData,this)},ws.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var s=j("clipPath"),a=j("rect");a.setAttribute("width",t.w),a.setAttribute("height",t.h),a.setAttribute("x",0),a.setAttribute("y",0);var r=L();s.setAttribute("id",r),s.appendChild(a),this.layerElement.setAttribute("clip-path","url("+i()+"#"+r+")"),e.appendChild(s),this.layers=t.layers,this.elements=l(t.layers.length)},ws.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},ws.prototype.updateContainerSize=function(){},ws.prototype.findIndexByInd=function(t){var e=0,s=this.layers.length;for(e=0;e<s;e+=1)if(this.layers[e].ind===t)return e;return-1},ws.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){e[t]=!0;var s=this.createItem(this.layers[t]);if(e[t]=s,N()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(s),s.initExpressions()),this.appendElementInPos(s,t),this.layers[t].tt){var i="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1;if(-1===i)return;if(this.elements[i]&&!0!==this.elements[i]){var a=e[i].getMatte(this.layers[t].tt);s.setMatte(a)}else this.buildItem(i),this.addPendingElement(s)}}},ws.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,s=this.elements.length;e<s;){if(this.elements[e]===t){var i="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,a=this.elements[i].getMatte(this.layers[e].tt);t.setMatte(a);break}e+=1}}},ws.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){var e;null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var s=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=s-1;e>=0;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<s;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},ws.prototype.appendElementInPos=function(t,e){var s=t.getBaseElement();if(s){for(var i,a=0;a<e;)this.elements[a]&&!0!==this.elements[a]&&this.elements[a].getBaseElement()&&(i=this.elements[a].getBaseElement()),a+=1;i?this.layerElement.insertBefore(s,i):this.layerElement.appendChild(s)}},ws.prototype.hide=function(){this.layerElement.style.display="none"},ws.prototype.show=function(){this.layerElement.style.display="block"},r([Ve,We,Ue,ze,Ze],As),As.prototype.initElement=function(t,e,s){this.initFrame(),this.initBaseData(t,e,s),this.initTransform(t,e,s),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},As.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var s,i=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),s=i-1;s>=0;s-=1)(this.completeLayers||this.elements[s])&&(this.elements[s].prepareFrame(this.renderedFrame-this.layers[s].st),this.elements[s]._mdf&&(this._mdf=!0))}},As.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},As.prototype.setElements=function(t){this.elements=t},As.prototype.getElements=function(){return this.elements},As.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},As.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},r([ws,As,Ke],Ms),Ms.prototype.createComp=function(t){return new Ms(t,this.globalData,this)},r([ws],Ts),Ts.prototype.createComp=function(t){return new Ms(t,this.globalData,this)},Fs.prototype={addTransformSequence:function(t){var e,s=t.length,i="_";for(e=0;e<s;e+=1)i+=t[e].transform.key+"_";var a=this.sequences[i];return a||(a={transforms:[].concat(t),finalTransform:new Ft,_mdf:!1},this.sequences[i]=a,this.sequenceList.push(a)),a},processSequence:function(t,e){for(var s=0,i=t.transforms.length,a=e;s<i&&!e;){if(t.transforms[s].transform.mProps._mdf){a=!0;break}s+=1}if(a)for(t.finalTransform.reset(),s=i-1;s>=0;s-=1)t.finalTransform.multiply(t.transforms[s].transform.mProps.v);t._mdf=a},processSequences:function(t){var e,s=this.sequenceList.length;for(e=0;e<s;e+=1)this.processSequence(this.sequenceList[e],t)},getNewKey:function(){return this.transform_key_count+=1,"_"+this.transform_key_count}};var Es=function(){var t="__lottie_element_luma_buffer",e=null,s=null,i=null;function r(){var r,n,o;e||(r=j("svg"),n=j("filter"),o=j("feColorMatrix"),n.setAttribute("id",t),o.setAttribute("type","matrix"),o.setAttribute("color-interpolation-filters","sRGB"),o.setAttribute("values","0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0"),n.appendChild(o),r.appendChild(n),r.setAttribute("id",t+"_svg"),Je.svgLumaHidden&&(r.style.display="none"),i=r,document.body.appendChild(i),e=a("canvas"),(s=e.getContext("2d")).filter="url(#"+t+")",s.fillStyle="rgba(0,0,0,0)",s.fillRect(0,0,1,1))}return{load:r,get:function(i){return e||r(),e.width=i.width,e.height=i.height,s.filter="url(#"+t+")",e}}};function Ls(t,e){if(Je.offscreenCanvas)return new OffscreenCanvas(t,e);var s=a("canvas");return s.width=t,s.height=e,s}var Is={loadLumaCanvas:Es.load,getLumaCanvas:Es.get,createCanvas:Ls},Rs={};function Vs(t){var e,s,i=t.data.ef?t.data.ef.length:0;for(this.filters=[],e=0;e<i;e+=1){s=null;var a=t.data.ef[e].ty;if(Rs[a])s=new(0,Rs[a].effect)(t.effectsManager.effectElements[e],t);s&&this.filters.push(s)}this.filters.length&&t.addRenderableComponent(this)}function zs(t,e){var s;this.data=t,this.element=e,this.masksProperties=this.data.masksProperties||[],this.viewData=l(this.masksProperties.length);var i=this.masksProperties.length,a=!1;for(s=0;s<i;s+=1)"n"!==this.masksProperties[s].mode&&(a=!0),this.viewData[s]=Tt.getShapeProp(this.element,this.masksProperties[s],3);this.hasMasks=a,a&&this.element.addRenderableComponent(this)}function Os(){}Vs.prototype.renderFrame=function(t){var e,s=this.filters.length;for(e=0;e<s;e+=1)this.filters[e].renderFrame(t)},Vs.prototype.getEffects=function(t){var e,s=this.filters.length,i=[];for(e=0;e<s;e+=1)this.filters[e].type===t&&i.push(this.filters[e]);return i},zs.prototype.renderFrame=function(){if(this.hasMasks){var t,e,s,i,a=this.element.finalTransform.mat,r=this.element.canvasContext,n=this.masksProperties.length;for(r.beginPath(),t=0;t<n;t+=1)if("n"!==this.masksProperties[t].mode){var o;this.masksProperties[t].inv&&(r.moveTo(0,0),r.lineTo(this.element.globalData.compSize.w,0),r.lineTo(this.element.globalData.compSize.w,this.element.globalData.compSize.h),r.lineTo(0,this.element.globalData.compSize.h),r.lineTo(0,0)),i=this.viewData[t].v,e=a.applyToPointArray(i.v[0][0],i.v[0][1],0),r.moveTo(e[0],e[1]);var h=i._length;for(o=1;o<h;o+=1)s=a.applyToTriplePoints(i.o[o-1],i.i[o],i.v[o]),r.bezierCurveTo(s[0],s[1],s[2],s[3],s[4],s[5]);s=a.applyToTriplePoints(i.o[o-1],i.i[0],i.v[0]),r.bezierCurveTo(s[0],s[1],s[2],s[3],s[4],s[5])}this.element.globalData.renderer.save(!0),r.clip()}},zs.prototype.getMaskProperty=je.prototype.getMaskProperty,zs.prototype.destroy=function(){this.element=null};var Ns,qs={1:"source-in",2:"source-out",3:"source-in",4:"source-out"};function Bs(t,e,s,i){this.styledShapes=[],this.tr=[0,0,0,0,0,0];var a,r=4;"rc"===e.ty?r=5:"el"===e.ty?r=6:"sr"===e.ty&&(r=7),this.sh=Tt.getShapeProp(t,e,r,t);var n,o=s.length;for(a=0;a<o;a+=1)s[a].closed||(n={transforms:i.addTransformSequence(s[a].transforms),trNodes:[]},this.styledShapes.push(n),s[a].elements.push(n))}function Ws(t,e,s){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.itemsData=[],this.prevViewData=[],this.shapeModifiers=[],this.processedElements=[],this.transformsManager=new Fs,this.initElement(t,e,s)}function js(t,e,s){this.textSpans=[],this.yOffset=0,this.fillColorAnim=!1,this.strokeColorAnim=!1,this.strokeWidthAnim=!1,this.stroke=!1,this.fill=!1,this.justifyOffset=0,this.currentRender=null,this.renderType="canvas",this.values={fill:"rgba(0,0,0,0)",stroke:"rgba(0,0,0,0)",sWidth:0,fValue:""},this.initElement(t,e,s)}function Ys(t,e,s){this.assetData=e.getAssetData(t.refId),this.img=e.imageLoader.getAsset(this.assetData),this.initElement(t,e,s)}function Js(t,e,s){this.initElement(t,e,s)}function Hs(){}function Gs(){this.opacity=-1,this.transform=h("float32",16),this.fillStyle="",this.strokeStyle="",this.lineWidth="",this.lineCap="",this.lineJoin="",this.miterLimit="",this.id=Math.random()}function Xs(){var t;this.stack=[],this.cArrPos=0,this.cTr=new Ft;for(t=0;t<15;t+=1){var e=new Gs;this.stack[t]=e}this._length=15,this.nativeContext=null,this.transformMat=new Ft,this.currentOpacity=1,this.currentFillStyle="",this.appliedFillStyle="",this.currentStrokeStyle="",this.appliedStrokeStyle="",this.currentLineWidth="",this.appliedLineWidth="",this.currentLineCap="",this.appliedLineCap="",this.currentLineJoin="",this.appliedLineJoin="",this.appliedMiterLimit="",this.currentMiterLimit=""}function Ks(t,e,s){this.completeLayers=!1,this.layers=t.layers,this.pendingElements=[],this.elements=l(this.layers.length),this.initElement(t,e,s),this.tm=t.tm?vt.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function Us(t,e){this.animationItem=t,this.renderConfig={clearCanvas:!e||void 0===e.clearCanvas||e.clearCanvas,context:e&&e.context||null,progressiveLoad:e&&e.progressiveLoad||!1,preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",className:e&&e.className||"",id:e&&e.id||"",runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.renderConfig.dpr=e&&e.dpr||1,this.animationItem.wrapper&&(this.renderConfig.dpr=e&&e.dpr||window.devicePixelRatio||1),this.renderedFrame=-1,this.globalData={frameNum:-1,_mdf:!1,renderConfig:this.renderConfig,currentGlobalAlpha:-1},this.contextData=new Xs,this.elements=[],this.pendingElements=[],this.transformMat=new Ft,this.completeLayers=!1,this.rendererType="canvas",this.renderConfig.clearCanvas&&(this.ctxTransform=this.contextData.transform.bind(this.contextData),this.ctxOpacity=this.contextData.opacity.bind(this.contextData),this.ctxFillStyle=this.contextData.fillStyle.bind(this.contextData),this.ctxStrokeStyle=this.contextData.strokeStyle.bind(this.contextData),this.ctxLineWidth=this.contextData.lineWidth.bind(this.contextData),this.ctxLineCap=this.contextData.lineCap.bind(this.contextData),this.ctxLineJoin=this.contextData.lineJoin.bind(this.contextData),this.ctxMiterLimit=this.contextData.miterLimit.bind(this.contextData),this.ctxFill=this.contextData.fill.bind(this.contextData),this.ctxFillRect=this.contextData.fillRect.bind(this.contextData),this.ctxStroke=this.contextData.stroke.bind(this.contextData),this.save=this.contextData.save.bind(this.contextData))}return Os.prototype={createElements:function(){},initRendererElement:function(){},createContainerElements:function(){if(this.data.tt>=1){this.buffers=[];var t=this.globalData.canvasContext,e=Is.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(e);var s=Is.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(s),this.data.tt>=3&&!document._isProxy&&Is.loadLumaCanvas()}this.canvasContext=this.globalData.canvasContext,this.transformCanvas=this.globalData.transformCanvas,this.renderableEffectsManager=new Vs(this),this.searchEffectTransforms()},createContent:function(){},setBlendMode:function(){var t=this.globalData;if(t.blendMode!==this.data.bm){t.blendMode=this.data.bm;var e=Pe(this.data.bm);t.canvasContext.globalCompositeOperation=e}},createRenderableComponents:function(){this.maskManager=new zs(this.data,this),this.transformEffects=this.renderableEffectsManager.getEffects(Be)},hideElement:function(){this.hidden||this.isInRange&&!this.isTransparent||(this.hidden=!0)},showElement:function(){this.isInRange&&!this.isTransparent&&(this.hidden=!1,this._isFirstFrame=!0,this.maskManager._isFirstFrame=!0)},clearCanvas:function(t){t.clearRect(this.transformCanvas.tx,this.transformCanvas.ty,this.transformCanvas.w*this.transformCanvas.sx,this.transformCanvas.h*this.transformCanvas.sy)},prepareLayer:function(){if(this.data.tt>=1){var t=this.buffers[0].getContext("2d");this.clearCanvas(t),t.drawImage(this.canvasContext.canvas,0,0),this.currentTransform=this.canvasContext.getTransform(),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform)}},exitLayer:function(){if(this.data.tt>=1){var t=this.buffers[1],e=t.getContext("2d");if(this.clearCanvas(e),e.drawImage(this.canvasContext.canvas,0,0),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform),this.comp.getElementById("tp"in this.data?this.data.tp:this.data.ind-1).renderFrame(!0),this.canvasContext.setTransform(1,0,0,1,0,0),this.data.tt>=3&&!document._isProxy){var s=Is.getLumaCanvas(this.canvasContext.canvas);s.getContext("2d").drawImage(this.canvasContext.canvas,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.drawImage(s,0,0)}this.canvasContext.globalCompositeOperation=qs[this.data.tt],this.canvasContext.drawImage(t,0,0),this.canvasContext.globalCompositeOperation="destination-over",this.canvasContext.drawImage(this.buffers[0],0,0),this.canvasContext.setTransform(this.currentTransform),this.canvasContext.globalCompositeOperation="source-over"}},renderFrame:function(t){if(!this.hidden&&!this.data.hd&&(1!==this.data.td||t)){this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.setBlendMode();var e=0===this.data.ty;this.prepareLayer(),this.globalData.renderer.save(e),this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props),this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity),this.renderInnerContent(),this.globalData.renderer.restore(e),this.exitLayer(),this.maskManager.hasMasks&&this.globalData.renderer.restore(!0),this._isFirstFrame&&(this._isFirstFrame=!1)}},destroy:function(){this.canvasContext=null,this.data=null,this.globalData=null,this.maskManager.destroy()},mHelper:new Ft},Os.prototype.hide=Os.prototype.hideElement,Os.prototype.show=Os.prototype.showElement,Bs.prototype.setAsAnimated=is.prototype.setAsAnimated,r([Ve,We,Os,ts,Ue,ze,ke],Ws),Ws.prototype.initElement=Ze.prototype.initElement,Ws.prototype.transformHelper={opacity:1,_opMdf:!1},Ws.prototype.dashResetter=[],Ws.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[])},Ws.prototype.createStyleElement=function(t,e){var s={data:t,type:t.ty,preTransforms:this.transformsManager.addTransformSequence(e),transforms:[],elements:[],closed:!0===t.hd},i={};if("fl"===t.ty||"st"===t.ty?(i.c=vt.getProp(this,t.c,1,255,this),i.c.k||(s.co="rgb("+v(i.c.v[0])+","+v(i.c.v[1])+","+v(i.c.v[2])+")")):"gf"!==t.ty&&"gs"!==t.ty||(i.s=vt.getProp(this,t.s,1,null,this),i.e=vt.getProp(this,t.e,1,null,this),i.h=vt.getProp(this,t.h||{k:0},0,.01,this),i.a=vt.getProp(this,t.a||{k:0},0,x,this),i.g=new ls(this,t.g,this)),i.o=vt.getProp(this,t.o,0,.01,this),"st"===t.ty||"gs"===t.ty){if(s.lc=es[t.lc||2],s.lj=ss[t.lj||2],1==t.lj&&(s.ml=t.ml),i.w=vt.getProp(this,t.w,0,null,this),i.w.k||(s.wi=i.w.v),t.d){var a=new rs(this,t.d,"canvas",this);i.d=a,i.d.k||(s.da=i.d.dashArray,s.do=i.d.dashoffset[0])}}else s.r=2===t.r?"evenodd":"nonzero";return this.stylesList.push(s),i.style=s,i},Ws.prototype.createGroupElement=function(){return{it:[],prevViewData:[]}},Ws.prototype.createTransformElement=function(t){return{transform:{opacity:1,_opMdf:!1,key:this.transformsManager.getNewKey(),op:vt.getProp(this,t.o,0,.01,this),mProps:jt.getTransformProperty(this,t,this)}}},Ws.prototype.createShapeElement=function(t){var e=new Bs(this,t,this.stylesList,this.transformsManager);return this.shapes.push(e),this.addShapeToModifiers(e),e},Ws.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[]),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame)},Ws.prototype.addTransformToStyleList=function(t){var e,s=this.stylesList.length;for(e=0;e<s;e+=1)this.stylesList[e].closed||this.stylesList[e].transforms.push(t)},Ws.prototype.removeTransformFromStyleList=function(){var t,e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].closed||this.stylesList[t].transforms.pop()},Ws.prototype.closeStyles=function(t){var e,s=t.length;for(e=0;e<s;e+=1)t[e].closed=!0},Ws.prototype.searchShapes=function(t,e,s,i,a){var r,n,o,h,l,p,f=t.length-1,c=[],d=[],m=[].concat(a);for(r=f;r>=0;r-=1){if((h=this.searchProcessedElement(t[r]))?e[r]=s[h-1]:t[r]._shouldRender=i,"fl"===t[r].ty||"st"===t[r].ty||"gf"===t[r].ty||"gs"===t[r].ty)h?e[r].style.closed=!1:e[r]=this.createStyleElement(t[r],m),c.push(e[r].style);else if("gr"===t[r].ty){if(h)for(o=e[r].it.length,n=0;n<o;n+=1)e[r].prevViewData[n]=e[r].it[n];else e[r]=this.createGroupElement(t[r]);this.searchShapes(t[r].it,e[r].it,e[r].prevViewData,i,m)}else"tr"===t[r].ty?(h||(p=this.createTransformElement(t[r]),e[r]=p),m.push(e[r]),this.addTransformToStyleList(e[r])):"sh"===t[r].ty||"rc"===t[r].ty||"el"===t[r].ty||"sr"===t[r].ty?h||(e[r]=this.createShapeElement(t[r])):"tm"===t[r].ty||"rd"===t[r].ty||"pb"===t[r].ty||"zz"===t[r].ty||"op"===t[r].ty?(h?(l=e[r]).closed=!1:((l=Nt.getModifier(t[r].ty)).init(this,t[r]),e[r]=l,this.shapeModifiers.push(l)),d.push(l)):"rp"===t[r].ty&&(h?(l=e[r]).closed=!0:(l=Nt.getModifier(t[r].ty),e[r]=l,l.init(this,t,r,e),this.shapeModifiers.push(l),i=!1),d.push(l));this.addProcessedElement(t[r],r+1)}for(this.removeTransformFromStyleList(),this.closeStyles(c),f=d.length,r=0;r<f;r+=1)d[r].closed=!0},Ws.prototype.renderInnerContent=function(){this.transformHelper.opacity=1,this.transformHelper._opMdf=!1,this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame),this.renderShape(this.transformHelper,this.shapesData,this.itemsData,!0)},Ws.prototype.renderShapeTransform=function(t,e){(t._opMdf||e.op._mdf||this._isFirstFrame)&&(e.opacity=t.opacity,e.opacity*=e.op.v,e._opMdf=!0)},Ws.prototype.drawLayer=function(){var t,e,s,i,a,r,n,o,h,l=this.stylesList.length,p=this.globalData.renderer,f=this.globalData.canvasContext;for(t=0;t<l;t+=1)if(("st"!==(o=(h=this.stylesList[t]).type)&&"gs"!==o||0!==h.wi)&&h.data._shouldRender&&0!==h.coOp&&0!==this.globalData.currentGlobalAlpha){for(p.save(),r=h.elements,"st"===o||"gs"===o?(p.ctxStrokeStyle("st"===o?h.co:h.grd),p.ctxLineWidth(h.wi),p.ctxLineCap(h.lc),p.ctxLineJoin(h.lj),p.ctxMiterLimit(h.ml||0)):p.ctxFillStyle("fl"===o?h.co:h.grd),p.ctxOpacity(h.coOp),"st"!==o&&"gs"!==o&&f.beginPath(),p.ctxTransform(h.preTransforms.finalTransform.props),s=r.length,e=0;e<s;e+=1){for("st"!==o&&"gs"!==o||(f.beginPath(),h.da&&(f.setLineDash(h.da),f.lineDashOffset=h.do)),a=(n=r[e].trNodes).length,i=0;i<a;i+=1)"m"===n[i].t?f.moveTo(n[i].p[0],n[i].p[1]):"c"===n[i].t?f.bezierCurveTo(n[i].pts[0],n[i].pts[1],n[i].pts[2],n[i].pts[3],n[i].pts[4],n[i].pts[5]):f.closePath();"st"!==o&&"gs"!==o||(p.ctxStroke(),h.da&&f.setLineDash(this.dashResetter))}"st"!==o&&"gs"!==o&&this.globalData.renderer.ctxFill(h.r),p.restore()}},Ws.prototype.renderShape=function(t,e,s,i){var a,r;for(r=t,a=e.length-1;a>=0;a-=1)"tr"===e[a].ty?(r=s[a].transform,this.renderShapeTransform(t,r)):"sh"===e[a].ty||"el"===e[a].ty||"rc"===e[a].ty||"sr"===e[a].ty?this.renderPath(e[a],s[a]):"fl"===e[a].ty?this.renderFill(e[a],s[a],r):"st"===e[a].ty?this.renderStroke(e[a],s[a],r):"gf"===e[a].ty||"gs"===e[a].ty?this.renderGradientFill(e[a],s[a],r):"gr"===e[a].ty?this.renderShape(r,e[a].it,s[a].it):e[a].ty;i&&this.drawLayer()},Ws.prototype.renderStyledShape=function(t,e){if(this._isFirstFrame||e._mdf||t.transforms._mdf){var s,i,a,r=t.trNodes,n=e.paths,o=n._length;r.length=0;var h=t.transforms.finalTransform;for(a=0;a<o;a+=1){var l=n.shapes[a];if(l&&l.v){for(i=l._length,s=1;s<i;s+=1)1===s&&r.push({t:"m",p:h.applyToPointArray(l.v[0][0],l.v[0][1],0)}),r.push({t:"c",pts:h.applyToTriplePoints(l.o[s-1],l.i[s],l.v[s])});1===i&&r.push({t:"m",p:h.applyToPointArray(l.v[0][0],l.v[0][1],0)}),l.c&&i&&(r.push({t:"c",pts:h.applyToTriplePoints(l.o[s-1],l.i[0],l.v[0])}),r.push({t:"z"}))}}t.trNodes=r}},Ws.prototype.renderPath=function(t,e){if(!0!==t.hd&&t._shouldRender){var s,i=e.styledShapes.length;for(s=0;s<i;s+=1)this.renderStyledShape(e.styledShapes[s],e.sh)}},Ws.prototype.renderFill=function(t,e,s){var i=e.style;(e.c._mdf||this._isFirstFrame)&&(i.co="rgb("+v(e.c.v[0])+","+v(e.c.v[1])+","+v(e.c.v[2])+")"),(e.o._mdf||s._opMdf||this._isFirstFrame)&&(i.coOp=e.o.v*s.opacity)},Ws.prototype.renderGradientFill=function(t,e,s){var i,a=e.style;if(!a.grd||e.g._mdf||e.s._mdf||e.e._mdf||1!==t.t&&(e.h._mdf||e.a._mdf)){var r,n=this.globalData.canvasContext,o=e.s.v,h=e.e.v;if(1===t.t)i=n.createLinearGradient(o[0],o[1],h[0],h[1]);else{var l=Math.sqrt(Math.pow(o[0]-h[0],2)+Math.pow(o[1]-h[1],2)),p=Math.atan2(h[1]-o[1],h[0]-o[0]),f=e.h.v;f>=1?f=.99:f<=-1&&(f=-.99);var c=l*f,d=Math.cos(p+e.a.v)*c+o[0],m=Math.sin(p+e.a.v)*c+o[1];i=n.createRadialGradient(d,m,0,o[0],o[1],l)}var u=t.g.p,g=e.g.c,y=1;for(r=0;r<u;r+=1)e.g._hasOpacity&&e.g._collapsable&&(y=e.g.o[2*r+1]),i.addColorStop(g[4*r]/100,"rgba("+g[4*r+1]+","+g[4*r+2]+","+g[4*r+3]+","+y+")");a.grd=i}a.coOp=e.o.v*s.opacity},Ws.prototype.renderStroke=function(t,e,s){var i=e.style,a=e.d;a&&(a._mdf||this._isFirstFrame)&&(i.da=a.dashArray,i.do=a.dashoffset[0]),(e.c._mdf||this._isFirstFrame)&&(i.co="rgb("+v(e.c.v[0])+","+v(e.c.v[1])+","+v(e.c.v[2])+")"),(e.o._mdf||s._opMdf||this._isFirstFrame)&&(i.coOp=e.o.v*s.opacity),(e.w._mdf||this._isFirstFrame)&&(i.wi=e.w.v)},Ws.prototype.destroy=function(){this.shapesData=null,this.globalData=null,this.canvasContext=null,this.stylesList.length=0,this.itemsData.length=0},r([Ve,We,Os,Ue,ze,ke,xs],js),js.prototype.tHelper=a("canvas").getContext("2d"),js.prototype.buildNewText=function(){var t=this.textProperty.currentData;this.renderedLetters=l(t.l?t.l.length:0);var e=!1;t.fc?(e=!0,this.values.fill=this.buildColor(t.fc)):this.values.fill="rgba(0,0,0,0)",this.fill=e;var s=!1;t.sc&&(s=!0,this.values.stroke=this.buildColor(t.sc),this.values.sWidth=t.sw);var i,a,r,n,o,h,p,f,c,d,m,u,g=this.globalData.fontManager.getFontByName(t.f),y=t.l,v=this.mHelper;this.stroke=s,this.values.fValue=t.finalSize+"px "+this.globalData.fontManager.getFontByName(t.f).fFamily,a=t.finalText.length;var b=this.data.singleShape,_=.001*t.tr*t.finalSize,C=0,x=0,k=!0,S=0;for(i=0;i<a;i+=1){n=(r=this.globalData.fontManager.getCharData(t.finalText[i],g.fStyle,this.globalData.fontManager.getFontByName(t.f).fFamily))&&r.data||{},v.reset(),b&&y[i].n&&(C=-_,x+=t.yOffset,x+=k?1:0,k=!1),c=(p=n.shapes?n.shapes[0].it:[]).length,v.scale(t.finalSize/100,t.finalSize/100),b&&this.applyTextPropertiesToMatrix(t,v,y[i].line,C,x),m=l(c-1);var P=0;for(f=0;f<c;f+=1)if("sh"===p[f].ty){for(h=p[f].ks.k.i.length,d=p[f].ks.k,u=[],o=1;o<h;o+=1)1===o&&u.push(v.applyToX(d.v[0][0],d.v[0][1],0),v.applyToY(d.v[0][0],d.v[0][1],0)),u.push(v.applyToX(d.o[o-1][0],d.o[o-1][1],0),v.applyToY(d.o[o-1][0],d.o[o-1][1],0),v.applyToX(d.i[o][0],d.i[o][1],0),v.applyToY(d.i[o][0],d.i[o][1],0),v.applyToX(d.v[o][0],d.v[o][1],0),v.applyToY(d.v[o][0],d.v[o][1],0));u.push(v.applyToX(d.o[o-1][0],d.o[o-1][1],0),v.applyToY(d.o[o-1][0],d.o[o-1][1],0),v.applyToX(d.i[0][0],d.i[0][1],0),v.applyToY(d.i[0][0],d.i[0][1],0),v.applyToX(d.v[0][0],d.v[0][1],0),v.applyToY(d.v[0][0],d.v[0][1],0)),m[P]=u,P+=1}b&&(C+=y[i].l,C+=_),this.textSpans[S]?this.textSpans[S].elem=m:this.textSpans[S]={elem:m},S+=1}},js.prototype.renderInnerContent=function(){var t,e,s,i,a,r;this.validateText(),this.canvasContext.font=this.values.fValue,this.globalData.renderer.ctxLineCap("butt"),this.globalData.renderer.ctxLineJoin("miter"),this.globalData.renderer.ctxMiterLimit(4),this.data.singleShape||this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag);var n,o=this.textAnimator.renderedLetters,h=this.textProperty.currentData.l;e=h.length;var l,p,f=null,c=null,d=null,m=this.globalData.renderer;for(t=0;t<e;t+=1)if(!h[t].n){if((n=o[t])&&(m.save(),m.ctxTransform(n.p),m.ctxOpacity(n.o)),this.fill){for(n&&n.fc?f!==n.fc&&(m.ctxFillStyle(n.fc),f=n.fc):f!==this.values.fill&&(f=this.values.fill,m.ctxFillStyle(this.values.fill)),i=(l=this.textSpans[t].elem).length,this.globalData.canvasContext.beginPath(),s=0;s<i;s+=1)for(r=(p=l[s]).length,this.globalData.canvasContext.moveTo(p[0],p[1]),a=2;a<r;a+=6)this.globalData.canvasContext.bezierCurveTo(p[a],p[a+1],p[a+2],p[a+3],p[a+4],p[a+5]);this.globalData.canvasContext.closePath(),m.ctxFill()}if(this.stroke){for(n&&n.sw?d!==n.sw&&(d=n.sw,m.ctxLineWidth(n.sw)):d!==this.values.sWidth&&(d=this.values.sWidth,m.ctxLineWidth(this.values.sWidth)),n&&n.sc?c!==n.sc&&(c=n.sc,m.ctxStrokeStyle(n.sc)):c!==this.values.stroke&&(c=this.values.stroke,m.ctxStrokeStyle(this.values.stroke)),i=(l=this.textSpans[t].elem).length,this.globalData.canvasContext.beginPath(),s=0;s<i;s+=1)for(r=(p=l[s]).length,this.globalData.canvasContext.moveTo(p[0],p[1]),a=2;a<r;a+=6)this.globalData.canvasContext.bezierCurveTo(p[a],p[a+1],p[a+2],p[a+3],p[a+4],p[a+5]);this.globalData.canvasContext.closePath(),m.ctxStroke()}n&&this.globalData.renderer.restore()}},r([Ve,We,Os,Ue,ze,ke],Ys),Ys.prototype.initElement=gs.prototype.initElement,Ys.prototype.prepareFrame=Qe.prototype.prepareFrame,Ys.prototype.createContent=function(){if(this.img.width&&(this.assetData.w!==this.img.width||this.assetData.h!==this.img.height)){var t=a("canvas");t.width=this.assetData.w,t.height=this.assetData.h;var e,s,i=t.getContext("2d"),r=this.img.width,n=this.img.height,o=r/n,h=this.assetData.w/this.assetData.h,l=this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio;o>h&&"xMidYMid slice"===l||o<h&&"xMidYMid slice"!==l?e=(s=n)*h:s=(e=r)/h,i.drawImage(this.img,(r-e)/2,(n-s)/2,e,s,0,0,this.assetData.w,this.assetData.h),this.img=t}},Ys.prototype.renderInnerContent=function(){this.canvasContext.drawImage(this.img,0,0)},Ys.prototype.destroy=function(){this.img=null},r([Ve,We,Os,Ue,ze,ke],Js),Js.prototype.initElement=gs.prototype.initElement,Js.prototype.prepareFrame=Qe.prototype.prepareFrame,Js.prototype.renderInnerContent=function(){this.globalData.renderer.ctxFillStyle(this.data.sc),this.globalData.renderer.ctxFillRect(0,0,this.data.sw,this.data.sh)},r([qe],Hs),Hs.prototype.createShape=function(t){return new Ws(t,this.globalData,this)},Hs.prototype.createText=function(t){return new js(t,this.globalData,this)},Hs.prototype.createImage=function(t){return new Ys(t,this.globalData,this)},Hs.prototype.createSolid=function(t){return new Js(t,this.globalData,this)},Hs.prototype.createNull=Ts.prototype.createNull,Hs.prototype.ctxTransform=function(t){1===t[0]&&0===t[1]&&0===t[4]&&1===t[5]&&0===t[12]&&0===t[13]||this.canvasContext.transform(t[0],t[1],t[4],t[5],t[12],t[13])},Hs.prototype.ctxOpacity=function(t){this.canvasContext.globalAlpha*=t<0?0:t},Hs.prototype.ctxFillStyle=function(t){this.canvasContext.fillStyle=t},Hs.prototype.ctxStrokeStyle=function(t){this.canvasContext.strokeStyle=t},Hs.prototype.ctxLineWidth=function(t){this.canvasContext.lineWidth=t},Hs.prototype.ctxLineCap=function(t){this.canvasContext.lineCap=t},Hs.prototype.ctxLineJoin=function(t){this.canvasContext.lineJoin=t},Hs.prototype.ctxMiterLimit=function(t){this.canvasContext.miterLimit=t},Hs.prototype.ctxFill=function(t){this.canvasContext.fill(t)},Hs.prototype.ctxFillRect=function(t,e,s,i){this.canvasContext.fillRect(t,e,s,i)},Hs.prototype.ctxStroke=function(){this.canvasContext.stroke()},Hs.prototype.reset=function(){this.renderConfig.clearCanvas?this.contextData.reset():this.canvasContext.restore()},Hs.prototype.save=function(){this.canvasContext.save()},Hs.prototype.restore=function(t){this.renderConfig.clearCanvas?(t&&(this.globalData.blendMode="source-over"),this.contextData.restore(t)):this.canvasContext.restore()},Hs.prototype.configAnimation=function(t){if(this.animationItem.wrapper){this.animationItem.container=a("canvas");var e=this.animationItem.container.style;e.width="100%",e.height="100%";var s="0px 0px 0px";e.transformOrigin=s,e.mozTransformOrigin=s,e.webkitTransformOrigin=s,e["-webkit-transform"]=s,e.contentVisibility=this.renderConfig.contentVisibility,this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.animationItem.container.setAttribute("id",this.renderConfig.id)}else this.canvasContext=this.renderConfig.context;this.contextData.setContext(this.canvasContext),this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.setupGlobalData(t,document.body),this.globalData.canvasContext=this.canvasContext,this.globalData.renderer=this,this.globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=l(t.layers.length),this.updateContainerSize()},Hs.prototype.updateContainerSize=function(t,e){var s,i,a,r;if(this.reset(),t?(s=t,i=e,this.canvasContext.canvas.width=s,this.canvasContext.canvas.height=i):(this.animationItem.wrapper&&this.animationItem.container?(s=this.animationItem.wrapper.offsetWidth,i=this.animationItem.wrapper.offsetHeight):(s=this.canvasContext.canvas.width,i=this.canvasContext.canvas.height),this.canvasContext.canvas.width=s*this.renderConfig.dpr,this.canvasContext.canvas.height=i*this.renderConfig.dpr),-1!==this.renderConfig.preserveAspectRatio.indexOf("meet")||-1!==this.renderConfig.preserveAspectRatio.indexOf("slice")){var n=this.renderConfig.preserveAspectRatio.split(" "),o=n[1]||"meet",h=n[0]||"xMidYMid",l=h.substr(0,4),p=h.substr(4);a=s/i,(r=this.transformCanvas.w/this.transformCanvas.h)>a&&"meet"===o||r<a&&"slice"===o?(this.transformCanvas.sx=s/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=s/(this.transformCanvas.w/this.renderConfig.dpr)):(this.transformCanvas.sx=i/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.sy=i/(this.transformCanvas.h/this.renderConfig.dpr)),this.transformCanvas.tx="xMid"===l&&(r<a&&"meet"===o||r>a&&"slice"===o)?(s-this.transformCanvas.w*(i/this.transformCanvas.h))/2*this.renderConfig.dpr:"xMax"===l&&(r<a&&"meet"===o||r>a&&"slice"===o)?(s-this.transformCanvas.w*(i/this.transformCanvas.h))*this.renderConfig.dpr:0,this.transformCanvas.ty="YMid"===p&&(r>a&&"meet"===o||r<a&&"slice"===o)?(i-this.transformCanvas.h*(s/this.transformCanvas.w))/2*this.renderConfig.dpr:"YMax"===p&&(r>a&&"meet"===o||r<a&&"slice"===o)?(i-this.transformCanvas.h*(s/this.transformCanvas.w))*this.renderConfig.dpr:0}else"none"===this.renderConfig.preserveAspectRatio?(this.transformCanvas.sx=s/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=i/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.tx=0,this.transformCanvas.ty=0):(this.transformCanvas.sx=this.renderConfig.dpr,this.transformCanvas.sy=this.renderConfig.dpr,this.transformCanvas.tx=0,this.transformCanvas.ty=0);this.transformCanvas.props=[this.transformCanvas.sx,0,0,0,0,this.transformCanvas.sy,0,0,0,0,1,0,this.transformCanvas.tx,this.transformCanvas.ty,0,1],this.ctxTransform(this.transformCanvas.props),this.canvasContext.beginPath(),this.canvasContext.rect(0,0,this.transformCanvas.w,this.transformCanvas.h),this.canvasContext.closePath(),this.canvasContext.clip(),this.renderFrame(this.renderedFrame,!0)},Hs.prototype.destroy=function(){var t;for(this.renderConfig.clearCanvas&&this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),t=(this.layers?this.layers.length:0)-1;t>=0;t-=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.globalData.canvasContext=null,this.animationItem.container=null,this.destroyed=!0},Hs.prototype.renderFrame=function(t,e){if((this.renderedFrame!==t||!0!==this.renderConfig.clearCanvas||e)&&!this.destroyed&&-1!==t){var s;this.renderedFrame=t,this.globalData.frameNum=t-this.animationItem._isFirstFrame,this.globalData.frameId+=1,this.globalData._mdf=!this.renderConfig.clearCanvas||e,this.globalData.projectInterface.currentFrame=t;var i=this.layers.length;for(this.completeLayers||this.checkLayers(t),s=i-1;s>=0;s-=1)(this.completeLayers||this.elements[s])&&this.elements[s].prepareFrame(t-this.layers[s].st);if(this.globalData._mdf){for(!0===this.renderConfig.clearCanvas?this.canvasContext.clearRect(0,0,this.transformCanvas.w,this.transformCanvas.h):this.save(),s=i-1;s>=0;s-=1)(this.completeLayers||this.elements[s])&&this.elements[s].renderFrame();!0!==this.renderConfig.clearCanvas&&this.restore()}}},Hs.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){var s=this.createItem(this.layers[t],this,this.globalData);e[t]=s,s.initExpressions()}},Hs.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},Hs.prototype.hide=function(){this.animationItem.container.style.display="none"},Hs.prototype.show=function(){this.animationItem.container.style.display="block"},Xs.prototype.duplicate=function(){var t=2*this._length,e=0;for(e=this._length;e<t;e+=1)this.stack[e]=new Gs;this._length=t},Xs.prototype.reset=function(){this.cArrPos=0,this.cTr.reset(),this.stack[this.cArrPos].opacity=1},Xs.prototype.restore=function(t){this.cArrPos-=1;var e,s=this.stack[this.cArrPos],i=s.transform,a=this.cTr.props;for(e=0;e<16;e+=1)a[e]=i[e];if(t){this.nativeContext.restore();var r=this.stack[this.cArrPos+1];this.appliedFillStyle=r.fillStyle,this.appliedStrokeStyle=r.strokeStyle,this.appliedLineWidth=r.lineWidth,this.appliedLineCap=r.lineCap,this.appliedLineJoin=r.lineJoin,this.appliedMiterLimit=r.miterLimit}this.nativeContext.setTransform(i[0],i[1],i[4],i[5],i[12],i[13]),(t||-1!==s.opacity&&this.currentOpacity!==s.opacity)&&(this.nativeContext.globalAlpha=s.opacity,this.currentOpacity=s.opacity),this.currentFillStyle=s.fillStyle,this.currentStrokeStyle=s.strokeStyle,this.currentLineWidth=s.lineWidth,this.currentLineCap=s.lineCap,this.currentLineJoin=s.lineJoin,this.currentMiterLimit=s.miterLimit},Xs.prototype.save=function(t){t&&this.nativeContext.save();var e=this.cTr.props;this._length<=this.cArrPos&&this.duplicate();var s,i=this.stack[this.cArrPos];for(s=0;s<16;s+=1)i.transform[s]=e[s];this.cArrPos+=1;var a=this.stack[this.cArrPos];a.opacity=i.opacity,a.fillStyle=i.fillStyle,a.strokeStyle=i.strokeStyle,a.lineWidth=i.lineWidth,a.lineCap=i.lineCap,a.lineJoin=i.lineJoin,a.miterLimit=i.miterLimit},Xs.prototype.setOpacity=function(t){this.stack[this.cArrPos].opacity=t},Xs.prototype.setContext=function(t){this.nativeContext=t},Xs.prototype.fillStyle=function(t){this.stack[this.cArrPos].fillStyle!==t&&(this.currentFillStyle=t,this.stack[this.cArrPos].fillStyle=t)},Xs.prototype.strokeStyle=function(t){this.stack[this.cArrPos].strokeStyle!==t&&(this.currentStrokeStyle=t,this.stack[this.cArrPos].strokeStyle=t)},Xs.prototype.lineWidth=function(t){this.stack[this.cArrPos].lineWidth!==t&&(this.currentLineWidth=t,this.stack[this.cArrPos].lineWidth=t)},Xs.prototype.lineCap=function(t){this.stack[this.cArrPos].lineCap!==t&&(this.currentLineCap=t,this.stack[this.cArrPos].lineCap=t)},Xs.prototype.lineJoin=function(t){this.stack[this.cArrPos].lineJoin!==t&&(this.currentLineJoin=t,this.stack[this.cArrPos].lineJoin=t)},Xs.prototype.miterLimit=function(t){this.stack[this.cArrPos].miterLimit!==t&&(this.currentMiterLimit=t,this.stack[this.cArrPos].miterLimit=t)},Xs.prototype.transform=function(t){this.transformMat.cloneFromProps(t);var e=this.cTr;this.transformMat.multiply(e),e.cloneFromProps(this.transformMat.props);var s=e.props;this.nativeContext.setTransform(s[0],s[1],s[4],s[5],s[12],s[13])},Xs.prototype.opacity=function(t){var e=this.stack[this.cArrPos].opacity;e*=t<0?0:t,this.stack[this.cArrPos].opacity!==e&&(this.currentOpacity!==t&&(this.nativeContext.globalAlpha=t,this.currentOpacity=t),this.stack[this.cArrPos].opacity=e)},Xs.prototype.fill=function(t){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fill(t)},Xs.prototype.fillRect=function(t,e,s,i){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fillRect(t,e,s,i)},Xs.prototype.stroke=function(){this.appliedStrokeStyle!==this.currentStrokeStyle&&(this.appliedStrokeStyle=this.currentStrokeStyle,this.nativeContext.strokeStyle=this.appliedStrokeStyle),this.appliedLineWidth!==this.currentLineWidth&&(this.appliedLineWidth=this.currentLineWidth,this.nativeContext.lineWidth=this.appliedLineWidth),this.appliedLineCap!==this.currentLineCap&&(this.appliedLineCap=this.currentLineCap,this.nativeContext.lineCap=this.appliedLineCap),this.appliedLineJoin!==this.currentLineJoin&&(this.appliedLineJoin=this.currentLineJoin,this.nativeContext.lineJoin=this.appliedLineJoin),this.appliedMiterLimit!==this.currentMiterLimit&&(this.appliedMiterLimit=this.currentMiterLimit,this.nativeContext.miterLimit=this.appliedMiterLimit),this.nativeContext.stroke()},r([Hs,As,Os],Ks),Ks.prototype.renderInnerContent=function(){var t,e=this.canvasContext;for(e.beginPath(),e.moveTo(0,0),e.lineTo(this.data.w,0),e.lineTo(this.data.w,this.data.h),e.lineTo(0,this.data.h),e.lineTo(0,0),e.clip(),t=this.layers.length-1;t>=0;t-=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},Ks.prototype.destroy=function(){var t;for(t=this.layers.length-1;t>=0;t-=1)this.elements[t]&&this.elements[t].destroy();this.layers=null,this.elements=null},Ks.prototype.createComp=function(t){return new Ks(t,this.globalData,this)},r([Hs],Us),Us.prototype.createComp=function(t){return new Ks(t,this.globalData,this)},Ns=Us,U["canvas"]=Ns,Nt.registerModifier("tm",Bt),Nt.registerModifier("pb",Wt),Nt.registerModifier("rp",Yt),Nt.registerModifier("rd",Jt),Nt.registerModifier("zz",he),Nt.registerModifier("op",be),Lt}));
+"undefined"!=typeof document&&"undefined"!=typeof navigator&&function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lottie=e()}(this,(function(){"use strict";var t="",e=!1,s=-999999,i=function(){return t};function a(t){return document.createElement(t)}function r(t,e){var s,i,a=t.length;for(s=0;s<a;s+=1)for(var r in i=t[s].prototype)Object.prototype.hasOwnProperty.call(i,r)&&(e.prototype[r]=i[r])}function n(t){function e(){}return e.prototype=t,e}var o=function(){function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].pause()},resume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].resume()},setRate:function(t){var e,s=this.audios.length;for(e=0;e<s;e+=1)this.audios[e].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}}(),h=function(){function t(t,e){var s,i=0,a=[];switch(t){case"int16":case"uint8c":s=1;break;default:s=1.1}for(i=0;i<e;i+=1)a.push(s);return a}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(e,s){return"float32"===e?new Float32Array(s):"int16"===e?new Int16Array(s):"uint8c"===e?new Uint8ClampedArray(s):t(e,s)}:t}();function l(t){return Array.apply(null,{length:t})}function p(t){return p="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},p(t)}var f=!0,c=null,d=null,m="",u=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),g=Math.pow,y=Math.sqrt,v=Math.floor,b=(Math.max,Math.min),_={};!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],s=e.length;for(t=0;t<s;t+=1)_[e[t]]=Math[e[t]]}(),_.random=Math.random,_.abs=function(t){if("object"===p(t)&&t.length){var e,s=l(t.length),i=t.length;for(e=0;e<i;e+=1)s[e]=Math.abs(t[e]);return s}return Math.abs(t)};var C=150,x=Math.PI/180,k=.5519;function S(t){0}function P(t,e,s,i){this.type=t,this.currentTime=e,this.totalTime=s,this.direction=i<0?-1:1}function D(t,e){this.type=t,this.direction=e<0?-1:1}function w(t,e,s,i){this.type=t,this.currentLoop=s,this.totalLoops=e,this.direction=i<0?-1:1}function A(t,e,s){this.type=t,this.firstFrame=e,this.totalFrames=s}function M(t,e){this.type=t,this.target=e}function T(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function F(t){this.type="configError",this.nativeError=t}var E,L=(E=0,function(){return m+"__lottie_element_"+(E+=1)});function I(t,e,s){var i,a,r,n,o,h,l,p;switch(h=s*(1-e),l=s*(1-(o=6*t-(n=Math.floor(6*t)))*e),p=s*(1-(1-o)*e),n%6){case 0:i=s,a=p,r=h;break;case 1:i=l,a=s,r=h;break;case 2:i=h,a=s,r=p;break;case 3:i=h,a=l,r=s;break;case 4:i=p,a=h,r=s;break;case 5:i=s,a=h,r=l}return[i,a,r]}function R(t,e,s){var i,a=Math.max(t,e,s),r=Math.min(t,e,s),n=a-r,o=0===a?0:n/a,h=a/255;switch(a){case r:i=0;break;case t:i=e-s+n*(e<s?6:0),i/=6*n;break;case e:i=s-t+2*n,i/=6*n;break;case s:i=t-e+4*n,i/=6*n}return[i,o,h]}function V(t,e){var s=R(255*t[0],255*t[1],255*t[2]);return s[1]+=e,s[1]>1?s[1]=1:s[1]<=0&&(s[1]=0),I(s[0],s[1],s[2])}function z(t,e){var s=R(255*t[0],255*t[1],255*t[2]);return s[2]+=e,s[2]>1?s[2]=1:s[2]<0&&(s[2]=0),I(s[0],s[1],s[2])}function O(t,e){var s=R(255*t[0],255*t[1],255*t[2]);return s[0]+=e/360,s[0]>1?s[0]-=1:s[0]<0&&(s[0]+=1),I(s[0],s[1],s[2])}!function(){var t,e,s=[];for(t=0;t<256;t+=1)e=t.toString(16),s[t]=1===e.length?"0"+e:e}();var N=function(){return c},q=function(){return d},B=function(t){C=t},W=function(){return C};function j(t){return document.createElementNS("http://www.w3.org/2000/svg",t)}function Y(t){return Y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Y(t)}var J=function(){var t,s,i=1,a=[],r={onmessage:function(){},postMessage:function(e){t({data:e})}},n={postMessage:function(t){r.onmessage({data:t})}};function o(s){if(window.Worker&&window.Blob&&e){var i=new Blob(["var _workerSelf = self; self.onmessage = ",s.toString()],{type:"text/javascript"}),a=URL.createObjectURL(i);return new Worker(a)}return t=s,r}function h(){s||(s=o((function(t){if(n.dataManager||(n.dataManager=function(){function t(a,r){var n,o,h,l,p,c,d=a.length;for(o=0;o<d;o+=1)if("ks"in(n=a[o])&&!n.completed){if(n.completed=!0,n.hasMask){var m=n.masksProperties;for(l=m.length,h=0;h<l;h+=1)if(m[h].pt.k.i)i(m[h].pt.k);else for(c=m[h].pt.k.length,p=0;p<c;p+=1)m[h].pt.k[p].s&&i(m[h].pt.k[p].s[0]),m[h].pt.k[p].e&&i(m[h].pt.k[p].e[0])}0===n.ty?(n.layers=e(n.refId,r),t(n.layers,r)):4===n.ty?s(n.shapes):5===n.ty&&f(n)}}function e(t,e){var s=function(t,e){for(var s=0,i=e.length;s<i;){if(e[s].id===t)return e[s];s+=1}return null}(t,e);return s?s.layers.__used?JSON.parse(JSON.stringify(s.layers)):(s.layers.__used=!0,s.layers):null}function s(t){var e,a,r;for(e=t.length-1;e>=0;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)i(t[e].ks.k);else for(r=t[e].ks.k.length,a=0;a<r;a+=1)t[e].ks.k[a].s&&i(t[e].ks.k[a].s[0]),t[e].ks.k[a].e&&i(t[e].ks.k[a].e[0]);else"gr"===t[e].ty&&s(t[e].it)}function i(t){var e,s=t.i.length;for(e=0;e<s;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function a(t,e){var s=e?e.split("."):[100,100,100];return t[0]>s[0]||!(s[0]>t[0])&&(t[1]>s[1]||!(s[1]>t[1])&&(t[2]>s[2]||!(s[2]>t[2])&&null))}var r,n=function(){var t=[4,4,14];function e(t){var e,s,i,a=t.length;for(e=0;e<a;e+=1)5===t[e].ty&&(i=void 0,i=(s=t[e]).t.d,s.t.d={k:[{s:i,t:0}]})}return function(s){if(a(t,s.v)&&(e(s.layers),s.assets)){var i,r=s.assets.length;for(i=0;i<r;i+=1)s.assets[i].layers&&e(s.assets[i].layers)}}}(),o=(r=[4,7,99],function(t){if(t.chars&&!a(r,t.v)){var e,i=t.chars.length;for(e=0;e<i;e+=1){var n=t.chars[e];n.data&&n.data.shapes&&(s(n.data.shapes),n.data.ip=0,n.data.op=99999,n.data.st=0,n.data.sr=1,n.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[e].t||(n.data.shapes.push({ty:"no"}),n.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}}}),h=function(){var t=[5,7,15];function e(t){var e,s,i=t.length;for(e=0;e<i;e+=1)5===t[e].ty&&(s=void 0,"number"==typeof(s=t[e].t.p).a&&(s.a={a:0,k:s.a}),"number"==typeof s.p&&(s.p={a:0,k:s.p}),"number"==typeof s.r&&(s.r={a:0,k:s.r}))}return function(s){if(a(t,s.v)&&(e(s.layers),s.assets)){var i,r=s.assets.length;for(i=0;i<r;i+=1)s.assets[i].layers&&e(s.assets[i].layers)}}}(),l=function(){var t=[4,1,9];function e(t){var s,i,a,r=t.length;for(s=0;s<r;s+=1)if("gr"===t[s].ty)e(t[s].it);else if("fl"===t[s].ty||"st"===t[s].ty)if(t[s].c.k&&t[s].c.k[0].i)for(a=t[s].c.k.length,i=0;i<a;i+=1)t[s].c.k[i].s&&(t[s].c.k[i].s[0]/=255,t[s].c.k[i].s[1]/=255,t[s].c.k[i].s[2]/=255,t[s].c.k[i].s[3]/=255),t[s].c.k[i].e&&(t[s].c.k[i].e[0]/=255,t[s].c.k[i].e[1]/=255,t[s].c.k[i].e[2]/=255,t[s].c.k[i].e[3]/=255);else t[s].c.k[0]/=255,t[s].c.k[1]/=255,t[s].c.k[2]/=255,t[s].c.k[3]/=255}function s(t){var s,i=t.length;for(s=0;s<i;s+=1)4===t[s].ty&&e(t[s].shapes)}return function(e){if(a(t,e.v)&&(s(e.layers),e.assets)){var i,r=e.assets.length;for(i=0;i<r;i+=1)e.assets[i].layers&&s(e.assets[i].layers)}}}(),p=function(){var t=[4,4,18];function e(t){var s,i,a;for(s=t.length-1;s>=0;s-=1)if("sh"===t[s].ty)if(t[s].ks.k.i)t[s].ks.k.c=t[s].closed;else for(a=t[s].ks.k.length,i=0;i<a;i+=1)t[s].ks.k[i].s&&(t[s].ks.k[i].s[0].c=t[s].closed),t[s].ks.k[i].e&&(t[s].ks.k[i].e[0].c=t[s].closed);else"gr"===t[s].ty&&e(t[s].it)}function s(t){var s,i,a,r,n,o,h=t.length;for(i=0;i<h;i+=1){if((s=t[i]).hasMask){var l=s.masksProperties;for(r=l.length,a=0;a<r;a+=1)if(l[a].pt.k.i)l[a].pt.k.c=l[a].cl;else for(o=l[a].pt.k.length,n=0;n<o;n+=1)l[a].pt.k[n].s&&(l[a].pt.k[n].s[0].c=l[a].cl),l[a].pt.k[n].e&&(l[a].pt.k[n].e[0].c=l[a].cl)}4===s.ty&&e(s.shapes)}}return function(e){if(a(t,e.v)&&(s(e.layers),e.assets)){var i,r=e.assets.length;for(i=0;i<r;i+=1)e.assets[i].layers&&s(e.assets[i].layers)}}}();function f(t){0===t.t.a.length&&t.t.p}var c={completeData:function(s){s.__complete||(l(s),n(s),o(s),h(s),p(s),t(s.layers,s.assets),function(s,i){if(s){var a=0,r=s.length;for(a=0;a<r;a+=1)1===s[a].t&&(s[a].data.layers=e(s[a].data.refId,i),t(s[a].data.layers,i))}}(s.chars,s.assets),s.__complete=!0)}};return c.checkColors=l,c.checkChars=o,c.checkPathProperties=h,c.checkShapes=p,c.completeLayers=t,c}()),n.assetLoader||(n.assetLoader=function(){function t(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")||t.response&&"object"===Y(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}return{load:function(e,s,i,a){var r,n=new XMLHttpRequest;try{n.responseType="json"}catch(t){}n.onreadystatechange=function(){if(4===n.readyState)if(200===n.status)r=t(n),i(r);else try{r=t(n),i(r)}catch(t){a&&a(t)}};try{n.open(["G","E","T"].join(""),e,!0)}catch(t){n.open(["G","E","T"].join(""),s+"/"+e,!0)}n.send()}}}()),"loadAnimation"===t.data.type)n.assetLoader.load(t.data.path,t.data.fullPath,(function(e){n.dataManager.completeData(e),n.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){n.postMessage({id:t.data.id,status:"error"})}));else if("complete"===t.data.type){var e=t.data.animation;n.dataManager.completeData(e),n.postMessage({id:t.data.id,payload:e,status:"success"})}else"loadData"===t.data.type&&n.assetLoader.load(t.data.path,t.data.fullPath,(function(e){n.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){n.postMessage({id:t.data.id,status:"error"})}))})),s.onmessage=function(t){var e=t.data,s=e.id,i=a[s];a[s]=null,"success"===e.status?i.onComplete(e.payload):i.onError&&i.onError()})}function l(t,e){var s="processId_"+(i+=1);return a[s]={onComplete:t,onError:e},s}return{loadAnimation:function(t,e,i){h();var a=l(e,i);s.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:a})},loadData:function(t,e,i){h();var a=l(e,i);s.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:a})},completeAnimation:function(t,e,i){h();var a=l(e,i);s.postMessage({type:"complete",animation:t,id:a})}}}(),H=function(){var t=function(){var t=a("canvas");t.width=1,t.height=1;var e=t.getContext("2d");return e.fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1),t}();function e(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function s(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function i(t,e,s){var i="";if(t.e)i=t.p;else if(e){var a=t.p;-1!==a.indexOf("images/")&&(a=a.split("/")[1]),i=e+a}else i=s,i+=t.u?t.u:"",i+=t.p;return i}function r(t){var e=0,s=setInterval(function(){(t.getBBox().width||e>500)&&(this._imageLoaded(),clearInterval(s)),e+=1}.bind(this),50)}function n(t){var e={assetData:t},s=i(t,this.assetsPath,this.path);return J.loadData(s,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}function o(){this._imageLoaded=e.bind(this),this._footageLoaded=s.bind(this),this.testImageLoaded=r.bind(this),this.createFootageData=n.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return o.prototype={loadAssets:function(t,e){var s;this.imagesLoadedCb=e;var i=t.length;for(s=0;s<i;s+=1)t[s].layers||(t[s].t&&"seq"!==t[s].t?3===t[s].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[s]))):(this.totalImages+=1,this.images.push(this._createImageData(t[s]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,s=this.images.length;e<s;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(e){var s=i(e,this.assetsPath,this.path),r=a("img");r.crossOrigin="anonymous",r.addEventListener("load",this._imageLoaded,!1),r.addEventListener("error",function(){n.img=t,this._imageLoaded()}.bind(this),!1),r.src=s;var n={img:r,assetData:e};return n},createImageData:function(e){var s=i(e,this.assetsPath,this.path),a=j("image");u?this.testImageLoaded(a):a.addEventListener("load",this._imageLoaded,!1),a.addEventListener("error",function(){r.img=t,this._imageLoaded()}.bind(this),!1),a.setAttributeNS("http://www.w3.org/1999/xlink","href",s),this._elementHelper.append?this._elementHelper.append(a):this._elementHelper.appendChild(a);var r={img:a,assetData:e};return r},imageLoaded:e,footageLoaded:s,setCacheType:function(t,e){"svg"===t?(this._elementHelper=e,this._createImageData=this.createImageData.bind(this)):this._createImageData=this.createImgData.bind(this)}},o}();function G(){}G.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var s=this._cbs[t],i=0;i<s.length;i+=1)s[i](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var s=0,i=this._cbs[t].length;s<i;)this._cbs[t][s]===e&&(this._cbs[t].splice(s,1),s-=1,i-=1),s+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var X=function(){function t(t){for(var e,s=t.split("\r\n"),i={},a=0,r=0;r<s.length;r+=1)2===(e=s[r].split(":")).length&&(i[e[0]]=e[1].trim(),a+=1);if(0===a)throw new Error;return i}return function(e){for(var s=[],i=0;i<e.length;i+=1){var a=e[i],r={time:a.tm,duration:a.dr};try{r.payload=JSON.parse(e[i].cm)}catch(s){try{r.payload=t(e[i].cm)}catch(t){r.payload={name:e[i].cm}}}s.push(r)}return s}}(),K=function(){function t(t){this.compositions.push(t)}return function(){function e(t){for(var e=0,s=this.compositions.length;e<s;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return e.compositions=[],e.currentFrame=0,e.registerComposition=t,e}}(),U={};function Z(t){return Z="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Z(t)}var Q=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=L(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=f,this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=K(),this.imagePreloader=new H,this.audioController=o(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new P("drawnFrame",0,0,0),this.expressionsPlugin=N()};r([G],Q),Q.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg";t.animType?e=t.animType:t.renderer&&(e=t.renderer);var s=U[e];this.renderer=new s(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||void 0===t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),J.loadAnimation(t.path,this.configAnimation,this.onSetupError))},Q.prototype.onSetupError=function(){this.trigger("data_failed")},Q.prototype.setupAnimation=function(t){J.completeAnimation(t,this.configAnimation)},Q.prototype.setData=function(t,e){e&&"object"!==Z(e)&&(e=JSON.parse(e));var s={wrapper:t,animationData:e},i=t.attributes;s.path=i.getNamedItem("data-animation-path")?i.getNamedItem("data-animation-path").value:i.getNamedItem("data-bm-path")?i.getNamedItem("data-bm-path").value:i.getNamedItem("bm-path")?i.getNamedItem("bm-path").value:"",s.animType=i.getNamedItem("data-anim-type")?i.getNamedItem("data-anim-type").value:i.getNamedItem("data-bm-type")?i.getNamedItem("data-bm-type").value:i.getNamedItem("bm-type")?i.getNamedItem("bm-type").value:i.getNamedItem("data-bm-renderer")?i.getNamedItem("data-bm-renderer").value:i.getNamedItem("bm-renderer")?i.getNamedItem("bm-renderer").value:function(){if(U.canvas)return"canvas";for(var t in U)if(U[t])return t;return""}()||"canvas";var a=i.getNamedItem("data-anim-loop")?i.getNamedItem("data-anim-loop").value:i.getNamedItem("data-bm-loop")?i.getNamedItem("data-bm-loop").value:i.getNamedItem("bm-loop")?i.getNamedItem("bm-loop").value:"";"false"===a?s.loop=!1:"true"===a?s.loop=!0:""!==a&&(s.loop=parseInt(a,10));var r=i.getNamedItem("data-anim-autoplay")?i.getNamedItem("data-anim-autoplay").value:i.getNamedItem("data-bm-autoplay")?i.getNamedItem("data-bm-autoplay").value:!i.getNamedItem("bm-autoplay")||i.getNamedItem("bm-autoplay").value;s.autoplay="false"!==r,s.name=i.getNamedItem("data-name")?i.getNamedItem("data-name").value:i.getNamedItem("data-bm-name")?i.getNamedItem("data-bm-name").value:i.getNamedItem("bm-name")?i.getNamedItem("bm-name").value:"","false"===(i.getNamedItem("data-anim-prerender")?i.getNamedItem("data-anim-prerender").value:i.getNamedItem("data-bm-prerender")?i.getNamedItem("data-bm-prerender").value:i.getNamedItem("bm-prerender")?i.getNamedItem("bm-prerender").value:"")&&(s.prerender=!1),s.path?this.setParams(s):this.trigger("destroy")},Q.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,s,i=this.animationData.layers,a=i.length,r=t.layers,n=r.length;for(s=0;s<n;s+=1)for(e=0;e<a;){if(i[e].id===r[s].id){i[e]=r[s];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(a=t.assets.length,e=0;e<a;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,J.completeAnimation(this.animationData,this.onSegmentComplete)},Q.prototype.onSegmentComplete=function(t){this.animationData=t;var e=N();e&&e.initExpressions(this),this.loadNextSegment()},Q.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var s=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,J.loadData(s,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},Q.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},Q.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},Q.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},Q.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=X(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},Q.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},Q.prototype.checkLoaded=function(){if(!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()){this.isLoaded=!0;var t=N();t&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play()}},Q.prototype.resize=function(t,e){var s="number"==typeof t?t:void 0,i="number"==typeof e?e:void 0;this.renderer.updateContainerSize(s,i)},Q.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},Q.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},Q.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},Q.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},Q.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},Q.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},Q.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},Q.prototype.getMarkerData=function(t){for(var e,s=0;s<this.markers.length;s+=1)if((e=this.markers[s]).payload&&e.payload.name===t)return e;return null},Q.prototype.goToAndStop=function(t,e,s){if(!s||this.name===s){var i=Number(t);if(isNaN(i)){var a=this.getMarkerData(t);a&&this.goToAndStop(a.time,!0)}else e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier);this.pause()}},Q.prototype.goToAndPlay=function(t,e,s){if(!s||this.name===s){var i=Number(t);if(isNaN(i)){var a=this.getMarkerData(t);a&&(a.duration?this.playSegments([a.time,a.time+a.duration],!0):this.goToAndStop(a.time,!0))}else this.goToAndStop(i,e,s);this.play()}},Q.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,s=!1;e>=this.totalFrames-1&&this.frameModifier>0?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(s=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(s=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),s&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},Q.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(this.frameModifier>0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},Q.prototype.setSegment=function(t,e){var s=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?s=t:this.currentRawFrame+this.firstFrame>e&&(s=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==s&&this.goToAndStop(s,!0)},Q.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===Z(t[0])){var s,i=t.length;for(s=0;s<i;s+=1)this.segments.push(t[s])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},Q.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},Q.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},Q.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},Q.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},Q.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},Q.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},Q.prototype.setLoop=function(t){this.loop=t},Q.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},Q.prototype.getVolume=function(){return this.audioController.getVolume()},Q.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},Q.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},Q.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},Q.prototype.getPath=function(){return this.path},Q.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var s=t.p;-1!==s.indexOf("images/")&&(s=s.split("/")[1]),e=this.assetsPath+s}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},Q.prototype.getAssetData=function(t){for(var e=0,s=this.assets.length;e<s;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},Q.prototype.hide=function(){this.renderer.hide()},Q.prototype.show=function(){this.renderer.show()},Q.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},Q.prototype.updateDocumentData=function(t,e,s){try{this.renderer.getElementByPath(t).updateDocumentData(e,s)}catch(t){}},Q.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new P(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new w(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new D(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new A(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new M(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new P(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new w(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new D(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new A(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new M(t,this))},Q.prototype.triggerRenderFrameError=function(t){var e=new T(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)},Q.prototype.triggerConfigError=function(t){var e=new F(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)};var $=function(){var t={},e=[],s=0,i=0,r=0,n=!0,o=!1;function h(t){for(var s=0,a=t.target;s<i;)e[s].animation===a&&(e.splice(s,1),s-=1,i-=1,a.isPaused||f()),s+=1}function l(t,s){if(!t)return null;for(var a=0;a<i;){if(e[a].elem===t&&null!==e[a].elem)return e[a].animation;a+=1}var r=new Q;return c(r,t),r.setData(t,s),r}function p(){r+=1,u()}function f(){r-=1}function c(t,s){t.addEventListener("destroy",h),t.addEventListener("_active",p),t.addEventListener("_idle",f),e.push({elem:s,animation:t}),i+=1}function d(t){var a,h=t-s;for(a=0;a<i;a+=1)e[a].animation.advanceTime(h);s=t,r&&!o?window.requestAnimationFrame(d):n=!0}function m(t){s=t,window.requestAnimationFrame(d)}function u(){!o&&r&&n&&(window.requestAnimationFrame(m),n=!1)}return t.registerAnimation=l,t.loadAnimation=function(t){var e=new Q;return c(e,null),e.setParams(t),e},t.setSpeed=function(t,s){var a;for(a=0;a<i;a+=1)e[a].animation.setSpeed(t,s)},t.setDirection=function(t,s){var a;for(a=0;a<i;a+=1)e[a].animation.setDirection(t,s)},t.play=function(t){var s;for(s=0;s<i;s+=1)e[s].animation.play(t)},t.pause=function(t){var s;for(s=0;s<i;s+=1)e[s].animation.pause(t)},t.stop=function(t){var s;for(s=0;s<i;s+=1)e[s].animation.stop(t)},t.togglePause=function(t){var s;for(s=0;s<i;s+=1)e[s].animation.togglePause(t)},t.searchAnimations=function(t,e,s){var i,r=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),n=r.length;for(i=0;i<n;i+=1)s&&r[i].setAttribute("data-bm-type",s),l(r[i],t);if(e&&0===n){s||(s="svg");var o=document.getElementsByTagName("body")[0];o.innerText="";var h=a("div");h.style.width="100%",h.style.height="100%",h.setAttribute("data-bm-type",s),o.appendChild(h),l(h,t)}},t.resize=function(){var t;for(t=0;t<i;t+=1)e[t].animation.resize()},t.goToAndStop=function(t,s,a){var r;for(r=0;r<i;r+=1)e[r].animation.goToAndStop(t,s,a)},t.destroy=function(t){var s;for(s=i-1;s>=0;s-=1)e[s].animation.destroy(t)},t.freeze=function(){o=!0},t.unfreeze=function(){o=!1,u()},t.setVolume=function(t,s){var a;for(a=0;a<i;a+=1)e[a].animation.setVolume(t,s)},t.mute=function(t){var s;for(s=0;s<i;s+=1)e[s].animation.mute(t)},t.unmute=function(t){var s;for(s=0;s<i;s+=1)e[s].animation.unmute(t)},t.getRegisteredAnimations=function(){var t,s=e.length,i=[];for(t=0;t<s;t+=1)i.push(e[t].animation);return i},t}(),tt=function(){var t={getBezierEasing:function(t,s,i,a,r){var n=r||("bez_"+t+"_"+s+"_"+i+"_"+a).replace(/\./g,"p");if(e[n])return e[n];var o=new p([t,s,i,a]);return e[n]=o,o}},e={};var s=11,i=1/(s-1),a="function"==typeof Float32Array;function r(t,e){return 1-3*e+3*t}function n(t,e){return 3*e-6*t}function o(t){return 3*t}function h(t,e,s){return((r(e,s)*t+n(e,s))*t+o(e))*t}function l(t,e,s){return 3*r(e,s)*t*t+2*n(e,s)*t+o(e)}function p(t){this._p=t,this._mSampleValues=a?new Float32Array(s):new Array(s),this._precomputed=!1,this.get=this.get.bind(this)}return p.prototype={get:function(t){var e=this._p[0],s=this._p[1],i=this._p[2],a=this._p[3];return this._precomputed||this._precompute(),e===s&&i===a?t:0===t?0:1===t?1:h(this._getTForX(t),s,a)},_precompute:function(){var t=this._p[0],e=this._p[1],s=this._p[2],i=this._p[3];this._precomputed=!0,t===e&&s===i||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],a=0;a<s;++a)this._mSampleValues[a]=h(a*i,t,e)},_getTForX:function(t){for(var e=this._p[0],a=this._p[2],r=this._mSampleValues,n=0,o=1,p=s-1;o!==p&&r[o]<=t;++o)n+=i;var f=n+(t-r[--o])/(r[o+1]-r[o])*i,c=l(f,e,a);return c>=.001?function(t,e,s,i){for(var a=0;a<4;++a){var r=l(e,s,i);if(0===r)return e;e-=(h(e,s,i)-t)/r}return e}(t,f,e,a):0===c?f:function(t,e,s,i,a){var r,n,o=0;do{(r=h(n=e+(s-e)/2,i,a)-t)>0?s=n:e=n}while(Math.abs(r)>1e-7&&++o<10);return n}(t,n,n+i,e,a)}},t}(),et={double:function(t){return t.concat(l(t.length))}},st=function(t,e,s){var i=0,a=t,r=l(a);return{newElement:function(){return i?r[i-=1]:e()},release:function(t){i===a&&(r=et.double(r),a*=2),s&&s(t),r[i]=t,i+=1}}},it=st(8,(function(){return{addedLength:0,percents:h("float32",W()),lengths:h("float32",W())}})),at=st(8,(function(){return{lengths:[],totalLength:0}}),(function(t){var e,s=t.lengths.length;for(e=0;e<s;e+=1)it.release(t.lengths[e]);t.lengths.length=0}));var rt=function(){var t=Math;function e(t,e,s,i,a,r){var n=t*i+e*a+s*r-a*i-r*t-s*e;return n>-.001&&n<.001}var s=function(t,e,s,i){var a,r,n,o,h,l,p=W(),f=0,c=[],d=[],m=it.newElement();for(n=s.length,a=0;a<p;a+=1){for(h=a/(p-1),l=0,r=0;r<n;r+=1)o=g(1-h,3)*t[r]+3*g(1-h,2)*h*s[r]+3*(1-h)*g(h,2)*i[r]+g(h,3)*e[r],c[r]=o,null!==d[r]&&(l+=g(c[r]-d[r],2)),d[r]=c[r];l&&(f+=l=y(l)),m.percents[a]=h,m.lengths[a]=f}return m.addedLength=f,m};function i(t){this.segmentLength=0,this.points=new Array(t)}function a(t,e){this.partialLength=t,this.point=e}var r,n=(r={},function(t,s,n,o){var h=(t[0]+"_"+t[1]+"_"+s[0]+"_"+s[1]+"_"+n[0]+"_"+n[1]+"_"+o[0]+"_"+o[1]).replace(/\./g,"p");if(!r[h]){var p,f,c,d,m,u,v,b=W(),_=0,C=null;2===t.length&&(t[0]!==s[0]||t[1]!==s[1])&&e(t[0],t[1],s[0],s[1],t[0]+n[0],t[1]+n[1])&&e(t[0],t[1],s[0],s[1],s[0]+o[0],s[1]+o[1])&&(b=2);var x=new i(b);for(c=n.length,p=0;p<b;p+=1){for(v=l(c),m=p/(b-1),u=0,f=0;f<c;f+=1)d=g(1-m,3)*t[f]+3*g(1-m,2)*m*(t[f]+n[f])+3*(1-m)*g(m,2)*(s[f]+o[f])+g(m,3)*s[f],v[f]=d,null!==C&&(u+=g(v[f]-C[f],2));_+=u=y(u),x.points[p]=new a(u,v),C=v}x.segmentLength=_,r[h]=x}return r[h]});function o(t,e){var s=e.percents,i=e.lengths,a=s.length,r=v((a-1)*t),n=t*e.addedLength,o=0;if(r===a-1||0===r||n===i[r])return s[r];for(var h=i[r]>n?-1:1,l=!0;l;)if(i[r]<=n&&i[r+1]>n?(o=(n-i[r])/(i[r+1]-i[r]),l=!1):r+=h,r<0||r>=a-1){if(r===a-1)return s[r];l=!1}return s[r]+(s[r+1]-s[r])*o}var p=h("float32",8);return{getSegmentsLength:function(t){var e,i=at.newElement(),a=t.c,r=t.v,n=t.o,o=t.i,h=t._length,l=i.lengths,p=0;for(e=0;e<h-1;e+=1)l[e]=s(r[e],r[e+1],n[e],o[e+1]),p+=l[e].addedLength;return a&&h&&(l[e]=s(r[e],r[0],n[e],o[0]),p+=l[e].addedLength),i.totalLength=p,i},getNewSegment:function(e,s,i,a,r,n,h){r<0?r=0:r>1&&(r=1);var l,f=o(r,h),c=o(n=n>1?1:n,h),d=e.length,m=1-f,u=1-c,g=m*m*m,y=f*m*m*3,v=f*f*m*3,b=f*f*f,_=m*m*u,C=f*m*u+m*f*u+m*m*c,x=f*f*u+m*f*c+f*m*c,k=f*f*c,S=m*u*u,P=f*u*u+m*c*u+m*u*c,D=f*c*u+m*c*c+f*u*c,w=f*c*c,A=u*u*u,M=c*u*u+u*c*u+u*u*c,T=c*c*u+u*c*c+c*u*c,F=c*c*c;for(l=0;l<d;l+=1)p[4*l]=t.round(1e3*(g*e[l]+y*i[l]+v*a[l]+b*s[l]))/1e3,p[4*l+1]=t.round(1e3*(_*e[l]+C*i[l]+x*a[l]+k*s[l]))/1e3,p[4*l+2]=t.round(1e3*(S*e[l]+P*i[l]+D*a[l]+w*s[l]))/1e3,p[4*l+3]=t.round(1e3*(A*e[l]+M*i[l]+T*a[l]+F*s[l]))/1e3;return p},getPointInSegment:function(e,s,i,a,r,n){var h=o(r,n),l=1-h;return[t.round(1e3*(l*l*l*e[0]+(h*l*l+l*h*l+l*l*h)*i[0]+(h*h*l+l*h*h+h*l*h)*a[0]+h*h*h*s[0]))/1e3,t.round(1e3*(l*l*l*e[1]+(h*l*l+l*h*l+l*l*h)*i[1]+(h*h*l+l*h*h+h*l*h)*a[1]+h*h*h*s[1]))/1e3]},buildBezierData:n,pointOnLine2D:e,pointOnLine3D:function(s,i,a,r,n,o,h,l,p){if(0===a&&0===o&&0===p)return e(s,i,r,n,h,l);var f,c=t.sqrt(t.pow(r-s,2)+t.pow(n-i,2)+t.pow(o-a,2)),d=t.sqrt(t.pow(h-s,2)+t.pow(l-i,2)+t.pow(p-a,2)),m=t.sqrt(t.pow(h-r,2)+t.pow(l-n,2)+t.pow(p-o,2));return(f=c>d?c>m?c-d-m:m-d-c:m>d?m-d-c:d-c-m)>-1e-4&&f<1e-4}}}(),nt=s,ot=Math.abs;function ht(t,e){var s,i=this.offsetTime;"multidimensional"===this.propType&&(s=h("float32",this.pv.length));for(var a,r,n,o,l,p,f,c,d,m=e.lastIndex,u=m,g=this.keyframes.length-1,y=!0;y;){if(a=this.keyframes[u],r=this.keyframes[u+1],u===g-1&&t>=r.t-i){a.h&&(a=r),m=0;break}if(r.t-i>t){m=u;break}u<g-1?u+=1:(m=0,y=!1)}n=this.keyframesMetadata[u]||{};var v,b,_,C,k,S,P,D,w,A,M=r.t-i,T=a.t-i;if(a.to){n.bezierData||(n.bezierData=rt.buildBezierData(a.s,r.s||a.e,a.to,a.ti));var F=n.bezierData;if(t>=M||t<T){var E=t>=M?F.points.length-1:0;for(l=F.points[E].point.length,o=0;o<l;o+=1)s[o]=F.points[E].point[o]}else{n.__fnct?d=n.__fnct:(d=tt.getBezierEasing(a.o.x,a.o.y,a.i.x,a.i.y,a.n).get,n.__fnct=d),p=d((t-T)/(M-T));var L,I=F.segmentLength*p,R=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastAddedLength:0;for(c=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastPoint:0,y=!0,f=F.points.length;y;){if(R+=F.points[c].partialLength,0===I||0===p||c===F.points.length-1){for(l=F.points[c].point.length,o=0;o<l;o+=1)s[o]=F.points[c].point[o];break}if(I>=R&&I<R+F.points[c+1].partialLength){for(L=(I-R)/F.points[c+1].partialLength,l=F.points[c].point.length,o=0;o<l;o+=1)s[o]=F.points[c].point[o]+(F.points[c+1].point[o]-F.points[c].point[o])*L;break}c<f-1?c+=1:y=!1}e._lastPoint=c,e._lastAddedLength=R-F.points[c].partialLength,e._lastKeyframeIndex=u}}else{var V,z,O,N,q;if(g=a.s.length,v=r.s||a.e,this.sh&&1!==a.h)if(t>=M)s[0]=v[0],s[1]=v[1],s[2]=v[2];else if(t<=T)s[0]=a.s[0],s[1]=a.s[1],s[2]=a.s[2];else{var B=lt(a.s),W=lt(v);b=s,_=function(t,e,s){var i,a,r,n,o,h=[],l=t[0],p=t[1],f=t[2],c=t[3],d=e[0],m=e[1],u=e[2],g=e[3];return(a=l*d+p*m+f*u+c*g)<0&&(a=-a,d=-d,m=-m,u=-u,g=-g),1-a>1e-6?(i=Math.acos(a),r=Math.sin(i),n=Math.sin((1-s)*i)/r,o=Math.sin(s*i)/r):(n=1-s,o=s),h[0]=n*l+o*d,h[1]=n*p+o*m,h[2]=n*f+o*u,h[3]=n*c+o*g,h}(B,W,(t-T)/(M-T)),C=_[0],k=_[1],S=_[2],P=_[3],D=Math.atan2(2*k*P-2*C*S,1-2*k*k-2*S*S),w=Math.asin(2*C*k+2*S*P),A=Math.atan2(2*C*P-2*k*S,1-2*C*C-2*S*S),b[0]=D/x,b[1]=w/x,b[2]=A/x}else for(u=0;u<g;u+=1)1!==a.h&&(t>=M?p=1:t<T?p=0:(a.o.x.constructor===Array?(n.__fnct||(n.__fnct=[]),n.__fnct[u]?d=n.__fnct[u]:(V=void 0===a.o.x[u]?a.o.x[0]:a.o.x[u],z=void 0===a.o.y[u]?a.o.y[0]:a.o.y[u],O=void 0===a.i.x[u]?a.i.x[0]:a.i.x[u],N=void 0===a.i.y[u]?a.i.y[0]:a.i.y[u],d=tt.getBezierEasing(V,z,O,N).get,n.__fnct[u]=d)):n.__fnct?d=n.__fnct:(V=a.o.x,z=a.o.y,O=a.i.x,N=a.i.y,d=tt.getBezierEasing(V,z,O,N).get,a.keyframeMetadata=d),p=d((t-T)/(M-T)))),v=r.s||a.e,q=1===a.h?a.s[u]:a.s[u]+(v[u]-a.s[u])*p,"multidimensional"===this.propType?s[u]=q:s=q}return e.lastIndex=m,s}function lt(t){var e=t[0]*x,s=t[1]*x,i=t[2]*x,a=Math.cos(e/2),r=Math.cos(s/2),n=Math.cos(i/2),o=Math.sin(e/2),h=Math.sin(s/2),l=Math.sin(i/2);return[o*h*n+a*r*l,o*r*n+a*h*l,a*h*n-o*r*l,a*r*n-o*h*l]}function pt(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,s=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==nt&&(this._caching.lastFrame>=s&&t>=s||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var i=this.interpolateValue(t,this._caching);this.pv=i}return this._caching.lastFrame=t,this.pv}function ft(t){var e;if("unidimensional"===this.propType)e=t*this.mult,ot(this.v-e)>1e-5&&(this.v=e,this._mdf=!0);else for(var s=0,i=this.v.length;s<i;)e=t[s]*this.mult,ot(this.v[s]-e)>1e-5&&(this.v[s]=e,this._mdf=!0),s+=1}function ct(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t;this.lock=!0,this._mdf=this._isFirstFrame;var e=this.effectsSequence.length,s=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)s=this.effectsSequence[t](s);this.setVValue(s),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function dt(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function mt(t,e,s,i){this.propType="unidimensional",this.mult=s||1,this.data=e,this.v=s?e.k*s:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=i,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=ct,this.setVValue=ft,this.addEffect=dt}function ut(t,e,s,i){var a;this.propType="multidimensional",this.mult=s||1,this.data=e,this._mdf=!1,this.elem=t,this.container=i,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var r=e.k.length;for(this.v=h("float32",r),this.pv=h("float32",r),this.vel=h("float32",r),a=0;a<r;a+=1)this.v[a]=e.k[a]*this.mult,this.pv[a]=e.k[a];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=ct,this.setVValue=ft,this.addEffect=dt}function gt(t,e,s,i){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:nt,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=s||1,this.elem=t,this.container=i,this.comp=t.comp,this.v=nt,this.pv=nt,this._isFirstFrame=!0,this.getValue=ct,this.setVValue=ft,this.interpolateValue=ht,this.effectsSequence=[pt.bind(this)],this.addEffect=dt}function yt(t,e,s,i){var a;this.propType="multidimensional";var r,n,o,l,p=e.k.length;for(a=0;a<p-1;a+=1)e.k[a].to&&e.k[a].s&&e.k[a+1]&&e.k[a+1].s&&(r=e.k[a].s,n=e.k[a+1].s,o=e.k[a].to,l=e.k[a].ti,(2===r.length&&(r[0]!==n[0]||r[1]!==n[1])&&rt.pointOnLine2D(r[0],r[1],n[0],n[1],r[0]+o[0],r[1]+o[1])&&rt.pointOnLine2D(r[0],r[1],n[0],n[1],n[0]+l[0],n[1]+l[1])||3===r.length&&(r[0]!==n[0]||r[1]!==n[1]||r[2]!==n[2])&&rt.pointOnLine3D(r[0],r[1],r[2],n[0],n[1],n[2],r[0]+o[0],r[1]+o[1],r[2]+o[2])&&rt.pointOnLine3D(r[0],r[1],r[2],n[0],n[1],n[2],n[0]+l[0],n[1]+l[1],n[2]+l[2]))&&(e.k[a].to=null,e.k[a].ti=null),r[0]===n[0]&&r[1]===n[1]&&0===o[0]&&0===o[1]&&0===l[0]&&0===l[1]&&(2===r.length||r[2]===n[2]&&0===o[2]&&0===l[2])&&(e.k[a].to=null,e.k[a].ti=null));this.effectsSequence=[pt.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=s||1,this.elem=t,this.container=i,this.comp=t.comp,this.getValue=ct,this.setVValue=ft,this.interpolateValue=ht,this.frameId=-1;var f=e.k[0].s.length;for(this.v=h("float32",f),this.pv=h("float32",f),a=0;a<f;a+=1)this.v[a]=nt,this.pv[a]=nt;this._caching={lastFrame:nt,lastIndex:0,value:h("float32",f)},this.addEffect=dt}var vt={getProp:function(t,e,s,i,a){var r;if(e.sid&&(e=t.globalData.slotManager.getProp(e)),e.k.length)if("number"==typeof e.k[0])r=new ut(t,e,i,a);else switch(s){case 0:r=new gt(t,e,i,a);break;case 1:r=new yt(t,e,i,a)}else r=new mt(t,e,i,a);return r.effectsSequence.length&&a.addDynamicProperty(r),r}};function bt(){}bt.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){var t;this._mdf=!1;var e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var _t=st(8,(function(){return h("float32",2)}));function Ct(){this.c=!1,this._length=0,this._maxLength=8,this.v=l(this._maxLength),this.o=l(this._maxLength),this.i=l(this._maxLength)}Ct.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var s=0;s<e;)this.v[s]=_t.newElement(),this.o[s]=_t.newElement(),this.i[s]=_t.newElement(),s+=1},Ct.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},Ct.prototype.doubleArrayLength=function(){this.v=this.v.concat(l(this._maxLength)),this.i=this.i.concat(l(this._maxLength)),this.o=this.o.concat(l(this._maxLength)),this._maxLength*=2},Ct.prototype.setXYAt=function(t,e,s,i,a){var r;switch(this._length=Math.max(this._length,i+1),this._length>=this._maxLength&&this.doubleArrayLength(),s){case"v":r=this.v;break;case"i":r=this.i;break;case"o":r=this.o;break;default:r=[]}(!r[i]||r[i]&&!a)&&(r[i]=_t.newElement()),r[i][0]=t,r[i][1]=e},Ct.prototype.setTripleAt=function(t,e,s,i,a,r,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(s,i,"o",n,o),this.setXYAt(a,r,"i",n,o)},Ct.prototype.reverse=function(){var t=new Ct;t.setPathData(this.c,this._length);var e=this.v,s=this.o,i=this.i,a=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],i[0][0],i[0][1],s[0][0],s[0][1],0,!1),a=1);var r,n=this._length-1,o=this._length;for(r=a;r<o;r+=1)t.setTripleAt(e[n][0],e[n][1],i[n][0],i[n][1],s[n][0],s[n][1],r,!1),n-=1;return t},Ct.prototype.length=function(){return this._length};var xt,kt=((xt=st(4,(function(){return new Ct}),(function(t){var e,s=t._length;for(e=0;e<s;e+=1)_t.release(t.v[e]),_t.release(t.i[e]),_t.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1}))).clone=function(t){var e,s=xt.newElement(),i=void 0===t._length?t.v.length:t._length;for(s.setLength(i),s.c=t.c,e=0;e<i;e+=1)s.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return s},xt);function St(){this._length=0,this._maxLength=4,this.shapes=l(this._maxLength)}St.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(l(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},St.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)kt.release(this.shapes[t]);this._length=0};var Pt,Dt,wt,At,Mt=(Pt={newShapeCollection:function(){return Dt?At[Dt-=1]:new St},release:function(t){var e,s=t._length;for(e=0;e<s;e+=1)kt.release(t.shapes[e]);t._length=0,Dt===wt&&(At=et.double(At),wt*=2),At[Dt]=t,Dt+=1}},Dt=0,At=l(wt=4),Pt),Tt=function(){var t=-999999;function e(t,e,s){var i,a,r,n,o,h,l,p,f,c=s.lastIndex,d=this.keyframes;if(t<d[0].t-this.offsetTime)i=d[0].s[0],r=!0,c=0;else if(t>=d[d.length-1].t-this.offsetTime)i=d[d.length-1].s?d[d.length-1].s[0]:d[d.length-2].e[0],r=!0;else{for(var m,u,g,y=c,v=d.length-1,b=!0;b&&(m=d[y],!((u=d[y+1]).t-this.offsetTime>t));)y<v-1?y+=1:b=!1;if(g=this.keyframesMetadata[y]||{},c=y,!(r=1===m.h)){if(t>=u.t-this.offsetTime)p=1;else if(t<m.t-this.offsetTime)p=0;else{var _;g.__fnct?_=g.__fnct:(_=tt.getBezierEasing(m.o.x,m.o.y,m.i.x,m.i.y).get,g.__fnct=_),p=_((t-(m.t-this.offsetTime))/(u.t-this.offsetTime-(m.t-this.offsetTime)))}a=u.s?u.s[0]:m.e[0]}i=m.s[0]}for(h=e._length,l=i.i[0].length,s.lastIndex=c,n=0;n<h;n+=1)for(o=0;o<l;o+=1)f=r?i.i[n][o]:i.i[n][o]+(a.i[n][o]-i.i[n][o])*p,e.i[n][o]=f,f=r?i.o[n][o]:i.o[n][o]+(a.o[n][o]-i.o[n][o])*p,e.o[n][o]=f,f=r?i.v[n][o]:i.v[n][o]+(a.v[n][o]-i.v[n][o])*p,e.v[n][o]=f}function s(){var e=this.comp.renderedFrame-this.offsetTime,s=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime,a=this._caching.lastFrame;return a!==t&&(a<s&&e<s||a>i&&e>i)||(this._caching.lastIndex=a<e?this._caching.lastIndex:0,this.interpolateShape(e,this.pv,this._caching)),this._caching.lastFrame=e,this.pv}function i(){this.paths=this.localShapeCollection}function a(t){(function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var s,i=t._length;for(s=0;s<i;s+=1)if(t.v[s][0]!==e.v[s][0]||t.v[s][1]!==e.v[s][1]||t.o[s][0]!==e.o[s][0]||t.o[s][1]!==e.o[s][1]||t.i[s][0]!==e.i[s][0]||t.i[s][1]!==e.i[s][1])return!1;return!0})(this.v,t)||(this.v=kt.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function n(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t,e;this.lock=!0,this._mdf=!1,t=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k;var s=this.effectsSequence.length;for(e=0;e<s;e+=1)t=this.effectsSequence[e](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function o(t,e,s){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var a=3===s?e.pt.k:e.ks.k;this.v=kt.clone(a),this.pv=kt.clone(this.v),this.localShapeCollection=Mt.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=i,this.effectsSequence=[]}function h(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function l(e,a,r){this.propType="shape",this.comp=e.comp,this.elem=e,this.container=e,this.offsetTime=e.data.st,this.keyframes=3===r?a.pt.k:a.ks.k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;var n=this.keyframes[0].s[0].i.length;this.v=kt.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,n),this.pv=kt.clone(this.v),this.localShapeCollection=Mt.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=t,this.reset=i,this._caching={lastFrame:t,lastIndex:0},this.effectsSequence=[s.bind(this)]}o.prototype.interpolateShape=e,o.prototype.getValue=n,o.prototype.setVValue=a,o.prototype.addEffect=h,l.prototype.getValue=n,l.prototype.interpolateShape=e,l.prototype.setVValue=a,l.prototype.addEffect=h;var p=function(){var t=k;function e(t,e){this.v=kt.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=Mt.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=vt.getProp(t,e.p,1,0,this),this.s=vt.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}return e.prototype={reset:i,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var e=this.p.v[0],s=this.p.v[1],i=this.s.v[0]/2,a=this.s.v[1]/2,r=3!==this.d,n=this.v;n.v[0][0]=e,n.v[0][1]=s-a,n.v[1][0]=r?e+i:e-i,n.v[1][1]=s,n.v[2][0]=e,n.v[2][1]=s+a,n.v[3][0]=r?e-i:e+i,n.v[3][1]=s,n.i[0][0]=r?e-i*t:e+i*t,n.i[0][1]=s-a,n.i[1][0]=r?e+i:e-i,n.i[1][1]=s-a*t,n.i[2][0]=r?e+i*t:e-i*t,n.i[2][1]=s+a,n.i[3][0]=r?e-i:e+i,n.i[3][1]=s+a*t,n.o[0][0]=r?e+i*t:e-i*t,n.o[0][1]=s-a,n.o[1][0]=r?e+i:e-i,n.o[1][1]=s+a*t,n.o[2][0]=r?e-i*t:e+i*t,n.o[2][1]=s+a,n.o[3][0]=r?e-i:e+i,n.o[3][1]=s-a*t}},r([bt],e),e}(),f=function(){function t(t,e){this.v=kt.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=vt.getProp(t,e.ir,0,0,this),this.is=vt.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=vt.getProp(t,e.pt,0,0,this),this.p=vt.getProp(t,e.p,1,0,this),this.r=vt.getProp(t,e.r,0,x,this),this.or=vt.getProp(t,e.or,0,0,this),this.os=vt.getProp(t,e.os,0,.01,this),this.localShapeCollection=Mt.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}return t.prototype={reset:i,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,s,i,a=2*Math.floor(this.pt.v),r=2*Math.PI/a,n=!0,o=this.or.v,h=this.ir.v,l=this.os.v,p=this.is.v,f=2*Math.PI*o/(2*a),c=2*Math.PI*h/(2*a),d=-Math.PI/2;d+=this.r.v;var m=3===this.data.d?-1:1;for(this.v._length=0,t=0;t<a;t+=1){s=n?l:p,i=n?f:c;var u=(e=n?o:h)*Math.cos(d),g=e*Math.sin(d),y=0===u&&0===g?0:g/Math.sqrt(u*u+g*g),v=0===u&&0===g?0:-u/Math.sqrt(u*u+g*g);u+=+this.p.v[0],g+=+this.p.v[1],this.v.setTripleAt(u,g,u-y*i*s*m,g-v*i*s*m,u+y*i*s*m,g+v*i*s*m,t,!0),n=!n,d+=r*m}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),s=2*Math.PI/e,i=this.or.v,a=this.os.v,r=2*Math.PI*i/(4*e),n=.5*-Math.PI,o=3===this.data.d?-1:1;for(n+=this.r.v,this.v._length=0,t=0;t<e;t+=1){var h=i*Math.cos(n),l=i*Math.sin(n),p=0===h&&0===l?0:l/Math.sqrt(h*h+l*l),f=0===h&&0===l?0:-h/Math.sqrt(h*h+l*l);h+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(h,l,h-p*r*a*o,l-f*r*a*o,h+p*r*a*o,l+f*r*a*o,t,!0),n+=s*o}this.paths.length=0,this.paths[0]=this.v}},r([bt],t),t}(),c=function(){function t(t,e){this.v=kt.newElement(),this.v.c=!0,this.localShapeCollection=Mt.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=vt.getProp(t,e.p,1,0,this),this.s=vt.getProp(t,e.s,1,0,this),this.r=vt.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}return t.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],s=this.s.v[0]/2,i=this.s.v[1]/2,a=b(s,i,this.r.v),r=a*(1-k);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+s,e-i+a,t+s,e-i+a,t+s,e-i+r,0,!0),this.v.setTripleAt(t+s,e+i-a,t+s,e+i-r,t+s,e+i-a,1,!0),0!==a?(this.v.setTripleAt(t+s-a,e+i,t+s-a,e+i,t+s-r,e+i,2,!0),this.v.setTripleAt(t-s+a,e+i,t-s+r,e+i,t-s+a,e+i,3,!0),this.v.setTripleAt(t-s,e+i-a,t-s,e+i-a,t-s,e+i-r,4,!0),this.v.setTripleAt(t-s,e-i+a,t-s,e-i+r,t-s,e-i+a,5,!0),this.v.setTripleAt(t-s+a,e-i,t-s+a,e-i,t-s+r,e-i,6,!0),this.v.setTripleAt(t+s-a,e-i,t+s-r,e-i,t+s-a,e-i,7,!0)):(this.v.setTripleAt(t-s,e+i,t-s+r,e+i,t-s,e+i,2),this.v.setTripleAt(t-s,e-i,t-s,e-i+r,t-s,e-i,3))):(this.v.setTripleAt(t+s,e-i+a,t+s,e-i+r,t+s,e-i+a,0,!0),0!==a?(this.v.setTripleAt(t+s-a,e-i,t+s-a,e-i,t+s-r,e-i,1,!0),this.v.setTripleAt(t-s+a,e-i,t-s+r,e-i,t-s+a,e-i,2,!0),this.v.setTripleAt(t-s,e-i+a,t-s,e-i+a,t-s,e-i+r,3,!0),this.v.setTripleAt(t-s,e+i-a,t-s,e+i-r,t-s,e+i-a,4,!0),this.v.setTripleAt(t-s+a,e+i,t-s+a,e+i,t-s+r,e+i,5,!0),this.v.setTripleAt(t+s-a,e+i,t+s-r,e+i,t+s-a,e+i,6,!0),this.v.setTripleAt(t+s,e+i-a,t+s,e+i-a,t+s,e+i-r,7,!0)):(this.v.setTripleAt(t-s,e-i,t-s+r,e-i,t-s,e-i,1,!0),this.v.setTripleAt(t-s,e+i,t-s,e+i-r,t-s,e+i,2,!0),this.v.setTripleAt(t+s,e+i,t+s-r,e+i,t+s,e+i,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:i},r([bt],t),t}();var d={getShapeProp:function(t,e,s){var i;return 3===s||4===s?i=(3===s?e.pt:e.ks).k.length?new l(t,e,s):new o(t,e,s):5===s?i=new c(t,e):6===s?i=new p(t,e):7===s&&(i=new f(t,e)),i.k&&t.addDynamicProperty(i),i},getConstructorFunction:function(){return o},getKeyframedConstructorFunction:function(){return l}};return d}(),Ft=function(){var t=Math.cos,e=Math.sin,s=Math.tan,i=Math.round;function a(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function r(s){if(0===s)return this;var i=t(s),a=e(s);return this._t(i,-a,0,0,a,i,0,0,0,0,1,0,0,0,0,1)}function n(s){if(0===s)return this;var i=t(s),a=e(s);return this._t(1,0,0,0,0,i,-a,0,0,a,i,0,0,0,0,1)}function o(s){if(0===s)return this;var i=t(s),a=e(s);return this._t(i,0,a,0,0,1,0,0,-a,0,i,0,0,0,0,1)}function l(s){if(0===s)return this;var i=t(s),a=e(s);return this._t(i,-a,0,0,a,i,0,0,0,0,1,0,0,0,0,1)}function p(t,e){return this._t(1,e,t,1,0,0)}function f(t,e){return this.shear(s(t),s(e))}function c(i,a){var r=t(a),n=e(a);return this._t(r,n,0,0,-n,r,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,s(i),1,0,0,0,0,1,0,0,0,0,1)._t(r,-n,0,0,n,r,0,0,0,0,1,0,0,0,0,1)}function d(t,e,s){return s||0===s||(s=1),1===t&&1===e&&1===s?this:this._t(t,0,0,0,0,e,0,0,0,0,s,0,0,0,0,1)}function m(t,e,s,i,a,r,n,o,h,l,p,f,c,d,m,u){return this.props[0]=t,this.props[1]=e,this.props[2]=s,this.props[3]=i,this.props[4]=a,this.props[5]=r,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=l,this.props[10]=p,this.props[11]=f,this.props[12]=c,this.props[13]=d,this.props[14]=m,this.props[15]=u,this}function u(t,e,s){return s=s||0,0!==t||0!==e||0!==s?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,s,1):this}function g(t,e,s,i,a,r,n,o,h,l,p,f,c,d,m,u){var g=this.props;if(1===t&&0===e&&0===s&&0===i&&0===a&&1===r&&0===n&&0===o&&0===h&&0===l&&1===p&&0===f)return g[12]=g[12]*t+g[15]*c,g[13]=g[13]*r+g[15]*d,g[14]=g[14]*p+g[15]*m,g[15]*=u,this._identityCalculated=!1,this;var y=g[0],v=g[1],b=g[2],_=g[3],C=g[4],x=g[5],k=g[6],S=g[7],P=g[8],D=g[9],w=g[10],A=g[11],M=g[12],T=g[13],F=g[14],E=g[15];return g[0]=y*t+v*a+b*h+_*c,g[1]=y*e+v*r+b*l+_*d,g[2]=y*s+v*n+b*p+_*m,g[3]=y*i+v*o+b*f+_*u,g[4]=C*t+x*a+k*h+S*c,g[5]=C*e+x*r+k*l+S*d,g[6]=C*s+x*n+k*p+S*m,g[7]=C*i+x*o+k*f+S*u,g[8]=P*t+D*a+w*h+A*c,g[9]=P*e+D*r+w*l+A*d,g[10]=P*s+D*n+w*p+A*m,g[11]=P*i+D*o+w*f+A*u,g[12]=M*t+T*a+F*h+E*c,g[13]=M*e+T*r+F*l+E*d,g[14]=M*s+T*n+F*p+E*m,g[15]=M*i+T*o+F*f+E*u,this._identityCalculated=!1,this}function y(t){var e=t.props;return this.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}function v(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function b(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function _(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function C(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function x(t,e,s){return{x:t*this.props[0]+e*this.props[4]+s*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+s*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+s*this.props[10]+this.props[14]}}function k(t,e,s){return t*this.props[0]+e*this.props[4]+s*this.props[8]+this.props[12]}function S(t,e,s){return t*this.props[1]+e*this.props[5]+s*this.props[9]+this.props[13]}function P(t,e,s){return t*this.props[2]+e*this.props[6]+s*this.props[10]+this.props[14]}function D(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,s=-this.props[1]/t,i=-this.props[4]/t,a=this.props[0]/t,r=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,n=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,o=new Ft;return o.props[0]=e,o.props[1]=s,o.props[4]=i,o.props[5]=a,o.props[12]=r,o.props[13]=n,o}function w(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function A(t){var e,s=t.length,i=[];for(e=0;e<s;e+=1)i[e]=w(t[e]);return i}function M(t,e,s){var i=h("float32",6);if(this.isIdentity())i[0]=t[0],i[1]=t[1],i[2]=e[0],i[3]=e[1],i[4]=s[0],i[5]=s[1];else{var a=this.props[0],r=this.props[1],n=this.props[4],o=this.props[5],l=this.props[12],p=this.props[13];i[0]=t[0]*a+t[1]*n+l,i[1]=t[0]*r+t[1]*o+p,i[2]=e[0]*a+e[1]*n+l,i[3]=e[0]*r+e[1]*o+p,i[4]=s[0]*a+s[1]*n+l,i[5]=s[0]*r+s[1]*o+p}return i}function T(t,e,s){return this.isIdentity()?[t,e,s]:[t*this.props[0]+e*this.props[4]+s*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+s*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+s*this.props[10]+this.props[14]]}function F(t,e){if(this.isIdentity())return t+","+e;var s=this.props;return Math.round(100*(t*s[0]+e*s[4]+s[12]))/100+","+Math.round(100*(t*s[1]+e*s[5]+s[13]))/100}function E(){for(var t=0,e=this.props,s="matrix3d(";t<16;)s+=i(1e4*e[t])/1e4,s+=15===t?")":",",t+=1;return s}function L(t){return t<1e-6&&t>0||t>-1e-6&&t<0?i(1e4*t)/1e4:t}function I(){var t=this.props;return"matrix("+L(t[0])+","+L(t[1])+","+L(t[4])+","+L(t[5])+","+L(t[12])+","+L(t[13])+")"}return function(){this.reset=a,this.rotate=r,this.rotateX=n,this.rotateY=o,this.rotateZ=l,this.skew=f,this.skewFromAxis=c,this.shear=p,this.scale=d,this.setTransform=m,this.translate=u,this.transform=g,this.multiply=y,this.applyToPoint=x,this.applyToX=k,this.applyToY=S,this.applyToZ=P,this.applyToPointArray=T,this.applyToTriplePoints=M,this.applyToPointStringified=F,this.toCSS=E,this.to2dCSS=I,this.clone=_,this.cloneFromProps=C,this.equals=b,this.inversePoints=A,this.inversePoint=w,this.getInverseMatrix=D,this._t=this.transform,this.isIdentity=v,this._identity=!0,this._identityCalculated=!1,this.props=h("float32",16),this.reset()}}();function Et(t){return Et="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Et(t)}var Lt={},It="__[STANDALONE]__";function Rt(){$.searchAnimations()}Lt.play=$.play,Lt.pause=$.pause,Lt.setLocationHref=function(e){t=e},Lt.togglePause=$.togglePause,Lt.setSpeed=$.setSpeed,Lt.setDirection=$.setDirection,Lt.stop=$.stop,Lt.searchAnimations=Rt,Lt.registerAnimation=$.registerAnimation,Lt.loadAnimation=function(t){return $.loadAnimation(t)},Lt.setSubframeRendering=function(t){!function(t){f=!!t}(t)},Lt.resize=$.resize,Lt.goToAndStop=$.goToAndStop,Lt.destroy=$.destroy,Lt.setQuality=function(t){if("string"==typeof t)switch(t){case"high":B(200);break;default:case"medium":B(50);break;case"low":B(10)}else!isNaN(t)&&t>1&&B(t);W()>=50?S(!1):S(!0)},Lt.inBrowser=function(){return"undefined"!=typeof navigator},Lt.installPlugin=function(t,e){"expressions"===t&&(c=e)},Lt.freeze=$.freeze,Lt.unfreeze=$.unfreeze,Lt.setVolume=$.setVolume,Lt.mute=$.mute,Lt.unmute=$.unmute,Lt.getRegisteredAnimations=$.getRegisteredAnimations,Lt.useWebWorker=function(t){e=!!t},Lt.setIDPrefix=function(t){m=t},Lt.__getFactory=function(t){switch(t){case"propertyFactory":return vt;case"shapePropertyFactory":return Tt;case"matrix":return Ft;default:return null}},Lt.version="5.13.0";var Vt="";if(It){var zt=document.getElementsByTagName("script"),Ot=zt[zt.length-1]||{src:""};Vt=Ot.src?Ot.src.replace(/^[^\?]+\??/,""):"",function(t){for(var e=Vt.split("&"),s=0;s<e.length;s+=1){var i=e[s].split("=");if(decodeURIComponent(i[0])==t)return decodeURIComponent(i[1])}return null}("renderer")}var Nt=setInterval((function(){"complete"===document.readyState&&(clearInterval(Nt),Rt())}),100);try{"object"===("undefined"==typeof exports?"undefined":Et(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=Lt)}catch(t){}var qt=function(){var t={},e={};return t.registerModifier=function(t,s){e[t]||(e[t]=s)},t.getModifier=function(t,s,i){return new e[t](s,i)},t}();function Bt(){}function Wt(){}function jt(){}Bt.prototype.initModifierProperties=function(){},Bt.prototype.addShapeToModifier=function(){},Bt.prototype.addShape=function(t){if(!this.closed){t.sh.container.addDynamicProperty(t.sh);var e={shape:t.sh,data:t,localShapeCollection:Mt.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},Bt.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=s,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},Bt.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},r([bt],Bt),r([Bt],Wt),Wt.prototype.initModifierProperties=function(t,e){this.s=vt.getProp(t,e.s,0,.01,this),this.e=vt.getProp(t,e.e,0,.01,this),this.o=vt.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},Wt.prototype.addShapeToModifier=function(t){t.pathsData=[]},Wt.prototype.calculateShapeEdges=function(t,e,s,i,a){var r=[];e<=1?r.push({s:t,e:e}):t>=1?r.push({s:t-1,e:e-1}):(r.push({s:t,e:1}),r.push({s:0,e:e-1}));var n,o,h=[],l=r.length;for(n=0;n<l;n+=1){var p,f;if(!((o=r[n]).e*a<i||o.s*a>i+s))p=o.s*a<=i?0:(o.s*a-i)/s,f=o.e*a>=i+s?1:(o.e*a-i)/s,h.push([p,f])}return h.length||h.push([0,0]),h},Wt.prototype.releasePathsData=function(t){var e,s=t.length;for(e=0;e<s;e+=1)at.release(t[e]);return t.length=0,t},Wt.prototype.processShapes=function(t){var e,s,i,a;if(this._mdf||t){var r=this.o.v%360/360;if(r<0&&(r+=1),(e=this.s.v>1?1+r:this.s.v<0?0+r:this.s.v+r)>(s=this.e.v>1?1+r:this.e.v<0?0+r:this.e.v+r)){var n=e;e=s,s=n}e=1e-4*Math.round(1e4*e),s=1e-4*Math.round(1e4*s),this.sValue=e,this.eValue=s}else e=this.sValue,s=this.eValue;var o,h,l,p,f,c=this.shapes.length,d=0;if(s===e)for(a=0;a<c;a+=1)this.shapes[a].localShapeCollection.releaseShapes(),this.shapes[a].shape._mdf=!0,this.shapes[a].shape.paths=this.shapes[a].localShapeCollection,this._mdf&&(this.shapes[a].pathsData.length=0);else if(1===s&&0===e||0===s&&1===e){if(this._mdf)for(a=0;a<c;a+=1)this.shapes[a].pathsData.length=0,this.shapes[a].shape._mdf=!0}else{var m,u,g=[];for(a=0;a<c;a+=1)if((m=this.shapes[a]).shape._mdf||this._mdf||t||2===this.m){if(h=(i=m.shape.paths)._length,f=0,!m.shape._mdf&&m.pathsData.length)f=m.totalShapeLength;else{for(l=this.releasePathsData(m.pathsData),o=0;o<h;o+=1)p=rt.getSegmentsLength(i.shapes[o]),l.push(p),f+=p.totalLength;m.totalShapeLength=f,m.pathsData=l}d+=f,m.shape._mdf=!0}else m.shape.paths=m.localShapeCollection;var y,v=e,b=s,_=0;for(a=c-1;a>=0;a-=1)if((m=this.shapes[a]).shape._mdf){for((u=m.localShapeCollection).releaseShapes(),2===this.m&&c>1?(y=this.calculateShapeEdges(e,s,m.totalShapeLength,_,d),_+=m.totalShapeLength):y=[[v,b]],h=y.length,o=0;o<h;o+=1){v=y[o][0],b=y[o][1],g.length=0,b<=1?g.push({s:m.totalShapeLength*v,e:m.totalShapeLength*b}):v>=1?g.push({s:m.totalShapeLength*(v-1),e:m.totalShapeLength*(b-1)}):(g.push({s:m.totalShapeLength*v,e:m.totalShapeLength}),g.push({s:0,e:m.totalShapeLength*(b-1)}));var C=this.addShapes(m,g[0]);if(g[0].s!==g[0].e){if(g.length>1)if(m.shape.paths.shapes[m.shape.paths._length-1].c){var x=C.pop();this.addPaths(C,u),C=this.addShapes(m,g[1],x)}else this.addPaths(C,u),C=this.addShapes(m,g[1]);this.addPaths(C,u)}}m.shape.paths=u}}},Wt.prototype.addPaths=function(t,e){var s,i=t.length;for(s=0;s<i;s+=1)e.addShape(t[s])},Wt.prototype.addSegment=function(t,e,s,i,a,r,n){a.setXYAt(e[0],e[1],"o",r),a.setXYAt(s[0],s[1],"i",r+1),n&&a.setXYAt(t[0],t[1],"v",r),a.setXYAt(i[0],i[1],"v",r+1)},Wt.prototype.addSegmentFromArray=function(t,e,s,i){e.setXYAt(t[1],t[5],"o",s),e.setXYAt(t[2],t[6],"i",s+1),i&&e.setXYAt(t[0],t[4],"v",s),e.setXYAt(t[3],t[7],"v",s+1)},Wt.prototype.addShapes=function(t,e,s){var i,a,r,n,o,h,l,p,f=t.pathsData,c=t.shape.paths.shapes,d=t.shape.paths._length,m=0,u=[],g=!0;for(s?(o=s._length,p=s._length):(s=kt.newElement(),o=0,p=0),u.push(s),i=0;i<d;i+=1){for(h=f[i].lengths,s.c=c[i].c,r=c[i].c?h.length:h.length+1,a=1;a<r;a+=1)if(m+(n=h[a-1]).addedLength<e.s)m+=n.addedLength,s.c=!1;else{if(m>e.e){s.c=!1;break}e.s<=m&&e.e>=m+n.addedLength?(this.addSegment(c[i].v[a-1],c[i].o[a-1],c[i].i[a],c[i].v[a],s,o,g),g=!1):(l=rt.getNewSegment(c[i].v[a-1],c[i].v[a],c[i].o[a-1],c[i].i[a],(e.s-m)/n.addedLength,(e.e-m)/n.addedLength,h[a-1]),this.addSegmentFromArray(l,s,o,g),g=!1,s.c=!1),m+=n.addedLength,o+=1}if(c[i].c&&h.length){if(n=h[a-1],m<=e.e){var y=h[a-1].addedLength;e.s<=m&&e.e>=m+y?(this.addSegment(c[i].v[a-1],c[i].o[a-1],c[i].i[0],c[i].v[0],s,o,g),g=!1):(l=rt.getNewSegment(c[i].v[a-1],c[i].v[0],c[i].o[a-1],c[i].i[0],(e.s-m)/y,(e.e-m)/y,h[a-1]),this.addSegmentFromArray(l,s,o,g),g=!1,s.c=!1)}else s.c=!1;m+=n.addedLength,o+=1}if(s._length&&(s.setXYAt(s.v[p][0],s.v[p][1],"i",p),s.setXYAt(s.v[s._length-1][0],s.v[s._length-1][1],"o",s._length-1)),m>e.e)break;i<d-1&&(s=kt.newElement(),g=!0,u.push(s),o=0)}return u},r([Bt],jt),jt.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=vt.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},jt.prototype.processPath=function(t,e){var s=e/100,i=[0,0],a=t._length,r=0;for(r=0;r<a;r+=1)i[0]+=t.v[r][0],i[1]+=t.v[r][1];i[0]/=a,i[1]/=a;var n,o,h,l,p,f,c=kt.newElement();for(c.c=t.c,r=0;r<a;r+=1)n=t.v[r][0]+(i[0]-t.v[r][0])*s,o=t.v[r][1]+(i[1]-t.v[r][1])*s,h=t.o[r][0]+(i[0]-t.o[r][0])*-s,l=t.o[r][1]+(i[1]-t.o[r][1])*-s,p=t.i[r][0]+(i[0]-t.i[r][0])*-s,f=t.i[r][1]+(i[1]-t.i[r][1])*-s,c.setTripleAt(n,o,h,l,p,f,r);return c},jt.prototype.processShapes=function(t){var e,s,i,a,r,n,o=this.shapes.length,h=this.amount.v;if(0!==h)for(s=0;s<o;s+=1){if(n=(r=this.shapes[s]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,i=0;i<a;i+=1)n.addShape(this.processPath(e[i],h));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var Yt=function(){var t=[0,0];function e(t,e,s){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Ft,this.pre=new Ft,this.appliedTransformations=0,this.initDynamicPropertyContainer(s||t),e.p&&e.p.s?(this.px=vt.getProp(t,e.p.x,0,0,this),this.py=vt.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=vt.getProp(t,e.p.z,0,0,this))):this.p=vt.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=vt.getProp(t,e.rx,0,x,this),this.ry=vt.getProp(t,e.ry,0,x,this),this.rz=vt.getProp(t,e.rz,0,x,this),e.or.k[0].ti){var i,a=e.or.k.length;for(i=0;i<a;i+=1)e.or.k[i].to=null,e.or.k[i].ti=null}this.or=vt.getProp(t,e.or,1,x,this),this.or.sh=!0}else this.r=vt.getProp(t,e.r||{k:0},0,x,this);e.sk&&(this.sk=vt.getProp(t,e.sk,0,x,this),this.sa=vt.getProp(t,e.sa,0,x,this)),this.a=vt.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=vt.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=vt.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return e.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(e){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||e){var s;if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var i,a;if(s=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime)this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(i=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/s,0),a=this.p.getValueAtTime(this.p.keyframes[0].t/s,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(i=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/s,0),a=this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/s,0)):(i=this.p.pv,a=this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/s,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){i=[],a=[];var r=this.px,n=this.py;r._caching.lastFrame+r.offsetTime<=r.keyframes[0].t?(i[0]=r.getValueAtTime((r.keyframes[0].t+.01)/s,0),i[1]=n.getValueAtTime((n.keyframes[0].t+.01)/s,0),a[0]=r.getValueAtTime(r.keyframes[0].t/s,0),a[1]=n.getValueAtTime(n.keyframes[0].t/s,0)):r._caching.lastFrame+r.offsetTime>=r.keyframes[r.keyframes.length-1].t?(i[0]=r.getValueAtTime(r.keyframes[r.keyframes.length-1].t/s,0),i[1]=n.getValueAtTime(n.keyframes[n.keyframes.length-1].t/s,0),a[0]=r.getValueAtTime((r.keyframes[r.keyframes.length-1].t-.01)/s,0),a[1]=n.getValueAtTime((n.keyframes[n.keyframes.length-1].t-.01)/s,0)):(i=[r.pv,n.pv],a[0]=r.getValueAtTime((r._caching.lastFrame+r.offsetTime-.01)/s,r.offsetTime),a[1]=n.getValueAtTime((n._caching.lastFrame+n.offsetTime-.01)/s,n.offsetTime))}else i=a=t;this.v.rotate(-Math.atan2(i[1]-a[1],i[0]-a[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},r([bt],e),e.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},e.prototype._addDynamicProperty=bt.prototype.addDynamicProperty,{getTransformProperty:function(t,s,i){return new e(t,s,i)}}}();function Jt(){}function Ht(){}function Gt(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function Xt(t){return Math.abs(t)<=1e-5}function Kt(t,e,s){return t*(1-s)+e*s}function Ut(t,e,s){return[Kt(t[0],e[0],s),Kt(t[1],e[1],s)]}function Zt(t,e,s,i){return[3*e-t-3*s+i,3*t-6*e+3*s,-3*t+3*e,t]}function Qt(t){return new $t(t,t,t,t,!1)}function $t(t,e,s,i,a){a&&he(t,e)&&(e=Ut(t,i,1/3)),a&&he(s,i)&&(s=Ut(t,i,2/3));var r=Zt(t[0],e[0],s[0],i[0]),n=Zt(t[1],e[1],s[1],i[1]);this.a=[r[0],n[0]],this.b=[r[1],n[1]],this.c=[r[2],n[2]],this.d=[r[3],n[3]],this.points=[t,e,s,i]}function te(t,e){var s=t.points[0][e],i=t.points[t.points.length-1][e];if(s>i){var a=i;i=s,s=a}for(var r=function(t,e,s){if(0===t)return[];var i=e*e-4*t*s;if(i<0)return[];var a=-e/(2*t);if(0===i)return[a];var r=Math.sqrt(i)/(2*t);return[a-r,a+r]}(3*t.a[e],2*t.b[e],t.c[e]),n=0;n<r.length;n+=1)if(r[n]>0&&r[n]<1){var o=t.point(r[n])[e];o<s?s=o:o>i&&(i=o)}return{min:s,max:i}}function ee(t,e,s){var i=t.boundingBox();return{cx:i.cx,cy:i.cy,width:i.width,height:i.height,bez:t,t:(e+s)/2,t1:e,t2:s}}function se(t){var e=t.bez.split(.5);return[ee(e[0],t.t1,t.t),ee(e[1],t.t,t.t2)]}function ie(t,e,s,i,a,r){var n,o;if(n=t,o=e,2*Math.abs(n.cx-o.cx)<n.width+o.width&&2*Math.abs(n.cy-o.cy)<n.height+o.height)if(s>=r||t.width<=i&&t.height<=i&&e.width<=i&&e.height<=i)a.push([t.t,e.t]);else{var h=se(t),l=se(e);ie(h[0],l[0],s+1,i,a,r),ie(h[0],l[1],s+1,i,a,r),ie(h[1],l[0],s+1,i,a,r),ie(h[1],l[1],s+1,i,a,r)}}function ae(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function re(t,e,s,i){var a=[t[0],t[1],1],r=[e[0],e[1],1],n=[s[0],s[1],1],o=[i[0],i[1],1],h=ae(ae(a,r),ae(n,o));return Xt(h[2])?null:[h[0]/h[2],h[1]/h[2]]}function ne(t,e,s){return[t[0]+Math.cos(e)*s,t[1]-Math.sin(e)*s]}function oe(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function he(t,e){return Gt(t[0],e[0])&&Gt(t[1],e[1])}function le(){}function pe(t,e,s,i,a,r,n){var o=s-Math.PI/2,h=s+Math.PI/2,l=e[0]+Math.cos(s)*i*a,p=e[1]-Math.sin(s)*i*a;t.setTripleAt(l,p,l+Math.cos(o)*r,p-Math.sin(o)*r,l+Math.cos(h)*n,p-Math.sin(h)*n,t.length())}function fe(t,e){var s,i,a,r,n=0===e?t.length()-1:e-1,o=(e+1)%t.length(),h=t.v[n],l=t.v[o],p=(s=h,a=[(i=l)[0]-s[0],i[1]-s[1]],r=.5*-Math.PI,[Math.cos(r)*a[0]-Math.sin(r)*a[1],Math.sin(r)*a[0]+Math.cos(r)*a[1]]);return Math.atan2(0,1)-Math.atan2(p[1],p[0])}function ce(t,e,s,i,a,r,n){var o=fe(e,s),h=e.v[s%e._length],l=e.v[0===s?e._length-1:s-1],p=e.v[(s+1)%e._length],f=2===r?Math.sqrt(Math.pow(h[0]-l[0],2)+Math.pow(h[1]-l[1],2)):0,c=2===r?Math.sqrt(Math.pow(h[0]-p[0],2)+Math.pow(h[1]-p[1],2)):0;pe(t,e.v[s%e._length],o,n,i,c/(2*(a+1)),f/(2*(a+1)))}function de(t,e,s,i,a,r){for(var n=0;n<i;n+=1){var o=(n+1)/(i+1),h=2===a?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(o);pe(t,e.point(o),l,r,s,h/(2*(i+1)),h/(2*(i+1))),r=-r}return r}function me(t,e,s){var i=Math.atan2(e[0]-t[0],e[1]-t[1]);return[ne(t,i,s),ne(e,i,s)]}function ue(t,e){var s,i,a,r,n,o,h;s=(h=me(t.points[0],t.points[1],e))[0],i=h[1],a=(h=me(t.points[1],t.points[2],e))[0],r=h[1],n=(h=me(t.points[2],t.points[3],e))[0],o=h[1];var l=re(s,i,a,r);null===l&&(l=i);var p=re(n,o,a,r);return null===p&&(p=n),new $t(s,l,p,o)}function ge(t,e,s,i,a){var r=e.points[3],n=s.points[0];if(3===i)return r;if(he(r,n))return r;if(2===i){var o=-e.tangentAngle(1),h=-s.tangentAngle(0)+Math.PI,l=re(r,ne(r,o+Math.PI/2,100),n,ne(n,o+Math.PI/2,100)),p=l?oe(l,r):oe(r,n)/2,f=ne(r,o,2*p*k);return t.setXYAt(f[0],f[1],"o",t.length()-1),f=ne(n,h,2*p*k),t.setTripleAt(n[0],n[1],n[0],n[1],f[0],f[1],t.length()),n}var c=re(he(r,e.points[2])?e.points[0]:e.points[2],r,n,he(n,s.points[1])?s.points[3]:s.points[1]);return c&&oe(c,r)<a?(t.setTripleAt(c[0],c[1],c[0],c[1],c[0],c[1],t.length()),c):r}function ye(t,e){var s=t.intersections(e);return s.length&&Gt(s[0][0],1)&&s.shift(),s.length?s[0]:null}function ve(t,e){var s=t.slice(),i=e.slice(),a=ye(t[t.length-1],e[0]);return a&&(s[t.length-1]=t[t.length-1].split(a[0])[0],i[0]=e[0].split(a[1])[1]),t.length>1&&e.length>1&&(a=ye(t[0],e[e.length-1]))?[[t[0].split(a[0])[0]],[e[e.length-1].split(a[1])[1]]]:[s,i]}function be(t,e){var s,i,a,r,n=t.inflectionPoints();if(0===n.length)return[ue(t,e)];if(1===n.length||Gt(n[1],1))return s=(a=t.split(n[0]))[0],i=a[1],[ue(s,e),ue(i,e)];s=(a=t.split(n[0]))[0];var o=(n[1]-n[0])/(1-n[0]);return r=(a=a[1].split(o))[0],i=a[1],[ue(s,e),ue(r,e),ue(i,e)]}function _e(){}function Ce(t){for(var e=t.fStyle?t.fStyle.split(" "):[],s="normal",i="normal",a=e.length,r=0;r<a;r+=1)switch(e[r].toLowerCase()){case"italic":i="italic";break;case"bold":s="700";break;case"black":s="900";break;case"medium":s="500";break;case"regular":case"normal":s="400";break;case"light":case"thin":s="200"}return{style:i,weight:t.fWeight||s}}r([Bt],Jt),Jt.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=vt.getProp(t,e.c,0,null,this),this.o=vt.getProp(t,e.o,0,null,this),this.tr=Yt.getTransformProperty(t,e.tr,this),this.so=vt.getProp(t,e.tr.so,0,.01,this),this.eo=vt.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Ft,this.rMatrix=new Ft,this.sMatrix=new Ft,this.tMatrix=new Ft,this.matrix=new Ft},Jt.prototype.applyTransforms=function(t,e,s,i,a,r){var n=r?-1:1,o=i.s.v[0]+(1-i.s.v[0])*(1-a),h=i.s.v[1]+(1-i.s.v[1])*(1-a);t.translate(i.p.v[0]*n*a,i.p.v[1]*n*a,i.p.v[2]),e.translate(-i.a.v[0],-i.a.v[1],i.a.v[2]),e.rotate(-i.r.v*n*a),e.translate(i.a.v[0],i.a.v[1],i.a.v[2]),s.translate(-i.a.v[0],-i.a.v[1],i.a.v[2]),s.scale(r?1/o:o,r?1/h:h),s.translate(i.a.v[0],i.a.v[1],i.a.v[2])},Jt.prototype.init=function(t,e,s,i){for(this.elem=t,this.arr=e,this.pos=s,this.elemsData=i,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[s]);s>0;)s-=1,this._elements.unshift(e[s]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},Jt.prototype.resetElements=function(t){var e,s=t.length;for(e=0;e<s;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},Jt.prototype.cloneElements=function(t){var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},Jt.prototype.changeGroupRender=function(t,e){var s,i=t.length;for(s=0;s<i;s+=1)t[s]._render=e,"gr"===t[s].ty&&this.changeGroupRender(t[s].it,e)},Jt.prototype.processShapes=function(t){var e,s,i,a,r,n=!1;if(this._mdf||t){var o,h=Math.ceil(this.c.v);if(this._groups.length<h){for(;this._groups.length<h;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(r=0,i=0;i<=this._groups.length-1;i+=1){if(o=r<h,this._groups[i]._render=o,this.changeGroupRender(this._groups[i].it,o),!o){var p=this.elemsData[i].it,f=p[p.length-1];0!==f.transform.op.v?(f.transform.op._mdf=!0,f.transform.op.v=0):f.transform.op._mdf=!1}r+=1}this._currentCopies=h;var c=this.o.v,d=c%1,m=c>0?Math.floor(c):Math.ceil(c),u=this.pMatrix.props,g=this.rMatrix.props,y=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var v,b,_=0;if(c>0){for(;_<m;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),_+=1;d&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,d,!1),_+=d)}else if(c<0){for(;_>m;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),_-=1;d&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-d,!0),_-=d)}for(i=1===this.data.m?0:this._currentCopies-1,a=1===this.data.m?1:-1,r=this._currentCopies;r;){if(b=(s=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(i/(this._currentCopies-1)),0!==_){for((0!==i&&1===a||i!==this._currentCopies-1&&-1===a)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]),v=0;v<b;v+=1)s[v]=this.matrix.props[v];this.matrix.reset()}else for(this.matrix.reset(),v=0;v<b;v+=1)s[v]=this.matrix.props[v];_+=1,r-=1,i+=a}}else for(r=this._currentCopies,i=0,a=1;r;)s=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,r-=1,i+=a;return n},Jt.prototype.addShape=function(){},r([Bt],Ht),Ht.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=vt.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},Ht.prototype.processPath=function(t,e){var s,i=kt.newElement();i.c=t.c;var a,r,n,o,h,l,p,f,c,d,m,u,g=t._length,y=0;for(s=0;s<g;s+=1)a=t.v[s],n=t.o[s],r=t.i[s],a[0]===n[0]&&a[1]===n[1]&&a[0]===r[0]&&a[1]===r[1]?0!==s&&s!==g-1||t.c?(o=0===s?t.v[g-1]:t.v[s-1],l=(h=Math.sqrt(Math.pow(a[0]-o[0],2)+Math.pow(a[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=m=a[0]+(o[0]-a[0])*l,f=u=a[1]-(a[1]-o[1])*l,c=p-(p-a[0])*k,d=f-(f-a[1])*k,i.setTripleAt(p,f,c,d,m,u,y),y+=1,o=s===g-1?t.v[0]:t.v[s+1],l=(h=Math.sqrt(Math.pow(a[0]-o[0],2)+Math.pow(a[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=c=a[0]+(o[0]-a[0])*l,f=d=a[1]+(o[1]-a[1])*l,m=p-(p-a[0])*k,u=f-(f-a[1])*k,i.setTripleAt(p,f,c,d,m,u,y),y+=1):(i.setTripleAt(a[0],a[1],n[0],n[1],r[0],r[1],y),y+=1):(i.setTripleAt(t.v[s][0],t.v[s][1],t.o[s][0],t.o[s][1],t.i[s][0],t.i[s][1],y),y+=1);return i},Ht.prototype.processShapes=function(t){var e,s,i,a,r,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(s=0;s<o;s+=1){if(n=(r=this.shapes[s]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,i=0;i<a;i+=1)n.addShape(this.processPath(e[i],h));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},$t.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},$t.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},$t.prototype.tangentAngle=function(t){var e=this.derivative(t);return Math.atan2(e[1],e[0])},$t.prototype.normalAngle=function(t){var e=this.derivative(t);return Math.atan2(e[0],e[1])},$t.prototype.inflectionPoints=function(){var t=this.a[1]*this.b[0]-this.a[0]*this.b[1];if(Xt(t))return[];var e=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/t,s=e*e-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/t;if(s<0)return[];var i=Math.sqrt(s);return Xt(i)?i>0&&i<1?[e]:[]:[e-i,e+i].filter((function(t){return t>0&&t<1}))},$t.prototype.split=function(t){if(t<=0)return[Qt(this.points[0]),this];if(t>=1)return[this,Qt(this.points[this.points.length-1])];var e=Ut(this.points[0],this.points[1],t),s=Ut(this.points[1],this.points[2],t),i=Ut(this.points[2],this.points[3],t),a=Ut(e,s,t),r=Ut(s,i,t),n=Ut(a,r,t);return[new $t(this.points[0],e,a,n,!0),new $t(n,r,i,this.points[3],!0)]},$t.prototype.bounds=function(){return{x:te(this,0),y:te(this,1)}},$t.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},$t.prototype.intersections=function(t,e,s){void 0===e&&(e=2),void 0===s&&(s=7);var i=[];return ie(ee(this,0,1),ee(t,0,1),0,e,i,s),i},$t.shapeSegment=function(t,e){var s=(e+1)%t.length();return new $t(t.v[e],t.o[e],t.i[s],t.v[s],!0)},$t.shapeSegmentInverted=function(t,e){var s=(e+1)%t.length();return new $t(t.v[s],t.i[s],t.o[e],t.v[e],!0)},r([Bt],le),le.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=vt.getProp(t,e.s,0,null,this),this.frequency=vt.getProp(t,e.r,0,null,this),this.pointsType=vt.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},le.prototype.processPath=function(t,e,s,i){var a=t._length,r=kt.newElement();if(r.c=t.c,t.c||(a-=1),0===a)return r;var n=-1,o=$t.shapeSegment(t,0);ce(r,t,0,e,s,i,n);for(var h=0;h<a;h+=1)n=de(r,o,e,s,i,-n),o=h!==a-1||t.c?$t.shapeSegment(t,(h+1)%a):null,ce(r,t,h+1,e,s,i,n);return r},le.prototype.processShapes=function(t){var e,s,i,a,r,n,o=this.shapes.length,h=this.amplitude.v,l=Math.max(0,Math.round(this.frequency.v)),p=this.pointsType.v;if(0!==h)for(s=0;s<o;s+=1){if(n=(r=this.shapes[s]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,i=0;i<a;i+=1)n.addShape(this.processPath(e[i],h,l,p));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},r([Bt],_e),_e.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=vt.getProp(t,e.a,0,null,this),this.miterLimit=vt.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},_e.prototype.processPath=function(t,e,s,i){var a=kt.newElement();a.c=t.c;var r,n,o,h=t.length();t.c||(h-=1);var l=[];for(r=0;r<h;r+=1)o=$t.shapeSegment(t,r),l.push(be(o,e));if(!t.c)for(r=h-1;r>=0;r-=1)o=$t.shapeSegmentInverted(t,r),l.push(be(o,e));l=function(t){for(var e,s=1;s<t.length;s+=1)e=ve(t[s-1],t[s]),t[s-1]=e[0],t[s]=e[1];return t.length>1&&(e=ve(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}(l);var p=null,f=null;for(r=0;r<l.length;r+=1){var c=l[r];for(f&&(p=ge(a,f,c[0],s,i)),f=c[c.length-1],n=0;n<c.length;n+=1)o=c[n],p&&he(o.points[0],p)?a.setXYAt(o.points[1][0],o.points[1][1],"o",a.length()-1):a.setTripleAt(o.points[0][0],o.points[0][1],o.points[1][0],o.points[1][1],o.points[0][0],o.points[0][1],a.length()),a.setTripleAt(o.points[3][0],o.points[3][1],o.points[3][0],o.points[3][1],o.points[2][0],o.points[2][1],a.length()),p=o.points[3]}return l.length&&ge(a,f,l[0][0],s,i),a},_e.prototype.processShapes=function(t){var e,s,i,a,r,n,o=this.shapes.length,h=this.amount.v,l=this.miterLimit.v,p=this.lineJoin;if(0!==h)for(s=0;s<o;s+=1){if(n=(r=this.shapes[s]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,i=0;i<a;i+=1)n.addShape(this.processPath(e[i],h,p,l));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var xe=function(){var t={w:0,size:0,shapes:[],data:{shapes:[]}},e=[];e=e.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);var s=127988,i=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function r(t,e){var s=a("span");s.setAttribute("aria-hidden",!0),s.style.fontFamily=e;var i=a("span");i.innerText="giItT1WQy@!-/#",s.style.position="absolute",s.style.left="-10000px",s.style.top="-10000px",s.style.fontSize="300px",s.style.fontVariant="normal",s.style.fontStyle="normal",s.style.fontWeight="normal",s.style.letterSpacing="0",s.appendChild(i),document.body.appendChild(s);var r=i.offsetWidth;return i.style.fontFamily=function(t){var e,s=t.split(","),i=s.length,a=[];for(e=0;e<i;e+=1)"sans-serif"!==s[e]&&"monospace"!==s[e]&&a.push(s[e]);return a.join(",")}(t)+", "+e,{node:i,w:r,parent:s}}function n(t,e){var s,i=document.body&&e?"svg":"canvas",a=Ce(t);if("svg"===i){var r=j("text");r.style.fontSize="100px",r.setAttribute("font-family",t.fFamily),r.setAttribute("font-style",a.style),r.setAttribute("font-weight",a.weight),r.textContent="1",t.fClass?(r.style.fontFamily="inherit",r.setAttribute("class",t.fClass)):r.style.fontFamily=t.fFamily,e.appendChild(r),s=r}else{var n=new OffscreenCanvas(500,500).getContext("2d");n.font=a.style+" "+a.weight+" 100px "+t.fFamily,s=n}return{measureText:function(t){return"svg"===i?(s.textContent=t,s.getComputedTextLength()):s.measureText(t).width}}}function o(t){var e=0,s=t.charCodeAt(0);if(s>=55296&&s<=56319){var i=t.charCodeAt(1);i>=56320&&i<=57343&&(e=1024*(s-55296)+i-56320+65536)}return e}function h(t){var e=o(t);return e>=127462&&e<=127487}var l=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)};l.isModifier=function(t,e){var s=t.toString(16)+e.toString(16);return-1!==i.indexOf(s)},l.isZeroWidthJoiner=function(t){return 8205===t},l.isFlagEmoji=function(t){return h(t.substr(0,2))&&h(t.substr(2,2))},l.isRegionalCode=h,l.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},l.isRegionalFlag=function(t,e){var i=o(t.substr(e,2));if(i!==s)return!1;var a=0;for(e+=2;a<5;){if((i=o(t.substr(e,2)))<917601||i>917626)return!1;a+=1,e+=2}return 917631===o(t.substr(e,2))},l.isVariationSelector=function(t){return 65039===t},l.BLACK_FLAG_CODE_POINT=s;var p={addChars:function(t){if(t){var e;this.chars||(this.chars=[]);var s,i,a=t.length,r=this.chars.length;for(e=0;e<a;e+=1){for(s=0,i=!1;s<r;)this.chars[s].style===t[e].style&&this.chars[s].fFamily===t[e].fFamily&&this.chars[s].ch===t[e].ch&&(i=!0),s+=1;i||(this.chars.push(t[e]),r+=1)}}},addFonts:function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);if(!document.body)return this.isLoaded=!0,t.list.forEach((function(t){t.helper=n(t),t.cache={}})),void(this.fonts=t.list);var s,i=t.list,o=i.length,h=o;for(s=0;s<o;s+=1){var l,p,f=!0;if(i[s].loaded=!1,i[s].monoCase=r(i[s].fFamily,"monospace"),i[s].sansCase=r(i[s].fFamily,"sans-serif"),i[s].fPath){if("p"===i[s].fOrigin||3===i[s].origin){if((l=document.querySelectorAll('style[f-forigin="p"][f-family="'+i[s].fFamily+'"], style[f-origin="3"][f-family="'+i[s].fFamily+'"]')).length>0&&(f=!1),f){var c=a("style");c.setAttribute("f-forigin",i[s].fOrigin),c.setAttribute("f-origin",i[s].origin),c.setAttribute("f-family",i[s].fFamily),c.type="text/css",c.innerText="@font-face {font-family: "+i[s].fFamily+"; font-style: normal; src: url('"+i[s].fPath+"');}",e.appendChild(c)}}else if("g"===i[s].fOrigin||1===i[s].origin){for(l=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),p=0;p<l.length;p+=1)-1!==l[p].href.indexOf(i[s].fPath)&&(f=!1);if(f){var d=a("link");d.setAttribute("f-forigin",i[s].fOrigin),d.setAttribute("f-origin",i[s].origin),d.type="text/css",d.rel="stylesheet",d.href=i[s].fPath,document.body.appendChild(d)}}else if("t"===i[s].fOrigin||2===i[s].origin){for(l=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),p=0;p<l.length;p+=1)i[s].fPath===l[p].src&&(f=!1);if(f){var m=a("link");m.setAttribute("f-forigin",i[s].fOrigin),m.setAttribute("f-origin",i[s].origin),m.setAttribute("rel","stylesheet"),m.setAttribute("href",i[s].fPath),e.appendChild(m)}}}else i[s].loaded=!0,h-=1;i[s].helper=n(i[s],e),i[s].cache={},this.fonts.push(i[s])}0===h?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},getCharData:function(e,s,i){for(var a=0,r=this.chars.length;a<r;){if(this.chars[a].ch===e&&this.chars[a].style===s&&this.chars[a].fFamily===i)return this.chars[a];a+=1}return("string"==typeof e&&13!==e.charCodeAt(0)||!e)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",e,s,i)),t},getFontByName:function(t){for(var e=0,s=this.fonts.length;e<s;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,s){var i=this.getFontByName(e),a=t;if(!i.cache[a]){var r=i.helper;if(" "===t){var n=r.measureText("|"+t+"|"),o=r.measureText("||");i.cache[a]=(n-o)/100}else i.cache[a]=r.measureText(t)/100}return i.cache[a]*s},checkLoadedFonts:function(){var t,e,s,i=this.fonts.length,a=i;for(t=0;t<i;t+=1)this.fonts[t].loaded?a-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,s=this.fonts[t].monoCase.w,e.offsetWidth!==s?(a-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,s=this.fonts[t].sansCase.w,e.offsetWidth!==s&&(a-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==a&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}};return l.prototype=p,l}();function ke(t){this.animationData=t}function Se(){}ke.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},Se.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var Pe,De=(Pe={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return Pe[t]||""});function we(t,e,s){this.p=vt.getProp(e,t.v,0,0,s)}function Ae(t,e,s){this.p=vt.getProp(e,t.v,0,0,s)}function Me(t,e,s){this.p=vt.getProp(e,t.v,1,0,s)}function Te(t,e,s){this.p=vt.getProp(e,t.v,1,0,s)}function Fe(t,e,s){this.p=vt.getProp(e,t.v,0,0,s)}function Ee(t,e,s){this.p=vt.getProp(e,t.v,0,0,s)}function Le(t,e,s){this.p=vt.getProp(e,t.v,0,0,s)}function Ie(){this.p={}}function Re(t,e){var s,i=t.ef||[];this.effectElements=[];var a,r=i.length;for(s=0;s<r;s+=1)a=new Ve(i[s],e),this.effectElements.push(a)}function Ve(t,e){this.init(t,e)}function ze(){}function Oe(){}function Ne(t,e,s){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,s)}function qe(t,e,s){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,s),this._isPlaying=!1,this._canPlay=!1;var i=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(i),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?vt.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=vt.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function Be(){}r([bt],Ve),Ve.prototype.getValue=Ve.prototype.iterateDynamicProperties,Ve.prototype.init=function(t,e){var s;this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var i,a=this.data.ef.length,r=this.data.ef;for(s=0;s<a;s+=1){switch(i=null,r[s].ty){case 0:i=new we(r[s],e,this);break;case 1:i=new Ae(r[s],e,this);break;case 2:i=new Me(r[s],e,this);break;case 3:i=new Te(r[s],e,this);break;case 4:case 7:i=new Le(r[s],e,this);break;case 10:i=new Fe(r[s],e,this);break;case 11:i=new Ee(r[s],e,this);break;case 5:i=new Re(r[s],e,this);break;default:i=new Ie(r[s],e,this)}i&&this.effectElements.push(i)}},ze.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t=q();if(t){var e=t("layer"),s=t("effects"),i=t("shape"),a=t("text"),r=t("comp");this.layerInterface=e(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var n=s.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(n),0===this.data.ty||this.data.xt?this.compInterface=r(this):4===this.data.ty?(this.layerInterface.shapeInterface=i(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=a(this),this.layerInterface.text=this.layerInterface.textInterface)}},setBlendMode:function(){var t=De(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,s){this.globalData=e,this.comp=s,this.data=t,this.layerId=L(),this.data.sr||(this.data.sr=1),this.effectsManager=new Re(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},Oe.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var s,i=this.dynamicProperties.length;for(s=0;s<i;s+=1)(e||this._isParent&&"transform"===this.dynamicProperties[s].propType)&&(this.dynamicProperties[s].getValue(),this.dynamicProperties[s]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},Ne.prototype.prepareFrame=function(){},r([Se,ze,Oe],Ne),Ne.prototype.getBaseElement=function(){return null},Ne.prototype.renderFrame=function(){},Ne.prototype.destroy=function(){},Ne.prototype.initExpressions=function(){var t=q();if(t){var e=t("footage");this.layerInterface=e(this)}},Ne.prototype.getFootageData=function(){return this.footageData},qe.prototype.prepareFrame=function(t){if(this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder)this._currentTime=t/this.data.sr;else{var e=this.tm.v;this._currentTime=e}this._volume=this.lv.v[0];var s=this._volume*this._volumeMultiplier;this._previousVolume!==s&&(this._previousVolume=s,this.audio.volume(s))},r([Se,ze,Oe],qe),qe.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek())>.1)&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},qe.prototype.show=function(){},qe.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},qe.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},qe.prototype.resume=function(){this._canPlay=!0},qe.prototype.setRate=function(t){this.audio.rate(t)},qe.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},qe.prototype.getBaseElement=function(){return null},qe.prototype.destroy=function(){},qe.prototype.sourceRectAtTime=function(){},qe.prototype.initExpressions=function(){},Be.prototype.checkLayers=function(t){var e,s,i=this.layers.length;for(this.completeLayers=!0,e=i-1;e>=0;e-=1)this.elements[e]||(s=this.layers[e]).ip-s.st<=t-this.layers[e].st&&s.op-s.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},Be.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:default:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t)}},Be.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},Be.prototype.createAudio=function(t){return new qe(t,this.globalData,this)},Be.prototype.createFootage=function(t){return new Ne(t,this.globalData,this)},Be.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},Be.prototype.includeLayers=function(t){var e;this.completeLayers=!1;var s,i=t.length,a=this.layers.length;for(e=0;e<i;e+=1)for(s=0;s<a;){if(this.layers[s].id===t[e].id){this.layers[s]=t[e];break}s+=1}},Be.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},Be.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},Be.prototype.buildElementParenting=function(t,e,s){for(var i=this.elements,a=this.layers,r=0,n=a.length;r<n;)a[r].ind==e&&(i[r]&&!0!==i[r]?(s.push(i[r]),i[r].setAsParent(),void 0!==a[r].parent?this.buildElementParenting(t,a[r].parent,s):t.setHierarchy(s)):(this.buildItem(r),this.addPendingElement(t))),r+=1},Be.prototype.addPendingElement=function(t){this.pendingElements.push(t)},Be.prototype.searchExtraCompositions=function(t){var e,s=t.length;for(e=0;e<s;e+=1)if(t[e].xt){var i=this.createComp(t[e]);i.initExpressions(),this.globalData.projectInterface.registerComposition(i)}},Be.prototype.getElementById=function(t){var e,s=this.elements.length;for(e=0;e<s;e+=1)if(this.elements[e].data.ind===t)return this.elements[e];return null},Be.prototype.getElementByPath=function(t){var e,s=t.shift();if("number"==typeof s)e=this.elements[s];else{var i,a=this.elements.length;for(i=0;i<a;i+=1)if(this.elements[i].data.nm===s){e=this.elements[i];break}}return 0===t.length?e:e.getElementByPath(t)},Be.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new xe,this.globalData.slotManager=function(t){return new ke(t)}(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var We="transformEFfect";function je(){}function Ye(t,e,s){this.data=t,this.element=e,this.globalData=s,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var a,r,n=this.globalData.defs,o=this.masksProperties?this.masksProperties.length:0;this.viewData=l(o),this.solidPath="";var h,p,f,c,d,m,u=this.masksProperties,g=0,y=[],v=L(),b="clipPath",_="clip-path";for(a=0;a<o;a+=1)if(("a"!==u[a].mode&&"n"!==u[a].mode||u[a].inv||100!==u[a].o.k||u[a].o.x)&&(b="mask",_="mask"),"s"!==u[a].mode&&"i"!==u[a].mode||0!==g?f=null:((f=j("rect")).setAttribute("fill","#ffffff"),f.setAttribute("width",this.element.comp.data.w||0),f.setAttribute("height",this.element.comp.data.h||0),y.push(f)),r=j("path"),"n"===u[a].mode)this.viewData[a]={op:vt.getProp(this.element,u[a].o,0,.01,this.element),prop:Tt.getShapeProp(this.element,u[a],3),elem:r,lastPath:""},n.appendChild(r);else{var C;if(g+=1,r.setAttribute("fill","s"===u[a].mode?"#000000":"#ffffff"),r.setAttribute("clip-rule","nonzero"),0!==u[a].x.k?(b="mask",_="mask",m=vt.getProp(this.element,u[a].x,0,null,this.element),C=L(),(c=j("filter")).setAttribute("id",C),(d=j("feMorphology")).setAttribute("operator","erode"),d.setAttribute("in","SourceGraphic"),d.setAttribute("radius","0"),c.appendChild(d),n.appendChild(c),r.setAttribute("stroke","s"===u[a].mode?"#000000":"#ffffff")):(d=null,m=null),this.storedData[a]={elem:r,x:m,expan:d,lastPath:"",lastOperator:"",filterId:C,lastRadius:0},"i"===u[a].mode){p=y.length;var x=j("g");for(h=0;h<p;h+=1)x.appendChild(y[h]);var k=j("mask");k.setAttribute("mask-type","alpha"),k.setAttribute("id",v+"_"+g),k.appendChild(r),n.appendChild(k),x.setAttribute("mask","url("+i()+"#"+v+"_"+g+")"),y.length=0,y.push(x)}else y.push(r);u[a].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[a]={elem:r,lastPath:"",op:vt.getProp(this.element,u[a].o,0,.01,this.element),prop:Tt.getShapeProp(this.element,u[a],3),invRect:f},this.viewData[a].prop.k||this.drawPath(u[a],this.viewData[a].prop.v,this.viewData[a])}for(this.maskElement=j(b),o=y.length,a=0;a<o;a+=1)this.maskElement.appendChild(y[a]);g>0&&(this.maskElement.setAttribute("id",v),this.element.maskedElement.setAttribute(_,"url("+i()+"#"+v+")"),n.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}je.prototype={initTransform:function(){var t=new Ft;this.finalTransform={mProp:this.data.ks?Yt.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,s=0,i=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;s<i;){if(this.hierarchy[s].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}s+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),s=0;s<i;s+=1)e.multiply(this.hierarchy[s].finalTransform.mProp.v)}this.localTransforms&&!this.finalTransform._matMdf||(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var s=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(s),t=1;t<e;t+=1){var i=this.localTransforms[t].matrix;s.multiply(i)}s.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){var a=this.finalTransform.localOpacity;for(t=0;t<e;t+=1)a*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=a}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(We);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new Ft;var e=0,s=t.length;for(e=0;e<s;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var s,i=!0,a=this.comp;i;)a.finalTransform?(a.data.hasMask&&e.splice(0,0,a.finalTransform),a=a.comp):i=!1;var r,n=e.length;for(s=0;s<n;s+=1)r=e[s].mat.applyToPointArray(0,0,0),t=[t[0]-r[0],t[1]-r[1],0];return t},mHelper:new Ft},Ye.prototype.getMaskProperty=function(t){return this.viewData[t].prop},Ye.prototype.renderFrame=function(t){var e,s=this.element.finalTransform.mat,a=this.masksProperties.length;for(e=0;e<a;e+=1)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[e].invRect.setAttribute("transform",s.getInverseMatrix().to2dCSS()),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var r=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+i()+"#"+this.storedData[e].filterId+")")),r.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},Ye.prototype.getMaskelement=function(){return this.maskElement},Ye.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},Ye.prototype.drawPath=function(t,e,s){var i,a,r=" M"+e.v[0][0]+","+e.v[0][1];for(a=e._length,i=1;i<a;i+=1)r+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[i][0]+","+e.i[i][1]+" "+e.v[i][0]+","+e.v[i][1];if(e.c&&a>1&&(r+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),s.lastPath!==r){var n="";s.elem&&(e.c&&(n=t.inv?this.solidPath+r:r),s.elem.setAttribute("d",n)),s.lastPath=r}},Ye.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var Je=function(){var t={};return t.createFilter=function(t,e){var s=j("filter");s.setAttribute("id",t),!0!==e&&(s.setAttribute("filterUnits","objectBoundingBox"),s.setAttribute("x","0%"),s.setAttribute("y","0%"),s.setAttribute("width","100%"),s.setAttribute("height","100%"));return s},t.createAlphaToLuminanceFilter=function(){var t=j("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},t}(),He=function(){var t={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),/firefox/i.test(navigator.userAgent)&&(t.svgLumaHidden=!1),t}(),Ge={},Xe="filter_result_";function Ke(t){var e,s,a="SourceGraphic",r=t.data.ef?t.data.ef.length:0,n=L(),o=Je.createFilter(n,!0),h=0;for(this.filters=[],e=0;e<r;e+=1){s=null;var l=t.data.ef[e].ty;if(Ge[l])s=new(0,Ge[l].effect)(o,t.effectsManager.effectElements[e],t,Xe+h,a),a=Xe+h,Ge[l].countsAsEffect&&(h+=1);s&&this.filters.push(s)}h&&(t.globalData.defs.appendChild(o),t.layerElement.setAttribute("filter","url("+i()+"#"+n+")")),this.filters.length&&t.addRenderableComponent(this)}function Ue(){}function Ze(){}function Qe(){}function $e(t,e,s){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,s),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ts(t,e){this.elem=t,this.pos=e}function es(){}Ke.prototype.renderFrame=function(t){var e,s=this.filters.length;for(e=0;e<s;e+=1)this.filters[e].renderFrame(t)},Ke.prototype.getEffects=function(t){var e,s=this.filters.length,i=[];for(e=0;e<s;e+=1)this.filters[e].type===t&&i.push(this.filters[e]);return i},Ue.prototype={initRendererElement:function(){this.layerElement=j("g")},createContainerElements:function(){this.matteElement=j("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t=null;if(this.data.td){this.matteMasks={};var e=j("g");e.setAttribute("id",this.layerId),e.appendChild(this.layerElement),t=e,this.globalData.defs.appendChild(e)}else this.data.tt?(this.matteElement.appendChild(this.layerElement),t=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var s=j("clipPath"),a=j("path");a.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var r=L();if(s.setAttribute("id",r),s.appendChild(a),this.globalData.defs.appendChild(s),this.checkMasks()){var n=j("g");n.setAttribute("clip-path","url("+i()+"#"+r+")"),n.appendChild(this.layerElement),this.transformedElement=n,t?t.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+i()+"#"+r+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new Ye(this.data,this,this.globalData),this.renderableEffectsManager=new Ke(this),this.searchEffectTransforms()},getMatte:function(t){if(this.matteMasks||(this.matteMasks={}),!this.matteMasks[t]){var e,s,a,r,n=this.layerId+"_"+t;if(1===t||3===t){var o=j("mask");o.setAttribute("id",n),o.setAttribute("mask-type",3===t?"luminance":"alpha"),(a=j("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),o.appendChild(a),this.globalData.defs.appendChild(o),He.maskType||1!==t||(o.setAttribute("mask-type","luminance"),e=L(),s=Je.createFilter(e),this.globalData.defs.appendChild(s),s.appendChild(Je.createAlphaToLuminanceFilter()),(r=j("g")).appendChild(a),o.appendChild(r),r.setAttribute("filter","url("+i()+"#"+e+")"))}else if(2===t){var h=j("mask");h.setAttribute("id",n),h.setAttribute("mask-type","alpha");var l=j("g");h.appendChild(l),e=L(),s=Je.createFilter(e);var p=j("feComponentTransfer");p.setAttribute("in","SourceGraphic"),s.appendChild(p);var f=j("feFuncA");f.setAttribute("type","table"),f.setAttribute("tableValues","1.0 0.0"),p.appendChild(f),this.globalData.defs.appendChild(s);var c=j("rect");c.setAttribute("width",this.comp.data.w),c.setAttribute("height",this.comp.data.h),c.setAttribute("x","0"),c.setAttribute("y","0"),c.setAttribute("fill","#ffffff"),c.setAttribute("opacity","0"),l.setAttribute("filter","url("+i()+"#"+e+")"),l.appendChild(c),(a=j("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),l.appendChild(a),He.maskType||(h.setAttribute("mask-type","luminance"),s.appendChild(Je.createAlphaToLuminanceFilter()),r=j("g"),l.appendChild(c),r.appendChild(this.layerElement),l.appendChild(r)),this.globalData.defs.appendChild(h)}this.matteMasks[t]=n}return this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+i()+"#"+t+")")}},Ze.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},r([Se,n({initElement:function(t,e,s){this.initFrame(),this.initBaseData(t,e,s),this.initTransform(t,e,s),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],Qe),r([ze,je,Ue,Ze,Oe,Qe],$e),$e.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=j("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},$e.prototype.sourceRectAtTime=function(){return this.sourceRect},es.prototype={addShapeToModifiers:function(t){var e,s=this.shapeModifiers.length;for(e=0;e<s;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;t>=0&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,s=0,i=e.length;s<i;){if(e[s].elem===t)return e[s].pos;s+=1}return 0},addProcessedElement:function(t,e){for(var s=this.processedElements,i=s.length;i;)if(s[i-=1].elem===t)return void(s[i].pos=e);s.push(new ts(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var ss={1:"butt",2:"round",3:"square"},is={1:"miter",2:"round",3:"bevel"};function as(t,e,s){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=s,this.lvl=e,this._isAnimated=!!s.k;for(var i=0,a=t.length;i<a;){if(t[i].mProps.dynamicProperties.length){this._isAnimated=!0;break}i+=1}}function rs(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=j("path"),this.msElem=null}function ns(t,e,s,i){var a;this.elem=t,this.frameId=-1,this.dataProps=l(e.length),this.renderer=s,this.k=!1,this.dashStr="",this.dashArray=h("float32",e.length?e.length-1:0),this.dashoffset=h("float32",1),this.initDynamicPropertyContainer(i);var r,n=e.length||0;for(a=0;a<n;a+=1)r=vt.getProp(t,e[a].v,0,0,this),this.k=r.k||this.k,this.dataProps[a]={n:e[a].n,p:r};this.k||this.getValue(!0),this._isAnimated=this.k}function os(t,e,s){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=vt.getProp(t,e.o,0,.01,this),this.w=vt.getProp(t,e.w,0,null,this),this.d=new ns(t,e.d||{},"svg",this),this.c=vt.getProp(t,e.c,1,255,this),this.style=s,this._isAnimated=!!this._isAnimated}function hs(t,e,s){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=vt.getProp(t,e.o,0,.01,this),this.c=vt.getProp(t,e.c,1,255,this),this.style=s}function ls(t,e,s){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=s}function ps(t,e,s){this.data=e,this.c=h("uint8c",4*e.p);var i=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=h("float32",i),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=i,this.initDynamicPropertyContainer(s),this.prop=vt.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function fs(t,e,s){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,s)}function cs(t,e,s){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=vt.getProp(t,e.w,0,null,this),this.d=new ns(t,e.d||{},"svg",this),this.initGradientData(t,e,s),this._isAnimated=!!this._isAnimated}function ds(){this.it=[],this.prevViewData=[],this.gr=j("g")}function ms(t,e,s){this.transform={mProps:t,op:e,container:s},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}as.prototype.setAsAnimated=function(){this._isAnimated=!0},rs.prototype.reset=function(){this.d="",this._mdf=!1},ns.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,s=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<s;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},r([bt],ns),r([bt],os),r([bt],hs),r([bt],ls),ps.prototype.comparePoints=function(t,e){for(var s=0,i=this.o.length/2;s<i;){if(Math.abs(t[4*s]-t[4*e+2*s])>.01)return!1;s+=1}return!0},ps.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},ps.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,s,i,a=4*this.data.p;for(e=0;e<a;e+=1)s=e%4==0?100:255,i=Math.round(this.prop.v[e]*s),this.c[e]!==i&&(this.c[e]=i,this._cmdf=!t);if(this.o.length)for(a=this.prop.v.length,e=4*this.data.p;e<a;e+=1)s=e%2==0?100:1,i=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==i&&(this.o[e-4*this.data.p]=i,this._omdf=!t);this._mdf=!t}},r([bt],ps),fs.prototype.initGradientData=function(t,e,s){this.o=vt.getProp(t,e.o,0,.01,this),this.s=vt.getProp(t,e.s,1,null,this),this.e=vt.getProp(t,e.e,1,null,this),this.h=vt.getProp(t,e.h||{k:0},0,.01,this),this.a=vt.getProp(t,e.a||{k:0},0,x,this),this.g=new ps(t,e.g,this),this.style=s,this.stops=[],this.setGradientData(s.pElem,e),this.setGradientOpacity(e,s),this._isAnimated=!!this._isAnimated},fs.prototype.setGradientData=function(t,e){var s=L(),a=j(1===e.t?"linearGradient":"radialGradient");a.setAttribute("id",s),a.setAttribute("spreadMethod","pad"),a.setAttribute("gradientUnits","userSpaceOnUse");var r,n,o,h=[];for(o=4*e.g.p,n=0;n<o;n+=4)r=j("stop"),a.appendChild(r),h.push(r);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+i()+"#"+s+")"),this.gf=a,this.cst=h},fs.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){var s,a,r,n=j("mask"),o=j("path");n.appendChild(o);var h=L(),l=L();n.setAttribute("id",l);var p=j(1===t.t?"linearGradient":"radialGradient");p.setAttribute("id",h),p.setAttribute("spreadMethod","pad"),p.setAttribute("gradientUnits","userSpaceOnUse"),r=t.g.k.k[0].s?t.g.k.k[0].s.length:t.g.k.k.length;var f=this.stops;for(a=4*t.g.p;a<r;a+=2)(s=j("stop")).setAttribute("stop-color","rgb(255,255,255)"),p.appendChild(s),f.push(s);o.setAttribute("gf"===t.ty?"fill":"stroke","url("+i()+"#"+h+")"),"gs"===t.ty&&(o.setAttribute("stroke-linecap",ss[t.lc||2]),o.setAttribute("stroke-linejoin",is[t.lj||2]),1===t.lj&&o.setAttribute("stroke-miterlimit",t.ml)),this.of=p,this.ms=n,this.ost=f,this.maskId=l,e.msElem=o}},r([bt],fs),r([fs,bt],cs);var us=function(t,e,s,i){if(0===e)return"";var a,r=t.o,n=t.i,o=t.v,h=" M"+i.applyToPointStringified(o[0][0],o[0][1]);for(a=1;a<e;a+=1)h+=" C"+i.applyToPointStringified(r[a-1][0],r[a-1][1])+" "+i.applyToPointStringified(n[a][0],n[a][1])+" "+i.applyToPointStringified(o[a][0],o[a][1]);return s&&e&&(h+=" C"+i.applyToPointStringified(r[a-1][0],r[a-1][1])+" "+i.applyToPointStringified(n[0][0],n[0][1])+" "+i.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},gs=function(){var t=new Ft,e=new Ft;function s(t,e,s){(s||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(s||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function i(){}function a(s,i,a){var r,n,o,h,l,p,f,c,d,m,u=i.styles.length,g=i.lvl;for(p=0;p<u;p+=1){if(h=i.sh._mdf||a,i.styles[p].lvl<g){for(c=e.reset(),d=g-i.styles[p].lvl,m=i.transformers.length-1;!h&&d>0;)h=i.transformers[m].mProps._mdf||h,d-=1,m-=1;if(h)for(d=g-i.styles[p].lvl,m=i.transformers.length-1;d>0;)c.multiply(i.transformers[m].mProps.v),d-=1,m-=1}else c=t;if(n=(f=i.sh.paths)._length,h){for(o="",r=0;r<n;r+=1)(l=f.shapes[r])&&l._length&&(o+=us(l,l._length,l.c,c));i.caches[p]=o}else o=i.caches[p];i.styles[p].d+=!0===s.hd?"":o,i.styles[p]._mdf=h||i.styles[p]._mdf}}function r(t,e,s){var i=e.style;(e.c._mdf||s)&&i.pElem.setAttribute("fill","rgb("+v(e.c.v[0])+","+v(e.c.v[1])+","+v(e.c.v[2])+")"),(e.o._mdf||s)&&i.pElem.setAttribute("fill-opacity",e.o.v)}function n(t,e,s){o(t,e,s),h(t,e,s)}function o(t,e,s){var i,a,r,n,o,h=e.gf,l=e.g._hasOpacity,p=e.s.v,f=e.e.v;if(e.o._mdf||s){var c="gf"===t.ty?"fill-opacity":"stroke-opacity";e.style.pElem.setAttribute(c,e.o.v)}if(e.s._mdf||s){var d=1===t.t?"x1":"cx",m="x1"===d?"y1":"cy";h.setAttribute(d,p[0]),h.setAttribute(m,p[1]),l&&!e.g._collapsable&&(e.of.setAttribute(d,p[0]),e.of.setAttribute(m,p[1]))}if(e.g._cmdf||s){i=e.cst;var u=e.g.c;for(r=i.length,a=0;a<r;a+=1)(n=i[a]).setAttribute("offset",u[4*a]+"%"),n.setAttribute("stop-color","rgb("+u[4*a+1]+","+u[4*a+2]+","+u[4*a+3]+")")}if(l&&(e.g._omdf||s)){var g=e.g.o;for(r=(i=e.g._collapsable?e.cst:e.ost).length,a=0;a<r;a+=1)n=i[a],e.g._collapsable||n.setAttribute("offset",g[2*a]+"%"),n.setAttribute("stop-opacity",g[2*a+1])}if(1===t.t)(e.e._mdf||s)&&(h.setAttribute("x2",f[0]),h.setAttribute("y2",f[1]),l&&!e.g._collapsable&&(e.of.setAttribute("x2",f[0]),e.of.setAttribute("y2",f[1])));else if((e.s._mdf||e.e._mdf||s)&&(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)),h.setAttribute("r",o),l&&!e.g._collapsable&&e.of.setAttribute("r",o)),e.s._mdf||e.e._mdf||e.h._mdf||e.a._mdf||s){o||(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)));var y=Math.atan2(f[1]-p[1],f[0]-p[0]),v=e.h.v;v>=1?v=.99:v<=-1&&(v=-.99);var b=o*v,_=Math.cos(y+e.a.v)*b+p[0],C=Math.sin(y+e.a.v)*b+p[1];h.setAttribute("fx",_),h.setAttribute("fy",C),l&&!e.g._collapsable&&(e.of.setAttribute("fx",_),e.of.setAttribute("fy",C))}}function h(t,e,s){var i=e.style,a=e.d;a&&(a._mdf||s)&&a.dashStr&&(i.pElem.setAttribute("stroke-dasharray",a.dashStr),i.pElem.setAttribute("stroke-dashoffset",a.dashoffset[0])),e.c&&(e.c._mdf||s)&&i.pElem.setAttribute("stroke","rgb("+v(e.c.v[0])+","+v(e.c.v[1])+","+v(e.c.v[2])+")"),(e.o._mdf||s)&&i.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||s)&&(i.pElem.setAttribute("stroke-width",e.w.v),i.msElem&&i.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function(t){switch(t.ty){case"fl":return r;case"gf":return o;case"gs":return n;case"st":return h;case"sh":case"el":case"rc":case"sr":return a;case"tr":return s;case"no":return i;default:return null}}}}();function ys(t,e,s){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,s),this.prevViewData=[]}function vs(t,e,s,i,a,r){this.o=t,this.sw=e,this.sc=s,this.fc=i,this.m=a,this.p=r,this._mdf={o:!0,sw:!!e,sc:!!s,fc:!!i,m:!0,p:!0}}function bs(t,e){this._frameId=s,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}r([ze,je,Ue,es,Ze,Oe,Qe],ys),ys.prototype.initSecondaryElement=function(){},ys.prototype.identityMatrix=new Ft,ys.prototype.buildExpressionInterface=function(){},ys.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},ys.prototype.filterUniqueShapes=function(){var t,e,s,i,a=this.shapes.length,r=this.stylesList.length,n=[],o=!1;for(s=0;s<r;s+=1){for(i=this.stylesList[s],o=!1,n.length=0,t=0;t<a;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(i)&&(n.push(e),o=e._isAnimated||o);n.length>1&&o&&this.setShapesAsAnimated(n)}},ys.prototype.setShapesAsAnimated=function(t){var e,s=t.length;for(e=0;e<s;e+=1)t[e].setAsAnimated()},ys.prototype.createStyleElement=function(t,e){var s,a=new rs(t,e),r=a.pElem;if("st"===t.ty)s=new os(this,t,a);else if("fl"===t.ty)s=new hs(this,t,a);else if("gf"===t.ty||"gs"===t.ty){s=new("gf"===t.ty?fs:cs)(this,t,a),this.globalData.defs.appendChild(s.gf),s.maskId&&(this.globalData.defs.appendChild(s.ms),this.globalData.defs.appendChild(s.of),r.setAttribute("mask","url("+i()+"#"+s.maskId+")"))}else"no"===t.ty&&(s=new ls(this,t,a));return"st"!==t.ty&&"gs"!==t.ty||(r.setAttribute("stroke-linecap",ss[t.lc||2]),r.setAttribute("stroke-linejoin",is[t.lj||2]),r.setAttribute("fill-opacity","0"),1===t.lj&&r.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&r.setAttribute("fill-rule","evenodd"),t.ln&&r.setAttribute("id",t.ln),t.cl&&r.setAttribute("class",t.cl),t.bm&&(r.style["mix-blend-mode"]=De(t.bm)),this.stylesList.push(a),this.addToAnimatedContents(t,s),s},ys.prototype.createGroupElement=function(t){var e=new ds;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=De(t.bm)),e},ys.prototype.createTransformElement=function(t,e){var s=Yt.getTransformProperty(this,t,this),i=new ms(s,s.o,e);return this.addToAnimatedContents(t,i),i},ys.prototype.createShapeElement=function(t,e,s){var i=4;"rc"===t.ty?i=5:"el"===t.ty?i=6:"sr"===t.ty&&(i=7);var a=new as(e,s,Tt.getShapeProp(this,t,i,this));return this.shapes.push(a),this.addShapeToModifiers(a),this.addToAnimatedContents(t,a),a},ys.prototype.addToAnimatedContents=function(t,e){for(var s=0,i=this.animatedContents.length;s<i;){if(this.animatedContents[s].element===e)return;s+=1}this.animatedContents.push({fn:gs.createRenderFunction(t),element:e,data:t})},ys.prototype.setElementStyles=function(t){var e,s=t.styles,i=this.stylesList.length;for(e=0;e<i;e+=1)-1!==s.indexOf(this.stylesList[e])||this.stylesList[e].closed||s.push(this.stylesList[e])},ys.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},ys.prototype.searchShapes=function(t,e,s,i,a,r,n){var o,h,l,p,f,c,d=[].concat(r),m=t.length-1,u=[],g=[];for(o=m;o>=0;o-=1){if((c=this.searchProcessedElement(t[o]))?e[o]=s[c-1]:t[o]._render=n,"fl"===t[o].ty||"st"===t[o].ty||"gf"===t[o].ty||"gs"===t[o].ty||"no"===t[o].ty)c?e[o].style.closed=t[o].hd:e[o]=this.createStyleElement(t[o],a),t[o]._render&&e[o].style.pElem.parentNode!==i&&i.appendChild(e[o].style.pElem),u.push(e[o].style);else if("gr"===t[o].ty){if(c)for(l=e[o].it.length,h=0;h<l;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,a+1,d,n),t[o]._render&&e[o].gr.parentNode!==i&&i.appendChild(e[o].gr)}else"tr"===t[o].ty?(c||(e[o]=this.createTransformElement(t[o],i)),p=e[o].transform,d.push(p)):"sh"===t[o].ty||"rc"===t[o].ty||"el"===t[o].ty||"sr"===t[o].ty?(c||(e[o]=this.createShapeElement(t[o],d,a)),this.setElementStyles(e[o])):"tm"===t[o].ty||"rd"===t[o].ty||"ms"===t[o].ty||"pb"===t[o].ty||"zz"===t[o].ty||"op"===t[o].ty?(c?(f=e[o]).closed=!1:((f=qt.getModifier(t[o].ty)).init(this,t[o]),e[o]=f,this.shapeModifiers.push(f)),g.push(f)):"rp"===t[o].ty&&(c?(f=e[o]).closed=!0:(f=qt.getModifier(t[o].ty),e[o]=f,f.init(this,t,o,e),this.shapeModifiers.push(f),n=!1),g.push(f));this.addProcessedElement(t[o],o+1)}for(m=u.length,o=0;o<m;o+=1)u[o].closed=!0;for(m=g.length,o=0;o<m;o+=1)g[o].closed=!0},ys.prototype.renderInnerContent=function(){var t;this.renderModifiers();var e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},ys.prototype.renderShape=function(){var t,e,s=this.animatedContents.length;for(t=0;t<s;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},ys.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},vs.prototype.update=function(t,e,s,i,a,r){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1,this._mdf.p=!1;var n=!1;return this.o!==t&&(this.o=t,this._mdf.o=!0,n=!0),this.sw!==e&&(this.sw=e,this._mdf.sw=!0,n=!0),this.sc!==s&&(this.sc=s,this._mdf.sc=!0,n=!0),this.fc!==i&&(this.fc=i,this._mdf.fc=!0,n=!0),this.m!==a&&(this.m=a,this._mdf.m=!0,n=!0),!r.length||this.p[0]===r[0]&&this.p[1]===r[1]&&this.p[4]===r[4]&&this.p[5]===r[5]&&this.p[12]===r[12]&&this.p[13]===r[13]||(this.p=r,this._mdf.p=!0,n=!0),n},bs.prototype.defaultBoxWidth=[0,0],bs.prototype.copyData=function(t,e){for(var s in e)Object.prototype.hasOwnProperty.call(e,s)&&(t[s]=e[s]);return t},bs.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},bs.prototype.searchProperty=function(){return this.searchKeyframes()},bs.prototype.searchKeyframes=function(){return this.kf=this.data.d.k.length>1,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},bs.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},bs.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,s=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{var i;this.lock=!0,this._mdf=!1;var a=this.effectsSequence.length,r=t||this.data.d.k[this.keysIndex].s;for(i=0;i<a;i+=1)r=s!==this.keysIndex?this.effectsSequence[i](r,r.t):this.effectsSequence[i](this.currentData,r.t);e!==r&&this.setCurrentData(r),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},bs.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,s=0,i=t.length;s<=i-1&&!(s===i-1||t[s+1].t>e);)s+=1;return this.keysIndex!==s&&(this.keysIndex=s),this.data.d.k[this.keysIndex].s},bs.prototype.buildFinalText=function(t){for(var e,s,i=[],a=0,r=t.length,n=!1,o=!1,h="";a<r;)n=o,o=!1,e=t.charCodeAt(a),h=t.charAt(a),xe.isCombinedCharacter(e)?n=!0:e>=55296&&e<=56319?xe.isRegionalFlag(t,a)?h=t.substr(a,14):(s=t.charCodeAt(a+1))>=56320&&s<=57343&&(xe.isModifier(e,s)?(h=t.substr(a,2),n=!0):h=xe.isFlagEmoji(t.substr(a,4))?t.substr(a,4):t.substr(a,2)):e>56319?(s=t.charCodeAt(a+1),xe.isVariationSelector(e)&&(n=!0)):xe.isZeroWidthJoiner(e)&&(n=!0,o=!0),n?(i[i.length-1]+=h,n=!1):i.push(h),a+=h.length;return i},bs.prototype.completeTextData=function(t){t.__complete=!0;var e,s,i,a,r,n,o,h=this.elem.globalData.fontManager,l=this.data,p=[],f=0,c=l.m.g,d=0,m=0,u=0,g=[],y=0,v=0,b=h.getFontByName(t.f),_=0,C=Ce(b);t.fWeight=C.weight,t.fStyle=C.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),s=t.finalText.length,t.finalLineHeight=t.lh;var x,k=t.tr/1e3*t.finalSize;if(t.sz)for(var S,P,D=!0,w=t.sz[0],A=t.sz[1];D;){S=0,y=0,s=(P=this.buildFinalText(t.t)).length,k=t.tr/1e3*t.finalSize;var M=-1;for(e=0;e<s;e+=1)x=P[e].charCodeAt(0),i=!1," "===P[e]?M=e:13!==x&&3!==x||(y=0,i=!0,S+=t.finalLineHeight||1.2*t.finalSize),h.chars?(o=h.getCharData(P[e],b.fStyle,b.fFamily),_=i?0:o.w*t.finalSize/100):_=h.measureText(P[e],t.f,t.finalSize),y+_>w&&" "!==P[e]?(-1===M?s+=1:e=M,S+=t.finalLineHeight||1.2*t.finalSize,P.splice(e,M===e?1:0,"\r"),M=-1,y=0):(y+=_,y+=k);S+=b.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&A<S?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=P,s=t.finalText.length,D=!1)}y=-k,_=0;var T,F=0;for(e=0;e<s;e+=1)if(i=!1,13===(x=(T=t.finalText[e]).charCodeAt(0))||3===x?(F=0,g.push(y),v=y>v?y:v,y=-2*k,a="",i=!0,u+=1):a=T,h.chars?(o=h.getCharData(T,b.fStyle,h.getFontByName(t.f).fFamily),_=i?0:o.w*t.finalSize/100):_=h.measureText(a,t.f,t.finalSize)," "===T?F+=_+k:(y+=_+k+F,F=0),p.push({l:_,an:_,add:d,n:i,anIndexes:[],val:a,line:u,animatorJustifyOffset:0}),2==c){if(d+=_,""===a||" "===a||e===s-1){for(""!==a&&" "!==a||(d-=_);m<=e;)p[m].an=d,p[m].ind=f,p[m].extra=_,m+=1;f+=1,d=0}}else if(3==c){if(d+=_,""===a||e===s-1){for(""===a&&(d-=_);m<=e;)p[m].an=d,p[m].ind=f,p[m].extra=_,m+=1;d=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=y>v?y:v,g.push(y),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=g;var E,L,I,R,V=l.a;n=V.length;var z=[];for(r=0;r<n;r+=1){for((E=V[r]).a.sc&&(t.strokeColorAnim=!0),E.a.sw&&(t.strokeWidthAnim=!0),(E.a.fc||E.a.fh||E.a.fs||E.a.fb)&&(t.fillColorAnim=!0),R=0,I=E.s.b,e=0;e<s;e+=1)(L=p[e]).anIndexes[r]=R,(1==I&&""!==L.val||2==I&&""!==L.val&&" "!==L.val||3==I&&(L.n||" "==L.val||e==s-1)||4==I&&(L.n||e==s-1))&&(1===E.s.rn&&z.push(R),R+=1);l.a[r].s.totalChars=R;var O,N=-1;if(1===E.s.rn)for(e=0;e<s;e+=1)N!=(L=p[e]).anIndexes[r]&&(N=L.anIndexes[r],O=z.splice(Math.floor(Math.random()*z.length),1)[0]),L.anIndexes[r]=O}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=b.ascent*t.finalSize/100},bs.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var s=this.copyData({},this.data.d.k[e].s);s=this.copyData(s,t),this.data.d.k[e].s=s,this.recalculate(e),this.setCurrentData(s),this.elem.addDynamicProperty(this)},bs.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},bs.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},bs.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var _s=function(){var t=Math.max,e=Math.min,s=Math.floor;function i(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=vt.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?vt.getProp(t,e.e,0,0,this):{v:100},this.o=vt.getProp(t,e.o||{k:0},0,0,this),this.xe=vt.getProp(t,e.xe||{k:0},0,0,this),this.ne=vt.getProp(t,e.ne||{k:0},0,0,this),this.sm=vt.getProp(t,e.sm||{k:100},0,0,this),this.a=vt.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return i.prototype={getMult:function(i){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var a=0,r=0,n=1,o=1;this.ne.v>0?a=this.ne.v/100:r=-this.ne.v/100,this.xe.v>0?n=1-this.xe.v/100:o=1+this.xe.v/100;var h=tt.getBezierEasing(a,r,n,o).get,l=0,p=this.finalS,f=this.finalE,c=this.data.sh;if(2===c)l=h(l=f===p?i>=f?1:0:t(0,e(.5/(f-p)+(i-p)/(f-p),1)));else if(3===c)l=h(l=f===p?i>=f?0:1:1-t(0,e(.5/(f-p)+(i-p)/(f-p),1)));else if(4===c)f===p?l=0:(l=t(0,e(.5/(f-p)+(i-p)/(f-p),1)))<.5?l*=2:l=1-2*(l-.5),l=h(l);else if(5===c){if(f===p)l=0;else{var d=f-p,m=-d/2+(i=e(t(0,i+.5-p),f-p)),u=d/2;l=Math.sqrt(1-m*m/(u*u))}l=h(l)}else 6===c?(f===p?l=0:(i=e(t(0,i+.5-p),f-p),l=(1+Math.cos(Math.PI+2*Math.PI*i/(f-p)))/2),l=h(l)):(i>=s(p)&&(l=t(0,e(i-p<0?e(f,1)-(p-i):f-i,1))),l=h(l));if(100!==this.sm.v){var g=.01*this.sm.v;0===g&&(g=1e-8);var y=.5-.5*g;l<y?l=0:(l=(l-y)/g)>1&&(l=1)}return l*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,s=this.o.v/e,i=this.s.v/e+s,a=this.e.v/e+s;if(i>a){var r=i;i=a,a=r}this.finalS=i,this.finalE=a}},r([bt],i),{getTextSelectorProp:function(t,e,s){return new i(t,e,s)}}}();function Cs(t,e,s){var i={propType:!1},a=vt.getProp,r=e.a;this.a={r:r.r?a(t,r.r,0,x,s):i,rx:r.rx?a(t,r.rx,0,x,s):i,ry:r.ry?a(t,r.ry,0,x,s):i,sk:r.sk?a(t,r.sk,0,x,s):i,sa:r.sa?a(t,r.sa,0,x,s):i,s:r.s?a(t,r.s,1,.01,s):i,a:r.a?a(t,r.a,1,0,s):i,o:r.o?a(t,r.o,0,.01,s):i,p:r.p?a(t,r.p,1,0,s):i,sw:r.sw?a(t,r.sw,0,0,s):i,sc:r.sc?a(t,r.sc,1,0,s):i,fc:r.fc?a(t,r.fc,1,0,s):i,fh:r.fh?a(t,r.fh,0,0,s):i,fs:r.fs?a(t,r.fs,0,.01,s):i,fb:r.fb?a(t,r.fb,0,.01,s):i,t:r.t?a(t,r.t,0,0,s):i},this.s=_s.getTextSelectorProp(t,e.s,s),this.s.t=e.s.t}function xs(t,e,s){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=s,this._animatorsData=l(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(s)}function ks(){}xs.prototype.searchProperties=function(){var t,e,s=this._textData.a.length,i=vt.getProp;for(t=0;t<s;t+=1)e=this._textData.a[t],this._animatorsData[t]=new Cs(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:i(this._elem,this._textData.p.a,0,0,this),f:i(this._elem,this._textData.p.f,0,0,this),l:i(this._elem,this._textData.p.l,0,0,this),r:i(this._elem,this._textData.p.r,0,0,this),p:i(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=i(this._elem,this._textData.m.a,1,0,this)},xs.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var s,i,a,r,n,o,h,l,p,f,c,d,m,u,g,y,v,b,_,C=this._moreOptions.alignment.v,x=this._animatorsData,k=this._textData,S=this.mHelper,P=this._renderType,D=this.renderedLetters.length,w=t.l;if(this._hasMaskedPath){if(_=this._pathData.m,!this._pathData.n||this._pathData._mdf){var A,M=_.v;for(this._pathData.r.v&&(M=M.reverse()),n={tLength:0,segments:[]},r=M._length-1,y=0,a=0;a<r;a+=1)A=rt.buildBezierData(M.v[a],M.v[a+1],[M.o[a][0]-M.v[a][0],M.o[a][1]-M.v[a][1]],[M.i[a+1][0]-M.v[a+1][0],M.i[a+1][1]-M.v[a+1][1]]),n.tLength+=A.segmentLength,n.segments.push(A),y+=A.segmentLength;a=r,_.v.c&&(A=rt.buildBezierData(M.v[a],M.v[0],[M.o[a][0]-M.v[a][0],M.o[a][1]-M.v[a][1]],[M.i[0][0]-M.v[0][0],M.i[0][1]-M.v[0][1]]),n.tLength+=A.segmentLength,n.segments.push(A),y+=A.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,c=0,f=1,l=0,p=!0,u=n.segments,o<0&&_.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),f=(m=u[c=u.length-1].points).length-1;o<0;)o+=m[f].partialLength,(f-=1)<0&&(f=(m=u[c-=1].points).length-1);d=(m=u[c].points)[f-1],g=(h=m[f]).partialLength}r=w.length,s=0,i=0;var T,F,E,L,I,R=1.2*t.finalSize*.714,N=!0;E=x.length;var q,B,W,j,Y,J,H,G,X,K,U,Z,Q=-1,$=o,tt=c,et=f,st=-1,it="",at=this.defaultPropsArray;if(2===t.j||1===t.j){var nt=0,ot=0,ht=2===t.j?-.5:-1,lt=0,pt=!0;for(a=0;a<r;a+=1)if(w[a].n){for(nt&&(nt+=ot);lt<a;)w[lt].animatorJustifyOffset=nt,lt+=1;nt=0,pt=!0}else{for(F=0;F<E;F+=1)(T=x[F].a).t.propType&&(pt&&2===t.j&&(ot+=T.t.v*ht),(I=x[F].s.getMult(w[a].anIndexes[F],k.a[F].s.totalChars)).length?nt+=T.t.v*I[0]*ht:nt+=T.t.v*I*ht);pt=!1}for(nt&&(nt+=ot);lt<a;)w[lt].animatorJustifyOffset=nt,lt+=1}for(a=0;a<r;a+=1){if(S.reset(),j=1,w[a].n)s=0,i+=t.yOffset,i+=N?1:0,o=$,N=!1,this._hasMaskedPath&&(f=et,d=(m=u[c=tt].points)[f-1],g=(h=m[f]).partialLength,l=0),it="",U="",X="",Z="",at=this.defaultPropsArray;else{if(this._hasMaskedPath){if(st!==w[a].line){switch(t.j){case 1:o+=y-t.lineWidths[w[a].line];break;case 2:o+=(y-t.lineWidths[w[a].line])/2}st=w[a].line}Q!==w[a].ind&&(w[Q]&&(o+=w[Q].extra),o+=w[a].an/2,Q=w[a].ind),o+=C[0]*w[a].an*.005;var ft=0;for(F=0;F<E;F+=1)(T=x[F].a).p.propType&&((I=x[F].s.getMult(w[a].anIndexes[F],k.a[F].s.totalChars)).length?ft+=T.p.v[0]*I[0]:ft+=T.p.v[0]*I),T.a.propType&&((I=x[F].s.getMult(w[a].anIndexes[F],k.a[F].s.totalChars)).length?ft+=T.a.v[0]*I[0]:ft+=T.a.v[0]*I);for(p=!0,this._pathData.a.v&&(o=.5*w[0].an+(y-this._pathData.f.v-.5*w[0].an-.5*w[w.length-1].an)*Q/(r-1),o+=this._pathData.f.v);p;)l+g>=o+ft||!m?(v=(o+ft-l)/h.partialLength,B=d.point[0]+(h.point[0]-d.point[0])*v,W=d.point[1]+(h.point[1]-d.point[1])*v,S.translate(-C[0]*w[a].an*.005,-C[1]*R*.01),p=!1):m&&(l+=h.partialLength,(f+=1)>=m.length&&(f=0,u[c+=1]?m=u[c].points:_.v.c?(f=0,m=u[c=0].points):(l-=h.partialLength,m=null)),m&&(d=h,g=(h=m[f]).partialLength));q=w[a].an/2-w[a].add,S.translate(-q,0,0)}else q=w[a].an/2-w[a].add,S.translate(-q,0,0),S.translate(-C[0]*w[a].an*.005,-C[1]*R*.01,0);for(F=0;F<E;F+=1)(T=x[F].a).t.propType&&(I=x[F].s.getMult(w[a].anIndexes[F],k.a[F].s.totalChars),0===s&&0===t.j||(this._hasMaskedPath?I.length?o+=T.t.v*I[0]:o+=T.t.v*I:I.length?s+=T.t.v*I[0]:s+=T.t.v*I));for(t.strokeWidthAnim&&(J=t.sw||0),t.strokeColorAnim&&(Y=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(H=[t.fc[0],t.fc[1],t.fc[2]]),F=0;F<E;F+=1)(T=x[F].a).a.propType&&((I=x[F].s.getMult(w[a].anIndexes[F],k.a[F].s.totalChars)).length?S.translate(-T.a.v[0]*I[0],-T.a.v[1]*I[1],T.a.v[2]*I[2]):S.translate(-T.a.v[0]*I,-T.a.v[1]*I,T.a.v[2]*I));for(F=0;F<E;F+=1)(T=x[F].a).s.propType&&((I=x[F].s.getMult(w[a].anIndexes[F],k.a[F].s.totalChars)).length?S.scale(1+(T.s.v[0]-1)*I[0],1+(T.s.v[1]-1)*I[1],1):S.scale(1+(T.s.v[0]-1)*I,1+(T.s.v[1]-1)*I,1));for(F=0;F<E;F+=1){if(T=x[F].a,I=x[F].s.getMult(w[a].anIndexes[F],k.a[F].s.totalChars),T.sk.propType&&(I.length?S.skewFromAxis(-T.sk.v*I[0],T.sa.v*I[1]):S.skewFromAxis(-T.sk.v*I,T.sa.v*I)),T.r.propType&&(I.length?S.rotateZ(-T.r.v*I[2]):S.rotateZ(-T.r.v*I)),T.ry.propType&&(I.length?S.rotateY(T.ry.v*I[1]):S.rotateY(T.ry.v*I)),T.rx.propType&&(I.length?S.rotateX(T.rx.v*I[0]):S.rotateX(T.rx.v*I)),T.o.propType&&(I.length?j+=(T.o.v*I[0]-j)*I[0]:j+=(T.o.v*I-j)*I),t.strokeWidthAnim&&T.sw.propType&&(I.length?J+=T.sw.v*I[0]:J+=T.sw.v*I),t.strokeColorAnim&&T.sc.propType)for(G=0;G<3;G+=1)I.length?Y[G]+=(T.sc.v[G]-Y[G])*I[0]:Y[G]+=(T.sc.v[G]-Y[G])*I;if(t.fillColorAnim&&t.fc){if(T.fc.propType)for(G=0;G<3;G+=1)I.length?H[G]+=(T.fc.v[G]-H[G])*I[0]:H[G]+=(T.fc.v[G]-H[G])*I;T.fh.propType&&(H=I.length?O(H,T.fh.v*I[0]):O(H,T.fh.v*I)),T.fs.propType&&(H=I.length?V(H,T.fs.v*I[0]):V(H,T.fs.v*I)),T.fb.propType&&(H=I.length?z(H,T.fb.v*I[0]):z(H,T.fb.v*I))}}for(F=0;F<E;F+=1)(T=x[F].a).p.propType&&(I=x[F].s.getMult(w[a].anIndexes[F],k.a[F].s.totalChars),this._hasMaskedPath?I.length?S.translate(0,T.p.v[1]*I[0],-T.p.v[2]*I[1]):S.translate(0,T.p.v[1]*I,-T.p.v[2]*I):I.length?S.translate(T.p.v[0]*I[0],T.p.v[1]*I[1],-T.p.v[2]*I[2]):S.translate(T.p.v[0]*I,T.p.v[1]*I,-T.p.v[2]*I));if(t.strokeWidthAnim&&(X=J<0?0:J),t.strokeColorAnim&&(K="rgb("+Math.round(255*Y[0])+","+Math.round(255*Y[1])+","+Math.round(255*Y[2])+")"),t.fillColorAnim&&t.fc&&(U="rgb("+Math.round(255*H[0])+","+Math.round(255*H[1])+","+Math.round(255*H[2])+")"),this._hasMaskedPath){if(S.translate(0,-t.ls),S.translate(0,C[1]*R*.01+i,0),this._pathData.p.v){b=(h.point[1]-d.point[1])/(h.point[0]-d.point[0]);var ct=180*Math.atan(b)/Math.PI;h.point[0]<d.point[0]&&(ct+=180),S.rotate(-ct*Math.PI/180)}S.translate(B,W,0),o-=C[0]*w[a].an*.005,w[a+1]&&Q!==w[a+1].ind&&(o+=w[a].an/2,o+=.001*t.tr*t.finalSize)}else{switch(S.translate(s,i,0),t.ps&&S.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:S.translate(w[a].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[w[a].line]),0,0);break;case 2:S.translate(w[a].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[w[a].line])/2,0,0)}S.translate(0,-t.ls),S.translate(q,0,0),S.translate(C[0]*w[a].an*.005,C[1]*R*.01,0),s+=w[a].l+.001*t.tr*t.finalSize}"html"===P?it=S.toCSS():"svg"===P?it=S.to2dCSS():at=[S.props[0],S.props[1],S.props[2],S.props[3],S.props[4],S.props[5],S.props[6],S.props[7],S.props[8],S.props[9],S.props[10],S.props[11],S.props[12],S.props[13],S.props[14],S.props[15]],Z=j}D<=a?(L=new vs(Z,X,K,U,it,at),this.renderedLetters.push(L),D+=1,this.lettersChangedFlag=!0):(L=this.renderedLetters[a],this.lettersChangedFlag=L.update(Z,X,K,U,it,at)||this.lettersChangedFlag)}}},xs.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},xs.prototype.mHelper=new Ft,xs.prototype.defaultPropsArray=[],r([bt],xs),ks.prototype.initElement=function(t,e,s){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,s),this.textProperty=new bs(this,t.t,this.dynamicProperties),this.textAnimator=new xs(t.t,this.renderType,this),this.initTransform(t,e,s),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},ks.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},ks.prototype.createPathShape=function(t,e){var s,i,a=e.length,r="";for(s=0;s<a;s+=1)"sh"===e[s].ty&&(i=e[s].ks.k,r+=us(i,i.i.length,!0,t));return r},ks.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},ks.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},ks.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},ks.prototype.applyTextPropertiesToMatrix=function(t,e,s,i,a){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[s]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[s])/2,0,0)}e.translate(i,a,0)},ks.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},ks.prototype.emptyProp=new vs,ks.prototype.destroy=function(){},ks.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var Ss={shapes:[]};function Ps(t,e,s){this.textSpans=[],this.renderType="svg",this.initElement(t,e,s)}function Ds(t,e,s){this.initElement(t,e,s)}function ws(t,e,s){this.initFrame(),this.initBaseData(t,e,s),this.initFrame(),this.initTransform(t,e,s),this.initHierarchy()}function As(){}function Ms(){}function Ts(t,e,s){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?l(this.layers.length):[],this.initElement(t,e,s),this.tm=t.tm?vt.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function Fs(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=j("svg");var s="";if(e&&e.title){var i=j("title"),a=L();i.setAttribute("id",a),i.textContent=e.title,this.svgElement.appendChild(i),s+=a}if(e&&e.description){var r=j("desc"),n=L();r.setAttribute("id",n),r.textContent=e.description,this.svgElement.appendChild(r),s+=" "+n}s&&this.svgElement.setAttribute("aria-labelledby",s);var o=j("defs");this.svgElement.appendChild(o);var h=j("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}function Es(){this.sequences={},this.sequenceList=[],this.transform_key_count=0}r([ze,je,Ue,Ze,Oe,Qe,ks],Ps),Ps.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=j("text"))},Ps.prototype.buildTextContents=function(t){for(var e=0,s=t.length,i=[],a="";e<s;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(i.push(a),a=""):a+=t[e],e+=1;return i.push(a),i},Ps.prototype.buildShapeData=function(t,e){if(t.shapes&&t.shapes.length){var s=t.shapes[0];if(s.it){var i=s.it[s.it.length-1];i.s&&(i.s.k[0]=e,i.s.k[1]=e)}}return t},Ps.prototype.buildNewText=function(){var t,e;this.addDynamicProperty(this);var s=this.textProperty.currentData;this.renderedLetters=l(s?s.l.length:0),s.fc?this.layerElement.setAttribute("fill",this.buildColor(s.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),s.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(s.sc)),this.layerElement.setAttribute("stroke-width",s.sw)),this.layerElement.setAttribute("font-size",s.finalSize);var i=this.globalData.fontManager.getFontByName(s.f);if(i.fClass)this.layerElement.setAttribute("class",i.fClass);else{this.layerElement.setAttribute("font-family",i.fFamily);var a=s.fWeight,r=s.fStyle;this.layerElement.setAttribute("font-style",r),this.layerElement.setAttribute("font-weight",a)}this.layerElement.setAttribute("aria-label",s.t);var n,o=s.l||[],h=!!this.globalData.fontManager.chars;e=o.length;var p=this.mHelper,f=this.data.singleShape,c=0,d=0,m=!0,u=.001*s.tr*s.finalSize;if(!f||h||s.sz){var g,y=this.textSpans.length;for(t=0;t<e;t+=1){if(this.textSpans[t]||(this.textSpans[t]={span:null,childSpan:null,glyph:null}),!h||!f||0===t){if(n=y>t?this.textSpans[t].span:j(h?"g":"text"),y<=t){if(n.setAttribute("stroke-linecap","butt"),n.setAttribute("stroke-linejoin","round"),n.setAttribute("stroke-miterlimit","4"),this.textSpans[t].span=n,h){var v=j("g");n.appendChild(v),this.textSpans[t].childSpan=v}this.textSpans[t].span=n,this.layerElement.appendChild(n)}n.style.display="inherit"}if(p.reset(),f&&(o[t].n&&(c=-u,d+=s.yOffset,d+=m?1:0,m=!1),this.applyTextPropertiesToMatrix(s,p,o[t].line,c,d),c+=o[t].l||0,c+=u),h){var b;if(1===(g=this.globalData.fontManager.getCharData(s.finalText[t],i.fStyle,this.globalData.fontManager.getFontByName(s.f).fFamily)).t)b=new Ts(g.data,this.globalData,this);else{var _=Ss;g.data&&g.data.shapes&&(_=this.buildShapeData(g.data,s.finalSize)),b=new ys(_,this.globalData,this)}if(this.textSpans[t].glyph){var C=this.textSpans[t].glyph;this.textSpans[t].childSpan.removeChild(C.layerElement),C.destroy()}this.textSpans[t].glyph=b,b._debug=!0,b.prepareFrame(0),b.renderFrame(),this.textSpans[t].childSpan.appendChild(b.layerElement),1===g.t&&this.textSpans[t].childSpan.setAttribute("transform","scale("+s.finalSize/100+","+s.finalSize/100+")")}else f&&n.setAttribute("transform","translate("+p.props[12]+","+p.props[13]+")"),n.textContent=o[t].val,n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}f&&n&&n.setAttribute("d","")}else{var x=this.textContainer,k="start";switch(s.j){case 1:k="end";break;case 2:k="middle";break;default:k="start"}x.setAttribute("text-anchor",k),x.setAttribute("letter-spacing",u);var S=this.buildTextContents(s.finalText);for(e=S.length,d=s.ps?s.ps[1]+s.ascent:0,t=0;t<e;t+=1)(n=this.textSpans[t].span||j("tspan")).textContent=S[t],n.setAttribute("x",0),n.setAttribute("y",d),n.style.display="inherit",x.appendChild(n),this.textSpans[t]||(this.textSpans[t]={span:null,glyph:null}),this.textSpans[t].span=n,d+=s.finalLineHeight;this.layerElement.appendChild(x)}for(;t<this.textSpans.length;)this.textSpans[t].span.style.display="none",t+=1;this._sizeChanged=!0},Ps.prototype.sourceRectAtTime=function(){if(this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged){this._sizeChanged=!1;var t=this.layerElement.getBBox();this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}}return this.bbox},Ps.prototype.getValue=function(){var t,e,s=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<s;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf&&(this._mdf=!0))},Ps.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){var t,e;this._sizeChanged=!0;var s,i,a,r=this.textAnimator.renderedLetters,n=this.textProperty.currentData.l;for(e=n.length,t=0;t<e;t+=1)n[t].n||(s=r[t],i=this.textSpans[t].span,(a=this.textSpans[t].glyph)&&a.renderFrame(),s._mdf.m&&i.setAttribute("transform",s.m),s._mdf.o&&i.setAttribute("opacity",s.o),s._mdf.sw&&i.setAttribute("stroke-width",s.sw),s._mdf.sc&&i.setAttribute("stroke",s.sc),s._mdf.fc&&i.setAttribute("fill",s.fc))}},r([$e],Ds),Ds.prototype.createContent=function(){var t=j("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},ws.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},ws.prototype.renderFrame=function(){},ws.prototype.getBaseElement=function(){return null},ws.prototype.destroy=function(){},ws.prototype.sourceRectAtTime=function(){},ws.prototype.hide=function(){},r([ze,je,Ze,Oe],ws),r([Be],As),As.prototype.createNull=function(t){return new ws(t,this.globalData,this)},As.prototype.createShape=function(t){return new ys(t,this.globalData,this)},As.prototype.createText=function(t){return new Ps(t,this.globalData,this)},As.prototype.createImage=function(t){return new $e(t,this.globalData,this)},As.prototype.createSolid=function(t){return new Ds(t,this.globalData,this)},As.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var s=j("clipPath"),a=j("rect");a.setAttribute("width",t.w),a.setAttribute("height",t.h),a.setAttribute("x",0),a.setAttribute("y",0);var r=L();s.setAttribute("id",r),s.appendChild(a),this.layerElement.setAttribute("clip-path","url("+i()+"#"+r+")"),e.appendChild(s),this.layers=t.layers,this.elements=l(t.layers.length)},As.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},As.prototype.updateContainerSize=function(){},As.prototype.findIndexByInd=function(t){var e=0,s=this.layers.length;for(e=0;e<s;e+=1)if(this.layers[e].ind===t)return e;return-1},As.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){e[t]=!0;var s=this.createItem(this.layers[t]);if(e[t]=s,N()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(s),s.initExpressions()),this.appendElementInPos(s,t),this.layers[t].tt){var i="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1;if(-1===i)return;if(this.elements[i]&&!0!==this.elements[i]){var a=e[i].getMatte(this.layers[t].tt);s.setMatte(a)}else this.buildItem(i),this.addPendingElement(s)}}},As.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,s=this.elements.length;e<s;){if(this.elements[e]===t){var i="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,a=this.elements[i].getMatte(this.layers[e].tt);t.setMatte(a);break}e+=1}}},As.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){var e;null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var s=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=s-1;e>=0;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<s;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},As.prototype.appendElementInPos=function(t,e){var s=t.getBaseElement();if(s){for(var i,a=0;a<e;)this.elements[a]&&!0!==this.elements[a]&&this.elements[a].getBaseElement()&&(i=this.elements[a].getBaseElement()),a+=1;i?this.layerElement.insertBefore(s,i):this.layerElement.appendChild(s)}},As.prototype.hide=function(){this.layerElement.style.display="none"},As.prototype.show=function(){this.layerElement.style.display="block"},r([ze,je,Ze,Oe,Qe],Ms),Ms.prototype.initElement=function(t,e,s){this.initFrame(),this.initBaseData(t,e,s),this.initTransform(t,e,s),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},Ms.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var s,i=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),s=i-1;s>=0;s-=1)(this.completeLayers||this.elements[s])&&(this.elements[s].prepareFrame(this.renderedFrame-this.layers[s].st),this.elements[s]._mdf&&(this._mdf=!0))}},Ms.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},Ms.prototype.setElements=function(t){this.elements=t},Ms.prototype.getElements=function(){return this.elements},Ms.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},Ms.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},r([As,Ms,Ue],Ts),Ts.prototype.createComp=function(t){return new Ts(t,this.globalData,this)},r([As],Fs),Fs.prototype.createComp=function(t){return new Ts(t,this.globalData,this)},Es.prototype={addTransformSequence:function(t){var e,s=t.length,i="_";for(e=0;e<s;e+=1)i+=t[e].transform.key+"_";var a=this.sequences[i];return a||(a={transforms:[].concat(t),finalTransform:new Ft,_mdf:!1},this.sequences[i]=a,this.sequenceList.push(a)),a},processSequence:function(t,e){for(var s=0,i=t.transforms.length,a=e;s<i&&!e;){if(t.transforms[s].transform.mProps._mdf){a=!0;break}s+=1}if(a)for(t.finalTransform.reset(),s=i-1;s>=0;s-=1)t.finalTransform.multiply(t.transforms[s].transform.mProps.v);t._mdf=a},processSequences:function(t){var e,s=this.sequenceList.length;for(e=0;e<s;e+=1)this.processSequence(this.sequenceList[e],t)},getNewKey:function(){return this.transform_key_count+=1,"_"+this.transform_key_count}};var Ls=function(){var t="__lottie_element_luma_buffer",e=null,s=null,i=null;function r(){var r,n,o;e||(r=j("svg"),n=j("filter"),o=j("feColorMatrix"),n.setAttribute("id",t),o.setAttribute("type","matrix"),o.setAttribute("color-interpolation-filters","sRGB"),o.setAttribute("values","0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0"),n.appendChild(o),r.appendChild(n),r.setAttribute("id",t+"_svg"),He.svgLumaHidden&&(r.style.display="none"),i=r,document.body.appendChild(i),e=a("canvas"),(s=e.getContext("2d")).filter="url(#"+t+")",s.fillStyle="rgba(0,0,0,0)",s.fillRect(0,0,1,1))}return{load:r,get:function(i){return e||r(),e.width=i.width,e.height=i.height,s.filter="url(#"+t+")",e}}};function Is(t,e){if(He.offscreenCanvas)return new OffscreenCanvas(t,e);var s=a("canvas");return s.width=t,s.height=e,s}var Rs={loadLumaCanvas:Ls.load,getLumaCanvas:Ls.get,createCanvas:Is},Vs={};function zs(t){var e,s,i=t.data.ef?t.data.ef.length:0;for(this.filters=[],e=0;e<i;e+=1){s=null;var a=t.data.ef[e].ty;if(Vs[a])s=new(0,Vs[a].effect)(t.effectsManager.effectElements[e],t);s&&this.filters.push(s)}this.filters.length&&t.addRenderableComponent(this)}function Os(t,e){var s;this.data=t,this.element=e,this.masksProperties=this.data.masksProperties||[],this.viewData=l(this.masksProperties.length);var i=this.masksProperties.length,a=!1;for(s=0;s<i;s+=1)"n"!==this.masksProperties[s].mode&&(a=!0),this.viewData[s]=Tt.getShapeProp(this.element,this.masksProperties[s],3);this.hasMasks=a,a&&this.element.addRenderableComponent(this)}function Ns(){}zs.prototype.renderFrame=function(t){var e,s=this.filters.length;for(e=0;e<s;e+=1)this.filters[e].renderFrame(t)},zs.prototype.getEffects=function(t){var e,s=this.filters.length,i=[];for(e=0;e<s;e+=1)this.filters[e].type===t&&i.push(this.filters[e]);return i},Os.prototype.renderFrame=function(){if(this.hasMasks){var t,e,s,i,a=this.element.finalTransform.mat,r=this.element.canvasContext,n=this.masksProperties.length;for(r.beginPath(),t=0;t<n;t+=1)if("n"!==this.masksProperties[t].mode){var o;this.masksProperties[t].inv&&(r.moveTo(0,0),r.lineTo(this.element.globalData.compSize.w,0),r.lineTo(this.element.globalData.compSize.w,this.element.globalData.compSize.h),r.lineTo(0,this.element.globalData.compSize.h),r.lineTo(0,0)),i=this.viewData[t].v,e=a.applyToPointArray(i.v[0][0],i.v[0][1],0),r.moveTo(e[0],e[1]);var h=i._length;for(o=1;o<h;o+=1)s=a.applyToTriplePoints(i.o[o-1],i.i[o],i.v[o]),r.bezierCurveTo(s[0],s[1],s[2],s[3],s[4],s[5]);s=a.applyToTriplePoints(i.o[o-1],i.i[0],i.v[0]),r.bezierCurveTo(s[0],s[1],s[2],s[3],s[4],s[5])}this.element.globalData.renderer.save(!0),r.clip()}},Os.prototype.getMaskProperty=Ye.prototype.getMaskProperty,Os.prototype.destroy=function(){this.element=null};var qs,Bs={1:"source-in",2:"source-out",3:"source-in",4:"source-out"};function Ws(t,e,s,i){this.styledShapes=[],this.tr=[0,0,0,0,0,0];var a,r=4;"rc"===e.ty?r=5:"el"===e.ty?r=6:"sr"===e.ty&&(r=7),this.sh=Tt.getShapeProp(t,e,r,t);var n,o=s.length;for(a=0;a<o;a+=1)s[a].closed||(n={transforms:i.addTransformSequence(s[a].transforms),trNodes:[]},this.styledShapes.push(n),s[a].elements.push(n))}function js(t,e,s){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.itemsData=[],this.prevViewData=[],this.shapeModifiers=[],this.processedElements=[],this.transformsManager=new Es,this.initElement(t,e,s)}function Ys(t,e,s){this.textSpans=[],this.yOffset=0,this.fillColorAnim=!1,this.strokeColorAnim=!1,this.strokeWidthAnim=!1,this.stroke=!1,this.fill=!1,this.justifyOffset=0,this.currentRender=null,this.renderType="canvas",this.values={fill:"rgba(0,0,0,0)",stroke:"rgba(0,0,0,0)",sWidth:0,fValue:""},this.initElement(t,e,s)}function Js(t,e,s){this.assetData=e.getAssetData(t.refId),this.img=e.imageLoader.getAsset(this.assetData),this.initElement(t,e,s)}function Hs(t,e,s){this.initElement(t,e,s)}function Gs(){}function Xs(){this.opacity=-1,this.transform=h("float32",16),this.fillStyle="",this.strokeStyle="",this.lineWidth="",this.lineCap="",this.lineJoin="",this.miterLimit="",this.id=Math.random()}function Ks(){var t;this.stack=[],this.cArrPos=0,this.cTr=new Ft;for(t=0;t<15;t+=1){var e=new Xs;this.stack[t]=e}this._length=15,this.nativeContext=null,this.transformMat=new Ft,this.currentOpacity=1,this.currentFillStyle="",this.appliedFillStyle="",this.currentStrokeStyle="",this.appliedStrokeStyle="",this.currentLineWidth="",this.appliedLineWidth="",this.currentLineCap="",this.appliedLineCap="",this.currentLineJoin="",this.appliedLineJoin="",this.appliedMiterLimit="",this.currentMiterLimit=""}function Us(t,e,s){this.completeLayers=!1,this.layers=t.layers,this.pendingElements=[],this.elements=l(this.layers.length),this.initElement(t,e,s),this.tm=t.tm?vt.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function Zs(t,e){this.animationItem=t,this.renderConfig={clearCanvas:!e||void 0===e.clearCanvas||e.clearCanvas,context:e&&e.context||null,progressiveLoad:e&&e.progressiveLoad||!1,preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",className:e&&e.className||"",id:e&&e.id||"",runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.renderConfig.dpr=e&&e.dpr||1,this.animationItem.wrapper&&(this.renderConfig.dpr=e&&e.dpr||window.devicePixelRatio||1),this.renderedFrame=-1,this.globalData={frameNum:-1,_mdf:!1,renderConfig:this.renderConfig,currentGlobalAlpha:-1},this.contextData=new Ks,this.elements=[],this.pendingElements=[],this.transformMat=new Ft,this.completeLayers=!1,this.rendererType="canvas",this.renderConfig.clearCanvas&&(this.ctxTransform=this.contextData.transform.bind(this.contextData),this.ctxOpacity=this.contextData.opacity.bind(this.contextData),this.ctxFillStyle=this.contextData.fillStyle.bind(this.contextData),this.ctxStrokeStyle=this.contextData.strokeStyle.bind(this.contextData),this.ctxLineWidth=this.contextData.lineWidth.bind(this.contextData),this.ctxLineCap=this.contextData.lineCap.bind(this.contextData),this.ctxLineJoin=this.contextData.lineJoin.bind(this.contextData),this.ctxMiterLimit=this.contextData.miterLimit.bind(this.contextData),this.ctxFill=this.contextData.fill.bind(this.contextData),this.ctxFillRect=this.contextData.fillRect.bind(this.contextData),this.ctxStroke=this.contextData.stroke.bind(this.contextData),this.save=this.contextData.save.bind(this.contextData))}return Ns.prototype={createElements:function(){},initRendererElement:function(){},createContainerElements:function(){if(this.data.tt>=1){this.buffers=[];var t=this.globalData.canvasContext,e=Rs.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(e);var s=Rs.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(s),this.data.tt>=3&&!document._isProxy&&Rs.loadLumaCanvas()}this.canvasContext=this.globalData.canvasContext,this.transformCanvas=this.globalData.transformCanvas,this.renderableEffectsManager=new zs(this),this.searchEffectTransforms()},createContent:function(){},setBlendMode:function(){var t=this.globalData;if(t.blendMode!==this.data.bm){t.blendMode=this.data.bm;var e=De(this.data.bm);t.canvasContext.globalCompositeOperation=e}},createRenderableComponents:function(){this.maskManager=new Os(this.data,this),this.transformEffects=this.renderableEffectsManager.getEffects(We)},hideElement:function(){this.hidden||this.isInRange&&!this.isTransparent||(this.hidden=!0)},showElement:function(){this.isInRange&&!this.isTransparent&&(this.hidden=!1,this._isFirstFrame=!0,this.maskManager._isFirstFrame=!0)},clearCanvas:function(t){t.clearRect(this.transformCanvas.tx,this.transformCanvas.ty,this.transformCanvas.w*this.transformCanvas.sx,this.transformCanvas.h*this.transformCanvas.sy)},prepareLayer:function(){if(this.data.tt>=1){var t=this.buffers[0].getContext("2d");this.clearCanvas(t),t.drawImage(this.canvasContext.canvas,0,0),this.currentTransform=this.canvasContext.getTransform(),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform)}},exitLayer:function(){if(this.data.tt>=1){var t=this.buffers[1],e=t.getContext("2d");if(this.clearCanvas(e),e.drawImage(this.canvasContext.canvas,0,0),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform),this.comp.getElementById("tp"in this.data?this.data.tp:this.data.ind-1).renderFrame(!0),this.canvasContext.setTransform(1,0,0,1,0,0),this.data.tt>=3&&!document._isProxy){var s=Rs.getLumaCanvas(this.canvasContext.canvas);s.getContext("2d").drawImage(this.canvasContext.canvas,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.drawImage(s,0,0)}this.canvasContext.globalCompositeOperation=Bs[this.data.tt],this.canvasContext.drawImage(t,0,0),this.canvasContext.globalCompositeOperation="destination-over",this.canvasContext.drawImage(this.buffers[0],0,0),this.canvasContext.setTransform(this.currentTransform),this.canvasContext.globalCompositeOperation="source-over"}},renderFrame:function(t){if(!this.hidden&&!this.data.hd&&(1!==this.data.td||t)){this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.setBlendMode();var e=0===this.data.ty;this.prepareLayer(),this.globalData.renderer.save(e),this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props),this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity),this.renderInnerContent(),this.globalData.renderer.restore(e),this.exitLayer(),this.maskManager.hasMasks&&this.globalData.renderer.restore(!0),this._isFirstFrame&&(this._isFirstFrame=!1)}},destroy:function(){this.canvasContext=null,this.data=null,this.globalData=null,this.maskManager.destroy()},mHelper:new Ft},Ns.prototype.hide=Ns.prototype.hideElement,Ns.prototype.show=Ns.prototype.showElement,Ws.prototype.setAsAnimated=as.prototype.setAsAnimated,r([ze,je,Ns,es,Ze,Oe,Se],js),js.prototype.initElement=Qe.prototype.initElement,js.prototype.transformHelper={opacity:1,_opMdf:!1},js.prototype.dashResetter=[],js.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[])},js.prototype.createStyleElement=function(t,e){var s={data:t,type:t.ty,preTransforms:this.transformsManager.addTransformSequence(e),transforms:[],elements:[],closed:!0===t.hd},i={};if("fl"===t.ty||"st"===t.ty?(i.c=vt.getProp(this,t.c,1,255,this),i.c.k||(s.co="rgb("+v(i.c.v[0])+","+v(i.c.v[1])+","+v(i.c.v[2])+")")):"gf"!==t.ty&&"gs"!==t.ty||(i.s=vt.getProp(this,t.s,1,null,this),i.e=vt.getProp(this,t.e,1,null,this),i.h=vt.getProp(this,t.h||{k:0},0,.01,this),i.a=vt.getProp(this,t.a||{k:0},0,x,this),i.g=new ps(this,t.g,this)),i.o=vt.getProp(this,t.o,0,.01,this),"st"===t.ty||"gs"===t.ty){if(s.lc=ss[t.lc||2],s.lj=is[t.lj||2],1==t.lj&&(s.ml=t.ml),i.w=vt.getProp(this,t.w,0,null,this),i.w.k||(s.wi=i.w.v),t.d){var a=new ns(this,t.d,"canvas",this);i.d=a,i.d.k||(s.da=i.d.dashArray,s.do=i.d.dashoffset[0])}}else s.r=2===t.r?"evenodd":"nonzero";return this.stylesList.push(s),i.style=s,i},js.prototype.createGroupElement=function(){return{it:[],prevViewData:[]}},js.prototype.createTransformElement=function(t){return{transform:{opacity:1,_opMdf:!1,key:this.transformsManager.getNewKey(),op:vt.getProp(this,t.o,0,.01,this),mProps:Yt.getTransformProperty(this,t,this)}}},js.prototype.createShapeElement=function(t){var e=new Ws(this,t,this.stylesList,this.transformsManager);return this.shapes.push(e),this.addShapeToModifiers(e),e},js.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[]),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame)},js.prototype.addTransformToStyleList=function(t){var e,s=this.stylesList.length;for(e=0;e<s;e+=1)this.stylesList[e].closed||this.stylesList[e].transforms.push(t)},js.prototype.removeTransformFromStyleList=function(){var t,e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].closed||this.stylesList[t].transforms.pop()},js.prototype.closeStyles=function(t){var e,s=t.length;for(e=0;e<s;e+=1)t[e].closed=!0},js.prototype.searchShapes=function(t,e,s,i,a){var r,n,o,h,l,p,f=t.length-1,c=[],d=[],m=[].concat(a);for(r=f;r>=0;r-=1){if((h=this.searchProcessedElement(t[r]))?e[r]=s[h-1]:t[r]._shouldRender=i,"fl"===t[r].ty||"st"===t[r].ty||"gf"===t[r].ty||"gs"===t[r].ty)h?e[r].style.closed=!1:e[r]=this.createStyleElement(t[r],m),c.push(e[r].style);else if("gr"===t[r].ty){if(h)for(o=e[r].it.length,n=0;n<o;n+=1)e[r].prevViewData[n]=e[r].it[n];else e[r]=this.createGroupElement(t[r]);this.searchShapes(t[r].it,e[r].it,e[r].prevViewData,i,m)}else"tr"===t[r].ty?(h||(p=this.createTransformElement(t[r]),e[r]=p),m.push(e[r]),this.addTransformToStyleList(e[r])):"sh"===t[r].ty||"rc"===t[r].ty||"el"===t[r].ty||"sr"===t[r].ty?h||(e[r]=this.createShapeElement(t[r])):"tm"===t[r].ty||"rd"===t[r].ty||"pb"===t[r].ty||"zz"===t[r].ty||"op"===t[r].ty?(h?(l=e[r]).closed=!1:((l=qt.getModifier(t[r].ty)).init(this,t[r]),e[r]=l,this.shapeModifiers.push(l)),d.push(l)):"rp"===t[r].ty&&(h?(l=e[r]).closed=!0:(l=qt.getModifier(t[r].ty),e[r]=l,l.init(this,t,r,e),this.shapeModifiers.push(l),i=!1),d.push(l));this.addProcessedElement(t[r],r+1)}for(this.removeTransformFromStyleList(),this.closeStyles(c),f=d.length,r=0;r<f;r+=1)d[r].closed=!0},js.prototype.renderInnerContent=function(){this.transformHelper.opacity=1,this.transformHelper._opMdf=!1,this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame),this.renderShape(this.transformHelper,this.shapesData,this.itemsData,!0)},js.prototype.renderShapeTransform=function(t,e){(t._opMdf||e.op._mdf||this._isFirstFrame)&&(e.opacity=t.opacity,e.opacity*=e.op.v,e._opMdf=!0)},js.prototype.drawLayer=function(){var t,e,s,i,a,r,n,o,h,l=this.stylesList.length,p=this.globalData.renderer,f=this.globalData.canvasContext;for(t=0;t<l;t+=1)if(("st"!==(o=(h=this.stylesList[t]).type)&&"gs"!==o||0!==h.wi)&&h.data._shouldRender&&0!==h.coOp&&0!==this.globalData.currentGlobalAlpha){for(p.save(),r=h.elements,"st"===o||"gs"===o?(p.ctxStrokeStyle("st"===o?h.co:h.grd),p.ctxLineWidth(h.wi),p.ctxLineCap(h.lc),p.ctxLineJoin(h.lj),p.ctxMiterLimit(h.ml||0)):p.ctxFillStyle("fl"===o?h.co:h.grd),p.ctxOpacity(h.coOp),"st"!==o&&"gs"!==o&&f.beginPath(),p.ctxTransform(h.preTransforms.finalTransform.props),s=r.length,e=0;e<s;e+=1){for("st"!==o&&"gs"!==o||(f.beginPath(),h.da&&(f.setLineDash(h.da),f.lineDashOffset=h.do)),a=(n=r[e].trNodes).length,i=0;i<a;i+=1)"m"===n[i].t?f.moveTo(n[i].p[0],n[i].p[1]):"c"===n[i].t?f.bezierCurveTo(n[i].pts[0],n[i].pts[1],n[i].pts[2],n[i].pts[3],n[i].pts[4],n[i].pts[5]):f.closePath();"st"!==o&&"gs"!==o||(p.ctxStroke(),h.da&&f.setLineDash(this.dashResetter))}"st"!==o&&"gs"!==o&&this.globalData.renderer.ctxFill(h.r),p.restore()}},js.prototype.renderShape=function(t,e,s,i){var a,r;for(r=t,a=e.length-1;a>=0;a-=1)"tr"===e[a].ty?(r=s[a].transform,this.renderShapeTransform(t,r)):"sh"===e[a].ty||"el"===e[a].ty||"rc"===e[a].ty||"sr"===e[a].ty?this.renderPath(e[a],s[a]):"fl"===e[a].ty?this.renderFill(e[a],s[a],r):"st"===e[a].ty?this.renderStroke(e[a],s[a],r):"gf"===e[a].ty||"gs"===e[a].ty?this.renderGradientFill(e[a],s[a],r):"gr"===e[a].ty?this.renderShape(r,e[a].it,s[a].it):e[a].ty;i&&this.drawLayer()},js.prototype.renderStyledShape=function(t,e){if(this._isFirstFrame||e._mdf||t.transforms._mdf){var s,i,a,r=t.trNodes,n=e.paths,o=n._length;r.length=0;var h=t.transforms.finalTransform;for(a=0;a<o;a+=1){var l=n.shapes[a];if(l&&l.v){for(i=l._length,s=1;s<i;s+=1)1===s&&r.push({t:"m",p:h.applyToPointArray(l.v[0][0],l.v[0][1],0)}),r.push({t:"c",pts:h.applyToTriplePoints(l.o[s-1],l.i[s],l.v[s])});1===i&&r.push({t:"m",p:h.applyToPointArray(l.v[0][0],l.v[0][1],0)}),l.c&&i&&(r.push({t:"c",pts:h.applyToTriplePoints(l.o[s-1],l.i[0],l.v[0])}),r.push({t:"z"}))}}t.trNodes=r}},js.prototype.renderPath=function(t,e){if(!0!==t.hd&&t._shouldRender){var s,i=e.styledShapes.length;for(s=0;s<i;s+=1)this.renderStyledShape(e.styledShapes[s],e.sh)}},js.prototype.renderFill=function(t,e,s){var i=e.style;(e.c._mdf||this._isFirstFrame)&&(i.co="rgb("+v(e.c.v[0])+","+v(e.c.v[1])+","+v(e.c.v[2])+")"),(e.o._mdf||s._opMdf||this._isFirstFrame)&&(i.coOp=e.o.v*s.opacity)},js.prototype.renderGradientFill=function(t,e,s){var i,a=e.style;if(!a.grd||e.g._mdf||e.s._mdf||e.e._mdf||1!==t.t&&(e.h._mdf||e.a._mdf)){var r,n=this.globalData.canvasContext,o=e.s.v,h=e.e.v;if(1===t.t)i=n.createLinearGradient(o[0],o[1],h[0],h[1]);else{var l=Math.sqrt(Math.pow(o[0]-h[0],2)+Math.pow(o[1]-h[1],2)),p=Math.atan2(h[1]-o[1],h[0]-o[0]),f=e.h.v;f>=1?f=.99:f<=-1&&(f=-.99);var c=l*f,d=Math.cos(p+e.a.v)*c+o[0],m=Math.sin(p+e.a.v)*c+o[1];i=n.createRadialGradient(d,m,0,o[0],o[1],l)}var u=t.g.p,g=e.g.c,y=1;for(r=0;r<u;r+=1)e.g._hasOpacity&&e.g._collapsable&&(y=e.g.o[2*r+1]),i.addColorStop(g[4*r]/100,"rgba("+g[4*r+1]+","+g[4*r+2]+","+g[4*r+3]+","+y+")");a.grd=i}a.coOp=e.o.v*s.opacity},js.prototype.renderStroke=function(t,e,s){var i=e.style,a=e.d;a&&(a._mdf||this._isFirstFrame)&&(i.da=a.dashArray,i.do=a.dashoffset[0]),(e.c._mdf||this._isFirstFrame)&&(i.co="rgb("+v(e.c.v[0])+","+v(e.c.v[1])+","+v(e.c.v[2])+")"),(e.o._mdf||s._opMdf||this._isFirstFrame)&&(i.coOp=e.o.v*s.opacity),(e.w._mdf||this._isFirstFrame)&&(i.wi=e.w.v)},js.prototype.destroy=function(){this.shapesData=null,this.globalData=null,this.canvasContext=null,this.stylesList.length=0,this.itemsData.length=0},r([ze,je,Ns,Ze,Oe,Se,ks],Ys),Ys.prototype.tHelper=a("canvas").getContext("2d"),Ys.prototype.buildNewText=function(){var t=this.textProperty.currentData;this.renderedLetters=l(t.l?t.l.length:0);var e=!1;t.fc?(e=!0,this.values.fill=this.buildColor(t.fc)):this.values.fill="rgba(0,0,0,0)",this.fill=e;var s=!1;t.sc&&(s=!0,this.values.stroke=this.buildColor(t.sc),this.values.sWidth=t.sw);var i,a,r,n,o,h,p,f,c,d,m,u,g=this.globalData.fontManager.getFontByName(t.f),y=t.l,v=this.mHelper;this.stroke=s,this.values.fValue=t.finalSize+"px "+this.globalData.fontManager.getFontByName(t.f).fFamily,a=t.finalText.length;var b=this.data.singleShape,_=.001*t.tr*t.finalSize,C=0,x=0,k=!0,S=0;for(i=0;i<a;i+=1){n=(r=this.globalData.fontManager.getCharData(t.finalText[i],g.fStyle,this.globalData.fontManager.getFontByName(t.f).fFamily))&&r.data||{},v.reset(),b&&y[i].n&&(C=-_,x+=t.yOffset,x+=k?1:0,k=!1),c=(p=n.shapes?n.shapes[0].it:[]).length,v.scale(t.finalSize/100,t.finalSize/100),b&&this.applyTextPropertiesToMatrix(t,v,y[i].line,C,x),m=l(c-1);var P=0;for(f=0;f<c;f+=1)if("sh"===p[f].ty){for(h=p[f].ks.k.i.length,d=p[f].ks.k,u=[],o=1;o<h;o+=1)1===o&&u.push(v.applyToX(d.v[0][0],d.v[0][1],0),v.applyToY(d.v[0][0],d.v[0][1],0)),u.push(v.applyToX(d.o[o-1][0],d.o[o-1][1],0),v.applyToY(d.o[o-1][0],d.o[o-1][1],0),v.applyToX(d.i[o][0],d.i[o][1],0),v.applyToY(d.i[o][0],d.i[o][1],0),v.applyToX(d.v[o][0],d.v[o][1],0),v.applyToY(d.v[o][0],d.v[o][1],0));u.push(v.applyToX(d.o[o-1][0],d.o[o-1][1],0),v.applyToY(d.o[o-1][0],d.o[o-1][1],0),v.applyToX(d.i[0][0],d.i[0][1],0),v.applyToY(d.i[0][0],d.i[0][1],0),v.applyToX(d.v[0][0],d.v[0][1],0),v.applyToY(d.v[0][0],d.v[0][1],0)),m[P]=u,P+=1}b&&(C+=y[i].l,C+=_),this.textSpans[S]?this.textSpans[S].elem=m:this.textSpans[S]={elem:m},S+=1}},Ys.prototype.renderInnerContent=function(){var t,e,s,i,a,r;this.validateText(),this.canvasContext.font=this.values.fValue,this.globalData.renderer.ctxLineCap("butt"),this.globalData.renderer.ctxLineJoin("miter"),this.globalData.renderer.ctxMiterLimit(4),this.data.singleShape||this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag);var n,o=this.textAnimator.renderedLetters,h=this.textProperty.currentData.l;e=h.length;var l,p,f=null,c=null,d=null,m=this.globalData.renderer;for(t=0;t<e;t+=1)if(!h[t].n){if((n=o[t])&&(m.save(),m.ctxTransform(n.p),m.ctxOpacity(n.o)),this.fill){for(n&&n.fc?f!==n.fc&&(m.ctxFillStyle(n.fc),f=n.fc):f!==this.values.fill&&(f=this.values.fill,m.ctxFillStyle(this.values.fill)),i=(l=this.textSpans[t].elem).length,this.globalData.canvasContext.beginPath(),s=0;s<i;s+=1)for(r=(p=l[s]).length,this.globalData.canvasContext.moveTo(p[0],p[1]),a=2;a<r;a+=6)this.globalData.canvasContext.bezierCurveTo(p[a],p[a+1],p[a+2],p[a+3],p[a+4],p[a+5]);this.globalData.canvasContext.closePath(),m.ctxFill()}if(this.stroke){for(n&&n.sw?d!==n.sw&&(d=n.sw,m.ctxLineWidth(n.sw)):d!==this.values.sWidth&&(d=this.values.sWidth,m.ctxLineWidth(this.values.sWidth)),n&&n.sc?c!==n.sc&&(c=n.sc,m.ctxStrokeStyle(n.sc)):c!==this.values.stroke&&(c=this.values.stroke,m.ctxStrokeStyle(this.values.stroke)),i=(l=this.textSpans[t].elem).length,this.globalData.canvasContext.beginPath(),s=0;s<i;s+=1)for(r=(p=l[s]).length,this.globalData.canvasContext.moveTo(p[0],p[1]),a=2;a<r;a+=6)this.globalData.canvasContext.bezierCurveTo(p[a],p[a+1],p[a+2],p[a+3],p[a+4],p[a+5]);this.globalData.canvasContext.closePath(),m.ctxStroke()}n&&this.globalData.renderer.restore()}},r([ze,je,Ns,Ze,Oe,Se],Js),Js.prototype.initElement=ys.prototype.initElement,Js.prototype.prepareFrame=$e.prototype.prepareFrame,Js.prototype.createContent=function(){if(this.img.width&&(this.assetData.w!==this.img.width||this.assetData.h!==this.img.height)){var t=a("canvas");t.width=this.assetData.w,t.height=this.assetData.h;var e,s,i=t.getContext("2d"),r=this.img.width,n=this.img.height,o=r/n,h=this.assetData.w/this.assetData.h,l=this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio;o>h&&"xMidYMid slice"===l||o<h&&"xMidYMid slice"!==l?e=(s=n)*h:s=(e=r)/h,i.drawImage(this.img,(r-e)/2,(n-s)/2,e,s,0,0,this.assetData.w,this.assetData.h),this.img=t}},Js.prototype.renderInnerContent=function(){this.canvasContext.drawImage(this.img,0,0)},Js.prototype.destroy=function(){this.img=null},r([ze,je,Ns,Ze,Oe,Se],Hs),Hs.prototype.initElement=ys.prototype.initElement,Hs.prototype.prepareFrame=$e.prototype.prepareFrame,Hs.prototype.renderInnerContent=function(){this.globalData.renderer.ctxFillStyle(this.data.sc),this.globalData.renderer.ctxFillRect(0,0,this.data.sw,this.data.sh)},r([Be],Gs),Gs.prototype.createShape=function(t){return new js(t,this.globalData,this)},Gs.prototype.createText=function(t){return new Ys(t,this.globalData,this)},Gs.prototype.createImage=function(t){return new Js(t,this.globalData,this)},Gs.prototype.createSolid=function(t){return new Hs(t,this.globalData,this)},Gs.prototype.createNull=Fs.prototype.createNull,Gs.prototype.ctxTransform=function(t){1===t[0]&&0===t[1]&&0===t[4]&&1===t[5]&&0===t[12]&&0===t[13]||this.canvasContext.transform(t[0],t[1],t[4],t[5],t[12],t[13])},Gs.prototype.ctxOpacity=function(t){this.canvasContext.globalAlpha*=t<0?0:t},Gs.prototype.ctxFillStyle=function(t){this.canvasContext.fillStyle=t},Gs.prototype.ctxStrokeStyle=function(t){this.canvasContext.strokeStyle=t},Gs.prototype.ctxLineWidth=function(t){this.canvasContext.lineWidth=t},Gs.prototype.ctxLineCap=function(t){this.canvasContext.lineCap=t},Gs.prototype.ctxLineJoin=function(t){this.canvasContext.lineJoin=t},Gs.prototype.ctxMiterLimit=function(t){this.canvasContext.miterLimit=t},Gs.prototype.ctxFill=function(t){this.canvasContext.fill(t)},Gs.prototype.ctxFillRect=function(t,e,s,i){this.canvasContext.fillRect(t,e,s,i)},Gs.prototype.ctxStroke=function(){this.canvasContext.stroke()},Gs.prototype.reset=function(){this.renderConfig.clearCanvas?this.contextData.reset():this.canvasContext.restore()},Gs.prototype.save=function(){this.canvasContext.save()},Gs.prototype.restore=function(t){this.renderConfig.clearCanvas?(t&&(this.globalData.blendMode="source-over"),this.contextData.restore(t)):this.canvasContext.restore()},Gs.prototype.configAnimation=function(t){if(this.animationItem.wrapper){this.animationItem.container=a("canvas");var e=this.animationItem.container.style;e.width="100%",e.height="100%";var s="0px 0px 0px";e.transformOrigin=s,e.mozTransformOrigin=s,e.webkitTransformOrigin=s,e["-webkit-transform"]=s,e.contentVisibility=this.renderConfig.contentVisibility,this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.animationItem.container.setAttribute("id",this.renderConfig.id)}else this.canvasContext=this.renderConfig.context;this.contextData.setContext(this.canvasContext),this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.setupGlobalData(t,document.body),this.globalData.canvasContext=this.canvasContext,this.globalData.renderer=this,this.globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=l(t.layers.length),this.updateContainerSize()},Gs.prototype.updateContainerSize=function(t,e){var s,i,a,r;if(this.reset(),t?(s=t,i=e,this.canvasContext.canvas.width=s,this.canvasContext.canvas.height=i):(this.animationItem.wrapper&&this.animationItem.container?(s=this.animationItem.wrapper.offsetWidth,i=this.animationItem.wrapper.offsetHeight):(s=this.canvasContext.canvas.width,i=this.canvasContext.canvas.height),this.canvasContext.canvas.width=s*this.renderConfig.dpr,this.canvasContext.canvas.height=i*this.renderConfig.dpr),-1!==this.renderConfig.preserveAspectRatio.indexOf("meet")||-1!==this.renderConfig.preserveAspectRatio.indexOf("slice")){var n=this.renderConfig.preserveAspectRatio.split(" "),o=n[1]||"meet",h=n[0]||"xMidYMid",l=h.substr(0,4),p=h.substr(4);a=s/i,(r=this.transformCanvas.w/this.transformCanvas.h)>a&&"meet"===o||r<a&&"slice"===o?(this.transformCanvas.sx=s/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=s/(this.transformCanvas.w/this.renderConfig.dpr)):(this.transformCanvas.sx=i/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.sy=i/(this.transformCanvas.h/this.renderConfig.dpr)),this.transformCanvas.tx="xMid"===l&&(r<a&&"meet"===o||r>a&&"slice"===o)?(s-this.transformCanvas.w*(i/this.transformCanvas.h))/2*this.renderConfig.dpr:"xMax"===l&&(r<a&&"meet"===o||r>a&&"slice"===o)?(s-this.transformCanvas.w*(i/this.transformCanvas.h))*this.renderConfig.dpr:0,this.transformCanvas.ty="YMid"===p&&(r>a&&"meet"===o||r<a&&"slice"===o)?(i-this.transformCanvas.h*(s/this.transformCanvas.w))/2*this.renderConfig.dpr:"YMax"===p&&(r>a&&"meet"===o||r<a&&"slice"===o)?(i-this.transformCanvas.h*(s/this.transformCanvas.w))*this.renderConfig.dpr:0}else"none"===this.renderConfig.preserveAspectRatio?(this.transformCanvas.sx=s/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=i/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.tx=0,this.transformCanvas.ty=0):(this.transformCanvas.sx=this.renderConfig.dpr,this.transformCanvas.sy=this.renderConfig.dpr,this.transformCanvas.tx=0,this.transformCanvas.ty=0);this.transformCanvas.props=[this.transformCanvas.sx,0,0,0,0,this.transformCanvas.sy,0,0,0,0,1,0,this.transformCanvas.tx,this.transformCanvas.ty,0,1],this.ctxTransform(this.transformCanvas.props),this.canvasContext.beginPath(),this.canvasContext.rect(0,0,this.transformCanvas.w,this.transformCanvas.h),this.canvasContext.closePath(),this.canvasContext.clip(),this.renderFrame(this.renderedFrame,!0)},Gs.prototype.destroy=function(){var t;for(this.renderConfig.clearCanvas&&this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),t=(this.layers?this.layers.length:0)-1;t>=0;t-=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.globalData.canvasContext=null,this.animationItem.container=null,this.destroyed=!0},Gs.prototype.renderFrame=function(t,e){if((this.renderedFrame!==t||!0!==this.renderConfig.clearCanvas||e)&&!this.destroyed&&-1!==t){var s;this.renderedFrame=t,this.globalData.frameNum=t-this.animationItem._isFirstFrame,this.globalData.frameId+=1,this.globalData._mdf=!this.renderConfig.clearCanvas||e,this.globalData.projectInterface.currentFrame=t;var i=this.layers.length;for(this.completeLayers||this.checkLayers(t),s=i-1;s>=0;s-=1)(this.completeLayers||this.elements[s])&&this.elements[s].prepareFrame(t-this.layers[s].st);if(this.globalData._mdf){for(!0===this.renderConfig.clearCanvas?this.canvasContext.clearRect(0,0,this.transformCanvas.w,this.transformCanvas.h):this.save(),s=i-1;s>=0;s-=1)(this.completeLayers||this.elements[s])&&this.elements[s].renderFrame();!0!==this.renderConfig.clearCanvas&&this.restore()}}},Gs.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){var s=this.createItem(this.layers[t],this,this.globalData);e[t]=s,s.initExpressions()}},Gs.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},Gs.prototype.hide=function(){this.animationItem.container.style.display="none"},Gs.prototype.show=function(){this.animationItem.container.style.display="block"},Ks.prototype.duplicate=function(){var t=2*this._length,e=0;for(e=this._length;e<t;e+=1)this.stack[e]=new Xs;this._length=t},Ks.prototype.reset=function(){this.cArrPos=0,this.cTr.reset(),this.stack[this.cArrPos].opacity=1},Ks.prototype.restore=function(t){this.cArrPos-=1;var e,s=this.stack[this.cArrPos],i=s.transform,a=this.cTr.props;for(e=0;e<16;e+=1)a[e]=i[e];if(t){this.nativeContext.restore();var r=this.stack[this.cArrPos+1];this.appliedFillStyle=r.fillStyle,this.appliedStrokeStyle=r.strokeStyle,this.appliedLineWidth=r.lineWidth,this.appliedLineCap=r.lineCap,this.appliedLineJoin=r.lineJoin,this.appliedMiterLimit=r.miterLimit}this.nativeContext.setTransform(i[0],i[1],i[4],i[5],i[12],i[13]),(t||-1!==s.opacity&&this.currentOpacity!==s.opacity)&&(this.nativeContext.globalAlpha=s.opacity,this.currentOpacity=s.opacity),this.currentFillStyle=s.fillStyle,this.currentStrokeStyle=s.strokeStyle,this.currentLineWidth=s.lineWidth,this.currentLineCap=s.lineCap,this.currentLineJoin=s.lineJoin,this.currentMiterLimit=s.miterLimit},Ks.prototype.save=function(t){t&&this.nativeContext.save();var e=this.cTr.props;this._length<=this.cArrPos&&this.duplicate();var s,i=this.stack[this.cArrPos];for(s=0;s<16;s+=1)i.transform[s]=e[s];this.cArrPos+=1;var a=this.stack[this.cArrPos];a.opacity=i.opacity,a.fillStyle=i.fillStyle,a.strokeStyle=i.strokeStyle,a.lineWidth=i.lineWidth,a.lineCap=i.lineCap,a.lineJoin=i.lineJoin,a.miterLimit=i.miterLimit},Ks.prototype.setOpacity=function(t){this.stack[this.cArrPos].opacity=t},Ks.prototype.setContext=function(t){this.nativeContext=t},Ks.prototype.fillStyle=function(t){this.stack[this.cArrPos].fillStyle!==t&&(this.currentFillStyle=t,this.stack[this.cArrPos].fillStyle=t)},Ks.prototype.strokeStyle=function(t){this.stack[this.cArrPos].strokeStyle!==t&&(this.currentStrokeStyle=t,this.stack[this.cArrPos].strokeStyle=t)},Ks.prototype.lineWidth=function(t){this.stack[this.cArrPos].lineWidth!==t&&(this.currentLineWidth=t,this.stack[this.cArrPos].lineWidth=t)},Ks.prototype.lineCap=function(t){this.stack[this.cArrPos].lineCap!==t&&(this.currentLineCap=t,this.stack[this.cArrPos].lineCap=t)},Ks.prototype.lineJoin=function(t){this.stack[this.cArrPos].lineJoin!==t&&(this.currentLineJoin=t,this.stack[this.cArrPos].lineJoin=t)},Ks.prototype.miterLimit=function(t){this.stack[this.cArrPos].miterLimit!==t&&(this.currentMiterLimit=t,this.stack[this.cArrPos].miterLimit=t)},Ks.prototype.transform=function(t){this.transformMat.cloneFromProps(t);var e=this.cTr;this.transformMat.multiply(e),e.cloneFromProps(this.transformMat.props);var s=e.props;this.nativeContext.setTransform(s[0],s[1],s[4],s[5],s[12],s[13])},Ks.prototype.opacity=function(t){var e=this.stack[this.cArrPos].opacity;e*=t<0?0:t,this.stack[this.cArrPos].opacity!==e&&(this.currentOpacity!==t&&(this.nativeContext.globalAlpha=t,this.currentOpacity=t),this.stack[this.cArrPos].opacity=e)},Ks.prototype.fill=function(t){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fill(t)},Ks.prototype.fillRect=function(t,e,s,i){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fillRect(t,e,s,i)},Ks.prototype.stroke=function(){this.appliedStrokeStyle!==this.currentStrokeStyle&&(this.appliedStrokeStyle=this.currentStrokeStyle,this.nativeContext.strokeStyle=this.appliedStrokeStyle),this.appliedLineWidth!==this.currentLineWidth&&(this.appliedLineWidth=this.currentLineWidth,this.nativeContext.lineWidth=this.appliedLineWidth),this.appliedLineCap!==this.currentLineCap&&(this.appliedLineCap=this.currentLineCap,this.nativeContext.lineCap=this.appliedLineCap),this.appliedLineJoin!==this.currentLineJoin&&(this.appliedLineJoin=this.currentLineJoin,this.nativeContext.lineJoin=this.appliedLineJoin),this.appliedMiterLimit!==this.currentMiterLimit&&(this.appliedMiterLimit=this.currentMiterLimit,this.nativeContext.miterLimit=this.appliedMiterLimit),this.nativeContext.stroke()},r([Gs,Ms,Ns],Us),Us.prototype.renderInnerContent=function(){var t,e=this.canvasContext;for(e.beginPath(),e.moveTo(0,0),e.lineTo(this.data.w,0),e.lineTo(this.data.w,this.data.h),e.lineTo(0,this.data.h),e.lineTo(0,0),e.clip(),t=this.layers.length-1;t>=0;t-=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},Us.prototype.destroy=function(){var t;for(t=this.layers.length-1;t>=0;t-=1)this.elements[t]&&this.elements[t].destroy();this.layers=null,this.elements=null},Us.prototype.createComp=function(t){return new Us(t,this.globalData,this)},r([Gs],Zs),Zs.prototype.createComp=function(t){return new Us(t,this.globalData,this)},qs=Zs,U["canvas"]=qs,qt.registerModifier("tm",Wt),qt.registerModifier("pb",jt),qt.registerModifier("rp",Jt),qt.registerModifier("rd",Ht),qt.registerModifier("zz",le),qt.registerModifier("op",_e),Lt}));
diff --git a/build/player/lottie_light_html.js b/build/player/lottie_light_html.js
index 6fe4095..db93dd1 100644
--- a/build/player/lottie_light_html.js
+++ b/build/player/lottie_light_html.js
@@ -1,4 +1,4 @@
-(typeof navigator !== "undefined") && (function (global, factory) {
+(typeof document !== "undefined") && (typeof navigator !== "undefined") && (function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
   typeof define === 'function' && define.amd ? define(factory) :
   (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lottie = factory());
@@ -8,19 +8,15 @@
   var locationHref = '';
   var _useWebWorker = false;
   var initialDefaultFrame = -999999;
-
   var setWebWorker = function setWebWorker(flag) {
     _useWebWorker = !!flag;
   };
-
   var getWebWorker = function getWebWorker() {
     return _useWebWorker;
   };
-
   var setLocationHref = function setLocationHref(value) {
     locationHref = value;
   };
-
   var getLocationHref = function getLocationHref() {
     return locationHref;
   };
@@ -34,28 +30,24 @@
     var i;
     var len = sources.length;
     var sourcePrototype;
-
     for (i = 0; i < len; i += 1) {
       sourcePrototype = sources[i].prototype;
-
       for (var attr in sourcePrototype) {
         if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
       }
     }
   }
-
   function getDescriptor(object, prop) {
     return Object.getOwnPropertyDescriptor(object, prop);
   }
-
   function createProxyFunction(prototype) {
     function ProxyFunction() {}
-
     ProxyFunction.prototype = prototype;
     return ProxyFunction;
   }
 
   // import Howl from '../../3rd_party/howler';
+
   var audioControllerFactory = function () {
     function AudioController(audioFactory) {
       this.audios = [];
@@ -63,7 +55,6 @@
       this._volume = 1;
       this._isMuted = false;
     }
-
     AudioController.prototype = {
       addAudio: function addAudio(audio) {
         this.audios.push(audio);
@@ -71,7 +62,6 @@
       pause: function pause() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].pause();
         }
@@ -79,7 +69,6 @@
       resume: function resume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].resume();
         }
@@ -87,7 +76,6 @@
       setRate: function setRate(rateValue) {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].setRate(rateValue);
         }
@@ -96,13 +84,11 @@
         if (this.audioFactory) {
           return this.audioFactory(assetPath);
         }
-
         if (window.Howl) {
           return new window.Howl({
             src: [assetPath]
           });
         }
-
         return {
           isPlaying: false,
           play: function play() {
@@ -121,17 +107,14 @@
       },
       setVolume: function setVolume(value) {
         this._volume = value;
-
         this._updateVolume();
       },
       mute: function mute() {
         this._isMuted = true;
-
         this._updateVolume();
       },
       unmute: function unmute() {
         this._isMuted = false;
-
         this._updateVolume();
       },
       getVolume: function getVolume() {
@@ -140,7 +123,6 @@
       _updateVolume: function _updateVolume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
         }
@@ -156,55 +138,44 @@
       var i = 0;
       var arr = [];
       var value;
-
       switch (type) {
         case 'int16':
         case 'uint8c':
           value = 1;
           break;
-
         default:
           value = 1.1;
           break;
       }
-
       for (i = 0; i < len; i += 1) {
         arr.push(value);
       }
-
       return arr;
     }
-
     function createTypedArrayFactory(type, len) {
       if (type === 'float32') {
         return new Float32Array(len);
       }
-
       if (type === 'int16') {
         return new Int16Array(len);
       }
-
       if (type === 'uint8c') {
         return new Uint8ClampedArray(len);
       }
-
       return createRegularArray(type, len);
     }
-
     if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
       return createTypedArrayFactory;
     }
-
     return createRegularArray;
   }();
-
   function createSizedArray(len) {
     return Array.apply(null, {
       length: len
     });
   }
 
-  function _typeof$3(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$3 = function _typeof(obj) { return typeof obj; }; } else { _typeof$3 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$3(obj); }
+  function _typeof$3(o) { "@babel/helpers - typeof"; return _typeof$3 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$3(o); }
   var subframeEnabled = true;
   var expressionsPlugin = null;
   var expressionsInterfaces = null;
@@ -217,57 +188,43 @@
   var bmMax = Math.max;
   var bmMin = Math.min;
   var BMMath = {};
-
   (function () {
     var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
     var i;
     var len = propertyNames.length;
-
     for (i = 0; i < len; i += 1) {
       BMMath[propertyNames[i]] = Math[propertyNames[i]];
     }
   })();
-
   function ProjectInterface$1() {
     return {};
   }
-
   BMMath.random = Math.random;
-
   BMMath.abs = function (val) {
     var tOfVal = _typeof$3(val);
-
     if (tOfVal === 'object' && val.length) {
       var absArr = createSizedArray(val.length);
       var i;
       var len = val.length;
-
       for (i = 0; i < len; i += 1) {
         absArr[i] = Math.abs(val[i]);
       }
-
       return absArr;
     }
-
     return Math.abs(val);
   };
-
   var defaultCurveSegments = 150;
   var degToRads = Math.PI / 180;
   var roundCorner = 0.5519;
-
   function roundValues(flag) {
     _shouldRoundValues = !!flag;
   }
-
   function bmRnd(value) {
     if (_shouldRoundValues) {
       return Math.round(value);
     }
-
     return value;
   }
-
   function styleDiv(element) {
     element.style.position = 'absolute';
     element.style.top = 0;
@@ -281,53 +238,44 @@
     element.style.webkitTransformStyle = 'preserve-3d';
     element.style.mozTransformStyle = 'preserve-3d';
   }
-
   function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
     this.type = type;
     this.currentTime = currentTime;
     this.totalTime = totalTime;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteEvent(type, frameMultiplier) {
     this.type = type;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
     this.type = type;
     this.currentLoop = currentLoop;
     this.totalLoops = totalLoops;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMSegmentStartEvent(type, firstFrame, totalFrames) {
     this.type = type;
     this.firstFrame = firstFrame;
     this.totalFrames = totalFrames;
   }
-
   function BMDestroyEvent(type, target) {
     this.type = type;
     this.target = target;
   }
-
   function BMRenderFrameErrorEvent(nativeError, currentTime) {
     this.type = 'renderFrameError';
     this.nativeError = nativeError;
     this.currentTime = currentTime;
   }
-
   function BMConfigErrorEvent(nativeError) {
     this.type = 'configError';
     this.nativeError = nativeError;
   }
-
   function BMAnimationConfigErrorEvent(type, nativeError) {
     this.type = type;
     this.nativeError = nativeError;
   }
-
   var createElementID = function () {
     var _count = 0;
     return function createID() {
@@ -335,7 +283,6 @@
       return idPrefix$1 + '__lottie_element_' + _count;
     };
   }();
-
   function HSVtoRGB(h, s, v) {
     var r;
     var g;
@@ -350,51 +297,42 @@
     p = v * (1 - s);
     q = v * (1 - f * s);
     t = v * (1 - (1 - f) * s);
-
     switch (i % 6) {
       case 0:
         r = v;
         g = t;
         b = p;
         break;
-
       case 1:
         r = q;
         g = v;
         b = p;
         break;
-
       case 2:
         r = p;
         g = v;
         b = t;
         break;
-
       case 3:
         r = p;
         g = q;
         b = v;
         break;
-
       case 4:
         r = t;
         g = p;
         b = v;
         break;
-
       case 5:
         r = v;
         g = p;
         b = q;
         break;
-
       default:
         break;
     }
-
     return [r, g, b];
   }
-
   function RGBtoHSV(r, g, b) {
     var max = Math.max(r, g, b);
     var min = Math.min(r, g, b);
@@ -402,136 +340,105 @@
     var h;
     var s = max === 0 ? 0 : d / max;
     var v = max / 255;
-
     switch (max) {
       case min:
         h = 0;
         break;
-
       case r:
         h = g - b + d * (g < b ? 6 : 0);
         h /= 6 * d;
         break;
-
       case g:
         h = b - r + d * 2;
         h /= 6 * d;
         break;
-
       case b:
         h = r - g + d * 4;
         h /= 6 * d;
         break;
-
       default:
         break;
     }
-
     return [h, s, v];
   }
-
   function addSaturationToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[1] += offset;
-
     if (hsv[1] > 1) {
       hsv[1] = 1;
     } else if (hsv[1] <= 0) {
       hsv[1] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addBrightnessToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[2] += offset;
-
     if (hsv[2] > 1) {
       hsv[2] = 1;
     } else if (hsv[2] < 0) {
       hsv[2] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addHueToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[0] += offset / 360;
-
     if (hsv[0] > 1) {
       hsv[0] -= 1;
     } else if (hsv[0] < 0) {
       hsv[0] += 1;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   var rgbToHex = function () {
     var colorMap = [];
     var i;
     var hex;
-
     for (i = 0; i < 256; i += 1) {
       hex = i.toString(16);
       colorMap[i] = hex.length === 1 ? '0' + hex : hex;
     }
-
     return function (r, g, b) {
       if (r < 0) {
         r = 0;
       }
-
       if (g < 0) {
         g = 0;
       }
-
       if (b < 0) {
         b = 0;
       }
-
       return '#' + colorMap[r] + colorMap[g] + colorMap[b];
     };
   }();
-
   var setSubframeEnabled = function setSubframeEnabled(flag) {
     subframeEnabled = !!flag;
   };
-
   var getSubframeEnabled = function getSubframeEnabled() {
     return subframeEnabled;
   };
-
   var setExpressionsPlugin = function setExpressionsPlugin(value) {
     expressionsPlugin = value;
   };
-
   var getExpressionsPlugin = function getExpressionsPlugin() {
     return expressionsPlugin;
   };
-
   var setExpressionInterfaces = function setExpressionInterfaces(value) {
     expressionsInterfaces = value;
   };
-
   var getExpressionInterfaces = function getExpressionInterfaces() {
     return expressionsInterfaces;
   };
-
   var setDefaultCurveSegments = function setDefaultCurveSegments(value) {
     defaultCurveSegments = value;
   };
-
   var getDefaultCurveSegments = function getDefaultCurveSegments() {
     return defaultCurveSegments;
   };
-
   var setIdPrefix = function setIdPrefix(value) {
     idPrefix$1 = value;
   };
-
   var getIdPrefix = function getIdPrefix() {
     return idPrefix$1;
   };
@@ -541,8 +448,7 @@
     return document.createElementNS(svgNS, type);
   }
 
-  function _typeof$2(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$2 = function _typeof(obj) { return typeof obj; }; } else { _typeof$2 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$2(obj); }
-
+  function _typeof$2(o) { "@babel/helpers - typeof"; return _typeof$2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$2(o); }
   var dataManager = function () {
     var _counterId = 1;
     var processes = [];
@@ -563,21 +469,18 @@
         });
       }
     };
-
     function createWorker(fn) {
       if (window.Worker && window.Blob && getWebWorker()) {
         var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], {
           type: 'text/javascript'
-        }); // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
-
+        });
+        // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
         var url = URL.createObjectURL(blob);
         return new Worker(url);
       }
-
       workerFn = fn;
       return workerProxy;
     }
-
     function setupWorker() {
       if (!workerInstance) {
         workerInstance = createWorker(function workerStart(e) {
@@ -590,28 +493,22 @@
               var jLen;
               var k;
               var kLen;
-
               for (i = 0; i < len; i += 1) {
                 layerData = layers[i];
-
                 if ('ks' in layerData && !layerData.completed) {
                   layerData.completed = true;
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         convertPathsToAbsoluteValues(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) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
                           }
@@ -619,7 +516,6 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 0) {
                     layerData.layers = findCompLayers(layerData.refId, comps);
                     completeLayers(layerData.layers, comps);
@@ -631,16 +527,15 @@
                 }
               }
             }
-
             function completeChars(chars, assets) {
               if (chars) {
                 var i = 0;
                 var len = chars.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (chars[i].t === 1) {
                     // var compData = findComp(chars[i].data.refId, assets);
-                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets); // chars[i].data.ip = 0;
+                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                    // chars[i].data.ip = 0;
                     // chars[i].data.op = 99999;
                     // chars[i].data.st = 0;
                     // chars[i].data.sr = 1;
@@ -652,61 +547,48 @@
                     //   s: { k: [100, 100], a: 0 },
                     //   o: { k: 100, a: 0 },
                     // };
-
                     completeLayers(chars[i].data.layers, assets);
                   }
                 }
               }
             }
-
             function findComp(id, comps) {
               var i = 0;
               var len = comps.length;
-
               while (i < len) {
                 if (comps[i].id === id) {
                   return comps[i];
                 }
-
                 i += 1;
               }
-
               return null;
             }
-
             function findCompLayers(id, comps) {
               var comp = findComp(id, comps);
-
               if (comp) {
                 if (!comp.layers.__used) {
                   comp.layers.__used = true;
                   return comp.layers;
                 }
-
                 return JSON.parse(JSON.stringify(comp.layers));
               }
-
               return null;
             }
-
             function completeShapes(arr) {
               var i;
               var len = arr.length;
               var j;
               var jLen;
-
               for (i = len - 1; i >= 0; i -= 1) {
                 if (arr[i].ty === 'sh') {
                   if (arr[i].ks.k.i) {
                     convertPathsToAbsoluteValues(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) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
                       }
-
                       if (arr[i].ks.k[j].e) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
                       }
@@ -717,11 +599,9 @@
                 }
               }
             }
-
             function convertPathsToAbsoluteValues(path) {
               var i;
               var len = path.i.length;
-
               for (i = 0; i < len; i += 1) {
                 path.i[i][0] += path.v[i][0];
                 path.i[i][1] += path.v[i][1];
@@ -729,40 +609,30 @@
                 path.o[i][1] += path.v[i][1];
               }
             }
-
             function checkVersion(minimum, animVersionString) {
               var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
-
               if (minimum[0] > animVersion[0]) {
                 return true;
               }
-
               if (animVersion[0] > minimum[0]) {
                 return false;
               }
-
               if (minimum[1] > animVersion[1]) {
                 return true;
               }
-
               if (animVersion[1] > minimum[1]) {
                 return false;
               }
-
               if (minimum[2] > animVersion[2]) {
                 return true;
               }
-
               if (animVersion[2] > minimum[2]) {
                 return false;
               }
-
               return null;
             }
-
             var checkText = function () {
               var minimumVersion = [4, 4, 14];
-
               function updateTextLayer(textLayer) {
                 var documentData = textLayer.t.d;
                 textLayer.t.d = {
@@ -772,26 +642,21 @@
                   }]
                 };
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -801,17 +666,14 @@
                 }
               };
             }();
-
             var checkChars = function () {
               var minimumVersion = [4, 7, 99];
               return function (animationData) {
                 if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
                   var i;
                   var len = animationData.chars.length;
-
                   for (i = 0; i < len; i += 1) {
                     var charData = animationData.chars[i];
-
                     if (charData.data && charData.data.shapes) {
                       completeShapes(charData.data.shapes);
                       charData.data.ip = 0;
@@ -840,7 +702,6 @@
                           a: 0
                         }
                       };
-
                       if (!animationData.chars[i].t) {
                         charData.data.shapes.push({
                           ty: 'no'
@@ -882,27 +743,22 @@
                 }
               };
             }();
-
             var checkPathProperties = function () {
               var minimumVersion = [5, 7, 15];
-
               function updateTextLayer(textLayer) {
                 var pathData = textLayer.t.p;
-
                 if (typeof pathData.a === 'number') {
                   pathData.a = {
                     a: 0,
                     k: pathData.a
                   };
                 }
-
                 if (typeof pathData.p === 'number') {
                   pathData.p = {
                     a: 0,
                     k: pathData.p
                   };
                 }
-
                 if (typeof pathData.r === 'number') {
                   pathData.r = {
                     a: 0,
@@ -910,26 +766,21 @@
                   };
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -939,23 +790,19 @@
                 }
               };
             }();
-
             var checkColors = function () {
               var minimumVersion = [4, 1, 9];
-
               function iterateShapes(shapes) {
                 var i;
                 var len = shapes.length;
                 var j;
                 var jLen;
-
                 for (i = 0; i < len; i += 1) {
                   if (shapes[i].ty === 'gr') {
                     iterateShapes(shapes[i].it);
                   } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
                     if (shapes[i].c.k && shapes[i].c.k[0].i) {
                       jLen = shapes[i].c.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (shapes[i].c.k[j].s) {
                           shapes[i].c.k[j].s[0] /= 255;
@@ -963,7 +810,6 @@
                           shapes[i].c.k[j].s[2] /= 255;
                           shapes[i].c.k[j].s[3] /= 255;
                         }
-
                         if (shapes[i].c.k[j].e) {
                           shapes[i].c.k[j].e[0] /= 255;
                           shapes[i].c.k[j].e[1] /= 255;
@@ -980,26 +826,21 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 4) {
                     iterateShapes(layers[i].shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1009,28 +850,23 @@
                 }
               };
             }();
-
             var checkShapes = function () {
               var minimumVersion = [4, 4, 18];
-
               function completeClosingShapes(arr) {
                 var i;
                 var len = arr.length;
                 var j;
                 var jLen;
-
                 for (i = len - 1; i >= 0; i -= 1) {
                   if (arr[i].ty === 'sh') {
                     if (arr[i].ks.k.i) {
                       arr[i].ks.k.c = arr[i].closed;
                     } else {
                       jLen = arr[i].ks.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (arr[i].ks.k[j].s) {
                           arr[i].ks.k[j].s[0].c = arr[i].closed;
                         }
-
                         if (arr[i].ks.k[j].e) {
                           arr[i].ks.k[j].e[0].c = arr[i].closed;
                         }
@@ -1041,7 +877,6 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var layerData;
                 var i;
@@ -1050,25 +885,20 @@
                 var jLen;
                 var k;
                 var kLen;
-
                 for (i = 0; i < len; i += 1) {
                   layerData = layers[i];
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         maskProps[j].pt.k.c = maskProps[j].cl;
                       } else {
                         kLen = maskProps[j].pt.k.length;
-
                         for (k = 0; k < kLen; k += 1) {
                           if (maskProps[j].pt.k[k].s) {
                             maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
                           }
@@ -1076,21 +906,17 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 4) {
                     completeClosingShapes(layerData.shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1100,12 +926,10 @@
                 }
               };
             }();
-
             function completeData(animationData) {
               if (animationData.__complete) {
                 return;
               }
-
               checkColors(animationData);
               checkText(animationData);
               checkChars(animationData);
@@ -1115,12 +939,11 @@
               completeChars(animationData.chars, animationData.assets);
               animationData.__complete = true;
             }
-
             function completeText(data) {
-              if (data.t.a.length === 0 && !('m' in data.t.p)) {// data.singleShape = true;
+              if (data.t.a.length === 0 && !('m' in data.t.p)) {
+                // data.singleShape = true;
               }
             }
-
             var moduleOb = {};
             moduleOb.completeData = completeData;
             moduleOb.checkColors = checkColors;
@@ -1130,47 +953,37 @@
             moduleOb.completeLayers = completeLayers;
             return moduleOb;
           }
-
           if (!_workerSelf.dataManager) {
             _workerSelf.dataManager = dataFunctionManager();
           }
-
           if (!_workerSelf.assetLoader) {
             _workerSelf.assetLoader = function () {
               function formatResponse(xhr) {
                 // using typeof doubles the time of execution of this method,
                 // so if available, it's better to use the header to validate the type
                 var contentTypeHeader = xhr.getResponseHeader('content-type');
-
                 if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
                   return xhr.response;
                 }
-
                 if (xhr.response && _typeof$2(xhr.response) === 'object') {
                   return xhr.response;
                 }
-
                 if (xhr.response && typeof xhr.response === 'string') {
                   return JSON.parse(xhr.response);
                 }
-
                 if (xhr.responseText) {
                   return JSON.parse(xhr.responseText);
                 }
-
                 return null;
               }
-
               function loadAsset(path, fullPath, callback, errorCallback) {
                 var response;
-                var xhr = new XMLHttpRequest(); // set responseType after calling open or IE will break.
-
+                var xhr = new XMLHttpRequest();
+                // set responseType after calling open or IE will break.
                 try {
                   // This crashes on Android WebView prior to KitKat
                   xhr.responseType = 'json';
                 } catch (err) {} // eslint-disable-line no-empty
-
-
                 xhr.onreadystatechange = function () {
                   if (xhr.readyState === 4) {
                     if (xhr.status === 200) {
@@ -1188,7 +1001,6 @@
                     }
                   }
                 };
-
                 try {
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), path, true);
@@ -1196,20 +1008,16 @@
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
                 }
-
                 xhr.send();
               }
-
               return {
                 load: loadAsset
               };
             }();
           }
-
           if (e.data.type === 'loadAnimation') {
             _workerSelf.assetLoader.load(e.data.path, e.data.fullPath, function (data) {
               _workerSelf.dataManager.completeData(data);
-
               _workerSelf.postMessage({
                 id: e.data.id,
                 payload: data,
@@ -1223,9 +1031,7 @@
             });
           } else if (e.data.type === 'complete') {
             var animation = e.data.animation;
-
             _workerSelf.dataManager.completeData(animation);
-
             _workerSelf.postMessage({
               id: e.data.id,
               payload: animation,
@@ -1246,13 +1052,11 @@
             });
           }
         });
-
         workerInstance.onmessage = function (event) {
           var data = event.data;
           var id = data.id;
           var process = processes[id];
           processes[id] = null;
-
           if (data.status === 'success') {
             process.onComplete(data.payload);
           } else if (process.onError) {
@@ -1261,7 +1065,6 @@
         };
       }
     }
-
     function createProcess(onComplete, onError) {
       _counterId += 1;
       var id = 'processId_' + _counterId;
@@ -1271,7 +1074,6 @@
       };
       return id;
     }
-
     function loadAnimation(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1282,7 +1084,6 @@
         id: processId
       });
     }
-
     function loadData(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1293,7 +1094,6 @@
         id: processId
       });
     }
-
     function completeAnimation(anim, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1303,7 +1103,6 @@
         id: processId
       });
     }
-
     return {
       loadAnimation: loadAnimation,
       loadData: loadData,
@@ -1321,94 +1120,74 @@
       ctx.fillRect(0, 0, 1, 1);
       return canvas;
     }();
-
     function imageLoaded() {
       this.loadedAssets += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function footageLoaded() {
       this.loadedFootagesCount += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function getAssetsPath(assetData, assetsPath, originalPath) {
       var path = '';
-
       if (assetData.e) {
         path = assetData.p;
       } else if (assetsPath) {
         var imagePath = assetData.p;
-
         if (imagePath.indexOf('images/') !== -1) {
           imagePath = imagePath.split('/')[1];
         }
-
         path = assetsPath + imagePath;
       } else {
         path = originalPath;
         path += assetData.u ? assetData.u : '';
         path += assetData.p;
       }
-
       return path;
     }
-
     function testImageLoaded(img) {
       var _count = 0;
       var intervalId = setInterval(function () {
         var box = img.getBBox();
-
         if (box.width || _count > 500) {
           this._imageLoaded();
-
           clearInterval(intervalId);
         }
-
         _count += 1;
       }.bind(this), 50);
     }
-
     function createImageData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createNS('image');
-
       if (isSafari) {
         this.testImageLoaded(img);
       } else {
         img.addEventListener('load', this._imageLoaded, false);
       }
-
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
-
       if (this._elementHelper.append) {
         this._elementHelper.append(img);
       } else {
         this._elementHelper.appendChild(img);
       }
-
       var ob = {
         img: img,
         assetData: assetData
       };
       return ob;
     }
-
     function createImgData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createTag('img');
@@ -1416,7 +1195,6 @@
       img.addEventListener('load', this._imageLoaded, false);
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.src = path;
@@ -1426,7 +1204,6 @@
       };
       return ob;
     }
-
     function createFootageData(data) {
       var ob = {
         assetData: data
@@ -1434,21 +1211,17 @@
       var path = getAssetsPath(data, this.assetsPath, this.path);
       dataManager.loadData(path, function (footageData) {
         ob.img = footageData;
-
         this._footageLoaded();
       }.bind(this), function () {
         ob.img = {};
-
         this._footageLoaded();
       }.bind(this));
       return ob;
     }
-
     function loadAssets(assets, cb) {
       this.imagesLoadedCb = cb;
       var i;
       var len = assets.length;
-
       for (i = 0; i < len; i += 1) {
         if (!assets[i].layers) {
           if (!assets[i].t || assets[i].t === 'seq') {
@@ -1461,43 +1234,33 @@
         }
       }
     }
-
     function setPath(path) {
       this.path = path || '';
     }
-
     function setAssetsPath(path) {
       this.assetsPath = path || '';
     }
-
     function getAsset(assetData) {
       var i = 0;
       var len = this.images.length;
-
       while (i < len) {
         if (this.images[i].assetData === assetData) {
           return this.images[i].img;
         }
-
         i += 1;
       }
-
       return null;
     }
-
     function destroy() {
       this.imagesLoadedCb = null;
       this.images.length = 0;
     }
-
     function loadedImages() {
       return this.totalImages === this.loadedAssets;
     }
-
     function loadedFootages() {
       return this.totalFootages === this.loadedFootagesCount;
     }
-
     function setCacheType(type, elementHelper) {
       if (type === 'svg') {
         this._elementHelper = elementHelper;
@@ -1506,7 +1269,6 @@
         this._createImageData = this.createImgData.bind(this);
       }
     }
-
     function ImagePreloaderFactory() {
       this._imageLoaded = imageLoaded.bind(this);
       this._footageLoaded = footageLoaded.bind(this);
@@ -1521,7 +1283,6 @@
       this.imagesLoadedCb = null;
       this.images = [];
     }
-
     ImagePreloaderFactory.prototype = {
       loadAssets: loadAssets,
       setAssetsPath: setAssetsPath,
@@ -1540,12 +1301,10 @@
   }();
 
   function BaseEvent() {}
-
   BaseEvent.prototype = {
     triggerEvent: function triggerEvent(eventName, args) {
       if (this._cbs[eventName]) {
         var callbacks = this._cbs[eventName];
-
         for (var i = 0; i < callbacks.length; i += 1) {
           callbacks[i](args);
         }
@@ -1555,9 +1314,7 @@
       if (!this._cbs[eventName]) {
         this._cbs[eventName] = [];
       }
-
       this._cbs[eventName].push(callback);
-
       return function () {
         this.removeEventListener(eventName, callback);
       }.bind(this);
@@ -1568,18 +1325,14 @@
       } else if (this._cbs[eventName]) {
         var i = 0;
         var len = this._cbs[eventName].length;
-
         while (i < len) {
           if (this._cbs[eventName][i] === callback) {
             this._cbs[eventName].splice(i, 1);
-
             i -= 1;
             len -= 1;
           }
-
           i += 1;
         }
-
         if (!this._cbs[eventName].length) {
           this._cbs[eventName] = null;
         }
@@ -1593,33 +1346,26 @@
       var keys = {};
       var line;
       var keysCount = 0;
-
       for (var i = 0; i < lines.length; i += 1) {
         line = lines[i].split(':');
-
         if (line.length === 2) {
           keys[line[0]] = line[1].trim();
           keysCount += 1;
         }
       }
-
       if (keysCount === 0) {
         throw new Error();
       }
-
       return keys;
     }
-
     return function (_markers) {
       var markers = [];
-
       for (var i = 0; i < _markers.length; i += 1) {
         var _marker = _markers[i];
         var markerData = {
           time: _marker.tm,
           duration: _marker.dr
         };
-
         try {
           markerData.payload = JSON.parse(_markers[i].cm);
         } catch (_) {
@@ -1631,10 +1377,8 @@
             };
           }
         }
-
         markers.push(markerData);
       }
-
       return markers;
     };
   }();
@@ -1643,27 +1387,21 @@
     function registerComposition(comp) {
       this.compositions.push(comp);
     }
-
     return function () {
       function _thisProjectFunction(name) {
         var i = 0;
         var len = this.compositions.length;
-
         while (i < len) {
           if (this.compositions[i].data && this.compositions[i].data.nm === name) {
             if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
               this.compositions[i].prepareFrame(this.currentFrame);
             }
-
             return this.compositions[i].compInterface;
           }
-
           i += 1;
         }
-
         return null;
       }
-
       _thisProjectFunction.compositions = [];
       _thisProjectFunction.currentFrame = 0;
       _thisProjectFunction.registerComposition = registerComposition;
@@ -1672,33 +1410,27 @@
   }();
 
   var renderers = {};
-
   var registerRenderer = function registerRenderer(key, value) {
     renderers[key] = value;
   };
-
   function getRenderer(key) {
     return renderers[key];
   }
-
   function getRegisteredRenderer() {
     // Returns canvas by default for compatibility
     if (renderers.canvas) {
       return 'canvas';
-    } // Returns any renderer that is registered
-
-
+    }
+    // Returns any renderer that is registered
     for (var key in renderers) {
       if (renderers[key]) {
         return key;
       }
     }
-
     return '';
   }
 
-  function _typeof$1(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$1 = function _typeof(obj) { return typeof obj; }; } else { _typeof$1 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$1(obj); }
-
+  function _typeof$1(o) { "@babel/helpers - typeof"; return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$1(o); }
   var AnimationItem = function AnimationItem() {
     this._cbs = [];
     this.name = '';
@@ -1737,28 +1469,22 @@
     this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
     this.expressionsPlugin = getExpressionsPlugin();
   };
-
   extendPrototype([BaseEvent], AnimationItem);
-
   AnimationItem.prototype.setParams = function (params) {
     if (params.wrapper || params.container) {
       this.wrapper = params.wrapper || params.container;
     }
-
     var animType = 'svg';
-
     if (params.animType) {
       animType = params.animType;
     } else if (params.renderer) {
       animType = params.renderer;
     }
-
     var RendererClass = getRenderer(animType);
     this.renderer = new RendererClass(this, params.rendererSettings);
     this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
     this.renderer.setProjectInterface(this.projectInterface);
     this.animType = animType;
-
     if (params.loop === '' || params.loop === null || params.loop === undefined || params.loop === true) {
       this.loop = true;
     } else if (params.loop === false) {
@@ -1766,17 +1492,14 @@
     } else {
       this.loop = parseInt(params.loop, 10);
     }
-
     this.autoplay = 'autoplay' in params ? params.autoplay : true;
     this.name = params.name ? params.name : '';
     this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
     this.assetsPath = params.assetsPath;
     this.initialSegment = params.initialSegment;
-
     if (params.audioFactory) {
       this.audioController.setAudioFactory(params.audioFactory);
     }
-
     if (params.animationData) {
       this.setupAnimation(params.animationData);
     } else if (params.path) {
@@ -1785,28 +1508,23 @@
       } else {
         this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
       }
-
       this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
       this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
       dataManager.loadAnimation(params.path, this.configAnimation, this.onSetupError);
     }
   };
-
   AnimationItem.prototype.onSetupError = function () {
     this.trigger('data_failed');
   };
-
   AnimationItem.prototype.setupAnimation = function (data) {
     dataManager.completeAnimation(data, this.configAnimation);
   };
-
   AnimationItem.prototype.setData = function (wrapper, animationData) {
     if (animationData) {
       if (_typeof$1(animationData) !== 'object') {
         animationData = JSON.parse(animationData);
       }
     }
-
     var params = {
       wrapper: wrapper,
       animationData: animationData
@@ -1823,7 +1541,6 @@
     var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-loop').value : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-loop').value : wrapperAttributes.getNamedItem('bm-loop') ? wrapperAttributes.getNamedItem('bm-loop').value : '';
-
     if (loop === 'false') {
       params.loop = false;
     } else if (loop === 'true') {
@@ -1831,7 +1548,6 @@
     } else if (loop !== '') {
       params.loop = parseInt(loop, 10);
     }
-
     var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-autoplay').value : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-autoplay').value : wrapperAttributes.getNamedItem('bm-autoplay') ? wrapperAttributes.getNamedItem('bm-autoplay').value : true;
@@ -1842,81 +1558,64 @@
     var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-prerender').value : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-prerender').value : wrapperAttributes.getNamedItem('bm-prerender') ? wrapperAttributes.getNamedItem('bm-prerender').value : '';
-
     if (prerender === 'false') {
       params.prerender = false;
     }
-
     if (!params.path) {
       this.trigger('destroy');
     } else {
       this.setParams(params);
     }
   };
-
   AnimationItem.prototype.includeLayers = function (data) {
     if (data.op > this.animationData.op) {
       this.animationData.op = data.op;
       this.totalFrames = Math.floor(data.op - this.animationData.ip);
     }
-
     var layers = this.animationData.layers;
     var i;
     var len = layers.length;
     var newLayers = data.layers;
     var j;
     var jLen = newLayers.length;
-
     for (j = 0; j < jLen; j += 1) {
       i = 0;
-
       while (i < len) {
         if (layers[i].id === newLayers[j].id) {
           layers[i] = newLayers[j];
           break;
         }
-
         i += 1;
       }
     }
-
     if (data.chars || data.fonts) {
       this.renderer.globalData.fontManager.addChars(data.chars);
       this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
     }
-
     if (data.assets) {
       len = data.assets.length;
-
       for (i = 0; i < len; i += 1) {
         this.animationData.assets.push(data.assets[i]);
       }
     }
-
     this.animationData.__complete = false;
     dataManager.completeAnimation(this.animationData, this.onSegmentComplete);
   };
-
   AnimationItem.prototype.onSegmentComplete = function (data) {
     this.animationData = data;
     var expressionsPlugin = getExpressionsPlugin();
-
     if (expressionsPlugin) {
       expressionsPlugin.initExpressions(this);
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.loadNextSegment = function () {
     var segments = this.animationData.segments;
-
     if (!segments || segments.length === 0 || !this.autoloadSegments) {
       this.trigger('data_ready');
       this.timeCompleted = this.totalFrames;
       return;
     }
-
     var segment = segments.shift();
     this.timeCompleted = segment.time * this.frameRate;
     var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
@@ -1925,36 +1624,28 @@
       this.trigger('data_failed');
     }.bind(this));
   };
-
   AnimationItem.prototype.loadSegments = function () {
     var segments = this.animationData.segments;
-
     if (!segments) {
       this.timeCompleted = this.totalFrames;
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.imagesLoaded = function () {
     this.trigger('loaded_images');
     this.checkLoaded();
   };
-
   AnimationItem.prototype.preloadImages = function () {
     this.imagePreloader.setAssetsPath(this.assetsPath);
     this.imagePreloader.setPath(this.path);
     this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
   };
-
   AnimationItem.prototype.configAnimation = function (animData) {
     if (!this.renderer) {
       return;
     }
-
     try {
       this.animationData = animData;
-
       if (this.initialSegment) {
         this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
         this.firstFrame = Math.round(this.initialSegment[0]);
@@ -1962,13 +1653,10 @@
         this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
         this.firstFrame = Math.round(this.animationData.ip);
       }
-
       this.renderer.configAnimation(animData);
-
       if (!animData.assets) {
         animData.assets = [];
       }
-
       this.assets = this.animationData.assets;
       this.frameRate = this.animationData.fr;
       this.frameMult = this.animationData.fr / 1000;
@@ -1979,7 +1667,6 @@
       this.loadSegments();
       this.updaFrameModifier();
       this.waitForFontsLoaded();
-
       if (this.isPaused) {
         this.audioController.pause();
       }
@@ -1987,103 +1674,83 @@
       this.triggerConfigError(error);
     }
   };
-
   AnimationItem.prototype.waitForFontsLoaded = function () {
     if (!this.renderer) {
       return;
     }
-
     if (this.renderer.globalData.fontManager.isLoaded) {
       this.checkLoaded();
     } else {
       setTimeout(this.waitForFontsLoaded.bind(this), 20);
     }
   };
-
   AnimationItem.prototype.checkLoaded = function () {
     if (!this.isLoaded && this.renderer.globalData.fontManager.isLoaded && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas') && this.imagePreloader.loadedFootages()) {
       this.isLoaded = true;
       var expressionsPlugin = getExpressionsPlugin();
-
       if (expressionsPlugin) {
         expressionsPlugin.initExpressions(this);
       }
-
       this.renderer.initItems();
       setTimeout(function () {
         this.trigger('DOMLoaded');
       }.bind(this), 0);
       this.gotoFrame();
-
       if (this.autoplay) {
         this.play();
       }
     }
   };
-
   AnimationItem.prototype.resize = function (width, height) {
     // Adding this validation for backwards compatibility in case an event object was being passed down
     var _width = typeof width === 'number' ? width : undefined;
-
     var _height = typeof height === 'number' ? height : undefined;
-
     this.renderer.updateContainerSize(_width, _height);
   };
-
   AnimationItem.prototype.setSubframe = function (flag) {
     this.isSubframeEnabled = !!flag;
   };
-
   AnimationItem.prototype.gotoFrame = function () {
     this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
 
     if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
       this.currentFrame = this.timeCompleted;
     }
-
     this.trigger('enterFrame');
     this.renderFrame();
     this.trigger('drawnFrame');
   };
-
   AnimationItem.prototype.renderFrame = function () {
     if (this.isLoaded === false || !this.renderer) {
       return;
     }
-
     try {
       if (this.expressionsPlugin) {
         this.expressionsPlugin.resetFrame();
       }
-
       this.renderer.renderFrame(this.currentFrame + this.firstFrame);
     } catch (error) {
       this.triggerRenderFrameError(error);
     }
   };
-
   AnimationItem.prototype.play = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.isPaused = false;
       this.trigger('_play');
       this.audioController.resume();
-
       if (this._idle) {
         this._idle = false;
         this.trigger('_active');
       }
     }
   };
-
   AnimationItem.prototype.pause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === false) {
       this.isPaused = true;
       this.trigger('_pause');
@@ -2092,54 +1759,42 @@
       this.audioController.pause();
     }
   };
-
   AnimationItem.prototype.togglePause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.play();
     } else {
       this.pause();
     }
   };
-
   AnimationItem.prototype.stop = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.pause();
     this.playCount = 0;
     this._completedLoop = false;
     this.setCurrentRawFrameValue(0);
   };
-
   AnimationItem.prototype.getMarkerData = function (markerName) {
     var marker;
-
     for (var i = 0; i < this.markers.length; i += 1) {
       marker = this.markers[i];
-
       if (marker.payload && marker.payload.name === markerName) {
         return marker;
       }
     }
-
     return null;
   };
-
   AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         this.goToAndStop(marker.time, true);
       }
@@ -2148,20 +1803,15 @@
     } else {
       this.setCurrentRawFrameValue(value * this.frameModifier);
     }
-
     this.pause();
   };
-
   AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         if (!marker.duration) {
           this.goToAndStop(marker.time, true);
@@ -2172,19 +1822,16 @@
     } else {
       this.goToAndStop(numValue, isFrame, name);
     }
-
     this.play();
   };
-
   AnimationItem.prototype.advanceTime = function (value) {
     if (this.isPaused === true || this.isLoaded === false) {
       return;
     }
-
     var nextValue = this.currentRawFrame + value * this.frameModifier;
-    var _isComplete = false; // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+    var _isComplete = false;
+    // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
     // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
-
     if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
       if (!this.loop || this.playCount === this.loop) {
         if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
@@ -2193,7 +1840,6 @@
         }
       } else if (nextValue >= this.totalFrames) {
         this.playCount += 1;
-
         if (!this.checkSegments(nextValue % this.totalFrames)) {
           this.setCurrentRawFrameValue(nextValue % this.totalFrames);
           this._completedLoop = true;
@@ -2207,7 +1853,6 @@
         if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) {
           // eslint-disable-line no-plusplus
           this.setCurrentRawFrameValue(this.totalFrames + nextValue % this.totalFrames);
-
           if (!this._completedLoop) {
             this._completedLoop = true;
           } else {
@@ -2221,17 +1866,14 @@
     } else {
       this.setCurrentRawFrameValue(nextValue);
     }
-
     if (_isComplete) {
       this.setCurrentRawFrameValue(nextValue);
       this.pause();
       this.trigger('complete');
     }
   };
-
   AnimationItem.prototype.adjustSegment = function (arr, offset) {
     this.playCount = 0;
-
     if (arr[1] < arr[0]) {
       if (this.frameModifier > 0) {
         if (this.playSpeed < 0) {
@@ -2240,7 +1882,6 @@
           this.setDirection(-1);
         }
       }
-
       this.totalFrames = arr[0] - arr[1];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[1];
@@ -2253,19 +1894,15 @@
           this.setDirection(1);
         }
       }
-
       this.totalFrames = arr[1] - arr[0];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[0];
       this.setCurrentRawFrameValue(0.001 + offset);
     }
-
     this.trigger('segmentStart');
   };
-
   AnimationItem.prototype.setSegment = function (init, end) {
     var pendingFrame = -1;
-
     if (this.isPaused) {
       if (this.currentRawFrame + this.firstFrame < init) {
         pendingFrame = init;
@@ -2273,64 +1910,51 @@
         pendingFrame = end - init;
       }
     }
-
     this.firstFrame = init;
     this.totalFrames = end - init;
     this.timeCompleted = this.totalFrames;
-
     if (pendingFrame !== -1) {
       this.goToAndStop(pendingFrame, true);
     }
   };
-
   AnimationItem.prototype.playSegments = function (arr, forceFlag) {
     if (forceFlag) {
       this.segments.length = 0;
     }
-
     if (_typeof$1(arr[0]) === 'object') {
       var i;
       var len = arr.length;
-
       for (i = 0; i < len; i += 1) {
         this.segments.push(arr[i]);
       }
     } else {
       this.segments.push(arr);
     }
-
     if (this.segments.length && forceFlag) {
       this.adjustSegment(this.segments.shift(), 0);
     }
-
     if (this.isPaused) {
       this.play();
     }
   };
-
   AnimationItem.prototype.resetSegments = function (forceFlag) {
     this.segments.length = 0;
     this.segments.push([this.animationData.ip, this.animationData.op]);
-
     if (forceFlag) {
       this.checkSegments(0);
     }
   };
-
   AnimationItem.prototype.checkSegments = function (offset) {
     if (this.segments.length) {
       this.adjustSegment(this.segments.shift(), offset);
       return true;
     }
-
     return false;
   };
-
   AnimationItem.prototype.destroy = function (name) {
     if (name && this.name !== name || !this.renderer) {
       return;
     }
-
     this.renderer.destroy();
     this.imagePreloader.destroy();
     this.trigger('destroy');
@@ -2345,189 +1969,148 @@
     this.imagePreloader = null;
     this.projectInterface = null;
   };
-
   AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
     this.currentRawFrame = value;
     this.gotoFrame();
   };
-
   AnimationItem.prototype.setSpeed = function (val) {
     this.playSpeed = val;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setDirection = function (val) {
     this.playDirection = val < 0 ? -1 : 1;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setLoop = function (isLooping) {
     this.loop = isLooping;
   };
-
   AnimationItem.prototype.setVolume = function (val, name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.setVolume(val);
   };
-
   AnimationItem.prototype.getVolume = function () {
     return this.audioController.getVolume();
   };
-
   AnimationItem.prototype.mute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.mute();
   };
-
   AnimationItem.prototype.unmute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.unmute();
   };
-
   AnimationItem.prototype.updaFrameModifier = function () {
     this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
     this.audioController.setRate(this.playSpeed * this.playDirection);
   };
-
   AnimationItem.prototype.getPath = function () {
     return this.path;
   };
-
   AnimationItem.prototype.getAssetsPath = function (assetData) {
     var path = '';
-
     if (assetData.e) {
       path = assetData.p;
     } else if (this.assetsPath) {
       var imagePath = assetData.p;
-
       if (imagePath.indexOf('images/') !== -1) {
         imagePath = imagePath.split('/')[1];
       }
-
       path = this.assetsPath + imagePath;
     } else {
       path = this.path;
       path += assetData.u ? assetData.u : '';
       path += assetData.p;
     }
-
     return path;
   };
-
   AnimationItem.prototype.getAssetData = function (id) {
     var i = 0;
     var len = this.assets.length;
-
     while (i < len) {
       if (id === this.assets[i].id) {
         return this.assets[i];
       }
-
       i += 1;
     }
-
     return null;
   };
-
   AnimationItem.prototype.hide = function () {
     this.renderer.hide();
   };
-
   AnimationItem.prototype.show = function () {
     this.renderer.show();
   };
-
   AnimationItem.prototype.getDuration = function (isFrame) {
     return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
   };
-
   AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
     try {
       var element = this.renderer.getElementByPath(path);
       element.updateDocumentData(documentData, index);
-    } catch (error) {// TODO: decide how to handle catch case
+    } catch (error) {
+      // TODO: decide how to handle catch case
     }
   };
-
   AnimationItem.prototype.trigger = function (name) {
     if (this._cbs && this._cbs[name]) {
       switch (name) {
         case 'enterFrame':
           this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
           break;
-
         case 'drawnFrame':
           this.drawnFrameEvent.currentTime = this.currentFrame;
           this.drawnFrameEvent.totalTime = this.totalFrames;
           this.drawnFrameEvent.direction = this.frameModifier;
           this.triggerEvent(name, this.drawnFrameEvent);
           break;
-
         case 'loopComplete':
           this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
           break;
-
         case 'complete':
           this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
           break;
-
         case 'segmentStart':
           this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
           break;
-
         case 'destroy':
           this.triggerEvent(name, new BMDestroyEvent(name, this));
           break;
-
         default:
           this.triggerEvent(name);
       }
     }
-
     if (name === 'enterFrame' && this.onEnterFrame) {
       this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
     }
-
     if (name === 'loopComplete' && this.onLoopComplete) {
       this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
     }
-
     if (name === 'complete' && this.onComplete) {
       this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
     }
-
     if (name === 'segmentStart' && this.onSegmentStart) {
       this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
     }
-
     if (name === 'destroy' && this.onDestroy) {
       this.onDestroy.call(this, new BMDestroyEvent(name, this));
     }
   };
-
   AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
     var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
   };
-
   AnimationItem.prototype.triggerConfigError = function (nativeError) {
     var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
@@ -2541,68 +2124,53 @@
     var playingAnimationsNum = 0;
     var _stopped = true;
     var _isFrozen = false;
-
     function removeElement(ev) {
       var i = 0;
       var animItem = ev.target;
-
       while (i < len) {
         if (registeredAnimations[i].animation === animItem) {
           registeredAnimations.splice(i, 1);
           i -= 1;
           len -= 1;
-
           if (!animItem.isPaused) {
             subtractPlayingCount();
           }
         }
-
         i += 1;
       }
     }
-
     function registerAnimation(element, animationData) {
       if (!element) {
         return null;
       }
-
       var i = 0;
-
       while (i < len) {
         if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
           return registeredAnimations[i].animation;
         }
-
         i += 1;
       }
-
       var animItem = new AnimationItem();
       setupAnimation(animItem, element);
       animItem.setData(element, animationData);
       return animItem;
     }
-
     function getRegisteredAnimations() {
       var i;
       var lenAnims = registeredAnimations.length;
       var animations = [];
-
       for (i = 0; i < lenAnims; i += 1) {
         animations.push(registeredAnimations[i].animation);
       }
-
       return animations;
     }
-
     function addPlayingCount() {
       playingAnimationsNum += 1;
       activate();
     }
-
     function subtractPlayingCount() {
       playingAnimationsNum -= 1;
     }
-
     function setupAnimation(animItem, element) {
       animItem.addEventListener('destroy', removeElement);
       animItem.addEventListener('_active', addPlayingCount);
@@ -2613,118 +2181,91 @@
       });
       len += 1;
     }
-
     function loadAnimation(params) {
       var animItem = new AnimationItem();
       setupAnimation(animItem, null);
       animItem.setParams(params);
       return animItem;
     }
-
     function setSpeed(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setSpeed(val, animation);
       }
     }
-
     function setDirection(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setDirection(val, animation);
       }
     }
-
     function play(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.play(animation);
       }
     }
-
     function resume(nowTime) {
       var elapsedTime = nowTime - initTime;
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.advanceTime(elapsedTime);
       }
-
       initTime = nowTime;
-
       if (playingAnimationsNum && !_isFrozen) {
         window.requestAnimationFrame(resume);
       } else {
         _stopped = true;
       }
     }
-
     function first(nowTime) {
       initTime = nowTime;
       window.requestAnimationFrame(resume);
     }
-
     function pause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.pause(animation);
       }
     }
-
     function goToAndStop(value, isFrame, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
       }
     }
-
     function stop(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.stop(animation);
       }
     }
-
     function togglePause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.togglePause(animation);
       }
     }
-
     function destroy(animation) {
       var i;
-
       for (i = len - 1; i >= 0; i -= 1) {
         registeredAnimations[i].animation.destroy(animation);
       }
     }
-
     function searchAnimations(animationData, standalone, renderer) {
       var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')), [].slice.call(document.getElementsByClassName('bodymovin')));
       var i;
       var lenAnims = animElements.length;
-
       for (i = 0; i < lenAnims; i += 1) {
         if (renderer) {
           animElements[i].setAttribute('data-bm-type', renderer);
         }
-
         registerAnimation(animElements[i], animationData);
       }
-
       if (standalone && lenAnims === 0) {
         if (!renderer) {
           renderer = 'svg';
         }
-
         var body = document.getElementsByTagName('body')[0];
         body.innerText = '';
         var div = createTag('div');
@@ -2735,15 +2276,12 @@
         registerAnimation(div, animationData);
       }
     }
-
     function resize() {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.resize();
       }
     }
-
     function activate() {
       if (!_isFrozen && playingAnimationsNum) {
         if (_stopped) {
@@ -2752,40 +2290,31 @@
         }
       }
     }
-
     function freeze() {
       _isFrozen = true;
     }
-
     function unfreeze() {
       _isFrozen = false;
       activate();
     }
-
     function setVolume(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setVolume(val, animation);
       }
     }
-
     function mute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.mute(animation);
       }
     }
-
     function unmute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.unmute(animation);
       }
     }
-
     moduleOb.registerAnimation = registerAnimation;
     moduleOb.loadAnimation = loadAnimation;
     moduleOb.setSpeed = setSpeed;
@@ -2795,8 +2324,8 @@
     moduleOb.stop = stop;
     moduleOb.togglePause = togglePause;
     moduleOb.searchAnimations = searchAnimations;
-    moduleOb.resize = resize; // moduleOb.start = start;
-
+    moduleOb.resize = resize;
+    // moduleOb.start = start;
     moduleOb.goToAndStop = goToAndStop;
     moduleOb.destroy = destroy;
     moduleOb.freeze = freeze;
@@ -2820,23 +2349,21 @@
        * spline.get(x) => returns the easing value | x must be in [0, 1] range
        *
        */
+
     var ob = {};
     ob.getBezierEasing = getBezierEasing;
     var beziers = {};
-
     function getBezierEasing(a, b, c, d, nm) {
       var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
-
       if (beziers[str]) {
         return beziers[str];
       }
-
       var bezEasing = new BezierEasing([a, b, c, d]);
       beziers[str] = bezEasing;
       return bezEasing;
-    } // These values are established by empiricism with tests (tradeoff: performance VS precision)
+    }
 
-
+    // These values are established by empiricism with tests (tradeoff: performance VS precision)
     var NEWTON_ITERATIONS = 4;
     var NEWTON_MIN_SLOPE = 0.001;
     var SUBDIVISION_PRECISION = 0.0000001;
@@ -2844,48 +2371,40 @@
     var kSplineTableSize = 11;
     var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
     var float32ArraySupported = typeof Float32Array === 'function';
-
     function A(aA1, aA2) {
       return 1.0 - 3.0 * aA2 + 3.0 * aA1;
     }
-
     function B(aA1, aA2) {
       return 3.0 * aA2 - 6.0 * aA1;
     }
-
     function C(aA1) {
       return 3.0 * aA1;
-    } // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+    }
 
-
+    // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
     function calcBezier(aT, aA1, aA2) {
       return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
-    } // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+    }
 
-
+    // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
     function getSlope(aT, aA1, aA2) {
       return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
     }
-
     function binarySubdivide(aX, aA, aB, mX1, mX2) {
       var currentX,
-          currentT,
-          i = 0;
-
+        currentT,
+        i = 0;
       do {
         currentT = aA + (aB - aA) / 2.0;
         currentX = calcBezier(currentT, mX1, mX2) - aX;
-
         if (currentX > 0.0) {
           aB = currentT;
         } else {
           aA = currentT;
         }
       } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
-
       return currentT;
     }
-
     function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
       for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
         var currentSlope = getSlope(aGuessT, mX1, mX2);
@@ -2893,85 +2412,75 @@
         var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
         aGuessT -= currentX / currentSlope;
       }
-
       return aGuessT;
     }
+
     /**
        * points is an array of [ mX1, mY1, mX2, mY2 ]
        */
-
-
     function BezierEasing(points) {
       this._p = points;
       this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
       this._precomputed = false;
       this.get = this.get.bind(this);
     }
-
     BezierEasing.prototype = {
       get: function get(x) {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         if (!this._precomputed) this._precompute();
         if (mX1 === mY1 && mX2 === mY2) return x; // linear
         // Because JavaScript number are imprecise, we should guarantee the extremes are right.
-
         if (x === 0) return 0;
         if (x === 1) return 1;
         return calcBezier(this._getTForX(x), mY1, mY2);
       },
       // Private part
+
       _precompute: function _precompute() {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         this._precomputed = true;
-
         if (mX1 !== mY1 || mX2 !== mY2) {
           this._calcSampleValues();
         }
       },
       _calcSampleValues: function _calcSampleValues() {
         var mX1 = this._p[0],
-            mX2 = this._p[2];
-
+          mX2 = this._p[2];
         for (var i = 0; i < kSplineTableSize; ++i) {
           this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
         }
       },
-
       /**
            * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
            */
       _getTForX: function _getTForX(aX) {
         var mX1 = this._p[0],
-            mX2 = this._p[2],
-            mSampleValues = this._mSampleValues;
+          mX2 = this._p[2],
+          mSampleValues = this._mSampleValues;
         var intervalStart = 0.0;
         var currentSample = 1;
         var lastSample = kSplineTableSize - 1;
-
         for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
           intervalStart += kSampleStepSize;
         }
+        --currentSample;
 
-        --currentSample; // Interpolate to provide an initial guess for t
-
+        // Interpolate to provide an initial guess for t
         var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
         var guessForT = intervalStart + dist * kSampleStepSize;
         var initialSlope = getSlope(guessForT, mX1, mX2);
-
         if (initialSlope >= NEWTON_MIN_SLOPE) {
           return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
         }
-
         if (initialSlope === 0.0) {
           return guessForT;
         }
-
         return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
       }
     };
@@ -2982,7 +2491,6 @@
     function _double(arr) {
       return arr.concat(createSizedArray(arr.length));
     }
-
     return {
       "double": _double
     };
@@ -2997,34 +2505,27 @@
         newElement: newElement,
         release: release
       };
-
       function newElement() {
         var element;
-
         if (_length) {
           _length -= 1;
           element = pool[_length];
         } else {
           element = _create();
         }
-
         return element;
       }
-
       function release(element) {
         if (_length === _maxLength) {
           pool = pooling["double"](pool);
           _maxLength *= 2;
         }
-
         if (_release) {
           _release(element);
         }
-
         pool[_length] = element;
         _length += 1;
       }
-
       return ob;
     };
   }();
@@ -3037,7 +2538,6 @@
         lengths: createTypedArray('float32', getDefaultCurveSegments())
       };
     }
-
     return poolFactory(8, create);
   }();
 
@@ -3048,39 +2548,31 @@
         totalLength: 0
       };
     }
-
     function release(element) {
       var i;
       var len = element.lengths.length;
-
       for (i = 0; i < len; i += 1) {
         bezierLengthPool.release(element.lengths[i]);
       }
-
       element.lengths.length = 0;
     }
-
     return poolFactory(8, create, release);
   }();
 
   function bezFunction() {
     var math = Math;
-
     function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
       var det1 = x1 * y2 + y1 * x3 + x2 * y3 - x3 * y2 - y3 * x1 - x2 * y1;
       return det1 > -0.001 && det1 < 0.001;
     }
-
     function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
       if (z1 === 0 && z2 === 0 && z3 === 0) {
         return pointOnLine2D(x1, y1, x2, y2, x3, y3);
       }
-
       var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
       var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
       var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
       var diffDist;
-
       if (dist1 > dist2) {
         if (dist1 > dist3) {
           diffDist = dist1 - dist2 - dist3;
@@ -3092,10 +2584,8 @@
       } else {
         diffDist = dist2 - dist1 - dist3;
       }
-
       return diffDist > -0.0001 && diffDist < 0.0001;
     }
-
     var getBezierLength = function () {
       return function (pt1, pt2, pt3, pt4) {
         var curveSegments = getDefaultCurveSegments();
@@ -3110,36 +2600,28 @@
         var lastPoint = [];
         var lengthData = bezierLengthPool.newElement();
         len = pt3.length;
-
         for (k = 0; k < curveSegments; k += 1) {
           perc = k / (curveSegments - 1);
           ptDistance = 0;
-
           for (i = 0; i < len; i += 1) {
             ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
             point[i] = ptCoord;
-
             if (lastPoint[i] !== null) {
               ptDistance += bmPow(point[i] - lastPoint[i], 2);
             }
-
             lastPoint[i] = point[i];
           }
-
           if (ptDistance) {
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
           }
-
           lengthData.percents[k] = perc;
           lengthData.lengths[k] = addedLength;
         }
-
         lengthData.addedLength = addedLength;
         return lengthData;
       };
     }();
-
     function getSegmentsLength(shapeData) {
       var segmentsLength = segmentsLengthPool.newElement();
       var closed = shapeData.c;
@@ -3150,36 +2632,29 @@
       var len = shapeData._length;
       var lengths = segmentsLength.lengths;
       var totalLength = 0;
-
       for (i = 0; i < len - 1; i += 1) {
         lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
         totalLength += lengths[i].addedLength;
       }
-
       if (closed && len) {
         lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
         totalLength += lengths[i].addedLength;
       }
-
       segmentsLength.totalLength = totalLength;
       return segmentsLength;
     }
-
     function BezierData(length) {
       this.segmentLength = 0;
       this.points = new Array(length);
     }
-
     function PointData(partial, point) {
       this.partialLength = partial;
       this.point = point;
     }
-
     var buildBezierData = function () {
       var storedData = {};
       return function (pt1, pt2, pt3, pt4) {
         var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
-
         if (!storedData[bezierName]) {
           var curveSegments = getDefaultCurveSegments();
           var k;
@@ -3191,42 +2666,33 @@
           var ptDistance;
           var point;
           var lastPoint = null;
-
           if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
             curveSegments = 2;
           }
-
           var bezierData = new BezierData(curveSegments);
           len = pt3.length;
-
           for (k = 0; k < curveSegments; k += 1) {
             point = createSizedArray(len);
             perc = k / (curveSegments - 1);
             ptDistance = 0;
-
             for (i = 0; i < len; i += 1) {
               ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
               point[i] = ptCoord;
-
               if (lastPoint !== null) {
                 ptDistance += bmPow(point[i] - lastPoint[i], 2);
               }
             }
-
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
             bezierData.points[k] = new PointData(ptDistance, point);
             lastPoint = point;
           }
-
           bezierData.segmentLength = addedLength;
           storedData[bezierName] = bezierData;
         }
-
         return storedData[bezierName];
       };
     }();
-
     function getDistancePerc(perc, bezierData) {
       var percents = bezierData.percents;
       var lengths = bezierData.lengths;
@@ -3234,14 +2700,11 @@
       var initPos = bmFloor((len - 1) * perc);
       var lengthPos = perc * bezierData.addedLength;
       var lPerc = 0;
-
       if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
         return percents[initPos];
       }
-
       var dir = lengths[initPos] > lengthPos ? -1 : 1;
       var flag = true;
-
       while (flag) {
         if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
           lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
@@ -3249,20 +2712,16 @@
         } else {
           initPos += dir;
         }
-
         if (initPos < 0 || initPos >= len - 1) {
           // FIX for TypedArrays that don't store floating point values with enough accuracy
           if (initPos === len - 1) {
             return percents[initPos];
           }
-
           flag = false;
         }
       }
-
       return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
     }
-
     function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
       var t1 = getDistancePerc(percent, bezierData);
       var u1 = 1 - t1;
@@ -3270,16 +2729,13 @@
       var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
       return [ptX, ptY];
     }
-
     var bezierSegmentPoints = createTypedArray('float32', 8);
-
     function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
       if (startPerc < 0) {
         startPerc = 0;
       } else if (startPerc > 1) {
         startPerc = 1;
       }
-
       var t0 = getDistancePerc(startPerc, bezierData);
       endPerc = endPerc > 1 ? 1 : endPerc;
       var t1 = getDistancePerc(endPerc, bezierData);
@@ -3289,45 +2745,31 @@
       var u1 = 1 - t1;
       var u0u0u0 = u0 * u0 * u0;
       var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
-
       var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
-
-      var t0t0t0 = t0 * t0 * t0; //
-
+      var t0t0t0 = t0 * t0 * t0;
+      //
       var u0u0u1 = u0 * u0 * u1;
       var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
-
       var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
-
-      var t0t0t1 = t0 * t0 * t1; //
-
+      var t0t0t1 = t0 * t0 * t1;
+      //
       var u0u1u1 = u0 * u1 * u1;
       var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
-
       var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
-
-      var t0t1t1 = t0 * t1 * t1; //
-
+      var t0t1t1 = t0 * t1 * t1;
+      //
       var u1u1u1 = u1 * u1 * u1;
       var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1t1 = t1 * t1 * t1;
-
       for (i = 0; i < len; i += 1) {
         bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
       }
-
       return bezierSegmentPoints;
     }
-
     return {
       getSegmentsLength: getSegmentsLength,
       getNewSegment: getNewSegment,
@@ -3337,20 +2779,16 @@
       pointOnLine3D: pointOnLine3D
     };
   }
-
   var bez = bezFunction();
 
   var initFrame = initialDefaultFrame;
   var mathAbs = Math.abs;
-
   function interpolateValue(frameNum, caching) {
     var offsetTime = this.offsetTime;
     var newValue;
-
     if (this.propType === 'multidimensional') {
       newValue = createTypedArray('float32', this.pv.length);
     }
-
     var iterationIndex = caching.lastIndex;
     var i = iterationIndex;
     var len = this.keyframes.length - 1;
@@ -3358,25 +2796,20 @@
     var keyData;
     var nextKeyData;
     var keyframeMetadata;
-
     while (flag) {
       keyData = this.keyframes[i];
       nextKeyData = this.keyframes[i + 1];
-
       if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
         if (keyData.h) {
           keyData = nextKeyData;
         }
-
         iterationIndex = 0;
         break;
       }
-
       if (nextKeyData.t - offsetTime > frameNum) {
         iterationIndex = i;
         break;
       }
-
       if (i < len - 1) {
         i += 1;
       } else {
@@ -3384,7 +2817,6 @@
         flag = false;
       }
     }
-
     keyframeMetadata = this.keyframesMetadata[i] || {};
     var k;
     var kLen;
@@ -3395,22 +2827,18 @@
     var nextKeyTime = nextKeyData.t - offsetTime;
     var keyTime = keyData.t - offsetTime;
     var endValue;
-
     if (keyData.to) {
       if (!keyframeMetadata.bezierData) {
         keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
       }
-
       var bezierData = keyframeMetadata.bezierData;
-
       if (frameNum >= nextKeyTime || frameNum < keyTime) {
         var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
         kLen = bezierData.points[ind].point.length;
-
         for (k = 0; k < kLen; k += 1) {
           newValue[k] = bezierData.points[ind].point[k];
-        } // caching._lastKeyframeIndex = -1;
-
+        }
+        // caching._lastKeyframeIndex = -1;
       } else {
         if (keyframeMetadata.__fnct) {
           fnc = keyframeMetadata.__fnct;
@@ -3418,7 +2846,6 @@
           fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
           keyframeMetadata.__fnct = fnc;
         }
-
         perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
         var distanceInLine = bezierData.segmentLength * perc;
         var segmentPerc;
@@ -3426,36 +2853,28 @@
         j = caching.lastFrame < frameNum && caching._lastKeyframeIndex === i ? caching._lastPoint : 0;
         flag = true;
         jLen = bezierData.points.length;
-
         while (flag) {
           addedLength += bezierData.points[j].partialLength;
-
           if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k];
             }
-
             break;
           } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
             segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
             }
-
             break;
           }
-
           if (j < jLen - 1) {
             j += 1;
           } else {
             flag = false;
           }
         }
-
         caching._lastPoint = j;
         caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
         caching._lastKeyframeIndex = i;
@@ -3468,7 +2887,6 @@
       var keyValue;
       len = keyData.s.length;
       endValue = nextKeyData.s || keyData.e;
-
       if (this.sh && keyData.h !== 1) {
         if (frameNum >= nextKeyTime) {
           newValue[0] = endValue[0];
@@ -3496,7 +2914,6 @@
                 if (!keyframeMetadata.__fnct) {
                   keyframeMetadata.__fnct = [];
                 }
-
                 if (!keyframeMetadata.__fnct[i]) {
                   outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
                   outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
@@ -3517,14 +2934,11 @@
               } else {
                 fnc = keyframeMetadata.__fnct;
               }
-
               perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
             }
           }
-
           endValue = nextKeyData.s || keyData.e;
           keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
-
           if (this.propType === 'multidimensional') {
             newValue[i] = keyValue;
           } else {
@@ -3533,12 +2947,11 @@
         }
       }
     }
-
     caching.lastIndex = iterationIndex;
     return newValue;
-  } // based on @Toji's https://github.com/toji/gl-matrix/
+  }
 
-
+  // based on @Toji's https://github.com/toji/gl-matrix/
   function slerp(a, b, t) {
     var out = [];
     var ax = a[0];
@@ -3555,7 +2968,6 @@
     var scale0;
     var scale1;
     cosom = ax * bx + ay * by + az * bz + aw * bw;
-
     if (cosom < 0.0) {
       cosom = -cosom;
       bx = -bx;
@@ -3563,7 +2975,6 @@
       bz = -bz;
       bw = -bw;
     }
-
     if (1.0 - cosom > 0.000001) {
       omega = Math.acos(cosom);
       sinom = Math.sin(omega);
@@ -3573,14 +2984,12 @@
       scale0 = 1.0 - t;
       scale1 = t;
     }
-
     out[0] = scale0 * ax + scale1 * bx;
     out[1] = scale0 * ay + scale1 * by;
     out[2] = scale0 * az + scale1 * bz;
     out[3] = scale0 * aw + scale1 * bw;
     return out;
   }
-
   function quaternionToEuler(out, quat) {
     var qx = quat[0];
     var qy = quat[1];
@@ -3593,7 +3002,6 @@
     out[1] = attitude / degToRads;
     out[2] = bank / degToRads;
   }
-
   function createQuaternion(values) {
     var heading = values[0] * degToRads;
     var attitude = values[1] * degToRads;
@@ -3610,32 +3018,25 @@
     var z = c1 * s2 * c3 - s1 * c2 * s3;
     return [x, y, z, w];
   }
-
   function getValueAtCurrentTime() {
     var frameNum = this.comp.renderedFrame - this.offsetTime;
     var initTime = this.keyframes[0].t - this.offsetTime;
     var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
-
     if (!(frameNum === this._caching.lastFrame || this._caching.lastFrame !== initFrame && (this._caching.lastFrame >= endTime && frameNum >= endTime || this._caching.lastFrame < initTime && frameNum < initTime))) {
       if (this._caching.lastFrame >= frameNum) {
         this._caching._lastKeyframeIndex = -1;
         this._caching.lastIndex = 0;
       }
-
       var renderResult = this.interpolateValue(frameNum, this._caching);
       this.pv = renderResult;
     }
-
     this._caching.lastFrame = frameNum;
     return this.pv;
   }
-
   function setVValue(val) {
     var multipliedValue;
-
     if (this.propType === 'unidimensional') {
       multipliedValue = val * this.mult;
-
       if (mathAbs(this.v - multipliedValue) > 0.00001) {
         this.v = multipliedValue;
         this._mdf = true;
@@ -3643,51 +3044,41 @@
     } else {
       var i = 0;
       var len = this.v.length;
-
       while (i < len) {
         multipliedValue = val[i] * this.mult;
-
         if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
           this.v[i] = multipliedValue;
           this._mdf = true;
         }
-
         i += 1;
       }
     }
   }
-
   function processEffectsSequence() {
     if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
       return;
     }
-
     if (this.lock) {
       this.setVValue(this.pv);
       return;
     }
-
     this.lock = true;
     this._mdf = this._isFirstFrame;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = this.kf ? this.pv : this.data.k;
-
     for (i = 0; i < len; i += 1) {
       finalValue = this.effectsSequence[i](finalValue);
     }
-
     this.setVValue(finalValue);
     this._isFirstFrame = false;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   }
-
   function addEffect(effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.container.addDynamicProperty(this);
   }
-
   function ValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.mult = mult || 1;
@@ -3707,7 +3098,6 @@
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function MultiDimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     this.mult = mult || 1;
@@ -3724,19 +3114,16 @@
     this.v = createTypedArray('float32', len);
     this.pv = createTypedArray('float32', len);
     this.vel = createTypedArray('float32', len);
-
     for (i = 0; i < len; i += 1) {
       this.v[i] = data.k[i] * this.mult;
       this.pv[i] = data.k[i];
     }
-
     this._isFirstFrame = true;
     this.effectsSequence = [];
     this.getValue = processEffectsSequence;
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function KeyframedValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.keyframes = data.k;
@@ -3765,7 +3152,6 @@
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.addEffect = addEffect;
   }
-
   function KeyframedMultidimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     var i;
@@ -3774,19 +3160,16 @@
     var e;
     var to;
     var ti;
-
     for (i = 0; i < len - 1; i += 1) {
       if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
         s = data.k[i].s;
         e = data.k[i + 1].s;
         to = data.k[i].to;
         ti = data.k[i].ti;
-
         if (s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1]) || s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2])) {
           data.k[i].to = null;
           data.k[i].ti = null;
         }
-
         if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
           if (s.length === 2 || s[2] === e[2] && to[2] === 0 && ti[2] === 0) {
             data.k[i].to = null;
@@ -3795,7 +3178,6 @@
         }
       }
     }
-
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.data = data;
     this.keyframes = data.k;
@@ -3815,12 +3197,10 @@
     var arrLen = data.k[0].s.length;
     this.v = createTypedArray('float32', arrLen);
     this.pv = createTypedArray('float32', arrLen);
-
     for (i = 0; i < arrLen; i += 1) {
       this.v[i] = initFrame;
       this.pv[i] = initFrame;
     }
-
     this._caching = {
       lastFrame: initFrame,
       lastIndex: 0,
@@ -3828,15 +3208,12 @@
     };
     this.addEffect = addEffect;
   }
-
   var PropertyFactory = function () {
     function getProp(elem, data, type, mult, container) {
       if (data.sid) {
         data = elem.globalData.slotManager.getProp(data);
       }
-
       var p;
-
       if (!data.k.length) {
         p = new ValueProperty(elem, data, mult, container);
       } else if (typeof data.k[0] === 'number') {
@@ -3846,23 +3223,18 @@
           case 0:
             p = new KeyframedValueProperty(elem, data, mult, container);
             break;
-
           case 1:
             p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
             break;
-
           default:
             break;
         }
       }
-
       if (p.effectsSequence.length) {
         container.addDynamicProperty(p);
       }
-
       return p;
     }
-
     var ob = {
       getProp: getProp
     };
@@ -3870,7 +3242,6 @@
   }();
 
   function DynamicPropertyContainer() {}
-
   DynamicPropertyContainer.prototype = {
     addDynamicProperty: function addDynamicProperty(prop) {
       if (this.dynamicProperties.indexOf(prop) === -1) {
@@ -3883,10 +3254,8 @@
       this._mdf = false;
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         this.dynamicProperties[i].getValue();
-
         if (this.dynamicProperties[i]._mdf) {
           this._mdf = true;
         }
@@ -3904,7 +3273,6 @@
     function create() {
       return createTypedArray('float32', 2);
     }
-
     return poolFactory(8, create);
   }();
 
@@ -3916,12 +3284,10 @@
     this.o = createSizedArray(this._maxLength);
     this.i = createSizedArray(this._maxLength);
   }
-
   ShapePath.prototype.setPathData = function (closed, len) {
     this.c = closed;
     this.setLength(len);
     var i = 0;
-
     while (i < len) {
       this.v[i] = pointPool.newElement();
       this.o[i] = pointPool.newElement();
@@ -3929,62 +3295,49 @@
       i += 1;
     }
   };
-
   ShapePath.prototype.setLength = function (len) {
     while (this._maxLength < len) {
       this.doubleArrayLength();
     }
-
     this._length = len;
   };
-
   ShapePath.prototype.doubleArrayLength = function () {
     this.v = this.v.concat(createSizedArray(this._maxLength));
     this.i = this.i.concat(createSizedArray(this._maxLength));
     this.o = this.o.concat(createSizedArray(this._maxLength));
     this._maxLength *= 2;
   };
-
   ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
     var arr;
     this._length = Math.max(this._length, pos + 1);
-
     if (this._length >= this._maxLength) {
       this.doubleArrayLength();
     }
-
     switch (type) {
       case 'v':
         arr = this.v;
         break;
-
       case 'i':
         arr = this.i;
         break;
-
       case 'o':
         arr = this.o;
         break;
-
       default:
         arr = [];
         break;
     }
-
     if (!arr[pos] || arr[pos] && !replace) {
       arr[pos] = pointPool.newElement();
     }
-
     arr[pos][0] = x;
     arr[pos][1] = y;
   };
-
   ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
     this.setXYAt(vX, vY, 'v', pos, replace);
     this.setXYAt(oX, oY, 'o', pos, replace);
     this.setXYAt(iX, iY, 'i', pos, replace);
   };
-
   ShapePath.prototype.reverse = function () {
     var newPath = new ShapePath();
     newPath.setPathData(this.c, this._length);
@@ -3992,24 +3345,19 @@
     var outPoints = this.o;
     var inPoints = this.i;
     var init = 0;
-
     if (this.c) {
       newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
       init = 1;
     }
-
     var cnt = this._length - 1;
     var len = this._length;
     var i;
-
     for (i = init; i < len; i += 1) {
       newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
       cnt -= 1;
     }
-
     return newPath;
   };
-
   ShapePath.prototype.length = function () {
     return this._length;
   };
@@ -4018,11 +3366,9 @@
     function create() {
       return new ShapePath();
     }
-
     function release(shapePath) {
       var len = shapePath._length;
       var i;
-
       for (i = 0; i < len; i += 1) {
         pointPool.release(shapePath.v[i]);
         pointPool.release(shapePath.i[i]);
@@ -4031,25 +3377,20 @@
         shapePath.i[i] = null;
         shapePath.o[i] = null;
       }
-
       shapePath._length = 0;
       shapePath.c = false;
     }
-
     function clone(shape) {
       var cloned = factory.newElement();
       var i;
       var len = shape._length === undefined ? shape.v.length : shape._length;
       cloned.setLength(len);
       cloned.c = shape.c;
-
       for (i = 0; i < len; i += 1) {
         cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
       }
-
       return cloned;
     }
-
     var factory = poolFactory(4, create, release);
     factory.clone = clone;
     return factory;
@@ -4060,24 +3401,19 @@
     this._maxLength = 4;
     this.shapes = createSizedArray(this._maxLength);
   }
-
   ShapeCollection.prototype.addShape = function (shapeData) {
     if (this._length === this._maxLength) {
       this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
       this._maxLength *= 2;
     }
-
     this.shapes[this._length] = shapeData;
     this._length += 1;
   };
-
   ShapeCollection.prototype.releaseShapes = function () {
     var i;
-
     for (i = 0; i < this._length; i += 1) {
       shapePool.release(this.shapes[i]);
     }
-
     this._length = 0;
   };
 
@@ -4089,45 +3425,35 @@
     var _length = 0;
     var _maxLength = 4;
     var pool = createSizedArray(_maxLength);
-
     function newShapeCollection() {
       var shapeCollection;
-
       if (_length) {
         _length -= 1;
         shapeCollection = pool[_length];
       } else {
         shapeCollection = new ShapeCollection();
       }
-
       return shapeCollection;
     }
-
     function release(shapeCollection) {
       var i;
       var len = shapeCollection._length;
-
       for (i = 0; i < len; i += 1) {
         shapePool.release(shapeCollection.shapes[i]);
       }
-
       shapeCollection._length = 0;
-
       if (_length === _maxLength) {
         pool = pooling["double"](pool);
         _maxLength *= 2;
       }
-
       pool[_length] = shapeCollection;
       _length += 1;
     }
-
     return ob;
   }();
 
   var ShapePropertyFactory = function () {
     var initFrame = -999999;
-
     function interpolateShape(frameNum, previousValue, caching) {
       var iterationIndex = caching.lastIndex;
       var keyPropS;
@@ -4140,7 +3466,6 @@
       var perc;
       var vertexValue;
       var kf = this.keyframes;
-
       if (frameNum < kf[0].t - this.offsetTime) {
         keyPropS = kf[0].s[0];
         isHold = true;
@@ -4152,7 +3477,6 @@
               }else{
                   keyPropS = kf[kf.length - 2].e[0];
               } */
-
         isHold = true;
       } else {
         var i = iterationIndex;
@@ -4161,26 +3485,21 @@
         var keyData;
         var nextKeyData;
         var keyframeMetadata;
-
         while (flag) {
           keyData = kf[i];
           nextKeyData = kf[i + 1];
-
           if (nextKeyData.t - this.offsetTime > frameNum) {
             break;
           }
-
           if (i < len - 1) {
             i += 1;
           } else {
             flag = false;
           }
         }
-
         keyframeMetadata = this.keyframesMetadata[i] || {};
         isHold = keyData.h === 1;
         iterationIndex = i;
-
         if (!isHold) {
           if (frameNum >= nextKeyData.t - this.offsetTime) {
             perc = 1;
@@ -4188,27 +3507,21 @@
             perc = 0;
           } else {
             var fnc;
-
             if (keyframeMetadata.__fnct) {
               fnc = keyframeMetadata.__fnct;
             } else {
               fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
               keyframeMetadata.__fnct = fnc;
             }
-
             perc = fnc((frameNum - (keyData.t - this.offsetTime)) / (nextKeyData.t - this.offsetTime - (keyData.t - this.offsetTime)));
           }
-
           keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
         }
-
         keyPropS = keyData.s[0];
       }
-
       jLen = previousValue._length;
       kLen = keyPropS.i[0].length;
       caching.lastIndex = iterationIndex;
-
       for (j = 0; j < jLen; j += 1) {
         for (k = 0; k < kLen; k += 1) {
           vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
@@ -4220,44 +3533,36 @@
         }
       }
     }
-
     function interpolateShapeCurrentTime() {
       var frameNum = this.comp.renderedFrame - this.offsetTime;
       var initTime = this.keyframes[0].t - this.offsetTime;
       var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
       var lastFrame = this._caching.lastFrame;
-
       if (!(lastFrame !== initFrame && (lastFrame < initTime && frameNum < initTime || lastFrame > endTime && frameNum > endTime))) {
         /// /
         this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
-        this.interpolateShape(frameNum, this.pv, this._caching); /// /
+        this.interpolateShape(frameNum, this.pv, this._caching);
+        /// /
       }
-
       this._caching.lastFrame = frameNum;
       return this.pv;
     }
-
     function resetShape() {
       this.paths = this.localShapeCollection;
     }
-
     function shapesEqual(shape1, shape2) {
       if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
         return false;
       }
-
       var i;
       var len = shape1._length;
-
       for (i = 0; i < len; i += 1) {
         if (shape1.v[i][0] !== shape2.v[i][0] || shape1.v[i][1] !== shape2.v[i][1] || shape1.o[i][0] !== shape2.o[i][0] || shape1.o[i][1] !== shape2.o[i][1] || shape1.i[i][0] !== shape2.i[i][0] || shape1.i[i][1] !== shape2.i[i][1]) {
           return false;
         }
       }
-
       return true;
     }
-
     function setVValue(newPath) {
       if (!shapesEqual(this.v, newPath)) {
         this.v = shapePool.clone(newPath);
@@ -4267,26 +3572,21 @@
         this.paths = this.localShapeCollection;
       }
     }
-
     function processEffectsSequence() {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (!this.effectsSequence.length) {
         this._mdf = false;
         return;
       }
-
       if (this.lock) {
         this.setVValue(this.pv);
         return;
       }
-
       this.lock = true;
       this._mdf = false;
       var finalValue;
-
       if (this.kf) {
         finalValue = this.pv;
       } else if (this.data.ks) {
@@ -4294,19 +3594,15 @@
       } else {
         finalValue = this.data.pt.k;
       }
-
       var i;
       var len = this.effectsSequence.length;
-
       for (i = 0; i < len; i += 1) {
         finalValue = this.effectsSequence[i](finalValue);
       }
-
       this.setVValue(finalValue);
       this.lock = false;
       this.frameId = this.elem.globalData.frameId;
     }
-
     function ShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4325,17 +3621,14 @@
       this.reset = resetShape;
       this.effectsSequence = [];
     }
-
     function addEffect(effectFunction) {
       this.effectsSequence.push(effectFunction);
       this.container.addDynamicProperty(this);
     }
-
     ShapeProperty.prototype.interpolateShape = interpolateShape;
     ShapeProperty.prototype.getValue = processEffectsSequence;
     ShapeProperty.prototype.setVValue = setVValue;
     ShapeProperty.prototype.addEffect = addEffect;
-
     function KeyframedShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4361,15 +3654,12 @@
       };
       this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
     }
-
     KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
     KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
     KeyframedShapeProperty.prototype.setVValue = setVValue;
     KeyframedShapeProperty.prototype.addEffect = addEffect;
-
     var EllShapeProperty = function () {
       var cPoint = roundCorner;
-
       function EllShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
         this.v.setPathData(true, 4);
@@ -4383,7 +3673,6 @@
         this.initDynamicPropertyContainer(elem);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4391,17 +3680,14 @@
           this.convertEllToPath();
         }
       }
-
       EllShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertEllToPath();
           }
@@ -4411,9 +3697,7 @@
           var p1 = this.p.v[1];
           var s0 = this.s.v[0] / 2;
           var s1 = this.s.v[1] / 2;
-
           var _cw = this.d !== 3;
-
           var _v = this.v;
           _v.v[0][0] = p0;
           _v.v[0][1] = p1 - s1;
@@ -4444,7 +3728,6 @@
       extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
       return EllShapePropertyFactory;
     }();
-
     var StarShapeProperty = function () {
       function StarShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4455,7 +3738,6 @@
         this.frameId = -1;
         this.d = data.d;
         this.initDynamicPropertyContainer(elem);
-
         if (data.sy === 1) {
           this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
           this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
@@ -4463,7 +3745,6 @@
         } else {
           this.convertToPath = this.convertPolygonToPath;
         }
-
         this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
@@ -4472,7 +3753,6 @@
         this.localShapeCollection = shapeCollectionPool.newShapeCollection();
         this.localShapeCollection.addShape(this.v);
         this.paths = this.localShapeCollection;
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4480,17 +3760,14 @@
           this.convertToPath();
         }
       }
-
       StarShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertToPath();
           }
@@ -4501,7 +3778,6 @@
           /* this.v.v.length = numPts;
                   this.v.i.length = numPts;
                   this.v.o.length = numPts; */
-
           var longFlag = true;
           var longRad = this.or.v;
           var shortRad = this.ir.v;
@@ -4517,7 +3793,6 @@
           currentAng += this.r.v;
           var dir = this.data.d === 3 ? -1 : 1;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             rad = longFlag ? longRad : shortRad;
             roundness = longFlag ? longRound : shortRound;
@@ -4529,11 +3804,11 @@
             x += +this.p.v[0];
             y += +this.p.v[1];
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
             /* this.v.v[i] = [x,y];
                       this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
                       this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
                       this.v._length = numPts; */
-
             longFlag = !longFlag;
             currentAng += angle * dir;
           }
@@ -4549,7 +3824,6 @@
           var dir = this.data.d === 3 ? -1 : 1;
           currentAng += this.r.v;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             var x = rad * Math.cos(currentAng);
             var y = rad * Math.sin(currentAng);
@@ -4560,7 +3834,6 @@
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
             currentAng += angle * dir;
           }
-
           this.paths.length = 0;
           this.paths[0] = this.v;
         }
@@ -4568,7 +3841,6 @@
       extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
       return StarShapePropertyFactory;
     }();
-
     var RectShapeProperty = function () {
       function RectShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4584,7 +3856,6 @@
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4592,7 +3863,6 @@
           this.convertRectToPath();
         }
       }
-
       RectShapePropertyFactory.prototype = {
         convertRectToPath: function convertRectToPath() {
           var p0 = this.p.v[0];
@@ -4602,11 +3872,9 @@
           var round = bmMin(v0, v1, this.r.v);
           var cPoint = round * (1 - roundCorner);
           this.v._length = 0;
-
           if (this.d === 2 || this.d === 1) {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
             this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
               this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
@@ -4620,7 +3888,6 @@
             }
           } else {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
               this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
@@ -4640,10 +3907,8 @@
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertRectToPath();
           }
@@ -4653,14 +3918,11 @@
       extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
       return RectShapePropertyFactory;
     }();
-
     function getShapeProp(elem, data, type) {
       var prop;
-
       if (type === 3 || type === 4) {
         var dataProp = type === 3 ? data.pt : data.ks;
         var keys = dataProp.k;
-
         if (keys.length) {
           prop = new KeyframedShapeProperty(elem, data, type);
         } else {
@@ -4673,22 +3935,17 @@
       } else if (type === 7) {
         prop = new StarShapeProperty(elem, data);
       }
-
       if (prop.k) {
         elem.addDynamicProperty(prop);
       }
-
       return prop;
     }
-
     function getConstructorFunction() {
       return ShapeProperty;
     }
-
     function getKeyframedConstructorFunction() {
       return KeyframedShapeProperty;
     }
-
     var ob = {};
     ob.getShapeProp = getShapeProp;
     ob.getConstructorFunction = getConstructorFunction;
@@ -4730,7 +3987,6 @@
     var _sin = Math.sin;
     var _tan = Math.tan;
     var _rnd = Math.round;
-
     function reset() {
       this.props[0] = 1;
       this.props[1] = 0;
@@ -4750,83 +4006,59 @@
       this.props[15] = 1;
       return this;
     }
-
     function rotate(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function rotateX(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateY(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateZ(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function shear(sx, sy) {
       return this._t(1, sy, sx, 1, 0, 0);
     }
-
     function skew(ax, ay) {
       return this.shear(_tan(ax), _tan(ay));
     }
-
     function skewFromAxis(ax, angle) {
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
-      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+      // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
     }
-
     function scale(sx, sy, sz) {
       if (!sz && sz !== 0) {
         sz = 1;
       }
-
       if (sx === 1 && sy === 1 && sz === 1) {
         return this;
       }
-
       return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
     }
-
     function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
       this.props[0] = a;
       this.props[1] = b;
@@ -4846,32 +4078,26 @@
       this.props[15] = p;
       return this;
     }
-
     function translate(tx, ty, tz) {
       tz = tz || 0;
-
       if (tx !== 0 || ty !== 0 || tz !== 0) {
         return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
       }
-
       return this;
     }
-
     function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
       var _p = this.props;
-
       if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
         // NOTE: commenting this condition because TurboFan deoptimizes code when present
         // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
         _p[12] = _p[12] * a2 + _p[15] * m2;
         _p[13] = _p[13] * f2 + _p[15] * n2;
         _p[14] = _p[14] * k2 + _p[15] * o2;
-        _p[15] *= p2; // }
-
+        _p[15] *= p2;
+        // }
         this._identityCalculated = false;
         return this;
       }
-
       var a1 = _p[0];
       var b1 = _p[1];
       var c1 = _p[2];
@@ -4888,12 +4114,12 @@
       var n1 = _p[13];
       var o1 = _p[14];
       var p1 = _p[15];
+
       /* matrix order (canvas compatible):
            * ace
            * bdf
            * 001
            */
-
       _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
       _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
       _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
@@ -4913,53 +4139,40 @@
       this._identityCalculated = false;
       return this;
     }
-
     function multiply(matrix) {
       var matrixProps = matrix.props;
       return this.transform(matrixProps[0], matrixProps[1], matrixProps[2], matrixProps[3], matrixProps[4], matrixProps[5], matrixProps[6], matrixProps[7], matrixProps[8], matrixProps[9], matrixProps[10], matrixProps[11], matrixProps[12], matrixProps[13], matrixProps[14], matrixProps[15]);
     }
-
     function isIdentity() {
       if (!this._identityCalculated) {
         this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
         this._identityCalculated = true;
       }
-
       return this._identity;
     }
-
     function equals(matr) {
       var i = 0;
-
       while (i < 16) {
         if (matr.props[i] !== this.props[i]) {
           return false;
         }
-
         i += 1;
       }
-
       return true;
     }
-
     function clone(matr) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         matr.props[i] = this.props[i];
       }
-
       return matr;
     }
-
     function cloneFromProps(props) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         this.props[i] = props[i];
       }
     }
-
     function applyToPoint(x, y, z) {
       return {
         x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
@@ -4971,19 +4184,15 @@
            y: x * me.b + y * me.d + me.f
            }; */
     }
-
     function applyToX(x, y, z) {
       return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
     }
-
     function applyToY(x, y, z) {
       return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
     }
-
     function applyToZ(x, y, z) {
       return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
     }
-
     function getInverseMatrix() {
       var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
       var a = this.props[5] / determinant;
@@ -5001,27 +4210,21 @@
       inverseMatrix.props[13] = f;
       return inverseMatrix;
     }
-
     function inversePoint(pt) {
       var inverseMatrix = this.getInverseMatrix();
       return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
     }
-
     function inversePoints(pts) {
       var i;
       var len = pts.length;
       var retPts = [];
-
       for (i = 0; i < len; i += 1) {
         retPts[i] = inversePoint(pts[i]);
       }
-
       return retPts;
     }
-
     function applyToTriplePoints(pt1, pt2, pt3) {
       var arr = createTypedArray('float32', 6);
-
       if (this.isIdentity()) {
         arr[0] = pt1[0];
         arr[1] = pt1[1];
@@ -5043,34 +4246,26 @@
         arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
         arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
       }
-
       return arr;
     }
-
     function applyToPointArray(x, y, z) {
       var arr;
-
       if (this.isIdentity()) {
         arr = [x, y, z];
       } else {
         arr = [x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12], x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13], x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14]];
       }
-
       return arr;
     }
-
     function applyToPointStringified(x, y) {
       if (this.isIdentity()) {
         return x + ',' + y;
       }
-
       var _p = this.props;
       return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
     }
-
     function toCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
@@ -5078,49 +4273,34 @@
       var props = this.props;
       var cssValue = 'matrix3d(';
       var v = 10000;
-
       while (i < 16) {
         cssValue += _rnd(props[i] * v) / v;
         cssValue += i === 15 ? ')' : ',';
         i += 1;
       }
-
       return cssValue;
     }
-
     function roundMatrixProperty(val) {
       var v = 10000;
-
       if (val < 0.000001 && val > 0 || val > -0.000001 && val < 0) {
         return _rnd(val * v) / v;
       }
-
       return val;
     }
-
     function to2dCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
       var props = this.props;
-
       var _a = roundMatrixProperty(props[0]);
-
       var _b = roundMatrixProperty(props[1]);
-
       var _c = roundMatrixProperty(props[4]);
-
       var _d = roundMatrixProperty(props[5]);
-
       var _e = roundMatrixProperty(props[12]);
-
       var _f = roundMatrixProperty(props[13]);
-
       return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
     }
-
     return function () {
       this.reset = reset;
       this.rotate = rotate;
@@ -5159,16 +4339,14 @@
     };
   }();
 
-  function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
   var lottie = {};
   var standalone = '__[STANDALONE]__';
   var animationData = '__[ANIMATIONDATA]__';
   var renderer = '';
-
   function setLocation(href) {
     setLocationHref(href);
   }
-
   function searchAnimations() {
     if (standalone === true) {
       animationManager.searchAnimations(animationData, standalone, renderer);
@@ -5176,35 +4354,28 @@
       animationManager.searchAnimations();
     }
   }
-
   function setSubframeRendering(flag) {
     setSubframeEnabled(flag);
   }
-
   function setPrefix(prefix) {
     setIdPrefix(prefix);
   }
-
   function loadAnimation(params) {
     if (standalone === true) {
       params.animationData = JSON.parse(animationData);
     }
-
     return animationManager.loadAnimation(params);
   }
-
   function setQuality(value) {
     if (typeof value === 'string') {
       switch (value) {
         case 'high':
           setDefaultCurveSegments(200);
           break;
-
         default:
         case 'medium':
           setDefaultCurveSegments(50);
           break;
-
         case 'low':
           setDefaultCurveSegments(10);
           break;
@@ -5212,40 +4383,32 @@
     } else if (!isNaN(value) && value > 1) {
       setDefaultCurveSegments(value);
     }
-
     if (getDefaultCurveSegments() >= 50) {
       roundValues(false);
     } else {
       roundValues(true);
     }
   }
-
   function inBrowser() {
     return typeof navigator !== 'undefined';
   }
-
   function installPlugin(type, plugin) {
     if (type === 'expressions') {
       setExpressionsPlugin(plugin);
     }
   }
-
   function getFactory(name) {
     switch (name) {
       case 'propertyFactory':
         return PropertyFactory;
-
       case 'shapePropertyFactory':
         return ShapePropertyFactory;
-
       case 'matrix':
         return Matrix;
-
       default:
         return null;
     }
   }
-
   lottie.play = animationManager.play;
   lottie.pause = animationManager.pause;
   lottie.setLocationHref = setLocation;
@@ -5257,8 +4420,8 @@
   lottie.registerAnimation = animationManager.registerAnimation;
   lottie.loadAnimation = loadAnimation;
   lottie.setSubframeRendering = setSubframeRendering;
-  lottie.resize = animationManager.resize; // lottie.start = start;
-
+  lottie.resize = animationManager.resize;
+  // lottie.start = start;
   lottie.goToAndStop = animationManager.goToAndStop;
   lottie.destroy = animationManager.destroy;
   lottie.setQuality = setQuality;
@@ -5273,32 +4436,25 @@
   lottie.useWebWorker = setWebWorker;
   lottie.setIDPrefix = setPrefix;
   lottie.__getFactory = getFactory;
-  lottie.version = '5.12.2';
-
+  lottie.version = '5.13.0';
   function checkReady() {
     if (document.readyState === 'complete') {
       clearInterval(readyStateCheckInterval);
       searchAnimations();
     }
   }
-
   function getQueryVariable(variable) {
     var vars = queryString.split('&');
-
     for (var i = 0; i < vars.length; i += 1) {
       var pair = vars[i].split('=');
-
       if (decodeURIComponent(pair[0]) == variable) {
         // eslint-disable-line eqeqeq
         return decodeURIComponent(pair[1]);
       }
     }
-
     return null;
   }
-
   var queryString = '';
-
   if (standalone) {
     var scripts = document.getElementsByTagName('script');
     var index = scripts.length - 1;
@@ -5306,18 +4462,18 @@
       src: ''
     };
     queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
-
     renderer = getQueryVariable('renderer');
   }
+  var readyStateCheckInterval = setInterval(checkReady, 100);
 
-  var readyStateCheckInterval = setInterval(checkReady, 100); // this adds bodymovin to the window object for backwards compatibility
-
+  // this adds bodymovin to the window object for backwards compatibility
   try {
     if (!((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === 'object' && typeof module !== 'undefined') && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
     ) {
       window.bodymovin = lottie;
     }
-  } catch (err) {//
+  } catch (err) {
+    //
   }
 
   var ShapeModifiers = function () {
@@ -5325,26 +4481,19 @@
     var modifiers = {};
     ob.registerModifier = registerModifier;
     ob.getModifier = getModifier;
-
     function registerModifier(nm, factory) {
       if (!modifiers[nm]) {
         modifiers[nm] = factory;
       }
     }
-
     function getModifier(nm, elem, data) {
       return new modifiers[nm](elem, data);
     }
-
     return ob;
   }();
-
   function ShapeModifier() {}
-
   ShapeModifier.prototype.initModifierProperties = function () {};
-
   ShapeModifier.prototype.addShapeToModifier = function () {};
-
   ShapeModifier.prototype.addShape = function (data) {
     if (!this.closed) {
       // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
@@ -5356,13 +4505,11 @@
       };
       this.shapes.push(shapeData);
       this.addShapeToModifier(shapeData);
-
       if (this._isAnimated) {
         data.setAsAnimated();
       }
     }
   };
-
   ShapeModifier.prototype.init = function (elem, data) {
     this.shapes = [];
     this.elem = elem;
@@ -5371,29 +4518,23 @@
     this.frameId = initialDefaultFrame;
     this.closed = false;
     this.k = false;
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   ShapeModifier.prototype.processKeys = function () {
     if (this.elem.globalData.frameId === this.frameId) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   extendPrototype([DynamicPropertyContainer], ShapeModifier);
 
   function TrimModifier() {}
-
   extendPrototype([ShapeModifier], TrimModifier);
-
   TrimModifier.prototype.initModifierProperties = function (elem, data) {
     this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
     this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
@@ -5404,14 +4545,11 @@
     this.m = data.m;
     this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
   };
-
   TrimModifier.prototype.addShapeToModifier = function (shapeData) {
     shapeData.pathsData = [];
   };
-
   TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
     var segments = [];
-
     if (e <= 1) {
       segments.push({
         s: s,
@@ -5432,65 +4570,50 @@
         e: e - 1
       });
     }
-
     var shapeSegments = [];
     var i;
     var len = segments.length;
     var segmentOb;
-
     for (i = 0; i < len; i += 1) {
       segmentOb = segments[i];
-
       if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
         var shapeS;
         var shapeE;
-
         if (segmentOb.s * totalModifierLength <= addedLength) {
           shapeS = 0;
         } else {
           shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
         }
-
         if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
           shapeE = 1;
         } else {
           shapeE = (segmentOb.e * totalModifierLength - addedLength) / shapeLength;
         }
-
         shapeSegments.push([shapeS, shapeE]);
       }
     }
-
     if (!shapeSegments.length) {
       shapeSegments.push([0, 0]);
     }
-
     return shapeSegments;
   };
-
   TrimModifier.prototype.releasePathsData = function (pathsData) {
     var i;
     var len = pathsData.length;
-
     for (i = 0; i < len; i += 1) {
       segmentsLengthPool.release(pathsData[i]);
     }
-
     pathsData.length = 0;
     return pathsData;
   };
-
   TrimModifier.prototype.processShapes = function (_isFirstFrame) {
     var s;
     var e;
-
     if (this._mdf || _isFirstFrame) {
       var o = this.o.v % 360 / 360;
-
       if (o < 0) {
         o += 1;
       }
-
       if (this.s.v > 1) {
         s = 1 + o;
       } else if (this.s.v < 0) {
@@ -5498,7 +4621,6 @@
       } else {
         s = this.s.v + o;
       }
-
       if (this.e.v > 1) {
         e = 1 + o;
       } else if (this.e.v < 0) {
@@ -5506,13 +4628,11 @@
       } else {
         e = this.e.v + o;
       }
-
       if (s > e) {
         var _s = s;
         s = e;
         e = _s;
       }
-
       s = Math.round(s * 10000) * 0.0001;
       e = Math.round(e * 10000) * 0.0001;
       this.sValue = s;
@@ -5521,7 +4641,6 @@
       s = this.sValue;
       e = this.eValue;
     }
-
     var shapePaths;
     var i;
     var len = this.shapes.length;
@@ -5531,13 +4650,11 @@
     var pathData;
     var totalShapeLength;
     var totalModifierLength = 0;
-
     if (e === s) {
       for (i = 0; i < len; i += 1) {
         this.shapes[i].localShapeCollection.releaseShapes();
         this.shapes[i].shape._mdf = true;
         this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
-
         if (this._mdf) {
           this.shapes[i].pathsData.length = 0;
         }
@@ -5546,63 +4663,52 @@
       var segments = [];
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
-        shapeData = this.shapes[i]; // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
-
+        shapeData = this.shapes[i];
+        // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
         if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
           shapeData.shape.paths = shapeData.localShapeCollection;
         } else {
           shapePaths = shapeData.shape.paths;
           jLen = shapePaths._length;
           totalShapeLength = 0;
-
           if (!shapeData.shape._mdf && shapeData.pathsData.length) {
             totalShapeLength = shapeData.totalShapeLength;
           } else {
             pathsData = this.releasePathsData(shapeData.pathsData);
-
             for (j = 0; j < jLen; j += 1) {
               pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
               pathsData.push(pathData);
               totalShapeLength += pathData.totalLength;
             }
-
             shapeData.totalShapeLength = totalShapeLength;
             shapeData.pathsData = pathsData;
           }
-
           totalModifierLength += totalShapeLength;
           shapeData.shape._mdf = true;
         }
       }
-
       var shapeS = s;
       var shapeE = e;
       var addedLength = 0;
       var edges;
-
       for (i = len - 1; i >= 0; i -= 1) {
         shapeData = this.shapes[i];
-
         if (shapeData.shape._mdf) {
           localShapeCollection = shapeData.localShapeCollection;
-          localShapeCollection.releaseShapes(); // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
-
+          localShapeCollection.releaseShapes();
+          // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
           if (this.m === 2 && len > 1) {
             edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
             addedLength += shapeData.totalShapeLength;
           } else {
             edges = [[shapeS, shapeE]];
           }
-
           jLen = edges.length;
-
           for (j = 0; j < jLen; j += 1) {
             shapeS = edges[j][0];
             shapeE = edges[j][1];
             segments.length = 0;
-
             if (shapeE <= 1) {
               segments.push({
                 s: shapeData.totalShapeLength * shapeS,
@@ -5623,13 +4729,10 @@
                 e: shapeData.totalShapeLength * (shapeE - 1)
               });
             }
-
             var newShapesData = this.addShapes(shapeData, segments[0]);
-
             if (segments[0].s !== segments[0].e) {
               if (segments.length > 1) {
                 var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
-
                 if (lastShapeInCollection.c) {
                   var lastShape = newShapesData.pop();
                   this.addPaths(newShapesData, localShapeCollection);
@@ -5639,11 +4742,9 @@
                   newShapesData = this.addShapes(shapeData, segments[1]);
                 }
               }
-
               this.addPaths(newShapesData, localShapeCollection);
             }
           }
-
           shapeData.shape.paths = localShapeCollection;
         }
       }
@@ -5656,38 +4757,29 @@
       }
     }
   };
-
   TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
     var i;
     var len = newPaths.length;
-
     for (i = 0; i < len; i += 1) {
       localShapeCollection.addShape(newPaths[i]);
     }
   };
-
   TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
     shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
     shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
     }
-
     shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
     shapePath.setXYAt(points[1], points[5], 'o', pos);
     shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(points[0], points[4], 'v', pos);
     }
-
     shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
     var pathsData = shapeData.pathsData;
     var shapePaths = shapeData.shape.paths.shapes;
@@ -5703,7 +4795,6 @@
     var shapes = [];
     var initPos;
     var newShape = true;
-
     if (!shapePath) {
       shapePath = shapePool.newElement();
       segmentCount = 0;
@@ -5712,17 +4803,13 @@
       segmentCount = shapePath._length;
       initPos = shapePath._length;
     }
-
     shapes.push(shapePath);
-
     for (i = 0; i < len; i += 1) {
       lengths = pathsData[i].lengths;
       shapePath.c = shapePaths[i].c;
       jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
-
       for (j = 1; j < jLen; j += 1) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
           addedLength += currentLengthData.addedLength;
           shapePath.c = false;
@@ -5735,50 +4822,42 @@
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
-
           addedLength += currentLengthData.addedLength;
           segmentCount += 1;
         }
       }
-
       if (shapePaths[i].c && lengths.length) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength <= shapeSegment.e) {
           var segmentLength = lengths[j - 1].addedLength;
-
           if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
             this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
         } else {
           shapePath.c = false;
         }
-
         addedLength += currentLengthData.addedLength;
         segmentCount += 1;
       }
-
       if (shapePath._length) {
         shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
         shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
       }
-
       if (addedLength > shapeSegment.e) {
         break;
       }
-
       if (i < len - 1) {
         shapePath = shapePool.newElement();
         newShape = true;
@@ -5786,31 +4865,25 @@
         segmentCount = 0;
       }
     }
-
     return shapes;
   };
 
   function PuckerAndBloatModifier() {}
-
   extendPrototype([ShapeModifier], PuckerAndBloatModifier);
-
   PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
     this._isAnimated = !!this.amount.effectsSequence.length;
   };
-
   PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
     var percent = amount / 100;
     var centerPoint = [0, 0];
     var pathLength = path._length;
     var i = 0;
-
     for (i = 0; i < pathLength; i += 1) {
       centerPoint[0] += path.v[i][0];
       centerPoint[1] += path.v[i][1];
     }
-
     centerPoint[0] /= pathLength;
     centerPoint[1] /= pathLength;
     var clonedPath = shapePool.newElement();
@@ -5821,7 +4894,6 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < pathLength; i += 1) {
       vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
       vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
@@ -5831,10 +4903,8 @@
       iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
       clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
     }
-
     return clonedPath;
   };
-
   PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -5842,30 +4912,24 @@
     var j;
     var jLen;
     var amount = this.amount.v;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -5873,30 +4937,24 @@
 
   var TransformPropertyFactory = function () {
     var defaultVector = [0, 0];
-
     function applyToMatrix(mat) {
       var _mdf = this._mdf;
       this.iterateDynamicProperties();
       this._mdf = this._mdf || _mdf;
-
       if (this.a) {
         mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
       }
-
       if (this.s) {
         mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
       }
-
       if (this.sk) {
         mat.skewFromAxis(-this.sk.v, this.sa.v);
       }
-
       if (this.r) {
         mat.rotate(-this.r.v);
       } else {
         mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
       }
-
       if (this.data.p.s) {
         if (this.data.p.z) {
           mat.translate(this.px.v, this.py.v, -this.pz.v);
@@ -5907,46 +4965,36 @@
         mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
       }
     }
-
     function processKeys(forceRender) {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (this._isDirty) {
         this.precalculateMatrix();
         this._isDirty = false;
       }
-
       this.iterateDynamicProperties();
-
       if (this._mdf || forceRender) {
         var frameRate;
         this.v.cloneFromProps(this.pre.props);
-
         if (this.appliedTransformations < 1) {
           this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         }
-
         if (this.appliedTransformations < 2) {
           this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         }
-
         if (this.sk && this.appliedTransformations < 3) {
           this.v.skewFromAxis(-this.sk.v, this.sa.v);
         }
-
         if (this.r && this.appliedTransformations < 4) {
           this.v.rotate(-this.r.v);
         } else if (!this.r && this.appliedTransformations < 4) {
           this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
         }
-
         if (this.autoOriented) {
           var v1;
           var v2;
           frameRate = this.elem.globalData.frameRate;
-
           if (this.p && this.p.keyframes && this.p.getValueAtTime) {
             if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
               v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
@@ -5963,7 +5011,6 @@
             v2 = [];
             var px = this.px;
             var py = this.py;
-
             if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
               v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
               v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
@@ -5983,10 +5030,8 @@
             v2 = defaultVector;
             v1 = v2;
           }
-
           this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
         }
-
         if (this.data.p && this.data.p.s) {
           if (this.data.p.z) {
             this.v.translate(this.px.v, this.py.v, -this.pz.v);
@@ -5997,28 +5042,23 @@
           this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
         }
       }
-
       this.frameId = this.elem.globalData.frameId;
     }
-
     function precalculateMatrix() {
       this.appliedTransformations = 0;
       this.pre.reset();
-
       if (!this.a.effectsSequence.length) {
         this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         this.appliedTransformations = 1;
       } else {
         return;
       }
-
       if (!this.s.effectsSequence.length) {
         this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         this.appliedTransformations = 2;
       } else {
         return;
       }
-
       if (this.sk) {
         if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
           this.pre.skewFromAxis(-this.sk.v, this.sa.v);
@@ -6027,7 +5067,6 @@
           return;
         }
       }
-
       if (this.r) {
         if (!this.r.effectsSequence.length) {
           this.pre.rotate(-this.r.v);
@@ -6038,33 +5077,28 @@
         this.appliedTransformations = 4;
       }
     }
-
-    function autoOrient() {//
+    function autoOrient() {
+      //
       // var prevP = this.getValueAtTime();
     }
-
     function addDynamicProperty(prop) {
       this._addDynamicProperty(prop);
-
       this.elem.addDynamicProperty(prop);
       this._isDirty = true;
     }
-
     function TransformProperty(elem, data, container) {
       this.elem = elem;
       this.frameId = -1;
       this.propType = 'transform';
       this.data = data;
-      this.v = new Matrix(); // Precalculated matrix with non animated properties
-
+      this.v = new Matrix();
+      // Precalculated matrix with non animated properties
       this.pre = new Matrix();
       this.appliedTransformations = 0;
       this.initDynamicPropertyContainer(container || elem);
-
       if (data.p && data.p.s) {
         this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
         this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
-
         if (data.p.z) {
           this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
         }
@@ -6073,43 +5107,37 @@
           k: [0, 0, 0]
         }, 1, 0, this);
       }
-
       if (data.rx) {
         this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
         this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
         this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
-
         if (data.or.k[0].ti) {
           var i;
           var len = data.or.k.length;
-
           for (i = 0; i < len; i += 1) {
             data.or.k[i].to = null;
             data.or.k[i].ti = null;
           }
         }
-
-        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this); // sh Indicates it needs to be capped between -180 and 180
-
+        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+        // sh Indicates it needs to be capped between -180 and 180
         this.or.sh = true;
       } else {
         this.r = PropertyFactory.getProp(elem, data.r || {
           k: 0
         }, 0, degToRads, this);
       }
-
       if (data.sk) {
         this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
         this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
       }
-
       this.a = PropertyFactory.getProp(elem, data.a || {
         k: [0, 0, 0]
       }, 1, 0, this);
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: [100, 100, 100]
-      }, 1, 0.01, this); // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
-
+      }, 1, 0.01, this);
+      // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
       if (data.o) {
         this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
       } else {
@@ -6118,14 +5146,11 @@
           v: 1
         };
       }
-
       this._isDirty = true;
-
       if (!this.dynamicProperties.length) {
         this.getValue(true);
       }
     }
-
     TransformProperty.prototype = {
       applyToMatrix: applyToMatrix,
       getValue: processKeys,
@@ -6135,20 +5160,16 @@
     extendPrototype([DynamicPropertyContainer], TransformProperty);
     TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
     TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
-
     function getTransformProperty(elem, data, container) {
       return new TransformProperty(elem, data, container);
     }
-
     return {
       getTransformProperty: getTransformProperty
     };
   }();
 
   function RepeaterModifier() {}
-
   extendPrototype([ShapeModifier], RepeaterModifier);
-
   RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
@@ -6157,11 +5178,9 @@
     this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
     this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
     this.data = data;
-
     if (!this.dynamicProperties.length) {
       this.getValue(true);
     }
-
     this._isAnimated = !!this.dynamicProperties.length;
     this.pMatrix = new Matrix();
     this.rMatrix = new Matrix();
@@ -6169,7 +5188,6 @@
     this.tMatrix = new Matrix();
     this.matrix = new Matrix();
   };
-
   RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
     var dir = inv ? -1 : 1;
     var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
@@ -6182,7 +5200,6 @@
     sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
     sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
   };
-
   RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
     this.elem = elem;
     this.arr = arr;
@@ -6194,52 +5211,42 @@
     this.frameId = -1;
     this.initDynamicPropertyContainer(elem);
     this.initModifierProperties(elem, arr[pos]);
-
     while (pos > 0) {
-      pos -= 1; // this._elements.unshift(arr.splice(pos,1)[0]);
-
+      pos -= 1;
+      // this._elements.unshift(arr.splice(pos,1)[0]);
       this._elements.unshift(arr[pos]);
     }
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   RepeaterModifier.prototype.resetElements = function (elements) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._processed = false;
-
       if (elements[i].ty === 'gr') {
         this.resetElements(elements[i].it);
       }
     }
   };
-
   RepeaterModifier.prototype.cloneElements = function (elements) {
     var newElements = JSON.parse(JSON.stringify(elements));
     this.resetElements(newElements);
     return newElements;
   };
-
   RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._render = renderFlag;
-
       if (elements[i].ty === 'gr') {
         this.changeGroupRender(elements[i].it, renderFlag);
       }
     }
   };
-
   RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
     var items;
     var itemsTransform;
@@ -6247,10 +5254,8 @@
     var dir;
     var cont;
     var hasReloaded = false;
-
     if (this._mdf || _isFirstFrame) {
       var copies = Math.ceil(this.c.v);
-
       if (this._groups.length < copies) {
         while (this._groups.length < copies) {
           var group = {
@@ -6305,28 +5310,21 @@
             ty: 'tr'
           });
           this.arr.splice(0, 0, group);
-
           this._groups.splice(0, 0, group);
-
           this._currentCopies += 1;
         }
-
         this.elem.reloadShapes();
         hasReloaded = true;
       }
-
       cont = 0;
       var renderFlag;
-
       for (i = 0; i <= this._groups.length - 1; i += 1) {
         renderFlag = cont < copies;
         this._groups[i]._render = renderFlag;
         this.changeGroupRender(this._groups[i].it, renderFlag);
-
         if (!renderFlag) {
           var elems = this.elemsData[i].it;
           var transformData = elems[elems.length - 1];
-
           if (transformData.transform.op.v !== 0) {
             transformData.transform.op._mdf = true;
             transformData.transform.op.v = 0;
@@ -6334,11 +5332,10 @@
             transformData.transform.op._mdf = false;
           }
         }
-
         cont += 1;
       }
-
-      this._currentCopies = copies; /// /
+      this._currentCopies = copies;
+      /// /
 
       var offset = this.o.v;
       var offsetModulo = offset % 1;
@@ -6352,13 +5349,11 @@
       this.tMatrix.reset();
       this.matrix.reset();
       var iteration = 0;
-
       if (offset > 0) {
         while (iteration < roundOffset) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           iteration += 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
           iteration += offsetModulo;
@@ -6368,19 +5363,16 @@
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
           iteration -= 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
           iteration -= offsetModulo;
         }
       }
-
       i = this.data.m === 1 ? 0 : this._currentCopies - 1;
       dir = this.data.m === 1 ? 1 : -1;
       cont = this._currentCopies;
       var j;
       var jLen;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6388,29 +5380,23 @@
         items[items.length - 1].transform.mProps._mdf = true;
         items[items.length - 1].transform.op._mdf = true;
         items[items.length - 1].transform.op.v = this._currentCopies === 1 ? this.so.v : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
-
         if (iteration !== 0) {
           if (i !== 0 && dir === 1 || i !== this._currentCopies - 1 && dir === -1) {
             this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           }
-
           this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
           this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
           this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
-
           this.matrix.reset();
         } else {
           this.matrix.reset();
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
         }
-
         iteration += 1;
         cont -= 1;
         i += dir;
@@ -6419,7 +5405,6 @@
       cont = this._currentCopies;
       i = 0;
       dir = 1;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6429,22 +5414,17 @@
         i += dir;
       }
     }
-
     return hasReloaded;
   };
-
   RepeaterModifier.prototype.addShape = function () {};
 
   function RoundCornersModifier() {}
-
   extendPrototype([ShapeModifier], RoundCornersModifier);
-
   RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
     this._isAnimated = !!this.rd.effectsSequence.length;
   };
-
   RoundCornersModifier.prototype.processPath = function (path, round) {
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
@@ -6463,19 +5443,16 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < len; i += 1) {
       currentV = path.v[i];
       currentO = path.o[i];
       currentI = path.i[i];
-
       if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
         if ((i === 0 || i === len - 1) && !path.c) {
           clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
           /* clonedPath.v[index] = currentV;
                   clonedPath.o[index] = currentO;
                   clonedPath.i[index] = currentI; */
-
           index += 1;
         } else {
           if (i === 0) {
@@ -6483,7 +5460,6 @@
           } else {
             closerV = path.v[i - 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6494,13 +5470,11 @@
           oY = vY - (vY - currentV[1]) * roundCorner;
           clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
           index += 1;
-
           if (i === len - 1) {
             closerV = path.v[0];
           } else {
             closerV = path.v[i + 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6517,10 +5491,8 @@
         index += 1;
       }
     }
-
     return clonedPath;
   };
-
   RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6528,30 +5500,24 @@
     var j;
     var jLen;
     var rd = this.rd.v;
-
     if (rd !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6560,50 +5526,41 @@
   function floatEqual(a, b) {
     return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
   }
-
   function floatZero(f) {
     return Math.abs(f) <= 0.00001;
   }
-
   function lerp(p0, p1, amount) {
     return p0 * (1 - amount) + p1 * amount;
   }
-
   function lerpPoint(p0, p1, amount) {
     return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
   }
-
   function quadRoots(a, b, c) {
     // no root
     if (a === 0) return [];
-    var s = b * b - 4 * a * c; // Complex roots
-
+    var s = b * b - 4 * a * c;
+    // Complex roots
     if (s < 0) return [];
-    var singleRoot = -b / (2 * a); // 1 root
-
+    var singleRoot = -b / (2 * a);
+    // 1 root
     if (s === 0) return [singleRoot];
-    var delta = Math.sqrt(s) / (2 * a); // 2 roots
-
+    var delta = Math.sqrt(s) / (2 * a);
+    // 2 roots
     return [singleRoot - delta, singleRoot + delta];
   }
-
   function polynomialCoefficients(p0, p1, p2, p3) {
     return [-p0 + 3 * p1 - 3 * p2 + p3, 3 * p0 - 6 * p1 + 3 * p2, -3 * p0 + 3 * p1, p0];
   }
-
   function singlePoint(p) {
     return new PolynomialBezier(p, p, p, p, false);
   }
-
   function PolynomialBezier(p0, p1, p2, p3, linearize) {
     if (linearize && pointEqual(p0, p1)) {
       p1 = lerpPoint(p0, p3, 1 / 3);
     }
-
     if (linearize && pointEqual(p2, p3)) {
       p2 = lerpPoint(p0, p3, 2 / 3);
     }
-
     var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
     var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
     this.a = [coeffx[0], coeffy[0]];
@@ -6612,25 +5569,20 @@
     this.d = [coeffx[3], coeffy[3]];
     this.points = [p0, p1, p2, p3];
   }
-
   PolynomialBezier.prototype.point = function (t) {
     return [((this.a[0] * t + this.b[0]) * t + this.c[0]) * t + this.d[0], ((this.a[1] * t + this.b[1]) * t + this.c[1]) * t + this.d[1]];
   };
-
   PolynomialBezier.prototype.derivative = function (t) {
     return [(3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0], (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1]];
   };
-
   PolynomialBezier.prototype.tangentAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[1], p[0]);
   };
-
   PolynomialBezier.prototype.normalAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[0], p[1]);
   };
-
   PolynomialBezier.prototype.inflectionPoints = function () {
     var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
     if (floatZero(denom)) return [];
@@ -6638,17 +5590,14 @@
     var square = tcusp * tcusp - 1 / 3 * (this.b[1] * this.c[0] - this.b[0] * this.c[1]) / denom;
     if (square < 0) return [];
     var root = Math.sqrt(square);
-
     if (floatZero(root)) {
       if (root > 0 && root < 1) return [tcusp];
       return [];
     }
-
     return [tcusp - root, tcusp + root].filter(function (r) {
       return r > 0 && r < 1;
     });
   };
-
   PolynomialBezier.prototype.split = function (t) {
     if (t <= 0) return [singlePoint(this.points[0]), this];
     if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
@@ -6660,40 +5609,33 @@
     var p3 = lerpPoint(p20, p21, t);
     return [new PolynomialBezier(this.points[0], p10, p20, p3, true), new PolynomialBezier(p3, p21, p12, this.points[3], true)];
   };
-
   function extrema(bez, comp) {
     var min = bez.points[0][comp];
     var max = bez.points[bez.points.length - 1][comp];
-
     if (min > max) {
       var e = max;
       max = min;
       min = e;
-    } // Derivative roots to find min/max
-
-
+    }
+    // Derivative roots to find min/max
     var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
-
     for (var i = 0; i < f.length; i += 1) {
       if (f[i] > 0 && f[i] < 1) {
         var val = bez.point(f[i])[comp];
         if (val < min) min = val;else if (val > max) max = val;
       }
     }
-
     return {
       min: min,
       max: max
     };
   }
-
   PolynomialBezier.prototype.bounds = function () {
     return {
       x: extrema(this, 0),
       y: extrema(this, 1)
     };
   };
-
   PolynomialBezier.prototype.boundingBox = function () {
     var bounds = this.bounds();
     return {
@@ -6707,7 +5649,6 @@
       cy: (bounds.y.max + bounds.y.min) / 2
     };
   };
-
   function intersectData(bez, t1, t2) {
     var box = bez.boundingBox();
     return {
@@ -6721,24 +5662,19 @@
       t2: t2
     };
   }
-
   function splitData(data) {
     var split = data.bez.split(0.5);
     return [intersectData(split[0], data.t1, data.t), intersectData(split[1], data.t, data.t2)];
   }
-
   function boxIntersect(b1, b2) {
     return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
   }
-
   function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
     if (!boxIntersect(d1, d2)) return;
-
     if (depth >= maxRecursion || d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance) {
       intersections.push([d1.t, d2.t]);
       return;
     }
-
     var d1s = splitData(d1);
     var d2s = splitData(d2);
     intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
@@ -6746,7 +5682,6 @@
     intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
     intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
   }
-
   PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
     if (tolerance === undefined) tolerance = 2;
     if (maxRecursion === undefined) maxRecursion = 7;
@@ -6754,21 +5689,17 @@
     intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
     return intersections;
   };
-
   PolynomialBezier.shapeSegment = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
   };
-
   PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
   };
-
   function crossProduct(a, b) {
     return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
   }
-
   function lineIntersection(start1, end1, start2, end2) {
     var v1 = [start1[0], start1[1], 1];
     var v2 = [end1[0], end1[1], 1];
@@ -6778,23 +5709,18 @@
     if (floatZero(r[2])) return null;
     return [r[0] / r[2], r[1] / r[2]];
   }
-
   function polarOffset(p, angle, length) {
     return [p[0] + Math.cos(angle) * length, p[1] - Math.sin(angle) * length];
   }
-
   function pointDistance(p1, p2) {
     return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
   }
-
   function pointEqual(p1, p2) {
     return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
   }
 
   function ZigZagModifier() {}
-
   extendPrototype([ShapeModifier], ZigZagModifier);
-
   ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
@@ -6802,7 +5728,6 @@
     this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
     this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
   };
-
   function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
     var angO = angle - Math.PI / 2;
     var angI = angle + Math.PI / 2;
@@ -6810,14 +5735,12 @@
     var py = point[1] - Math.sin(angle) * direction * amplitude;
     outputBezier.setTripleAt(px, py, px + Math.cos(angO) * outAmplitude, py - Math.sin(angO) * outAmplitude, px + Math.cos(angI) * inAmplitude, py - Math.sin(angI) * inAmplitude, outputBezier.length());
   }
-
   function getPerpendicularVector(pt1, pt2) {
     var vector = [pt2[0] - pt1[0], pt2[1] - pt1[1]];
     var rot = -Math.PI * 0.5;
     var rotatedVector = [Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1], Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1]];
     return rotatedVector;
   }
-
   function getProjectingAngle(path, cur) {
     var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
     var nextIndex = (cur + 1) % path.length();
@@ -6826,7 +5749,6 @@
     var pVector = getPerpendicularVector(prevPoint, nextPoint);
     return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
   }
-
   function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
     var angle = getProjectingAngle(path, cur);
     var point = path.v[cur % path._length];
@@ -6836,7 +5758,6 @@
     var nextDist = pointType === 2 ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2)) : 0;
     setPoint(outputBezier, path.v[cur % path._length], angle, direction, amplitude, nextDist / ((frequency + 1) * 2), prevDist / ((frequency + 1) * 2), pointType);
   }
-
   function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
     for (var i = 0; i < frequency; i += 1) {
       var t = (i + 1) / (frequency + 1);
@@ -6846,39 +5767,30 @@
       setPoint(outputBezier, point, angle, direction, amplitude, dist / ((frequency + 1) * 2), dist / ((frequency + 1) * 2), pointType);
       direction = -direction;
     }
-
     return direction;
   }
-
   ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
     var count = path._length;
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
-
     if (!path.c) {
       count -= 1;
     }
-
     if (count === 0) return clonedPath;
     var direction = -1;
     var segment = PolynomialBezier.shapeSegment(path, 0);
     zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
-
     for (var i = 0; i < count; i += 1) {
       direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
-
       if (i === count - 1 && !path.c) {
         segment = null;
       } else {
         segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
       }
-
       zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
     }
-
     return clonedPath;
   };
-
   ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6888,30 +5800,24 @@
     var amplitude = this.amplitude.v;
     var frequency = Math.max(0, Math.round(this.frequency.v));
     var pointType = this.pointsType.v;
-
     if (amplitude !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6921,7 +5827,6 @@
     var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
     return [polarOffset(p1, angle, amount), polarOffset(p2, angle, amount)];
   }
-
   function offsetSegment(segment, amount) {
     var p0;
     var p1a;
@@ -6945,15 +5850,17 @@
     if (p2 === null) p2 = p2a;
     return new PolynomialBezier(p0, p1, p2, p3);
   }
-
   function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
     var p0 = seg1.points[3];
-    var p1 = seg2.points[0]; // Bevel
+    var p1 = seg2.points[0];
 
-    if (lineJoin === 3) return p0; // Connected, they don't need a joint
+    // Bevel
+    if (lineJoin === 3) return p0;
 
-    if (pointEqual(p0, p1)) return p0; // Round
+    // Connected, they don't need a joint
+    if (pointEqual(p0, p1)) return p0;
 
+    // Round
     if (lineJoin === 2) {
       var angleOut = -seg1.tangentAngle(1);
       var angleIn = -seg2.tangentAngle(0) + Math.PI;
@@ -6964,91 +5871,75 @@
       tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
       outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
       return p1;
-    } // Miter
+    }
 
-
+    // Miter
     var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
     var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
     var intersection = lineIntersection(t0, p0, p1, t1);
-
     if (intersection && pointDistance(intersection, p0) < miterLimit) {
       outputBezier.setTripleAt(intersection[0], intersection[1], intersection[0], intersection[1], intersection[0], intersection[1], outputBezier.length());
       return intersection;
     }
-
     return p0;
   }
-
   function getIntersection(a, b) {
     var intersect = a.intersections(b);
     if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
     if (intersect.length) return intersect[0];
     return null;
   }
-
   function pruneSegmentIntersection(a, b) {
     var outa = a.slice();
     var outb = b.slice();
     var intersect = getIntersection(a[a.length - 1], b[0]);
-
     if (intersect) {
       outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
       outb[0] = b[0].split(intersect[1])[1];
     }
-
     if (a.length > 1 && b.length > 1) {
       intersect = getIntersection(a[0], b[b.length - 1]);
-
       if (intersect) {
         return [[a[0].split(intersect[0])[0]], [b[b.length - 1].split(intersect[1])[1]]];
       }
     }
-
     return [outa, outb];
   }
-
   function pruneIntersections(segments) {
     var e;
-
     for (var i = 1; i < segments.length; i += 1) {
       e = pruneSegmentIntersection(segments[i - 1], segments[i]);
       segments[i - 1] = e[0];
       segments[i] = e[1];
     }
-
     if (segments.length > 1) {
       e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
       segments[segments.length - 1] = e[0];
       segments[0] = e[1];
     }
-
     return segments;
   }
-
   function offsetSegmentSplit(segment, amount) {
     /*
       We split each bezier segment into smaller pieces based
       on inflection points, this ensures the control point
       polygon is convex.
-        (A cubic bezier can have none, one, or two inflection points)
+       (A cubic bezier can have none, one, or two inflection points)
     */
     var flex = segment.inflectionPoints();
     var left;
     var right;
     var split;
     var mid;
-
     if (flex.length === 0) {
       return [offsetSegment(segment, amount)];
     }
-
     if (flex.length === 1 || floatEqual(flex[1], 1)) {
       split = segment.split(flex[0]);
       left = split[0];
       right = split[1];
       return [offsetSegment(left, amount), offsetSegment(right, amount)];
     }
-
     split = segment.split(flex[0]);
     left = split[0];
     var t = (flex[1] - flex[0]) / (1 - flex[0]);
@@ -7057,11 +5948,8 @@
     right = split[1];
     return [offsetSegment(left, amount), offsetSegment(mid, amount), offsetSegment(right, amount)];
   }
-
   function OffsetPathModifier() {}
-
   extendPrototype([ShapeModifier], OffsetPathModifier);
-
   OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
@@ -7069,61 +5957,50 @@
     this.lineJoin = data.lj;
     this._isAnimated = this.amount.effectsSequence.length !== 0;
   };
-
   OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
     var outputBezier = shapePool.newElement();
     outputBezier.c = inputBezier.c;
     var count = inputBezier.length();
-
     if (!inputBezier.c) {
       count -= 1;
     }
-
     var i;
     var j;
     var segment;
     var multiSegments = [];
-
     for (i = 0; i < count; i += 1) {
       segment = PolynomialBezier.shapeSegment(inputBezier, i);
       multiSegments.push(offsetSegmentSplit(segment, amount));
     }
-
     if (!inputBezier.c) {
       for (i = count - 1; i >= 0; i -= 1) {
         segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
         multiSegments.push(offsetSegmentSplit(segment, amount));
       }
     }
+    multiSegments = pruneIntersections(multiSegments);
 
-    multiSegments = pruneIntersections(multiSegments); // Add bezier segments to the output and apply line joints
-
+    // Add bezier segments to the output and apply line joints
     var lastPoint = null;
     var lastSeg = null;
-
     for (i = 0; i < multiSegments.length; i += 1) {
       var multiSegment = multiSegments[i];
       if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
       lastSeg = multiSegment[multiSegment.length - 1];
-
       for (j = 0; j < multiSegment.length; j += 1) {
         segment = multiSegment[j];
-
         if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
           outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
         } else {
           outputBezier.setTripleAt(segment.points[0][0], segment.points[0][1], segment.points[1][0], segment.points[1][1], segment.points[0][0], segment.points[0][1], outputBezier.length());
         }
-
         outputBezier.setTripleAt(segment.points[3][0], segment.points[3][1], segment.points[3][0], segment.points[3][1], segment.points[2][0], segment.points[2][1], outputBezier.length());
         lastPoint = segment.points[3];
       }
     }
-
     if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
     return outputBezier;
   };
-
   OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -7133,30 +6010,24 @@
     var amount = this.amount.v;
     var miterLimit = this.miterLimit.v;
     var lineJoin = this.lineJoin;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -7168,42 +6039,33 @@
     var fStyle = 'normal';
     var len = styles.length;
     var styleName;
-
     for (var i = 0; i < len; i += 1) {
       styleName = styles[i].toLowerCase();
-
       switch (styleName) {
         case 'italic':
           fStyle = 'italic';
           break;
-
         case 'bold':
           fWeight = '700';
           break;
-
         case 'black':
           fWeight = '900';
           break;
-
         case 'medium':
           fWeight = '500';
           break;
-
         case 'regular':
         case 'normal':
           fWeight = '400';
           break;
-
         case 'light':
         case 'thin':
           fWeight = '200';
           break;
-
         default:
           break;
       }
     }
-
     return {
       style: fStyle,
       weight: fontData.fWeight || fWeight
@@ -7220,8 +6082,8 @@
         shapes: []
       }
     };
-    var combinedCharacters = []; // Hindi characters
-
+    var combinedCharacters = [];
+    // Hindi characters
     combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
     var BLACK_FLAG_CODE_POINT = 127988;
     var CANCEL_TAG_CODE_POINT = 917631;
@@ -7232,44 +6094,41 @@
     var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
     var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
     var surrogateModifiers = ['d83cdffb', 'd83cdffc', 'd83cdffd', 'd83cdffe', 'd83cdfff'];
-
     function trimFontOptions(font) {
       var familyArray = font.split(',');
       var i;
       var len = familyArray.length;
       var enabledFamilies = [];
-
       for (i = 0; i < len; i += 1) {
         if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
           enabledFamilies.push(familyArray[i]);
         }
       }
-
       return enabledFamilies.join(',');
     }
-
     function setUpNode(font, family) {
-      var parentNode = createTag('span'); // Node is invisible to screen readers.
-
+      var parentNode = createTag('span');
+      // Node is invisible to screen readers.
       parentNode.setAttribute('aria-hidden', true);
       parentNode.style.fontFamily = family;
-      var node = createTag('span'); // Characters that vary significantly among different fonts
-
-      node.innerText = 'giItT1WQy@!-/#'; // Visible - so we can measure it - but not on the screen
-
+      var node = createTag('span');
+      // Characters that vary significantly among different fonts
+      node.innerText = 'giItT1WQy@!-/#';
+      // Visible - so we can measure it - but not on the screen
       parentNode.style.position = 'absolute';
       parentNode.style.left = '-10000px';
-      parentNode.style.top = '-10000px'; // Large font size makes even subtle changes obvious
-
-      parentNode.style.fontSize = '300px'; // Reset any font properties
-
+      parentNode.style.top = '-10000px';
+      // Large font size makes even subtle changes obvious
+      parentNode.style.fontSize = '300px';
+      // Reset any font properties
       parentNode.style.fontVariant = 'normal';
       parentNode.style.fontStyle = 'normal';
       parentNode.style.fontWeight = 'normal';
       parentNode.style.letterSpacing = '0';
       parentNode.appendChild(node);
-      document.body.appendChild(parentNode); // Remember width with no applied web font
+      document.body.appendChild(parentNode);
 
+      // Remember width with no applied web font
       var width = node.offsetWidth;
       node.style.fontFamily = trimFontOptions(font) + ', ' + family;
       return {
@@ -7278,14 +6137,12 @@
         parent: parentNode
       };
     }
-
     function checkLoadedFonts() {
       var i;
       var len = this.fonts.length;
       var node;
       var w;
       var loadedCount = len;
-
       for (i = 0; i < len; i += 1) {
         if (this.fonts[i].loaded) {
           loadedCount -= 1;
@@ -7294,55 +6151,47 @@
         } else {
           node = this.fonts[i].monoCase.node;
           w = this.fonts[i].monoCase.w;
-
           if (node.offsetWidth !== w) {
             loadedCount -= 1;
             this.fonts[i].loaded = true;
           } else {
             node = this.fonts[i].sansCase.node;
             w = this.fonts[i].sansCase.w;
-
             if (node.offsetWidth !== w) {
               loadedCount -= 1;
               this.fonts[i].loaded = true;
             }
           }
-
           if (this.fonts[i].loaded) {
             this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
             this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
           }
         }
       }
-
       if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
         setTimeout(this.checkLoadedFontsBinded, 20);
       } else {
         setTimeout(this.setIsLoadedBinded, 10);
       }
     }
-
     function createHelper(fontData, def) {
       var engine = document.body && def ? 'svg' : 'canvas';
       var helper;
       var fontProps = getFontProperties(fontData);
-
       if (engine === 'svg') {
         var tHelper = createNS('text');
-        tHelper.style.fontSize = '100px'; // tHelper.style.fontFamily = fontData.fFamily;
-
+        tHelper.style.fontSize = '100px';
+        // tHelper.style.fontFamily = fontData.fFamily;
         tHelper.setAttribute('font-family', fontData.fFamily);
         tHelper.setAttribute('font-style', fontProps.style);
         tHelper.setAttribute('font-weight', fontProps.weight);
         tHelper.textContent = '1';
-
         if (fontData.fClass) {
           tHelper.style.fontFamily = 'inherit';
           tHelper.setAttribute('class', fontData.fClass);
         } else {
           tHelper.style.fontFamily = fontData.fFamily;
         }
-
         def.appendChild(tHelper);
         helper = tHelper;
       } else {
@@ -7350,33 +6199,27 @@
         tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
         helper = tCanvasHelper;
       }
-
       function measure(text) {
         if (engine === 'svg') {
           helper.textContent = text;
           return helper.getComputedTextLength();
         }
-
         return helper.measureText(text).width;
       }
-
       return {
         measureText: measure
       };
     }
-
     function addFonts(fontData, defs) {
       if (!fontData) {
         this.isLoaded = true;
         return;
       }
-
       if (this.chars) {
         this.isLoaded = true;
         this.fonts = fontData.list;
         return;
       }
-
       if (!document.body) {
         this.isLoaded = true;
         fontData.list.forEach(function (data) {
@@ -7386,12 +6229,10 @@
         this.fonts = fontData.list;
         return;
       }
-
       var fontArr = fontData.list;
       var i;
       var len = fontArr.length;
       var _pendingFonts = len;
-
       for (i = 0; i < len; i += 1) {
         var shouldLoadFont = true;
         var loadedSelector;
@@ -7399,17 +6240,14 @@
         fontArr[i].loaded = false;
         fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
         fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
-
         if (!fontArr[i].fPath) {
           fontArr[i].loaded = true;
           _pendingFonts -= 1;
         } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
           loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
-
           if (loadedSelector.length > 0) {
             shouldLoadFont = false;
           }
-
           if (shouldLoadFont) {
             var s = createTag('style');
             s.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7421,14 +6259,12 @@
           }
         } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
           loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var l = createTag('link');
             l.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7440,14 +6276,12 @@
           }
         } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
           loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (fontArr[i].fPath === loadedSelector[j].src) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var sc = createTag('link');
             sc.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7457,12 +6291,10 @@
             defs.appendChild(sc);
           }
         }
-
         fontArr[i].helper = createHelper(fontArr[i], defs);
         fontArr[i].cache = {};
         this.fonts.push(fontArr[i]);
       }
-
       if (_pendingFonts === 0) {
         this.isLoaded = true;
       } else {
@@ -7471,71 +6303,56 @@
         setTimeout(this.checkLoadedFonts.bind(this), 100);
       }
     }
-
     function addChars(chars) {
       if (!chars) {
         return;
       }
-
       if (!this.chars) {
         this.chars = [];
       }
-
       var i;
       var len = chars.length;
       var j;
       var jLen = this.chars.length;
       var found;
-
       for (i = 0; i < len; i += 1) {
         j = 0;
         found = false;
-
         while (j < jLen) {
           if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
             found = true;
           }
-
           j += 1;
         }
-
         if (!found) {
           this.chars.push(chars[i]);
           jLen += 1;
         }
       }
     }
-
     function getCharData(_char, style, font) {
       var i = 0;
       var len = this.chars.length;
-
       while (i < len) {
         if (this.chars[i].ch === _char && this.chars[i].style === style && this.chars[i].fFamily === font) {
           return this.chars[i];
         }
-
         i += 1;
       }
-
       if ((typeof _char === 'string' && _char.charCodeAt(0) !== 13 || !_char) && console && console.warn // eslint-disable-line no-console
       && !this._warned) {
         this._warned = true;
         console.warn('Missing character from exported characters list: ', _char, style, font); // eslint-disable-line no-console
       }
-
       return emptyChar;
     }
-
     function measureText(_char2, fontName, size) {
-      var fontData = this.getFontByName(fontName); // Using the char instead of char.charCodeAt(0)
+      var fontData = this.getFontByName(fontName);
+      // Using the char instead of char.charCodeAt(0)
       // to avoid collisions between equal chars
-
       var index = _char2;
-
       if (!fontData.cache[index]) {
         var tHelper = fontData.helper;
-
         if (_char2 === ' ') {
           var doubleSize = tHelper.measureText('|' + _char2 + '|');
           var singleSize = tHelper.measureText('||');
@@ -7544,111 +6361,90 @@
           fontData.cache[index] = tHelper.measureText(_char2) / 100;
         }
       }
-
       return fontData.cache[index] * size;
     }
-
     function getFontByName(name) {
       var i = 0;
       var len = this.fonts.length;
-
       while (i < len) {
         if (this.fonts[i].fName === name) {
           return this.fonts[i];
         }
-
         i += 1;
       }
-
       return this.fonts[0];
     }
-
     function getCodePoint(string) {
       var codePoint = 0;
       var first = string.charCodeAt(0);
-
       if (first >= 0xD800 && first <= 0xDBFF) {
         var second = string.charCodeAt(1);
-
         if (second >= 0xDC00 && second <= 0xDFFF) {
           codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
         }
       }
-
       return codePoint;
-    } // Skin tone modifiers
+    }
 
-
+    // Skin tone modifiers
     function isModifier(firstCharCode, secondCharCode) {
       var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
       return surrogateModifiers.indexOf(sum) !== -1;
     }
-
     function isZeroWidthJoiner(charCode) {
       return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
-    } // This codepoint may change the appearance of the preceding character.
+    }
+
+    // This codepoint may change the appearance of the preceding character.
     // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
     // as a colorful image as compared to a monochrome text variant.
-
-
     function isVariationSelector(charCode) {
       return charCode === VARIATION_SELECTOR_16_CODE_POINT;
-    } // The regional indicator symbols are a set of 26 alphabetic Unicode
+    }
+
+    // The regional indicator symbols are a set of 26 alphabetic Unicode
     /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
     // two-letter country codes in a way that allows optional special treatment.
-
-
     function isRegionalCode(string) {
       var codePoint = getCodePoint(string);
-
       if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
         return true;
       }
-
       return false;
-    } // Some Emoji implementations represent combinations of
+    }
+
+    // Some Emoji implementations represent combinations of
     // two “regional indicator” letters as a single flag symbol.
-
-
     function isFlagEmoji(string) {
       return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
     }
-
     function isCombinedCharacter(_char3) {
       return combinedCharacters.indexOf(_char3) !== -1;
-    } // Regional flags start with a BLACK_FLAG_CODE_POINT
+    }
+
+    // Regional flags start with a BLACK_FLAG_CODE_POINT
     // folowed by 5 chars in the TAG range
     // and end with a CANCEL_TAG_CODE_POINT
-
-
     function isRegionalFlag(text, index) {
       var codePoint = getCodePoint(text.substr(index, 2));
-
       if (codePoint !== BLACK_FLAG_CODE_POINT) {
         return false;
       }
-
       var count = 0;
       index += 2;
-
       while (count < 5) {
         codePoint = getCodePoint(text.substr(index, 2));
-
         if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
           return false;
         }
-
         count += 1;
         index += 2;
       }
-
       return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
     }
-
     function setIsLoaded() {
       this.isLoaded = true;
     }
-
     var Font = function Font() {
       this.fonts = [];
       this.chars = null;
@@ -7659,7 +6455,6 @@
       this.setIsLoadedBinded = this.setIsLoaded.bind(this);
       this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
     };
-
     Font.isModifier = isModifier;
     Font.isZeroWidthJoiner = isZeroWidthJoiner;
     Font.isFlagEmoji = isFlagEmoji;
@@ -7684,30 +6479,26 @@
   function SlotManager(animationData) {
     this.animationData = animationData;
   }
-
   SlotManager.prototype.getProp = function (data) {
     if (this.animationData.slots && this.animationData.slots[data.sid]) {
       return Object.assign(data, this.animationData.slots[data.sid].p);
     }
-
     return data;
   };
-
   function slotFactory(animationData) {
     return new SlotManager(animationData);
   }
 
   function RenderableElement() {}
-
   RenderableElement.prototype = {
     initRenderable: function initRenderable() {
       // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
-      this.isInRange = false; // layer's display state
-
-      this.hidden = false; // If layer's transparency equals 0, it can be hidden
-
-      this.isTransparent = false; // list of animated components
-
+      this.isInRange = false;
+      // layer's display state
+      this.hidden = false;
+      // If layer's transparency equals 0, it can be hidden
+      this.isTransparent = false;
+      // list of animated components
       this.renderableComponents = [];
     },
     addRenderableComponent: function addRenderableComponent(component) {
@@ -7734,7 +6525,6 @@
         this.show();
       }
     },
-
     /**
        * @function
        * Initializes frame related properties.
@@ -7760,13 +6550,11 @@
     renderRenderable: function renderRenderable() {
       var i;
       var len = this.renderableComponents.length;
-
       for (i = 0; i < len; i += 1) {
         this.renderableComponents[i].renderFrame(this._isFirstFrame);
       }
       /* this.maskManager.renderFrame(this.finalTransform.mat);
           this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
-
     },
     sourceRectAtTime: function sourceRectAtTime() {
       return {
@@ -7783,7 +6571,6 @@
           h: this.data.textData.height
         };
       }
-
       return {
         w: this.data.width,
         h: this.data.height
@@ -7818,31 +6605,24 @@
   function SliderEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function AngleEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function ColorEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function PointEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function LayerIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function MaskIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function CheckboxEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function NoValueEffect() {
     this.p = {};
   }
@@ -7853,20 +6633,16 @@
     var i;
     var len = effects.length;
     var effectItem;
-
     for (i = 0; i < len; i += 1) {
       effectItem = new GroupEffect(effects[i], element);
       this.effectElements.push(effectItem);
     }
   }
-
   function GroupEffect(data, element) {
     this.init(data, element);
   }
-
   extendPrototype([DynamicPropertyContainer], GroupEffect);
   GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
-
   GroupEffect.prototype.init = function (data, element) {
     this.data = data;
     this.effectElements = [];
@@ -7875,50 +6651,39 @@
     var len = this.data.ef.length;
     var eff;
     var effects = this.data.ef;
-
     for (i = 0; i < len; i += 1) {
       eff = null;
-
       switch (effects[i].ty) {
         case 0:
           eff = new SliderEffect(effects[i], element, this);
           break;
-
         case 1:
           eff = new AngleEffect(effects[i], element, this);
           break;
-
         case 2:
           eff = new ColorEffect(effects[i], element, this);
           break;
-
         case 3:
           eff = new PointEffect(effects[i], element, this);
           break;
-
         case 4:
         case 7:
           eff = new CheckboxEffect(effects[i], element, this);
           break;
-
         case 10:
           eff = new LayerIndexEffect(effects[i], element, this);
           break;
-
         case 11:
           eff = new MaskIndexEffect(effects[i], element, this);
           break;
-
         case 5:
           eff = new EffectsManager(effects[i], element, this);
           break;
         // case 6:
-
         default:
           eff = new NoValueEffect(effects[i], element, this);
           break;
       }
-
       if (eff) {
         this.effectElements.push(eff);
       }
@@ -7926,47 +6691,37 @@
   };
 
   function BaseElement() {}
-
   BaseElement.prototype = {
     checkMasks: function checkMasks() {
       if (!this.data.hasMask) {
         return false;
       }
-
       var i = 0;
       var len = this.data.masksProperties.length;
-
       while (i < len) {
         if (this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false) {
           return true;
         }
-
         i += 1;
       }
-
       return false;
     },
     initExpressions: function initExpressions() {
       var expressionsInterfaces = getExpressionInterfaces();
-
       if (!expressionsInterfaces) {
         return;
       }
-
       var LayerExpressionInterface = expressionsInterfaces('layer');
       var EffectsExpressionInterface = expressionsInterfaces('effects');
       var ShapeExpressionInterface = expressionsInterfaces('shape');
       var TextExpressionInterface = expressionsInterfaces('text');
       var CompExpressionInterface = expressionsInterfaces('comp');
       this.layerInterface = LayerExpressionInterface(this);
-
       if (this.data.hasMask && this.maskManager) {
         this.layerInterface.registerMaskInterface(this.maskManager);
       }
-
       var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
       this.layerInterface.registerEffectsInterface(effectsInterface);
-
       if (this.data.ty === 0 || this.data.xt) {
         this.compInterface = CompExpressionInterface(this);
       } else if (this.data.ty === 4) {
@@ -7986,13 +6741,13 @@
       this.globalData = globalData;
       this.comp = comp;
       this.data = data;
-      this.layerId = createElementID(); // Stretch factor for old animations missing this property.
+      this.layerId = createElementID();
 
+      // Stretch factor for old animations missing this property.
       if (!this.data.sr) {
         this.data.sr = 1;
-      } // effects manager
-
-
+      }
+      // effects manager
       this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
     },
     getType: function getType() {
@@ -8007,8 +6762,8 @@
    * Checks layer in point and out point
    *
    */
-  function FrameElement() {}
 
+  function FrameElement() {}
   FrameElement.prototype = {
     /**
        * @function
@@ -8017,13 +6772,12 @@
        */
     initFrame: function initFrame() {
       // set to true when inpoint is rendered
-      this._isFirstFrame = false; // list of animated properties
-
-      this.dynamicProperties = []; // If layer has been modified in current tick this will be true
-
+      this._isFirstFrame = false;
+      // list of animated properties
+      this.dynamicProperties = [];
+      // If layer has been modified in current tick this will be true
       this._mdf = false;
     },
-
     /**
        * @function
        * Calculates all dynamic values
@@ -8037,11 +6791,9 @@
     prepareProperties: function prepareProperties(num, isVisible) {
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         if (isVisible || this._isParent && this.dynamicProperties[i].propType === 'transform') {
           this.dynamicProperties[i].getValue();
-
           if (this.dynamicProperties[i]._mdf) {
             this.globalData._mdf = true;
             this._mdf = true;
@@ -8063,30 +6815,21 @@
     this.footageData = globalData.imageLoader.getAsset(this.assetData);
     this.initBaseData(data, globalData, comp);
   }
-
   FootageElement.prototype.prepareFrame = function () {};
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
-
   FootageElement.prototype.getBaseElement = function () {
     return null;
   };
-
   FootageElement.prototype.renderFrame = function () {};
-
   FootageElement.prototype.destroy = function () {};
-
   FootageElement.prototype.initExpressions = function () {
     var expressionsInterfaces = getExpressionInterfaces();
-
     if (!expressionsInterfaces) {
       return;
     }
-
     var FootageInterface = expressionsInterfaces('footage');
     this.layerInterface = FootageInterface(this);
   };
-
   FootageElement.prototype.getFootageData = function () {
     return this.footageData;
   };
@@ -8112,29 +6855,23 @@
       k: [100]
     }, 1, 0.01, this);
   }
-
   AudioElement.prototype.prepareFrame = function (num) {
     this.prepareRenderableFrame(num, true);
     this.prepareProperties(num, true);
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
       this._currentTime = timeRemapped;
     } else {
       this._currentTime = num / this.data.sr;
     }
-
     this._volume = this.lv.v[0];
     var totalVolume = this._volume * this._volumeMultiplier;
-
     if (this._previousVolume !== totalVolume) {
       this._previousVolume = totalVolume;
       this.audio.volume(totalVolume);
     }
   };
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
-
   AudioElement.prototype.renderFrame = function () {
     if (this.isInRange && this._canPlay) {
       if (!this._isPlaying) {
@@ -8146,162 +6883,124 @@
       }
     }
   };
-
-  AudioElement.prototype.show = function () {// this.audio.play()
+  AudioElement.prototype.show = function () {
+    // this.audio.play()
   };
-
   AudioElement.prototype.hide = function () {
     this.audio.pause();
     this._isPlaying = false;
   };
-
   AudioElement.prototype.pause = function () {
     this.audio.pause();
     this._isPlaying = false;
     this._canPlay = false;
   };
-
   AudioElement.prototype.resume = function () {
     this._canPlay = true;
   };
-
   AudioElement.prototype.setRate = function (rateValue) {
     this.audio.rate(rateValue);
   };
-
   AudioElement.prototype.volume = function (volumeValue) {
     this._volumeMultiplier = volumeValue;
     this._previousVolume = volumeValue * this._volume;
     this.audio.volume(this._previousVolume);
   };
-
   AudioElement.prototype.getBaseElement = function () {
     return null;
   };
-
   AudioElement.prototype.destroy = function () {};
-
   AudioElement.prototype.sourceRectAtTime = function () {};
-
   AudioElement.prototype.initExpressions = function () {};
 
   function BaseRenderer() {}
-
   BaseRenderer.prototype.checkLayers = function (num) {
     var i;
     var len = this.layers.length;
     var data;
     this.completeLayers = true;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (!this.elements[i]) {
         data = this.layers[i];
-
         if (data.ip - data.st <= num - this.layers[i].st && data.op - data.st > num - this.layers[i].st) {
           this.buildItem(i);
         }
       }
-
       this.completeLayers = this.elements[i] ? this.completeLayers : false;
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.createItem = function (layer) {
     switch (layer.ty) {
       case 2:
         return this.createImage(layer);
-
       case 0:
         return this.createComp(layer);
-
       case 1:
         return this.createSolid(layer);
-
       case 3:
         return this.createNull(layer);
-
       case 4:
         return this.createShape(layer);
-
       case 5:
         return this.createText(layer);
-
       case 6:
         return this.createAudio(layer);
-
       case 13:
         return this.createCamera(layer);
-
       case 15:
         return this.createFootage(layer);
-
       default:
         return this.createNull(layer);
     }
   };
-
   BaseRenderer.prototype.createCamera = function () {
     throw new Error('You\'re using a 3d camera. Try the html renderer.');
   };
-
   BaseRenderer.prototype.createAudio = function (data) {
     return new AudioElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.createFootage = function (data) {
     return new FootageElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.buildAllItems = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       this.buildItem(i);
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.includeLayers = function (newLayers) {
     this.completeLayers = false;
     var i;
     var len = newLayers.length;
     var j;
     var jLen = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       j = 0;
-
       while (j < jLen) {
         if (this.layers[j].id === newLayers[i].id) {
           this.layers[j] = newLayers[i];
           break;
         }
-
         j += 1;
       }
     }
   };
-
   BaseRenderer.prototype.setProjectInterface = function (pInterface) {
     this.globalData.projectInterface = pInterface;
   };
-
   BaseRenderer.prototype.initItems = function () {
     if (!this.globalData.progressiveLoad) {
       this.buildAllItems();
     }
   };
-
   BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
     var elements = this.elements;
     var layers = this.layers;
     var i = 0;
     var len = layers.length;
-
     while (i < len) {
       if (layers[i].ind == parentName) {
         // eslint-disable-line eqeqeq
@@ -8311,7 +7010,6 @@
         } else {
           hierarchy.push(elements[i]);
           elements[i].setAsParent();
-
           if (layers[i].parent !== undefined) {
             this.buildElementParenting(element, layers[i].parent, hierarchy);
           } else {
@@ -8319,19 +7017,15 @@
           }
         }
       }
-
       i += 1;
     }
   };
-
   BaseRenderer.prototype.addPendingElement = function (element) {
     this.pendingElements.push(element);
   };
-
   BaseRenderer.prototype.searchExtraCompositions = function (assets) {
     var i;
     var len = assets.length;
-
     for (i = 0; i < len; i += 1) {
       if (assets[i].xt) {
         var comp = this.createComp(assets[i]);
@@ -8340,30 +7034,24 @@
       }
     }
   };
-
   BaseRenderer.prototype.getElementById = function (ind) {
     var i;
     var len = this.elements.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i].data.ind === ind) {
         return this.elements[i];
       }
     }
-
     return null;
   };
-
   BaseRenderer.prototype.getElementByPath = function (path) {
     var pathValue = path.shift();
     var element;
-
     if (typeof pathValue === 'number') {
       element = this.elements[pathValue];
     } else {
       var i;
       var len = this.elements.length;
-
       for (i = 0; i < len; i += 1) {
         if (this.elements[i].data.nm === pathValue) {
           element = this.elements[i];
@@ -8371,14 +7059,11 @@
         }
       }
     }
-
     if (path.length === 0) {
       return element;
     }
-
     return element.getElementByPath(path);
   };
-
   BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
     this.globalData.fontManager = new FontManager();
     this.globalData.slotManager = slotFactory(animData);
@@ -8402,7 +7087,6 @@
   };
 
   function TransformElement() {}
-
   TransformElement.prototype = {
     initTransform: function initTransform() {
       var mat = new Matrix();
@@ -8417,50 +7101,44 @@
         localMat: mat,
         localOpacity: 1
       };
-
       if (this.data.ao) {
         this.finalTransform.mProp.autoOriented = true;
-      } // TODO: check TYPE 11: Guided elements
+      }
 
-
-      if (this.data.ty !== 11) {// this.createElements();
+      // TODO: check TYPE 11: Guided elements
+      if (this.data.ty !== 11) {
+        // this.createElements();
       }
     },
     renderTransform: function renderTransform() {
       this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
       this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
-
       if (this.hierarchy) {
         var mat;
         var finalMat = this.finalTransform.mat;
         var i = 0;
-        var len = this.hierarchy.length; // Checking if any of the transformation matrices in the hierarchy chain has changed.
-
+        var len = this.hierarchy.length;
+        // Checking if any of the transformation matrices in the hierarchy chain has changed.
         if (!this.finalTransform._matMdf) {
           while (i < len) {
             if (this.hierarchy[i].finalTransform.mProp._mdf) {
               this.finalTransform._matMdf = true;
               break;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._matMdf) {
           mat = this.finalTransform.mProp.v.props;
           finalMat.cloneFromProps(mat);
-
           for (i = 0; i < len; i += 1) {
             finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
           }
         }
       }
-
-      if (this.finalTransform._matMdf) {
+      if (!this.localTransforms || this.finalTransform._matMdf) {
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
       }
-
       if (this.finalTransform._opMdf) {
         this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
       }
@@ -8470,41 +7148,32 @@
         var i = 0;
         var len = this.localTransforms.length;
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
-
         if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
           while (i < len) {
             if (this.localTransforms[i]._mdf) {
               this.finalTransform._localMatMdf = true;
             }
-
             if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
               this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
               this.finalTransform._opMdf = true;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._localMatMdf) {
           var localMat = this.finalTransform.localMat;
           this.localTransforms[0].matrix.clone(localMat);
-
           for (i = 1; i < len; i += 1) {
             var lmat = this.localTransforms[i].matrix;
             localMat.multiply(lmat);
           }
-
           localMat.multiply(this.finalTransform.mat);
         }
-
         if (this.finalTransform._opMdf) {
           var localOp = this.finalTransform.localOpacity;
-
           for (i = 0; i < len; i += 1) {
             localOp *= this.localTransforms[i].opacity * 0.01;
           }
-
           this.finalTransform.localOpacity = localOp;
         }
       }
@@ -8512,13 +7181,11 @@
     searchEffectTransforms: function searchEffectTransforms() {
       if (this.renderableEffectsManager) {
         var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
-
         if (transformEffects.length) {
           this.localTransforms = [];
           this.finalTransform.localMat = new Matrix();
           var i = 0;
           var len = transformEffects.length;
-
           for (i = 0; i < len; i += 1) {
             this.localTransforms.push(transformEffects[i]);
           }
@@ -8530,29 +7197,24 @@
       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;
       var len = transforms.length;
       var 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]);
-
+        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;
     },
     mHelper: new Matrix()
@@ -8583,13 +7245,11 @@
     var x;
     var maskType = 'clipPath';
     var maskRef = 'clip-path';
-
     for (i = 0; i < len; i += 1) {
       if (properties[i].mode !== 'a' && properties[i].mode !== 'n' || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
         maskType = 'mask';
         maskRef = 'mask';
       }
-
       if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
         rect = createNS('rect');
         rect.setAttribute('fill', '#ffffff');
@@ -8599,9 +7259,7 @@
       } else {
         rect = null;
       }
-
       path = createNS('path');
-
       if (properties[i].mode === 'n') {
         // TODO move this to a factory or to a constructor
         this.viewData[i] = {
@@ -8616,7 +7274,6 @@
         path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
         path.setAttribute('clip-rule', 'nonzero');
         var filterID;
-
         if (properties[i].x.k !== 0) {
           maskType = 'mask';
           maskRef = 'mask';
@@ -8634,9 +7291,9 @@
         } else {
           feMorph = null;
           x = null;
-        } // TODO move this to a factory or to a constructor
+        }
 
-
+        // TODO move this to a factory or to a constructor
         this.storedData[i] = {
           elem: path,
           x: x,
@@ -8646,15 +7303,12 @@
           filterId: filterID,
           lastRadius: 0
         };
-
         if (properties[i].mode === 'i') {
           jLen = currentMasks.length;
           var g = createNS('g');
-
           for (j = 0; j < jLen; j += 1) {
             g.appendChild(currentMasks[j]);
           }
-
           var mask = createNS('mask');
           mask.setAttribute('mask-type', 'alpha');
           mask.setAttribute('id', layerId + '_' + count);
@@ -8666,12 +7320,10 @@
         } else {
           currentMasks.push(path);
         }
-
         if (properties[i].inv && !this.solidPath) {
           this.solidPath = this.createLayerSolidPath();
-        } // TODO move this to a factory or to a constructor
-
-
+        }
+        // TODO move this to a factory or to a constructor
         this.viewData[i] = {
           elem: path,
           lastPath: '',
@@ -8679,81 +7331,65 @@
           prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
           invRect: rect
         };
-
         if (!this.viewData[i].prop.k) {
           this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
         }
       }
     }
-
     this.maskElement = createNS(maskType);
     len = currentMasks.length;
-
     for (i = 0; i < len; i += 1) {
       this.maskElement.appendChild(currentMasks[i]);
     }
-
     if (count > 0) {
       this.maskElement.setAttribute('id', layerId);
       this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
       defs.appendChild(this.maskElement);
     }
-
     if (this.viewData.length) {
       this.element.addRenderableComponent(this);
     }
   }
-
   MaskElement.prototype.getMaskProperty = function (pos) {
     return this.viewData[pos].prop;
   };
-
   MaskElement.prototype.renderFrame = function (isFirstFrame) {
     var finalMat = this.element.finalTransform.mat;
     var i;
     var len = this.masksProperties.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.viewData[i].prop._mdf || isFirstFrame) {
         this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
       }
-
       if (this.viewData[i].op._mdf || isFirstFrame) {
         this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
       }
-
       if (this.masksProperties[i].mode !== 'n') {
         if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
           this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
         }
-
         if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
           var feMorph = this.storedData[i].expan;
-
           if (this.storedData[i].x.v < 0) {
             if (this.storedData[i].lastOperator !== 'erode') {
               this.storedData[i].lastOperator = 'erode';
               this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
             }
-
             feMorph.setAttribute('radius', -this.storedData[i].x.v);
           } else {
             if (this.storedData[i].lastOperator !== 'dilate') {
               this.storedData[i].lastOperator = 'dilate';
               this.storedData[i].elem.setAttribute('filter', null);
             }
-
             this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
           }
         }
       }
     }
   };
-
   MaskElement.prototype.getMaskelement = function () {
     return this.maskElement;
   };
-
   MaskElement.prototype.createLayerSolidPath = function () {
     var path = 'M0,0 ';
     path += ' h' + this.globalData.compSize.w;
@@ -8762,39 +7398,32 @@
     path += ' v-' + this.globalData.compSize.h + ' ';
     return path;
   };
-
   MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
     var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
     var i;
     var len;
     len = pathNodes._length;
-
     for (i = 1; i < len; i += 1) {
       // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
-    } // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
-
-
+    }
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
     if (pathNodes.c && len > 1) {
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
-    } // pathNodes.__renderedString = pathString;
-
+    }
+    // pathNodes.__renderedString = pathString;
 
     if (viewData.lastPath !== pathString) {
       var pathShapeValue = '';
-
       if (viewData.elem) {
         if (pathNodes.c) {
           pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
         }
-
         viewData.elem.setAttribute('d', pathShapeValue);
       }
-
       viewData.lastPath = pathString;
     }
   };
-
   MaskElement.prototype.destroy = function () {
     this.element = null;
     this.globalData = null;
@@ -8807,11 +7436,9 @@
     var ob = {};
     ob.createFilter = createFilter;
     ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
-
     function createFilter(filId, skipCoordinates) {
       var fil = createNS('filter');
       fil.setAttribute('id', filId);
-
       if (skipCoordinates !== true) {
         fil.setAttribute('filterUnits', 'objectBoundingBox');
         fil.setAttribute('x', '0%');
@@ -8819,10 +7446,8 @@
         fil.setAttribute('width', '100%');
         fil.setAttribute('height', '100%');
       }
-
       return fil;
     }
-
     function createAlphaToLuminanceFilter() {
       var feColorMatrix = createNS('feColorMatrix');
       feColorMatrix.setAttribute('type', 'matrix');
@@ -8830,7 +7455,6 @@
       feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
       return feColorMatrix;
     }
-
     return ob;
   }();
 
@@ -8840,21 +7464,17 @@
       svgLumaHidden: true,
       offscreenCanvas: typeof OffscreenCanvas !== 'undefined'
     };
-
     if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
       ob.maskType = false;
     }
-
     if (/firefox/i.test(navigator.userAgent)) {
       ob.svgLumaHidden = false;
     }
-
     return ob;
   }();
 
   var registeredEffects$1 = {};
   var idPrefix = 'filter_result_';
-
   function SVGEffects(elem) {
     var i;
     var source = 'SourceGraphic';
@@ -8864,59 +7484,47 @@
     var count = 0;
     this.filters = [];
     var filterManager;
-
     for (i = 0; i < len; i += 1) {
       filterManager = null;
       var type = elem.data.ef[i].ty;
-
       if (registeredEffects$1[type]) {
         var Effect = registeredEffects$1[type].effect;
         filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
         source = idPrefix + count;
-
         if (registeredEffects$1[type].countsAsEffect) {
           count += 1;
         }
       }
-
       if (filterManager) {
         this.filters.push(filterManager);
       }
     }
-
     if (count) {
       elem.globalData.defs.appendChild(fil);
       elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
     }
-
     if (this.filters.length) {
       elem.addRenderableComponent(this);
     }
   }
-
   SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
     var i;
     var len = this.filters.length;
-
     for (i = 0; i < len; i += 1) {
       this.filters[i].renderFrame(_isFirstFrame);
     }
   };
-
   SVGEffects.prototype.getEffects = function (type) {
     var i;
     var len = this.filters.length;
     var effects = [];
-
     for (i = 0; i < len; i += 1) {
       if (this.filters[i].type === type) {
         effects.push(this.filters[i]);
       }
     }
-
     return effects;
   };
-
   function registerEffect$1(id, effect, countsAsEffect) {
     registeredEffects$1[id] = {
       effect: effect,
@@ -8925,7 +7533,6 @@
   }
 
   function SVGBaseElement() {}
-
   SVGBaseElement.prototype = {
     initRendererElement: function initRendererElement() {
       this.layerElement = createNS('g');
@@ -8935,8 +7542,8 @@
       this.transformedElement = this.layerElement;
       this.maskedElement = this.layerElement;
       this._sizeChanged = false;
-      var layerElementParent = null; // If this layer acts as a mask for the following layer
-
+      var layerElementParent = null;
+      // If this layer acts as a mask for the following layer
       if (this.data.td) {
         this.matteMasks = {};
         var gg = createNS('g');
@@ -8951,16 +7558,13 @@
       } else {
         this.baseElement = this.layerElement;
       }
-
       if (this.data.ln) {
         this.layerElement.setAttribute('id', this.data.ln);
       }
-
       if (this.data.cl) {
         this.layerElement.setAttribute('class', this.data.cl);
-      } // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
-
-
+      }
+      // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
       if (this.data.ty === 0 && !this.data.hd) {
         var cp = createNS('clipPath');
         var pt = createNS('path');
@@ -8969,13 +7573,11 @@
         cp.setAttribute('id', clipId);
         cp.appendChild(pt);
         this.globalData.defs.appendChild(cp);
-
         if (this.checkMasks()) {
           var cpGroup = createNS('g');
           cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
           cpGroup.appendChild(this.layerElement);
           this.transformedElement = cpGroup;
-
           if (layerElementParent) {
             layerElementParent.appendChild(this.transformedElement);
           } else {
@@ -8985,7 +7587,6 @@
           this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
         }
       }
-
       if (this.data.bm !== 0) {
         this.setBlendMode();
       }
@@ -8994,7 +7595,6 @@
       if (this.finalTransform._localMatMdf) {
         this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
       }
-
       if (this.finalTransform._opMdf) {
         this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
       }
@@ -9008,7 +7608,6 @@
       if (this.data.hd) {
         return null;
       }
-
       return this.baseElement;
     },
     createRenderableComponents: function createRenderableComponents() {
@@ -9023,14 +7622,12 @@
       if (!this.matteMasks) {
         this.matteMasks = {};
       }
-
       if (!this.matteMasks[matteType]) {
         var id = this.layerId + '_' + matteType;
         var filId;
         var fil;
         var useElement;
         var gg;
-
         if (matteType === 1 || matteType === 3) {
           var masker = createNS('mask');
           masker.setAttribute('id', id);
@@ -9039,7 +7636,6 @@
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           masker.appendChild(useElement);
           this.globalData.defs.appendChild(masker);
-
           if (!featureSupport.maskType && matteType === 1) {
             masker.setAttribute('mask-type', 'luminance');
             filId = createElementID();
@@ -9058,16 +7654,16 @@
           var maskGrouper = createNS('g');
           maskGroup.appendChild(maskGrouper);
           filId = createElementID();
-          fil = filtersFactory.createFilter(filId); /// /
-
+          fil = filtersFactory.createFilter(filId);
+          /// /
           var feCTr = createNS('feComponentTransfer');
           feCTr.setAttribute('in', 'SourceGraphic');
           fil.appendChild(feCTr);
           var feFunc = createNS('feFuncA');
           feFunc.setAttribute('type', 'table');
           feFunc.setAttribute('tableValues', '1.0 0.0');
-          feCTr.appendChild(feFunc); /// /
-
+          feCTr.appendChild(feFunc);
+          /// /
           this.globalData.defs.appendChild(fil);
           var alphaRect = createNS('rect');
           alphaRect.setAttribute('width', this.comp.data.w);
@@ -9081,7 +7677,6 @@
           useElement = createNS('use');
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           maskGrouper.appendChild(useElement);
-
           if (!featureSupport.maskType) {
             maskGroup.setAttribute('mask-type', 'luminance');
             fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
@@ -9090,20 +7685,16 @@
             gg.appendChild(this.layerElement);
             maskGrouper.appendChild(gg);
           }
-
           this.globalData.defs.appendChild(maskGroup);
         }
-
         this.matteMasks[matteType] = id;
       }
-
       return this.matteMasks[matteType];
     },
     setMatte: function setMatte(id) {
       if (!this.matteElement) {
         return;
       }
-
       this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
     }
   };
@@ -9113,8 +7704,8 @@
    * Handles AE's layer parenting property.
    *
    */
-  function HierarchyElement() {}
 
+  function HierarchyElement() {}
   HierarchyElement.prototype = {
     /**
        * @function
@@ -9123,12 +7714,11 @@
        */
     initHierarchy: function initHierarchy() {
       // element's parent list
-      this.hierarchy = []; // if element is parent of another layer _isParent will be true
-
+      this.hierarchy = [];
+      // if element is parent of another layer _isParent will be true
       this._isParent = false;
       this.checkParenting();
     },
-
     /**
        * @function
        * Sets layer's hierarchy.
@@ -9139,7 +7729,6 @@
     setHierarchy: function setHierarchy(hierarchy) {
       this.hierarchy = hierarchy;
     },
-
     /**
        * @function
        * Sets layer as parent.
@@ -9148,7 +7737,6 @@
     setAsParent: function setAsParent() {
       this._isParent = true;
     },
-
     /**
        * @function
        * Searches layer's parenting chain
@@ -9162,7 +7750,6 @@
   };
 
   function RenderableDOMElement() {}
-
   (function () {
     var _prototype = {
       initElement: function initElement(data, globalData, comp) {
@@ -9192,7 +7779,6 @@
             var elem = this.baseElement || this.layerElement;
             elem.style.display = 'block';
           }
-
           this.hidden = false;
           this._isFirstFrame = true;
         }
@@ -9203,13 +7789,11 @@
         if (this.data.hd || this.hidden) {
           return;
         }
-
         this.renderTransform();
         this.renderRenderable();
         this.renderLocalTransform();
         this.renderElement();
         this.renderInnerContent();
-
         if (this._isFirstFrame) {
           this._isFirstFrame = false;
         }
@@ -9231,11 +7815,9 @@
 
   function IImageElement(data, globalData, comp) {
     this.assetData = globalData.getAssetData(data.refId);
-
     if (this.assetData && this.assetData.sid) {
       this.assetData = globalData.slotManager.getProp(this.assetData);
     }
-
     this.initElement(data, globalData, comp);
     this.sourceRect = {
       top: 0,
@@ -9244,9 +7826,7 @@
       height: this.assetData.h
     };
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
-
   IImageElement.prototype.createContent = function () {
     var assetPath = this.globalData.getAssetsPath(this.assetData);
     this.innerElem = createNS('image');
@@ -9256,7 +7836,6 @@
     this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
     this.layerElement.appendChild(this.innerElem);
   };
-
   IImageElement.prototype.sourceRectAtTime = function () {
     return this.sourceRect;
   };
@@ -9267,12 +7846,10 @@
   }
 
   function IShapeElement() {}
-
   IShapeElement.prototype = {
     addShapeToModifiers: function addShapeToModifiers(data) {
       var i;
       var len = this.shapeModifiers.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapeModifiers[i].addShape(data);
       }
@@ -9280,34 +7857,28 @@
     isShapeInAnimatedModifiers: function isShapeInAnimatedModifiers(data) {
       var i = 0;
       var len = this.shapeModifiers.length;
-
       while (i < len) {
         if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
           return true;
         }
       }
-
       return false;
     },
     renderModifiers: function renderModifiers() {
       if (!this.shapeModifiers.length) {
         return;
       }
-
       var i;
       var len = this.shapes.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapes[i].sh.reset();
       }
-
       len = this.shapeModifiers.length;
       var shouldBreakProcess;
-
       for (i = len - 1; i >= 0; i -= 1) {
-        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame); // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+        // workaround to fix cases where a repeater resets the shape so the following processes get called twice
         // TODO: find a better solution for this
-
         if (shouldBreakProcess) {
           break;
         }
@@ -9317,30 +7888,24 @@
       var elements = this.processedElements;
       var i = 0;
       var len = elements.length;
-
       while (i < len) {
         if (elements[i].elem === elem) {
           return elements[i].pos;
         }
-
         i += 1;
       }
-
       return 0;
     },
     addProcessedElement: function addProcessedElement(elem, pos) {
       var elements = this.processedElements;
       var i = elements.length;
-
       while (i) {
         i -= 1;
-
         if (elements[i].elem === elem) {
           elements[i].pos = pos;
           return;
         }
       }
-
       elements.push(new ProcessedElement(elem, pos));
     },
     prepareFrame: function prepareFrame(num) {
@@ -9366,25 +7931,22 @@
     this.transformers = transformers;
     this.lStr = '';
     this.sh = shape;
-    this.lvl = level; // TODO find if there are some cases where _isAnimated can be false.
+    this.lvl = level;
+    // TODO find if there are some cases where _isAnimated can be false.
     // For now, since shapes add up with other shapes. They have to be calculated every time.
     // One way of finding out is checking if all styles associated to this shape depend only of this shape
-
-    this._isAnimated = !!shape.k; // TODO: commenting this for now since all shapes are animated
-
+    this._isAnimated = !!shape.k;
+    // TODO: commenting this for now since all shapes are animated
     var i = 0;
     var len = transformers.length;
-
     while (i < len) {
       if (transformers[i].mProps.dynamicProperties.length) {
         this._isAnimated = true;
         break;
       }
-
       i += 1;
     }
   }
-
   SVGShapeData.prototype.setAsAnimated = function () {
     this._isAnimated = true;
   };
@@ -9399,7 +7961,6 @@
     this.pElem = createNS('path');
     this.msElem = null;
   }
-
   SVGStyleData.prototype.reset = function () {
     this.d = '';
     this._mdf = false;
@@ -9418,7 +7979,6 @@
     var i;
     var len = data.length || 0;
     var prop;
-
     for (i = 0; i < len; i += 1) {
       prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
       this.k = prop.k || this.k;
@@ -9427,31 +7987,24 @@
         p: prop
       };
     }
-
     if (!this.k) {
       this.getValue(true);
     }
-
     this._isAnimated = this.k;
   }
-
   DashProperty.prototype.getValue = function (forceRender) {
     if (this.elem.globalData.frameId === this.frameId && !forceRender) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
     this._mdf = this._mdf || forceRender;
-
     if (this._mdf) {
       var i = 0;
       var len = this.dataProps.length;
-
       if (this.renderer === 'svg') {
         this.dashStr = '';
       }
-
       for (i = 0; i < len; i += 1) {
         if (this.dataProps[i].n !== 'o') {
           if (this.renderer === 'svg') {
@@ -9465,7 +8018,6 @@
       }
     }
   };
-
   extendPrototype([DynamicPropertyContainer], DashProperty);
 
   function SVGStrokeStyleData(elem, data, styleOb) {
@@ -9478,7 +8030,6 @@
     this.style = styleOb;
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
 
   function SVGFillStyleData(elem, data, styleOb) {
@@ -9488,7 +8039,6 @@
     this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
 
   function SVGNoStyleData(elem, data, styleOb) {
@@ -9496,7 +8046,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
 
   function GradientProperty(elem, data, container) {
@@ -9513,88 +8062,69 @@
     this.k = this.prop.k;
     this.getValue(true);
   }
-
   GradientProperty.prototype.comparePoints = function (values, points) {
     var i = 0;
     var len = this.o.length / 2;
     var diff;
-
     while (i < len) {
       diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
-
       if (diff > 0.01) {
         return false;
       }
-
       i += 1;
     }
-
     return true;
   };
-
   GradientProperty.prototype.checkCollapsable = function () {
     if (this.o.length / 2 !== this.c.length / 4) {
       return false;
     }
-
     if (this.data.k.k[0].s) {
       var i = 0;
       var len = this.data.k.k.length;
-
       while (i < len) {
         if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
           return false;
         }
-
         i += 1;
       }
     } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
       return false;
     }
-
     return true;
   };
-
   GradientProperty.prototype.getValue = function (forceRender) {
     this.prop.getValue();
     this._mdf = false;
     this._cmdf = false;
     this._omdf = false;
-
     if (this.prop._mdf || forceRender) {
       var i;
       var len = this.data.p * 4;
       var mult;
       var val;
-
       for (i = 0; i < len; i += 1) {
         mult = i % 4 === 0 ? 100 : 255;
         val = Math.round(this.prop.v[i] * mult);
-
         if (this.c[i] !== val) {
           this.c[i] = val;
           this._cmdf = !forceRender;
         }
       }
-
       if (this.o.length) {
         len = this.prop.v.length;
-
         for (i = this.data.p * 4; i < len; i += 1) {
           mult = i % 2 === 0 ? 100 : 1;
           val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
-
           if (this.o[i - this.data.p * 4] !== val) {
             this.o[i - this.data.p * 4] = val;
             this._omdf = !forceRender;
           }
         }
       }
-
       this._mdf = !forceRender;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], GradientProperty);
 
   function SVGGradientFillStyleData(elem, data, styleOb) {
@@ -9602,7 +8132,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.initGradientData(elem, data, styleOb);
   }
-
   SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
     this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
     this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
@@ -9620,7 +8149,6 @@
     this.setGradientOpacity(data, styleOb);
     this._isAnimated = !!this._isAnimated;
   };
-
   SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
     var gradientId = createElementID();
     var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
@@ -9632,18 +8160,15 @@
     var j;
     var jLen;
     jLen = data.g.p * 4;
-
     for (j = 0; j < jLen; j += 4) {
       stop = createNS('stop');
       gfill.appendChild(stop);
       stops.push(stop);
     }
-
     pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
     this.gf = gfill;
     this.cst = stops;
   };
-
   SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
     if (this.g._hasOpacity && !this.g._collapsable) {
       var stop;
@@ -9661,25 +8186,20 @@
       opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
       jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
       var stops = this.stops;
-
       for (j = data.g.p * 4; j < jLen; j += 2) {
         stop = createNS('stop');
         stop.setAttribute('stop-color', 'rgb(255,255,255)');
         opFill.appendChild(stop);
         stops.push(stop);
       }
-
       maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
@@ -9687,7 +8207,6 @@
       styleOb.msElem = maskElement;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
 
   function SVGGradientStrokeStyleData(elem, data, styleOb) {
@@ -9698,7 +8217,6 @@
     this.initGradientData(elem, data, styleOb);
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
 
   function ShapeGroupData() {
@@ -9721,77 +8239,59 @@
     if (length === 0) {
       return '';
     }
-
     var _o = pathNodes.o;
     var _i = pathNodes.i;
     var _v = pathNodes.v;
     var i;
     var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
-
     for (i = 1; i < length; i += 1) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
     }
-
     if (closed && length) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
       shapeString += 'z';
     }
-
     return shapeString;
   };
 
   var SVGElementsRenderer = function () {
     var _identityMatrix = new Matrix();
-
     var _matrixHelper = new Matrix();
-
     var ob = {
       createRenderFunction: createRenderFunction
     };
-
     function createRenderFunction(data) {
       switch (data.ty) {
         case 'fl':
           return renderFill;
-
         case 'gf':
           return renderGradient;
-
         case 'gs':
           return renderGradientStroke;
-
         case 'st':
           return renderStroke;
-
         case 'sh':
         case 'el':
         case 'rc':
         case 'sr':
           return renderPath;
-
         case 'tr':
           return renderContentTransform;
-
         case 'no':
           return renderNoop;
-
         default:
           return null;
       }
     }
-
     function renderContentTransform(styleData, itemData, isFirstFrame) {
       if (isFirstFrame || itemData.transform.op._mdf) {
         itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
       }
-
       if (isFirstFrame || itemData.transform.mProps._mdf) {
         itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
       }
     }
-
     function renderNoop() {}
-
     function renderPath(styleData, itemData, isFirstFrame) {
       var j;
       var jLen;
@@ -9805,25 +8305,20 @@
       var mat;
       var iterations;
       var k;
-
       for (l = 0; l < lLen; l += 1) {
         redraw = itemData.sh._mdf || isFirstFrame;
-
         if (itemData.styles[l].lvl < lvl) {
           mat = _matrixHelper.reset();
           iterations = lvl - itemData.styles[l].lvl;
           k = itemData.transformers.length - 1;
-
           while (!redraw && iterations > 0) {
             redraw = itemData.transformers[k].mProps._mdf || redraw;
             iterations -= 1;
             k -= 1;
           }
-
           if (redraw) {
             iterations = lvl - itemData.styles[l].lvl;
             k = itemData.transformers.length - 1;
-
             while (iterations > 0) {
               mat.multiply(itemData.transformers[k].mProps.v);
               iterations -= 1;
@@ -9833,115 +8328,90 @@
         } else {
           mat = _identityMatrix;
         }
-
         paths = itemData.sh.paths;
         jLen = paths._length;
-
         if (redraw) {
           pathStringTransformed = '';
-
           for (j = 0; j < jLen; j += 1) {
             pathNodes = paths.shapes[j];
-
             if (pathNodes && pathNodes._length) {
               pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
             }
           }
-
           itemData.caches[l] = pathStringTransformed;
         } else {
           pathStringTransformed = itemData.caches[l];
         }
-
         itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
         itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
       }
     }
-
     function renderFill(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
-
       if (itemData.c._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
       }
     }
-
     function renderGradientStroke(styleData, itemData, isFirstFrame) {
       renderGradient(styleData, itemData, isFirstFrame);
       renderStroke(styleData, itemData, isFirstFrame);
     }
-
     function renderGradient(styleData, itemData, isFirstFrame) {
       var gfill = itemData.gf;
       var hasOpacity = itemData.g._hasOpacity;
       var pt1 = itemData.s.v;
       var pt2 = itemData.e.v;
-
       if (itemData.o._mdf || isFirstFrame) {
         var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
         itemData.style.pElem.setAttribute(attr, itemData.o.v);
       }
-
       if (itemData.s._mdf || isFirstFrame) {
         var attr1 = styleData.t === 1 ? 'x1' : 'cx';
         var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
         gfill.setAttribute(attr1, pt1[0]);
         gfill.setAttribute(attr2, pt1[1]);
-
         if (hasOpacity && !itemData.g._collapsable) {
           itemData.of.setAttribute(attr1, pt1[0]);
           itemData.of.setAttribute(attr2, pt1[1]);
         }
       }
-
       var stops;
       var i;
       var len;
       var stop;
-
       if (itemData.g._cmdf || isFirstFrame) {
         stops = itemData.cst;
         var cValues = itemData.g.c;
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
           stop.setAttribute('offset', cValues[i * 4] + '%');
           stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
         }
       }
-
       if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
         var oValues = itemData.g.o;
-
         if (itemData.g._collapsable) {
           stops = itemData.cst;
         } else {
           stops = itemData.ost;
         }
-
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
-
           if (!itemData.g._collapsable) {
             stop.setAttribute('offset', oValues[i * 2] + '%');
           }
-
           stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
         }
       }
-
       if (styleData.t === 1) {
         if (itemData.e._mdf || isFirstFrame) {
           gfill.setAttribute('x2', pt2[0]);
           gfill.setAttribute('y2', pt2[1]);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('x2', pt2[0]);
             itemData.of.setAttribute('y2', pt2[1]);
@@ -9949,112 +8419,93 @@
         }
       } else {
         var rad;
-
         if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
           rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           gfill.setAttribute('r', rad);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('r', rad);
           }
         }
-
-        if (itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
           if (!rad) {
             rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           }
-
           var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
           var percent = itemData.h.v;
-
           if (percent >= 1) {
             percent = 0.99;
           } else if (percent <= -1) {
             percent = -0.99;
           }
-
           var dist = rad * percent;
           var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
           var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
           gfill.setAttribute('fx', x);
           gfill.setAttribute('fy', y);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('fx', x);
             itemData.of.setAttribute('fy', y);
           }
-        } // gfill.setAttribute('fy','200');
-
+        }
+        // gfill.setAttribute('fy','200');
       }
     }
-
     function renderStroke(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
       var d = itemData.d;
-
       if (d && (d._mdf || isFirstFrame) && d.dashStr) {
         styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
         styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
       }
-
       if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
         styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
       }
-
       if (itemData.w._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
-
         if (styleElem.msElem) {
           styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
         }
       }
     }
-
     return ob;
   }();
 
   function SVGShapeElement(data, globalData, comp) {
     // List of drawable elements
-    this.shapes = []; // Full shape data
-
-    this.shapesData = data.shapes; // List of styles that will be applied to shapes
-
-    this.stylesList = []; // List of modifiers that will be applied to shapes
-
-    this.shapeModifiers = []; // List of items in shape tree
-
-    this.itemsData = []; // List of items in previous shape tree
-
-    this.processedElements = []; // List of animated components
-
+    this.shapes = [];
+    // Full shape data
+    this.shapesData = data.shapes;
+    // List of styles that will be applied to shapes
+    this.stylesList = [];
+    // List of modifiers that will be applied to shapes
+    this.shapeModifiers = [];
+    // List of items in shape tree
+    this.itemsData = [];
+    // List of items in previous shape tree
+    this.processedElements = [];
+    // List of animated components
     this.animatedContents = [];
-    this.initElement(data, globalData, comp); // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.initElement(data, globalData, comp);
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
     // List of elements that have been created
-
-    this.prevViewData = []; // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.prevViewData = [];
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
-
   SVGShapeElement.prototype.initSecondaryElement = function () {};
-
   SVGShapeElement.prototype.identityMatrix = new Matrix();
-
   SVGShapeElement.prototype.buildExpressionInterface = function () {};
-
   SVGShapeElement.prototype.createContent = function () {
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
   };
+
   /*
   This method searches for multiple shapes that affect a single element and one of them is animated
   */
-
-
   SVGShapeElement.prototype.filterUniqueShapes = function () {
     var i;
     var len = this.shapes.length;
@@ -10064,42 +8515,34 @@
     var style;
     var tempShapes = [];
     var areAnimated = false;
-
     for (j = 0; j < jLen; j += 1) {
       style = this.stylesList[j];
       areAnimated = false;
       tempShapes.length = 0;
-
       for (i = 0; i < len; i += 1) {
         shape = this.shapes[i];
-
         if (shape.styles.indexOf(style) !== -1) {
           tempShapes.push(shape);
           areAnimated = shape._isAnimated || areAnimated;
         }
       }
-
       if (tempShapes.length > 1 && areAnimated) {
         this.setShapesAsAnimated(tempShapes);
       }
     }
   };
-
   SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
     var i;
     var len = shapes.length;
-
     for (i = 0; i < len; i += 1) {
       shapes[i].setAsAnimated();
     }
   };
-
   SVGShapeElement.prototype.createStyleElement = function (data, level) {
     // TODO: prevent drawing of hidden styles
     var elementData;
     var styleOb = new SVGStyleData(data, level);
     var pathElement = styleOb.pElem;
-
     if (data.ty === 'st') {
       elementData = new SVGStrokeStyleData(this, data, styleOb);
     } else if (data.ty === 'fl') {
@@ -10108,7 +8551,6 @@
       var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
       elementData = new GradientConstructor(this, data, styleOb);
       this.globalData.defs.appendChild(elementData.gf);
-
       if (elementData.maskId) {
         this.globalData.defs.appendChild(elementData.ms);
         this.globalData.defs.appendChild(elementData.of);
@@ -10117,66 +8559,51 @@
     } else if (data.ty === 'no') {
       elementData = new SVGNoStyleData(this, data, styleOb);
     }
-
     if (data.ty === 'st' || data.ty === 'gs') {
       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);
       }
     }
-
     if (data.r === 2) {
       pathElement.setAttribute('fill-rule', 'evenodd');
     }
-
     if (data.ln) {
       pathElement.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       pathElement.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     this.stylesList.push(styleOb);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createGroupElement = function (data) {
     var elementData = new ShapeGroupData();
-
     if (data.ln) {
       elementData.gr.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       elementData.gr.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     return elementData;
   };
-
   SVGShapeElement.prototype.createTransformElement = function (data, container) {
     var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
     var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
     var ty = 4;
-
     if (data.ty === 'rc') {
       ty = 5;
     } else if (data.ty === 'el') {
@@ -10184,7 +8611,6 @@
     } else if (data.ty === 'sr') {
       ty = 7;
     }
-
     var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
     var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
     this.shapes.push(elementData);
@@ -10192,58 +8618,46 @@
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
     var i = 0;
     var len = this.animatedContents.length;
-
     while (i < len) {
       if (this.animatedContents[i].element === element) {
         return;
       }
-
       i += 1;
     }
-
     this.animatedContents.push({
       fn: SVGElementsRenderer.createRenderFunction(data),
       element: element,
       data: data
     });
   };
-
   SVGShapeElement.prototype.setElementStyles = function (elementData) {
     var arr = elementData.styles;
     var j;
     var jLen = this.stylesList.length;
-
     for (j = 0; j < jLen; j += 1) {
-      if (!this.stylesList[j].closed) {
+      if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
         arr.push(this.stylesList[j]);
       }
     }
   };
-
   SVGShapeElement.prototype.reloadShapes = function () {
     this._isFirstFrame = true;
     var i;
     var len = this.itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       this.prevViewData[i] = this.itemsData[i];
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
     len = this.dynamicProperties.length;
-
     for (i = 0; i < len; i += 1) {
       this.dynamicProperties[i].getValue();
     }
-
     this.renderModifiers();
   };
-
   SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
     var ownTransformers = [].concat(transformers);
     var i;
@@ -10255,43 +8669,35 @@
     var currentTransform;
     var modifier;
     var processedPos;
-
     for (i = len; i >= 0; i -= 1) {
       processedPos = this.searchProcessedElement(arr[i]);
-
       if (!processedPos) {
         arr[i]._render = render;
       } else {
         itemsData[i] = prevViewData[processedPos - 1];
       }
-
       if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
         if (!processedPos) {
           itemsData[i] = this.createStyleElement(arr[i], level);
         } else {
-          itemsData[i].style.closed = false;
+          itemsData[i].style.closed = arr[i].hd;
         }
-
         if (arr[i]._render) {
           if (itemsData[i].style.pElem.parentNode !== container) {
             container.appendChild(itemsData[i].style.pElem);
           }
         }
-
         ownStyles.push(itemsData[i].style);
       } else if (arr[i].ty === 'gr') {
         if (!processedPos) {
           itemsData[i] = this.createGroupElement(arr[i]);
         } else {
           jLen = itemsData[i].it.length;
-
           for (j = 0; j < jLen; j += 1) {
             itemsData[i].prevViewData[j] = itemsData[i].it[j];
           }
         }
-
         this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
-
         if (arr[i]._render) {
           if (itemsData[i].gr.parentNode !== container) {
             container.appendChild(itemsData[i].gr);
@@ -10301,14 +8707,12 @@
         if (!processedPos) {
           itemsData[i] = this.createTransformElement(arr[i], container);
         }
-
         currentTransform = itemsData[i].transform;
         ownTransformers.push(currentTransform);
       } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
         if (!processedPos) {
           itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
         }
-
         this.setElementStyles(itemsData[i]);
       } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
         if (!processedPos) {
@@ -10320,7 +8724,6 @@
           modifier = itemsData[i];
           modifier.closed = false;
         }
-
         ownModifiers.push(modifier);
       } else if (arr[i].ty === 'rp') {
         if (!processedPos) {
@@ -10333,64 +8736,49 @@
           modifier = itemsData[i];
           modifier.closed = true;
         }
-
         ownModifiers.push(modifier);
       }
-
       this.addProcessedElement(arr[i], i + 1);
     }
-
     len = ownStyles.length;
-
     for (i = 0; i < len; i += 1) {
       ownStyles[i].closed = true;
     }
-
     len = ownModifiers.length;
-
     for (i = 0; i < len; i += 1) {
       ownModifiers[i].closed = true;
     }
   };
-
   SVGShapeElement.prototype.renderInnerContent = function () {
     this.renderModifiers();
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       this.stylesList[i].reset();
     }
-
     this.renderShape();
-
     for (i = 0; i < len; i += 1) {
       if (this.stylesList[i]._mdf || this._isFirstFrame) {
         if (this.stylesList[i].msElem) {
-          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d); // Adding M0 0 fixes same mask bug on all browsers
-
+          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+          // Adding M0 0 fixes same mask bug on all browsers
           this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
         }
-
         this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
       }
     }
   };
-
   SVGShapeElement.prototype.renderShape = function () {
     var i;
     var len = this.animatedContents.length;
     var animatedContent;
-
     for (i = 0; i < len; i += 1) {
       animatedContent = this.animatedContents[i];
-
       if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
         animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
       }
     }
   };
-
   SVGShapeElement.prototype.destroy = function () {
     this.destroyBaseElement();
     this.shapesData = null;
@@ -10413,7 +8801,6 @@
       p: true
     };
   }
-
   LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
     this._mdf.o = false;
     this._mdf.sw = false;
@@ -10422,43 +8809,36 @@
     this._mdf.m = false;
     this._mdf.p = false;
     var updated = false;
-
     if (this.o !== o) {
       this.o = o;
       this._mdf.o = true;
       updated = true;
     }
-
     if (this.sw !== sw) {
       this.sw = sw;
       this._mdf.sw = true;
       updated = true;
     }
-
     if (this.sc !== sc) {
       this.sc = sc;
       this._mdf.sc = true;
       updated = true;
     }
-
     if (this.fc !== fc) {
       this.fc = fc;
       this._mdf.fc = true;
       updated = true;
     }
-
     if (this.m !== m) {
       this.m = m;
       this._mdf.m = true;
       updated = true;
     }
-
     if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
       this.p = p;
       this._mdf.p = true;
       updated = true;
     }
-
     return updated;
   };
 
@@ -10469,11 +8849,9 @@
     this.kf = false;
     this._isFirstFrame = true;
     this._mdf = false;
-
     if (data.d && data.d.sid) {
       data.d = elem.globalData.slotManager.getProp(data.d);
     }
-
     this.data = data;
     this.elem = elem;
     this.comp = this.elem.comp;
@@ -10512,73 +8890,57 @@
       __complete: false
     };
     this.copyData(this.currentData, this.data.d.k[0].s);
-
     if (!this.searchProperty()) {
       this.completeTextData(this.currentData);
     }
   }
-
   TextProperty.prototype.defaultBoxWidth = [0, 0];
-
   TextProperty.prototype.copyData = function (obj, data) {
     for (var s in data) {
       if (Object.prototype.hasOwnProperty.call(data, s)) {
         obj[s] = data[s];
       }
     }
-
     return obj;
   };
-
   TextProperty.prototype.setCurrentData = function (data) {
     if (!data.__complete) {
       this.completeTextData(data);
     }
-
     this.currentData = data;
     this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
     this._mdf = true;
   };
-
   TextProperty.prototype.searchProperty = function () {
     return this.searchKeyframes();
   };
-
   TextProperty.prototype.searchKeyframes = function () {
     this.kf = this.data.d.k.length > 1;
-
     if (this.kf) {
       this.addEffect(this.getKeyframeValue.bind(this));
     }
-
     return this.kf;
   };
-
   TextProperty.prototype.addEffect = function (effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.getValue = function (_finalValue) {
     if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
       return;
     }
-
     this.currentData.t = this.data.d.k[this.keysIndex].s.t;
     var currentValue = this.currentData;
     var currentIndex = this.keysIndex;
-
     if (this.lock) {
       this.setCurrentData(this.currentData);
       return;
     }
-
     this.lock = true;
     this._mdf = false;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
-
     for (i = 0; i < len; i += 1) {
       // Checking if index changed to prevent creating a new object every time the expression updates.
       if (currentIndex !== this.keysIndex) {
@@ -10587,38 +8949,30 @@
         finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
       }
     }
-
     if (currentValue !== finalValue) {
       this.setCurrentData(finalValue);
     }
-
     this.v = this.currentData;
     this.pv = this.v;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   };
-
   TextProperty.prototype.getKeyframeValue = function () {
     var textKeys = this.data.d.k;
     var frameNum = this.elem.comp.renderedFrame;
     var i = 0;
     var len = textKeys.length;
-
     while (i <= len - 1) {
       if (i === len - 1 || textKeys[i + 1].t > frameNum) {
         break;
       }
-
       i += 1;
     }
-
     if (this.keysIndex !== i) {
       this.keysIndex = i;
     }
-
     return this.data.d.k[this.keysIndex].s;
   };
-
   TextProperty.prototype.buildFinalText = function (text) {
     var charactersArray = [];
     var i = 0;
@@ -10628,21 +8982,20 @@
     var shouldCombine = false;
     var shouldCombineNext = false;
     var currentChars = '';
-
     while (i < len) {
       shouldCombine = shouldCombineNext;
       shouldCombineNext = false;
       charCode = text.charCodeAt(i);
       currentChars = text.charAt(i);
-
       if (FontManager.isCombinedCharacter(charCode)) {
-        shouldCombine = true; // It's a potential surrogate pair (this is the High surrogate)
+        shouldCombine = true;
+        // It's a potential surrogate pair (this is the High surrogate)
       } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
         if (FontManager.isRegionalFlag(text, i)) {
           currentChars = text.substr(i, 14);
         } else {
-          secondCharCode = text.charCodeAt(i + 1); // It's a surrogate pair (this is the Low surrogate)
-
+          secondCharCode = text.charCodeAt(i + 1);
+          // It's a surrogate pair (this is the Low surrogate)
           if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
             if (FontManager.isModifier(charCode, secondCharCode)) {
               currentChars = text.substr(i, 2);
@@ -10656,7 +9009,6 @@
         }
       } else if (charCode > 0xDBFF) {
         secondCharCode = text.charCodeAt(i + 1);
-
         if (FontManager.isVariationSelector(charCode)) {
           shouldCombine = true;
         }
@@ -10664,20 +9016,16 @@
         shouldCombine = true;
         shouldCombineNext = true;
       }
-
       if (shouldCombine) {
         charactersArray[charactersArray.length - 1] += currentChars;
         shouldCombine = false;
       } else {
         charactersArray.push(currentChars);
       }
-
       i += currentChars.length;
     }
-
     return charactersArray;
   };
-
   TextProperty.prototype.completeTextData = function (documentData) {
     documentData.__complete = true;
     var fontManager = this.elem.globalData.fontManager;
@@ -10709,14 +9057,12 @@
     documentData.finalLineHeight = documentData.lh;
     var trackingOffset = documentData.tr / 1000 * documentData.finalSize;
     var charCode;
-
     if (documentData.sz) {
       var flag = true;
       var boxWidth = documentData.sz[0];
       var boxHeight = documentData.sz[1];
       var currentHeight;
       var finalText;
-
       while (flag) {
         finalText = this.buildFinalText(documentData.t);
         currentHeight = 0;
@@ -10724,11 +9070,9 @@
         len = finalText.length;
         trackingOffset = documentData.tr / 1000 * documentData.finalSize;
         var lastSpaceIndex = -1;
-
         for (i = 0; i < len; i += 1) {
           charCode = finalText[i].charCodeAt(0);
           newLineFlag = false;
-
           if (finalText[i] === ' ') {
             lastSpaceIndex = i;
           } else if (charCode === 13 || charCode === 3) {
@@ -10736,7 +9080,6 @@
             newLineFlag = true;
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
           }
-
           if (fontManager.chars) {
             charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
             cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -10744,17 +9087,15 @@
             // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
             cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
           }
-
           if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
             if (lastSpaceIndex === -1) {
               len += 1;
             } else {
               i = lastSpaceIndex;
             }
-
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
-            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r'); // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
-
+            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+            // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
             lastSpaceIndex = -1;
             lineWidth = 0;
           } else {
@@ -10762,9 +9103,7 @@
             lineWidth += trackingOffset;
           }
         }
-
         currentHeight += fontData.ascent * documentData.finalSize / 100;
-
         if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
           documentData.finalSize -= 1;
           documentData.finalLineHeight = documentData.finalSize * documentData.lh / documentData.s;
@@ -10775,17 +9114,14 @@
         }
       }
     }
-
     lineWidth = -trackingOffset;
     cLength = 0;
     var uncollapsedSpaces = 0;
     var currentChar;
-
     for (i = 0; i < len; i += 1) {
       newLineFlag = false;
       currentChar = documentData.finalText[i];
       charCode = currentChar.charCodeAt(0);
-
       if (charCode === 13 || charCode === 3) {
         uncollapsedSpaces = 0;
         lineWidths.push(lineWidth);
@@ -10797,7 +9133,6 @@
       } else {
         val = currentChar;
       }
-
       if (fontManager.chars) {
         charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
         cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -10805,16 +9140,15 @@
         // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
         // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
         cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
-      } //
+      }
 
-
+      //
       if (currentChar === ' ') {
         uncollapsedSpaces += cLength + trackingOffset;
       } else {
         lineWidth += cLength + trackingOffset + uncollapsedSpaces;
         uncollapsedSpaces = 0;
       }
-
       letters.push({
         l: cLength,
         an: cLength,
@@ -10825,42 +9159,35 @@
         line: currentLine,
         animatorJustifyOffset: 0
       });
-
       if (anchorGrouping == 2) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || val === ' ' || i === len - 1) {
           if (val === '' || val === ' ') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           index += 1;
           currentSize = 0;
         }
       } else if (anchorGrouping == 3) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || i === len - 1) {
           if (val === '') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           currentSize = 0;
           index += 1;
         }
@@ -10870,31 +9197,25 @@
         index += 1;
       }
     }
-
     documentData.l = letters;
     maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
     lineWidths.push(lineWidth);
-
     if (documentData.sz) {
       documentData.boxWidth = documentData.sz[0];
       documentData.justifyOffset = 0;
     } else {
       documentData.boxWidth = maxLineWidth;
-
       switch (documentData.j) {
         case 1:
           documentData.justifyOffset = -documentData.boxWidth;
           break;
-
         case 2:
           documentData.justifyOffset = -documentData.boxWidth / 2;
           break;
-
         default:
           documentData.justifyOffset = 0;
       }
     }
-
     documentData.lineWidths = lineWidths;
     var animators = data.a;
     var animatorData;
@@ -10903,63 +9224,49 @@
     var based;
     var ind;
     var indexes = [];
-
     for (j = 0; j < jLen; j += 1) {
       animatorData = animators[j];
-
       if (animatorData.a.sc) {
         documentData.strokeColorAnim = true;
       }
-
       if (animatorData.a.sw) {
         documentData.strokeWidthAnim = true;
       }
-
       if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
         documentData.fillColorAnim = true;
       }
-
       ind = 0;
       based = animatorData.s.b;
-
       for (i = 0; i < len; i += 1) {
         letterData = letters[i];
         letterData.anIndexes[j] = ind;
-
         if (based == 1 && letterData.val !== '' || based == 2 && letterData.val !== '' && letterData.val !== ' ' || based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1) || based == 4 && (letterData.n || i == len - 1)) {
           // eslint-disable-line eqeqeq
           if (animatorData.s.rn === 1) {
             indexes.push(ind);
           }
-
           ind += 1;
         }
       }
-
       data.a[j].s.totalChars = ind;
       var currentInd = -1;
       var newInd;
-
       if (animatorData.s.rn === 1) {
         for (i = 0; i < len; i += 1) {
           letterData = letters[i];
-
           if (currentInd != letterData.anIndexes[j]) {
             // eslint-disable-line eqeqeq
             currentInd = letterData.anIndexes[j];
             newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
           }
-
           letterData.anIndexes[j] = newInd;
         }
       }
     }
-
     documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
     documentData.ls = documentData.ls || 0;
     documentData.ascent = fontData.ascent * documentData.finalSize / 100;
   };
-
   TextProperty.prototype.updateDocumentData = function (newData, index) {
     index = index === undefined ? this.keysIndex : index;
     var dData = this.copyData({}, this.data.d.k[index].s);
@@ -10969,7 +9276,6 @@
     this.setCurrentData(dData);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.recalculate = function (index) {
     var dData = this.data.d.k[index].s;
     dData.__complete = false;
@@ -10977,13 +9283,11 @@
     this._isFirstFrame = true;
     this.getValue(dData);
   };
-
   TextProperty.prototype.canResizeFont = function (_canResize) {
     this.canResize = _canResize;
     this.recalculate(this.keysIndex);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
     this.minimumFontSize = Math.floor(_fontValue) || 1;
     this.recalculate(this.keysIndex);
@@ -10994,7 +9298,6 @@
     var max = Math.max;
     var min = Math.min;
     var floor = Math.floor;
-
     function TextSelectorPropFactory(elem, data) {
       this._currentTextLength = -1;
       this.k = false;
@@ -11007,7 +9310,6 @@
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: 0
       }, 0, 0, this);
-
       if ('e' in data) {
         this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
       } else {
@@ -11015,7 +9317,6 @@
           v: 100
         };
       }
-
       this.o = PropertyFactory.getProp(elem, data.o || {
         k: 0
       }, 0, 0, this);
@@ -11029,48 +9330,40 @@
         k: 100
       }, 0, 0, this);
       this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
-
       if (!this.dynamicProperties.length) {
         this.getValue();
       }
     }
-
     TextSelectorPropFactory.prototype = {
       getMult: function getMult(ind) {
         if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
           this.getValue();
         }
-
         var x1 = 0;
         var y1 = 0;
         var x2 = 1;
         var y2 = 1;
-
         if (this.ne.v > 0) {
           x1 = this.ne.v / 100.0;
         } else {
           y1 = -this.ne.v / 100.0;
         }
-
         if (this.xe.v > 0) {
           x2 = 1.0 - this.xe.v / 100.0;
         } else {
           y2 = 1.0 + this.xe.v / 100.0;
         }
-
         var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
         var mult = 0;
         var s = this.finalS;
         var e = this.finalE;
         var type = this.data.sh;
-
         if (type === 2) {
           if (e === s) {
             mult = ind >= e ? 1 : 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 3) {
           if (e === s) {
@@ -11078,21 +9371,18 @@
           } else {
             mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 4) {
           if (e === s) {
             mult = 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
-
             if (mult < 0.5) {
               mult *= 2;
             } else {
               mult = 1 - 2 * (mult - 0.5);
             }
           }
-
           mult = easer(mult);
         } else if (type === 5) {
           if (e === s) {
@@ -11101,13 +9391,11 @@
             var tot = e - s;
             /* ind += 0.5;
                       mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
-
             ind = min(max(0, ind + 0.5 - s), e - s);
             var x = -tot / 2 + ind;
             var a = tot / 2;
             mult = Math.sqrt(1 - x * x / (a * a));
           }
-
           mult = easer(mult);
         } else if (type === 6) {
           if (e === s) {
@@ -11116,7 +9404,6 @@
             ind = min(max(0, ind + 0.5 - s), e - s);
             mult = (1 + Math.cos(Math.PI + Math.PI * 2 * ind / (e - s))) / 2; // eslint-disable-line
           }
-
           mult = easer(mult);
         } else {
           if (ind >= floor(s)) {
@@ -11126,9 +9413,9 @@
               mult = max(0, min(e - ind, 1));
             }
           }
-
           mult = easer(mult);
-        } // Smoothness implementation.
+        }
+        // Smoothness implementation.
         // The smoothness represents a reduced range of the original [0; 1] range.
         // if smoothness is 25%, the new range will be [0.375; 0.625]
         // Steps are:
@@ -11138,60 +9425,47 @@
         //     - subtract the threshold
         //     - divide it by the smoothness (this will return the range to [0; 1])
         // Note: If it doesn't work on some scenarios, consider applying it before the easer.
-
-
         if (this.sm.v !== 100) {
           var smoothness = this.sm.v * 0.01;
-
           if (smoothness === 0) {
             smoothness = 0.00000001;
           }
-
           var threshold = 0.5 - smoothness * 0.5;
-
           if (mult < threshold) {
             mult = 0;
           } else {
             mult = (mult - threshold) / smoothness;
-
             if (mult > 1) {
               mult = 1;
             }
           }
         }
-
         return mult * this.a.v;
       },
       getValue: function getValue(newCharsFlag) {
         this.iterateDynamicProperties();
         this._mdf = newCharsFlag || this._mdf;
         this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
-
         if (newCharsFlag && this.data.r === 2) {
           this.e.v = this._currentTextLength;
         }
-
         var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
         var o = this.o.v / divisor;
         var s = this.s.v / divisor + o;
         var e = this.e.v / divisor + o;
-
         if (s > e) {
           var _s = s;
           s = e;
           e = _s;
         }
-
         this.finalS = s;
         this.finalE = e;
       }
     };
     extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
-
     function getTextSelectorProp(elem, data, arr) {
       return new TextSelectorPropFactory(elem, data, arr);
     }
-
     return {
       getTextSelectorProp: getTextSelectorProp
     };
@@ -11241,18 +9515,15 @@
     this.lettersChangedFlag = false;
     this.initDynamicPropertyContainer(elem);
   }
-
   TextAnimatorProperty.prototype.searchProperties = function () {
     var i;
     var len = this._textData.a.length;
     var animatorProps;
     var getProp = PropertyFactory.getProp;
-
     for (i = 0; i < len; i += 1) {
       animatorProps = this._textData.a[i];
       this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
     }
-
     if (this._textData.p && 'm' in this._textData.p) {
       this._pathData = {
         a: getProp(this._elem, this._textData.p.a, 0, 0, this),
@@ -11266,17 +9537,13 @@
     } else {
       this._hasMaskedPath = false;
     }
-
     this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
   };
-
   TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
     this.lettersChangedFlag = lettersChangedFlag;
-
     if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
       return;
     }
-
     this._isFirstFrame = false;
     var alignment = this._moreOptions.alignment.v;
     var animators = this._animatorsData;
@@ -11304,18 +9571,14 @@
     var perc;
     var tanAngle;
     var mask;
-
     if (this._hasMaskedPath) {
       mask = this._pathData.m;
-
       if (!this._pathData.n || this._pathData._mdf) {
         var paths = mask.v;
-
         if (this._pathData.r.v) {
           paths = paths.reverse();
-        } // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
-
-
+        }
+        // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
         pathInfo = {
           tLength: 0,
           segments: []
@@ -11323,26 +9586,21 @@
         len = paths._length - 1;
         var bezierData;
         totalLength = 0;
-
         for (i = 0; i < len; i += 1) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[i + 1], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         i = len;
-
         if (mask.v.c) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[0], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         this._pathData.pi = pathInfo;
       }
-
       pathInfo = this._pathData.pi;
       currentLength = this._pathData.f.v;
       segmentInd = 0;
@@ -11350,20 +9608,16 @@
       segmentLength = 0;
       flag = true;
       segments = pathInfo.segments;
-
       if (currentLength < 0 && mask.v.c) {
         if (pathInfo.tLength < Math.abs(currentLength)) {
           currentLength = -Math.abs(currentLength) % pathInfo.tLength;
         }
-
         segmentInd = segments.length - 1;
         points = segments[segmentInd].points;
         pointInd = points.length - 1;
-
         while (currentLength < 0) {
           currentLength += points[pointInd].partialLength;
           pointInd -= 1;
-
           if (pointInd < 0) {
             segmentInd -= 1;
             points = segments[segmentInd].points;
@@ -11371,13 +9625,11 @@
           }
         }
       }
-
       points = segments[segmentInd].points;
       prevPoint = points[pointInd - 1];
       currentPoint = points[pointInd];
       partialLength = currentPoint.partialLength;
     }
-
     len = letters.length;
     xPos = 0;
     yPos = 0;
@@ -11408,40 +9660,35 @@
     var letterFc;
     var letterM = '';
     var letterP = this.defaultPropsArray;
-    var letterO; //
+    var letterO;
 
+    //
     if (documentData.j === 2 || documentData.j === 1) {
       var animatorJustifyOffset = 0;
       var animatorFirstCharOffset = 0;
       var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
       var lastIndex = 0;
       var isNewLine = true;
-
       for (i = 0; i < len; i += 1) {
         if (letters[i].n) {
           if (animatorJustifyOffset) {
             animatorJustifyOffset += animatorFirstCharOffset;
           }
-
           while (lastIndex < i) {
             letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
             lastIndex += 1;
           }
-
           animatorJustifyOffset = 0;
           isNewLine = true;
         } else {
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.t.propType) {
               if (isNewLine && documentData.j === 2) {
                 animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
               }
-
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
               } else {
@@ -11449,33 +9696,28 @@
               }
             }
           }
-
           isNewLine = false;
         }
       }
-
       if (animatorJustifyOffset) {
         animatorJustifyOffset += animatorFirstCharOffset;
       }
-
       while (lastIndex < i) {
         letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
         lastIndex += 1;
       }
-    } //
-
+    }
+    //
 
     for (i = 0; i < len; i += 1) {
       matrixHelper.reset();
       elemOpacity = 1;
-
       if (letters[i].n) {
         xPos = 0;
         yPos += documentData.yOffset;
         yPos += firstLine ? 1 : 0;
         currentLength = initPathPos;
         firstLine = false;
-
         if (this._hasMaskedPath) {
           segmentInd = initSegmentInd;
           pointInd = initPointInd;
@@ -11485,7 +9727,6 @@
           partialLength = currentPoint.partialLength;
           segmentLength = 0;
         }
-
         letterM = '';
         letterFc = '';
         letterSw = '';
@@ -11498,48 +9739,37 @@
               case 1:
                 currentLength += totalLength - documentData.lineWidths[letters[i].line];
                 break;
-
               case 2:
                 currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
                 break;
-
               default:
                 break;
             }
-
             currentLine = letters[i].line;
           }
-
           if (ind !== letters[i].ind) {
             if (letters[ind]) {
               currentLength += letters[ind].extra;
             }
-
             currentLength += letters[i].an / 2;
             ind = letters[i].ind;
           }
-
           currentLength += alignment[0] * letters[i].an * 0.005;
           var animatorOffset = 0;
-
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.p.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.p.v[0] * mult[0];
               } else {
                 animatorOffset += animatorProps.p.v[0] * mult;
               }
             }
-
             if (animatorProps.a.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.a.v[0] * mult[0];
               } else {
@@ -11547,14 +9777,12 @@
               }
             }
           }
-
-          flag = true; // Force alignment only works with a single line for now
-
+          flag = true;
+          // Force alignment only works with a single line for now
           if (this._pathData.a.v) {
             currentLength = letters[0].an * 0.5 + (totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind / (len - 1);
             currentLength += this._pathData.f.v;
           }
-
           while (flag) {
             if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
               perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
@@ -11565,11 +9793,9 @@
             } else if (points) {
               segmentLength += currentPoint.partialLength;
               pointInd += 1;
-
               if (pointInd >= points.length) {
                 pointInd = 0;
                 segmentInd += 1;
-
                 if (!segments[segmentInd]) {
                   if (mask.v.c) {
                     pointInd = 0;
@@ -11583,7 +9809,6 @@
                   points = segments[segmentInd].points;
                 }
               }
-
               if (points) {
                 prevPoint = currentPoint;
                 currentPoint = points[pointInd];
@@ -11591,23 +9816,21 @@
               }
             }
           }
-
           offf = letters[i].an / 2 - letters[i].add;
           matrixHelper.translate(-offf, 0, 0);
         } else {
           offf = letters[i].an / 2 - letters[i].add;
-          matrixHelper.translate(-offf, 0, 0); // Grouping alignment
+          matrixHelper.translate(-offf, 0, 0);
 
+          // Grouping alignment
           matrixHelper.translate(-alignment[0] * letters[i].an * 0.005, -alignment[1] * yOff * 0.01, 0);
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.t.propType) {
             animatorSelector = animators[j].s;
-            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars); // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
-
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
             if (xPos !== 0 || documentData.j !== 0) {
               if (this._hasMaskedPath) {
                 if (mult.length) {
@@ -11623,11 +9846,9 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           sw = documentData.sw || 0;
         }
-
         if (documentData.strokeColorAnim) {
           if (documentData.sc) {
             sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
@@ -11635,18 +9856,14 @@
             sc = [0, 0, 0];
           }
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.a.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
             } else {
@@ -11654,14 +9871,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.s.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.scale(1 + (animatorProps.s.v[0] - 1) * mult[0], 1 + (animatorProps.s.v[1] - 1) * mult[1], 1);
             } else {
@@ -11669,12 +9883,10 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
           animatorSelector = animators[j].s;
           mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
           if (animatorProps.sk.propType) {
             if (mult.length) {
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
@@ -11682,7 +9894,6 @@
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
             }
           }
-
           if (animatorProps.r.propType) {
             if (mult.length) {
               matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
@@ -11690,7 +9901,6 @@
               matrixHelper.rotateZ(-animatorProps.r.v * mult);
             }
           }
-
           if (animatorProps.ry.propType) {
             if (mult.length) {
               matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
@@ -11698,7 +9908,6 @@
               matrixHelper.rotateY(animatorProps.ry.v * mult);
             }
           }
-
           if (animatorProps.rx.propType) {
             if (mult.length) {
               matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
@@ -11706,7 +9915,6 @@
               matrixHelper.rotateX(animatorProps.rx.v * mult);
             }
           }
-
           if (animatorProps.o.propType) {
             if (mult.length) {
               elemOpacity += (animatorProps.o.v * mult[0] - elemOpacity) * mult[0];
@@ -11714,7 +9922,6 @@
               elemOpacity += (animatorProps.o.v * mult - elemOpacity) * mult;
             }
           }
-
           if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
             if (mult.length) {
               sw += animatorProps.sw.v * mult[0];
@@ -11722,7 +9929,6 @@
               sw += animatorProps.sw.v * mult;
             }
           }
-
           if (documentData.strokeColorAnim && animatorProps.sc.propType) {
             for (k = 0; k < 3; k += 1) {
               if (mult.length) {
@@ -11732,7 +9938,6 @@
               }
             }
           }
-
           if (documentData.fillColorAnim && documentData.fc) {
             if (animatorProps.fc.propType) {
               for (k = 0; k < 3; k += 1) {
@@ -11743,7 +9948,6 @@
                 }
               }
             }
-
             if (animatorProps.fh.propType) {
               if (mult.length) {
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
@@ -11751,7 +9955,6 @@
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult);
               }
             }
-
             if (animatorProps.fs.propType) {
               if (mult.length) {
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
@@ -11759,7 +9962,6 @@
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
               }
             }
-
             if (animatorProps.fb.propType) {
               if (mult.length) {
                 fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
@@ -11769,14 +9971,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.p.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (this._hasMaskedPath) {
               if (mult.length) {
                 matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
@@ -11790,68 +9989,53 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           letterSw = sw < 0 ? 0 : sw;
         }
-
         if (documentData.strokeColorAnim) {
           letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
         }
-
         if (this._hasMaskedPath) {
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(0, alignment[1] * yOff * 0.01 + yPos, 0);
-
           if (this._pathData.p.v) {
             tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
             var rot = Math.atan(tanAngle) * 180 / Math.PI;
-
             if (currentPoint.point[0] < prevPoint.point[0]) {
               rot += 180;
             }
-
             matrixHelper.rotate(-rot * Math.PI / 180);
           }
-
           matrixHelper.translate(xPathPos, yPathPos, 0);
           currentLength -= alignment[0] * letters[i].an * 0.005;
-
           if (letters[i + 1] && ind !== letters[i + 1].ind) {
             currentLength += letters[i].an / 2;
             currentLength += documentData.tr * 0.001 * documentData.finalSize;
           }
         } else {
           matrixHelper.translate(xPos, yPos, 0);
-
           if (documentData.ps) {
             // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
             matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
           }
-
           switch (documentData.j) {
             case 1:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
               break;
-
             case 2:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
               break;
-
             default:
               break;
           }
-
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(offf, 0, 0);
           matrixHelper.translate(alignment[0] * letters[i].an * 0.005, alignment[1] * yOff * 0.01, 0);
           xPos += letters[i].l + documentData.tr * 0.001 * documentData.finalSize;
         }
-
         if (renderType === 'html') {
           letterM = matrixHelper.toCSS();
         } else if (renderType === 'svg') {
@@ -11859,10 +10043,8 @@
         } else {
           letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
         }
-
         letterO = elemOpacity;
       }
-
       if (renderedLettersCount <= i) {
         letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
         this.renderedLetters.push(letterValue);
@@ -11874,22 +10056,18 @@
       }
     }
   };
-
   TextAnimatorProperty.prototype.getValue = function () {
     if (this._elem.globalData.frameId === this._frameId) {
       return;
     }
-
     this._frameId = this._elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   TextAnimatorProperty.prototype.mHelper = new Matrix();
   TextAnimatorProperty.prototype.defaultPropsArray = [];
   extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
 
   function ITextElement() {}
-
   ITextElement.prototype.initElement = function (data, globalData, comp) {
     this.lettersChangedFlag = true;
     this.initFrame();
@@ -11906,72 +10084,55 @@
     this.hide();
     this.textAnimator.searchProperties(this.dynamicProperties);
   };
-
   ITextElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
   };
-
   ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
     var j;
     var jLen = shapes.length;
     var pathNodes;
     var shapeStr = '';
-
     for (j = 0; j < jLen; j += 1) {
       if (shapes[j].ty === 'sh') {
         pathNodes = shapes[j].ks.k;
         shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
       }
     }
-
     return shapeStr;
   };
-
   ITextElement.prototype.updateDocumentData = function (newData, index) {
     this.textProperty.updateDocumentData(newData, index);
   };
-
   ITextElement.prototype.canResizeFont = function (_canResize) {
     this.textProperty.canResizeFont(_canResize);
   };
-
   ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
     this.textProperty.setMinimumFontSize(_fontSize);
   };
-
   ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
     if (documentData.ps) {
       matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
     }
-
     matrixHelper.translate(0, -documentData.ls, 0);
-
     switch (documentData.j) {
       case 1:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
         break;
-
       case 2:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
         break;
-
       default:
         break;
     }
-
     matrixHelper.translate(xPos, yPos, 0);
   };
-
   ITextElement.prototype.buildColor = function (colorData) {
     return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
   };
-
   ITextElement.prototype.emptyProp = new LetterProps();
-
   ITextElement.prototype.destroy = function () {};
-
   ITextElement.prototype.validateText = function () {
     if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
       this.buildNewText();
@@ -11983,27 +10144,22 @@
   var emptyShapeData = {
     shapes: []
   };
-
   function SVGTextLottieElement(data, globalData, comp) {
     this.textSpans = [];
     this.renderType = 'svg';
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
-
   SVGTextLottieElement.prototype.createContent = function () {
     if (this.data.singleShape && !this.globalData.fontManager.chars) {
       this.textContainer = createNS('text');
     }
   };
-
   SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
     var i = 0;
     var len = textArray.length;
     var textContents = [];
     var currentTextContent = '';
-
     while (i < len) {
       if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
         textContents.push(currentTextContent);
@@ -12011,14 +10167,11 @@
       } else {
         currentTextContent += textArray[i];
       }
-
       i += 1;
     }
-
     textContents.push(currentTextContent);
     return textContents;
   };
-
   SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
     // data should probably be cloned to apply scale separately to each instance of a text on different layers
     // but since text internal content gets only rendered once and then it's never rerendered,
@@ -12026,41 +10179,33 @@
     // Avoiding cloning is preferred since cloning each character shape data is expensive
     if (data.shapes && data.shapes.length) {
       var shape = data.shapes[0];
-
       if (shape.it) {
         var shapeItem = shape.it[shape.it.length - 1];
-
         if (shapeItem.s) {
           shapeItem.s.k[0] = scale;
           shapeItem.s.k[1] = scale;
         }
       }
     }
-
     return data;
   };
-
   SVGTextLottieElement.prototype.buildNewText = function () {
     this.addDynamicProperty(this);
     var i;
     var len;
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
-
     if (documentData.fc) {
       this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
     } else {
       this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
     }
-
     if (documentData.sc) {
       this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
       this.layerElement.setAttribute('stroke-width', documentData.sw);
     }
-
     this.layerElement.setAttribute('font-size', documentData.finalSize);
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
-
     if (fontData.fClass) {
       this.layerElement.setAttribute('class', fontData.fClass);
     } else {
@@ -12070,7 +10215,6 @@
       this.layerElement.setAttribute('font-style', fStyle);
       this.layerElement.setAttribute('font-weight', fWeight);
     }
-
     this.layerElement.setAttribute('aria-label', documentData.t);
     var letters = documentData.l || [];
     var usesGlyphs = !!this.globalData.fontManager.chars;
@@ -12083,31 +10227,25 @@
     var yPos = 0;
     var firstLine = true;
     var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
-
     if (singleShape && !usesGlyphs && !documentData.sz) {
       var tElement = this.textContainer;
       var justify = 'start';
-
       switch (documentData.j) {
         case 1:
           justify = 'end';
           break;
-
         case 2:
           justify = 'middle';
           break;
-
         default:
           justify = 'start';
           break;
       }
-
       tElement.setAttribute('text-anchor', justify);
       tElement.setAttribute('letter-spacing', trackingOffset);
       var textContent = this.buildTextContents(documentData.finalText);
       len = textContent.length;
       yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
-
       for (i = 0; i < len; i += 1) {
         tSpan = this.textSpans[i].span || createNS('tspan');
         tSpan.textContent = textContent[i];
@@ -12115,23 +10253,19 @@
         tSpan.setAttribute('y', yPos);
         tSpan.style.display = 'inherit';
         tElement.appendChild(tSpan);
-
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
             span: null,
             glyph: null
           };
         }
-
         this.textSpans[i].span = tSpan;
         yPos += documentData.finalLineHeight;
       }
-
       this.layerElement.appendChild(tElement);
     } else {
       var cachedSpansLength = this.textSpans.length;
       var charData;
-
       for (i = 0; i < len; i += 1) {
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
@@ -12140,31 +10274,24 @@
             glyph: null
           };
         }
-
         if (!usesGlyphs || !singleShape || i === 0) {
           tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
-
           if (cachedSpansLength <= i) {
             tSpan.setAttribute('stroke-linecap', 'butt');
             tSpan.setAttribute('stroke-linejoin', 'round');
             tSpan.setAttribute('stroke-miterlimit', '4');
             this.textSpans[i].span = tSpan;
-
             if (usesGlyphs) {
               var childSpan = createNS('g');
               tSpan.appendChild(childSpan);
               this.textSpans[i].childSpan = childSpan;
             }
-
             this.textSpans[i].span = tSpan;
             this.layerElement.appendChild(tSpan);
           }
-
           tSpan.style.display = 'inherit';
         }
-
         matrixHelper.reset();
-
         if (singleShape) {
           if (letters[i].n) {
             xPos = -trackingOffset;
@@ -12172,42 +10299,36 @@
             yPos += firstLine ? 1 : 0;
             firstLine = false;
           }
-
           this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
-          xPos += letters[i].l || 0; // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
-
+          xPos += letters[i].l || 0;
+          // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
           xPos += trackingOffset;
         }
-
         if (usesGlyphs) {
           charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
-          var glyphElement; // t === 1 means the character has been replaced with an animated shaped
-
+          var glyphElement;
+          // t === 1 means the character has been replaced with an animated shaped
           if (charData.t === 1) {
             glyphElement = new SVGCompElement(charData.data, this.globalData, this);
           } else {
             var data = emptyShapeData;
-
             if (charData.data && charData.data.shapes) {
               data = this.buildShapeData(charData.data, documentData.finalSize);
             }
-
             glyphElement = new SVGShapeElement(data, this.globalData, this);
           }
-
           if (this.textSpans[i].glyph) {
             var glyph = this.textSpans[i].glyph;
             this.textSpans[i].childSpan.removeChild(glyph.layerElement);
             glyph.destroy();
           }
-
           this.textSpans[i].glyph = glyphElement;
           glyphElement._debug = true;
           glyphElement.prepareFrame(0);
           glyphElement.renderFrame();
-          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement); // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+          // when using animated shapes, the layer will be scaled instead of replacing the internal scale
           // this might have issues with strokes and might need a different solution
-
           if (charData.t === 1) {
             this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
           }
@@ -12215,30 +10336,24 @@
           if (singleShape) {
             tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
           }
-
           tSpan.textContent = letters[i].val;
           tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
-        } //
-
+        }
+        //
       }
-
       if (singleShape && tSpan) {
         tSpan.setAttribute('d', shapeStr);
       }
     }
-
     while (i < this.textSpans.length) {
       this.textSpans[i].span.style.display = 'none';
       i += 1;
     }
-
     this._sizeChanged = true;
   };
-
   SVGTextLottieElement.prototype.sourceRectAtTime = function () {
     this.prepareFrame(this.comp.renderedFrame - this.data.st);
     this.renderInnerContent();
-
     if (this._sizeChanged) {
       this._sizeChanged = false;
       var textBox = this.layerElement.getBBox();
@@ -12249,35 +10364,27 @@
         height: textBox.height
       };
     }
-
     return this.bbox;
   };
-
   SVGTextLottieElement.prototype.getValue = function () {
     var i;
     var len = this.textSpans.length;
     var glyphElement;
     this.renderedFrame = this.comp.renderedFrame;
-
     for (i = 0; i < len; i += 1) {
       glyphElement = this.textSpans[i].glyph;
-
       if (glyphElement) {
         glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
-
         if (glyphElement._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   SVGTextLottieElement.prototype.renderInnerContent = function () {
     this.validateText();
-
     if (!this.data.singleShape || this._mdf) {
       this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
-
       if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
         this._sizeChanged = true;
         var i;
@@ -12288,33 +10395,26 @@
         var renderedLetter;
         var textSpan;
         var glyphElement;
-
         for (i = 0; i < len; i += 1) {
           if (!letters[i].n) {
             renderedLetter = renderedLetters[i];
             textSpan = this.textSpans[i].span;
             glyphElement = this.textSpans[i].glyph;
-
             if (glyphElement) {
               glyphElement.renderFrame();
             }
-
             if (renderedLetter._mdf.m) {
               textSpan.setAttribute('transform', renderedLetter.m);
             }
-
             if (renderedLetter._mdf.o) {
               textSpan.setAttribute('opacity', renderedLetter.o);
             }
-
             if (renderedLetter._mdf.sw) {
               textSpan.setAttribute('stroke-width', renderedLetter.sw);
             }
-
             if (renderedLetter._mdf.sc) {
               textSpan.setAttribute('stroke', renderedLetter.sc);
             }
-
             if (renderedLetter._mdf.fc) {
               textSpan.setAttribute('fill', renderedLetter.fc);
             }
@@ -12327,14 +10427,12 @@
   function ISolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([IImageElement], ISolidElement);
-
   ISolidElement.prototype.createContent = function () {
-    var rect = createNS('rect'); /// /rect.style.width = this.data.sw;
+    var rect = createNS('rect');
+    /// /rect.style.width = this.data.sw;
     /// /rect.style.height = this.data.sh;
     /// /rect.style.fill = this.data.sc;
-
     rect.setAttribute('width', this.data.sw);
     rect.setAttribute('height', this.data.sh);
     rect.setAttribute('fill', this.data.sc);
@@ -12348,59 +10446,43 @@
     this.initTransform(data, globalData, comp);
     this.initHierarchy();
   }
-
   NullElement.prototype.prepareFrame = function (num) {
     this.prepareProperties(num, true);
   };
-
   NullElement.prototype.renderFrame = function () {};
-
   NullElement.prototype.getBaseElement = function () {
     return null;
   };
-
   NullElement.prototype.destroy = function () {};
-
   NullElement.prototype.sourceRectAtTime = function () {};
-
   NullElement.prototype.hide = function () {};
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
 
   function SVGRendererBase() {}
-
   extendPrototype([BaseRenderer], SVGRendererBase);
-
   SVGRendererBase.prototype.createNull = function (data) {
     return new NullElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createShape = function (data) {
     return new SVGShapeElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createText = function (data) {
     return new SVGTextLottieElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createImage = function (data) {
     return new IImageElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createSolid = function (data) {
     return new ISolidElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.configAnimation = function (animData) {
     this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
     this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
-
     if (this.renderConfig.viewBoxSize) {
       this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
     } else {
       this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
     }
-
     if (!this.renderConfig.viewBoxOnly) {
       this.svgElement.setAttribute('width', animData.w);
       this.svgElement.setAttribute('height', animData.h);
@@ -12409,32 +10491,26 @@
       this.svgElement.style.transform = 'translate3d(0,0,0)';
       this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
     }
-
     if (this.renderConfig.width) {
       this.svgElement.setAttribute('width', this.renderConfig.width);
     }
-
     if (this.renderConfig.height) {
       this.svgElement.setAttribute('height', this.renderConfig.height);
     }
-
     if (this.renderConfig.className) {
       this.svgElement.setAttribute('class', this.renderConfig.className);
     }
-
     if (this.renderConfig.id) {
       this.svgElement.setAttribute('id', this.renderConfig.id);
     }
-
     if (this.renderConfig.focusable !== undefined) {
       this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
     }
-
-    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio); // this.layerElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+    // this.layerElement.style.transform = 'translate3d(0,0,0)';
     // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
-
-    this.animationItem.wrapper.appendChild(this.svgElement); // Mask animation
-
+    this.animationItem.wrapper.appendChild(this.svgElement);
+    // Mask animation
     var defs = this.globalData.defs;
     this.setupGlobalData(animData, defs);
     this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
@@ -12453,71 +10529,54 @@
     this.layers = animData.layers;
     this.elements = createSizedArray(animData.layers.length);
   };
-
   SVGRendererBase.prototype.destroy = function () {
     if (this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     this.layerElement = null;
     this.globalData.defs = null;
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.destroyed = true;
     this.animationItem = null;
   };
-
   SVGRendererBase.prototype.updateContainerSize = function () {};
-
   SVGRendererBase.prototype.findIndexByInd = function (ind) {
     var i = 0;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.layers[i].ind === ind) {
         return i;
       }
     }
-
     return -1;
   };
-
   SVGRendererBase.prototype.buildItem = function (pos) {
     var elements = this.elements;
-
     if (elements[pos] || this.layers[pos].ty === 99) {
       return;
     }
-
     elements[pos] = true;
     var element = this.createItem(this.layers[pos]);
     elements[pos] = element;
-
     if (getExpressionsPlugin()) {
       if (this.layers[pos].ty === 0) {
         this.globalData.projectInterface.registerComposition(element);
       }
-
       element.initExpressions();
     }
-
     this.appendElementInPos(element, pos);
-
     if (this.layers[pos].tt) {
       var elementIndex = 'tp' in this.layers[pos] ? this.findIndexByInd(this.layers[pos].tp) : pos - 1;
-
       if (elementIndex === -1) {
         return;
       }
-
       if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
         this.buildItem(elementIndex);
         this.addPendingElement(element);
@@ -12528,16 +10587,13 @@
       }
     }
   };
-
   SVGRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
-
       if (element.data.tt) {
         var i = 0;
         var len = this.elements.length;
-
         while (i < len) {
           if (this.elements[i] === element) {
             var elementIndex = 'tp' in element.data ? this.findIndexByInd(element.data.tp) : i - 1;
@@ -12546,43 +10602,36 @@
             element.setMatte(matteMask);
             break;
           }
-
           i += 1;
         }
       }
     }
   };
-
   SVGRendererBase.prototype.renderFrame = function (num) {
     if (this.renderedFrame === num || this.destroyed) {
       return;
     }
-
     if (num === null) {
       num = this.renderedFrame;
     } else {
       this.renderedFrame = num;
-    } // console.log('-------');
+    }
+    // console.log('-------');
     // console.log('FRAME ',num);
-
-
     this.globalData.frameNum = num;
     this.globalData.frameId += 1;
     this.globalData.projectInterface.currentFrame = num;
     this.globalData._mdf = false;
     var i;
     var len = this.layers.length;
-
     if (!this.completeLayers) {
       this.checkLayers(num);
     }
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(num - this.layers[i].st);
       }
     }
-
     if (this.globalData._mdf) {
       for (i = 0; i < len; i += 1) {
         if (this.completeLayers || this.elements[i]) {
@@ -12591,44 +10640,34 @@
       }
     }
   };
-
   SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
     var newElement = element.getBaseElement();
-
     if (!newElement) {
       return;
     }
-
     var i = 0;
     var nextElement;
-
     while (i < pos) {
       if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
         nextElement = this.elements[i].getBaseElement();
       }
-
       i += 1;
     }
-
     if (nextElement) {
       this.layerElement.insertBefore(newElement, nextElement);
     } else {
       this.layerElement.appendChild(newElement);
     }
   };
-
   SVGRendererBase.prototype.hide = function () {
     this.layerElement.style.display = 'none';
   };
-
   SVGRendererBase.prototype.show = function () {
     this.layerElement.style.display = 'block';
   };
 
   function ICompElement() {}
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
-
   ICompElement.prototype.initElement = function (data, globalData, comp) {
     this.initFrame();
     this.initBaseData(data, globalData, comp);
@@ -12638,13 +10677,12 @@
     this.initRendererElement();
     this.createContainerElements();
     this.createRenderableComponents();
-
     if (this.data.xt || !globalData.progressiveLoad) {
       this.buildAllItems();
     }
-
     this.hide();
   };
+
   /* ICompElement.prototype.hide = function(){
       if(!this.hidden){
           this.hideElement();
@@ -12657,77 +10695,61 @@
       }
   }; */
 
-
   ICompElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
-
     if (!this.isInRange && !this.data.xt) {
       return;
     }
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
-
       if (timeRemapped === this.data.op) {
         timeRemapped = this.data.op - 1;
       }
-
       this.renderedFrame = timeRemapped;
     } else {
       this.renderedFrame = num / this.data.sr;
     }
-
     var i;
     var len = this.elements.length;
-
     if (!this.completeLayers) {
       this.checkLayers(this.renderedFrame);
-    } // This iteration needs to be backwards because of how expressions connect between each other
-
-
+    }
+    // This iteration needs to be backwards because of how expressions connect between each other
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
-
         if (this.elements[i]._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   ICompElement.prototype.renderInnerContent = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].renderFrame();
       }
     }
   };
-
   ICompElement.prototype.setElements = function (elems) {
     this.elements = elems;
   };
-
   ICompElement.prototype.getElements = function () {
     return this.elements;
   };
-
   ICompElement.prototype.destroyElements = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i]) {
         this.elements[i].destroy();
       }
     }
   };
-
   ICompElement.prototype.destroy = function () {
     this.destroyElements();
     this.destroyBaseElement();
@@ -12744,9 +10766,7 @@
       _placeholder: true
     };
   }
-
   extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
-
   SVGCompElement.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
@@ -12757,7 +10777,6 @@
     this.renderedFrame = -1;
     this.svgElement = createNS('svg');
     var ariaLabel = '';
-
     if (config && config.title) {
       var titleElement = createNS('title');
       var titleId = createElementID();
@@ -12766,7 +10785,6 @@
       this.svgElement.appendChild(titleElement);
       ariaLabel += titleId;
     }
-
     if (config && config.description) {
       var descElement = createNS('desc');
       var descId = createElementID();
@@ -12775,11 +10793,9 @@
       this.svgElement.appendChild(descElement);
       ariaLabel += ' ' + descId;
     }
-
     if (ariaLabel) {
       this.svgElement.setAttribute('aria-labelledby', ariaLabel);
     }
-
     var defs = createNS('defs');
     this.svgElement.appendChild(defs);
     var maskElement = createNS('g');
@@ -12817,63 +10833,50 @@
     this.destroyed = false;
     this.rendererType = 'svg';
   }
-
   extendPrototype([SVGRendererBase], SVGRenderer);
-
   SVGRenderer.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
 
   var registeredEffects = {};
-
   function CVEffects(elem) {
     var i;
     var len = elem.data.ef ? elem.data.ef.length : 0;
     this.filters = [];
     var filterManager;
-
     for (i = 0; i < len; i += 1) {
       filterManager = null;
       var type = elem.data.ef[i].ty;
-
       if (registeredEffects[type]) {
         var Effect = registeredEffects[type].effect;
         filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
       }
-
       if (filterManager) {
         this.filters.push(filterManager);
       }
     }
-
     if (this.filters.length) {
       elem.addRenderableComponent(this);
     }
   }
-
   CVEffects.prototype.renderFrame = function (_isFirstFrame) {
     var i;
     var len = this.filters.length;
-
     for (i = 0; i < len; i += 1) {
       this.filters[i].renderFrame(_isFirstFrame);
     }
   };
-
   CVEffects.prototype.getEffects = function (type) {
     var i;
     var len = this.filters.length;
     var effects = [];
-
     for (i = 0; i < len; i += 1) {
       if (this.filters[i].type === type) {
         effects.push(this.filters[i]);
       }
     }
-
     return effects;
   };
-
   function registerEffect(id, effect) {
     registeredEffects[id] = {
       effect: effect
@@ -12881,12 +10884,10 @@
   }
 
   function HBaseElement() {}
-
   HBaseElement.prototype = {
     checkBlendMode: function checkBlendMode() {},
     initRendererElement: function initRendererElement() {
       this.baseElement = createTag(this.data.tg || 'div');
-
       if (this.data.hasMask) {
         this.svgElement = createNS('svg');
         this.layerElement = createNS('g');
@@ -12896,35 +10897,29 @@
       } else {
         this.layerElement = this.baseElement;
       }
-
       styleDiv(this.baseElement);
     },
     createContainerElements: function createContainerElements() {
       this.renderableEffectsManager = new CVEffects(this);
       this.transformedElement = this.baseElement;
       this.maskedElement = this.layerElement;
-
       if (this.data.ln) {
         this.layerElement.setAttribute('id', this.data.ln);
       }
-
       if (this.data.cl) {
         this.layerElement.setAttribute('class', this.data.cl);
       }
-
       if (this.data.bm !== 0) {
         this.setBlendMode();
       }
     },
     renderElement: function renderElement() {
       var transformedElementStyle = this.transformedElement ? this.transformedElement.style : {};
-
       if (this.finalTransform._matMdf) {
         var matrixValue = this.finalTransform.mat.toCSS();
         transformedElementStyle.transform = matrixValue;
         transformedElementStyle.webkitTransform = matrixValue;
       }
-
       if (this.finalTransform._opMdf) {
         transformedElementStyle.opacity = this.finalTransform.mProp.o.v;
       }
@@ -12935,12 +10930,10 @@
       if (this.data.hd || this.hidden) {
         return;
       }
-
       this.renderTransform();
       this.renderRenderable();
       this.renderElement();
       this.renderInnerContent();
-
       if (this._isFirstFrame) {
         this._isFirstFrame = false;
       }
@@ -12948,11 +10941,9 @@
     destroy: function destroy() {
       this.layerElement = null;
       this.transformedElement = null;
-
       if (this.matteElement) {
         this.matteElement = null;
       }
-
       if (this.maskManager) {
         this.maskManager.destroy();
         this.maskManager = null;
@@ -12971,12 +10962,9 @@
   function HSolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], HSolidElement);
-
   HSolidElement.prototype.createContent = function () {
     var rect;
-
     if (this.data.hasMask) {
       rect = createNS('rect');
       rect.setAttribute('width', this.data.sw);
@@ -12990,29 +10978,28 @@
       rect.style.height = this.data.sh + 'px';
       rect.style.backgroundColor = this.data.sc;
     }
-
     this.layerElement.appendChild(rect);
   };
 
   function HShapeElement(data, globalData, comp) {
     // List of drawable elements
-    this.shapes = []; // Full shape data
-
-    this.shapesData = data.shapes; // List of styles that will be applied to shapes
-
-    this.stylesList = []; // List of modifiers that will be applied to shapes
-
-    this.shapeModifiers = []; // List of items in shape tree
-
-    this.itemsData = []; // List of items in previous shape tree
-
-    this.processedElements = []; // List of animated components
-
+    this.shapes = [];
+    // Full shape data
+    this.shapesData = data.shapes;
+    // List of styles that will be applied to shapes
+    this.stylesList = [];
+    // List of modifiers that will be applied to shapes
+    this.shapeModifiers = [];
+    // List of items in shape tree
+    this.itemsData = [];
+    // List of items in previous shape tree
+    this.processedElements = [];
+    // List of animated components
     this.animatedContents = [];
     this.shapesContainer = createNS('g');
-    this.initElement(data, globalData, comp); // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.initElement(data, globalData, comp);
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
     // List of elements that have been created
-
     this.prevViewData = [];
     this.currentBBox = {
       x: 999999,
@@ -13021,14 +11008,11 @@
       w: 0
     };
   }
-
   extendPrototype([BaseElement, TransformElement, HSolidElement, SVGShapeElement, HBaseElement, HierarchyElement, FrameElement, RenderableElement], HShapeElement);
   HShapeElement.prototype._renderShapeFrame = HShapeElement.prototype.renderInnerContent;
-
   HShapeElement.prototype.createContent = function () {
     var cont;
     this.baseElement.style.fontSize = 0;
-
     if (this.data.hasMask) {
       this.layerElement.appendChild(this.shapesContainer);
       cont = this.svgElement;
@@ -13040,23 +11024,18 @@
       cont.appendChild(this.shapesContainer);
       this.layerElement.appendChild(cont);
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.shapesContainer, 0, [], true);
     this.filterUniqueShapes();
     this.shapeCont = cont;
   };
-
   HShapeElement.prototype.getTransformedPoint = function (transformers, point) {
     var i;
     var len = transformers.length;
-
     for (i = 0; i < len; i += 1) {
       point = transformers[i].mProps.v.applyToPointArray(point[0], point[1], 0);
     }
-
     return point;
   };
-
   HShapeElement.prototype.calculateShapeBoundingBox = function (item, boundingBox) {
     var shape = item.sh.v;
     var transformers = item.transformers;
@@ -13066,11 +11045,9 @@
     var oPoint;
     var nextIPoint;
     var nextVPoint;
-
     if (len <= 1) {
       return;
     }
-
     for (i = 0; i < len - 1; i += 1) {
       vPoint = this.getTransformedPoint(transformers, shape.v[i]);
       oPoint = this.getTransformedPoint(transformers, shape.o[i]);
@@ -13078,7 +11055,6 @@
       nextVPoint = this.getTransformedPoint(transformers, shape.v[i + 1]);
       this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
     }
-
     if (shape.c) {
       vPoint = this.getTransformedPoint(transformers, shape.v[i]);
       oPoint = this.getTransformedPoint(transformers, shape.o[i]);
@@ -13087,7 +11063,6 @@
       this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
     }
   };
-
   HShapeElement.prototype.checkBounds = function (vPoint, oPoint, nextIPoint, nextVPoint, boundingBox) {
     this.getBoundsOfCurve(vPoint, oPoint, nextIPoint, nextVPoint);
     var bounds = this.shapeBoundingBox;
@@ -13096,7 +11071,6 @@
     boundingBox.y = bmMin(bounds.top, boundingBox.y);
     boundingBox.yMax = bmMax(bounds.bottom, boundingBox.yMax);
   };
-
   HShapeElement.prototype.shapeBoundingBox = {
     left: 0,
     right: 0,
@@ -13111,31 +11085,26 @@
     width: 0,
     height: 0
   };
-
   HShapeElement.prototype.getBoundsOfCurve = function (p0, p1, p2, p3) {
     var bounds = [[p0[0], p3[0]], [p0[1], p3[1]]];
-
     for (var a, b, c, t, b2ac, t1, t2, i = 0; i < 2; ++i) {
       // eslint-disable-line no-plusplus
       b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];
       a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];
       c = 3 * p1[i] - 3 * p0[i];
       b |= 0; // eslint-disable-line no-bitwise
-
       a |= 0; // eslint-disable-line no-bitwise
-
       c |= 0; // eslint-disable-line no-bitwise
 
-      if (a === 0 && b === 0) {//
+      if (a === 0 && b === 0) {
+        //
       } else if (a === 0) {
         t = -c / b;
-
         if (t > 0 && t < 1) {
           bounds[i].push(this.calculateF(t, p0, p1, p2, p3, i));
         }
       } else {
         b2ac = b * b - 4 * c * a;
-
         if (b2ac >= 0) {
           t1 = (-b + bmSqrt(b2ac)) / (2 * a);
           if (t1 > 0 && t1 < 1) bounds[i].push(this.calculateF(t1, p0, p1, p2, p3, i));
@@ -13144,21 +11113,17 @@
         }
       }
     }
-
     this.shapeBoundingBox.left = bmMin.apply(null, bounds[0]);
     this.shapeBoundingBox.top = bmMin.apply(null, bounds[1]);
     this.shapeBoundingBox.right = bmMax.apply(null, bounds[0]);
     this.shapeBoundingBox.bottom = bmMax.apply(null, bounds[1]);
   };
-
   HShapeElement.prototype.calculateF = function (t, p0, p1, p2, p3, i) {
     return bmPow(1 - t, 3) * p0[i] + 3 * bmPow(1 - t, 2) * t * p1[i] + 3 * (1 - t) * bmPow(t, 2) * p2[i] + bmPow(t, 3) * p3[i];
   };
-
   HShapeElement.prototype.calculateBoundingBox = function (itemsData, boundingBox) {
     var i;
     var len = itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       if (itemsData[i] && itemsData[i].sh) {
         this.calculateShapeBoundingBox(itemsData[i], boundingBox);
@@ -13169,37 +11134,29 @@
       }
     }
   };
-
   HShapeElement.prototype.expandStrokeBoundingBox = function (widthProperty, boundingBox) {
     var width = 0;
-
     if (widthProperty.keyframes) {
       for (var i = 0; i < widthProperty.keyframes.length; i += 1) {
         var kfw = widthProperty.keyframes[i].s;
-
         if (kfw > width) {
           width = kfw;
         }
       }
-
       width *= widthProperty.mult;
     } else {
       width = widthProperty.v * widthProperty.mult;
     }
-
     boundingBox.x -= width;
     boundingBox.xMax += width;
     boundingBox.y -= width;
     boundingBox.yMax += width;
   };
-
   HShapeElement.prototype.currentBoxContains = function (box) {
     return this.currentBBox.x <= box.x && this.currentBBox.y <= box.y && this.currentBBox.width + this.currentBBox.x >= box.x + box.width && this.currentBBox.height + this.currentBBox.y >= box.y + box.height;
   };
-
   HShapeElement.prototype.renderInnerContent = function () {
     this._renderShapeFrame();
-
     if (!this.hidden && (this._isFirstFrame || this._mdf)) {
       var tempBoundingBox = this.tempBoundingBox;
       var max = 999999;
@@ -13209,26 +11166,22 @@
       tempBoundingBox.yMax = -max;
       this.calculateBoundingBox(this.itemsData, tempBoundingBox);
       tempBoundingBox.width = tempBoundingBox.xMax < tempBoundingBox.x ? 0 : tempBoundingBox.xMax - tempBoundingBox.x;
-      tempBoundingBox.height = tempBoundingBox.yMax < tempBoundingBox.y ? 0 : tempBoundingBox.yMax - tempBoundingBox.y; // var tempBoundingBox = this.shapeCont.getBBox();
-
+      tempBoundingBox.height = tempBoundingBox.yMax < tempBoundingBox.y ? 0 : tempBoundingBox.yMax - tempBoundingBox.y;
+      // var tempBoundingBox = this.shapeCont.getBBox();
       if (this.currentBoxContains(tempBoundingBox)) {
         return;
       }
-
       var changed = false;
-
       if (this.currentBBox.w !== tempBoundingBox.width) {
         this.currentBBox.w = tempBoundingBox.width;
         this.shapeCont.setAttribute('width', tempBoundingBox.width);
         changed = true;
       }
-
       if (this.currentBBox.h !== tempBoundingBox.height) {
         this.currentBBox.h = tempBoundingBox.height;
         this.shapeCont.setAttribute('height', tempBoundingBox.height);
         changed = true;
       }
-
       if (changed || this.currentBBox.x !== tempBoundingBox.x || this.currentBBox.y !== tempBoundingBox.y) {
         this.currentBBox.w = tempBoundingBox.width;
         this.currentBBox.h = tempBoundingBox.height;
@@ -13256,12 +11209,9 @@
     this.isMasked = false;
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], HTextElement);
-
   HTextElement.prototype.createContent = function () {
     this.isMasked = this.checkMasks();
-
     if (this.isMasked) {
       this.renderType = 'svg';
       this.compW = this.comp.data.w;
@@ -13275,10 +11225,8 @@
       this.renderType = 'html';
       this.innerElem = this.layerElement;
     }
-
     this.checkParenting();
   };
-
   HTextElement.prototype.buildNewText = function () {
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
@@ -13286,18 +11234,14 @@
     var textColor = documentData.fc ? this.buildColor(documentData.fc) : 'rgba(0,0,0,0)';
     innerElemStyle.fill = textColor;
     innerElemStyle.color = textColor;
-
     if (documentData.sc) {
       innerElemStyle.stroke = this.buildColor(documentData.sc);
       innerElemStyle.strokeWidth = documentData.sw + 'px';
     }
-
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
-
     if (!this.globalData.fontManager.chars) {
       innerElemStyle.fontSize = documentData.finalSize + 'px';
       innerElemStyle.lineHeight = documentData.finalSize + 'px';
-
       if (fontData.fClass) {
         this.innerElem.className = fontData.fClass;
       } else {
@@ -13308,7 +11252,6 @@
         innerElemStyle.fontWeight = fWeight;
       }
     }
-
     var i;
     var len;
     var letters = documentData.l;
@@ -13320,7 +11263,6 @@
     var shapes;
     var shapeStr = '';
     var cnt = 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.globalData.fontManager.chars) {
         if (!this.textPaths[cnt]) {
@@ -13331,7 +11273,6 @@
         } else {
           tSpan = this.textPaths[cnt];
         }
-
         if (!this.isMasked) {
           if (this.textSpans[cnt]) {
             tParent = this.textSpans[cnt];
@@ -13357,31 +11298,25 @@
         }
       } else {
         tSpan = this.textPaths[cnt] ? this.textPaths[cnt] : createNS('text');
-      } // tSpan.setAttribute('visibility', 'hidden');
-
-
+      }
+      // tSpan.setAttribute('visibility', 'hidden');
       if (this.globalData.fontManager.chars) {
         var charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
         var shapeData;
-
         if (charData) {
           shapeData = charData.data;
         } else {
           shapeData = null;
         }
-
         matrixHelper.reset();
-
         if (shapeData && shapeData.shapes && shapeData.shapes.length) {
           shapes = shapeData.shapes[0].it;
           matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
           shapeStr = this.createPathShape(matrixHelper, shapes);
           tSpan.setAttribute('d', shapeStr);
         }
-
         if (!this.isMasked) {
           this.innerElem.appendChild(tParent);
-
           if (shapeData && shapeData.shapes) {
             // document.body.appendChild is needed to get exact measure of shape
             document.body.appendChild(tCont);
@@ -13398,7 +11333,6 @@
             tCont.setAttribute('width', 1);
             tCont.setAttribute('height', 1);
           }
-
           tParent.appendChild(tCont);
         } else {
           this.innerElem.appendChild(tSpan);
@@ -13406,10 +11340,9 @@
       } else {
         tSpan.textContent = letters[i].val;
         tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
-
         if (!this.isMasked) {
-          this.innerElem.appendChild(tParent); //
-
+          this.innerElem.appendChild(tParent);
+          //
           var tStyle = tSpan.style;
           var tSpanTranslation = 'translate3d(0,' + -documentData.finalSize / 1.2 + 'px,0)';
           tStyle.transform = tSpanTranslation;
@@ -13417,35 +11350,29 @@
         } else {
           this.innerElem.appendChild(tSpan);
         }
-      } //
-
-
+      }
+      //
       if (!this.isMasked) {
         this.textSpans[cnt] = tParent;
       } else {
         this.textSpans[cnt] = tSpan;
       }
-
       this.textSpans[cnt].style.display = 'block';
       this.textPaths[cnt] = tSpan;
       cnt += 1;
     }
-
     while (cnt < this.textSpans.length) {
       this.textSpans[cnt].style.display = 'none';
       cnt += 1;
     }
   };
-
   HTextElement.prototype.renderInnerContent = function () {
     this.validateText();
     var svgStyle;
-
     if (this.data.singleShape) {
       if (!this._isFirstFrame && !this.lettersChangedFlag) {
         return;
       }
-
       if (this.isMasked && this.finalTransform._matMdf) {
         // Todo Benchmark if using this is better than getBBox
         this.svgElement.setAttribute('viewBox', -this.finalTransform.mProp.p.v[0] + ' ' + -this.finalTransform.mProp.p.v[1] + ' ' + this.compW + ' ' + this.compH);
@@ -13455,13 +11382,10 @@
         svgStyle.webkitTransform = translation;
       }
     }
-
     this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
-
     if (!this.lettersChangedFlag && !this.textAnimator.lettersChangedFlag) {
       return;
     }
-
     var i;
     var len;
     var count = 0;
@@ -13471,7 +11395,6 @@
     var renderedLetter;
     var textSpan;
     var textPath;
-
     for (i = 0; i < len; i += 1) {
       if (letters[i].n) {
         count += 1;
@@ -13480,7 +11403,6 @@
         textPath = this.textPaths[i];
         renderedLetter = renderedLetters[count];
         count += 1;
-
         if (renderedLetter._mdf.m) {
           if (!this.isMasked) {
             textSpan.style.webkitTransform = renderedLetter.m;
@@ -13488,41 +11410,32 @@
           } else {
             textSpan.setAttribute('transform', renderedLetter.m);
           }
-        } /// /textSpan.setAttribute('opacity',renderedLetter.o);
-
-
+        }
+        /// /textSpan.setAttribute('opacity',renderedLetter.o);
         textSpan.style.opacity = renderedLetter.o;
-
         if (renderedLetter.sw && renderedLetter._mdf.sw) {
           textPath.setAttribute('stroke-width', renderedLetter.sw);
         }
-
         if (renderedLetter.sc && renderedLetter._mdf.sc) {
           textPath.setAttribute('stroke', renderedLetter.sc);
         }
-
         if (renderedLetter.fc && renderedLetter._mdf.fc) {
           textPath.setAttribute('fill', renderedLetter.fc);
           textPath.style.color = renderedLetter.fc;
         }
       }
     }
-
     if (this.innerElem.getBBox && !this.hidden && (this._isFirstFrame || this._mdf)) {
       var boundingBox = this.innerElem.getBBox();
-
       if (this.currentBBox.w !== boundingBox.width) {
         this.currentBBox.w = boundingBox.width;
         this.svgElement.setAttribute('width', boundingBox.width);
       }
-
       if (this.currentBBox.h !== boundingBox.height) {
         this.currentBBox.h = boundingBox.height;
         this.svgElement.setAttribute('height', boundingBox.height);
       }
-
       var margin = 1;
-
       if (this.currentBBox.w !== boundingBox.width + margin * 2 || this.currentBBox.h !== boundingBox.height + margin * 2 || this.currentBBox.x !== boundingBox.x - margin || this.currentBBox.y !== boundingBox.y - margin) {
         this.currentBBox.w = boundingBox.width + margin * 2;
         this.currentBBox.h = boundingBox.height + margin * 2;
@@ -13543,7 +11456,6 @@
     this.initHierarchy();
     var getProp = PropertyFactory.getProp;
     this.pe = getProp(this, data.pe, 0, 0, this);
-
     if (data.ks.p.s) {
       this.px = getProp(this, data.ks.p.x, 1, 0, this);
       this.py = getProp(this, data.ks.p.y, 1, 0, this);
@@ -13551,21 +11463,17 @@
     } else {
       this.p = getProp(this, data.ks.p, 1, 0, this);
     }
-
     if (data.ks.a) {
       this.a = getProp(this, data.ks.a, 1, 0, this);
     }
-
     if (data.ks.or.k.length && data.ks.or.k[0].to) {
       var i;
       var len = data.ks.or.k.length;
-
       for (i = 0; i < len; i += 1) {
         data.ks.or.k[i].to = null;
         data.ks.or.k[i].ti = null;
       }
     }
-
     this.or = getProp(this, data.ks.or, 1, degToRads, this);
     this.or.sh = true;
     this.rx = getProp(this, data.ks.rx, 0, degToRads, this);
@@ -13573,26 +11481,23 @@
     this.rz = getProp(this, data.ks.rz, 0, degToRads, this);
     this.mat = new Matrix();
     this._prevMat = new Matrix();
-    this._isFirstFrame = true; // TODO: find a better way to make the HCamera element to be compatible with the LayerInterface and TransformInterface.
+    this._isFirstFrame = true;
 
+    // TODO: find a better way to make the HCamera element to be compatible with the LayerInterface and TransformInterface.
     this.finalTransform = {
       mProp: this
     };
   }
-
   extendPrototype([BaseElement, FrameElement, HierarchyElement], HCameraElement);
-
   HCameraElement.prototype.setup = function () {
     var i;
     var len = this.comp.threeDElements.length;
     var comp;
     var perspectiveStyle;
     var containerStyle;
-
     for (i = 0; i < len; i += 1) {
       // [perspectiveElem,container]
       comp = this.comp.threeDElements[i];
-
       if (comp.type === '3d') {
         perspectiveStyle = comp.perspectiveElem.style;
         containerStyle = comp.container.style;
@@ -13609,30 +11514,22 @@
       }
     }
   };
-
   HCameraElement.prototype.createElements = function () {};
-
   HCameraElement.prototype.hide = function () {};
-
   HCameraElement.prototype.renderFrame = function () {
     var _mdf = this._isFirstFrame;
     var i;
     var len;
-
     if (this.hierarchy) {
       len = this.hierarchy.length;
-
       for (i = 0; i < len; i += 1) {
         _mdf = this.hierarchy[i].finalTransform.mProp._mdf || _mdf;
       }
     }
-
     if (_mdf || this.pe._mdf || this.p && this.p._mdf || this.px && (this.px._mdf || this.py._mdf || this.pz._mdf) || this.rx._mdf || this.ry._mdf || this.rz._mdf || this.or._mdf || this.a && this.a._mdf) {
       this.mat.reset();
-
       if (this.hierarchy) {
         len = this.hierarchy.length - 1;
-
         for (i = len; i >= 0; i -= 1) {
           var mTransf = this.hierarchy[i].finalTransform.mProp;
           this.mat.translate(-mTransf.p.v[0], -mTransf.p.v[1], mTransf.p.v[2]);
@@ -13642,46 +11539,38 @@
           this.mat.translate(mTransf.a.v[0], mTransf.a.v[1], mTransf.a.v[2]);
         }
       }
-
       if (this.p) {
         this.mat.translate(-this.p.v[0], -this.p.v[1], this.p.v[2]);
       } else {
         this.mat.translate(-this.px.v, -this.py.v, this.pz.v);
       }
-
       if (this.a) {
         var diffVector;
-
         if (this.p) {
           diffVector = [this.p.v[0] - this.a.v[0], this.p.v[1] - this.a.v[1], this.p.v[2] - this.a.v[2]];
         } else {
           diffVector = [this.px.v - this.a.v[0], this.py.v - this.a.v[1], this.pz.v - this.a.v[2]];
         }
-
-        var mag = Math.sqrt(Math.pow(diffVector[0], 2) + Math.pow(diffVector[1], 2) + Math.pow(diffVector[2], 2)); // var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
-
+        var mag = Math.sqrt(Math.pow(diffVector[0], 2) + Math.pow(diffVector[1], 2) + Math.pow(diffVector[2], 2));
+        // var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
         var lookDir = [diffVector[0] / mag, diffVector[1] / mag, diffVector[2] / mag];
         var lookLengthOnXZ = Math.sqrt(lookDir[2] * lookDir[2] + lookDir[0] * lookDir[0]);
         var mRotationX = Math.atan2(lookDir[1], lookLengthOnXZ);
         var mRotationY = Math.atan2(lookDir[0], -lookDir[2]);
         this.mat.rotateY(mRotationY).rotateX(-mRotationX);
       }
-
       this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v);
       this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]);
       this.mat.translate(this.globalData.compSize.w / 2, this.globalData.compSize.h / 2, 0);
       this.mat.translate(0, 0, this.pe.v);
       var hasMatrixChanged = !this._prevMat.equals(this.mat);
-
       if ((hasMatrixChanged || this.pe._mdf) && this.comp.threeDElements) {
         len = this.comp.threeDElements.length;
         var comp;
         var perspectiveStyle;
         var containerStyle;
-
         for (i = 0; i < len; i += 1) {
           comp = this.comp.threeDElements[i];
-
           if (comp.type === '3d') {
             if (hasMatrixChanged) {
               var matValue = this.mat.toCSS();
@@ -13689,7 +11578,6 @@
               containerStyle.transform = matValue;
               containerStyle.webkitTransform = matValue;
             }
-
             if (this.pe._mdf) {
               perspectiveStyle = comp.perspectiveElem.style;
               perspectiveStyle.perspective = this.pe.v + 'px';
@@ -13697,20 +11585,15 @@
             }
           }
         }
-
         this.mat.clone(this._prevMat);
       }
     }
-
     this._isFirstFrame = false;
   };
-
   HCameraElement.prototype.prepareFrame = function (num) {
     this.prepareProperties(num, true);
   };
-
   HCameraElement.prototype.destroy = function () {};
-
   HCameraElement.prototype.getBaseElement = function () {
     return null;
   };
@@ -13719,13 +11602,10 @@
     this.assetData = globalData.getAssetData(data.refId);
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, HBaseElement, HSolidElement, HierarchyElement, FrameElement, RenderableElement], HImageElement);
-
   HImageElement.prototype.createContent = function () {
     var assetPath = this.globalData.getAssetsPath(this.assetData);
     var img = new Image();
-
     if (this.data.hasMask) {
       this.imageElem = createNS('image');
       this.imageElem.setAttribute('width', this.assetData.w + 'px');
@@ -13737,10 +11617,8 @@
     } else {
       this.layerElement.appendChild(img);
     }
-
     img.crossOrigin = 'anonymous';
     img.src = assetPath;
-
     if (this.data.ln) {
       this.baseElement.setAttribute('id', this.data.ln);
     }
@@ -13774,26 +11652,20 @@
     this.supports3d = true;
     this.rendererType = 'html';
   }
-
   extendPrototype([BaseRenderer], HybridRendererBase);
   HybridRendererBase.prototype.buildItem = SVGRenderer.prototype.buildItem;
-
   HybridRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
     }
   };
-
   HybridRendererBase.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);
@@ -13802,17 +11674,14 @@
         var nextDOMElement;
         var nextLayer;
         var 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);
@@ -13825,61 +11694,46 @@
       this.addTo3dContainer(newDOMElement, pos);
     }
   };
-
   HybridRendererBase.prototype.createShape = function (data) {
     if (!this.supports3d) {
       return new SVGShapeElement(data, this.globalData, this);
     }
-
     return new HShapeElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createText = function (data) {
     if (!this.supports3d) {
       return new SVGTextLottieElement(data, this.globalData, this);
     }
-
     return new HTextElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createCamera = function (data) {
     this.camera = new HCameraElement(data, this.globalData, this);
     return this.camera;
   };
-
   HybridRendererBase.prototype.createImage = function (data) {
     if (!this.supports3d) {
       return new IImageElement(data, this.globalData, this);
     }
-
     return new HImageElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createSolid = function (data) {
     if (!this.supports3d) {
       return new ISolidElement(data, this.globalData, this);
     }
-
     return new HSolidElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
-
   HybridRendererBase.prototype.getThreeDContainerByPos = function (pos) {
     var i = 0;
     var 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;
     }
-
     return null;
   };
-
   HybridRendererBase.prototype.createThreeDContainer = function (pos, type) {
     var perspectiveElem = createTag('div');
     var style;
@@ -13887,7 +11741,6 @@
     styleDiv(perspectiveElem);
     var container = createTag('div');
     styleDiv(container);
-
     if (type === '3d') {
       style = perspectiveElem.style;
       style.width = this.globalData.compSize.w + 'px';
@@ -13901,9 +11754,8 @@
       containerStyle.transform = matrix;
       containerStyle.webkitTransform = matrix;
     }
-
-    perspectiveElem.appendChild(container); // this.resizerElem.appendChild(perspectiveElem);
-
+    perspectiveElem.appendChild(container);
+    // this.resizerElem.appendChild(perspectiveElem);
     var threeDContainerData = {
       container: container,
       perspectiveElem: perspectiveElem,
@@ -13914,68 +11766,54 @@
     this.threeDElements.push(threeDContainerData);
     return threeDContainerData;
   };
-
   HybridRendererBase.prototype.build3dContainers = function () {
     var i;
     var 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 -= 1) {
       this.resizerElem.appendChild(this.threeDElements[i].perspectiveElem);
     }
   };
-
   HybridRendererBase.prototype.addTo3dContainer = function (elem, pos) {
     var i = 0;
     var 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;
     }
   };
-
   HybridRendererBase.prototype.configAnimation = function (animData) {
     var resizerElem = createTag('div');
     var wrapper = this.animationItem.wrapper;
@@ -13987,11 +11825,9 @@
     style.transformStyle = 'flat';
     style.mozTransformStyle = 'flat';
     style.webkitTransformStyle = 'flat';
-
     if (this.renderConfig.className) {
       resizerElem.setAttribute('class', this.renderConfig.className);
     }
-
     wrapper.appendChild(resizerElem);
     style.overflow = 'hidden';
     var svg = createNS('svg');
@@ -14001,8 +11837,8 @@
     this.resizerElem.appendChild(svg);
     var defs = createNS('defs');
     svg.appendChild(defs);
-    this.data = animData; // Mask animation
-
+    this.data = animData;
+    // Mask animation
     this.setupGlobalData(animData, svg);
     this.globalData.defs = defs;
     this.layers = animData.layers;
@@ -14010,28 +11846,23 @@
     this.build3dContainers();
     this.updateContainerSize();
   };
-
   HybridRendererBase.prototype.destroy = function () {
     if (this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     this.animationItem.container = null;
     this.globalData.defs = null;
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.destroyed = true;
     this.animationItem = null;
   };
-
   HybridRendererBase.prototype.updateContainerSize = function () {
     var elementWidth = this.animationItem.wrapper.offsetWidth;
     var elementHeight = this.animationItem.wrapper.offsetHeight;
@@ -14041,7 +11872,6 @@
     var sy;
     var tx;
     var ty;
-
     if (animationRel > elementRel) {
       sx = elementWidth / this.globalData.compSize.w;
       sy = elementWidth / this.globalData.compSize.w;
@@ -14053,25 +11883,19 @@
       tx = (elementWidth - this.globalData.compSize.w * (elementHeight / this.globalData.compSize.h)) / 2;
       ty = 0;
     }
-
     var style = this.resizerElem.style;
     style.webkitTransform = 'matrix3d(' + sx + ',0,0,0,0,' + sy + ',0,0,0,0,1,0,' + tx + ',' + ty + ',0,1)';
     style.transform = style.webkitTransform;
   };
-
   HybridRendererBase.prototype.renderFrame = SVGRenderer.prototype.renderFrame;
-
   HybridRendererBase.prototype.hide = function () {
     this.resizerElem.style.display = 'none';
   };
-
   HybridRendererBase.prototype.show = function () {
     this.resizerElem.style.display = 'block';
   };
-
   HybridRendererBase.prototype.initItems = function () {
     this.buildAllItems();
-
     if (this.camera) {
       this.camera.setup();
     } else {
@@ -14079,7 +11903,6 @@
       var cHeight = this.globalData.compSize.h;
       var i;
       var len = this.threeDElements.length;
-
       for (i = 0; i < len; i += 1) {
         var style = this.threeDElements[i].perspectiveElem.style;
         style.webkitPerspective = Math.sqrt(Math.pow(cWidth, 2) + Math.pow(cHeight, 2)) + 'px';
@@ -14087,12 +11910,10 @@
       }
     }
   };
-
   HybridRendererBase.prototype.searchExtraCompositions = function (assets) {
     var i;
     var 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);
@@ -14113,14 +11934,11 @@
       _placeholder: true
     };
   }
-
   extendPrototype([HybridRendererBase, ICompElement, HBaseElement], HCompElement);
   HCompElement.prototype._createBaseContainerElements = HCompElement.prototype.createContainerElements;
-
   HCompElement.prototype.createContainerElements = function () {
-    this._createBaseContainerElements(); // divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
-
-
+    this._createBaseContainerElements();
+    // divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
     if (this.data.hasMask) {
       this.svgElement.setAttribute('width', this.data.w);
       this.svgElement.setAttribute('height', this.data.h);
@@ -14129,31 +11947,25 @@
       this.transformedElement = this.layerElement;
     }
   };
-
   HCompElement.prototype.addTo3dContainer = function (elem, pos) {
     var j = 0;
     var nextElement;
-
     while (j < pos) {
       if (this.elements[j] && this.elements[j].getBaseElement) {
         nextElement = this.elements[j].getBaseElement();
       }
-
       j += 1;
     }
-
     if (nextElement) {
       this.layerElement.insertBefore(elem, nextElement);
     } else {
       this.layerElement.appendChild(elem);
     }
   };
-
   HCompElement.prototype.createComp = function (data) {
     if (!this.supports3d) {
       return new SVGCompElement(data, this.globalData, this);
     }
-
     return new HCompElement(data, this.globalData, this);
   };
 
@@ -14186,19 +11998,18 @@
     this.supports3d = true;
     this.rendererType = 'html';
   }
-
   extendPrototype([HybridRendererBase], HybridRenderer);
-
   HybridRenderer.prototype.createComp = function (data) {
     if (!this.supports3d) {
       return new SVGCompElement(data, this.globalData, this);
     }
-
     return new HCompElement(data, this.globalData, this);
   };
 
-  registerRenderer('html', HybridRenderer); // Registering shape modifiers
+  // Registering renderers
+  registerRenderer('html', HybridRenderer);
 
+  // Registering shape modifiers
   ShapeModifiers.registerModifier('tm', TrimModifier);
   ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
   ShapeModifiers.registerModifier('rp', RepeaterModifier);
diff --git a/build/player/lottie_light_html.min.js b/build/player/lottie_light_html.min.js
index 21a4c54..8c8a2ef 100644
--- a/build/player/lottie_light_html.min.js
+++ b/build/player/lottie_light_html.min.js
@@ -1 +1 @@
-"undefined"!=typeof navigator&&function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lottie=e()}(this,(function(){"use strict";var t="",e=!1,i=-999999,s=function(){return t};function a(t){return document.createElement(t)}function r(t,e){var i,s,a=t.length;for(i=0;i<a;i+=1)for(var r in s=t[i].prototype)Object.prototype.hasOwnProperty.call(s,r)&&(e.prototype[r]=s[r])}function n(t){function e(){}return e.prototype=t,e}var h=function(){function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].pause()},resume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].resume()},setRate:function(t){var e,i=this.audios.length;for(e=0;e<i;e+=1)this.audios[e].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}}(),o=function(){function t(t,e){var i,s=0,a=[];switch(t){case"int16":case"uint8c":i=1;break;default:i=1.1}for(s=0;s<e;s+=1)a.push(i);return a}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(e,i){return"float32"===e?new Float32Array(i):"int16"===e?new Int16Array(i):"uint8c"===e?new Uint8ClampedArray(i):t(e,i)}:t}();function l(t){return Array.apply(null,{length:t})}function p(t){return p="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},p(t)}var f=!0,m=null,d=null,c="",u=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),g=Math.pow,y=Math.sqrt,v=Math.floor,b=Math.max,_=Math.min,x={};!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],i=e.length;for(t=0;t<i;t+=1)x[e[t]]=Math[e[t]]}(),x.random=Math.random,x.abs=function(t){if("object"===p(t)&&t.length){var e,i=l(t.length),s=t.length;for(e=0;e<s;e+=1)i[e]=Math.abs(t[e]);return i}return Math.abs(t)};var k=150,w=Math.PI/180,P=.5519;function S(t){!!t}function A(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin="0 0",t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility="visible",t.style.webkitBackfaceVisibility="visible",t.style.transformStyle="preserve-3d",t.style.webkitTransformStyle="preserve-3d",t.style.mozTransformStyle="preserve-3d"}function D(t,e,i,s){this.type=t,this.currentTime=e,this.totalTime=i,this.direction=s<0?-1:1}function C(t,e){this.type=t,this.direction=e<0?-1:1}function E(t,e,i,s){this.type=t,this.currentLoop=i,this.totalLoops=e,this.direction=s<0?-1:1}function M(t,e,i){this.type=t,this.firstFrame=e,this.totalFrames=i}function T(t,e){this.type=t,this.target=e}function F(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function I(t){this.type="configError",this.nativeError=t}var L,B=(L=0,function(){return c+"__lottie_element_"+(L+=1)});function z(t,e,i){var s,a,r,n,h,o,l,p;switch(o=i*(1-e),l=i*(1-(h=6*t-(n=Math.floor(6*t)))*e),p=i*(1-(1-h)*e),n%6){case 0:s=i,a=p,r=o;break;case 1:s=l,a=i,r=o;break;case 2:s=o,a=i,r=p;break;case 3:s=o,a=l,r=i;break;case 4:s=p,a=o,r=i;break;case 5:s=i,a=o,r=l}return[s,a,r]}function V(t,e,i){var s,a=Math.max(t,e,i),r=Math.min(t,e,i),n=a-r,h=0===a?0:n/a,o=a/255;switch(a){case r:s=0;break;case t:s=e-i+n*(e<i?6:0),s/=6*n;break;case e:s=i-t+2*n,s/=6*n;break;case i:s=t-e+4*n,s/=6*n}return[s,h,o]}function R(t,e){var i=V(255*t[0],255*t[1],255*t[2]);return i[1]+=e,i[1]>1?i[1]=1:i[1]<=0&&(i[1]=0),z(i[0],i[1],i[2])}function O(t,e){var i=V(255*t[0],255*t[1],255*t[2]);return i[2]+=e,i[2]>1?i[2]=1:i[2]<0&&(i[2]=0),z(i[0],i[1],i[2])}function N(t,e){var i=V(255*t[0],255*t[1],255*t[2]);return i[0]+=e/360,i[0]>1?i[0]-=1:i[0]<0&&(i[0]+=1),z(i[0],i[1],i[2])}!function(){var t,e,i=[];for(t=0;t<256;t+=1)e=t.toString(16),i[t]=1===e.length?"0"+e:e}();var q=function(){return m},j=function(){return d},W=function(t){k=t},H=function(){return k};function X(t){return document.createElementNS("http://www.w3.org/2000/svg",t)}function Y(t){return Y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Y(t)}var G=function(){var t,i,s=1,a=[],r={onmessage:function(){},postMessage:function(e){t({data:e})}},n={postMessage:function(t){r.onmessage({data:t})}};function h(i){if(window.Worker&&window.Blob&&e){var s=new Blob(["var _workerSelf = self; self.onmessage = ",i.toString()],{type:"text/javascript"}),a=URL.createObjectURL(s);return new Worker(a)}return t=i,r}function o(){i||(i=h((function(t){if(n.dataManager||(n.dataManager=function(){function t(a,r){var n,h,o,l,p,m,d=a.length;for(h=0;h<d;h+=1)if("ks"in(n=a[h])&&!n.completed){if(n.completed=!0,n.hasMask){var c=n.masksProperties;for(l=c.length,o=0;o<l;o+=1)if(c[o].pt.k.i)s(c[o].pt.k);else for(m=c[o].pt.k.length,p=0;p<m;p+=1)c[o].pt.k[p].s&&s(c[o].pt.k[p].s[0]),c[o].pt.k[p].e&&s(c[o].pt.k[p].e[0])}0===n.ty?(n.layers=e(n.refId,r),t(n.layers,r)):4===n.ty?i(n.shapes):5===n.ty&&f(n)}}function e(t,e){var i=function(t,e){for(var i=0,s=e.length;i<s;){if(e[i].id===t)return e[i];i+=1}return null}(t,e);return i?i.layers.__used?JSON.parse(JSON.stringify(i.layers)):(i.layers.__used=!0,i.layers):null}function i(t){var e,a,r;for(e=t.length-1;e>=0;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)s(t[e].ks.k);else for(r=t[e].ks.k.length,a=0;a<r;a+=1)t[e].ks.k[a].s&&s(t[e].ks.k[a].s[0]),t[e].ks.k[a].e&&s(t[e].ks.k[a].e[0]);else"gr"===t[e].ty&&i(t[e].it)}function s(t){var e,i=t.i.length;for(e=0;e<i;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function a(t,e){var i=e?e.split("."):[100,100,100];return t[0]>i[0]||!(i[0]>t[0])&&(t[1]>i[1]||!(i[1]>t[1])&&(t[2]>i[2]||!(i[2]>t[2])&&null))}var r,n=function(){var t=[4,4,14];function e(t){var e,i,s,a=t.length;for(e=0;e<a;e+=1)5===t[e].ty&&(s=void 0,s=(i=t[e]).t.d,i.t.d={k:[{s:s,t:0}]})}return function(i){if(a(t,i.v)&&(e(i.layers),i.assets)){var s,r=i.assets.length;for(s=0;s<r;s+=1)i.assets[s].layers&&e(i.assets[s].layers)}}}(),h=(r=[4,7,99],function(t){if(t.chars&&!a(r,t.v)){var e,s=t.chars.length;for(e=0;e<s;e+=1){var n=t.chars[e];n.data&&n.data.shapes&&(i(n.data.shapes),n.data.ip=0,n.data.op=99999,n.data.st=0,n.data.sr=1,n.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[e].t||(n.data.shapes.push({ty:"no"}),n.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}}}),o=function(){var t=[5,7,15];function e(t){var e,i,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(i=void 0,"number"==typeof(i=t[e].t.p).a&&(i.a={a:0,k:i.a}),"number"==typeof i.p&&(i.p={a:0,k:i.p}),"number"==typeof i.r&&(i.r={a:0,k:i.r}))}return function(i){if(a(t,i.v)&&(e(i.layers),i.assets)){var s,r=i.assets.length;for(s=0;s<r;s+=1)i.assets[s].layers&&e(i.assets[s].layers)}}}(),l=function(){var t=[4,1,9];function e(t){var i,s,a,r=t.length;for(i=0;i<r;i+=1)if("gr"===t[i].ty)e(t[i].it);else if("fl"===t[i].ty||"st"===t[i].ty)if(t[i].c.k&&t[i].c.k[0].i)for(a=t[i].c.k.length,s=0;s<a;s+=1)t[i].c.k[s].s&&(t[i].c.k[s].s[0]/=255,t[i].c.k[s].s[1]/=255,t[i].c.k[s].s[2]/=255,t[i].c.k[s].s[3]/=255),t[i].c.k[s].e&&(t[i].c.k[s].e[0]/=255,t[i].c.k[s].e[1]/=255,t[i].c.k[s].e[2]/=255,t[i].c.k[s].e[3]/=255);else t[i].c.k[0]/=255,t[i].c.k[1]/=255,t[i].c.k[2]/=255,t[i].c.k[3]/=255}function i(t){var i,s=t.length;for(i=0;i<s;i+=1)4===t[i].ty&&e(t[i].shapes)}return function(e){if(a(t,e.v)&&(i(e.layers),e.assets)){var s,r=e.assets.length;for(s=0;s<r;s+=1)e.assets[s].layers&&i(e.assets[s].layers)}}}(),p=function(){var t=[4,4,18];function e(t){var i,s,a;for(i=t.length-1;i>=0;i-=1)if("sh"===t[i].ty)if(t[i].ks.k.i)t[i].ks.k.c=t[i].closed;else for(a=t[i].ks.k.length,s=0;s<a;s+=1)t[i].ks.k[s].s&&(t[i].ks.k[s].s[0].c=t[i].closed),t[i].ks.k[s].e&&(t[i].ks.k[s].e[0].c=t[i].closed);else"gr"===t[i].ty&&e(t[i].it)}function i(t){var i,s,a,r,n,h,o=t.length;for(s=0;s<o;s+=1){if((i=t[s]).hasMask){var l=i.masksProperties;for(r=l.length,a=0;a<r;a+=1)if(l[a].pt.k.i)l[a].pt.k.c=l[a].cl;else for(h=l[a].pt.k.length,n=0;n<h;n+=1)l[a].pt.k[n].s&&(l[a].pt.k[n].s[0].c=l[a].cl),l[a].pt.k[n].e&&(l[a].pt.k[n].e[0].c=l[a].cl)}4===i.ty&&e(i.shapes)}}return function(e){if(a(t,e.v)&&(i(e.layers),e.assets)){var s,r=e.assets.length;for(s=0;s<r;s+=1)e.assets[s].layers&&i(e.assets[s].layers)}}}();function f(t){0===t.t.a.length&&t.t.p}var m={completeData:function(i){i.__complete||(l(i),n(i),h(i),o(i),p(i),t(i.layers,i.assets),function(i,s){if(i){var a=0,r=i.length;for(a=0;a<r;a+=1)1===i[a].t&&(i[a].data.layers=e(i[a].data.refId,s),t(i[a].data.layers,s))}}(i.chars,i.assets),i.__complete=!0)}};return m.checkColors=l,m.checkChars=h,m.checkPathProperties=o,m.checkShapes=p,m.completeLayers=t,m}()),n.assetLoader||(n.assetLoader=function(){function t(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")||t.response&&"object"===Y(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}return{load:function(e,i,s,a){var r,n=new XMLHttpRequest;try{n.responseType="json"}catch(t){}n.onreadystatechange=function(){if(4===n.readyState)if(200===n.status)r=t(n),s(r);else try{r=t(n),s(r)}catch(t){a&&a(t)}};try{n.open(["G","E","T"].join(""),e,!0)}catch(t){n.open(["G","E","T"].join(""),i+"/"+e,!0)}n.send()}}}()),"loadAnimation"===t.data.type)n.assetLoader.load(t.data.path,t.data.fullPath,(function(e){n.dataManager.completeData(e),n.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){n.postMessage({id:t.data.id,status:"error"})}));else if("complete"===t.data.type){var e=t.data.animation;n.dataManager.completeData(e),n.postMessage({id:t.data.id,payload:e,status:"success"})}else"loadData"===t.data.type&&n.assetLoader.load(t.data.path,t.data.fullPath,(function(e){n.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){n.postMessage({id:t.data.id,status:"error"})}))})),i.onmessage=function(t){var e=t.data,i=e.id,s=a[i];a[i]=null,"success"===e.status?s.onComplete(e.payload):s.onError&&s.onError()})}function l(t,e){var i="processId_"+(s+=1);return a[i]={onComplete:t,onError:e},i}return{loadAnimation:function(t,e,s){o();var a=l(e,s);i.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:a})},loadData:function(t,e,s){o();var a=l(e,s);i.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:a})},completeAnimation:function(t,e,s){o();var a=l(e,s);i.postMessage({type:"complete",animation:t,id:a})}}}(),K=function(){var t=function(){var t=a("canvas");t.width=1,t.height=1;var e=t.getContext("2d");return e.fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1),t}();function e(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function i(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function s(t,e,i){var s="";if(t.e)s=t.p;else if(e){var a=t.p;-1!==a.indexOf("images/")&&(a=a.split("/")[1]),s=e+a}else s=i,s+=t.u?t.u:"",s+=t.p;return s}function r(t){var e=0,i=setInterval(function(){(t.getBBox().width||e>500)&&(this._imageLoaded(),clearInterval(i)),e+=1}.bind(this),50)}function n(t){var e={assetData:t},i=s(t,this.assetsPath,this.path);return G.loadData(i,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}function h(){this._imageLoaded=e.bind(this),this._footageLoaded=i.bind(this),this.testImageLoaded=r.bind(this),this.createFootageData=n.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return h.prototype={loadAssets:function(t,e){var i;this.imagesLoadedCb=e;var s=t.length;for(i=0;i<s;i+=1)t[i].layers||(t[i].t&&"seq"!==t[i].t?3===t[i].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[i]))):(this.totalImages+=1,this.images.push(this._createImageData(t[i]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,i=this.images.length;e<i;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(e){var i=s(e,this.assetsPath,this.path),r=a("img");r.crossOrigin="anonymous",r.addEventListener("load",this._imageLoaded,!1),r.addEventListener("error",function(){n.img=t,this._imageLoaded()}.bind(this),!1),r.src=i;var n={img:r,assetData:e};return n},createImageData:function(e){var i=s(e,this.assetsPath,this.path),a=X("image");u?this.testImageLoaded(a):a.addEventListener("load",this._imageLoaded,!1),a.addEventListener("error",function(){r.img=t,this._imageLoaded()}.bind(this),!1),a.setAttributeNS("http://www.w3.org/1999/xlink","href",i),this._elementHelper.append?this._elementHelper.append(a):this._elementHelper.appendChild(a);var r={img:a,assetData:e};return r},imageLoaded:e,footageLoaded:i,setCacheType:function(t,e){"svg"===t?(this._elementHelper=e,this._createImageData=this.createImageData.bind(this)):this._createImageData=this.createImgData.bind(this)}},h}();function J(){}J.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var i=this._cbs[t],s=0;s<i.length;s+=1)i[s](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var i=0,s=this._cbs[t].length;i<s;)this._cbs[t][i]===e&&(this._cbs[t].splice(i,1),i-=1,s-=1),i+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var Z=function(){function t(t){for(var e,i=t.split("\r\n"),s={},a=0,r=0;r<i.length;r+=1)2===(e=i[r].split(":")).length&&(s[e[0]]=e[1].trim(),a+=1);if(0===a)throw new Error;return s}return function(e){for(var i=[],s=0;s<e.length;s+=1){var a=e[s],r={time:a.tm,duration:a.dr};try{r.payload=JSON.parse(e[s].cm)}catch(i){try{r.payload=t(e[s].cm)}catch(t){r.payload={name:e[s].cm}}}i.push(r)}return i}}(),U=function(){function t(t){this.compositions.push(t)}return function(){function e(t){for(var e=0,i=this.compositions.length;e<i;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return e.compositions=[],e.currentFrame=0,e.registerComposition=t,e}}(),Q={};function $(t){return $="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},$(t)}var tt=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=B(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=f,this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=U(),this.imagePreloader=new K,this.audioController=h(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new D("drawnFrame",0,0,0),this.expressionsPlugin=q()};r([J],tt),tt.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg";t.animType?e=t.animType:t.renderer&&(e=t.renderer);var i=Q[e];this.renderer=new i(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||void 0===t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),G.loadAnimation(t.path,this.configAnimation,this.onSetupError))},tt.prototype.onSetupError=function(){this.trigger("data_failed")},tt.prototype.setupAnimation=function(t){G.completeAnimation(t,this.configAnimation)},tt.prototype.setData=function(t,e){e&&"object"!==$(e)&&(e=JSON.parse(e));var i={wrapper:t,animationData:e},s=t.attributes;i.path=s.getNamedItem("data-animation-path")?s.getNamedItem("data-animation-path").value:s.getNamedItem("data-bm-path")?s.getNamedItem("data-bm-path").value:s.getNamedItem("bm-path")?s.getNamedItem("bm-path").value:"",i.animType=s.getNamedItem("data-anim-type")?s.getNamedItem("data-anim-type").value:s.getNamedItem("data-bm-type")?s.getNamedItem("data-bm-type").value:s.getNamedItem("bm-type")?s.getNamedItem("bm-type").value:s.getNamedItem("data-bm-renderer")?s.getNamedItem("data-bm-renderer").value:s.getNamedItem("bm-renderer")?s.getNamedItem("bm-renderer").value:function(){if(Q.canvas)return"canvas";for(var t in Q)if(Q[t])return t;return""}()||"canvas";var a=s.getNamedItem("data-anim-loop")?s.getNamedItem("data-anim-loop").value:s.getNamedItem("data-bm-loop")?s.getNamedItem("data-bm-loop").value:s.getNamedItem("bm-loop")?s.getNamedItem("bm-loop").value:"";"false"===a?i.loop=!1:"true"===a?i.loop=!0:""!==a&&(i.loop=parseInt(a,10));var r=s.getNamedItem("data-anim-autoplay")?s.getNamedItem("data-anim-autoplay").value:s.getNamedItem("data-bm-autoplay")?s.getNamedItem("data-bm-autoplay").value:!s.getNamedItem("bm-autoplay")||s.getNamedItem("bm-autoplay").value;i.autoplay="false"!==r,i.name=s.getNamedItem("data-name")?s.getNamedItem("data-name").value:s.getNamedItem("data-bm-name")?s.getNamedItem("data-bm-name").value:s.getNamedItem("bm-name")?s.getNamedItem("bm-name").value:"","false"===(s.getNamedItem("data-anim-prerender")?s.getNamedItem("data-anim-prerender").value:s.getNamedItem("data-bm-prerender")?s.getNamedItem("data-bm-prerender").value:s.getNamedItem("bm-prerender")?s.getNamedItem("bm-prerender").value:"")&&(i.prerender=!1),i.path?this.setParams(i):this.trigger("destroy")},tt.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,i,s=this.animationData.layers,a=s.length,r=t.layers,n=r.length;for(i=0;i<n;i+=1)for(e=0;e<a;){if(s[e].id===r[i].id){s[e]=r[i];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(a=t.assets.length,e=0;e<a;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,G.completeAnimation(this.animationData,this.onSegmentComplete)},tt.prototype.onSegmentComplete=function(t){this.animationData=t;var e=q();e&&e.initExpressions(this),this.loadNextSegment()},tt.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var i=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,G.loadData(i,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},tt.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},tt.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},tt.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},tt.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=Z(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},tt.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},tt.prototype.checkLoaded=function(){if(!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()){this.isLoaded=!0;var t=q();t&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play()}},tt.prototype.resize=function(t,e){var i="number"==typeof t?t:void 0,s="number"==typeof e?e:void 0;this.renderer.updateContainerSize(i,s)},tt.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},tt.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},tt.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},tt.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},tt.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},tt.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},tt.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},tt.prototype.getMarkerData=function(t){for(var e,i=0;i<this.markers.length;i+=1)if((e=this.markers[i]).payload&&e.payload.name===t)return e;return null},tt.prototype.goToAndStop=function(t,e,i){if(!i||this.name===i){var s=Number(t);if(isNaN(s)){var a=this.getMarkerData(t);a&&this.goToAndStop(a.time,!0)}else e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier);this.pause()}},tt.prototype.goToAndPlay=function(t,e,i){if(!i||this.name===i){var s=Number(t);if(isNaN(s)){var a=this.getMarkerData(t);a&&(a.duration?this.playSegments([a.time,a.time+a.duration],!0):this.goToAndStop(a.time,!0))}else this.goToAndStop(s,e,i);this.play()}},tt.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,i=!1;e>=this.totalFrames-1&&this.frameModifier>0?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(i=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(i=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),i&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},tt.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(this.frameModifier>0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},tt.prototype.setSegment=function(t,e){var i=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?i=t:this.currentRawFrame+this.firstFrame>e&&(i=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==i&&this.goToAndStop(i,!0)},tt.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===$(t[0])){var i,s=t.length;for(i=0;i<s;i+=1)this.segments.push(t[i])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},tt.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},tt.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},tt.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},tt.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},tt.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},tt.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},tt.prototype.setLoop=function(t){this.loop=t},tt.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},tt.prototype.getVolume=function(){return this.audioController.getVolume()},tt.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},tt.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},tt.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},tt.prototype.getPath=function(){return this.path},tt.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var i=t.p;-1!==i.indexOf("images/")&&(i=i.split("/")[1]),e=this.assetsPath+i}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},tt.prototype.getAssetData=function(t){for(var e=0,i=this.assets.length;e<i;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},tt.prototype.hide=function(){this.renderer.hide()},tt.prototype.show=function(){this.renderer.show()},tt.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},tt.prototype.updateDocumentData=function(t,e,i){try{this.renderer.getElementByPath(t).updateDocumentData(e,i)}catch(t){}},tt.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new D(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new E(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new C(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new M(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new T(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new D(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new E(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new C(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new M(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new T(t,this))},tt.prototype.triggerRenderFrameError=function(t){var e=new F(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)},tt.prototype.triggerConfigError=function(t){var e=new I(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)};var et=function(){var t={},e=[],i=0,s=0,r=0,n=!0,h=!1;function o(t){for(var i=0,a=t.target;i<s;)e[i].animation===a&&(e.splice(i,1),i-=1,s-=1,a.isPaused||f()),i+=1}function l(t,i){if(!t)return null;for(var a=0;a<s;){if(e[a].elem===t&&null!==e[a].elem)return e[a].animation;a+=1}var r=new tt;return m(r,t),r.setData(t,i),r}function p(){r+=1,u()}function f(){r-=1}function m(t,i){t.addEventListener("destroy",o),t.addEventListener("_active",p),t.addEventListener("_idle",f),e.push({elem:i,animation:t}),s+=1}function d(t){var a,o=t-i;for(a=0;a<s;a+=1)e[a].animation.advanceTime(o);i=t,r&&!h?window.requestAnimationFrame(d):n=!0}function c(t){i=t,window.requestAnimationFrame(d)}function u(){!h&&r&&n&&(window.requestAnimationFrame(c),n=!1)}return t.registerAnimation=l,t.loadAnimation=function(t){var e=new tt;return m(e,null),e.setParams(t),e},t.setSpeed=function(t,i){var a;for(a=0;a<s;a+=1)e[a].animation.setSpeed(t,i)},t.setDirection=function(t,i){var a;for(a=0;a<s;a+=1)e[a].animation.setDirection(t,i)},t.play=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.play(t)},t.pause=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.pause(t)},t.stop=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.stop(t)},t.togglePause=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.togglePause(t)},t.searchAnimations=function(t,e,i){var s,r=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),n=r.length;for(s=0;s<n;s+=1)i&&r[s].setAttribute("data-bm-type",i),l(r[s],t);if(e&&0===n){i||(i="svg");var h=document.getElementsByTagName("body")[0];h.innerText="";var o=a("div");o.style.width="100%",o.style.height="100%",o.setAttribute("data-bm-type",i),h.appendChild(o),l(o,t)}},t.resize=function(){var t;for(t=0;t<s;t+=1)e[t].animation.resize()},t.goToAndStop=function(t,i,a){var r;for(r=0;r<s;r+=1)e[r].animation.goToAndStop(t,i,a)},t.destroy=function(t){var i;for(i=s-1;i>=0;i-=1)e[i].animation.destroy(t)},t.freeze=function(){h=!0},t.unfreeze=function(){h=!1,u()},t.setVolume=function(t,i){var a;for(a=0;a<s;a+=1)e[a].animation.setVolume(t,i)},t.mute=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.mute(t)},t.unmute=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.unmute(t)},t.getRegisteredAnimations=function(){var t,i=e.length,s=[];for(t=0;t<i;t+=1)s.push(e[t].animation);return s},t}(),it=function(){var t={getBezierEasing:function(t,i,s,a,r){var n=r||("bez_"+t+"_"+i+"_"+s+"_"+a).replace(/\./g,"p");if(e[n])return e[n];var h=new l([t,i,s,a]);return e[n]=h,h}},e={};var i=.1,s="function"==typeof Float32Array;function a(t,e){return 1-3*e+3*t}function r(t,e){return 3*e-6*t}function n(t){return 3*t}function h(t,e,i){return((a(e,i)*t+r(e,i))*t+n(e))*t}function o(t,e,i){return 3*a(e,i)*t*t+2*r(e,i)*t+n(e)}function l(t){this._p=t,this._mSampleValues=s?new Float32Array(11):new Array(11),this._precomputed=!1,this.get=this.get.bind(this)}return l.prototype={get:function(t){var e=this._p[0],i=this._p[1],s=this._p[2],a=this._p[3];return this._precomputed||this._precompute(),e===i&&s===a?t:0===t?0:1===t?1:h(this._getTForX(t),i,a)},_precompute:function(){var t=this._p[0],e=this._p[1],i=this._p[2],s=this._p[3];this._precomputed=!0,t===e&&i===s||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],s=0;s<11;++s)this._mSampleValues[s]=h(s*i,t,e)},_getTForX:function(t){for(var e=this._p[0],s=this._p[2],a=this._mSampleValues,r=0,n=1;10!==n&&a[n]<=t;++n)r+=i;var l=r+(t-a[--n])/(a[n+1]-a[n])*i,p=o(l,e,s);return p>=.001?function(t,e,i,s){for(var a=0;a<4;++a){var r=o(e,i,s);if(0===r)return e;e-=(h(e,i,s)-t)/r}return e}(t,l,e,s):0===p?l:function(t,e,i,s,a){var r,n,o=0;do{(r=h(n=e+(i-e)/2,s,a)-t)>0?i=n:e=n}while(Math.abs(r)>1e-7&&++o<10);return n}(t,r,r+i,e,s)}},t}(),st={double:function(t){return t.concat(l(t.length))}},at=function(t,e,i){var s=0,a=t,r=l(a);return{newElement:function(){return s?r[s-=1]:e()},release:function(t){s===a&&(r=st.double(r),a*=2),i&&i(t),r[s]=t,s+=1}}},rt=at(8,(function(){return{addedLength:0,percents:o("float32",H()),lengths:o("float32",H())}})),nt=at(8,(function(){return{lengths:[],totalLength:0}}),(function(t){var e,i=t.lengths.length;for(e=0;e<i;e+=1)rt.release(t.lengths[e]);t.lengths.length=0}));var ht=function(){var t=Math;function e(t,e,i,s,a,r){var n=t*s+e*a+i*r-a*s-r*t-i*e;return n>-.001&&n<.001}var i=function(t,e,i,s){var a,r,n,h,o,l,p=H(),f=0,m=[],d=[],c=rt.newElement();for(n=i.length,a=0;a<p;a+=1){for(o=a/(p-1),l=0,r=0;r<n;r+=1)h=g(1-o,3)*t[r]+3*g(1-o,2)*o*i[r]+3*(1-o)*g(o,2)*s[r]+g(o,3)*e[r],m[r]=h,null!==d[r]&&(l+=g(m[r]-d[r],2)),d[r]=m[r];l&&(f+=l=y(l)),c.percents[a]=o,c.lengths[a]=f}return c.addedLength=f,c};function s(t){this.segmentLength=0,this.points=new Array(t)}function a(t,e){this.partialLength=t,this.point=e}var r,n=(r={},function(t,i,n,h){var o=(t[0]+"_"+t[1]+"_"+i[0]+"_"+i[1]+"_"+n[0]+"_"+n[1]+"_"+h[0]+"_"+h[1]).replace(/\./g,"p");if(!r[o]){var p,f,m,d,c,u,v,b=H(),_=0,x=null;2===t.length&&(t[0]!==i[0]||t[1]!==i[1])&&e(t[0],t[1],i[0],i[1],t[0]+n[0],t[1]+n[1])&&e(t[0],t[1],i[0],i[1],i[0]+h[0],i[1]+h[1])&&(b=2);var k=new s(b);for(m=n.length,p=0;p<b;p+=1){for(v=l(m),c=p/(b-1),u=0,f=0;f<m;f+=1)d=g(1-c,3)*t[f]+3*g(1-c,2)*c*(t[f]+n[f])+3*(1-c)*g(c,2)*(i[f]+h[f])+g(c,3)*i[f],v[f]=d,null!==x&&(u+=g(v[f]-x[f],2));_+=u=y(u),k.points[p]=new a(u,v),x=v}k.segmentLength=_,r[o]=k}return r[o]});function h(t,e){var i=e.percents,s=e.lengths,a=i.length,r=v((a-1)*t),n=t*e.addedLength,h=0;if(r===a-1||0===r||n===s[r])return i[r];for(var o=s[r]>n?-1:1,l=!0;l;)if(s[r]<=n&&s[r+1]>n?(h=(n-s[r])/(s[r+1]-s[r]),l=!1):r+=o,r<0||r>=a-1){if(r===a-1)return i[r];l=!1}return i[r]+(i[r+1]-i[r])*h}var p=o("float32",8);return{getSegmentsLength:function(t){var e,s=nt.newElement(),a=t.c,r=t.v,n=t.o,h=t.i,o=t._length,l=s.lengths,p=0;for(e=0;e<o-1;e+=1)l[e]=i(r[e],r[e+1],n[e],h[e+1]),p+=l[e].addedLength;return a&&o&&(l[e]=i(r[e],r[0],n[e],h[0]),p+=l[e].addedLength),s.totalLength=p,s},getNewSegment:function(e,i,s,a,r,n,o){r<0?r=0:r>1&&(r=1);var l,f=h(r,o),m=h(n=n>1?1:n,o),d=e.length,c=1-f,u=1-m,g=c*c*c,y=f*c*c*3,v=f*f*c*3,b=f*f*f,_=c*c*u,x=f*c*u+c*f*u+c*c*m,k=f*f*u+c*f*m+f*c*m,w=f*f*m,P=c*u*u,S=f*u*u+c*m*u+c*u*m,A=f*m*u+c*m*m+f*u*m,D=f*m*m,C=u*u*u,E=m*u*u+u*m*u+u*u*m,M=m*m*u+u*m*m+m*u*m,T=m*m*m;for(l=0;l<d;l+=1)p[4*l]=t.round(1e3*(g*e[l]+y*s[l]+v*a[l]+b*i[l]))/1e3,p[4*l+1]=t.round(1e3*(_*e[l]+x*s[l]+k*a[l]+w*i[l]))/1e3,p[4*l+2]=t.round(1e3*(P*e[l]+S*s[l]+A*a[l]+D*i[l]))/1e3,p[4*l+3]=t.round(1e3*(C*e[l]+E*s[l]+M*a[l]+T*i[l]))/1e3;return p},getPointInSegment:function(e,i,s,a,r,n){var o=h(r,n),l=1-o;return[t.round(1e3*(l*l*l*e[0]+(o*l*l+l*o*l+l*l*o)*s[0]+(o*o*l+l*o*o+o*l*o)*a[0]+o*o*o*i[0]))/1e3,t.round(1e3*(l*l*l*e[1]+(o*l*l+l*o*l+l*l*o)*s[1]+(o*o*l+l*o*o+o*l*o)*a[1]+o*o*o*i[1]))/1e3]},buildBezierData:n,pointOnLine2D:e,pointOnLine3D:function(i,s,a,r,n,h,o,l,p){if(0===a&&0===h&&0===p)return e(i,s,r,n,o,l);var f,m=t.sqrt(t.pow(r-i,2)+t.pow(n-s,2)+t.pow(h-a,2)),d=t.sqrt(t.pow(o-i,2)+t.pow(l-s,2)+t.pow(p-a,2)),c=t.sqrt(t.pow(o-r,2)+t.pow(l-n,2)+t.pow(p-h,2));return(f=m>d?m>c?m-d-c:c-d-m:c>d?c-d-m:d-m-c)>-1e-4&&f<1e-4}}}(),ot=i,lt=Math.abs;function pt(t,e){var i,s=this.offsetTime;"multidimensional"===this.propType&&(i=o("float32",this.pv.length));for(var a,r,n,h,l,p,f,m,d,c=e.lastIndex,u=c,g=this.keyframes.length-1,y=!0;y;){if(a=this.keyframes[u],r=this.keyframes[u+1],u===g-1&&t>=r.t-s){a.h&&(a=r),c=0;break}if(r.t-s>t){c=u;break}u<g-1?u+=1:(c=0,y=!1)}n=this.keyframesMetadata[u]||{};var v,b,_,x,k,P,S,A,D,C,E=r.t-s,M=a.t-s;if(a.to){n.bezierData||(n.bezierData=ht.buildBezierData(a.s,r.s||a.e,a.to,a.ti));var T=n.bezierData;if(t>=E||t<M){var F=t>=E?T.points.length-1:0;for(l=T.points[F].point.length,h=0;h<l;h+=1)i[h]=T.points[F].point[h]}else{n.__fnct?d=n.__fnct:(d=it.getBezierEasing(a.o.x,a.o.y,a.i.x,a.i.y,a.n).get,n.__fnct=d),p=d((t-M)/(E-M));var I,L=T.segmentLength*p,B=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastAddedLength:0;for(m=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastPoint:0,y=!0,f=T.points.length;y;){if(B+=T.points[m].partialLength,0===L||0===p||m===T.points.length-1){for(l=T.points[m].point.length,h=0;h<l;h+=1)i[h]=T.points[m].point[h];break}if(L>=B&&L<B+T.points[m+1].partialLength){for(I=(L-B)/T.points[m+1].partialLength,l=T.points[m].point.length,h=0;h<l;h+=1)i[h]=T.points[m].point[h]+(T.points[m+1].point[h]-T.points[m].point[h])*I;break}m<f-1?m+=1:y=!1}e._lastPoint=m,e._lastAddedLength=B-T.points[m].partialLength,e._lastKeyframeIndex=u}}else{var z,V,R,O,N;if(g=a.s.length,v=r.s||a.e,this.sh&&1!==a.h)if(t>=E)i[0]=v[0],i[1]=v[1],i[2]=v[2];else if(t<=M)i[0]=a.s[0],i[1]=a.s[1],i[2]=a.s[2];else{var q=ft(a.s),j=ft(v);b=i,_=function(t,e,i){var s,a,r,n,h,o=[],l=t[0],p=t[1],f=t[2],m=t[3],d=e[0],c=e[1],u=e[2],g=e[3];return(a=l*d+p*c+f*u+m*g)<0&&(a=-a,d=-d,c=-c,u=-u,g=-g),1-a>1e-6?(s=Math.acos(a),r=Math.sin(s),n=Math.sin((1-i)*s)/r,h=Math.sin(i*s)/r):(n=1-i,h=i),o[0]=n*l+h*d,o[1]=n*p+h*c,o[2]=n*f+h*u,o[3]=n*m+h*g,o}(q,j,(t-M)/(E-M)),x=_[0],k=_[1],P=_[2],S=_[3],A=Math.atan2(2*k*S-2*x*P,1-2*k*k-2*P*P),D=Math.asin(2*x*k+2*P*S),C=Math.atan2(2*x*S-2*k*P,1-2*x*x-2*P*P),b[0]=A/w,b[1]=D/w,b[2]=C/w}else for(u=0;u<g;u+=1)1!==a.h&&(t>=E?p=1:t<M?p=0:(a.o.x.constructor===Array?(n.__fnct||(n.__fnct=[]),n.__fnct[u]?d=n.__fnct[u]:(z=void 0===a.o.x[u]?a.o.x[0]:a.o.x[u],V=void 0===a.o.y[u]?a.o.y[0]:a.o.y[u],R=void 0===a.i.x[u]?a.i.x[0]:a.i.x[u],O=void 0===a.i.y[u]?a.i.y[0]:a.i.y[u],d=it.getBezierEasing(z,V,R,O).get,n.__fnct[u]=d)):n.__fnct?d=n.__fnct:(z=a.o.x,V=a.o.y,R=a.i.x,O=a.i.y,d=it.getBezierEasing(z,V,R,O).get,a.keyframeMetadata=d),p=d((t-M)/(E-M)))),v=r.s||a.e,N=1===a.h?a.s[u]:a.s[u]+(v[u]-a.s[u])*p,"multidimensional"===this.propType?i[u]=N:i=N}return e.lastIndex=c,i}function ft(t){var e=t[0]*w,i=t[1]*w,s=t[2]*w,a=Math.cos(e/2),r=Math.cos(i/2),n=Math.cos(s/2),h=Math.sin(e/2),o=Math.sin(i/2),l=Math.sin(s/2);return[h*o*n+a*r*l,h*r*n+a*o*l,a*o*n-h*r*l,a*r*n-h*o*l]}function mt(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==ot&&(this._caching.lastFrame>=i&&t>=i||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var s=this.interpolateValue(t,this._caching);this.pv=s}return this._caching.lastFrame=t,this.pv}function dt(t){var e;if("unidimensional"===this.propType)e=t*this.mult,lt(this.v-e)>1e-5&&(this.v=e,this._mdf=!0);else for(var i=0,s=this.v.length;i<s;)e=t[i]*this.mult,lt(this.v[i]-e)>1e-5&&(this.v[i]=e,this._mdf=!0),i+=1}function ct(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t;this.lock=!0,this._mdf=this._isFirstFrame;var e=this.effectsSequence.length,i=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)i=this.effectsSequence[t](i);this.setVValue(i),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function ut(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function gt(t,e,i,s){this.propType="unidimensional",this.mult=i||1,this.data=e,this.v=i?e.k*i:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=s,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=ct,this.setVValue=dt,this.addEffect=ut}function yt(t,e,i,s){var a;this.propType="multidimensional",this.mult=i||1,this.data=e,this._mdf=!1,this.elem=t,this.container=s,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var r=e.k.length;for(this.v=o("float32",r),this.pv=o("float32",r),this.vel=o("float32",r),a=0;a<r;a+=1)this.v[a]=e.k[a]*this.mult,this.pv[a]=e.k[a];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=ct,this.setVValue=dt,this.addEffect=ut}function vt(t,e,i,s){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:ot,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=i||1,this.elem=t,this.container=s,this.comp=t.comp,this.v=ot,this.pv=ot,this._isFirstFrame=!0,this.getValue=ct,this.setVValue=dt,this.interpolateValue=pt,this.effectsSequence=[mt.bind(this)],this.addEffect=ut}function bt(t,e,i,s){var a;this.propType="multidimensional";var r,n,h,l,p=e.k.length;for(a=0;a<p-1;a+=1)e.k[a].to&&e.k[a].s&&e.k[a+1]&&e.k[a+1].s&&(r=e.k[a].s,n=e.k[a+1].s,h=e.k[a].to,l=e.k[a].ti,(2===r.length&&(r[0]!==n[0]||r[1]!==n[1])&&ht.pointOnLine2D(r[0],r[1],n[0],n[1],r[0]+h[0],r[1]+h[1])&&ht.pointOnLine2D(r[0],r[1],n[0],n[1],n[0]+l[0],n[1]+l[1])||3===r.length&&(r[0]!==n[0]||r[1]!==n[1]||r[2]!==n[2])&&ht.pointOnLine3D(r[0],r[1],r[2],n[0],n[1],n[2],r[0]+h[0],r[1]+h[1],r[2]+h[2])&&ht.pointOnLine3D(r[0],r[1],r[2],n[0],n[1],n[2],n[0]+l[0],n[1]+l[1],n[2]+l[2]))&&(e.k[a].to=null,e.k[a].ti=null),r[0]===n[0]&&r[1]===n[1]&&0===h[0]&&0===h[1]&&0===l[0]&&0===l[1]&&(2===r.length||r[2]===n[2]&&0===h[2]&&0===l[2])&&(e.k[a].to=null,e.k[a].ti=null));this.effectsSequence=[mt.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=i||1,this.elem=t,this.container=s,this.comp=t.comp,this.getValue=ct,this.setVValue=dt,this.interpolateValue=pt,this.frameId=-1;var f=e.k[0].s.length;for(this.v=o("float32",f),this.pv=o("float32",f),a=0;a<f;a+=1)this.v[a]=ot,this.pv[a]=ot;this._caching={lastFrame:ot,lastIndex:0,value:o("float32",f)},this.addEffect=ut}var _t={getProp:function(t,e,i,s,a){var r;if(e.sid&&(e=t.globalData.slotManager.getProp(e)),e.k.length)if("number"==typeof e.k[0])r=new yt(t,e,s,a);else switch(i){case 0:r=new vt(t,e,s,a);break;case 1:r=new bt(t,e,s,a)}else r=new gt(t,e,s,a);return r.effectsSequence.length&&a.addDynamicProperty(r),r}};function xt(){}xt.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){var t;this._mdf=!1;var e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var kt=at(8,(function(){return o("float32",2)}));function wt(){this.c=!1,this._length=0,this._maxLength=8,this.v=l(this._maxLength),this.o=l(this._maxLength),this.i=l(this._maxLength)}wt.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var i=0;i<e;)this.v[i]=kt.newElement(),this.o[i]=kt.newElement(),this.i[i]=kt.newElement(),i+=1},wt.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},wt.prototype.doubleArrayLength=function(){this.v=this.v.concat(l(this._maxLength)),this.i=this.i.concat(l(this._maxLength)),this.o=this.o.concat(l(this._maxLength)),this._maxLength*=2},wt.prototype.setXYAt=function(t,e,i,s,a){var r;switch(this._length=Math.max(this._length,s+1),this._length>=this._maxLength&&this.doubleArrayLength(),i){case"v":r=this.v;break;case"i":r=this.i;break;case"o":r=this.o;break;default:r=[]}(!r[s]||r[s]&&!a)&&(r[s]=kt.newElement()),r[s][0]=t,r[s][1]=e},wt.prototype.setTripleAt=function(t,e,i,s,a,r,n,h){this.setXYAt(t,e,"v",n,h),this.setXYAt(i,s,"o",n,h),this.setXYAt(a,r,"i",n,h)},wt.prototype.reverse=function(){var t=new wt;t.setPathData(this.c,this._length);var e=this.v,i=this.o,s=this.i,a=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],s[0][0],s[0][1],i[0][0],i[0][1],0,!1),a=1);var r,n=this._length-1,h=this._length;for(r=a;r<h;r+=1)t.setTripleAt(e[n][0],e[n][1],s[n][0],s[n][1],i[n][0],i[n][1],r,!1),n-=1;return t},wt.prototype.length=function(){return this._length};var Pt,St=((Pt=at(4,(function(){return new wt}),(function(t){var e,i=t._length;for(e=0;e<i;e+=1)kt.release(t.v[e]),kt.release(t.i[e]),kt.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1}))).clone=function(t){var e,i=Pt.newElement(),s=void 0===t._length?t.v.length:t._length;for(i.setLength(s),i.c=t.c,e=0;e<s;e+=1)i.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return i},Pt);function At(){this._length=0,this._maxLength=4,this.shapes=l(this._maxLength)}At.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(l(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},At.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)St.release(this.shapes[t]);this._length=0};var Dt,Ct,Et,Mt,Tt=(Dt={newShapeCollection:function(){return Ct?Mt[Ct-=1]:new At},release:function(t){var e,i=t._length;for(e=0;e<i;e+=1)St.release(t.shapes[e]);t._length=0,Ct===Et&&(Mt=st.double(Mt),Et*=2),Mt[Ct]=t,Ct+=1}},Ct=0,Mt=l(Et=4),Dt),Ft=function(){var t=-999999;function e(t,e,i){var s,a,r,n,h,o,l,p,f,m=i.lastIndex,d=this.keyframes;if(t<d[0].t-this.offsetTime)s=d[0].s[0],r=!0,m=0;else if(t>=d[d.length-1].t-this.offsetTime)s=d[d.length-1].s?d[d.length-1].s[0]:d[d.length-2].e[0],r=!0;else{for(var c,u,g,y=m,v=d.length-1,b=!0;b&&(c=d[y],!((u=d[y+1]).t-this.offsetTime>t));)y<v-1?y+=1:b=!1;if(g=this.keyframesMetadata[y]||{},m=y,!(r=1===c.h)){if(t>=u.t-this.offsetTime)p=1;else if(t<c.t-this.offsetTime)p=0;else{var _;g.__fnct?_=g.__fnct:(_=it.getBezierEasing(c.o.x,c.o.y,c.i.x,c.i.y).get,g.__fnct=_),p=_((t-(c.t-this.offsetTime))/(u.t-this.offsetTime-(c.t-this.offsetTime)))}a=u.s?u.s[0]:c.e[0]}s=c.s[0]}for(o=e._length,l=s.i[0].length,i.lastIndex=m,n=0;n<o;n+=1)for(h=0;h<l;h+=1)f=r?s.i[n][h]:s.i[n][h]+(a.i[n][h]-s.i[n][h])*p,e.i[n][h]=f,f=r?s.o[n][h]:s.o[n][h]+(a.o[n][h]-s.o[n][h])*p,e.o[n][h]=f,f=r?s.v[n][h]:s.v[n][h]+(a.v[n][h]-s.v[n][h])*p,e.v[n][h]=f}function i(){var e=this.comp.renderedFrame-this.offsetTime,i=this.keyframes[0].t-this.offsetTime,s=this.keyframes[this.keyframes.length-1].t-this.offsetTime,a=this._caching.lastFrame;return a!==t&&(a<i&&e<i||a>s&&e>s)||(this._caching.lastIndex=a<e?this._caching.lastIndex:0,this.interpolateShape(e,this.pv,this._caching)),this._caching.lastFrame=e,this.pv}function s(){this.paths=this.localShapeCollection}function a(t){(function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var i,s=t._length;for(i=0;i<s;i+=1)if(t.v[i][0]!==e.v[i][0]||t.v[i][1]!==e.v[i][1]||t.o[i][0]!==e.o[i][0]||t.o[i][1]!==e.o[i][1]||t.i[i][0]!==e.i[i][0]||t.i[i][1]!==e.i[i][1])return!1;return!0})(this.v,t)||(this.v=St.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function n(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t,e;this.lock=!0,this._mdf=!1,t=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k;var i=this.effectsSequence.length;for(e=0;e<i;e+=1)t=this.effectsSequence[e](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function h(t,e,i){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var a=3===i?e.pt.k:e.ks.k;this.v=St.clone(a),this.pv=St.clone(this.v),this.localShapeCollection=Tt.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=s,this.effectsSequence=[]}function o(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function l(e,a,r){this.propType="shape",this.comp=e.comp,this.elem=e,this.container=e,this.offsetTime=e.data.st,this.keyframes=3===r?a.pt.k:a.ks.k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;var n=this.keyframes[0].s[0].i.length;this.v=St.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,n),this.pv=St.clone(this.v),this.localShapeCollection=Tt.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=t,this.reset=s,this._caching={lastFrame:t,lastIndex:0},this.effectsSequence=[i.bind(this)]}h.prototype.interpolateShape=e,h.prototype.getValue=n,h.prototype.setVValue=a,h.prototype.addEffect=o,l.prototype.getValue=n,l.prototype.interpolateShape=e,l.prototype.setVValue=a,l.prototype.addEffect=o;var p=function(){var t=P;function e(t,e){this.v=St.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=Tt.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=_t.getProp(t,e.p,1,0,this),this.s=_t.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}return e.prototype={reset:s,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var e=this.p.v[0],i=this.p.v[1],s=this.s.v[0]/2,a=this.s.v[1]/2,r=3!==this.d,n=this.v;n.v[0][0]=e,n.v[0][1]=i-a,n.v[1][0]=r?e+s:e-s,n.v[1][1]=i,n.v[2][0]=e,n.v[2][1]=i+a,n.v[3][0]=r?e-s:e+s,n.v[3][1]=i,n.i[0][0]=r?e-s*t:e+s*t,n.i[0][1]=i-a,n.i[1][0]=r?e+s:e-s,n.i[1][1]=i-a*t,n.i[2][0]=r?e+s*t:e-s*t,n.i[2][1]=i+a,n.i[3][0]=r?e-s:e+s,n.i[3][1]=i+a*t,n.o[0][0]=r?e+s*t:e-s*t,n.o[0][1]=i-a,n.o[1][0]=r?e+s:e-s,n.o[1][1]=i+a*t,n.o[2][0]=r?e-s*t:e+s*t,n.o[2][1]=i+a,n.o[3][0]=r?e-s:e+s,n.o[3][1]=i-a*t}},r([xt],e),e}(),f=function(){function t(t,e){this.v=St.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=_t.getProp(t,e.ir,0,0,this),this.is=_t.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=_t.getProp(t,e.pt,0,0,this),this.p=_t.getProp(t,e.p,1,0,this),this.r=_t.getProp(t,e.r,0,w,this),this.or=_t.getProp(t,e.or,0,0,this),this.os=_t.getProp(t,e.os,0,.01,this),this.localShapeCollection=Tt.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}return t.prototype={reset:s,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,i,s,a=2*Math.floor(this.pt.v),r=2*Math.PI/a,n=!0,h=this.or.v,o=this.ir.v,l=this.os.v,p=this.is.v,f=2*Math.PI*h/(2*a),m=2*Math.PI*o/(2*a),d=-Math.PI/2;d+=this.r.v;var c=3===this.data.d?-1:1;for(this.v._length=0,t=0;t<a;t+=1){i=n?l:p,s=n?f:m;var u=(e=n?h:o)*Math.cos(d),g=e*Math.sin(d),y=0===u&&0===g?0:g/Math.sqrt(u*u+g*g),v=0===u&&0===g?0:-u/Math.sqrt(u*u+g*g);u+=+this.p.v[0],g+=+this.p.v[1],this.v.setTripleAt(u,g,u-y*s*i*c,g-v*s*i*c,u+y*s*i*c,g+v*s*i*c,t,!0),n=!n,d+=r*c}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),i=2*Math.PI/e,s=this.or.v,a=this.os.v,r=2*Math.PI*s/(4*e),n=.5*-Math.PI,h=3===this.data.d?-1:1;for(n+=this.r.v,this.v._length=0,t=0;t<e;t+=1){var o=s*Math.cos(n),l=s*Math.sin(n),p=0===o&&0===l?0:l/Math.sqrt(o*o+l*l),f=0===o&&0===l?0:-o/Math.sqrt(o*o+l*l);o+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(o,l,o-p*r*a*h,l-f*r*a*h,o+p*r*a*h,l+f*r*a*h,t,!0),n+=i*h}this.paths.length=0,this.paths[0]=this.v}},r([xt],t),t}(),m=function(){function t(t,e){this.v=St.newElement(),this.v.c=!0,this.localShapeCollection=Tt.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=_t.getProp(t,e.p,1,0,this),this.s=_t.getProp(t,e.s,1,0,this),this.r=_t.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}return t.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,s=this.s.v[1]/2,a=_(i,s,this.r.v),r=a*(1-P);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+i,e-s+a,t+i,e-s+a,t+i,e-s+r,0,!0),this.v.setTripleAt(t+i,e+s-a,t+i,e+s-r,t+i,e+s-a,1,!0),0!==a?(this.v.setTripleAt(t+i-a,e+s,t+i-a,e+s,t+i-r,e+s,2,!0),this.v.setTripleAt(t-i+a,e+s,t-i+r,e+s,t-i+a,e+s,3,!0),this.v.setTripleAt(t-i,e+s-a,t-i,e+s-a,t-i,e+s-r,4,!0),this.v.setTripleAt(t-i,e-s+a,t-i,e-s+r,t-i,e-s+a,5,!0),this.v.setTripleAt(t-i+a,e-s,t-i+a,e-s,t-i+r,e-s,6,!0),this.v.setTripleAt(t+i-a,e-s,t+i-r,e-s,t+i-a,e-s,7,!0)):(this.v.setTripleAt(t-i,e+s,t-i+r,e+s,t-i,e+s,2),this.v.setTripleAt(t-i,e-s,t-i,e-s+r,t-i,e-s,3))):(this.v.setTripleAt(t+i,e-s+a,t+i,e-s+r,t+i,e-s+a,0,!0),0!==a?(this.v.setTripleAt(t+i-a,e-s,t+i-a,e-s,t+i-r,e-s,1,!0),this.v.setTripleAt(t-i+a,e-s,t-i+r,e-s,t-i+a,e-s,2,!0),this.v.setTripleAt(t-i,e-s+a,t-i,e-s+a,t-i,e-s+r,3,!0),this.v.setTripleAt(t-i,e+s-a,t-i,e+s-r,t-i,e+s-a,4,!0),this.v.setTripleAt(t-i+a,e+s,t-i+a,e+s,t-i+r,e+s,5,!0),this.v.setTripleAt(t+i-a,e+s,t+i-r,e+s,t+i-a,e+s,6,!0),this.v.setTripleAt(t+i,e+s-a,t+i,e+s-a,t+i,e+s-r,7,!0)):(this.v.setTripleAt(t-i,e-s,t-i+r,e-s,t-i,e-s,1,!0),this.v.setTripleAt(t-i,e+s,t-i,e+s-r,t-i,e+s,2,!0),this.v.setTripleAt(t+i,e+s,t+i-r,e+s,t+i,e+s,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:s},r([xt],t),t}();var d={getShapeProp:function(t,e,i){var s;return 3===i||4===i?s=(3===i?e.pt:e.ks).k.length?new l(t,e,i):new h(t,e,i):5===i?s=new m(t,e):6===i?s=new p(t,e):7===i&&(s=new f(t,e)),s.k&&t.addDynamicProperty(s),s},getConstructorFunction:function(){return h},getKeyframedConstructorFunction:function(){return l}};return d}(),It=function(){var t=Math.cos,e=Math.sin,i=Math.tan,s=Math.round;function a(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function r(i){if(0===i)return this;var s=t(i),a=e(i);return this._t(s,-a,0,0,a,s,0,0,0,0,1,0,0,0,0,1)}function n(i){if(0===i)return this;var s=t(i),a=e(i);return this._t(1,0,0,0,0,s,-a,0,0,a,s,0,0,0,0,1)}function h(i){if(0===i)return this;var s=t(i),a=e(i);return this._t(s,0,a,0,0,1,0,0,-a,0,s,0,0,0,0,1)}function l(i){if(0===i)return this;var s=t(i),a=e(i);return this._t(s,-a,0,0,a,s,0,0,0,0,1,0,0,0,0,1)}function p(t,e){return this._t(1,e,t,1,0,0)}function f(t,e){return this.shear(i(t),i(e))}function m(s,a){var r=t(a),n=e(a);return this._t(r,n,0,0,-n,r,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,i(s),1,0,0,0,0,1,0,0,0,0,1)._t(r,-n,0,0,n,r,0,0,0,0,1,0,0,0,0,1)}function d(t,e,i){return i||0===i||(i=1),1===t&&1===e&&1===i?this:this._t(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1)}function c(t,e,i,s,a,r,n,h,o,l,p,f,m,d,c,u){return this.props[0]=t,this.props[1]=e,this.props[2]=i,this.props[3]=s,this.props[4]=a,this.props[5]=r,this.props[6]=n,this.props[7]=h,this.props[8]=o,this.props[9]=l,this.props[10]=p,this.props[11]=f,this.props[12]=m,this.props[13]=d,this.props[14]=c,this.props[15]=u,this}function u(t,e,i){return i=i||0,0!==t||0!==e||0!==i?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,i,1):this}function g(t,e,i,s,a,r,n,h,o,l,p,f,m,d,c,u){var g=this.props;if(1===t&&0===e&&0===i&&0===s&&0===a&&1===r&&0===n&&0===h&&0===o&&0===l&&1===p&&0===f)return g[12]=g[12]*t+g[15]*m,g[13]=g[13]*r+g[15]*d,g[14]=g[14]*p+g[15]*c,g[15]*=u,this._identityCalculated=!1,this;var y=g[0],v=g[1],b=g[2],_=g[3],x=g[4],k=g[5],w=g[6],P=g[7],S=g[8],A=g[9],D=g[10],C=g[11],E=g[12],M=g[13],T=g[14],F=g[15];return g[0]=y*t+v*a+b*o+_*m,g[1]=y*e+v*r+b*l+_*d,g[2]=y*i+v*n+b*p+_*c,g[3]=y*s+v*h+b*f+_*u,g[4]=x*t+k*a+w*o+P*m,g[5]=x*e+k*r+w*l+P*d,g[6]=x*i+k*n+w*p+P*c,g[7]=x*s+k*h+w*f+P*u,g[8]=S*t+A*a+D*o+C*m,g[9]=S*e+A*r+D*l+C*d,g[10]=S*i+A*n+D*p+C*c,g[11]=S*s+A*h+D*f+C*u,g[12]=E*t+M*a+T*o+F*m,g[13]=E*e+M*r+T*l+F*d,g[14]=E*i+M*n+T*p+F*c,g[15]=E*s+M*h+T*f+F*u,this._identityCalculated=!1,this}function y(t){var e=t.props;return this.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}function v(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function b(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function _(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function x(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function k(t,e,i){return{x:t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}}function w(t,e,i){return t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12]}function P(t,e,i){return t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13]}function S(t,e,i){return t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}function A(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,i=-this.props[1]/t,s=-this.props[4]/t,a=this.props[0]/t,r=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,n=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,h=new It;return h.props[0]=e,h.props[1]=i,h.props[4]=s,h.props[5]=a,h.props[12]=r,h.props[13]=n,h}function D(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function C(t){var e,i=t.length,s=[];for(e=0;e<i;e+=1)s[e]=D(t[e]);return s}function E(t,e,i){var s=o("float32",6);if(this.isIdentity())s[0]=t[0],s[1]=t[1],s[2]=e[0],s[3]=e[1],s[4]=i[0],s[5]=i[1];else{var a=this.props[0],r=this.props[1],n=this.props[4],h=this.props[5],l=this.props[12],p=this.props[13];s[0]=t[0]*a+t[1]*n+l,s[1]=t[0]*r+t[1]*h+p,s[2]=e[0]*a+e[1]*n+l,s[3]=e[0]*r+e[1]*h+p,s[4]=i[0]*a+i[1]*n+l,s[5]=i[0]*r+i[1]*h+p}return s}function M(t,e,i){return this.isIdentity()?[t,e,i]:[t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]]}function T(t,e){if(this.isIdentity())return t+","+e;var i=this.props;return Math.round(100*(t*i[0]+e*i[4]+i[12]))/100+","+Math.round(100*(t*i[1]+e*i[5]+i[13]))/100}function F(){for(var t=0,e=this.props,i="matrix3d(";t<16;)i+=s(1e4*e[t])/1e4,i+=15===t?")":",",t+=1;return i}function I(t){return t<1e-6&&t>0||t>-1e-6&&t<0?s(1e4*t)/1e4:t}function L(){var t=this.props;return"matrix("+I(t[0])+","+I(t[1])+","+I(t[4])+","+I(t[5])+","+I(t[12])+","+I(t[13])+")"}return function(){this.reset=a,this.rotate=r,this.rotateX=n,this.rotateY=h,this.rotateZ=l,this.skew=f,this.skewFromAxis=m,this.shear=p,this.scale=d,this.setTransform=c,this.translate=u,this.transform=g,this.multiply=y,this.applyToPoint=k,this.applyToX=w,this.applyToY=P,this.applyToZ=S,this.applyToPointArray=M,this.applyToTriplePoints=E,this.applyToPointStringified=T,this.toCSS=F,this.to2dCSS=L,this.clone=_,this.cloneFromProps=x,this.equals=b,this.inversePoints=C,this.inversePoint=D,this.getInverseMatrix=A,this._t=this.transform,this.isIdentity=v,this._identity=!0,this._identityCalculated=!1,this.props=o("float32",16),this.reset()}}();function Lt(t){return Lt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Lt(t)}var Bt={};function zt(){et.searchAnimations()}Bt.play=et.play,Bt.pause=et.pause,Bt.setLocationHref=function(e){t=e},Bt.togglePause=et.togglePause,Bt.setSpeed=et.setSpeed,Bt.setDirection=et.setDirection,Bt.stop=et.stop,Bt.searchAnimations=zt,Bt.registerAnimation=et.registerAnimation,Bt.loadAnimation=function(t){return et.loadAnimation(t)},Bt.setSubframeRendering=function(t){!function(t){f=!!t}(t)},Bt.resize=et.resize,Bt.goToAndStop=et.goToAndStop,Bt.destroy=et.destroy,Bt.setQuality=function(t){if("string"==typeof t)switch(t){case"high":W(200);break;default:case"medium":W(50);break;case"low":W(10)}else!isNaN(t)&&t>1&&W(t);H()>=50?S(!1):S(!0)},Bt.inBrowser=function(){return"undefined"!=typeof navigator},Bt.installPlugin=function(t,e){"expressions"===t&&(m=e)},Bt.freeze=et.freeze,Bt.unfreeze=et.unfreeze,Bt.setVolume=et.setVolume,Bt.mute=et.mute,Bt.unmute=et.unmute,Bt.getRegisteredAnimations=et.getRegisteredAnimations,Bt.useWebWorker=function(t){e=!!t},Bt.setIDPrefix=function(t){c=t},Bt.__getFactory=function(t){switch(t){case"propertyFactory":return _t;case"shapePropertyFactory":return Ft;case"matrix":return It;default:return null}},Bt.version="5.12.2";var Vt="",Rt=document.getElementsByTagName("script"),Ot=Rt[Rt.length-1]||{src:""};Vt=Ot.src?Ot.src.replace(/^[^\?]+\??/,""):"",function(t){for(var e=Vt.split("&"),i=0;i<e.length;i+=1){var s=e[i].split("=");if(decodeURIComponent(s[0])==t)return decodeURIComponent(s[1])}}("renderer");var Nt=setInterval((function(){"complete"===document.readyState&&(clearInterval(Nt),zt())}),100);try{"object"===("undefined"==typeof exports?"undefined":Lt(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=Bt)}catch(t){}var qt=function(){var t={},e={};return t.registerModifier=function(t,i){e[t]||(e[t]=i)},t.getModifier=function(t,i,s){return new e[t](i,s)},t}();function jt(){}function Wt(){}function Ht(){}jt.prototype.initModifierProperties=function(){},jt.prototype.addShapeToModifier=function(){},jt.prototype.addShape=function(t){if(!this.closed){t.sh.container.addDynamicProperty(t.sh);var e={shape:t.sh,data:t,localShapeCollection:Tt.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},jt.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=i,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},jt.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},r([xt],jt),r([jt],Wt),Wt.prototype.initModifierProperties=function(t,e){this.s=_t.getProp(t,e.s,0,.01,this),this.e=_t.getProp(t,e.e,0,.01,this),this.o=_t.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},Wt.prototype.addShapeToModifier=function(t){t.pathsData=[]},Wt.prototype.calculateShapeEdges=function(t,e,i,s,a){var r=[];e<=1?r.push({s:t,e:e}):t>=1?r.push({s:t-1,e:e-1}):(r.push({s:t,e:1}),r.push({s:0,e:e-1}));var n,h,o=[],l=r.length;for(n=0;n<l;n+=1){var p,f;if(!((h=r[n]).e*a<s||h.s*a>s+i))p=h.s*a<=s?0:(h.s*a-s)/i,f=h.e*a>=s+i?1:(h.e*a-s)/i,o.push([p,f])}return o.length||o.push([0,0]),o},Wt.prototype.releasePathsData=function(t){var e,i=t.length;for(e=0;e<i;e+=1)nt.release(t[e]);return t.length=0,t},Wt.prototype.processShapes=function(t){var e,i,s,a;if(this._mdf||t){var r=this.o.v%360/360;if(r<0&&(r+=1),(e=this.s.v>1?1+r:this.s.v<0?0+r:this.s.v+r)>(i=this.e.v>1?1+r:this.e.v<0?0+r:this.e.v+r)){var n=e;e=i,i=n}e=1e-4*Math.round(1e4*e),i=1e-4*Math.round(1e4*i),this.sValue=e,this.eValue=i}else e=this.sValue,i=this.eValue;var h,o,l,p,f,m=this.shapes.length,d=0;if(i===e)for(a=0;a<m;a+=1)this.shapes[a].localShapeCollection.releaseShapes(),this.shapes[a].shape._mdf=!0,this.shapes[a].shape.paths=this.shapes[a].localShapeCollection,this._mdf&&(this.shapes[a].pathsData.length=0);else if(1===i&&0===e||0===i&&1===e){if(this._mdf)for(a=0;a<m;a+=1)this.shapes[a].pathsData.length=0,this.shapes[a].shape._mdf=!0}else{var c,u,g=[];for(a=0;a<m;a+=1)if((c=this.shapes[a]).shape._mdf||this._mdf||t||2===this.m){if(o=(s=c.shape.paths)._length,f=0,!c.shape._mdf&&c.pathsData.length)f=c.totalShapeLength;else{for(l=this.releasePathsData(c.pathsData),h=0;h<o;h+=1)p=ht.getSegmentsLength(s.shapes[h]),l.push(p),f+=p.totalLength;c.totalShapeLength=f,c.pathsData=l}d+=f,c.shape._mdf=!0}else c.shape.paths=c.localShapeCollection;var y,v=e,b=i,_=0;for(a=m-1;a>=0;a-=1)if((c=this.shapes[a]).shape._mdf){for((u=c.localShapeCollection).releaseShapes(),2===this.m&&m>1?(y=this.calculateShapeEdges(e,i,c.totalShapeLength,_,d),_+=c.totalShapeLength):y=[[v,b]],o=y.length,h=0;h<o;h+=1){v=y[h][0],b=y[h][1],g.length=0,b<=1?g.push({s:c.totalShapeLength*v,e:c.totalShapeLength*b}):v>=1?g.push({s:c.totalShapeLength*(v-1),e:c.totalShapeLength*(b-1)}):(g.push({s:c.totalShapeLength*v,e:c.totalShapeLength}),g.push({s:0,e:c.totalShapeLength*(b-1)}));var x=this.addShapes(c,g[0]);if(g[0].s!==g[0].e){if(g.length>1)if(c.shape.paths.shapes[c.shape.paths._length-1].c){var k=x.pop();this.addPaths(x,u),x=this.addShapes(c,g[1],k)}else this.addPaths(x,u),x=this.addShapes(c,g[1]);this.addPaths(x,u)}}c.shape.paths=u}}},Wt.prototype.addPaths=function(t,e){var i,s=t.length;for(i=0;i<s;i+=1)e.addShape(t[i])},Wt.prototype.addSegment=function(t,e,i,s,a,r,n){a.setXYAt(e[0],e[1],"o",r),a.setXYAt(i[0],i[1],"i",r+1),n&&a.setXYAt(t[0],t[1],"v",r),a.setXYAt(s[0],s[1],"v",r+1)},Wt.prototype.addSegmentFromArray=function(t,e,i,s){e.setXYAt(t[1],t[5],"o",i),e.setXYAt(t[2],t[6],"i",i+1),s&&e.setXYAt(t[0],t[4],"v",i),e.setXYAt(t[3],t[7],"v",i+1)},Wt.prototype.addShapes=function(t,e,i){var s,a,r,n,h,o,l,p,f=t.pathsData,m=t.shape.paths.shapes,d=t.shape.paths._length,c=0,u=[],g=!0;for(i?(h=i._length,p=i._length):(i=St.newElement(),h=0,p=0),u.push(i),s=0;s<d;s+=1){for(o=f[s].lengths,i.c=m[s].c,r=m[s].c?o.length:o.length+1,a=1;a<r;a+=1)if(c+(n=o[a-1]).addedLength<e.s)c+=n.addedLength,i.c=!1;else{if(c>e.e){i.c=!1;break}e.s<=c&&e.e>=c+n.addedLength?(this.addSegment(m[s].v[a-1],m[s].o[a-1],m[s].i[a],m[s].v[a],i,h,g),g=!1):(l=ht.getNewSegment(m[s].v[a-1],m[s].v[a],m[s].o[a-1],m[s].i[a],(e.s-c)/n.addedLength,(e.e-c)/n.addedLength,o[a-1]),this.addSegmentFromArray(l,i,h,g),g=!1,i.c=!1),c+=n.addedLength,h+=1}if(m[s].c&&o.length){if(n=o[a-1],c<=e.e){var y=o[a-1].addedLength;e.s<=c&&e.e>=c+y?(this.addSegment(m[s].v[a-1],m[s].o[a-1],m[s].i[0],m[s].v[0],i,h,g),g=!1):(l=ht.getNewSegment(m[s].v[a-1],m[s].v[0],m[s].o[a-1],m[s].i[0],(e.s-c)/y,(e.e-c)/y,o[a-1]),this.addSegmentFromArray(l,i,h,g),g=!1,i.c=!1)}else i.c=!1;c+=n.addedLength,h+=1}if(i._length&&(i.setXYAt(i.v[p][0],i.v[p][1],"i",p),i.setXYAt(i.v[i._length-1][0],i.v[i._length-1][1],"o",i._length-1)),c>e.e)break;s<d-1&&(i=St.newElement(),g=!0,u.push(i),h=0)}return u},r([jt],Ht),Ht.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=_t.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},Ht.prototype.processPath=function(t,e){var i=e/100,s=[0,0],a=t._length,r=0;for(r=0;r<a;r+=1)s[0]+=t.v[r][0],s[1]+=t.v[r][1];s[0]/=a,s[1]/=a;var n,h,o,l,p,f,m=St.newElement();for(m.c=t.c,r=0;r<a;r+=1)n=t.v[r][0]+(s[0]-t.v[r][0])*i,h=t.v[r][1]+(s[1]-t.v[r][1])*i,o=t.o[r][0]+(s[0]-t.o[r][0])*-i,l=t.o[r][1]+(s[1]-t.o[r][1])*-i,p=t.i[r][0]+(s[0]-t.i[r][0])*-i,f=t.i[r][1]+(s[1]-t.i[r][1])*-i,m.setTripleAt(n,h,o,l,p,f,r);return m},Ht.prototype.processShapes=function(t){var e,i,s,a,r,n,h=this.shapes.length,o=this.amount.v;if(0!==o)for(i=0;i<h;i+=1){if(n=(r=this.shapes[i]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,s=0;s<a;s+=1)n.addShape(this.processPath(e[s],o));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var Xt=function(){var t=[0,0];function e(t,e,i){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new It,this.pre=new It,this.appliedTransformations=0,this.initDynamicPropertyContainer(i||t),e.p&&e.p.s?(this.px=_t.getProp(t,e.p.x,0,0,this),this.py=_t.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=_t.getProp(t,e.p.z,0,0,this))):this.p=_t.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=_t.getProp(t,e.rx,0,w,this),this.ry=_t.getProp(t,e.ry,0,w,this),this.rz=_t.getProp(t,e.rz,0,w,this),e.or.k[0].ti){var s,a=e.or.k.length;for(s=0;s<a;s+=1)e.or.k[s].to=null,e.or.k[s].ti=null}this.or=_t.getProp(t,e.or,1,w,this),this.or.sh=!0}else this.r=_t.getProp(t,e.r||{k:0},0,w,this);e.sk&&(this.sk=_t.getProp(t,e.sk,0,w,this),this.sa=_t.getProp(t,e.sa,0,w,this)),this.a=_t.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=_t.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=_t.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return e.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(e){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||e){var i;if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var s,a;if(i=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime)this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(s=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/i,0),a=this.p.getValueAtTime(this.p.keyframes[0].t/i,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(s=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/i,0),a=this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/i,0)):(s=this.p.pv,a=this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/i,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){s=[],a=[];var r=this.px,n=this.py;r._caching.lastFrame+r.offsetTime<=r.keyframes[0].t?(s[0]=r.getValueAtTime((r.keyframes[0].t+.01)/i,0),s[1]=n.getValueAtTime((n.keyframes[0].t+.01)/i,0),a[0]=r.getValueAtTime(r.keyframes[0].t/i,0),a[1]=n.getValueAtTime(n.keyframes[0].t/i,0)):r._caching.lastFrame+r.offsetTime>=r.keyframes[r.keyframes.length-1].t?(s[0]=r.getValueAtTime(r.keyframes[r.keyframes.length-1].t/i,0),s[1]=n.getValueAtTime(n.keyframes[n.keyframes.length-1].t/i,0),a[0]=r.getValueAtTime((r.keyframes[r.keyframes.length-1].t-.01)/i,0),a[1]=n.getValueAtTime((n.keyframes[n.keyframes.length-1].t-.01)/i,0)):(s=[r.pv,n.pv],a[0]=r.getValueAtTime((r._caching.lastFrame+r.offsetTime-.01)/i,r.offsetTime),a[1]=n.getValueAtTime((n._caching.lastFrame+n.offsetTime-.01)/i,n.offsetTime))}else s=a=t;this.v.rotate(-Math.atan2(s[1]-a[1],s[0]-a[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},r([xt],e),e.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},e.prototype._addDynamicProperty=xt.prototype.addDynamicProperty,{getTransformProperty:function(t,i,s){return new e(t,i,s)}}}();function Yt(){}function Gt(){}function Kt(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function Jt(t){return Math.abs(t)<=1e-5}function Zt(t,e,i){return t*(1-i)+e*i}function Ut(t,e,i){return[Zt(t[0],e[0],i),Zt(t[1],e[1],i)]}function Qt(t,e,i,s){return[3*e-t-3*i+s,3*t-6*e+3*i,-3*t+3*e,t]}function $t(t){return new te(t,t,t,t,!1)}function te(t,e,i,s,a){a&&le(t,e)&&(e=Ut(t,s,1/3)),a&&le(i,s)&&(i=Ut(t,s,2/3));var r=Qt(t[0],e[0],i[0],s[0]),n=Qt(t[1],e[1],i[1],s[1]);this.a=[r[0],n[0]],this.b=[r[1],n[1]],this.c=[r[2],n[2]],this.d=[r[3],n[3]],this.points=[t,e,i,s]}function ee(t,e){var i=t.points[0][e],s=t.points[t.points.length-1][e];if(i>s){var a=s;s=i,i=a}for(var r=function(t,e,i){if(0===t)return[];var s=e*e-4*t*i;if(s<0)return[];var a=-e/(2*t);if(0===s)return[a];var r=Math.sqrt(s)/(2*t);return[a-r,a+r]}(3*t.a[e],2*t.b[e],t.c[e]),n=0;n<r.length;n+=1)if(r[n]>0&&r[n]<1){var h=t.point(r[n])[e];h<i?i=h:h>s&&(s=h)}return{min:i,max:s}}function ie(t,e,i){var s=t.boundingBox();return{cx:s.cx,cy:s.cy,width:s.width,height:s.height,bez:t,t:(e+i)/2,t1:e,t2:i}}function se(t){var e=t.bez.split(.5);return[ie(e[0],t.t1,t.t),ie(e[1],t.t,t.t2)]}function ae(t,e,i,s,a,r){var n,h;if(n=t,h=e,2*Math.abs(n.cx-h.cx)<n.width+h.width&&2*Math.abs(n.cy-h.cy)<n.height+h.height)if(i>=r||t.width<=s&&t.height<=s&&e.width<=s&&e.height<=s)a.push([t.t,e.t]);else{var o=se(t),l=se(e);ae(o[0],l[0],i+1,s,a,r),ae(o[0],l[1],i+1,s,a,r),ae(o[1],l[0],i+1,s,a,r),ae(o[1],l[1],i+1,s,a,r)}}function re(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function ne(t,e,i,s){var a=[t[0],t[1],1],r=[e[0],e[1],1],n=[i[0],i[1],1],h=[s[0],s[1],1],o=re(re(a,r),re(n,h));return Jt(o[2])?null:[o[0]/o[2],o[1]/o[2]]}function he(t,e,i){return[t[0]+Math.cos(e)*i,t[1]-Math.sin(e)*i]}function oe(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function le(t,e){return Kt(t[0],e[0])&&Kt(t[1],e[1])}function pe(){}function fe(t,e,i,s,a,r,n){var h=i-Math.PI/2,o=i+Math.PI/2,l=e[0]+Math.cos(i)*s*a,p=e[1]-Math.sin(i)*s*a;t.setTripleAt(l,p,l+Math.cos(h)*r,p-Math.sin(h)*r,l+Math.cos(o)*n,p-Math.sin(o)*n,t.length())}function me(t,e){var i,s,a,r,n=0===e?t.length()-1:e-1,h=(e+1)%t.length(),o=t.v[n],l=t.v[h],p=(i=o,a=[(s=l)[0]-i[0],s[1]-i[1]],r=.5*-Math.PI,[Math.cos(r)*a[0]-Math.sin(r)*a[1],Math.sin(r)*a[0]+Math.cos(r)*a[1]]);return Math.atan2(0,1)-Math.atan2(p[1],p[0])}function de(t,e,i,s,a,r,n){var h=me(e,i),o=e.v[i%e._length],l=e.v[0===i?e._length-1:i-1],p=e.v[(i+1)%e._length],f=2===r?Math.sqrt(Math.pow(o[0]-l[0],2)+Math.pow(o[1]-l[1],2)):0,m=2===r?Math.sqrt(Math.pow(o[0]-p[0],2)+Math.pow(o[1]-p[1],2)):0;fe(t,e.v[i%e._length],h,n,s,m/(2*(a+1)),f/(2*(a+1)))}function ce(t,e,i,s,a,r){for(var n=0;n<s;n+=1){var h=(n+1)/(s+1),o=2===a?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(h);fe(t,e.point(h),l,r,i,o/(2*(s+1)),o/(2*(s+1))),r=-r}return r}function ue(t,e,i){var s=Math.atan2(e[0]-t[0],e[1]-t[1]);return[he(t,s,i),he(e,s,i)]}function ge(t,e){var i,s,a,r,n,h,o;i=(o=ue(t.points[0],t.points[1],e))[0],s=o[1],a=(o=ue(t.points[1],t.points[2],e))[0],r=o[1],n=(o=ue(t.points[2],t.points[3],e))[0],h=o[1];var l=ne(i,s,a,r);null===l&&(l=s);var p=ne(n,h,a,r);return null===p&&(p=n),new te(i,l,p,h)}function ye(t,e,i,s,a){var r=e.points[3],n=i.points[0];if(3===s)return r;if(le(r,n))return r;if(2===s){var h=-e.tangentAngle(1),o=-i.tangentAngle(0)+Math.PI,l=ne(r,he(r,h+Math.PI/2,100),n,he(n,h+Math.PI/2,100)),p=l?oe(l,r):oe(r,n)/2,f=he(r,h,2*p*P);return t.setXYAt(f[0],f[1],"o",t.length()-1),f=he(n,o,2*p*P),t.setTripleAt(n[0],n[1],n[0],n[1],f[0],f[1],t.length()),n}var m=ne(le(r,e.points[2])?e.points[0]:e.points[2],r,n,le(n,i.points[1])?i.points[3]:i.points[1]);return m&&oe(m,r)<a?(t.setTripleAt(m[0],m[1],m[0],m[1],m[0],m[1],t.length()),m):r}function ve(t,e){var i=t.intersections(e);return i.length&&Kt(i[0][0],1)&&i.shift(),i.length?i[0]:null}function be(t,e){var i=t.slice(),s=e.slice(),a=ve(t[t.length-1],e[0]);return a&&(i[t.length-1]=t[t.length-1].split(a[0])[0],s[0]=e[0].split(a[1])[1]),t.length>1&&e.length>1&&(a=ve(t[0],e[e.length-1]))?[[t[0].split(a[0])[0]],[e[e.length-1].split(a[1])[1]]]:[i,s]}function _e(t,e){var i,s,a,r,n=t.inflectionPoints();if(0===n.length)return[ge(t,e)];if(1===n.length||Kt(n[1],1))return i=(a=t.split(n[0]))[0],s=a[1],[ge(i,e),ge(s,e)];i=(a=t.split(n[0]))[0];var h=(n[1]-n[0])/(1-n[0]);return r=(a=a[1].split(h))[0],s=a[1],[ge(i,e),ge(r,e),ge(s,e)]}function xe(){}function ke(t){for(var e=t.fStyle?t.fStyle.split(" "):[],i="normal",s="normal",a=e.length,r=0;r<a;r+=1)switch(e[r].toLowerCase()){case"italic":s="italic";break;case"bold":i="700";break;case"black":i="900";break;case"medium":i="500";break;case"regular":case"normal":i="400";break;case"light":case"thin":i="200"}return{style:s,weight:t.fWeight||i}}r([jt],Yt),Yt.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=_t.getProp(t,e.c,0,null,this),this.o=_t.getProp(t,e.o,0,null,this),this.tr=Xt.getTransformProperty(t,e.tr,this),this.so=_t.getProp(t,e.tr.so,0,.01,this),this.eo=_t.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new It,this.rMatrix=new It,this.sMatrix=new It,this.tMatrix=new It,this.matrix=new It},Yt.prototype.applyTransforms=function(t,e,i,s,a,r){var n=r?-1:1,h=s.s.v[0]+(1-s.s.v[0])*(1-a),o=s.s.v[1]+(1-s.s.v[1])*(1-a);t.translate(s.p.v[0]*n*a,s.p.v[1]*n*a,s.p.v[2]),e.translate(-s.a.v[0],-s.a.v[1],s.a.v[2]),e.rotate(-s.r.v*n*a),e.translate(s.a.v[0],s.a.v[1],s.a.v[2]),i.translate(-s.a.v[0],-s.a.v[1],s.a.v[2]),i.scale(r?1/h:h,r?1/o:o),i.translate(s.a.v[0],s.a.v[1],s.a.v[2])},Yt.prototype.init=function(t,e,i,s){for(this.elem=t,this.arr=e,this.pos=i,this.elemsData=s,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[i]);i>0;)i-=1,this._elements.unshift(e[i]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},Yt.prototype.resetElements=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},Yt.prototype.cloneElements=function(t){var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},Yt.prototype.changeGroupRender=function(t,e){var i,s=t.length;for(i=0;i<s;i+=1)t[i]._render=e,"gr"===t[i].ty&&this.changeGroupRender(t[i].it,e)},Yt.prototype.processShapes=function(t){var e,i,s,a,r,n=!1;if(this._mdf||t){var h,o=Math.ceil(this.c.v);if(this._groups.length<o){for(;this._groups.length<o;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(r=0,s=0;s<=this._groups.length-1;s+=1){if(h=r<o,this._groups[s]._render=h,this.changeGroupRender(this._groups[s].it,h),!h){var p=this.elemsData[s].it,f=p[p.length-1];0!==f.transform.op.v?(f.transform.op._mdf=!0,f.transform.op.v=0):f.transform.op._mdf=!1}r+=1}this._currentCopies=o;var m=this.o.v,d=m%1,c=m>0?Math.floor(m):Math.ceil(m),u=this.pMatrix.props,g=this.rMatrix.props,y=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var v,b,_=0;if(m>0){for(;_<c;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),_+=1;d&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,d,!1),_+=d)}else if(m<0){for(;_>c;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),_-=1;d&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-d,!0),_-=d)}for(s=1===this.data.m?0:this._currentCopies-1,a=1===this.data.m?1:-1,r=this._currentCopies;r;){if(b=(i=(e=this.elemsData[s].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(s/(this._currentCopies-1)),0!==_){for((0!==s&&1===a||s!==this._currentCopies-1&&-1===a)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]),v=0;v<b;v+=1)i[v]=this.matrix.props[v];this.matrix.reset()}else for(this.matrix.reset(),v=0;v<b;v+=1)i[v]=this.matrix.props[v];_+=1,r-=1,s+=a}}else for(r=this._currentCopies,s=0,a=1;r;)i=(e=this.elemsData[s].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,r-=1,s+=a;return n},Yt.prototype.addShape=function(){},r([jt],Gt),Gt.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=_t.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},Gt.prototype.processPath=function(t,e){var i,s=St.newElement();s.c=t.c;var a,r,n,h,o,l,p,f,m,d,c,u,g=t._length,y=0;for(i=0;i<g;i+=1)a=t.v[i],n=t.o[i],r=t.i[i],a[0]===n[0]&&a[1]===n[1]&&a[0]===r[0]&&a[1]===r[1]?0!==i&&i!==g-1||t.c?(h=0===i?t.v[g-1]:t.v[i-1],l=(o=Math.sqrt(Math.pow(a[0]-h[0],2)+Math.pow(a[1]-h[1],2)))?Math.min(o/2,e)/o:0,p=c=a[0]+(h[0]-a[0])*l,f=u=a[1]-(a[1]-h[1])*l,m=p-(p-a[0])*P,d=f-(f-a[1])*P,s.setTripleAt(p,f,m,d,c,u,y),y+=1,h=i===g-1?t.v[0]:t.v[i+1],l=(o=Math.sqrt(Math.pow(a[0]-h[0],2)+Math.pow(a[1]-h[1],2)))?Math.min(o/2,e)/o:0,p=m=a[0]+(h[0]-a[0])*l,f=d=a[1]+(h[1]-a[1])*l,c=p-(p-a[0])*P,u=f-(f-a[1])*P,s.setTripleAt(p,f,m,d,c,u,y),y+=1):(s.setTripleAt(a[0],a[1],n[0],n[1],r[0],r[1],y),y+=1):(s.setTripleAt(t.v[i][0],t.v[i][1],t.o[i][0],t.o[i][1],t.i[i][0],t.i[i][1],y),y+=1);return s},Gt.prototype.processShapes=function(t){var e,i,s,a,r,n,h=this.shapes.length,o=this.rd.v;if(0!==o)for(i=0;i<h;i+=1){if(n=(r=this.shapes[i]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,s=0;s<a;s+=1)n.addShape(this.processPath(e[s],o));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},te.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},te.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},te.prototype.tangentAngle=function(t){var e=this.derivative(t);return Math.atan2(e[1],e[0])},te.prototype.normalAngle=function(t){var e=this.derivative(t);return Math.atan2(e[0],e[1])},te.prototype.inflectionPoints=function(){var t=this.a[1]*this.b[0]-this.a[0]*this.b[1];if(Jt(t))return[];var e=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/t,i=e*e-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/t;if(i<0)return[];var s=Math.sqrt(i);return Jt(s)?s>0&&s<1?[e]:[]:[e-s,e+s].filter((function(t){return t>0&&t<1}))},te.prototype.split=function(t){if(t<=0)return[$t(this.points[0]),this];if(t>=1)return[this,$t(this.points[this.points.length-1])];var e=Ut(this.points[0],this.points[1],t),i=Ut(this.points[1],this.points[2],t),s=Ut(this.points[2],this.points[3],t),a=Ut(e,i,t),r=Ut(i,s,t),n=Ut(a,r,t);return[new te(this.points[0],e,a,n,!0),new te(n,r,s,this.points[3],!0)]},te.prototype.bounds=function(){return{x:ee(this,0),y:ee(this,1)}},te.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},te.prototype.intersections=function(t,e,i){void 0===e&&(e=2),void 0===i&&(i=7);var s=[];return ae(ie(this,0,1),ie(t,0,1),0,e,s,i),s},te.shapeSegment=function(t,e){var i=(e+1)%t.length();return new te(t.v[e],t.o[e],t.i[i],t.v[i],!0)},te.shapeSegmentInverted=function(t,e){var i=(e+1)%t.length();return new te(t.v[i],t.i[i],t.o[e],t.v[e],!0)},r([jt],pe),pe.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=_t.getProp(t,e.s,0,null,this),this.frequency=_t.getProp(t,e.r,0,null,this),this.pointsType=_t.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},pe.prototype.processPath=function(t,e,i,s){var a=t._length,r=St.newElement();if(r.c=t.c,t.c||(a-=1),0===a)return r;var n=-1,h=te.shapeSegment(t,0);de(r,t,0,e,i,s,n);for(var o=0;o<a;o+=1)n=ce(r,h,e,i,s,-n),h=o!==a-1||t.c?te.shapeSegment(t,(o+1)%a):null,de(r,t,o+1,e,i,s,n);return r},pe.prototype.processShapes=function(t){var e,i,s,a,r,n,h=this.shapes.length,o=this.amplitude.v,l=Math.max(0,Math.round(this.frequency.v)),p=this.pointsType.v;if(0!==o)for(i=0;i<h;i+=1){if(n=(r=this.shapes[i]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,s=0;s<a;s+=1)n.addShape(this.processPath(e[s],o,l,p));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},r([jt],xe),xe.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=_t.getProp(t,e.a,0,null,this),this.miterLimit=_t.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},xe.prototype.processPath=function(t,e,i,s){var a=St.newElement();a.c=t.c;var r,n,h,o=t.length();t.c||(o-=1);var l=[];for(r=0;r<o;r+=1)h=te.shapeSegment(t,r),l.push(_e(h,e));if(!t.c)for(r=o-1;r>=0;r-=1)h=te.shapeSegmentInverted(t,r),l.push(_e(h,e));l=function(t){for(var e,i=1;i<t.length;i+=1)e=be(t[i-1],t[i]),t[i-1]=e[0],t[i]=e[1];return t.length>1&&(e=be(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}(l);var p=null,f=null;for(r=0;r<l.length;r+=1){var m=l[r];for(f&&(p=ye(a,f,m[0],i,s)),f=m[m.length-1],n=0;n<m.length;n+=1)h=m[n],p&&le(h.points[0],p)?a.setXYAt(h.points[1][0],h.points[1][1],"o",a.length()-1):a.setTripleAt(h.points[0][0],h.points[0][1],h.points[1][0],h.points[1][1],h.points[0][0],h.points[0][1],a.length()),a.setTripleAt(h.points[3][0],h.points[3][1],h.points[3][0],h.points[3][1],h.points[2][0],h.points[2][1],a.length()),p=h.points[3]}return l.length&&ye(a,f,l[0][0],i,s),a},xe.prototype.processShapes=function(t){var e,i,s,a,r,n,h=this.shapes.length,o=this.amount.v,l=this.miterLimit.v,p=this.lineJoin;if(0!==o)for(i=0;i<h;i+=1){if(n=(r=this.shapes[i]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,s=0;s<a;s+=1)n.addShape(this.processPath(e[s],o,p,l));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var we=function(){var t={w:0,size:0,shapes:[],data:{shapes:[]}},e=[];e=e.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);var i=127988,s=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function r(t,e){var i=a("span");i.setAttribute("aria-hidden",!0),i.style.fontFamily=e;var s=a("span");s.innerText="giItT1WQy@!-/#",i.style.position="absolute",i.style.left="-10000px",i.style.top="-10000px",i.style.fontSize="300px",i.style.fontVariant="normal",i.style.fontStyle="normal",i.style.fontWeight="normal",i.style.letterSpacing="0",i.appendChild(s),document.body.appendChild(i);var r=s.offsetWidth;return s.style.fontFamily=function(t){var e,i=t.split(","),s=i.length,a=[];for(e=0;e<s;e+=1)"sans-serif"!==i[e]&&"monospace"!==i[e]&&a.push(i[e]);return a.join(",")}(t)+", "+e,{node:s,w:r,parent:i}}function n(t,e){var i,s=document.body&&e?"svg":"canvas",a=ke(t);if("svg"===s){var r=X("text");r.style.fontSize="100px",r.setAttribute("font-family",t.fFamily),r.setAttribute("font-style",a.style),r.setAttribute("font-weight",a.weight),r.textContent="1",t.fClass?(r.style.fontFamily="inherit",r.setAttribute("class",t.fClass)):r.style.fontFamily=t.fFamily,e.appendChild(r),i=r}else{var n=new OffscreenCanvas(500,500).getContext("2d");n.font=a.style+" "+a.weight+" 100px "+t.fFamily,i=n}return{measureText:function(t){return"svg"===s?(i.textContent=t,i.getComputedTextLength()):i.measureText(t).width}}}function h(t){var e=0,i=t.charCodeAt(0);if(i>=55296&&i<=56319){var s=t.charCodeAt(1);s>=56320&&s<=57343&&(e=1024*(i-55296)+s-56320+65536)}return e}function o(t){var e=h(t);return e>=127462&&e<=127487}var l=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)};l.isModifier=function(t,e){var i=t.toString(16)+e.toString(16);return-1!==s.indexOf(i)},l.isZeroWidthJoiner=function(t){return 8205===t},l.isFlagEmoji=function(t){return o(t.substr(0,2))&&o(t.substr(2,2))},l.isRegionalCode=o,l.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},l.isRegionalFlag=function(t,e){var s=h(t.substr(e,2));if(s!==i)return!1;var a=0;for(e+=2;a<5;){if((s=h(t.substr(e,2)))<917601||s>917626)return!1;a+=1,e+=2}return 917631===h(t.substr(e,2))},l.isVariationSelector=function(t){return 65039===t},l.BLACK_FLAG_CODE_POINT=i;var p={addChars:function(t){if(t){var e;this.chars||(this.chars=[]);var i,s,a=t.length,r=this.chars.length;for(e=0;e<a;e+=1){for(i=0,s=!1;i<r;)this.chars[i].style===t[e].style&&this.chars[i].fFamily===t[e].fFamily&&this.chars[i].ch===t[e].ch&&(s=!0),i+=1;s||(this.chars.push(t[e]),r+=1)}}},addFonts:function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);if(!document.body)return this.isLoaded=!0,t.list.forEach((function(t){t.helper=n(t),t.cache={}})),void(this.fonts=t.list);var i,s=t.list,h=s.length,o=h;for(i=0;i<h;i+=1){var l,p,f=!0;if(s[i].loaded=!1,s[i].monoCase=r(s[i].fFamily,"monospace"),s[i].sansCase=r(s[i].fFamily,"sans-serif"),s[i].fPath){if("p"===s[i].fOrigin||3===s[i].origin){if((l=document.querySelectorAll('style[f-forigin="p"][f-family="'+s[i].fFamily+'"], style[f-origin="3"][f-family="'+s[i].fFamily+'"]')).length>0&&(f=!1),f){var m=a("style");m.setAttribute("f-forigin",s[i].fOrigin),m.setAttribute("f-origin",s[i].origin),m.setAttribute("f-family",s[i].fFamily),m.type="text/css",m.innerText="@font-face {font-family: "+s[i].fFamily+"; font-style: normal; src: url('"+s[i].fPath+"');}",e.appendChild(m)}}else if("g"===s[i].fOrigin||1===s[i].origin){for(l=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),p=0;p<l.length;p+=1)-1!==l[p].href.indexOf(s[i].fPath)&&(f=!1);if(f){var d=a("link");d.setAttribute("f-forigin",s[i].fOrigin),d.setAttribute("f-origin",s[i].origin),d.type="text/css",d.rel="stylesheet",d.href=s[i].fPath,document.body.appendChild(d)}}else if("t"===s[i].fOrigin||2===s[i].origin){for(l=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),p=0;p<l.length;p+=1)s[i].fPath===l[p].src&&(f=!1);if(f){var c=a("link");c.setAttribute("f-forigin",s[i].fOrigin),c.setAttribute("f-origin",s[i].origin),c.setAttribute("rel","stylesheet"),c.setAttribute("href",s[i].fPath),e.appendChild(c)}}}else s[i].loaded=!0,o-=1;s[i].helper=n(s[i],e),s[i].cache={},this.fonts.push(s[i])}0===o?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},getCharData:function(e,i,s){for(var a=0,r=this.chars.length;a<r;){if(this.chars[a].ch===e&&this.chars[a].style===i&&this.chars[a].fFamily===s)return this.chars[a];a+=1}return("string"==typeof e&&13!==e.charCodeAt(0)||!e)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",e,i,s)),t},getFontByName:function(t){for(var e=0,i=this.fonts.length;e<i;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,i){var s=this.getFontByName(e),a=t;if(!s.cache[a]){var r=s.helper;if(" "===t){var n=r.measureText("|"+t+"|"),h=r.measureText("||");s.cache[a]=(n-h)/100}else s.cache[a]=r.measureText(t)/100}return s.cache[a]*i},checkLoadedFonts:function(){var t,e,i,s=this.fonts.length,a=s;for(t=0;t<s;t+=1)this.fonts[t].loaded?a-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,i=this.fonts[t].monoCase.w,e.offsetWidth!==i?(a-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,i=this.fonts[t].sansCase.w,e.offsetWidth!==i&&(a-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==a&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}};return l.prototype=p,l}();function Pe(t){this.animationData=t}function Se(){}Pe.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},Se.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var Ae,De=(Ae={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return Ae[t]||""});function Ce(t,e,i){this.p=_t.getProp(e,t.v,0,0,i)}function Ee(t,e,i){this.p=_t.getProp(e,t.v,0,0,i)}function Me(t,e,i){this.p=_t.getProp(e,t.v,1,0,i)}function Te(t,e,i){this.p=_t.getProp(e,t.v,1,0,i)}function Fe(t,e,i){this.p=_t.getProp(e,t.v,0,0,i)}function Ie(t,e,i){this.p=_t.getProp(e,t.v,0,0,i)}function Le(t,e,i){this.p=_t.getProp(e,t.v,0,0,i)}function Be(){this.p={}}function ze(t,e){var i,s=t.ef||[];this.effectElements=[];var a,r=s.length;for(i=0;i<r;i+=1)a=new Ve(s[i],e),this.effectElements.push(a)}function Ve(t,e){this.init(t,e)}function Re(){}function Oe(){}function Ne(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,i)}function qe(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,i),this._isPlaying=!1,this._canPlay=!1;var s=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(s),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?_t.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=_t.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function je(){}r([xt],Ve),Ve.prototype.getValue=Ve.prototype.iterateDynamicProperties,Ve.prototype.init=function(t,e){var i;this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var s,a=this.data.ef.length,r=this.data.ef;for(i=0;i<a;i+=1){switch(s=null,r[i].ty){case 0:s=new Ce(r[i],e,this);break;case 1:s=new Ee(r[i],e,this);break;case 2:s=new Me(r[i],e,this);break;case 3:s=new Te(r[i],e,this);break;case 4:case 7:s=new Le(r[i],e,this);break;case 10:s=new Fe(r[i],e,this);break;case 11:s=new Ie(r[i],e,this);break;case 5:s=new ze(r[i],e,this);break;default:s=new Be(r[i],e,this)}s&&this.effectElements.push(s)}},Re.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t=j();if(t){var e=t("layer"),i=t("effects"),s=t("shape"),a=t("text"),r=t("comp");this.layerInterface=e(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var n=i.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(n),0===this.data.ty||this.data.xt?this.compInterface=r(this):4===this.data.ty?(this.layerInterface.shapeInterface=s(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=a(this),this.layerInterface.text=this.layerInterface.textInterface)}},setBlendMode:function(){var t=De(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,i){this.globalData=e,this.comp=i,this.data=t,this.layerId=B(),this.data.sr||(this.data.sr=1),this.effectsManager=new ze(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},Oe.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var i,s=this.dynamicProperties.length;for(i=0;i<s;i+=1)(e||this._isParent&&"transform"===this.dynamicProperties[i].propType)&&(this.dynamicProperties[i].getValue(),this.dynamicProperties[i]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},Ne.prototype.prepareFrame=function(){},r([Se,Re,Oe],Ne),Ne.prototype.getBaseElement=function(){return null},Ne.prototype.renderFrame=function(){},Ne.prototype.destroy=function(){},Ne.prototype.initExpressions=function(){var t=j();if(t){var e=t("footage");this.layerInterface=e(this)}},Ne.prototype.getFootageData=function(){return this.footageData},qe.prototype.prepareFrame=function(t){if(this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder)this._currentTime=t/this.data.sr;else{var e=this.tm.v;this._currentTime=e}this._volume=this.lv.v[0];var i=this._volume*this._volumeMultiplier;this._previousVolume!==i&&(this._previousVolume=i,this.audio.volume(i))},r([Se,Re,Oe],qe),qe.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek())>.1)&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},qe.prototype.show=function(){},qe.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},qe.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},qe.prototype.resume=function(){this._canPlay=!0},qe.prototype.setRate=function(t){this.audio.rate(t)},qe.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},qe.prototype.getBaseElement=function(){return null},qe.prototype.destroy=function(){},qe.prototype.sourceRectAtTime=function(){},qe.prototype.initExpressions=function(){},je.prototype.checkLayers=function(t){var e,i,s=this.layers.length;for(this.completeLayers=!0,e=s-1;e>=0;e-=1)this.elements[e]||(i=this.layers[e]).ip-i.st<=t-this.layers[e].st&&i.op-i.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},je.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:default:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t)}},je.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},je.prototype.createAudio=function(t){return new qe(t,this.globalData,this)},je.prototype.createFootage=function(t){return new Ne(t,this.globalData,this)},je.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},je.prototype.includeLayers=function(t){var e;this.completeLayers=!1;var i,s=t.length,a=this.layers.length;for(e=0;e<s;e+=1)for(i=0;i<a;){if(this.layers[i].id===t[e].id){this.layers[i]=t[e];break}i+=1}},je.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},je.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},je.prototype.buildElementParenting=function(t,e,i){for(var s=this.elements,a=this.layers,r=0,n=a.length;r<n;)a[r].ind==e&&(s[r]&&!0!==s[r]?(i.push(s[r]),s[r].setAsParent(),void 0!==a[r].parent?this.buildElementParenting(t,a[r].parent,i):t.setHierarchy(i)):(this.buildItem(r),this.addPendingElement(t))),r+=1},je.prototype.addPendingElement=function(t){this.pendingElements.push(t)},je.prototype.searchExtraCompositions=function(t){var e,i=t.length;for(e=0;e<i;e+=1)if(t[e].xt){var s=this.createComp(t[e]);s.initExpressions(),this.globalData.projectInterface.registerComposition(s)}},je.prototype.getElementById=function(t){var e,i=this.elements.length;for(e=0;e<i;e+=1)if(this.elements[e].data.ind===t)return this.elements[e];return null},je.prototype.getElementByPath=function(t){var e,i=t.shift();if("number"==typeof i)e=this.elements[i];else{var s,a=this.elements.length;for(s=0;s<a;s+=1)if(this.elements[s].data.nm===i){e=this.elements[s];break}}return 0===t.length?e:e.getElementByPath(t)},je.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new we,this.globalData.slotManager=function(t){return new Pe(t)}(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var We="transformEFfect";function He(){}function Xe(t,e,i){this.data=t,this.element=e,this.globalData=i,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var a,r,n=this.globalData.defs,h=this.masksProperties?this.masksProperties.length:0;this.viewData=l(h),this.solidPath="";var o,p,f,m,d,c,u=this.masksProperties,g=0,y=[],v=B(),b="clipPath",_="clip-path";for(a=0;a<h;a+=1)if(("a"!==u[a].mode&&"n"!==u[a].mode||u[a].inv||100!==u[a].o.k||u[a].o.x)&&(b="mask",_="mask"),"s"!==u[a].mode&&"i"!==u[a].mode||0!==g?f=null:((f=X("rect")).setAttribute("fill","#ffffff"),f.setAttribute("width",this.element.comp.data.w||0),f.setAttribute("height",this.element.comp.data.h||0),y.push(f)),r=X("path"),"n"===u[a].mode)this.viewData[a]={op:_t.getProp(this.element,u[a].o,0,.01,this.element),prop:Ft.getShapeProp(this.element,u[a],3),elem:r,lastPath:""},n.appendChild(r);else{var x;if(g+=1,r.setAttribute("fill","s"===u[a].mode?"#000000":"#ffffff"),r.setAttribute("clip-rule","nonzero"),0!==u[a].x.k?(b="mask",_="mask",c=_t.getProp(this.element,u[a].x,0,null,this.element),x=B(),(m=X("filter")).setAttribute("id",x),(d=X("feMorphology")).setAttribute("operator","erode"),d.setAttribute("in","SourceGraphic"),d.setAttribute("radius","0"),m.appendChild(d),n.appendChild(m),r.setAttribute("stroke","s"===u[a].mode?"#000000":"#ffffff")):(d=null,c=null),this.storedData[a]={elem:r,x:c,expan:d,lastPath:"",lastOperator:"",filterId:x,lastRadius:0},"i"===u[a].mode){p=y.length;var k=X("g");for(o=0;o<p;o+=1)k.appendChild(y[o]);var w=X("mask");w.setAttribute("mask-type","alpha"),w.setAttribute("id",v+"_"+g),w.appendChild(r),n.appendChild(w),k.setAttribute("mask","url("+s()+"#"+v+"_"+g+")"),y.length=0,y.push(k)}else y.push(r);u[a].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[a]={elem:r,lastPath:"",op:_t.getProp(this.element,u[a].o,0,.01,this.element),prop:Ft.getShapeProp(this.element,u[a],3),invRect:f},this.viewData[a].prop.k||this.drawPath(u[a],this.viewData[a].prop.v,this.viewData[a])}for(this.maskElement=X(b),h=y.length,a=0;a<h;a+=1)this.maskElement.appendChild(y[a]);g>0&&(this.maskElement.setAttribute("id",v),this.element.maskedElement.setAttribute(_,"url("+s()+"#"+v+")"),n.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}He.prototype={initTransform:function(){var t=new It;this.finalTransform={mProp:this.data.ks?Xt.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,i=0,s=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;i<s;){if(this.hierarchy[i].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}i+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),i=0;i<s;i+=1)e.multiply(this.hierarchy[i].finalTransform.mProp.v)}this.finalTransform._matMdf&&(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var i=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(i),t=1;t<e;t+=1){var s=this.localTransforms[t].matrix;i.multiply(s)}i.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){var a=this.finalTransform.localOpacity;for(t=0;t<e;t+=1)a*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=a}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(We);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new It;var e=0,i=t.length;for(e=0;e<i;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var i,s=!0,a=this.comp;s;)a.finalTransform?(a.data.hasMask&&e.splice(0,0,a.finalTransform),a=a.comp):s=!1;var r,n=e.length;for(i=0;i<n;i+=1)r=e[i].mat.applyToPointArray(0,0,0),t=[t[0]-r[0],t[1]-r[1],0];return t},mHelper:new It},Xe.prototype.getMaskProperty=function(t){return this.viewData[t].prop},Xe.prototype.renderFrame=function(t){var e,i=this.element.finalTransform.mat,a=this.masksProperties.length;for(e=0;e<a;e+=1)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[e].invRect.setAttribute("transform",i.getInverseMatrix().to2dCSS()),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var r=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+s()+"#"+this.storedData[e].filterId+")")),r.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},Xe.prototype.getMaskelement=function(){return this.maskElement},Xe.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},Xe.prototype.drawPath=function(t,e,i){var s,a,r=" M"+e.v[0][0]+","+e.v[0][1];for(a=e._length,s=1;s<a;s+=1)r+=" C"+e.o[s-1][0]+","+e.o[s-1][1]+" "+e.i[s][0]+","+e.i[s][1]+" "+e.v[s][0]+","+e.v[s][1];if(e.c&&a>1&&(r+=" C"+e.o[s-1][0]+","+e.o[s-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),i.lastPath!==r){var n="";i.elem&&(e.c&&(n=t.inv?this.solidPath+r:r),i.elem.setAttribute("d",n)),i.lastPath=r}},Xe.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var Ye=function(){var t={};return t.createFilter=function(t,e){var i=X("filter");i.setAttribute("id",t),!0!==e&&(i.setAttribute("filterUnits","objectBoundingBox"),i.setAttribute("x","0%"),i.setAttribute("y","0%"),i.setAttribute("width","100%"),i.setAttribute("height","100%"));return i},t.createAlphaToLuminanceFilter=function(){var t=X("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},t}(),Ge=function(){var t={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),/firefox/i.test(navigator.userAgent)&&(t.svgLumaHidden=!1),t}(),Ke={},Je="filter_result_";function Ze(t){var e,i,a="SourceGraphic",r=t.data.ef?t.data.ef.length:0,n=B(),h=Ye.createFilter(n,!0),o=0;for(this.filters=[],e=0;e<r;e+=1){i=null;var l=t.data.ef[e].ty;if(Ke[l])i=new(0,Ke[l].effect)(h,t.effectsManager.effectElements[e],t,Je+o,a),a=Je+o,Ke[l].countsAsEffect&&(o+=1);i&&this.filters.push(i)}o&&(t.globalData.defs.appendChild(h),t.layerElement.setAttribute("filter","url("+s()+"#"+n+")")),this.filters.length&&t.addRenderableComponent(this)}function Ue(){}function Qe(){}function $e(){}function ti(t,e,i){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,i),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ei(t,e){this.elem=t,this.pos=e}function ii(){}Ze.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},Ze.prototype.getEffects=function(t){var e,i=this.filters.length,s=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&s.push(this.filters[e]);return s},Ue.prototype={initRendererElement:function(){this.layerElement=X("g")},createContainerElements:function(){this.matteElement=X("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t=null;if(this.data.td){this.matteMasks={};var e=X("g");e.setAttribute("id",this.layerId),e.appendChild(this.layerElement),t=e,this.globalData.defs.appendChild(e)}else this.data.tt?(this.matteElement.appendChild(this.layerElement),t=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var i=X("clipPath"),a=X("path");a.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var r=B();if(i.setAttribute("id",r),i.appendChild(a),this.globalData.defs.appendChild(i),this.checkMasks()){var n=X("g");n.setAttribute("clip-path","url("+s()+"#"+r+")"),n.appendChild(this.layerElement),this.transformedElement=n,t?t.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+s()+"#"+r+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new Xe(this.data,this,this.globalData),this.renderableEffectsManager=new Ze(this),this.searchEffectTransforms()},getMatte:function(t){if(this.matteMasks||(this.matteMasks={}),!this.matteMasks[t]){var e,i,a,r,n=this.layerId+"_"+t;if(1===t||3===t){var h=X("mask");h.setAttribute("id",n),h.setAttribute("mask-type",3===t?"luminance":"alpha"),(a=X("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),h.appendChild(a),this.globalData.defs.appendChild(h),Ge.maskType||1!==t||(h.setAttribute("mask-type","luminance"),e=B(),i=Ye.createFilter(e),this.globalData.defs.appendChild(i),i.appendChild(Ye.createAlphaToLuminanceFilter()),(r=X("g")).appendChild(a),h.appendChild(r),r.setAttribute("filter","url("+s()+"#"+e+")"))}else if(2===t){var o=X("mask");o.setAttribute("id",n),o.setAttribute("mask-type","alpha");var l=X("g");o.appendChild(l),e=B(),i=Ye.createFilter(e);var p=X("feComponentTransfer");p.setAttribute("in","SourceGraphic"),i.appendChild(p);var f=X("feFuncA");f.setAttribute("type","table"),f.setAttribute("tableValues","1.0 0.0"),p.appendChild(f),this.globalData.defs.appendChild(i);var m=X("rect");m.setAttribute("width",this.comp.data.w),m.setAttribute("height",this.comp.data.h),m.setAttribute("x","0"),m.setAttribute("y","0"),m.setAttribute("fill","#ffffff"),m.setAttribute("opacity","0"),l.setAttribute("filter","url("+s()+"#"+e+")"),l.appendChild(m),(a=X("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),l.appendChild(a),Ge.maskType||(o.setAttribute("mask-type","luminance"),i.appendChild(Ye.createAlphaToLuminanceFilter()),r=X("g"),l.appendChild(m),r.appendChild(this.layerElement),l.appendChild(r)),this.globalData.defs.appendChild(o)}this.matteMasks[t]=n}return this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+s()+"#"+t+")")}},Qe.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},r([Se,n({initElement:function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],$e),r([Re,He,Ue,Qe,Oe,$e],ti),ti.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=X("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},ti.prototype.sourceRectAtTime=function(){return this.sourceRect},ii.prototype={addShapeToModifiers:function(t){var e,i=this.shapeModifiers.length;for(e=0;e<i;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;t>=0&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,i=0,s=e.length;i<s;){if(e[i].elem===t)return e[i].pos;i+=1}return 0},addProcessedElement:function(t,e){for(var i=this.processedElements,s=i.length;s;)if(i[s-=1].elem===t)return void(i[s].pos=e);i.push(new ei(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var si={1:"butt",2:"round",3:"square"},ai={1:"miter",2:"round",3:"bevel"};function ri(t,e,i){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=i,this.lvl=e,this._isAnimated=!!i.k;for(var s=0,a=t.length;s<a;){if(t[s].mProps.dynamicProperties.length){this._isAnimated=!0;break}s+=1}}function ni(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=X("path"),this.msElem=null}function hi(t,e,i,s){var a;this.elem=t,this.frameId=-1,this.dataProps=l(e.length),this.renderer=i,this.k=!1,this.dashStr="",this.dashArray=o("float32",e.length?e.length-1:0),this.dashoffset=o("float32",1),this.initDynamicPropertyContainer(s);var r,n=e.length||0;for(a=0;a<n;a+=1)r=_t.getProp(t,e[a].v,0,0,this),this.k=r.k||this.k,this.dataProps[a]={n:e[a].n,p:r};this.k||this.getValue(!0),this._isAnimated=this.k}function oi(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=_t.getProp(t,e.o,0,.01,this),this.w=_t.getProp(t,e.w,0,null,this),this.d=new hi(t,e.d||{},"svg",this),this.c=_t.getProp(t,e.c,1,255,this),this.style=i,this._isAnimated=!!this._isAnimated}function li(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=_t.getProp(t,e.o,0,.01,this),this.c=_t.getProp(t,e.c,1,255,this),this.style=i}function pi(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=i}function fi(t,e,i){this.data=e,this.c=o("uint8c",4*e.p);var s=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=o("float32",s),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=s,this.initDynamicPropertyContainer(i),this.prop=_t.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function mi(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,i)}function di(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=_t.getProp(t,e.w,0,null,this),this.d=new hi(t,e.d||{},"svg",this),this.initGradientData(t,e,i),this._isAnimated=!!this._isAnimated}function ci(){this.it=[],this.prevViewData=[],this.gr=X("g")}function ui(t,e,i){this.transform={mProps:t,op:e,container:i},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}ri.prototype.setAsAnimated=function(){this._isAnimated=!0},ni.prototype.reset=function(){this.d="",this._mdf=!1},hi.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,i=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<i;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},r([xt],hi),r([xt],oi),r([xt],li),r([xt],pi),fi.prototype.comparePoints=function(t,e){for(var i=0,s=this.o.length/2;i<s;){if(Math.abs(t[4*i]-t[4*e+2*i])>.01)return!1;i+=1}return!0},fi.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},fi.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,i,s,a=4*this.data.p;for(e=0;e<a;e+=1)i=e%4==0?100:255,s=Math.round(this.prop.v[e]*i),this.c[e]!==s&&(this.c[e]=s,this._cmdf=!t);if(this.o.length)for(a=this.prop.v.length,e=4*this.data.p;e<a;e+=1)i=e%2==0?100:1,s=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==s&&(this.o[e-4*this.data.p]=s,this._omdf=!t);this._mdf=!t}},r([xt],fi),mi.prototype.initGradientData=function(t,e,i){this.o=_t.getProp(t,e.o,0,.01,this),this.s=_t.getProp(t,e.s,1,null,this),this.e=_t.getProp(t,e.e,1,null,this),this.h=_t.getProp(t,e.h||{k:0},0,.01,this),this.a=_t.getProp(t,e.a||{k:0},0,w,this),this.g=new fi(t,e.g,this),this.style=i,this.stops=[],this.setGradientData(i.pElem,e),this.setGradientOpacity(e,i),this._isAnimated=!!this._isAnimated},mi.prototype.setGradientData=function(t,e){var i=B(),a=X(1===e.t?"linearGradient":"radialGradient");a.setAttribute("id",i),a.setAttribute("spreadMethod","pad"),a.setAttribute("gradientUnits","userSpaceOnUse");var r,n,h,o=[];for(h=4*e.g.p,n=0;n<h;n+=4)r=X("stop"),a.appendChild(r),o.push(r);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+s()+"#"+i+")"),this.gf=a,this.cst=o},mi.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){var i,a,r,n=X("mask"),h=X("path");n.appendChild(h);var o=B(),l=B();n.setAttribute("id",l);var p=X(1===t.t?"linearGradient":"radialGradient");p.setAttribute("id",o),p.setAttribute("spreadMethod","pad"),p.setAttribute("gradientUnits","userSpaceOnUse"),r=t.g.k.k[0].s?t.g.k.k[0].s.length:t.g.k.k.length;var f=this.stops;for(a=4*t.g.p;a<r;a+=2)(i=X("stop")).setAttribute("stop-color","rgb(255,255,255)"),p.appendChild(i),f.push(i);h.setAttribute("gf"===t.ty?"fill":"stroke","url("+s()+"#"+o+")"),"gs"===t.ty&&(h.setAttribute("stroke-linecap",si[t.lc||2]),h.setAttribute("stroke-linejoin",ai[t.lj||2]),1===t.lj&&h.setAttribute("stroke-miterlimit",t.ml)),this.of=p,this.ms=n,this.ost=f,this.maskId=l,e.msElem=h}},r([xt],mi),r([mi,xt],di);var gi=function(t,e,i,s){if(0===e)return"";var a,r=t.o,n=t.i,h=t.v,o=" M"+s.applyToPointStringified(h[0][0],h[0][1]);for(a=1;a<e;a+=1)o+=" C"+s.applyToPointStringified(r[a-1][0],r[a-1][1])+" "+s.applyToPointStringified(n[a][0],n[a][1])+" "+s.applyToPointStringified(h[a][0],h[a][1]);return i&&e&&(o+=" C"+s.applyToPointStringified(r[a-1][0],r[a-1][1])+" "+s.applyToPointStringified(n[0][0],n[0][1])+" "+s.applyToPointStringified(h[0][0],h[0][1]),o+="z"),o},yi=function(){var t=new It,e=new It;function i(t,e,i){(i||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(i||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function s(){}function a(i,s,a){var r,n,h,o,l,p,f,m,d,c,u=s.styles.length,g=s.lvl;for(p=0;p<u;p+=1){if(o=s.sh._mdf||a,s.styles[p].lvl<g){for(m=e.reset(),d=g-s.styles[p].lvl,c=s.transformers.length-1;!o&&d>0;)o=s.transformers[c].mProps._mdf||o,d-=1,c-=1;if(o)for(d=g-s.styles[p].lvl,c=s.transformers.length-1;d>0;)m.multiply(s.transformers[c].mProps.v),d-=1,c-=1}else m=t;if(n=(f=s.sh.paths)._length,o){for(h="",r=0;r<n;r+=1)(l=f.shapes[r])&&l._length&&(h+=gi(l,l._length,l.c,m));s.caches[p]=h}else h=s.caches[p];s.styles[p].d+=!0===i.hd?"":h,s.styles[p]._mdf=o||s.styles[p]._mdf}}function r(t,e,i){var s=e.style;(e.c._mdf||i)&&s.pElem.setAttribute("fill","rgb("+v(e.c.v[0])+","+v(e.c.v[1])+","+v(e.c.v[2])+")"),(e.o._mdf||i)&&s.pElem.setAttribute("fill-opacity",e.o.v)}function n(t,e,i){h(t,e,i),o(t,e,i)}function h(t,e,i){var s,a,r,n,h,o=e.gf,l=e.g._hasOpacity,p=e.s.v,f=e.e.v;if(e.o._mdf||i){var m="gf"===t.ty?"fill-opacity":"stroke-opacity";e.style.pElem.setAttribute(m,e.o.v)}if(e.s._mdf||i){var d=1===t.t?"x1":"cx",c="x1"===d?"y1":"cy";o.setAttribute(d,p[0]),o.setAttribute(c,p[1]),l&&!e.g._collapsable&&(e.of.setAttribute(d,p[0]),e.of.setAttribute(c,p[1]))}if(e.g._cmdf||i){s=e.cst;var u=e.g.c;for(r=s.length,a=0;a<r;a+=1)(n=s[a]).setAttribute("offset",u[4*a]+"%"),n.setAttribute("stop-color","rgb("+u[4*a+1]+","+u[4*a+2]+","+u[4*a+3]+")")}if(l&&(e.g._omdf||i)){var g=e.g.o;for(r=(s=e.g._collapsable?e.cst:e.ost).length,a=0;a<r;a+=1)n=s[a],e.g._collapsable||n.setAttribute("offset",g[2*a]+"%"),n.setAttribute("stop-opacity",g[2*a+1])}if(1===t.t)(e.e._mdf||i)&&(o.setAttribute("x2",f[0]),o.setAttribute("y2",f[1]),l&&!e.g._collapsable&&(e.of.setAttribute("x2",f[0]),e.of.setAttribute("y2",f[1])));else if((e.s._mdf||e.e._mdf||i)&&(h=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)),o.setAttribute("r",h),l&&!e.g._collapsable&&e.of.setAttribute("r",h)),e.e._mdf||e.h._mdf||e.a._mdf||i){h||(h=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)));var y=Math.atan2(f[1]-p[1],f[0]-p[0]),v=e.h.v;v>=1?v=.99:v<=-1&&(v=-.99);var b=h*v,_=Math.cos(y+e.a.v)*b+p[0],x=Math.sin(y+e.a.v)*b+p[1];o.setAttribute("fx",_),o.setAttribute("fy",x),l&&!e.g._collapsable&&(e.of.setAttribute("fx",_),e.of.setAttribute("fy",x))}}function o(t,e,i){var s=e.style,a=e.d;a&&(a._mdf||i)&&a.dashStr&&(s.pElem.setAttribute("stroke-dasharray",a.dashStr),s.pElem.setAttribute("stroke-dashoffset",a.dashoffset[0])),e.c&&(e.c._mdf||i)&&s.pElem.setAttribute("stroke","rgb("+v(e.c.v[0])+","+v(e.c.v[1])+","+v(e.c.v[2])+")"),(e.o._mdf||i)&&s.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||i)&&(s.pElem.setAttribute("stroke-width",e.w.v),s.msElem&&s.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function(t){switch(t.ty){case"fl":return r;case"gf":return h;case"gs":return n;case"st":return o;case"sh":case"el":case"rc":case"sr":return a;case"tr":return i;case"no":return s;default:return null}}}}();function vi(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,i),this.prevViewData=[]}function bi(t,e,i,s,a,r){this.o=t,this.sw=e,this.sc=i,this.fc=s,this.m=a,this.p=r,this._mdf={o:!0,sw:!!e,sc:!!i,fc:!!s,m:!0,p:!0}}function _i(t,e){this._frameId=i,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}r([Re,He,Ue,ii,Qe,Oe,$e],vi),vi.prototype.initSecondaryElement=function(){},vi.prototype.identityMatrix=new It,vi.prototype.buildExpressionInterface=function(){},vi.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},vi.prototype.filterUniqueShapes=function(){var t,e,i,s,a=this.shapes.length,r=this.stylesList.length,n=[],h=!1;for(i=0;i<r;i+=1){for(s=this.stylesList[i],h=!1,n.length=0,t=0;t<a;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(s)&&(n.push(e),h=e._isAnimated||h);n.length>1&&h&&this.setShapesAsAnimated(n)}},vi.prototype.setShapesAsAnimated=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].setAsAnimated()},vi.prototype.createStyleElement=function(t,e){var i,a=new ni(t,e),r=a.pElem;if("st"===t.ty)i=new oi(this,t,a);else if("fl"===t.ty)i=new li(this,t,a);else if("gf"===t.ty||"gs"===t.ty){i=new("gf"===t.ty?mi:di)(this,t,a),this.globalData.defs.appendChild(i.gf),i.maskId&&(this.globalData.defs.appendChild(i.ms),this.globalData.defs.appendChild(i.of),r.setAttribute("mask","url("+s()+"#"+i.maskId+")"))}else"no"===t.ty&&(i=new pi(this,t,a));return"st"!==t.ty&&"gs"!==t.ty||(r.setAttribute("stroke-linecap",si[t.lc||2]),r.setAttribute("stroke-linejoin",ai[t.lj||2]),r.setAttribute("fill-opacity","0"),1===t.lj&&r.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&r.setAttribute("fill-rule","evenodd"),t.ln&&r.setAttribute("id",t.ln),t.cl&&r.setAttribute("class",t.cl),t.bm&&(r.style["mix-blend-mode"]=De(t.bm)),this.stylesList.push(a),this.addToAnimatedContents(t,i),i},vi.prototype.createGroupElement=function(t){var e=new ci;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=De(t.bm)),e},vi.prototype.createTransformElement=function(t,e){var i=Xt.getTransformProperty(this,t,this),s=new ui(i,i.o,e);return this.addToAnimatedContents(t,s),s},vi.prototype.createShapeElement=function(t,e,i){var s=4;"rc"===t.ty?s=5:"el"===t.ty?s=6:"sr"===t.ty&&(s=7);var a=new ri(e,i,Ft.getShapeProp(this,t,s,this));return this.shapes.push(a),this.addShapeToModifiers(a),this.addToAnimatedContents(t,a),a},vi.prototype.addToAnimatedContents=function(t,e){for(var i=0,s=this.animatedContents.length;i<s;){if(this.animatedContents[i].element===e)return;i+=1}this.animatedContents.push({fn:yi.createRenderFunction(t),element:e,data:t})},vi.prototype.setElementStyles=function(t){var e,i=t.styles,s=this.stylesList.length;for(e=0;e<s;e+=1)this.stylesList[e].closed||i.push(this.stylesList[e])},vi.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},vi.prototype.searchShapes=function(t,e,i,s,a,r,n){var h,o,l,p,f,m,d=[].concat(r),c=t.length-1,u=[],g=[];for(h=c;h>=0;h-=1){if((m=this.searchProcessedElement(t[h]))?e[h]=i[m-1]:t[h]._render=n,"fl"===t[h].ty||"st"===t[h].ty||"gf"===t[h].ty||"gs"===t[h].ty||"no"===t[h].ty)m?e[h].style.closed=!1:e[h]=this.createStyleElement(t[h],a),t[h]._render&&e[h].style.pElem.parentNode!==s&&s.appendChild(e[h].style.pElem),u.push(e[h].style);else if("gr"===t[h].ty){if(m)for(l=e[h].it.length,o=0;o<l;o+=1)e[h].prevViewData[o]=e[h].it[o];else e[h]=this.createGroupElement(t[h]);this.searchShapes(t[h].it,e[h].it,e[h].prevViewData,e[h].gr,a+1,d,n),t[h]._render&&e[h].gr.parentNode!==s&&s.appendChild(e[h].gr)}else"tr"===t[h].ty?(m||(e[h]=this.createTransformElement(t[h],s)),p=e[h].transform,d.push(p)):"sh"===t[h].ty||"rc"===t[h].ty||"el"===t[h].ty||"sr"===t[h].ty?(m||(e[h]=this.createShapeElement(t[h],d,a)),this.setElementStyles(e[h])):"tm"===t[h].ty||"rd"===t[h].ty||"ms"===t[h].ty||"pb"===t[h].ty||"zz"===t[h].ty||"op"===t[h].ty?(m?(f=e[h]).closed=!1:((f=qt.getModifier(t[h].ty)).init(this,t[h]),e[h]=f,this.shapeModifiers.push(f)),g.push(f)):"rp"===t[h].ty&&(m?(f=e[h]).closed=!0:(f=qt.getModifier(t[h].ty),e[h]=f,f.init(this,t,h,e),this.shapeModifiers.push(f),n=!1),g.push(f));this.addProcessedElement(t[h],h+1)}for(c=u.length,h=0;h<c;h+=1)u[h].closed=!0;for(c=g.length,h=0;h<c;h+=1)g[h].closed=!0},vi.prototype.renderInnerContent=function(){var t;this.renderModifiers();var e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},vi.prototype.renderShape=function(){var t,e,i=this.animatedContents.length;for(t=0;t<i;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},vi.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},bi.prototype.update=function(t,e,i,s,a,r){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1,this._mdf.p=!1;var n=!1;return this.o!==t&&(this.o=t,this._mdf.o=!0,n=!0),this.sw!==e&&(this.sw=e,this._mdf.sw=!0,n=!0),this.sc!==i&&(this.sc=i,this._mdf.sc=!0,n=!0),this.fc!==s&&(this.fc=s,this._mdf.fc=!0,n=!0),this.m!==a&&(this.m=a,this._mdf.m=!0,n=!0),!r.length||this.p[0]===r[0]&&this.p[1]===r[1]&&this.p[4]===r[4]&&this.p[5]===r[5]&&this.p[12]===r[12]&&this.p[13]===r[13]||(this.p=r,this._mdf.p=!0,n=!0),n},_i.prototype.defaultBoxWidth=[0,0],_i.prototype.copyData=function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},_i.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},_i.prototype.searchProperty=function(){return this.searchKeyframes()},_i.prototype.searchKeyframes=function(){return this.kf=this.data.d.k.length>1,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},_i.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},_i.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,i=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{var s;this.lock=!0,this._mdf=!1;var a=this.effectsSequence.length,r=t||this.data.d.k[this.keysIndex].s;for(s=0;s<a;s+=1)r=i!==this.keysIndex?this.effectsSequence[s](r,r.t):this.effectsSequence[s](this.currentData,r.t);e!==r&&this.setCurrentData(r),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},_i.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,i=0,s=t.length;i<=s-1&&!(i===s-1||t[i+1].t>e);)i+=1;return this.keysIndex!==i&&(this.keysIndex=i),this.data.d.k[this.keysIndex].s},_i.prototype.buildFinalText=function(t){for(var e,i,s=[],a=0,r=t.length,n=!1,h=!1,o="";a<r;)n=h,h=!1,e=t.charCodeAt(a),o=t.charAt(a),we.isCombinedCharacter(e)?n=!0:e>=55296&&e<=56319?we.isRegionalFlag(t,a)?o=t.substr(a,14):(i=t.charCodeAt(a+1))>=56320&&i<=57343&&(we.isModifier(e,i)?(o=t.substr(a,2),n=!0):o=we.isFlagEmoji(t.substr(a,4))?t.substr(a,4):t.substr(a,2)):e>56319?(i=t.charCodeAt(a+1),we.isVariationSelector(e)&&(n=!0)):we.isZeroWidthJoiner(e)&&(n=!0,h=!0),n?(s[s.length-1]+=o,n=!1):s.push(o),a+=o.length;return s},_i.prototype.completeTextData=function(t){t.__complete=!0;var e,i,s,a,r,n,h,o=this.elem.globalData.fontManager,l=this.data,p=[],f=0,m=l.m.g,d=0,c=0,u=0,g=[],y=0,v=0,b=o.getFontByName(t.f),_=0,x=ke(b);t.fWeight=x.weight,t.fStyle=x.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),i=t.finalText.length,t.finalLineHeight=t.lh;var k,w=t.tr/1e3*t.finalSize;if(t.sz)for(var P,S,A=!0,D=t.sz[0],C=t.sz[1];A;){P=0,y=0,i=(S=this.buildFinalText(t.t)).length,w=t.tr/1e3*t.finalSize;var E=-1;for(e=0;e<i;e+=1)k=S[e].charCodeAt(0),s=!1," "===S[e]?E=e:13!==k&&3!==k||(y=0,s=!0,P+=t.finalLineHeight||1.2*t.finalSize),o.chars?(h=o.getCharData(S[e],b.fStyle,b.fFamily),_=s?0:h.w*t.finalSize/100):_=o.measureText(S[e],t.f,t.finalSize),y+_>D&&" "!==S[e]?(-1===E?i+=1:e=E,P+=t.finalLineHeight||1.2*t.finalSize,S.splice(e,E===e?1:0,"\r"),E=-1,y=0):(y+=_,y+=w);P+=b.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&C<P?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=S,i=t.finalText.length,A=!1)}y=-w,_=0;var M,T=0;for(e=0;e<i;e+=1)if(s=!1,13===(k=(M=t.finalText[e]).charCodeAt(0))||3===k?(T=0,g.push(y),v=y>v?y:v,y=-2*w,a="",s=!0,u+=1):a=M,o.chars?(h=o.getCharData(M,b.fStyle,o.getFontByName(t.f).fFamily),_=s?0:h.w*t.finalSize/100):_=o.measureText(a,t.f,t.finalSize)," "===M?T+=_+w:(y+=_+w+T,T=0),p.push({l:_,an:_,add:d,n:s,anIndexes:[],val:a,line:u,animatorJustifyOffset:0}),2==m){if(d+=_,""===a||" "===a||e===i-1){for(""!==a&&" "!==a||(d-=_);c<=e;)p[c].an=d,p[c].ind=f,p[c].extra=_,c+=1;f+=1,d=0}}else if(3==m){if(d+=_,""===a||e===i-1){for(""===a&&(d-=_);c<=e;)p[c].an=d,p[c].ind=f,p[c].extra=_,c+=1;d=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=y>v?y:v,g.push(y),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=g;var F,I,L,B,z=l.a;n=z.length;var V=[];for(r=0;r<n;r+=1){for((F=z[r]).a.sc&&(t.strokeColorAnim=!0),F.a.sw&&(t.strokeWidthAnim=!0),(F.a.fc||F.a.fh||F.a.fs||F.a.fb)&&(t.fillColorAnim=!0),B=0,L=F.s.b,e=0;e<i;e+=1)(I=p[e]).anIndexes[r]=B,(1==L&&""!==I.val||2==L&&""!==I.val&&" "!==I.val||3==L&&(I.n||" "==I.val||e==i-1)||4==L&&(I.n||e==i-1))&&(1===F.s.rn&&V.push(B),B+=1);l.a[r].s.totalChars=B;var R,O=-1;if(1===F.s.rn)for(e=0;e<i;e+=1)O!=(I=p[e]).anIndexes[r]&&(O=I.anIndexes[r],R=V.splice(Math.floor(Math.random()*V.length),1)[0]),I.anIndexes[r]=R}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=b.ascent*t.finalSize/100},_i.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var i=this.copyData({},this.data.d.k[e].s);i=this.copyData(i,t),this.data.d.k[e].s=i,this.recalculate(e),this.setCurrentData(i),this.elem.addDynamicProperty(this)},_i.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},_i.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},_i.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var xi=function(){var t=Math.max,e=Math.min,i=Math.floor;function s(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=_t.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?_t.getProp(t,e.e,0,0,this):{v:100},this.o=_t.getProp(t,e.o||{k:0},0,0,this),this.xe=_t.getProp(t,e.xe||{k:0},0,0,this),this.ne=_t.getProp(t,e.ne||{k:0},0,0,this),this.sm=_t.getProp(t,e.sm||{k:100},0,0,this),this.a=_t.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return s.prototype={getMult:function(s){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var a=0,r=0,n=1,h=1;this.ne.v>0?a=this.ne.v/100:r=-this.ne.v/100,this.xe.v>0?n=1-this.xe.v/100:h=1+this.xe.v/100;var o=it.getBezierEasing(a,r,n,h).get,l=0,p=this.finalS,f=this.finalE,m=this.data.sh;if(2===m)l=o(l=f===p?s>=f?1:0:t(0,e(.5/(f-p)+(s-p)/(f-p),1)));else if(3===m)l=o(l=f===p?s>=f?0:1:1-t(0,e(.5/(f-p)+(s-p)/(f-p),1)));else if(4===m)f===p?l=0:(l=t(0,e(.5/(f-p)+(s-p)/(f-p),1)))<.5?l*=2:l=1-2*(l-.5),l=o(l);else if(5===m){if(f===p)l=0;else{var d=f-p,c=-d/2+(s=e(t(0,s+.5-p),f-p)),u=d/2;l=Math.sqrt(1-c*c/(u*u))}l=o(l)}else 6===m?(f===p?l=0:(s=e(t(0,s+.5-p),f-p),l=(1+Math.cos(Math.PI+2*Math.PI*s/(f-p)))/2),l=o(l)):(s>=i(p)&&(l=t(0,e(s-p<0?e(f,1)-(p-s):f-s,1))),l=o(l));if(100!==this.sm.v){var g=.01*this.sm.v;0===g&&(g=1e-8);var y=.5-.5*g;l<y?l=0:(l=(l-y)/g)>1&&(l=1)}return l*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,i=this.o.v/e,s=this.s.v/e+i,a=this.e.v/e+i;if(s>a){var r=s;s=a,a=r}this.finalS=s,this.finalE=a}},r([xt],s),{getTextSelectorProp:function(t,e,i){return new s(t,e,i)}}}();function ki(t,e,i){var s={propType:!1},a=_t.getProp,r=e.a;this.a={r:r.r?a(t,r.r,0,w,i):s,rx:r.rx?a(t,r.rx,0,w,i):s,ry:r.ry?a(t,r.ry,0,w,i):s,sk:r.sk?a(t,r.sk,0,w,i):s,sa:r.sa?a(t,r.sa,0,w,i):s,s:r.s?a(t,r.s,1,.01,i):s,a:r.a?a(t,r.a,1,0,i):s,o:r.o?a(t,r.o,0,.01,i):s,p:r.p?a(t,r.p,1,0,i):s,sw:r.sw?a(t,r.sw,0,0,i):s,sc:r.sc?a(t,r.sc,1,0,i):s,fc:r.fc?a(t,r.fc,1,0,i):s,fh:r.fh?a(t,r.fh,0,0,i):s,fs:r.fs?a(t,r.fs,0,.01,i):s,fb:r.fb?a(t,r.fb,0,.01,i):s,t:r.t?a(t,r.t,0,0,i):s},this.s=xi.getTextSelectorProp(t,e.s,i),this.s.t=e.s.t}function wi(t,e,i){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=i,this._animatorsData=l(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(i)}function Pi(){}wi.prototype.searchProperties=function(){var t,e,i=this._textData.a.length,s=_t.getProp;for(t=0;t<i;t+=1)e=this._textData.a[t],this._animatorsData[t]=new ki(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:s(this._elem,this._textData.p.a,0,0,this),f:s(this._elem,this._textData.p.f,0,0,this),l:s(this._elem,this._textData.p.l,0,0,this),r:s(this._elem,this._textData.p.r,0,0,this),p:s(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=s(this._elem,this._textData.m.a,1,0,this)},wi.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var i,s,a,r,n,h,o,l,p,f,m,d,c,u,g,y,v,b,_,x=this._moreOptions.alignment.v,k=this._animatorsData,w=this._textData,P=this.mHelper,S=this._renderType,A=this.renderedLetters.length,D=t.l;if(this._hasMaskedPath){if(_=this._pathData.m,!this._pathData.n||this._pathData._mdf){var C,E=_.v;for(this._pathData.r.v&&(E=E.reverse()),n={tLength:0,segments:[]},r=E._length-1,y=0,a=0;a<r;a+=1)C=ht.buildBezierData(E.v[a],E.v[a+1],[E.o[a][0]-E.v[a][0],E.o[a][1]-E.v[a][1]],[E.i[a+1][0]-E.v[a+1][0],E.i[a+1][1]-E.v[a+1][1]]),n.tLength+=C.segmentLength,n.segments.push(C),y+=C.segmentLength;a=r,_.v.c&&(C=ht.buildBezierData(E.v[a],E.v[0],[E.o[a][0]-E.v[a][0],E.o[a][1]-E.v[a][1]],[E.i[0][0]-E.v[0][0],E.i[0][1]-E.v[0][1]]),n.tLength+=C.segmentLength,n.segments.push(C),y+=C.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,h=this._pathData.f.v,m=0,f=1,l=0,p=!0,u=n.segments,h<0&&_.v.c)for(n.tLength<Math.abs(h)&&(h=-Math.abs(h)%n.tLength),f=(c=u[m=u.length-1].points).length-1;h<0;)h+=c[f].partialLength,(f-=1)<0&&(f=(c=u[m-=1].points).length-1);d=(c=u[m].points)[f-1],g=(o=c[f]).partialLength}r=D.length,i=0,s=0;var M,T,F,I,L,B=1.2*t.finalSize*.714,z=!0;F=k.length;var V,q,j,W,H,X,Y,G,K,J,Z,U,Q=-1,$=h,tt=m,et=f,it=-1,st="",at=this.defaultPropsArray;if(2===t.j||1===t.j){var rt=0,nt=0,ot=2===t.j?-.5:-1,lt=0,pt=!0;for(a=0;a<r;a+=1)if(D[a].n){for(rt&&(rt+=nt);lt<a;)D[lt].animatorJustifyOffset=rt,lt+=1;rt=0,pt=!0}else{for(T=0;T<F;T+=1)(M=k[T].a).t.propType&&(pt&&2===t.j&&(nt+=M.t.v*ot),(L=k[T].s.getMult(D[a].anIndexes[T],w.a[T].s.totalChars)).length?rt+=M.t.v*L[0]*ot:rt+=M.t.v*L*ot);pt=!1}for(rt&&(rt+=nt);lt<a;)D[lt].animatorJustifyOffset=rt,lt+=1}for(a=0;a<r;a+=1){if(P.reset(),W=1,D[a].n)i=0,s+=t.yOffset,s+=z?1:0,h=$,z=!1,this._hasMaskedPath&&(f=et,d=(c=u[m=tt].points)[f-1],g=(o=c[f]).partialLength,l=0),st="",Z="",K="",U="",at=this.defaultPropsArray;else{if(this._hasMaskedPath){if(it!==D[a].line){switch(t.j){case 1:h+=y-t.lineWidths[D[a].line];break;case 2:h+=(y-t.lineWidths[D[a].line])/2}it=D[a].line}Q!==D[a].ind&&(D[Q]&&(h+=D[Q].extra),h+=D[a].an/2,Q=D[a].ind),h+=x[0]*D[a].an*.005;var ft=0;for(T=0;T<F;T+=1)(M=k[T].a).p.propType&&((L=k[T].s.getMult(D[a].anIndexes[T],w.a[T].s.totalChars)).length?ft+=M.p.v[0]*L[0]:ft+=M.p.v[0]*L),M.a.propType&&((L=k[T].s.getMult(D[a].anIndexes[T],w.a[T].s.totalChars)).length?ft+=M.a.v[0]*L[0]:ft+=M.a.v[0]*L);for(p=!0,this._pathData.a.v&&(h=.5*D[0].an+(y-this._pathData.f.v-.5*D[0].an-.5*D[D.length-1].an)*Q/(r-1),h+=this._pathData.f.v);p;)l+g>=h+ft||!c?(v=(h+ft-l)/o.partialLength,q=d.point[0]+(o.point[0]-d.point[0])*v,j=d.point[1]+(o.point[1]-d.point[1])*v,P.translate(-x[0]*D[a].an*.005,-x[1]*B*.01),p=!1):c&&(l+=o.partialLength,(f+=1)>=c.length&&(f=0,u[m+=1]?c=u[m].points:_.v.c?(f=0,c=u[m=0].points):(l-=o.partialLength,c=null)),c&&(d=o,g=(o=c[f]).partialLength));V=D[a].an/2-D[a].add,P.translate(-V,0,0)}else V=D[a].an/2-D[a].add,P.translate(-V,0,0),P.translate(-x[0]*D[a].an*.005,-x[1]*B*.01,0);for(T=0;T<F;T+=1)(M=k[T].a).t.propType&&(L=k[T].s.getMult(D[a].anIndexes[T],w.a[T].s.totalChars),0===i&&0===t.j||(this._hasMaskedPath?L.length?h+=M.t.v*L[0]:h+=M.t.v*L:L.length?i+=M.t.v*L[0]:i+=M.t.v*L));for(t.strokeWidthAnim&&(X=t.sw||0),t.strokeColorAnim&&(H=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(Y=[t.fc[0],t.fc[1],t.fc[2]]),T=0;T<F;T+=1)(M=k[T].a).a.propType&&((L=k[T].s.getMult(D[a].anIndexes[T],w.a[T].s.totalChars)).length?P.translate(-M.a.v[0]*L[0],-M.a.v[1]*L[1],M.a.v[2]*L[2]):P.translate(-M.a.v[0]*L,-M.a.v[1]*L,M.a.v[2]*L));for(T=0;T<F;T+=1)(M=k[T].a).s.propType&&((L=k[T].s.getMult(D[a].anIndexes[T],w.a[T].s.totalChars)).length?P.scale(1+(M.s.v[0]-1)*L[0],1+(M.s.v[1]-1)*L[1],1):P.scale(1+(M.s.v[0]-1)*L,1+(M.s.v[1]-1)*L,1));for(T=0;T<F;T+=1){if(M=k[T].a,L=k[T].s.getMult(D[a].anIndexes[T],w.a[T].s.totalChars),M.sk.propType&&(L.length?P.skewFromAxis(-M.sk.v*L[0],M.sa.v*L[1]):P.skewFromAxis(-M.sk.v*L,M.sa.v*L)),M.r.propType&&(L.length?P.rotateZ(-M.r.v*L[2]):P.rotateZ(-M.r.v*L)),M.ry.propType&&(L.length?P.rotateY(M.ry.v*L[1]):P.rotateY(M.ry.v*L)),M.rx.propType&&(L.length?P.rotateX(M.rx.v*L[0]):P.rotateX(M.rx.v*L)),M.o.propType&&(L.length?W+=(M.o.v*L[0]-W)*L[0]:W+=(M.o.v*L-W)*L),t.strokeWidthAnim&&M.sw.propType&&(L.length?X+=M.sw.v*L[0]:X+=M.sw.v*L),t.strokeColorAnim&&M.sc.propType)for(G=0;G<3;G+=1)L.length?H[G]+=(M.sc.v[G]-H[G])*L[0]:H[G]+=(M.sc.v[G]-H[G])*L;if(t.fillColorAnim&&t.fc){if(M.fc.propType)for(G=0;G<3;G+=1)L.length?Y[G]+=(M.fc.v[G]-Y[G])*L[0]:Y[G]+=(M.fc.v[G]-Y[G])*L;M.fh.propType&&(Y=L.length?N(Y,M.fh.v*L[0]):N(Y,M.fh.v*L)),M.fs.propType&&(Y=L.length?R(Y,M.fs.v*L[0]):R(Y,M.fs.v*L)),M.fb.propType&&(Y=L.length?O(Y,M.fb.v*L[0]):O(Y,M.fb.v*L))}}for(T=0;T<F;T+=1)(M=k[T].a).p.propType&&(L=k[T].s.getMult(D[a].anIndexes[T],w.a[T].s.totalChars),this._hasMaskedPath?L.length?P.translate(0,M.p.v[1]*L[0],-M.p.v[2]*L[1]):P.translate(0,M.p.v[1]*L,-M.p.v[2]*L):L.length?P.translate(M.p.v[0]*L[0],M.p.v[1]*L[1],-M.p.v[2]*L[2]):P.translate(M.p.v[0]*L,M.p.v[1]*L,-M.p.v[2]*L));if(t.strokeWidthAnim&&(K=X<0?0:X),t.strokeColorAnim&&(J="rgb("+Math.round(255*H[0])+","+Math.round(255*H[1])+","+Math.round(255*H[2])+")"),t.fillColorAnim&&t.fc&&(Z="rgb("+Math.round(255*Y[0])+","+Math.round(255*Y[1])+","+Math.round(255*Y[2])+")"),this._hasMaskedPath){if(P.translate(0,-t.ls),P.translate(0,x[1]*B*.01+s,0),this._pathData.p.v){b=(o.point[1]-d.point[1])/(o.point[0]-d.point[0]);var mt=180*Math.atan(b)/Math.PI;o.point[0]<d.point[0]&&(mt+=180),P.rotate(-mt*Math.PI/180)}P.translate(q,j,0),h-=x[0]*D[a].an*.005,D[a+1]&&Q!==D[a+1].ind&&(h+=D[a].an/2,h+=.001*t.tr*t.finalSize)}else{switch(P.translate(i,s,0),t.ps&&P.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:P.translate(D[a].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[D[a].line]),0,0);break;case 2:P.translate(D[a].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[D[a].line])/2,0,0)}P.translate(0,-t.ls),P.translate(V,0,0),P.translate(x[0]*D[a].an*.005,x[1]*B*.01,0),i+=D[a].l+.001*t.tr*t.finalSize}"html"===S?st=P.toCSS():"svg"===S?st=P.to2dCSS():at=[P.props[0],P.props[1],P.props[2],P.props[3],P.props[4],P.props[5],P.props[6],P.props[7],P.props[8],P.props[9],P.props[10],P.props[11],P.props[12],P.props[13],P.props[14],P.props[15]],U=W}A<=a?(I=new bi(U,K,J,Z,st,at),this.renderedLetters.push(I),A+=1,this.lettersChangedFlag=!0):(I=this.renderedLetters[a],this.lettersChangedFlag=I.update(U,K,J,Z,st,at)||this.lettersChangedFlag)}}},wi.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},wi.prototype.mHelper=new It,wi.prototype.defaultPropsArray=[],r([xt],wi),Pi.prototype.initElement=function(t,e,i){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,i),this.textProperty=new _i(this,t.t,this.dynamicProperties),this.textAnimator=new wi(t.t,this.renderType,this),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},Pi.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},Pi.prototype.createPathShape=function(t,e){var i,s,a=e.length,r="";for(i=0;i<a;i+=1)"sh"===e[i].ty&&(s=e[i].ks.k,r+=gi(s,s.i.length,!0,t));return r},Pi.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},Pi.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},Pi.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},Pi.prototype.applyTextPropertiesToMatrix=function(t,e,i,s,a){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i])/2,0,0)}e.translate(s,a,0)},Pi.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},Pi.prototype.emptyProp=new bi,Pi.prototype.destroy=function(){},Pi.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var Si={shapes:[]};function Ai(t,e,i){this.textSpans=[],this.renderType="svg",this.initElement(t,e,i)}function Di(t,e,i){this.initElement(t,e,i)}function Ci(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initFrame(),this.initTransform(t,e,i),this.initHierarchy()}function Ei(){}function Mi(){}function Ti(t,e,i){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?l(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?_t.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function Fi(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=X("svg");var i="";if(e&&e.title){var s=X("title"),a=B();s.setAttribute("id",a),s.textContent=e.title,this.svgElement.appendChild(s),i+=a}if(e&&e.description){var r=X("desc"),n=B();r.setAttribute("id",n),r.textContent=e.description,this.svgElement.appendChild(r),i+=" "+n}i&&this.svgElement.setAttribute("aria-labelledby",i);var h=X("defs");this.svgElement.appendChild(h);var o=X("g");this.svgElement.appendChild(o),this.layerElement=o,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:h,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}r([Re,He,Ue,Qe,Oe,$e,Pi],Ai),Ai.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=X("text"))},Ai.prototype.buildTextContents=function(t){for(var e=0,i=t.length,s=[],a="";e<i;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(s.push(a),a=""):a+=t[e],e+=1;return s.push(a),s},Ai.prototype.buildShapeData=function(t,e){if(t.shapes&&t.shapes.length){var i=t.shapes[0];if(i.it){var s=i.it[i.it.length-1];s.s&&(s.s.k[0]=e,s.s.k[1]=e)}}return t},Ai.prototype.buildNewText=function(){var t,e;this.addDynamicProperty(this);var i=this.textProperty.currentData;this.renderedLetters=l(i?i.l.length:0),i.fc?this.layerElement.setAttribute("fill",this.buildColor(i.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),i.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(i.sc)),this.layerElement.setAttribute("stroke-width",i.sw)),this.layerElement.setAttribute("font-size",i.finalSize);var s=this.globalData.fontManager.getFontByName(i.f);if(s.fClass)this.layerElement.setAttribute("class",s.fClass);else{this.layerElement.setAttribute("font-family",s.fFamily);var a=i.fWeight,r=i.fStyle;this.layerElement.setAttribute("font-style",r),this.layerElement.setAttribute("font-weight",a)}this.layerElement.setAttribute("aria-label",i.t);var n,h=i.l||[],o=!!this.globalData.fontManager.chars;e=h.length;var p=this.mHelper,f=this.data.singleShape,m=0,d=0,c=!0,u=.001*i.tr*i.finalSize;if(!f||o||i.sz){var g,y=this.textSpans.length;for(t=0;t<e;t+=1){if(this.textSpans[t]||(this.textSpans[t]={span:null,childSpan:null,glyph:null}),!o||!f||0===t){if(n=y>t?this.textSpans[t].span:X(o?"g":"text"),y<=t){if(n.setAttribute("stroke-linecap","butt"),n.setAttribute("stroke-linejoin","round"),n.setAttribute("stroke-miterlimit","4"),this.textSpans[t].span=n,o){var v=X("g");n.appendChild(v),this.textSpans[t].childSpan=v}this.textSpans[t].span=n,this.layerElement.appendChild(n)}n.style.display="inherit"}if(p.reset(),f&&(h[t].n&&(m=-u,d+=i.yOffset,d+=c?1:0,c=!1),this.applyTextPropertiesToMatrix(i,p,h[t].line,m,d),m+=h[t].l||0,m+=u),o){var b;if(1===(g=this.globalData.fontManager.getCharData(i.finalText[t],s.fStyle,this.globalData.fontManager.getFontByName(i.f).fFamily)).t)b=new Ti(g.data,this.globalData,this);else{var _=Si;g.data&&g.data.shapes&&(_=this.buildShapeData(g.data,i.finalSize)),b=new vi(_,this.globalData,this)}if(this.textSpans[t].glyph){var x=this.textSpans[t].glyph;this.textSpans[t].childSpan.removeChild(x.layerElement),x.destroy()}this.textSpans[t].glyph=b,b._debug=!0,b.prepareFrame(0),b.renderFrame(),this.textSpans[t].childSpan.appendChild(b.layerElement),1===g.t&&this.textSpans[t].childSpan.setAttribute("transform","scale("+i.finalSize/100+","+i.finalSize/100+")")}else f&&n.setAttribute("transform","translate("+p.props[12]+","+p.props[13]+")"),n.textContent=h[t].val,n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}f&&n&&n.setAttribute("d","")}else{var k=this.textContainer,w="start";switch(i.j){case 1:w="end";break;case 2:w="middle";break;default:w="start"}k.setAttribute("text-anchor",w),k.setAttribute("letter-spacing",u);var P=this.buildTextContents(i.finalText);for(e=P.length,d=i.ps?i.ps[1]+i.ascent:0,t=0;t<e;t+=1)(n=this.textSpans[t].span||X("tspan")).textContent=P[t],n.setAttribute("x",0),n.setAttribute("y",d),n.style.display="inherit",k.appendChild(n),this.textSpans[t]||(this.textSpans[t]={span:null,glyph:null}),this.textSpans[t].span=n,d+=i.finalLineHeight;this.layerElement.appendChild(k)}for(;t<this.textSpans.length;)this.textSpans[t].span.style.display="none",t+=1;this._sizeChanged=!0},Ai.prototype.sourceRectAtTime=function(){if(this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged){this._sizeChanged=!1;var t=this.layerElement.getBBox();this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}}return this.bbox},Ai.prototype.getValue=function(){var t,e,i=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<i;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf&&(this._mdf=!0))},Ai.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){var t,e;this._sizeChanged=!0;var i,s,a,r=this.textAnimator.renderedLetters,n=this.textProperty.currentData.l;for(e=n.length,t=0;t<e;t+=1)n[t].n||(i=r[t],s=this.textSpans[t].span,(a=this.textSpans[t].glyph)&&a.renderFrame(),i._mdf.m&&s.setAttribute("transform",i.m),i._mdf.o&&s.setAttribute("opacity",i.o),i._mdf.sw&&s.setAttribute("stroke-width",i.sw),i._mdf.sc&&s.setAttribute("stroke",i.sc),i._mdf.fc&&s.setAttribute("fill",i.fc))}},r([ti],Di),Di.prototype.createContent=function(){var t=X("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},Ci.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},Ci.prototype.renderFrame=function(){},Ci.prototype.getBaseElement=function(){return null},Ci.prototype.destroy=function(){},Ci.prototype.sourceRectAtTime=function(){},Ci.prototype.hide=function(){},r([Re,He,Qe,Oe],Ci),r([je],Ei),Ei.prototype.createNull=function(t){return new Ci(t,this.globalData,this)},Ei.prototype.createShape=function(t){return new vi(t,this.globalData,this)},Ei.prototype.createText=function(t){return new Ai(t,this.globalData,this)},Ei.prototype.createImage=function(t){return new ti(t,this.globalData,this)},Ei.prototype.createSolid=function(t){return new Di(t,this.globalData,this)},Ei.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var i=X("clipPath"),a=X("rect");a.setAttribute("width",t.w),a.setAttribute("height",t.h),a.setAttribute("x",0),a.setAttribute("y",0);var r=B();i.setAttribute("id",r),i.appendChild(a),this.layerElement.setAttribute("clip-path","url("+s()+"#"+r+")"),e.appendChild(i),this.layers=t.layers,this.elements=l(t.layers.length)},Ei.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},Ei.prototype.updateContainerSize=function(){},Ei.prototype.findIndexByInd=function(t){var e=0,i=this.layers.length;for(e=0;e<i;e+=1)if(this.layers[e].ind===t)return e;return-1},Ei.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){e[t]=!0;var i=this.createItem(this.layers[t]);if(e[t]=i,q()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(i),i.initExpressions()),this.appendElementInPos(i,t),this.layers[t].tt){var s="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1;if(-1===s)return;if(this.elements[s]&&!0!==this.elements[s]){var a=e[s].getMatte(this.layers[t].tt);i.setMatte(a)}else this.buildItem(s),this.addPendingElement(i)}}},Ei.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,i=this.elements.length;e<i;){if(this.elements[e]===t){var s="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,a=this.elements[s].getMatte(this.layers[e].tt);t.setMatte(a);break}e+=1}}},Ei.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){var e;null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var i=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=i-1;e>=0;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<i;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},Ei.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){for(var s,a=0;a<e;)this.elements[a]&&!0!==this.elements[a]&&this.elements[a].getBaseElement()&&(s=this.elements[a].getBaseElement()),a+=1;s?this.layerElement.insertBefore(i,s):this.layerElement.appendChild(i)}},Ei.prototype.hide=function(){this.layerElement.style.display="none"},Ei.prototype.show=function(){this.layerElement.style.display="block"},r([Re,He,Qe,Oe,$e],Mi),Mi.prototype.initElement=function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},Mi.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var i,s=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),i=s-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&(this.elements[i].prepareFrame(this.renderedFrame-this.layers[i].st),this.elements[i]._mdf&&(this._mdf=!0))}},Mi.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},Mi.prototype.setElements=function(t){this.elements=t},Mi.prototype.getElements=function(){return this.elements},Mi.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},Mi.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},r([Ei,Mi,Ue],Ti),Ti.prototype.createComp=function(t){return new Ti(t,this.globalData,this)},r([Ei],Fi),Fi.prototype.createComp=function(t){return new Ti(t,this.globalData,this)};var Ii,Li={};function Bi(t){var e,i,s=t.data.ef?t.data.ef.length:0;for(this.filters=[],e=0;e<s;e+=1){i=null;var a=t.data.ef[e].ty;if(Li[a])i=new(0,Li[a].effect)(t.effectsManager.effectElements[e],t);i&&this.filters.push(i)}this.filters.length&&t.addRenderableComponent(this)}function zi(){}function Vi(t,e,i){this.initElement(t,e,i)}function Ri(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.shapesContainer=X("g"),this.initElement(t,e,i),this.prevViewData=[],this.currentBBox={x:999999,y:-999999,h:0,w:0}}function Oi(t,e,i){this.textSpans=[],this.textPaths=[],this.currentBBox={x:999999,y:-999999,h:0,w:0},this.renderType="svg",this.isMasked=!1,this.initElement(t,e,i)}function Ni(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initHierarchy();var s=_t.getProp;if(this.pe=s(this,t.pe,0,0,this),t.ks.p.s?(this.px=s(this,t.ks.p.x,1,0,this),this.py=s(this,t.ks.p.y,1,0,this),this.pz=s(this,t.ks.p.z,1,0,this)):this.p=s(this,t.ks.p,1,0,this),t.ks.a&&(this.a=s(this,t.ks.a,1,0,this)),t.ks.or.k.length&&t.ks.or.k[0].to){var a,r=t.ks.or.k.length;for(a=0;a<r;a+=1)t.ks.or.k[a].to=null,t.ks.or.k[a].ti=null}this.or=s(this,t.ks.or,1,w,this),this.or.sh=!0,this.rx=s(this,t.ks.rx,0,w,this),this.ry=s(this,t.ks.ry,0,w,this),this.rz=s(this,t.ks.rz,0,w,this),this.mat=new It,this._prevMat=new It,this._isFirstFrame=!0,this.finalTransform={mProp:this}}function qi(t,e,i){this.assetData=e.getAssetData(t.refId),this.initElement(t,e,i)}function ji(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"}},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}function Wi(t,e,i){this.layers=t.layers,this.supports3d=!t.hasMask,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?l(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?_t.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function Hi(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"},runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}return Bi.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},Bi.prototype.getEffects=function(t){var e,i=this.filters.length,s=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&s.push(this.filters[e]);return s},zi.prototype={checkBlendMode:function(){},initRendererElement:function(){this.baseElement=a(this.data.tg||"div"),this.data.hasMask?(this.svgElement=X("svg"),this.layerElement=X("g"),this.maskedElement=this.layerElement,this.svgElement.appendChild(this.layerElement),this.baseElement.appendChild(this.svgElement)):this.layerElement=this.baseElement,A(this.baseElement)},createContainerElements:function(){this.renderableEffectsManager=new Bi(this),this.transformedElement=this.baseElement,this.maskedElement=this.layerElement,this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0!==this.data.bm&&this.setBlendMode()},renderElement:function(){var t=this.transformedElement?this.transformedElement.style:{};if(this.finalTransform._matMdf){var e=this.finalTransform.mat.toCSS();t.transform=e,t.webkitTransform=e}this.finalTransform._opMdf&&(t.opacity=this.finalTransform.mProp.o.v)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},destroy:function(){this.layerElement=null,this.transformedElement=null,this.matteElement&&(this.matteElement=null),this.maskManager&&(this.maskManager.destroy(),this.maskManager=null)},createRenderableComponents:function(){this.maskManager=new Xe(this.data,this,this.globalData)},addEffects:function(){},setMatte:function(){}},zi.prototype.getBaseElement=Ue.prototype.getBaseElement,zi.prototype.destroyBaseElement=zi.prototype.destroy,zi.prototype.buildElementParenting=je.prototype.buildElementParenting,r([Re,He,zi,Qe,Oe,$e],Vi),Vi.prototype.createContent=function(){var t;this.data.hasMask?((t=X("rect")).setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.svgElement.setAttribute("width",this.data.sw),this.svgElement.setAttribute("height",this.data.sh)):((t=a("div")).style.width=this.data.sw+"px",t.style.height=this.data.sh+"px",t.style.backgroundColor=this.data.sc),this.layerElement.appendChild(t)},r([Re,He,Vi,vi,zi,Qe,Oe,Se],Ri),Ri.prototype._renderShapeFrame=Ri.prototype.renderInnerContent,Ri.prototype.createContent=function(){var t;if(this.baseElement.style.fontSize=0,this.data.hasMask)this.layerElement.appendChild(this.shapesContainer),t=this.svgElement;else{t=X("svg");var e=this.comp.data?this.comp.data:this.globalData.compSize;t.setAttribute("width",e.w),t.setAttribute("height",e.h),t.appendChild(this.shapesContainer),this.layerElement.appendChild(t)}this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.shapesContainer,0,[],!0),this.filterUniqueShapes(),this.shapeCont=t},Ri.prototype.getTransformedPoint=function(t,e){var i,s=t.length;for(i=0;i<s;i+=1)e=t[i].mProps.v.applyToPointArray(e[0],e[1],0);return e},Ri.prototype.calculateShapeBoundingBox=function(t,e){var i,s,a,r,n,h=t.sh.v,o=t.transformers,l=h._length;if(!(l<=1)){for(i=0;i<l-1;i+=1)s=this.getTransformedPoint(o,h.v[i]),a=this.getTransformedPoint(o,h.o[i]),r=this.getTransformedPoint(o,h.i[i+1]),n=this.getTransformedPoint(o,h.v[i+1]),this.checkBounds(s,a,r,n,e);h.c&&(s=this.getTransformedPoint(o,h.v[i]),a=this.getTransformedPoint(o,h.o[i]),r=this.getTransformedPoint(o,h.i[0]),n=this.getTransformedPoint(o,h.v[0]),this.checkBounds(s,a,r,n,e))}},Ri.prototype.checkBounds=function(t,e,i,s,a){this.getBoundsOfCurve(t,e,i,s);var r=this.shapeBoundingBox;a.x=_(r.left,a.x),a.xMax=b(r.right,a.xMax),a.y=_(r.top,a.y),a.yMax=b(r.bottom,a.yMax)},Ri.prototype.shapeBoundingBox={left:0,right:0,top:0,bottom:0},Ri.prototype.tempBoundingBox={x:0,xMax:0,y:0,yMax:0,width:0,height:0},Ri.prototype.getBoundsOfCurve=function(t,e,i,s){for(var a,r,n,h,o,l,p,f=[[t[0],s[0]],[t[1],s[1]]],m=0;m<2;++m)r=6*t[m]-12*e[m]+6*i[m],a=-3*t[m]+9*e[m]-9*i[m]+3*s[m],n=3*e[m]-3*t[m],r|=0,n|=0,0===(a|=0)&&0===r||(0===a?(h=-n/r)>0&&h<1&&f[m].push(this.calculateF(h,t,e,i,s,m)):(o=r*r-4*n*a)>=0&&((l=(-r+y(o))/(2*a))>0&&l<1&&f[m].push(this.calculateF(l,t,e,i,s,m)),(p=(-r-y(o))/(2*a))>0&&p<1&&f[m].push(this.calculateF(p,t,e,i,s,m))));this.shapeBoundingBox.left=_.apply(null,f[0]),this.shapeBoundingBox.top=_.apply(null,f[1]),this.shapeBoundingBox.right=b.apply(null,f[0]),this.shapeBoundingBox.bottom=b.apply(null,f[1])},Ri.prototype.calculateF=function(t,e,i,s,a,r){return g(1-t,3)*e[r]+3*g(1-t,2)*t*i[r]+3*(1-t)*g(t,2)*s[r]+g(t,3)*a[r]},Ri.prototype.calculateBoundingBox=function(t,e){var i,s=t.length;for(i=0;i<s;i+=1)t[i]&&t[i].sh?this.calculateShapeBoundingBox(t[i],e):t[i]&&t[i].it?this.calculateBoundingBox(t[i].it,e):t[i]&&t[i].style&&t[i].w&&this.expandStrokeBoundingBox(t[i].w,e)},Ri.prototype.expandStrokeBoundingBox=function(t,e){var i=0;if(t.keyframes){for(var s=0;s<t.keyframes.length;s+=1){var a=t.keyframes[s].s;a>i&&(i=a)}i*=t.mult}else i=t.v*t.mult;e.x-=i,e.xMax+=i,e.y-=i,e.yMax+=i},Ri.prototype.currentBoxContains=function(t){return this.currentBBox.x<=t.x&&this.currentBBox.y<=t.y&&this.currentBBox.width+this.currentBBox.x>=t.x+t.width&&this.currentBBox.height+this.currentBBox.y>=t.y+t.height},Ri.prototype.renderInnerContent=function(){if(this._renderShapeFrame(),!this.hidden&&(this._isFirstFrame||this._mdf)){var t=this.tempBoundingBox,e=999999;if(t.x=e,t.xMax=-e,t.y=e,t.yMax=-e,this.calculateBoundingBox(this.itemsData,t),t.width=t.xMax<t.x?0:t.xMax-t.x,t.height=t.yMax<t.y?0:t.yMax-t.y,this.currentBoxContains(t))return;var i=!1;if(this.currentBBox.w!==t.width&&(this.currentBBox.w=t.width,this.shapeCont.setAttribute("width",t.width),i=!0),this.currentBBox.h!==t.height&&(this.currentBBox.h=t.height,this.shapeCont.setAttribute("height",t.height),i=!0),i||this.currentBBox.x!==t.x||this.currentBBox.y!==t.y){this.currentBBox.w=t.width,this.currentBBox.h=t.height,this.currentBBox.x=t.x,this.currentBBox.y=t.y,this.shapeCont.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h);var s=this.shapeCont.style,a="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)";s.transform=a,s.webkitTransform=a}}},r([Re,He,zi,Qe,Oe,$e,Pi],Oi),Oi.prototype.createContent=function(){if(this.isMasked=this.checkMasks(),this.isMasked){this.renderType="svg",this.compW=this.comp.data.w,this.compH=this.comp.data.h,this.svgElement.setAttribute("width",this.compW),this.svgElement.setAttribute("height",this.compH);var t=X("g");this.maskedElement.appendChild(t),this.innerElem=t}else this.renderType="html",this.innerElem=this.layerElement;this.checkParenting()},Oi.prototype.buildNewText=function(){var t=this.textProperty.currentData;this.renderedLetters=l(t.l?t.l.length:0);var e=this.innerElem.style,i=t.fc?this.buildColor(t.fc):"rgba(0,0,0,0)";e.fill=i,e.color=i,t.sc&&(e.stroke=this.buildColor(t.sc),e.strokeWidth=t.sw+"px");var s,r,n=this.globalData.fontManager.getFontByName(t.f);if(!this.globalData.fontManager.chars)if(e.fontSize=t.finalSize+"px",e.lineHeight=t.finalSize+"px",n.fClass)this.innerElem.className=n.fClass;else{e.fontFamily=n.fFamily;var h=t.fWeight,o=t.fStyle;e.fontStyle=o,e.fontWeight=h}var p,f,m,d=t.l;r=d.length;var c,u=this.mHelper,g="",y=0;for(s=0;s<r;s+=1){if(this.globalData.fontManager.chars?(this.textPaths[y]?p=this.textPaths[y]:((p=X("path")).setAttribute("stroke-linecap",si[1]),p.setAttribute("stroke-linejoin",ai[2]),p.setAttribute("stroke-miterlimit","4")),this.isMasked||(this.textSpans[y]?m=(f=this.textSpans[y]).children[0]:((f=a("div")).style.lineHeight=0,(m=X("svg")).appendChild(p),A(f)))):this.isMasked?p=this.textPaths[y]?this.textPaths[y]:X("text"):this.textSpans[y]?(f=this.textSpans[y],p=this.textPaths[y]):(A(f=a("span")),A(p=a("span")),f.appendChild(p)),this.globalData.fontManager.chars){var v,b=this.globalData.fontManager.getCharData(t.finalText[s],n.fStyle,this.globalData.fontManager.getFontByName(t.f).fFamily);if(v=b?b.data:null,u.reset(),v&&v.shapes&&v.shapes.length&&(c=v.shapes[0].it,u.scale(t.finalSize/100,t.finalSize/100),g=this.createPathShape(u,c),p.setAttribute("d",g)),this.isMasked)this.innerElem.appendChild(p);else{if(this.innerElem.appendChild(f),v&&v.shapes){document.body.appendChild(m);var _=m.getBBox();m.setAttribute("width",_.width+2),m.setAttribute("height",_.height+2),m.setAttribute("viewBox",_.x-1+" "+(_.y-1)+" "+(_.width+2)+" "+(_.height+2));var x=m.style,k="translate("+(_.x-1)+"px,"+(_.y-1)+"px)";x.transform=k,x.webkitTransform=k,d[s].yOffset=_.y-1}else m.setAttribute("width",1),m.setAttribute("height",1);f.appendChild(m)}}else if(p.textContent=d[s].val,p.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),this.isMasked)this.innerElem.appendChild(p);else{this.innerElem.appendChild(f);var w=p.style,P="translate3d(0,"+-t.finalSize/1.2+"px,0)";w.transform=P,w.webkitTransform=P}this.isMasked?this.textSpans[y]=p:this.textSpans[y]=f,this.textSpans[y].style.display="block",this.textPaths[y]=p,y+=1}for(;y<this.textSpans.length;)this.textSpans[y].style.display="none",y+=1},Oi.prototype.renderInnerContent=function(){var t;if(this.validateText(),this.data.singleShape){if(!this._isFirstFrame&&!this.lettersChangedFlag)return;if(this.isMasked&&this.finalTransform._matMdf){this.svgElement.setAttribute("viewBox",-this.finalTransform.mProp.p.v[0]+" "+-this.finalTransform.mProp.p.v[1]+" "+this.compW+" "+this.compH),t=this.svgElement.style;var e="translate("+-this.finalTransform.mProp.p.v[0]+"px,"+-this.finalTransform.mProp.p.v[1]+"px)";t.transform=e,t.webkitTransform=e}}if(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag){var i,s,a,r,n,h=0,o=this.textAnimator.renderedLetters,l=this.textProperty.currentData.l;for(s=l.length,i=0;i<s;i+=1)l[i].n?h+=1:(r=this.textSpans[i],n=this.textPaths[i],a=o[h],h+=1,a._mdf.m&&(this.isMasked?r.setAttribute("transform",a.m):(r.style.webkitTransform=a.m,r.style.transform=a.m)),r.style.opacity=a.o,a.sw&&a._mdf.sw&&n.setAttribute("stroke-width",a.sw),a.sc&&a._mdf.sc&&n.setAttribute("stroke",a.sc),a.fc&&a._mdf.fc&&(n.setAttribute("fill",a.fc),n.style.color=a.fc));if(this.innerElem.getBBox&&!this.hidden&&(this._isFirstFrame||this._mdf)){var p=this.innerElem.getBBox();this.currentBBox.w!==p.width&&(this.currentBBox.w=p.width,this.svgElement.setAttribute("width",p.width)),this.currentBBox.h!==p.height&&(this.currentBBox.h=p.height,this.svgElement.setAttribute("height",p.height));if(this.currentBBox.w!==p.width+2||this.currentBBox.h!==p.height+2||this.currentBBox.x!==p.x-1||this.currentBBox.y!==p.y-1){this.currentBBox.w=p.width+2,this.currentBBox.h=p.height+2,this.currentBBox.x=p.x-1,this.currentBBox.y=p.y-1,this.svgElement.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h),t=this.svgElement.style;var f="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)";t.transform=f,t.webkitTransform=f}}}},r([Re,Oe,Qe],Ni),Ni.prototype.setup=function(){var t,e,i,s,a=this.comp.threeDElements.length;for(t=0;t<a;t+=1)if("3d"===(e=this.comp.threeDElements[t]).type){i=e.perspectiveElem.style,s=e.container.style;var r=this.pe.v+"px",n="0px 0px 0px",h="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";i.perspective=r,i.webkitPerspective=r,s.transformOrigin=n,s.mozTransformOrigin=n,s.webkitTransformOrigin=n,i.transform=h,i.webkitTransform=h}},Ni.prototype.createElements=function(){},Ni.prototype.hide=function(){},Ni.prototype.renderFrame=function(){var t,e,i=this._isFirstFrame;if(this.hierarchy)for(e=this.hierarchy.length,t=0;t<e;t+=1)i=this.hierarchy[t].finalTransform.mProp._mdf||i;if(i||this.pe._mdf||this.p&&this.p._mdf||this.px&&(this.px._mdf||this.py._mdf||this.pz._mdf)||this.rx._mdf||this.ry._mdf||this.rz._mdf||this.or._mdf||this.a&&this.a._mdf){if(this.mat.reset(),this.hierarchy)for(t=e=this.hierarchy.length-1;t>=0;t-=1){var s=this.hierarchy[t].finalTransform.mProp;this.mat.translate(-s.p.v[0],-s.p.v[1],s.p.v[2]),this.mat.rotateX(-s.or.v[0]).rotateY(-s.or.v[1]).rotateZ(s.or.v[2]),this.mat.rotateX(-s.rx.v).rotateY(-s.ry.v).rotateZ(s.rz.v),this.mat.scale(1/s.s.v[0],1/s.s.v[1],1/s.s.v[2]),this.mat.translate(s.a.v[0],s.a.v[1],s.a.v[2])}if(this.p?this.mat.translate(-this.p.v[0],-this.p.v[1],this.p.v[2]):this.mat.translate(-this.px.v,-this.py.v,this.pz.v),this.a){var a;a=this.p?[this.p.v[0]-this.a.v[0],this.p.v[1]-this.a.v[1],this.p.v[2]-this.a.v[2]]:[this.px.v-this.a.v[0],this.py.v-this.a.v[1],this.pz.v-this.a.v[2]];var r=Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)+Math.pow(a[2],2)),n=[a[0]/r,a[1]/r,a[2]/r],h=Math.sqrt(n[2]*n[2]+n[0]*n[0]),o=Math.atan2(n[1],h),l=Math.atan2(n[0],-n[2]);this.mat.rotateY(l).rotateX(-o)}this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v),this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]),this.mat.translate(this.globalData.compSize.w/2,this.globalData.compSize.h/2,0),this.mat.translate(0,0,this.pe.v);var p=!this._prevMat.equals(this.mat);if((p||this.pe._mdf)&&this.comp.threeDElements){var f,m,d;for(e=this.comp.threeDElements.length,t=0;t<e;t+=1)if("3d"===(f=this.comp.threeDElements[t]).type){if(p){var c=this.mat.toCSS();(d=f.container.style).transform=c,d.webkitTransform=c}this.pe._mdf&&((m=f.perspectiveElem.style).perspective=this.pe.v+"px",m.webkitPerspective=this.pe.v+"px")}this.mat.clone(this._prevMat)}}this._isFirstFrame=!1},Ni.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},Ni.prototype.destroy=function(){},Ni.prototype.getBaseElement=function(){return null},r([Re,He,zi,Vi,Qe,Oe,Se],qi),qi.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData),e=new Image;this.data.hasMask?(this.imageElem=X("image"),this.imageElem.setAttribute("width",this.assetData.w+"px"),this.imageElem.setAttribute("height",this.assetData.h+"px"),this.imageElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.imageElem),this.baseElement.setAttribute("width",this.assetData.w),this.baseElement.setAttribute("height",this.assetData.h)):this.layerElement.appendChild(e),e.crossOrigin="anonymous",e.src=t,this.data.ln&&this.baseElement.setAttribute("id",this.data.ln)},r([je],ji),ji.prototype.buildItem=Fi.prototype.buildItem,ji.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},ji.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){var s=this.layers[e];if(s.ddd&&this.supports3d)this.addTo3dContainer(i,e);else if(this.threeDElements)this.addTo3dContainer(i,e);else{for(var a,r,n=0;n<e;)this.elements[n]&&!0!==this.elements[n]&&this.elements[n].getBaseElement&&(r=this.elements[n],a=(this.layers[n].ddd?this.getThreeDContainerByPos(n):r.getBaseElement())||a),n+=1;a?s.ddd&&this.supports3d||this.layerElement.insertBefore(i,a):s.ddd&&this.supports3d||this.layerElement.appendChild(i)}}},ji.prototype.createShape=function(t){return this.supports3d?new Ri(t,this.globalData,this):new vi(t,this.globalData,this)},ji.prototype.createText=function(t){return this.supports3d?new Oi(t,this.globalData,this):new Ai(t,this.globalData,this)},ji.prototype.createCamera=function(t){return this.camera=new Ni(t,this.globalData,this),this.camera},ji.prototype.createImage=function(t){return this.supports3d?new qi(t,this.globalData,this):new ti(t,this.globalData,this)},ji.prototype.createSolid=function(t){return this.supports3d?new Vi(t,this.globalData,this):new Di(t,this.globalData,this)},ji.prototype.createNull=Fi.prototype.createNull,ji.prototype.getThreeDContainerByPos=function(t){for(var e=0,i=this.threeDElements.length;e<i;){if(this.threeDElements[e].startPos<=t&&this.threeDElements[e].endPos>=t)return this.threeDElements[e].perspectiveElem;e+=1}return null},ji.prototype.createThreeDContainer=function(t,e){var i,s,r=a("div");A(r);var n=a("div");if(A(n),"3d"===e){(i=r.style).width=this.globalData.compSize.w+"px",i.height=this.globalData.compSize.h+"px";var h="50% 50%";i.webkitTransformOrigin=h,i.mozTransformOrigin=h,i.transformOrigin=h;var o="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";(s=n.style).transform=o,s.webkitTransform=o}r.appendChild(n);var l={container:n,perspectiveElem:r,startPos:t,endPos:t,type:e};return this.threeDElements.push(l),l},ji.prototype.build3dContainers=function(){var t,e,i=this.layers.length,s="";for(t=0;t<i;t+=1)this.layers[t].ddd&&3!==this.layers[t].ty?("3d"!==s&&(s="3d",e=this.createThreeDContainer(t,"3d")),e.endPos=Math.max(e.endPos,t)):("2d"!==s&&(s="2d",e=this.createThreeDContainer(t,"2d")),e.endPos=Math.max(e.endPos,t));for(t=(i=this.threeDElements.length)-1;t>=0;t-=1)this.resizerElem.appendChild(this.threeDElements[t].perspectiveElem)},ji.prototype.addTo3dContainer=function(t,e){for(var i=0,s=this.threeDElements.length;i<s;){if(e<=this.threeDElements[i].endPos){for(var a,r=this.threeDElements[i].startPos;r<e;)this.elements[r]&&this.elements[r].getBaseElement&&(a=this.elements[r].getBaseElement()),r+=1;a?this.threeDElements[i].container.insertBefore(t,a):this.threeDElements[i].container.appendChild(t);break}i+=1}},ji.prototype.configAnimation=function(t){var e=a("div"),i=this.animationItem.wrapper,s=e.style;s.width=t.w+"px",s.height=t.h+"px",this.resizerElem=e,A(e),s.transformStyle="flat",s.mozTransformStyle="flat",s.webkitTransformStyle="flat",this.renderConfig.className&&e.setAttribute("class",this.renderConfig.className),i.appendChild(e),s.overflow="hidden";var r=X("svg");r.setAttribute("width","1"),r.setAttribute("height","1"),A(r),this.resizerElem.appendChild(r);var n=X("defs");r.appendChild(n),this.data=t,this.setupGlobalData(t,r),this.globalData.defs=n,this.layers=t.layers,this.layerElement=this.resizerElem,this.build3dContainers(),this.updateContainerSize()},ji.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.animationItem.container=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},ji.prototype.updateContainerSize=function(){var t,e,i,s,a=this.animationItem.wrapper.offsetWidth,r=this.animationItem.wrapper.offsetHeight,n=a/r;this.globalData.compSize.w/this.globalData.compSize.h>n?(t=a/this.globalData.compSize.w,e=a/this.globalData.compSize.w,i=0,s=(r-this.globalData.compSize.h*(a/this.globalData.compSize.w))/2):(t=r/this.globalData.compSize.h,e=r/this.globalData.compSize.h,i=(a-this.globalData.compSize.w*(r/this.globalData.compSize.h))/2,s=0);var h=this.resizerElem.style;h.webkitTransform="matrix3d("+t+",0,0,0,0,"+e+",0,0,0,0,1,0,"+i+","+s+",0,1)",h.transform=h.webkitTransform},ji.prototype.renderFrame=Fi.prototype.renderFrame,ji.prototype.hide=function(){this.resizerElem.style.display="none"},ji.prototype.show=function(){this.resizerElem.style.display="block"},ji.prototype.initItems=function(){if(this.buildAllItems(),this.camera)this.camera.setup();else{var t,e=this.globalData.compSize.w,i=this.globalData.compSize.h,s=this.threeDElements.length;for(t=0;t<s;t+=1){var a=this.threeDElements[t].perspectiveElem.style;a.webkitPerspective=Math.sqrt(Math.pow(e,2)+Math.pow(i,2))+"px",a.perspective=a.webkitPerspective}}},ji.prototype.searchExtraCompositions=function(t){var e,i=t.length,s=a("div");for(e=0;e<i;e+=1)if(t[e].xt){var r=this.createComp(t[e],s,this.globalData.comp,null);r.initExpressions(),this.globalData.projectInterface.registerComposition(r)}},r([ji,Mi,zi],Wi),Wi.prototype._createBaseContainerElements=Wi.prototype.createContainerElements,Wi.prototype.createContainerElements=function(){this._createBaseContainerElements(),this.data.hasMask?(this.svgElement.setAttribute("width",this.data.w),this.svgElement.setAttribute("height",this.data.h),this.transformedElement=this.baseElement):this.transformedElement=this.layerElement},Wi.prototype.addTo3dContainer=function(t,e){for(var i,s=0;s<e;)this.elements[s]&&this.elements[s].getBaseElement&&(i=this.elements[s].getBaseElement()),s+=1;i?this.layerElement.insertBefore(t,i):this.layerElement.appendChild(t)},Wi.prototype.createComp=function(t){return this.supports3d?new Wi(t,this.globalData,this):new Ti(t,this.globalData,this)},r([ji],Hi),Hi.prototype.createComp=function(t){return this.supports3d?new Wi(t,this.globalData,this):new Ti(t,this.globalData,this)},Ii=Hi,Q["html"]=Ii,qt.registerModifier("tm",Wt),qt.registerModifier("pb",Ht),qt.registerModifier("rp",Yt),qt.registerModifier("rd",Gt),qt.registerModifier("zz",pe),qt.registerModifier("op",xe),Bt}));
+"undefined"!=typeof document&&"undefined"!=typeof navigator&&function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lottie=e()}(this,(function(){"use strict";var t="",e=!1,i=-999999,s=function(){return t};function a(t){return document.createElement(t)}function r(t,e){var i,s,a=t.length;for(i=0;i<a;i+=1)for(var r in s=t[i].prototype)Object.prototype.hasOwnProperty.call(s,r)&&(e.prototype[r]=s[r])}function n(t){function e(){}return e.prototype=t,e}var h=function(){function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].pause()},resume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].resume()},setRate:function(t){var e,i=this.audios.length;for(e=0;e<i;e+=1)this.audios[e].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}}(),o=function(){function t(t,e){var i,s=0,a=[];switch(t){case"int16":case"uint8c":i=1;break;default:i=1.1}for(s=0;s<e;s+=1)a.push(i);return a}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(e,i){return"float32"===e?new Float32Array(i):"int16"===e?new Int16Array(i):"uint8c"===e?new Uint8ClampedArray(i):t(e,i)}:t}();function l(t){return Array.apply(null,{length:t})}function p(t){return p="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},p(t)}var f=!0,m=null,d=null,c="",u=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),g=Math.pow,y=Math.sqrt,v=Math.floor,b=Math.max,_=Math.min,x={};!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],i=e.length;for(t=0;t<i;t+=1)x[e[t]]=Math[e[t]]}(),x.random=Math.random,x.abs=function(t){if("object"===p(t)&&t.length){var e,i=l(t.length),s=t.length;for(e=0;e<s;e+=1)i[e]=Math.abs(t[e]);return i}return Math.abs(t)};var k=150,w=Math.PI/180,P=.5519;function S(t){0}function A(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin="0 0",t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility="visible",t.style.webkitBackfaceVisibility="visible",t.style.transformStyle="preserve-3d",t.style.webkitTransformStyle="preserve-3d",t.style.mozTransformStyle="preserve-3d"}function D(t,e,i,s){this.type=t,this.currentTime=e,this.totalTime=i,this.direction=s<0?-1:1}function C(t,e){this.type=t,this.direction=e<0?-1:1}function E(t,e,i,s){this.type=t,this.currentLoop=i,this.totalLoops=e,this.direction=s<0?-1:1}function M(t,e,i){this.type=t,this.firstFrame=e,this.totalFrames=i}function T(t,e){this.type=t,this.target=e}function F(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function I(t){this.type="configError",this.nativeError=t}var L,B=(L=0,function(){return c+"__lottie_element_"+(L+=1)});function z(t,e,i){var s,a,r,n,h,o,l,p;switch(o=i*(1-e),l=i*(1-(h=6*t-(n=Math.floor(6*t)))*e),p=i*(1-(1-h)*e),n%6){case 0:s=i,a=p,r=o;break;case 1:s=l,a=i,r=o;break;case 2:s=o,a=i,r=p;break;case 3:s=o,a=l,r=i;break;case 4:s=p,a=o,r=i;break;case 5:s=i,a=o,r=l}return[s,a,r]}function V(t,e,i){var s,a=Math.max(t,e,i),r=Math.min(t,e,i),n=a-r,h=0===a?0:n/a,o=a/255;switch(a){case r:s=0;break;case t:s=e-i+n*(e<i?6:0),s/=6*n;break;case e:s=i-t+2*n,s/=6*n;break;case i:s=t-e+4*n,s/=6*n}return[s,h,o]}function R(t,e){var i=V(255*t[0],255*t[1],255*t[2]);return i[1]+=e,i[1]>1?i[1]=1:i[1]<=0&&(i[1]=0),z(i[0],i[1],i[2])}function O(t,e){var i=V(255*t[0],255*t[1],255*t[2]);return i[2]+=e,i[2]>1?i[2]=1:i[2]<0&&(i[2]=0),z(i[0],i[1],i[2])}function N(t,e){var i=V(255*t[0],255*t[1],255*t[2]);return i[0]+=e/360,i[0]>1?i[0]-=1:i[0]<0&&(i[0]+=1),z(i[0],i[1],i[2])}!function(){var t,e,i=[];for(t=0;t<256;t+=1)e=t.toString(16),i[t]=1===e.length?"0"+e:e}();var q=function(){return m},j=function(){return d},W=function(t){k=t},H=function(){return k};function X(t){return document.createElementNS("http://www.w3.org/2000/svg",t)}function Y(t){return Y="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Y(t)}var G=function(){var t,i,s=1,a=[],r={onmessage:function(){},postMessage:function(e){t({data:e})}},n={postMessage:function(t){r.onmessage({data:t})}};function h(i){if(window.Worker&&window.Blob&&e){var s=new Blob(["var _workerSelf = self; self.onmessage = ",i.toString()],{type:"text/javascript"}),a=URL.createObjectURL(s);return new Worker(a)}return t=i,r}function o(){i||(i=h((function(t){if(n.dataManager||(n.dataManager=function(){function t(a,r){var n,h,o,l,p,m,d=a.length;for(h=0;h<d;h+=1)if("ks"in(n=a[h])&&!n.completed){if(n.completed=!0,n.hasMask){var c=n.masksProperties;for(l=c.length,o=0;o<l;o+=1)if(c[o].pt.k.i)s(c[o].pt.k);else for(m=c[o].pt.k.length,p=0;p<m;p+=1)c[o].pt.k[p].s&&s(c[o].pt.k[p].s[0]),c[o].pt.k[p].e&&s(c[o].pt.k[p].e[0])}0===n.ty?(n.layers=e(n.refId,r),t(n.layers,r)):4===n.ty?i(n.shapes):5===n.ty&&f(n)}}function e(t,e){var i=function(t,e){for(var i=0,s=e.length;i<s;){if(e[i].id===t)return e[i];i+=1}return null}(t,e);return i?i.layers.__used?JSON.parse(JSON.stringify(i.layers)):(i.layers.__used=!0,i.layers):null}function i(t){var e,a,r;for(e=t.length-1;e>=0;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)s(t[e].ks.k);else for(r=t[e].ks.k.length,a=0;a<r;a+=1)t[e].ks.k[a].s&&s(t[e].ks.k[a].s[0]),t[e].ks.k[a].e&&s(t[e].ks.k[a].e[0]);else"gr"===t[e].ty&&i(t[e].it)}function s(t){var e,i=t.i.length;for(e=0;e<i;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function a(t,e){var i=e?e.split("."):[100,100,100];return t[0]>i[0]||!(i[0]>t[0])&&(t[1]>i[1]||!(i[1]>t[1])&&(t[2]>i[2]||!(i[2]>t[2])&&null))}var r,n=function(){var t=[4,4,14];function e(t){var e,i,s,a=t.length;for(e=0;e<a;e+=1)5===t[e].ty&&(s=void 0,s=(i=t[e]).t.d,i.t.d={k:[{s:s,t:0}]})}return function(i){if(a(t,i.v)&&(e(i.layers),i.assets)){var s,r=i.assets.length;for(s=0;s<r;s+=1)i.assets[s].layers&&e(i.assets[s].layers)}}}(),h=(r=[4,7,99],function(t){if(t.chars&&!a(r,t.v)){var e,s=t.chars.length;for(e=0;e<s;e+=1){var n=t.chars[e];n.data&&n.data.shapes&&(i(n.data.shapes),n.data.ip=0,n.data.op=99999,n.data.st=0,n.data.sr=1,n.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[e].t||(n.data.shapes.push({ty:"no"}),n.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}}}),o=function(){var t=[5,7,15];function e(t){var e,i,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(i=void 0,"number"==typeof(i=t[e].t.p).a&&(i.a={a:0,k:i.a}),"number"==typeof i.p&&(i.p={a:0,k:i.p}),"number"==typeof i.r&&(i.r={a:0,k:i.r}))}return function(i){if(a(t,i.v)&&(e(i.layers),i.assets)){var s,r=i.assets.length;for(s=0;s<r;s+=1)i.assets[s].layers&&e(i.assets[s].layers)}}}(),l=function(){var t=[4,1,9];function e(t){var i,s,a,r=t.length;for(i=0;i<r;i+=1)if("gr"===t[i].ty)e(t[i].it);else if("fl"===t[i].ty||"st"===t[i].ty)if(t[i].c.k&&t[i].c.k[0].i)for(a=t[i].c.k.length,s=0;s<a;s+=1)t[i].c.k[s].s&&(t[i].c.k[s].s[0]/=255,t[i].c.k[s].s[1]/=255,t[i].c.k[s].s[2]/=255,t[i].c.k[s].s[3]/=255),t[i].c.k[s].e&&(t[i].c.k[s].e[0]/=255,t[i].c.k[s].e[1]/=255,t[i].c.k[s].e[2]/=255,t[i].c.k[s].e[3]/=255);else t[i].c.k[0]/=255,t[i].c.k[1]/=255,t[i].c.k[2]/=255,t[i].c.k[3]/=255}function i(t){var i,s=t.length;for(i=0;i<s;i+=1)4===t[i].ty&&e(t[i].shapes)}return function(e){if(a(t,e.v)&&(i(e.layers),e.assets)){var s,r=e.assets.length;for(s=0;s<r;s+=1)e.assets[s].layers&&i(e.assets[s].layers)}}}(),p=function(){var t=[4,4,18];function e(t){var i,s,a;for(i=t.length-1;i>=0;i-=1)if("sh"===t[i].ty)if(t[i].ks.k.i)t[i].ks.k.c=t[i].closed;else for(a=t[i].ks.k.length,s=0;s<a;s+=1)t[i].ks.k[s].s&&(t[i].ks.k[s].s[0].c=t[i].closed),t[i].ks.k[s].e&&(t[i].ks.k[s].e[0].c=t[i].closed);else"gr"===t[i].ty&&e(t[i].it)}function i(t){var i,s,a,r,n,h,o=t.length;for(s=0;s<o;s+=1){if((i=t[s]).hasMask){var l=i.masksProperties;for(r=l.length,a=0;a<r;a+=1)if(l[a].pt.k.i)l[a].pt.k.c=l[a].cl;else for(h=l[a].pt.k.length,n=0;n<h;n+=1)l[a].pt.k[n].s&&(l[a].pt.k[n].s[0].c=l[a].cl),l[a].pt.k[n].e&&(l[a].pt.k[n].e[0].c=l[a].cl)}4===i.ty&&e(i.shapes)}}return function(e){if(a(t,e.v)&&(i(e.layers),e.assets)){var s,r=e.assets.length;for(s=0;s<r;s+=1)e.assets[s].layers&&i(e.assets[s].layers)}}}();function f(t){0===t.t.a.length&&t.t.p}var m={completeData:function(i){i.__complete||(l(i),n(i),h(i),o(i),p(i),t(i.layers,i.assets),function(i,s){if(i){var a=0,r=i.length;for(a=0;a<r;a+=1)1===i[a].t&&(i[a].data.layers=e(i[a].data.refId,s),t(i[a].data.layers,s))}}(i.chars,i.assets),i.__complete=!0)}};return m.checkColors=l,m.checkChars=h,m.checkPathProperties=o,m.checkShapes=p,m.completeLayers=t,m}()),n.assetLoader||(n.assetLoader=function(){function t(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")||t.response&&"object"===Y(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}return{load:function(e,i,s,a){var r,n=new XMLHttpRequest;try{n.responseType="json"}catch(t){}n.onreadystatechange=function(){if(4===n.readyState)if(200===n.status)r=t(n),s(r);else try{r=t(n),s(r)}catch(t){a&&a(t)}};try{n.open(["G","E","T"].join(""),e,!0)}catch(t){n.open(["G","E","T"].join(""),i+"/"+e,!0)}n.send()}}}()),"loadAnimation"===t.data.type)n.assetLoader.load(t.data.path,t.data.fullPath,(function(e){n.dataManager.completeData(e),n.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){n.postMessage({id:t.data.id,status:"error"})}));else if("complete"===t.data.type){var e=t.data.animation;n.dataManager.completeData(e),n.postMessage({id:t.data.id,payload:e,status:"success"})}else"loadData"===t.data.type&&n.assetLoader.load(t.data.path,t.data.fullPath,(function(e){n.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){n.postMessage({id:t.data.id,status:"error"})}))})),i.onmessage=function(t){var e=t.data,i=e.id,s=a[i];a[i]=null,"success"===e.status?s.onComplete(e.payload):s.onError&&s.onError()})}function l(t,e){var i="processId_"+(s+=1);return a[i]={onComplete:t,onError:e},i}return{loadAnimation:function(t,e,s){o();var a=l(e,s);i.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:a})},loadData:function(t,e,s){o();var a=l(e,s);i.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:a})},completeAnimation:function(t,e,s){o();var a=l(e,s);i.postMessage({type:"complete",animation:t,id:a})}}}(),K=function(){var t=function(){var t=a("canvas");t.width=1,t.height=1;var e=t.getContext("2d");return e.fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1),t}();function e(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function i(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function s(t,e,i){var s="";if(t.e)s=t.p;else if(e){var a=t.p;-1!==a.indexOf("images/")&&(a=a.split("/")[1]),s=e+a}else s=i,s+=t.u?t.u:"",s+=t.p;return s}function r(t){var e=0,i=setInterval(function(){(t.getBBox().width||e>500)&&(this._imageLoaded(),clearInterval(i)),e+=1}.bind(this),50)}function n(t){var e={assetData:t},i=s(t,this.assetsPath,this.path);return G.loadData(i,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}function h(){this._imageLoaded=e.bind(this),this._footageLoaded=i.bind(this),this.testImageLoaded=r.bind(this),this.createFootageData=n.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return h.prototype={loadAssets:function(t,e){var i;this.imagesLoadedCb=e;var s=t.length;for(i=0;i<s;i+=1)t[i].layers||(t[i].t&&"seq"!==t[i].t?3===t[i].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[i]))):(this.totalImages+=1,this.images.push(this._createImageData(t[i]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,i=this.images.length;e<i;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(e){var i=s(e,this.assetsPath,this.path),r=a("img");r.crossOrigin="anonymous",r.addEventListener("load",this._imageLoaded,!1),r.addEventListener("error",function(){n.img=t,this._imageLoaded()}.bind(this),!1),r.src=i;var n={img:r,assetData:e};return n},createImageData:function(e){var i=s(e,this.assetsPath,this.path),a=X("image");u?this.testImageLoaded(a):a.addEventListener("load",this._imageLoaded,!1),a.addEventListener("error",function(){r.img=t,this._imageLoaded()}.bind(this),!1),a.setAttributeNS("http://www.w3.org/1999/xlink","href",i),this._elementHelper.append?this._elementHelper.append(a):this._elementHelper.appendChild(a);var r={img:a,assetData:e};return r},imageLoaded:e,footageLoaded:i,setCacheType:function(t,e){"svg"===t?(this._elementHelper=e,this._createImageData=this.createImageData.bind(this)):this._createImageData=this.createImgData.bind(this)}},h}();function J(){}J.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var i=this._cbs[t],s=0;s<i.length;s+=1)i[s](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var i=0,s=this._cbs[t].length;i<s;)this._cbs[t][i]===e&&(this._cbs[t].splice(i,1),i-=1,s-=1),i+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var Z=function(){function t(t){for(var e,i=t.split("\r\n"),s={},a=0,r=0;r<i.length;r+=1)2===(e=i[r].split(":")).length&&(s[e[0]]=e[1].trim(),a+=1);if(0===a)throw new Error;return s}return function(e){for(var i=[],s=0;s<e.length;s+=1){var a=e[s],r={time:a.tm,duration:a.dr};try{r.payload=JSON.parse(e[s].cm)}catch(i){try{r.payload=t(e[s].cm)}catch(t){r.payload={name:e[s].cm}}}i.push(r)}return i}}(),U=function(){function t(t){this.compositions.push(t)}return function(){function e(t){for(var e=0,i=this.compositions.length;e<i;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return e.compositions=[],e.currentFrame=0,e.registerComposition=t,e}}(),Q={};function $(t){return $="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},$(t)}var tt=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=B(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=f,this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=U(),this.imagePreloader=new K,this.audioController=h(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new D("drawnFrame",0,0,0),this.expressionsPlugin=q()};r([J],tt),tt.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg";t.animType?e=t.animType:t.renderer&&(e=t.renderer);var i=Q[e];this.renderer=new i(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||void 0===t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),G.loadAnimation(t.path,this.configAnimation,this.onSetupError))},tt.prototype.onSetupError=function(){this.trigger("data_failed")},tt.prototype.setupAnimation=function(t){G.completeAnimation(t,this.configAnimation)},tt.prototype.setData=function(t,e){e&&"object"!==$(e)&&(e=JSON.parse(e));var i={wrapper:t,animationData:e},s=t.attributes;i.path=s.getNamedItem("data-animation-path")?s.getNamedItem("data-animation-path").value:s.getNamedItem("data-bm-path")?s.getNamedItem("data-bm-path").value:s.getNamedItem("bm-path")?s.getNamedItem("bm-path").value:"",i.animType=s.getNamedItem("data-anim-type")?s.getNamedItem("data-anim-type").value:s.getNamedItem("data-bm-type")?s.getNamedItem("data-bm-type").value:s.getNamedItem("bm-type")?s.getNamedItem("bm-type").value:s.getNamedItem("data-bm-renderer")?s.getNamedItem("data-bm-renderer").value:s.getNamedItem("bm-renderer")?s.getNamedItem("bm-renderer").value:function(){if(Q.canvas)return"canvas";for(var t in Q)if(Q[t])return t;return""}()||"canvas";var a=s.getNamedItem("data-anim-loop")?s.getNamedItem("data-anim-loop").value:s.getNamedItem("data-bm-loop")?s.getNamedItem("data-bm-loop").value:s.getNamedItem("bm-loop")?s.getNamedItem("bm-loop").value:"";"false"===a?i.loop=!1:"true"===a?i.loop=!0:""!==a&&(i.loop=parseInt(a,10));var r=s.getNamedItem("data-anim-autoplay")?s.getNamedItem("data-anim-autoplay").value:s.getNamedItem("data-bm-autoplay")?s.getNamedItem("data-bm-autoplay").value:!s.getNamedItem("bm-autoplay")||s.getNamedItem("bm-autoplay").value;i.autoplay="false"!==r,i.name=s.getNamedItem("data-name")?s.getNamedItem("data-name").value:s.getNamedItem("data-bm-name")?s.getNamedItem("data-bm-name").value:s.getNamedItem("bm-name")?s.getNamedItem("bm-name").value:"","false"===(s.getNamedItem("data-anim-prerender")?s.getNamedItem("data-anim-prerender").value:s.getNamedItem("data-bm-prerender")?s.getNamedItem("data-bm-prerender").value:s.getNamedItem("bm-prerender")?s.getNamedItem("bm-prerender").value:"")&&(i.prerender=!1),i.path?this.setParams(i):this.trigger("destroy")},tt.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,i,s=this.animationData.layers,a=s.length,r=t.layers,n=r.length;for(i=0;i<n;i+=1)for(e=0;e<a;){if(s[e].id===r[i].id){s[e]=r[i];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(a=t.assets.length,e=0;e<a;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,G.completeAnimation(this.animationData,this.onSegmentComplete)},tt.prototype.onSegmentComplete=function(t){this.animationData=t;var e=q();e&&e.initExpressions(this),this.loadNextSegment()},tt.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var i=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,G.loadData(i,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},tt.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},tt.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},tt.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},tt.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=Z(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},tt.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},tt.prototype.checkLoaded=function(){if(!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()){this.isLoaded=!0;var t=q();t&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play()}},tt.prototype.resize=function(t,e){var i="number"==typeof t?t:void 0,s="number"==typeof e?e:void 0;this.renderer.updateContainerSize(i,s)},tt.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},tt.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},tt.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},tt.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},tt.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},tt.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},tt.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},tt.prototype.getMarkerData=function(t){for(var e,i=0;i<this.markers.length;i+=1)if((e=this.markers[i]).payload&&e.payload.name===t)return e;return null},tt.prototype.goToAndStop=function(t,e,i){if(!i||this.name===i){var s=Number(t);if(isNaN(s)){var a=this.getMarkerData(t);a&&this.goToAndStop(a.time,!0)}else e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier);this.pause()}},tt.prototype.goToAndPlay=function(t,e,i){if(!i||this.name===i){var s=Number(t);if(isNaN(s)){var a=this.getMarkerData(t);a&&(a.duration?this.playSegments([a.time,a.time+a.duration],!0):this.goToAndStop(a.time,!0))}else this.goToAndStop(s,e,i);this.play()}},tt.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,i=!1;e>=this.totalFrames-1&&this.frameModifier>0?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(i=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(i=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),i&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},tt.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(this.frameModifier>0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},tt.prototype.setSegment=function(t,e){var i=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?i=t:this.currentRawFrame+this.firstFrame>e&&(i=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==i&&this.goToAndStop(i,!0)},tt.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===$(t[0])){var i,s=t.length;for(i=0;i<s;i+=1)this.segments.push(t[i])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},tt.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},tt.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},tt.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},tt.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},tt.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},tt.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},tt.prototype.setLoop=function(t){this.loop=t},tt.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},tt.prototype.getVolume=function(){return this.audioController.getVolume()},tt.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},tt.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},tt.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},tt.prototype.getPath=function(){return this.path},tt.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var i=t.p;-1!==i.indexOf("images/")&&(i=i.split("/")[1]),e=this.assetsPath+i}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},tt.prototype.getAssetData=function(t){for(var e=0,i=this.assets.length;e<i;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},tt.prototype.hide=function(){this.renderer.hide()},tt.prototype.show=function(){this.renderer.show()},tt.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},tt.prototype.updateDocumentData=function(t,e,i){try{this.renderer.getElementByPath(t).updateDocumentData(e,i)}catch(t){}},tt.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new D(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new E(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new C(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new M(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new T(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new D(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new E(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new C(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new M(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new T(t,this))},tt.prototype.triggerRenderFrameError=function(t){var e=new F(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)},tt.prototype.triggerConfigError=function(t){var e=new I(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)};var et=function(){var t={},e=[],i=0,s=0,r=0,n=!0,h=!1;function o(t){for(var i=0,a=t.target;i<s;)e[i].animation===a&&(e.splice(i,1),i-=1,s-=1,a.isPaused||f()),i+=1}function l(t,i){if(!t)return null;for(var a=0;a<s;){if(e[a].elem===t&&null!==e[a].elem)return e[a].animation;a+=1}var r=new tt;return m(r,t),r.setData(t,i),r}function p(){r+=1,u()}function f(){r-=1}function m(t,i){t.addEventListener("destroy",o),t.addEventListener("_active",p),t.addEventListener("_idle",f),e.push({elem:i,animation:t}),s+=1}function d(t){var a,o=t-i;for(a=0;a<s;a+=1)e[a].animation.advanceTime(o);i=t,r&&!h?window.requestAnimationFrame(d):n=!0}function c(t){i=t,window.requestAnimationFrame(d)}function u(){!h&&r&&n&&(window.requestAnimationFrame(c),n=!1)}return t.registerAnimation=l,t.loadAnimation=function(t){var e=new tt;return m(e,null),e.setParams(t),e},t.setSpeed=function(t,i){var a;for(a=0;a<s;a+=1)e[a].animation.setSpeed(t,i)},t.setDirection=function(t,i){var a;for(a=0;a<s;a+=1)e[a].animation.setDirection(t,i)},t.play=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.play(t)},t.pause=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.pause(t)},t.stop=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.stop(t)},t.togglePause=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.togglePause(t)},t.searchAnimations=function(t,e,i){var s,r=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),n=r.length;for(s=0;s<n;s+=1)i&&r[s].setAttribute("data-bm-type",i),l(r[s],t);if(e&&0===n){i||(i="svg");var h=document.getElementsByTagName("body")[0];h.innerText="";var o=a("div");o.style.width="100%",o.style.height="100%",o.setAttribute("data-bm-type",i),h.appendChild(o),l(o,t)}},t.resize=function(){var t;for(t=0;t<s;t+=1)e[t].animation.resize()},t.goToAndStop=function(t,i,a){var r;for(r=0;r<s;r+=1)e[r].animation.goToAndStop(t,i,a)},t.destroy=function(t){var i;for(i=s-1;i>=0;i-=1)e[i].animation.destroy(t)},t.freeze=function(){h=!0},t.unfreeze=function(){h=!1,u()},t.setVolume=function(t,i){var a;for(a=0;a<s;a+=1)e[a].animation.setVolume(t,i)},t.mute=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.mute(t)},t.unmute=function(t){var i;for(i=0;i<s;i+=1)e[i].animation.unmute(t)},t.getRegisteredAnimations=function(){var t,i=e.length,s=[];for(t=0;t<i;t+=1)s.push(e[t].animation);return s},t}(),it=function(){var t={getBezierEasing:function(t,i,s,a,r){var n=r||("bez_"+t+"_"+i+"_"+s+"_"+a).replace(/\./g,"p");if(e[n])return e[n];var h=new p([t,i,s,a]);return e[n]=h,h}},e={};var i=11,s=1/(i-1),a="function"==typeof Float32Array;function r(t,e){return 1-3*e+3*t}function n(t,e){return 3*e-6*t}function h(t){return 3*t}function o(t,e,i){return((r(e,i)*t+n(e,i))*t+h(e))*t}function l(t,e,i){return 3*r(e,i)*t*t+2*n(e,i)*t+h(e)}function p(t){this._p=t,this._mSampleValues=a?new Float32Array(i):new Array(i),this._precomputed=!1,this.get=this.get.bind(this)}return p.prototype={get:function(t){var e=this._p[0],i=this._p[1],s=this._p[2],a=this._p[3];return this._precomputed||this._precompute(),e===i&&s===a?t:0===t?0:1===t?1:o(this._getTForX(t),i,a)},_precompute:function(){var t=this._p[0],e=this._p[1],i=this._p[2],s=this._p[3];this._precomputed=!0,t===e&&i===s||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],a=0;a<i;++a)this._mSampleValues[a]=o(a*s,t,e)},_getTForX:function(t){for(var e=this._p[0],a=this._p[2],r=this._mSampleValues,n=0,h=1,p=i-1;h!==p&&r[h]<=t;++h)n+=s;var f=n+(t-r[--h])/(r[h+1]-r[h])*s,m=l(f,e,a);return m>=.001?function(t,e,i,s){for(var a=0;a<4;++a){var r=l(e,i,s);if(0===r)return e;e-=(o(e,i,s)-t)/r}return e}(t,f,e,a):0===m?f:function(t,e,i,s,a){var r,n,h=0;do{(r=o(n=e+(i-e)/2,s,a)-t)>0?i=n:e=n}while(Math.abs(r)>1e-7&&++h<10);return n}(t,n,n+s,e,a)}},t}(),st={double:function(t){return t.concat(l(t.length))}},at=function(t,e,i){var s=0,a=t,r=l(a);return{newElement:function(){return s?r[s-=1]:e()},release:function(t){s===a&&(r=st.double(r),a*=2),i&&i(t),r[s]=t,s+=1}}},rt=at(8,(function(){return{addedLength:0,percents:o("float32",H()),lengths:o("float32",H())}})),nt=at(8,(function(){return{lengths:[],totalLength:0}}),(function(t){var e,i=t.lengths.length;for(e=0;e<i;e+=1)rt.release(t.lengths[e]);t.lengths.length=0}));var ht=function(){var t=Math;function e(t,e,i,s,a,r){var n=t*s+e*a+i*r-a*s-r*t-i*e;return n>-.001&&n<.001}var i=function(t,e,i,s){var a,r,n,h,o,l,p=H(),f=0,m=[],d=[],c=rt.newElement();for(n=i.length,a=0;a<p;a+=1){for(o=a/(p-1),l=0,r=0;r<n;r+=1)h=g(1-o,3)*t[r]+3*g(1-o,2)*o*i[r]+3*(1-o)*g(o,2)*s[r]+g(o,3)*e[r],m[r]=h,null!==d[r]&&(l+=g(m[r]-d[r],2)),d[r]=m[r];l&&(f+=l=y(l)),c.percents[a]=o,c.lengths[a]=f}return c.addedLength=f,c};function s(t){this.segmentLength=0,this.points=new Array(t)}function a(t,e){this.partialLength=t,this.point=e}var r,n=(r={},function(t,i,n,h){var o=(t[0]+"_"+t[1]+"_"+i[0]+"_"+i[1]+"_"+n[0]+"_"+n[1]+"_"+h[0]+"_"+h[1]).replace(/\./g,"p");if(!r[o]){var p,f,m,d,c,u,v,b=H(),_=0,x=null;2===t.length&&(t[0]!==i[0]||t[1]!==i[1])&&e(t[0],t[1],i[0],i[1],t[0]+n[0],t[1]+n[1])&&e(t[0],t[1],i[0],i[1],i[0]+h[0],i[1]+h[1])&&(b=2);var k=new s(b);for(m=n.length,p=0;p<b;p+=1){for(v=l(m),c=p/(b-1),u=0,f=0;f<m;f+=1)d=g(1-c,3)*t[f]+3*g(1-c,2)*c*(t[f]+n[f])+3*(1-c)*g(c,2)*(i[f]+h[f])+g(c,3)*i[f],v[f]=d,null!==x&&(u+=g(v[f]-x[f],2));_+=u=y(u),k.points[p]=new a(u,v),x=v}k.segmentLength=_,r[o]=k}return r[o]});function h(t,e){var i=e.percents,s=e.lengths,a=i.length,r=v((a-1)*t),n=t*e.addedLength,h=0;if(r===a-1||0===r||n===s[r])return i[r];for(var o=s[r]>n?-1:1,l=!0;l;)if(s[r]<=n&&s[r+1]>n?(h=(n-s[r])/(s[r+1]-s[r]),l=!1):r+=o,r<0||r>=a-1){if(r===a-1)return i[r];l=!1}return i[r]+(i[r+1]-i[r])*h}var p=o("float32",8);return{getSegmentsLength:function(t){var e,s=nt.newElement(),a=t.c,r=t.v,n=t.o,h=t.i,o=t._length,l=s.lengths,p=0;for(e=0;e<o-1;e+=1)l[e]=i(r[e],r[e+1],n[e],h[e+1]),p+=l[e].addedLength;return a&&o&&(l[e]=i(r[e],r[0],n[e],h[0]),p+=l[e].addedLength),s.totalLength=p,s},getNewSegment:function(e,i,s,a,r,n,o){r<0?r=0:r>1&&(r=1);var l,f=h(r,o),m=h(n=n>1?1:n,o),d=e.length,c=1-f,u=1-m,g=c*c*c,y=f*c*c*3,v=f*f*c*3,b=f*f*f,_=c*c*u,x=f*c*u+c*f*u+c*c*m,k=f*f*u+c*f*m+f*c*m,w=f*f*m,P=c*u*u,S=f*u*u+c*m*u+c*u*m,A=f*m*u+c*m*m+f*u*m,D=f*m*m,C=u*u*u,E=m*u*u+u*m*u+u*u*m,M=m*m*u+u*m*m+m*u*m,T=m*m*m;for(l=0;l<d;l+=1)p[4*l]=t.round(1e3*(g*e[l]+y*s[l]+v*a[l]+b*i[l]))/1e3,p[4*l+1]=t.round(1e3*(_*e[l]+x*s[l]+k*a[l]+w*i[l]))/1e3,p[4*l+2]=t.round(1e3*(P*e[l]+S*s[l]+A*a[l]+D*i[l]))/1e3,p[4*l+3]=t.round(1e3*(C*e[l]+E*s[l]+M*a[l]+T*i[l]))/1e3;return p},getPointInSegment:function(e,i,s,a,r,n){var o=h(r,n),l=1-o;return[t.round(1e3*(l*l*l*e[0]+(o*l*l+l*o*l+l*l*o)*s[0]+(o*o*l+l*o*o+o*l*o)*a[0]+o*o*o*i[0]))/1e3,t.round(1e3*(l*l*l*e[1]+(o*l*l+l*o*l+l*l*o)*s[1]+(o*o*l+l*o*o+o*l*o)*a[1]+o*o*o*i[1]))/1e3]},buildBezierData:n,pointOnLine2D:e,pointOnLine3D:function(i,s,a,r,n,h,o,l,p){if(0===a&&0===h&&0===p)return e(i,s,r,n,o,l);var f,m=t.sqrt(t.pow(r-i,2)+t.pow(n-s,2)+t.pow(h-a,2)),d=t.sqrt(t.pow(o-i,2)+t.pow(l-s,2)+t.pow(p-a,2)),c=t.sqrt(t.pow(o-r,2)+t.pow(l-n,2)+t.pow(p-h,2));return(f=m>d?m>c?m-d-c:c-d-m:c>d?c-d-m:d-m-c)>-1e-4&&f<1e-4}}}(),ot=i,lt=Math.abs;function pt(t,e){var i,s=this.offsetTime;"multidimensional"===this.propType&&(i=o("float32",this.pv.length));for(var a,r,n,h,l,p,f,m,d,c=e.lastIndex,u=c,g=this.keyframes.length-1,y=!0;y;){if(a=this.keyframes[u],r=this.keyframes[u+1],u===g-1&&t>=r.t-s){a.h&&(a=r),c=0;break}if(r.t-s>t){c=u;break}u<g-1?u+=1:(c=0,y=!1)}n=this.keyframesMetadata[u]||{};var v,b,_,x,k,P,S,A,D,C,E=r.t-s,M=a.t-s;if(a.to){n.bezierData||(n.bezierData=ht.buildBezierData(a.s,r.s||a.e,a.to,a.ti));var T=n.bezierData;if(t>=E||t<M){var F=t>=E?T.points.length-1:0;for(l=T.points[F].point.length,h=0;h<l;h+=1)i[h]=T.points[F].point[h]}else{n.__fnct?d=n.__fnct:(d=it.getBezierEasing(a.o.x,a.o.y,a.i.x,a.i.y,a.n).get,n.__fnct=d),p=d((t-M)/(E-M));var I,L=T.segmentLength*p,B=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastAddedLength:0;for(m=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastPoint:0,y=!0,f=T.points.length;y;){if(B+=T.points[m].partialLength,0===L||0===p||m===T.points.length-1){for(l=T.points[m].point.length,h=0;h<l;h+=1)i[h]=T.points[m].point[h];break}if(L>=B&&L<B+T.points[m+1].partialLength){for(I=(L-B)/T.points[m+1].partialLength,l=T.points[m].point.length,h=0;h<l;h+=1)i[h]=T.points[m].point[h]+(T.points[m+1].point[h]-T.points[m].point[h])*I;break}m<f-1?m+=1:y=!1}e._lastPoint=m,e._lastAddedLength=B-T.points[m].partialLength,e._lastKeyframeIndex=u}}else{var z,V,R,O,N;if(g=a.s.length,v=r.s||a.e,this.sh&&1!==a.h)if(t>=E)i[0]=v[0],i[1]=v[1],i[2]=v[2];else if(t<=M)i[0]=a.s[0],i[1]=a.s[1],i[2]=a.s[2];else{var q=ft(a.s),j=ft(v);b=i,_=function(t,e,i){var s,a,r,n,h,o=[],l=t[0],p=t[1],f=t[2],m=t[3],d=e[0],c=e[1],u=e[2],g=e[3];return(a=l*d+p*c+f*u+m*g)<0&&(a=-a,d=-d,c=-c,u=-u,g=-g),1-a>1e-6?(s=Math.acos(a),r=Math.sin(s),n=Math.sin((1-i)*s)/r,h=Math.sin(i*s)/r):(n=1-i,h=i),o[0]=n*l+h*d,o[1]=n*p+h*c,o[2]=n*f+h*u,o[3]=n*m+h*g,o}(q,j,(t-M)/(E-M)),x=_[0],k=_[1],P=_[2],S=_[3],A=Math.atan2(2*k*S-2*x*P,1-2*k*k-2*P*P),D=Math.asin(2*x*k+2*P*S),C=Math.atan2(2*x*S-2*k*P,1-2*x*x-2*P*P),b[0]=A/w,b[1]=D/w,b[2]=C/w}else for(u=0;u<g;u+=1)1!==a.h&&(t>=E?p=1:t<M?p=0:(a.o.x.constructor===Array?(n.__fnct||(n.__fnct=[]),n.__fnct[u]?d=n.__fnct[u]:(z=void 0===a.o.x[u]?a.o.x[0]:a.o.x[u],V=void 0===a.o.y[u]?a.o.y[0]:a.o.y[u],R=void 0===a.i.x[u]?a.i.x[0]:a.i.x[u],O=void 0===a.i.y[u]?a.i.y[0]:a.i.y[u],d=it.getBezierEasing(z,V,R,O).get,n.__fnct[u]=d)):n.__fnct?d=n.__fnct:(z=a.o.x,V=a.o.y,R=a.i.x,O=a.i.y,d=it.getBezierEasing(z,V,R,O).get,a.keyframeMetadata=d),p=d((t-M)/(E-M)))),v=r.s||a.e,N=1===a.h?a.s[u]:a.s[u]+(v[u]-a.s[u])*p,"multidimensional"===this.propType?i[u]=N:i=N}return e.lastIndex=c,i}function ft(t){var e=t[0]*w,i=t[1]*w,s=t[2]*w,a=Math.cos(e/2),r=Math.cos(i/2),n=Math.cos(s/2),h=Math.sin(e/2),o=Math.sin(i/2),l=Math.sin(s/2);return[h*o*n+a*r*l,h*r*n+a*o*l,a*o*n-h*r*l,a*r*n-h*o*l]}function mt(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==ot&&(this._caching.lastFrame>=i&&t>=i||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var s=this.interpolateValue(t,this._caching);this.pv=s}return this._caching.lastFrame=t,this.pv}function dt(t){var e;if("unidimensional"===this.propType)e=t*this.mult,lt(this.v-e)>1e-5&&(this.v=e,this._mdf=!0);else for(var i=0,s=this.v.length;i<s;)e=t[i]*this.mult,lt(this.v[i]-e)>1e-5&&(this.v[i]=e,this._mdf=!0),i+=1}function ct(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t;this.lock=!0,this._mdf=this._isFirstFrame;var e=this.effectsSequence.length,i=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)i=this.effectsSequence[t](i);this.setVValue(i),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function ut(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function gt(t,e,i,s){this.propType="unidimensional",this.mult=i||1,this.data=e,this.v=i?e.k*i:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=s,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=ct,this.setVValue=dt,this.addEffect=ut}function yt(t,e,i,s){var a;this.propType="multidimensional",this.mult=i||1,this.data=e,this._mdf=!1,this.elem=t,this.container=s,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var r=e.k.length;for(this.v=o("float32",r),this.pv=o("float32",r),this.vel=o("float32",r),a=0;a<r;a+=1)this.v[a]=e.k[a]*this.mult,this.pv[a]=e.k[a];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=ct,this.setVValue=dt,this.addEffect=ut}function vt(t,e,i,s){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:ot,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=i||1,this.elem=t,this.container=s,this.comp=t.comp,this.v=ot,this.pv=ot,this._isFirstFrame=!0,this.getValue=ct,this.setVValue=dt,this.interpolateValue=pt,this.effectsSequence=[mt.bind(this)],this.addEffect=ut}function bt(t,e,i,s){var a;this.propType="multidimensional";var r,n,h,l,p=e.k.length;for(a=0;a<p-1;a+=1)e.k[a].to&&e.k[a].s&&e.k[a+1]&&e.k[a+1].s&&(r=e.k[a].s,n=e.k[a+1].s,h=e.k[a].to,l=e.k[a].ti,(2===r.length&&(r[0]!==n[0]||r[1]!==n[1])&&ht.pointOnLine2D(r[0],r[1],n[0],n[1],r[0]+h[0],r[1]+h[1])&&ht.pointOnLine2D(r[0],r[1],n[0],n[1],n[0]+l[0],n[1]+l[1])||3===r.length&&(r[0]!==n[0]||r[1]!==n[1]||r[2]!==n[2])&&ht.pointOnLine3D(r[0],r[1],r[2],n[0],n[1],n[2],r[0]+h[0],r[1]+h[1],r[2]+h[2])&&ht.pointOnLine3D(r[0],r[1],r[2],n[0],n[1],n[2],n[0]+l[0],n[1]+l[1],n[2]+l[2]))&&(e.k[a].to=null,e.k[a].ti=null),r[0]===n[0]&&r[1]===n[1]&&0===h[0]&&0===h[1]&&0===l[0]&&0===l[1]&&(2===r.length||r[2]===n[2]&&0===h[2]&&0===l[2])&&(e.k[a].to=null,e.k[a].ti=null));this.effectsSequence=[mt.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=i||1,this.elem=t,this.container=s,this.comp=t.comp,this.getValue=ct,this.setVValue=dt,this.interpolateValue=pt,this.frameId=-1;var f=e.k[0].s.length;for(this.v=o("float32",f),this.pv=o("float32",f),a=0;a<f;a+=1)this.v[a]=ot,this.pv[a]=ot;this._caching={lastFrame:ot,lastIndex:0,value:o("float32",f)},this.addEffect=ut}var _t={getProp:function(t,e,i,s,a){var r;if(e.sid&&(e=t.globalData.slotManager.getProp(e)),e.k.length)if("number"==typeof e.k[0])r=new yt(t,e,s,a);else switch(i){case 0:r=new vt(t,e,s,a);break;case 1:r=new bt(t,e,s,a)}else r=new gt(t,e,s,a);return r.effectsSequence.length&&a.addDynamicProperty(r),r}};function xt(){}xt.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){var t;this._mdf=!1;var e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var kt=at(8,(function(){return o("float32",2)}));function wt(){this.c=!1,this._length=0,this._maxLength=8,this.v=l(this._maxLength),this.o=l(this._maxLength),this.i=l(this._maxLength)}wt.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var i=0;i<e;)this.v[i]=kt.newElement(),this.o[i]=kt.newElement(),this.i[i]=kt.newElement(),i+=1},wt.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},wt.prototype.doubleArrayLength=function(){this.v=this.v.concat(l(this._maxLength)),this.i=this.i.concat(l(this._maxLength)),this.o=this.o.concat(l(this._maxLength)),this._maxLength*=2},wt.prototype.setXYAt=function(t,e,i,s,a){var r;switch(this._length=Math.max(this._length,s+1),this._length>=this._maxLength&&this.doubleArrayLength(),i){case"v":r=this.v;break;case"i":r=this.i;break;case"o":r=this.o;break;default:r=[]}(!r[s]||r[s]&&!a)&&(r[s]=kt.newElement()),r[s][0]=t,r[s][1]=e},wt.prototype.setTripleAt=function(t,e,i,s,a,r,n,h){this.setXYAt(t,e,"v",n,h),this.setXYAt(i,s,"o",n,h),this.setXYAt(a,r,"i",n,h)},wt.prototype.reverse=function(){var t=new wt;t.setPathData(this.c,this._length);var e=this.v,i=this.o,s=this.i,a=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],s[0][0],s[0][1],i[0][0],i[0][1],0,!1),a=1);var r,n=this._length-1,h=this._length;for(r=a;r<h;r+=1)t.setTripleAt(e[n][0],e[n][1],s[n][0],s[n][1],i[n][0],i[n][1],r,!1),n-=1;return t},wt.prototype.length=function(){return this._length};var Pt,St=((Pt=at(4,(function(){return new wt}),(function(t){var e,i=t._length;for(e=0;e<i;e+=1)kt.release(t.v[e]),kt.release(t.i[e]),kt.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1}))).clone=function(t){var e,i=Pt.newElement(),s=void 0===t._length?t.v.length:t._length;for(i.setLength(s),i.c=t.c,e=0;e<s;e+=1)i.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return i},Pt);function At(){this._length=0,this._maxLength=4,this.shapes=l(this._maxLength)}At.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(l(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},At.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)St.release(this.shapes[t]);this._length=0};var Dt,Ct,Et,Mt,Tt=(Dt={newShapeCollection:function(){return Ct?Mt[Ct-=1]:new At},release:function(t){var e,i=t._length;for(e=0;e<i;e+=1)St.release(t.shapes[e]);t._length=0,Ct===Et&&(Mt=st.double(Mt),Et*=2),Mt[Ct]=t,Ct+=1}},Ct=0,Mt=l(Et=4),Dt),Ft=function(){var t=-999999;function e(t,e,i){var s,a,r,n,h,o,l,p,f,m=i.lastIndex,d=this.keyframes;if(t<d[0].t-this.offsetTime)s=d[0].s[0],r=!0,m=0;else if(t>=d[d.length-1].t-this.offsetTime)s=d[d.length-1].s?d[d.length-1].s[0]:d[d.length-2].e[0],r=!0;else{for(var c,u,g,y=m,v=d.length-1,b=!0;b&&(c=d[y],!((u=d[y+1]).t-this.offsetTime>t));)y<v-1?y+=1:b=!1;if(g=this.keyframesMetadata[y]||{},m=y,!(r=1===c.h)){if(t>=u.t-this.offsetTime)p=1;else if(t<c.t-this.offsetTime)p=0;else{var _;g.__fnct?_=g.__fnct:(_=it.getBezierEasing(c.o.x,c.o.y,c.i.x,c.i.y).get,g.__fnct=_),p=_((t-(c.t-this.offsetTime))/(u.t-this.offsetTime-(c.t-this.offsetTime)))}a=u.s?u.s[0]:c.e[0]}s=c.s[0]}for(o=e._length,l=s.i[0].length,i.lastIndex=m,n=0;n<o;n+=1)for(h=0;h<l;h+=1)f=r?s.i[n][h]:s.i[n][h]+(a.i[n][h]-s.i[n][h])*p,e.i[n][h]=f,f=r?s.o[n][h]:s.o[n][h]+(a.o[n][h]-s.o[n][h])*p,e.o[n][h]=f,f=r?s.v[n][h]:s.v[n][h]+(a.v[n][h]-s.v[n][h])*p,e.v[n][h]=f}function i(){var e=this.comp.renderedFrame-this.offsetTime,i=this.keyframes[0].t-this.offsetTime,s=this.keyframes[this.keyframes.length-1].t-this.offsetTime,a=this._caching.lastFrame;return a!==t&&(a<i&&e<i||a>s&&e>s)||(this._caching.lastIndex=a<e?this._caching.lastIndex:0,this.interpolateShape(e,this.pv,this._caching)),this._caching.lastFrame=e,this.pv}function s(){this.paths=this.localShapeCollection}function a(t){(function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var i,s=t._length;for(i=0;i<s;i+=1)if(t.v[i][0]!==e.v[i][0]||t.v[i][1]!==e.v[i][1]||t.o[i][0]!==e.o[i][0]||t.o[i][1]!==e.o[i][1]||t.i[i][0]!==e.i[i][0]||t.i[i][1]!==e.i[i][1])return!1;return!0})(this.v,t)||(this.v=St.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function n(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t,e;this.lock=!0,this._mdf=!1,t=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k;var i=this.effectsSequence.length;for(e=0;e<i;e+=1)t=this.effectsSequence[e](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function h(t,e,i){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var a=3===i?e.pt.k:e.ks.k;this.v=St.clone(a),this.pv=St.clone(this.v),this.localShapeCollection=Tt.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=s,this.effectsSequence=[]}function o(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function l(e,a,r){this.propType="shape",this.comp=e.comp,this.elem=e,this.container=e,this.offsetTime=e.data.st,this.keyframes=3===r?a.pt.k:a.ks.k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;var n=this.keyframes[0].s[0].i.length;this.v=St.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,n),this.pv=St.clone(this.v),this.localShapeCollection=Tt.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=t,this.reset=s,this._caching={lastFrame:t,lastIndex:0},this.effectsSequence=[i.bind(this)]}h.prototype.interpolateShape=e,h.prototype.getValue=n,h.prototype.setVValue=a,h.prototype.addEffect=o,l.prototype.getValue=n,l.prototype.interpolateShape=e,l.prototype.setVValue=a,l.prototype.addEffect=o;var p=function(){var t=P;function e(t,e){this.v=St.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=Tt.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=_t.getProp(t,e.p,1,0,this),this.s=_t.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}return e.prototype={reset:s,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var e=this.p.v[0],i=this.p.v[1],s=this.s.v[0]/2,a=this.s.v[1]/2,r=3!==this.d,n=this.v;n.v[0][0]=e,n.v[0][1]=i-a,n.v[1][0]=r?e+s:e-s,n.v[1][1]=i,n.v[2][0]=e,n.v[2][1]=i+a,n.v[3][0]=r?e-s:e+s,n.v[3][1]=i,n.i[0][0]=r?e-s*t:e+s*t,n.i[0][1]=i-a,n.i[1][0]=r?e+s:e-s,n.i[1][1]=i-a*t,n.i[2][0]=r?e+s*t:e-s*t,n.i[2][1]=i+a,n.i[3][0]=r?e-s:e+s,n.i[3][1]=i+a*t,n.o[0][0]=r?e+s*t:e-s*t,n.o[0][1]=i-a,n.o[1][0]=r?e+s:e-s,n.o[1][1]=i+a*t,n.o[2][0]=r?e-s*t:e+s*t,n.o[2][1]=i+a,n.o[3][0]=r?e-s:e+s,n.o[3][1]=i-a*t}},r([xt],e),e}(),f=function(){function t(t,e){this.v=St.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=_t.getProp(t,e.ir,0,0,this),this.is=_t.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=_t.getProp(t,e.pt,0,0,this),this.p=_t.getProp(t,e.p,1,0,this),this.r=_t.getProp(t,e.r,0,w,this),this.or=_t.getProp(t,e.or,0,0,this),this.os=_t.getProp(t,e.os,0,.01,this),this.localShapeCollection=Tt.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}return t.prototype={reset:s,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,i,s,a=2*Math.floor(this.pt.v),r=2*Math.PI/a,n=!0,h=this.or.v,o=this.ir.v,l=this.os.v,p=this.is.v,f=2*Math.PI*h/(2*a),m=2*Math.PI*o/(2*a),d=-Math.PI/2;d+=this.r.v;var c=3===this.data.d?-1:1;for(this.v._length=0,t=0;t<a;t+=1){i=n?l:p,s=n?f:m;var u=(e=n?h:o)*Math.cos(d),g=e*Math.sin(d),y=0===u&&0===g?0:g/Math.sqrt(u*u+g*g),v=0===u&&0===g?0:-u/Math.sqrt(u*u+g*g);u+=+this.p.v[0],g+=+this.p.v[1],this.v.setTripleAt(u,g,u-y*s*i*c,g-v*s*i*c,u+y*s*i*c,g+v*s*i*c,t,!0),n=!n,d+=r*c}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),i=2*Math.PI/e,s=this.or.v,a=this.os.v,r=2*Math.PI*s/(4*e),n=.5*-Math.PI,h=3===this.data.d?-1:1;for(n+=this.r.v,this.v._length=0,t=0;t<e;t+=1){var o=s*Math.cos(n),l=s*Math.sin(n),p=0===o&&0===l?0:l/Math.sqrt(o*o+l*l),f=0===o&&0===l?0:-o/Math.sqrt(o*o+l*l);o+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(o,l,o-p*r*a*h,l-f*r*a*h,o+p*r*a*h,l+f*r*a*h,t,!0),n+=i*h}this.paths.length=0,this.paths[0]=this.v}},r([xt],t),t}(),m=function(){function t(t,e){this.v=St.newElement(),this.v.c=!0,this.localShapeCollection=Tt.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=_t.getProp(t,e.p,1,0,this),this.s=_t.getProp(t,e.s,1,0,this),this.r=_t.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}return t.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,s=this.s.v[1]/2,a=_(i,s,this.r.v),r=a*(1-P);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+i,e-s+a,t+i,e-s+a,t+i,e-s+r,0,!0),this.v.setTripleAt(t+i,e+s-a,t+i,e+s-r,t+i,e+s-a,1,!0),0!==a?(this.v.setTripleAt(t+i-a,e+s,t+i-a,e+s,t+i-r,e+s,2,!0),this.v.setTripleAt(t-i+a,e+s,t-i+r,e+s,t-i+a,e+s,3,!0),this.v.setTripleAt(t-i,e+s-a,t-i,e+s-a,t-i,e+s-r,4,!0),this.v.setTripleAt(t-i,e-s+a,t-i,e-s+r,t-i,e-s+a,5,!0),this.v.setTripleAt(t-i+a,e-s,t-i+a,e-s,t-i+r,e-s,6,!0),this.v.setTripleAt(t+i-a,e-s,t+i-r,e-s,t+i-a,e-s,7,!0)):(this.v.setTripleAt(t-i,e+s,t-i+r,e+s,t-i,e+s,2),this.v.setTripleAt(t-i,e-s,t-i,e-s+r,t-i,e-s,3))):(this.v.setTripleAt(t+i,e-s+a,t+i,e-s+r,t+i,e-s+a,0,!0),0!==a?(this.v.setTripleAt(t+i-a,e-s,t+i-a,e-s,t+i-r,e-s,1,!0),this.v.setTripleAt(t-i+a,e-s,t-i+r,e-s,t-i+a,e-s,2,!0),this.v.setTripleAt(t-i,e-s+a,t-i,e-s+a,t-i,e-s+r,3,!0),this.v.setTripleAt(t-i,e+s-a,t-i,e+s-r,t-i,e+s-a,4,!0),this.v.setTripleAt(t-i+a,e+s,t-i+a,e+s,t-i+r,e+s,5,!0),this.v.setTripleAt(t+i-a,e+s,t+i-r,e+s,t+i-a,e+s,6,!0),this.v.setTripleAt(t+i,e+s-a,t+i,e+s-a,t+i,e+s-r,7,!0)):(this.v.setTripleAt(t-i,e-s,t-i+r,e-s,t-i,e-s,1,!0),this.v.setTripleAt(t-i,e+s,t-i,e+s-r,t-i,e+s,2,!0),this.v.setTripleAt(t+i,e+s,t+i-r,e+s,t+i,e+s,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:s},r([xt],t),t}();var d={getShapeProp:function(t,e,i){var s;return 3===i||4===i?s=(3===i?e.pt:e.ks).k.length?new l(t,e,i):new h(t,e,i):5===i?s=new m(t,e):6===i?s=new p(t,e):7===i&&(s=new f(t,e)),s.k&&t.addDynamicProperty(s),s},getConstructorFunction:function(){return h},getKeyframedConstructorFunction:function(){return l}};return d}(),It=function(){var t=Math.cos,e=Math.sin,i=Math.tan,s=Math.round;function a(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function r(i){if(0===i)return this;var s=t(i),a=e(i);return this._t(s,-a,0,0,a,s,0,0,0,0,1,0,0,0,0,1)}function n(i){if(0===i)return this;var s=t(i),a=e(i);return this._t(1,0,0,0,0,s,-a,0,0,a,s,0,0,0,0,1)}function h(i){if(0===i)return this;var s=t(i),a=e(i);return this._t(s,0,a,0,0,1,0,0,-a,0,s,0,0,0,0,1)}function l(i){if(0===i)return this;var s=t(i),a=e(i);return this._t(s,-a,0,0,a,s,0,0,0,0,1,0,0,0,0,1)}function p(t,e){return this._t(1,e,t,1,0,0)}function f(t,e){return this.shear(i(t),i(e))}function m(s,a){var r=t(a),n=e(a);return this._t(r,n,0,0,-n,r,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,i(s),1,0,0,0,0,1,0,0,0,0,1)._t(r,-n,0,0,n,r,0,0,0,0,1,0,0,0,0,1)}function d(t,e,i){return i||0===i||(i=1),1===t&&1===e&&1===i?this:this._t(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1)}function c(t,e,i,s,a,r,n,h,o,l,p,f,m,d,c,u){return this.props[0]=t,this.props[1]=e,this.props[2]=i,this.props[3]=s,this.props[4]=a,this.props[5]=r,this.props[6]=n,this.props[7]=h,this.props[8]=o,this.props[9]=l,this.props[10]=p,this.props[11]=f,this.props[12]=m,this.props[13]=d,this.props[14]=c,this.props[15]=u,this}function u(t,e,i){return i=i||0,0!==t||0!==e||0!==i?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,i,1):this}function g(t,e,i,s,a,r,n,h,o,l,p,f,m,d,c,u){var g=this.props;if(1===t&&0===e&&0===i&&0===s&&0===a&&1===r&&0===n&&0===h&&0===o&&0===l&&1===p&&0===f)return g[12]=g[12]*t+g[15]*m,g[13]=g[13]*r+g[15]*d,g[14]=g[14]*p+g[15]*c,g[15]*=u,this._identityCalculated=!1,this;var y=g[0],v=g[1],b=g[2],_=g[3],x=g[4],k=g[5],w=g[6],P=g[7],S=g[8],A=g[9],D=g[10],C=g[11],E=g[12],M=g[13],T=g[14],F=g[15];return g[0]=y*t+v*a+b*o+_*m,g[1]=y*e+v*r+b*l+_*d,g[2]=y*i+v*n+b*p+_*c,g[3]=y*s+v*h+b*f+_*u,g[4]=x*t+k*a+w*o+P*m,g[5]=x*e+k*r+w*l+P*d,g[6]=x*i+k*n+w*p+P*c,g[7]=x*s+k*h+w*f+P*u,g[8]=S*t+A*a+D*o+C*m,g[9]=S*e+A*r+D*l+C*d,g[10]=S*i+A*n+D*p+C*c,g[11]=S*s+A*h+D*f+C*u,g[12]=E*t+M*a+T*o+F*m,g[13]=E*e+M*r+T*l+F*d,g[14]=E*i+M*n+T*p+F*c,g[15]=E*s+M*h+T*f+F*u,this._identityCalculated=!1,this}function y(t){var e=t.props;return this.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}function v(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function b(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function _(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function x(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function k(t,e,i){return{x:t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}}function w(t,e,i){return t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12]}function P(t,e,i){return t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13]}function S(t,e,i){return t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}function A(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,i=-this.props[1]/t,s=-this.props[4]/t,a=this.props[0]/t,r=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,n=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,h=new It;return h.props[0]=e,h.props[1]=i,h.props[4]=s,h.props[5]=a,h.props[12]=r,h.props[13]=n,h}function D(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function C(t){var e,i=t.length,s=[];for(e=0;e<i;e+=1)s[e]=D(t[e]);return s}function E(t,e,i){var s=o("float32",6);if(this.isIdentity())s[0]=t[0],s[1]=t[1],s[2]=e[0],s[3]=e[1],s[4]=i[0],s[5]=i[1];else{var a=this.props[0],r=this.props[1],n=this.props[4],h=this.props[5],l=this.props[12],p=this.props[13];s[0]=t[0]*a+t[1]*n+l,s[1]=t[0]*r+t[1]*h+p,s[2]=e[0]*a+e[1]*n+l,s[3]=e[0]*r+e[1]*h+p,s[4]=i[0]*a+i[1]*n+l,s[5]=i[0]*r+i[1]*h+p}return s}function M(t,e,i){return this.isIdentity()?[t,e,i]:[t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]]}function T(t,e){if(this.isIdentity())return t+","+e;var i=this.props;return Math.round(100*(t*i[0]+e*i[4]+i[12]))/100+","+Math.round(100*(t*i[1]+e*i[5]+i[13]))/100}function F(){for(var t=0,e=this.props,i="matrix3d(";t<16;)i+=s(1e4*e[t])/1e4,i+=15===t?")":",",t+=1;return i}function I(t){return t<1e-6&&t>0||t>-1e-6&&t<0?s(1e4*t)/1e4:t}function L(){var t=this.props;return"matrix("+I(t[0])+","+I(t[1])+","+I(t[4])+","+I(t[5])+","+I(t[12])+","+I(t[13])+")"}return function(){this.reset=a,this.rotate=r,this.rotateX=n,this.rotateY=h,this.rotateZ=l,this.skew=f,this.skewFromAxis=m,this.shear=p,this.scale=d,this.setTransform=c,this.translate=u,this.transform=g,this.multiply=y,this.applyToPoint=k,this.applyToX=w,this.applyToY=P,this.applyToZ=S,this.applyToPointArray=M,this.applyToTriplePoints=E,this.applyToPointStringified=T,this.toCSS=F,this.to2dCSS=L,this.clone=_,this.cloneFromProps=x,this.equals=b,this.inversePoints=C,this.inversePoint=D,this.getInverseMatrix=A,this._t=this.transform,this.isIdentity=v,this._identity=!0,this._identityCalculated=!1,this.props=o("float32",16),this.reset()}}();function Lt(t){return Lt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},Lt(t)}var Bt={},zt="__[STANDALONE]__";function Vt(){et.searchAnimations()}Bt.play=et.play,Bt.pause=et.pause,Bt.setLocationHref=function(e){t=e},Bt.togglePause=et.togglePause,Bt.setSpeed=et.setSpeed,Bt.setDirection=et.setDirection,Bt.stop=et.stop,Bt.searchAnimations=Vt,Bt.registerAnimation=et.registerAnimation,Bt.loadAnimation=function(t){return et.loadAnimation(t)},Bt.setSubframeRendering=function(t){!function(t){f=!!t}(t)},Bt.resize=et.resize,Bt.goToAndStop=et.goToAndStop,Bt.destroy=et.destroy,Bt.setQuality=function(t){if("string"==typeof t)switch(t){case"high":W(200);break;default:case"medium":W(50);break;case"low":W(10)}else!isNaN(t)&&t>1&&W(t);H()>=50?S(!1):S(!0)},Bt.inBrowser=function(){return"undefined"!=typeof navigator},Bt.installPlugin=function(t,e){"expressions"===t&&(m=e)},Bt.freeze=et.freeze,Bt.unfreeze=et.unfreeze,Bt.setVolume=et.setVolume,Bt.mute=et.mute,Bt.unmute=et.unmute,Bt.getRegisteredAnimations=et.getRegisteredAnimations,Bt.useWebWorker=function(t){e=!!t},Bt.setIDPrefix=function(t){c=t},Bt.__getFactory=function(t){switch(t){case"propertyFactory":return _t;case"shapePropertyFactory":return Ft;case"matrix":return It;default:return null}},Bt.version="5.13.0";var Rt="";if(zt){var Ot=document.getElementsByTagName("script"),Nt=Ot[Ot.length-1]||{src:""};Rt=Nt.src?Nt.src.replace(/^[^\?]+\??/,""):"",function(t){for(var e=Rt.split("&"),i=0;i<e.length;i+=1){var s=e[i].split("=");if(decodeURIComponent(s[0])==t)return decodeURIComponent(s[1])}return null}("renderer")}var qt=setInterval((function(){"complete"===document.readyState&&(clearInterval(qt),Vt())}),100);try{"object"===("undefined"==typeof exports?"undefined":Lt(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=Bt)}catch(t){}var jt=function(){var t={},e={};return t.registerModifier=function(t,i){e[t]||(e[t]=i)},t.getModifier=function(t,i,s){return new e[t](i,s)},t}();function Wt(){}function Ht(){}function Xt(){}Wt.prototype.initModifierProperties=function(){},Wt.prototype.addShapeToModifier=function(){},Wt.prototype.addShape=function(t){if(!this.closed){t.sh.container.addDynamicProperty(t.sh);var e={shape:t.sh,data:t,localShapeCollection:Tt.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},Wt.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=i,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},Wt.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},r([xt],Wt),r([Wt],Ht),Ht.prototype.initModifierProperties=function(t,e){this.s=_t.getProp(t,e.s,0,.01,this),this.e=_t.getProp(t,e.e,0,.01,this),this.o=_t.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},Ht.prototype.addShapeToModifier=function(t){t.pathsData=[]},Ht.prototype.calculateShapeEdges=function(t,e,i,s,a){var r=[];e<=1?r.push({s:t,e:e}):t>=1?r.push({s:t-1,e:e-1}):(r.push({s:t,e:1}),r.push({s:0,e:e-1}));var n,h,o=[],l=r.length;for(n=0;n<l;n+=1){var p,f;if(!((h=r[n]).e*a<s||h.s*a>s+i))p=h.s*a<=s?0:(h.s*a-s)/i,f=h.e*a>=s+i?1:(h.e*a-s)/i,o.push([p,f])}return o.length||o.push([0,0]),o},Ht.prototype.releasePathsData=function(t){var e,i=t.length;for(e=0;e<i;e+=1)nt.release(t[e]);return t.length=0,t},Ht.prototype.processShapes=function(t){var e,i,s,a;if(this._mdf||t){var r=this.o.v%360/360;if(r<0&&(r+=1),(e=this.s.v>1?1+r:this.s.v<0?0+r:this.s.v+r)>(i=this.e.v>1?1+r:this.e.v<0?0+r:this.e.v+r)){var n=e;e=i,i=n}e=1e-4*Math.round(1e4*e),i=1e-4*Math.round(1e4*i),this.sValue=e,this.eValue=i}else e=this.sValue,i=this.eValue;var h,o,l,p,f,m=this.shapes.length,d=0;if(i===e)for(a=0;a<m;a+=1)this.shapes[a].localShapeCollection.releaseShapes(),this.shapes[a].shape._mdf=!0,this.shapes[a].shape.paths=this.shapes[a].localShapeCollection,this._mdf&&(this.shapes[a].pathsData.length=0);else if(1===i&&0===e||0===i&&1===e){if(this._mdf)for(a=0;a<m;a+=1)this.shapes[a].pathsData.length=0,this.shapes[a].shape._mdf=!0}else{var c,u,g=[];for(a=0;a<m;a+=1)if((c=this.shapes[a]).shape._mdf||this._mdf||t||2===this.m){if(o=(s=c.shape.paths)._length,f=0,!c.shape._mdf&&c.pathsData.length)f=c.totalShapeLength;else{for(l=this.releasePathsData(c.pathsData),h=0;h<o;h+=1)p=ht.getSegmentsLength(s.shapes[h]),l.push(p),f+=p.totalLength;c.totalShapeLength=f,c.pathsData=l}d+=f,c.shape._mdf=!0}else c.shape.paths=c.localShapeCollection;var y,v=e,b=i,_=0;for(a=m-1;a>=0;a-=1)if((c=this.shapes[a]).shape._mdf){for((u=c.localShapeCollection).releaseShapes(),2===this.m&&m>1?(y=this.calculateShapeEdges(e,i,c.totalShapeLength,_,d),_+=c.totalShapeLength):y=[[v,b]],o=y.length,h=0;h<o;h+=1){v=y[h][0],b=y[h][1],g.length=0,b<=1?g.push({s:c.totalShapeLength*v,e:c.totalShapeLength*b}):v>=1?g.push({s:c.totalShapeLength*(v-1),e:c.totalShapeLength*(b-1)}):(g.push({s:c.totalShapeLength*v,e:c.totalShapeLength}),g.push({s:0,e:c.totalShapeLength*(b-1)}));var x=this.addShapes(c,g[0]);if(g[0].s!==g[0].e){if(g.length>1)if(c.shape.paths.shapes[c.shape.paths._length-1].c){var k=x.pop();this.addPaths(x,u),x=this.addShapes(c,g[1],k)}else this.addPaths(x,u),x=this.addShapes(c,g[1]);this.addPaths(x,u)}}c.shape.paths=u}}},Ht.prototype.addPaths=function(t,e){var i,s=t.length;for(i=0;i<s;i+=1)e.addShape(t[i])},Ht.prototype.addSegment=function(t,e,i,s,a,r,n){a.setXYAt(e[0],e[1],"o",r),a.setXYAt(i[0],i[1],"i",r+1),n&&a.setXYAt(t[0],t[1],"v",r),a.setXYAt(s[0],s[1],"v",r+1)},Ht.prototype.addSegmentFromArray=function(t,e,i,s){e.setXYAt(t[1],t[5],"o",i),e.setXYAt(t[2],t[6],"i",i+1),s&&e.setXYAt(t[0],t[4],"v",i),e.setXYAt(t[3],t[7],"v",i+1)},Ht.prototype.addShapes=function(t,e,i){var s,a,r,n,h,o,l,p,f=t.pathsData,m=t.shape.paths.shapes,d=t.shape.paths._length,c=0,u=[],g=!0;for(i?(h=i._length,p=i._length):(i=St.newElement(),h=0,p=0),u.push(i),s=0;s<d;s+=1){for(o=f[s].lengths,i.c=m[s].c,r=m[s].c?o.length:o.length+1,a=1;a<r;a+=1)if(c+(n=o[a-1]).addedLength<e.s)c+=n.addedLength,i.c=!1;else{if(c>e.e){i.c=!1;break}e.s<=c&&e.e>=c+n.addedLength?(this.addSegment(m[s].v[a-1],m[s].o[a-1],m[s].i[a],m[s].v[a],i,h,g),g=!1):(l=ht.getNewSegment(m[s].v[a-1],m[s].v[a],m[s].o[a-1],m[s].i[a],(e.s-c)/n.addedLength,(e.e-c)/n.addedLength,o[a-1]),this.addSegmentFromArray(l,i,h,g),g=!1,i.c=!1),c+=n.addedLength,h+=1}if(m[s].c&&o.length){if(n=o[a-1],c<=e.e){var y=o[a-1].addedLength;e.s<=c&&e.e>=c+y?(this.addSegment(m[s].v[a-1],m[s].o[a-1],m[s].i[0],m[s].v[0],i,h,g),g=!1):(l=ht.getNewSegment(m[s].v[a-1],m[s].v[0],m[s].o[a-1],m[s].i[0],(e.s-c)/y,(e.e-c)/y,o[a-1]),this.addSegmentFromArray(l,i,h,g),g=!1,i.c=!1)}else i.c=!1;c+=n.addedLength,h+=1}if(i._length&&(i.setXYAt(i.v[p][0],i.v[p][1],"i",p),i.setXYAt(i.v[i._length-1][0],i.v[i._length-1][1],"o",i._length-1)),c>e.e)break;s<d-1&&(i=St.newElement(),g=!0,u.push(i),h=0)}return u},r([Wt],Xt),Xt.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=_t.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},Xt.prototype.processPath=function(t,e){var i=e/100,s=[0,0],a=t._length,r=0;for(r=0;r<a;r+=1)s[0]+=t.v[r][0],s[1]+=t.v[r][1];s[0]/=a,s[1]/=a;var n,h,o,l,p,f,m=St.newElement();for(m.c=t.c,r=0;r<a;r+=1)n=t.v[r][0]+(s[0]-t.v[r][0])*i,h=t.v[r][1]+(s[1]-t.v[r][1])*i,o=t.o[r][0]+(s[0]-t.o[r][0])*-i,l=t.o[r][1]+(s[1]-t.o[r][1])*-i,p=t.i[r][0]+(s[0]-t.i[r][0])*-i,f=t.i[r][1]+(s[1]-t.i[r][1])*-i,m.setTripleAt(n,h,o,l,p,f,r);return m},Xt.prototype.processShapes=function(t){var e,i,s,a,r,n,h=this.shapes.length,o=this.amount.v;if(0!==o)for(i=0;i<h;i+=1){if(n=(r=this.shapes[i]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,s=0;s<a;s+=1)n.addShape(this.processPath(e[s],o));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var Yt=function(){var t=[0,0];function e(t,e,i){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new It,this.pre=new It,this.appliedTransformations=0,this.initDynamicPropertyContainer(i||t),e.p&&e.p.s?(this.px=_t.getProp(t,e.p.x,0,0,this),this.py=_t.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=_t.getProp(t,e.p.z,0,0,this))):this.p=_t.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=_t.getProp(t,e.rx,0,w,this),this.ry=_t.getProp(t,e.ry,0,w,this),this.rz=_t.getProp(t,e.rz,0,w,this),e.or.k[0].ti){var s,a=e.or.k.length;for(s=0;s<a;s+=1)e.or.k[s].to=null,e.or.k[s].ti=null}this.or=_t.getProp(t,e.or,1,w,this),this.or.sh=!0}else this.r=_t.getProp(t,e.r||{k:0},0,w,this);e.sk&&(this.sk=_t.getProp(t,e.sk,0,w,this),this.sa=_t.getProp(t,e.sa,0,w,this)),this.a=_t.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=_t.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=_t.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return e.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(e){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||e){var i;if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var s,a;if(i=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime)this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(s=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/i,0),a=this.p.getValueAtTime(this.p.keyframes[0].t/i,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(s=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/i,0),a=this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/i,0)):(s=this.p.pv,a=this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/i,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){s=[],a=[];var r=this.px,n=this.py;r._caching.lastFrame+r.offsetTime<=r.keyframes[0].t?(s[0]=r.getValueAtTime((r.keyframes[0].t+.01)/i,0),s[1]=n.getValueAtTime((n.keyframes[0].t+.01)/i,0),a[0]=r.getValueAtTime(r.keyframes[0].t/i,0),a[1]=n.getValueAtTime(n.keyframes[0].t/i,0)):r._caching.lastFrame+r.offsetTime>=r.keyframes[r.keyframes.length-1].t?(s[0]=r.getValueAtTime(r.keyframes[r.keyframes.length-1].t/i,0),s[1]=n.getValueAtTime(n.keyframes[n.keyframes.length-1].t/i,0),a[0]=r.getValueAtTime((r.keyframes[r.keyframes.length-1].t-.01)/i,0),a[1]=n.getValueAtTime((n.keyframes[n.keyframes.length-1].t-.01)/i,0)):(s=[r.pv,n.pv],a[0]=r.getValueAtTime((r._caching.lastFrame+r.offsetTime-.01)/i,r.offsetTime),a[1]=n.getValueAtTime((n._caching.lastFrame+n.offsetTime-.01)/i,n.offsetTime))}else s=a=t;this.v.rotate(-Math.atan2(s[1]-a[1],s[0]-a[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},r([xt],e),e.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},e.prototype._addDynamicProperty=xt.prototype.addDynamicProperty,{getTransformProperty:function(t,i,s){return new e(t,i,s)}}}();function Gt(){}function Kt(){}function Jt(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function Zt(t){return Math.abs(t)<=1e-5}function Ut(t,e,i){return t*(1-i)+e*i}function Qt(t,e,i){return[Ut(t[0],e[0],i),Ut(t[1],e[1],i)]}function $t(t,e,i,s){return[3*e-t-3*i+s,3*t-6*e+3*i,-3*t+3*e,t]}function te(t){return new ee(t,t,t,t,!1)}function ee(t,e,i,s,a){a&&pe(t,e)&&(e=Qt(t,s,1/3)),a&&pe(i,s)&&(i=Qt(t,s,2/3));var r=$t(t[0],e[0],i[0],s[0]),n=$t(t[1],e[1],i[1],s[1]);this.a=[r[0],n[0]],this.b=[r[1],n[1]],this.c=[r[2],n[2]],this.d=[r[3],n[3]],this.points=[t,e,i,s]}function ie(t,e){var i=t.points[0][e],s=t.points[t.points.length-1][e];if(i>s){var a=s;s=i,i=a}for(var r=function(t,e,i){if(0===t)return[];var s=e*e-4*t*i;if(s<0)return[];var a=-e/(2*t);if(0===s)return[a];var r=Math.sqrt(s)/(2*t);return[a-r,a+r]}(3*t.a[e],2*t.b[e],t.c[e]),n=0;n<r.length;n+=1)if(r[n]>0&&r[n]<1){var h=t.point(r[n])[e];h<i?i=h:h>s&&(s=h)}return{min:i,max:s}}function se(t,e,i){var s=t.boundingBox();return{cx:s.cx,cy:s.cy,width:s.width,height:s.height,bez:t,t:(e+i)/2,t1:e,t2:i}}function ae(t){var e=t.bez.split(.5);return[se(e[0],t.t1,t.t),se(e[1],t.t,t.t2)]}function re(t,e,i,s,a,r){var n,h;if(n=t,h=e,2*Math.abs(n.cx-h.cx)<n.width+h.width&&2*Math.abs(n.cy-h.cy)<n.height+h.height)if(i>=r||t.width<=s&&t.height<=s&&e.width<=s&&e.height<=s)a.push([t.t,e.t]);else{var o=ae(t),l=ae(e);re(o[0],l[0],i+1,s,a,r),re(o[0],l[1],i+1,s,a,r),re(o[1],l[0],i+1,s,a,r),re(o[1],l[1],i+1,s,a,r)}}function ne(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function he(t,e,i,s){var a=[t[0],t[1],1],r=[e[0],e[1],1],n=[i[0],i[1],1],h=[s[0],s[1],1],o=ne(ne(a,r),ne(n,h));return Zt(o[2])?null:[o[0]/o[2],o[1]/o[2]]}function oe(t,e,i){return[t[0]+Math.cos(e)*i,t[1]-Math.sin(e)*i]}function le(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function pe(t,e){return Jt(t[0],e[0])&&Jt(t[1],e[1])}function fe(){}function me(t,e,i,s,a,r,n){var h=i-Math.PI/2,o=i+Math.PI/2,l=e[0]+Math.cos(i)*s*a,p=e[1]-Math.sin(i)*s*a;t.setTripleAt(l,p,l+Math.cos(h)*r,p-Math.sin(h)*r,l+Math.cos(o)*n,p-Math.sin(o)*n,t.length())}function de(t,e){var i,s,a,r,n=0===e?t.length()-1:e-1,h=(e+1)%t.length(),o=t.v[n],l=t.v[h],p=(i=o,a=[(s=l)[0]-i[0],s[1]-i[1]],r=.5*-Math.PI,[Math.cos(r)*a[0]-Math.sin(r)*a[1],Math.sin(r)*a[0]+Math.cos(r)*a[1]]);return Math.atan2(0,1)-Math.atan2(p[1],p[0])}function ce(t,e,i,s,a,r,n){var h=de(e,i),o=e.v[i%e._length],l=e.v[0===i?e._length-1:i-1],p=e.v[(i+1)%e._length],f=2===r?Math.sqrt(Math.pow(o[0]-l[0],2)+Math.pow(o[1]-l[1],2)):0,m=2===r?Math.sqrt(Math.pow(o[0]-p[0],2)+Math.pow(o[1]-p[1],2)):0;me(t,e.v[i%e._length],h,n,s,m/(2*(a+1)),f/(2*(a+1)))}function ue(t,e,i,s,a,r){for(var n=0;n<s;n+=1){var h=(n+1)/(s+1),o=2===a?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(h);me(t,e.point(h),l,r,i,o/(2*(s+1)),o/(2*(s+1))),r=-r}return r}function ge(t,e,i){var s=Math.atan2(e[0]-t[0],e[1]-t[1]);return[oe(t,s,i),oe(e,s,i)]}function ye(t,e){var i,s,a,r,n,h,o;i=(o=ge(t.points[0],t.points[1],e))[0],s=o[1],a=(o=ge(t.points[1],t.points[2],e))[0],r=o[1],n=(o=ge(t.points[2],t.points[3],e))[0],h=o[1];var l=he(i,s,a,r);null===l&&(l=s);var p=he(n,h,a,r);return null===p&&(p=n),new ee(i,l,p,h)}function ve(t,e,i,s,a){var r=e.points[3],n=i.points[0];if(3===s)return r;if(pe(r,n))return r;if(2===s){var h=-e.tangentAngle(1),o=-i.tangentAngle(0)+Math.PI,l=he(r,oe(r,h+Math.PI/2,100),n,oe(n,h+Math.PI/2,100)),p=l?le(l,r):le(r,n)/2,f=oe(r,h,2*p*P);return t.setXYAt(f[0],f[1],"o",t.length()-1),f=oe(n,o,2*p*P),t.setTripleAt(n[0],n[1],n[0],n[1],f[0],f[1],t.length()),n}var m=he(pe(r,e.points[2])?e.points[0]:e.points[2],r,n,pe(n,i.points[1])?i.points[3]:i.points[1]);return m&&le(m,r)<a?(t.setTripleAt(m[0],m[1],m[0],m[1],m[0],m[1],t.length()),m):r}function be(t,e){var i=t.intersections(e);return i.length&&Jt(i[0][0],1)&&i.shift(),i.length?i[0]:null}function _e(t,e){var i=t.slice(),s=e.slice(),a=be(t[t.length-1],e[0]);return a&&(i[t.length-1]=t[t.length-1].split(a[0])[0],s[0]=e[0].split(a[1])[1]),t.length>1&&e.length>1&&(a=be(t[0],e[e.length-1]))?[[t[0].split(a[0])[0]],[e[e.length-1].split(a[1])[1]]]:[i,s]}function xe(t,e){var i,s,a,r,n=t.inflectionPoints();if(0===n.length)return[ye(t,e)];if(1===n.length||Jt(n[1],1))return i=(a=t.split(n[0]))[0],s=a[1],[ye(i,e),ye(s,e)];i=(a=t.split(n[0]))[0];var h=(n[1]-n[0])/(1-n[0]);return r=(a=a[1].split(h))[0],s=a[1],[ye(i,e),ye(r,e),ye(s,e)]}function ke(){}function we(t){for(var e=t.fStyle?t.fStyle.split(" "):[],i="normal",s="normal",a=e.length,r=0;r<a;r+=1)switch(e[r].toLowerCase()){case"italic":s="italic";break;case"bold":i="700";break;case"black":i="900";break;case"medium":i="500";break;case"regular":case"normal":i="400";break;case"light":case"thin":i="200"}return{style:s,weight:t.fWeight||i}}r([Wt],Gt),Gt.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=_t.getProp(t,e.c,0,null,this),this.o=_t.getProp(t,e.o,0,null,this),this.tr=Yt.getTransformProperty(t,e.tr,this),this.so=_t.getProp(t,e.tr.so,0,.01,this),this.eo=_t.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new It,this.rMatrix=new It,this.sMatrix=new It,this.tMatrix=new It,this.matrix=new It},Gt.prototype.applyTransforms=function(t,e,i,s,a,r){var n=r?-1:1,h=s.s.v[0]+(1-s.s.v[0])*(1-a),o=s.s.v[1]+(1-s.s.v[1])*(1-a);t.translate(s.p.v[0]*n*a,s.p.v[1]*n*a,s.p.v[2]),e.translate(-s.a.v[0],-s.a.v[1],s.a.v[2]),e.rotate(-s.r.v*n*a),e.translate(s.a.v[0],s.a.v[1],s.a.v[2]),i.translate(-s.a.v[0],-s.a.v[1],s.a.v[2]),i.scale(r?1/h:h,r?1/o:o),i.translate(s.a.v[0],s.a.v[1],s.a.v[2])},Gt.prototype.init=function(t,e,i,s){for(this.elem=t,this.arr=e,this.pos=i,this.elemsData=s,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[i]);i>0;)i-=1,this._elements.unshift(e[i]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},Gt.prototype.resetElements=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},Gt.prototype.cloneElements=function(t){var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},Gt.prototype.changeGroupRender=function(t,e){var i,s=t.length;for(i=0;i<s;i+=1)t[i]._render=e,"gr"===t[i].ty&&this.changeGroupRender(t[i].it,e)},Gt.prototype.processShapes=function(t){var e,i,s,a,r,n=!1;if(this._mdf||t){var h,o=Math.ceil(this.c.v);if(this._groups.length<o){for(;this._groups.length<o;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(r=0,s=0;s<=this._groups.length-1;s+=1){if(h=r<o,this._groups[s]._render=h,this.changeGroupRender(this._groups[s].it,h),!h){var p=this.elemsData[s].it,f=p[p.length-1];0!==f.transform.op.v?(f.transform.op._mdf=!0,f.transform.op.v=0):f.transform.op._mdf=!1}r+=1}this._currentCopies=o;var m=this.o.v,d=m%1,c=m>0?Math.floor(m):Math.ceil(m),u=this.pMatrix.props,g=this.rMatrix.props,y=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var v,b,_=0;if(m>0){for(;_<c;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),_+=1;d&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,d,!1),_+=d)}else if(m<0){for(;_>c;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),_-=1;d&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-d,!0),_-=d)}for(s=1===this.data.m?0:this._currentCopies-1,a=1===this.data.m?1:-1,r=this._currentCopies;r;){if(b=(i=(e=this.elemsData[s].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(s/(this._currentCopies-1)),0!==_){for((0!==s&&1===a||s!==this._currentCopies-1&&-1===a)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]),v=0;v<b;v+=1)i[v]=this.matrix.props[v];this.matrix.reset()}else for(this.matrix.reset(),v=0;v<b;v+=1)i[v]=this.matrix.props[v];_+=1,r-=1,s+=a}}else for(r=this._currentCopies,s=0,a=1;r;)i=(e=this.elemsData[s].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,r-=1,s+=a;return n},Gt.prototype.addShape=function(){},r([Wt],Kt),Kt.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=_t.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},Kt.prototype.processPath=function(t,e){var i,s=St.newElement();s.c=t.c;var a,r,n,h,o,l,p,f,m,d,c,u,g=t._length,y=0;for(i=0;i<g;i+=1)a=t.v[i],n=t.o[i],r=t.i[i],a[0]===n[0]&&a[1]===n[1]&&a[0]===r[0]&&a[1]===r[1]?0!==i&&i!==g-1||t.c?(h=0===i?t.v[g-1]:t.v[i-1],l=(o=Math.sqrt(Math.pow(a[0]-h[0],2)+Math.pow(a[1]-h[1],2)))?Math.min(o/2,e)/o:0,p=c=a[0]+(h[0]-a[0])*l,f=u=a[1]-(a[1]-h[1])*l,m=p-(p-a[0])*P,d=f-(f-a[1])*P,s.setTripleAt(p,f,m,d,c,u,y),y+=1,h=i===g-1?t.v[0]:t.v[i+1],l=(o=Math.sqrt(Math.pow(a[0]-h[0],2)+Math.pow(a[1]-h[1],2)))?Math.min(o/2,e)/o:0,p=m=a[0]+(h[0]-a[0])*l,f=d=a[1]+(h[1]-a[1])*l,c=p-(p-a[0])*P,u=f-(f-a[1])*P,s.setTripleAt(p,f,m,d,c,u,y),y+=1):(s.setTripleAt(a[0],a[1],n[0],n[1],r[0],r[1],y),y+=1):(s.setTripleAt(t.v[i][0],t.v[i][1],t.o[i][0],t.o[i][1],t.i[i][0],t.i[i][1],y),y+=1);return s},Kt.prototype.processShapes=function(t){var e,i,s,a,r,n,h=this.shapes.length,o=this.rd.v;if(0!==o)for(i=0;i<h;i+=1){if(n=(r=this.shapes[i]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,s=0;s<a;s+=1)n.addShape(this.processPath(e[s],o));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},ee.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},ee.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},ee.prototype.tangentAngle=function(t){var e=this.derivative(t);return Math.atan2(e[1],e[0])},ee.prototype.normalAngle=function(t){var e=this.derivative(t);return Math.atan2(e[0],e[1])},ee.prototype.inflectionPoints=function(){var t=this.a[1]*this.b[0]-this.a[0]*this.b[1];if(Zt(t))return[];var e=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/t,i=e*e-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/t;if(i<0)return[];var s=Math.sqrt(i);return Zt(s)?s>0&&s<1?[e]:[]:[e-s,e+s].filter((function(t){return t>0&&t<1}))},ee.prototype.split=function(t){if(t<=0)return[te(this.points[0]),this];if(t>=1)return[this,te(this.points[this.points.length-1])];var e=Qt(this.points[0],this.points[1],t),i=Qt(this.points[1],this.points[2],t),s=Qt(this.points[2],this.points[3],t),a=Qt(e,i,t),r=Qt(i,s,t),n=Qt(a,r,t);return[new ee(this.points[0],e,a,n,!0),new ee(n,r,s,this.points[3],!0)]},ee.prototype.bounds=function(){return{x:ie(this,0),y:ie(this,1)}},ee.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},ee.prototype.intersections=function(t,e,i){void 0===e&&(e=2),void 0===i&&(i=7);var s=[];return re(se(this,0,1),se(t,0,1),0,e,s,i),s},ee.shapeSegment=function(t,e){var i=(e+1)%t.length();return new ee(t.v[e],t.o[e],t.i[i],t.v[i],!0)},ee.shapeSegmentInverted=function(t,e){var i=(e+1)%t.length();return new ee(t.v[i],t.i[i],t.o[e],t.v[e],!0)},r([Wt],fe),fe.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=_t.getProp(t,e.s,0,null,this),this.frequency=_t.getProp(t,e.r,0,null,this),this.pointsType=_t.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},fe.prototype.processPath=function(t,e,i,s){var a=t._length,r=St.newElement();if(r.c=t.c,t.c||(a-=1),0===a)return r;var n=-1,h=ee.shapeSegment(t,0);ce(r,t,0,e,i,s,n);for(var o=0;o<a;o+=1)n=ue(r,h,e,i,s,-n),h=o!==a-1||t.c?ee.shapeSegment(t,(o+1)%a):null,ce(r,t,o+1,e,i,s,n);return r},fe.prototype.processShapes=function(t){var e,i,s,a,r,n,h=this.shapes.length,o=this.amplitude.v,l=Math.max(0,Math.round(this.frequency.v)),p=this.pointsType.v;if(0!==o)for(i=0;i<h;i+=1){if(n=(r=this.shapes[i]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,s=0;s<a;s+=1)n.addShape(this.processPath(e[s],o,l,p));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},r([Wt],ke),ke.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=_t.getProp(t,e.a,0,null,this),this.miterLimit=_t.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},ke.prototype.processPath=function(t,e,i,s){var a=St.newElement();a.c=t.c;var r,n,h,o=t.length();t.c||(o-=1);var l=[];for(r=0;r<o;r+=1)h=ee.shapeSegment(t,r),l.push(xe(h,e));if(!t.c)for(r=o-1;r>=0;r-=1)h=ee.shapeSegmentInverted(t,r),l.push(xe(h,e));l=function(t){for(var e,i=1;i<t.length;i+=1)e=_e(t[i-1],t[i]),t[i-1]=e[0],t[i]=e[1];return t.length>1&&(e=_e(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}(l);var p=null,f=null;for(r=0;r<l.length;r+=1){var m=l[r];for(f&&(p=ve(a,f,m[0],i,s)),f=m[m.length-1],n=0;n<m.length;n+=1)h=m[n],p&&pe(h.points[0],p)?a.setXYAt(h.points[1][0],h.points[1][1],"o",a.length()-1):a.setTripleAt(h.points[0][0],h.points[0][1],h.points[1][0],h.points[1][1],h.points[0][0],h.points[0][1],a.length()),a.setTripleAt(h.points[3][0],h.points[3][1],h.points[3][0],h.points[3][1],h.points[2][0],h.points[2][1],a.length()),p=h.points[3]}return l.length&&ve(a,f,l[0][0],i,s),a},ke.prototype.processShapes=function(t){var e,i,s,a,r,n,h=this.shapes.length,o=this.amount.v,l=this.miterLimit.v,p=this.lineJoin;if(0!==o)for(i=0;i<h;i+=1){if(n=(r=this.shapes[i]).localShapeCollection,r.shape._mdf||this._mdf||t)for(n.releaseShapes(),r.shape._mdf=!0,e=r.shape.paths.shapes,a=r.shape.paths._length,s=0;s<a;s+=1)n.addShape(this.processPath(e[s],o,p,l));r.shape.paths=r.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var Pe=function(){var t={w:0,size:0,shapes:[],data:{shapes:[]}},e=[];e=e.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);var i=127988,s=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function r(t,e){var i=a("span");i.setAttribute("aria-hidden",!0),i.style.fontFamily=e;var s=a("span");s.innerText="giItT1WQy@!-/#",i.style.position="absolute",i.style.left="-10000px",i.style.top="-10000px",i.style.fontSize="300px",i.style.fontVariant="normal",i.style.fontStyle="normal",i.style.fontWeight="normal",i.style.letterSpacing="0",i.appendChild(s),document.body.appendChild(i);var r=s.offsetWidth;return s.style.fontFamily=function(t){var e,i=t.split(","),s=i.length,a=[];for(e=0;e<s;e+=1)"sans-serif"!==i[e]&&"monospace"!==i[e]&&a.push(i[e]);return a.join(",")}(t)+", "+e,{node:s,w:r,parent:i}}function n(t,e){var i,s=document.body&&e?"svg":"canvas",a=we(t);if("svg"===s){var r=X("text");r.style.fontSize="100px",r.setAttribute("font-family",t.fFamily),r.setAttribute("font-style",a.style),r.setAttribute("font-weight",a.weight),r.textContent="1",t.fClass?(r.style.fontFamily="inherit",r.setAttribute("class",t.fClass)):r.style.fontFamily=t.fFamily,e.appendChild(r),i=r}else{var n=new OffscreenCanvas(500,500).getContext("2d");n.font=a.style+" "+a.weight+" 100px "+t.fFamily,i=n}return{measureText:function(t){return"svg"===s?(i.textContent=t,i.getComputedTextLength()):i.measureText(t).width}}}function h(t){var e=0,i=t.charCodeAt(0);if(i>=55296&&i<=56319){var s=t.charCodeAt(1);s>=56320&&s<=57343&&(e=1024*(i-55296)+s-56320+65536)}return e}function o(t){var e=h(t);return e>=127462&&e<=127487}var l=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)};l.isModifier=function(t,e){var i=t.toString(16)+e.toString(16);return-1!==s.indexOf(i)},l.isZeroWidthJoiner=function(t){return 8205===t},l.isFlagEmoji=function(t){return o(t.substr(0,2))&&o(t.substr(2,2))},l.isRegionalCode=o,l.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},l.isRegionalFlag=function(t,e){var s=h(t.substr(e,2));if(s!==i)return!1;var a=0;for(e+=2;a<5;){if((s=h(t.substr(e,2)))<917601||s>917626)return!1;a+=1,e+=2}return 917631===h(t.substr(e,2))},l.isVariationSelector=function(t){return 65039===t},l.BLACK_FLAG_CODE_POINT=i;var p={addChars:function(t){if(t){var e;this.chars||(this.chars=[]);var i,s,a=t.length,r=this.chars.length;for(e=0;e<a;e+=1){for(i=0,s=!1;i<r;)this.chars[i].style===t[e].style&&this.chars[i].fFamily===t[e].fFamily&&this.chars[i].ch===t[e].ch&&(s=!0),i+=1;s||(this.chars.push(t[e]),r+=1)}}},addFonts:function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);if(!document.body)return this.isLoaded=!0,t.list.forEach((function(t){t.helper=n(t),t.cache={}})),void(this.fonts=t.list);var i,s=t.list,h=s.length,o=h;for(i=0;i<h;i+=1){var l,p,f=!0;if(s[i].loaded=!1,s[i].monoCase=r(s[i].fFamily,"monospace"),s[i].sansCase=r(s[i].fFamily,"sans-serif"),s[i].fPath){if("p"===s[i].fOrigin||3===s[i].origin){if((l=document.querySelectorAll('style[f-forigin="p"][f-family="'+s[i].fFamily+'"], style[f-origin="3"][f-family="'+s[i].fFamily+'"]')).length>0&&(f=!1),f){var m=a("style");m.setAttribute("f-forigin",s[i].fOrigin),m.setAttribute("f-origin",s[i].origin),m.setAttribute("f-family",s[i].fFamily),m.type="text/css",m.innerText="@font-face {font-family: "+s[i].fFamily+"; font-style: normal; src: url('"+s[i].fPath+"');}",e.appendChild(m)}}else if("g"===s[i].fOrigin||1===s[i].origin){for(l=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),p=0;p<l.length;p+=1)-1!==l[p].href.indexOf(s[i].fPath)&&(f=!1);if(f){var d=a("link");d.setAttribute("f-forigin",s[i].fOrigin),d.setAttribute("f-origin",s[i].origin),d.type="text/css",d.rel="stylesheet",d.href=s[i].fPath,document.body.appendChild(d)}}else if("t"===s[i].fOrigin||2===s[i].origin){for(l=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),p=0;p<l.length;p+=1)s[i].fPath===l[p].src&&(f=!1);if(f){var c=a("link");c.setAttribute("f-forigin",s[i].fOrigin),c.setAttribute("f-origin",s[i].origin),c.setAttribute("rel","stylesheet"),c.setAttribute("href",s[i].fPath),e.appendChild(c)}}}else s[i].loaded=!0,o-=1;s[i].helper=n(s[i],e),s[i].cache={},this.fonts.push(s[i])}0===o?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},getCharData:function(e,i,s){for(var a=0,r=this.chars.length;a<r;){if(this.chars[a].ch===e&&this.chars[a].style===i&&this.chars[a].fFamily===s)return this.chars[a];a+=1}return("string"==typeof e&&13!==e.charCodeAt(0)||!e)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",e,i,s)),t},getFontByName:function(t){for(var e=0,i=this.fonts.length;e<i;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,i){var s=this.getFontByName(e),a=t;if(!s.cache[a]){var r=s.helper;if(" "===t){var n=r.measureText("|"+t+"|"),h=r.measureText("||");s.cache[a]=(n-h)/100}else s.cache[a]=r.measureText(t)/100}return s.cache[a]*i},checkLoadedFonts:function(){var t,e,i,s=this.fonts.length,a=s;for(t=0;t<s;t+=1)this.fonts[t].loaded?a-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,i=this.fonts[t].monoCase.w,e.offsetWidth!==i?(a-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,i=this.fonts[t].sansCase.w,e.offsetWidth!==i&&(a-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==a&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}};return l.prototype=p,l}();function Se(t){this.animationData=t}function Ae(){}Se.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},Ae.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var De,Ce=(De={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return De[t]||""});function Ee(t,e,i){this.p=_t.getProp(e,t.v,0,0,i)}function Me(t,e,i){this.p=_t.getProp(e,t.v,0,0,i)}function Te(t,e,i){this.p=_t.getProp(e,t.v,1,0,i)}function Fe(t,e,i){this.p=_t.getProp(e,t.v,1,0,i)}function Ie(t,e,i){this.p=_t.getProp(e,t.v,0,0,i)}function Le(t,e,i){this.p=_t.getProp(e,t.v,0,0,i)}function Be(t,e,i){this.p=_t.getProp(e,t.v,0,0,i)}function ze(){this.p={}}function Ve(t,e){var i,s=t.ef||[];this.effectElements=[];var a,r=s.length;for(i=0;i<r;i+=1)a=new Re(s[i],e),this.effectElements.push(a)}function Re(t,e){this.init(t,e)}function Oe(){}function Ne(){}function qe(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,i)}function je(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,i),this._isPlaying=!1,this._canPlay=!1;var s=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(s),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?_t.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=_t.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function We(){}r([xt],Re),Re.prototype.getValue=Re.prototype.iterateDynamicProperties,Re.prototype.init=function(t,e){var i;this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var s,a=this.data.ef.length,r=this.data.ef;for(i=0;i<a;i+=1){switch(s=null,r[i].ty){case 0:s=new Ee(r[i],e,this);break;case 1:s=new Me(r[i],e,this);break;case 2:s=new Te(r[i],e,this);break;case 3:s=new Fe(r[i],e,this);break;case 4:case 7:s=new Be(r[i],e,this);break;case 10:s=new Ie(r[i],e,this);break;case 11:s=new Le(r[i],e,this);break;case 5:s=new Ve(r[i],e,this);break;default:s=new ze(r[i],e,this)}s&&this.effectElements.push(s)}},Oe.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t=j();if(t){var e=t("layer"),i=t("effects"),s=t("shape"),a=t("text"),r=t("comp");this.layerInterface=e(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var n=i.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(n),0===this.data.ty||this.data.xt?this.compInterface=r(this):4===this.data.ty?(this.layerInterface.shapeInterface=s(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=a(this),this.layerInterface.text=this.layerInterface.textInterface)}},setBlendMode:function(){var t=Ce(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,i){this.globalData=e,this.comp=i,this.data=t,this.layerId=B(),this.data.sr||(this.data.sr=1),this.effectsManager=new Ve(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},Ne.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var i,s=this.dynamicProperties.length;for(i=0;i<s;i+=1)(e||this._isParent&&"transform"===this.dynamicProperties[i].propType)&&(this.dynamicProperties[i].getValue(),this.dynamicProperties[i]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},qe.prototype.prepareFrame=function(){},r([Ae,Oe,Ne],qe),qe.prototype.getBaseElement=function(){return null},qe.prototype.renderFrame=function(){},qe.prototype.destroy=function(){},qe.prototype.initExpressions=function(){var t=j();if(t){var e=t("footage");this.layerInterface=e(this)}},qe.prototype.getFootageData=function(){return this.footageData},je.prototype.prepareFrame=function(t){if(this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder)this._currentTime=t/this.data.sr;else{var e=this.tm.v;this._currentTime=e}this._volume=this.lv.v[0];var i=this._volume*this._volumeMultiplier;this._previousVolume!==i&&(this._previousVolume=i,this.audio.volume(i))},r([Ae,Oe,Ne],je),je.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek())>.1)&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},je.prototype.show=function(){},je.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},je.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},je.prototype.resume=function(){this._canPlay=!0},je.prototype.setRate=function(t){this.audio.rate(t)},je.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},je.prototype.getBaseElement=function(){return null},je.prototype.destroy=function(){},je.prototype.sourceRectAtTime=function(){},je.prototype.initExpressions=function(){},We.prototype.checkLayers=function(t){var e,i,s=this.layers.length;for(this.completeLayers=!0,e=s-1;e>=0;e-=1)this.elements[e]||(i=this.layers[e]).ip-i.st<=t-this.layers[e].st&&i.op-i.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},We.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:default:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t)}},We.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},We.prototype.createAudio=function(t){return new je(t,this.globalData,this)},We.prototype.createFootage=function(t){return new qe(t,this.globalData,this)},We.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},We.prototype.includeLayers=function(t){var e;this.completeLayers=!1;var i,s=t.length,a=this.layers.length;for(e=0;e<s;e+=1)for(i=0;i<a;){if(this.layers[i].id===t[e].id){this.layers[i]=t[e];break}i+=1}},We.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},We.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},We.prototype.buildElementParenting=function(t,e,i){for(var s=this.elements,a=this.layers,r=0,n=a.length;r<n;)a[r].ind==e&&(s[r]&&!0!==s[r]?(i.push(s[r]),s[r].setAsParent(),void 0!==a[r].parent?this.buildElementParenting(t,a[r].parent,i):t.setHierarchy(i)):(this.buildItem(r),this.addPendingElement(t))),r+=1},We.prototype.addPendingElement=function(t){this.pendingElements.push(t)},We.prototype.searchExtraCompositions=function(t){var e,i=t.length;for(e=0;e<i;e+=1)if(t[e].xt){var s=this.createComp(t[e]);s.initExpressions(),this.globalData.projectInterface.registerComposition(s)}},We.prototype.getElementById=function(t){var e,i=this.elements.length;for(e=0;e<i;e+=1)if(this.elements[e].data.ind===t)return this.elements[e];return null},We.prototype.getElementByPath=function(t){var e,i=t.shift();if("number"==typeof i)e=this.elements[i];else{var s,a=this.elements.length;for(s=0;s<a;s+=1)if(this.elements[s].data.nm===i){e=this.elements[s];break}}return 0===t.length?e:e.getElementByPath(t)},We.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new Pe,this.globalData.slotManager=function(t){return new Se(t)}(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var He="transformEFfect";function Xe(){}function Ye(t,e,i){this.data=t,this.element=e,this.globalData=i,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var a,r,n=this.globalData.defs,h=this.masksProperties?this.masksProperties.length:0;this.viewData=l(h),this.solidPath="";var o,p,f,m,d,c,u=this.masksProperties,g=0,y=[],v=B(),b="clipPath",_="clip-path";for(a=0;a<h;a+=1)if(("a"!==u[a].mode&&"n"!==u[a].mode||u[a].inv||100!==u[a].o.k||u[a].o.x)&&(b="mask",_="mask"),"s"!==u[a].mode&&"i"!==u[a].mode||0!==g?f=null:((f=X("rect")).setAttribute("fill","#ffffff"),f.setAttribute("width",this.element.comp.data.w||0),f.setAttribute("height",this.element.comp.data.h||0),y.push(f)),r=X("path"),"n"===u[a].mode)this.viewData[a]={op:_t.getProp(this.element,u[a].o,0,.01,this.element),prop:Ft.getShapeProp(this.element,u[a],3),elem:r,lastPath:""},n.appendChild(r);else{var x;if(g+=1,r.setAttribute("fill","s"===u[a].mode?"#000000":"#ffffff"),r.setAttribute("clip-rule","nonzero"),0!==u[a].x.k?(b="mask",_="mask",c=_t.getProp(this.element,u[a].x,0,null,this.element),x=B(),(m=X("filter")).setAttribute("id",x),(d=X("feMorphology")).setAttribute("operator","erode"),d.setAttribute("in","SourceGraphic"),d.setAttribute("radius","0"),m.appendChild(d),n.appendChild(m),r.setAttribute("stroke","s"===u[a].mode?"#000000":"#ffffff")):(d=null,c=null),this.storedData[a]={elem:r,x:c,expan:d,lastPath:"",lastOperator:"",filterId:x,lastRadius:0},"i"===u[a].mode){p=y.length;var k=X("g");for(o=0;o<p;o+=1)k.appendChild(y[o]);var w=X("mask");w.setAttribute("mask-type","alpha"),w.setAttribute("id",v+"_"+g),w.appendChild(r),n.appendChild(w),k.setAttribute("mask","url("+s()+"#"+v+"_"+g+")"),y.length=0,y.push(k)}else y.push(r);u[a].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[a]={elem:r,lastPath:"",op:_t.getProp(this.element,u[a].o,0,.01,this.element),prop:Ft.getShapeProp(this.element,u[a],3),invRect:f},this.viewData[a].prop.k||this.drawPath(u[a],this.viewData[a].prop.v,this.viewData[a])}for(this.maskElement=X(b),h=y.length,a=0;a<h;a+=1)this.maskElement.appendChild(y[a]);g>0&&(this.maskElement.setAttribute("id",v),this.element.maskedElement.setAttribute(_,"url("+s()+"#"+v+")"),n.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}Xe.prototype={initTransform:function(){var t=new It;this.finalTransform={mProp:this.data.ks?Yt.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,i=0,s=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;i<s;){if(this.hierarchy[i].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}i+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),i=0;i<s;i+=1)e.multiply(this.hierarchy[i].finalTransform.mProp.v)}this.localTransforms&&!this.finalTransform._matMdf||(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var i=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(i),t=1;t<e;t+=1){var s=this.localTransforms[t].matrix;i.multiply(s)}i.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){var a=this.finalTransform.localOpacity;for(t=0;t<e;t+=1)a*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=a}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(He);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new It;var e=0,i=t.length;for(e=0;e<i;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var i,s=!0,a=this.comp;s;)a.finalTransform?(a.data.hasMask&&e.splice(0,0,a.finalTransform),a=a.comp):s=!1;var r,n=e.length;for(i=0;i<n;i+=1)r=e[i].mat.applyToPointArray(0,0,0),t=[t[0]-r[0],t[1]-r[1],0];return t},mHelper:new It},Ye.prototype.getMaskProperty=function(t){return this.viewData[t].prop},Ye.prototype.renderFrame=function(t){var e,i=this.element.finalTransform.mat,a=this.masksProperties.length;for(e=0;e<a;e+=1)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[e].invRect.setAttribute("transform",i.getInverseMatrix().to2dCSS()),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var r=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+s()+"#"+this.storedData[e].filterId+")")),r.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},Ye.prototype.getMaskelement=function(){return this.maskElement},Ye.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},Ye.prototype.drawPath=function(t,e,i){var s,a,r=" M"+e.v[0][0]+","+e.v[0][1];for(a=e._length,s=1;s<a;s+=1)r+=" C"+e.o[s-1][0]+","+e.o[s-1][1]+" "+e.i[s][0]+","+e.i[s][1]+" "+e.v[s][0]+","+e.v[s][1];if(e.c&&a>1&&(r+=" C"+e.o[s-1][0]+","+e.o[s-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),i.lastPath!==r){var n="";i.elem&&(e.c&&(n=t.inv?this.solidPath+r:r),i.elem.setAttribute("d",n)),i.lastPath=r}},Ye.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var Ge=function(){var t={};return t.createFilter=function(t,e){var i=X("filter");i.setAttribute("id",t),!0!==e&&(i.setAttribute("filterUnits","objectBoundingBox"),i.setAttribute("x","0%"),i.setAttribute("y","0%"),i.setAttribute("width","100%"),i.setAttribute("height","100%"));return i},t.createAlphaToLuminanceFilter=function(){var t=X("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},t}(),Ke=function(){var t={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),/firefox/i.test(navigator.userAgent)&&(t.svgLumaHidden=!1),t}(),Je={},Ze="filter_result_";function Ue(t){var e,i,a="SourceGraphic",r=t.data.ef?t.data.ef.length:0,n=B(),h=Ge.createFilter(n,!0),o=0;for(this.filters=[],e=0;e<r;e+=1){i=null;var l=t.data.ef[e].ty;if(Je[l])i=new(0,Je[l].effect)(h,t.effectsManager.effectElements[e],t,Ze+o,a),a=Ze+o,Je[l].countsAsEffect&&(o+=1);i&&this.filters.push(i)}o&&(t.globalData.defs.appendChild(h),t.layerElement.setAttribute("filter","url("+s()+"#"+n+")")),this.filters.length&&t.addRenderableComponent(this)}function Qe(){}function $e(){}function ti(){}function ei(t,e,i){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,i),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ii(t,e){this.elem=t,this.pos=e}function si(){}Ue.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},Ue.prototype.getEffects=function(t){var e,i=this.filters.length,s=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&s.push(this.filters[e]);return s},Qe.prototype={initRendererElement:function(){this.layerElement=X("g")},createContainerElements:function(){this.matteElement=X("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t=null;if(this.data.td){this.matteMasks={};var e=X("g");e.setAttribute("id",this.layerId),e.appendChild(this.layerElement),t=e,this.globalData.defs.appendChild(e)}else this.data.tt?(this.matteElement.appendChild(this.layerElement),t=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var i=X("clipPath"),a=X("path");a.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var r=B();if(i.setAttribute("id",r),i.appendChild(a),this.globalData.defs.appendChild(i),this.checkMasks()){var n=X("g");n.setAttribute("clip-path","url("+s()+"#"+r+")"),n.appendChild(this.layerElement),this.transformedElement=n,t?t.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+s()+"#"+r+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new Ye(this.data,this,this.globalData),this.renderableEffectsManager=new Ue(this),this.searchEffectTransforms()},getMatte:function(t){if(this.matteMasks||(this.matteMasks={}),!this.matteMasks[t]){var e,i,a,r,n=this.layerId+"_"+t;if(1===t||3===t){var h=X("mask");h.setAttribute("id",n),h.setAttribute("mask-type",3===t?"luminance":"alpha"),(a=X("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),h.appendChild(a),this.globalData.defs.appendChild(h),Ke.maskType||1!==t||(h.setAttribute("mask-type","luminance"),e=B(),i=Ge.createFilter(e),this.globalData.defs.appendChild(i),i.appendChild(Ge.createAlphaToLuminanceFilter()),(r=X("g")).appendChild(a),h.appendChild(r),r.setAttribute("filter","url("+s()+"#"+e+")"))}else if(2===t){var o=X("mask");o.setAttribute("id",n),o.setAttribute("mask-type","alpha");var l=X("g");o.appendChild(l),e=B(),i=Ge.createFilter(e);var p=X("feComponentTransfer");p.setAttribute("in","SourceGraphic"),i.appendChild(p);var f=X("feFuncA");f.setAttribute("type","table"),f.setAttribute("tableValues","1.0 0.0"),p.appendChild(f),this.globalData.defs.appendChild(i);var m=X("rect");m.setAttribute("width",this.comp.data.w),m.setAttribute("height",this.comp.data.h),m.setAttribute("x","0"),m.setAttribute("y","0"),m.setAttribute("fill","#ffffff"),m.setAttribute("opacity","0"),l.setAttribute("filter","url("+s()+"#"+e+")"),l.appendChild(m),(a=X("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),l.appendChild(a),Ke.maskType||(o.setAttribute("mask-type","luminance"),i.appendChild(Ge.createAlphaToLuminanceFilter()),r=X("g"),l.appendChild(m),r.appendChild(this.layerElement),l.appendChild(r)),this.globalData.defs.appendChild(o)}this.matteMasks[t]=n}return this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+s()+"#"+t+")")}},$e.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},r([Ae,n({initElement:function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],ti),r([Oe,Xe,Qe,$e,Ne,ti],ei),ei.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=X("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},ei.prototype.sourceRectAtTime=function(){return this.sourceRect},si.prototype={addShapeToModifiers:function(t){var e,i=this.shapeModifiers.length;for(e=0;e<i;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;t>=0&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,i=0,s=e.length;i<s;){if(e[i].elem===t)return e[i].pos;i+=1}return 0},addProcessedElement:function(t,e){for(var i=this.processedElements,s=i.length;s;)if(i[s-=1].elem===t)return void(i[s].pos=e);i.push(new ii(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var ai={1:"butt",2:"round",3:"square"},ri={1:"miter",2:"round",3:"bevel"};function ni(t,e,i){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=i,this.lvl=e,this._isAnimated=!!i.k;for(var s=0,a=t.length;s<a;){if(t[s].mProps.dynamicProperties.length){this._isAnimated=!0;break}s+=1}}function hi(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=X("path"),this.msElem=null}function oi(t,e,i,s){var a;this.elem=t,this.frameId=-1,this.dataProps=l(e.length),this.renderer=i,this.k=!1,this.dashStr="",this.dashArray=o("float32",e.length?e.length-1:0),this.dashoffset=o("float32",1),this.initDynamicPropertyContainer(s);var r,n=e.length||0;for(a=0;a<n;a+=1)r=_t.getProp(t,e[a].v,0,0,this),this.k=r.k||this.k,this.dataProps[a]={n:e[a].n,p:r};this.k||this.getValue(!0),this._isAnimated=this.k}function li(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=_t.getProp(t,e.o,0,.01,this),this.w=_t.getProp(t,e.w,0,null,this),this.d=new oi(t,e.d||{},"svg",this),this.c=_t.getProp(t,e.c,1,255,this),this.style=i,this._isAnimated=!!this._isAnimated}function pi(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=_t.getProp(t,e.o,0,.01,this),this.c=_t.getProp(t,e.c,1,255,this),this.style=i}function fi(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=i}function mi(t,e,i){this.data=e,this.c=o("uint8c",4*e.p);var s=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=o("float32",s),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=s,this.initDynamicPropertyContainer(i),this.prop=_t.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function di(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,i)}function ci(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=_t.getProp(t,e.w,0,null,this),this.d=new oi(t,e.d||{},"svg",this),this.initGradientData(t,e,i),this._isAnimated=!!this._isAnimated}function ui(){this.it=[],this.prevViewData=[],this.gr=X("g")}function gi(t,e,i){this.transform={mProps:t,op:e,container:i},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}ni.prototype.setAsAnimated=function(){this._isAnimated=!0},hi.prototype.reset=function(){this.d="",this._mdf=!1},oi.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,i=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<i;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},r([xt],oi),r([xt],li),r([xt],pi),r([xt],fi),mi.prototype.comparePoints=function(t,e){for(var i=0,s=this.o.length/2;i<s;){if(Math.abs(t[4*i]-t[4*e+2*i])>.01)return!1;i+=1}return!0},mi.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},mi.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,i,s,a=4*this.data.p;for(e=0;e<a;e+=1)i=e%4==0?100:255,s=Math.round(this.prop.v[e]*i),this.c[e]!==s&&(this.c[e]=s,this._cmdf=!t);if(this.o.length)for(a=this.prop.v.length,e=4*this.data.p;e<a;e+=1)i=e%2==0?100:1,s=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==s&&(this.o[e-4*this.data.p]=s,this._omdf=!t);this._mdf=!t}},r([xt],mi),di.prototype.initGradientData=function(t,e,i){this.o=_t.getProp(t,e.o,0,.01,this),this.s=_t.getProp(t,e.s,1,null,this),this.e=_t.getProp(t,e.e,1,null,this),this.h=_t.getProp(t,e.h||{k:0},0,.01,this),this.a=_t.getProp(t,e.a||{k:0},0,w,this),this.g=new mi(t,e.g,this),this.style=i,this.stops=[],this.setGradientData(i.pElem,e),this.setGradientOpacity(e,i),this._isAnimated=!!this._isAnimated},di.prototype.setGradientData=function(t,e){var i=B(),a=X(1===e.t?"linearGradient":"radialGradient");a.setAttribute("id",i),a.setAttribute("spreadMethod","pad"),a.setAttribute("gradientUnits","userSpaceOnUse");var r,n,h,o=[];for(h=4*e.g.p,n=0;n<h;n+=4)r=X("stop"),a.appendChild(r),o.push(r);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+s()+"#"+i+")"),this.gf=a,this.cst=o},di.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){var i,a,r,n=X("mask"),h=X("path");n.appendChild(h);var o=B(),l=B();n.setAttribute("id",l);var p=X(1===t.t?"linearGradient":"radialGradient");p.setAttribute("id",o),p.setAttribute("spreadMethod","pad"),p.setAttribute("gradientUnits","userSpaceOnUse"),r=t.g.k.k[0].s?t.g.k.k[0].s.length:t.g.k.k.length;var f=this.stops;for(a=4*t.g.p;a<r;a+=2)(i=X("stop")).setAttribute("stop-color","rgb(255,255,255)"),p.appendChild(i),f.push(i);h.setAttribute("gf"===t.ty?"fill":"stroke","url("+s()+"#"+o+")"),"gs"===t.ty&&(h.setAttribute("stroke-linecap",ai[t.lc||2]),h.setAttribute("stroke-linejoin",ri[t.lj||2]),1===t.lj&&h.setAttribute("stroke-miterlimit",t.ml)),this.of=p,this.ms=n,this.ost=f,this.maskId=l,e.msElem=h}},r([xt],di),r([di,xt],ci);var yi=function(t,e,i,s){if(0===e)return"";var a,r=t.o,n=t.i,h=t.v,o=" M"+s.applyToPointStringified(h[0][0],h[0][1]);for(a=1;a<e;a+=1)o+=" C"+s.applyToPointStringified(r[a-1][0],r[a-1][1])+" "+s.applyToPointStringified(n[a][0],n[a][1])+" "+s.applyToPointStringified(h[a][0],h[a][1]);return i&&e&&(o+=" C"+s.applyToPointStringified(r[a-1][0],r[a-1][1])+" "+s.applyToPointStringified(n[0][0],n[0][1])+" "+s.applyToPointStringified(h[0][0],h[0][1]),o+="z"),o},vi=function(){var t=new It,e=new It;function i(t,e,i){(i||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(i||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function s(){}function a(i,s,a){var r,n,h,o,l,p,f,m,d,c,u=s.styles.length,g=s.lvl;for(p=0;p<u;p+=1){if(o=s.sh._mdf||a,s.styles[p].lvl<g){for(m=e.reset(),d=g-s.styles[p].lvl,c=s.transformers.length-1;!o&&d>0;)o=s.transformers[c].mProps._mdf||o,d-=1,c-=1;if(o)for(d=g-s.styles[p].lvl,c=s.transformers.length-1;d>0;)m.multiply(s.transformers[c].mProps.v),d-=1,c-=1}else m=t;if(n=(f=s.sh.paths)._length,o){for(h="",r=0;r<n;r+=1)(l=f.shapes[r])&&l._length&&(h+=yi(l,l._length,l.c,m));s.caches[p]=h}else h=s.caches[p];s.styles[p].d+=!0===i.hd?"":h,s.styles[p]._mdf=o||s.styles[p]._mdf}}function r(t,e,i){var s=e.style;(e.c._mdf||i)&&s.pElem.setAttribute("fill","rgb("+v(e.c.v[0])+","+v(e.c.v[1])+","+v(e.c.v[2])+")"),(e.o._mdf||i)&&s.pElem.setAttribute("fill-opacity",e.o.v)}function n(t,e,i){h(t,e,i),o(t,e,i)}function h(t,e,i){var s,a,r,n,h,o=e.gf,l=e.g._hasOpacity,p=e.s.v,f=e.e.v;if(e.o._mdf||i){var m="gf"===t.ty?"fill-opacity":"stroke-opacity";e.style.pElem.setAttribute(m,e.o.v)}if(e.s._mdf||i){var d=1===t.t?"x1":"cx",c="x1"===d?"y1":"cy";o.setAttribute(d,p[0]),o.setAttribute(c,p[1]),l&&!e.g._collapsable&&(e.of.setAttribute(d,p[0]),e.of.setAttribute(c,p[1]))}if(e.g._cmdf||i){s=e.cst;var u=e.g.c;for(r=s.length,a=0;a<r;a+=1)(n=s[a]).setAttribute("offset",u[4*a]+"%"),n.setAttribute("stop-color","rgb("+u[4*a+1]+","+u[4*a+2]+","+u[4*a+3]+")")}if(l&&(e.g._omdf||i)){var g=e.g.o;for(r=(s=e.g._collapsable?e.cst:e.ost).length,a=0;a<r;a+=1)n=s[a],e.g._collapsable||n.setAttribute("offset",g[2*a]+"%"),n.setAttribute("stop-opacity",g[2*a+1])}if(1===t.t)(e.e._mdf||i)&&(o.setAttribute("x2",f[0]),o.setAttribute("y2",f[1]),l&&!e.g._collapsable&&(e.of.setAttribute("x2",f[0]),e.of.setAttribute("y2",f[1])));else if((e.s._mdf||e.e._mdf||i)&&(h=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)),o.setAttribute("r",h),l&&!e.g._collapsable&&e.of.setAttribute("r",h)),e.s._mdf||e.e._mdf||e.h._mdf||e.a._mdf||i){h||(h=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)));var y=Math.atan2(f[1]-p[1],f[0]-p[0]),v=e.h.v;v>=1?v=.99:v<=-1&&(v=-.99);var b=h*v,_=Math.cos(y+e.a.v)*b+p[0],x=Math.sin(y+e.a.v)*b+p[1];o.setAttribute("fx",_),o.setAttribute("fy",x),l&&!e.g._collapsable&&(e.of.setAttribute("fx",_),e.of.setAttribute("fy",x))}}function o(t,e,i){var s=e.style,a=e.d;a&&(a._mdf||i)&&a.dashStr&&(s.pElem.setAttribute("stroke-dasharray",a.dashStr),s.pElem.setAttribute("stroke-dashoffset",a.dashoffset[0])),e.c&&(e.c._mdf||i)&&s.pElem.setAttribute("stroke","rgb("+v(e.c.v[0])+","+v(e.c.v[1])+","+v(e.c.v[2])+")"),(e.o._mdf||i)&&s.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||i)&&(s.pElem.setAttribute("stroke-width",e.w.v),s.msElem&&s.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function(t){switch(t.ty){case"fl":return r;case"gf":return h;case"gs":return n;case"st":return o;case"sh":case"el":case"rc":case"sr":return a;case"tr":return i;case"no":return s;default:return null}}}}();function bi(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,i),this.prevViewData=[]}function _i(t,e,i,s,a,r){this.o=t,this.sw=e,this.sc=i,this.fc=s,this.m=a,this.p=r,this._mdf={o:!0,sw:!!e,sc:!!i,fc:!!s,m:!0,p:!0}}function xi(t,e){this._frameId=i,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}r([Oe,Xe,Qe,si,$e,Ne,ti],bi),bi.prototype.initSecondaryElement=function(){},bi.prototype.identityMatrix=new It,bi.prototype.buildExpressionInterface=function(){},bi.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},bi.prototype.filterUniqueShapes=function(){var t,e,i,s,a=this.shapes.length,r=this.stylesList.length,n=[],h=!1;for(i=0;i<r;i+=1){for(s=this.stylesList[i],h=!1,n.length=0,t=0;t<a;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(s)&&(n.push(e),h=e._isAnimated||h);n.length>1&&h&&this.setShapesAsAnimated(n)}},bi.prototype.setShapesAsAnimated=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].setAsAnimated()},bi.prototype.createStyleElement=function(t,e){var i,a=new hi(t,e),r=a.pElem;if("st"===t.ty)i=new li(this,t,a);else if("fl"===t.ty)i=new pi(this,t,a);else if("gf"===t.ty||"gs"===t.ty){i=new("gf"===t.ty?di:ci)(this,t,a),this.globalData.defs.appendChild(i.gf),i.maskId&&(this.globalData.defs.appendChild(i.ms),this.globalData.defs.appendChild(i.of),r.setAttribute("mask","url("+s()+"#"+i.maskId+")"))}else"no"===t.ty&&(i=new fi(this,t,a));return"st"!==t.ty&&"gs"!==t.ty||(r.setAttribute("stroke-linecap",ai[t.lc||2]),r.setAttribute("stroke-linejoin",ri[t.lj||2]),r.setAttribute("fill-opacity","0"),1===t.lj&&r.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&r.setAttribute("fill-rule","evenodd"),t.ln&&r.setAttribute("id",t.ln),t.cl&&r.setAttribute("class",t.cl),t.bm&&(r.style["mix-blend-mode"]=Ce(t.bm)),this.stylesList.push(a),this.addToAnimatedContents(t,i),i},bi.prototype.createGroupElement=function(t){var e=new ui;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=Ce(t.bm)),e},bi.prototype.createTransformElement=function(t,e){var i=Yt.getTransformProperty(this,t,this),s=new gi(i,i.o,e);return this.addToAnimatedContents(t,s),s},bi.prototype.createShapeElement=function(t,e,i){var s=4;"rc"===t.ty?s=5:"el"===t.ty?s=6:"sr"===t.ty&&(s=7);var a=new ni(e,i,Ft.getShapeProp(this,t,s,this));return this.shapes.push(a),this.addShapeToModifiers(a),this.addToAnimatedContents(t,a),a},bi.prototype.addToAnimatedContents=function(t,e){for(var i=0,s=this.animatedContents.length;i<s;){if(this.animatedContents[i].element===e)return;i+=1}this.animatedContents.push({fn:vi.createRenderFunction(t),element:e,data:t})},bi.prototype.setElementStyles=function(t){var e,i=t.styles,s=this.stylesList.length;for(e=0;e<s;e+=1)-1!==i.indexOf(this.stylesList[e])||this.stylesList[e].closed||i.push(this.stylesList[e])},bi.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},bi.prototype.searchShapes=function(t,e,i,s,a,r,n){var h,o,l,p,f,m,d=[].concat(r),c=t.length-1,u=[],g=[];for(h=c;h>=0;h-=1){if((m=this.searchProcessedElement(t[h]))?e[h]=i[m-1]:t[h]._render=n,"fl"===t[h].ty||"st"===t[h].ty||"gf"===t[h].ty||"gs"===t[h].ty||"no"===t[h].ty)m?e[h].style.closed=t[h].hd:e[h]=this.createStyleElement(t[h],a),t[h]._render&&e[h].style.pElem.parentNode!==s&&s.appendChild(e[h].style.pElem),u.push(e[h].style);else if("gr"===t[h].ty){if(m)for(l=e[h].it.length,o=0;o<l;o+=1)e[h].prevViewData[o]=e[h].it[o];else e[h]=this.createGroupElement(t[h]);this.searchShapes(t[h].it,e[h].it,e[h].prevViewData,e[h].gr,a+1,d,n),t[h]._render&&e[h].gr.parentNode!==s&&s.appendChild(e[h].gr)}else"tr"===t[h].ty?(m||(e[h]=this.createTransformElement(t[h],s)),p=e[h].transform,d.push(p)):"sh"===t[h].ty||"rc"===t[h].ty||"el"===t[h].ty||"sr"===t[h].ty?(m||(e[h]=this.createShapeElement(t[h],d,a)),this.setElementStyles(e[h])):"tm"===t[h].ty||"rd"===t[h].ty||"ms"===t[h].ty||"pb"===t[h].ty||"zz"===t[h].ty||"op"===t[h].ty?(m?(f=e[h]).closed=!1:((f=jt.getModifier(t[h].ty)).init(this,t[h]),e[h]=f,this.shapeModifiers.push(f)),g.push(f)):"rp"===t[h].ty&&(m?(f=e[h]).closed=!0:(f=jt.getModifier(t[h].ty),e[h]=f,f.init(this,t,h,e),this.shapeModifiers.push(f),n=!1),g.push(f));this.addProcessedElement(t[h],h+1)}for(c=u.length,h=0;h<c;h+=1)u[h].closed=!0;for(c=g.length,h=0;h<c;h+=1)g[h].closed=!0},bi.prototype.renderInnerContent=function(){var t;this.renderModifiers();var e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},bi.prototype.renderShape=function(){var t,e,i=this.animatedContents.length;for(t=0;t<i;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},bi.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},_i.prototype.update=function(t,e,i,s,a,r){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1,this._mdf.p=!1;var n=!1;return this.o!==t&&(this.o=t,this._mdf.o=!0,n=!0),this.sw!==e&&(this.sw=e,this._mdf.sw=!0,n=!0),this.sc!==i&&(this.sc=i,this._mdf.sc=!0,n=!0),this.fc!==s&&(this.fc=s,this._mdf.fc=!0,n=!0),this.m!==a&&(this.m=a,this._mdf.m=!0,n=!0),!r.length||this.p[0]===r[0]&&this.p[1]===r[1]&&this.p[4]===r[4]&&this.p[5]===r[5]&&this.p[12]===r[12]&&this.p[13]===r[13]||(this.p=r,this._mdf.p=!0,n=!0),n},xi.prototype.defaultBoxWidth=[0,0],xi.prototype.copyData=function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},xi.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},xi.prototype.searchProperty=function(){return this.searchKeyframes()},xi.prototype.searchKeyframes=function(){return this.kf=this.data.d.k.length>1,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},xi.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},xi.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,i=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{var s;this.lock=!0,this._mdf=!1;var a=this.effectsSequence.length,r=t||this.data.d.k[this.keysIndex].s;for(s=0;s<a;s+=1)r=i!==this.keysIndex?this.effectsSequence[s](r,r.t):this.effectsSequence[s](this.currentData,r.t);e!==r&&this.setCurrentData(r),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},xi.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,i=0,s=t.length;i<=s-1&&!(i===s-1||t[i+1].t>e);)i+=1;return this.keysIndex!==i&&(this.keysIndex=i),this.data.d.k[this.keysIndex].s},xi.prototype.buildFinalText=function(t){for(var e,i,s=[],a=0,r=t.length,n=!1,h=!1,o="";a<r;)n=h,h=!1,e=t.charCodeAt(a),o=t.charAt(a),Pe.isCombinedCharacter(e)?n=!0:e>=55296&&e<=56319?Pe.isRegionalFlag(t,a)?o=t.substr(a,14):(i=t.charCodeAt(a+1))>=56320&&i<=57343&&(Pe.isModifier(e,i)?(o=t.substr(a,2),n=!0):o=Pe.isFlagEmoji(t.substr(a,4))?t.substr(a,4):t.substr(a,2)):e>56319?(i=t.charCodeAt(a+1),Pe.isVariationSelector(e)&&(n=!0)):Pe.isZeroWidthJoiner(e)&&(n=!0,h=!0),n?(s[s.length-1]+=o,n=!1):s.push(o),a+=o.length;return s},xi.prototype.completeTextData=function(t){t.__complete=!0;var e,i,s,a,r,n,h,o=this.elem.globalData.fontManager,l=this.data,p=[],f=0,m=l.m.g,d=0,c=0,u=0,g=[],y=0,v=0,b=o.getFontByName(t.f),_=0,x=we(b);t.fWeight=x.weight,t.fStyle=x.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),i=t.finalText.length,t.finalLineHeight=t.lh;var k,w=t.tr/1e3*t.finalSize;if(t.sz)for(var P,S,A=!0,D=t.sz[0],C=t.sz[1];A;){P=0,y=0,i=(S=this.buildFinalText(t.t)).length,w=t.tr/1e3*t.finalSize;var E=-1;for(e=0;e<i;e+=1)k=S[e].charCodeAt(0),s=!1," "===S[e]?E=e:13!==k&&3!==k||(y=0,s=!0,P+=t.finalLineHeight||1.2*t.finalSize),o.chars?(h=o.getCharData(S[e],b.fStyle,b.fFamily),_=s?0:h.w*t.finalSize/100):_=o.measureText(S[e],t.f,t.finalSize),y+_>D&&" "!==S[e]?(-1===E?i+=1:e=E,P+=t.finalLineHeight||1.2*t.finalSize,S.splice(e,E===e?1:0,"\r"),E=-1,y=0):(y+=_,y+=w);P+=b.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&C<P?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=S,i=t.finalText.length,A=!1)}y=-w,_=0;var M,T=0;for(e=0;e<i;e+=1)if(s=!1,13===(k=(M=t.finalText[e]).charCodeAt(0))||3===k?(T=0,g.push(y),v=y>v?y:v,y=-2*w,a="",s=!0,u+=1):a=M,o.chars?(h=o.getCharData(M,b.fStyle,o.getFontByName(t.f).fFamily),_=s?0:h.w*t.finalSize/100):_=o.measureText(a,t.f,t.finalSize)," "===M?T+=_+w:(y+=_+w+T,T=0),p.push({l:_,an:_,add:d,n:s,anIndexes:[],val:a,line:u,animatorJustifyOffset:0}),2==m){if(d+=_,""===a||" "===a||e===i-1){for(""!==a&&" "!==a||(d-=_);c<=e;)p[c].an=d,p[c].ind=f,p[c].extra=_,c+=1;f+=1,d=0}}else if(3==m){if(d+=_,""===a||e===i-1){for(""===a&&(d-=_);c<=e;)p[c].an=d,p[c].ind=f,p[c].extra=_,c+=1;d=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=y>v?y:v,g.push(y),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=g;var F,I,L,B,z=l.a;n=z.length;var V=[];for(r=0;r<n;r+=1){for((F=z[r]).a.sc&&(t.strokeColorAnim=!0),F.a.sw&&(t.strokeWidthAnim=!0),(F.a.fc||F.a.fh||F.a.fs||F.a.fb)&&(t.fillColorAnim=!0),B=0,L=F.s.b,e=0;e<i;e+=1)(I=p[e]).anIndexes[r]=B,(1==L&&""!==I.val||2==L&&""!==I.val&&" "!==I.val||3==L&&(I.n||" "==I.val||e==i-1)||4==L&&(I.n||e==i-1))&&(1===F.s.rn&&V.push(B),B+=1);l.a[r].s.totalChars=B;var R,O=-1;if(1===F.s.rn)for(e=0;e<i;e+=1)O!=(I=p[e]).anIndexes[r]&&(O=I.anIndexes[r],R=V.splice(Math.floor(Math.random()*V.length),1)[0]),I.anIndexes[r]=R}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=b.ascent*t.finalSize/100},xi.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var i=this.copyData({},this.data.d.k[e].s);i=this.copyData(i,t),this.data.d.k[e].s=i,this.recalculate(e),this.setCurrentData(i),this.elem.addDynamicProperty(this)},xi.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},xi.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},xi.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var ki=function(){var t=Math.max,e=Math.min,i=Math.floor;function s(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=_t.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?_t.getProp(t,e.e,0,0,this):{v:100},this.o=_t.getProp(t,e.o||{k:0},0,0,this),this.xe=_t.getProp(t,e.xe||{k:0},0,0,this),this.ne=_t.getProp(t,e.ne||{k:0},0,0,this),this.sm=_t.getProp(t,e.sm||{k:100},0,0,this),this.a=_t.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return s.prototype={getMult:function(s){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var a=0,r=0,n=1,h=1;this.ne.v>0?a=this.ne.v/100:r=-this.ne.v/100,this.xe.v>0?n=1-this.xe.v/100:h=1+this.xe.v/100;var o=it.getBezierEasing(a,r,n,h).get,l=0,p=this.finalS,f=this.finalE,m=this.data.sh;if(2===m)l=o(l=f===p?s>=f?1:0:t(0,e(.5/(f-p)+(s-p)/(f-p),1)));else if(3===m)l=o(l=f===p?s>=f?0:1:1-t(0,e(.5/(f-p)+(s-p)/(f-p),1)));else if(4===m)f===p?l=0:(l=t(0,e(.5/(f-p)+(s-p)/(f-p),1)))<.5?l*=2:l=1-2*(l-.5),l=o(l);else if(5===m){if(f===p)l=0;else{var d=f-p,c=-d/2+(s=e(t(0,s+.5-p),f-p)),u=d/2;l=Math.sqrt(1-c*c/(u*u))}l=o(l)}else 6===m?(f===p?l=0:(s=e(t(0,s+.5-p),f-p),l=(1+Math.cos(Math.PI+2*Math.PI*s/(f-p)))/2),l=o(l)):(s>=i(p)&&(l=t(0,e(s-p<0?e(f,1)-(p-s):f-s,1))),l=o(l));if(100!==this.sm.v){var g=.01*this.sm.v;0===g&&(g=1e-8);var y=.5-.5*g;l<y?l=0:(l=(l-y)/g)>1&&(l=1)}return l*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,i=this.o.v/e,s=this.s.v/e+i,a=this.e.v/e+i;if(s>a){var r=s;s=a,a=r}this.finalS=s,this.finalE=a}},r([xt],s),{getTextSelectorProp:function(t,e,i){return new s(t,e,i)}}}();function wi(t,e,i){var s={propType:!1},a=_t.getProp,r=e.a;this.a={r:r.r?a(t,r.r,0,w,i):s,rx:r.rx?a(t,r.rx,0,w,i):s,ry:r.ry?a(t,r.ry,0,w,i):s,sk:r.sk?a(t,r.sk,0,w,i):s,sa:r.sa?a(t,r.sa,0,w,i):s,s:r.s?a(t,r.s,1,.01,i):s,a:r.a?a(t,r.a,1,0,i):s,o:r.o?a(t,r.o,0,.01,i):s,p:r.p?a(t,r.p,1,0,i):s,sw:r.sw?a(t,r.sw,0,0,i):s,sc:r.sc?a(t,r.sc,1,0,i):s,fc:r.fc?a(t,r.fc,1,0,i):s,fh:r.fh?a(t,r.fh,0,0,i):s,fs:r.fs?a(t,r.fs,0,.01,i):s,fb:r.fb?a(t,r.fb,0,.01,i):s,t:r.t?a(t,r.t,0,0,i):s},this.s=ki.getTextSelectorProp(t,e.s,i),this.s.t=e.s.t}function Pi(t,e,i){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=i,this._animatorsData=l(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(i)}function Si(){}Pi.prototype.searchProperties=function(){var t,e,i=this._textData.a.length,s=_t.getProp;for(t=0;t<i;t+=1)e=this._textData.a[t],this._animatorsData[t]=new wi(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:s(this._elem,this._textData.p.a,0,0,this),f:s(this._elem,this._textData.p.f,0,0,this),l:s(this._elem,this._textData.p.l,0,0,this),r:s(this._elem,this._textData.p.r,0,0,this),p:s(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=s(this._elem,this._textData.m.a,1,0,this)},Pi.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var i,s,a,r,n,h,o,l,p,f,m,d,c,u,g,y,v,b,_,x=this._moreOptions.alignment.v,k=this._animatorsData,w=this._textData,P=this.mHelper,S=this._renderType,A=this.renderedLetters.length,D=t.l;if(this._hasMaskedPath){if(_=this._pathData.m,!this._pathData.n||this._pathData._mdf){var C,E=_.v;for(this._pathData.r.v&&(E=E.reverse()),n={tLength:0,segments:[]},r=E._length-1,y=0,a=0;a<r;a+=1)C=ht.buildBezierData(E.v[a],E.v[a+1],[E.o[a][0]-E.v[a][0],E.o[a][1]-E.v[a][1]],[E.i[a+1][0]-E.v[a+1][0],E.i[a+1][1]-E.v[a+1][1]]),n.tLength+=C.segmentLength,n.segments.push(C),y+=C.segmentLength;a=r,_.v.c&&(C=ht.buildBezierData(E.v[a],E.v[0],[E.o[a][0]-E.v[a][0],E.o[a][1]-E.v[a][1]],[E.i[0][0]-E.v[0][0],E.i[0][1]-E.v[0][1]]),n.tLength+=C.segmentLength,n.segments.push(C),y+=C.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,h=this._pathData.f.v,m=0,f=1,l=0,p=!0,u=n.segments,h<0&&_.v.c)for(n.tLength<Math.abs(h)&&(h=-Math.abs(h)%n.tLength),f=(c=u[m=u.length-1].points).length-1;h<0;)h+=c[f].partialLength,(f-=1)<0&&(f=(c=u[m-=1].points).length-1);d=(c=u[m].points)[f-1],g=(o=c[f]).partialLength}r=D.length,i=0,s=0;var M,T,F,I,L,B=1.2*t.finalSize*.714,z=!0;F=k.length;var V,q,j,W,H,X,Y,G,K,J,Z,U,Q=-1,$=h,tt=m,et=f,it=-1,st="",at=this.defaultPropsArray;if(2===t.j||1===t.j){var rt=0,nt=0,ot=2===t.j?-.5:-1,lt=0,pt=!0;for(a=0;a<r;a+=1)if(D[a].n){for(rt&&(rt+=nt);lt<a;)D[lt].animatorJustifyOffset=rt,lt+=1;rt=0,pt=!0}else{for(T=0;T<F;T+=1)(M=k[T].a).t.propType&&(pt&&2===t.j&&(nt+=M.t.v*ot),(L=k[T].s.getMult(D[a].anIndexes[T],w.a[T].s.totalChars)).length?rt+=M.t.v*L[0]*ot:rt+=M.t.v*L*ot);pt=!1}for(rt&&(rt+=nt);lt<a;)D[lt].animatorJustifyOffset=rt,lt+=1}for(a=0;a<r;a+=1){if(P.reset(),W=1,D[a].n)i=0,s+=t.yOffset,s+=z?1:0,h=$,z=!1,this._hasMaskedPath&&(f=et,d=(c=u[m=tt].points)[f-1],g=(o=c[f]).partialLength,l=0),st="",Z="",K="",U="",at=this.defaultPropsArray;else{if(this._hasMaskedPath){if(it!==D[a].line){switch(t.j){case 1:h+=y-t.lineWidths[D[a].line];break;case 2:h+=(y-t.lineWidths[D[a].line])/2}it=D[a].line}Q!==D[a].ind&&(D[Q]&&(h+=D[Q].extra),h+=D[a].an/2,Q=D[a].ind),h+=x[0]*D[a].an*.005;var ft=0;for(T=0;T<F;T+=1)(M=k[T].a).p.propType&&((L=k[T].s.getMult(D[a].anIndexes[T],w.a[T].s.totalChars)).length?ft+=M.p.v[0]*L[0]:ft+=M.p.v[0]*L),M.a.propType&&((L=k[T].s.getMult(D[a].anIndexes[T],w.a[T].s.totalChars)).length?ft+=M.a.v[0]*L[0]:ft+=M.a.v[0]*L);for(p=!0,this._pathData.a.v&&(h=.5*D[0].an+(y-this._pathData.f.v-.5*D[0].an-.5*D[D.length-1].an)*Q/(r-1),h+=this._pathData.f.v);p;)l+g>=h+ft||!c?(v=(h+ft-l)/o.partialLength,q=d.point[0]+(o.point[0]-d.point[0])*v,j=d.point[1]+(o.point[1]-d.point[1])*v,P.translate(-x[0]*D[a].an*.005,-x[1]*B*.01),p=!1):c&&(l+=o.partialLength,(f+=1)>=c.length&&(f=0,u[m+=1]?c=u[m].points:_.v.c?(f=0,c=u[m=0].points):(l-=o.partialLength,c=null)),c&&(d=o,g=(o=c[f]).partialLength));V=D[a].an/2-D[a].add,P.translate(-V,0,0)}else V=D[a].an/2-D[a].add,P.translate(-V,0,0),P.translate(-x[0]*D[a].an*.005,-x[1]*B*.01,0);for(T=0;T<F;T+=1)(M=k[T].a).t.propType&&(L=k[T].s.getMult(D[a].anIndexes[T],w.a[T].s.totalChars),0===i&&0===t.j||(this._hasMaskedPath?L.length?h+=M.t.v*L[0]:h+=M.t.v*L:L.length?i+=M.t.v*L[0]:i+=M.t.v*L));for(t.strokeWidthAnim&&(X=t.sw||0),t.strokeColorAnim&&(H=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(Y=[t.fc[0],t.fc[1],t.fc[2]]),T=0;T<F;T+=1)(M=k[T].a).a.propType&&((L=k[T].s.getMult(D[a].anIndexes[T],w.a[T].s.totalChars)).length?P.translate(-M.a.v[0]*L[0],-M.a.v[1]*L[1],M.a.v[2]*L[2]):P.translate(-M.a.v[0]*L,-M.a.v[1]*L,M.a.v[2]*L));for(T=0;T<F;T+=1)(M=k[T].a).s.propType&&((L=k[T].s.getMult(D[a].anIndexes[T],w.a[T].s.totalChars)).length?P.scale(1+(M.s.v[0]-1)*L[0],1+(M.s.v[1]-1)*L[1],1):P.scale(1+(M.s.v[0]-1)*L,1+(M.s.v[1]-1)*L,1));for(T=0;T<F;T+=1){if(M=k[T].a,L=k[T].s.getMult(D[a].anIndexes[T],w.a[T].s.totalChars),M.sk.propType&&(L.length?P.skewFromAxis(-M.sk.v*L[0],M.sa.v*L[1]):P.skewFromAxis(-M.sk.v*L,M.sa.v*L)),M.r.propType&&(L.length?P.rotateZ(-M.r.v*L[2]):P.rotateZ(-M.r.v*L)),M.ry.propType&&(L.length?P.rotateY(M.ry.v*L[1]):P.rotateY(M.ry.v*L)),M.rx.propType&&(L.length?P.rotateX(M.rx.v*L[0]):P.rotateX(M.rx.v*L)),M.o.propType&&(L.length?W+=(M.o.v*L[0]-W)*L[0]:W+=(M.o.v*L-W)*L),t.strokeWidthAnim&&M.sw.propType&&(L.length?X+=M.sw.v*L[0]:X+=M.sw.v*L),t.strokeColorAnim&&M.sc.propType)for(G=0;G<3;G+=1)L.length?H[G]+=(M.sc.v[G]-H[G])*L[0]:H[G]+=(M.sc.v[G]-H[G])*L;if(t.fillColorAnim&&t.fc){if(M.fc.propType)for(G=0;G<3;G+=1)L.length?Y[G]+=(M.fc.v[G]-Y[G])*L[0]:Y[G]+=(M.fc.v[G]-Y[G])*L;M.fh.propType&&(Y=L.length?N(Y,M.fh.v*L[0]):N(Y,M.fh.v*L)),M.fs.propType&&(Y=L.length?R(Y,M.fs.v*L[0]):R(Y,M.fs.v*L)),M.fb.propType&&(Y=L.length?O(Y,M.fb.v*L[0]):O(Y,M.fb.v*L))}}for(T=0;T<F;T+=1)(M=k[T].a).p.propType&&(L=k[T].s.getMult(D[a].anIndexes[T],w.a[T].s.totalChars),this._hasMaskedPath?L.length?P.translate(0,M.p.v[1]*L[0],-M.p.v[2]*L[1]):P.translate(0,M.p.v[1]*L,-M.p.v[2]*L):L.length?P.translate(M.p.v[0]*L[0],M.p.v[1]*L[1],-M.p.v[2]*L[2]):P.translate(M.p.v[0]*L,M.p.v[1]*L,-M.p.v[2]*L));if(t.strokeWidthAnim&&(K=X<0?0:X),t.strokeColorAnim&&(J="rgb("+Math.round(255*H[0])+","+Math.round(255*H[1])+","+Math.round(255*H[2])+")"),t.fillColorAnim&&t.fc&&(Z="rgb("+Math.round(255*Y[0])+","+Math.round(255*Y[1])+","+Math.round(255*Y[2])+")"),this._hasMaskedPath){if(P.translate(0,-t.ls),P.translate(0,x[1]*B*.01+s,0),this._pathData.p.v){b=(o.point[1]-d.point[1])/(o.point[0]-d.point[0]);var mt=180*Math.atan(b)/Math.PI;o.point[0]<d.point[0]&&(mt+=180),P.rotate(-mt*Math.PI/180)}P.translate(q,j,0),h-=x[0]*D[a].an*.005,D[a+1]&&Q!==D[a+1].ind&&(h+=D[a].an/2,h+=.001*t.tr*t.finalSize)}else{switch(P.translate(i,s,0),t.ps&&P.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:P.translate(D[a].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[D[a].line]),0,0);break;case 2:P.translate(D[a].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[D[a].line])/2,0,0)}P.translate(0,-t.ls),P.translate(V,0,0),P.translate(x[0]*D[a].an*.005,x[1]*B*.01,0),i+=D[a].l+.001*t.tr*t.finalSize}"html"===S?st=P.toCSS():"svg"===S?st=P.to2dCSS():at=[P.props[0],P.props[1],P.props[2],P.props[3],P.props[4],P.props[5],P.props[6],P.props[7],P.props[8],P.props[9],P.props[10],P.props[11],P.props[12],P.props[13],P.props[14],P.props[15]],U=W}A<=a?(I=new _i(U,K,J,Z,st,at),this.renderedLetters.push(I),A+=1,this.lettersChangedFlag=!0):(I=this.renderedLetters[a],this.lettersChangedFlag=I.update(U,K,J,Z,st,at)||this.lettersChangedFlag)}}},Pi.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},Pi.prototype.mHelper=new It,Pi.prototype.defaultPropsArray=[],r([xt],Pi),Si.prototype.initElement=function(t,e,i){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,i),this.textProperty=new xi(this,t.t,this.dynamicProperties),this.textAnimator=new Pi(t.t,this.renderType,this),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},Si.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},Si.prototype.createPathShape=function(t,e){var i,s,a=e.length,r="";for(i=0;i<a;i+=1)"sh"===e[i].ty&&(s=e[i].ks.k,r+=yi(s,s.i.length,!0,t));return r},Si.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},Si.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},Si.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},Si.prototype.applyTextPropertiesToMatrix=function(t,e,i,s,a){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i])/2,0,0)}e.translate(s,a,0)},Si.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},Si.prototype.emptyProp=new _i,Si.prototype.destroy=function(){},Si.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var Ai={shapes:[]};function Di(t,e,i){this.textSpans=[],this.renderType="svg",this.initElement(t,e,i)}function Ci(t,e,i){this.initElement(t,e,i)}function Ei(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initFrame(),this.initTransform(t,e,i),this.initHierarchy()}function Mi(){}function Ti(){}function Fi(t,e,i){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?l(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?_t.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function Ii(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=X("svg");var i="";if(e&&e.title){var s=X("title"),a=B();s.setAttribute("id",a),s.textContent=e.title,this.svgElement.appendChild(s),i+=a}if(e&&e.description){var r=X("desc"),n=B();r.setAttribute("id",n),r.textContent=e.description,this.svgElement.appendChild(r),i+=" "+n}i&&this.svgElement.setAttribute("aria-labelledby",i);var h=X("defs");this.svgElement.appendChild(h);var o=X("g");this.svgElement.appendChild(o),this.layerElement=o,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:h,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}r([Oe,Xe,Qe,$e,Ne,ti,Si],Di),Di.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=X("text"))},Di.prototype.buildTextContents=function(t){for(var e=0,i=t.length,s=[],a="";e<i;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(s.push(a),a=""):a+=t[e],e+=1;return s.push(a),s},Di.prototype.buildShapeData=function(t,e){if(t.shapes&&t.shapes.length){var i=t.shapes[0];if(i.it){var s=i.it[i.it.length-1];s.s&&(s.s.k[0]=e,s.s.k[1]=e)}}return t},Di.prototype.buildNewText=function(){var t,e;this.addDynamicProperty(this);var i=this.textProperty.currentData;this.renderedLetters=l(i?i.l.length:0),i.fc?this.layerElement.setAttribute("fill",this.buildColor(i.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),i.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(i.sc)),this.layerElement.setAttribute("stroke-width",i.sw)),this.layerElement.setAttribute("font-size",i.finalSize);var s=this.globalData.fontManager.getFontByName(i.f);if(s.fClass)this.layerElement.setAttribute("class",s.fClass);else{this.layerElement.setAttribute("font-family",s.fFamily);var a=i.fWeight,r=i.fStyle;this.layerElement.setAttribute("font-style",r),this.layerElement.setAttribute("font-weight",a)}this.layerElement.setAttribute("aria-label",i.t);var n,h=i.l||[],o=!!this.globalData.fontManager.chars;e=h.length;var p=this.mHelper,f=this.data.singleShape,m=0,d=0,c=!0,u=.001*i.tr*i.finalSize;if(!f||o||i.sz){var g,y=this.textSpans.length;for(t=0;t<e;t+=1){if(this.textSpans[t]||(this.textSpans[t]={span:null,childSpan:null,glyph:null}),!o||!f||0===t){if(n=y>t?this.textSpans[t].span:X(o?"g":"text"),y<=t){if(n.setAttribute("stroke-linecap","butt"),n.setAttribute("stroke-linejoin","round"),n.setAttribute("stroke-miterlimit","4"),this.textSpans[t].span=n,o){var v=X("g");n.appendChild(v),this.textSpans[t].childSpan=v}this.textSpans[t].span=n,this.layerElement.appendChild(n)}n.style.display="inherit"}if(p.reset(),f&&(h[t].n&&(m=-u,d+=i.yOffset,d+=c?1:0,c=!1),this.applyTextPropertiesToMatrix(i,p,h[t].line,m,d),m+=h[t].l||0,m+=u),o){var b;if(1===(g=this.globalData.fontManager.getCharData(i.finalText[t],s.fStyle,this.globalData.fontManager.getFontByName(i.f).fFamily)).t)b=new Fi(g.data,this.globalData,this);else{var _=Ai;g.data&&g.data.shapes&&(_=this.buildShapeData(g.data,i.finalSize)),b=new bi(_,this.globalData,this)}if(this.textSpans[t].glyph){var x=this.textSpans[t].glyph;this.textSpans[t].childSpan.removeChild(x.layerElement),x.destroy()}this.textSpans[t].glyph=b,b._debug=!0,b.prepareFrame(0),b.renderFrame(),this.textSpans[t].childSpan.appendChild(b.layerElement),1===g.t&&this.textSpans[t].childSpan.setAttribute("transform","scale("+i.finalSize/100+","+i.finalSize/100+")")}else f&&n.setAttribute("transform","translate("+p.props[12]+","+p.props[13]+")"),n.textContent=h[t].val,n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}f&&n&&n.setAttribute("d","")}else{var k=this.textContainer,w="start";switch(i.j){case 1:w="end";break;case 2:w="middle";break;default:w="start"}k.setAttribute("text-anchor",w),k.setAttribute("letter-spacing",u);var P=this.buildTextContents(i.finalText);for(e=P.length,d=i.ps?i.ps[1]+i.ascent:0,t=0;t<e;t+=1)(n=this.textSpans[t].span||X("tspan")).textContent=P[t],n.setAttribute("x",0),n.setAttribute("y",d),n.style.display="inherit",k.appendChild(n),this.textSpans[t]||(this.textSpans[t]={span:null,glyph:null}),this.textSpans[t].span=n,d+=i.finalLineHeight;this.layerElement.appendChild(k)}for(;t<this.textSpans.length;)this.textSpans[t].span.style.display="none",t+=1;this._sizeChanged=!0},Di.prototype.sourceRectAtTime=function(){if(this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged){this._sizeChanged=!1;var t=this.layerElement.getBBox();this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}}return this.bbox},Di.prototype.getValue=function(){var t,e,i=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<i;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf&&(this._mdf=!0))},Di.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){var t,e;this._sizeChanged=!0;var i,s,a,r=this.textAnimator.renderedLetters,n=this.textProperty.currentData.l;for(e=n.length,t=0;t<e;t+=1)n[t].n||(i=r[t],s=this.textSpans[t].span,(a=this.textSpans[t].glyph)&&a.renderFrame(),i._mdf.m&&s.setAttribute("transform",i.m),i._mdf.o&&s.setAttribute("opacity",i.o),i._mdf.sw&&s.setAttribute("stroke-width",i.sw),i._mdf.sc&&s.setAttribute("stroke",i.sc),i._mdf.fc&&s.setAttribute("fill",i.fc))}},r([ei],Ci),Ci.prototype.createContent=function(){var t=X("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},Ei.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},Ei.prototype.renderFrame=function(){},Ei.prototype.getBaseElement=function(){return null},Ei.prototype.destroy=function(){},Ei.prototype.sourceRectAtTime=function(){},Ei.prototype.hide=function(){},r([Oe,Xe,$e,Ne],Ei),r([We],Mi),Mi.prototype.createNull=function(t){return new Ei(t,this.globalData,this)},Mi.prototype.createShape=function(t){return new bi(t,this.globalData,this)},Mi.prototype.createText=function(t){return new Di(t,this.globalData,this)},Mi.prototype.createImage=function(t){return new ei(t,this.globalData,this)},Mi.prototype.createSolid=function(t){return new Ci(t,this.globalData,this)},Mi.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var i=X("clipPath"),a=X("rect");a.setAttribute("width",t.w),a.setAttribute("height",t.h),a.setAttribute("x",0),a.setAttribute("y",0);var r=B();i.setAttribute("id",r),i.appendChild(a),this.layerElement.setAttribute("clip-path","url("+s()+"#"+r+")"),e.appendChild(i),this.layers=t.layers,this.elements=l(t.layers.length)},Mi.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},Mi.prototype.updateContainerSize=function(){},Mi.prototype.findIndexByInd=function(t){var e=0,i=this.layers.length;for(e=0;e<i;e+=1)if(this.layers[e].ind===t)return e;return-1},Mi.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){e[t]=!0;var i=this.createItem(this.layers[t]);if(e[t]=i,q()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(i),i.initExpressions()),this.appendElementInPos(i,t),this.layers[t].tt){var s="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1;if(-1===s)return;if(this.elements[s]&&!0!==this.elements[s]){var a=e[s].getMatte(this.layers[t].tt);i.setMatte(a)}else this.buildItem(s),this.addPendingElement(i)}}},Mi.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,i=this.elements.length;e<i;){if(this.elements[e]===t){var s="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,a=this.elements[s].getMatte(this.layers[e].tt);t.setMatte(a);break}e+=1}}},Mi.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){var e;null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var i=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=i-1;e>=0;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<i;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},Mi.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){for(var s,a=0;a<e;)this.elements[a]&&!0!==this.elements[a]&&this.elements[a].getBaseElement()&&(s=this.elements[a].getBaseElement()),a+=1;s?this.layerElement.insertBefore(i,s):this.layerElement.appendChild(i)}},Mi.prototype.hide=function(){this.layerElement.style.display="none"},Mi.prototype.show=function(){this.layerElement.style.display="block"},r([Oe,Xe,$e,Ne,ti],Ti),Ti.prototype.initElement=function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},Ti.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var i,s=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),i=s-1;i>=0;i-=1)(this.completeLayers||this.elements[i])&&(this.elements[i].prepareFrame(this.renderedFrame-this.layers[i].st),this.elements[i]._mdf&&(this._mdf=!0))}},Ti.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},Ti.prototype.setElements=function(t){this.elements=t},Ti.prototype.getElements=function(){return this.elements},Ti.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},Ti.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},r([Mi,Ti,Qe],Fi),Fi.prototype.createComp=function(t){return new Fi(t,this.globalData,this)},r([Mi],Ii),Ii.prototype.createComp=function(t){return new Fi(t,this.globalData,this)};var Li,Bi={};function zi(t){var e,i,s=t.data.ef?t.data.ef.length:0;for(this.filters=[],e=0;e<s;e+=1){i=null;var a=t.data.ef[e].ty;if(Bi[a])i=new(0,Bi[a].effect)(t.effectsManager.effectElements[e],t);i&&this.filters.push(i)}this.filters.length&&t.addRenderableComponent(this)}function Vi(){}function Ri(t,e,i){this.initElement(t,e,i)}function Oi(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.shapesContainer=X("g"),this.initElement(t,e,i),this.prevViewData=[],this.currentBBox={x:999999,y:-999999,h:0,w:0}}function Ni(t,e,i){this.textSpans=[],this.textPaths=[],this.currentBBox={x:999999,y:-999999,h:0,w:0},this.renderType="svg",this.isMasked=!1,this.initElement(t,e,i)}function qi(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initHierarchy();var s=_t.getProp;if(this.pe=s(this,t.pe,0,0,this),t.ks.p.s?(this.px=s(this,t.ks.p.x,1,0,this),this.py=s(this,t.ks.p.y,1,0,this),this.pz=s(this,t.ks.p.z,1,0,this)):this.p=s(this,t.ks.p,1,0,this),t.ks.a&&(this.a=s(this,t.ks.a,1,0,this)),t.ks.or.k.length&&t.ks.or.k[0].to){var a,r=t.ks.or.k.length;for(a=0;a<r;a+=1)t.ks.or.k[a].to=null,t.ks.or.k[a].ti=null}this.or=s(this,t.ks.or,1,w,this),this.or.sh=!0,this.rx=s(this,t.ks.rx,0,w,this),this.ry=s(this,t.ks.ry,0,w,this),this.rz=s(this,t.ks.rz,0,w,this),this.mat=new It,this._prevMat=new It,this._isFirstFrame=!0,this.finalTransform={mProp:this}}function ji(t,e,i){this.assetData=e.getAssetData(t.refId),this.initElement(t,e,i)}function Wi(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"}},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}function Hi(t,e,i){this.layers=t.layers,this.supports3d=!t.hasMask,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?l(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?_t.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function Xi(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"},runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}return zi.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},zi.prototype.getEffects=function(t){var e,i=this.filters.length,s=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&s.push(this.filters[e]);return s},Vi.prototype={checkBlendMode:function(){},initRendererElement:function(){this.baseElement=a(this.data.tg||"div"),this.data.hasMask?(this.svgElement=X("svg"),this.layerElement=X("g"),this.maskedElement=this.layerElement,this.svgElement.appendChild(this.layerElement),this.baseElement.appendChild(this.svgElement)):this.layerElement=this.baseElement,A(this.baseElement)},createContainerElements:function(){this.renderableEffectsManager=new zi(this),this.transformedElement=this.baseElement,this.maskedElement=this.layerElement,this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0!==this.data.bm&&this.setBlendMode()},renderElement:function(){var t=this.transformedElement?this.transformedElement.style:{};if(this.finalTransform._matMdf){var e=this.finalTransform.mat.toCSS();t.transform=e,t.webkitTransform=e}this.finalTransform._opMdf&&(t.opacity=this.finalTransform.mProp.o.v)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},destroy:function(){this.layerElement=null,this.transformedElement=null,this.matteElement&&(this.matteElement=null),this.maskManager&&(this.maskManager.destroy(),this.maskManager=null)},createRenderableComponents:function(){this.maskManager=new Ye(this.data,this,this.globalData)},addEffects:function(){},setMatte:function(){}},Vi.prototype.getBaseElement=Qe.prototype.getBaseElement,Vi.prototype.destroyBaseElement=Vi.prototype.destroy,Vi.prototype.buildElementParenting=We.prototype.buildElementParenting,r([Oe,Xe,Vi,$e,Ne,ti],Ri),Ri.prototype.createContent=function(){var t;this.data.hasMask?((t=X("rect")).setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.svgElement.setAttribute("width",this.data.sw),this.svgElement.setAttribute("height",this.data.sh)):((t=a("div")).style.width=this.data.sw+"px",t.style.height=this.data.sh+"px",t.style.backgroundColor=this.data.sc),this.layerElement.appendChild(t)},r([Oe,Xe,Ri,bi,Vi,$e,Ne,Ae],Oi),Oi.prototype._renderShapeFrame=Oi.prototype.renderInnerContent,Oi.prototype.createContent=function(){var t;if(this.baseElement.style.fontSize=0,this.data.hasMask)this.layerElement.appendChild(this.shapesContainer),t=this.svgElement;else{t=X("svg");var e=this.comp.data?this.comp.data:this.globalData.compSize;t.setAttribute("width",e.w),t.setAttribute("height",e.h),t.appendChild(this.shapesContainer),this.layerElement.appendChild(t)}this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.shapesContainer,0,[],!0),this.filterUniqueShapes(),this.shapeCont=t},Oi.prototype.getTransformedPoint=function(t,e){var i,s=t.length;for(i=0;i<s;i+=1)e=t[i].mProps.v.applyToPointArray(e[0],e[1],0);return e},Oi.prototype.calculateShapeBoundingBox=function(t,e){var i,s,a,r,n,h=t.sh.v,o=t.transformers,l=h._length;if(!(l<=1)){for(i=0;i<l-1;i+=1)s=this.getTransformedPoint(o,h.v[i]),a=this.getTransformedPoint(o,h.o[i]),r=this.getTransformedPoint(o,h.i[i+1]),n=this.getTransformedPoint(o,h.v[i+1]),this.checkBounds(s,a,r,n,e);h.c&&(s=this.getTransformedPoint(o,h.v[i]),a=this.getTransformedPoint(o,h.o[i]),r=this.getTransformedPoint(o,h.i[0]),n=this.getTransformedPoint(o,h.v[0]),this.checkBounds(s,a,r,n,e))}},Oi.prototype.checkBounds=function(t,e,i,s,a){this.getBoundsOfCurve(t,e,i,s);var r=this.shapeBoundingBox;a.x=_(r.left,a.x),a.xMax=b(r.right,a.xMax),a.y=_(r.top,a.y),a.yMax=b(r.bottom,a.yMax)},Oi.prototype.shapeBoundingBox={left:0,right:0,top:0,bottom:0},Oi.prototype.tempBoundingBox={x:0,xMax:0,y:0,yMax:0,width:0,height:0},Oi.prototype.getBoundsOfCurve=function(t,e,i,s){for(var a,r,n,h,o,l,p,f=[[t[0],s[0]],[t[1],s[1]]],m=0;m<2;++m)r=6*t[m]-12*e[m]+6*i[m],a=-3*t[m]+9*e[m]-9*i[m]+3*s[m],n=3*e[m]-3*t[m],r|=0,n|=0,0===(a|=0)&&0===r||(0===a?(h=-n/r)>0&&h<1&&f[m].push(this.calculateF(h,t,e,i,s,m)):(o=r*r-4*n*a)>=0&&((l=(-r+y(o))/(2*a))>0&&l<1&&f[m].push(this.calculateF(l,t,e,i,s,m)),(p=(-r-y(o))/(2*a))>0&&p<1&&f[m].push(this.calculateF(p,t,e,i,s,m))));this.shapeBoundingBox.left=_.apply(null,f[0]),this.shapeBoundingBox.top=_.apply(null,f[1]),this.shapeBoundingBox.right=b.apply(null,f[0]),this.shapeBoundingBox.bottom=b.apply(null,f[1])},Oi.prototype.calculateF=function(t,e,i,s,a,r){return g(1-t,3)*e[r]+3*g(1-t,2)*t*i[r]+3*(1-t)*g(t,2)*s[r]+g(t,3)*a[r]},Oi.prototype.calculateBoundingBox=function(t,e){var i,s=t.length;for(i=0;i<s;i+=1)t[i]&&t[i].sh?this.calculateShapeBoundingBox(t[i],e):t[i]&&t[i].it?this.calculateBoundingBox(t[i].it,e):t[i]&&t[i].style&&t[i].w&&this.expandStrokeBoundingBox(t[i].w,e)},Oi.prototype.expandStrokeBoundingBox=function(t,e){var i=0;if(t.keyframes){for(var s=0;s<t.keyframes.length;s+=1){var a=t.keyframes[s].s;a>i&&(i=a)}i*=t.mult}else i=t.v*t.mult;e.x-=i,e.xMax+=i,e.y-=i,e.yMax+=i},Oi.prototype.currentBoxContains=function(t){return this.currentBBox.x<=t.x&&this.currentBBox.y<=t.y&&this.currentBBox.width+this.currentBBox.x>=t.x+t.width&&this.currentBBox.height+this.currentBBox.y>=t.y+t.height},Oi.prototype.renderInnerContent=function(){if(this._renderShapeFrame(),!this.hidden&&(this._isFirstFrame||this._mdf)){var t=this.tempBoundingBox,e=999999;if(t.x=e,t.xMax=-e,t.y=e,t.yMax=-e,this.calculateBoundingBox(this.itemsData,t),t.width=t.xMax<t.x?0:t.xMax-t.x,t.height=t.yMax<t.y?0:t.yMax-t.y,this.currentBoxContains(t))return;var i=!1;if(this.currentBBox.w!==t.width&&(this.currentBBox.w=t.width,this.shapeCont.setAttribute("width",t.width),i=!0),this.currentBBox.h!==t.height&&(this.currentBBox.h=t.height,this.shapeCont.setAttribute("height",t.height),i=!0),i||this.currentBBox.x!==t.x||this.currentBBox.y!==t.y){this.currentBBox.w=t.width,this.currentBBox.h=t.height,this.currentBBox.x=t.x,this.currentBBox.y=t.y,this.shapeCont.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h);var s=this.shapeCont.style,a="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)";s.transform=a,s.webkitTransform=a}}},r([Oe,Xe,Vi,$e,Ne,ti,Si],Ni),Ni.prototype.createContent=function(){if(this.isMasked=this.checkMasks(),this.isMasked){this.renderType="svg",this.compW=this.comp.data.w,this.compH=this.comp.data.h,this.svgElement.setAttribute("width",this.compW),this.svgElement.setAttribute("height",this.compH);var t=X("g");this.maskedElement.appendChild(t),this.innerElem=t}else this.renderType="html",this.innerElem=this.layerElement;this.checkParenting()},Ni.prototype.buildNewText=function(){var t=this.textProperty.currentData;this.renderedLetters=l(t.l?t.l.length:0);var e=this.innerElem.style,i=t.fc?this.buildColor(t.fc):"rgba(0,0,0,0)";e.fill=i,e.color=i,t.sc&&(e.stroke=this.buildColor(t.sc),e.strokeWidth=t.sw+"px");var s,r,n=this.globalData.fontManager.getFontByName(t.f);if(!this.globalData.fontManager.chars)if(e.fontSize=t.finalSize+"px",e.lineHeight=t.finalSize+"px",n.fClass)this.innerElem.className=n.fClass;else{e.fontFamily=n.fFamily;var h=t.fWeight,o=t.fStyle;e.fontStyle=o,e.fontWeight=h}var p,f,m,d=t.l;r=d.length;var c,u=this.mHelper,g="",y=0;for(s=0;s<r;s+=1){if(this.globalData.fontManager.chars?(this.textPaths[y]?p=this.textPaths[y]:((p=X("path")).setAttribute("stroke-linecap",ai[1]),p.setAttribute("stroke-linejoin",ri[2]),p.setAttribute("stroke-miterlimit","4")),this.isMasked||(this.textSpans[y]?m=(f=this.textSpans[y]).children[0]:((f=a("div")).style.lineHeight=0,(m=X("svg")).appendChild(p),A(f)))):this.isMasked?p=this.textPaths[y]?this.textPaths[y]:X("text"):this.textSpans[y]?(f=this.textSpans[y],p=this.textPaths[y]):(A(f=a("span")),A(p=a("span")),f.appendChild(p)),this.globalData.fontManager.chars){var v,b=this.globalData.fontManager.getCharData(t.finalText[s],n.fStyle,this.globalData.fontManager.getFontByName(t.f).fFamily);if(v=b?b.data:null,u.reset(),v&&v.shapes&&v.shapes.length&&(c=v.shapes[0].it,u.scale(t.finalSize/100,t.finalSize/100),g=this.createPathShape(u,c),p.setAttribute("d",g)),this.isMasked)this.innerElem.appendChild(p);else{if(this.innerElem.appendChild(f),v&&v.shapes){document.body.appendChild(m);var _=m.getBBox();m.setAttribute("width",_.width+2),m.setAttribute("height",_.height+2),m.setAttribute("viewBox",_.x-1+" "+(_.y-1)+" "+(_.width+2)+" "+(_.height+2));var x=m.style,k="translate("+(_.x-1)+"px,"+(_.y-1)+"px)";x.transform=k,x.webkitTransform=k,d[s].yOffset=_.y-1}else m.setAttribute("width",1),m.setAttribute("height",1);f.appendChild(m)}}else if(p.textContent=d[s].val,p.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),this.isMasked)this.innerElem.appendChild(p);else{this.innerElem.appendChild(f);var w=p.style,P="translate3d(0,"+-t.finalSize/1.2+"px,0)";w.transform=P,w.webkitTransform=P}this.isMasked?this.textSpans[y]=p:this.textSpans[y]=f,this.textSpans[y].style.display="block",this.textPaths[y]=p,y+=1}for(;y<this.textSpans.length;)this.textSpans[y].style.display="none",y+=1},Ni.prototype.renderInnerContent=function(){var t;if(this.validateText(),this.data.singleShape){if(!this._isFirstFrame&&!this.lettersChangedFlag)return;if(this.isMasked&&this.finalTransform._matMdf){this.svgElement.setAttribute("viewBox",-this.finalTransform.mProp.p.v[0]+" "+-this.finalTransform.mProp.p.v[1]+" "+this.compW+" "+this.compH),t=this.svgElement.style;var e="translate("+-this.finalTransform.mProp.p.v[0]+"px,"+-this.finalTransform.mProp.p.v[1]+"px)";t.transform=e,t.webkitTransform=e}}if(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag){var i,s,a,r,n,h=0,o=this.textAnimator.renderedLetters,l=this.textProperty.currentData.l;for(s=l.length,i=0;i<s;i+=1)l[i].n?h+=1:(r=this.textSpans[i],n=this.textPaths[i],a=o[h],h+=1,a._mdf.m&&(this.isMasked?r.setAttribute("transform",a.m):(r.style.webkitTransform=a.m,r.style.transform=a.m)),r.style.opacity=a.o,a.sw&&a._mdf.sw&&n.setAttribute("stroke-width",a.sw),a.sc&&a._mdf.sc&&n.setAttribute("stroke",a.sc),a.fc&&a._mdf.fc&&(n.setAttribute("fill",a.fc),n.style.color=a.fc));if(this.innerElem.getBBox&&!this.hidden&&(this._isFirstFrame||this._mdf)){var p=this.innerElem.getBBox();this.currentBBox.w!==p.width&&(this.currentBBox.w=p.width,this.svgElement.setAttribute("width",p.width)),this.currentBBox.h!==p.height&&(this.currentBBox.h=p.height,this.svgElement.setAttribute("height",p.height));if(this.currentBBox.w!==p.width+2||this.currentBBox.h!==p.height+2||this.currentBBox.x!==p.x-1||this.currentBBox.y!==p.y-1){this.currentBBox.w=p.width+2,this.currentBBox.h=p.height+2,this.currentBBox.x=p.x-1,this.currentBBox.y=p.y-1,this.svgElement.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h),t=this.svgElement.style;var f="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)";t.transform=f,t.webkitTransform=f}}}},r([Oe,Ne,$e],qi),qi.prototype.setup=function(){var t,e,i,s,a=this.comp.threeDElements.length;for(t=0;t<a;t+=1)if("3d"===(e=this.comp.threeDElements[t]).type){i=e.perspectiveElem.style,s=e.container.style;var r=this.pe.v+"px",n="0px 0px 0px",h="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";i.perspective=r,i.webkitPerspective=r,s.transformOrigin=n,s.mozTransformOrigin=n,s.webkitTransformOrigin=n,i.transform=h,i.webkitTransform=h}},qi.prototype.createElements=function(){},qi.prototype.hide=function(){},qi.prototype.renderFrame=function(){var t,e,i=this._isFirstFrame;if(this.hierarchy)for(e=this.hierarchy.length,t=0;t<e;t+=1)i=this.hierarchy[t].finalTransform.mProp._mdf||i;if(i||this.pe._mdf||this.p&&this.p._mdf||this.px&&(this.px._mdf||this.py._mdf||this.pz._mdf)||this.rx._mdf||this.ry._mdf||this.rz._mdf||this.or._mdf||this.a&&this.a._mdf){if(this.mat.reset(),this.hierarchy)for(t=e=this.hierarchy.length-1;t>=0;t-=1){var s=this.hierarchy[t].finalTransform.mProp;this.mat.translate(-s.p.v[0],-s.p.v[1],s.p.v[2]),this.mat.rotateX(-s.or.v[0]).rotateY(-s.or.v[1]).rotateZ(s.or.v[2]),this.mat.rotateX(-s.rx.v).rotateY(-s.ry.v).rotateZ(s.rz.v),this.mat.scale(1/s.s.v[0],1/s.s.v[1],1/s.s.v[2]),this.mat.translate(s.a.v[0],s.a.v[1],s.a.v[2])}if(this.p?this.mat.translate(-this.p.v[0],-this.p.v[1],this.p.v[2]):this.mat.translate(-this.px.v,-this.py.v,this.pz.v),this.a){var a;a=this.p?[this.p.v[0]-this.a.v[0],this.p.v[1]-this.a.v[1],this.p.v[2]-this.a.v[2]]:[this.px.v-this.a.v[0],this.py.v-this.a.v[1],this.pz.v-this.a.v[2]];var r=Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)+Math.pow(a[2],2)),n=[a[0]/r,a[1]/r,a[2]/r],h=Math.sqrt(n[2]*n[2]+n[0]*n[0]),o=Math.atan2(n[1],h),l=Math.atan2(n[0],-n[2]);this.mat.rotateY(l).rotateX(-o)}this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v),this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]),this.mat.translate(this.globalData.compSize.w/2,this.globalData.compSize.h/2,0),this.mat.translate(0,0,this.pe.v);var p=!this._prevMat.equals(this.mat);if((p||this.pe._mdf)&&this.comp.threeDElements){var f,m,d;for(e=this.comp.threeDElements.length,t=0;t<e;t+=1)if("3d"===(f=this.comp.threeDElements[t]).type){if(p){var c=this.mat.toCSS();(d=f.container.style).transform=c,d.webkitTransform=c}this.pe._mdf&&((m=f.perspectiveElem.style).perspective=this.pe.v+"px",m.webkitPerspective=this.pe.v+"px")}this.mat.clone(this._prevMat)}}this._isFirstFrame=!1},qi.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},qi.prototype.destroy=function(){},qi.prototype.getBaseElement=function(){return null},r([Oe,Xe,Vi,Ri,$e,Ne,Ae],ji),ji.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData),e=new Image;this.data.hasMask?(this.imageElem=X("image"),this.imageElem.setAttribute("width",this.assetData.w+"px"),this.imageElem.setAttribute("height",this.assetData.h+"px"),this.imageElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.imageElem),this.baseElement.setAttribute("width",this.assetData.w),this.baseElement.setAttribute("height",this.assetData.h)):this.layerElement.appendChild(e),e.crossOrigin="anonymous",e.src=t,this.data.ln&&this.baseElement.setAttribute("id",this.data.ln)},r([We],Wi),Wi.prototype.buildItem=Ii.prototype.buildItem,Wi.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},Wi.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){var s=this.layers[e];if(s.ddd&&this.supports3d)this.addTo3dContainer(i,e);else if(this.threeDElements)this.addTo3dContainer(i,e);else{for(var a,r,n=0;n<e;)this.elements[n]&&!0!==this.elements[n]&&this.elements[n].getBaseElement&&(r=this.elements[n],a=(this.layers[n].ddd?this.getThreeDContainerByPos(n):r.getBaseElement())||a),n+=1;a?s.ddd&&this.supports3d||this.layerElement.insertBefore(i,a):s.ddd&&this.supports3d||this.layerElement.appendChild(i)}}},Wi.prototype.createShape=function(t){return this.supports3d?new Oi(t,this.globalData,this):new bi(t,this.globalData,this)},Wi.prototype.createText=function(t){return this.supports3d?new Ni(t,this.globalData,this):new Di(t,this.globalData,this)},Wi.prototype.createCamera=function(t){return this.camera=new qi(t,this.globalData,this),this.camera},Wi.prototype.createImage=function(t){return this.supports3d?new ji(t,this.globalData,this):new ei(t,this.globalData,this)},Wi.prototype.createSolid=function(t){return this.supports3d?new Ri(t,this.globalData,this):new Ci(t,this.globalData,this)},Wi.prototype.createNull=Ii.prototype.createNull,Wi.prototype.getThreeDContainerByPos=function(t){for(var e=0,i=this.threeDElements.length;e<i;){if(this.threeDElements[e].startPos<=t&&this.threeDElements[e].endPos>=t)return this.threeDElements[e].perspectiveElem;e+=1}return null},Wi.prototype.createThreeDContainer=function(t,e){var i,s,r=a("div");A(r);var n=a("div");if(A(n),"3d"===e){(i=r.style).width=this.globalData.compSize.w+"px",i.height=this.globalData.compSize.h+"px";var h="50% 50%";i.webkitTransformOrigin=h,i.mozTransformOrigin=h,i.transformOrigin=h;var o="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";(s=n.style).transform=o,s.webkitTransform=o}r.appendChild(n);var l={container:n,perspectiveElem:r,startPos:t,endPos:t,type:e};return this.threeDElements.push(l),l},Wi.prototype.build3dContainers=function(){var t,e,i=this.layers.length,s="";for(t=0;t<i;t+=1)this.layers[t].ddd&&3!==this.layers[t].ty?("3d"!==s&&(s="3d",e=this.createThreeDContainer(t,"3d")),e.endPos=Math.max(e.endPos,t)):("2d"!==s&&(s="2d",e=this.createThreeDContainer(t,"2d")),e.endPos=Math.max(e.endPos,t));for(t=(i=this.threeDElements.length)-1;t>=0;t-=1)this.resizerElem.appendChild(this.threeDElements[t].perspectiveElem)},Wi.prototype.addTo3dContainer=function(t,e){for(var i=0,s=this.threeDElements.length;i<s;){if(e<=this.threeDElements[i].endPos){for(var a,r=this.threeDElements[i].startPos;r<e;)this.elements[r]&&this.elements[r].getBaseElement&&(a=this.elements[r].getBaseElement()),r+=1;a?this.threeDElements[i].container.insertBefore(t,a):this.threeDElements[i].container.appendChild(t);break}i+=1}},Wi.prototype.configAnimation=function(t){var e=a("div"),i=this.animationItem.wrapper,s=e.style;s.width=t.w+"px",s.height=t.h+"px",this.resizerElem=e,A(e),s.transformStyle="flat",s.mozTransformStyle="flat",s.webkitTransformStyle="flat",this.renderConfig.className&&e.setAttribute("class",this.renderConfig.className),i.appendChild(e),s.overflow="hidden";var r=X("svg");r.setAttribute("width","1"),r.setAttribute("height","1"),A(r),this.resizerElem.appendChild(r);var n=X("defs");r.appendChild(n),this.data=t,this.setupGlobalData(t,r),this.globalData.defs=n,this.layers=t.layers,this.layerElement=this.resizerElem,this.build3dContainers(),this.updateContainerSize()},Wi.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.animationItem.container=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},Wi.prototype.updateContainerSize=function(){var t,e,i,s,a=this.animationItem.wrapper.offsetWidth,r=this.animationItem.wrapper.offsetHeight,n=a/r;this.globalData.compSize.w/this.globalData.compSize.h>n?(t=a/this.globalData.compSize.w,e=a/this.globalData.compSize.w,i=0,s=(r-this.globalData.compSize.h*(a/this.globalData.compSize.w))/2):(t=r/this.globalData.compSize.h,e=r/this.globalData.compSize.h,i=(a-this.globalData.compSize.w*(r/this.globalData.compSize.h))/2,s=0);var h=this.resizerElem.style;h.webkitTransform="matrix3d("+t+",0,0,0,0,"+e+",0,0,0,0,1,0,"+i+","+s+",0,1)",h.transform=h.webkitTransform},Wi.prototype.renderFrame=Ii.prototype.renderFrame,Wi.prototype.hide=function(){this.resizerElem.style.display="none"},Wi.prototype.show=function(){this.resizerElem.style.display="block"},Wi.prototype.initItems=function(){if(this.buildAllItems(),this.camera)this.camera.setup();else{var t,e=this.globalData.compSize.w,i=this.globalData.compSize.h,s=this.threeDElements.length;for(t=0;t<s;t+=1){var a=this.threeDElements[t].perspectiveElem.style;a.webkitPerspective=Math.sqrt(Math.pow(e,2)+Math.pow(i,2))+"px",a.perspective=a.webkitPerspective}}},Wi.prototype.searchExtraCompositions=function(t){var e,i=t.length,s=a("div");for(e=0;e<i;e+=1)if(t[e].xt){var r=this.createComp(t[e],s,this.globalData.comp,null);r.initExpressions(),this.globalData.projectInterface.registerComposition(r)}},r([Wi,Ti,Vi],Hi),Hi.prototype._createBaseContainerElements=Hi.prototype.createContainerElements,Hi.prototype.createContainerElements=function(){this._createBaseContainerElements(),this.data.hasMask?(this.svgElement.setAttribute("width",this.data.w),this.svgElement.setAttribute("height",this.data.h),this.transformedElement=this.baseElement):this.transformedElement=this.layerElement},Hi.prototype.addTo3dContainer=function(t,e){for(var i,s=0;s<e;)this.elements[s]&&this.elements[s].getBaseElement&&(i=this.elements[s].getBaseElement()),s+=1;i?this.layerElement.insertBefore(t,i):this.layerElement.appendChild(t)},Hi.prototype.createComp=function(t){return this.supports3d?new Hi(t,this.globalData,this):new Fi(t,this.globalData,this)},r([Wi],Xi),Xi.prototype.createComp=function(t){return this.supports3d?new Hi(t,this.globalData,this):new Fi(t,this.globalData,this)},Li=Xi,Q["html"]=Li,jt.registerModifier("tm",Ht),jt.registerModifier("pb",Xt),jt.registerModifier("rp",Gt),jt.registerModifier("rd",Kt),jt.registerModifier("zz",fe),jt.registerModifier("op",ke),Bt}));
diff --git a/build/player/lottie_svg.js b/build/player/lottie_svg.js
index 36bb873..58009e8 100644
--- a/build/player/lottie_svg.js
+++ b/build/player/lottie_svg.js
@@ -1,4 +1,4 @@
-(typeof navigator !== "undefined") && (function (global, factory) {
+(typeof document !== "undefined") && (typeof navigator !== "undefined") && (function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
   typeof define === 'function' && define.amd ? define(factory) :
   (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lottie = factory());
@@ -8,19 +8,15 @@
   var locationHref = '';
   var _useWebWorker = false;
   var initialDefaultFrame = -999999;
-
   var setWebWorker = function setWebWorker(flag) {
     _useWebWorker = !!flag;
   };
-
   var getWebWorker = function getWebWorker() {
     return _useWebWorker;
   };
-
   var setLocationHref = function setLocationHref(value) {
     locationHref = value;
   };
-
   var getLocationHref = function getLocationHref() {
     return locationHref;
   };
@@ -34,28 +30,24 @@
     var i;
     var len = sources.length;
     var sourcePrototype;
-
     for (i = 0; i < len; i += 1) {
       sourcePrototype = sources[i].prototype;
-
       for (var attr in sourcePrototype) {
         if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
       }
     }
   }
-
   function getDescriptor(object, prop) {
     return Object.getOwnPropertyDescriptor(object, prop);
   }
-
   function createProxyFunction(prototype) {
     function ProxyFunction() {}
-
     ProxyFunction.prototype = prototype;
     return ProxyFunction;
   }
 
   // import Howl from '../../3rd_party/howler';
+
   var audioControllerFactory = function () {
     function AudioController(audioFactory) {
       this.audios = [];
@@ -63,7 +55,6 @@
       this._volume = 1;
       this._isMuted = false;
     }
-
     AudioController.prototype = {
       addAudio: function addAudio(audio) {
         this.audios.push(audio);
@@ -71,7 +62,6 @@
       pause: function pause() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].pause();
         }
@@ -79,7 +69,6 @@
       resume: function resume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].resume();
         }
@@ -87,7 +76,6 @@
       setRate: function setRate(rateValue) {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].setRate(rateValue);
         }
@@ -96,13 +84,11 @@
         if (this.audioFactory) {
           return this.audioFactory(assetPath);
         }
-
         if (window.Howl) {
           return new window.Howl({
             src: [assetPath]
           });
         }
-
         return {
           isPlaying: false,
           play: function play() {
@@ -121,17 +107,14 @@
       },
       setVolume: function setVolume(value) {
         this._volume = value;
-
         this._updateVolume();
       },
       mute: function mute() {
         this._isMuted = true;
-
         this._updateVolume();
       },
       unmute: function unmute() {
         this._isMuted = false;
-
         this._updateVolume();
       },
       getVolume: function getVolume() {
@@ -140,7 +123,6 @@
       _updateVolume: function _updateVolume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
         }
@@ -156,55 +138,44 @@
       var i = 0;
       var arr = [];
       var value;
-
       switch (type) {
         case 'int16':
         case 'uint8c':
           value = 1;
           break;
-
         default:
           value = 1.1;
           break;
       }
-
       for (i = 0; i < len; i += 1) {
         arr.push(value);
       }
-
       return arr;
     }
-
     function createTypedArrayFactory(type, len) {
       if (type === 'float32') {
         return new Float32Array(len);
       }
-
       if (type === 'int16') {
         return new Int16Array(len);
       }
-
       if (type === 'uint8c') {
         return new Uint8ClampedArray(len);
       }
-
       return createRegularArray(type, len);
     }
-
     if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
       return createTypedArrayFactory;
     }
-
     return createRegularArray;
   }();
-
   function createSizedArray(len) {
     return Array.apply(null, {
       length: len
     });
   }
 
-  function _typeof$6(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$6 = function _typeof(obj) { return typeof obj; }; } else { _typeof$6 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$6(obj); }
+  function _typeof$6(o) { "@babel/helpers - typeof"; return _typeof$6 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$6(o); }
   var subframeEnabled = true;
   var expressionsPlugin = null;
   var expressionsInterfaces = null;
@@ -217,57 +188,43 @@
   var bmMax = Math.max;
   var bmMin = Math.min;
   var BMMath = {};
-
   (function () {
     var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
     var i;
     var len = propertyNames.length;
-
     for (i = 0; i < len; i += 1) {
       BMMath[propertyNames[i]] = Math[propertyNames[i]];
     }
   })();
-
   function ProjectInterface$1() {
     return {};
   }
-
   BMMath.random = Math.random;
-
   BMMath.abs = function (val) {
     var tOfVal = _typeof$6(val);
-
     if (tOfVal === 'object' && val.length) {
       var absArr = createSizedArray(val.length);
       var i;
       var len = val.length;
-
       for (i = 0; i < len; i += 1) {
         absArr[i] = Math.abs(val[i]);
       }
-
       return absArr;
     }
-
     return Math.abs(val);
   };
-
   var defaultCurveSegments = 150;
   var degToRads = Math.PI / 180;
   var roundCorner = 0.5519;
-
   function roundValues(flag) {
     _shouldRoundValues = !!flag;
   }
-
   function bmRnd(value) {
     if (_shouldRoundValues) {
       return Math.round(value);
     }
-
     return value;
   }
-
   function styleDiv(element) {
     element.style.position = 'absolute';
     element.style.top = 0;
@@ -281,53 +238,44 @@
     element.style.webkitTransformStyle = 'preserve-3d';
     element.style.mozTransformStyle = 'preserve-3d';
   }
-
   function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
     this.type = type;
     this.currentTime = currentTime;
     this.totalTime = totalTime;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteEvent(type, frameMultiplier) {
     this.type = type;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
     this.type = type;
     this.currentLoop = currentLoop;
     this.totalLoops = totalLoops;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMSegmentStartEvent(type, firstFrame, totalFrames) {
     this.type = type;
     this.firstFrame = firstFrame;
     this.totalFrames = totalFrames;
   }
-
   function BMDestroyEvent(type, target) {
     this.type = type;
     this.target = target;
   }
-
   function BMRenderFrameErrorEvent(nativeError, currentTime) {
     this.type = 'renderFrameError';
     this.nativeError = nativeError;
     this.currentTime = currentTime;
   }
-
   function BMConfigErrorEvent(nativeError) {
     this.type = 'configError';
     this.nativeError = nativeError;
   }
-
   function BMAnimationConfigErrorEvent(type, nativeError) {
     this.type = type;
     this.nativeError = nativeError;
   }
-
   var createElementID = function () {
     var _count = 0;
     return function createID() {
@@ -335,7 +283,6 @@
       return idPrefix$1 + '__lottie_element_' + _count;
     };
   }();
-
   function HSVtoRGB(h, s, v) {
     var r;
     var g;
@@ -350,51 +297,42 @@
     p = v * (1 - s);
     q = v * (1 - f * s);
     t = v * (1 - (1 - f) * s);
-
     switch (i % 6) {
       case 0:
         r = v;
         g = t;
         b = p;
         break;
-
       case 1:
         r = q;
         g = v;
         b = p;
         break;
-
       case 2:
         r = p;
         g = v;
         b = t;
         break;
-
       case 3:
         r = p;
         g = q;
         b = v;
         break;
-
       case 4:
         r = t;
         g = p;
         b = v;
         break;
-
       case 5:
         r = v;
         g = p;
         b = q;
         break;
-
       default:
         break;
     }
-
     return [r, g, b];
   }
-
   function RGBtoHSV(r, g, b) {
     var max = Math.max(r, g, b);
     var min = Math.min(r, g, b);
@@ -402,136 +340,105 @@
     var h;
     var s = max === 0 ? 0 : d / max;
     var v = max / 255;
-
     switch (max) {
       case min:
         h = 0;
         break;
-
       case r:
         h = g - b + d * (g < b ? 6 : 0);
         h /= 6 * d;
         break;
-
       case g:
         h = b - r + d * 2;
         h /= 6 * d;
         break;
-
       case b:
         h = r - g + d * 4;
         h /= 6 * d;
         break;
-
       default:
         break;
     }
-
     return [h, s, v];
   }
-
   function addSaturationToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[1] += offset;
-
     if (hsv[1] > 1) {
       hsv[1] = 1;
     } else if (hsv[1] <= 0) {
       hsv[1] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addBrightnessToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[2] += offset;
-
     if (hsv[2] > 1) {
       hsv[2] = 1;
     } else if (hsv[2] < 0) {
       hsv[2] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addHueToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[0] += offset / 360;
-
     if (hsv[0] > 1) {
       hsv[0] -= 1;
     } else if (hsv[0] < 0) {
       hsv[0] += 1;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   var rgbToHex = function () {
     var colorMap = [];
     var i;
     var hex;
-
     for (i = 0; i < 256; i += 1) {
       hex = i.toString(16);
       colorMap[i] = hex.length === 1 ? '0' + hex : hex;
     }
-
     return function (r, g, b) {
       if (r < 0) {
         r = 0;
       }
-
       if (g < 0) {
         g = 0;
       }
-
       if (b < 0) {
         b = 0;
       }
-
       return '#' + colorMap[r] + colorMap[g] + colorMap[b];
     };
   }();
-
   var setSubframeEnabled = function setSubframeEnabled(flag) {
     subframeEnabled = !!flag;
   };
-
   var getSubframeEnabled = function getSubframeEnabled() {
     return subframeEnabled;
   };
-
   var setExpressionsPlugin = function setExpressionsPlugin(value) {
     expressionsPlugin = value;
   };
-
   var getExpressionsPlugin = function getExpressionsPlugin() {
     return expressionsPlugin;
   };
-
   var setExpressionInterfaces = function setExpressionInterfaces(value) {
     expressionsInterfaces = value;
   };
-
   var getExpressionInterfaces = function getExpressionInterfaces() {
     return expressionsInterfaces;
   };
-
   var setDefaultCurveSegments = function setDefaultCurveSegments(value) {
     defaultCurveSegments = value;
   };
-
   var getDefaultCurveSegments = function getDefaultCurveSegments() {
     return defaultCurveSegments;
   };
-
   var setIdPrefix = function setIdPrefix(value) {
     idPrefix$1 = value;
   };
-
   var getIdPrefix = function getIdPrefix() {
     return idPrefix$1;
   };
@@ -541,8 +448,7 @@
     return document.createElementNS(svgNS, type);
   }
 
-  function _typeof$5(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$5 = function _typeof(obj) { return typeof obj; }; } else { _typeof$5 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$5(obj); }
-
+  function _typeof$5(o) { "@babel/helpers - typeof"; return _typeof$5 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$5(o); }
   var dataManager = function () {
     var _counterId = 1;
     var processes = [];
@@ -563,21 +469,18 @@
         });
       }
     };
-
     function createWorker(fn) {
       if (window.Worker && window.Blob && getWebWorker()) {
         var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], {
           type: 'text/javascript'
-        }); // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
-
+        });
+        // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
         var url = URL.createObjectURL(blob);
         return new Worker(url);
       }
-
       workerFn = fn;
       return workerProxy;
     }
-
     function setupWorker() {
       if (!workerInstance) {
         workerInstance = createWorker(function workerStart(e) {
@@ -590,28 +493,22 @@
               var jLen;
               var k;
               var kLen;
-
               for (i = 0; i < len; i += 1) {
                 layerData = layers[i];
-
                 if ('ks' in layerData && !layerData.completed) {
                   layerData.completed = true;
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         convertPathsToAbsoluteValues(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) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
                           }
@@ -619,7 +516,6 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 0) {
                     layerData.layers = findCompLayers(layerData.refId, comps);
                     completeLayers(layerData.layers, comps);
@@ -631,16 +527,15 @@
                 }
               }
             }
-
             function completeChars(chars, assets) {
               if (chars) {
                 var i = 0;
                 var len = chars.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (chars[i].t === 1) {
                     // var compData = findComp(chars[i].data.refId, assets);
-                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets); // chars[i].data.ip = 0;
+                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                    // chars[i].data.ip = 0;
                     // chars[i].data.op = 99999;
                     // chars[i].data.st = 0;
                     // chars[i].data.sr = 1;
@@ -652,61 +547,48 @@
                     //   s: { k: [100, 100], a: 0 },
                     //   o: { k: 100, a: 0 },
                     // };
-
                     completeLayers(chars[i].data.layers, assets);
                   }
                 }
               }
             }
-
             function findComp(id, comps) {
               var i = 0;
               var len = comps.length;
-
               while (i < len) {
                 if (comps[i].id === id) {
                   return comps[i];
                 }
-
                 i += 1;
               }
-
               return null;
             }
-
             function findCompLayers(id, comps) {
               var comp = findComp(id, comps);
-
               if (comp) {
                 if (!comp.layers.__used) {
                   comp.layers.__used = true;
                   return comp.layers;
                 }
-
                 return JSON.parse(JSON.stringify(comp.layers));
               }
-
               return null;
             }
-
             function completeShapes(arr) {
               var i;
               var len = arr.length;
               var j;
               var jLen;
-
               for (i = len - 1; i >= 0; i -= 1) {
                 if (arr[i].ty === 'sh') {
                   if (arr[i].ks.k.i) {
                     convertPathsToAbsoluteValues(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) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
                       }
-
                       if (arr[i].ks.k[j].e) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
                       }
@@ -717,11 +599,9 @@
                 }
               }
             }
-
             function convertPathsToAbsoluteValues(path) {
               var i;
               var len = path.i.length;
-
               for (i = 0; i < len; i += 1) {
                 path.i[i][0] += path.v[i][0];
                 path.i[i][1] += path.v[i][1];
@@ -729,40 +609,30 @@
                 path.o[i][1] += path.v[i][1];
               }
             }
-
             function checkVersion(minimum, animVersionString) {
               var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
-
               if (minimum[0] > animVersion[0]) {
                 return true;
               }
-
               if (animVersion[0] > minimum[0]) {
                 return false;
               }
-
               if (minimum[1] > animVersion[1]) {
                 return true;
               }
-
               if (animVersion[1] > minimum[1]) {
                 return false;
               }
-
               if (minimum[2] > animVersion[2]) {
                 return true;
               }
-
               if (animVersion[2] > minimum[2]) {
                 return false;
               }
-
               return null;
             }
-
             var checkText = function () {
               var minimumVersion = [4, 4, 14];
-
               function updateTextLayer(textLayer) {
                 var documentData = textLayer.t.d;
                 textLayer.t.d = {
@@ -772,26 +642,21 @@
                   }]
                 };
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -801,17 +666,14 @@
                 }
               };
             }();
-
             var checkChars = function () {
               var minimumVersion = [4, 7, 99];
               return function (animationData) {
                 if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
                   var i;
                   var len = animationData.chars.length;
-
                   for (i = 0; i < len; i += 1) {
                     var charData = animationData.chars[i];
-
                     if (charData.data && charData.data.shapes) {
                       completeShapes(charData.data.shapes);
                       charData.data.ip = 0;
@@ -840,7 +702,6 @@
                           a: 0
                         }
                       };
-
                       if (!animationData.chars[i].t) {
                         charData.data.shapes.push({
                           ty: 'no'
@@ -882,27 +743,22 @@
                 }
               };
             }();
-
             var checkPathProperties = function () {
               var minimumVersion = [5, 7, 15];
-
               function updateTextLayer(textLayer) {
                 var pathData = textLayer.t.p;
-
                 if (typeof pathData.a === 'number') {
                   pathData.a = {
                     a: 0,
                     k: pathData.a
                   };
                 }
-
                 if (typeof pathData.p === 'number') {
                   pathData.p = {
                     a: 0,
                     k: pathData.p
                   };
                 }
-
                 if (typeof pathData.r === 'number') {
                   pathData.r = {
                     a: 0,
@@ -910,26 +766,21 @@
                   };
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -939,23 +790,19 @@
                 }
               };
             }();
-
             var checkColors = function () {
               var minimumVersion = [4, 1, 9];
-
               function iterateShapes(shapes) {
                 var i;
                 var len = shapes.length;
                 var j;
                 var jLen;
-
                 for (i = 0; i < len; i += 1) {
                   if (shapes[i].ty === 'gr') {
                     iterateShapes(shapes[i].it);
                   } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
                     if (shapes[i].c.k && shapes[i].c.k[0].i) {
                       jLen = shapes[i].c.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (shapes[i].c.k[j].s) {
                           shapes[i].c.k[j].s[0] /= 255;
@@ -963,7 +810,6 @@
                           shapes[i].c.k[j].s[2] /= 255;
                           shapes[i].c.k[j].s[3] /= 255;
                         }
-
                         if (shapes[i].c.k[j].e) {
                           shapes[i].c.k[j].e[0] /= 255;
                           shapes[i].c.k[j].e[1] /= 255;
@@ -980,26 +826,21 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 4) {
                     iterateShapes(layers[i].shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1009,28 +850,23 @@
                 }
               };
             }();
-
             var checkShapes = function () {
               var minimumVersion = [4, 4, 18];
-
               function completeClosingShapes(arr) {
                 var i;
                 var len = arr.length;
                 var j;
                 var jLen;
-
                 for (i = len - 1; i >= 0; i -= 1) {
                   if (arr[i].ty === 'sh') {
                     if (arr[i].ks.k.i) {
                       arr[i].ks.k.c = arr[i].closed;
                     } else {
                       jLen = arr[i].ks.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (arr[i].ks.k[j].s) {
                           arr[i].ks.k[j].s[0].c = arr[i].closed;
                         }
-
                         if (arr[i].ks.k[j].e) {
                           arr[i].ks.k[j].e[0].c = arr[i].closed;
                         }
@@ -1041,7 +877,6 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var layerData;
                 var i;
@@ -1050,25 +885,20 @@
                 var jLen;
                 var k;
                 var kLen;
-
                 for (i = 0; i < len; i += 1) {
                   layerData = layers[i];
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         maskProps[j].pt.k.c = maskProps[j].cl;
                       } else {
                         kLen = maskProps[j].pt.k.length;
-
                         for (k = 0; k < kLen; k += 1) {
                           if (maskProps[j].pt.k[k].s) {
                             maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
                           }
@@ -1076,21 +906,17 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 4) {
                     completeClosingShapes(layerData.shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1100,12 +926,10 @@
                 }
               };
             }();
-
             function completeData(animationData) {
               if (animationData.__complete) {
                 return;
               }
-
               checkColors(animationData);
               checkText(animationData);
               checkChars(animationData);
@@ -1115,12 +939,11 @@
               completeChars(animationData.chars, animationData.assets);
               animationData.__complete = true;
             }
-
             function completeText(data) {
-              if (data.t.a.length === 0 && !('m' in data.t.p)) {// data.singleShape = true;
+              if (data.t.a.length === 0 && !('m' in data.t.p)) {
+                // data.singleShape = true;
               }
             }
-
             var moduleOb = {};
             moduleOb.completeData = completeData;
             moduleOb.checkColors = checkColors;
@@ -1130,47 +953,37 @@
             moduleOb.completeLayers = completeLayers;
             return moduleOb;
           }
-
           if (!_workerSelf.dataManager) {
             _workerSelf.dataManager = dataFunctionManager();
           }
-
           if (!_workerSelf.assetLoader) {
             _workerSelf.assetLoader = function () {
               function formatResponse(xhr) {
                 // using typeof doubles the time of execution of this method,
                 // so if available, it's better to use the header to validate the type
                 var contentTypeHeader = xhr.getResponseHeader('content-type');
-
                 if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
                   return xhr.response;
                 }
-
                 if (xhr.response && _typeof$5(xhr.response) === 'object') {
                   return xhr.response;
                 }
-
                 if (xhr.response && typeof xhr.response === 'string') {
                   return JSON.parse(xhr.response);
                 }
-
                 if (xhr.responseText) {
                   return JSON.parse(xhr.responseText);
                 }
-
                 return null;
               }
-
               function loadAsset(path, fullPath, callback, errorCallback) {
                 var response;
-                var xhr = new XMLHttpRequest(); // set responseType after calling open or IE will break.
-
+                var xhr = new XMLHttpRequest();
+                // set responseType after calling open or IE will break.
                 try {
                   // This crashes on Android WebView prior to KitKat
                   xhr.responseType = 'json';
                 } catch (err) {} // eslint-disable-line no-empty
-
-
                 xhr.onreadystatechange = function () {
                   if (xhr.readyState === 4) {
                     if (xhr.status === 200) {
@@ -1188,7 +1001,6 @@
                     }
                   }
                 };
-
                 try {
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), path, true);
@@ -1196,20 +1008,16 @@
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
                 }
-
                 xhr.send();
               }
-
               return {
                 load: loadAsset
               };
             }();
           }
-
           if (e.data.type === 'loadAnimation') {
             _workerSelf.assetLoader.load(e.data.path, e.data.fullPath, function (data) {
               _workerSelf.dataManager.completeData(data);
-
               _workerSelf.postMessage({
                 id: e.data.id,
                 payload: data,
@@ -1223,9 +1031,7 @@
             });
           } else if (e.data.type === 'complete') {
             var animation = e.data.animation;
-
             _workerSelf.dataManager.completeData(animation);
-
             _workerSelf.postMessage({
               id: e.data.id,
               payload: animation,
@@ -1246,13 +1052,11 @@
             });
           }
         });
-
         workerInstance.onmessage = function (event) {
           var data = event.data;
           var id = data.id;
           var process = processes[id];
           processes[id] = null;
-
           if (data.status === 'success') {
             process.onComplete(data.payload);
           } else if (process.onError) {
@@ -1261,7 +1065,6 @@
         };
       }
     }
-
     function createProcess(onComplete, onError) {
       _counterId += 1;
       var id = 'processId_' + _counterId;
@@ -1271,7 +1074,6 @@
       };
       return id;
     }
-
     function loadAnimation(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1282,7 +1084,6 @@
         id: processId
       });
     }
-
     function loadData(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1293,7 +1094,6 @@
         id: processId
       });
     }
-
     function completeAnimation(anim, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1303,7 +1103,6 @@
         id: processId
       });
     }
-
     return {
       loadAnimation: loadAnimation,
       loadData: loadData,
@@ -1321,94 +1120,74 @@
       ctx.fillRect(0, 0, 1, 1);
       return canvas;
     }();
-
     function imageLoaded() {
       this.loadedAssets += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function footageLoaded() {
       this.loadedFootagesCount += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function getAssetsPath(assetData, assetsPath, originalPath) {
       var path = '';
-
       if (assetData.e) {
         path = assetData.p;
       } else if (assetsPath) {
         var imagePath = assetData.p;
-
         if (imagePath.indexOf('images/') !== -1) {
           imagePath = imagePath.split('/')[1];
         }
-
         path = assetsPath + imagePath;
       } else {
         path = originalPath;
         path += assetData.u ? assetData.u : '';
         path += assetData.p;
       }
-
       return path;
     }
-
     function testImageLoaded(img) {
       var _count = 0;
       var intervalId = setInterval(function () {
         var box = img.getBBox();
-
         if (box.width || _count > 500) {
           this._imageLoaded();
-
           clearInterval(intervalId);
         }
-
         _count += 1;
       }.bind(this), 50);
     }
-
     function createImageData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createNS('image');
-
       if (isSafari) {
         this.testImageLoaded(img);
       } else {
         img.addEventListener('load', this._imageLoaded, false);
       }
-
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
-
       if (this._elementHelper.append) {
         this._elementHelper.append(img);
       } else {
         this._elementHelper.appendChild(img);
       }
-
       var ob = {
         img: img,
         assetData: assetData
       };
       return ob;
     }
-
     function createImgData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createTag('img');
@@ -1416,7 +1195,6 @@
       img.addEventListener('load', this._imageLoaded, false);
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.src = path;
@@ -1426,7 +1204,6 @@
       };
       return ob;
     }
-
     function createFootageData(data) {
       var ob = {
         assetData: data
@@ -1434,21 +1211,17 @@
       var path = getAssetsPath(data, this.assetsPath, this.path);
       dataManager.loadData(path, function (footageData) {
         ob.img = footageData;
-
         this._footageLoaded();
       }.bind(this), function () {
         ob.img = {};
-
         this._footageLoaded();
       }.bind(this));
       return ob;
     }
-
     function loadAssets(assets, cb) {
       this.imagesLoadedCb = cb;
       var i;
       var len = assets.length;
-
       for (i = 0; i < len; i += 1) {
         if (!assets[i].layers) {
           if (!assets[i].t || assets[i].t === 'seq') {
@@ -1461,43 +1234,33 @@
         }
       }
     }
-
     function setPath(path) {
       this.path = path || '';
     }
-
     function setAssetsPath(path) {
       this.assetsPath = path || '';
     }
-
     function getAsset(assetData) {
       var i = 0;
       var len = this.images.length;
-
       while (i < len) {
         if (this.images[i].assetData === assetData) {
           return this.images[i].img;
         }
-
         i += 1;
       }
-
       return null;
     }
-
     function destroy() {
       this.imagesLoadedCb = null;
       this.images.length = 0;
     }
-
     function loadedImages() {
       return this.totalImages === this.loadedAssets;
     }
-
     function loadedFootages() {
       return this.totalFootages === this.loadedFootagesCount;
     }
-
     function setCacheType(type, elementHelper) {
       if (type === 'svg') {
         this._elementHelper = elementHelper;
@@ -1506,7 +1269,6 @@
         this._createImageData = this.createImgData.bind(this);
       }
     }
-
     function ImagePreloaderFactory() {
       this._imageLoaded = imageLoaded.bind(this);
       this._footageLoaded = footageLoaded.bind(this);
@@ -1521,7 +1283,6 @@
       this.imagesLoadedCb = null;
       this.images = [];
     }
-
     ImagePreloaderFactory.prototype = {
       loadAssets: loadAssets,
       setAssetsPath: setAssetsPath,
@@ -1540,12 +1301,10 @@
   }();
 
   function BaseEvent() {}
-
   BaseEvent.prototype = {
     triggerEvent: function triggerEvent(eventName, args) {
       if (this._cbs[eventName]) {
         var callbacks = this._cbs[eventName];
-
         for (var i = 0; i < callbacks.length; i += 1) {
           callbacks[i](args);
         }
@@ -1555,9 +1314,7 @@
       if (!this._cbs[eventName]) {
         this._cbs[eventName] = [];
       }
-
       this._cbs[eventName].push(callback);
-
       return function () {
         this.removeEventListener(eventName, callback);
       }.bind(this);
@@ -1568,18 +1325,14 @@
       } else if (this._cbs[eventName]) {
         var i = 0;
         var len = this._cbs[eventName].length;
-
         while (i < len) {
           if (this._cbs[eventName][i] === callback) {
             this._cbs[eventName].splice(i, 1);
-
             i -= 1;
             len -= 1;
           }
-
           i += 1;
         }
-
         if (!this._cbs[eventName].length) {
           this._cbs[eventName] = null;
         }
@@ -1593,33 +1346,26 @@
       var keys = {};
       var line;
       var keysCount = 0;
-
       for (var i = 0; i < lines.length; i += 1) {
         line = lines[i].split(':');
-
         if (line.length === 2) {
           keys[line[0]] = line[1].trim();
           keysCount += 1;
         }
       }
-
       if (keysCount === 0) {
         throw new Error();
       }
-
       return keys;
     }
-
     return function (_markers) {
       var markers = [];
-
       for (var i = 0; i < _markers.length; i += 1) {
         var _marker = _markers[i];
         var markerData = {
           time: _marker.tm,
           duration: _marker.dr
         };
-
         try {
           markerData.payload = JSON.parse(_markers[i].cm);
         } catch (_) {
@@ -1631,10 +1377,8 @@
             };
           }
         }
-
         markers.push(markerData);
       }
-
       return markers;
     };
   }();
@@ -1643,27 +1387,21 @@
     function registerComposition(comp) {
       this.compositions.push(comp);
     }
-
     return function () {
       function _thisProjectFunction(name) {
         var i = 0;
         var len = this.compositions.length;
-
         while (i < len) {
           if (this.compositions[i].data && this.compositions[i].data.nm === name) {
             if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
               this.compositions[i].prepareFrame(this.currentFrame);
             }
-
             return this.compositions[i].compInterface;
           }
-
           i += 1;
         }
-
         return null;
       }
-
       _thisProjectFunction.compositions = [];
       _thisProjectFunction.currentFrame = 0;
       _thisProjectFunction.registerComposition = registerComposition;
@@ -1672,33 +1410,27 @@
   }();
 
   var renderers = {};
-
   var registerRenderer = function registerRenderer(key, value) {
     renderers[key] = value;
   };
-
   function getRenderer(key) {
     return renderers[key];
   }
-
   function getRegisteredRenderer() {
     // Returns canvas by default for compatibility
     if (renderers.canvas) {
       return 'canvas';
-    } // Returns any renderer that is registered
-
-
+    }
+    // Returns any renderer that is registered
     for (var key in renderers) {
       if (renderers[key]) {
         return key;
       }
     }
-
     return '';
   }
 
-  function _typeof$4(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$4 = function _typeof(obj) { return typeof obj; }; } else { _typeof$4 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$4(obj); }
-
+  function _typeof$4(o) { "@babel/helpers - typeof"; return _typeof$4 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$4(o); }
   var AnimationItem = function AnimationItem() {
     this._cbs = [];
     this.name = '';
@@ -1737,28 +1469,22 @@
     this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
     this.expressionsPlugin = getExpressionsPlugin();
   };
-
   extendPrototype([BaseEvent], AnimationItem);
-
   AnimationItem.prototype.setParams = function (params) {
     if (params.wrapper || params.container) {
       this.wrapper = params.wrapper || params.container;
     }
-
     var animType = 'svg';
-
     if (params.animType) {
       animType = params.animType;
     } else if (params.renderer) {
       animType = params.renderer;
     }
-
     var RendererClass = getRenderer(animType);
     this.renderer = new RendererClass(this, params.rendererSettings);
     this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
     this.renderer.setProjectInterface(this.projectInterface);
     this.animType = animType;
-
     if (params.loop === '' || params.loop === null || params.loop === undefined || params.loop === true) {
       this.loop = true;
     } else if (params.loop === false) {
@@ -1766,17 +1492,14 @@
     } else {
       this.loop = parseInt(params.loop, 10);
     }
-
     this.autoplay = 'autoplay' in params ? params.autoplay : true;
     this.name = params.name ? params.name : '';
     this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
     this.assetsPath = params.assetsPath;
     this.initialSegment = params.initialSegment;
-
     if (params.audioFactory) {
       this.audioController.setAudioFactory(params.audioFactory);
     }
-
     if (params.animationData) {
       this.setupAnimation(params.animationData);
     } else if (params.path) {
@@ -1785,28 +1508,23 @@
       } else {
         this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
       }
-
       this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
       this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
       dataManager.loadAnimation(params.path, this.configAnimation, this.onSetupError);
     }
   };
-
   AnimationItem.prototype.onSetupError = function () {
     this.trigger('data_failed');
   };
-
   AnimationItem.prototype.setupAnimation = function (data) {
     dataManager.completeAnimation(data, this.configAnimation);
   };
-
   AnimationItem.prototype.setData = function (wrapper, animationData) {
     if (animationData) {
       if (_typeof$4(animationData) !== 'object') {
         animationData = JSON.parse(animationData);
       }
     }
-
     var params = {
       wrapper: wrapper,
       animationData: animationData
@@ -1823,7 +1541,6 @@
     var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-loop').value : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-loop').value : wrapperAttributes.getNamedItem('bm-loop') ? wrapperAttributes.getNamedItem('bm-loop').value : '';
-
     if (loop === 'false') {
       params.loop = false;
     } else if (loop === 'true') {
@@ -1831,7 +1548,6 @@
     } else if (loop !== '') {
       params.loop = parseInt(loop, 10);
     }
-
     var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-autoplay').value : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-autoplay').value : wrapperAttributes.getNamedItem('bm-autoplay') ? wrapperAttributes.getNamedItem('bm-autoplay').value : true;
@@ -1842,81 +1558,64 @@
     var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-prerender').value : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-prerender').value : wrapperAttributes.getNamedItem('bm-prerender') ? wrapperAttributes.getNamedItem('bm-prerender').value : '';
-
     if (prerender === 'false') {
       params.prerender = false;
     }
-
     if (!params.path) {
       this.trigger('destroy');
     } else {
       this.setParams(params);
     }
   };
-
   AnimationItem.prototype.includeLayers = function (data) {
     if (data.op > this.animationData.op) {
       this.animationData.op = data.op;
       this.totalFrames = Math.floor(data.op - this.animationData.ip);
     }
-
     var layers = this.animationData.layers;
     var i;
     var len = layers.length;
     var newLayers = data.layers;
     var j;
     var jLen = newLayers.length;
-
     for (j = 0; j < jLen; j += 1) {
       i = 0;
-
       while (i < len) {
         if (layers[i].id === newLayers[j].id) {
           layers[i] = newLayers[j];
           break;
         }
-
         i += 1;
       }
     }
-
     if (data.chars || data.fonts) {
       this.renderer.globalData.fontManager.addChars(data.chars);
       this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
     }
-
     if (data.assets) {
       len = data.assets.length;
-
       for (i = 0; i < len; i += 1) {
         this.animationData.assets.push(data.assets[i]);
       }
     }
-
     this.animationData.__complete = false;
     dataManager.completeAnimation(this.animationData, this.onSegmentComplete);
   };
-
   AnimationItem.prototype.onSegmentComplete = function (data) {
     this.animationData = data;
     var expressionsPlugin = getExpressionsPlugin();
-
     if (expressionsPlugin) {
       expressionsPlugin.initExpressions(this);
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.loadNextSegment = function () {
     var segments = this.animationData.segments;
-
     if (!segments || segments.length === 0 || !this.autoloadSegments) {
       this.trigger('data_ready');
       this.timeCompleted = this.totalFrames;
       return;
     }
-
     var segment = segments.shift();
     this.timeCompleted = segment.time * this.frameRate;
     var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
@@ -1925,36 +1624,28 @@
       this.trigger('data_failed');
     }.bind(this));
   };
-
   AnimationItem.prototype.loadSegments = function () {
     var segments = this.animationData.segments;
-
     if (!segments) {
       this.timeCompleted = this.totalFrames;
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.imagesLoaded = function () {
     this.trigger('loaded_images');
     this.checkLoaded();
   };
-
   AnimationItem.prototype.preloadImages = function () {
     this.imagePreloader.setAssetsPath(this.assetsPath);
     this.imagePreloader.setPath(this.path);
     this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
   };
-
   AnimationItem.prototype.configAnimation = function (animData) {
     if (!this.renderer) {
       return;
     }
-
     try {
       this.animationData = animData;
-
       if (this.initialSegment) {
         this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
         this.firstFrame = Math.round(this.initialSegment[0]);
@@ -1962,13 +1653,10 @@
         this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
         this.firstFrame = Math.round(this.animationData.ip);
       }
-
       this.renderer.configAnimation(animData);
-
       if (!animData.assets) {
         animData.assets = [];
       }
-
       this.assets = this.animationData.assets;
       this.frameRate = this.animationData.fr;
       this.frameMult = this.animationData.fr / 1000;
@@ -1979,7 +1667,6 @@
       this.loadSegments();
       this.updaFrameModifier();
       this.waitForFontsLoaded();
-
       if (this.isPaused) {
         this.audioController.pause();
       }
@@ -1987,103 +1674,83 @@
       this.triggerConfigError(error);
     }
   };
-
   AnimationItem.prototype.waitForFontsLoaded = function () {
     if (!this.renderer) {
       return;
     }
-
     if (this.renderer.globalData.fontManager.isLoaded) {
       this.checkLoaded();
     } else {
       setTimeout(this.waitForFontsLoaded.bind(this), 20);
     }
   };
-
   AnimationItem.prototype.checkLoaded = function () {
     if (!this.isLoaded && this.renderer.globalData.fontManager.isLoaded && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas') && this.imagePreloader.loadedFootages()) {
       this.isLoaded = true;
       var expressionsPlugin = getExpressionsPlugin();
-
       if (expressionsPlugin) {
         expressionsPlugin.initExpressions(this);
       }
-
       this.renderer.initItems();
       setTimeout(function () {
         this.trigger('DOMLoaded');
       }.bind(this), 0);
       this.gotoFrame();
-
       if (this.autoplay) {
         this.play();
       }
     }
   };
-
   AnimationItem.prototype.resize = function (width, height) {
     // Adding this validation for backwards compatibility in case an event object was being passed down
     var _width = typeof width === 'number' ? width : undefined;
-
     var _height = typeof height === 'number' ? height : undefined;
-
     this.renderer.updateContainerSize(_width, _height);
   };
-
   AnimationItem.prototype.setSubframe = function (flag) {
     this.isSubframeEnabled = !!flag;
   };
-
   AnimationItem.prototype.gotoFrame = function () {
     this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
 
     if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
       this.currentFrame = this.timeCompleted;
     }
-
     this.trigger('enterFrame');
     this.renderFrame();
     this.trigger('drawnFrame');
   };
-
   AnimationItem.prototype.renderFrame = function () {
     if (this.isLoaded === false || !this.renderer) {
       return;
     }
-
     try {
       if (this.expressionsPlugin) {
         this.expressionsPlugin.resetFrame();
       }
-
       this.renderer.renderFrame(this.currentFrame + this.firstFrame);
     } catch (error) {
       this.triggerRenderFrameError(error);
     }
   };
-
   AnimationItem.prototype.play = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.isPaused = false;
       this.trigger('_play');
       this.audioController.resume();
-
       if (this._idle) {
         this._idle = false;
         this.trigger('_active');
       }
     }
   };
-
   AnimationItem.prototype.pause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === false) {
       this.isPaused = true;
       this.trigger('_pause');
@@ -2092,54 +1759,42 @@
       this.audioController.pause();
     }
   };
-
   AnimationItem.prototype.togglePause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.play();
     } else {
       this.pause();
     }
   };
-
   AnimationItem.prototype.stop = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.pause();
     this.playCount = 0;
     this._completedLoop = false;
     this.setCurrentRawFrameValue(0);
   };
-
   AnimationItem.prototype.getMarkerData = function (markerName) {
     var marker;
-
     for (var i = 0; i < this.markers.length; i += 1) {
       marker = this.markers[i];
-
       if (marker.payload && marker.payload.name === markerName) {
         return marker;
       }
     }
-
     return null;
   };
-
   AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         this.goToAndStop(marker.time, true);
       }
@@ -2148,20 +1803,15 @@
     } else {
       this.setCurrentRawFrameValue(value * this.frameModifier);
     }
-
     this.pause();
   };
-
   AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         if (!marker.duration) {
           this.goToAndStop(marker.time, true);
@@ -2172,19 +1822,16 @@
     } else {
       this.goToAndStop(numValue, isFrame, name);
     }
-
     this.play();
   };
-
   AnimationItem.prototype.advanceTime = function (value) {
     if (this.isPaused === true || this.isLoaded === false) {
       return;
     }
-
     var nextValue = this.currentRawFrame + value * this.frameModifier;
-    var _isComplete = false; // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+    var _isComplete = false;
+    // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
     // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
-
     if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
       if (!this.loop || this.playCount === this.loop) {
         if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
@@ -2193,7 +1840,6 @@
         }
       } else if (nextValue >= this.totalFrames) {
         this.playCount += 1;
-
         if (!this.checkSegments(nextValue % this.totalFrames)) {
           this.setCurrentRawFrameValue(nextValue % this.totalFrames);
           this._completedLoop = true;
@@ -2207,7 +1853,6 @@
         if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) {
           // eslint-disable-line no-plusplus
           this.setCurrentRawFrameValue(this.totalFrames + nextValue % this.totalFrames);
-
           if (!this._completedLoop) {
             this._completedLoop = true;
           } else {
@@ -2221,17 +1866,14 @@
     } else {
       this.setCurrentRawFrameValue(nextValue);
     }
-
     if (_isComplete) {
       this.setCurrentRawFrameValue(nextValue);
       this.pause();
       this.trigger('complete');
     }
   };
-
   AnimationItem.prototype.adjustSegment = function (arr, offset) {
     this.playCount = 0;
-
     if (arr[1] < arr[0]) {
       if (this.frameModifier > 0) {
         if (this.playSpeed < 0) {
@@ -2240,7 +1882,6 @@
           this.setDirection(-1);
         }
       }
-
       this.totalFrames = arr[0] - arr[1];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[1];
@@ -2253,19 +1894,15 @@
           this.setDirection(1);
         }
       }
-
       this.totalFrames = arr[1] - arr[0];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[0];
       this.setCurrentRawFrameValue(0.001 + offset);
     }
-
     this.trigger('segmentStart');
   };
-
   AnimationItem.prototype.setSegment = function (init, end) {
     var pendingFrame = -1;
-
     if (this.isPaused) {
       if (this.currentRawFrame + this.firstFrame < init) {
         pendingFrame = init;
@@ -2273,64 +1910,51 @@
         pendingFrame = end - init;
       }
     }
-
     this.firstFrame = init;
     this.totalFrames = end - init;
     this.timeCompleted = this.totalFrames;
-
     if (pendingFrame !== -1) {
       this.goToAndStop(pendingFrame, true);
     }
   };
-
   AnimationItem.prototype.playSegments = function (arr, forceFlag) {
     if (forceFlag) {
       this.segments.length = 0;
     }
-
     if (_typeof$4(arr[0]) === 'object') {
       var i;
       var len = arr.length;
-
       for (i = 0; i < len; i += 1) {
         this.segments.push(arr[i]);
       }
     } else {
       this.segments.push(arr);
     }
-
     if (this.segments.length && forceFlag) {
       this.adjustSegment(this.segments.shift(), 0);
     }
-
     if (this.isPaused) {
       this.play();
     }
   };
-
   AnimationItem.prototype.resetSegments = function (forceFlag) {
     this.segments.length = 0;
     this.segments.push([this.animationData.ip, this.animationData.op]);
-
     if (forceFlag) {
       this.checkSegments(0);
     }
   };
-
   AnimationItem.prototype.checkSegments = function (offset) {
     if (this.segments.length) {
       this.adjustSegment(this.segments.shift(), offset);
       return true;
     }
-
     return false;
   };
-
   AnimationItem.prototype.destroy = function (name) {
     if (name && this.name !== name || !this.renderer) {
       return;
     }
-
     this.renderer.destroy();
     this.imagePreloader.destroy();
     this.trigger('destroy');
@@ -2345,189 +1969,148 @@
     this.imagePreloader = null;
     this.projectInterface = null;
   };
-
   AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
     this.currentRawFrame = value;
     this.gotoFrame();
   };
-
   AnimationItem.prototype.setSpeed = function (val) {
     this.playSpeed = val;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setDirection = function (val) {
     this.playDirection = val < 0 ? -1 : 1;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setLoop = function (isLooping) {
     this.loop = isLooping;
   };
-
   AnimationItem.prototype.setVolume = function (val, name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.setVolume(val);
   };
-
   AnimationItem.prototype.getVolume = function () {
     return this.audioController.getVolume();
   };
-
   AnimationItem.prototype.mute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.mute();
   };
-
   AnimationItem.prototype.unmute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.unmute();
   };
-
   AnimationItem.prototype.updaFrameModifier = function () {
     this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
     this.audioController.setRate(this.playSpeed * this.playDirection);
   };
-
   AnimationItem.prototype.getPath = function () {
     return this.path;
   };
-
   AnimationItem.prototype.getAssetsPath = function (assetData) {
     var path = '';
-
     if (assetData.e) {
       path = assetData.p;
     } else if (this.assetsPath) {
       var imagePath = assetData.p;
-
       if (imagePath.indexOf('images/') !== -1) {
         imagePath = imagePath.split('/')[1];
       }
-
       path = this.assetsPath + imagePath;
     } else {
       path = this.path;
       path += assetData.u ? assetData.u : '';
       path += assetData.p;
     }
-
     return path;
   };
-
   AnimationItem.prototype.getAssetData = function (id) {
     var i = 0;
     var len = this.assets.length;
-
     while (i < len) {
       if (id === this.assets[i].id) {
         return this.assets[i];
       }
-
       i += 1;
     }
-
     return null;
   };
-
   AnimationItem.prototype.hide = function () {
     this.renderer.hide();
   };
-
   AnimationItem.prototype.show = function () {
     this.renderer.show();
   };
-
   AnimationItem.prototype.getDuration = function (isFrame) {
     return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
   };
-
   AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
     try {
       var element = this.renderer.getElementByPath(path);
       element.updateDocumentData(documentData, index);
-    } catch (error) {// TODO: decide how to handle catch case
+    } catch (error) {
+      // TODO: decide how to handle catch case
     }
   };
-
   AnimationItem.prototype.trigger = function (name) {
     if (this._cbs && this._cbs[name]) {
       switch (name) {
         case 'enterFrame':
           this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
           break;
-
         case 'drawnFrame':
           this.drawnFrameEvent.currentTime = this.currentFrame;
           this.drawnFrameEvent.totalTime = this.totalFrames;
           this.drawnFrameEvent.direction = this.frameModifier;
           this.triggerEvent(name, this.drawnFrameEvent);
           break;
-
         case 'loopComplete':
           this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
           break;
-
         case 'complete':
           this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
           break;
-
         case 'segmentStart':
           this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
           break;
-
         case 'destroy':
           this.triggerEvent(name, new BMDestroyEvent(name, this));
           break;
-
         default:
           this.triggerEvent(name);
       }
     }
-
     if (name === 'enterFrame' && this.onEnterFrame) {
       this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
     }
-
     if (name === 'loopComplete' && this.onLoopComplete) {
       this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
     }
-
     if (name === 'complete' && this.onComplete) {
       this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
     }
-
     if (name === 'segmentStart' && this.onSegmentStart) {
       this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
     }
-
     if (name === 'destroy' && this.onDestroy) {
       this.onDestroy.call(this, new BMDestroyEvent(name, this));
     }
   };
-
   AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
     var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
   };
-
   AnimationItem.prototype.triggerConfigError = function (nativeError) {
     var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
@@ -2541,68 +2124,53 @@
     var playingAnimationsNum = 0;
     var _stopped = true;
     var _isFrozen = false;
-
     function removeElement(ev) {
       var i = 0;
       var animItem = ev.target;
-
       while (i < len) {
         if (registeredAnimations[i].animation === animItem) {
           registeredAnimations.splice(i, 1);
           i -= 1;
           len -= 1;
-
           if (!animItem.isPaused) {
             subtractPlayingCount();
           }
         }
-
         i += 1;
       }
     }
-
     function registerAnimation(element, animationData) {
       if (!element) {
         return null;
       }
-
       var i = 0;
-
       while (i < len) {
         if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
           return registeredAnimations[i].animation;
         }
-
         i += 1;
       }
-
       var animItem = new AnimationItem();
       setupAnimation(animItem, element);
       animItem.setData(element, animationData);
       return animItem;
     }
-
     function getRegisteredAnimations() {
       var i;
       var lenAnims = registeredAnimations.length;
       var animations = [];
-
       for (i = 0; i < lenAnims; i += 1) {
         animations.push(registeredAnimations[i].animation);
       }
-
       return animations;
     }
-
     function addPlayingCount() {
       playingAnimationsNum += 1;
       activate();
     }
-
     function subtractPlayingCount() {
       playingAnimationsNum -= 1;
     }
-
     function setupAnimation(animItem, element) {
       animItem.addEventListener('destroy', removeElement);
       animItem.addEventListener('_active', addPlayingCount);
@@ -2613,118 +2181,91 @@
       });
       len += 1;
     }
-
     function loadAnimation(params) {
       var animItem = new AnimationItem();
       setupAnimation(animItem, null);
       animItem.setParams(params);
       return animItem;
     }
-
     function setSpeed(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setSpeed(val, animation);
       }
     }
-
     function setDirection(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setDirection(val, animation);
       }
     }
-
     function play(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.play(animation);
       }
     }
-
     function resume(nowTime) {
       var elapsedTime = nowTime - initTime;
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.advanceTime(elapsedTime);
       }
-
       initTime = nowTime;
-
       if (playingAnimationsNum && !_isFrozen) {
         window.requestAnimationFrame(resume);
       } else {
         _stopped = true;
       }
     }
-
     function first(nowTime) {
       initTime = nowTime;
       window.requestAnimationFrame(resume);
     }
-
     function pause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.pause(animation);
       }
     }
-
     function goToAndStop(value, isFrame, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
       }
     }
-
     function stop(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.stop(animation);
       }
     }
-
     function togglePause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.togglePause(animation);
       }
     }
-
     function destroy(animation) {
       var i;
-
       for (i = len - 1; i >= 0; i -= 1) {
         registeredAnimations[i].animation.destroy(animation);
       }
     }
-
     function searchAnimations(animationData, standalone, renderer) {
       var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')), [].slice.call(document.getElementsByClassName('bodymovin')));
       var i;
       var lenAnims = animElements.length;
-
       for (i = 0; i < lenAnims; i += 1) {
         if (renderer) {
           animElements[i].setAttribute('data-bm-type', renderer);
         }
-
         registerAnimation(animElements[i], animationData);
       }
-
       if (standalone && lenAnims === 0) {
         if (!renderer) {
           renderer = 'svg';
         }
-
         var body = document.getElementsByTagName('body')[0];
         body.innerText = '';
         var div = createTag('div');
@@ -2735,15 +2276,12 @@
         registerAnimation(div, animationData);
       }
     }
-
     function resize() {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.resize();
       }
     }
-
     function activate() {
       if (!_isFrozen && playingAnimationsNum) {
         if (_stopped) {
@@ -2752,40 +2290,31 @@
         }
       }
     }
-
     function freeze() {
       _isFrozen = true;
     }
-
     function unfreeze() {
       _isFrozen = false;
       activate();
     }
-
     function setVolume(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setVolume(val, animation);
       }
     }
-
     function mute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.mute(animation);
       }
     }
-
     function unmute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.unmute(animation);
       }
     }
-
     moduleOb.registerAnimation = registerAnimation;
     moduleOb.loadAnimation = loadAnimation;
     moduleOb.setSpeed = setSpeed;
@@ -2795,8 +2324,8 @@
     moduleOb.stop = stop;
     moduleOb.togglePause = togglePause;
     moduleOb.searchAnimations = searchAnimations;
-    moduleOb.resize = resize; // moduleOb.start = start;
-
+    moduleOb.resize = resize;
+    // moduleOb.start = start;
     moduleOb.goToAndStop = goToAndStop;
     moduleOb.destroy = destroy;
     moduleOb.freeze = freeze;
@@ -2820,23 +2349,21 @@
        * spline.get(x) => returns the easing value | x must be in [0, 1] range
        *
        */
+
     var ob = {};
     ob.getBezierEasing = getBezierEasing;
     var beziers = {};
-
     function getBezierEasing(a, b, c, d, nm) {
       var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
-
       if (beziers[str]) {
         return beziers[str];
       }
-
       var bezEasing = new BezierEasing([a, b, c, d]);
       beziers[str] = bezEasing;
       return bezEasing;
-    } // These values are established by empiricism with tests (tradeoff: performance VS precision)
+    }
 
-
+    // These values are established by empiricism with tests (tradeoff: performance VS precision)
     var NEWTON_ITERATIONS = 4;
     var NEWTON_MIN_SLOPE = 0.001;
     var SUBDIVISION_PRECISION = 0.0000001;
@@ -2844,48 +2371,40 @@
     var kSplineTableSize = 11;
     var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
     var float32ArraySupported = typeof Float32Array === 'function';
-
     function A(aA1, aA2) {
       return 1.0 - 3.0 * aA2 + 3.0 * aA1;
     }
-
     function B(aA1, aA2) {
       return 3.0 * aA2 - 6.0 * aA1;
     }
-
     function C(aA1) {
       return 3.0 * aA1;
-    } // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+    }
 
-
+    // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
     function calcBezier(aT, aA1, aA2) {
       return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
-    } // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+    }
 
-
+    // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
     function getSlope(aT, aA1, aA2) {
       return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
     }
-
     function binarySubdivide(aX, aA, aB, mX1, mX2) {
       var currentX,
-          currentT,
-          i = 0;
-
+        currentT,
+        i = 0;
       do {
         currentT = aA + (aB - aA) / 2.0;
         currentX = calcBezier(currentT, mX1, mX2) - aX;
-
         if (currentX > 0.0) {
           aB = currentT;
         } else {
           aA = currentT;
         }
       } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
-
       return currentT;
     }
-
     function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
       for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
         var currentSlope = getSlope(aGuessT, mX1, mX2);
@@ -2893,85 +2412,75 @@
         var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
         aGuessT -= currentX / currentSlope;
       }
-
       return aGuessT;
     }
+
     /**
        * points is an array of [ mX1, mY1, mX2, mY2 ]
        */
-
-
     function BezierEasing(points) {
       this._p = points;
       this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
       this._precomputed = false;
       this.get = this.get.bind(this);
     }
-
     BezierEasing.prototype = {
       get: function get(x) {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         if (!this._precomputed) this._precompute();
         if (mX1 === mY1 && mX2 === mY2) return x; // linear
         // Because JavaScript number are imprecise, we should guarantee the extremes are right.
-
         if (x === 0) return 0;
         if (x === 1) return 1;
         return calcBezier(this._getTForX(x), mY1, mY2);
       },
       // Private part
+
       _precompute: function _precompute() {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         this._precomputed = true;
-
         if (mX1 !== mY1 || mX2 !== mY2) {
           this._calcSampleValues();
         }
       },
       _calcSampleValues: function _calcSampleValues() {
         var mX1 = this._p[0],
-            mX2 = this._p[2];
-
+          mX2 = this._p[2];
         for (var i = 0; i < kSplineTableSize; ++i) {
           this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
         }
       },
-
       /**
            * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
            */
       _getTForX: function _getTForX(aX) {
         var mX1 = this._p[0],
-            mX2 = this._p[2],
-            mSampleValues = this._mSampleValues;
+          mX2 = this._p[2],
+          mSampleValues = this._mSampleValues;
         var intervalStart = 0.0;
         var currentSample = 1;
         var lastSample = kSplineTableSize - 1;
-
         for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
           intervalStart += kSampleStepSize;
         }
+        --currentSample;
 
-        --currentSample; // Interpolate to provide an initial guess for t
-
+        // Interpolate to provide an initial guess for t
         var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
         var guessForT = intervalStart + dist * kSampleStepSize;
         var initialSlope = getSlope(guessForT, mX1, mX2);
-
         if (initialSlope >= NEWTON_MIN_SLOPE) {
           return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
         }
-
         if (initialSlope === 0.0) {
           return guessForT;
         }
-
         return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
       }
     };
@@ -2982,7 +2491,6 @@
     function _double(arr) {
       return arr.concat(createSizedArray(arr.length));
     }
-
     return {
       "double": _double
     };
@@ -2997,34 +2505,27 @@
         newElement: newElement,
         release: release
       };
-
       function newElement() {
         var element;
-
         if (_length) {
           _length -= 1;
           element = pool[_length];
         } else {
           element = _create();
         }
-
         return element;
       }
-
       function release(element) {
         if (_length === _maxLength) {
           pool = pooling["double"](pool);
           _maxLength *= 2;
         }
-
         if (_release) {
           _release(element);
         }
-
         pool[_length] = element;
         _length += 1;
       }
-
       return ob;
     };
   }();
@@ -3037,7 +2538,6 @@
         lengths: createTypedArray('float32', getDefaultCurveSegments())
       };
     }
-
     return poolFactory(8, create);
   }();
 
@@ -3048,39 +2548,31 @@
         totalLength: 0
       };
     }
-
     function release(element) {
       var i;
       var len = element.lengths.length;
-
       for (i = 0; i < len; i += 1) {
         bezierLengthPool.release(element.lengths[i]);
       }
-
       element.lengths.length = 0;
     }
-
     return poolFactory(8, create, release);
   }();
 
   function bezFunction() {
     var math = Math;
-
     function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
       var det1 = x1 * y2 + y1 * x3 + x2 * y3 - x3 * y2 - y3 * x1 - x2 * y1;
       return det1 > -0.001 && det1 < 0.001;
     }
-
     function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
       if (z1 === 0 && z2 === 0 && z3 === 0) {
         return pointOnLine2D(x1, y1, x2, y2, x3, y3);
       }
-
       var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
       var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
       var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
       var diffDist;
-
       if (dist1 > dist2) {
         if (dist1 > dist3) {
           diffDist = dist1 - dist2 - dist3;
@@ -3092,10 +2584,8 @@
       } else {
         diffDist = dist2 - dist1 - dist3;
       }
-
       return diffDist > -0.0001 && diffDist < 0.0001;
     }
-
     var getBezierLength = function () {
       return function (pt1, pt2, pt3, pt4) {
         var curveSegments = getDefaultCurveSegments();
@@ -3110,36 +2600,28 @@
         var lastPoint = [];
         var lengthData = bezierLengthPool.newElement();
         len = pt3.length;
-
         for (k = 0; k < curveSegments; k += 1) {
           perc = k / (curveSegments - 1);
           ptDistance = 0;
-
           for (i = 0; i < len; i += 1) {
             ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
             point[i] = ptCoord;
-
             if (lastPoint[i] !== null) {
               ptDistance += bmPow(point[i] - lastPoint[i], 2);
             }
-
             lastPoint[i] = point[i];
           }
-
           if (ptDistance) {
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
           }
-
           lengthData.percents[k] = perc;
           lengthData.lengths[k] = addedLength;
         }
-
         lengthData.addedLength = addedLength;
         return lengthData;
       };
     }();
-
     function getSegmentsLength(shapeData) {
       var segmentsLength = segmentsLengthPool.newElement();
       var closed = shapeData.c;
@@ -3150,36 +2632,29 @@
       var len = shapeData._length;
       var lengths = segmentsLength.lengths;
       var totalLength = 0;
-
       for (i = 0; i < len - 1; i += 1) {
         lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
         totalLength += lengths[i].addedLength;
       }
-
       if (closed && len) {
         lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
         totalLength += lengths[i].addedLength;
       }
-
       segmentsLength.totalLength = totalLength;
       return segmentsLength;
     }
-
     function BezierData(length) {
       this.segmentLength = 0;
       this.points = new Array(length);
     }
-
     function PointData(partial, point) {
       this.partialLength = partial;
       this.point = point;
     }
-
     var buildBezierData = function () {
       var storedData = {};
       return function (pt1, pt2, pt3, pt4) {
         var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
-
         if (!storedData[bezierName]) {
           var curveSegments = getDefaultCurveSegments();
           var k;
@@ -3191,42 +2666,33 @@
           var ptDistance;
           var point;
           var lastPoint = null;
-
           if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
             curveSegments = 2;
           }
-
           var bezierData = new BezierData(curveSegments);
           len = pt3.length;
-
           for (k = 0; k < curveSegments; k += 1) {
             point = createSizedArray(len);
             perc = k / (curveSegments - 1);
             ptDistance = 0;
-
             for (i = 0; i < len; i += 1) {
               ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
               point[i] = ptCoord;
-
               if (lastPoint !== null) {
                 ptDistance += bmPow(point[i] - lastPoint[i], 2);
               }
             }
-
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
             bezierData.points[k] = new PointData(ptDistance, point);
             lastPoint = point;
           }
-
           bezierData.segmentLength = addedLength;
           storedData[bezierName] = bezierData;
         }
-
         return storedData[bezierName];
       };
     }();
-
     function getDistancePerc(perc, bezierData) {
       var percents = bezierData.percents;
       var lengths = bezierData.lengths;
@@ -3234,14 +2700,11 @@
       var initPos = bmFloor((len - 1) * perc);
       var lengthPos = perc * bezierData.addedLength;
       var lPerc = 0;
-
       if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
         return percents[initPos];
       }
-
       var dir = lengths[initPos] > lengthPos ? -1 : 1;
       var flag = true;
-
       while (flag) {
         if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
           lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
@@ -3249,20 +2712,16 @@
         } else {
           initPos += dir;
         }
-
         if (initPos < 0 || initPos >= len - 1) {
           // FIX for TypedArrays that don't store floating point values with enough accuracy
           if (initPos === len - 1) {
             return percents[initPos];
           }
-
           flag = false;
         }
       }
-
       return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
     }
-
     function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
       var t1 = getDistancePerc(percent, bezierData);
       var u1 = 1 - t1;
@@ -3270,16 +2729,13 @@
       var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
       return [ptX, ptY];
     }
-
     var bezierSegmentPoints = createTypedArray('float32', 8);
-
     function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
       if (startPerc < 0) {
         startPerc = 0;
       } else if (startPerc > 1) {
         startPerc = 1;
       }
-
       var t0 = getDistancePerc(startPerc, bezierData);
       endPerc = endPerc > 1 ? 1 : endPerc;
       var t1 = getDistancePerc(endPerc, bezierData);
@@ -3289,45 +2745,31 @@
       var u1 = 1 - t1;
       var u0u0u0 = u0 * u0 * u0;
       var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
-
       var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
-
-      var t0t0t0 = t0 * t0 * t0; //
-
+      var t0t0t0 = t0 * t0 * t0;
+      //
       var u0u0u1 = u0 * u0 * u1;
       var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
-
       var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
-
-      var t0t0t1 = t0 * t0 * t1; //
-
+      var t0t0t1 = t0 * t0 * t1;
+      //
       var u0u1u1 = u0 * u1 * u1;
       var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
-
       var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
-
-      var t0t1t1 = t0 * t1 * t1; //
-
+      var t0t1t1 = t0 * t1 * t1;
+      //
       var u1u1u1 = u1 * u1 * u1;
       var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1t1 = t1 * t1 * t1;
-
       for (i = 0; i < len; i += 1) {
         bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
       }
-
       return bezierSegmentPoints;
     }
-
     return {
       getSegmentsLength: getSegmentsLength,
       getNewSegment: getNewSegment,
@@ -3337,20 +2779,16 @@
       pointOnLine3D: pointOnLine3D
     };
   }
-
   var bez = bezFunction();
 
   var initFrame = initialDefaultFrame;
   var mathAbs = Math.abs;
-
   function interpolateValue(frameNum, caching) {
     var offsetTime = this.offsetTime;
     var newValue;
-
     if (this.propType === 'multidimensional') {
       newValue = createTypedArray('float32', this.pv.length);
     }
-
     var iterationIndex = caching.lastIndex;
     var i = iterationIndex;
     var len = this.keyframes.length - 1;
@@ -3358,25 +2796,20 @@
     var keyData;
     var nextKeyData;
     var keyframeMetadata;
-
     while (flag) {
       keyData = this.keyframes[i];
       nextKeyData = this.keyframes[i + 1];
-
       if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
         if (keyData.h) {
           keyData = nextKeyData;
         }
-
         iterationIndex = 0;
         break;
       }
-
       if (nextKeyData.t - offsetTime > frameNum) {
         iterationIndex = i;
         break;
       }
-
       if (i < len - 1) {
         i += 1;
       } else {
@@ -3384,7 +2817,6 @@
         flag = false;
       }
     }
-
     keyframeMetadata = this.keyframesMetadata[i] || {};
     var k;
     var kLen;
@@ -3395,22 +2827,18 @@
     var nextKeyTime = nextKeyData.t - offsetTime;
     var keyTime = keyData.t - offsetTime;
     var endValue;
-
     if (keyData.to) {
       if (!keyframeMetadata.bezierData) {
         keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
       }
-
       var bezierData = keyframeMetadata.bezierData;
-
       if (frameNum >= nextKeyTime || frameNum < keyTime) {
         var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
         kLen = bezierData.points[ind].point.length;
-
         for (k = 0; k < kLen; k += 1) {
           newValue[k] = bezierData.points[ind].point[k];
-        } // caching._lastKeyframeIndex = -1;
-
+        }
+        // caching._lastKeyframeIndex = -1;
       } else {
         if (keyframeMetadata.__fnct) {
           fnc = keyframeMetadata.__fnct;
@@ -3418,7 +2846,6 @@
           fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
           keyframeMetadata.__fnct = fnc;
         }
-
         perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
         var distanceInLine = bezierData.segmentLength * perc;
         var segmentPerc;
@@ -3426,36 +2853,28 @@
         j = caching.lastFrame < frameNum && caching._lastKeyframeIndex === i ? caching._lastPoint : 0;
         flag = true;
         jLen = bezierData.points.length;
-
         while (flag) {
           addedLength += bezierData.points[j].partialLength;
-
           if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k];
             }
-
             break;
           } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
             segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
             }
-
             break;
           }
-
           if (j < jLen - 1) {
             j += 1;
           } else {
             flag = false;
           }
         }
-
         caching._lastPoint = j;
         caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
         caching._lastKeyframeIndex = i;
@@ -3468,7 +2887,6 @@
       var keyValue;
       len = keyData.s.length;
       endValue = nextKeyData.s || keyData.e;
-
       if (this.sh && keyData.h !== 1) {
         if (frameNum >= nextKeyTime) {
           newValue[0] = endValue[0];
@@ -3496,7 +2914,6 @@
                 if (!keyframeMetadata.__fnct) {
                   keyframeMetadata.__fnct = [];
                 }
-
                 if (!keyframeMetadata.__fnct[i]) {
                   outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
                   outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
@@ -3517,14 +2934,11 @@
               } else {
                 fnc = keyframeMetadata.__fnct;
               }
-
               perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
             }
           }
-
           endValue = nextKeyData.s || keyData.e;
           keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
-
           if (this.propType === 'multidimensional') {
             newValue[i] = keyValue;
           } else {
@@ -3533,12 +2947,11 @@
         }
       }
     }
-
     caching.lastIndex = iterationIndex;
     return newValue;
-  } // based on @Toji's https://github.com/toji/gl-matrix/
+  }
 
-
+  // based on @Toji's https://github.com/toji/gl-matrix/
   function slerp(a, b, t) {
     var out = [];
     var ax = a[0];
@@ -3555,7 +2968,6 @@
     var scale0;
     var scale1;
     cosom = ax * bx + ay * by + az * bz + aw * bw;
-
     if (cosom < 0.0) {
       cosom = -cosom;
       bx = -bx;
@@ -3563,7 +2975,6 @@
       bz = -bz;
       bw = -bw;
     }
-
     if (1.0 - cosom > 0.000001) {
       omega = Math.acos(cosom);
       sinom = Math.sin(omega);
@@ -3573,14 +2984,12 @@
       scale0 = 1.0 - t;
       scale1 = t;
     }
-
     out[0] = scale0 * ax + scale1 * bx;
     out[1] = scale0 * ay + scale1 * by;
     out[2] = scale0 * az + scale1 * bz;
     out[3] = scale0 * aw + scale1 * bw;
     return out;
   }
-
   function quaternionToEuler(out, quat) {
     var qx = quat[0];
     var qy = quat[1];
@@ -3593,7 +3002,6 @@
     out[1] = attitude / degToRads;
     out[2] = bank / degToRads;
   }
-
   function createQuaternion(values) {
     var heading = values[0] * degToRads;
     var attitude = values[1] * degToRads;
@@ -3610,32 +3018,25 @@
     var z = c1 * s2 * c3 - s1 * c2 * s3;
     return [x, y, z, w];
   }
-
   function getValueAtCurrentTime() {
     var frameNum = this.comp.renderedFrame - this.offsetTime;
     var initTime = this.keyframes[0].t - this.offsetTime;
     var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
-
     if (!(frameNum === this._caching.lastFrame || this._caching.lastFrame !== initFrame && (this._caching.lastFrame >= endTime && frameNum >= endTime || this._caching.lastFrame < initTime && frameNum < initTime))) {
       if (this._caching.lastFrame >= frameNum) {
         this._caching._lastKeyframeIndex = -1;
         this._caching.lastIndex = 0;
       }
-
       var renderResult = this.interpolateValue(frameNum, this._caching);
       this.pv = renderResult;
     }
-
     this._caching.lastFrame = frameNum;
     return this.pv;
   }
-
   function setVValue(val) {
     var multipliedValue;
-
     if (this.propType === 'unidimensional') {
       multipliedValue = val * this.mult;
-
       if (mathAbs(this.v - multipliedValue) > 0.00001) {
         this.v = multipliedValue;
         this._mdf = true;
@@ -3643,51 +3044,41 @@
     } else {
       var i = 0;
       var len = this.v.length;
-
       while (i < len) {
         multipliedValue = val[i] * this.mult;
-
         if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
           this.v[i] = multipliedValue;
           this._mdf = true;
         }
-
         i += 1;
       }
     }
   }
-
   function processEffectsSequence() {
     if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
       return;
     }
-
     if (this.lock) {
       this.setVValue(this.pv);
       return;
     }
-
     this.lock = true;
     this._mdf = this._isFirstFrame;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = this.kf ? this.pv : this.data.k;
-
     for (i = 0; i < len; i += 1) {
       finalValue = this.effectsSequence[i](finalValue);
     }
-
     this.setVValue(finalValue);
     this._isFirstFrame = false;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   }
-
   function addEffect(effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.container.addDynamicProperty(this);
   }
-
   function ValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.mult = mult || 1;
@@ -3707,7 +3098,6 @@
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function MultiDimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     this.mult = mult || 1;
@@ -3724,19 +3114,16 @@
     this.v = createTypedArray('float32', len);
     this.pv = createTypedArray('float32', len);
     this.vel = createTypedArray('float32', len);
-
     for (i = 0; i < len; i += 1) {
       this.v[i] = data.k[i] * this.mult;
       this.pv[i] = data.k[i];
     }
-
     this._isFirstFrame = true;
     this.effectsSequence = [];
     this.getValue = processEffectsSequence;
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function KeyframedValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.keyframes = data.k;
@@ -3765,7 +3152,6 @@
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.addEffect = addEffect;
   }
-
   function KeyframedMultidimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     var i;
@@ -3774,19 +3160,16 @@
     var e;
     var to;
     var ti;
-
     for (i = 0; i < len - 1; i += 1) {
       if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
         s = data.k[i].s;
         e = data.k[i + 1].s;
         to = data.k[i].to;
         ti = data.k[i].ti;
-
         if (s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1]) || s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2])) {
           data.k[i].to = null;
           data.k[i].ti = null;
         }
-
         if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
           if (s.length === 2 || s[2] === e[2] && to[2] === 0 && ti[2] === 0) {
             data.k[i].to = null;
@@ -3795,7 +3178,6 @@
         }
       }
     }
-
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.data = data;
     this.keyframes = data.k;
@@ -3815,12 +3197,10 @@
     var arrLen = data.k[0].s.length;
     this.v = createTypedArray('float32', arrLen);
     this.pv = createTypedArray('float32', arrLen);
-
     for (i = 0; i < arrLen; i += 1) {
       this.v[i] = initFrame;
       this.pv[i] = initFrame;
     }
-
     this._caching = {
       lastFrame: initFrame,
       lastIndex: 0,
@@ -3828,15 +3208,12 @@
     };
     this.addEffect = addEffect;
   }
-
   var PropertyFactory = function () {
     function getProp(elem, data, type, mult, container) {
       if (data.sid) {
         data = elem.globalData.slotManager.getProp(data);
       }
-
       var p;
-
       if (!data.k.length) {
         p = new ValueProperty(elem, data, mult, container);
       } else if (typeof data.k[0] === 'number') {
@@ -3846,23 +3223,18 @@
           case 0:
             p = new KeyframedValueProperty(elem, data, mult, container);
             break;
-
           case 1:
             p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
             break;
-
           default:
             break;
         }
       }
-
       if (p.effectsSequence.length) {
         container.addDynamicProperty(p);
       }
-
       return p;
     }
-
     var ob = {
       getProp: getProp
     };
@@ -3870,7 +3242,6 @@
   }();
 
   function DynamicPropertyContainer() {}
-
   DynamicPropertyContainer.prototype = {
     addDynamicProperty: function addDynamicProperty(prop) {
       if (this.dynamicProperties.indexOf(prop) === -1) {
@@ -3883,10 +3254,8 @@
       this._mdf = false;
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         this.dynamicProperties[i].getValue();
-
         if (this.dynamicProperties[i]._mdf) {
           this._mdf = true;
         }
@@ -3904,7 +3273,6 @@
     function create() {
       return createTypedArray('float32', 2);
     }
-
     return poolFactory(8, create);
   }();
 
@@ -3916,12 +3284,10 @@
     this.o = createSizedArray(this._maxLength);
     this.i = createSizedArray(this._maxLength);
   }
-
   ShapePath.prototype.setPathData = function (closed, len) {
     this.c = closed;
     this.setLength(len);
     var i = 0;
-
     while (i < len) {
       this.v[i] = pointPool.newElement();
       this.o[i] = pointPool.newElement();
@@ -3929,62 +3295,49 @@
       i += 1;
     }
   };
-
   ShapePath.prototype.setLength = function (len) {
     while (this._maxLength < len) {
       this.doubleArrayLength();
     }
-
     this._length = len;
   };
-
   ShapePath.prototype.doubleArrayLength = function () {
     this.v = this.v.concat(createSizedArray(this._maxLength));
     this.i = this.i.concat(createSizedArray(this._maxLength));
     this.o = this.o.concat(createSizedArray(this._maxLength));
     this._maxLength *= 2;
   };
-
   ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
     var arr;
     this._length = Math.max(this._length, pos + 1);
-
     if (this._length >= this._maxLength) {
       this.doubleArrayLength();
     }
-
     switch (type) {
       case 'v':
         arr = this.v;
         break;
-
       case 'i':
         arr = this.i;
         break;
-
       case 'o':
         arr = this.o;
         break;
-
       default:
         arr = [];
         break;
     }
-
     if (!arr[pos] || arr[pos] && !replace) {
       arr[pos] = pointPool.newElement();
     }
-
     arr[pos][0] = x;
     arr[pos][1] = y;
   };
-
   ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
     this.setXYAt(vX, vY, 'v', pos, replace);
     this.setXYAt(oX, oY, 'o', pos, replace);
     this.setXYAt(iX, iY, 'i', pos, replace);
   };
-
   ShapePath.prototype.reverse = function () {
     var newPath = new ShapePath();
     newPath.setPathData(this.c, this._length);
@@ -3992,24 +3345,19 @@
     var outPoints = this.o;
     var inPoints = this.i;
     var init = 0;
-
     if (this.c) {
       newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
       init = 1;
     }
-
     var cnt = this._length - 1;
     var len = this._length;
     var i;
-
     for (i = init; i < len; i += 1) {
       newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
       cnt -= 1;
     }
-
     return newPath;
   };
-
   ShapePath.prototype.length = function () {
     return this._length;
   };
@@ -4018,11 +3366,9 @@
     function create() {
       return new ShapePath();
     }
-
     function release(shapePath) {
       var len = shapePath._length;
       var i;
-
       for (i = 0; i < len; i += 1) {
         pointPool.release(shapePath.v[i]);
         pointPool.release(shapePath.i[i]);
@@ -4031,25 +3377,20 @@
         shapePath.i[i] = null;
         shapePath.o[i] = null;
       }
-
       shapePath._length = 0;
       shapePath.c = false;
     }
-
     function clone(shape) {
       var cloned = factory.newElement();
       var i;
       var len = shape._length === undefined ? shape.v.length : shape._length;
       cloned.setLength(len);
       cloned.c = shape.c;
-
       for (i = 0; i < len; i += 1) {
         cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
       }
-
       return cloned;
     }
-
     var factory = poolFactory(4, create, release);
     factory.clone = clone;
     return factory;
@@ -4060,24 +3401,19 @@
     this._maxLength = 4;
     this.shapes = createSizedArray(this._maxLength);
   }
-
   ShapeCollection.prototype.addShape = function (shapeData) {
     if (this._length === this._maxLength) {
       this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
       this._maxLength *= 2;
     }
-
     this.shapes[this._length] = shapeData;
     this._length += 1;
   };
-
   ShapeCollection.prototype.releaseShapes = function () {
     var i;
-
     for (i = 0; i < this._length; i += 1) {
       shapePool.release(this.shapes[i]);
     }
-
     this._length = 0;
   };
 
@@ -4089,45 +3425,35 @@
     var _length = 0;
     var _maxLength = 4;
     var pool = createSizedArray(_maxLength);
-
     function newShapeCollection() {
       var shapeCollection;
-
       if (_length) {
         _length -= 1;
         shapeCollection = pool[_length];
       } else {
         shapeCollection = new ShapeCollection();
       }
-
       return shapeCollection;
     }
-
     function release(shapeCollection) {
       var i;
       var len = shapeCollection._length;
-
       for (i = 0; i < len; i += 1) {
         shapePool.release(shapeCollection.shapes[i]);
       }
-
       shapeCollection._length = 0;
-
       if (_length === _maxLength) {
         pool = pooling["double"](pool);
         _maxLength *= 2;
       }
-
       pool[_length] = shapeCollection;
       _length += 1;
     }
-
     return ob;
   }();
 
   var ShapePropertyFactory = function () {
     var initFrame = -999999;
-
     function interpolateShape(frameNum, previousValue, caching) {
       var iterationIndex = caching.lastIndex;
       var keyPropS;
@@ -4140,7 +3466,6 @@
       var perc;
       var vertexValue;
       var kf = this.keyframes;
-
       if (frameNum < kf[0].t - this.offsetTime) {
         keyPropS = kf[0].s[0];
         isHold = true;
@@ -4152,7 +3477,6 @@
               }else{
                   keyPropS = kf[kf.length - 2].e[0];
               } */
-
         isHold = true;
       } else {
         var i = iterationIndex;
@@ -4161,26 +3485,21 @@
         var keyData;
         var nextKeyData;
         var keyframeMetadata;
-
         while (flag) {
           keyData = kf[i];
           nextKeyData = kf[i + 1];
-
           if (nextKeyData.t - this.offsetTime > frameNum) {
             break;
           }
-
           if (i < len - 1) {
             i += 1;
           } else {
             flag = false;
           }
         }
-
         keyframeMetadata = this.keyframesMetadata[i] || {};
         isHold = keyData.h === 1;
         iterationIndex = i;
-
         if (!isHold) {
           if (frameNum >= nextKeyData.t - this.offsetTime) {
             perc = 1;
@@ -4188,27 +3507,21 @@
             perc = 0;
           } else {
             var fnc;
-
             if (keyframeMetadata.__fnct) {
               fnc = keyframeMetadata.__fnct;
             } else {
               fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
               keyframeMetadata.__fnct = fnc;
             }
-
             perc = fnc((frameNum - (keyData.t - this.offsetTime)) / (nextKeyData.t - this.offsetTime - (keyData.t - this.offsetTime)));
           }
-
           keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
         }
-
         keyPropS = keyData.s[0];
       }
-
       jLen = previousValue._length;
       kLen = keyPropS.i[0].length;
       caching.lastIndex = iterationIndex;
-
       for (j = 0; j < jLen; j += 1) {
         for (k = 0; k < kLen; k += 1) {
           vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
@@ -4220,44 +3533,36 @@
         }
       }
     }
-
     function interpolateShapeCurrentTime() {
       var frameNum = this.comp.renderedFrame - this.offsetTime;
       var initTime = this.keyframes[0].t - this.offsetTime;
       var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
       var lastFrame = this._caching.lastFrame;
-
       if (!(lastFrame !== initFrame && (lastFrame < initTime && frameNum < initTime || lastFrame > endTime && frameNum > endTime))) {
         /// /
         this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
-        this.interpolateShape(frameNum, this.pv, this._caching); /// /
+        this.interpolateShape(frameNum, this.pv, this._caching);
+        /// /
       }
-
       this._caching.lastFrame = frameNum;
       return this.pv;
     }
-
     function resetShape() {
       this.paths = this.localShapeCollection;
     }
-
     function shapesEqual(shape1, shape2) {
       if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
         return false;
       }
-
       var i;
       var len = shape1._length;
-
       for (i = 0; i < len; i += 1) {
         if (shape1.v[i][0] !== shape2.v[i][0] || shape1.v[i][1] !== shape2.v[i][1] || shape1.o[i][0] !== shape2.o[i][0] || shape1.o[i][1] !== shape2.o[i][1] || shape1.i[i][0] !== shape2.i[i][0] || shape1.i[i][1] !== shape2.i[i][1]) {
           return false;
         }
       }
-
       return true;
     }
-
     function setVValue(newPath) {
       if (!shapesEqual(this.v, newPath)) {
         this.v = shapePool.clone(newPath);
@@ -4267,26 +3572,21 @@
         this.paths = this.localShapeCollection;
       }
     }
-
     function processEffectsSequence() {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (!this.effectsSequence.length) {
         this._mdf = false;
         return;
       }
-
       if (this.lock) {
         this.setVValue(this.pv);
         return;
       }
-
       this.lock = true;
       this._mdf = false;
       var finalValue;
-
       if (this.kf) {
         finalValue = this.pv;
       } else if (this.data.ks) {
@@ -4294,19 +3594,15 @@
       } else {
         finalValue = this.data.pt.k;
       }
-
       var i;
       var len = this.effectsSequence.length;
-
       for (i = 0; i < len; i += 1) {
         finalValue = this.effectsSequence[i](finalValue);
       }
-
       this.setVValue(finalValue);
       this.lock = false;
       this.frameId = this.elem.globalData.frameId;
     }
-
     function ShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4325,17 +3621,14 @@
       this.reset = resetShape;
       this.effectsSequence = [];
     }
-
     function addEffect(effectFunction) {
       this.effectsSequence.push(effectFunction);
       this.container.addDynamicProperty(this);
     }
-
     ShapeProperty.prototype.interpolateShape = interpolateShape;
     ShapeProperty.prototype.getValue = processEffectsSequence;
     ShapeProperty.prototype.setVValue = setVValue;
     ShapeProperty.prototype.addEffect = addEffect;
-
     function KeyframedShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4361,15 +3654,12 @@
       };
       this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
     }
-
     KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
     KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
     KeyframedShapeProperty.prototype.setVValue = setVValue;
     KeyframedShapeProperty.prototype.addEffect = addEffect;
-
     var EllShapeProperty = function () {
       var cPoint = roundCorner;
-
       function EllShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
         this.v.setPathData(true, 4);
@@ -4383,7 +3673,6 @@
         this.initDynamicPropertyContainer(elem);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4391,17 +3680,14 @@
           this.convertEllToPath();
         }
       }
-
       EllShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertEllToPath();
           }
@@ -4411,9 +3697,7 @@
           var p1 = this.p.v[1];
           var s0 = this.s.v[0] / 2;
           var s1 = this.s.v[1] / 2;
-
           var _cw = this.d !== 3;
-
           var _v = this.v;
           _v.v[0][0] = p0;
           _v.v[0][1] = p1 - s1;
@@ -4444,7 +3728,6 @@
       extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
       return EllShapePropertyFactory;
     }();
-
     var StarShapeProperty = function () {
       function StarShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4455,7 +3738,6 @@
         this.frameId = -1;
         this.d = data.d;
         this.initDynamicPropertyContainer(elem);
-
         if (data.sy === 1) {
           this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
           this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
@@ -4463,7 +3745,6 @@
         } else {
           this.convertToPath = this.convertPolygonToPath;
         }
-
         this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
@@ -4472,7 +3753,6 @@
         this.localShapeCollection = shapeCollectionPool.newShapeCollection();
         this.localShapeCollection.addShape(this.v);
         this.paths = this.localShapeCollection;
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4480,17 +3760,14 @@
           this.convertToPath();
         }
       }
-
       StarShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertToPath();
           }
@@ -4501,7 +3778,6 @@
           /* this.v.v.length = numPts;
                   this.v.i.length = numPts;
                   this.v.o.length = numPts; */
-
           var longFlag = true;
           var longRad = this.or.v;
           var shortRad = this.ir.v;
@@ -4517,7 +3793,6 @@
           currentAng += this.r.v;
           var dir = this.data.d === 3 ? -1 : 1;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             rad = longFlag ? longRad : shortRad;
             roundness = longFlag ? longRound : shortRound;
@@ -4529,11 +3804,11 @@
             x += +this.p.v[0];
             y += +this.p.v[1];
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
             /* this.v.v[i] = [x,y];
                       this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
                       this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
                       this.v._length = numPts; */
-
             longFlag = !longFlag;
             currentAng += angle * dir;
           }
@@ -4549,7 +3824,6 @@
           var dir = this.data.d === 3 ? -1 : 1;
           currentAng += this.r.v;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             var x = rad * Math.cos(currentAng);
             var y = rad * Math.sin(currentAng);
@@ -4560,7 +3834,6 @@
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
             currentAng += angle * dir;
           }
-
           this.paths.length = 0;
           this.paths[0] = this.v;
         }
@@ -4568,7 +3841,6 @@
       extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
       return StarShapePropertyFactory;
     }();
-
     var RectShapeProperty = function () {
       function RectShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4584,7 +3856,6 @@
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4592,7 +3863,6 @@
           this.convertRectToPath();
         }
       }
-
       RectShapePropertyFactory.prototype = {
         convertRectToPath: function convertRectToPath() {
           var p0 = this.p.v[0];
@@ -4602,11 +3872,9 @@
           var round = bmMin(v0, v1, this.r.v);
           var cPoint = round * (1 - roundCorner);
           this.v._length = 0;
-
           if (this.d === 2 || this.d === 1) {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
             this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
               this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
@@ -4620,7 +3888,6 @@
             }
           } else {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
               this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
@@ -4640,10 +3907,8 @@
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertRectToPath();
           }
@@ -4653,14 +3918,11 @@
       extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
       return RectShapePropertyFactory;
     }();
-
     function getShapeProp(elem, data, type) {
       var prop;
-
       if (type === 3 || type === 4) {
         var dataProp = type === 3 ? data.pt : data.ks;
         var keys = dataProp.k;
-
         if (keys.length) {
           prop = new KeyframedShapeProperty(elem, data, type);
         } else {
@@ -4673,22 +3935,17 @@
       } else if (type === 7) {
         prop = new StarShapeProperty(elem, data);
       }
-
       if (prop.k) {
         elem.addDynamicProperty(prop);
       }
-
       return prop;
     }
-
     function getConstructorFunction() {
       return ShapeProperty;
     }
-
     function getKeyframedConstructorFunction() {
       return KeyframedShapeProperty;
     }
-
     var ob = {};
     ob.getShapeProp = getShapeProp;
     ob.getConstructorFunction = getConstructorFunction;
@@ -4730,7 +3987,6 @@
     var _sin = Math.sin;
     var _tan = Math.tan;
     var _rnd = Math.round;
-
     function reset() {
       this.props[0] = 1;
       this.props[1] = 0;
@@ -4750,83 +4006,59 @@
       this.props[15] = 1;
       return this;
     }
-
     function rotate(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function rotateX(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateY(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateZ(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function shear(sx, sy) {
       return this._t(1, sy, sx, 1, 0, 0);
     }
-
     function skew(ax, ay) {
       return this.shear(_tan(ax), _tan(ay));
     }
-
     function skewFromAxis(ax, angle) {
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
-      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+      // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
     }
-
     function scale(sx, sy, sz) {
       if (!sz && sz !== 0) {
         sz = 1;
       }
-
       if (sx === 1 && sy === 1 && sz === 1) {
         return this;
       }
-
       return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
     }
-
     function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
       this.props[0] = a;
       this.props[1] = b;
@@ -4846,32 +4078,26 @@
       this.props[15] = p;
       return this;
     }
-
     function translate(tx, ty, tz) {
       tz = tz || 0;
-
       if (tx !== 0 || ty !== 0 || tz !== 0) {
         return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
       }
-
       return this;
     }
-
     function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
       var _p = this.props;
-
       if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
         // NOTE: commenting this condition because TurboFan deoptimizes code when present
         // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
         _p[12] = _p[12] * a2 + _p[15] * m2;
         _p[13] = _p[13] * f2 + _p[15] * n2;
         _p[14] = _p[14] * k2 + _p[15] * o2;
-        _p[15] *= p2; // }
-
+        _p[15] *= p2;
+        // }
         this._identityCalculated = false;
         return this;
       }
-
       var a1 = _p[0];
       var b1 = _p[1];
       var c1 = _p[2];
@@ -4888,12 +4114,12 @@
       var n1 = _p[13];
       var o1 = _p[14];
       var p1 = _p[15];
+
       /* matrix order (canvas compatible):
            * ace
            * bdf
            * 001
            */
-
       _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
       _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
       _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
@@ -4913,53 +4139,40 @@
       this._identityCalculated = false;
       return this;
     }
-
     function multiply(matrix) {
       var matrixProps = matrix.props;
       return this.transform(matrixProps[0], matrixProps[1], matrixProps[2], matrixProps[3], matrixProps[4], matrixProps[5], matrixProps[6], matrixProps[7], matrixProps[8], matrixProps[9], matrixProps[10], matrixProps[11], matrixProps[12], matrixProps[13], matrixProps[14], matrixProps[15]);
     }
-
     function isIdentity() {
       if (!this._identityCalculated) {
         this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
         this._identityCalculated = true;
       }
-
       return this._identity;
     }
-
     function equals(matr) {
       var i = 0;
-
       while (i < 16) {
         if (matr.props[i] !== this.props[i]) {
           return false;
         }
-
         i += 1;
       }
-
       return true;
     }
-
     function clone(matr) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         matr.props[i] = this.props[i];
       }
-
       return matr;
     }
-
     function cloneFromProps(props) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         this.props[i] = props[i];
       }
     }
-
     function applyToPoint(x, y, z) {
       return {
         x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
@@ -4971,19 +4184,15 @@
            y: x * me.b + y * me.d + me.f
            }; */
     }
-
     function applyToX(x, y, z) {
       return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
     }
-
     function applyToY(x, y, z) {
       return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
     }
-
     function applyToZ(x, y, z) {
       return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
     }
-
     function getInverseMatrix() {
       var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
       var a = this.props[5] / determinant;
@@ -5001,27 +4210,21 @@
       inverseMatrix.props[13] = f;
       return inverseMatrix;
     }
-
     function inversePoint(pt) {
       var inverseMatrix = this.getInverseMatrix();
       return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
     }
-
     function inversePoints(pts) {
       var i;
       var len = pts.length;
       var retPts = [];
-
       for (i = 0; i < len; i += 1) {
         retPts[i] = inversePoint(pts[i]);
       }
-
       return retPts;
     }
-
     function applyToTriplePoints(pt1, pt2, pt3) {
       var arr = createTypedArray('float32', 6);
-
       if (this.isIdentity()) {
         arr[0] = pt1[0];
         arr[1] = pt1[1];
@@ -5043,34 +4246,26 @@
         arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
         arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
       }
-
       return arr;
     }
-
     function applyToPointArray(x, y, z) {
       var arr;
-
       if (this.isIdentity()) {
         arr = [x, y, z];
       } else {
         arr = [x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12], x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13], x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14]];
       }
-
       return arr;
     }
-
     function applyToPointStringified(x, y) {
       if (this.isIdentity()) {
         return x + ',' + y;
       }
-
       var _p = this.props;
       return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
     }
-
     function toCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
@@ -5078,49 +4273,34 @@
       var props = this.props;
       var cssValue = 'matrix3d(';
       var v = 10000;
-
       while (i < 16) {
         cssValue += _rnd(props[i] * v) / v;
         cssValue += i === 15 ? ')' : ',';
         i += 1;
       }
-
       return cssValue;
     }
-
     function roundMatrixProperty(val) {
       var v = 10000;
-
       if (val < 0.000001 && val > 0 || val > -0.000001 && val < 0) {
         return _rnd(val * v) / v;
       }
-
       return val;
     }
-
     function to2dCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
       var props = this.props;
-
       var _a = roundMatrixProperty(props[0]);
-
       var _b = roundMatrixProperty(props[1]);
-
       var _c = roundMatrixProperty(props[4]);
-
       var _d = roundMatrixProperty(props[5]);
-
       var _e = roundMatrixProperty(props[12]);
-
       var _f = roundMatrixProperty(props[13]);
-
       return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
     }
-
     return function () {
       this.reset = reset;
       this.rotate = rotate;
@@ -5159,16 +4339,14 @@
     };
   }();
 
-  function _typeof$3(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$3 = function _typeof(obj) { return typeof obj; }; } else { _typeof$3 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$3(obj); }
+  function _typeof$3(o) { "@babel/helpers - typeof"; return _typeof$3 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$3(o); }
   var lottie = {};
   var standalone = '__[STANDALONE]__';
   var animationData = '__[ANIMATIONDATA]__';
   var renderer = '';
-
   function setLocation(href) {
     setLocationHref(href);
   }
-
   function searchAnimations() {
     if (standalone === true) {
       animationManager.searchAnimations(animationData, standalone, renderer);
@@ -5176,35 +4354,28 @@
       animationManager.searchAnimations();
     }
   }
-
   function setSubframeRendering(flag) {
     setSubframeEnabled(flag);
   }
-
   function setPrefix(prefix) {
     setIdPrefix(prefix);
   }
-
   function loadAnimation(params) {
     if (standalone === true) {
       params.animationData = JSON.parse(animationData);
     }
-
     return animationManager.loadAnimation(params);
   }
-
   function setQuality(value) {
     if (typeof value === 'string') {
       switch (value) {
         case 'high':
           setDefaultCurveSegments(200);
           break;
-
         default:
         case 'medium':
           setDefaultCurveSegments(50);
           break;
-
         case 'low':
           setDefaultCurveSegments(10);
           break;
@@ -5212,40 +4383,32 @@
     } else if (!isNaN(value) && value > 1) {
       setDefaultCurveSegments(value);
     }
-
     if (getDefaultCurveSegments() >= 50) {
       roundValues(false);
     } else {
       roundValues(true);
     }
   }
-
   function inBrowser() {
     return typeof navigator !== 'undefined';
   }
-
   function installPlugin(type, plugin) {
     if (type === 'expressions') {
       setExpressionsPlugin(plugin);
     }
   }
-
   function getFactory(name) {
     switch (name) {
       case 'propertyFactory':
         return PropertyFactory;
-
       case 'shapePropertyFactory':
         return ShapePropertyFactory;
-
       case 'matrix':
         return Matrix;
-
       default:
         return null;
     }
   }
-
   lottie.play = animationManager.play;
   lottie.pause = animationManager.pause;
   lottie.setLocationHref = setLocation;
@@ -5257,8 +4420,8 @@
   lottie.registerAnimation = animationManager.registerAnimation;
   lottie.loadAnimation = loadAnimation;
   lottie.setSubframeRendering = setSubframeRendering;
-  lottie.resize = animationManager.resize; // lottie.start = start;
-
+  lottie.resize = animationManager.resize;
+  // lottie.start = start;
   lottie.goToAndStop = animationManager.goToAndStop;
   lottie.destroy = animationManager.destroy;
   lottie.setQuality = setQuality;
@@ -5273,32 +4436,25 @@
   lottie.useWebWorker = setWebWorker;
   lottie.setIDPrefix = setPrefix;
   lottie.__getFactory = getFactory;
-  lottie.version = '5.12.2';
-
+  lottie.version = '5.13.0';
   function checkReady() {
     if (document.readyState === 'complete') {
       clearInterval(readyStateCheckInterval);
       searchAnimations();
     }
   }
-
   function getQueryVariable(variable) {
     var vars = queryString.split('&');
-
     for (var i = 0; i < vars.length; i += 1) {
       var pair = vars[i].split('=');
-
       if (decodeURIComponent(pair[0]) == variable) {
         // eslint-disable-line eqeqeq
         return decodeURIComponent(pair[1]);
       }
     }
-
     return null;
   }
-
   var queryString = '';
-
   if (standalone) {
     var scripts = document.getElementsByTagName('script');
     var index = scripts.length - 1;
@@ -5306,18 +4462,18 @@
       src: ''
     };
     queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
-
     renderer = getQueryVariable('renderer');
   }
+  var readyStateCheckInterval = setInterval(checkReady, 100);
 
-  var readyStateCheckInterval = setInterval(checkReady, 100); // this adds bodymovin to the window object for backwards compatibility
-
+  // this adds bodymovin to the window object for backwards compatibility
   try {
     if (!((typeof exports === "undefined" ? "undefined" : _typeof$3(exports)) === 'object' && typeof module !== 'undefined') && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
     ) {
       window.bodymovin = lottie;
     }
-  } catch (err) {//
+  } catch (err) {
+    //
   }
 
   var ShapeModifiers = function () {
@@ -5325,26 +4481,19 @@
     var modifiers = {};
     ob.registerModifier = registerModifier;
     ob.getModifier = getModifier;
-
     function registerModifier(nm, factory) {
       if (!modifiers[nm]) {
         modifiers[nm] = factory;
       }
     }
-
     function getModifier(nm, elem, data) {
       return new modifiers[nm](elem, data);
     }
-
     return ob;
   }();
-
   function ShapeModifier() {}
-
   ShapeModifier.prototype.initModifierProperties = function () {};
-
   ShapeModifier.prototype.addShapeToModifier = function () {};
-
   ShapeModifier.prototype.addShape = function (data) {
     if (!this.closed) {
       // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
@@ -5356,13 +4505,11 @@
       };
       this.shapes.push(shapeData);
       this.addShapeToModifier(shapeData);
-
       if (this._isAnimated) {
         data.setAsAnimated();
       }
     }
   };
-
   ShapeModifier.prototype.init = function (elem, data) {
     this.shapes = [];
     this.elem = elem;
@@ -5371,29 +4518,23 @@
     this.frameId = initialDefaultFrame;
     this.closed = false;
     this.k = false;
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   ShapeModifier.prototype.processKeys = function () {
     if (this.elem.globalData.frameId === this.frameId) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   extendPrototype([DynamicPropertyContainer], ShapeModifier);
 
   function TrimModifier() {}
-
   extendPrototype([ShapeModifier], TrimModifier);
-
   TrimModifier.prototype.initModifierProperties = function (elem, data) {
     this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
     this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
@@ -5404,14 +4545,11 @@
     this.m = data.m;
     this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
   };
-
   TrimModifier.prototype.addShapeToModifier = function (shapeData) {
     shapeData.pathsData = [];
   };
-
   TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
     var segments = [];
-
     if (e <= 1) {
       segments.push({
         s: s,
@@ -5432,65 +4570,50 @@
         e: e - 1
       });
     }
-
     var shapeSegments = [];
     var i;
     var len = segments.length;
     var segmentOb;
-
     for (i = 0; i < len; i += 1) {
       segmentOb = segments[i];
-
       if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
         var shapeS;
         var shapeE;
-
         if (segmentOb.s * totalModifierLength <= addedLength) {
           shapeS = 0;
         } else {
           shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
         }
-
         if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
           shapeE = 1;
         } else {
           shapeE = (segmentOb.e * totalModifierLength - addedLength) / shapeLength;
         }
-
         shapeSegments.push([shapeS, shapeE]);
       }
     }
-
     if (!shapeSegments.length) {
       shapeSegments.push([0, 0]);
     }
-
     return shapeSegments;
   };
-
   TrimModifier.prototype.releasePathsData = function (pathsData) {
     var i;
     var len = pathsData.length;
-
     for (i = 0; i < len; i += 1) {
       segmentsLengthPool.release(pathsData[i]);
     }
-
     pathsData.length = 0;
     return pathsData;
   };
-
   TrimModifier.prototype.processShapes = function (_isFirstFrame) {
     var s;
     var e;
-
     if (this._mdf || _isFirstFrame) {
       var o = this.o.v % 360 / 360;
-
       if (o < 0) {
         o += 1;
       }
-
       if (this.s.v > 1) {
         s = 1 + o;
       } else if (this.s.v < 0) {
@@ -5498,7 +4621,6 @@
       } else {
         s = this.s.v + o;
       }
-
       if (this.e.v > 1) {
         e = 1 + o;
       } else if (this.e.v < 0) {
@@ -5506,13 +4628,11 @@
       } else {
         e = this.e.v + o;
       }
-
       if (s > e) {
         var _s = s;
         s = e;
         e = _s;
       }
-
       s = Math.round(s * 10000) * 0.0001;
       e = Math.round(e * 10000) * 0.0001;
       this.sValue = s;
@@ -5521,7 +4641,6 @@
       s = this.sValue;
       e = this.eValue;
     }
-
     var shapePaths;
     var i;
     var len = this.shapes.length;
@@ -5531,13 +4650,11 @@
     var pathData;
     var totalShapeLength;
     var totalModifierLength = 0;
-
     if (e === s) {
       for (i = 0; i < len; i += 1) {
         this.shapes[i].localShapeCollection.releaseShapes();
         this.shapes[i].shape._mdf = true;
         this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
-
         if (this._mdf) {
           this.shapes[i].pathsData.length = 0;
         }
@@ -5546,63 +4663,52 @@
       var segments = [];
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
-        shapeData = this.shapes[i]; // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
-
+        shapeData = this.shapes[i];
+        // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
         if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
           shapeData.shape.paths = shapeData.localShapeCollection;
         } else {
           shapePaths = shapeData.shape.paths;
           jLen = shapePaths._length;
           totalShapeLength = 0;
-
           if (!shapeData.shape._mdf && shapeData.pathsData.length) {
             totalShapeLength = shapeData.totalShapeLength;
           } else {
             pathsData = this.releasePathsData(shapeData.pathsData);
-
             for (j = 0; j < jLen; j += 1) {
               pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
               pathsData.push(pathData);
               totalShapeLength += pathData.totalLength;
             }
-
             shapeData.totalShapeLength = totalShapeLength;
             shapeData.pathsData = pathsData;
           }
-
           totalModifierLength += totalShapeLength;
           shapeData.shape._mdf = true;
         }
       }
-
       var shapeS = s;
       var shapeE = e;
       var addedLength = 0;
       var edges;
-
       for (i = len - 1; i >= 0; i -= 1) {
         shapeData = this.shapes[i];
-
         if (shapeData.shape._mdf) {
           localShapeCollection = shapeData.localShapeCollection;
-          localShapeCollection.releaseShapes(); // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
-
+          localShapeCollection.releaseShapes();
+          // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
           if (this.m === 2 && len > 1) {
             edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
             addedLength += shapeData.totalShapeLength;
           } else {
             edges = [[shapeS, shapeE]];
           }
-
           jLen = edges.length;
-
           for (j = 0; j < jLen; j += 1) {
             shapeS = edges[j][0];
             shapeE = edges[j][1];
             segments.length = 0;
-
             if (shapeE <= 1) {
               segments.push({
                 s: shapeData.totalShapeLength * shapeS,
@@ -5623,13 +4729,10 @@
                 e: shapeData.totalShapeLength * (shapeE - 1)
               });
             }
-
             var newShapesData = this.addShapes(shapeData, segments[0]);
-
             if (segments[0].s !== segments[0].e) {
               if (segments.length > 1) {
                 var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
-
                 if (lastShapeInCollection.c) {
                   var lastShape = newShapesData.pop();
                   this.addPaths(newShapesData, localShapeCollection);
@@ -5639,11 +4742,9 @@
                   newShapesData = this.addShapes(shapeData, segments[1]);
                 }
               }
-
               this.addPaths(newShapesData, localShapeCollection);
             }
           }
-
           shapeData.shape.paths = localShapeCollection;
         }
       }
@@ -5656,38 +4757,29 @@
       }
     }
   };
-
   TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
     var i;
     var len = newPaths.length;
-
     for (i = 0; i < len; i += 1) {
       localShapeCollection.addShape(newPaths[i]);
     }
   };
-
   TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
     shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
     shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
     }
-
     shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
     shapePath.setXYAt(points[1], points[5], 'o', pos);
     shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(points[0], points[4], 'v', pos);
     }
-
     shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
     var pathsData = shapeData.pathsData;
     var shapePaths = shapeData.shape.paths.shapes;
@@ -5703,7 +4795,6 @@
     var shapes = [];
     var initPos;
     var newShape = true;
-
     if (!shapePath) {
       shapePath = shapePool.newElement();
       segmentCount = 0;
@@ -5712,17 +4803,13 @@
       segmentCount = shapePath._length;
       initPos = shapePath._length;
     }
-
     shapes.push(shapePath);
-
     for (i = 0; i < len; i += 1) {
       lengths = pathsData[i].lengths;
       shapePath.c = shapePaths[i].c;
       jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
-
       for (j = 1; j < jLen; j += 1) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
           addedLength += currentLengthData.addedLength;
           shapePath.c = false;
@@ -5735,50 +4822,42 @@
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
-
           addedLength += currentLengthData.addedLength;
           segmentCount += 1;
         }
       }
-
       if (shapePaths[i].c && lengths.length) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength <= shapeSegment.e) {
           var segmentLength = lengths[j - 1].addedLength;
-
           if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
             this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
         } else {
           shapePath.c = false;
         }
-
         addedLength += currentLengthData.addedLength;
         segmentCount += 1;
       }
-
       if (shapePath._length) {
         shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
         shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
       }
-
       if (addedLength > shapeSegment.e) {
         break;
       }
-
       if (i < len - 1) {
         shapePath = shapePool.newElement();
         newShape = true;
@@ -5786,31 +4865,25 @@
         segmentCount = 0;
       }
     }
-
     return shapes;
   };
 
   function PuckerAndBloatModifier() {}
-
   extendPrototype([ShapeModifier], PuckerAndBloatModifier);
-
   PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
     this._isAnimated = !!this.amount.effectsSequence.length;
   };
-
   PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
     var percent = amount / 100;
     var centerPoint = [0, 0];
     var pathLength = path._length;
     var i = 0;
-
     for (i = 0; i < pathLength; i += 1) {
       centerPoint[0] += path.v[i][0];
       centerPoint[1] += path.v[i][1];
     }
-
     centerPoint[0] /= pathLength;
     centerPoint[1] /= pathLength;
     var clonedPath = shapePool.newElement();
@@ -5821,7 +4894,6 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < pathLength; i += 1) {
       vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
       vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
@@ -5831,10 +4903,8 @@
       iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
       clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
     }
-
     return clonedPath;
   };
-
   PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -5842,30 +4912,24 @@
     var j;
     var jLen;
     var amount = this.amount.v;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -5873,30 +4937,24 @@
 
   var TransformPropertyFactory = function () {
     var defaultVector = [0, 0];
-
     function applyToMatrix(mat) {
       var _mdf = this._mdf;
       this.iterateDynamicProperties();
       this._mdf = this._mdf || _mdf;
-
       if (this.a) {
         mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
       }
-
       if (this.s) {
         mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
       }
-
       if (this.sk) {
         mat.skewFromAxis(-this.sk.v, this.sa.v);
       }
-
       if (this.r) {
         mat.rotate(-this.r.v);
       } else {
         mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
       }
-
       if (this.data.p.s) {
         if (this.data.p.z) {
           mat.translate(this.px.v, this.py.v, -this.pz.v);
@@ -5907,46 +4965,36 @@
         mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
       }
     }
-
     function processKeys(forceRender) {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (this._isDirty) {
         this.precalculateMatrix();
         this._isDirty = false;
       }
-
       this.iterateDynamicProperties();
-
       if (this._mdf || forceRender) {
         var frameRate;
         this.v.cloneFromProps(this.pre.props);
-
         if (this.appliedTransformations < 1) {
           this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         }
-
         if (this.appliedTransformations < 2) {
           this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         }
-
         if (this.sk && this.appliedTransformations < 3) {
           this.v.skewFromAxis(-this.sk.v, this.sa.v);
         }
-
         if (this.r && this.appliedTransformations < 4) {
           this.v.rotate(-this.r.v);
         } else if (!this.r && this.appliedTransformations < 4) {
           this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
         }
-
         if (this.autoOriented) {
           var v1;
           var v2;
           frameRate = this.elem.globalData.frameRate;
-
           if (this.p && this.p.keyframes && this.p.getValueAtTime) {
             if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
               v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
@@ -5963,7 +5011,6 @@
             v2 = [];
             var px = this.px;
             var py = this.py;
-
             if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
               v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
               v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
@@ -5983,10 +5030,8 @@
             v2 = defaultVector;
             v1 = v2;
           }
-
           this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
         }
-
         if (this.data.p && this.data.p.s) {
           if (this.data.p.z) {
             this.v.translate(this.px.v, this.py.v, -this.pz.v);
@@ -5997,28 +5042,23 @@
           this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
         }
       }
-
       this.frameId = this.elem.globalData.frameId;
     }
-
     function precalculateMatrix() {
       this.appliedTransformations = 0;
       this.pre.reset();
-
       if (!this.a.effectsSequence.length) {
         this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         this.appliedTransformations = 1;
       } else {
         return;
       }
-
       if (!this.s.effectsSequence.length) {
         this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         this.appliedTransformations = 2;
       } else {
         return;
       }
-
       if (this.sk) {
         if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
           this.pre.skewFromAxis(-this.sk.v, this.sa.v);
@@ -6027,7 +5067,6 @@
           return;
         }
       }
-
       if (this.r) {
         if (!this.r.effectsSequence.length) {
           this.pre.rotate(-this.r.v);
@@ -6038,33 +5077,28 @@
         this.appliedTransformations = 4;
       }
     }
-
-    function autoOrient() {//
+    function autoOrient() {
+      //
       // var prevP = this.getValueAtTime();
     }
-
     function addDynamicProperty(prop) {
       this._addDynamicProperty(prop);
-
       this.elem.addDynamicProperty(prop);
       this._isDirty = true;
     }
-
     function TransformProperty(elem, data, container) {
       this.elem = elem;
       this.frameId = -1;
       this.propType = 'transform';
       this.data = data;
-      this.v = new Matrix(); // Precalculated matrix with non animated properties
-
+      this.v = new Matrix();
+      // Precalculated matrix with non animated properties
       this.pre = new Matrix();
       this.appliedTransformations = 0;
       this.initDynamicPropertyContainer(container || elem);
-
       if (data.p && data.p.s) {
         this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
         this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
-
         if (data.p.z) {
           this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
         }
@@ -6073,43 +5107,37 @@
           k: [0, 0, 0]
         }, 1, 0, this);
       }
-
       if (data.rx) {
         this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
         this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
         this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
-
         if (data.or.k[0].ti) {
           var i;
           var len = data.or.k.length;
-
           for (i = 0; i < len; i += 1) {
             data.or.k[i].to = null;
             data.or.k[i].ti = null;
           }
         }
-
-        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this); // sh Indicates it needs to be capped between -180 and 180
-
+        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+        // sh Indicates it needs to be capped between -180 and 180
         this.or.sh = true;
       } else {
         this.r = PropertyFactory.getProp(elem, data.r || {
           k: 0
         }, 0, degToRads, this);
       }
-
       if (data.sk) {
         this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
         this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
       }
-
       this.a = PropertyFactory.getProp(elem, data.a || {
         k: [0, 0, 0]
       }, 1, 0, this);
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: [100, 100, 100]
-      }, 1, 0.01, this); // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
-
+      }, 1, 0.01, this);
+      // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
       if (data.o) {
         this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
       } else {
@@ -6118,14 +5146,11 @@
           v: 1
         };
       }
-
       this._isDirty = true;
-
       if (!this.dynamicProperties.length) {
         this.getValue(true);
       }
     }
-
     TransformProperty.prototype = {
       applyToMatrix: applyToMatrix,
       getValue: processKeys,
@@ -6135,20 +5160,16 @@
     extendPrototype([DynamicPropertyContainer], TransformProperty);
     TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
     TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
-
     function getTransformProperty(elem, data, container) {
       return new TransformProperty(elem, data, container);
     }
-
     return {
       getTransformProperty: getTransformProperty
     };
   }();
 
   function RepeaterModifier() {}
-
   extendPrototype([ShapeModifier], RepeaterModifier);
-
   RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
@@ -6157,11 +5178,9 @@
     this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
     this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
     this.data = data;
-
     if (!this.dynamicProperties.length) {
       this.getValue(true);
     }
-
     this._isAnimated = !!this.dynamicProperties.length;
     this.pMatrix = new Matrix();
     this.rMatrix = new Matrix();
@@ -6169,7 +5188,6 @@
     this.tMatrix = new Matrix();
     this.matrix = new Matrix();
   };
-
   RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
     var dir = inv ? -1 : 1;
     var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
@@ -6182,7 +5200,6 @@
     sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
     sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
   };
-
   RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
     this.elem = elem;
     this.arr = arr;
@@ -6194,52 +5211,42 @@
     this.frameId = -1;
     this.initDynamicPropertyContainer(elem);
     this.initModifierProperties(elem, arr[pos]);
-
     while (pos > 0) {
-      pos -= 1; // this._elements.unshift(arr.splice(pos,1)[0]);
-
+      pos -= 1;
+      // this._elements.unshift(arr.splice(pos,1)[0]);
       this._elements.unshift(arr[pos]);
     }
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   RepeaterModifier.prototype.resetElements = function (elements) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._processed = false;
-
       if (elements[i].ty === 'gr') {
         this.resetElements(elements[i].it);
       }
     }
   };
-
   RepeaterModifier.prototype.cloneElements = function (elements) {
     var newElements = JSON.parse(JSON.stringify(elements));
     this.resetElements(newElements);
     return newElements;
   };
-
   RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._render = renderFlag;
-
       if (elements[i].ty === 'gr') {
         this.changeGroupRender(elements[i].it, renderFlag);
       }
     }
   };
-
   RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
     var items;
     var itemsTransform;
@@ -6247,10 +5254,8 @@
     var dir;
     var cont;
     var hasReloaded = false;
-
     if (this._mdf || _isFirstFrame) {
       var copies = Math.ceil(this.c.v);
-
       if (this._groups.length < copies) {
         while (this._groups.length < copies) {
           var group = {
@@ -6305,28 +5310,21 @@
             ty: 'tr'
           });
           this.arr.splice(0, 0, group);
-
           this._groups.splice(0, 0, group);
-
           this._currentCopies += 1;
         }
-
         this.elem.reloadShapes();
         hasReloaded = true;
       }
-
       cont = 0;
       var renderFlag;
-
       for (i = 0; i <= this._groups.length - 1; i += 1) {
         renderFlag = cont < copies;
         this._groups[i]._render = renderFlag;
         this.changeGroupRender(this._groups[i].it, renderFlag);
-
         if (!renderFlag) {
           var elems = this.elemsData[i].it;
           var transformData = elems[elems.length - 1];
-
           if (transformData.transform.op.v !== 0) {
             transformData.transform.op._mdf = true;
             transformData.transform.op.v = 0;
@@ -6334,11 +5332,10 @@
             transformData.transform.op._mdf = false;
           }
         }
-
         cont += 1;
       }
-
-      this._currentCopies = copies; /// /
+      this._currentCopies = copies;
+      /// /
 
       var offset = this.o.v;
       var offsetModulo = offset % 1;
@@ -6352,13 +5349,11 @@
       this.tMatrix.reset();
       this.matrix.reset();
       var iteration = 0;
-
       if (offset > 0) {
         while (iteration < roundOffset) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           iteration += 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
           iteration += offsetModulo;
@@ -6368,19 +5363,16 @@
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
           iteration -= 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
           iteration -= offsetModulo;
         }
       }
-
       i = this.data.m === 1 ? 0 : this._currentCopies - 1;
       dir = this.data.m === 1 ? 1 : -1;
       cont = this._currentCopies;
       var j;
       var jLen;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6388,29 +5380,23 @@
         items[items.length - 1].transform.mProps._mdf = true;
         items[items.length - 1].transform.op._mdf = true;
         items[items.length - 1].transform.op.v = this._currentCopies === 1 ? this.so.v : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
-
         if (iteration !== 0) {
           if (i !== 0 && dir === 1 || i !== this._currentCopies - 1 && dir === -1) {
             this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           }
-
           this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
           this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
           this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
-
           this.matrix.reset();
         } else {
           this.matrix.reset();
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
         }
-
         iteration += 1;
         cont -= 1;
         i += dir;
@@ -6419,7 +5405,6 @@
       cont = this._currentCopies;
       i = 0;
       dir = 1;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6429,22 +5414,17 @@
         i += dir;
       }
     }
-
     return hasReloaded;
   };
-
   RepeaterModifier.prototype.addShape = function () {};
 
   function RoundCornersModifier() {}
-
   extendPrototype([ShapeModifier], RoundCornersModifier);
-
   RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
     this._isAnimated = !!this.rd.effectsSequence.length;
   };
-
   RoundCornersModifier.prototype.processPath = function (path, round) {
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
@@ -6463,19 +5443,16 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < len; i += 1) {
       currentV = path.v[i];
       currentO = path.o[i];
       currentI = path.i[i];
-
       if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
         if ((i === 0 || i === len - 1) && !path.c) {
           clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
           /* clonedPath.v[index] = currentV;
                   clonedPath.o[index] = currentO;
                   clonedPath.i[index] = currentI; */
-
           index += 1;
         } else {
           if (i === 0) {
@@ -6483,7 +5460,6 @@
           } else {
             closerV = path.v[i - 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6494,13 +5470,11 @@
           oY = vY - (vY - currentV[1]) * roundCorner;
           clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
           index += 1;
-
           if (i === len - 1) {
             closerV = path.v[0];
           } else {
             closerV = path.v[i + 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6517,10 +5491,8 @@
         index += 1;
       }
     }
-
     return clonedPath;
   };
-
   RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6528,30 +5500,24 @@
     var j;
     var jLen;
     var rd = this.rd.v;
-
     if (rd !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6560,50 +5526,41 @@
   function floatEqual(a, b) {
     return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
   }
-
   function floatZero(f) {
     return Math.abs(f) <= 0.00001;
   }
-
   function lerp(p0, p1, amount) {
     return p0 * (1 - amount) + p1 * amount;
   }
-
   function lerpPoint(p0, p1, amount) {
     return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
   }
-
   function quadRoots(a, b, c) {
     // no root
     if (a === 0) return [];
-    var s = b * b - 4 * a * c; // Complex roots
-
+    var s = b * b - 4 * a * c;
+    // Complex roots
     if (s < 0) return [];
-    var singleRoot = -b / (2 * a); // 1 root
-
+    var singleRoot = -b / (2 * a);
+    // 1 root
     if (s === 0) return [singleRoot];
-    var delta = Math.sqrt(s) / (2 * a); // 2 roots
-
+    var delta = Math.sqrt(s) / (2 * a);
+    // 2 roots
     return [singleRoot - delta, singleRoot + delta];
   }
-
   function polynomialCoefficients(p0, p1, p2, p3) {
     return [-p0 + 3 * p1 - 3 * p2 + p3, 3 * p0 - 6 * p1 + 3 * p2, -3 * p0 + 3 * p1, p0];
   }
-
   function singlePoint(p) {
     return new PolynomialBezier(p, p, p, p, false);
   }
-
   function PolynomialBezier(p0, p1, p2, p3, linearize) {
     if (linearize && pointEqual(p0, p1)) {
       p1 = lerpPoint(p0, p3, 1 / 3);
     }
-
     if (linearize && pointEqual(p2, p3)) {
       p2 = lerpPoint(p0, p3, 2 / 3);
     }
-
     var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
     var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
     this.a = [coeffx[0], coeffy[0]];
@@ -6612,25 +5569,20 @@
     this.d = [coeffx[3], coeffy[3]];
     this.points = [p0, p1, p2, p3];
   }
-
   PolynomialBezier.prototype.point = function (t) {
     return [((this.a[0] * t + this.b[0]) * t + this.c[0]) * t + this.d[0], ((this.a[1] * t + this.b[1]) * t + this.c[1]) * t + this.d[1]];
   };
-
   PolynomialBezier.prototype.derivative = function (t) {
     return [(3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0], (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1]];
   };
-
   PolynomialBezier.prototype.tangentAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[1], p[0]);
   };
-
   PolynomialBezier.prototype.normalAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[0], p[1]);
   };
-
   PolynomialBezier.prototype.inflectionPoints = function () {
     var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
     if (floatZero(denom)) return [];
@@ -6638,17 +5590,14 @@
     var square = tcusp * tcusp - 1 / 3 * (this.b[1] * this.c[0] - this.b[0] * this.c[1]) / denom;
     if (square < 0) return [];
     var root = Math.sqrt(square);
-
     if (floatZero(root)) {
       if (root > 0 && root < 1) return [tcusp];
       return [];
     }
-
     return [tcusp - root, tcusp + root].filter(function (r) {
       return r > 0 && r < 1;
     });
   };
-
   PolynomialBezier.prototype.split = function (t) {
     if (t <= 0) return [singlePoint(this.points[0]), this];
     if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
@@ -6660,40 +5609,33 @@
     var p3 = lerpPoint(p20, p21, t);
     return [new PolynomialBezier(this.points[0], p10, p20, p3, true), new PolynomialBezier(p3, p21, p12, this.points[3], true)];
   };
-
   function extrema(bez, comp) {
     var min = bez.points[0][comp];
     var max = bez.points[bez.points.length - 1][comp];
-
     if (min > max) {
       var e = max;
       max = min;
       min = e;
-    } // Derivative roots to find min/max
-
-
+    }
+    // Derivative roots to find min/max
     var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
-
     for (var i = 0; i < f.length; i += 1) {
       if (f[i] > 0 && f[i] < 1) {
         var val = bez.point(f[i])[comp];
         if (val < min) min = val;else if (val > max) max = val;
       }
     }
-
     return {
       min: min,
       max: max
     };
   }
-
   PolynomialBezier.prototype.bounds = function () {
     return {
       x: extrema(this, 0),
       y: extrema(this, 1)
     };
   };
-
   PolynomialBezier.prototype.boundingBox = function () {
     var bounds = this.bounds();
     return {
@@ -6707,7 +5649,6 @@
       cy: (bounds.y.max + bounds.y.min) / 2
     };
   };
-
   function intersectData(bez, t1, t2) {
     var box = bez.boundingBox();
     return {
@@ -6721,24 +5662,19 @@
       t2: t2
     };
   }
-
   function splitData(data) {
     var split = data.bez.split(0.5);
     return [intersectData(split[0], data.t1, data.t), intersectData(split[1], data.t, data.t2)];
   }
-
   function boxIntersect(b1, b2) {
     return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
   }
-
   function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
     if (!boxIntersect(d1, d2)) return;
-
     if (depth >= maxRecursion || d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance) {
       intersections.push([d1.t, d2.t]);
       return;
     }
-
     var d1s = splitData(d1);
     var d2s = splitData(d2);
     intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
@@ -6746,7 +5682,6 @@
     intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
     intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
   }
-
   PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
     if (tolerance === undefined) tolerance = 2;
     if (maxRecursion === undefined) maxRecursion = 7;
@@ -6754,21 +5689,17 @@
     intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
     return intersections;
   };
-
   PolynomialBezier.shapeSegment = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
   };
-
   PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
   };
-
   function crossProduct(a, b) {
     return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
   }
-
   function lineIntersection(start1, end1, start2, end2) {
     var v1 = [start1[0], start1[1], 1];
     var v2 = [end1[0], end1[1], 1];
@@ -6778,23 +5709,18 @@
     if (floatZero(r[2])) return null;
     return [r[0] / r[2], r[1] / r[2]];
   }
-
   function polarOffset(p, angle, length) {
     return [p[0] + Math.cos(angle) * length, p[1] - Math.sin(angle) * length];
   }
-
   function pointDistance(p1, p2) {
     return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
   }
-
   function pointEqual(p1, p2) {
     return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
   }
 
   function ZigZagModifier() {}
-
   extendPrototype([ShapeModifier], ZigZagModifier);
-
   ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
@@ -6802,7 +5728,6 @@
     this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
     this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
   };
-
   function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
     var angO = angle - Math.PI / 2;
     var angI = angle + Math.PI / 2;
@@ -6810,14 +5735,12 @@
     var py = point[1] - Math.sin(angle) * direction * amplitude;
     outputBezier.setTripleAt(px, py, px + Math.cos(angO) * outAmplitude, py - Math.sin(angO) * outAmplitude, px + Math.cos(angI) * inAmplitude, py - Math.sin(angI) * inAmplitude, outputBezier.length());
   }
-
   function getPerpendicularVector(pt1, pt2) {
     var vector = [pt2[0] - pt1[0], pt2[1] - pt1[1]];
     var rot = -Math.PI * 0.5;
     var rotatedVector = [Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1], Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1]];
     return rotatedVector;
   }
-
   function getProjectingAngle(path, cur) {
     var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
     var nextIndex = (cur + 1) % path.length();
@@ -6826,7 +5749,6 @@
     var pVector = getPerpendicularVector(prevPoint, nextPoint);
     return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
   }
-
   function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
     var angle = getProjectingAngle(path, cur);
     var point = path.v[cur % path._length];
@@ -6836,7 +5758,6 @@
     var nextDist = pointType === 2 ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2)) : 0;
     setPoint(outputBezier, path.v[cur % path._length], angle, direction, amplitude, nextDist / ((frequency + 1) * 2), prevDist / ((frequency + 1) * 2), pointType);
   }
-
   function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
     for (var i = 0; i < frequency; i += 1) {
       var t = (i + 1) / (frequency + 1);
@@ -6846,39 +5767,30 @@
       setPoint(outputBezier, point, angle, direction, amplitude, dist / ((frequency + 1) * 2), dist / ((frequency + 1) * 2), pointType);
       direction = -direction;
     }
-
     return direction;
   }
-
   ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
     var count = path._length;
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
-
     if (!path.c) {
       count -= 1;
     }
-
     if (count === 0) return clonedPath;
     var direction = -1;
     var segment = PolynomialBezier.shapeSegment(path, 0);
     zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
-
     for (var i = 0; i < count; i += 1) {
       direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
-
       if (i === count - 1 && !path.c) {
         segment = null;
       } else {
         segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
       }
-
       zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
     }
-
     return clonedPath;
   };
-
   ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6888,30 +5800,24 @@
     var amplitude = this.amplitude.v;
     var frequency = Math.max(0, Math.round(this.frequency.v));
     var pointType = this.pointsType.v;
-
     if (amplitude !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6921,7 +5827,6 @@
     var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
     return [polarOffset(p1, angle, amount), polarOffset(p2, angle, amount)];
   }
-
   function offsetSegment(segment, amount) {
     var p0;
     var p1a;
@@ -6945,15 +5850,17 @@
     if (p2 === null) p2 = p2a;
     return new PolynomialBezier(p0, p1, p2, p3);
   }
-
   function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
     var p0 = seg1.points[3];
-    var p1 = seg2.points[0]; // Bevel
+    var p1 = seg2.points[0];
 
-    if (lineJoin === 3) return p0; // Connected, they don't need a joint
+    // Bevel
+    if (lineJoin === 3) return p0;
 
-    if (pointEqual(p0, p1)) return p0; // Round
+    // Connected, they don't need a joint
+    if (pointEqual(p0, p1)) return p0;
 
+    // Round
     if (lineJoin === 2) {
       var angleOut = -seg1.tangentAngle(1);
       var angleIn = -seg2.tangentAngle(0) + Math.PI;
@@ -6964,91 +5871,75 @@
       tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
       outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
       return p1;
-    } // Miter
+    }
 
-
+    // Miter
     var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
     var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
     var intersection = lineIntersection(t0, p0, p1, t1);
-
     if (intersection && pointDistance(intersection, p0) < miterLimit) {
       outputBezier.setTripleAt(intersection[0], intersection[1], intersection[0], intersection[1], intersection[0], intersection[1], outputBezier.length());
       return intersection;
     }
-
     return p0;
   }
-
   function getIntersection(a, b) {
     var intersect = a.intersections(b);
     if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
     if (intersect.length) return intersect[0];
     return null;
   }
-
   function pruneSegmentIntersection(a, b) {
     var outa = a.slice();
     var outb = b.slice();
     var intersect = getIntersection(a[a.length - 1], b[0]);
-
     if (intersect) {
       outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
       outb[0] = b[0].split(intersect[1])[1];
     }
-
     if (a.length > 1 && b.length > 1) {
       intersect = getIntersection(a[0], b[b.length - 1]);
-
       if (intersect) {
         return [[a[0].split(intersect[0])[0]], [b[b.length - 1].split(intersect[1])[1]]];
       }
     }
-
     return [outa, outb];
   }
-
   function pruneIntersections(segments) {
     var e;
-
     for (var i = 1; i < segments.length; i += 1) {
       e = pruneSegmentIntersection(segments[i - 1], segments[i]);
       segments[i - 1] = e[0];
       segments[i] = e[1];
     }
-
     if (segments.length > 1) {
       e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
       segments[segments.length - 1] = e[0];
       segments[0] = e[1];
     }
-
     return segments;
   }
-
   function offsetSegmentSplit(segment, amount) {
     /*
       We split each bezier segment into smaller pieces based
       on inflection points, this ensures the control point
       polygon is convex.
-        (A cubic bezier can have none, one, or two inflection points)
+       (A cubic bezier can have none, one, or two inflection points)
     */
     var flex = segment.inflectionPoints();
     var left;
     var right;
     var split;
     var mid;
-
     if (flex.length === 0) {
       return [offsetSegment(segment, amount)];
     }
-
     if (flex.length === 1 || floatEqual(flex[1], 1)) {
       split = segment.split(flex[0]);
       left = split[0];
       right = split[1];
       return [offsetSegment(left, amount), offsetSegment(right, amount)];
     }
-
     split = segment.split(flex[0]);
     left = split[0];
     var t = (flex[1] - flex[0]) / (1 - flex[0]);
@@ -7057,11 +5948,8 @@
     right = split[1];
     return [offsetSegment(left, amount), offsetSegment(mid, amount), offsetSegment(right, amount)];
   }
-
   function OffsetPathModifier() {}
-
   extendPrototype([ShapeModifier], OffsetPathModifier);
-
   OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
@@ -7069,61 +5957,50 @@
     this.lineJoin = data.lj;
     this._isAnimated = this.amount.effectsSequence.length !== 0;
   };
-
   OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
     var outputBezier = shapePool.newElement();
     outputBezier.c = inputBezier.c;
     var count = inputBezier.length();
-
     if (!inputBezier.c) {
       count -= 1;
     }
-
     var i;
     var j;
     var segment;
     var multiSegments = [];
-
     for (i = 0; i < count; i += 1) {
       segment = PolynomialBezier.shapeSegment(inputBezier, i);
       multiSegments.push(offsetSegmentSplit(segment, amount));
     }
-
     if (!inputBezier.c) {
       for (i = count - 1; i >= 0; i -= 1) {
         segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
         multiSegments.push(offsetSegmentSplit(segment, amount));
       }
     }
+    multiSegments = pruneIntersections(multiSegments);
 
-    multiSegments = pruneIntersections(multiSegments); // Add bezier segments to the output and apply line joints
-
+    // Add bezier segments to the output and apply line joints
     var lastPoint = null;
     var lastSeg = null;
-
     for (i = 0; i < multiSegments.length; i += 1) {
       var multiSegment = multiSegments[i];
       if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
       lastSeg = multiSegment[multiSegment.length - 1];
-
       for (j = 0; j < multiSegment.length; j += 1) {
         segment = multiSegment[j];
-
         if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
           outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
         } else {
           outputBezier.setTripleAt(segment.points[0][0], segment.points[0][1], segment.points[1][0], segment.points[1][1], segment.points[0][0], segment.points[0][1], outputBezier.length());
         }
-
         outputBezier.setTripleAt(segment.points[3][0], segment.points[3][1], segment.points[3][0], segment.points[3][1], segment.points[2][0], segment.points[2][1], outputBezier.length());
         lastPoint = segment.points[3];
       }
     }
-
     if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
     return outputBezier;
   };
-
   OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -7133,30 +6010,24 @@
     var amount = this.amount.v;
     var miterLimit = this.miterLimit.v;
     var lineJoin = this.lineJoin;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -7168,42 +6039,33 @@
     var fStyle = 'normal';
     var len = styles.length;
     var styleName;
-
     for (var i = 0; i < len; i += 1) {
       styleName = styles[i].toLowerCase();
-
       switch (styleName) {
         case 'italic':
           fStyle = 'italic';
           break;
-
         case 'bold':
           fWeight = '700';
           break;
-
         case 'black':
           fWeight = '900';
           break;
-
         case 'medium':
           fWeight = '500';
           break;
-
         case 'regular':
         case 'normal':
           fWeight = '400';
           break;
-
         case 'light':
         case 'thin':
           fWeight = '200';
           break;
-
         default:
           break;
       }
     }
-
     return {
       style: fStyle,
       weight: fontData.fWeight || fWeight
@@ -7220,8 +6082,8 @@
         shapes: []
       }
     };
-    var combinedCharacters = []; // Hindi characters
-
+    var combinedCharacters = [];
+    // Hindi characters
     combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
     var BLACK_FLAG_CODE_POINT = 127988;
     var CANCEL_TAG_CODE_POINT = 917631;
@@ -7232,44 +6094,41 @@
     var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
     var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
     var surrogateModifiers = ['d83cdffb', 'd83cdffc', 'd83cdffd', 'd83cdffe', 'd83cdfff'];
-
     function trimFontOptions(font) {
       var familyArray = font.split(',');
       var i;
       var len = familyArray.length;
       var enabledFamilies = [];
-
       for (i = 0; i < len; i += 1) {
         if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
           enabledFamilies.push(familyArray[i]);
         }
       }
-
       return enabledFamilies.join(',');
     }
-
     function setUpNode(font, family) {
-      var parentNode = createTag('span'); // Node is invisible to screen readers.
-
+      var parentNode = createTag('span');
+      // Node is invisible to screen readers.
       parentNode.setAttribute('aria-hidden', true);
       parentNode.style.fontFamily = family;
-      var node = createTag('span'); // Characters that vary significantly among different fonts
-
-      node.innerText = 'giItT1WQy@!-/#'; // Visible - so we can measure it - but not on the screen
-
+      var node = createTag('span');
+      // Characters that vary significantly among different fonts
+      node.innerText = 'giItT1WQy@!-/#';
+      // Visible - so we can measure it - but not on the screen
       parentNode.style.position = 'absolute';
       parentNode.style.left = '-10000px';
-      parentNode.style.top = '-10000px'; // Large font size makes even subtle changes obvious
-
-      parentNode.style.fontSize = '300px'; // Reset any font properties
-
+      parentNode.style.top = '-10000px';
+      // Large font size makes even subtle changes obvious
+      parentNode.style.fontSize = '300px';
+      // Reset any font properties
       parentNode.style.fontVariant = 'normal';
       parentNode.style.fontStyle = 'normal';
       parentNode.style.fontWeight = 'normal';
       parentNode.style.letterSpacing = '0';
       parentNode.appendChild(node);
-      document.body.appendChild(parentNode); // Remember width with no applied web font
+      document.body.appendChild(parentNode);
 
+      // Remember width with no applied web font
       var width = node.offsetWidth;
       node.style.fontFamily = trimFontOptions(font) + ', ' + family;
       return {
@@ -7278,14 +6137,12 @@
         parent: parentNode
       };
     }
-
     function checkLoadedFonts() {
       var i;
       var len = this.fonts.length;
       var node;
       var w;
       var loadedCount = len;
-
       for (i = 0; i < len; i += 1) {
         if (this.fonts[i].loaded) {
           loadedCount -= 1;
@@ -7294,55 +6151,47 @@
         } else {
           node = this.fonts[i].monoCase.node;
           w = this.fonts[i].monoCase.w;
-
           if (node.offsetWidth !== w) {
             loadedCount -= 1;
             this.fonts[i].loaded = true;
           } else {
             node = this.fonts[i].sansCase.node;
             w = this.fonts[i].sansCase.w;
-
             if (node.offsetWidth !== w) {
               loadedCount -= 1;
               this.fonts[i].loaded = true;
             }
           }
-
           if (this.fonts[i].loaded) {
             this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
             this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
           }
         }
       }
-
       if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
         setTimeout(this.checkLoadedFontsBinded, 20);
       } else {
         setTimeout(this.setIsLoadedBinded, 10);
       }
     }
-
     function createHelper(fontData, def) {
       var engine = document.body && def ? 'svg' : 'canvas';
       var helper;
       var fontProps = getFontProperties(fontData);
-
       if (engine === 'svg') {
         var tHelper = createNS('text');
-        tHelper.style.fontSize = '100px'; // tHelper.style.fontFamily = fontData.fFamily;
-
+        tHelper.style.fontSize = '100px';
+        // tHelper.style.fontFamily = fontData.fFamily;
         tHelper.setAttribute('font-family', fontData.fFamily);
         tHelper.setAttribute('font-style', fontProps.style);
         tHelper.setAttribute('font-weight', fontProps.weight);
         tHelper.textContent = '1';
-
         if (fontData.fClass) {
           tHelper.style.fontFamily = 'inherit';
           tHelper.setAttribute('class', fontData.fClass);
         } else {
           tHelper.style.fontFamily = fontData.fFamily;
         }
-
         def.appendChild(tHelper);
         helper = tHelper;
       } else {
@@ -7350,33 +6199,27 @@
         tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
         helper = tCanvasHelper;
       }
-
       function measure(text) {
         if (engine === 'svg') {
           helper.textContent = text;
           return helper.getComputedTextLength();
         }
-
         return helper.measureText(text).width;
       }
-
       return {
         measureText: measure
       };
     }
-
     function addFonts(fontData, defs) {
       if (!fontData) {
         this.isLoaded = true;
         return;
       }
-
       if (this.chars) {
         this.isLoaded = true;
         this.fonts = fontData.list;
         return;
       }
-
       if (!document.body) {
         this.isLoaded = true;
         fontData.list.forEach(function (data) {
@@ -7386,12 +6229,10 @@
         this.fonts = fontData.list;
         return;
       }
-
       var fontArr = fontData.list;
       var i;
       var len = fontArr.length;
       var _pendingFonts = len;
-
       for (i = 0; i < len; i += 1) {
         var shouldLoadFont = true;
         var loadedSelector;
@@ -7399,17 +6240,14 @@
         fontArr[i].loaded = false;
         fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
         fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
-
         if (!fontArr[i].fPath) {
           fontArr[i].loaded = true;
           _pendingFonts -= 1;
         } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
           loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
-
           if (loadedSelector.length > 0) {
             shouldLoadFont = false;
           }
-
           if (shouldLoadFont) {
             var s = createTag('style');
             s.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7421,14 +6259,12 @@
           }
         } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
           loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var l = createTag('link');
             l.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7440,14 +6276,12 @@
           }
         } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
           loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (fontArr[i].fPath === loadedSelector[j].src) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var sc = createTag('link');
             sc.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7457,12 +6291,10 @@
             defs.appendChild(sc);
           }
         }
-
         fontArr[i].helper = createHelper(fontArr[i], defs);
         fontArr[i].cache = {};
         this.fonts.push(fontArr[i]);
       }
-
       if (_pendingFonts === 0) {
         this.isLoaded = true;
       } else {
@@ -7471,71 +6303,56 @@
         setTimeout(this.checkLoadedFonts.bind(this), 100);
       }
     }
-
     function addChars(chars) {
       if (!chars) {
         return;
       }
-
       if (!this.chars) {
         this.chars = [];
       }
-
       var i;
       var len = chars.length;
       var j;
       var jLen = this.chars.length;
       var found;
-
       for (i = 0; i < len; i += 1) {
         j = 0;
         found = false;
-
         while (j < jLen) {
           if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
             found = true;
           }
-
           j += 1;
         }
-
         if (!found) {
           this.chars.push(chars[i]);
           jLen += 1;
         }
       }
     }
-
     function getCharData(_char, style, font) {
       var i = 0;
       var len = this.chars.length;
-
       while (i < len) {
         if (this.chars[i].ch === _char && this.chars[i].style === style && this.chars[i].fFamily === font) {
           return this.chars[i];
         }
-
         i += 1;
       }
-
       if ((typeof _char === 'string' && _char.charCodeAt(0) !== 13 || !_char) && console && console.warn // eslint-disable-line no-console
       && !this._warned) {
         this._warned = true;
         console.warn('Missing character from exported characters list: ', _char, style, font); // eslint-disable-line no-console
       }
-
       return emptyChar;
     }
-
     function measureText(_char2, fontName, size) {
-      var fontData = this.getFontByName(fontName); // Using the char instead of char.charCodeAt(0)
+      var fontData = this.getFontByName(fontName);
+      // Using the char instead of char.charCodeAt(0)
       // to avoid collisions between equal chars
-
       var index = _char2;
-
       if (!fontData.cache[index]) {
         var tHelper = fontData.helper;
-
         if (_char2 === ' ') {
           var doubleSize = tHelper.measureText('|' + _char2 + '|');
           var singleSize = tHelper.measureText('||');
@@ -7544,111 +6361,90 @@
           fontData.cache[index] = tHelper.measureText(_char2) / 100;
         }
       }
-
       return fontData.cache[index] * size;
     }
-
     function getFontByName(name) {
       var i = 0;
       var len = this.fonts.length;
-
       while (i < len) {
         if (this.fonts[i].fName === name) {
           return this.fonts[i];
         }
-
         i += 1;
       }
-
       return this.fonts[0];
     }
-
     function getCodePoint(string) {
       var codePoint = 0;
       var first = string.charCodeAt(0);
-
       if (first >= 0xD800 && first <= 0xDBFF) {
         var second = string.charCodeAt(1);
-
         if (second >= 0xDC00 && second <= 0xDFFF) {
           codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
         }
       }
-
       return codePoint;
-    } // Skin tone modifiers
+    }
 
-
+    // Skin tone modifiers
     function isModifier(firstCharCode, secondCharCode) {
       var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
       return surrogateModifiers.indexOf(sum) !== -1;
     }
-
     function isZeroWidthJoiner(charCode) {
       return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
-    } // This codepoint may change the appearance of the preceding character.
+    }
+
+    // This codepoint may change the appearance of the preceding character.
     // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
     // as a colorful image as compared to a monochrome text variant.
-
-
     function isVariationSelector(charCode) {
       return charCode === VARIATION_SELECTOR_16_CODE_POINT;
-    } // The regional indicator symbols are a set of 26 alphabetic Unicode
+    }
+
+    // The regional indicator symbols are a set of 26 alphabetic Unicode
     /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
     // two-letter country codes in a way that allows optional special treatment.
-
-
     function isRegionalCode(string) {
       var codePoint = getCodePoint(string);
-
       if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
         return true;
       }
-
       return false;
-    } // Some Emoji implementations represent combinations of
+    }
+
+    // Some Emoji implementations represent combinations of
     // two “regional indicator” letters as a single flag symbol.
-
-
     function isFlagEmoji(string) {
       return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
     }
-
     function isCombinedCharacter(_char3) {
       return combinedCharacters.indexOf(_char3) !== -1;
-    } // Regional flags start with a BLACK_FLAG_CODE_POINT
+    }
+
+    // Regional flags start with a BLACK_FLAG_CODE_POINT
     // folowed by 5 chars in the TAG range
     // and end with a CANCEL_TAG_CODE_POINT
-
-
     function isRegionalFlag(text, index) {
       var codePoint = getCodePoint(text.substr(index, 2));
-
       if (codePoint !== BLACK_FLAG_CODE_POINT) {
         return false;
       }
-
       var count = 0;
       index += 2;
-
       while (count < 5) {
         codePoint = getCodePoint(text.substr(index, 2));
-
         if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
           return false;
         }
-
         count += 1;
         index += 2;
       }
-
       return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
     }
-
     function setIsLoaded() {
       this.isLoaded = true;
     }
-
     var Font = function Font() {
       this.fonts = [];
       this.chars = null;
@@ -7659,7 +6455,6 @@
       this.setIsLoadedBinded = this.setIsLoaded.bind(this);
       this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
     };
-
     Font.isModifier = isModifier;
     Font.isZeroWidthJoiner = isZeroWidthJoiner;
     Font.isFlagEmoji = isFlagEmoji;
@@ -7684,30 +6479,26 @@
   function SlotManager(animationData) {
     this.animationData = animationData;
   }
-
   SlotManager.prototype.getProp = function (data) {
     if (this.animationData.slots && this.animationData.slots[data.sid]) {
       return Object.assign(data, this.animationData.slots[data.sid].p);
     }
-
     return data;
   };
-
   function slotFactory(animationData) {
     return new SlotManager(animationData);
   }
 
   function RenderableElement() {}
-
   RenderableElement.prototype = {
     initRenderable: function initRenderable() {
       // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
-      this.isInRange = false; // layer's display state
-
-      this.hidden = false; // If layer's transparency equals 0, it can be hidden
-
-      this.isTransparent = false; // list of animated components
-
+      this.isInRange = false;
+      // layer's display state
+      this.hidden = false;
+      // If layer's transparency equals 0, it can be hidden
+      this.isTransparent = false;
+      // list of animated components
       this.renderableComponents = [];
     },
     addRenderableComponent: function addRenderableComponent(component) {
@@ -7734,7 +6525,6 @@
         this.show();
       }
     },
-
     /**
        * @function
        * Initializes frame related properties.
@@ -7760,13 +6550,11 @@
     renderRenderable: function renderRenderable() {
       var i;
       var len = this.renderableComponents.length;
-
       for (i = 0; i < len; i += 1) {
         this.renderableComponents[i].renderFrame(this._isFirstFrame);
       }
       /* this.maskManager.renderFrame(this.finalTransform.mat);
           this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
-
     },
     sourceRectAtTime: function sourceRectAtTime() {
       return {
@@ -7783,7 +6571,6 @@
           h: this.data.textData.height
         };
       }
-
       return {
         w: this.data.width,
         h: this.data.height
@@ -7818,31 +6605,24 @@
   function SliderEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function AngleEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function ColorEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function PointEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function LayerIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function MaskIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function CheckboxEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function NoValueEffect() {
     this.p = {};
   }
@@ -7853,20 +6633,16 @@
     var i;
     var len = effects.length;
     var effectItem;
-
     for (i = 0; i < len; i += 1) {
       effectItem = new GroupEffect(effects[i], element);
       this.effectElements.push(effectItem);
     }
   }
-
   function GroupEffect(data, element) {
     this.init(data, element);
   }
-
   extendPrototype([DynamicPropertyContainer], GroupEffect);
   GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
-
   GroupEffect.prototype.init = function (data, element) {
     this.data = data;
     this.effectElements = [];
@@ -7875,50 +6651,39 @@
     var len = this.data.ef.length;
     var eff;
     var effects = this.data.ef;
-
     for (i = 0; i < len; i += 1) {
       eff = null;
-
       switch (effects[i].ty) {
         case 0:
           eff = new SliderEffect(effects[i], element, this);
           break;
-
         case 1:
           eff = new AngleEffect(effects[i], element, this);
           break;
-
         case 2:
           eff = new ColorEffect(effects[i], element, this);
           break;
-
         case 3:
           eff = new PointEffect(effects[i], element, this);
           break;
-
         case 4:
         case 7:
           eff = new CheckboxEffect(effects[i], element, this);
           break;
-
         case 10:
           eff = new LayerIndexEffect(effects[i], element, this);
           break;
-
         case 11:
           eff = new MaskIndexEffect(effects[i], element, this);
           break;
-
         case 5:
           eff = new EffectsManager(effects[i], element, this);
           break;
         // case 6:
-
         default:
           eff = new NoValueEffect(effects[i], element, this);
           break;
       }
-
       if (eff) {
         this.effectElements.push(eff);
       }
@@ -7926,47 +6691,37 @@
   };
 
   function BaseElement() {}
-
   BaseElement.prototype = {
     checkMasks: function checkMasks() {
       if (!this.data.hasMask) {
         return false;
       }
-
       var i = 0;
       var len = this.data.masksProperties.length;
-
       while (i < len) {
         if (this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false) {
           return true;
         }
-
         i += 1;
       }
-
       return false;
     },
     initExpressions: function initExpressions() {
       var expressionsInterfaces = getExpressionInterfaces();
-
       if (!expressionsInterfaces) {
         return;
       }
-
       var LayerExpressionInterface = expressionsInterfaces('layer');
       var EffectsExpressionInterface = expressionsInterfaces('effects');
       var ShapeExpressionInterface = expressionsInterfaces('shape');
       var TextExpressionInterface = expressionsInterfaces('text');
       var CompExpressionInterface = expressionsInterfaces('comp');
       this.layerInterface = LayerExpressionInterface(this);
-
       if (this.data.hasMask && this.maskManager) {
         this.layerInterface.registerMaskInterface(this.maskManager);
       }
-
       var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
       this.layerInterface.registerEffectsInterface(effectsInterface);
-
       if (this.data.ty === 0 || this.data.xt) {
         this.compInterface = CompExpressionInterface(this);
       } else if (this.data.ty === 4) {
@@ -7986,13 +6741,13 @@
       this.globalData = globalData;
       this.comp = comp;
       this.data = data;
-      this.layerId = createElementID(); // Stretch factor for old animations missing this property.
+      this.layerId = createElementID();
 
+      // Stretch factor for old animations missing this property.
       if (!this.data.sr) {
         this.data.sr = 1;
-      } // effects manager
-
-
+      }
+      // effects manager
       this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
     },
     getType: function getType() {
@@ -8007,8 +6762,8 @@
    * Checks layer in point and out point
    *
    */
-  function FrameElement() {}
 
+  function FrameElement() {}
   FrameElement.prototype = {
     /**
        * @function
@@ -8017,13 +6772,12 @@
        */
     initFrame: function initFrame() {
       // set to true when inpoint is rendered
-      this._isFirstFrame = false; // list of animated properties
-
-      this.dynamicProperties = []; // If layer has been modified in current tick this will be true
-
+      this._isFirstFrame = false;
+      // list of animated properties
+      this.dynamicProperties = [];
+      // If layer has been modified in current tick this will be true
       this._mdf = false;
     },
-
     /**
        * @function
        * Calculates all dynamic values
@@ -8037,11 +6791,9 @@
     prepareProperties: function prepareProperties(num, isVisible) {
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         if (isVisible || this._isParent && this.dynamicProperties[i].propType === 'transform') {
           this.dynamicProperties[i].getValue();
-
           if (this.dynamicProperties[i]._mdf) {
             this.globalData._mdf = true;
             this._mdf = true;
@@ -8063,30 +6815,21 @@
     this.footageData = globalData.imageLoader.getAsset(this.assetData);
     this.initBaseData(data, globalData, comp);
   }
-
   FootageElement.prototype.prepareFrame = function () {};
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
-
   FootageElement.prototype.getBaseElement = function () {
     return null;
   };
-
   FootageElement.prototype.renderFrame = function () {};
-
   FootageElement.prototype.destroy = function () {};
-
   FootageElement.prototype.initExpressions = function () {
     var expressionsInterfaces = getExpressionInterfaces();
-
     if (!expressionsInterfaces) {
       return;
     }
-
     var FootageInterface = expressionsInterfaces('footage');
     this.layerInterface = FootageInterface(this);
   };
-
   FootageElement.prototype.getFootageData = function () {
     return this.footageData;
   };
@@ -8112,29 +6855,23 @@
       k: [100]
     }, 1, 0.01, this);
   }
-
   AudioElement.prototype.prepareFrame = function (num) {
     this.prepareRenderableFrame(num, true);
     this.prepareProperties(num, true);
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
       this._currentTime = timeRemapped;
     } else {
       this._currentTime = num / this.data.sr;
     }
-
     this._volume = this.lv.v[0];
     var totalVolume = this._volume * this._volumeMultiplier;
-
     if (this._previousVolume !== totalVolume) {
       this._previousVolume = totalVolume;
       this.audio.volume(totalVolume);
     }
   };
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
-
   AudioElement.prototype.renderFrame = function () {
     if (this.isInRange && this._canPlay) {
       if (!this._isPlaying) {
@@ -8146,162 +6883,124 @@
       }
     }
   };
-
-  AudioElement.prototype.show = function () {// this.audio.play()
+  AudioElement.prototype.show = function () {
+    // this.audio.play()
   };
-
   AudioElement.prototype.hide = function () {
     this.audio.pause();
     this._isPlaying = false;
   };
-
   AudioElement.prototype.pause = function () {
     this.audio.pause();
     this._isPlaying = false;
     this._canPlay = false;
   };
-
   AudioElement.prototype.resume = function () {
     this._canPlay = true;
   };
-
   AudioElement.prototype.setRate = function (rateValue) {
     this.audio.rate(rateValue);
   };
-
   AudioElement.prototype.volume = function (volumeValue) {
     this._volumeMultiplier = volumeValue;
     this._previousVolume = volumeValue * this._volume;
     this.audio.volume(this._previousVolume);
   };
-
   AudioElement.prototype.getBaseElement = function () {
     return null;
   };
-
   AudioElement.prototype.destroy = function () {};
-
   AudioElement.prototype.sourceRectAtTime = function () {};
-
   AudioElement.prototype.initExpressions = function () {};
 
   function BaseRenderer() {}
-
   BaseRenderer.prototype.checkLayers = function (num) {
     var i;
     var len = this.layers.length;
     var data;
     this.completeLayers = true;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (!this.elements[i]) {
         data = this.layers[i];
-
         if (data.ip - data.st <= num - this.layers[i].st && data.op - data.st > num - this.layers[i].st) {
           this.buildItem(i);
         }
       }
-
       this.completeLayers = this.elements[i] ? this.completeLayers : false;
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.createItem = function (layer) {
     switch (layer.ty) {
       case 2:
         return this.createImage(layer);
-
       case 0:
         return this.createComp(layer);
-
       case 1:
         return this.createSolid(layer);
-
       case 3:
         return this.createNull(layer);
-
       case 4:
         return this.createShape(layer);
-
       case 5:
         return this.createText(layer);
-
       case 6:
         return this.createAudio(layer);
-
       case 13:
         return this.createCamera(layer);
-
       case 15:
         return this.createFootage(layer);
-
       default:
         return this.createNull(layer);
     }
   };
-
   BaseRenderer.prototype.createCamera = function () {
     throw new Error('You\'re using a 3d camera. Try the html renderer.');
   };
-
   BaseRenderer.prototype.createAudio = function (data) {
     return new AudioElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.createFootage = function (data) {
     return new FootageElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.buildAllItems = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       this.buildItem(i);
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.includeLayers = function (newLayers) {
     this.completeLayers = false;
     var i;
     var len = newLayers.length;
     var j;
     var jLen = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       j = 0;
-
       while (j < jLen) {
         if (this.layers[j].id === newLayers[i].id) {
           this.layers[j] = newLayers[i];
           break;
         }
-
         j += 1;
       }
     }
   };
-
   BaseRenderer.prototype.setProjectInterface = function (pInterface) {
     this.globalData.projectInterface = pInterface;
   };
-
   BaseRenderer.prototype.initItems = function () {
     if (!this.globalData.progressiveLoad) {
       this.buildAllItems();
     }
   };
-
   BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
     var elements = this.elements;
     var layers = this.layers;
     var i = 0;
     var len = layers.length;
-
     while (i < len) {
       if (layers[i].ind == parentName) {
         // eslint-disable-line eqeqeq
@@ -8311,7 +7010,6 @@
         } else {
           hierarchy.push(elements[i]);
           elements[i].setAsParent();
-
           if (layers[i].parent !== undefined) {
             this.buildElementParenting(element, layers[i].parent, hierarchy);
           } else {
@@ -8319,19 +7017,15 @@
           }
         }
       }
-
       i += 1;
     }
   };
-
   BaseRenderer.prototype.addPendingElement = function (element) {
     this.pendingElements.push(element);
   };
-
   BaseRenderer.prototype.searchExtraCompositions = function (assets) {
     var i;
     var len = assets.length;
-
     for (i = 0; i < len; i += 1) {
       if (assets[i].xt) {
         var comp = this.createComp(assets[i]);
@@ -8340,30 +7034,24 @@
       }
     }
   };
-
   BaseRenderer.prototype.getElementById = function (ind) {
     var i;
     var len = this.elements.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i].data.ind === ind) {
         return this.elements[i];
       }
     }
-
     return null;
   };
-
   BaseRenderer.prototype.getElementByPath = function (path) {
     var pathValue = path.shift();
     var element;
-
     if (typeof pathValue === 'number') {
       element = this.elements[pathValue];
     } else {
       var i;
       var len = this.elements.length;
-
       for (i = 0; i < len; i += 1) {
         if (this.elements[i].data.nm === pathValue) {
           element = this.elements[i];
@@ -8371,14 +7059,11 @@
         }
       }
     }
-
     if (path.length === 0) {
       return element;
     }
-
     return element.getElementByPath(path);
   };
-
   BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
     this.globalData.fontManager = new FontManager();
     this.globalData.slotManager = slotFactory(animData);
@@ -8402,7 +7087,6 @@
   };
 
   function TransformElement() {}
-
   TransformElement.prototype = {
     initTransform: function initTransform() {
       var mat = new Matrix();
@@ -8417,50 +7101,44 @@
         localMat: mat,
         localOpacity: 1
       };
-
       if (this.data.ao) {
         this.finalTransform.mProp.autoOriented = true;
-      } // TODO: check TYPE 11: Guided elements
+      }
 
-
-      if (this.data.ty !== 11) {// this.createElements();
+      // TODO: check TYPE 11: Guided elements
+      if (this.data.ty !== 11) {
+        // this.createElements();
       }
     },
     renderTransform: function renderTransform() {
       this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
       this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
-
       if (this.hierarchy) {
         var mat;
         var finalMat = this.finalTransform.mat;
         var i = 0;
-        var len = this.hierarchy.length; // Checking if any of the transformation matrices in the hierarchy chain has changed.
-
+        var len = this.hierarchy.length;
+        // Checking if any of the transformation matrices in the hierarchy chain has changed.
         if (!this.finalTransform._matMdf) {
           while (i < len) {
             if (this.hierarchy[i].finalTransform.mProp._mdf) {
               this.finalTransform._matMdf = true;
               break;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._matMdf) {
           mat = this.finalTransform.mProp.v.props;
           finalMat.cloneFromProps(mat);
-
           for (i = 0; i < len; i += 1) {
             finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
           }
         }
       }
-
-      if (this.finalTransform._matMdf) {
+      if (!this.localTransforms || this.finalTransform._matMdf) {
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
       }
-
       if (this.finalTransform._opMdf) {
         this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
       }
@@ -8470,41 +7148,32 @@
         var i = 0;
         var len = this.localTransforms.length;
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
-
         if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
           while (i < len) {
             if (this.localTransforms[i]._mdf) {
               this.finalTransform._localMatMdf = true;
             }
-
             if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
               this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
               this.finalTransform._opMdf = true;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._localMatMdf) {
           var localMat = this.finalTransform.localMat;
           this.localTransforms[0].matrix.clone(localMat);
-
           for (i = 1; i < len; i += 1) {
             var lmat = this.localTransforms[i].matrix;
             localMat.multiply(lmat);
           }
-
           localMat.multiply(this.finalTransform.mat);
         }
-
         if (this.finalTransform._opMdf) {
           var localOp = this.finalTransform.localOpacity;
-
           for (i = 0; i < len; i += 1) {
             localOp *= this.localTransforms[i].opacity * 0.01;
           }
-
           this.finalTransform.localOpacity = localOp;
         }
       }
@@ -8512,13 +7181,11 @@
     searchEffectTransforms: function searchEffectTransforms() {
       if (this.renderableEffectsManager) {
         var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
-
         if (transformEffects.length) {
           this.localTransforms = [];
           this.finalTransform.localMat = new Matrix();
           var i = 0;
           var len = transformEffects.length;
-
           for (i = 0; i < len; i += 1) {
             this.localTransforms.push(transformEffects[i]);
           }
@@ -8530,29 +7197,24 @@
       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;
       var len = transforms.length;
       var 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]);
-
+        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;
     },
     mHelper: new Matrix()
@@ -8583,13 +7245,11 @@
     var x;
     var maskType = 'clipPath';
     var maskRef = 'clip-path';
-
     for (i = 0; i < len; i += 1) {
       if (properties[i].mode !== 'a' && properties[i].mode !== 'n' || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
         maskType = 'mask';
         maskRef = 'mask';
       }
-
       if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
         rect = createNS('rect');
         rect.setAttribute('fill', '#ffffff');
@@ -8599,9 +7259,7 @@
       } else {
         rect = null;
       }
-
       path = createNS('path');
-
       if (properties[i].mode === 'n') {
         // TODO move this to a factory or to a constructor
         this.viewData[i] = {
@@ -8616,7 +7274,6 @@
         path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
         path.setAttribute('clip-rule', 'nonzero');
         var filterID;
-
         if (properties[i].x.k !== 0) {
           maskType = 'mask';
           maskRef = 'mask';
@@ -8634,9 +7291,9 @@
         } else {
           feMorph = null;
           x = null;
-        } // TODO move this to a factory or to a constructor
+        }
 
-
+        // TODO move this to a factory or to a constructor
         this.storedData[i] = {
           elem: path,
           x: x,
@@ -8646,15 +7303,12 @@
           filterId: filterID,
           lastRadius: 0
         };
-
         if (properties[i].mode === 'i') {
           jLen = currentMasks.length;
           var g = createNS('g');
-
           for (j = 0; j < jLen; j += 1) {
             g.appendChild(currentMasks[j]);
           }
-
           var mask = createNS('mask');
           mask.setAttribute('mask-type', 'alpha');
           mask.setAttribute('id', layerId + '_' + count);
@@ -8666,12 +7320,10 @@
         } else {
           currentMasks.push(path);
         }
-
         if (properties[i].inv && !this.solidPath) {
           this.solidPath = this.createLayerSolidPath();
-        } // TODO move this to a factory or to a constructor
-
-
+        }
+        // TODO move this to a factory or to a constructor
         this.viewData[i] = {
           elem: path,
           lastPath: '',
@@ -8679,81 +7331,65 @@
           prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
           invRect: rect
         };
-
         if (!this.viewData[i].prop.k) {
           this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
         }
       }
     }
-
     this.maskElement = createNS(maskType);
     len = currentMasks.length;
-
     for (i = 0; i < len; i += 1) {
       this.maskElement.appendChild(currentMasks[i]);
     }
-
     if (count > 0) {
       this.maskElement.setAttribute('id', layerId);
       this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
       defs.appendChild(this.maskElement);
     }
-
     if (this.viewData.length) {
       this.element.addRenderableComponent(this);
     }
   }
-
   MaskElement.prototype.getMaskProperty = function (pos) {
     return this.viewData[pos].prop;
   };
-
   MaskElement.prototype.renderFrame = function (isFirstFrame) {
     var finalMat = this.element.finalTransform.mat;
     var i;
     var len = this.masksProperties.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.viewData[i].prop._mdf || isFirstFrame) {
         this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
       }
-
       if (this.viewData[i].op._mdf || isFirstFrame) {
         this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
       }
-
       if (this.masksProperties[i].mode !== 'n') {
         if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
           this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
         }
-
         if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
           var feMorph = this.storedData[i].expan;
-
           if (this.storedData[i].x.v < 0) {
             if (this.storedData[i].lastOperator !== 'erode') {
               this.storedData[i].lastOperator = 'erode';
               this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
             }
-
             feMorph.setAttribute('radius', -this.storedData[i].x.v);
           } else {
             if (this.storedData[i].lastOperator !== 'dilate') {
               this.storedData[i].lastOperator = 'dilate';
               this.storedData[i].elem.setAttribute('filter', null);
             }
-
             this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
           }
         }
       }
     }
   };
-
   MaskElement.prototype.getMaskelement = function () {
     return this.maskElement;
   };
-
   MaskElement.prototype.createLayerSolidPath = function () {
     var path = 'M0,0 ';
     path += ' h' + this.globalData.compSize.w;
@@ -8762,39 +7398,32 @@
     path += ' v-' + this.globalData.compSize.h + ' ';
     return path;
   };
-
   MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
     var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
     var i;
     var len;
     len = pathNodes._length;
-
     for (i = 1; i < len; i += 1) {
       // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
-    } // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
-
-
+    }
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
     if (pathNodes.c && len > 1) {
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
-    } // pathNodes.__renderedString = pathString;
-
+    }
+    // pathNodes.__renderedString = pathString;
 
     if (viewData.lastPath !== pathString) {
       var pathShapeValue = '';
-
       if (viewData.elem) {
         if (pathNodes.c) {
           pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
         }
-
         viewData.elem.setAttribute('d', pathShapeValue);
       }
-
       viewData.lastPath = pathString;
     }
   };
-
   MaskElement.prototype.destroy = function () {
     this.element = null;
     this.globalData = null;
@@ -8807,11 +7436,9 @@
     var ob = {};
     ob.createFilter = createFilter;
     ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
-
     function createFilter(filId, skipCoordinates) {
       var fil = createNS('filter');
       fil.setAttribute('id', filId);
-
       if (skipCoordinates !== true) {
         fil.setAttribute('filterUnits', 'objectBoundingBox');
         fil.setAttribute('x', '0%');
@@ -8819,10 +7446,8 @@
         fil.setAttribute('width', '100%');
         fil.setAttribute('height', '100%');
       }
-
       return fil;
     }
-
     function createAlphaToLuminanceFilter() {
       var feColorMatrix = createNS('feColorMatrix');
       feColorMatrix.setAttribute('type', 'matrix');
@@ -8830,7 +7455,6 @@
       feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
       return feColorMatrix;
     }
-
     return ob;
   }();
 
@@ -8840,21 +7464,17 @@
       svgLumaHidden: true,
       offscreenCanvas: typeof OffscreenCanvas !== 'undefined'
     };
-
     if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
       ob.maskType = false;
     }
-
     if (/firefox/i.test(navigator.userAgent)) {
       ob.svgLumaHidden = false;
     }
-
     return ob;
   }();
 
   var registeredEffects = {};
   var idPrefix = 'filter_result_';
-
   function SVGEffects(elem) {
     var i;
     var source = 'SourceGraphic';
@@ -8864,59 +7484,47 @@
     var count = 0;
     this.filters = [];
     var filterManager;
-
     for (i = 0; i < len; i += 1) {
       filterManager = null;
       var type = elem.data.ef[i].ty;
-
       if (registeredEffects[type]) {
         var Effect = registeredEffects[type].effect;
         filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
         source = idPrefix + count;
-
         if (registeredEffects[type].countsAsEffect) {
           count += 1;
         }
       }
-
       if (filterManager) {
         this.filters.push(filterManager);
       }
     }
-
     if (count) {
       elem.globalData.defs.appendChild(fil);
       elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
     }
-
     if (this.filters.length) {
       elem.addRenderableComponent(this);
     }
   }
-
   SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
     var i;
     var len = this.filters.length;
-
     for (i = 0; i < len; i += 1) {
       this.filters[i].renderFrame(_isFirstFrame);
     }
   };
-
   SVGEffects.prototype.getEffects = function (type) {
     var i;
     var len = this.filters.length;
     var effects = [];
-
     for (i = 0; i < len; i += 1) {
       if (this.filters[i].type === type) {
         effects.push(this.filters[i]);
       }
     }
-
     return effects;
   };
-
   function registerEffect(id, effect, countsAsEffect) {
     registeredEffects[id] = {
       effect: effect,
@@ -8925,7 +7533,6 @@
   }
 
   function SVGBaseElement() {}
-
   SVGBaseElement.prototype = {
     initRendererElement: function initRendererElement() {
       this.layerElement = createNS('g');
@@ -8935,8 +7542,8 @@
       this.transformedElement = this.layerElement;
       this.maskedElement = this.layerElement;
       this._sizeChanged = false;
-      var layerElementParent = null; // If this layer acts as a mask for the following layer
-
+      var layerElementParent = null;
+      // If this layer acts as a mask for the following layer
       if (this.data.td) {
         this.matteMasks = {};
         var gg = createNS('g');
@@ -8951,16 +7558,13 @@
       } else {
         this.baseElement = this.layerElement;
       }
-
       if (this.data.ln) {
         this.layerElement.setAttribute('id', this.data.ln);
       }
-
       if (this.data.cl) {
         this.layerElement.setAttribute('class', this.data.cl);
-      } // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
-
-
+      }
+      // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
       if (this.data.ty === 0 && !this.data.hd) {
         var cp = createNS('clipPath');
         var pt = createNS('path');
@@ -8969,13 +7573,11 @@
         cp.setAttribute('id', clipId);
         cp.appendChild(pt);
         this.globalData.defs.appendChild(cp);
-
         if (this.checkMasks()) {
           var cpGroup = createNS('g');
           cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
           cpGroup.appendChild(this.layerElement);
           this.transformedElement = cpGroup;
-
           if (layerElementParent) {
             layerElementParent.appendChild(this.transformedElement);
           } else {
@@ -8985,7 +7587,6 @@
           this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
         }
       }
-
       if (this.data.bm !== 0) {
         this.setBlendMode();
       }
@@ -8994,7 +7595,6 @@
       if (this.finalTransform._localMatMdf) {
         this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
       }
-
       if (this.finalTransform._opMdf) {
         this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
       }
@@ -9008,7 +7608,6 @@
       if (this.data.hd) {
         return null;
       }
-
       return this.baseElement;
     },
     createRenderableComponents: function createRenderableComponents() {
@@ -9023,14 +7622,12 @@
       if (!this.matteMasks) {
         this.matteMasks = {};
       }
-
       if (!this.matteMasks[matteType]) {
         var id = this.layerId + '_' + matteType;
         var filId;
         var fil;
         var useElement;
         var gg;
-
         if (matteType === 1 || matteType === 3) {
           var masker = createNS('mask');
           masker.setAttribute('id', id);
@@ -9039,7 +7636,6 @@
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           masker.appendChild(useElement);
           this.globalData.defs.appendChild(masker);
-
           if (!featureSupport.maskType && matteType === 1) {
             masker.setAttribute('mask-type', 'luminance');
             filId = createElementID();
@@ -9058,16 +7654,16 @@
           var maskGrouper = createNS('g');
           maskGroup.appendChild(maskGrouper);
           filId = createElementID();
-          fil = filtersFactory.createFilter(filId); /// /
-
+          fil = filtersFactory.createFilter(filId);
+          /// /
           var feCTr = createNS('feComponentTransfer');
           feCTr.setAttribute('in', 'SourceGraphic');
           fil.appendChild(feCTr);
           var feFunc = createNS('feFuncA');
           feFunc.setAttribute('type', 'table');
           feFunc.setAttribute('tableValues', '1.0 0.0');
-          feCTr.appendChild(feFunc); /// /
-
+          feCTr.appendChild(feFunc);
+          /// /
           this.globalData.defs.appendChild(fil);
           var alphaRect = createNS('rect');
           alphaRect.setAttribute('width', this.comp.data.w);
@@ -9081,7 +7677,6 @@
           useElement = createNS('use');
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           maskGrouper.appendChild(useElement);
-
           if (!featureSupport.maskType) {
             maskGroup.setAttribute('mask-type', 'luminance');
             fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
@@ -9090,20 +7685,16 @@
             gg.appendChild(this.layerElement);
             maskGrouper.appendChild(gg);
           }
-
           this.globalData.defs.appendChild(maskGroup);
         }
-
         this.matteMasks[matteType] = id;
       }
-
       return this.matteMasks[matteType];
     },
     setMatte: function setMatte(id) {
       if (!this.matteElement) {
         return;
       }
-
       this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
     }
   };
@@ -9113,8 +7704,8 @@
    * Handles AE's layer parenting property.
    *
    */
-  function HierarchyElement() {}
 
+  function HierarchyElement() {}
   HierarchyElement.prototype = {
     /**
        * @function
@@ -9123,12 +7714,11 @@
        */
     initHierarchy: function initHierarchy() {
       // element's parent list
-      this.hierarchy = []; // if element is parent of another layer _isParent will be true
-
+      this.hierarchy = [];
+      // if element is parent of another layer _isParent will be true
       this._isParent = false;
       this.checkParenting();
     },
-
     /**
        * @function
        * Sets layer's hierarchy.
@@ -9139,7 +7729,6 @@
     setHierarchy: function setHierarchy(hierarchy) {
       this.hierarchy = hierarchy;
     },
-
     /**
        * @function
        * Sets layer as parent.
@@ -9148,7 +7737,6 @@
     setAsParent: function setAsParent() {
       this._isParent = true;
     },
-
     /**
        * @function
        * Searches layer's parenting chain
@@ -9162,7 +7750,6 @@
   };
 
   function RenderableDOMElement() {}
-
   (function () {
     var _prototype = {
       initElement: function initElement(data, globalData, comp) {
@@ -9192,7 +7779,6 @@
             var elem = this.baseElement || this.layerElement;
             elem.style.display = 'block';
           }
-
           this.hidden = false;
           this._isFirstFrame = true;
         }
@@ -9203,13 +7789,11 @@
         if (this.data.hd || this.hidden) {
           return;
         }
-
         this.renderTransform();
         this.renderRenderable();
         this.renderLocalTransform();
         this.renderElement();
         this.renderInnerContent();
-
         if (this._isFirstFrame) {
           this._isFirstFrame = false;
         }
@@ -9231,11 +7815,9 @@
 
   function IImageElement(data, globalData, comp) {
     this.assetData = globalData.getAssetData(data.refId);
-
     if (this.assetData && this.assetData.sid) {
       this.assetData = globalData.slotManager.getProp(this.assetData);
     }
-
     this.initElement(data, globalData, comp);
     this.sourceRect = {
       top: 0,
@@ -9244,9 +7826,7 @@
       height: this.assetData.h
     };
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
-
   IImageElement.prototype.createContent = function () {
     var assetPath = this.globalData.getAssetsPath(this.assetData);
     this.innerElem = createNS('image');
@@ -9256,7 +7836,6 @@
     this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
     this.layerElement.appendChild(this.innerElem);
   };
-
   IImageElement.prototype.sourceRectAtTime = function () {
     return this.sourceRect;
   };
@@ -9267,12 +7846,10 @@
   }
 
   function IShapeElement() {}
-
   IShapeElement.prototype = {
     addShapeToModifiers: function addShapeToModifiers(data) {
       var i;
       var len = this.shapeModifiers.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapeModifiers[i].addShape(data);
       }
@@ -9280,34 +7857,28 @@
     isShapeInAnimatedModifiers: function isShapeInAnimatedModifiers(data) {
       var i = 0;
       var len = this.shapeModifiers.length;
-
       while (i < len) {
         if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
           return true;
         }
       }
-
       return false;
     },
     renderModifiers: function renderModifiers() {
       if (!this.shapeModifiers.length) {
         return;
       }
-
       var i;
       var len = this.shapes.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapes[i].sh.reset();
       }
-
       len = this.shapeModifiers.length;
       var shouldBreakProcess;
-
       for (i = len - 1; i >= 0; i -= 1) {
-        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame); // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+        // workaround to fix cases where a repeater resets the shape so the following processes get called twice
         // TODO: find a better solution for this
-
         if (shouldBreakProcess) {
           break;
         }
@@ -9317,30 +7888,24 @@
       var elements = this.processedElements;
       var i = 0;
       var len = elements.length;
-
       while (i < len) {
         if (elements[i].elem === elem) {
           return elements[i].pos;
         }
-
         i += 1;
       }
-
       return 0;
     },
     addProcessedElement: function addProcessedElement(elem, pos) {
       var elements = this.processedElements;
       var i = elements.length;
-
       while (i) {
         i -= 1;
-
         if (elements[i].elem === elem) {
           elements[i].pos = pos;
           return;
         }
       }
-
       elements.push(new ProcessedElement(elem, pos));
     },
     prepareFrame: function prepareFrame(num) {
@@ -9366,25 +7931,22 @@
     this.transformers = transformers;
     this.lStr = '';
     this.sh = shape;
-    this.lvl = level; // TODO find if there are some cases where _isAnimated can be false.
+    this.lvl = level;
+    // TODO find if there are some cases where _isAnimated can be false.
     // For now, since shapes add up with other shapes. They have to be calculated every time.
     // One way of finding out is checking if all styles associated to this shape depend only of this shape
-
-    this._isAnimated = !!shape.k; // TODO: commenting this for now since all shapes are animated
-
+    this._isAnimated = !!shape.k;
+    // TODO: commenting this for now since all shapes are animated
     var i = 0;
     var len = transformers.length;
-
     while (i < len) {
       if (transformers[i].mProps.dynamicProperties.length) {
         this._isAnimated = true;
         break;
       }
-
       i += 1;
     }
   }
-
   SVGShapeData.prototype.setAsAnimated = function () {
     this._isAnimated = true;
   };
@@ -9399,7 +7961,6 @@
     this.pElem = createNS('path');
     this.msElem = null;
   }
-
   SVGStyleData.prototype.reset = function () {
     this.d = '';
     this._mdf = false;
@@ -9418,7 +7979,6 @@
     var i;
     var len = data.length || 0;
     var prop;
-
     for (i = 0; i < len; i += 1) {
       prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
       this.k = prop.k || this.k;
@@ -9427,31 +7987,24 @@
         p: prop
       };
     }
-
     if (!this.k) {
       this.getValue(true);
     }
-
     this._isAnimated = this.k;
   }
-
   DashProperty.prototype.getValue = function (forceRender) {
     if (this.elem.globalData.frameId === this.frameId && !forceRender) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
     this._mdf = this._mdf || forceRender;
-
     if (this._mdf) {
       var i = 0;
       var len = this.dataProps.length;
-
       if (this.renderer === 'svg') {
         this.dashStr = '';
       }
-
       for (i = 0; i < len; i += 1) {
         if (this.dataProps[i].n !== 'o') {
           if (this.renderer === 'svg') {
@@ -9465,7 +8018,6 @@
       }
     }
   };
-
   extendPrototype([DynamicPropertyContainer], DashProperty);
 
   function SVGStrokeStyleData(elem, data, styleOb) {
@@ -9478,7 +8030,6 @@
     this.style = styleOb;
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
 
   function SVGFillStyleData(elem, data, styleOb) {
@@ -9488,7 +8039,6 @@
     this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
 
   function SVGNoStyleData(elem, data, styleOb) {
@@ -9496,7 +8046,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
 
   function GradientProperty(elem, data, container) {
@@ -9513,88 +8062,69 @@
     this.k = this.prop.k;
     this.getValue(true);
   }
-
   GradientProperty.prototype.comparePoints = function (values, points) {
     var i = 0;
     var len = this.o.length / 2;
     var diff;
-
     while (i < len) {
       diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
-
       if (diff > 0.01) {
         return false;
       }
-
       i += 1;
     }
-
     return true;
   };
-
   GradientProperty.prototype.checkCollapsable = function () {
     if (this.o.length / 2 !== this.c.length / 4) {
       return false;
     }
-
     if (this.data.k.k[0].s) {
       var i = 0;
       var len = this.data.k.k.length;
-
       while (i < len) {
         if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
           return false;
         }
-
         i += 1;
       }
     } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
       return false;
     }
-
     return true;
   };
-
   GradientProperty.prototype.getValue = function (forceRender) {
     this.prop.getValue();
     this._mdf = false;
     this._cmdf = false;
     this._omdf = false;
-
     if (this.prop._mdf || forceRender) {
       var i;
       var len = this.data.p * 4;
       var mult;
       var val;
-
       for (i = 0; i < len; i += 1) {
         mult = i % 4 === 0 ? 100 : 255;
         val = Math.round(this.prop.v[i] * mult);
-
         if (this.c[i] !== val) {
           this.c[i] = val;
           this._cmdf = !forceRender;
         }
       }
-
       if (this.o.length) {
         len = this.prop.v.length;
-
         for (i = this.data.p * 4; i < len; i += 1) {
           mult = i % 2 === 0 ? 100 : 1;
           val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
-
           if (this.o[i - this.data.p * 4] !== val) {
             this.o[i - this.data.p * 4] = val;
             this._omdf = !forceRender;
           }
         }
       }
-
       this._mdf = !forceRender;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], GradientProperty);
 
   function SVGGradientFillStyleData(elem, data, styleOb) {
@@ -9602,7 +8132,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.initGradientData(elem, data, styleOb);
   }
-
   SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
     this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
     this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
@@ -9620,7 +8149,6 @@
     this.setGradientOpacity(data, styleOb);
     this._isAnimated = !!this._isAnimated;
   };
-
   SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
     var gradientId = createElementID();
     var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
@@ -9632,18 +8160,15 @@
     var j;
     var jLen;
     jLen = data.g.p * 4;
-
     for (j = 0; j < jLen; j += 4) {
       stop = createNS('stop');
       gfill.appendChild(stop);
       stops.push(stop);
     }
-
     pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
     this.gf = gfill;
     this.cst = stops;
   };
-
   SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
     if (this.g._hasOpacity && !this.g._collapsable) {
       var stop;
@@ -9661,25 +8186,20 @@
       opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
       jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
       var stops = this.stops;
-
       for (j = data.g.p * 4; j < jLen; j += 2) {
         stop = createNS('stop');
         stop.setAttribute('stop-color', 'rgb(255,255,255)');
         opFill.appendChild(stop);
         stops.push(stop);
       }
-
       maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
@@ -9687,7 +8207,6 @@
       styleOb.msElem = maskElement;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
 
   function SVGGradientStrokeStyleData(elem, data, styleOb) {
@@ -9698,7 +8217,6 @@
     this.initGradientData(elem, data, styleOb);
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
 
   function ShapeGroupData() {
@@ -9721,77 +8239,59 @@
     if (length === 0) {
       return '';
     }
-
     var _o = pathNodes.o;
     var _i = pathNodes.i;
     var _v = pathNodes.v;
     var i;
     var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
-
     for (i = 1; i < length; i += 1) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
     }
-
     if (closed && length) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
       shapeString += 'z';
     }
-
     return shapeString;
   };
 
   var SVGElementsRenderer = function () {
     var _identityMatrix = new Matrix();
-
     var _matrixHelper = new Matrix();
-
     var ob = {
       createRenderFunction: createRenderFunction
     };
-
     function createRenderFunction(data) {
       switch (data.ty) {
         case 'fl':
           return renderFill;
-
         case 'gf':
           return renderGradient;
-
         case 'gs':
           return renderGradientStroke;
-
         case 'st':
           return renderStroke;
-
         case 'sh':
         case 'el':
         case 'rc':
         case 'sr':
           return renderPath;
-
         case 'tr':
           return renderContentTransform;
-
         case 'no':
           return renderNoop;
-
         default:
           return null;
       }
     }
-
     function renderContentTransform(styleData, itemData, isFirstFrame) {
       if (isFirstFrame || itemData.transform.op._mdf) {
         itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
       }
-
       if (isFirstFrame || itemData.transform.mProps._mdf) {
         itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
       }
     }
-
     function renderNoop() {}
-
     function renderPath(styleData, itemData, isFirstFrame) {
       var j;
       var jLen;
@@ -9805,25 +8305,20 @@
       var mat;
       var iterations;
       var k;
-
       for (l = 0; l < lLen; l += 1) {
         redraw = itemData.sh._mdf || isFirstFrame;
-
         if (itemData.styles[l].lvl < lvl) {
           mat = _matrixHelper.reset();
           iterations = lvl - itemData.styles[l].lvl;
           k = itemData.transformers.length - 1;
-
           while (!redraw && iterations > 0) {
             redraw = itemData.transformers[k].mProps._mdf || redraw;
             iterations -= 1;
             k -= 1;
           }
-
           if (redraw) {
             iterations = lvl - itemData.styles[l].lvl;
             k = itemData.transformers.length - 1;
-
             while (iterations > 0) {
               mat.multiply(itemData.transformers[k].mProps.v);
               iterations -= 1;
@@ -9833,115 +8328,90 @@
         } else {
           mat = _identityMatrix;
         }
-
         paths = itemData.sh.paths;
         jLen = paths._length;
-
         if (redraw) {
           pathStringTransformed = '';
-
           for (j = 0; j < jLen; j += 1) {
             pathNodes = paths.shapes[j];
-
             if (pathNodes && pathNodes._length) {
               pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
             }
           }
-
           itemData.caches[l] = pathStringTransformed;
         } else {
           pathStringTransformed = itemData.caches[l];
         }
-
         itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
         itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
       }
     }
-
     function renderFill(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
-
       if (itemData.c._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
       }
     }
-
     function renderGradientStroke(styleData, itemData, isFirstFrame) {
       renderGradient(styleData, itemData, isFirstFrame);
       renderStroke(styleData, itemData, isFirstFrame);
     }
-
     function renderGradient(styleData, itemData, isFirstFrame) {
       var gfill = itemData.gf;
       var hasOpacity = itemData.g._hasOpacity;
       var pt1 = itemData.s.v;
       var pt2 = itemData.e.v;
-
       if (itemData.o._mdf || isFirstFrame) {
         var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
         itemData.style.pElem.setAttribute(attr, itemData.o.v);
       }
-
       if (itemData.s._mdf || isFirstFrame) {
         var attr1 = styleData.t === 1 ? 'x1' : 'cx';
         var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
         gfill.setAttribute(attr1, pt1[0]);
         gfill.setAttribute(attr2, pt1[1]);
-
         if (hasOpacity && !itemData.g._collapsable) {
           itemData.of.setAttribute(attr1, pt1[0]);
           itemData.of.setAttribute(attr2, pt1[1]);
         }
       }
-
       var stops;
       var i;
       var len;
       var stop;
-
       if (itemData.g._cmdf || isFirstFrame) {
         stops = itemData.cst;
         var cValues = itemData.g.c;
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
           stop.setAttribute('offset', cValues[i * 4] + '%');
           stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
         }
       }
-
       if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
         var oValues = itemData.g.o;
-
         if (itemData.g._collapsable) {
           stops = itemData.cst;
         } else {
           stops = itemData.ost;
         }
-
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
-
           if (!itemData.g._collapsable) {
             stop.setAttribute('offset', oValues[i * 2] + '%');
           }
-
           stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
         }
       }
-
       if (styleData.t === 1) {
         if (itemData.e._mdf || isFirstFrame) {
           gfill.setAttribute('x2', pt2[0]);
           gfill.setAttribute('y2', pt2[1]);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('x2', pt2[0]);
             itemData.of.setAttribute('y2', pt2[1]);
@@ -9949,112 +8419,93 @@
         }
       } else {
         var rad;
-
         if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
           rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           gfill.setAttribute('r', rad);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('r', rad);
           }
         }
-
-        if (itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
           if (!rad) {
             rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           }
-
           var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
           var percent = itemData.h.v;
-
           if (percent >= 1) {
             percent = 0.99;
           } else if (percent <= -1) {
             percent = -0.99;
           }
-
           var dist = rad * percent;
           var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
           var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
           gfill.setAttribute('fx', x);
           gfill.setAttribute('fy', y);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('fx', x);
             itemData.of.setAttribute('fy', y);
           }
-        } // gfill.setAttribute('fy','200');
-
+        }
+        // gfill.setAttribute('fy','200');
       }
     }
-
     function renderStroke(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
       var d = itemData.d;
-
       if (d && (d._mdf || isFirstFrame) && d.dashStr) {
         styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
         styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
       }
-
       if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
         styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
       }
-
       if (itemData.w._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
-
         if (styleElem.msElem) {
           styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
         }
       }
     }
-
     return ob;
   }();
 
   function SVGShapeElement(data, globalData, comp) {
     // List of drawable elements
-    this.shapes = []; // Full shape data
-
-    this.shapesData = data.shapes; // List of styles that will be applied to shapes
-
-    this.stylesList = []; // List of modifiers that will be applied to shapes
-
-    this.shapeModifiers = []; // List of items in shape tree
-
-    this.itemsData = []; // List of items in previous shape tree
-
-    this.processedElements = []; // List of animated components
-
+    this.shapes = [];
+    // Full shape data
+    this.shapesData = data.shapes;
+    // List of styles that will be applied to shapes
+    this.stylesList = [];
+    // List of modifiers that will be applied to shapes
+    this.shapeModifiers = [];
+    // List of items in shape tree
+    this.itemsData = [];
+    // List of items in previous shape tree
+    this.processedElements = [];
+    // List of animated components
     this.animatedContents = [];
-    this.initElement(data, globalData, comp); // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.initElement(data, globalData, comp);
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
     // List of elements that have been created
-
-    this.prevViewData = []; // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.prevViewData = [];
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
-
   SVGShapeElement.prototype.initSecondaryElement = function () {};
-
   SVGShapeElement.prototype.identityMatrix = new Matrix();
-
   SVGShapeElement.prototype.buildExpressionInterface = function () {};
-
   SVGShapeElement.prototype.createContent = function () {
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
   };
+
   /*
   This method searches for multiple shapes that affect a single element and one of them is animated
   */
-
-
   SVGShapeElement.prototype.filterUniqueShapes = function () {
     var i;
     var len = this.shapes.length;
@@ -10064,42 +8515,34 @@
     var style;
     var tempShapes = [];
     var areAnimated = false;
-
     for (j = 0; j < jLen; j += 1) {
       style = this.stylesList[j];
       areAnimated = false;
       tempShapes.length = 0;
-
       for (i = 0; i < len; i += 1) {
         shape = this.shapes[i];
-
         if (shape.styles.indexOf(style) !== -1) {
           tempShapes.push(shape);
           areAnimated = shape._isAnimated || areAnimated;
         }
       }
-
       if (tempShapes.length > 1 && areAnimated) {
         this.setShapesAsAnimated(tempShapes);
       }
     }
   };
-
   SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
     var i;
     var len = shapes.length;
-
     for (i = 0; i < len; i += 1) {
       shapes[i].setAsAnimated();
     }
   };
-
   SVGShapeElement.prototype.createStyleElement = function (data, level) {
     // TODO: prevent drawing of hidden styles
     var elementData;
     var styleOb = new SVGStyleData(data, level);
     var pathElement = styleOb.pElem;
-
     if (data.ty === 'st') {
       elementData = new SVGStrokeStyleData(this, data, styleOb);
     } else if (data.ty === 'fl') {
@@ -10108,7 +8551,6 @@
       var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
       elementData = new GradientConstructor(this, data, styleOb);
       this.globalData.defs.appendChild(elementData.gf);
-
       if (elementData.maskId) {
         this.globalData.defs.appendChild(elementData.ms);
         this.globalData.defs.appendChild(elementData.of);
@@ -10117,66 +8559,51 @@
     } else if (data.ty === 'no') {
       elementData = new SVGNoStyleData(this, data, styleOb);
     }
-
     if (data.ty === 'st' || data.ty === 'gs') {
       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);
       }
     }
-
     if (data.r === 2) {
       pathElement.setAttribute('fill-rule', 'evenodd');
     }
-
     if (data.ln) {
       pathElement.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       pathElement.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     this.stylesList.push(styleOb);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createGroupElement = function (data) {
     var elementData = new ShapeGroupData();
-
     if (data.ln) {
       elementData.gr.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       elementData.gr.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     return elementData;
   };
-
   SVGShapeElement.prototype.createTransformElement = function (data, container) {
     var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
     var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
     var ty = 4;
-
     if (data.ty === 'rc') {
       ty = 5;
     } else if (data.ty === 'el') {
@@ -10184,7 +8611,6 @@
     } else if (data.ty === 'sr') {
       ty = 7;
     }
-
     var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
     var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
     this.shapes.push(elementData);
@@ -10192,58 +8618,46 @@
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
     var i = 0;
     var len = this.animatedContents.length;
-
     while (i < len) {
       if (this.animatedContents[i].element === element) {
         return;
       }
-
       i += 1;
     }
-
     this.animatedContents.push({
       fn: SVGElementsRenderer.createRenderFunction(data),
       element: element,
       data: data
     });
   };
-
   SVGShapeElement.prototype.setElementStyles = function (elementData) {
     var arr = elementData.styles;
     var j;
     var jLen = this.stylesList.length;
-
     for (j = 0; j < jLen; j += 1) {
-      if (!this.stylesList[j].closed) {
+      if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
         arr.push(this.stylesList[j]);
       }
     }
   };
-
   SVGShapeElement.prototype.reloadShapes = function () {
     this._isFirstFrame = true;
     var i;
     var len = this.itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       this.prevViewData[i] = this.itemsData[i];
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
     len = this.dynamicProperties.length;
-
     for (i = 0; i < len; i += 1) {
       this.dynamicProperties[i].getValue();
     }
-
     this.renderModifiers();
   };
-
   SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
     var ownTransformers = [].concat(transformers);
     var i;
@@ -10255,43 +8669,35 @@
     var currentTransform;
     var modifier;
     var processedPos;
-
     for (i = len; i >= 0; i -= 1) {
       processedPos = this.searchProcessedElement(arr[i]);
-
       if (!processedPos) {
         arr[i]._render = render;
       } else {
         itemsData[i] = prevViewData[processedPos - 1];
       }
-
       if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
         if (!processedPos) {
           itemsData[i] = this.createStyleElement(arr[i], level);
         } else {
-          itemsData[i].style.closed = false;
+          itemsData[i].style.closed = arr[i].hd;
         }
-
         if (arr[i]._render) {
           if (itemsData[i].style.pElem.parentNode !== container) {
             container.appendChild(itemsData[i].style.pElem);
           }
         }
-
         ownStyles.push(itemsData[i].style);
       } else if (arr[i].ty === 'gr') {
         if (!processedPos) {
           itemsData[i] = this.createGroupElement(arr[i]);
         } else {
           jLen = itemsData[i].it.length;
-
           for (j = 0; j < jLen; j += 1) {
             itemsData[i].prevViewData[j] = itemsData[i].it[j];
           }
         }
-
         this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
-
         if (arr[i]._render) {
           if (itemsData[i].gr.parentNode !== container) {
             container.appendChild(itemsData[i].gr);
@@ -10301,14 +8707,12 @@
         if (!processedPos) {
           itemsData[i] = this.createTransformElement(arr[i], container);
         }
-
         currentTransform = itemsData[i].transform;
         ownTransformers.push(currentTransform);
       } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
         if (!processedPos) {
           itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
         }
-
         this.setElementStyles(itemsData[i]);
       } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
         if (!processedPos) {
@@ -10320,7 +8724,6 @@
           modifier = itemsData[i];
           modifier.closed = false;
         }
-
         ownModifiers.push(modifier);
       } else if (arr[i].ty === 'rp') {
         if (!processedPos) {
@@ -10333,64 +8736,49 @@
           modifier = itemsData[i];
           modifier.closed = true;
         }
-
         ownModifiers.push(modifier);
       }
-
       this.addProcessedElement(arr[i], i + 1);
     }
-
     len = ownStyles.length;
-
     for (i = 0; i < len; i += 1) {
       ownStyles[i].closed = true;
     }
-
     len = ownModifiers.length;
-
     for (i = 0; i < len; i += 1) {
       ownModifiers[i].closed = true;
     }
   };
-
   SVGShapeElement.prototype.renderInnerContent = function () {
     this.renderModifiers();
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       this.stylesList[i].reset();
     }
-
     this.renderShape();
-
     for (i = 0; i < len; i += 1) {
       if (this.stylesList[i]._mdf || this._isFirstFrame) {
         if (this.stylesList[i].msElem) {
-          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d); // Adding M0 0 fixes same mask bug on all browsers
-
+          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+          // Adding M0 0 fixes same mask bug on all browsers
           this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
         }
-
         this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
       }
     }
   };
-
   SVGShapeElement.prototype.renderShape = function () {
     var i;
     var len = this.animatedContents.length;
     var animatedContent;
-
     for (i = 0; i < len; i += 1) {
       animatedContent = this.animatedContents[i];
-
       if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
         animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
       }
     }
   };
-
   SVGShapeElement.prototype.destroy = function () {
     this.destroyBaseElement();
     this.shapesData = null;
@@ -10413,7 +8801,6 @@
       p: true
     };
   }
-
   LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
     this._mdf.o = false;
     this._mdf.sw = false;
@@ -10422,43 +8809,36 @@
     this._mdf.m = false;
     this._mdf.p = false;
     var updated = false;
-
     if (this.o !== o) {
       this.o = o;
       this._mdf.o = true;
       updated = true;
     }
-
     if (this.sw !== sw) {
       this.sw = sw;
       this._mdf.sw = true;
       updated = true;
     }
-
     if (this.sc !== sc) {
       this.sc = sc;
       this._mdf.sc = true;
       updated = true;
     }
-
     if (this.fc !== fc) {
       this.fc = fc;
       this._mdf.fc = true;
       updated = true;
     }
-
     if (this.m !== m) {
       this.m = m;
       this._mdf.m = true;
       updated = true;
     }
-
     if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
       this.p = p;
       this._mdf.p = true;
       updated = true;
     }
-
     return updated;
   };
 
@@ -10469,11 +8849,9 @@
     this.kf = false;
     this._isFirstFrame = true;
     this._mdf = false;
-
     if (data.d && data.d.sid) {
       data.d = elem.globalData.slotManager.getProp(data.d);
     }
-
     this.data = data;
     this.elem = elem;
     this.comp = this.elem.comp;
@@ -10512,73 +8890,57 @@
       __complete: false
     };
     this.copyData(this.currentData, this.data.d.k[0].s);
-
     if (!this.searchProperty()) {
       this.completeTextData(this.currentData);
     }
   }
-
   TextProperty.prototype.defaultBoxWidth = [0, 0];
-
   TextProperty.prototype.copyData = function (obj, data) {
     for (var s in data) {
       if (Object.prototype.hasOwnProperty.call(data, s)) {
         obj[s] = data[s];
       }
     }
-
     return obj;
   };
-
   TextProperty.prototype.setCurrentData = function (data) {
     if (!data.__complete) {
       this.completeTextData(data);
     }
-
     this.currentData = data;
     this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
     this._mdf = true;
   };
-
   TextProperty.prototype.searchProperty = function () {
     return this.searchKeyframes();
   };
-
   TextProperty.prototype.searchKeyframes = function () {
     this.kf = this.data.d.k.length > 1;
-
     if (this.kf) {
       this.addEffect(this.getKeyframeValue.bind(this));
     }
-
     return this.kf;
   };
-
   TextProperty.prototype.addEffect = function (effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.getValue = function (_finalValue) {
     if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
       return;
     }
-
     this.currentData.t = this.data.d.k[this.keysIndex].s.t;
     var currentValue = this.currentData;
     var currentIndex = this.keysIndex;
-
     if (this.lock) {
       this.setCurrentData(this.currentData);
       return;
     }
-
     this.lock = true;
     this._mdf = false;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
-
     for (i = 0; i < len; i += 1) {
       // Checking if index changed to prevent creating a new object every time the expression updates.
       if (currentIndex !== this.keysIndex) {
@@ -10587,38 +8949,30 @@
         finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
       }
     }
-
     if (currentValue !== finalValue) {
       this.setCurrentData(finalValue);
     }
-
     this.v = this.currentData;
     this.pv = this.v;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   };
-
   TextProperty.prototype.getKeyframeValue = function () {
     var textKeys = this.data.d.k;
     var frameNum = this.elem.comp.renderedFrame;
     var i = 0;
     var len = textKeys.length;
-
     while (i <= len - 1) {
       if (i === len - 1 || textKeys[i + 1].t > frameNum) {
         break;
       }
-
       i += 1;
     }
-
     if (this.keysIndex !== i) {
       this.keysIndex = i;
     }
-
     return this.data.d.k[this.keysIndex].s;
   };
-
   TextProperty.prototype.buildFinalText = function (text) {
     var charactersArray = [];
     var i = 0;
@@ -10628,21 +8982,20 @@
     var shouldCombine = false;
     var shouldCombineNext = false;
     var currentChars = '';
-
     while (i < len) {
       shouldCombine = shouldCombineNext;
       shouldCombineNext = false;
       charCode = text.charCodeAt(i);
       currentChars = text.charAt(i);
-
       if (FontManager.isCombinedCharacter(charCode)) {
-        shouldCombine = true; // It's a potential surrogate pair (this is the High surrogate)
+        shouldCombine = true;
+        // It's a potential surrogate pair (this is the High surrogate)
       } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
         if (FontManager.isRegionalFlag(text, i)) {
           currentChars = text.substr(i, 14);
         } else {
-          secondCharCode = text.charCodeAt(i + 1); // It's a surrogate pair (this is the Low surrogate)
-
+          secondCharCode = text.charCodeAt(i + 1);
+          // It's a surrogate pair (this is the Low surrogate)
           if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
             if (FontManager.isModifier(charCode, secondCharCode)) {
               currentChars = text.substr(i, 2);
@@ -10656,7 +9009,6 @@
         }
       } else if (charCode > 0xDBFF) {
         secondCharCode = text.charCodeAt(i + 1);
-
         if (FontManager.isVariationSelector(charCode)) {
           shouldCombine = true;
         }
@@ -10664,20 +9016,16 @@
         shouldCombine = true;
         shouldCombineNext = true;
       }
-
       if (shouldCombine) {
         charactersArray[charactersArray.length - 1] += currentChars;
         shouldCombine = false;
       } else {
         charactersArray.push(currentChars);
       }
-
       i += currentChars.length;
     }
-
     return charactersArray;
   };
-
   TextProperty.prototype.completeTextData = function (documentData) {
     documentData.__complete = true;
     var fontManager = this.elem.globalData.fontManager;
@@ -10709,14 +9057,12 @@
     documentData.finalLineHeight = documentData.lh;
     var trackingOffset = documentData.tr / 1000 * documentData.finalSize;
     var charCode;
-
     if (documentData.sz) {
       var flag = true;
       var boxWidth = documentData.sz[0];
       var boxHeight = documentData.sz[1];
       var currentHeight;
       var finalText;
-
       while (flag) {
         finalText = this.buildFinalText(documentData.t);
         currentHeight = 0;
@@ -10724,11 +9070,9 @@
         len = finalText.length;
         trackingOffset = documentData.tr / 1000 * documentData.finalSize;
         var lastSpaceIndex = -1;
-
         for (i = 0; i < len; i += 1) {
           charCode = finalText[i].charCodeAt(0);
           newLineFlag = false;
-
           if (finalText[i] === ' ') {
             lastSpaceIndex = i;
           } else if (charCode === 13 || charCode === 3) {
@@ -10736,7 +9080,6 @@
             newLineFlag = true;
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
           }
-
           if (fontManager.chars) {
             charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
             cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -10744,17 +9087,15 @@
             // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
             cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
           }
-
           if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
             if (lastSpaceIndex === -1) {
               len += 1;
             } else {
               i = lastSpaceIndex;
             }
-
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
-            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r'); // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
-
+            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+            // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
             lastSpaceIndex = -1;
             lineWidth = 0;
           } else {
@@ -10762,9 +9103,7 @@
             lineWidth += trackingOffset;
           }
         }
-
         currentHeight += fontData.ascent * documentData.finalSize / 100;
-
         if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
           documentData.finalSize -= 1;
           documentData.finalLineHeight = documentData.finalSize * documentData.lh / documentData.s;
@@ -10775,17 +9114,14 @@
         }
       }
     }
-
     lineWidth = -trackingOffset;
     cLength = 0;
     var uncollapsedSpaces = 0;
     var currentChar;
-
     for (i = 0; i < len; i += 1) {
       newLineFlag = false;
       currentChar = documentData.finalText[i];
       charCode = currentChar.charCodeAt(0);
-
       if (charCode === 13 || charCode === 3) {
         uncollapsedSpaces = 0;
         lineWidths.push(lineWidth);
@@ -10797,7 +9133,6 @@
       } else {
         val = currentChar;
       }
-
       if (fontManager.chars) {
         charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
         cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -10805,16 +9140,15 @@
         // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
         // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
         cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
-      } //
+      }
 
-
+      //
       if (currentChar === ' ') {
         uncollapsedSpaces += cLength + trackingOffset;
       } else {
         lineWidth += cLength + trackingOffset + uncollapsedSpaces;
         uncollapsedSpaces = 0;
       }
-
       letters.push({
         l: cLength,
         an: cLength,
@@ -10825,42 +9159,35 @@
         line: currentLine,
         animatorJustifyOffset: 0
       });
-
       if (anchorGrouping == 2) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || val === ' ' || i === len - 1) {
           if (val === '' || val === ' ') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           index += 1;
           currentSize = 0;
         }
       } else if (anchorGrouping == 3) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || i === len - 1) {
           if (val === '') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           currentSize = 0;
           index += 1;
         }
@@ -10870,31 +9197,25 @@
         index += 1;
       }
     }
-
     documentData.l = letters;
     maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
     lineWidths.push(lineWidth);
-
     if (documentData.sz) {
       documentData.boxWidth = documentData.sz[0];
       documentData.justifyOffset = 0;
     } else {
       documentData.boxWidth = maxLineWidth;
-
       switch (documentData.j) {
         case 1:
           documentData.justifyOffset = -documentData.boxWidth;
           break;
-
         case 2:
           documentData.justifyOffset = -documentData.boxWidth / 2;
           break;
-
         default:
           documentData.justifyOffset = 0;
       }
     }
-
     documentData.lineWidths = lineWidths;
     var animators = data.a;
     var animatorData;
@@ -10903,63 +9224,49 @@
     var based;
     var ind;
     var indexes = [];
-
     for (j = 0; j < jLen; j += 1) {
       animatorData = animators[j];
-
       if (animatorData.a.sc) {
         documentData.strokeColorAnim = true;
       }
-
       if (animatorData.a.sw) {
         documentData.strokeWidthAnim = true;
       }
-
       if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
         documentData.fillColorAnim = true;
       }
-
       ind = 0;
       based = animatorData.s.b;
-
       for (i = 0; i < len; i += 1) {
         letterData = letters[i];
         letterData.anIndexes[j] = ind;
-
         if (based == 1 && letterData.val !== '' || based == 2 && letterData.val !== '' && letterData.val !== ' ' || based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1) || based == 4 && (letterData.n || i == len - 1)) {
           // eslint-disable-line eqeqeq
           if (animatorData.s.rn === 1) {
             indexes.push(ind);
           }
-
           ind += 1;
         }
       }
-
       data.a[j].s.totalChars = ind;
       var currentInd = -1;
       var newInd;
-
       if (animatorData.s.rn === 1) {
         for (i = 0; i < len; i += 1) {
           letterData = letters[i];
-
           if (currentInd != letterData.anIndexes[j]) {
             // eslint-disable-line eqeqeq
             currentInd = letterData.anIndexes[j];
             newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
           }
-
           letterData.anIndexes[j] = newInd;
         }
       }
     }
-
     documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
     documentData.ls = documentData.ls || 0;
     documentData.ascent = fontData.ascent * documentData.finalSize / 100;
   };
-
   TextProperty.prototype.updateDocumentData = function (newData, index) {
     index = index === undefined ? this.keysIndex : index;
     var dData = this.copyData({}, this.data.d.k[index].s);
@@ -10969,7 +9276,6 @@
     this.setCurrentData(dData);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.recalculate = function (index) {
     var dData = this.data.d.k[index].s;
     dData.__complete = false;
@@ -10977,13 +9283,11 @@
     this._isFirstFrame = true;
     this.getValue(dData);
   };
-
   TextProperty.prototype.canResizeFont = function (_canResize) {
     this.canResize = _canResize;
     this.recalculate(this.keysIndex);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
     this.minimumFontSize = Math.floor(_fontValue) || 1;
     this.recalculate(this.keysIndex);
@@ -10994,7 +9298,6 @@
     var max = Math.max;
     var min = Math.min;
     var floor = Math.floor;
-
     function TextSelectorPropFactory(elem, data) {
       this._currentTextLength = -1;
       this.k = false;
@@ -11007,7 +9310,6 @@
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: 0
       }, 0, 0, this);
-
       if ('e' in data) {
         this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
       } else {
@@ -11015,7 +9317,6 @@
           v: 100
         };
       }
-
       this.o = PropertyFactory.getProp(elem, data.o || {
         k: 0
       }, 0, 0, this);
@@ -11029,48 +9330,40 @@
         k: 100
       }, 0, 0, this);
       this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
-
       if (!this.dynamicProperties.length) {
         this.getValue();
       }
     }
-
     TextSelectorPropFactory.prototype = {
       getMult: function getMult(ind) {
         if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
           this.getValue();
         }
-
         var x1 = 0;
         var y1 = 0;
         var x2 = 1;
         var y2 = 1;
-
         if (this.ne.v > 0) {
           x1 = this.ne.v / 100.0;
         } else {
           y1 = -this.ne.v / 100.0;
         }
-
         if (this.xe.v > 0) {
           x2 = 1.0 - this.xe.v / 100.0;
         } else {
           y2 = 1.0 + this.xe.v / 100.0;
         }
-
         var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
         var mult = 0;
         var s = this.finalS;
         var e = this.finalE;
         var type = this.data.sh;
-
         if (type === 2) {
           if (e === s) {
             mult = ind >= e ? 1 : 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 3) {
           if (e === s) {
@@ -11078,21 +9371,18 @@
           } else {
             mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 4) {
           if (e === s) {
             mult = 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
-
             if (mult < 0.5) {
               mult *= 2;
             } else {
               mult = 1 - 2 * (mult - 0.5);
             }
           }
-
           mult = easer(mult);
         } else if (type === 5) {
           if (e === s) {
@@ -11101,13 +9391,11 @@
             var tot = e - s;
             /* ind += 0.5;
                       mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
-
             ind = min(max(0, ind + 0.5 - s), e - s);
             var x = -tot / 2 + ind;
             var a = tot / 2;
             mult = Math.sqrt(1 - x * x / (a * a));
           }
-
           mult = easer(mult);
         } else if (type === 6) {
           if (e === s) {
@@ -11116,7 +9404,6 @@
             ind = min(max(0, ind + 0.5 - s), e - s);
             mult = (1 + Math.cos(Math.PI + Math.PI * 2 * ind / (e - s))) / 2; // eslint-disable-line
           }
-
           mult = easer(mult);
         } else {
           if (ind >= floor(s)) {
@@ -11126,9 +9413,9 @@
               mult = max(0, min(e - ind, 1));
             }
           }
-
           mult = easer(mult);
-        } // Smoothness implementation.
+        }
+        // Smoothness implementation.
         // The smoothness represents a reduced range of the original [0; 1] range.
         // if smoothness is 25%, the new range will be [0.375; 0.625]
         // Steps are:
@@ -11138,60 +9425,47 @@
         //     - subtract the threshold
         //     - divide it by the smoothness (this will return the range to [0; 1])
         // Note: If it doesn't work on some scenarios, consider applying it before the easer.
-
-
         if (this.sm.v !== 100) {
           var smoothness = this.sm.v * 0.01;
-
           if (smoothness === 0) {
             smoothness = 0.00000001;
           }
-
           var threshold = 0.5 - smoothness * 0.5;
-
           if (mult < threshold) {
             mult = 0;
           } else {
             mult = (mult - threshold) / smoothness;
-
             if (mult > 1) {
               mult = 1;
             }
           }
         }
-
         return mult * this.a.v;
       },
       getValue: function getValue(newCharsFlag) {
         this.iterateDynamicProperties();
         this._mdf = newCharsFlag || this._mdf;
         this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
-
         if (newCharsFlag && this.data.r === 2) {
           this.e.v = this._currentTextLength;
         }
-
         var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
         var o = this.o.v / divisor;
         var s = this.s.v / divisor + o;
         var e = this.e.v / divisor + o;
-
         if (s > e) {
           var _s = s;
           s = e;
           e = _s;
         }
-
         this.finalS = s;
         this.finalE = e;
       }
     };
     extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
-
     function getTextSelectorProp(elem, data, arr) {
       return new TextSelectorPropFactory(elem, data, arr);
     }
-
     return {
       getTextSelectorProp: getTextSelectorProp
     };
@@ -11241,18 +9515,15 @@
     this.lettersChangedFlag = false;
     this.initDynamicPropertyContainer(elem);
   }
-
   TextAnimatorProperty.prototype.searchProperties = function () {
     var i;
     var len = this._textData.a.length;
     var animatorProps;
     var getProp = PropertyFactory.getProp;
-
     for (i = 0; i < len; i += 1) {
       animatorProps = this._textData.a[i];
       this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
     }
-
     if (this._textData.p && 'm' in this._textData.p) {
       this._pathData = {
         a: getProp(this._elem, this._textData.p.a, 0, 0, this),
@@ -11266,17 +9537,13 @@
     } else {
       this._hasMaskedPath = false;
     }
-
     this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
   };
-
   TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
     this.lettersChangedFlag = lettersChangedFlag;
-
     if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
       return;
     }
-
     this._isFirstFrame = false;
     var alignment = this._moreOptions.alignment.v;
     var animators = this._animatorsData;
@@ -11304,18 +9571,14 @@
     var perc;
     var tanAngle;
     var mask;
-
     if (this._hasMaskedPath) {
       mask = this._pathData.m;
-
       if (!this._pathData.n || this._pathData._mdf) {
         var paths = mask.v;
-
         if (this._pathData.r.v) {
           paths = paths.reverse();
-        } // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
-
-
+        }
+        // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
         pathInfo = {
           tLength: 0,
           segments: []
@@ -11323,26 +9586,21 @@
         len = paths._length - 1;
         var bezierData;
         totalLength = 0;
-
         for (i = 0; i < len; i += 1) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[i + 1], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         i = len;
-
         if (mask.v.c) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[0], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         this._pathData.pi = pathInfo;
       }
-
       pathInfo = this._pathData.pi;
       currentLength = this._pathData.f.v;
       segmentInd = 0;
@@ -11350,20 +9608,16 @@
       segmentLength = 0;
       flag = true;
       segments = pathInfo.segments;
-
       if (currentLength < 0 && mask.v.c) {
         if (pathInfo.tLength < Math.abs(currentLength)) {
           currentLength = -Math.abs(currentLength) % pathInfo.tLength;
         }
-
         segmentInd = segments.length - 1;
         points = segments[segmentInd].points;
         pointInd = points.length - 1;
-
         while (currentLength < 0) {
           currentLength += points[pointInd].partialLength;
           pointInd -= 1;
-
           if (pointInd < 0) {
             segmentInd -= 1;
             points = segments[segmentInd].points;
@@ -11371,13 +9625,11 @@
           }
         }
       }
-
       points = segments[segmentInd].points;
       prevPoint = points[pointInd - 1];
       currentPoint = points[pointInd];
       partialLength = currentPoint.partialLength;
     }
-
     len = letters.length;
     xPos = 0;
     yPos = 0;
@@ -11408,40 +9660,35 @@
     var letterFc;
     var letterM = '';
     var letterP = this.defaultPropsArray;
-    var letterO; //
+    var letterO;
 
+    //
     if (documentData.j === 2 || documentData.j === 1) {
       var animatorJustifyOffset = 0;
       var animatorFirstCharOffset = 0;
       var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
       var lastIndex = 0;
       var isNewLine = true;
-
       for (i = 0; i < len; i += 1) {
         if (letters[i].n) {
           if (animatorJustifyOffset) {
             animatorJustifyOffset += animatorFirstCharOffset;
           }
-
           while (lastIndex < i) {
             letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
             lastIndex += 1;
           }
-
           animatorJustifyOffset = 0;
           isNewLine = true;
         } else {
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.t.propType) {
               if (isNewLine && documentData.j === 2) {
                 animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
               }
-
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
               } else {
@@ -11449,33 +9696,28 @@
               }
             }
           }
-
           isNewLine = false;
         }
       }
-
       if (animatorJustifyOffset) {
         animatorJustifyOffset += animatorFirstCharOffset;
       }
-
       while (lastIndex < i) {
         letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
         lastIndex += 1;
       }
-    } //
-
+    }
+    //
 
     for (i = 0; i < len; i += 1) {
       matrixHelper.reset();
       elemOpacity = 1;
-
       if (letters[i].n) {
         xPos = 0;
         yPos += documentData.yOffset;
         yPos += firstLine ? 1 : 0;
         currentLength = initPathPos;
         firstLine = false;
-
         if (this._hasMaskedPath) {
           segmentInd = initSegmentInd;
           pointInd = initPointInd;
@@ -11485,7 +9727,6 @@
           partialLength = currentPoint.partialLength;
           segmentLength = 0;
         }
-
         letterM = '';
         letterFc = '';
         letterSw = '';
@@ -11498,48 +9739,37 @@
               case 1:
                 currentLength += totalLength - documentData.lineWidths[letters[i].line];
                 break;
-
               case 2:
                 currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
                 break;
-
               default:
                 break;
             }
-
             currentLine = letters[i].line;
           }
-
           if (ind !== letters[i].ind) {
             if (letters[ind]) {
               currentLength += letters[ind].extra;
             }
-
             currentLength += letters[i].an / 2;
             ind = letters[i].ind;
           }
-
           currentLength += alignment[0] * letters[i].an * 0.005;
           var animatorOffset = 0;
-
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.p.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.p.v[0] * mult[0];
               } else {
                 animatorOffset += animatorProps.p.v[0] * mult;
               }
             }
-
             if (animatorProps.a.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.a.v[0] * mult[0];
               } else {
@@ -11547,14 +9777,12 @@
               }
             }
           }
-
-          flag = true; // Force alignment only works with a single line for now
-
+          flag = true;
+          // Force alignment only works with a single line for now
           if (this._pathData.a.v) {
             currentLength = letters[0].an * 0.5 + (totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind / (len - 1);
             currentLength += this._pathData.f.v;
           }
-
           while (flag) {
             if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
               perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
@@ -11565,11 +9793,9 @@
             } else if (points) {
               segmentLength += currentPoint.partialLength;
               pointInd += 1;
-
               if (pointInd >= points.length) {
                 pointInd = 0;
                 segmentInd += 1;
-
                 if (!segments[segmentInd]) {
                   if (mask.v.c) {
                     pointInd = 0;
@@ -11583,7 +9809,6 @@
                   points = segments[segmentInd].points;
                 }
               }
-
               if (points) {
                 prevPoint = currentPoint;
                 currentPoint = points[pointInd];
@@ -11591,23 +9816,21 @@
               }
             }
           }
-
           offf = letters[i].an / 2 - letters[i].add;
           matrixHelper.translate(-offf, 0, 0);
         } else {
           offf = letters[i].an / 2 - letters[i].add;
-          matrixHelper.translate(-offf, 0, 0); // Grouping alignment
+          matrixHelper.translate(-offf, 0, 0);
 
+          // Grouping alignment
           matrixHelper.translate(-alignment[0] * letters[i].an * 0.005, -alignment[1] * yOff * 0.01, 0);
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.t.propType) {
             animatorSelector = animators[j].s;
-            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars); // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
-
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
             if (xPos !== 0 || documentData.j !== 0) {
               if (this._hasMaskedPath) {
                 if (mult.length) {
@@ -11623,11 +9846,9 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           sw = documentData.sw || 0;
         }
-
         if (documentData.strokeColorAnim) {
           if (documentData.sc) {
             sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
@@ -11635,18 +9856,14 @@
             sc = [0, 0, 0];
           }
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.a.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
             } else {
@@ -11654,14 +9871,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.s.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.scale(1 + (animatorProps.s.v[0] - 1) * mult[0], 1 + (animatorProps.s.v[1] - 1) * mult[1], 1);
             } else {
@@ -11669,12 +9883,10 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
           animatorSelector = animators[j].s;
           mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
           if (animatorProps.sk.propType) {
             if (mult.length) {
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
@@ -11682,7 +9894,6 @@
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
             }
           }
-
           if (animatorProps.r.propType) {
             if (mult.length) {
               matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
@@ -11690,7 +9901,6 @@
               matrixHelper.rotateZ(-animatorProps.r.v * mult);
             }
           }
-
           if (animatorProps.ry.propType) {
             if (mult.length) {
               matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
@@ -11698,7 +9908,6 @@
               matrixHelper.rotateY(animatorProps.ry.v * mult);
             }
           }
-
           if (animatorProps.rx.propType) {
             if (mult.length) {
               matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
@@ -11706,7 +9915,6 @@
               matrixHelper.rotateX(animatorProps.rx.v * mult);
             }
           }
-
           if (animatorProps.o.propType) {
             if (mult.length) {
               elemOpacity += (animatorProps.o.v * mult[0] - elemOpacity) * mult[0];
@@ -11714,7 +9922,6 @@
               elemOpacity += (animatorProps.o.v * mult - elemOpacity) * mult;
             }
           }
-
           if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
             if (mult.length) {
               sw += animatorProps.sw.v * mult[0];
@@ -11722,7 +9929,6 @@
               sw += animatorProps.sw.v * mult;
             }
           }
-
           if (documentData.strokeColorAnim && animatorProps.sc.propType) {
             for (k = 0; k < 3; k += 1) {
               if (mult.length) {
@@ -11732,7 +9938,6 @@
               }
             }
           }
-
           if (documentData.fillColorAnim && documentData.fc) {
             if (animatorProps.fc.propType) {
               for (k = 0; k < 3; k += 1) {
@@ -11743,7 +9948,6 @@
                 }
               }
             }
-
             if (animatorProps.fh.propType) {
               if (mult.length) {
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
@@ -11751,7 +9955,6 @@
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult);
               }
             }
-
             if (animatorProps.fs.propType) {
               if (mult.length) {
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
@@ -11759,7 +9962,6 @@
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
               }
             }
-
             if (animatorProps.fb.propType) {
               if (mult.length) {
                 fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
@@ -11769,14 +9971,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.p.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (this._hasMaskedPath) {
               if (mult.length) {
                 matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
@@ -11790,68 +9989,53 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           letterSw = sw < 0 ? 0 : sw;
         }
-
         if (documentData.strokeColorAnim) {
           letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
         }
-
         if (this._hasMaskedPath) {
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(0, alignment[1] * yOff * 0.01 + yPos, 0);
-
           if (this._pathData.p.v) {
             tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
             var rot = Math.atan(tanAngle) * 180 / Math.PI;
-
             if (currentPoint.point[0] < prevPoint.point[0]) {
               rot += 180;
             }
-
             matrixHelper.rotate(-rot * Math.PI / 180);
           }
-
           matrixHelper.translate(xPathPos, yPathPos, 0);
           currentLength -= alignment[0] * letters[i].an * 0.005;
-
           if (letters[i + 1] && ind !== letters[i + 1].ind) {
             currentLength += letters[i].an / 2;
             currentLength += documentData.tr * 0.001 * documentData.finalSize;
           }
         } else {
           matrixHelper.translate(xPos, yPos, 0);
-
           if (documentData.ps) {
             // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
             matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
           }
-
           switch (documentData.j) {
             case 1:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
               break;
-
             case 2:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
               break;
-
             default:
               break;
           }
-
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(offf, 0, 0);
           matrixHelper.translate(alignment[0] * letters[i].an * 0.005, alignment[1] * yOff * 0.01, 0);
           xPos += letters[i].l + documentData.tr * 0.001 * documentData.finalSize;
         }
-
         if (renderType === 'html') {
           letterM = matrixHelper.toCSS();
         } else if (renderType === 'svg') {
@@ -11859,10 +10043,8 @@
         } else {
           letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
         }
-
         letterO = elemOpacity;
       }
-
       if (renderedLettersCount <= i) {
         letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
         this.renderedLetters.push(letterValue);
@@ -11874,22 +10056,18 @@
       }
     }
   };
-
   TextAnimatorProperty.prototype.getValue = function () {
     if (this._elem.globalData.frameId === this._frameId) {
       return;
     }
-
     this._frameId = this._elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   TextAnimatorProperty.prototype.mHelper = new Matrix();
   TextAnimatorProperty.prototype.defaultPropsArray = [];
   extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
 
   function ITextElement() {}
-
   ITextElement.prototype.initElement = function (data, globalData, comp) {
     this.lettersChangedFlag = true;
     this.initFrame();
@@ -11906,72 +10084,55 @@
     this.hide();
     this.textAnimator.searchProperties(this.dynamicProperties);
   };
-
   ITextElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
   };
-
   ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
     var j;
     var jLen = shapes.length;
     var pathNodes;
     var shapeStr = '';
-
     for (j = 0; j < jLen; j += 1) {
       if (shapes[j].ty === 'sh') {
         pathNodes = shapes[j].ks.k;
         shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
       }
     }
-
     return shapeStr;
   };
-
   ITextElement.prototype.updateDocumentData = function (newData, index) {
     this.textProperty.updateDocumentData(newData, index);
   };
-
   ITextElement.prototype.canResizeFont = function (_canResize) {
     this.textProperty.canResizeFont(_canResize);
   };
-
   ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
     this.textProperty.setMinimumFontSize(_fontSize);
   };
-
   ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
     if (documentData.ps) {
       matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
     }
-
     matrixHelper.translate(0, -documentData.ls, 0);
-
     switch (documentData.j) {
       case 1:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
         break;
-
       case 2:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
         break;
-
       default:
         break;
     }
-
     matrixHelper.translate(xPos, yPos, 0);
   };
-
   ITextElement.prototype.buildColor = function (colorData) {
     return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
   };
-
   ITextElement.prototype.emptyProp = new LetterProps();
-
   ITextElement.prototype.destroy = function () {};
-
   ITextElement.prototype.validateText = function () {
     if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
       this.buildNewText();
@@ -11983,27 +10144,22 @@
   var emptyShapeData = {
     shapes: []
   };
-
   function SVGTextLottieElement(data, globalData, comp) {
     this.textSpans = [];
     this.renderType = 'svg';
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
-
   SVGTextLottieElement.prototype.createContent = function () {
     if (this.data.singleShape && !this.globalData.fontManager.chars) {
       this.textContainer = createNS('text');
     }
   };
-
   SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
     var i = 0;
     var len = textArray.length;
     var textContents = [];
     var currentTextContent = '';
-
     while (i < len) {
       if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
         textContents.push(currentTextContent);
@@ -12011,14 +10167,11 @@
       } else {
         currentTextContent += textArray[i];
       }
-
       i += 1;
     }
-
     textContents.push(currentTextContent);
     return textContents;
   };
-
   SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
     // data should probably be cloned to apply scale separately to each instance of a text on different layers
     // but since text internal content gets only rendered once and then it's never rerendered,
@@ -12026,41 +10179,33 @@
     // Avoiding cloning is preferred since cloning each character shape data is expensive
     if (data.shapes && data.shapes.length) {
       var shape = data.shapes[0];
-
       if (shape.it) {
         var shapeItem = shape.it[shape.it.length - 1];
-
         if (shapeItem.s) {
           shapeItem.s.k[0] = scale;
           shapeItem.s.k[1] = scale;
         }
       }
     }
-
     return data;
   };
-
   SVGTextLottieElement.prototype.buildNewText = function () {
     this.addDynamicProperty(this);
     var i;
     var len;
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
-
     if (documentData.fc) {
       this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
     } else {
       this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
     }
-
     if (documentData.sc) {
       this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
       this.layerElement.setAttribute('stroke-width', documentData.sw);
     }
-
     this.layerElement.setAttribute('font-size', documentData.finalSize);
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
-
     if (fontData.fClass) {
       this.layerElement.setAttribute('class', fontData.fClass);
     } else {
@@ -12070,7 +10215,6 @@
       this.layerElement.setAttribute('font-style', fStyle);
       this.layerElement.setAttribute('font-weight', fWeight);
     }
-
     this.layerElement.setAttribute('aria-label', documentData.t);
     var letters = documentData.l || [];
     var usesGlyphs = !!this.globalData.fontManager.chars;
@@ -12083,31 +10227,25 @@
     var yPos = 0;
     var firstLine = true;
     var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
-
     if (singleShape && !usesGlyphs && !documentData.sz) {
       var tElement = this.textContainer;
       var justify = 'start';
-
       switch (documentData.j) {
         case 1:
           justify = 'end';
           break;
-
         case 2:
           justify = 'middle';
           break;
-
         default:
           justify = 'start';
           break;
       }
-
       tElement.setAttribute('text-anchor', justify);
       tElement.setAttribute('letter-spacing', trackingOffset);
       var textContent = this.buildTextContents(documentData.finalText);
       len = textContent.length;
       yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
-
       for (i = 0; i < len; i += 1) {
         tSpan = this.textSpans[i].span || createNS('tspan');
         tSpan.textContent = textContent[i];
@@ -12115,23 +10253,19 @@
         tSpan.setAttribute('y', yPos);
         tSpan.style.display = 'inherit';
         tElement.appendChild(tSpan);
-
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
             span: null,
             glyph: null
           };
         }
-
         this.textSpans[i].span = tSpan;
         yPos += documentData.finalLineHeight;
       }
-
       this.layerElement.appendChild(tElement);
     } else {
       var cachedSpansLength = this.textSpans.length;
       var charData;
-
       for (i = 0; i < len; i += 1) {
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
@@ -12140,31 +10274,24 @@
             glyph: null
           };
         }
-
         if (!usesGlyphs || !singleShape || i === 0) {
           tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
-
           if (cachedSpansLength <= i) {
             tSpan.setAttribute('stroke-linecap', 'butt');
             tSpan.setAttribute('stroke-linejoin', 'round');
             tSpan.setAttribute('stroke-miterlimit', '4');
             this.textSpans[i].span = tSpan;
-
             if (usesGlyphs) {
               var childSpan = createNS('g');
               tSpan.appendChild(childSpan);
               this.textSpans[i].childSpan = childSpan;
             }
-
             this.textSpans[i].span = tSpan;
             this.layerElement.appendChild(tSpan);
           }
-
           tSpan.style.display = 'inherit';
         }
-
         matrixHelper.reset();
-
         if (singleShape) {
           if (letters[i].n) {
             xPos = -trackingOffset;
@@ -12172,42 +10299,36 @@
             yPos += firstLine ? 1 : 0;
             firstLine = false;
           }
-
           this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
-          xPos += letters[i].l || 0; // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
-
+          xPos += letters[i].l || 0;
+          // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
           xPos += trackingOffset;
         }
-
         if (usesGlyphs) {
           charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
-          var glyphElement; // t === 1 means the character has been replaced with an animated shaped
-
+          var glyphElement;
+          // t === 1 means the character has been replaced with an animated shaped
           if (charData.t === 1) {
             glyphElement = new SVGCompElement(charData.data, this.globalData, this);
           } else {
             var data = emptyShapeData;
-
             if (charData.data && charData.data.shapes) {
               data = this.buildShapeData(charData.data, documentData.finalSize);
             }
-
             glyphElement = new SVGShapeElement(data, this.globalData, this);
           }
-
           if (this.textSpans[i].glyph) {
             var glyph = this.textSpans[i].glyph;
             this.textSpans[i].childSpan.removeChild(glyph.layerElement);
             glyph.destroy();
           }
-
           this.textSpans[i].glyph = glyphElement;
           glyphElement._debug = true;
           glyphElement.prepareFrame(0);
           glyphElement.renderFrame();
-          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement); // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+          // when using animated shapes, the layer will be scaled instead of replacing the internal scale
           // this might have issues with strokes and might need a different solution
-
           if (charData.t === 1) {
             this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
           }
@@ -12215,30 +10336,24 @@
           if (singleShape) {
             tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
           }
-
           tSpan.textContent = letters[i].val;
           tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
-        } //
-
+        }
+        //
       }
-
       if (singleShape && tSpan) {
         tSpan.setAttribute('d', shapeStr);
       }
     }
-
     while (i < this.textSpans.length) {
       this.textSpans[i].span.style.display = 'none';
       i += 1;
     }
-
     this._sizeChanged = true;
   };
-
   SVGTextLottieElement.prototype.sourceRectAtTime = function () {
     this.prepareFrame(this.comp.renderedFrame - this.data.st);
     this.renderInnerContent();
-
     if (this._sizeChanged) {
       this._sizeChanged = false;
       var textBox = this.layerElement.getBBox();
@@ -12249,35 +10364,27 @@
         height: textBox.height
       };
     }
-
     return this.bbox;
   };
-
   SVGTextLottieElement.prototype.getValue = function () {
     var i;
     var len = this.textSpans.length;
     var glyphElement;
     this.renderedFrame = this.comp.renderedFrame;
-
     for (i = 0; i < len; i += 1) {
       glyphElement = this.textSpans[i].glyph;
-
       if (glyphElement) {
         glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
-
         if (glyphElement._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   SVGTextLottieElement.prototype.renderInnerContent = function () {
     this.validateText();
-
     if (!this.data.singleShape || this._mdf) {
       this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
-
       if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
         this._sizeChanged = true;
         var i;
@@ -12288,33 +10395,26 @@
         var renderedLetter;
         var textSpan;
         var glyphElement;
-
         for (i = 0; i < len; i += 1) {
           if (!letters[i].n) {
             renderedLetter = renderedLetters[i];
             textSpan = this.textSpans[i].span;
             glyphElement = this.textSpans[i].glyph;
-
             if (glyphElement) {
               glyphElement.renderFrame();
             }
-
             if (renderedLetter._mdf.m) {
               textSpan.setAttribute('transform', renderedLetter.m);
             }
-
             if (renderedLetter._mdf.o) {
               textSpan.setAttribute('opacity', renderedLetter.o);
             }
-
             if (renderedLetter._mdf.sw) {
               textSpan.setAttribute('stroke-width', renderedLetter.sw);
             }
-
             if (renderedLetter._mdf.sc) {
               textSpan.setAttribute('stroke', renderedLetter.sc);
             }
-
             if (renderedLetter._mdf.fc) {
               textSpan.setAttribute('fill', renderedLetter.fc);
             }
@@ -12327,14 +10427,12 @@
   function ISolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([IImageElement], ISolidElement);
-
   ISolidElement.prototype.createContent = function () {
-    var rect = createNS('rect'); /// /rect.style.width = this.data.sw;
+    var rect = createNS('rect');
+    /// /rect.style.width = this.data.sw;
     /// /rect.style.height = this.data.sh;
     /// /rect.style.fill = this.data.sc;
-
     rect.setAttribute('width', this.data.sw);
     rect.setAttribute('height', this.data.sh);
     rect.setAttribute('fill', this.data.sc);
@@ -12348,59 +10446,43 @@
     this.initTransform(data, globalData, comp);
     this.initHierarchy();
   }
-
   NullElement.prototype.prepareFrame = function (num) {
     this.prepareProperties(num, true);
   };
-
   NullElement.prototype.renderFrame = function () {};
-
   NullElement.prototype.getBaseElement = function () {
     return null;
   };
-
   NullElement.prototype.destroy = function () {};
-
   NullElement.prototype.sourceRectAtTime = function () {};
-
   NullElement.prototype.hide = function () {};
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
 
   function SVGRendererBase() {}
-
   extendPrototype([BaseRenderer], SVGRendererBase);
-
   SVGRendererBase.prototype.createNull = function (data) {
     return new NullElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createShape = function (data) {
     return new SVGShapeElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createText = function (data) {
     return new SVGTextLottieElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createImage = function (data) {
     return new IImageElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createSolid = function (data) {
     return new ISolidElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.configAnimation = function (animData) {
     this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
     this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
-
     if (this.renderConfig.viewBoxSize) {
       this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
     } else {
       this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
     }
-
     if (!this.renderConfig.viewBoxOnly) {
       this.svgElement.setAttribute('width', animData.w);
       this.svgElement.setAttribute('height', animData.h);
@@ -12409,32 +10491,26 @@
       this.svgElement.style.transform = 'translate3d(0,0,0)';
       this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
     }
-
     if (this.renderConfig.width) {
       this.svgElement.setAttribute('width', this.renderConfig.width);
     }
-
     if (this.renderConfig.height) {
       this.svgElement.setAttribute('height', this.renderConfig.height);
     }
-
     if (this.renderConfig.className) {
       this.svgElement.setAttribute('class', this.renderConfig.className);
     }
-
     if (this.renderConfig.id) {
       this.svgElement.setAttribute('id', this.renderConfig.id);
     }
-
     if (this.renderConfig.focusable !== undefined) {
       this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
     }
-
-    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio); // this.layerElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+    // this.layerElement.style.transform = 'translate3d(0,0,0)';
     // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
-
-    this.animationItem.wrapper.appendChild(this.svgElement); // Mask animation
-
+    this.animationItem.wrapper.appendChild(this.svgElement);
+    // Mask animation
     var defs = this.globalData.defs;
     this.setupGlobalData(animData, defs);
     this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
@@ -12453,71 +10529,54 @@
     this.layers = animData.layers;
     this.elements = createSizedArray(animData.layers.length);
   };
-
   SVGRendererBase.prototype.destroy = function () {
     if (this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     this.layerElement = null;
     this.globalData.defs = null;
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.destroyed = true;
     this.animationItem = null;
   };
-
   SVGRendererBase.prototype.updateContainerSize = function () {};
-
   SVGRendererBase.prototype.findIndexByInd = function (ind) {
     var i = 0;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.layers[i].ind === ind) {
         return i;
       }
     }
-
     return -1;
   };
-
   SVGRendererBase.prototype.buildItem = function (pos) {
     var elements = this.elements;
-
     if (elements[pos] || this.layers[pos].ty === 99) {
       return;
     }
-
     elements[pos] = true;
     var element = this.createItem(this.layers[pos]);
     elements[pos] = element;
-
     if (getExpressionsPlugin()) {
       if (this.layers[pos].ty === 0) {
         this.globalData.projectInterface.registerComposition(element);
       }
-
       element.initExpressions();
     }
-
     this.appendElementInPos(element, pos);
-
     if (this.layers[pos].tt) {
       var elementIndex = 'tp' in this.layers[pos] ? this.findIndexByInd(this.layers[pos].tp) : pos - 1;
-
       if (elementIndex === -1) {
         return;
       }
-
       if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
         this.buildItem(elementIndex);
         this.addPendingElement(element);
@@ -12528,16 +10587,13 @@
       }
     }
   };
-
   SVGRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
-
       if (element.data.tt) {
         var i = 0;
         var len = this.elements.length;
-
         while (i < len) {
           if (this.elements[i] === element) {
             var elementIndex = 'tp' in element.data ? this.findIndexByInd(element.data.tp) : i - 1;
@@ -12546,43 +10602,36 @@
             element.setMatte(matteMask);
             break;
           }
-
           i += 1;
         }
       }
     }
   };
-
   SVGRendererBase.prototype.renderFrame = function (num) {
     if (this.renderedFrame === num || this.destroyed) {
       return;
     }
-
     if (num === null) {
       num = this.renderedFrame;
     } else {
       this.renderedFrame = num;
-    } // console.log('-------');
+    }
+    // console.log('-------');
     // console.log('FRAME ',num);
-
-
     this.globalData.frameNum = num;
     this.globalData.frameId += 1;
     this.globalData.projectInterface.currentFrame = num;
     this.globalData._mdf = false;
     var i;
     var len = this.layers.length;
-
     if (!this.completeLayers) {
       this.checkLayers(num);
     }
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(num - this.layers[i].st);
       }
     }
-
     if (this.globalData._mdf) {
       for (i = 0; i < len; i += 1) {
         if (this.completeLayers || this.elements[i]) {
@@ -12591,44 +10640,34 @@
       }
     }
   };
-
   SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
     var newElement = element.getBaseElement();
-
     if (!newElement) {
       return;
     }
-
     var i = 0;
     var nextElement;
-
     while (i < pos) {
       if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
         nextElement = this.elements[i].getBaseElement();
       }
-
       i += 1;
     }
-
     if (nextElement) {
       this.layerElement.insertBefore(newElement, nextElement);
     } else {
       this.layerElement.appendChild(newElement);
     }
   };
-
   SVGRendererBase.prototype.hide = function () {
     this.layerElement.style.display = 'none';
   };
-
   SVGRendererBase.prototype.show = function () {
     this.layerElement.style.display = 'block';
   };
 
   function ICompElement() {}
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
-
   ICompElement.prototype.initElement = function (data, globalData, comp) {
     this.initFrame();
     this.initBaseData(data, globalData, comp);
@@ -12638,13 +10677,12 @@
     this.initRendererElement();
     this.createContainerElements();
     this.createRenderableComponents();
-
     if (this.data.xt || !globalData.progressiveLoad) {
       this.buildAllItems();
     }
-
     this.hide();
   };
+
   /* ICompElement.prototype.hide = function(){
       if(!this.hidden){
           this.hideElement();
@@ -12657,77 +10695,61 @@
       }
   }; */
 
-
   ICompElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
-
     if (!this.isInRange && !this.data.xt) {
       return;
     }
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
-
       if (timeRemapped === this.data.op) {
         timeRemapped = this.data.op - 1;
       }
-
       this.renderedFrame = timeRemapped;
     } else {
       this.renderedFrame = num / this.data.sr;
     }
-
     var i;
     var len = this.elements.length;
-
     if (!this.completeLayers) {
       this.checkLayers(this.renderedFrame);
-    } // This iteration needs to be backwards because of how expressions connect between each other
-
-
+    }
+    // This iteration needs to be backwards because of how expressions connect between each other
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
-
         if (this.elements[i]._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   ICompElement.prototype.renderInnerContent = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].renderFrame();
       }
     }
   };
-
   ICompElement.prototype.setElements = function (elems) {
     this.elements = elems;
   };
-
   ICompElement.prototype.getElements = function () {
     return this.elements;
   };
-
   ICompElement.prototype.destroyElements = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i]) {
         this.elements[i].destroy();
       }
     }
   };
-
   ICompElement.prototype.destroy = function () {
     this.destroyElements();
     this.destroyBaseElement();
@@ -12744,9 +10766,7 @@
       _placeholder: true
     };
   }
-
   extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
-
   SVGCompElement.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
@@ -12757,7 +10777,6 @@
     this.renderedFrame = -1;
     this.svgElement = createNS('svg');
     var ariaLabel = '';
-
     if (config && config.title) {
       var titleElement = createNS('title');
       var titleId = createElementID();
@@ -12766,7 +10785,6 @@
       this.svgElement.appendChild(titleElement);
       ariaLabel += titleId;
     }
-
     if (config && config.description) {
       var descElement = createNS('desc');
       var descId = createElementID();
@@ -12775,11 +10793,9 @@
       this.svgElement.appendChild(descElement);
       ariaLabel += ' ' + descId;
     }
-
     if (ariaLabel) {
       this.svgElement.setAttribute('aria-labelledby', ariaLabel);
     }
-
     var defs = createNS('defs');
     this.svgElement.appendChild(defs);
     var maskElement = createNS('g');
@@ -12817,15 +10833,15 @@
     this.destroyed = false;
     this.rendererType = 'svg';
   }
-
   extendPrototype([SVGRendererBase], SVGRenderer);
-
   SVGRenderer.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
 
-  registerRenderer('svg', SVGRenderer); // Registering shape modifiers
+  // Registering renderers
+  registerRenderer('svg', SVGRenderer);
 
+  // Registering shape modifiers
   ShapeModifiers.registerModifier('tm', TrimModifier);
   ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
   ShapeModifiers.registerModifier('rp', RepeaterModifier);
@@ -12838,18 +10854,15 @@
       function _thisLayerFunction(name) {
         var i = 0;
         var len = comp.layers.length;
-
         while (i < len) {
           if (comp.layers[i].nm === name || comp.layers[i].ind === name) {
             return comp.elements[i].layerInterface;
           }
-
           i += 1;
         }
-
-        return null; // return {active:false};
+        return null;
+        // return {active:false};
       }
-
       Object.defineProperty(_thisLayerFunction, '_name', {
         value: comp.data.nm
       });
@@ -12865,10 +10878,8 @@
     };
   }();
 
-  function _typeof$2(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$2 = function _typeof(obj) { return typeof obj; }; } else { _typeof$2 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$2(obj); }
-
+  function _typeof$2(o) { "@babel/helpers - typeof"; return _typeof$2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$2(o); }
   /* eslint-disable */
-
   /*
    Copyright 2014 David Bau.
 
@@ -12892,105 +10903,103 @@
    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
    */
+
   function seedRandom(pool, math) {
     //
     // The following constants are related to IEEE 754 limits.
     //
     var global = this,
-        width = 256,
-        // each RC4 output is 0 <= x < 256
-    chunks = 6,
-        // at least six RC4 outputs for each double
-    digits = 52,
-        // there are 52 significant digits in a double
-    rngname = 'random',
-        // rngname: name for Math.random and Math.seedrandom
-    startdenom = math.pow(width, chunks),
-        significance = math.pow(2, digits),
-        overflow = significance * 2,
-        mask = width - 1,
-        nodecrypto; // node.js crypto module, initialized at the bottom.
+      width = 256,
+      // each RC4 output is 0 <= x < 256
+      chunks = 6,
+      // at least six RC4 outputs for each double
+      digits = 52,
+      // there are 52 significant digits in a double
+      rngname = 'random',
+      // rngname: name for Math.random and Math.seedrandom
+      startdenom = math.pow(width, chunks),
+      significance = math.pow(2, digits),
+      overflow = significance * 2,
+      mask = width - 1,
+      nodecrypto; // node.js crypto module, initialized at the bottom.
+
     //
     // seedrandom()
     // This is the seedrandom function described above.
     //
-
     function seedrandom(seed, options, callback) {
       var key = [];
       options = options === true ? {
         entropy: true
-      } : options || {}; // Flatten the seed string or build one from local entropy if needed.
+      } : options || {};
 
-      var shortseed = mixkey(flatten(options.entropy ? [seed, tostring(pool)] : seed === null ? autoseed() : seed, 3), key); // Use the seed to initialize an ARC4 generator.
+      // Flatten the seed string or build one from local entropy if needed.
+      var shortseed = mixkey(flatten(options.entropy ? [seed, tostring(pool)] : seed === null ? autoseed() : seed, 3), key);
 
-      var arc4 = new ARC4(key); // This function returns a random double in [0, 1) that contains
+      // Use the seed to initialize an ARC4 generator.
+      var arc4 = new ARC4(key);
+
+      // This function returns a random double in [0, 1) that contains
       // randomness in every bit of the mantissa of the IEEE 754 value.
-
       var prng = function prng() {
         var n = arc4.g(chunks),
-            // Start with a numerator n < 2 ^ 48
-        d = startdenom,
-            //   and denominator d = 2 ^ 48.
-        x = 0; //   and no 'extra last byte'.
-
+          // Start with a numerator n < 2 ^ 48
+          d = startdenom,
+          //   and denominator d = 2 ^ 48.
+          x = 0; //   and no 'extra last byte'.
         while (n < significance) {
           // Fill up all significant digits by
           n = (n + x) * width; //   shifting numerator and
-
           d *= width; //   denominator and generating a
-
           x = arc4.g(1); //   new least-significant-byte.
         }
-
         while (n >= overflow) {
           // To avoid rounding up, before adding
           n /= 2; //   last byte, shift everything
-
           d /= 2; //   right using integer math until
-
           x >>>= 1; //   we have exactly the desired bits.
         }
-
         return (n + x) / d; // Form the number within [0, 1).
       };
-
       prng.int32 = function () {
         return arc4.g(4) | 0;
       };
-
       prng.quick = function () {
         return arc4.g(4) / 0x100000000;
       };
+      prng["double"] = prng;
 
-      prng["double"] = prng; // Mix the randomness into accumulated entropy.
+      // Mix the randomness into accumulated entropy.
+      mixkey(tostring(arc4.S), pool);
 
-      mixkey(tostring(arc4.S), pool); // Calling convention: what to return as a function of prng, seed, is_math.
-
+      // Calling convention: what to return as a function of prng, seed, is_math.
       return (options.pass || callback || function (prng, seed, is_math_call, state) {
         if (state) {
           // Load the arc4 state from the given state if it has an S array.
           if (state.S) {
             copy(state, arc4);
-          } // Only provide the .state method if requested via options.state.
-
-
+          }
+          // Only provide the .state method if requested via options.state.
           prng.state = function () {
             return copy(arc4, {});
           };
-        } // If called as a method of Math (Math.seedrandom()), mutate
+        }
+
+        // If called as a method of Math (Math.seedrandom()), mutate
         // Math.random because that is how seedrandom.js has worked since v1.0.
-
-
         if (is_math_call) {
           math[rngname] = prng;
           return seed;
-        } // Otherwise, it is a newer calling convention, so return the
+        }
+
+        // Otherwise, it is a newer calling convention, so return the
         // prng directly.
         else return prng;
       })(prng, shortseed, 'global' in options ? options.global : this == math, options.state);
     }
+    math['seed' + rngname] = seedrandom;
 
-    math['seed' + rngname] = seedrandom; //
+    //
     // ARC4
     //
     // An ARC4 implementation.  The constructor takes a key in the form of
@@ -13000,71 +11009,68 @@
     // the next (count) outputs from ARC4.  Its return value is a number x
     // that is in the range 0 <= x < (width ^ count).
     //
-
     function ARC4(key) {
       var t,
-          keylen = key.length,
-          me = this,
-          i = 0,
-          j = me.i = me.j = 0,
-          s = me.S = []; // The empty key [] is treated as [0].
+        keylen = key.length,
+        me = this,
+        i = 0,
+        j = me.i = me.j = 0,
+        s = me.S = [];
 
+      // The empty key [] is treated as [0].
       if (!keylen) {
         key = [keylen++];
-      } // Set up S using the standard key scheduling algorithm.
+      }
 
-
+      // Set up S using the standard key scheduling algorithm.
       while (i < width) {
         s[i] = i++;
       }
-
       for (i = 0; i < width; i++) {
         s[i] = s[j = mask & j + key[i % keylen] + (t = s[i])];
         s[j] = t;
-      } // The "g" method returns the next (count) outputs as one number.
+      }
 
-
+      // The "g" method returns the next (count) outputs as one number.
       me.g = function (count) {
         // Using instance members instead of closure state nearly doubles speed.
         var t,
-            r = 0,
-            i = me.i,
-            j = me.j,
-            s = me.S;
-
+          r = 0,
+          i = me.i,
+          j = me.j,
+          s = me.S;
         while (count--) {
           t = s[i = mask & i + 1];
           r = r * width + s[mask & (s[i] = s[j = mask & j + t]) + (s[j] = t)];
         }
-
         me.i = i;
         me.j = j;
-        return r; // For robust unpredictability, the function call below automatically
+        return r;
+        // For robust unpredictability, the function call below automatically
         // discards an initial batch of values.  This is called RC4-drop[256].
         // See http://google.com/search?q=rsa+fluhrer+response&btnI
       };
-    } //
+    }
+
+    //
     // copy()
     // Copies internal state of ARC4 to or from a plain object.
     //
-
-
     function copy(f, t) {
       t.i = f.i;
       t.j = f.j;
       t.S = f.S.slice();
       return t;
-    } //
+    }
+
+    //
     // flatten()
     // Converts an object tree to nested arrays of strings.
     //
-
-
     function flatten(obj, depth) {
       var result = [],
-          typ = _typeof$2(obj),
-          prop;
-
+        typ = _typeof$2(obj),
+        prop;
       if (depth && typ == 'object') {
         for (prop in obj) {
           try {
@@ -13072,72 +11078,69 @@
           } catch (e) {}
         }
       }
-
       return result.length ? result : typ == 'string' ? obj : obj + '\0';
-    } //
+    }
+
+    //
     // mixkey()
     // Mixes a string seed into a key that is an array of integers, and
     // returns a shortened string seed that is equivalent to the result key.
     //
-
-
     function mixkey(seed, key) {
       var stringseed = seed + '',
-          smear,
-          j = 0;
-
+        smear,
+        j = 0;
       while (j < stringseed.length) {
         key[mask & j] = mask & (smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++);
       }
-
       return tostring(key);
-    } //
+    }
+
+    //
     // autoseed()
     // Returns an object for autoseeding, using window.crypto and Node crypto
     // module if available.
     //
-
-
     function autoseed() {
       try {
         if (nodecrypto) {
           return tostring(nodecrypto.randomBytes(width));
         }
-
         var out = new Uint8Array(width);
         (global.crypto || global.msCrypto).getRandomValues(out);
         return tostring(out);
       } catch (e) {
         var browser = global.navigator,
-            plugins = browser && browser.plugins;
+          plugins = browser && browser.plugins;
         return [+new Date(), global, plugins, global.screen, tostring(pool)];
       }
-    } //
+    }
+
+    //
     // tostring()
     // Converts an array of charcodes to a string
     //
-
-
     function tostring(a) {
       return String.fromCharCode.apply(0, a);
-    } //
+    }
+
+    //
     // When seedrandom.js is loaded, we immediately mix a few bits
     // from the built-in RNG into the entropy pool.  Because we do
     // not want to interfere with deterministic PRNG state later,
     // seedrandom will not call math.random on its own again after
     // initialization.
     //
+    mixkey(math.random(), pool);
 
-
-    mixkey(math.random(), pool); //
+    //
     // Nodejs and AMD support: export the implementation as a module using
     // either convention.
     //
+
     // End anonymous scope, and pass initial values.
   }
-
   ;
-
   function initialize$2(BMMath) {
     seedRandom([], BMMath);
   }
@@ -13146,8 +11149,7 @@
     SHAPE: 'shape'
   };
 
-  function _typeof$1(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$1 = function _typeof(obj) { return typeof obj; }; } else { _typeof$1 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$1(obj); }
-
+  function _typeof$1(o) { "@babel/helpers - typeof"; return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$1(o); }
   var ExpressionManager = function () {
     'use strict';
 
@@ -13160,289 +11162,214 @@
     var frames = null;
     var _lottieGlobal = {};
     initialize$2(BMMath);
-
     function resetFrame() {
       _lottieGlobal = {};
     }
-
     function $bm_isInstanceOfArray(arr) {
       return arr.constructor === Array || arr.constructor === Float32Array;
     }
-
     function isNumerable(tOfV, v) {
       return tOfV === 'number' || v instanceof Number || tOfV === 'boolean' || tOfV === 'string';
     }
-
     function $bm_neg(a) {
       var tOfA = _typeof$1(a);
-
       if (tOfA === 'number' || a instanceof Number || tOfA === 'boolean') {
         return -a;
       }
-
       if ($bm_isInstanceOfArray(a)) {
         var i;
         var lenA = a.length;
         var retArr = [];
-
         for (i = 0; i < lenA; i += 1) {
           retArr[i] = -a[i];
         }
-
         return retArr;
       }
-
       if (a.propType) {
         return a.v;
       }
-
       return -a;
     }
-
     var easeInBez = BezierFactory.getBezierEasing(0.333, 0, 0.833, 0.833, 'easeIn').get;
     var easeOutBez = BezierFactory.getBezierEasing(0.167, 0.167, 0.667, 1, 'easeOut').get;
     var easeInOutBez = BezierFactory.getBezierEasing(0.33, 0, 0.667, 1, 'easeInOut').get;
-
     function sum(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b) || tOfA === 'string' || tOfB === 'string') {
         return a + b;
       }
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         a = a.slice(0);
         a[0] += b;
         return a;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         b = b.slice(0);
         b[0] = a + b[0];
         return b;
       }
-
       if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
         var i = 0;
         var lenA = a.length;
         var lenB = b.length;
         var retArr = [];
-
         while (i < lenA || i < lenB) {
           if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
             retArr[i] = a[i] + b[i];
           } else {
             retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
           }
-
           i += 1;
         }
-
         return retArr;
       }
-
       return 0;
     }
-
     var add = sum;
-
     function sub(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         if (tOfA === 'string') {
           a = parseInt(a, 10);
         }
-
         if (tOfB === 'string') {
           b = parseInt(b, 10);
         }
-
         return a - b;
       }
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         a = a.slice(0);
         a[0] -= b;
         return a;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         b = b.slice(0);
         b[0] = a - b[0];
         return b;
       }
-
       if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
         var i = 0;
         var lenA = a.length;
         var lenB = b.length;
         var retArr = [];
-
         while (i < lenA || i < lenB) {
           if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
             retArr[i] = a[i] - b[i];
           } else {
             retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
           }
-
           i += 1;
         }
-
         return retArr;
       }
-
       return 0;
     }
-
     function mul(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       var arr;
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         return a * b;
       }
-
       var i;
       var len;
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         len = a.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a[i] * b;
         }
-
         return arr;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         len = b.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a * b[i];
         }
-
         return arr;
       }
-
       return 0;
     }
-
     function div(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       var arr;
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         return a / b;
       }
-
       var i;
       var len;
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         len = a.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a[i] / b;
         }
-
         return arr;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         len = b.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a / b[i];
         }
-
         return arr;
       }
-
       return 0;
     }
-
     function mod(a, b) {
       if (typeof a === 'string') {
         a = parseInt(a, 10);
       }
-
       if (typeof b === 'string') {
         b = parseInt(b, 10);
       }
-
       return a % b;
     }
-
     var $bm_sum = sum;
     var $bm_sub = sub;
     var $bm_mul = mul;
     var $bm_div = div;
     var $bm_mod = mod;
-
     function clamp(num, min, max) {
       if (min > max) {
         var mm = max;
         max = min;
         min = mm;
       }
-
       return Math.min(Math.max(num, min), max);
     }
-
     function radiansToDegrees(val) {
       return val / degToRads;
     }
-
     var radians_to_degrees = radiansToDegrees;
-
     function degreesToRadians(val) {
       return val * degToRads;
     }
-
     var degrees_to_radians = radiansToDegrees;
     var helperLengthArray = [0, 0, 0, 0, 0, 0];
-
     function length(arr1, arr2) {
       if (typeof arr1 === 'number' || arr1 instanceof Number) {
         arr2 = arr2 || 0;
         return Math.abs(arr1 - arr2);
       }
-
       if (!arr2) {
         arr2 = helperLengthArray;
       }
-
       var i;
       var len = Math.min(arr1.length, arr2.length);
       var addedLength = 0;
-
       for (i = 0; i < len; i += 1) {
         addedLength += Math.pow(arr2[i] - arr1[i], 2);
       }
-
       return Math.sqrt(addedLength);
     }
-
     function normalize(vec) {
       return div(vec, length(vec));
     }
-
     function rgbToHsl(val) {
       var r = val[0];
       var g = val[1];
@@ -13452,38 +11379,29 @@
       var h;
       var s;
       var l = (max + min) / 2;
-
       if (max === min) {
         h = 0; // achromatic
-
         s = 0; // achromatic
       } else {
         var d = max - min;
         s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
-
         switch (max) {
           case r:
             h = (g - b) / d + (g < b ? 6 : 0);
             break;
-
           case g:
             h = (b - r) / d + 2;
             break;
-
           case b:
             h = (r - g) / d + 4;
             break;
-
           default:
             break;
         }
-
         h /= 6;
       }
-
       return [h, s, l, val[3]];
     }
-
     function hue2rgb(p, q, t) {
       if (t < 0) t += 1;
       if (t > 1) t -= 1;
@@ -13492,7 +11410,6 @@
       if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
       return p;
     }
-
     function hslToRgb(val) {
       var h = val[0];
       var s = val[1];
@@ -13500,12 +11417,9 @@
       var r;
       var g;
       var b;
-
       if (s === 0) {
         r = l; // achromatic
-
         b = l; // achromatic
-
         g = l; // achromatic
       } else {
         var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
@@ -13514,10 +11428,8 @@
         g = hue2rgb(p, q, h);
         b = hue2rgb(p, q, h - 1 / 3);
       }
-
       return [r, g, b, val[3]];
     }
-
     function linear(t, tMin, tMax, value1, value2) {
       if (value1 === undefined || value2 === undefined) {
         value1 = tMin;
@@ -13525,38 +11437,29 @@
         tMin = 0;
         tMax = 1;
       }
-
       if (tMax < tMin) {
         var _tMin = tMax;
         tMax = tMin;
         tMin = _tMin;
       }
-
       if (t <= tMin) {
         return value1;
       }
-
       if (t >= tMax) {
         return value2;
       }
-
       var perc = tMax === tMin ? 0 : (t - tMin) / (tMax - tMin);
-
       if (!value1.length) {
         return value1 + (value2 - value1) * perc;
       }
-
       var i;
       var len = value1.length;
       var arr = createTypedArray('float32', len);
-
       for (i = 0; i < len; i += 1) {
         arr[i] = value1[i] + (value2[i] - value1[i]) * perc;
       }
-
       return arr;
     }
-
     function random(min, max) {
       if (max === undefined) {
         if (min === undefined) {
@@ -13567,33 +11470,25 @@
           min = undefined;
         }
       }
-
       if (max.length) {
         var i;
         var len = max.length;
-
         if (!min) {
           min = createTypedArray('float32', len);
         }
-
         var arr = createTypedArray('float32', len);
         var rnd = BMMath.random();
-
         for (i = 0; i < len; i += 1) {
           arr[i] = min[i] + rnd * (max[i] - min[i]);
         }
-
         return arr;
       }
-
       if (min === undefined) {
         min = 0;
       }
-
       var rndm = BMMath.random();
       return min + rndm * (max - min);
     }
-
     function createPath(points, inTangents, outTangents, closed) {
       var i;
       var len = points.length;
@@ -13602,37 +11497,31 @@
       var arrPlaceholder = [0, 0];
       var inVertexPoint;
       var outVertexPoint;
-
       for (i = 0; i < len; i += 1) {
         inVertexPoint = inTangents && inTangents[i] ? inTangents[i] : arrPlaceholder;
         outVertexPoint = outTangents && outTangents[i] ? outTangents[i] : arrPlaceholder;
         path.setTripleAt(points[i][0], points[i][1], outVertexPoint[0] + points[i][0], outVertexPoint[1] + points[i][1], inVertexPoint[0] + points[i][0], inVertexPoint[1] + points[i][1], i, true);
       }
-
       return path;
     }
-
     function initiateExpression(elem, data, property) {
       // Bail out if we don't want expressions
       function noOp(_value) {
         return _value;
       }
-
       if (!elem.globalData.renderConfig.runExpressions) {
         return noOp;
       }
-
       var val = data.x;
       var needsVelocity = /velocity(?![\w\d])/.test(val);
-
       var _needsRandom = val.indexOf('random') !== -1;
-
       var elemType = elem.data.ty;
       var transform;
       var $bm_transform;
       var content;
       var effect;
       var thisProperty = property;
+      thisProperty._name = elem.data.nm;
       thisProperty.valueAtTime = thisProperty.getValueAtTime;
       Object.defineProperty(thisProperty, 'value', {
         get: function get() {
@@ -13665,13 +11554,11 @@
       var mask;
       var valueAtTime;
       var velocityAtTime;
-      var scoped_bm_rt; // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
-
+      var scoped_bm_rt;
+      // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
       var expression_function = eval('[function _expression_function(){' + val + ';scoped_bm_rt=$bm_rt}]')[0]; // eslint-disable-line no-eval
-
       var numKeys = property.kf ? data.k.length : 0;
       var active = !this.data || this.data.hd !== true;
-
       var wiggle = function wiggle(freq, amp) {
         var iWiggle;
         var j;
@@ -13681,84 +11568,67 @@
         var iterations = Math.floor(time * freq);
         iWiggle = 0;
         j = 0;
-
         while (iWiggle < iterations) {
           // var rnd = BMMath.random();
           for (j = 0; j < lenWiggle; j += 1) {
-            addedAmps[j] += -amp + amp * 2 * BMMath.random(); // addedAmps[j] += -amp + amp*2*rnd;
+            addedAmps[j] += -amp + amp * 2 * BMMath.random();
+            // addedAmps[j] += -amp + amp*2*rnd;
           }
-
           iWiggle += 1;
-        } // var rnd2 = BMMath.random();
-
-
+        }
+        // var rnd2 = BMMath.random();
         var periods = time * freq;
         var perc = periods - Math.floor(periods);
         var arr = createTypedArray('float32', lenWiggle);
-
         if (lenWiggle > 1) {
           for (j = 0; j < lenWiggle; j += 1) {
-            arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc; // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
+            arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc;
+            // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
             // arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc);
           }
-
           return arr;
         }
-
         return this.pv + addedAmps[0] + (-amp + amp * 2 * BMMath.random()) * perc;
       }.bind(this);
-
       if (thisProperty.loopIn) {
         loopIn = thisProperty.loopIn.bind(thisProperty);
         loop_in = loopIn;
       }
-
       if (thisProperty.loopOut) {
         loopOut = thisProperty.loopOut.bind(thisProperty);
         loop_out = loopOut;
       }
-
       if (thisProperty.smooth) {
         smooth = thisProperty.smooth.bind(thisProperty);
       }
-
       function loopInDuration(type, duration) {
         return loopIn(type, duration, true);
       }
-
       function loopOutDuration(type, duration) {
         return loopOut(type, duration, true);
       }
-
       if (this.getValueAtTime) {
         valueAtTime = this.getValueAtTime.bind(this);
       }
-
       if (this.getVelocityAtTime) {
         velocityAtTime = this.getVelocityAtTime.bind(this);
       }
-
       var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface);
-
       function lookAt(elem1, elem2) {
         var fVec = [elem2[0] - elem1[0], elem2[1] - elem1[1], elem2[2] - elem1[2]];
         var pitch = Math.atan2(fVec[0], Math.sqrt(fVec[1] * fVec[1] + fVec[2] * fVec[2])) / degToRads;
         var yaw = -Math.atan2(fVec[1], fVec[2]) / degToRads;
         return [yaw, pitch, 0];
       }
-
       function easeOut(t, tMin, tMax, val1, val2) {
         return applyEase(easeOutBez, t, tMin, tMax, val1, val2);
       }
-
       function easeIn(t, tMin, tMax, val1, val2) {
         return applyEase(easeInBez, t, tMin, tMax, val1, val2);
       }
-
       function ease(t, tMin, tMax, val1, val2) {
         return applyEase(easeInOutBez, t, tMin, tMax, val1, val2);
       }
-
       function applyEase(fn, t, tMin, tMax, val1, val2) {
         if (val1 === undefined) {
           val1 = tMin;
@@ -13766,43 +11636,34 @@
         } else {
           t = (t - tMin) / (tMax - tMin);
         }
-
         if (t > 1) {
           t = 1;
         } else if (t < 0) {
           t = 0;
         }
-
         var mult = fn(t);
-
         if ($bm_isInstanceOfArray(val1)) {
           var iKey;
           var lenKey = val1.length;
           var arr = createTypedArray('float32', lenKey);
-
           for (iKey = 0; iKey < lenKey; iKey += 1) {
             arr[iKey] = (val2[iKey] - val1[iKey]) * mult + val1[iKey];
           }
-
           return arr;
         }
-
         return (val2 - val1) * mult + val1;
       }
-
       function nearestKey(time) {
         var iKey;
         var lenKey = data.k.length;
         var index;
         var keyTime;
-
         if (!data.k.length || typeof data.k[0] === 'number') {
           index = 0;
           keyTime = 0;
         } else {
           index = -1;
           time *= elem.comp.globalData.frameRate;
-
           if (time < data.k[0].t) {
             index = 1;
             keyTime = data.k[0].t;
@@ -13820,33 +11681,27 @@
                   index = iKey + 1;
                   keyTime = data.k[iKey].t;
                 }
-
                 break;
               }
             }
-
             if (index === -1) {
               index = iKey + 1;
               keyTime = data.k[iKey].t;
             }
           }
         }
-
         var obKey = {};
         obKey.index = index;
         obKey.time = keyTime / elem.comp.globalData.frameRate;
         return obKey;
       }
-
       function key(ind) {
         var obKey;
         var iKey;
         var lenKey;
-
         if (!data.k.length || typeof data.k[0] === 'number') {
           throw new Error('The property has no keyframe at index ' + ind);
         }
-
         ind -= 1;
         obKey = {
           time: data.k[ind].t / elem.comp.globalData.frameRate,
@@ -13854,72 +11709,55 @@
         };
         var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e;
         lenKey = arr.length;
-
         for (iKey = 0; iKey < lenKey; iKey += 1) {
           obKey[iKey] = arr[iKey];
           obKey.value[iKey] = arr[iKey];
         }
-
         return obKey;
       }
-
       function framesToTime(fr, fps) {
         if (!fps) {
           fps = elem.comp.globalData.frameRate;
         }
-
         return fr / fps;
       }
-
       function timeToFrames(t, fps) {
         if (!t && t !== 0) {
           t = time;
         }
-
         if (!fps) {
           fps = elem.comp.globalData.frameRate;
         }
-
         return t * fps;
       }
-
       function seedRandom(seed) {
         BMMath.seedrandom(randSeed + seed);
       }
-
       function sourceRectAtTime() {
         return elem.sourceRectAtTime();
       }
-
       function substring(init, end) {
         if (typeof value === 'string') {
           if (end === undefined) {
             return value.substring(init);
           }
-
           return value.substring(init, end);
         }
-
         return '';
       }
-
       function substr(init, end) {
         if (typeof value === 'string') {
           if (end === undefined) {
             return value.substr(init);
           }
-
           return value.substr(init, end);
         }
-
         return '';
       }
-
       function posterizeTime(framesPerSecond) {
         time = framesPerSecond === 0 ? 0 : Math.floor(time * framesPerSecond) / framesPerSecond;
         value = valueAtTime(time);
       }
-
       var time;
       var velocity;
       var value;
@@ -13932,21 +11770,17 @@
       var parent;
       var randSeed = Math.floor(Math.random() * 1000000);
       var globalData = elem.globalData;
-
       function executeExpression(_value) {
         // globalData.pushExpression();
         value = _value;
-
         if (this.frameExpressionId === elem.globalData.frameId && this.propType !== 'textSelector') {
           return value;
         }
-
         if (this.propType === 'textSelector') {
           textIndex = this.textIndex;
           textTotal = this.textTotal;
           selectorValue = this.selectorValue;
         }
-
         if (!thisLayer) {
           text = elem.layerInterface.text;
           thisLayer = elem.layerInterface;
@@ -13958,11 +11792,9 @@
           mask = thisLayer.mask ? thisLayer.mask.bind(thisLayer) : null;
           fromCompToSurface = fromComp;
         }
-
         if (!transform) {
           transform = elem.layerInterface('ADBE Transform Group');
           $bm_transform = transform;
-
           if (transform) {
             anchorPoint = transform.anchorPoint;
             /* position = transform.position;
@@ -13970,44 +11802,35 @@
                       scale = transform.scale; */
           }
         }
-
         if (elemType === 4 && !content) {
           content = thisLayer('ADBE Root Vectors Group');
         }
-
         if (!effect) {
           effect = thisLayer(4);
         }
-
         hasParent = !!(elem.hierarchy && elem.hierarchy.length);
-
         if (hasParent && !parent) {
           parent = elem.hierarchy[0].layerInterface;
         }
-
         time = this.comp.renderedFrame / this.comp.globalData.frameRate;
-
         if (_needsRandom) {
           seedRandom(randSeed + time);
         }
-
         if (needsVelocity) {
           velocity = velocityAtTime(time);
         }
-
         expression_function();
-        this.frameExpressionId = elem.globalData.frameId; // TODO: Check if it's possible to return on ShapeInterface the .v value
-        // Changed this to a ternary operation because Rollup failed compiling it correctly
+        this.frameExpressionId = elem.globalData.frameId;
 
+        // TODO: Check if it's possible to return on ShapeInterface the .v value
+        // Changed this to a ternary operation because Rollup failed compiling it correctly
         scoped_bm_rt = scoped_bm_rt.propType === propTypes.SHAPE ? scoped_bm_rt.v : scoped_bm_rt;
         return scoped_bm_rt;
-      } // Bundlers will see these as dead code and unless we reference them
-
-
+      }
+      // Bundlers will see these as dead code and unless we reference them
       executeExpression.__preventDeadCodeRemoval = [$bm_transform, anchorPoint, time, velocity, inPoint, outPoint, width, height, name, loop_in, loop_out, smooth, toComp, fromCompToSurface, toWorld, fromWorld, mask, position, rotation, scale, thisComp, numKeys, active, wiggle, loopInDuration, loopOutDuration, comp, lookAt, easeOut, easeIn, ease, nearestKey, key, text, textIndex, textTotal, selectorValue, framesToTime, timeToFrames, sourceRectAtTime, substring, substr, posterizeTime, index, globalData];
       return executeExpression;
     }
-
     ob.initiateExpression = initiateExpression;
     ob.__preventDeadCodeRemoval = [window, document, XMLHttpRequest, fetch, frames, $bm_neg, add, $bm_sum, $bm_sub, $bm_mul, $bm_div, $bm_mod, clamp, radians_to_degrees, degreesToRadians, degrees_to_radians, normalize, rgbToHsl, hslToRgb, linear, random, createPath, _lottieGlobal];
     ob.resetFrame = resetFrame;
@@ -14018,47 +11841,37 @@
     var ob = {};
     ob.initExpressions = initExpressions;
     ob.resetFrame = ExpressionManager.resetFrame;
-
     function initExpressions(animation) {
       var stackCount = 0;
       var registers = [];
-
       function pushExpression() {
         stackCount += 1;
       }
-
       function popExpression() {
         stackCount -= 1;
-
         if (stackCount === 0) {
           releaseInstances();
         }
       }
-
       function registerExpressionProperty(expression) {
         if (registers.indexOf(expression) === -1) {
           registers.push(expression);
         }
       }
-
       function releaseInstances() {
         var i;
         var len = registers.length;
-
         for (i = 0; i < len; i += 1) {
           registers[i].release();
         }
-
         registers.length = 0;
       }
-
       animation.renderer.compInterface = CompExpressionInterface(animation.renderer);
       animation.renderer.globalData.projectInterface.registerComposition(animation.renderer);
       animation.renderer.globalData.pushExpression = pushExpression;
       animation.renderer.globalData.popExpression = popExpression;
       animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty;
     }
-
     return ob;
   }();
 
@@ -14067,13 +11880,11 @@
       this._mask = mask;
       this._data = data;
     }
-
     Object.defineProperty(MaskInterface.prototype, 'maskPath', {
       get: function get() {
         if (this._mask.prop.k) {
           this._mask.prop.getValue();
         }
-
         return this._mask.prop;
       }
     });
@@ -14082,38 +11893,28 @@
         if (this._mask.op.k) {
           this._mask.op.getValue();
         }
-
         return this._mask.op.v * 100;
       }
     });
-
     var MaskManager = function MaskManager(maskManager) {
       var _masksInterfaces = createSizedArray(maskManager.viewData.length);
-
       var i;
       var len = maskManager.viewData.length;
-
       for (i = 0; i < len; i += 1) {
         _masksInterfaces[i] = new MaskInterface(maskManager.viewData[i], maskManager.masksProperties[i]);
       }
-
       var maskFunction = function maskFunction(name) {
         i = 0;
-
         while (i < len) {
           if (maskManager.masksProperties[i].nm === name) {
             return _masksInterfaces[i];
           }
-
           i += 1;
         }
-
         return null;
       };
-
       return maskFunction;
     };
-
     return MaskManager;
   }();
 
@@ -14128,7 +11929,6 @@
       v: [0, 0, 0],
       mult: 1
     };
-
     function completeProperty(expressionValue, property, type) {
       Object.defineProperty(expressionValue, 'velocity', {
         get: function get() {
@@ -14136,14 +11936,11 @@
         }
       });
       expressionValue.numKeys = property.keyframes ? property.keyframes.length : 0;
-
       expressionValue.key = function (pos) {
         if (!expressionValue.numKeys) {
           return 0;
         }
-
         var value = '';
-
         if ('s' in property.keyframes[pos - 1]) {
           value = property.keyframes[pos - 1].s;
         } else if ('e' in property.keyframes[pos - 2]) {
@@ -14151,54 +11948,43 @@
         } else {
           value = property.keyframes[pos - 2].s;
         }
-
         var valueProp = type === 'unidimensional' ? new Number(value) : Object.assign({}, value); // eslint-disable-line no-new-wrappers
-
         valueProp.time = property.keyframes[pos - 1].t / property.elem.comp.globalData.frameRate;
         valueProp.value = type === 'unidimensional' ? value[0] : value;
         return valueProp;
       };
-
       expressionValue.valueAtTime = property.getValueAtTime;
       expressionValue.speedAtTime = property.getSpeedAtTime;
       expressionValue.velocityAtTime = property.getVelocityAtTime;
       expressionValue.propertyGroup = property.propertyGroup;
     }
-
     function UnidimensionalPropertyInterface(property) {
       if (!property || !('pv' in property)) {
         property = defaultUnidimensionalValue;
       }
-
       var mult = 1 / property.mult;
       var val = property.pv * mult;
       var expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
-
       expressionValue.value = val;
       completeProperty(expressionValue, property, 'unidimensional');
       return function () {
         if (property.k) {
           property.getValue();
         }
-
         val = property.v * mult;
-
         if (expressionValue.value !== val) {
           expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
-
           expressionValue.value = val;
+          expressionValue[0] = val;
           completeProperty(expressionValue, property, 'unidimensional');
         }
-
         return expressionValue;
       };
     }
-
     function MultidimensionalPropertyInterface(property) {
       if (!property || !('pv' in property)) {
         property = defaultMultidimensionalValue;
       }
-
       var mult = 1 / property.mult;
       var len = property.data && property.data.l || property.pv.length;
       var expressionValue = createTypedArray('float32', len);
@@ -14209,30 +11995,25 @@
         if (property.k) {
           property.getValue();
         }
-
         for (var i = 0; i < len; i += 1) {
           arrValue[i] = property.v[i] * mult;
           expressionValue[i] = arrValue[i];
         }
-
         return expressionValue;
       };
-    } // TODO: try to avoid using this getter
+    }
 
-
+    // TODO: try to avoid using this getter
     function defaultGetter() {
       return defaultUnidimensionalValue;
     }
-
     return function (property) {
       if (!property) {
         return defaultGetter;
       }
-
       if (property.propType === 'unidimensional') {
         return UnidimensionalPropertyInterface(property);
       }
-
       return MultidimensionalPropertyInterface(property);
     };
   }();
@@ -14246,52 +12027,41 @@
           case 'ADBE Scale':
           case 6:
             return _thisFunction.scale;
-
           case 'rotation':
           case 'Rotation':
           case 'ADBE Rotation':
           case 'ADBE Rotate Z':
           case 10:
             return _thisFunction.rotation;
-
           case 'ADBE Rotate X':
             return _thisFunction.xRotation;
-
           case 'ADBE Rotate Y':
             return _thisFunction.yRotation;
-
           case 'position':
           case 'Position':
           case 'ADBE Position':
           case 2:
             return _thisFunction.position;
-
           case 'ADBE Position_0':
             return _thisFunction.xPosition;
-
           case 'ADBE Position_1':
             return _thisFunction.yPosition;
-
           case 'ADBE Position_2':
             return _thisFunction.zPosition;
-
           case 'anchorPoint':
           case 'AnchorPoint':
           case 'Anchor Point':
           case 'ADBE AnchorPoint':
           case 1:
             return _thisFunction.anchorPoint;
-
           case 'opacity':
           case 'Opacity':
           case 11:
             return _thisFunction.opacity;
-
           default:
             return null;
         }
       }
-
       Object.defineProperty(_thisFunction, 'rotation', {
         get: ExpressionPropertyInterface(transform.r || transform.rz)
       });
@@ -14307,32 +12077,24 @@
       Object.defineProperty(_thisFunction, 'scale', {
         get: ExpressionPropertyInterface(transform.s)
       });
-
       var _px;
-
       var _py;
-
       var _pz;
-
       var _transformFactory;
-
       if (transform.p) {
         _transformFactory = ExpressionPropertyInterface(transform.p);
       } else {
         _px = ExpressionPropertyInterface(transform.px);
         _py = ExpressionPropertyInterface(transform.py);
-
         if (transform.pz) {
           _pz = ExpressionPropertyInterface(transform.pz);
         }
       }
-
       Object.defineProperty(_thisFunction, 'position', {
         get: function get() {
           if (transform.p) {
             return _transformFactory();
           }
-
           return [_px(), _py(), _pz ? _pz() : 0];
         }
       });
@@ -14367,19 +12129,15 @@
   var LayerExpressionInterface = function () {
     function getMatrix(time) {
       var toWorldMat = new Matrix();
-
       if (time !== undefined) {
         var propMatrix = this._elem.finalTransform.mProp.getValueAtTime(time);
-
         propMatrix.clone(toWorldMat);
       } else {
         var transformMat = this._elem.finalTransform.mProp;
         transformMat.applyToMatrix(toWorldMat);
       }
-
       return toWorldMat;
     }
-
     function toWorldVec(arr, time) {
       var toWorldMat = this.getMatrix(time);
       toWorldMat.props[12] = 0;
@@ -14387,12 +12145,10 @@
       toWorldMat.props[14] = 0;
       return this.applyPoint(toWorldMat, arr);
     }
-
     function toWorld(arr, time) {
       var toWorldMat = this.getMatrix(time);
       return this.applyPoint(toWorldMat, arr);
     }
-
     function fromWorldVec(arr, time) {
       var toWorldMat = this.getMatrix(time);
       toWorldMat.props[12] = 0;
@@ -14400,101 +12156,78 @@
       toWorldMat.props[14] = 0;
       return this.invertPoint(toWorldMat, arr);
     }
-
     function fromWorld(arr, time) {
       var toWorldMat = this.getMatrix(time);
       return this.invertPoint(toWorldMat, arr);
     }
-
     function applyPoint(matrix, arr) {
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
         }
       }
-
       return matrix.applyToPointArray(arr[0], arr[1], arr[2] || 0);
     }
-
     function invertPoint(matrix, arr) {
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
         }
       }
-
       return matrix.inversePoint(arr);
     }
-
     function fromComp(arr) {
       var toWorldMat = new Matrix();
       toWorldMat.reset();
-
       this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
-
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
         }
-
         return toWorldMat.inversePoint(arr);
       }
-
       return toWorldMat.inversePoint(arr);
     }
-
     function sampleImage() {
       return [1, 1, 1, 1];
     }
-
     return function (elem) {
       var transformInterface;
-
       function _registerMaskInterface(maskManager) {
         _thisLayerFunction.mask = new MaskManagerInterface(maskManager, elem);
       }
-
       function _registerEffectsInterface(effects) {
         _thisLayerFunction.effect = effects;
       }
-
       function _thisLayerFunction(name) {
         switch (name) {
           case 'ADBE Root Vectors Group':
           case 'Contents':
           case 2:
             return _thisLayerFunction.shapeInterface;
-
           case 1:
           case 6:
           case 'Transform':
           case 'transform':
           case 'ADBE Transform Group':
             return transformInterface;
-
           case 4:
           case 'ADBE Effect Parade':
           case 'effects':
           case 'Effects':
             return _thisLayerFunction.effect;
-
           case 'ADBE Text Properties':
             return _thisLayerFunction.textInterface;
-
           default:
             return null;
         }
       }
-
       _thisLayerFunction.getMatrix = getMatrix;
       _thisLayerFunction.invertPoint = invertPoint;
       _thisLayerFunction.applyPoint = applyPoint;
@@ -14555,11 +12288,9 @@
     return function (interfaceFunction, parentPropertyGroup) {
       return function (val) {
         val = val === undefined ? 1 : val;
-
         if (val <= 0) {
           return interfaceFunction;
         }
-
         return parentPropertyGroup(val - 1);
       };
     };
@@ -14570,17 +12301,13 @@
       var interfaceFunction = {
         _name: propertyName
       };
-
       function _propertyGroup(val) {
         val = val === undefined ? 1 : val;
-
         if (val <= 0) {
           return interfaceFunction;
         }
-
         return propertyGroup(val - 1);
       }
-
       return _propertyGroup;
     };
   }();
@@ -14589,35 +12316,27 @@
     var ob = {
       createEffectsInterface: createEffectsInterface
     };
-
     function createEffectsInterface(elem, propertyGroup) {
       if (elem.effectsManager) {
         var effectElements = [];
         var effectsData = elem.data.ef;
         var i;
         var len = elem.effectsManager.effectElements.length;
-
         for (i = 0; i < len; i += 1) {
           effectElements.push(createGroupInterface(effectsData[i], elem.effectsManager.effectElements[i], propertyGroup, elem));
         }
-
         var effects = elem.data.ef || [];
-
         var groupInterface = function groupInterface(name) {
           i = 0;
           len = effects.length;
-
           while (i < len) {
             if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
               return effectElements[i];
             }
-
             i += 1;
           }
-
           return null;
         };
-
         Object.defineProperty(groupInterface, 'numProperties', {
           get: function get() {
             return effects.length;
@@ -14625,37 +12344,28 @@
         });
         return groupInterface;
       }
-
       return null;
     }
-
     function createGroupInterface(data, elements, propertyGroup, elem) {
       function groupInterface(name) {
         var effects = data.ef;
         var i = 0;
         var len = effects.length;
-
         while (i < len) {
           if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
             if (effects[i].ty === 5) {
               return effectElements[i];
             }
-
             return effectElements[i]();
           }
-
           i += 1;
         }
-
         throw new Error();
       }
-
       var _propertyGroup = propertyGroupFactory(groupInterface, propertyGroup);
-
       var effectElements = [];
       var i;
       var len = data.ef.length;
-
       for (i = 0; i < len; i += 1) {
         if (data.ef[i].ty === 5) {
           effectElements.push(createGroupInterface(data.ef[i], elements.effectElements[i], elements.effectElements[i].propertyGroup, elem));
@@ -14663,7 +12373,6 @@
           effectElements.push(createValueInterface(elements.effectElements[i], data.ef[i].ty, elem, _propertyGroup));
         }
       }
-
       if (data.mn === 'ADBE Color Control') {
         Object.defineProperty(groupInterface, 'color', {
           get: function get() {
@@ -14671,7 +12380,6 @@
           }
         });
       }
-
       Object.defineProperties(groupInterface, {
         numProperties: {
           get: function get() {
@@ -14689,42 +12397,32 @@
       groupInterface.active = groupInterface.enabled;
       return groupInterface;
     }
-
     function createValueInterface(element, type, elem, propertyGroup) {
       var expressionProperty = ExpressionPropertyInterface(element.p);
-
       function interfaceFunction() {
         if (type === 10) {
           return elem.comp.compInterface(element.p.v);
         }
-
         return expressionProperty();
       }
-
       if (element.p.setGroupProperty) {
         element.p.setGroupProperty(PropertyInterface('', propertyGroup));
       }
-
       return interfaceFunction;
     }
-
     return ob;
   }();
 
   var ShapePathInterface = function () {
     return function pathInterfaceFactory(shape, view, propertyGroup) {
       var prop = view.sh;
-
       function interfaceFunction(val) {
         if (val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2) {
           return interfaceFunction.path;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       prop.setGroupProperty(PropertyInterface('Path', _propertyGroup));
       Object.defineProperties(interfaceFunction, {
         path: {
@@ -14732,7 +12430,6 @@
             if (prop.k) {
               prop.getValue();
             }
-
             return prop;
           }
         },
@@ -14741,7 +12438,6 @@
             if (prop.k) {
               prop.getValue();
             }
-
             return prop;
           }
         },
@@ -14770,7 +12466,6 @@
       var arr = [];
       var i;
       var len = shapes ? shapes.length : 0;
-
       for (i = 0; i < len; i += 1) {
         if (shapes[i].ty === 'gr') {
           arr.push(groupInterfaceFactory(shapes[i], view[i], propertyGroup));
@@ -14780,7 +12475,8 @@
           arr.push(strokeInterfaceFactory(shapes[i], view[i], propertyGroup));
         } else if (shapes[i].ty === 'tm') {
           arr.push(trimInterfaceFactory(shapes[i], view[i], propertyGroup));
-        } else if (shapes[i].ty === 'tr') {// arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
+        } else if (shapes[i].ty === 'tr') {
+          // arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
         } else if (shapes[i].ty === 'el') {
           arr.push(ellipseInterfaceFactory(shapes[i], view[i], propertyGroup));
         } else if (shapes[i].ty === 'sr') {
@@ -14799,32 +12495,24 @@
           arr.push(defaultInterfaceFactory(shapes[i], view[i], propertyGroup));
         }
       }
-
       return arr;
     }
-
     function contentsInterfaceFactory(shape, view, propertyGroup) {
       var interfaces;
-
       var interfaceFunction = function _interfaceFunction(value) {
         var i = 0;
         var len = interfaces.length;
-
         while (i < len) {
           if (interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value) {
             return interfaces[i];
           }
-
           i += 1;
         }
-
         if (typeof value === 'number') {
           return interfaces[value - 1];
         }
-
         return null;
       };
-
       interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
       interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup);
       interfaceFunction.numProperties = interfaces.length;
@@ -14834,7 +12522,6 @@
       interfaceFunction._name = shape.nm;
       return interfaceFunction;
     }
-
     function groupInterfaceFactory(shape, view, propertyGroup) {
       var interfaceFunction = function _interfaceFunction(value) {
         switch (value) {
@@ -14845,12 +12532,10 @@
           // Not necessary for now. Keeping them here in case a new case appears
           // case 'ADBE Vector Transform Group':
           // case 3:
-
           default:
             return interfaceFunction.transform;
         }
       };
-
       interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
       var content = contentsInterfaceFactory(shape, view, interfaceFunction.propertyGroup);
       var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
@@ -14860,28 +12545,24 @@
         get: function get() {
           return shape.nm;
         }
-      }); // interfaceFunction.content = interfaceFunction;
-
+      });
+      // interfaceFunction.content = interfaceFunction;
       interfaceFunction.numProperties = shape.np;
       interfaceFunction.propertyIndex = shape.ix;
       interfaceFunction.nm = shape.nm;
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function fillInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(val) {
         if (val === 'Color' || val === 'color') {
           return interfaceFunction.color;
         }
-
         if (val === 'Opacity' || val === 'opacity') {
           return interfaceFunction.opacity;
         }
-
         return null;
       }
-
       Object.defineProperties(interfaceFunction, {
         color: {
           get: ExpressionPropertyInterface(view.c)
@@ -14900,24 +12581,19 @@
       view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
       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)
@@ -14945,51 +12621,39 @@
       view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
       return interfaceFunction;
     }
-
     function defaultInterfaceFactory() {
       function interfaceFunction() {
         return null;
       }
-
       return interfaceFunction;
     }
-
     function strokeInterfaceFactory(shape, view, propertyGroup) {
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup);
-
       function addPropertyToDashOb(i) {
         Object.defineProperty(dashOb, shape.d[i].nm, {
           get: ExpressionPropertyInterface(view.d.dataProps[i].p)
         });
       }
-
       var i;
       var len = shape.d ? shape.d.length : 0;
       var dashOb = {};
-
       for (i = 0; i < len; i += 1) {
         addPropertyToDashOb(i);
         view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup);
       }
-
       function interfaceFunction(val) {
         if (val === 'Color' || val === 'color') {
           return interfaceFunction.color;
         }
-
         if (val === 'Opacity' || val === 'opacity') {
           return interfaceFunction.opacity;
         }
-
         if (val === 'Stroke Width' || val === 'stroke width') {
           return interfaceFunction.strokeWidth;
         }
-
         return null;
       }
-
       Object.defineProperties(interfaceFunction, {
         color: {
           get: ExpressionPropertyInterface(view.c)
@@ -15017,26 +12681,20 @@
       view.w.setGroupProperty(PropertyInterface('Stroke Width', _propertyGroup));
       return interfaceFunction;
     }
-
     function trimInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(val) {
         if (val === shape.e.ix || val === 'End' || val === 'end') {
           return interfaceFunction.end;
         }
-
         if (val === shape.s.ix) {
           return interfaceFunction.start;
         }
-
         if (val === shape.o.ix) {
           return interfaceFunction.offset;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       interfaceFunction.propertyIndex = shape.ix;
       view.s.setGroupProperty(PropertyInterface('Start', _propertyGroup));
       view.e.setGroupProperty(PropertyInterface('End', _propertyGroup));
@@ -15060,53 +12718,41 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function transformInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.a.ix === value || value === 'Anchor Point') {
           return interfaceFunction.anchorPoint;
         }
-
         if (shape.o.ix === value || value === 'Opacity') {
           return interfaceFunction.opacity;
         }
-
         if (shape.p.ix === value || value === 'Position') {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value || value === 'Rotation' || value === 'ADBE Vector Rotation') {
           return interfaceFunction.rotation;
         }
-
         if (shape.s.ix === value || value === 'Scale') {
           return interfaceFunction.scale;
         }
-
         if (shape.sk && shape.sk.ix === value || value === 'Skew') {
           return interfaceFunction.skew;
         }
-
         if (shape.sa && shape.sa.ix === value || value === 'Skew Axis') {
           return interfaceFunction.skewAxis;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
       view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
       view.transform.mProps.a.setGroupProperty(PropertyInterface('Anchor Point', _propertyGroup));
       view.transform.mProps.s.setGroupProperty(PropertyInterface('Scale', _propertyGroup));
       view.transform.mProps.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
-
       if (view.transform.mProps.sk) {
         view.transform.mProps.sk.setGroupProperty(PropertyInterface('Skew', _propertyGroup));
         view.transform.mProps.sa.setGroupProperty(PropertyInterface('Skew Angle', _propertyGroup));
       }
-
       view.transform.op.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
       Object.defineProperties(interfaceFunction, {
         opacity: {
@@ -15139,22 +12785,17 @@
       interfaceFunction.propertyGroup = propertyGroup;
       return interfaceFunction;
     }
-
     function ellipseInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.s.ix === value) {
           return interfaceFunction.size;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       interfaceFunction.propertyIndex = shape.ix;
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
@@ -15173,42 +12814,32 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function starInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value) {
           return interfaceFunction.rotation;
         }
-
         if (shape.pt.ix === value) {
           return interfaceFunction.points;
         }
-
         if (shape.or.ix === value || value === 'ADBE Vector Star Outer Radius') {
           return interfaceFunction.outerRadius;
         }
-
         if (shape.os.ix === value) {
           return interfaceFunction.outerRoundness;
         }
-
         if (shape.ir && (shape.ir.ix === value || value === 'ADBE Vector Star Inner Radius')) {
           return interfaceFunction.innerRadius;
         }
-
         if (shape.is && shape.is.ix === value) {
           return interfaceFunction.innerRoundness;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       interfaceFunction.propertyIndex = shape.ix;
       prop.or.setGroupProperty(PropertyInterface('Outer Radius', _propertyGroup));
@@ -15216,12 +12847,10 @@
       prop.pt.setGroupProperty(PropertyInterface('Points', _propertyGroup));
       prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
       prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
-
       if (shape.ir) {
         prop.ir.setGroupProperty(PropertyInterface('Inner Radius', _propertyGroup));
         prop.is.setGroupProperty(PropertyInterface('Inner Roundness', _propertyGroup));
       }
-
       Object.defineProperties(interfaceFunction, {
         position: {
           get: ExpressionPropertyInterface(prop.p)
@@ -15251,26 +12880,20 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function rectInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value) {
           return interfaceFunction.roundness;
         }
-
         if (shape.s.ix === value || value === 'Size' || value === 'ADBE Vector Rect Size') {
           return interfaceFunction.size;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       interfaceFunction.propertyIndex = shape.ix;
       prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
@@ -15293,18 +12916,14 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function roundedInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.r.ix === value || value === 'Round Corners 1') {
           return interfaceFunction.radius;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view;
       interfaceFunction.propertyIndex = shape.ix;
       prop.rd.setGroupProperty(PropertyInterface('Radius', _propertyGroup));
@@ -15319,22 +12938,17 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function repeaterInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.c.ix === value || value === 'Copies') {
           return interfaceFunction.copies;
         }
-
         if (shape.o.ix === value || value === 'Offset') {
           return interfaceFunction.offset;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view;
       interfaceFunction.propertyIndex = shape.ix;
       prop.c.setGroupProperty(PropertyInterface('Copies', _propertyGroup));
@@ -15353,39 +12967,29 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     return function (shapes, view, propertyGroup) {
       var interfaces;
-
       function _interfaceFunction(value) {
         if (typeof value === 'number') {
           value = value === undefined ? 1 : value;
-
           if (value === 0) {
             return propertyGroup;
           }
-
           return interfaces[value - 1];
         }
-
         var i = 0;
         var len = interfaces.length;
-
         while (i < len) {
           if (interfaces[i]._name === value) {
             return interfaces[i];
           }
-
           i += 1;
         }
-
         return null;
       }
-
       function parentGroupWrapper() {
         return propertyGroup;
       }
-
       _interfaceFunction.propertyGroup = propertyGroupFactory(_interfaceFunction, parentGroupWrapper);
       interfaces = iterateElements(shapes, view, _interfaceFunction.propertyGroup);
       _interfaceFunction.numProperties = interfaces.length;
@@ -15397,28 +13001,22 @@
   var TextExpressionInterface = function () {
     return function (elem) {
       var _sourceText;
-
       function _thisLayerFunction(name) {
         switch (name) {
           case 'ADBE Text Document':
             return _thisLayerFunction.sourceText;
-
           default:
             return null;
         }
       }
-
       Object.defineProperty(_thisLayerFunction, 'sourceText', {
         get: function get() {
           elem.textProperty.getValue();
           var stringValue = elem.textProperty.currentData.t;
-
           if (!_sourceText || stringValue !== _sourceText.value) {
             _sourceText = new String(stringValue); // eslint-disable-line no-new-wrappers
             // If stringValue is an empty string, eval returns undefined, so it has to be returned as a String primitive
-
             _sourceText.value = stringValue || new String(stringValue); // eslint-disable-line no-new-wrappers
-
             Object.defineProperty(_sourceText, 'style', {
               get: function get() {
                 return {
@@ -15427,7 +13025,6 @@
               }
             });
           }
-
           return _sourceText;
         }
       });
@@ -15435,73 +13032,56 @@
     };
   }();
 
-  function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
-
+  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
   var FootageInterface = function () {
     var outlineInterfaceFactory = function outlineInterfaceFactory(elem) {
       var currentPropertyName = '';
       var currentProperty = elem.getFootageData();
-
       function init() {
         currentPropertyName = '';
         currentProperty = elem.getFootageData();
         return searchProperty;
       }
-
       function searchProperty(value) {
         if (currentProperty[value]) {
           currentPropertyName = value;
           currentProperty = currentProperty[value];
-
           if (_typeof(currentProperty) === 'object') {
             return searchProperty;
           }
-
           return currentProperty;
         }
-
         var propertyNameIndex = value.indexOf(currentPropertyName);
-
         if (propertyNameIndex !== -1) {
           var index = parseInt(value.substr(propertyNameIndex + currentPropertyName.length), 10);
           currentProperty = currentProperty[index];
-
           if (_typeof(currentProperty) === 'object') {
             return searchProperty;
           }
-
           return currentProperty;
         }
-
         return '';
       }
-
       return init;
     };
-
     var dataInterfaceFactory = function dataInterfaceFactory(elem) {
       function interfaceFunction(value) {
         if (value === 'Outline') {
           return interfaceFunction.outlineInterface();
         }
-
         return null;
       }
-
       interfaceFunction._name = 'Outline';
       interfaceFunction.outlineInterface = outlineInterfaceFactory(elem);
       return interfaceFunction;
     };
-
     return function (elem) {
       function _interfaceFunction(value) {
         if (value === 'Data') {
           return _interfaceFunction.dataInterface;
         }
-
         return null;
       }
-
       _interfaceFunction._name = 'Data';
       _interfaceFunction.dataInterface = dataInterfaceFactory(elem);
       return _interfaceFunction;
@@ -15516,7 +13096,6 @@
     text: TextExpressionInterface,
     footage: FootageInterface
   };
-
   function getInterface(type) {
     return interfaces[type] || null;
   }
@@ -15530,56 +13109,44 @@
         prop.effectsSequence.push(prop.initiateExpression(elem, data, prop).bind(prop));
       }
     }
-
     function getValueAtTime(frameNum) {
       frameNum *= this.elem.globalData.frameRate;
       frameNum -= this.offsetTime;
-
       if (frameNum !== this._cachingAtTime.lastFrame) {
         this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0;
         this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime);
         this._cachingAtTime.lastFrame = frameNum;
       }
-
       return this._cachingAtTime.value;
     }
-
     function getSpeedAtTime(frameNum) {
       var delta = -0.01;
       var v1 = this.getValueAtTime(frameNum);
       var v2 = this.getValueAtTime(frameNum + delta);
       var speed = 0;
-
       if (v1.length) {
         var i;
-
         for (i = 0; i < v1.length; i += 1) {
           speed += Math.pow(v2[i] - v1[i], 2);
         }
-
         speed = Math.sqrt(speed) * 100;
       } else {
         speed = 0;
       }
-
       return speed;
     }
-
     function getVelocityAtTime(frameNum) {
       if (this.vel !== undefined) {
         return this.vel;
       }
-
-      var delta = -0.001; // frameNum += this.elem.data.st;
-
+      var delta = -0.001;
+      // frameNum += this.elem.data.st;
       var v1 = this.getValueAtTime(frameNum);
       var v2 = this.getValueAtTime(frameNum + delta);
       var velocity;
-
       if (v1.length) {
         velocity = createTypedArray('float32', v1.length);
         var i;
-
         for (i = 0; i < v1.length; i += 1) {
           // removing frameRate
           // if needed, don't add it here
@@ -15589,18 +13156,14 @@
       } else {
         velocity = (v2 - v1) / delta;
       }
-
       return velocity;
     }
-
     function getStaticValueAtTime() {
       return this.pv;
     }
-
     function setGroupProperty(propertyGroup) {
       this.propertyGroup = propertyGroup;
     }
-
     return {
       searchExpressions: searchExpressions,
       getSpeedAtTime: getSpeedAtTime,
@@ -15616,24 +13179,19 @@
       if (!this.k || !this.keyframes) {
         return this.pv;
       }
-
       type = type ? type.toLowerCase() : '';
       var currentFrame = this.comp.renderedFrame;
       var keyframes = this.keyframes;
       var lastKeyFrame = keyframes[keyframes.length - 1].t;
-
       if (currentFrame <= lastKeyFrame) {
         return this.pv;
       }
-
       var cycleDuration;
       var firstKeyFrame;
-
       if (!durationFlag) {
         if (!duration || duration > keyframes.length - 1) {
           duration = keyframes.length - 1;
         }
-
         firstKeyFrame = keyframes[keyframes.length - 1 - duration].t;
         cycleDuration = lastKeyFrame - firstKeyFrame;
       } else {
@@ -15642,17 +13200,13 @@
         } else {
           cycleDuration = Math.abs(lastKeyFrame - this.elem.comp.globalData.frameRate * duration);
         }
-
         firstKeyFrame = lastKeyFrame - cycleDuration;
       }
-
       var i;
       var len;
       var ret;
-
       if (type === 'pingpong') {
         var iterations = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
-
         if (iterations % 2 !== 0) {
           return this.getValueAtTime((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
         }
@@ -15660,64 +13214,48 @@
         var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
         var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
-
         var repeats = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
-
         if (this.pv.length) {
           ret = new Array(initV.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = (endV[i] - initV[i]) * repeats + current[i];
           }
-
           return ret;
         }
-
         return (endV - initV) * repeats + current;
       } else if (type === 'continue') {
         var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0);
-
         if (this.pv.length) {
           ret = new Array(lastValue.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = lastValue[i] + (lastValue[i] - nextLastValue[i]) * ((currentFrame - lastKeyFrame) / this.comp.globalData.frameRate) / 0.0005; // eslint-disable-line
           }
-
           return ret;
         }
-
         return lastValue + (lastValue - nextLastValue) * ((currentFrame - lastKeyFrame) / 0.001);
       }
-
       return this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
     }
-
     function loopIn(type, duration, durationFlag) {
       if (!this.k) {
         return this.pv;
       }
-
       type = type ? type.toLowerCase() : '';
       var currentFrame = this.comp.renderedFrame;
       var keyframes = this.keyframes;
       var firstKeyFrame = keyframes[0].t;
-
       if (currentFrame >= firstKeyFrame) {
         return this.pv;
       }
-
       var cycleDuration;
       var lastKeyFrame;
-
       if (!durationFlag) {
         if (!duration || duration > keyframes.length - 1) {
           duration = keyframes.length - 1;
         }
-
         lastKeyFrame = keyframes[duration].t;
         cycleDuration = lastKeyFrame - firstKeyFrame;
       } else {
@@ -15726,17 +13264,13 @@
         } else {
           cycleDuration = Math.abs(this.elem.comp.globalData.frameRate * duration);
         }
-
         lastKeyFrame = firstKeyFrame + cycleDuration;
       }
-
       var i;
       var len;
       var ret;
-
       if (type === 'pingpong') {
         var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration);
-
         if (iterations % 2 === 0) {
           return this.getValueAtTime(((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
         }
@@ -15745,52 +13279,39 @@
         var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var current = this.getValueAtTime((cycleDuration - (firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0);
         var repeats = Math.floor((firstKeyFrame - currentFrame) / cycleDuration) + 1;
-
         if (this.pv.length) {
           ret = new Array(initV.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = current[i] - (endV[i] - initV[i]) * repeats;
           }
-
           return ret;
         }
-
         return current - (endV - initV) * repeats;
       } else if (type === 'continue') {
         var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
         var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0);
-
         if (this.pv.length) {
           ret = new Array(firstValue.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = firstValue[i] + (firstValue[i] - nextFirstValue[i]) * (firstKeyFrame - currentFrame) / 0.001;
           }
-
           return ret;
         }
-
         return firstValue + (firstValue - nextFirstValue) * (firstKeyFrame - currentFrame) / 0.001;
       }
-
       return this.getValueAtTime((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
     }
-
     function smooth(width, samples) {
       if (!this.k) {
         return this.pv;
       }
-
       width = (width || 0.4) * 0.5;
       samples = Math.floor(samples || 5);
-
       if (samples <= 1) {
         return this.pv;
       }
-
       var currentTime = this.comp.renderedFrame / this.comp.globalData.frameRate;
       var initFrame = currentTime - width;
       var endFrame = currentTime + width;
@@ -15798,18 +13319,14 @@
       var i = 0;
       var j = 0;
       var value;
-
       if (this.pv.length) {
         value = createTypedArray('float32', this.pv.length);
       } else {
         value = 0;
       }
-
       var sampleValue;
-
       while (i < samples) {
         sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency);
-
         if (this.pv.length) {
           for (j = 0; j < this.pv.length; j += 1) {
             value[j] += sampleValue[j];
@@ -15817,10 +13334,8 @@
         } else {
           value += sampleValue;
         }
-
         i += 1;
       }
-
       if (this.pv.length) {
         for (j = 0; j < this.pv.length; j += 1) {
           value[j] /= samples;
@@ -15828,37 +13343,30 @@
       } else {
         value /= samples;
       }
-
       return value;
     }
-
     function getTransformValueAtTime(time) {
       if (!this._transformCachingAtTime) {
         this._transformCachingAtTime = {
           v: new Matrix()
         };
-      } /// /
-
-
+      }
+      /// /
       var matrix = this._transformCachingAtTime.v;
       matrix.cloneFromProps(this.pre.props);
-
       if (this.appliedTransformations < 1) {
         var anchor = this.a.getValueAtTime(time);
         matrix.translate(-anchor[0] * this.a.mult, -anchor[1] * this.a.mult, anchor[2] * this.a.mult);
       }
-
       if (this.appliedTransformations < 2) {
         var scale = this.s.getValueAtTime(time);
         matrix.scale(scale[0] * this.s.mult, scale[1] * this.s.mult, scale[2] * this.s.mult);
       }
-
       if (this.sk && this.appliedTransformations < 3) {
         var skew = this.sk.getValueAtTime(time);
         var skewAxis = this.sa.getValueAtTime(time);
         matrix.skewFromAxis(-skew * this.sk.mult, skewAxis * this.sa.mult);
       }
-
       if (this.r && this.appliedTransformations < 4) {
         var rotation = this.r.getValueAtTime(time);
         matrix.rotate(-rotation * this.r.mult);
@@ -15869,11 +13377,9 @@
         var orientation = this.or.getValueAtTime(time);
         matrix.rotateZ(-rotationZ * this.rz.mult).rotateY(rotationY * this.ry.mult).rotateX(rotationX * this.rx.mult).rotateZ(-orientation[2] * this.or.mult).rotateY(orientation[1] * this.or.mult).rotateX(orientation[0] * this.or.mult);
       }
-
       if (this.data.p && this.data.p.s) {
         var positionX = this.px.getValueAtTime(time);
         var positionY = this.py.getValueAtTime(time);
-
         if (this.data.p.z) {
           var positionZ = this.pz.getValueAtTime(time);
           matrix.translate(positionX * this.px.mult, positionY * this.py.mult, -positionZ * this.pz.mult);
@@ -15884,42 +13390,34 @@
         var position = this.p.getValueAtTime(time);
         matrix.translate(position[0] * this.p.mult, position[1] * this.p.mult, -position[2] * this.p.mult);
       }
-
-      return matrix; /// /
+      return matrix;
+      /// /
     }
-
     function getTransformStaticValueAtTime() {
       return this.v.clone(new Matrix());
     }
-
     var getTransformProperty = TransformPropertyFactory.getTransformProperty;
-
     TransformPropertyFactory.getTransformProperty = function (elem, data, container) {
       var prop = getTransformProperty(elem, data, container);
-
       if (prop.dynamicProperties.length) {
         prop.getValueAtTime = getTransformValueAtTime.bind(prop);
       } else {
         prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop);
       }
-
       prop.setGroupProperty = expressionHelpers.setGroupProperty;
       return prop;
     };
-
     var propertyGetProp = PropertyFactory.getProp;
-
     PropertyFactory.getProp = function (elem, data, type, mult, container) {
-      var prop = propertyGetProp(elem, data, type, mult, container); // prop.getVelocityAtTime = getVelocityAtTime;
+      var prop = propertyGetProp(elem, data, type, mult, container);
+      // prop.getVelocityAtTime = getVelocityAtTime;
       // prop.loopOut = loopOut;
       // prop.loopIn = loopIn;
-
       if (prop.kf) {
         prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop);
       } else {
         prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop);
       }
-
       prop.setGroupProperty = expressionHelpers.setGroupProperty;
       prop.loopOut = loopOut;
       prop.loopIn = loopIn;
@@ -15929,25 +13427,20 @@
       prop.numKeys = data.a === 1 ? data.k.length : 0;
       prop.propertyIndex = data.ix;
       var value = 0;
-
       if (type !== 0) {
         value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length);
       }
-
       prop._cachingAtTime = {
         lastFrame: initialDefaultFrame,
         lastIndex: 0,
         value: value
       };
       expressionHelpers.searchExpressions(elem, data, prop);
-
       if (prop.k) {
         container.addDynamicProperty(prop);
       }
-
       return prop;
     };
-
     function getShapeValueAtTime(frameNum) {
       // For now this caching object is created only when needed instead of creating it when the shape is initialized.
       if (!this._cachingAtTime) {
@@ -15957,42 +13450,32 @@
           lastTime: initialDefaultFrame
         };
       }
-
       frameNum *= this.elem.globalData.frameRate;
       frameNum -= this.offsetTime;
-
       if (frameNum !== this._cachingAtTime.lastTime) {
         this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0;
         this._cachingAtTime.lastTime = frameNum;
         this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime);
       }
-
       return this._cachingAtTime.shapeValue;
     }
-
     var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction();
     var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction();
-
     function ShapeExpressions() {}
-
     ShapeExpressions.prototype = {
       vertices: function vertices(prop, time) {
         if (this.k) {
           this.getValue();
         }
-
         var shapePath = this.v;
-
         if (time !== undefined) {
           shapePath = this.getValueAtTime(time, 0);
         }
-
         var i;
         var len = shapePath._length;
         var vertices = shapePath[prop];
         var points = shapePath.v;
         var arr = createSizedArray(len);
-
         for (i = 0; i < len; i += 1) {
           if (prop === 'i' || prop === 'o') {
             arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]];
@@ -16000,7 +13483,6 @@
             arr[i] = [vertices[i][0], vertices[i][1]];
           }
         }
-
         return arr;
       },
       points: function points(time) {
@@ -16017,15 +13499,12 @@
       },
       pointOnPath: function pointOnPath(perc, time) {
         var shapePath = this.v;
-
         if (time !== undefined) {
           shapePath = this.getValueAtTime(time, 0);
         }
-
         if (!this._segmentsLength) {
           this._segmentsLength = bez.getSegmentsLength(shapePath);
         }
-
         var segmentsLength = this._segmentsLength;
         var lengths = segmentsLength.lengths;
         var lengthPos = segmentsLength.totalLength * perc;
@@ -16033,7 +13512,6 @@
         var len = lengths.length;
         var accumulatedLength = 0;
         var pt;
-
         while (i < len) {
           if (accumulatedLength + lengths[i].addedLength > lengthPos) {
             var initIndex = i;
@@ -16044,14 +13522,11 @@
           } else {
             accumulatedLength += lengths[i].addedLength;
           }
-
           i += 1;
         }
-
         if (!pt) {
           pt = shapePath.c ? [shapePath.v[0][0], shapePath.v[0][1]] : [shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1]];
         }
-
         return pt;
       },
       vectorOnPath: function vectorOnPath(perc, time, vectorType) {
@@ -16063,17 +13538,14 @@
           // eslint-disable-line eqeqeq
           perc = 0.999;
         }
-
         var pt1 = this.pointOnPath(perc, time);
         var pt2 = this.pointOnPath(perc + 0.001, time);
         var xLength = pt2[0] - pt1[0];
         var yLength = pt2[1] - pt1[1];
         var magnitude = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2));
-
         if (magnitude === 0) {
           return [0, 0];
         }
-
         var unitVector = vectorType === 'tangent' ? [xLength / magnitude, yLength / magnitude] : [-yLength / magnitude, xLength / magnitude];
         return unitVector;
       },
@@ -16091,26 +13563,21 @@
     KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime;
     KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression;
     var propertyGetShapeProp = ShapePropertyFactory.getShapeProp;
-
     ShapePropertyFactory.getShapeProp = function (elem, data, type, arr, trims) {
       var prop = propertyGetShapeProp(elem, data, type, arr, trims);
       prop.propertyIndex = data.ix;
       prop.lock = false;
-
       if (type === 3) {
         expressionHelpers.searchExpressions(elem, data.pt, prop);
       } else if (type === 4) {
         expressionHelpers.searchExpressions(elem, data.ks, prop);
       }
-
       if (prop.k) {
         elem.addDynamicProperty(prop);
       }
-
       return prop;
     };
   }
-
   function initialize$1() {
     addPropertyDecorator();
   }
@@ -16122,13 +13589,10 @@
         this.addEffect(this.getExpressionValue.bind(this));
         return true;
       }
-
       return null;
     }
-
     TextProperty.prototype.getExpressionValue = function (currentValue, text) {
       var newValue = this.calculateExpression(text);
-
       if (currentValue.t !== newValue) {
         var newData = {};
         this.copyData(newData, currentValue);
@@ -16136,46 +13600,38 @@
         newData.__complete = false;
         return newData;
       }
-
       return currentValue;
     };
-
     TextProperty.prototype.searchProperty = function () {
       var isKeyframed = this.searchKeyframes();
       var hasExpressions = this.searchExpressions();
       this.kf = isKeyframed || hasExpressions;
       return this.kf;
     };
-
     TextProperty.prototype.searchExpressions = searchExpressions;
   }
-
   function initialize() {
     addDecorator();
   }
 
   function SVGComposableEffect() {}
-
   SVGComposableEffect.prototype = {
     createMergeNode: function createMergeNode(resultId, ins) {
       var feMerge = createNS('feMerge');
       feMerge.setAttribute('result', resultId);
       var feMergeNode;
       var i;
-
       for (i = 0; i < ins.length; i += 1) {
         feMergeNode = createNS('feMergeNode');
         feMergeNode.setAttribute('in', ins[i]);
         feMerge.appendChild(feMergeNode);
         feMerge.appendChild(feMergeNode);
       }
-
       return feMerge;
     }
   };
 
   var linearFilterValue = '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0';
-
   function SVGTintFilter(filter, filterManager, elem, id, source) {
     this.filterManager = filterManager;
     var feColorMatrix = createNS('feColorMatrix');
@@ -16195,9 +13651,7 @@
     var feMerge = this.createMergeNode(id, [source, id + '_tint_1', id + '_tint_2']);
     filter.appendChild(feMerge);
   }
-
   extendPrototype([SVGComposableEffect], SVGTintFilter);
-
   SVGTintFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var colorBlack = this.filterManager.effectElements[0].p.v;
@@ -16218,7 +13672,6 @@
     filter.appendChild(feColorMatrix);
     this.matrixFilter = feColorMatrix;
   }
-
   SVGFillFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var color = this.filterManager.effectElements[2].p.v;
@@ -16233,14 +13686,12 @@
     this.elem = elem;
     this.paths = [];
   }
-
   SVGStrokeEffect.prototype.initialize = function () {
     var elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
     var path;
     var groupPath;
     var i;
     var len;
-
     if (this.filterManager.effectElements[1].p.v === 1) {
       len = this.elem.maskManager.masksProperties.length;
       i = 0;
@@ -16248,12 +13699,10 @@
       i = this.filterManager.effectElements[0].p.v - 1;
       len = i + 1;
     }
-
     groupPath = createNS('g');
     groupPath.setAttribute('fill', 'none');
     groupPath.setAttribute('stroke-linecap', 'round');
     groupPath.setAttribute('stroke-dashoffset', 1);
-
     for (i; i < len; i += 1) {
       path = createNS('path');
       groupPath.appendChild(path);
@@ -16262,7 +13711,6 @@
         m: i
       });
     }
-
     if (this.filterManager.effectElements[10].p.v === 3) {
       var mask = createNS('mask');
       var id = createElementID();
@@ -16272,54 +13720,43 @@
       this.elem.globalData.defs.appendChild(mask);
       var g = createNS('g');
       g.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
-
       while (elemChildren[0]) {
         g.appendChild(elemChildren[0]);
       }
-
       this.elem.layerElement.appendChild(g);
       this.masker = mask;
       groupPath.setAttribute('stroke', '#fff');
     } else if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
       if (this.filterManager.effectElements[10].p.v === 2) {
         elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
-
         while (elemChildren.length) {
           this.elem.layerElement.removeChild(elemChildren[0]);
         }
       }
-
       this.elem.layerElement.appendChild(groupPath);
       this.elem.layerElement.removeAttribute('mask');
       groupPath.setAttribute('stroke', '#fff');
     }
-
     this.initialized = true;
     this.pathMasker = groupPath;
   };
-
   SVGStrokeEffect.prototype.renderFrame = function (forceRender) {
     if (!this.initialized) {
       this.initialize();
     }
-
     var i;
     var len = this.paths.length;
     var mask;
     var path;
-
     for (i = 0; i < len; i += 1) {
       if (this.paths[i].m !== -1) {
         mask = this.elem.maskManager.viewData[this.paths[i].m];
         path = this.paths[i].p;
-
         if (forceRender || this.filterManager._mdf || mask.prop._mdf) {
           path.setAttribute('d', mask.lastPath);
         }
-
         if (forceRender || this.filterManager.effectElements[9].p._mdf || this.filterManager.effectElements[4].p._mdf || this.filterManager.effectElements[7].p._mdf || this.filterManager.effectElements[8].p._mdf || mask.prop._mdf) {
           var dasharrayValue;
-
           if (this.filterManager.effectElements[7].p.v !== 0 || this.filterManager.effectElements[8].p.v !== 100) {
             var s = Math.min(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
             var e = Math.max(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
@@ -16329,29 +13766,23 @@
             var segment = 1 + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
             var units = Math.floor(lineLength / segment);
             var j;
-
             for (j = 0; j < units; j += 1) {
               dasharrayValue += '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01 + ' ';
             }
-
             dasharrayValue += '0 ' + l * 10 + ' 0 0';
           } else {
             dasharrayValue = '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
           }
-
           path.setAttribute('stroke-dasharray', dasharrayValue);
         }
       }
     }
-
     if (forceRender || this.filterManager.effectElements[4].p._mdf) {
       this.pathMasker.setAttribute('stroke-width', this.filterManager.effectElements[4].p.v * 2);
     }
-
     if (forceRender || this.filterManager.effectElements[6].p._mdf) {
       this.pathMasker.setAttribute('opacity', this.filterManager.effectElements[6].p.v);
     }
-
     if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
       if (forceRender || this.filterManager.effectElements[3].p._mdf) {
         var color = this.filterManager.effectElements[3].p.v;
@@ -16385,7 +13816,6 @@
     this.feFuncB = feFuncB;
     filter.appendChild(feComponentTransfer);
   }
-
   SVGTritoneFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var color1 = this.filterManager.effectElements[0].p.v;
@@ -16403,33 +13833,29 @@
   function SVGProLevelsFilter(filter, filterManager, elem, id) {
     this.filterManager = filterManager;
     var effectElements = this.filterManager.effectElements;
-    var feComponentTransfer = createNS('feComponentTransfer'); // Red
+    var feComponentTransfer = createNS('feComponentTransfer');
 
+    // Red
     if (effectElements[10].p.k || effectElements[10].p.v !== 0 || effectElements[11].p.k || effectElements[11].p.v !== 1 || effectElements[12].p.k || effectElements[12].p.v !== 1 || effectElements[13].p.k || effectElements[13].p.v !== 0 || effectElements[14].p.k || effectElements[14].p.v !== 1) {
       this.feFuncR = this.createFeFunc('feFuncR', feComponentTransfer);
-    } // Green
-
-
+    }
+    // Green
     if (effectElements[17].p.k || effectElements[17].p.v !== 0 || effectElements[18].p.k || effectElements[18].p.v !== 1 || effectElements[19].p.k || effectElements[19].p.v !== 1 || effectElements[20].p.k || effectElements[20].p.v !== 0 || effectElements[21].p.k || effectElements[21].p.v !== 1) {
       this.feFuncG = this.createFeFunc('feFuncG', feComponentTransfer);
-    } // Blue
-
-
+    }
+    // Blue
     if (effectElements[24].p.k || effectElements[24].p.v !== 0 || effectElements[25].p.k || effectElements[25].p.v !== 1 || effectElements[26].p.k || effectElements[26].p.v !== 1 || effectElements[27].p.k || effectElements[27].p.v !== 0 || effectElements[28].p.k || effectElements[28].p.v !== 1) {
       this.feFuncB = this.createFeFunc('feFuncB', feComponentTransfer);
-    } // Alpha
-
-
+    }
+    // Alpha
     if (effectElements[31].p.k || effectElements[31].p.v !== 0 || effectElements[32].p.k || effectElements[32].p.v !== 1 || effectElements[33].p.k || effectElements[33].p.v !== 1 || effectElements[34].p.k || effectElements[34].p.v !== 0 || effectElements[35].p.k || effectElements[35].p.v !== 1) {
       this.feFuncA = this.createFeFunc('feFuncA', feComponentTransfer);
-    } // RGB
-
-
+    }
+    // RGB
     if (this.feFuncR || this.feFuncG || this.feFuncB || this.feFuncA) {
       feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
       filter.appendChild(feComponentTransfer);
     }
-
     if (effectElements[3].p.k || effectElements[3].p.v !== 0 || effectElements[4].p.k || effectElements[4].p.v !== 1 || effectElements[5].p.k || effectElements[5].p.v !== 1 || effectElements[6].p.k || effectElements[6].p.v !== 0 || effectElements[7].p.k || effectElements[7].p.v !== 1) {
       feComponentTransfer = createNS('feComponentTransfer');
       feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
@@ -16440,14 +13866,12 @@
       this.feFuncBComposed = this.createFeFunc('feFuncB', feComponentTransfer);
     }
   }
-
   SVGProLevelsFilter.prototype.createFeFunc = function (type, feComponentTransfer) {
     var feFunc = createNS(type);
     feFunc.setAttribute('type', 'table');
     feComponentTransfer.appendChild(feFunc);
     return feFunc;
   };
-
   SVGProLevelsFilter.prototype.getTableValue = function (inputBlack, inputWhite, gamma, outputBlack, outputWhite) {
     var cnt = 0;
     var segments = 256;
@@ -16461,10 +13885,8 @@
     var pos = 0;
     var outputDelta = outputWhite - outputBlack;
     var inputDelta = inputWhite - inputBlack;
-
     while (cnt <= 256) {
       perc = cnt / 256;
-
       if (perc <= min) {
         colorValue = inputDelta < 0 ? outputWhite : outputBlack;
       } else if (perc >= max) {
@@ -16472,42 +13894,34 @@
       } else {
         colorValue = outputBlack + outputDelta * Math.pow((perc - inputBlack) / inputDelta, 1 / gamma);
       }
-
       table[pos] = colorValue;
       pos += 1;
       cnt += 256 / (segments - 1);
     }
-
     return table.join(' ');
   };
-
   SVGProLevelsFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var val;
       var effectElements = this.filterManager.effectElements;
-
       if (this.feFuncRComposed && (forceRender || effectElements[3].p._mdf || effectElements[4].p._mdf || effectElements[5].p._mdf || effectElements[6].p._mdf || effectElements[7].p._mdf)) {
         val = this.getTableValue(effectElements[3].p.v, effectElements[4].p.v, effectElements[5].p.v, effectElements[6].p.v, effectElements[7].p.v);
         this.feFuncRComposed.setAttribute('tableValues', val);
         this.feFuncGComposed.setAttribute('tableValues', val);
         this.feFuncBComposed.setAttribute('tableValues', val);
       }
-
       if (this.feFuncR && (forceRender || effectElements[10].p._mdf || effectElements[11].p._mdf || effectElements[12].p._mdf || effectElements[13].p._mdf || effectElements[14].p._mdf)) {
         val = this.getTableValue(effectElements[10].p.v, effectElements[11].p.v, effectElements[12].p.v, effectElements[13].p.v, effectElements[14].p.v);
         this.feFuncR.setAttribute('tableValues', val);
       }
-
       if (this.feFuncG && (forceRender || effectElements[17].p._mdf || effectElements[18].p._mdf || effectElements[19].p._mdf || effectElements[20].p._mdf || effectElements[21].p._mdf)) {
         val = this.getTableValue(effectElements[17].p.v, effectElements[18].p.v, effectElements[19].p.v, effectElements[20].p.v, effectElements[21].p.v);
         this.feFuncG.setAttribute('tableValues', val);
       }
-
       if (this.feFuncB && (forceRender || effectElements[24].p._mdf || effectElements[25].p._mdf || effectElements[26].p._mdf || effectElements[27].p._mdf || effectElements[28].p._mdf)) {
         val = this.getTableValue(effectElements[24].p.v, effectElements[25].p.v, effectElements[26].p.v, effectElements[27].p.v, effectElements[28].p.v);
         this.feFuncB.setAttribute('tableValues', val);
       }
-
       if (this.feFuncA && (forceRender || effectElements[31].p._mdf || effectElements[32].p._mdf || effectElements[33].p._mdf || effectElements[34].p._mdf || effectElements[35].p._mdf)) {
         val = this.getTableValue(effectElements[31].p.v, effectElements[32].p.v, effectElements[33].p.v, effectElements[34].p.v, effectElements[35].p.v);
         this.feFuncA.setAttribute('tableValues', val);
@@ -16549,26 +13963,22 @@
     feComposite.setAttribute('result', id + '_drop_shadow_4');
     filter.appendChild(feComposite);
     var feMerge = this.createMergeNode(id, [id + '_drop_shadow_4', source]);
-    filter.appendChild(feMerge); //
+    filter.appendChild(feMerge);
+    //
   }
-
   extendPrototype([SVGComposableEffect], SVGDropShadowEffect);
-
   SVGDropShadowEffect.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       if (forceRender || this.filterManager.effectElements[4].p._mdf) {
         this.feGaussianBlur.setAttribute('stdDeviation', this.filterManager.effectElements[4].p.v / 4);
       }
-
       if (forceRender || this.filterManager.effectElements[0].p._mdf) {
         var col = this.filterManager.effectElements[0].p.v;
         this.feFlood.setAttribute('flood-color', rgbToHex(Math.round(col[0] * 255), Math.round(col[1] * 255), Math.round(col[2] * 255)));
       }
-
       if (forceRender || this.filterManager.effectElements[1].p._mdf) {
         this.feFlood.setAttribute('flood-opacity', this.filterManager.effectElements[1].p.v / 255);
       }
-
       if (forceRender || this.filterManager.effectElements[2].p._mdf || this.filterManager.effectElements[3].p._mdf) {
         var distance = this.filterManager.effectElements[3].p.v;
         var angle = (this.filterManager.effectElements[2].p.v - 90) * degToRads;
@@ -16581,7 +13991,6 @@
   };
 
   var _svgMatteSymbols = [];
-
   function SVGMatte3Effect(filterElem, filterManager, elem) {
     this.initialized = false;
     this.filterManager = filterManager;
@@ -16592,66 +14001,50 @@
     elem.matteElement.appendChild(elem.transformedElement);
     elem.baseElement = elem.matteElement;
   }
-
   SVGMatte3Effect.prototype.findSymbol = function (mask) {
     var i = 0;
     var len = _svgMatteSymbols.length;
-
     while (i < len) {
       if (_svgMatteSymbols[i] === mask) {
         return _svgMatteSymbols[i];
       }
-
       i += 1;
     }
-
     return null;
   };
-
   SVGMatte3Effect.prototype.replaceInParent = function (mask, symbolId) {
     var parentNode = mask.layerElement.parentNode;
-
     if (!parentNode) {
       return;
     }
-
     var children = parentNode.children;
     var i = 0;
     var len = children.length;
-
     while (i < len) {
       if (children[i] === mask.layerElement) {
         break;
       }
-
       i += 1;
     }
-
     var nextChild;
-
     if (i <= len - 2) {
       nextChild = children[i + 1];
     }
-
     var useElem = createNS('use');
     useElem.setAttribute('href', '#' + symbolId);
-
     if (nextChild) {
       parentNode.insertBefore(useElem, nextChild);
     } else {
       parentNode.appendChild(useElem);
     }
   };
-
   SVGMatte3Effect.prototype.setElementAsMask = function (elem, mask) {
     if (!this.findSymbol(mask)) {
       var symbolId = createElementID();
       var masker = createNS('mask');
       masker.setAttribute('id', mask.layerId);
       masker.setAttribute('mask-type', 'alpha');
-
       _svgMatteSymbols.push(mask);
-
       var defs = elem.globalData.defs;
       defs.appendChild(masker);
       var symbol = createNS('symbol');
@@ -16665,27 +14058,21 @@
       mask.data.hd = false;
       mask.show();
     }
-
     elem.setMatte(mask.layerId);
   };
-
   SVGMatte3Effect.prototype.initialize = function () {
     var ind = this.filterManager.effectElements[0].p.v;
     var elements = this.elem.comp.elements;
     var i = 0;
     var len = elements.length;
-
     while (i < len) {
       if (elements[i] && elements[i].data.ind === ind) {
         this.setElementAsMask(this.elem, elements[i]);
       }
-
       i += 1;
     }
-
     this.initialized = true;
   };
-
   SVGMatte3Effect.prototype.renderFrame = function () {
     if (!this.initialized) {
       this.initialize();
@@ -16704,36 +14091,34 @@
     filter.appendChild(feGaussianBlur);
     this.feGaussianBlur = feGaussianBlur;
   }
-
   SVGGaussianBlurEffect.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       // Empirical value, matching AE's blur appearance.
       var kBlurrinessToSigma = 0.3;
-      var sigma = this.filterManager.effectElements[0].p.v * kBlurrinessToSigma; // Dimensions mapping:
+      var sigma = this.filterManager.effectElements[0].p.v * kBlurrinessToSigma;
+
+      // Dimensions mapping:
       //
       //   1 -> horizontal & vertical
       //   2 -> horizontal only
       //   3 -> vertical only
       //
-
       var dimensions = this.filterManager.effectElements[1].p.v;
       var sigmaX = dimensions == 3 ? 0 : sigma; // eslint-disable-line eqeqeq
-
       var sigmaY = dimensions == 2 ? 0 : sigma; // eslint-disable-line eqeqeq
 
-      this.feGaussianBlur.setAttribute('stdDeviation', sigmaX + ' ' + sigmaY); // Repeat edges mapping:
+      this.feGaussianBlur.setAttribute('stdDeviation', sigmaX + ' ' + sigmaY);
+
+      // Repeat edges mapping:
       //
       //   0 -> off -> duplicate
       //   1 -> on  -> wrap
-
       var edgeMode = this.filterManager.effectElements[2].p.v == 1 ? 'wrap' : 'duplicate'; // eslint-disable-line eqeqeq
-
       this.feGaussianBlur.setAttribute('edgeMode', edgeMode);
     }
   };
 
   function TransformEffect() {}
-
   TransformEffect.prototype.init = function (effectsManager) {
     this.effectsManager = effectsManager;
     this.type = effectTypes.TRANSFORM_EFFECT;
@@ -16742,11 +14127,9 @@
     this._mdf = false;
     this._opMdf = false;
   };
-
   TransformEffect.prototype.renderFrame = function (forceFrame) {
     this._opMdf = false;
     this._mdf = false;
-
     if (forceFrame || this.effectsManager._mdf) {
       var effectElements = this.effectsManager.effectElements;
       var anchor = effectElements[0].p.v;
@@ -16764,7 +14147,6 @@
       this.matrix.skewFromAxis(-skew * degToRads, (skewAxis + 90) * degToRads);
       this.matrix.translate(position[0], position[1], 0);
       this._mdf = true;
-
       if (this.opacity !== effectElements[8].p.v) {
         this.opacity = effectElements[8].p.v;
         this._opMdf = true;
@@ -16775,9 +14157,9 @@
   function SVGTransformEffect(_, filterManager) {
     this.init(filterManager);
   }
-
   extendPrototype([TransformEffect], SVGTransformEffect);
 
+  // Registering expression plugin
   setExpressionsPlugin(Expressions);
   setExpressionInterfaces(getInterface);
   initialize$1();
diff --git a/build/player/lottie_svg.min.js b/build/player/lottie_svg.min.js
index 8d14e4a..8ed41b8 100644
--- a/build/player/lottie_svg.min.js
+++ b/build/player/lottie_svg.min.js
@@ -1 +1 @@
-"undefined"!=typeof navigator&&function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lottie=e()}(this,(function(){"use strict";var svgNS="http://www.w3.org/2000/svg",locationHref="",_useWebWorker=!1,initialDefaultFrame=-999999,setWebWorker=function(t){_useWebWorker=!!t},getWebWorker=function(){return _useWebWorker},setLocationHref=function(t){locationHref=t},getLocationHref=function(){return locationHref};function createTag(t){return document.createElement(t)}function extendPrototype(t,e){var r,i,s=t.length;for(r=0;r<s;r+=1)for(var a in i=t[r].prototype)Object.prototype.hasOwnProperty.call(i,a)&&(e.prototype[a]=i[a])}function getDescriptor(t,e){return Object.getOwnPropertyDescriptor(t,e)}function createProxyFunction(t){function e(){}return e.prototype=t,e}var audioControllerFactory=function(){function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].pause()},resume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].resume()},setRate:function(t){var e,r=this.audios.length;for(e=0;e<r;e+=1)this.audios[e].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}}(),createTypedArray=function(){function t(t,e){var r,i=0,s=[];switch(t){case"int16":case"uint8c":r=1;break;default:r=1.1}for(i=0;i<e;i+=1)s.push(r);return s}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(e,r){return"float32"===e?new Float32Array(r):"int16"===e?new Int16Array(r):"uint8c"===e?new Uint8ClampedArray(r):t(e,r)}:t}();function createSizedArray(t){return Array.apply(null,{length:t})}function _typeof$6(t){return _typeof$6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$6(t)}var subframeEnabled=!0,expressionsPlugin=null,expressionsInterfaces=null,idPrefix$1="",isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),_shouldRoundValues=!1,bmPow=Math.pow,bmSqrt=Math.sqrt,bmFloor=Math.floor,bmMax=Math.max,bmMin=Math.min,BMMath={};function ProjectInterface$1(){return{}}!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],r=e.length;for(t=0;t<r;t+=1)BMMath[e[t]]=Math[e[t]]}(),BMMath.random=Math.random,BMMath.abs=function(t){if("object"===_typeof$6(t)&&t.length){var e,r=createSizedArray(t.length),i=t.length;for(e=0;e<i;e+=1)r[e]=Math.abs(t[e]);return r}return Math.abs(t)};var defaultCurveSegments=150,degToRads=Math.PI/180,roundCorner=.5519;function roundValues(t){_shouldRoundValues=!!t}function bmRnd(t){return _shouldRoundValues?Math.round(t):t}function styleDiv(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin="0 0",t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility="visible",t.style.webkitBackfaceVisibility="visible",t.style.transformStyle="preserve-3d",t.style.webkitTransformStyle="preserve-3d",t.style.mozTransformStyle="preserve-3d"}function BMEnterFrameEvent(t,e,r,i){this.type=t,this.currentTime=e,this.totalTime=r,this.direction=i<0?-1:1}function BMCompleteEvent(t,e){this.type=t,this.direction=e<0?-1:1}function BMCompleteLoopEvent(t,e,r,i){this.type=t,this.currentLoop=r,this.totalLoops=e,this.direction=i<0?-1:1}function BMSegmentStartEvent(t,e,r){this.type=t,this.firstFrame=e,this.totalFrames=r}function BMDestroyEvent(t,e){this.type=t,this.target=e}function BMRenderFrameErrorEvent(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function BMConfigErrorEvent(t){this.type="configError",this.nativeError=t}function BMAnimationConfigErrorEvent(t,e){this.type=t,this.nativeError=e}var createElementID=(_count=0,function(){return idPrefix$1+"__lottie_element_"+(_count+=1)}),_count;function HSVtoRGB(t,e,r){var i,s,a,n,o,h,l,p;switch(h=r*(1-e),l=r*(1-(o=6*t-(n=Math.floor(6*t)))*e),p=r*(1-(1-o)*e),n%6){case 0:i=r,s=p,a=h;break;case 1:i=l,s=r,a=h;break;case 2:i=h,s=r,a=p;break;case 3:i=h,s=l,a=r;break;case 4:i=p,s=h,a=r;break;case 5:i=r,s=h,a=l}return[i,s,a]}function RGBtoHSV(t,e,r){var i,s=Math.max(t,e,r),a=Math.min(t,e,r),n=s-a,o=0===s?0:n/s,h=s/255;switch(s){case a:i=0;break;case t:i=e-r+n*(e<r?6:0),i/=6*n;break;case e:i=r-t+2*n,i/=6*n;break;case r:i=t-e+4*n,i/=6*n}return[i,o,h]}function addSaturationToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[1]+=e,r[1]>1?r[1]=1:r[1]<=0&&(r[1]=0),HSVtoRGB(r[0],r[1],r[2])}function addBrightnessToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[2]+=e,r[2]>1?r[2]=1:r[2]<0&&(r[2]=0),HSVtoRGB(r[0],r[1],r[2])}function addHueToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[0]+=e/360,r[0]>1?r[0]-=1:r[0]<0&&(r[0]+=1),HSVtoRGB(r[0],r[1],r[2])}var rgbToHex=function(){var t,e,r=[];for(t=0;t<256;t+=1)e=t.toString(16),r[t]=1===e.length?"0"+e:e;return function(t,e,i){return t<0&&(t=0),e<0&&(e=0),i<0&&(i=0),"#"+r[t]+r[e]+r[i]}}(),setSubframeEnabled=function(t){subframeEnabled=!!t},getSubframeEnabled=function(){return subframeEnabled},setExpressionsPlugin=function(t){expressionsPlugin=t},getExpressionsPlugin=function(){return expressionsPlugin},setExpressionInterfaces=function(t){expressionsInterfaces=t},getExpressionInterfaces=function(){return expressionsInterfaces},setDefaultCurveSegments=function(t){defaultCurveSegments=t},getDefaultCurveSegments=function(){return defaultCurveSegments},setIdPrefix=function(t){idPrefix$1=t},getIdPrefix=function(){return idPrefix$1};function createNS(t){return document.createElementNS(svgNS,t)}function _typeof$5(t){return _typeof$5="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$5(t)}var dataManager=function(){var t,e,r=1,i=[],s={onmessage:function(){},postMessage:function(e){t({data:e})}},a={postMessage:function(t){s.onmessage({data:t})}};function n(){e||(e=function(e){if(window.Worker&&window.Blob&&getWebWorker()){var r=new Blob(["var _workerSelf = self; self.onmessage = ",e.toString()],{type:"text/javascript"}),i=URL.createObjectURL(r);return new Worker(i)}return t=e,s}((function(t){if(a.dataManager||(a.dataManager=function(){function t(s,a){var n,o,h,l,p,c,m=s.length;for(o=0;o<m;o+=1)if("ks"in(n=s[o])&&!n.completed){if(n.completed=!0,n.hasMask){var u=n.masksProperties;for(l=u.length,h=0;h<l;h+=1)if(u[h].pt.k.i)i(u[h].pt.k);else for(c=u[h].pt.k.length,p=0;p<c;p+=1)u[h].pt.k[p].s&&i(u[h].pt.k[p].s[0]),u[h].pt.k[p].e&&i(u[h].pt.k[p].e[0])}0===n.ty?(n.layers=e(n.refId,a),t(n.layers,a)):4===n.ty?r(n.shapes):5===n.ty&&f(n)}}function e(t,e){var r=function(t,e){for(var r=0,i=e.length;r<i;){if(e[r].id===t)return e[r];r+=1}return null}(t,e);return r?r.layers.__used?JSON.parse(JSON.stringify(r.layers)):(r.layers.__used=!0,r.layers):null}function r(t){var e,s,a;for(e=t.length-1;e>=0;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)i(t[e].ks.k);else for(a=t[e].ks.k.length,s=0;s<a;s+=1)t[e].ks.k[s].s&&i(t[e].ks.k[s].s[0]),t[e].ks.k[s].e&&i(t[e].ks.k[s].e[0]);else"gr"===t[e].ty&&r(t[e].it)}function i(t){var e,r=t.i.length;for(e=0;e<r;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function s(t,e){var r=e?e.split("."):[100,100,100];return t[0]>r[0]||!(r[0]>t[0])&&(t[1]>r[1]||!(r[1]>t[1])&&(t[2]>r[2]||!(r[2]>t[2])&&null))}var a,n=function(){var t=[4,4,14];function e(t){var e,r,i,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(i=void 0,i=(r=t[e]).t.d,r.t.d={k:[{s:i,t:0}]})}return function(r){if(s(t,r.v)&&(e(r.layers),r.assets)){var i,a=r.assets.length;for(i=0;i<a;i+=1)r.assets[i].layers&&e(r.assets[i].layers)}}}(),o=(a=[4,7,99],function(t){if(t.chars&&!s(a,t.v)){var e,i=t.chars.length;for(e=0;e<i;e+=1){var n=t.chars[e];n.data&&n.data.shapes&&(r(n.data.shapes),n.data.ip=0,n.data.op=99999,n.data.st=0,n.data.sr=1,n.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[e].t||(n.data.shapes.push({ty:"no"}),n.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}}}),h=function(){var t=[5,7,15];function e(t){var e,r,i=t.length;for(e=0;e<i;e+=1)5===t[e].ty&&(r=void 0,"number"==typeof(r=t[e].t.p).a&&(r.a={a:0,k:r.a}),"number"==typeof r.p&&(r.p={a:0,k:r.p}),"number"==typeof r.r&&(r.r={a:0,k:r.r}))}return function(r){if(s(t,r.v)&&(e(r.layers),r.assets)){var i,a=r.assets.length;for(i=0;i<a;i+=1)r.assets[i].layers&&e(r.assets[i].layers)}}}(),l=function(){var t=[4,1,9];function e(t){var r,i,s,a=t.length;for(r=0;r<a;r+=1)if("gr"===t[r].ty)e(t[r].it);else if("fl"===t[r].ty||"st"===t[r].ty)if(t[r].c.k&&t[r].c.k[0].i)for(s=t[r].c.k.length,i=0;i<s;i+=1)t[r].c.k[i].s&&(t[r].c.k[i].s[0]/=255,t[r].c.k[i].s[1]/=255,t[r].c.k[i].s[2]/=255,t[r].c.k[i].s[3]/=255),t[r].c.k[i].e&&(t[r].c.k[i].e[0]/=255,t[r].c.k[i].e[1]/=255,t[r].c.k[i].e[2]/=255,t[r].c.k[i].e[3]/=255);else t[r].c.k[0]/=255,t[r].c.k[1]/=255,t[r].c.k[2]/=255,t[r].c.k[3]/=255}function r(t){var r,i=t.length;for(r=0;r<i;r+=1)4===t[r].ty&&e(t[r].shapes)}return function(e){if(s(t,e.v)&&(r(e.layers),e.assets)){var i,a=e.assets.length;for(i=0;i<a;i+=1)e.assets[i].layers&&r(e.assets[i].layers)}}}(),p=function(){var t=[4,4,18];function e(t){var r,i,s;for(r=t.length-1;r>=0;r-=1)if("sh"===t[r].ty)if(t[r].ks.k.i)t[r].ks.k.c=t[r].closed;else for(s=t[r].ks.k.length,i=0;i<s;i+=1)t[r].ks.k[i].s&&(t[r].ks.k[i].s[0].c=t[r].closed),t[r].ks.k[i].e&&(t[r].ks.k[i].e[0].c=t[r].closed);else"gr"===t[r].ty&&e(t[r].it)}function r(t){var r,i,s,a,n,o,h=t.length;for(i=0;i<h;i+=1){if((r=t[i]).hasMask){var l=r.masksProperties;for(a=l.length,s=0;s<a;s+=1)if(l[s].pt.k.i)l[s].pt.k.c=l[s].cl;else for(o=l[s].pt.k.length,n=0;n<o;n+=1)l[s].pt.k[n].s&&(l[s].pt.k[n].s[0].c=l[s].cl),l[s].pt.k[n].e&&(l[s].pt.k[n].e[0].c=l[s].cl)}4===r.ty&&e(r.shapes)}}return function(e){if(s(t,e.v)&&(r(e.layers),e.assets)){var i,a=e.assets.length;for(i=0;i<a;i+=1)e.assets[i].layers&&r(e.assets[i].layers)}}}();function f(t){0===t.t.a.length&&t.t.p}var c={completeData:function(r){r.__complete||(l(r),n(r),o(r),h(r),p(r),t(r.layers,r.assets),function(r,i){if(r){var s=0,a=r.length;for(s=0;s<a;s+=1)1===r[s].t&&(r[s].data.layers=e(r[s].data.refId,i),t(r[s].data.layers,i))}}(r.chars,r.assets),r.__complete=!0)}};return c.checkColors=l,c.checkChars=o,c.checkPathProperties=h,c.checkShapes=p,c.completeLayers=t,c}()),a.assetLoader||(a.assetLoader=function(){function t(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")||t.response&&"object"===_typeof$5(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}return{load:function(e,r,i,s){var a,n=new XMLHttpRequest;try{n.responseType="json"}catch(t){}n.onreadystatechange=function(){if(4===n.readyState)if(200===n.status)a=t(n),i(a);else try{a=t(n),i(a)}catch(t){s&&s(t)}};try{n.open(["G","E","T"].join(""),e,!0)}catch(t){n.open(["G","E","T"].join(""),r+"/"+e,!0)}n.send()}}}()),"loadAnimation"===t.data.type)a.assetLoader.load(t.data.path,t.data.fullPath,(function(e){a.dataManager.completeData(e),a.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){a.postMessage({id:t.data.id,status:"error"})}));else if("complete"===t.data.type){var e=t.data.animation;a.dataManager.completeData(e),a.postMessage({id:t.data.id,payload:e,status:"success"})}else"loadData"===t.data.type&&a.assetLoader.load(t.data.path,t.data.fullPath,(function(e){a.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){a.postMessage({id:t.data.id,status:"error"})}))})),e.onmessage=function(t){var e=t.data,r=e.id,s=i[r];i[r]=null,"success"===e.status?s.onComplete(e.payload):s.onError&&s.onError()})}function o(t,e){var s="processId_"+(r+=1);return i[s]={onComplete:t,onError:e},s}return{loadAnimation:function(t,r,i){n();var s=o(r,i);e.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:s})},loadData:function(t,r,i){n();var s=o(r,i);e.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:s})},completeAnimation:function(t,r,i){n();var s=o(r,i);e.postMessage({type:"complete",animation:t,id:s})}}}(),ImagePreloader=function(){var t=function(){var t=createTag("canvas");t.width=1,t.height=1;var e=t.getContext("2d");return e.fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1),t}();function e(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function r(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function i(t,e,r){var i="";if(t.e)i=t.p;else if(e){var s=t.p;-1!==s.indexOf("images/")&&(s=s.split("/")[1]),i=e+s}else i=r,i+=t.u?t.u:"",i+=t.p;return i}function s(t){var e=0,r=setInterval(function(){(t.getBBox().width||e>500)&&(this._imageLoaded(),clearInterval(r)),e+=1}.bind(this),50)}function a(t){var e={assetData:t},r=i(t,this.assetsPath,this.path);return dataManager.loadData(r,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}function n(){this._imageLoaded=e.bind(this),this._footageLoaded=r.bind(this),this.testImageLoaded=s.bind(this),this.createFootageData=a.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return n.prototype={loadAssets:function(t,e){var r;this.imagesLoadedCb=e;var i=t.length;for(r=0;r<i;r+=1)t[r].layers||(t[r].t&&"seq"!==t[r].t?3===t[r].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[r]))):(this.totalImages+=1,this.images.push(this._createImageData(t[r]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,r=this.images.length;e<r;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(e){var r=i(e,this.assetsPath,this.path),s=createTag("img");s.crossOrigin="anonymous",s.addEventListener("load",this._imageLoaded,!1),s.addEventListener("error",function(){a.img=t,this._imageLoaded()}.bind(this),!1),s.src=r;var a={img:s,assetData:e};return a},createImageData:function(e){var r=i(e,this.assetsPath,this.path),s=createNS("image");isSafari?this.testImageLoaded(s):s.addEventListener("load",this._imageLoaded,!1),s.addEventListener("error",function(){a.img=t,this._imageLoaded()}.bind(this),!1),s.setAttributeNS("http://www.w3.org/1999/xlink","href",r),this._elementHelper.append?this._elementHelper.append(s):this._elementHelper.appendChild(s);var a={img:s,assetData:e};return a},imageLoaded:e,footageLoaded:r,setCacheType:function(t,e){"svg"===t?(this._elementHelper=e,this._createImageData=this.createImageData.bind(this)):this._createImageData=this.createImgData.bind(this)}},n}();function BaseEvent(){}BaseEvent.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var r=this._cbs[t],i=0;i<r.length;i+=1)r[i](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var r=0,i=this._cbs[t].length;r<i;)this._cbs[t][r]===e&&(this._cbs[t].splice(r,1),r-=1,i-=1),r+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var markerParser=function(){function t(t){for(var e,r=t.split("\r\n"),i={},s=0,a=0;a<r.length;a+=1)2===(e=r[a].split(":")).length&&(i[e[0]]=e[1].trim(),s+=1);if(0===s)throw new Error;return i}return function(e){for(var r=[],i=0;i<e.length;i+=1){var s=e[i],a={time:s.tm,duration:s.dr};try{a.payload=JSON.parse(e[i].cm)}catch(r){try{a.payload=t(e[i].cm)}catch(t){a.payload={name:e[i].cm}}}r.push(a)}return r}}(),ProjectInterface=function(){function t(t){this.compositions.push(t)}return function(){function e(t){for(var e=0,r=this.compositions.length;e<r;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return e.compositions=[],e.currentFrame=0,e.registerComposition=t,e}}(),renderers={},registerRenderer=function(t,e){renderers[t]=e};function getRenderer(t){return renderers[t]}function getRegisteredRenderer(){if(renderers.canvas)return"canvas";for(var t in renderers)if(renderers[t])return t;return""}function _typeof$4(t){return _typeof$4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$4(t)}var AnimationItem=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=createElementID(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=getSubframeEnabled(),this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=ProjectInterface(),this.imagePreloader=new ImagePreloader,this.audioController=audioControllerFactory(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new BMEnterFrameEvent("drawnFrame",0,0,0),this.expressionsPlugin=getExpressionsPlugin()};extendPrototype([BaseEvent],AnimationItem),AnimationItem.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg";t.animType?e=t.animType:t.renderer&&(e=t.renderer);var r=getRenderer(e);this.renderer=new r(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||void 0===t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),dataManager.loadAnimation(t.path,this.configAnimation,this.onSetupError))},AnimationItem.prototype.onSetupError=function(){this.trigger("data_failed")},AnimationItem.prototype.setupAnimation=function(t){dataManager.completeAnimation(t,this.configAnimation)},AnimationItem.prototype.setData=function(t,e){e&&"object"!==_typeof$4(e)&&(e=JSON.parse(e));var r={wrapper:t,animationData:e},i=t.attributes;r.path=i.getNamedItem("data-animation-path")?i.getNamedItem("data-animation-path").value:i.getNamedItem("data-bm-path")?i.getNamedItem("data-bm-path").value:i.getNamedItem("bm-path")?i.getNamedItem("bm-path").value:"",r.animType=i.getNamedItem("data-anim-type")?i.getNamedItem("data-anim-type").value:i.getNamedItem("data-bm-type")?i.getNamedItem("data-bm-type").value:i.getNamedItem("bm-type")?i.getNamedItem("bm-type").value:i.getNamedItem("data-bm-renderer")?i.getNamedItem("data-bm-renderer").value:i.getNamedItem("bm-renderer")?i.getNamedItem("bm-renderer").value:getRegisteredRenderer()||"canvas";var s=i.getNamedItem("data-anim-loop")?i.getNamedItem("data-anim-loop").value:i.getNamedItem("data-bm-loop")?i.getNamedItem("data-bm-loop").value:i.getNamedItem("bm-loop")?i.getNamedItem("bm-loop").value:"";"false"===s?r.loop=!1:"true"===s?r.loop=!0:""!==s&&(r.loop=parseInt(s,10));var a=i.getNamedItem("data-anim-autoplay")?i.getNamedItem("data-anim-autoplay").value:i.getNamedItem("data-bm-autoplay")?i.getNamedItem("data-bm-autoplay").value:!i.getNamedItem("bm-autoplay")||i.getNamedItem("bm-autoplay").value;r.autoplay="false"!==a,r.name=i.getNamedItem("data-name")?i.getNamedItem("data-name").value:i.getNamedItem("data-bm-name")?i.getNamedItem("data-bm-name").value:i.getNamedItem("bm-name")?i.getNamedItem("bm-name").value:"","false"===(i.getNamedItem("data-anim-prerender")?i.getNamedItem("data-anim-prerender").value:i.getNamedItem("data-bm-prerender")?i.getNamedItem("data-bm-prerender").value:i.getNamedItem("bm-prerender")?i.getNamedItem("bm-prerender").value:"")&&(r.prerender=!1),r.path?this.setParams(r):this.trigger("destroy")},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,r,i=this.animationData.layers,s=i.length,a=t.layers,n=a.length;for(r=0;r<n;r+=1)for(e=0;e<s;){if(i[e].id===a[r].id){i[e]=a[r];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(s=t.assets.length,e=0;e<s;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,dataManager.completeAnimation(this.animationData,this.onSegmentComplete)},AnimationItem.prototype.onSegmentComplete=function(t){this.animationData=t;var e=getExpressionsPlugin();e&&e.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var r=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,dataManager.loadData(r,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},AnimationItem.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},AnimationItem.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=markerParser(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},AnimationItem.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},AnimationItem.prototype.checkLoaded=function(){if(!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()){this.isLoaded=!0;var t=getExpressionsPlugin();t&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play()}},AnimationItem.prototype.resize=function(t,e){var r="number"==typeof t?t:void 0,i="number"==typeof e?e:void 0;this.renderer.updateContainerSize(r,i)},AnimationItem.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},AnimationItem.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},AnimationItem.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},AnimationItem.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},AnimationItem.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.getMarkerData=function(t){for(var e,r=0;r<this.markers.length;r+=1)if((e=this.markers[r]).payload&&e.payload.name===t)return e;return null},AnimationItem.prototype.goToAndStop=function(t,e,r){if(!r||this.name===r){var i=Number(t);if(isNaN(i)){var s=this.getMarkerData(t);s&&this.goToAndStop(s.time,!0)}else e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier);this.pause()}},AnimationItem.prototype.goToAndPlay=function(t,e,r){if(!r||this.name===r){var i=Number(t);if(isNaN(i)){var s=this.getMarkerData(t);s&&(s.duration?this.playSegments([s.time,s.time+s.duration],!0):this.goToAndStop(s.time,!0))}else this.goToAndStop(i,e,r);this.play()}},AnimationItem.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,r=!1;e>=this.totalFrames-1&&this.frameModifier>0?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(r=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(r=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),r&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(this.frameModifier>0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var r=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?r=t:this.currentRawFrame+this.firstFrame>e&&(r=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==r&&this.goToAndStop(r,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===_typeof$4(t[0])){var r,i=t.length;for(r=0;r<i;r+=1)this.segments.push(t[r])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},AnimationItem.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},AnimationItem.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},AnimationItem.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},AnimationItem.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},AnimationItem.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},AnimationItem.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},AnimationItem.prototype.setLoop=function(t){this.loop=t},AnimationItem.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},AnimationItem.prototype.getVolume=function(){return this.audioController.getVolume()},AnimationItem.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},AnimationItem.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},AnimationItem.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},AnimationItem.prototype.getPath=function(){return this.path},AnimationItem.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var r=t.p;-1!==r.indexOf("images/")&&(r=r.split("/")[1]),e=this.assetsPath+r}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},AnimationItem.prototype.getAssetData=function(t){for(var e=0,r=this.assets.length;e<r;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},AnimationItem.prototype.hide=function(){this.renderer.hide()},AnimationItem.prototype.show=function(){this.renderer.show()},AnimationItem.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},AnimationItem.prototype.updateDocumentData=function(t,e,r){try{this.renderer.getElementByPath(t).updateDocumentData(e,r)}catch(t){}},AnimationItem.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new BMCompleteEvent(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new BMDestroyEvent(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new BMCompleteEvent(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new BMDestroyEvent(t,this))},AnimationItem.prototype.triggerRenderFrameError=function(t){var e=new BMRenderFrameErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)},AnimationItem.prototype.triggerConfigError=function(t){var e=new BMConfigErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)};var animationManager=function(){var t={},e=[],r=0,i=0,s=0,a=!0,n=!1;function o(t){for(var r=0,s=t.target;r<i;)e[r].animation===s&&(e.splice(r,1),r-=1,i-=1,s.isPaused||p()),r+=1}function h(t,r){if(!t)return null;for(var s=0;s<i;){if(e[s].elem===t&&null!==e[s].elem)return e[s].animation;s+=1}var a=new AnimationItem;return f(a,t),a.setData(t,r),a}function l(){s+=1,u()}function p(){s-=1}function f(t,r){t.addEventListener("destroy",o),t.addEventListener("_active",l),t.addEventListener("_idle",p),e.push({elem:r,animation:t}),i+=1}function c(t){var o,h=t-r;for(o=0;o<i;o+=1)e[o].animation.advanceTime(h);r=t,s&&!n?window.requestAnimationFrame(c):a=!0}function m(t){r=t,window.requestAnimationFrame(c)}function u(){!n&&s&&a&&(window.requestAnimationFrame(m),a=!1)}return t.registerAnimation=h,t.loadAnimation=function(t){var e=new AnimationItem;return f(e,null),e.setParams(t),e},t.setSpeed=function(t,r){var s;for(s=0;s<i;s+=1)e[s].animation.setSpeed(t,r)},t.setDirection=function(t,r){var s;for(s=0;s<i;s+=1)e[s].animation.setDirection(t,r)},t.play=function(t){var r;for(r=0;r<i;r+=1)e[r].animation.play(t)},t.pause=function(t){var r;for(r=0;r<i;r+=1)e[r].animation.pause(t)},t.stop=function(t){var r;for(r=0;r<i;r+=1)e[r].animation.stop(t)},t.togglePause=function(t){var r;for(r=0;r<i;r+=1)e[r].animation.togglePause(t)},t.searchAnimations=function(t,e,r){var i,s=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),a=s.length;for(i=0;i<a;i+=1)r&&s[i].setAttribute("data-bm-type",r),h(s[i],t);if(e&&0===a){r||(r="svg");var n=document.getElementsByTagName("body")[0];n.innerText="";var o=createTag("div");o.style.width="100%",o.style.height="100%",o.setAttribute("data-bm-type",r),n.appendChild(o),h(o,t)}},t.resize=function(){var t;for(t=0;t<i;t+=1)e[t].animation.resize()},t.goToAndStop=function(t,r,s){var a;for(a=0;a<i;a+=1)e[a].animation.goToAndStop(t,r,s)},t.destroy=function(t){var r;for(r=i-1;r>=0;r-=1)e[r].animation.destroy(t)},t.freeze=function(){n=!0},t.unfreeze=function(){n=!1,u()},t.setVolume=function(t,r){var s;for(s=0;s<i;s+=1)e[s].animation.setVolume(t,r)},t.mute=function(t){var r;for(r=0;r<i;r+=1)e[r].animation.mute(t)},t.unmute=function(t){var r;for(r=0;r<i;r+=1)e[r].animation.unmute(t)},t.getRegisteredAnimations=function(){var t,r=e.length,i=[];for(t=0;t<r;t+=1)i.push(e[t].animation);return i},t}(),BezierFactory=function(){var t={getBezierEasing:function(t,r,i,s,a){var n=a||("bez_"+t+"_"+r+"_"+i+"_"+s).replace(/\./g,"p");if(e[n])return e[n];var o=new l([t,r,i,s]);return e[n]=o,o}},e={};var r=.1,i="function"==typeof Float32Array;function s(t,e){return 1-3*e+3*t}function a(t,e){return 3*e-6*t}function n(t){return 3*t}function o(t,e,r){return((s(e,r)*t+a(e,r))*t+n(e))*t}function h(t,e,r){return 3*s(e,r)*t*t+2*a(e,r)*t+n(e)}function l(t){this._p=t,this._mSampleValues=i?new Float32Array(11):new Array(11),this._precomputed=!1,this.get=this.get.bind(this)}return l.prototype={get:function(t){var e=this._p[0],r=this._p[1],i=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===r&&i===s?t:0===t?0:1===t?1:o(this._getTForX(t),r,s)},_precompute:function(){var t=this._p[0],e=this._p[1],r=this._p[2],i=this._p[3];this._precomputed=!0,t===e&&r===i||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],i=0;i<11;++i)this._mSampleValues[i]=o(i*r,t,e)},_getTForX:function(t){for(var e=this._p[0],i=this._p[2],s=this._mSampleValues,a=0,n=1;10!==n&&s[n]<=t;++n)a+=r;var l=a+(t-s[--n])/(s[n+1]-s[n])*r,p=h(l,e,i);return p>=.001?function(t,e,r,i){for(var s=0;s<4;++s){var a=h(e,r,i);if(0===a)return e;e-=(o(e,r,i)-t)/a}return e}(t,l,e,i):0===p?l:function(t,e,r,i,s){var a,n,h=0;do{(a=o(n=e+(r-e)/2,i,s)-t)>0?r=n:e=n}while(Math.abs(a)>1e-7&&++h<10);return n}(t,a,a+r,e,i)}},t}(),pooling={double:function(t){return t.concat(createSizedArray(t.length))}},poolFactory=function(t,e,r){var i=0,s=t,a=createSizedArray(s);return{newElement:function(){return i?a[i-=1]:e()},release:function(t){i===s&&(a=pooling.double(a),s*=2),r&&r(t),a[i]=t,i+=1}}},bezierLengthPool=poolFactory(8,(function(){return{addedLength:0,percents:createTypedArray("float32",getDefaultCurveSegments()),lengths:createTypedArray("float32",getDefaultCurveSegments())}})),segmentsLengthPool=poolFactory(8,(function(){return{lengths:[],totalLength:0}}),(function(t){var e,r=t.lengths.length;for(e=0;e<r;e+=1)bezierLengthPool.release(t.lengths[e]);t.lengths.length=0}));function bezFunction(){var t=Math;function e(t,e,r,i,s,a){var n=t*i+e*s+r*a-s*i-a*t-r*e;return n>-.001&&n<.001}var r=function(t,e,r,i){var s,a,n,o,h,l,p=getDefaultCurveSegments(),f=0,c=[],m=[],u=bezierLengthPool.newElement();for(n=r.length,s=0;s<p;s+=1){for(h=s/(p-1),l=0,a=0;a<n;a+=1)o=bmPow(1-h,3)*t[a]+3*bmPow(1-h,2)*h*r[a]+3*(1-h)*bmPow(h,2)*i[a]+bmPow(h,3)*e[a],c[a]=o,null!==m[a]&&(l+=bmPow(c[a]-m[a],2)),m[a]=c[a];l&&(f+=l=bmSqrt(l)),u.percents[s]=h,u.lengths[s]=f}return u.addedLength=f,u};function i(t){this.segmentLength=0,this.points=new Array(t)}function s(t,e){this.partialLength=t,this.point=e}var a,n=(a={},function(t,r,n,o){var h=(t[0]+"_"+t[1]+"_"+r[0]+"_"+r[1]+"_"+n[0]+"_"+n[1]+"_"+o[0]+"_"+o[1]).replace(/\./g,"p");if(!a[h]){var l,p,f,c,m,u,d,y=getDefaultCurveSegments(),g=0,v=null;2===t.length&&(t[0]!==r[0]||t[1]!==r[1])&&e(t[0],t[1],r[0],r[1],t[0]+n[0],t[1]+n[1])&&e(t[0],t[1],r[0],r[1],r[0]+o[0],r[1]+o[1])&&(y=2);var b=new i(y);for(f=n.length,l=0;l<y;l+=1){for(d=createSizedArray(f),m=l/(y-1),u=0,p=0;p<f;p+=1)c=bmPow(1-m,3)*t[p]+3*bmPow(1-m,2)*m*(t[p]+n[p])+3*(1-m)*bmPow(m,2)*(r[p]+o[p])+bmPow(m,3)*r[p],d[p]=c,null!==v&&(u+=bmPow(d[p]-v[p],2));g+=u=bmSqrt(u),b.points[l]=new s(u,d),v=d}b.segmentLength=g,a[h]=b}return a[h]});function o(t,e){var r=e.percents,i=e.lengths,s=r.length,a=bmFloor((s-1)*t),n=t*e.addedLength,o=0;if(a===s-1||0===a||n===i[a])return r[a];for(var h=i[a]>n?-1:1,l=!0;l;)if(i[a]<=n&&i[a+1]>n?(o=(n-i[a])/(i[a+1]-i[a]),l=!1):a+=h,a<0||a>=s-1){if(a===s-1)return r[a];l=!1}return r[a]+(r[a+1]-r[a])*o}var h=createTypedArray("float32",8);return{getSegmentsLength:function(t){var e,i=segmentsLengthPool.newElement(),s=t.c,a=t.v,n=t.o,o=t.i,h=t._length,l=i.lengths,p=0;for(e=0;e<h-1;e+=1)l[e]=r(a[e],a[e+1],n[e],o[e+1]),p+=l[e].addedLength;return s&&h&&(l[e]=r(a[e],a[0],n[e],o[0]),p+=l[e].addedLength),i.totalLength=p,i},getNewSegment:function(e,r,i,s,a,n,l){a<0?a=0:a>1&&(a=1);var p,f=o(a,l),c=o(n=n>1?1:n,l),m=e.length,u=1-f,d=1-c,y=u*u*u,g=f*u*u*3,v=f*f*u*3,b=f*f*f,P=u*u*d,S=f*u*d+u*f*d+u*u*c,_=f*f*d+u*f*c+f*u*c,E=f*f*c,x=u*d*d,A=f*d*d+u*c*d+u*d*c,M=f*c*d+u*c*c+f*d*c,T=f*c*c,k=d*d*d,F=c*d*d+d*c*d+d*d*c,I=c*c*d+d*c*c+c*d*c,D=c*c*c;for(p=0;p<m;p+=1)h[4*p]=t.round(1e3*(y*e[p]+g*i[p]+v*s[p]+b*r[p]))/1e3,h[4*p+1]=t.round(1e3*(P*e[p]+S*i[p]+_*s[p]+E*r[p]))/1e3,h[4*p+2]=t.round(1e3*(x*e[p]+A*i[p]+M*s[p]+T*r[p]))/1e3,h[4*p+3]=t.round(1e3*(k*e[p]+F*i[p]+I*s[p]+D*r[p]))/1e3;return h},getPointInSegment:function(e,r,i,s,a,n){var h=o(a,n),l=1-h;return[t.round(1e3*(l*l*l*e[0]+(h*l*l+l*h*l+l*l*h)*i[0]+(h*h*l+l*h*h+h*l*h)*s[0]+h*h*h*r[0]))/1e3,t.round(1e3*(l*l*l*e[1]+(h*l*l+l*h*l+l*l*h)*i[1]+(h*h*l+l*h*h+h*l*h)*s[1]+h*h*h*r[1]))/1e3]},buildBezierData:n,pointOnLine2D:e,pointOnLine3D:function(r,i,s,a,n,o,h,l,p){if(0===s&&0===o&&0===p)return e(r,i,a,n,h,l);var f,c=t.sqrt(t.pow(a-r,2)+t.pow(n-i,2)+t.pow(o-s,2)),m=t.sqrt(t.pow(h-r,2)+t.pow(l-i,2)+t.pow(p-s,2)),u=t.sqrt(t.pow(h-a,2)+t.pow(l-n,2)+t.pow(p-o,2));return(f=c>m?c>u?c-m-u:u-m-c:u>m?u-m-c:m-c-u)>-1e-4&&f<1e-4}}}var bez=bezFunction(),initFrame=initialDefaultFrame,mathAbs=Math.abs;function interpolateValue(t,e){var r,i=this.offsetTime;"multidimensional"===this.propType&&(r=createTypedArray("float32",this.pv.length));for(var s,a,n,o,h,l,p,f,c,m=e.lastIndex,u=m,d=this.keyframes.length-1,y=!0;y;){if(s=this.keyframes[u],a=this.keyframes[u+1],u===d-1&&t>=a.t-i){s.h&&(s=a),m=0;break}if(a.t-i>t){m=u;break}u<d-1?u+=1:(m=0,y=!1)}n=this.keyframesMetadata[u]||{};var g,v=a.t-i,b=s.t-i;if(s.to){n.bezierData||(n.bezierData=bez.buildBezierData(s.s,a.s||s.e,s.to,s.ti));var P=n.bezierData;if(t>=v||t<b){var S=t>=v?P.points.length-1:0;for(h=P.points[S].point.length,o=0;o<h;o+=1)r[o]=P.points[S].point[o]}else{n.__fnct?c=n.__fnct:(c=BezierFactory.getBezierEasing(s.o.x,s.o.y,s.i.x,s.i.y,s.n).get,n.__fnct=c),l=c((t-b)/(v-b));var _,E=P.segmentLength*l,x=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastAddedLength:0;for(f=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastPoint:0,y=!0,p=P.points.length;y;){if(x+=P.points[f].partialLength,0===E||0===l||f===P.points.length-1){for(h=P.points[f].point.length,o=0;o<h;o+=1)r[o]=P.points[f].point[o];break}if(E>=x&&E<x+P.points[f+1].partialLength){for(_=(E-x)/P.points[f+1].partialLength,h=P.points[f].point.length,o=0;o<h;o+=1)r[o]=P.points[f].point[o]+(P.points[f+1].point[o]-P.points[f].point[o])*_;break}f<p-1?f+=1:y=!1}e._lastPoint=f,e._lastAddedLength=x-P.points[f].partialLength,e._lastKeyframeIndex=u}}else{var A,M,T,k,F;if(d=s.s.length,g=a.s||s.e,this.sh&&1!==s.h)if(t>=v)r[0]=g[0],r[1]=g[1],r[2]=g[2];else if(t<=b)r[0]=s.s[0],r[1]=s.s[1],r[2]=s.s[2];else{quaternionToEuler(r,slerp(createQuaternion(s.s),createQuaternion(g),(t-b)/(v-b)))}else for(u=0;u<d;u+=1)1!==s.h&&(t>=v?l=1:t<b?l=0:(s.o.x.constructor===Array?(n.__fnct||(n.__fnct=[]),n.__fnct[u]?c=n.__fnct[u]:(A=void 0===s.o.x[u]?s.o.x[0]:s.o.x[u],M=void 0===s.o.y[u]?s.o.y[0]:s.o.y[u],T=void 0===s.i.x[u]?s.i.x[0]:s.i.x[u],k=void 0===s.i.y[u]?s.i.y[0]:s.i.y[u],c=BezierFactory.getBezierEasing(A,M,T,k).get,n.__fnct[u]=c)):n.__fnct?c=n.__fnct:(A=s.o.x,M=s.o.y,T=s.i.x,k=s.i.y,c=BezierFactory.getBezierEasing(A,M,T,k).get,s.keyframeMetadata=c),l=c((t-b)/(v-b)))),g=a.s||s.e,F=1===s.h?s.s[u]:s.s[u]+(g[u]-s.s[u])*l,"multidimensional"===this.propType?r[u]=F:r=F}return e.lastIndex=m,r}function slerp(t,e,r){var i,s,a,n,o,h=[],l=t[0],p=t[1],f=t[2],c=t[3],m=e[0],u=e[1],d=e[2],y=e[3];return(s=l*m+p*u+f*d+c*y)<0&&(s=-s,m=-m,u=-u,d=-d,y=-y),1-s>1e-6?(i=Math.acos(s),a=Math.sin(i),n=Math.sin((1-r)*i)/a,o=Math.sin(r*i)/a):(n=1-r,o=r),h[0]=n*l+o*m,h[1]=n*p+o*u,h[2]=n*f+o*d,h[3]=n*c+o*y,h}function quaternionToEuler(t,e){var r=e[0],i=e[1],s=e[2],a=e[3],n=Math.atan2(2*i*a-2*r*s,1-2*i*i-2*s*s),o=Math.asin(2*r*i+2*s*a),h=Math.atan2(2*r*a-2*i*s,1-2*r*r-2*s*s);t[0]=n/degToRads,t[1]=o/degToRads,t[2]=h/degToRads}function createQuaternion(t){var e=t[0]*degToRads,r=t[1]*degToRads,i=t[2]*degToRads,s=Math.cos(e/2),a=Math.cos(r/2),n=Math.cos(i/2),o=Math.sin(e/2),h=Math.sin(r/2),l=Math.sin(i/2);return[o*h*n+s*a*l,o*a*n+s*h*l,s*h*n-o*a*l,s*a*n-o*h*l]}function getValueAtCurrentTime(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,r=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==initFrame&&(this._caching.lastFrame>=r&&t>=r||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var i=this.interpolateValue(t,this._caching);this.pv=i}return this._caching.lastFrame=t,this.pv}function setVValue(t){var e;if("unidimensional"===this.propType)e=t*this.mult,mathAbs(this.v-e)>1e-5&&(this.v=e,this._mdf=!0);else for(var r=0,i=this.v.length;r<i;)e=t[r]*this.mult,mathAbs(this.v[r]-e)>1e-5&&(this.v[r]=e,this._mdf=!0),r+=1}function processEffectsSequence(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t;this.lock=!0,this._mdf=this._isFirstFrame;var e=this.effectsSequence.length,r=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)r=this.effectsSequence[t](r);this.setVValue(r),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function addEffect(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function ValueProperty(t,e,r,i){this.propType="unidimensional",this.mult=r||1,this.data=e,this.v=r?e.k*r:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=i,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function MultiDimensionalProperty(t,e,r,i){var s;this.propType="multidimensional",this.mult=r||1,this.data=e,this._mdf=!1,this.elem=t,this.container=i,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var a=e.k.length;for(this.v=createTypedArray("float32",a),this.pv=createTypedArray("float32",a),this.vel=createTypedArray("float32",a),s=0;s<a;s+=1)this.v[s]=e.k[s]*this.mult,this.pv[s]=e.k[s];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function KeyframedValueProperty(t,e,r,i){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:initFrame,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=r||1,this.elem=t,this.container=i,this.comp=t.comp,this.v=initFrame,this.pv=initFrame,this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.addEffect=addEffect}function KeyframedMultidimensionalProperty(t,e,r,i){var s;this.propType="multidimensional";var a,n,o,h,l=e.k.length;for(s=0;s<l-1;s+=1)e.k[s].to&&e.k[s].s&&e.k[s+1]&&e.k[s+1].s&&(a=e.k[s].s,n=e.k[s+1].s,o=e.k[s].to,h=e.k[s].ti,(2===a.length&&(a[0]!==n[0]||a[1]!==n[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],a[0]+o[0],a[1]+o[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],n[0]+h[0],n[1]+h[1])||3===a.length&&(a[0]!==n[0]||a[1]!==n[1]||a[2]!==n[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],a[0]+o[0],a[1]+o[1],a[2]+o[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],n[0]+h[0],n[1]+h[1],n[2]+h[2]))&&(e.k[s].to=null,e.k[s].ti=null),a[0]===n[0]&&a[1]===n[1]&&0===o[0]&&0===o[1]&&0===h[0]&&0===h[1]&&(2===a.length||a[2]===n[2]&&0===o[2]&&0===h[2])&&(e.k[s].to=null,e.k[s].ti=null));this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=r||1,this.elem=t,this.container=i,this.comp=t.comp,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.frameId=-1;var p=e.k[0].s.length;for(this.v=createTypedArray("float32",p),this.pv=createTypedArray("float32",p),s=0;s<p;s+=1)this.v[s]=initFrame,this.pv[s]=initFrame;this._caching={lastFrame:initFrame,lastIndex:0,value:createTypedArray("float32",p)},this.addEffect=addEffect}var PropertyFactory={getProp:function(t,e,r,i,s){var a;if(e.sid&&(e=t.globalData.slotManager.getProp(e)),e.k.length)if("number"==typeof e.k[0])a=new MultiDimensionalProperty(t,e,i,s);else switch(r){case 0:a=new KeyframedValueProperty(t,e,i,s);break;case 1:a=new KeyframedMultidimensionalProperty(t,e,i,s)}else a=new ValueProperty(t,e,i,s);return a.effectsSequence.length&&s.addDynamicProperty(a),a}};function DynamicPropertyContainer(){}DynamicPropertyContainer.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){var t;this._mdf=!1;var e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var pointPool=poolFactory(8,(function(){return createTypedArray("float32",2)}));function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var r=0;r<e;)this.v[r]=pointPool.newElement(),this.o[r]=pointPool.newElement(),this.i[r]=pointPool.newElement(),r+=1},ShapePath.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},ShapePath.prototype.doubleArrayLength=function(){this.v=this.v.concat(createSizedArray(this._maxLength)),this.i=this.i.concat(createSizedArray(this._maxLength)),this.o=this.o.concat(createSizedArray(this._maxLength)),this._maxLength*=2},ShapePath.prototype.setXYAt=function(t,e,r,i,s){var a;switch(this._length=Math.max(this._length,i+1),this._length>=this._maxLength&&this.doubleArrayLength(),r){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o;break;default:a=[]}(!a[i]||a[i]&&!s)&&(a[i]=pointPool.newElement()),a[i][0]=t,a[i][1]=e},ShapePath.prototype.setTripleAt=function(t,e,r,i,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(r,i,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t=new ShapePath;t.setPathData(this.c,this._length);var e=this.v,r=this.o,i=this.i,s=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],i[0][0],i[0][1],r[0][0],r[0][1],0,!1),s=1);var a,n=this._length-1,o=this._length;for(a=s;a<o;a+=1)t.setTripleAt(e[n][0],e[n][1],i[n][0],i[n][1],r[n][0],r[n][1],a,!1),n-=1;return t},ShapePath.prototype.length=function(){return this._length};var shapePool=(factory=poolFactory(4,(function(){return new ShapePath}),(function(t){var e,r=t._length;for(e=0;e<r;e+=1)pointPool.release(t.v[e]),pointPool.release(t.i[e]),pointPool.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1})),factory.clone=function(t){var e,r=factory.newElement(),i=void 0===t._length?t.v.length:t._length;for(r.setLength(i),r.c=t.c,e=0;e<i;e+=1)r.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return r},factory),factory;function ShapeCollection(){this._length=0,this._maxLength=4,this.shapes=createSizedArray(this._maxLength)}ShapeCollection.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(createSizedArray(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},ShapeCollection.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)shapePool.release(this.shapes[t]);this._length=0};var shapeCollectionPool=(ob={newShapeCollection:function(){return _length?pool[_length-=1]:new ShapeCollection},release:function(t){var e,r=t._length;for(e=0;e<r;e+=1)shapePool.release(t.shapes[e]);t._length=0,_length===_maxLength&&(pool=pooling.double(pool),_maxLength*=2),pool[_length]=t,_length+=1}},_length=0,_maxLength=4,pool=createSizedArray(_maxLength),ob),ob,_length,_maxLength,pool,ShapePropertyFactory=function(){var t=-999999;function e(t,e,r){var i,s,a,n,o,h,l,p,f,c=r.lastIndex,m=this.keyframes;if(t<m[0].t-this.offsetTime)i=m[0].s[0],a=!0,c=0;else if(t>=m[m.length-1].t-this.offsetTime)i=m[m.length-1].s?m[m.length-1].s[0]:m[m.length-2].e[0],a=!0;else{for(var u,d,y,g=c,v=m.length-1,b=!0;b&&(u=m[g],!((d=m[g+1]).t-this.offsetTime>t));)g<v-1?g+=1:b=!1;if(y=this.keyframesMetadata[g]||{},c=g,!(a=1===u.h)){if(t>=d.t-this.offsetTime)p=1;else if(t<u.t-this.offsetTime)p=0;else{var P;y.__fnct?P=y.__fnct:(P=BezierFactory.getBezierEasing(u.o.x,u.o.y,u.i.x,u.i.y).get,y.__fnct=P),p=P((t-(u.t-this.offsetTime))/(d.t-this.offsetTime-(u.t-this.offsetTime)))}s=d.s?d.s[0]:u.e[0]}i=u.s[0]}for(h=e._length,l=i.i[0].length,r.lastIndex=c,n=0;n<h;n+=1)for(o=0;o<l;o+=1)f=a?i.i[n][o]:i.i[n][o]+(s.i[n][o]-i.i[n][o])*p,e.i[n][o]=f,f=a?i.o[n][o]:i.o[n][o]+(s.o[n][o]-i.o[n][o])*p,e.o[n][o]=f,f=a?i.v[n][o]:i.v[n][o]+(s.v[n][o]-i.v[n][o])*p,e.v[n][o]=f}function r(){var e=this.comp.renderedFrame-this.offsetTime,r=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime,s=this._caching.lastFrame;return s!==t&&(s<r&&e<r||s>i&&e>i)||(this._caching.lastIndex=s<e?this._caching.lastIndex:0,this.interpolateShape(e,this.pv,this._caching)),this._caching.lastFrame=e,this.pv}function i(){this.paths=this.localShapeCollection}function s(t){(function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var r,i=t._length;for(r=0;r<i;r+=1)if(t.v[r][0]!==e.v[r][0]||t.v[r][1]!==e.v[r][1]||t.o[r][0]!==e.o[r][0]||t.o[r][1]!==e.o[r][1]||t.i[r][0]!==e.i[r][0]||t.i[r][1]!==e.i[r][1])return!1;return!0})(this.v,t)||(this.v=shapePool.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function a(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t,e;this.lock=!0,this._mdf=!1,t=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k;var r=this.effectsSequence.length;for(e=0;e<r;e+=1)t=this.effectsSequence[e](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function n(t,e,r){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var s=3===r?e.pt.k:e.ks.k;this.v=shapePool.clone(s),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=i,this.effectsSequence=[]}function o(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function h(e,s,a){this.propType="shape",this.comp=e.comp,this.elem=e,this.container=e,this.offsetTime=e.data.st,this.keyframes=3===a?s.pt.k:s.ks.k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;var n=this.keyframes[0].s[0].i.length;this.v=shapePool.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,n),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=t,this.reset=i,this._caching={lastFrame:t,lastIndex:0},this.effectsSequence=[r.bind(this)]}n.prototype.interpolateShape=e,n.prototype.getValue=a,n.prototype.setVValue=s,n.prototype.addEffect=o,h.prototype.getValue=a,h.prototype.interpolateShape=e,h.prototype.setVValue=s,h.prototype.addEffect=o;var l=function(){var t=roundCorner;function e(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}return e.prototype={reset:i,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var e=this.p.v[0],r=this.p.v[1],i=this.s.v[0]/2,s=this.s.v[1]/2,a=3!==this.d,n=this.v;n.v[0][0]=e,n.v[0][1]=r-s,n.v[1][0]=a?e+i:e-i,n.v[1][1]=r,n.v[2][0]=e,n.v[2][1]=r+s,n.v[3][0]=a?e-i:e+i,n.v[3][1]=r,n.i[0][0]=a?e-i*t:e+i*t,n.i[0][1]=r-s,n.i[1][0]=a?e+i:e-i,n.i[1][1]=r-s*t,n.i[2][0]=a?e+i*t:e-i*t,n.i[2][1]=r+s,n.i[3][0]=a?e-i:e+i,n.i[3][1]=r+s*t,n.o[0][0]=a?e+i*t:e-i*t,n.o[0][1]=r-s,n.o[1][0]=a?e+i:e-i,n.o[1][1]=r+s*t,n.o[2][0]=a?e-i*t:e+i*t,n.o[2][1]=r+s,n.o[3][0]=a?e-i:e+i,n.o[3][1]=r-s*t}},extendPrototype([DynamicPropertyContainer],e),e}(),p=function(){function t(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=PropertyFactory.getProp(t,e.ir,0,0,this),this.is=PropertyFactory.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=PropertyFactory.getProp(t,e.pt,0,0,this),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,degToRads,this),this.or=PropertyFactory.getProp(t,e.or,0,0,this),this.os=PropertyFactory.getProp(t,e.os,0,.01,this),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}return t.prototype={reset:i,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,r,i,s=2*Math.floor(this.pt.v),a=2*Math.PI/s,n=!0,o=this.or.v,h=this.ir.v,l=this.os.v,p=this.is.v,f=2*Math.PI*o/(2*s),c=2*Math.PI*h/(2*s),m=-Math.PI/2;m+=this.r.v;var u=3===this.data.d?-1:1;for(this.v._length=0,t=0;t<s;t+=1){r=n?l:p,i=n?f:c;var d=(e=n?o:h)*Math.cos(m),y=e*Math.sin(m),g=0===d&&0===y?0:y/Math.sqrt(d*d+y*y),v=0===d&&0===y?0:-d/Math.sqrt(d*d+y*y);d+=+this.p.v[0],y+=+this.p.v[1],this.v.setTripleAt(d,y,d-g*i*r*u,y-v*i*r*u,d+g*i*r*u,y+v*i*r*u,t,!0),n=!n,m+=a*u}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),r=2*Math.PI/e,i=this.or.v,s=this.os.v,a=2*Math.PI*i/(4*e),n=.5*-Math.PI,o=3===this.data.d?-1:1;for(n+=this.r.v,this.v._length=0,t=0;t<e;t+=1){var h=i*Math.cos(n),l=i*Math.sin(n),p=0===h&&0===l?0:l/Math.sqrt(h*h+l*l),f=0===h&&0===l?0:-h/Math.sqrt(h*h+l*l);h+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(h,l,h-p*a*s*o,l-f*a*s*o,h+p*a*s*o,l+f*a*s*o,t,!0),n+=r*o}this.paths.length=0,this.paths[0]=this.v}},extendPrototype([DynamicPropertyContainer],t),t}(),f=function(){function t(t,e){this.v=shapePool.newElement(),this.v.c=!0,this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}return t.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],r=this.s.v[0]/2,i=this.s.v[1]/2,s=bmMin(r,i,this.r.v),a=s*(1-roundCorner);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+r,e-i+s,t+r,e-i+s,t+r,e-i+a,0,!0),this.v.setTripleAt(t+r,e+i-s,t+r,e+i-a,t+r,e+i-s,1,!0),0!==s?(this.v.setTripleAt(t+r-s,e+i,t+r-s,e+i,t+r-a,e+i,2,!0),this.v.setTripleAt(t-r+s,e+i,t-r+a,e+i,t-r+s,e+i,3,!0),this.v.setTripleAt(t-r,e+i-s,t-r,e+i-s,t-r,e+i-a,4,!0),this.v.setTripleAt(t-r,e-i+s,t-r,e-i+a,t-r,e-i+s,5,!0),this.v.setTripleAt(t-r+s,e-i,t-r+s,e-i,t-r+a,e-i,6,!0),this.v.setTripleAt(t+r-s,e-i,t+r-a,e-i,t+r-s,e-i,7,!0)):(this.v.setTripleAt(t-r,e+i,t-r+a,e+i,t-r,e+i,2),this.v.setTripleAt(t-r,e-i,t-r,e-i+a,t-r,e-i,3))):(this.v.setTripleAt(t+r,e-i+s,t+r,e-i+a,t+r,e-i+s,0,!0),0!==s?(this.v.setTripleAt(t+r-s,e-i,t+r-s,e-i,t+r-a,e-i,1,!0),this.v.setTripleAt(t-r+s,e-i,t-r+a,e-i,t-r+s,e-i,2,!0),this.v.setTripleAt(t-r,e-i+s,t-r,e-i+s,t-r,e-i+a,3,!0),this.v.setTripleAt(t-r,e+i-s,t-r,e+i-a,t-r,e+i-s,4,!0),this.v.setTripleAt(t-r+s,e+i,t-r+s,e+i,t-r+a,e+i,5,!0),this.v.setTripleAt(t+r-s,e+i,t+r-a,e+i,t+r-s,e+i,6,!0),this.v.setTripleAt(t+r,e+i-s,t+r,e+i-s,t+r,e+i-a,7,!0)):(this.v.setTripleAt(t-r,e-i,t-r+a,e-i,t-r,e-i,1,!0),this.v.setTripleAt(t-r,e+i,t-r,e+i-a,t-r,e+i,2,!0),this.v.setTripleAt(t+r,e+i,t+r-a,e+i,t+r,e+i,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:i},extendPrototype([DynamicPropertyContainer],t),t}();var c={getShapeProp:function(t,e,r){var i;return 3===r||4===r?i=(3===r?e.pt:e.ks).k.length?new h(t,e,r):new n(t,e,r):5===r?i=new f(t,e):6===r?i=new l(t,e):7===r&&(i=new p(t,e)),i.k&&t.addDynamicProperty(i),i},getConstructorFunction:function(){return n},getKeyframedConstructorFunction:function(){return h}};return c}(),Matrix=function(){var t=Math.cos,e=Math.sin,r=Math.tan,i=Math.round;function s(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function a(r){if(0===r)return this;var i=t(r),s=e(r);return this._t(i,-s,0,0,s,i,0,0,0,0,1,0,0,0,0,1)}function n(r){if(0===r)return this;var i=t(r),s=e(r);return this._t(1,0,0,0,0,i,-s,0,0,s,i,0,0,0,0,1)}function o(r){if(0===r)return this;var i=t(r),s=e(r);return this._t(i,0,s,0,0,1,0,0,-s,0,i,0,0,0,0,1)}function h(r){if(0===r)return this;var i=t(r),s=e(r);return this._t(i,-s,0,0,s,i,0,0,0,0,1,0,0,0,0,1)}function l(t,e){return this._t(1,e,t,1,0,0)}function p(t,e){return this.shear(r(t),r(e))}function f(i,s){var a=t(s),n=e(s);return this._t(a,n,0,0,-n,a,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,r(i),1,0,0,0,0,1,0,0,0,0,1)._t(a,-n,0,0,n,a,0,0,0,0,1,0,0,0,0,1)}function c(t,e,r){return r||0===r||(r=1),1===t&&1===e&&1===r?this:this._t(t,0,0,0,0,e,0,0,0,0,r,0,0,0,0,1)}function m(t,e,r,i,s,a,n,o,h,l,p,f,c,m,u,d){return this.props[0]=t,this.props[1]=e,this.props[2]=r,this.props[3]=i,this.props[4]=s,this.props[5]=a,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=l,this.props[10]=p,this.props[11]=f,this.props[12]=c,this.props[13]=m,this.props[14]=u,this.props[15]=d,this}function u(t,e,r){return r=r||0,0!==t||0!==e||0!==r?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,r,1):this}function d(t,e,r,i,s,a,n,o,h,l,p,f,c,m,u,d){var y=this.props;if(1===t&&0===e&&0===r&&0===i&&0===s&&1===a&&0===n&&0===o&&0===h&&0===l&&1===p&&0===f)return y[12]=y[12]*t+y[15]*c,y[13]=y[13]*a+y[15]*m,y[14]=y[14]*p+y[15]*u,y[15]*=d,this._identityCalculated=!1,this;var g=y[0],v=y[1],b=y[2],P=y[3],S=y[4],_=y[5],E=y[6],x=y[7],A=y[8],M=y[9],T=y[10],k=y[11],F=y[12],I=y[13],D=y[14],C=y[15];return y[0]=g*t+v*s+b*h+P*c,y[1]=g*e+v*a+b*l+P*m,y[2]=g*r+v*n+b*p+P*u,y[3]=g*i+v*o+b*f+P*d,y[4]=S*t+_*s+E*h+x*c,y[5]=S*e+_*a+E*l+x*m,y[6]=S*r+_*n+E*p+x*u,y[7]=S*i+_*o+E*f+x*d,y[8]=A*t+M*s+T*h+k*c,y[9]=A*e+M*a+T*l+k*m,y[10]=A*r+M*n+T*p+k*u,y[11]=A*i+M*o+T*f+k*d,y[12]=F*t+I*s+D*h+C*c,y[13]=F*e+I*a+D*l+C*m,y[14]=F*r+I*n+D*p+C*u,y[15]=F*i+I*o+D*f+C*d,this._identityCalculated=!1,this}function y(t){var e=t.props;return this.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}function g(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function v(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function b(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function P(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function S(t,e,r){return{x:t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]}}function _(t,e,r){return t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12]}function E(t,e,r){return t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13]}function x(t,e,r){return t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]}function A(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,r=-this.props[1]/t,i=-this.props[4]/t,s=this.props[0]/t,a=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,n=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,o=new Matrix;return o.props[0]=e,o.props[1]=r,o.props[4]=i,o.props[5]=s,o.props[12]=a,o.props[13]=n,o}function M(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function T(t){var e,r=t.length,i=[];for(e=0;e<r;e+=1)i[e]=M(t[e]);return i}function k(t,e,r){var i=createTypedArray("float32",6);if(this.isIdentity())i[0]=t[0],i[1]=t[1],i[2]=e[0],i[3]=e[1],i[4]=r[0],i[5]=r[1];else{var s=this.props[0],a=this.props[1],n=this.props[4],o=this.props[5],h=this.props[12],l=this.props[13];i[0]=t[0]*s+t[1]*n+h,i[1]=t[0]*a+t[1]*o+l,i[2]=e[0]*s+e[1]*n+h,i[3]=e[0]*a+e[1]*o+l,i[4]=r[0]*s+r[1]*n+h,i[5]=r[0]*a+r[1]*o+l}return i}function F(t,e,r){return this.isIdentity()?[t,e,r]:[t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]]}function I(t,e){if(this.isIdentity())return t+","+e;var r=this.props;return Math.round(100*(t*r[0]+e*r[4]+r[12]))/100+","+Math.round(100*(t*r[1]+e*r[5]+r[13]))/100}function D(){for(var t=0,e=this.props,r="matrix3d(";t<16;)r+=i(1e4*e[t])/1e4,r+=15===t?")":",",t+=1;return r}function C(t){return t<1e-6&&t>0||t>-1e-6&&t<0?i(1e4*t)/1e4:t}function w(){var t=this.props;return"matrix("+C(t[0])+","+C(t[1])+","+C(t[4])+","+C(t[5])+","+C(t[12])+","+C(t[13])+")"}return function(){this.reset=s,this.rotate=a,this.rotateX=n,this.rotateY=o,this.rotateZ=h,this.skew=p,this.skewFromAxis=f,this.shear=l,this.scale=c,this.setTransform=m,this.translate=u,this.transform=d,this.multiply=y,this.applyToPoint=S,this.applyToX=_,this.applyToY=E,this.applyToZ=x,this.applyToPointArray=F,this.applyToTriplePoints=k,this.applyToPointStringified=I,this.toCSS=D,this.to2dCSS=w,this.clone=b,this.cloneFromProps=P,this.equals=v,this.inversePoints=T,this.inversePoint=M,this.getInverseMatrix=A,this._t=this.transform,this.isIdentity=g,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}}();function _typeof$3(t){return _typeof$3="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$3(t)}var lottie={},standalone="__[STANDALONE]__",animationData="__[ANIMATIONDATA]__",renderer="";function setLocation(t){setLocationHref(t)}function searchAnimations(){!0===standalone?animationManager.searchAnimations(animationData,standalone,renderer):animationManager.searchAnimations()}function setSubframeRendering(t){setSubframeEnabled(t)}function setPrefix(t){setIdPrefix(t)}function loadAnimation(t){return!0===standalone&&(t.animationData=JSON.parse(animationData)),animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":setDefaultCurveSegments(200);break;default:case"medium":setDefaultCurveSegments(50);break;case"low":setDefaultCurveSegments(10)}else!isNaN(t)&&t>1&&setDefaultCurveSegments(t);getDefaultCurveSegments()>=50?roundValues(!1):roundValues(!0)}function inBrowser(){return"undefined"!=typeof navigator}function installPlugin(t,e){"expressions"===t&&setExpressionsPlugin(e)}function getFactory(t){switch(t){case"propertyFactory":return PropertyFactory;case"shapePropertyFactory":return ShapePropertyFactory;case"matrix":return Matrix;default:return null}}function checkReady(){"complete"===document.readyState&&(clearInterval(readyStateCheckInterval),searchAnimations())}function getQueryVariable(t){for(var e=queryString.split("&"),r=0;r<e.length;r+=1){var i=e[r].split("=");if(decodeURIComponent(i[0])==t)return decodeURIComponent(i[1])}return null}lottie.play=animationManager.play,lottie.pause=animationManager.pause,lottie.setLocationHref=setLocation,lottie.togglePause=animationManager.togglePause,lottie.setSpeed=animationManager.setSpeed,lottie.setDirection=animationManager.setDirection,lottie.stop=animationManager.stop,lottie.searchAnimations=searchAnimations,lottie.registerAnimation=animationManager.registerAnimation,lottie.loadAnimation=loadAnimation,lottie.setSubframeRendering=setSubframeRendering,lottie.resize=animationManager.resize,lottie.goToAndStop=animationManager.goToAndStop,lottie.destroy=animationManager.destroy,lottie.setQuality=setQuality,lottie.inBrowser=inBrowser,lottie.installPlugin=installPlugin,lottie.freeze=animationManager.freeze,lottie.unfreeze=animationManager.unfreeze,lottie.setVolume=animationManager.setVolume,lottie.mute=animationManager.mute,lottie.unmute=animationManager.unmute,lottie.getRegisteredAnimations=animationManager.getRegisteredAnimations,lottie.useWebWorker=setWebWorker,lottie.setIDPrefix=setPrefix,lottie.__getFactory=getFactory,lottie.version="5.12.2";var queryString="";if(standalone){var scripts=document.getElementsByTagName("script"),index=scripts.length-1,myScript=scripts[index]||{src:""};queryString=myScript.src?myScript.src.replace(/^[^\?]+\??/,""):"",renderer=getQueryVariable("renderer")}var readyStateCheckInterval=setInterval(checkReady,100);try{"object"===("undefined"==typeof exports?"undefined":_typeof$3(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=lottie)}catch(t){}var ShapeModifiers=function(){var t={},e={};return t.registerModifier=function(t,r){e[t]||(e[t]=r)},t.getModifier=function(t,r,i){return new e[t](r,i)},t}();function ShapeModifier(){}function TrimModifier(){}function PuckerAndBloatModifier(){}ShapeModifier.prototype.initModifierProperties=function(){},ShapeModifier.prototype.addShapeToModifier=function(){},ShapeModifier.prototype.addShape=function(t){if(!this.closed){t.sh.container.addDynamicProperty(t.sh);var e={shape:t.sh,data:t,localShapeCollection:shapeCollectionPool.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},ShapeModifier.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=initialDefaultFrame,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},ShapeModifier.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},extendPrototype([DynamicPropertyContainer],ShapeModifier),extendPrototype([ShapeModifier],TrimModifier),TrimModifier.prototype.initModifierProperties=function(t,e){this.s=PropertyFactory.getProp(t,e.s,0,.01,this),this.e=PropertyFactory.getProp(t,e.e,0,.01,this),this.o=PropertyFactory.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},TrimModifier.prototype.addShapeToModifier=function(t){t.pathsData=[]},TrimModifier.prototype.calculateShapeEdges=function(t,e,r,i,s){var a=[];e<=1?a.push({s:t,e:e}):t>=1?a.push({s:t-1,e:e-1}):(a.push({s:t,e:1}),a.push({s:0,e:e-1}));var n,o,h=[],l=a.length;for(n=0;n<l;n+=1){var p,f;if(!((o=a[n]).e*s<i||o.s*s>i+r))p=o.s*s<=i?0:(o.s*s-i)/r,f=o.e*s>=i+r?1:(o.e*s-i)/r,h.push([p,f])}return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){var e,r=t.length;for(e=0;e<r;e+=1)segmentsLengthPool.release(t[e]);return t.length=0,t},TrimModifier.prototype.processShapes=function(t){var e,r,i,s;if(this._mdf||t){var a=this.o.v%360/360;if(a<0&&(a+=1),(e=this.s.v>1?1+a:this.s.v<0?0+a:this.s.v+a)>(r=this.e.v>1?1+a:this.e.v<0?0+a:this.e.v+a)){var n=e;e=r,r=n}e=1e-4*Math.round(1e4*e),r=1e-4*Math.round(1e4*r),this.sValue=e,this.eValue=r}else e=this.sValue,r=this.eValue;var o,h,l,p,f,c=this.shapes.length,m=0;if(r===e)for(s=0;s<c;s+=1)this.shapes[s].localShapeCollection.releaseShapes(),this.shapes[s].shape._mdf=!0,this.shapes[s].shape.paths=this.shapes[s].localShapeCollection,this._mdf&&(this.shapes[s].pathsData.length=0);else if(1===r&&0===e||0===r&&1===e){if(this._mdf)for(s=0;s<c;s+=1)this.shapes[s].pathsData.length=0,this.shapes[s].shape._mdf=!0}else{var u,d,y=[];for(s=0;s<c;s+=1)if((u=this.shapes[s]).shape._mdf||this._mdf||t||2===this.m){if(h=(i=u.shape.paths)._length,f=0,!u.shape._mdf&&u.pathsData.length)f=u.totalShapeLength;else{for(l=this.releasePathsData(u.pathsData),o=0;o<h;o+=1)p=bez.getSegmentsLength(i.shapes[o]),l.push(p),f+=p.totalLength;u.totalShapeLength=f,u.pathsData=l}m+=f,u.shape._mdf=!0}else u.shape.paths=u.localShapeCollection;var g,v=e,b=r,P=0;for(s=c-1;s>=0;s-=1)if((u=this.shapes[s]).shape._mdf){for((d=u.localShapeCollection).releaseShapes(),2===this.m&&c>1?(g=this.calculateShapeEdges(e,r,u.totalShapeLength,P,m),P+=u.totalShapeLength):g=[[v,b]],h=g.length,o=0;o<h;o+=1){v=g[o][0],b=g[o][1],y.length=0,b<=1?y.push({s:u.totalShapeLength*v,e:u.totalShapeLength*b}):v>=1?y.push({s:u.totalShapeLength*(v-1),e:u.totalShapeLength*(b-1)}):(y.push({s:u.totalShapeLength*v,e:u.totalShapeLength}),y.push({s:0,e:u.totalShapeLength*(b-1)}));var S=this.addShapes(u,y[0]);if(y[0].s!==y[0].e){if(y.length>1)if(u.shape.paths.shapes[u.shape.paths._length-1].c){var _=S.pop();this.addPaths(S,d),S=this.addShapes(u,y[1],_)}else this.addPaths(S,d),S=this.addShapes(u,y[1]);this.addPaths(S,d)}}u.shape.paths=d}}},TrimModifier.prototype.addPaths=function(t,e){var r,i=t.length;for(r=0;r<i;r+=1)e.addShape(t[r])},TrimModifier.prototype.addSegment=function(t,e,r,i,s,a,n){s.setXYAt(e[0],e[1],"o",a),s.setXYAt(r[0],r[1],"i",a+1),n&&s.setXYAt(t[0],t[1],"v",a),s.setXYAt(i[0],i[1],"v",a+1)},TrimModifier.prototype.addSegmentFromArray=function(t,e,r,i){e.setXYAt(t[1],t[5],"o",r),e.setXYAt(t[2],t[6],"i",r+1),i&&e.setXYAt(t[0],t[4],"v",r),e.setXYAt(t[3],t[7],"v",r+1)},TrimModifier.prototype.addShapes=function(t,e,r){var i,s,a,n,o,h,l,p,f=t.pathsData,c=t.shape.paths.shapes,m=t.shape.paths._length,u=0,d=[],y=!0;for(r?(o=r._length,p=r._length):(r=shapePool.newElement(),o=0,p=0),d.push(r),i=0;i<m;i+=1){for(h=f[i].lengths,r.c=c[i].c,a=c[i].c?h.length:h.length+1,s=1;s<a;s+=1)if(u+(n=h[s-1]).addedLength<e.s)u+=n.addedLength,r.c=!1;else{if(u>e.e){r.c=!1;break}e.s<=u&&e.e>=u+n.addedLength?(this.addSegment(c[i].v[s-1],c[i].o[s-1],c[i].i[s],c[i].v[s],r,o,y),y=!1):(l=bez.getNewSegment(c[i].v[s-1],c[i].v[s],c[i].o[s-1],c[i].i[s],(e.s-u)/n.addedLength,(e.e-u)/n.addedLength,h[s-1]),this.addSegmentFromArray(l,r,o,y),y=!1,r.c=!1),u+=n.addedLength,o+=1}if(c[i].c&&h.length){if(n=h[s-1],u<=e.e){var g=h[s-1].addedLength;e.s<=u&&e.e>=u+g?(this.addSegment(c[i].v[s-1],c[i].o[s-1],c[i].i[0],c[i].v[0],r,o,y),y=!1):(l=bez.getNewSegment(c[i].v[s-1],c[i].v[0],c[i].o[s-1],c[i].i[0],(e.s-u)/g,(e.e-u)/g,h[s-1]),this.addSegmentFromArray(l,r,o,y),y=!1,r.c=!1)}else r.c=!1;u+=n.addedLength,o+=1}if(r._length&&(r.setXYAt(r.v[p][0],r.v[p][1],"i",p),r.setXYAt(r.v[r._length-1][0],r.v[r._length-1][1],"o",r._length-1)),u>e.e)break;i<m-1&&(r=shapePool.newElement(),y=!0,d.push(r),o=0)}return d},extendPrototype([ShapeModifier],PuckerAndBloatModifier),PuckerAndBloatModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},PuckerAndBloatModifier.prototype.processPath=function(t,e){var r=e/100,i=[0,0],s=t._length,a=0;for(a=0;a<s;a+=1)i[0]+=t.v[a][0],i[1]+=t.v[a][1];i[0]/=s,i[1]/=s;var n,o,h,l,p,f,c=shapePool.newElement();for(c.c=t.c,a=0;a<s;a+=1)n=t.v[a][0]+(i[0]-t.v[a][0])*r,o=t.v[a][1]+(i[1]-t.v[a][1])*r,h=t.o[a][0]+(i[0]-t.o[a][0])*-r,l=t.o[a][1]+(i[1]-t.o[a][1])*-r,p=t.i[a][0]+(i[0]-t.i[a][0])*-r,f=t.i[a][1]+(i[1]-t.i[a][1])*-r,c.setTripleAt(n,o,h,l,p,f,a);return c},PuckerAndBloatModifier.prototype.processShapes=function(t){var e,r,i,s,a,n,o=this.shapes.length,h=this.amount.v;if(0!==h)for(r=0;r<o;r+=1){if(n=(a=this.shapes[r]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,i=0;i<s;i+=1)n.addShape(this.processPath(e[i],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var TransformPropertyFactory=function(){var t=[0,0];function e(t,e,r){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Matrix,this.pre=new Matrix,this.appliedTransformations=0,this.initDynamicPropertyContainer(r||t),e.p&&e.p.s?(this.px=PropertyFactory.getProp(t,e.p.x,0,0,this),this.py=PropertyFactory.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=PropertyFactory.getProp(t,e.p.z,0,0,this))):this.p=PropertyFactory.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=PropertyFactory.getProp(t,e.rx,0,degToRads,this),this.ry=PropertyFactory.getProp(t,e.ry,0,degToRads,this),this.rz=PropertyFactory.getProp(t,e.rz,0,degToRads,this),e.or.k[0].ti){var i,s=e.or.k.length;for(i=0;i<s;i+=1)e.or.k[i].to=null,e.or.k[i].ti=null}this.or=PropertyFactory.getProp(t,e.or,1,degToRads,this),this.or.sh=!0}else this.r=PropertyFactory.getProp(t,e.r||{k:0},0,degToRads,this);e.sk&&(this.sk=PropertyFactory.getProp(t,e.sk,0,degToRads,this),this.sa=PropertyFactory.getProp(t,e.sa,0,degToRads,this)),this.a=PropertyFactory.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=PropertyFactory.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=PropertyFactory.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return e.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(e){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||e){var r;if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var i,s;if(r=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime)this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(i=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/r,0),s=this.p.getValueAtTime(this.p.keyframes[0].t/r,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(i=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/r,0),s=this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/r,0)):(i=this.p.pv,s=this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/r,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){i=[],s=[];var a=this.px,n=this.py;a._caching.lastFrame+a.offsetTime<=a.keyframes[0].t?(i[0]=a.getValueAtTime((a.keyframes[0].t+.01)/r,0),i[1]=n.getValueAtTime((n.keyframes[0].t+.01)/r,0),s[0]=a.getValueAtTime(a.keyframes[0].t/r,0),s[1]=n.getValueAtTime(n.keyframes[0].t/r,0)):a._caching.lastFrame+a.offsetTime>=a.keyframes[a.keyframes.length-1].t?(i[0]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/r,0),i[1]=n.getValueAtTime(n.keyframes[n.keyframes.length-1].t/r,0),s[0]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/r,0),s[1]=n.getValueAtTime((n.keyframes[n.keyframes.length-1].t-.01)/r,0)):(i=[a.pv,n.pv],s[0]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/r,a.offsetTime),s[1]=n.getValueAtTime((n._caching.lastFrame+n.offsetTime-.01)/r,n.offsetTime))}else i=s=t;this.v.rotate(-Math.atan2(i[1]-s[1],i[0]-s[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],e),e.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},e.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,r,i){return new e(t,r,i)}}}();function RepeaterModifier(){}function RoundCornersModifier(){}function floatEqual(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function floatZero(t){return Math.abs(t)<=1e-5}function lerp(t,e,r){return t*(1-r)+e*r}function lerpPoint(t,e,r){return[lerp(t[0],e[0],r),lerp(t[1],e[1],r)]}function quadRoots(t,e,r){if(0===t)return[];var i=e*e-4*t*r;if(i<0)return[];var s=-e/(2*t);if(0===i)return[s];var a=Math.sqrt(i)/(2*t);return[s-a,s+a]}function polynomialCoefficients(t,e,r,i){return[3*e-t-3*r+i,3*t-6*e+3*r,-3*t+3*e,t]}function singlePoint(t){return new PolynomialBezier(t,t,t,t,!1)}function PolynomialBezier(t,e,r,i,s){s&&pointEqual(t,e)&&(e=lerpPoint(t,i,1/3)),s&&pointEqual(r,i)&&(r=lerpPoint(t,i,2/3));var a=polynomialCoefficients(t[0],e[0],r[0],i[0]),n=polynomialCoefficients(t[1],e[1],r[1],i[1]);this.a=[a[0],n[0]],this.b=[a[1],n[1]],this.c=[a[2],n[2]],this.d=[a[3],n[3]],this.points=[t,e,r,i]}function extrema(t,e){var r=t.points[0][e],i=t.points[t.points.length-1][e];if(r>i){var s=i;i=r,r=s}for(var a=quadRoots(3*t.a[e],2*t.b[e],t.c[e]),n=0;n<a.length;n+=1)if(a[n]>0&&a[n]<1){var o=t.point(a[n])[e];o<r?r=o:o>i&&(i=o)}return{min:r,max:i}}function intersectData(t,e,r){var i=t.boundingBox();return{cx:i.cx,cy:i.cy,width:i.width,height:i.height,bez:t,t:(e+r)/2,t1:e,t2:r}}function splitData(t){var e=t.bez.split(.5);return[intersectData(e[0],t.t1,t.t),intersectData(e[1],t.t,t.t2)]}function boxIntersect(t,e){return 2*Math.abs(t.cx-e.cx)<t.width+e.width&&2*Math.abs(t.cy-e.cy)<t.height+e.height}function intersectsImpl(t,e,r,i,s,a){if(boxIntersect(t,e))if(r>=a||t.width<=i&&t.height<=i&&e.width<=i&&e.height<=i)s.push([t.t,e.t]);else{var n=splitData(t),o=splitData(e);intersectsImpl(n[0],o[0],r+1,i,s,a),intersectsImpl(n[0],o[1],r+1,i,s,a),intersectsImpl(n[1],o[0],r+1,i,s,a),intersectsImpl(n[1],o[1],r+1,i,s,a)}}function crossProduct(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function lineIntersection(t,e,r,i){var s=[t[0],t[1],1],a=[e[0],e[1],1],n=[r[0],r[1],1],o=[i[0],i[1],1],h=crossProduct(crossProduct(s,a),crossProduct(n,o));return floatZero(h[2])?null:[h[0]/h[2],h[1]/h[2]]}function polarOffset(t,e,r){return[t[0]+Math.cos(e)*r,t[1]-Math.sin(e)*r]}function pointDistance(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function pointEqual(t,e){return floatEqual(t[0],e[0])&&floatEqual(t[1],e[1])}function ZigZagModifier(){}function setPoint(t,e,r,i,s,a,n){var o=r-Math.PI/2,h=r+Math.PI/2,l=e[0]+Math.cos(r)*i*s,p=e[1]-Math.sin(r)*i*s;t.setTripleAt(l,p,l+Math.cos(o)*a,p-Math.sin(o)*a,l+Math.cos(h)*n,p-Math.sin(h)*n,t.length())}function getPerpendicularVector(t,e){var r=[e[0]-t[0],e[1]-t[1]],i=.5*-Math.PI;return[Math.cos(i)*r[0]-Math.sin(i)*r[1],Math.sin(i)*r[0]+Math.cos(i)*r[1]]}function getProjectingAngle(t,e){var r=0===e?t.length()-1:e-1,i=(e+1)%t.length(),s=getPerpendicularVector(t.v[r],t.v[i]);return Math.atan2(0,1)-Math.atan2(s[1],s[0])}function zigZagCorner(t,e,r,i,s,a,n){var o=getProjectingAngle(e,r),h=e.v[r%e._length],l=e.v[0===r?e._length-1:r-1],p=e.v[(r+1)%e._length],f=2===a?Math.sqrt(Math.pow(h[0]-l[0],2)+Math.pow(h[1]-l[1],2)):0,c=2===a?Math.sqrt(Math.pow(h[0]-p[0],2)+Math.pow(h[1]-p[1],2)):0;setPoint(t,e.v[r%e._length],o,n,i,c/(2*(s+1)),f/(2*(s+1)),a)}function zigZagSegment(t,e,r,i,s,a){for(var n=0;n<i;n+=1){var o=(n+1)/(i+1),h=2===s?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(o);setPoint(t,e.point(o),l,a,r,h/(2*(i+1)),h/(2*(i+1)),s),a=-a}return a}function linearOffset(t,e,r){var i=Math.atan2(e[0]-t[0],e[1]-t[1]);return[polarOffset(t,i,r),polarOffset(e,i,r)]}function offsetSegment(t,e){var r,i,s,a,n,o,h;r=(h=linearOffset(t.points[0],t.points[1],e))[0],i=h[1],s=(h=linearOffset(t.points[1],t.points[2],e))[0],a=h[1],n=(h=linearOffset(t.points[2],t.points[3],e))[0],o=h[1];var l=lineIntersection(r,i,s,a);null===l&&(l=i);var p=lineIntersection(n,o,s,a);return null===p&&(p=n),new PolynomialBezier(r,l,p,o)}function joinLines(t,e,r,i,s){var a=e.points[3],n=r.points[0];if(3===i)return a;if(pointEqual(a,n))return a;if(2===i){var o=-e.tangentAngle(1),h=-r.tangentAngle(0)+Math.PI,l=lineIntersection(a,polarOffset(a,o+Math.PI/2,100),n,polarOffset(n,o+Math.PI/2,100)),p=l?pointDistance(l,a):pointDistance(a,n)/2,f=polarOffset(a,o,2*p*roundCorner);return t.setXYAt(f[0],f[1],"o",t.length()-1),f=polarOffset(n,h,2*p*roundCorner),t.setTripleAt(n[0],n[1],n[0],n[1],f[0],f[1],t.length()),n}var c=lineIntersection(pointEqual(a,e.points[2])?e.points[0]:e.points[2],a,n,pointEqual(n,r.points[1])?r.points[3]:r.points[1]);return c&&pointDistance(c,a)<s?(t.setTripleAt(c[0],c[1],c[0],c[1],c[0],c[1],t.length()),c):a}function getIntersection(t,e){var r=t.intersections(e);return r.length&&floatEqual(r[0][0],1)&&r.shift(),r.length?r[0]:null}function pruneSegmentIntersection(t,e){var r=t.slice(),i=e.slice(),s=getIntersection(t[t.length-1],e[0]);return s&&(r[t.length-1]=t[t.length-1].split(s[0])[0],i[0]=e[0].split(s[1])[1]),t.length>1&&e.length>1&&(s=getIntersection(t[0],e[e.length-1]))?[[t[0].split(s[0])[0]],[e[e.length-1].split(s[1])[1]]]:[r,i]}function pruneIntersections(t){for(var e,r=1;r<t.length;r+=1)e=pruneSegmentIntersection(t[r-1],t[r]),t[r-1]=e[0],t[r]=e[1];return t.length>1&&(e=pruneSegmentIntersection(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}function offsetSegmentSplit(t,e){var r,i,s,a,n=t.inflectionPoints();if(0===n.length)return[offsetSegment(t,e)];if(1===n.length||floatEqual(n[1],1))return r=(s=t.split(n[0]))[0],i=s[1],[offsetSegment(r,e),offsetSegment(i,e)];r=(s=t.split(n[0]))[0];var o=(n[1]-n[0])/(1-n[0]);return a=(s=s[1].split(o))[0],i=s[1],[offsetSegment(r,e),offsetSegment(a,e),offsetSegment(i,e)]}function OffsetPathModifier(){}function getFontProperties(t){for(var e=t.fStyle?t.fStyle.split(" "):[],r="normal",i="normal",s=e.length,a=0;a<s;a+=1)switch(e[a].toLowerCase()){case"italic":i="italic";break;case"bold":r="700";break;case"black":r="900";break;case"medium":r="500";break;case"regular":case"normal":r="400";break;case"light":case"thin":r="200"}return{style:i,weight:t.fWeight||r}}extendPrototype([ShapeModifier],RepeaterModifier),RepeaterModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=PropertyFactory.getProp(t,e.c,0,null,this),this.o=PropertyFactory.getProp(t,e.o,0,null,this),this.tr=TransformPropertyFactory.getTransformProperty(t,e.tr,this),this.so=PropertyFactory.getProp(t,e.tr.so,0,.01,this),this.eo=PropertyFactory.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Matrix,this.rMatrix=new Matrix,this.sMatrix=new Matrix,this.tMatrix=new Matrix,this.matrix=new Matrix},RepeaterModifier.prototype.applyTransforms=function(t,e,r,i,s,a){var n=a?-1:1,o=i.s.v[0]+(1-i.s.v[0])*(1-s),h=i.s.v[1]+(1-i.s.v[1])*(1-s);t.translate(i.p.v[0]*n*s,i.p.v[1]*n*s,i.p.v[2]),e.translate(-i.a.v[0],-i.a.v[1],i.a.v[2]),e.rotate(-i.r.v*n*s),e.translate(i.a.v[0],i.a.v[1],i.a.v[2]),r.translate(-i.a.v[0],-i.a.v[1],i.a.v[2]),r.scale(a?1/o:o,a?1/h:h),r.translate(i.a.v[0],i.a.v[1],i.a.v[2])},RepeaterModifier.prototype.init=function(t,e,r,i){for(this.elem=t,this.arr=e,this.pos=r,this.elemsData=i,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[r]);r>0;)r-=1,this._elements.unshift(e[r]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){var e,r=t.length;for(e=0;e<r;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},RepeaterModifier.prototype.cloneElements=function(t){var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},RepeaterModifier.prototype.changeGroupRender=function(t,e){var r,i=t.length;for(r=0;r<i;r+=1)t[r]._render=e,"gr"===t[r].ty&&this.changeGroupRender(t[r].it,e)},RepeaterModifier.prototype.processShapes=function(t){var e,r,i,s,a,n=!1;if(this._mdf||t){var o,h=Math.ceil(this.c.v);if(this._groups.length<h){for(;this._groups.length<h;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(a=0,i=0;i<=this._groups.length-1;i+=1){if(o=a<h,this._groups[i]._render=o,this.changeGroupRender(this._groups[i].it,o),!o){var p=this.elemsData[i].it,f=p[p.length-1];0!==f.transform.op.v?(f.transform.op._mdf=!0,f.transform.op.v=0):f.transform.op._mdf=!1}a+=1}this._currentCopies=h;var c=this.o.v,m=c%1,u=c>0?Math.floor(c):Math.ceil(c),d=this.pMatrix.props,y=this.rMatrix.props,g=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var v,b,P=0;if(c>0){for(;P<u;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),P+=1;m&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,m,!1),P+=m)}else if(c<0){for(;P>u;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),P-=1;m&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-m,!0),P-=m)}for(i=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(b=(r=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(i/(this._currentCopies-1)),0!==P){for((0!==i&&1===s||i!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]),this.matrix.transform(d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9],d[10],d[11],d[12],d[13],d[14],d[15]),v=0;v<b;v+=1)r[v]=this.matrix.props[v];this.matrix.reset()}else for(this.matrix.reset(),v=0;v<b;v+=1)r[v]=this.matrix.props[v];P+=1,a-=1,i+=s}}else for(a=this._currentCopies,i=0,s=1;a;)r=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,a-=1,i+=s;return n},RepeaterModifier.prototype.addShape=function(){},extendPrototype([ShapeModifier],RoundCornersModifier),RoundCornersModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=PropertyFactory.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},RoundCornersModifier.prototype.processPath=function(t,e){var r,i=shapePool.newElement();i.c=t.c;var s,a,n,o,h,l,p,f,c,m,u,d,y=t._length,g=0;for(r=0;r<y;r+=1)s=t.v[r],n=t.o[r],a=t.i[r],s[0]===n[0]&&s[1]===n[1]&&s[0]===a[0]&&s[1]===a[1]?0!==r&&r!==y-1||t.c?(o=0===r?t.v[y-1]:t.v[r-1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=u=s[0]+(o[0]-s[0])*l,f=d=s[1]-(s[1]-o[1])*l,c=p-(p-s[0])*roundCorner,m=f-(f-s[1])*roundCorner,i.setTripleAt(p,f,c,m,u,d,g),g+=1,o=r===y-1?t.v[0]:t.v[r+1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=c=s[0]+(o[0]-s[0])*l,f=m=s[1]+(o[1]-s[1])*l,u=p-(p-s[0])*roundCorner,d=f-(f-s[1])*roundCorner,i.setTripleAt(p,f,c,m,u,d,g),g+=1):(i.setTripleAt(s[0],s[1],n[0],n[1],a[0],a[1],g),g+=1):(i.setTripleAt(t.v[r][0],t.v[r][1],t.o[r][0],t.o[r][1],t.i[r][0],t.i[r][1],g),g+=1);return i},RoundCornersModifier.prototype.processShapes=function(t){var e,r,i,s,a,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(r=0;r<o;r+=1){if(n=(a=this.shapes[r]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,i=0;i<s;i+=1)n.addShape(this.processPath(e[i],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},PolynomialBezier.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},PolynomialBezier.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},PolynomialBezier.prototype.tangentAngle=function(t){var e=this.derivative(t);return Math.atan2(e[1],e[0])},PolynomialBezier.prototype.normalAngle=function(t){var e=this.derivative(t);return Math.atan2(e[0],e[1])},PolynomialBezier.prototype.inflectionPoints=function(){var t=this.a[1]*this.b[0]-this.a[0]*this.b[1];if(floatZero(t))return[];var e=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/t,r=e*e-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/t;if(r<0)return[];var i=Math.sqrt(r);return floatZero(i)?i>0&&i<1?[e]:[]:[e-i,e+i].filter((function(t){return t>0&&t<1}))},PolynomialBezier.prototype.split=function(t){if(t<=0)return[singlePoint(this.points[0]),this];if(t>=1)return[this,singlePoint(this.points[this.points.length-1])];var e=lerpPoint(this.points[0],this.points[1],t),r=lerpPoint(this.points[1],this.points[2],t),i=lerpPoint(this.points[2],this.points[3],t),s=lerpPoint(e,r,t),a=lerpPoint(r,i,t),n=lerpPoint(s,a,t);return[new PolynomialBezier(this.points[0],e,s,n,!0),new PolynomialBezier(n,a,i,this.points[3],!0)]},PolynomialBezier.prototype.bounds=function(){return{x:extrema(this,0),y:extrema(this,1)}},PolynomialBezier.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},PolynomialBezier.prototype.intersections=function(t,e,r){void 0===e&&(e=2),void 0===r&&(r=7);var i=[];return intersectsImpl(intersectData(this,0,1),intersectData(t,0,1),0,e,i,r),i},PolynomialBezier.shapeSegment=function(t,e){var r=(e+1)%t.length();return new PolynomialBezier(t.v[e],t.o[e],t.i[r],t.v[r],!0)},PolynomialBezier.shapeSegmentInverted=function(t,e){var r=(e+1)%t.length();return new PolynomialBezier(t.v[r],t.i[r],t.o[e],t.v[e],!0)},extendPrototype([ShapeModifier],ZigZagModifier),ZigZagModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=PropertyFactory.getProp(t,e.s,0,null,this),this.frequency=PropertyFactory.getProp(t,e.r,0,null,this),this.pointsType=PropertyFactory.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},ZigZagModifier.prototype.processPath=function(t,e,r,i){var s=t._length,a=shapePool.newElement();if(a.c=t.c,t.c||(s-=1),0===s)return a;var n=-1,o=PolynomialBezier.shapeSegment(t,0);zigZagCorner(a,t,0,e,r,i,n);for(var h=0;h<s;h+=1)n=zigZagSegment(a,o,e,r,i,-n),o=h!==s-1||t.c?PolynomialBezier.shapeSegment(t,(h+1)%s):null,zigZagCorner(a,t,h+1,e,r,i,n);return a},ZigZagModifier.prototype.processShapes=function(t){var e,r,i,s,a,n,o=this.shapes.length,h=this.amplitude.v,l=Math.max(0,Math.round(this.frequency.v)),p=this.pointsType.v;if(0!==h)for(r=0;r<o;r+=1){if(n=(a=this.shapes[r]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,i=0;i<s;i+=1)n.addShape(this.processPath(e[i],h,l,p));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},extendPrototype([ShapeModifier],OffsetPathModifier),OffsetPathModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this.miterLimit=PropertyFactory.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},OffsetPathModifier.prototype.processPath=function(t,e,r,i){var s=shapePool.newElement();s.c=t.c;var a,n,o,h=t.length();t.c||(h-=1);var l=[];for(a=0;a<h;a+=1)o=PolynomialBezier.shapeSegment(t,a),l.push(offsetSegmentSplit(o,e));if(!t.c)for(a=h-1;a>=0;a-=1)o=PolynomialBezier.shapeSegmentInverted(t,a),l.push(offsetSegmentSplit(o,e));l=pruneIntersections(l);var p=null,f=null;for(a=0;a<l.length;a+=1){var c=l[a];for(f&&(p=joinLines(s,f,c[0],r,i)),f=c[c.length-1],n=0;n<c.length;n+=1)o=c[n],p&&pointEqual(o.points[0],p)?s.setXYAt(o.points[1][0],o.points[1][1],"o",s.length()-1):s.setTripleAt(o.points[0][0],o.points[0][1],o.points[1][0],o.points[1][1],o.points[0][0],o.points[0][1],s.length()),s.setTripleAt(o.points[3][0],o.points[3][1],o.points[3][0],o.points[3][1],o.points[2][0],o.points[2][1],s.length()),p=o.points[3]}return l.length&&joinLines(s,f,l[0][0],r,i),s},OffsetPathModifier.prototype.processShapes=function(t){var e,r,i,s,a,n,o=this.shapes.length,h=this.amount.v,l=this.miterLimit.v,p=this.lineJoin;if(0!==h)for(r=0;r<o;r+=1){if(n=(a=this.shapes[r]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,i=0;i<s;i+=1)n.addShape(this.processPath(e[i],h,p,l));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var FontManager=function(){var t={w:0,size:0,shapes:[],data:{shapes:[]}},e=[];e=e.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);var r=127988,i=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function s(t,e){var r=createTag("span");r.setAttribute("aria-hidden",!0),r.style.fontFamily=e;var i=createTag("span");i.innerText="giItT1WQy@!-/#",r.style.position="absolute",r.style.left="-10000px",r.style.top="-10000px",r.style.fontSize="300px",r.style.fontVariant="normal",r.style.fontStyle="normal",r.style.fontWeight="normal",r.style.letterSpacing="0",r.appendChild(i),document.body.appendChild(r);var s=i.offsetWidth;return i.style.fontFamily=function(t){var e,r=t.split(","),i=r.length,s=[];for(e=0;e<i;e+=1)"sans-serif"!==r[e]&&"monospace"!==r[e]&&s.push(r[e]);return s.join(",")}(t)+", "+e,{node:i,w:s,parent:r}}function a(t,e){var r,i=document.body&&e?"svg":"canvas",s=getFontProperties(t);if("svg"===i){var a=createNS("text");a.style.fontSize="100px",a.setAttribute("font-family",t.fFamily),a.setAttribute("font-style",s.style),a.setAttribute("font-weight",s.weight),a.textContent="1",t.fClass?(a.style.fontFamily="inherit",a.setAttribute("class",t.fClass)):a.style.fontFamily=t.fFamily,e.appendChild(a),r=a}else{var n=new OffscreenCanvas(500,500).getContext("2d");n.font=s.style+" "+s.weight+" 100px "+t.fFamily,r=n}return{measureText:function(t){return"svg"===i?(r.textContent=t,r.getComputedTextLength()):r.measureText(t).width}}}function n(t){var e=0,r=t.charCodeAt(0);if(r>=55296&&r<=56319){var i=t.charCodeAt(1);i>=56320&&i<=57343&&(e=1024*(r-55296)+i-56320+65536)}return e}function o(t){var e=n(t);return e>=127462&&e<=127487}var h=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)};h.isModifier=function(t,e){var r=t.toString(16)+e.toString(16);return-1!==i.indexOf(r)},h.isZeroWidthJoiner=function(t){return 8205===t},h.isFlagEmoji=function(t){return o(t.substr(0,2))&&o(t.substr(2,2))},h.isRegionalCode=o,h.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},h.isRegionalFlag=function(t,e){var i=n(t.substr(e,2));if(i!==r)return!1;var s=0;for(e+=2;s<5;){if((i=n(t.substr(e,2)))<917601||i>917626)return!1;s+=1,e+=2}return 917631===n(t.substr(e,2))},h.isVariationSelector=function(t){return 65039===t},h.BLACK_FLAG_CODE_POINT=r;var l={addChars:function(t){if(t){var e;this.chars||(this.chars=[]);var r,i,s=t.length,a=this.chars.length;for(e=0;e<s;e+=1){for(r=0,i=!1;r<a;)this.chars[r].style===t[e].style&&this.chars[r].fFamily===t[e].fFamily&&this.chars[r].ch===t[e].ch&&(i=!0),r+=1;i||(this.chars.push(t[e]),a+=1)}}},addFonts:function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);if(!document.body)return this.isLoaded=!0,t.list.forEach((function(t){t.helper=a(t),t.cache={}})),void(this.fonts=t.list);var r,i=t.list,n=i.length,o=n;for(r=0;r<n;r+=1){var h,l,p=!0;if(i[r].loaded=!1,i[r].monoCase=s(i[r].fFamily,"monospace"),i[r].sansCase=s(i[r].fFamily,"sans-serif"),i[r].fPath){if("p"===i[r].fOrigin||3===i[r].origin){if((h=document.querySelectorAll('style[f-forigin="p"][f-family="'+i[r].fFamily+'"], style[f-origin="3"][f-family="'+i[r].fFamily+'"]')).length>0&&(p=!1),p){var f=createTag("style");f.setAttribute("f-forigin",i[r].fOrigin),f.setAttribute("f-origin",i[r].origin),f.setAttribute("f-family",i[r].fFamily),f.type="text/css",f.innerText="@font-face {font-family: "+i[r].fFamily+"; font-style: normal; src: url('"+i[r].fPath+"');}",e.appendChild(f)}}else if("g"===i[r].fOrigin||1===i[r].origin){for(h=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),l=0;l<h.length;l+=1)-1!==h[l].href.indexOf(i[r].fPath)&&(p=!1);if(p){var c=createTag("link");c.setAttribute("f-forigin",i[r].fOrigin),c.setAttribute("f-origin",i[r].origin),c.type="text/css",c.rel="stylesheet",c.href=i[r].fPath,document.body.appendChild(c)}}else if("t"===i[r].fOrigin||2===i[r].origin){for(h=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),l=0;l<h.length;l+=1)i[r].fPath===h[l].src&&(p=!1);if(p){var m=createTag("link");m.setAttribute("f-forigin",i[r].fOrigin),m.setAttribute("f-origin",i[r].origin),m.setAttribute("rel","stylesheet"),m.setAttribute("href",i[r].fPath),e.appendChild(m)}}}else i[r].loaded=!0,o-=1;i[r].helper=a(i[r],e),i[r].cache={},this.fonts.push(i[r])}0===o?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},getCharData:function(e,r,i){for(var s=0,a=this.chars.length;s<a;){if(this.chars[s].ch===e&&this.chars[s].style===r&&this.chars[s].fFamily===i)return this.chars[s];s+=1}return("string"==typeof e&&13!==e.charCodeAt(0)||!e)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",e,r,i)),t},getFontByName:function(t){for(var e=0,r=this.fonts.length;e<r;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,r){var i=this.getFontByName(e),s=t;if(!i.cache[s]){var a=i.helper;if(" "===t){var n=a.measureText("|"+t+"|"),o=a.measureText("||");i.cache[s]=(n-o)/100}else i.cache[s]=a.measureText(t)/100}return i.cache[s]*r},checkLoadedFonts:function(){var t,e,r,i=this.fonts.length,s=i;for(t=0;t<i;t+=1)this.fonts[t].loaded?s-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,r=this.fonts[t].monoCase.w,e.offsetWidth!==r?(s-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,r=this.fonts[t].sansCase.w,e.offsetWidth!==r&&(s-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==s&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}};return h.prototype=l,h}();function SlotManager(t){this.animationData=t}function slotFactory(t){return new SlotManager(t)}function RenderableElement(){}SlotManager.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},RenderableElement.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var getBlendMode=(blendModeEnums={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return blendModeEnums[t]||""}),blendModeEnums;function SliderEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function AngleEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function ColorEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,1,0,r)}function PointEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,1,0,r)}function LayerIndexEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function MaskIndexEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function CheckboxEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function NoValueEffect(){this.p={}}function EffectsManager(t,e){var r,i=t.ef||[];this.effectElements=[];var s,a=i.length;for(r=0;r<a;r+=1)s=new GroupEffect(i[r],e),this.effectElements.push(s)}function GroupEffect(t,e){this.init(t,e)}function BaseElement(){}function FrameElement(){}function FootageElement(t,e,r){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,r)}function AudioElement(t,e,r){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,r),this._isPlaying=!1,this._canPlay=!1;var i=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(i),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=PropertyFactory.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function BaseRenderer(){}extendPrototype([DynamicPropertyContainer],GroupEffect),GroupEffect.prototype.getValue=GroupEffect.prototype.iterateDynamicProperties,GroupEffect.prototype.init=function(t,e){var r;this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var i,s=this.data.ef.length,a=this.data.ef;for(r=0;r<s;r+=1){switch(i=null,a[r].ty){case 0:i=new SliderEffect(a[r],e,this);break;case 1:i=new AngleEffect(a[r],e,this);break;case 2:i=new ColorEffect(a[r],e,this);break;case 3:i=new PointEffect(a[r],e,this);break;case 4:case 7:i=new CheckboxEffect(a[r],e,this);break;case 10:i=new LayerIndexEffect(a[r],e,this);break;case 11:i=new MaskIndexEffect(a[r],e,this);break;case 5:i=new EffectsManager(a[r],e,this);break;default:i=new NoValueEffect(a[r],e,this)}i&&this.effectElements.push(i)}},BaseElement.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t=getExpressionInterfaces();if(t){var e=t("layer"),r=t("effects"),i=t("shape"),s=t("text"),a=t("comp");this.layerInterface=e(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var n=r.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(n),0===this.data.ty||this.data.xt?this.compInterface=a(this):4===this.data.ty?(this.layerInterface.shapeInterface=i(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=s(this),this.layerInterface.text=this.layerInterface.textInterface)}},setBlendMode:function(){var t=getBlendMode(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,r){this.globalData=e,this.comp=r,this.data=t,this.layerId=createElementID(),this.data.sr||(this.data.sr=1),this.effectsManager=new EffectsManager(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},FrameElement.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var r,i=this.dynamicProperties.length;for(r=0;r<i;r+=1)(e||this._isParent&&"transform"===this.dynamicProperties[r].propType)&&(this.dynamicProperties[r].getValue(),this.dynamicProperties[r]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},FootageElement.prototype.prepareFrame=function(){},extendPrototype([RenderableElement,BaseElement,FrameElement],FootageElement),FootageElement.prototype.getBaseElement=function(){return null},FootageElement.prototype.renderFrame=function(){},FootageElement.prototype.destroy=function(){},FootageElement.prototype.initExpressions=function(){var t=getExpressionInterfaces();if(t){var e=t("footage");this.layerInterface=e(this)}},FootageElement.prototype.getFootageData=function(){return this.footageData},AudioElement.prototype.prepareFrame=function(t){if(this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder)this._currentTime=t/this.data.sr;else{var e=this.tm.v;this._currentTime=e}this._volume=this.lv.v[0];var r=this._volume*this._volumeMultiplier;this._previousVolume!==r&&(this._previousVolume=r,this.audio.volume(r))},extendPrototype([RenderableElement,BaseElement,FrameElement],AudioElement),AudioElement.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek())>.1)&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},AudioElement.prototype.show=function(){},AudioElement.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},AudioElement.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},AudioElement.prototype.resume=function(){this._canPlay=!0},AudioElement.prototype.setRate=function(t){this.audio.rate(t)},AudioElement.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},AudioElement.prototype.getBaseElement=function(){return null},AudioElement.prototype.destroy=function(){},AudioElement.prototype.sourceRectAtTime=function(){},AudioElement.prototype.initExpressions=function(){},BaseRenderer.prototype.checkLayers=function(t){var e,r,i=this.layers.length;for(this.completeLayers=!0,e=i-1;e>=0;e-=1)this.elements[e]||(r=this.layers[e]).ip-r.st<=t-this.layers[e].st&&r.op-r.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:default:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t)}},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.createAudio=function(t){return new AudioElement(t,this.globalData,this)},BaseRenderer.prototype.createFootage=function(t){return new FootageElement(t,this.globalData,this)},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},BaseRenderer.prototype.includeLayers=function(t){var e;this.completeLayers=!1;var r,i=t.length,s=this.layers.length;for(e=0;e<i;e+=1)for(r=0;r<s;){if(this.layers[r].id===t[e].id){this.layers[r]=t[e];break}r+=1}},BaseRenderer.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},BaseRenderer.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},BaseRenderer.prototype.buildElementParenting=function(t,e,r){for(var i=this.elements,s=this.layers,a=0,n=s.length;a<n;)s[a].ind==e&&(i[a]&&!0!==i[a]?(r.push(i[a]),i[a].setAsParent(),void 0!==s[a].parent?this.buildElementParenting(t,s[a].parent,r):t.setHierarchy(r)):(this.buildItem(a),this.addPendingElement(t))),a+=1},BaseRenderer.prototype.addPendingElement=function(t){this.pendingElements.push(t)},BaseRenderer.prototype.searchExtraCompositions=function(t){var e,r=t.length;for(e=0;e<r;e+=1)if(t[e].xt){var i=this.createComp(t[e]);i.initExpressions(),this.globalData.projectInterface.registerComposition(i)}},BaseRenderer.prototype.getElementById=function(t){var e,r=this.elements.length;for(e=0;e<r;e+=1)if(this.elements[e].data.ind===t)return this.elements[e];return null},BaseRenderer.prototype.getElementByPath=function(t){var e,r=t.shift();if("number"==typeof r)e=this.elements[r];else{var i,s=this.elements.length;for(i=0;i<s;i+=1)if(this.elements[i].data.nm===r){e=this.elements[i];break}}return 0===t.length?e:e.getElementByPath(t)},BaseRenderer.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new FontManager,this.globalData.slotManager=slotFactory(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var effectTypes={TRANSFORM_EFFECT:"transformEFfect"};function TransformElement(){}function MaskElement(t,e,r){this.data=t,this.element=e,this.globalData=r,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var i,s,a=this.globalData.defs,n=this.masksProperties?this.masksProperties.length:0;this.viewData=createSizedArray(n),this.solidPath="";var o,h,l,p,f,c,m=this.masksProperties,u=0,d=[],y=createElementID(),g="clipPath",v="clip-path";for(i=0;i<n;i+=1)if(("a"!==m[i].mode&&"n"!==m[i].mode||m[i].inv||100!==m[i].o.k||m[i].o.x)&&(g="mask",v="mask"),"s"!==m[i].mode&&"i"!==m[i].mode||0!==u?l=null:((l=createNS("rect")).setAttribute("fill","#ffffff"),l.setAttribute("width",this.element.comp.data.w||0),l.setAttribute("height",this.element.comp.data.h||0),d.push(l)),s=createNS("path"),"n"===m[i].mode)this.viewData[i]={op:PropertyFactory.getProp(this.element,m[i].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,m[i],3),elem:s,lastPath:""},a.appendChild(s);else{var b;if(u+=1,s.setAttribute("fill","s"===m[i].mode?"#000000":"#ffffff"),s.setAttribute("clip-rule","nonzero"),0!==m[i].x.k?(g="mask",v="mask",c=PropertyFactory.getProp(this.element,m[i].x,0,null,this.element),b=createElementID(),(p=createNS("filter")).setAttribute("id",b),(f=createNS("feMorphology")).setAttribute("operator","erode"),f.setAttribute("in","SourceGraphic"),f.setAttribute("radius","0"),p.appendChild(f),a.appendChild(p),s.setAttribute("stroke","s"===m[i].mode?"#000000":"#ffffff")):(f=null,c=null),this.storedData[i]={elem:s,x:c,expan:f,lastPath:"",lastOperator:"",filterId:b,lastRadius:0},"i"===m[i].mode){h=d.length;var P=createNS("g");for(o=0;o<h;o+=1)P.appendChild(d[o]);var S=createNS("mask");S.setAttribute("mask-type","alpha"),S.setAttribute("id",y+"_"+u),S.appendChild(s),a.appendChild(S),P.setAttribute("mask","url("+getLocationHref()+"#"+y+"_"+u+")"),d.length=0,d.push(P)}else d.push(s);m[i].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[i]={elem:s,lastPath:"",op:PropertyFactory.getProp(this.element,m[i].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,m[i],3),invRect:l},this.viewData[i].prop.k||this.drawPath(m[i],this.viewData[i].prop.v,this.viewData[i])}for(this.maskElement=createNS(g),n=d.length,i=0;i<n;i+=1)this.maskElement.appendChild(d[i]);u>0&&(this.maskElement.setAttribute("id",y),this.element.maskedElement.setAttribute(v,"url("+getLocationHref()+"#"+y+")"),a.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}TransformElement.prototype={initTransform:function(){var t=new Matrix;this.finalTransform={mProp:this.data.ks?TransformPropertyFactory.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,r=0,i=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;r<i;){if(this.hierarchy[r].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}r+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),r=0;r<i;r+=1)e.multiply(this.hierarchy[r].finalTransform.mProp.v)}this.finalTransform._matMdf&&(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var r=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(r),t=1;t<e;t+=1){var i=this.localTransforms[t].matrix;r.multiply(i)}r.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){var s=this.finalTransform.localOpacity;for(t=0;t<e;t+=1)s*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=s}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new Matrix;var e=0,r=t.length;for(e=0;e<r;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var r,i=!0,s=this.comp;i;)s.finalTransform?(s.data.hasMask&&e.splice(0,0,s.finalTransform),s=s.comp):i=!1;var a,n=e.length;for(r=0;r<n;r+=1)a=e[r].mat.applyToPointArray(0,0,0),t=[t[0]-a[0],t[1]-a[1],0];return t},mHelper:new Matrix},MaskElement.prototype.getMaskProperty=function(t){return this.viewData[t].prop},MaskElement.prototype.renderFrame=function(t){var e,r=this.element.finalTransform.mat,i=this.masksProperties.length;for(e=0;e<i;e+=1)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[e].invRect.setAttribute("transform",r.getInverseMatrix().to2dCSS()),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var s=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+getLocationHref()+"#"+this.storedData[e].filterId+")")),s.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},MaskElement.prototype.getMaskelement=function(){return this.maskElement},MaskElement.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},MaskElement.prototype.drawPath=function(t,e,r){var i,s,a=" M"+e.v[0][0]+","+e.v[0][1];for(s=e._length,i=1;i<s;i+=1)a+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[i][0]+","+e.i[i][1]+" "+e.v[i][0]+","+e.v[i][1];if(e.c&&s>1&&(a+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),r.lastPath!==a){var n="";r.elem&&(e.c&&(n=t.inv?this.solidPath+a:a),r.elem.setAttribute("d",n)),r.lastPath=a}},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var filtersFactory=function(){var t={};return t.createFilter=function(t,e){var r=createNS("filter");r.setAttribute("id",t),!0!==e&&(r.setAttribute("filterUnits","objectBoundingBox"),r.setAttribute("x","0%"),r.setAttribute("y","0%"),r.setAttribute("width","100%"),r.setAttribute("height","100%"));return r},t.createAlphaToLuminanceFilter=function(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},t}(),featureSupport=function(){var t={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),/firefox/i.test(navigator.userAgent)&&(t.svgLumaHidden=!1),t}(),registeredEffects={},idPrefix="filter_result_";function SVGEffects(t){var e,r,i="SourceGraphic",s=t.data.ef?t.data.ef.length:0,a=createElementID(),n=filtersFactory.createFilter(a,!0),o=0;for(this.filters=[],e=0;e<s;e+=1){r=null;var h=t.data.ef[e].ty;if(registeredEffects[h])r=new(0,registeredEffects[h].effect)(n,t.effectsManager.effectElements[e],t,idPrefix+o,i),i=idPrefix+o,registeredEffects[h].countsAsEffect&&(o+=1);r&&this.filters.push(r)}o&&(t.globalData.defs.appendChild(n),t.layerElement.setAttribute("filter","url("+getLocationHref()+"#"+a+")")),this.filters.length&&t.addRenderableComponent(this)}function registerEffect(t,e,r){registeredEffects[t]={effect:e,countsAsEffect:r}}function SVGBaseElement(){}function HierarchyElement(){}function RenderableDOMElement(){}function IImageElement(t,e,r){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,r),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ProcessedElement(t,e){this.elem=t,this.pos=e}function IShapeElement(){}SVGEffects.prototype.renderFrame=function(t){var e,r=this.filters.length;for(e=0;e<r;e+=1)this.filters[e].renderFrame(t)},SVGEffects.prototype.getEffects=function(t){var e,r=this.filters.length,i=[];for(e=0;e<r;e+=1)this.filters[e].type===t&&i.push(this.filters[e]);return i},SVGBaseElement.prototype={initRendererElement:function(){this.layerElement=createNS("g")},createContainerElements:function(){this.matteElement=createNS("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t=null;if(this.data.td){this.matteMasks={};var e=createNS("g");e.setAttribute("id",this.layerId),e.appendChild(this.layerElement),t=e,this.globalData.defs.appendChild(e)}else this.data.tt?(this.matteElement.appendChild(this.layerElement),t=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var r=createNS("clipPath"),i=createNS("path");i.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var s=createElementID();if(r.setAttribute("id",s),r.appendChild(i),this.globalData.defs.appendChild(r),this.checkMasks()){var a=createNS("g");a.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),a.appendChild(this.layerElement),this.transformedElement=a,t?t.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData),this.renderableEffectsManager=new SVGEffects(this),this.searchEffectTransforms()},getMatte:function(t){if(this.matteMasks||(this.matteMasks={}),!this.matteMasks[t]){var e,r,i,s,a=this.layerId+"_"+t;if(1===t||3===t){var n=createNS("mask");n.setAttribute("id",a),n.setAttribute("mask-type",3===t?"luminance":"alpha"),(i=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),n.appendChild(i),this.globalData.defs.appendChild(n),featureSupport.maskType||1!==t||(n.setAttribute("mask-type","luminance"),e=createElementID(),r=filtersFactory.createFilter(e),this.globalData.defs.appendChild(r),r.appendChild(filtersFactory.createAlphaToLuminanceFilter()),(s=createNS("g")).appendChild(i),n.appendChild(s),s.setAttribute("filter","url("+getLocationHref()+"#"+e+")"))}else if(2===t){var o=createNS("mask");o.setAttribute("id",a),o.setAttribute("mask-type","alpha");var h=createNS("g");o.appendChild(h),e=createElementID(),r=filtersFactory.createFilter(e);var l=createNS("feComponentTransfer");l.setAttribute("in","SourceGraphic"),r.appendChild(l);var p=createNS("feFuncA");p.setAttribute("type","table"),p.setAttribute("tableValues","1.0 0.0"),l.appendChild(p),this.globalData.defs.appendChild(r);var f=createNS("rect");f.setAttribute("width",this.comp.data.w),f.setAttribute("height",this.comp.data.h),f.setAttribute("x","0"),f.setAttribute("y","0"),f.setAttribute("fill","#ffffff"),f.setAttribute("opacity","0"),h.setAttribute("filter","url("+getLocationHref()+"#"+e+")"),h.appendChild(f),(i=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),h.appendChild(i),featureSupport.maskType||(o.setAttribute("mask-type","luminance"),r.appendChild(filtersFactory.createAlphaToLuminanceFilter()),s=createNS("g"),h.appendChild(f),s.appendChild(this.layerElement),h.appendChild(s)),this.globalData.defs.appendChild(o)}this.matteMasks[t]=a}return this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+getLocationHref()+"#"+t+")")}},HierarchyElement.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},extendPrototype([RenderableElement,createProxyFunction({initElement:function(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initTransform(t,e,r),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],RenderableDOMElement),extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],IImageElement),IImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=createNS("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},IImageElement.prototype.sourceRectAtTime=function(){return this.sourceRect},IShapeElement.prototype={addShapeToModifiers:function(t){var e,r=this.shapeModifiers.length;for(e=0;e<r;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;t>=0&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,r=0,i=e.length;r<i;){if(e[r].elem===t)return e[r].pos;r+=1}return 0},addProcessedElement:function(t,e){for(var r=this.processedElements,i=r.length;i;)if(r[i-=1].elem===t)return void(r[i].pos=e);r.push(new ProcessedElement(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var lineCapEnum={1:"butt",2:"round",3:"square"},lineJoinEnum={1:"miter",2:"round",3:"bevel"};function SVGShapeData(t,e,r){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=r,this.lvl=e,this._isAnimated=!!r.k;for(var i=0,s=t.length;i<s;){if(t[i].mProps.dynamicProperties.length){this._isAnimated=!0;break}i+=1}}function SVGStyleData(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=createNS("path"),this.msElem=null}function DashProperty(t,e,r,i){var s;this.elem=t,this.frameId=-1,this.dataProps=createSizedArray(e.length),this.renderer=r,this.k=!1,this.dashStr="",this.dashArray=createTypedArray("float32",e.length?e.length-1:0),this.dashoffset=createTypedArray("float32",1),this.initDynamicPropertyContainer(i);var a,n=e.length||0;for(s=0;s<n;s+=1)a=PropertyFactory.getProp(t,e[s].v,0,0,this),this.k=a.k||this.k,this.dataProps[s]={n:e[s].n,p:a};this.k||this.getValue(!0),this._isAnimated=this.k}function SVGStrokeStyleData(t,e,r){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=r,this._isAnimated=!!this._isAnimated}function SVGFillStyleData(t,e,r){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=r}function SVGNoStyleData(t,e,r){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=r}function GradientProperty(t,e,r){this.data=e,this.c=createTypedArray("uint8c",4*e.p);var i=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=createTypedArray("float32",i),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=i,this.initDynamicPropertyContainer(r),this.prop=PropertyFactory.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function SVGGradientFillStyleData(t,e,r){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,r)}function SVGGradientStrokeStyleData(t,e,r){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.initGradientData(t,e,r),this._isAnimated=!!this._isAnimated}function ShapeGroupData(){this.it=[],this.prevViewData=[],this.gr=createNS("g")}function SVGTransformData(t,e,r){this.transform={mProps:t,op:e,container:r},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}SVGShapeData.prototype.setAsAnimated=function(){this._isAnimated=!0},SVGStyleData.prototype.reset=function(){this.d="",this._mdf=!1},DashProperty.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,r=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<r;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},extendPrototype([DynamicPropertyContainer],DashProperty),extendPrototype([DynamicPropertyContainer],SVGStrokeStyleData),extendPrototype([DynamicPropertyContainer],SVGFillStyleData),extendPrototype([DynamicPropertyContainer],SVGNoStyleData),GradientProperty.prototype.comparePoints=function(t,e){for(var r=0,i=this.o.length/2;r<i;){if(Math.abs(t[4*r]-t[4*e+2*r])>.01)return!1;r+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},GradientProperty.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,r,i,s=4*this.data.p;for(e=0;e<s;e+=1)r=e%4==0?100:255,i=Math.round(this.prop.v[e]*r),this.c[e]!==i&&(this.c[e]=i,this._cmdf=!t);if(this.o.length)for(s=this.prop.v.length,e=4*this.data.p;e<s;e+=1)r=e%2==0?100:1,i=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==i&&(this.o[e-4*this.data.p]=i,this._omdf=!t);this._mdf=!t}},extendPrototype([DynamicPropertyContainer],GradientProperty),SVGGradientFillStyleData.prototype.initGradientData=function(t,e,r){this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.s=PropertyFactory.getProp(t,e.s,1,null,this),this.e=PropertyFactory.getProp(t,e.e,1,null,this),this.h=PropertyFactory.getProp(t,e.h||{k:0},0,.01,this),this.a=PropertyFactory.getProp(t,e.a||{k:0},0,degToRads,this),this.g=new GradientProperty(t,e.g,this),this.style=r,this.stops=[],this.setGradientData(r.pElem,e),this.setGradientOpacity(e,r),this._isAnimated=!!this._isAnimated},SVGGradientFillStyleData.prototype.setGradientData=function(t,e){var r=createElementID(),i=createNS(1===e.t?"linearGradient":"radialGradient");i.setAttribute("id",r),i.setAttribute("spreadMethod","pad"),i.setAttribute("gradientUnits","userSpaceOnUse");var s,a,n,o=[];for(n=4*e.g.p,a=0;a<n;a+=4)s=createNS("stop"),i.appendChild(s),o.push(s);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+getLocationHref()+"#"+r+")"),this.gf=i,this.cst=o},SVGGradientFillStyleData.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){var r,i,s,a=createNS("mask"),n=createNS("path");a.appendChild(n);var o=createElementID(),h=createElementID();a.setAttribute("id",h);var l=createNS(1===t.t?"linearGradient":"radialGradient");l.setAttribute("id",o),l.setAttribute("spreadMethod","pad"),l.setAttribute("gradientUnits","userSpaceOnUse"),s=t.g.k.k[0].s?t.g.k.k[0].s.length:t.g.k.k.length;var p=this.stops;for(i=4*t.g.p;i<s;i+=2)(r=createNS("stop")).setAttribute("stop-color","rgb(255,255,255)"),l.appendChild(r),p.push(r);n.setAttribute("gf"===t.ty?"fill":"stroke","url("+getLocationHref()+"#"+o+")"),"gs"===t.ty&&(n.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),n.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),1===t.lj&&n.setAttribute("stroke-miterlimit",t.ml)),this.of=l,this.ms=a,this.ost=p,this.maskId=h,e.msElem=n}},extendPrototype([DynamicPropertyContainer],SVGGradientFillStyleData),extendPrototype([SVGGradientFillStyleData,DynamicPropertyContainer],SVGGradientStrokeStyleData);var buildShapeString=function(t,e,r,i){if(0===e)return"";var s,a=t.o,n=t.i,o=t.v,h=" M"+i.applyToPointStringified(o[0][0],o[0][1]);for(s=1;s<e;s+=1)h+=" C"+i.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+i.applyToPointStringified(n[s][0],n[s][1])+" "+i.applyToPointStringified(o[s][0],o[s][1]);return r&&e&&(h+=" C"+i.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+i.applyToPointStringified(n[0][0],n[0][1])+" "+i.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},SVGElementsRenderer=function(){var t=new Matrix,e=new Matrix;function r(t,e,r){(r||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(r||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function i(){}function s(r,i,s){var a,n,o,h,l,p,f,c,m,u,d=i.styles.length,y=i.lvl;for(p=0;p<d;p+=1){if(h=i.sh._mdf||s,i.styles[p].lvl<y){for(c=e.reset(),m=y-i.styles[p].lvl,u=i.transformers.length-1;!h&&m>0;)h=i.transformers[u].mProps._mdf||h,m-=1,u-=1;if(h)for(m=y-i.styles[p].lvl,u=i.transformers.length-1;m>0;)c.multiply(i.transformers[u].mProps.v),m-=1,u-=1}else c=t;if(n=(f=i.sh.paths)._length,h){for(o="",a=0;a<n;a+=1)(l=f.shapes[a])&&l._length&&(o+=buildShapeString(l,l._length,l.c,c));i.caches[p]=o}else o=i.caches[p];i.styles[p].d+=!0===r.hd?"":o,i.styles[p]._mdf=h||i.styles[p]._mdf}}function a(t,e,r){var i=e.style;(e.c._mdf||r)&&i.pElem.setAttribute("fill","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||r)&&i.pElem.setAttribute("fill-opacity",e.o.v)}function n(t,e,r){o(t,e,r),h(t,e,r)}function o(t,e,r){var i,s,a,n,o,h=e.gf,l=e.g._hasOpacity,p=e.s.v,f=e.e.v;if(e.o._mdf||r){var c="gf"===t.ty?"fill-opacity":"stroke-opacity";e.style.pElem.setAttribute(c,e.o.v)}if(e.s._mdf||r){var m=1===t.t?"x1":"cx",u="x1"===m?"y1":"cy";h.setAttribute(m,p[0]),h.setAttribute(u,p[1]),l&&!e.g._collapsable&&(e.of.setAttribute(m,p[0]),e.of.setAttribute(u,p[1]))}if(e.g._cmdf||r){i=e.cst;var d=e.g.c;for(a=i.length,s=0;s<a;s+=1)(n=i[s]).setAttribute("offset",d[4*s]+"%"),n.setAttribute("stop-color","rgb("+d[4*s+1]+","+d[4*s+2]+","+d[4*s+3]+")")}if(l&&(e.g._omdf||r)){var y=e.g.o;for(a=(i=e.g._collapsable?e.cst:e.ost).length,s=0;s<a;s+=1)n=i[s],e.g._collapsable||n.setAttribute("offset",y[2*s]+"%"),n.setAttribute("stop-opacity",y[2*s+1])}if(1===t.t)(e.e._mdf||r)&&(h.setAttribute("x2",f[0]),h.setAttribute("y2",f[1]),l&&!e.g._collapsable&&(e.of.setAttribute("x2",f[0]),e.of.setAttribute("y2",f[1])));else if((e.s._mdf||e.e._mdf||r)&&(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)),h.setAttribute("r",o),l&&!e.g._collapsable&&e.of.setAttribute("r",o)),e.e._mdf||e.h._mdf||e.a._mdf||r){o||(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)));var g=Math.atan2(f[1]-p[1],f[0]-p[0]),v=e.h.v;v>=1?v=.99:v<=-1&&(v=-.99);var b=o*v,P=Math.cos(g+e.a.v)*b+p[0],S=Math.sin(g+e.a.v)*b+p[1];h.setAttribute("fx",P),h.setAttribute("fy",S),l&&!e.g._collapsable&&(e.of.setAttribute("fx",P),e.of.setAttribute("fy",S))}}function h(t,e,r){var i=e.style,s=e.d;s&&(s._mdf||r)&&s.dashStr&&(i.pElem.setAttribute("stroke-dasharray",s.dashStr),i.pElem.setAttribute("stroke-dashoffset",s.dashoffset[0])),e.c&&(e.c._mdf||r)&&i.pElem.setAttribute("stroke","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||r)&&i.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||r)&&(i.pElem.setAttribute("stroke-width",e.w.v),i.msElem&&i.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function(t){switch(t.ty){case"fl":return a;case"gf":return o;case"gs":return n;case"st":return h;case"sh":case"el":case"rc":case"sr":return s;case"tr":return r;case"no":return i;default:return null}}}}();function SVGShapeElement(t,e,r){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,r),this.prevViewData=[]}function LetterProps(t,e,r,i,s,a){this.o=t,this.sw=e,this.sc=r,this.fc=i,this.m=s,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!r,fc:!!i,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){var t,e,r,i,s=this.shapes.length,a=this.stylesList.length,n=[],o=!1;for(r=0;r<a;r+=1){for(i=this.stylesList[r],o=!1,n.length=0,t=0;t<s;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(i)&&(n.push(e),o=e._isAnimated||o);n.length>1&&o&&this.setShapesAsAnimated(n)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){var e,r=t.length;for(e=0;e<r;e+=1)t[e].setAsAnimated()},SVGShapeElement.prototype.createStyleElement=function(t,e){var r,i=new SVGStyleData(t,e),s=i.pElem;if("st"===t.ty)r=new SVGStrokeStyleData(this,t,i);else if("fl"===t.ty)r=new SVGFillStyleData(this,t,i);else if("gf"===t.ty||"gs"===t.ty){r=new("gf"===t.ty?SVGGradientFillStyleData:SVGGradientStrokeStyleData)(this,t,i),this.globalData.defs.appendChild(r.gf),r.maskId&&(this.globalData.defs.appendChild(r.ms),this.globalData.defs.appendChild(r.of),s.setAttribute("mask","url("+getLocationHref()+"#"+r.maskId+")"))}else"no"===t.ty&&(r=new SVGNoStyleData(this,t,i));return"st"!==t.ty&&"gs"!==t.ty||(s.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),s.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),s.setAttribute("fill-opacity","0"),1===t.lj&&s.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&s.setAttribute("fill-rule","evenodd"),t.ln&&s.setAttribute("id",t.ln),t.cl&&s.setAttribute("class",t.cl),t.bm&&(s.style["mix-blend-mode"]=getBlendMode(t.bm)),this.stylesList.push(i),this.addToAnimatedContents(t,r),r},SVGShapeElement.prototype.createGroupElement=function(t){var e=new ShapeGroupData;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=getBlendMode(t.bm)),e},SVGShapeElement.prototype.createTransformElement=function(t,e){var r=TransformPropertyFactory.getTransformProperty(this,t,this),i=new SVGTransformData(r,r.o,e);return this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createShapeElement=function(t,e,r){var i=4;"rc"===t.ty?i=5:"el"===t.ty?i=6:"sr"===t.ty&&(i=7);var s=new SVGShapeData(e,r,ShapePropertyFactory.getShapeProp(this,t,i,this));return this.shapes.push(s),this.addShapeToModifiers(s),this.addToAnimatedContents(t,s),s},SVGShapeElement.prototype.addToAnimatedContents=function(t,e){for(var r=0,i=this.animatedContents.length;r<i;){if(this.animatedContents[r].element===e)return;r+=1}this.animatedContents.push({fn:SVGElementsRenderer.createRenderFunction(t),element:e,data:t})},SVGShapeElement.prototype.setElementStyles=function(t){var e,r=t.styles,i=this.stylesList.length;for(e=0;e<i;e+=1)this.stylesList[e].closed||r.push(this.stylesList[e])},SVGShapeElement.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},SVGShapeElement.prototype.searchShapes=function(t,e,r,i,s,a,n){var o,h,l,p,f,c,m=[].concat(a),u=t.length-1,d=[],y=[];for(o=u;o>=0;o-=1){if((c=this.searchProcessedElement(t[o]))?e[o]=r[c-1]:t[o]._render=n,"fl"===t[o].ty||"st"===t[o].ty||"gf"===t[o].ty||"gs"===t[o].ty||"no"===t[o].ty)c?e[o].style.closed=!1:e[o]=this.createStyleElement(t[o],s),t[o]._render&&e[o].style.pElem.parentNode!==i&&i.appendChild(e[o].style.pElem),d.push(e[o].style);else if("gr"===t[o].ty){if(c)for(l=e[o].it.length,h=0;h<l;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,s+1,m,n),t[o]._render&&e[o].gr.parentNode!==i&&i.appendChild(e[o].gr)}else"tr"===t[o].ty?(c||(e[o]=this.createTransformElement(t[o],i)),p=e[o].transform,m.push(p)):"sh"===t[o].ty||"rc"===t[o].ty||"el"===t[o].ty||"sr"===t[o].ty?(c||(e[o]=this.createShapeElement(t[o],m,s)),this.setElementStyles(e[o])):"tm"===t[o].ty||"rd"===t[o].ty||"ms"===t[o].ty||"pb"===t[o].ty||"zz"===t[o].ty||"op"===t[o].ty?(c?(f=e[o]).closed=!1:((f=ShapeModifiers.getModifier(t[o].ty)).init(this,t[o]),e[o]=f,this.shapeModifiers.push(f)),y.push(f)):"rp"===t[o].ty&&(c?(f=e[o]).closed=!0:(f=ShapeModifiers.getModifier(t[o].ty),e[o]=f,f.init(this,t,o,e),this.shapeModifiers.push(f),n=!1),y.push(f));this.addProcessedElement(t[o],o+1)}for(u=d.length,o=0;o<u;o+=1)d[o].closed=!0;for(u=y.length,o=0;o<u;o+=1)y[o].closed=!0},SVGShapeElement.prototype.renderInnerContent=function(){var t;this.renderModifiers();var e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},SVGShapeElement.prototype.renderShape=function(){var t,e,r=this.animatedContents.length;for(t=0;t<r;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},SVGShapeElement.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},LetterProps.prototype.update=function(t,e,r,i,s,a){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1,this._mdf.p=!1;var n=!1;return this.o!==t&&(this.o=t,this._mdf.o=!0,n=!0),this.sw!==e&&(this.sw=e,this._mdf.sw=!0,n=!0),this.sc!==r&&(this.sc=r,this._mdf.sc=!0,n=!0),this.fc!==i&&(this.fc=i,this._mdf.fc=!0,n=!0),this.m!==s&&(this.m=s,this._mdf.m=!0,n=!0),!a.length||this.p[0]===a[0]&&this.p[1]===a[1]&&this.p[4]===a[4]&&this.p[5]===a[5]&&this.p[12]===a[12]&&this.p[13]===a[13]||(this.p=a,this._mdf.p=!0,n=!0),n},TextProperty.prototype.defaultBoxWidth=[0,0],TextProperty.prototype.copyData=function(t,e){for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t},TextProperty.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},TextProperty.prototype.searchProperty=function(){return this.searchKeyframes()},TextProperty.prototype.searchKeyframes=function(){return this.kf=this.data.d.k.length>1,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,r=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{var i;this.lock=!0,this._mdf=!1;var s=this.effectsSequence.length,a=t||this.data.d.k[this.keysIndex].s;for(i=0;i<s;i+=1)a=r!==this.keysIndex?this.effectsSequence[i](a,a.t):this.effectsSequence[i](this.currentData,a.t);e!==a&&this.setCurrentData(a),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},TextProperty.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,r=0,i=t.length;r<=i-1&&!(r===i-1||t[r+1].t>e);)r+=1;return this.keysIndex!==r&&(this.keysIndex=r),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e,r,i=[],s=0,a=t.length,n=!1,o=!1,h="";s<a;)n=o,o=!1,e=t.charCodeAt(s),h=t.charAt(s),FontManager.isCombinedCharacter(e)?n=!0:e>=55296&&e<=56319?FontManager.isRegionalFlag(t,s)?h=t.substr(s,14):(r=t.charCodeAt(s+1))>=56320&&r<=57343&&(FontManager.isModifier(e,r)?(h=t.substr(s,2),n=!0):h=FontManager.isFlagEmoji(t.substr(s,4))?t.substr(s,4):t.substr(s,2)):e>56319?(r=t.charCodeAt(s+1),FontManager.isVariationSelector(e)&&(n=!0)):FontManager.isZeroWidthJoiner(e)&&(n=!0,o=!0),n?(i[i.length-1]+=h,n=!1):i.push(h),s+=h.length;return i},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,r,i,s,a,n,o,h=this.elem.globalData.fontManager,l=this.data,p=[],f=0,c=l.m.g,m=0,u=0,d=0,y=[],g=0,v=0,b=h.getFontByName(t.f),P=0,S=getFontProperties(b);t.fWeight=S.weight,t.fStyle=S.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),r=t.finalText.length,t.finalLineHeight=t.lh;var _,E=t.tr/1e3*t.finalSize;if(t.sz)for(var x,A,M=!0,T=t.sz[0],k=t.sz[1];M;){x=0,g=0,r=(A=this.buildFinalText(t.t)).length,E=t.tr/1e3*t.finalSize;var F=-1;for(e=0;e<r;e+=1)_=A[e].charCodeAt(0),i=!1," "===A[e]?F=e:13!==_&&3!==_||(g=0,i=!0,x+=t.finalLineHeight||1.2*t.finalSize),h.chars?(o=h.getCharData(A[e],b.fStyle,b.fFamily),P=i?0:o.w*t.finalSize/100):P=h.measureText(A[e],t.f,t.finalSize),g+P>T&&" "!==A[e]?(-1===F?r+=1:e=F,x+=t.finalLineHeight||1.2*t.finalSize,A.splice(e,F===e?1:0,"\r"),F=-1,g=0):(g+=P,g+=E);x+=b.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&k<x?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=A,r=t.finalText.length,M=!1)}g=-E,P=0;var I,D=0;for(e=0;e<r;e+=1)if(i=!1,13===(_=(I=t.finalText[e]).charCodeAt(0))||3===_?(D=0,y.push(g),v=g>v?g:v,g=-2*E,s="",i=!0,d+=1):s=I,h.chars?(o=h.getCharData(I,b.fStyle,h.getFontByName(t.f).fFamily),P=i?0:o.w*t.finalSize/100):P=h.measureText(s,t.f,t.finalSize)," "===I?D+=P+E:(g+=P+E+D,D=0),p.push({l:P,an:P,add:m,n:i,anIndexes:[],val:s,line:d,animatorJustifyOffset:0}),2==c){if(m+=P,""===s||" "===s||e===r-1){for(""!==s&&" "!==s||(m-=P);u<=e;)p[u].an=m,p[u].ind=f,p[u].extra=P,u+=1;f+=1,m=0}}else if(3==c){if(m+=P,""===s||e===r-1){for(""===s&&(m-=P);u<=e;)p[u].an=m,p[u].ind=f,p[u].extra=P,u+=1;m=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=g>v?g:v,y.push(g),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=y;var C,w,V,R,L=l.a;n=L.length;var G=[];for(a=0;a<n;a+=1){for((C=L[a]).a.sc&&(t.strokeColorAnim=!0),C.a.sw&&(t.strokeWidthAnim=!0),(C.a.fc||C.a.fh||C.a.fs||C.a.fb)&&(t.fillColorAnim=!0),R=0,V=C.s.b,e=0;e<r;e+=1)(w=p[e]).anIndexes[a]=R,(1==V&&""!==w.val||2==V&&""!==w.val&&" "!==w.val||3==V&&(w.n||" "==w.val||e==r-1)||4==V&&(w.n||e==r-1))&&(1===C.s.rn&&G.push(R),R+=1);l.a[a].s.totalChars=R;var B,z=-1;if(1===C.s.rn)for(e=0;e<r;e+=1)z!=(w=p[e]).anIndexes[a]&&(z=w.anIndexes[a],B=G.splice(Math.floor(Math.random()*G.length),1)[0]),w.anIndexes[a]=B}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=b.ascent*t.finalSize/100},TextProperty.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var r=this.copyData({},this.data.d.k[e].s);r=this.copyData(r,t),this.data.d.k[e].s=r,this.recalculate(e),this.setCurrentData(r),this.elem.addDynamicProperty(this)},TextProperty.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},TextProperty.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},TextProperty.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var TextSelectorProp=function(){var t=Math.max,e=Math.min,r=Math.floor;function i(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=PropertyFactory.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?PropertyFactory.getProp(t,e.e,0,0,this):{v:100},this.o=PropertyFactory.getProp(t,e.o||{k:0},0,0,this),this.xe=PropertyFactory.getProp(t,e.xe||{k:0},0,0,this),this.ne=PropertyFactory.getProp(t,e.ne||{k:0},0,0,this),this.sm=PropertyFactory.getProp(t,e.sm||{k:100},0,0,this),this.a=PropertyFactory.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return i.prototype={getMult:function(i){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var s=0,a=0,n=1,o=1;this.ne.v>0?s=this.ne.v/100:a=-this.ne.v/100,this.xe.v>0?n=1-this.xe.v/100:o=1+this.xe.v/100;var h=BezierFactory.getBezierEasing(s,a,n,o).get,l=0,p=this.finalS,f=this.finalE,c=this.data.sh;if(2===c)l=h(l=f===p?i>=f?1:0:t(0,e(.5/(f-p)+(i-p)/(f-p),1)));else if(3===c)l=h(l=f===p?i>=f?0:1:1-t(0,e(.5/(f-p)+(i-p)/(f-p),1)));else if(4===c)f===p?l=0:(l=t(0,e(.5/(f-p)+(i-p)/(f-p),1)))<.5?l*=2:l=1-2*(l-.5),l=h(l);else if(5===c){if(f===p)l=0;else{var m=f-p,u=-m/2+(i=e(t(0,i+.5-p),f-p)),d=m/2;l=Math.sqrt(1-u*u/(d*d))}l=h(l)}else 6===c?(f===p?l=0:(i=e(t(0,i+.5-p),f-p),l=(1+Math.cos(Math.PI+2*Math.PI*i/(f-p)))/2),l=h(l)):(i>=r(p)&&(l=t(0,e(i-p<0?e(f,1)-(p-i):f-i,1))),l=h(l));if(100!==this.sm.v){var y=.01*this.sm.v;0===y&&(y=1e-8);var g=.5-.5*y;l<g?l=0:(l=(l-g)/y)>1&&(l=1)}return l*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,r=this.o.v/e,i=this.s.v/e+r,s=this.e.v/e+r;if(i>s){var a=i;i=s,s=a}this.finalS=i,this.finalE=s}},extendPrototype([DynamicPropertyContainer],i),{getTextSelectorProp:function(t,e,r){return new i(t,e,r)}}}();function TextAnimatorDataProperty(t,e,r){var i={propType:!1},s=PropertyFactory.getProp,a=e.a;this.a={r:a.r?s(t,a.r,0,degToRads,r):i,rx:a.rx?s(t,a.rx,0,degToRads,r):i,ry:a.ry?s(t,a.ry,0,degToRads,r):i,sk:a.sk?s(t,a.sk,0,degToRads,r):i,sa:a.sa?s(t,a.sa,0,degToRads,r):i,s:a.s?s(t,a.s,1,.01,r):i,a:a.a?s(t,a.a,1,0,r):i,o:a.o?s(t,a.o,0,.01,r):i,p:a.p?s(t,a.p,1,0,r):i,sw:a.sw?s(t,a.sw,0,0,r):i,sc:a.sc?s(t,a.sc,1,0,r):i,fc:a.fc?s(t,a.fc,1,0,r):i,fh:a.fh?s(t,a.fh,0,0,r):i,fs:a.fs?s(t,a.fs,0,.01,r):i,fb:a.fb?s(t,a.fb,0,.01,r):i,t:a.t?s(t,a.t,0,0,r):i},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,r),this.s.t=e.s.t}function TextAnimatorProperty(t,e,r){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=r,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(r)}function ITextElement(){}TextAnimatorProperty.prototype.searchProperties=function(){var t,e,r=this._textData.a.length,i=PropertyFactory.getProp;for(t=0;t<r;t+=1)e=this._textData.a[t],this._animatorsData[t]=new TextAnimatorDataProperty(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:i(this._elem,this._textData.p.a,0,0,this),f:i(this._elem,this._textData.p.f,0,0,this),l:i(this._elem,this._textData.p.l,0,0,this),r:i(this._elem,this._textData.p.r,0,0,this),p:i(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=i(this._elem,this._textData.m.a,1,0,this)},TextAnimatorProperty.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var r,i,s,a,n,o,h,l,p,f,c,m,u,d,y,g,v,b,P,S=this._moreOptions.alignment.v,_=this._animatorsData,E=this._textData,x=this.mHelper,A=this._renderType,M=this.renderedLetters.length,T=t.l;if(this._hasMaskedPath){if(P=this._pathData.m,!this._pathData.n||this._pathData._mdf){var k,F=P.v;for(this._pathData.r.v&&(F=F.reverse()),n={tLength:0,segments:[]},a=F._length-1,g=0,s=0;s<a;s+=1)k=bez.buildBezierData(F.v[s],F.v[s+1],[F.o[s][0]-F.v[s][0],F.o[s][1]-F.v[s][1]],[F.i[s+1][0]-F.v[s+1][0],F.i[s+1][1]-F.v[s+1][1]]),n.tLength+=k.segmentLength,n.segments.push(k),g+=k.segmentLength;s=a,P.v.c&&(k=bez.buildBezierData(F.v[s],F.v[0],[F.o[s][0]-F.v[s][0],F.o[s][1]-F.v[s][1]],[F.i[0][0]-F.v[0][0],F.i[0][1]-F.v[0][1]]),n.tLength+=k.segmentLength,n.segments.push(k),g+=k.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,c=0,f=1,l=0,p=!0,d=n.segments,o<0&&P.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),f=(u=d[c=d.length-1].points).length-1;o<0;)o+=u[f].partialLength,(f-=1)<0&&(f=(u=d[c-=1].points).length-1);m=(u=d[c].points)[f-1],y=(h=u[f]).partialLength}a=T.length,r=0,i=0;var I,D,C,w,V,R=1.2*t.finalSize*.714,L=!0;C=_.length;var G,B,z,O,N,j,q,H,W,$,Z,X,Y=-1,K=o,J=c,U=f,Q=-1,tt="",et=this.defaultPropsArray;if(2===t.j||1===t.j){var rt=0,it=0,st=2===t.j?-.5:-1,at=0,nt=!0;for(s=0;s<a;s+=1)if(T[s].n){for(rt&&(rt+=it);at<s;)T[at].animatorJustifyOffset=rt,at+=1;rt=0,nt=!0}else{for(D=0;D<C;D+=1)(I=_[D].a).t.propType&&(nt&&2===t.j&&(it+=I.t.v*st),(V=_[D].s.getMult(T[s].anIndexes[D],E.a[D].s.totalChars)).length?rt+=I.t.v*V[0]*st:rt+=I.t.v*V*st);nt=!1}for(rt&&(rt+=it);at<s;)T[at].animatorJustifyOffset=rt,at+=1}for(s=0;s<a;s+=1){if(x.reset(),O=1,T[s].n)r=0,i+=t.yOffset,i+=L?1:0,o=K,L=!1,this._hasMaskedPath&&(f=U,m=(u=d[c=J].points)[f-1],y=(h=u[f]).partialLength,l=0),tt="",Z="",W="",X="",et=this.defaultPropsArray;else{if(this._hasMaskedPath){if(Q!==T[s].line){switch(t.j){case 1:o+=g-t.lineWidths[T[s].line];break;case 2:o+=(g-t.lineWidths[T[s].line])/2}Q=T[s].line}Y!==T[s].ind&&(T[Y]&&(o+=T[Y].extra),o+=T[s].an/2,Y=T[s].ind),o+=S[0]*T[s].an*.005;var ot=0;for(D=0;D<C;D+=1)(I=_[D].a).p.propType&&((V=_[D].s.getMult(T[s].anIndexes[D],E.a[D].s.totalChars)).length?ot+=I.p.v[0]*V[0]:ot+=I.p.v[0]*V),I.a.propType&&((V=_[D].s.getMult(T[s].anIndexes[D],E.a[D].s.totalChars)).length?ot+=I.a.v[0]*V[0]:ot+=I.a.v[0]*V);for(p=!0,this._pathData.a.v&&(o=.5*T[0].an+(g-this._pathData.f.v-.5*T[0].an-.5*T[T.length-1].an)*Y/(a-1),o+=this._pathData.f.v);p;)l+y>=o+ot||!u?(v=(o+ot-l)/h.partialLength,B=m.point[0]+(h.point[0]-m.point[0])*v,z=m.point[1]+(h.point[1]-m.point[1])*v,x.translate(-S[0]*T[s].an*.005,-S[1]*R*.01),p=!1):u&&(l+=h.partialLength,(f+=1)>=u.length&&(f=0,d[c+=1]?u=d[c].points:P.v.c?(f=0,u=d[c=0].points):(l-=h.partialLength,u=null)),u&&(m=h,y=(h=u[f]).partialLength));G=T[s].an/2-T[s].add,x.translate(-G,0,0)}else G=T[s].an/2-T[s].add,x.translate(-G,0,0),x.translate(-S[0]*T[s].an*.005,-S[1]*R*.01,0);for(D=0;D<C;D+=1)(I=_[D].a).t.propType&&(V=_[D].s.getMult(T[s].anIndexes[D],E.a[D].s.totalChars),0===r&&0===t.j||(this._hasMaskedPath?V.length?o+=I.t.v*V[0]:o+=I.t.v*V:V.length?r+=I.t.v*V[0]:r+=I.t.v*V));for(t.strokeWidthAnim&&(j=t.sw||0),t.strokeColorAnim&&(N=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(q=[t.fc[0],t.fc[1],t.fc[2]]),D=0;D<C;D+=1)(I=_[D].a).a.propType&&((V=_[D].s.getMult(T[s].anIndexes[D],E.a[D].s.totalChars)).length?x.translate(-I.a.v[0]*V[0],-I.a.v[1]*V[1],I.a.v[2]*V[2]):x.translate(-I.a.v[0]*V,-I.a.v[1]*V,I.a.v[2]*V));for(D=0;D<C;D+=1)(I=_[D].a).s.propType&&((V=_[D].s.getMult(T[s].anIndexes[D],E.a[D].s.totalChars)).length?x.scale(1+(I.s.v[0]-1)*V[0],1+(I.s.v[1]-1)*V[1],1):x.scale(1+(I.s.v[0]-1)*V,1+(I.s.v[1]-1)*V,1));for(D=0;D<C;D+=1){if(I=_[D].a,V=_[D].s.getMult(T[s].anIndexes[D],E.a[D].s.totalChars),I.sk.propType&&(V.length?x.skewFromAxis(-I.sk.v*V[0],I.sa.v*V[1]):x.skewFromAxis(-I.sk.v*V,I.sa.v*V)),I.r.propType&&(V.length?x.rotateZ(-I.r.v*V[2]):x.rotateZ(-I.r.v*V)),I.ry.propType&&(V.length?x.rotateY(I.ry.v*V[1]):x.rotateY(I.ry.v*V)),I.rx.propType&&(V.length?x.rotateX(I.rx.v*V[0]):x.rotateX(I.rx.v*V)),I.o.propType&&(V.length?O+=(I.o.v*V[0]-O)*V[0]:O+=(I.o.v*V-O)*V),t.strokeWidthAnim&&I.sw.propType&&(V.length?j+=I.sw.v*V[0]:j+=I.sw.v*V),t.strokeColorAnim&&I.sc.propType)for(H=0;H<3;H+=1)V.length?N[H]+=(I.sc.v[H]-N[H])*V[0]:N[H]+=(I.sc.v[H]-N[H])*V;if(t.fillColorAnim&&t.fc){if(I.fc.propType)for(H=0;H<3;H+=1)V.length?q[H]+=(I.fc.v[H]-q[H])*V[0]:q[H]+=(I.fc.v[H]-q[H])*V;I.fh.propType&&(q=V.length?addHueToRGB(q,I.fh.v*V[0]):addHueToRGB(q,I.fh.v*V)),I.fs.propType&&(q=V.length?addSaturationToRGB(q,I.fs.v*V[0]):addSaturationToRGB(q,I.fs.v*V)),I.fb.propType&&(q=V.length?addBrightnessToRGB(q,I.fb.v*V[0]):addBrightnessToRGB(q,I.fb.v*V))}}for(D=0;D<C;D+=1)(I=_[D].a).p.propType&&(V=_[D].s.getMult(T[s].anIndexes[D],E.a[D].s.totalChars),this._hasMaskedPath?V.length?x.translate(0,I.p.v[1]*V[0],-I.p.v[2]*V[1]):x.translate(0,I.p.v[1]*V,-I.p.v[2]*V):V.length?x.translate(I.p.v[0]*V[0],I.p.v[1]*V[1],-I.p.v[2]*V[2]):x.translate(I.p.v[0]*V,I.p.v[1]*V,-I.p.v[2]*V));if(t.strokeWidthAnim&&(W=j<0?0:j),t.strokeColorAnim&&($="rgb("+Math.round(255*N[0])+","+Math.round(255*N[1])+","+Math.round(255*N[2])+")"),t.fillColorAnim&&t.fc&&(Z="rgb("+Math.round(255*q[0])+","+Math.round(255*q[1])+","+Math.round(255*q[2])+")"),this._hasMaskedPath){if(x.translate(0,-t.ls),x.translate(0,S[1]*R*.01+i,0),this._pathData.p.v){b=(h.point[1]-m.point[1])/(h.point[0]-m.point[0]);var ht=180*Math.atan(b)/Math.PI;h.point[0]<m.point[0]&&(ht+=180),x.rotate(-ht*Math.PI/180)}x.translate(B,z,0),o-=S[0]*T[s].an*.005,T[s+1]&&Y!==T[s+1].ind&&(o+=T[s].an/2,o+=.001*t.tr*t.finalSize)}else{switch(x.translate(r,i,0),t.ps&&x.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:x.translate(T[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[T[s].line]),0,0);break;case 2:x.translate(T[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[T[s].line])/2,0,0)}x.translate(0,-t.ls),x.translate(G,0,0),x.translate(S[0]*T[s].an*.005,S[1]*R*.01,0),r+=T[s].l+.001*t.tr*t.finalSize}"html"===A?tt=x.toCSS():"svg"===A?tt=x.to2dCSS():et=[x.props[0],x.props[1],x.props[2],x.props[3],x.props[4],x.props[5],x.props[6],x.props[7],x.props[8],x.props[9],x.props[10],x.props[11],x.props[12],x.props[13],x.props[14],x.props[15]],X=O}M<=s?(w=new LetterProps(X,W,$,Z,tt,et),this.renderedLetters.push(w),M+=1,this.lettersChangedFlag=!0):(w=this.renderedLetters[s],this.lettersChangedFlag=w.update(X,W,$,Z,tt,et)||this.lettersChangedFlag)}}},TextAnimatorProperty.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},TextAnimatorProperty.prototype.mHelper=new Matrix,TextAnimatorProperty.prototype.defaultPropsArray=[],extendPrototype([DynamicPropertyContainer],TextAnimatorProperty),ITextElement.prototype.initElement=function(t,e,r){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,r),this.textProperty=new TextProperty(this,t.t,this.dynamicProperties),this.textAnimator=new TextAnimatorProperty(t.t,this.renderType,this),this.initTransform(t,e,r),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},ITextElement.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},ITextElement.prototype.createPathShape=function(t,e){var r,i,s=e.length,a="";for(r=0;r<s;r+=1)"sh"===e[r].ty&&(i=e[r].ks.k,a+=buildShapeString(i,i.i.length,!0,t));return a},ITextElement.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},ITextElement.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},ITextElement.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},ITextElement.prototype.applyTextPropertiesToMatrix=function(t,e,r,i,s){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[r]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[r])/2,0,0)}e.translate(i,s,0)},ITextElement.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},ITextElement.prototype.emptyProp=new LetterProps,ITextElement.prototype.destroy=function(){},ITextElement.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var emptyShapeData={shapes:[]};function SVGTextLottieElement(t,e,r){this.textSpans=[],this.renderType="svg",this.initElement(t,e,r)}function ISolidElement(t,e,r){this.initElement(t,e,r)}function NullElement(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initFrame(),this.initTransform(t,e,r),this.initHierarchy()}function SVGRendererBase(){}function ICompElement(){}function SVGCompElement(t,e,r){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,r),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function SVGRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=createNS("svg");var r="";if(e&&e.title){var i=createNS("title"),s=createElementID();i.setAttribute("id",s),i.textContent=e.title,this.svgElement.appendChild(i),r+=s}if(e&&e.description){var a=createNS("desc"),n=createElementID();a.setAttribute("id",n),a.textContent=e.description,this.svgElement.appendChild(a),r+=" "+n}r&&this.svgElement.setAttribute("aria-labelledby",r);var o=createNS("defs");this.svgElement.appendChild(o);var h=createNS("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],SVGTextLottieElement),SVGTextLottieElement.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=createNS("text"))},SVGTextLottieElement.prototype.buildTextContents=function(t){for(var e=0,r=t.length,i=[],s="";e<r;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(i.push(s),s=""):s+=t[e],e+=1;return i.push(s),i},SVGTextLottieElement.prototype.buildShapeData=function(t,e){if(t.shapes&&t.shapes.length){var r=t.shapes[0];if(r.it){var i=r.it[r.it.length-1];i.s&&(i.s.k[0]=e,i.s.k[1]=e)}}return t},SVGTextLottieElement.prototype.buildNewText=function(){var t,e;this.addDynamicProperty(this);var r=this.textProperty.currentData;this.renderedLetters=createSizedArray(r?r.l.length:0),r.fc?this.layerElement.setAttribute("fill",this.buildColor(r.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),r.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(r.sc)),this.layerElement.setAttribute("stroke-width",r.sw)),this.layerElement.setAttribute("font-size",r.finalSize);var i=this.globalData.fontManager.getFontByName(r.f);if(i.fClass)this.layerElement.setAttribute("class",i.fClass);else{this.layerElement.setAttribute("font-family",i.fFamily);var s=r.fWeight,a=r.fStyle;this.layerElement.setAttribute("font-style",a),this.layerElement.setAttribute("font-weight",s)}this.layerElement.setAttribute("aria-label",r.t);var n,o=r.l||[],h=!!this.globalData.fontManager.chars;e=o.length;var l=this.mHelper,p=this.data.singleShape,f=0,c=0,m=!0,u=.001*r.tr*r.finalSize;if(!p||h||r.sz){var d,y=this.textSpans.length;for(t=0;t<e;t+=1){if(this.textSpans[t]||(this.textSpans[t]={span:null,childSpan:null,glyph:null}),!h||!p||0===t){if(n=y>t?this.textSpans[t].span:createNS(h?"g":"text"),y<=t){if(n.setAttribute("stroke-linecap","butt"),n.setAttribute("stroke-linejoin","round"),n.setAttribute("stroke-miterlimit","4"),this.textSpans[t].span=n,h){var g=createNS("g");n.appendChild(g),this.textSpans[t].childSpan=g}this.textSpans[t].span=n,this.layerElement.appendChild(n)}n.style.display="inherit"}if(l.reset(),p&&(o[t].n&&(f=-u,c+=r.yOffset,c+=m?1:0,m=!1),this.applyTextPropertiesToMatrix(r,l,o[t].line,f,c),f+=o[t].l||0,f+=u),h){var v;if(1===(d=this.globalData.fontManager.getCharData(r.finalText[t],i.fStyle,this.globalData.fontManager.getFontByName(r.f).fFamily)).t)v=new SVGCompElement(d.data,this.globalData,this);else{var b=emptyShapeData;d.data&&d.data.shapes&&(b=this.buildShapeData(d.data,r.finalSize)),v=new SVGShapeElement(b,this.globalData,this)}if(this.textSpans[t].glyph){var P=this.textSpans[t].glyph;this.textSpans[t].childSpan.removeChild(P.layerElement),P.destroy()}this.textSpans[t].glyph=v,v._debug=!0,v.prepareFrame(0),v.renderFrame(),this.textSpans[t].childSpan.appendChild(v.layerElement),1===d.t&&this.textSpans[t].childSpan.setAttribute("transform","scale("+r.finalSize/100+","+r.finalSize/100+")")}else p&&n.setAttribute("transform","translate("+l.props[12]+","+l.props[13]+")"),n.textContent=o[t].val,n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}p&&n&&n.setAttribute("d","")}else{var S=this.textContainer,_="start";switch(r.j){case 1:_="end";break;case 2:_="middle";break;default:_="start"}S.setAttribute("text-anchor",_),S.setAttribute("letter-spacing",u);var E=this.buildTextContents(r.finalText);for(e=E.length,c=r.ps?r.ps[1]+r.ascent:0,t=0;t<e;t+=1)(n=this.textSpans[t].span||createNS("tspan")).textContent=E[t],n.setAttribute("x",0),n.setAttribute("y",c),n.style.display="inherit",S.appendChild(n),this.textSpans[t]||(this.textSpans[t]={span:null,glyph:null}),this.textSpans[t].span=n,c+=r.finalLineHeight;this.layerElement.appendChild(S)}for(;t<this.textSpans.length;)this.textSpans[t].span.style.display="none",t+=1;this._sizeChanged=!0},SVGTextLottieElement.prototype.sourceRectAtTime=function(){if(this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged){this._sizeChanged=!1;var t=this.layerElement.getBBox();this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}}return this.bbox},SVGTextLottieElement.prototype.getValue=function(){var t,e,r=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<r;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf&&(this._mdf=!0))},SVGTextLottieElement.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){var t,e;this._sizeChanged=!0;var r,i,s,a=this.textAnimator.renderedLetters,n=this.textProperty.currentData.l;for(e=n.length,t=0;t<e;t+=1)n[t].n||(r=a[t],i=this.textSpans[t].span,(s=this.textSpans[t].glyph)&&s.renderFrame(),r._mdf.m&&i.setAttribute("transform",r.m),r._mdf.o&&i.setAttribute("opacity",r.o),r._mdf.sw&&i.setAttribute("stroke-width",r.sw),r._mdf.sc&&i.setAttribute("stroke",r.sc),r._mdf.fc&&i.setAttribute("fill",r.fc))}},extendPrototype([IImageElement],ISolidElement),ISolidElement.prototype.createContent=function(){var t=createNS("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},NullElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},NullElement.prototype.renderFrame=function(){},NullElement.prototype.getBaseElement=function(){return null},NullElement.prototype.destroy=function(){},NullElement.prototype.sourceRectAtTime=function(){},NullElement.prototype.hide=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement],NullElement),extendPrototype([BaseRenderer],SVGRendererBase),SVGRendererBase.prototype.createNull=function(t){return new NullElement(t,this.globalData,this)},SVGRendererBase.prototype.createShape=function(t){return new SVGShapeElement(t,this.globalData,this)},SVGRendererBase.prototype.createText=function(t){return new SVGTextLottieElement(t,this.globalData,this)},SVGRendererBase.prototype.createImage=function(t){return new IImageElement(t,this.globalData,this)},SVGRendererBase.prototype.createSolid=function(t){return new ISolidElement(t,this.globalData,this)},SVGRendererBase.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var r=createNS("clipPath"),i=createNS("rect");i.setAttribute("width",t.w),i.setAttribute("height",t.h),i.setAttribute("x",0),i.setAttribute("y",0);var s=createElementID();r.setAttribute("id",s),r.appendChild(i),this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),e.appendChild(r),this.layers=t.layers,this.elements=createSizedArray(t.layers.length)},SVGRendererBase.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},SVGRendererBase.prototype.updateContainerSize=function(){},SVGRendererBase.prototype.findIndexByInd=function(t){var e=0,r=this.layers.length;for(e=0;e<r;e+=1)if(this.layers[e].ind===t)return e;return-1},SVGRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){e[t]=!0;var r=this.createItem(this.layers[t]);if(e[t]=r,getExpressionsPlugin()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(r),r.initExpressions()),this.appendElementInPos(r,t),this.layers[t].tt){var i="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1;if(-1===i)return;if(this.elements[i]&&!0!==this.elements[i]){var s=e[i].getMatte(this.layers[t].tt);r.setMatte(s)}else this.buildItem(i),this.addPendingElement(r)}}},SVGRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,r=this.elements.length;e<r;){if(this.elements[e]===t){var i="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,s=this.elements[i].getMatte(this.layers[e].tt);t.setMatte(s);break}e+=1}}},SVGRendererBase.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){var e;null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var r=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=r-1;e>=0;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<r;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},SVGRendererBase.prototype.appendElementInPos=function(t,e){var r=t.getBaseElement();if(r){for(var i,s=0;s<e;)this.elements[s]&&!0!==this.elements[s]&&this.elements[s].getBaseElement()&&(i=this.elements[s].getBaseElement()),s+=1;i?this.layerElement.insertBefore(r,i):this.layerElement.appendChild(r)}},SVGRendererBase.prototype.hide=function(){this.layerElement.style.display="none"},SVGRendererBase.prototype.show=function(){this.layerElement.style.display="block"},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement,RenderableDOMElement],ICompElement),ICompElement.prototype.initElement=function(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initTransform(t,e,r),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},ICompElement.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var r,i=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),r=i-1;r>=0;r-=1)(this.completeLayers||this.elements[r])&&(this.elements[r].prepareFrame(this.renderedFrame-this.layers[r].st),this.elements[r]._mdf&&(this._mdf=!0))}},ICompElement.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},ICompElement.prototype.setElements=function(t){this.elements=t},ICompElement.prototype.getElements=function(){return this.elements},ICompElement.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},ICompElement.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},extendPrototype([SVGRendererBase,ICompElement,SVGBaseElement],SVGCompElement),SVGCompElement.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},extendPrototype([SVGRendererBase],SVGRenderer),SVGRenderer.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},registerRenderer("svg",SVGRenderer),ShapeModifiers.registerModifier("tm",TrimModifier),ShapeModifiers.registerModifier("pb",PuckerAndBloatModifier),ShapeModifiers.registerModifier("rp",RepeaterModifier),ShapeModifiers.registerModifier("rd",RoundCornersModifier),ShapeModifiers.registerModifier("zz",ZigZagModifier),ShapeModifiers.registerModifier("op",OffsetPathModifier);var CompExpressionInterface=function(t){function e(e){for(var r=0,i=t.layers.length;r<i;){if(t.layers[r].nm===e||t.layers[r].ind===e)return t.elements[r].layerInterface;r+=1}return null}return Object.defineProperty(e,"_name",{value:t.data.nm}),e.layer=e,e.pixelAspect=1,e.height=t.data.h||t.globalData.compSize.h,e.width=t.data.w||t.globalData.compSize.w,e.pixelAspect=1,e.frameDuration=1/t.globalData.frameRate,e.displayStartTime=0,e.numLayers=t.layers.length,e};function _typeof$2(t){return _typeof$2="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$2(t)}function seedRandom(t,e){var r,i=this,s=256,a=e.pow(s,6),n=e.pow(2,52),o=2*n,h=255;function l(t){var e,r=t.length,i=this,a=0,n=i.i=i.j=0,o=i.S=[];for(r||(t=[r++]);a<s;)o[a]=a++;for(a=0;a<s;a++)o[a]=o[n=h&n+t[a%r]+(e=o[a])],o[n]=e;i.g=function(t){for(var e,r=0,a=i.i,n=i.j,o=i.S;t--;)e=o[a=h&a+1],r=r*s+o[h&(o[a]=o[n=h&n+e])+(o[n]=e)];return i.i=a,i.j=n,r}}function p(t,e){return e.i=t.i,e.j=t.j,e.S=t.S.slice(),e}function f(t,e){var r,i=[],s=_typeof$2(t);if(e&&"object"==s)for(r in t)try{i.push(f(t[r],e-1))}catch(t){}return i.length?i:"string"==s?t:t+"\0"}function c(t,e){for(var r,i=t+"",s=0;s<i.length;)e[h&s]=h&(r^=19*e[h&s])+i.charCodeAt(s++);return m(e)}function m(t){return String.fromCharCode.apply(0,t)}e.seedrandom=function(h,u,d){var y=[],g=c(f((u=!0===u?{entropy:!0}:u||{}).entropy?[h,m(t)]:null===h?function(){try{r;var e=new Uint8Array(s);return(i.crypto||i.msCrypto).getRandomValues(e),m(e)}catch(e){var a=i.navigator,n=a&&a.plugins;return[+new Date,i,n,i.screen,m(t)]}}():h,3),y),v=new l(y),b=function(){for(var t=v.g(6),e=a,r=0;t<n;)t=(t+r)*s,e*=s,r=v.g(1);for(;t>=o;)t/=2,e/=2,r>>>=1;return(t+r)/e};return b.int32=function(){return 0|v.g(4)},b.quick=function(){return v.g(4)/4294967296},b.double=b,c(m(v.S),t),(u.pass||d||function(t,r,i,s){return s&&(s.S&&p(s,v),t.state=function(){return p(v,{})}),i?(e.random=t,r):t})(b,g,"global"in u?u.global:this==e,u.state)},c(e.random(),t)}function initialize$2(t){seedRandom([],t)}var propTypes={SHAPE:"shape"};function _typeof$1(t){return _typeof$1="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$1(t)}var ExpressionManager=function(){var ob={},Math=BMMath,window=null,document=null,XMLHttpRequest=null,fetch=null,frames=null,_lottieGlobal={};function resetFrame(){_lottieGlobal={}}function $bm_isInstanceOfArray(t){return t.constructor===Array||t.constructor===Float32Array}function isNumerable(t,e){return"number"===t||e instanceof Number||"boolean"===t||"string"===t}function $bm_neg(t){var e=_typeof$1(t);if("number"===e||t instanceof Number||"boolean"===e)return-t;if($bm_isInstanceOfArray(t)){var r,i=t.length,s=[];for(r=0;r<i;r+=1)s[r]=-t[r];return s}return t.propType?t.v:-t}initialize$2(BMMath);var easeInBez=BezierFactory.getBezierEasing(.333,0,.833,.833,"easeIn").get,easeOutBez=BezierFactory.getBezierEasing(.167,.167,.667,1,"easeOut").get,easeInOutBez=BezierFactory.getBezierEasing(.33,0,.667,1,"easeInOut").get;function sum(t,e){var r=_typeof$1(t),i=_typeof$1(e);if(isNumerable(r,t)&&isNumerable(i,e)||"string"===r||"string"===i)return t+e;if($bm_isInstanceOfArray(t)&&isNumerable(i,e))return(t=t.slice(0))[0]+=e,t;if(isNumerable(r,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t+e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]+e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}var add=sum;function sub(t,e){var r=_typeof$1(t),i=_typeof$1(e);if(isNumerable(r,t)&&isNumerable(i,e))return"string"===r&&(t=parseInt(t,10)),"string"===i&&(e=parseInt(e,10)),t-e;if($bm_isInstanceOfArray(t)&&isNumerable(i,e))return(t=t.slice(0))[0]-=e,t;if(isNumerable(r,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t-e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]-e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}function mul(t,e){var r,i,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t*e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t[i]*e;return r}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t*e[i];return r}return 0}function div(t,e){var r,i,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t/e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t[i]/e;return r}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t/e[i];return r}return 0}function mod(t,e){return"string"==typeof t&&(t=parseInt(t,10)),"string"==typeof e&&(e=parseInt(e,10)),t%e}var $bm_sum=sum,$bm_sub=sub,$bm_mul=mul,$bm_div=div,$bm_mod=mod;function clamp(t,e,r){if(e>r){var i=r;r=e,e=i}return Math.min(Math.max(t,e),r)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return e=e||0,Math.abs(t-e);var r;e||(e=helperLengthArray);var i=Math.min(t.length,e.length),s=0;for(r=0;r<i;r+=1)s+=Math.pow(e[r]-t[r],2);return Math.sqrt(s)}function normalize(t){return div(t,length(t))}function rgbToHsl(t){var e,r,i=t[0],s=t[1],a=t[2],n=Math.max(i,s,a),o=Math.min(i,s,a),h=(n+o)/2;if(n===o)e=0,r=0;else{var l=n-o;switch(r=h>.5?l/(2-n-o):l/(n+o),n){case i:e=(s-a)/l+(s<a?6:0);break;case s:e=(a-i)/l+2;break;case a:e=(i-s)/l+4}e/=6}return[e,r,h,t[3]]}function hue2rgb(t,e,r){return r<0&&(r+=1),r>1&&(r-=1),r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t}function hslToRgb(t){var e,r,i,s=t[0],a=t[1],n=t[2];if(0===a)e=n,i=n,r=n;else{var o=n<.5?n*(1+a):n+a-n*a,h=2*n-o;e=hue2rgb(h,o,s+1/3),r=hue2rgb(h,o,s),i=hue2rgb(h,o,s-1/3)}return[e,r,i,t[3]]}function linear(t,e,r,i,s){if(void 0!==i&&void 0!==s||(i=e,s=r,e=0,r=1),r<e){var a=r;r=e,e=a}if(t<=e)return i;if(t>=r)return s;var n,o=r===e?0:(t-e)/(r-e);if(!i.length)return i+(s-i)*o;var h=i.length,l=createTypedArray("float32",h);for(n=0;n<h;n+=1)l[n]=i[n]+(s[n]-i[n])*o;return l}function random(t,e){if(void 0===e&&(void 0===t?(t=0,e=1):(e=t,t=void 0)),e.length){var r,i=e.length;t||(t=createTypedArray("float32",i));var s=createTypedArray("float32",i),a=BMMath.random();for(r=0;r<i;r+=1)s[r]=t[r]+a*(e[r]-t[r]);return s}return void 0===t&&(t=0),t+BMMath.random()*(e-t)}function createPath(t,e,r,i){var s,a=t.length,n=shapePool.newElement();n.setPathData(!!i,a);var o,h,l=[0,0];for(s=0;s<a;s+=1)o=e&&e[s]?e[s]:l,h=r&&r[s]?r[s]:l,n.setTripleAt(t[s][0],t[s][1],h[0]+t[s][0],h[1]+t[s][1],o[0]+t[s][0],o[1]+t[s][1],s,!0);return n}function initiateExpression(elem,data,property){function noOp(t){return t}if(!elem.globalData.renderConfig.runExpressions)return noOp;var val=data.x,needsVelocity=/velocity(?![\w\d])/.test(val),_needsRandom=-1!==val.indexOf("random"),elemType=elem.data.ty,transform,$bm_transform,content,effect,thisProperty=property;thisProperty.valueAtTime=thisProperty.getValueAtTime,Object.defineProperty(thisProperty,"value",{get:function(){return thisProperty.v}}),elem.comp.frameDuration=1/elem.comp.globalData.frameRate,elem.comp.displayStartTime=0;var inPoint=elem.data.ip/elem.comp.globalData.frameRate,outPoint=elem.data.op/elem.comp.globalData.frameRate,width=elem.data.sw?elem.data.sw:0,height=elem.data.sh?elem.data.sh:0,name=elem.data.nm,loopIn,loop_in,loopOut,loop_out,smooth,toWorld,fromWorld,fromComp,toComp,fromCompToSurface,position,rotation,anchorPoint,scale,thisLayer,thisComp,mask,valueAtTime,velocityAtTime,scoped_bm_rt,expression_function=eval("[function _expression_function(){"+val+";scoped_bm_rt=$bm_rt}]")[0],numKeys=property.kf?data.k.length:0,active=!this.data||!0!==this.data.hd,wiggle=function(t,e){var r,i,s=this.pv.length?this.pv.length:1,a=createTypedArray("float32",s);var n=Math.floor(5*time);for(r=0,i=0;r<n;){for(i=0;i<s;i+=1)a[i]+=-e+2*e*BMMath.random();r+=1}var o=5*time,h=o-Math.floor(o),l=createTypedArray("float32",s);if(s>1){for(i=0;i<s;i+=1)l[i]=this.pv[i]+a[i]+(-e+2*e*BMMath.random())*h;return l}return this.pv+a[0]+(-e+2*e*BMMath.random())*h}.bind(this);function loopInDuration(t,e){return loopIn(t,e,!0)}function loopOutDuration(t,e){return loopOut(t,e,!0)}thisProperty.loopIn&&(loopIn=thisProperty.loopIn.bind(thisProperty),loop_in=loopIn),thisProperty.loopOut&&(loopOut=thisProperty.loopOut.bind(thisProperty),loop_out=loopOut),thisProperty.smooth&&(smooth=thisProperty.smooth.bind(thisProperty)),this.getValueAtTime&&(valueAtTime=this.getValueAtTime.bind(this)),this.getVelocityAtTime&&(velocityAtTime=this.getVelocityAtTime.bind(this));var comp=elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface),time,velocity,value,text,textIndex,textTotal,selectorValue;function lookAt(t,e){var r=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],i=Math.atan2(r[0],Math.sqrt(r[1]*r[1]+r[2]*r[2]))/degToRads;return[-Math.atan2(r[1],r[2])/degToRads,i,0]}function easeOut(t,e,r,i,s){return applyEase(easeOutBez,t,e,r,i,s)}function easeIn(t,e,r,i,s){return applyEase(easeInBez,t,e,r,i,s)}function ease(t,e,r,i,s){return applyEase(easeInOutBez,t,e,r,i,s)}function applyEase(t,e,r,i,s,a){void 0===s?(s=r,a=i):e=(e-r)/(i-r),e>1?e=1:e<0&&(e=0);var n=t(e);if($bm_isInstanceOfArray(s)){var o,h=s.length,l=createTypedArray("float32",h);for(o=0;o<h;o+=1)l[o]=(a[o]-s[o])*n+s[o];return l}return(a-s)*n+s}function nearestKey(t){var e,r,i,s=data.k.length;if(data.k.length&&"number"!=typeof data.k[0])if(r=-1,(t*=elem.comp.globalData.frameRate)<data.k[0].t)r=1,i=data.k[0].t;else{for(e=0;e<s-1;e+=1){if(t===data.k[e].t){r=e+1,i=data.k[e].t;break}if(t>data.k[e].t&&t<data.k[e+1].t){t-data.k[e].t>data.k[e+1].t-t?(r=e+2,i=data.k[e+1].t):(r=e+1,i=data.k[e].t);break}}-1===r&&(r=e+1,i=data.k[e].t)}else r=0,i=0;var a={};return a.index=r,a.time=i/elem.comp.globalData.frameRate,a}function key(t){var e,r,i;if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]};var s=Object.prototype.hasOwnProperty.call(data.k[t],"s")?data.k[t].s:data.k[t-1].e;for(i=s.length,r=0;r<i;r+=1)e[r]=s[r],e.value[r]=s[r];return e}function framesToTime(t,e){return e||(e=elem.comp.globalData.frameRate),t/e}function timeToFrames(t,e){return t||0===t||(t=time),e||(e=elem.comp.globalData.frameRate),t*e}function seedRandom(t){BMMath.seedrandom(randSeed+t)}function sourceRectAtTime(){return elem.sourceRectAtTime()}function substring(t,e){return"string"==typeof value?void 0===e?value.substring(t):value.substring(t,e):""}function substr(t,e){return"string"==typeof value?void 0===e?value.substr(t):value.substr(t,e):""}function posterizeTime(t){time=0===t?0:Math.floor(time*t)/t,value=valueAtTime(time)}var index=elem.data.ind,hasParent=!(!elem.hierarchy||!elem.hierarchy.length),parent,randSeed=Math.floor(1e6*Math.random()),globalData=elem.globalData;function executeExpression(t){return value=t,this.frameExpressionId===elem.globalData.frameId&&"textSelector"!==this.propType?value:("textSelector"===this.propType&&(textIndex=this.textIndex,textTotal=this.textTotal,selectorValue=this.selectorValue),thisLayer||(text=elem.layerInterface.text,thisLayer=elem.layerInterface,thisComp=elem.comp.compInterface,toWorld=thisLayer.toWorld.bind(thisLayer),fromWorld=thisLayer.fromWorld.bind(thisLayer),fromComp=thisLayer.fromComp.bind(thisLayer),toComp=thisLayer.toComp.bind(thisLayer),mask=thisLayer.mask?thisLayer.mask.bind(thisLayer):null,fromCompToSurface=fromComp),transform||(transform=elem.layerInterface("ADBE Transform Group"),$bm_transform=transform,transform&&(anchorPoint=transform.anchorPoint)),4!==elemType||content||(content=thisLayer("ADBE Root Vectors Group")),effect||(effect=thisLayer(4)),(hasParent=!(!elem.hierarchy||!elem.hierarchy.length))&&!parent&&(parent=elem.hierarchy[0].layerInterface),time=this.comp.renderedFrame/this.comp.globalData.frameRate,_needsRandom&&seedRandom(randSeed+time),needsVelocity&&(velocity=velocityAtTime(time)),expression_function(),this.frameExpressionId=elem.globalData.frameId,scoped_bm_rt=scoped_bm_rt.propType===propTypes.SHAPE?scoped_bm_rt.v:scoped_bm_rt)}return executeExpression.__preventDeadCodeRemoval=[$bm_transform,anchorPoint,time,velocity,inPoint,outPoint,width,height,name,loop_in,loop_out,smooth,toComp,fromCompToSurface,toWorld,fromWorld,mask,position,rotation,scale,thisComp,numKeys,active,wiggle,loopInDuration,loopOutDuration,comp,lookAt,easeOut,easeIn,ease,nearestKey,key,text,textIndex,textTotal,selectorValue,framesToTime,timeToFrames,sourceRectAtTime,substring,substr,posterizeTime,index,globalData],executeExpression}return ob.initiateExpression=initiateExpression,ob.__preventDeadCodeRemoval=[window,document,XMLHttpRequest,fetch,frames,$bm_neg,add,$bm_sum,$bm_sub,$bm_mul,$bm_div,$bm_mod,clamp,radians_to_degrees,degreesToRadians,degrees_to_radians,normalize,rgbToHsl,hslToRgb,linear,random,createPath,_lottieGlobal],ob.resetFrame=resetFrame,ob}(),Expressions=function(){var t={};return t.initExpressions=function(t){var e=0,r=[];t.renderer.compInterface=CompExpressionInterface(t.renderer),t.renderer.globalData.projectInterface.registerComposition(t.renderer),t.renderer.globalData.pushExpression=function(){e+=1},t.renderer.globalData.popExpression=function(){0==(e-=1)&&function(){var t,e=r.length;for(t=0;t<e;t+=1)r[t].release();r.length=0}()},t.renderer.globalData.registerExpressionProperty=function(t){-1===r.indexOf(t)&&r.push(t)}},t.resetFrame=ExpressionManager.resetFrame,t}(),MaskManagerInterface=function(){function t(t,e){this._mask=t,this._data=e}Object.defineProperty(t.prototype,"maskPath",{get:function(){return this._mask.prop.k&&this._mask.prop.getValue(),this._mask.prop}}),Object.defineProperty(t.prototype,"maskOpacity",{get:function(){return this._mask.op.k&&this._mask.op.getValue(),100*this._mask.op.v}});return function(e){var r,i=createSizedArray(e.viewData.length),s=e.viewData.length;for(r=0;r<s;r+=1)i[r]=new t(e.viewData[r],e.masksProperties[r]);return function(t){for(r=0;r<s;){if(e.masksProperties[r].nm===t)return i[r];r+=1}return null}}}(),ExpressionPropertyInterface=function(){var t={pv:0,v:0,mult:1},e={pv:[0,0,0],v:[0,0,0],mult:1};function r(t,e,r){Object.defineProperty(t,"velocity",{get:function(){return e.getVelocityAtTime(e.comp.currentFrame)}}),t.numKeys=e.keyframes?e.keyframes.length:0,t.key=function(i){if(!t.numKeys)return 0;var s="";s="s"in e.keyframes[i-1]?e.keyframes[i-1].s:"e"in e.keyframes[i-2]?e.keyframes[i-2].e:e.keyframes[i-2].s;var a="unidimensional"===r?new Number(s):Object.assign({},s);return a.time=e.keyframes[i-1].t/e.elem.comp.globalData.frameRate,a.value="unidimensional"===r?s[0]:s,a},t.valueAtTime=e.getValueAtTime,t.speedAtTime=e.getSpeedAtTime,t.velocityAtTime=e.getVelocityAtTime,t.propertyGroup=e.propertyGroup}function i(){return t}return function(s){return s?"unidimensional"===s.propType?function(e){e&&"pv"in e||(e=t);var i=1/e.mult,s=e.pv*i,a=new Number(s);return a.value=s,r(a,e,"unidimensional"),function(){return e.k&&e.getValue(),s=e.v*i,a.value!==s&&((a=new Number(s)).value=s,r(a,e,"unidimensional")),a}}(s):function(t){t&&"pv"in t||(t=e);var i=1/t.mult,s=t.data&&t.data.l||t.pv.length,a=createTypedArray("float32",s),n=createTypedArray("float32",s);return a.value=n,r(a,t,"multidimensional"),function(){t.k&&t.getValue();for(var e=0;e<s;e+=1)n[e]=t.v[e]*i,a[e]=n[e];return a}}(s):i}}(),TransformExpressionInterface=function(t){function e(t){switch(t){case"scale":case"Scale":case"ADBE Scale":case 6:return e.scale;case"rotation":case"Rotation":case"ADBE Rotation":case"ADBE Rotate Z":case 10:return e.rotation;case"ADBE Rotate X":return e.xRotation;case"ADBE Rotate Y":return e.yRotation;case"position":case"Position":case"ADBE Position":case 2:return e.position;case"ADBE Position_0":return e.xPosition;case"ADBE Position_1":return e.yPosition;case"ADBE Position_2":return e.zPosition;case"anchorPoint":case"AnchorPoint":case"Anchor Point":case"ADBE AnchorPoint":case 1:return e.anchorPoint;case"opacity":case"Opacity":case 11:return e.opacity;default:return null}}var r,i,s,a;return Object.defineProperty(e,"rotation",{get:ExpressionPropertyInterface(t.r||t.rz)}),Object.defineProperty(e,"zRotation",{get:ExpressionPropertyInterface(t.rz||t.r)}),Object.defineProperty(e,"xRotation",{get:ExpressionPropertyInterface(t.rx)}),Object.defineProperty(e,"yRotation",{get:ExpressionPropertyInterface(t.ry)}),Object.defineProperty(e,"scale",{get:ExpressionPropertyInterface(t.s)}),t.p?a=ExpressionPropertyInterface(t.p):(r=ExpressionPropertyInterface(t.px),i=ExpressionPropertyInterface(t.py),t.pz&&(s=ExpressionPropertyInterface(t.pz))),Object.defineProperty(e,"position",{get:function(){return t.p?a():[r(),i(),s?s():0]}}),Object.defineProperty(e,"xPosition",{get:ExpressionPropertyInterface(t.px)}),Object.defineProperty(e,"yPosition",{get:ExpressionPropertyInterface(t.py)}),Object.defineProperty(e,"zPosition",{get:ExpressionPropertyInterface(t.pz)}),Object.defineProperty(e,"anchorPoint",{get:ExpressionPropertyInterface(t.a)}),Object.defineProperty(e,"opacity",{get:ExpressionPropertyInterface(t.o)}),Object.defineProperty(e,"skew",{get:ExpressionPropertyInterface(t.sk)}),Object.defineProperty(e,"skewAxis",{get:ExpressionPropertyInterface(t.sa)}),Object.defineProperty(e,"orientation",{get:ExpressionPropertyInterface(t.or)}),e},LayerExpressionInterface=function(){function t(t){var e=new Matrix;void 0!==t?this._elem.finalTransform.mProp.getValueAtTime(t).clone(e):this._elem.finalTransform.mProp.applyToMatrix(e);return e}function e(t,e){var r=this.getMatrix(e);return r.props[12]=0,r.props[13]=0,r.props[14]=0,this.applyPoint(r,t)}function r(t,e){var r=this.getMatrix(e);return this.applyPoint(r,t)}function i(t,e){var r=this.getMatrix(e);return r.props[12]=0,r.props[13]=0,r.props[14]=0,this.invertPoint(r,t)}function s(t,e){var r=this.getMatrix(e);return this.invertPoint(r,t)}function a(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var r,i=this._elem.hierarchy.length;for(r=0;r<i;r+=1)this._elem.hierarchy[r].finalTransform.mProp.applyToMatrix(t)}return t.applyToPointArray(e[0],e[1],e[2]||0)}function n(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var r,i=this._elem.hierarchy.length;for(r=0;r<i;r+=1)this._elem.hierarchy[r].finalTransform.mProp.applyToMatrix(t)}return t.inversePoint(e)}function o(t){var e=new Matrix;if(e.reset(),this._elem.finalTransform.mProp.applyToMatrix(e),this._elem.hierarchy&&this._elem.hierarchy.length){var r,i=this._elem.hierarchy.length;for(r=0;r<i;r+=1)this._elem.hierarchy[r].finalTransform.mProp.applyToMatrix(e);return e.inversePoint(t)}return e.inversePoint(t)}function h(){return[1,1,1,1]}return function(l){var p;function f(t){switch(t){case"ADBE Root Vectors Group":case"Contents":case 2:return f.shapeInterface;case 1:case 6:case"Transform":case"transform":case"ADBE Transform Group":return p;case 4:case"ADBE Effect Parade":case"effects":case"Effects":return f.effect;case"ADBE Text Properties":return f.textInterface;default:return null}}f.getMatrix=t,f.invertPoint=n,f.applyPoint=a,f.toWorld=r,f.toWorldVec=e,f.fromWorld=s,f.fromWorldVec=i,f.toComp=r,f.fromComp=o,f.sampleImage=h,f.sourceRectAtTime=l.sourceRectAtTime.bind(l),f._elem=l;var c=getDescriptor(p=TransformExpressionInterface(l.finalTransform.mProp),"anchorPoint");return Object.defineProperties(f,{hasParent:{get:function(){return l.hierarchy.length}},parent:{get:function(){return l.hierarchy[0].layerInterface}},rotation:getDescriptor(p,"rotation"),scale:getDescriptor(p,"scale"),position:getDescriptor(p,"position"),opacity:getDescriptor(p,"opacity"),anchorPoint:c,anchor_point:c,transform:{get:function(){return p}},active:{get:function(){return l.isInRange}}}),f.startTime=l.data.st,f.index=l.data.ind,f.source=l.data.refId,f.height=0===l.data.ty?l.data.h:100,f.width=0===l.data.ty?l.data.w:100,f.inPoint=l.data.ip/l.comp.globalData.frameRate,f.outPoint=l.data.op/l.comp.globalData.frameRate,f._name=l.data.nm,f.registerMaskInterface=function(t){f.mask=new MaskManagerInterface(t,l)},f.registerEffectsInterface=function(t){f.effect=t},f}}(),propertyGroupFactory=function(t,e){return function(r){return(r=void 0===r?1:r)<=0?t:e(r-1)}},PropertyInterface=function(t,e){var r={_name:t};return function(t){return(t=void 0===t?1:t)<=0?r:e(t-1)}},EffectsExpressionInterface=function(){function t(r,i,s,a){function n(t){for(var e=r.ef,i=0,s=e.length;i<s;){if(t===e[i].nm||t===e[i].mn||t===e[i].ix)return 5===e[i].ty?l[i]:l[i]();i+=1}throw new Error}var o,h=propertyGroupFactory(n,s),l=[],p=r.ef.length;for(o=0;o<p;o+=1)5===r.ef[o].ty?l.push(t(r.ef[o],i.effectElements[o],i.effectElements[o].propertyGroup,a)):l.push(e(i.effectElements[o],r.ef[o].ty,a,h));return"ADBE Color Control"===r.mn&&Object.defineProperty(n,"color",{get:function(){return l[0]()}}),Object.defineProperties(n,{numProperties:{get:function(){return r.np}},_name:{value:r.nm},propertyGroup:{value:h}}),n.enabled=0!==r.en,n.active=n.enabled,n}function e(t,e,r,i){var s=ExpressionPropertyInterface(t.p);return t.p.setGroupProperty&&t.p.setGroupProperty(PropertyInterface("",i)),function(){return 10===e?r.comp.compInterface(t.p.v):s()}}return{createEffectsInterface:function(e,r){if(e.effectsManager){var i,s=[],a=e.data.ef,n=e.effectsManager.effectElements.length;for(i=0;i<n;i+=1)s.push(t(a[i],e.effectsManager.effectElements[i],r,e));var o=e.data.ef||[],h=function(t){for(i=0,n=o.length;i<n;){if(t===o[i].nm||t===o[i].mn||t===o[i].ix)return s[i];i+=1}return null};return Object.defineProperty(h,"numProperties",{get:function(){return o.length}}),h}return null}}}(),ShapePathInterface=function(t,e,r){var i=e.sh;function s(t){return"Shape"===t||"shape"===t||"Path"===t||"path"===t||"ADBE Vector Shape"===t||2===t?s.path:null}var a=propertyGroupFactory(s,r);return i.setGroupProperty(PropertyInterface("Path",a)),Object.defineProperties(s,{path:{get:function(){return i.k&&i.getValue(),i}},shape:{get:function(){return i.k&&i.getValue(),i}},_name:{value:t.nm},ix:{value:t.ix},propertyIndex:{value:t.ix},mn:{value:t.mn},propertyGroup:{value:r}}),s},ShapeExpressionInterface=function(){function t(t,o,m){var u,d=[],y=t?t.length:0;for(u=0;u<y;u+=1)"gr"===t[u].ty?d.push(e(t[u],o[u],m)):"fl"===t[u].ty?d.push(r(t[u],o[u],m)):"st"===t[u].ty?d.push(a(t[u],o[u],m)):"tm"===t[u].ty?d.push(n(t[u],o[u],m)):"tr"===t[u].ty||("el"===t[u].ty?d.push(h(t[u],o[u],m)):"sr"===t[u].ty?d.push(l(t[u],o[u],m)):"sh"===t[u].ty?d.push(ShapePathInterface(t[u],o[u],m)):"rc"===t[u].ty?d.push(p(t[u],o[u],m)):"rd"===t[u].ty?d.push(f(t[u],o[u],m)):"rp"===t[u].ty?d.push(c(t[u],o[u],m)):"gf"===t[u].ty?d.push(i(t[u],o[u],m)):d.push(s(t[u],o[u])));return d}function e(e,r,i){var s=function(t){switch(t){case"ADBE Vectors Group":case"Contents":case 2:return s.content;default:return s.transform}};s.propertyGroup=propertyGroupFactory(s,i);var a=function(e,r,i){var s,a=function(t){for(var e=0,r=s.length;e<r;){if(s[e]._name===t||s[e].mn===t||s[e].propertyIndex===t||s[e].ix===t||s[e].ind===t)return s[e];e+=1}return"number"==typeof t?s[t-1]:null};a.propertyGroup=propertyGroupFactory(a,i),s=t(e.it,r.it,a.propertyGroup),a.numProperties=s.length;var n=o(e.it[e.it.length-1],r.it[r.it.length-1],a.propertyGroup);return a.transform=n,a.propertyIndex=e.cix,a._name=e.nm,a}(e,r,s.propertyGroup),n=o(e.it[e.it.length-1],r.it[r.it.length-1],s.propertyGroup);return s.content=a,s.transform=n,Object.defineProperty(s,"_name",{get:function(){return e.nm}}),s.numProperties=e.np,s.propertyIndex=e.ix,s.nm=e.nm,s.mn=e.mn,s}function r(t,e,r){function i(t){return"Color"===t||"color"===t?i.color:"Opacity"===t||"opacity"===t?i.opacity:null}return Object.defineProperties(i,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",r)),e.o.setGroupProperty(PropertyInterface("Opacity",r)),i}function i(t,e,r){function i(t){return"Start Point"===t||"start point"===t?i.startPoint:"End Point"===t||"end point"===t?i.endPoint:"Opacity"===t||"opacity"===t?i.opacity:null}return Object.defineProperties(i,{startPoint:{get:ExpressionPropertyInterface(e.s)},endPoint:{get:ExpressionPropertyInterface(e.e)},opacity:{get:ExpressionPropertyInterface(e.o)},type:{get:function(){return"a"}},_name:{value:t.nm},mn:{value:t.mn}}),e.s.setGroupProperty(PropertyInterface("Start Point",r)),e.e.setGroupProperty(PropertyInterface("End Point",r)),e.o.setGroupProperty(PropertyInterface("Opacity",r)),i}function s(){return function(){return null}}function a(t,e,r){var i,s=propertyGroupFactory(l,r),a=propertyGroupFactory(h,s);function n(r){Object.defineProperty(h,t.d[r].nm,{get:ExpressionPropertyInterface(e.d.dataProps[r].p)})}var o=t.d?t.d.length:0,h={};for(i=0;i<o;i+=1)n(i),e.d.dataProps[i].p.setGroupProperty(a);function l(t){return"Color"===t||"color"===t?l.color:"Opacity"===t||"opacity"===t?l.opacity:"Stroke Width"===t||"stroke width"===t?l.strokeWidth:null}return Object.defineProperties(l,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},strokeWidth:{get:ExpressionPropertyInterface(e.w)},dash:{get:function(){return h}},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",s)),e.o.setGroupProperty(PropertyInterface("Opacity",s)),e.w.setGroupProperty(PropertyInterface("Stroke Width",s)),l}function n(t,e,r){function i(e){return e===t.e.ix||"End"===e||"end"===e?i.end:e===t.s.ix?i.start:e===t.o.ix?i.offset:null}var s=propertyGroupFactory(i,r);return i.propertyIndex=t.ix,e.s.setGroupProperty(PropertyInterface("Start",s)),e.e.setGroupProperty(PropertyInterface("End",s)),e.o.setGroupProperty(PropertyInterface("Offset",s)),i.propertyIndex=t.ix,i.propertyGroup=r,Object.defineProperties(i,{start:{get:ExpressionPropertyInterface(e.s)},end:{get:ExpressionPropertyInterface(e.e)},offset:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm}}),i.mn=t.mn,i}function o(t,e,r){function i(e){return t.a.ix===e||"Anchor Point"===e?i.anchorPoint:t.o.ix===e||"Opacity"===e?i.opacity:t.p.ix===e||"Position"===e?i.position:t.r.ix===e||"Rotation"===e||"ADBE Vector Rotation"===e?i.rotation:t.s.ix===e||"Scale"===e?i.scale:t.sk&&t.sk.ix===e||"Skew"===e?i.skew:t.sa&&t.sa.ix===e||"Skew Axis"===e?i.skewAxis:null}var s=propertyGroupFactory(i,r);return e.transform.mProps.o.setGroupProperty(PropertyInterface("Opacity",s)),e.transform.mProps.p.setGroupProperty(PropertyInterface("Position",s)),e.transform.mProps.a.setGroupProperty(PropertyInterface("Anchor Point",s)),e.transform.mProps.s.setGroupProperty(PropertyInterface("Scale",s)),e.transform.mProps.r.setGroupProperty(PropertyInterface("Rotation",s)),e.transform.mProps.sk&&(e.transform.mProps.sk.setGroupProperty(PropertyInterface("Skew",s)),e.transform.mProps.sa.setGroupProperty(PropertyInterface("Skew Angle",s))),e.transform.op.setGroupProperty(PropertyInterface("Opacity",s)),Object.defineProperties(i,{opacity:{get:ExpressionPropertyInterface(e.transform.mProps.o)},position:{get:ExpressionPropertyInterface(e.transform.mProps.p)},anchorPoint:{get:ExpressionPropertyInterface(e.transform.mProps.a)},scale:{get:ExpressionPropertyInterface(e.transform.mProps.s)},rotation:{get:ExpressionPropertyInterface(e.transform.mProps.r)},skew:{get:ExpressionPropertyInterface(e.transform.mProps.sk)},skewAxis:{get:ExpressionPropertyInterface(e.transform.mProps.sa)},_name:{value:t.nm}}),i.ty="tr",i.mn=t.mn,i.propertyGroup=r,i}function h(t,e,r){function i(e){return t.p.ix===e?i.position:t.s.ix===e?i.size:null}var s=propertyGroupFactory(i,r);i.propertyIndex=t.ix;var a="tm"===e.sh.ty?e.sh.prop:e.sh;return a.s.setGroupProperty(PropertyInterface("Size",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),Object.defineProperties(i,{size:{get:ExpressionPropertyInterface(a.s)},position:{get:ExpressionPropertyInterface(a.p)},_name:{value:t.nm}}),i.mn=t.mn,i}function l(t,e,r){function i(e){return t.p.ix===e?i.position:t.r.ix===e?i.rotation:t.pt.ix===e?i.points:t.or.ix===e||"ADBE Vector Star Outer Radius"===e?i.outerRadius:t.os.ix===e?i.outerRoundness:!t.ir||t.ir.ix!==e&&"ADBE Vector Star Inner Radius"!==e?t.is&&t.is.ix===e?i.innerRoundness:null:i.innerRadius}var s=propertyGroupFactory(i,r),a="tm"===e.sh.ty?e.sh.prop:e.sh;return i.propertyIndex=t.ix,a.or.setGroupProperty(PropertyInterface("Outer Radius",s)),a.os.setGroupProperty(PropertyInterface("Outer Roundness",s)),a.pt.setGroupProperty(PropertyInterface("Points",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),t.ir&&(a.ir.setGroupProperty(PropertyInterface("Inner Radius",s)),a.is.setGroupProperty(PropertyInterface("Inner Roundness",s))),Object.defineProperties(i,{position:{get:ExpressionPropertyInterface(a.p)},rotation:{get:ExpressionPropertyInterface(a.r)},points:{get:ExpressionPropertyInterface(a.pt)},outerRadius:{get:ExpressionPropertyInterface(a.or)},outerRoundness:{get:ExpressionPropertyInterface(a.os)},innerRadius:{get:ExpressionPropertyInterface(a.ir)},innerRoundness:{get:ExpressionPropertyInterface(a.is)},_name:{value:t.nm}}),i.mn=t.mn,i}function p(t,e,r){function i(e){return t.p.ix===e?i.position:t.r.ix===e?i.roundness:t.s.ix===e||"Size"===e||"ADBE Vector Rect Size"===e?i.size:null}var s=propertyGroupFactory(i,r),a="tm"===e.sh.ty?e.sh.prop:e.sh;return i.propertyIndex=t.ix,a.p.setGroupProperty(PropertyInterface("Position",s)),a.s.setGroupProperty(PropertyInterface("Size",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),Object.defineProperties(i,{position:{get:ExpressionPropertyInterface(a.p)},roundness:{get:ExpressionPropertyInterface(a.r)},size:{get:ExpressionPropertyInterface(a.s)},_name:{value:t.nm}}),i.mn=t.mn,i}function f(t,e,r){function i(e){return t.r.ix===e||"Round Corners 1"===e?i.radius:null}var s=propertyGroupFactory(i,r),a=e;return i.propertyIndex=t.ix,a.rd.setGroupProperty(PropertyInterface("Radius",s)),Object.defineProperties(i,{radius:{get:ExpressionPropertyInterface(a.rd)},_name:{value:t.nm}}),i.mn=t.mn,i}function c(t,e,r){function i(e){return t.c.ix===e||"Copies"===e?i.copies:t.o.ix===e||"Offset"===e?i.offset:null}var s=propertyGroupFactory(i,r),a=e;return i.propertyIndex=t.ix,a.c.setGroupProperty(PropertyInterface("Copies",s)),a.o.setGroupProperty(PropertyInterface("Offset",s)),Object.defineProperties(i,{copies:{get:ExpressionPropertyInterface(a.c)},offset:{get:ExpressionPropertyInterface(a.o)},_name:{value:t.nm}}),i.mn=t.mn,i}return function(e,r,i){var s;function a(t){if("number"==typeof t)return 0===(t=void 0===t?1:t)?i:s[t-1];for(var e=0,r=s.length;e<r;){if(s[e]._name===t)return s[e];e+=1}return null}return a.propertyGroup=propertyGroupFactory(a,(function(){return i})),s=t(e,r,a.propertyGroup),a.numProperties=s.length,a._name="Contents",a}}(),TextExpressionInterface=function(t){var e;function r(t){return"ADBE Text Document"===t?r.sourceText:null}return Object.defineProperty(r,"sourceText",{get:function(){t.textProperty.getValue();var r=t.textProperty.currentData.t;return e&&r===e.value||((e=new String(r)).value=r||new String(r),Object.defineProperty(e,"style",{get:function(){return{fillColor:t.textProperty.currentData.fc}}})),e}}),r};function _typeof(t){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof(t)}var FootageInterface=(dataInterfaceFactory=function(t){function e(t){return"Outline"===t?e.outlineInterface():null}return e._name="Outline",e.outlineInterface=function(t){var e="",r=t.getFootageData();function i(t){if(r[t])return e=t,"object"===_typeof(r=r[t])?i:r;var s=t.indexOf(e);if(-1!==s){var a=parseInt(t.substr(s+e.length),10);return"object"===_typeof(r=r[a])?i:r}return""}return function(){return e="",r=t.getFootageData(),i}}(t),e},function(t){function e(t){return"Data"===t?e.dataInterface:null}return e._name="Data",e.dataInterface=dataInterfaceFactory(t),e}),dataInterfaceFactory,interfaces={layer:LayerExpressionInterface,effects:EffectsExpressionInterface,comp:CompExpressionInterface,shape:ShapeExpressionInterface,text:TextExpressionInterface,footage:FootageInterface};function getInterface(t){return interfaces[t]||null}var expressionHelpers={searchExpressions:function(t,e,r){e.x&&(r.k=!0,r.x=!0,r.initiateExpression=ExpressionManager.initiateExpression,r.effectsSequence.push(r.initiateExpression(t,e,r).bind(r)))},getSpeedAtTime:function(t){var e=this.getValueAtTime(t),r=this.getValueAtTime(t+-.01),i=0;if(e.length){var s;for(s=0;s<e.length;s+=1)i+=Math.pow(r[s]-e[s],2);i=100*Math.sqrt(i)}else i=0;return i},getVelocityAtTime:function(t){if(void 0!==this.vel)return this.vel;var e,r,i=-.001,s=this.getValueAtTime(t),a=this.getValueAtTime(t+i);if(s.length)for(e=createTypedArray("float32",s.length),r=0;r<s.length;r+=1)e[r]=(a[r]-s[r])/i;else e=(a-s)/i;return e},getValueAtTime:function(t){return t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastFrame&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastFrame<t?this._cachingAtTime.lastIndex:0,this._cachingAtTime.value=this.interpolateValue(t,this._cachingAtTime),this._cachingAtTime.lastFrame=t),this._cachingAtTime.value},getStaticValueAtTime:function(){return this.pv},setGroupProperty:function(t){this.propertyGroup=t}};function addPropertyDecorator(){function t(t,e,r){if(!this.k||!this.keyframes)return this.pv;t=t?t.toLowerCase():"";var i,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[l.length-1].t;if(h<=p)return this.pv;if(r?s=p-(i=e?Math.abs(p-this.elem.comp.globalData.frameRate*e):Math.max(0,p-this.elem.data.ip)):((!e||e>l.length-1)&&(e=l.length-1),i=p-(s=l[l.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/i)%2!=0)return this.getValueAtTime((i-(h-s)%i+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime(p/this.comp.globalData.frameRate,0),m=this.getValueAtTime(((h-s)%i+s)/this.comp.globalData.frameRate,0),u=Math.floor((h-s)/i);if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=(c[a]-f[a])*u+m[a];return o}return(c-f)*u+m}if("continue"===t){var d=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p-.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(d.length)).length,a=0;a<n;a+=1)o[a]=d[a]+(d[a]-y[a])*((h-p)/this.comp.globalData.frameRate)/5e-4;return o}return d+(h-p)/.001*(d-y)}}return this.getValueAtTime(((h-s)%i+s)/this.comp.globalData.frameRate,0)}function e(t,e,r){if(!this.k)return this.pv;t=t?t.toLowerCase():"";var i,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[0].t;if(h>=p)return this.pv;if(r?s=p+(i=e?Math.abs(this.elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-p)):((!e||e>l.length-1)&&(e=l.length-1),i=(s=l[e].t)-p),"pingpong"===t){if(Math.floor((p-h)/i)%2==0)return this.getValueAtTime(((p-h)%i+p)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(p/this.comp.globalData.frameRate,0),c=this.getValueAtTime(s/this.comp.globalData.frameRate,0),m=this.getValueAtTime((i-(p-h)%i+p)/this.comp.globalData.frameRate,0),u=Math.floor((p-h)/i)+1;if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=m[a]-(c[a]-f[a])*u;return o}return m-(c-f)*u}if("continue"===t){var d=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p+.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(d.length)).length,a=0;a<n;a+=1)o[a]=d[a]+(d[a]-y[a])*(p-h)/.001;return o}return d+(d-y)*(p-h)/.001}}return this.getValueAtTime((i-((p-h)%i+p))/this.comp.globalData.frameRate,0)}function r(t,e){if(!this.k)return this.pv;if(t=.5*(t||.4),(e=Math.floor(e||5))<=1)return this.pv;var r,i,s=this.comp.renderedFrame/this.comp.globalData.frameRate,a=s-t,n=e>1?(s+t-a)/(e-1):1,o=0,h=0;for(r=this.pv.length?createTypedArray("float32",this.pv.length):0;o<e;){if(i=this.getValueAtTime(a+o*n),this.pv.length)for(h=0;h<this.pv.length;h+=1)r[h]+=i[h];else r+=i;o+=1}if(this.pv.length)for(h=0;h<this.pv.length;h+=1)r[h]/=e;else r/=e;return r}function i(t){this._transformCachingAtTime||(this._transformCachingAtTime={v:new Matrix});var e=this._transformCachingAtTime.v;if(e.cloneFromProps(this.pre.props),this.appliedTransformations<1){var r=this.a.getValueAtTime(t);e.translate(-r[0]*this.a.mult,-r[1]*this.a.mult,r[2]*this.a.mult)}if(this.appliedTransformations<2){var i=this.s.getValueAtTime(t);e.scale(i[0]*this.s.mult,i[1]*this.s.mult,i[2]*this.s.mult)}if(this.sk&&this.appliedTransformations<3){var s=this.sk.getValueAtTime(t),a=this.sa.getValueAtTime(t);e.skewFromAxis(-s*this.sk.mult,a*this.sa.mult)}if(this.r&&this.appliedTransformations<4){var n=this.r.getValueAtTime(t);e.rotate(-n*this.r.mult)}else if(!this.r&&this.appliedTransformations<4){var o=this.rz.getValueAtTime(t),h=this.ry.getValueAtTime(t),l=this.rx.getValueAtTime(t),p=this.or.getValueAtTime(t);e.rotateZ(-o*this.rz.mult).rotateY(h*this.ry.mult).rotateX(l*this.rx.mult).rotateZ(-p[2]*this.or.mult).rotateY(p[1]*this.or.mult).rotateX(p[0]*this.or.mult)}if(this.data.p&&this.data.p.s){var f=this.px.getValueAtTime(t),c=this.py.getValueAtTime(t);if(this.data.p.z){var m=this.pz.getValueAtTime(t);e.translate(f*this.px.mult,c*this.py.mult,-m*this.pz.mult)}else e.translate(f*this.px.mult,c*this.py.mult,0)}else{var u=this.p.getValueAtTime(t);e.translate(u[0]*this.p.mult,u[1]*this.p.mult,-u[2]*this.p.mult)}return e}function s(){return this.v.clone(new Matrix)}var a=TransformPropertyFactory.getTransformProperty;TransformPropertyFactory.getTransformProperty=function(t,e,r){var n=a(t,e,r);return n.dynamicProperties.length?n.getValueAtTime=i.bind(n):n.getValueAtTime=s.bind(n),n.setGroupProperty=expressionHelpers.setGroupProperty,n};var n=PropertyFactory.getProp;PropertyFactory.getProp=function(i,s,a,o,h){var l=n(i,s,a,o,h);l.kf?l.getValueAtTime=expressionHelpers.getValueAtTime.bind(l):l.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(l),l.setGroupProperty=expressionHelpers.setGroupProperty,l.loopOut=t,l.loopIn=e,l.smooth=r,l.getVelocityAtTime=expressionHelpers.getVelocityAtTime.bind(l),l.getSpeedAtTime=expressionHelpers.getSpeedAtTime.bind(l),l.numKeys=1===s.a?s.k.length:0,l.propertyIndex=s.ix;var p=0;return 0!==a&&(p=createTypedArray("float32",1===s.a?s.k[0].s.length:s.k.length)),l._cachingAtTime={lastFrame:initialDefaultFrame,lastIndex:0,value:p},expressionHelpers.searchExpressions(i,s,l),l.k&&h.addDynamicProperty(l),l};var o=ShapePropertyFactory.getConstructorFunction(),h=ShapePropertyFactory.getKeyframedConstructorFunction();function l(){}l.prototype={vertices:function(t,e){this.k&&this.getValue();var r,i=this.v;void 0!==e&&(i=this.getValueAtTime(e,0));var s=i._length,a=i[t],n=i.v,o=createSizedArray(s);for(r=0;r<s;r+=1)o[r]="i"===t||"o"===t?[a[r][0]-n[r][0],a[r][1]-n[r][1]]:[a[r][0],a[r][1]];return o},points:function(t){return this.vertices("v",t)},inTangents:function(t){return this.vertices("i",t)},outTangents:function(t){return this.vertices("o",t)},isClosed:function(){return this.v.c},pointOnPath:function(t,e){var r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0)),this._segmentsLength||(this._segmentsLength=bez.getSegmentsLength(r));for(var i,s=this._segmentsLength,a=s.lengths,n=s.totalLength*t,o=0,h=a.length,l=0;o<h;){if(l+a[o].addedLength>n){var p=o,f=r.c&&o===h-1?0:o+1,c=(n-l)/a[o].addedLength;i=bez.getPointInSegment(r.v[p],r.v[f],r.o[p],r.i[f],c,a[o]);break}l+=a[o].addedLength,o+=1}return i||(i=r.c?[r.v[0][0],r.v[0][1]]:[r.v[r._length-1][0],r.v[r._length-1][1]]),i},vectorOnPath:function(t,e,r){1==t?t=this.v.c:0==t&&(t=.999);var i=this.pointOnPath(t,e),s=this.pointOnPath(t+.001,e),a=s[0]-i[0],n=s[1]-i[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return 0===o?[0,0]:"tangent"===r?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([l],o),extendPrototype([l],h),h.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shapePool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime<t?this._caching.lastIndex:0,this._cachingAtTime.lastTime=t,this.interpolateShape(t,this._cachingAtTime.shapeValue,this._cachingAtTime)),this._cachingAtTime.shapeValue},h.prototype.initiateExpression=ExpressionManager.initiateExpression;var p=ShapePropertyFactory.getShapeProp;ShapePropertyFactory.getShapeProp=function(t,e,r,i,s){var a=p(t,e,r,i,s);return a.propertyIndex=e.ix,a.lock=!1,3===r?expressionHelpers.searchExpressions(t,e.pt,a):4===r&&expressionHelpers.searchExpressions(t,e.ks,a),a.k&&t.addDynamicProperty(a),a}}function initialize$1(){addPropertyDecorator()}function addDecorator(){TextProperty.prototype.getExpressionValue=function(t,e){var r=this.calculateExpression(e);if(t.t!==r){var i={};return this.copyData(i,t),i.t=r.toString(),i.__complete=!1,i}return t},TextProperty.prototype.searchProperty=function(){var t=this.searchKeyframes(),e=this.searchExpressions();return this.kf=t||e,this.kf},TextProperty.prototype.searchExpressions=function(){return this.data.d.x?(this.calculateExpression=ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this),this.addEffect(this.getExpressionValue.bind(this)),!0):null}}function initialize(){addDecorator()}function SVGComposableEffect(){}SVGComposableEffect.prototype={createMergeNode:function(t,e){var r,i,s=createNS("feMerge");for(s.setAttribute("result",t),i=0;i<e.length;i+=1)(r=createNS("feMergeNode")).setAttribute("in",e[i]),s.appendChild(r),s.appendChild(r);return s}};var linearFilterValue="0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0";function SVGTintFilter(t,e,r,i,s){this.filterManager=e;var a=createNS("feColorMatrix");a.setAttribute("type","matrix"),a.setAttribute("color-interpolation-filters","linearRGB"),a.setAttribute("values",linearFilterValue+" 1 0"),this.linearFilter=a,a.setAttribute("result",i+"_tint_1"),t.appendChild(a),(a=createNS("feColorMatrix")).setAttribute("type","matrix"),a.setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),a.setAttribute("result",i+"_tint_2"),t.appendChild(a),this.matrixFilter=a;var n=this.createMergeNode(i,[s,i+"_tint_1",i+"_tint_2"]);t.appendChild(n)}function SVGFillFilter(t,e,r,i){this.filterManager=e;var s=createNS("feColorMatrix");s.setAttribute("type","matrix"),s.setAttribute("color-interpolation-filters","sRGB"),s.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),s.setAttribute("result",i),t.appendChild(s),this.matrixFilter=s}function SVGStrokeEffect(t,e,r){this.initialized=!1,this.filterManager=e,this.elem=r,this.paths=[]}function SVGTritoneFilter(t,e,r,i){this.filterManager=e;var s=createNS("feColorMatrix");s.setAttribute("type","matrix"),s.setAttribute("color-interpolation-filters","linearRGB"),s.setAttribute("values","0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0"),t.appendChild(s);var a=createNS("feComponentTransfer");a.setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("result",i),this.matrixFilter=a;var n=createNS("feFuncR");n.setAttribute("type","table"),a.appendChild(n),this.feFuncR=n;var o=createNS("feFuncG");o.setAttribute("type","table"),a.appendChild(o),this.feFuncG=o;var h=createNS("feFuncB");h.setAttribute("type","table"),a.appendChild(h),this.feFuncB=h,t.appendChild(a)}function SVGProLevelsFilter(t,e,r,i){this.filterManager=e;var s=this.filterManager.effectElements,a=createNS("feComponentTransfer");(s[10].p.k||0!==s[10].p.v||s[11].p.k||1!==s[11].p.v||s[12].p.k||1!==s[12].p.v||s[13].p.k||0!==s[13].p.v||s[14].p.k||1!==s[14].p.v)&&(this.feFuncR=this.createFeFunc("feFuncR",a)),(s[17].p.k||0!==s[17].p.v||s[18].p.k||1!==s[18].p.v||s[19].p.k||1!==s[19].p.v||s[20].p.k||0!==s[20].p.v||s[21].p.k||1!==s[21].p.v)&&(this.feFuncG=this.createFeFunc("feFuncG",a)),(s[24].p.k||0!==s[24].p.v||s[25].p.k||1!==s[25].p.v||s[26].p.k||1!==s[26].p.v||s[27].p.k||0!==s[27].p.v||s[28].p.k||1!==s[28].p.v)&&(this.feFuncB=this.createFeFunc("feFuncB",a)),(s[31].p.k||0!==s[31].p.v||s[32].p.k||1!==s[32].p.v||s[33].p.k||1!==s[33].p.v||s[34].p.k||0!==s[34].p.v||s[35].p.k||1!==s[35].p.v)&&(this.feFuncA=this.createFeFunc("feFuncA",a)),(this.feFuncR||this.feFuncG||this.feFuncB||this.feFuncA)&&(a.setAttribute("color-interpolation-filters","sRGB"),t.appendChild(a)),(s[3].p.k||0!==s[3].p.v||s[4].p.k||1!==s[4].p.v||s[5].p.k||1!==s[5].p.v||s[6].p.k||0!==s[6].p.v||s[7].p.k||1!==s[7].p.v)&&((a=createNS("feComponentTransfer")).setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("result",i),t.appendChild(a),this.feFuncRComposed=this.createFeFunc("feFuncR",a),this.feFuncGComposed=this.createFeFunc("feFuncG",a),this.feFuncBComposed=this.createFeFunc("feFuncB",a))}function SVGDropShadowEffect(t,e,r,i,s){var a=e.container.globalData.renderConfig.filterSize,n=e.data.fs||a;t.setAttribute("x",n.x||a.x),t.setAttribute("y",n.y||a.y),t.setAttribute("width",n.width||a.width),t.setAttribute("height",n.height||a.height),this.filterManager=e;var o=createNS("feGaussianBlur");o.setAttribute("in","SourceAlpha"),o.setAttribute("result",i+"_drop_shadow_1"),o.setAttribute("stdDeviation","0"),this.feGaussianBlur=o,t.appendChild(o);var h=createNS("feOffset");h.setAttribute("dx","25"),h.setAttribute("dy","0"),h.setAttribute("in",i+"_drop_shadow_1"),h.setAttribute("result",i+"_drop_shadow_2"),this.feOffset=h,t.appendChild(h);var l=createNS("feFlood");l.setAttribute("flood-color","#00ff00"),l.setAttribute("flood-opacity","1"),l.setAttribute("result",i+"_drop_shadow_3"),this.feFlood=l,t.appendChild(l);var p=createNS("feComposite");p.setAttribute("in",i+"_drop_shadow_3"),p.setAttribute("in2",i+"_drop_shadow_2"),p.setAttribute("operator","in"),p.setAttribute("result",i+"_drop_shadow_4"),t.appendChild(p);var f=this.createMergeNode(i,[i+"_drop_shadow_4",s]);t.appendChild(f)}extendPrototype([SVGComposableEffect],SVGTintFilter),SVGTintFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[0].p.v,r=this.filterManager.effectElements[1].p.v,i=this.filterManager.effectElements[2].p.v/100;this.linearFilter.setAttribute("values",linearFilterValue+" "+i+" 0"),this.matrixFilter.setAttribute("values",r[0]-e[0]+" 0 0 0 "+e[0]+" "+(r[1]-e[1])+" 0 0 0 "+e[1]+" "+(r[2]-e[2])+" 0 0 0 "+e[2]+" 0 0 0 1 0")}},SVGFillFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[2].p.v,r=this.filterManager.effectElements[6].p.v;this.matrixFilter.setAttribute("values","0 0 0 0 "+e[0]+" 0 0 0 0 "+e[1]+" 0 0 0 0 "+e[2]+" 0 0 0 "+r+" 0")}},SVGStrokeEffect.prototype.initialize=function(){var t,e,r,i,s=this.elem.layerElement.children||this.elem.layerElement.childNodes;for(1===this.filterManager.effectElements[1].p.v?(i=this.elem.maskManager.masksProperties.length,r=0):i=(r=this.filterManager.effectElements[0].p.v-1)+1,(e=createNS("g")).setAttribute("fill","none"),e.setAttribute("stroke-linecap","round"),e.setAttribute("stroke-dashoffset",1);r<i;r+=1)t=createNS("path"),e.appendChild(t),this.paths.push({p:t,m:r});if(3===this.filterManager.effectElements[10].p.v){var a=createNS("mask"),n=createElementID();a.setAttribute("id",n),a.setAttribute("mask-type","alpha"),a.appendChild(e),this.elem.globalData.defs.appendChild(a);var o=createNS("g");for(o.setAttribute("mask","url("+getLocationHref()+"#"+n+")");s[0];)o.appendChild(s[0]);this.elem.layerElement.appendChild(o),this.masker=a,e.setAttribute("stroke","#fff")}else if(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v){if(2===this.filterManager.effectElements[10].p.v)for(s=this.elem.layerElement.children||this.elem.layerElement.childNodes;s.length;)this.elem.layerElement.removeChild(s[0]);this.elem.layerElement.appendChild(e),this.elem.layerElement.removeAttribute("mask"),e.setAttribute("stroke","#fff")}this.initialized=!0,this.pathMasker=e},SVGStrokeEffect.prototype.renderFrame=function(t){var e;this.initialized||this.initialize();var r,i,s=this.paths.length;for(e=0;e<s;e+=1)if(-1!==this.paths[e].m&&(r=this.elem.maskManager.viewData[this.paths[e].m],i=this.paths[e].p,(t||this.filterManager._mdf||r.prop._mdf)&&i.setAttribute("d",r.lastPath),t||this.filterManager.effectElements[9].p._mdf||this.filterManager.effectElements[4].p._mdf||this.filterManager.effectElements[7].p._mdf||this.filterManager.effectElements[8].p._mdf||r.prop._mdf)){var a;if(0!==this.filterManager.effectElements[7].p.v||100!==this.filterManager.effectElements[8].p.v){var n=.01*Math.min(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),o=.01*Math.max(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),h=i.getTotalLength();a="0 0 0 "+h*n+" ";var l,p=h*(o-n),f=1+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01,c=Math.floor(p/f);for(l=0;l<c;l+=1)a+="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01+" ";a+="0 "+10*h+" 0 0"}else a="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01;i.setAttribute("stroke-dasharray",a)}if((t||this.filterManager.effectElements[4].p._mdf)&&this.pathMasker.setAttribute("stroke-width",2*this.filterManager.effectElements[4].p.v),(t||this.filterManager.effectElements[6].p._mdf)&&this.pathMasker.setAttribute("opacity",this.filterManager.effectElements[6].p.v),(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v)&&(t||this.filterManager.effectElements[3].p._mdf)){var m=this.filterManager.effectElements[3].p.v;this.pathMasker.setAttribute("stroke","rgb("+bmFloor(255*m[0])+","+bmFloor(255*m[1])+","+bmFloor(255*m[2])+")")}},SVGTritoneFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[0].p.v,r=this.filterManager.effectElements[1].p.v,i=this.filterManager.effectElements[2].p.v,s=i[0]+" "+r[0]+" "+e[0],a=i[1]+" "+r[1]+" "+e[1],n=i[2]+" "+r[2]+" "+e[2];this.feFuncR.setAttribute("tableValues",s),this.feFuncG.setAttribute("tableValues",a),this.feFuncB.setAttribute("tableValues",n)}},SVGProLevelsFilter.prototype.createFeFunc=function(t,e){var r=createNS(t);return r.setAttribute("type","table"),e.appendChild(r),r},SVGProLevelsFilter.prototype.getTableValue=function(t,e,r,i,s){for(var a,n,o=0,h=Math.min(t,e),l=Math.max(t,e),p=Array.call(null,{length:256}),f=0,c=s-i,m=e-t;o<=256;)n=(a=o/256)<=h?m<0?s:i:a>=l?m<0?i:s:i+c*Math.pow((a-t)/m,1/r),p[f]=n,f+=1,o+=256/255;return p.join(" ")},SVGProLevelsFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e,r=this.filterManager.effectElements;this.feFuncRComposed&&(t||r[3].p._mdf||r[4].p._mdf||r[5].p._mdf||r[6].p._mdf||r[7].p._mdf)&&(e=this.getTableValue(r[3].p.v,r[4].p.v,r[5].p.v,r[6].p.v,r[7].p.v),this.feFuncRComposed.setAttribute("tableValues",e),this.feFuncGComposed.setAttribute("tableValues",e),this.feFuncBComposed.setAttribute("tableValues",e)),this.feFuncR&&(t||r[10].p._mdf||r[11].p._mdf||r[12].p._mdf||r[13].p._mdf||r[14].p._mdf)&&(e=this.getTableValue(r[10].p.v,r[11].p.v,r[12].p.v,r[13].p.v,r[14].p.v),this.feFuncR.setAttribute("tableValues",e)),this.feFuncG&&(t||r[17].p._mdf||r[18].p._mdf||r[19].p._mdf||r[20].p._mdf||r[21].p._mdf)&&(e=this.getTableValue(r[17].p.v,r[18].p.v,r[19].p.v,r[20].p.v,r[21].p.v),this.feFuncG.setAttribute("tableValues",e)),this.feFuncB&&(t||r[24].p._mdf||r[25].p._mdf||r[26].p._mdf||r[27].p._mdf||r[28].p._mdf)&&(e=this.getTableValue(r[24].p.v,r[25].p.v,r[26].p.v,r[27].p.v,r[28].p.v),this.feFuncB.setAttribute("tableValues",e)),this.feFuncA&&(t||r[31].p._mdf||r[32].p._mdf||r[33].p._mdf||r[34].p._mdf||r[35].p._mdf)&&(e=this.getTableValue(r[31].p.v,r[32].p.v,r[33].p.v,r[34].p.v,r[35].p.v),this.feFuncA.setAttribute("tableValues",e))}},extendPrototype([SVGComposableEffect],SVGDropShadowEffect),SVGDropShadowEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){if((t||this.filterManager.effectElements[4].p._mdf)&&this.feGaussianBlur.setAttribute("stdDeviation",this.filterManager.effectElements[4].p.v/4),t||this.filterManager.effectElements[0].p._mdf){var e=this.filterManager.effectElements[0].p.v;this.feFlood.setAttribute("flood-color",rgbToHex(Math.round(255*e[0]),Math.round(255*e[1]),Math.round(255*e[2])))}if((t||this.filterManager.effectElements[1].p._mdf)&&this.feFlood.setAttribute("flood-opacity",this.filterManager.effectElements[1].p.v/255),t||this.filterManager.effectElements[2].p._mdf||this.filterManager.effectElements[3].p._mdf){var r=this.filterManager.effectElements[3].p.v,i=(this.filterManager.effectElements[2].p.v-90)*degToRads,s=r*Math.cos(i),a=r*Math.sin(i);this.feOffset.setAttribute("dx",s),this.feOffset.setAttribute("dy",a)}}};var _svgMatteSymbols=[];function SVGMatte3Effect(t,e,r){this.initialized=!1,this.filterManager=e,this.filterElem=t,this.elem=r,r.matteElement=createNS("g"),r.matteElement.appendChild(r.layerElement),r.matteElement.appendChild(r.transformedElement),r.baseElement=r.matteElement}function SVGGaussianBlurEffect(t,e,r,i){t.setAttribute("x","-100%"),t.setAttribute("y","-100%"),t.setAttribute("width","300%"),t.setAttribute("height","300%"),this.filterManager=e;var s=createNS("feGaussianBlur");s.setAttribute("result",i),t.appendChild(s),this.feGaussianBlur=s}function TransformEffect(){}function SVGTransformEffect(t,e){this.init(e)}return SVGMatte3Effect.prototype.findSymbol=function(t){for(var e=0,r=_svgMatteSymbols.length;e<r;){if(_svgMatteSymbols[e]===t)return _svgMatteSymbols[e];e+=1}return null},SVGMatte3Effect.prototype.replaceInParent=function(t,e){var r=t.layerElement.parentNode;if(r){for(var i,s=r.children,a=0,n=s.length;a<n&&s[a]!==t.layerElement;)a+=1;a<=n-2&&(i=s[a+1]);var o=createNS("use");o.setAttribute("href","#"+e),i?r.insertBefore(o,i):r.appendChild(o)}},SVGMatte3Effect.prototype.setElementAsMask=function(t,e){if(!this.findSymbol(e)){var r=createElementID(),i=createNS("mask");i.setAttribute("id",e.layerId),i.setAttribute("mask-type","alpha"),_svgMatteSymbols.push(e);var s=t.globalData.defs;s.appendChild(i);var a=createNS("symbol");a.setAttribute("id",r),this.replaceInParent(e,r),a.appendChild(e.layerElement),s.appendChild(a);var n=createNS("use");n.setAttribute("href","#"+r),i.appendChild(n),e.data.hd=!1,e.show()}t.setMatte(e.layerId)},SVGMatte3Effect.prototype.initialize=function(){for(var t=this.filterManager.effectElements[0].p.v,e=this.elem.comp.elements,r=0,i=e.length;r<i;)e[r]&&e[r].data.ind===t&&this.setElementAsMask(this.elem,e[r]),r+=1;this.initialized=!0},SVGMatte3Effect.prototype.renderFrame=function(){this.initialized||this.initialize()},SVGGaussianBlurEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=.3*this.filterManager.effectElements[0].p.v,r=this.filterManager.effectElements[1].p.v,i=3==r?0:e,s=2==r?0:e;this.feGaussianBlur.setAttribute("stdDeviation",i+" "+s);var a=1==this.filterManager.effectElements[2].p.v?"wrap":"duplicate";this.feGaussianBlur.setAttribute("edgeMode",a)}},TransformEffect.prototype.init=function(t){this.effectsManager=t,this.type=effectTypes.TRANSFORM_EFFECT,this.matrix=new Matrix,this.opacity=-1,this._mdf=!1,this._opMdf=!1},TransformEffect.prototype.renderFrame=function(t){if(this._opMdf=!1,this._mdf=!1,t||this.effectsManager._mdf){var e=this.effectsManager.effectElements,r=e[0].p.v,i=e[1].p.v,s=1===e[2].p.v,a=e[3].p.v,n=s?a:e[4].p.v,o=e[5].p.v,h=e[6].p.v,l=e[7].p.v;this.matrix.reset(),this.matrix.translate(-r[0],-r[1],r[2]),this.matrix.scale(.01*n,.01*a,1),this.matrix.rotate(-l*degToRads),this.matrix.skewFromAxis(-o*degToRads,(h+90)*degToRads),this.matrix.translate(i[0],i[1],0),this._mdf=!0,this.opacity!==e[8].p.v&&(this.opacity=e[8].p.v,this._opMdf=!0)}},extendPrototype([TransformEffect],SVGTransformEffect),setExpressionsPlugin(Expressions),setExpressionInterfaces(getInterface),initialize$1(),initialize(),registerEffect(20,SVGTintFilter,!0),registerEffect(21,SVGFillFilter,!0),registerEffect(22,SVGStrokeEffect,!1),registerEffect(23,SVGTritoneFilter,!0),registerEffect(24,SVGProLevelsFilter,!0),registerEffect(25,SVGDropShadowEffect,!0),registerEffect(28,SVGMatte3Effect,!1),registerEffect(29,SVGGaussianBlurEffect,!0),registerEffect(35,SVGTransformEffect,!1),lottie}));
+"undefined"!=typeof document&&"undefined"!=typeof navigator&&function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lottie=e()}(this,(function(){"use strict";var svgNS="http://www.w3.org/2000/svg",locationHref="",_useWebWorker=!1,initialDefaultFrame=-999999,setWebWorker=function(t){_useWebWorker=!!t},getWebWorker=function(){return _useWebWorker},setLocationHref=function(t){locationHref=t},getLocationHref=function(){return locationHref};function createTag(t){return document.createElement(t)}function extendPrototype(t,e){var r,i,s=t.length;for(r=0;r<s;r+=1)for(var a in i=t[r].prototype)Object.prototype.hasOwnProperty.call(i,a)&&(e.prototype[a]=i[a])}function getDescriptor(t,e){return Object.getOwnPropertyDescriptor(t,e)}function createProxyFunction(t){function e(){}return e.prototype=t,e}var audioControllerFactory=function(){function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].pause()},resume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].resume()},setRate:function(t){var e,r=this.audios.length;for(e=0;e<r;e+=1)this.audios[e].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}}(),createTypedArray=function(){function t(t,e){var r,i=0,s=[];switch(t){case"int16":case"uint8c":r=1;break;default:r=1.1}for(i=0;i<e;i+=1)s.push(r);return s}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(e,r){return"float32"===e?new Float32Array(r):"int16"===e?new Int16Array(r):"uint8c"===e?new Uint8ClampedArray(r):t(e,r)}:t}();function createSizedArray(t){return Array.apply(null,{length:t})}function _typeof$6(t){return _typeof$6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$6(t)}var subframeEnabled=!0,expressionsPlugin=null,expressionsInterfaces=null,idPrefix$1="",isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),_shouldRoundValues=!1,bmPow=Math.pow,bmSqrt=Math.sqrt,bmFloor=Math.floor,bmMax=Math.max,bmMin=Math.min,BMMath={};function ProjectInterface$1(){return{}}!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],r=e.length;for(t=0;t<r;t+=1)BMMath[e[t]]=Math[e[t]]}(),BMMath.random=Math.random,BMMath.abs=function(t){if("object"===_typeof$6(t)&&t.length){var e,r=createSizedArray(t.length),i=t.length;for(e=0;e<i;e+=1)r[e]=Math.abs(t[e]);return r}return Math.abs(t)};var defaultCurveSegments=150,degToRads=Math.PI/180,roundCorner=.5519;function roundValues(t){_shouldRoundValues=!!t}function bmRnd(t){return _shouldRoundValues?Math.round(t):t}function styleDiv(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin="0 0",t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility="visible",t.style.webkitBackfaceVisibility="visible",t.style.transformStyle="preserve-3d",t.style.webkitTransformStyle="preserve-3d",t.style.mozTransformStyle="preserve-3d"}function BMEnterFrameEvent(t,e,r,i){this.type=t,this.currentTime=e,this.totalTime=r,this.direction=i<0?-1:1}function BMCompleteEvent(t,e){this.type=t,this.direction=e<0?-1:1}function BMCompleteLoopEvent(t,e,r,i){this.type=t,this.currentLoop=r,this.totalLoops=e,this.direction=i<0?-1:1}function BMSegmentStartEvent(t,e,r){this.type=t,this.firstFrame=e,this.totalFrames=r}function BMDestroyEvent(t,e){this.type=t,this.target=e}function BMRenderFrameErrorEvent(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function BMConfigErrorEvent(t){this.type="configError",this.nativeError=t}function BMAnimationConfigErrorEvent(t,e){this.type=t,this.nativeError=e}var createElementID=(_count=0,function(){return idPrefix$1+"__lottie_element_"+(_count+=1)}),_count;function HSVtoRGB(t,e,r){var i,s,a,n,o,h,l,p;switch(h=r*(1-e),l=r*(1-(o=6*t-(n=Math.floor(6*t)))*e),p=r*(1-(1-o)*e),n%6){case 0:i=r,s=p,a=h;break;case 1:i=l,s=r,a=h;break;case 2:i=h,s=r,a=p;break;case 3:i=h,s=l,a=r;break;case 4:i=p,s=h,a=r;break;case 5:i=r,s=h,a=l}return[i,s,a]}function RGBtoHSV(t,e,r){var i,s=Math.max(t,e,r),a=Math.min(t,e,r),n=s-a,o=0===s?0:n/s,h=s/255;switch(s){case a:i=0;break;case t:i=e-r+n*(e<r?6:0),i/=6*n;break;case e:i=r-t+2*n,i/=6*n;break;case r:i=t-e+4*n,i/=6*n}return[i,o,h]}function addSaturationToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[1]+=e,r[1]>1?r[1]=1:r[1]<=0&&(r[1]=0),HSVtoRGB(r[0],r[1],r[2])}function addBrightnessToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[2]+=e,r[2]>1?r[2]=1:r[2]<0&&(r[2]=0),HSVtoRGB(r[0],r[1],r[2])}function addHueToRGB(t,e){var r=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return r[0]+=e/360,r[0]>1?r[0]-=1:r[0]<0&&(r[0]+=1),HSVtoRGB(r[0],r[1],r[2])}var rgbToHex=function(){var t,e,r=[];for(t=0;t<256;t+=1)e=t.toString(16),r[t]=1===e.length?"0"+e:e;return function(t,e,i){return t<0&&(t=0),e<0&&(e=0),i<0&&(i=0),"#"+r[t]+r[e]+r[i]}}(),setSubframeEnabled=function(t){subframeEnabled=!!t},getSubframeEnabled=function(){return subframeEnabled},setExpressionsPlugin=function(t){expressionsPlugin=t},getExpressionsPlugin=function(){return expressionsPlugin},setExpressionInterfaces=function(t){expressionsInterfaces=t},getExpressionInterfaces=function(){return expressionsInterfaces},setDefaultCurveSegments=function(t){defaultCurveSegments=t},getDefaultCurveSegments=function(){return defaultCurveSegments},setIdPrefix=function(t){idPrefix$1=t},getIdPrefix=function(){return idPrefix$1};function createNS(t){return document.createElementNS(svgNS,t)}function _typeof$5(t){return _typeof$5="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$5(t)}var dataManager=function(){var t,e,r=1,i=[],s={onmessage:function(){},postMessage:function(e){t({data:e})}},a={postMessage:function(t){s.onmessage({data:t})}};function n(){e||(e=function(e){if(window.Worker&&window.Blob&&getWebWorker()){var r=new Blob(["var _workerSelf = self; self.onmessage = ",e.toString()],{type:"text/javascript"}),i=URL.createObjectURL(r);return new Worker(i)}return t=e,s}((function(t){if(a.dataManager||(a.dataManager=function(){function t(s,a){var n,o,h,l,p,c,m=s.length;for(o=0;o<m;o+=1)if("ks"in(n=s[o])&&!n.completed){if(n.completed=!0,n.hasMask){var u=n.masksProperties;for(l=u.length,h=0;h<l;h+=1)if(u[h].pt.k.i)i(u[h].pt.k);else for(c=u[h].pt.k.length,p=0;p<c;p+=1)u[h].pt.k[p].s&&i(u[h].pt.k[p].s[0]),u[h].pt.k[p].e&&i(u[h].pt.k[p].e[0])}0===n.ty?(n.layers=e(n.refId,a),t(n.layers,a)):4===n.ty?r(n.shapes):5===n.ty&&f(n)}}function e(t,e){var r=function(t,e){for(var r=0,i=e.length;r<i;){if(e[r].id===t)return e[r];r+=1}return null}(t,e);return r?r.layers.__used?JSON.parse(JSON.stringify(r.layers)):(r.layers.__used=!0,r.layers):null}function r(t){var e,s,a;for(e=t.length-1;e>=0;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)i(t[e].ks.k);else for(a=t[e].ks.k.length,s=0;s<a;s+=1)t[e].ks.k[s].s&&i(t[e].ks.k[s].s[0]),t[e].ks.k[s].e&&i(t[e].ks.k[s].e[0]);else"gr"===t[e].ty&&r(t[e].it)}function i(t){var e,r=t.i.length;for(e=0;e<r;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function s(t,e){var r=e?e.split("."):[100,100,100];return t[0]>r[0]||!(r[0]>t[0])&&(t[1]>r[1]||!(r[1]>t[1])&&(t[2]>r[2]||!(r[2]>t[2])&&null))}var a,n=function(){var t=[4,4,14];function e(t){var e,r,i,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(i=void 0,i=(r=t[e]).t.d,r.t.d={k:[{s:i,t:0}]})}return function(r){if(s(t,r.v)&&(e(r.layers),r.assets)){var i,a=r.assets.length;for(i=0;i<a;i+=1)r.assets[i].layers&&e(r.assets[i].layers)}}}(),o=(a=[4,7,99],function(t){if(t.chars&&!s(a,t.v)){var e,i=t.chars.length;for(e=0;e<i;e+=1){var n=t.chars[e];n.data&&n.data.shapes&&(r(n.data.shapes),n.data.ip=0,n.data.op=99999,n.data.st=0,n.data.sr=1,n.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[e].t||(n.data.shapes.push({ty:"no"}),n.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}}}),h=function(){var t=[5,7,15];function e(t){var e,r,i=t.length;for(e=0;e<i;e+=1)5===t[e].ty&&(r=void 0,"number"==typeof(r=t[e].t.p).a&&(r.a={a:0,k:r.a}),"number"==typeof r.p&&(r.p={a:0,k:r.p}),"number"==typeof r.r&&(r.r={a:0,k:r.r}))}return function(r){if(s(t,r.v)&&(e(r.layers),r.assets)){var i,a=r.assets.length;for(i=0;i<a;i+=1)r.assets[i].layers&&e(r.assets[i].layers)}}}(),l=function(){var t=[4,1,9];function e(t){var r,i,s,a=t.length;for(r=0;r<a;r+=1)if("gr"===t[r].ty)e(t[r].it);else if("fl"===t[r].ty||"st"===t[r].ty)if(t[r].c.k&&t[r].c.k[0].i)for(s=t[r].c.k.length,i=0;i<s;i+=1)t[r].c.k[i].s&&(t[r].c.k[i].s[0]/=255,t[r].c.k[i].s[1]/=255,t[r].c.k[i].s[2]/=255,t[r].c.k[i].s[3]/=255),t[r].c.k[i].e&&(t[r].c.k[i].e[0]/=255,t[r].c.k[i].e[1]/=255,t[r].c.k[i].e[2]/=255,t[r].c.k[i].e[3]/=255);else t[r].c.k[0]/=255,t[r].c.k[1]/=255,t[r].c.k[2]/=255,t[r].c.k[3]/=255}function r(t){var r,i=t.length;for(r=0;r<i;r+=1)4===t[r].ty&&e(t[r].shapes)}return function(e){if(s(t,e.v)&&(r(e.layers),e.assets)){var i,a=e.assets.length;for(i=0;i<a;i+=1)e.assets[i].layers&&r(e.assets[i].layers)}}}(),p=function(){var t=[4,4,18];function e(t){var r,i,s;for(r=t.length-1;r>=0;r-=1)if("sh"===t[r].ty)if(t[r].ks.k.i)t[r].ks.k.c=t[r].closed;else for(s=t[r].ks.k.length,i=0;i<s;i+=1)t[r].ks.k[i].s&&(t[r].ks.k[i].s[0].c=t[r].closed),t[r].ks.k[i].e&&(t[r].ks.k[i].e[0].c=t[r].closed);else"gr"===t[r].ty&&e(t[r].it)}function r(t){var r,i,s,a,n,o,h=t.length;for(i=0;i<h;i+=1){if((r=t[i]).hasMask){var l=r.masksProperties;for(a=l.length,s=0;s<a;s+=1)if(l[s].pt.k.i)l[s].pt.k.c=l[s].cl;else for(o=l[s].pt.k.length,n=0;n<o;n+=1)l[s].pt.k[n].s&&(l[s].pt.k[n].s[0].c=l[s].cl),l[s].pt.k[n].e&&(l[s].pt.k[n].e[0].c=l[s].cl)}4===r.ty&&e(r.shapes)}}return function(e){if(s(t,e.v)&&(r(e.layers),e.assets)){var i,a=e.assets.length;for(i=0;i<a;i+=1)e.assets[i].layers&&r(e.assets[i].layers)}}}();function f(t){0===t.t.a.length&&t.t.p}var c={completeData:function(r){r.__complete||(l(r),n(r),o(r),h(r),p(r),t(r.layers,r.assets),function(r,i){if(r){var s=0,a=r.length;for(s=0;s<a;s+=1)1===r[s].t&&(r[s].data.layers=e(r[s].data.refId,i),t(r[s].data.layers,i))}}(r.chars,r.assets),r.__complete=!0)}};return c.checkColors=l,c.checkChars=o,c.checkPathProperties=h,c.checkShapes=p,c.completeLayers=t,c}()),a.assetLoader||(a.assetLoader=function(){function t(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")||t.response&&"object"===_typeof$5(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}return{load:function(e,r,i,s){var a,n=new XMLHttpRequest;try{n.responseType="json"}catch(t){}n.onreadystatechange=function(){if(4===n.readyState)if(200===n.status)a=t(n),i(a);else try{a=t(n),i(a)}catch(t){s&&s(t)}};try{n.open(["G","E","T"].join(""),e,!0)}catch(t){n.open(["G","E","T"].join(""),r+"/"+e,!0)}n.send()}}}()),"loadAnimation"===t.data.type)a.assetLoader.load(t.data.path,t.data.fullPath,(function(e){a.dataManager.completeData(e),a.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){a.postMessage({id:t.data.id,status:"error"})}));else if("complete"===t.data.type){var e=t.data.animation;a.dataManager.completeData(e),a.postMessage({id:t.data.id,payload:e,status:"success"})}else"loadData"===t.data.type&&a.assetLoader.load(t.data.path,t.data.fullPath,(function(e){a.postMessage({id:t.data.id,payload:e,status:"success"})}),(function(){a.postMessage({id:t.data.id,status:"error"})}))})),e.onmessage=function(t){var e=t.data,r=e.id,s=i[r];i[r]=null,"success"===e.status?s.onComplete(e.payload):s.onError&&s.onError()})}function o(t,e){var s="processId_"+(r+=1);return i[s]={onComplete:t,onError:e},s}return{loadAnimation:function(t,r,i){n();var s=o(r,i);e.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:s})},loadData:function(t,r,i){n();var s=o(r,i);e.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:s})},completeAnimation:function(t,r,i){n();var s=o(r,i);e.postMessage({type:"complete",animation:t,id:s})}}}(),ImagePreloader=function(){var t=function(){var t=createTag("canvas");t.width=1,t.height=1;var e=t.getContext("2d");return e.fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1),t}();function e(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function r(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function i(t,e,r){var i="";if(t.e)i=t.p;else if(e){var s=t.p;-1!==s.indexOf("images/")&&(s=s.split("/")[1]),i=e+s}else i=r,i+=t.u?t.u:"",i+=t.p;return i}function s(t){var e=0,r=setInterval(function(){(t.getBBox().width||e>500)&&(this._imageLoaded(),clearInterval(r)),e+=1}.bind(this),50)}function a(t){var e={assetData:t},r=i(t,this.assetsPath,this.path);return dataManager.loadData(r,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}function n(){this._imageLoaded=e.bind(this),this._footageLoaded=r.bind(this),this.testImageLoaded=s.bind(this),this.createFootageData=a.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return n.prototype={loadAssets:function(t,e){var r;this.imagesLoadedCb=e;var i=t.length;for(r=0;r<i;r+=1)t[r].layers||(t[r].t&&"seq"!==t[r].t?3===t[r].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[r]))):(this.totalImages+=1,this.images.push(this._createImageData(t[r]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,r=this.images.length;e<r;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(e){var r=i(e,this.assetsPath,this.path),s=createTag("img");s.crossOrigin="anonymous",s.addEventListener("load",this._imageLoaded,!1),s.addEventListener("error",function(){a.img=t,this._imageLoaded()}.bind(this),!1),s.src=r;var a={img:s,assetData:e};return a},createImageData:function(e){var r=i(e,this.assetsPath,this.path),s=createNS("image");isSafari?this.testImageLoaded(s):s.addEventListener("load",this._imageLoaded,!1),s.addEventListener("error",function(){a.img=t,this._imageLoaded()}.bind(this),!1),s.setAttributeNS("http://www.w3.org/1999/xlink","href",r),this._elementHelper.append?this._elementHelper.append(s):this._elementHelper.appendChild(s);var a={img:s,assetData:e};return a},imageLoaded:e,footageLoaded:r,setCacheType:function(t,e){"svg"===t?(this._elementHelper=e,this._createImageData=this.createImageData.bind(this)):this._createImageData=this.createImgData.bind(this)}},n}();function BaseEvent(){}BaseEvent.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var r=this._cbs[t],i=0;i<r.length;i+=1)r[i](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var r=0,i=this._cbs[t].length;r<i;)this._cbs[t][r]===e&&(this._cbs[t].splice(r,1),r-=1,i-=1),r+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var markerParser=function(){function t(t){for(var e,r=t.split("\r\n"),i={},s=0,a=0;a<r.length;a+=1)2===(e=r[a].split(":")).length&&(i[e[0]]=e[1].trim(),s+=1);if(0===s)throw new Error;return i}return function(e){for(var r=[],i=0;i<e.length;i+=1){var s=e[i],a={time:s.tm,duration:s.dr};try{a.payload=JSON.parse(e[i].cm)}catch(r){try{a.payload=t(e[i].cm)}catch(t){a.payload={name:e[i].cm}}}r.push(a)}return r}}(),ProjectInterface=function(){function t(t){this.compositions.push(t)}return function(){function e(t){for(var e=0,r=this.compositions.length;e<r;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return e.compositions=[],e.currentFrame=0,e.registerComposition=t,e}}(),renderers={},registerRenderer=function(t,e){renderers[t]=e};function getRenderer(t){return renderers[t]}function getRegisteredRenderer(){if(renderers.canvas)return"canvas";for(var t in renderers)if(renderers[t])return t;return""}function _typeof$4(t){return _typeof$4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$4(t)}var AnimationItem=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=createElementID(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=getSubframeEnabled(),this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=ProjectInterface(),this.imagePreloader=new ImagePreloader,this.audioController=audioControllerFactory(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new BMEnterFrameEvent("drawnFrame",0,0,0),this.expressionsPlugin=getExpressionsPlugin()};extendPrototype([BaseEvent],AnimationItem),AnimationItem.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg";t.animType?e=t.animType:t.renderer&&(e=t.renderer);var r=getRenderer(e);this.renderer=new r(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||void 0===t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),dataManager.loadAnimation(t.path,this.configAnimation,this.onSetupError))},AnimationItem.prototype.onSetupError=function(){this.trigger("data_failed")},AnimationItem.prototype.setupAnimation=function(t){dataManager.completeAnimation(t,this.configAnimation)},AnimationItem.prototype.setData=function(t,e){e&&"object"!==_typeof$4(e)&&(e=JSON.parse(e));var r={wrapper:t,animationData:e},i=t.attributes;r.path=i.getNamedItem("data-animation-path")?i.getNamedItem("data-animation-path").value:i.getNamedItem("data-bm-path")?i.getNamedItem("data-bm-path").value:i.getNamedItem("bm-path")?i.getNamedItem("bm-path").value:"",r.animType=i.getNamedItem("data-anim-type")?i.getNamedItem("data-anim-type").value:i.getNamedItem("data-bm-type")?i.getNamedItem("data-bm-type").value:i.getNamedItem("bm-type")?i.getNamedItem("bm-type").value:i.getNamedItem("data-bm-renderer")?i.getNamedItem("data-bm-renderer").value:i.getNamedItem("bm-renderer")?i.getNamedItem("bm-renderer").value:getRegisteredRenderer()||"canvas";var s=i.getNamedItem("data-anim-loop")?i.getNamedItem("data-anim-loop").value:i.getNamedItem("data-bm-loop")?i.getNamedItem("data-bm-loop").value:i.getNamedItem("bm-loop")?i.getNamedItem("bm-loop").value:"";"false"===s?r.loop=!1:"true"===s?r.loop=!0:""!==s&&(r.loop=parseInt(s,10));var a=i.getNamedItem("data-anim-autoplay")?i.getNamedItem("data-anim-autoplay").value:i.getNamedItem("data-bm-autoplay")?i.getNamedItem("data-bm-autoplay").value:!i.getNamedItem("bm-autoplay")||i.getNamedItem("bm-autoplay").value;r.autoplay="false"!==a,r.name=i.getNamedItem("data-name")?i.getNamedItem("data-name").value:i.getNamedItem("data-bm-name")?i.getNamedItem("data-bm-name").value:i.getNamedItem("bm-name")?i.getNamedItem("bm-name").value:"","false"===(i.getNamedItem("data-anim-prerender")?i.getNamedItem("data-anim-prerender").value:i.getNamedItem("data-bm-prerender")?i.getNamedItem("data-bm-prerender").value:i.getNamedItem("bm-prerender")?i.getNamedItem("bm-prerender").value:"")&&(r.prerender=!1),r.path?this.setParams(r):this.trigger("destroy")},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,r,i=this.animationData.layers,s=i.length,a=t.layers,n=a.length;for(r=0;r<n;r+=1)for(e=0;e<s;){if(i[e].id===a[r].id){i[e]=a[r];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(s=t.assets.length,e=0;e<s;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,dataManager.completeAnimation(this.animationData,this.onSegmentComplete)},AnimationItem.prototype.onSegmentComplete=function(t){this.animationData=t;var e=getExpressionsPlugin();e&&e.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var r=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,dataManager.loadData(r,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},AnimationItem.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},AnimationItem.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=markerParser(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},AnimationItem.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},AnimationItem.prototype.checkLoaded=function(){if(!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()){this.isLoaded=!0;var t=getExpressionsPlugin();t&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play()}},AnimationItem.prototype.resize=function(t,e){var r="number"==typeof t?t:void 0,i="number"==typeof e?e:void 0;this.renderer.updateContainerSize(r,i)},AnimationItem.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},AnimationItem.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},AnimationItem.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},AnimationItem.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},AnimationItem.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.getMarkerData=function(t){for(var e,r=0;r<this.markers.length;r+=1)if((e=this.markers[r]).payload&&e.payload.name===t)return e;return null},AnimationItem.prototype.goToAndStop=function(t,e,r){if(!r||this.name===r){var i=Number(t);if(isNaN(i)){var s=this.getMarkerData(t);s&&this.goToAndStop(s.time,!0)}else e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier);this.pause()}},AnimationItem.prototype.goToAndPlay=function(t,e,r){if(!r||this.name===r){var i=Number(t);if(isNaN(i)){var s=this.getMarkerData(t);s&&(s.duration?this.playSegments([s.time,s.time+s.duration],!0):this.goToAndStop(s.time,!0))}else this.goToAndStop(i,e,r);this.play()}},AnimationItem.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,r=!1;e>=this.totalFrames-1&&this.frameModifier>0?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(r=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(r=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),r&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(this.frameModifier>0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var r=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?r=t:this.currentRawFrame+this.firstFrame>e&&(r=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==r&&this.goToAndStop(r,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===_typeof$4(t[0])){var r,i=t.length;for(r=0;r<i;r+=1)this.segments.push(t[r])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},AnimationItem.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},AnimationItem.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},AnimationItem.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},AnimationItem.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},AnimationItem.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},AnimationItem.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},AnimationItem.prototype.setLoop=function(t){this.loop=t},AnimationItem.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},AnimationItem.prototype.getVolume=function(){return this.audioController.getVolume()},AnimationItem.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},AnimationItem.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},AnimationItem.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},AnimationItem.prototype.getPath=function(){return this.path},AnimationItem.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var r=t.p;-1!==r.indexOf("images/")&&(r=r.split("/")[1]),e=this.assetsPath+r}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},AnimationItem.prototype.getAssetData=function(t){for(var e=0,r=this.assets.length;e<r;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},AnimationItem.prototype.hide=function(){this.renderer.hide()},AnimationItem.prototype.show=function(){this.renderer.show()},AnimationItem.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},AnimationItem.prototype.updateDocumentData=function(t,e,r){try{this.renderer.getElementByPath(t).updateDocumentData(e,r)}catch(t){}},AnimationItem.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new BMCompleteEvent(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new BMDestroyEvent(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new BMCompleteEvent(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new BMDestroyEvent(t,this))},AnimationItem.prototype.triggerRenderFrameError=function(t){var e=new BMRenderFrameErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)},AnimationItem.prototype.triggerConfigError=function(t){var e=new BMConfigErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)};var animationManager=function(){var t={},e=[],r=0,i=0,s=0,a=!0,n=!1;function o(t){for(var r=0,s=t.target;r<i;)e[r].animation===s&&(e.splice(r,1),r-=1,i-=1,s.isPaused||p()),r+=1}function h(t,r){if(!t)return null;for(var s=0;s<i;){if(e[s].elem===t&&null!==e[s].elem)return e[s].animation;s+=1}var a=new AnimationItem;return f(a,t),a.setData(t,r),a}function l(){s+=1,u()}function p(){s-=1}function f(t,r){t.addEventListener("destroy",o),t.addEventListener("_active",l),t.addEventListener("_idle",p),e.push({elem:r,animation:t}),i+=1}function c(t){var o,h=t-r;for(o=0;o<i;o+=1)e[o].animation.advanceTime(h);r=t,s&&!n?window.requestAnimationFrame(c):a=!0}function m(t){r=t,window.requestAnimationFrame(c)}function u(){!n&&s&&a&&(window.requestAnimationFrame(m),a=!1)}return t.registerAnimation=h,t.loadAnimation=function(t){var e=new AnimationItem;return f(e,null),e.setParams(t),e},t.setSpeed=function(t,r){var s;for(s=0;s<i;s+=1)e[s].animation.setSpeed(t,r)},t.setDirection=function(t,r){var s;for(s=0;s<i;s+=1)e[s].animation.setDirection(t,r)},t.play=function(t){var r;for(r=0;r<i;r+=1)e[r].animation.play(t)},t.pause=function(t){var r;for(r=0;r<i;r+=1)e[r].animation.pause(t)},t.stop=function(t){var r;for(r=0;r<i;r+=1)e[r].animation.stop(t)},t.togglePause=function(t){var r;for(r=0;r<i;r+=1)e[r].animation.togglePause(t)},t.searchAnimations=function(t,e,r){var i,s=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),a=s.length;for(i=0;i<a;i+=1)r&&s[i].setAttribute("data-bm-type",r),h(s[i],t);if(e&&0===a){r||(r="svg");var n=document.getElementsByTagName("body")[0];n.innerText="";var o=createTag("div");o.style.width="100%",o.style.height="100%",o.setAttribute("data-bm-type",r),n.appendChild(o),h(o,t)}},t.resize=function(){var t;for(t=0;t<i;t+=1)e[t].animation.resize()},t.goToAndStop=function(t,r,s){var a;for(a=0;a<i;a+=1)e[a].animation.goToAndStop(t,r,s)},t.destroy=function(t){var r;for(r=i-1;r>=0;r-=1)e[r].animation.destroy(t)},t.freeze=function(){n=!0},t.unfreeze=function(){n=!1,u()},t.setVolume=function(t,r){var s;for(s=0;s<i;s+=1)e[s].animation.setVolume(t,r)},t.mute=function(t){var r;for(r=0;r<i;r+=1)e[r].animation.mute(t)},t.unmute=function(t){var r;for(r=0;r<i;r+=1)e[r].animation.unmute(t)},t.getRegisteredAnimations=function(){var t,r=e.length,i=[];for(t=0;t<r;t+=1)i.push(e[t].animation);return i},t}(),BezierFactory=function(){var t={getBezierEasing:function(t,r,i,s,a){var n=a||("bez_"+t+"_"+r+"_"+i+"_"+s).replace(/\./g,"p");if(e[n])return e[n];var o=new p([t,r,i,s]);return e[n]=o,o}},e={};var r=11,i=1/(r-1),s="function"==typeof Float32Array;function a(t,e){return 1-3*e+3*t}function n(t,e){return 3*e-6*t}function o(t){return 3*t}function h(t,e,r){return((a(e,r)*t+n(e,r))*t+o(e))*t}function l(t,e,r){return 3*a(e,r)*t*t+2*n(e,r)*t+o(e)}function p(t){this._p=t,this._mSampleValues=s?new Float32Array(r):new Array(r),this._precomputed=!1,this.get=this.get.bind(this)}return p.prototype={get:function(t){var e=this._p[0],r=this._p[1],i=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===r&&i===s?t:0===t?0:1===t?1:h(this._getTForX(t),r,s)},_precompute:function(){var t=this._p[0],e=this._p[1],r=this._p[2],i=this._p[3];this._precomputed=!0,t===e&&r===i||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],s=0;s<r;++s)this._mSampleValues[s]=h(s*i,t,e)},_getTForX:function(t){for(var e=this._p[0],s=this._p[2],a=this._mSampleValues,n=0,o=1,p=r-1;o!==p&&a[o]<=t;++o)n+=i;var f=n+(t-a[--o])/(a[o+1]-a[o])*i,c=l(f,e,s);return c>=.001?function(t,e,r,i){for(var s=0;s<4;++s){var a=l(e,r,i);if(0===a)return e;e-=(h(e,r,i)-t)/a}return e}(t,f,e,s):0===c?f:function(t,e,r,i,s){var a,n,o=0;do{(a=h(n=e+(r-e)/2,i,s)-t)>0?r=n:e=n}while(Math.abs(a)>1e-7&&++o<10);return n}(t,n,n+i,e,s)}},t}(),pooling={double:function(t){return t.concat(createSizedArray(t.length))}},poolFactory=function(t,e,r){var i=0,s=t,a=createSizedArray(s);return{newElement:function(){return i?a[i-=1]:e()},release:function(t){i===s&&(a=pooling.double(a),s*=2),r&&r(t),a[i]=t,i+=1}}},bezierLengthPool=poolFactory(8,(function(){return{addedLength:0,percents:createTypedArray("float32",getDefaultCurveSegments()),lengths:createTypedArray("float32",getDefaultCurveSegments())}})),segmentsLengthPool=poolFactory(8,(function(){return{lengths:[],totalLength:0}}),(function(t){var e,r=t.lengths.length;for(e=0;e<r;e+=1)bezierLengthPool.release(t.lengths[e]);t.lengths.length=0}));function bezFunction(){var t=Math;function e(t,e,r,i,s,a){var n=t*i+e*s+r*a-s*i-a*t-r*e;return n>-.001&&n<.001}var r=function(t,e,r,i){var s,a,n,o,h,l,p=getDefaultCurveSegments(),f=0,c=[],m=[],u=bezierLengthPool.newElement();for(n=r.length,s=0;s<p;s+=1){for(h=s/(p-1),l=0,a=0;a<n;a+=1)o=bmPow(1-h,3)*t[a]+3*bmPow(1-h,2)*h*r[a]+3*(1-h)*bmPow(h,2)*i[a]+bmPow(h,3)*e[a],c[a]=o,null!==m[a]&&(l+=bmPow(c[a]-m[a],2)),m[a]=c[a];l&&(f+=l=bmSqrt(l)),u.percents[s]=h,u.lengths[s]=f}return u.addedLength=f,u};function i(t){this.segmentLength=0,this.points=new Array(t)}function s(t,e){this.partialLength=t,this.point=e}var a,n=(a={},function(t,r,n,o){var h=(t[0]+"_"+t[1]+"_"+r[0]+"_"+r[1]+"_"+n[0]+"_"+n[1]+"_"+o[0]+"_"+o[1]).replace(/\./g,"p");if(!a[h]){var l,p,f,c,m,u,d,y=getDefaultCurveSegments(),g=0,v=null;2===t.length&&(t[0]!==r[0]||t[1]!==r[1])&&e(t[0],t[1],r[0],r[1],t[0]+n[0],t[1]+n[1])&&e(t[0],t[1],r[0],r[1],r[0]+o[0],r[1]+o[1])&&(y=2);var b=new i(y);for(f=n.length,l=0;l<y;l+=1){for(d=createSizedArray(f),m=l/(y-1),u=0,p=0;p<f;p+=1)c=bmPow(1-m,3)*t[p]+3*bmPow(1-m,2)*m*(t[p]+n[p])+3*(1-m)*bmPow(m,2)*(r[p]+o[p])+bmPow(m,3)*r[p],d[p]=c,null!==v&&(u+=bmPow(d[p]-v[p],2));g+=u=bmSqrt(u),b.points[l]=new s(u,d),v=d}b.segmentLength=g,a[h]=b}return a[h]});function o(t,e){var r=e.percents,i=e.lengths,s=r.length,a=bmFloor((s-1)*t),n=t*e.addedLength,o=0;if(a===s-1||0===a||n===i[a])return r[a];for(var h=i[a]>n?-1:1,l=!0;l;)if(i[a]<=n&&i[a+1]>n?(o=(n-i[a])/(i[a+1]-i[a]),l=!1):a+=h,a<0||a>=s-1){if(a===s-1)return r[a];l=!1}return r[a]+(r[a+1]-r[a])*o}var h=createTypedArray("float32",8);return{getSegmentsLength:function(t){var e,i=segmentsLengthPool.newElement(),s=t.c,a=t.v,n=t.o,o=t.i,h=t._length,l=i.lengths,p=0;for(e=0;e<h-1;e+=1)l[e]=r(a[e],a[e+1],n[e],o[e+1]),p+=l[e].addedLength;return s&&h&&(l[e]=r(a[e],a[0],n[e],o[0]),p+=l[e].addedLength),i.totalLength=p,i},getNewSegment:function(e,r,i,s,a,n,l){a<0?a=0:a>1&&(a=1);var p,f=o(a,l),c=o(n=n>1?1:n,l),m=e.length,u=1-f,d=1-c,y=u*u*u,g=f*u*u*3,v=f*f*u*3,b=f*f*f,P=u*u*d,S=f*u*d+u*f*d+u*u*c,_=f*f*d+u*f*c+f*u*c,E=f*f*c,x=u*d*d,A=f*d*d+u*c*d+u*d*c,M=f*c*d+u*c*c+f*d*c,T=f*c*c,k=d*d*d,F=c*d*d+d*c*d+d*d*c,I=c*c*d+d*c*c+c*d*c,D=c*c*c;for(p=0;p<m;p+=1)h[4*p]=t.round(1e3*(y*e[p]+g*i[p]+v*s[p]+b*r[p]))/1e3,h[4*p+1]=t.round(1e3*(P*e[p]+S*i[p]+_*s[p]+E*r[p]))/1e3,h[4*p+2]=t.round(1e3*(x*e[p]+A*i[p]+M*s[p]+T*r[p]))/1e3,h[4*p+3]=t.round(1e3*(k*e[p]+F*i[p]+I*s[p]+D*r[p]))/1e3;return h},getPointInSegment:function(e,r,i,s,a,n){var h=o(a,n),l=1-h;return[t.round(1e3*(l*l*l*e[0]+(h*l*l+l*h*l+l*l*h)*i[0]+(h*h*l+l*h*h+h*l*h)*s[0]+h*h*h*r[0]))/1e3,t.round(1e3*(l*l*l*e[1]+(h*l*l+l*h*l+l*l*h)*i[1]+(h*h*l+l*h*h+h*l*h)*s[1]+h*h*h*r[1]))/1e3]},buildBezierData:n,pointOnLine2D:e,pointOnLine3D:function(r,i,s,a,n,o,h,l,p){if(0===s&&0===o&&0===p)return e(r,i,a,n,h,l);var f,c=t.sqrt(t.pow(a-r,2)+t.pow(n-i,2)+t.pow(o-s,2)),m=t.sqrt(t.pow(h-r,2)+t.pow(l-i,2)+t.pow(p-s,2)),u=t.sqrt(t.pow(h-a,2)+t.pow(l-n,2)+t.pow(p-o,2));return(f=c>m?c>u?c-m-u:u-m-c:u>m?u-m-c:m-c-u)>-1e-4&&f<1e-4}}}var bez=bezFunction(),initFrame=initialDefaultFrame,mathAbs=Math.abs;function interpolateValue(t,e){var r,i=this.offsetTime;"multidimensional"===this.propType&&(r=createTypedArray("float32",this.pv.length));for(var s,a,n,o,h,l,p,f,c,m=e.lastIndex,u=m,d=this.keyframes.length-1,y=!0;y;){if(s=this.keyframes[u],a=this.keyframes[u+1],u===d-1&&t>=a.t-i){s.h&&(s=a),m=0;break}if(a.t-i>t){m=u;break}u<d-1?u+=1:(m=0,y=!1)}n=this.keyframesMetadata[u]||{};var g,v=a.t-i,b=s.t-i;if(s.to){n.bezierData||(n.bezierData=bez.buildBezierData(s.s,a.s||s.e,s.to,s.ti));var P=n.bezierData;if(t>=v||t<b){var S=t>=v?P.points.length-1:0;for(h=P.points[S].point.length,o=0;o<h;o+=1)r[o]=P.points[S].point[o]}else{n.__fnct?c=n.__fnct:(c=BezierFactory.getBezierEasing(s.o.x,s.o.y,s.i.x,s.i.y,s.n).get,n.__fnct=c),l=c((t-b)/(v-b));var _,E=P.segmentLength*l,x=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastAddedLength:0;for(f=e.lastFrame<t&&e._lastKeyframeIndex===u?e._lastPoint:0,y=!0,p=P.points.length;y;){if(x+=P.points[f].partialLength,0===E||0===l||f===P.points.length-1){for(h=P.points[f].point.length,o=0;o<h;o+=1)r[o]=P.points[f].point[o];break}if(E>=x&&E<x+P.points[f+1].partialLength){for(_=(E-x)/P.points[f+1].partialLength,h=P.points[f].point.length,o=0;o<h;o+=1)r[o]=P.points[f].point[o]+(P.points[f+1].point[o]-P.points[f].point[o])*_;break}f<p-1?f+=1:y=!1}e._lastPoint=f,e._lastAddedLength=x-P.points[f].partialLength,e._lastKeyframeIndex=u}}else{var A,M,T,k,F;if(d=s.s.length,g=a.s||s.e,this.sh&&1!==s.h)if(t>=v)r[0]=g[0],r[1]=g[1],r[2]=g[2];else if(t<=b)r[0]=s.s[0],r[1]=s.s[1],r[2]=s.s[2];else{quaternionToEuler(r,slerp(createQuaternion(s.s),createQuaternion(g),(t-b)/(v-b)))}else for(u=0;u<d;u+=1)1!==s.h&&(t>=v?l=1:t<b?l=0:(s.o.x.constructor===Array?(n.__fnct||(n.__fnct=[]),n.__fnct[u]?c=n.__fnct[u]:(A=void 0===s.o.x[u]?s.o.x[0]:s.o.x[u],M=void 0===s.o.y[u]?s.o.y[0]:s.o.y[u],T=void 0===s.i.x[u]?s.i.x[0]:s.i.x[u],k=void 0===s.i.y[u]?s.i.y[0]:s.i.y[u],c=BezierFactory.getBezierEasing(A,M,T,k).get,n.__fnct[u]=c)):n.__fnct?c=n.__fnct:(A=s.o.x,M=s.o.y,T=s.i.x,k=s.i.y,c=BezierFactory.getBezierEasing(A,M,T,k).get,s.keyframeMetadata=c),l=c((t-b)/(v-b)))),g=a.s||s.e,F=1===s.h?s.s[u]:s.s[u]+(g[u]-s.s[u])*l,"multidimensional"===this.propType?r[u]=F:r=F}return e.lastIndex=m,r}function slerp(t,e,r){var i,s,a,n,o,h=[],l=t[0],p=t[1],f=t[2],c=t[3],m=e[0],u=e[1],d=e[2],y=e[3];return(s=l*m+p*u+f*d+c*y)<0&&(s=-s,m=-m,u=-u,d=-d,y=-y),1-s>1e-6?(i=Math.acos(s),a=Math.sin(i),n=Math.sin((1-r)*i)/a,o=Math.sin(r*i)/a):(n=1-r,o=r),h[0]=n*l+o*m,h[1]=n*p+o*u,h[2]=n*f+o*d,h[3]=n*c+o*y,h}function quaternionToEuler(t,e){var r=e[0],i=e[1],s=e[2],a=e[3],n=Math.atan2(2*i*a-2*r*s,1-2*i*i-2*s*s),o=Math.asin(2*r*i+2*s*a),h=Math.atan2(2*r*a-2*i*s,1-2*r*r-2*s*s);t[0]=n/degToRads,t[1]=o/degToRads,t[2]=h/degToRads}function createQuaternion(t){var e=t[0]*degToRads,r=t[1]*degToRads,i=t[2]*degToRads,s=Math.cos(e/2),a=Math.cos(r/2),n=Math.cos(i/2),o=Math.sin(e/2),h=Math.sin(r/2),l=Math.sin(i/2);return[o*h*n+s*a*l,o*a*n+s*h*l,s*h*n-o*a*l,s*a*n-o*h*l]}function getValueAtCurrentTime(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,r=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==initFrame&&(this._caching.lastFrame>=r&&t>=r||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var i=this.interpolateValue(t,this._caching);this.pv=i}return this._caching.lastFrame=t,this.pv}function setVValue(t){var e;if("unidimensional"===this.propType)e=t*this.mult,mathAbs(this.v-e)>1e-5&&(this.v=e,this._mdf=!0);else for(var r=0,i=this.v.length;r<i;)e=t[r]*this.mult,mathAbs(this.v[r]-e)>1e-5&&(this.v[r]=e,this._mdf=!0),r+=1}function processEffectsSequence(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t;this.lock=!0,this._mdf=this._isFirstFrame;var e=this.effectsSequence.length,r=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)r=this.effectsSequence[t](r);this.setVValue(r),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function addEffect(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function ValueProperty(t,e,r,i){this.propType="unidimensional",this.mult=r||1,this.data=e,this.v=r?e.k*r:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=i,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function MultiDimensionalProperty(t,e,r,i){var s;this.propType="multidimensional",this.mult=r||1,this.data=e,this._mdf=!1,this.elem=t,this.container=i,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var a=e.k.length;for(this.v=createTypedArray("float32",a),this.pv=createTypedArray("float32",a),this.vel=createTypedArray("float32",a),s=0;s<a;s+=1)this.v[s]=e.k[s]*this.mult,this.pv[s]=e.k[s];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function KeyframedValueProperty(t,e,r,i){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:initFrame,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=r||1,this.elem=t,this.container=i,this.comp=t.comp,this.v=initFrame,this.pv=initFrame,this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.addEffect=addEffect}function KeyframedMultidimensionalProperty(t,e,r,i){var s;this.propType="multidimensional";var a,n,o,h,l=e.k.length;for(s=0;s<l-1;s+=1)e.k[s].to&&e.k[s].s&&e.k[s+1]&&e.k[s+1].s&&(a=e.k[s].s,n=e.k[s+1].s,o=e.k[s].to,h=e.k[s].ti,(2===a.length&&(a[0]!==n[0]||a[1]!==n[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],a[0]+o[0],a[1]+o[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],n[0]+h[0],n[1]+h[1])||3===a.length&&(a[0]!==n[0]||a[1]!==n[1]||a[2]!==n[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],a[0]+o[0],a[1]+o[1],a[2]+o[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],n[0]+h[0],n[1]+h[1],n[2]+h[2]))&&(e.k[s].to=null,e.k[s].ti=null),a[0]===n[0]&&a[1]===n[1]&&0===o[0]&&0===o[1]&&0===h[0]&&0===h[1]&&(2===a.length||a[2]===n[2]&&0===o[2]&&0===h[2])&&(e.k[s].to=null,e.k[s].ti=null));this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=r||1,this.elem=t,this.container=i,this.comp=t.comp,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.frameId=-1;var p=e.k[0].s.length;for(this.v=createTypedArray("float32",p),this.pv=createTypedArray("float32",p),s=0;s<p;s+=1)this.v[s]=initFrame,this.pv[s]=initFrame;this._caching={lastFrame:initFrame,lastIndex:0,value:createTypedArray("float32",p)},this.addEffect=addEffect}var PropertyFactory={getProp:function(t,e,r,i,s){var a;if(e.sid&&(e=t.globalData.slotManager.getProp(e)),e.k.length)if("number"==typeof e.k[0])a=new MultiDimensionalProperty(t,e,i,s);else switch(r){case 0:a=new KeyframedValueProperty(t,e,i,s);break;case 1:a=new KeyframedMultidimensionalProperty(t,e,i,s)}else a=new ValueProperty(t,e,i,s);return a.effectsSequence.length&&s.addDynamicProperty(a),a}};function DynamicPropertyContainer(){}DynamicPropertyContainer.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){var t;this._mdf=!1;var e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var pointPool=poolFactory(8,(function(){return createTypedArray("float32",2)}));function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var r=0;r<e;)this.v[r]=pointPool.newElement(),this.o[r]=pointPool.newElement(),this.i[r]=pointPool.newElement(),r+=1},ShapePath.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},ShapePath.prototype.doubleArrayLength=function(){this.v=this.v.concat(createSizedArray(this._maxLength)),this.i=this.i.concat(createSizedArray(this._maxLength)),this.o=this.o.concat(createSizedArray(this._maxLength)),this._maxLength*=2},ShapePath.prototype.setXYAt=function(t,e,r,i,s){var a;switch(this._length=Math.max(this._length,i+1),this._length>=this._maxLength&&this.doubleArrayLength(),r){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o;break;default:a=[]}(!a[i]||a[i]&&!s)&&(a[i]=pointPool.newElement()),a[i][0]=t,a[i][1]=e},ShapePath.prototype.setTripleAt=function(t,e,r,i,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(r,i,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t=new ShapePath;t.setPathData(this.c,this._length);var e=this.v,r=this.o,i=this.i,s=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],i[0][0],i[0][1],r[0][0],r[0][1],0,!1),s=1);var a,n=this._length-1,o=this._length;for(a=s;a<o;a+=1)t.setTripleAt(e[n][0],e[n][1],i[n][0],i[n][1],r[n][0],r[n][1],a,!1),n-=1;return t},ShapePath.prototype.length=function(){return this._length};var shapePool=(factory=poolFactory(4,(function(){return new ShapePath}),(function(t){var e,r=t._length;for(e=0;e<r;e+=1)pointPool.release(t.v[e]),pointPool.release(t.i[e]),pointPool.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1})),factory.clone=function(t){var e,r=factory.newElement(),i=void 0===t._length?t.v.length:t._length;for(r.setLength(i),r.c=t.c,e=0;e<i;e+=1)r.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return r},factory),factory;function ShapeCollection(){this._length=0,this._maxLength=4,this.shapes=createSizedArray(this._maxLength)}ShapeCollection.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(createSizedArray(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},ShapeCollection.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)shapePool.release(this.shapes[t]);this._length=0};var shapeCollectionPool=(ob={newShapeCollection:function(){return _length?pool[_length-=1]:new ShapeCollection},release:function(t){var e,r=t._length;for(e=0;e<r;e+=1)shapePool.release(t.shapes[e]);t._length=0,_length===_maxLength&&(pool=pooling.double(pool),_maxLength*=2),pool[_length]=t,_length+=1}},_length=0,_maxLength=4,pool=createSizedArray(_maxLength),ob),ob,_length,_maxLength,pool,ShapePropertyFactory=function(){var t=-999999;function e(t,e,r){var i,s,a,n,o,h,l,p,f,c=r.lastIndex,m=this.keyframes;if(t<m[0].t-this.offsetTime)i=m[0].s[0],a=!0,c=0;else if(t>=m[m.length-1].t-this.offsetTime)i=m[m.length-1].s?m[m.length-1].s[0]:m[m.length-2].e[0],a=!0;else{for(var u,d,y,g=c,v=m.length-1,b=!0;b&&(u=m[g],!((d=m[g+1]).t-this.offsetTime>t));)g<v-1?g+=1:b=!1;if(y=this.keyframesMetadata[g]||{},c=g,!(a=1===u.h)){if(t>=d.t-this.offsetTime)p=1;else if(t<u.t-this.offsetTime)p=0;else{var P;y.__fnct?P=y.__fnct:(P=BezierFactory.getBezierEasing(u.o.x,u.o.y,u.i.x,u.i.y).get,y.__fnct=P),p=P((t-(u.t-this.offsetTime))/(d.t-this.offsetTime-(u.t-this.offsetTime)))}s=d.s?d.s[0]:u.e[0]}i=u.s[0]}for(h=e._length,l=i.i[0].length,r.lastIndex=c,n=0;n<h;n+=1)for(o=0;o<l;o+=1)f=a?i.i[n][o]:i.i[n][o]+(s.i[n][o]-i.i[n][o])*p,e.i[n][o]=f,f=a?i.o[n][o]:i.o[n][o]+(s.o[n][o]-i.o[n][o])*p,e.o[n][o]=f,f=a?i.v[n][o]:i.v[n][o]+(s.v[n][o]-i.v[n][o])*p,e.v[n][o]=f}function r(){var e=this.comp.renderedFrame-this.offsetTime,r=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime,s=this._caching.lastFrame;return s!==t&&(s<r&&e<r||s>i&&e>i)||(this._caching.lastIndex=s<e?this._caching.lastIndex:0,this.interpolateShape(e,this.pv,this._caching)),this._caching.lastFrame=e,this.pv}function i(){this.paths=this.localShapeCollection}function s(t){(function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var r,i=t._length;for(r=0;r<i;r+=1)if(t.v[r][0]!==e.v[r][0]||t.v[r][1]!==e.v[r][1]||t.o[r][0]!==e.o[r][0]||t.o[r][1]!==e.o[r][1]||t.i[r][0]!==e.i[r][0]||t.i[r][1]!==e.i[r][1])return!1;return!0})(this.v,t)||(this.v=shapePool.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function a(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t,e;this.lock=!0,this._mdf=!1,t=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k;var r=this.effectsSequence.length;for(e=0;e<r;e+=1)t=this.effectsSequence[e](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function n(t,e,r){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var s=3===r?e.pt.k:e.ks.k;this.v=shapePool.clone(s),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=i,this.effectsSequence=[]}function o(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function h(e,s,a){this.propType="shape",this.comp=e.comp,this.elem=e,this.container=e,this.offsetTime=e.data.st,this.keyframes=3===a?s.pt.k:s.ks.k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;var n=this.keyframes[0].s[0].i.length;this.v=shapePool.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,n),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=t,this.reset=i,this._caching={lastFrame:t,lastIndex:0},this.effectsSequence=[r.bind(this)]}n.prototype.interpolateShape=e,n.prototype.getValue=a,n.prototype.setVValue=s,n.prototype.addEffect=o,h.prototype.getValue=a,h.prototype.interpolateShape=e,h.prototype.setVValue=s,h.prototype.addEffect=o;var l=function(){var t=roundCorner;function e(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}return e.prototype={reset:i,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var e=this.p.v[0],r=this.p.v[1],i=this.s.v[0]/2,s=this.s.v[1]/2,a=3!==this.d,n=this.v;n.v[0][0]=e,n.v[0][1]=r-s,n.v[1][0]=a?e+i:e-i,n.v[1][1]=r,n.v[2][0]=e,n.v[2][1]=r+s,n.v[3][0]=a?e-i:e+i,n.v[3][1]=r,n.i[0][0]=a?e-i*t:e+i*t,n.i[0][1]=r-s,n.i[1][0]=a?e+i:e-i,n.i[1][1]=r-s*t,n.i[2][0]=a?e+i*t:e-i*t,n.i[2][1]=r+s,n.i[3][0]=a?e-i:e+i,n.i[3][1]=r+s*t,n.o[0][0]=a?e+i*t:e-i*t,n.o[0][1]=r-s,n.o[1][0]=a?e+i:e-i,n.o[1][1]=r+s*t,n.o[2][0]=a?e-i*t:e+i*t,n.o[2][1]=r+s,n.o[3][0]=a?e-i:e+i,n.o[3][1]=r-s*t}},extendPrototype([DynamicPropertyContainer],e),e}(),p=function(){function t(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=PropertyFactory.getProp(t,e.ir,0,0,this),this.is=PropertyFactory.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=PropertyFactory.getProp(t,e.pt,0,0,this),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,degToRads,this),this.or=PropertyFactory.getProp(t,e.or,0,0,this),this.os=PropertyFactory.getProp(t,e.os,0,.01,this),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}return t.prototype={reset:i,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,r,i,s=2*Math.floor(this.pt.v),a=2*Math.PI/s,n=!0,o=this.or.v,h=this.ir.v,l=this.os.v,p=this.is.v,f=2*Math.PI*o/(2*s),c=2*Math.PI*h/(2*s),m=-Math.PI/2;m+=this.r.v;var u=3===this.data.d?-1:1;for(this.v._length=0,t=0;t<s;t+=1){r=n?l:p,i=n?f:c;var d=(e=n?o:h)*Math.cos(m),y=e*Math.sin(m),g=0===d&&0===y?0:y/Math.sqrt(d*d+y*y),v=0===d&&0===y?0:-d/Math.sqrt(d*d+y*y);d+=+this.p.v[0],y+=+this.p.v[1],this.v.setTripleAt(d,y,d-g*i*r*u,y-v*i*r*u,d+g*i*r*u,y+v*i*r*u,t,!0),n=!n,m+=a*u}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),r=2*Math.PI/e,i=this.or.v,s=this.os.v,a=2*Math.PI*i/(4*e),n=.5*-Math.PI,o=3===this.data.d?-1:1;for(n+=this.r.v,this.v._length=0,t=0;t<e;t+=1){var h=i*Math.cos(n),l=i*Math.sin(n),p=0===h&&0===l?0:l/Math.sqrt(h*h+l*l),f=0===h&&0===l?0:-h/Math.sqrt(h*h+l*l);h+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(h,l,h-p*a*s*o,l-f*a*s*o,h+p*a*s*o,l+f*a*s*o,t,!0),n+=r*o}this.paths.length=0,this.paths[0]=this.v}},extendPrototype([DynamicPropertyContainer],t),t}(),f=function(){function t(t,e){this.v=shapePool.newElement(),this.v.c=!0,this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}return t.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],r=this.s.v[0]/2,i=this.s.v[1]/2,s=bmMin(r,i,this.r.v),a=s*(1-roundCorner);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+r,e-i+s,t+r,e-i+s,t+r,e-i+a,0,!0),this.v.setTripleAt(t+r,e+i-s,t+r,e+i-a,t+r,e+i-s,1,!0),0!==s?(this.v.setTripleAt(t+r-s,e+i,t+r-s,e+i,t+r-a,e+i,2,!0),this.v.setTripleAt(t-r+s,e+i,t-r+a,e+i,t-r+s,e+i,3,!0),this.v.setTripleAt(t-r,e+i-s,t-r,e+i-s,t-r,e+i-a,4,!0),this.v.setTripleAt(t-r,e-i+s,t-r,e-i+a,t-r,e-i+s,5,!0),this.v.setTripleAt(t-r+s,e-i,t-r+s,e-i,t-r+a,e-i,6,!0),this.v.setTripleAt(t+r-s,e-i,t+r-a,e-i,t+r-s,e-i,7,!0)):(this.v.setTripleAt(t-r,e+i,t-r+a,e+i,t-r,e+i,2),this.v.setTripleAt(t-r,e-i,t-r,e-i+a,t-r,e-i,3))):(this.v.setTripleAt(t+r,e-i+s,t+r,e-i+a,t+r,e-i+s,0,!0),0!==s?(this.v.setTripleAt(t+r-s,e-i,t+r-s,e-i,t+r-a,e-i,1,!0),this.v.setTripleAt(t-r+s,e-i,t-r+a,e-i,t-r+s,e-i,2,!0),this.v.setTripleAt(t-r,e-i+s,t-r,e-i+s,t-r,e-i+a,3,!0),this.v.setTripleAt(t-r,e+i-s,t-r,e+i-a,t-r,e+i-s,4,!0),this.v.setTripleAt(t-r+s,e+i,t-r+s,e+i,t-r+a,e+i,5,!0),this.v.setTripleAt(t+r-s,e+i,t+r-a,e+i,t+r-s,e+i,6,!0),this.v.setTripleAt(t+r,e+i-s,t+r,e+i-s,t+r,e+i-a,7,!0)):(this.v.setTripleAt(t-r,e-i,t-r+a,e-i,t-r,e-i,1,!0),this.v.setTripleAt(t-r,e+i,t-r,e+i-a,t-r,e+i,2,!0),this.v.setTripleAt(t+r,e+i,t+r-a,e+i,t+r,e+i,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:i},extendPrototype([DynamicPropertyContainer],t),t}();var c={getShapeProp:function(t,e,r){var i;return 3===r||4===r?i=(3===r?e.pt:e.ks).k.length?new h(t,e,r):new n(t,e,r):5===r?i=new f(t,e):6===r?i=new l(t,e):7===r&&(i=new p(t,e)),i.k&&t.addDynamicProperty(i),i},getConstructorFunction:function(){return n},getKeyframedConstructorFunction:function(){return h}};return c}(),Matrix=function(){var t=Math.cos,e=Math.sin,r=Math.tan,i=Math.round;function s(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function a(r){if(0===r)return this;var i=t(r),s=e(r);return this._t(i,-s,0,0,s,i,0,0,0,0,1,0,0,0,0,1)}function n(r){if(0===r)return this;var i=t(r),s=e(r);return this._t(1,0,0,0,0,i,-s,0,0,s,i,0,0,0,0,1)}function o(r){if(0===r)return this;var i=t(r),s=e(r);return this._t(i,0,s,0,0,1,0,0,-s,0,i,0,0,0,0,1)}function h(r){if(0===r)return this;var i=t(r),s=e(r);return this._t(i,-s,0,0,s,i,0,0,0,0,1,0,0,0,0,1)}function l(t,e){return this._t(1,e,t,1,0,0)}function p(t,e){return this.shear(r(t),r(e))}function f(i,s){var a=t(s),n=e(s);return this._t(a,n,0,0,-n,a,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,r(i),1,0,0,0,0,1,0,0,0,0,1)._t(a,-n,0,0,n,a,0,0,0,0,1,0,0,0,0,1)}function c(t,e,r){return r||0===r||(r=1),1===t&&1===e&&1===r?this:this._t(t,0,0,0,0,e,0,0,0,0,r,0,0,0,0,1)}function m(t,e,r,i,s,a,n,o,h,l,p,f,c,m,u,d){return this.props[0]=t,this.props[1]=e,this.props[2]=r,this.props[3]=i,this.props[4]=s,this.props[5]=a,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=l,this.props[10]=p,this.props[11]=f,this.props[12]=c,this.props[13]=m,this.props[14]=u,this.props[15]=d,this}function u(t,e,r){return r=r||0,0!==t||0!==e||0!==r?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,r,1):this}function d(t,e,r,i,s,a,n,o,h,l,p,f,c,m,u,d){var y=this.props;if(1===t&&0===e&&0===r&&0===i&&0===s&&1===a&&0===n&&0===o&&0===h&&0===l&&1===p&&0===f)return y[12]=y[12]*t+y[15]*c,y[13]=y[13]*a+y[15]*m,y[14]=y[14]*p+y[15]*u,y[15]*=d,this._identityCalculated=!1,this;var g=y[0],v=y[1],b=y[2],P=y[3],S=y[4],_=y[5],E=y[6],x=y[7],A=y[8],M=y[9],T=y[10],k=y[11],F=y[12],I=y[13],D=y[14],C=y[15];return y[0]=g*t+v*s+b*h+P*c,y[1]=g*e+v*a+b*l+P*m,y[2]=g*r+v*n+b*p+P*u,y[3]=g*i+v*o+b*f+P*d,y[4]=S*t+_*s+E*h+x*c,y[5]=S*e+_*a+E*l+x*m,y[6]=S*r+_*n+E*p+x*u,y[7]=S*i+_*o+E*f+x*d,y[8]=A*t+M*s+T*h+k*c,y[9]=A*e+M*a+T*l+k*m,y[10]=A*r+M*n+T*p+k*u,y[11]=A*i+M*o+T*f+k*d,y[12]=F*t+I*s+D*h+C*c,y[13]=F*e+I*a+D*l+C*m,y[14]=F*r+I*n+D*p+C*u,y[15]=F*i+I*o+D*f+C*d,this._identityCalculated=!1,this}function y(t){var e=t.props;return this.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}function g(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function v(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function b(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function P(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function S(t,e,r){return{x:t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]}}function _(t,e,r){return t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12]}function E(t,e,r){return t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13]}function x(t,e,r){return t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]}function A(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,r=-this.props[1]/t,i=-this.props[4]/t,s=this.props[0]/t,a=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,n=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,o=new Matrix;return o.props[0]=e,o.props[1]=r,o.props[4]=i,o.props[5]=s,o.props[12]=a,o.props[13]=n,o}function M(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function T(t){var e,r=t.length,i=[];for(e=0;e<r;e+=1)i[e]=M(t[e]);return i}function k(t,e,r){var i=createTypedArray("float32",6);if(this.isIdentity())i[0]=t[0],i[1]=t[1],i[2]=e[0],i[3]=e[1],i[4]=r[0],i[5]=r[1];else{var s=this.props[0],a=this.props[1],n=this.props[4],o=this.props[5],h=this.props[12],l=this.props[13];i[0]=t[0]*s+t[1]*n+h,i[1]=t[0]*a+t[1]*o+l,i[2]=e[0]*s+e[1]*n+h,i[3]=e[0]*a+e[1]*o+l,i[4]=r[0]*s+r[1]*n+h,i[5]=r[0]*a+r[1]*o+l}return i}function F(t,e,r){return this.isIdentity()?[t,e,r]:[t*this.props[0]+e*this.props[4]+r*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+r*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+r*this.props[10]+this.props[14]]}function I(t,e){if(this.isIdentity())return t+","+e;var r=this.props;return Math.round(100*(t*r[0]+e*r[4]+r[12]))/100+","+Math.round(100*(t*r[1]+e*r[5]+r[13]))/100}function D(){for(var t=0,e=this.props,r="matrix3d(";t<16;)r+=i(1e4*e[t])/1e4,r+=15===t?")":",",t+=1;return r}function C(t){return t<1e-6&&t>0||t>-1e-6&&t<0?i(1e4*t)/1e4:t}function w(){var t=this.props;return"matrix("+C(t[0])+","+C(t[1])+","+C(t[4])+","+C(t[5])+","+C(t[12])+","+C(t[13])+")"}return function(){this.reset=s,this.rotate=a,this.rotateX=n,this.rotateY=o,this.rotateZ=h,this.skew=p,this.skewFromAxis=f,this.shear=l,this.scale=c,this.setTransform=m,this.translate=u,this.transform=d,this.multiply=y,this.applyToPoint=S,this.applyToX=_,this.applyToY=E,this.applyToZ=x,this.applyToPointArray=F,this.applyToTriplePoints=k,this.applyToPointStringified=I,this.toCSS=D,this.to2dCSS=w,this.clone=b,this.cloneFromProps=P,this.equals=v,this.inversePoints=T,this.inversePoint=M,this.getInverseMatrix=A,this._t=this.transform,this.isIdentity=g,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}}();function _typeof$3(t){return _typeof$3="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$3(t)}var lottie={},standalone="__[STANDALONE]__",animationData="__[ANIMATIONDATA]__",renderer="";function setLocation(t){setLocationHref(t)}function searchAnimations(){!0===standalone?animationManager.searchAnimations(animationData,standalone,renderer):animationManager.searchAnimations()}function setSubframeRendering(t){setSubframeEnabled(t)}function setPrefix(t){setIdPrefix(t)}function loadAnimation(t){return!0===standalone&&(t.animationData=JSON.parse(animationData)),animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":setDefaultCurveSegments(200);break;default:case"medium":setDefaultCurveSegments(50);break;case"low":setDefaultCurveSegments(10)}else!isNaN(t)&&t>1&&setDefaultCurveSegments(t);getDefaultCurveSegments()>=50?roundValues(!1):roundValues(!0)}function inBrowser(){return"undefined"!=typeof navigator}function installPlugin(t,e){"expressions"===t&&setExpressionsPlugin(e)}function getFactory(t){switch(t){case"propertyFactory":return PropertyFactory;case"shapePropertyFactory":return ShapePropertyFactory;case"matrix":return Matrix;default:return null}}function checkReady(){"complete"===document.readyState&&(clearInterval(readyStateCheckInterval),searchAnimations())}function getQueryVariable(t){for(var e=queryString.split("&"),r=0;r<e.length;r+=1){var i=e[r].split("=");if(decodeURIComponent(i[0])==t)return decodeURIComponent(i[1])}return null}lottie.play=animationManager.play,lottie.pause=animationManager.pause,lottie.setLocationHref=setLocation,lottie.togglePause=animationManager.togglePause,lottie.setSpeed=animationManager.setSpeed,lottie.setDirection=animationManager.setDirection,lottie.stop=animationManager.stop,lottie.searchAnimations=searchAnimations,lottie.registerAnimation=animationManager.registerAnimation,lottie.loadAnimation=loadAnimation,lottie.setSubframeRendering=setSubframeRendering,lottie.resize=animationManager.resize,lottie.goToAndStop=animationManager.goToAndStop,lottie.destroy=animationManager.destroy,lottie.setQuality=setQuality,lottie.inBrowser=inBrowser,lottie.installPlugin=installPlugin,lottie.freeze=animationManager.freeze,lottie.unfreeze=animationManager.unfreeze,lottie.setVolume=animationManager.setVolume,lottie.mute=animationManager.mute,lottie.unmute=animationManager.unmute,lottie.getRegisteredAnimations=animationManager.getRegisteredAnimations,lottie.useWebWorker=setWebWorker,lottie.setIDPrefix=setPrefix,lottie.__getFactory=getFactory,lottie.version="5.13.0";var queryString="";if(standalone){var scripts=document.getElementsByTagName("script"),index=scripts.length-1,myScript=scripts[index]||{src:""};queryString=myScript.src?myScript.src.replace(/^[^\?]+\??/,""):"",renderer=getQueryVariable("renderer")}var readyStateCheckInterval=setInterval(checkReady,100);try{"object"===("undefined"==typeof exports?"undefined":_typeof$3(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=lottie)}catch(t){}var ShapeModifiers=function(){var t={},e={};return t.registerModifier=function(t,r){e[t]||(e[t]=r)},t.getModifier=function(t,r,i){return new e[t](r,i)},t}();function ShapeModifier(){}function TrimModifier(){}function PuckerAndBloatModifier(){}ShapeModifier.prototype.initModifierProperties=function(){},ShapeModifier.prototype.addShapeToModifier=function(){},ShapeModifier.prototype.addShape=function(t){if(!this.closed){t.sh.container.addDynamicProperty(t.sh);var e={shape:t.sh,data:t,localShapeCollection:shapeCollectionPool.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},ShapeModifier.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=initialDefaultFrame,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},ShapeModifier.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},extendPrototype([DynamicPropertyContainer],ShapeModifier),extendPrototype([ShapeModifier],TrimModifier),TrimModifier.prototype.initModifierProperties=function(t,e){this.s=PropertyFactory.getProp(t,e.s,0,.01,this),this.e=PropertyFactory.getProp(t,e.e,0,.01,this),this.o=PropertyFactory.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},TrimModifier.prototype.addShapeToModifier=function(t){t.pathsData=[]},TrimModifier.prototype.calculateShapeEdges=function(t,e,r,i,s){var a=[];e<=1?a.push({s:t,e:e}):t>=1?a.push({s:t-1,e:e-1}):(a.push({s:t,e:1}),a.push({s:0,e:e-1}));var n,o,h=[],l=a.length;for(n=0;n<l;n+=1){var p,f;if(!((o=a[n]).e*s<i||o.s*s>i+r))p=o.s*s<=i?0:(o.s*s-i)/r,f=o.e*s>=i+r?1:(o.e*s-i)/r,h.push([p,f])}return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){var e,r=t.length;for(e=0;e<r;e+=1)segmentsLengthPool.release(t[e]);return t.length=0,t},TrimModifier.prototype.processShapes=function(t){var e,r,i,s;if(this._mdf||t){var a=this.o.v%360/360;if(a<0&&(a+=1),(e=this.s.v>1?1+a:this.s.v<0?0+a:this.s.v+a)>(r=this.e.v>1?1+a:this.e.v<0?0+a:this.e.v+a)){var n=e;e=r,r=n}e=1e-4*Math.round(1e4*e),r=1e-4*Math.round(1e4*r),this.sValue=e,this.eValue=r}else e=this.sValue,r=this.eValue;var o,h,l,p,f,c=this.shapes.length,m=0;if(r===e)for(s=0;s<c;s+=1)this.shapes[s].localShapeCollection.releaseShapes(),this.shapes[s].shape._mdf=!0,this.shapes[s].shape.paths=this.shapes[s].localShapeCollection,this._mdf&&(this.shapes[s].pathsData.length=0);else if(1===r&&0===e||0===r&&1===e){if(this._mdf)for(s=0;s<c;s+=1)this.shapes[s].pathsData.length=0,this.shapes[s].shape._mdf=!0}else{var u,d,y=[];for(s=0;s<c;s+=1)if((u=this.shapes[s]).shape._mdf||this._mdf||t||2===this.m){if(h=(i=u.shape.paths)._length,f=0,!u.shape._mdf&&u.pathsData.length)f=u.totalShapeLength;else{for(l=this.releasePathsData(u.pathsData),o=0;o<h;o+=1)p=bez.getSegmentsLength(i.shapes[o]),l.push(p),f+=p.totalLength;u.totalShapeLength=f,u.pathsData=l}m+=f,u.shape._mdf=!0}else u.shape.paths=u.localShapeCollection;var g,v=e,b=r,P=0;for(s=c-1;s>=0;s-=1)if((u=this.shapes[s]).shape._mdf){for((d=u.localShapeCollection).releaseShapes(),2===this.m&&c>1?(g=this.calculateShapeEdges(e,r,u.totalShapeLength,P,m),P+=u.totalShapeLength):g=[[v,b]],h=g.length,o=0;o<h;o+=1){v=g[o][0],b=g[o][1],y.length=0,b<=1?y.push({s:u.totalShapeLength*v,e:u.totalShapeLength*b}):v>=1?y.push({s:u.totalShapeLength*(v-1),e:u.totalShapeLength*(b-1)}):(y.push({s:u.totalShapeLength*v,e:u.totalShapeLength}),y.push({s:0,e:u.totalShapeLength*(b-1)}));var S=this.addShapes(u,y[0]);if(y[0].s!==y[0].e){if(y.length>1)if(u.shape.paths.shapes[u.shape.paths._length-1].c){var _=S.pop();this.addPaths(S,d),S=this.addShapes(u,y[1],_)}else this.addPaths(S,d),S=this.addShapes(u,y[1]);this.addPaths(S,d)}}u.shape.paths=d}}},TrimModifier.prototype.addPaths=function(t,e){var r,i=t.length;for(r=0;r<i;r+=1)e.addShape(t[r])},TrimModifier.prototype.addSegment=function(t,e,r,i,s,a,n){s.setXYAt(e[0],e[1],"o",a),s.setXYAt(r[0],r[1],"i",a+1),n&&s.setXYAt(t[0],t[1],"v",a),s.setXYAt(i[0],i[1],"v",a+1)},TrimModifier.prototype.addSegmentFromArray=function(t,e,r,i){e.setXYAt(t[1],t[5],"o",r),e.setXYAt(t[2],t[6],"i",r+1),i&&e.setXYAt(t[0],t[4],"v",r),e.setXYAt(t[3],t[7],"v",r+1)},TrimModifier.prototype.addShapes=function(t,e,r){var i,s,a,n,o,h,l,p,f=t.pathsData,c=t.shape.paths.shapes,m=t.shape.paths._length,u=0,d=[],y=!0;for(r?(o=r._length,p=r._length):(r=shapePool.newElement(),o=0,p=0),d.push(r),i=0;i<m;i+=1){for(h=f[i].lengths,r.c=c[i].c,a=c[i].c?h.length:h.length+1,s=1;s<a;s+=1)if(u+(n=h[s-1]).addedLength<e.s)u+=n.addedLength,r.c=!1;else{if(u>e.e){r.c=!1;break}e.s<=u&&e.e>=u+n.addedLength?(this.addSegment(c[i].v[s-1],c[i].o[s-1],c[i].i[s],c[i].v[s],r,o,y),y=!1):(l=bez.getNewSegment(c[i].v[s-1],c[i].v[s],c[i].o[s-1],c[i].i[s],(e.s-u)/n.addedLength,(e.e-u)/n.addedLength,h[s-1]),this.addSegmentFromArray(l,r,o,y),y=!1,r.c=!1),u+=n.addedLength,o+=1}if(c[i].c&&h.length){if(n=h[s-1],u<=e.e){var g=h[s-1].addedLength;e.s<=u&&e.e>=u+g?(this.addSegment(c[i].v[s-1],c[i].o[s-1],c[i].i[0],c[i].v[0],r,o,y),y=!1):(l=bez.getNewSegment(c[i].v[s-1],c[i].v[0],c[i].o[s-1],c[i].i[0],(e.s-u)/g,(e.e-u)/g,h[s-1]),this.addSegmentFromArray(l,r,o,y),y=!1,r.c=!1)}else r.c=!1;u+=n.addedLength,o+=1}if(r._length&&(r.setXYAt(r.v[p][0],r.v[p][1],"i",p),r.setXYAt(r.v[r._length-1][0],r.v[r._length-1][1],"o",r._length-1)),u>e.e)break;i<m-1&&(r=shapePool.newElement(),y=!0,d.push(r),o=0)}return d},extendPrototype([ShapeModifier],PuckerAndBloatModifier),PuckerAndBloatModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},PuckerAndBloatModifier.prototype.processPath=function(t,e){var r=e/100,i=[0,0],s=t._length,a=0;for(a=0;a<s;a+=1)i[0]+=t.v[a][0],i[1]+=t.v[a][1];i[0]/=s,i[1]/=s;var n,o,h,l,p,f,c=shapePool.newElement();for(c.c=t.c,a=0;a<s;a+=1)n=t.v[a][0]+(i[0]-t.v[a][0])*r,o=t.v[a][1]+(i[1]-t.v[a][1])*r,h=t.o[a][0]+(i[0]-t.o[a][0])*-r,l=t.o[a][1]+(i[1]-t.o[a][1])*-r,p=t.i[a][0]+(i[0]-t.i[a][0])*-r,f=t.i[a][1]+(i[1]-t.i[a][1])*-r,c.setTripleAt(n,o,h,l,p,f,a);return c},PuckerAndBloatModifier.prototype.processShapes=function(t){var e,r,i,s,a,n,o=this.shapes.length,h=this.amount.v;if(0!==h)for(r=0;r<o;r+=1){if(n=(a=this.shapes[r]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,i=0;i<s;i+=1)n.addShape(this.processPath(e[i],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var TransformPropertyFactory=function(){var t=[0,0];function e(t,e,r){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Matrix,this.pre=new Matrix,this.appliedTransformations=0,this.initDynamicPropertyContainer(r||t),e.p&&e.p.s?(this.px=PropertyFactory.getProp(t,e.p.x,0,0,this),this.py=PropertyFactory.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=PropertyFactory.getProp(t,e.p.z,0,0,this))):this.p=PropertyFactory.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=PropertyFactory.getProp(t,e.rx,0,degToRads,this),this.ry=PropertyFactory.getProp(t,e.ry,0,degToRads,this),this.rz=PropertyFactory.getProp(t,e.rz,0,degToRads,this),e.or.k[0].ti){var i,s=e.or.k.length;for(i=0;i<s;i+=1)e.or.k[i].to=null,e.or.k[i].ti=null}this.or=PropertyFactory.getProp(t,e.or,1,degToRads,this),this.or.sh=!0}else this.r=PropertyFactory.getProp(t,e.r||{k:0},0,degToRads,this);e.sk&&(this.sk=PropertyFactory.getProp(t,e.sk,0,degToRads,this),this.sa=PropertyFactory.getProp(t,e.sa,0,degToRads,this)),this.a=PropertyFactory.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=PropertyFactory.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=PropertyFactory.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return e.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(e){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||e){var r;if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var i,s;if(r=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime)this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(i=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/r,0),s=this.p.getValueAtTime(this.p.keyframes[0].t/r,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(i=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/r,0),s=this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/r,0)):(i=this.p.pv,s=this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/r,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){i=[],s=[];var a=this.px,n=this.py;a._caching.lastFrame+a.offsetTime<=a.keyframes[0].t?(i[0]=a.getValueAtTime((a.keyframes[0].t+.01)/r,0),i[1]=n.getValueAtTime((n.keyframes[0].t+.01)/r,0),s[0]=a.getValueAtTime(a.keyframes[0].t/r,0),s[1]=n.getValueAtTime(n.keyframes[0].t/r,0)):a._caching.lastFrame+a.offsetTime>=a.keyframes[a.keyframes.length-1].t?(i[0]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/r,0),i[1]=n.getValueAtTime(n.keyframes[n.keyframes.length-1].t/r,0),s[0]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/r,0),s[1]=n.getValueAtTime((n.keyframes[n.keyframes.length-1].t-.01)/r,0)):(i=[a.pv,n.pv],s[0]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/r,a.offsetTime),s[1]=n.getValueAtTime((n._caching.lastFrame+n.offsetTime-.01)/r,n.offsetTime))}else i=s=t;this.v.rotate(-Math.atan2(i[1]-s[1],i[0]-s[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],e),e.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},e.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,r,i){return new e(t,r,i)}}}();function RepeaterModifier(){}function RoundCornersModifier(){}function floatEqual(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function floatZero(t){return Math.abs(t)<=1e-5}function lerp(t,e,r){return t*(1-r)+e*r}function lerpPoint(t,e,r){return[lerp(t[0],e[0],r),lerp(t[1],e[1],r)]}function quadRoots(t,e,r){if(0===t)return[];var i=e*e-4*t*r;if(i<0)return[];var s=-e/(2*t);if(0===i)return[s];var a=Math.sqrt(i)/(2*t);return[s-a,s+a]}function polynomialCoefficients(t,e,r,i){return[3*e-t-3*r+i,3*t-6*e+3*r,-3*t+3*e,t]}function singlePoint(t){return new PolynomialBezier(t,t,t,t,!1)}function PolynomialBezier(t,e,r,i,s){s&&pointEqual(t,e)&&(e=lerpPoint(t,i,1/3)),s&&pointEqual(r,i)&&(r=lerpPoint(t,i,2/3));var a=polynomialCoefficients(t[0],e[0],r[0],i[0]),n=polynomialCoefficients(t[1],e[1],r[1],i[1]);this.a=[a[0],n[0]],this.b=[a[1],n[1]],this.c=[a[2],n[2]],this.d=[a[3],n[3]],this.points=[t,e,r,i]}function extrema(t,e){var r=t.points[0][e],i=t.points[t.points.length-1][e];if(r>i){var s=i;i=r,r=s}for(var a=quadRoots(3*t.a[e],2*t.b[e],t.c[e]),n=0;n<a.length;n+=1)if(a[n]>0&&a[n]<1){var o=t.point(a[n])[e];o<r?r=o:o>i&&(i=o)}return{min:r,max:i}}function intersectData(t,e,r){var i=t.boundingBox();return{cx:i.cx,cy:i.cy,width:i.width,height:i.height,bez:t,t:(e+r)/2,t1:e,t2:r}}function splitData(t){var e=t.bez.split(.5);return[intersectData(e[0],t.t1,t.t),intersectData(e[1],t.t,t.t2)]}function boxIntersect(t,e){return 2*Math.abs(t.cx-e.cx)<t.width+e.width&&2*Math.abs(t.cy-e.cy)<t.height+e.height}function intersectsImpl(t,e,r,i,s,a){if(boxIntersect(t,e))if(r>=a||t.width<=i&&t.height<=i&&e.width<=i&&e.height<=i)s.push([t.t,e.t]);else{var n=splitData(t),o=splitData(e);intersectsImpl(n[0],o[0],r+1,i,s,a),intersectsImpl(n[0],o[1],r+1,i,s,a),intersectsImpl(n[1],o[0],r+1,i,s,a),intersectsImpl(n[1],o[1],r+1,i,s,a)}}function crossProduct(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function lineIntersection(t,e,r,i){var s=[t[0],t[1],1],a=[e[0],e[1],1],n=[r[0],r[1],1],o=[i[0],i[1],1],h=crossProduct(crossProduct(s,a),crossProduct(n,o));return floatZero(h[2])?null:[h[0]/h[2],h[1]/h[2]]}function polarOffset(t,e,r){return[t[0]+Math.cos(e)*r,t[1]-Math.sin(e)*r]}function pointDistance(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function pointEqual(t,e){return floatEqual(t[0],e[0])&&floatEqual(t[1],e[1])}function ZigZagModifier(){}function setPoint(t,e,r,i,s,a,n){var o=r-Math.PI/2,h=r+Math.PI/2,l=e[0]+Math.cos(r)*i*s,p=e[1]-Math.sin(r)*i*s;t.setTripleAt(l,p,l+Math.cos(o)*a,p-Math.sin(o)*a,l+Math.cos(h)*n,p-Math.sin(h)*n,t.length())}function getPerpendicularVector(t,e){var r=[e[0]-t[0],e[1]-t[1]],i=.5*-Math.PI;return[Math.cos(i)*r[0]-Math.sin(i)*r[1],Math.sin(i)*r[0]+Math.cos(i)*r[1]]}function getProjectingAngle(t,e){var r=0===e?t.length()-1:e-1,i=(e+1)%t.length(),s=getPerpendicularVector(t.v[r],t.v[i]);return Math.atan2(0,1)-Math.atan2(s[1],s[0])}function zigZagCorner(t,e,r,i,s,a,n){var o=getProjectingAngle(e,r),h=e.v[r%e._length],l=e.v[0===r?e._length-1:r-1],p=e.v[(r+1)%e._length],f=2===a?Math.sqrt(Math.pow(h[0]-l[0],2)+Math.pow(h[1]-l[1],2)):0,c=2===a?Math.sqrt(Math.pow(h[0]-p[0],2)+Math.pow(h[1]-p[1],2)):0;setPoint(t,e.v[r%e._length],o,n,i,c/(2*(s+1)),f/(2*(s+1)),a)}function zigZagSegment(t,e,r,i,s,a){for(var n=0;n<i;n+=1){var o=(n+1)/(i+1),h=2===s?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(o);setPoint(t,e.point(o),l,a,r,h/(2*(i+1)),h/(2*(i+1)),s),a=-a}return a}function linearOffset(t,e,r){var i=Math.atan2(e[0]-t[0],e[1]-t[1]);return[polarOffset(t,i,r),polarOffset(e,i,r)]}function offsetSegment(t,e){var r,i,s,a,n,o,h;r=(h=linearOffset(t.points[0],t.points[1],e))[0],i=h[1],s=(h=linearOffset(t.points[1],t.points[2],e))[0],a=h[1],n=(h=linearOffset(t.points[2],t.points[3],e))[0],o=h[1];var l=lineIntersection(r,i,s,a);null===l&&(l=i);var p=lineIntersection(n,o,s,a);return null===p&&(p=n),new PolynomialBezier(r,l,p,o)}function joinLines(t,e,r,i,s){var a=e.points[3],n=r.points[0];if(3===i)return a;if(pointEqual(a,n))return a;if(2===i){var o=-e.tangentAngle(1),h=-r.tangentAngle(0)+Math.PI,l=lineIntersection(a,polarOffset(a,o+Math.PI/2,100),n,polarOffset(n,o+Math.PI/2,100)),p=l?pointDistance(l,a):pointDistance(a,n)/2,f=polarOffset(a,o,2*p*roundCorner);return t.setXYAt(f[0],f[1],"o",t.length()-1),f=polarOffset(n,h,2*p*roundCorner),t.setTripleAt(n[0],n[1],n[0],n[1],f[0],f[1],t.length()),n}var c=lineIntersection(pointEqual(a,e.points[2])?e.points[0]:e.points[2],a,n,pointEqual(n,r.points[1])?r.points[3]:r.points[1]);return c&&pointDistance(c,a)<s?(t.setTripleAt(c[0],c[1],c[0],c[1],c[0],c[1],t.length()),c):a}function getIntersection(t,e){var r=t.intersections(e);return r.length&&floatEqual(r[0][0],1)&&r.shift(),r.length?r[0]:null}function pruneSegmentIntersection(t,e){var r=t.slice(),i=e.slice(),s=getIntersection(t[t.length-1],e[0]);return s&&(r[t.length-1]=t[t.length-1].split(s[0])[0],i[0]=e[0].split(s[1])[1]),t.length>1&&e.length>1&&(s=getIntersection(t[0],e[e.length-1]))?[[t[0].split(s[0])[0]],[e[e.length-1].split(s[1])[1]]]:[r,i]}function pruneIntersections(t){for(var e,r=1;r<t.length;r+=1)e=pruneSegmentIntersection(t[r-1],t[r]),t[r-1]=e[0],t[r]=e[1];return t.length>1&&(e=pruneSegmentIntersection(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}function offsetSegmentSplit(t,e){var r,i,s,a,n=t.inflectionPoints();if(0===n.length)return[offsetSegment(t,e)];if(1===n.length||floatEqual(n[1],1))return r=(s=t.split(n[0]))[0],i=s[1],[offsetSegment(r,e),offsetSegment(i,e)];r=(s=t.split(n[0]))[0];var o=(n[1]-n[0])/(1-n[0]);return a=(s=s[1].split(o))[0],i=s[1],[offsetSegment(r,e),offsetSegment(a,e),offsetSegment(i,e)]}function OffsetPathModifier(){}function getFontProperties(t){for(var e=t.fStyle?t.fStyle.split(" "):[],r="normal",i="normal",s=e.length,a=0;a<s;a+=1)switch(e[a].toLowerCase()){case"italic":i="italic";break;case"bold":r="700";break;case"black":r="900";break;case"medium":r="500";break;case"regular":case"normal":r="400";break;case"light":case"thin":r="200"}return{style:i,weight:t.fWeight||r}}extendPrototype([ShapeModifier],RepeaterModifier),RepeaterModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=PropertyFactory.getProp(t,e.c,0,null,this),this.o=PropertyFactory.getProp(t,e.o,0,null,this),this.tr=TransformPropertyFactory.getTransformProperty(t,e.tr,this),this.so=PropertyFactory.getProp(t,e.tr.so,0,.01,this),this.eo=PropertyFactory.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Matrix,this.rMatrix=new Matrix,this.sMatrix=new Matrix,this.tMatrix=new Matrix,this.matrix=new Matrix},RepeaterModifier.prototype.applyTransforms=function(t,e,r,i,s,a){var n=a?-1:1,o=i.s.v[0]+(1-i.s.v[0])*(1-s),h=i.s.v[1]+(1-i.s.v[1])*(1-s);t.translate(i.p.v[0]*n*s,i.p.v[1]*n*s,i.p.v[2]),e.translate(-i.a.v[0],-i.a.v[1],i.a.v[2]),e.rotate(-i.r.v*n*s),e.translate(i.a.v[0],i.a.v[1],i.a.v[2]),r.translate(-i.a.v[0],-i.a.v[1],i.a.v[2]),r.scale(a?1/o:o,a?1/h:h),r.translate(i.a.v[0],i.a.v[1],i.a.v[2])},RepeaterModifier.prototype.init=function(t,e,r,i){for(this.elem=t,this.arr=e,this.pos=r,this.elemsData=i,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[r]);r>0;)r-=1,this._elements.unshift(e[r]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){var e,r=t.length;for(e=0;e<r;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},RepeaterModifier.prototype.cloneElements=function(t){var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},RepeaterModifier.prototype.changeGroupRender=function(t,e){var r,i=t.length;for(r=0;r<i;r+=1)t[r]._render=e,"gr"===t[r].ty&&this.changeGroupRender(t[r].it,e)},RepeaterModifier.prototype.processShapes=function(t){var e,r,i,s,a,n=!1;if(this._mdf||t){var o,h=Math.ceil(this.c.v);if(this._groups.length<h){for(;this._groups.length<h;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(a=0,i=0;i<=this._groups.length-1;i+=1){if(o=a<h,this._groups[i]._render=o,this.changeGroupRender(this._groups[i].it,o),!o){var p=this.elemsData[i].it,f=p[p.length-1];0!==f.transform.op.v?(f.transform.op._mdf=!0,f.transform.op.v=0):f.transform.op._mdf=!1}a+=1}this._currentCopies=h;var c=this.o.v,m=c%1,u=c>0?Math.floor(c):Math.ceil(c),d=this.pMatrix.props,y=this.rMatrix.props,g=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var v,b,P=0;if(c>0){for(;P<u;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),P+=1;m&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,m,!1),P+=m)}else if(c<0){for(;P>u;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),P-=1;m&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-m,!0),P-=m)}for(i=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(b=(r=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(i/(this._currentCopies-1)),0!==P){for((0!==i&&1===s||i!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]),this.matrix.transform(d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9],d[10],d[11],d[12],d[13],d[14],d[15]),v=0;v<b;v+=1)r[v]=this.matrix.props[v];this.matrix.reset()}else for(this.matrix.reset(),v=0;v<b;v+=1)r[v]=this.matrix.props[v];P+=1,a-=1,i+=s}}else for(a=this._currentCopies,i=0,s=1;a;)r=(e=this.elemsData[i].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,a-=1,i+=s;return n},RepeaterModifier.prototype.addShape=function(){},extendPrototype([ShapeModifier],RoundCornersModifier),RoundCornersModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=PropertyFactory.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},RoundCornersModifier.prototype.processPath=function(t,e){var r,i=shapePool.newElement();i.c=t.c;var s,a,n,o,h,l,p,f,c,m,u,d,y=t._length,g=0;for(r=0;r<y;r+=1)s=t.v[r],n=t.o[r],a=t.i[r],s[0]===n[0]&&s[1]===n[1]&&s[0]===a[0]&&s[1]===a[1]?0!==r&&r!==y-1||t.c?(o=0===r?t.v[y-1]:t.v[r-1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=u=s[0]+(o[0]-s[0])*l,f=d=s[1]-(s[1]-o[1])*l,c=p-(p-s[0])*roundCorner,m=f-(f-s[1])*roundCorner,i.setTripleAt(p,f,c,m,u,d,g),g+=1,o=r===y-1?t.v[0]:t.v[r+1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=c=s[0]+(o[0]-s[0])*l,f=m=s[1]+(o[1]-s[1])*l,u=p-(p-s[0])*roundCorner,d=f-(f-s[1])*roundCorner,i.setTripleAt(p,f,c,m,u,d,g),g+=1):(i.setTripleAt(s[0],s[1],n[0],n[1],a[0],a[1],g),g+=1):(i.setTripleAt(t.v[r][0],t.v[r][1],t.o[r][0],t.o[r][1],t.i[r][0],t.i[r][1],g),g+=1);return i},RoundCornersModifier.prototype.processShapes=function(t){var e,r,i,s,a,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(r=0;r<o;r+=1){if(n=(a=this.shapes[r]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,i=0;i<s;i+=1)n.addShape(this.processPath(e[i],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},PolynomialBezier.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},PolynomialBezier.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},PolynomialBezier.prototype.tangentAngle=function(t){var e=this.derivative(t);return Math.atan2(e[1],e[0])},PolynomialBezier.prototype.normalAngle=function(t){var e=this.derivative(t);return Math.atan2(e[0],e[1])},PolynomialBezier.prototype.inflectionPoints=function(){var t=this.a[1]*this.b[0]-this.a[0]*this.b[1];if(floatZero(t))return[];var e=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/t,r=e*e-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/t;if(r<0)return[];var i=Math.sqrt(r);return floatZero(i)?i>0&&i<1?[e]:[]:[e-i,e+i].filter((function(t){return t>0&&t<1}))},PolynomialBezier.prototype.split=function(t){if(t<=0)return[singlePoint(this.points[0]),this];if(t>=1)return[this,singlePoint(this.points[this.points.length-1])];var e=lerpPoint(this.points[0],this.points[1],t),r=lerpPoint(this.points[1],this.points[2],t),i=lerpPoint(this.points[2],this.points[3],t),s=lerpPoint(e,r,t),a=lerpPoint(r,i,t),n=lerpPoint(s,a,t);return[new PolynomialBezier(this.points[0],e,s,n,!0),new PolynomialBezier(n,a,i,this.points[3],!0)]},PolynomialBezier.prototype.bounds=function(){return{x:extrema(this,0),y:extrema(this,1)}},PolynomialBezier.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},PolynomialBezier.prototype.intersections=function(t,e,r){void 0===e&&(e=2),void 0===r&&(r=7);var i=[];return intersectsImpl(intersectData(this,0,1),intersectData(t,0,1),0,e,i,r),i},PolynomialBezier.shapeSegment=function(t,e){var r=(e+1)%t.length();return new PolynomialBezier(t.v[e],t.o[e],t.i[r],t.v[r],!0)},PolynomialBezier.shapeSegmentInverted=function(t,e){var r=(e+1)%t.length();return new PolynomialBezier(t.v[r],t.i[r],t.o[e],t.v[e],!0)},extendPrototype([ShapeModifier],ZigZagModifier),ZigZagModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=PropertyFactory.getProp(t,e.s,0,null,this),this.frequency=PropertyFactory.getProp(t,e.r,0,null,this),this.pointsType=PropertyFactory.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},ZigZagModifier.prototype.processPath=function(t,e,r,i){var s=t._length,a=shapePool.newElement();if(a.c=t.c,t.c||(s-=1),0===s)return a;var n=-1,o=PolynomialBezier.shapeSegment(t,0);zigZagCorner(a,t,0,e,r,i,n);for(var h=0;h<s;h+=1)n=zigZagSegment(a,o,e,r,i,-n),o=h!==s-1||t.c?PolynomialBezier.shapeSegment(t,(h+1)%s):null,zigZagCorner(a,t,h+1,e,r,i,n);return a},ZigZagModifier.prototype.processShapes=function(t){var e,r,i,s,a,n,o=this.shapes.length,h=this.amplitude.v,l=Math.max(0,Math.round(this.frequency.v)),p=this.pointsType.v;if(0!==h)for(r=0;r<o;r+=1){if(n=(a=this.shapes[r]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,i=0;i<s;i+=1)n.addShape(this.processPath(e[i],h,l,p));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},extendPrototype([ShapeModifier],OffsetPathModifier),OffsetPathModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this.miterLimit=PropertyFactory.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},OffsetPathModifier.prototype.processPath=function(t,e,r,i){var s=shapePool.newElement();s.c=t.c;var a,n,o,h=t.length();t.c||(h-=1);var l=[];for(a=0;a<h;a+=1)o=PolynomialBezier.shapeSegment(t,a),l.push(offsetSegmentSplit(o,e));if(!t.c)for(a=h-1;a>=0;a-=1)o=PolynomialBezier.shapeSegmentInverted(t,a),l.push(offsetSegmentSplit(o,e));l=pruneIntersections(l);var p=null,f=null;for(a=0;a<l.length;a+=1){var c=l[a];for(f&&(p=joinLines(s,f,c[0],r,i)),f=c[c.length-1],n=0;n<c.length;n+=1)o=c[n],p&&pointEqual(o.points[0],p)?s.setXYAt(o.points[1][0],o.points[1][1],"o",s.length()-1):s.setTripleAt(o.points[0][0],o.points[0][1],o.points[1][0],o.points[1][1],o.points[0][0],o.points[0][1],s.length()),s.setTripleAt(o.points[3][0],o.points[3][1],o.points[3][0],o.points[3][1],o.points[2][0],o.points[2][1],s.length()),p=o.points[3]}return l.length&&joinLines(s,f,l[0][0],r,i),s},OffsetPathModifier.prototype.processShapes=function(t){var e,r,i,s,a,n,o=this.shapes.length,h=this.amount.v,l=this.miterLimit.v,p=this.lineJoin;if(0!==h)for(r=0;r<o;r+=1){if(n=(a=this.shapes[r]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,i=0;i<s;i+=1)n.addShape(this.processPath(e[i],h,p,l));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var FontManager=function(){var t={w:0,size:0,shapes:[],data:{shapes:[]}},e=[];e=e.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);var r=127988,i=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function s(t,e){var r=createTag("span");r.setAttribute("aria-hidden",!0),r.style.fontFamily=e;var i=createTag("span");i.innerText="giItT1WQy@!-/#",r.style.position="absolute",r.style.left="-10000px",r.style.top="-10000px",r.style.fontSize="300px",r.style.fontVariant="normal",r.style.fontStyle="normal",r.style.fontWeight="normal",r.style.letterSpacing="0",r.appendChild(i),document.body.appendChild(r);var s=i.offsetWidth;return i.style.fontFamily=function(t){var e,r=t.split(","),i=r.length,s=[];for(e=0;e<i;e+=1)"sans-serif"!==r[e]&&"monospace"!==r[e]&&s.push(r[e]);return s.join(",")}(t)+", "+e,{node:i,w:s,parent:r}}function a(t,e){var r,i=document.body&&e?"svg":"canvas",s=getFontProperties(t);if("svg"===i){var a=createNS("text");a.style.fontSize="100px",a.setAttribute("font-family",t.fFamily),a.setAttribute("font-style",s.style),a.setAttribute("font-weight",s.weight),a.textContent="1",t.fClass?(a.style.fontFamily="inherit",a.setAttribute("class",t.fClass)):a.style.fontFamily=t.fFamily,e.appendChild(a),r=a}else{var n=new OffscreenCanvas(500,500).getContext("2d");n.font=s.style+" "+s.weight+" 100px "+t.fFamily,r=n}return{measureText:function(t){return"svg"===i?(r.textContent=t,r.getComputedTextLength()):r.measureText(t).width}}}function n(t){var e=0,r=t.charCodeAt(0);if(r>=55296&&r<=56319){var i=t.charCodeAt(1);i>=56320&&i<=57343&&(e=1024*(r-55296)+i-56320+65536)}return e}function o(t){var e=n(t);return e>=127462&&e<=127487}var h=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)};h.isModifier=function(t,e){var r=t.toString(16)+e.toString(16);return-1!==i.indexOf(r)},h.isZeroWidthJoiner=function(t){return 8205===t},h.isFlagEmoji=function(t){return o(t.substr(0,2))&&o(t.substr(2,2))},h.isRegionalCode=o,h.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},h.isRegionalFlag=function(t,e){var i=n(t.substr(e,2));if(i!==r)return!1;var s=0;for(e+=2;s<5;){if((i=n(t.substr(e,2)))<917601||i>917626)return!1;s+=1,e+=2}return 917631===n(t.substr(e,2))},h.isVariationSelector=function(t){return 65039===t},h.BLACK_FLAG_CODE_POINT=r;var l={addChars:function(t){if(t){var e;this.chars||(this.chars=[]);var r,i,s=t.length,a=this.chars.length;for(e=0;e<s;e+=1){for(r=0,i=!1;r<a;)this.chars[r].style===t[e].style&&this.chars[r].fFamily===t[e].fFamily&&this.chars[r].ch===t[e].ch&&(i=!0),r+=1;i||(this.chars.push(t[e]),a+=1)}}},addFonts:function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);if(!document.body)return this.isLoaded=!0,t.list.forEach((function(t){t.helper=a(t),t.cache={}})),void(this.fonts=t.list);var r,i=t.list,n=i.length,o=n;for(r=0;r<n;r+=1){var h,l,p=!0;if(i[r].loaded=!1,i[r].monoCase=s(i[r].fFamily,"monospace"),i[r].sansCase=s(i[r].fFamily,"sans-serif"),i[r].fPath){if("p"===i[r].fOrigin||3===i[r].origin){if((h=document.querySelectorAll('style[f-forigin="p"][f-family="'+i[r].fFamily+'"], style[f-origin="3"][f-family="'+i[r].fFamily+'"]')).length>0&&(p=!1),p){var f=createTag("style");f.setAttribute("f-forigin",i[r].fOrigin),f.setAttribute("f-origin",i[r].origin),f.setAttribute("f-family",i[r].fFamily),f.type="text/css",f.innerText="@font-face {font-family: "+i[r].fFamily+"; font-style: normal; src: url('"+i[r].fPath+"');}",e.appendChild(f)}}else if("g"===i[r].fOrigin||1===i[r].origin){for(h=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),l=0;l<h.length;l+=1)-1!==h[l].href.indexOf(i[r].fPath)&&(p=!1);if(p){var c=createTag("link");c.setAttribute("f-forigin",i[r].fOrigin),c.setAttribute("f-origin",i[r].origin),c.type="text/css",c.rel="stylesheet",c.href=i[r].fPath,document.body.appendChild(c)}}else if("t"===i[r].fOrigin||2===i[r].origin){for(h=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),l=0;l<h.length;l+=1)i[r].fPath===h[l].src&&(p=!1);if(p){var m=createTag("link");m.setAttribute("f-forigin",i[r].fOrigin),m.setAttribute("f-origin",i[r].origin),m.setAttribute("rel","stylesheet"),m.setAttribute("href",i[r].fPath),e.appendChild(m)}}}else i[r].loaded=!0,o-=1;i[r].helper=a(i[r],e),i[r].cache={},this.fonts.push(i[r])}0===o?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},getCharData:function(e,r,i){for(var s=0,a=this.chars.length;s<a;){if(this.chars[s].ch===e&&this.chars[s].style===r&&this.chars[s].fFamily===i)return this.chars[s];s+=1}return("string"==typeof e&&13!==e.charCodeAt(0)||!e)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",e,r,i)),t},getFontByName:function(t){for(var e=0,r=this.fonts.length;e<r;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,r){var i=this.getFontByName(e),s=t;if(!i.cache[s]){var a=i.helper;if(" "===t){var n=a.measureText("|"+t+"|"),o=a.measureText("||");i.cache[s]=(n-o)/100}else i.cache[s]=a.measureText(t)/100}return i.cache[s]*r},checkLoadedFonts:function(){var t,e,r,i=this.fonts.length,s=i;for(t=0;t<i;t+=1)this.fonts[t].loaded?s-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,r=this.fonts[t].monoCase.w,e.offsetWidth!==r?(s-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,r=this.fonts[t].sansCase.w,e.offsetWidth!==r&&(s-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==s&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}};return h.prototype=l,h}();function SlotManager(t){this.animationData=t}function slotFactory(t){return new SlotManager(t)}function RenderableElement(){}SlotManager.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},RenderableElement.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var getBlendMode=(blendModeEnums={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return blendModeEnums[t]||""}),blendModeEnums;function SliderEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function AngleEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function ColorEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,1,0,r)}function PointEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,1,0,r)}function LayerIndexEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function MaskIndexEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function CheckboxEffect(t,e,r){this.p=PropertyFactory.getProp(e,t.v,0,0,r)}function NoValueEffect(){this.p={}}function EffectsManager(t,e){var r,i=t.ef||[];this.effectElements=[];var s,a=i.length;for(r=0;r<a;r+=1)s=new GroupEffect(i[r],e),this.effectElements.push(s)}function GroupEffect(t,e){this.init(t,e)}function BaseElement(){}function FrameElement(){}function FootageElement(t,e,r){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,r)}function AudioElement(t,e,r){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,r),this._isPlaying=!1,this._canPlay=!1;var i=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(i),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=PropertyFactory.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function BaseRenderer(){}extendPrototype([DynamicPropertyContainer],GroupEffect),GroupEffect.prototype.getValue=GroupEffect.prototype.iterateDynamicProperties,GroupEffect.prototype.init=function(t,e){var r;this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var i,s=this.data.ef.length,a=this.data.ef;for(r=0;r<s;r+=1){switch(i=null,a[r].ty){case 0:i=new SliderEffect(a[r],e,this);break;case 1:i=new AngleEffect(a[r],e,this);break;case 2:i=new ColorEffect(a[r],e,this);break;case 3:i=new PointEffect(a[r],e,this);break;case 4:case 7:i=new CheckboxEffect(a[r],e,this);break;case 10:i=new LayerIndexEffect(a[r],e,this);break;case 11:i=new MaskIndexEffect(a[r],e,this);break;case 5:i=new EffectsManager(a[r],e,this);break;default:i=new NoValueEffect(a[r],e,this)}i&&this.effectElements.push(i)}},BaseElement.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t=getExpressionInterfaces();if(t){var e=t("layer"),r=t("effects"),i=t("shape"),s=t("text"),a=t("comp");this.layerInterface=e(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var n=r.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(n),0===this.data.ty||this.data.xt?this.compInterface=a(this):4===this.data.ty?(this.layerInterface.shapeInterface=i(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=s(this),this.layerInterface.text=this.layerInterface.textInterface)}},setBlendMode:function(){var t=getBlendMode(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,r){this.globalData=e,this.comp=r,this.data=t,this.layerId=createElementID(),this.data.sr||(this.data.sr=1),this.effectsManager=new EffectsManager(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},FrameElement.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var r,i=this.dynamicProperties.length;for(r=0;r<i;r+=1)(e||this._isParent&&"transform"===this.dynamicProperties[r].propType)&&(this.dynamicProperties[r].getValue(),this.dynamicProperties[r]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},FootageElement.prototype.prepareFrame=function(){},extendPrototype([RenderableElement,BaseElement,FrameElement],FootageElement),FootageElement.prototype.getBaseElement=function(){return null},FootageElement.prototype.renderFrame=function(){},FootageElement.prototype.destroy=function(){},FootageElement.prototype.initExpressions=function(){var t=getExpressionInterfaces();if(t){var e=t("footage");this.layerInterface=e(this)}},FootageElement.prototype.getFootageData=function(){return this.footageData},AudioElement.prototype.prepareFrame=function(t){if(this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder)this._currentTime=t/this.data.sr;else{var e=this.tm.v;this._currentTime=e}this._volume=this.lv.v[0];var r=this._volume*this._volumeMultiplier;this._previousVolume!==r&&(this._previousVolume=r,this.audio.volume(r))},extendPrototype([RenderableElement,BaseElement,FrameElement],AudioElement),AudioElement.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek())>.1)&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},AudioElement.prototype.show=function(){},AudioElement.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},AudioElement.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},AudioElement.prototype.resume=function(){this._canPlay=!0},AudioElement.prototype.setRate=function(t){this.audio.rate(t)},AudioElement.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},AudioElement.prototype.getBaseElement=function(){return null},AudioElement.prototype.destroy=function(){},AudioElement.prototype.sourceRectAtTime=function(){},AudioElement.prototype.initExpressions=function(){},BaseRenderer.prototype.checkLayers=function(t){var e,r,i=this.layers.length;for(this.completeLayers=!0,e=i-1;e>=0;e-=1)this.elements[e]||(r=this.layers[e]).ip-r.st<=t-this.layers[e].st&&r.op-r.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:default:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t)}},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.createAudio=function(t){return new AudioElement(t,this.globalData,this)},BaseRenderer.prototype.createFootage=function(t){return new FootageElement(t,this.globalData,this)},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},BaseRenderer.prototype.includeLayers=function(t){var e;this.completeLayers=!1;var r,i=t.length,s=this.layers.length;for(e=0;e<i;e+=1)for(r=0;r<s;){if(this.layers[r].id===t[e].id){this.layers[r]=t[e];break}r+=1}},BaseRenderer.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},BaseRenderer.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},BaseRenderer.prototype.buildElementParenting=function(t,e,r){for(var i=this.elements,s=this.layers,a=0,n=s.length;a<n;)s[a].ind==e&&(i[a]&&!0!==i[a]?(r.push(i[a]),i[a].setAsParent(),void 0!==s[a].parent?this.buildElementParenting(t,s[a].parent,r):t.setHierarchy(r)):(this.buildItem(a),this.addPendingElement(t))),a+=1},BaseRenderer.prototype.addPendingElement=function(t){this.pendingElements.push(t)},BaseRenderer.prototype.searchExtraCompositions=function(t){var e,r=t.length;for(e=0;e<r;e+=1)if(t[e].xt){var i=this.createComp(t[e]);i.initExpressions(),this.globalData.projectInterface.registerComposition(i)}},BaseRenderer.prototype.getElementById=function(t){var e,r=this.elements.length;for(e=0;e<r;e+=1)if(this.elements[e].data.ind===t)return this.elements[e];return null},BaseRenderer.prototype.getElementByPath=function(t){var e,r=t.shift();if("number"==typeof r)e=this.elements[r];else{var i,s=this.elements.length;for(i=0;i<s;i+=1)if(this.elements[i].data.nm===r){e=this.elements[i];break}}return 0===t.length?e:e.getElementByPath(t)},BaseRenderer.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new FontManager,this.globalData.slotManager=slotFactory(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var effectTypes={TRANSFORM_EFFECT:"transformEFfect"};function TransformElement(){}function MaskElement(t,e,r){this.data=t,this.element=e,this.globalData=r,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var i,s,a=this.globalData.defs,n=this.masksProperties?this.masksProperties.length:0;this.viewData=createSizedArray(n),this.solidPath="";var o,h,l,p,f,c,m=this.masksProperties,u=0,d=[],y=createElementID(),g="clipPath",v="clip-path";for(i=0;i<n;i+=1)if(("a"!==m[i].mode&&"n"!==m[i].mode||m[i].inv||100!==m[i].o.k||m[i].o.x)&&(g="mask",v="mask"),"s"!==m[i].mode&&"i"!==m[i].mode||0!==u?l=null:((l=createNS("rect")).setAttribute("fill","#ffffff"),l.setAttribute("width",this.element.comp.data.w||0),l.setAttribute("height",this.element.comp.data.h||0),d.push(l)),s=createNS("path"),"n"===m[i].mode)this.viewData[i]={op:PropertyFactory.getProp(this.element,m[i].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,m[i],3),elem:s,lastPath:""},a.appendChild(s);else{var b;if(u+=1,s.setAttribute("fill","s"===m[i].mode?"#000000":"#ffffff"),s.setAttribute("clip-rule","nonzero"),0!==m[i].x.k?(g="mask",v="mask",c=PropertyFactory.getProp(this.element,m[i].x,0,null,this.element),b=createElementID(),(p=createNS("filter")).setAttribute("id",b),(f=createNS("feMorphology")).setAttribute("operator","erode"),f.setAttribute("in","SourceGraphic"),f.setAttribute("radius","0"),p.appendChild(f),a.appendChild(p),s.setAttribute("stroke","s"===m[i].mode?"#000000":"#ffffff")):(f=null,c=null),this.storedData[i]={elem:s,x:c,expan:f,lastPath:"",lastOperator:"",filterId:b,lastRadius:0},"i"===m[i].mode){h=d.length;var P=createNS("g");for(o=0;o<h;o+=1)P.appendChild(d[o]);var S=createNS("mask");S.setAttribute("mask-type","alpha"),S.setAttribute("id",y+"_"+u),S.appendChild(s),a.appendChild(S),P.setAttribute("mask","url("+getLocationHref()+"#"+y+"_"+u+")"),d.length=0,d.push(P)}else d.push(s);m[i].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[i]={elem:s,lastPath:"",op:PropertyFactory.getProp(this.element,m[i].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,m[i],3),invRect:l},this.viewData[i].prop.k||this.drawPath(m[i],this.viewData[i].prop.v,this.viewData[i])}for(this.maskElement=createNS(g),n=d.length,i=0;i<n;i+=1)this.maskElement.appendChild(d[i]);u>0&&(this.maskElement.setAttribute("id",y),this.element.maskedElement.setAttribute(v,"url("+getLocationHref()+"#"+y+")"),a.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}TransformElement.prototype={initTransform:function(){var t=new Matrix;this.finalTransform={mProp:this.data.ks?TransformPropertyFactory.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,r=0,i=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;r<i;){if(this.hierarchy[r].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}r+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),r=0;r<i;r+=1)e.multiply(this.hierarchy[r].finalTransform.mProp.v)}this.localTransforms&&!this.finalTransform._matMdf||(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var r=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(r),t=1;t<e;t+=1){var i=this.localTransforms[t].matrix;r.multiply(i)}r.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){var s=this.finalTransform.localOpacity;for(t=0;t<e;t+=1)s*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=s}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new Matrix;var e=0,r=t.length;for(e=0;e<r;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var r,i=!0,s=this.comp;i;)s.finalTransform?(s.data.hasMask&&e.splice(0,0,s.finalTransform),s=s.comp):i=!1;var a,n=e.length;for(r=0;r<n;r+=1)a=e[r].mat.applyToPointArray(0,0,0),t=[t[0]-a[0],t[1]-a[1],0];return t},mHelper:new Matrix},MaskElement.prototype.getMaskProperty=function(t){return this.viewData[t].prop},MaskElement.prototype.renderFrame=function(t){var e,r=this.element.finalTransform.mat,i=this.masksProperties.length;for(e=0;e<i;e+=1)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[e].invRect.setAttribute("transform",r.getInverseMatrix().to2dCSS()),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var s=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+getLocationHref()+"#"+this.storedData[e].filterId+")")),s.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},MaskElement.prototype.getMaskelement=function(){return this.maskElement},MaskElement.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},MaskElement.prototype.drawPath=function(t,e,r){var i,s,a=" M"+e.v[0][0]+","+e.v[0][1];for(s=e._length,i=1;i<s;i+=1)a+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[i][0]+","+e.i[i][1]+" "+e.v[i][0]+","+e.v[i][1];if(e.c&&s>1&&(a+=" C"+e.o[i-1][0]+","+e.o[i-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),r.lastPath!==a){var n="";r.elem&&(e.c&&(n=t.inv?this.solidPath+a:a),r.elem.setAttribute("d",n)),r.lastPath=a}},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var filtersFactory=function(){var t={};return t.createFilter=function(t,e){var r=createNS("filter");r.setAttribute("id",t),!0!==e&&(r.setAttribute("filterUnits","objectBoundingBox"),r.setAttribute("x","0%"),r.setAttribute("y","0%"),r.setAttribute("width","100%"),r.setAttribute("height","100%"));return r},t.createAlphaToLuminanceFilter=function(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},t}(),featureSupport=function(){var t={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),/firefox/i.test(navigator.userAgent)&&(t.svgLumaHidden=!1),t}(),registeredEffects={},idPrefix="filter_result_";function SVGEffects(t){var e,r,i="SourceGraphic",s=t.data.ef?t.data.ef.length:0,a=createElementID(),n=filtersFactory.createFilter(a,!0),o=0;for(this.filters=[],e=0;e<s;e+=1){r=null;var h=t.data.ef[e].ty;if(registeredEffects[h])r=new(0,registeredEffects[h].effect)(n,t.effectsManager.effectElements[e],t,idPrefix+o,i),i=idPrefix+o,registeredEffects[h].countsAsEffect&&(o+=1);r&&this.filters.push(r)}o&&(t.globalData.defs.appendChild(n),t.layerElement.setAttribute("filter","url("+getLocationHref()+"#"+a+")")),this.filters.length&&t.addRenderableComponent(this)}function registerEffect(t,e,r){registeredEffects[t]={effect:e,countsAsEffect:r}}function SVGBaseElement(){}function HierarchyElement(){}function RenderableDOMElement(){}function IImageElement(t,e,r){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,r),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ProcessedElement(t,e){this.elem=t,this.pos=e}function IShapeElement(){}SVGEffects.prototype.renderFrame=function(t){var e,r=this.filters.length;for(e=0;e<r;e+=1)this.filters[e].renderFrame(t)},SVGEffects.prototype.getEffects=function(t){var e,r=this.filters.length,i=[];for(e=0;e<r;e+=1)this.filters[e].type===t&&i.push(this.filters[e]);return i},SVGBaseElement.prototype={initRendererElement:function(){this.layerElement=createNS("g")},createContainerElements:function(){this.matteElement=createNS("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t=null;if(this.data.td){this.matteMasks={};var e=createNS("g");e.setAttribute("id",this.layerId),e.appendChild(this.layerElement),t=e,this.globalData.defs.appendChild(e)}else this.data.tt?(this.matteElement.appendChild(this.layerElement),t=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var r=createNS("clipPath"),i=createNS("path");i.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var s=createElementID();if(r.setAttribute("id",s),r.appendChild(i),this.globalData.defs.appendChild(r),this.checkMasks()){var a=createNS("g");a.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),a.appendChild(this.layerElement),this.transformedElement=a,t?t.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData),this.renderableEffectsManager=new SVGEffects(this),this.searchEffectTransforms()},getMatte:function(t){if(this.matteMasks||(this.matteMasks={}),!this.matteMasks[t]){var e,r,i,s,a=this.layerId+"_"+t;if(1===t||3===t){var n=createNS("mask");n.setAttribute("id",a),n.setAttribute("mask-type",3===t?"luminance":"alpha"),(i=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),n.appendChild(i),this.globalData.defs.appendChild(n),featureSupport.maskType||1!==t||(n.setAttribute("mask-type","luminance"),e=createElementID(),r=filtersFactory.createFilter(e),this.globalData.defs.appendChild(r),r.appendChild(filtersFactory.createAlphaToLuminanceFilter()),(s=createNS("g")).appendChild(i),n.appendChild(s),s.setAttribute("filter","url("+getLocationHref()+"#"+e+")"))}else if(2===t){var o=createNS("mask");o.setAttribute("id",a),o.setAttribute("mask-type","alpha");var h=createNS("g");o.appendChild(h),e=createElementID(),r=filtersFactory.createFilter(e);var l=createNS("feComponentTransfer");l.setAttribute("in","SourceGraphic"),r.appendChild(l);var p=createNS("feFuncA");p.setAttribute("type","table"),p.setAttribute("tableValues","1.0 0.0"),l.appendChild(p),this.globalData.defs.appendChild(r);var f=createNS("rect");f.setAttribute("width",this.comp.data.w),f.setAttribute("height",this.comp.data.h),f.setAttribute("x","0"),f.setAttribute("y","0"),f.setAttribute("fill","#ffffff"),f.setAttribute("opacity","0"),h.setAttribute("filter","url("+getLocationHref()+"#"+e+")"),h.appendChild(f),(i=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),h.appendChild(i),featureSupport.maskType||(o.setAttribute("mask-type","luminance"),r.appendChild(filtersFactory.createAlphaToLuminanceFilter()),s=createNS("g"),h.appendChild(f),s.appendChild(this.layerElement),h.appendChild(s)),this.globalData.defs.appendChild(o)}this.matteMasks[t]=a}return this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+getLocationHref()+"#"+t+")")}},HierarchyElement.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},extendPrototype([RenderableElement,createProxyFunction({initElement:function(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initTransform(t,e,r),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],RenderableDOMElement),extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],IImageElement),IImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=createNS("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},IImageElement.prototype.sourceRectAtTime=function(){return this.sourceRect},IShapeElement.prototype={addShapeToModifiers:function(t){var e,r=this.shapeModifiers.length;for(e=0;e<r;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;t>=0&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,r=0,i=e.length;r<i;){if(e[r].elem===t)return e[r].pos;r+=1}return 0},addProcessedElement:function(t,e){for(var r=this.processedElements,i=r.length;i;)if(r[i-=1].elem===t)return void(r[i].pos=e);r.push(new ProcessedElement(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var lineCapEnum={1:"butt",2:"round",3:"square"},lineJoinEnum={1:"miter",2:"round",3:"bevel"};function SVGShapeData(t,e,r){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=r,this.lvl=e,this._isAnimated=!!r.k;for(var i=0,s=t.length;i<s;){if(t[i].mProps.dynamicProperties.length){this._isAnimated=!0;break}i+=1}}function SVGStyleData(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=createNS("path"),this.msElem=null}function DashProperty(t,e,r,i){var s;this.elem=t,this.frameId=-1,this.dataProps=createSizedArray(e.length),this.renderer=r,this.k=!1,this.dashStr="",this.dashArray=createTypedArray("float32",e.length?e.length-1:0),this.dashoffset=createTypedArray("float32",1),this.initDynamicPropertyContainer(i);var a,n=e.length||0;for(s=0;s<n;s+=1)a=PropertyFactory.getProp(t,e[s].v,0,0,this),this.k=a.k||this.k,this.dataProps[s]={n:e[s].n,p:a};this.k||this.getValue(!0),this._isAnimated=this.k}function SVGStrokeStyleData(t,e,r){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=r,this._isAnimated=!!this._isAnimated}function SVGFillStyleData(t,e,r){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=r}function SVGNoStyleData(t,e,r){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=r}function GradientProperty(t,e,r){this.data=e,this.c=createTypedArray("uint8c",4*e.p);var i=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=createTypedArray("float32",i),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=i,this.initDynamicPropertyContainer(r),this.prop=PropertyFactory.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function SVGGradientFillStyleData(t,e,r){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,r)}function SVGGradientStrokeStyleData(t,e,r){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.initGradientData(t,e,r),this._isAnimated=!!this._isAnimated}function ShapeGroupData(){this.it=[],this.prevViewData=[],this.gr=createNS("g")}function SVGTransformData(t,e,r){this.transform={mProps:t,op:e,container:r},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}SVGShapeData.prototype.setAsAnimated=function(){this._isAnimated=!0},SVGStyleData.prototype.reset=function(){this.d="",this._mdf=!1},DashProperty.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,r=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<r;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},extendPrototype([DynamicPropertyContainer],DashProperty),extendPrototype([DynamicPropertyContainer],SVGStrokeStyleData),extendPrototype([DynamicPropertyContainer],SVGFillStyleData),extendPrototype([DynamicPropertyContainer],SVGNoStyleData),GradientProperty.prototype.comparePoints=function(t,e){for(var r=0,i=this.o.length/2;r<i;){if(Math.abs(t[4*r]-t[4*e+2*r])>.01)return!1;r+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},GradientProperty.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,r,i,s=4*this.data.p;for(e=0;e<s;e+=1)r=e%4==0?100:255,i=Math.round(this.prop.v[e]*r),this.c[e]!==i&&(this.c[e]=i,this._cmdf=!t);if(this.o.length)for(s=this.prop.v.length,e=4*this.data.p;e<s;e+=1)r=e%2==0?100:1,i=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==i&&(this.o[e-4*this.data.p]=i,this._omdf=!t);this._mdf=!t}},extendPrototype([DynamicPropertyContainer],GradientProperty),SVGGradientFillStyleData.prototype.initGradientData=function(t,e,r){this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.s=PropertyFactory.getProp(t,e.s,1,null,this),this.e=PropertyFactory.getProp(t,e.e,1,null,this),this.h=PropertyFactory.getProp(t,e.h||{k:0},0,.01,this),this.a=PropertyFactory.getProp(t,e.a||{k:0},0,degToRads,this),this.g=new GradientProperty(t,e.g,this),this.style=r,this.stops=[],this.setGradientData(r.pElem,e),this.setGradientOpacity(e,r),this._isAnimated=!!this._isAnimated},SVGGradientFillStyleData.prototype.setGradientData=function(t,e){var r=createElementID(),i=createNS(1===e.t?"linearGradient":"radialGradient");i.setAttribute("id",r),i.setAttribute("spreadMethod","pad"),i.setAttribute("gradientUnits","userSpaceOnUse");var s,a,n,o=[];for(n=4*e.g.p,a=0;a<n;a+=4)s=createNS("stop"),i.appendChild(s),o.push(s);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+getLocationHref()+"#"+r+")"),this.gf=i,this.cst=o},SVGGradientFillStyleData.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){var r,i,s,a=createNS("mask"),n=createNS("path");a.appendChild(n);var o=createElementID(),h=createElementID();a.setAttribute("id",h);var l=createNS(1===t.t?"linearGradient":"radialGradient");l.setAttribute("id",o),l.setAttribute("spreadMethod","pad"),l.setAttribute("gradientUnits","userSpaceOnUse"),s=t.g.k.k[0].s?t.g.k.k[0].s.length:t.g.k.k.length;var p=this.stops;for(i=4*t.g.p;i<s;i+=2)(r=createNS("stop")).setAttribute("stop-color","rgb(255,255,255)"),l.appendChild(r),p.push(r);n.setAttribute("gf"===t.ty?"fill":"stroke","url("+getLocationHref()+"#"+o+")"),"gs"===t.ty&&(n.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),n.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),1===t.lj&&n.setAttribute("stroke-miterlimit",t.ml)),this.of=l,this.ms=a,this.ost=p,this.maskId=h,e.msElem=n}},extendPrototype([DynamicPropertyContainer],SVGGradientFillStyleData),extendPrototype([SVGGradientFillStyleData,DynamicPropertyContainer],SVGGradientStrokeStyleData);var buildShapeString=function(t,e,r,i){if(0===e)return"";var s,a=t.o,n=t.i,o=t.v,h=" M"+i.applyToPointStringified(o[0][0],o[0][1]);for(s=1;s<e;s+=1)h+=" C"+i.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+i.applyToPointStringified(n[s][0],n[s][1])+" "+i.applyToPointStringified(o[s][0],o[s][1]);return r&&e&&(h+=" C"+i.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+i.applyToPointStringified(n[0][0],n[0][1])+" "+i.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},SVGElementsRenderer=function(){var t=new Matrix,e=new Matrix;function r(t,e,r){(r||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(r||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function i(){}function s(r,i,s){var a,n,o,h,l,p,f,c,m,u,d=i.styles.length,y=i.lvl;for(p=0;p<d;p+=1){if(h=i.sh._mdf||s,i.styles[p].lvl<y){for(c=e.reset(),m=y-i.styles[p].lvl,u=i.transformers.length-1;!h&&m>0;)h=i.transformers[u].mProps._mdf||h,m-=1,u-=1;if(h)for(m=y-i.styles[p].lvl,u=i.transformers.length-1;m>0;)c.multiply(i.transformers[u].mProps.v),m-=1,u-=1}else c=t;if(n=(f=i.sh.paths)._length,h){for(o="",a=0;a<n;a+=1)(l=f.shapes[a])&&l._length&&(o+=buildShapeString(l,l._length,l.c,c));i.caches[p]=o}else o=i.caches[p];i.styles[p].d+=!0===r.hd?"":o,i.styles[p]._mdf=h||i.styles[p]._mdf}}function a(t,e,r){var i=e.style;(e.c._mdf||r)&&i.pElem.setAttribute("fill","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||r)&&i.pElem.setAttribute("fill-opacity",e.o.v)}function n(t,e,r){o(t,e,r),h(t,e,r)}function o(t,e,r){var i,s,a,n,o,h=e.gf,l=e.g._hasOpacity,p=e.s.v,f=e.e.v;if(e.o._mdf||r){var c="gf"===t.ty?"fill-opacity":"stroke-opacity";e.style.pElem.setAttribute(c,e.o.v)}if(e.s._mdf||r){var m=1===t.t?"x1":"cx",u="x1"===m?"y1":"cy";h.setAttribute(m,p[0]),h.setAttribute(u,p[1]),l&&!e.g._collapsable&&(e.of.setAttribute(m,p[0]),e.of.setAttribute(u,p[1]))}if(e.g._cmdf||r){i=e.cst;var d=e.g.c;for(a=i.length,s=0;s<a;s+=1)(n=i[s]).setAttribute("offset",d[4*s]+"%"),n.setAttribute("stop-color","rgb("+d[4*s+1]+","+d[4*s+2]+","+d[4*s+3]+")")}if(l&&(e.g._omdf||r)){var y=e.g.o;for(a=(i=e.g._collapsable?e.cst:e.ost).length,s=0;s<a;s+=1)n=i[s],e.g._collapsable||n.setAttribute("offset",y[2*s]+"%"),n.setAttribute("stop-opacity",y[2*s+1])}if(1===t.t)(e.e._mdf||r)&&(h.setAttribute("x2",f[0]),h.setAttribute("y2",f[1]),l&&!e.g._collapsable&&(e.of.setAttribute("x2",f[0]),e.of.setAttribute("y2",f[1])));else if((e.s._mdf||e.e._mdf||r)&&(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)),h.setAttribute("r",o),l&&!e.g._collapsable&&e.of.setAttribute("r",o)),e.s._mdf||e.e._mdf||e.h._mdf||e.a._mdf||r){o||(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)));var g=Math.atan2(f[1]-p[1],f[0]-p[0]),v=e.h.v;v>=1?v=.99:v<=-1&&(v=-.99);var b=o*v,P=Math.cos(g+e.a.v)*b+p[0],S=Math.sin(g+e.a.v)*b+p[1];h.setAttribute("fx",P),h.setAttribute("fy",S),l&&!e.g._collapsable&&(e.of.setAttribute("fx",P),e.of.setAttribute("fy",S))}}function h(t,e,r){var i=e.style,s=e.d;s&&(s._mdf||r)&&s.dashStr&&(i.pElem.setAttribute("stroke-dasharray",s.dashStr),i.pElem.setAttribute("stroke-dashoffset",s.dashoffset[0])),e.c&&(e.c._mdf||r)&&i.pElem.setAttribute("stroke","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||r)&&i.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||r)&&(i.pElem.setAttribute("stroke-width",e.w.v),i.msElem&&i.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function(t){switch(t.ty){case"fl":return a;case"gf":return o;case"gs":return n;case"st":return h;case"sh":case"el":case"rc":case"sr":return s;case"tr":return r;case"no":return i;default:return null}}}}();function SVGShapeElement(t,e,r){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,r),this.prevViewData=[]}function LetterProps(t,e,r,i,s,a){this.o=t,this.sw=e,this.sc=r,this.fc=i,this.m=s,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!r,fc:!!i,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){var t,e,r,i,s=this.shapes.length,a=this.stylesList.length,n=[],o=!1;for(r=0;r<a;r+=1){for(i=this.stylesList[r],o=!1,n.length=0,t=0;t<s;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(i)&&(n.push(e),o=e._isAnimated||o);n.length>1&&o&&this.setShapesAsAnimated(n)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){var e,r=t.length;for(e=0;e<r;e+=1)t[e].setAsAnimated()},SVGShapeElement.prototype.createStyleElement=function(t,e){var r,i=new SVGStyleData(t,e),s=i.pElem;if("st"===t.ty)r=new SVGStrokeStyleData(this,t,i);else if("fl"===t.ty)r=new SVGFillStyleData(this,t,i);else if("gf"===t.ty||"gs"===t.ty){r=new("gf"===t.ty?SVGGradientFillStyleData:SVGGradientStrokeStyleData)(this,t,i),this.globalData.defs.appendChild(r.gf),r.maskId&&(this.globalData.defs.appendChild(r.ms),this.globalData.defs.appendChild(r.of),s.setAttribute("mask","url("+getLocationHref()+"#"+r.maskId+")"))}else"no"===t.ty&&(r=new SVGNoStyleData(this,t,i));return"st"!==t.ty&&"gs"!==t.ty||(s.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),s.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),s.setAttribute("fill-opacity","0"),1===t.lj&&s.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&s.setAttribute("fill-rule","evenodd"),t.ln&&s.setAttribute("id",t.ln),t.cl&&s.setAttribute("class",t.cl),t.bm&&(s.style["mix-blend-mode"]=getBlendMode(t.bm)),this.stylesList.push(i),this.addToAnimatedContents(t,r),r},SVGShapeElement.prototype.createGroupElement=function(t){var e=new ShapeGroupData;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=getBlendMode(t.bm)),e},SVGShapeElement.prototype.createTransformElement=function(t,e){var r=TransformPropertyFactory.getTransformProperty(this,t,this),i=new SVGTransformData(r,r.o,e);return this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createShapeElement=function(t,e,r){var i=4;"rc"===t.ty?i=5:"el"===t.ty?i=6:"sr"===t.ty&&(i=7);var s=new SVGShapeData(e,r,ShapePropertyFactory.getShapeProp(this,t,i,this));return this.shapes.push(s),this.addShapeToModifiers(s),this.addToAnimatedContents(t,s),s},SVGShapeElement.prototype.addToAnimatedContents=function(t,e){for(var r=0,i=this.animatedContents.length;r<i;){if(this.animatedContents[r].element===e)return;r+=1}this.animatedContents.push({fn:SVGElementsRenderer.createRenderFunction(t),element:e,data:t})},SVGShapeElement.prototype.setElementStyles=function(t){var e,r=t.styles,i=this.stylesList.length;for(e=0;e<i;e+=1)-1!==r.indexOf(this.stylesList[e])||this.stylesList[e].closed||r.push(this.stylesList[e])},SVGShapeElement.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},SVGShapeElement.prototype.searchShapes=function(t,e,r,i,s,a,n){var o,h,l,p,f,c,m=[].concat(a),u=t.length-1,d=[],y=[];for(o=u;o>=0;o-=1){if((c=this.searchProcessedElement(t[o]))?e[o]=r[c-1]:t[o]._render=n,"fl"===t[o].ty||"st"===t[o].ty||"gf"===t[o].ty||"gs"===t[o].ty||"no"===t[o].ty)c?e[o].style.closed=t[o].hd:e[o]=this.createStyleElement(t[o],s),t[o]._render&&e[o].style.pElem.parentNode!==i&&i.appendChild(e[o].style.pElem),d.push(e[o].style);else if("gr"===t[o].ty){if(c)for(l=e[o].it.length,h=0;h<l;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,s+1,m,n),t[o]._render&&e[o].gr.parentNode!==i&&i.appendChild(e[o].gr)}else"tr"===t[o].ty?(c||(e[o]=this.createTransformElement(t[o],i)),p=e[o].transform,m.push(p)):"sh"===t[o].ty||"rc"===t[o].ty||"el"===t[o].ty||"sr"===t[o].ty?(c||(e[o]=this.createShapeElement(t[o],m,s)),this.setElementStyles(e[o])):"tm"===t[o].ty||"rd"===t[o].ty||"ms"===t[o].ty||"pb"===t[o].ty||"zz"===t[o].ty||"op"===t[o].ty?(c?(f=e[o]).closed=!1:((f=ShapeModifiers.getModifier(t[o].ty)).init(this,t[o]),e[o]=f,this.shapeModifiers.push(f)),y.push(f)):"rp"===t[o].ty&&(c?(f=e[o]).closed=!0:(f=ShapeModifiers.getModifier(t[o].ty),e[o]=f,f.init(this,t,o,e),this.shapeModifiers.push(f),n=!1),y.push(f));this.addProcessedElement(t[o],o+1)}for(u=d.length,o=0;o<u;o+=1)d[o].closed=!0;for(u=y.length,o=0;o<u;o+=1)y[o].closed=!0},SVGShapeElement.prototype.renderInnerContent=function(){var t;this.renderModifiers();var e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},SVGShapeElement.prototype.renderShape=function(){var t,e,r=this.animatedContents.length;for(t=0;t<r;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},SVGShapeElement.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},LetterProps.prototype.update=function(t,e,r,i,s,a){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1,this._mdf.p=!1;var n=!1;return this.o!==t&&(this.o=t,this._mdf.o=!0,n=!0),this.sw!==e&&(this.sw=e,this._mdf.sw=!0,n=!0),this.sc!==r&&(this.sc=r,this._mdf.sc=!0,n=!0),this.fc!==i&&(this.fc=i,this._mdf.fc=!0,n=!0),this.m!==s&&(this.m=s,this._mdf.m=!0,n=!0),!a.length||this.p[0]===a[0]&&this.p[1]===a[1]&&this.p[4]===a[4]&&this.p[5]===a[5]&&this.p[12]===a[12]&&this.p[13]===a[13]||(this.p=a,this._mdf.p=!0,n=!0),n},TextProperty.prototype.defaultBoxWidth=[0,0],TextProperty.prototype.copyData=function(t,e){for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t},TextProperty.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},TextProperty.prototype.searchProperty=function(){return this.searchKeyframes()},TextProperty.prototype.searchKeyframes=function(){return this.kf=this.data.d.k.length>1,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,r=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{var i;this.lock=!0,this._mdf=!1;var s=this.effectsSequence.length,a=t||this.data.d.k[this.keysIndex].s;for(i=0;i<s;i+=1)a=r!==this.keysIndex?this.effectsSequence[i](a,a.t):this.effectsSequence[i](this.currentData,a.t);e!==a&&this.setCurrentData(a),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},TextProperty.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,r=0,i=t.length;r<=i-1&&!(r===i-1||t[r+1].t>e);)r+=1;return this.keysIndex!==r&&(this.keysIndex=r),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e,r,i=[],s=0,a=t.length,n=!1,o=!1,h="";s<a;)n=o,o=!1,e=t.charCodeAt(s),h=t.charAt(s),FontManager.isCombinedCharacter(e)?n=!0:e>=55296&&e<=56319?FontManager.isRegionalFlag(t,s)?h=t.substr(s,14):(r=t.charCodeAt(s+1))>=56320&&r<=57343&&(FontManager.isModifier(e,r)?(h=t.substr(s,2),n=!0):h=FontManager.isFlagEmoji(t.substr(s,4))?t.substr(s,4):t.substr(s,2)):e>56319?(r=t.charCodeAt(s+1),FontManager.isVariationSelector(e)&&(n=!0)):FontManager.isZeroWidthJoiner(e)&&(n=!0,o=!0),n?(i[i.length-1]+=h,n=!1):i.push(h),s+=h.length;return i},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,r,i,s,a,n,o,h=this.elem.globalData.fontManager,l=this.data,p=[],f=0,c=l.m.g,m=0,u=0,d=0,y=[],g=0,v=0,b=h.getFontByName(t.f),P=0,S=getFontProperties(b);t.fWeight=S.weight,t.fStyle=S.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),r=t.finalText.length,t.finalLineHeight=t.lh;var _,E=t.tr/1e3*t.finalSize;if(t.sz)for(var x,A,M=!0,T=t.sz[0],k=t.sz[1];M;){x=0,g=0,r=(A=this.buildFinalText(t.t)).length,E=t.tr/1e3*t.finalSize;var F=-1;for(e=0;e<r;e+=1)_=A[e].charCodeAt(0),i=!1," "===A[e]?F=e:13!==_&&3!==_||(g=0,i=!0,x+=t.finalLineHeight||1.2*t.finalSize),h.chars?(o=h.getCharData(A[e],b.fStyle,b.fFamily),P=i?0:o.w*t.finalSize/100):P=h.measureText(A[e],t.f,t.finalSize),g+P>T&&" "!==A[e]?(-1===F?r+=1:e=F,x+=t.finalLineHeight||1.2*t.finalSize,A.splice(e,F===e?1:0,"\r"),F=-1,g=0):(g+=P,g+=E);x+=b.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&k<x?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=A,r=t.finalText.length,M=!1)}g=-E,P=0;var I,D=0;for(e=0;e<r;e+=1)if(i=!1,13===(_=(I=t.finalText[e]).charCodeAt(0))||3===_?(D=0,y.push(g),v=g>v?g:v,g=-2*E,s="",i=!0,d+=1):s=I,h.chars?(o=h.getCharData(I,b.fStyle,h.getFontByName(t.f).fFamily),P=i?0:o.w*t.finalSize/100):P=h.measureText(s,t.f,t.finalSize)," "===I?D+=P+E:(g+=P+E+D,D=0),p.push({l:P,an:P,add:m,n:i,anIndexes:[],val:s,line:d,animatorJustifyOffset:0}),2==c){if(m+=P,""===s||" "===s||e===r-1){for(""!==s&&" "!==s||(m-=P);u<=e;)p[u].an=m,p[u].ind=f,p[u].extra=P,u+=1;f+=1,m=0}}else if(3==c){if(m+=P,""===s||e===r-1){for(""===s&&(m-=P);u<=e;)p[u].an=m,p[u].ind=f,p[u].extra=P,u+=1;m=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=g>v?g:v,y.push(g),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=y;var C,w,V,R,L=l.a;n=L.length;var G=[];for(a=0;a<n;a+=1){for((C=L[a]).a.sc&&(t.strokeColorAnim=!0),C.a.sw&&(t.strokeWidthAnim=!0),(C.a.fc||C.a.fh||C.a.fs||C.a.fb)&&(t.fillColorAnim=!0),R=0,V=C.s.b,e=0;e<r;e+=1)(w=p[e]).anIndexes[a]=R,(1==V&&""!==w.val||2==V&&""!==w.val&&" "!==w.val||3==V&&(w.n||" "==w.val||e==r-1)||4==V&&(w.n||e==r-1))&&(1===C.s.rn&&G.push(R),R+=1);l.a[a].s.totalChars=R;var B,z=-1;if(1===C.s.rn)for(e=0;e<r;e+=1)z!=(w=p[e]).anIndexes[a]&&(z=w.anIndexes[a],B=G.splice(Math.floor(Math.random()*G.length),1)[0]),w.anIndexes[a]=B}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=b.ascent*t.finalSize/100},TextProperty.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var r=this.copyData({},this.data.d.k[e].s);r=this.copyData(r,t),this.data.d.k[e].s=r,this.recalculate(e),this.setCurrentData(r),this.elem.addDynamicProperty(this)},TextProperty.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},TextProperty.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},TextProperty.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var TextSelectorProp=function(){var t=Math.max,e=Math.min,r=Math.floor;function i(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=PropertyFactory.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?PropertyFactory.getProp(t,e.e,0,0,this):{v:100},this.o=PropertyFactory.getProp(t,e.o||{k:0},0,0,this),this.xe=PropertyFactory.getProp(t,e.xe||{k:0},0,0,this),this.ne=PropertyFactory.getProp(t,e.ne||{k:0},0,0,this),this.sm=PropertyFactory.getProp(t,e.sm||{k:100},0,0,this),this.a=PropertyFactory.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return i.prototype={getMult:function(i){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var s=0,a=0,n=1,o=1;this.ne.v>0?s=this.ne.v/100:a=-this.ne.v/100,this.xe.v>0?n=1-this.xe.v/100:o=1+this.xe.v/100;var h=BezierFactory.getBezierEasing(s,a,n,o).get,l=0,p=this.finalS,f=this.finalE,c=this.data.sh;if(2===c)l=h(l=f===p?i>=f?1:0:t(0,e(.5/(f-p)+(i-p)/(f-p),1)));else if(3===c)l=h(l=f===p?i>=f?0:1:1-t(0,e(.5/(f-p)+(i-p)/(f-p),1)));else if(4===c)f===p?l=0:(l=t(0,e(.5/(f-p)+(i-p)/(f-p),1)))<.5?l*=2:l=1-2*(l-.5),l=h(l);else if(5===c){if(f===p)l=0;else{var m=f-p,u=-m/2+(i=e(t(0,i+.5-p),f-p)),d=m/2;l=Math.sqrt(1-u*u/(d*d))}l=h(l)}else 6===c?(f===p?l=0:(i=e(t(0,i+.5-p),f-p),l=(1+Math.cos(Math.PI+2*Math.PI*i/(f-p)))/2),l=h(l)):(i>=r(p)&&(l=t(0,e(i-p<0?e(f,1)-(p-i):f-i,1))),l=h(l));if(100!==this.sm.v){var y=.01*this.sm.v;0===y&&(y=1e-8);var g=.5-.5*y;l<g?l=0:(l=(l-g)/y)>1&&(l=1)}return l*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,r=this.o.v/e,i=this.s.v/e+r,s=this.e.v/e+r;if(i>s){var a=i;i=s,s=a}this.finalS=i,this.finalE=s}},extendPrototype([DynamicPropertyContainer],i),{getTextSelectorProp:function(t,e,r){return new i(t,e,r)}}}();function TextAnimatorDataProperty(t,e,r){var i={propType:!1},s=PropertyFactory.getProp,a=e.a;this.a={r:a.r?s(t,a.r,0,degToRads,r):i,rx:a.rx?s(t,a.rx,0,degToRads,r):i,ry:a.ry?s(t,a.ry,0,degToRads,r):i,sk:a.sk?s(t,a.sk,0,degToRads,r):i,sa:a.sa?s(t,a.sa,0,degToRads,r):i,s:a.s?s(t,a.s,1,.01,r):i,a:a.a?s(t,a.a,1,0,r):i,o:a.o?s(t,a.o,0,.01,r):i,p:a.p?s(t,a.p,1,0,r):i,sw:a.sw?s(t,a.sw,0,0,r):i,sc:a.sc?s(t,a.sc,1,0,r):i,fc:a.fc?s(t,a.fc,1,0,r):i,fh:a.fh?s(t,a.fh,0,0,r):i,fs:a.fs?s(t,a.fs,0,.01,r):i,fb:a.fb?s(t,a.fb,0,.01,r):i,t:a.t?s(t,a.t,0,0,r):i},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,r),this.s.t=e.s.t}function TextAnimatorProperty(t,e,r){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=r,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(r)}function ITextElement(){}TextAnimatorProperty.prototype.searchProperties=function(){var t,e,r=this._textData.a.length,i=PropertyFactory.getProp;for(t=0;t<r;t+=1)e=this._textData.a[t],this._animatorsData[t]=new TextAnimatorDataProperty(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:i(this._elem,this._textData.p.a,0,0,this),f:i(this._elem,this._textData.p.f,0,0,this),l:i(this._elem,this._textData.p.l,0,0,this),r:i(this._elem,this._textData.p.r,0,0,this),p:i(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=i(this._elem,this._textData.m.a,1,0,this)},TextAnimatorProperty.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var r,i,s,a,n,o,h,l,p,f,c,m,u,d,y,g,v,b,P,S=this._moreOptions.alignment.v,_=this._animatorsData,E=this._textData,x=this.mHelper,A=this._renderType,M=this.renderedLetters.length,T=t.l;if(this._hasMaskedPath){if(P=this._pathData.m,!this._pathData.n||this._pathData._mdf){var k,F=P.v;for(this._pathData.r.v&&(F=F.reverse()),n={tLength:0,segments:[]},a=F._length-1,g=0,s=0;s<a;s+=1)k=bez.buildBezierData(F.v[s],F.v[s+1],[F.o[s][0]-F.v[s][0],F.o[s][1]-F.v[s][1]],[F.i[s+1][0]-F.v[s+1][0],F.i[s+1][1]-F.v[s+1][1]]),n.tLength+=k.segmentLength,n.segments.push(k),g+=k.segmentLength;s=a,P.v.c&&(k=bez.buildBezierData(F.v[s],F.v[0],[F.o[s][0]-F.v[s][0],F.o[s][1]-F.v[s][1]],[F.i[0][0]-F.v[0][0],F.i[0][1]-F.v[0][1]]),n.tLength+=k.segmentLength,n.segments.push(k),g+=k.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,c=0,f=1,l=0,p=!0,d=n.segments,o<0&&P.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),f=(u=d[c=d.length-1].points).length-1;o<0;)o+=u[f].partialLength,(f-=1)<0&&(f=(u=d[c-=1].points).length-1);m=(u=d[c].points)[f-1],y=(h=u[f]).partialLength}a=T.length,r=0,i=0;var I,D,C,w,V,R=1.2*t.finalSize*.714,L=!0;C=_.length;var G,B,z,O,N,j,q,H,W,$,Z,X,Y=-1,K=o,J=c,U=f,Q=-1,tt="",et=this.defaultPropsArray;if(2===t.j||1===t.j){var rt=0,it=0,st=2===t.j?-.5:-1,at=0,nt=!0;for(s=0;s<a;s+=1)if(T[s].n){for(rt&&(rt+=it);at<s;)T[at].animatorJustifyOffset=rt,at+=1;rt=0,nt=!0}else{for(D=0;D<C;D+=1)(I=_[D].a).t.propType&&(nt&&2===t.j&&(it+=I.t.v*st),(V=_[D].s.getMult(T[s].anIndexes[D],E.a[D].s.totalChars)).length?rt+=I.t.v*V[0]*st:rt+=I.t.v*V*st);nt=!1}for(rt&&(rt+=it);at<s;)T[at].animatorJustifyOffset=rt,at+=1}for(s=0;s<a;s+=1){if(x.reset(),O=1,T[s].n)r=0,i+=t.yOffset,i+=L?1:0,o=K,L=!1,this._hasMaskedPath&&(f=U,m=(u=d[c=J].points)[f-1],y=(h=u[f]).partialLength,l=0),tt="",Z="",W="",X="",et=this.defaultPropsArray;else{if(this._hasMaskedPath){if(Q!==T[s].line){switch(t.j){case 1:o+=g-t.lineWidths[T[s].line];break;case 2:o+=(g-t.lineWidths[T[s].line])/2}Q=T[s].line}Y!==T[s].ind&&(T[Y]&&(o+=T[Y].extra),o+=T[s].an/2,Y=T[s].ind),o+=S[0]*T[s].an*.005;var ot=0;for(D=0;D<C;D+=1)(I=_[D].a).p.propType&&((V=_[D].s.getMult(T[s].anIndexes[D],E.a[D].s.totalChars)).length?ot+=I.p.v[0]*V[0]:ot+=I.p.v[0]*V),I.a.propType&&((V=_[D].s.getMult(T[s].anIndexes[D],E.a[D].s.totalChars)).length?ot+=I.a.v[0]*V[0]:ot+=I.a.v[0]*V);for(p=!0,this._pathData.a.v&&(o=.5*T[0].an+(g-this._pathData.f.v-.5*T[0].an-.5*T[T.length-1].an)*Y/(a-1),o+=this._pathData.f.v);p;)l+y>=o+ot||!u?(v=(o+ot-l)/h.partialLength,B=m.point[0]+(h.point[0]-m.point[0])*v,z=m.point[1]+(h.point[1]-m.point[1])*v,x.translate(-S[0]*T[s].an*.005,-S[1]*R*.01),p=!1):u&&(l+=h.partialLength,(f+=1)>=u.length&&(f=0,d[c+=1]?u=d[c].points:P.v.c?(f=0,u=d[c=0].points):(l-=h.partialLength,u=null)),u&&(m=h,y=(h=u[f]).partialLength));G=T[s].an/2-T[s].add,x.translate(-G,0,0)}else G=T[s].an/2-T[s].add,x.translate(-G,0,0),x.translate(-S[0]*T[s].an*.005,-S[1]*R*.01,0);for(D=0;D<C;D+=1)(I=_[D].a).t.propType&&(V=_[D].s.getMult(T[s].anIndexes[D],E.a[D].s.totalChars),0===r&&0===t.j||(this._hasMaskedPath?V.length?o+=I.t.v*V[0]:o+=I.t.v*V:V.length?r+=I.t.v*V[0]:r+=I.t.v*V));for(t.strokeWidthAnim&&(j=t.sw||0),t.strokeColorAnim&&(N=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(q=[t.fc[0],t.fc[1],t.fc[2]]),D=0;D<C;D+=1)(I=_[D].a).a.propType&&((V=_[D].s.getMult(T[s].anIndexes[D],E.a[D].s.totalChars)).length?x.translate(-I.a.v[0]*V[0],-I.a.v[1]*V[1],I.a.v[2]*V[2]):x.translate(-I.a.v[0]*V,-I.a.v[1]*V,I.a.v[2]*V));for(D=0;D<C;D+=1)(I=_[D].a).s.propType&&((V=_[D].s.getMult(T[s].anIndexes[D],E.a[D].s.totalChars)).length?x.scale(1+(I.s.v[0]-1)*V[0],1+(I.s.v[1]-1)*V[1],1):x.scale(1+(I.s.v[0]-1)*V,1+(I.s.v[1]-1)*V,1));for(D=0;D<C;D+=1){if(I=_[D].a,V=_[D].s.getMult(T[s].anIndexes[D],E.a[D].s.totalChars),I.sk.propType&&(V.length?x.skewFromAxis(-I.sk.v*V[0],I.sa.v*V[1]):x.skewFromAxis(-I.sk.v*V,I.sa.v*V)),I.r.propType&&(V.length?x.rotateZ(-I.r.v*V[2]):x.rotateZ(-I.r.v*V)),I.ry.propType&&(V.length?x.rotateY(I.ry.v*V[1]):x.rotateY(I.ry.v*V)),I.rx.propType&&(V.length?x.rotateX(I.rx.v*V[0]):x.rotateX(I.rx.v*V)),I.o.propType&&(V.length?O+=(I.o.v*V[0]-O)*V[0]:O+=(I.o.v*V-O)*V),t.strokeWidthAnim&&I.sw.propType&&(V.length?j+=I.sw.v*V[0]:j+=I.sw.v*V),t.strokeColorAnim&&I.sc.propType)for(H=0;H<3;H+=1)V.length?N[H]+=(I.sc.v[H]-N[H])*V[0]:N[H]+=(I.sc.v[H]-N[H])*V;if(t.fillColorAnim&&t.fc){if(I.fc.propType)for(H=0;H<3;H+=1)V.length?q[H]+=(I.fc.v[H]-q[H])*V[0]:q[H]+=(I.fc.v[H]-q[H])*V;I.fh.propType&&(q=V.length?addHueToRGB(q,I.fh.v*V[0]):addHueToRGB(q,I.fh.v*V)),I.fs.propType&&(q=V.length?addSaturationToRGB(q,I.fs.v*V[0]):addSaturationToRGB(q,I.fs.v*V)),I.fb.propType&&(q=V.length?addBrightnessToRGB(q,I.fb.v*V[0]):addBrightnessToRGB(q,I.fb.v*V))}}for(D=0;D<C;D+=1)(I=_[D].a).p.propType&&(V=_[D].s.getMult(T[s].anIndexes[D],E.a[D].s.totalChars),this._hasMaskedPath?V.length?x.translate(0,I.p.v[1]*V[0],-I.p.v[2]*V[1]):x.translate(0,I.p.v[1]*V,-I.p.v[2]*V):V.length?x.translate(I.p.v[0]*V[0],I.p.v[1]*V[1],-I.p.v[2]*V[2]):x.translate(I.p.v[0]*V,I.p.v[1]*V,-I.p.v[2]*V));if(t.strokeWidthAnim&&(W=j<0?0:j),t.strokeColorAnim&&($="rgb("+Math.round(255*N[0])+","+Math.round(255*N[1])+","+Math.round(255*N[2])+")"),t.fillColorAnim&&t.fc&&(Z="rgb("+Math.round(255*q[0])+","+Math.round(255*q[1])+","+Math.round(255*q[2])+")"),this._hasMaskedPath){if(x.translate(0,-t.ls),x.translate(0,S[1]*R*.01+i,0),this._pathData.p.v){b=(h.point[1]-m.point[1])/(h.point[0]-m.point[0]);var ht=180*Math.atan(b)/Math.PI;h.point[0]<m.point[0]&&(ht+=180),x.rotate(-ht*Math.PI/180)}x.translate(B,z,0),o-=S[0]*T[s].an*.005,T[s+1]&&Y!==T[s+1].ind&&(o+=T[s].an/2,o+=.001*t.tr*t.finalSize)}else{switch(x.translate(r,i,0),t.ps&&x.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:x.translate(T[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[T[s].line]),0,0);break;case 2:x.translate(T[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[T[s].line])/2,0,0)}x.translate(0,-t.ls),x.translate(G,0,0),x.translate(S[0]*T[s].an*.005,S[1]*R*.01,0),r+=T[s].l+.001*t.tr*t.finalSize}"html"===A?tt=x.toCSS():"svg"===A?tt=x.to2dCSS():et=[x.props[0],x.props[1],x.props[2],x.props[3],x.props[4],x.props[5],x.props[6],x.props[7],x.props[8],x.props[9],x.props[10],x.props[11],x.props[12],x.props[13],x.props[14],x.props[15]],X=O}M<=s?(w=new LetterProps(X,W,$,Z,tt,et),this.renderedLetters.push(w),M+=1,this.lettersChangedFlag=!0):(w=this.renderedLetters[s],this.lettersChangedFlag=w.update(X,W,$,Z,tt,et)||this.lettersChangedFlag)}}},TextAnimatorProperty.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},TextAnimatorProperty.prototype.mHelper=new Matrix,TextAnimatorProperty.prototype.defaultPropsArray=[],extendPrototype([DynamicPropertyContainer],TextAnimatorProperty),ITextElement.prototype.initElement=function(t,e,r){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,r),this.textProperty=new TextProperty(this,t.t,this.dynamicProperties),this.textAnimator=new TextAnimatorProperty(t.t,this.renderType,this),this.initTransform(t,e,r),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},ITextElement.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},ITextElement.prototype.createPathShape=function(t,e){var r,i,s=e.length,a="";for(r=0;r<s;r+=1)"sh"===e[r].ty&&(i=e[r].ks.k,a+=buildShapeString(i,i.i.length,!0,t));return a},ITextElement.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},ITextElement.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},ITextElement.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},ITextElement.prototype.applyTextPropertiesToMatrix=function(t,e,r,i,s){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[r]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[r])/2,0,0)}e.translate(i,s,0)},ITextElement.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},ITextElement.prototype.emptyProp=new LetterProps,ITextElement.prototype.destroy=function(){},ITextElement.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var emptyShapeData={shapes:[]};function SVGTextLottieElement(t,e,r){this.textSpans=[],this.renderType="svg",this.initElement(t,e,r)}function ISolidElement(t,e,r){this.initElement(t,e,r)}function NullElement(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initFrame(),this.initTransform(t,e,r),this.initHierarchy()}function SVGRendererBase(){}function ICompElement(){}function SVGCompElement(t,e,r){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,r),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function SVGRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=createNS("svg");var r="";if(e&&e.title){var i=createNS("title"),s=createElementID();i.setAttribute("id",s),i.textContent=e.title,this.svgElement.appendChild(i),r+=s}if(e&&e.description){var a=createNS("desc"),n=createElementID();a.setAttribute("id",n),a.textContent=e.description,this.svgElement.appendChild(a),r+=" "+n}r&&this.svgElement.setAttribute("aria-labelledby",r);var o=createNS("defs");this.svgElement.appendChild(o);var h=createNS("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],SVGTextLottieElement),SVGTextLottieElement.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=createNS("text"))},SVGTextLottieElement.prototype.buildTextContents=function(t){for(var e=0,r=t.length,i=[],s="";e<r;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(i.push(s),s=""):s+=t[e],e+=1;return i.push(s),i},SVGTextLottieElement.prototype.buildShapeData=function(t,e){if(t.shapes&&t.shapes.length){var r=t.shapes[0];if(r.it){var i=r.it[r.it.length-1];i.s&&(i.s.k[0]=e,i.s.k[1]=e)}}return t},SVGTextLottieElement.prototype.buildNewText=function(){var t,e;this.addDynamicProperty(this);var r=this.textProperty.currentData;this.renderedLetters=createSizedArray(r?r.l.length:0),r.fc?this.layerElement.setAttribute("fill",this.buildColor(r.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),r.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(r.sc)),this.layerElement.setAttribute("stroke-width",r.sw)),this.layerElement.setAttribute("font-size",r.finalSize);var i=this.globalData.fontManager.getFontByName(r.f);if(i.fClass)this.layerElement.setAttribute("class",i.fClass);else{this.layerElement.setAttribute("font-family",i.fFamily);var s=r.fWeight,a=r.fStyle;this.layerElement.setAttribute("font-style",a),this.layerElement.setAttribute("font-weight",s)}this.layerElement.setAttribute("aria-label",r.t);var n,o=r.l||[],h=!!this.globalData.fontManager.chars;e=o.length;var l=this.mHelper,p=this.data.singleShape,f=0,c=0,m=!0,u=.001*r.tr*r.finalSize;if(!p||h||r.sz){var d,y=this.textSpans.length;for(t=0;t<e;t+=1){if(this.textSpans[t]||(this.textSpans[t]={span:null,childSpan:null,glyph:null}),!h||!p||0===t){if(n=y>t?this.textSpans[t].span:createNS(h?"g":"text"),y<=t){if(n.setAttribute("stroke-linecap","butt"),n.setAttribute("stroke-linejoin","round"),n.setAttribute("stroke-miterlimit","4"),this.textSpans[t].span=n,h){var g=createNS("g");n.appendChild(g),this.textSpans[t].childSpan=g}this.textSpans[t].span=n,this.layerElement.appendChild(n)}n.style.display="inherit"}if(l.reset(),p&&(o[t].n&&(f=-u,c+=r.yOffset,c+=m?1:0,m=!1),this.applyTextPropertiesToMatrix(r,l,o[t].line,f,c),f+=o[t].l||0,f+=u),h){var v;if(1===(d=this.globalData.fontManager.getCharData(r.finalText[t],i.fStyle,this.globalData.fontManager.getFontByName(r.f).fFamily)).t)v=new SVGCompElement(d.data,this.globalData,this);else{var b=emptyShapeData;d.data&&d.data.shapes&&(b=this.buildShapeData(d.data,r.finalSize)),v=new SVGShapeElement(b,this.globalData,this)}if(this.textSpans[t].glyph){var P=this.textSpans[t].glyph;this.textSpans[t].childSpan.removeChild(P.layerElement),P.destroy()}this.textSpans[t].glyph=v,v._debug=!0,v.prepareFrame(0),v.renderFrame(),this.textSpans[t].childSpan.appendChild(v.layerElement),1===d.t&&this.textSpans[t].childSpan.setAttribute("transform","scale("+r.finalSize/100+","+r.finalSize/100+")")}else p&&n.setAttribute("transform","translate("+l.props[12]+","+l.props[13]+")"),n.textContent=o[t].val,n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}p&&n&&n.setAttribute("d","")}else{var S=this.textContainer,_="start";switch(r.j){case 1:_="end";break;case 2:_="middle";break;default:_="start"}S.setAttribute("text-anchor",_),S.setAttribute("letter-spacing",u);var E=this.buildTextContents(r.finalText);for(e=E.length,c=r.ps?r.ps[1]+r.ascent:0,t=0;t<e;t+=1)(n=this.textSpans[t].span||createNS("tspan")).textContent=E[t],n.setAttribute("x",0),n.setAttribute("y",c),n.style.display="inherit",S.appendChild(n),this.textSpans[t]||(this.textSpans[t]={span:null,glyph:null}),this.textSpans[t].span=n,c+=r.finalLineHeight;this.layerElement.appendChild(S)}for(;t<this.textSpans.length;)this.textSpans[t].span.style.display="none",t+=1;this._sizeChanged=!0},SVGTextLottieElement.prototype.sourceRectAtTime=function(){if(this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged){this._sizeChanged=!1;var t=this.layerElement.getBBox();this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}}return this.bbox},SVGTextLottieElement.prototype.getValue=function(){var t,e,r=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<r;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf&&(this._mdf=!0))},SVGTextLottieElement.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){var t,e;this._sizeChanged=!0;var r,i,s,a=this.textAnimator.renderedLetters,n=this.textProperty.currentData.l;for(e=n.length,t=0;t<e;t+=1)n[t].n||(r=a[t],i=this.textSpans[t].span,(s=this.textSpans[t].glyph)&&s.renderFrame(),r._mdf.m&&i.setAttribute("transform",r.m),r._mdf.o&&i.setAttribute("opacity",r.o),r._mdf.sw&&i.setAttribute("stroke-width",r.sw),r._mdf.sc&&i.setAttribute("stroke",r.sc),r._mdf.fc&&i.setAttribute("fill",r.fc))}},extendPrototype([IImageElement],ISolidElement),ISolidElement.prototype.createContent=function(){var t=createNS("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},NullElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},NullElement.prototype.renderFrame=function(){},NullElement.prototype.getBaseElement=function(){return null},NullElement.prototype.destroy=function(){},NullElement.prototype.sourceRectAtTime=function(){},NullElement.prototype.hide=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement],NullElement),extendPrototype([BaseRenderer],SVGRendererBase),SVGRendererBase.prototype.createNull=function(t){return new NullElement(t,this.globalData,this)},SVGRendererBase.prototype.createShape=function(t){return new SVGShapeElement(t,this.globalData,this)},SVGRendererBase.prototype.createText=function(t){return new SVGTextLottieElement(t,this.globalData,this)},SVGRendererBase.prototype.createImage=function(t){return new IImageElement(t,this.globalData,this)},SVGRendererBase.prototype.createSolid=function(t){return new ISolidElement(t,this.globalData,this)},SVGRendererBase.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var r=createNS("clipPath"),i=createNS("rect");i.setAttribute("width",t.w),i.setAttribute("height",t.h),i.setAttribute("x",0),i.setAttribute("y",0);var s=createElementID();r.setAttribute("id",s),r.appendChild(i),this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),e.appendChild(r),this.layers=t.layers,this.elements=createSizedArray(t.layers.length)},SVGRendererBase.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},SVGRendererBase.prototype.updateContainerSize=function(){},SVGRendererBase.prototype.findIndexByInd=function(t){var e=0,r=this.layers.length;for(e=0;e<r;e+=1)if(this.layers[e].ind===t)return e;return-1},SVGRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){e[t]=!0;var r=this.createItem(this.layers[t]);if(e[t]=r,getExpressionsPlugin()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(r),r.initExpressions()),this.appendElementInPos(r,t),this.layers[t].tt){var i="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1;if(-1===i)return;if(this.elements[i]&&!0!==this.elements[i]){var s=e[i].getMatte(this.layers[t].tt);r.setMatte(s)}else this.buildItem(i),this.addPendingElement(r)}}},SVGRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,r=this.elements.length;e<r;){if(this.elements[e]===t){var i="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,s=this.elements[i].getMatte(this.layers[e].tt);t.setMatte(s);break}e+=1}}},SVGRendererBase.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){var e;null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var r=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=r-1;e>=0;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<r;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},SVGRendererBase.prototype.appendElementInPos=function(t,e){var r=t.getBaseElement();if(r){for(var i,s=0;s<e;)this.elements[s]&&!0!==this.elements[s]&&this.elements[s].getBaseElement()&&(i=this.elements[s].getBaseElement()),s+=1;i?this.layerElement.insertBefore(r,i):this.layerElement.appendChild(r)}},SVGRendererBase.prototype.hide=function(){this.layerElement.style.display="none"},SVGRendererBase.prototype.show=function(){this.layerElement.style.display="block"},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement,RenderableDOMElement],ICompElement),ICompElement.prototype.initElement=function(t,e,r){this.initFrame(),this.initBaseData(t,e,r),this.initTransform(t,e,r),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},ICompElement.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var r,i=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),r=i-1;r>=0;r-=1)(this.completeLayers||this.elements[r])&&(this.elements[r].prepareFrame(this.renderedFrame-this.layers[r].st),this.elements[r]._mdf&&(this._mdf=!0))}},ICompElement.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},ICompElement.prototype.setElements=function(t){this.elements=t},ICompElement.prototype.getElements=function(){return this.elements},ICompElement.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},ICompElement.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},extendPrototype([SVGRendererBase,ICompElement,SVGBaseElement],SVGCompElement),SVGCompElement.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},extendPrototype([SVGRendererBase],SVGRenderer),SVGRenderer.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},registerRenderer("svg",SVGRenderer),ShapeModifiers.registerModifier("tm",TrimModifier),ShapeModifiers.registerModifier("pb",PuckerAndBloatModifier),ShapeModifiers.registerModifier("rp",RepeaterModifier),ShapeModifiers.registerModifier("rd",RoundCornersModifier),ShapeModifiers.registerModifier("zz",ZigZagModifier),ShapeModifiers.registerModifier("op",OffsetPathModifier);var CompExpressionInterface=function(t){function e(e){for(var r=0,i=t.layers.length;r<i;){if(t.layers[r].nm===e||t.layers[r].ind===e)return t.elements[r].layerInterface;r+=1}return null}return Object.defineProperty(e,"_name",{value:t.data.nm}),e.layer=e,e.pixelAspect=1,e.height=t.data.h||t.globalData.compSize.h,e.width=t.data.w||t.globalData.compSize.w,e.pixelAspect=1,e.frameDuration=1/t.globalData.frameRate,e.displayStartTime=0,e.numLayers=t.layers.length,e};function _typeof$2(t){return _typeof$2="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$2(t)}function seedRandom(t,e){var r,i=this,s=256,a="random",n=e.pow(s,6),o=e.pow(2,52),h=2*o,l=255;function p(t){var e,r=t.length,i=this,a=0,n=i.i=i.j=0,o=i.S=[];for(r||(t=[r++]);a<s;)o[a]=a++;for(a=0;a<s;a++)o[a]=o[n=l&n+t[a%r]+(e=o[a])],o[n]=e;i.g=function(t){for(var e,r=0,a=i.i,n=i.j,o=i.S;t--;)e=o[a=l&a+1],r=r*s+o[l&(o[a]=o[n=l&n+e])+(o[n]=e)];return i.i=a,i.j=n,r}}function f(t,e){return e.i=t.i,e.j=t.j,e.S=t.S.slice(),e}function c(t,e){var r,i=[],s=_typeof$2(t);if(e&&"object"==s)for(r in t)try{i.push(c(t[r],e-1))}catch(t){}return i.length?i:"string"==s?t:t+"\0"}function m(t,e){for(var r,i=t+"",s=0;s<i.length;)e[l&s]=l&(r^=19*e[l&s])+i.charCodeAt(s++);return u(e)}function u(t){return String.fromCharCode.apply(0,t)}e["seed"+a]=function(l,d,y){var g=[],v=m(c((d=!0===d?{entropy:!0}:d||{}).entropy?[l,u(t)]:null===l?function(){try{r;var e=new Uint8Array(s);return(i.crypto||i.msCrypto).getRandomValues(e),u(e)}catch(e){var a=i.navigator,n=a&&a.plugins;return[+new Date,i,n,i.screen,u(t)]}}():l,3),g),b=new p(g),P=function(){for(var t=b.g(6),e=n,r=0;t<o;)t=(t+r)*s,e*=s,r=b.g(1);for(;t>=h;)t/=2,e/=2,r>>>=1;return(t+r)/e};return P.int32=function(){return 0|b.g(4)},P.quick=function(){return b.g(4)/4294967296},P.double=P,m(u(b.S),t),(d.pass||y||function(t,r,i,s){return s&&(s.S&&f(s,b),t.state=function(){return f(b,{})}),i?(e[a]=t,r):t})(P,v,"global"in d?d.global:this==e,d.state)},m(e.random(),t)}function initialize$2(t){seedRandom([],t)}var propTypes={SHAPE:"shape"};function _typeof$1(t){return _typeof$1="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof$1(t)}var ExpressionManager=function(){var ob={},Math=BMMath,window=null,document=null,XMLHttpRequest=null,fetch=null,frames=null,_lottieGlobal={};function resetFrame(){_lottieGlobal={}}function $bm_isInstanceOfArray(t){return t.constructor===Array||t.constructor===Float32Array}function isNumerable(t,e){return"number"===t||e instanceof Number||"boolean"===t||"string"===t}function $bm_neg(t){var e=_typeof$1(t);if("number"===e||t instanceof Number||"boolean"===e)return-t;if($bm_isInstanceOfArray(t)){var r,i=t.length,s=[];for(r=0;r<i;r+=1)s[r]=-t[r];return s}return t.propType?t.v:-t}initialize$2(BMMath);var easeInBez=BezierFactory.getBezierEasing(.333,0,.833,.833,"easeIn").get,easeOutBez=BezierFactory.getBezierEasing(.167,.167,.667,1,"easeOut").get,easeInOutBez=BezierFactory.getBezierEasing(.33,0,.667,1,"easeInOut").get;function sum(t,e){var r=_typeof$1(t),i=_typeof$1(e);if(isNumerable(r,t)&&isNumerable(i,e)||"string"===r||"string"===i)return t+e;if($bm_isInstanceOfArray(t)&&isNumerable(i,e))return(t=t.slice(0))[0]+=e,t;if(isNumerable(r,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t+e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]+e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}var add=sum;function sub(t,e){var r=_typeof$1(t),i=_typeof$1(e);if(isNumerable(r,t)&&isNumerable(i,e))return"string"===r&&(t=parseInt(t,10)),"string"===i&&(e=parseInt(e,10)),t-e;if($bm_isInstanceOfArray(t)&&isNumerable(i,e))return(t=t.slice(0))[0]-=e,t;if(isNumerable(r,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t-e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]-e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}function mul(t,e){var r,i,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t*e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t[i]*e;return r}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t*e[i];return r}return 0}function div(t,e){var r,i,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t/e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t[i]/e;return r}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,r=createTypedArray("float32",s),i=0;i<s;i+=1)r[i]=t/e[i];return r}return 0}function mod(t,e){return"string"==typeof t&&(t=parseInt(t,10)),"string"==typeof e&&(e=parseInt(e,10)),t%e}var $bm_sum=sum,$bm_sub=sub,$bm_mul=mul,$bm_div=div,$bm_mod=mod;function clamp(t,e,r){if(e>r){var i=r;r=e,e=i}return Math.min(Math.max(t,e),r)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return e=e||0,Math.abs(t-e);var r;e||(e=helperLengthArray);var i=Math.min(t.length,e.length),s=0;for(r=0;r<i;r+=1)s+=Math.pow(e[r]-t[r],2);return Math.sqrt(s)}function normalize(t){return div(t,length(t))}function rgbToHsl(t){var e,r,i=t[0],s=t[1],a=t[2],n=Math.max(i,s,a),o=Math.min(i,s,a),h=(n+o)/2;if(n===o)e=0,r=0;else{var l=n-o;switch(r=h>.5?l/(2-n-o):l/(n+o),n){case i:e=(s-a)/l+(s<a?6:0);break;case s:e=(a-i)/l+2;break;case a:e=(i-s)/l+4}e/=6}return[e,r,h,t[3]]}function hue2rgb(t,e,r){return r<0&&(r+=1),r>1&&(r-=1),r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t}function hslToRgb(t){var e,r,i,s=t[0],a=t[1],n=t[2];if(0===a)e=n,i=n,r=n;else{var o=n<.5?n*(1+a):n+a-n*a,h=2*n-o;e=hue2rgb(h,o,s+1/3),r=hue2rgb(h,o,s),i=hue2rgb(h,o,s-1/3)}return[e,r,i,t[3]]}function linear(t,e,r,i,s){if(void 0!==i&&void 0!==s||(i=e,s=r,e=0,r=1),r<e){var a=r;r=e,e=a}if(t<=e)return i;if(t>=r)return s;var n,o=r===e?0:(t-e)/(r-e);if(!i.length)return i+(s-i)*o;var h=i.length,l=createTypedArray("float32",h);for(n=0;n<h;n+=1)l[n]=i[n]+(s[n]-i[n])*o;return l}function random(t,e){if(void 0===e&&(void 0===t?(t=0,e=1):(e=t,t=void 0)),e.length){var r,i=e.length;t||(t=createTypedArray("float32",i));var s=createTypedArray("float32",i),a=BMMath.random();for(r=0;r<i;r+=1)s[r]=t[r]+a*(e[r]-t[r]);return s}return void 0===t&&(t=0),t+BMMath.random()*(e-t)}function createPath(t,e,r,i){var s,a=t.length,n=shapePool.newElement();n.setPathData(!!i,a);var o,h,l=[0,0];for(s=0;s<a;s+=1)o=e&&e[s]?e[s]:l,h=r&&r[s]?r[s]:l,n.setTripleAt(t[s][0],t[s][1],h[0]+t[s][0],h[1]+t[s][1],o[0]+t[s][0],o[1]+t[s][1],s,!0);return n}function initiateExpression(elem,data,property){function noOp(t){return t}if(!elem.globalData.renderConfig.runExpressions)return noOp;var val=data.x,needsVelocity=/velocity(?![\w\d])/.test(val),_needsRandom=-1!==val.indexOf("random"),elemType=elem.data.ty,transform,$bm_transform,content,effect,thisProperty=property;thisProperty._name=elem.data.nm,thisProperty.valueAtTime=thisProperty.getValueAtTime,Object.defineProperty(thisProperty,"value",{get:function(){return thisProperty.v}}),elem.comp.frameDuration=1/elem.comp.globalData.frameRate,elem.comp.displayStartTime=0;var inPoint=elem.data.ip/elem.comp.globalData.frameRate,outPoint=elem.data.op/elem.comp.globalData.frameRate,width=elem.data.sw?elem.data.sw:0,height=elem.data.sh?elem.data.sh:0,name=elem.data.nm,loopIn,loop_in,loopOut,loop_out,smooth,toWorld,fromWorld,fromComp,toComp,fromCompToSurface,position,rotation,anchorPoint,scale,thisLayer,thisComp,mask,valueAtTime,velocityAtTime,scoped_bm_rt,expression_function=eval("[function _expression_function(){"+val+";scoped_bm_rt=$bm_rt}]")[0],numKeys=property.kf?data.k.length:0,active=!this.data||!0!==this.data.hd,wiggle=function(t,e){var r,i,s=this.pv.length?this.pv.length:1,a=createTypedArray("float32",s);var n=Math.floor(5*time);for(r=0,i=0;r<n;){for(i=0;i<s;i+=1)a[i]+=-e+2*e*BMMath.random();r+=1}var o=5*time,h=o-Math.floor(o),l=createTypedArray("float32",s);if(s>1){for(i=0;i<s;i+=1)l[i]=this.pv[i]+a[i]+(-e+2*e*BMMath.random())*h;return l}return this.pv+a[0]+(-e+2*e*BMMath.random())*h}.bind(this);function loopInDuration(t,e){return loopIn(t,e,!0)}function loopOutDuration(t,e){return loopOut(t,e,!0)}thisProperty.loopIn&&(loopIn=thisProperty.loopIn.bind(thisProperty),loop_in=loopIn),thisProperty.loopOut&&(loopOut=thisProperty.loopOut.bind(thisProperty),loop_out=loopOut),thisProperty.smooth&&(smooth=thisProperty.smooth.bind(thisProperty)),this.getValueAtTime&&(valueAtTime=this.getValueAtTime.bind(this)),this.getVelocityAtTime&&(velocityAtTime=this.getVelocityAtTime.bind(this));var comp=elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface),time,velocity,value,text,textIndex,textTotal,selectorValue;function lookAt(t,e){var r=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],i=Math.atan2(r[0],Math.sqrt(r[1]*r[1]+r[2]*r[2]))/degToRads;return[-Math.atan2(r[1],r[2])/degToRads,i,0]}function easeOut(t,e,r,i,s){return applyEase(easeOutBez,t,e,r,i,s)}function easeIn(t,e,r,i,s){return applyEase(easeInBez,t,e,r,i,s)}function ease(t,e,r,i,s){return applyEase(easeInOutBez,t,e,r,i,s)}function applyEase(t,e,r,i,s,a){void 0===s?(s=r,a=i):e=(e-r)/(i-r),e>1?e=1:e<0&&(e=0);var n=t(e);if($bm_isInstanceOfArray(s)){var o,h=s.length,l=createTypedArray("float32",h);for(o=0;o<h;o+=1)l[o]=(a[o]-s[o])*n+s[o];return l}return(a-s)*n+s}function nearestKey(t){var e,r,i,s=data.k.length;if(data.k.length&&"number"!=typeof data.k[0])if(r=-1,(t*=elem.comp.globalData.frameRate)<data.k[0].t)r=1,i=data.k[0].t;else{for(e=0;e<s-1;e+=1){if(t===data.k[e].t){r=e+1,i=data.k[e].t;break}if(t>data.k[e].t&&t<data.k[e+1].t){t-data.k[e].t>data.k[e+1].t-t?(r=e+2,i=data.k[e+1].t):(r=e+1,i=data.k[e].t);break}}-1===r&&(r=e+1,i=data.k[e].t)}else r=0,i=0;var a={};return a.index=r,a.time=i/elem.comp.globalData.frameRate,a}function key(t){var e,r,i;if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]};var s=Object.prototype.hasOwnProperty.call(data.k[t],"s")?data.k[t].s:data.k[t-1].e;for(i=s.length,r=0;r<i;r+=1)e[r]=s[r],e.value[r]=s[r];return e}function framesToTime(t,e){return e||(e=elem.comp.globalData.frameRate),t/e}function timeToFrames(t,e){return t||0===t||(t=time),e||(e=elem.comp.globalData.frameRate),t*e}function seedRandom(t){BMMath.seedrandom(randSeed+t)}function sourceRectAtTime(){return elem.sourceRectAtTime()}function substring(t,e){return"string"==typeof value?void 0===e?value.substring(t):value.substring(t,e):""}function substr(t,e){return"string"==typeof value?void 0===e?value.substr(t):value.substr(t,e):""}function posterizeTime(t){time=0===t?0:Math.floor(time*t)/t,value=valueAtTime(time)}var index=elem.data.ind,hasParent=!(!elem.hierarchy||!elem.hierarchy.length),parent,randSeed=Math.floor(1e6*Math.random()),globalData=elem.globalData;function executeExpression(t){return value=t,this.frameExpressionId===elem.globalData.frameId&&"textSelector"!==this.propType?value:("textSelector"===this.propType&&(textIndex=this.textIndex,textTotal=this.textTotal,selectorValue=this.selectorValue),thisLayer||(text=elem.layerInterface.text,thisLayer=elem.layerInterface,thisComp=elem.comp.compInterface,toWorld=thisLayer.toWorld.bind(thisLayer),fromWorld=thisLayer.fromWorld.bind(thisLayer),fromComp=thisLayer.fromComp.bind(thisLayer),toComp=thisLayer.toComp.bind(thisLayer),mask=thisLayer.mask?thisLayer.mask.bind(thisLayer):null,fromCompToSurface=fromComp),transform||(transform=elem.layerInterface("ADBE Transform Group"),$bm_transform=transform,transform&&(anchorPoint=transform.anchorPoint)),4!==elemType||content||(content=thisLayer("ADBE Root Vectors Group")),effect||(effect=thisLayer(4)),(hasParent=!(!elem.hierarchy||!elem.hierarchy.length))&&!parent&&(parent=elem.hierarchy[0].layerInterface),time=this.comp.renderedFrame/this.comp.globalData.frameRate,_needsRandom&&seedRandom(randSeed+time),needsVelocity&&(velocity=velocityAtTime(time)),expression_function(),this.frameExpressionId=elem.globalData.frameId,scoped_bm_rt=scoped_bm_rt.propType===propTypes.SHAPE?scoped_bm_rt.v:scoped_bm_rt)}return executeExpression.__preventDeadCodeRemoval=[$bm_transform,anchorPoint,time,velocity,inPoint,outPoint,width,height,name,loop_in,loop_out,smooth,toComp,fromCompToSurface,toWorld,fromWorld,mask,position,rotation,scale,thisComp,numKeys,active,wiggle,loopInDuration,loopOutDuration,comp,lookAt,easeOut,easeIn,ease,nearestKey,key,text,textIndex,textTotal,selectorValue,framesToTime,timeToFrames,sourceRectAtTime,substring,substr,posterizeTime,index,globalData],executeExpression}return ob.initiateExpression=initiateExpression,ob.__preventDeadCodeRemoval=[window,document,XMLHttpRequest,fetch,frames,$bm_neg,add,$bm_sum,$bm_sub,$bm_mul,$bm_div,$bm_mod,clamp,radians_to_degrees,degreesToRadians,degrees_to_radians,normalize,rgbToHsl,hslToRgb,linear,random,createPath,_lottieGlobal],ob.resetFrame=resetFrame,ob}(),Expressions=function(){var t={};return t.initExpressions=function(t){var e=0,r=[];t.renderer.compInterface=CompExpressionInterface(t.renderer),t.renderer.globalData.projectInterface.registerComposition(t.renderer),t.renderer.globalData.pushExpression=function(){e+=1},t.renderer.globalData.popExpression=function(){0==(e-=1)&&function(){var t,e=r.length;for(t=0;t<e;t+=1)r[t].release();r.length=0}()},t.renderer.globalData.registerExpressionProperty=function(t){-1===r.indexOf(t)&&r.push(t)}},t.resetFrame=ExpressionManager.resetFrame,t}(),MaskManagerInterface=function(){function t(t,e){this._mask=t,this._data=e}Object.defineProperty(t.prototype,"maskPath",{get:function(){return this._mask.prop.k&&this._mask.prop.getValue(),this._mask.prop}}),Object.defineProperty(t.prototype,"maskOpacity",{get:function(){return this._mask.op.k&&this._mask.op.getValue(),100*this._mask.op.v}});return function(e){var r,i=createSizedArray(e.viewData.length),s=e.viewData.length;for(r=0;r<s;r+=1)i[r]=new t(e.viewData[r],e.masksProperties[r]);return function(t){for(r=0;r<s;){if(e.masksProperties[r].nm===t)return i[r];r+=1}return null}}}(),ExpressionPropertyInterface=function(){var t={pv:0,v:0,mult:1},e={pv:[0,0,0],v:[0,0,0],mult:1};function r(t,e,r){Object.defineProperty(t,"velocity",{get:function(){return e.getVelocityAtTime(e.comp.currentFrame)}}),t.numKeys=e.keyframes?e.keyframes.length:0,t.key=function(i){if(!t.numKeys)return 0;var s="";s="s"in e.keyframes[i-1]?e.keyframes[i-1].s:"e"in e.keyframes[i-2]?e.keyframes[i-2].e:e.keyframes[i-2].s;var a="unidimensional"===r?new Number(s):Object.assign({},s);return a.time=e.keyframes[i-1].t/e.elem.comp.globalData.frameRate,a.value="unidimensional"===r?s[0]:s,a},t.valueAtTime=e.getValueAtTime,t.speedAtTime=e.getSpeedAtTime,t.velocityAtTime=e.getVelocityAtTime,t.propertyGroup=e.propertyGroup}function i(){return t}return function(s){return s?"unidimensional"===s.propType?function(e){e&&"pv"in e||(e=t);var i=1/e.mult,s=e.pv*i,a=new Number(s);return a.value=s,r(a,e,"unidimensional"),function(){return e.k&&e.getValue(),s=e.v*i,a.value!==s&&((a=new Number(s)).value=s,a[0]=s,r(a,e,"unidimensional")),a}}(s):function(t){t&&"pv"in t||(t=e);var i=1/t.mult,s=t.data&&t.data.l||t.pv.length,a=createTypedArray("float32",s),n=createTypedArray("float32",s);return a.value=n,r(a,t,"multidimensional"),function(){t.k&&t.getValue();for(var e=0;e<s;e+=1)n[e]=t.v[e]*i,a[e]=n[e];return a}}(s):i}}(),TransformExpressionInterface=function(t){function e(t){switch(t){case"scale":case"Scale":case"ADBE Scale":case 6:return e.scale;case"rotation":case"Rotation":case"ADBE Rotation":case"ADBE Rotate Z":case 10:return e.rotation;case"ADBE Rotate X":return e.xRotation;case"ADBE Rotate Y":return e.yRotation;case"position":case"Position":case"ADBE Position":case 2:return e.position;case"ADBE Position_0":return e.xPosition;case"ADBE Position_1":return e.yPosition;case"ADBE Position_2":return e.zPosition;case"anchorPoint":case"AnchorPoint":case"Anchor Point":case"ADBE AnchorPoint":case 1:return e.anchorPoint;case"opacity":case"Opacity":case 11:return e.opacity;default:return null}}var r,i,s,a;return Object.defineProperty(e,"rotation",{get:ExpressionPropertyInterface(t.r||t.rz)}),Object.defineProperty(e,"zRotation",{get:ExpressionPropertyInterface(t.rz||t.r)}),Object.defineProperty(e,"xRotation",{get:ExpressionPropertyInterface(t.rx)}),Object.defineProperty(e,"yRotation",{get:ExpressionPropertyInterface(t.ry)}),Object.defineProperty(e,"scale",{get:ExpressionPropertyInterface(t.s)}),t.p?a=ExpressionPropertyInterface(t.p):(r=ExpressionPropertyInterface(t.px),i=ExpressionPropertyInterface(t.py),t.pz&&(s=ExpressionPropertyInterface(t.pz))),Object.defineProperty(e,"position",{get:function(){return t.p?a():[r(),i(),s?s():0]}}),Object.defineProperty(e,"xPosition",{get:ExpressionPropertyInterface(t.px)}),Object.defineProperty(e,"yPosition",{get:ExpressionPropertyInterface(t.py)}),Object.defineProperty(e,"zPosition",{get:ExpressionPropertyInterface(t.pz)}),Object.defineProperty(e,"anchorPoint",{get:ExpressionPropertyInterface(t.a)}),Object.defineProperty(e,"opacity",{get:ExpressionPropertyInterface(t.o)}),Object.defineProperty(e,"skew",{get:ExpressionPropertyInterface(t.sk)}),Object.defineProperty(e,"skewAxis",{get:ExpressionPropertyInterface(t.sa)}),Object.defineProperty(e,"orientation",{get:ExpressionPropertyInterface(t.or)}),e},LayerExpressionInterface=function(){function t(t){var e=new Matrix;void 0!==t?this._elem.finalTransform.mProp.getValueAtTime(t).clone(e):this._elem.finalTransform.mProp.applyToMatrix(e);return e}function e(t,e){var r=this.getMatrix(e);return r.props[12]=0,r.props[13]=0,r.props[14]=0,this.applyPoint(r,t)}function r(t,e){var r=this.getMatrix(e);return this.applyPoint(r,t)}function i(t,e){var r=this.getMatrix(e);return r.props[12]=0,r.props[13]=0,r.props[14]=0,this.invertPoint(r,t)}function s(t,e){var r=this.getMatrix(e);return this.invertPoint(r,t)}function a(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var r,i=this._elem.hierarchy.length;for(r=0;r<i;r+=1)this._elem.hierarchy[r].finalTransform.mProp.applyToMatrix(t)}return t.applyToPointArray(e[0],e[1],e[2]||0)}function n(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var r,i=this._elem.hierarchy.length;for(r=0;r<i;r+=1)this._elem.hierarchy[r].finalTransform.mProp.applyToMatrix(t)}return t.inversePoint(e)}function o(t){var e=new Matrix;if(e.reset(),this._elem.finalTransform.mProp.applyToMatrix(e),this._elem.hierarchy&&this._elem.hierarchy.length){var r,i=this._elem.hierarchy.length;for(r=0;r<i;r+=1)this._elem.hierarchy[r].finalTransform.mProp.applyToMatrix(e);return e.inversePoint(t)}return e.inversePoint(t)}function h(){return[1,1,1,1]}return function(l){var p;function f(t){switch(t){case"ADBE Root Vectors Group":case"Contents":case 2:return f.shapeInterface;case 1:case 6:case"Transform":case"transform":case"ADBE Transform Group":return p;case 4:case"ADBE Effect Parade":case"effects":case"Effects":return f.effect;case"ADBE Text Properties":return f.textInterface;default:return null}}f.getMatrix=t,f.invertPoint=n,f.applyPoint=a,f.toWorld=r,f.toWorldVec=e,f.fromWorld=s,f.fromWorldVec=i,f.toComp=r,f.fromComp=o,f.sampleImage=h,f.sourceRectAtTime=l.sourceRectAtTime.bind(l),f._elem=l;var c=getDescriptor(p=TransformExpressionInterface(l.finalTransform.mProp),"anchorPoint");return Object.defineProperties(f,{hasParent:{get:function(){return l.hierarchy.length}},parent:{get:function(){return l.hierarchy[0].layerInterface}},rotation:getDescriptor(p,"rotation"),scale:getDescriptor(p,"scale"),position:getDescriptor(p,"position"),opacity:getDescriptor(p,"opacity"),anchorPoint:c,anchor_point:c,transform:{get:function(){return p}},active:{get:function(){return l.isInRange}}}),f.startTime=l.data.st,f.index=l.data.ind,f.source=l.data.refId,f.height=0===l.data.ty?l.data.h:100,f.width=0===l.data.ty?l.data.w:100,f.inPoint=l.data.ip/l.comp.globalData.frameRate,f.outPoint=l.data.op/l.comp.globalData.frameRate,f._name=l.data.nm,f.registerMaskInterface=function(t){f.mask=new MaskManagerInterface(t,l)},f.registerEffectsInterface=function(t){f.effect=t},f}}(),propertyGroupFactory=function(t,e){return function(r){return(r=void 0===r?1:r)<=0?t:e(r-1)}},PropertyInterface=function(t,e){var r={_name:t};return function(t){return(t=void 0===t?1:t)<=0?r:e(t-1)}},EffectsExpressionInterface=function(){function t(r,i,s,a){function n(t){for(var e=r.ef,i=0,s=e.length;i<s;){if(t===e[i].nm||t===e[i].mn||t===e[i].ix)return 5===e[i].ty?l[i]:l[i]();i+=1}throw new Error}var o,h=propertyGroupFactory(n,s),l=[],p=r.ef.length;for(o=0;o<p;o+=1)5===r.ef[o].ty?l.push(t(r.ef[o],i.effectElements[o],i.effectElements[o].propertyGroup,a)):l.push(e(i.effectElements[o],r.ef[o].ty,a,h));return"ADBE Color Control"===r.mn&&Object.defineProperty(n,"color",{get:function(){return l[0]()}}),Object.defineProperties(n,{numProperties:{get:function(){return r.np}},_name:{value:r.nm},propertyGroup:{value:h}}),n.enabled=0!==r.en,n.active=n.enabled,n}function e(t,e,r,i){var s=ExpressionPropertyInterface(t.p);return t.p.setGroupProperty&&t.p.setGroupProperty(PropertyInterface("",i)),function(){return 10===e?r.comp.compInterface(t.p.v):s()}}return{createEffectsInterface:function(e,r){if(e.effectsManager){var i,s=[],a=e.data.ef,n=e.effectsManager.effectElements.length;for(i=0;i<n;i+=1)s.push(t(a[i],e.effectsManager.effectElements[i],r,e));var o=e.data.ef||[],h=function(t){for(i=0,n=o.length;i<n;){if(t===o[i].nm||t===o[i].mn||t===o[i].ix)return s[i];i+=1}return null};return Object.defineProperty(h,"numProperties",{get:function(){return o.length}}),h}return null}}}(),ShapePathInterface=function(t,e,r){var i=e.sh;function s(t){return"Shape"===t||"shape"===t||"Path"===t||"path"===t||"ADBE Vector Shape"===t||2===t?s.path:null}var a=propertyGroupFactory(s,r);return i.setGroupProperty(PropertyInterface("Path",a)),Object.defineProperties(s,{path:{get:function(){return i.k&&i.getValue(),i}},shape:{get:function(){return i.k&&i.getValue(),i}},_name:{value:t.nm},ix:{value:t.ix},propertyIndex:{value:t.ix},mn:{value:t.mn},propertyGroup:{value:r}}),s},ShapeExpressionInterface=function(){function t(t,o,m){var u,d=[],y=t?t.length:0;for(u=0;u<y;u+=1)"gr"===t[u].ty?d.push(e(t[u],o[u],m)):"fl"===t[u].ty?d.push(r(t[u],o[u],m)):"st"===t[u].ty?d.push(a(t[u],o[u],m)):"tm"===t[u].ty?d.push(n(t[u],o[u],m)):"tr"===t[u].ty||("el"===t[u].ty?d.push(h(t[u],o[u],m)):"sr"===t[u].ty?d.push(l(t[u],o[u],m)):"sh"===t[u].ty?d.push(ShapePathInterface(t[u],o[u],m)):"rc"===t[u].ty?d.push(p(t[u],o[u],m)):"rd"===t[u].ty?d.push(f(t[u],o[u],m)):"rp"===t[u].ty?d.push(c(t[u],o[u],m)):"gf"===t[u].ty?d.push(i(t[u],o[u],m)):d.push(s(t[u],o[u])));return d}function e(e,r,i){var s=function(t){switch(t){case"ADBE Vectors Group":case"Contents":case 2:return s.content;default:return s.transform}};s.propertyGroup=propertyGroupFactory(s,i);var a=function(e,r,i){var s,a=function(t){for(var e=0,r=s.length;e<r;){if(s[e]._name===t||s[e].mn===t||s[e].propertyIndex===t||s[e].ix===t||s[e].ind===t)return s[e];e+=1}return"number"==typeof t?s[t-1]:null};a.propertyGroup=propertyGroupFactory(a,i),s=t(e.it,r.it,a.propertyGroup),a.numProperties=s.length;var n=o(e.it[e.it.length-1],r.it[r.it.length-1],a.propertyGroup);return a.transform=n,a.propertyIndex=e.cix,a._name=e.nm,a}(e,r,s.propertyGroup),n=o(e.it[e.it.length-1],r.it[r.it.length-1],s.propertyGroup);return s.content=a,s.transform=n,Object.defineProperty(s,"_name",{get:function(){return e.nm}}),s.numProperties=e.np,s.propertyIndex=e.ix,s.nm=e.nm,s.mn=e.mn,s}function r(t,e,r){function i(t){return"Color"===t||"color"===t?i.color:"Opacity"===t||"opacity"===t?i.opacity:null}return Object.defineProperties(i,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",r)),e.o.setGroupProperty(PropertyInterface("Opacity",r)),i}function i(t,e,r){function i(t){return"Start Point"===t||"start point"===t?i.startPoint:"End Point"===t||"end point"===t?i.endPoint:"Opacity"===t||"opacity"===t?i.opacity:null}return Object.defineProperties(i,{startPoint:{get:ExpressionPropertyInterface(e.s)},endPoint:{get:ExpressionPropertyInterface(e.e)},opacity:{get:ExpressionPropertyInterface(e.o)},type:{get:function(){return"a"}},_name:{value:t.nm},mn:{value:t.mn}}),e.s.setGroupProperty(PropertyInterface("Start Point",r)),e.e.setGroupProperty(PropertyInterface("End Point",r)),e.o.setGroupProperty(PropertyInterface("Opacity",r)),i}function s(){return function(){return null}}function a(t,e,r){var i,s=propertyGroupFactory(l,r),a=propertyGroupFactory(h,s);function n(r){Object.defineProperty(h,t.d[r].nm,{get:ExpressionPropertyInterface(e.d.dataProps[r].p)})}var o=t.d?t.d.length:0,h={};for(i=0;i<o;i+=1)n(i),e.d.dataProps[i].p.setGroupProperty(a);function l(t){return"Color"===t||"color"===t?l.color:"Opacity"===t||"opacity"===t?l.opacity:"Stroke Width"===t||"stroke width"===t?l.strokeWidth:null}return Object.defineProperties(l,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},strokeWidth:{get:ExpressionPropertyInterface(e.w)},dash:{get:function(){return h}},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",s)),e.o.setGroupProperty(PropertyInterface("Opacity",s)),e.w.setGroupProperty(PropertyInterface("Stroke Width",s)),l}function n(t,e,r){function i(e){return e===t.e.ix||"End"===e||"end"===e?i.end:e===t.s.ix?i.start:e===t.o.ix?i.offset:null}var s=propertyGroupFactory(i,r);return i.propertyIndex=t.ix,e.s.setGroupProperty(PropertyInterface("Start",s)),e.e.setGroupProperty(PropertyInterface("End",s)),e.o.setGroupProperty(PropertyInterface("Offset",s)),i.propertyIndex=t.ix,i.propertyGroup=r,Object.defineProperties(i,{start:{get:ExpressionPropertyInterface(e.s)},end:{get:ExpressionPropertyInterface(e.e)},offset:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm}}),i.mn=t.mn,i}function o(t,e,r){function i(e){return t.a.ix===e||"Anchor Point"===e?i.anchorPoint:t.o.ix===e||"Opacity"===e?i.opacity:t.p.ix===e||"Position"===e?i.position:t.r.ix===e||"Rotation"===e||"ADBE Vector Rotation"===e?i.rotation:t.s.ix===e||"Scale"===e?i.scale:t.sk&&t.sk.ix===e||"Skew"===e?i.skew:t.sa&&t.sa.ix===e||"Skew Axis"===e?i.skewAxis:null}var s=propertyGroupFactory(i,r);return e.transform.mProps.o.setGroupProperty(PropertyInterface("Opacity",s)),e.transform.mProps.p.setGroupProperty(PropertyInterface("Position",s)),e.transform.mProps.a.setGroupProperty(PropertyInterface("Anchor Point",s)),e.transform.mProps.s.setGroupProperty(PropertyInterface("Scale",s)),e.transform.mProps.r.setGroupProperty(PropertyInterface("Rotation",s)),e.transform.mProps.sk&&(e.transform.mProps.sk.setGroupProperty(PropertyInterface("Skew",s)),e.transform.mProps.sa.setGroupProperty(PropertyInterface("Skew Angle",s))),e.transform.op.setGroupProperty(PropertyInterface("Opacity",s)),Object.defineProperties(i,{opacity:{get:ExpressionPropertyInterface(e.transform.mProps.o)},position:{get:ExpressionPropertyInterface(e.transform.mProps.p)},anchorPoint:{get:ExpressionPropertyInterface(e.transform.mProps.a)},scale:{get:ExpressionPropertyInterface(e.transform.mProps.s)},rotation:{get:ExpressionPropertyInterface(e.transform.mProps.r)},skew:{get:ExpressionPropertyInterface(e.transform.mProps.sk)},skewAxis:{get:ExpressionPropertyInterface(e.transform.mProps.sa)},_name:{value:t.nm}}),i.ty="tr",i.mn=t.mn,i.propertyGroup=r,i}function h(t,e,r){function i(e){return t.p.ix===e?i.position:t.s.ix===e?i.size:null}var s=propertyGroupFactory(i,r);i.propertyIndex=t.ix;var a="tm"===e.sh.ty?e.sh.prop:e.sh;return a.s.setGroupProperty(PropertyInterface("Size",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),Object.defineProperties(i,{size:{get:ExpressionPropertyInterface(a.s)},position:{get:ExpressionPropertyInterface(a.p)},_name:{value:t.nm}}),i.mn=t.mn,i}function l(t,e,r){function i(e){return t.p.ix===e?i.position:t.r.ix===e?i.rotation:t.pt.ix===e?i.points:t.or.ix===e||"ADBE Vector Star Outer Radius"===e?i.outerRadius:t.os.ix===e?i.outerRoundness:!t.ir||t.ir.ix!==e&&"ADBE Vector Star Inner Radius"!==e?t.is&&t.is.ix===e?i.innerRoundness:null:i.innerRadius}var s=propertyGroupFactory(i,r),a="tm"===e.sh.ty?e.sh.prop:e.sh;return i.propertyIndex=t.ix,a.or.setGroupProperty(PropertyInterface("Outer Radius",s)),a.os.setGroupProperty(PropertyInterface("Outer Roundness",s)),a.pt.setGroupProperty(PropertyInterface("Points",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),t.ir&&(a.ir.setGroupProperty(PropertyInterface("Inner Radius",s)),a.is.setGroupProperty(PropertyInterface("Inner Roundness",s))),Object.defineProperties(i,{position:{get:ExpressionPropertyInterface(a.p)},rotation:{get:ExpressionPropertyInterface(a.r)},points:{get:ExpressionPropertyInterface(a.pt)},outerRadius:{get:ExpressionPropertyInterface(a.or)},outerRoundness:{get:ExpressionPropertyInterface(a.os)},innerRadius:{get:ExpressionPropertyInterface(a.ir)},innerRoundness:{get:ExpressionPropertyInterface(a.is)},_name:{value:t.nm}}),i.mn=t.mn,i}function p(t,e,r){function i(e){return t.p.ix===e?i.position:t.r.ix===e?i.roundness:t.s.ix===e||"Size"===e||"ADBE Vector Rect Size"===e?i.size:null}var s=propertyGroupFactory(i,r),a="tm"===e.sh.ty?e.sh.prop:e.sh;return i.propertyIndex=t.ix,a.p.setGroupProperty(PropertyInterface("Position",s)),a.s.setGroupProperty(PropertyInterface("Size",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),Object.defineProperties(i,{position:{get:ExpressionPropertyInterface(a.p)},roundness:{get:ExpressionPropertyInterface(a.r)},size:{get:ExpressionPropertyInterface(a.s)},_name:{value:t.nm}}),i.mn=t.mn,i}function f(t,e,r){function i(e){return t.r.ix===e||"Round Corners 1"===e?i.radius:null}var s=propertyGroupFactory(i,r),a=e;return i.propertyIndex=t.ix,a.rd.setGroupProperty(PropertyInterface("Radius",s)),Object.defineProperties(i,{radius:{get:ExpressionPropertyInterface(a.rd)},_name:{value:t.nm}}),i.mn=t.mn,i}function c(t,e,r){function i(e){return t.c.ix===e||"Copies"===e?i.copies:t.o.ix===e||"Offset"===e?i.offset:null}var s=propertyGroupFactory(i,r),a=e;return i.propertyIndex=t.ix,a.c.setGroupProperty(PropertyInterface("Copies",s)),a.o.setGroupProperty(PropertyInterface("Offset",s)),Object.defineProperties(i,{copies:{get:ExpressionPropertyInterface(a.c)},offset:{get:ExpressionPropertyInterface(a.o)},_name:{value:t.nm}}),i.mn=t.mn,i}return function(e,r,i){var s;function a(t){if("number"==typeof t)return 0===(t=void 0===t?1:t)?i:s[t-1];for(var e=0,r=s.length;e<r;){if(s[e]._name===t)return s[e];e+=1}return null}return a.propertyGroup=propertyGroupFactory(a,(function(){return i})),s=t(e,r,a.propertyGroup),a.numProperties=s.length,a._name="Contents",a}}(),TextExpressionInterface=function(t){var e;function r(t){return"ADBE Text Document"===t?r.sourceText:null}return Object.defineProperty(r,"sourceText",{get:function(){t.textProperty.getValue();var r=t.textProperty.currentData.t;return e&&r===e.value||((e=new String(r)).value=r||new String(r),Object.defineProperty(e,"style",{get:function(){return{fillColor:t.textProperty.currentData.fc}}})),e}}),r};function _typeof(t){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof(t)}var FootageInterface=(dataInterfaceFactory=function(t){function e(t){return"Outline"===t?e.outlineInterface():null}return e._name="Outline",e.outlineInterface=function(t){var e="",r=t.getFootageData();function i(t){if(r[t])return e=t,"object"===_typeof(r=r[t])?i:r;var s=t.indexOf(e);if(-1!==s){var a=parseInt(t.substr(s+e.length),10);return"object"===_typeof(r=r[a])?i:r}return""}return function(){return e="",r=t.getFootageData(),i}}(t),e},function(t){function e(t){return"Data"===t?e.dataInterface:null}return e._name="Data",e.dataInterface=dataInterfaceFactory(t),e}),dataInterfaceFactory,interfaces={layer:LayerExpressionInterface,effects:EffectsExpressionInterface,comp:CompExpressionInterface,shape:ShapeExpressionInterface,text:TextExpressionInterface,footage:FootageInterface};function getInterface(t){return interfaces[t]||null}var expressionHelpers={searchExpressions:function(t,e,r){e.x&&(r.k=!0,r.x=!0,r.initiateExpression=ExpressionManager.initiateExpression,r.effectsSequence.push(r.initiateExpression(t,e,r).bind(r)))},getSpeedAtTime:function(t){var e=this.getValueAtTime(t),r=this.getValueAtTime(t+-.01),i=0;if(e.length){var s;for(s=0;s<e.length;s+=1)i+=Math.pow(r[s]-e[s],2);i=100*Math.sqrt(i)}else i=0;return i},getVelocityAtTime:function(t){if(void 0!==this.vel)return this.vel;var e,r,i=-.001,s=this.getValueAtTime(t),a=this.getValueAtTime(t+i);if(s.length)for(e=createTypedArray("float32",s.length),r=0;r<s.length;r+=1)e[r]=(a[r]-s[r])/i;else e=(a-s)/i;return e},getValueAtTime:function(t){return t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastFrame&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastFrame<t?this._cachingAtTime.lastIndex:0,this._cachingAtTime.value=this.interpolateValue(t,this._cachingAtTime),this._cachingAtTime.lastFrame=t),this._cachingAtTime.value},getStaticValueAtTime:function(){return this.pv},setGroupProperty:function(t){this.propertyGroup=t}};function addPropertyDecorator(){function t(t,e,r){if(!this.k||!this.keyframes)return this.pv;t=t?t.toLowerCase():"";var i,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[l.length-1].t;if(h<=p)return this.pv;if(r?s=p-(i=e?Math.abs(p-this.elem.comp.globalData.frameRate*e):Math.max(0,p-this.elem.data.ip)):((!e||e>l.length-1)&&(e=l.length-1),i=p-(s=l[l.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/i)%2!=0)return this.getValueAtTime((i-(h-s)%i+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime(p/this.comp.globalData.frameRate,0),m=this.getValueAtTime(((h-s)%i+s)/this.comp.globalData.frameRate,0),u=Math.floor((h-s)/i);if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=(c[a]-f[a])*u+m[a];return o}return(c-f)*u+m}if("continue"===t){var d=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p-.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(d.length)).length,a=0;a<n;a+=1)o[a]=d[a]+(d[a]-y[a])*((h-p)/this.comp.globalData.frameRate)/5e-4;return o}return d+(h-p)/.001*(d-y)}}return this.getValueAtTime(((h-s)%i+s)/this.comp.globalData.frameRate,0)}function e(t,e,r){if(!this.k)return this.pv;t=t?t.toLowerCase():"";var i,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[0].t;if(h>=p)return this.pv;if(r?s=p+(i=e?Math.abs(this.elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-p)):((!e||e>l.length-1)&&(e=l.length-1),i=(s=l[e].t)-p),"pingpong"===t){if(Math.floor((p-h)/i)%2==0)return this.getValueAtTime(((p-h)%i+p)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(p/this.comp.globalData.frameRate,0),c=this.getValueAtTime(s/this.comp.globalData.frameRate,0),m=this.getValueAtTime((i-(p-h)%i+p)/this.comp.globalData.frameRate,0),u=Math.floor((p-h)/i)+1;if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=m[a]-(c[a]-f[a])*u;return o}return m-(c-f)*u}if("continue"===t){var d=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p+.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(d.length)).length,a=0;a<n;a+=1)o[a]=d[a]+(d[a]-y[a])*(p-h)/.001;return o}return d+(d-y)*(p-h)/.001}}return this.getValueAtTime((i-((p-h)%i+p))/this.comp.globalData.frameRate,0)}function r(t,e){if(!this.k)return this.pv;if(t=.5*(t||.4),(e=Math.floor(e||5))<=1)return this.pv;var r,i,s=this.comp.renderedFrame/this.comp.globalData.frameRate,a=s-t,n=e>1?(s+t-a)/(e-1):1,o=0,h=0;for(r=this.pv.length?createTypedArray("float32",this.pv.length):0;o<e;){if(i=this.getValueAtTime(a+o*n),this.pv.length)for(h=0;h<this.pv.length;h+=1)r[h]+=i[h];else r+=i;o+=1}if(this.pv.length)for(h=0;h<this.pv.length;h+=1)r[h]/=e;else r/=e;return r}function i(t){this._transformCachingAtTime||(this._transformCachingAtTime={v:new Matrix});var e=this._transformCachingAtTime.v;if(e.cloneFromProps(this.pre.props),this.appliedTransformations<1){var r=this.a.getValueAtTime(t);e.translate(-r[0]*this.a.mult,-r[1]*this.a.mult,r[2]*this.a.mult)}if(this.appliedTransformations<2){var i=this.s.getValueAtTime(t);e.scale(i[0]*this.s.mult,i[1]*this.s.mult,i[2]*this.s.mult)}if(this.sk&&this.appliedTransformations<3){var s=this.sk.getValueAtTime(t),a=this.sa.getValueAtTime(t);e.skewFromAxis(-s*this.sk.mult,a*this.sa.mult)}if(this.r&&this.appliedTransformations<4){var n=this.r.getValueAtTime(t);e.rotate(-n*this.r.mult)}else if(!this.r&&this.appliedTransformations<4){var o=this.rz.getValueAtTime(t),h=this.ry.getValueAtTime(t),l=this.rx.getValueAtTime(t),p=this.or.getValueAtTime(t);e.rotateZ(-o*this.rz.mult).rotateY(h*this.ry.mult).rotateX(l*this.rx.mult).rotateZ(-p[2]*this.or.mult).rotateY(p[1]*this.or.mult).rotateX(p[0]*this.or.mult)}if(this.data.p&&this.data.p.s){var f=this.px.getValueAtTime(t),c=this.py.getValueAtTime(t);if(this.data.p.z){var m=this.pz.getValueAtTime(t);e.translate(f*this.px.mult,c*this.py.mult,-m*this.pz.mult)}else e.translate(f*this.px.mult,c*this.py.mult,0)}else{var u=this.p.getValueAtTime(t);e.translate(u[0]*this.p.mult,u[1]*this.p.mult,-u[2]*this.p.mult)}return e}function s(){return this.v.clone(new Matrix)}var a=TransformPropertyFactory.getTransformProperty;TransformPropertyFactory.getTransformProperty=function(t,e,r){var n=a(t,e,r);return n.dynamicProperties.length?n.getValueAtTime=i.bind(n):n.getValueAtTime=s.bind(n),n.setGroupProperty=expressionHelpers.setGroupProperty,n};var n=PropertyFactory.getProp;PropertyFactory.getProp=function(i,s,a,o,h){var l=n(i,s,a,o,h);l.kf?l.getValueAtTime=expressionHelpers.getValueAtTime.bind(l):l.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(l),l.setGroupProperty=expressionHelpers.setGroupProperty,l.loopOut=t,l.loopIn=e,l.smooth=r,l.getVelocityAtTime=expressionHelpers.getVelocityAtTime.bind(l),l.getSpeedAtTime=expressionHelpers.getSpeedAtTime.bind(l),l.numKeys=1===s.a?s.k.length:0,l.propertyIndex=s.ix;var p=0;return 0!==a&&(p=createTypedArray("float32",1===s.a?s.k[0].s.length:s.k.length)),l._cachingAtTime={lastFrame:initialDefaultFrame,lastIndex:0,value:p},expressionHelpers.searchExpressions(i,s,l),l.k&&h.addDynamicProperty(l),l};var o=ShapePropertyFactory.getConstructorFunction(),h=ShapePropertyFactory.getKeyframedConstructorFunction();function l(){}l.prototype={vertices:function(t,e){this.k&&this.getValue();var r,i=this.v;void 0!==e&&(i=this.getValueAtTime(e,0));var s=i._length,a=i[t],n=i.v,o=createSizedArray(s);for(r=0;r<s;r+=1)o[r]="i"===t||"o"===t?[a[r][0]-n[r][0],a[r][1]-n[r][1]]:[a[r][0],a[r][1]];return o},points:function(t){return this.vertices("v",t)},inTangents:function(t){return this.vertices("i",t)},outTangents:function(t){return this.vertices("o",t)},isClosed:function(){return this.v.c},pointOnPath:function(t,e){var r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0)),this._segmentsLength||(this._segmentsLength=bez.getSegmentsLength(r));for(var i,s=this._segmentsLength,a=s.lengths,n=s.totalLength*t,o=0,h=a.length,l=0;o<h;){if(l+a[o].addedLength>n){var p=o,f=r.c&&o===h-1?0:o+1,c=(n-l)/a[o].addedLength;i=bez.getPointInSegment(r.v[p],r.v[f],r.o[p],r.i[f],c,a[o]);break}l+=a[o].addedLength,o+=1}return i||(i=r.c?[r.v[0][0],r.v[0][1]]:[r.v[r._length-1][0],r.v[r._length-1][1]]),i},vectorOnPath:function(t,e,r){1==t?t=this.v.c:0==t&&(t=.999);var i=this.pointOnPath(t,e),s=this.pointOnPath(t+.001,e),a=s[0]-i[0],n=s[1]-i[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return 0===o?[0,0]:"tangent"===r?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([l],o),extendPrototype([l],h),h.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shapePool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime<t?this._caching.lastIndex:0,this._cachingAtTime.lastTime=t,this.interpolateShape(t,this._cachingAtTime.shapeValue,this._cachingAtTime)),this._cachingAtTime.shapeValue},h.prototype.initiateExpression=ExpressionManager.initiateExpression;var p=ShapePropertyFactory.getShapeProp;ShapePropertyFactory.getShapeProp=function(t,e,r,i,s){var a=p(t,e,r,i,s);return a.propertyIndex=e.ix,a.lock=!1,3===r?expressionHelpers.searchExpressions(t,e.pt,a):4===r&&expressionHelpers.searchExpressions(t,e.ks,a),a.k&&t.addDynamicProperty(a),a}}function initialize$1(){addPropertyDecorator()}function addDecorator(){TextProperty.prototype.getExpressionValue=function(t,e){var r=this.calculateExpression(e);if(t.t!==r){var i={};return this.copyData(i,t),i.t=r.toString(),i.__complete=!1,i}return t},TextProperty.prototype.searchProperty=function(){var t=this.searchKeyframes(),e=this.searchExpressions();return this.kf=t||e,this.kf},TextProperty.prototype.searchExpressions=function(){return this.data.d.x?(this.calculateExpression=ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this),this.addEffect(this.getExpressionValue.bind(this)),!0):null}}function initialize(){addDecorator()}function SVGComposableEffect(){}SVGComposableEffect.prototype={createMergeNode:function(t,e){var r,i,s=createNS("feMerge");for(s.setAttribute("result",t),i=0;i<e.length;i+=1)(r=createNS("feMergeNode")).setAttribute("in",e[i]),s.appendChild(r),s.appendChild(r);return s}};var linearFilterValue="0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0";function SVGTintFilter(t,e,r,i,s){this.filterManager=e;var a=createNS("feColorMatrix");a.setAttribute("type","matrix"),a.setAttribute("color-interpolation-filters","linearRGB"),a.setAttribute("values",linearFilterValue+" 1 0"),this.linearFilter=a,a.setAttribute("result",i+"_tint_1"),t.appendChild(a),(a=createNS("feColorMatrix")).setAttribute("type","matrix"),a.setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),a.setAttribute("result",i+"_tint_2"),t.appendChild(a),this.matrixFilter=a;var n=this.createMergeNode(i,[s,i+"_tint_1",i+"_tint_2"]);t.appendChild(n)}function SVGFillFilter(t,e,r,i){this.filterManager=e;var s=createNS("feColorMatrix");s.setAttribute("type","matrix"),s.setAttribute("color-interpolation-filters","sRGB"),s.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),s.setAttribute("result",i),t.appendChild(s),this.matrixFilter=s}function SVGStrokeEffect(t,e,r){this.initialized=!1,this.filterManager=e,this.elem=r,this.paths=[]}function SVGTritoneFilter(t,e,r,i){this.filterManager=e;var s=createNS("feColorMatrix");s.setAttribute("type","matrix"),s.setAttribute("color-interpolation-filters","linearRGB"),s.setAttribute("values","0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0"),t.appendChild(s);var a=createNS("feComponentTransfer");a.setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("result",i),this.matrixFilter=a;var n=createNS("feFuncR");n.setAttribute("type","table"),a.appendChild(n),this.feFuncR=n;var o=createNS("feFuncG");o.setAttribute("type","table"),a.appendChild(o),this.feFuncG=o;var h=createNS("feFuncB");h.setAttribute("type","table"),a.appendChild(h),this.feFuncB=h,t.appendChild(a)}function SVGProLevelsFilter(t,e,r,i){this.filterManager=e;var s=this.filterManager.effectElements,a=createNS("feComponentTransfer");(s[10].p.k||0!==s[10].p.v||s[11].p.k||1!==s[11].p.v||s[12].p.k||1!==s[12].p.v||s[13].p.k||0!==s[13].p.v||s[14].p.k||1!==s[14].p.v)&&(this.feFuncR=this.createFeFunc("feFuncR",a)),(s[17].p.k||0!==s[17].p.v||s[18].p.k||1!==s[18].p.v||s[19].p.k||1!==s[19].p.v||s[20].p.k||0!==s[20].p.v||s[21].p.k||1!==s[21].p.v)&&(this.feFuncG=this.createFeFunc("feFuncG",a)),(s[24].p.k||0!==s[24].p.v||s[25].p.k||1!==s[25].p.v||s[26].p.k||1!==s[26].p.v||s[27].p.k||0!==s[27].p.v||s[28].p.k||1!==s[28].p.v)&&(this.feFuncB=this.createFeFunc("feFuncB",a)),(s[31].p.k||0!==s[31].p.v||s[32].p.k||1!==s[32].p.v||s[33].p.k||1!==s[33].p.v||s[34].p.k||0!==s[34].p.v||s[35].p.k||1!==s[35].p.v)&&(this.feFuncA=this.createFeFunc("feFuncA",a)),(this.feFuncR||this.feFuncG||this.feFuncB||this.feFuncA)&&(a.setAttribute("color-interpolation-filters","sRGB"),t.appendChild(a)),(s[3].p.k||0!==s[3].p.v||s[4].p.k||1!==s[4].p.v||s[5].p.k||1!==s[5].p.v||s[6].p.k||0!==s[6].p.v||s[7].p.k||1!==s[7].p.v)&&((a=createNS("feComponentTransfer")).setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("result",i),t.appendChild(a),this.feFuncRComposed=this.createFeFunc("feFuncR",a),this.feFuncGComposed=this.createFeFunc("feFuncG",a),this.feFuncBComposed=this.createFeFunc("feFuncB",a))}function SVGDropShadowEffect(t,e,r,i,s){var a=e.container.globalData.renderConfig.filterSize,n=e.data.fs||a;t.setAttribute("x",n.x||a.x),t.setAttribute("y",n.y||a.y),t.setAttribute("width",n.width||a.width),t.setAttribute("height",n.height||a.height),this.filterManager=e;var o=createNS("feGaussianBlur");o.setAttribute("in","SourceAlpha"),o.setAttribute("result",i+"_drop_shadow_1"),o.setAttribute("stdDeviation","0"),this.feGaussianBlur=o,t.appendChild(o);var h=createNS("feOffset");h.setAttribute("dx","25"),h.setAttribute("dy","0"),h.setAttribute("in",i+"_drop_shadow_1"),h.setAttribute("result",i+"_drop_shadow_2"),this.feOffset=h,t.appendChild(h);var l=createNS("feFlood");l.setAttribute("flood-color","#00ff00"),l.setAttribute("flood-opacity","1"),l.setAttribute("result",i+"_drop_shadow_3"),this.feFlood=l,t.appendChild(l);var p=createNS("feComposite");p.setAttribute("in",i+"_drop_shadow_3"),p.setAttribute("in2",i+"_drop_shadow_2"),p.setAttribute("operator","in"),p.setAttribute("result",i+"_drop_shadow_4"),t.appendChild(p);var f=this.createMergeNode(i,[i+"_drop_shadow_4",s]);t.appendChild(f)}extendPrototype([SVGComposableEffect],SVGTintFilter),SVGTintFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[0].p.v,r=this.filterManager.effectElements[1].p.v,i=this.filterManager.effectElements[2].p.v/100;this.linearFilter.setAttribute("values",linearFilterValue+" "+i+" 0"),this.matrixFilter.setAttribute("values",r[0]-e[0]+" 0 0 0 "+e[0]+" "+(r[1]-e[1])+" 0 0 0 "+e[1]+" "+(r[2]-e[2])+" 0 0 0 "+e[2]+" 0 0 0 1 0")}},SVGFillFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[2].p.v,r=this.filterManager.effectElements[6].p.v;this.matrixFilter.setAttribute("values","0 0 0 0 "+e[0]+" 0 0 0 0 "+e[1]+" 0 0 0 0 "+e[2]+" 0 0 0 "+r+" 0")}},SVGStrokeEffect.prototype.initialize=function(){var t,e,r,i,s=this.elem.layerElement.children||this.elem.layerElement.childNodes;for(1===this.filterManager.effectElements[1].p.v?(i=this.elem.maskManager.masksProperties.length,r=0):i=(r=this.filterManager.effectElements[0].p.v-1)+1,(e=createNS("g")).setAttribute("fill","none"),e.setAttribute("stroke-linecap","round"),e.setAttribute("stroke-dashoffset",1);r<i;r+=1)t=createNS("path"),e.appendChild(t),this.paths.push({p:t,m:r});if(3===this.filterManager.effectElements[10].p.v){var a=createNS("mask"),n=createElementID();a.setAttribute("id",n),a.setAttribute("mask-type","alpha"),a.appendChild(e),this.elem.globalData.defs.appendChild(a);var o=createNS("g");for(o.setAttribute("mask","url("+getLocationHref()+"#"+n+")");s[0];)o.appendChild(s[0]);this.elem.layerElement.appendChild(o),this.masker=a,e.setAttribute("stroke","#fff")}else if(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v){if(2===this.filterManager.effectElements[10].p.v)for(s=this.elem.layerElement.children||this.elem.layerElement.childNodes;s.length;)this.elem.layerElement.removeChild(s[0]);this.elem.layerElement.appendChild(e),this.elem.layerElement.removeAttribute("mask"),e.setAttribute("stroke","#fff")}this.initialized=!0,this.pathMasker=e},SVGStrokeEffect.prototype.renderFrame=function(t){var e;this.initialized||this.initialize();var r,i,s=this.paths.length;for(e=0;e<s;e+=1)if(-1!==this.paths[e].m&&(r=this.elem.maskManager.viewData[this.paths[e].m],i=this.paths[e].p,(t||this.filterManager._mdf||r.prop._mdf)&&i.setAttribute("d",r.lastPath),t||this.filterManager.effectElements[9].p._mdf||this.filterManager.effectElements[4].p._mdf||this.filterManager.effectElements[7].p._mdf||this.filterManager.effectElements[8].p._mdf||r.prop._mdf)){var a;if(0!==this.filterManager.effectElements[7].p.v||100!==this.filterManager.effectElements[8].p.v){var n=.01*Math.min(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),o=.01*Math.max(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),h=i.getTotalLength();a="0 0 0 "+h*n+" ";var l,p=h*(o-n),f=1+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01,c=Math.floor(p/f);for(l=0;l<c;l+=1)a+="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01+" ";a+="0 "+10*h+" 0 0"}else a="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01;i.setAttribute("stroke-dasharray",a)}if((t||this.filterManager.effectElements[4].p._mdf)&&this.pathMasker.setAttribute("stroke-width",2*this.filterManager.effectElements[4].p.v),(t||this.filterManager.effectElements[6].p._mdf)&&this.pathMasker.setAttribute("opacity",this.filterManager.effectElements[6].p.v),(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v)&&(t||this.filterManager.effectElements[3].p._mdf)){var m=this.filterManager.effectElements[3].p.v;this.pathMasker.setAttribute("stroke","rgb("+bmFloor(255*m[0])+","+bmFloor(255*m[1])+","+bmFloor(255*m[2])+")")}},SVGTritoneFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[0].p.v,r=this.filterManager.effectElements[1].p.v,i=this.filterManager.effectElements[2].p.v,s=i[0]+" "+r[0]+" "+e[0],a=i[1]+" "+r[1]+" "+e[1],n=i[2]+" "+r[2]+" "+e[2];this.feFuncR.setAttribute("tableValues",s),this.feFuncG.setAttribute("tableValues",a),this.feFuncB.setAttribute("tableValues",n)}},SVGProLevelsFilter.prototype.createFeFunc=function(t,e){var r=createNS(t);return r.setAttribute("type","table"),e.appendChild(r),r},SVGProLevelsFilter.prototype.getTableValue=function(t,e,r,i,s){for(var a,n,o=0,h=Math.min(t,e),l=Math.max(t,e),p=Array.call(null,{length:256}),f=0,c=s-i,m=e-t;o<=256;)n=(a=o/256)<=h?m<0?s:i:a>=l?m<0?i:s:i+c*Math.pow((a-t)/m,1/r),p[f]=n,f+=1,o+=256/255;return p.join(" ")},SVGProLevelsFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e,r=this.filterManager.effectElements;this.feFuncRComposed&&(t||r[3].p._mdf||r[4].p._mdf||r[5].p._mdf||r[6].p._mdf||r[7].p._mdf)&&(e=this.getTableValue(r[3].p.v,r[4].p.v,r[5].p.v,r[6].p.v,r[7].p.v),this.feFuncRComposed.setAttribute("tableValues",e),this.feFuncGComposed.setAttribute("tableValues",e),this.feFuncBComposed.setAttribute("tableValues",e)),this.feFuncR&&(t||r[10].p._mdf||r[11].p._mdf||r[12].p._mdf||r[13].p._mdf||r[14].p._mdf)&&(e=this.getTableValue(r[10].p.v,r[11].p.v,r[12].p.v,r[13].p.v,r[14].p.v),this.feFuncR.setAttribute("tableValues",e)),this.feFuncG&&(t||r[17].p._mdf||r[18].p._mdf||r[19].p._mdf||r[20].p._mdf||r[21].p._mdf)&&(e=this.getTableValue(r[17].p.v,r[18].p.v,r[19].p.v,r[20].p.v,r[21].p.v),this.feFuncG.setAttribute("tableValues",e)),this.feFuncB&&(t||r[24].p._mdf||r[25].p._mdf||r[26].p._mdf||r[27].p._mdf||r[28].p._mdf)&&(e=this.getTableValue(r[24].p.v,r[25].p.v,r[26].p.v,r[27].p.v,r[28].p.v),this.feFuncB.setAttribute("tableValues",e)),this.feFuncA&&(t||r[31].p._mdf||r[32].p._mdf||r[33].p._mdf||r[34].p._mdf||r[35].p._mdf)&&(e=this.getTableValue(r[31].p.v,r[32].p.v,r[33].p.v,r[34].p.v,r[35].p.v),this.feFuncA.setAttribute("tableValues",e))}},extendPrototype([SVGComposableEffect],SVGDropShadowEffect),SVGDropShadowEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){if((t||this.filterManager.effectElements[4].p._mdf)&&this.feGaussianBlur.setAttribute("stdDeviation",this.filterManager.effectElements[4].p.v/4),t||this.filterManager.effectElements[0].p._mdf){var e=this.filterManager.effectElements[0].p.v;this.feFlood.setAttribute("flood-color",rgbToHex(Math.round(255*e[0]),Math.round(255*e[1]),Math.round(255*e[2])))}if((t||this.filterManager.effectElements[1].p._mdf)&&this.feFlood.setAttribute("flood-opacity",this.filterManager.effectElements[1].p.v/255),t||this.filterManager.effectElements[2].p._mdf||this.filterManager.effectElements[3].p._mdf){var r=this.filterManager.effectElements[3].p.v,i=(this.filterManager.effectElements[2].p.v-90)*degToRads,s=r*Math.cos(i),a=r*Math.sin(i);this.feOffset.setAttribute("dx",s),this.feOffset.setAttribute("dy",a)}}};var _svgMatteSymbols=[];function SVGMatte3Effect(t,e,r){this.initialized=!1,this.filterManager=e,this.filterElem=t,this.elem=r,r.matteElement=createNS("g"),r.matteElement.appendChild(r.layerElement),r.matteElement.appendChild(r.transformedElement),r.baseElement=r.matteElement}function SVGGaussianBlurEffect(t,e,r,i){t.setAttribute("x","-100%"),t.setAttribute("y","-100%"),t.setAttribute("width","300%"),t.setAttribute("height","300%"),this.filterManager=e;var s=createNS("feGaussianBlur");s.setAttribute("result",i),t.appendChild(s),this.feGaussianBlur=s}function TransformEffect(){}function SVGTransformEffect(t,e){this.init(e)}return SVGMatte3Effect.prototype.findSymbol=function(t){for(var e=0,r=_svgMatteSymbols.length;e<r;){if(_svgMatteSymbols[e]===t)return _svgMatteSymbols[e];e+=1}return null},SVGMatte3Effect.prototype.replaceInParent=function(t,e){var r=t.layerElement.parentNode;if(r){for(var i,s=r.children,a=0,n=s.length;a<n&&s[a]!==t.layerElement;)a+=1;a<=n-2&&(i=s[a+1]);var o=createNS("use");o.setAttribute("href","#"+e),i?r.insertBefore(o,i):r.appendChild(o)}},SVGMatte3Effect.prototype.setElementAsMask=function(t,e){if(!this.findSymbol(e)){var r=createElementID(),i=createNS("mask");i.setAttribute("id",e.layerId),i.setAttribute("mask-type","alpha"),_svgMatteSymbols.push(e);var s=t.globalData.defs;s.appendChild(i);var a=createNS("symbol");a.setAttribute("id",r),this.replaceInParent(e,r),a.appendChild(e.layerElement),s.appendChild(a);var n=createNS("use");n.setAttribute("href","#"+r),i.appendChild(n),e.data.hd=!1,e.show()}t.setMatte(e.layerId)},SVGMatte3Effect.prototype.initialize=function(){for(var t=this.filterManager.effectElements[0].p.v,e=this.elem.comp.elements,r=0,i=e.length;r<i;)e[r]&&e[r].data.ind===t&&this.setElementAsMask(this.elem,e[r]),r+=1;this.initialized=!0},SVGMatte3Effect.prototype.renderFrame=function(){this.initialized||this.initialize()},SVGGaussianBlurEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=.3*this.filterManager.effectElements[0].p.v,r=this.filterManager.effectElements[1].p.v,i=3==r?0:e,s=2==r?0:e;this.feGaussianBlur.setAttribute("stdDeviation",i+" "+s);var a=1==this.filterManager.effectElements[2].p.v?"wrap":"duplicate";this.feGaussianBlur.setAttribute("edgeMode",a)}},TransformEffect.prototype.init=function(t){this.effectsManager=t,this.type=effectTypes.TRANSFORM_EFFECT,this.matrix=new Matrix,this.opacity=-1,this._mdf=!1,this._opMdf=!1},TransformEffect.prototype.renderFrame=function(t){if(this._opMdf=!1,this._mdf=!1,t||this.effectsManager._mdf){var e=this.effectsManager.effectElements,r=e[0].p.v,i=e[1].p.v,s=1===e[2].p.v,a=e[3].p.v,n=s?a:e[4].p.v,o=e[5].p.v,h=e[6].p.v,l=e[7].p.v;this.matrix.reset(),this.matrix.translate(-r[0],-r[1],r[2]),this.matrix.scale(.01*n,.01*a,1),this.matrix.rotate(-l*degToRads),this.matrix.skewFromAxis(-o*degToRads,(h+90)*degToRads),this.matrix.translate(i[0],i[1],0),this._mdf=!0,this.opacity!==e[8].p.v&&(this.opacity=e[8].p.v,this._opMdf=!0)}},extendPrototype([TransformEffect],SVGTransformEffect),setExpressionsPlugin(Expressions),setExpressionInterfaces(getInterface),initialize$1(),initialize(),registerEffect(20,SVGTintFilter,!0),registerEffect(21,SVGFillFilter,!0),registerEffect(22,SVGStrokeEffect,!1),registerEffect(23,SVGTritoneFilter,!0),registerEffect(24,SVGProLevelsFilter,!0),registerEffect(25,SVGDropShadowEffect,!0),registerEffect(28,SVGMatte3Effect,!1),registerEffect(29,SVGGaussianBlurEffect,!0),registerEffect(35,SVGTransformEffect,!1),lottie}));
diff --git a/build/player/lottie_worker.js b/build/player/lottie_worker.js
index 0b19a37..1311700 100644
--- a/build/player/lottie_worker.js
+++ b/build/player/lottie_worker.js
@@ -294,7 +294,7 @@
   var lottieInternal = (function () {
     'use strict';
 
-    (typeof navigator !== "undefined") && (function (global, factory) {
+    (typeof document !== "undefined") && (typeof navigator !== "undefined") && (function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
   typeof define === 'function' && define.amd ? define(factory) :
   (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lottie = factory());
@@ -304,19 +304,15 @@
   var locationHref = '';
   var _useWebWorker = false;
   var initialDefaultFrame = -999999;
-
   var setWebWorker = function setWebWorker(flag) {
     _useWebWorker = !!flag;
   };
-
   var getWebWorker = function getWebWorker() {
     return _useWebWorker;
   };
-
   var setLocationHref = function setLocationHref(value) {
     locationHref = value;
   };
-
   var getLocationHref = function getLocationHref() {
     return locationHref;
   };
@@ -330,28 +326,24 @@
     var i;
     var len = sources.length;
     var sourcePrototype;
-
     for (i = 0; i < len; i += 1) {
       sourcePrototype = sources[i].prototype;
-
       for (var attr in sourcePrototype) {
         if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
       }
     }
   }
-
   function getDescriptor(object, prop) {
     return Object.getOwnPropertyDescriptor(object, prop);
   }
-
   function createProxyFunction(prototype) {
     function ProxyFunction() {}
-
     ProxyFunction.prototype = prototype;
     return ProxyFunction;
   }
 
   // import Howl from '../../3rd_party/howler';
+
   var audioControllerFactory = function () {
     function AudioController(audioFactory) {
       this.audios = [];
@@ -359,7 +351,6 @@
       this._volume = 1;
       this._isMuted = false;
     }
-
     AudioController.prototype = {
       addAudio: function addAudio(audio) {
         this.audios.push(audio);
@@ -367,7 +358,6 @@
       pause: function pause() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].pause();
         }
@@ -375,7 +365,6 @@
       resume: function resume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].resume();
         }
@@ -383,7 +372,6 @@
       setRate: function setRate(rateValue) {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].setRate(rateValue);
         }
@@ -392,13 +380,11 @@
         if (this.audioFactory) {
           return this.audioFactory(assetPath);
         }
-
         if (window.Howl) {
           return new window.Howl({
             src: [assetPath]
           });
         }
-
         return {
           isPlaying: false,
           play: function play() {
@@ -417,17 +403,14 @@
       },
       setVolume: function setVolume(value) {
         this._volume = value;
-
         this._updateVolume();
       },
       mute: function mute() {
         this._isMuted = true;
-
         this._updateVolume();
       },
       unmute: function unmute() {
         this._isMuted = false;
-
         this._updateVolume();
       },
       getVolume: function getVolume() {
@@ -436,7 +419,6 @@
       _updateVolume: function _updateVolume() {
         var i;
         var len = this.audios.length;
-
         for (i = 0; i < len; i += 1) {
           this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
         }
@@ -452,55 +434,44 @@
       var i = 0;
       var arr = [];
       var value;
-
       switch (type) {
         case 'int16':
         case 'uint8c':
           value = 1;
           break;
-
         default:
           value = 1.1;
           break;
       }
-
       for (i = 0; i < len; i += 1) {
         arr.push(value);
       }
-
       return arr;
     }
-
     function createTypedArrayFactory(type, len) {
       if (type === 'float32') {
         return new Float32Array(len);
       }
-
       if (type === 'int16') {
         return new Int16Array(len);
       }
-
       if (type === 'uint8c') {
         return new Uint8ClampedArray(len);
       }
-
       return createRegularArray(type, len);
     }
-
     if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
       return createTypedArrayFactory;
     }
-
     return createRegularArray;
   }();
-
   function createSizedArray(len) {
     return Array.apply(null, {
       length: len
     });
   }
 
-  function _typeof$6(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$6 = function _typeof(obj) { return typeof obj; }; } else { _typeof$6 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$6(obj); }
+  function _typeof$6(o) { "@babel/helpers - typeof"; return _typeof$6 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$6(o); }
   var subframeEnabled = true;
   var expressionsPlugin = null;
   var expressionsInterfaces = null;
@@ -513,57 +484,43 @@
   var bmMax = Math.max;
   var bmMin = Math.min;
   var BMMath = {};
-
   (function () {
     var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
     var i;
     var len = propertyNames.length;
-
     for (i = 0; i < len; i += 1) {
       BMMath[propertyNames[i]] = Math[propertyNames[i]];
     }
   })();
-
   function ProjectInterface$1() {
     return {};
   }
-
   BMMath.random = Math.random;
-
   BMMath.abs = function (val) {
     var tOfVal = _typeof$6(val);
-
     if (tOfVal === 'object' && val.length) {
       var absArr = createSizedArray(val.length);
       var i;
       var len = val.length;
-
       for (i = 0; i < len; i += 1) {
         absArr[i] = Math.abs(val[i]);
       }
-
       return absArr;
     }
-
     return Math.abs(val);
   };
-
   var defaultCurveSegments = 150;
   var degToRads = Math.PI / 180;
   var roundCorner = 0.5519;
-
   function roundValues(flag) {
     _shouldRoundValues = !!flag;
   }
-
   function bmRnd(value) {
     if (_shouldRoundValues) {
       return Math.round(value);
     }
-
     return value;
   }
-
   function styleDiv(element) {
     element.style.position = 'absolute';
     element.style.top = 0;
@@ -577,53 +534,44 @@
     element.style.webkitTransformStyle = 'preserve-3d';
     element.style.mozTransformStyle = 'preserve-3d';
   }
-
   function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
     this.type = type;
     this.currentTime = currentTime;
     this.totalTime = totalTime;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteEvent(type, frameMultiplier) {
     this.type = type;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
     this.type = type;
     this.currentLoop = currentLoop;
     this.totalLoops = totalLoops;
     this.direction = frameMultiplier < 0 ? -1 : 1;
   }
-
   function BMSegmentStartEvent(type, firstFrame, totalFrames) {
     this.type = type;
     this.firstFrame = firstFrame;
     this.totalFrames = totalFrames;
   }
-
   function BMDestroyEvent(type, target) {
     this.type = type;
     this.target = target;
   }
-
   function BMRenderFrameErrorEvent(nativeError, currentTime) {
     this.type = 'renderFrameError';
     this.nativeError = nativeError;
     this.currentTime = currentTime;
   }
-
   function BMConfigErrorEvent(nativeError) {
     this.type = 'configError';
     this.nativeError = nativeError;
   }
-
   function BMAnimationConfigErrorEvent(type, nativeError) {
     this.type = type;
     this.nativeError = nativeError;
   }
-
   var createElementID = function () {
     var _count = 0;
     return function createID() {
@@ -631,7 +579,6 @@
       return idPrefix$1 + '__lottie_element_' + _count;
     };
   }();
-
   function HSVtoRGB(h, s, v) {
     var r;
     var g;
@@ -646,51 +593,42 @@
     p = v * (1 - s);
     q = v * (1 - f * s);
     t = v * (1 - (1 - f) * s);
-
     switch (i % 6) {
       case 0:
         r = v;
         g = t;
         b = p;
         break;
-
       case 1:
         r = q;
         g = v;
         b = p;
         break;
-
       case 2:
         r = p;
         g = v;
         b = t;
         break;
-
       case 3:
         r = p;
         g = q;
         b = v;
         break;
-
       case 4:
         r = t;
         g = p;
         b = v;
         break;
-
       case 5:
         r = v;
         g = p;
         b = q;
         break;
-
       default:
         break;
     }
-
     return [r, g, b];
   }
-
   function RGBtoHSV(r, g, b) {
     var max = Math.max(r, g, b);
     var min = Math.min(r, g, b);
@@ -698,136 +636,105 @@
     var h;
     var s = max === 0 ? 0 : d / max;
     var v = max / 255;
-
     switch (max) {
       case min:
         h = 0;
         break;
-
       case r:
         h = g - b + d * (g < b ? 6 : 0);
         h /= 6 * d;
         break;
-
       case g:
         h = b - r + d * 2;
         h /= 6 * d;
         break;
-
       case b:
         h = r - g + d * 4;
         h /= 6 * d;
         break;
-
       default:
         break;
     }
-
     return [h, s, v];
   }
-
   function addSaturationToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[1] += offset;
-
     if (hsv[1] > 1) {
       hsv[1] = 1;
     } else if (hsv[1] <= 0) {
       hsv[1] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addBrightnessToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[2] += offset;
-
     if (hsv[2] > 1) {
       hsv[2] = 1;
     } else if (hsv[2] < 0) {
       hsv[2] = 0;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   function addHueToRGB(color, offset) {
     var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
     hsv[0] += offset / 360;
-
     if (hsv[0] > 1) {
       hsv[0] -= 1;
     } else if (hsv[0] < 0) {
       hsv[0] += 1;
     }
-
     return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
   }
-
   var rgbToHex = function () {
     var colorMap = [];
     var i;
     var hex;
-
     for (i = 0; i < 256; i += 1) {
       hex = i.toString(16);
       colorMap[i] = hex.length === 1 ? '0' + hex : hex;
     }
-
     return function (r, g, b) {
       if (r < 0) {
         r = 0;
       }
-
       if (g < 0) {
         g = 0;
       }
-
       if (b < 0) {
         b = 0;
       }
-
       return '#' + colorMap[r] + colorMap[g] + colorMap[b];
     };
   }();
-
   var setSubframeEnabled = function setSubframeEnabled(flag) {
     subframeEnabled = !!flag;
   };
-
   var getSubframeEnabled = function getSubframeEnabled() {
     return subframeEnabled;
   };
-
   var setExpressionsPlugin = function setExpressionsPlugin(value) {
     expressionsPlugin = value;
   };
-
   var getExpressionsPlugin = function getExpressionsPlugin() {
     return expressionsPlugin;
   };
-
   var setExpressionInterfaces = function setExpressionInterfaces(value) {
     expressionsInterfaces = value;
   };
-
   var getExpressionInterfaces = function getExpressionInterfaces() {
     return expressionsInterfaces;
   };
-
   var setDefaultCurveSegments = function setDefaultCurveSegments(value) {
     defaultCurveSegments = value;
   };
-
   var getDefaultCurveSegments = function getDefaultCurveSegments() {
     return defaultCurveSegments;
   };
-
   var setIdPrefix = function setIdPrefix(value) {
     idPrefix$1 = value;
   };
-
   var getIdPrefix = function getIdPrefix() {
     return idPrefix$1;
   };
@@ -837,8 +744,7 @@
     return document.createElementNS(svgNS, type);
   }
 
-  function _typeof$5(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$5 = function _typeof(obj) { return typeof obj; }; } else { _typeof$5 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$5(obj); }
-
+  function _typeof$5(o) { "@babel/helpers - typeof"; return _typeof$5 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$5(o); }
   var dataManager = function () {
     var _counterId = 1;
     var processes = [];
@@ -859,21 +765,18 @@
         });
       }
     };
-
     function createWorker(fn) {
       if (window.Worker && window.Blob && getWebWorker()) {
         var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], {
           type: 'text/javascript'
-        }); // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
-
+        });
+        // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
         var url = URL.createObjectURL(blob);
         return new Worker(url);
       }
-
       workerFn = fn;
       return workerProxy;
     }
-
     function setupWorker() {
       if (!workerInstance) {
         workerInstance = createWorker(function workerStart(e) {
@@ -886,28 +789,22 @@
               var jLen;
               var k;
               var kLen;
-
               for (i = 0; i < len; i += 1) {
                 layerData = layers[i];
-
                 if ('ks' in layerData && !layerData.completed) {
                   layerData.completed = true;
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         convertPathsToAbsoluteValues(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) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
                           }
@@ -915,7 +812,6 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 0) {
                     layerData.layers = findCompLayers(layerData.refId, comps);
                     completeLayers(layerData.layers, comps);
@@ -927,16 +823,15 @@
                 }
               }
             }
-
             function completeChars(chars, assets) {
               if (chars) {
                 var i = 0;
                 var len = chars.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (chars[i].t === 1) {
                     // var compData = findComp(chars[i].data.refId, assets);
-                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets); // chars[i].data.ip = 0;
+                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
+                    // chars[i].data.ip = 0;
                     // chars[i].data.op = 99999;
                     // chars[i].data.st = 0;
                     // chars[i].data.sr = 1;
@@ -948,61 +843,48 @@
                     //   s: { k: [100, 100], a: 0 },
                     //   o: { k: 100, a: 0 },
                     // };
-
                     completeLayers(chars[i].data.layers, assets);
                   }
                 }
               }
             }
-
             function findComp(id, comps) {
               var i = 0;
               var len = comps.length;
-
               while (i < len) {
                 if (comps[i].id === id) {
                   return comps[i];
                 }
-
                 i += 1;
               }
-
               return null;
             }
-
             function findCompLayers(id, comps) {
               var comp = findComp(id, comps);
-
               if (comp) {
                 if (!comp.layers.__used) {
                   comp.layers.__used = true;
                   return comp.layers;
                 }
-
                 return JSON.parse(JSON.stringify(comp.layers));
               }
-
               return null;
             }
-
             function completeShapes(arr) {
               var i;
               var len = arr.length;
               var j;
               var jLen;
-
               for (i = len - 1; i >= 0; i -= 1) {
                 if (arr[i].ty === 'sh') {
                   if (arr[i].ks.k.i) {
                     convertPathsToAbsoluteValues(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) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
                       }
-
                       if (arr[i].ks.k[j].e) {
                         convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
                       }
@@ -1013,11 +895,9 @@
                 }
               }
             }
-
             function convertPathsToAbsoluteValues(path) {
               var i;
               var len = path.i.length;
-
               for (i = 0; i < len; i += 1) {
                 path.i[i][0] += path.v[i][0];
                 path.i[i][1] += path.v[i][1];
@@ -1025,40 +905,30 @@
                 path.o[i][1] += path.v[i][1];
               }
             }
-
             function checkVersion(minimum, animVersionString) {
               var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
-
               if (minimum[0] > animVersion[0]) {
                 return true;
               }
-
               if (animVersion[0] > minimum[0]) {
                 return false;
               }
-
               if (minimum[1] > animVersion[1]) {
                 return true;
               }
-
               if (animVersion[1] > minimum[1]) {
                 return false;
               }
-
               if (minimum[2] > animVersion[2]) {
                 return true;
               }
-
               if (animVersion[2] > minimum[2]) {
                 return false;
               }
-
               return null;
             }
-
             var checkText = function () {
               var minimumVersion = [4, 4, 14];
-
               function updateTextLayer(textLayer) {
                 var documentData = textLayer.t.d;
                 textLayer.t.d = {
@@ -1068,26 +938,21 @@
                   }]
                 };
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1097,17 +962,14 @@
                 }
               };
             }();
-
             var checkChars = function () {
               var minimumVersion = [4, 7, 99];
               return function (animationData) {
                 if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
                   var i;
                   var len = animationData.chars.length;
-
                   for (i = 0; i < len; i += 1) {
                     var charData = animationData.chars[i];
-
                     if (charData.data && charData.data.shapes) {
                       completeShapes(charData.data.shapes);
                       charData.data.ip = 0;
@@ -1136,7 +998,6 @@
                           a: 0
                         }
                       };
-
                       if (!animationData.chars[i].t) {
                         charData.data.shapes.push({
                           ty: 'no'
@@ -1178,27 +1039,22 @@
                 }
               };
             }();
-
             var checkPathProperties = function () {
               var minimumVersion = [5, 7, 15];
-
               function updateTextLayer(textLayer) {
                 var pathData = textLayer.t.p;
-
                 if (typeof pathData.a === 'number') {
                   pathData.a = {
                     a: 0,
                     k: pathData.a
                   };
                 }
-
                 if (typeof pathData.p === 'number') {
                   pathData.p = {
                     a: 0,
                     k: pathData.p
                   };
                 }
-
                 if (typeof pathData.r === 'number') {
                   pathData.r = {
                     a: 0,
@@ -1206,26 +1062,21 @@
                   };
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 5) {
                     updateTextLayer(layers[i]);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1235,23 +1086,19 @@
                 }
               };
             }();
-
             var checkColors = function () {
               var minimumVersion = [4, 1, 9];
-
               function iterateShapes(shapes) {
                 var i;
                 var len = shapes.length;
                 var j;
                 var jLen;
-
                 for (i = 0; i < len; i += 1) {
                   if (shapes[i].ty === 'gr') {
                     iterateShapes(shapes[i].it);
                   } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
                     if (shapes[i].c.k && shapes[i].c.k[0].i) {
                       jLen = shapes[i].c.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (shapes[i].c.k[j].s) {
                           shapes[i].c.k[j].s[0] /= 255;
@@ -1259,7 +1106,6 @@
                           shapes[i].c.k[j].s[2] /= 255;
                           shapes[i].c.k[j].s[3] /= 255;
                         }
-
                         if (shapes[i].c.k[j].e) {
                           shapes[i].c.k[j].e[0] /= 255;
                           shapes[i].c.k[j].e[1] /= 255;
@@ -1276,26 +1122,21 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var i;
                 var len = layers.length;
-
                 for (i = 0; i < len; i += 1) {
                   if (layers[i].ty === 4) {
                     iterateShapes(layers[i].shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1305,28 +1146,23 @@
                 }
               };
             }();
-
             var checkShapes = function () {
               var minimumVersion = [4, 4, 18];
-
               function completeClosingShapes(arr) {
                 var i;
                 var len = arr.length;
                 var j;
                 var jLen;
-
                 for (i = len - 1; i >= 0; i -= 1) {
                   if (arr[i].ty === 'sh') {
                     if (arr[i].ks.k.i) {
                       arr[i].ks.k.c = arr[i].closed;
                     } else {
                       jLen = arr[i].ks.k.length;
-
                       for (j = 0; j < jLen; j += 1) {
                         if (arr[i].ks.k[j].s) {
                           arr[i].ks.k[j].s[0].c = arr[i].closed;
                         }
-
                         if (arr[i].ks.k[j].e) {
                           arr[i].ks.k[j].e[0].c = arr[i].closed;
                         }
@@ -1337,7 +1173,6 @@
                   }
                 }
               }
-
               function iterateLayers(layers) {
                 var layerData;
                 var i;
@@ -1346,25 +1181,20 @@
                 var jLen;
                 var k;
                 var kLen;
-
                 for (i = 0; i < len; i += 1) {
                   layerData = layers[i];
-
                   if (layerData.hasMask) {
                     var maskProps = layerData.masksProperties;
                     jLen = maskProps.length;
-
                     for (j = 0; j < jLen; j += 1) {
                       if (maskProps[j].pt.k.i) {
                         maskProps[j].pt.k.c = maskProps[j].cl;
                       } else {
                         kLen = maskProps[j].pt.k.length;
-
                         for (k = 0; k < kLen; k += 1) {
                           if (maskProps[j].pt.k[k].s) {
                             maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
                           }
-
                           if (maskProps[j].pt.k[k].e) {
                             maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
                           }
@@ -1372,21 +1202,17 @@
                       }
                     }
                   }
-
                   if (layerData.ty === 4) {
                     completeClosingShapes(layerData.shapes);
                   }
                 }
               }
-
               return function (animationData) {
                 if (checkVersion(minimumVersion, animationData.v)) {
                   iterateLayers(animationData.layers);
-
                   if (animationData.assets) {
                     var i;
                     var len = animationData.assets.length;
-
                     for (i = 0; i < len; i += 1) {
                       if (animationData.assets[i].layers) {
                         iterateLayers(animationData.assets[i].layers);
@@ -1396,12 +1222,10 @@
                 }
               };
             }();
-
             function completeData(animationData) {
               if (animationData.__complete) {
                 return;
               }
-
               checkColors(animationData);
               checkText(animationData);
               checkChars(animationData);
@@ -1411,12 +1235,11 @@
               completeChars(animationData.chars, animationData.assets);
               animationData.__complete = true;
             }
-
             function completeText(data) {
-              if (data.t.a.length === 0 && !('m' in data.t.p)) {// data.singleShape = true;
+              if (data.t.a.length === 0 && !('m' in data.t.p)) {
+                // data.singleShape = true;
               }
             }
-
             var moduleOb = {};
             moduleOb.completeData = completeData;
             moduleOb.checkColors = checkColors;
@@ -1426,47 +1249,37 @@
             moduleOb.completeLayers = completeLayers;
             return moduleOb;
           }
-
           if (!_workerSelf.dataManager) {
             _workerSelf.dataManager = dataFunctionManager();
           }
-
           if (!_workerSelf.assetLoader) {
             _workerSelf.assetLoader = function () {
               function formatResponse(xhr) {
                 // using typeof doubles the time of execution of this method,
                 // so if available, it's better to use the header to validate the type
                 var contentTypeHeader = xhr.getResponseHeader('content-type');
-
                 if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
                   return xhr.response;
                 }
-
                 if (xhr.response && _typeof$5(xhr.response) === 'object') {
                   return xhr.response;
                 }
-
                 if (xhr.response && typeof xhr.response === 'string') {
                   return JSON.parse(xhr.response);
                 }
-
                 if (xhr.responseText) {
                   return JSON.parse(xhr.responseText);
                 }
-
                 return null;
               }
-
               function loadAsset(path, fullPath, callback, errorCallback) {
                 var response;
-                var xhr = new XMLHttpRequest(); // set responseType after calling open or IE will break.
-
+                var xhr = new XMLHttpRequest();
+                // set responseType after calling open or IE will break.
                 try {
                   // This crashes on Android WebView prior to KitKat
                   xhr.responseType = 'json';
                 } catch (err) {} // eslint-disable-line no-empty
-
-
                 xhr.onreadystatechange = function () {
                   if (xhr.readyState === 4) {
                     if (xhr.status === 200) {
@@ -1484,7 +1297,6 @@
                     }
                   }
                 };
-
                 try {
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), path, true);
@@ -1492,20 +1304,16 @@
                   // Hack to workaround banner validation
                   xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
                 }
-
                 xhr.send();
               }
-
               return {
                 load: loadAsset
               };
             }();
           }
-
           if (e.data.type === 'loadAnimation') {
             _workerSelf.assetLoader.load(e.data.path, e.data.fullPath, function (data) {
               _workerSelf.dataManager.completeData(data);
-
               _workerSelf.postMessage({
                 id: e.data.id,
                 payload: data,
@@ -1519,9 +1327,7 @@
             });
           } else if (e.data.type === 'complete') {
             var animation = e.data.animation;
-
             _workerSelf.dataManager.completeData(animation);
-
             _workerSelf.postMessage({
               id: e.data.id,
               payload: animation,
@@ -1542,13 +1348,11 @@
             });
           }
         });
-
         workerInstance.onmessage = function (event) {
           var data = event.data;
           var id = data.id;
           var process = processes[id];
           processes[id] = null;
-
           if (data.status === 'success') {
             process.onComplete(data.payload);
           } else if (process.onError) {
@@ -1557,7 +1361,6 @@
         };
       }
     }
-
     function createProcess(onComplete, onError) {
       _counterId += 1;
       var id = 'processId_' + _counterId;
@@ -1567,7 +1370,6 @@
       };
       return id;
     }
-
     function loadAnimation(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1578,7 +1380,6 @@
         id: processId
       });
     }
-
     function loadData(path, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1589,7 +1390,6 @@
         id: processId
       });
     }
-
     function completeAnimation(anim, onComplete, onError) {
       setupWorker();
       var processId = createProcess(onComplete, onError);
@@ -1599,7 +1399,6 @@
         id: processId
       });
     }
-
     return {
       loadAnimation: loadAnimation,
       loadData: loadData,
@@ -1617,94 +1416,74 @@
       ctx.fillRect(0, 0, 1, 1);
       return canvas;
     }();
-
     function imageLoaded() {
       this.loadedAssets += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function footageLoaded() {
       this.loadedFootagesCount += 1;
-
       if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
         if (this.imagesLoadedCb) {
           this.imagesLoadedCb(null);
         }
       }
     }
-
     function getAssetsPath(assetData, assetsPath, originalPath) {
       var path = '';
-
       if (assetData.e) {
         path = assetData.p;
       } else if (assetsPath) {
         var imagePath = assetData.p;
-
         if (imagePath.indexOf('images/') !== -1) {
           imagePath = imagePath.split('/')[1];
         }
-
         path = assetsPath + imagePath;
       } else {
         path = originalPath;
         path += assetData.u ? assetData.u : '';
         path += assetData.p;
       }
-
       return path;
     }
-
     function testImageLoaded(img) {
       var _count = 0;
       var intervalId = setInterval(function () {
         var box = img.getBBox();
-
         if (box.width || _count > 500) {
           this._imageLoaded();
-
           clearInterval(intervalId);
         }
-
         _count += 1;
       }.bind(this), 50);
     }
-
     function createImageData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createNS('image');
-
       if (isSafari) {
         this.testImageLoaded(img);
       } else {
         img.addEventListener('load', this._imageLoaded, false);
       }
-
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
-
       if (this._elementHelper.append) {
         this._elementHelper.append(img);
       } else {
         this._elementHelper.appendChild(img);
       }
-
       var ob = {
         img: img,
         assetData: assetData
       };
       return ob;
     }
-
     function createImgData(assetData) {
       var path = getAssetsPath(assetData, this.assetsPath, this.path);
       var img = createTag('img');
@@ -1712,7 +1491,6 @@
       img.addEventListener('load', this._imageLoaded, false);
       img.addEventListener('error', function () {
         ob.img = proxyImage;
-
         this._imageLoaded();
       }.bind(this), false);
       img.src = path;
@@ -1722,7 +1500,6 @@
       };
       return ob;
     }
-
     function createFootageData(data) {
       var ob = {
         assetData: data
@@ -1730,21 +1507,17 @@
       var path = getAssetsPath(data, this.assetsPath, this.path);
       dataManager.loadData(path, function (footageData) {
         ob.img = footageData;
-
         this._footageLoaded();
       }.bind(this), function () {
         ob.img = {};
-
         this._footageLoaded();
       }.bind(this));
       return ob;
     }
-
     function loadAssets(assets, cb) {
       this.imagesLoadedCb = cb;
       var i;
       var len = assets.length;
-
       for (i = 0; i < len; i += 1) {
         if (!assets[i].layers) {
           if (!assets[i].t || assets[i].t === 'seq') {
@@ -1757,43 +1530,33 @@
         }
       }
     }
-
     function setPath(path) {
       this.path = path || '';
     }
-
     function setAssetsPath(path) {
       this.assetsPath = path || '';
     }
-
     function getAsset(assetData) {
       var i = 0;
       var len = this.images.length;
-
       while (i < len) {
         if (this.images[i].assetData === assetData) {
           return this.images[i].img;
         }
-
         i += 1;
       }
-
       return null;
     }
-
     function destroy() {
       this.imagesLoadedCb = null;
       this.images.length = 0;
     }
-
     function loadedImages() {
       return this.totalImages === this.loadedAssets;
     }
-
     function loadedFootages() {
       return this.totalFootages === this.loadedFootagesCount;
     }
-
     function setCacheType(type, elementHelper) {
       if (type === 'svg') {
         this._elementHelper = elementHelper;
@@ -1802,7 +1565,6 @@
         this._createImageData = this.createImgData.bind(this);
       }
     }
-
     function ImagePreloaderFactory() {
       this._imageLoaded = imageLoaded.bind(this);
       this._footageLoaded = footageLoaded.bind(this);
@@ -1817,7 +1579,6 @@
       this.imagesLoadedCb = null;
       this.images = [];
     }
-
     ImagePreloaderFactory.prototype = {
       loadAssets: loadAssets,
       setAssetsPath: setAssetsPath,
@@ -1836,12 +1597,10 @@
   }();
 
   function BaseEvent() {}
-
   BaseEvent.prototype = {
     triggerEvent: function triggerEvent(eventName, args) {
       if (this._cbs[eventName]) {
         var callbacks = this._cbs[eventName];
-
         for (var i = 0; i < callbacks.length; i += 1) {
           callbacks[i](args);
         }
@@ -1851,9 +1610,7 @@
       if (!this._cbs[eventName]) {
         this._cbs[eventName] = [];
       }
-
       this._cbs[eventName].push(callback);
-
       return function () {
         this.removeEventListener(eventName, callback);
       }.bind(this);
@@ -1864,18 +1621,14 @@
       } else if (this._cbs[eventName]) {
         var i = 0;
         var len = this._cbs[eventName].length;
-
         while (i < len) {
           if (this._cbs[eventName][i] === callback) {
             this._cbs[eventName].splice(i, 1);
-
             i -= 1;
             len -= 1;
           }
-
           i += 1;
         }
-
         if (!this._cbs[eventName].length) {
           this._cbs[eventName] = null;
         }
@@ -1889,33 +1642,26 @@
       var keys = {};
       var line;
       var keysCount = 0;
-
       for (var i = 0; i < lines.length; i += 1) {
         line = lines[i].split(':');
-
         if (line.length === 2) {
           keys[line[0]] = line[1].trim();
           keysCount += 1;
         }
       }
-
       if (keysCount === 0) {
         throw new Error();
       }
-
       return keys;
     }
-
     return function (_markers) {
       var markers = [];
-
       for (var i = 0; i < _markers.length; i += 1) {
         var _marker = _markers[i];
         var markerData = {
           time: _marker.tm,
           duration: _marker.dr
         };
-
         try {
           markerData.payload = JSON.parse(_markers[i].cm);
         } catch (_) {
@@ -1927,10 +1673,8 @@
             };
           }
         }
-
         markers.push(markerData);
       }
-
       return markers;
     };
   }();
@@ -1939,27 +1683,21 @@
     function registerComposition(comp) {
       this.compositions.push(comp);
     }
-
     return function () {
       function _thisProjectFunction(name) {
         var i = 0;
         var len = this.compositions.length;
-
         while (i < len) {
           if (this.compositions[i].data && this.compositions[i].data.nm === name) {
             if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
               this.compositions[i].prepareFrame(this.currentFrame);
             }
-
             return this.compositions[i].compInterface;
           }
-
           i += 1;
         }
-
         return null;
       }
-
       _thisProjectFunction.compositions = [];
       _thisProjectFunction.currentFrame = 0;
       _thisProjectFunction.registerComposition = registerComposition;
@@ -1968,33 +1706,27 @@
   }();
 
   var renderers = {};
-
   var registerRenderer = function registerRenderer(key, value) {
     renderers[key] = value;
   };
-
   function getRenderer(key) {
     return renderers[key];
   }
-
   function getRegisteredRenderer() {
     // Returns canvas by default for compatibility
     if (renderers.canvas) {
       return 'canvas';
-    } // Returns any renderer that is registered
-
-
+    }
+    // Returns any renderer that is registered
     for (var key in renderers) {
       if (renderers[key]) {
         return key;
       }
     }
-
     return '';
   }
 
-  function _typeof$4(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$4 = function _typeof(obj) { return typeof obj; }; } else { _typeof$4 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$4(obj); }
-
+  function _typeof$4(o) { "@babel/helpers - typeof"; return _typeof$4 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$4(o); }
   var AnimationItem = function AnimationItem() {
     this._cbs = [];
     this.name = '';
@@ -2033,28 +1765,22 @@
     this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
     this.expressionsPlugin = getExpressionsPlugin();
   };
-
   extendPrototype([BaseEvent], AnimationItem);
-
   AnimationItem.prototype.setParams = function (params) {
     if (params.wrapper || params.container) {
       this.wrapper = params.wrapper || params.container;
     }
-
     var animType = 'svg';
-
     if (params.animType) {
       animType = params.animType;
     } else if (params.renderer) {
       animType = params.renderer;
     }
-
     var RendererClass = getRenderer(animType);
     this.renderer = new RendererClass(this, params.rendererSettings);
     this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
     this.renderer.setProjectInterface(this.projectInterface);
     this.animType = animType;
-
     if (params.loop === '' || params.loop === null || params.loop === undefined || params.loop === true) {
       this.loop = true;
     } else if (params.loop === false) {
@@ -2062,17 +1788,14 @@
     } else {
       this.loop = parseInt(params.loop, 10);
     }
-
     this.autoplay = 'autoplay' in params ? params.autoplay : true;
     this.name = params.name ? params.name : '';
     this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
     this.assetsPath = params.assetsPath;
     this.initialSegment = params.initialSegment;
-
     if (params.audioFactory) {
       this.audioController.setAudioFactory(params.audioFactory);
     }
-
     if (params.animationData) {
       this.setupAnimation(params.animationData);
     } else if (params.path) {
@@ -2081,28 +1804,23 @@
       } else {
         this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
       }
-
       this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
       this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
       dataManager.loadAnimation(params.path, this.configAnimation, this.onSetupError);
     }
   };
-
   AnimationItem.prototype.onSetupError = function () {
     this.trigger('data_failed');
   };
-
   AnimationItem.prototype.setupAnimation = function (data) {
     dataManager.completeAnimation(data, this.configAnimation);
   };
-
   AnimationItem.prototype.setData = function (wrapper, animationData) {
     if (animationData) {
       if (_typeof$4(animationData) !== 'object') {
         animationData = JSON.parse(animationData);
       }
     }
-
     var params = {
       wrapper: wrapper,
       animationData: animationData
@@ -2119,7 +1837,6 @@
     var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-loop').value : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-loop').value : wrapperAttributes.getNamedItem('bm-loop') ? wrapperAttributes.getNamedItem('bm-loop').value : '';
-
     if (loop === 'false') {
       params.loop = false;
     } else if (loop === 'true') {
@@ -2127,7 +1844,6 @@
     } else if (loop !== '') {
       params.loop = parseInt(loop, 10);
     }
-
     var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-autoplay').value : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-autoplay').value : wrapperAttributes.getNamedItem('bm-autoplay') ? wrapperAttributes.getNamedItem('bm-autoplay').value : true;
@@ -2138,81 +1854,64 @@
     var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-anim-prerender').value : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
     ? wrapperAttributes.getNamedItem('data-bm-prerender').value : wrapperAttributes.getNamedItem('bm-prerender') ? wrapperAttributes.getNamedItem('bm-prerender').value : '';
-
     if (prerender === 'false') {
       params.prerender = false;
     }
-
     if (!params.path) {
       this.trigger('destroy');
     } else {
       this.setParams(params);
     }
   };
-
   AnimationItem.prototype.includeLayers = function (data) {
     if (data.op > this.animationData.op) {
       this.animationData.op = data.op;
       this.totalFrames = Math.floor(data.op - this.animationData.ip);
     }
-
     var layers = this.animationData.layers;
     var i;
     var len = layers.length;
     var newLayers = data.layers;
     var j;
     var jLen = newLayers.length;
-
     for (j = 0; j < jLen; j += 1) {
       i = 0;
-
       while (i < len) {
         if (layers[i].id === newLayers[j].id) {
           layers[i] = newLayers[j];
           break;
         }
-
         i += 1;
       }
     }
-
     if (data.chars || data.fonts) {
       this.renderer.globalData.fontManager.addChars(data.chars);
       this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
     }
-
     if (data.assets) {
       len = data.assets.length;
-
       for (i = 0; i < len; i += 1) {
         this.animationData.assets.push(data.assets[i]);
       }
     }
-
     this.animationData.__complete = false;
     dataManager.completeAnimation(this.animationData, this.onSegmentComplete);
   };
-
   AnimationItem.prototype.onSegmentComplete = function (data) {
     this.animationData = data;
     var expressionsPlugin = getExpressionsPlugin();
-
     if (expressionsPlugin) {
       expressionsPlugin.initExpressions(this);
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.loadNextSegment = function () {
     var segments = this.animationData.segments;
-
     if (!segments || segments.length === 0 || !this.autoloadSegments) {
       this.trigger('data_ready');
       this.timeCompleted = this.totalFrames;
       return;
     }
-
     var segment = segments.shift();
     this.timeCompleted = segment.time * this.frameRate;
     var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
@@ -2221,36 +1920,28 @@
       this.trigger('data_failed');
     }.bind(this));
   };
-
   AnimationItem.prototype.loadSegments = function () {
     var segments = this.animationData.segments;
-
     if (!segments) {
       this.timeCompleted = this.totalFrames;
     }
-
     this.loadNextSegment();
   };
-
   AnimationItem.prototype.imagesLoaded = function () {
     this.trigger('loaded_images');
     this.checkLoaded();
   };
-
   AnimationItem.prototype.preloadImages = function () {
     this.imagePreloader.setAssetsPath(this.assetsPath);
     this.imagePreloader.setPath(this.path);
     this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
   };
-
   AnimationItem.prototype.configAnimation = function (animData) {
     if (!this.renderer) {
       return;
     }
-
     try {
       this.animationData = animData;
-
       if (this.initialSegment) {
         this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
         this.firstFrame = Math.round(this.initialSegment[0]);
@@ -2258,13 +1949,10 @@
         this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
         this.firstFrame = Math.round(this.animationData.ip);
       }
-
       this.renderer.configAnimation(animData);
-
       if (!animData.assets) {
         animData.assets = [];
       }
-
       this.assets = this.animationData.assets;
       this.frameRate = this.animationData.fr;
       this.frameMult = this.animationData.fr / 1000;
@@ -2275,7 +1963,6 @@
       this.loadSegments();
       this.updaFrameModifier();
       this.waitForFontsLoaded();
-
       if (this.isPaused) {
         this.audioController.pause();
       }
@@ -2283,103 +1970,83 @@
       this.triggerConfigError(error);
     }
   };
-
   AnimationItem.prototype.waitForFontsLoaded = function () {
     if (!this.renderer) {
       return;
     }
-
     if (this.renderer.globalData.fontManager.isLoaded) {
       this.checkLoaded();
     } else {
       setTimeout(this.waitForFontsLoaded.bind(this), 20);
     }
   };
-
   AnimationItem.prototype.checkLoaded = function () {
     if (!this.isLoaded && this.renderer.globalData.fontManager.isLoaded && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas') && this.imagePreloader.loadedFootages()) {
       this.isLoaded = true;
       var expressionsPlugin = getExpressionsPlugin();
-
       if (expressionsPlugin) {
         expressionsPlugin.initExpressions(this);
       }
-
       this.renderer.initItems();
       setTimeout(function () {
         this.trigger('DOMLoaded');
       }.bind(this), 0);
       this.gotoFrame();
-
       if (this.autoplay) {
         this.play();
       }
     }
   };
-
   AnimationItem.prototype.resize = function (width, height) {
     // Adding this validation for backwards compatibility in case an event object was being passed down
     var _width = typeof width === 'number' ? width : undefined;
-
     var _height = typeof height === 'number' ? height : undefined;
-
     this.renderer.updateContainerSize(_width, _height);
   };
-
   AnimationItem.prototype.setSubframe = function (flag) {
     this.isSubframeEnabled = !!flag;
   };
-
   AnimationItem.prototype.gotoFrame = function () {
     this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
 
     if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
       this.currentFrame = this.timeCompleted;
     }
-
     this.trigger('enterFrame');
     this.renderFrame();
     this.trigger('drawnFrame');
   };
-
   AnimationItem.prototype.renderFrame = function () {
     if (this.isLoaded === false || !this.renderer) {
       return;
     }
-
     try {
       if (this.expressionsPlugin) {
         this.expressionsPlugin.resetFrame();
       }
-
       this.renderer.renderFrame(this.currentFrame + this.firstFrame);
     } catch (error) {
       this.triggerRenderFrameError(error);
     }
   };
-
   AnimationItem.prototype.play = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.isPaused = false;
       this.trigger('_play');
       this.audioController.resume();
-
       if (this._idle) {
         this._idle = false;
         this.trigger('_active');
       }
     }
   };
-
   AnimationItem.prototype.pause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === false) {
       this.isPaused = true;
       this.trigger('_pause');
@@ -2388,54 +2055,42 @@
       this.audioController.pause();
     }
   };
-
   AnimationItem.prototype.togglePause = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     if (this.isPaused === true) {
       this.play();
     } else {
       this.pause();
     }
   };
-
   AnimationItem.prototype.stop = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.pause();
     this.playCount = 0;
     this._completedLoop = false;
     this.setCurrentRawFrameValue(0);
   };
-
   AnimationItem.prototype.getMarkerData = function (markerName) {
     var marker;
-
     for (var i = 0; i < this.markers.length; i += 1) {
       marker = this.markers[i];
-
       if (marker.payload && marker.payload.name === markerName) {
         return marker;
       }
     }
-
     return null;
   };
-
   AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         this.goToAndStop(marker.time, true);
       }
@@ -2444,20 +2099,15 @@
     } else {
       this.setCurrentRawFrameValue(value * this.frameModifier);
     }
-
     this.pause();
   };
-
   AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
     if (name && this.name !== name) {
       return;
     }
-
     var numValue = Number(value);
-
     if (isNaN(numValue)) {
       var marker = this.getMarkerData(value);
-
       if (marker) {
         if (!marker.duration) {
           this.goToAndStop(marker.time, true);
@@ -2468,19 +2118,16 @@
     } else {
       this.goToAndStop(numValue, isFrame, name);
     }
-
     this.play();
   };
-
   AnimationItem.prototype.advanceTime = function (value) {
     if (this.isPaused === true || this.isLoaded === false) {
       return;
     }
-
     var nextValue = this.currentRawFrame + value * this.frameModifier;
-    var _isComplete = false; // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
+    var _isComplete = false;
+    // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
     // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
-
     if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
       if (!this.loop || this.playCount === this.loop) {
         if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
@@ -2489,7 +2136,6 @@
         }
       } else if (nextValue >= this.totalFrames) {
         this.playCount += 1;
-
         if (!this.checkSegments(nextValue % this.totalFrames)) {
           this.setCurrentRawFrameValue(nextValue % this.totalFrames);
           this._completedLoop = true;
@@ -2503,7 +2149,6 @@
         if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) {
           // eslint-disable-line no-plusplus
           this.setCurrentRawFrameValue(this.totalFrames + nextValue % this.totalFrames);
-
           if (!this._completedLoop) {
             this._completedLoop = true;
           } else {
@@ -2517,17 +2162,14 @@
     } else {
       this.setCurrentRawFrameValue(nextValue);
     }
-
     if (_isComplete) {
       this.setCurrentRawFrameValue(nextValue);
       this.pause();
       this.trigger('complete');
     }
   };
-
   AnimationItem.prototype.adjustSegment = function (arr, offset) {
     this.playCount = 0;
-
     if (arr[1] < arr[0]) {
       if (this.frameModifier > 0) {
         if (this.playSpeed < 0) {
@@ -2536,7 +2178,6 @@
           this.setDirection(-1);
         }
       }
-
       this.totalFrames = arr[0] - arr[1];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[1];
@@ -2549,19 +2190,15 @@
           this.setDirection(1);
         }
       }
-
       this.totalFrames = arr[1] - arr[0];
       this.timeCompleted = this.totalFrames;
       this.firstFrame = arr[0];
       this.setCurrentRawFrameValue(0.001 + offset);
     }
-
     this.trigger('segmentStart');
   };
-
   AnimationItem.prototype.setSegment = function (init, end) {
     var pendingFrame = -1;
-
     if (this.isPaused) {
       if (this.currentRawFrame + this.firstFrame < init) {
         pendingFrame = init;
@@ -2569,64 +2206,51 @@
         pendingFrame = end - init;
       }
     }
-
     this.firstFrame = init;
     this.totalFrames = end - init;
     this.timeCompleted = this.totalFrames;
-
     if (pendingFrame !== -1) {
       this.goToAndStop(pendingFrame, true);
     }
   };
-
   AnimationItem.prototype.playSegments = function (arr, forceFlag) {
     if (forceFlag) {
       this.segments.length = 0;
     }
-
     if (_typeof$4(arr[0]) === 'object') {
       var i;
       var len = arr.length;
-
       for (i = 0; i < len; i += 1) {
         this.segments.push(arr[i]);
       }
     } else {
       this.segments.push(arr);
     }
-
     if (this.segments.length && forceFlag) {
       this.adjustSegment(this.segments.shift(), 0);
     }
-
     if (this.isPaused) {
       this.play();
     }
   };
-
   AnimationItem.prototype.resetSegments = function (forceFlag) {
     this.segments.length = 0;
     this.segments.push([this.animationData.ip, this.animationData.op]);
-
     if (forceFlag) {
       this.checkSegments(0);
     }
   };
-
   AnimationItem.prototype.checkSegments = function (offset) {
     if (this.segments.length) {
       this.adjustSegment(this.segments.shift(), offset);
       return true;
     }
-
     return false;
   };
-
   AnimationItem.prototype.destroy = function (name) {
     if (name && this.name !== name || !this.renderer) {
       return;
     }
-
     this.renderer.destroy();
     this.imagePreloader.destroy();
     this.trigger('destroy');
@@ -2641,189 +2265,148 @@
     this.imagePreloader = null;
     this.projectInterface = null;
   };
-
   AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
     this.currentRawFrame = value;
     this.gotoFrame();
   };
-
   AnimationItem.prototype.setSpeed = function (val) {
     this.playSpeed = val;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setDirection = function (val) {
     this.playDirection = val < 0 ? -1 : 1;
     this.updaFrameModifier();
   };
-
   AnimationItem.prototype.setLoop = function (isLooping) {
     this.loop = isLooping;
   };
-
   AnimationItem.prototype.setVolume = function (val, name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.setVolume(val);
   };
-
   AnimationItem.prototype.getVolume = function () {
     return this.audioController.getVolume();
   };
-
   AnimationItem.prototype.mute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.mute();
   };
-
   AnimationItem.prototype.unmute = function (name) {
     if (name && this.name !== name) {
       return;
     }
-
     this.audioController.unmute();
   };
-
   AnimationItem.prototype.updaFrameModifier = function () {
     this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
     this.audioController.setRate(this.playSpeed * this.playDirection);
   };
-
   AnimationItem.prototype.getPath = function () {
     return this.path;
   };
-
   AnimationItem.prototype.getAssetsPath = function (assetData) {
     var path = '';
-
     if (assetData.e) {
       path = assetData.p;
     } else if (this.assetsPath) {
       var imagePath = assetData.p;
-
       if (imagePath.indexOf('images/') !== -1) {
         imagePath = imagePath.split('/')[1];
       }
-
       path = this.assetsPath + imagePath;
     } else {
       path = this.path;
       path += assetData.u ? assetData.u : '';
       path += assetData.p;
     }
-
     return path;
   };
-
   AnimationItem.prototype.getAssetData = function (id) {
     var i = 0;
     var len = this.assets.length;
-
     while (i < len) {
       if (id === this.assets[i].id) {
         return this.assets[i];
       }
-
       i += 1;
     }
-
     return null;
   };
-
   AnimationItem.prototype.hide = function () {
     this.renderer.hide();
   };
-
   AnimationItem.prototype.show = function () {
     this.renderer.show();
   };
-
   AnimationItem.prototype.getDuration = function (isFrame) {
     return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
   };
-
   AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
     try {
       var element = this.renderer.getElementByPath(path);
       element.updateDocumentData(documentData, index);
-    } catch (error) {// TODO: decide how to handle catch case
+    } catch (error) {
+      // TODO: decide how to handle catch case
     }
   };
-
   AnimationItem.prototype.trigger = function (name) {
     if (this._cbs && this._cbs[name]) {
       switch (name) {
         case 'enterFrame':
           this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
           break;
-
         case 'drawnFrame':
           this.drawnFrameEvent.currentTime = this.currentFrame;
           this.drawnFrameEvent.totalTime = this.totalFrames;
           this.drawnFrameEvent.direction = this.frameModifier;
           this.triggerEvent(name, this.drawnFrameEvent);
           break;
-
         case 'loopComplete':
           this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
           break;
-
         case 'complete':
           this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
           break;
-
         case 'segmentStart':
           this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
           break;
-
         case 'destroy':
           this.triggerEvent(name, new BMDestroyEvent(name, this));
           break;
-
         default:
           this.triggerEvent(name);
       }
     }
-
     if (name === 'enterFrame' && this.onEnterFrame) {
       this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
     }
-
     if (name === 'loopComplete' && this.onLoopComplete) {
       this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
     }
-
     if (name === 'complete' && this.onComplete) {
       this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
     }
-
     if (name === 'segmentStart' && this.onSegmentStart) {
       this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
     }
-
     if (name === 'destroy' && this.onDestroy) {
       this.onDestroy.call(this, new BMDestroyEvent(name, this));
     }
   };
-
   AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
     var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
   };
-
   AnimationItem.prototype.triggerConfigError = function (nativeError) {
     var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
     this.triggerEvent('error', error);
-
     if (this.onError) {
       this.onError.call(this, error);
     }
@@ -2837,68 +2420,53 @@
     var playingAnimationsNum = 0;
     var _stopped = true;
     var _isFrozen = false;
-
     function removeElement(ev) {
       var i = 0;
       var animItem = ev.target;
-
       while (i < len) {
         if (registeredAnimations[i].animation === animItem) {
           registeredAnimations.splice(i, 1);
           i -= 1;
           len -= 1;
-
           if (!animItem.isPaused) {
             subtractPlayingCount();
           }
         }
-
         i += 1;
       }
     }
-
     function registerAnimation(element, animationData) {
       if (!element) {
         return null;
       }
-
       var i = 0;
-
       while (i < len) {
         if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
           return registeredAnimations[i].animation;
         }
-
         i += 1;
       }
-
       var animItem = new AnimationItem();
       setupAnimation(animItem, element);
       animItem.setData(element, animationData);
       return animItem;
     }
-
     function getRegisteredAnimations() {
       var i;
       var lenAnims = registeredAnimations.length;
       var animations = [];
-
       for (i = 0; i < lenAnims; i += 1) {
         animations.push(registeredAnimations[i].animation);
       }
-
       return animations;
     }
-
     function addPlayingCount() {
       playingAnimationsNum += 1;
       activate();
     }
-
     function subtractPlayingCount() {
       playingAnimationsNum -= 1;
     }
-
     function setupAnimation(animItem, element) {
       animItem.addEventListener('destroy', removeElement);
       animItem.addEventListener('_active', addPlayingCount);
@@ -2909,118 +2477,91 @@
       });
       len += 1;
     }
-
     function loadAnimation(params) {
       var animItem = new AnimationItem();
       setupAnimation(animItem, null);
       animItem.setParams(params);
       return animItem;
     }
-
     function setSpeed(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setSpeed(val, animation);
       }
     }
-
     function setDirection(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setDirection(val, animation);
       }
     }
-
     function play(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.play(animation);
       }
     }
-
     function resume(nowTime) {
       var elapsedTime = nowTime - initTime;
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.advanceTime(elapsedTime);
       }
-
       initTime = nowTime;
-
       if (playingAnimationsNum && !_isFrozen) {
         window.requestAnimationFrame(resume);
       } else {
         _stopped = true;
       }
     }
-
     function first(nowTime) {
       initTime = nowTime;
       window.requestAnimationFrame(resume);
     }
-
     function pause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.pause(animation);
       }
     }
-
     function goToAndStop(value, isFrame, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
       }
     }
-
     function stop(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.stop(animation);
       }
     }
-
     function togglePause(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.togglePause(animation);
       }
     }
-
     function destroy(animation) {
       var i;
-
       for (i = len - 1; i >= 0; i -= 1) {
         registeredAnimations[i].animation.destroy(animation);
       }
     }
-
     function searchAnimations(animationData, standalone, renderer) {
       var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')), [].slice.call(document.getElementsByClassName('bodymovin')));
       var i;
       var lenAnims = animElements.length;
-
       for (i = 0; i < lenAnims; i += 1) {
         if (renderer) {
           animElements[i].setAttribute('data-bm-type', renderer);
         }
-
         registerAnimation(animElements[i], animationData);
       }
-
       if (standalone && lenAnims === 0) {
         if (!renderer) {
           renderer = 'svg';
         }
-
         var body = document.getElementsByTagName('body')[0];
         body.innerText = '';
         var div = createTag('div');
@@ -3031,15 +2572,12 @@
         registerAnimation(div, animationData);
       }
     }
-
     function resize() {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.resize();
       }
     }
-
     function activate() {
       if (!_isFrozen && playingAnimationsNum) {
         if (_stopped) {
@@ -3048,40 +2586,31 @@
         }
       }
     }
-
     function freeze() {
       _isFrozen = true;
     }
-
     function unfreeze() {
       _isFrozen = false;
       activate();
     }
-
     function setVolume(val, animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.setVolume(val, animation);
       }
     }
-
     function mute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.mute(animation);
       }
     }
-
     function unmute(animation) {
       var i;
-
       for (i = 0; i < len; i += 1) {
         registeredAnimations[i].animation.unmute(animation);
       }
     }
-
     moduleOb.registerAnimation = registerAnimation;
     moduleOb.loadAnimation = loadAnimation;
     moduleOb.setSpeed = setSpeed;
@@ -3091,8 +2620,8 @@
     moduleOb.stop = stop;
     moduleOb.togglePause = togglePause;
     moduleOb.searchAnimations = searchAnimations;
-    moduleOb.resize = resize; // moduleOb.start = start;
-
+    moduleOb.resize = resize;
+    // moduleOb.start = start;
     moduleOb.goToAndStop = goToAndStop;
     moduleOb.destroy = destroy;
     moduleOb.freeze = freeze;
@@ -3116,23 +2645,21 @@
        * spline.get(x) => returns the easing value | x must be in [0, 1] range
        *
        */
+
     var ob = {};
     ob.getBezierEasing = getBezierEasing;
     var beziers = {};
-
     function getBezierEasing(a, b, c, d, nm) {
       var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
-
       if (beziers[str]) {
         return beziers[str];
       }
-
       var bezEasing = new BezierEasing([a, b, c, d]);
       beziers[str] = bezEasing;
       return bezEasing;
-    } // These values are established by empiricism with tests (tradeoff: performance VS precision)
+    }
 
-
+    // These values are established by empiricism with tests (tradeoff: performance VS precision)
     var NEWTON_ITERATIONS = 4;
     var NEWTON_MIN_SLOPE = 0.001;
     var SUBDIVISION_PRECISION = 0.0000001;
@@ -3140,48 +2667,40 @@
     var kSplineTableSize = 11;
     var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
     var float32ArraySupported = typeof Float32Array === 'function';
-
     function A(aA1, aA2) {
       return 1.0 - 3.0 * aA2 + 3.0 * aA1;
     }
-
     function B(aA1, aA2) {
       return 3.0 * aA2 - 6.0 * aA1;
     }
-
     function C(aA1) {
       return 3.0 * aA1;
-    } // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+    }
 
-
+    // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
     function calcBezier(aT, aA1, aA2) {
       return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
-    } // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+    }
 
-
+    // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
     function getSlope(aT, aA1, aA2) {
       return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
     }
-
     function binarySubdivide(aX, aA, aB, mX1, mX2) {
       var currentX,
-          currentT,
-          i = 0;
-
+        currentT,
+        i = 0;
       do {
         currentT = aA + (aB - aA) / 2.0;
         currentX = calcBezier(currentT, mX1, mX2) - aX;
-
         if (currentX > 0.0) {
           aB = currentT;
         } else {
           aA = currentT;
         }
       } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
-
       return currentT;
     }
-
     function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
       for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
         var currentSlope = getSlope(aGuessT, mX1, mX2);
@@ -3189,85 +2708,75 @@
         var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
         aGuessT -= currentX / currentSlope;
       }
-
       return aGuessT;
     }
+
     /**
        * points is an array of [ mX1, mY1, mX2, mY2 ]
        */
-
-
     function BezierEasing(points) {
       this._p = points;
       this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
       this._precomputed = false;
       this.get = this.get.bind(this);
     }
-
     BezierEasing.prototype = {
       get: function get(x) {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         if (!this._precomputed) this._precompute();
         if (mX1 === mY1 && mX2 === mY2) return x; // linear
         // Because JavaScript number are imprecise, we should guarantee the extremes are right.
-
         if (x === 0) return 0;
         if (x === 1) return 1;
         return calcBezier(this._getTForX(x), mY1, mY2);
       },
       // Private part
+
       _precompute: function _precompute() {
         var mX1 = this._p[0],
-            mY1 = this._p[1],
-            mX2 = this._p[2],
-            mY2 = this._p[3];
+          mY1 = this._p[1],
+          mX2 = this._p[2],
+          mY2 = this._p[3];
         this._precomputed = true;
-
         if (mX1 !== mY1 || mX2 !== mY2) {
           this._calcSampleValues();
         }
       },
       _calcSampleValues: function _calcSampleValues() {
         var mX1 = this._p[0],
-            mX2 = this._p[2];
-
+          mX2 = this._p[2];
         for (var i = 0; i < kSplineTableSize; ++i) {
           this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
         }
       },
-
       /**
            * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
            */
       _getTForX: function _getTForX(aX) {
         var mX1 = this._p[0],
-            mX2 = this._p[2],
-            mSampleValues = this._mSampleValues;
+          mX2 = this._p[2],
+          mSampleValues = this._mSampleValues;
         var intervalStart = 0.0;
         var currentSample = 1;
         var lastSample = kSplineTableSize - 1;
-
         for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
           intervalStart += kSampleStepSize;
         }
+        --currentSample;
 
-        --currentSample; // Interpolate to provide an initial guess for t
-
+        // Interpolate to provide an initial guess for t
         var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
         var guessForT = intervalStart + dist * kSampleStepSize;
         var initialSlope = getSlope(guessForT, mX1, mX2);
-
         if (initialSlope >= NEWTON_MIN_SLOPE) {
           return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
         }
-
         if (initialSlope === 0.0) {
           return guessForT;
         }
-
         return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
       }
     };
@@ -3278,7 +2787,6 @@
     function _double(arr) {
       return arr.concat(createSizedArray(arr.length));
     }
-
     return {
       "double": _double
     };
@@ -3293,34 +2801,27 @@
         newElement: newElement,
         release: release
       };
-
       function newElement() {
         var element;
-
         if (_length) {
           _length -= 1;
           element = pool[_length];
         } else {
           element = _create();
         }
-
         return element;
       }
-
       function release(element) {
         if (_length === _maxLength) {
           pool = pooling["double"](pool);
           _maxLength *= 2;
         }
-
         if (_release) {
           _release(element);
         }
-
         pool[_length] = element;
         _length += 1;
       }
-
       return ob;
     };
   }();
@@ -3333,7 +2834,6 @@
         lengths: createTypedArray('float32', getDefaultCurveSegments())
       };
     }
-
     return poolFactory(8, create);
   }();
 
@@ -3344,39 +2844,31 @@
         totalLength: 0
       };
     }
-
     function release(element) {
       var i;
       var len = element.lengths.length;
-
       for (i = 0; i < len; i += 1) {
         bezierLengthPool.release(element.lengths[i]);
       }
-
       element.lengths.length = 0;
     }
-
     return poolFactory(8, create, release);
   }();
 
   function bezFunction() {
     var math = Math;
-
     function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
       var det1 = x1 * y2 + y1 * x3 + x2 * y3 - x3 * y2 - y3 * x1 - x2 * y1;
       return det1 > -0.001 && det1 < 0.001;
     }
-
     function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
       if (z1 === 0 && z2 === 0 && z3 === 0) {
         return pointOnLine2D(x1, y1, x2, y2, x3, y3);
       }
-
       var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
       var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
       var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
       var diffDist;
-
       if (dist1 > dist2) {
         if (dist1 > dist3) {
           diffDist = dist1 - dist2 - dist3;
@@ -3388,10 +2880,8 @@
       } else {
         diffDist = dist2 - dist1 - dist3;
       }
-
       return diffDist > -0.0001 && diffDist < 0.0001;
     }
-
     var getBezierLength = function () {
       return function (pt1, pt2, pt3, pt4) {
         var curveSegments = getDefaultCurveSegments();
@@ -3406,36 +2896,28 @@
         var lastPoint = [];
         var lengthData = bezierLengthPool.newElement();
         len = pt3.length;
-
         for (k = 0; k < curveSegments; k += 1) {
           perc = k / (curveSegments - 1);
           ptDistance = 0;
-
           for (i = 0; i < len; i += 1) {
             ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
             point[i] = ptCoord;
-
             if (lastPoint[i] !== null) {
               ptDistance += bmPow(point[i] - lastPoint[i], 2);
             }
-
             lastPoint[i] = point[i];
           }
-
           if (ptDistance) {
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
           }
-
           lengthData.percents[k] = perc;
           lengthData.lengths[k] = addedLength;
         }
-
         lengthData.addedLength = addedLength;
         return lengthData;
       };
     }();
-
     function getSegmentsLength(shapeData) {
       var segmentsLength = segmentsLengthPool.newElement();
       var closed = shapeData.c;
@@ -3446,36 +2928,29 @@
       var len = shapeData._length;
       var lengths = segmentsLength.lengths;
       var totalLength = 0;
-
       for (i = 0; i < len - 1; i += 1) {
         lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
         totalLength += lengths[i].addedLength;
       }
-
       if (closed && len) {
         lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
         totalLength += lengths[i].addedLength;
       }
-
       segmentsLength.totalLength = totalLength;
       return segmentsLength;
     }
-
     function BezierData(length) {
       this.segmentLength = 0;
       this.points = new Array(length);
     }
-
     function PointData(partial, point) {
       this.partialLength = partial;
       this.point = point;
     }
-
     var buildBezierData = function () {
       var storedData = {};
       return function (pt1, pt2, pt3, pt4) {
         var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
-
         if (!storedData[bezierName]) {
           var curveSegments = getDefaultCurveSegments();
           var k;
@@ -3487,42 +2962,33 @@
           var ptDistance;
           var point;
           var lastPoint = null;
-
           if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
             curveSegments = 2;
           }
-
           var bezierData = new BezierData(curveSegments);
           len = pt3.length;
-
           for (k = 0; k < curveSegments; k += 1) {
             point = createSizedArray(len);
             perc = k / (curveSegments - 1);
             ptDistance = 0;
-
             for (i = 0; i < len; i += 1) {
               ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
               point[i] = ptCoord;
-
               if (lastPoint !== null) {
                 ptDistance += bmPow(point[i] - lastPoint[i], 2);
               }
             }
-
             ptDistance = bmSqrt(ptDistance);
             addedLength += ptDistance;
             bezierData.points[k] = new PointData(ptDistance, point);
             lastPoint = point;
           }
-
           bezierData.segmentLength = addedLength;
           storedData[bezierName] = bezierData;
         }
-
         return storedData[bezierName];
       };
     }();
-
     function getDistancePerc(perc, bezierData) {
       var percents = bezierData.percents;
       var lengths = bezierData.lengths;
@@ -3530,14 +2996,11 @@
       var initPos = bmFloor((len - 1) * perc);
       var lengthPos = perc * bezierData.addedLength;
       var lPerc = 0;
-
       if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
         return percents[initPos];
       }
-
       var dir = lengths[initPos] > lengthPos ? -1 : 1;
       var flag = true;
-
       while (flag) {
         if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
           lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
@@ -3545,20 +3008,16 @@
         } else {
           initPos += dir;
         }
-
         if (initPos < 0 || initPos >= len - 1) {
           // FIX for TypedArrays that don't store floating point values with enough accuracy
           if (initPos === len - 1) {
             return percents[initPos];
           }
-
           flag = false;
         }
       }
-
       return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
     }
-
     function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
       var t1 = getDistancePerc(percent, bezierData);
       var u1 = 1 - t1;
@@ -3566,16 +3025,13 @@
       var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
       return [ptX, ptY];
     }
-
     var bezierSegmentPoints = createTypedArray('float32', 8);
-
     function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
       if (startPerc < 0) {
         startPerc = 0;
       } else if (startPerc > 1) {
         startPerc = 1;
       }
-
       var t0 = getDistancePerc(startPerc, bezierData);
       endPerc = endPerc > 1 ? 1 : endPerc;
       var t1 = getDistancePerc(endPerc, bezierData);
@@ -3585,45 +3041,31 @@
       var u1 = 1 - t1;
       var u0u0u0 = u0 * u0 * u0;
       var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
-
       var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
-
-      var t0t0t0 = t0 * t0 * t0; //
-
+      var t0t0t0 = t0 * t0 * t0;
+      //
       var u0u0u1 = u0 * u0 * u1;
       var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
-
       var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
-
-      var t0t0t1 = t0 * t0 * t1; //
-
+      var t0t0t1 = t0 * t0 * t1;
+      //
       var u0u1u1 = u0 * u1 * u1;
       var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
-
       var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
-
-      var t0t1t1 = t0 * t1 * t1; //
-
+      var t0t1t1 = t0 * t1 * t1;
+      //
       var u1u1u1 = u1 * u1 * u1;
       var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
-
       var t1t1t1 = t1 * t1 * t1;
-
       for (i = 0; i < len; i += 1) {
         bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-
         bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
       }
-
       return bezierSegmentPoints;
     }
-
     return {
       getSegmentsLength: getSegmentsLength,
       getNewSegment: getNewSegment,
@@ -3633,20 +3075,16 @@
       pointOnLine3D: pointOnLine3D
     };
   }
-
   var bez = bezFunction();
 
   var initFrame = initialDefaultFrame;
   var mathAbs = Math.abs;
-
   function interpolateValue(frameNum, caching) {
     var offsetTime = this.offsetTime;
     var newValue;
-
     if (this.propType === 'multidimensional') {
       newValue = createTypedArray('float32', this.pv.length);
     }
-
     var iterationIndex = caching.lastIndex;
     var i = iterationIndex;
     var len = this.keyframes.length - 1;
@@ -3654,25 +3092,20 @@
     var keyData;
     var nextKeyData;
     var keyframeMetadata;
-
     while (flag) {
       keyData = this.keyframes[i];
       nextKeyData = this.keyframes[i + 1];
-
       if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
         if (keyData.h) {
           keyData = nextKeyData;
         }
-
         iterationIndex = 0;
         break;
       }
-
       if (nextKeyData.t - offsetTime > frameNum) {
         iterationIndex = i;
         break;
       }
-
       if (i < len - 1) {
         i += 1;
       } else {
@@ -3680,7 +3113,6 @@
         flag = false;
       }
     }
-
     keyframeMetadata = this.keyframesMetadata[i] || {};
     var k;
     var kLen;
@@ -3691,22 +3123,18 @@
     var nextKeyTime = nextKeyData.t - offsetTime;
     var keyTime = keyData.t - offsetTime;
     var endValue;
-
     if (keyData.to) {
       if (!keyframeMetadata.bezierData) {
         keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
       }
-
       var bezierData = keyframeMetadata.bezierData;
-
       if (frameNum >= nextKeyTime || frameNum < keyTime) {
         var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
         kLen = bezierData.points[ind].point.length;
-
         for (k = 0; k < kLen; k += 1) {
           newValue[k] = bezierData.points[ind].point[k];
-        } // caching._lastKeyframeIndex = -1;
-
+        }
+        // caching._lastKeyframeIndex = -1;
       } else {
         if (keyframeMetadata.__fnct) {
           fnc = keyframeMetadata.__fnct;
@@ -3714,7 +3142,6 @@
           fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
           keyframeMetadata.__fnct = fnc;
         }
-
         perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
         var distanceInLine = bezierData.segmentLength * perc;
         var segmentPerc;
@@ -3722,36 +3149,28 @@
         j = caching.lastFrame < frameNum && caching._lastKeyframeIndex === i ? caching._lastPoint : 0;
         flag = true;
         jLen = bezierData.points.length;
-
         while (flag) {
           addedLength += bezierData.points[j].partialLength;
-
           if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k];
             }
-
             break;
           } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
             segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
             kLen = bezierData.points[j].point.length;
-
             for (k = 0; k < kLen; k += 1) {
               newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
             }
-
             break;
           }
-
           if (j < jLen - 1) {
             j += 1;
           } else {
             flag = false;
           }
         }
-
         caching._lastPoint = j;
         caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
         caching._lastKeyframeIndex = i;
@@ -3764,7 +3183,6 @@
       var keyValue;
       len = keyData.s.length;
       endValue = nextKeyData.s || keyData.e;
-
       if (this.sh && keyData.h !== 1) {
         if (frameNum >= nextKeyTime) {
           newValue[0] = endValue[0];
@@ -3792,7 +3210,6 @@
                 if (!keyframeMetadata.__fnct) {
                   keyframeMetadata.__fnct = [];
                 }
-
                 if (!keyframeMetadata.__fnct[i]) {
                   outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
                   outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
@@ -3813,14 +3230,11 @@
               } else {
                 fnc = keyframeMetadata.__fnct;
               }
-
               perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
             }
           }
-
           endValue = nextKeyData.s || keyData.e;
           keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
-
           if (this.propType === 'multidimensional') {
             newValue[i] = keyValue;
           } else {
@@ -3829,12 +3243,11 @@
         }
       }
     }
-
     caching.lastIndex = iterationIndex;
     return newValue;
-  } // based on @Toji's https://github.com/toji/gl-matrix/
+  }
 
-
+  // based on @Toji's https://github.com/toji/gl-matrix/
   function slerp(a, b, t) {
     var out = [];
     var ax = a[0];
@@ -3851,7 +3264,6 @@
     var scale0;
     var scale1;
     cosom = ax * bx + ay * by + az * bz + aw * bw;
-
     if (cosom < 0.0) {
       cosom = -cosom;
       bx = -bx;
@@ -3859,7 +3271,6 @@
       bz = -bz;
       bw = -bw;
     }
-
     if (1.0 - cosom > 0.000001) {
       omega = Math.acos(cosom);
       sinom = Math.sin(omega);
@@ -3869,14 +3280,12 @@
       scale0 = 1.0 - t;
       scale1 = t;
     }
-
     out[0] = scale0 * ax + scale1 * bx;
     out[1] = scale0 * ay + scale1 * by;
     out[2] = scale0 * az + scale1 * bz;
     out[3] = scale0 * aw + scale1 * bw;
     return out;
   }
-
   function quaternionToEuler(out, quat) {
     var qx = quat[0];
     var qy = quat[1];
@@ -3889,7 +3298,6 @@
     out[1] = attitude / degToRads;
     out[2] = bank / degToRads;
   }
-
   function createQuaternion(values) {
     var heading = values[0] * degToRads;
     var attitude = values[1] * degToRads;
@@ -3906,32 +3314,25 @@
     var z = c1 * s2 * c3 - s1 * c2 * s3;
     return [x, y, z, w];
   }
-
   function getValueAtCurrentTime() {
     var frameNum = this.comp.renderedFrame - this.offsetTime;
     var initTime = this.keyframes[0].t - this.offsetTime;
     var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
-
     if (!(frameNum === this._caching.lastFrame || this._caching.lastFrame !== initFrame && (this._caching.lastFrame >= endTime && frameNum >= endTime || this._caching.lastFrame < initTime && frameNum < initTime))) {
       if (this._caching.lastFrame >= frameNum) {
         this._caching._lastKeyframeIndex = -1;
         this._caching.lastIndex = 0;
       }
-
       var renderResult = this.interpolateValue(frameNum, this._caching);
       this.pv = renderResult;
     }
-
     this._caching.lastFrame = frameNum;
     return this.pv;
   }
-
   function setVValue(val) {
     var multipliedValue;
-
     if (this.propType === 'unidimensional') {
       multipliedValue = val * this.mult;
-
       if (mathAbs(this.v - multipliedValue) > 0.00001) {
         this.v = multipliedValue;
         this._mdf = true;
@@ -3939,51 +3340,41 @@
     } else {
       var i = 0;
       var len = this.v.length;
-
       while (i < len) {
         multipliedValue = val[i] * this.mult;
-
         if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
           this.v[i] = multipliedValue;
           this._mdf = true;
         }
-
         i += 1;
       }
     }
   }
-
   function processEffectsSequence() {
     if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
       return;
     }
-
     if (this.lock) {
       this.setVValue(this.pv);
       return;
     }
-
     this.lock = true;
     this._mdf = this._isFirstFrame;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = this.kf ? this.pv : this.data.k;
-
     for (i = 0; i < len; i += 1) {
       finalValue = this.effectsSequence[i](finalValue);
     }
-
     this.setVValue(finalValue);
     this._isFirstFrame = false;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   }
-
   function addEffect(effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.container.addDynamicProperty(this);
   }
-
   function ValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.mult = mult || 1;
@@ -4003,7 +3394,6 @@
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function MultiDimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     this.mult = mult || 1;
@@ -4020,19 +3410,16 @@
     this.v = createTypedArray('float32', len);
     this.pv = createTypedArray('float32', len);
     this.vel = createTypedArray('float32', len);
-
     for (i = 0; i < len; i += 1) {
       this.v[i] = data.k[i] * this.mult;
       this.pv[i] = data.k[i];
     }
-
     this._isFirstFrame = true;
     this.effectsSequence = [];
     this.getValue = processEffectsSequence;
     this.setVValue = setVValue;
     this.addEffect = addEffect;
   }
-
   function KeyframedValueProperty(elem, data, mult, container) {
     this.propType = 'unidimensional';
     this.keyframes = data.k;
@@ -4061,7 +3448,6 @@
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.addEffect = addEffect;
   }
-
   function KeyframedMultidimensionalProperty(elem, data, mult, container) {
     this.propType = 'multidimensional';
     var i;
@@ -4070,19 +3456,16 @@
     var e;
     var to;
     var ti;
-
     for (i = 0; i < len - 1; i += 1) {
       if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
         s = data.k[i].s;
         e = data.k[i + 1].s;
         to = data.k[i].to;
         ti = data.k[i].ti;
-
         if (s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1]) || s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2])) {
           data.k[i].to = null;
           data.k[i].ti = null;
         }
-
         if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
           if (s.length === 2 || s[2] === e[2] && to[2] === 0 && ti[2] === 0) {
             data.k[i].to = null;
@@ -4091,7 +3474,6 @@
         }
       }
     }
-
     this.effectsSequence = [getValueAtCurrentTime.bind(this)];
     this.data = data;
     this.keyframes = data.k;
@@ -4111,12 +3493,10 @@
     var arrLen = data.k[0].s.length;
     this.v = createTypedArray('float32', arrLen);
     this.pv = createTypedArray('float32', arrLen);
-
     for (i = 0; i < arrLen; i += 1) {
       this.v[i] = initFrame;
       this.pv[i] = initFrame;
     }
-
     this._caching = {
       lastFrame: initFrame,
       lastIndex: 0,
@@ -4124,15 +3504,12 @@
     };
     this.addEffect = addEffect;
   }
-
   var PropertyFactory = function () {
     function getProp(elem, data, type, mult, container) {
       if (data.sid) {
         data = elem.globalData.slotManager.getProp(data);
       }
-
       var p;
-
       if (!data.k.length) {
         p = new ValueProperty(elem, data, mult, container);
       } else if (typeof data.k[0] === 'number') {
@@ -4142,23 +3519,18 @@
           case 0:
             p = new KeyframedValueProperty(elem, data, mult, container);
             break;
-
           case 1:
             p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
             break;
-
           default:
             break;
         }
       }
-
       if (p.effectsSequence.length) {
         container.addDynamicProperty(p);
       }
-
       return p;
     }
-
     var ob = {
       getProp: getProp
     };
@@ -4166,7 +3538,6 @@
   }();
 
   function DynamicPropertyContainer() {}
-
   DynamicPropertyContainer.prototype = {
     addDynamicProperty: function addDynamicProperty(prop) {
       if (this.dynamicProperties.indexOf(prop) === -1) {
@@ -4179,10 +3550,8 @@
       this._mdf = false;
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         this.dynamicProperties[i].getValue();
-
         if (this.dynamicProperties[i]._mdf) {
           this._mdf = true;
         }
@@ -4200,7 +3569,6 @@
     function create() {
       return createTypedArray('float32', 2);
     }
-
     return poolFactory(8, create);
   }();
 
@@ -4212,12 +3580,10 @@
     this.o = createSizedArray(this._maxLength);
     this.i = createSizedArray(this._maxLength);
   }
-
   ShapePath.prototype.setPathData = function (closed, len) {
     this.c = closed;
     this.setLength(len);
     var i = 0;
-
     while (i < len) {
       this.v[i] = pointPool.newElement();
       this.o[i] = pointPool.newElement();
@@ -4225,62 +3591,49 @@
       i += 1;
     }
   };
-
   ShapePath.prototype.setLength = function (len) {
     while (this._maxLength < len) {
       this.doubleArrayLength();
     }
-
     this._length = len;
   };
-
   ShapePath.prototype.doubleArrayLength = function () {
     this.v = this.v.concat(createSizedArray(this._maxLength));
     this.i = this.i.concat(createSizedArray(this._maxLength));
     this.o = this.o.concat(createSizedArray(this._maxLength));
     this._maxLength *= 2;
   };
-
   ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
     var arr;
     this._length = Math.max(this._length, pos + 1);
-
     if (this._length >= this._maxLength) {
       this.doubleArrayLength();
     }
-
     switch (type) {
       case 'v':
         arr = this.v;
         break;
-
       case 'i':
         arr = this.i;
         break;
-
       case 'o':
         arr = this.o;
         break;
-
       default:
         arr = [];
         break;
     }
-
     if (!arr[pos] || arr[pos] && !replace) {
       arr[pos] = pointPool.newElement();
     }
-
     arr[pos][0] = x;
     arr[pos][1] = y;
   };
-
   ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
     this.setXYAt(vX, vY, 'v', pos, replace);
     this.setXYAt(oX, oY, 'o', pos, replace);
     this.setXYAt(iX, iY, 'i', pos, replace);
   };
-
   ShapePath.prototype.reverse = function () {
     var newPath = new ShapePath();
     newPath.setPathData(this.c, this._length);
@@ -4288,24 +3641,19 @@
     var outPoints = this.o;
     var inPoints = this.i;
     var init = 0;
-
     if (this.c) {
       newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
       init = 1;
     }
-
     var cnt = this._length - 1;
     var len = this._length;
     var i;
-
     for (i = init; i < len; i += 1) {
       newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
       cnt -= 1;
     }
-
     return newPath;
   };
-
   ShapePath.prototype.length = function () {
     return this._length;
   };
@@ -4314,11 +3662,9 @@
     function create() {
       return new ShapePath();
     }
-
     function release(shapePath) {
       var len = shapePath._length;
       var i;
-
       for (i = 0; i < len; i += 1) {
         pointPool.release(shapePath.v[i]);
         pointPool.release(shapePath.i[i]);
@@ -4327,25 +3673,20 @@
         shapePath.i[i] = null;
         shapePath.o[i] = null;
       }
-
       shapePath._length = 0;
       shapePath.c = false;
     }
-
     function clone(shape) {
       var cloned = factory.newElement();
       var i;
       var len = shape._length === undefined ? shape.v.length : shape._length;
       cloned.setLength(len);
       cloned.c = shape.c;
-
       for (i = 0; i < len; i += 1) {
         cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
       }
-
       return cloned;
     }
-
     var factory = poolFactory(4, create, release);
     factory.clone = clone;
     return factory;
@@ -4356,24 +3697,19 @@
     this._maxLength = 4;
     this.shapes = createSizedArray(this._maxLength);
   }
-
   ShapeCollection.prototype.addShape = function (shapeData) {
     if (this._length === this._maxLength) {
       this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
       this._maxLength *= 2;
     }
-
     this.shapes[this._length] = shapeData;
     this._length += 1;
   };
-
   ShapeCollection.prototype.releaseShapes = function () {
     var i;
-
     for (i = 0; i < this._length; i += 1) {
       shapePool.release(this.shapes[i]);
     }
-
     this._length = 0;
   };
 
@@ -4385,45 +3721,35 @@
     var _length = 0;
     var _maxLength = 4;
     var pool = createSizedArray(_maxLength);
-
     function newShapeCollection() {
       var shapeCollection;
-
       if (_length) {
         _length -= 1;
         shapeCollection = pool[_length];
       } else {
         shapeCollection = new ShapeCollection();
       }
-
       return shapeCollection;
     }
-
     function release(shapeCollection) {
       var i;
       var len = shapeCollection._length;
-
       for (i = 0; i < len; i += 1) {
         shapePool.release(shapeCollection.shapes[i]);
       }
-
       shapeCollection._length = 0;
-
       if (_length === _maxLength) {
         pool = pooling["double"](pool);
         _maxLength *= 2;
       }
-
       pool[_length] = shapeCollection;
       _length += 1;
     }
-
     return ob;
   }();
 
   var ShapePropertyFactory = function () {
     var initFrame = -999999;
-
     function interpolateShape(frameNum, previousValue, caching) {
       var iterationIndex = caching.lastIndex;
       var keyPropS;
@@ -4436,7 +3762,6 @@
       var perc;
       var vertexValue;
       var kf = this.keyframes;
-
       if (frameNum < kf[0].t - this.offsetTime) {
         keyPropS = kf[0].s[0];
         isHold = true;
@@ -4448,7 +3773,6 @@
               }else{
                   keyPropS = kf[kf.length - 2].e[0];
               } */
-
         isHold = true;
       } else {
         var i = iterationIndex;
@@ -4457,26 +3781,21 @@
         var keyData;
         var nextKeyData;
         var keyframeMetadata;
-
         while (flag) {
           keyData = kf[i];
           nextKeyData = kf[i + 1];
-
           if (nextKeyData.t - this.offsetTime > frameNum) {
             break;
           }
-
           if (i < len - 1) {
             i += 1;
           } else {
             flag = false;
           }
         }
-
         keyframeMetadata = this.keyframesMetadata[i] || {};
         isHold = keyData.h === 1;
         iterationIndex = i;
-
         if (!isHold) {
           if (frameNum >= nextKeyData.t - this.offsetTime) {
             perc = 1;
@@ -4484,27 +3803,21 @@
             perc = 0;
           } else {
             var fnc;
-
             if (keyframeMetadata.__fnct) {
               fnc = keyframeMetadata.__fnct;
             } else {
               fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
               keyframeMetadata.__fnct = fnc;
             }
-
             perc = fnc((frameNum - (keyData.t - this.offsetTime)) / (nextKeyData.t - this.offsetTime - (keyData.t - this.offsetTime)));
           }
-
           keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
         }
-
         keyPropS = keyData.s[0];
       }
-
       jLen = previousValue._length;
       kLen = keyPropS.i[0].length;
       caching.lastIndex = iterationIndex;
-
       for (j = 0; j < jLen; j += 1) {
         for (k = 0; k < kLen; k += 1) {
           vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
@@ -4516,44 +3829,36 @@
         }
       }
     }
-
     function interpolateShapeCurrentTime() {
       var frameNum = this.comp.renderedFrame - this.offsetTime;
       var initTime = this.keyframes[0].t - this.offsetTime;
       var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
       var lastFrame = this._caching.lastFrame;
-
       if (!(lastFrame !== initFrame && (lastFrame < initTime && frameNum < initTime || lastFrame > endTime && frameNum > endTime))) {
         /// /
         this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
-        this.interpolateShape(frameNum, this.pv, this._caching); /// /
+        this.interpolateShape(frameNum, this.pv, this._caching);
+        /// /
       }
-
       this._caching.lastFrame = frameNum;
       return this.pv;
     }
-
     function resetShape() {
       this.paths = this.localShapeCollection;
     }
-
     function shapesEqual(shape1, shape2) {
       if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
         return false;
       }
-
       var i;
       var len = shape1._length;
-
       for (i = 0; i < len; i += 1) {
         if (shape1.v[i][0] !== shape2.v[i][0] || shape1.v[i][1] !== shape2.v[i][1] || shape1.o[i][0] !== shape2.o[i][0] || shape1.o[i][1] !== shape2.o[i][1] || shape1.i[i][0] !== shape2.i[i][0] || shape1.i[i][1] !== shape2.i[i][1]) {
           return false;
         }
       }
-
       return true;
     }
-
     function setVValue(newPath) {
       if (!shapesEqual(this.v, newPath)) {
         this.v = shapePool.clone(newPath);
@@ -4563,26 +3868,21 @@
         this.paths = this.localShapeCollection;
       }
     }
-
     function processEffectsSequence() {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (!this.effectsSequence.length) {
         this._mdf = false;
         return;
       }
-
       if (this.lock) {
         this.setVValue(this.pv);
         return;
       }
-
       this.lock = true;
       this._mdf = false;
       var finalValue;
-
       if (this.kf) {
         finalValue = this.pv;
       } else if (this.data.ks) {
@@ -4590,19 +3890,15 @@
       } else {
         finalValue = this.data.pt.k;
       }
-
       var i;
       var len = this.effectsSequence.length;
-
       for (i = 0; i < len; i += 1) {
         finalValue = this.effectsSequence[i](finalValue);
       }
-
       this.setVValue(finalValue);
       this.lock = false;
       this.frameId = this.elem.globalData.frameId;
     }
-
     function ShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4621,17 +3917,14 @@
       this.reset = resetShape;
       this.effectsSequence = [];
     }
-
     function addEffect(effectFunction) {
       this.effectsSequence.push(effectFunction);
       this.container.addDynamicProperty(this);
     }
-
     ShapeProperty.prototype.interpolateShape = interpolateShape;
     ShapeProperty.prototype.getValue = processEffectsSequence;
     ShapeProperty.prototype.setVValue = setVValue;
     ShapeProperty.prototype.addEffect = addEffect;
-
     function KeyframedShapeProperty(elem, data, type) {
       this.propType = 'shape';
       this.comp = elem.comp;
@@ -4657,15 +3950,12 @@
       };
       this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
     }
-
     KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
     KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
     KeyframedShapeProperty.prototype.setVValue = setVValue;
     KeyframedShapeProperty.prototype.addEffect = addEffect;
-
     var EllShapeProperty = function () {
       var cPoint = roundCorner;
-
       function EllShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
         this.v.setPathData(true, 4);
@@ -4679,7 +3969,6 @@
         this.initDynamicPropertyContainer(elem);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4687,17 +3976,14 @@
           this.convertEllToPath();
         }
       }
-
       EllShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertEllToPath();
           }
@@ -4707,9 +3993,7 @@
           var p1 = this.p.v[1];
           var s0 = this.s.v[0] / 2;
           var s1 = this.s.v[1] / 2;
-
           var _cw = this.d !== 3;
-
           var _v = this.v;
           _v.v[0][0] = p0;
           _v.v[0][1] = p1 - s1;
@@ -4740,7 +4024,6 @@
       extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
       return EllShapePropertyFactory;
     }();
-
     var StarShapeProperty = function () {
       function StarShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4751,7 +4034,6 @@
         this.frameId = -1;
         this.d = data.d;
         this.initDynamicPropertyContainer(elem);
-
         if (data.sy === 1) {
           this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
           this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
@@ -4759,7 +4041,6 @@
         } else {
           this.convertToPath = this.convertPolygonToPath;
         }
-
         this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
@@ -4768,7 +4049,6 @@
         this.localShapeCollection = shapeCollectionPool.newShapeCollection();
         this.localShapeCollection.addShape(this.v);
         this.paths = this.localShapeCollection;
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4776,17 +4056,14 @@
           this.convertToPath();
         }
       }
-
       StarShapePropertyFactory.prototype = {
         reset: resetShape,
         getValue: function getValue() {
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertToPath();
           }
@@ -4797,7 +4074,6 @@
           /* this.v.v.length = numPts;
                   this.v.i.length = numPts;
                   this.v.o.length = numPts; */
-
           var longFlag = true;
           var longRad = this.or.v;
           var shortRad = this.ir.v;
@@ -4813,7 +4089,6 @@
           currentAng += this.r.v;
           var dir = this.data.d === 3 ? -1 : 1;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             rad = longFlag ? longRad : shortRad;
             roundness = longFlag ? longRound : shortRound;
@@ -4825,11 +4100,11 @@
             x += +this.p.v[0];
             y += +this.p.v[1];
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
+
             /* this.v.v[i] = [x,y];
                       this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
                       this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
                       this.v._length = numPts; */
-
             longFlag = !longFlag;
             currentAng += angle * dir;
           }
@@ -4845,7 +4120,6 @@
           var dir = this.data.d === 3 ? -1 : 1;
           currentAng += this.r.v;
           this.v._length = 0;
-
           for (i = 0; i < numPts; i += 1) {
             var x = rad * Math.cos(currentAng);
             var y = rad * Math.sin(currentAng);
@@ -4856,7 +4130,6 @@
             this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
             currentAng += angle * dir;
           }
-
           this.paths.length = 0;
           this.paths[0] = this.v;
         }
@@ -4864,7 +4137,6 @@
       extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
       return StarShapePropertyFactory;
     }();
-
     var RectShapeProperty = function () {
       function RectShapePropertyFactory(elem, data) {
         this.v = shapePool.newElement();
@@ -4880,7 +4152,6 @@
         this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
         this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
         this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
-
         if (this.dynamicProperties.length) {
           this.k = true;
         } else {
@@ -4888,7 +4159,6 @@
           this.convertRectToPath();
         }
       }
-
       RectShapePropertyFactory.prototype = {
         convertRectToPath: function convertRectToPath() {
           var p0 = this.p.v[0];
@@ -4898,11 +4168,9 @@
           var round = bmMin(v0, v1, this.r.v);
           var cPoint = round * (1 - roundCorner);
           this.v._length = 0;
-
           if (this.d === 2 || this.d === 1) {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
             this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
               this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
@@ -4916,7 +4184,6 @@
             }
           } else {
             this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
-
             if (round !== 0) {
               this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
               this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
@@ -4936,10 +4203,8 @@
           if (this.elem.globalData.frameId === this.frameId) {
             return;
           }
-
           this.frameId = this.elem.globalData.frameId;
           this.iterateDynamicProperties();
-
           if (this._mdf) {
             this.convertRectToPath();
           }
@@ -4949,14 +4214,11 @@
       extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
       return RectShapePropertyFactory;
     }();
-
     function getShapeProp(elem, data, type) {
       var prop;
-
       if (type === 3 || type === 4) {
         var dataProp = type === 3 ? data.pt : data.ks;
         var keys = dataProp.k;
-
         if (keys.length) {
           prop = new KeyframedShapeProperty(elem, data, type);
         } else {
@@ -4969,22 +4231,17 @@
       } else if (type === 7) {
         prop = new StarShapeProperty(elem, data);
       }
-
       if (prop.k) {
         elem.addDynamicProperty(prop);
       }
-
       return prop;
     }
-
     function getConstructorFunction() {
       return ShapeProperty;
     }
-
     function getKeyframedConstructorFunction() {
       return KeyframedShapeProperty;
     }
-
     var ob = {};
     ob.getShapeProp = getShapeProp;
     ob.getConstructorFunction = getConstructorFunction;
@@ -5026,7 +4283,6 @@
     var _sin = Math.sin;
     var _tan = Math.tan;
     var _rnd = Math.round;
-
     function reset() {
       this.props[0] = 1;
       this.props[1] = 0;
@@ -5046,83 +4302,59 @@
       this.props[15] = 1;
       return this;
     }
-
     function rotate(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function rotateX(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateY(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
     }
-
     function rotateZ(angle) {
       if (angle === 0) {
         return this;
       }
-
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
       return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
     }
-
     function shear(sx, sy) {
       return this._t(1, sy, sx, 1, 0, 0);
     }
-
     function skew(ax, ay) {
       return this.shear(_tan(ax), _tan(ay));
     }
-
     function skewFromAxis(ax, angle) {
       var mCos = _cos(angle);
-
       var mSin = _sin(angle);
-
-      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
+      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+      // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
     }
-
     function scale(sx, sy, sz) {
       if (!sz && sz !== 0) {
         sz = 1;
       }
-
       if (sx === 1 && sy === 1 && sz === 1) {
         return this;
       }
-
       return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
     }
-
     function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
       this.props[0] = a;
       this.props[1] = b;
@@ -5142,32 +4374,26 @@
       this.props[15] = p;
       return this;
     }
-
     function translate(tx, ty, tz) {
       tz = tz || 0;
-
       if (tx !== 0 || ty !== 0 || tz !== 0) {
         return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
       }
-
       return this;
     }
-
     function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
       var _p = this.props;
-
       if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
         // NOTE: commenting this condition because TurboFan deoptimizes code when present
         // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
         _p[12] = _p[12] * a2 + _p[15] * m2;
         _p[13] = _p[13] * f2 + _p[15] * n2;
         _p[14] = _p[14] * k2 + _p[15] * o2;
-        _p[15] *= p2; // }
-
+        _p[15] *= p2;
+        // }
         this._identityCalculated = false;
         return this;
       }
-
       var a1 = _p[0];
       var b1 = _p[1];
       var c1 = _p[2];
@@ -5184,12 +4410,12 @@
       var n1 = _p[13];
       var o1 = _p[14];
       var p1 = _p[15];
+
       /* matrix order (canvas compatible):
            * ace
            * bdf
            * 001
            */
-
       _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
       _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
       _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
@@ -5209,53 +4435,40 @@
       this._identityCalculated = false;
       return this;
     }
-
     function multiply(matrix) {
       var matrixProps = matrix.props;
       return this.transform(matrixProps[0], matrixProps[1], matrixProps[2], matrixProps[3], matrixProps[4], matrixProps[5], matrixProps[6], matrixProps[7], matrixProps[8], matrixProps[9], matrixProps[10], matrixProps[11], matrixProps[12], matrixProps[13], matrixProps[14], matrixProps[15]);
     }
-
     function isIdentity() {
       if (!this._identityCalculated) {
         this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
         this._identityCalculated = true;
       }
-
       return this._identity;
     }
-
     function equals(matr) {
       var i = 0;
-
       while (i < 16) {
         if (matr.props[i] !== this.props[i]) {
           return false;
         }
-
         i += 1;
       }
-
       return true;
     }
-
     function clone(matr) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         matr.props[i] = this.props[i];
       }
-
       return matr;
     }
-
     function cloneFromProps(props) {
       var i;
-
       for (i = 0; i < 16; i += 1) {
         this.props[i] = props[i];
       }
     }
-
     function applyToPoint(x, y, z) {
       return {
         x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
@@ -5267,19 +4480,15 @@
            y: x * me.b + y * me.d + me.f
            }; */
     }
-
     function applyToX(x, y, z) {
       return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
     }
-
     function applyToY(x, y, z) {
       return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
     }
-
     function applyToZ(x, y, z) {
       return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
     }
-
     function getInverseMatrix() {
       var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
       var a = this.props[5] / determinant;
@@ -5297,27 +4506,21 @@
       inverseMatrix.props[13] = f;
       return inverseMatrix;
     }
-
     function inversePoint(pt) {
       var inverseMatrix = this.getInverseMatrix();
       return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
     }
-
     function inversePoints(pts) {
       var i;
       var len = pts.length;
       var retPts = [];
-
       for (i = 0; i < len; i += 1) {
         retPts[i] = inversePoint(pts[i]);
       }
-
       return retPts;
     }
-
     function applyToTriplePoints(pt1, pt2, pt3) {
       var arr = createTypedArray('float32', 6);
-
       if (this.isIdentity()) {
         arr[0] = pt1[0];
         arr[1] = pt1[1];
@@ -5339,34 +4542,26 @@
         arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
         arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
       }
-
       return arr;
     }
-
     function applyToPointArray(x, y, z) {
       var arr;
-
       if (this.isIdentity()) {
         arr = [x, y, z];
       } else {
         arr = [x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12], x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13], x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14]];
       }
-
       return arr;
     }
-
     function applyToPointStringified(x, y) {
       if (this.isIdentity()) {
         return x + ',' + y;
       }
-
       var _p = this.props;
       return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
     }
-
     function toCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
@@ -5374,49 +4569,34 @@
       var props = this.props;
       var cssValue = 'matrix3d(';
       var v = 10000;
-
       while (i < 16) {
         cssValue += _rnd(props[i] * v) / v;
         cssValue += i === 15 ? ')' : ',';
         i += 1;
       }
-
       return cssValue;
     }
-
     function roundMatrixProperty(val) {
       var v = 10000;
-
       if (val < 0.000001 && val > 0 || val > -0.000001 && val < 0) {
         return _rnd(val * v) / v;
       }
-
       return val;
     }
-
     function to2dCSS() {
       // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-
       /* if(this.isIdentity()) {
               return '';
           } */
       var props = this.props;
-
       var _a = roundMatrixProperty(props[0]);
-
       var _b = roundMatrixProperty(props[1]);
-
       var _c = roundMatrixProperty(props[4]);
-
       var _d = roundMatrixProperty(props[5]);
-
       var _e = roundMatrixProperty(props[12]);
-
       var _f = roundMatrixProperty(props[13]);
-
       return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
     }
-
     return function () {
       this.reset = reset;
       this.rotate = rotate;
@@ -5455,16 +4635,14 @@
     };
   }();
 
-  function _typeof$3(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$3 = function _typeof(obj) { return typeof obj; }; } else { _typeof$3 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$3(obj); }
+  function _typeof$3(o) { "@babel/helpers - typeof"; return _typeof$3 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$3(o); }
   var lottie = {};
   var standalone = '__[STANDALONE]__';
   var animationData = '__[ANIMATIONDATA]__';
   var renderer = '';
-
   function setLocation(href) {
     setLocationHref(href);
   }
-
   function searchAnimations() {
     if (standalone === true) {
       animationManager.searchAnimations(animationData, standalone, renderer);
@@ -5472,35 +4650,28 @@
       animationManager.searchAnimations();
     }
   }
-
   function setSubframeRendering(flag) {
     setSubframeEnabled(flag);
   }
-
   function setPrefix(prefix) {
     setIdPrefix(prefix);
   }
-
   function loadAnimation(params) {
     if (standalone === true) {
       params.animationData = JSON.parse(animationData);
     }
-
     return animationManager.loadAnimation(params);
   }
-
   function setQuality(value) {
     if (typeof value === 'string') {
       switch (value) {
         case 'high':
           setDefaultCurveSegments(200);
           break;
-
         default:
         case 'medium':
           setDefaultCurveSegments(50);
           break;
-
         case 'low':
           setDefaultCurveSegments(10);
           break;
@@ -5508,40 +4679,32 @@
     } else if (!isNaN(value) && value > 1) {
       setDefaultCurveSegments(value);
     }
-
     if (getDefaultCurveSegments() >= 50) {
       roundValues(false);
     } else {
       roundValues(true);
     }
   }
-
   function inBrowser() {
     return typeof navigator !== 'undefined';
   }
-
   function installPlugin(type, plugin) {
     if (type === 'expressions') {
       setExpressionsPlugin(plugin);
     }
   }
-
   function getFactory(name) {
     switch (name) {
       case 'propertyFactory':
         return PropertyFactory;
-
       case 'shapePropertyFactory':
         return ShapePropertyFactory;
-
       case 'matrix':
         return Matrix;
-
       default:
         return null;
     }
   }
-
   lottie.play = animationManager.play;
   lottie.pause = animationManager.pause;
   lottie.setLocationHref = setLocation;
@@ -5553,8 +4716,8 @@
   lottie.registerAnimation = animationManager.registerAnimation;
   lottie.loadAnimation = loadAnimation;
   lottie.setSubframeRendering = setSubframeRendering;
-  lottie.resize = animationManager.resize; // lottie.start = start;
-
+  lottie.resize = animationManager.resize;
+  // lottie.start = start;
   lottie.goToAndStop = animationManager.goToAndStop;
   lottie.destroy = animationManager.destroy;
   lottie.setQuality = setQuality;
@@ -5569,32 +4732,25 @@
   lottie.useWebWorker = setWebWorker;
   lottie.setIDPrefix = setPrefix;
   lottie.__getFactory = getFactory;
-  lottie.version = '5.12.2';
-
+  lottie.version = '5.13.0';
   function checkReady() {
     if (document.readyState === 'complete') {
       clearInterval(readyStateCheckInterval);
       searchAnimations();
     }
   }
-
   function getQueryVariable(variable) {
     var vars = queryString.split('&');
-
     for (var i = 0; i < vars.length; i += 1) {
       var pair = vars[i].split('=');
-
       if (decodeURIComponent(pair[0]) == variable) {
         // eslint-disable-line eqeqeq
         return decodeURIComponent(pair[1]);
       }
     }
-
     return null;
   }
-
   var queryString = '';
-
   if (standalone) {
     var scripts = document.getElementsByTagName('script');
     var index = scripts.length - 1;
@@ -5602,18 +4758,18 @@
       src: ''
     };
     queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
-
     renderer = getQueryVariable('renderer');
   }
+  var readyStateCheckInterval = setInterval(checkReady, 100);
 
-  var readyStateCheckInterval = setInterval(checkReady, 100); // this adds bodymovin to the window object for backwards compatibility
-
+  // this adds bodymovin to the window object for backwards compatibility
   try {
     if (!((typeof exports === "undefined" ? "undefined" : _typeof$3(exports)) === 'object' && typeof module !== 'undefined') && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
     ) {
       window.bodymovin = lottie;
     }
-  } catch (err) {//
+  } catch (err) {
+    //
   }
 
   var ShapeModifiers = function () {
@@ -5621,26 +4777,19 @@
     var modifiers = {};
     ob.registerModifier = registerModifier;
     ob.getModifier = getModifier;
-
     function registerModifier(nm, factory) {
       if (!modifiers[nm]) {
         modifiers[nm] = factory;
       }
     }
-
     function getModifier(nm, elem, data) {
       return new modifiers[nm](elem, data);
     }
-
     return ob;
   }();
-
   function ShapeModifier() {}
-
   ShapeModifier.prototype.initModifierProperties = function () {};
-
   ShapeModifier.prototype.addShapeToModifier = function () {};
-
   ShapeModifier.prototype.addShape = function (data) {
     if (!this.closed) {
       // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
@@ -5652,13 +4801,11 @@
       };
       this.shapes.push(shapeData);
       this.addShapeToModifier(shapeData);
-
       if (this._isAnimated) {
         data.setAsAnimated();
       }
     }
   };
-
   ShapeModifier.prototype.init = function (elem, data) {
     this.shapes = [];
     this.elem = elem;
@@ -5667,29 +4814,23 @@
     this.frameId = initialDefaultFrame;
     this.closed = false;
     this.k = false;
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   ShapeModifier.prototype.processKeys = function () {
     if (this.elem.globalData.frameId === this.frameId) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   extendPrototype([DynamicPropertyContainer], ShapeModifier);
 
   function TrimModifier() {}
-
   extendPrototype([ShapeModifier], TrimModifier);
-
   TrimModifier.prototype.initModifierProperties = function (elem, data) {
     this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
     this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
@@ -5700,14 +4841,11 @@
     this.m = data.m;
     this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
   };
-
   TrimModifier.prototype.addShapeToModifier = function (shapeData) {
     shapeData.pathsData = [];
   };
-
   TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
     var segments = [];
-
     if (e <= 1) {
       segments.push({
         s: s,
@@ -5728,65 +4866,50 @@
         e: e - 1
       });
     }
-
     var shapeSegments = [];
     var i;
     var len = segments.length;
     var segmentOb;
-
     for (i = 0; i < len; i += 1) {
       segmentOb = segments[i];
-
       if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
         var shapeS;
         var shapeE;
-
         if (segmentOb.s * totalModifierLength <= addedLength) {
           shapeS = 0;
         } else {
           shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
         }
-
         if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
           shapeE = 1;
         } else {
           shapeE = (segmentOb.e * totalModifierLength - addedLength) / shapeLength;
         }
-
         shapeSegments.push([shapeS, shapeE]);
       }
     }
-
     if (!shapeSegments.length) {
       shapeSegments.push([0, 0]);
     }
-
     return shapeSegments;
   };
-
   TrimModifier.prototype.releasePathsData = function (pathsData) {
     var i;
     var len = pathsData.length;
-
     for (i = 0; i < len; i += 1) {
       segmentsLengthPool.release(pathsData[i]);
     }
-
     pathsData.length = 0;
     return pathsData;
   };
-
   TrimModifier.prototype.processShapes = function (_isFirstFrame) {
     var s;
     var e;
-
     if (this._mdf || _isFirstFrame) {
       var o = this.o.v % 360 / 360;
-
       if (o < 0) {
         o += 1;
       }
-
       if (this.s.v > 1) {
         s = 1 + o;
       } else if (this.s.v < 0) {
@@ -5794,7 +4917,6 @@
       } else {
         s = this.s.v + o;
       }
-
       if (this.e.v > 1) {
         e = 1 + o;
       } else if (this.e.v < 0) {
@@ -5802,13 +4924,11 @@
       } else {
         e = this.e.v + o;
       }
-
       if (s > e) {
         var _s = s;
         s = e;
         e = _s;
       }
-
       s = Math.round(s * 10000) * 0.0001;
       e = Math.round(e * 10000) * 0.0001;
       this.sValue = s;
@@ -5817,7 +4937,6 @@
       s = this.sValue;
       e = this.eValue;
     }
-
     var shapePaths;
     var i;
     var len = this.shapes.length;
@@ -5827,13 +4946,11 @@
     var pathData;
     var totalShapeLength;
     var totalModifierLength = 0;
-
     if (e === s) {
       for (i = 0; i < len; i += 1) {
         this.shapes[i].localShapeCollection.releaseShapes();
         this.shapes[i].shape._mdf = true;
         this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
-
         if (this._mdf) {
           this.shapes[i].pathsData.length = 0;
         }
@@ -5842,63 +4959,52 @@
       var segments = [];
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
-        shapeData = this.shapes[i]; // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
-
+        shapeData = this.shapes[i];
+        // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
         if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
           shapeData.shape.paths = shapeData.localShapeCollection;
         } else {
           shapePaths = shapeData.shape.paths;
           jLen = shapePaths._length;
           totalShapeLength = 0;
-
           if (!shapeData.shape._mdf && shapeData.pathsData.length) {
             totalShapeLength = shapeData.totalShapeLength;
           } else {
             pathsData = this.releasePathsData(shapeData.pathsData);
-
             for (j = 0; j < jLen; j += 1) {
               pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
               pathsData.push(pathData);
               totalShapeLength += pathData.totalLength;
             }
-
             shapeData.totalShapeLength = totalShapeLength;
             shapeData.pathsData = pathsData;
           }
-
           totalModifierLength += totalShapeLength;
           shapeData.shape._mdf = true;
         }
       }
-
       var shapeS = s;
       var shapeE = e;
       var addedLength = 0;
       var edges;
-
       for (i = len - 1; i >= 0; i -= 1) {
         shapeData = this.shapes[i];
-
         if (shapeData.shape._mdf) {
           localShapeCollection = shapeData.localShapeCollection;
-          localShapeCollection.releaseShapes(); // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
-
+          localShapeCollection.releaseShapes();
+          // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
           if (this.m === 2 && len > 1) {
             edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
             addedLength += shapeData.totalShapeLength;
           } else {
             edges = [[shapeS, shapeE]];
           }
-
           jLen = edges.length;
-
           for (j = 0; j < jLen; j += 1) {
             shapeS = edges[j][0];
             shapeE = edges[j][1];
             segments.length = 0;
-
             if (shapeE <= 1) {
               segments.push({
                 s: shapeData.totalShapeLength * shapeS,
@@ -5919,13 +5025,10 @@
                 e: shapeData.totalShapeLength * (shapeE - 1)
               });
             }
-
             var newShapesData = this.addShapes(shapeData, segments[0]);
-
             if (segments[0].s !== segments[0].e) {
               if (segments.length > 1) {
                 var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
-
                 if (lastShapeInCollection.c) {
                   var lastShape = newShapesData.pop();
                   this.addPaths(newShapesData, localShapeCollection);
@@ -5935,11 +5038,9 @@
                   newShapesData = this.addShapes(shapeData, segments[1]);
                 }
               }
-
               this.addPaths(newShapesData, localShapeCollection);
             }
           }
-
           shapeData.shape.paths = localShapeCollection;
         }
       }
@@ -5952,38 +5053,29 @@
       }
     }
   };
-
   TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
     var i;
     var len = newPaths.length;
-
     for (i = 0; i < len; i += 1) {
       localShapeCollection.addShape(newPaths[i]);
     }
   };
-
   TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
     shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
     shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
     }
-
     shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
     shapePath.setXYAt(points[1], points[5], 'o', pos);
     shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
-
     if (newShape) {
       shapePath.setXYAt(points[0], points[4], 'v', pos);
     }
-
     shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
   };
-
   TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
     var pathsData = shapeData.pathsData;
     var shapePaths = shapeData.shape.paths.shapes;
@@ -5999,7 +5091,6 @@
     var shapes = [];
     var initPos;
     var newShape = true;
-
     if (!shapePath) {
       shapePath = shapePool.newElement();
       segmentCount = 0;
@@ -6008,17 +5099,13 @@
       segmentCount = shapePath._length;
       initPos = shapePath._length;
     }
-
     shapes.push(shapePath);
-
     for (i = 0; i < len; i += 1) {
       lengths = pathsData[i].lengths;
       shapePath.c = shapePaths[i].c;
       jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
-
       for (j = 1; j < jLen; j += 1) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
           addedLength += currentLengthData.addedLength;
           shapePath.c = false;
@@ -6031,50 +5118,42 @@
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
-
           addedLength += currentLengthData.addedLength;
           segmentCount += 1;
         }
       }
-
       if (shapePaths[i].c && lengths.length) {
         currentLengthData = lengths[j - 1];
-
         if (addedLength <= shapeSegment.e) {
           var segmentLength = lengths[j - 1].addedLength;
-
           if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
             this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
             newShape = false;
           } else {
             segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
-            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape); // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-
+            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
+            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
             newShape = false;
             shapePath.c = false;
           }
         } else {
           shapePath.c = false;
         }
-
         addedLength += currentLengthData.addedLength;
         segmentCount += 1;
       }
-
       if (shapePath._length) {
         shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
         shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
       }
-
       if (addedLength > shapeSegment.e) {
         break;
       }
-
       if (i < len - 1) {
         shapePath = shapePool.newElement();
         newShape = true;
@@ -6082,31 +5161,25 @@
         segmentCount = 0;
       }
     }
-
     return shapes;
   };
 
   function PuckerAndBloatModifier() {}
-
   extendPrototype([ShapeModifier], PuckerAndBloatModifier);
-
   PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
     this._isAnimated = !!this.amount.effectsSequence.length;
   };
-
   PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
     var percent = amount / 100;
     var centerPoint = [0, 0];
     var pathLength = path._length;
     var i = 0;
-
     for (i = 0; i < pathLength; i += 1) {
       centerPoint[0] += path.v[i][0];
       centerPoint[1] += path.v[i][1];
     }
-
     centerPoint[0] /= pathLength;
     centerPoint[1] /= pathLength;
     var clonedPath = shapePool.newElement();
@@ -6117,7 +5190,6 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < pathLength; i += 1) {
       vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
       vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
@@ -6127,10 +5199,8 @@
       iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
       clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
     }
-
     return clonedPath;
   };
-
   PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6138,30 +5208,24 @@
     var j;
     var jLen;
     var amount = this.amount.v;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6169,30 +5233,24 @@
 
   var TransformPropertyFactory = function () {
     var defaultVector = [0, 0];
-
     function applyToMatrix(mat) {
       var _mdf = this._mdf;
       this.iterateDynamicProperties();
       this._mdf = this._mdf || _mdf;
-
       if (this.a) {
         mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
       }
-
       if (this.s) {
         mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
       }
-
       if (this.sk) {
         mat.skewFromAxis(-this.sk.v, this.sa.v);
       }
-
       if (this.r) {
         mat.rotate(-this.r.v);
       } else {
         mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
       }
-
       if (this.data.p.s) {
         if (this.data.p.z) {
           mat.translate(this.px.v, this.py.v, -this.pz.v);
@@ -6203,46 +5261,36 @@
         mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
       }
     }
-
     function processKeys(forceRender) {
       if (this.elem.globalData.frameId === this.frameId) {
         return;
       }
-
       if (this._isDirty) {
         this.precalculateMatrix();
         this._isDirty = false;
       }
-
       this.iterateDynamicProperties();
-
       if (this._mdf || forceRender) {
         var frameRate;
         this.v.cloneFromProps(this.pre.props);
-
         if (this.appliedTransformations < 1) {
           this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         }
-
         if (this.appliedTransformations < 2) {
           this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         }
-
         if (this.sk && this.appliedTransformations < 3) {
           this.v.skewFromAxis(-this.sk.v, this.sa.v);
         }
-
         if (this.r && this.appliedTransformations < 4) {
           this.v.rotate(-this.r.v);
         } else if (!this.r && this.appliedTransformations < 4) {
           this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
         }
-
         if (this.autoOriented) {
           var v1;
           var v2;
           frameRate = this.elem.globalData.frameRate;
-
           if (this.p && this.p.keyframes && this.p.getValueAtTime) {
             if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
               v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
@@ -6259,7 +5307,6 @@
             v2 = [];
             var px = this.px;
             var py = this.py;
-
             if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
               v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
               v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
@@ -6279,10 +5326,8 @@
             v2 = defaultVector;
             v1 = v2;
           }
-
           this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
         }
-
         if (this.data.p && this.data.p.s) {
           if (this.data.p.z) {
             this.v.translate(this.px.v, this.py.v, -this.pz.v);
@@ -6293,28 +5338,23 @@
           this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
         }
       }
-
       this.frameId = this.elem.globalData.frameId;
     }
-
     function precalculateMatrix() {
       this.appliedTransformations = 0;
       this.pre.reset();
-
       if (!this.a.effectsSequence.length) {
         this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
         this.appliedTransformations = 1;
       } else {
         return;
       }
-
       if (!this.s.effectsSequence.length) {
         this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
         this.appliedTransformations = 2;
       } else {
         return;
       }
-
       if (this.sk) {
         if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
           this.pre.skewFromAxis(-this.sk.v, this.sa.v);
@@ -6323,7 +5363,6 @@
           return;
         }
       }
-
       if (this.r) {
         if (!this.r.effectsSequence.length) {
           this.pre.rotate(-this.r.v);
@@ -6334,33 +5373,28 @@
         this.appliedTransformations = 4;
       }
     }
-
-    function autoOrient() {//
+    function autoOrient() {
+      //
       // var prevP = this.getValueAtTime();
     }
-
     function addDynamicProperty(prop) {
       this._addDynamicProperty(prop);
-
       this.elem.addDynamicProperty(prop);
       this._isDirty = true;
     }
-
     function TransformProperty(elem, data, container) {
       this.elem = elem;
       this.frameId = -1;
       this.propType = 'transform';
       this.data = data;
-      this.v = new Matrix(); // Precalculated matrix with non animated properties
-
+      this.v = new Matrix();
+      // Precalculated matrix with non animated properties
       this.pre = new Matrix();
       this.appliedTransformations = 0;
       this.initDynamicPropertyContainer(container || elem);
-
       if (data.p && data.p.s) {
         this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
         this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
-
         if (data.p.z) {
           this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
         }
@@ -6369,43 +5403,37 @@
           k: [0, 0, 0]
         }, 1, 0, this);
       }
-
       if (data.rx) {
         this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
         this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
         this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
-
         if (data.or.k[0].ti) {
           var i;
           var len = data.or.k.length;
-
           for (i = 0; i < len; i += 1) {
             data.or.k[i].to = null;
             data.or.k[i].ti = null;
           }
         }
-
-        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this); // sh Indicates it needs to be capped between -180 and 180
-
+        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
+        // sh Indicates it needs to be capped between -180 and 180
         this.or.sh = true;
       } else {
         this.r = PropertyFactory.getProp(elem, data.r || {
           k: 0
         }, 0, degToRads, this);
       }
-
       if (data.sk) {
         this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
         this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
       }
-
       this.a = PropertyFactory.getProp(elem, data.a || {
         k: [0, 0, 0]
       }, 1, 0, this);
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: [100, 100, 100]
-      }, 1, 0.01, this); // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
-
+      }, 1, 0.01, this);
+      // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
       if (data.o) {
         this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
       } else {
@@ -6414,14 +5442,11 @@
           v: 1
         };
       }
-
       this._isDirty = true;
-
       if (!this.dynamicProperties.length) {
         this.getValue(true);
       }
     }
-
     TransformProperty.prototype = {
       applyToMatrix: applyToMatrix,
       getValue: processKeys,
@@ -6431,20 +5456,16 @@
     extendPrototype([DynamicPropertyContainer], TransformProperty);
     TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
     TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
-
     function getTransformProperty(elem, data, container) {
       return new TransformProperty(elem, data, container);
     }
-
     return {
       getTransformProperty: getTransformProperty
     };
   }();
 
   function RepeaterModifier() {}
-
   extendPrototype([ShapeModifier], RepeaterModifier);
-
   RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
@@ -6453,11 +5474,9 @@
     this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
     this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
     this.data = data;
-
     if (!this.dynamicProperties.length) {
       this.getValue(true);
     }
-
     this._isAnimated = !!this.dynamicProperties.length;
     this.pMatrix = new Matrix();
     this.rMatrix = new Matrix();
@@ -6465,7 +5484,6 @@
     this.tMatrix = new Matrix();
     this.matrix = new Matrix();
   };
-
   RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
     var dir = inv ? -1 : 1;
     var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
@@ -6478,7 +5496,6 @@
     sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
     sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
   };
-
   RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
     this.elem = elem;
     this.arr = arr;
@@ -6490,52 +5507,42 @@
     this.frameId = -1;
     this.initDynamicPropertyContainer(elem);
     this.initModifierProperties(elem, arr[pos]);
-
     while (pos > 0) {
-      pos -= 1; // this._elements.unshift(arr.splice(pos,1)[0]);
-
+      pos -= 1;
+      // this._elements.unshift(arr.splice(pos,1)[0]);
       this._elements.unshift(arr[pos]);
     }
-
     if (this.dynamicProperties.length) {
       this.k = true;
     } else {
       this.getValue(true);
     }
   };
-
   RepeaterModifier.prototype.resetElements = function (elements) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._processed = false;
-
       if (elements[i].ty === 'gr') {
         this.resetElements(elements[i].it);
       }
     }
   };
-
   RepeaterModifier.prototype.cloneElements = function (elements) {
     var newElements = JSON.parse(JSON.stringify(elements));
     this.resetElements(newElements);
     return newElements;
   };
-
   RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
     var i;
     var len = elements.length;
-
     for (i = 0; i < len; i += 1) {
       elements[i]._render = renderFlag;
-
       if (elements[i].ty === 'gr') {
         this.changeGroupRender(elements[i].it, renderFlag);
       }
     }
   };
-
   RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
     var items;
     var itemsTransform;
@@ -6543,10 +5550,8 @@
     var dir;
     var cont;
     var hasReloaded = false;
-
     if (this._mdf || _isFirstFrame) {
       var copies = Math.ceil(this.c.v);
-
       if (this._groups.length < copies) {
         while (this._groups.length < copies) {
           var group = {
@@ -6601,28 +5606,21 @@
             ty: 'tr'
           });
           this.arr.splice(0, 0, group);
-
           this._groups.splice(0, 0, group);
-
           this._currentCopies += 1;
         }
-
         this.elem.reloadShapes();
         hasReloaded = true;
       }
-
       cont = 0;
       var renderFlag;
-
       for (i = 0; i <= this._groups.length - 1; i += 1) {
         renderFlag = cont < copies;
         this._groups[i]._render = renderFlag;
         this.changeGroupRender(this._groups[i].it, renderFlag);
-
         if (!renderFlag) {
           var elems = this.elemsData[i].it;
           var transformData = elems[elems.length - 1];
-
           if (transformData.transform.op.v !== 0) {
             transformData.transform.op._mdf = true;
             transformData.transform.op.v = 0;
@@ -6630,11 +5628,10 @@
             transformData.transform.op._mdf = false;
           }
         }
-
         cont += 1;
       }
-
-      this._currentCopies = copies; /// /
+      this._currentCopies = copies;
+      /// /
 
       var offset = this.o.v;
       var offsetModulo = offset % 1;
@@ -6648,13 +5645,11 @@
       this.tMatrix.reset();
       this.matrix.reset();
       var iteration = 0;
-
       if (offset > 0) {
         while (iteration < roundOffset) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           iteration += 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
           iteration += offsetModulo;
@@ -6664,19 +5659,16 @@
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
           iteration -= 1;
         }
-
         if (offsetModulo) {
           this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
           iteration -= offsetModulo;
         }
       }
-
       i = this.data.m === 1 ? 0 : this._currentCopies - 1;
       dir = this.data.m === 1 ? 1 : -1;
       cont = this._currentCopies;
       var j;
       var jLen;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6684,29 +5676,23 @@
         items[items.length - 1].transform.mProps._mdf = true;
         items[items.length - 1].transform.op._mdf = true;
         items[items.length - 1].transform.op.v = this._currentCopies === 1 ? this.so.v : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
-
         if (iteration !== 0) {
           if (i !== 0 && dir === 1 || i !== this._currentCopies - 1 && dir === -1) {
             this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
           }
-
           this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
           this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
           this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
-
           this.matrix.reset();
         } else {
           this.matrix.reset();
-
           for (j = 0; j < jLen; j += 1) {
             itemsTransform[j] = this.matrix.props[j];
           }
         }
-
         iteration += 1;
         cont -= 1;
         i += dir;
@@ -6715,7 +5701,6 @@
       cont = this._currentCopies;
       i = 0;
       dir = 1;
-
       while (cont) {
         items = this.elemsData[i].it;
         itemsTransform = items[items.length - 1].transform.mProps.v.props;
@@ -6725,22 +5710,17 @@
         i += dir;
       }
     }
-
     return hasReloaded;
   };
-
   RepeaterModifier.prototype.addShape = function () {};
 
   function RoundCornersModifier() {}
-
   extendPrototype([ShapeModifier], RoundCornersModifier);
-
   RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
     this._isAnimated = !!this.rd.effectsSequence.length;
   };
-
   RoundCornersModifier.prototype.processPath = function (path, round) {
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
@@ -6759,19 +5739,16 @@
     var oY;
     var iX;
     var iY;
-
     for (i = 0; i < len; i += 1) {
       currentV = path.v[i];
       currentO = path.o[i];
       currentI = path.i[i];
-
       if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
         if ((i === 0 || i === len - 1) && !path.c) {
           clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
           /* clonedPath.v[index] = currentV;
                   clonedPath.o[index] = currentO;
                   clonedPath.i[index] = currentI; */
-
           index += 1;
         } else {
           if (i === 0) {
@@ -6779,7 +5756,6 @@
           } else {
             closerV = path.v[i - 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6790,13 +5766,11 @@
           oY = vY - (vY - currentV[1]) * roundCorner;
           clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
           index += 1;
-
           if (i === len - 1) {
             closerV = path.v[0];
           } else {
             closerV = path.v[i + 1];
           }
-
           distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
           newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
           oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
@@ -6813,10 +5787,8 @@
         index += 1;
       }
     }
-
     return clonedPath;
   };
-
   RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -6824,30 +5796,24 @@
     var j;
     var jLen;
     var rd = this.rd.v;
-
     if (rd !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -6856,50 +5822,41 @@
   function floatEqual(a, b) {
     return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
   }
-
   function floatZero(f) {
     return Math.abs(f) <= 0.00001;
   }
-
   function lerp(p0, p1, amount) {
     return p0 * (1 - amount) + p1 * amount;
   }
-
   function lerpPoint(p0, p1, amount) {
     return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
   }
-
   function quadRoots(a, b, c) {
     // no root
     if (a === 0) return [];
-    var s = b * b - 4 * a * c; // Complex roots
-
+    var s = b * b - 4 * a * c;
+    // Complex roots
     if (s < 0) return [];
-    var singleRoot = -b / (2 * a); // 1 root
-
+    var singleRoot = -b / (2 * a);
+    // 1 root
     if (s === 0) return [singleRoot];
-    var delta = Math.sqrt(s) / (2 * a); // 2 roots
-
+    var delta = Math.sqrt(s) / (2 * a);
+    // 2 roots
     return [singleRoot - delta, singleRoot + delta];
   }
-
   function polynomialCoefficients(p0, p1, p2, p3) {
     return [-p0 + 3 * p1 - 3 * p2 + p3, 3 * p0 - 6 * p1 + 3 * p2, -3 * p0 + 3 * p1, p0];
   }
-
   function singlePoint(p) {
     return new PolynomialBezier(p, p, p, p, false);
   }
-
   function PolynomialBezier(p0, p1, p2, p3, linearize) {
     if (linearize && pointEqual(p0, p1)) {
       p1 = lerpPoint(p0, p3, 1 / 3);
     }
-
     if (linearize && pointEqual(p2, p3)) {
       p2 = lerpPoint(p0, p3, 2 / 3);
     }
-
     var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
     var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
     this.a = [coeffx[0], coeffy[0]];
@@ -6908,25 +5865,20 @@
     this.d = [coeffx[3], coeffy[3]];
     this.points = [p0, p1, p2, p3];
   }
-
   PolynomialBezier.prototype.point = function (t) {
     return [((this.a[0] * t + this.b[0]) * t + this.c[0]) * t + this.d[0], ((this.a[1] * t + this.b[1]) * t + this.c[1]) * t + this.d[1]];
   };
-
   PolynomialBezier.prototype.derivative = function (t) {
     return [(3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0], (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1]];
   };
-
   PolynomialBezier.prototype.tangentAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[1], p[0]);
   };
-
   PolynomialBezier.prototype.normalAngle = function (t) {
     var p = this.derivative(t);
     return Math.atan2(p[0], p[1]);
   };
-
   PolynomialBezier.prototype.inflectionPoints = function () {
     var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
     if (floatZero(denom)) return [];
@@ -6934,17 +5886,14 @@
     var square = tcusp * tcusp - 1 / 3 * (this.b[1] * this.c[0] - this.b[0] * this.c[1]) / denom;
     if (square < 0) return [];
     var root = Math.sqrt(square);
-
     if (floatZero(root)) {
       if (root > 0 && root < 1) return [tcusp];
       return [];
     }
-
     return [tcusp - root, tcusp + root].filter(function (r) {
       return r > 0 && r < 1;
     });
   };
-
   PolynomialBezier.prototype.split = function (t) {
     if (t <= 0) return [singlePoint(this.points[0]), this];
     if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
@@ -6956,40 +5905,33 @@
     var p3 = lerpPoint(p20, p21, t);
     return [new PolynomialBezier(this.points[0], p10, p20, p3, true), new PolynomialBezier(p3, p21, p12, this.points[3], true)];
   };
-
   function extrema(bez, comp) {
     var min = bez.points[0][comp];
     var max = bez.points[bez.points.length - 1][comp];
-
     if (min > max) {
       var e = max;
       max = min;
       min = e;
-    } // Derivative roots to find min/max
-
-
+    }
+    // Derivative roots to find min/max
     var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
-
     for (var i = 0; i < f.length; i += 1) {
       if (f[i] > 0 && f[i] < 1) {
         var val = bez.point(f[i])[comp];
         if (val < min) min = val;else if (val > max) max = val;
       }
     }
-
     return {
       min: min,
       max: max
     };
   }
-
   PolynomialBezier.prototype.bounds = function () {
     return {
       x: extrema(this, 0),
       y: extrema(this, 1)
     };
   };
-
   PolynomialBezier.prototype.boundingBox = function () {
     var bounds = this.bounds();
     return {
@@ -7003,7 +5945,6 @@
       cy: (bounds.y.max + bounds.y.min) / 2
     };
   };
-
   function intersectData(bez, t1, t2) {
     var box = bez.boundingBox();
     return {
@@ -7017,24 +5958,19 @@
       t2: t2
     };
   }
-
   function splitData(data) {
     var split = data.bez.split(0.5);
     return [intersectData(split[0], data.t1, data.t), intersectData(split[1], data.t, data.t2)];
   }
-
   function boxIntersect(b1, b2) {
     return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
   }
-
   function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
     if (!boxIntersect(d1, d2)) return;
-
     if (depth >= maxRecursion || d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance) {
       intersections.push([d1.t, d2.t]);
       return;
     }
-
     var d1s = splitData(d1);
     var d2s = splitData(d2);
     intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
@@ -7042,7 +5978,6 @@
     intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
     intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
   }
-
   PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
     if (tolerance === undefined) tolerance = 2;
     if (maxRecursion === undefined) maxRecursion = 7;
@@ -7050,21 +5985,17 @@
     intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
     return intersections;
   };
-
   PolynomialBezier.shapeSegment = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
   };
-
   PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
     var nextIndex = (index + 1) % shapePath.length();
     return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
   };
-
   function crossProduct(a, b) {
     return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
   }
-
   function lineIntersection(start1, end1, start2, end2) {
     var v1 = [start1[0], start1[1], 1];
     var v2 = [end1[0], end1[1], 1];
@@ -7074,23 +6005,18 @@
     if (floatZero(r[2])) return null;
     return [r[0] / r[2], r[1] / r[2]];
   }
-
   function polarOffset(p, angle, length) {
     return [p[0] + Math.cos(angle) * length, p[1] - Math.sin(angle) * length];
   }
-
   function pointDistance(p1, p2) {
     return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
   }
-
   function pointEqual(p1, p2) {
     return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
   }
 
   function ZigZagModifier() {}
-
   extendPrototype([ShapeModifier], ZigZagModifier);
-
   ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
@@ -7098,7 +6024,6 @@
     this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
     this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
   };
-
   function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
     var angO = angle - Math.PI / 2;
     var angI = angle + Math.PI / 2;
@@ -7106,14 +6031,12 @@
     var py = point[1] - Math.sin(angle) * direction * amplitude;
     outputBezier.setTripleAt(px, py, px + Math.cos(angO) * outAmplitude, py - Math.sin(angO) * outAmplitude, px + Math.cos(angI) * inAmplitude, py - Math.sin(angI) * inAmplitude, outputBezier.length());
   }
-
   function getPerpendicularVector(pt1, pt2) {
     var vector = [pt2[0] - pt1[0], pt2[1] - pt1[1]];
     var rot = -Math.PI * 0.5;
     var rotatedVector = [Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1], Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1]];
     return rotatedVector;
   }
-
   function getProjectingAngle(path, cur) {
     var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
     var nextIndex = (cur + 1) % path.length();
@@ -7122,7 +6045,6 @@
     var pVector = getPerpendicularVector(prevPoint, nextPoint);
     return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
   }
-
   function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
     var angle = getProjectingAngle(path, cur);
     var point = path.v[cur % path._length];
@@ -7132,7 +6054,6 @@
     var nextDist = pointType === 2 ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2)) : 0;
     setPoint(outputBezier, path.v[cur % path._length], angle, direction, amplitude, nextDist / ((frequency + 1) * 2), prevDist / ((frequency + 1) * 2), pointType);
   }
-
   function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
     for (var i = 0; i < frequency; i += 1) {
       var t = (i + 1) / (frequency + 1);
@@ -7142,39 +6063,30 @@
       setPoint(outputBezier, point, angle, direction, amplitude, dist / ((frequency + 1) * 2), dist / ((frequency + 1) * 2), pointType);
       direction = -direction;
     }
-
     return direction;
   }
-
   ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
     var count = path._length;
     var clonedPath = shapePool.newElement();
     clonedPath.c = path.c;
-
     if (!path.c) {
       count -= 1;
     }
-
     if (count === 0) return clonedPath;
     var direction = -1;
     var segment = PolynomialBezier.shapeSegment(path, 0);
     zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
-
     for (var i = 0; i < count; i += 1) {
       direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
-
       if (i === count - 1 && !path.c) {
         segment = null;
       } else {
         segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
       }
-
       zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
     }
-
     return clonedPath;
   };
-
   ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -7184,30 +6096,24 @@
     var amplitude = this.amplitude.v;
     var frequency = Math.max(0, Math.round(this.frequency.v));
     var pointType = this.pointsType.v;
-
     if (amplitude !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -7217,7 +6123,6 @@
     var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
     return [polarOffset(p1, angle, amount), polarOffset(p2, angle, amount)];
   }
-
   function offsetSegment(segment, amount) {
     var p0;
     var p1a;
@@ -7241,15 +6146,17 @@
     if (p2 === null) p2 = p2a;
     return new PolynomialBezier(p0, p1, p2, p3);
   }
-
   function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
     var p0 = seg1.points[3];
-    var p1 = seg2.points[0]; // Bevel
+    var p1 = seg2.points[0];
 
-    if (lineJoin === 3) return p0; // Connected, they don't need a joint
+    // Bevel
+    if (lineJoin === 3) return p0;
 
-    if (pointEqual(p0, p1)) return p0; // Round
+    // Connected, they don't need a joint
+    if (pointEqual(p0, p1)) return p0;
 
+    // Round
     if (lineJoin === 2) {
       var angleOut = -seg1.tangentAngle(1);
       var angleIn = -seg2.tangentAngle(0) + Math.PI;
@@ -7260,91 +6167,75 @@
       tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
       outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
       return p1;
-    } // Miter
+    }
 
-
+    // Miter
     var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
     var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
     var intersection = lineIntersection(t0, p0, p1, t1);
-
     if (intersection && pointDistance(intersection, p0) < miterLimit) {
       outputBezier.setTripleAt(intersection[0], intersection[1], intersection[0], intersection[1], intersection[0], intersection[1], outputBezier.length());
       return intersection;
     }
-
     return p0;
   }
-
   function getIntersection(a, b) {
     var intersect = a.intersections(b);
     if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
     if (intersect.length) return intersect[0];
     return null;
   }
-
   function pruneSegmentIntersection(a, b) {
     var outa = a.slice();
     var outb = b.slice();
     var intersect = getIntersection(a[a.length - 1], b[0]);
-
     if (intersect) {
       outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
       outb[0] = b[0].split(intersect[1])[1];
     }
-
     if (a.length > 1 && b.length > 1) {
       intersect = getIntersection(a[0], b[b.length - 1]);
-
       if (intersect) {
         return [[a[0].split(intersect[0])[0]], [b[b.length - 1].split(intersect[1])[1]]];
       }
     }
-
     return [outa, outb];
   }
-
   function pruneIntersections(segments) {
     var e;
-
     for (var i = 1; i < segments.length; i += 1) {
       e = pruneSegmentIntersection(segments[i - 1], segments[i]);
       segments[i - 1] = e[0];
       segments[i] = e[1];
     }
-
     if (segments.length > 1) {
       e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
       segments[segments.length - 1] = e[0];
       segments[0] = e[1];
     }
-
     return segments;
   }
-
   function offsetSegmentSplit(segment, amount) {
     /*
       We split each bezier segment into smaller pieces based
       on inflection points, this ensures the control point
       polygon is convex.
-        (A cubic bezier can have none, one, or two inflection points)
+       (A cubic bezier can have none, one, or two inflection points)
     */
     var flex = segment.inflectionPoints();
     var left;
     var right;
     var split;
     var mid;
-
     if (flex.length === 0) {
       return [offsetSegment(segment, amount)];
     }
-
     if (flex.length === 1 || floatEqual(flex[1], 1)) {
       split = segment.split(flex[0]);
       left = split[0];
       right = split[1];
       return [offsetSegment(left, amount), offsetSegment(right, amount)];
     }
-
     split = segment.split(flex[0]);
     left = split[0];
     var t = (flex[1] - flex[0]) / (1 - flex[0]);
@@ -7353,11 +6244,8 @@
     right = split[1];
     return [offsetSegment(left, amount), offsetSegment(mid, amount), offsetSegment(right, amount)];
   }
-
   function OffsetPathModifier() {}
-
   extendPrototype([ShapeModifier], OffsetPathModifier);
-
   OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
     this.getValue = this.processKeys;
     this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
@@ -7365,61 +6253,50 @@
     this.lineJoin = data.lj;
     this._isAnimated = this.amount.effectsSequence.length !== 0;
   };
-
   OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
     var outputBezier = shapePool.newElement();
     outputBezier.c = inputBezier.c;
     var count = inputBezier.length();
-
     if (!inputBezier.c) {
       count -= 1;
     }
-
     var i;
     var j;
     var segment;
     var multiSegments = [];
-
     for (i = 0; i < count; i += 1) {
       segment = PolynomialBezier.shapeSegment(inputBezier, i);
       multiSegments.push(offsetSegmentSplit(segment, amount));
     }
-
     if (!inputBezier.c) {
       for (i = count - 1; i >= 0; i -= 1) {
         segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
         multiSegments.push(offsetSegmentSplit(segment, amount));
       }
     }
+    multiSegments = pruneIntersections(multiSegments);
 
-    multiSegments = pruneIntersections(multiSegments); // Add bezier segments to the output and apply line joints
-
+    // Add bezier segments to the output and apply line joints
     var lastPoint = null;
     var lastSeg = null;
-
     for (i = 0; i < multiSegments.length; i += 1) {
       var multiSegment = multiSegments[i];
       if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
       lastSeg = multiSegment[multiSegment.length - 1];
-
       for (j = 0; j < multiSegment.length; j += 1) {
         segment = multiSegment[j];
-
         if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
           outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
         } else {
           outputBezier.setTripleAt(segment.points[0][0], segment.points[0][1], segment.points[1][0], segment.points[1][1], segment.points[0][0], segment.points[0][1], outputBezier.length());
         }
-
         outputBezier.setTripleAt(segment.points[3][0], segment.points[3][1], segment.points[3][0], segment.points[3][1], segment.points[2][0], segment.points[2][1], outputBezier.length());
         lastPoint = segment.points[3];
       }
     }
-
     if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
     return outputBezier;
   };
-
   OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
     var shapePaths;
     var i;
@@ -7429,30 +6306,24 @@
     var amount = this.amount.v;
     var miterLimit = this.miterLimit.v;
     var lineJoin = this.lineJoin;
-
     if (amount !== 0) {
       var shapeData;
       var localShapeCollection;
-
       for (i = 0; i < len; i += 1) {
         shapeData = this.shapes[i];
         localShapeCollection = shapeData.localShapeCollection;
-
         if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
           localShapeCollection.releaseShapes();
           shapeData.shape._mdf = true;
           shapePaths = shapeData.shape.paths.shapes;
           jLen = shapeData.shape.paths._length;
-
           for (j = 0; j < jLen; j += 1) {
             localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
           }
         }
-
         shapeData.shape.paths = shapeData.localShapeCollection;
       }
     }
-
     if (!this.dynamicProperties.length) {
       this._mdf = false;
     }
@@ -7464,42 +6335,33 @@
     var fStyle = 'normal';
     var len = styles.length;
     var styleName;
-
     for (var i = 0; i < len; i += 1) {
       styleName = styles[i].toLowerCase();
-
       switch (styleName) {
         case 'italic':
           fStyle = 'italic';
           break;
-
         case 'bold':
           fWeight = '700';
           break;
-
         case 'black':
           fWeight = '900';
           break;
-
         case 'medium':
           fWeight = '500';
           break;
-
         case 'regular':
         case 'normal':
           fWeight = '400';
           break;
-
         case 'light':
         case 'thin':
           fWeight = '200';
           break;
-
         default:
           break;
       }
     }
-
     return {
       style: fStyle,
       weight: fontData.fWeight || fWeight
@@ -7516,8 +6378,8 @@
         shapes: []
       }
     };
-    var combinedCharacters = []; // Hindi characters
-
+    var combinedCharacters = [];
+    // Hindi characters
     combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
     var BLACK_FLAG_CODE_POINT = 127988;
     var CANCEL_TAG_CODE_POINT = 917631;
@@ -7528,44 +6390,41 @@
     var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
     var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
     var surrogateModifiers = ['d83cdffb', 'd83cdffc', 'd83cdffd', 'd83cdffe', 'd83cdfff'];
-
     function trimFontOptions(font) {
       var familyArray = font.split(',');
       var i;
       var len = familyArray.length;
       var enabledFamilies = [];
-
       for (i = 0; i < len; i += 1) {
         if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
           enabledFamilies.push(familyArray[i]);
         }
       }
-
       return enabledFamilies.join(',');
     }
-
     function setUpNode(font, family) {
-      var parentNode = createTag('span'); // Node is invisible to screen readers.
-
+      var parentNode = createTag('span');
+      // Node is invisible to screen readers.
       parentNode.setAttribute('aria-hidden', true);
       parentNode.style.fontFamily = family;
-      var node = createTag('span'); // Characters that vary significantly among different fonts
-
-      node.innerText = 'giItT1WQy@!-/#'; // Visible - so we can measure it - but not on the screen
-
+      var node = createTag('span');
+      // Characters that vary significantly among different fonts
+      node.innerText = 'giItT1WQy@!-/#';
+      // Visible - so we can measure it - but not on the screen
       parentNode.style.position = 'absolute';
       parentNode.style.left = '-10000px';
-      parentNode.style.top = '-10000px'; // Large font size makes even subtle changes obvious
-
-      parentNode.style.fontSize = '300px'; // Reset any font properties
-
+      parentNode.style.top = '-10000px';
+      // Large font size makes even subtle changes obvious
+      parentNode.style.fontSize = '300px';
+      // Reset any font properties
       parentNode.style.fontVariant = 'normal';
       parentNode.style.fontStyle = 'normal';
       parentNode.style.fontWeight = 'normal';
       parentNode.style.letterSpacing = '0';
       parentNode.appendChild(node);
-      document.body.appendChild(parentNode); // Remember width with no applied web font
+      document.body.appendChild(parentNode);
 
+      // Remember width with no applied web font
       var width = node.offsetWidth;
       node.style.fontFamily = trimFontOptions(font) + ', ' + family;
       return {
@@ -7574,14 +6433,12 @@
         parent: parentNode
       };
     }
-
     function checkLoadedFonts() {
       var i;
       var len = this.fonts.length;
       var node;
       var w;
       var loadedCount = len;
-
       for (i = 0; i < len; i += 1) {
         if (this.fonts[i].loaded) {
           loadedCount -= 1;
@@ -7590,55 +6447,47 @@
         } else {
           node = this.fonts[i].monoCase.node;
           w = this.fonts[i].monoCase.w;
-
           if (node.offsetWidth !== w) {
             loadedCount -= 1;
             this.fonts[i].loaded = true;
           } else {
             node = this.fonts[i].sansCase.node;
             w = this.fonts[i].sansCase.w;
-
             if (node.offsetWidth !== w) {
               loadedCount -= 1;
               this.fonts[i].loaded = true;
             }
           }
-
           if (this.fonts[i].loaded) {
             this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
             this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
           }
         }
       }
-
       if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
         setTimeout(this.checkLoadedFontsBinded, 20);
       } else {
         setTimeout(this.setIsLoadedBinded, 10);
       }
     }
-
     function createHelper(fontData, def) {
       var engine = document.body && def ? 'svg' : 'canvas';
       var helper;
       var fontProps = getFontProperties(fontData);
-
       if (engine === 'svg') {
         var tHelper = createNS('text');
-        tHelper.style.fontSize = '100px'; // tHelper.style.fontFamily = fontData.fFamily;
-
+        tHelper.style.fontSize = '100px';
+        // tHelper.style.fontFamily = fontData.fFamily;
         tHelper.setAttribute('font-family', fontData.fFamily);
         tHelper.setAttribute('font-style', fontProps.style);
         tHelper.setAttribute('font-weight', fontProps.weight);
         tHelper.textContent = '1';
-
         if (fontData.fClass) {
           tHelper.style.fontFamily = 'inherit';
           tHelper.setAttribute('class', fontData.fClass);
         } else {
           tHelper.style.fontFamily = fontData.fFamily;
         }
-
         def.appendChild(tHelper);
         helper = tHelper;
       } else {
@@ -7646,33 +6495,27 @@
         tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
         helper = tCanvasHelper;
       }
-
       function measure(text) {
         if (engine === 'svg') {
           helper.textContent = text;
           return helper.getComputedTextLength();
         }
-
         return helper.measureText(text).width;
       }
-
       return {
         measureText: measure
       };
     }
-
     function addFonts(fontData, defs) {
       if (!fontData) {
         this.isLoaded = true;
         return;
       }
-
       if (this.chars) {
         this.isLoaded = true;
         this.fonts = fontData.list;
         return;
       }
-
       if (!document.body) {
         this.isLoaded = true;
         fontData.list.forEach(function (data) {
@@ -7682,12 +6525,10 @@
         this.fonts = fontData.list;
         return;
       }
-
       var fontArr = fontData.list;
       var i;
       var len = fontArr.length;
       var _pendingFonts = len;
-
       for (i = 0; i < len; i += 1) {
         var shouldLoadFont = true;
         var loadedSelector;
@@ -7695,17 +6536,14 @@
         fontArr[i].loaded = false;
         fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
         fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
-
         if (!fontArr[i].fPath) {
           fontArr[i].loaded = true;
           _pendingFonts -= 1;
         } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
           loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
-
           if (loadedSelector.length > 0) {
             shouldLoadFont = false;
           }
-
           if (shouldLoadFont) {
             var s = createTag('style');
             s.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7717,14 +6555,12 @@
           }
         } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
           loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var l = createTag('link');
             l.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7736,14 +6572,12 @@
           }
         } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
           loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
-
           for (j = 0; j < loadedSelector.length; j += 1) {
             if (fontArr[i].fPath === loadedSelector[j].src) {
               // Font is already loaded
               shouldLoadFont = false;
             }
           }
-
           if (shouldLoadFont) {
             var sc = createTag('link');
             sc.setAttribute('f-forigin', fontArr[i].fOrigin);
@@ -7753,12 +6587,10 @@
             defs.appendChild(sc);
           }
         }
-
         fontArr[i].helper = createHelper(fontArr[i], defs);
         fontArr[i].cache = {};
         this.fonts.push(fontArr[i]);
       }
-
       if (_pendingFonts === 0) {
         this.isLoaded = true;
       } else {
@@ -7767,71 +6599,56 @@
         setTimeout(this.checkLoadedFonts.bind(this), 100);
       }
     }
-
     function addChars(chars) {
       if (!chars) {
         return;
       }
-
       if (!this.chars) {
         this.chars = [];
       }
-
       var i;
       var len = chars.length;
       var j;
       var jLen = this.chars.length;
       var found;
-
       for (i = 0; i < len; i += 1) {
         j = 0;
         found = false;
-
         while (j < jLen) {
           if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
             found = true;
           }
-
           j += 1;
         }
-
         if (!found) {
           this.chars.push(chars[i]);
           jLen += 1;
         }
       }
     }
-
     function getCharData(_char, style, font) {
       var i = 0;
       var len = this.chars.length;
-
       while (i < len) {
         if (this.chars[i].ch === _char && this.chars[i].style === style && this.chars[i].fFamily === font) {
           return this.chars[i];
         }
-
         i += 1;
       }
-
       if ((typeof _char === 'string' && _char.charCodeAt(0) !== 13 || !_char) && console && console.warn // eslint-disable-line no-console
       && !this._warned) {
         this._warned = true;
         console.warn('Missing character from exported characters list: ', _char, style, font); // eslint-disable-line no-console
       }
-
       return emptyChar;
     }
-
     function measureText(_char2, fontName, size) {
-      var fontData = this.getFontByName(fontName); // Using the char instead of char.charCodeAt(0)
+      var fontData = this.getFontByName(fontName);
+      // Using the char instead of char.charCodeAt(0)
       // to avoid collisions between equal chars
-
       var index = _char2;
-
       if (!fontData.cache[index]) {
         var tHelper = fontData.helper;
-
         if (_char2 === ' ') {
           var doubleSize = tHelper.measureText('|' + _char2 + '|');
           var singleSize = tHelper.measureText('||');
@@ -7840,111 +6657,90 @@
           fontData.cache[index] = tHelper.measureText(_char2) / 100;
         }
       }
-
       return fontData.cache[index] * size;
     }
-
     function getFontByName(name) {
       var i = 0;
       var len = this.fonts.length;
-
       while (i < len) {
         if (this.fonts[i].fName === name) {
           return this.fonts[i];
         }
-
         i += 1;
       }
-
       return this.fonts[0];
     }
-
     function getCodePoint(string) {
       var codePoint = 0;
       var first = string.charCodeAt(0);
-
       if (first >= 0xD800 && first <= 0xDBFF) {
         var second = string.charCodeAt(1);
-
         if (second >= 0xDC00 && second <= 0xDFFF) {
           codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
         }
       }
-
       return codePoint;
-    } // Skin tone modifiers
+    }
 
-
+    // Skin tone modifiers
     function isModifier(firstCharCode, secondCharCode) {
       var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
       return surrogateModifiers.indexOf(sum) !== -1;
     }
-
     function isZeroWidthJoiner(charCode) {
       return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
-    } // This codepoint may change the appearance of the preceding character.
+    }
+
+    // This codepoint may change the appearance of the preceding character.
     // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
     // as a colorful image as compared to a monochrome text variant.
-
-
     function isVariationSelector(charCode) {
       return charCode === VARIATION_SELECTOR_16_CODE_POINT;
-    } // The regional indicator symbols are a set of 26 alphabetic Unicode
+    }
+
+    // The regional indicator symbols are a set of 26 alphabetic Unicode
     /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
     // two-letter country codes in a way that allows optional special treatment.
-
-
     function isRegionalCode(string) {
       var codePoint = getCodePoint(string);
-
       if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
         return true;
       }
-
       return false;
-    } // Some Emoji implementations represent combinations of
+    }
+
+    // Some Emoji implementations represent combinations of
     // two “regional indicator” letters as a single flag symbol.
-
-
     function isFlagEmoji(string) {
       return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
     }
-
     function isCombinedCharacter(_char3) {
       return combinedCharacters.indexOf(_char3) !== -1;
-    } // Regional flags start with a BLACK_FLAG_CODE_POINT
+    }
+
+    // Regional flags start with a BLACK_FLAG_CODE_POINT
     // folowed by 5 chars in the TAG range
     // and end with a CANCEL_TAG_CODE_POINT
-
-
     function isRegionalFlag(text, index) {
       var codePoint = getCodePoint(text.substr(index, 2));
-
       if (codePoint !== BLACK_FLAG_CODE_POINT) {
         return false;
       }
-
       var count = 0;
       index += 2;
-
       while (count < 5) {
         codePoint = getCodePoint(text.substr(index, 2));
-
         if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
           return false;
         }
-
         count += 1;
         index += 2;
       }
-
       return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
     }
-
     function setIsLoaded() {
       this.isLoaded = true;
     }
-
     var Font = function Font() {
       this.fonts = [];
       this.chars = null;
@@ -7955,7 +6751,6 @@
       this.setIsLoadedBinded = this.setIsLoaded.bind(this);
       this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
     };
-
     Font.isModifier = isModifier;
     Font.isZeroWidthJoiner = isZeroWidthJoiner;
     Font.isFlagEmoji = isFlagEmoji;
@@ -7980,30 +6775,26 @@
   function SlotManager(animationData) {
     this.animationData = animationData;
   }
-
   SlotManager.prototype.getProp = function (data) {
     if (this.animationData.slots && this.animationData.slots[data.sid]) {
       return Object.assign(data, this.animationData.slots[data.sid].p);
     }
-
     return data;
   };
-
   function slotFactory(animationData) {
     return new SlotManager(animationData);
   }
 
   function RenderableElement() {}
-
   RenderableElement.prototype = {
     initRenderable: function initRenderable() {
       // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
-      this.isInRange = false; // layer's display state
-
-      this.hidden = false; // If layer's transparency equals 0, it can be hidden
-
-      this.isTransparent = false; // list of animated components
-
+      this.isInRange = false;
+      // layer's display state
+      this.hidden = false;
+      // If layer's transparency equals 0, it can be hidden
+      this.isTransparent = false;
+      // list of animated components
       this.renderableComponents = [];
     },
     addRenderableComponent: function addRenderableComponent(component) {
@@ -8030,7 +6821,6 @@
         this.show();
       }
     },
-
     /**
        * @function
        * Initializes frame related properties.
@@ -8056,13 +6846,11 @@
     renderRenderable: function renderRenderable() {
       var i;
       var len = this.renderableComponents.length;
-
       for (i = 0; i < len; i += 1) {
         this.renderableComponents[i].renderFrame(this._isFirstFrame);
       }
       /* this.maskManager.renderFrame(this.finalTransform.mat);
           this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
-
     },
     sourceRectAtTime: function sourceRectAtTime() {
       return {
@@ -8079,7 +6867,6 @@
           h: this.data.textData.height
         };
       }
-
       return {
         w: this.data.width,
         h: this.data.height
@@ -8114,31 +6901,24 @@
   function SliderEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function AngleEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function ColorEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function PointEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
   }
-
   function LayerIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function MaskIndexEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function CheckboxEffect(data, elem, container) {
     this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
   }
-
   function NoValueEffect() {
     this.p = {};
   }
@@ -8149,20 +6929,16 @@
     var i;
     var len = effects.length;
     var effectItem;
-
     for (i = 0; i < len; i += 1) {
       effectItem = new GroupEffect(effects[i], element);
       this.effectElements.push(effectItem);
     }
   }
-
   function GroupEffect(data, element) {
     this.init(data, element);
   }
-
   extendPrototype([DynamicPropertyContainer], GroupEffect);
   GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
-
   GroupEffect.prototype.init = function (data, element) {
     this.data = data;
     this.effectElements = [];
@@ -8171,50 +6947,39 @@
     var len = this.data.ef.length;
     var eff;
     var effects = this.data.ef;
-
     for (i = 0; i < len; i += 1) {
       eff = null;
-
       switch (effects[i].ty) {
         case 0:
           eff = new SliderEffect(effects[i], element, this);
           break;
-
         case 1:
           eff = new AngleEffect(effects[i], element, this);
           break;
-
         case 2:
           eff = new ColorEffect(effects[i], element, this);
           break;
-
         case 3:
           eff = new PointEffect(effects[i], element, this);
           break;
-
         case 4:
         case 7:
           eff = new CheckboxEffect(effects[i], element, this);
           break;
-
         case 10:
           eff = new LayerIndexEffect(effects[i], element, this);
           break;
-
         case 11:
           eff = new MaskIndexEffect(effects[i], element, this);
           break;
-
         case 5:
           eff = new EffectsManager(effects[i], element, this);
           break;
         // case 6:
-
         default:
           eff = new NoValueEffect(effects[i], element, this);
           break;
       }
-
       if (eff) {
         this.effectElements.push(eff);
       }
@@ -8222,47 +6987,37 @@
   };
 
   function BaseElement() {}
-
   BaseElement.prototype = {
     checkMasks: function checkMasks() {
       if (!this.data.hasMask) {
         return false;
       }
-
       var i = 0;
       var len = this.data.masksProperties.length;
-
       while (i < len) {
         if (this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false) {
           return true;
         }
-
         i += 1;
       }
-
       return false;
     },
     initExpressions: function initExpressions() {
       var expressionsInterfaces = getExpressionInterfaces();
-
       if (!expressionsInterfaces) {
         return;
       }
-
       var LayerExpressionInterface = expressionsInterfaces('layer');
       var EffectsExpressionInterface = expressionsInterfaces('effects');
       var ShapeExpressionInterface = expressionsInterfaces('shape');
       var TextExpressionInterface = expressionsInterfaces('text');
       var CompExpressionInterface = expressionsInterfaces('comp');
       this.layerInterface = LayerExpressionInterface(this);
-
       if (this.data.hasMask && this.maskManager) {
         this.layerInterface.registerMaskInterface(this.maskManager);
       }
-
       var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
       this.layerInterface.registerEffectsInterface(effectsInterface);
-
       if (this.data.ty === 0 || this.data.xt) {
         this.compInterface = CompExpressionInterface(this);
       } else if (this.data.ty === 4) {
@@ -8282,13 +7037,13 @@
       this.globalData = globalData;
       this.comp = comp;
       this.data = data;
-      this.layerId = createElementID(); // Stretch factor for old animations missing this property.
+      this.layerId = createElementID();
 
+      // Stretch factor for old animations missing this property.
       if (!this.data.sr) {
         this.data.sr = 1;
-      } // effects manager
-
-
+      }
+      // effects manager
       this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
     },
     getType: function getType() {
@@ -8303,8 +7058,8 @@
    * Checks layer in point and out point
    *
    */
-  function FrameElement() {}
 
+  function FrameElement() {}
   FrameElement.prototype = {
     /**
        * @function
@@ -8313,13 +7068,12 @@
        */
     initFrame: function initFrame() {
       // set to true when inpoint is rendered
-      this._isFirstFrame = false; // list of animated properties
-
-      this.dynamicProperties = []; // If layer has been modified in current tick this will be true
-
+      this._isFirstFrame = false;
+      // list of animated properties
+      this.dynamicProperties = [];
+      // If layer has been modified in current tick this will be true
       this._mdf = false;
     },
-
     /**
        * @function
        * Calculates all dynamic values
@@ -8333,11 +7087,9 @@
     prepareProperties: function prepareProperties(num, isVisible) {
       var i;
       var len = this.dynamicProperties.length;
-
       for (i = 0; i < len; i += 1) {
         if (isVisible || this._isParent && this.dynamicProperties[i].propType === 'transform') {
           this.dynamicProperties[i].getValue();
-
           if (this.dynamicProperties[i]._mdf) {
             this.globalData._mdf = true;
             this._mdf = true;
@@ -8359,30 +7111,21 @@
     this.footageData = globalData.imageLoader.getAsset(this.assetData);
     this.initBaseData(data, globalData, comp);
   }
-
   FootageElement.prototype.prepareFrame = function () {};
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
-
   FootageElement.prototype.getBaseElement = function () {
     return null;
   };
-
   FootageElement.prototype.renderFrame = function () {};
-
   FootageElement.prototype.destroy = function () {};
-
   FootageElement.prototype.initExpressions = function () {
     var expressionsInterfaces = getExpressionInterfaces();
-
     if (!expressionsInterfaces) {
       return;
     }
-
     var FootageInterface = expressionsInterfaces('footage');
     this.layerInterface = FootageInterface(this);
   };
-
   FootageElement.prototype.getFootageData = function () {
     return this.footageData;
   };
@@ -8408,29 +7151,23 @@
       k: [100]
     }, 1, 0.01, this);
   }
-
   AudioElement.prototype.prepareFrame = function (num) {
     this.prepareRenderableFrame(num, true);
     this.prepareProperties(num, true);
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
       this._currentTime = timeRemapped;
     } else {
       this._currentTime = num / this.data.sr;
     }
-
     this._volume = this.lv.v[0];
     var totalVolume = this._volume * this._volumeMultiplier;
-
     if (this._previousVolume !== totalVolume) {
       this._previousVolume = totalVolume;
       this.audio.volume(totalVolume);
     }
   };
-
   extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
-
   AudioElement.prototype.renderFrame = function () {
     if (this.isInRange && this._canPlay) {
       if (!this._isPlaying) {
@@ -8442,162 +7179,124 @@
       }
     }
   };
-
-  AudioElement.prototype.show = function () {// this.audio.play()
+  AudioElement.prototype.show = function () {
+    // this.audio.play()
   };
-
   AudioElement.prototype.hide = function () {
     this.audio.pause();
     this._isPlaying = false;
   };
-
   AudioElement.prototype.pause = function () {
     this.audio.pause();
     this._isPlaying = false;
     this._canPlay = false;
   };
-
   AudioElement.prototype.resume = function () {
     this._canPlay = true;
   };
-
   AudioElement.prototype.setRate = function (rateValue) {
     this.audio.rate(rateValue);
   };
-
   AudioElement.prototype.volume = function (volumeValue) {
     this._volumeMultiplier = volumeValue;
     this._previousVolume = volumeValue * this._volume;
     this.audio.volume(this._previousVolume);
   };
-
   AudioElement.prototype.getBaseElement = function () {
     return null;
   };
-
   AudioElement.prototype.destroy = function () {};
-
   AudioElement.prototype.sourceRectAtTime = function () {};
-
   AudioElement.prototype.initExpressions = function () {};
 
   function BaseRenderer() {}
-
   BaseRenderer.prototype.checkLayers = function (num) {
     var i;
     var len = this.layers.length;
     var data;
     this.completeLayers = true;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (!this.elements[i]) {
         data = this.layers[i];
-
         if (data.ip - data.st <= num - this.layers[i].st && data.op - data.st > num - this.layers[i].st) {
           this.buildItem(i);
         }
       }
-
       this.completeLayers = this.elements[i] ? this.completeLayers : false;
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.createItem = function (layer) {
     switch (layer.ty) {
       case 2:
         return this.createImage(layer);
-
       case 0:
         return this.createComp(layer);
-
       case 1:
         return this.createSolid(layer);
-
       case 3:
         return this.createNull(layer);
-
       case 4:
         return this.createShape(layer);
-
       case 5:
         return this.createText(layer);
-
       case 6:
         return this.createAudio(layer);
-
       case 13:
         return this.createCamera(layer);
-
       case 15:
         return this.createFootage(layer);
-
       default:
         return this.createNull(layer);
     }
   };
-
   BaseRenderer.prototype.createCamera = function () {
     throw new Error('You\'re using a 3d camera. Try the html renderer.');
   };
-
   BaseRenderer.prototype.createAudio = function (data) {
     return new AudioElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.createFootage = function (data) {
     return new FootageElement(data, this.globalData, this);
   };
-
   BaseRenderer.prototype.buildAllItems = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       this.buildItem(i);
     }
-
     this.checkPendingElements();
   };
-
   BaseRenderer.prototype.includeLayers = function (newLayers) {
     this.completeLayers = false;
     var i;
     var len = newLayers.length;
     var j;
     var jLen = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       j = 0;
-
       while (j < jLen) {
         if (this.layers[j].id === newLayers[i].id) {
           this.layers[j] = newLayers[i];
           break;
         }
-
         j += 1;
       }
     }
   };
-
   BaseRenderer.prototype.setProjectInterface = function (pInterface) {
     this.globalData.projectInterface = pInterface;
   };
-
   BaseRenderer.prototype.initItems = function () {
     if (!this.globalData.progressiveLoad) {
       this.buildAllItems();
     }
   };
-
   BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
     var elements = this.elements;
     var layers = this.layers;
     var i = 0;
     var len = layers.length;
-
     while (i < len) {
       if (layers[i].ind == parentName) {
         // eslint-disable-line eqeqeq
@@ -8607,7 +7306,6 @@
         } else {
           hierarchy.push(elements[i]);
           elements[i].setAsParent();
-
           if (layers[i].parent !== undefined) {
             this.buildElementParenting(element, layers[i].parent, hierarchy);
           } else {
@@ -8615,19 +7313,15 @@
           }
         }
       }
-
       i += 1;
     }
   };
-
   BaseRenderer.prototype.addPendingElement = function (element) {
     this.pendingElements.push(element);
   };
-
   BaseRenderer.prototype.searchExtraCompositions = function (assets) {
     var i;
     var len = assets.length;
-
     for (i = 0; i < len; i += 1) {
       if (assets[i].xt) {
         var comp = this.createComp(assets[i]);
@@ -8636,30 +7330,24 @@
       }
     }
   };
-
   BaseRenderer.prototype.getElementById = function (ind) {
     var i;
     var len = this.elements.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i].data.ind === ind) {
         return this.elements[i];
       }
     }
-
     return null;
   };
-
   BaseRenderer.prototype.getElementByPath = function (path) {
     var pathValue = path.shift();
     var element;
-
     if (typeof pathValue === 'number') {
       element = this.elements[pathValue];
     } else {
       var i;
       var len = this.elements.length;
-
       for (i = 0; i < len; i += 1) {
         if (this.elements[i].data.nm === pathValue) {
           element = this.elements[i];
@@ -8667,14 +7355,11 @@
         }
       }
     }
-
     if (path.length === 0) {
       return element;
     }
-
     return element.getElementByPath(path);
   };
-
   BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
     this.globalData.fontManager = new FontManager();
     this.globalData.slotManager = slotFactory(animData);
@@ -8698,7 +7383,6 @@
   };
 
   function TransformElement() {}
-
   TransformElement.prototype = {
     initTransform: function initTransform() {
       var mat = new Matrix();
@@ -8713,50 +7397,44 @@
         localMat: mat,
         localOpacity: 1
       };
-
       if (this.data.ao) {
         this.finalTransform.mProp.autoOriented = true;
-      } // TODO: check TYPE 11: Guided elements
+      }
 
-
-      if (this.data.ty !== 11) {// this.createElements();
+      // TODO: check TYPE 11: Guided elements
+      if (this.data.ty !== 11) {
+        // this.createElements();
       }
     },
     renderTransform: function renderTransform() {
       this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
       this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
-
       if (this.hierarchy) {
         var mat;
         var finalMat = this.finalTransform.mat;
         var i = 0;
-        var len = this.hierarchy.length; // Checking if any of the transformation matrices in the hierarchy chain has changed.
-
+        var len = this.hierarchy.length;
+        // Checking if any of the transformation matrices in the hierarchy chain has changed.
         if (!this.finalTransform._matMdf) {
           while (i < len) {
             if (this.hierarchy[i].finalTransform.mProp._mdf) {
               this.finalTransform._matMdf = true;
               break;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._matMdf) {
           mat = this.finalTransform.mProp.v.props;
           finalMat.cloneFromProps(mat);
-
           for (i = 0; i < len; i += 1) {
             finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
           }
         }
       }
-
-      if (this.finalTransform._matMdf) {
+      if (!this.localTransforms || this.finalTransform._matMdf) {
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
       }
-
       if (this.finalTransform._opMdf) {
         this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
       }
@@ -8766,41 +7444,32 @@
         var i = 0;
         var len = this.localTransforms.length;
         this.finalTransform._localMatMdf = this.finalTransform._matMdf;
-
         if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
           while (i < len) {
             if (this.localTransforms[i]._mdf) {
               this.finalTransform._localMatMdf = true;
             }
-
             if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
               this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
               this.finalTransform._opMdf = true;
             }
-
             i += 1;
           }
         }
-
         if (this.finalTransform._localMatMdf) {
           var localMat = this.finalTransform.localMat;
           this.localTransforms[0].matrix.clone(localMat);
-
           for (i = 1; i < len; i += 1) {
             var lmat = this.localTransforms[i].matrix;
             localMat.multiply(lmat);
           }
-
           localMat.multiply(this.finalTransform.mat);
         }
-
         if (this.finalTransform._opMdf) {
           var localOp = this.finalTransform.localOpacity;
-
           for (i = 0; i < len; i += 1) {
             localOp *= this.localTransforms[i].opacity * 0.01;
           }
-
           this.finalTransform.localOpacity = localOp;
         }
       }
@@ -8808,13 +7477,11 @@
     searchEffectTransforms: function searchEffectTransforms() {
       if (this.renderableEffectsManager) {
         var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
-
         if (transformEffects.length) {
           this.localTransforms = [];
           this.finalTransform.localMat = new Matrix();
           var i = 0;
           var len = transformEffects.length;
-
           for (i = 0; i < len; i += 1) {
             this.localTransforms.push(transformEffects[i]);
           }
@@ -8826,29 +7493,24 @@
       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;
       var len = transforms.length;
       var 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]);
-
+        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;
     },
     mHelper: new Matrix()
@@ -8879,13 +7541,11 @@
     var x;
     var maskType = 'clipPath';
     var maskRef = 'clip-path';
-
     for (i = 0; i < len; i += 1) {
       if (properties[i].mode !== 'a' && properties[i].mode !== 'n' || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
         maskType = 'mask';
         maskRef = 'mask';
       }
-
       if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
         rect = createNS('rect');
         rect.setAttribute('fill', '#ffffff');
@@ -8895,9 +7555,7 @@
       } else {
         rect = null;
       }
-
       path = createNS('path');
-
       if (properties[i].mode === 'n') {
         // TODO move this to a factory or to a constructor
         this.viewData[i] = {
@@ -8912,7 +7570,6 @@
         path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
         path.setAttribute('clip-rule', 'nonzero');
         var filterID;
-
         if (properties[i].x.k !== 0) {
           maskType = 'mask';
           maskRef = 'mask';
@@ -8930,9 +7587,9 @@
         } else {
           feMorph = null;
           x = null;
-        } // TODO move this to a factory or to a constructor
+        }
 
-
+        // TODO move this to a factory or to a constructor
         this.storedData[i] = {
           elem: path,
           x: x,
@@ -8942,15 +7599,12 @@
           filterId: filterID,
           lastRadius: 0
         };
-
         if (properties[i].mode === 'i') {
           jLen = currentMasks.length;
           var g = createNS('g');
-
           for (j = 0; j < jLen; j += 1) {
             g.appendChild(currentMasks[j]);
           }
-
           var mask = createNS('mask');
           mask.setAttribute('mask-type', 'alpha');
           mask.setAttribute('id', layerId + '_' + count);
@@ -8962,12 +7616,10 @@
         } else {
           currentMasks.push(path);
         }
-
         if (properties[i].inv && !this.solidPath) {
           this.solidPath = this.createLayerSolidPath();
-        } // TODO move this to a factory or to a constructor
-
-
+        }
+        // TODO move this to a factory or to a constructor
         this.viewData[i] = {
           elem: path,
           lastPath: '',
@@ -8975,81 +7627,65 @@
           prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
           invRect: rect
         };
-
         if (!this.viewData[i].prop.k) {
           this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
         }
       }
     }
-
     this.maskElement = createNS(maskType);
     len = currentMasks.length;
-
     for (i = 0; i < len; i += 1) {
       this.maskElement.appendChild(currentMasks[i]);
     }
-
     if (count > 0) {
       this.maskElement.setAttribute('id', layerId);
       this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
       defs.appendChild(this.maskElement);
     }
-
     if (this.viewData.length) {
       this.element.addRenderableComponent(this);
     }
   }
-
   MaskElement.prototype.getMaskProperty = function (pos) {
     return this.viewData[pos].prop;
   };
-
   MaskElement.prototype.renderFrame = function (isFirstFrame) {
     var finalMat = this.element.finalTransform.mat;
     var i;
     var len = this.masksProperties.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.viewData[i].prop._mdf || isFirstFrame) {
         this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
       }
-
       if (this.viewData[i].op._mdf || isFirstFrame) {
         this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
       }
-
       if (this.masksProperties[i].mode !== 'n') {
         if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
           this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
         }
-
         if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
           var feMorph = this.storedData[i].expan;
-
           if (this.storedData[i].x.v < 0) {
             if (this.storedData[i].lastOperator !== 'erode') {
               this.storedData[i].lastOperator = 'erode';
               this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
             }
-
             feMorph.setAttribute('radius', -this.storedData[i].x.v);
           } else {
             if (this.storedData[i].lastOperator !== 'dilate') {
               this.storedData[i].lastOperator = 'dilate';
               this.storedData[i].elem.setAttribute('filter', null);
             }
-
             this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
           }
         }
       }
     }
   };
-
   MaskElement.prototype.getMaskelement = function () {
     return this.maskElement;
   };
-
   MaskElement.prototype.createLayerSolidPath = function () {
     var path = 'M0,0 ';
     path += ' h' + this.globalData.compSize.w;
@@ -9058,39 +7694,32 @@
     path += ' v-' + this.globalData.compSize.h + ' ';
     return path;
   };
-
   MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
     var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
     var i;
     var len;
     len = pathNodes._length;
-
     for (i = 1; i < len; i += 1) {
       // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
-    } // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
-
-
+    }
+    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
     if (pathNodes.c && len > 1) {
       pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
-    } // pathNodes.__renderedString = pathString;
-
+    }
+    // pathNodes.__renderedString = pathString;
 
     if (viewData.lastPath !== pathString) {
       var pathShapeValue = '';
-
       if (viewData.elem) {
         if (pathNodes.c) {
           pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
         }
-
         viewData.elem.setAttribute('d', pathShapeValue);
       }
-
       viewData.lastPath = pathString;
     }
   };
-
   MaskElement.prototype.destroy = function () {
     this.element = null;
     this.globalData = null;
@@ -9103,11 +7732,9 @@
     var ob = {};
     ob.createFilter = createFilter;
     ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
-
     function createFilter(filId, skipCoordinates) {
       var fil = createNS('filter');
       fil.setAttribute('id', filId);
-
       if (skipCoordinates !== true) {
         fil.setAttribute('filterUnits', 'objectBoundingBox');
         fil.setAttribute('x', '0%');
@@ -9115,10 +7742,8 @@
         fil.setAttribute('width', '100%');
         fil.setAttribute('height', '100%');
       }
-
       return fil;
     }
-
     function createAlphaToLuminanceFilter() {
       var feColorMatrix = createNS('feColorMatrix');
       feColorMatrix.setAttribute('type', 'matrix');
@@ -9126,7 +7751,6 @@
       feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
       return feColorMatrix;
     }
-
     return ob;
   }();
 
@@ -9136,21 +7760,17 @@
       svgLumaHidden: true,
       offscreenCanvas: typeof OffscreenCanvas !== 'undefined'
     };
-
     if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
       ob.maskType = false;
     }
-
     if (/firefox/i.test(navigator.userAgent)) {
       ob.svgLumaHidden = false;
     }
-
     return ob;
   }();
 
   var registeredEffects$1 = {};
   var idPrefix = 'filter_result_';
-
   function SVGEffects(elem) {
     var i;
     var source = 'SourceGraphic';
@@ -9160,59 +7780,47 @@
     var count = 0;
     this.filters = [];
     var filterManager;
-
     for (i = 0; i < len; i += 1) {
       filterManager = null;
       var type = elem.data.ef[i].ty;
-
       if (registeredEffects$1[type]) {
         var Effect = registeredEffects$1[type].effect;
         filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
         source = idPrefix + count;
-
         if (registeredEffects$1[type].countsAsEffect) {
           count += 1;
         }
       }
-
       if (filterManager) {
         this.filters.push(filterManager);
       }
     }
-
     if (count) {
       elem.globalData.defs.appendChild(fil);
       elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
     }
-
     if (this.filters.length) {
       elem.addRenderableComponent(this);
     }
   }
-
   SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
     var i;
     var len = this.filters.length;
-
     for (i = 0; i < len; i += 1) {
       this.filters[i].renderFrame(_isFirstFrame);
     }
   };
-
   SVGEffects.prototype.getEffects = function (type) {
     var i;
     var len = this.filters.length;
     var effects = [];
-
     for (i = 0; i < len; i += 1) {
       if (this.filters[i].type === type) {
         effects.push(this.filters[i]);
       }
     }
-
     return effects;
   };
-
   function registerEffect$1(id, effect, countsAsEffect) {
     registeredEffects$1[id] = {
       effect: effect,
@@ -9221,7 +7829,6 @@
   }
 
   function SVGBaseElement() {}
-
   SVGBaseElement.prototype = {
     initRendererElement: function initRendererElement() {
       this.layerElement = createNS('g');
@@ -9231,8 +7838,8 @@
       this.transformedElement = this.layerElement;
       this.maskedElement = this.layerElement;
       this._sizeChanged = false;
-      var layerElementParent = null; // If this layer acts as a mask for the following layer
-
+      var layerElementParent = null;
+      // If this layer acts as a mask for the following layer
       if (this.data.td) {
         this.matteMasks = {};
         var gg = createNS('g');
@@ -9247,16 +7854,13 @@
       } else {
         this.baseElement = this.layerElement;
       }
-
       if (this.data.ln) {
         this.layerElement.setAttribute('id', this.data.ln);
       }
-
       if (this.data.cl) {
         this.layerElement.setAttribute('class', this.data.cl);
-      } // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
-
-
+      }
+      // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
       if (this.data.ty === 0 && !this.data.hd) {
         var cp = createNS('clipPath');
         var pt = createNS('path');
@@ -9265,13 +7869,11 @@
         cp.setAttribute('id', clipId);
         cp.appendChild(pt);
         this.globalData.defs.appendChild(cp);
-
         if (this.checkMasks()) {
           var cpGroup = createNS('g');
           cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
           cpGroup.appendChild(this.layerElement);
           this.transformedElement = cpGroup;
-
           if (layerElementParent) {
             layerElementParent.appendChild(this.transformedElement);
           } else {
@@ -9281,7 +7883,6 @@
           this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
         }
       }
-
       if (this.data.bm !== 0) {
         this.setBlendMode();
       }
@@ -9290,7 +7891,6 @@
       if (this.finalTransform._localMatMdf) {
         this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
       }
-
       if (this.finalTransform._opMdf) {
         this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
       }
@@ -9304,7 +7904,6 @@
       if (this.data.hd) {
         return null;
       }
-
       return this.baseElement;
     },
     createRenderableComponents: function createRenderableComponents() {
@@ -9319,14 +7918,12 @@
       if (!this.matteMasks) {
         this.matteMasks = {};
       }
-
       if (!this.matteMasks[matteType]) {
         var id = this.layerId + '_' + matteType;
         var filId;
         var fil;
         var useElement;
         var gg;
-
         if (matteType === 1 || matteType === 3) {
           var masker = createNS('mask');
           masker.setAttribute('id', id);
@@ -9335,7 +7932,6 @@
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           masker.appendChild(useElement);
           this.globalData.defs.appendChild(masker);
-
           if (!featureSupport.maskType && matteType === 1) {
             masker.setAttribute('mask-type', 'luminance');
             filId = createElementID();
@@ -9354,16 +7950,16 @@
           var maskGrouper = createNS('g');
           maskGroup.appendChild(maskGrouper);
           filId = createElementID();
-          fil = filtersFactory.createFilter(filId); /// /
-
+          fil = filtersFactory.createFilter(filId);
+          /// /
           var feCTr = createNS('feComponentTransfer');
           feCTr.setAttribute('in', 'SourceGraphic');
           fil.appendChild(feCTr);
           var feFunc = createNS('feFuncA');
           feFunc.setAttribute('type', 'table');
           feFunc.setAttribute('tableValues', '1.0 0.0');
-          feCTr.appendChild(feFunc); /// /
-
+          feCTr.appendChild(feFunc);
+          /// /
           this.globalData.defs.appendChild(fil);
           var alphaRect = createNS('rect');
           alphaRect.setAttribute('width', this.comp.data.w);
@@ -9377,7 +7973,6 @@
           useElement = createNS('use');
           useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
           maskGrouper.appendChild(useElement);
-
           if (!featureSupport.maskType) {
             maskGroup.setAttribute('mask-type', 'luminance');
             fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
@@ -9386,20 +7981,16 @@
             gg.appendChild(this.layerElement);
             maskGrouper.appendChild(gg);
           }
-
           this.globalData.defs.appendChild(maskGroup);
         }
-
         this.matteMasks[matteType] = id;
       }
-
       return this.matteMasks[matteType];
     },
     setMatte: function setMatte(id) {
       if (!this.matteElement) {
         return;
       }
-
       this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
     }
   };
@@ -9409,8 +8000,8 @@
    * Handles AE's layer parenting property.
    *
    */
-  function HierarchyElement() {}
 
+  function HierarchyElement() {}
   HierarchyElement.prototype = {
     /**
        * @function
@@ -9419,12 +8010,11 @@
        */
     initHierarchy: function initHierarchy() {
       // element's parent list
-      this.hierarchy = []; // if element is parent of another layer _isParent will be true
-
+      this.hierarchy = [];
+      // if element is parent of another layer _isParent will be true
       this._isParent = false;
       this.checkParenting();
     },
-
     /**
        * @function
        * Sets layer's hierarchy.
@@ -9435,7 +8025,6 @@
     setHierarchy: function setHierarchy(hierarchy) {
       this.hierarchy = hierarchy;
     },
-
     /**
        * @function
        * Sets layer as parent.
@@ -9444,7 +8033,6 @@
     setAsParent: function setAsParent() {
       this._isParent = true;
     },
-
     /**
        * @function
        * Searches layer's parenting chain
@@ -9458,7 +8046,6 @@
   };
 
   function RenderableDOMElement() {}
-
   (function () {
     var _prototype = {
       initElement: function initElement(data, globalData, comp) {
@@ -9488,7 +8075,6 @@
             var elem = this.baseElement || this.layerElement;
             elem.style.display = 'block';
           }
-
           this.hidden = false;
           this._isFirstFrame = true;
         }
@@ -9499,13 +8085,11 @@
         if (this.data.hd || this.hidden) {
           return;
         }
-
         this.renderTransform();
         this.renderRenderable();
         this.renderLocalTransform();
         this.renderElement();
         this.renderInnerContent();
-
         if (this._isFirstFrame) {
           this._isFirstFrame = false;
         }
@@ -9527,11 +8111,9 @@
 
   function IImageElement(data, globalData, comp) {
     this.assetData = globalData.getAssetData(data.refId);
-
     if (this.assetData && this.assetData.sid) {
       this.assetData = globalData.slotManager.getProp(this.assetData);
     }
-
     this.initElement(data, globalData, comp);
     this.sourceRect = {
       top: 0,
@@ -9540,9 +8122,7 @@
       height: this.assetData.h
     };
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
-
   IImageElement.prototype.createContent = function () {
     var assetPath = this.globalData.getAssetsPath(this.assetData);
     this.innerElem = createNS('image');
@@ -9552,7 +8132,6 @@
     this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
     this.layerElement.appendChild(this.innerElem);
   };
-
   IImageElement.prototype.sourceRectAtTime = function () {
     return this.sourceRect;
   };
@@ -9563,12 +8142,10 @@
   }
 
   function IShapeElement() {}
-
   IShapeElement.prototype = {
     addShapeToModifiers: function addShapeToModifiers(data) {
       var i;
       var len = this.shapeModifiers.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapeModifiers[i].addShape(data);
       }
@@ -9576,34 +8153,28 @@
     isShapeInAnimatedModifiers: function isShapeInAnimatedModifiers(data) {
       var i = 0;
       var len = this.shapeModifiers.length;
-
       while (i < len) {
         if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
           return true;
         }
       }
-
       return false;
     },
     renderModifiers: function renderModifiers() {
       if (!this.shapeModifiers.length) {
         return;
       }
-
       var i;
       var len = this.shapes.length;
-
       for (i = 0; i < len; i += 1) {
         this.shapes[i].sh.reset();
       }
-
       len = this.shapeModifiers.length;
       var shouldBreakProcess;
-
       for (i = len - 1; i >= 0; i -= 1) {
-        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame); // workaround to fix cases where a repeater resets the shape so the following processes get called twice
+        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
+        // workaround to fix cases where a repeater resets the shape so the following processes get called twice
         // TODO: find a better solution for this
-
         if (shouldBreakProcess) {
           break;
         }
@@ -9613,30 +8184,24 @@
       var elements = this.processedElements;
       var i = 0;
       var len = elements.length;
-
       while (i < len) {
         if (elements[i].elem === elem) {
           return elements[i].pos;
         }
-
         i += 1;
       }
-
       return 0;
     },
     addProcessedElement: function addProcessedElement(elem, pos) {
       var elements = this.processedElements;
       var i = elements.length;
-
       while (i) {
         i -= 1;
-
         if (elements[i].elem === elem) {
           elements[i].pos = pos;
           return;
         }
       }
-
       elements.push(new ProcessedElement(elem, pos));
     },
     prepareFrame: function prepareFrame(num) {
@@ -9662,25 +8227,22 @@
     this.transformers = transformers;
     this.lStr = '';
     this.sh = shape;
-    this.lvl = level; // TODO find if there are some cases where _isAnimated can be false.
+    this.lvl = level;
+    // TODO find if there are some cases where _isAnimated can be false.
     // For now, since shapes add up with other shapes. They have to be calculated every time.
     // One way of finding out is checking if all styles associated to this shape depend only of this shape
-
-    this._isAnimated = !!shape.k; // TODO: commenting this for now since all shapes are animated
-
+    this._isAnimated = !!shape.k;
+    // TODO: commenting this for now since all shapes are animated
     var i = 0;
     var len = transformers.length;
-
     while (i < len) {
       if (transformers[i].mProps.dynamicProperties.length) {
         this._isAnimated = true;
         break;
       }
-
       i += 1;
     }
   }
-
   SVGShapeData.prototype.setAsAnimated = function () {
     this._isAnimated = true;
   };
@@ -9695,7 +8257,6 @@
     this.pElem = createNS('path');
     this.msElem = null;
   }
-
   SVGStyleData.prototype.reset = function () {
     this.d = '';
     this._mdf = false;
@@ -9714,7 +8275,6 @@
     var i;
     var len = data.length || 0;
     var prop;
-
     for (i = 0; i < len; i += 1) {
       prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
       this.k = prop.k || this.k;
@@ -9723,31 +8283,24 @@
         p: prop
       };
     }
-
     if (!this.k) {
       this.getValue(true);
     }
-
     this._isAnimated = this.k;
   }
-
   DashProperty.prototype.getValue = function (forceRender) {
     if (this.elem.globalData.frameId === this.frameId && !forceRender) {
       return;
     }
-
     this.frameId = this.elem.globalData.frameId;
     this.iterateDynamicProperties();
     this._mdf = this._mdf || forceRender;
-
     if (this._mdf) {
       var i = 0;
       var len = this.dataProps.length;
-
       if (this.renderer === 'svg') {
         this.dashStr = '';
       }
-
       for (i = 0; i < len; i += 1) {
         if (this.dataProps[i].n !== 'o') {
           if (this.renderer === 'svg') {
@@ -9761,7 +8314,6 @@
       }
     }
   };
-
   extendPrototype([DynamicPropertyContainer], DashProperty);
 
   function SVGStrokeStyleData(elem, data, styleOb) {
@@ -9774,7 +8326,6 @@
     this.style = styleOb;
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
 
   function SVGFillStyleData(elem, data, styleOb) {
@@ -9784,7 +8335,6 @@
     this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
 
   function SVGNoStyleData(elem, data, styleOb) {
@@ -9792,7 +8342,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.style = styleOb;
   }
-
   extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
 
   function GradientProperty(elem, data, container) {
@@ -9809,88 +8358,69 @@
     this.k = this.prop.k;
     this.getValue(true);
   }
-
   GradientProperty.prototype.comparePoints = function (values, points) {
     var i = 0;
     var len = this.o.length / 2;
     var diff;
-
     while (i < len) {
       diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
-
       if (diff > 0.01) {
         return false;
       }
-
       i += 1;
     }
-
     return true;
   };
-
   GradientProperty.prototype.checkCollapsable = function () {
     if (this.o.length / 2 !== this.c.length / 4) {
       return false;
     }
-
     if (this.data.k.k[0].s) {
       var i = 0;
       var len = this.data.k.k.length;
-
       while (i < len) {
         if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
           return false;
         }
-
         i += 1;
       }
     } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
       return false;
     }
-
     return true;
   };
-
   GradientProperty.prototype.getValue = function (forceRender) {
     this.prop.getValue();
     this._mdf = false;
     this._cmdf = false;
     this._omdf = false;
-
     if (this.prop._mdf || forceRender) {
       var i;
       var len = this.data.p * 4;
       var mult;
       var val;
-
       for (i = 0; i < len; i += 1) {
         mult = i % 4 === 0 ? 100 : 255;
         val = Math.round(this.prop.v[i] * mult);
-
         if (this.c[i] !== val) {
           this.c[i] = val;
           this._cmdf = !forceRender;
         }
       }
-
       if (this.o.length) {
         len = this.prop.v.length;
-
         for (i = this.data.p * 4; i < len; i += 1) {
           mult = i % 2 === 0 ? 100 : 1;
           val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
-
           if (this.o[i - this.data.p * 4] !== val) {
             this.o[i - this.data.p * 4] = val;
             this._omdf = !forceRender;
           }
         }
       }
-
       this._mdf = !forceRender;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], GradientProperty);
 
   function SVGGradientFillStyleData(elem, data, styleOb) {
@@ -9898,7 +8428,6 @@
     this.getValue = this.iterateDynamicProperties;
     this.initGradientData(elem, data, styleOb);
   }
-
   SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
     this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
     this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
@@ -9916,7 +8445,6 @@
     this.setGradientOpacity(data, styleOb);
     this._isAnimated = !!this._isAnimated;
   };
-
   SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
     var gradientId = createElementID();
     var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
@@ -9928,18 +8456,15 @@
     var j;
     var jLen;
     jLen = data.g.p * 4;
-
     for (j = 0; j < jLen; j += 4) {
       stop = createNS('stop');
       gfill.appendChild(stop);
       stops.push(stop);
     }
-
     pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
     this.gf = gfill;
     this.cst = stops;
   };
-
   SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
     if (this.g._hasOpacity && !this.g._collapsable) {
       var stop;
@@ -9957,25 +8482,20 @@
       opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
       jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
       var stops = this.stops;
-
       for (j = data.g.p * 4; j < jLen; j += 2) {
         stop = createNS('stop');
         stop.setAttribute('stop-color', 'rgb(255,255,255)');
         opFill.appendChild(stop);
         stops.push(stop);
       }
-
       maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + 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;
@@ -9983,7 +8503,6 @@
       styleOb.msElem = maskElement;
     }
   };
-
   extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
 
   function SVGGradientStrokeStyleData(elem, data, styleOb) {
@@ -9994,7 +8513,6 @@
     this.initGradientData(elem, data, styleOb);
     this._isAnimated = !!this._isAnimated;
   }
-
   extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
 
   function ShapeGroupData() {
@@ -10017,77 +8535,59 @@
     if (length === 0) {
       return '';
     }
-
     var _o = pathNodes.o;
     var _i = pathNodes.i;
     var _v = pathNodes.v;
     var i;
     var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
-
     for (i = 1; i < length; i += 1) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
     }
-
     if (closed && length) {
       shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
       shapeString += 'z';
     }
-
     return shapeString;
   };
 
   var SVGElementsRenderer = function () {
     var _identityMatrix = new Matrix();
-
     var _matrixHelper = new Matrix();
-
     var ob = {
       createRenderFunction: createRenderFunction
     };
-
     function createRenderFunction(data) {
       switch (data.ty) {
         case 'fl':
           return renderFill;
-
         case 'gf':
           return renderGradient;
-
         case 'gs':
           return renderGradientStroke;
-
         case 'st':
           return renderStroke;
-
         case 'sh':
         case 'el':
         case 'rc':
         case 'sr':
           return renderPath;
-
         case 'tr':
           return renderContentTransform;
-
         case 'no':
           return renderNoop;
-
         default:
           return null;
       }
     }
-
     function renderContentTransform(styleData, itemData, isFirstFrame) {
       if (isFirstFrame || itemData.transform.op._mdf) {
         itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
       }
-
       if (isFirstFrame || itemData.transform.mProps._mdf) {
         itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
       }
     }
-
     function renderNoop() {}
-
     function renderPath(styleData, itemData, isFirstFrame) {
       var j;
       var jLen;
@@ -10101,25 +8601,20 @@
       var mat;
       var iterations;
       var k;
-
       for (l = 0; l < lLen; l += 1) {
         redraw = itemData.sh._mdf || isFirstFrame;
-
         if (itemData.styles[l].lvl < lvl) {
           mat = _matrixHelper.reset();
           iterations = lvl - itemData.styles[l].lvl;
           k = itemData.transformers.length - 1;
-
           while (!redraw && iterations > 0) {
             redraw = itemData.transformers[k].mProps._mdf || redraw;
             iterations -= 1;
             k -= 1;
           }
-
           if (redraw) {
             iterations = lvl - itemData.styles[l].lvl;
             k = itemData.transformers.length - 1;
-
             while (iterations > 0) {
               mat.multiply(itemData.transformers[k].mProps.v);
               iterations -= 1;
@@ -10129,115 +8624,90 @@
         } else {
           mat = _identityMatrix;
         }
-
         paths = itemData.sh.paths;
         jLen = paths._length;
-
         if (redraw) {
           pathStringTransformed = '';
-
           for (j = 0; j < jLen; j += 1) {
             pathNodes = paths.shapes[j];
-
             if (pathNodes && pathNodes._length) {
               pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
             }
           }
-
           itemData.caches[l] = pathStringTransformed;
         } else {
           pathStringTransformed = itemData.caches[l];
         }
-
         itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
         itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
       }
     }
-
     function renderFill(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
-
       if (itemData.c._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
       }
     }
-
     function renderGradientStroke(styleData, itemData, isFirstFrame) {
       renderGradient(styleData, itemData, isFirstFrame);
       renderStroke(styleData, itemData, isFirstFrame);
     }
-
     function renderGradient(styleData, itemData, isFirstFrame) {
       var gfill = itemData.gf;
       var hasOpacity = itemData.g._hasOpacity;
       var pt1 = itemData.s.v;
       var pt2 = itemData.e.v;
-
       if (itemData.o._mdf || isFirstFrame) {
         var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
         itemData.style.pElem.setAttribute(attr, itemData.o.v);
       }
-
       if (itemData.s._mdf || isFirstFrame) {
         var attr1 = styleData.t === 1 ? 'x1' : 'cx';
         var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
         gfill.setAttribute(attr1, pt1[0]);
         gfill.setAttribute(attr2, pt1[1]);
-
         if (hasOpacity && !itemData.g._collapsable) {
           itemData.of.setAttribute(attr1, pt1[0]);
           itemData.of.setAttribute(attr2, pt1[1]);
         }
       }
-
       var stops;
       var i;
       var len;
       var stop;
-
       if (itemData.g._cmdf || isFirstFrame) {
         stops = itemData.cst;
         var cValues = itemData.g.c;
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
           stop.setAttribute('offset', cValues[i * 4] + '%');
           stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
         }
       }
-
       if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
         var oValues = itemData.g.o;
-
         if (itemData.g._collapsable) {
           stops = itemData.cst;
         } else {
           stops = itemData.ost;
         }
-
         len = stops.length;
-
         for (i = 0; i < len; i += 1) {
           stop = stops[i];
-
           if (!itemData.g._collapsable) {
             stop.setAttribute('offset', oValues[i * 2] + '%');
           }
-
           stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
         }
       }
-
       if (styleData.t === 1) {
         if (itemData.e._mdf || isFirstFrame) {
           gfill.setAttribute('x2', pt2[0]);
           gfill.setAttribute('y2', pt2[1]);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('x2', pt2[0]);
             itemData.of.setAttribute('y2', pt2[1]);
@@ -10245,112 +8715,93 @@
         }
       } else {
         var rad;
-
         if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
           rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           gfill.setAttribute('r', rad);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('r', rad);
           }
         }
-
-        if (itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
+        if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
           if (!rad) {
             rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
           }
-
           var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
           var percent = itemData.h.v;
-
           if (percent >= 1) {
             percent = 0.99;
           } else if (percent <= -1) {
             percent = -0.99;
           }
-
           var dist = rad * percent;
           var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
           var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
           gfill.setAttribute('fx', x);
           gfill.setAttribute('fy', y);
-
           if (hasOpacity && !itemData.g._collapsable) {
             itemData.of.setAttribute('fx', x);
             itemData.of.setAttribute('fy', y);
           }
-        } // gfill.setAttribute('fy','200');
-
+        }
+        // gfill.setAttribute('fy','200');
       }
     }
-
     function renderStroke(styleData, itemData, isFirstFrame) {
       var styleElem = itemData.style;
       var d = itemData.d;
-
       if (d && (d._mdf || isFirstFrame) && d.dashStr) {
         styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
         styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
       }
-
       if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
         styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
       }
-
       if (itemData.o._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
       }
-
       if (itemData.w._mdf || isFirstFrame) {
         styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
-
         if (styleElem.msElem) {
           styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
         }
       }
     }
-
     return ob;
   }();
 
   function SVGShapeElement(data, globalData, comp) {
     // List of drawable elements
-    this.shapes = []; // Full shape data
-
-    this.shapesData = data.shapes; // List of styles that will be applied to shapes
-
-    this.stylesList = []; // List of modifiers that will be applied to shapes
-
-    this.shapeModifiers = []; // List of items in shape tree
-
-    this.itemsData = []; // List of items in previous shape tree
-
-    this.processedElements = []; // List of animated components
-
+    this.shapes = [];
+    // Full shape data
+    this.shapesData = data.shapes;
+    // List of styles that will be applied to shapes
+    this.stylesList = [];
+    // List of modifiers that will be applied to shapes
+    this.shapeModifiers = [];
+    // List of items in shape tree
+    this.itemsData = [];
+    // List of items in previous shape tree
+    this.processedElements = [];
+    // List of animated components
     this.animatedContents = [];
-    this.initElement(data, globalData, comp); // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.initElement(data, globalData, comp);
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
     // List of elements that have been created
-
-    this.prevViewData = []; // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.prevViewData = [];
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
-
   SVGShapeElement.prototype.initSecondaryElement = function () {};
-
   SVGShapeElement.prototype.identityMatrix = new Matrix();
-
   SVGShapeElement.prototype.buildExpressionInterface = function () {};
-
   SVGShapeElement.prototype.createContent = function () {
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
   };
+
   /*
   This method searches for multiple shapes that affect a single element and one of them is animated
   */
-
-
   SVGShapeElement.prototype.filterUniqueShapes = function () {
     var i;
     var len = this.shapes.length;
@@ -10360,42 +8811,34 @@
     var style;
     var tempShapes = [];
     var areAnimated = false;
-
     for (j = 0; j < jLen; j += 1) {
       style = this.stylesList[j];
       areAnimated = false;
       tempShapes.length = 0;
-
       for (i = 0; i < len; i += 1) {
         shape = this.shapes[i];
-
         if (shape.styles.indexOf(style) !== -1) {
           tempShapes.push(shape);
           areAnimated = shape._isAnimated || areAnimated;
         }
       }
-
       if (tempShapes.length > 1 && areAnimated) {
         this.setShapesAsAnimated(tempShapes);
       }
     }
   };
-
   SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
     var i;
     var len = shapes.length;
-
     for (i = 0; i < len; i += 1) {
       shapes[i].setAsAnimated();
     }
   };
-
   SVGShapeElement.prototype.createStyleElement = function (data, level) {
     // TODO: prevent drawing of hidden styles
     var elementData;
     var styleOb = new SVGStyleData(data, level);
     var pathElement = styleOb.pElem;
-
     if (data.ty === 'st') {
       elementData = new SVGStrokeStyleData(this, data, styleOb);
     } else if (data.ty === 'fl') {
@@ -10404,7 +8847,6 @@
       var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
       elementData = new GradientConstructor(this, data, styleOb);
       this.globalData.defs.appendChild(elementData.gf);
-
       if (elementData.maskId) {
         this.globalData.defs.appendChild(elementData.ms);
         this.globalData.defs.appendChild(elementData.of);
@@ -10413,66 +8855,51 @@
     } else if (data.ty === 'no') {
       elementData = new SVGNoStyleData(this, data, styleOb);
     }
-
     if (data.ty === 'st' || data.ty === 'gs') {
       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);
       }
     }
-
     if (data.r === 2) {
       pathElement.setAttribute('fill-rule', 'evenodd');
     }
-
     if (data.ln) {
       pathElement.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       pathElement.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     this.stylesList.push(styleOb);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createGroupElement = function (data) {
     var elementData = new ShapeGroupData();
-
     if (data.ln) {
       elementData.gr.setAttribute('id', data.ln);
     }
-
     if (data.cl) {
       elementData.gr.setAttribute('class', data.cl);
     }
-
     if (data.bm) {
       elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
     }
-
     return elementData;
   };
-
   SVGShapeElement.prototype.createTransformElement = function (data, container) {
     var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
     var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
     var ty = 4;
-
     if (data.ty === 'rc') {
       ty = 5;
     } else if (data.ty === 'el') {
@@ -10480,7 +8907,6 @@
     } else if (data.ty === 'sr') {
       ty = 7;
     }
-
     var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
     var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
     this.shapes.push(elementData);
@@ -10488,58 +8914,46 @@
     this.addToAnimatedContents(data, elementData);
     return elementData;
   };
-
   SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
     var i = 0;
     var len = this.animatedContents.length;
-
     while (i < len) {
       if (this.animatedContents[i].element === element) {
         return;
       }
-
       i += 1;
     }
-
     this.animatedContents.push({
       fn: SVGElementsRenderer.createRenderFunction(data),
       element: element,
       data: data
     });
   };
-
   SVGShapeElement.prototype.setElementStyles = function (elementData) {
     var arr = elementData.styles;
     var j;
     var jLen = this.stylesList.length;
-
     for (j = 0; j < jLen; j += 1) {
-      if (!this.stylesList[j].closed) {
+      if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
         arr.push(this.stylesList[j]);
       }
     }
   };
-
   SVGShapeElement.prototype.reloadShapes = function () {
     this._isFirstFrame = true;
     var i;
     var len = this.itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       this.prevViewData[i] = this.itemsData[i];
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
     this.filterUniqueShapes();
     len = this.dynamicProperties.length;
-
     for (i = 0; i < len; i += 1) {
       this.dynamicProperties[i].getValue();
     }
-
     this.renderModifiers();
   };
-
   SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
     var ownTransformers = [].concat(transformers);
     var i;
@@ -10551,43 +8965,35 @@
     var currentTransform;
     var modifier;
     var processedPos;
-
     for (i = len; i >= 0; i -= 1) {
       processedPos = this.searchProcessedElement(arr[i]);
-
       if (!processedPos) {
         arr[i]._render = render;
       } else {
         itemsData[i] = prevViewData[processedPos - 1];
       }
-
       if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
         if (!processedPos) {
           itemsData[i] = this.createStyleElement(arr[i], level);
         } else {
-          itemsData[i].style.closed = false;
+          itemsData[i].style.closed = arr[i].hd;
         }
-
         if (arr[i]._render) {
           if (itemsData[i].style.pElem.parentNode !== container) {
             container.appendChild(itemsData[i].style.pElem);
           }
         }
-
         ownStyles.push(itemsData[i].style);
       } else if (arr[i].ty === 'gr') {
         if (!processedPos) {
           itemsData[i] = this.createGroupElement(arr[i]);
         } else {
           jLen = itemsData[i].it.length;
-
           for (j = 0; j < jLen; j += 1) {
             itemsData[i].prevViewData[j] = itemsData[i].it[j];
           }
         }
-
         this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
-
         if (arr[i]._render) {
           if (itemsData[i].gr.parentNode !== container) {
             container.appendChild(itemsData[i].gr);
@@ -10597,14 +9003,12 @@
         if (!processedPos) {
           itemsData[i] = this.createTransformElement(arr[i], container);
         }
-
         currentTransform = itemsData[i].transform;
         ownTransformers.push(currentTransform);
       } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
         if (!processedPos) {
           itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
         }
-
         this.setElementStyles(itemsData[i]);
       } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
         if (!processedPos) {
@@ -10616,7 +9020,6 @@
           modifier = itemsData[i];
           modifier.closed = false;
         }
-
         ownModifiers.push(modifier);
       } else if (arr[i].ty === 'rp') {
         if (!processedPos) {
@@ -10629,64 +9032,49 @@
           modifier = itemsData[i];
           modifier.closed = true;
         }
-
         ownModifiers.push(modifier);
       }
-
       this.addProcessedElement(arr[i], i + 1);
     }
-
     len = ownStyles.length;
-
     for (i = 0; i < len; i += 1) {
       ownStyles[i].closed = true;
     }
-
     len = ownModifiers.length;
-
     for (i = 0; i < len; i += 1) {
       ownModifiers[i].closed = true;
     }
   };
-
   SVGShapeElement.prototype.renderInnerContent = function () {
     this.renderModifiers();
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       this.stylesList[i].reset();
     }
-
     this.renderShape();
-
     for (i = 0; i < len; i += 1) {
       if (this.stylesList[i]._mdf || this._isFirstFrame) {
         if (this.stylesList[i].msElem) {
-          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d); // Adding M0 0 fixes same mask bug on all browsers
-
+          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
+          // Adding M0 0 fixes same mask bug on all browsers
           this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
         }
-
         this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
       }
     }
   };
-
   SVGShapeElement.prototype.renderShape = function () {
     var i;
     var len = this.animatedContents.length;
     var animatedContent;
-
     for (i = 0; i < len; i += 1) {
       animatedContent = this.animatedContents[i];
-
       if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
         animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
       }
     }
   };
-
   SVGShapeElement.prototype.destroy = function () {
     this.destroyBaseElement();
     this.shapesData = null;
@@ -10709,7 +9097,6 @@
       p: true
     };
   }
-
   LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
     this._mdf.o = false;
     this._mdf.sw = false;
@@ -10718,43 +9105,36 @@
     this._mdf.m = false;
     this._mdf.p = false;
     var updated = false;
-
     if (this.o !== o) {
       this.o = o;
       this._mdf.o = true;
       updated = true;
     }
-
     if (this.sw !== sw) {
       this.sw = sw;
       this._mdf.sw = true;
       updated = true;
     }
-
     if (this.sc !== sc) {
       this.sc = sc;
       this._mdf.sc = true;
       updated = true;
     }
-
     if (this.fc !== fc) {
       this.fc = fc;
       this._mdf.fc = true;
       updated = true;
     }
-
     if (this.m !== m) {
       this.m = m;
       this._mdf.m = true;
       updated = true;
     }
-
     if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
       this.p = p;
       this._mdf.p = true;
       updated = true;
     }
-
     return updated;
   };
 
@@ -10765,11 +9145,9 @@
     this.kf = false;
     this._isFirstFrame = true;
     this._mdf = false;
-
     if (data.d && data.d.sid) {
       data.d = elem.globalData.slotManager.getProp(data.d);
     }
-
     this.data = data;
     this.elem = elem;
     this.comp = this.elem.comp;
@@ -10808,73 +9186,57 @@
       __complete: false
     };
     this.copyData(this.currentData, this.data.d.k[0].s);
-
     if (!this.searchProperty()) {
       this.completeTextData(this.currentData);
     }
   }
-
   TextProperty.prototype.defaultBoxWidth = [0, 0];
-
   TextProperty.prototype.copyData = function (obj, data) {
     for (var s in data) {
       if (Object.prototype.hasOwnProperty.call(data, s)) {
         obj[s] = data[s];
       }
     }
-
     return obj;
   };
-
   TextProperty.prototype.setCurrentData = function (data) {
     if (!data.__complete) {
       this.completeTextData(data);
     }
-
     this.currentData = data;
     this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
     this._mdf = true;
   };
-
   TextProperty.prototype.searchProperty = function () {
     return this.searchKeyframes();
   };
-
   TextProperty.prototype.searchKeyframes = function () {
     this.kf = this.data.d.k.length > 1;
-
     if (this.kf) {
       this.addEffect(this.getKeyframeValue.bind(this));
     }
-
     return this.kf;
   };
-
   TextProperty.prototype.addEffect = function (effectFunction) {
     this.effectsSequence.push(effectFunction);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.getValue = function (_finalValue) {
     if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
       return;
     }
-
     this.currentData.t = this.data.d.k[this.keysIndex].s.t;
     var currentValue = this.currentData;
     var currentIndex = this.keysIndex;
-
     if (this.lock) {
       this.setCurrentData(this.currentData);
       return;
     }
-
     this.lock = true;
     this._mdf = false;
     var i;
     var len = this.effectsSequence.length;
     var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
-
     for (i = 0; i < len; i += 1) {
       // Checking if index changed to prevent creating a new object every time the expression updates.
       if (currentIndex !== this.keysIndex) {
@@ -10883,38 +9245,30 @@
         finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
       }
     }
-
     if (currentValue !== finalValue) {
       this.setCurrentData(finalValue);
     }
-
     this.v = this.currentData;
     this.pv = this.v;
     this.lock = false;
     this.frameId = this.elem.globalData.frameId;
   };
-
   TextProperty.prototype.getKeyframeValue = function () {
     var textKeys = this.data.d.k;
     var frameNum = this.elem.comp.renderedFrame;
     var i = 0;
     var len = textKeys.length;
-
     while (i <= len - 1) {
       if (i === len - 1 || textKeys[i + 1].t > frameNum) {
         break;
       }
-
       i += 1;
     }
-
     if (this.keysIndex !== i) {
       this.keysIndex = i;
     }
-
     return this.data.d.k[this.keysIndex].s;
   };
-
   TextProperty.prototype.buildFinalText = function (text) {
     var charactersArray = [];
     var i = 0;
@@ -10924,21 +9278,20 @@
     var shouldCombine = false;
     var shouldCombineNext = false;
     var currentChars = '';
-
     while (i < len) {
       shouldCombine = shouldCombineNext;
       shouldCombineNext = false;
       charCode = text.charCodeAt(i);
       currentChars = text.charAt(i);
-
       if (FontManager.isCombinedCharacter(charCode)) {
-        shouldCombine = true; // It's a potential surrogate pair (this is the High surrogate)
+        shouldCombine = true;
+        // It's a potential surrogate pair (this is the High surrogate)
       } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
         if (FontManager.isRegionalFlag(text, i)) {
           currentChars = text.substr(i, 14);
         } else {
-          secondCharCode = text.charCodeAt(i + 1); // It's a surrogate pair (this is the Low surrogate)
-
+          secondCharCode = text.charCodeAt(i + 1);
+          // It's a surrogate pair (this is the Low surrogate)
           if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
             if (FontManager.isModifier(charCode, secondCharCode)) {
               currentChars = text.substr(i, 2);
@@ -10952,7 +9305,6 @@
         }
       } else if (charCode > 0xDBFF) {
         secondCharCode = text.charCodeAt(i + 1);
-
         if (FontManager.isVariationSelector(charCode)) {
           shouldCombine = true;
         }
@@ -10960,20 +9312,16 @@
         shouldCombine = true;
         shouldCombineNext = true;
       }
-
       if (shouldCombine) {
         charactersArray[charactersArray.length - 1] += currentChars;
         shouldCombine = false;
       } else {
         charactersArray.push(currentChars);
       }
-
       i += currentChars.length;
     }
-
     return charactersArray;
   };
-
   TextProperty.prototype.completeTextData = function (documentData) {
     documentData.__complete = true;
     var fontManager = this.elem.globalData.fontManager;
@@ -11005,14 +9353,12 @@
     documentData.finalLineHeight = documentData.lh;
     var trackingOffset = documentData.tr / 1000 * documentData.finalSize;
     var charCode;
-
     if (documentData.sz) {
       var flag = true;
       var boxWidth = documentData.sz[0];
       var boxHeight = documentData.sz[1];
       var currentHeight;
       var finalText;
-
       while (flag) {
         finalText = this.buildFinalText(documentData.t);
         currentHeight = 0;
@@ -11020,11 +9366,9 @@
         len = finalText.length;
         trackingOffset = documentData.tr / 1000 * documentData.finalSize;
         var lastSpaceIndex = -1;
-
         for (i = 0; i < len; i += 1) {
           charCode = finalText[i].charCodeAt(0);
           newLineFlag = false;
-
           if (finalText[i] === ' ') {
             lastSpaceIndex = i;
           } else if (charCode === 13 || charCode === 3) {
@@ -11032,7 +9376,6 @@
             newLineFlag = true;
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
           }
-
           if (fontManager.chars) {
             charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
             cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -11040,17 +9383,15 @@
             // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
             cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
           }
-
           if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
             if (lastSpaceIndex === -1) {
               len += 1;
             } else {
               i = lastSpaceIndex;
             }
-
             currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
-            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r'); // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
-
+            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
+            // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
             lastSpaceIndex = -1;
             lineWidth = 0;
           } else {
@@ -11058,9 +9399,7 @@
             lineWidth += trackingOffset;
           }
         }
-
         currentHeight += fontData.ascent * documentData.finalSize / 100;
-
         if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
           documentData.finalSize -= 1;
           documentData.finalLineHeight = documentData.finalSize * documentData.lh / documentData.s;
@@ -11071,17 +9410,14 @@
         }
       }
     }
-
     lineWidth = -trackingOffset;
     cLength = 0;
     var uncollapsedSpaces = 0;
     var currentChar;
-
     for (i = 0; i < len; i += 1) {
       newLineFlag = false;
       currentChar = documentData.finalText[i];
       charCode = currentChar.charCodeAt(0);
-
       if (charCode === 13 || charCode === 3) {
         uncollapsedSpaces = 0;
         lineWidths.push(lineWidth);
@@ -11093,7 +9429,6 @@
       } else {
         val = currentChar;
       }
-
       if (fontManager.chars) {
         charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
         cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
@@ -11101,16 +9436,15 @@
         // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
         // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
         cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
-      } //
+      }
 
-
+      //
       if (currentChar === ' ') {
         uncollapsedSpaces += cLength + trackingOffset;
       } else {
         lineWidth += cLength + trackingOffset + uncollapsedSpaces;
         uncollapsedSpaces = 0;
       }
-
       letters.push({
         l: cLength,
         an: cLength,
@@ -11121,42 +9455,35 @@
         line: currentLine,
         animatorJustifyOffset: 0
       });
-
       if (anchorGrouping == 2) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || val === ' ' || i === len - 1) {
           if (val === '' || val === ' ') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           index += 1;
           currentSize = 0;
         }
       } else if (anchorGrouping == 3) {
         // eslint-disable-line eqeqeq
         currentSize += cLength;
-
         if (val === '' || i === len - 1) {
           if (val === '') {
             currentSize -= cLength;
           }
-
           while (currentPos <= i) {
             letters[currentPos].an = currentSize;
             letters[currentPos].ind = index;
             letters[currentPos].extra = cLength;
             currentPos += 1;
           }
-
           currentSize = 0;
           index += 1;
         }
@@ -11166,31 +9493,25 @@
         index += 1;
       }
     }
-
     documentData.l = letters;
     maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
     lineWidths.push(lineWidth);
-
     if (documentData.sz) {
       documentData.boxWidth = documentData.sz[0];
       documentData.justifyOffset = 0;
     } else {
       documentData.boxWidth = maxLineWidth;
-
       switch (documentData.j) {
         case 1:
           documentData.justifyOffset = -documentData.boxWidth;
           break;
-
         case 2:
           documentData.justifyOffset = -documentData.boxWidth / 2;
           break;
-
         default:
           documentData.justifyOffset = 0;
       }
     }
-
     documentData.lineWidths = lineWidths;
     var animators = data.a;
     var animatorData;
@@ -11199,63 +9520,49 @@
     var based;
     var ind;
     var indexes = [];
-
     for (j = 0; j < jLen; j += 1) {
       animatorData = animators[j];
-
       if (animatorData.a.sc) {
         documentData.strokeColorAnim = true;
       }
-
       if (animatorData.a.sw) {
         documentData.strokeWidthAnim = true;
       }
-
       if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
         documentData.fillColorAnim = true;
       }
-
       ind = 0;
       based = animatorData.s.b;
-
       for (i = 0; i < len; i += 1) {
         letterData = letters[i];
         letterData.anIndexes[j] = ind;
-
         if (based == 1 && letterData.val !== '' || based == 2 && letterData.val !== '' && letterData.val !== ' ' || based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1) || based == 4 && (letterData.n || i == len - 1)) {
           // eslint-disable-line eqeqeq
           if (animatorData.s.rn === 1) {
             indexes.push(ind);
           }
-
           ind += 1;
         }
       }
-
       data.a[j].s.totalChars = ind;
       var currentInd = -1;
       var newInd;
-
       if (animatorData.s.rn === 1) {
         for (i = 0; i < len; i += 1) {
           letterData = letters[i];
-
           if (currentInd != letterData.anIndexes[j]) {
             // eslint-disable-line eqeqeq
             currentInd = letterData.anIndexes[j];
             newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
           }
-
           letterData.anIndexes[j] = newInd;
         }
       }
     }
-
     documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
     documentData.ls = documentData.ls || 0;
     documentData.ascent = fontData.ascent * documentData.finalSize / 100;
   };
-
   TextProperty.prototype.updateDocumentData = function (newData, index) {
     index = index === undefined ? this.keysIndex : index;
     var dData = this.copyData({}, this.data.d.k[index].s);
@@ -11265,7 +9572,6 @@
     this.setCurrentData(dData);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.recalculate = function (index) {
     var dData = this.data.d.k[index].s;
     dData.__complete = false;
@@ -11273,13 +9579,11 @@
     this._isFirstFrame = true;
     this.getValue(dData);
   };
-
   TextProperty.prototype.canResizeFont = function (_canResize) {
     this.canResize = _canResize;
     this.recalculate(this.keysIndex);
     this.elem.addDynamicProperty(this);
   };
-
   TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
     this.minimumFontSize = Math.floor(_fontValue) || 1;
     this.recalculate(this.keysIndex);
@@ -11290,7 +9594,6 @@
     var max = Math.max;
     var min = Math.min;
     var floor = Math.floor;
-
     function TextSelectorPropFactory(elem, data) {
       this._currentTextLength = -1;
       this.k = false;
@@ -11303,7 +9606,6 @@
       this.s = PropertyFactory.getProp(elem, data.s || {
         k: 0
       }, 0, 0, this);
-
       if ('e' in data) {
         this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
       } else {
@@ -11311,7 +9613,6 @@
           v: 100
         };
       }
-
       this.o = PropertyFactory.getProp(elem, data.o || {
         k: 0
       }, 0, 0, this);
@@ -11325,48 +9626,40 @@
         k: 100
       }, 0, 0, this);
       this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
-
       if (!this.dynamicProperties.length) {
         this.getValue();
       }
     }
-
     TextSelectorPropFactory.prototype = {
       getMult: function getMult(ind) {
         if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
           this.getValue();
         }
-
         var x1 = 0;
         var y1 = 0;
         var x2 = 1;
         var y2 = 1;
-
         if (this.ne.v > 0) {
           x1 = this.ne.v / 100.0;
         } else {
           y1 = -this.ne.v / 100.0;
         }
-
         if (this.xe.v > 0) {
           x2 = 1.0 - this.xe.v / 100.0;
         } else {
           y2 = 1.0 + this.xe.v / 100.0;
         }
-
         var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
         var mult = 0;
         var s = this.finalS;
         var e = this.finalE;
         var type = this.data.sh;
-
         if (type === 2) {
           if (e === s) {
             mult = ind >= e ? 1 : 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 3) {
           if (e === s) {
@@ -11374,21 +9667,18 @@
           } else {
             mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
           }
-
           mult = easer(mult);
         } else if (type === 4) {
           if (e === s) {
             mult = 0;
           } else {
             mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
-
             if (mult < 0.5) {
               mult *= 2;
             } else {
               mult = 1 - 2 * (mult - 0.5);
             }
           }
-
           mult = easer(mult);
         } else if (type === 5) {
           if (e === s) {
@@ -11397,13 +9687,11 @@
             var tot = e - s;
             /* ind += 0.5;
                       mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
-
             ind = min(max(0, ind + 0.5 - s), e - s);
             var x = -tot / 2 + ind;
             var a = tot / 2;
             mult = Math.sqrt(1 - x * x / (a * a));
           }
-
           mult = easer(mult);
         } else if (type === 6) {
           if (e === s) {
@@ -11412,7 +9700,6 @@
             ind = min(max(0, ind + 0.5 - s), e - s);
             mult = (1 + Math.cos(Math.PI + Math.PI * 2 * ind / (e - s))) / 2; // eslint-disable-line
           }
-
           mult = easer(mult);
         } else {
           if (ind >= floor(s)) {
@@ -11422,9 +9709,9 @@
               mult = max(0, min(e - ind, 1));
             }
           }
-
           mult = easer(mult);
-        } // Smoothness implementation.
+        }
+        // Smoothness implementation.
         // The smoothness represents a reduced range of the original [0; 1] range.
         // if smoothness is 25%, the new range will be [0.375; 0.625]
         // Steps are:
@@ -11434,60 +9721,47 @@
         //     - subtract the threshold
         //     - divide it by the smoothness (this will return the range to [0; 1])
         // Note: If it doesn't work on some scenarios, consider applying it before the easer.
-
-
         if (this.sm.v !== 100) {
           var smoothness = this.sm.v * 0.01;
-
           if (smoothness === 0) {
             smoothness = 0.00000001;
           }
-
           var threshold = 0.5 - smoothness * 0.5;
-
           if (mult < threshold) {
             mult = 0;
           } else {
             mult = (mult - threshold) / smoothness;
-
             if (mult > 1) {
               mult = 1;
             }
           }
         }
-
         return mult * this.a.v;
       },
       getValue: function getValue(newCharsFlag) {
         this.iterateDynamicProperties();
         this._mdf = newCharsFlag || this._mdf;
         this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
-
         if (newCharsFlag && this.data.r === 2) {
           this.e.v = this._currentTextLength;
         }
-
         var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
         var o = this.o.v / divisor;
         var s = this.s.v / divisor + o;
         var e = this.e.v / divisor + o;
-
         if (s > e) {
           var _s = s;
           s = e;
           e = _s;
         }
-
         this.finalS = s;
         this.finalE = e;
       }
     };
     extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
-
     function getTextSelectorProp(elem, data, arr) {
       return new TextSelectorPropFactory(elem, data, arr);
     }
-
     return {
       getTextSelectorProp: getTextSelectorProp
     };
@@ -11537,18 +9811,15 @@
     this.lettersChangedFlag = false;
     this.initDynamicPropertyContainer(elem);
   }
-
   TextAnimatorProperty.prototype.searchProperties = function () {
     var i;
     var len = this._textData.a.length;
     var animatorProps;
     var getProp = PropertyFactory.getProp;
-
     for (i = 0; i < len; i += 1) {
       animatorProps = this._textData.a[i];
       this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
     }
-
     if (this._textData.p && 'm' in this._textData.p) {
       this._pathData = {
         a: getProp(this._elem, this._textData.p.a, 0, 0, this),
@@ -11562,17 +9833,13 @@
     } else {
       this._hasMaskedPath = false;
     }
-
     this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
   };
-
   TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
     this.lettersChangedFlag = lettersChangedFlag;
-
     if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
       return;
     }
-
     this._isFirstFrame = false;
     var alignment = this._moreOptions.alignment.v;
     var animators = this._animatorsData;
@@ -11600,18 +9867,14 @@
     var perc;
     var tanAngle;
     var mask;
-
     if (this._hasMaskedPath) {
       mask = this._pathData.m;
-
       if (!this._pathData.n || this._pathData._mdf) {
         var paths = mask.v;
-
         if (this._pathData.r.v) {
           paths = paths.reverse();
-        } // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
-
-
+        }
+        // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
         pathInfo = {
           tLength: 0,
           segments: []
@@ -11619,26 +9882,21 @@
         len = paths._length - 1;
         var bezierData;
         totalLength = 0;
-
         for (i = 0; i < len; i += 1) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[i + 1], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         i = len;
-
         if (mask.v.c) {
           bezierData = bez.buildBezierData(paths.v[i], paths.v[0], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
           pathInfo.tLength += bezierData.segmentLength;
           pathInfo.segments.push(bezierData);
           totalLength += bezierData.segmentLength;
         }
-
         this._pathData.pi = pathInfo;
       }
-
       pathInfo = this._pathData.pi;
       currentLength = this._pathData.f.v;
       segmentInd = 0;
@@ -11646,20 +9904,16 @@
       segmentLength = 0;
       flag = true;
       segments = pathInfo.segments;
-
       if (currentLength < 0 && mask.v.c) {
         if (pathInfo.tLength < Math.abs(currentLength)) {
           currentLength = -Math.abs(currentLength) % pathInfo.tLength;
         }
-
         segmentInd = segments.length - 1;
         points = segments[segmentInd].points;
         pointInd = points.length - 1;
-
         while (currentLength < 0) {
           currentLength += points[pointInd].partialLength;
           pointInd -= 1;
-
           if (pointInd < 0) {
             segmentInd -= 1;
             points = segments[segmentInd].points;
@@ -11667,13 +9921,11 @@
           }
         }
       }
-
       points = segments[segmentInd].points;
       prevPoint = points[pointInd - 1];
       currentPoint = points[pointInd];
       partialLength = currentPoint.partialLength;
     }
-
     len = letters.length;
     xPos = 0;
     yPos = 0;
@@ -11704,40 +9956,35 @@
     var letterFc;
     var letterM = '';
     var letterP = this.defaultPropsArray;
-    var letterO; //
+    var letterO;
 
+    //
     if (documentData.j === 2 || documentData.j === 1) {
       var animatorJustifyOffset = 0;
       var animatorFirstCharOffset = 0;
       var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
       var lastIndex = 0;
       var isNewLine = true;
-
       for (i = 0; i < len; i += 1) {
         if (letters[i].n) {
           if (animatorJustifyOffset) {
             animatorJustifyOffset += animatorFirstCharOffset;
           }
-
           while (lastIndex < i) {
             letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
             lastIndex += 1;
           }
-
           animatorJustifyOffset = 0;
           isNewLine = true;
         } else {
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.t.propType) {
               if (isNewLine && documentData.j === 2) {
                 animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
               }
-
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
               } else {
@@ -11745,33 +9992,28 @@
               }
             }
           }
-
           isNewLine = false;
         }
       }
-
       if (animatorJustifyOffset) {
         animatorJustifyOffset += animatorFirstCharOffset;
       }
-
       while (lastIndex < i) {
         letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
         lastIndex += 1;
       }
-    } //
-
+    }
+    //
 
     for (i = 0; i < len; i += 1) {
       matrixHelper.reset();
       elemOpacity = 1;
-
       if (letters[i].n) {
         xPos = 0;
         yPos += documentData.yOffset;
         yPos += firstLine ? 1 : 0;
         currentLength = initPathPos;
         firstLine = false;
-
         if (this._hasMaskedPath) {
           segmentInd = initSegmentInd;
           pointInd = initPointInd;
@@ -11781,7 +10023,6 @@
           partialLength = currentPoint.partialLength;
           segmentLength = 0;
         }
-
         letterM = '';
         letterFc = '';
         letterSw = '';
@@ -11794,48 +10035,37 @@
               case 1:
                 currentLength += totalLength - documentData.lineWidths[letters[i].line];
                 break;
-
               case 2:
                 currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
                 break;
-
               default:
                 break;
             }
-
             currentLine = letters[i].line;
           }
-
           if (ind !== letters[i].ind) {
             if (letters[ind]) {
               currentLength += letters[ind].extra;
             }
-
             currentLength += letters[i].an / 2;
             ind = letters[i].ind;
           }
-
           currentLength += alignment[0] * letters[i].an * 0.005;
           var animatorOffset = 0;
-
           for (j = 0; j < jLen; j += 1) {
             animatorProps = animators[j].a;
-
             if (animatorProps.p.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.p.v[0] * mult[0];
               } else {
                 animatorOffset += animatorProps.p.v[0] * mult;
               }
             }
-
             if (animatorProps.a.propType) {
               animatorSelector = animators[j].s;
               mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
               if (mult.length) {
                 animatorOffset += animatorProps.a.v[0] * mult[0];
               } else {
@@ -11843,14 +10073,12 @@
               }
             }
           }
-
-          flag = true; // Force alignment only works with a single line for now
-
+          flag = true;
+          // Force alignment only works with a single line for now
           if (this._pathData.a.v) {
             currentLength = letters[0].an * 0.5 + (totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind / (len - 1);
             currentLength += this._pathData.f.v;
           }
-
           while (flag) {
             if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
               perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
@@ -11861,11 +10089,9 @@
             } else if (points) {
               segmentLength += currentPoint.partialLength;
               pointInd += 1;
-
               if (pointInd >= points.length) {
                 pointInd = 0;
                 segmentInd += 1;
-
                 if (!segments[segmentInd]) {
                   if (mask.v.c) {
                     pointInd = 0;
@@ -11879,7 +10105,6 @@
                   points = segments[segmentInd].points;
                 }
               }
-
               if (points) {
                 prevPoint = currentPoint;
                 currentPoint = points[pointInd];
@@ -11887,23 +10112,21 @@
               }
             }
           }
-
           offf = letters[i].an / 2 - letters[i].add;
           matrixHelper.translate(-offf, 0, 0);
         } else {
           offf = letters[i].an / 2 - letters[i].add;
-          matrixHelper.translate(-offf, 0, 0); // Grouping alignment
+          matrixHelper.translate(-offf, 0, 0);
 
+          // Grouping alignment
           matrixHelper.translate(-alignment[0] * letters[i].an * 0.005, -alignment[1] * yOff * 0.01, 0);
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.t.propType) {
             animatorSelector = animators[j].s;
-            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars); // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
-
+            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
+            // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
             if (xPos !== 0 || documentData.j !== 0) {
               if (this._hasMaskedPath) {
                 if (mult.length) {
@@ -11919,11 +10142,9 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           sw = documentData.sw || 0;
         }
-
         if (documentData.strokeColorAnim) {
           if (documentData.sc) {
             sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
@@ -11931,18 +10152,14 @@
             sc = [0, 0, 0];
           }
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.a.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
             } else {
@@ -11950,14 +10167,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.s.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (mult.length) {
               matrixHelper.scale(1 + (animatorProps.s.v[0] - 1) * mult[0], 1 + (animatorProps.s.v[1] - 1) * mult[1], 1);
             } else {
@@ -11965,12 +10179,10 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
           animatorSelector = animators[j].s;
           mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
           if (animatorProps.sk.propType) {
             if (mult.length) {
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
@@ -11978,7 +10190,6 @@
               matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
             }
           }
-
           if (animatorProps.r.propType) {
             if (mult.length) {
               matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
@@ -11986,7 +10197,6 @@
               matrixHelper.rotateZ(-animatorProps.r.v * mult);
             }
           }
-
           if (animatorProps.ry.propType) {
             if (mult.length) {
               matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
@@ -11994,7 +10204,6 @@
               matrixHelper.rotateY(animatorProps.ry.v * mult);
             }
           }
-
           if (animatorProps.rx.propType) {
             if (mult.length) {
               matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
@@ -12002,7 +10211,6 @@
               matrixHelper.rotateX(animatorProps.rx.v * mult);
             }
           }
-
           if (animatorProps.o.propType) {
             if (mult.length) {
               elemOpacity += (animatorProps.o.v * mult[0] - elemOpacity) * mult[0];
@@ -12010,7 +10218,6 @@
               elemOpacity += (animatorProps.o.v * mult - elemOpacity) * mult;
             }
           }
-
           if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
             if (mult.length) {
               sw += animatorProps.sw.v * mult[0];
@@ -12018,7 +10225,6 @@
               sw += animatorProps.sw.v * mult;
             }
           }
-
           if (documentData.strokeColorAnim && animatorProps.sc.propType) {
             for (k = 0; k < 3; k += 1) {
               if (mult.length) {
@@ -12028,7 +10234,6 @@
               }
             }
           }
-
           if (documentData.fillColorAnim && documentData.fc) {
             if (animatorProps.fc.propType) {
               for (k = 0; k < 3; k += 1) {
@@ -12039,7 +10244,6 @@
                 }
               }
             }
-
             if (animatorProps.fh.propType) {
               if (mult.length) {
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
@@ -12047,7 +10251,6 @@
                 fc = addHueToRGB(fc, animatorProps.fh.v * mult);
               }
             }
-
             if (animatorProps.fs.propType) {
               if (mult.length) {
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
@@ -12055,7 +10258,6 @@
                 fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
               }
             }
-
             if (animatorProps.fb.propType) {
               if (mult.length) {
                 fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
@@ -12065,14 +10267,11 @@
             }
           }
         }
-
         for (j = 0; j < jLen; j += 1) {
           animatorProps = animators[j].a;
-
           if (animatorProps.p.propType) {
             animatorSelector = animators[j].s;
             mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
             if (this._hasMaskedPath) {
               if (mult.length) {
                 matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
@@ -12086,68 +10285,53 @@
             }
           }
         }
-
         if (documentData.strokeWidthAnim) {
           letterSw = sw < 0 ? 0 : sw;
         }
-
         if (documentData.strokeColorAnim) {
           letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
         }
-
         if (documentData.fillColorAnim && documentData.fc) {
           letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
         }
-
         if (this._hasMaskedPath) {
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(0, alignment[1] * yOff * 0.01 + yPos, 0);
-
           if (this._pathData.p.v) {
             tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
             var rot = Math.atan(tanAngle) * 180 / Math.PI;
-
             if (currentPoint.point[0] < prevPoint.point[0]) {
               rot += 180;
             }
-
             matrixHelper.rotate(-rot * Math.PI / 180);
           }
-
           matrixHelper.translate(xPathPos, yPathPos, 0);
           currentLength -= alignment[0] * letters[i].an * 0.005;
-
           if (letters[i + 1] && ind !== letters[i + 1].ind) {
             currentLength += letters[i].an / 2;
             currentLength += documentData.tr * 0.001 * documentData.finalSize;
           }
         } else {
           matrixHelper.translate(xPos, yPos, 0);
-
           if (documentData.ps) {
             // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
             matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
           }
-
           switch (documentData.j) {
             case 1:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
               break;
-
             case 2:
               matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
               break;
-
             default:
               break;
           }
-
           matrixHelper.translate(0, -documentData.ls);
           matrixHelper.translate(offf, 0, 0);
           matrixHelper.translate(alignment[0] * letters[i].an * 0.005, alignment[1] * yOff * 0.01, 0);
           xPos += letters[i].l + documentData.tr * 0.001 * documentData.finalSize;
         }
-
         if (renderType === 'html') {
           letterM = matrixHelper.toCSS();
         } else if (renderType === 'svg') {
@@ -12155,10 +10339,8 @@
         } else {
           letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
         }
-
         letterO = elemOpacity;
       }
-
       if (renderedLettersCount <= i) {
         letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
         this.renderedLetters.push(letterValue);
@@ -12170,22 +10352,18 @@
       }
     }
   };
-
   TextAnimatorProperty.prototype.getValue = function () {
     if (this._elem.globalData.frameId === this._frameId) {
       return;
     }
-
     this._frameId = this._elem.globalData.frameId;
     this.iterateDynamicProperties();
   };
-
   TextAnimatorProperty.prototype.mHelper = new Matrix();
   TextAnimatorProperty.prototype.defaultPropsArray = [];
   extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
 
   function ITextElement() {}
-
   ITextElement.prototype.initElement = function (data, globalData, comp) {
     this.lettersChangedFlag = true;
     this.initFrame();
@@ -12202,72 +10380,55 @@
     this.hide();
     this.textAnimator.searchProperties(this.dynamicProperties);
   };
-
   ITextElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
   };
-
   ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
     var j;
     var jLen = shapes.length;
     var pathNodes;
     var shapeStr = '';
-
     for (j = 0; j < jLen; j += 1) {
       if (shapes[j].ty === 'sh') {
         pathNodes = shapes[j].ks.k;
         shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
       }
     }
-
     return shapeStr;
   };
-
   ITextElement.prototype.updateDocumentData = function (newData, index) {
     this.textProperty.updateDocumentData(newData, index);
   };
-
   ITextElement.prototype.canResizeFont = function (_canResize) {
     this.textProperty.canResizeFont(_canResize);
   };
-
   ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
     this.textProperty.setMinimumFontSize(_fontSize);
   };
-
   ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
     if (documentData.ps) {
       matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
     }
-
     matrixHelper.translate(0, -documentData.ls, 0);
-
     switch (documentData.j) {
       case 1:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
         break;
-
       case 2:
         matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
         break;
-
       default:
         break;
     }
-
     matrixHelper.translate(xPos, yPos, 0);
   };
-
   ITextElement.prototype.buildColor = function (colorData) {
     return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
   };
-
   ITextElement.prototype.emptyProp = new LetterProps();
-
   ITextElement.prototype.destroy = function () {};
-
   ITextElement.prototype.validateText = function () {
     if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
       this.buildNewText();
@@ -12279,27 +10440,22 @@
   var emptyShapeData = {
     shapes: []
   };
-
   function SVGTextLottieElement(data, globalData, comp) {
     this.textSpans = [];
     this.renderType = 'svg';
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
-
   SVGTextLottieElement.prototype.createContent = function () {
     if (this.data.singleShape && !this.globalData.fontManager.chars) {
       this.textContainer = createNS('text');
     }
   };
-
   SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
     var i = 0;
     var len = textArray.length;
     var textContents = [];
     var currentTextContent = '';
-
     while (i < len) {
       if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
         textContents.push(currentTextContent);
@@ -12307,14 +10463,11 @@
       } else {
         currentTextContent += textArray[i];
       }
-
       i += 1;
     }
-
     textContents.push(currentTextContent);
     return textContents;
   };
-
   SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
     // data should probably be cloned to apply scale separately to each instance of a text on different layers
     // but since text internal content gets only rendered once and then it's never rerendered,
@@ -12322,41 +10475,33 @@
     // Avoiding cloning is preferred since cloning each character shape data is expensive
     if (data.shapes && data.shapes.length) {
       var shape = data.shapes[0];
-
       if (shape.it) {
         var shapeItem = shape.it[shape.it.length - 1];
-
         if (shapeItem.s) {
           shapeItem.s.k[0] = scale;
           shapeItem.s.k[1] = scale;
         }
       }
     }
-
     return data;
   };
-
   SVGTextLottieElement.prototype.buildNewText = function () {
     this.addDynamicProperty(this);
     var i;
     var len;
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
-
     if (documentData.fc) {
       this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
     } else {
       this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
     }
-
     if (documentData.sc) {
       this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
       this.layerElement.setAttribute('stroke-width', documentData.sw);
     }
-
     this.layerElement.setAttribute('font-size', documentData.finalSize);
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
-
     if (fontData.fClass) {
       this.layerElement.setAttribute('class', fontData.fClass);
     } else {
@@ -12366,7 +10511,6 @@
       this.layerElement.setAttribute('font-style', fStyle);
       this.layerElement.setAttribute('font-weight', fWeight);
     }
-
     this.layerElement.setAttribute('aria-label', documentData.t);
     var letters = documentData.l || [];
     var usesGlyphs = !!this.globalData.fontManager.chars;
@@ -12379,31 +10523,25 @@
     var yPos = 0;
     var firstLine = true;
     var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
-
     if (singleShape && !usesGlyphs && !documentData.sz) {
       var tElement = this.textContainer;
       var justify = 'start';
-
       switch (documentData.j) {
         case 1:
           justify = 'end';
           break;
-
         case 2:
           justify = 'middle';
           break;
-
         default:
           justify = 'start';
           break;
       }
-
       tElement.setAttribute('text-anchor', justify);
       tElement.setAttribute('letter-spacing', trackingOffset);
       var textContent = this.buildTextContents(documentData.finalText);
       len = textContent.length;
       yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
-
       for (i = 0; i < len; i += 1) {
         tSpan = this.textSpans[i].span || createNS('tspan');
         tSpan.textContent = textContent[i];
@@ -12411,23 +10549,19 @@
         tSpan.setAttribute('y', yPos);
         tSpan.style.display = 'inherit';
         tElement.appendChild(tSpan);
-
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
             span: null,
             glyph: null
           };
         }
-
         this.textSpans[i].span = tSpan;
         yPos += documentData.finalLineHeight;
       }
-
       this.layerElement.appendChild(tElement);
     } else {
       var cachedSpansLength = this.textSpans.length;
       var charData;
-
       for (i = 0; i < len; i += 1) {
         if (!this.textSpans[i]) {
           this.textSpans[i] = {
@@ -12436,31 +10570,24 @@
             glyph: null
           };
         }
-
         if (!usesGlyphs || !singleShape || i === 0) {
           tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
-
           if (cachedSpansLength <= i) {
             tSpan.setAttribute('stroke-linecap', 'butt');
             tSpan.setAttribute('stroke-linejoin', 'round');
             tSpan.setAttribute('stroke-miterlimit', '4');
             this.textSpans[i].span = tSpan;
-
             if (usesGlyphs) {
               var childSpan = createNS('g');
               tSpan.appendChild(childSpan);
               this.textSpans[i].childSpan = childSpan;
             }
-
             this.textSpans[i].span = tSpan;
             this.layerElement.appendChild(tSpan);
           }
-
           tSpan.style.display = 'inherit';
         }
-
         matrixHelper.reset();
-
         if (singleShape) {
           if (letters[i].n) {
             xPos = -trackingOffset;
@@ -12468,42 +10595,36 @@
             yPos += firstLine ? 1 : 0;
             firstLine = false;
           }
-
           this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
-          xPos += letters[i].l || 0; // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
-
+          xPos += letters[i].l || 0;
+          // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
           xPos += trackingOffset;
         }
-
         if (usesGlyphs) {
           charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
-          var glyphElement; // t === 1 means the character has been replaced with an animated shaped
-
+          var glyphElement;
+          // t === 1 means the character has been replaced with an animated shaped
           if (charData.t === 1) {
             glyphElement = new SVGCompElement(charData.data, this.globalData, this);
           } else {
             var data = emptyShapeData;
-
             if (charData.data && charData.data.shapes) {
               data = this.buildShapeData(charData.data, documentData.finalSize);
             }
-
             glyphElement = new SVGShapeElement(data, this.globalData, this);
           }
-
           if (this.textSpans[i].glyph) {
             var glyph = this.textSpans[i].glyph;
             this.textSpans[i].childSpan.removeChild(glyph.layerElement);
             glyph.destroy();
           }
-
           this.textSpans[i].glyph = glyphElement;
           glyphElement._debug = true;
           glyphElement.prepareFrame(0);
           glyphElement.renderFrame();
-          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement); // when using animated shapes, the layer will be scaled instead of replacing the internal scale
+          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
+          // when using animated shapes, the layer will be scaled instead of replacing the internal scale
           // this might have issues with strokes and might need a different solution
-
           if (charData.t === 1) {
             this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
           }
@@ -12511,30 +10632,24 @@
           if (singleShape) {
             tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
           }
-
           tSpan.textContent = letters[i].val;
           tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
-        } //
-
+        }
+        //
       }
-
       if (singleShape && tSpan) {
         tSpan.setAttribute('d', shapeStr);
       }
     }
-
     while (i < this.textSpans.length) {
       this.textSpans[i].span.style.display = 'none';
       i += 1;
     }
-
     this._sizeChanged = true;
   };
-
   SVGTextLottieElement.prototype.sourceRectAtTime = function () {
     this.prepareFrame(this.comp.renderedFrame - this.data.st);
     this.renderInnerContent();
-
     if (this._sizeChanged) {
       this._sizeChanged = false;
       var textBox = this.layerElement.getBBox();
@@ -12545,35 +10660,27 @@
         height: textBox.height
       };
     }
-
     return this.bbox;
   };
-
   SVGTextLottieElement.prototype.getValue = function () {
     var i;
     var len = this.textSpans.length;
     var glyphElement;
     this.renderedFrame = this.comp.renderedFrame;
-
     for (i = 0; i < len; i += 1) {
       glyphElement = this.textSpans[i].glyph;
-
       if (glyphElement) {
         glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
-
         if (glyphElement._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   SVGTextLottieElement.prototype.renderInnerContent = function () {
     this.validateText();
-
     if (!this.data.singleShape || this._mdf) {
       this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
-
       if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
         this._sizeChanged = true;
         var i;
@@ -12584,33 +10691,26 @@
         var renderedLetter;
         var textSpan;
         var glyphElement;
-
         for (i = 0; i < len; i += 1) {
           if (!letters[i].n) {
             renderedLetter = renderedLetters[i];
             textSpan = this.textSpans[i].span;
             glyphElement = this.textSpans[i].glyph;
-
             if (glyphElement) {
               glyphElement.renderFrame();
             }
-
             if (renderedLetter._mdf.m) {
               textSpan.setAttribute('transform', renderedLetter.m);
             }
-
             if (renderedLetter._mdf.o) {
               textSpan.setAttribute('opacity', renderedLetter.o);
             }
-
             if (renderedLetter._mdf.sw) {
               textSpan.setAttribute('stroke-width', renderedLetter.sw);
             }
-
             if (renderedLetter._mdf.sc) {
               textSpan.setAttribute('stroke', renderedLetter.sc);
             }
-
             if (renderedLetter._mdf.fc) {
               textSpan.setAttribute('fill', renderedLetter.fc);
             }
@@ -12623,14 +10723,12 @@
   function ISolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([IImageElement], ISolidElement);
-
   ISolidElement.prototype.createContent = function () {
-    var rect = createNS('rect'); /// /rect.style.width = this.data.sw;
+    var rect = createNS('rect');
+    /// /rect.style.width = this.data.sw;
     /// /rect.style.height = this.data.sh;
     /// /rect.style.fill = this.data.sc;
-
     rect.setAttribute('width', this.data.sw);
     rect.setAttribute('height', this.data.sh);
     rect.setAttribute('fill', this.data.sc);
@@ -12644,59 +10742,43 @@
     this.initTransform(data, globalData, comp);
     this.initHierarchy();
   }
-
   NullElement.prototype.prepareFrame = function (num) {
     this.prepareProperties(num, true);
   };
-
   NullElement.prototype.renderFrame = function () {};
-
   NullElement.prototype.getBaseElement = function () {
     return null;
   };
-
   NullElement.prototype.destroy = function () {};
-
   NullElement.prototype.sourceRectAtTime = function () {};
-
   NullElement.prototype.hide = function () {};
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
 
   function SVGRendererBase() {}
-
   extendPrototype([BaseRenderer], SVGRendererBase);
-
   SVGRendererBase.prototype.createNull = function (data) {
     return new NullElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createShape = function (data) {
     return new SVGShapeElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createText = function (data) {
     return new SVGTextLottieElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createImage = function (data) {
     return new IImageElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.createSolid = function (data) {
     return new ISolidElement(data, this.globalData, this);
   };
-
   SVGRendererBase.prototype.configAnimation = function (animData) {
     this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
     this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
-
     if (this.renderConfig.viewBoxSize) {
       this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
     } else {
       this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
     }
-
     if (!this.renderConfig.viewBoxOnly) {
       this.svgElement.setAttribute('width', animData.w);
       this.svgElement.setAttribute('height', animData.h);
@@ -12705,32 +10787,26 @@
       this.svgElement.style.transform = 'translate3d(0,0,0)';
       this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
     }
-
     if (this.renderConfig.width) {
       this.svgElement.setAttribute('width', this.renderConfig.width);
     }
-
     if (this.renderConfig.height) {
       this.svgElement.setAttribute('height', this.renderConfig.height);
     }
-
     if (this.renderConfig.className) {
       this.svgElement.setAttribute('class', this.renderConfig.className);
     }
-
     if (this.renderConfig.id) {
       this.svgElement.setAttribute('id', this.renderConfig.id);
     }
-
     if (this.renderConfig.focusable !== undefined) {
       this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
     }
-
-    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio); // this.layerElement.style.transform = 'translate3d(0,0,0)';
+    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
+    // this.layerElement.style.transform = 'translate3d(0,0,0)';
     // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
-
-    this.animationItem.wrapper.appendChild(this.svgElement); // Mask animation
-
+    this.animationItem.wrapper.appendChild(this.svgElement);
+    // Mask animation
     var defs = this.globalData.defs;
     this.setupGlobalData(animData, defs);
     this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
@@ -12749,71 +10825,54 @@
     this.layers = animData.layers;
     this.elements = createSizedArray(animData.layers.length);
   };
-
   SVGRendererBase.prototype.destroy = function () {
     if (this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     this.layerElement = null;
     this.globalData.defs = null;
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.destroyed = true;
     this.animationItem = null;
   };
-
   SVGRendererBase.prototype.updateContainerSize = function () {};
-
   SVGRendererBase.prototype.findIndexByInd = function (ind) {
     var i = 0;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.layers[i].ind === ind) {
         return i;
       }
     }
-
     return -1;
   };
-
   SVGRendererBase.prototype.buildItem = function (pos) {
     var elements = this.elements;
-
     if (elements[pos] || this.layers[pos].ty === 99) {
       return;
     }
-
     elements[pos] = true;
     var element = this.createItem(this.layers[pos]);
     elements[pos] = element;
-
     if (getExpressionsPlugin()) {
       if (this.layers[pos].ty === 0) {
         this.globalData.projectInterface.registerComposition(element);
       }
-
       element.initExpressions();
     }
-
     this.appendElementInPos(element, pos);
-
     if (this.layers[pos].tt) {
       var elementIndex = 'tp' in this.layers[pos] ? this.findIndexByInd(this.layers[pos].tp) : pos - 1;
-
       if (elementIndex === -1) {
         return;
       }
-
       if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
         this.buildItem(elementIndex);
         this.addPendingElement(element);
@@ -12824,16 +10883,13 @@
       }
     }
   };
-
   SVGRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
-
       if (element.data.tt) {
         var i = 0;
         var len = this.elements.length;
-
         while (i < len) {
           if (this.elements[i] === element) {
             var elementIndex = 'tp' in element.data ? this.findIndexByInd(element.data.tp) : i - 1;
@@ -12842,43 +10898,36 @@
             element.setMatte(matteMask);
             break;
           }
-
           i += 1;
         }
       }
     }
   };
-
   SVGRendererBase.prototype.renderFrame = function (num) {
     if (this.renderedFrame === num || this.destroyed) {
       return;
     }
-
     if (num === null) {
       num = this.renderedFrame;
     } else {
       this.renderedFrame = num;
-    } // console.log('-------');
+    }
+    // console.log('-------');
     // console.log('FRAME ',num);
-
-
     this.globalData.frameNum = num;
     this.globalData.frameId += 1;
     this.globalData.projectInterface.currentFrame = num;
     this.globalData._mdf = false;
     var i;
     var len = this.layers.length;
-
     if (!this.completeLayers) {
       this.checkLayers(num);
     }
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(num - this.layers[i].st);
       }
     }
-
     if (this.globalData._mdf) {
       for (i = 0; i < len; i += 1) {
         if (this.completeLayers || this.elements[i]) {
@@ -12887,44 +10936,34 @@
       }
     }
   };
-
   SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
     var newElement = element.getBaseElement();
-
     if (!newElement) {
       return;
     }
-
     var i = 0;
     var nextElement;
-
     while (i < pos) {
       if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
         nextElement = this.elements[i].getBaseElement();
       }
-
       i += 1;
     }
-
     if (nextElement) {
       this.layerElement.insertBefore(newElement, nextElement);
     } else {
       this.layerElement.appendChild(newElement);
     }
   };
-
   SVGRendererBase.prototype.hide = function () {
     this.layerElement.style.display = 'none';
   };
-
   SVGRendererBase.prototype.show = function () {
     this.layerElement.style.display = 'block';
   };
 
   function ICompElement() {}
-
   extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
-
   ICompElement.prototype.initElement = function (data, globalData, comp) {
     this.initFrame();
     this.initBaseData(data, globalData, comp);
@@ -12934,13 +10973,12 @@
     this.initRendererElement();
     this.createContainerElements();
     this.createRenderableComponents();
-
     if (this.data.xt || !globalData.progressiveLoad) {
       this.buildAllItems();
     }
-
     this.hide();
   };
+
   /* ICompElement.prototype.hide = function(){
       if(!this.hidden){
           this.hideElement();
@@ -12953,77 +10991,61 @@
       }
   }; */
 
-
   ICompElement.prototype.prepareFrame = function (num) {
     this._mdf = false;
     this.prepareRenderableFrame(num);
     this.prepareProperties(num, this.isInRange);
-
     if (!this.isInRange && !this.data.xt) {
       return;
     }
-
     if (!this.tm._placeholder) {
       var timeRemapped = this.tm.v;
-
       if (timeRemapped === this.data.op) {
         timeRemapped = this.data.op - 1;
       }
-
       this.renderedFrame = timeRemapped;
     } else {
       this.renderedFrame = num / this.data.sr;
     }
-
     var i;
     var len = this.elements.length;
-
     if (!this.completeLayers) {
       this.checkLayers(this.renderedFrame);
-    } // This iteration needs to be backwards because of how expressions connect between each other
-
-
+    }
+    // This iteration needs to be backwards because of how expressions connect between each other
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
-
         if (this.elements[i]._mdf) {
           this._mdf = true;
         }
       }
     }
   };
-
   ICompElement.prototype.renderInnerContent = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].renderFrame();
       }
     }
   };
-
   ICompElement.prototype.setElements = function (elems) {
     this.elements = elems;
   };
-
   ICompElement.prototype.getElements = function () {
     return this.elements;
   };
-
   ICompElement.prototype.destroyElements = function () {
     var i;
     var len = this.layers.length;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i]) {
         this.elements[i].destroy();
       }
     }
   };
-
   ICompElement.prototype.destroy = function () {
     this.destroyElements();
     this.destroyBaseElement();
@@ -13040,9 +11062,7 @@
       _placeholder: true
     };
   }
-
   extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
-
   SVGCompElement.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
@@ -13053,7 +11073,6 @@
     this.renderedFrame = -1;
     this.svgElement = createNS('svg');
     var ariaLabel = '';
-
     if (config && config.title) {
       var titleElement = createNS('title');
       var titleId = createElementID();
@@ -13062,7 +11081,6 @@
       this.svgElement.appendChild(titleElement);
       ariaLabel += titleId;
     }
-
     if (config && config.description) {
       var descElement = createNS('desc');
       var descId = createElementID();
@@ -13071,11 +11089,9 @@
       this.svgElement.appendChild(descElement);
       ariaLabel += ' ' + descId;
     }
-
     if (ariaLabel) {
       this.svgElement.setAttribute('aria-labelledby', ariaLabel);
     }
-
     var defs = createNS('defs');
     this.svgElement.appendChild(defs);
     var maskElement = createNS('g');
@@ -13113,9 +11129,7 @@
     this.destroyed = false;
     this.rendererType = 'svg';
   }
-
   extendPrototype([SVGRendererBase], SVGRenderer);
-
   SVGRenderer.prototype.createComp = function (data) {
     return new SVGCompElement(data, this.globalData, this);
   };
@@ -13125,19 +11139,15 @@
     this.sequenceList = [];
     this.transform_key_count = 0;
   }
-
   ShapeTransformManager.prototype = {
     addTransformSequence: function addTransformSequence(transforms) {
       var i;
       var len = transforms.length;
       var key = '_';
-
       for (i = 0; i < len; i += 1) {
         key += transforms[i].transform.key + '_';
       }
-
       var sequence = this.sequences[key];
-
       if (!sequence) {
         sequence = {
           transforms: [].concat(transforms),
@@ -13147,37 +11157,30 @@
         this.sequences[key] = sequence;
         this.sequenceList.push(sequence);
       }
-
       return sequence;
     },
     processSequence: function processSequence(sequence, isFirstFrame) {
       var i = 0;
       var len = sequence.transforms.length;
       var _mdf = isFirstFrame;
-
       while (i < len && !isFirstFrame) {
         if (sequence.transforms[i].transform.mProps._mdf) {
           _mdf = true;
           break;
         }
-
         i += 1;
       }
-
       if (_mdf) {
         sequence.finalTransform.reset();
-
         for (i = len - 1; i >= 0; i -= 1) {
           sequence.finalTransform.multiply(sequence.transforms[i].transform.mProps.v);
         }
       }
-
       sequence._mdf = _mdf;
     },
     processSequences: function processSequences(isFirstFrame) {
       var i;
       var len = this.sequenceList.length;
-
       for (i = 0; i < len; i += 1) {
         this.processSequence(this.sequenceList[i], isFirstFrame);
       }
@@ -13192,11 +11195,12 @@
     var id = '__lottie_element_luma_buffer';
     var lumaBuffer = null;
     var lumaBufferCtx = null;
-    var svg = null; // This alternate solution has a slight delay before the filter is applied, resulting in a flicker on the first frame.
+    var svg = null;
+
+    // This alternate solution has a slight delay before the filter is applied, resulting in a flicker on the first frame.
     // Keeping this here for reference, and in the future, if offscreen canvas supports url filters, this can be used.
     // For now, neither of them work for offscreen canvas, so canvas workers can't support the luma track matte mask.
     // Naming it solution 2 to mark the extra comment lines.
-
     /*
     var svgString = [
       '<svg xmlns="http://www.w3.org/2000/svg">',
@@ -13216,7 +11220,6 @@
 
     function createLumaSvgFilter() {
       var _svg = createNS('svg');
-
       var fil = createNS('filter');
       var matrix = createNS('feColorMatrix');
       fil.setAttribute('id', id);
@@ -13224,60 +11227,49 @@
       matrix.setAttribute('color-interpolation-filters', 'sRGB');
       matrix.setAttribute('values', '0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0');
       fil.appendChild(matrix);
-
       _svg.appendChild(fil);
-
       _svg.setAttribute('id', id + '_svg');
-
       if (featureSupport.svgLumaHidden) {
         _svg.style.display = 'none';
       }
-
       return _svg;
     }
-
     function loadLuma() {
       if (!lumaBuffer) {
         svg = createLumaSvgFilter();
         document.body.appendChild(svg);
         lumaBuffer = createTag('canvas');
-        lumaBufferCtx = lumaBuffer.getContext('2d'); // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
-
+        lumaBufferCtx = lumaBuffer.getContext('2d');
+        // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
         lumaBufferCtx.filter = 'url(#' + id + ')';
         lumaBufferCtx.fillStyle = 'rgba(0,0,0,0)';
         lumaBufferCtx.fillRect(0, 0, 1, 1);
       }
     }
-
     function getLuma(canvas) {
       if (!lumaBuffer) {
         loadLuma();
       }
-
       lumaBuffer.width = canvas.width;
-      lumaBuffer.height = canvas.height; // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
-
+      lumaBuffer.height = canvas.height;
+      // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
       lumaBufferCtx.filter = 'url(#' + id + ')';
       return lumaBuffer;
     }
-
     return {
       load: loadLuma,
       get: getLuma
     };
   };
-
   function createCanvas(width, height) {
     if (featureSupport.offscreenCanvas) {
       return new OffscreenCanvas(width, height);
     }
-
     var canvas = createTag('canvas');
     canvas.width = width;
     canvas.height = height;
     return canvas;
   }
-
   var assetLoader = function () {
     return {
       loadLumaCanvas: lumaLoader.load,
@@ -13287,55 +11279,44 @@
   }();
 
   var registeredEffects = {};
-
   function CVEffects(elem) {
     var i;
     var len = elem.data.ef ? elem.data.ef.length : 0;
     this.filters = [];
     var filterManager;
-
     for (i = 0; i < len; i += 1) {
       filterManager = null;
       var type = elem.data.ef[i].ty;
-
       if (registeredEffects[type]) {
         var Effect = registeredEffects[type].effect;
         filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
       }
-
       if (filterManager) {
         this.filters.push(filterManager);
       }
     }
-
     if (this.filters.length) {
       elem.addRenderableComponent(this);
     }
   }
-
   CVEffects.prototype.renderFrame = function (_isFirstFrame) {
     var i;
     var len = this.filters.length;
-
     for (i = 0; i < len; i += 1) {
       this.filters[i].renderFrame(_isFirstFrame);
     }
   };
-
   CVEffects.prototype.getEffects = function (type) {
     var i;
     var len = this.filters.length;
     var effects = [];
-
     for (i = 0; i < len; i += 1) {
       if (this.filters[i].type === type) {
         effects.push(this.filters[i]);
       }
     }
-
     return effects;
   };
-
   function registerEffect(id, effect) {
     registeredEffects[id] = {
       effect: effect
@@ -13350,27 +11331,21 @@
     var i;
     var len = this.masksProperties.length;
     var hasMasks = false;
-
     for (i = 0; i < len; i += 1) {
       if (this.masksProperties[i].mode !== 'n') {
         hasMasks = true;
       }
-
       this.viewData[i] = ShapePropertyFactory.getShapeProp(this.element, this.masksProperties[i], 3);
     }
-
     this.hasMasks = hasMasks;
-
     if (hasMasks) {
       this.element.addRenderableComponent(this);
     }
   }
-
   CVMaskElement.prototype.renderFrame = function () {
     if (!this.hasMasks) {
       return;
     }
-
     var transform = this.element.finalTransform.mat;
     var ctx = this.element.canvasContext;
     var i;
@@ -13379,7 +11354,6 @@
     var pts;
     var data;
     ctx.beginPath();
-
     for (i = 0; i < len; i += 1) {
       if (this.masksProperties[i].mode !== 'n') {
         if (this.masksProperties[i].inv) {
@@ -13389,35 +11363,28 @@
           ctx.lineTo(0, this.element.globalData.compSize.h);
           ctx.lineTo(0, 0);
         }
-
         data = this.viewData[i].v;
         pt = transform.applyToPointArray(data.v[0][0], data.v[0][1], 0);
         ctx.moveTo(pt[0], pt[1]);
         var j;
         var jLen = data._length;
-
         for (j = 1; j < jLen; j += 1) {
           pts = transform.applyToTriplePoints(data.o[j - 1], data.i[j], data.v[j]);
           ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
         }
-
         pts = transform.applyToTriplePoints(data.o[j - 1], data.i[0], data.v[0]);
         ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
       }
     }
-
     this.element.globalData.renderer.save(true);
     ctx.clip();
   };
-
   CVMaskElement.prototype.getMaskProperty = MaskElement.prototype.getMaskProperty;
-
   CVMaskElement.prototype.destroy = function () {
     this.element = null;
   };
 
   function CVBaseElement() {}
-
   var operationsMap = {
     1: 'source-in',
     2: 'source-out',
@@ -13440,12 +11407,10 @@
         this.buffers.push(bufferCanvas);
         var bufferCanvas2 = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
         this.buffers.push(bufferCanvas2);
-
         if (this.data.tt >= 3 && !document._isProxy) {
           assetLoader.loadLumaCanvas();
         }
       }
-
       this.canvasContext = this.globalData.canvasContext;
       this.transformCanvas = this.globalData.transformCanvas;
       this.renderableEffectsManager = new CVEffects(this);
@@ -13454,7 +11419,6 @@
     createContent: function createContent() {},
     setBlendMode: function setBlendMode() {
       var globalData = this.globalData;
-
       if (globalData.blendMode !== this.data.bm) {
         globalData.blendMode = this.data.bm;
         var blendModeValue = getBlendMode(this.data.bm);
@@ -13484,11 +11448,11 @@
       if (this.data.tt >= 1) {
         var buffer = this.buffers[0];
         var bufferCtx = buffer.getContext('2d');
-        this.clearCanvas(bufferCtx); // on the first buffer we store the current state of the global drawing
-
-        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0); // The next four lines are to clear the canvas
+        this.clearCanvas(bufferCtx);
+        // on the first buffer we store the current state of the global drawing
+        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+        // The next four lines are to clear the canvas
         // TODO: Check if there is a way to clear the canvas without resetting the transform
-
         this.currentTransform = this.canvasContext.getTransform();
         this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
         this.clearCanvas(this.canvasContext);
@@ -13497,43 +11461,43 @@
     },
     exitLayer: function exitLayer() {
       if (this.data.tt >= 1) {
-        var buffer = this.buffers[1]; // On the second buffer we store the current state of the global drawing
+        var buffer = this.buffers[1];
+        // On the second buffer we store the current state of the global drawing
         // that only contains the content of this layer
         // (if it is a composition, it also includes the nested layers)
-
         var bufferCtx = buffer.getContext('2d');
         this.clearCanvas(bufferCtx);
-        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0); // We clear the canvas again
-
+        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
+        // We clear the canvas again
         this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
         this.clearCanvas(this.canvasContext);
-        this.canvasContext.setTransform(this.currentTransform); // We draw the mask
-
+        this.canvasContext.setTransform(this.currentTransform);
+        // We draw the mask
         var mask = this.comp.getElementById('tp' in this.data ? this.data.tp : this.data.ind - 1);
-        mask.renderFrame(true); // We draw the second buffer (that contains the content of this layer)
+        mask.renderFrame(true);
+        // We draw the second buffer (that contains the content of this layer)
+        this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
 
-        this.canvasContext.setTransform(1, 0, 0, 1, 0, 0); // If the mask is a Luma matte, we need to do two extra painting operations
+        // If the mask is a Luma matte, we need to do two extra painting operations
         // the _isProxy check is to avoid drawing a fake canvas in workers that will throw an error
-
         if (this.data.tt >= 3 && !document._isProxy) {
           // We copy the painted mask to a buffer that has a color matrix filter applied to it
           // that applies the rgb values to the alpha channel
           var lumaBuffer = assetLoader.getLumaCanvas(this.canvasContext.canvas);
           var lumaBufferCtx = lumaBuffer.getContext('2d');
           lumaBufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
-          this.clearCanvas(this.canvasContext); // we repaint the context with the mask applied to it
-
+          this.clearCanvas(this.canvasContext);
+          // we repaint the context with the mask applied to it
           this.canvasContext.drawImage(lumaBuffer, 0, 0);
         }
-
         this.canvasContext.globalCompositeOperation = operationsMap[this.data.tt];
-        this.canvasContext.drawImage(buffer, 0, 0); // We finally draw the first buffer (that contains the content of the global drawing)
+        this.canvasContext.drawImage(buffer, 0, 0);
+        // We finally draw the first buffer (that contains the content of the global drawing)
         // We use destination-over to draw the global drawing below the current layer
-
         this.canvasContext.globalCompositeOperation = 'destination-over';
         this.canvasContext.drawImage(this.buffers[0], 0, 0);
-        this.canvasContext.setTransform(this.currentTransform); // We reset the globalCompositeOperation to source-over, the standard type of operation
-
+        this.canvasContext.setTransform(this.currentTransform);
+        // We reset the globalCompositeOperation to source-over, the standard type of operation
         this.canvasContext.globalCompositeOperation = 'source-over';
       }
     },
@@ -13541,11 +11505,9 @@
       if (this.hidden || this.data.hd) {
         return;
       }
-
       if (this.data.td === 1 && !forceRender) {
         return;
       }
-
       this.renderTransform();
       this.renderRenderable();
       this.renderLocalTransform();
@@ -13558,11 +11520,9 @@
       this.renderInnerContent();
       this.globalData.renderer.restore(forceRealStack);
       this.exitLayer();
-
       if (this.maskManager.hasMasks) {
         this.globalData.renderer.restore(true);
       }
-
       if (this._isFirstFrame) {
         this._isFirstFrame = false;
       }
@@ -13582,7 +11542,6 @@
     this.styledShapes = [];
     this.tr = [0, 0, 0, 0, 0, 0];
     var ty = 4;
-
     if (data.ty === 'rc') {
       ty = 5;
     } else if (data.ty === 'el') {
@@ -13590,12 +11549,10 @@
     } else if (data.ty === 'sr') {
       ty = 7;
     }
-
     this.sh = ShapePropertyFactory.getShapeProp(element, data, ty, element);
     var i;
     var len = styles.length;
     var styledShape;
-
     for (i = 0; i < len; i += 1) {
       if (!styles[i].closed) {
         styledShape = {
@@ -13607,7 +11564,6 @@
       }
     }
   }
-
   CVShapeData.prototype.setAsAnimated = SVGShapeData.prototype.setAsAnimated;
 
   function CVShapeElement(data, globalData, comp) {
@@ -13621,7 +11577,6 @@
     this.transformsManager = new ShapeTransformManager();
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableElement], CVShapeElement);
   CVShapeElement.prototype.initElement = RenderableDOMElement.prototype.initElement;
   CVShapeElement.prototype.transformHelper = {
@@ -13629,11 +11584,9 @@
     _opMdf: false
   };
   CVShapeElement.prototype.dashResetter = [];
-
   CVShapeElement.prototype.createContent = function () {
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
   };
-
   CVShapeElement.prototype.createStyleElement = function (data, transforms) {
     var styleElem = {
       data: data,
@@ -13644,10 +11597,8 @@
       closed: data.hd === true
     };
     var elementData = {};
-
     if (data.ty === 'fl' || data.ty === 'st') {
       elementData.c = PropertyFactory.getProp(this, data.c, 1, 255, this);
-
       if (!elementData.c.k) {
         styleElem.co = 'rgb(' + bmFloor(elementData.c.v[0]) + ',' + bmFloor(elementData.c.v[1]) + ',' + bmFloor(elementData.c.v[2]) + ')';
       }
@@ -13662,28 +11613,21 @@
       }, 0, degToRads, this);
       elementData.g = new GradientProperty(this, data.g, this);
     }
-
     elementData.o = PropertyFactory.getProp(this, data.o, 0, 0.01, this);
-
     if (data.ty === 'st' || data.ty === 'gs') {
       styleElem.lc = lineCapEnum[data.lc || 2];
       styleElem.lj = lineJoinEnum[data.lj || 2];
-
       if (data.lj == 1) {
         // eslint-disable-line eqeqeq
         styleElem.ml = data.ml;
       }
-
       elementData.w = PropertyFactory.getProp(this, data.w, 0, null, this);
-
       if (!elementData.w.k) {
         styleElem.wi = elementData.w.v;
       }
-
       if (data.d) {
         var d = new DashProperty(this, data.d, 'canvas', this);
         elementData.d = d;
-
         if (!elementData.d.k) {
           styleElem.da = elementData.d.dashArray;
           styleElem["do"] = elementData.d.dashoffset[0];
@@ -13692,12 +11636,10 @@
     } else {
       styleElem.r = data.r === 2 ? 'evenodd' : 'nonzero';
     }
-
     this.stylesList.push(styleElem);
     elementData.style = styleElem;
     return elementData;
   };
-
   CVShapeElement.prototype.createGroupElement = function () {
     var elementData = {
       it: [],
@@ -13705,7 +11647,6 @@
     };
     return elementData;
   };
-
   CVShapeElement.prototype.createTransformElement = function (data) {
     var elementData = {
       transform: {
@@ -13718,65 +11659,52 @@
     };
     return elementData;
   };
-
   CVShapeElement.prototype.createShapeElement = function (data) {
     var elementData = new CVShapeData(this, data, this.stylesList, this.transformsManager);
     this.shapes.push(elementData);
     this.addShapeToModifiers(elementData);
     return elementData;
   };
-
   CVShapeElement.prototype.reloadShapes = function () {
     this._isFirstFrame = true;
     var i;
     var len = this.itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       this.prevViewData[i] = this.itemsData[i];
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
     len = this.dynamicProperties.length;
-
     for (i = 0; i < len; i += 1) {
       this.dynamicProperties[i].getValue();
     }
-
     this.renderModifiers();
     this.transformsManager.processSequences(this._isFirstFrame);
   };
-
   CVShapeElement.prototype.addTransformToStyleList = function (transform) {
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       if (!this.stylesList[i].closed) {
         this.stylesList[i].transforms.push(transform);
       }
     }
   };
-
   CVShapeElement.prototype.removeTransformFromStyleList = function () {
     var i;
     var len = this.stylesList.length;
-
     for (i = 0; i < len; i += 1) {
       if (!this.stylesList[i].closed) {
         this.stylesList[i].transforms.pop();
       }
     }
   };
-
   CVShapeElement.prototype.closeStyles = function (styles) {
     var i;
     var len = styles.length;
-
     for (i = 0; i < len; i += 1) {
       styles[i].closed = true;
     }
   };
-
   CVShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, shouldRender, transforms) {
     var i;
     var len = arr.length - 1;
@@ -13788,42 +11716,35 @@
     var modifier;
     var currentTransform;
     var ownTransforms = [].concat(transforms);
-
     for (i = len; i >= 0; i -= 1) {
       processedPos = this.searchProcessedElement(arr[i]);
-
       if (!processedPos) {
         arr[i]._shouldRender = shouldRender;
       } else {
         itemsData[i] = prevViewData[processedPos - 1];
       }
-
       if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs') {
         if (!processedPos) {
           itemsData[i] = this.createStyleElement(arr[i], ownTransforms);
         } else {
           itemsData[i].style.closed = false;
         }
-
         ownStyles.push(itemsData[i].style);
       } else if (arr[i].ty === 'gr') {
         if (!processedPos) {
           itemsData[i] = this.createGroupElement(arr[i]);
         } else {
           jLen = itemsData[i].it.length;
-
           for (j = 0; j < jLen; j += 1) {
             itemsData[i].prevViewData[j] = itemsData[i].it[j];
           }
         }
-
         this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, shouldRender, ownTransforms);
       } else if (arr[i].ty === 'tr') {
         if (!processedPos) {
           currentTransform = this.createTransformElement(arr[i]);
           itemsData[i] = currentTransform;
         }
-
         ownTransforms.push(itemsData[i]);
         this.addTransformToStyleList(itemsData[i]);
       } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
@@ -13840,7 +11761,6 @@
           modifier = itemsData[i];
           modifier.closed = false;
         }
-
         ownModifiers.push(modifier);
       } else if (arr[i].ty === 'rp') {
         if (!processedPos) {
@@ -13853,22 +11773,17 @@
           modifier = itemsData[i];
           modifier.closed = true;
         }
-
         ownModifiers.push(modifier);
       }
-
       this.addProcessedElement(arr[i], i + 1);
     }
-
     this.removeTransformFromStyleList();
     this.closeStyles(ownStyles);
     len = ownModifiers.length;
-
     for (i = 0; i < len; i += 1) {
       ownModifiers[i].closed = true;
     }
   };
-
   CVShapeElement.prototype.renderInnerContent = function () {
     this.transformHelper.opacity = 1;
     this.transformHelper._opMdf = false;
@@ -13876,7 +11791,6 @@
     this.transformsManager.processSequences(this._isFirstFrame);
     this.renderShape(this.transformHelper, this.shapesData, this.itemsData, true);
   };
-
   CVShapeElement.prototype.renderShapeTransform = function (parentTransform, groupTransform) {
     if (parentTransform._opMdf || groupTransform.op._mdf || this._isFirstFrame) {
       groupTransform.opacity = parentTransform.opacity;
@@ -13884,7 +11798,6 @@
       groupTransform._opMdf = true;
     }
   };
-
   CVShapeElement.prototype.drawLayer = function () {
     var i;
     var len = this.stylesList.length;
@@ -13898,55 +11811,49 @@
     var ctx = this.globalData.canvasContext;
     var type;
     var currentStyle;
-
     for (i = 0; i < len; i += 1) {
       currentStyle = this.stylesList[i];
-      type = currentStyle.type; // Skipping style when
+      type = currentStyle.type;
+
+      // Skipping style when
       // Stroke width equals 0
       // style should not be rendered (extra unused repeaters)
       // current opacity equals 0
       // global opacity equals 0
-
       if (!((type === 'st' || type === 'gs') && currentStyle.wi === 0 || !currentStyle.data._shouldRender || currentStyle.coOp === 0 || this.globalData.currentGlobalAlpha === 0)) {
         renderer.save();
         elems = currentStyle.elements;
-
         if (type === 'st' || type === 'gs') {
-          renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd); // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
-
-          renderer.ctxLineWidth(currentStyle.wi); // ctx.lineWidth = currentStyle.wi;
-
-          renderer.ctxLineCap(currentStyle.lc); // ctx.lineCap = currentStyle.lc;
-
-          renderer.ctxLineJoin(currentStyle.lj); // ctx.lineJoin = currentStyle.lj;
-
-          renderer.ctxMiterLimit(currentStyle.ml || 0); // ctx.miterLimit = currentStyle.ml || 0;
+          renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd);
+          // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
+          renderer.ctxLineWidth(currentStyle.wi);
+          // ctx.lineWidth = currentStyle.wi;
+          renderer.ctxLineCap(currentStyle.lc);
+          // ctx.lineCap = currentStyle.lc;
+          renderer.ctxLineJoin(currentStyle.lj);
+          // ctx.lineJoin = currentStyle.lj;
+          renderer.ctxMiterLimit(currentStyle.ml || 0);
+          // ctx.miterLimit = currentStyle.ml || 0;
         } else {
-          renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd); // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
+          renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd);
+          // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
         }
-
         renderer.ctxOpacity(currentStyle.coOp);
-
         if (type !== 'st' && type !== 'gs') {
           ctx.beginPath();
         }
-
         renderer.ctxTransform(currentStyle.preTransforms.finalTransform.props);
         jLen = elems.length;
-
         for (j = 0; j < jLen; j += 1) {
           if (type === 'st' || type === 'gs') {
             ctx.beginPath();
-
             if (currentStyle.da) {
               ctx.setLineDash(currentStyle.da);
               ctx.lineDashOffset = currentStyle["do"];
             }
           }
-
           nodes = elems[j].trNodes;
           kLen = nodes.length;
-
           for (k = 0; k < kLen; k += 1) {
             if (nodes[k].t === 'm') {
               ctx.moveTo(nodes[k].p[0], nodes[k].p[1]);
@@ -13956,33 +11863,27 @@
               ctx.closePath();
             }
           }
-
           if (type === 'st' || type === 'gs') {
             // ctx.stroke();
             renderer.ctxStroke();
-
             if (currentStyle.da) {
               ctx.setLineDash(this.dashResetter);
             }
           }
         }
-
         if (type !== 'st' && type !== 'gs') {
           // ctx.fill(currentStyle.r);
           this.globalData.renderer.ctxFill(currentStyle.r);
         }
-
         renderer.restore();
       }
     }
   };
-
   CVShapeElement.prototype.renderShape = function (parentTransform, items, data, isMain) {
     var i;
     var len = items.length - 1;
     var groupTransform;
     groupTransform = parentTransform;
-
     for (i = len; i >= 0; i -= 1) {
       if (items[i].ty === 'tr') {
         groupTransform = data[i].transform;
@@ -13997,15 +11898,14 @@
         this.renderGradientFill(items[i], data[i], groupTransform);
       } else if (items[i].ty === 'gr') {
         this.renderShape(groupTransform, items[i].it, data[i].it);
-      } else if (items[i].ty === 'tm') {//
+      } else if (items[i].ty === 'tm') {
+        //
       }
     }
-
     if (isMain) {
       this.drawLayer();
     }
   };
-
   CVShapeElement.prototype.renderStyledShape = function (styledShape, shape) {
     if (this._isFirstFrame || shape._mdf || styledShape.transforms._mdf) {
       var shapeNodes = styledShape.trNodes;
@@ -14016,13 +11916,10 @@
       var jLen = paths._length;
       shapeNodes.length = 0;
       var groupTransformMat = styledShape.transforms.finalTransform;
-
       for (j = 0; j < jLen; j += 1) {
         var pathNodes = paths.shapes[j];
-
         if (pathNodes && pathNodes.v) {
           len = pathNodes._length;
-
           for (i = 1; i < len; i += 1) {
             if (i === 1) {
               shapeNodes.push({
@@ -14030,20 +11927,17 @@
                 p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0)
               });
             }
-
             shapeNodes.push({
               t: 'c',
               pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[i], pathNodes.v[i])
             });
           }
-
           if (len === 1) {
             shapeNodes.push({
               t: 'm',
               p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0)
             });
           }
-
           if (pathNodes.c && len) {
             shapeNodes.push({
               t: 'c',
@@ -14055,103 +11949,81 @@
           }
         }
       }
-
       styledShape.trNodes = shapeNodes;
     }
   };
-
   CVShapeElement.prototype.renderPath = function (pathData, itemData) {
     if (pathData.hd !== true && pathData._shouldRender) {
       var i;
       var len = itemData.styledShapes.length;
-
       for (i = 0; i < len; i += 1) {
         this.renderStyledShape(itemData.styledShapes[i], itemData.sh);
       }
     }
   };
-
   CVShapeElement.prototype.renderFill = function (styleData, itemData, groupTransform) {
     var styleElem = itemData.style;
-
     if (itemData.c._mdf || this._isFirstFrame) {
       styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
     }
-
     if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
       styleElem.coOp = itemData.o.v * groupTransform.opacity;
     }
   };
-
   CVShapeElement.prototype.renderGradientFill = function (styleData, itemData, groupTransform) {
     var styleElem = itemData.style;
     var grd;
-
     if (!styleElem.grd || itemData.g._mdf || itemData.s._mdf || itemData.e._mdf || styleData.t !== 1 && (itemData.h._mdf || itemData.a._mdf)) {
       var ctx = this.globalData.canvasContext;
       var pt1 = itemData.s.v;
       var pt2 = itemData.e.v;
-
       if (styleData.t === 1) {
         grd = ctx.createLinearGradient(pt1[0], pt1[1], pt2[0], pt2[1]);
       } else {
         var rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
         var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
         var percent = itemData.h.v;
-
         if (percent >= 1) {
           percent = 0.99;
         } else if (percent <= -1) {
           percent = -0.99;
         }
-
         var dist = rad * percent;
         var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
         var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
         grd = ctx.createRadialGradient(x, y, 0, pt1[0], pt1[1], rad);
       }
-
       var i;
       var len = styleData.g.p;
       var cValues = itemData.g.c;
       var opacity = 1;
-
       for (i = 0; i < len; i += 1) {
         if (itemData.g._hasOpacity && itemData.g._collapsable) {
           opacity = itemData.g.o[i * 2 + 1];
         }
-
         grd.addColorStop(cValues[i * 4] / 100, 'rgba(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ',' + opacity + ')');
       }
-
       styleElem.grd = grd;
     }
-
     styleElem.coOp = itemData.o.v * groupTransform.opacity;
   };
-
   CVShapeElement.prototype.renderStroke = function (styleData, itemData, groupTransform) {
     var styleElem = itemData.style;
     var d = itemData.d;
-
     if (d && (d._mdf || this._isFirstFrame)) {
       styleElem.da = d.dashArray;
       styleElem["do"] = d.dashoffset[0];
     }
-
     if (itemData.c._mdf || this._isFirstFrame) {
       styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
     }
-
     if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
       styleElem.coOp = itemData.o.v * groupTransform.opacity;
     }
-
     if (itemData.w._mdf || this._isFirstFrame) {
       styleElem.wi = itemData.w.v;
     }
   };
-
   CVShapeElement.prototype.destroy = function () {
     this.shapesData = null;
     this.globalData = null;
@@ -14179,31 +12051,25 @@
     };
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement, ITextElement], CVTextElement);
   CVTextElement.prototype.tHelper = createTag('canvas').getContext('2d');
-
   CVTextElement.prototype.buildNewText = function () {
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
     var hasFill = false;
-
     if (documentData.fc) {
       hasFill = true;
       this.values.fill = this.buildColor(documentData.fc);
     } else {
       this.values.fill = 'rgba(0,0,0,0)';
     }
-
     this.fill = hasFill;
     var hasStroke = false;
-
     if (documentData.sc) {
       hasStroke = true;
       this.values.stroke = this.buildColor(documentData.sc);
       this.values.sWidth = documentData.sw;
     }
-
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
     var i;
     var len;
@@ -14211,8 +12077,8 @@
     var matrixHelper = this.mHelper;
     this.stroke = hasStroke;
     this.values.fValue = documentData.finalSize + 'px ' + this.globalData.fontManager.getFontByName(documentData.f).fFamily;
-    len = documentData.finalText.length; // this.tHelper.font = this.values.fValue;
-
+    len = documentData.finalText.length;
+    // this.tHelper.font = this.values.fValue;
     var charData;
     var shapeData;
     var k;
@@ -14229,55 +12095,44 @@
     var yPos = 0;
     var firstLine = true;
     var cnt = 0;
-
     for (i = 0; i < len; i += 1) {
       charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
       shapeData = charData && charData.data || {};
       matrixHelper.reset();
-
       if (singleShape && letters[i].n) {
         xPos = -trackingOffset;
         yPos += documentData.yOffset;
         yPos += firstLine ? 1 : 0;
         firstLine = false;
       }
-
       shapes = shapeData.shapes ? shapeData.shapes[0].it : [];
       jLen = shapes.length;
       matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
-
       if (singleShape) {
         this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
       }
-
       commands = createSizedArray(jLen - 1);
       var commandsCounter = 0;
-
       for (j = 0; j < jLen; j += 1) {
         if (shapes[j].ty === 'sh') {
           kLen = shapes[j].ks.k.i.length;
           pathNodes = shapes[j].ks.k;
           pathArr = [];
-
           for (k = 1; k < kLen; k += 1) {
             if (k === 1) {
               pathArr.push(matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
             }
-
             pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToY(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToX(pathNodes.v[k][0], pathNodes.v[k][1], 0), matrixHelper.applyToY(pathNodes.v[k][0], pathNodes.v[k][1], 0));
           }
-
           pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToY(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
           commands[commandsCounter] = pathArr;
           commandsCounter += 1;
         }
       }
-
       if (singleShape) {
         xPos += letters[i].l;
         xPos += trackingOffset;
       }
-
       if (this.textSpans[cnt]) {
         this.textSpans[cnt].elem = commands;
       } else {
@@ -14285,25 +12140,23 @@
           elem: commands
         };
       }
-
       cnt += 1;
     }
   };
-
   CVTextElement.prototype.renderInnerContent = function () {
     this.validateText();
     var ctx = this.canvasContext;
     ctx.font = this.values.fValue;
-    this.globalData.renderer.ctxLineCap('butt'); // ctx.lineCap = 'butt';
-
-    this.globalData.renderer.ctxLineJoin('miter'); // ctx.lineJoin = 'miter';
-
-    this.globalData.renderer.ctxMiterLimit(4); // ctx.miterLimit = 4;
+    this.globalData.renderer.ctxLineCap('butt');
+    // ctx.lineCap = 'butt';
+    this.globalData.renderer.ctxLineJoin('miter');
+    // ctx.lineJoin = 'miter';
+    this.globalData.renderer.ctxMiterLimit(4);
+    // ctx.miterLimit = 4;
 
     if (!this.data.singleShape) {
       this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
     }
-
     var i;
     var len;
     var j;
@@ -14320,87 +12173,81 @@
     var commands;
     var pathArr;
     var renderer = this.globalData.renderer;
-
     for (i = 0; i < len; i += 1) {
       if (!letters[i].n) {
         renderedLetter = renderedLetters[i];
-
         if (renderedLetter) {
           renderer.save();
           renderer.ctxTransform(renderedLetter.p);
           renderer.ctxOpacity(renderedLetter.o);
         }
-
         if (this.fill) {
           if (renderedLetter && renderedLetter.fc) {
             if (lastFill !== renderedLetter.fc) {
               renderer.ctxFillStyle(renderedLetter.fc);
-              lastFill = renderedLetter.fc; // ctx.fillStyle = renderedLetter.fc;
+              lastFill = renderedLetter.fc;
+              // ctx.fillStyle = renderedLetter.fc;
             }
           } else if (lastFill !== this.values.fill) {
             lastFill = this.values.fill;
-            renderer.ctxFillStyle(this.values.fill); // ctx.fillStyle = this.values.fill;
+            renderer.ctxFillStyle(this.values.fill);
+            // ctx.fillStyle = this.values.fill;
           }
-
           commands = this.textSpans[i].elem;
           jLen = commands.length;
           this.globalData.canvasContext.beginPath();
-
           for (j = 0; j < jLen; j += 1) {
             pathArr = commands[j];
             kLen = pathArr.length;
             this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
-
             for (k = 2; k < kLen; k += 6) {
               this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
             }
           }
-
           this.globalData.canvasContext.closePath();
-          renderer.ctxFill(); // this.globalData.canvasContext.fill();
+          renderer.ctxFill();
+          // this.globalData.canvasContext.fill();
           /// ctx.fillText(this.textSpans[i].val,0,0);
         }
-
         if (this.stroke) {
           if (renderedLetter && renderedLetter.sw) {
             if (lastStrokeW !== renderedLetter.sw) {
               lastStrokeW = renderedLetter.sw;
-              renderer.ctxLineWidth(renderedLetter.sw); // ctx.lineWidth = renderedLetter.sw;
+              renderer.ctxLineWidth(renderedLetter.sw);
+              // ctx.lineWidth = renderedLetter.sw;
             }
           } else if (lastStrokeW !== this.values.sWidth) {
             lastStrokeW = this.values.sWidth;
-            renderer.ctxLineWidth(this.values.sWidth); // ctx.lineWidth = this.values.sWidth;
+            renderer.ctxLineWidth(this.values.sWidth);
+            // ctx.lineWidth = this.values.sWidth;
           }
-
           if (renderedLetter && renderedLetter.sc) {
             if (lastStroke !== renderedLetter.sc) {
               lastStroke = renderedLetter.sc;
-              renderer.ctxStrokeStyle(renderedLetter.sc); // ctx.strokeStyle = renderedLetter.sc;
+              renderer.ctxStrokeStyle(renderedLetter.sc);
+              // ctx.strokeStyle = renderedLetter.sc;
             }
           } else if (lastStroke !== this.values.stroke) {
             lastStroke = this.values.stroke;
-            renderer.ctxStrokeStyle(this.values.stroke); // ctx.strokeStyle = this.values.stroke;
+            renderer.ctxStrokeStyle(this.values.stroke);
+            // ctx.strokeStyle = this.values.stroke;
           }
-
           commands = this.textSpans[i].elem;
           jLen = commands.length;
           this.globalData.canvasContext.beginPath();
-
           for (j = 0; j < jLen; j += 1) {
             pathArr = commands[j];
             kLen = pathArr.length;
             this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
-
             for (k = 2; k < kLen; k += 6) {
               this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
             }
           }
-
           this.globalData.canvasContext.closePath();
-          renderer.ctxStroke(); // this.globalData.canvasContext.stroke();
+          renderer.ctxStroke();
+          // this.globalData.canvasContext.stroke();
           /// ctx.strokeText(letters[i].val,0,0);
         }
-
         if (renderedLetter) {
           this.globalData.renderer.restore();
         }
@@ -14413,11 +12260,9 @@
     this.img = globalData.imageLoader.getAsset(this.assetData);
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVImageElement);
   CVImageElement.prototype.initElement = SVGShapeElement.prototype.initElement;
   CVImageElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
-
   CVImageElement.prototype.createContent = function () {
     if (this.img.width && (this.assetData.w !== this.img.width || this.assetData.h !== this.img.height)) {
       var canvas = createTag('canvas');
@@ -14431,7 +12276,6 @@
       var widthCrop;
       var heightCrop;
       var par = this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio;
-
       if (imgRel > canvasRel && par === 'xMidYMid slice' || imgRel < canvasRel && par !== 'xMidYMid slice') {
         heightCrop = imgH;
         widthCrop = heightCrop * canvasRel;
@@ -14439,16 +12283,13 @@
         widthCrop = imgW;
         heightCrop = widthCrop / canvasRel;
       }
-
       ctx.drawImage(this.img, (imgW - widthCrop) / 2, (imgH - heightCrop) / 2, widthCrop, heightCrop, 0, 0, this.assetData.w, this.assetData.h);
       this.img = canvas;
     }
   };
-
   CVImageElement.prototype.renderInnerContent = function () {
     this.canvasContext.drawImage(this.img, 0, 0);
   };
-
   CVImageElement.prototype.destroy = function () {
     this.img = null;
   };
@@ -14456,115 +12297,89 @@
   function CVSolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVSolidElement);
   CVSolidElement.prototype.initElement = SVGShapeElement.prototype.initElement;
   CVSolidElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
-
   CVSolidElement.prototype.renderInnerContent = function () {
     // var ctx = this.canvasContext;
-    this.globalData.renderer.ctxFillStyle(this.data.sc); // ctx.fillStyle = this.data.sc;
-
-    this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh); // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
+    this.globalData.renderer.ctxFillStyle(this.data.sc);
+    // ctx.fillStyle = this.data.sc;
+    this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh);
+    // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
     //
   };
 
   function CanvasRendererBase() {}
-
   extendPrototype([BaseRenderer], CanvasRendererBase);
-
   CanvasRendererBase.prototype.createShape = function (data) {
     return new CVShapeElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createText = function (data) {
     return new CVTextElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createImage = function (data) {
     return new CVImageElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createSolid = function (data) {
     return new CVSolidElement(data, this.globalData, this);
   };
-
   CanvasRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
-
   CanvasRendererBase.prototype.ctxTransform = function (props) {
     if (props[0] === 1 && props[1] === 0 && props[4] === 0 && props[5] === 1 && props[12] === 0 && props[13] === 0) {
       return;
     }
-
     this.canvasContext.transform(props[0], props[1], props[4], props[5], props[12], props[13]);
   };
-
   CanvasRendererBase.prototype.ctxOpacity = function (op) {
     this.canvasContext.globalAlpha *= op < 0 ? 0 : op;
   };
-
   CanvasRendererBase.prototype.ctxFillStyle = function (value) {
     this.canvasContext.fillStyle = value;
   };
-
   CanvasRendererBase.prototype.ctxStrokeStyle = function (value) {
     this.canvasContext.strokeStyle = value;
   };
-
   CanvasRendererBase.prototype.ctxLineWidth = function (value) {
     this.canvasContext.lineWidth = value;
   };
-
   CanvasRendererBase.prototype.ctxLineCap = function (value) {
     this.canvasContext.lineCap = value;
   };
-
   CanvasRendererBase.prototype.ctxLineJoin = function (value) {
     this.canvasContext.lineJoin = value;
   };
-
   CanvasRendererBase.prototype.ctxMiterLimit = function (value) {
     this.canvasContext.miterLimit = value;
   };
-
   CanvasRendererBase.prototype.ctxFill = function (rule) {
     this.canvasContext.fill(rule);
   };
-
   CanvasRendererBase.prototype.ctxFillRect = function (x, y, w, h) {
     this.canvasContext.fillRect(x, y, w, h);
   };
-
   CanvasRendererBase.prototype.ctxStroke = function () {
     this.canvasContext.stroke();
   };
-
   CanvasRendererBase.prototype.reset = function () {
     if (!this.renderConfig.clearCanvas) {
       this.canvasContext.restore();
       return;
     }
-
     this.contextData.reset();
   };
-
   CanvasRendererBase.prototype.save = function () {
     this.canvasContext.save();
   };
-
   CanvasRendererBase.prototype.restore = function (actionFlag) {
     if (!this.renderConfig.clearCanvas) {
       this.canvasContext.restore();
       return;
     }
-
     if (actionFlag) {
       this.globalData.blendMode = 'source-over';
     }
-
     this.contextData.restore(actionFlag);
   };
-
   CanvasRendererBase.prototype.configAnimation = function (animData) {
     if (this.animationItem.wrapper) {
       this.animationItem.container = createTag('canvas');
@@ -14579,18 +12394,15 @@
       containerStyle.contentVisibility = this.renderConfig.contentVisibility;
       this.animationItem.wrapper.appendChild(this.animationItem.container);
       this.canvasContext = this.animationItem.container.getContext('2d');
-
       if (this.renderConfig.className) {
         this.animationItem.container.setAttribute('class', this.renderConfig.className);
       }
-
       if (this.renderConfig.id) {
         this.animationItem.container.setAttribute('id', this.renderConfig.id);
       }
     } else {
       this.canvasContext = this.renderConfig.context;
     }
-
     this.contextData.setContext(this.canvasContext);
     this.data = animData;
     this.layers = animData.layers;
@@ -14611,12 +12423,10 @@
     this.elements = createSizedArray(animData.layers.length);
     this.updateContainerSize();
   };
-
   CanvasRendererBase.prototype.updateContainerSize = function (width, height) {
     this.reset();
     var elementWidth;
     var elementHeight;
-
     if (width) {
       elementWidth = width;
       elementHeight = height;
@@ -14630,14 +12440,11 @@
         elementWidth = this.canvasContext.canvas.width;
         elementHeight = this.canvasContext.canvas.height;
       }
-
       this.canvasContext.canvas.width = elementWidth * this.renderConfig.dpr;
       this.canvasContext.canvas.height = elementHeight * this.renderConfig.dpr;
     }
-
     var elementRel;
     var animationRel;
-
     if (this.renderConfig.preserveAspectRatio.indexOf('meet') !== -1 || this.renderConfig.preserveAspectRatio.indexOf('slice') !== -1) {
       var par = this.renderConfig.preserveAspectRatio.split(' ');
       var fillType = par[1] || 'meet';
@@ -14646,7 +12453,6 @@
       var yPos = pos.substr(4);
       elementRel = elementWidth / elementHeight;
       animationRel = this.transformCanvas.w / this.transformCanvas.h;
-
       if (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice') {
         this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
         this.transformCanvas.sy = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
@@ -14654,7 +12460,6 @@
         this.transformCanvas.sx = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
         this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
       }
-
       if (xPos === 'xMid' && (animationRel < elementRel && fillType === 'meet' || animationRel > elementRel && fillType === 'slice')) {
         this.transformCanvas.tx = (elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) / 2 * this.renderConfig.dpr;
       } else if (xPos === 'xMax' && (animationRel < elementRel && fillType === 'meet' || animationRel > elementRel && fillType === 'slice')) {
@@ -14662,7 +12467,6 @@
       } else {
         this.transformCanvas.tx = 0;
       }
-
       if (yPos === 'YMid' && (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice')) {
         this.transformCanvas.ty = (elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w)) / 2 * this.renderConfig.dpr;
       } else if (yPos === 'YMax' && (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice')) {
@@ -14681,7 +12485,6 @@
       this.transformCanvas.tx = 0;
       this.transformCanvas.ty = 0;
     }
-
     this.transformCanvas.props = [this.transformCanvas.sx, 0, 0, 0, 0, this.transformCanvas.sy, 0, 0, 0, 0, 1, 0, this.transformCanvas.tx, this.transformCanvas.ty, 0, 1];
     /* var i, len = this.elements.length;
       for(i=0;i<len;i+=1){
@@ -14689,7 +12492,6 @@
               this.elements[i].resize(this.globalData.transformCanvas);
           }
       } */
-
     this.ctxTransform(this.transformCanvas.props);
     this.canvasContext.beginPath();
     this.canvasContext.rect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
@@ -14697,78 +12499,65 @@
     this.canvasContext.clip();
     this.renderFrame(this.renderedFrame, true);
   };
-
   CanvasRendererBase.prototype.destroy = function () {
     if (this.renderConfig.clearCanvas && this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.globalData.canvasContext = null;
     this.animationItem.container = null;
     this.destroyed = true;
   };
-
   CanvasRendererBase.prototype.renderFrame = function (num, forceRender) {
     if (this.renderedFrame === num && this.renderConfig.clearCanvas === true && !forceRender || this.destroyed || num === -1) {
       return;
     }
-
     this.renderedFrame = num;
     this.globalData.frameNum = num - this.animationItem._isFirstFrame;
     this.globalData.frameId += 1;
     this.globalData._mdf = !this.renderConfig.clearCanvas || forceRender;
-    this.globalData.projectInterface.currentFrame = num; // console.log('--------');
-    // console.log('NEW: ',num);
+    this.globalData.projectInterface.currentFrame = num;
 
+    // console.log('--------');
+    // console.log('NEW: ',num);
     var i;
     var len = this.layers.length;
-
     if (!this.completeLayers) {
       this.checkLayers(num);
     }
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].prepareFrame(num - this.layers[i].st);
       }
     }
-
     if (this.globalData._mdf) {
       if (this.renderConfig.clearCanvas === true) {
         this.canvasContext.clearRect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
       } else {
         this.save();
       }
-
       for (i = len - 1; i >= 0; i -= 1) {
         if (this.completeLayers || this.elements[i]) {
           this.elements[i].renderFrame();
         }
       }
-
       if (this.renderConfig.clearCanvas !== true) {
         this.restore();
       }
     }
   };
-
   CanvasRendererBase.prototype.buildItem = function (pos) {
     var elements = this.elements;
-
     if (elements[pos] || this.layers[pos].ty === 99) {
       return;
     }
-
     var element = this.createItem(this.layers[pos], this, this.globalData);
     elements[pos] = element;
     element.initExpressions();
@@ -14776,18 +12565,15 @@
           element.resize(this.globalData.transformCanvas);
       } */
   };
-
   CanvasRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
     }
   };
-
   CanvasRendererBase.prototype.hide = function () {
     this.animationItem.container.style.display = 'none';
   };
-
   CanvasRendererBase.prototype.show = function () {
     this.animationItem.container.style.display = 'block';
   };
@@ -14803,71 +12589,61 @@
     this.miterLimit = '';
     this.id = Math.random();
   }
-
   function CVContextData() {
     this.stack = [];
     this.cArrPos = 0;
     this.cTr = new Matrix();
     var i;
     var len = 15;
-
     for (i = 0; i < len; i += 1) {
       var canvasContext = new CanvasContext();
       this.stack[i] = canvasContext;
     }
-
     this._length = len;
     this.nativeContext = null;
     this.transformMat = new Matrix();
-    this.currentOpacity = 1; //
-
+    this.currentOpacity = 1;
+    //
     this.currentFillStyle = '';
-    this.appliedFillStyle = ''; //
-
+    this.appliedFillStyle = '';
+    //
     this.currentStrokeStyle = '';
-    this.appliedStrokeStyle = ''; //
-
+    this.appliedStrokeStyle = '';
+    //
     this.currentLineWidth = '';
-    this.appliedLineWidth = ''; //
-
+    this.appliedLineWidth = '';
+    //
     this.currentLineCap = '';
-    this.appliedLineCap = ''; //
-
+    this.appliedLineCap = '';
+    //
     this.currentLineJoin = '';
-    this.appliedLineJoin = ''; //
-
+    this.appliedLineJoin = '';
+    //
     this.appliedMiterLimit = '';
     this.currentMiterLimit = '';
   }
-
   CVContextData.prototype.duplicate = function () {
     var newLength = this._length * 2;
     var i = 0;
-
     for (i = this._length; i < newLength; i += 1) {
       this.stack[i] = new CanvasContext();
     }
-
     this._length = newLength;
   };
-
   CVContextData.prototype.reset = function () {
     this.cArrPos = 0;
     this.cTr.reset();
     this.stack[this.cArrPos].opacity = 1;
   };
-
   CVContextData.prototype.restore = function (forceRestore) {
     this.cArrPos -= 1;
     var currentContext = this.stack[this.cArrPos];
     var transform = currentContext.transform;
     var i;
     var arr = this.cTr.props;
-
     for (i = 0; i < 16; i += 1) {
       arr[i] = transform[i];
     }
-
     if (forceRestore) {
       this.nativeContext.restore();
       var prevStack = this.stack[this.cArrPos + 1];
@@ -14878,14 +12654,11 @@
       this.appliedLineJoin = prevStack.lineJoin;
       this.appliedMiterLimit = prevStack.miterLimit;
     }
-
     this.nativeContext.setTransform(transform[0], transform[1], transform[4], transform[5], transform[12], transform[13]);
-
     if (forceRestore || currentContext.opacity !== -1 && this.currentOpacity !== currentContext.opacity) {
       this.nativeContext.globalAlpha = currentContext.opacity;
       this.currentOpacity = currentContext.opacity;
     }
-
     this.currentFillStyle = currentContext.fillStyle;
     this.currentStrokeStyle = currentContext.strokeStyle;
     this.currentLineWidth = currentContext.lineWidth;
@@ -14893,25 +12666,19 @@
     this.currentLineJoin = currentContext.lineJoin;
     this.currentMiterLimit = currentContext.miterLimit;
   };
-
   CVContextData.prototype.save = function (saveOnNativeFlag) {
     if (saveOnNativeFlag) {
       this.nativeContext.save();
     }
-
     var props = this.cTr.props;
-
     if (this._length <= this.cArrPos) {
       this.duplicate();
     }
-
     var currentStack = this.stack[this.cArrPos];
     var i;
-
     for (i = 0; i < 16; i += 1) {
       currentStack.transform[i] = props[i];
     }
-
     this.cArrPos += 1;
     var newStack = this.stack[this.cArrPos];
     newStack.opacity = currentStack.opacity;
@@ -14922,128 +12689,106 @@
     newStack.lineJoin = currentStack.lineJoin;
     newStack.miterLimit = currentStack.miterLimit;
   };
-
   CVContextData.prototype.setOpacity = function (value) {
     this.stack[this.cArrPos].opacity = value;
   };
-
   CVContextData.prototype.setContext = function (value) {
     this.nativeContext = value;
   };
-
   CVContextData.prototype.fillStyle = function (value) {
     if (this.stack[this.cArrPos].fillStyle !== value) {
       this.currentFillStyle = value;
       this.stack[this.cArrPos].fillStyle = value;
     }
   };
-
   CVContextData.prototype.strokeStyle = function (value) {
     if (this.stack[this.cArrPos].strokeStyle !== value) {
       this.currentStrokeStyle = value;
       this.stack[this.cArrPos].strokeStyle = value;
     }
   };
-
   CVContextData.prototype.lineWidth = function (value) {
     if (this.stack[this.cArrPos].lineWidth !== value) {
       this.currentLineWidth = value;
       this.stack[this.cArrPos].lineWidth = value;
     }
   };
-
   CVContextData.prototype.lineCap = function (value) {
     if (this.stack[this.cArrPos].lineCap !== value) {
       this.currentLineCap = value;
       this.stack[this.cArrPos].lineCap = value;
     }
   };
-
   CVContextData.prototype.lineJoin = function (value) {
     if (this.stack[this.cArrPos].lineJoin !== value) {
       this.currentLineJoin = value;
       this.stack[this.cArrPos].lineJoin = value;
     }
   };
-
   CVContextData.prototype.miterLimit = function (value) {
     if (this.stack[this.cArrPos].miterLimit !== value) {
       this.currentMiterLimit = value;
       this.stack[this.cArrPos].miterLimit = value;
     }
   };
-
   CVContextData.prototype.transform = function (props) {
-    this.transformMat.cloneFromProps(props); // Taking the last transform value from the stored stack of transforms
-
-    var currentTransform = this.cTr; // Applying the last transform value after the new transform to respect the order of transformations
-
-    this.transformMat.multiply(currentTransform); // Storing the new transformed value in the stored transform
-
+    this.transformMat.cloneFromProps(props);
+    // Taking the last transform value from the stored stack of transforms
+    var currentTransform = this.cTr;
+    // Applying the last transform value after the new transform to respect the order of transformations
+    this.transformMat.multiply(currentTransform);
+    // Storing the new transformed value in the stored transform
     currentTransform.cloneFromProps(this.transformMat.props);
-    var trProps = currentTransform.props; // Applying the new transform to the canvas
-
+    var trProps = currentTransform.props;
+    // Applying the new transform to the canvas
     this.nativeContext.setTransform(trProps[0], trProps[1], trProps[4], trProps[5], trProps[12], trProps[13]);
   };
-
   CVContextData.prototype.opacity = function (op) {
     var currentOpacity = this.stack[this.cArrPos].opacity;
     currentOpacity *= op < 0 ? 0 : op;
-
     if (this.stack[this.cArrPos].opacity !== currentOpacity) {
       if (this.currentOpacity !== op) {
         this.nativeContext.globalAlpha = op;
         this.currentOpacity = op;
       }
-
       this.stack[this.cArrPos].opacity = currentOpacity;
     }
   };
-
   CVContextData.prototype.fill = function (rule) {
     if (this.appliedFillStyle !== this.currentFillStyle) {
       this.appliedFillStyle = this.currentFillStyle;
       this.nativeContext.fillStyle = this.appliedFillStyle;
     }
-
     this.nativeContext.fill(rule);
   };
-
   CVContextData.prototype.fillRect = function (x, y, w, h) {
     if (this.appliedFillStyle !== this.currentFillStyle) {
       this.appliedFillStyle = this.currentFillStyle;
       this.nativeContext.fillStyle = this.appliedFillStyle;
     }
-
     this.nativeContext.fillRect(x, y, w, h);
   };
-
   CVContextData.prototype.stroke = function () {
     if (this.appliedStrokeStyle !== this.currentStrokeStyle) {
       this.appliedStrokeStyle = this.currentStrokeStyle;
       this.nativeContext.strokeStyle = this.appliedStrokeStyle;
     }
-
     if (this.appliedLineWidth !== this.currentLineWidth) {
       this.appliedLineWidth = this.currentLineWidth;
       this.nativeContext.lineWidth = this.appliedLineWidth;
     }
-
     if (this.appliedLineCap !== this.currentLineCap) {
       this.appliedLineCap = this.currentLineCap;
       this.nativeContext.lineCap = this.appliedLineCap;
     }
-
     if (this.appliedLineJoin !== this.currentLineJoin) {
       this.appliedLineJoin = this.currentLineJoin;
       this.nativeContext.lineJoin = this.appliedLineJoin;
     }
-
     if (this.appliedMiterLimit !== this.currentMiterLimit) {
       this.appliedMiterLimit = this.currentMiterLimit;
       this.nativeContext.miterLimit = this.appliedMiterLimit;
     }
-
     this.nativeContext.stroke();
   };
 
@@ -15057,9 +12802,7 @@
       _placeholder: true
     };
   }
-
   extendPrototype([CanvasRendererBase, ICompElement, CVBaseElement], CVCompElement);
-
   CVCompElement.prototype.renderInnerContent = function () {
     var ctx = this.canvasContext;
     ctx.beginPath();
@@ -15071,28 +12814,23 @@
     ctx.clip();
     var i;
     var len = this.layers.length;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.completeLayers || this.elements[i]) {
         this.elements[i].renderFrame();
       }
     }
   };
-
   CVCompElement.prototype.destroy = function () {
     var i;
     var len = this.layers.length;
-
     for (i = len - 1; i >= 0; i -= 1) {
       if (this.elements[i]) {
         this.elements[i].destroy();
       }
     }
-
     this.layers = null;
     this.elements = null;
   };
-
   CVCompElement.prototype.createComp = function (data) {
     return new CVCompElement(data, this.globalData, this);
   };
@@ -15111,11 +12849,9 @@
       runExpressions: !config || config.runExpressions === undefined || config.runExpressions
     };
     this.renderConfig.dpr = config && config.dpr || 1;
-
     if (this.animationItem.wrapper) {
       this.renderConfig.dpr = config && config.dpr || window.devicePixelRatio || 1;
     }
-
     this.renderedFrame = -1;
     this.globalData = {
       frameNum: -1,
@@ -15129,7 +12865,6 @@
     this.transformMat = new Matrix();
     this.completeLayers = false;
     this.rendererType = 'canvas';
-
     if (this.renderConfig.clearCanvas) {
       this.ctxTransform = this.contextData.transform.bind(this.contextData);
       this.ctxOpacity = this.contextData.opacity.bind(this.contextData);
@@ -15145,20 +12880,16 @@
       this.save = this.contextData.save.bind(this.contextData);
     }
   }
-
   extendPrototype([CanvasRendererBase], CanvasRenderer);
-
   CanvasRenderer.prototype.createComp = function (data) {
     return new CVCompElement(data, this.globalData, this);
   };
 
   function HBaseElement() {}
-
   HBaseElement.prototype = {
     checkBlendMode: function checkBlendMode() {},
     initRendererElement: function initRendererElement() {
       this.baseElement = createTag(this.data.tg || 'div');
-
       if (this.data.hasMask) {
         this.svgElement = createNS('svg');
         this.layerElement = createNS('g');
@@ -15168,35 +12899,29 @@
       } else {
         this.layerElement = this.baseElement;
       }
-
       styleDiv(this.baseElement);
     },
     createContainerElements: function createContainerElements() {
       this.renderableEffectsManager = new CVEffects(this);
       this.transformedElement = this.baseElement;
       this.maskedElement = this.layerElement;
-
       if (this.data.ln) {
         this.layerElement.setAttribute('id', this.data.ln);
       }
-
       if (this.data.cl) {
         this.layerElement.setAttribute('class', this.data.cl);
       }
-
       if (this.data.bm !== 0) {
         this.setBlendMode();
       }
     },
     renderElement: function renderElement() {
       var transformedElementStyle = this.transformedElement ? this.transformedElement.style : {};
-
       if (this.finalTransform._matMdf) {
         var matrixValue = this.finalTransform.mat.toCSS();
         transformedElementStyle.transform = matrixValue;
         transformedElementStyle.webkitTransform = matrixValue;
       }
-
       if (this.finalTransform._opMdf) {
         transformedElementStyle.opacity = this.finalTransform.mProp.o.v;
       }
@@ -15207,12 +12932,10 @@
       if (this.data.hd || this.hidden) {
         return;
       }
-
       this.renderTransform();
       this.renderRenderable();
       this.renderElement();
       this.renderInnerContent();
-
       if (this._isFirstFrame) {
         this._isFirstFrame = false;
       }
@@ -15220,11 +12943,9 @@
     destroy: function destroy() {
       this.layerElement = null;
       this.transformedElement = null;
-
       if (this.matteElement) {
         this.matteElement = null;
       }
-
       if (this.maskManager) {
         this.maskManager.destroy();
         this.maskManager = null;
@@ -15243,12 +12964,9 @@
   function HSolidElement(data, globalData, comp) {
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], HSolidElement);
-
   HSolidElement.prototype.createContent = function () {
     var rect;
-
     if (this.data.hasMask) {
       rect = createNS('rect');
       rect.setAttribute('width', this.data.sw);
@@ -15262,29 +12980,28 @@
       rect.style.height = this.data.sh + 'px';
       rect.style.backgroundColor = this.data.sc;
     }
-
     this.layerElement.appendChild(rect);
   };
 
   function HShapeElement(data, globalData, comp) {
     // List of drawable elements
-    this.shapes = []; // Full shape data
-
-    this.shapesData = data.shapes; // List of styles that will be applied to shapes
-
-    this.stylesList = []; // List of modifiers that will be applied to shapes
-
-    this.shapeModifiers = []; // List of items in shape tree
-
-    this.itemsData = []; // List of items in previous shape tree
-
-    this.processedElements = []; // List of animated components
-
+    this.shapes = [];
+    // Full shape data
+    this.shapesData = data.shapes;
+    // List of styles that will be applied to shapes
+    this.stylesList = [];
+    // List of modifiers that will be applied to shapes
+    this.shapeModifiers = [];
+    // List of items in shape tree
+    this.itemsData = [];
+    // List of items in previous shape tree
+    this.processedElements = [];
+    // List of animated components
     this.animatedContents = [];
     this.shapesContainer = createNS('g');
-    this.initElement(data, globalData, comp); // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
+    this.initElement(data, globalData, comp);
+    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
     // List of elements that have been created
-
     this.prevViewData = [];
     this.currentBBox = {
       x: 999999,
@@ -15293,14 +13010,11 @@
       w: 0
     };
   }
-
   extendPrototype([BaseElement, TransformElement, HSolidElement, SVGShapeElement, HBaseElement, HierarchyElement, FrameElement, RenderableElement], HShapeElement);
   HShapeElement.prototype._renderShapeFrame = HShapeElement.prototype.renderInnerContent;
-
   HShapeElement.prototype.createContent = function () {
     var cont;
     this.baseElement.style.fontSize = 0;
-
     if (this.data.hasMask) {
       this.layerElement.appendChild(this.shapesContainer);
       cont = this.svgElement;
@@ -15312,23 +13026,18 @@
       cont.appendChild(this.shapesContainer);
       this.layerElement.appendChild(cont);
     }
-
     this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.shapesContainer, 0, [], true);
     this.filterUniqueShapes();
     this.shapeCont = cont;
   };
-
   HShapeElement.prototype.getTransformedPoint = function (transformers, point) {
     var i;
     var len = transformers.length;
-
     for (i = 0; i < len; i += 1) {
       point = transformers[i].mProps.v.applyToPointArray(point[0], point[1], 0);
     }
-
     return point;
   };
-
   HShapeElement.prototype.calculateShapeBoundingBox = function (item, boundingBox) {
     var shape = item.sh.v;
     var transformers = item.transformers;
@@ -15338,11 +13047,9 @@
     var oPoint;
     var nextIPoint;
     var nextVPoint;
-
     if (len <= 1) {
       return;
     }
-
     for (i = 0; i < len - 1; i += 1) {
       vPoint = this.getTransformedPoint(transformers, shape.v[i]);
       oPoint = this.getTransformedPoint(transformers, shape.o[i]);
@@ -15350,7 +13057,6 @@
       nextVPoint = this.getTransformedPoint(transformers, shape.v[i + 1]);
       this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
     }
-
     if (shape.c) {
       vPoint = this.getTransformedPoint(transformers, shape.v[i]);
       oPoint = this.getTransformedPoint(transformers, shape.o[i]);
@@ -15359,7 +13065,6 @@
       this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
     }
   };
-
   HShapeElement.prototype.checkBounds = function (vPoint, oPoint, nextIPoint, nextVPoint, boundingBox) {
     this.getBoundsOfCurve(vPoint, oPoint, nextIPoint, nextVPoint);
     var bounds = this.shapeBoundingBox;
@@ -15368,7 +13073,6 @@
     boundingBox.y = bmMin(bounds.top, boundingBox.y);
     boundingBox.yMax = bmMax(bounds.bottom, boundingBox.yMax);
   };
-
   HShapeElement.prototype.shapeBoundingBox = {
     left: 0,
     right: 0,
@@ -15383,31 +13087,26 @@
     width: 0,
     height: 0
   };
-
   HShapeElement.prototype.getBoundsOfCurve = function (p0, p1, p2, p3) {
     var bounds = [[p0[0], p3[0]], [p0[1], p3[1]]];
-
     for (var a, b, c, t, b2ac, t1, t2, i = 0; i < 2; ++i) {
       // eslint-disable-line no-plusplus
       b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];
       a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];
       c = 3 * p1[i] - 3 * p0[i];
       b |= 0; // eslint-disable-line no-bitwise
-
       a |= 0; // eslint-disable-line no-bitwise
-
       c |= 0; // eslint-disable-line no-bitwise
 
-      if (a === 0 && b === 0) {//
+      if (a === 0 && b === 0) {
+        //
       } else if (a === 0) {
         t = -c / b;
-
         if (t > 0 && t < 1) {
           bounds[i].push(this.calculateF(t, p0, p1, p2, p3, i));
         }
       } else {
         b2ac = b * b - 4 * c * a;
-
         if (b2ac >= 0) {
           t1 = (-b + bmSqrt(b2ac)) / (2 * a);
           if (t1 > 0 && t1 < 1) bounds[i].push(this.calculateF(t1, p0, p1, p2, p3, i));
@@ -15416,21 +13115,17 @@
         }
       }
     }
-
     this.shapeBoundingBox.left = bmMin.apply(null, bounds[0]);
     this.shapeBoundingBox.top = bmMin.apply(null, bounds[1]);
     this.shapeBoundingBox.right = bmMax.apply(null, bounds[0]);
     this.shapeBoundingBox.bottom = bmMax.apply(null, bounds[1]);
   };
-
   HShapeElement.prototype.calculateF = function (t, p0, p1, p2, p3, i) {
     return bmPow(1 - t, 3) * p0[i] + 3 * bmPow(1 - t, 2) * t * p1[i] + 3 * (1 - t) * bmPow(t, 2) * p2[i] + bmPow(t, 3) * p3[i];
   };
-
   HShapeElement.prototype.calculateBoundingBox = function (itemsData, boundingBox) {
     var i;
     var len = itemsData.length;
-
     for (i = 0; i < len; i += 1) {
       if (itemsData[i] && itemsData[i].sh) {
         this.calculateShapeBoundingBox(itemsData[i], boundingBox);
@@ -15441,37 +13136,29 @@
       }
     }
   };
-
   HShapeElement.prototype.expandStrokeBoundingBox = function (widthProperty, boundingBox) {
     var width = 0;
-
     if (widthProperty.keyframes) {
       for (var i = 0; i < widthProperty.keyframes.length; i += 1) {
         var kfw = widthProperty.keyframes[i].s;
-
         if (kfw > width) {
           width = kfw;
         }
       }
-
       width *= widthProperty.mult;
     } else {
       width = widthProperty.v * widthProperty.mult;
     }
-
     boundingBox.x -= width;
     boundingBox.xMax += width;
     boundingBox.y -= width;
     boundingBox.yMax += width;
   };
-
   HShapeElement.prototype.currentBoxContains = function (box) {
     return this.currentBBox.x <= box.x && this.currentBBox.y <= box.y && this.currentBBox.width + this.currentBBox.x >= box.x + box.width && this.currentBBox.height + this.currentBBox.y >= box.y + box.height;
   };
-
   HShapeElement.prototype.renderInnerContent = function () {
     this._renderShapeFrame();
-
     if (!this.hidden && (this._isFirstFrame || this._mdf)) {
       var tempBoundingBox = this.tempBoundingBox;
       var max = 999999;
@@ -15481,26 +13168,22 @@
       tempBoundingBox.yMax = -max;
       this.calculateBoundingBox(this.itemsData, tempBoundingBox);
       tempBoundingBox.width = tempBoundingBox.xMax < tempBoundingBox.x ? 0 : tempBoundingBox.xMax - tempBoundingBox.x;
-      tempBoundingBox.height = tempBoundingBox.yMax < tempBoundingBox.y ? 0 : tempBoundingBox.yMax - tempBoundingBox.y; // var tempBoundingBox = this.shapeCont.getBBox();
-
+      tempBoundingBox.height = tempBoundingBox.yMax < tempBoundingBox.y ? 0 : tempBoundingBox.yMax - tempBoundingBox.y;
+      // var tempBoundingBox = this.shapeCont.getBBox();
       if (this.currentBoxContains(tempBoundingBox)) {
         return;
       }
-
       var changed = false;
-
       if (this.currentBBox.w !== tempBoundingBox.width) {
         this.currentBBox.w = tempBoundingBox.width;
         this.shapeCont.setAttribute('width', tempBoundingBox.width);
         changed = true;
       }
-
       if (this.currentBBox.h !== tempBoundingBox.height) {
         this.currentBBox.h = tempBoundingBox.height;
         this.shapeCont.setAttribute('height', tempBoundingBox.height);
         changed = true;
       }
-
       if (changed || this.currentBBox.x !== tempBoundingBox.x || this.currentBBox.y !== tempBoundingBox.y) {
         this.currentBBox.w = tempBoundingBox.width;
         this.currentBBox.h = tempBoundingBox.height;
@@ -15528,12 +13211,9 @@
     this.isMasked = false;
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], HTextElement);
-
   HTextElement.prototype.createContent = function () {
     this.isMasked = this.checkMasks();
-
     if (this.isMasked) {
       this.renderType = 'svg';
       this.compW = this.comp.data.w;
@@ -15547,10 +13227,8 @@
       this.renderType = 'html';
       this.innerElem = this.layerElement;
     }
-
     this.checkParenting();
   };
-
   HTextElement.prototype.buildNewText = function () {
     var documentData = this.textProperty.currentData;
     this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
@@ -15558,18 +13236,14 @@
     var textColor = documentData.fc ? this.buildColor(documentData.fc) : 'rgba(0,0,0,0)';
     innerElemStyle.fill = textColor;
     innerElemStyle.color = textColor;
-
     if (documentData.sc) {
       innerElemStyle.stroke = this.buildColor(documentData.sc);
       innerElemStyle.strokeWidth = documentData.sw + 'px';
     }
-
     var fontData = this.globalData.fontManager.getFontByName(documentData.f);
-
     if (!this.globalData.fontManager.chars) {
       innerElemStyle.fontSize = documentData.finalSize + 'px';
       innerElemStyle.lineHeight = documentData.finalSize + 'px';
-
       if (fontData.fClass) {
         this.innerElem.className = fontData.fClass;
       } else {
@@ -15580,7 +13254,6 @@
         innerElemStyle.fontWeight = fWeight;
       }
     }
-
     var i;
     var len;
     var letters = documentData.l;
@@ -15592,7 +13265,6 @@
     var shapes;
     var shapeStr = '';
     var cnt = 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.globalData.fontManager.chars) {
         if (!this.textPaths[cnt]) {
@@ -15603,7 +13275,6 @@
         } else {
           tSpan = this.textPaths[cnt];
         }
-
         if (!this.isMasked) {
           if (this.textSpans[cnt]) {
             tParent = this.textSpans[cnt];
@@ -15629,31 +13300,25 @@
         }
       } else {
         tSpan = this.textPaths[cnt] ? this.textPaths[cnt] : createNS('text');
-      } // tSpan.setAttribute('visibility', 'hidden');
-
-
+      }
+      // tSpan.setAttribute('visibility', 'hidden');
       if (this.globalData.fontManager.chars) {
         var charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
         var shapeData;
-
         if (charData) {
           shapeData = charData.data;
         } else {
           shapeData = null;
         }
-
         matrixHelper.reset();
-
         if (shapeData && shapeData.shapes && shapeData.shapes.length) {
           shapes = shapeData.shapes[0].it;
           matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
           shapeStr = this.createPathShape(matrixHelper, shapes);
           tSpan.setAttribute('d', shapeStr);
         }
-
         if (!this.isMasked) {
           this.innerElem.appendChild(tParent);
-
           if (shapeData && shapeData.shapes) {
             // document.body.appendChild is needed to get exact measure of shape
             document.body.appendChild(tCont);
@@ -15670,7 +13335,6 @@
             tCont.setAttribute('width', 1);
             tCont.setAttribute('height', 1);
           }
-
           tParent.appendChild(tCont);
         } else {
           this.innerElem.appendChild(tSpan);
@@ -15678,10 +13342,9 @@
       } else {
         tSpan.textContent = letters[i].val;
         tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
-
         if (!this.isMasked) {
-          this.innerElem.appendChild(tParent); //
-
+          this.innerElem.appendChild(tParent);
+          //
           var tStyle = tSpan.style;
           var tSpanTranslation = 'translate3d(0,' + -documentData.finalSize / 1.2 + 'px,0)';
           tStyle.transform = tSpanTranslation;
@@ -15689,35 +13352,29 @@
         } else {
           this.innerElem.appendChild(tSpan);
         }
-      } //
-
-
+      }
+      //
       if (!this.isMasked) {
         this.textSpans[cnt] = tParent;
       } else {
         this.textSpans[cnt] = tSpan;
       }
-
       this.textSpans[cnt].style.display = 'block';
       this.textPaths[cnt] = tSpan;
       cnt += 1;
     }
-
     while (cnt < this.textSpans.length) {
       this.textSpans[cnt].style.display = 'none';
       cnt += 1;
     }
   };
-
   HTextElement.prototype.renderInnerContent = function () {
     this.validateText();
     var svgStyle;
-
     if (this.data.singleShape) {
       if (!this._isFirstFrame && !this.lettersChangedFlag) {
         return;
       }
-
       if (this.isMasked && this.finalTransform._matMdf) {
         // Todo Benchmark if using this is better than getBBox
         this.svgElement.setAttribute('viewBox', -this.finalTransform.mProp.p.v[0] + ' ' + -this.finalTransform.mProp.p.v[1] + ' ' + this.compW + ' ' + this.compH);
@@ -15727,13 +13384,10 @@
         svgStyle.webkitTransform = translation;
       }
     }
-
     this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
-
     if (!this.lettersChangedFlag && !this.textAnimator.lettersChangedFlag) {
       return;
     }
-
     var i;
     var len;
     var count = 0;
@@ -15743,7 +13397,6 @@
     var renderedLetter;
     var textSpan;
     var textPath;
-
     for (i = 0; i < len; i += 1) {
       if (letters[i].n) {
         count += 1;
@@ -15752,7 +13405,6 @@
         textPath = this.textPaths[i];
         renderedLetter = renderedLetters[count];
         count += 1;
-
         if (renderedLetter._mdf.m) {
           if (!this.isMasked) {
             textSpan.style.webkitTransform = renderedLetter.m;
@@ -15760,41 +13412,32 @@
           } else {
             textSpan.setAttribute('transform', renderedLetter.m);
           }
-        } /// /textSpan.setAttribute('opacity',renderedLetter.o);
-
-
+        }
+        /// /textSpan.setAttribute('opacity',renderedLetter.o);
         textSpan.style.opacity = renderedLetter.o;
-
         if (renderedLetter.sw && renderedLetter._mdf.sw) {
           textPath.setAttribute('stroke-width', renderedLetter.sw);
         }
-
         if (renderedLetter.sc && renderedLetter._mdf.sc) {
           textPath.setAttribute('stroke', renderedLetter.sc);
         }
-
         if (renderedLetter.fc && renderedLetter._mdf.fc) {
           textPath.setAttribute('fill', renderedLetter.fc);
           textPath.style.color = renderedLetter.fc;
         }
       }
     }
-
     if (this.innerElem.getBBox && !this.hidden && (this._isFirstFrame || this._mdf)) {
       var boundingBox = this.innerElem.getBBox();
-
       if (this.currentBBox.w !== boundingBox.width) {
         this.currentBBox.w = boundingBox.width;
         this.svgElement.setAttribute('width', boundingBox.width);
       }
-
       if (this.currentBBox.h !== boundingBox.height) {
         this.currentBBox.h = boundingBox.height;
         this.svgElement.setAttribute('height', boundingBox.height);
       }
-
       var margin = 1;
-
       if (this.currentBBox.w !== boundingBox.width + margin * 2 || this.currentBBox.h !== boundingBox.height + margin * 2 || this.currentBBox.x !== boundingBox.x - margin || this.currentBBox.y !== boundingBox.y - margin) {
         this.currentBBox.w = boundingBox.width + margin * 2;
         this.currentBBox.h = boundingBox.height + margin * 2;
@@ -15815,7 +13458,6 @@
     this.initHierarchy();
     var getProp = PropertyFactory.getProp;
     this.pe = getProp(this, data.pe, 0, 0, this);
-
     if (data.ks.p.s) {
       this.px = getProp(this, data.ks.p.x, 1, 0, this);
       this.py = getProp(this, data.ks.p.y, 1, 0, this);
@@ -15823,21 +13465,17 @@
     } else {
       this.p = getProp(this, data.ks.p, 1, 0, this);
     }
-
     if (data.ks.a) {
       this.a = getProp(this, data.ks.a, 1, 0, this);
     }
-
     if (data.ks.or.k.length && data.ks.or.k[0].to) {
       var i;
       var len = data.ks.or.k.length;
-
       for (i = 0; i < len; i += 1) {
         data.ks.or.k[i].to = null;
         data.ks.or.k[i].ti = null;
       }
     }
-
     this.or = getProp(this, data.ks.or, 1, degToRads, this);
     this.or.sh = true;
     this.rx = getProp(this, data.ks.rx, 0, degToRads, this);
@@ -15845,26 +13483,23 @@
     this.rz = getProp(this, data.ks.rz, 0, degToRads, this);
     this.mat = new Matrix();
     this._prevMat = new Matrix();
-    this._isFirstFrame = true; // TODO: find a better way to make the HCamera element to be compatible with the LayerInterface and TransformInterface.
+    this._isFirstFrame = true;
 
+    // TODO: find a better way to make the HCamera element to be compatible with the LayerInterface and TransformInterface.
     this.finalTransform = {
       mProp: this
     };
   }
-
   extendPrototype([BaseElement, FrameElement, HierarchyElement], HCameraElement);
-
   HCameraElement.prototype.setup = function () {
     var i;
     var len = this.comp.threeDElements.length;
     var comp;
     var perspectiveStyle;
     var containerStyle;
-
     for (i = 0; i < len; i += 1) {
       // [perspectiveElem,container]
       comp = this.comp.threeDElements[i];
-
       if (comp.type === '3d') {
         perspectiveStyle = comp.perspectiveElem.style;
         containerStyle = comp.container.style;
@@ -15881,30 +13516,22 @@
       }
     }
   };
-
   HCameraElement.prototype.createElements = function () {};
-
   HCameraElement.prototype.hide = function () {};
-
   HCameraElement.prototype.renderFrame = function () {
     var _mdf = this._isFirstFrame;
     var i;
     var len;
-
     if (this.hierarchy) {
       len = this.hierarchy.length;
-
       for (i = 0; i < len; i += 1) {
         _mdf = this.hierarchy[i].finalTransform.mProp._mdf || _mdf;
       }
     }
-
     if (_mdf || this.pe._mdf || this.p && this.p._mdf || this.px && (this.px._mdf || this.py._mdf || this.pz._mdf) || this.rx._mdf || this.ry._mdf || this.rz._mdf || this.or._mdf || this.a && this.a._mdf) {
       this.mat.reset();
-
       if (this.hierarchy) {
         len = this.hierarchy.length - 1;
-
         for (i = len; i >= 0; i -= 1) {
           var mTransf = this.hierarchy[i].finalTransform.mProp;
           this.mat.translate(-mTransf.p.v[0], -mTransf.p.v[1], mTransf.p.v[2]);
@@ -15914,46 +13541,38 @@
           this.mat.translate(mTransf.a.v[0], mTransf.a.v[1], mTransf.a.v[2]);
         }
       }
-
       if (this.p) {
         this.mat.translate(-this.p.v[0], -this.p.v[1], this.p.v[2]);
       } else {
         this.mat.translate(-this.px.v, -this.py.v, this.pz.v);
       }
-
       if (this.a) {
         var diffVector;
-
         if (this.p) {
           diffVector = [this.p.v[0] - this.a.v[0], this.p.v[1] - this.a.v[1], this.p.v[2] - this.a.v[2]];
         } else {
           diffVector = [this.px.v - this.a.v[0], this.py.v - this.a.v[1], this.pz.v - this.a.v[2]];
         }
-
-        var mag = Math.sqrt(Math.pow(diffVector[0], 2) + Math.pow(diffVector[1], 2) + Math.pow(diffVector[2], 2)); // var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
-
+        var mag = Math.sqrt(Math.pow(diffVector[0], 2) + Math.pow(diffVector[1], 2) + Math.pow(diffVector[2], 2));
+        // var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
         var lookDir = [diffVector[0] / mag, diffVector[1] / mag, diffVector[2] / mag];
         var lookLengthOnXZ = Math.sqrt(lookDir[2] * lookDir[2] + lookDir[0] * lookDir[0]);
         var mRotationX = Math.atan2(lookDir[1], lookLengthOnXZ);
         var mRotationY = Math.atan2(lookDir[0], -lookDir[2]);
         this.mat.rotateY(mRotationY).rotateX(-mRotationX);
       }
-
       this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v);
       this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]);
       this.mat.translate(this.globalData.compSize.w / 2, this.globalData.compSize.h / 2, 0);
       this.mat.translate(0, 0, this.pe.v);
       var hasMatrixChanged = !this._prevMat.equals(this.mat);
-
       if ((hasMatrixChanged || this.pe._mdf) && this.comp.threeDElements) {
         len = this.comp.threeDElements.length;
         var comp;
         var perspectiveStyle;
         var containerStyle;
-
         for (i = 0; i < len; i += 1) {
           comp = this.comp.threeDElements[i];
-
           if (comp.type === '3d') {
             if (hasMatrixChanged) {
               var matValue = this.mat.toCSS();
@@ -15961,7 +13580,6 @@
               containerStyle.transform = matValue;
               containerStyle.webkitTransform = matValue;
             }
-
             if (this.pe._mdf) {
               perspectiveStyle = comp.perspectiveElem.style;
               perspectiveStyle.perspective = this.pe.v + 'px';
@@ -15969,20 +13587,15 @@
             }
           }
         }
-
         this.mat.clone(this._prevMat);
       }
     }
-
     this._isFirstFrame = false;
   };
-
   HCameraElement.prototype.prepareFrame = function (num) {
     this.prepareProperties(num, true);
   };
-
   HCameraElement.prototype.destroy = function () {};
-
   HCameraElement.prototype.getBaseElement = function () {
     return null;
   };
@@ -15991,13 +13604,10 @@
     this.assetData = globalData.getAssetData(data.refId);
     this.initElement(data, globalData, comp);
   }
-
   extendPrototype([BaseElement, TransformElement, HBaseElement, HSolidElement, HierarchyElement, FrameElement, RenderableElement], HImageElement);
-
   HImageElement.prototype.createContent = function () {
     var assetPath = this.globalData.getAssetsPath(this.assetData);
     var img = new Image();
-
     if (this.data.hasMask) {
       this.imageElem = createNS('image');
       this.imageElem.setAttribute('width', this.assetData.w + 'px');
@@ -16009,10 +13619,8 @@
     } else {
       this.layerElement.appendChild(img);
     }
-
     img.crossOrigin = 'anonymous';
     img.src = assetPath;
-
     if (this.data.ln) {
       this.baseElement.setAttribute('id', this.data.ln);
     }
@@ -16046,26 +13654,20 @@
     this.supports3d = true;
     this.rendererType = 'html';
   }
-
   extendPrototype([BaseRenderer], HybridRendererBase);
   HybridRendererBase.prototype.buildItem = SVGRenderer.prototype.buildItem;
-
   HybridRendererBase.prototype.checkPendingElements = function () {
     while (this.pendingElements.length) {
       var element = this.pendingElements.pop();
       element.checkParenting();
     }
   };
-
   HybridRendererBase.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);
@@ -16074,17 +13676,14 @@
         var nextDOMElement;
         var nextLayer;
         var 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);
@@ -16097,61 +13696,46 @@
       this.addTo3dContainer(newDOMElement, pos);
     }
   };
-
   HybridRendererBase.prototype.createShape = function (data) {
     if (!this.supports3d) {
       return new SVGShapeElement(data, this.globalData, this);
     }
-
     return new HShapeElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createText = function (data) {
     if (!this.supports3d) {
       return new SVGTextLottieElement(data, this.globalData, this);
     }
-
     return new HTextElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createCamera = function (data) {
     this.camera = new HCameraElement(data, this.globalData, this);
     return this.camera;
   };
-
   HybridRendererBase.prototype.createImage = function (data) {
     if (!this.supports3d) {
       return new IImageElement(data, this.globalData, this);
     }
-
     return new HImageElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createSolid = function (data) {
     if (!this.supports3d) {
       return new ISolidElement(data, this.globalData, this);
     }
-
     return new HSolidElement(data, this.globalData, this);
   };
-
   HybridRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
-
   HybridRendererBase.prototype.getThreeDContainerByPos = function (pos) {
     var i = 0;
     var 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;
     }
-
     return null;
   };
-
   HybridRendererBase.prototype.createThreeDContainer = function (pos, type) {
     var perspectiveElem = createTag('div');
     var style;
@@ -16159,7 +13743,6 @@
     styleDiv(perspectiveElem);
     var container = createTag('div');
     styleDiv(container);
-
     if (type === '3d') {
       style = perspectiveElem.style;
       style.width = this.globalData.compSize.w + 'px';
@@ -16173,9 +13756,8 @@
       containerStyle.transform = matrix;
       containerStyle.webkitTransform = matrix;
     }
-
-    perspectiveElem.appendChild(container); // this.resizerElem.appendChild(perspectiveElem);
-
+    perspectiveElem.appendChild(container);
+    // this.resizerElem.appendChild(perspectiveElem);
     var threeDContainerData = {
       container: container,
       perspectiveElem: perspectiveElem,
@@ -16186,68 +13768,54 @@
     this.threeDElements.push(threeDContainerData);
     return threeDContainerData;
   };
-
   HybridRendererBase.prototype.build3dContainers = function () {
     var i;
     var 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 -= 1) {
       this.resizerElem.appendChild(this.threeDElements[i].perspectiveElem);
     }
   };
-
   HybridRendererBase.prototype.addTo3dContainer = function (elem, pos) {
     var i = 0;
     var 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;
     }
   };
-
   HybridRendererBase.prototype.configAnimation = function (animData) {
     var resizerElem = createTag('div');
     var wrapper = this.animationItem.wrapper;
@@ -16259,11 +13827,9 @@
     style.transformStyle = 'flat';
     style.mozTransformStyle = 'flat';
     style.webkitTransformStyle = 'flat';
-
     if (this.renderConfig.className) {
       resizerElem.setAttribute('class', this.renderConfig.className);
     }
-
     wrapper.appendChild(resizerElem);
     style.overflow = 'hidden';
     var svg = createNS('svg');
@@ -16273,8 +13839,8 @@
     this.resizerElem.appendChild(svg);
     var defs = createNS('defs');
     svg.appendChild(defs);
-    this.data = animData; // Mask animation
-
+    this.data = animData;
+    // Mask animation
     this.setupGlobalData(animData, svg);
     this.globalData.defs = defs;
     this.layers = animData.layers;
@@ -16282,28 +13848,23 @@
     this.build3dContainers();
     this.updateContainerSize();
   };
-
   HybridRendererBase.prototype.destroy = function () {
     if (this.animationItem.wrapper) {
       this.animationItem.wrapper.innerText = '';
     }
-
     this.animationItem.container = null;
     this.globalData.defs = null;
     var i;
     var len = this.layers ? this.layers.length : 0;
-
     for (i = 0; i < len; i += 1) {
       if (this.elements[i] && this.elements[i].destroy) {
         this.elements[i].destroy();
       }
     }
-
     this.elements.length = 0;
     this.destroyed = true;
     this.animationItem = null;
   };
-
   HybridRendererBase.prototype.updateContainerSize = function () {
     var elementWidth = this.animationItem.wrapper.offsetWidth;
     var elementHeight = this.animationItem.wrapper.offsetHeight;
@@ -16313,7 +13874,6 @@
     var sy;
     var tx;
     var ty;
-
     if (animationRel > elementRel) {
       sx = elementWidth / this.globalData.compSize.w;
       sy = elementWidth / this.globalData.compSize.w;
@@ -16325,25 +13885,19 @@
       tx = (elementWidth - this.globalData.compSize.w * (elementHeight / this.globalData.compSize.h)) / 2;
       ty = 0;
     }
-
     var style = this.resizerElem.style;
     style.webkitTransform = 'matrix3d(' + sx + ',0,0,0,0,' + sy + ',0,0,0,0,1,0,' + tx + ',' + ty + ',0,1)';
     style.transform = style.webkitTransform;
   };
-
   HybridRendererBase.prototype.renderFrame = SVGRenderer.prototype.renderFrame;
-
   HybridRendererBase.prototype.hide = function () {
     this.resizerElem.style.display = 'none';
   };
-
   HybridRendererBase.prototype.show = function () {
     this.resizerElem.style.display = 'block';
   };
-
   HybridRendererBase.prototype.initItems = function () {
     this.buildAllItems();
-
     if (this.camera) {
       this.camera.setup();
     } else {
@@ -16351,7 +13905,6 @@
       var cHeight = this.globalData.compSize.h;
       var i;
       var len = this.threeDElements.length;
-
       for (i = 0; i < len; i += 1) {
         var style = this.threeDElements[i].perspectiveElem.style;
         style.webkitPerspective = Math.sqrt(Math.pow(cWidth, 2) + Math.pow(cHeight, 2)) + 'px';
@@ -16359,12 +13912,10 @@
       }
     }
   };
-
   HybridRendererBase.prototype.searchExtraCompositions = function (assets) {
     var i;
     var 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);
@@ -16385,14 +13936,11 @@
       _placeholder: true
     };
   }
-
   extendPrototype([HybridRendererBase, ICompElement, HBaseElement], HCompElement);
   HCompElement.prototype._createBaseContainerElements = HCompElement.prototype.createContainerElements;
-
   HCompElement.prototype.createContainerElements = function () {
-    this._createBaseContainerElements(); // divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
-
-
+    this._createBaseContainerElements();
+    // divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
     if (this.data.hasMask) {
       this.svgElement.setAttribute('width', this.data.w);
       this.svgElement.setAttribute('height', this.data.h);
@@ -16401,31 +13949,25 @@
       this.transformedElement = this.layerElement;
     }
   };
-
   HCompElement.prototype.addTo3dContainer = function (elem, pos) {
     var j = 0;
     var nextElement;
-
     while (j < pos) {
       if (this.elements[j] && this.elements[j].getBaseElement) {
         nextElement = this.elements[j].getBaseElement();
       }
-
       j += 1;
     }
-
     if (nextElement) {
       this.layerElement.insertBefore(elem, nextElement);
     } else {
       this.layerElement.appendChild(elem);
     }
   };
-
   HCompElement.prototype.createComp = function (data) {
     if (!this.supports3d) {
       return new SVGCompElement(data, this.globalData, this);
     }
-
     return new HCompElement(data, this.globalData, this);
   };
 
@@ -16458,14 +14000,11 @@
     this.supports3d = true;
     this.rendererType = 'html';
   }
-
   extendPrototype([HybridRendererBase], HybridRenderer);
-
   HybridRenderer.prototype.createComp = function (data) {
     if (!this.supports3d) {
       return new SVGCompElement(data, this.globalData, this);
     }
-
     return new HCompElement(data, this.globalData, this);
   };
 
@@ -16474,18 +14013,15 @@
       function _thisLayerFunction(name) {
         var i = 0;
         var len = comp.layers.length;
-
         while (i < len) {
           if (comp.layers[i].nm === name || comp.layers[i].ind === name) {
             return comp.elements[i].layerInterface;
           }
-
           i += 1;
         }
-
-        return null; // return {active:false};
+        return null;
+        // return {active:false};
       }
-
       Object.defineProperty(_thisLayerFunction, '_name', {
         value: comp.data.nm
       });
@@ -16501,10 +14037,8 @@
     };
   }();
 
-  function _typeof$2(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$2 = function _typeof(obj) { return typeof obj; }; } else { _typeof$2 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$2(obj); }
-
+  function _typeof$2(o) { "@babel/helpers - typeof"; return _typeof$2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$2(o); }
   /* eslint-disable */
-
   /*
    Copyright 2014 David Bau.
 
@@ -16528,105 +14062,103 @@
    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
    */
+
   function seedRandom(pool, math) {
     //
     // The following constants are related to IEEE 754 limits.
     //
     var global = this,
-        width = 256,
-        // each RC4 output is 0 <= x < 256
-    chunks = 6,
-        // at least six RC4 outputs for each double
-    digits = 52,
-        // there are 52 significant digits in a double
-    rngname = 'random',
-        // rngname: name for Math.random and Math.seedrandom
-    startdenom = math.pow(width, chunks),
-        significance = math.pow(2, digits),
-        overflow = significance * 2,
-        mask = width - 1,
-        nodecrypto; // node.js crypto module, initialized at the bottom.
+      width = 256,
+      // each RC4 output is 0 <= x < 256
+      chunks = 6,
+      // at least six RC4 outputs for each double
+      digits = 52,
+      // there are 52 significant digits in a double
+      rngname = 'random',
+      // rngname: name for Math.random and Math.seedrandom
+      startdenom = math.pow(width, chunks),
+      significance = math.pow(2, digits),
+      overflow = significance * 2,
+      mask = width - 1,
+      nodecrypto; // node.js crypto module, initialized at the bottom.
+
     //
     // seedrandom()
     // This is the seedrandom function described above.
     //
-
     function seedrandom(seed, options, callback) {
       var key = [];
       options = options === true ? {
         entropy: true
-      } : options || {}; // Flatten the seed string or build one from local entropy if needed.
+      } : options || {};
 
-      var shortseed = mixkey(flatten(options.entropy ? [seed, tostring(pool)] : seed === null ? autoseed() : seed, 3), key); // Use the seed to initialize an ARC4 generator.
+      // Flatten the seed string or build one from local entropy if needed.
+      var shortseed = mixkey(flatten(options.entropy ? [seed, tostring(pool)] : seed === null ? autoseed() : seed, 3), key);
 
-      var arc4 = new ARC4(key); // This function returns a random double in [0, 1) that contains
+      // Use the seed to initialize an ARC4 generator.
+      var arc4 = new ARC4(key);
+
+      // This function returns a random double in [0, 1) that contains
       // randomness in every bit of the mantissa of the IEEE 754 value.
-
       var prng = function prng() {
         var n = arc4.g(chunks),
-            // Start with a numerator n < 2 ^ 48
-        d = startdenom,
-            //   and denominator d = 2 ^ 48.
-        x = 0; //   and no 'extra last byte'.
-
+          // Start with a numerator n < 2 ^ 48
+          d = startdenom,
+          //   and denominator d = 2 ^ 48.
+          x = 0; //   and no 'extra last byte'.
         while (n < significance) {
           // Fill up all significant digits by
           n = (n + x) * width; //   shifting numerator and
-
           d *= width; //   denominator and generating a
-
           x = arc4.g(1); //   new least-significant-byte.
         }
-
         while (n >= overflow) {
           // To avoid rounding up, before adding
           n /= 2; //   last byte, shift everything
-
           d /= 2; //   right using integer math until
-
           x >>>= 1; //   we have exactly the desired bits.
         }
-
         return (n + x) / d; // Form the number within [0, 1).
       };
-
       prng.int32 = function () {
         return arc4.g(4) | 0;
       };
-
       prng.quick = function () {
         return arc4.g(4) / 0x100000000;
       };
+      prng["double"] = prng;
 
-      prng["double"] = prng; // Mix the randomness into accumulated entropy.
+      // Mix the randomness into accumulated entropy.
+      mixkey(tostring(arc4.S), pool);
 
-      mixkey(tostring(arc4.S), pool); // Calling convention: what to return as a function of prng, seed, is_math.
-
+      // Calling convention: what to return as a function of prng, seed, is_math.
       return (options.pass || callback || function (prng, seed, is_math_call, state) {
         if (state) {
           // Load the arc4 state from the given state if it has an S array.
           if (state.S) {
             copy(state, arc4);
-          } // Only provide the .state method if requested via options.state.
-
-
+          }
+          // Only provide the .state method if requested via options.state.
           prng.state = function () {
             return copy(arc4, {});
           };
-        } // If called as a method of Math (Math.seedrandom()), mutate
+        }
+
+        // If called as a method of Math (Math.seedrandom()), mutate
         // Math.random because that is how seedrandom.js has worked since v1.0.
-
-
         if (is_math_call) {
           math[rngname] = prng;
           return seed;
-        } // Otherwise, it is a newer calling convention, so return the
+        }
+
+        // Otherwise, it is a newer calling convention, so return the
         // prng directly.
         else return prng;
       })(prng, shortseed, 'global' in options ? options.global : this == math, options.state);
     }
+    math['seed' + rngname] = seedrandom;
 
-    math['seed' + rngname] = seedrandom; //
+    //
     // ARC4
     //
     // An ARC4 implementation.  The constructor takes a key in the form of
@@ -16636,71 +14168,68 @@
     // the next (count) outputs from ARC4.  Its return value is a number x
     // that is in the range 0 <= x < (width ^ count).
     //
-
     function ARC4(key) {
       var t,
-          keylen = key.length,
-          me = this,
-          i = 0,
-          j = me.i = me.j = 0,
-          s = me.S = []; // The empty key [] is treated as [0].
+        keylen = key.length,
+        me = this,
+        i = 0,
+        j = me.i = me.j = 0,
+        s = me.S = [];
 
+      // The empty key [] is treated as [0].
       if (!keylen) {
         key = [keylen++];
-      } // Set up S using the standard key scheduling algorithm.
+      }
 
-
+      // Set up S using the standard key scheduling algorithm.
       while (i < width) {
         s[i] = i++;
       }
-
       for (i = 0; i < width; i++) {
         s[i] = s[j = mask & j + key[i % keylen] + (t = s[i])];
         s[j] = t;
-      } // The "g" method returns the next (count) outputs as one number.
+      }
 
-
+      // The "g" method returns the next (count) outputs as one number.
       me.g = function (count) {
         // Using instance members instead of closure state nearly doubles speed.
         var t,
-            r = 0,
-            i = me.i,
-            j = me.j,
-            s = me.S;
-
+          r = 0,
+          i = me.i,
+          j = me.j,
+          s = me.S;
         while (count--) {
           t = s[i = mask & i + 1];
           r = r * width + s[mask & (s[i] = s[j = mask & j + t]) + (s[j] = t)];
         }
-
         me.i = i;
         me.j = j;
-        return r; // For robust unpredictability, the function call below automatically
+        return r;
+        // For robust unpredictability, the function call below automatically
         // discards an initial batch of values.  This is called RC4-drop[256].
         // See http://google.com/search?q=rsa+fluhrer+response&btnI
       };
-    } //
+    }
+
+    //
     // copy()
     // Copies internal state of ARC4 to or from a plain object.
     //
-
-
     function copy(f, t) {
       t.i = f.i;
       t.j = f.j;
       t.S = f.S.slice();
       return t;
-    } //
+    }
+
+    //
     // flatten()
     // Converts an object tree to nested arrays of strings.
     //
-
-
     function flatten(obj, depth) {
       var result = [],
-          typ = _typeof$2(obj),
-          prop;
-
+        typ = _typeof$2(obj),
+        prop;
       if (depth && typ == 'object') {
         for (prop in obj) {
           try {
@@ -16708,72 +14237,69 @@
           } catch (e) {}
         }
       }
-
       return result.length ? result : typ == 'string' ? obj : obj + '\0';
-    } //
+    }
+
+    //
     // mixkey()
     // Mixes a string seed into a key that is an array of integers, and
     // returns a shortened string seed that is equivalent to the result key.
     //
-
-
     function mixkey(seed, key) {
       var stringseed = seed + '',
-          smear,
-          j = 0;
-
+        smear,
+        j = 0;
       while (j < stringseed.length) {
         key[mask & j] = mask & (smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++);
       }
-
       return tostring(key);
-    } //
+    }
+
+    //
     // autoseed()
     // Returns an object for autoseeding, using window.crypto and Node crypto
     // module if available.
     //
-
-
     function autoseed() {
       try {
         if (nodecrypto) {
           return tostring(nodecrypto.randomBytes(width));
         }
-
         var out = new Uint8Array(width);
         (global.crypto || global.msCrypto).getRandomValues(out);
         return tostring(out);
       } catch (e) {
         var browser = global.navigator,
-            plugins = browser && browser.plugins;
+          plugins = browser && browser.plugins;
         return [+new Date(), global, plugins, global.screen, tostring(pool)];
       }
-    } //
+    }
+
+    //
     // tostring()
     // Converts an array of charcodes to a string
     //
-
-
     function tostring(a) {
       return String.fromCharCode.apply(0, a);
-    } //
+    }
+
+    //
     // When seedrandom.js is loaded, we immediately mix a few bits
     // from the built-in RNG into the entropy pool.  Because we do
     // not want to interfere with deterministic PRNG state later,
     // seedrandom will not call math.random on its own again after
     // initialization.
     //
+    mixkey(math.random(), pool);
 
-
-    mixkey(math.random(), pool); //
+    //
     // Nodejs and AMD support: export the implementation as a module using
     // either convention.
     //
+
     // End anonymous scope, and pass initial values.
   }
-
   ;
-
   function initialize$2(BMMath) {
     seedRandom([], BMMath);
   }
@@ -16782,8 +14308,7 @@
     SHAPE: 'shape'
   };
 
-  function _typeof$1(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof$1 = function _typeof(obj) { return typeof obj; }; } else { _typeof$1 = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof$1(obj); }
-
+  function _typeof$1(o) { "@babel/helpers - typeof"; return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof$1(o); }
   var ExpressionManager = function () {
     'use strict';
 
@@ -16796,289 +14321,214 @@
     var frames = null;
     var _lottieGlobal = {};
     initialize$2(BMMath);
-
     function resetFrame() {
       _lottieGlobal = {};
     }
-
     function $bm_isInstanceOfArray(arr) {
       return arr.constructor === Array || arr.constructor === Float32Array;
     }
-
     function isNumerable(tOfV, v) {
       return tOfV === 'number' || v instanceof Number || tOfV === 'boolean' || tOfV === 'string';
     }
-
     function $bm_neg(a) {
       var tOfA = _typeof$1(a);
-
       if (tOfA === 'number' || a instanceof Number || tOfA === 'boolean') {
         return -a;
       }
-
       if ($bm_isInstanceOfArray(a)) {
         var i;
         var lenA = a.length;
         var retArr = [];
-
         for (i = 0; i < lenA; i += 1) {
           retArr[i] = -a[i];
         }
-
         return retArr;
       }
-
       if (a.propType) {
         return a.v;
       }
-
       return -a;
     }
-
     var easeInBez = BezierFactory.getBezierEasing(0.333, 0, 0.833, 0.833, 'easeIn').get;
     var easeOutBez = BezierFactory.getBezierEasing(0.167, 0.167, 0.667, 1, 'easeOut').get;
     var easeInOutBez = BezierFactory.getBezierEasing(0.33, 0, 0.667, 1, 'easeInOut').get;
-
     function sum(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b) || tOfA === 'string' || tOfB === 'string') {
         return a + b;
       }
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         a = a.slice(0);
         a[0] += b;
         return a;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         b = b.slice(0);
         b[0] = a + b[0];
         return b;
       }
-
       if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
         var i = 0;
         var lenA = a.length;
         var lenB = b.length;
         var retArr = [];
-
         while (i < lenA || i < lenB) {
           if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
             retArr[i] = a[i] + b[i];
           } else {
             retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
           }
-
           i += 1;
         }
-
         return retArr;
       }
-
       return 0;
     }
-
     var add = sum;
-
     function sub(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         if (tOfA === 'string') {
           a = parseInt(a, 10);
         }
-
         if (tOfB === 'string') {
           b = parseInt(b, 10);
         }
-
         return a - b;
       }
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         a = a.slice(0);
         a[0] -= b;
         return a;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         b = b.slice(0);
         b[0] = a - b[0];
         return b;
       }
-
       if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
         var i = 0;
         var lenA = a.length;
         var lenB = b.length;
         var retArr = [];
-
         while (i < lenA || i < lenB) {
           if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
             retArr[i] = a[i] - b[i];
           } else {
             retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
           }
-
           i += 1;
         }
-
         return retArr;
       }
-
       return 0;
     }
-
     function mul(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       var arr;
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         return a * b;
       }
-
       var i;
       var len;
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         len = a.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a[i] * b;
         }
-
         return arr;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         len = b.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a * b[i];
         }
-
         return arr;
       }
-
       return 0;
     }
-
     function div(a, b) {
       var tOfA = _typeof$1(a);
-
       var tOfB = _typeof$1(b);
-
       var arr;
-
       if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
         return a / b;
       }
-
       var i;
       var len;
-
       if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
         len = a.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a[i] / b;
         }
-
         return arr;
       }
-
       if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
         len = b.length;
         arr = createTypedArray('float32', len);
-
         for (i = 0; i < len; i += 1) {
           arr[i] = a / b[i];
         }
-
         return arr;
       }
-
       return 0;
     }
-
     function mod(a, b) {
       if (typeof a === 'string') {
         a = parseInt(a, 10);
       }
-
       if (typeof b === 'string') {
         b = parseInt(b, 10);
       }
-
       return a % b;
     }
-
     var $bm_sum = sum;
     var $bm_sub = sub;
     var $bm_mul = mul;
     var $bm_div = div;
     var $bm_mod = mod;
-
     function clamp(num, min, max) {
       if (min > max) {
         var mm = max;
         max = min;
         min = mm;
       }
-
       return Math.min(Math.max(num, min), max);
     }
-
     function radiansToDegrees(val) {
       return val / degToRads;
     }
-
     var radians_to_degrees = radiansToDegrees;
-
     function degreesToRadians(val) {
       return val * degToRads;
     }
-
     var degrees_to_radians = radiansToDegrees;
     var helperLengthArray = [0, 0, 0, 0, 0, 0];
-
     function length(arr1, arr2) {
       if (typeof arr1 === 'number' || arr1 instanceof Number) {
         arr2 = arr2 || 0;
         return Math.abs(arr1 - arr2);
       }
-
       if (!arr2) {
         arr2 = helperLengthArray;
       }
-
       var i;
       var len = Math.min(arr1.length, arr2.length);
       var addedLength = 0;
-
       for (i = 0; i < len; i += 1) {
         addedLength += Math.pow(arr2[i] - arr1[i], 2);
       }
-
       return Math.sqrt(addedLength);
     }
-
     function normalize(vec) {
       return div(vec, length(vec));
     }
-
     function rgbToHsl(val) {
       var r = val[0];
       var g = val[1];
@@ -17088,38 +14538,29 @@
       var h;
       var s;
       var l = (max + min) / 2;
-
       if (max === min) {
         h = 0; // achromatic
-
         s = 0; // achromatic
       } else {
         var d = max - min;
         s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
-
         switch (max) {
           case r:
             h = (g - b) / d + (g < b ? 6 : 0);
             break;
-
           case g:
             h = (b - r) / d + 2;
             break;
-
           case b:
             h = (r - g) / d + 4;
             break;
-
           default:
             break;
         }
-
         h /= 6;
       }
-
       return [h, s, l, val[3]];
     }
-
     function hue2rgb(p, q, t) {
       if (t < 0) t += 1;
       if (t > 1) t -= 1;
@@ -17128,7 +14569,6 @@
       if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
       return p;
     }
-
     function hslToRgb(val) {
       var h = val[0];
       var s = val[1];
@@ -17136,12 +14576,9 @@
       var r;
       var g;
       var b;
-
       if (s === 0) {
         r = l; // achromatic
-
         b = l; // achromatic
-
         g = l; // achromatic
       } else {
         var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
@@ -17150,10 +14587,8 @@
         g = hue2rgb(p, q, h);
         b = hue2rgb(p, q, h - 1 / 3);
       }
-
       return [r, g, b, val[3]];
     }
-
     function linear(t, tMin, tMax, value1, value2) {
       if (value1 === undefined || value2 === undefined) {
         value1 = tMin;
@@ -17161,38 +14596,29 @@
         tMin = 0;
         tMax = 1;
       }
-
       if (tMax < tMin) {
         var _tMin = tMax;
         tMax = tMin;
         tMin = _tMin;
       }
-
       if (t <= tMin) {
         return value1;
       }
-
       if (t >= tMax) {
         return value2;
       }
-
       var perc = tMax === tMin ? 0 : (t - tMin) / (tMax - tMin);
-
       if (!value1.length) {
         return value1 + (value2 - value1) * perc;
       }
-
       var i;
       var len = value1.length;
       var arr = createTypedArray('float32', len);
-
       for (i = 0; i < len; i += 1) {
         arr[i] = value1[i] + (value2[i] - value1[i]) * perc;
       }
-
       return arr;
     }
-
     function random(min, max) {
       if (max === undefined) {
         if (min === undefined) {
@@ -17203,33 +14629,25 @@
           min = undefined;
         }
       }
-
       if (max.length) {
         var i;
         var len = max.length;
-
         if (!min) {
           min = createTypedArray('float32', len);
         }
-
         var arr = createTypedArray('float32', len);
         var rnd = BMMath.random();
-
         for (i = 0; i < len; i += 1) {
           arr[i] = min[i] + rnd * (max[i] - min[i]);
         }
-
         return arr;
       }
-
       if (min === undefined) {
         min = 0;
       }
-
       var rndm = BMMath.random();
       return min + rndm * (max - min);
     }
-
     function createPath(points, inTangents, outTangents, closed) {
       var i;
       var len = points.length;
@@ -17238,37 +14656,31 @@
       var arrPlaceholder = [0, 0];
       var inVertexPoint;
       var outVertexPoint;
-
       for (i = 0; i < len; i += 1) {
         inVertexPoint = inTangents && inTangents[i] ? inTangents[i] : arrPlaceholder;
         outVertexPoint = outTangents && outTangents[i] ? outTangents[i] : arrPlaceholder;
         path.setTripleAt(points[i][0], points[i][1], outVertexPoint[0] + points[i][0], outVertexPoint[1] + points[i][1], inVertexPoint[0] + points[i][0], inVertexPoint[1] + points[i][1], i, true);
       }
-
       return path;
     }
-
     function initiateExpression(elem, data, property) {
       // Bail out if we don't want expressions
       function noOp(_value) {
         return _value;
       }
-
       if (!elem.globalData.renderConfig.runExpressions) {
         return noOp;
       }
-
       var val = data.x;
       var needsVelocity = /velocity(?![\w\d])/.test(val);
-
       var _needsRandom = val.indexOf('random') !== -1;
-
       var elemType = elem.data.ty;
       var transform;
       var $bm_transform;
       var content;
       var effect;
       var thisProperty = property;
+      thisProperty._name = elem.data.nm;
       thisProperty.valueAtTime = thisProperty.getValueAtTime;
       Object.defineProperty(thisProperty, 'value', {
         get: function get() {
@@ -17301,13 +14713,11 @@
       var mask;
       var valueAtTime;
       var velocityAtTime;
-      var scoped_bm_rt; // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
-
+      var scoped_bm_rt;
+      // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
       var expression_function = eval('[function _expression_function(){' + val + ';scoped_bm_rt=$bm_rt}]')[0]; // eslint-disable-line no-eval
-
       var numKeys = property.kf ? data.k.length : 0;
       var active = !this.data || this.data.hd !== true;
-
       var wiggle = function wiggle(freq, amp) {
         var iWiggle;
         var j;
@@ -17317,84 +14727,67 @@
         var iterations = Math.floor(time * freq);
         iWiggle = 0;
         j = 0;
-
         while (iWiggle < iterations) {
           // var rnd = BMMath.random();
           for (j = 0; j < lenWiggle; j += 1) {
-            addedAmps[j] += -amp + amp * 2 * BMMath.random(); // addedAmps[j] += -amp + amp*2*rnd;
+            addedAmps[j] += -amp + amp * 2 * BMMath.random();
+            // addedAmps[j] += -amp + amp*2*rnd;
           }
-
           iWiggle += 1;
-        } // var rnd2 = BMMath.random();
-
-
+        }
+        // var rnd2 = BMMath.random();
         var periods = time * freq;
         var perc = periods - Math.floor(periods);
         var arr = createTypedArray('float32', lenWiggle);
-
         if (lenWiggle > 1) {
           for (j = 0; j < lenWiggle; j += 1) {
-            arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc; // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
+            arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc;
+            // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
             // arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc);
           }
-
           return arr;
         }
-
         return this.pv + addedAmps[0] + (-amp + amp * 2 * BMMath.random()) * perc;
       }.bind(this);
-
       if (thisProperty.loopIn) {
         loopIn = thisProperty.loopIn.bind(thisProperty);
         loop_in = loopIn;
       }
-
       if (thisProperty.loopOut) {
         loopOut = thisProperty.loopOut.bind(thisProperty);
         loop_out = loopOut;
       }
-
       if (thisProperty.smooth) {
         smooth = thisProperty.smooth.bind(thisProperty);
       }
-
       function loopInDuration(type, duration) {
         return loopIn(type, duration, true);
       }
-
       function loopOutDuration(type, duration) {
         return loopOut(type, duration, true);
       }
-
       if (this.getValueAtTime) {
         valueAtTime = this.getValueAtTime.bind(this);
       }
-
       if (this.getVelocityAtTime) {
         velocityAtTime = this.getVelocityAtTime.bind(this);
       }
-
       var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface);
-
       function lookAt(elem1, elem2) {
         var fVec = [elem2[0] - elem1[0], elem2[1] - elem1[1], elem2[2] - elem1[2]];
         var pitch = Math.atan2(fVec[0], Math.sqrt(fVec[1] * fVec[1] + fVec[2] * fVec[2])) / degToRads;
         var yaw = -Math.atan2(fVec[1], fVec[2]) / degToRads;
         return [yaw, pitch, 0];
       }
-
       function easeOut(t, tMin, tMax, val1, val2) {
         return applyEase(easeOutBez, t, tMin, tMax, val1, val2);
       }
-
       function easeIn(t, tMin, tMax, val1, val2) {
         return applyEase(easeInBez, t, tMin, tMax, val1, val2);
       }
-
       function ease(t, tMin, tMax, val1, val2) {
         return applyEase(easeInOutBez, t, tMin, tMax, val1, val2);
       }
-
       function applyEase(fn, t, tMin, tMax, val1, val2) {
         if (val1 === undefined) {
           val1 = tMin;
@@ -17402,43 +14795,34 @@
         } else {
           t = (t - tMin) / (tMax - tMin);
         }
-
         if (t > 1) {
           t = 1;
         } else if (t < 0) {
           t = 0;
         }
-
         var mult = fn(t);
-
         if ($bm_isInstanceOfArray(val1)) {
           var iKey;
           var lenKey = val1.length;
           var arr = createTypedArray('float32', lenKey);
-
           for (iKey = 0; iKey < lenKey; iKey += 1) {
             arr[iKey] = (val2[iKey] - val1[iKey]) * mult + val1[iKey];
           }
-
           return arr;
         }
-
         return (val2 - val1) * mult + val1;
       }
-
       function nearestKey(time) {
         var iKey;
         var lenKey = data.k.length;
         var index;
         var keyTime;
-
         if (!data.k.length || typeof data.k[0] === 'number') {
           index = 0;
           keyTime = 0;
         } else {
           index = -1;
           time *= elem.comp.globalData.frameRate;
-
           if (time < data.k[0].t) {
             index = 1;
             keyTime = data.k[0].t;
@@ -17456,33 +14840,27 @@
                   index = iKey + 1;
                   keyTime = data.k[iKey].t;
                 }
-
                 break;
               }
             }
-
             if (index === -1) {
               index = iKey + 1;
               keyTime = data.k[iKey].t;
             }
           }
         }
-
         var obKey = {};
         obKey.index = index;
         obKey.time = keyTime / elem.comp.globalData.frameRate;
         return obKey;
       }
-
       function key(ind) {
         var obKey;
         var iKey;
         var lenKey;
-
         if (!data.k.length || typeof data.k[0] === 'number') {
           throw new Error('The property has no keyframe at index ' + ind);
         }
-
         ind -= 1;
         obKey = {
           time: data.k[ind].t / elem.comp.globalData.frameRate,
@@ -17490,72 +14868,55 @@
         };
         var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e;
         lenKey = arr.length;
-
         for (iKey = 0; iKey < lenKey; iKey += 1) {
           obKey[iKey] = arr[iKey];
           obKey.value[iKey] = arr[iKey];
         }
-
         return obKey;
       }
-
       function framesToTime(fr, fps) {
         if (!fps) {
           fps = elem.comp.globalData.frameRate;
         }
-
         return fr / fps;
       }
-
       function timeToFrames(t, fps) {
         if (!t && t !== 0) {
           t = time;
         }
-
         if (!fps) {
           fps = elem.comp.globalData.frameRate;
         }
-
         return t * fps;
       }
-
       function seedRandom(seed) {
         BMMath.seedrandom(randSeed + seed);
       }
-
       function sourceRectAtTime() {
         return elem.sourceRectAtTime();
       }
-
       function substring(init, end) {
         if (typeof value === 'string') {
           if (end === undefined) {
             return value.substring(init);
           }
-
           return value.substring(init, end);
         }
-
         return '';
       }
-
       function substr(init, end) {
         if (typeof value === 'string') {
           if (end === undefined) {
             return value.substr(init);
           }
-
           return value.substr(init, end);
         }
-
         return '';
       }
-
       function posterizeTime(framesPerSecond) {
         time = framesPerSecond === 0 ? 0 : Math.floor(time * framesPerSecond) / framesPerSecond;
         value = valueAtTime(time);
       }
-
       var time;
       var velocity;
       var value;
@@ -17568,21 +14929,17 @@
       var parent;
       var randSeed = Math.floor(Math.random() * 1000000);
       var globalData = elem.globalData;
-
       function executeExpression(_value) {
         // globalData.pushExpression();
         value = _value;
-
         if (this.frameExpressionId === elem.globalData.frameId && this.propType !== 'textSelector') {
           return value;
         }
-
         if (this.propType === 'textSelector') {
           textIndex = this.textIndex;
           textTotal = this.textTotal;
           selectorValue = this.selectorValue;
         }
-
         if (!thisLayer) {
           text = elem.layerInterface.text;
           thisLayer = elem.layerInterface;
@@ -17594,11 +14951,9 @@
           mask = thisLayer.mask ? thisLayer.mask.bind(thisLayer) : null;
           fromCompToSurface = fromComp;
         }
-
         if (!transform) {
           transform = elem.layerInterface('ADBE Transform Group');
           $bm_transform = transform;
-
           if (transform) {
             anchorPoint = transform.anchorPoint;
             /* position = transform.position;
@@ -17606,44 +14961,35 @@
                       scale = transform.scale; */
           }
         }
-
         if (elemType === 4 && !content) {
           content = thisLayer('ADBE Root Vectors Group');
         }
-
         if (!effect) {
           effect = thisLayer(4);
         }
-
         hasParent = !!(elem.hierarchy && elem.hierarchy.length);
-
         if (hasParent && !parent) {
           parent = elem.hierarchy[0].layerInterface;
         }
-
         time = this.comp.renderedFrame / this.comp.globalData.frameRate;
-
         if (_needsRandom) {
           seedRandom(randSeed + time);
         }
-
         if (needsVelocity) {
           velocity = velocityAtTime(time);
         }
-
         expression_function();
-        this.frameExpressionId = elem.globalData.frameId; // TODO: Check if it's possible to return on ShapeInterface the .v value
-        // Changed this to a ternary operation because Rollup failed compiling it correctly
+        this.frameExpressionId = elem.globalData.frameId;
 
+        // TODO: Check if it's possible to return on ShapeInterface the .v value
+        // Changed this to a ternary operation because Rollup failed compiling it correctly
         scoped_bm_rt = scoped_bm_rt.propType === propTypes.SHAPE ? scoped_bm_rt.v : scoped_bm_rt;
         return scoped_bm_rt;
-      } // Bundlers will see these as dead code and unless we reference them
-
-
+      }
+      // Bundlers will see these as dead code and unless we reference them
       executeExpression.__preventDeadCodeRemoval = [$bm_transform, anchorPoint, time, velocity, inPoint, outPoint, width, height, name, loop_in, loop_out, smooth, toComp, fromCompToSurface, toWorld, fromWorld, mask, position, rotation, scale, thisComp, numKeys, active, wiggle, loopInDuration, loopOutDuration, comp, lookAt, easeOut, easeIn, ease, nearestKey, key, text, textIndex, textTotal, selectorValue, framesToTime, timeToFrames, sourceRectAtTime, substring, substr, posterizeTime, index, globalData];
       return executeExpression;
     }
-
     ob.initiateExpression = initiateExpression;
     ob.__preventDeadCodeRemoval = [window, document, XMLHttpRequest, fetch, frames, $bm_neg, add, $bm_sum, $bm_sub, $bm_mul, $bm_div, $bm_mod, clamp, radians_to_degrees, degreesToRadians, degrees_to_radians, normalize, rgbToHsl, hslToRgb, linear, random, createPath, _lottieGlobal];
     ob.resetFrame = resetFrame;
@@ -17654,47 +15000,37 @@
     var ob = {};
     ob.initExpressions = initExpressions;
     ob.resetFrame = ExpressionManager.resetFrame;
-
     function initExpressions(animation) {
       var stackCount = 0;
       var registers = [];
-
       function pushExpression() {
         stackCount += 1;
       }
-
       function popExpression() {
         stackCount -= 1;
-
         if (stackCount === 0) {
           releaseInstances();
         }
       }
-
       function registerExpressionProperty(expression) {
         if (registers.indexOf(expression) === -1) {
           registers.push(expression);
         }
       }
-
       function releaseInstances() {
         var i;
         var len = registers.length;
-
         for (i = 0; i < len; i += 1) {
           registers[i].release();
         }
-
         registers.length = 0;
       }
-
       animation.renderer.compInterface = CompExpressionInterface(animation.renderer);
       animation.renderer.globalData.projectInterface.registerComposition(animation.renderer);
       animation.renderer.globalData.pushExpression = pushExpression;
       animation.renderer.globalData.popExpression = popExpression;
       animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty;
     }
-
     return ob;
   }();
 
@@ -17703,13 +15039,11 @@
       this._mask = mask;
       this._data = data;
     }
-
     Object.defineProperty(MaskInterface.prototype, 'maskPath', {
       get: function get() {
         if (this._mask.prop.k) {
           this._mask.prop.getValue();
         }
-
         return this._mask.prop;
       }
     });
@@ -17718,38 +15052,28 @@
         if (this._mask.op.k) {
           this._mask.op.getValue();
         }
-
         return this._mask.op.v * 100;
       }
     });
-
     var MaskManager = function MaskManager(maskManager) {
       var _masksInterfaces = createSizedArray(maskManager.viewData.length);
-
       var i;
       var len = maskManager.viewData.length;
-
       for (i = 0; i < len; i += 1) {
         _masksInterfaces[i] = new MaskInterface(maskManager.viewData[i], maskManager.masksProperties[i]);
       }
-
       var maskFunction = function maskFunction(name) {
         i = 0;
-
         while (i < len) {
           if (maskManager.masksProperties[i].nm === name) {
             return _masksInterfaces[i];
           }
-
           i += 1;
         }
-
         return null;
       };
-
       return maskFunction;
     };
-
     return MaskManager;
   }();
 
@@ -17764,7 +15088,6 @@
       v: [0, 0, 0],
       mult: 1
     };
-
     function completeProperty(expressionValue, property, type) {
       Object.defineProperty(expressionValue, 'velocity', {
         get: function get() {
@@ -17772,14 +15095,11 @@
         }
       });
       expressionValue.numKeys = property.keyframes ? property.keyframes.length : 0;
-
       expressionValue.key = function (pos) {
         if (!expressionValue.numKeys) {
           return 0;
         }
-
         var value = '';
-
         if ('s' in property.keyframes[pos - 1]) {
           value = property.keyframes[pos - 1].s;
         } else if ('e' in property.keyframes[pos - 2]) {
@@ -17787,54 +15107,43 @@
         } else {
           value = property.keyframes[pos - 2].s;
         }
-
         var valueProp = type === 'unidimensional' ? new Number(value) : Object.assign({}, value); // eslint-disable-line no-new-wrappers
-
         valueProp.time = property.keyframes[pos - 1].t / property.elem.comp.globalData.frameRate;
         valueProp.value = type === 'unidimensional' ? value[0] : value;
         return valueProp;
       };
-
       expressionValue.valueAtTime = property.getValueAtTime;
       expressionValue.speedAtTime = property.getSpeedAtTime;
       expressionValue.velocityAtTime = property.getVelocityAtTime;
       expressionValue.propertyGroup = property.propertyGroup;
     }
-
     function UnidimensionalPropertyInterface(property) {
       if (!property || !('pv' in property)) {
         property = defaultUnidimensionalValue;
       }
-
       var mult = 1 / property.mult;
       var val = property.pv * mult;
       var expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
-
       expressionValue.value = val;
       completeProperty(expressionValue, property, 'unidimensional');
       return function () {
         if (property.k) {
           property.getValue();
         }
-
         val = property.v * mult;
-
         if (expressionValue.value !== val) {
           expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
-
           expressionValue.value = val;
+          expressionValue[0] = val;
           completeProperty(expressionValue, property, 'unidimensional');
         }
-
         return expressionValue;
       };
     }
-
     function MultidimensionalPropertyInterface(property) {
       if (!property || !('pv' in property)) {
         property = defaultMultidimensionalValue;
       }
-
       var mult = 1 / property.mult;
       var len = property.data && property.data.l || property.pv.length;
       var expressionValue = createTypedArray('float32', len);
@@ -17845,30 +15154,25 @@
         if (property.k) {
           property.getValue();
         }
-
         for (var i = 0; i < len; i += 1) {
           arrValue[i] = property.v[i] * mult;
           expressionValue[i] = arrValue[i];
         }
-
         return expressionValue;
       };
-    } // TODO: try to avoid using this getter
+    }
 
-
+    // TODO: try to avoid using this getter
     function defaultGetter() {
       return defaultUnidimensionalValue;
     }
-
     return function (property) {
       if (!property) {
         return defaultGetter;
       }
-
       if (property.propType === 'unidimensional') {
         return UnidimensionalPropertyInterface(property);
       }
-
       return MultidimensionalPropertyInterface(property);
     };
   }();
@@ -17882,52 +15186,41 @@
           case 'ADBE Scale':
           case 6:
             return _thisFunction.scale;
-
           case 'rotation':
           case 'Rotation':
           case 'ADBE Rotation':
           case 'ADBE Rotate Z':
           case 10:
             return _thisFunction.rotation;
-
           case 'ADBE Rotate X':
             return _thisFunction.xRotation;
-
           case 'ADBE Rotate Y':
             return _thisFunction.yRotation;
-
           case 'position':
           case 'Position':
           case 'ADBE Position':
           case 2:
             return _thisFunction.position;
-
           case 'ADBE Position_0':
             return _thisFunction.xPosition;
-
           case 'ADBE Position_1':
             return _thisFunction.yPosition;
-
           case 'ADBE Position_2':
             return _thisFunction.zPosition;
-
           case 'anchorPoint':
           case 'AnchorPoint':
           case 'Anchor Point':
           case 'ADBE AnchorPoint':
           case 1:
             return _thisFunction.anchorPoint;
-
           case 'opacity':
           case 'Opacity':
           case 11:
             return _thisFunction.opacity;
-
           default:
             return null;
         }
       }
-
       Object.defineProperty(_thisFunction, 'rotation', {
         get: ExpressionPropertyInterface(transform.r || transform.rz)
       });
@@ -17943,32 +15236,24 @@
       Object.defineProperty(_thisFunction, 'scale', {
         get: ExpressionPropertyInterface(transform.s)
       });
-
       var _px;
-
       var _py;
-
       var _pz;
-
       var _transformFactory;
-
       if (transform.p) {
         _transformFactory = ExpressionPropertyInterface(transform.p);
       } else {
         _px = ExpressionPropertyInterface(transform.px);
         _py = ExpressionPropertyInterface(transform.py);
-
         if (transform.pz) {
           _pz = ExpressionPropertyInterface(transform.pz);
         }
       }
-
       Object.defineProperty(_thisFunction, 'position', {
         get: function get() {
           if (transform.p) {
             return _transformFactory();
           }
-
           return [_px(), _py(), _pz ? _pz() : 0];
         }
       });
@@ -18003,19 +15288,15 @@
   var LayerExpressionInterface = function () {
     function getMatrix(time) {
       var toWorldMat = new Matrix();
-
       if (time !== undefined) {
         var propMatrix = this._elem.finalTransform.mProp.getValueAtTime(time);
-
         propMatrix.clone(toWorldMat);
       } else {
         var transformMat = this._elem.finalTransform.mProp;
         transformMat.applyToMatrix(toWorldMat);
       }
-
       return toWorldMat;
     }
-
     function toWorldVec(arr, time) {
       var toWorldMat = this.getMatrix(time);
       toWorldMat.props[12] = 0;
@@ -18023,12 +15304,10 @@
       toWorldMat.props[14] = 0;
       return this.applyPoint(toWorldMat, arr);
     }
-
     function toWorld(arr, time) {
       var toWorldMat = this.getMatrix(time);
       return this.applyPoint(toWorldMat, arr);
     }
-
     function fromWorldVec(arr, time) {
       var toWorldMat = this.getMatrix(time);
       toWorldMat.props[12] = 0;
@@ -18036,101 +15315,78 @@
       toWorldMat.props[14] = 0;
       return this.invertPoint(toWorldMat, arr);
     }
-
     function fromWorld(arr, time) {
       var toWorldMat = this.getMatrix(time);
       return this.invertPoint(toWorldMat, arr);
     }
-
     function applyPoint(matrix, arr) {
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
         }
       }
-
       return matrix.applyToPointArray(arr[0], arr[1], arr[2] || 0);
     }
-
     function invertPoint(matrix, arr) {
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
         }
       }
-
       return matrix.inversePoint(arr);
     }
-
     function fromComp(arr) {
       var toWorldMat = new Matrix();
       toWorldMat.reset();
-
       this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
-
       if (this._elem.hierarchy && this._elem.hierarchy.length) {
         var i;
         var len = this._elem.hierarchy.length;
-
         for (i = 0; i < len; i += 1) {
           this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
         }
-
         return toWorldMat.inversePoint(arr);
       }
-
       return toWorldMat.inversePoint(arr);
     }
-
     function sampleImage() {
       return [1, 1, 1, 1];
     }
-
     return function (elem) {
       var transformInterface;
-
       function _registerMaskInterface(maskManager) {
         _thisLayerFunction.mask = new MaskManagerInterface(maskManager, elem);
       }
-
       function _registerEffectsInterface(effects) {
         _thisLayerFunction.effect = effects;
       }
-
       function _thisLayerFunction(name) {
         switch (name) {
           case 'ADBE Root Vectors Group':
           case 'Contents':
           case 2:
             return _thisLayerFunction.shapeInterface;
-
           case 1:
           case 6:
           case 'Transform':
           case 'transform':
           case 'ADBE Transform Group':
             return transformInterface;
-
           case 4:
           case 'ADBE Effect Parade':
           case 'effects':
           case 'Effects':
             return _thisLayerFunction.effect;
-
           case 'ADBE Text Properties':
             return _thisLayerFunction.textInterface;
-
           default:
             return null;
         }
       }
-
       _thisLayerFunction.getMatrix = getMatrix;
       _thisLayerFunction.invertPoint = invertPoint;
       _thisLayerFunction.applyPoint = applyPoint;
@@ -18191,11 +15447,9 @@
     return function (interfaceFunction, parentPropertyGroup) {
       return function (val) {
         val = val === undefined ? 1 : val;
-
         if (val <= 0) {
           return interfaceFunction;
         }
-
         return parentPropertyGroup(val - 1);
       };
     };
@@ -18206,17 +15460,13 @@
       var interfaceFunction = {
         _name: propertyName
       };
-
       function _propertyGroup(val) {
         val = val === undefined ? 1 : val;
-
         if (val <= 0) {
           return interfaceFunction;
         }
-
         return propertyGroup(val - 1);
       }
-
       return _propertyGroup;
     };
   }();
@@ -18225,35 +15475,27 @@
     var ob = {
       createEffectsInterface: createEffectsInterface
     };
-
     function createEffectsInterface(elem, propertyGroup) {
       if (elem.effectsManager) {
         var effectElements = [];
         var effectsData = elem.data.ef;
         var i;
         var len = elem.effectsManager.effectElements.length;
-
         for (i = 0; i < len; i += 1) {
           effectElements.push(createGroupInterface(effectsData[i], elem.effectsManager.effectElements[i], propertyGroup, elem));
         }
-
         var effects = elem.data.ef || [];
-
         var groupInterface = function groupInterface(name) {
           i = 0;
           len = effects.length;
-
           while (i < len) {
             if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
               return effectElements[i];
             }
-
             i += 1;
           }
-
           return null;
         };
-
         Object.defineProperty(groupInterface, 'numProperties', {
           get: function get() {
             return effects.length;
@@ -18261,37 +15503,28 @@
         });
         return groupInterface;
       }
-
       return null;
     }
-
     function createGroupInterface(data, elements, propertyGroup, elem) {
       function groupInterface(name) {
         var effects = data.ef;
         var i = 0;
         var len = effects.length;
-
         while (i < len) {
           if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
             if (effects[i].ty === 5) {
               return effectElements[i];
             }
-
             return effectElements[i]();
           }
-
           i += 1;
         }
-
         throw new Error();
       }
-
       var _propertyGroup = propertyGroupFactory(groupInterface, propertyGroup);
-
       var effectElements = [];
       var i;
       var len = data.ef.length;
-
       for (i = 0; i < len; i += 1) {
         if (data.ef[i].ty === 5) {
           effectElements.push(createGroupInterface(data.ef[i], elements.effectElements[i], elements.effectElements[i].propertyGroup, elem));
@@ -18299,7 +15532,6 @@
           effectElements.push(createValueInterface(elements.effectElements[i], data.ef[i].ty, elem, _propertyGroup));
         }
       }
-
       if (data.mn === 'ADBE Color Control') {
         Object.defineProperty(groupInterface, 'color', {
           get: function get() {
@@ -18307,7 +15539,6 @@
           }
         });
       }
-
       Object.defineProperties(groupInterface, {
         numProperties: {
           get: function get() {
@@ -18325,42 +15556,32 @@
       groupInterface.active = groupInterface.enabled;
       return groupInterface;
     }
-
     function createValueInterface(element, type, elem, propertyGroup) {
       var expressionProperty = ExpressionPropertyInterface(element.p);
-
       function interfaceFunction() {
         if (type === 10) {
           return elem.comp.compInterface(element.p.v);
         }
-
         return expressionProperty();
       }
-
       if (element.p.setGroupProperty) {
         element.p.setGroupProperty(PropertyInterface('', propertyGroup));
       }
-
       return interfaceFunction;
     }
-
     return ob;
   }();
 
   var ShapePathInterface = function () {
     return function pathInterfaceFactory(shape, view, propertyGroup) {
       var prop = view.sh;
-
       function interfaceFunction(val) {
         if (val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2) {
           return interfaceFunction.path;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       prop.setGroupProperty(PropertyInterface('Path', _propertyGroup));
       Object.defineProperties(interfaceFunction, {
         path: {
@@ -18368,7 +15589,6 @@
             if (prop.k) {
               prop.getValue();
             }
-
             return prop;
           }
         },
@@ -18377,7 +15597,6 @@
             if (prop.k) {
               prop.getValue();
             }
-
             return prop;
           }
         },
@@ -18406,7 +15625,6 @@
       var arr = [];
       var i;
       var len = shapes ? shapes.length : 0;
-
       for (i = 0; i < len; i += 1) {
         if (shapes[i].ty === 'gr') {
           arr.push(groupInterfaceFactory(shapes[i], view[i], propertyGroup));
@@ -18416,7 +15634,8 @@
           arr.push(strokeInterfaceFactory(shapes[i], view[i], propertyGroup));
         } else if (shapes[i].ty === 'tm') {
           arr.push(trimInterfaceFactory(shapes[i], view[i], propertyGroup));
-        } else if (shapes[i].ty === 'tr') {// arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
+        } else if (shapes[i].ty === 'tr') {
+          // arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
         } else if (shapes[i].ty === 'el') {
           arr.push(ellipseInterfaceFactory(shapes[i], view[i], propertyGroup));
         } else if (shapes[i].ty === 'sr') {
@@ -18435,32 +15654,24 @@
           arr.push(defaultInterfaceFactory(shapes[i], view[i], propertyGroup));
         }
       }
-
       return arr;
     }
-
     function contentsInterfaceFactory(shape, view, propertyGroup) {
       var interfaces;
-
       var interfaceFunction = function _interfaceFunction(value) {
         var i = 0;
         var len = interfaces.length;
-
         while (i < len) {
           if (interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value) {
             return interfaces[i];
           }
-
           i += 1;
         }
-
         if (typeof value === 'number') {
           return interfaces[value - 1];
         }
-
         return null;
       };
-
       interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
       interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup);
       interfaceFunction.numProperties = interfaces.length;
@@ -18470,7 +15681,6 @@
       interfaceFunction._name = shape.nm;
       return interfaceFunction;
     }
-
     function groupInterfaceFactory(shape, view, propertyGroup) {
       var interfaceFunction = function _interfaceFunction(value) {
         switch (value) {
@@ -18481,12 +15691,10 @@
           // Not necessary for now. Keeping them here in case a new case appears
           // case 'ADBE Vector Transform Group':
           // case 3:
-
           default:
             return interfaceFunction.transform;
         }
       };
-
       interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
       var content = contentsInterfaceFactory(shape, view, interfaceFunction.propertyGroup);
       var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
@@ -18496,28 +15704,24 @@
         get: function get() {
           return shape.nm;
         }
-      }); // interfaceFunction.content = interfaceFunction;
-
+      });
+      // interfaceFunction.content = interfaceFunction;
       interfaceFunction.numProperties = shape.np;
       interfaceFunction.propertyIndex = shape.ix;
       interfaceFunction.nm = shape.nm;
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function fillInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(val) {
         if (val === 'Color' || val === 'color') {
           return interfaceFunction.color;
         }
-
         if (val === 'Opacity' || val === 'opacity') {
           return interfaceFunction.opacity;
         }
-
         return null;
       }
-
       Object.defineProperties(interfaceFunction, {
         color: {
           get: ExpressionPropertyInterface(view.c)
@@ -18536,24 +15740,19 @@
       view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
       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)
@@ -18581,51 +15780,39 @@
       view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
       return interfaceFunction;
     }
-
     function defaultInterfaceFactory() {
       function interfaceFunction() {
         return null;
       }
-
       return interfaceFunction;
     }
-
     function strokeInterfaceFactory(shape, view, propertyGroup) {
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup);
-
       function addPropertyToDashOb(i) {
         Object.defineProperty(dashOb, shape.d[i].nm, {
           get: ExpressionPropertyInterface(view.d.dataProps[i].p)
         });
       }
-
       var i;
       var len = shape.d ? shape.d.length : 0;
       var dashOb = {};
-
       for (i = 0; i < len; i += 1) {
         addPropertyToDashOb(i);
         view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup);
       }
-
       function interfaceFunction(val) {
         if (val === 'Color' || val === 'color') {
           return interfaceFunction.color;
         }
-
         if (val === 'Opacity' || val === 'opacity') {
           return interfaceFunction.opacity;
         }
-
         if (val === 'Stroke Width' || val === 'stroke width') {
           return interfaceFunction.strokeWidth;
         }
-
         return null;
       }
-
       Object.defineProperties(interfaceFunction, {
         color: {
           get: ExpressionPropertyInterface(view.c)
@@ -18653,26 +15840,20 @@
       view.w.setGroupProperty(PropertyInterface('Stroke Width', _propertyGroup));
       return interfaceFunction;
     }
-
     function trimInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(val) {
         if (val === shape.e.ix || val === 'End' || val === 'end') {
           return interfaceFunction.end;
         }
-
         if (val === shape.s.ix) {
           return interfaceFunction.start;
         }
-
         if (val === shape.o.ix) {
           return interfaceFunction.offset;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       interfaceFunction.propertyIndex = shape.ix;
       view.s.setGroupProperty(PropertyInterface('Start', _propertyGroup));
       view.e.setGroupProperty(PropertyInterface('End', _propertyGroup));
@@ -18696,53 +15877,41 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function transformInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.a.ix === value || value === 'Anchor Point') {
           return interfaceFunction.anchorPoint;
         }
-
         if (shape.o.ix === value || value === 'Opacity') {
           return interfaceFunction.opacity;
         }
-
         if (shape.p.ix === value || value === 'Position') {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value || value === 'Rotation' || value === 'ADBE Vector Rotation') {
           return interfaceFunction.rotation;
         }
-
         if (shape.s.ix === value || value === 'Scale') {
           return interfaceFunction.scale;
         }
-
         if (shape.sk && shape.sk.ix === value || value === 'Skew') {
           return interfaceFunction.skew;
         }
-
         if (shape.sa && shape.sa.ix === value || value === 'Skew Axis') {
           return interfaceFunction.skewAxis;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
       view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
       view.transform.mProps.a.setGroupProperty(PropertyInterface('Anchor Point', _propertyGroup));
       view.transform.mProps.s.setGroupProperty(PropertyInterface('Scale', _propertyGroup));
       view.transform.mProps.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
-
       if (view.transform.mProps.sk) {
         view.transform.mProps.sk.setGroupProperty(PropertyInterface('Skew', _propertyGroup));
         view.transform.mProps.sa.setGroupProperty(PropertyInterface('Skew Angle', _propertyGroup));
       }
-
       view.transform.op.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
       Object.defineProperties(interfaceFunction, {
         opacity: {
@@ -18775,22 +15944,17 @@
       interfaceFunction.propertyGroup = propertyGroup;
       return interfaceFunction;
     }
-
     function ellipseInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.s.ix === value) {
           return interfaceFunction.size;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       interfaceFunction.propertyIndex = shape.ix;
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
@@ -18809,42 +15973,32 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function starInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value) {
           return interfaceFunction.rotation;
         }
-
         if (shape.pt.ix === value) {
           return interfaceFunction.points;
         }
-
         if (shape.or.ix === value || value === 'ADBE Vector Star Outer Radius') {
           return interfaceFunction.outerRadius;
         }
-
         if (shape.os.ix === value) {
           return interfaceFunction.outerRoundness;
         }
-
         if (shape.ir && (shape.ir.ix === value || value === 'ADBE Vector Star Inner Radius')) {
           return interfaceFunction.innerRadius;
         }
-
         if (shape.is && shape.is.ix === value) {
           return interfaceFunction.innerRoundness;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       interfaceFunction.propertyIndex = shape.ix;
       prop.or.setGroupProperty(PropertyInterface('Outer Radius', _propertyGroup));
@@ -18852,12 +16006,10 @@
       prop.pt.setGroupProperty(PropertyInterface('Points', _propertyGroup));
       prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
       prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
-
       if (shape.ir) {
         prop.ir.setGroupProperty(PropertyInterface('Inner Radius', _propertyGroup));
         prop.is.setGroupProperty(PropertyInterface('Inner Roundness', _propertyGroup));
       }
-
       Object.defineProperties(interfaceFunction, {
         position: {
           get: ExpressionPropertyInterface(prop.p)
@@ -18887,26 +16039,20 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function rectInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.p.ix === value) {
           return interfaceFunction.position;
         }
-
         if (shape.r.ix === value) {
           return interfaceFunction.roundness;
         }
-
         if (shape.s.ix === value || value === 'Size' || value === 'ADBE Vector Rect Size') {
           return interfaceFunction.size;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
       interfaceFunction.propertyIndex = shape.ix;
       prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
@@ -18929,18 +16075,14 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function roundedInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.r.ix === value || value === 'Round Corners 1') {
           return interfaceFunction.radius;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view;
       interfaceFunction.propertyIndex = shape.ix;
       prop.rd.setGroupProperty(PropertyInterface('Radius', _propertyGroup));
@@ -18955,22 +16097,17 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     function repeaterInterfaceFactory(shape, view, propertyGroup) {
       function interfaceFunction(value) {
         if (shape.c.ix === value || value === 'Copies') {
           return interfaceFunction.copies;
         }
-
         if (shape.o.ix === value || value === 'Offset') {
           return interfaceFunction.offset;
         }
-
         return null;
       }
-
       var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
       var prop = view;
       interfaceFunction.propertyIndex = shape.ix;
       prop.c.setGroupProperty(PropertyInterface('Copies', _propertyGroup));
@@ -18989,39 +16126,29 @@
       interfaceFunction.mn = shape.mn;
       return interfaceFunction;
     }
-
     return function (shapes, view, propertyGroup) {
       var interfaces;
-
       function _interfaceFunction(value) {
         if (typeof value === 'number') {
           value = value === undefined ? 1 : value;
-
           if (value === 0) {
             return propertyGroup;
           }
-
           return interfaces[value - 1];
         }
-
         var i = 0;
         var len = interfaces.length;
-
         while (i < len) {
           if (interfaces[i]._name === value) {
             return interfaces[i];
           }
-
           i += 1;
         }
-
         return null;
       }
-
       function parentGroupWrapper() {
         return propertyGroup;
       }
-
       _interfaceFunction.propertyGroup = propertyGroupFactory(_interfaceFunction, parentGroupWrapper);
       interfaces = iterateElements(shapes, view, _interfaceFunction.propertyGroup);
       _interfaceFunction.numProperties = interfaces.length;
@@ -19033,28 +16160,22 @@
   var TextExpressionInterface = function () {
     return function (elem) {
       var _sourceText;
-
       function _thisLayerFunction(name) {
         switch (name) {
           case 'ADBE Text Document':
             return _thisLayerFunction.sourceText;
-
           default:
             return null;
         }
       }
-
       Object.defineProperty(_thisLayerFunction, 'sourceText', {
         get: function get() {
           elem.textProperty.getValue();
           var stringValue = elem.textProperty.currentData.t;
-
           if (!_sourceText || stringValue !== _sourceText.value) {
             _sourceText = new String(stringValue); // eslint-disable-line no-new-wrappers
             // If stringValue is an empty string, eval returns undefined, so it has to be returned as a String primitive
-
             _sourceText.value = stringValue || new String(stringValue); // eslint-disable-line no-new-wrappers
-
             Object.defineProperty(_sourceText, 'style', {
               get: function get() {
                 return {
@@ -19063,7 +16184,6 @@
               }
             });
           }
-
           return _sourceText;
         }
       });
@@ -19071,73 +16191,56 @@
     };
   }();
 
-  function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
-
+  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
   var FootageInterface = function () {
     var outlineInterfaceFactory = function outlineInterfaceFactory(elem) {
       var currentPropertyName = '';
       var currentProperty = elem.getFootageData();
-
       function init() {
         currentPropertyName = '';
         currentProperty = elem.getFootageData();
         return searchProperty;
       }
-
       function searchProperty(value) {
         if (currentProperty[value]) {
           currentPropertyName = value;
           currentProperty = currentProperty[value];
-
           if (_typeof(currentProperty) === 'object') {
             return searchProperty;
           }
-
           return currentProperty;
         }
-
         var propertyNameIndex = value.indexOf(currentPropertyName);
-
         if (propertyNameIndex !== -1) {
           var index = parseInt(value.substr(propertyNameIndex + currentPropertyName.length), 10);
           currentProperty = currentProperty[index];
-
           if (_typeof(currentProperty) === 'object') {
             return searchProperty;
           }
-
           return currentProperty;
         }
-
         return '';
       }
-
       return init;
     };
-
     var dataInterfaceFactory = function dataInterfaceFactory(elem) {
       function interfaceFunction(value) {
         if (value === 'Outline') {
           return interfaceFunction.outlineInterface();
         }
-
         return null;
       }
-
       interfaceFunction._name = 'Outline';
       interfaceFunction.outlineInterface = outlineInterfaceFactory(elem);
       return interfaceFunction;
     };
-
     return function (elem) {
       function _interfaceFunction(value) {
         if (value === 'Data') {
           return _interfaceFunction.dataInterface;
         }
-
         return null;
       }
-
       _interfaceFunction._name = 'Data';
       _interfaceFunction.dataInterface = dataInterfaceFactory(elem);
       return _interfaceFunction;
@@ -19152,7 +16255,6 @@
     text: TextExpressionInterface,
     footage: FootageInterface
   };
-
   function getInterface(type) {
     return interfaces[type] || null;
   }
@@ -19166,56 +16268,44 @@
         prop.effectsSequence.push(prop.initiateExpression(elem, data, prop).bind(prop));
       }
     }
-
     function getValueAtTime(frameNum) {
       frameNum *= this.elem.globalData.frameRate;
       frameNum -= this.offsetTime;
-
       if (frameNum !== this._cachingAtTime.lastFrame) {
         this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0;
         this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime);
         this._cachingAtTime.lastFrame = frameNum;
       }
-
       return this._cachingAtTime.value;
     }
-
     function getSpeedAtTime(frameNum) {
       var delta = -0.01;
       var v1 = this.getValueAtTime(frameNum);
       var v2 = this.getValueAtTime(frameNum + delta);
       var speed = 0;
-
       if (v1.length) {
         var i;
-
         for (i = 0; i < v1.length; i += 1) {
           speed += Math.pow(v2[i] - v1[i], 2);
         }
-
         speed = Math.sqrt(speed) * 100;
       } else {
         speed = 0;
       }
-
       return speed;
     }
-
     function getVelocityAtTime(frameNum) {
       if (this.vel !== undefined) {
         return this.vel;
       }
-
-      var delta = -0.001; // frameNum += this.elem.data.st;
-
+      var delta = -0.001;
+      // frameNum += this.elem.data.st;
       var v1 = this.getValueAtTime(frameNum);
       var v2 = this.getValueAtTime(frameNum + delta);
       var velocity;
-
       if (v1.length) {
         velocity = createTypedArray('float32', v1.length);
         var i;
-
         for (i = 0; i < v1.length; i += 1) {
           // removing frameRate
           // if needed, don't add it here
@@ -19225,18 +16315,14 @@
       } else {
         velocity = (v2 - v1) / delta;
       }
-
       return velocity;
     }
-
     function getStaticValueAtTime() {
       return this.pv;
     }
-
     function setGroupProperty(propertyGroup) {
       this.propertyGroup = propertyGroup;
     }
-
     return {
       searchExpressions: searchExpressions,
       getSpeedAtTime: getSpeedAtTime,
@@ -19252,24 +16338,19 @@
       if (!this.k || !this.keyframes) {
         return this.pv;
       }
-
       type = type ? type.toLowerCase() : '';
       var currentFrame = this.comp.renderedFrame;
       var keyframes = this.keyframes;
       var lastKeyFrame = keyframes[keyframes.length - 1].t;
-
       if (currentFrame <= lastKeyFrame) {
         return this.pv;
       }
-
       var cycleDuration;
       var firstKeyFrame;
-
       if (!durationFlag) {
         if (!duration || duration > keyframes.length - 1) {
           duration = keyframes.length - 1;
         }
-
         firstKeyFrame = keyframes[keyframes.length - 1 - duration].t;
         cycleDuration = lastKeyFrame - firstKeyFrame;
       } else {
@@ -19278,17 +16359,13 @@
         } else {
           cycleDuration = Math.abs(lastKeyFrame - this.elem.comp.globalData.frameRate * duration);
         }
-
         firstKeyFrame = lastKeyFrame - cycleDuration;
       }
-
       var i;
       var len;
       var ret;
-
       if (type === 'pingpong') {
         var iterations = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
-
         if (iterations % 2 !== 0) {
           return this.getValueAtTime((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
         }
@@ -19296,64 +16373,48 @@
         var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
         var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
-
         var repeats = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
-
         if (this.pv.length) {
           ret = new Array(initV.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = (endV[i] - initV[i]) * repeats + current[i];
           }
-
           return ret;
         }
-
         return (endV - initV) * repeats + current;
       } else if (type === 'continue') {
         var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0);
-
         if (this.pv.length) {
           ret = new Array(lastValue.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = lastValue[i] + (lastValue[i] - nextLastValue[i]) * ((currentFrame - lastKeyFrame) / this.comp.globalData.frameRate) / 0.0005; // eslint-disable-line
           }
-
           return ret;
         }
-
         return lastValue + (lastValue - nextLastValue) * ((currentFrame - lastKeyFrame) / 0.001);
       }
-
       return this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
     }
-
     function loopIn(type, duration, durationFlag) {
       if (!this.k) {
         return this.pv;
       }
-
       type = type ? type.toLowerCase() : '';
       var currentFrame = this.comp.renderedFrame;
       var keyframes = this.keyframes;
       var firstKeyFrame = keyframes[0].t;
-
       if (currentFrame >= firstKeyFrame) {
         return this.pv;
       }
-
       var cycleDuration;
       var lastKeyFrame;
-
       if (!durationFlag) {
         if (!duration || duration > keyframes.length - 1) {
           duration = keyframes.length - 1;
         }
-
         lastKeyFrame = keyframes[duration].t;
         cycleDuration = lastKeyFrame - firstKeyFrame;
       } else {
@@ -19362,17 +16423,13 @@
         } else {
           cycleDuration = Math.abs(this.elem.comp.globalData.frameRate * duration);
         }
-
         lastKeyFrame = firstKeyFrame + cycleDuration;
       }
-
       var i;
       var len;
       var ret;
-
       if (type === 'pingpong') {
         var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration);
-
         if (iterations % 2 === 0) {
           return this.getValueAtTime(((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
         }
@@ -19381,52 +16438,39 @@
         var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
         var current = this.getValueAtTime((cycleDuration - (firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0);
         var repeats = Math.floor((firstKeyFrame - currentFrame) / cycleDuration) + 1;
-
         if (this.pv.length) {
           ret = new Array(initV.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = current[i] - (endV[i] - initV[i]) * repeats;
           }
-
           return ret;
         }
-
         return current - (endV - initV) * repeats;
       } else if (type === 'continue') {
         var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
         var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0);
-
         if (this.pv.length) {
           ret = new Array(firstValue.length);
           len = ret.length;
-
           for (i = 0; i < len; i += 1) {
             ret[i] = firstValue[i] + (firstValue[i] - nextFirstValue[i]) * (firstKeyFrame - currentFrame) / 0.001;
           }
-
           return ret;
         }
-
         return firstValue + (firstValue - nextFirstValue) * (firstKeyFrame - currentFrame) / 0.001;
       }
-
       return this.getValueAtTime((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
     }
-
     function smooth(width, samples) {
       if (!this.k) {
         return this.pv;
       }
-
       width = (width || 0.4) * 0.5;
       samples = Math.floor(samples || 5);
-
       if (samples <= 1) {
         return this.pv;
       }
-
       var currentTime = this.comp.renderedFrame / this.comp.globalData.frameRate;
       var initFrame = currentTime - width;
       var endFrame = currentTime + width;
@@ -19434,18 +16478,14 @@
       var i = 0;
       var j = 0;
       var value;
-
       if (this.pv.length) {
         value = createTypedArray('float32', this.pv.length);
       } else {
         value = 0;
       }
-
       var sampleValue;
-
       while (i < samples) {
         sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency);
-
         if (this.pv.length) {
           for (j = 0; j < this.pv.length; j += 1) {
             value[j] += sampleValue[j];
@@ -19453,10 +16493,8 @@
         } else {
           value += sampleValue;
         }
-
         i += 1;
       }
-
       if (this.pv.length) {
         for (j = 0; j < this.pv.length; j += 1) {
           value[j] /= samples;
@@ -19464,37 +16502,30 @@
       } else {
         value /= samples;
       }
-
       return value;
     }
-
     function getTransformValueAtTime(time) {
       if (!this._transformCachingAtTime) {
         this._transformCachingAtTime = {
           v: new Matrix()
         };
-      } /// /
-
-
+      }
+      /// /
       var matrix = this._transformCachingAtTime.v;
       matrix.cloneFromProps(this.pre.props);
-
       if (this.appliedTransformations < 1) {
         var anchor = this.a.getValueAtTime(time);
         matrix.translate(-anchor[0] * this.a.mult, -anchor[1] * this.a.mult, anchor[2] * this.a.mult);
       }
-
       if (this.appliedTransformations < 2) {
         var scale = this.s.getValueAtTime(time);
         matrix.scale(scale[0] * this.s.mult, scale[1] * this.s.mult, scale[2] * this.s.mult);
       }
-
       if (this.sk && this.appliedTransformations < 3) {
         var skew = this.sk.getValueAtTime(time);
         var skewAxis = this.sa.getValueAtTime(time);
         matrix.skewFromAxis(-skew * this.sk.mult, skewAxis * this.sa.mult);
       }
-
       if (this.r && this.appliedTransformations < 4) {
         var rotation = this.r.getValueAtTime(time);
         matrix.rotate(-rotation * this.r.mult);
@@ -19505,11 +16536,9 @@
         var orientation = this.or.getValueAtTime(time);
         matrix.rotateZ(-rotationZ * this.rz.mult).rotateY(rotationY * this.ry.mult).rotateX(rotationX * this.rx.mult).rotateZ(-orientation[2] * this.or.mult).rotateY(orientation[1] * this.or.mult).rotateX(orientation[0] * this.or.mult);
       }
-
       if (this.data.p && this.data.p.s) {
         var positionX = this.px.getValueAtTime(time);
         var positionY = this.py.getValueAtTime(time);
-
         if (this.data.p.z) {
           var positionZ = this.pz.getValueAtTime(time);
           matrix.translate(positionX * this.px.mult, positionY * this.py.mult, -positionZ * this.pz.mult);
@@ -19520,42 +16549,34 @@
         var position = this.p.getValueAtTime(time);
         matrix.translate(position[0] * this.p.mult, position[1] * this.p.mult, -position[2] * this.p.mult);
       }
-
-      return matrix; /// /
+      return matrix;
+      /// /
     }
-
     function getTransformStaticValueAtTime() {
       return this.v.clone(new Matrix());
     }
-
     var getTransformProperty = TransformPropertyFactory.getTransformProperty;
-
     TransformPropertyFactory.getTransformProperty = function (elem, data, container) {
       var prop = getTransformProperty(elem, data, container);
-
       if (prop.dynamicProperties.length) {
         prop.getValueAtTime = getTransformValueAtTime.bind(prop);
       } else {
         prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop);
       }
-
       prop.setGroupProperty = expressionHelpers.setGroupProperty;
       return prop;
     };
-
     var propertyGetProp = PropertyFactory.getProp;
-
     PropertyFactory.getProp = function (elem, data, type, mult, container) {
-      var prop = propertyGetProp(elem, data, type, mult, container); // prop.getVelocityAtTime = getVelocityAtTime;
+      var prop = propertyGetProp(elem, data, type, mult, container);
+      // prop.getVelocityAtTime = getVelocityAtTime;
       // prop.loopOut = loopOut;
       // prop.loopIn = loopIn;
-
       if (prop.kf) {
         prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop);
       } else {
         prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop);
       }
-
       prop.setGroupProperty = expressionHelpers.setGroupProperty;
       prop.loopOut = loopOut;
       prop.loopIn = loopIn;
@@ -19565,25 +16586,20 @@
       prop.numKeys = data.a === 1 ? data.k.length : 0;
       prop.propertyIndex = data.ix;
       var value = 0;
-
       if (type !== 0) {
         value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length);
       }
-
       prop._cachingAtTime = {
         lastFrame: initialDefaultFrame,
         lastIndex: 0,
         value: value
       };
       expressionHelpers.searchExpressions(elem, data, prop);
-
       if (prop.k) {
         container.addDynamicProperty(prop);
       }
-
       return prop;
     };
-
     function getShapeValueAtTime(frameNum) {
       // For now this caching object is created only when needed instead of creating it when the shape is initialized.
       if (!this._cachingAtTime) {
@@ -19593,42 +16609,32 @@
           lastTime: initialDefaultFrame
         };
       }
-
       frameNum *= this.elem.globalData.frameRate;
       frameNum -= this.offsetTime;
-
       if (frameNum !== this._cachingAtTime.lastTime) {
         this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0;
         this._cachingAtTime.lastTime = frameNum;
         this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime);
       }
-
       return this._cachingAtTime.shapeValue;
     }
-
     var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction();
     var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction();
-
     function ShapeExpressions() {}
-
     ShapeExpressions.prototype = {
       vertices: function vertices(prop, time) {
         if (this.k) {
           this.getValue();
         }
-
         var shapePath = this.v;
-
         if (time !== undefined) {
           shapePath = this.getValueAtTime(time, 0);
         }
-
         var i;
         var len = shapePath._length;
         var vertices = shapePath[prop];
         var points = shapePath.v;
         var arr = createSizedArray(len);
-
         for (i = 0; i < len; i += 1) {
           if (prop === 'i' || prop === 'o') {
             arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]];
@@ -19636,7 +16642,6 @@
             arr[i] = [vertices[i][0], vertices[i][1]];
           }
         }
-
         return arr;
       },
       points: function points(time) {
@@ -19653,15 +16658,12 @@
       },
       pointOnPath: function pointOnPath(perc, time) {
         var shapePath = this.v;
-
         if (time !== undefined) {
           shapePath = this.getValueAtTime(time, 0);
         }
-
         if (!this._segmentsLength) {
           this._segmentsLength = bez.getSegmentsLength(shapePath);
         }
-
         var segmentsLength = this._segmentsLength;
         var lengths = segmentsLength.lengths;
         var lengthPos = segmentsLength.totalLength * perc;
@@ -19669,7 +16671,6 @@
         var len = lengths.length;
         var accumulatedLength = 0;
         var pt;
-
         while (i < len) {
           if (accumulatedLength + lengths[i].addedLength > lengthPos) {
             var initIndex = i;
@@ -19680,14 +16681,11 @@
           } else {
             accumulatedLength += lengths[i].addedLength;
           }
-
           i += 1;
         }
-
         if (!pt) {
           pt = shapePath.c ? [shapePath.v[0][0], shapePath.v[0][1]] : [shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1]];
         }
-
         return pt;
       },
       vectorOnPath: function vectorOnPath(perc, time, vectorType) {
@@ -19699,17 +16697,14 @@
           // eslint-disable-line eqeqeq
           perc = 0.999;
         }
-
         var pt1 = this.pointOnPath(perc, time);
         var pt2 = this.pointOnPath(perc + 0.001, time);
         var xLength = pt2[0] - pt1[0];
         var yLength = pt2[1] - pt1[1];
         var magnitude = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2));
-
         if (magnitude === 0) {
           return [0, 0];
         }
-
         var unitVector = vectorType === 'tangent' ? [xLength / magnitude, yLength / magnitude] : [-yLength / magnitude, xLength / magnitude];
         return unitVector;
       },
@@ -19727,26 +16722,21 @@
     KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime;
     KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression;
     var propertyGetShapeProp = ShapePropertyFactory.getShapeProp;
-
     ShapePropertyFactory.getShapeProp = function (elem, data, type, arr, trims) {
       var prop = propertyGetShapeProp(elem, data, type, arr, trims);
       prop.propertyIndex = data.ix;
       prop.lock = false;
-
       if (type === 3) {
         expressionHelpers.searchExpressions(elem, data.pt, prop);
       } else if (type === 4) {
         expressionHelpers.searchExpressions(elem, data.ks, prop);
       }
-
       if (prop.k) {
         elem.addDynamicProperty(prop);
       }
-
       return prop;
     };
   }
-
   function initialize$1() {
     addPropertyDecorator();
   }
@@ -19758,13 +16748,10 @@
         this.addEffect(this.getExpressionValue.bind(this));
         return true;
       }
-
       return null;
     }
-
     TextProperty.prototype.getExpressionValue = function (currentValue, text) {
       var newValue = this.calculateExpression(text);
-
       if (currentValue.t !== newValue) {
         var newData = {};
         this.copyData(newData, currentValue);
@@ -19772,46 +16759,38 @@
         newData.__complete = false;
         return newData;
       }
-
       return currentValue;
     };
-
     TextProperty.prototype.searchProperty = function () {
       var isKeyframed = this.searchKeyframes();
       var hasExpressions = this.searchExpressions();
       this.kf = isKeyframed || hasExpressions;
       return this.kf;
     };
-
     TextProperty.prototype.searchExpressions = searchExpressions;
   }
-
   function initialize() {
     addDecorator();
   }
 
   function SVGComposableEffect() {}
-
   SVGComposableEffect.prototype = {
     createMergeNode: function createMergeNode(resultId, ins) {
       var feMerge = createNS('feMerge');
       feMerge.setAttribute('result', resultId);
       var feMergeNode;
       var i;
-
       for (i = 0; i < ins.length; i += 1) {
         feMergeNode = createNS('feMergeNode');
         feMergeNode.setAttribute('in', ins[i]);
         feMerge.appendChild(feMergeNode);
         feMerge.appendChild(feMergeNode);
       }
-
       return feMerge;
     }
   };
 
   var linearFilterValue = '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0';
-
   function SVGTintFilter(filter, filterManager, elem, id, source) {
     this.filterManager = filterManager;
     var feColorMatrix = createNS('feColorMatrix');
@@ -19831,9 +16810,7 @@
     var feMerge = this.createMergeNode(id, [source, id + '_tint_1', id + '_tint_2']);
     filter.appendChild(feMerge);
   }
-
   extendPrototype([SVGComposableEffect], SVGTintFilter);
-
   SVGTintFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var colorBlack = this.filterManager.effectElements[0].p.v;
@@ -19854,7 +16831,6 @@
     filter.appendChild(feColorMatrix);
     this.matrixFilter = feColorMatrix;
   }
-
   SVGFillFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var color = this.filterManager.effectElements[2].p.v;
@@ -19869,14 +16845,12 @@
     this.elem = elem;
     this.paths = [];
   }
-
   SVGStrokeEffect.prototype.initialize = function () {
     var elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
     var path;
     var groupPath;
     var i;
     var len;
-
     if (this.filterManager.effectElements[1].p.v === 1) {
       len = this.elem.maskManager.masksProperties.length;
       i = 0;
@@ -19884,12 +16858,10 @@
       i = this.filterManager.effectElements[0].p.v - 1;
       len = i + 1;
     }
-
     groupPath = createNS('g');
     groupPath.setAttribute('fill', 'none');
     groupPath.setAttribute('stroke-linecap', 'round');
     groupPath.setAttribute('stroke-dashoffset', 1);
-
     for (i; i < len; i += 1) {
       path = createNS('path');
       groupPath.appendChild(path);
@@ -19898,7 +16870,6 @@
         m: i
       });
     }
-
     if (this.filterManager.effectElements[10].p.v === 3) {
       var mask = createNS('mask');
       var id = createElementID();
@@ -19908,54 +16879,43 @@
       this.elem.globalData.defs.appendChild(mask);
       var g = createNS('g');
       g.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
-
       while (elemChildren[0]) {
         g.appendChild(elemChildren[0]);
       }
-
       this.elem.layerElement.appendChild(g);
       this.masker = mask;
       groupPath.setAttribute('stroke', '#fff');
     } else if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
       if (this.filterManager.effectElements[10].p.v === 2) {
         elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
-
         while (elemChildren.length) {
           this.elem.layerElement.removeChild(elemChildren[0]);
         }
       }
-
       this.elem.layerElement.appendChild(groupPath);
       this.elem.layerElement.removeAttribute('mask');
       groupPath.setAttribute('stroke', '#fff');
     }
-
     this.initialized = true;
     this.pathMasker = groupPath;
   };
-
   SVGStrokeEffect.prototype.renderFrame = function (forceRender) {
     if (!this.initialized) {
       this.initialize();
     }
-
     var i;
     var len = this.paths.length;
     var mask;
     var path;
-
     for (i = 0; i < len; i += 1) {
       if (this.paths[i].m !== -1) {
         mask = this.elem.maskManager.viewData[this.paths[i].m];
         path = this.paths[i].p;
-
         if (forceRender || this.filterManager._mdf || mask.prop._mdf) {
           path.setAttribute('d', mask.lastPath);
         }
-
         if (forceRender || this.filterManager.effectElements[9].p._mdf || this.filterManager.effectElements[4].p._mdf || this.filterManager.effectElements[7].p._mdf || this.filterManager.effectElements[8].p._mdf || mask.prop._mdf) {
           var dasharrayValue;
-
           if (this.filterManager.effectElements[7].p.v !== 0 || this.filterManager.effectElements[8].p.v !== 100) {
             var s = Math.min(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
             var e = Math.max(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
@@ -19965,29 +16925,23 @@
             var segment = 1 + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
             var units = Math.floor(lineLength / segment);
             var j;
-
             for (j = 0; j < units; j += 1) {
               dasharrayValue += '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01 + ' ';
             }
-
             dasharrayValue += '0 ' + l * 10 + ' 0 0';
           } else {
             dasharrayValue = '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
           }
-
           path.setAttribute('stroke-dasharray', dasharrayValue);
         }
       }
     }
-
     if (forceRender || this.filterManager.effectElements[4].p._mdf) {
       this.pathMasker.setAttribute('stroke-width', this.filterManager.effectElements[4].p.v * 2);
     }
-
     if (forceRender || this.filterManager.effectElements[6].p._mdf) {
       this.pathMasker.setAttribute('opacity', this.filterManager.effectElements[6].p.v);
     }
-
     if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
       if (forceRender || this.filterManager.effectElements[3].p._mdf) {
         var color = this.filterManager.effectElements[3].p.v;
@@ -20021,7 +16975,6 @@
     this.feFuncB = feFuncB;
     filter.appendChild(feComponentTransfer);
   }
-
   SVGTritoneFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var color1 = this.filterManager.effectElements[0].p.v;
@@ -20039,33 +16992,29 @@
   function SVGProLevelsFilter(filter, filterManager, elem, id) {
     this.filterManager = filterManager;
     var effectElements = this.filterManager.effectElements;
-    var feComponentTransfer = createNS('feComponentTransfer'); // Red
+    var feComponentTransfer = createNS('feComponentTransfer');
 
+    // Red
     if (effectElements[10].p.k || effectElements[10].p.v !== 0 || effectElements[11].p.k || effectElements[11].p.v !== 1 || effectElements[12].p.k || effectElements[12].p.v !== 1 || effectElements[13].p.k || effectElements[13].p.v !== 0 || effectElements[14].p.k || effectElements[14].p.v !== 1) {
       this.feFuncR = this.createFeFunc('feFuncR', feComponentTransfer);
-    } // Green
-
-
+    }
+    // Green
     if (effectElements[17].p.k || effectElements[17].p.v !== 0 || effectElements[18].p.k || effectElements[18].p.v !== 1 || effectElements[19].p.k || effectElements[19].p.v !== 1 || effectElements[20].p.k || effectElements[20].p.v !== 0 || effectElements[21].p.k || effectElements[21].p.v !== 1) {
       this.feFuncG = this.createFeFunc('feFuncG', feComponentTransfer);
-    } // Blue
-
-
+    }
+    // Blue
     if (effectElements[24].p.k || effectElements[24].p.v !== 0 || effectElements[25].p.k || effectElements[25].p.v !== 1 || effectElements[26].p.k || effectElements[26].p.v !== 1 || effectElements[27].p.k || effectElements[27].p.v !== 0 || effectElements[28].p.k || effectElements[28].p.v !== 1) {
       this.feFuncB = this.createFeFunc('feFuncB', feComponentTransfer);
-    } // Alpha
-
-
+    }
+    // Alpha
     if (effectElements[31].p.k || effectElements[31].p.v !== 0 || effectElements[32].p.k || effectElements[32].p.v !== 1 || effectElements[33].p.k || effectElements[33].p.v !== 1 || effectElements[34].p.k || effectElements[34].p.v !== 0 || effectElements[35].p.k || effectElements[35].p.v !== 1) {
       this.feFuncA = this.createFeFunc('feFuncA', feComponentTransfer);
-    } // RGB
-
-
+    }
+    // RGB
     if (this.feFuncR || this.feFuncG || this.feFuncB || this.feFuncA) {
       feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
       filter.appendChild(feComponentTransfer);
     }
-
     if (effectElements[3].p.k || effectElements[3].p.v !== 0 || effectElements[4].p.k || effectElements[4].p.v !== 1 || effectElements[5].p.k || effectElements[5].p.v !== 1 || effectElements[6].p.k || effectElements[6].p.v !== 0 || effectElements[7].p.k || effectElements[7].p.v !== 1) {
       feComponentTransfer = createNS('feComponentTransfer');
       feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
@@ -20076,14 +17025,12 @@
       this.feFuncBComposed = this.createFeFunc('feFuncB', feComponentTransfer);
     }
   }
-
   SVGProLevelsFilter.prototype.createFeFunc = function (type, feComponentTransfer) {
     var feFunc = createNS(type);
     feFunc.setAttribute('type', 'table');
     feComponentTransfer.appendChild(feFunc);
     return feFunc;
   };
-
   SVGProLevelsFilter.prototype.getTableValue = function (inputBlack, inputWhite, gamma, outputBlack, outputWhite) {
     var cnt = 0;
     var segments = 256;
@@ -20097,10 +17044,8 @@
     var pos = 0;
     var outputDelta = outputWhite - outputBlack;
     var inputDelta = inputWhite - inputBlack;
-
     while (cnt <= 256) {
       perc = cnt / 256;
-
       if (perc <= min) {
         colorValue = inputDelta < 0 ? outputWhite : outputBlack;
       } else if (perc >= max) {
@@ -20108,42 +17053,34 @@
       } else {
         colorValue = outputBlack + outputDelta * Math.pow((perc - inputBlack) / inputDelta, 1 / gamma);
       }
-
       table[pos] = colorValue;
       pos += 1;
       cnt += 256 / (segments - 1);
     }
-
     return table.join(' ');
   };
-
   SVGProLevelsFilter.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       var val;
       var effectElements = this.filterManager.effectElements;
-
       if (this.feFuncRComposed && (forceRender || effectElements[3].p._mdf || effectElements[4].p._mdf || effectElements[5].p._mdf || effectElements[6].p._mdf || effectElements[7].p._mdf)) {
         val = this.getTableValue(effectElements[3].p.v, effectElements[4].p.v, effectElements[5].p.v, effectElements[6].p.v, effectElements[7].p.v);
         this.feFuncRComposed.setAttribute('tableValues', val);
         this.feFuncGComposed.setAttribute('tableValues', val);
         this.feFuncBComposed.setAttribute('tableValues', val);
       }
-
       if (this.feFuncR && (forceRender || effectElements[10].p._mdf || effectElements[11].p._mdf || effectElements[12].p._mdf || effectElements[13].p._mdf || effectElements[14].p._mdf)) {
         val = this.getTableValue(effectElements[10].p.v, effectElements[11].p.v, effectElements[12].p.v, effectElements[13].p.v, effectElements[14].p.v);
         this.feFuncR.setAttribute('tableValues', val);
       }
-
       if (this.feFuncG && (forceRender || effectElements[17].p._mdf || effectElements[18].p._mdf || effectElements[19].p._mdf || effectElements[20].p._mdf || effectElements[21].p._mdf)) {
         val = this.getTableValue(effectElements[17].p.v, effectElements[18].p.v, effectElements[19].p.v, effectElements[20].p.v, effectElements[21].p.v);
         this.feFuncG.setAttribute('tableValues', val);
       }
-
       if (this.feFuncB && (forceRender || effectElements[24].p._mdf || effectElements[25].p._mdf || effectElements[26].p._mdf || effectElements[27].p._mdf || effectElements[28].p._mdf)) {
         val = this.getTableValue(effectElements[24].p.v, effectElements[25].p.v, effectElements[26].p.v, effectElements[27].p.v, effectElements[28].p.v);
         this.feFuncB.setAttribute('tableValues', val);
       }
-
       if (this.feFuncA && (forceRender || effectElements[31].p._mdf || effectElements[32].p._mdf || effectElements[33].p._mdf || effectElements[34].p._mdf || effectElements[35].p._mdf)) {
         val = this.getTableValue(effectElements[31].p.v, effectElements[32].p.v, effectElements[33].p.v, effectElements[34].p.v, effectElements[35].p.v);
         this.feFuncA.setAttribute('tableValues', val);
@@ -20185,26 +17122,22 @@
     feComposite.setAttribute('result', id + '_drop_shadow_4');
     filter.appendChild(feComposite);
     var feMerge = this.createMergeNode(id, [id + '_drop_shadow_4', source]);
-    filter.appendChild(feMerge); //
+    filter.appendChild(feMerge);
+    //
   }
-
   extendPrototype([SVGComposableEffect], SVGDropShadowEffect);
-
   SVGDropShadowEffect.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       if (forceRender || this.filterManager.effectElements[4].p._mdf) {
         this.feGaussianBlur.setAttribute('stdDeviation', this.filterManager.effectElements[4].p.v / 4);
       }
-
       if (forceRender || this.filterManager.effectElements[0].p._mdf) {
         var col = this.filterManager.effectElements[0].p.v;
         this.feFlood.setAttribute('flood-color', rgbToHex(Math.round(col[0] * 255), Math.round(col[1] * 255), Math.round(col[2] * 255)));
       }
-
       if (forceRender || this.filterManager.effectElements[1].p._mdf) {
         this.feFlood.setAttribute('flood-opacity', this.filterManager.effectElements[1].p.v / 255);
       }
-
       if (forceRender || this.filterManager.effectElements[2].p._mdf || this.filterManager.effectElements[3].p._mdf) {
         var distance = this.filterManager.effectElements[3].p.v;
         var angle = (this.filterManager.effectElements[2].p.v - 90) * degToRads;
@@ -20217,7 +17150,6 @@
   };
 
   var _svgMatteSymbols = [];
-
   function SVGMatte3Effect(filterElem, filterManager, elem) {
     this.initialized = false;
     this.filterManager = filterManager;
@@ -20228,66 +17160,50 @@
     elem.matteElement.appendChild(elem.transformedElement);
     elem.baseElement = elem.matteElement;
   }
-
   SVGMatte3Effect.prototype.findSymbol = function (mask) {
     var i = 0;
     var len = _svgMatteSymbols.length;
-
     while (i < len) {
       if (_svgMatteSymbols[i] === mask) {
         return _svgMatteSymbols[i];
       }
-
       i += 1;
     }
-
     return null;
   };
-
   SVGMatte3Effect.prototype.replaceInParent = function (mask, symbolId) {
     var parentNode = mask.layerElement.parentNode;
-
     if (!parentNode) {
       return;
     }
-
     var children = parentNode.children;
     var i = 0;
     var len = children.length;
-
     while (i < len) {
       if (children[i] === mask.layerElement) {
         break;
       }
-
       i += 1;
     }
-
     var nextChild;
-
     if (i <= len - 2) {
       nextChild = children[i + 1];
     }
-
     var useElem = createNS('use');
     useElem.setAttribute('href', '#' + symbolId);
-
     if (nextChild) {
       parentNode.insertBefore(useElem, nextChild);
     } else {
       parentNode.appendChild(useElem);
     }
   };
-
   SVGMatte3Effect.prototype.setElementAsMask = function (elem, mask) {
     if (!this.findSymbol(mask)) {
       var symbolId = createElementID();
       var masker = createNS('mask');
       masker.setAttribute('id', mask.layerId);
       masker.setAttribute('mask-type', 'alpha');
-
       _svgMatteSymbols.push(mask);
-
       var defs = elem.globalData.defs;
       defs.appendChild(masker);
       var symbol = createNS('symbol');
@@ -20301,27 +17217,21 @@
       mask.data.hd = false;
       mask.show();
     }
-
     elem.setMatte(mask.layerId);
   };
-
   SVGMatte3Effect.prototype.initialize = function () {
     var ind = this.filterManager.effectElements[0].p.v;
     var elements = this.elem.comp.elements;
     var i = 0;
     var len = elements.length;
-
     while (i < len) {
       if (elements[i] && elements[i].data.ind === ind) {
         this.setElementAsMask(this.elem, elements[i]);
       }
-
       i += 1;
     }
-
     this.initialized = true;
   };
-
   SVGMatte3Effect.prototype.renderFrame = function () {
     if (!this.initialized) {
       this.initialize();
@@ -20340,36 +17250,34 @@
     filter.appendChild(feGaussianBlur);
     this.feGaussianBlur = feGaussianBlur;
   }
-
   SVGGaussianBlurEffect.prototype.renderFrame = function (forceRender) {
     if (forceRender || this.filterManager._mdf) {
       // Empirical value, matching AE's blur appearance.
       var kBlurrinessToSigma = 0.3;
-      var sigma = this.filterManager.effectElements[0].p.v * kBlurrinessToSigma; // Dimensions mapping:
+      var sigma = this.filterManager.effectElements[0].p.v * kBlurrinessToSigma;
+
+      // Dimensions mapping:
       //
       //   1 -> horizontal & vertical
       //   2 -> horizontal only
       //   3 -> vertical only
       //
-
       var dimensions = this.filterManager.effectElements[1].p.v;
       var sigmaX = dimensions == 3 ? 0 : sigma; // eslint-disable-line eqeqeq
-
       var sigmaY = dimensions == 2 ? 0 : sigma; // eslint-disable-line eqeqeq
 
-      this.feGaussianBlur.setAttribute('stdDeviation', sigmaX + ' ' + sigmaY); // Repeat edges mapping:
+      this.feGaussianBlur.setAttribute('stdDeviation', sigmaX + ' ' + sigmaY);
+
+      // Repeat edges mapping:
       //
       //   0 -> off -> duplicate
       //   1 -> on  -> wrap
-
       var edgeMode = this.filterManager.effectElements[2].p.v == 1 ? 'wrap' : 'duplicate'; // eslint-disable-line eqeqeq
-
       this.feGaussianBlur.setAttribute('edgeMode', edgeMode);
     }
   };
 
   function TransformEffect() {}
-
   TransformEffect.prototype.init = function (effectsManager) {
     this.effectsManager = effectsManager;
     this.type = effectTypes.TRANSFORM_EFFECT;
@@ -20378,11 +17286,9 @@
     this._mdf = false;
     this._opMdf = false;
   };
-
   TransformEffect.prototype.renderFrame = function (forceFrame) {
     this._opMdf = false;
     this._mdf = false;
-
     if (forceFrame || this.effectsManager._mdf) {
       var effectElements = this.effectsManager.effectElements;
       var anchor = effectElements[0].p.v;
@@ -20400,7 +17306,6 @@
       this.matrix.skewFromAxis(-skew * degToRads, (skewAxis + 90) * degToRads);
       this.matrix.translate(position[0], position[1], 0);
       this._mdf = true;
-
       if (this.opacity !== effectElements[8].p.v) {
         this.opacity = effectElements[8].p.v;
         this._opMdf = true;
@@ -20411,31 +17316,33 @@
   function SVGTransformEffect(_, filterManager) {
     this.init(filterManager);
   }
-
   extendPrototype([TransformEffect], SVGTransformEffect);
 
   function CVTransformEffect(effectsManager) {
     this.init(effectsManager);
   }
-
   extendPrototype([TransformEffect], CVTransformEffect);
 
+  // Registering renderers
   registerRenderer('canvas', CanvasRenderer);
   registerRenderer('html', HybridRenderer);
-  registerRenderer('svg', SVGRenderer); // Registering shape modifiers
+  registerRenderer('svg', SVGRenderer);
 
+  // Registering shape modifiers
   ShapeModifiers.registerModifier('tm', TrimModifier);
   ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
   ShapeModifiers.registerModifier('rp', RepeaterModifier);
   ShapeModifiers.registerModifier('rd', RoundCornersModifier);
   ShapeModifiers.registerModifier('zz', ZigZagModifier);
-  ShapeModifiers.registerModifier('op', OffsetPathModifier); // Registering expression plugin
+  ShapeModifiers.registerModifier('op', OffsetPathModifier);
 
+  // Registering expression plugin
   setExpressionsPlugin(Expressions);
   setExpressionInterfaces(getInterface);
   initialize$1();
-  initialize(); // Registering svg effects
+  initialize();
 
+  // Registering svg effects
   registerEffect$1(20, SVGTintFilter, true);
   registerEffect$1(21, SVGFillFilter, true);
   registerEffect$1(22, SVGStrokeEffect, false);
@@ -20450,7 +17357,7 @@
   return lottie;
 
 }));
-
+
 
 
     function addElementToList(element, list) {
@@ -20699,6 +17606,10 @@
       if (animations[payload.id]) {
         animations[payload.id].animation.playSegments(payload.arr, payload.forceFlag);
       }
+    } else if (type === 'resetSegments') {
+      if (animations[payload.id]) {
+        animations[payload.id].animation.resetSegments(payload.forceFlag);
+      }
     } else if (type === 'updateDocumentData') {
       animations[payload.id].animation.updateDocumentData(payload.path, payload.documentData, payload.index);
     }
diff --git a/build/player/lottie_worker.min.js b/build/player/lottie_worker.min.js
index 7ad99b4..03cb66c 100644
--- a/build/player/lottie_worker.min.js
+++ b/build/player/lottie_worker.min.js
@@ -10,6 +10,6 @@
         root.bodymovin = root.lottie;
     }
 }((self || {}), function(window) {
-	function workerContent(){function extendPrototype(t,e){var i,r,s=t.length;for(i=0;i<s;i+=1)for(var a in r=t[i].prototype)Object.prototype.hasOwnProperty.call(r,a)&&(e.prototype[a]=r[a])}function ProxyElement(t,e){this._state="init",this._isDirty=!1,this._isProxy=!0,this._changedStyles=[],this._changedAttributes=[],this._changedElements=[],this._textContent=null,this.type=t,this.namespace=e,this.children=[],localIdCounter+=1,this.attributes={id:"l_d_"+localIdCounter},this.style=new Style(this)}ProxyElement.prototype={appendChild:function(t){(t.parentNode=this).children.push(t),this._isDirty=!0,this._changedElements.push([t,this.attributes.id])},insertBefore:function(t,e){for(var i=this.children,r=0;r<i.length;r+=1)if(i[r]===e)return i.splice(r,0,t),this._isDirty=!0,void this._changedElements.push([t,this.attributes.id,e.attributes.id]);i.push(e)},setAttribute:function(t,e){this.attributes[t]=e,this._isDirty||(this._isDirty=!0),this._changedAttributes.push(t)},serialize:function(){return{type:this.type,namespace:this.namespace,style:this.style.serialize(),attributes:this.attributes,children:this.children.map(function(t){return t.serialize()}),textContent:this._textContent}},addEventListener:function(t,e){setTimeout(e,1)},setAttributeNS:function(t,e,i){this.attributes[e]=i,this._isDirty||(this._isDirty=!0),this._changedAttributes.push(e)}},Object.defineProperty(ProxyElement.prototype,"textContent",{set:function(t){this._isDirty=!0,this._textContent=t}});var localIdCounter=0,animations={},styleProperties=["width","height","display","transform","opacity","contentVisibility","mix-blend-mode"];function convertArguments(t){var e,i=[],r=t.length;for(e=0;e<r;e+=1)i.push(t[e]);return i}function Style(t){this.element=t}function CanvasContext(t){this.element=t}Style.prototype={serialize:function(){for(var t={},e=0;e<styleProperties.length;e+=1){var i=styleProperties[e],r="_"+i;r in this&&(t[i]=this[r])}return t}},styleProperties.forEach(function(e){Object.defineProperty(Style.prototype,e,{set:function(t){this.element._isDirty||(this.element._isDirty=!0),this.element._changedStyles.push(e),this["_"+e]=t},get:function(){return this["_"+e]}})}),CanvasContext.prototype={createRadialGradient:function(){var t={t:"rGradient",a:convertArguments(arguments),stops:[]};return this.element.instructions.push(t),{addColorStop:function(){t.stops.push(convertArguments(arguments))}}},createLinearGradient:function(){var t={t:"lGradient",a:convertArguments(arguments),stops:[]};return this.element.instructions.push(t),{addColorStop:function(){t.stops.push(convertArguments(arguments))}}}},Object.defineProperties(CanvasContext.prototype,{canvas:{enumerable:!0,get:function(){return this.element}}});var canvasContextMethods=["fillRect","setTransform","drawImage","beginPath","moveTo","save","restore","fillText","setLineDash","clearRect","clip","rect","stroke","fill","closePath","bezierCurveTo","lineTo"];canvasContextMethods.forEach(function(t){CanvasContext.prototype[t]=function(){this.element.instructions.push({t:t,a:convertArguments(arguments)})}});var canvasContextProperties=["globalAlpha","strokeStyle","fillStyle","lineCap","lineJoin","lineWidth","miterLimit","lineDashOffset","globalCompositeOperation"];function CanvasElement(t,e){ProxyElement.call(this,t,e),this.instructions=[],this.width=0,this.height=0,this.context=new CanvasContext(this)}function createElement(t,e){return"canvas"===e?new CanvasElement(e,t):new ProxyElement(e,t)}canvasContextProperties.forEach(function(e){Object.defineProperty(CanvasContext.prototype,e,{set:function(t){this.element.instructions.push({t:e,a:t})}})}),CanvasElement.prototype={getContext:function(){return this.context},resetInstructions:function(){this.instructions.length=0}},extendPrototype([ProxyElement],CanvasElement);var window=self,document={createElementNS:function(t,e){return createElement(t,e)},createElement:function(t){return createElement("",t)},getElementsByTagName:function(){return[]},body:createElement("","body"),_isProxy:!0},lottieInternal=function(){"use strict";var Y,Z;function addElementToList(t,e){e.push(t),t._isDirty=!1,t._changedStyles.length=0,t._changedAttributes.length=0,t._changedElements.length=0,t._textContent=null,t.children.forEach(function(t){addElementToList(t,e)})}function addChangedAttributes(t){for(var e,i=t._changedAttributes,r=[],s=0;s<i.length;s+=1)e=i[s],r.push([e,t.attributes[e]]);return r}function addChangedStyles(t){for(var e,i=t._changedStyles,r=[],s=0;s<i.length;s+=1)e=i[s],r.push([e,t.style[e]]);return r}function addChangedElements(t,e){for(var i,r=t._changedElements,s=[],a=0;a<r.length;a+=1)i=r[a],s.push([i[0].serialize(),i[1],i[2]]),addElementToList(i[0],e);return s}function loadAnimation(a){var e,t,i,r=a.params,n=[];if("svg"===r.renderer)e=document.createElement("div"),r.container=e;else{(i=r.rendererSettings.canvas)||((i=document.createElement("canvas")).width=r.animationData.w,i.height=r.animationData.h);var s=i.getContext("2d");r.rendererSettings.context=s}(t=lottie.loadAnimation(r)).addEventListener("error",function(t){console.log(t)}),t.onError=function(t){console.log("ERRORO",t)},t.addEventListener("_play",function(){self.postMessage({type:"playing",payload:{id:a.id}})}),t.addEventListener("_pause",function(){self.postMessage({type:"paused",payload:{id:a.id}})}),"svg"===r.renderer?(t.addEventListener("DOMLoaded",function(){var t=e.serialize();addElementToList(e,n),self.postMessage({type:"SVGloaded",payload:{id:a.id,tree:t.children[0]}})}),t.addEventListener("drawnFrame",function(t){for(var e,i=[],r=0;r<n.length;r+=1)if((e=n[r])._isDirty){var s={id:e.attributes.id,styles:addChangedStyles(e),attributes:addChangedAttributes(e),elements:addChangedElements(e,n),textContent:e._textContent||void 0};i.push(s),e._isDirty=!1,e._changedAttributes.length=0,e._changedStyles.length=0,e._changedElements.length=0,e._textContent=null}self.postMessage({type:"SVGupdated",payload:{elements:i,id:a.id,currentTime:t.currentTime}})})):i._isProxy&&t.addEventListener("drawnFrame",function(t){self.postMessage({type:"CanvasUpdated",payload:{instructions:i.instructions,id:a.id,currentTime:t.currentTime}}),i.resetInstructions()}),t.addEventListener("DOMLoaded",function(){self.postMessage({type:"DOMLoaded",payload:{id:a.id,totalFrames:t.totalFrames,frameRate:t.frameRate,firstFrame:t.firstFrame,currentFrame:t.currentFrame,playDirection:t.playDirection,isSubframeEnabled:t.isSubframeEnabled,currentRawFrame:t.currentRawFrame,timeCompleted:t.timeCompleted}})}),animations[a.id]={animation:t,events:{}}}return"undefined"!=typeof navigator&&(Y=this,Z=function(){var svgNS="http://www.w3.org/2000/svg",locationHref="",_useWebWorker=!1,initialDefaultFrame=-999999,setWebWorker=function(t){_useWebWorker=!!t},getWebWorker=function(){return _useWebWorker},setLocationHref=function(t){locationHref=t},getLocationHref=function(){return locationHref};function createTag(t){return document.createElement(t)}function extendPrototype(t,e){var i,r,s=t.length;for(i=0;i<s;i+=1)for(var a in r=t[i].prototype)Object.prototype.hasOwnProperty.call(r,a)&&(e.prototype[a]=r[a])}function getDescriptor(t,e){return Object.getOwnPropertyDescriptor(t,e)}function createProxyFunction(t){function e(){}return e.prototype=t,e}var audioControllerFactory=function(){function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].pause()},resume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].resume()},setRate:function(t){var e,i=this.audios.length;for(e=0;e<i;e+=1)this.audios[e].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){var t,e=this.audios.length;for(t=0;t<e;t+=1)this.audios[t].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}}(),createTypedArray=function(){function i(t,e){var i,r=0,s=[];switch(t){case"int16":case"uint8c":i=1;break;default:i=1.1}for(r=0;r<e;r+=1)s.push(i);return s}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(t,e){return"float32"===t?new Float32Array(e):"int16"===t?new Int16Array(e):"uint8c"===t?new Uint8ClampedArray(e):i(t,e)}:i}();function createSizedArray(t){return Array.apply(null,{length:t})}function _typeof$6(t){return(_typeof$6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var subframeEnabled=!0,expressionsPlugin=null,expressionsInterfaces=null,idPrefix$1="",isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),_shouldRoundValues=!1,bmPow=Math.pow,bmSqrt=Math.sqrt,bmFloor=Math.floor,bmMax=Math.max,bmMin=Math.min,BMMath={};function ProjectInterface$1(){return{}}!function(){var t,e=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],i=e.length;for(t=0;t<i;t+=1)BMMath[e[t]]=Math[e[t]]}(),BMMath.random=Math.random,BMMath.abs=function(t){if("object"===_typeof$6(t)&&t.length){var e,i=createSizedArray(t.length),r=t.length;for(e=0;e<r;e+=1)i[e]=Math.abs(t[e]);return i}return Math.abs(t)};var defaultCurveSegments=150,degToRads=Math.PI/180,roundCorner=.5519;function roundValues(t){_shouldRoundValues=!!t}function bmRnd(t){return _shouldRoundValues?Math.round(t):t}function styleDiv(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin="0 0",t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility="visible",t.style.webkitBackfaceVisibility="visible",t.style.transformStyle="preserve-3d",t.style.webkitTransformStyle="preserve-3d",t.style.mozTransformStyle="preserve-3d"}function BMEnterFrameEvent(t,e,i,r){this.type=t,this.currentTime=e,this.totalTime=i,this.direction=r<0?-1:1}function BMCompleteEvent(t,e){this.type=t,this.direction=e<0?-1:1}function BMCompleteLoopEvent(t,e,i,r){this.type=t,this.currentLoop=i,this.totalLoops=e,this.direction=r<0?-1:1}function BMSegmentStartEvent(t,e,i){this.type=t,this.firstFrame=e,this.totalFrames=i}function BMDestroyEvent(t,e){this.type=t,this.target=e}function BMRenderFrameErrorEvent(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function BMConfigErrorEvent(t){this.type="configError",this.nativeError=t}function BMAnimationConfigErrorEvent(t,e){this.type=t,this.nativeError=e}var createElementID=(Nb=0,function(){return idPrefix$1+"__lottie_element_"+(Nb+=1)}),Nb;function HSVtoRGB(t,e,i){var r,s,a,n,o,h,l,p;switch(h=i*(1-e),l=i*(1-(o=6*t-(n=Math.floor(6*t)))*e),p=i*(1-(1-o)*e),n%6){case 0:r=i,s=p,a=h;break;case 1:r=l,s=i,a=h;break;case 2:r=h,s=i,a=p;break;case 3:r=h,s=l,a=i;break;case 4:r=p,s=h,a=i;break;case 5:r=i,s=h,a=l}return[r,s,a]}function RGBtoHSV(t,e,i){var r,s=Math.max(t,e,i),a=Math.min(t,e,i),n=s-a,o=0===s?0:n/s,h=s/255;switch(s){case a:r=0;break;case t:r=e-i+n*(e<i?6:0),r/=6*n;break;case e:r=i-t+2*n,r/=6*n;break;case i:r=t-e+4*n,r/=6*n}return[r,o,h]}function addSaturationToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[1]+=e,1<i[1]?i[1]=1:i[1]<=0&&(i[1]=0),HSVtoRGB(i[0],i[1],i[2])}function addBrightnessToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[2]+=e,1<i[2]?i[2]=1:i[2]<0&&(i[2]=0),HSVtoRGB(i[0],i[1],i[2])}function addHueToRGB(t,e){var i=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return i[0]+=e/360,1<i[0]?i[0]-=1:i[0]<0&&(i[0]+=1),HSVtoRGB(i[0],i[1],i[2])}var rgbToHex=function(){var t,e,r=[];for(t=0;t<256;t+=1)e=t.toString(16),r[t]=1===e.length?"0"+e:e;return function(t,e,i){return t<0&&(t=0),e<0&&(e=0),i<0&&(i=0),"#"+r[t]+r[e]+r[i]}}(),setSubframeEnabled=function(t){subframeEnabled=!!t},getSubframeEnabled=function(){return subframeEnabled},setExpressionsPlugin=function(t){expressionsPlugin=t},getExpressionsPlugin=function(){return expressionsPlugin},setExpressionInterfaces=function(t){expressionsInterfaces=t},getExpressionInterfaces=function(){return expressionsInterfaces},setDefaultCurveSegments=function(t){defaultCurveSegments=t},getDefaultCurveSegments=function(){return defaultCurveSegments},setIdPrefix=function(t){idPrefix$1=t},getIdPrefix=function(){return idPrefix$1};function createNS(t){return document.createElementNS(svgNS,t)}function _typeof$5(t){return(_typeof$5="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var dataManager=function(){var r,s,a=1,n=[],o={onmessage:function(){},postMessage:function(t){r({data:t})}},i={postMessage:function(t){o.onmessage({data:t})}};function h(){s||((s=function(t){if(window.Worker&&window.Blob&&getWebWorker()){var e=new Blob(["var _workerSelf = self; self.onmessage = ",t.toString()],{type:"text/javascript"}),i=URL.createObjectURL(e);return new Worker(i)}return r=t,o}(function(e){if(i.dataManager||(i.dataManager=function(){function f(t,e){var i,r,s,a,n,o,h,l=t.length;for(r=0;r<l;r+=1)if("ks"in(i=t[r])&&!i.completed){if(i.completed=!0,i.hasMask){var p=i.masksProperties;for(a=p.length,s=0;s<a;s+=1)if(p[s].pt.k.i)d(p[s].pt.k);else for(o=p[s].pt.k.length,n=0;n<o;n+=1)p[s].pt.k[n].s&&d(p[s].pt.k[n].s[0]),p[s].pt.k[n].e&&d(p[s].pt.k[n].e[0])}0===i.ty?(i.layers=m(i.refId,e),f(i.layers,e)):4===i.ty?c(i.shapes):5===i.ty&&(0===(h=i).t.a.length&&h.t.p)}}function m(t,e){var i=function(t,e){for(var i=0,r=e.length;i<r;){if(e[i].id===t)return e[i];i+=1}return null}(t,e);return i?i.layers.__used?JSON.parse(JSON.stringify(i.layers)):(i.layers.__used=!0,i.layers):null}function c(t){var e,i,r;for(e=t.length-1;0<=e;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)d(t[e].ks.k);else for(r=t[e].ks.k.length,i=0;i<r;i+=1)t[e].ks.k[i].s&&d(t[e].ks.k[i].s[0]),t[e].ks.k[i].e&&d(t[e].ks.k[i].e[0]);else"gr"===t[e].ty&&c(t[e].it)}function d(t){var e,i=t.i.length;for(e=0;e<i;e+=1)t.i[e][0]+=t.v[e][0],t.i[e][1]+=t.v[e][1],t.o[e][0]+=t.v[e][0],t.o[e][1]+=t.v[e][1]}function n(t,e){var i=e?e.split("."):[100,100,100];return t[0]>i[0]||!(i[0]>t[0])&&(t[1]>i[1]||!(i[1]>t[1])&&(t[2]>i[2]||!(i[2]>t[2])&&null))}var s,e=function(){var r=[4,4,14];function s(t){var e,i,r,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(i=t[e],r=i.t.d,i.t.d={k:[{s:r,t:0}]})}return function(t){if(n(r,t.v)&&(s(t.layers),t.assets)){var e,i=t.assets.length;for(e=0;e<i;e+=1)t.assets[e].layers&&s(t.assets[e].layers)}}}(),i=(s=[4,7,99],function(t){if(t.chars&&!n(s,t.v)){var e,i=t.chars.length;for(e=0;e<i;e+=1){var r=t.chars[e];r.data&&r.data.shapes&&(c(r.data.shapes),r.data.ip=0,r.data.op=99999,r.data.st=0,r.data.sr=1,r.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[e].t||(r.data.shapes.push({ty:"no"}),r.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}}}),r=function(){var r=[5,7,15];function s(t){var e,i,r,s=t.length;for(e=0;e<s;e+=1)5===t[e].ty&&(i=t[e],r=void 0,"number"==typeof(r=i.t.p).a&&(r.a={a:0,k:r.a}),"number"==typeof r.p&&(r.p={a:0,k:r.p}),"number"==typeof r.r&&(r.r={a:0,k:r.r}))}return function(t){if(n(r,t.v)&&(s(t.layers),t.assets)){var e,i=t.assets.length;for(e=0;e<i;e+=1)t.assets[e].layers&&s(t.assets[e].layers)}}}(),a=function(){var r=[4,1,9];function a(t){var e,i,r,s=t.length;for(e=0;e<s;e+=1)if("gr"===t[e].ty)a(t[e].it);else if("fl"===t[e].ty||"st"===t[e].ty)if(t[e].c.k&&t[e].c.k[0].i)for(r=t[e].c.k.length,i=0;i<r;i+=1)t[e].c.k[i].s&&(t[e].c.k[i].s[0]/=255,t[e].c.k[i].s[1]/=255,t[e].c.k[i].s[2]/=255,t[e].c.k[i].s[3]/=255),t[e].c.k[i].e&&(t[e].c.k[i].e[0]/=255,t[e].c.k[i].e[1]/=255,t[e].c.k[i].e[2]/=255,t[e].c.k[i].e[3]/=255);else t[e].c.k[0]/=255,t[e].c.k[1]/=255,t[e].c.k[2]/=255,t[e].c.k[3]/=255}function s(t){var e,i=t.length;for(e=0;e<i;e+=1)4===t[e].ty&&a(t[e].shapes)}return function(t){if(n(r,t.v)&&(s(t.layers),t.assets)){var e,i=t.assets.length;for(e=0;e<i;e+=1)t.assets[e].layers&&s(t.assets[e].layers)}}}(),o=function(){var r=[4,4,18];function l(t){var e,i,r;for(e=t.length-1;0<=e;e-=1)if("sh"===t[e].ty)if(t[e].ks.k.i)t[e].ks.k.c=t[e].closed;else for(r=t[e].ks.k.length,i=0;i<r;i+=1)t[e].ks.k[i].s&&(t[e].ks.k[i].s[0].c=t[e].closed),t[e].ks.k[i].e&&(t[e].ks.k[i].e[0].c=t[e].closed);else"gr"===t[e].ty&&l(t[e].it)}function s(t){var e,i,r,s,a,n,o=t.length;for(i=0;i<o;i+=1){if((e=t[i]).hasMask){var h=e.masksProperties;for(s=h.length,r=0;r<s;r+=1)if(h[r].pt.k.i)h[r].pt.k.c=h[r].cl;else for(n=h[r].pt.k.length,a=0;a<n;a+=1)h[r].pt.k[a].s&&(h[r].pt.k[a].s[0].c=h[r].cl),h[r].pt.k[a].e&&(h[r].pt.k[a].e[0].c=h[r].cl)}4===e.ty&&l(e.shapes)}}return function(t){if(n(r,t.v)&&(s(t.layers),t.assets)){var e,i=t.assets.length;for(e=0;e<i;e+=1)t.assets[e].layers&&s(t.assets[e].layers)}}}();var t={};return t.completeData=function(t){t.__complete||(a(t),e(t),i(t),r(t),o(t),f(t.layers,t.assets),function(t,e){if(t){var i=0,r=t.length;for(i=0;i<r;i+=1)1===t[i].t&&(t[i].data.layers=m(t[i].data.refId,e),f(t[i].data.layers,e))}}(t.chars,t.assets),t.__complete=!0)},t.checkColors=a,t.checkChars=i,t.checkPathProperties=r,t.checkShapes=o,t.completeLayers=f,t}()),i.assetLoader||(i.assetLoader=function(){function n(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")?t.response:t.response&&"object"===_typeof$5(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}return{load:function(e,i,t,r){var s,a=new XMLHttpRequest;try{a.responseType="json"}catch(t){}a.onreadystatechange=function(){if(4===a.readyState)if(200===a.status)s=n(a),t(s);else try{s=n(a),t(s)}catch(t){r&&r(t)}};try{a.open(["G","E","T"].join(""),e,!0)}catch(t){a.open(["G","E","T"].join(""),i+"/"+e,!0)}a.send()}}}()),"loadAnimation"===e.data.type)i.assetLoader.load(e.data.path,e.data.fullPath,function(t){i.dataManager.completeData(t),i.postMessage({id:e.data.id,payload:t,status:"success"})},function(){i.postMessage({id:e.data.id,status:"error"})});else if("complete"===e.data.type){var t=e.data.animation;i.dataManager.completeData(t),i.postMessage({id:e.data.id,payload:t,status:"success"})}else"loadData"===e.data.type&&i.assetLoader.load(e.data.path,e.data.fullPath,function(t){i.postMessage({id:e.data.id,payload:t,status:"success"})},function(){i.postMessage({id:e.data.id,status:"error"})})})).onmessage=function(t){var e=t.data,i=e.id,r=n[i];n[i]=null,"success"===e.status?r.onComplete(e.payload):r.onError&&r.onError()})}function l(t,e){var i="processId_"+(a+=1);return n[i]={onComplete:t,onError:e},i}return{loadAnimation:function(t,e,i){h();var r=l(e,i);s.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:r})},loadData:function(t,e,i){h();var r=l(e,i);s.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:r})},completeAnimation:function(t,e,i){h();var r=l(e,i);s.postMessage({type:"complete",animation:t,id:r})}}}(),ImagePreloader=function(){var s=function(){var t=createTag("canvas");t.width=1,t.height=1;var e=t.getContext("2d");return e.fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1),t}();function t(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function e(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function a(t,e,i){var r="";if(t.e)r=t.p;else if(e){var s=t.p;-1!==s.indexOf("images/")&&(s=s.split("/")[1]),r=e+s}else r=i,r+=t.u?t.u:"",r+=t.p;return r}function i(){this._imageLoaded=t.bind(this),this._footageLoaded=e.bind(this),this.testImageLoaded=function(t){var e=0,i=setInterval(function(){(t.getBBox().width||500<e)&&(this._imageLoaded(),clearInterval(i)),e+=1}.bind(this),50)}.bind(this),this.createFootageData=function(t){var e={assetData:t},i=a(t,this.assetsPath,this.path);return dataManager.loadData(i,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return i.prototype={loadAssets:function(t,e){var i;this.imagesLoadedCb=e;var r=t.length;for(i=0;i<r;i+=1)t[i].layers||(t[i].t&&"seq"!==t[i].t?3===t[i].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[i]))):(this.totalImages+=1,this.images.push(this._createImageData(t[i]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,i=this.images.length;e<i;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(t){var e=a(t,this.assetsPath,this.path),i=createTag("img");i.crossOrigin="anonymous",i.addEventListener("load",this._imageLoaded,!1),i.addEventListener("error",function(){r.img=s,this._imageLoaded()}.bind(this),!1),i.src=e;var r={img:i,assetData:t};return r},createImageData:function(t){var e=a(t,this.assetsPath,this.path),i=createNS("image");isSafari?this.testImageLoaded(i):i.addEventListener("load",this._imageLoaded,!1),i.addEventListener("error",function(){r.img=s,this._imageLoaded()}.bind(this),!1),i.setAttributeNS("http://www.w3.org/1999/xlink","href",e),this._elementHelper.append?this._elementHelper.append(i):this._elementHelper.appendChild(i);var r={img:i,assetData:t};return r},imageLoaded:t,footageLoaded:e,setCacheType:function(t,e){this._createImageData="svg"===t?(this._elementHelper=e,this.createImageData.bind(this)):this.createImgData.bind(this)}},i}();function BaseEvent(){}BaseEvent.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var i=this._cbs[t],r=0;r<i.length;r+=1)i[r](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var i=0,r=this._cbs[t].length;i<r;)this._cbs[t][i]===e&&(this._cbs[t].splice(i,1),i-=1,r-=1),i+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var markerParser=function(){function a(t){for(var e,i=t.split("\r\n"),r={},s=0,a=0;a<i.length;a+=1)2===(e=i[a].split(":")).length&&(r[e[0]]=e[1].trim(),s+=1);if(0===s)throw new Error;return r}return function(e){for(var t=[],i=0;i<e.length;i+=1){var r=e[i],s={time:r.tm,duration:r.dr};try{s.payload=JSON.parse(e[i].cm)}catch(t){try{s.payload=a(e[i].cm)}catch(t){s.payload={name:e[i].cm}}}t.push(s)}return t}}(),ProjectInterface=function(){function e(t){this.compositions.push(t)}return function(){function t(t){for(var e=0,i=this.compositions.length;e<i;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return t.compositions=[],t.currentFrame=0,t.registerComposition=e,t}}(),renderers={},registerRenderer=function(t,e){renderers[t]=e};function getRenderer(t){return renderers[t]}function getRegisteredRenderer(){if(renderers.canvas)return"canvas";for(var t in renderers)if(renderers[t])return t;return""}function _typeof$4(t){return(_typeof$4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var AnimationItem=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=createElementID(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=getSubframeEnabled(),this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=ProjectInterface(),this.imagePreloader=new ImagePreloader,this.audioController=audioControllerFactory(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new BMEnterFrameEvent("drawnFrame",0,0,0),this.expressionsPlugin=getExpressionsPlugin()};extendPrototype([BaseEvent],AnimationItem),AnimationItem.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg";t.animType?e=t.animType:t.renderer&&(e=t.renderer);var i=getRenderer(e);this.renderer=new i(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null===t.loop||void 0===t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name?t.name:"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),dataManager.loadAnimation(t.path,this.configAnimation,this.onSetupError))},AnimationItem.prototype.onSetupError=function(){this.trigger("data_failed")},AnimationItem.prototype.setupAnimation=function(t){dataManager.completeAnimation(t,this.configAnimation)},AnimationItem.prototype.setData=function(t,e){e&&"object"!==_typeof$4(e)&&(e=JSON.parse(e));var i={wrapper:t,animationData:e},r=t.attributes;i.path=r.getNamedItem("data-animation-path")?r.getNamedItem("data-animation-path").value:r.getNamedItem("data-bm-path")?r.getNamedItem("data-bm-path").value:r.getNamedItem("bm-path")?r.getNamedItem("bm-path").value:"",i.animType=r.getNamedItem("data-anim-type")?r.getNamedItem("data-anim-type").value:r.getNamedItem("data-bm-type")?r.getNamedItem("data-bm-type").value:r.getNamedItem("bm-type")?r.getNamedItem("bm-type").value:r.getNamedItem("data-bm-renderer")?r.getNamedItem("data-bm-renderer").value:r.getNamedItem("bm-renderer")?r.getNamedItem("bm-renderer").value:getRegisteredRenderer()||"canvas";var s=r.getNamedItem("data-anim-loop")?r.getNamedItem("data-anim-loop").value:r.getNamedItem("data-bm-loop")?r.getNamedItem("data-bm-loop").value:r.getNamedItem("bm-loop")?r.getNamedItem("bm-loop").value:"";"false"===s?i.loop=!1:"true"===s?i.loop=!0:""!==s&&(i.loop=parseInt(s,10));var a=r.getNamedItem("data-anim-autoplay")?r.getNamedItem("data-anim-autoplay").value:r.getNamedItem("data-bm-autoplay")?r.getNamedItem("data-bm-autoplay").value:!r.getNamedItem("bm-autoplay")||r.getNamedItem("bm-autoplay").value;i.autoplay="false"!==a,i.name=r.getNamedItem("data-name")?r.getNamedItem("data-name").value:r.getNamedItem("data-bm-name")?r.getNamedItem("data-bm-name").value:r.getNamedItem("bm-name")?r.getNamedItem("bm-name").value:"","false"===(r.getNamedItem("data-anim-prerender")?r.getNamedItem("data-anim-prerender").value:r.getNamedItem("data-bm-prerender")?r.getNamedItem("data-bm-prerender").value:r.getNamedItem("bm-prerender")?r.getNamedItem("bm-prerender").value:"")&&(i.prerender=!1),i.path?this.setParams(i):this.trigger("destroy")},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));var e,i,r=this.animationData.layers,s=r.length,a=t.layers,n=a.length;for(i=0;i<n;i+=1)for(e=0;e<s;){if(r[e].id===a[i].id){r[e]=a[i];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(s=t.assets.length,e=0;e<s;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,dataManager.completeAnimation(this.animationData,this.onSegmentComplete)},AnimationItem.prototype.onSegmentComplete=function(t){this.animationData=t;var e=getExpressionsPlugin();e&&e.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;if(!t||0===t.length||!this.autoloadSegments)return this.trigger("data_ready"),void(this.timeCompleted=this.totalFrames);var e=t.shift();this.timeCompleted=e.time*this.frameRate;var i=this.path+this.fileName+"_"+this.segmentPos+".json";this.segmentPos+=1,dataManager.loadData(i,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},AnimationItem.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},AnimationItem.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=markerParser(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},AnimationItem.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},AnimationItem.prototype.checkLoaded=function(){if(!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()){this.isLoaded=!0;var t=getExpressionsPlugin();t&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay&&this.play()}},AnimationItem.prototype.resize=function(t,e){var i="number"==typeof t?t:void 0,r="number"==typeof e?e:void 0;this.renderer.updateContainerSize(i,r)},AnimationItem.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},AnimationItem.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},AnimationItem.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},AnimationItem.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle&&(this._idle=!1,this.trigger("_active")))},AnimationItem.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},AnimationItem.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.getMarkerData=function(t){for(var e,i=0;i<this.markers.length;i+=1)if((e=this.markers[i]).payload&&e.payload.name===t)return e;return null},AnimationItem.prototype.goToAndStop=function(t,e,i){if(!i||this.name===i){var r=Number(t);if(isNaN(r)){var s=this.getMarkerData(t);s&&this.goToAndStop(s.time,!0)}else e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier);this.pause()}},AnimationItem.prototype.goToAndPlay=function(t,e,i){if(!i||this.name===i){var r=Number(t);if(isNaN(r)){var s=this.getMarkerData(t);s&&(s.duration?this.playSegments([s.time,s.time+s.duration],!0):this.goToAndStop(s.time,!0))}else this.goToAndStop(r,e,i);this.play()}},AnimationItem.prototype.advanceTime=function(t){if(!0!==this.isPaused&&!1!==this.isLoaded){var e=this.currentRawFrame+t*this.frameModifier,i=!1;e>=this.totalFrames-1&&0<this.frameModifier?this.loop&&this.playCount!==this.loop?e>=this.totalFrames?(this.playCount+=1,this.checkSegments(e%this.totalFrames)||(this.setCurrentRawFrameValue(e%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(e):this.checkSegments(e>this.totalFrames?e%this.totalFrames:0)||(i=!0,e=this.totalFrames-1):e<0?this.checkSegments(e%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(i=!0,e=0):(this.setCurrentRawFrameValue(this.totalFrames+e%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(e),i&&(this.setCurrentRawFrameValue(e),this.pause(),this.trigger("complete"))}},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(0<this.frameModifier&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var i=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?i=t:this.currentRawFrame+this.firstFrame>e&&(i=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==i&&this.goToAndStop(i,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===_typeof$4(t[0])){var i,r=t.length;for(i=0;i<r;i+=1)this.segments.push(t[i])}else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},AnimationItem.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},AnimationItem.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},AnimationItem.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},AnimationItem.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},AnimationItem.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},AnimationItem.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},AnimationItem.prototype.setLoop=function(t){this.loop=t},AnimationItem.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},AnimationItem.prototype.getVolume=function(){return this.audioController.getVolume()},AnimationItem.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},AnimationItem.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},AnimationItem.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},AnimationItem.prototype.getPath=function(){return this.path},AnimationItem.prototype.getAssetsPath=function(t){var e="";if(t.e)e=t.p;else if(this.assetsPath){var i=t.p;-1!==i.indexOf("images/")&&(i=i.split("/")[1]),e=this.assetsPath+i}else e=this.path,e+=t.u?t.u:"",e+=t.p;return e},AnimationItem.prototype.getAssetData=function(t){for(var e=0,i=this.assets.length;e<i;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},AnimationItem.prototype.hide=function(){this.renderer.hide()},AnimationItem.prototype.show=function(){this.renderer.show()},AnimationItem.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},AnimationItem.prototype.updateDocumentData=function(t,e,i){try{this.renderer.getElementByPath(t).updateDocumentData(e,i)}catch(t){}},AnimationItem.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new BMCompleteEvent(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new BMDestroyEvent(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new BMCompleteEvent(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new BMDestroyEvent(t,this))},AnimationItem.prototype.triggerRenderFrameError=function(t){var e=new BMRenderFrameErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)},AnimationItem.prototype.triggerConfigError=function(t){var e=new BMConfigErrorEvent(t,this.currentFrame);this.triggerEvent("error",e),this.onError&&this.onError.call(this,e)};var animationManager=function(){var t={},s=[],r=0,a=0,n=0,o=!0,h=!1;function i(t){for(var e=0,i=t.target;e<a;)s[e].animation===i&&(s.splice(e,1),e-=1,a-=1,i.isPaused||f()),e+=1}function l(t,e){if(!t)return null;for(var i=0;i<a;){if(s[i].elem===t&&null!==s[i].elem)return s[i].animation;i+=1}var r=new AnimationItem;return m(r,t),r.setData(t,e),r}function p(){n+=1,d()}function f(){n-=1}function m(t,e){t.addEventListener("destroy",i),t.addEventListener("_active",p),t.addEventListener("_idle",f),s.push({elem:e,animation:t}),a+=1}function c(t){var e,i=t-r;for(e=0;e<a;e+=1)s[e].animation.advanceTime(i);r=t,n&&!h?window.requestAnimationFrame(c):o=!0}function e(t){r=t,window.requestAnimationFrame(c)}function d(){!h&&n&&o&&(window.requestAnimationFrame(e),o=!1)}return t.registerAnimation=l,t.loadAnimation=function(t){var e=new AnimationItem;return m(e,null),e.setParams(t),e},t.setSpeed=function(t,e){var i;for(i=0;i<a;i+=1)s[i].animation.setSpeed(t,e)},t.setDirection=function(t,e){var i;for(i=0;i<a;i+=1)s[i].animation.setDirection(t,e)},t.play=function(t){var e;for(e=0;e<a;e+=1)s[e].animation.play(t)},t.pause=function(t){var e;for(e=0;e<a;e+=1)s[e].animation.pause(t)},t.stop=function(t){var e;for(e=0;e<a;e+=1)s[e].animation.stop(t)},t.togglePause=function(t){var e;for(e=0;e<a;e+=1)s[e].animation.togglePause(t)},t.searchAnimations=function(t,e,i){var r,s=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),a=s.length;for(r=0;r<a;r+=1)i&&s[r].setAttribute("data-bm-type",i),l(s[r],t);if(e&&0===a){i||(i="svg");var n=document.getElementsByTagName("body")[0];n.innerText="";var o=createTag("div");o.style.width="100%",o.style.height="100%",o.setAttribute("data-bm-type",i),n.appendChild(o),l(o,t)}},t.resize=function(){var t;for(t=0;t<a;t+=1)s[t].animation.resize()},t.goToAndStop=function(t,e,i){var r;for(r=0;r<a;r+=1)s[r].animation.goToAndStop(t,e,i)},t.destroy=function(t){var e;for(e=a-1;0<=e;e-=1)s[e].animation.destroy(t)},t.freeze=function(){h=!0},t.unfreeze=function(){h=!1,d()},t.setVolume=function(t,e){var i;for(i=0;i<a;i+=1)s[i].animation.setVolume(t,e)},t.mute=function(t){var e;for(e=0;e<a;e+=1)s[e].animation.mute(t)},t.unmute=function(t){var e;for(e=0;e<a;e+=1)s[e].animation.unmute(t)},t.getRegisteredAnimations=function(){var t,e=s.length,i=[];for(t=0;t<e;t+=1)i.push(s[t].animation);return i},t}(),BezierFactory=function(){var t={getBezierEasing:function(t,e,i,r,s){var a=s||("bez_"+t+"_"+e+"_"+i+"_"+r).replace(/\./g,"p");if(o[a])return o[a];var n=new h([t,e,i,r]);return o[a]=n}},o={};var l=11,p=1/(l-1),e="function"==typeof Float32Array;function r(t,e){return 1-3*e+3*t}function s(t,e){return 3*e-6*t}function a(t){return 3*t}function f(t,e,i){return((r(e,i)*t+s(e,i))*t+a(e))*t}function m(t,e,i){return 3*r(e,i)*t*t+2*s(e,i)*t+a(e)}function h(t){this._p=t,this._mSampleValues=e?new Float32Array(l):new Array(l),this._precomputed=!1,this.get=this.get.bind(this)}return h.prototype={get:function(t){var e=this._p[0],i=this._p[1],r=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===i&&r===s?t:0===t?0:1===t?1:f(this._getTForX(t),i,s)},_precompute:function(){var t=this._p[0],e=this._p[1],i=this._p[2],r=this._p[3];this._precomputed=!0,t===e&&i===r||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],i=0;i<l;++i)this._mSampleValues[i]=f(i*p,t,e)},_getTForX:function(t){for(var e=this._p[0],i=this._p[2],r=this._mSampleValues,s=0,a=1,n=l-1;a!==n&&r[a]<=t;++a)s+=p;var o=s+(t-r[--a])/(r[a+1]-r[a])*p,h=m(o,e,i);return.001<=h?function(t,e,i,r){for(var s=0;s<4;++s){var a=m(e,i,r);if(0===a)return e;e-=(f(e,i,r)-t)/a}return e}(t,o,e,i):0===h?o:function(t,e,i,r,s){for(var a,n,o=0;0<(a=f(n=e+(i-e)/2,r,s)-t)?i=n:e=n,1e-7<Math.abs(a)&&++o<10;);return n}(t,s,s+p,e,i)}},t}(),pooling={double:function(t){return t.concat(createSizedArray(t.length))}},poolFactory=function(t,e,i){var r=0,s=t,a=createSizedArray(s);return{newElement:function(){return r?a[r-=1]:e()},release:function(t){r===s&&(a=pooling.double(a),s*=2),i&&i(t),a[r]=t,r+=1}}},bezierLengthPool=poolFactory(8,function(){return{addedLength:0,percents:createTypedArray("float32",getDefaultCurveSegments()),lengths:createTypedArray("float32",getDefaultCurveSegments())}}),segmentsLengthPool=poolFactory(8,function(){return{lengths:[],totalLength:0}},function(t){var e,i=t.lengths.length;for(e=0;e<i;e+=1)bezierLengthPool.release(t.lengths[e]);t.lengths.length=0});function bezFunction(){var k=Math;function y(t,e,i,r,s,a){var n=t*r+e*s+i*a-s*r-a*t-i*e;return-.001<n&&n<.001}var p=function(t,e,i,r){var s,a,n,o,h,l,p=getDefaultCurveSegments(),f=0,m=[],c=[],d=bezierLengthPool.newElement();for(n=i.length,s=0;s<p;s+=1){for(h=s/(p-1),a=l=0;a<n;a+=1)o=bmPow(1-h,3)*t[a]+3*bmPow(1-h,2)*h*i[a]+3*(1-h)*bmPow(h,2)*r[a]+bmPow(h,3)*e[a],m[a]=o,null!==c[a]&&(l+=bmPow(m[a]-c[a],2)),c[a]=m[a];l&&(f+=l=bmSqrt(l)),d.percents[s]=h,d.lengths[s]=f}return d.addedLength=f,d};function g(t){this.segmentLength=0,this.points=new Array(t)}function v(t,e){this.partialLength=t,this.point=e}var b,t=(b={},function(t,e,i,r){var s=(t[0]+"_"+t[1]+"_"+e[0]+"_"+e[1]+"_"+i[0]+"_"+i[1]+"_"+r[0]+"_"+r[1]).replace(/\./g,"p");if(!b[s]){var a,n,o,h,l,p,f,m=getDefaultCurveSegments(),c=0,d=null;2===t.length&&(t[0]!==e[0]||t[1]!==e[1])&&y(t[0],t[1],e[0],e[1],t[0]+i[0],t[1]+i[1])&&y(t[0],t[1],e[0],e[1],e[0]+r[0],e[1]+r[1])&&(m=2);var u=new g(m);for(o=i.length,a=0;a<m;a+=1){for(f=createSizedArray(o),l=a/(m-1),n=p=0;n<o;n+=1)h=bmPow(1-l,3)*t[n]+3*bmPow(1-l,2)*l*(t[n]+i[n])+3*(1-l)*bmPow(l,2)*(e[n]+r[n])+bmPow(l,3)*e[n],f[n]=h,null!==d&&(p+=bmPow(f[n]-d[n],2));c+=p=bmSqrt(p),u.points[a]=new v(p,f),d=f}u.segmentLength=c,b[s]=u}return b[s]});function D(t,e){var i=e.percents,r=e.lengths,s=i.length,a=bmFloor((s-1)*t),n=t*e.addedLength,o=0;if(a===s-1||0===a||n===r[a])return i[a];for(var h=r[a]>n?-1:1,l=!0;l;)if(r[a]<=n&&r[a+1]>n?(o=(n-r[a])/(r[a+1]-r[a]),l=!1):a+=h,a<0||s-1<=a){if(a===s-1)return i[a];l=!1}return i[a]+(i[a+1]-i[a])*o}var F=createTypedArray("float32",8);return{getSegmentsLength:function(t){var e,i=segmentsLengthPool.newElement(),r=t.c,s=t.v,a=t.o,n=t.i,o=t._length,h=i.lengths,l=0;for(e=0;e<o-1;e+=1)h[e]=p(s[e],s[e+1],a[e],n[e+1]),l+=h[e].addedLength;return r&&o&&(h[e]=p(s[e],s[0],a[e],n[0]),l+=h[e].addedLength),i.totalLength=l,i},getNewSegment:function(t,e,i,r,s,a,n){s<0?s=0:1<s&&(s=1);var o,h=D(s,n),l=D(a=1<a?1:a,n),p=t.length,f=1-h,m=1-l,c=f*f*f,d=h*f*f*3,u=h*h*f*3,y=h*h*h,g=f*f*m,v=h*f*m+f*h*m+f*f*l,b=h*h*m+f*h*l+h*f*l,x=h*h*l,P=f*m*m,E=h*m*m+f*l*m+f*m*l,S=h*l*m+f*l*l+h*m*l,C=h*l*l,_=m*m*m,A=l*m*m+m*l*m+m*m*l,T=l*l*m+m*l*l+l*m*l,M=l*l*l;for(o=0;o<p;o+=1)F[4*o]=k.round(1e3*(c*t[o]+d*i[o]+u*r[o]+y*e[o]))/1e3,F[4*o+1]=k.round(1e3*(g*t[o]+v*i[o]+b*r[o]+x*e[o]))/1e3,F[4*o+2]=k.round(1e3*(P*t[o]+E*i[o]+S*r[o]+C*e[o]))/1e3,F[4*o+3]=k.round(1e3*(_*t[o]+A*i[o]+T*r[o]+M*e[o]))/1e3;return F},getPointInSegment:function(t,e,i,r,s,a){var n=D(s,a),o=1-n;return[k.round(1e3*(o*o*o*t[0]+(n*o*o+o*n*o+o*o*n)*i[0]+(n*n*o+o*n*n+n*o*n)*r[0]+n*n*n*e[0]))/1e3,k.round(1e3*(o*o*o*t[1]+(n*o*o+o*n*o+o*o*n)*i[1]+(n*n*o+o*n*n+n*o*n)*r[1]+n*n*n*e[1]))/1e3]},buildBezierData:t,pointOnLine2D:y,pointOnLine3D:function(t,e,i,r,s,a,n,o,h){if(0===i&&0===a&&0===h)return y(t,e,r,s,n,o);var l,p=k.sqrt(k.pow(r-t,2)+k.pow(s-e,2)+k.pow(a-i,2)),f=k.sqrt(k.pow(n-t,2)+k.pow(o-e,2)+k.pow(h-i,2)),m=k.sqrt(k.pow(n-r,2)+k.pow(o-s,2)+k.pow(h-a,2));return-1e-4<(l=f<p?m<p?p-f-m:m-f-p:f<m?m-f-p:f-p-m)&&l<1e-4}}}var bez=bezFunction(),initFrame=initialDefaultFrame,mathAbs=Math.abs;function interpolateValue(t,e){var i,r=this.offsetTime;"multidimensional"===this.propType&&(i=createTypedArray("float32",this.pv.length));for(var s,a,n,o,h,l,p,f,m,c=e.lastIndex,d=c,u=this.keyframes.length-1,y=!0;y;){if(s=this.keyframes[d],a=this.keyframes[d+1],d===u-1&&t>=a.t-r){s.h&&(s=a),c=0;break}if(a.t-r>t){c=d;break}d<u-1?d+=1:(c=0,y=!1)}n=this.keyframesMetadata[d]||{};var g,v=a.t-r,b=s.t-r;if(s.to){n.bezierData||(n.bezierData=bez.buildBezierData(s.s,a.s||s.e,s.to,s.ti));var x=n.bezierData;if(v<=t||t<b){var P=v<=t?x.points.length-1:0;for(h=x.points[P].point.length,o=0;o<h;o+=1)i[o]=x.points[P].point[o]}else{n.__fnct?m=n.__fnct:(m=BezierFactory.getBezierEasing(s.o.x,s.o.y,s.i.x,s.i.y,s.n).get,n.__fnct=m),l=m((t-b)/(v-b));var E,S=x.segmentLength*l,C=e.lastFrame<t&&e._lastKeyframeIndex===d?e._lastAddedLength:0;for(f=e.lastFrame<t&&e._lastKeyframeIndex===d?e._lastPoint:0,y=!0,p=x.points.length;y;){if(C+=x.points[f].partialLength,0===S||0===l||f===x.points.length-1){for(h=x.points[f].point.length,o=0;o<h;o+=1)i[o]=x.points[f].point[o];break}if(C<=S&&S<C+x.points[f+1].partialLength){for(E=(S-C)/x.points[f+1].partialLength,h=x.points[f].point.length,o=0;o<h;o+=1)i[o]=x.points[f].point[o]+(x.points[f+1].point[o]-x.points[f].point[o])*E;break}f<p-1?f+=1:y=!1}e._lastPoint=f,e._lastAddedLength=C-x.points[f].partialLength,e._lastKeyframeIndex=d}}else{var _,A,T,M,k;if(u=s.s.length,g=a.s||s.e,this.sh&&1!==s.h)if(v<=t)i[0]=g[0],i[1]=g[1],i[2]=g[2];else if(t<=b)i[0]=s.s[0],i[1]=s.s[1],i[2]=s.s[2];else{quaternionToEuler(i,slerp(createQuaternion(s.s),createQuaternion(g),(t-b)/(v-b)))}else for(d=0;d<u;d+=1)1!==s.h&&(l=v<=t?1:t<b?0:(s.o.x.constructor===Array?(n.__fnct||(n.__fnct=[]),n.__fnct[d]?m=n.__fnct[d]:(_=void 0===s.o.x[d]?s.o.x[0]:s.o.x[d],A=void 0===s.o.y[d]?s.o.y[0]:s.o.y[d],T=void 0===s.i.x[d]?s.i.x[0]:s.i.x[d],M=void 0===s.i.y[d]?s.i.y[0]:s.i.y[d],m=BezierFactory.getBezierEasing(_,A,T,M).get,n.__fnct[d]=m)):n.__fnct?m=n.__fnct:(_=s.o.x,A=s.o.y,T=s.i.x,M=s.i.y,m=BezierFactory.getBezierEasing(_,A,T,M).get,s.keyframeMetadata=m),m((t-b)/(v-b)))),g=a.s||s.e,k=1===s.h?s.s[d]:s.s[d]+(g[d]-s.s[d])*l,"multidimensional"===this.propType?i[d]=k:i=k}return e.lastIndex=c,i}function slerp(t,e,i){var r,s,a,n,o,h=[],l=t[0],p=t[1],f=t[2],m=t[3],c=e[0],d=e[1],u=e[2],y=e[3];return(s=l*c+p*d+f*u+m*y)<0&&(s=-s,c=-c,d=-d,u=-u,y=-y),o=1e-6<1-s?(r=Math.acos(s),a=Math.sin(r),n=Math.sin((1-i)*r)/a,Math.sin(i*r)/a):(n=1-i,i),h[0]=n*l+o*c,h[1]=n*p+o*d,h[2]=n*f+o*u,h[3]=n*m+o*y,h}function quaternionToEuler(t,e){var i=e[0],r=e[1],s=e[2],a=e[3],n=Math.atan2(2*r*a-2*i*s,1-2*r*r-2*s*s),o=Math.asin(2*i*r+2*s*a),h=Math.atan2(2*i*a-2*r*s,1-2*i*i-2*s*s);t[0]=n/degToRads,t[1]=o/degToRads,t[2]=h/degToRads}function createQuaternion(t){var e=t[0]*degToRads,i=t[1]*degToRads,r=t[2]*degToRads,s=Math.cos(e/2),a=Math.cos(i/2),n=Math.cos(r/2),o=Math.sin(e/2),h=Math.sin(i/2),l=Math.sin(r/2);return[o*h*n+s*a*l,o*a*n+s*h*l,s*h*n-o*a*l,s*a*n-o*h*l]}function getValueAtCurrentTime(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime;if(!(t===this._caching.lastFrame||this._caching.lastFrame!==initFrame&&(this._caching.lastFrame>=i&&i<=t||this._caching.lastFrame<e&&t<e))){this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0);var r=this.interpolateValue(t,this._caching);this.pv=r}return this._caching.lastFrame=t,this.pv}function setVValue(t){var e;if("unidimensional"===this.propType)e=t*this.mult,1e-5<mathAbs(this.v-e)&&(this.v=e,this._mdf=!0);else for(var i=0,r=this.v.length;i<r;)e=t[i]*this.mult,1e-5<mathAbs(this.v[i]-e)&&(this.v[i]=e,this._mdf=!0),i+=1}function processEffectsSequence(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t;this.lock=!0,this._mdf=this._isFirstFrame;var e=this.effectsSequence.length,i=this.kf?this.pv:this.data.k;for(t=0;t<e;t+=1)i=this.effectsSequence[t](i);this.setVValue(i),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function addEffect(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function ValueProperty(t,e,i,r){this.propType="unidimensional",this.mult=i||1,this.data=e,this.v=i?e.k*i:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function MultiDimensionalProperty(t,e,i,r){var s;this.propType="multidimensional",this.mult=i||1,this.data=e,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var a=e.k.length;for(this.v=createTypedArray("float32",a),this.pv=createTypedArray("float32",a),this.vel=createTypedArray("float32",a),s=0;s<a;s+=1)this.v[s]=e.k[s]*this.mult,this.pv[s]=e.k[s];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function KeyframedValueProperty(t,e,i,r){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:initFrame,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.v=initFrame,this.pv=initFrame,this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.addEffect=addEffect}function KeyframedMultidimensionalProperty(t,e,i,r){var s;this.propType="multidimensional";var a,n,o,h,l=e.k.length;for(s=0;s<l-1;s+=1)e.k[s].to&&e.k[s].s&&e.k[s+1]&&e.k[s+1].s&&(a=e.k[s].s,n=e.k[s+1].s,o=e.k[s].to,h=e.k[s].ti,(2===a.length&&(a[0]!==n[0]||a[1]!==n[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],a[0]+o[0],a[1]+o[1])&&bez.pointOnLine2D(a[0],a[1],n[0],n[1],n[0]+h[0],n[1]+h[1])||3===a.length&&(a[0]!==n[0]||a[1]!==n[1]||a[2]!==n[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],a[0]+o[0],a[1]+o[1],a[2]+o[2])&&bez.pointOnLine3D(a[0],a[1],a[2],n[0],n[1],n[2],n[0]+h[0],n[1]+h[1],n[2]+h[2]))&&(e.k[s].to=null,e.k[s].ti=null),a[0]===n[0]&&a[1]===n[1]&&0===o[0]&&0===o[1]&&0===h[0]&&0===h[1]&&(2===a.length||a[2]===n[2]&&0===o[2]&&0===h[2])&&(e.k[s].to=null,e.k[s].ti=null));this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.frameId=-1;var p=e.k[0].s.length;for(this.v=createTypedArray("float32",p),this.pv=createTypedArray("float32",p),s=0;s<p;s+=1)this.v[s]=initFrame,this.pv[s]=initFrame;this._caching={lastFrame:initFrame,lastIndex:0,value:createTypedArray("float32",p)},this.addEffect=addEffect}var PropertyFactory={getProp:function(t,e,i,r,s){var a;if(e.sid&&(e=t.globalData.slotManager.getProp(e)),e.k.length)if("number"==typeof e.k[0])a=new MultiDimensionalProperty(t,e,r,s);else switch(i){case 0:a=new KeyframedValueProperty(t,e,r,s);break;case 1:a=new KeyframedMultidimensionalProperty(t,e,r,s)}else a=new ValueProperty(t,e,r,s);return a.effectsSequence.length&&s.addDynamicProperty(a),a}};function DynamicPropertyContainer(){}DynamicPropertyContainer.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){var t;this._mdf=!1;var e=this.dynamicProperties.length;for(t=0;t<e;t+=1)this.dynamicProperties[t].getValue(),this.dynamicProperties[t]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var pointPool=poolFactory(8,function(){return createTypedArray("float32",2)});function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var i=0;i<e;)this.v[i]=pointPool.newElement(),this.o[i]=pointPool.newElement(),this.i[i]=pointPool.newElement(),i+=1},ShapePath.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},ShapePath.prototype.doubleArrayLength=function(){this.v=this.v.concat(createSizedArray(this._maxLength)),this.i=this.i.concat(createSizedArray(this._maxLength)),this.o=this.o.concat(createSizedArray(this._maxLength)),this._maxLength*=2},ShapePath.prototype.setXYAt=function(t,e,i,r,s){var a;switch(this._length=Math.max(this._length,r+1),this._length>=this._maxLength&&this.doubleArrayLength(),i){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o;break;default:a=[]}(!a[r]||a[r]&&!s)&&(a[r]=pointPool.newElement()),a[r][0]=t,a[r][1]=e},ShapePath.prototype.setTripleAt=function(t,e,i,r,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(i,r,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){var t=new ShapePath;t.setPathData(this.c,this._length);var e=this.v,i=this.o,r=this.i,s=0;this.c&&(t.setTripleAt(e[0][0],e[0][1],r[0][0],r[0][1],i[0][0],i[0][1],0,!1),s=1);var a,n=this._length-1,o=this._length;for(a=s;a<o;a+=1)t.setTripleAt(e[n][0],e[n][1],r[n][0],r[n][1],i[n][0],i[n][1],a,!1),n-=1;return t},ShapePath.prototype.length=function(){return this._length};var shapePool=(_r=poolFactory(4,function(){return new ShapePath},function(t){var e,i=t._length;for(e=0;e<i;e+=1)pointPool.release(t.v[e]),pointPool.release(t.i[e]),pointPool.release(t.o[e]),t.v[e]=null,t.i[e]=null,t.o[e]=null;t._length=0,t.c=!1}),_r.clone=function(t){var e,i=_r.newElement(),r=void 0===t._length?t.v.length:t._length;for(i.setLength(r),i.c=t.c,e=0;e<r;e+=1)i.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return i},_r),_r;function ShapeCollection(){this._length=0,this._maxLength=4,this.shapes=createSizedArray(this._maxLength)}ShapeCollection.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(createSizedArray(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},ShapeCollection.prototype.releaseShapes=function(){var t;for(t=0;t<this._length;t+=1)shapePool.release(this.shapes[t]);this._length=0};var shapeCollectionPool=(js={newShapeCollection:function(){var t;t=ks?ms[ks-=1]:new ShapeCollection;return t},release:function(t){var e,i=t._length;for(e=0;e<i;e+=1)shapePool.release(t.shapes[e]);t._length=0,ks===ls&&(ms=pooling.double(ms),ls*=2);ms[ks]=t,ks+=1}},ks=0,ls=4,ms=createSizedArray(ls),js),js,ks,ls,ms,ShapePropertyFactory=function(){var s=-999999;function t(t,e,i){var r,s,a,n,o,h,l,p,f,m=i.lastIndex,c=this.keyframes;if(t<c[0].t-this.offsetTime)r=c[0].s[0],a=!0,m=0;else if(t>=c[c.length-1].t-this.offsetTime)r=c[c.length-1].s?c[c.length-1].s[0]:c[c.length-2].e[0],a=!0;else{for(var d,u,y,g=m,v=c.length-1,b=!0;b&&(d=c[g],!((u=c[g+1]).t-this.offsetTime>t));)g<v-1?g+=1:b=!1;if(y=this.keyframesMetadata[g]||{},m=g,!(a=1===d.h)){if(t>=u.t-this.offsetTime)p=1;else if(t<d.t-this.offsetTime)p=0;else{var x;y.__fnct?x=y.__fnct:(x=BezierFactory.getBezierEasing(d.o.x,d.o.y,d.i.x,d.i.y).get,y.__fnct=x),p=x((t-(d.t-this.offsetTime))/(u.t-this.offsetTime-(d.t-this.offsetTime)))}s=u.s?u.s[0]:d.e[0]}r=d.s[0]}for(h=e._length,l=r.i[0].length,i.lastIndex=m,n=0;n<h;n+=1)for(o=0;o<l;o+=1)f=a?r.i[n][o]:r.i[n][o]+(s.i[n][o]-r.i[n][o])*p,e.i[n][o]=f,f=a?r.o[n][o]:r.o[n][o]+(s.o[n][o]-r.o[n][o])*p,e.o[n][o]=f,f=a?r.v[n][o]:r.v[n][o]+(s.v[n][o]-r.v[n][o])*p,e.v[n][o]=f}function a(){this.paths=this.localShapeCollection}function e(t){(function(t,e){if(t._length!==e._length||t.c!==e.c)return!1;var i,r=t._length;for(i=0;i<r;i+=1)if(t.v[i][0]!==e.v[i][0]||t.v[i][1]!==e.v[i][1]||t.o[i][0]!==e.o[i][0]||t.o[i][1]!==e.o[i][1]||t.i[i][0]!==e.i[i][0]||t.i[i][1]!==e.i[i][1])return!1;return!0})(this.v,t)||(this.v=shapePool.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function i(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{var t,e;this.lock=!0,this._mdf=!1,t=this.kf?this.pv:this.data.ks?this.data.ks.k:this.data.pt.k;var i=this.effectsSequence.length;for(e=0;e<i;e+=1)t=this.effectsSequence[e](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function n(t,e,i){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;var r=3===i?e.pt.k:e.ks.k;this.v=shapePool.clone(r),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=a,this.effectsSequence=[]}function r(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function o(t,e,i){this.propType="shape",this.comp=t.comp,this.elem=t,this.container=t,this.offsetTime=t.data.st,this.keyframes=3===i?e.pt.k:e.ks.k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;var r=this.keyframes[0].s[0].i.length;this.v=shapePool.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,r),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=s,this.reset=a,this._caching={lastFrame:s,lastIndex:0},this.effectsSequence=[function(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime,r=this._caching.lastFrame;return r!==s&&(r<e&&t<e||i<r&&i<t)||(this._caching.lastIndex=r<t?this._caching.lastIndex:0,this.interpolateShape(t,this.pv,this._caching)),this._caching.lastFrame=t,this.pv}.bind(this)]}n.prototype.interpolateShape=t,n.prototype.getValue=i,n.prototype.setVValue=e,n.prototype.addEffect=r,o.prototype.getValue=i,o.prototype.interpolateShape=t,o.prototype.setVValue=e,o.prototype.addEffect=r;var h=function(){var n=roundCorner;function t(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}return t.prototype={reset:a,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertEllToPath())},convertEllToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,r=this.s.v[1]/2,s=3!==this.d,a=this.v;a.v[0][0]=t,a.v[0][1]=e-r,a.v[1][0]=s?t+i:t-i,a.v[1][1]=e,a.v[2][0]=t,a.v[2][1]=e+r,a.v[3][0]=s?t-i:t+i,a.v[3][1]=e,a.i[0][0]=s?t-i*n:t+i*n,a.i[0][1]=e-r,a.i[1][0]=s?t+i:t-i,a.i[1][1]=e-r*n,a.i[2][0]=s?t+i*n:t-i*n,a.i[2][1]=e+r,a.i[3][0]=s?t-i:t+i,a.i[3][1]=e+r*n,a.o[0][0]=s?t+i*n:t-i*n,a.o[0][1]=e-r,a.o[1][0]=s?t+i:t-i,a.o[1][1]=e+r*n,a.o[2][0]=s?t-i*n:t+i*n,a.o[2][1]=e+r,a.o[3][0]=s?t-i:t+i,a.o[3][1]=e-r*n}},extendPrototype([DynamicPropertyContainer],t),t}(),l=function(){function t(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=PropertyFactory.getProp(t,e.ir,0,0,this),this.is=PropertyFactory.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=PropertyFactory.getProp(t,e.pt,0,0,this),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,degToRads,this),this.or=PropertyFactory.getProp(t,e.or,0,0,this),this.os=PropertyFactory.getProp(t,e.os,0,.01,this),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}return t.prototype={reset:a,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertToPath())},convertStarToPath:function(){var t,e,i,r,s=2*Math.floor(this.pt.v),a=2*Math.PI/s,n=!0,o=this.or.v,h=this.ir.v,l=this.os.v,p=this.is.v,f=2*Math.PI*o/(2*s),m=2*Math.PI*h/(2*s),c=-Math.PI/2;c+=this.r.v;var d=3===this.data.d?-1:1;for(t=this.v._length=0;t<s;t+=1){i=n?l:p,r=n?f:m;var u=(e=n?o:h)*Math.cos(c),y=e*Math.sin(c),g=0===u&&0===y?0:y/Math.sqrt(u*u+y*y),v=0===u&&0===y?0:-u/Math.sqrt(u*u+y*y);u+=+this.p.v[0],y+=+this.p.v[1],this.v.setTripleAt(u,y,u-g*r*i*d,y-v*r*i*d,u+g*r*i*d,y+v*r*i*d,t,!0),n=!n,c+=a*d}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),i=2*Math.PI/e,r=this.or.v,s=this.os.v,a=2*Math.PI*r/(4*e),n=.5*-Math.PI,o=3===this.data.d?-1:1;for(n+=this.r.v,t=this.v._length=0;t<e;t+=1){var h=r*Math.cos(n),l=r*Math.sin(n),p=0===h&&0===l?0:l/Math.sqrt(h*h+l*l),f=0===h&&0===l?0:-h/Math.sqrt(h*h+l*l);h+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(h,l,h-p*a*s*o,l-f*a*s*o,h+p*a*s*o,l+f*a*s*o,t,!0),n+=i*o}this.paths.length=0,this.paths[0]=this.v}},extendPrototype([DynamicPropertyContainer],t),t}(),p=function(){function t(t,e){this.v=shapePool.newElement(),this.v.c=!0,this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}return t.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,r=this.s.v[1]/2,s=bmMin(i,r,this.r.v),a=s*(1-roundCorner);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+s,t+i,e-r+a,0,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-a,t+i,e+r-s,1,!0),0!==s?(this.v.setTripleAt(t+i-s,e+r,t+i-s,e+r,t+i-a,e+r,2,!0),this.v.setTripleAt(t-i+s,e+r,t-i+a,e+r,t-i+s,e+r,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-s,t-i,e+r-a,4,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+a,t-i,e-r+s,5,!0),this.v.setTripleAt(t-i+s,e-r,t-i+s,e-r,t-i+a,e-r,6,!0),this.v.setTripleAt(t+i-s,e-r,t+i-a,e-r,t+i-s,e-r,7,!0)):(this.v.setTripleAt(t-i,e+r,t-i+a,e+r,t-i,e+r,2),this.v.setTripleAt(t-i,e-r,t-i,e-r+a,t-i,e-r,3))):(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+a,t+i,e-r+s,0,!0),0!==s?(this.v.setTripleAt(t+i-s,e-r,t+i-s,e-r,t+i-a,e-r,1,!0),this.v.setTripleAt(t-i+s,e-r,t-i+a,e-r,t-i+s,e-r,2,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+s,t-i,e-r+a,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-a,t-i,e+r-s,4,!0),this.v.setTripleAt(t-i+s,e+r,t-i+s,e+r,t-i+a,e+r,5,!0),this.v.setTripleAt(t+i-s,e+r,t+i-a,e+r,t+i-s,e+r,6,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-s,t+i,e+r-a,7,!0)):(this.v.setTripleAt(t-i,e-r,t-i+a,e-r,t-i,e-r,1,!0),this.v.setTripleAt(t-i,e+r,t-i,e+r-a,t-i,e+r,2,!0),this.v.setTripleAt(t+i,e+r,t+i-a,e+r,t+i,e+r,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf&&this.convertRectToPath())},reset:a},extendPrototype([DynamicPropertyContainer],t),t}();var f={getShapeProp:function(t,e,i){var r;return 3===i||4===i?r=(3===i?e.pt:e.ks).k.length?new o(t,e,i):new n(t,e,i):5===i?r=new p(t,e):6===i?r=new h(t,e):7===i&&(r=new l(t,e)),r.k&&t.addDynamicProperty(r),r},getConstructorFunction:function(){return n},getKeyframedConstructorFunction:function(){return o}};return f}(),Matrix=function(){var s=Math.cos,a=Math.sin,n=Math.tan,r=Math.round;function t(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function e(t){if(0===t)return this;var e=s(t),i=a(t);return this._t(e,-i,0,0,i,e,0,0,0,0,1,0,0,0,0,1)}function i(t){if(0===t)return this;var e=s(t),i=a(t);return this._t(1,0,0,0,0,e,-i,0,0,i,e,0,0,0,0,1)}function o(t){if(0===t)return this;var e=s(t),i=a(t);return this._t(e,0,i,0,0,1,0,0,-i,0,e,0,0,0,0,1)}function h(t){if(0===t)return this;var e=s(t),i=a(t);return this._t(e,-i,0,0,i,e,0,0,0,0,1,0,0,0,0,1)}function l(t,e){return this._t(1,e,t,1,0,0)}function p(t,e){return this.shear(n(t),n(e))}function f(t,e){var i=s(e),r=a(e);return this._t(i,r,0,0,-r,i,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,n(t),1,0,0,0,0,1,0,0,0,0,1)._t(i,-r,0,0,r,i,0,0,0,0,1,0,0,0,0,1)}function m(t,e,i){return i||0===i||(i=1),1===t&&1===e&&1===i?this:this._t(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1)}function c(t,e,i,r,s,a,n,o,h,l,p,f,m,c,d,u){return this.props[0]=t,this.props[1]=e,this.props[2]=i,this.props[3]=r,this.props[4]=s,this.props[5]=a,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=l,this.props[10]=p,this.props[11]=f,this.props[12]=m,this.props[13]=c,this.props[14]=d,this.props[15]=u,this}function d(t,e,i){return i=i||0,0!==t||0!==e||0!==i?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,i,1):this}function u(t,e,i,r,s,a,n,o,h,l,p,f,m,c,d,u){var y=this.props;if(1===t&&0===e&&0===i&&0===r&&0===s&&1===a&&0===n&&0===o&&0===h&&0===l&&1===p&&0===f)return y[12]=y[12]*t+y[15]*m,y[13]=y[13]*a+y[15]*c,y[14]=y[14]*p+y[15]*d,y[15]*=u,this._identityCalculated=!1,this;var g=y[0],v=y[1],b=y[2],x=y[3],P=y[4],E=y[5],S=y[6],C=y[7],_=y[8],A=y[9],T=y[10],M=y[11],k=y[12],D=y[13],F=y[14],w=y[15];return y[0]=g*t+v*s+b*h+x*m,y[1]=g*e+v*a+b*l+x*c,y[2]=g*i+v*n+b*p+x*d,y[3]=g*r+v*o+b*f+x*u,y[4]=P*t+E*s+S*h+C*m,y[5]=P*e+E*a+S*l+C*c,y[6]=P*i+E*n+S*p+C*d,y[7]=P*r+E*o+S*f+C*u,y[8]=_*t+A*s+T*h+M*m,y[9]=_*e+A*a+T*l+M*c,y[10]=_*i+A*n+T*p+M*d,y[11]=_*r+A*o+T*f+M*u,y[12]=k*t+D*s+F*h+w*m,y[13]=k*e+D*a+F*l+w*c,y[14]=k*i+D*n+F*p+w*d,y[15]=k*r+D*o+F*f+w*u,this._identityCalculated=!1,this}function y(t){var e=t.props;return this.transform(e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15])}function g(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function v(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function b(t){var e;for(e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function x(t){var e;for(e=0;e<16;e+=1)this.props[e]=t[e]}function P(t,e,i){return{x:t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}}function E(t,e,i){return t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12]}function S(t,e,i){return t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13]}function C(t,e,i){return t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}function _(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,i=-this.props[1]/t,r=-this.props[4]/t,s=this.props[0]/t,a=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,n=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,o=new Matrix;return o.props[0]=e,o.props[1]=i,o.props[4]=r,o.props[5]=s,o.props[12]=a,o.props[13]=n,o}function A(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function T(t){var e,i=t.length,r=[];for(e=0;e<i;e+=1)r[e]=A(t[e]);return r}function M(t,e,i){var r=createTypedArray("float32",6);if(this.isIdentity())r[0]=t[0],r[1]=t[1],r[2]=e[0],r[3]=e[1],r[4]=i[0],r[5]=i[1];else{var s=this.props[0],a=this.props[1],n=this.props[4],o=this.props[5],h=this.props[12],l=this.props[13];r[0]=t[0]*s+t[1]*n+h,r[1]=t[0]*a+t[1]*o+l,r[2]=e[0]*s+e[1]*n+h,r[3]=e[0]*a+e[1]*o+l,r[4]=i[0]*s+i[1]*n+h,r[5]=i[0]*a+i[1]*o+l}return r}function k(t,e,i){return this.isIdentity()?[t,e,i]:[t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]]}function D(t,e){if(this.isIdentity())return t+","+e;var i=this.props;return Math.round(100*(t*i[0]+e*i[4]+i[12]))/100+","+Math.round(100*(t*i[1]+e*i[5]+i[13]))/100}function F(){for(var t=0,e=this.props,i="matrix3d(";t<16;)i+=r(1e4*e[t])/1e4,i+=15===t?")":",",t+=1;return i}function w(t){return t<1e-6&&0<t||-1e-6<t&&t<0?r(1e4*t)/1e4:t}function I(){var t=this.props;return"matrix("+w(t[0])+","+w(t[1])+","+w(t[4])+","+w(t[5])+","+w(t[12])+","+w(t[13])+")"}return function(){this.reset=t,this.rotate=e,this.rotateX=i,this.rotateY=o,this.rotateZ=h,this.skew=p,this.skewFromAxis=f,this.shear=l,this.scale=m,this.setTransform=c,this.translate=d,this.transform=u,this.multiply=y,this.applyToPoint=P,this.applyToX=E,this.applyToY=S,this.applyToZ=C,this.applyToPointArray=k,this.applyToTriplePoints=M,this.applyToPointStringified=D,this.toCSS=F,this.to2dCSS=I,this.clone=b,this.cloneFromProps=x,this.equals=v,this.inversePoints=T,this.inversePoint=A,this.getInverseMatrix=_,this._t=this.transform,this.isIdentity=g,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}}();function _typeof$3(t){return(_typeof$3="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var lottie={},standalone="__[STANDALONE]__",animationData="__[ANIMATIONDATA]__",renderer="";function setLocation(t){setLocationHref(t)}function searchAnimations(){!0===standalone?animationManager.searchAnimations(animationData,standalone,renderer):animationManager.searchAnimations()}function setSubframeRendering(t){setSubframeEnabled(t)}function setPrefix(t){setIdPrefix(t)}function loadAnimation(t){return!0===standalone&&(t.animationData=JSON.parse(animationData)),animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":setDefaultCurveSegments(200);break;default:case"medium":setDefaultCurveSegments(50);break;case"low":setDefaultCurveSegments(10)}else!isNaN(t)&&1<t&&setDefaultCurveSegments(t);50<=getDefaultCurveSegments()?roundValues(!1):roundValues(!0)}function inBrowser(){return"undefined"!=typeof navigator}function installPlugin(t,e){"expressions"===t&&setExpressionsPlugin(e)}function getFactory(t){switch(t){case"propertyFactory":return PropertyFactory;case"shapePropertyFactory":return ShapePropertyFactory;case"matrix":return Matrix;default:return null}}function checkReady(){"complete"===document.readyState&&(clearInterval(readyStateCheckInterval),searchAnimations())}function getQueryVariable(t){for(var e=queryString.split("&"),i=0;i<e.length;i+=1){var r=e[i].split("=");if(decodeURIComponent(r[0])==t)return decodeURIComponent(r[1])}return null}lottie.play=animationManager.play,lottie.pause=animationManager.pause,lottie.setLocationHref=setLocation,lottie.togglePause=animationManager.togglePause,lottie.setSpeed=animationManager.setSpeed,lottie.setDirection=animationManager.setDirection,lottie.stop=animationManager.stop,lottie.searchAnimations=searchAnimations,lottie.registerAnimation=animationManager.registerAnimation,lottie.loadAnimation=loadAnimation,lottie.setSubframeRendering=setSubframeRendering,lottie.resize=animationManager.resize,lottie.goToAndStop=animationManager.goToAndStop,lottie.destroy=animationManager.destroy,lottie.setQuality=setQuality,lottie.inBrowser=inBrowser,lottie.installPlugin=installPlugin,lottie.freeze=animationManager.freeze,lottie.unfreeze=animationManager.unfreeze,lottie.setVolume=animationManager.setVolume,lottie.mute=animationManager.mute,lottie.unmute=animationManager.unmute,lottie.getRegisteredAnimations=animationManager.getRegisteredAnimations,lottie.useWebWorker=setWebWorker,lottie.setIDPrefix=setPrefix,lottie.__getFactory=getFactory,lottie.version="5.12.2";var queryString="";if(standalone){var scripts=document.getElementsByTagName("script"),index=scripts.length-1,myScript=scripts[index]||{src:""};queryString=myScript.src?myScript.src.replace(/^[^\?]+\??/,""):"",renderer=getQueryVariable("renderer")}var readyStateCheckInterval=setInterval(checkReady,100);try{"object"===("undefined"==typeof exports?"undefined":_typeof$3(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=lottie)}catch(t){}var ShapeModifiers=(ly={},my={},ly.registerModifier=function(t,e){my[t]||(my[t]=e)},ly.getModifier=function(t,e,i){return new my[t](e,i)},ly),ly,my;function ShapeModifier(){}function TrimModifier(){}function PuckerAndBloatModifier(){}ShapeModifier.prototype.initModifierProperties=function(){},ShapeModifier.prototype.addShapeToModifier=function(){},ShapeModifier.prototype.addShape=function(t){if(!this.closed){t.sh.container.addDynamicProperty(t.sh);var e={shape:t.sh,data:t,localShapeCollection:shapeCollectionPool.newShapeCollection()};this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated()}},ShapeModifier.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=initialDefaultFrame,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},ShapeModifier.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},extendPrototype([DynamicPropertyContainer],ShapeModifier),extendPrototype([ShapeModifier],TrimModifier),TrimModifier.prototype.initModifierProperties=function(t,e){this.s=PropertyFactory.getProp(t,e.s,0,.01,this),this.e=PropertyFactory.getProp(t,e.e,0,.01,this),this.o=PropertyFactory.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},TrimModifier.prototype.addShapeToModifier=function(t){t.pathsData=[]},TrimModifier.prototype.calculateShapeEdges=function(t,e,i,r,s){var a=[];e<=1?a.push({s:t,e:e}):1<=t?a.push({s:t-1,e:e-1}):(a.push({s:t,e:1}),a.push({s:0,e:e-1}));var n,o,h=[],l=a.length;for(n=0;n<l;n+=1){var p,f;if(!((o=a[n]).e*s<r||o.s*s>r+i))p=o.s*s<=r?0:(o.s*s-r)/i,f=o.e*s>=r+i?1:(o.e*s-r)/i,h.push([p,f])}return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){var e,i=t.length;for(e=0;e<i;e+=1)segmentsLengthPool.release(t[e]);return t.length=0,t},TrimModifier.prototype.processShapes=function(t){var e,i,r,s;if(this._mdf||t){var a=this.o.v%360/360;if(a<0&&(a+=1),e=1<this.s.v?1+a:this.s.v<0?0+a:this.s.v+a,(i=1<this.e.v?1+a:this.e.v<0?0+a:this.e.v+a)<e){var n=e;e=i,i=n}e=1e-4*Math.round(1e4*e),i=1e-4*Math.round(1e4*i),this.sValue=e,this.eValue=i}else e=this.sValue,i=this.eValue;var o,h,l,p,f,m=this.shapes.length,c=0;if(i===e)for(s=0;s<m;s+=1)this.shapes[s].localShapeCollection.releaseShapes(),this.shapes[s].shape._mdf=!0,this.shapes[s].shape.paths=this.shapes[s].localShapeCollection,this._mdf&&(this.shapes[s].pathsData.length=0);else if(1===i&&0===e||0===i&&1===e){if(this._mdf)for(s=0;s<m;s+=1)this.shapes[s].pathsData.length=0,this.shapes[s].shape._mdf=!0}else{var d,u,y=[];for(s=0;s<m;s+=1)if((d=this.shapes[s]).shape._mdf||this._mdf||t||2===this.m){if(h=(r=d.shape.paths)._length,f=0,!d.shape._mdf&&d.pathsData.length)f=d.totalShapeLength;else{for(l=this.releasePathsData(d.pathsData),o=0;o<h;o+=1)p=bez.getSegmentsLength(r.shapes[o]),l.push(p),f+=p.totalLength;d.totalShapeLength=f,d.pathsData=l}c+=f,d.shape._mdf=!0}else d.shape.paths=d.localShapeCollection;var g,v=e,b=i,x=0;for(s=m-1;0<=s;s-=1)if((d=this.shapes[s]).shape._mdf){for((u=d.localShapeCollection).releaseShapes(),2===this.m&&1<m?(g=this.calculateShapeEdges(e,i,d.totalShapeLength,x,c),x+=d.totalShapeLength):g=[[v,b]],h=g.length,o=0;o<h;o+=1){v=g[o][0],b=g[o][1],y.length=0,b<=1?y.push({s:d.totalShapeLength*v,e:d.totalShapeLength*b}):1<=v?y.push({s:d.totalShapeLength*(v-1),e:d.totalShapeLength*(b-1)}):(y.push({s:d.totalShapeLength*v,e:d.totalShapeLength}),y.push({s:0,e:d.totalShapeLength*(b-1)}));var P=this.addShapes(d,y[0]);if(y[0].s!==y[0].e){if(1<y.length)if(d.shape.paths.shapes[d.shape.paths._length-1].c){var E=P.pop();this.addPaths(P,u),P=this.addShapes(d,y[1],E)}else this.addPaths(P,u),P=this.addShapes(d,y[1]);this.addPaths(P,u)}}d.shape.paths=u}}},TrimModifier.prototype.addPaths=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)e.addShape(t[i])},TrimModifier.prototype.addSegment=function(t,e,i,r,s,a,n){s.setXYAt(e[0],e[1],"o",a),s.setXYAt(i[0],i[1],"i",a+1),n&&s.setXYAt(t[0],t[1],"v",a),s.setXYAt(r[0],r[1],"v",a+1)},TrimModifier.prototype.addSegmentFromArray=function(t,e,i,r){e.setXYAt(t[1],t[5],"o",i),e.setXYAt(t[2],t[6],"i",i+1),r&&e.setXYAt(t[0],t[4],"v",i),e.setXYAt(t[3],t[7],"v",i+1)},TrimModifier.prototype.addShapes=function(t,e,i){var r,s,a,n,o,h,l,p,f=t.pathsData,m=t.shape.paths.shapes,c=t.shape.paths._length,d=0,u=[],y=!0;for(p=i?(o=i._length,i._length):(i=shapePool.newElement(),o=0),u.push(i),r=0;r<c;r+=1){for(h=f[r].lengths,i.c=m[r].c,a=m[r].c?h.length:h.length+1,s=1;s<a;s+=1)if(d+(n=h[s-1]).addedLength<e.s)d+=n.addedLength,i.c=!1;else{if(d>e.e){i.c=!1;break}e.s<=d&&e.e>=d+n.addedLength?(this.addSegment(m[r].v[s-1],m[r].o[s-1],m[r].i[s],m[r].v[s],i,o,y),y=!1):(l=bez.getNewSegment(m[r].v[s-1],m[r].v[s],m[r].o[s-1],m[r].i[s],(e.s-d)/n.addedLength,(e.e-d)/n.addedLength,h[s-1]),this.addSegmentFromArray(l,i,o,y),y=!1,i.c=!1),d+=n.addedLength,o+=1}if(m[r].c&&h.length){if(n=h[s-1],d<=e.e){var g=h[s-1].addedLength;e.s<=d&&e.e>=d+g?(this.addSegment(m[r].v[s-1],m[r].o[s-1],m[r].i[0],m[r].v[0],i,o,y),y=!1):(l=bez.getNewSegment(m[r].v[s-1],m[r].v[0],m[r].o[s-1],m[r].i[0],(e.s-d)/g,(e.e-d)/g,h[s-1]),this.addSegmentFromArray(l,i,o,y),y=!1,i.c=!1)}else i.c=!1;d+=n.addedLength,o+=1}if(i._length&&(i.setXYAt(i.v[p][0],i.v[p][1],"i",p),i.setXYAt(i.v[i._length-1][0],i.v[i._length-1][1],"o",i._length-1)),d>e.e)break;r<c-1&&(i=shapePool.newElement(),y=!0,u.push(i),o=0)}return u},extendPrototype([ShapeModifier],PuckerAndBloatModifier),PuckerAndBloatModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},PuckerAndBloatModifier.prototype.processPath=function(t,e){var i=e/100,r=[0,0],s=t._length,a=0;for(a=0;a<s;a+=1)r[0]+=t.v[a][0],r[1]+=t.v[a][1];r[0]/=s,r[1]/=s;var n,o,h,l,p,f,m=shapePool.newElement();for(m.c=t.c,a=0;a<s;a+=1)n=t.v[a][0]+(r[0]-t.v[a][0])*i,o=t.v[a][1]+(r[1]-t.v[a][1])*i,h=t.o[a][0]+(r[0]-t.o[a][0])*-i,l=t.o[a][1]+(r[1]-t.o[a][1])*-i,p=t.i[a][0]+(r[0]-t.i[a][0])*-i,f=t.i[a][1]+(r[1]-t.i[a][1])*-i,m.setTripleAt(n,o,h,l,p,f,a);return m},PuckerAndBloatModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amount.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var TransformPropertyFactory=function(){var n=[0,0];function r(t,e,i){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Matrix,this.pre=new Matrix,this.appliedTransformations=0,this.initDynamicPropertyContainer(i||t),e.p&&e.p.s?(this.px=PropertyFactory.getProp(t,e.p.x,0,0,this),this.py=PropertyFactory.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=PropertyFactory.getProp(t,e.p.z,0,0,this))):this.p=PropertyFactory.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=PropertyFactory.getProp(t,e.rx,0,degToRads,this),this.ry=PropertyFactory.getProp(t,e.ry,0,degToRads,this),this.rz=PropertyFactory.getProp(t,e.rz,0,degToRads,this),e.or.k[0].ti){var r,s=e.or.k.length;for(r=0;r<s;r+=1)e.or.k[r].to=null,e.or.k[r].ti=null}this.or=PropertyFactory.getProp(t,e.or,1,degToRads,this),this.or.sh=!0}else this.r=PropertyFactory.getProp(t,e.r||{k:0},0,degToRads,this);e.sk&&(this.sk=PropertyFactory.getProp(t,e.sk,0,degToRads,this),this.sa=PropertyFactory.getProp(t,e.sa,0,degToRads,this)),this.a=PropertyFactory.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=PropertyFactory.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=PropertyFactory.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return r.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(t){if(this.elem.globalData.frameId!==this.frameId){if(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),this._mdf||t){var e;if(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented){var i,r;if(e=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime)r=this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(i=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/e,0),this.p.getValueAtTime(this.p.keyframes[0].t/e,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(i=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/e,0),this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/e,0)):(i=this.p.pv,this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/e,this.p.offsetTime));else if(this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime){i=[],r=[];var s=this.px,a=this.py;s._caching.lastFrame+s.offsetTime<=s.keyframes[0].t?(i[0]=s.getValueAtTime((s.keyframes[0].t+.01)/e,0),i[1]=a.getValueAtTime((a.keyframes[0].t+.01)/e,0),r[0]=s.getValueAtTime(s.keyframes[0].t/e,0),r[1]=a.getValueAtTime(a.keyframes[0].t/e,0)):s._caching.lastFrame+s.offsetTime>=s.keyframes[s.keyframes.length-1].t?(i[0]=s.getValueAtTime(s.keyframes[s.keyframes.length-1].t/e,0),i[1]=a.getValueAtTime(a.keyframes[a.keyframes.length-1].t/e,0),r[0]=s.getValueAtTime((s.keyframes[s.keyframes.length-1].t-.01)/e,0),r[1]=a.getValueAtTime((a.keyframes[a.keyframes.length-1].t-.01)/e,0)):(i=[s.pv,a.pv],r[0]=s.getValueAtTime((s._caching.lastFrame+s.offsetTime-.01)/e,s.offsetTime),r[1]=a.getValueAtTime((a._caching.lastFrame+a.offsetTime-.01)/e,a.offsetTime))}else i=r=n;this.v.rotate(-Math.atan2(i[1]-r[1],i[0]-r[0]))}this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])}this.frameId=this.elem.globalData.frameId}},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],r),r.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},r.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,e,i){return new r(t,e,i)}}}();function RepeaterModifier(){}function RoundCornersModifier(){}function floatEqual(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function floatZero(t){return Math.abs(t)<=1e-5}function lerp(t,e,i){return t*(1-i)+e*i}function lerpPoint(t,e,i){return[lerp(t[0],e[0],i),lerp(t[1],e[1],i)]}function quadRoots(t,e,i){if(0===t)return[];var r=e*e-4*t*i;if(r<0)return[];var s=-e/(2*t);if(0===r)return[s];var a=Math.sqrt(r)/(2*t);return[s-a,s+a]}function polynomialCoefficients(t,e,i,r){return[3*e-t-3*i+r,3*t-6*e+3*i,-3*t+3*e,t]}function singlePoint(t){return new PolynomialBezier(t,t,t,t,!1)}function PolynomialBezier(t,e,i,r,s){s&&pointEqual(t,e)&&(e=lerpPoint(t,r,1/3)),s&&pointEqual(i,r)&&(i=lerpPoint(t,r,2/3));var a=polynomialCoefficients(t[0],e[0],i[0],r[0]),n=polynomialCoefficients(t[1],e[1],i[1],r[1]);this.a=[a[0],n[0]],this.b=[a[1],n[1]],this.c=[a[2],n[2]],this.d=[a[3],n[3]],this.points=[t,e,i,r]}function extrema(t,e){var i=t.points[0][e],r=t.points[t.points.length-1][e];if(r<i){var s=r;r=i,i=s}for(var a=quadRoots(3*t.a[e],2*t.b[e],t.c[e]),n=0;n<a.length;n+=1)if(0<a[n]&&a[n]<1){var o=t.point(a[n])[e];o<i?i=o:r<o&&(r=o)}return{min:i,max:r}}function intersectData(t,e,i){var r=t.boundingBox();return{cx:r.cx,cy:r.cy,width:r.width,height:r.height,bez:t,t:(e+i)/2,t1:e,t2:i}}function splitData(t){var e=t.bez.split(.5);return[intersectData(e[0],t.t1,t.t),intersectData(e[1],t.t,t.t2)]}function boxIntersect(t,e){return 2*Math.abs(t.cx-e.cx)<t.width+e.width&&2*Math.abs(t.cy-e.cy)<t.height+e.height}function intersectsImpl(t,e,i,r,s,a){if(boxIntersect(t,e))if(a<=i||t.width<=r&&t.height<=r&&e.width<=r&&e.height<=r)s.push([t.t,e.t]);else{var n=splitData(t),o=splitData(e);intersectsImpl(n[0],o[0],i+1,r,s,a),intersectsImpl(n[0],o[1],i+1,r,s,a),intersectsImpl(n[1],o[0],i+1,r,s,a),intersectsImpl(n[1],o[1],i+1,r,s,a)}}function crossProduct(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function lineIntersection(t,e,i,r){var s=[t[0],t[1],1],a=[e[0],e[1],1],n=[i[0],i[1],1],o=[r[0],r[1],1],h=crossProduct(crossProduct(s,a),crossProduct(n,o));return floatZero(h[2])?null:[h[0]/h[2],h[1]/h[2]]}function polarOffset(t,e,i){return[t[0]+Math.cos(e)*i,t[1]-Math.sin(e)*i]}function pointDistance(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function pointEqual(t,e){return floatEqual(t[0],e[0])&&floatEqual(t[1],e[1])}function ZigZagModifier(){}function setPoint(t,e,i,r,s,a,n){var o=i-Math.PI/2,h=i+Math.PI/2,l=e[0]+Math.cos(i)*r*s,p=e[1]-Math.sin(i)*r*s;t.setTripleAt(l,p,l+Math.cos(o)*a,p-Math.sin(o)*a,l+Math.cos(h)*n,p-Math.sin(h)*n,t.length())}function getPerpendicularVector(t,e){var i=[e[0]-t[0],e[1]-t[1]],r=.5*-Math.PI;return[Math.cos(r)*i[0]-Math.sin(r)*i[1],Math.sin(r)*i[0]+Math.cos(r)*i[1]]}function getProjectingAngle(t,e){var i=0===e?t.length()-1:e-1,r=(e+1)%t.length(),s=getPerpendicularVector(t.v[i],t.v[r]);return Math.atan2(0,1)-Math.atan2(s[1],s[0])}function zigZagCorner(t,e,i,r,s,a,n){var o=getProjectingAngle(e,i),h=e.v[i%e._length],l=e.v[0===i?e._length-1:i-1],p=e.v[(i+1)%e._length],f=2===a?Math.sqrt(Math.pow(h[0]-l[0],2)+Math.pow(h[1]-l[1],2)):0,m=2===a?Math.sqrt(Math.pow(h[0]-p[0],2)+Math.pow(h[1]-p[1],2)):0;setPoint(t,e.v[i%e._length],o,n,r,m/(2*(s+1)),f/(2*(s+1)),a)}function zigZagSegment(t,e,i,r,s,a){for(var n=0;n<r;n+=1){var o=(n+1)/(r+1),h=2===s?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(o);setPoint(t,e.point(o),l,a,i,h/(2*(r+1)),h/(2*(r+1)),s),a=-a}return a}function linearOffset(t,e,i){var r=Math.atan2(e[0]-t[0],e[1]-t[1]);return[polarOffset(t,r,i),polarOffset(e,r,i)]}function offsetSegment(t,e){var i,r,s,a,n,o,h;i=(h=linearOffset(t.points[0],t.points[1],e))[0],r=h[1],s=(h=linearOffset(t.points[1],t.points[2],e))[0],a=h[1],n=(h=linearOffset(t.points[2],t.points[3],e))[0],o=h[1];var l=lineIntersection(i,r,s,a);null===l&&(l=r);var p=lineIntersection(n,o,s,a);return null===p&&(p=n),new PolynomialBezier(i,l,p,o)}function joinLines(t,e,i,r,s){var a=e.points[3],n=i.points[0];if(3===r)return a;if(pointEqual(a,n))return a;if(2===r){var o=-e.tangentAngle(1),h=-i.tangentAngle(0)+Math.PI,l=lineIntersection(a,polarOffset(a,o+Math.PI/2,100),n,polarOffset(n,o+Math.PI/2,100)),p=l?pointDistance(l,a):pointDistance(a,n)/2,f=polarOffset(a,o,2*p*roundCorner);return t.setXYAt(f[0],f[1],"o",t.length()-1),f=polarOffset(n,h,2*p*roundCorner),t.setTripleAt(n[0],n[1],n[0],n[1],f[0],f[1],t.length()),n}var m=lineIntersection(pointEqual(a,e.points[2])?e.points[0]:e.points[2],a,n,pointEqual(n,i.points[1])?i.points[3]:i.points[1]);return m&&pointDistance(m,a)<s?(t.setTripleAt(m[0],m[1],m[0],m[1],m[0],m[1],t.length()),m):a}function getIntersection(t,e){var i=t.intersections(e);return i.length&&floatEqual(i[0][0],1)&&i.shift(),i.length?i[0]:null}function pruneSegmentIntersection(t,e){var i=t.slice(),r=e.slice(),s=getIntersection(t[t.length-1],e[0]);return s&&(i[t.length-1]=t[t.length-1].split(s[0])[0],r[0]=e[0].split(s[1])[1]),1<t.length&&1<e.length&&(s=getIntersection(t[0],e[e.length-1]))?[[t[0].split(s[0])[0]],[e[e.length-1].split(s[1])[1]]]:[i,r]}function pruneIntersections(t){for(var e,i=1;i<t.length;i+=1)e=pruneSegmentIntersection(t[i-1],t[i]),t[i-1]=e[0],t[i]=e[1];return 1<t.length&&(e=pruneSegmentIntersection(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}function offsetSegmentSplit(t,e){var i,r,s,a,n=t.inflectionPoints();if(0===n.length)return[offsetSegment(t,e)];if(1===n.length||floatEqual(n[1],1))return i=(s=t.split(n[0]))[0],r=s[1],[offsetSegment(i,e),offsetSegment(r,e)];i=(s=t.split(n[0]))[0];var o=(n[1]-n[0])/(1-n[0]);return a=(s=s[1].split(o))[0],r=s[1],[offsetSegment(i,e),offsetSegment(a,e),offsetSegment(r,e)]}function OffsetPathModifier(){}function getFontProperties(t){for(var e=t.fStyle?t.fStyle.split(" "):[],i="normal",r="normal",s=e.length,a=0;a<s;a+=1)switch(e[a].toLowerCase()){case"italic":r="italic";break;case"bold":i="700";break;case"black":i="900";break;case"medium":i="500";break;case"regular":case"normal":i="400";break;case"light":case"thin":i="200"}return{style:r,weight:t.fWeight||i}}extendPrototype([ShapeModifier],RepeaterModifier),RepeaterModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=PropertyFactory.getProp(t,e.c,0,null,this),this.o=PropertyFactory.getProp(t,e.o,0,null,this),this.tr=TransformPropertyFactory.getTransformProperty(t,e.tr,this),this.so=PropertyFactory.getProp(t,e.tr.so,0,.01,this),this.eo=PropertyFactory.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Matrix,this.rMatrix=new Matrix,this.sMatrix=new Matrix,this.tMatrix=new Matrix,this.matrix=new Matrix},RepeaterModifier.prototype.applyTransforms=function(t,e,i,r,s,a){var n=a?-1:1,o=r.s.v[0]+(1-r.s.v[0])*(1-s),h=r.s.v[1]+(1-r.s.v[1])*(1-s);t.translate(r.p.v[0]*n*s,r.p.v[1]*n*s,r.p.v[2]),e.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),e.rotate(-r.r.v*n*s),e.translate(r.a.v[0],r.a.v[1],r.a.v[2]),i.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),i.scale(a?1/o:o,a?1/h:h),i.translate(r.a.v[0],r.a.v[1],r.a.v[2])},RepeaterModifier.prototype.init=function(t,e,i,r){for(this.elem=t,this.arr=e,this.pos=i,this.elemsData=r,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[i]);0<i;)i-=1,this._elements.unshift(e[i]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e]._processed=!1,"gr"===t[e].ty&&this.resetElements(t[e].it)},RepeaterModifier.prototype.cloneElements=function(t){var e=JSON.parse(JSON.stringify(t));return this.resetElements(e),e},RepeaterModifier.prototype.changeGroupRender=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)t[i]._render=e,"gr"===t[i].ty&&this.changeGroupRender(t[i].it,e)},RepeaterModifier.prototype.processShapes=function(t){var e,i,r,s,a,n=!1;if(this._mdf||t){var o,h=Math.ceil(this.c.v);if(this._groups.length<h){for(;this._groups.length<h;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(r=a=0;r<=this._groups.length-1;r+=1){if(o=a<h,this._groups[r]._render=o,this.changeGroupRender(this._groups[r].it,o),!o){var p=this.elemsData[r].it,f=p[p.length-1];0!==f.transform.op.v?(f.transform.op._mdf=!0,f.transform.op.v=0):f.transform.op._mdf=!1}a+=1}this._currentCopies=h;var m=this.o.v,c=m%1,d=0<m?Math.floor(m):Math.ceil(m),u=this.pMatrix.props,y=this.rMatrix.props,g=this.sMatrix.props;this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset();var v,b,x=0;if(0<m){for(;x<d;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),x+=1;c&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,c,!1),x+=c)}else if(m<0){for(;d<x;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),x-=1;c&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-c,!0),x-=c)}for(r=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(b=(i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(r/(this._currentCopies-1)),0!==x){for((0!==r&&1===s||r!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]),this.matrix.transform(u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]),v=0;v<b;v+=1)i[v]=this.matrix.props[v];this.matrix.reset()}else for(this.matrix.reset(),v=0;v<b;v+=1)i[v]=this.matrix.props[v];x+=1,a-=1,r+=s}}else for(a=this._currentCopies,r=0,s=1;a;)i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,a-=1,r+=s;return n},RepeaterModifier.prototype.addShape=function(){},extendPrototype([ShapeModifier],RoundCornersModifier),RoundCornersModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=PropertyFactory.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},RoundCornersModifier.prototype.processPath=function(t,e){var i,r=shapePool.newElement();r.c=t.c;var s,a,n,o,h,l,p,f,m,c,d,u,y=t._length,g=0;for(i=0;i<y;i+=1)s=t.v[i],n=t.o[i],a=t.i[i],s[0]===n[0]&&s[1]===n[1]&&s[0]===a[0]&&s[1]===a[1]?0!==i&&i!==y-1||t.c?(o=0===i?t.v[y-1]:t.v[i-1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=d=s[0]+(o[0]-s[0])*l,f=u=s[1]-(s[1]-o[1])*l,m=p-(p-s[0])*roundCorner,c=f-(f-s[1])*roundCorner,r.setTripleAt(p,f,m,c,d,u,g),g+=1,o=i===y-1?t.v[0]:t.v[i+1],l=(h=Math.sqrt(Math.pow(s[0]-o[0],2)+Math.pow(s[1]-o[1],2)))?Math.min(h/2,e)/h:0,p=m=s[0]+(o[0]-s[0])*l,f=c=s[1]+(o[1]-s[1])*l,d=p-(p-s[0])*roundCorner,u=f-(f-s[1])*roundCorner,r.setTripleAt(p,f,m,c,d,u,g)):r.setTripleAt(s[0],s[1],n[0],n[1],a[0],a[1],g):r.setTripleAt(t.v[i][0],t.v[i][1],t.o[i][0],t.o[i][1],t.i[i][0],t.i[i][1],g),g+=1;return r},RoundCornersModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.rd.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},PolynomialBezier.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},PolynomialBezier.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},PolynomialBezier.prototype.tangentAngle=function(t){var e=this.derivative(t);return Math.atan2(e[1],e[0])},PolynomialBezier.prototype.normalAngle=function(t){var e=this.derivative(t);return Math.atan2(e[0],e[1])},PolynomialBezier.prototype.inflectionPoints=function(){var t=this.a[1]*this.b[0]-this.a[0]*this.b[1];if(floatZero(t))return[];var e=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/t,i=e*e-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/t;if(i<0)return[];var r=Math.sqrt(i);return floatZero(r)?0<r&&r<1?[e]:[]:[e-r,e+r].filter(function(t){return 0<t&&t<1})},PolynomialBezier.prototype.split=function(t){if(t<=0)return[singlePoint(this.points[0]),this];if(1<=t)return[this,singlePoint(this.points[this.points.length-1])];var e=lerpPoint(this.points[0],this.points[1],t),i=lerpPoint(this.points[1],this.points[2],t),r=lerpPoint(this.points[2],this.points[3],t),s=lerpPoint(e,i,t),a=lerpPoint(i,r,t),n=lerpPoint(s,a,t);return[new PolynomialBezier(this.points[0],e,s,n,!0),new PolynomialBezier(n,a,r,this.points[3],!0)]},PolynomialBezier.prototype.bounds=function(){return{x:extrema(this,0),y:extrema(this,1)}},PolynomialBezier.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},PolynomialBezier.prototype.intersections=function(t,e,i){void 0===e&&(e=2),void 0===i&&(i=7);var r=[];return intersectsImpl(intersectData(this,0,1),intersectData(t,0,1),0,e,r,i),r},PolynomialBezier.shapeSegment=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[e],t.o[e],t.i[i],t.v[i],!0)},PolynomialBezier.shapeSegmentInverted=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[i],t.i[i],t.o[e],t.v[e],!0)},extendPrototype([ShapeModifier],ZigZagModifier),ZigZagModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=PropertyFactory.getProp(t,e.s,0,null,this),this.frequency=PropertyFactory.getProp(t,e.r,0,null,this),this.pointsType=PropertyFactory.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},ZigZagModifier.prototype.processPath=function(t,e,i,r){var s=t._length,a=shapePool.newElement();if(a.c=t.c,t.c||(s-=1),0===s)return a;var n=-1,o=PolynomialBezier.shapeSegment(t,0);zigZagCorner(a,t,0,e,i,r,n);for(var h=0;h<s;h+=1)n=zigZagSegment(a,o,e,i,r,-n),o=h!==s-1||t.c?PolynomialBezier.shapeSegment(t,(h+1)%s):null,zigZagCorner(a,t,h+1,e,i,r,n);return a},ZigZagModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amplitude.v,l=Math.max(0,Math.round(this.frequency.v)),p=this.pointsType.v;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h,l,p));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},extendPrototype([ShapeModifier],OffsetPathModifier),OffsetPathModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this.miterLimit=PropertyFactory.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},OffsetPathModifier.prototype.processPath=function(t,e,i,r){var s=shapePool.newElement();s.c=t.c;var a,n,o,h=t.length();t.c||(h-=1);var l=[];for(a=0;a<h;a+=1)o=PolynomialBezier.shapeSegment(t,a),l.push(offsetSegmentSplit(o,e));if(!t.c)for(a=h-1;0<=a;a-=1)o=PolynomialBezier.shapeSegmentInverted(t,a),l.push(offsetSegmentSplit(o,e));l=pruneIntersections(l);var p=null,f=null;for(a=0;a<l.length;a+=1){var m=l[a];for(f&&(p=joinLines(s,f,m[0],i,r)),f=m[m.length-1],n=0;n<m.length;n+=1)o=m[n],p&&pointEqual(o.points[0],p)?s.setXYAt(o.points[1][0],o.points[1][1],"o",s.length()-1):s.setTripleAt(o.points[0][0],o.points[0][1],o.points[1][0],o.points[1][1],o.points[0][0],o.points[0][1],s.length()),s.setTripleAt(o.points[3][0],o.points[3][1],o.points[3][0],o.points[3][1],o.points[2][0],o.points[2][1],s.length()),p=o.points[3]}return l.length&&joinLines(s,f,l[0][0],i,r),s},OffsetPathModifier.prototype.processShapes=function(t){var e,i,r,s,a,n,o=this.shapes.length,h=this.amount.v,l=this.miterLimit.v,p=this.lineJoin;if(0!==h)for(i=0;i<o;i+=1){if(n=(a=this.shapes[i]).localShapeCollection,a.shape._mdf||this._mdf||t)for(n.releaseShapes(),a.shape._mdf=!0,e=a.shape.paths.shapes,s=a.shape.paths._length,r=0;r<s;r+=1)n.addShape(this.processPath(e[r],h,p,l));a.shape.paths=a.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var FontManager=function(){var a={w:0,size:0,shapes:[],data:{shapes:[]}},e=[];e=e.concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]);var i=127462,r=127487,s=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function m(t,e){var i=createTag("span");i.setAttribute("aria-hidden",!0),i.style.fontFamily=e;var r=createTag("span");r.innerText="giItT1WQy@!-/#",i.style.position="absolute",i.style.left="-10000px",i.style.top="-10000px",i.style.fontSize="300px",i.style.fontVariant="normal",i.style.fontStyle="normal",i.style.fontWeight="normal",i.style.letterSpacing="0",i.appendChild(r),document.body.appendChild(i);var s=r.offsetWidth;return r.style.fontFamily=function(t){var e,i=t.split(","),r=i.length,s=[];for(e=0;e<r;e+=1)"sans-serif"!==i[e]&&"monospace"!==i[e]&&s.push(i[e]);return s.join(",")}(t)+", "+e,{node:r,w:s,parent:i}}function c(t,e){var i,r=document.body&&e?"svg":"canvas",s=getFontProperties(t);if("svg"===r){var a=createNS("text");a.style.fontSize="100px",a.setAttribute("font-family",t.fFamily),a.setAttribute("font-style",s.style),a.setAttribute("font-weight",s.weight),a.textContent="1",t.fClass?(a.style.fontFamily="inherit",a.setAttribute("class",t.fClass)):a.style.fontFamily=t.fFamily,e.appendChild(a),i=a}else{var n=new OffscreenCanvas(500,500).getContext("2d");n.font=s.style+" "+s.weight+" 100px "+t.fFamily,i=n}return{measureText:function(t){return"svg"===r?(i.textContent=t,i.getComputedTextLength()):i.measureText(t).width}}}function n(t){var e=0,i=t.charCodeAt(0);if(55296<=i&&i<=56319){var r=t.charCodeAt(1);56320<=r&&r<=57343&&(e=1024*(i-55296)+r-56320+65536)}return e}function o(t){var e=n(t);return i<=e&&e<=r}var t=function(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)};return t.isModifier=function(t,e){var i=t.toString(16)+e.toString(16);return-1!==s.indexOf(i)},t.isZeroWidthJoiner=function(t){return 8205===t},t.isFlagEmoji=function(t){return o(t.substr(0,2))&&o(t.substr(2,2))},t.isRegionalCode=o,t.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},t.isRegionalFlag=function(t,e){var i=n(t.substr(e,2));if(127988!==i)return!1;var r=0;for(e+=2;r<5;){if((i=n(t.substr(e,2)))<917601||917626<i)return!1;r+=1,e+=2}return 917631===n(t.substr(e,2))},t.isVariationSelector=function(t){return 65039===t},t.BLACK_FLAG_CODE_POINT=127988,t.prototype={addChars:function(t){if(t){var e;this.chars||(this.chars=[]);var i,r,s=t.length,a=this.chars.length;for(e=0;e<s;e+=1){for(i=0,r=!1;i<a;)this.chars[i].style===t[e].style&&this.chars[i].fFamily===t[e].fFamily&&this.chars[i].ch===t[e].ch&&(r=!0),i+=1;r||(this.chars.push(t[e]),a+=1)}}},addFonts:function(t,e){if(t){if(this.chars)return this.isLoaded=!0,void(this.fonts=t.list);if(!document.body)return this.isLoaded=!0,t.list.forEach(function(t){t.helper=c(t),t.cache={}}),void(this.fonts=t.list);var i,r=t.list,s=r.length,a=s;for(i=0;i<s;i+=1){var n,o,h=!0;if(r[i].loaded=!1,r[i].monoCase=m(r[i].fFamily,"monospace"),r[i].sansCase=m(r[i].fFamily,"sans-serif"),r[i].fPath){if("p"===r[i].fOrigin||3===r[i].origin){if(0<(n=document.querySelectorAll('style[f-forigin="p"][f-family="'+r[i].fFamily+'"], style[f-origin="3"][f-family="'+r[i].fFamily+'"]')).length&&(h=!1),h){var l=createTag("style");l.setAttribute("f-forigin",r[i].fOrigin),l.setAttribute("f-origin",r[i].origin),l.setAttribute("f-family",r[i].fFamily),l.type="text/css",l.innerText="@font-face {font-family: "+r[i].fFamily+"; font-style: normal; src: url('"+r[i].fPath+"');}",e.appendChild(l)}}else if("g"===r[i].fOrigin||1===r[i].origin){for(n=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),o=0;o<n.length;o+=1)-1!==n[o].href.indexOf(r[i].fPath)&&(h=!1);if(h){var p=createTag("link");p.setAttribute("f-forigin",r[i].fOrigin),p.setAttribute("f-origin",r[i].origin),p.type="text/css",p.rel="stylesheet",p.href=r[i].fPath,document.body.appendChild(p)}}else if("t"===r[i].fOrigin||2===r[i].origin){for(n=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),o=0;o<n.length;o+=1)r[i].fPath===n[o].src&&(h=!1);if(h){var f=createTag("link");f.setAttribute("f-forigin",r[i].fOrigin),f.setAttribute("f-origin",r[i].origin),f.setAttribute("rel","stylesheet"),f.setAttribute("href",r[i].fPath),e.appendChild(f)}}}else r[i].loaded=!0,a-=1;r[i].helper=c(r[i],e),r[i].cache={},this.fonts.push(r[i])}0===a?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0},getCharData:function(t,e,i){for(var r=0,s=this.chars.length;r<s;){if(this.chars[r].ch===t&&this.chars[r].style===e&&this.chars[r].fFamily===i)return this.chars[r];r+=1}return("string"==typeof t&&13!==t.charCodeAt(0)||!t)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",t,e,i)),a},getFontByName:function(t){for(var e=0,i=this.fonts.length;e<i;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,i){var r=this.getFontByName(e),s=t;if(!r.cache[s]){var a=r.helper;if(" "===t){var n=a.measureText("|"+t+"|"),o=a.measureText("||");r.cache[s]=(n-o)/100}else r.cache[s]=a.measureText(t)/100}return r.cache[s]*i},checkLoadedFonts:function(){var t,e,i,r=this.fonts.length,s=r;for(t=0;t<r;t+=1)this.fonts[t].loaded?s-=1:"n"===this.fonts[t].fOrigin||0===this.fonts[t].origin?this.fonts[t].loaded=!0:(e=this.fonts[t].monoCase.node,i=this.fonts[t].monoCase.w,e.offsetWidth!==i?(s-=1,this.fonts[t].loaded=!0):(e=this.fonts[t].sansCase.node,i=this.fonts[t].sansCase.w,e.offsetWidth!==i&&(s-=1,this.fonts[t].loaded=!0)),this.fonts[t].loaded&&(this.fonts[t].sansCase.parent.parentNode.removeChild(this.fonts[t].sansCase.parent),this.fonts[t].monoCase.parent.parentNode.removeChild(this.fonts[t].monoCase.parent)));0!==s&&Date.now()-this.initTime<5e3?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}},t}();function SlotManager(t){this.animationData=t}function slotFactory(t){return new SlotManager(t)}function RenderableElement(){}SlotManager.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},RenderableElement.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){var t,e=this.renderableComponents.length;for(t=0;t<e;t+=1)this.renderableComponents[t].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var getBlendMode=(eJ={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"},function(t){return eJ[t]||""}),eJ;function SliderEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function AngleEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function ColorEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function PointEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function LayerIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function MaskIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function CheckboxEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function NoValueEffect(){this.p={}}function EffectsManager(t,e){var i,r=t.ef||[];this.effectElements=[];var s,a=r.length;for(i=0;i<a;i+=1)s=new GroupEffect(r[i],e),this.effectElements.push(s)}function GroupEffect(t,e){this.init(t,e)}function BaseElement(){}function FrameElement(){}function FootageElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,i)}function AudioElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,i),this._isPlaying=!1,this._canPlay=!1;var r=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(r),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=PropertyFactory.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function BaseRenderer(){}extendPrototype([DynamicPropertyContainer],GroupEffect),GroupEffect.prototype.getValue=GroupEffect.prototype.iterateDynamicProperties,GroupEffect.prototype.init=function(t,e){var i;this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);var r,s=this.data.ef.length,a=this.data.ef;for(i=0;i<s;i+=1){switch(r=null,a[i].ty){case 0:r=new SliderEffect(a[i],e,this);break;case 1:r=new AngleEffect(a[i],e,this);break;case 2:r=new ColorEffect(a[i],e,this);break;case 3:r=new PointEffect(a[i],e,this);break;case 4:case 7:r=new CheckboxEffect(a[i],e,this);break;case 10:r=new LayerIndexEffect(a[i],e,this);break;case 11:r=new MaskIndexEffect(a[i],e,this);break;case 5:r=new EffectsManager(a[i],e,this);break;default:r=new NoValueEffect(a[i],e,this)}r&&this.effectElements.push(r)}},BaseElement.prototype={checkMasks:function(){if(!this.data.hasMask)return!1;for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t=getExpressionInterfaces();if(t){var e=t("layer"),i=t("effects"),r=t("shape"),s=t("text"),a=t("comp");this.layerInterface=e(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager);var n=i.createEffectsInterface(this,this.layerInterface);this.layerInterface.registerEffectsInterface(n),0===this.data.ty||this.data.xt?this.compInterface=a(this):4===this.data.ty?(this.layerInterface.shapeInterface=r(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=s(this),this.layerInterface.text=this.layerInterface.textInterface)}},setBlendMode:function(){var t=getBlendMode(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,i){this.globalData=e,this.comp=i,this.data=t,this.layerId=createElementID(),this.data.sr||(this.data.sr=1),this.effectsManager=new EffectsManager(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},FrameElement.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){var i,r=this.dynamicProperties.length;for(i=0;i<r;i+=1)(e||this._isParent&&"transform"===this.dynamicProperties[i].propType)&&(this.dynamicProperties[i].getValue(),this.dynamicProperties[i]._mdf&&(this.globalData._mdf=!0,this._mdf=!0))},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},FootageElement.prototype.prepareFrame=function(){},extendPrototype([RenderableElement,BaseElement,FrameElement],FootageElement),FootageElement.prototype.getBaseElement=function(){return null},FootageElement.prototype.renderFrame=function(){},FootageElement.prototype.destroy=function(){},FootageElement.prototype.initExpressions=function(){var t=getExpressionInterfaces();if(t){var e=t("footage");this.layerInterface=e(this)}},FootageElement.prototype.getFootageData=function(){return this.footageData},AudioElement.prototype.prepareFrame=function(t){if(this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder)this._currentTime=t/this.data.sr;else{var e=this.tm.v;this._currentTime=e}this._volume=this.lv.v[0];var i=this._volume*this._volumeMultiplier;this._previousVolume!==i&&(this._previousVolume=i,this.audio.volume(i))},extendPrototype([RenderableElement,BaseElement,FrameElement],AudioElement),AudioElement.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||.1<Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek()))&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},AudioElement.prototype.show=function(){},AudioElement.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},AudioElement.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},AudioElement.prototype.resume=function(){this._canPlay=!0},AudioElement.prototype.setRate=function(t){this.audio.rate(t)},AudioElement.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},AudioElement.prototype.getBaseElement=function(){return null},AudioElement.prototype.destroy=function(){},AudioElement.prototype.sourceRectAtTime=function(){},AudioElement.prototype.initExpressions=function(){},BaseRenderer.prototype.checkLayers=function(t){var e,i,r=this.layers.length;for(this.completeLayers=!0,e=r-1;0<=e;e-=1)this.elements[e]||(i=this.layers[e]).ip-i.st<=t-this.layers[e].st&&i.op-i.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t);default:return this.createNull(t)}},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.createAudio=function(t){return new AudioElement(t,this.globalData,this)},BaseRenderer.prototype.createFootage=function(t){return new FootageElement(t,this.globalData,this)},BaseRenderer.prototype.buildAllItems=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.buildItem(t);this.checkPendingElements()},BaseRenderer.prototype.includeLayers=function(t){var e;this.completeLayers=!1;var i,r=t.length,s=this.layers.length;for(e=0;e<r;e+=1)for(i=0;i<s;){if(this.layers[i].id===t[e].id){this.layers[i]=t[e];break}i+=1}},BaseRenderer.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},BaseRenderer.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},BaseRenderer.prototype.buildElementParenting=function(t,e,i){for(var r=this.elements,s=this.layers,a=0,n=s.length;a<n;)s[a].ind==e&&(r[a]&&!0!==r[a]?(i.push(r[a]),r[a].setAsParent(),void 0!==s[a].parent?this.buildElementParenting(t,s[a].parent,i):t.setHierarchy(i)):(this.buildItem(a),this.addPendingElement(t))),a+=1},BaseRenderer.prototype.addPendingElement=function(t){this.pendingElements.push(t)},BaseRenderer.prototype.searchExtraCompositions=function(t){var e,i=t.length;for(e=0;e<i;e+=1)if(t[e].xt){var r=this.createComp(t[e]);r.initExpressions(),this.globalData.projectInterface.registerComposition(r)}},BaseRenderer.prototype.getElementById=function(t){var e,i=this.elements.length;for(e=0;e<i;e+=1)if(this.elements[e].data.ind===t)return this.elements[e];return null},BaseRenderer.prototype.getElementByPath=function(t){var e,i=t.shift();if("number"==typeof i)e=this.elements[i];else{var r,s=this.elements.length;for(r=0;r<s;r+=1)if(this.elements[r].data.nm===i){e=this.elements[r];break}}return 0===t.length?e:e.getElementByPath(t)},BaseRenderer.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new FontManager,this.globalData.slotManager=slotFactory(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var effectTypes={TRANSFORM_EFFECT:"transformEFfect"};function TransformElement(){}function MaskElement(t,e,i){this.data=t,this.element=e,this.globalData=i,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;var r,s,a=this.globalData.defs,n=this.masksProperties?this.masksProperties.length:0;this.viewData=createSizedArray(n),this.solidPath="";var o,h,l,p,f,m,c=this.masksProperties,d=0,u=[],y=createElementID(),g="clipPath",v="clip-path";for(r=0;r<n;r+=1)if(("a"!==c[r].mode&&"n"!==c[r].mode||c[r].inv||100!==c[r].o.k||c[r].o.x)&&(v=g="mask"),"s"!==c[r].mode&&"i"!==c[r].mode||0!==d?l=null:((l=createNS("rect")).setAttribute("fill","#ffffff"),l.setAttribute("width",this.element.comp.data.w||0),l.setAttribute("height",this.element.comp.data.h||0),u.push(l)),s=createNS("path"),"n"===c[r].mode)this.viewData[r]={op:PropertyFactory.getProp(this.element,c[r].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[r],3),elem:s,lastPath:""},a.appendChild(s);else{var b;if(d+=1,s.setAttribute("fill","s"===c[r].mode?"#000000":"#ffffff"),s.setAttribute("clip-rule","nonzero"),0!==c[r].x.k?(v=g="mask",m=PropertyFactory.getProp(this.element,c[r].x,0,null,this.element),b=createElementID(),(p=createNS("filter")).setAttribute("id",b),(f=createNS("feMorphology")).setAttribute("operator","erode"),f.setAttribute("in","SourceGraphic"),f.setAttribute("radius","0"),p.appendChild(f),a.appendChild(p),s.setAttribute("stroke","s"===c[r].mode?"#000000":"#ffffff")):m=f=null,this.storedData[r]={elem:s,x:m,expan:f,lastPath:"",lastOperator:"",filterId:b,lastRadius:0},"i"===c[r].mode){h=u.length;var x=createNS("g");for(o=0;o<h;o+=1)x.appendChild(u[o]);var P=createNS("mask");P.setAttribute("mask-type","alpha"),P.setAttribute("id",y+"_"+d),P.appendChild(s),a.appendChild(P),x.setAttribute("mask","url("+getLocationHref()+"#"+y+"_"+d+")"),u.length=0,u.push(x)}else u.push(s);c[r].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[r]={elem:s,lastPath:"",op:PropertyFactory.getProp(this.element,c[r].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,c[r],3),invRect:l},this.viewData[r].prop.k||this.drawPath(c[r],this.viewData[r].prop.v,this.viewData[r])}for(this.maskElement=createNS(g),n=u.length,r=0;r<n;r+=1)this.maskElement.appendChild(u[r]);0<d&&(this.maskElement.setAttribute("id",y),this.element.maskedElement.setAttribute(v,"url("+getLocationHref()+"#"+y+")"),a.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}TransformElement.prototype={initTransform:function(){var t=new Matrix;this.finalTransform={mProp:this.data.ks?TransformPropertyFactory.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,i=0,r=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;i<r;){if(this.hierarchy[i].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}i+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),i=0;i<r;i+=1)e.multiply(this.hierarchy[i].finalTransform.mProp.v)}this.finalTransform._matMdf&&(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var i=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(i),t=1;t<e;t+=1){var r=this.localTransforms[t].matrix;i.multiply(r)}i.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){var s=this.finalTransform.localOpacity;for(t=0;t<e;t+=1)s*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=s}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new Matrix;var e=0,i=t.length;for(e=0;e<i;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){var e=[];e.push(this.finalTransform);for(var i,r=!0,s=this.comp;r;)s.finalTransform?(s.data.hasMask&&e.splice(0,0,s.finalTransform),s=s.comp):r=!1;var a,n=e.length;for(i=0;i<n;i+=1)a=e[i].mat.applyToPointArray(0,0,0),t=[t[0]-a[0],t[1]-a[1],0];return t},mHelper:new Matrix},MaskElement.prototype.getMaskProperty=function(t){return this.viewData[t].prop},MaskElement.prototype.renderFrame=function(t){var e,i=this.element.finalTransform.mat,r=this.masksProperties.length;for(e=0;e<r;e+=1)if((this.viewData[e].prop._mdf||t)&&this.drawPath(this.masksProperties[e],this.viewData[e].prop.v,this.viewData[e]),(this.viewData[e].op._mdf||t)&&this.viewData[e].elem.setAttribute("fill-opacity",this.viewData[e].op.v),"n"!==this.masksProperties[e].mode&&(this.viewData[e].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[e].invRect.setAttribute("transform",i.getInverseMatrix().to2dCSS()),this.storedData[e].x&&(this.storedData[e].x._mdf||t))){var s=this.storedData[e].expan;this.storedData[e].x.v<0?("erode"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="erode",this.storedData[e].elem.setAttribute("filter","url("+getLocationHref()+"#"+this.storedData[e].filterId+")")),s.setAttribute("radius",-this.storedData[e].x.v)):("dilate"!==this.storedData[e].lastOperator&&(this.storedData[e].lastOperator="dilate",this.storedData[e].elem.setAttribute("filter",null)),this.storedData[e].elem.setAttribute("stroke-width",2*this.storedData[e].x.v))}},MaskElement.prototype.getMaskelement=function(){return this.maskElement},MaskElement.prototype.createLayerSolidPath=function(){var t="M0,0 ";return t+=" h"+this.globalData.compSize.w,t+=" v"+this.globalData.compSize.h,t+=" h-"+this.globalData.compSize.w,t+=" v-"+this.globalData.compSize.h+" "},MaskElement.prototype.drawPath=function(t,e,i){var r,s,a=" M"+e.v[0][0]+","+e.v[0][1];for(s=e._length,r=1;r<s;r+=1)a+=" C"+e.o[r-1][0]+","+e.o[r-1][1]+" "+e.i[r][0]+","+e.i[r][1]+" "+e.v[r][0]+","+e.v[r][1];if(e.c&&1<s&&(a+=" C"+e.o[r-1][0]+","+e.o[r-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),i.lastPath!==a){var n="";i.elem&&(e.c&&(n=t.inv?this.solidPath+a:a),i.elem.setAttribute("d",n)),i.lastPath=a}},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var filtersFactory=(tM={},tM.createFilter=function(t,e){var i=createNS("filter");return i.setAttribute("id",t),!0!==e&&(i.setAttribute("filterUnits","objectBoundingBox"),i.setAttribute("x","0%"),i.setAttribute("y","0%"),i.setAttribute("width","100%"),i.setAttribute("height","100%")),i},tM.createAlphaToLuminanceFilter=function(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t},tM),tM,featureSupport=(AM={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas},(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(AM.maskType=!1),/firefox/i.test(navigator.userAgent)&&(AM.svgLumaHidden=!1),AM),AM,registeredEffects$1={},idPrefix="filter_result_";function SVGEffects(t){var e,i,r="SourceGraphic",s=t.data.ef?t.data.ef.length:0,a=createElementID(),n=filtersFactory.createFilter(a,!0),o=0;for(this.filters=[],e=0;e<s;e+=1){i=null;var h=t.data.ef[e].ty;if(registeredEffects$1[h])i=new registeredEffects$1[h].effect(n,t.effectsManager.effectElements[e],t,idPrefix+o,r),r=idPrefix+o,registeredEffects$1[h].countsAsEffect&&(o+=1);i&&this.filters.push(i)}o&&(t.globalData.defs.appendChild(n),t.layerElement.setAttribute("filter","url("+getLocationHref()+"#"+a+")")),this.filters.length&&t.addRenderableComponent(this)}function registerEffect$1(t,e,i){registeredEffects$1[t]={effect:e,countsAsEffect:i}}function SVGBaseElement(){}function HierarchyElement(){}function RenderableDOMElement(){}function IImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,i),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ProcessedElement(t,e){this.elem=t,this.pos=e}function IShapeElement(){}SVGEffects.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},SVGEffects.prototype.getEffects=function(t){var e,i=this.filters.length,r=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&r.push(this.filters[e]);return r},SVGBaseElement.prototype={initRendererElement:function(){this.layerElement=createNS("g")},createContainerElements:function(){this.matteElement=createNS("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t=null;if(this.data.td){this.matteMasks={};var e=createNS("g");e.setAttribute("id",this.layerId),e.appendChild(this.layerElement),t=e,this.globalData.defs.appendChild(e)}else this.data.tt?(this.matteElement.appendChild(this.layerElement),t=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement;if(this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0===this.data.ty&&!this.data.hd){var i=createNS("clipPath"),r=createNS("path");r.setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z");var s=createElementID();if(i.setAttribute("id",s),i.appendChild(r),this.globalData.defs.appendChild(i),this.checkMasks()){var a=createNS("g");a.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),a.appendChild(this.layerElement),this.transformedElement=a,t?t.appendChild(this.transformedElement):this.baseElement=this.transformedElement}else this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")")}0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData),this.renderableEffectsManager=new SVGEffects(this),this.searchEffectTransforms()},getMatte:function(t){if(this.matteMasks||(this.matteMasks={}),!this.matteMasks[t]){var e,i,r,s,a=this.layerId+"_"+t;if(1===t||3===t){var n=createNS("mask");n.setAttribute("id",a),n.setAttribute("mask-type",3===t?"luminance":"alpha"),(r=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),n.appendChild(r),this.globalData.defs.appendChild(n),featureSupport.maskType||1!==t||(n.setAttribute("mask-type","luminance"),e=createElementID(),i=filtersFactory.createFilter(e),this.globalData.defs.appendChild(i),i.appendChild(filtersFactory.createAlphaToLuminanceFilter()),(s=createNS("g")).appendChild(r),n.appendChild(s),s.setAttribute("filter","url("+getLocationHref()+"#"+e+")"))}else if(2===t){var o=createNS("mask");o.setAttribute("id",a),o.setAttribute("mask-type","alpha");var h=createNS("g");o.appendChild(h),e=createElementID(),i=filtersFactory.createFilter(e);var l=createNS("feComponentTransfer");l.setAttribute("in","SourceGraphic"),i.appendChild(l);var p=createNS("feFuncA");p.setAttribute("type","table"),p.setAttribute("tableValues","1.0 0.0"),l.appendChild(p),this.globalData.defs.appendChild(i);var f=createNS("rect");f.setAttribute("width",this.comp.data.w),f.setAttribute("height",this.comp.data.h),f.setAttribute("x","0"),f.setAttribute("y","0"),f.setAttribute("fill","#ffffff"),f.setAttribute("opacity","0"),h.setAttribute("filter","url("+getLocationHref()+"#"+e+")"),h.appendChild(f),(r=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),h.appendChild(r),featureSupport.maskType||(o.setAttribute("mask-type","luminance"),i.appendChild(filtersFactory.createAlphaToLuminanceFilter()),s=createNS("g"),h.appendChild(f),s.appendChild(this.layerElement),h.appendChild(s)),this.globalData.defs.appendChild(o)}this.matteMasks[t]=a}return this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+getLocationHref()+"#"+t+")")}},HierarchyElement.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},extendPrototype([RenderableElement,createProxyFunction({initElement:function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],RenderableDOMElement),extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],IImageElement),IImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=createNS("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},IImageElement.prototype.sourceRectAtTime=function(){return this.sourceRect},IShapeElement.prototype={addShapeToModifiers:function(t){var e,i=this.shapeModifiers.length;for(e=0;e<i;e+=1)this.shapeModifiers[e].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){var t,e=this.shapes.length;for(t=0;t<e;t+=1)this.shapes[t].sh.reset();for(t=(e=this.shapeModifiers.length)-1;0<=t&&!this.shapeModifiers[t].processShapes(this._isFirstFrame);t-=1);}},searchProcessedElement:function(t){for(var e=this.processedElements,i=0,r=e.length;i<r;){if(e[i].elem===t)return e[i].pos;i+=1}return 0},addProcessedElement:function(t,e){for(var i=this.processedElements,r=i.length;r;)if(i[r-=1].elem===t)return void(i[r].pos=e);i.push(new ProcessedElement(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var lineCapEnum={1:"butt",2:"round",3:"square"},lineJoinEnum={1:"miter",2:"round",3:"bevel"};function SVGShapeData(t,e,i){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=i,this.lvl=e,this._isAnimated=!!i.k;for(var r=0,s=t.length;r<s;){if(t[r].mProps.dynamicProperties.length){this._isAnimated=!0;break}r+=1}}function SVGStyleData(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=createNS("path"),this.msElem=null}function DashProperty(t,e,i,r){var s;this.elem=t,this.frameId=-1,this.dataProps=createSizedArray(e.length),this.renderer=i,this.k=!1,this.dashStr="",this.dashArray=createTypedArray("float32",e.length?e.length-1:0),this.dashoffset=createTypedArray("float32",1),this.initDynamicPropertyContainer(r);var a,n=e.length||0;for(s=0;s<n;s+=1)a=PropertyFactory.getProp(t,e[s].v,0,0,this),this.k=a.k||this.k,this.dataProps[s]={n:e[s].n,p:a};this.k||this.getValue(!0),this._isAnimated=this.k}function SVGStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i,this._isAnimated=!!this._isAnimated}function SVGFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i}function SVGNoStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=i}function GradientProperty(t,e,i){this.data=e,this.c=createTypedArray("uint8c",4*e.p);var r=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=createTypedArray("float32",r),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=r,this.initDynamicPropertyContainer(i),this.prop=PropertyFactory.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function SVGGradientFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,i)}function SVGGradientStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.initGradientData(t,e,i),this._isAnimated=!!this._isAnimated}function ShapeGroupData(){this.it=[],this.prevViewData=[],this.gr=createNS("g")}function SVGTransformData(t,e,i){this.transform={mProps:t,op:e,container:i},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}SVGShapeData.prototype.setAsAnimated=function(){this._isAnimated=!0},SVGStyleData.prototype.reset=function(){this.d="",this._mdf=!1},DashProperty.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,i=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<i;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},extendPrototype([DynamicPropertyContainer],DashProperty),extendPrototype([DynamicPropertyContainer],SVGStrokeStyleData),extendPrototype([DynamicPropertyContainer],SVGFillStyleData),extendPrototype([DynamicPropertyContainer],SVGNoStyleData),GradientProperty.prototype.comparePoints=function(t,e){for(var i=0,r=this.o.length/2;i<r;){if(.01<Math.abs(t[4*i]-t[4*e+2*i]))return!1;i+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},GradientProperty.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){var e,i,r,s=4*this.data.p;for(e=0;e<s;e+=1)i=e%4==0?100:255,r=Math.round(this.prop.v[e]*i),this.c[e]!==r&&(this.c[e]=r,this._cmdf=!t);if(this.o.length)for(s=this.prop.v.length,e=4*this.data.p;e<s;e+=1)i=e%2==0?100:1,r=e%2==0?Math.round(100*this.prop.v[e]):this.prop.v[e],this.o[e-4*this.data.p]!==r&&(this.o[e-4*this.data.p]=r,this._omdf=!t);this._mdf=!t}},extendPrototype([DynamicPropertyContainer],GradientProperty),SVGGradientFillStyleData.prototype.initGradientData=function(t,e,i){this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.s=PropertyFactory.getProp(t,e.s,1,null,this),this.e=PropertyFactory.getProp(t,e.e,1,null,this),this.h=PropertyFactory.getProp(t,e.h||{k:0},0,.01,this),this.a=PropertyFactory.getProp(t,e.a||{k:0},0,degToRads,this),this.g=new GradientProperty(t,e.g,this),this.style=i,this.stops=[],this.setGradientData(i.pElem,e),this.setGradientOpacity(e,i),this._isAnimated=!!this._isAnimated},SVGGradientFillStyleData.prototype.setGradientData=function(t,e){var i=createElementID(),r=createNS(1===e.t?"linearGradient":"radialGradient");r.setAttribute("id",i),r.setAttribute("spreadMethod","pad"),r.setAttribute("gradientUnits","userSpaceOnUse");var s,a,n,o=[];for(n=4*e.g.p,a=0;a<n;a+=4)s=createNS("stop"),r.appendChild(s),o.push(s);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+getLocationHref()+"#"+i+")"),this.gf=r,this.cst=o},SVGGradientFillStyleData.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){var i,r,s,a=createNS("mask"),n=createNS("path");a.appendChild(n);var o=createElementID(),h=createElementID();a.setAttribute("id",h);var l=createNS(1===t.t?"linearGradient":"radialGradient");l.setAttribute("id",o),l.setAttribute("spreadMethod","pad"),l.setAttribute("gradientUnits","userSpaceOnUse"),s=t.g.k.k[0].s?t.g.k.k[0].s.length:t.g.k.k.length;var p=this.stops;for(r=4*t.g.p;r<s;r+=2)(i=createNS("stop")).setAttribute("stop-color","rgb(255,255,255)"),l.appendChild(i),p.push(i);n.setAttribute("gf"===t.ty?"fill":"stroke","url("+getLocationHref()+"#"+o+")"),"gs"===t.ty&&(n.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),n.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),1===t.lj&&n.setAttribute("stroke-miterlimit",t.ml)),this.of=l,this.ms=a,this.ost=p,this.maskId=h,e.msElem=n}},extendPrototype([DynamicPropertyContainer],SVGGradientFillStyleData),extendPrototype([SVGGradientFillStyleData,DynamicPropertyContainer],SVGGradientStrokeStyleData);var buildShapeString=function(t,e,i,r){if(0===e)return"";var s,a=t.o,n=t.i,o=t.v,h=" M"+r.applyToPointStringified(o[0][0],o[0][1]);for(s=1;s<e;s+=1)h+=" C"+r.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+r.applyToPointStringified(n[s][0],n[s][1])+" "+r.applyToPointStringified(o[s][0],o[s][1]);return i&&e&&(h+=" C"+r.applyToPointStringified(a[s-1][0],a[s-1][1])+" "+r.applyToPointStringified(n[0][0],n[0][1])+" "+r.applyToPointStringified(o[0][0],o[0][1]),h+="z"),h},SVGElementsRenderer=function(){var u=new Matrix,y=new Matrix;function e(t,e,i){(i||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(i||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function i(){}function r(t,e,i){var r,s,a,n,o,h,l,p,f,m,c=e.styles.length,d=e.lvl;for(h=0;h<c;h+=1){if(n=e.sh._mdf||i,e.styles[h].lvl<d){for(p=y.reset(),f=d-e.styles[h].lvl,m=e.transformers.length-1;!n&&0<f;)n=e.transformers[m].mProps._mdf||n,f-=1,m-=1;if(n)for(f=d-e.styles[h].lvl,m=e.transformers.length-1;0<f;)p.multiply(e.transformers[m].mProps.v),f-=1,m-=1}else p=u;if(s=(l=e.sh.paths)._length,n){for(a="",r=0;r<s;r+=1)(o=l.shapes[r])&&o._length&&(a+=buildShapeString(o,o._length,o.c,p));e.caches[h]=a}else a=e.caches[h];e.styles[h].d+=!0===t.hd?"":a,e.styles[h]._mdf=n||e.styles[h]._mdf}}function s(t,e,i){var r=e.style;(e.c._mdf||i)&&r.pElem.setAttribute("fill","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("fill-opacity",e.o.v)}function a(t,e,i){n(t,e,i),o(t,e,i)}function n(t,e,i){var r,s,a,n,o,h=e.gf,l=e.g._hasOpacity,p=e.s.v,f=e.e.v;if(e.o._mdf||i){var m="gf"===t.ty?"fill-opacity":"stroke-opacity";e.style.pElem.setAttribute(m,e.o.v)}if(e.s._mdf||i){var c=1===t.t?"x1":"cx",d="x1"===c?"y1":"cy";h.setAttribute(c,p[0]),h.setAttribute(d,p[1]),l&&!e.g._collapsable&&(e.of.setAttribute(c,p[0]),e.of.setAttribute(d,p[1]))}if(e.g._cmdf||i){r=e.cst;var u=e.g.c;for(a=r.length,s=0;s<a;s+=1)(n=r[s]).setAttribute("offset",u[4*s]+"%"),n.setAttribute("stop-color","rgb("+u[4*s+1]+","+u[4*s+2]+","+u[4*s+3]+")")}if(l&&(e.g._omdf||i)){var y=e.g.o;for(a=(r=e.g._collapsable?e.cst:e.ost).length,s=0;s<a;s+=1)n=r[s],e.g._collapsable||n.setAttribute("offset",y[2*s]+"%"),n.setAttribute("stop-opacity",y[2*s+1])}if(1===t.t)(e.e._mdf||i)&&(h.setAttribute("x2",f[0]),h.setAttribute("y2",f[1]),l&&!e.g._collapsable&&(e.of.setAttribute("x2",f[0]),e.of.setAttribute("y2",f[1])));else if((e.s._mdf||e.e._mdf||i)&&(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)),h.setAttribute("r",o),l&&!e.g._collapsable&&e.of.setAttribute("r",o)),e.e._mdf||e.h._mdf||e.a._mdf||i){o||(o=Math.sqrt(Math.pow(p[0]-f[0],2)+Math.pow(p[1]-f[1],2)));var g=Math.atan2(f[1]-p[1],f[0]-p[0]),v=e.h.v;1<=v?v=.99:v<=-1&&(v=-.99);var b=o*v,x=Math.cos(g+e.a.v)*b+p[0],P=Math.sin(g+e.a.v)*b+p[1];h.setAttribute("fx",x),h.setAttribute("fy",P),l&&!e.g._collapsable&&(e.of.setAttribute("fx",x),e.of.setAttribute("fy",P))}}function o(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||i)&&s.dashStr&&(r.pElem.setAttribute("stroke-dasharray",s.dashStr),r.pElem.setAttribute("stroke-dashoffset",s.dashoffset[0])),e.c&&(e.c._mdf||i)&&r.pElem.setAttribute("stroke","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||i)&&(r.pElem.setAttribute("stroke-width",e.w.v),r.msElem&&r.msElem.setAttribute("stroke-width",e.w.v))}return{createRenderFunction:function(t){switch(t.ty){case"fl":return s;case"gf":return n;case"gs":return a;case"st":return o;case"sh":case"el":case"rc":case"sr":return r;case"tr":return e;case"no":return i;default:return null}}}}();function SVGShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,i),this.prevViewData=[]}function LetterProps(t,e,i,r,s,a){this.o=t,this.sw=e,this.sc=i,this.fc=r,this.m=s,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!i,fc:!!r,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){var t,e,i,r,s=this.shapes.length,a=this.stylesList.length,n=[],o=!1;for(i=0;i<a;i+=1){for(r=this.stylesList[i],o=!1,t=n.length=0;t<s;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(r)&&(n.push(e),o=e._isAnimated||o);1<n.length&&o&&this.setShapesAsAnimated(n)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].setAsAnimated()},SVGShapeElement.prototype.createStyleElement=function(t,e){var i,r=new SVGStyleData(t,e),s=r.pElem;if("st"===t.ty)i=new SVGStrokeStyleData(this,t,r);else if("fl"===t.ty)i=new SVGFillStyleData(this,t,r);else if("gf"===t.ty||"gs"===t.ty){i=new("gf"===t.ty?SVGGradientFillStyleData:SVGGradientStrokeStyleData)(this,t,r),this.globalData.defs.appendChild(i.gf),i.maskId&&(this.globalData.defs.appendChild(i.ms),this.globalData.defs.appendChild(i.of),s.setAttribute("mask","url("+getLocationHref()+"#"+i.maskId+")"))}else"no"===t.ty&&(i=new SVGNoStyleData(this,t,r));return"st"!==t.ty&&"gs"!==t.ty||(s.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),s.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),s.setAttribute("fill-opacity","0"),1===t.lj&&s.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&s.setAttribute("fill-rule","evenodd"),t.ln&&s.setAttribute("id",t.ln),t.cl&&s.setAttribute("class",t.cl),t.bm&&(s.style["mix-blend-mode"]=getBlendMode(t.bm)),this.stylesList.push(r),this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createGroupElement=function(t){var e=new ShapeGroupData;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=getBlendMode(t.bm)),e},SVGShapeElement.prototype.createTransformElement=function(t,e){var i=TransformPropertyFactory.getTransformProperty(this,t,this),r=new SVGTransformData(i,i.o,e);return this.addToAnimatedContents(t,r),r},SVGShapeElement.prototype.createShapeElement=function(t,e,i){var r=4;"rc"===t.ty?r=5:"el"===t.ty?r=6:"sr"===t.ty&&(r=7);var s=new SVGShapeData(e,i,ShapePropertyFactory.getShapeProp(this,t,r,this));return this.shapes.push(s),this.addShapeToModifiers(s),this.addToAnimatedContents(t,s),s},SVGShapeElement.prototype.addToAnimatedContents=function(t,e){for(var i=0,r=this.animatedContents.length;i<r;){if(this.animatedContents[i].element===e)return;i+=1}this.animatedContents.push({fn:SVGElementsRenderer.createRenderFunction(t),element:e,data:t})},SVGShapeElement.prototype.setElementStyles=function(t){var e,i=t.styles,r=this.stylesList.length;for(e=0;e<r;e+=1)this.stylesList[e].closed||i.push(this.stylesList[e])},SVGShapeElement.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers()},SVGShapeElement.prototype.searchShapes=function(t,e,i,r,s,a,n){var o,h,l,p,f,m,c=[].concat(a),d=t.length-1,u=[],y=[];for(o=d;0<=o;o-=1){if((m=this.searchProcessedElement(t[o]))?e[o]=i[m-1]:t[o]._render=n,"fl"===t[o].ty||"st"===t[o].ty||"gf"===t[o].ty||"gs"===t[o].ty||"no"===t[o].ty)m?e[o].style.closed=!1:e[o]=this.createStyleElement(t[o],s),t[o]._render&&e[o].style.pElem.parentNode!==r&&r.appendChild(e[o].style.pElem),u.push(e[o].style);else if("gr"===t[o].ty){if(m)for(l=e[o].it.length,h=0;h<l;h+=1)e[o].prevViewData[h]=e[o].it[h];else e[o]=this.createGroupElement(t[o]);this.searchShapes(t[o].it,e[o].it,e[o].prevViewData,e[o].gr,s+1,c,n),t[o]._render&&e[o].gr.parentNode!==r&&r.appendChild(e[o].gr)}else"tr"===t[o].ty?(m||(e[o]=this.createTransformElement(t[o],r)),p=e[o].transform,c.push(p)):"sh"===t[o].ty||"rc"===t[o].ty||"el"===t[o].ty||"sr"===t[o].ty?(m||(e[o]=this.createShapeElement(t[o],c,s)),this.setElementStyles(e[o])):"tm"===t[o].ty||"rd"===t[o].ty||"ms"===t[o].ty||"pb"===t[o].ty||"zz"===t[o].ty||"op"===t[o].ty?(m?(f=e[o]).closed=!1:((f=ShapeModifiers.getModifier(t[o].ty)).init(this,t[o]),e[o]=f,this.shapeModifiers.push(f)),y.push(f)):"rp"===t[o].ty&&(m?(f=e[o]).closed=!0:(f=ShapeModifiers.getModifier(t[o].ty),(e[o]=f).init(this,t,o,e),this.shapeModifiers.push(f),n=!1),y.push(f));this.addProcessedElement(t[o],o+1)}for(d=u.length,o=0;o<d;o+=1)u[o].closed=!0;for(d=y.length,o=0;o<d;o+=1)y[o].closed=!0},SVGShapeElement.prototype.renderInnerContent=function(){var t;this.renderModifiers();var e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].reset();for(this.renderShape(),t=0;t<e;t+=1)(this.stylesList[t]._mdf||this._isFirstFrame)&&(this.stylesList[t].msElem&&(this.stylesList[t].msElem.setAttribute("d",this.stylesList[t].d),this.stylesList[t].d="M0 0"+this.stylesList[t].d),this.stylesList[t].pElem.setAttribute("d",this.stylesList[t].d||"M0 0"))},SVGShapeElement.prototype.renderShape=function(){var t,e,i=this.animatedContents.length;for(t=0;t<i;t+=1)e=this.animatedContents[t],(this._isFirstFrame||e.element._isAnimated)&&!0!==e.data&&e.fn(e.data,e.element,this._isFirstFrame)},SVGShapeElement.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},LetterProps.prototype.update=function(t,e,i,r,s,a){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1;var n=this._mdf.p=!1;return this.o!==t&&(this.o=t,n=this._mdf.o=!0),this.sw!==e&&(this.sw=e,n=this._mdf.sw=!0),this.sc!==i&&(this.sc=i,n=this._mdf.sc=!0),this.fc!==r&&(this.fc=r,n=this._mdf.fc=!0),this.m!==s&&(this.m=s,n=this._mdf.m=!0),!a.length||this.p[0]===a[0]&&this.p[1]===a[1]&&this.p[4]===a[4]&&this.p[5]===a[5]&&this.p[12]===a[12]&&this.p[13]===a[13]||(this.p=a,n=this._mdf.p=!0),n},TextProperty.prototype.defaultBoxWidth=[0,0],TextProperty.prototype.copyData=function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},TextProperty.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},TextProperty.prototype.searchProperty=function(){return this.searchKeyframes()},TextProperty.prototype.searchKeyframes=function(){return this.kf=1<this.data.d.k.length,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,i=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{var r;this.lock=!0,this._mdf=!1;var s=this.effectsSequence.length,a=t||this.data.d.k[this.keysIndex].s;for(r=0;r<s;r+=1)a=i!==this.keysIndex?this.effectsSequence[r](a,a.t):this.effectsSequence[r](this.currentData,a.t);e!==a&&this.setCurrentData(a),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},TextProperty.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,i=0,r=t.length;i<=r-1&&!(i===r-1||t[i+1].t>e);)i+=1;return this.keysIndex!==i&&(this.keysIndex=i),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e,i,r=[],s=0,a=t.length,n=!1,o=!1,h="";s<a;)n=o,o=!1,e=t.charCodeAt(s),h=t.charAt(s),FontManager.isCombinedCharacter(e)?n=!0:55296<=e&&e<=56319?FontManager.isRegionalFlag(t,s)?h=t.substr(s,14):56320<=(i=t.charCodeAt(s+1))&&i<=57343&&(FontManager.isModifier(e,i)?(h=t.substr(s,2),n=!0):h=FontManager.isFlagEmoji(t.substr(s,4))?t.substr(s,4):t.substr(s,2)):56319<e?(i=t.charCodeAt(s+1),FontManager.isVariationSelector(e)&&(n=!0)):FontManager.isZeroWidthJoiner(e)&&(o=n=!0),n?(r[r.length-1]+=h,n=!1):r.push(h),s+=h.length;return r},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,i,r,s,a,n,o,h=this.elem.globalData.fontManager,l=this.data,p=[],f=0,m=l.m.g,c=0,d=0,u=0,y=[],g=0,v=0,b=h.getFontByName(t.f),x=0,P=getFontProperties(b);t.fWeight=P.weight,t.fStyle=P.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),i=t.finalText.length,t.finalLineHeight=t.lh;var E,S=t.tr/1e3*t.finalSize;if(t.sz)for(var C,_,A=!0,T=t.sz[0],M=t.sz[1];A;){g=C=0,i=(_=this.buildFinalText(t.t)).length,S=t.tr/1e3*t.finalSize;var k=-1;for(e=0;e<i;e+=1)E=_[e].charCodeAt(0),r=!1," "===_[e]?k=e:13!==E&&3!==E||(r=!(g=0),C+=t.finalLineHeight||1.2*t.finalSize),T<g+(x=h.chars?(o=h.getCharData(_[e],b.fStyle,b.fFamily),r?0:o.w*t.finalSize/100):h.measureText(_[e],t.f,t.finalSize))&&" "!==_[e]?(-1===k?i+=1:e=k,C+=t.finalLineHeight||1.2*t.finalSize,_.splice(e,k===e?1:0,"\r"),k=-1,g=0):(g+=x,g+=S);C+=b.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&M<C?(t.finalSize-=1,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=_,i=t.finalText.length,A=!1)}g=-S;var D,F=x=0;for(e=0;e<i;e+=1)if(r=!1,13===(E=(D=t.finalText[e]).charCodeAt(0))||3===E?(F=0,y.push(g),v=v<g?g:v,g=-2*S,r=!(s=""),u+=1):s=D,x=h.chars?(o=h.getCharData(D,b.fStyle,h.getFontByName(t.f).fFamily),r?0:o.w*t.finalSize/100):h.measureText(s,t.f,t.finalSize)," "===D?F+=x+S:(g+=x+S+F,F=0),p.push({l:x,an:x,add:c,n:r,anIndexes:[],val:s,line:u,animatorJustifyOffset:0}),2==m){if(c+=x,""===s||" "===s||e===i-1){for(""!==s&&" "!==s||(c-=x);d<=e;)p[d].an=c,p[d].ind=f,p[d].extra=x,d+=1;f+=1,c=0}}else if(3==m){if(c+=x,""===s||e===i-1){for(""===s&&(c-=x);d<=e;)p[d].an=c,p[d].ind=f,p[d].extra=x,d+=1;c=0,f+=1}}else p[f].ind=f,p[f].extra=0,f+=1;if(t.l=p,v=v<g?g:v,y.push(g),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=v,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=y;var w,I,V,B,R=l.a;n=R.length;var L=[];for(a=0;a<n;a+=1){for((w=R[a]).a.sc&&(t.strokeColorAnim=!0),w.a.sw&&(t.strokeWidthAnim=!0),(w.a.fc||w.a.fh||w.a.fs||w.a.fb)&&(t.fillColorAnim=!0),B=0,V=w.s.b,e=0;e<i;e+=1)(I=p[e]).anIndexes[a]=B,(1==V&&""!==I.val||2==V&&""!==I.val&&" "!==I.val||3==V&&(I.n||" "==I.val||e==i-1)||4==V&&(I.n||e==i-1))&&(1===w.s.rn&&L.push(B),B+=1);l.a[a].s.totalChars=B;var z,G=-1;if(1===w.s.rn)for(e=0;e<i;e+=1)G!=(I=p[e]).anIndexes[a]&&(G=I.anIndexes[a],z=L.splice(Math.floor(Math.random()*L.length),1)[0]),I.anIndexes[a]=z}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=b.ascent*t.finalSize/100},TextProperty.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var i=this.copyData({},this.data.d.k[e].s);i=this.copyData(i,t),this.data.d.k[e].s=i,this.recalculate(e),this.setCurrentData(i),this.elem.addDynamicProperty(this)},TextProperty.prototype.recalculate=function(t){var e=this.data.d.k[t].s;e.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(e)},TextProperty.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},TextProperty.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var TextSelectorProp=function(){var u=Math.max,y=Math.min,g=Math.floor;function r(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=PropertyFactory.getProp(t,e.s||{k:0},0,0,this),this.e="e"in e?PropertyFactory.getProp(t,e.e,0,0,this):{v:100},this.o=PropertyFactory.getProp(t,e.o||{k:0},0,0,this),this.xe=PropertyFactory.getProp(t,e.xe||{k:0},0,0,this),this.ne=PropertyFactory.getProp(t,e.ne||{k:0},0,0,this),this.sm=PropertyFactory.getProp(t,e.sm||{k:100},0,0,this),this.a=PropertyFactory.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return r.prototype={getMult:function(t){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var e=0,i=0,r=1,s=1;0<this.ne.v?e=this.ne.v/100:i=-this.ne.v/100,0<this.xe.v?r=1-this.xe.v/100:s=1+this.xe.v/100;var a=BezierFactory.getBezierEasing(e,i,r,s).get,n=0,o=this.finalS,h=this.finalE,l=this.data.sh;if(2===l)n=a(n=h===o?h<=t?1:0:u(0,y(.5/(h-o)+(t-o)/(h-o),1)));else if(3===l)n=a(n=h===o?h<=t?0:1:1-u(0,y(.5/(h-o)+(t-o)/(h-o),1)));else if(4===l)h===o?n=0:(n=u(0,y(.5/(h-o)+(t-o)/(h-o),1)))<.5?n*=2:n=1-2*(n-.5),n=a(n);else if(5===l){if(h===o)n=0;else{var p=h-o,f=-p/2+(t=y(u(0,t+.5-o),h-o)),m=p/2;n=Math.sqrt(1-f*f/(m*m))}n=a(n)}else n=6===l?a(n=h===o?0:(t=y(u(0,t+.5-o),h-o),(1+Math.cos(Math.PI+2*Math.PI*t/(h-o)))/2)):(t>=g(o)&&(n=u(0,y(t-o<0?y(h,1)-(o-t):h-t,1))),a(n));if(100!==this.sm.v){var c=.01*this.sm.v;0===c&&(c=1e-8);var d=.5-.5*c;n<d?n=0:1<(n=(n-d)/c)&&(n=1)}return n*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var e=2===this.data.r?1:100/this.data.totalChars,i=this.o.v/e,r=this.s.v/e+i,s=this.e.v/e+i;if(s<r){var a=r;r=s,s=a}this.finalS=r,this.finalE=s}},extendPrototype([DynamicPropertyContainer],r),{getTextSelectorProp:function(t,e,i){return new r(t,e,i)}}}();function TextAnimatorDataProperty(t,e,i){var r={propType:!1},s=PropertyFactory.getProp,a=e.a;this.a={r:a.r?s(t,a.r,0,degToRads,i):r,rx:a.rx?s(t,a.rx,0,degToRads,i):r,ry:a.ry?s(t,a.ry,0,degToRads,i):r,sk:a.sk?s(t,a.sk,0,degToRads,i):r,sa:a.sa?s(t,a.sa,0,degToRads,i):r,s:a.s?s(t,a.s,1,.01,i):r,a:a.a?s(t,a.a,1,0,i):r,o:a.o?s(t,a.o,0,.01,i):r,p:a.p?s(t,a.p,1,0,i):r,sw:a.sw?s(t,a.sw,0,0,i):r,sc:a.sc?s(t,a.sc,1,0,i):r,fc:a.fc?s(t,a.fc,1,0,i):r,fh:a.fh?s(t,a.fh,0,0,i):r,fs:a.fs?s(t,a.fs,0,.01,i):r,fb:a.fb?s(t,a.fb,0,.01,i):r,t:a.t?s(t,a.t,0,0,i):r},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,i),this.s.t=e.s.t}function TextAnimatorProperty(t,e,i){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=i,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(i)}function ITextElement(){}TextAnimatorProperty.prototype.searchProperties=function(){var t,e,i=this._textData.a.length,r=PropertyFactory.getProp;for(t=0;t<i;t+=1)e=this._textData.a[t],this._animatorsData[t]=new TextAnimatorDataProperty(this._elem,e,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:r(this._elem,this._textData.p.a,0,0,this),f:r(this._elem,this._textData.p.f,0,0,this),l:r(this._elem,this._textData.p.l,0,0,this),r:r(this._elem,this._textData.p.r,0,0,this),p:r(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=r(this._elem,this._textData.m.a,1,0,this)},TextAnimatorProperty.prototype.getMeasures=function(t,e){if(this.lettersChangedFlag=e,this._mdf||this._isFirstFrame||e||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var i,r,s,a,n,o,h,l,p,f,m,c,d,u,y,g,v,b,x,P=this._moreOptions.alignment.v,E=this._animatorsData,S=this._textData,C=this.mHelper,_=this._renderType,A=this.renderedLetters.length,T=t.l;if(this._hasMaskedPath){if(x=this._pathData.m,!this._pathData.n||this._pathData._mdf){var M,k=x.v;for(this._pathData.r.v&&(k=k.reverse()),n={tLength:0,segments:[]},a=k._length-1,s=g=0;s<a;s+=1)M=bez.buildBezierData(k.v[s],k.v[s+1],[k.o[s][0]-k.v[s][0],k.o[s][1]-k.v[s][1]],[k.i[s+1][0]-k.v[s+1][0],k.i[s+1][1]-k.v[s+1][1]]),n.tLength+=M.segmentLength,n.segments.push(M),g+=M.segmentLength;s=a,x.v.c&&(M=bez.buildBezierData(k.v[s],k.v[0],[k.o[s][0]-k.v[s][0],k.o[s][1]-k.v[s][1]],[k.i[0][0]-k.v[0][0],k.i[0][1]-k.v[0][1]]),n.tLength+=M.segmentLength,n.segments.push(M),g+=M.segmentLength),this._pathData.pi=n}if(n=this._pathData.pi,o=this._pathData.f.v,f=1,p=!(l=m=0),u=n.segments,o<0&&x.v.c)for(n.tLength<Math.abs(o)&&(o=-Math.abs(o)%n.tLength),f=(d=u[m=u.length-1].points).length-1;o<0;)o+=d[f].partialLength,(f-=1)<0&&(f=(d=u[m-=1].points).length-1);c=(d=u[m].points)[f-1],y=(h=d[f]).partialLength}a=T.length,r=i=0;var D,F,w,I,V,B=1.2*t.finalSize*.714,R=!0;w=E.length;var L,z,G,O,N,H,j,q,W,$,Y,J,X=-1,Z=o,K=m,U=f,Q=-1,tt="",et=this.defaultPropsArray;if(2===t.j||1===t.j){var it=0,rt=0,st=2===t.j?-.5:-1,at=0,nt=!0;for(s=0;s<a;s+=1)if(T[s].n){for(it&&(it+=rt);at<s;)T[at].animatorJustifyOffset=it,at+=1;nt=!(it=0)}else{for(F=0;F<w;F+=1)(D=E[F].a).t.propType&&(nt&&2===t.j&&(rt+=D.t.v*st),(V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?it+=D.t.v*V[0]*st:it+=D.t.v*V*st);nt=!1}for(it&&(it+=rt);at<s;)T[at].animatorJustifyOffset=it,at+=1}for(s=0;s<a;s+=1){if(C.reset(),O=1,T[s].n)i=0,r+=t.yOffset,r+=R?1:0,o=Z,R=!1,this._hasMaskedPath&&(f=U,c=(d=u[m=K].points)[f-1],y=(h=d[f]).partialLength,l=0),J=W=Y=tt="",et=this.defaultPropsArray;else{if(this._hasMaskedPath){if(Q!==T[s].line){switch(t.j){case 1:o+=g-t.lineWidths[T[s].line];break;case 2:o+=(g-t.lineWidths[T[s].line])/2}Q=T[s].line}X!==T[s].ind&&(T[X]&&(o+=T[X].extra),o+=T[s].an/2,X=T[s].ind),o+=P[0]*T[s].an*.005;var ot=0;for(F=0;F<w;F+=1)(D=E[F].a).p.propType&&((V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?ot+=D.p.v[0]*V[0]:ot+=D.p.v[0]*V),D.a.propType&&((V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?ot+=D.a.v[0]*V[0]:ot+=D.a.v[0]*V);for(p=!0,this._pathData.a.v&&(o=.5*T[0].an+(g-this._pathData.f.v-.5*T[0].an-.5*T[T.length-1].an)*X/(a-1),o+=this._pathData.f.v);p;)o+ot<=l+y||!d?(v=(o+ot-l)/h.partialLength,z=c.point[0]+(h.point[0]-c.point[0])*v,G=c.point[1]+(h.point[1]-c.point[1])*v,C.translate(-P[0]*T[s].an*.005,-P[1]*B*.01),p=!1):d&&(l+=h.partialLength,(f+=1)>=d.length&&(f=0,d=u[m+=1]?u[m].points:x.v.c?u[m=f=0].points:(l-=h.partialLength,null)),d&&(c=h,y=(h=d[f]).partialLength));L=T[s].an/2-T[s].add,C.translate(-L,0,0)}else L=T[s].an/2-T[s].add,C.translate(-L,0,0),C.translate(-P[0]*T[s].an*.005,-P[1]*B*.01,0);for(F=0;F<w;F+=1)(D=E[F].a).t.propType&&(V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars),0===i&&0===t.j||(this._hasMaskedPath?V.length?o+=D.t.v*V[0]:o+=D.t.v*V:V.length?i+=D.t.v*V[0]:i+=D.t.v*V));for(t.strokeWidthAnim&&(H=t.sw||0),t.strokeColorAnim&&(N=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(j=[t.fc[0],t.fc[1],t.fc[2]]),F=0;F<w;F+=1)(D=E[F].a).a.propType&&((V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?C.translate(-D.a.v[0]*V[0],-D.a.v[1]*V[1],D.a.v[2]*V[2]):C.translate(-D.a.v[0]*V,-D.a.v[1]*V,D.a.v[2]*V));for(F=0;F<w;F+=1)(D=E[F].a).s.propType&&((V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars)).length?C.scale(1+(D.s.v[0]-1)*V[0],1+(D.s.v[1]-1)*V[1],1):C.scale(1+(D.s.v[0]-1)*V,1+(D.s.v[1]-1)*V,1));for(F=0;F<w;F+=1){if(D=E[F].a,V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars),D.sk.propType&&(V.length?C.skewFromAxis(-D.sk.v*V[0],D.sa.v*V[1]):C.skewFromAxis(-D.sk.v*V,D.sa.v*V)),D.r.propType&&(V.length?C.rotateZ(-D.r.v*V[2]):C.rotateZ(-D.r.v*V)),D.ry.propType&&(V.length?C.rotateY(D.ry.v*V[1]):C.rotateY(D.ry.v*V)),D.rx.propType&&(V.length?C.rotateX(D.rx.v*V[0]):C.rotateX(D.rx.v*V)),D.o.propType&&(V.length?O+=(D.o.v*V[0]-O)*V[0]:O+=(D.o.v*V-O)*V),t.strokeWidthAnim&&D.sw.propType&&(V.length?H+=D.sw.v*V[0]:H+=D.sw.v*V),t.strokeColorAnim&&D.sc.propType)for(q=0;q<3;q+=1)V.length?N[q]+=(D.sc.v[q]-N[q])*V[0]:N[q]+=(D.sc.v[q]-N[q])*V;if(t.fillColorAnim&&t.fc){if(D.fc.propType)for(q=0;q<3;q+=1)V.length?j[q]+=(D.fc.v[q]-j[q])*V[0]:j[q]+=(D.fc.v[q]-j[q])*V;D.fh.propType&&(j=V.length?addHueToRGB(j,D.fh.v*V[0]):addHueToRGB(j,D.fh.v*V)),D.fs.propType&&(j=V.length?addSaturationToRGB(j,D.fs.v*V[0]):addSaturationToRGB(j,D.fs.v*V)),D.fb.propType&&(j=V.length?addBrightnessToRGB(j,D.fb.v*V[0]):addBrightnessToRGB(j,D.fb.v*V))}}for(F=0;F<w;F+=1)(D=E[F].a).p.propType&&(V=E[F].s.getMult(T[s].anIndexes[F],S.a[F].s.totalChars),this._hasMaskedPath?V.length?C.translate(0,D.p.v[1]*V[0],-D.p.v[2]*V[1]):C.translate(0,D.p.v[1]*V,-D.p.v[2]*V):V.length?C.translate(D.p.v[0]*V[0],D.p.v[1]*V[1],-D.p.v[2]*V[2]):C.translate(D.p.v[0]*V,D.p.v[1]*V,-D.p.v[2]*V));if(t.strokeWidthAnim&&(W=H<0?0:H),t.strokeColorAnim&&($="rgb("+Math.round(255*N[0])+","+Math.round(255*N[1])+","+Math.round(255*N[2])+")"),t.fillColorAnim&&t.fc&&(Y="rgb("+Math.round(255*j[0])+","+Math.round(255*j[1])+","+Math.round(255*j[2])+")"),this._hasMaskedPath){if(C.translate(0,-t.ls),C.translate(0,P[1]*B*.01+r,0),this._pathData.p.v){b=(h.point[1]-c.point[1])/(h.point[0]-c.point[0]);var ht=180*Math.atan(b)/Math.PI;h.point[0]<c.point[0]&&(ht+=180),C.rotate(-ht*Math.PI/180)}C.translate(z,G,0),o-=P[0]*T[s].an*.005,T[s+1]&&X!==T[s+1].ind&&(o+=T[s].an/2,o+=.001*t.tr*t.finalSize)}else{switch(C.translate(i,r,0),t.ps&&C.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:C.translate(T[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[T[s].line]),0,0);break;case 2:C.translate(T[s].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[T[s].line])/2,0,0)}C.translate(0,-t.ls),C.translate(L,0,0),C.translate(P[0]*T[s].an*.005,P[1]*B*.01,0),i+=T[s].l+.001*t.tr*t.finalSize}"html"===_?tt=C.toCSS():"svg"===_?tt=C.to2dCSS():et=[C.props[0],C.props[1],C.props[2],C.props[3],C.props[4],C.props[5],C.props[6],C.props[7],C.props[8],C.props[9],C.props[10],C.props[11],C.props[12],C.props[13],C.props[14],C.props[15]],J=O}this.lettersChangedFlag=A<=s?(I=new LetterProps(J,W,$,Y,tt,et),this.renderedLetters.push(I),A+=1,!0):(I=this.renderedLetters[s]).update(J,W,$,Y,tt,et)||this.lettersChangedFlag}}},TextAnimatorProperty.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},TextAnimatorProperty.prototype.mHelper=new Matrix,TextAnimatorProperty.prototype.defaultPropsArray=[],extendPrototype([DynamicPropertyContainer],TextAnimatorProperty),ITextElement.prototype.initElement=function(t,e,i){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,i),this.textProperty=new TextProperty(this,t.t,this.dynamicProperties),this.textAnimator=new TextAnimatorProperty(t.t,this.renderType,this),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},ITextElement.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},ITextElement.prototype.createPathShape=function(t,e){var i,r,s=e.length,a="";for(i=0;i<s;i+=1)"sh"===e[i].ty&&(r=e[i].ks.k,a+=buildShapeString(r,r.i.length,!0,t));return a},ITextElement.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},ITextElement.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},ITextElement.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},ITextElement.prototype.applyTextPropertiesToMatrix=function(t,e,i,r,s){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i])/2,0,0)}e.translate(r,s,0)},ITextElement.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},ITextElement.prototype.emptyProp=new LetterProps,ITextElement.prototype.destroy=function(){},ITextElement.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var emptyShapeData={shapes:[]};function SVGTextLottieElement(t,e,i){this.textSpans=[],this.renderType="svg",this.initElement(t,e,i)}function ISolidElement(t,e,i){this.initElement(t,e,i)}function NullElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initFrame(),this.initTransform(t,e,i),this.initHierarchy()}function SVGRendererBase(){}function ICompElement(){}function SVGCompElement(t,e,i){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function SVGRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=createNS("svg");var i="";if(e&&e.title){var r=createNS("title"),s=createElementID();r.setAttribute("id",s),r.textContent=e.title,this.svgElement.appendChild(r),i+=s}if(e&&e.description){var a=createNS("desc"),n=createElementID();a.setAttribute("id",n),a.textContent=e.description,this.svgElement.appendChild(a),i+=" "+n}i&&this.svgElement.setAttribute("aria-labelledby",i);var o=createNS("defs");this.svgElement.appendChild(o);var h=createNS("g");this.svgElement.appendChild(h),this.layerElement=h,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:o,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}function ShapeTransformManager(){this.sequences={},this.sequenceList=[],this.transform_key_count=0}extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],SVGTextLottieElement),SVGTextLottieElement.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=createNS("text"))},SVGTextLottieElement.prototype.buildTextContents=function(t){for(var e=0,i=t.length,r=[],s="";e<i;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(r.push(s),s=""):s+=t[e],e+=1;return r.push(s),r},SVGTextLottieElement.prototype.buildShapeData=function(t,e){if(t.shapes&&t.shapes.length){var i=t.shapes[0];if(i.it){var r=i.it[i.it.length-1];r.s&&(r.s.k[0]=e,r.s.k[1]=e)}}return t},SVGTextLottieElement.prototype.buildNewText=function(){var t,e;this.addDynamicProperty(this);var i=this.textProperty.currentData;this.renderedLetters=createSizedArray(i?i.l.length:0),i.fc?this.layerElement.setAttribute("fill",this.buildColor(i.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),i.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(i.sc)),this.layerElement.setAttribute("stroke-width",i.sw)),this.layerElement.setAttribute("font-size",i.finalSize);var r=this.globalData.fontManager.getFontByName(i.f);if(r.fClass)this.layerElement.setAttribute("class",r.fClass);else{this.layerElement.setAttribute("font-family",r.fFamily);var s=i.fWeight,a=i.fStyle;this.layerElement.setAttribute("font-style",a),this.layerElement.setAttribute("font-weight",s)}this.layerElement.setAttribute("aria-label",i.t);var n,o=i.l||[],h=!!this.globalData.fontManager.chars;e=o.length;var l=this.mHelper,p=this.data.singleShape,f=0,m=0,c=!0,d=.001*i.tr*i.finalSize;if(!p||h||i.sz){var u,y=this.textSpans.length;for(t=0;t<e;t+=1){if(this.textSpans[t]||(this.textSpans[t]={span:null,childSpan:null,glyph:null}),!h||!p||0===t){if(n=t<y?this.textSpans[t].span:createNS(h?"g":"text"),y<=t){if(n.setAttribute("stroke-linecap","butt"),n.setAttribute("stroke-linejoin","round"),n.setAttribute("stroke-miterlimit","4"),this.textSpans[t].span=n,h){var g=createNS("g");n.appendChild(g),this.textSpans[t].childSpan=g}this.textSpans[t].span=n,this.layerElement.appendChild(n)}n.style.display="inherit"}if(l.reset(),p&&(o[t].n&&(f=-d,m+=i.yOffset,m+=c?1:0,c=!1),this.applyTextPropertiesToMatrix(i,l,o[t].line,f,m),f+=o[t].l||0,f+=d),h){var v;if(1===(u=this.globalData.fontManager.getCharData(i.finalText[t],r.fStyle,this.globalData.fontManager.getFontByName(i.f).fFamily)).t)v=new SVGCompElement(u.data,this.globalData,this);else{var b=emptyShapeData;u.data&&u.data.shapes&&(b=this.buildShapeData(u.data,i.finalSize)),v=new SVGShapeElement(b,this.globalData,this)}if(this.textSpans[t].glyph){var x=this.textSpans[t].glyph;this.textSpans[t].childSpan.removeChild(x.layerElement),x.destroy()}(this.textSpans[t].glyph=v)._debug=!0,v.prepareFrame(0),v.renderFrame(),this.textSpans[t].childSpan.appendChild(v.layerElement),1===u.t&&this.textSpans[t].childSpan.setAttribute("transform","scale("+i.finalSize/100+","+i.finalSize/100+")")}else p&&n.setAttribute("transform","translate("+l.props[12]+","+l.props[13]+")"),n.textContent=o[t].val,n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve")}p&&n&&n.setAttribute("d","")}else{var P=this.textContainer,E="start";switch(i.j){case 1:E="end";break;case 2:E="middle";break;default:E="start"}P.setAttribute("text-anchor",E),P.setAttribute("letter-spacing",d);var S=this.buildTextContents(i.finalText);for(e=S.length,m=i.ps?i.ps[1]+i.ascent:0,t=0;t<e;t+=1)(n=this.textSpans[t].span||createNS("tspan")).textContent=S[t],n.setAttribute("x",0),n.setAttribute("y",m),n.style.display="inherit",P.appendChild(n),this.textSpans[t]||(this.textSpans[t]={span:null,glyph:null}),this.textSpans[t].span=n,m+=i.finalLineHeight;this.layerElement.appendChild(P)}for(;t<this.textSpans.length;)this.textSpans[t].span.style.display="none",t+=1;this._sizeChanged=!0},SVGTextLottieElement.prototype.sourceRectAtTime=function(){if(this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged){this._sizeChanged=!1;var t=this.layerElement.getBBox();this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}}return this.bbox},SVGTextLottieElement.prototype.getValue=function(){var t,e,i=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<i;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf&&(this._mdf=!0))},SVGTextLottieElement.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){var t,e;this._sizeChanged=!0;var i,r,s,a=this.textAnimator.renderedLetters,n=this.textProperty.currentData.l;for(e=n.length,t=0;t<e;t+=1)n[t].n||(i=a[t],r=this.textSpans[t].span,(s=this.textSpans[t].glyph)&&s.renderFrame(),i._mdf.m&&r.setAttribute("transform",i.m),i._mdf.o&&r.setAttribute("opacity",i.o),i._mdf.sw&&r.setAttribute("stroke-width",i.sw),i._mdf.sc&&r.setAttribute("stroke",i.sc),i._mdf.fc&&r.setAttribute("fill",i.fc))}},extendPrototype([IImageElement],ISolidElement),ISolidElement.prototype.createContent=function(){var t=createNS("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},NullElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},NullElement.prototype.renderFrame=function(){},NullElement.prototype.getBaseElement=function(){return null},NullElement.prototype.destroy=function(){},NullElement.prototype.sourceRectAtTime=function(){},NullElement.prototype.hide=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement],NullElement),extendPrototype([BaseRenderer],SVGRendererBase),SVGRendererBase.prototype.createNull=function(t){return new NullElement(t,this.globalData,this)},SVGRendererBase.prototype.createShape=function(t){return new SVGShapeElement(t,this.globalData,this)},SVGRendererBase.prototype.createText=function(t){return new SVGTextLottieElement(t,this.globalData,this)},SVGRendererBase.prototype.createImage=function(t){return new IImageElement(t,this.globalData,this)},SVGRendererBase.prototype.createSolid=function(t){return new ISolidElement(t,this.globalData,this)},SVGRendererBase.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs;this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t;var i=createNS("clipPath"),r=createNS("rect");r.setAttribute("width",t.w),r.setAttribute("height",t.h),r.setAttribute("x",0),r.setAttribute("y",0);var s=createElementID();i.setAttribute("id",s),i.appendChild(r),this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),e.appendChild(i),this.layers=t.layers,this.elements=createSizedArray(t.layers.length)},SVGRendererBase.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},SVGRendererBase.prototype.updateContainerSize=function(){},SVGRendererBase.prototype.findIndexByInd=function(t){var e=0,i=this.layers.length;for(e=0;e<i;e+=1)if(this.layers[e].ind===t)return e;return-1},SVGRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){e[t]=!0;var i=this.createItem(this.layers[t]);if(e[t]=i,getExpressionsPlugin()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(i),i.initExpressions()),this.appendElementInPos(i,t),this.layers[t].tt){var r="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1;if(-1===r)return;if(this.elements[r]&&!0!==this.elements[r]){var s=e[r].getMatte(this.layers[t].tt);i.setMatte(s)}else this.buildItem(r),this.addPendingElement(i)}}},SVGRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,i=this.elements.length;e<i;){if(this.elements[e]===t){var r="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,s=this.elements[r].getMatte(this.layers[e].tt);t.setMatte(s);break}e+=1}}},SVGRendererBase.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){var e;null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var i=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=i-1;0<=e;e-=1)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<i;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},SVGRendererBase.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){for(var r,s=0;s<e;)this.elements[s]&&!0!==this.elements[s]&&this.elements[s].getBaseElement()&&(r=this.elements[s].getBaseElement()),s+=1;r?this.layerElement.insertBefore(i,r):this.layerElement.appendChild(i)}},SVGRendererBase.prototype.hide=function(){this.layerElement.style.display="none"},SVGRendererBase.prototype.show=function(){this.layerElement.style.display="block"},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement,RenderableDOMElement],ICompElement),ICompElement.prototype.initElement=function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},ICompElement.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){if(this.tm._placeholder)this.renderedFrame=t/this.data.sr;else{var e=this.tm.v;e===this.data.op&&(e=this.data.op-1),this.renderedFrame=e}var i,r=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),i=r-1;0<=i;i-=1)(this.completeLayers||this.elements[i])&&(this.elements[i].prepareFrame(this.renderedFrame-this.layers[i].st),this.elements[i]._mdf&&(this._mdf=!0))}},ICompElement.prototype.renderInnerContent=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},ICompElement.prototype.setElements=function(t){this.elements=t},ICompElement.prototype.getElements=function(){return this.elements},ICompElement.prototype.destroyElements=function(){var t,e=this.layers.length;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy()},ICompElement.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},extendPrototype([SVGRendererBase,ICompElement,SVGBaseElement],SVGCompElement),SVGCompElement.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},extendPrototype([SVGRendererBase],SVGRenderer),SVGRenderer.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},ShapeTransformManager.prototype={addTransformSequence:function(t){var e,i=t.length,r="_";for(e=0;e<i;e+=1)r+=t[e].transform.key+"_";var s=this.sequences[r];return s||(s={transforms:[].concat(t),finalTransform:new Matrix,_mdf:!1},this.sequences[r]=s,this.sequenceList.push(s)),s},processSequence:function(t,e){for(var i=0,r=t.transforms.length,s=e;i<r&&!e;){if(t.transforms[i].transform.mProps._mdf){s=!0;break}i+=1}if(s)for(t.finalTransform.reset(),i=r-1;0<=i;i-=1)t.finalTransform.multiply(t.transforms[i].transform.mProps.v);t._mdf=s},processSequences:function(t){var e,i=this.sequenceList.length;for(e=0;e<i;e+=1)this.processSequence(this.sequenceList[e],t)},getNewKey:function(){return this.transform_key_count+=1,"_"+this.transform_key_count}};var lumaLoader=function(){var r="__lottie_element_luma_buffer",s=null,a=null,n=null;function e(){var t,e,i;s||(t=createNS("svg"),e=createNS("filter"),i=createNS("feColorMatrix"),e.setAttribute("id",r),i.setAttribute("type","matrix"),i.setAttribute("color-interpolation-filters","sRGB"),i.setAttribute("values","0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0"),e.appendChild(i),t.appendChild(e),t.setAttribute("id",r+"_svg"),featureSupport.svgLumaHidden&&(t.style.display="none"),n=t,document.body.appendChild(n),s=createTag("canvas"),(a=s.getContext("2d")).filter="url(#"+r+")",a.fillStyle="rgba(0,0,0,0)",a.fillRect(0,0,1,1))}return{load:e,get:function(t){return s||e(),s.width=t.width,s.height=t.height,a.filter="url(#"+r+")",s}}};function createCanvas(t,e){if(featureSupport.offscreenCanvas)return new OffscreenCanvas(t,e);var i=createTag("canvas");return i.width=t,i.height=e,i}var assetLoader={loadLumaCanvas:lumaLoader.load,getLumaCanvas:lumaLoader.get,createCanvas:createCanvas},registeredEffects={};function CVEffects(t){var e,i,r=t.data.ef?t.data.ef.length:0;for(this.filters=[],e=0;e<r;e+=1){i=null;var s=t.data.ef[e].ty;if(registeredEffects[s])i=new registeredEffects[s].effect(t.effectsManager.effectElements[e],t);i&&this.filters.push(i)}this.filters.length&&t.addRenderableComponent(this)}function registerEffect(t,e){registeredEffects[t]={effect:e}}function CVMaskElement(t,e){var i;this.data=t,this.element=e,this.masksProperties=this.data.masksProperties||[],this.viewData=createSizedArray(this.masksProperties.length);var r=this.masksProperties.length,s=!1;for(i=0;i<r;i+=1)"n"!==this.masksProperties[i].mode&&(s=!0),this.viewData[i]=ShapePropertyFactory.getShapeProp(this.element,this.masksProperties[i],3);(this.hasMasks=s)&&this.element.addRenderableComponent(this)}function CVBaseElement(){}CVEffects.prototype.renderFrame=function(t){var e,i=this.filters.length;for(e=0;e<i;e+=1)this.filters[e].renderFrame(t)},CVEffects.prototype.getEffects=function(t){var e,i=this.filters.length,r=[];for(e=0;e<i;e+=1)this.filters[e].type===t&&r.push(this.filters[e]);return r},CVMaskElement.prototype.renderFrame=function(){if(this.hasMasks){var t,e,i,r,s=this.element.finalTransform.mat,a=this.element.canvasContext,n=this.masksProperties.length;for(a.beginPath(),t=0;t<n;t+=1)if("n"!==this.masksProperties[t].mode){var o;this.masksProperties[t].inv&&(a.moveTo(0,0),a.lineTo(this.element.globalData.compSize.w,0),a.lineTo(this.element.globalData.compSize.w,this.element.globalData.compSize.h),a.lineTo(0,this.element.globalData.compSize.h),a.lineTo(0,0)),r=this.viewData[t].v,e=s.applyToPointArray(r.v[0][0],r.v[0][1],0),a.moveTo(e[0],e[1]);var h=r._length;for(o=1;o<h;o+=1)i=s.applyToTriplePoints(r.o[o-1],r.i[o],r.v[o]),a.bezierCurveTo(i[0],i[1],i[2],i[3],i[4],i[5]);i=s.applyToTriplePoints(r.o[o-1],r.i[0],r.v[0]),a.bezierCurveTo(i[0],i[1],i[2],i[3],i[4],i[5])}this.element.globalData.renderer.save(!0),a.clip()}},CVMaskElement.prototype.getMaskProperty=MaskElement.prototype.getMaskProperty,CVMaskElement.prototype.destroy=function(){this.element=null};var operationsMap={1:"source-in",2:"source-out",3:"source-in",4:"source-out"};function CVShapeData(t,e,i,r){this.styledShapes=[],this.tr=[0,0,0,0,0,0];var s,a=4;"rc"===e.ty?a=5:"el"===e.ty?a=6:"sr"===e.ty&&(a=7),this.sh=ShapePropertyFactory.getShapeProp(t,e,a,t);var n,o=i.length;for(s=0;s<o;s+=1)i[s].closed||(n={transforms:r.addTransformSequence(i[s].transforms),trNodes:[]},this.styledShapes.push(n),i[s].elements.push(n))}function CVShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.itemsData=[],this.prevViewData=[],this.shapeModifiers=[],this.processedElements=[],this.transformsManager=new ShapeTransformManager,this.initElement(t,e,i)}function CVTextElement(t,e,i){this.textSpans=[],this.yOffset=0,this.fillColorAnim=!1,this.strokeColorAnim=!1,this.strokeWidthAnim=!1,this.stroke=!1,this.fill=!1,this.justifyOffset=0,this.currentRender=null,this.renderType="canvas",this.values={fill:"rgba(0,0,0,0)",stroke:"rgba(0,0,0,0)",sWidth:0,fValue:""},this.initElement(t,e,i)}function CVImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.img=e.imageLoader.getAsset(this.assetData),this.initElement(t,e,i)}function CVSolidElement(t,e,i){this.initElement(t,e,i)}function CanvasRendererBase(){}function CanvasContext(){this.opacity=-1,this.transform=createTypedArray("float32",16),this.fillStyle="",this.strokeStyle="",this.lineWidth="",this.lineCap="",this.lineJoin="",this.miterLimit="",this.id=Math.random()}function CVContextData(){var t;this.stack=[],this.cArrPos=0,this.cTr=new Matrix;for(t=0;t<15;t+=1){var e=new CanvasContext;this.stack[t]=e}this._length=15,this.nativeContext=null,this.transformMat=new Matrix,this.currentOpacity=1,this.currentFillStyle="",this.appliedFillStyle="",this.currentStrokeStyle="",this.appliedStrokeStyle="",this.currentLineWidth="",this.appliedLineWidth="",this.currentLineCap="",this.appliedLineCap="",this.currentLineJoin="",this.appliedLineJoin="",this.appliedMiterLimit="",this.currentMiterLimit=""}function CVCompElement(t,e,i){this.completeLayers=!1,this.layers=t.layers,this.pendingElements=[],this.elements=createSizedArray(this.layers.length),this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function CanvasRenderer(t,e){this.animationItem=t,this.renderConfig={clearCanvas:!e||void 0===e.clearCanvas||e.clearCanvas,context:e&&e.context||null,progressiveLoad:e&&e.progressiveLoad||!1,preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",className:e&&e.className||"",id:e&&e.id||"",runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.renderConfig.dpr=e&&e.dpr||1,this.animationItem.wrapper&&(this.renderConfig.dpr=e&&e.dpr||window.devicePixelRatio||1),this.renderedFrame=-1,this.globalData={frameNum:-1,_mdf:!1,renderConfig:this.renderConfig,currentGlobalAlpha:-1},this.contextData=new CVContextData,this.elements=[],this.pendingElements=[],this.transformMat=new Matrix,this.completeLayers=!1,this.rendererType="canvas",this.renderConfig.clearCanvas&&(this.ctxTransform=this.contextData.transform.bind(this.contextData),this.ctxOpacity=this.contextData.opacity.bind(this.contextData),this.ctxFillStyle=this.contextData.fillStyle.bind(this.contextData),this.ctxStrokeStyle=this.contextData.strokeStyle.bind(this.contextData),this.ctxLineWidth=this.contextData.lineWidth.bind(this.contextData),this.ctxLineCap=this.contextData.lineCap.bind(this.contextData),this.ctxLineJoin=this.contextData.lineJoin.bind(this.contextData),this.ctxMiterLimit=this.contextData.miterLimit.bind(this.contextData),this.ctxFill=this.contextData.fill.bind(this.contextData),this.ctxFillRect=this.contextData.fillRect.bind(this.contextData),this.ctxStroke=this.contextData.stroke.bind(this.contextData),this.save=this.contextData.save.bind(this.contextData))}function HBaseElement(){}function HSolidElement(t,e,i){this.initElement(t,e,i)}function HShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.shapesContainer=createNS("g"),this.initElement(t,e,i),this.prevViewData=[],this.currentBBox={x:999999,y:-999999,h:0,w:0}}function HTextElement(t,e,i){this.textSpans=[],this.textPaths=[],this.currentBBox={x:999999,y:-999999,h:0,w:0},this.renderType="svg",this.isMasked=!1,this.initElement(t,e,i)}function HCameraElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initHierarchy();var r=PropertyFactory.getProp;if(this.pe=r(this,t.pe,0,0,this),t.ks.p.s?(this.px=r(this,t.ks.p.x,1,0,this),this.py=r(this,t.ks.p.y,1,0,this),this.pz=r(this,t.ks.p.z,1,0,this)):this.p=r(this,t.ks.p,1,0,this),t.ks.a&&(this.a=r(this,t.ks.a,1,0,this)),t.ks.or.k.length&&t.ks.or.k[0].to){var s,a=t.ks.or.k.length;for(s=0;s<a;s+=1)t.ks.or.k[s].to=null,t.ks.or.k[s].ti=null}this.or=r(this,t.ks.or,1,degToRads,this),this.or.sh=!0,this.rx=r(this,t.ks.rx,0,degToRads,this),this.ry=r(this,t.ks.ry,0,degToRads,this),this.rz=r(this,t.ks.rz,0,degToRads,this),this.mat=new Matrix,this._prevMat=new Matrix,this._isFirstFrame=!0,this.finalTransform={mProp:this}}function HImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.initElement(t,e,i)}function HybridRendererBase(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"}},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}function HCompElement(t,e,i){this.layers=t.layers,this.supports3d=!t.hasMask,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function HybridRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"},runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}CVBaseElement.prototype={createElements:function(){},initRendererElement:function(){},createContainerElements:function(){if(1<=this.data.tt){this.buffers=[];var t=this.globalData.canvasContext,e=assetLoader.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(e);var i=assetLoader.createCanvas(t.canvas.width,t.canvas.height);this.buffers.push(i),3<=this.data.tt&&!document._isProxy&&assetLoader.loadLumaCanvas()}this.canvasContext=this.globalData.canvasContext,this.transformCanvas=this.globalData.transformCanvas,this.renderableEffectsManager=new CVEffects(this),this.searchEffectTransforms()},createContent:function(){},setBlendMode:function(){var t=this.globalData;if(t.blendMode!==this.data.bm){t.blendMode=this.data.bm;var e=getBlendMode(this.data.bm);t.canvasContext.globalCompositeOperation=e}},createRenderableComponents:function(){this.maskManager=new CVMaskElement(this.data,this),this.transformEffects=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT)},hideElement:function(){this.hidden||this.isInRange&&!this.isTransparent||(this.hidden=!0)},showElement:function(){this.isInRange&&!this.isTransparent&&(this.hidden=!1,this._isFirstFrame=!0,this.maskManager._isFirstFrame=!0)},clearCanvas:function(t){t.clearRect(this.transformCanvas.tx,this.transformCanvas.ty,this.transformCanvas.w*this.transformCanvas.sx,this.transformCanvas.h*this.transformCanvas.sy)},prepareLayer:function(){if(1<=this.data.tt){var t=this.buffers[0].getContext("2d");this.clearCanvas(t),t.drawImage(this.canvasContext.canvas,0,0),this.currentTransform=this.canvasContext.getTransform(),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform)}},exitLayer:function(){if(1<=this.data.tt){var t=this.buffers[1],e=t.getContext("2d");if(this.clearCanvas(e),e.drawImage(this.canvasContext.canvas,0,0),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform),this.comp.getElementById("tp"in this.data?this.data.tp:this.data.ind-1).renderFrame(!0),this.canvasContext.setTransform(1,0,0,1,0,0),3<=this.data.tt&&!document._isProxy){var i=assetLoader.getLumaCanvas(this.canvasContext.canvas);i.getContext("2d").drawImage(this.canvasContext.canvas,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.drawImage(i,0,0)}this.canvasContext.globalCompositeOperation=operationsMap[this.data.tt],this.canvasContext.drawImage(t,0,0),this.canvasContext.globalCompositeOperation="destination-over",this.canvasContext.drawImage(this.buffers[0],0,0),this.canvasContext.setTransform(this.currentTransform),this.canvasContext.globalCompositeOperation="source-over"}},renderFrame:function(t){if(!this.hidden&&!this.data.hd&&(1!==this.data.td||t)){this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.setBlendMode();var e=0===this.data.ty;this.prepareLayer(),this.globalData.renderer.save(e),this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props),this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity),this.renderInnerContent(),this.globalData.renderer.restore(e),this.exitLayer(),this.maskManager.hasMasks&&this.globalData.renderer.restore(!0),this._isFirstFrame&&(this._isFirstFrame=!1)}},destroy:function(){this.canvasContext=null,this.data=null,this.globalData=null,this.maskManager.destroy()},mHelper:new Matrix},CVBaseElement.prototype.hide=CVBaseElement.prototype.hideElement,CVBaseElement.prototype.show=CVBaseElement.prototype.showElement,CVShapeData.prototype.setAsAnimated=SVGShapeData.prototype.setAsAnimated,extendPrototype([BaseElement,TransformElement,CVBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableElement],CVShapeElement),CVShapeElement.prototype.initElement=RenderableDOMElement.prototype.initElement,CVShapeElement.prototype.transformHelper={opacity:1,_opMdf:!1},CVShapeElement.prototype.dashResetter=[],CVShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[])},CVShapeElement.prototype.createStyleElement=function(t,e){var i={data:t,type:t.ty,preTransforms:this.transformsManager.addTransformSequence(e),transforms:[],elements:[],closed:!0===t.hd},r={};if("fl"===t.ty||"st"===t.ty?(r.c=PropertyFactory.getProp(this,t.c,1,255,this),r.c.k||(i.co="rgb("+bmFloor(r.c.v[0])+","+bmFloor(r.c.v[1])+","+bmFloor(r.c.v[2])+")")):"gf"!==t.ty&&"gs"!==t.ty||(r.s=PropertyFactory.getProp(this,t.s,1,null,this),r.e=PropertyFactory.getProp(this,t.e,1,null,this),r.h=PropertyFactory.getProp(this,t.h||{k:0},0,.01,this),r.a=PropertyFactory.getProp(this,t.a||{k:0},0,degToRads,this),r.g=new GradientProperty(this,t.g,this)),r.o=PropertyFactory.getProp(this,t.o,0,.01,this),"st"===t.ty||"gs"===t.ty){if(i.lc=lineCapEnum[t.lc||2],i.lj=lineJoinEnum[t.lj||2],1==t.lj&&(i.ml=t.ml),r.w=PropertyFactory.getProp(this,t.w,0,null,this),r.w.k||(i.wi=r.w.v),t.d){var s=new DashProperty(this,t.d,"canvas",this);r.d=s,r.d.k||(i.da=r.d.dashArray,i.do=r.d.dashoffset[0])}}else i.r=2===t.r?"evenodd":"nonzero";return this.stylesList.push(i),r.style=i,r},CVShapeElement.prototype.createGroupElement=function(){return{it:[],prevViewData:[]}},CVShapeElement.prototype.createTransformElement=function(t){return{transform:{opacity:1,_opMdf:!1,key:this.transformsManager.getNewKey(),op:PropertyFactory.getProp(this,t.o,0,.01,this),mProps:TransformPropertyFactory.getTransformProperty(this,t,this)}}},CVShapeElement.prototype.createShapeElement=function(t){var e=new CVShapeData(this,t,this.stylesList,this.transformsManager);return this.shapes.push(e),this.addShapeToModifiers(e),e},CVShapeElement.prototype.reloadShapes=function(){var t;this._isFirstFrame=!0;var e=this.itemsData.length;for(t=0;t<e;t+=1)this.prevViewData[t]=this.itemsData[t];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[]),e=this.dynamicProperties.length,t=0;t<e;t+=1)this.dynamicProperties[t].getValue();this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame)},CVShapeElement.prototype.addTransformToStyleList=function(t){var e,i=this.stylesList.length;for(e=0;e<i;e+=1)this.stylesList[e].closed||this.stylesList[e].transforms.push(t)},CVShapeElement.prototype.removeTransformFromStyleList=function(){var t,e=this.stylesList.length;for(t=0;t<e;t+=1)this.stylesList[t].closed||this.stylesList[t].transforms.pop()},CVShapeElement.prototype.closeStyles=function(t){var e,i=t.length;for(e=0;e<i;e+=1)t[e].closed=!0},CVShapeElement.prototype.searchShapes=function(t,e,i,r,s){var a,n,o,h,l,p,f=t.length-1,m=[],c=[],d=[].concat(s);for(a=f;0<=a;a-=1){if((h=this.searchProcessedElement(t[a]))?e[a]=i[h-1]:t[a]._shouldRender=r,"fl"===t[a].ty||"st"===t[a].ty||"gf"===t[a].ty||"gs"===t[a].ty)h?e[a].style.closed=!1:e[a]=this.createStyleElement(t[a],d),m.push(e[a].style);else if("gr"===t[a].ty){if(h)for(o=e[a].it.length,n=0;n<o;n+=1)e[a].prevViewData[n]=e[a].it[n];else e[a]=this.createGroupElement(t[a]);this.searchShapes(t[a].it,e[a].it,e[a].prevViewData,r,d)}else"tr"===t[a].ty?(h||(p=this.createTransformElement(t[a]),e[a]=p),d.push(e[a]),this.addTransformToStyleList(e[a])):"sh"===t[a].ty||"rc"===t[a].ty||"el"===t[a].ty||"sr"===t[a].ty?h||(e[a]=this.createShapeElement(t[a])):"tm"===t[a].ty||"rd"===t[a].ty||"pb"===t[a].ty||"zz"===t[a].ty||"op"===t[a].ty?(h?(l=e[a]).closed=!1:((l=ShapeModifiers.getModifier(t[a].ty)).init(this,t[a]),e[a]=l,this.shapeModifiers.push(l)),c.push(l)):"rp"===t[a].ty&&(h?(l=e[a]).closed=!0:(l=ShapeModifiers.getModifier(t[a].ty),(e[a]=l).init(this,t,a,e),this.shapeModifiers.push(l),r=!1),c.push(l));this.addProcessedElement(t[a],a+1)}for(this.removeTransformFromStyleList(),this.closeStyles(m),f=c.length,a=0;a<f;a+=1)c[a].closed=!0},CVShapeElement.prototype.renderInnerContent=function(){this.transformHelper.opacity=1,this.transformHelper._opMdf=!1,this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame),this.renderShape(this.transformHelper,this.shapesData,this.itemsData,!0)},CVShapeElement.prototype.renderShapeTransform=function(t,e){(t._opMdf||e.op._mdf||this._isFirstFrame)&&(e.opacity=t.opacity,e.opacity*=e.op.v,e._opMdf=!0)},CVShapeElement.prototype.drawLayer=function(){var t,e,i,r,s,a,n,o,h,l=this.stylesList.length,p=this.globalData.renderer,f=this.globalData.canvasContext;for(t=0;t<l;t+=1)if(("st"!==(o=(h=this.stylesList[t]).type)&&"gs"!==o||0!==h.wi)&&h.data._shouldRender&&0!==h.coOp&&0!==this.globalData.currentGlobalAlpha){for(p.save(),a=h.elements,"st"===o||"gs"===o?(p.ctxStrokeStyle("st"===o?h.co:h.grd),p.ctxLineWidth(h.wi),p.ctxLineCap(h.lc),p.ctxLineJoin(h.lj),p.ctxMiterLimit(h.ml||0)):p.ctxFillStyle("fl"===o?h.co:h.grd),p.ctxOpacity(h.coOp),"st"!==o&&"gs"!==o&&f.beginPath(),p.ctxTransform(h.preTransforms.finalTransform.props),i=a.length,e=0;e<i;e+=1){for("st"!==o&&"gs"!==o||(f.beginPath(),h.da&&(f.setLineDash(h.da),f.lineDashOffset=h.do)),s=(n=a[e].trNodes).length,r=0;r<s;r+=1)"m"===n[r].t?f.moveTo(n[r].p[0],n[r].p[1]):"c"===n[r].t?f.bezierCurveTo(n[r].pts[0],n[r].pts[1],n[r].pts[2],n[r].pts[3],n[r].pts[4],n[r].pts[5]):f.closePath();"st"!==o&&"gs"!==o||(p.ctxStroke(),h.da&&f.setLineDash(this.dashResetter))}"st"!==o&&"gs"!==o&&this.globalData.renderer.ctxFill(h.r),p.restore()}},CVShapeElement.prototype.renderShape=function(t,e,i,r){var s,a;for(a=t,s=e.length-1;0<=s;s-=1)"tr"===e[s].ty?(a=i[s].transform,this.renderShapeTransform(t,a)):"sh"===e[s].ty||"el"===e[s].ty||"rc"===e[s].ty||"sr"===e[s].ty?this.renderPath(e[s],i[s]):"fl"===e[s].ty?this.renderFill(e[s],i[s],a):"st"===e[s].ty?this.renderStroke(e[s],i[s],a):"gf"===e[s].ty||"gs"===e[s].ty?this.renderGradientFill(e[s],i[s],a):"gr"===e[s].ty?this.renderShape(a,e[s].it,i[s].it):e[s].ty;r&&this.drawLayer()},CVShapeElement.prototype.renderStyledShape=function(t,e){if(this._isFirstFrame||e._mdf||t.transforms._mdf){var i,r,s,a=t.trNodes,n=e.paths,o=n._length;a.length=0;var h=t.transforms.finalTransform;for(s=0;s<o;s+=1){var l=n.shapes[s];if(l&&l.v){for(r=l._length,i=1;i<r;i+=1)1===i&&a.push({t:"m",p:h.applyToPointArray(l.v[0][0],l.v[0][1],0)}),a.push({t:"c",pts:h.applyToTriplePoints(l.o[i-1],l.i[i],l.v[i])});1===r&&a.push({t:"m",p:h.applyToPointArray(l.v[0][0],l.v[0][1],0)}),l.c&&r&&(a.push({t:"c",pts:h.applyToTriplePoints(l.o[i-1],l.i[0],l.v[0])}),a.push({t:"z"}))}}t.trNodes=a}},CVShapeElement.prototype.renderPath=function(t,e){if(!0!==t.hd&&t._shouldRender){var i,r=e.styledShapes.length;for(i=0;i<r;i+=1)this.renderStyledShape(e.styledShapes[i],e.sh)}},CVShapeElement.prototype.renderFill=function(t,e,i){var r=e.style;(e.c._mdf||this._isFirstFrame)&&(r.co="rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i._opMdf||this._isFirstFrame)&&(r.coOp=e.o.v*i.opacity)},CVShapeElement.prototype.renderGradientFill=function(t,e,i){var r,s=e.style;if(!s.grd||e.g._mdf||e.s._mdf||e.e._mdf||1!==t.t&&(e.h._mdf||e.a._mdf)){var a,n=this.globalData.canvasContext,o=e.s.v,h=e.e.v;if(1===t.t)r=n.createLinearGradient(o[0],o[1],h[0],h[1]);else{var l=Math.sqrt(Math.pow(o[0]-h[0],2)+Math.pow(o[1]-h[1],2)),p=Math.atan2(h[1]-o[1],h[0]-o[0]),f=e.h.v;1<=f?f=.99:f<=-1&&(f=-.99);var m=l*f,c=Math.cos(p+e.a.v)*m+o[0],d=Math.sin(p+e.a.v)*m+o[1];r=n.createRadialGradient(c,d,0,o[0],o[1],l)}var u=t.g.p,y=e.g.c,g=1;for(a=0;a<u;a+=1)e.g._hasOpacity&&e.g._collapsable&&(g=e.g.o[2*a+1]),r.addColorStop(y[4*a]/100,"rgba("+y[4*a+1]+","+y[4*a+2]+","+y[4*a+3]+","+g+")");s.grd=r}s.coOp=e.o.v*i.opacity},CVShapeElement.prototype.renderStroke=function(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||this._isFirstFrame)&&(r.da=s.dashArray,r.do=s.dashoffset[0]),(e.c._mdf||this._isFirstFrame)&&(r.co="rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i._opMdf||this._isFirstFrame)&&(r.coOp=e.o.v*i.opacity),(e.w._mdf||this._isFirstFrame)&&(r.wi=e.w.v)},CVShapeElement.prototype.destroy=function(){this.shapesData=null,this.globalData=null,this.canvasContext=null,this.stylesList.length=0,this.itemsData.length=0},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement,ITextElement],CVTextElement),CVTextElement.prototype.tHelper=createTag("canvas").getContext("2d"),CVTextElement.prototype.buildNewText=function(){var t=this.textProperty.currentData;this.renderedLetters=createSizedArray(t.l?t.l.length:0);var e=!1;t.fc?(e=!0,this.values.fill=this.buildColor(t.fc)):this.values.fill="rgba(0,0,0,0)",this.fill=e;var i=!1;t.sc&&(i=!0,this.values.stroke=this.buildColor(t.sc),this.values.sWidth=t.sw);var r,s,a,n,o,h,l,p,f,m,c,d,u=this.globalData.fontManager.getFontByName(t.f),y=t.l,g=this.mHelper;this.stroke=i,this.values.fValue=t.finalSize+"px "+this.globalData.fontManager.getFontByName(t.f).fFamily,s=t.finalText.length;var v=this.data.singleShape,b=.001*t.tr*t.finalSize,x=0,P=0,E=!0,S=0;for(r=0;r<s;r+=1){n=(a=this.globalData.fontManager.getCharData(t.finalText[r],u.fStyle,this.globalData.fontManager.getFontByName(t.f).fFamily))&&a.data||{},g.reset(),v&&y[r].n&&(x=-b,P+=t.yOffset,P+=E?1:0,E=!1),f=(l=n.shapes?n.shapes[0].it:[]).length,g.scale(t.finalSize/100,t.finalSize/100),v&&this.applyTextPropertiesToMatrix(t,g,y[r].line,x,P),c=createSizedArray(f-1);var C=0;for(p=0;p<f;p+=1)if("sh"===l[p].ty){for(h=l[p].ks.k.i.length,m=l[p].ks.k,d=[],o=1;o<h;o+=1)1===o&&d.push(g.applyToX(m.v[0][0],m.v[0][1],0),g.applyToY(m.v[0][0],m.v[0][1],0)),d.push(g.applyToX(m.o[o-1][0],m.o[o-1][1],0),g.applyToY(m.o[o-1][0],m.o[o-1][1],0),g.applyToX(m.i[o][0],m.i[o][1],0),g.applyToY(m.i[o][0],m.i[o][1],0),g.applyToX(m.v[o][0],m.v[o][1],0),g.applyToY(m.v[o][0],m.v[o][1],0));d.push(g.applyToX(m.o[o-1][0],m.o[o-1][1],0),g.applyToY(m.o[o-1][0],m.o[o-1][1],0),g.applyToX(m.i[0][0],m.i[0][1],0),g.applyToY(m.i[0][0],m.i[0][1],0),g.applyToX(m.v[0][0],m.v[0][1],0),g.applyToY(m.v[0][0],m.v[0][1],0)),c[C]=d,C+=1}v&&(x+=y[r].l,x+=b),this.textSpans[S]?this.textSpans[S].elem=c:this.textSpans[S]={elem:c},S+=1}},CVTextElement.prototype.renderInnerContent=function(){var t,e,i,r,s,a;this.validateText(),this.canvasContext.font=this.values.fValue,this.globalData.renderer.ctxLineCap("butt"),this.globalData.renderer.ctxLineJoin("miter"),this.globalData.renderer.ctxMiterLimit(4),this.data.singleShape||this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag);var n,o=this.textAnimator.renderedLetters,h=this.textProperty.currentData.l;e=h.length;var l,p,f=null,m=null,c=null,d=this.globalData.renderer;for(t=0;t<e;t+=1)if(!h[t].n){if((n=o[t])&&(d.save(),d.ctxTransform(n.p),d.ctxOpacity(n.o)),this.fill){for(n&&n.fc?f!==n.fc&&(d.ctxFillStyle(n.fc),f=n.fc):f!==this.values.fill&&(f=this.values.fill,d.ctxFillStyle(this.values.fill)),r=(l=this.textSpans[t].elem).length,this.globalData.canvasContext.beginPath(),i=0;i<r;i+=1)for(a=(p=l[i]).length,this.globalData.canvasContext.moveTo(p[0],p[1]),s=2;s<a;s+=6)this.globalData.canvasContext.bezierCurveTo(p[s],p[s+1],p[s+2],p[s+3],p[s+4],p[s+5]);this.globalData.canvasContext.closePath(),d.ctxFill()}if(this.stroke){for(n&&n.sw?c!==n.sw&&(c=n.sw,d.ctxLineWidth(n.sw)):c!==this.values.sWidth&&(c=this.values.sWidth,d.ctxLineWidth(this.values.sWidth)),n&&n.sc?m!==n.sc&&(m=n.sc,d.ctxStrokeStyle(n.sc)):m!==this.values.stroke&&(m=this.values.stroke,d.ctxStrokeStyle(this.values.stroke)),r=(l=this.textSpans[t].elem).length,this.globalData.canvasContext.beginPath(),i=0;i<r;i+=1)for(a=(p=l[i]).length,this.globalData.canvasContext.moveTo(p[0],p[1]),s=2;s<a;s+=6)this.globalData.canvasContext.bezierCurveTo(p[s],p[s+1],p[s+2],p[s+3],p[s+4],p[s+5]);this.globalData.canvasContext.closePath(),d.ctxStroke()}n&&this.globalData.renderer.restore()}},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVImageElement),CVImageElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVImageElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVImageElement.prototype.createContent=function(){if(this.img.width&&(this.assetData.w!==this.img.width||this.assetData.h!==this.img.height)){var t=createTag("canvas");t.width=this.assetData.w,t.height=this.assetData.h;var e,i,r=t.getContext("2d"),s=this.img.width,a=this.img.height,n=s/a,o=this.assetData.w/this.assetData.h,h=this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio;o<n&&"xMidYMid slice"===h||n<o&&"xMidYMid slice"!==h?e=(i=a)*o:i=(e=s)/o,r.drawImage(this.img,(s-e)/2,(a-i)/2,e,i,0,0,this.assetData.w,this.assetData.h),this.img=t}},CVImageElement.prototype.renderInnerContent=function(){this.canvasContext.drawImage(this.img,0,0)},CVImageElement.prototype.destroy=function(){this.img=null},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVSolidElement),CVSolidElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVSolidElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVSolidElement.prototype.renderInnerContent=function(){this.globalData.renderer.ctxFillStyle(this.data.sc),this.globalData.renderer.ctxFillRect(0,0,this.data.sw,this.data.sh)},extendPrototype([BaseRenderer],CanvasRendererBase),CanvasRendererBase.prototype.createShape=function(t){return new CVShapeElement(t,this.globalData,this)},CanvasRendererBase.prototype.createText=function(t){return new CVTextElement(t,this.globalData,this)},CanvasRendererBase.prototype.createImage=function(t){return new CVImageElement(t,this.globalData,this)},CanvasRendererBase.prototype.createSolid=function(t){return new CVSolidElement(t,this.globalData,this)},CanvasRendererBase.prototype.createNull=SVGRenderer.prototype.createNull,CanvasRendererBase.prototype.ctxTransform=function(t){1===t[0]&&0===t[1]&&0===t[4]&&1===t[5]&&0===t[12]&&0===t[13]||this.canvasContext.transform(t[0],t[1],t[4],t[5],t[12],t[13])},CanvasRendererBase.prototype.ctxOpacity=function(t){this.canvasContext.globalAlpha*=t<0?0:t},CanvasRendererBase.prototype.ctxFillStyle=function(t){this.canvasContext.fillStyle=t},CanvasRendererBase.prototype.ctxStrokeStyle=function(t){this.canvasContext.strokeStyle=t},CanvasRendererBase.prototype.ctxLineWidth=function(t){this.canvasContext.lineWidth=t},CanvasRendererBase.prototype.ctxLineCap=function(t){this.canvasContext.lineCap=t},CanvasRendererBase.prototype.ctxLineJoin=function(t){this.canvasContext.lineJoin=t},CanvasRendererBase.prototype.ctxMiterLimit=function(t){this.canvasContext.miterLimit=t},CanvasRendererBase.prototype.ctxFill=function(t){this.canvasContext.fill(t)},CanvasRendererBase.prototype.ctxFillRect=function(t,e,i,r){this.canvasContext.fillRect(t,e,i,r)},CanvasRendererBase.prototype.ctxStroke=function(){this.canvasContext.stroke()},CanvasRendererBase.prototype.reset=function(){this.renderConfig.clearCanvas?this.contextData.reset():this.canvasContext.restore()},CanvasRendererBase.prototype.save=function(){this.canvasContext.save()},CanvasRendererBase.prototype.restore=function(t){this.renderConfig.clearCanvas?(t&&(this.globalData.blendMode="source-over"),this.contextData.restore(t)):this.canvasContext.restore()},CanvasRendererBase.prototype.configAnimation=function(t){if(this.animationItem.wrapper){this.animationItem.container=createTag("canvas");var e=this.animationItem.container.style;e.width="100%",e.height="100%";var i="0px 0px 0px";e.transformOrigin=i,e.mozTransformOrigin=i,e.webkitTransformOrigin=i,e["-webkit-transform"]=i,e.contentVisibility=this.renderConfig.contentVisibility,this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.animationItem.container.setAttribute("id",this.renderConfig.id)}else this.canvasContext=this.renderConfig.context;this.contextData.setContext(this.canvasContext),this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.setupGlobalData(t,document.body),this.globalData.canvasContext=this.canvasContext,(this.globalData.renderer=this).globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=createSizedArray(t.layers.length),this.updateContainerSize()},CanvasRendererBase.prototype.updateContainerSize=function(t,e){var i,r,s,a;if(this.reset(),this.canvasContext.canvas.height=t?(i=t,r=e,this.canvasContext.canvas.width=i,r):(r=this.animationItem.wrapper&&this.animationItem.container?(i=this.animationItem.wrapper.offsetWidth,this.animationItem.wrapper.offsetHeight):(i=this.canvasContext.canvas.width,this.canvasContext.canvas.height),this.canvasContext.canvas.width=i*this.renderConfig.dpr,r*this.renderConfig.dpr),-1!==this.renderConfig.preserveAspectRatio.indexOf("meet")||-1!==this.renderConfig.preserveAspectRatio.indexOf("slice")){var n=this.renderConfig.preserveAspectRatio.split(" "),o=n[1]||"meet",h=n[0]||"xMidYMid",l=h.substr(0,4),p=h.substr(4);s=i/r,a=this.transformCanvas.w/this.transformCanvas.h,this.transformCanvas.sy=s<a&&"meet"===o||a<s&&"slice"===o?(this.transformCanvas.sx=i/(this.transformCanvas.w/this.renderConfig.dpr),i/(this.transformCanvas.w/this.renderConfig.dpr)):(this.transformCanvas.sx=r/(this.transformCanvas.h/this.renderConfig.dpr),r/(this.transformCanvas.h/this.renderConfig.dpr)),this.transformCanvas.tx="xMid"===l&&(a<s&&"meet"===o||s<a&&"slice"===o)?(i-this.transformCanvas.w*(r/this.transformCanvas.h))/2*this.renderConfig.dpr:"xMax"===l&&(a<s&&"meet"===o||s<a&&"slice"===o)?(i-this.transformCanvas.w*(r/this.transformCanvas.h))*this.renderConfig.dpr:0,this.transformCanvas.ty="YMid"===p&&(s<a&&"meet"===o||a<s&&"slice"===o)?(r-this.transformCanvas.h*(i/this.transformCanvas.w))/2*this.renderConfig.dpr:"YMax"===p&&(s<a&&"meet"===o||a<s&&"slice"===o)?(r-this.transformCanvas.h*(i/this.transformCanvas.w))*this.renderConfig.dpr:0}else"none"===this.renderConfig.preserveAspectRatio?(this.transformCanvas.sx=i/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=r/(this.transformCanvas.h/this.renderConfig.dpr)):(this.transformCanvas.sx=this.renderConfig.dpr,this.transformCanvas.sy=this.renderConfig.dpr),this.transformCanvas.tx=0,this.transformCanvas.ty=0;this.transformCanvas.props=[this.transformCanvas.sx,0,0,0,0,this.transformCanvas.sy,0,0,0,0,1,0,this.transformCanvas.tx,this.transformCanvas.ty,0,1],this.ctxTransform(this.transformCanvas.props),this.canvasContext.beginPath(),this.canvasContext.rect(0,0,this.transformCanvas.w,this.transformCanvas.h),this.canvasContext.closePath(),this.canvasContext.clip(),this.renderFrame(this.renderedFrame,!0)},CanvasRendererBase.prototype.destroy=function(){var t;for(this.renderConfig.clearCanvas&&this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),t=(this.layers?this.layers.length:0)-1;0<=t;t-=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.globalData.canvasContext=null,this.animationItem.container=null,this.destroyed=!0},CanvasRendererBase.prototype.renderFrame=function(t,e){if((this.renderedFrame!==t||!0!==this.renderConfig.clearCanvas||e)&&!this.destroyed&&-1!==t){var i;this.renderedFrame=t,this.globalData.frameNum=t-this.animationItem._isFirstFrame,this.globalData.frameId+=1,this.globalData._mdf=!this.renderConfig.clearCanvas||e,this.globalData.projectInterface.currentFrame=t;var r=this.layers.length;for(this.completeLayers||this.checkLayers(t),i=r-1;0<=i;i-=1)(this.completeLayers||this.elements[i])&&this.elements[i].prepareFrame(t-this.layers[i].st);if(this.globalData._mdf){for(!0===this.renderConfig.clearCanvas?this.canvasContext.clearRect(0,0,this.transformCanvas.w,this.transformCanvas.h):this.save(),i=r-1;0<=i;i-=1)(this.completeLayers||this.elements[i])&&this.elements[i].renderFrame();!0!==this.renderConfig.clearCanvas&&this.restore()}}},CanvasRendererBase.prototype.buildItem=function(t){var e=this.elements;if(!e[t]&&99!==this.layers[t].ty){var i=this.createItem(this.layers[t],this,this.globalData);(e[t]=i).initExpressions()}},CanvasRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},CanvasRendererBase.prototype.hide=function(){this.animationItem.container.style.display="none"},CanvasRendererBase.prototype.show=function(){this.animationItem.container.style.display="block"},CVContextData.prototype.duplicate=function(){var t=2*this._length,e=0;for(e=this._length;e<t;e+=1)this.stack[e]=new CanvasContext;this._length=t},CVContextData.prototype.reset=function(){this.cArrPos=0,this.cTr.reset(),this.stack[this.cArrPos].opacity=1},CVContextData.prototype.restore=function(t){this.cArrPos-=1;var e,i=this.stack[this.cArrPos],r=i.transform,s=this.cTr.props;for(e=0;e<16;e+=1)s[e]=r[e];if(t){this.nativeContext.restore();var a=this.stack[this.cArrPos+1];this.appliedFillStyle=a.fillStyle,this.appliedStrokeStyle=a.strokeStyle,this.appliedLineWidth=a.lineWidth,this.appliedLineCap=a.lineCap,this.appliedLineJoin=a.lineJoin,this.appliedMiterLimit=a.miterLimit}this.nativeContext.setTransform(r[0],r[1],r[4],r[5],r[12],r[13]),(t||-1!==i.opacity&&this.currentOpacity!==i.opacity)&&(this.nativeContext.globalAlpha=i.opacity,this.currentOpacity=i.opacity),this.currentFillStyle=i.fillStyle,this.currentStrokeStyle=i.strokeStyle,this.currentLineWidth=i.lineWidth,this.currentLineCap=i.lineCap,this.currentLineJoin=i.lineJoin,this.currentMiterLimit=i.miterLimit},CVContextData.prototype.save=function(t){t&&this.nativeContext.save();var e=this.cTr.props;this._length<=this.cArrPos&&this.duplicate();var i,r=this.stack[this.cArrPos];for(i=0;i<16;i+=1)r.transform[i]=e[i];this.cArrPos+=1;var s=this.stack[this.cArrPos];s.opacity=r.opacity,s.fillStyle=r.fillStyle,s.strokeStyle=r.strokeStyle,s.lineWidth=r.lineWidth,s.lineCap=r.lineCap,s.lineJoin=r.lineJoin,s.miterLimit=r.miterLimit},CVContextData.prototype.setOpacity=function(t){this.stack[this.cArrPos].opacity=t},CVContextData.prototype.setContext=function(t){this.nativeContext=t},CVContextData.prototype.fillStyle=function(t){this.stack[this.cArrPos].fillStyle!==t&&(this.currentFillStyle=t,this.stack[this.cArrPos].fillStyle=t)},CVContextData.prototype.strokeStyle=function(t){this.stack[this.cArrPos].strokeStyle!==t&&(this.currentStrokeStyle=t,this.stack[this.cArrPos].strokeStyle=t)},CVContextData.prototype.lineWidth=function(t){this.stack[this.cArrPos].lineWidth!==t&&(this.currentLineWidth=t,this.stack[this.cArrPos].lineWidth=t)},CVContextData.prototype.lineCap=function(t){this.stack[this.cArrPos].lineCap!==t&&(this.currentLineCap=t,this.stack[this.cArrPos].lineCap=t)},CVContextData.prototype.lineJoin=function(t){this.stack[this.cArrPos].lineJoin!==t&&(this.currentLineJoin=t,this.stack[this.cArrPos].lineJoin=t)},CVContextData.prototype.miterLimit=function(t){this.stack[this.cArrPos].miterLimit!==t&&(this.currentMiterLimit=t,this.stack[this.cArrPos].miterLimit=t)},CVContextData.prototype.transform=function(t){this.transformMat.cloneFromProps(t);var e=this.cTr;this.transformMat.multiply(e),e.cloneFromProps(this.transformMat.props);var i=e.props;this.nativeContext.setTransform(i[0],i[1],i[4],i[5],i[12],i[13])},CVContextData.prototype.opacity=function(t){var e=this.stack[this.cArrPos].opacity;e*=t<0?0:t,this.stack[this.cArrPos].opacity!==e&&(this.currentOpacity!==t&&(this.nativeContext.globalAlpha=t,this.currentOpacity=t),this.stack[this.cArrPos].opacity=e)},CVContextData.prototype.fill=function(t){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fill(t)},CVContextData.prototype.fillRect=function(t,e,i,r){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fillRect(t,e,i,r)},CVContextData.prototype.stroke=function(){this.appliedStrokeStyle!==this.currentStrokeStyle&&(this.appliedStrokeStyle=this.currentStrokeStyle,this.nativeContext.strokeStyle=this.appliedStrokeStyle),this.appliedLineWidth!==this.currentLineWidth&&(this.appliedLineWidth=this.currentLineWidth,this.nativeContext.lineWidth=this.appliedLineWidth),this.appliedLineCap!==this.currentLineCap&&(this.appliedLineCap=this.currentLineCap,this.nativeContext.lineCap=this.appliedLineCap),this.appliedLineJoin!==this.currentLineJoin&&(this.appliedLineJoin=this.currentLineJoin,this.nativeContext.lineJoin=this.appliedLineJoin),this.appliedMiterLimit!==this.currentMiterLimit&&(this.appliedMiterLimit=this.currentMiterLimit,this.nativeContext.miterLimit=this.appliedMiterLimit),this.nativeContext.stroke()},extendPrototype([CanvasRendererBase,ICompElement,CVBaseElement],CVCompElement),CVCompElement.prototype.renderInnerContent=function(){var t,e=this.canvasContext;for(e.beginPath(),e.moveTo(0,0),e.lineTo(this.data.w,0),e.lineTo(this.data.w,this.data.h),e.lineTo(0,this.data.h),e.lineTo(0,0),e.clip(),t=this.layers.length-1;0<=t;t-=1)(this.completeLayers||this.elements[t])&&this.elements[t].renderFrame()},CVCompElement.prototype.destroy=function(){var t;for(t=this.layers.length-1;0<=t;t-=1)this.elements[t]&&this.elements[t].destroy();this.layers=null,this.elements=null},CVCompElement.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},extendPrototype([CanvasRendererBase],CanvasRenderer),CanvasRenderer.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},HBaseElement.prototype={checkBlendMode:function(){},initRendererElement:function(){this.baseElement=createTag(this.data.tg||"div"),this.data.hasMask?(this.svgElement=createNS("svg"),this.layerElement=createNS("g"),this.maskedElement=this.layerElement,this.svgElement.appendChild(this.layerElement),this.baseElement.appendChild(this.svgElement)):this.layerElement=this.baseElement,styleDiv(this.baseElement)},createContainerElements:function(){this.renderableEffectsManager=new CVEffects(this),this.transformedElement=this.baseElement,this.maskedElement=this.layerElement,this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0!==this.data.bm&&this.setBlendMode()},renderElement:function(){var t=this.transformedElement?this.transformedElement.style:{};if(this.finalTransform._matMdf){var e=this.finalTransform.mat.toCSS();t.transform=e,t.webkitTransform=e}this.finalTransform._opMdf&&(t.opacity=this.finalTransform.mProp.o.v)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},destroy:function(){this.layerElement=null,this.transformedElement=null,this.matteElement&&(this.matteElement=null),this.maskManager&&(this.maskManager.destroy(),this.maskManager=null)},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData)},addEffects:function(){},setMatte:function(){}},HBaseElement.prototype.getBaseElement=SVGBaseElement.prototype.getBaseElement,HBaseElement.prototype.destroyBaseElement=HBaseElement.prototype.destroy,HBaseElement.prototype.buildElementParenting=BaseRenderer.prototype.buildElementParenting,extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],HSolidElement),HSolidElement.prototype.createContent=function(){var t;this.data.hasMask?((t=createNS("rect")).setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.svgElement.setAttribute("width",this.data.sw),this.svgElement.setAttribute("height",this.data.sh)):((t=createTag("div")).style.width=this.data.sw+"px",t.style.height=this.data.sh+"px",t.style.backgroundColor=this.data.sc),this.layerElement.appendChild(t)},extendPrototype([BaseElement,TransformElement,HSolidElement,SVGShapeElement,HBaseElement,HierarchyElement,FrameElement,RenderableElement],HShapeElement),HShapeElement.prototype._renderShapeFrame=HShapeElement.prototype.renderInnerContent,HShapeElement.prototype.createContent=function(){var t;if(this.baseElement.style.fontSize=0,this.data.hasMask)this.layerElement.appendChild(this.shapesContainer),t=this.svgElement;else{t=createNS("svg");var e=this.comp.data?this.comp.data:this.globalData.compSize;t.setAttribute("width",e.w),t.setAttribute("height",e.h),t.appendChild(this.shapesContainer),this.layerElement.appendChild(t)}this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.shapesContainer,0,[],!0),this.filterUniqueShapes(),this.shapeCont=t},HShapeElement.prototype.getTransformedPoint=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)e=t[i].mProps.v.applyToPointArray(e[0],e[1],0);return e},HShapeElement.prototype.calculateShapeBoundingBox=function(t,e){var i,r,s,a,n,o=t.sh.v,h=t.transformers,l=o._length;if(!(l<=1)){for(i=0;i<l-1;i+=1)r=this.getTransformedPoint(h,o.v[i]),s=this.getTransformedPoint(h,o.o[i]),a=this.getTransformedPoint(h,o.i[i+1]),n=this.getTransformedPoint(h,o.v[i+1]),this.checkBounds(r,s,a,n,e);o.c&&(r=this.getTransformedPoint(h,o.v[i]),s=this.getTransformedPoint(h,o.o[i]),a=this.getTransformedPoint(h,o.i[0]),n=this.getTransformedPoint(h,o.v[0]),this.checkBounds(r,s,a,n,e))}},HShapeElement.prototype.checkBounds=function(t,e,i,r,s){this.getBoundsOfCurve(t,e,i,r);var a=this.shapeBoundingBox;s.x=bmMin(a.left,s.x),s.xMax=bmMax(a.right,s.xMax),s.y=bmMin(a.top,s.y),s.yMax=bmMax(a.bottom,s.yMax)},HShapeElement.prototype.shapeBoundingBox={left:0,right:0,top:0,bottom:0},HShapeElement.prototype.tempBoundingBox={x:0,xMax:0,y:0,yMax:0,width:0,height:0},HShapeElement.prototype.getBoundsOfCurve=function(t,e,i,r){for(var s,a,n,o,h,l,p,f=[[t[0],r[0]],[t[1],r[1]]],m=0;m<2;++m)a=6*t[m]-12*e[m]+6*i[m],s=-3*t[m]+9*e[m]-9*i[m]+3*r[m],n=3*e[m]-3*t[m],a|=0,n|=0,0===(s|=0)&&0===a||(0===s?0<(o=-n/a)&&o<1&&f[m].push(this.calculateF(o,t,e,i,r,m)):0<=(h=a*a-4*n*s)&&(0<(l=(-a+bmSqrt(h))/(2*s))&&l<1&&f[m].push(this.calculateF(l,t,e,i,r,m)),0<(p=(-a-bmSqrt(h))/(2*s))&&p<1&&f[m].push(this.calculateF(p,t,e,i,r,m))));this.shapeBoundingBox.left=bmMin.apply(null,f[0]),this.shapeBoundingBox.top=bmMin.apply(null,f[1]),this.shapeBoundingBox.right=bmMax.apply(null,f[0]),this.shapeBoundingBox.bottom=bmMax.apply(null,f[1])},HShapeElement.prototype.calculateF=function(t,e,i,r,s,a){return bmPow(1-t,3)*e[a]+3*bmPow(1-t,2)*t*i[a]+3*(1-t)*bmPow(t,2)*r[a]+bmPow(t,3)*s[a]},HShapeElement.prototype.calculateBoundingBox=function(t,e){var i,r=t.length;for(i=0;i<r;i+=1)t[i]&&t[i].sh?this.calculateShapeBoundingBox(t[i],e):t[i]&&t[i].it?this.calculateBoundingBox(t[i].it,e):t[i]&&t[i].style&&t[i].w&&this.expandStrokeBoundingBox(t[i].w,e)},HShapeElement.prototype.expandStrokeBoundingBox=function(t,e){var i=0;if(t.keyframes){for(var r=0;r<t.keyframes.length;r+=1){var s=t.keyframes[r].s;i<s&&(i=s)}i*=t.mult}else i=t.v*t.mult;e.x-=i,e.xMax+=i,e.y-=i,e.yMax+=i},HShapeElement.prototype.currentBoxContains=function(t){return this.currentBBox.x<=t.x&&this.currentBBox.y<=t.y&&this.currentBBox.width+this.currentBBox.x>=t.x+t.width&&this.currentBBox.height+this.currentBBox.y>=t.y+t.height},HShapeElement.prototype.renderInnerContent=function(){if(this._renderShapeFrame(),!this.hidden&&(this._isFirstFrame||this._mdf)){var t=this.tempBoundingBox,e=999999;if(t.x=e,t.xMax=-e,t.y=e,t.yMax=-e,this.calculateBoundingBox(this.itemsData,t),t.width=t.xMax<t.x?0:t.xMax-t.x,t.height=t.yMax<t.y?0:t.yMax-t.y,this.currentBoxContains(t))return;var i=!1;if(this.currentBBox.w!==t.width&&(this.currentBBox.w=t.width,this.shapeCont.setAttribute("width",t.width),i=!0),this.currentBBox.h!==t.height&&(this.currentBBox.h=t.height,this.shapeCont.setAttribute("height",t.height),i=!0),i||this.currentBBox.x!==t.x||this.currentBBox.y!==t.y){this.currentBBox.w=t.width,this.currentBBox.h=t.height,this.currentBBox.x=t.x,this.currentBBox.y=t.y,this.shapeCont.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h);var r=this.shapeCont.style,s="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)";r.transform=s,r.webkitTransform=s}}},extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],HTextElement),HTextElement.prototype.createContent=function(){if(this.isMasked=this.checkMasks(),this.isMasked){this.renderType="svg",this.compW=this.comp.data.w,this.compH=this.comp.data.h,this.svgElement.setAttribute("width",this.compW),this.svgElement.setAttribute("height",this.compH);var t=createNS("g");this.maskedElement.appendChild(t),this.innerElem=t}else this.renderType="html",this.innerElem=this.layerElement;this.checkParenting()},HTextElement.prototype.buildNewText=function(){var t=this.textProperty.currentData;this.renderedLetters=createSizedArray(t.l?t.l.length:0);var e=this.innerElem.style,i=t.fc?this.buildColor(t.fc):"rgba(0,0,0,0)";e.fill=i,e.color=i,t.sc&&(e.stroke=this.buildColor(t.sc),e.strokeWidth=t.sw+"px");var r,s,a=this.globalData.fontManager.getFontByName(t.f);if(!this.globalData.fontManager.chars)if(e.fontSize=t.finalSize+"px",e.lineHeight=t.finalSize+"px",a.fClass)this.innerElem.className=a.fClass;else{e.fontFamily=a.fFamily;var n=t.fWeight,o=t.fStyle;e.fontStyle=o,e.fontWeight=n}var h,l,p,f=t.l;s=f.length;var m,c=this.mHelper,d="",u=0;for(r=0;r<s;r+=1){if(this.globalData.fontManager.chars?(this.textPaths[u]?h=this.textPaths[u]:((h=createNS("path")).setAttribute("stroke-linecap",lineCapEnum[1]),h.setAttribute("stroke-linejoin",lineJoinEnum[2]),h.setAttribute("stroke-miterlimit","4")),this.isMasked||(this.textSpans[u]?p=(l=this.textSpans[u]).children[0]:((l=createTag("div")).style.lineHeight=0,(p=createNS("svg")).appendChild(h),styleDiv(l)))):this.isMasked?h=this.textPaths[u]?this.textPaths[u]:createNS("text"):this.textSpans[u]?(l=this.textSpans[u],h=this.textPaths[u]):(styleDiv(l=createTag("span")),styleDiv(h=createTag("span")),l.appendChild(h)),this.globalData.fontManager.chars){var y,g=this.globalData.fontManager.getCharData(t.finalText[r],a.fStyle,this.globalData.fontManager.getFontByName(t.f).fFamily);if(y=g?g.data:null,c.reset(),y&&y.shapes&&y.shapes.length&&(m=y.shapes[0].it,c.scale(t.finalSize/100,t.finalSize/100),d=this.createPathShape(c,m),h.setAttribute("d",d)),this.isMasked)this.innerElem.appendChild(h);else{if(this.innerElem.appendChild(l),y&&y.shapes){document.body.appendChild(p);var v=p.getBBox();p.setAttribute("width",v.width+2),p.setAttribute("height",v.height+2),p.setAttribute("viewBox",v.x-1+" "+(v.y-1)+" "+(v.width+2)+" "+(v.height+2));var b=p.style,x="translate("+(v.x-1)+"px,"+(v.y-1)+"px)";b.transform=x,b.webkitTransform=x,f[r].yOffset=v.y-1}else p.setAttribute("width",1),p.setAttribute("height",1);l.appendChild(p)}}else if(h.textContent=f[r].val,h.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),this.isMasked)this.innerElem.appendChild(h);else{this.innerElem.appendChild(l);var P=h.style,E="translate3d(0,"+-t.finalSize/1.2+"px,0)";P.transform=E,P.webkitTransform=E}this.isMasked?this.textSpans[u]=h:this.textSpans[u]=l,this.textSpans[u].style.display="block",this.textPaths[u]=h,u+=1}for(;u<this.textSpans.length;)this.textSpans[u].style.display="none",u+=1},HTextElement.prototype.renderInnerContent=function(){var t;if(this.validateText(),this.data.singleShape){if(!this._isFirstFrame&&!this.lettersChangedFlag)return;if(this.isMasked&&this.finalTransform._matMdf){this.svgElement.setAttribute("viewBox",-this.finalTransform.mProp.p.v[0]+" "+-this.finalTransform.mProp.p.v[1]+" "+this.compW+" "+this.compH),t=this.svgElement.style;var e="translate("+-this.finalTransform.mProp.p.v[0]+"px,"+-this.finalTransform.mProp.p.v[1]+"px)";t.transform=e,t.webkitTransform=e}}if(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag){var i,r,s,a,n,o=0,h=this.textAnimator.renderedLetters,l=this.textProperty.currentData.l;for(r=l.length,i=0;i<r;i+=1)l[i].n?o+=1:(a=this.textSpans[i],n=this.textPaths[i],s=h[o],o+=1,s._mdf.m&&(this.isMasked?a.setAttribute("transform",s.m):(a.style.webkitTransform=s.m,a.style.transform=s.m)),a.style.opacity=s.o,s.sw&&s._mdf.sw&&n.setAttribute("stroke-width",s.sw),s.sc&&s._mdf.sc&&n.setAttribute("stroke",s.sc),s.fc&&s._mdf.fc&&(n.setAttribute("fill",s.fc),n.style.color=s.fc));if(this.innerElem.getBBox&&!this.hidden&&(this._isFirstFrame||this._mdf)){var p=this.innerElem.getBBox();this.currentBBox.w!==p.width&&(this.currentBBox.w=p.width,this.svgElement.setAttribute("width",p.width)),this.currentBBox.h!==p.height&&(this.currentBBox.h=p.height,this.svgElement.setAttribute("height",p.height));if(this.currentBBox.w!==p.width+2||this.currentBBox.h!==p.height+2||this.currentBBox.x!==p.x-1||this.currentBBox.y!==p.y-1){this.currentBBox.w=p.width+2,this.currentBBox.h=p.height+2,this.currentBBox.x=p.x-1,this.currentBBox.y=p.y-1,this.svgElement.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h),t=this.svgElement.style;var f="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)";t.transform=f,t.webkitTransform=f}}}},extendPrototype([BaseElement,FrameElement,HierarchyElement],HCameraElement),HCameraElement.prototype.setup=function(){var t,e,i,r,s=this.comp.threeDElements.length;for(t=0;t<s;t+=1)if("3d"===(e=this.comp.threeDElements[t]).type){i=e.perspectiveElem.style,r=e.container.style;var a=this.pe.v+"px",n="0px 0px 0px",o="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";i.perspective=a,i.webkitPerspective=a,r.transformOrigin=n,r.mozTransformOrigin=n,r.webkitTransformOrigin=n,i.transform=o,i.webkitTransform=o}},HCameraElement.prototype.createElements=function(){},HCameraElement.prototype.hide=function(){},HCameraElement.prototype.renderFrame=function(){var t,e,i=this._isFirstFrame;if(this.hierarchy)for(e=this.hierarchy.length,t=0;t<e;t+=1)i=this.hierarchy[t].finalTransform.mProp._mdf||i;if(i||this.pe._mdf||this.p&&this.p._mdf||this.px&&(this.px._mdf||this.py._mdf||this.pz._mdf)||this.rx._mdf||this.ry._mdf||this.rz._mdf||this.or._mdf||this.a&&this.a._mdf){if(this.mat.reset(),this.hierarchy)for(t=e=this.hierarchy.length-1;0<=t;t-=1){var r=this.hierarchy[t].finalTransform.mProp;this.mat.translate(-r.p.v[0],-r.p.v[1],r.p.v[2]),this.mat.rotateX(-r.or.v[0]).rotateY(-r.or.v[1]).rotateZ(r.or.v[2]),this.mat.rotateX(-r.rx.v).rotateY(-r.ry.v).rotateZ(r.rz.v),this.mat.scale(1/r.s.v[0],1/r.s.v[1],1/r.s.v[2]),this.mat.translate(r.a.v[0],r.a.v[1],r.a.v[2])}if(this.p?this.mat.translate(-this.p.v[0],-this.p.v[1],this.p.v[2]):this.mat.translate(-this.px.v,-this.py.v,this.pz.v),this.a){var s;s=this.p?[this.p.v[0]-this.a.v[0],this.p.v[1]-this.a.v[1],this.p.v[2]-this.a.v[2]]:[this.px.v-this.a.v[0],this.py.v-this.a.v[1],this.pz.v-this.a.v[2]];var a=Math.sqrt(Math.pow(s[0],2)+Math.pow(s[1],2)+Math.pow(s[2],2)),n=[s[0]/a,s[1]/a,s[2]/a],o=Math.sqrt(n[2]*n[2]+n[0]*n[0]),h=Math.atan2(n[1],o),l=Math.atan2(n[0],-n[2]);this.mat.rotateY(l).rotateX(-h)}this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v),this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]),this.mat.translate(this.globalData.compSize.w/2,this.globalData.compSize.h/2,0),this.mat.translate(0,0,this.pe.v);var p=!this._prevMat.equals(this.mat);if((p||this.pe._mdf)&&this.comp.threeDElements){var f,m,c;for(e=this.comp.threeDElements.length,t=0;t<e;t+=1)if("3d"===(f=this.comp.threeDElements[t]).type){if(p){var d=this.mat.toCSS();(c=f.container.style).transform=d,c.webkitTransform=d}this.pe._mdf&&((m=f.perspectiveElem.style).perspective=this.pe.v+"px",m.webkitPerspective=this.pe.v+"px")}this.mat.clone(this._prevMat)}}this._isFirstFrame=!1},HCameraElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},HCameraElement.prototype.destroy=function(){},HCameraElement.prototype.getBaseElement=function(){return null},extendPrototype([BaseElement,TransformElement,HBaseElement,HSolidElement,HierarchyElement,FrameElement,RenderableElement],HImageElement),HImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData),e=new Image;this.data.hasMask?(this.imageElem=createNS("image"),this.imageElem.setAttribute("width",this.assetData.w+"px"),this.imageElem.setAttribute("height",this.assetData.h+"px"),this.imageElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.imageElem),this.baseElement.setAttribute("width",this.assetData.w),this.baseElement.setAttribute("height",this.assetData.h)):this.layerElement.appendChild(e),e.crossOrigin="anonymous",e.src=t,this.data.ln&&this.baseElement.setAttribute("id",this.data.ln)},extendPrototype([BaseRenderer],HybridRendererBase),HybridRendererBase.prototype.buildItem=SVGRenderer.prototype.buildItem,HybridRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){this.pendingElements.pop().checkParenting()}},HybridRendererBase.prototype.appendElementInPos=function(t,e){var i=t.getBaseElement();if(i){var r=this.layers[e];if(r.ddd&&this.supports3d)this.addTo3dContainer(i,e);else if(this.threeDElements)this.addTo3dContainer(i,e);else{for(var s,a,n=0;n<e;)this.elements[n]&&!0!==this.elements[n]&&this.elements[n].getBaseElement&&(a=this.elements[n],s=(this.layers[n].ddd?this.getThreeDContainerByPos(n):a.getBaseElement())||s),n+=1;s?r.ddd&&this.supports3d||this.layerElement.insertBefore(i,s):r.ddd&&this.supports3d||this.layerElement.appendChild(i)}}},HybridRendererBase.prototype.createShape=function(t){return this.supports3d?new HShapeElement(t,this.globalData,this):new SVGShapeElement(t,this.globalData,this)},HybridRendererBase.prototype.createText=function(t){return this.supports3d?new HTextElement(t,this.globalData,this):new SVGTextLottieElement(t,this.globalData,this)},HybridRendererBase.prototype.createCamera=function(t){return this.camera=new HCameraElement(t,this.globalData,this),this.camera},HybridRendererBase.prototype.createImage=function(t){return this.supports3d?new HImageElement(t,this.globalData,this):new IImageElement(t,this.globalData,this)},HybridRendererBase.prototype.createSolid=function(t){return this.supports3d?new HSolidElement(t,this.globalData,this):new ISolidElement(t,this.globalData,this)},HybridRendererBase.prototype.createNull=SVGRenderer.prototype.createNull,HybridRendererBase.prototype.getThreeDContainerByPos=function(t){for(var e=0,i=this.threeDElements.length;e<i;){if(this.threeDElements[e].startPos<=t&&this.threeDElements[e].endPos>=t)return this.threeDElements[e].perspectiveElem;e+=1}return null},HybridRendererBase.prototype.createThreeDContainer=function(t,e){var i,r,s=createTag("div");styleDiv(s);var a=createTag("div");if(styleDiv(a),"3d"===e){(i=s.style).width=this.globalData.compSize.w+"px",i.height=this.globalData.compSize.h+"px";var n="50% 50%";i.webkitTransformOrigin=n,i.mozTransformOrigin=n,i.transformOrigin=n;var o="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)";(r=a.style).transform=o,r.webkitTransform=o}s.appendChild(a);var h={container:a,perspectiveElem:s,startPos:t,endPos:t,type:e};return this.threeDElements.push(h),h},HybridRendererBase.prototype.build3dContainers=function(){var t,e,i=this.layers.length,r="";for(t=0;t<i;t+=1)this.layers[t].ddd&&3!==this.layers[t].ty?"3d"!==r&&(r="3d",e=this.createThreeDContainer(t,"3d")):"2d"!==r&&(r="2d",e=this.createThreeDContainer(t,"2d")),e.endPos=Math.max(e.endPos,t);for(t=(i=this.threeDElements.length)-1;0<=t;t-=1)this.resizerElem.appendChild(this.threeDElements[t].perspectiveElem)},HybridRendererBase.prototype.addTo3dContainer=function(t,e){for(var i=0,r=this.threeDElements.length;i<r;){if(e<=this.threeDElements[i].endPos){for(var s,a=this.threeDElements[i].startPos;a<e;)this.elements[a]&&this.elements[a].getBaseElement&&(s=this.elements[a].getBaseElement()),a+=1;s?this.threeDElements[i].container.insertBefore(t,s):this.threeDElements[i].container.appendChild(t);break}i+=1}},HybridRendererBase.prototype.configAnimation=function(t){var e=createTag("div"),i=this.animationItem.wrapper,r=e.style;r.width=t.w+"px",r.height=t.h+"px",styleDiv(this.resizerElem=e),r.transformStyle="flat",r.mozTransformStyle="flat",r.webkitTransformStyle="flat",this.renderConfig.className&&e.setAttribute("class",this.renderConfig.className),i.appendChild(e),r.overflow="hidden";var s=createNS("svg");s.setAttribute("width","1"),s.setAttribute("height","1"),styleDiv(s),this.resizerElem.appendChild(s);var a=createNS("defs");s.appendChild(a),this.data=t,this.setupGlobalData(t,s),this.globalData.defs=a,this.layers=t.layers,this.layerElement=this.resizerElem,this.build3dContainers(),this.updateContainerSize()},HybridRendererBase.prototype.destroy=function(){var t;this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.animationItem.container=null,this.globalData.defs=null;var e=this.layers?this.layers.length:0;for(t=0;t<e;t+=1)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},HybridRendererBase.prototype.updateContainerSize=function(){var t,e,i,r,s=this.animationItem.wrapper.offsetWidth,a=this.animationItem.wrapper.offsetHeight;r=s/a<this.globalData.compSize.w/this.globalData.compSize.h?(t=s/this.globalData.compSize.w,e=s/this.globalData.compSize.w,i=0,(a-this.globalData.compSize.h*(s/this.globalData.compSize.w))/2):(t=a/this.globalData.compSize.h,e=a/this.globalData.compSize.h,i=(s-this.globalData.compSize.w*(a/this.globalData.compSize.h))/2,0);var n=this.resizerElem.style;n.webkitTransform="matrix3d("+t+",0,0,0,0,"+e+",0,0,0,0,1,0,"+i+","+r+",0,1)",n.transform=n.webkitTransform},HybridRendererBase.prototype.renderFrame=SVGRenderer.prototype.renderFrame,HybridRendererBase.prototype.hide=function(){this.resizerElem.style.display="none"},HybridRendererBase.prototype.show=function(){this.resizerElem.style.display="block"},HybridRendererBase.prototype.initItems=function(){if(this.buildAllItems(),this.camera)this.camera.setup();else{var t,e=this.globalData.compSize.w,i=this.globalData.compSize.h,r=this.threeDElements.length;for(t=0;t<r;t+=1){var s=this.threeDElements[t].perspectiveElem.style;s.webkitPerspective=Math.sqrt(Math.pow(e,2)+Math.pow(i,2))+"px",s.perspective=s.webkitPerspective}}},HybridRendererBase.prototype.searchExtraCompositions=function(t){var e,i=t.length,r=createTag("div");for(e=0;e<i;e+=1)if(t[e].xt){var s=this.createComp(t[e],r,this.globalData.comp,null);s.initExpressions(),this.globalData.projectInterface.registerComposition(s)}},extendPrototype([HybridRendererBase,ICompElement,HBaseElement],HCompElement),HCompElement.prototype._createBaseContainerElements=HCompElement.prototype.createContainerElements,HCompElement.prototype.createContainerElements=function(){this._createBaseContainerElements(),this.data.hasMask?(this.svgElement.setAttribute("width",this.data.w),this.svgElement.setAttribute("height",this.data.h),this.transformedElement=this.baseElement):this.transformedElement=this.layerElement},HCompElement.prototype.addTo3dContainer=function(t,e){for(var i,r=0;r<e;)this.elements[r]&&this.elements[r].getBaseElement&&(i=this.elements[r].getBaseElement()),r+=1;i?this.layerElement.insertBefore(t,i):this.layerElement.appendChild(t)},HCompElement.prototype.createComp=function(t){return this.supports3d?new HCompElement(t,this.globalData,this):new SVGCompElement(t,this.globalData,this)},extendPrototype([HybridRendererBase],HybridRenderer),HybridRenderer.prototype.createComp=function(t){return this.supports3d?new HCompElement(t,this.globalData,this):new SVGCompElement(t,this.globalData,this)};var CompExpressionInterface=function(r){function t(t){for(var e=0,i=r.layers.length;e<i;){if(r.layers[e].nm===t||r.layers[e].ind===t)return r.elements[e].layerInterface;e+=1}return null}return Object.defineProperty(t,"_name",{value:r.data.nm}),(t.layer=t).pixelAspect=1,t.height=r.data.h||r.globalData.compSize.h,t.width=r.data.w||r.globalData.compSize.w,t.pixelAspect=1,t.frameDuration=1/r.globalData.frameRate,t.displayStartTime=0,t.numLayers=r.layers.length,t};function _typeof$2(t){return(_typeof$2="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function seedRandom(o,h){var l,p=this,f=256,m=6,c="random",d=h.pow(f,m),u=h.pow(2,52),y=2*u,g=f-1;function v(t){var e,i=t.length,n=this,r=0,s=n.i=n.j=0,a=n.S=[];for(i||(t=[i++]);r<f;)a[r]=r++;for(r=0;r<f;r++)a[r]=a[s=g&s+t[r%i]+(e=a[r])],a[s]=e;n.g=function(t){for(var e,i=0,r=n.i,s=n.j,a=n.S;t--;)e=a[r=g&r+1],i=i*f+a[g&(a[r]=a[s=g&s+e])+(a[s]=e)];return n.i=r,n.j=s,i}}function b(t,e){return e.i=t.i,e.j=t.j,e.S=t.S.slice(),e}function x(t,e){for(var i,r=t+"",s=0;s<r.length;)e[g&s]=g&(i^=19*e[g&s])+r.charCodeAt(s++);return P(e)}function P(t){return String.fromCharCode.apply(0,t)}h["seed"+c]=function(t,e,i){var r=[],s=x(function t(e,i){var r,s=[],a=_typeof$2(e);if(i&&"object"==a)for(r in e)try{s.push(t(e[r],i-1))}catch(t){}return s.length?s:"string"==a?e:e+"\0"}((e=!0===e?{entropy:!0}:e||{}).entropy?[t,P(o)]:null===t?function(){try{if(l)return P(l.randomBytes(f));var t=new Uint8Array(f);return(p.crypto||p.msCrypto).getRandomValues(t),P(t)}catch(t){var e=p.navigator,i=e&&e.plugins;return[+new Date,p,i,p.screen,P(o)]}}():t,3),r),a=new v(r),n=function(){for(var t=a.g(m),e=d,i=0;t<u;)t=(t+i)*f,e*=f,i=a.g(1);for(;y<=t;)t/=2,e/=2,i>>>=1;return(t+i)/e};return n.int32=function(){return 0|a.g(4)},n.quick=function(){return a.g(4)/4294967296},n.double=n,x(P(a.S),o),(e.pass||i||function(t,e,i,r){return r&&(r.S&&b(r,a),t.state=function(){return b(a,{})}),i?(h[c]=t,e):t})(n,s,"global"in e?e.global:this==h,e.state)},x(h.random(),o)}function initialize$2(t){seedRandom([],t)}var propTypes={SHAPE:"shape"};function _typeof$1(t){return(_typeof$1="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var ExpressionManager=function(){var ob={},Math=BMMath,window=null,document=null,XMLHttpRequest=null,fetch=null,frames=null,_lottieGlobal={};function resetFrame(){_lottieGlobal={}}function $bm_isInstanceOfArray(t){return t.constructor===Array||t.constructor===Float32Array}function isNumerable(t,e){return"number"===t||e instanceof Number||"boolean"===t||"string"===t}function $bm_neg(t){var e=_typeof$1(t);if("number"===e||t instanceof Number||"boolean"===e)return-t;if($bm_isInstanceOfArray(t)){var i,r=t.length,s=[];for(i=0;i<r;i+=1)s[i]=-t[i];return s}return t.propType?t.v:-t}initialize$2(BMMath);var easeInBez=BezierFactory.getBezierEasing(.333,0,.833,.833,"easeIn").get,easeOutBez=BezierFactory.getBezierEasing(.167,.167,.667,1,"easeOut").get,easeInOutBez=BezierFactory.getBezierEasing(.33,0,.667,1,"easeInOut").get;function sum(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e)||"string"===i||"string"===r)return t+e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]+=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t+e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]+e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}var add=sum;function sub(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e))return"string"===i&&(t=parseInt(t,10)),"string"===r&&(e=parseInt(e,10)),t-e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]-=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t-e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]-e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}function mul(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t*e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]*e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t*e[r];return i}return 0}function div(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t/e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]/e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t/e[r];return i}return 0}function mod(t,e){return"string"==typeof t&&(t=parseInt(t,10)),"string"==typeof e&&(e=parseInt(e,10)),t%e}var $bm_sum=sum,$bm_sub=sub,$bm_mul=mul,$bm_div=div,$bm_mod=mod;function clamp(t,e,i){if(i<e){var r=i;i=e,e=r}return Math.min(Math.max(t,e),i)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return e=e||0,Math.abs(t-e);var i;e||(e=helperLengthArray);var r=Math.min(t.length,e.length),s=0;for(i=0;i<r;i+=1)s+=Math.pow(e[i]-t[i],2);return Math.sqrt(s)}function normalize(t){return div(t,length(t))}function rgbToHsl(t){var e,i,r=t[0],s=t[1],a=t[2],n=Math.max(r,s,a),o=Math.min(r,s,a),h=(n+o)/2;if(n===o)i=e=0;else{var l=n-o;switch(i=.5<h?l/(2-n-o):l/(n+o),n){case r:e=(s-a)/l+(s<a?6:0);break;case s:e=(a-r)/l+2;break;case a:e=(r-s)/l+4}e/=6}return[e,i,h,t[3]]}function hue2rgb(t,e,i){return i<0&&(i+=1),1<i&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}function hslToRgb(t){var e,i,r,s=t[0],a=t[1],n=t[2];if(0===a)i=r=e=n;else{var o=n<.5?n*(1+a):n+a-n*a,h=2*n-o;e=hue2rgb(h,o,s+1/3),i=hue2rgb(h,o,s),r=hue2rgb(h,o,s-1/3)}return[e,i,r,t[3]]}function linear(t,e,i,r,s){if(void 0!==r&&void 0!==s||(r=e,s=i,e=0,i=1),i<e){var a=i;i=e,e=a}if(t<=e)return r;if(i<=t)return s;var n,o=i===e?0:(t-e)/(i-e);if(!r.length)return r+(s-r)*o;var h=r.length,l=createTypedArray("float32",h);for(n=0;n<h;n+=1)l[n]=r[n]+(s[n]-r[n])*o;return l}function random(t,e){if(void 0===e&&(void 0===t?(t=0,e=1):(e=t,t=void 0)),e.length){var i,r=e.length;t||(t=createTypedArray("float32",r));var s=createTypedArray("float32",r),a=BMMath.random();for(i=0;i<r;i+=1)s[i]=t[i]+a*(e[i]-t[i]);return s}return void 0===t&&(t=0),t+BMMath.random()*(e-t)}function createPath(t,e,i,r){var s,a=t.length,n=shapePool.newElement();n.setPathData(!!r,a);var o,h,l=[0,0];for(s=0;s<a;s+=1)o=e&&e[s]?e[s]:l,h=i&&i[s]?i[s]:l,n.setTripleAt(t[s][0],t[s][1],h[0]+t[s][0],h[1]+t[s][1],o[0]+t[s][0],o[1]+t[s][1],s,!0);return n}function initiateExpression(elem,data,property){function noOp(t){return t}if(!elem.globalData.renderConfig.runExpressions)return noOp;var val=data.x,needsVelocity=/velocity(?![\w\d])/.test(val),_needsRandom=-1!==val.indexOf("random"),elemType=elem.data.ty,transform,$bm_transform,content,effect,thisProperty=property;thisProperty.valueAtTime=thisProperty.getValueAtTime,Object.defineProperty(thisProperty,"value",{get:function(){return thisProperty.v}}),elem.comp.frameDuration=1/elem.comp.globalData.frameRate,elem.comp.displayStartTime=0;var inPoint=elem.data.ip/elem.comp.globalData.frameRate,outPoint=elem.data.op/elem.comp.globalData.frameRate,width=elem.data.sw?elem.data.sw:0,height=elem.data.sh?elem.data.sh:0,name=elem.data.nm,loopIn,loop_in,loopOut,loop_out,smooth,toWorld,fromWorld,fromComp,toComp,fromCompToSurface,position,rotation,anchorPoint,scale,thisLayer,thisComp,mask,valueAtTime,velocityAtTime,scoped_bm_rt,expression_function=eval("[function _expression_function(){"+val+";scoped_bm_rt=$bm_rt}]")[0],numKeys=property.kf?data.k.length:0,active=!this.data||!0!==this.data.hd,wiggle=function(t,e){var i,r,s=this.pv.length?this.pv.length:1,a=createTypedArray("float32",s);var n=Math.floor(5*time);for(r=i=0;i<n;){for(r=0;r<s;r+=1)a[r]+=-e+2*e*BMMath.random();i+=1}var o=5*time,h=o-Math.floor(o),l=createTypedArray("float32",s);if(1<s){for(r=0;r<s;r+=1)l[r]=this.pv[r]+a[r]+(-e+2*e*BMMath.random())*h;return l}return this.pv+a[0]+(-e+2*e*BMMath.random())*h}.bind(this);function loopInDuration(t,e){return loopIn(t,e,!0)}function loopOutDuration(t,e){return loopOut(t,e,!0)}thisProperty.loopIn&&(loopIn=thisProperty.loopIn.bind(thisProperty),loop_in=loopIn),thisProperty.loopOut&&(loopOut=thisProperty.loopOut.bind(thisProperty),loop_out=loopOut),thisProperty.smooth&&(smooth=thisProperty.smooth.bind(thisProperty)),this.getValueAtTime&&(valueAtTime=this.getValueAtTime.bind(this)),this.getVelocityAtTime&&(velocityAtTime=this.getVelocityAtTime.bind(this));var comp=elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface),time,velocity,value,text,textIndex,textTotal,selectorValue;function lookAt(t,e){var i=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],r=Math.atan2(i[0],Math.sqrt(i[1]*i[1]+i[2]*i[2]))/degToRads;return[-Math.atan2(i[1],i[2])/degToRads,r,0]}function easeOut(t,e,i,r,s){return applyEase(easeOutBez,t,e,i,r,s)}function easeIn(t,e,i,r,s){return applyEase(easeInBez,t,e,i,r,s)}function ease(t,e,i,r,s){return applyEase(easeInOutBez,t,e,i,r,s)}function applyEase(t,e,i,r,s,a){void 0===s?(s=i,a=r):e=(e-i)/(r-i),1<e?e=1:e<0&&(e=0);var n=t(e);if($bm_isInstanceOfArray(s)){var o,h=s.length,l=createTypedArray("float32",h);for(o=0;o<h;o+=1)l[o]=(a[o]-s[o])*n+s[o];return l}return(a-s)*n+s}function nearestKey(t){var e,i,r,s=data.k.length;if(data.k.length&&"number"!=typeof data.k[0])if(i=-1,(t*=elem.comp.globalData.frameRate)<data.k[0].t)i=1,r=data.k[0].t;else{for(e=0;e<s-1;e+=1){if(t===data.k[e].t){i=e+1,r=data.k[e].t;break}if(t>data.k[e].t&&t<data.k[e+1].t){r=t-data.k[e].t>data.k[e+1].t-t?(i=e+2,data.k[e+1].t):(i=e+1,data.k[e].t);break}}-1===i&&(i=e+1,r=data.k[e].t)}else r=i=0;var a={};return a.index=i,a.time=r/elem.comp.globalData.frameRate,a}function key(t){var e,i,r;if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);t-=1,e={time:data.k[t].t/elem.comp.globalData.frameRate,value:[]};var s=Object.prototype.hasOwnProperty.call(data.k[t],"s")?data.k[t].s:data.k[t-1].e;for(r=s.length,i=0;i<r;i+=1)e[i]=s[i],e.value[i]=s[i];return e}function framesToTime(t,e){return e||(e=elem.comp.globalData.frameRate),t/e}function timeToFrames(t,e){return t||0===t||(t=time),e||(e=elem.comp.globalData.frameRate),t*e}function seedRandom(t){BMMath.seedrandom(randSeed+t)}function sourceRectAtTime(){return elem.sourceRectAtTime()}function substring(t,e){return"string"==typeof value?void 0===e?value.substring(t):value.substring(t,e):""}function substr(t,e){return"string"==typeof value?void 0===e?value.substr(t):value.substr(t,e):""}function posterizeTime(t){time=0===t?0:Math.floor(time*t)/t,value=valueAtTime(time)}var index=elem.data.ind,hasParent=!(!elem.hierarchy||!elem.hierarchy.length),parent,randSeed=Math.floor(1e6*Math.random()),globalData=elem.globalData;function executeExpression(t){return value=t,this.frameExpressionId===elem.globalData.frameId&&"textSelector"!==this.propType?value:("textSelector"===this.propType&&(textIndex=this.textIndex,textTotal=this.textTotal,selectorValue=this.selectorValue),thisLayer||(text=elem.layerInterface.text,thisLayer=elem.layerInterface,thisComp=elem.comp.compInterface,toWorld=thisLayer.toWorld.bind(thisLayer),fromWorld=thisLayer.fromWorld.bind(thisLayer),fromComp=thisLayer.fromComp.bind(thisLayer),toComp=thisLayer.toComp.bind(thisLayer),mask=thisLayer.mask?thisLayer.mask.bind(thisLayer):null,fromCompToSurface=fromComp),transform||(transform=elem.layerInterface("ADBE Transform Group"),($bm_transform=transform)&&(anchorPoint=transform.anchorPoint)),4!==elemType||content||(content=thisLayer("ADBE Root Vectors Group")),effect||(effect=thisLayer(4)),(hasParent=!(!elem.hierarchy||!elem.hierarchy.length))&&!parent&&(parent=elem.hierarchy[0].layerInterface),time=this.comp.renderedFrame/this.comp.globalData.frameRate,_needsRandom&&seedRandom(randSeed+time),needsVelocity&&(velocity=velocityAtTime(time)),expression_function(),this.frameExpressionId=elem.globalData.frameId,scoped_bm_rt=scoped_bm_rt.propType===propTypes.SHAPE?scoped_bm_rt.v:scoped_bm_rt)}return executeExpression.__preventDeadCodeRemoval=[$bm_transform,anchorPoint,time,velocity,inPoint,outPoint,width,height,name,loop_in,loop_out,smooth,toComp,fromCompToSurface,toWorld,fromWorld,mask,position,rotation,scale,thisComp,numKeys,active,wiggle,loopInDuration,loopOutDuration,comp,lookAt,easeOut,easeIn,ease,nearestKey,key,text,textIndex,textTotal,selectorValue,framesToTime,timeToFrames,sourceRectAtTime,substring,substr,posterizeTime,index,globalData],executeExpression}return ob.initiateExpression=initiateExpression,ob.__preventDeadCodeRemoval=[window,document,XMLHttpRequest,fetch,frames,$bm_neg,add,$bm_sum,$bm_sub,$bm_mul,$bm_div,$bm_mod,clamp,radians_to_degrees,degreesToRadians,degrees_to_radians,normalize,rgbToHsl,hslToRgb,linear,random,createPath,_lottieGlobal],ob.resetFrame=resetFrame,ob}(),Expressions=(Dba={},Dba.initExpressions=function(t){var e=0,i=[];function r(){var t,e=i.length;for(t=0;t<e;t+=1)i[t].release();i.length=0}t.renderer.compInterface=CompExpressionInterface(t.renderer),t.renderer.globalData.projectInterface.registerComposition(t.renderer),t.renderer.globalData.pushExpression=function(){e+=1},t.renderer.globalData.popExpression=function(){0==(e-=1)&&r()},t.renderer.globalData.registerExpressionProperty=function(t){-1===i.indexOf(t)&&i.push(t)}},Dba.resetFrame=ExpressionManager.resetFrame,Dba),Dba,MaskManagerInterface=function(){function t(t,e){this._mask=t,this._data=e}Object.defineProperty(t.prototype,"maskPath",{get:function(){return this._mask.prop.k&&this._mask.prop.getValue(),this._mask.prop}}),Object.defineProperty(t.prototype,"maskOpacity",{get:function(){return this._mask.op.k&&this._mask.op.getValue(),100*this._mask.op.v}});return function(e){var i,r=createSizedArray(e.viewData.length),s=e.viewData.length;for(i=0;i<s;i+=1)r[i]=new t(e.viewData[i],e.masksProperties[i]);return function(t){for(i=0;i<s;){if(e.masksProperties[i].nm===t)return r[i];i+=1}return null}}}(),ExpressionPropertyInterface=function(){var s={pv:0,v:0,mult:1},n={pv:[0,0,0],v:[0,0,0],mult:1};function o(r,s,a){Object.defineProperty(r,"velocity",{get:function(){return s.getVelocityAtTime(s.comp.currentFrame)}}),r.numKeys=s.keyframes?s.keyframes.length:0,r.key=function(t){if(!r.numKeys)return 0;var e="";e="s"in s.keyframes[t-1]?s.keyframes[t-1].s:"e"in s.keyframes[t-2]?s.keyframes[t-2].e:s.keyframes[t-2].s;var i="unidimensional"===a?new Number(e):Object.assign({},e);return i.time=s.keyframes[t-1].t/s.elem.comp.globalData.frameRate,i.value="unidimensional"===a?e[0]:e,i},r.valueAtTime=s.getValueAtTime,r.speedAtTime=s.getSpeedAtTime,r.velocityAtTime=s.getVelocityAtTime,r.propertyGroup=s.propertyGroup}function e(){return s}return function(t){return t?"unidimensional"===t.propType?function(t){t&&"pv"in t||(t=s);var e=1/t.mult,i=t.pv*e,r=new Number(i);return r.value=i,o(r,t,"unidimensional"),function(){return t.k&&t.getValue(),i=t.v*e,r.value!==i&&((r=new Number(i)).value=i,o(r,t,"unidimensional")),r}}(t):function(e){e&&"pv"in e||(e=n);var i=1/e.mult,r=e.data&&e.data.l||e.pv.length,s=createTypedArray("float32",r),a=createTypedArray("float32",r);return s.value=a,o(s,e,"multidimensional"),function(){e.k&&e.getValue();for(var t=0;t<r;t+=1)a[t]=e.v[t]*i,s[t]=a[t];return s}}(t):e}}(),TransformExpressionInterface=function(t){function e(t){switch(t){case"scale":case"Scale":case"ADBE Scale":case 6:return e.scale;case"rotation":case"Rotation":case"ADBE Rotation":case"ADBE Rotate Z":case 10:return e.rotation;case"ADBE Rotate X":return e.xRotation;case"ADBE Rotate Y":return e.yRotation;case"position":case"Position":case"ADBE Position":case 2:return e.position;case"ADBE Position_0":return e.xPosition;case"ADBE Position_1":return e.yPosition;case"ADBE Position_2":return e.zPosition;case"anchorPoint":case"AnchorPoint":case"Anchor Point":case"ADBE AnchorPoint":case 1:return e.anchorPoint;case"opacity":case"Opacity":case 11:return e.opacity;default:return null}}var i,r,s,a;return Object.defineProperty(e,"rotation",{get:ExpressionPropertyInterface(t.r||t.rz)}),Object.defineProperty(e,"zRotation",{get:ExpressionPropertyInterface(t.rz||t.r)}),Object.defineProperty(e,"xRotation",{get:ExpressionPropertyInterface(t.rx)}),Object.defineProperty(e,"yRotation",{get:ExpressionPropertyInterface(t.ry)}),Object.defineProperty(e,"scale",{get:ExpressionPropertyInterface(t.s)}),t.p?a=ExpressionPropertyInterface(t.p):(i=ExpressionPropertyInterface(t.px),r=ExpressionPropertyInterface(t.py),t.pz&&(s=ExpressionPropertyInterface(t.pz))),Object.defineProperty(e,"position",{get:function(){return t.p?a():[i(),r(),s?s():0]}}),Object.defineProperty(e,"xPosition",{get:ExpressionPropertyInterface(t.px)}),Object.defineProperty(e,"yPosition",{get:ExpressionPropertyInterface(t.py)}),Object.defineProperty(e,"zPosition",{get:ExpressionPropertyInterface(t.pz)}),Object.defineProperty(e,"anchorPoint",{get:ExpressionPropertyInterface(t.a)}),Object.defineProperty(e,"opacity",{get:ExpressionPropertyInterface(t.o)}),Object.defineProperty(e,"skew",{get:ExpressionPropertyInterface(t.sk)}),Object.defineProperty(e,"skewAxis",{get:ExpressionPropertyInterface(t.sa)}),Object.defineProperty(e,"orientation",{get:ExpressionPropertyInterface(t.or)}),e},LayerExpressionInterface=function(){function s(t){var e=new Matrix;void 0!==t?this._elem.finalTransform.mProp.getValueAtTime(t).clone(e):this._elem.finalTransform.mProp.applyToMatrix(e);return e}function a(t,e){var i=this.getMatrix(e);return i.props[12]=0,i.props[13]=0,i.props[14]=0,this.applyPoint(i,t)}function n(t,e){var i=this.getMatrix(e);return this.applyPoint(i,t)}function o(t,e){var i=this.getMatrix(e);return i.props[12]=0,i.props[13]=0,i.props[14]=0,this.invertPoint(i,t)}function h(t,e){var i=this.getMatrix(e);return this.invertPoint(i,t)}function l(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(t)}return t.applyToPointArray(e[0],e[1],e[2]||0)}function p(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(t)}return t.inversePoint(e)}function f(t){var e=new Matrix;if(e.reset(),this._elem.finalTransform.mProp.applyToMatrix(e),this._elem.hierarchy&&this._elem.hierarchy.length){var i,r=this._elem.hierarchy.length;for(i=0;i<r;i+=1)this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(e);return e.inversePoint(t)}return e.inversePoint(t)}function m(){return[1,1,1,1]}return function(e){var i;function r(t){switch(t){case"ADBE Root Vectors Group":case"Contents":case 2:return r.shapeInterface;case 1:case 6:case"Transform":case"transform":case"ADBE Transform Group":return i;case 4:case"ADBE Effect Parade":case"effects":case"Effects":return r.effect;case"ADBE Text Properties":return r.textInterface;default:return null}}r.getMatrix=s,r.invertPoint=p,r.applyPoint=l,r.toWorld=n,r.toWorldVec=a,r.fromWorld=h,r.fromWorldVec=o,r.toComp=n,r.fromComp=f,r.sampleImage=m,r.sourceRectAtTime=e.sourceRectAtTime.bind(e);var t=getDescriptor(i=TransformExpressionInterface((r._elem=e).finalTransform.mProp),"anchorPoint");return Object.defineProperties(r,{hasParent:{get:function(){return e.hierarchy.length}},parent:{get:function(){return e.hierarchy[0].layerInterface}},rotation:getDescriptor(i,"rotation"),scale:getDescriptor(i,"scale"),position:getDescriptor(i,"position"),opacity:getDescriptor(i,"opacity"),anchorPoint:t,anchor_point:t,transform:{get:function(){return i}},active:{get:function(){return e.isInRange}}}),r.startTime=e.data.st,r.index=e.data.ind,r.source=e.data.refId,r.height=0===e.data.ty?e.data.h:100,r.width=0===e.data.ty?e.data.w:100,r.inPoint=e.data.ip/e.comp.globalData.frameRate,r.outPoint=e.data.op/e.comp.globalData.frameRate,r._name=e.data.nm,r.registerMaskInterface=function(t){r.mask=new MaskManagerInterface(t,e)},r.registerEffectsInterface=function(t){r.effect=t},r}}(),propertyGroupFactory=function(e,i){return function(t){return(t=void 0===t?1:t)<=0?e:i(t-1)}},PropertyInterface=function(t,e){var i={_name:t};return function(t){return(t=void 0===t?1:t)<=0?i:e(t-1)}},EffectsExpressionInterface=function(){function l(s,t,e,i){function r(t){for(var e=s.ef,i=0,r=e.length;i<r;){if(t===e[i].nm||t===e[i].mn||t===e[i].ix)return 5===e[i].ty?o[i]:o[i]();i+=1}throw new Error}var a,n=propertyGroupFactory(r,e),o=[],h=s.ef.length;for(a=0;a<h;a+=1)5===s.ef[a].ty?o.push(l(s.ef[a],t.effectElements[a],t.effectElements[a].propertyGroup,i)):o.push(p(t.effectElements[a],s.ef[a].ty,i,n));return"ADBE Color Control"===s.mn&&Object.defineProperty(r,"color",{get:function(){return o[0]()}}),Object.defineProperties(r,{numProperties:{get:function(){return s.np}},_name:{value:s.nm},propertyGroup:{value:n}}),r.enabled=0!==s.en,r.active=r.enabled,r}function p(t,e,i,r){var s=ExpressionPropertyInterface(t.p);return t.p.setGroupProperty&&t.p.setGroupProperty(PropertyInterface("",r)),function(){return 10===e?i.comp.compInterface(t.p.v):s()}}return{createEffectsInterface:function(t,e){if(t.effectsManager){var i,r=[],s=t.data.ef,a=t.effectsManager.effectElements.length;for(i=0;i<a;i+=1)r.push(l(s[i],t.effectsManager.effectElements[i],e,t));var n=t.data.ef||[],o=function(t){for(i=0,a=n.length;i<a;){if(t===n[i].nm||t===n[i].mn||t===n[i].ix)return r[i];i+=1}return null};return Object.defineProperty(o,"numProperties",{get:function(){return n.length}}),o}return null}}}(),ShapePathInterface=function(t,e,i){var r=e.sh;function s(t){return"Shape"===t||"shape"===t||"Path"===t||"path"===t||"ADBE Vector Shape"===t||2===t?s.path:null}var a=propertyGroupFactory(s,i);return r.setGroupProperty(PropertyInterface("Path",a)),Object.defineProperties(s,{path:{get:function(){return r.k&&r.getValue(),r}},shape:{get:function(){return r.k&&r.getValue(),r}},_name:{value:t.nm},ix:{value:t.ix},propertyIndex:{value:t.ix},mn:{value:t.mn},propertyGroup:{value:i}}),s},ShapeExpressionInterface=function(){function n(t,e,i){var r,s=[],a=t?t.length:0;for(r=0;r<a;r+=1)"gr"===t[r].ty?s.push(o(t[r],e[r],i)):"fl"===t[r].ty?s.push(h(t[r],e[r],i)):"st"===t[r].ty?s.push(f(t[r],e[r],i)):"tm"===t[r].ty?s.push(m(t[r],e[r],i)):"tr"===t[r].ty||("el"===t[r].ty?s.push(d(t[r],e[r],i)):"sr"===t[r].ty?s.push(u(t[r],e[r],i)):"sh"===t[r].ty?s.push(ShapePathInterface(t[r],e[r],i)):"rc"===t[r].ty?s.push(y(t[r],e[r],i)):"rd"===t[r].ty?s.push(g(t[r],e[r],i)):"rp"===t[r].ty?s.push(v(t[r],e[r],i)):"gf"===t[r].ty?s.push(l(t[r],e[r],i)):s.push(p(t[r],e[r])));return s}function o(t,e,i){var r=function(t){switch(t){case"ADBE Vectors Group":case"Contents":case 2:return r.content;default:return r.transform}};r.propertyGroup=propertyGroupFactory(r,i);var s=function(t,e,i){var r,s=function(t){for(var e=0,i=r.length;e<i;){if(r[e]._name===t||r[e].mn===t||r[e].propertyIndex===t||r[e].ix===t||r[e].ind===t)return r[e];e+=1}return"number"==typeof t?r[t-1]:null};s.propertyGroup=propertyGroupFactory(s,i),r=n(t.it,e.it,s.propertyGroup),s.numProperties=r.length;var a=c(t.it[t.it.length-1],e.it[e.it.length-1],s.propertyGroup);return s.transform=a,s.propertyIndex=t.cix,s._name=t.nm,s}(t,e,r.propertyGroup),a=c(t.it[t.it.length-1],e.it[e.it.length-1],r.propertyGroup);return r.content=s,r.transform=a,Object.defineProperty(r,"_name",{get:function(){return t.nm}}),r.numProperties=t.np,r.propertyIndex=t.ix,r.nm=t.nm,r.mn=t.mn,r}function h(t,e,i){function r(t){return"Color"===t||"color"===t?r.color:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r}function l(t,e,i){function r(t){return"Start Point"===t||"start point"===t?r.startPoint:"End Point"===t||"end point"===t?r.endPoint:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{startPoint:{get:ExpressionPropertyInterface(e.s)},endPoint:{get:ExpressionPropertyInterface(e.e)},opacity:{get:ExpressionPropertyInterface(e.o)},type:{get:function(){return"a"}},_name:{value:t.nm},mn:{value:t.mn}}),e.s.setGroupProperty(PropertyInterface("Start Point",i)),e.e.setGroupProperty(PropertyInterface("End Point",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r}function p(){return function(){return null}}function f(t,e,i){var r,s=propertyGroupFactory(l,i),a=propertyGroupFactory(h,s);var n,o=t.d?t.d.length:0,h={};for(r=0;r<o;r+=1)n=r,Object.defineProperty(h,t.d[n].nm,{get:ExpressionPropertyInterface(e.d.dataProps[n].p)}),e.d.dataProps[r].p.setGroupProperty(a);function l(t){return"Color"===t||"color"===t?l.color:"Opacity"===t||"opacity"===t?l.opacity:"Stroke Width"===t||"stroke width"===t?l.strokeWidth:null}return Object.defineProperties(l,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},strokeWidth:{get:ExpressionPropertyInterface(e.w)},dash:{get:function(){return h}},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",s)),e.o.setGroupProperty(PropertyInterface("Opacity",s)),e.w.setGroupProperty(PropertyInterface("Stroke Width",s)),l}function m(e,t,i){function r(t){return t===e.e.ix||"End"===t||"end"===t?r.end:t===e.s.ix?r.start:t===e.o.ix?r.offset:null}var s=propertyGroupFactory(r,i);return r.propertyIndex=e.ix,t.s.setGroupProperty(PropertyInterface("Start",s)),t.e.setGroupProperty(PropertyInterface("End",s)),t.o.setGroupProperty(PropertyInterface("Offset",s)),r.propertyIndex=e.ix,r.propertyGroup=i,Object.defineProperties(r,{start:{get:ExpressionPropertyInterface(t.s)},end:{get:ExpressionPropertyInterface(t.e)},offset:{get:ExpressionPropertyInterface(t.o)},_name:{value:e.nm}}),r.mn=e.mn,r}function c(e,t,i){function r(t){return e.a.ix===t||"Anchor Point"===t?r.anchorPoint:e.o.ix===t||"Opacity"===t?r.opacity:e.p.ix===t||"Position"===t?r.position:e.r.ix===t||"Rotation"===t||"ADBE Vector Rotation"===t?r.rotation:e.s.ix===t||"Scale"===t?r.scale:e.sk&&e.sk.ix===t||"Skew"===t?r.skew:e.sa&&e.sa.ix===t||"Skew Axis"===t?r.skewAxis:null}var s=propertyGroupFactory(r,i);return t.transform.mProps.o.setGroupProperty(PropertyInterface("Opacity",s)),t.transform.mProps.p.setGroupProperty(PropertyInterface("Position",s)),t.transform.mProps.a.setGroupProperty(PropertyInterface("Anchor Point",s)),t.transform.mProps.s.setGroupProperty(PropertyInterface("Scale",s)),t.transform.mProps.r.setGroupProperty(PropertyInterface("Rotation",s)),t.transform.mProps.sk&&(t.transform.mProps.sk.setGroupProperty(PropertyInterface("Skew",s)),t.transform.mProps.sa.setGroupProperty(PropertyInterface("Skew Angle",s))),t.transform.op.setGroupProperty(PropertyInterface("Opacity",s)),Object.defineProperties(r,{opacity:{get:ExpressionPropertyInterface(t.transform.mProps.o)},position:{get:ExpressionPropertyInterface(t.transform.mProps.p)},anchorPoint:{get:ExpressionPropertyInterface(t.transform.mProps.a)},scale:{get:ExpressionPropertyInterface(t.transform.mProps.s)},rotation:{get:ExpressionPropertyInterface(t.transform.mProps.r)},skew:{get:ExpressionPropertyInterface(t.transform.mProps.sk)},skewAxis:{get:ExpressionPropertyInterface(t.transform.mProps.sa)},_name:{value:e.nm}}),r.ty="tr",r.mn=e.mn,r.propertyGroup=i,r}function d(e,t,i){function r(t){return e.p.ix===t?r.position:e.s.ix===t?r.size:null}var s=propertyGroupFactory(r,i);r.propertyIndex=e.ix;var a="tm"===t.sh.ty?t.sh.prop:t.sh;return a.s.setGroupProperty(PropertyInterface("Size",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),Object.defineProperties(r,{size:{get:ExpressionPropertyInterface(a.s)},position:{get:ExpressionPropertyInterface(a.p)},_name:{value:e.nm}}),r.mn=e.mn,r}function u(e,t,i){function r(t){return e.p.ix===t?r.position:e.r.ix===t?r.rotation:e.pt.ix===t?r.points:e.or.ix===t||"ADBE Vector Star Outer Radius"===t?r.outerRadius:e.os.ix===t?r.outerRoundness:!e.ir||e.ir.ix!==t&&"ADBE Vector Star Inner Radius"!==t?e.is&&e.is.ix===t?r.innerRoundness:null:r.innerRadius}var s=propertyGroupFactory(r,i),a="tm"===t.sh.ty?t.sh.prop:t.sh;return r.propertyIndex=e.ix,a.or.setGroupProperty(PropertyInterface("Outer Radius",s)),a.os.setGroupProperty(PropertyInterface("Outer Roundness",s)),a.pt.setGroupProperty(PropertyInterface("Points",s)),a.p.setGroupProperty(PropertyInterface("Position",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),e.ir&&(a.ir.setGroupProperty(PropertyInterface("Inner Radius",s)),a.is.setGroupProperty(PropertyInterface("Inner Roundness",s))),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(a.p)},rotation:{get:ExpressionPropertyInterface(a.r)},points:{get:ExpressionPropertyInterface(a.pt)},outerRadius:{get:ExpressionPropertyInterface(a.or)},outerRoundness:{get:ExpressionPropertyInterface(a.os)},innerRadius:{get:ExpressionPropertyInterface(a.ir)},innerRoundness:{get:ExpressionPropertyInterface(a.is)},_name:{value:e.nm}}),r.mn=e.mn,r}function y(e,t,i){function r(t){return e.p.ix===t?r.position:e.r.ix===t?r.roundness:e.s.ix===t||"Size"===t||"ADBE Vector Rect Size"===t?r.size:null}var s=propertyGroupFactory(r,i),a="tm"===t.sh.ty?t.sh.prop:t.sh;return r.propertyIndex=e.ix,a.p.setGroupProperty(PropertyInterface("Position",s)),a.s.setGroupProperty(PropertyInterface("Size",s)),a.r.setGroupProperty(PropertyInterface("Rotation",s)),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(a.p)},roundness:{get:ExpressionPropertyInterface(a.r)},size:{get:ExpressionPropertyInterface(a.s)},_name:{value:e.nm}}),r.mn=e.mn,r}function g(e,t,i){function r(t){return e.r.ix===t||"Round Corners 1"===t?r.radius:null}var s=propertyGroupFactory(r,i),a=t;return r.propertyIndex=e.ix,a.rd.setGroupProperty(PropertyInterface("Radius",s)),Object.defineProperties(r,{radius:{get:ExpressionPropertyInterface(a.rd)},_name:{value:e.nm}}),r.mn=e.mn,r}function v(e,t,i){function r(t){return e.c.ix===t||"Copies"===t?r.copies:e.o.ix===t||"Offset"===t?r.offset:null}var s=propertyGroupFactory(r,i),a=t;return r.propertyIndex=e.ix,a.c.setGroupProperty(PropertyInterface("Copies",s)),a.o.setGroupProperty(PropertyInterface("Offset",s)),Object.defineProperties(r,{copies:{get:ExpressionPropertyInterface(a.c)},offset:{get:ExpressionPropertyInterface(a.o)},_name:{value:e.nm}}),r.mn=e.mn,r}return function(t,e,r){var s;function i(t){if("number"==typeof t)return 0===(t=void 0===t?1:t)?r:s[t-1];for(var e=0,i=s.length;e<i;){if(s[e]._name===t)return s[e];e+=1}return null}return i.propertyGroup=propertyGroupFactory(i,function(){return r}),s=n(t,e,i.propertyGroup),i.numProperties=s.length,i._name="Contents",i}}(),TextExpressionInterface=function(e){var i;function r(t){switch(t){case"ADBE Text Document":return r.sourceText;default:return null}}return Object.defineProperty(r,"sourceText",{get:function(){e.textProperty.getValue();var t=e.textProperty.currentData.t;return i&&t===i.value||((i=new String(t)).value=t||new String(t),Object.defineProperty(i,"style",{get:function(){return{fillColor:e.textProperty.currentData.fc}}})),i}}),r};function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var FootageInterface=(aha=function(t){function e(t){return"Outline"===t?e.outlineInterface():null}return e._name="Outline",e.outlineInterface=function(t){var r="",s=t.getFootageData();function a(t){if(s[t])return"object"===_typeof(s=s[r=t])?a:s;var e=t.indexOf(r);if(-1===e)return"";var i=parseInt(t.substr(e+r.length),10);return"object"===_typeof(s=s[i])?a:s}return function(){return r="",s=t.getFootageData(),a}}(t),e},function(t){function e(t){return"Data"===t?e.dataInterface:null}return e._name="Data",e.dataInterface=aha(t),e}),aha,interfaces={layer:LayerExpressionInterface,effects:EffectsExpressionInterface,comp:CompExpressionInterface,shape:ShapeExpressionInterface,text:TextExpressionInterface,footage:FootageInterface};function getInterface(t){return interfaces[t]||null}var expressionHelpers={searchExpressions:function(t,e,i){e.x&&(i.k=!0,i.x=!0,i.initiateExpression=ExpressionManager.initiateExpression,i.effectsSequence.push(i.initiateExpression(t,e,i).bind(i)))},getSpeedAtTime:function(t){var e=this.getValueAtTime(t),i=this.getValueAtTime(t+-.01),r=0;if(e.length){var s;for(s=0;s<e.length;s+=1)r+=Math.pow(i[s]-e[s],2);r=100*Math.sqrt(r)}else r=0;return r},getVelocityAtTime:function(t){if(void 0!==this.vel)return this.vel;var e,i,r=this.getValueAtTime(t),s=this.getValueAtTime(t+-.001);if(r.length)for(e=createTypedArray("float32",r.length),i=0;i<r.length;i+=1)e[i]=(s[i]-r[i])/-.001;else e=(s-r)/-.001;return e},getValueAtTime:function(t){return t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastFrame&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastFrame<t?this._cachingAtTime.lastIndex:0,this._cachingAtTime.value=this.interpolateValue(t,this._cachingAtTime),this._cachingAtTime.lastFrame=t),this._cachingAtTime.value},getStaticValueAtTime:function(){return this.pv},setGroupProperty:function(t){this.propertyGroup=t}};function addPropertyDecorator(){function o(t,e,i){if(!this.k||!this.keyframes)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[l.length-1].t;if(h<=p)return this.pv;if(i?s=p-(r=e?Math.abs(p-this.elem.comp.globalData.frameRate*e):Math.max(0,p-this.elem.data.ip)):((!e||e>l.length-1)&&(e=l.length-1),r=p-(s=l[l.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/r)%2!=0)return this.getValueAtTime((r-(h-s)%r+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),m=this.getValueAtTime(p/this.comp.globalData.frameRate,0),c=this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0),d=Math.floor((h-s)/r);if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=(m[a]-f[a])*d+c[a];return o}return(m-f)*d+c}if("continue"===t){var u=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p-.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*((h-p)/this.comp.globalData.frameRate)/5e-4;return o}return u+(h-p)/.001*(u-y)}}return this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0)}function h(t,e,i){if(!this.k)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[0].t;if(p<=h)return this.pv;if(i?s=p+(r=e?Math.abs(this.elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-p)):((!e||e>l.length-1)&&(e=l.length-1),r=(s=l[e].t)-p),"pingpong"===t){if(Math.floor((p-h)/r)%2==0)return this.getValueAtTime(((p-h)%r+p)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var f=this.getValueAtTime(p/this.comp.globalData.frameRate,0),m=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime((r-(p-h)%r+p)/this.comp.globalData.frameRate,0),d=Math.floor((p-h)/r)+1;if(this.pv.length){for(n=(o=new Array(f.length)).length,a=0;a<n;a+=1)o[a]=c[a]-(m[a]-f[a])*d;return o}return c-(m-f)*d}if("continue"===t){var u=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p+.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*(p-h)/.001;return o}return u+(u-y)*(p-h)/.001}}return this.getValueAtTime((r-((p-h)%r+p))/this.comp.globalData.frameRate,0)}function l(t,e){if(!this.k)return this.pv;if(t=.5*(t||.4),(e=Math.floor(e||5))<=1)return this.pv;var i,r,s=this.comp.renderedFrame/this.comp.globalData.frameRate,a=s-t,n=1<e?(s+t-a)/(e-1):1,o=0,h=0;for(i=this.pv.length?createTypedArray("float32",this.pv.length):0;o<e;){if(r=this.getValueAtTime(a+o*n),this.pv.length)for(h=0;h<this.pv.length;h+=1)i[h]+=r[h];else i+=r;o+=1}if(this.pv.length)for(h=0;h<this.pv.length;h+=1)i[h]/=e;else i/=e;return i}var s=TransformPropertyFactory.getTransformProperty;TransformPropertyFactory.getTransformProperty=function(t,e,i){var r=s(t,e,i);return r.dynamicProperties.length?r.getValueAtTime=function(t){this._transformCachingAtTime||(this._transformCachingAtTime={v:new Matrix});var e=this._transformCachingAtTime.v;if(e.cloneFromProps(this.pre.props),this.appliedTransformations<1){var i=this.a.getValueAtTime(t);e.translate(-i[0]*this.a.mult,-i[1]*this.a.mult,i[2]*this.a.mult)}if(this.appliedTransformations<2){var r=this.s.getValueAtTime(t);e.scale(r[0]*this.s.mult,r[1]*this.s.mult,r[2]*this.s.mult)}if(this.sk&&this.appliedTransformations<3){var s=this.sk.getValueAtTime(t),a=this.sa.getValueAtTime(t);e.skewFromAxis(-s*this.sk.mult,a*this.sa.mult)}if(this.r&&this.appliedTransformations<4){var n=this.r.getValueAtTime(t);e.rotate(-n*this.r.mult)}else if(!this.r&&this.appliedTransformations<4){var o=this.rz.getValueAtTime(t),h=this.ry.getValueAtTime(t),l=this.rx.getValueAtTime(t),p=this.or.getValueAtTime(t);e.rotateZ(-o*this.rz.mult).rotateY(h*this.ry.mult).rotateX(l*this.rx.mult).rotateZ(-p[2]*this.or.mult).rotateY(p[1]*this.or.mult).rotateX(p[0]*this.or.mult)}if(this.data.p&&this.data.p.s){var f=this.px.getValueAtTime(t),m=this.py.getValueAtTime(t);if(this.data.p.z){var c=this.pz.getValueAtTime(t);e.translate(f*this.px.mult,m*this.py.mult,-c*this.pz.mult)}else e.translate(f*this.px.mult,m*this.py.mult,0)}else{var d=this.p.getValueAtTime(t);e.translate(d[0]*this.p.mult,d[1]*this.p.mult,-d[2]*this.p.mult)}return e}.bind(r):r.getValueAtTime=function(){return this.v.clone(new Matrix)}.bind(r),r.setGroupProperty=expressionHelpers.setGroupProperty,r};var p=PropertyFactory.getProp;PropertyFactory.getProp=function(t,e,i,r,s){var a=p(t,e,i,r,s);a.kf?a.getValueAtTime=expressionHelpers.getValueAtTime.bind(a):a.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(a),a.setGroupProperty=expressionHelpers.setGroupProperty,a.loopOut=o,a.loopIn=h,a.smooth=l,a.getVelocityAtTime=expressionHelpers.getVelocityAtTime.bind(a),a.getSpeedAtTime=expressionHelpers.getSpeedAtTime.bind(a),a.numKeys=1===e.a?e.k.length:0,a.propertyIndex=e.ix;var n=0;return 0!==i&&(n=createTypedArray("float32",1===e.a?e.k[0].s.length:e.k.length)),a._cachingAtTime={lastFrame:initialDefaultFrame,lastIndex:0,value:n},expressionHelpers.searchExpressions(t,e,a),a.k&&s.addDynamicProperty(a),a};var t=ShapePropertyFactory.getConstructorFunction(),e=ShapePropertyFactory.getKeyframedConstructorFunction();function i(){}i.prototype={vertices:function(t,e){this.k&&this.getValue();var i,r=this.v;void 0!==e&&(r=this.getValueAtTime(e,0));var s=r._length,a=r[t],n=r.v,o=createSizedArray(s);for(i=0;i<s;i+=1)o[i]="i"===t||"o"===t?[a[i][0]-n[i][0],a[i][1]-n[i][1]]:[a[i][0],a[i][1]];return o},points:function(t){return this.vertices("v",t)},inTangents:function(t){return this.vertices("i",t)},outTangents:function(t){return this.vertices("o",t)},isClosed:function(){return this.v.c},pointOnPath:function(t,e){var i=this.v;void 0!==e&&(i=this.getValueAtTime(e,0)),this._segmentsLength||(this._segmentsLength=bez.getSegmentsLength(i));for(var r,s=this._segmentsLength,a=s.lengths,n=s.totalLength*t,o=0,h=a.length,l=0;o<h;){if(l+a[o].addedLength>n){var p=o,f=i.c&&o===h-1?0:o+1,m=(n-l)/a[o].addedLength;r=bez.getPointInSegment(i.v[p],i.v[f],i.o[p],i.i[f],m,a[o]);break}l+=a[o].addedLength,o+=1}return r||(r=i.c?[i.v[0][0],i.v[0][1]]:[i.v[i._length-1][0],i.v[i._length-1][1]]),r},vectorOnPath:function(t,e,i){1==t?t=this.v.c:0==t&&(t=.999);var r=this.pointOnPath(t,e),s=this.pointOnPath(t+.001,e),a=s[0]-r[0],n=s[1]-r[1],o=Math.sqrt(Math.pow(a,2)+Math.pow(n,2));return 0===o?[0,0]:"tangent"===i?[a/o,n/o]:[-n/o,a/o]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([i],t),extendPrototype([i],e),e.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shapePool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),t*=this.elem.globalData.frameRate,(t-=this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime<t?this._caching.lastIndex:0,this._cachingAtTime.lastTime=t,this.interpolateShape(t,this._cachingAtTime.shapeValue,this._cachingAtTime)),this._cachingAtTime.shapeValue},e.prototype.initiateExpression=ExpressionManager.initiateExpression;var n=ShapePropertyFactory.getShapeProp;ShapePropertyFactory.getShapeProp=function(t,e,i,r,s){var a=n(t,e,i,r,s);return a.propertyIndex=e.ix,a.lock=!1,3===i?expressionHelpers.searchExpressions(t,e.pt,a):4===i&&expressionHelpers.searchExpressions(t,e.ks,a),a.k&&t.addDynamicProperty(a),a}}function initialize$1(){addPropertyDecorator()}function addDecorator(){TextProperty.prototype.getExpressionValue=function(t,e){var i=this.calculateExpression(e);if(t.t===i)return t;var r={};return this.copyData(r,t),r.t=i.toString(),r.__complete=!1,r},TextProperty.prototype.searchProperty=function(){var t=this.searchKeyframes(),e=this.searchExpressions();return this.kf=t||e,this.kf},TextProperty.prototype.searchExpressions=function(){return this.data.d.x?(this.calculateExpression=ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this),this.addEffect(this.getExpressionValue.bind(this)),!0):null}}function initialize(){addDecorator()}function SVGComposableEffect(){}SVGComposableEffect.prototype={createMergeNode:function(t,e){var i,r,s=createNS("feMerge");for(s.setAttribute("result",t),r=0;r<e.length;r+=1)(i=createNS("feMergeNode")).setAttribute("in",e[r]),s.appendChild(i),s.appendChild(i);return s}};var linearFilterValue="0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0";function SVGTintFilter(t,e,i,r,s){this.filterManager=e;var a=createNS("feColorMatrix");a.setAttribute("type","matrix"),a.setAttribute("color-interpolation-filters","linearRGB"),a.setAttribute("values",linearFilterValue+" 1 0"),(this.linearFilter=a).setAttribute("result",r+"_tint_1"),t.appendChild(a),(a=createNS("feColorMatrix")).setAttribute("type","matrix"),a.setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),a.setAttribute("result",r+"_tint_2"),t.appendChild(a),this.matrixFilter=a;var n=this.createMergeNode(r,[s,r+"_tint_1",r+"_tint_2"]);t.appendChild(n)}function SVGFillFilter(t,e,i,r){this.filterManager=e;var s=createNS("feColorMatrix");s.setAttribute("type","matrix"),s.setAttribute("color-interpolation-filters","sRGB"),s.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),s.setAttribute("result",r),t.appendChild(s),this.matrixFilter=s}function SVGStrokeEffect(t,e,i){this.initialized=!1,this.filterManager=e,this.elem=i,this.paths=[]}function SVGTritoneFilter(t,e,i,r){this.filterManager=e;var s=createNS("feColorMatrix");s.setAttribute("type","matrix"),s.setAttribute("color-interpolation-filters","linearRGB"),s.setAttribute("values","0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0"),t.appendChild(s);var a=createNS("feComponentTransfer");a.setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("result",r),this.matrixFilter=a;var n=createNS("feFuncR");n.setAttribute("type","table"),a.appendChild(n),this.feFuncR=n;var o=createNS("feFuncG");o.setAttribute("type","table"),a.appendChild(o),this.feFuncG=o;var h=createNS("feFuncB");h.setAttribute("type","table"),a.appendChild(h),this.feFuncB=h,t.appendChild(a)}function SVGProLevelsFilter(t,e,i,r){this.filterManager=e;var s=this.filterManager.effectElements,a=createNS("feComponentTransfer");(s[10].p.k||0!==s[10].p.v||s[11].p.k||1!==s[11].p.v||s[12].p.k||1!==s[12].p.v||s[13].p.k||0!==s[13].p.v||s[14].p.k||1!==s[14].p.v)&&(this.feFuncR=this.createFeFunc("feFuncR",a)),(s[17].p.k||0!==s[17].p.v||s[18].p.k||1!==s[18].p.v||s[19].p.k||1!==s[19].p.v||s[20].p.k||0!==s[20].p.v||s[21].p.k||1!==s[21].p.v)&&(this.feFuncG=this.createFeFunc("feFuncG",a)),(s[24].p.k||0!==s[24].p.v||s[25].p.k||1!==s[25].p.v||s[26].p.k||1!==s[26].p.v||s[27].p.k||0!==s[27].p.v||s[28].p.k||1!==s[28].p.v)&&(this.feFuncB=this.createFeFunc("feFuncB",a)),(s[31].p.k||0!==s[31].p.v||s[32].p.k||1!==s[32].p.v||s[33].p.k||1!==s[33].p.v||s[34].p.k||0!==s[34].p.v||s[35].p.k||1!==s[35].p.v)&&(this.feFuncA=this.createFeFunc("feFuncA",a)),(this.feFuncR||this.feFuncG||this.feFuncB||this.feFuncA)&&(a.setAttribute("color-interpolation-filters","sRGB"),t.appendChild(a)),(s[3].p.k||0!==s[3].p.v||s[4].p.k||1!==s[4].p.v||s[5].p.k||1!==s[5].p.v||s[6].p.k||0!==s[6].p.v||s[7].p.k||1!==s[7].p.v)&&((a=createNS("feComponentTransfer")).setAttribute("color-interpolation-filters","sRGB"),a.setAttribute("result",r),t.appendChild(a),this.feFuncRComposed=this.createFeFunc("feFuncR",a),this.feFuncGComposed=this.createFeFunc("feFuncG",a),this.feFuncBComposed=this.createFeFunc("feFuncB",a))}function SVGDropShadowEffect(t,e,i,r,s){var a=e.container.globalData.renderConfig.filterSize,n=e.data.fs||a;t.setAttribute("x",n.x||a.x),t.setAttribute("y",n.y||a.y),t.setAttribute("width",n.width||a.width),t.setAttribute("height",n.height||a.height),this.filterManager=e;var o=createNS("feGaussianBlur");o.setAttribute("in","SourceAlpha"),o.setAttribute("result",r+"_drop_shadow_1"),o.setAttribute("stdDeviation","0"),this.feGaussianBlur=o,t.appendChild(o);var h=createNS("feOffset");h.setAttribute("dx","25"),h.setAttribute("dy","0"),h.setAttribute("in",r+"_drop_shadow_1"),h.setAttribute("result",r+"_drop_shadow_2"),this.feOffset=h,t.appendChild(h);var l=createNS("feFlood");l.setAttribute("flood-color","#00ff00"),l.setAttribute("flood-opacity","1"),l.setAttribute("result",r+"_drop_shadow_3"),this.feFlood=l,t.appendChild(l);var p=createNS("feComposite");p.setAttribute("in",r+"_drop_shadow_3"),p.setAttribute("in2",r+"_drop_shadow_2"),p.setAttribute("operator","in"),p.setAttribute("result",r+"_drop_shadow_4"),t.appendChild(p);var f=this.createMergeNode(r,[r+"_drop_shadow_4",s]);t.appendChild(f)}extendPrototype([SVGComposableEffect],SVGTintFilter),SVGTintFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=this.filterManager.effectElements[2].p.v/100;this.linearFilter.setAttribute("values",linearFilterValue+" "+r+" 0"),this.matrixFilter.setAttribute("values",i[0]-e[0]+" 0 0 0 "+e[0]+" "+(i[1]-e[1])+" 0 0 0 "+e[1]+" "+(i[2]-e[2])+" 0 0 0 "+e[2]+" 0 0 0 1 0")}},SVGFillFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[2].p.v,i=this.filterManager.effectElements[6].p.v;this.matrixFilter.setAttribute("values","0 0 0 0 "+e[0]+" 0 0 0 0 "+e[1]+" 0 0 0 0 "+e[2]+" 0 0 0 "+i+" 0")}},SVGStrokeEffect.prototype.initialize=function(){var t,e,i,r,s=this.elem.layerElement.children||this.elem.layerElement.childNodes;for(1===this.filterManager.effectElements[1].p.v?(r=this.elem.maskManager.masksProperties.length,i=0):r=(i=this.filterManager.effectElements[0].p.v-1)+1,(e=createNS("g")).setAttribute("fill","none"),e.setAttribute("stroke-linecap","round"),e.setAttribute("stroke-dashoffset",1);i<r;i+=1)t=createNS("path"),e.appendChild(t),this.paths.push({p:t,m:i});if(3===this.filterManager.effectElements[10].p.v){var a=createNS("mask"),n=createElementID();a.setAttribute("id",n),a.setAttribute("mask-type","alpha"),a.appendChild(e),this.elem.globalData.defs.appendChild(a);var o=createNS("g");for(o.setAttribute("mask","url("+getLocationHref()+"#"+n+")");s[0];)o.appendChild(s[0]);this.elem.layerElement.appendChild(o),this.masker=a,e.setAttribute("stroke","#fff")}else if(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v){if(2===this.filterManager.effectElements[10].p.v)for(s=this.elem.layerElement.children||this.elem.layerElement.childNodes;s.length;)this.elem.layerElement.removeChild(s[0]);this.elem.layerElement.appendChild(e),this.elem.layerElement.removeAttribute("mask"),e.setAttribute("stroke","#fff")}this.initialized=!0,this.pathMasker=e},SVGStrokeEffect.prototype.renderFrame=function(t){var e;this.initialized||this.initialize();var i,r,s=this.paths.length;for(e=0;e<s;e+=1)if(-1!==this.paths[e].m&&(i=this.elem.maskManager.viewData[this.paths[e].m],r=this.paths[e].p,(t||this.filterManager._mdf||i.prop._mdf)&&r.setAttribute("d",i.lastPath),t||this.filterManager.effectElements[9].p._mdf||this.filterManager.effectElements[4].p._mdf||this.filterManager.effectElements[7].p._mdf||this.filterManager.effectElements[8].p._mdf||i.prop._mdf)){var a;if(0!==this.filterManager.effectElements[7].p.v||100!==this.filterManager.effectElements[8].p.v){var n=.01*Math.min(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),o=.01*Math.max(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),h=r.getTotalLength();a="0 0 0 "+h*n+" ";var l,p=h*(o-n),f=1+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01,m=Math.floor(p/f);for(l=0;l<m;l+=1)a+="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01+" ";a+="0 "+10*h+" 0 0"}else a="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01;r.setAttribute("stroke-dasharray",a)}if((t||this.filterManager.effectElements[4].p._mdf)&&this.pathMasker.setAttribute("stroke-width",2*this.filterManager.effectElements[4].p.v),(t||this.filterManager.effectElements[6].p._mdf)&&this.pathMasker.setAttribute("opacity",this.filterManager.effectElements[6].p.v),(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v)&&(t||this.filterManager.effectElements[3].p._mdf)){var c=this.filterManager.effectElements[3].p.v;this.pathMasker.setAttribute("stroke","rgb("+bmFloor(255*c[0])+","+bmFloor(255*c[1])+","+bmFloor(255*c[2])+")")}},SVGTritoneFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=this.filterManager.effectElements[2].p.v,s=r[0]+" "+i[0]+" "+e[0],a=r[1]+" "+i[1]+" "+e[1],n=r[2]+" "+i[2]+" "+e[2];this.feFuncR.setAttribute("tableValues",s),this.feFuncG.setAttribute("tableValues",a),this.feFuncB.setAttribute("tableValues",n)}},SVGProLevelsFilter.prototype.createFeFunc=function(t,e){var i=createNS(t);return i.setAttribute("type","table"),e.appendChild(i),i},SVGProLevelsFilter.prototype.getTableValue=function(t,e,i,r,s){for(var a,n,o=0,h=Math.min(t,e),l=Math.max(t,e),p=Array.call(null,{length:256}),f=0,m=s-r,c=e-t;o<=256;)n=(a=o/256)<=h?c<0?s:r:l<=a?c<0?r:s:r+m*Math.pow((a-t)/c,1/i),p[f]=n,f+=1,o+=256/255;return p.join(" ")},SVGProLevelsFilter.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e,i=this.filterManager.effectElements;this.feFuncRComposed&&(t||i[3].p._mdf||i[4].p._mdf||i[5].p._mdf||i[6].p._mdf||i[7].p._mdf)&&(e=this.getTableValue(i[3].p.v,i[4].p.v,i[5].p.v,i[6].p.v,i[7].p.v),this.feFuncRComposed.setAttribute("tableValues",e),this.feFuncGComposed.setAttribute("tableValues",e),this.feFuncBComposed.setAttribute("tableValues",e)),this.feFuncR&&(t||i[10].p._mdf||i[11].p._mdf||i[12].p._mdf||i[13].p._mdf||i[14].p._mdf)&&(e=this.getTableValue(i[10].p.v,i[11].p.v,i[12].p.v,i[13].p.v,i[14].p.v),this.feFuncR.setAttribute("tableValues",e)),this.feFuncG&&(t||i[17].p._mdf||i[18].p._mdf||i[19].p._mdf||i[20].p._mdf||i[21].p._mdf)&&(e=this.getTableValue(i[17].p.v,i[18].p.v,i[19].p.v,i[20].p.v,i[21].p.v),this.feFuncG.setAttribute("tableValues",e)),this.feFuncB&&(t||i[24].p._mdf||i[25].p._mdf||i[26].p._mdf||i[27].p._mdf||i[28].p._mdf)&&(e=this.getTableValue(i[24].p.v,i[25].p.v,i[26].p.v,i[27].p.v,i[28].p.v),this.feFuncB.setAttribute("tableValues",e)),this.feFuncA&&(t||i[31].p._mdf||i[32].p._mdf||i[33].p._mdf||i[34].p._mdf||i[35].p._mdf)&&(e=this.getTableValue(i[31].p.v,i[32].p.v,i[33].p.v,i[34].p.v,i[35].p.v),this.feFuncA.setAttribute("tableValues",e))}},extendPrototype([SVGComposableEffect],SVGDropShadowEffect),SVGDropShadowEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){if((t||this.filterManager.effectElements[4].p._mdf)&&this.feGaussianBlur.setAttribute("stdDeviation",this.filterManager.effectElements[4].p.v/4),t||this.filterManager.effectElements[0].p._mdf){var e=this.filterManager.effectElements[0].p.v;this.feFlood.setAttribute("flood-color",rgbToHex(Math.round(255*e[0]),Math.round(255*e[1]),Math.round(255*e[2])))}if((t||this.filterManager.effectElements[1].p._mdf)&&this.feFlood.setAttribute("flood-opacity",this.filterManager.effectElements[1].p.v/255),t||this.filterManager.effectElements[2].p._mdf||this.filterManager.effectElements[3].p._mdf){var i=this.filterManager.effectElements[3].p.v,r=(this.filterManager.effectElements[2].p.v-90)*degToRads,s=i*Math.cos(r),a=i*Math.sin(r);this.feOffset.setAttribute("dx",s),this.feOffset.setAttribute("dy",a)}}};var _svgMatteSymbols=[];function SVGMatte3Effect(t,e,i){this.initialized=!1,this.filterManager=e,this.filterElem=t,(this.elem=i).matteElement=createNS("g"),i.matteElement.appendChild(i.layerElement),i.matteElement.appendChild(i.transformedElement),i.baseElement=i.matteElement}function SVGGaussianBlurEffect(t,e,i,r){t.setAttribute("x","-100%"),t.setAttribute("y","-100%"),t.setAttribute("width","300%"),t.setAttribute("height","300%"),this.filterManager=e;var s=createNS("feGaussianBlur");s.setAttribute("result",r),t.appendChild(s),this.feGaussianBlur=s}function TransformEffect(){}function SVGTransformEffect(t,e){this.init(e)}function CVTransformEffect(t){this.init(t)}return SVGMatte3Effect.prototype.findSymbol=function(t){for(var e=0,i=_svgMatteSymbols.length;e<i;){if(_svgMatteSymbols[e]===t)return _svgMatteSymbols[e];e+=1}return null},SVGMatte3Effect.prototype.replaceInParent=function(t,e){var i=t.layerElement.parentNode;if(i){for(var r,s=i.children,a=0,n=s.length;a<n&&s[a]!==t.layerElement;)a+=1;a<=n-2&&(r=s[a+1]);var o=createNS("use");o.setAttribute("href","#"+e),r?i.insertBefore(o,r):i.appendChild(o)}},SVGMatte3Effect.prototype.setElementAsMask=function(t,e){if(!this.findSymbol(e)){var i=createElementID(),r=createNS("mask");r.setAttribute("id",e.layerId),r.setAttribute("mask-type","alpha"),_svgMatteSymbols.push(e);var s=t.globalData.defs;s.appendChild(r);var a=createNS("symbol");a.setAttribute("id",i),this.replaceInParent(e,i),a.appendChild(e.layerElement),s.appendChild(a);var n=createNS("use");n.setAttribute("href","#"+i),r.appendChild(n),e.data.hd=!1,e.show()}t.setMatte(e.layerId)},SVGMatte3Effect.prototype.initialize=function(){for(var t=this.filterManager.effectElements[0].p.v,e=this.elem.comp.elements,i=0,r=e.length;i<r;)e[i]&&e[i].data.ind===t&&this.setElementAsMask(this.elem,e[i]),i+=1;this.initialized=!0},SVGMatte3Effect.prototype.renderFrame=function(){this.initialized||this.initialize()},SVGGaussianBlurEffect.prototype.renderFrame=function(t){if(t||this.filterManager._mdf){var e=.3*this.filterManager.effectElements[0].p.v,i=this.filterManager.effectElements[1].p.v,r=3==i?0:e,s=2==i?0:e;this.feGaussianBlur.setAttribute("stdDeviation",r+" "+s);var a=1==this.filterManager.effectElements[2].p.v?"wrap":"duplicate";this.feGaussianBlur.setAttribute("edgeMode",a)}},TransformEffect.prototype.init=function(t){this.effectsManager=t,this.type=effectTypes.TRANSFORM_EFFECT,this.matrix=new Matrix,this.opacity=-1,this._mdf=!1,this._opMdf=!1},TransformEffect.prototype.renderFrame=function(t){if(this._opMdf=!1,this._mdf=!1,t||this.effectsManager._mdf){var e=this.effectsManager.effectElements,i=e[0].p.v,r=e[1].p.v,s=1===e[2].p.v,a=e[3].p.v,n=s?a:e[4].p.v,o=e[5].p.v,h=e[6].p.v,l=e[7].p.v;this.matrix.reset(),this.matrix.translate(-i[0],-i[1],i[2]),this.matrix.scale(.01*n,.01*a,1),this.matrix.rotate(-l*degToRads),this.matrix.skewFromAxis(-o*degToRads,(h+90)*degToRads),this.matrix.translate(r[0],r[1],0),this._mdf=!0,this.opacity!==e[8].p.v&&(this.opacity=e[8].p.v,this._opMdf=!0)}},extendPrototype([TransformEffect],SVGTransformEffect),extendPrototype([TransformEffect],CVTransformEffect),registerRenderer("canvas",CanvasRenderer),registerRenderer("html",HybridRenderer),registerRenderer("svg",SVGRenderer),ShapeModifiers.registerModifier("tm",TrimModifier),ShapeModifiers.registerModifier("pb",PuckerAndBloatModifier),ShapeModifiers.registerModifier("rp",RepeaterModifier),ShapeModifiers.registerModifier("rd",RoundCornersModifier),ShapeModifiers.registerModifier("zz",ZigZagModifier),ShapeModifiers.registerModifier("op",OffsetPathModifier),setExpressionsPlugin(Expressions),setExpressionInterfaces(getInterface),initialize$1(),initialize(),registerEffect$1(20,SVGTintFilter,!0),registerEffect$1(21,SVGFillFilter,!0),registerEffect$1(22,SVGStrokeEffect,!1),registerEffect$1(23,SVGTritoneFilter,!0),registerEffect$1(24,SVGProLevelsFilter,!0),registerEffect$1(25,SVGDropShadowEffect,!0),registerEffect$1(28,SVGMatte3Effect,!1),registerEffect$1(29,SVGGaussianBlurEffect,!0),registerEffect$1(35,SVGTransformEffect,!1),registerEffect(35,CVTransformEffect),lottie},"object"==typeof exports&&"undefined"!=typeof module?module.exports=Z():"function"==typeof define&&define.amd?define(Z):(Y="undefined"!=typeof globalThis?globalThis:Y||self).lottie=Z()),{loadAnimation:loadAnimation}}({});onmessage=function(t){var e=t.data,i=e.type,r=e.payload;if("load"===i)lottieInternal.loadAnimation(r);else if("pause"===i)animations[r.id]&&animations[r.id].animation.pause();else if("play"===i)animations[r.id]&&animations[r.id].animation.play();else if("stop"===i)animations[r.id]&&animations[r.id].animation.stop();else if("setSpeed"===i)animations[r.id]&&animations[r.id].animation.setSpeed(r.value);else if("setDirection"===i)animations[r.id]&&animations[r.id].animation.setDirection(r.value);else if("setLoop"===i)animations[r.id]&&animations[r.id].animation.setLoop(r.value);else if("goToAndPlay"===i)animations[r.id]&&animations[r.id].animation.goToAndPlay(r.value,r.isFrame);else if("goToAndStop"===i)animations[r.id]&&animations[r.id].animation.goToAndStop(r.value,r.isFrame);else if("setSubframe"===i)animations[r.id]&&animations[r.id].animation.setSubframe(r.value);else if("addEventListener"===i){if(animations[r.id]){var s=function(){self.postMessage({type:"event",payload:{id:r.id,callbackId:r.callbackId,argument:arguments[0]}})};animations[r.id].events[r.callbackId]={callback:s},animations[r.id].animation.addEventListener(r.eventName,s)}}else if("removeEventListener"===i){if(animations[r.id]){var a=animations[r.id].events[r.callbackId];animations[r.id].animation.removeEventListener(r.eventName,a)}}else"destroy"===i?animations[r.id]&&(animations[r.id].animation.destroy(),animations[r.id]=null):"resize"===i?animations[r.id]&&animations[r.id].animation.resize(r.width,r.height):"playSegments"===i?animations[r.id]&&animations[r.id].animation.playSegments(r.arr,r.forceFlag):"updateDocumentData"===i&&animations[r.id].animation.updateDocumentData(r.path,r.documentData,r.index)}}function createWorker(t){var e=new Blob(["("+t.toString()+"())"],{type:"text/javascript"}),i=URL.createObjectURL(e);return new Worker(i)}var lottie=function(){"use strict";var l=createWorker(workerContent),i=0,s=0,p={},a={rendererSettings:{}};function o(t,e,i,r){var s;for(var a in s="div"===t.type?document.createElement("div"):document.createElementNS(t.namespace,t.type),t.textContent&&(s.textContent=t.textContent),t.attributes)Object.prototype.hasOwnProperty.call(t.attributes,a)&&("href"===a?s.setAttributeNS("http://www.w3.org/1999/xlink",a,t.attributes[a]):s.setAttribute(a,t.attributes[a]),"id"===a&&(i[t.attributes[a]]=s));for(var n in t.style)Object.prototype.hasOwnProperty.call(t.style,n)&&(s.style[n]=t.style[n]);t.children.forEach(function(t){o(t,s,i)}),r?e.insertBefore(s,r):e.appendChild(s)}function f(t,e){for(var i,r=0;r<t.length;r+=1){var s,a=e[(i=t[r])[1]];if(a)i[2]&&(s=e[i[2]]),o(i[0],a,e,s),t.splice(r,1),r-=1}}function m(t,e){for(var i,r=0;r<e.length;r+=1)i=e[r],t.style[i[0]]=i[1]}function c(t,e){for(var i,r=0;r<e.length;r+=1)i=e[r],t.setAttribute(i[0],i[1])}var e={DOMLoaded:function(t){var e=p[t.id];e._loaded=!0,e.pendingCallbacks.forEach(function(t){e.animInstance.addEventListener(t.eventName,t.callback),"DOMLoaded"===t.eventName&&t.callback()}),e.animInstance.totalFrames=t.totalFrames,e.animInstance.frameRate=t.frameRate,e.animInstance.firstFrame=t.firstFrame,e.animInstance.playDirection=t.playDirection,e.animInstance.currentFrame=t.isSubframeEnabled?t.currentRawFrame:~~t.currentRawFrame,t.timeCompleted!==t.totalFrames&&t.currentFrame>t.timeCompleted&&(e.animInstance.currentFrame=t.timeCompleted)},SVGloaded:function(t){var e=p[t.id],i=e.container,r=e.elements;o(t.tree,i,r)},SVGupdated:function(t){var e,i,r=t.elements,s=p[t.id];if(s){for(var a,n=s.elements,o=0;o<r.length;o+=1){var h=n[(a=r[o]).id];f(a.elements,n),m(h,a.styles),c(h,a.attributes),e=h,(i=a.textContent)&&(e.textContent=i)}s.animInstance.currentFrame=t.currentTime}},CanvasUpdated:function(t){p[t.id].instructionsHandler(t.instructions)},event:function(t){var e=p[t.id];if(e){var i=e.callbacks;i[t.callbackId]&&i[t.callbackId].callback(t.argument)}},playing:function(t){var e=p[t.id];e&&(e.animInstance.isPaused=!1)},paused:function(t){var e=p[t.id];e&&(e.animInstance.isPaused=!0)}};return l.onmessage=function(t){e[t.data.type]&&e[t.data.type](t.data.payload)},{loadAnimation:function(t){var r,o="lottie_animationId_"+(i+=1),h={elements:{},callbacks:{},pendingCallbacks:[],status:"init"},e={id:o,isPaused:!0,pause:function(){l.postMessage({type:"pause",payload:{id:o}})},play:function(){l.postMessage({type:"play",payload:{id:o}})},stop:function(){l.postMessage({type:"stop",payload:{id:o}})},setSpeed:function(t){l.postMessage({type:"setSpeed",payload:{id:o,value:t}})},setDirection:function(t){l.postMessage({type:"setDirection",payload:{id:o,value:t}})},setLoop:function(t){l.postMessage({type:"setLoop",payload:{id:o,value:t}})},goToAndStop:function(t,e){l.postMessage({type:"goToAndStop",payload:{id:o,value:t,isFrame:e}})},goToAndPlay:function(t,e){l.postMessage({type:"goToAndPlay",payload:{id:o,value:t,isFrame:e}})},playSegments:function(t,e){l.postMessage({type:"playSegments",payload:{id:o,arr:t,forceFlag:e}})},setSubframe:function(t){l.postMessage({type:"setSubframe",payload:{id:o,value:t}})},addEventListener:function(t,e){if(h._loaded){var i="callback_"+(s+=1);h.callbacks[i]={eventName:t,callback:e},l.postMessage({type:"addEventListener",payload:{id:o,callbackId:i,eventName:t}})}else h.pendingCallbacks.push({eventName:t,callback:e})},removeEventListener:function(e,i){Object.keys(h.callbacks).forEach(function(t){h.callbacks[t].eventName!==e||h.callbacks[t].callback!==i&&i||(delete h.callbacks[t],l.postMessage({type:"removeEventListener",payload:{id:o,callbackId:t,eventName:e}}))})},destroy:function(){"init"===h.status?h.status="destroyable":(h.status="destroyed",p[o]=null,h.container&&(h.container.innerHTML=""),l.postMessage({type:"destroy",payload:{id:o}}))},resize:function(t,e){var i=window.devicePixelRatio||1;l.postMessage({type:"resize",payload:{id:o,width:t||(h.container?h.container.offsetWidth*i:0),height:e||(h.container?h.container.offsetHeight*i:0)}})},updateDocumentData:function(t,e,i){l.postMessage({type:"updateDocumentData",payload:{id:o,path:t,documentData:e,index:i}})}};return h.animInstance=e,(r=t,new Promise(function(e,t){var i=Object.assign({},a,r);i.animType&&!i.renderer&&(i.renderer=i.animType),i.wrapper&&(i.container||(i.container=i.wrapper),delete i.wrapper),i.animationData?e(i):i.path?fetch(i.path).then(function(t){return t.json()}).then(function(t){i.animationData=t,delete i.path,e(i)}):t()})).then(function(t){if("destroyable"!==h.status){h.status="loaded";var s,a,e=[];if(t.container&&(h.container=t.container,delete t.container),"canvas"===t.renderer){var i=t.rendererSettings.canvas;if(!i){var r=window.devicePixelRatio||1;i=document.createElement("canvas"),h.container.appendChild(i),i.width=(h.container?h.container.offsetWidth:t.animationData.w)*r,i.height=(h.container?h.container.offsetHeight:t.animationData.h)*r,i.style.width="100%",i.style.height="100%"}var n=i;"undefined"==typeof OffscreenCanvas?(h.canvas=i,h.instructionsHandler=(s=i.getContext("2d"),a={beginPath:s.beginPath,closePath:s.closePath,rect:s.rect,clip:s.clip,clearRect:s.clearRect,setTransform:s.setTransform,moveTo:s.moveTo,bezierCurveTo:s.bezierCurveTo,lineTo:s.lineTo,fill:s.fill,save:s.save,restore:s.restore},function(t){for(var e=0;e<t.length;e+=1){var i=t[e],r=a[i.t];r?r.apply(s,i.a):s[i.t]=i.a}})):(i instanceof OffscreenCanvas||(n=i.transferControlToOffscreen(),t.rendererSettings.canvas=n),e.push(n))}p[o]=h,l.postMessage({type:"load",payload:{params:t,id:o}},e)}else h.animInstance.destroy()}),e}}}();
+	function workerContent(){function extendPrototype(t,e){for(var i,r=t.length,s=0;s<r;s+=1)for(var a in i=t[s].prototype)Object.prototype.hasOwnProperty.call(i,a)&&(e.prototype[a]=i[a])}function ProxyElement(t,e){this._state="init",this._isDirty=!1,this._isProxy=!0,this._changedStyles=[],this._changedAttributes=[],this._changedElements=[],this._textContent=null,this.type=t,this.namespace=e,this.children=[],localIdCounter+=1,this.attributes={id:"l_d_"+localIdCounter},this.style=new Style(this)}ProxyElement.prototype={appendChild:function(t){(t.parentNode=this).children.push(t),this._isDirty=!0,this._changedElements.push([t,this.attributes.id])},insertBefore:function(t,e){for(var i=this.children,r=0;r<i.length;r+=1)if(i[r]===e)return i.splice(r,0,t),this._isDirty=!0,void this._changedElements.push([t,this.attributes.id,e.attributes.id]);i.push(e)},setAttribute:function(t,e){this.attributes[t]=e,this._isDirty||(this._isDirty=!0),this._changedAttributes.push(t)},serialize:function(){return{type:this.type,namespace:this.namespace,style:this.style.serialize(),attributes:this.attributes,children:this.children.map(function(t){return t.serialize()}),textContent:this._textContent}},addEventListener:function(t,e){setTimeout(e,1)},setAttributeNS:function(t,e,i){this.attributes[e]=i,this._isDirty||(this._isDirty=!0),this._changedAttributes.push(e)}},Object.defineProperty(ProxyElement.prototype,"textContent",{set:function(t){this._isDirty=!0,this._textContent=t}});var localIdCounter=0,animations={},styleProperties=["width","height","display","transform","opacity","contentVisibility","mix-blend-mode"];function convertArguments(t){for(var e=[],i=t.length,r=0;r<i;r+=1)e.push(t[r]);return e}function Style(t){this.element=t}function CanvasContext(t){this.element=t}Style.prototype={serialize:function(){for(var t={},e=0;e<styleProperties.length;e+=1){var i=styleProperties[e],r="_"+i;r in this&&(t[i]=this[r])}return t}},styleProperties.forEach(function(e){Object.defineProperty(Style.prototype,e,{set:function(t){this.element._isDirty||(this.element._isDirty=!0),this.element._changedStyles.push(e),this["_"+e]=t},get:function(){return this["_"+e]}})}),CanvasContext.prototype={createRadialGradient:function(){var t={t:"rGradient",a:convertArguments(arguments),stops:[]};return this.element.instructions.push(t),{addColorStop:function(){t.stops.push(convertArguments(arguments))}}},createLinearGradient:function(){var t={t:"lGradient",a:convertArguments(arguments),stops:[]};return this.element.instructions.push(t),{addColorStop:function(){t.stops.push(convertArguments(arguments))}}}},Object.defineProperties(CanvasContext.prototype,{canvas:{enumerable:!0,get:function(){return this.element}}});var canvasContextMethods=["fillRect","setTransform","drawImage","beginPath","moveTo","save","restore","fillText","setLineDash","clearRect","clip","rect","stroke","fill","closePath","bezierCurveTo","lineTo"],canvasContextProperties=(canvasContextMethods.forEach(function(t){CanvasContext.prototype[t]=function(){this.element.instructions.push({t:t,a:convertArguments(arguments)})}}),["globalAlpha","strokeStyle","fillStyle","lineCap","lineJoin","lineWidth","miterLimit","lineDashOffset","globalCompositeOperation"]);function CanvasElement(t,e){ProxyElement.call(this,t,e),this.instructions=[],this.width=0,this.height=0,this.context=new CanvasContext(this)}function createElement(t,e){return new("canvas"===e?CanvasElement:ProxyElement)(e,t)}canvasContextProperties.forEach(function(e){Object.defineProperty(CanvasContext.prototype,e,{set:function(t){this.element.instructions.push({t:e,a:t})}})}),CanvasElement.prototype={getContext:function(){return this.context},resetInstructions:function(){this.instructions.length=0}},extendPrototype([ProxyElement],CanvasElement);var window=self,document={createElementNS:function(t,e){return createElement(t,e)},createElement:function(t){return createElement("",t)},getElementsByTagName:function(){return[]},body:createElement("","body"),_isProxy:!0},lottieInternal=function(){function addElementToList(t,e){e.push(t),t._isDirty=!1,t._changedStyles.length=0,t._changedAttributes.length=0,t._changedElements.length=0,t._textContent=null,t.children.forEach(function(t){addElementToList(t,e)})}function addChangedAttributes(t){for(var e,i=t._changedAttributes,r=[],s=0;s<i.length;s+=1)e=i[s],r.push([e,t.attributes[e]]);return r}function addChangedStyles(t){for(var e,i=t._changedStyles,r=[],s=0;s<i.length;s+=1)e=i[s],r.push([e,t.style[e]]);return r}function addChangedElements(t,e){for(var i,r=t._changedElements,s=[],a=0;a<r.length;a+=1)i=r[a],s.push([i[0].serialize(),i[1],i[2]]),addElementToList(i[0],e);return s}function loadAnimation(a){var e,t,i,r,s=a.params,n=[];"svg"===s.renderer?(e=document.createElement("div"),s.container=e):((i=s.rendererSettings.canvas)||((i=document.createElement("canvas")).width=s.animationData.w,i.height=s.animationData.h),r=i.getContext("2d"),s.rendererSettings.context=r),(t=lottie.loadAnimation(s)).addEventListener("error",function(t){console.log(t)}),t.onError=function(t){console.log("ERRORO",t)},t.addEventListener("_play",function(){self.postMessage({type:"playing",payload:{id:a.id}})}),t.addEventListener("_pause",function(){self.postMessage({type:"paused",payload:{id:a.id}})}),"svg"===s.renderer?(t.addEventListener("DOMLoaded",function(){var t=e.serialize();addElementToList(e,n),self.postMessage({type:"SVGloaded",payload:{id:a.id,tree:t.children[0]}})}),t.addEventListener("drawnFrame",function(t){for(var e,i,r=[],s=0;s<n.length;s+=1)(i=n[s])._isDirty&&(e={id:i.attributes.id,styles:addChangedStyles(i),attributes:addChangedAttributes(i),elements:addChangedElements(i,n),textContent:i._textContent||void 0},r.push(e),i._isDirty=!1,i._changedAttributes.length=0,i._changedStyles.length=0,i._changedElements.length=0,i._textContent=null);self.postMessage({type:"SVGupdated",payload:{elements:r,id:a.id,currentTime:t.currentTime}})})):i._isProxy&&t.addEventListener("drawnFrame",function(t){self.postMessage({type:"CanvasUpdated",payload:{instructions:i.instructions,id:a.id,currentTime:t.currentTime}}),i.resetInstructions()}),t.addEventListener("DOMLoaded",function(){self.postMessage({type:"DOMLoaded",payload:{id:a.id,totalFrames:t.totalFrames,frameRate:t.frameRate,firstFrame:t.firstFrame,currentFrame:t.currentFrame,playDirection:t.playDirection,isSubframeEnabled:t.isSubframeEnabled,currentRawFrame:t.currentRawFrame,timeCompleted:t.timeCompleted}})}),animations[a.id]={animation:t,events:{}}}return void 0!==document&&"undefined"!=typeof navigator&&((t,e)=>{"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).lottie=e()})(this,function(){var svgNS="http://www.w3.org/2000/svg",locationHref="",_useWebWorker=!1,initialDefaultFrame=-999999,setWebWorker=function(t){_useWebWorker=!!t},getWebWorker=function(){return _useWebWorker},setLocationHref=function(t){locationHref=t},getLocationHref=function(){return locationHref};function createTag(t){return document.createElement(t)}function extendPrototype(t,e){for(var i,r=t.length,s=0;s<r;s+=1)for(var a in i=t[s].prototype)Object.prototype.hasOwnProperty.call(i,a)&&(e.prototype[a]=i[a])}function getDescriptor(t,e){return Object.getOwnPropertyDescriptor(t,e)}function createProxyFunction(t){function e(){}return e.prototype=t,e}var audioControllerFactory=(()=>{function t(t){this.audios=[],this.audioFactory=t,this._volume=1,this._isMuted=!1}return t.prototype={addAudio:function(t){this.audios.push(t)},pause:function(){for(var t=this.audios.length,e=0;e<t;e+=1)this.audios[e].pause()},resume:function(){for(var t=this.audios.length,e=0;e<t;e+=1)this.audios[e].resume()},setRate:function(t){for(var e=this.audios.length,i=0;i<e;i+=1)this.audios[i].setRate(t)},createAudio:function(t){return this.audioFactory?this.audioFactory(t):window.Howl?new window.Howl({src:[t]}):{isPlaying:!1,play:function(){this.isPlaying=!0},seek:function(){this.isPlaying=!1},playing:function(){},rate:function(){},setVolume:function(){}}},setAudioFactory:function(t){this.audioFactory=t},setVolume:function(t){this._volume=t,this._updateVolume()},mute:function(){this._isMuted=!0,this._updateVolume()},unmute:function(){this._isMuted=!1,this._updateVolume()},getVolume:function(){return this._volume},_updateVolume:function(){for(var t=this.audios.length,e=0;e<t;e+=1)this.audios[e].volume(this._volume*(this._isMuted?0:1))}},function(){return new t}})(),createTypedArray=(()=>{function i(t,e){var i,r=0,s=[];switch(t){case"int16":case"uint8c":i=1;break;default:i=1.1}for(r=0;r<e;r+=1)s.push(i);return s}return"function"==typeof Uint8ClampedArray&&"function"==typeof Float32Array?function(t,e){return"float32"===t?new Float32Array(e):"int16"===t?new Int16Array(e):"uint8c"===t?new Uint8ClampedArray(e):i(t,e)}:i})();function createSizedArray(t){return Array.apply(null,{length:t})}function _typeof$6(t){return(_typeof$6="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var subframeEnabled=!0,expressionsPlugin=null,expressionsInterfaces=null,idPrefix$1="",isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),_shouldRoundValues=!1,bmPow=Math.pow,bmSqrt=Math.sqrt,bmFloor=Math.floor,bmMax=Math.max,bmMin=Math.min,BMMath={};function ProjectInterface$1(){}(()=>{for(var t=["abs","acos","acosh","asin","asinh","atan","atanh","atan2","ceil","cbrt","expm1","clz32","cos","cosh","exp","floor","fround","hypot","imul","log","log1p","log2","log10","max","min","pow","random","round","sign","sin","sinh","sqrt","tan","tanh","trunc","E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"],e=t.length,i=0;i<e;i+=1)BMMath[t[i]]=Math[t[i]]})(),BMMath.random=Math.random,BMMath.abs=function(t){if("object"===_typeof$6(t)&&t.length){for(var e=createSizedArray(t.length),i=t.length,r=0;r<i;r+=1)e[r]=Math.abs(t[r]);return e}return Math.abs(t)};var defaultCurveSegments=150,degToRads=Math.PI/180,roundCorner=.5519;function roundValues(t){_shouldRoundValues=!!t}function bmRnd(t){if(_shouldRoundValues)return Math.round(t)}function styleDiv(t){t.style.position="absolute",t.style.top=0,t.style.left=0,t.style.display="block",t.style.transformOrigin="0 0",t.style.webkitTransformOrigin="0 0",t.style.backfaceVisibility="visible",t.style.webkitBackfaceVisibility="visible",t.style.transformStyle="preserve-3d",t.style.webkitTransformStyle="preserve-3d",t.style.mozTransformStyle="preserve-3d"}function BMEnterFrameEvent(t,e,i,r){this.type=t,this.currentTime=e,this.totalTime=i,this.direction=r<0?-1:1}function BMCompleteEvent(t,e){this.type=t,this.direction=e<0?-1:1}function BMCompleteLoopEvent(t,e,i,r){this.type=t,this.currentLoop=i,this.totalLoops=e,this.direction=r<0?-1:1}function BMSegmentStartEvent(t,e,i){this.type=t,this.firstFrame=e,this.totalFrames=i}function BMDestroyEvent(t,e){this.type=t,this.target=e}function BMRenderFrameErrorEvent(t,e){this.type="renderFrameError",this.nativeError=t,this.currentTime=e}function BMConfigErrorEvent(t){this.type="configError",this.nativeError=t}function BMAnimationConfigErrorEvent(t,e){this.type=t,this.nativeError=e}var createElementID=(()=>{var t=0;return function(){return idPrefix$1+"__lottie_element_"+(t+=1)}})();function HSVtoRGB(t,e,i){var r,s,a,n=Math.floor(6*t),t=6*t-n,o=i*(1-e),h=i*(1-t*e),l=i*(1-(1-t)*e);switch(n%6){case 0:r=i,s=l,a=o;break;case 1:r=h,s=i,a=o;break;case 2:r=o,s=i,a=l;break;case 3:r=o,s=h,a=i;break;case 4:r=l,s=o,a=i;break;case 5:r=i,s=o,a=h}return[r,s,a]}function RGBtoHSV(t,e,i){var r,s=Math.max(t,e,i),a=Math.min(t,e,i),n=s-a,o=0===s?0:n/s,h=s/255;switch(s){case a:r=0;break;case t:r=e-i+n*(e<i?6:0),r/=6*n;break;case e:r=i-t+2*n,r/=6*n;break;case i:r=t-e+4*n,r/=6*n}return[r,o,h]}function addSaturationToRGB(t,e){t=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return t[1]+=e,1<t[1]?t[1]=1:t[1]<=0&&(t[1]=0),HSVtoRGB(t[0],t[1],t[2])}function addBrightnessToRGB(t,e){t=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return t[2]+=e,1<t[2]?t[2]=1:t[2]<0&&(t[2]=0),HSVtoRGB(t[0],t[1],t[2])}function addHueToRGB(t,e){t=RGBtoHSV(255*t[0],255*t[1],255*t[2]);return t[0]+=e/360,1<t[0]?--t[0]:t[0]<0&&(t[0]+=1),HSVtoRGB(t[0],t[1],t[2])}var rgbToHex=(()=>{for(var t,r=[],e=0;e<256;e+=1)t=e.toString(16),r[e]=1===t.length?"0"+t:t;return function(t,e,i){return"#"+r[t=t<0?0:t]+r[e=e<0?0:e]+r[i=i<0?0:i]}})(),setSubframeEnabled=function(t){subframeEnabled=!!t},getSubframeEnabled=function(){return subframeEnabled},setExpressionsPlugin=function(t){expressionsPlugin=t},getExpressionsPlugin=function(){return expressionsPlugin},setExpressionInterfaces=function(t){expressionsInterfaces=t},getExpressionInterfaces=function(){return expressionsInterfaces},setDefaultCurveSegments=function(t){defaultCurveSegments=t},getDefaultCurveSegments=function(){return defaultCurveSegments},setIdPrefix=function(t){idPrefix$1=t},getIdPrefix=function(){return idPrefix$1};function createNS(t){return document.createElementNS(svgNS,t)}function _typeof$5(t){return(_typeof$5="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var dataManager=(()=>{var i,r,s=1,a=[],n={onmessage:function(){},postMessage:function(t){i({data:t})}},o={postMessage:function(t){n.onmessage({data:t})}};function h(){var t,e;r||(t=function(e){function t(){function p(t,e){for(var i,r,s,a=t.length,n=0;n<a;n+=1)if("ks"in(s=t[n])&&!s.completed){if(s.completed=!0,s.hasMask)for(var o=s.masksProperties,h=o.length,l=0;l<h;l+=1)if(o[l].pt.k.i)c(o[l].pt.k);else for(r=o[l].pt.k.length,i=0;i<r;i+=1)o[l].pt.k[i].s&&c(o[l].pt.k[i].s[0]),o[l].pt.k[i].e&&c(o[l].pt.k[i].e[0]);0===s.ty?(s.layers=m(s.refId,e),p(s.layers,e)):4===s.ty?f(s.shapes):5===s.ty&&0===(s=s).t.a.length&&0 in s.t.p}}function m(t,e){t=((t,e)=>{for(var i=0,r=e.length;i<r;){if(e[i].id===t)return e[i];i+=1}return null})(t,e);return t?t.layers.__used?JSON.parse(JSON.stringify(t.layers)):(t.layers.__used=!0,t.layers):null}function f(t){for(var e,i,r=t.length-1;0<=r;--r)if("sh"===t[r].ty)if(t[r].ks.k.i)c(t[r].ks.k);else for(i=t[r].ks.k.length,e=0;e<i;e+=1)t[r].ks.k[e].s&&c(t[r].ks.k[e].s[0]),t[r].ks.k[e].e&&c(t[r].ks.k[e].e[0]);else"gr"===t[r].ty&&f(t[r].it)}function c(t){for(var e=t.i.length,i=0;i<e;i+=1)t.i[i][0]+=t.v[i][0],t.i[i][1]+=t.v[i][1],t.o[i][0]+=t.v[i][0],t.o[i][1]+=t.v[i][1]}function s(t,e){e=e?e.split("."):[100,100,100];return t[0]>e[0]||!(t[0]<e[0])&&(e[1]<t[1]||!(t[1]<e[1])&&e[2]<t[2])}r=[4,4,14];var r,a=function(t){if(s(r,t.v)&&(n(t.layers),t.assets))for(var e=t.assets.length,i=0;i<e;i+=1)t.assets[i].layers&&n(t.assets[i].layers)};function n(t){for(var e,i,r=t.length,s=0;s<r;s+=1)5===t[s].ty&&(e=t[s],i=void 0,i=e.t.d,e.t.d={k:[{s:i,t:0}]})}o=[4,7,99];var o,h,l=function(t){if(t.chars&&!s(o,t.v))for(var e=t.chars.length,i=0;i<e;i+=1){var r=t.chars[i];r.data&&r.data.shapes&&(f(r.data.shapes),r.data.ip=0,r.data.op=99999,r.data.st=0,r.data.sr=1,r.data.ks={p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0}},t.chars[i].t||(r.data.shapes.push({ty:"no"}),r.data.shapes[0].it.push({p:{k:[0,0],a:0},s:{k:[100,100],a:0},a:{k:[0,0],a:0},r:{k:0,a:0},o:{k:100,a:0},sk:{k:0,a:0},sa:{k:0,a:0},ty:"tr"})))}},d=(h=[5,7,15],function(t){if(s(h,t.v)&&(u(t.layers),t.assets))for(var e=t.assets.length,i=0;i<e;i+=1)t.assets[i].layers&&u(t.assets[i].layers)});function u(t){for(var e,i=t.length,r=0;r<i;r+=1)5===t[r].ty&&("number"==typeof(e=(e=t[r]).t.p).a&&(e.a={a:0,k:e.a}),"number"==typeof e.p&&(e.p={a:0,k:e.p}),"number"==typeof e.r)&&(e.r={a:0,k:e.r})}y=[4,1,9];var y,g=function(t){if(s(y,t.v)&&(v(t.layers),t.assets))for(var e=t.assets.length,i=0;i<e;i+=1)t.assets[i].layers&&v(t.assets[i].layers)};function v(t){for(var e=t.length,i=0;i<e;i+=1)4===t[i].ty&&!function t(e){for(var i,r,s=e.length,a=0;a<s;a+=1)if("gr"===e[a].ty)t(e[a].it);else if("fl"===e[a].ty||"st"===e[a].ty)if(e[a].c.k&&e[a].c.k[0].i)for(r=e[a].c.k.length,i=0;i<r;i+=1)e[a].c.k[i].s&&(e[a].c.k[i].s[0]/=255,e[a].c.k[i].s[1]/=255,e[a].c.k[i].s[2]/=255,e[a].c.k[i].s[3]/=255),e[a].c.k[i].e&&(e[a].c.k[i].e[0]/=255,e[a].c.k[i].e[1]/=255,e[a].c.k[i].e[2]/=255,e[a].c.k[i].e[3]/=255);else e[a].c.k[0]/=255,e[a].c.k[1]/=255,e[a].c.k[2]/=255,e[a].c.k[3]/=255}(t[i].shapes)}b=[4,4,18];var b,x=function(t){if(s(b,t.v)&&(P(t.layers),t.assets))for(var e=t.assets.length,i=0;i<e;i+=1)t.assets[i].layers&&P(t.assets[i].layers)};function P(t){for(var e,i,r,s=t.length,a=0;a<s;a+=1){if((e=t[a]).hasMask)for(var n=e.masksProperties,o=n.length,h=0;h<o;h+=1)if(n[h].pt.k.i)n[h].pt.k.c=n[h].cl;else for(r=n[h].pt.k.length,i=0;i<r;i+=1)n[h].pt.k[i].s&&(n[h].pt.k[i].s[0].c=n[h].cl),n[h].pt.k[i].e&&(n[h].pt.k[i].e[0].c=n[h].cl);4===e.ty&&!function t(e){for(var i,r,s=e.length-1;0<=s;--s)if("sh"===e[s].ty)if(e[s].ks.k.i)e[s].ks.k.c=e[s].closed;else for(r=e[s].ks.k.length,i=0;i<r;i+=1)e[s].ks.k[i].s&&(e[s].ks.k[i].s[0].c=e[s].closed),e[s].ks.k[i].e&&(e[s].ks.k[i].e[0].c=e[s].closed);else"gr"===e[s].ty&&t(e[s].it)}(e.shapes)}}var t={};return t.completeData=function(t){if(!t.__complete){g(t),a(t),l(t),d(t),x(t),p(t.layers,t.assets);var e=t.chars,i=t.assets;if(e)for(var r=0,s=e.length,r=0;r<s;r+=1)1===e[r].t&&(e[r].data.layers=m(e[r].data.refId,i),p(e[r].data.layers,i));t.__complete=!0}},t.checkColors=g,t.checkChars=l,t.checkPathProperties=d,t.checkShapes=x,t.completeLayers=p,t}function n(t){var e=t.getResponseHeader("content-type");return e&&"json"===t.responseType&&-1!==e.indexOf("json")||t.response&&"object"===_typeof$5(t.response)?t.response:t.response&&"string"==typeof t.response?JSON.parse(t.response):t.responseText?JSON.parse(t.responseText):null}var i;o.dataManager||(o.dataManager=t()),o.assetLoader||(o.assetLoader={load:function(e,i,t,r){var s,a=new XMLHttpRequest;try{a.responseType="json"}catch(t){}a.onreadystatechange=function(){if(4===a.readyState)if(200===a.status)s=n(a),t(s);else try{s=n(a),t(s)}catch(t){r&&r(t)}};try{a.open(["G","E","T"].join(""),e,!0)}catch(t){a.open(["G","E","T"].join(""),i+"/"+e,!0)}a.send()}}),"loadAnimation"===e.data.type?o.assetLoader.load(e.data.path,e.data.fullPath,function(t){o.dataManager.completeData(t),o.postMessage({id:e.data.id,payload:t,status:"success"})},function(){o.postMessage({id:e.data.id,status:"error"})}):"complete"===e.data.type?(i=e.data.animation,o.dataManager.completeData(i),o.postMessage({id:e.data.id,payload:i,status:"success"})):"loadData"===e.data.type&&o.assetLoader.load(e.data.path,e.data.fullPath,function(t){o.postMessage({id:e.data.id,payload:t,status:"success"})},function(){o.postMessage({id:e.data.id,status:"error"})})},(r=window.Worker&&window.Blob&&getWebWorker()?(e=new Blob(["var _workerSelf = self; self.onmessage = ",t.toString()],{type:"text/javascript"}),e=URL.createObjectURL(e),new Worker(e)):(i=t,n)).onmessage=function(t){var t=t.data,e=t.id,i=a[e];a[e]=null,"success"===t.status?i.onComplete(t.payload):i.onError&&i.onError()})}function l(t,e){var i="processId_"+(s+=1);return a[i]={onComplete:t,onError:e},i}return{loadAnimation:function(t,e,i){h(),e=l(e,i),r.postMessage({type:"loadAnimation",path:t,fullPath:window.location.origin+window.location.pathname,id:e})},loadData:function(t,e,i){h(),e=l(e,i),r.postMessage({type:"loadData",path:t,fullPath:window.location.origin+window.location.pathname,id:e})},completeAnimation:function(t,e,i){h(),e=l(e,i),r.postMessage({type:"complete",animation:t,id:e})}}})(),ImagePreloader=(()=>{(t=createTag("canvas")).width=1,t.height=1,(e=t.getContext("2d")).fillStyle="rgba(0,0,0,0)",e.fillRect(0,0,1,1);var t,e,s=t;function i(){this.loadedAssets+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function r(){this.loadedFootagesCount+=1,this.loadedAssets===this.totalImages&&this.loadedFootagesCount===this.totalFootages&&this.imagesLoadedCb&&this.imagesLoadedCb(null)}function a(t,e,i){var r="";return r=t.e?t.p:e?e+(e=-1!==(e=t.p).indexOf("images/")?e.split("/")[1]:e):(r=i,(r+=t.u||"")+t.p)}function n(){this._imageLoaded=i.bind(this),this._footageLoaded=r.bind(this),this.testImageLoaded=function(t){var e=0,i=setInterval(function(){(t.getBBox().width||500<e)&&(this._imageLoaded(),clearInterval(i)),e+=1}.bind(this),50)}.bind(this),this.createFootageData=function(t){var e={assetData:t},t=a(t,this.assetsPath,this.path);return dataManager.loadData(t,function(t){e.img=t,this._footageLoaded()}.bind(this),function(){e.img={},this._footageLoaded()}.bind(this)),e}.bind(this),this.assetsPath="",this.path="",this.totalImages=0,this.totalFootages=0,this.loadedAssets=0,this.loadedFootagesCount=0,this.imagesLoadedCb=null,this.images=[]}return n.prototype={loadAssets:function(t,e){this.imagesLoadedCb=e;for(var i=t.length,r=0;r<i;r+=1)t[r].layers||(t[r].t&&"seq"!==t[r].t?3===t[r].t&&(this.totalFootages+=1,this.images.push(this.createFootageData(t[r]))):(this.totalImages+=1,this.images.push(this._createImageData(t[r]))))},setAssetsPath:function(t){this.assetsPath=t||""},setPath:function(t){this.path=t||""},loadedImages:function(){return this.totalImages===this.loadedAssets},loadedFootages:function(){return this.totalFootages===this.loadedFootagesCount},destroy:function(){this.imagesLoadedCb=null,this.images.length=0},getAsset:function(t){for(var e=0,i=this.images.length;e<i;){if(this.images[e].assetData===t)return this.images[e].img;e+=1}return null},createImgData:function(t){var e=a(t,this.assetsPath,this.path),i=createTag("img"),r=(i.crossOrigin="anonymous",i.addEventListener("load",this._imageLoaded,!1),i.addEventListener("error",function(){r.img=s,this._imageLoaded()}.bind(this),!1),i.src=e,{img:i,assetData:t});return r},createImageData:function(t){var e=a(t,this.assetsPath,this.path),i=createNS("image"),r=(isSafari?this.testImageLoaded(i):i.addEventListener("load",this._imageLoaded,!1),i.addEventListener("error",function(){r.img=s,this._imageLoaded()}.bind(this),!1),i.setAttributeNS("http://www.w3.org/1999/xlink","href",e),this._elementHelper.append?this._elementHelper.append(i):this._elementHelper.appendChild(i),{img:i,assetData:t});return r},imageLoaded:i,footageLoaded:r,setCacheType:function(t,e){"svg"===t?(this._elementHelper=e,this._createImageData=this.createImageData.bind(this)):this._createImageData=this.createImgData.bind(this)}},n})();function BaseEvent(){}BaseEvent.prototype={triggerEvent:function(t,e){if(this._cbs[t])for(var i=this._cbs[t],r=0;r<i.length;r+=1)i[r](e)},addEventListener:function(t,e){return this._cbs[t]||(this._cbs[t]=[]),this._cbs[t].push(e),function(){this.removeEventListener(t,e)}.bind(this)},removeEventListener:function(t,e){if(e){if(this._cbs[t]){for(var i=0,r=this._cbs[t].length;i<r;)this._cbs[t][i]===e&&(this._cbs[t].splice(i,1),--i,--r),i+=1;this._cbs[t].length||(this._cbs[t]=null)}}else this._cbs[t]=null}};var markerParser=function(e){for(var t=[],i=0;i<e.length;i+=1){var r=e[i],r={time:r.tm,duration:r.dr};try{r.payload=JSON.parse(e[i].cm)}catch(t){try{r.payload=(t=>{for(var e,i=t.split("\r\n"),r={},s=0,a=0;a<i.length;a+=1)2===(e=i[a].split(":")).length&&(r[e[0]]=e[1].trim(),s+=1);if(0===s)throw new Error;return r})(e[i].cm)}catch(t){r.payload={name:e[i].cm}}}t.push(r)}return t},ProjectInterface=(()=>{function e(t){this.compositions.push(t)}return function(){function t(t){for(var e=0,i=this.compositions.length;e<i;){if(this.compositions[e].data&&this.compositions[e].data.nm===t)return this.compositions[e].prepareFrame&&this.compositions[e].data.xt&&this.compositions[e].prepareFrame(this.currentFrame),this.compositions[e].compInterface;e+=1}return null}return t.compositions=[],t.currentFrame=0,t.registerComposition=e,t}})(),renderers={},registerRenderer=function(t,e){renderers[t]=e};function getRenderer(t){return renderers[t]}function getRegisteredRenderer(){if(renderers.canvas)return"canvas";for(var t in renderers)if(renderers[t])return t;return""}function _typeof$4(t){return(_typeof$4="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var AnimationItem=function(){this._cbs=[],this.name="",this.path="",this.isLoaded=!1,this.currentFrame=0,this.currentRawFrame=0,this.firstFrame=0,this.totalFrames=0,this.frameRate=0,this.frameMult=0,this.playSpeed=1,this.playDirection=1,this.playCount=0,this.animationData={},this.assets=[],this.isPaused=!0,this.autoplay=!1,this.loop=!0,this.renderer=null,this.animationID=createElementID(),this.assetsPath="",this.timeCompleted=0,this.segmentPos=0,this.isSubframeEnabled=getSubframeEnabled(),this.segments=[],this._idle=!0,this._completedLoop=!1,this.projectInterface=ProjectInterface(),this.imagePreloader=new ImagePreloader,this.audioController=audioControllerFactory(),this.markers=[],this.configAnimation=this.configAnimation.bind(this),this.onSetupError=this.onSetupError.bind(this),this.onSegmentComplete=this.onSegmentComplete.bind(this),this.drawnFrameEvent=new BMEnterFrameEvent("drawnFrame",0,0,0),this.expressionsPlugin=getExpressionsPlugin()},animationManager=(extendPrototype([BaseEvent],AnimationItem),AnimationItem.prototype.setParams=function(t){(t.wrapper||t.container)&&(this.wrapper=t.wrapper||t.container);var e="svg",i=(t.animType?e=t.animType:t.renderer&&(e=t.renderer),getRenderer(e));this.renderer=new i(this,t.rendererSettings),this.imagePreloader.setCacheType(e,this.renderer.globalData.defs),this.renderer.setProjectInterface(this.projectInterface),this.animType=e,""===t.loop||null==t.loop||!0===t.loop?this.loop=!0:!1===t.loop?this.loop=!1:this.loop=parseInt(t.loop,10),this.autoplay=!("autoplay"in t)||t.autoplay,this.name=t.name||"",this.autoloadSegments=!Object.prototype.hasOwnProperty.call(t,"autoloadSegments")||t.autoloadSegments,this.assetsPath=t.assetsPath,this.initialSegment=t.initialSegment,t.audioFactory&&this.audioController.setAudioFactory(t.audioFactory),t.animationData?this.setupAnimation(t.animationData):t.path&&(-1!==t.path.lastIndexOf("\\")?this.path=t.path.substr(0,t.path.lastIndexOf("\\")+1):this.path=t.path.substr(0,t.path.lastIndexOf("/")+1),this.fileName=t.path.substr(t.path.lastIndexOf("/")+1),this.fileName=this.fileName.substr(0,this.fileName.lastIndexOf(".json")),dataManager.loadAnimation(t.path,this.configAnimation,this.onSetupError))},AnimationItem.prototype.onSetupError=function(){this.trigger("data_failed")},AnimationItem.prototype.setupAnimation=function(t){dataManager.completeAnimation(t,this.configAnimation)},AnimationItem.prototype.setData=function(t,e){var e={wrapper:t,animationData:e=e&&"object"!==_typeof$4(e)?JSON.parse(e):e},t=t.attributes,i=(e.path=t.getNamedItem("data-animation-path")?t.getNamedItem("data-animation-path").value:t.getNamedItem("data-bm-path")?t.getNamedItem("data-bm-path").value:t.getNamedItem("bm-path")?t.getNamedItem("bm-path").value:"",e.animType=t.getNamedItem("data-anim-type")?t.getNamedItem("data-anim-type").value:t.getNamedItem("data-bm-type")?t.getNamedItem("data-bm-type").value:t.getNamedItem("bm-type")?t.getNamedItem("bm-type").value:t.getNamedItem("data-bm-renderer")?t.getNamedItem("data-bm-renderer").value:t.getNamedItem("bm-renderer")?t.getNamedItem("bm-renderer").value:getRegisteredRenderer()||"canvas",t.getNamedItem("data-anim-loop")?t.getNamedItem("data-anim-loop").value:t.getNamedItem("data-bm-loop")?t.getNamedItem("data-bm-loop").value:t.getNamedItem("bm-loop")?t.getNamedItem("bm-loop").value:""),i=("false"===i?e.loop=!1:"true"===i?e.loop=!0:""!==i&&(e.loop=parseInt(i,10)),t.getNamedItem("data-anim-autoplay")?t.getNamedItem("data-anim-autoplay").value:t.getNamedItem("data-bm-autoplay")?t.getNamedItem("data-bm-autoplay").value:!t.getNamedItem("bm-autoplay")||t.getNamedItem("bm-autoplay").value);e.autoplay="false"!==i,e.name=t.getNamedItem("data-name")?t.getNamedItem("data-name").value:t.getNamedItem("data-bm-name")?t.getNamedItem("data-bm-name").value:t.getNamedItem("bm-name")?t.getNamedItem("bm-name").value:"","false"===(t.getNamedItem("data-anim-prerender")?t.getNamedItem("data-anim-prerender").value:t.getNamedItem("data-bm-prerender")?t.getNamedItem("data-bm-prerender").value:t.getNamedItem("bm-prerender")?t.getNamedItem("bm-prerender").value:"")&&(e.prerender=!1),e.path?this.setParams(e):this.trigger("destroy")},AnimationItem.prototype.includeLayers=function(t){t.op>this.animationData.op&&(this.animationData.op=t.op,this.totalFrames=Math.floor(t.op-this.animationData.ip));for(var e,i=this.animationData.layers,r=i.length,s=t.layers,a=s.length,n=0;n<a;n+=1)for(e=0;e<r;){if(i[e].id===s[n].id){i[e]=s[n];break}e+=1}if((t.chars||t.fonts)&&(this.renderer.globalData.fontManager.addChars(t.chars),this.renderer.globalData.fontManager.addFonts(t.fonts,this.renderer.globalData.defs)),t.assets)for(r=t.assets.length,e=0;e<r;e+=1)this.animationData.assets.push(t.assets[e]);this.animationData.__complete=!1,dataManager.completeAnimation(this.animationData,this.onSegmentComplete)},AnimationItem.prototype.onSegmentComplete=function(t){this.animationData=t;t=getExpressionsPlugin();t&&t.initExpressions(this),this.loadNextSegment()},AnimationItem.prototype.loadNextSegment=function(){var t=this.animationData.segments;t&&0!==t.length&&this.autoloadSegments?(t=t.shift(),this.timeCompleted=t.time*this.frameRate,t=this.path+this.fileName+"_"+this.segmentPos+".json",this.segmentPos+=1,dataManager.loadData(t,this.includeLayers.bind(this),function(){this.trigger("data_failed")}.bind(this))):(this.trigger("data_ready"),this.timeCompleted=this.totalFrames)},AnimationItem.prototype.loadSegments=function(){this.animationData.segments||(this.timeCompleted=this.totalFrames),this.loadNextSegment()},AnimationItem.prototype.imagesLoaded=function(){this.trigger("loaded_images"),this.checkLoaded()},AnimationItem.prototype.preloadImages=function(){this.imagePreloader.setAssetsPath(this.assetsPath),this.imagePreloader.setPath(this.path),this.imagePreloader.loadAssets(this.animationData.assets,this.imagesLoaded.bind(this))},AnimationItem.prototype.configAnimation=function(t){if(this.renderer)try{this.animationData=t,this.initialSegment?(this.totalFrames=Math.floor(this.initialSegment[1]-this.initialSegment[0]),this.firstFrame=Math.round(this.initialSegment[0])):(this.totalFrames=Math.floor(this.animationData.op-this.animationData.ip),this.firstFrame=Math.round(this.animationData.ip)),this.renderer.configAnimation(t),t.assets||(t.assets=[]),this.assets=this.animationData.assets,this.frameRate=this.animationData.fr,this.frameMult=this.animationData.fr/1e3,this.renderer.searchExtraCompositions(t.assets),this.markers=markerParser(t.markers||[]),this.trigger("config_ready"),this.preloadImages(),this.loadSegments(),this.updaFrameModifier(),this.waitForFontsLoaded(),this.isPaused&&this.audioController.pause()}catch(t){this.triggerConfigError(t)}},AnimationItem.prototype.waitForFontsLoaded=function(){this.renderer&&(this.renderer.globalData.fontManager.isLoaded?this.checkLoaded():setTimeout(this.waitForFontsLoaded.bind(this),20))},AnimationItem.prototype.checkLoaded=function(){var t;!this.isLoaded&&this.renderer.globalData.fontManager.isLoaded&&(this.imagePreloader.loadedImages()||"canvas"!==this.renderer.rendererType)&&this.imagePreloader.loadedFootages()&&(this.isLoaded=!0,(t=getExpressionsPlugin())&&t.initExpressions(this),this.renderer.initItems(),setTimeout(function(){this.trigger("DOMLoaded")}.bind(this),0),this.gotoFrame(),this.autoplay)&&this.play()},AnimationItem.prototype.resize=function(t,e){this.renderer.updateContainerSize("number"==typeof t?t:void 0,"number"==typeof e?e:void 0)},AnimationItem.prototype.setSubframe=function(t){this.isSubframeEnabled=!!t},AnimationItem.prototype.gotoFrame=function(){this.currentFrame=this.isSubframeEnabled?this.currentRawFrame:~~this.currentRawFrame,this.timeCompleted!==this.totalFrames&&this.currentFrame>this.timeCompleted&&(this.currentFrame=this.timeCompleted),this.trigger("enterFrame"),this.renderFrame(),this.trigger("drawnFrame")},AnimationItem.prototype.renderFrame=function(){if(!1!==this.isLoaded&&this.renderer)try{this.expressionsPlugin&&this.expressionsPlugin.resetFrame(),this.renderer.renderFrame(this.currentFrame+this.firstFrame)}catch(t){this.triggerRenderFrameError(t)}},AnimationItem.prototype.play=function(t){t&&this.name!==t||!0===this.isPaused&&(this.isPaused=!1,this.trigger("_play"),this.audioController.resume(),this._idle)&&(this._idle=!1,this.trigger("_active"))},AnimationItem.prototype.pause=function(t){t&&this.name!==t||!1===this.isPaused&&(this.isPaused=!0,this.trigger("_pause"),this._idle=!0,this.trigger("_idle"),this.audioController.pause())},AnimationItem.prototype.togglePause=function(t){t&&this.name!==t||(!0===this.isPaused?this.play():this.pause())},AnimationItem.prototype.stop=function(t){t&&this.name!==t||(this.pause(),this.playCount=0,this._completedLoop=!1,this.setCurrentRawFrameValue(0))},AnimationItem.prototype.getMarkerData=function(t){for(var e,i=0;i<this.markers.length;i+=1)if((e=this.markers[i]).payload&&e.payload.name===t)return e;return null},AnimationItem.prototype.goToAndStop=function(t,e,i){i&&this.name!==i||(i=Number(t),isNaN(i)?(i=this.getMarkerData(t))&&this.goToAndStop(i.time,!0):e?this.setCurrentRawFrameValue(t):this.setCurrentRawFrameValue(t*this.frameModifier),this.pause())},AnimationItem.prototype.goToAndPlay=function(t,e,i){var r;i&&this.name!==i||(r=Number(t),isNaN(r)?(t=this.getMarkerData(t))&&(t.duration?this.playSegments([t.time,t.time+t.duration],!0):this.goToAndStop(t.time,!0)):this.goToAndStop(r,e,i),this.play())},AnimationItem.prototype.advanceTime=function(t){var e;!0!==this.isPaused&&!1!==this.isLoaded&&(e=!1,(t=this.currentRawFrame+t*this.frameModifier)>=this.totalFrames-1&&0<this.frameModifier?this.loop&&this.playCount!==this.loop?t>=this.totalFrames?(this.playCount+=1,this.checkSegments(t%this.totalFrames)||(this.setCurrentRawFrameValue(t%this.totalFrames),this._completedLoop=!0,this.trigger("loopComplete"))):this.setCurrentRawFrameValue(t):this.checkSegments(t>this.totalFrames?t%this.totalFrames:0)||(e=!0,t=this.totalFrames-1):t<0?this.checkSegments(t%this.totalFrames)||(!this.loop||this.playCount--<=0&&!0!==this.loop?(e=!0,t=0):(this.setCurrentRawFrameValue(this.totalFrames+t%this.totalFrames),this._completedLoop?this.trigger("loopComplete"):this._completedLoop=!0)):this.setCurrentRawFrameValue(t),e)&&(this.setCurrentRawFrameValue(t),this.pause(),this.trigger("complete"))},AnimationItem.prototype.adjustSegment=function(t,e){this.playCount=0,t[1]<t[0]?(0<this.frameModifier&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(-1)),this.totalFrames=t[0]-t[1],this.timeCompleted=this.totalFrames,this.firstFrame=t[1],this.setCurrentRawFrameValue(this.totalFrames-.001-e)):t[1]>t[0]&&(this.frameModifier<0&&(this.playSpeed<0?this.setSpeed(-this.playSpeed):this.setDirection(1)),this.totalFrames=t[1]-t[0],this.timeCompleted=this.totalFrames,this.firstFrame=t[0],this.setCurrentRawFrameValue(.001+e)),this.trigger("segmentStart")},AnimationItem.prototype.setSegment=function(t,e){var i=-1;this.isPaused&&(this.currentRawFrame+this.firstFrame<t?i=t:this.currentRawFrame+this.firstFrame>e&&(i=e-t)),this.firstFrame=t,this.totalFrames=e-t,this.timeCompleted=this.totalFrames,-1!==i&&this.goToAndStop(i,!0)},AnimationItem.prototype.playSegments=function(t,e){if(e&&(this.segments.length=0),"object"===_typeof$4(t[0]))for(var i=t.length,r=0;r<i;r+=1)this.segments.push(t[r]);else this.segments.push(t);this.segments.length&&e&&this.adjustSegment(this.segments.shift(),0),this.isPaused&&this.play()},AnimationItem.prototype.resetSegments=function(t){this.segments.length=0,this.segments.push([this.animationData.ip,this.animationData.op]),t&&this.checkSegments(0)},AnimationItem.prototype.checkSegments=function(t){return!!this.segments.length&&(this.adjustSegment(this.segments.shift(),t),!0)},AnimationItem.prototype.destroy=function(t){t&&this.name!==t||!this.renderer||(this.renderer.destroy(),this.imagePreloader.destroy(),this.trigger("destroy"),this._cbs=null,this.onEnterFrame=null,this.onLoopComplete=null,this.onComplete=null,this.onSegmentStart=null,this.onDestroy=null,this.renderer=null,this.expressionsPlugin=null,this.imagePreloader=null,this.projectInterface=null)},AnimationItem.prototype.setCurrentRawFrameValue=function(t){this.currentRawFrame=t,this.gotoFrame()},AnimationItem.prototype.setSpeed=function(t){this.playSpeed=t,this.updaFrameModifier()},AnimationItem.prototype.setDirection=function(t){this.playDirection=t<0?-1:1,this.updaFrameModifier()},AnimationItem.prototype.setLoop=function(t){this.loop=t},AnimationItem.prototype.setVolume=function(t,e){e&&this.name!==e||this.audioController.setVolume(t)},AnimationItem.prototype.getVolume=function(){return this.audioController.getVolume()},AnimationItem.prototype.mute=function(t){t&&this.name!==t||this.audioController.mute()},AnimationItem.prototype.unmute=function(t){t&&this.name!==t||this.audioController.unmute()},AnimationItem.prototype.updaFrameModifier=function(){this.frameModifier=this.frameMult*this.playSpeed*this.playDirection,this.audioController.setRate(this.playSpeed*this.playDirection)},AnimationItem.prototype.getPath=function(){return this.path},AnimationItem.prototype.getAssetsPath=function(t){var e,i="";return i=t.e?t.p:this.assetsPath?(-1!==(e=t.p).indexOf("images/")&&(e=e.split("/")[1]),this.assetsPath+e):(i=this.path,(i+=t.u||"")+t.p)},AnimationItem.prototype.getAssetData=function(t){for(var e=0,i=this.assets.length;e<i;){if(t===this.assets[e].id)return this.assets[e];e+=1}return null},AnimationItem.prototype.hide=function(){this.renderer.hide()},AnimationItem.prototype.show=function(){this.renderer.show()},AnimationItem.prototype.getDuration=function(t){return t?this.totalFrames:this.totalFrames/this.frameRate},AnimationItem.prototype.updateDocumentData=function(t,e,i){try{this.renderer.getElementByPath(t).updateDocumentData(e,i)}catch(t){}},AnimationItem.prototype.trigger=function(t){if(this._cbs&&this._cbs[t])switch(t){case"enterFrame":this.triggerEvent(t,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameModifier));break;case"drawnFrame":this.drawnFrameEvent.currentTime=this.currentFrame,this.drawnFrameEvent.totalTime=this.totalFrames,this.drawnFrameEvent.direction=this.frameModifier,this.triggerEvent(t,this.drawnFrameEvent);break;case"loopComplete":this.triggerEvent(t,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult));break;case"complete":this.triggerEvent(t,new BMCompleteEvent(t,this.frameMult));break;case"segmentStart":this.triggerEvent(t,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames));break;case"destroy":this.triggerEvent(t,new BMDestroyEvent(t,this));break;default:this.triggerEvent(t)}"enterFrame"===t&&this.onEnterFrame&&this.onEnterFrame.call(this,new BMEnterFrameEvent(t,this.currentFrame,this.totalFrames,this.frameMult)),"loopComplete"===t&&this.onLoopComplete&&this.onLoopComplete.call(this,new BMCompleteLoopEvent(t,this.loop,this.playCount,this.frameMult)),"complete"===t&&this.onComplete&&this.onComplete.call(this,new BMCompleteEvent(t,this.frameMult)),"segmentStart"===t&&this.onSegmentStart&&this.onSegmentStart.call(this,new BMSegmentStartEvent(t,this.firstFrame,this.totalFrames)),"destroy"===t&&this.onDestroy&&this.onDestroy.call(this,new BMDestroyEvent(t,this))},AnimationItem.prototype.triggerRenderFrameError=function(t){t=new BMRenderFrameErrorEvent(t,this.currentFrame);this.triggerEvent("error",t),this.onError&&this.onError.call(this,t)},AnimationItem.prototype.triggerConfigError=function(t){t=new BMConfigErrorEvent(t,this.currentFrame);this.triggerEvent("error",t),this.onError&&this.onError.call(this,t)},(()=>{var t={},s=[],r=0,a=0,n=0,o=!0,h=!1;function i(t){for(var e=0,i=t.target;e<a;)s[e].animation===i&&(s.splice(e,1),--e,--a,i.isPaused||m()),e+=1}function l(t,e){if(!t)return null;for(var i=0;i<a;){if(s[i].elem===t&&null!==s[i].elem)return s[i].animation;i+=1}var r=new AnimationItem;return f(r,t),r.setData(t,e),r}function p(){n+=1,d()}function m(){--n}function f(t,e){t.addEventListener("destroy",i),t.addEventListener("_active",p),t.addEventListener("_idle",m),s.push({elem:e,animation:t}),a+=1}function c(t){for(var e=t-r,i=0;i<a;i+=1)s[i].animation.advanceTime(e);r=t,n&&!h?window.requestAnimationFrame(c):o=!0}function e(t){r=t,window.requestAnimationFrame(c)}function d(){!h&&n&&o&&(window.requestAnimationFrame(e),o=!1)}return t.registerAnimation=l,t.loadAnimation=function(t){var e=new AnimationItem;return f(e,null),e.setParams(t),e},t.setSpeed=function(t,e){for(var i=0;i<a;i+=1)s[i].animation.setSpeed(t,e)},t.setDirection=function(t,e){for(var i=0;i<a;i+=1)s[i].animation.setDirection(t,e)},t.play=function(t){for(var e=0;e<a;e+=1)s[e].animation.play(t)},t.pause=function(t){for(var e=0;e<a;e+=1)s[e].animation.pause(t)},t.stop=function(t){for(var e=0;e<a;e+=1)s[e].animation.stop(t)},t.togglePause=function(t){for(var e=0;e<a;e+=1)s[e].animation.togglePause(t)},t.searchAnimations=function(t,e,i){for(var r,s=[].concat([].slice.call(document.getElementsByClassName("lottie")),[].slice.call(document.getElementsByClassName("bodymovin"))),a=s.length,n=0;n<a;n+=1)i&&s[n].setAttribute("data-bm-type",i),l(s[n],t);e&&0===a&&(i=i||"svg",(e=document.getElementsByTagName("body")[0]).innerText="",(r=createTag("div")).style.width="100%",r.style.height="100%",r.setAttribute("data-bm-type",i),e.appendChild(r),l(r,t))},t.resize=function(){for(var t=0;t<a;t+=1)s[t].animation.resize()},t.goToAndStop=function(t,e,i){for(var r=0;r<a;r+=1)s[r].animation.goToAndStop(t,e,i)},t.destroy=function(t){for(var e=a-1;0<=e;--e)s[e].animation.destroy(t)},t.freeze=function(){h=!0},t.unfreeze=function(){h=!1,d()},t.setVolume=function(t,e){for(var i=0;i<a;i+=1)s[i].animation.setVolume(t,e)},t.mute=function(t){for(var e=0;e<a;e+=1)s[e].animation.mute(t)},t.unmute=function(t){for(var e=0;e<a;e+=1)s[e].animation.unmute(t)},t.getRegisteredAnimations=function(){for(var t=s.length,e=[],i=0;i<t;i+=1)e.push(s[i].animation);return e},t})()),BezierFactory=(()=>{var t={getBezierEasing:function(t,e,i,r,s){s=s||("bez_"+t+"_"+e+"_"+i+"_"+r).replace(/\./g,"p");if(a[s])return a[s];t=new n([t,e,i,r]);return a[s]=t}},a={},S=4,C=1e-7,_=10,A=11,T=1/(A-1),e="function"==typeof Float32Array;function r(t,e){return 1-3*e+3*t}function M(t,e,i){return((r(e,i)*t+(3*i-6*e))*t+3*e)*t}function k(t,e,i){return 3*r(e,i)*t*t+2*(3*i-6*e)*t+3*e}function n(t){this._p=t,this._mSampleValues=new(e?Float32Array:Array)(A),this._precomputed=!1,this.get=this.get.bind(this)}return n.prototype={get:function(t){var e=this._p[0],i=this._p[1],r=this._p[2],s=this._p[3];return this._precomputed||this._precompute(),e===i&&r===s?t:0===t?0:1===t?1:M(this._getTForX(t),i,s)},_precompute:function(){var t=this._p[0],e=this._p[1],i=this._p[2],r=this._p[3];this._precomputed=!0,t===e&&i===r||this._calcSampleValues()},_calcSampleValues:function(){for(var t=this._p[0],e=this._p[2],i=0;i<A;++i)this._mSampleValues[i]=M(i*T,t,e)},_getTForX:function(t){for(var e=this._p[0],i=this._p[2],r=this._mSampleValues,s=0,a=1,n=A-1;a!==n&&r[a]<=t;++a)s+=T;var o=s+(t-r[--a])/(r[a+1]-r[a])*T,h=k(o,e,i);if(.001<=h){for(var l=t,p=o,m=e,f=i,c=0;c<S;++c){var d=k(p,m,f);if(0===d)return p;p-=(M(p,m,f)-l)/d}return p}if(0===h)return o;for(var u,y,g=t,v=s,b=s+T,x=e,P=i,E=0;0<(u=M(y=v+(b-v)/2,x,P)-g)?b=y:v=y,Math.abs(u)>C&&++E<_;);return y}},t})(),pooling={double:function(t){return t.concat(createSizedArray(t.length))}},poolFactory=function(t,e,i){var r=0,s=t,a=createSizedArray(s);return{newElement:function(){var t;t=r?a[--r]:e();return t},release:function(t){r===s&&(a=pooling.double(a),s*=2);i&&i(t);a[r]=t,r+=1}}},bezierLengthPool=poolFactory(8,function(){return{addedLength:0,percents:createTypedArray("float32",getDefaultCurveSegments()),lengths:createTypedArray("float32",getDefaultCurveSegments())}}),segmentsLengthPool=poolFactory(8,function(){return{lengths:[],totalLength:0}},function(t){for(var e=t.lengths.length,i=0;i<e;i+=1)bezierLengthPool.release(t.lengths[i]);t.lengths.length=0});function bezFunction(){var A=Math;function y(t,e,i,r,s,a){s=t*r+e*s+i*a-s*r-a*t-i*e;return-.001<s&&s<.001}var p=function(t,e,i,r){for(var s,a,n,o,h=getDefaultCurveSegments(),l=0,p=[],m=[],f=bezierLengthPool.newElement(),c=i.length,d=0;d<h;d+=1){for(n=d/(h-1),s=o=0;s<c;s+=1)a=bmPow(1-n,3)*t[s]+3*bmPow(1-n,2)*n*i[s]+3*(1-n)*bmPow(n,2)*r[s]+bmPow(n,3)*e[s],p[s]=a,null!==m[s]&&(o+=bmPow(p[s]-m[s],2)),m[s]=p[s];o&&(l+=o=bmSqrt(o)),f.percents[d]=n,f.lengths[d]=l}return f.addedLength=l,f};function g(t){this.segmentLength=0,this.points=new Array(t)}function v(t,e){this.partialLength=t,this.point=e}function t(t,e,i,r){var s=(t[0]+"_"+t[1]+"_"+e[0]+"_"+e[1]+"_"+i[0]+"_"+i[1]+"_"+r[0]+"_"+r[1]).replace(/\./g,"p");if(!b[s]){for(var a,n,o,h,l,p=getDefaultCurveSegments(),m=0,f=null,c=new g(p=2===t.length&&(t[0]!==e[0]||t[1]!==e[1])&&y(t[0],t[1],e[0],e[1],t[0]+i[0],t[1]+i[1])&&y(t[0],t[1],e[0],e[1],e[0]+r[0],e[1]+r[1])?2:p),d=i.length,u=0;u<p;u+=1){for(l=createSizedArray(d),o=u/(p-1),a=h=0;a<d;a+=1)n=bmPow(1-o,3)*t[a]+3*bmPow(1-o,2)*o*(t[a]+i[a])+3*(1-o)*bmPow(o,2)*(e[a]+r[a])+bmPow(o,3)*e[a],l[a]=n,null!==f&&(h+=bmPow(l[a]-f[a],2));m+=h=bmSqrt(h),c.points[u]=new v(h,l),f=l}c.segmentLength=m,b[s]=c}return b[s]}var b;b={};function T(t,e){var i=e.percents,r=e.lengths,s=i.length,a=bmFloor((s-1)*t),n=t*e.addedLength,o=0;if(a===s-1||0===a||n===r[a])return i[a];for(var h=r[a]>n?-1:1,l=!0;l;)if(r[a]<=n&&r[a+1]>n?(o=(n-r[a])/(r[a+1]-r[a]),l=!1):a+=h,a<0||s-1<=a){if(a===s-1)return i[a];l=!1}return i[a]+(i[a+1]-i[a])*o}var M=createTypedArray("float32",8);return{getSegmentsLength:function(t){for(var e=segmentsLengthPool.newElement(),i=t.c,r=t.v,s=t.o,a=t.i,n=t._length,o=e.lengths,h=0,l=0;l<n-1;l+=1)o[l]=p(r[l],r[l+1],s[l],a[l+1]),h+=o[l].addedLength;return i&&n&&(o[l]=p(r[l],r[0],s[l],a[0]),h+=o[l].addedLength),e.totalLength=h,e},getNewSegment:function(t,e,i,r,s,a,n){s<0?s=0:1<s&&(s=1);for(var s=T(s,n),a=T(a=1<a?1:a,n),o=t.length,h=1-a,l=(n=1-s)*n*n,p=s*n*n*3,m=s*s*n*3,f=s*s*s,c=n*n*h,d=s*n*h+n*s*h+n*n*a,u=s*s*h+n*s*a+s*n*a,y=s*s*a,g=n*h*h,v=s*h*h+n*a*h+n*h*a,b=s*a*h+n*a*a+s*h*a,x=s*a*a,P=h*h*h,E=a*h*h+h*a*h+h*h*a,S=a*a*h+h*a*a+a*h*a,C=a*a*a,_=0;_<o;_+=1)M[4*_]=A.round(1e3*(l*t[_]+p*i[_]+m*r[_]+f*e[_]))/1e3,M[4*_+1]=A.round(1e3*(c*t[_]+d*i[_]+u*r[_]+y*e[_]))/1e3,M[4*_+2]=A.round(1e3*(g*t[_]+v*i[_]+b*r[_]+x*e[_]))/1e3,M[4*_+3]=A.round(1e3*(P*t[_]+E*i[_]+S*r[_]+C*e[_]))/1e3;return M},getPointInSegment:function(t,e,i,r,s,a){return s=T(s,a),a=1-s,[A.round(1e3*(a*a*a*t[0]+(s*a*a+a*s*a+a*a*s)*i[0]+(s*s*a+a*s*s+s*a*s)*r[0]+s*s*s*e[0]))/1e3,A.round(1e3*(a*a*a*t[1]+(s*a*a+a*s*a+a*a*s)*i[1]+(s*s*a+a*s*s+s*a*s)*r[1]+s*s*s*e[1]))/1e3]},buildBezierData:t,pointOnLine2D:y,pointOnLine3D:function(t,e,i,r,s,a,n,o,h){var l;return 0===i&&0===a&&0===h?y(t,e,r,s,n,o):(l=A.sqrt(A.pow(r-t,2)+A.pow(s-e,2)+A.pow(a-i,2)),t=A.sqrt(A.pow(n-t,2)+A.pow(o-e,2)+A.pow(h-i,2)),e=A.sqrt(A.pow(n-r,2)+A.pow(o-s,2)+A.pow(h-a,2)),-1e-4<(i=t<l?e<l?l-t-e:e-t-l:t<e?e-t-l:t-l-e)&&i<1e-4)}}}var bez=bezFunction(),initFrame=initialDefaultFrame,mathAbs=Math.abs;function interpolateValue(t,e){for(var i,r,s,a,n=this.offsetTime,o=("multidimensional"===this.propType&&(i=createTypedArray("float32",this.pv.length)),e.lastIndex),h=o,l=this.keyframes.length-1,p=!0;p;){if(r=this.keyframes[h],s=this.keyframes[h+1],h===l-1&&t>=s.t-n){r.h&&(r=s),o=0;break}if(s.t-n>t){o=h;break}h<l-1?h+=1:(o=0,p=!1)}var m=this.keyframesMetadata[h]||{},f=s.t-n,c=r.t-n;if(r.to){m.bezierData||(m.bezierData=bez.buildBezierData(r.s,s.s||r.e,r.to,r.ti));var d=m.bezierData;if(f<=t||t<c)for(var u=f<=t?d.points.length-1:0,y=d.points[u].point.length,g=0;g<y;g+=1)i[g]=d.points[u].point[g];else{m.__fnct?a=m.__fnct:(a=BezierFactory.getBezierEasing(r.o.x,r.o.y,r.i.x,r.i.y,r.n).get,m.__fnct=a);for(var v,b=a((t-c)/(f-c)),x=d.segmentLength*b,P=e.lastFrame<t&&e._lastKeyframeIndex===h?e._lastAddedLength:0,E=e.lastFrame<t&&e._lastKeyframeIndex===h?e._lastPoint:0,p=!0,S=d.points.length;p;){if(P+=d.points[E].partialLength,0==x||0===b||E===d.points.length-1){for(y=d.points[E].point.length,g=0;g<y;g+=1)i[g]=d.points[E].point[g];break}if(P<=x&&x<P+d.points[E+1].partialLength){for(v=(x-P)/d.points[E+1].partialLength,y=d.points[E].point.length,g=0;g<y;g+=1)i[g]=d.points[E].point[g]+(d.points[E+1].point[g]-d.points[E].point[g])*v;break}E<S-1?E+=1:p=!1}e._lastPoint=E,e._lastAddedLength=P-d.points[E].partialLength,e._lastKeyframeIndex=h}}else{var C,_,A,T,M,l=r.s.length,k=s.s||r.e;if(this.sh&&1!==r.h)f<=t?(i[0]=k[0],i[1]=k[1],i[2]=k[2]):t<=c?(i[0]=r.s[0],i[1]=r.s[1],i[2]=r.s[2]):quaternionToEuler(i,slerp(createQuaternion(r.s),createQuaternion(k),(t-c)/(f-c)));else for(h=0;h<l;h+=1)1!==r.h&&(b=f<=t?1:t<c?0:(r.o.x.constructor===Array?(m.__fnct||(m.__fnct=[]),m.__fnct[h]?a=m.__fnct[h]:(C=void 0===r.o.x[h]?r.o.x[0]:r.o.x[h],_=void 0===r.o.y[h]?r.o.y[0]:r.o.y[h],A=void 0===r.i.x[h]?r.i.x[0]:r.i.x[h],T=void 0===r.i.y[h]?r.i.y[0]:r.i.y[h],a=BezierFactory.getBezierEasing(C,_,A,T).get,m.__fnct[h]=a)):m.__fnct?a=m.__fnct:(C=r.o.x,_=r.o.y,A=r.i.x,T=r.i.y,a=BezierFactory.getBezierEasing(C,_,A,T).get,r.keyframeMetadata=a),a((t-c)/(f-c)))),k=s.s||r.e,M=1===r.h?r.s[h]:r.s[h]+(k[h]-r.s[h])*b,"multidimensional"===this.propType?i[h]=M:i=M}return e.lastIndex=o,i}function slerp(t,e,i){var r,s,a=[],n=t[0],o=t[1],h=t[2],t=t[3],l=e[0],p=e[1],m=e[2],e=e[3],f=n*l+o*p+h*m+t*e;return f<0&&(f=-f,l=-l,p=-p,m=-m,e=-e),f=1e-6<1-f?(f=Math.acos(f),r=Math.sin(f),s=Math.sin((1-i)*f)/r,Math.sin(i*f)/r):(s=1-i,i),a[0]=s*n+f*l,a[1]=s*o+f*p,a[2]=s*h+f*m,a[3]=s*t+f*e,a}function quaternionToEuler(t,e){var i=e[0],r=e[1],s=e[2],e=e[3],a=Math.atan2(2*r*e-2*i*s,1-2*r*r-2*s*s),n=Math.asin(2*i*r+2*s*e),e=Math.atan2(2*i*e-2*r*s,1-2*i*i-2*s*s);t[0]=a/degToRads,t[1]=n/degToRads,t[2]=e/degToRads}function createQuaternion(t){var e=t[0]*degToRads,i=t[1]*degToRads,t=t[2]*degToRads,r=Math.cos(e/2),s=Math.cos(i/2),a=Math.cos(t/2),e=Math.sin(e/2),i=Math.sin(i/2),t=Math.sin(t/2);return[e*i*a+r*s*t,e*s*a+r*i*t,r*i*a-e*s*t,r*s*a-e*i*t]}function getValueAtCurrentTime(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime;return t===this._caching.lastFrame||this._caching.lastFrame!==initFrame&&(this._caching.lastFrame>=i&&i<=t||this._caching.lastFrame<e&&t<e)||(this._caching.lastFrame>=t&&(this._caching._lastKeyframeIndex=-1,this._caching.lastIndex=0),i=this.interpolateValue(t,this._caching),this.pv=i),this._caching.lastFrame=t,this.pv}function setVValue(t){var e;if("unidimensional"===this.propType)e=t*this.mult,1e-5<mathAbs(this.v-e)&&(this.v=e,this._mdf=!0);else for(var i=0,r=this.v.length;i<r;)e=t[i]*this.mult,1e-5<mathAbs(this.v[i]-e)&&(this.v[i]=e,this._mdf=!0),i+=1}function processEffectsSequence(){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{this.lock=!0,this._mdf=this._isFirstFrame;for(var t=this.effectsSequence.length,e=this.kf?this.pv:this.data.k,i=0;i<t;i+=1)e=this.effectsSequence[i](e);this.setVValue(e),this._isFirstFrame=!1,this.lock=!1,this.frameId=this.elem.globalData.frameId}}function addEffect(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function ValueProperty(t,e,i,r){this.propType="unidimensional",this.mult=i||1,this.data=e,this.v=i?e.k*i:e.k,this.pv=e.k,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.vel=0,this.effectsSequence=[],this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function MultiDimensionalProperty(t,e,i,r){this.propType="multidimensional",this.mult=i||1,this.data=e,this._mdf=!1,this.elem=t,this.container=r,this.comp=t.comp,this.k=!1,this.kf=!1,this.frameId=-1;var s,a=e.k.length;for(this.v=createTypedArray("float32",a),this.pv=createTypedArray("float32",a),this.vel=createTypedArray("float32",a),s=0;s<a;s+=1)this.v[s]=e.k[s]*this.mult,this.pv[s]=e.k[s];this._isFirstFrame=!0,this.effectsSequence=[],this.getValue=processEffectsSequence,this.setVValue=setVValue,this.addEffect=addEffect}function KeyframedValueProperty(t,e,i,r){this.propType="unidimensional",this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.frameId=-1,this._caching={lastFrame:initFrame,lastIndex:0,value:0,_lastKeyframeIndex:-1},this.k=!0,this.kf=!0,this.data=e,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.v=initFrame,this.pv=initFrame,this._isFirstFrame=!0,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.addEffect=addEffect}function KeyframedMultidimensionalProperty(t,e,i,r){this.propType="multidimensional";for(var s,a,n,o,h=e.k.length,l=0;l<h-1;l+=1)e.k[l].to&&e.k[l].s&&e.k[l+1]&&e.k[l+1].s&&(s=e.k[l].s,a=e.k[l+1].s,n=e.k[l].to,o=e.k[l].ti,(2===s.length&&(s[0]!==a[0]||s[1]!==a[1])&&bez.pointOnLine2D(s[0],s[1],a[0],a[1],s[0]+n[0],s[1]+n[1])&&bez.pointOnLine2D(s[0],s[1],a[0],a[1],a[0]+o[0],a[1]+o[1])||3===s.length&&(s[0]!==a[0]||s[1]!==a[1]||s[2]!==a[2])&&bez.pointOnLine3D(s[0],s[1],s[2],a[0],a[1],a[2],s[0]+n[0],s[1]+n[1],s[2]+n[2])&&bez.pointOnLine3D(s[0],s[1],s[2],a[0],a[1],a[2],a[0]+o[0],a[1]+o[1],a[2]+o[2]))&&(e.k[l].to=null,e.k[l].ti=null),s[0]===a[0])&&s[1]===a[1]&&0===n[0]&&0===n[1]&&0===o[0]&&0===o[1]&&(2===s.length||s[2]===a[2]&&0===n[2]&&0===o[2])&&(e.k[l].to=null,e.k[l].ti=null);this.effectsSequence=[getValueAtCurrentTime.bind(this)],this.data=e,this.keyframes=e.k,this.keyframesMetadata=[],this.offsetTime=t.data.st,this.k=!0,this.kf=!0,this._isFirstFrame=!0,this.mult=i||1,this.elem=t,this.container=r,this.comp=t.comp,this.getValue=processEffectsSequence,this.setVValue=setVValue,this.interpolateValue=interpolateValue,this.frameId=-1;var p=e.k[0].s.length;for(this.v=createTypedArray("float32",p),this.pv=createTypedArray("float32",p),l=0;l<p;l+=1)this.v[l]=initFrame,this.pv[l]=initFrame;this._caching={lastFrame:initFrame,lastIndex:0,value:createTypedArray("float32",p)},this.addEffect=addEffect}var PropertyFactory={getProp:function(t,e,i,r,s){var a;if((e=e.sid?t.globalData.slotManager.getProp(e):e).k.length)if("number"==typeof e.k[0])a=new MultiDimensionalProperty(t,e,r,s);else switch(i){case 0:a=new KeyframedValueProperty(t,e,r,s);break;case 1:a=new KeyframedMultidimensionalProperty(t,e,r,s)}else a=new ValueProperty(t,e,r,s);return a.effectsSequence.length&&s.addDynamicProperty(a),a}};function DynamicPropertyContainer(){}DynamicPropertyContainer.prototype={addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&(this.dynamicProperties.push(t),this.container.addDynamicProperty(this),this._isAnimated=!0)},iterateDynamicProperties:function(){this._mdf=!1;for(var t=this.dynamicProperties.length,e=0;e<t;e+=1)this.dynamicProperties[e].getValue(),this.dynamicProperties[e]._mdf&&(this._mdf=!0)},initDynamicPropertyContainer:function(t){this.container=t,this.dynamicProperties=[],this._mdf=!1,this._isAnimated=!1}};var pointPool=poolFactory(8,function(){return createTypedArray("float32",2)});function ShapePath(){this.c=!1,this._length=0,this._maxLength=8,this.v=createSizedArray(this._maxLength),this.o=createSizedArray(this._maxLength),this.i=createSizedArray(this._maxLength)}ShapePath.prototype.setPathData=function(t,e){this.c=t,this.setLength(e);for(var i=0;i<e;)this.v[i]=pointPool.newElement(),this.o[i]=pointPool.newElement(),this.i[i]=pointPool.newElement(),i+=1},ShapePath.prototype.setLength=function(t){for(;this._maxLength<t;)this.doubleArrayLength();this._length=t},ShapePath.prototype.doubleArrayLength=function(){this.v=this.v.concat(createSizedArray(this._maxLength)),this.i=this.i.concat(createSizedArray(this._maxLength)),this.o=this.o.concat(createSizedArray(this._maxLength)),this._maxLength*=2},ShapePath.prototype.setXYAt=function(t,e,i,r,s){var a;switch(this._length=Math.max(this._length,r+1),this._length>=this._maxLength&&this.doubleArrayLength(),i){case"v":a=this.v;break;case"i":a=this.i;break;case"o":a=this.o;break;default:a=[]}a[r]&&(a[r],s)||(a[r]=pointPool.newElement()),a[r][0]=t,a[r][1]=e},ShapePath.prototype.setTripleAt=function(t,e,i,r,s,a,n,o){this.setXYAt(t,e,"v",n,o),this.setXYAt(i,r,"o",n,o),this.setXYAt(s,a,"i",n,o)},ShapePath.prototype.reverse=function(){for(var t=new ShapePath,e=(t.setPathData(this.c,this._length),this.v),i=this.o,r=this.i,s=0,a=(this.c&&(t.setTripleAt(e[0][0],e[0][1],r[0][0],r[0][1],i[0][0],i[0][1],0,!1),s=1),this._length-1),n=this._length,o=s;o<n;o+=1)t.setTripleAt(e[a][0],e[a][1],r[a][0],r[a][1],i[a][0],i[a][1],o,!1),--a;return t},ShapePath.prototype.length=function(){return this._length};var shapePool=(()=>{var s=poolFactory(4,function(){return new ShapePath},function(t){for(var e=t._length,i=0;i<e;i+=1)pointPool.release(t.v[i]),pointPool.release(t.i[i]),pointPool.release(t.o[i]),t.v[i]=null,t.i[i]=null,t.o[i]=null;t._length=0,t.c=!1});return s.clone=function(t){var e,i=s.newElement(),r=void 0===t._length?t.v.length:t._length;for(i.setLength(r),i.c=t.c,e=0;e<r;e+=1)i.setTripleAt(t.v[e][0],t.v[e][1],t.o[e][0],t.o[e][1],t.i[e][0],t.i[e][1],e);return i},s})();function ShapeCollection(){this._length=0,this._maxLength=4,this.shapes=createSizedArray(this._maxLength)}ShapeCollection.prototype.addShape=function(t){this._length===this._maxLength&&(this.shapes=this.shapes.concat(createSizedArray(this._maxLength)),this._maxLength*=2),this.shapes[this._length]=t,this._length+=1},ShapeCollection.prototype.releaseShapes=function(){for(var t=0;t<this._length;t+=1)shapePool.release(this.shapes[t]);this._length=0};var shapeCollectionPool=(()=>{var t={newShapeCollection:function(){var t;t=r?a[--r]:new ShapeCollection;return t},release:function(t){var e,i=t._length;for(e=0;e<i;e+=1)shapePool.release(t.shapes[e]);t._length=0,r===s&&(a=pooling.double(a),s*=2);a[r]=t,r+=1}},r=0,s=4,a=createSizedArray(s);return t})(),ShapePropertyFactory=(()=>{var s=-999999;function t(t,e,i){var r,s,a,n,o,h,l,p=i.lastIndex,m=this.keyframes;if(t<m[0].t-this.offsetTime)r=m[0].s[0],s=!0,p=0;else if(t>=m[m.length-1].t-this.offsetTime)r=(m[m.length-1].s?m[m.length-1].s:m[m.length-2].e)[0],s=!0;else{for(var f,c,d,u,y,g,v=p,b=m.length-1,x=!0;x&&(f=m[v],!((c=m[v+1]).t-this.offsetTime>t));)v<b-1?v+=1:x=!1;d=this.keyframesMetadata[v]||{},p=v,(s=1===f.h)||(y=t>=c.t-this.offsetTime?1:t<f.t-this.offsetTime?0:(d.__fnct?u=d.__fnct:(u=BezierFactory.getBezierEasing(f.o.x,f.o.y,f.i.x,f.i.y).get,d.__fnct=u),u((t-(f.t-this.offsetTime))/(c.t-this.offsetTime-(f.t-this.offsetTime)))),g=(c.s||f.e)[0]),r=f.s[0]}for(o=e._length,h=r.i[0].length,i.lastIndex=p,a=0;a<o;a+=1)for(n=0;n<h;n+=1)l=s?r.i[a][n]:r.i[a][n]+(g.i[a][n]-r.i[a][n])*y,e.i[a][n]=l,l=s?r.o[a][n]:r.o[a][n]+(g.o[a][n]-r.o[a][n])*y,e.o[a][n]=l,l=s?r.v[a][n]:r.v[a][n]+(g.v[a][n]-r.v[a][n])*y,e.v[a][n]=l}function r(){this.paths=this.localShapeCollection}function e(t){((t,e)=>{if(t._length===e._length&&t.c===e.c){for(var i=t._length,r=0;r<i;r+=1)if(t.v[r][0]!==e.v[r][0]||t.v[r][1]!==e.v[r][1]||t.o[r][0]!==e.o[r][0]||t.o[r][1]!==e.o[r][1]||t.i[r][0]!==e.i[r][0]||t.i[r][1]!==e.i[r][1])return;return 1}})(this.v,t)||(this.v=shapePool.clone(t),this.localShapeCollection.releaseShapes(),this.localShapeCollection.addShape(this.v),this._mdf=!0,this.paths=this.localShapeCollection)}function i(){if(this.elem.globalData.frameId!==this.frameId)if(this.effectsSequence.length)if(this.lock)this.setVValue(this.pv);else{this.lock=!0,this._mdf=!1,t=this.kf?this.pv:(this.data.ks||this.data.pt).k;for(var t,e=this.effectsSequence.length,i=0;i<e;i+=1)t=this.effectsSequence[i](t);this.setVValue(t),this.lock=!1,this.frameId=this.elem.globalData.frameId}else this._mdf=!1}function a(t,e,i){this.propType="shape",this.comp=t.comp,this.container=t,this.elem=t,this.data=e,this.k=!1,this.kf=!1,this._mdf=!1;t=(3===i?e.pt:e.ks).k;this.v=shapePool.clone(t),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.reset=r,this.effectsSequence=[]}function n(t){this.effectsSequence.push(t),this.container.addDynamicProperty(this)}function o(t,e,i){this.propType="shape",this.comp=t.comp,this.elem=t,this.container=t,this.offsetTime=t.data.st,this.keyframes=(3===i?e.pt:e.ks).k,this.keyframesMetadata=[],this.k=!0,this.kf=!0;t=this.keyframes[0].s[0].i.length;this.v=shapePool.newElement(),this.v.setPathData(this.keyframes[0].s[0].c,t),this.pv=shapePool.clone(this.v),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.paths.addShape(this.v),this.lastFrame=s,this.reset=r,this._caching={lastFrame:s,lastIndex:0},this.effectsSequence=[function(){var t=this.comp.renderedFrame-this.offsetTime,e=this.keyframes[0].t-this.offsetTime,i=this.keyframes[this.keyframes.length-1].t-this.offsetTime,r=this._caching.lastFrame;return r!==s&&(r<e&&t<e||i<r&&i<t)||(this._caching.lastIndex=r<t?this._caching.lastIndex:0,this.interpolateShape(t,this.pv,this._caching)),this._caching.lastFrame=t,this.pv}.bind(this)]}a.prototype.interpolateShape=t,a.prototype.getValue=i,a.prototype.setVValue=e,a.prototype.addEffect=n,o.prototype.getValue=i,o.prototype.interpolateShape=t,o.prototype.setVValue=e,o.prototype.addEffect=n,h=roundCorner,p.prototype={reset:r,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf)&&this.convertEllToPath()},convertEllToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,r=this.s.v[1]/2,s=3!==this.d,a=this.v;a.v[0][0]=t,a.v[0][1]=e-r,a.v[1][0]=s?t+i:t-i,a.v[1][1]=e,a.v[2][0]=t,a.v[2][1]=e+r,a.v[3][0]=s?t-i:t+i,a.v[3][1]=e,a.i[0][0]=s?t-i*h:t+i*h,a.i[0][1]=e-r,a.i[1][0]=s?t+i:t-i,a.i[1][1]=e-r*h,a.i[2][0]=s?t+i*h:t-i*h,a.i[2][1]=e+r,a.i[3][0]=s?t-i:t+i,a.i[3][1]=e+r*h,a.o[0][0]=s?t+i*h:t-i*h,a.o[0][1]=e-r,a.o[1][0]=s?t+i:t-i,a.o[1][1]=e+r*h,a.o[2][0]=s?t-i*h:t+i*h,a.o[2][1]=e+r,a.o[3][0]=s?t-i:t+i,a.o[3][1]=e-r*h}},extendPrototype([DynamicPropertyContainer],p);var h,l=p;function p(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,4),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.paths=this.localShapeCollection,this.localShapeCollection.addShape(this.v),this.d=e.d,this.elem=t,this.comp=t.comp,this.frameId=-1,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertEllToPath())}f.prototype={reset:r,getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf)&&this.convertToPath()},convertStarToPath:function(){for(var t=2*Math.floor(this.pt.v),e=2*Math.PI/t,i=!0,r=this.or.v,s=this.ir.v,a=this.os.v,n=this.is.v,o=2*Math.PI*r/(2*t),h=2*Math.PI*s/(2*t),l=-Math.PI/2,p=(l+=this.r.v,3===this.data.d?-1:1),m=this.v._length=0;m<t;m+=1){var f=i?a:n,c=i?o:h,d=(u=i?r:s)*Math.cos(l),u=u*Math.sin(l),y=0==d&&0==u?0:u/Math.sqrt(d*d+u*u),g=0==d&&0==u?0:-d/Math.sqrt(d*d+u*u);d+=+this.p.v[0],u+=+this.p.v[1],this.v.setTripleAt(d,u,d-y*c*f*p,u-g*c*f*p,d+y*c*f*p,u+g*c*f*p,m,!0),i=!i,l+=e*p}},convertPolygonToPath:function(){var t,e=Math.floor(this.pt.v),i=2*Math.PI/e,r=this.or.v,s=this.os.v,a=2*Math.PI*r/(4*e),n=.5*-Math.PI,o=3===this.data.d?-1:1;for(n+=this.r.v,t=this.v._length=0;t<e;t+=1){var h=r*Math.cos(n),l=r*Math.sin(n),p=0==h&&0==l?0:l/Math.sqrt(h*h+l*l),m=0==h&&0==l?0:-h/Math.sqrt(h*h+l*l);h+=+this.p.v[0],l+=+this.p.v[1],this.v.setTripleAt(h,l,h-p*a*s*o,l-m*a*s*o,h+p*a*s*o,l+m*a*s*o,t,!0),n+=i*o}this.paths.length=0,this.paths[0]=this.v}},extendPrototype([DynamicPropertyContainer],f);var m=f;function f(t,e){this.v=shapePool.newElement(),this.v.setPathData(!0,0),this.elem=t,this.comp=t.comp,this.data=e,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),1===e.sy?(this.ir=PropertyFactory.getProp(t,e.ir,0,0,this),this.is=PropertyFactory.getProp(t,e.is,0,.01,this),this.convertToPath=this.convertStarToPath):this.convertToPath=this.convertPolygonToPath,this.pt=PropertyFactory.getProp(t,e.pt,0,0,this),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,degToRads,this),this.or=PropertyFactory.getProp(t,e.or,0,0,this),this.os=PropertyFactory.getProp(t,e.os,0,.01,this),this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertToPath())}d.prototype={convertRectToPath:function(){var t=this.p.v[0],e=this.p.v[1],i=this.s.v[0]/2,r=this.s.v[1]/2,s=bmMin(i,r,this.r.v),a=s*(1-roundCorner);this.v._length=0,2===this.d||1===this.d?(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+s,t+i,e-r+a,0,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-a,t+i,e+r-s,1,!0),0!==s?(this.v.setTripleAt(t+i-s,e+r,t+i-s,e+r,t+i-a,e+r,2,!0),this.v.setTripleAt(t-i+s,e+r,t-i+a,e+r,t-i+s,e+r,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-s,t-i,e+r-a,4,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+a,t-i,e-r+s,5,!0),this.v.setTripleAt(t-i+s,e-r,t-i+s,e-r,t-i+a,e-r,6,!0),this.v.setTripleAt(t+i-s,e-r,t+i-a,e-r,t+i-s,e-r,7,!0)):(this.v.setTripleAt(t-i,e+r,t-i+a,e+r,t-i,e+r,2),this.v.setTripleAt(t-i,e-r,t-i,e-r+a,t-i,e-r,3))):(this.v.setTripleAt(t+i,e-r+s,t+i,e-r+a,t+i,e-r+s,0,!0),0!==s?(this.v.setTripleAt(t+i-s,e-r,t+i-s,e-r,t+i-a,e-r,1,!0),this.v.setTripleAt(t-i+s,e-r,t-i+a,e-r,t-i+s,e-r,2,!0),this.v.setTripleAt(t-i,e-r+s,t-i,e-r+s,t-i,e-r+a,3,!0),this.v.setTripleAt(t-i,e+r-s,t-i,e+r-a,t-i,e+r-s,4,!0),this.v.setTripleAt(t-i+s,e+r,t-i+s,e+r,t-i+a,e+r,5,!0),this.v.setTripleAt(t+i-s,e+r,t+i-a,e+r,t+i-s,e+r,6,!0),this.v.setTripleAt(t+i,e+r-s,t+i,e+r-s,t+i,e+r-a,7,!0)):(this.v.setTripleAt(t-i,e-r,t-i+a,e-r,t-i,e-r,1,!0),this.v.setTripleAt(t-i,e+r,t-i,e+r-a,t-i,e+r,2,!0),this.v.setTripleAt(t+i,e+r,t+i-a,e+r,t+i,e+r,3,!0)))},getValue:function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf)&&this.convertRectToPath()},reset:r},extendPrototype([DynamicPropertyContainer],d);var c=d;function d(t,e){this.v=shapePool.newElement(),this.v.c=!0,this.localShapeCollection=shapeCollectionPool.newShapeCollection(),this.localShapeCollection.addShape(this.v),this.paths=this.localShapeCollection,this.elem=t,this.comp=t.comp,this.frameId=-1,this.d=e.d,this.initDynamicPropertyContainer(t),this.p=PropertyFactory.getProp(t,e.p,1,0,this),this.s=PropertyFactory.getProp(t,e.s,1,0,this),this.r=PropertyFactory.getProp(t,e.r,0,0,this),this.dynamicProperties.length?this.k=!0:(this.k=!1,this.convertRectToPath())}var u={getShapeProp:function(t,e,i){var r;return 3===i||4===i?r=new((3===i?e.pt:e.ks).k.length?o:a)(t,e,i):5===i?r=new c(t,e):6===i?r=new l(t,e):7===i&&(r=new m(t,e)),r.k&&t.addDynamicProperty(r),r},getConstructorFunction:function(){return a},getKeyframedConstructorFunction:function(){return o}};return u})(),Matrix=(()=>{var r=Math.cos,s=Math.sin,a=Math.tan,n=Math.round;function t(){return this.props[0]=1,this.props[1]=0,this.props[2]=0,this.props[3]=0,this.props[4]=0,this.props[5]=1,this.props[6]=0,this.props[7]=0,this.props[8]=0,this.props[9]=0,this.props[10]=1,this.props[11]=0,this.props[12]=0,this.props[13]=0,this.props[14]=0,this.props[15]=1,this}function e(t){var e;return 0===t?this:(e=r(t),t=s(t),this._t(e,-t,0,0,t,e,0,0,0,0,1,0,0,0,0,1))}function i(t){var e;return 0===t?this:(e=r(t),t=s(t),this._t(1,0,0,0,0,e,-t,0,0,t,e,0,0,0,0,1))}function o(t){var e;return 0===t?this:(e=r(t),t=s(t),this._t(e,0,t,0,0,1,0,0,-t,0,e,0,0,0,0,1))}function h(t){var e;return 0===t?this:(e=r(t),t=s(t),this._t(e,-t,0,0,t,e,0,0,0,0,1,0,0,0,0,1))}function l(t,e){return this._t(1,e,t,1,0,0)}function p(t,e){return this.shear(a(t),a(e))}function m(t,e){var i=r(e),e=s(e);return this._t(i,e,0,0,-e,i,0,0,0,0,1,0,0,0,0,1)._t(1,0,0,0,a(t),1,0,0,0,0,1,0,0,0,0,1)._t(i,-e,0,0,e,i,0,0,0,0,1,0,0,0,0,1)}function f(t,e,i){return i||0===i||(i=1),1===t&&1===e&&1===i?this:this._t(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1)}function c(t,e,i,r,s,a,n,o,h,l,p,m,f,c,d,u){return this.props[0]=t,this.props[1]=e,this.props[2]=i,this.props[3]=r,this.props[4]=s,this.props[5]=a,this.props[6]=n,this.props[7]=o,this.props[8]=h,this.props[9]=l,this.props[10]=p,this.props[11]=m,this.props[12]=f,this.props[13]=c,this.props[14]=d,this.props[15]=u,this}function d(t,e,i){return i=i||0,0!==t||0!==e||0!==i?this._t(1,0,0,0,0,1,0,0,0,0,1,0,t,e,i,1):this}function u(t,e,i,r,s,a,n,o,h,l,p,m,f,c,d,u){var y,g,v,b,x,P,E,S,C,_,A,T,M,k,D,F,w=this.props;return 1===t&&0===e&&0===i&&0===r&&0===s&&1===a&&0===n&&0===o&&0===h&&0===l&&1===p&&0===m?(w[12]=w[12]*t+w[15]*f,w[13]=w[13]*a+w[15]*c,w[14]=w[14]*p+w[15]*d,w[15]*=u,this._identityCalculated=!1):(y=w[0],x=w[4],P=w[5],E=w[6],S=w[7],C=w[8],_=w[9],A=w[10],T=w[11],M=w[12],k=w[13],D=w[14],F=w[15],w[0]=y*t+(g=w[1])*s+(v=w[2])*h+(b=w[3])*f,w[1]=y*e+g*a+v*l+b*c,w[2]=y*i+g*n+v*p+b*d,w[3]=y*r+g*o+v*m+b*u,w[4]=x*t+P*s+E*h+S*f,w[5]=x*e+P*a+E*l+S*c,w[6]=x*i+P*n+E*p+S*d,w[7]=x*r+P*o+E*m+S*u,w[8]=C*t+_*s+A*h+T*f,w[9]=C*e+_*a+A*l+T*c,w[10]=C*i+_*n+A*p+T*d,w[11]=C*r+_*o+A*m+T*u,w[12]=M*t+k*s+D*h+F*f,w[13]=M*e+k*a+D*l+F*c,w[14]=M*i+k*n+D*p+F*d,w[15]=M*r+k*o+D*m+F*u,this._identityCalculated=!1),this}function y(t){t=t.props;return this.transform(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])}function g(){return this._identityCalculated||(this._identity=!(1!==this.props[0]||0!==this.props[1]||0!==this.props[2]||0!==this.props[3]||0!==this.props[4]||1!==this.props[5]||0!==this.props[6]||0!==this.props[7]||0!==this.props[8]||0!==this.props[9]||1!==this.props[10]||0!==this.props[11]||0!==this.props[12]||0!==this.props[13]||0!==this.props[14]||1!==this.props[15]),this._identityCalculated=!0),this._identity}function v(t){for(var e=0;e<16;){if(t.props[e]!==this.props[e])return!1;e+=1}return!0}function b(t){for(var e=0;e<16;e+=1)t.props[e]=this.props[e];return t}function x(t){for(var e=0;e<16;e+=1)this.props[e]=t[e]}function P(t,e,i){return{x:t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],y:t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],z:t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}}function E(t,e,i){return t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12]}function S(t,e,i){return t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13]}function C(t,e,i){return t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]}function _(){var t=this.props[0]*this.props[5]-this.props[1]*this.props[4],e=this.props[5]/t,i=-this.props[1]/t,r=-this.props[4]/t,s=this.props[0]/t,a=(this.props[4]*this.props[13]-this.props[5]*this.props[12])/t,t=-(this.props[0]*this.props[13]-this.props[1]*this.props[12])/t,n=new Matrix;return n.props[0]=e,n.props[1]=i,n.props[4]=r,n.props[5]=s,n.props[12]=a,n.props[13]=t,n}function A(t){return this.getInverseMatrix().applyToPointArray(t[0],t[1],t[2]||0)}function T(t){for(var e=t.length,i=[],r=0;r<e;r+=1)i[r]=A(t[r]);return i}function M(t,e,i){var r,s,a,n,o,h,l=createTypedArray("float32",6);return this.isIdentity()?(l[0]=t[0],l[1]=t[1],l[2]=e[0],l[3]=e[1],l[4]=i[0],l[5]=i[1]):(r=this.props[0],s=this.props[1],a=this.props[4],n=this.props[5],o=this.props[12],h=this.props[13],l[0]=t[0]*r+t[1]*a+o,l[1]=t[0]*s+t[1]*n+h,l[2]=e[0]*r+e[1]*a+o,l[3]=e[0]*s+e[1]*n+h,l[4]=i[0]*r+i[1]*a+o,l[5]=i[0]*s+i[1]*n+h),l}function k(t,e,i){t=this.isIdentity()?[t,e,i]:[t*this.props[0]+e*this.props[4]+i*this.props[8]+this.props[12],t*this.props[1]+e*this.props[5]+i*this.props[9]+this.props[13],t*this.props[2]+e*this.props[6]+i*this.props[10]+this.props[14]];return t}function D(t,e){var i;return this.isIdentity()?t+","+e:(i=this.props,Math.round(100*(t*i[0]+e*i[4]+i[12]))/100+","+Math.round(100*(t*i[1]+e*i[5]+i[13]))/100)}function F(){for(var t=0,e=this.props,i="matrix3d(";t<16;)i=i+n(1e4*e[t])/1e4+(15===t?")":","),t+=1;return i}function w(t){return t<1e-6&&0<t||-1e-6<t&&t<0?n(1e4*t)/1e4:t}function I(){var t=this.props;return"matrix("+w(t[0])+","+w(t[1])+","+w(t[4])+","+w(t[5])+","+w(t[12])+","+w(t[13])+")"}return function(){this.reset=t,this.rotate=e,this.rotateX=i,this.rotateY=o,this.rotateZ=h,this.skew=p,this.skewFromAxis=m,this.shear=l,this.scale=f,this.setTransform=c,this.translate=d,this.transform=u,this.multiply=y,this.applyToPoint=P,this.applyToX=E,this.applyToY=S,this.applyToZ=C,this.applyToPointArray=k,this.applyToTriplePoints=M,this.applyToPointStringified=D,this.toCSS=F,this.to2dCSS=I,this.clone=b,this.cloneFromProps=x,this.equals=v,this.inversePoints=T,this.inversePoint=A,this.getInverseMatrix=_,this._t=this.transform,this.isIdentity=g,this._identity=!0,this._identityCalculated=!1,this.props=createTypedArray("float32",16),this.reset()}})();function _typeof$3(t){return(_typeof$3="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var lottie={},standalone="__[STANDALONE]__",animationData="__[ANIMATIONDATA]__",renderer="";function setLocation(t){setLocationHref(t)}function searchAnimations(){!0===standalone?animationManager.searchAnimations(animationData,standalone,renderer):animationManager.searchAnimations()}function setSubframeRendering(t){setSubframeEnabled(t)}function setPrefix(t){setIdPrefix(t)}function loadAnimation(t){return!0===standalone&&(t.animationData=JSON.parse(animationData)),animationManager.loadAnimation(t)}function setQuality(t){if("string"==typeof t)switch(t){case"high":setDefaultCurveSegments(200);break;default:case"medium":setDefaultCurveSegments(50);break;case"low":setDefaultCurveSegments(10)}else!isNaN(t)&&1<t&&setDefaultCurveSegments(t);50<=getDefaultCurveSegments()?roundValues(!1):roundValues(!0)}function inBrowser(){return"undefined"!=typeof navigator}function installPlugin(t,e){"expressions"===t&&setExpressionsPlugin(e)}function getFactory(t){switch(t){case"propertyFactory":return PropertyFactory;case"shapePropertyFactory":return ShapePropertyFactory;case"matrix":return Matrix;default:return null}}function checkReady(){"complete"===document.readyState&&(clearInterval(readyStateCheckInterval),searchAnimations())}function getQueryVariable(t){for(var e=queryString.split("&"),i=0;i<e.length;i+=1){var r=e[i].split("=");if(decodeURIComponent(r[0])==t)return decodeURIComponent(r[1])}return null}lottie.play=animationManager.play,lottie.pause=animationManager.pause,lottie.setLocationHref=setLocation,lottie.togglePause=animationManager.togglePause,lottie.setSpeed=animationManager.setSpeed,lottie.setDirection=animationManager.setDirection,lottie.stop=animationManager.stop,lottie.searchAnimations=searchAnimations,lottie.registerAnimation=animationManager.registerAnimation,lottie.loadAnimation=loadAnimation,lottie.setSubframeRendering=setSubframeRendering,lottie.resize=animationManager.resize,lottie.goToAndStop=animationManager.goToAndStop,lottie.destroy=animationManager.destroy,lottie.setQuality=setQuality,lottie.inBrowser=inBrowser,lottie.installPlugin=installPlugin,lottie.freeze=animationManager.freeze,lottie.unfreeze=animationManager.unfreeze,lottie.setVolume=animationManager.setVolume,lottie.mute=animationManager.mute,lottie.unmute=animationManager.unmute,lottie.getRegisteredAnimations=animationManager.getRegisteredAnimations,lottie.useWebWorker=setWebWorker,lottie.setIDPrefix=setPrefix,lottie.__getFactory=getFactory,lottie.version="5.13.0";var queryString="",scripts,index,myScript,queryString,renderer,readyStateCheckInterval=(standalone&&(scripts=document.getElementsByTagName("script"),index=scripts.length-1,myScript=scripts[index]||{src:""},queryString=myScript.src?myScript.src.replace(/^[^\?]+\??/,""):"",renderer=getQueryVariable("renderer")),setInterval(checkReady,100));try{"object"===("undefined"==typeof exports?"undefined":_typeof$3(exports))&&"undefined"!=typeof module||"function"==typeof define&&define.amd||(window.bodymovin=lottie)}catch(err){}var ShapeModifiers=(()=>{var t={},r={};return t.registerModifier=function(t,e){r[t]||(r[t]=e)},t.getModifier=function(t,e,i){return new r[t](e,i)},t})();function ShapeModifier(){}function TrimModifier(){}function PuckerAndBloatModifier(){}ShapeModifier.prototype.initModifierProperties=function(){},ShapeModifier.prototype.addShapeToModifier=function(){},ShapeModifier.prototype.addShape=function(t){var e;this.closed||(t.sh.container.addDynamicProperty(t.sh),e={shape:t.sh,data:t,localShapeCollection:shapeCollectionPool.newShapeCollection()},this.shapes.push(e),this.addShapeToModifier(e),this._isAnimated&&t.setAsAnimated())},ShapeModifier.prototype.init=function(t,e){this.shapes=[],this.elem=t,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e),this.frameId=initialDefaultFrame,this.closed=!1,this.k=!1,this.dynamicProperties.length?this.k=!0:this.getValue(!0)},ShapeModifier.prototype.processKeys=function(){this.elem.globalData.frameId!==this.frameId&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties())},extendPrototype([DynamicPropertyContainer],ShapeModifier),extendPrototype([ShapeModifier],TrimModifier),TrimModifier.prototype.initModifierProperties=function(t,e){this.s=PropertyFactory.getProp(t,e.s,0,.01,this),this.e=PropertyFactory.getProp(t,e.e,0,.01,this),this.o=PropertyFactory.getProp(t,e.o,0,0,this),this.sValue=0,this.eValue=0,this.getValue=this.processKeys,this.m=e.m,this._isAnimated=!!this.s.effectsSequence.length||!!this.e.effectsSequence.length||!!this.o.effectsSequence.length},TrimModifier.prototype.addShapeToModifier=function(t){t.pathsData=[]},TrimModifier.prototype.calculateShapeEdges=function(t,e,i,r,s){for(var a,n,o=[],h=(e<=1?o.push({s:t,e:e}):1<=t?o.push({s:t-1,e:e-1}):(o.push({s:t,e:1}),o.push({s:0,e:e-1})),[]),l=o.length,p=0;p<l;p+=1)(n=o[p]).e*s<r||n.s*s>r+i||(a=n.s*s<=r?0:(n.s*s-r)/i,n=n.e*s>=r+i?1:(n.e*s-r)/i,h.push([a,n]));return h.length||h.push([0,0]),h},TrimModifier.prototype.releasePathsData=function(t){for(var e=t.length,i=0;i<e;i+=1)segmentsLengthPool.release(t[i]);return t.length=0,t},TrimModifier.prototype.processShapes=function(t){this._mdf||t?((e=this.o.v%360/360)<0&&(e+=1),i=1<this.s.v?1+e:this.s.v<0?0+e:this.s.v+e,(r=1<this.e.v?1+e:this.e.v<0?0+e:this.e.v+e)<i&&(e=i,i=r,r=e),i=1e-4*Math.round(1e4*i),r=1e-4*Math.round(1e4*r),this.sValue=i,this.eValue=r):(i=this.sValue,r=this.eValue);var e,i,r,s,a,n,o,h,l,p=this.shapes.length,m=0;if(r===i)for(u=0;u<p;u+=1)this.shapes[u].localShapeCollection.releaseShapes(),this.shapes[u].shape._mdf=!0,this.shapes[u].shape.paths=this.shapes[u].localShapeCollection,this._mdf&&(this.shapes[u].pathsData.length=0);else if(1===r&&0===i||0===r&&1===i){if(this._mdf)for(u=0;u<p;u+=1)this.shapes[u].pathsData.length=0,this.shapes[u].shape._mdf=!0}else{for(var f,c,d=[],u=0;u<p;u+=1)if((f=this.shapes[u]).shape._mdf||this._mdf||t||2===this.m){if(n=(s=f.shape.paths)._length,l=0,!f.shape._mdf&&f.pathsData.length)l=f.totalShapeLength;else{for(o=this.releasePathsData(f.pathsData),a=0;a<n;a+=1)h=bez.getSegmentsLength(s.shapes[a]),o.push(h),l+=h.totalLength;f.totalShapeLength=l,f.pathsData=o}m+=l,f.shape._mdf=!0}else f.shape.paths=f.localShapeCollection;var y,g=i,v=r,b=0;for(u=p-1;0<=u;--u)if((f=this.shapes[u]).shape._mdf){for((c=f.localShapeCollection).releaseShapes(),2===this.m&&1<p?(y=this.calculateShapeEdges(i,r,f.totalShapeLength,b,m),b+=f.totalShapeLength):y=[[g,v]],n=y.length,a=0;a<n;a+=1){g=y[a][0],v=y[a][1],d.length=0,v<=1?d.push({s:f.totalShapeLength*g,e:f.totalShapeLength*v}):1<=g?d.push({s:f.totalShapeLength*(g-1),e:f.totalShapeLength*(v-1)}):(d.push({s:f.totalShapeLength*g,e:f.totalShapeLength}),d.push({s:0,e:f.totalShapeLength*(v-1)}));var x,P=this.addShapes(f,d[0]);d[0].s!==d[0].e&&(1<d.length&&(P=f.shape.paths.shapes[f.shape.paths._length-1].c?(x=P.pop(),this.addPaths(P,c),this.addShapes(f,d[1],x)):(this.addPaths(P,c),this.addShapes(f,d[1]))),this.addPaths(P,c))}f.shape.paths=c}}},TrimModifier.prototype.addPaths=function(t,e){for(var i=t.length,r=0;r<i;r+=1)e.addShape(t[r])},TrimModifier.prototype.addSegment=function(t,e,i,r,s,a,n){s.setXYAt(e[0],e[1],"o",a),s.setXYAt(i[0],i[1],"i",a+1),n&&s.setXYAt(t[0],t[1],"v",a),s.setXYAt(r[0],r[1],"v",a+1)},TrimModifier.prototype.addSegmentFromArray=function(t,e,i,r){e.setXYAt(t[1],t[5],"o",i),e.setXYAt(t[2],t[6],"i",i+1),r&&e.setXYAt(t[0],t[4],"v",i),e.setXYAt(t[3],t[7],"v",i+1)},TrimModifier.prototype.addShapes=function(t,e,i){var r,s,a,n,o,h,l,p,m=t.pathsData,f=t.shape.paths.shapes,c=t.shape.paths._length,d=0,u=[],y=!0,g=i?(n=i._length,i._length):(i=shapePool.newElement(),n=0);for(u.push(i),r=0;r<c;r+=1){for(o=m[r].lengths,i.c=f[r].c,a=f[r].c?o.length:o.length+1,s=1;s<a;s+=1)if(d+(p=o[s-1]).addedLength<e.s)d+=p.addedLength,i.c=!1;else{if(d>e.e){i.c=!1;break}e.s<=d&&e.e>=d+p.addedLength?(this.addSegment(f[r].v[s-1],f[r].o[s-1],f[r].i[s],f[r].v[s],i,n,y),y=!1):(h=bez.getNewSegment(f[r].v[s-1],f[r].v[s],f[r].o[s-1],f[r].i[s],(e.s-d)/p.addedLength,(e.e-d)/p.addedLength,o[s-1]),this.addSegmentFromArray(h,i,n,y),i.c=y=!1),d+=p.addedLength,n+=1}if(f[r].c&&o.length&&(p=o[s-1],d<=e.e?(l=o[s-1].addedLength,e.s<=d&&e.e>=d+l?(this.addSegment(f[r].v[s-1],f[r].o[s-1],f[r].i[0],f[r].v[0],i,n,y),y=!1):(h=bez.getNewSegment(f[r].v[s-1],f[r].v[0],f[r].o[s-1],f[r].i[0],(e.s-d)/l,(e.e-d)/l,o[s-1]),this.addSegmentFromArray(h,i,n,y),i.c=y=!1)):i.c=!1,d+=p.addedLength,n+=1),i._length&&(i.setXYAt(i.v[g][0],i.v[g][1],"i",g),i.setXYAt(i.v[i._length-1][0],i.v[i._length-1][1],"o",i._length-1)),d>e.e)break;r<c-1&&(i=shapePool.newElement(),y=!0,u.push(i),n=0)}return u},extendPrototype([ShapeModifier],PuckerAndBloatModifier),PuckerAndBloatModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this._isAnimated=!!this.amount.effectsSequence.length},PuckerAndBloatModifier.prototype.processPath=function(t,e){for(var i=e/100,r=[0,0],s=t._length,a=0,a=0;a<s;a+=1)r[0]+=t.v[a][0],r[1]+=t.v[a][1];r[0]/=s,r[1]/=s;var n,o,h,l,p,m,f=shapePool.newElement();for(f.c=t.c,a=0;a<s;a+=1)n=t.v[a][0]+(r[0]-t.v[a][0])*i,o=t.v[a][1]+(r[1]-t.v[a][1])*i,h=t.o[a][0]+(r[0]-t.o[a][0])*-i,l=t.o[a][1]+(r[1]-t.o[a][1])*-i,p=t.i[a][0]+(r[0]-t.i[a][0])*-i,m=t.i[a][1]+(r[1]-t.i[a][1])*-i,f.setTripleAt(n,o,h,l,p,m,a);return f},PuckerAndBloatModifier.prototype.processShapes=function(t){var e,i,r,s=this.shapes.length,a=this.amount.v;if(0!==a)for(var n,o,h=0;h<s;h+=1){if(o=(n=this.shapes[h]).localShapeCollection,n.shape._mdf||this._mdf||t)for(o.releaseShapes(),n.shape._mdf=!0,e=n.shape.paths.shapes,r=n.shape.paths._length,i=0;i<r;i+=1)o.addShape(this.processPath(e[i],a));n.shape.paths=n.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var TransformPropertyFactory=(()=>{var a=[0,0];function r(t,e,i){if(this.elem=t,this.frameId=-1,this.propType="transform",this.data=e,this.v=new Matrix,this.pre=new Matrix,this.appliedTransformations=0,this.initDynamicPropertyContainer(i||t),e.p&&e.p.s?(this.px=PropertyFactory.getProp(t,e.p.x,0,0,this),this.py=PropertyFactory.getProp(t,e.p.y,0,0,this),e.p.z&&(this.pz=PropertyFactory.getProp(t,e.p.z,0,0,this))):this.p=PropertyFactory.getProp(t,e.p||{k:[0,0,0]},1,0,this),e.rx){if(this.rx=PropertyFactory.getProp(t,e.rx,0,degToRads,this),this.ry=PropertyFactory.getProp(t,e.ry,0,degToRads,this),this.rz=PropertyFactory.getProp(t,e.rz,0,degToRads,this),e.or.k[0].ti)for(var r=e.or.k.length,s=0;s<r;s+=1)e.or.k[s].to=null,e.or.k[s].ti=null;this.or=PropertyFactory.getProp(t,e.or,1,degToRads,this),this.or.sh=!0}else this.r=PropertyFactory.getProp(t,e.r||{k:0},0,degToRads,this);e.sk&&(this.sk=PropertyFactory.getProp(t,e.sk,0,degToRads,this),this.sa=PropertyFactory.getProp(t,e.sa,0,degToRads,this)),this.a=PropertyFactory.getProp(t,e.a||{k:[0,0,0]},1,0,this),this.s=PropertyFactory.getProp(t,e.s||{k:[100,100,100]},1,.01,this),e.o?this.o=PropertyFactory.getProp(t,e.o,0,.01,t):this.o={_mdf:!1,v:1},this._isDirty=!0,this.dynamicProperties.length||this.getValue(!0)}return r.prototype={applyToMatrix:function(t){var e=this._mdf;this.iterateDynamicProperties(),this._mdf=this._mdf||e,this.a&&t.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.s&&t.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&t.skewFromAxis(-this.sk.v,this.sa.v),this.r?t.rotate(-this.r.v):t.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.data.p.s?this.data.p.z?t.translate(this.px.v,this.py.v,-this.pz.v):t.translate(this.px.v,this.py.v,0):t.translate(this.p.v[0],this.p.v[1],-this.p.v[2])},getValue:function(t){var e,i,r,s;this.elem.globalData.frameId!==this.frameId&&(this._isDirty&&(this.precalculateMatrix(),this._isDirty=!1),this.iterateDynamicProperties(),(this._mdf||t)&&(this.v.cloneFromProps(this.pre.props),this.appliedTransformations<1&&this.v.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations<2&&this.v.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.sk&&this.appliedTransformations<3&&this.v.skewFromAxis(-this.sk.v,this.sa.v),this.r&&this.appliedTransformations<4?this.v.rotate(-this.r.v):!this.r&&this.appliedTransformations<4&&this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.autoOriented&&(t=this.elem.globalData.frameRate,this.p&&this.p.keyframes&&this.p.getValueAtTime?i=this.p._caching.lastFrame+this.p.offsetTime<=this.p.keyframes[0].t?(e=this.p.getValueAtTime((this.p.keyframes[0].t+.01)/t,0),this.p.getValueAtTime(this.p.keyframes[0].t/t,0)):this.p._caching.lastFrame+this.p.offsetTime>=this.p.keyframes[this.p.keyframes.length-1].t?(e=this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length-1].t/t,0),this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length-1].t-.05)/t,0)):(e=this.p.pv,this.p.getValueAtTime((this.p._caching.lastFrame+this.p.offsetTime-.01)/t,this.p.offsetTime)):this.px&&this.px.keyframes&&this.py.keyframes&&this.px.getValueAtTime&&this.py.getValueAtTime?(e=[],i=[],r=this.px,s=this.py,r._caching.lastFrame+r.offsetTime<=r.keyframes[0].t?(e[0]=r.getValueAtTime((r.keyframes[0].t+.01)/t,0),e[1]=s.getValueAtTime((s.keyframes[0].t+.01)/t,0),i[0]=r.getValueAtTime(r.keyframes[0].t/t,0),i[1]=s.getValueAtTime(s.keyframes[0].t/t,0)):r._caching.lastFrame+r.offsetTime>=r.keyframes[r.keyframes.length-1].t?(e[0]=r.getValueAtTime(r.keyframes[r.keyframes.length-1].t/t,0),e[1]=s.getValueAtTime(s.keyframes[s.keyframes.length-1].t/t,0),i[0]=r.getValueAtTime((r.keyframes[r.keyframes.length-1].t-.01)/t,0),i[1]=s.getValueAtTime((s.keyframes[s.keyframes.length-1].t-.01)/t,0)):(e=[r.pv,s.pv],i[0]=r.getValueAtTime((r._caching.lastFrame+r.offsetTime-.01)/t,r.offsetTime),i[1]=s.getValueAtTime((s._caching.lastFrame+s.offsetTime-.01)/t,s.offsetTime))):e=i=a,this.v.rotate(-Math.atan2(e[1]-i[1],e[0]-i[0]))),this.data.p&&this.data.p.s?this.data.p.z?this.v.translate(this.px.v,this.py.v,-this.pz.v):this.v.translate(this.px.v,this.py.v,0):this.v.translate(this.p.v[0],this.p.v[1],-this.p.v[2])),this.frameId=this.elem.globalData.frameId)},precalculateMatrix:function(){if(this.appliedTransformations=0,this.pre.reset(),!this.a.effectsSequence.length&&(this.pre.translate(-this.a.v[0],-this.a.v[1],this.a.v[2]),this.appliedTransformations=1,!this.s.effectsSequence.length)){if(this.pre.scale(this.s.v[0],this.s.v[1],this.s.v[2]),this.appliedTransformations=2,this.sk){if(this.sk.effectsSequence.length||this.sa.effectsSequence.length)return;this.pre.skewFromAxis(-this.sk.v,this.sa.v),this.appliedTransformations=3}this.r?this.r.effectsSequence.length||(this.pre.rotate(-this.r.v),this.appliedTransformations=4):this.rz.effectsSequence.length||this.ry.effectsSequence.length||this.rx.effectsSequence.length||this.or.effectsSequence.length||(this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]),this.appliedTransformations=4)}},autoOrient:function(){}},extendPrototype([DynamicPropertyContainer],r),r.prototype.addDynamicProperty=function(t){this._addDynamicProperty(t),this.elem.addDynamicProperty(t),this._isDirty=!0},r.prototype._addDynamicProperty=DynamicPropertyContainer.prototype.addDynamicProperty,{getTransformProperty:function(t,e,i){return new r(t,e,i)}}})();function RepeaterModifier(){}function RoundCornersModifier(){}function floatEqual(t,e){return 1e5*Math.abs(t-e)<=Math.min(Math.abs(t),Math.abs(e))}function floatZero(t){return Math.abs(t)<=1e-5}function lerp(t,e,i){return t*(1-i)+e*i}function lerpPoint(t,e,i){return[lerp(t[0],e[0],i),lerp(t[1],e[1],i)]}function quadRoots(t,e,i){return 0===t||(i=e*e-4*t*i)<0?[]:(e=-e/(2*t),0==i?[e]:[e-(i=Math.sqrt(i)/(2*t)),e+i])}function polynomialCoefficients(t,e,i,r){return[3*e-t-3*i+r,3*t-6*e+3*i,-3*t+3*e,t]}function singlePoint(t){return new PolynomialBezier(t,t,t,t,!1)}function PolynomialBezier(t,e,i,r,s){s&&pointEqual(t,e)&&(e=lerpPoint(t,r,1/3)),s&&pointEqual(i,r)&&(i=lerpPoint(t,r,2/3));var s=polynomialCoefficients(t[0],e[0],i[0],r[0]),a=polynomialCoefficients(t[1],e[1],i[1],r[1]);this.a=[s[0],a[0]],this.b=[s[1],a[1]],this.c=[s[2],a[2]],this.d=[s[3],a[3]],this.points=[t,e,i,r]}function extrema(t,e){for(var i,r,s=t.points[0][e],a=t.points[t.points.length-1][e],n=(a<s&&(i=a,a=s,s=i),quadRoots(3*t.a[e],2*t.b[e],t.c[e])),o=0;o<n.length;o+=1)0<n[o]&&n[o]<1&&((r=t.point(n[o])[e])<s?s=r:a<r&&(a=r));return{min:s,max:a}}function intersectData(t,e,i){var r=t.boundingBox();return{cx:r.cx,cy:r.cy,width:r.width,height:r.height,bez:t,t:(e+i)/2,t1:e,t2:i}}function splitData(t){var e=t.bez.split(.5);return[intersectData(e[0],t.t1,t.t),intersectData(e[1],t.t,t.t2)]}function boxIntersect(t,e){return 2*Math.abs(t.cx-e.cx)<t.width+e.width&&2*Math.abs(t.cy-e.cy)<t.height+e.height}function intersectsImpl(t,e,i,r,s,a){boxIntersect(t,e)&&(a<=i||t.width<=r&&t.height<=r&&e.width<=r&&e.height<=r?s.push([t.t,e.t]):(t=splitData(t),e=splitData(e),intersectsImpl(t[0],e[0],i+1,r,s,a),intersectsImpl(t[0],e[1],i+1,r,s,a),intersectsImpl(t[1],e[0],i+1,r,s,a),intersectsImpl(t[1],e[1],i+1,r,s,a)))}function crossProduct(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function lineIntersection(t,e,i,r){t=[t[0],t[1],1],e=[e[0],e[1],1],i=[i[0],i[1],1],r=[r[0],r[1],1],t=crossProduct(crossProduct(t,e),crossProduct(i,r));return floatZero(t[2])?null:[t[0]/t[2],t[1]/t[2]]}function polarOffset(t,e,i){return[t[0]+Math.cos(e)*i,t[1]-Math.sin(e)*i]}function pointDistance(t,e){return Math.hypot(t[0]-e[0],t[1]-e[1])}function pointEqual(t,e){return floatEqual(t[0],e[0])&&floatEqual(t[1],e[1])}function ZigZagModifier(){}function setPoint(t,e,i,r,s,a,n){var o=i-Math.PI/2,h=i+Math.PI/2,l=e[0]+Math.cos(i)*r*s,e=e[1]-Math.sin(i)*r*s;t.setTripleAt(l,e,l+Math.cos(o)*a,e-Math.sin(o)*a,l+Math.cos(h)*n,e-Math.sin(h)*n,t.length())}function getPerpendicularVector(t,e){e=[e[0]-t[0],e[1]-t[1]],t=.5*-Math.PI;return[Math.cos(t)*e[0]-Math.sin(t)*e[1],Math.sin(t)*e[0]+Math.cos(t)*e[1]]}function getProjectingAngle(t,e){var i=0===e?t.length()-1:e-1,e=(e+1)%t.length(),i=getPerpendicularVector(t.v[i],t.v[e]);return Math.atan2(0,1)-Math.atan2(i[1],i[0])}function zigZagCorner(t,e,i,r,s,a,n){var o=getProjectingAngle(e,i),h=e.v[i%e._length],l=e.v[0===i?e._length-1:i-1],p=e.v[(i+1)%e._length],l=2===a?Math.sqrt(Math.pow(h[0]-l[0],2)+Math.pow(h[1]-l[1],2)):0,h=2===a?Math.sqrt(Math.pow(h[0]-p[0],2)+Math.pow(h[1]-p[1],2)):0;setPoint(t,e.v[i%e._length],o,n,r,h/(2*(s+1)),l/(2*(s+1)),a)}function zigZagSegment(t,e,i,r,s,a){for(var n=0;n<r;n+=1){var o=(n+1)/(r+1),h=2===s?Math.sqrt(Math.pow(e.points[3][0]-e.points[0][0],2)+Math.pow(e.points[3][1]-e.points[0][1],2)):0,l=e.normalAngle(o);setPoint(t,e.point(o),l,a,i,h/(2*(r+1)),h/(2*(r+1)),s),a=-a}return a}function linearOffset(t,e,i){var r=Math.atan2(e[0]-t[0],e[1]-t[1]);return[polarOffset(t,r,i),polarOffset(e,r,i)]}function offsetSegment(t,e){var i=linearOffset(t.points[0],t.points[1],e),r=i[0],s=i[1],a=(i=linearOffset(t.points[1],t.points[2],e))[0],n=i[1],t=(i=linearOffset(t.points[2],t.points[3],e))[0],e=i[1],i=lineIntersection(r,s,a,n),s=(null===i&&(i=s),lineIntersection(t,e,a,n));return new PolynomialBezier(r,i,s=null===s?t:s,e)}function joinLines(t,e,i,r,s){var a,n,o=e.points[3],h=i.points[0];return 3===r||pointEqual(o,h)?o:2===r?(r=-e.tangentAngle(1),n=-i.tangentAngle(0)+Math.PI,a=lineIntersection(o,polarOffset(o,r+Math.PI/2,100),h,polarOffset(h,r+Math.PI/2,100)),a=polarOffset(o,r,2*(r=a?pointDistance(a,o):pointDistance(o,h)/2)*roundCorner),t.setXYAt(a[0],a[1],"o",t.length()-1),a=polarOffset(h,n,2*r*roundCorner),t.setTripleAt(h[0],h[1],h[0],h[1],a[0],a[1],t.length()),h):(n=lineIntersection(pointEqual(o,e.points[2])?e.points[0]:e.points[2],o,h,pointEqual(h,i.points[1])?i.points[3]:i.points[1]))&&pointDistance(n,o)<s?(t.setTripleAt(n[0],n[1],n[0],n[1],n[0],n[1],t.length()),n):o}function getIntersection(t,e){t=t.intersections(e);return t.length&&floatEqual(t[0][0],1)&&t.shift(),t.length?t[0]:null}function pruneSegmentIntersection(t,e){var i=t.slice(),r=e.slice(),s=getIntersection(t[t.length-1],e[0]);return s&&(i[t.length-1]=t[t.length-1].split(s[0])[0],r[0]=e[0].split(s[1])[1]),1<t.length&&1<e.length&&(s=getIntersection(t[0],e[e.length-1]))?[[t[0].split(s[0])[0]],[e[e.length-1].split(s[1])[1]]]:[i,r]}function pruneIntersections(t){for(var e,i=1;i<t.length;i+=1)e=pruneSegmentIntersection(t[i-1],t[i]),t[i-1]=e[0],t[i]=e[1];return 1<t.length&&(e=pruneSegmentIntersection(t[t.length-1],t[0]),t[t.length-1]=e[0],t[0]=e[1]),t}function offsetSegmentSplit(t,e){var i,r,s,a=t.inflectionPoints();return 0===a.length?[offsetSegment(t,e)]:1===a.length||floatEqual(a[1],1)?(r=(i=t.split(a[0]))[0],s=i[1],[offsetSegment(r,e),offsetSegment(s,e)]):(r=(i=t.split(a[0]))[0],t=(a[1]-a[0])/(1-a[0]),a=(i=i[1].split(t))[0],s=i[1],[offsetSegment(r,e),offsetSegment(a,e),offsetSegment(s,e)])}function OffsetPathModifier(){}function getFontProperties(t){for(var e=t.fStyle?t.fStyle.split(" "):[],i="normal",r="normal",s=e.length,a=0;a<s;a+=1)switch(e[a].toLowerCase()){case"italic":r="italic";break;case"bold":i="700";break;case"black":i="900";break;case"medium":i="500";break;case"regular":case"normal":i="400";break;case"light":case"thin":i="200"}return{style:r,weight:t.fWeight||i}}extendPrototype([ShapeModifier],RepeaterModifier),RepeaterModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.c=PropertyFactory.getProp(t,e.c,0,null,this),this.o=PropertyFactory.getProp(t,e.o,0,null,this),this.tr=TransformPropertyFactory.getTransformProperty(t,e.tr,this),this.so=PropertyFactory.getProp(t,e.tr.so,0,.01,this),this.eo=PropertyFactory.getProp(t,e.tr.eo,0,.01,this),this.data=e,this.dynamicProperties.length||this.getValue(!0),this._isAnimated=!!this.dynamicProperties.length,this.pMatrix=new Matrix,this.rMatrix=new Matrix,this.sMatrix=new Matrix,this.tMatrix=new Matrix,this.matrix=new Matrix},RepeaterModifier.prototype.applyTransforms=function(t,e,i,r,s,a){var n=a?-1:1,o=r.s.v[0]+(1-r.s.v[0])*(1-s),h=r.s.v[1]+(1-r.s.v[1])*(1-s);t.translate(r.p.v[0]*n*s,r.p.v[1]*n*s,r.p.v[2]),e.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),e.rotate(-r.r.v*n*s),e.translate(r.a.v[0],r.a.v[1],r.a.v[2]),i.translate(-r.a.v[0],-r.a.v[1],r.a.v[2]),i.scale(a?1/o:o,a?1/h:h),i.translate(r.a.v[0],r.a.v[1],r.a.v[2])},RepeaterModifier.prototype.init=function(t,e,i,r){for(this.elem=t,this.arr=e,this.pos=i,this.elemsData=r,this._currentCopies=0,this._elements=[],this._groups=[],this.frameId=-1,this.initDynamicPropertyContainer(t),this.initModifierProperties(t,e[i]);0<i;)this._elements.unshift(e[--i]);this.dynamicProperties.length?this.k=!0:this.getValue(!0)},RepeaterModifier.prototype.resetElements=function(t){for(var e=t.length,i=0;i<e;i+=1)t[i]._processed=!1,"gr"===t[i].ty&&this.resetElements(t[i].it)},RepeaterModifier.prototype.cloneElements=function(t){t=JSON.parse(JSON.stringify(t));return this.resetElements(t),t},RepeaterModifier.prototype.changeGroupRender=function(t,e){for(var i=t.length,r=0;r<i;r+=1)t[r]._render=e,"gr"===t[r].ty&&this.changeGroupRender(t[r].it,e)},RepeaterModifier.prototype.processShapes=function(t){var e,i,r,s,a,n=!1;if(this._mdf||t){var o,h=Math.ceil(this.c.v);if(this._groups.length<h){for(;this._groups.length<h;){var l={it:this.cloneElements(this._elements),ty:"gr"};l.it.push({a:{a:0,ix:1,k:[0,0]},nm:"Transform",o:{a:0,ix:7,k:100},p:{a:0,ix:2,k:[0,0]},r:{a:1,ix:6,k:[{s:0,e:0,t:0},{s:0,e:0,t:1}]},s:{a:0,ix:3,k:[100,100]},sa:{a:0,ix:5,k:0},sk:{a:0,ix:4,k:0},ty:"tr"}),this.arr.splice(0,0,l),this._groups.splice(0,0,l),this._currentCopies+=1}this.elem.reloadShapes(),n=!0}for(r=a=0;r<=this._groups.length-1;r+=1)this._groups[r]._render=o=a<h,this.changeGroupRender(this._groups[r].it,o),o||(0!==(o=(o=this.elemsData[r].it)[o.length-1]).transform.op.v?(o.transform.op._mdf=!0,o.transform.op.v=0):o.transform.op._mdf=!1),a+=1;this._currentCopies=h;var p,m,t=this.o.v,f=t%1,c=0<t?Math.floor(t):Math.ceil(t),d=this.pMatrix.props,u=this.rMatrix.props,y=this.sMatrix.props,g=(this.pMatrix.reset(),this.rMatrix.reset(),this.sMatrix.reset(),this.tMatrix.reset(),this.matrix.reset(),0);if(0<t){for(;g<c;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),g+=1;f&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,f,!1),g+=f)}else if(t<0){for(;c<g;)this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!0),--g;f&&(this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,-f,!0),g-=f)}for(r=1===this.data.m?0:this._currentCopies-1,s=1===this.data.m?1:-1,a=this._currentCopies;a;){if(m=(i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props).length,e[e.length-1].transform.mProps._mdf=!0,e[e.length-1].transform.op._mdf=!0,e[e.length-1].transform.op.v=1===this._currentCopies?this.so.v:this.so.v+(this.eo.v-this.so.v)*(r/(this._currentCopies-1)),0!==g){for((0!==r&&1===s||r!==this._currentCopies-1&&-1===s)&&this.applyTransforms(this.pMatrix,this.rMatrix,this.sMatrix,this.tr,1,!1),this.matrix.transform(u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]),this.matrix.transform(y[0],y[1],y[2],y[3],y[4],y[5],y[6],y[7],y[8],y[9],y[10],y[11],y[12],y[13],y[14],y[15]),this.matrix.transform(d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9],d[10],d[11],d[12],d[13],d[14],d[15]),p=0;p<m;p+=1)i[p]=this.matrix.props[p];this.matrix.reset()}else for(this.matrix.reset(),p=0;p<m;p+=1)i[p]=this.matrix.props[p];g+=1,--a,r+=s}}else for(a=this._currentCopies,r=0,s=1;a;)i=(e=this.elemsData[r].it)[e.length-1].transform.mProps.v.props,e[e.length-1].transform.mProps._mdf=!1,e[e.length-1].transform.op._mdf=!1,--a,r+=s;return n},RepeaterModifier.prototype.addShape=function(){},extendPrototype([ShapeModifier],RoundCornersModifier),RoundCornersModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.rd=PropertyFactory.getProp(t,e.r,0,null,this),this._isAnimated=!!this.rd.effectsSequence.length},RoundCornersModifier.prototype.processPath=function(t,e){for(var i,r,s,a,n,o,h,l,p,m,f=shapePool.newElement(),c=(f.c=t.c,t._length),d=0,u=0;u<c;u+=1)i=t.v[u],s=t.o[u],r=t.i[u],i[0]===s[0]&&i[1]===s[1]&&i[0]===r[0]&&i[1]===r[1]?0!==u&&u!==c-1||t.c?(a=0===u?t.v[c-1]:t.v[u-1],o=(n=Math.sqrt(Math.pow(i[0]-a[0],2)+Math.pow(i[1]-a[1],2)))?Math.min(n/2,e)/n:0,p=i[0]+(a[0]-i[0])*o,m=i[1]-(i[1]-a[1])*o,h=p-(p-i[0])*roundCorner,l=m-(m-i[1])*roundCorner,f.setTripleAt(p,m,h,l,p,m,d),d+=1,a=u===c-1?t.v[0]:t.v[u+1],o=(n=Math.sqrt(Math.pow(i[0]-a[0],2)+Math.pow(i[1]-a[1],2)))?Math.min(n/2,e)/n:0,h=i[0]+(a[0]-i[0])*o,l=i[1]+(a[1]-i[1])*o,p=h-(h-i[0])*roundCorner,m=l-(l-i[1])*roundCorner,f.setTripleAt(h,l,h,l,p,m,d)):f.setTripleAt(i[0],i[1],s[0],s[1],r[0],r[1],d):f.setTripleAt(t.v[u][0],t.v[u][1],t.o[u][0],t.o[u][1],t.i[u][0],t.i[u][1],d),d+=1;return f},RoundCornersModifier.prototype.processShapes=function(t){var e,i,r,s=this.shapes.length,a=this.rd.v;if(0!==a)for(var n,o,h=0;h<s;h+=1){if(o=(n=this.shapes[h]).localShapeCollection,n.shape._mdf||this._mdf||t)for(o.releaseShapes(),n.shape._mdf=!0,e=n.shape.paths.shapes,r=n.shape.paths._length,i=0;i<r;i+=1)o.addShape(this.processPath(e[i],a));n.shape.paths=n.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},PolynomialBezier.prototype.point=function(t){return[((this.a[0]*t+this.b[0])*t+this.c[0])*t+this.d[0],((this.a[1]*t+this.b[1])*t+this.c[1])*t+this.d[1]]},PolynomialBezier.prototype.derivative=function(t){return[(3*t*this.a[0]+2*this.b[0])*t+this.c[0],(3*t*this.a[1]+2*this.b[1])*t+this.c[1]]},PolynomialBezier.prototype.tangentAngle=function(t){t=this.derivative(t);return Math.atan2(t[1],t[0])},PolynomialBezier.prototype.normalAngle=function(t){t=this.derivative(t);return Math.atan2(t[0],t[1])},PolynomialBezier.prototype.inflectionPoints=function(){var t,e=this.a[1]*this.b[0]-this.a[0]*this.b[1];return floatZero(e)||(e=(t=-.5*(this.a[1]*this.c[0]-this.a[0]*this.c[1])/e)*t-1/3*(this.b[1]*this.c[0]-this.b[0]*this.c[1])/e)<0?[]:floatZero(e=Math.sqrt(e))?0<e&&e<1?[t]:[]:[t-e,t+e].filter(function(t){return 0<t&&t<1})},PolynomialBezier.prototype.split=function(t){var e,i,r,s;return t<=0?[singlePoint(this.points[0]),this]:1<=t?[this,singlePoint(this.points[this.points.length-1])]:(e=lerpPoint(this.points[0],this.points[1],t),s=lerpPoint(this.points[1],this.points[2],t),i=lerpPoint(this.points[2],this.points[3],t),r=lerpPoint(e,s,t),s=lerpPoint(s,i,t),t=lerpPoint(r,s,t),[new PolynomialBezier(this.points[0],e,r,t,!0),new PolynomialBezier(t,s,i,this.points[3],!0)])},PolynomialBezier.prototype.bounds=function(){return{x:extrema(this,0),y:extrema(this,1)}},PolynomialBezier.prototype.boundingBox=function(){var t=this.bounds();return{left:t.x.min,right:t.x.max,top:t.y.min,bottom:t.y.max,width:t.x.max-t.x.min,height:t.y.max-t.y.min,cx:(t.x.max+t.x.min)/2,cy:(t.y.max+t.y.min)/2}},PolynomialBezier.prototype.intersections=function(t,e,i){void 0===e&&(e=2),void 0===i&&(i=7);var r=[];return intersectsImpl(intersectData(this,0,1),intersectData(t,0,1),0,e,r,i),r},PolynomialBezier.shapeSegment=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[e],t.o[e],t.i[i],t.v[i],!0)},PolynomialBezier.shapeSegmentInverted=function(t,e){var i=(e+1)%t.length();return new PolynomialBezier(t.v[i],t.i[i],t.o[e],t.v[e],!0)},extendPrototype([ShapeModifier],ZigZagModifier),ZigZagModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amplitude=PropertyFactory.getProp(t,e.s,0,null,this),this.frequency=PropertyFactory.getProp(t,e.r,0,null,this),this.pointsType=PropertyFactory.getProp(t,e.pt,0,null,this),this._isAnimated=0!==this.amplitude.effectsSequence.length||0!==this.frequency.effectsSequence.length||0!==this.pointsType.effectsSequence.length},ZigZagModifier.prototype.processPath=function(t,e,i,r){var s=t._length,a=shapePool.newElement();if(a.c=t.c,t.c||--s,0!==s){var n=-1,o=PolynomialBezier.shapeSegment(t,0);zigZagCorner(a,t,0,e,i,r,n);for(var h=0;h<s;h+=1)n=zigZagSegment(a,o,e,i,r,-n),o=h!==s-1||t.c?PolynomialBezier.shapeSegment(t,(h+1)%s):null,zigZagCorner(a,t,h+1,e,i,r,n)}return a},ZigZagModifier.prototype.processShapes=function(t){var e,i,r,s=this.shapes.length,a=this.amplitude.v,n=Math.max(0,Math.round(this.frequency.v)),o=this.pointsType.v;if(0!==a)for(var h,l,p=0;p<s;p+=1){if(l=(h=this.shapes[p]).localShapeCollection,h.shape._mdf||this._mdf||t)for(l.releaseShapes(),h.shape._mdf=!0,e=h.shape.paths.shapes,r=h.shape.paths._length,i=0;i<r;i+=1)l.addShape(this.processPath(e[i],a,n,o));h.shape.paths=h.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)},extendPrototype([ShapeModifier],OffsetPathModifier),OffsetPathModifier.prototype.initModifierProperties=function(t,e){this.getValue=this.processKeys,this.amount=PropertyFactory.getProp(t,e.a,0,null,this),this.miterLimit=PropertyFactory.getProp(t,e.ml,0,null,this),this.lineJoin=e.lj,this._isAnimated=0!==this.amount.effectsSequence.length},OffsetPathModifier.prototype.processPath=function(t,e,i,r){for(var s,a,n=shapePool.newElement(),o=(n.c=t.c,t.length()),h=(t.c||--o,[]),l=0;l<o;l+=1)a=PolynomialBezier.shapeSegment(t,l),h.push(offsetSegmentSplit(a,e));if(!t.c)for(l=o-1;0<=l;--l)a=PolynomialBezier.shapeSegmentInverted(t,l),h.push(offsetSegmentSplit(a,e));var h=pruneIntersections(h),p=null,m=null;for(l=0;l<h.length;l+=1){var f=h[l];for(m&&(p=joinLines(n,m,f[0],i,r)),m=f[f.length-1],s=0;s<f.length;s+=1)a=f[s],p&&pointEqual(a.points[0],p)?n.setXYAt(a.points[1][0],a.points[1][1],"o",n.length()-1):n.setTripleAt(a.points[0][0],a.points[0][1],a.points[1][0],a.points[1][1],a.points[0][0],a.points[0][1],n.length()),n.setTripleAt(a.points[3][0],a.points[3][1],a.points[3][0],a.points[3][1],a.points[2][0],a.points[2][1],n.length()),p=a.points[3]}return h.length&&joinLines(n,m,h[0][0],i,r),n},OffsetPathModifier.prototype.processShapes=function(t){var e,i,r,s=this.shapes.length,a=this.amount.v,n=this.miterLimit.v,o=this.lineJoin;if(0!==a)for(var h,l,p=0;p<s;p+=1){if(l=(h=this.shapes[p]).localShapeCollection,h.shape._mdf||this._mdf||t)for(l.releaseShapes(),h.shape._mdf=!0,e=h.shape.paths.shapes,r=h.shape.paths._length,i=0;i<r;i+=1)l.addShape(this.processPath(e[i],a,o,n));h.shape.paths=h.localShapeCollection}this.dynamicProperties.length||(this._mdf=!1)};var FontManager=(()=>{var a=5e3,n={w:0,size:0,shapes:[],data:{shapes:[]}},e=(e=[]).concat([2304,2305,2306,2307,2362,2363,2364,2364,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2387,2388,2389,2390,2391,2402,2403]),s=127988,o=917631,h=917601,l=917626,i=65039,r=8205,p=127462,m=127487,f=["d83cdffb","d83cdffc","d83cdffd","d83cdffe","d83cdfff"];function c(t,e){var i=createTag("span"),r=(i.setAttribute("aria-hidden",!0),i.style.fontFamily=e,createTag("span")),s=(r.innerText="giItT1WQy@!-/#",i.style.position="absolute",i.style.left="-10000px",i.style.top="-10000px",i.style.fontSize="300px",i.style.fontVariant="normal",i.style.fontStyle="normal",i.style.fontWeight="normal",i.style.letterSpacing="0",i.appendChild(r),document.body.appendChild(i),r.offsetWidth);return r.style.fontFamily=(t=>{for(var e=t.split(","),i=e.length,r=[],s=0;s<i;s+=1)"sans-serif"!==e[s]&&"monospace"!==e[s]&&r.push(e[s]);return r.join(",")})(t)+", "+e,{node:r,w:s,parent:i}}function d(t,e){var i,r,s=document.body&&e?"svg":"canvas",a=getFontProperties(t);return i="svg"==s?((r=createNS("text")).style.fontSize="100px",r.setAttribute("font-family",t.fFamily),r.setAttribute("font-style",a.style),r.setAttribute("font-weight",a.weight),r.textContent="1",t.fClass?(r.style.fontFamily="inherit",r.setAttribute("class",t.fClass)):r.style.fontFamily=t.fFamily,e.appendChild(r),r):((e=new OffscreenCanvas(500,500).getContext("2d")).font=a.style+" "+a.weight+" 100px "+t.fFamily,e),{measureText:function(t){return"svg"==s?(i.textContent=t,i.getComputedTextLength()):i.measureText(t).width}}}function u(t){var e=0,i=t.charCodeAt(0);return e=55296<=i&&i<=56319&&56320<=(t=t.charCodeAt(1))&&t<=57343?1024*(i-55296)+t-56320+65536:e}function y(t){t=u(t);return p<=t&&t<=m}function t(){this.fonts=[],this.chars=null,this.typekitLoaded=0,this.isLoaded=!1,this._warned=!1,this.initTime=Date.now(),this.setIsLoadedBinded=this.setIsLoaded.bind(this),this.checkLoadedFontsBinded=this.checkLoadedFonts.bind(this)}return t.isModifier=function(t,e){return t=t.toString(16)+e.toString(16),-1!==f.indexOf(t)},t.isZeroWidthJoiner=function(t){return t===r},t.isFlagEmoji=function(t){return y(t.substr(0,2))&&y(t.substr(2,2))},t.isRegionalCode=y,t.isCombinedCharacter=function(t){return-1!==e.indexOf(t)},t.isRegionalFlag=function(t,e){var i;if(u(t.substr(e,2))!==s)return!1;var r=0;for(e+=2;r<5;){if((i=u(t.substr(e,2)))<h||l<i)return!1;r+=1,e+=2}return u(t.substr(e,2))===o},t.isVariationSelector=function(t){return t===i},t.BLACK_FLAG_CODE_POINT=s,t.prototype={addChars:function(t){if(t){this.chars||(this.chars=[]);for(var e,i,r=t.length,s=this.chars.length,a=0;a<r;a+=1){for(e=0,i=!1;e<s;)this.chars[e].style===t[a].style&&this.chars[e].fFamily===t[a].fFamily&&this.chars[e].ch===t[a].ch&&(i=!0),e+=1;i||(this.chars.push(t[a]),s+=1)}}},addFonts:function(t,e){if(t)if(this.chars)this.isLoaded=!0,this.fonts=t.list;else if(document.body){for(var i=t.list,r=i.length,s=r,a=0;a<r;a+=1){var n,o,h,l,p=!0;if(i[a].loaded=!1,i[a].monoCase=c(i[a].fFamily,"monospace"),i[a].sansCase=c(i[a].fFamily,"sans-serif"),i[a].fPath){if("p"===i[a].fOrigin||3===i[a].origin)(p=0<(o=document.querySelectorAll('style[f-forigin="p"][f-family="'+i[a].fFamily+'"], style[f-origin="3"][f-family="'+i[a].fFamily+'"]')).length?!1:p)&&((h=createTag("style")).setAttribute("f-forigin",i[a].fOrigin),h.setAttribute("f-origin",i[a].origin),h.setAttribute("f-family",i[a].fFamily),h.type="text/css",h.innerText="@font-face {font-family: "+i[a].fFamily+"; font-style: normal; src: url('"+i[a].fPath+"');}",e.appendChild(h));else if("g"===i[a].fOrigin||1===i[a].origin){for(o=document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'),n=0;n<o.length;n+=1)-1!==o[n].href.indexOf(i[a].fPath)&&(p=!1);p&&((h=createTag("link")).setAttribute("f-forigin",i[a].fOrigin),h.setAttribute("f-origin",i[a].origin),h.type="text/css",h.rel="stylesheet",h.href=i[a].fPath,document.body.appendChild(h))}else if("t"===i[a].fOrigin||2===i[a].origin){for(o=document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'),n=0;n<o.length;n+=1)i[a].fPath===o[n].src&&(p=!1);p&&((l=createTag("link")).setAttribute("f-forigin",i[a].fOrigin),l.setAttribute("f-origin",i[a].origin),l.setAttribute("rel","stylesheet"),l.setAttribute("href",i[a].fPath),e.appendChild(l))}}else i[a].loaded=!0,--s;i[a].helper=d(i[a],e),i[a].cache={},this.fonts.push(i[a])}0===s?this.isLoaded=!0:setTimeout(this.checkLoadedFonts.bind(this),100)}else this.isLoaded=!0,t.list.forEach(function(t){t.helper=d(t),t.cache={}}),this.fonts=t.list;else this.isLoaded=!0},getCharData:function(t,e,i){for(var r=0,s=this.chars.length;r<s;){if(this.chars[r].ch===t&&this.chars[r].style===e&&this.chars[r].fFamily===i)return this.chars[r];r+=1}return("string"==typeof t&&13!==t.charCodeAt(0)||!t)&&console&&console.warn&&!this._warned&&(this._warned=!0,console.warn("Missing character from exported characters list: ",t,e,i)),n},getFontByName:function(t){for(var e=0,i=this.fonts.length;e<i;){if(this.fonts[e].fName===t)return this.fonts[e];e+=1}return this.fonts[0]},measureText:function(t,e,i){var r,s,a,e=this.getFontByName(e),n=t;return e.cache[n]||(r=e.helper," "===t?(s=r.measureText("|"+t+"|"),a=r.measureText("||"),e.cache[n]=(s-a)/100):e.cache[n]=r.measureText(t)/100),e.cache[n]*i},checkLoadedFonts:function(){for(var t,e,i=this.fonts.length,r=i,s=0;s<i;s+=1)this.fonts[s].loaded?--r:"n"===this.fonts[s].fOrigin||0===this.fonts[s].origin?this.fonts[s].loaded=!0:(t=this.fonts[s].monoCase.node,e=this.fonts[s].monoCase.w,t.offsetWidth===e&&(t=this.fonts[s].sansCase.node,e=this.fonts[s].sansCase.w,t.offsetWidth===e)||(--r,this.fonts[s].loaded=!0),this.fonts[s].loaded&&(this.fonts[s].sansCase.parent.parentNode.removeChild(this.fonts[s].sansCase.parent),this.fonts[s].monoCase.parent.parentNode.removeChild(this.fonts[s].monoCase.parent)));0!==r&&Date.now()-this.initTime<a?setTimeout(this.checkLoadedFontsBinded,20):setTimeout(this.setIsLoadedBinded,10)},setIsLoaded:function(){this.isLoaded=!0}},t})();function SlotManager(t){this.animationData=t}function slotFactory(t){return new SlotManager(t)}function RenderableElement(){}SlotManager.prototype.getProp=function(t){return this.animationData.slots&&this.animationData.slots[t.sid]?Object.assign(t,this.animationData.slots[t.sid].p):t},RenderableElement.prototype={initRenderable:function(){this.isInRange=!1,this.hidden=!1,this.isTransparent=!1,this.renderableComponents=[]},addRenderableComponent:function(t){-1===this.renderableComponents.indexOf(t)&&this.renderableComponents.push(t)},removeRenderableComponent:function(t){-1!==this.renderableComponents.indexOf(t)&&this.renderableComponents.splice(this.renderableComponents.indexOf(t),1)},prepareRenderableFrame:function(t){this.checkLayerLimits(t)},checkTransparency:function(){this.finalTransform.mProp.o.v<=0?!this.isTransparent&&this.globalData.renderConfig.hideOnTransparent&&(this.isTransparent=!0,this.hide()):this.isTransparent&&(this.isTransparent=!1,this.show())},checkLayerLimits:function(t){this.data.ip-this.data.st<=t&&this.data.op-this.data.st>t?!0!==this.isInRange&&(this.globalData._mdf=!0,this._mdf=!0,this.isInRange=!0,this.show()):!1!==this.isInRange&&(this.globalData._mdf=!0,this.isInRange=!1,this.hide())},renderRenderable:function(){for(var t=this.renderableComponents.length,e=0;e<t;e+=1)this.renderableComponents[e].renderFrame(this._isFirstFrame)},sourceRectAtTime:function(){return{top:0,left:0,width:100,height:100}},getLayerSize:function(){return 5===this.data.ty?{w:this.data.textData.width,h:this.data.textData.height}:{w:this.data.width,h:this.data.height}}};var getBlendMode=(()=>{var e={0:"source-over",1:"multiply",2:"screen",3:"overlay",4:"darken",5:"lighten",6:"color-dodge",7:"color-burn",8:"hard-light",9:"soft-light",10:"difference",11:"exclusion",12:"hue",13:"saturation",14:"color",15:"luminosity"};return function(t){return e[t]||""}})();function SliderEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function AngleEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function ColorEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function PointEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,1,0,i)}function LayerIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function MaskIndexEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function CheckboxEffect(t,e,i){this.p=PropertyFactory.getProp(e,t.v,0,0,i)}function NoValueEffect(){this.p={}}function EffectsManager(t,e){for(var i,r=t.ef||[],s=(this.effectElements=[],r.length),a=0;a<s;a+=1)i=new GroupEffect(r[a],e),this.effectElements.push(i)}function GroupEffect(t,e){this.init(t,e)}function BaseElement(){}function FrameElement(){}function FootageElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.footageData=e.imageLoader.getAsset(this.assetData),this.initBaseData(t,e,i)}function AudioElement(t,e,i){this.initFrame(),this.initRenderable(),this.assetData=e.getAssetData(t.refId),this.initBaseData(t,e,i),this._isPlaying=!1,this._canPlay=!1;i=this.globalData.getAssetsPath(this.assetData);this.audio=this.globalData.audioController.createAudio(i),this._currentTime=0,this.globalData.audioController.addAudio(this),this._volumeMultiplier=1,this._volume=1,this._previousVolume=null,this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0},this.lv=PropertyFactory.getProp(this,t.au&&t.au.lv?t.au.lv:{k:[100]},1,.01,this)}function BaseRenderer(){}extendPrototype([DynamicPropertyContainer],GroupEffect),GroupEffect.prototype.getValue=GroupEffect.prototype.iterateDynamicProperties,GroupEffect.prototype.init=function(t,e){this.data=t,this.effectElements=[],this.initDynamicPropertyContainer(e);for(var i,r=this.data.ef.length,s=this.data.ef,a=0;a<r;a+=1){switch(i=null,s[a].ty){case 0:i=new SliderEffect(s[a],e,this);break;case 1:i=new AngleEffect(s[a],e,this);break;case 2:i=new ColorEffect(s[a],e,this);break;case 3:i=new PointEffect(s[a],e,this);break;case 4:case 7:i=new CheckboxEffect(s[a],e,this);break;case 10:i=new LayerIndexEffect(s[a],e,this);break;case 11:i=new MaskIndexEffect(s[a],e,this);break;case 5:i=new EffectsManager(s[a],e,this);break;default:i=new NoValueEffect(s[a],e,this)}i&&this.effectElements.push(i)}},BaseElement.prototype={checkMasks:function(){if(this.data.hasMask)for(var t=0,e=this.data.masksProperties.length;t<e;){if("n"!==this.data.masksProperties[t].mode&&!1!==this.data.masksProperties[t].cl)return!0;t+=1}return!1},initExpressions:function(){var t,e,i,r,s=getExpressionInterfaces();s&&(r=s("layer"),t=s("effects"),e=s("shape"),i=s("text"),s=s("comp"),this.layerInterface=r(this),this.data.hasMask&&this.maskManager&&this.layerInterface.registerMaskInterface(this.maskManager),r=t.createEffectsInterface(this,this.layerInterface),this.layerInterface.registerEffectsInterface(r),0===this.data.ty||this.data.xt?this.compInterface=s(this):4===this.data.ty?(this.layerInterface.shapeInterface=e(this.shapesData,this.itemsData,this.layerInterface),this.layerInterface.content=this.layerInterface.shapeInterface):5===this.data.ty&&(this.layerInterface.textInterface=i(this),this.layerInterface.text=this.layerInterface.textInterface))},setBlendMode:function(){var t=getBlendMode(this.data.bm);(this.baseElement||this.layerElement).style["mix-blend-mode"]=t},initBaseData:function(t,e,i){this.globalData=e,this.comp=i,this.data=t,this.layerId=createElementID(),this.data.sr||(this.data.sr=1),this.effectsManager=new EffectsManager(this.data,this,this.dynamicProperties)},getType:function(){return this.type},sourceRectAtTime:function(){}},FrameElement.prototype={initFrame:function(){this._isFirstFrame=!1,this.dynamicProperties=[],this._mdf=!1},prepareProperties:function(t,e){for(var i=this.dynamicProperties.length,r=0;r<i;r+=1)(e||this._isParent&&"transform"===this.dynamicProperties[r].propType)&&(this.dynamicProperties[r].getValue(),this.dynamicProperties[r]._mdf)&&(this.globalData._mdf=!0,this._mdf=!0)},addDynamicProperty:function(t){-1===this.dynamicProperties.indexOf(t)&&this.dynamicProperties.push(t)}},FootageElement.prototype.prepareFrame=function(){},extendPrototype([RenderableElement,BaseElement,FrameElement],FootageElement),FootageElement.prototype.getBaseElement=function(){return null},FootageElement.prototype.renderFrame=function(){},FootageElement.prototype.destroy=function(){},FootageElement.prototype.initExpressions=function(){var t=getExpressionInterfaces();t&&(t=t("footage"),this.layerInterface=t(this))},FootageElement.prototype.getFootageData=function(){return this.footageData},AudioElement.prototype.prepareFrame=function(t){this.prepareRenderableFrame(t,!0),this.prepareProperties(t,!0),this.tm._placeholder?this._currentTime=t/this.data.sr:(t=this.tm.v,this._currentTime=t),this._volume=this.lv.v[0];t=this._volume*this._volumeMultiplier;this._previousVolume!==t&&(this._previousVolume=t,this.audio.volume(t))},extendPrototype([RenderableElement,BaseElement,FrameElement],AudioElement),AudioElement.prototype.renderFrame=function(){this.isInRange&&this._canPlay&&(this._isPlaying?(!this.audio.playing()||.1<Math.abs(this._currentTime/this.globalData.frameRate-this.audio.seek()))&&this.audio.seek(this._currentTime/this.globalData.frameRate):(this.audio.play(),this.audio.seek(this._currentTime/this.globalData.frameRate),this._isPlaying=!0))},AudioElement.prototype.show=function(){},AudioElement.prototype.hide=function(){this.audio.pause(),this._isPlaying=!1},AudioElement.prototype.pause=function(){this.audio.pause(),this._isPlaying=!1,this._canPlay=!1},AudioElement.prototype.resume=function(){this._canPlay=!0},AudioElement.prototype.setRate=function(t){this.audio.rate(t)},AudioElement.prototype.volume=function(t){this._volumeMultiplier=t,this._previousVolume=t*this._volume,this.audio.volume(this._previousVolume)},AudioElement.prototype.getBaseElement=function(){return null},AudioElement.prototype.destroy=function(){},AudioElement.prototype.sourceRectAtTime=function(){},AudioElement.prototype.initExpressions=function(){},BaseRenderer.prototype.checkLayers=function(t){var e,i,r=this.layers.length;for(this.completeLayers=!0,e=r-1;0<=e;--e)this.elements[e]||(i=this.layers[e]).ip-i.st<=t-this.layers[e].st&&i.op-i.st>t-this.layers[e].st&&this.buildItem(e),this.completeLayers=!!this.elements[e]&&this.completeLayers;this.checkPendingElements()},BaseRenderer.prototype.createItem=function(t){switch(t.ty){case 2:return this.createImage(t);case 0:return this.createComp(t);case 1:return this.createSolid(t);case 3:return this.createNull(t);case 4:return this.createShape(t);case 5:return this.createText(t);case 6:return this.createAudio(t);case 13:return this.createCamera(t);case 15:return this.createFootage(t);default:return this.createNull(t)}},BaseRenderer.prototype.createCamera=function(){throw new Error("You're using a 3d camera. Try the html renderer.")},BaseRenderer.prototype.createAudio=function(t){return new AudioElement(t,this.globalData,this)},BaseRenderer.prototype.createFootage=function(t){return new FootageElement(t,this.globalData,this)},BaseRenderer.prototype.buildAllItems=function(){for(var t=this.layers.length,e=0;e<t;e+=1)this.buildItem(e);this.checkPendingElements()},BaseRenderer.prototype.includeLayers=function(t){this.completeLayers=!1;for(var e,i=t.length,r=this.layers.length,s=0;s<i;s+=1)for(e=0;e<r;){if(this.layers[e].id===t[s].id){this.layers[e]=t[s];break}e+=1}},BaseRenderer.prototype.setProjectInterface=function(t){this.globalData.projectInterface=t},BaseRenderer.prototype.initItems=function(){this.globalData.progressiveLoad||this.buildAllItems()},BaseRenderer.prototype.buildElementParenting=function(t,e,i){for(var r=this.elements,s=this.layers,a=0,n=s.length;a<n;)s[a].ind==e&&(r[a]&&!0!==r[a]?(i.push(r[a]),r[a].setAsParent(),void 0!==s[a].parent?this.buildElementParenting(t,s[a].parent,i):t.setHierarchy(i)):(this.buildItem(a),this.addPendingElement(t))),a+=1},BaseRenderer.prototype.addPendingElement=function(t){this.pendingElements.push(t)},BaseRenderer.prototype.searchExtraCompositions=function(t){for(var e,i=t.length,r=0;r<i;r+=1)t[r].xt&&((e=this.createComp(t[r])).initExpressions(),this.globalData.projectInterface.registerComposition(e))},BaseRenderer.prototype.getElementById=function(t){for(var e=this.elements.length,i=0;i<e;i+=1)if(this.elements[i].data.ind===t)return this.elements[i];return null},BaseRenderer.prototype.getElementByPath=function(t){var e,i=t.shift();if("number"==typeof i)e=this.elements[i];else for(var r=this.elements.length,s=0;s<r;s+=1)if(this.elements[s].data.nm===i){e=this.elements[s];break}return 0===t.length?e:e.getElementByPath(t)},BaseRenderer.prototype.setupGlobalData=function(t,e){this.globalData.fontManager=new FontManager,this.globalData.slotManager=slotFactory(t),this.globalData.fontManager.addChars(t.chars),this.globalData.fontManager.addFonts(t.fonts,e),this.globalData.getAssetData=this.animationItem.getAssetData.bind(this.animationItem),this.globalData.getAssetsPath=this.animationItem.getAssetsPath.bind(this.animationItem),this.globalData.imageLoader=this.animationItem.imagePreloader,this.globalData.audioController=this.animationItem.audioController,this.globalData.frameId=0,this.globalData.frameRate=t.fr,this.globalData.nm=t.nm,this.globalData.compSize={w:t.w,h:t.h}};var effectTypes={TRANSFORM_EFFECT:"transformEFfect"};function TransformElement(){}function MaskElement(t,e,i){this.data=t,this.element=e,this.globalData=i,this.storedData=[],this.masksProperties=this.data.masksProperties||[],this.maskElement=null;for(var r,s,a,n,o,h=this.globalData.defs,l=this.masksProperties?this.masksProperties.length:0,p=(this.viewData=createSizedArray(l),this.solidPath="",this.masksProperties),m=0,f=[],c=createElementID(),d="clipPath",u="clip-path",y=0;y<l;y+=1)if(("a"!==p[y].mode&&"n"!==p[y].mode||p[y].inv||100!==p[y].o.k||p[y].o.x)&&(u=d="mask"),"s"!==p[y].mode&&"i"!==p[y].mode||0!==m?s=null:((s=createNS("rect")).setAttribute("fill","#ffffff"),s.setAttribute("width",this.element.comp.data.w||0),s.setAttribute("height",this.element.comp.data.h||0),f.push(s)),r=createNS("path"),"n"===p[y].mode)this.viewData[y]={op:PropertyFactory.getProp(this.element,p[y].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,p[y],3),elem:r,lastPath:""},h.appendChild(r);else{if(m+=1,r.setAttribute("fill","s"===p[y].mode?"#000000":"#ffffff"),r.setAttribute("clip-rule","nonzero"),0!==p[y].x.k?(u=d="mask",n=PropertyFactory.getProp(this.element,p[y].x,0,null,this.element),o=createElementID(),(x=createNS("filter")).setAttribute("id",o),(a=createNS("feMorphology")).setAttribute("operator","erode"),a.setAttribute("in","SourceGraphic"),a.setAttribute("radius","0"),x.appendChild(a),h.appendChild(x),r.setAttribute("stroke","s"===p[y].mode?"#000000":"#ffffff")):n=a=null,this.storedData[y]={elem:r,x:n,expan:a,lastPath:"",lastOperator:"",filterId:o,lastRadius:0},"i"===p[y].mode){for(var g=f.length,v=createNS("g"),b=0;b<g;b+=1)v.appendChild(f[b]);var x=createNS("mask");x.setAttribute("mask-type","alpha"),x.setAttribute("id",c+"_"+m),x.appendChild(r),h.appendChild(x),v.setAttribute("mask","url("+getLocationHref()+"#"+c+"_"+m+")"),f.length=0,f.push(v)}else f.push(r);p[y].inv&&!this.solidPath&&(this.solidPath=this.createLayerSolidPath()),this.viewData[y]={elem:r,lastPath:"",op:PropertyFactory.getProp(this.element,p[y].o,0,.01,this.element),prop:ShapePropertyFactory.getShapeProp(this.element,p[y],3),invRect:s},this.viewData[y].prop.k||this.drawPath(p[y],this.viewData[y].prop.v,this.viewData[y])}for(this.maskElement=createNS(d),l=f.length,y=0;y<l;y+=1)this.maskElement.appendChild(f[y]);0<m&&(this.maskElement.setAttribute("id",c),this.element.maskedElement.setAttribute(u,"url("+getLocationHref()+"#"+c+")"),h.appendChild(this.maskElement)),this.viewData.length&&this.element.addRenderableComponent(this)}TransformElement.prototype={initTransform:function(){var t=new Matrix;this.finalTransform={mProp:this.data.ks?TransformPropertyFactory.getTransformProperty(this,this.data.ks,this):{o:0},_matMdf:!1,_localMatMdf:!1,_opMdf:!1,mat:t,localMat:t,localOpacity:1},this.data.ao&&(this.finalTransform.mProp.autoOriented=!0),this.data.ty},renderTransform:function(){if(this.finalTransform._opMdf=this.finalTransform.mProp.o._mdf||this._isFirstFrame,this.finalTransform._matMdf=this.finalTransform.mProp._mdf||this._isFirstFrame,this.hierarchy){var t,e=this.finalTransform.mat,i=0,r=this.hierarchy.length;if(!this.finalTransform._matMdf)for(;i<r;){if(this.hierarchy[i].finalTransform.mProp._mdf){this.finalTransform._matMdf=!0;break}i+=1}if(this.finalTransform._matMdf)for(t=this.finalTransform.mProp.v.props,e.cloneFromProps(t),i=0;i<r;i+=1)e.multiply(this.hierarchy[i].finalTransform.mProp.v)}this.localTransforms&&!this.finalTransform._matMdf||(this.finalTransform._localMatMdf=this.finalTransform._matMdf),this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v)},renderLocalTransform:function(){if(this.localTransforms){var t=0,e=this.localTransforms.length;if(this.finalTransform._localMatMdf=this.finalTransform._matMdf,!this.finalTransform._localMatMdf||!this.finalTransform._opMdf)for(;t<e;)this.localTransforms[t]._mdf&&(this.finalTransform._localMatMdf=!0),this.localTransforms[t]._opMdf&&!this.finalTransform._opMdf&&(this.finalTransform.localOpacity=this.finalTransform.mProp.o.v,this.finalTransform._opMdf=!0),t+=1;if(this.finalTransform._localMatMdf){var i=this.finalTransform.localMat;for(this.localTransforms[0].matrix.clone(i),t=1;t<e;t+=1){var r=this.localTransforms[t].matrix;i.multiply(r)}i.multiply(this.finalTransform.mat)}if(this.finalTransform._opMdf){for(var s=this.finalTransform.localOpacity,t=0;t<e;t+=1)s*=.01*this.localTransforms[t].opacity;this.finalTransform.localOpacity=s}}},searchEffectTransforms:function(){if(this.renderableEffectsManager){var t=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);if(t.length){this.localTransforms=[],this.finalTransform.localMat=new Matrix;for(var e=0,i=t.length,e=0;e<i;e+=1)this.localTransforms.push(t[e])}}},globalToLocal:function(t){for(var e=[],i=(e.push(this.finalTransform),!0),r=this.comp;i;)r.finalTransform?(r.data.hasMask&&e.splice(0,0,r.finalTransform),r=r.comp):i=!1;for(var s,a=e.length,n=0;n<a;n+=1)s=e[n].mat.applyToPointArray(0,0,0),t=[t[0]-s[0],t[1]-s[1],0];return t},mHelper:new Matrix},MaskElement.prototype.getMaskProperty=function(t){return this.viewData[t].prop},MaskElement.prototype.renderFrame=function(t){for(var e,i=this.element.finalTransform.mat,r=this.masksProperties.length,s=0;s<r;s+=1)(this.viewData[s].prop._mdf||t)&&this.drawPath(this.masksProperties[s],this.viewData[s].prop.v,this.viewData[s]),(this.viewData[s].op._mdf||t)&&this.viewData[s].elem.setAttribute("fill-opacity",this.viewData[s].op.v),"n"!==this.masksProperties[s].mode&&(this.viewData[s].invRect&&(this.element.finalTransform.mProp._mdf||t)&&this.viewData[s].invRect.setAttribute("transform",i.getInverseMatrix().to2dCSS()),this.storedData[s].x)&&(this.storedData[s].x._mdf||t)&&(e=this.storedData[s].expan,this.storedData[s].x.v<0?("erode"!==this.storedData[s].lastOperator&&(this.storedData[s].lastOperator="erode",this.storedData[s].elem.setAttribute("filter","url("+getLocationHref()+"#"+this.storedData[s].filterId+")")),e.setAttribute("radius",-this.storedData[s].x.v)):("dilate"!==this.storedData[s].lastOperator&&(this.storedData[s].lastOperator="dilate",this.storedData[s].elem.setAttribute("filter",null)),this.storedData[s].elem.setAttribute("stroke-width",2*this.storedData[s].x.v)))},MaskElement.prototype.getMaskelement=function(){return this.maskElement},MaskElement.prototype.createLayerSolidPath=function(){var t="M0,0 ";return(t+=" h"+this.globalData.compSize.w)+(" v"+this.globalData.compSize.h)+(" h-"+this.globalData.compSize.w)+(" v-"+this.globalData.compSize.h+" ")},MaskElement.prototype.drawPath=function(t,e,i){for(var r,s=" M"+e.v[0][0]+","+e.v[0][1],a=e._length,n=1;n<a;n+=1)s+=" C"+e.o[n-1][0]+","+e.o[n-1][1]+" "+e.i[n][0]+","+e.i[n][1]+" "+e.v[n][0]+","+e.v[n][1];e.c&&1<a&&(s+=" C"+e.o[n-1][0]+","+e.o[n-1][1]+" "+e.i[0][0]+","+e.i[0][1]+" "+e.v[0][0]+","+e.v[0][1]),i.lastPath!==s&&(r="",i.elem&&(e.c&&(r=t.inv?this.solidPath+s:s),i.elem.setAttribute("d",r)),i.lastPath=s)},MaskElement.prototype.destroy=function(){this.element=null,this.globalData=null,this.maskElement=null,this.data=null,this.masksProperties=null};var filtersFactory=(()=>{var t={createFilter:function(t,e){var i=createNS("filter");i.setAttribute("id",t),!0!==e&&(i.setAttribute("filterUnits","objectBoundingBox"),i.setAttribute("x","0%"),i.setAttribute("y","0%"),i.setAttribute("width","100%"),i.setAttribute("height","100%"));return i},createAlphaToLuminanceFilter:function(){var t=createNS("feColorMatrix");return t.setAttribute("type","matrix"),t.setAttribute("color-interpolation-filters","sRGB"),t.setAttribute("values","0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1"),t}};return t})(),featureSupport=(()=>{var t={maskType:!0,svgLumaHidden:!0,offscreenCanvas:"undefined"!=typeof OffscreenCanvas};return(/MSIE 10/i.test(navigator.userAgent)||/MSIE 9/i.test(navigator.userAgent)||/rv:11.0/i.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent))&&(t.maskType=!1),/firefox/i.test(navigator.userAgent)&&(t.svgLumaHidden=!1),t})(),registeredEffects$1={},idPrefix="filter_result_";function SVGEffects(t){var e,i="SourceGraphic",r=t.data.ef?t.data.ef.length:0,s=createElementID(),a=filtersFactory.createFilter(s,!0),n=0;for(this.filters=[],e=0;e<r;e+=1){o=null;var o,h=t.data.ef[e].ty;registeredEffects$1[h]&&(o=new registeredEffects$1[h].effect(a,t.effectsManager.effectElements[e],t,idPrefix+n,i),i=idPrefix+n,registeredEffects$1[h].countsAsEffect)&&(n+=1),o&&this.filters.push(o)}n&&(t.globalData.defs.appendChild(a),t.layerElement.setAttribute("filter","url("+getLocationHref()+"#"+s+")")),this.filters.length&&t.addRenderableComponent(this)}function registerEffect$1(t,e,i){registeredEffects$1[t]={effect:e,countsAsEffect:i}}function SVGBaseElement(){}function HierarchyElement(){}function RenderableDOMElement(){}function IImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.assetData&&this.assetData.sid&&(this.assetData=e.slotManager.getProp(this.assetData)),this.initElement(t,e,i),this.sourceRect={top:0,left:0,width:this.assetData.w,height:this.assetData.h}}function ProcessedElement(t,e){this.elem=t,this.pos=e}function IShapeElement(){}SVGEffects.prototype.renderFrame=function(t){for(var e=this.filters.length,i=0;i<e;i+=1)this.filters[i].renderFrame(t)},SVGEffects.prototype.getEffects=function(t){for(var e=this.filters.length,i=[],r=0;r<e;r+=1)this.filters[r].type===t&&i.push(this.filters[r]);return i},SVGBaseElement.prototype={initRendererElement:function(){this.layerElement=createNS("g")},createContainerElements:function(){this.matteElement=createNS("g"),this.transformedElement=this.layerElement,this.maskedElement=this.layerElement,this._sizeChanged=!1;var t,e,i,r=null;this.data.td?(this.matteMasks={},(t=createNS("g")).setAttribute("id",this.layerId),t.appendChild(this.layerElement),this.globalData.defs.appendChild(r=t)):this.data.tt?(this.matteElement.appendChild(this.layerElement),r=this.matteElement,this.baseElement=this.matteElement):this.baseElement=this.layerElement,this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0!==this.data.ty||this.data.hd||(t=createNS("clipPath"),(i=createNS("path")).setAttribute("d","M0,0 L"+this.data.w+",0 L"+this.data.w+","+this.data.h+" L0,"+this.data.h+"z"),e=createElementID(),t.setAttribute("id",e),t.appendChild(i),this.globalData.defs.appendChild(t),this.checkMasks()?((i=createNS("g")).setAttribute("clip-path","url("+getLocationHref()+"#"+e+")"),i.appendChild(this.layerElement),this.transformedElement=i,r?r.appendChild(this.transformedElement):this.baseElement=this.transformedElement):this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+e+")")),0!==this.data.bm&&this.setBlendMode()},renderElement:function(){this.finalTransform._localMatMdf&&this.transformedElement.setAttribute("transform",this.finalTransform.localMat.to2dCSS()),this.finalTransform._opMdf&&this.transformedElement.setAttribute("opacity",this.finalTransform.localOpacity)},destroyBaseElement:function(){this.layerElement=null,this.matteElement=null,this.maskManager.destroy()},getBaseElement:function(){return this.data.hd?null:this.baseElement},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData),this.renderableEffectsManager=new SVGEffects(this),this.searchEffectTransforms()},getMatte:function(t){var e,i,r,s,a,n,o,h,l;return this.matteMasks||(this.matteMasks={}),this.matteMasks[t]||(e=this.layerId+"_"+t,1===t||3===t?((n=createNS("mask")).setAttribute("id",e),n.setAttribute("mask-type",3===t?"luminance":"alpha"),(s=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),n.appendChild(s),this.globalData.defs.appendChild(n),featureSupport.maskType||1!==t||(n.setAttribute("mask-type","luminance"),i=createElementID(),r=filtersFactory.createFilter(i),this.globalData.defs.appendChild(r),r.appendChild(filtersFactory.createAlphaToLuminanceFilter()),(a=createNS("g")).appendChild(s),n.appendChild(a),a.setAttribute("filter","url("+getLocationHref()+"#"+i+")"))):2===t&&((n=createNS("mask")).setAttribute("id",e),n.setAttribute("mask-type","alpha"),o=createNS("g"),n.appendChild(o),i=createElementID(),r=filtersFactory.createFilter(i),(l=createNS("feComponentTransfer")).setAttribute("in","SourceGraphic"),r.appendChild(l),(h=createNS("feFuncA")).setAttribute("type","table"),h.setAttribute("tableValues","1.0 0.0"),l.appendChild(h),this.globalData.defs.appendChild(r),(l=createNS("rect")).setAttribute("width",this.comp.data.w),l.setAttribute("height",this.comp.data.h),l.setAttribute("x","0"),l.setAttribute("y","0"),l.setAttribute("fill","#ffffff"),l.setAttribute("opacity","0"),o.setAttribute("filter","url("+getLocationHref()+"#"+i+")"),o.appendChild(l),(s=createNS("use")).setAttributeNS("http://www.w3.org/1999/xlink","href","#"+this.layerId),o.appendChild(s),featureSupport.maskType||(n.setAttribute("mask-type","luminance"),r.appendChild(filtersFactory.createAlphaToLuminanceFilter()),a=createNS("g"),o.appendChild(l),a.appendChild(this.layerElement),o.appendChild(a)),this.globalData.defs.appendChild(n)),this.matteMasks[t]=e),this.matteMasks[t]},setMatte:function(t){this.matteElement&&this.matteElement.setAttribute("mask","url("+getLocationHref()+"#"+t+")")}},HierarchyElement.prototype={initHierarchy:function(){this.hierarchy=[],this._isParent=!1,this.checkParenting()},setHierarchy:function(t){this.hierarchy=t},setAsParent:function(){this._isParent=!0},checkParenting:function(){void 0!==this.data.parent&&this.comp.buildElementParenting(this,this.data.parent,[])}},extendPrototype([RenderableElement,createProxyFunction({initElement:function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide()},hide:function(){this.hidden||this.isInRange&&!this.isTransparent||((this.baseElement||this.layerElement).style.display="none",this.hidden=!0)},show:function(){this.isInRange&&!this.isTransparent&&(this.data.hd||((this.baseElement||this.layerElement).style.display="block"),this.hidden=!1,this._isFirstFrame=!0)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},renderInnerContent:function(){},prepareFrame:function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.checkTransparency()},destroy:function(){this.innerElem=null,this.destroyBaseElement()}})],RenderableDOMElement),extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],IImageElement),IImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData);this.innerElem=createNS("image"),this.innerElem.setAttribute("width",this.assetData.w+"px"),this.innerElem.setAttribute("height",this.assetData.h+"px"),this.innerElem.setAttribute("preserveAspectRatio",this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio),this.innerElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.innerElem)},IImageElement.prototype.sourceRectAtTime=function(){return this.sourceRect},IShapeElement.prototype={addShapeToModifiers:function(t){for(var e=this.shapeModifiers.length,i=0;i<e;i+=1)this.shapeModifiers[i].addShape(t)},isShapeInAnimatedModifiers:function(t){for(var e=this.shapeModifiers.length;0<e;)if(this.shapeModifiers[0].isAnimatedWithShape(t))return!0;return!1},renderModifiers:function(){if(this.shapeModifiers.length){for(var t=this.shapes.length,e=0;e<t;e+=1)this.shapes[e].sh.reset();for(e=(t=this.shapeModifiers.length)-1;0<=e&&!this.shapeModifiers[e].processShapes(this._isFirstFrame);--e);}},searchProcessedElement:function(t){for(var e=this.processedElements,i=0,r=e.length;i<r;){if(e[i].elem===t)return e[i].pos;i+=1}return 0},addProcessedElement:function(t,e){for(var i=this.processedElements,r=i.length;r;)if(i[--r].elem===t)return void(i[r].pos=e);i.push(new ProcessedElement(t,e))},prepareFrame:function(t){this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)}};var lineCapEnum={1:"butt",2:"round",3:"square"},lineJoinEnum={1:"miter",2:"round",3:"bevel"};function SVGShapeData(t,e,i){this.caches=[],this.styles=[],this.transformers=t,this.lStr="",this.sh=i,this.lvl=e,this._isAnimated=!!i.k;for(var r=0,s=t.length;r<s;){if(t[r].mProps.dynamicProperties.length){this._isAnimated=!0;break}r+=1}}function SVGStyleData(t,e){this.data=t,this.type=t.ty,this.d="",this.lvl=e,this._mdf=!1,this.closed=!0===t.hd,this.pElem=createNS("path"),this.msElem=null}function DashProperty(t,e,i,r){this.elem=t,this.frameId=-1,this.dataProps=createSizedArray(e.length),this.renderer=i,this.k=!1,this.dashStr="",this.dashArray=createTypedArray("float32",e.length?e.length-1:0),this.dashoffset=createTypedArray("float32",1),this.initDynamicPropertyContainer(r);for(var s,a=e.length||0,n=0;n<a;n+=1)s=PropertyFactory.getProp(t,e[n].v,0,0,this),this.k=s.k||this.k,this.dataProps[n]={n:e[n].n,p:s};this.k||this.getValue(!0),this._isAnimated=this.k}function SVGStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i,this._isAnimated=!!this._isAnimated}function SVGFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.c=PropertyFactory.getProp(t,e.c,1,255,this),this.style=i}function SVGNoStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.style=i}function GradientProperty(t,e,i){this.data=e,this.c=createTypedArray("uint8c",4*e.p);var r=e.k.k[0].s?e.k.k[0].s.length-4*e.p:e.k.k.length-4*e.p;this.o=createTypedArray("float32",r),this._cmdf=!1,this._omdf=!1,this._collapsable=this.checkCollapsable(),this._hasOpacity=r,this.initDynamicPropertyContainer(i),this.prop=PropertyFactory.getProp(t,e.k,1,null,this),this.k=this.prop.k,this.getValue(!0)}function SVGGradientFillStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.initGradientData(t,e,i)}function SVGGradientStrokeStyleData(t,e,i){this.initDynamicPropertyContainer(t),this.getValue=this.iterateDynamicProperties,this.w=PropertyFactory.getProp(t,e.w,0,null,this),this.d=new DashProperty(t,e.d||{},"svg",this),this.initGradientData(t,e,i),this._isAnimated=!!this._isAnimated}function ShapeGroupData(){this.it=[],this.prevViewData=[],this.gr=createNS("g")}function SVGTransformData(t,e,i){this.transform={mProps:t,op:e,container:i},this.elements=[],this._isAnimated=this.transform.mProps.dynamicProperties.length||this.transform.op.effectsSequence.length}SVGShapeData.prototype.setAsAnimated=function(){this._isAnimated=!0},SVGStyleData.prototype.reset=function(){this.d="",this._mdf=!1},DashProperty.prototype.getValue=function(t){if((this.elem.globalData.frameId!==this.frameId||t)&&(this.frameId=this.elem.globalData.frameId,this.iterateDynamicProperties(),this._mdf=this._mdf||t,this._mdf)){var e=0,i=this.dataProps.length;for("svg"===this.renderer&&(this.dashStr=""),e=0;e<i;e+=1)"o"!==this.dataProps[e].n?"svg"===this.renderer?this.dashStr+=" "+this.dataProps[e].p.v:this.dashArray[e]=this.dataProps[e].p.v:this.dashoffset[0]=this.dataProps[e].p.v}},extendPrototype([DynamicPropertyContainer],DashProperty),extendPrototype([DynamicPropertyContainer],SVGStrokeStyleData),extendPrototype([DynamicPropertyContainer],SVGFillStyleData),extendPrototype([DynamicPropertyContainer],SVGNoStyleData),GradientProperty.prototype.comparePoints=function(t,e){for(var i=0,r=this.o.length/2;i<r;){if(.01<Math.abs(t[4*i]-t[4*e+2*i]))return!1;i+=1}return!0},GradientProperty.prototype.checkCollapsable=function(){if(this.o.length/2!=this.c.length/4)return!1;if(this.data.k.k[0].s)for(var t=0,e=this.data.k.k.length;t<e;){if(!this.comparePoints(this.data.k.k[t].s,this.data.p))return!1;t+=1}else if(!this.comparePoints(this.data.k.k,this.data.p))return!1;return!0},GradientProperty.prototype.getValue=function(t){if(this.prop.getValue(),this._mdf=!1,this._cmdf=!1,this._omdf=!1,this.prop._mdf||t){for(var e,i,r=4*this.data.p,s=0;s<r;s+=1)e=s%4==0?100:255,i=Math.round(this.prop.v[s]*e),this.c[s]!==i&&(this.c[s]=i,this._cmdf=!t);if(this.o.length)for(r=this.prop.v.length,s=4*this.data.p;s<r;s+=1)e=s%2==0?100:1,i=s%2==0?Math.round(100*this.prop.v[s]):this.prop.v[s],this.o[s-4*this.data.p]!==i&&(this.o[s-4*this.data.p]=i,this._omdf=!t);this._mdf=!t}},extendPrototype([DynamicPropertyContainer],GradientProperty),SVGGradientFillStyleData.prototype.initGradientData=function(t,e,i){this.o=PropertyFactory.getProp(t,e.o,0,.01,this),this.s=PropertyFactory.getProp(t,e.s,1,null,this),this.e=PropertyFactory.getProp(t,e.e,1,null,this),this.h=PropertyFactory.getProp(t,e.h||{k:0},0,.01,this),this.a=PropertyFactory.getProp(t,e.a||{k:0},0,degToRads,this),this.g=new GradientProperty(t,e.g,this),this.style=i,this.stops=[],this.setGradientData(i.pElem,e),this.setGradientOpacity(e,i),this._isAnimated=!!this._isAnimated},SVGGradientFillStyleData.prototype.setGradientData=function(t,e){for(var i,r=createElementID(),s=createNS(1===e.t?"linearGradient":"radialGradient"),a=(s.setAttribute("id",r),s.setAttribute("spreadMethod","pad"),s.setAttribute("gradientUnits","userSpaceOnUse"),[]),n=4*e.g.p,o=0;o<n;o+=4)i=createNS("stop"),s.appendChild(i),a.push(i);t.setAttribute("gf"===e.ty?"fill":"stroke","url("+getLocationHref()+"#"+r+")"),this.gf=s,this.cst=a},SVGGradientFillStyleData.prototype.setGradientOpacity=function(t,e){if(this.g._hasOpacity&&!this.g._collapsable){for(var i,r,s=createNS("mask"),a=createNS("path"),n=(s.appendChild(a),createElementID()),o=createElementID(),h=(s.setAttribute("id",o),createNS(1===t.t?"linearGradient":"radialGradient")),l=(h.setAttribute("id",n),h.setAttribute("spreadMethod","pad"),h.setAttribute("gradientUnits","userSpaceOnUse"),r=(t.g.k.k[0].s||t.g.k.k).length,this.stops),p=4*t.g.p;p<r;p+=2)(i=createNS("stop")).setAttribute("stop-color","rgb(255,255,255)"),h.appendChild(i),l.push(i);a.setAttribute("gf"===t.ty?"fill":"stroke","url("+getLocationHref()+"#"+n+")"),"gs"===t.ty&&(a.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),a.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),1===t.lj)&&a.setAttribute("stroke-miterlimit",t.ml),this.of=h,this.ms=s,this.ost=l,this.maskId=o,e.msElem=a}},extendPrototype([DynamicPropertyContainer],SVGGradientFillStyleData),extendPrototype([SVGGradientFillStyleData,DynamicPropertyContainer],SVGGradientStrokeStyleData);var buildShapeString=function(t,e,i,r){if(0===e)return"";for(var s=t.o,a=t.i,n=t.v,o=" M"+r.applyToPointStringified(n[0][0],n[0][1]),h=1;h<e;h+=1)o+=" C"+r.applyToPointStringified(s[h-1][0],s[h-1][1])+" "+r.applyToPointStringified(a[h][0],a[h][1])+" "+r.applyToPointStringified(n[h][0],n[h][1]);return o=i&&e?o+(" C"+r.applyToPointStringified(s[h-1][0],s[h-1][1])+" "+r.applyToPointStringified(a[0][0],a[0][1])+" "+r.applyToPointStringified(n[0][0],n[0][1]))+"z":o},SVGElementsRenderer=(()=>{var u=new Matrix,y=new Matrix;function e(t,e,i){(i||e.transform.op._mdf)&&e.transform.container.setAttribute("opacity",e.transform.op.v),(i||e.transform.mProps._mdf)&&e.transform.container.setAttribute("transform",e.transform.mProps.v.to2dCSS())}function i(){}function r(t,e,i){for(var r,s,a,n,o,h,l,p,m,f=e.styles.length,c=e.lvl,d=0;d<f;d+=1){if(n=e.sh._mdf||i,e.styles[d].lvl<c){for(l=y.reset(),p=c-e.styles[d].lvl,m=e.transformers.length-1;!n&&0<p;)n=e.transformers[m].mProps._mdf||n,--p,--m;if(n)for(p=c-e.styles[d].lvl,m=e.transformers.length-1;0<p;)l.multiply(e.transformers[m].mProps.v),--p,--m}else l=u;if(s=(h=e.sh.paths)._length,n){for(a="",r=0;r<s;r+=1)(o=h.shapes[r])&&o._length&&(a+=buildShapeString(o,o._length,o.c,l));e.caches[d]=a}else a=e.caches[d];e.styles[d].d+=!0===t.hd?"":a,e.styles[d]._mdf=n||e.styles[d]._mdf}}function s(t,e,i){var r=e.style;(e.c._mdf||i)&&r.pElem.setAttribute("fill","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("fill-opacity",e.o.v)}function a(t,e,i){n(t,e,i),o(0,e,i)}function n(t,e,i){var r,s,a,n,o=e.gf,h=e.g._hasOpacity,l=e.s.v,p=e.e.v;if((e.o._mdf||i)&&(a="gf"===t.ty?"fill-opacity":"stroke-opacity",e.style.pElem.setAttribute(a,e.o.v)),(e.s._mdf||i)&&(n="x1"==(a=1===t.t?"x1":"cx")?"y1":"cy",o.setAttribute(a,l[0]),o.setAttribute(n,l[1]),h)&&!e.g._collapsable&&(e.of.setAttribute(a,l[0]),e.of.setAttribute(n,l[1])),e.g._cmdf||i)for(var m=e.cst,f=e.g.c,c=m.length,d=0;d<c;d+=1)(r=m[d]).setAttribute("offset",f[4*d]+"%"),r.setAttribute("stop-color","rgb("+f[4*d+1]+","+f[4*d+2]+","+f[4*d+3]+")");if(h&&(e.g._omdf||i)){var u=e.g.o;for(c=(m=e.g._collapsable?e.cst:e.ost).length,d=0;d<c;d+=1)r=m[d],e.g._collapsable||r.setAttribute("offset",u[2*d]+"%"),r.setAttribute("stop-opacity",u[2*d+1])}1===t.t?(e.e._mdf||i)&&(o.setAttribute("x2",p[0]),o.setAttribute("y2",p[1]),h)&&!e.g._collapsable&&(e.of.setAttribute("x2",p[0]),e.of.setAttribute("y2",p[1])):((e.s._mdf||e.e._mdf||i)&&(s=Math.sqrt(Math.pow(l[0]-p[0],2)+Math.pow(l[1]-p[1],2)),o.setAttribute("r",s),h)&&!e.g._collapsable&&e.of.setAttribute("r",s),(e.s._mdf||e.e._mdf||e.h._mdf||e.a._mdf||i)&&(s=s||Math.sqrt(Math.pow(l[0]-p[0],2)+Math.pow(l[1]-p[1],2)),a=Math.atan2(p[1]-l[1],p[0]-l[0]),1<=(n=e.h.v)?n=.99:n<=-1&&(n=-.99),t=s*n,i=Math.cos(a+e.a.v)*t+l[0],p=Math.sin(a+e.a.v)*t+l[1],o.setAttribute("fx",i),o.setAttribute("fy",p),h)&&!e.g._collapsable&&(e.of.setAttribute("fx",i),e.of.setAttribute("fy",p)))}function o(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||i)&&s.dashStr&&(r.pElem.setAttribute("stroke-dasharray",s.dashStr),r.pElem.setAttribute("stroke-dashoffset",s.dashoffset[0])),e.c&&(e.c._mdf||i)&&r.pElem.setAttribute("stroke","rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i)&&r.pElem.setAttribute("stroke-opacity",e.o.v),(e.w._mdf||i)&&(r.pElem.setAttribute("stroke-width",e.w.v),r.msElem)&&r.msElem.setAttribute("stroke-width",e.w.v)}return{createRenderFunction:function(t){switch(t.ty){case"fl":return s;case"gf":return n;case"gs":return a;case"st":return o;case"sh":case"el":case"rc":case"sr":return r;case"tr":return e;case"no":return i;default:return null}}}})();function SVGShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.initElement(t,e,i),this.prevViewData=[]}function LetterProps(t,e,i,r,s,a){this.o=t,this.sw=e,this.sc=i,this.fc=r,this.m=s,this.p=a,this._mdf={o:!0,sw:!!e,sc:!!i,fc:!!r,m:!0,p:!0}}function TextProperty(t,e){this._frameId=initialDefaultFrame,this.pv="",this.v="",this.kf=!1,this._isFirstFrame=!0,this._mdf=!1,e.d&&e.d.sid&&(e.d=t.globalData.slotManager.getProp(e.d)),this.data=e,this.elem=t,this.comp=this.elem.comp,this.keysIndex=0,this.canResize=!1,this.minimumFontSize=1,this.effectsSequence=[],this.currentData={ascent:0,boxWidth:this.defaultBoxWidth,f:"",fStyle:"",fWeight:"",fc:"",j:"",justifyOffset:"",l:[],lh:0,lineWidths:[],ls:"",of:"",s:"",sc:"",sw:0,t:0,tr:0,sz:0,ps:null,fillColorAnim:!1,strokeColorAnim:!1,strokeWidthAnim:!1,yOffset:0,finalSize:0,finalText:[],finalLineHeight:0,__complete:!1},this.copyData(this.currentData,this.data.d.k[0].s),this.searchProperty()||this.completeTextData(this.currentData)}extendPrototype([BaseElement,TransformElement,SVGBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableDOMElement],SVGShapeElement),SVGShapeElement.prototype.initSecondaryElement=function(){},SVGShapeElement.prototype.identityMatrix=new Matrix,SVGShapeElement.prototype.buildExpressionInterface=function(){},SVGShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes()},SVGShapeElement.prototype.filterUniqueShapes=function(){for(var t,e,i,r=this.shapes.length,s=this.stylesList.length,a=[],n=!1,o=0;o<s;o+=1){for(i=this.stylesList[o],n=!1,t=a.length=0;t<r;t+=1)-1!==(e=this.shapes[t]).styles.indexOf(i)&&(a.push(e),n=e._isAnimated||n);1<a.length&&n&&this.setShapesAsAnimated(a)}},SVGShapeElement.prototype.setShapesAsAnimated=function(t){for(var e=t.length,i=0;i<e;i+=1)t[i].setAsAnimated()},SVGShapeElement.prototype.createStyleElement=function(t,e){var i,e=new SVGStyleData(t,e),r=e.pElem;return"st"===t.ty?i=new SVGStrokeStyleData(this,t,e):"fl"===t.ty?i=new SVGFillStyleData(this,t,e):"gf"===t.ty||"gs"===t.ty?(i=new("gf"===t.ty?SVGGradientFillStyleData:SVGGradientStrokeStyleData)(this,t,e),this.globalData.defs.appendChild(i.gf),i.maskId&&(this.globalData.defs.appendChild(i.ms),this.globalData.defs.appendChild(i.of),r.setAttribute("mask","url("+getLocationHref()+"#"+i.maskId+")"))):"no"===t.ty&&(i=new SVGNoStyleData(this,t,e)),"st"!==t.ty&&"gs"!==t.ty||(r.setAttribute("stroke-linecap",lineCapEnum[t.lc||2]),r.setAttribute("stroke-linejoin",lineJoinEnum[t.lj||2]),r.setAttribute("fill-opacity","0"),1===t.lj&&r.setAttribute("stroke-miterlimit",t.ml)),2===t.r&&r.setAttribute("fill-rule","evenodd"),t.ln&&r.setAttribute("id",t.ln),t.cl&&r.setAttribute("class",t.cl),t.bm&&(r.style["mix-blend-mode"]=getBlendMode(t.bm)),this.stylesList.push(e),this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createGroupElement=function(t){var e=new ShapeGroupData;return t.ln&&e.gr.setAttribute("id",t.ln),t.cl&&e.gr.setAttribute("class",t.cl),t.bm&&(e.gr.style["mix-blend-mode"]=getBlendMode(t.bm)),e},SVGShapeElement.prototype.createTransformElement=function(t,e){var i=TransformPropertyFactory.getTransformProperty(this,t,this),i=new SVGTransformData(i,i.o,e);return this.addToAnimatedContents(t,i),i},SVGShapeElement.prototype.createShapeElement=function(t,e,i){var r=4;"rc"===t.ty?r=5:"el"===t.ty?r=6:"sr"===t.ty&&(r=7);e=new SVGShapeData(e,i,ShapePropertyFactory.getShapeProp(this,t,r,this));return this.shapes.push(e),this.addShapeToModifiers(e),this.addToAnimatedContents(t,e),e},SVGShapeElement.prototype.addToAnimatedContents=function(t,e){for(var i=0,r=this.animatedContents.length;i<r;){if(this.animatedContents[i].element===e)return;i+=1}this.animatedContents.push({fn:SVGElementsRenderer.createRenderFunction(t),element:e,data:t})},SVGShapeElement.prototype.setElementStyles=function(t){for(var e=t.styles,i=this.stylesList.length,r=0;r<i;r+=1)-1!==e.indexOf(this.stylesList[r])||this.stylesList[r].closed||e.push(this.stylesList[r])},SVGShapeElement.prototype.reloadShapes=function(){this._isFirstFrame=!0;for(var t=this.itemsData.length,e=0;e<t;e+=1)this.prevViewData[e]=this.itemsData[e];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.layerElement,0,[],!0),this.filterUniqueShapes(),t=this.dynamicProperties.length,e=0;e<t;e+=1)this.dynamicProperties[e].getValue();this.renderModifiers()},SVGShapeElement.prototype.searchShapes=function(t,e,i,r,s,a,n){for(var o,h,l,p,m,f=[].concat(a),c=t.length-1,d=[],u=[],y=c;0<=y;--y){if((m=this.searchProcessedElement(t[y]))?e[y]=i[m-1]:t[y]._render=n,"fl"===t[y].ty||"st"===t[y].ty||"gf"===t[y].ty||"gs"===t[y].ty||"no"===t[y].ty)m?e[y].style.closed=t[y].hd:e[y]=this.createStyleElement(t[y],s),t[y]._render&&e[y].style.pElem.parentNode!==r&&r.appendChild(e[y].style.pElem),d.push(e[y].style);else if("gr"===t[y].ty){if(m)for(h=e[y].it.length,o=0;o<h;o+=1)e[y].prevViewData[o]=e[y].it[o];else e[y]=this.createGroupElement(t[y]);this.searchShapes(t[y].it,e[y].it,e[y].prevViewData,e[y].gr,s+1,f,n),t[y]._render&&e[y].gr.parentNode!==r&&r.appendChild(e[y].gr)}else"tr"===t[y].ty?(m||(e[y]=this.createTransformElement(t[y],r)),l=e[y].transform,f.push(l)):"sh"===t[y].ty||"rc"===t[y].ty||"el"===t[y].ty||"sr"===t[y].ty?(m||(e[y]=this.createShapeElement(t[y],f,s)),this.setElementStyles(e[y])):"tm"===t[y].ty||"rd"===t[y].ty||"ms"===t[y].ty||"pb"===t[y].ty||"zz"===t[y].ty||"op"===t[y].ty?(m?(p=e[y]).closed=!1:((p=ShapeModifiers.getModifier(t[y].ty)).init(this,t[y]),e[y]=p,this.shapeModifiers.push(p)),u.push(p)):"rp"===t[y].ty&&(m?(p=e[y]).closed=!0:(p=ShapeModifiers.getModifier(t[y].ty),(e[y]=p).init(this,t,y,e),this.shapeModifiers.push(p),n=!1),u.push(p));this.addProcessedElement(t[y],y+1)}for(c=d.length,y=0;y<c;y+=1)d[y].closed=!0;for(c=u.length,y=0;y<c;y+=1)u[y].closed=!0},SVGShapeElement.prototype.renderInnerContent=function(){this.renderModifiers();for(var t=this.stylesList.length,e=0;e<t;e+=1)this.stylesList[e].reset();for(this.renderShape(),e=0;e<t;e+=1)(this.stylesList[e]._mdf||this._isFirstFrame)&&(this.stylesList[e].msElem&&(this.stylesList[e].msElem.setAttribute("d",this.stylesList[e].d),this.stylesList[e].d="M0 0"+this.stylesList[e].d),this.stylesList[e].pElem.setAttribute("d",this.stylesList[e].d||"M0 0"))},SVGShapeElement.prototype.renderShape=function(){for(var t,e=this.animatedContents.length,i=0;i<e;i+=1)t=this.animatedContents[i],(this._isFirstFrame||t.element._isAnimated)&&!0!==t.data&&t.fn(t.data,t.element,this._isFirstFrame)},SVGShapeElement.prototype.destroy=function(){this.destroyBaseElement(),this.shapesData=null,this.itemsData=null},LetterProps.prototype.update=function(t,e,i,r,s,a){this._mdf.o=!1,this._mdf.sw=!1,this._mdf.sc=!1,this._mdf.fc=!1,this._mdf.m=!1;var n=this._mdf.p=!1;return this.o!==t&&(this.o=t,n=this._mdf.o=!0),this.sw!==e&&(this.sw=e,n=this._mdf.sw=!0),this.sc!==i&&(this.sc=i,n=this._mdf.sc=!0),this.fc!==r&&(this.fc=r,n=this._mdf.fc=!0),this.m!==s&&(this.m=s,n=this._mdf.m=!0),!a.length||this.p[0]===a[0]&&this.p[1]===a[1]&&this.p[4]===a[4]&&this.p[5]===a[5]&&this.p[12]===a[12]&&this.p[13]===a[13]||(this.p=a,n=this._mdf.p=!0),n},TextProperty.prototype.defaultBoxWidth=[0,0],TextProperty.prototype.copyData=function(t,e){for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},TextProperty.prototype.setCurrentData=function(t){t.__complete||this.completeTextData(t),this.currentData=t,this.currentData.boxWidth=this.currentData.boxWidth||this.defaultBoxWidth,this._mdf=!0},TextProperty.prototype.searchProperty=function(){return this.searchKeyframes()},TextProperty.prototype.searchKeyframes=function(){return this.kf=1<this.data.d.k.length,this.kf&&this.addEffect(this.getKeyframeValue.bind(this)),this.kf},TextProperty.prototype.addEffect=function(t){this.effectsSequence.push(t),this.elem.addDynamicProperty(this)},TextProperty.prototype.getValue=function(t){if(this.elem.globalData.frameId!==this.frameId&&this.effectsSequence.length||t){this.currentData.t=this.data.d.k[this.keysIndex].s.t;var e=this.currentData,i=this.keysIndex;if(this.lock)this.setCurrentData(this.currentData);else{this.lock=!0,this._mdf=!1;for(var r=this.effectsSequence.length,s=t||this.data.d.k[this.keysIndex].s,a=0;a<r;a+=1)s=i!==this.keysIndex?this.effectsSequence[a](s,s.t):this.effectsSequence[a](this.currentData,s.t);e!==s&&this.setCurrentData(s),this.v=this.currentData,this.pv=this.v,this.lock=!1,this.frameId=this.elem.globalData.frameId}}},TextProperty.prototype.getKeyframeValue=function(){for(var t=this.data.d.k,e=this.elem.comp.renderedFrame,i=0,r=t.length;i<=r-1&&!(i===r-1||t[i+1].t>e);)i+=1;return this.keysIndex!==i&&(this.keysIndex=i),this.data.d.k[this.keysIndex].s},TextProperty.prototype.buildFinalText=function(t){for(var e,i,r=[],s=0,a=t.length,n=!1,o=!1,h="";s<a;)n=o,o=!1,e=t.charCodeAt(s),h=t.charAt(s),FontManager.isCombinedCharacter(e)?n=!0:55296<=e&&e<=56319?FontManager.isRegionalFlag(t,s)?h=t.substr(s,14):56320<=(i=t.charCodeAt(s+1))&&i<=57343&&(FontManager.isModifier(e,i)?(h=t.substr(s,2),n=!0):h=FontManager.isFlagEmoji(t.substr(s,4))?t.substr(s,4):t.substr(s,2)):56319<e?(i=t.charCodeAt(s+1),FontManager.isVariationSelector(e)&&(n=!0)):FontManager.isZeroWidthJoiner(e)&&(o=n=!0),n?(r[r.length-1]+=h,n=!1):r.push(h),s+=h.length;return r},TextProperty.prototype.completeTextData=function(t){t.__complete=!0;var e,i,r,s,a=this.elem.globalData.fontManager,n=this.data,o=[],h=0,l=n.m.g,p=0,m=0,f=0,c=[],d=0,u=0,y=a.getFontByName(t.f),g=0,v=getFontProperties(y),b=(t.fWeight=v.weight,t.fStyle=v.style,t.finalSize=t.s,t.finalText=this.buildFinalText(t.t),S=t.finalText.length,t.finalLineHeight=t.lh,t.tr/1e3*t.finalSize);if(t.sz)for(var x=!0,R=t.sz[0],L=t.sz[1];x;){for(var P,E=0,d=0,S=(P=this.buildFinalText(t.t)).length,b=t.tr/1e3*t.finalSize,C=-1,_=0;_<S;_+=1)s=P[_].charCodeAt(0),e=!1," "===P[_]?C=_:13!==s&&3!==s||(e=!(d=0),E+=t.finalLineHeight||1.2*t.finalSize),d=R<d+(g=a.chars?(r=a.getCharData(P[_],y.fStyle,y.fFamily),e?0:r.w*t.finalSize/100):a.measureText(P[_],t.f,t.finalSize))&&" "!==P[_]?(-1===C?S+=1:_=C,E+=t.finalLineHeight||1.2*t.finalSize,P.splice(_,C===_?1:0,"\r"),C=-1,0):d+g+b;E+=y.ascent*t.finalSize/100,this.canResize&&t.finalSize>this.minimumFontSize&&L<E?(--t.finalSize,t.finalLineHeight=t.finalSize*t.lh/t.s):(t.finalText=P,S=t.finalText.length,x=!1)}d=-b;var A,g=0,T=0;for(_=0;_<S;_+=1)if(e=!1,13===(s=(A=t.finalText[_]).charCodeAt(0))||3===s?(T=0,c.push(d),u=u<d?d:u,d=-2*b,e=!(i=""),f+=1):i=A,g=a.chars?(r=a.getCharData(A,y.fStyle,a.getFontByName(t.f).fFamily),e?0:r.w*t.finalSize/100):a.measureText(i,t.f,t.finalSize)," "===A?T+=g+b:(d+=g+b+T,T=0),o.push({l:g,an:g,add:p,n:e,anIndexes:[],val:i,line:f,animatorJustifyOffset:0}),2==l){if(p+=g,""===i||" "===i||_===S-1){for(""!==i&&" "!==i||(p-=g);m<=_;)o[m].an=p,o[m].ind=h,o[m].extra=g,m+=1;h+=1,p=0}}else if(3==l){if(p+=g,""===i||_===S-1){for(""===i&&(p-=g);m<=_;)o[m].an=p,o[m].ind=h,o[m].extra=g,m+=1;p=0,h+=1}}else o[h].ind=h,o[h].extra=0,h+=1;if(t.l=o,u=u<d?d:u,c.push(d),t.sz)t.boxWidth=t.sz[0],t.justifyOffset=0;else switch(t.boxWidth=u,t.j){case 1:t.justifyOffset=-t.boxWidth;break;case 2:t.justifyOffset=-t.boxWidth/2;break;default:t.justifyOffset=0}t.lineWidths=c;for(var M,k,D,F,w=n.a,z=w.length,I=[],V=0;V<z;V+=1){for((M=w[V]).a.sc&&(t.strokeColorAnim=!0),M.a.sw&&(t.strokeWidthAnim=!0),(M.a.fc||M.a.fh||M.a.fs||M.a.fb)&&(t.fillColorAnim=!0),D=M.s.b,_=F=0;_<S;_+=1)(k=o[_]).anIndexes[V]=F,(1==D&&""!==k.val||2==D&&""!==k.val&&" "!==k.val||3==D&&(k.n||" "==k.val||_==S-1)||4==D&&(k.n||_==S-1))&&(1===M.s.rn&&I.push(F),F+=1);n.a[V].s.totalChars=F;var B,G=-1;if(1===M.s.rn)for(_=0;_<S;_+=1)G!=(k=o[_]).anIndexes[V]&&(G=k.anIndexes[V],B=I.splice(Math.floor(Math.random()*I.length),1)[0]),k.anIndexes[V]=B}t.yOffset=t.finalLineHeight||1.2*t.finalSize,t.ls=t.ls||0,t.ascent=y.ascent*t.finalSize/100},TextProperty.prototype.updateDocumentData=function(t,e){e=void 0===e?this.keysIndex:e;var i=this.copyData({},this.data.d.k[e].s),i=this.copyData(i,t);this.data.d.k[e].s=i,this.recalculate(e),this.setCurrentData(i),this.elem.addDynamicProperty(this)},TextProperty.prototype.recalculate=function(t){t=this.data.d.k[t].s;t.__complete=!1,this.keysIndex=0,this._isFirstFrame=!0,this.getValue(t)},TextProperty.prototype.canResizeFont=function(t){this.canResize=t,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)},TextProperty.prototype.setMinimumFontSize=function(t){this.minimumFontSize=Math.floor(t)||1,this.recalculate(this.keysIndex),this.elem.addDynamicProperty(this)};var TextSelectorProp=(()=>{var o=Math.max,h=Math.min,l=Math.floor;function r(t,e){this._currentTextLength=-1,this.k=!1,this.data=e,this.elem=t,this.comp=t.comp,this.finalS=0,this.finalE=0,this.initDynamicPropertyContainer(t),this.s=PropertyFactory.getProp(t,e.s||{k:0},0,0,this),"e"in e?this.e=PropertyFactory.getProp(t,e.e,0,0,this):this.e={v:100},this.o=PropertyFactory.getProp(t,e.o||{k:0},0,0,this),this.xe=PropertyFactory.getProp(t,e.xe||{k:0},0,0,this),this.ne=PropertyFactory.getProp(t,e.ne||{k:0},0,0,this),this.sm=PropertyFactory.getProp(t,e.sm||{k:100},0,0,this),this.a=PropertyFactory.getProp(t,e.a,0,.01,this),this.dynamicProperties.length||this.getValue()}return r.prototype={getMult:function(t){this._currentTextLength!==this.elem.textProperty.currentData.l.length&&this.getValue();var e,i=0,r=0,s=1,a=1,i=(0<this.ne.v?i=this.ne.v/100:r=-this.ne.v/100,0<this.xe.v?s=1-this.xe.v/100:a=1+this.xe.v/100,BezierFactory.getBezierEasing(i,r,s,a).get),r=0,s=this.finalS,a=this.finalE,n=this.data.sh;return r=2===n?i(r=a===s?a<=t?1:0:o(0,h(.5/(a-s)+(t-s)/(a-s),1))):3===n?i(r=a===s?a<=t?0:1:1-o(0,h(.5/(a-s)+(t-s)/(a-s),1))):4===n?(a===s?r=0:(r=o(0,h(.5/(a-s)+(t-s)/(a-s),1)))<.5?r*=2:r=1-2*(r-.5),i(r)):i(r=5===n?a===s?0:(e=-(i=a-s)/2+(t=h(o(0,t+.5-s),a-s)),i=i/2,Math.sqrt(1-e*e/(i*i))):6===n?a===s?0:(t=h(o(0,t+.5-s),a-s),(1+Math.cos(Math.PI+2*Math.PI*t/(a-s)))/2):t>=l(s)?o(0,h(t-s<0?h(a,1)-(s-t):a-t,1)):r),100!==this.sm.v&&(r<(i=.5-.5*(e=0===(e=.01*this.sm.v)?1e-8:e))?r=0:1<(r=(r-i)/e)&&(r=1)),r*this.a.v},getValue:function(t){this.iterateDynamicProperties(),this._mdf=t||this._mdf,this._currentTextLength=this.elem.textProperty.currentData.l.length||0,t&&2===this.data.r&&(this.e.v=this._currentTextLength);var t=2===this.data.r?1:100/this.data.totalChars,e=this.o.v/t,i=this.s.v/t+e,t=this.e.v/t+e;t<i&&(e=i,i=t,t=e),this.finalS=i,this.finalE=t}},extendPrototype([DynamicPropertyContainer],r),{getTextSelectorProp:function(t,e,i){return new r(t,e)}}})();function TextAnimatorDataProperty(t,e,i){var r={propType:!1},s=PropertyFactory.getProp,a=e.a;this.a={r:a.r?s(t,a.r,0,degToRads,i):r,rx:a.rx?s(t,a.rx,0,degToRads,i):r,ry:a.ry?s(t,a.ry,0,degToRads,i):r,sk:a.sk?s(t,a.sk,0,degToRads,i):r,sa:a.sa?s(t,a.sa,0,degToRads,i):r,s:a.s?s(t,a.s,1,.01,i):r,a:a.a?s(t,a.a,1,0,i):r,o:a.o?s(t,a.o,0,.01,i):r,p:a.p?s(t,a.p,1,0,i):r,sw:a.sw?s(t,a.sw,0,0,i):r,sc:a.sc?s(t,a.sc,1,0,i):r,fc:a.fc?s(t,a.fc,1,0,i):r,fh:a.fh?s(t,a.fh,0,0,i):r,fs:a.fs?s(t,a.fs,0,.01,i):r,fb:a.fb?s(t,a.fb,0,.01,i):r,t:a.t?s(t,a.t,0,0,i):r},this.s=TextSelectorProp.getTextSelectorProp(t,e.s,i),this.s.t=e.s.t}function TextAnimatorProperty(t,e,i){this._isFirstFrame=!0,this._hasMaskedPath=!1,this._frameId=-1,this._textData=t,this._renderType=e,this._elem=i,this._animatorsData=createSizedArray(this._textData.a.length),this._pathData={},this._moreOptions={alignment:{}},this.renderedLetters=[],this.lettersChangedFlag=!1,this.initDynamicPropertyContainer(i)}function ITextElement(){}TextAnimatorProperty.prototype.searchProperties=function(){for(var t,e=this._textData.a.length,i=PropertyFactory.getProp,r=0;r<e;r+=1)t=this._textData.a[r],this._animatorsData[r]=new TextAnimatorDataProperty(this._elem,t,this);this._textData.p&&"m"in this._textData.p?(this._pathData={a:i(this._elem,this._textData.p.a,0,0,this),f:i(this._elem,this._textData.p.f,0,0,this),l:i(this._elem,this._textData.p.l,0,0,this),r:i(this._elem,this._textData.p.r,0,0,this),p:i(this._elem,this._textData.p.p,0,0,this),m:this._elem.maskManager.getMaskProperty(this._textData.p.m)},this._hasMaskedPath=!0):this._hasMaskedPath=!1,this._moreOptions.alignment=i(this._elem,this._textData.m.a,1,0,this)},TextAnimatorProperty.prototype.getMeasures=function(t,R){if(this.lettersChangedFlag=R,this._mdf||this._isFirstFrame||R||this._hasMaskedPath&&this._pathData.m._mdf){this._isFirstFrame=!1;var e,i,r,L,s,a,n,o,h,z,l,G,p,m=this._moreOptions.alignment.v,f=this._animatorsData,c=this._textData,d=this.mHelper,O=this._renderType,N=this.renderedLetters.length,u=t.l;if(this._hasMaskedPath){if(p=this._pathData.m,!this._pathData.n||this._pathData._mdf){for(var y,g=p.v,v={tLength:0,segments:[]},b=(g=this._pathData.r.v?g.reverse():g)._length-1,x=l=0;x<b;x+=1)y=bez.buildBezierData(g.v[x],g.v[x+1],[g.o[x][0]-g.v[x][0],g.o[x][1]-g.v[x][1]],[g.i[x+1][0]-g.v[x+1][0],g.i[x+1][1]-g.v[x+1][1]]),v.tLength+=y.segmentLength,v.segments.push(y),l+=y.segmentLength;x=b,p.v.c&&(y=bez.buildBezierData(g.v[x],g.v[0],[g.o[x][0]-g.v[x][0],g.o[x][1]-g.v[x][1]],[g.i[0][0]-g.v[0][0],g.i[0][1]-g.v[0][1]]),v.tLength+=y.segmentLength,v.segments.push(y),l+=y.segmentLength),this._pathData.pi=v}if(v=this._pathData.pi,e=this._pathData.f.v,s=1,L=!(r=a=0),h=v.segments,e<0&&p.v.c)for(v.tLength<Math.abs(e)&&(e=-Math.abs(e)%v.tLength),s=(o=h[a=h.length-1].points).length-1;e<0;)e+=o[s].partialLength,--s<0&&(s=(o=h[--a].points).length-1);n=(o=h[a].points)[s-1],z=(i=o[s]).partialLength}b=u.length;var P,H,E,S,j,q,C,_,A,T,M,W,$,Y,J,X,k=0,Z=0,K=1.2*t.finalSize*.714,U=!0,D=f.length,F=-1,Q=e,tt=a,et=s,it=-1,rt="",st=this.defaultPropsArray;if(2===t.j||1===t.j){var w=0,at=0,nt=2===t.j?-.5:-1,I=0,ot=!0;for(x=0;x<b;x+=1)if(u[x].n){for(w&&(w+=at);I<x;)u[I].animatorJustifyOffset=w,I+=1;ot=!(w=0)}else{for(B=0;B<D;B+=1)(P=f[B].a).t.propType&&(ot&&2===t.j&&(at+=P.t.v*nt),(E=f[B].s.getMult(u[x].anIndexes[B],c.a[B].s.totalChars)).length?w+=P.t.v*E[0]*nt:w+=P.t.v*E*nt);ot=!1}for(w&&(w+=at);I<x;)u[I].animatorJustifyOffset=w,I+=1}for(x=0;x<b;x+=1){if(d.reset(),C=1,u[x].n)k=0,Z=Z+t.yOffset+(U?1:0),e=Q,U=!1,this._hasMaskedPath&&(n=(o=h[a=tt].points)[(s=et)-1],z=(i=o[s]).partialLength,r=0),J=W=Y=rt="",st=this.defaultPropsArray;else{if(this._hasMaskedPath){if(it!==u[x].line){switch(t.j){case 1:e+=l-t.lineWidths[u[x].line];break;case 2:e+=(l-t.lineWidths[u[x].line])/2}it=u[x].line}F!==u[x].ind&&(u[F]&&(e+=u[F].extra),e+=u[x].an/2,F=u[x].ind),e+=m[0]*u[x].an*.005;for(var V=0,B=0;B<D;B+=1)(P=f[B].a).p.propType&&((E=f[B].s.getMult(u[x].anIndexes[B],c.a[B].s.totalChars)).length?V+=P.p.v[0]*E[0]:V+=P.p.v[0]*E),P.a.propType&&((E=f[B].s.getMult(u[x].anIndexes[B],c.a[B].s.totalChars)).length?V+=P.a.v[0]*E[0]:V+=P.a.v[0]*E);for(L=!0,this._pathData.a.v&&(e=.5*u[0].an+(l-this._pathData.f.v-.5*u[0].an-.5*u[u.length-1].an)*F/(b-1),e+=this._pathData.f.v);L;)e+V<=r+z||!o?(G=(e+V-r)/i.partialLength,j=n.point[0]+(i.point[0]-n.point[0])*G,q=n.point[1]+(i.point[1]-n.point[1])*G,d.translate(-m[0]*u[x].an*.005,-m[1]*K*.01),L=!1):o&&(r+=i.partialLength,(s+=1)>=o.length&&(s=0,o=h[a+=1]?h[a].points:p.v.c?h[a=s=0].points:(r-=i.partialLength,null)),o)&&(n=i,z=(i=o[s]).partialLength);S=u[x].an/2-u[x].add,d.translate(-S,0,0)}else S=u[x].an/2-u[x].add,d.translate(-S,0,0),d.translate(-m[0]*u[x].an*.005,-m[1]*K*.01,0);for(B=0;B<D;B+=1)(P=f[B].a).t.propType&&(E=f[B].s.getMult(u[x].anIndexes[B],c.a[B].s.totalChars),0===k&&0===t.j||(this._hasMaskedPath?E.length?e+=P.t.v*E[0]:e+=P.t.v*E:E.length?k+=P.t.v*E[0]:k+=P.t.v*E));for(t.strokeWidthAnim&&(A=t.sw||0),t.strokeColorAnim&&(_=t.sc?[t.sc[0],t.sc[1],t.sc[2]]:[0,0,0]),t.fillColorAnim&&t.fc&&(T=[t.fc[0],t.fc[1],t.fc[2]]),B=0;B<D;B+=1)(P=f[B].a).a.propType&&((E=f[B].s.getMult(u[x].anIndexes[B],c.a[B].s.totalChars)).length?d.translate(-P.a.v[0]*E[0],-P.a.v[1]*E[1],P.a.v[2]*E[2]):d.translate(-P.a.v[0]*E,-P.a.v[1]*E,P.a.v[2]*E));for(B=0;B<D;B+=1)(P=f[B].a).s.propType&&((E=f[B].s.getMult(u[x].anIndexes[B],c.a[B].s.totalChars)).length?d.scale(1+(P.s.v[0]-1)*E[0],1+(P.s.v[1]-1)*E[1],1):d.scale(1+(P.s.v[0]-1)*E,1+(P.s.v[1]-1)*E,1));for(B=0;B<D;B+=1){if(P=f[B].a,E=f[B].s.getMult(u[x].anIndexes[B],c.a[B].s.totalChars),P.sk.propType&&(E.length?d.skewFromAxis(-P.sk.v*E[0],P.sa.v*E[1]):d.skewFromAxis(-P.sk.v*E,P.sa.v*E)),P.r.propType&&(E.length?d.rotateZ(-P.r.v*E[2]):d.rotateZ(-P.r.v*E)),P.ry.propType&&(E.length?d.rotateY(P.ry.v*E[1]):d.rotateY(P.ry.v*E)),P.rx.propType&&(E.length?d.rotateX(P.rx.v*E[0]):d.rotateX(P.rx.v*E)),P.o.propType&&(E.length?C+=(P.o.v*E[0]-C)*E[0]:C+=(P.o.v*E-C)*E),t.strokeWidthAnim&&P.sw.propType&&(E.length?A+=P.sw.v*E[0]:A+=P.sw.v*E),t.strokeColorAnim&&P.sc.propType)for(M=0;M<3;M+=1)E.length?_[M]+=(P.sc.v[M]-_[M])*E[0]:_[M]+=(P.sc.v[M]-_[M])*E;if(t.fillColorAnim&&t.fc){if(P.fc.propType)for(M=0;M<3;M+=1)E.length?T[M]+=(P.fc.v[M]-T[M])*E[0]:T[M]+=(P.fc.v[M]-T[M])*E;P.fh.propType&&(T=E.length?addHueToRGB(T,P.fh.v*E[0]):addHueToRGB(T,P.fh.v*E)),P.fs.propType&&(T=E.length?addSaturationToRGB(T,P.fs.v*E[0]):addSaturationToRGB(T,P.fs.v*E)),P.fb.propType&&(T=E.length?addBrightnessToRGB(T,P.fb.v*E[0]):addBrightnessToRGB(T,P.fb.v*E))}}for(B=0;B<D;B+=1)(P=f[B].a).p.propType&&(E=f[B].s.getMult(u[x].anIndexes[B],c.a[B].s.totalChars),this._hasMaskedPath?E.length?d.translate(0,P.p.v[1]*E[0],-P.p.v[2]*E[1]):d.translate(0,P.p.v[1]*E,-P.p.v[2]*E):E.length?d.translate(P.p.v[0]*E[0],P.p.v[1]*E[1],-P.p.v[2]*E[2]):d.translate(P.p.v[0]*E,P.p.v[1]*E,-P.p.v[2]*E));if(t.strokeWidthAnim&&(W=A<0?0:A),t.strokeColorAnim&&($="rgb("+Math.round(255*_[0])+","+Math.round(255*_[1])+","+Math.round(255*_[2])+")"),t.fillColorAnim&&t.fc&&(Y="rgb("+Math.round(255*T[0])+","+Math.round(255*T[1])+","+Math.round(255*T[2])+")"),this._hasMaskedPath)d.translate(0,-t.ls),d.translate(0,m[1]*K*.01+Z,0),this._pathData.p.v&&(X=(i.point[1]-n.point[1])/(i.point[0]-n.point[0]),X=180*Math.atan(X)/Math.PI,i.point[0]<n.point[0]&&(X+=180),d.rotate(-X*Math.PI/180)),d.translate(j,q,0),e-=m[0]*u[x].an*.005,u[x+1]&&F!==u[x+1].ind&&(e=(e+=u[x].an/2)+.001*t.tr*t.finalSize);else{switch(d.translate(k,Z,0),t.ps&&d.translate(t.ps[0],t.ps[1]+t.ascent,0),t.j){case 1:d.translate(u[x].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[u[x].line]),0,0);break;case 2:d.translate(u[x].animatorJustifyOffset+t.justifyOffset+(t.boxWidth-t.lineWidths[u[x].line])/2,0,0)}d.translate(0,-t.ls),d.translate(S,0,0),d.translate(m[0]*u[x].an*.005,m[1]*K*.01,0),k+=u[x].l+.001*t.tr*t.finalSize}"html"===O?rt=d.toCSS():"svg"===O?rt=d.to2dCSS():st=[d.props[0],d.props[1],d.props[2],d.props[3],d.props[4],d.props[5],d.props[6],d.props[7],d.props[8],d.props[9],d.props[10],d.props[11],d.props[12],d.props[13],d.props[14],d.props[15]],J=C}N<=x?(H=new LetterProps(J,W,$,Y,rt,st),this.renderedLetters.push(H),N+=1,this.lettersChangedFlag=!0):(H=this.renderedLetters[x],this.lettersChangedFlag=H.update(J,W,$,Y,rt,st)||this.lettersChangedFlag)}}},TextAnimatorProperty.prototype.getValue=function(){this._elem.globalData.frameId!==this._frameId&&(this._frameId=this._elem.globalData.frameId,this.iterateDynamicProperties())},TextAnimatorProperty.prototype.mHelper=new Matrix,TextAnimatorProperty.prototype.defaultPropsArray=[],extendPrototype([DynamicPropertyContainer],TextAnimatorProperty),ITextElement.prototype.initElement=function(t,e,i){this.lettersChangedFlag=!0,this.initFrame(),this.initBaseData(t,e,i),this.textProperty=new TextProperty(this,t.t,this.dynamicProperties),this.textAnimator=new TextAnimatorProperty(t.t,this.renderType,this),this.initTransform(t,e,i),this.initHierarchy(),this.initRenderable(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),this.createContent(),this.hide(),this.textAnimator.searchProperties(this.dynamicProperties)},ITextElement.prototype.prepareFrame=function(t){this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange)},ITextElement.prototype.createPathShape=function(t,e){for(var i,r=e.length,s="",a=0;a<r;a+=1)"sh"===e[a].ty&&(i=e[a].ks.k,s+=buildShapeString(i,i.i.length,!0,t));return s},ITextElement.prototype.updateDocumentData=function(t,e){this.textProperty.updateDocumentData(t,e)},ITextElement.prototype.canResizeFont=function(t){this.textProperty.canResizeFont(t)},ITextElement.prototype.setMinimumFontSize=function(t){this.textProperty.setMinimumFontSize(t)},ITextElement.prototype.applyTextPropertiesToMatrix=function(t,e,i,r,s){switch(t.ps&&e.translate(t.ps[0],t.ps[1]+t.ascent,0),e.translate(0,-t.ls,0),t.j){case 1:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i]),0,0);break;case 2:e.translate(t.justifyOffset+(t.boxWidth-t.lineWidths[i])/2,0,0)}e.translate(r,s,0)},ITextElement.prototype.buildColor=function(t){return"rgb("+Math.round(255*t[0])+","+Math.round(255*t[1])+","+Math.round(255*t[2])+")"},ITextElement.prototype.emptyProp=new LetterProps,ITextElement.prototype.destroy=function(){},ITextElement.prototype.validateText=function(){(this.textProperty._mdf||this.textProperty._isFirstFrame)&&(this.buildNewText(),this.textProperty._isFirstFrame=!1,this.textProperty._mdf=!1)};var emptyShapeData={shapes:[]};function SVGTextLottieElement(t,e,i){this.textSpans=[],this.renderType="svg",this.initElement(t,e,i)}function ISolidElement(t,e,i){this.initElement(t,e,i)}function NullElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initFrame(),this.initTransform(t,e,i),this.initHierarchy()}function SVGRendererBase(){}function ICompElement(){}function SVGCompElement(t,e,i){this.layers=t.layers,this.supports3d=!0,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function SVGRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.svgElement=createNS("svg");var t="",i=(e&&e.title&&(i=createNS("title"),r=createElementID(),i.setAttribute("id",r),i.textContent=e.title,this.svgElement.appendChild(i),t+=r),e&&e.description&&(i=createNS("desc"),r=createElementID(),i.setAttribute("id",r),i.textContent=e.description,this.svgElement.appendChild(i),t+=" "+r),t&&this.svgElement.setAttribute("aria-labelledby",t),createNS("defs")),r=(this.svgElement.appendChild(i),createNS("g"));this.svgElement.appendChild(r),this.layerElement=r,this.renderConfig={preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",progressiveLoad:e&&e.progressiveLoad||!1,hideOnTransparent:!(e&&!1===e.hideOnTransparent),viewBoxOnly:e&&e.viewBoxOnly||!1,viewBoxSize:e&&e.viewBoxSize||!1,className:e&&e.className||"",id:e&&e.id||"",focusable:e&&e.focusable,filterSize:{width:e&&e.filterSize&&e.filterSize.width||"100%",height:e&&e.filterSize&&e.filterSize.height||"100%",x:e&&e.filterSize&&e.filterSize.x||"0%",y:e&&e.filterSize&&e.filterSize.y||"0%"},width:e&&e.width,height:e&&e.height,runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,defs:i,renderConfig:this.renderConfig},this.elements=[],this.pendingElements=[],this.destroyed=!1,this.rendererType="svg"}function ShapeTransformManager(){this.sequences={},this.sequenceList=[],this.transform_key_count=0}extendPrototype([BaseElement,TransformElement,SVGBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],SVGTextLottieElement),SVGTextLottieElement.prototype.createContent=function(){this.data.singleShape&&!this.globalData.fontManager.chars&&(this.textContainer=createNS("text"))},SVGTextLottieElement.prototype.buildTextContents=function(t){for(var e=0,i=t.length,r=[],s="";e<i;)t[e]===String.fromCharCode(13)||t[e]===String.fromCharCode(3)?(r.push(s),s=""):s+=t[e],e+=1;return r.push(s),r},SVGTextLottieElement.prototype.buildShapeData=function(t,e){var i;return t.shapes&&t.shapes.length&&(i=t.shapes[0]).it&&(i=i.it[i.it.length-1]).s&&(i.s.k[0]=e,i.s.k[1]=e),t},SVGTextLottieElement.prototype.buildNewText=function(){this.addDynamicProperty(this);var t,e,i=this.textProperty.currentData,r=(this.renderedLetters=createSizedArray(i?i.l.length:0),i.fc?this.layerElement.setAttribute("fill",this.buildColor(i.fc)):this.layerElement.setAttribute("fill","rgba(0,0,0,0)"),i.sc&&(this.layerElement.setAttribute("stroke",this.buildColor(i.sc)),this.layerElement.setAttribute("stroke-width",i.sw)),this.layerElement.setAttribute("font-size",i.finalSize),this.globalData.fontManager.getFontByName(i.f)),s=(r.fClass?this.layerElement.setAttribute("class",r.fClass):(this.layerElement.setAttribute("font-family",r.fFamily),t=i.fWeight,e=i.fStyle,this.layerElement.setAttribute("font-style",e),this.layerElement.setAttribute("font-weight",t)),this.layerElement.setAttribute("aria-label",i.t),i.l||[]),a=!!this.globalData.fontManager.chars,n=(x=s.length,this.mHelper),o=this.data.singleShape,h=0,l=0,p=!0,m=.001*i.tr*i.finalSize;if(!o||a||i.sz){var f,c,d,u,y=this.textSpans.length;for(P=0;P<x;P+=1)this.textSpans[P]||(this.textSpans[P]={span:null,childSpan:null,glyph:null}),a&&o&&0!==P||(f=P<y?this.textSpans[P].span:createNS(a?"g":"text"),y<=P&&(f.setAttribute("stroke-linecap","butt"),f.setAttribute("stroke-linejoin","round"),f.setAttribute("stroke-miterlimit","4"),this.textSpans[P].span=f,a&&(u=createNS("g"),f.appendChild(u),this.textSpans[P].childSpan=u),this.textSpans[P].span=f,this.layerElement.appendChild(f)),f.style.display="inherit"),n.reset(),o&&(s[P].n&&(h=-m,l=l+i.yOffset+(p?1:0),p=!1),this.applyTextPropertiesToMatrix(i,n,s[P].line,h,l),h=h+(s[P].l||0)+m),a?(c=1===(u=this.globalData.fontManager.getCharData(i.finalText[P],r.fStyle,this.globalData.fontManager.getFontByName(i.f).fFamily)).t?new SVGCompElement(u.data,this.globalData,this):(c=emptyShapeData,new SVGShapeElement(c=u.data&&u.data.shapes?this.buildShapeData(u.data,i.finalSize):c,this.globalData,this)),this.textSpans[P].glyph&&(d=this.textSpans[P].glyph,this.textSpans[P].childSpan.removeChild(d.layerElement),d.destroy()),(this.textSpans[P].glyph=c)._debug=!0,c.prepareFrame(0),c.renderFrame(),this.textSpans[P].childSpan.appendChild(c.layerElement),1===u.t&&this.textSpans[P].childSpan.setAttribute("transform","scale("+i.finalSize/100+","+i.finalSize/100+")")):(o&&f.setAttribute("transform","translate("+n.props[12]+","+n.props[13]+")"),f.textContent=s[P].val,f.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"));o&&f&&f.setAttribute("d","")}else{var g=this.textContainer,v="start";switch(i.j){case 1:v="end";break;case 2:v="middle";break;default:v="start"}g.setAttribute("text-anchor",v),g.setAttribute("letter-spacing",m);for(var b=this.buildTextContents(i.finalText),x=b.length,l=i.ps?i.ps[1]+i.ascent:0,P=0;P<x;P+=1)(f=this.textSpans[P].span||createNS("tspan")).textContent=b[P],f.setAttribute("x",0),f.setAttribute("y",l),f.style.display="inherit",g.appendChild(f),this.textSpans[P]||(this.textSpans[P]={span:null,glyph:null}),this.textSpans[P].span=f,l+=i.finalLineHeight;this.layerElement.appendChild(g)}for(;P<this.textSpans.length;)this.textSpans[P].span.style.display="none",P+=1;this._sizeChanged=!0},SVGTextLottieElement.prototype.sourceRectAtTime=function(){var t;return this.prepareFrame(this.comp.renderedFrame-this.data.st),this.renderInnerContent(),this._sizeChanged&&(this._sizeChanged=!1,t=this.layerElement.getBBox(),this.bbox={top:t.y,left:t.x,width:t.width,height:t.height}),this.bbox},SVGTextLottieElement.prototype.getValue=function(){var t,e,i=this.textSpans.length;for(this.renderedFrame=this.comp.renderedFrame,t=0;t<i;t+=1)(e=this.textSpans[t].glyph)&&(e.prepareFrame(this.comp.renderedFrame-this.data.st),e._mdf)&&(this._mdf=!0)},SVGTextLottieElement.prototype.renderInnerContent=function(){if(this.validateText(),(!this.data.singleShape||this._mdf)&&(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag)){this._sizeChanged=!0;for(var t,e,i,r=this.textAnimator.renderedLetters,s=this.textProperty.currentData.l,a=s.length,n=0;n<a;n+=1)s[n].n||(t=r[n],e=this.textSpans[n].span,(i=this.textSpans[n].glyph)&&i.renderFrame(),t._mdf.m&&e.setAttribute("transform",t.m),t._mdf.o&&e.setAttribute("opacity",t.o),t._mdf.sw&&e.setAttribute("stroke-width",t.sw),t._mdf.sc&&e.setAttribute("stroke",t.sc),t._mdf.fc&&e.setAttribute("fill",t.fc))}},extendPrototype([IImageElement],ISolidElement),ISolidElement.prototype.createContent=function(){var t=createNS("rect");t.setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.layerElement.appendChild(t)},NullElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},NullElement.prototype.renderFrame=function(){},NullElement.prototype.getBaseElement=function(){return null},NullElement.prototype.destroy=function(){},NullElement.prototype.sourceRectAtTime=function(){},NullElement.prototype.hide=function(){},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement],NullElement),extendPrototype([BaseRenderer],SVGRendererBase),SVGRendererBase.prototype.createNull=function(t){return new NullElement(t,this.globalData,this)},SVGRendererBase.prototype.createShape=function(t){return new SVGShapeElement(t,this.globalData,this)},SVGRendererBase.prototype.createText=function(t){return new SVGTextLottieElement(t,this.globalData,this)},SVGRendererBase.prototype.createImage=function(t){return new IImageElement(t,this.globalData,this)},SVGRendererBase.prototype.createSolid=function(t){return new ISolidElement(t,this.globalData,this)},SVGRendererBase.prototype.configAnimation=function(t){this.svgElement.setAttribute("xmlns","http://www.w3.org/2000/svg"),this.svgElement.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),this.renderConfig.viewBoxSize?this.svgElement.setAttribute("viewBox",this.renderConfig.viewBoxSize):this.svgElement.setAttribute("viewBox","0 0 "+t.w+" "+t.h),this.renderConfig.viewBoxOnly||(this.svgElement.setAttribute("width",t.w),this.svgElement.setAttribute("height",t.h),this.svgElement.style.width="100%",this.svgElement.style.height="100%",this.svgElement.style.transform="translate3d(0,0,0)",this.svgElement.style.contentVisibility=this.renderConfig.contentVisibility),this.renderConfig.width&&this.svgElement.setAttribute("width",this.renderConfig.width),this.renderConfig.height&&this.svgElement.setAttribute("height",this.renderConfig.height),this.renderConfig.className&&this.svgElement.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.svgElement.setAttribute("id",this.renderConfig.id),void 0!==this.renderConfig.focusable&&this.svgElement.setAttribute("focusable",this.renderConfig.focusable),this.svgElement.setAttribute("preserveAspectRatio",this.renderConfig.preserveAspectRatio),this.animationItem.wrapper.appendChild(this.svgElement);var e=this.globalData.defs,i=(this.setupGlobalData(t,e),this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.data=t,createNS("clipPath")),r=createNS("rect"),s=(r.setAttribute("width",t.w),r.setAttribute("height",t.h),r.setAttribute("x",0),r.setAttribute("y",0),createElementID());i.setAttribute("id",s),i.appendChild(r),this.layerElement.setAttribute("clip-path","url("+getLocationHref()+"#"+s+")"),e.appendChild(i),this.layers=t.layers,this.elements=createSizedArray(t.layers.length)},SVGRendererBase.prototype.destroy=function(){this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.layerElement=null,this.globalData.defs=null;for(var t=this.layers?this.layers.length:0,e=0;e<t;e+=1)this.elements[e]&&this.elements[e].destroy&&this.elements[e].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},SVGRendererBase.prototype.updateContainerSize=function(){},SVGRendererBase.prototype.findIndexByInd=function(t){for(var e=0,i=this.layers.length,e=0;e<i;e+=1)if(this.layers[e].ind===t)return e;return-1},SVGRendererBase.prototype.buildItem=function(t){var e,i,r=this.elements;r[t]||99===this.layers[t].ty||(r[t]=!0,e=this.createItem(this.layers[t]),r[t]=e,getExpressionsPlugin()&&(0===this.layers[t].ty&&this.globalData.projectInterface.registerComposition(e),e.initExpressions()),this.appendElementInPos(e,t),this.layers[t].tt&&-1!==(i="tp"in this.layers[t]?this.findIndexByInd(this.layers[t].tp):t-1)&&(this.elements[i]&&!0!==this.elements[i]?(r=r[i].getMatte(this.layers[t].tt),e.setMatte(r)):(this.buildItem(i),this.addPendingElement(e))))},SVGRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;){var t=this.pendingElements.pop();if(t.checkParenting(),t.data.tt)for(var e=0,i=this.elements.length;e<i;){if(this.elements[e]===t){var r="tp"in t.data?this.findIndexByInd(t.data.tp):e-1,r=this.elements[r].getMatte(this.layers[e].tt);t.setMatte(r);break}e+=1}}},SVGRendererBase.prototype.renderFrame=function(t){if(this.renderedFrame!==t&&!this.destroyed){null===t?t=this.renderedFrame:this.renderedFrame=t,this.globalData.frameNum=t,this.globalData.frameId+=1,this.globalData.projectInterface.currentFrame=t,this.globalData._mdf=!1;var e,i=this.layers.length;for(this.completeLayers||this.checkLayers(t),e=i-1;0<=e;--e)(this.completeLayers||this.elements[e])&&this.elements[e].prepareFrame(t-this.layers[e].st);if(this.globalData._mdf)for(e=0;e<i;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()}},SVGRendererBase.prototype.appendElementInPos=function(t,e){t=t.getBaseElement();if(t){for(var i,r=0;r<e;)this.elements[r]&&!0!==this.elements[r]&&this.elements[r].getBaseElement()&&(i=this.elements[r].getBaseElement()),r+=1;i?this.layerElement.insertBefore(t,i):this.layerElement.appendChild(t)}},SVGRendererBase.prototype.hide=function(){this.layerElement.style.display="none"},SVGRendererBase.prototype.show=function(){this.layerElement.style.display="block"},extendPrototype([BaseElement,TransformElement,HierarchyElement,FrameElement,RenderableDOMElement],ICompElement),ICompElement.prototype.initElement=function(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initTransform(t,e,i),this.initRenderable(),this.initHierarchy(),this.initRendererElement(),this.createContainerElements(),this.createRenderableComponents(),!this.data.xt&&e.progressiveLoad||this.buildAllItems(),this.hide()},ICompElement.prototype.prepareFrame=function(t){if(this._mdf=!1,this.prepareRenderableFrame(t),this.prepareProperties(t,this.isInRange),this.isInRange||this.data.xt){this.tm._placeholder?this.renderedFrame=t/this.data.sr:((t=this.tm.v)===this.data.op&&(t=this.data.op-1),this.renderedFrame=t);var e,t=this.elements.length;for(this.completeLayers||this.checkLayers(this.renderedFrame),e=t-1;0<=e;--e)(this.completeLayers||this.elements[e])&&(this.elements[e].prepareFrame(this.renderedFrame-this.layers[e].st),this.elements[e]._mdf)&&(this._mdf=!0)}},ICompElement.prototype.renderInnerContent=function(){for(var t=this.layers.length,e=0;e<t;e+=1)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()},ICompElement.prototype.setElements=function(t){this.elements=t},ICompElement.prototype.getElements=function(){return this.elements},ICompElement.prototype.destroyElements=function(){for(var t=this.layers.length,e=0;e<t;e+=1)this.elements[e]&&this.elements[e].destroy()},ICompElement.prototype.destroy=function(){this.destroyElements(),this.destroyBaseElement()},extendPrototype([SVGRendererBase,ICompElement,SVGBaseElement],SVGCompElement),SVGCompElement.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},extendPrototype([SVGRendererBase],SVGRenderer),SVGRenderer.prototype.createComp=function(t){return new SVGCompElement(t,this.globalData,this)},ShapeTransformManager.prototype={addTransformSequence:function(t){for(var e=t.length,i="_",r=0;r<e;r+=1)i+=t[r].transform.key+"_";var s=this.sequences[i];return s||(s={transforms:[].concat(t),finalTransform:new Matrix,_mdf:!1},this.sequences[i]=s,this.sequenceList.push(s)),s},processSequence:function(t,e){for(var i=0,r=t.transforms.length,s=e;i<r&&!e;){if(t.transforms[i].transform.mProps._mdf){s=!0;break}i+=1}if(s)for(t.finalTransform.reset(),i=r-1;0<=i;--i)t.finalTransform.multiply(t.transforms[i].transform.mProps.v);t._mdf=s},processSequences:function(t){for(var e=this.sequenceList.length,i=0;i<e;i+=1)this.processSequence(this.sequenceList[i],t)},getNewKey:function(){return this.transform_key_count+=1,"_"+this.transform_key_count}};var lumaLoader=function(){var r="__lottie_element_luma_buffer",s=null,a=null,n=null;function e(){var t,e,i;s||(t=createNS("svg"),e=createNS("filter"),i=createNS("feColorMatrix"),e.setAttribute("id",r),i.setAttribute("type","matrix"),i.setAttribute("color-interpolation-filters","sRGB"),i.setAttribute("values","0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0"),e.appendChild(i),t.appendChild(e),t.setAttribute("id",r+"_svg"),featureSupport.svgLumaHidden&&(t.style.display="none"),n=t,document.body.appendChild(n),s=createTag("canvas"),(a=s.getContext("2d")).filter="url(#"+r+")",a.fillStyle="rgba(0,0,0,0)",a.fillRect(0,0,1,1))}return{load:e,get:function(t){return s||e(),s.width=t.width,s.height=t.height,a.filter="url(#"+r+")",s}}};function createCanvas(t,e){var i;return featureSupport.offscreenCanvas?new OffscreenCanvas(t,e):((i=createTag("canvas")).width=t,i.height=e,i)}var assetLoader={loadLumaCanvas:lumaLoader.load,getLumaCanvas:lumaLoader.get,createCanvas:createCanvas},registeredEffects={};function CVEffects(t){var e,i=t.data.ef?t.data.ef.length:0;for(this.filters=[],e=0;e<i;e+=1){r=null;var r,s=t.data.ef[e].ty;(r=registeredEffects[s]?new registeredEffects[s].effect(t.effectsManager.effectElements[e],t):r)&&this.filters.push(r)}this.filters.length&&t.addRenderableComponent(this)}function registerEffect(t,e){registeredEffects[t]={effect:e}}function CVMaskElement(t,e){this.data=t,this.element=e,this.masksProperties=this.data.masksProperties||[],this.viewData=createSizedArray(this.masksProperties.length);for(var i=this.masksProperties.length,r=!1,s=0;s<i;s+=1)"n"!==this.masksProperties[s].mode&&(r=!0),this.viewData[s]=ShapePropertyFactory.getShapeProp(this.element,this.masksProperties[s],3);(this.hasMasks=r)&&this.element.addRenderableComponent(this)}function CVBaseElement(){}CVEffects.prototype.renderFrame=function(t){for(var e=this.filters.length,i=0;i<e;i+=1)this.filters[i].renderFrame(t)},CVEffects.prototype.getEffects=function(t){for(var e=this.filters.length,i=[],r=0;r<e;r+=1)this.filters[r].type===t&&i.push(this.filters[r]);return i},CVMaskElement.prototype.renderFrame=function(){if(this.hasMasks){var t,e,i,r,s=this.element.finalTransform.mat,a=this.element.canvasContext,n=this.masksProperties.length;for(a.beginPath(),t=0;t<n;t+=1)if("n"!==this.masksProperties[t].mode){this.masksProperties[t].inv&&(a.moveTo(0,0),a.lineTo(this.element.globalData.compSize.w,0),a.lineTo(this.element.globalData.compSize.w,this.element.globalData.compSize.h),a.lineTo(0,this.element.globalData.compSize.h),a.lineTo(0,0)),r=this.viewData[t].v,e=s.applyToPointArray(r.v[0][0],r.v[0][1],0),a.moveTo(e[0],e[1]);for(var o=r._length,h=1;h<o;h+=1)i=s.applyToTriplePoints(r.o[h-1],r.i[h],r.v[h]),a.bezierCurveTo(i[0],i[1],i[2],i[3],i[4],i[5]);i=s.applyToTriplePoints(r.o[h-1],r.i[0],r.v[0]),a.bezierCurveTo(i[0],i[1],i[2],i[3],i[4],i[5])}this.element.globalData.renderer.save(!0),a.clip()}},CVMaskElement.prototype.getMaskProperty=MaskElement.prototype.getMaskProperty,CVMaskElement.prototype.destroy=function(){this.element=null};var operationsMap={1:"source-in",2:"source-out",3:"source-in",4:"source-out"};function CVShapeData(t,e,i,r){this.styledShapes=[],this.tr=[0,0,0,0,0,0];for(var s,a=4,n=("rc"===e.ty?a=5:"el"===e.ty?a=6:"sr"===e.ty&&(a=7),this.sh=ShapePropertyFactory.getShapeProp(t,e,a,t),i.length),o=0;o<n;o+=1)i[o].closed||(s={transforms:r.addTransformSequence(i[o].transforms),trNodes:[]},this.styledShapes.push(s),i[o].elements.push(s))}function CVShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.itemsData=[],this.prevViewData=[],this.shapeModifiers=[],this.processedElements=[],this.transformsManager=new ShapeTransformManager,this.initElement(t,e,i)}function CVTextElement(t,e,i){this.textSpans=[],this.yOffset=0,this.fillColorAnim=!1,this.strokeColorAnim=!1,this.strokeWidthAnim=!1,this.stroke=!1,this.fill=!1,this.justifyOffset=0,this.currentRender=null,this.renderType="canvas",this.values={fill:"rgba(0,0,0,0)",stroke:"rgba(0,0,0,0)",sWidth:0,fValue:""},this.initElement(t,e,i)}function CVImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.img=e.imageLoader.getAsset(this.assetData),this.initElement(t,e,i)}function CVSolidElement(t,e,i){this.initElement(t,e,i)}function CanvasRendererBase(){}function CanvasContext(){this.opacity=-1,this.transform=createTypedArray("float32",16),this.fillStyle="",this.strokeStyle="",this.lineWidth="",this.lineCap="",this.lineJoin="",this.miterLimit="",this.id=Math.random()}function CVContextData(){this.stack=[],this.cArrPos=0,this.cTr=new Matrix;for(var t=0;t<15;t+=1){var e=new CanvasContext;this.stack[t]=e}this._length=15,this.nativeContext=null,this.transformMat=new Matrix,this.currentOpacity=1,this.currentFillStyle="",this.appliedFillStyle="",this.currentStrokeStyle="",this.appliedStrokeStyle="",this.currentLineWidth="",this.appliedLineWidth="",this.currentLineCap="",this.appliedLineCap="",this.currentLineJoin="",this.appliedLineJoin="",this.appliedMiterLimit="",this.currentMiterLimit=""}function CVCompElement(t,e,i){this.completeLayers=!1,this.layers=t.layers,this.pendingElements=[],this.elements=createSizedArray(this.layers.length),this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function CanvasRenderer(t,e){this.animationItem=t,this.renderConfig={clearCanvas:!e||void 0===e.clearCanvas||e.clearCanvas,context:e&&e.context||null,progressiveLoad:e&&e.progressiveLoad||!1,preserveAspectRatio:e&&e.preserveAspectRatio||"xMidYMid meet",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",contentVisibility:e&&e.contentVisibility||"visible",className:e&&e.className||"",id:e&&e.id||"",runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.renderConfig.dpr=e&&e.dpr||1,this.animationItem.wrapper&&(this.renderConfig.dpr=e&&e.dpr||window.devicePixelRatio||1),this.renderedFrame=-1,this.globalData={frameNum:-1,_mdf:!1,renderConfig:this.renderConfig,currentGlobalAlpha:-1},this.contextData=new CVContextData,this.elements=[],this.pendingElements=[],this.transformMat=new Matrix,this.completeLayers=!1,this.rendererType="canvas",this.renderConfig.clearCanvas&&(this.ctxTransform=this.contextData.transform.bind(this.contextData),this.ctxOpacity=this.contextData.opacity.bind(this.contextData),this.ctxFillStyle=this.contextData.fillStyle.bind(this.contextData),this.ctxStrokeStyle=this.contextData.strokeStyle.bind(this.contextData),this.ctxLineWidth=this.contextData.lineWidth.bind(this.contextData),this.ctxLineCap=this.contextData.lineCap.bind(this.contextData),this.ctxLineJoin=this.contextData.lineJoin.bind(this.contextData),this.ctxMiterLimit=this.contextData.miterLimit.bind(this.contextData),this.ctxFill=this.contextData.fill.bind(this.contextData),this.ctxFillRect=this.contextData.fillRect.bind(this.contextData),this.ctxStroke=this.contextData.stroke.bind(this.contextData),this.save=this.contextData.save.bind(this.contextData))}function HBaseElement(){}function HSolidElement(t,e,i){this.initElement(t,e,i)}function HShapeElement(t,e,i){this.shapes=[],this.shapesData=t.shapes,this.stylesList=[],this.shapeModifiers=[],this.itemsData=[],this.processedElements=[],this.animatedContents=[],this.shapesContainer=createNS("g"),this.initElement(t,e,i),this.prevViewData=[],this.currentBBox={x:999999,y:-999999,h:0,w:0}}function HTextElement(t,e,i){this.textSpans=[],this.textPaths=[],this.currentBBox={x:999999,y:-999999,h:0,w:0},this.renderType="svg",this.isMasked=!1,this.initElement(t,e,i)}function HCameraElement(t,e,i){this.initFrame(),this.initBaseData(t,e,i),this.initHierarchy();e=PropertyFactory.getProp;if(this.pe=e(this,t.pe,0,0,this),t.ks.p.s?(this.px=e(this,t.ks.p.x,1,0,this),this.py=e(this,t.ks.p.y,1,0,this),this.pz=e(this,t.ks.p.z,1,0,this)):this.p=e(this,t.ks.p,1,0,this),t.ks.a&&(this.a=e(this,t.ks.a,1,0,this)),t.ks.or.k.length&&t.ks.or.k[0].to)for(var r=t.ks.or.k.length,s=0;s<r;s+=1)t.ks.or.k[s].to=null,t.ks.or.k[s].ti=null;this.or=e(this,t.ks.or,1,degToRads,this),this.or.sh=!0,this.rx=e(this,t.ks.rx,0,degToRads,this),this.ry=e(this,t.ks.ry,0,degToRads,this),this.rz=e(this,t.ks.rz,0,degToRads,this),this.mat=new Matrix,this._prevMat=new Matrix,this._isFirstFrame=!0,this.finalTransform={mProp:this}}function HImageElement(t,e,i){this.assetData=e.getAssetData(t.refId),this.initElement(t,e,i)}function HybridRendererBase(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"}},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}function HCompElement(t,e,i){this.layers=t.layers,this.supports3d=!t.hasMask,this.completeLayers=!1,this.pendingElements=[],this.elements=this.layers?createSizedArray(this.layers.length):[],this.initElement(t,e,i),this.tm=t.tm?PropertyFactory.getProp(this,t.tm,0,e.frameRate,this):{_placeholder:!0}}function HybridRenderer(t,e){this.animationItem=t,this.layers=null,this.renderedFrame=-1,this.renderConfig={className:e&&e.className||"",imagePreserveAspectRatio:e&&e.imagePreserveAspectRatio||"xMidYMid slice",hideOnTransparent:!(e&&!1===e.hideOnTransparent),filterSize:{width:e&&e.filterSize&&e.filterSize.width||"400%",height:e&&e.filterSize&&e.filterSize.height||"400%",x:e&&e.filterSize&&e.filterSize.x||"-100%",y:e&&e.filterSize&&e.filterSize.y||"-100%"},runExpressions:!e||void 0===e.runExpressions||e.runExpressions},this.globalData={_mdf:!1,frameNum:-1,renderConfig:this.renderConfig},this.pendingElements=[],this.elements=[],this.threeDElements=[],this.destroyed=!1,this.camera=null,this.supports3d=!0,this.rendererType="html"}CVBaseElement.prototype={createElements:function(){},initRendererElement:function(){},createContainerElements:function(){var t,e;1<=this.data.tt&&(this.buffers=[],t=this.globalData.canvasContext,e=assetLoader.createCanvas(t.canvas.width,t.canvas.height),this.buffers.push(e),e=assetLoader.createCanvas(t.canvas.width,t.canvas.height),this.buffers.push(e),3<=this.data.tt)&&!document._isProxy&&assetLoader.loadLumaCanvas(),this.canvasContext=this.globalData.canvasContext,this.transformCanvas=this.globalData.transformCanvas,this.renderableEffectsManager=new CVEffects(this),this.searchEffectTransforms()},createContent:function(){},setBlendMode:function(){var t,e=this.globalData;e.blendMode!==this.data.bm&&(e.blendMode=this.data.bm,t=getBlendMode(this.data.bm),e.canvasContext.globalCompositeOperation=t)},createRenderableComponents:function(){this.maskManager=new CVMaskElement(this.data,this),this.transformEffects=this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT)},hideElement:function(){this.hidden||this.isInRange&&!this.isTransparent||(this.hidden=!0)},showElement:function(){this.isInRange&&!this.isTransparent&&(this.hidden=!1,this._isFirstFrame=!0,this.maskManager._isFirstFrame=!0)},clearCanvas:function(t){t.clearRect(this.transformCanvas.tx,this.transformCanvas.ty,this.transformCanvas.w*this.transformCanvas.sx,this.transformCanvas.h*this.transformCanvas.sy)},prepareLayer:function(){var t;1<=this.data.tt&&(t=this.buffers[0].getContext("2d"),this.clearCanvas(t),t.drawImage(this.canvasContext.canvas,0,0),this.currentTransform=this.canvasContext.getTransform(),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform))},exitLayer:function(){var t,e;1<=this.data.tt&&(e=(t=this.buffers[1]).getContext("2d"),this.clearCanvas(e),e.drawImage(this.canvasContext.canvas,0,0),this.canvasContext.setTransform(1,0,0,1,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.setTransform(this.currentTransform),this.comp.getElementById("tp"in this.data?this.data.tp:this.data.ind-1).renderFrame(!0),this.canvasContext.setTransform(1,0,0,1,0,0),3<=this.data.tt&&!document._isProxy&&((e=assetLoader.getLumaCanvas(this.canvasContext.canvas)).getContext("2d").drawImage(this.canvasContext.canvas,0,0),this.clearCanvas(this.canvasContext),this.canvasContext.drawImage(e,0,0)),this.canvasContext.globalCompositeOperation=operationsMap[this.data.tt],this.canvasContext.drawImage(t,0,0),this.canvasContext.globalCompositeOperation="destination-over",this.canvasContext.drawImage(this.buffers[0],0,0),this.canvasContext.setTransform(this.currentTransform),this.canvasContext.globalCompositeOperation="source-over")},renderFrame:function(t){this.hidden||this.data.hd||(1!==this.data.td||t)&&(this.renderTransform(),this.renderRenderable(),this.renderLocalTransform(),this.setBlendMode(),t=0===this.data.ty,this.prepareLayer(),this.globalData.renderer.save(t),this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props),this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity),this.renderInnerContent(),this.globalData.renderer.restore(t),this.exitLayer(),this.maskManager.hasMasks&&this.globalData.renderer.restore(!0),this._isFirstFrame)&&(this._isFirstFrame=!1)},destroy:function(){this.canvasContext=null,this.data=null,this.globalData=null,this.maskManager.destroy()},mHelper:new Matrix},CVBaseElement.prototype.hide=CVBaseElement.prototype.hideElement,CVBaseElement.prototype.show=CVBaseElement.prototype.showElement,CVShapeData.prototype.setAsAnimated=SVGShapeData.prototype.setAsAnimated,extendPrototype([BaseElement,TransformElement,CVBaseElement,IShapeElement,HierarchyElement,FrameElement,RenderableElement],CVShapeElement),CVShapeElement.prototype.initElement=RenderableDOMElement.prototype.initElement,CVShapeElement.prototype.transformHelper={opacity:1,_opMdf:!1},CVShapeElement.prototype.dashResetter=[],CVShapeElement.prototype.createContent=function(){this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[])},CVShapeElement.prototype.createStyleElement=function(t,e){var i,e={data:t,type:t.ty,preTransforms:this.transformsManager.addTransformSequence(e),transforms:[],elements:[],closed:!0===t.hd},r={};return"fl"===t.ty||"st"===t.ty?(r.c=PropertyFactory.getProp(this,t.c,1,255,this),r.c.k||(e.co="rgb("+bmFloor(r.c.v[0])+","+bmFloor(r.c.v[1])+","+bmFloor(r.c.v[2])+")")):"gf"!==t.ty&&"gs"!==t.ty||(r.s=PropertyFactory.getProp(this,t.s,1,null,this),r.e=PropertyFactory.getProp(this,t.e,1,null,this),r.h=PropertyFactory.getProp(this,t.h||{k:0},0,.01,this),r.a=PropertyFactory.getProp(this,t.a||{k:0},0,degToRads,this),r.g=new GradientProperty(this,t.g,this)),r.o=PropertyFactory.getProp(this,t.o,0,.01,this),"st"===t.ty||"gs"===t.ty?(e.lc=lineCapEnum[t.lc||2],e.lj=lineJoinEnum[t.lj||2],1==t.lj&&(e.ml=t.ml),r.w=PropertyFactory.getProp(this,t.w,0,null,this),r.w.k||(e.wi=r.w.v),t.d&&(i=new DashProperty(this,t.d,"canvas",this),r.d=i,r.d.k||(e.da=r.d.dashArray,e.do=r.d.dashoffset[0]))):e.r=2===t.r?"evenodd":"nonzero",this.stylesList.push(e),r.style=e,r},CVShapeElement.prototype.createGroupElement=function(){return{it:[],prevViewData:[]}},CVShapeElement.prototype.createTransformElement=function(t){return{transform:{opacity:1,_opMdf:!1,key:this.transformsManager.getNewKey(),op:PropertyFactory.getProp(this,t.o,0,.01,this),mProps:TransformPropertyFactory.getTransformProperty(this,t,this)}}},CVShapeElement.prototype.createShapeElement=function(t){t=new CVShapeData(this,t,this.stylesList,this.transformsManager);return this.shapes.push(t),this.addShapeToModifiers(t),t},CVShapeElement.prototype.reloadShapes=function(){this._isFirstFrame=!0;for(var t=this.itemsData.length,e=0;e<t;e+=1)this.prevViewData[e]=this.itemsData[e];for(this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,!0,[]),t=this.dynamicProperties.length,e=0;e<t;e+=1)this.dynamicProperties[e].getValue();this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame)},CVShapeElement.prototype.addTransformToStyleList=function(t){for(var e=this.stylesList.length,i=0;i<e;i+=1)this.stylesList[i].closed||this.stylesList[i].transforms.push(t)},CVShapeElement.prototype.removeTransformFromStyleList=function(){for(var t=this.stylesList.length,e=0;e<t;e+=1)this.stylesList[e].closed||this.stylesList[e].transforms.pop()},CVShapeElement.prototype.closeStyles=function(t){for(var e=t.length,i=0;i<e;i+=1)t[i].closed=!0},CVShapeElement.prototype.searchShapes=function(t,e,i,r,s){for(var a,n,o,h,l,p=t.length-1,m=[],f=[],c=[].concat(s),d=p;0<=d;--d){if((o=this.searchProcessedElement(t[d]))?e[d]=i[o-1]:t[d]._shouldRender=r,"fl"===t[d].ty||"st"===t[d].ty||"gf"===t[d].ty||"gs"===t[d].ty)o?e[d].style.closed=!1:e[d]=this.createStyleElement(t[d],c),m.push(e[d].style);else if("gr"===t[d].ty){if(o)for(n=e[d].it.length,a=0;a<n;a+=1)e[d].prevViewData[a]=e[d].it[a];else e[d]=this.createGroupElement(t[d]);this.searchShapes(t[d].it,e[d].it,e[d].prevViewData,r,c)}else"tr"===t[d].ty?(o||(l=this.createTransformElement(t[d]),e[d]=l),c.push(e[d]),this.addTransformToStyleList(e[d])):"sh"===t[d].ty||"rc"===t[d].ty||"el"===t[d].ty||"sr"===t[d].ty?o||(e[d]=this.createShapeElement(t[d])):"tm"===t[d].ty||"rd"===t[d].ty||"pb"===t[d].ty||"zz"===t[d].ty||"op"===t[d].ty?(o?(h=e[d]).closed=!1:((h=ShapeModifiers.getModifier(t[d].ty)).init(this,t[d]),e[d]=h,this.shapeModifiers.push(h)),f.push(h)):"rp"===t[d].ty&&(o?(h=e[d]).closed=!0:(h=ShapeModifiers.getModifier(t[d].ty),(e[d]=h).init(this,t,d,e),this.shapeModifiers.push(h),r=!1),f.push(h));this.addProcessedElement(t[d],d+1)}for(this.removeTransformFromStyleList(),this.closeStyles(m),p=f.length,d=0;d<p;d+=1)f[d].closed=!0},CVShapeElement.prototype.renderInnerContent=function(){this.transformHelper.opacity=1,this.transformHelper._opMdf=!1,this.renderModifiers(),this.transformsManager.processSequences(this._isFirstFrame),this.renderShape(this.transformHelper,this.shapesData,this.itemsData,!0)},CVShapeElement.prototype.renderShapeTransform=function(t,e){(t._opMdf||e.op._mdf||this._isFirstFrame)&&(e.opacity=t.opacity,e.opacity*=e.op.v,e._opMdf=!0)},CVShapeElement.prototype.drawLayer=function(){for(var t,e,i,r,s,a,n,o,h=this.stylesList.length,l=this.globalData.renderer,p=this.globalData.canvasContext,m=0;m<h;m+=1)if(("st"!==(n=(o=this.stylesList[m]).type)&&"gs"!==n||0!==o.wi)&&o.data._shouldRender&&0!==o.coOp&&0!==this.globalData.currentGlobalAlpha){for(l.save(),s=o.elements,"st"===n||"gs"===n?(l.ctxStrokeStyle("st"===n?o.co:o.grd),l.ctxLineWidth(o.wi),l.ctxLineCap(o.lc),l.ctxLineJoin(o.lj),l.ctxMiterLimit(o.ml||0)):l.ctxFillStyle("fl"===n?o.co:o.grd),l.ctxOpacity(o.coOp),"st"!==n&&"gs"!==n&&p.beginPath(),l.ctxTransform(o.preTransforms.finalTransform.props),e=s.length,t=0;t<e;t+=1){for("st"!==n&&"gs"!==n||(p.beginPath(),o.da&&(p.setLineDash(o.da),p.lineDashOffset=o.do)),r=(a=s[t].trNodes).length,i=0;i<r;i+=1)"m"===a[i].t?p.moveTo(a[i].p[0],a[i].p[1]):"c"===a[i].t?p.bezierCurveTo(a[i].pts[0],a[i].pts[1],a[i].pts[2],a[i].pts[3],a[i].pts[4],a[i].pts[5]):p.closePath();"st"!==n&&"gs"!==n||(l.ctxStroke(),o.da&&p.setLineDash(this.dashResetter))}"st"!==n&&"gs"!==n&&this.globalData.renderer.ctxFill(o.r),l.restore()}},CVShapeElement.prototype.renderShape=function(t,e,i,r){for(var s=t,a=e.length-1;0<=a;--a)"tr"===e[a].ty?(s=i[a].transform,this.renderShapeTransform(t,s)):"sh"===e[a].ty||"el"===e[a].ty||"rc"===e[a].ty||"sr"===e[a].ty?this.renderPath(e[a],i[a]):"fl"===e[a].ty?this.renderFill(e[a],i[a],s):"st"===e[a].ty?this.renderStroke(e[a],i[a],s):"gf"===e[a].ty||"gs"===e[a].ty?this.renderGradientFill(e[a],i[a],s):"gr"===e[a].ty?this.renderShape(s,e[a].it,i[a].it):e[a].ty;r&&this.drawLayer()},CVShapeElement.prototype.renderStyledShape=function(t,e){if(this._isFirstFrame||e._mdf||t.transforms._mdf){for(var i,r,s=t.trNodes,a=e.paths,n=a._length,o=(s.length=0,t.transforms.finalTransform),h=0;h<n;h+=1){var l=a.shapes[h];if(l&&l.v){for(r=l._length,i=1;i<r;i+=1)1===i&&s.push({t:"m",p:o.applyToPointArray(l.v[0][0],l.v[0][1],0)}),s.push({t:"c",pts:o.applyToTriplePoints(l.o[i-1],l.i[i],l.v[i])});1===r&&s.push({t:"m",p:o.applyToPointArray(l.v[0][0],l.v[0][1],0)}),l.c&&r&&(s.push({t:"c",pts:o.applyToTriplePoints(l.o[i-1],l.i[0],l.v[0])}),s.push({t:"z"}))}}t.trNodes=s}},CVShapeElement.prototype.renderPath=function(t,e){if(!0!==t.hd&&t._shouldRender)for(var i=e.styledShapes.length,r=0;r<i;r+=1)this.renderStyledShape(e.styledShapes[r],e.sh)},CVShapeElement.prototype.renderFill=function(t,e,i){var r=e.style;(e.c._mdf||this._isFirstFrame)&&(r.co="rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i._opMdf||this._isFirstFrame)&&(r.coOp=e.o.v*i.opacity)},CVShapeElement.prototype.renderGradientFill=function(t,e,i){var r=e.style;if(!r.grd||e.g._mdf||e.s._mdf||e.e._mdf||1!==t.t&&(e.h._mdf||e.a._mdf)){for(var s,a,n,o,h=this.globalData.canvasContext,l=e.s.v,p=e.e.v,m=(o=1===t.t?h.createLinearGradient(l[0],l[1],p[0],p[1]):(s=Math.sqrt(Math.pow(l[0]-p[0],2)+Math.pow(l[1]-p[1],2)),p=Math.atan2(p[1]-l[1],p[0]-l[0]),1<=(a=e.h.v)?a=.99:a<=-1&&(a=-.99),a=s*a,n=Math.cos(p+e.a.v)*a+l[0],p=Math.sin(p+e.a.v)*a+l[1],h.createRadialGradient(n,p,0,l[0],l[1],s)),t.g.p),f=e.g.c,c=1,d=0;d<m;d+=1)e.g._hasOpacity&&e.g._collapsable&&(c=e.g.o[2*d+1]),o.addColorStop(f[4*d]/100,"rgba("+f[4*d+1]+","+f[4*d+2]+","+f[4*d+3]+","+c+")");r.grd=o}r.coOp=e.o.v*i.opacity},CVShapeElement.prototype.renderStroke=function(t,e,i){var r=e.style,s=e.d;s&&(s._mdf||this._isFirstFrame)&&(r.da=s.dashArray,r.do=s.dashoffset[0]),(e.c._mdf||this._isFirstFrame)&&(r.co="rgb("+bmFloor(e.c.v[0])+","+bmFloor(e.c.v[1])+","+bmFloor(e.c.v[2])+")"),(e.o._mdf||i._opMdf||this._isFirstFrame)&&(r.coOp=e.o.v*i.opacity),(e.w._mdf||this._isFirstFrame)&&(r.wi=e.w.v)},CVShapeElement.prototype.destroy=function(){this.shapesData=null,this.globalData=null,this.canvasContext=null,this.stylesList.length=0,this.itemsData.length=0},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement,ITextElement],CVTextElement),CVTextElement.prototype.tHelper=createTag("canvas").getContext("2d"),CVTextElement.prototype.buildNewText=function(){for(var t,e,i,r,s,a,n,o,h=this.textProperty.currentData,l=(this.renderedLetters=createSizedArray(h.l?h.l.length:0),!1),l=(h.fc?(l=!0,this.values.fill=this.buildColor(h.fc)):this.values.fill="rgba(0,0,0,0)",this.fill=l,!1),p=(h.sc&&(l=!0,this.values.stroke=this.buildColor(h.sc),this.values.sWidth=h.sw),this.globalData.fontManager.getFontByName(h.f)),m=h.l,f=this.mHelper,c=(this.stroke=l,this.values.fValue=h.finalSize+"px "+this.globalData.fontManager.getFontByName(h.f).fFamily,t=h.finalText.length,this.data.singleShape),d=.001*h.tr*h.finalSize,u=0,y=0,g=!0,v=0,b=0;b<t;b+=1){e=(e=this.globalData.fontManager.getCharData(h.finalText[b],p.fStyle,this.globalData.fontManager.getFontByName(h.f).fFamily))&&e.data||{},f.reset(),c&&m[b].n&&(u=-d,y=y+h.yOffset+(g?1:0),g=!1),a=(s=e.shapes?e.shapes[0].it:[]).length,f.scale(h.finalSize/100,h.finalSize/100),c&&this.applyTextPropertiesToMatrix(h,f,m[b].line,u,y);for(var x=createSizedArray(a-1),P=0,E=0;E<a;E+=1)if("sh"===s[E].ty){for(r=s[E].ks.k.i.length,n=s[E].ks.k,o=[],i=1;i<r;i+=1)1===i&&o.push(f.applyToX(n.v[0][0],n.v[0][1],0),f.applyToY(n.v[0][0],n.v[0][1],0)),o.push(f.applyToX(n.o[i-1][0],n.o[i-1][1],0),f.applyToY(n.o[i-1][0],n.o[i-1][1],0),f.applyToX(n.i[i][0],n.i[i][1],0),f.applyToY(n.i[i][0],n.i[i][1],0),f.applyToX(n.v[i][0],n.v[i][1],0),f.applyToY(n.v[i][0],n.v[i][1],0));o.push(f.applyToX(n.o[i-1][0],n.o[i-1][1],0),f.applyToY(n.o[i-1][0],n.o[i-1][1],0),f.applyToX(n.i[0][0],n.i[0][1],0),f.applyToY(n.i[0][0],n.i[0][1],0),f.applyToX(n.v[0][0],n.v[0][1],0),f.applyToY(n.v[0][0],n.v[0][1],0)),x[P]=o,P+=1}c&&(u=u+m[b].l+d),this.textSpans[v]?this.textSpans[v].elem=x:this.textSpans[v]={elem:x},v+=1}},CVTextElement.prototype.renderInnerContent=function(){this.validateText();this.canvasContext.font=this.values.fValue,this.globalData.renderer.ctxLineCap("butt"),this.globalData.renderer.ctxLineJoin("miter"),this.globalData.renderer.ctxMiterLimit(4),this.data.singleShape||this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag);for(var t,e,i,r,s,a,n,o=this.textAnimator.renderedLetters,h=this.textProperty.currentData.l,l=h.length,p=null,m=null,f=null,c=this.globalData.renderer,d=0;d<l;d+=1)if(!h[d].n){if((s=o[d])&&(c.save(),c.ctxTransform(s.p),c.ctxOpacity(s.o)),this.fill){for(s&&s.fc?p!==s.fc&&(c.ctxFillStyle(s.fc),p=s.fc):p!==this.values.fill&&(p=this.values.fill,c.ctxFillStyle(this.values.fill)),e=(a=this.textSpans[d].elem).length,this.globalData.canvasContext.beginPath(),t=0;t<e;t+=1)for(r=(n=a[t]).length,this.globalData.canvasContext.moveTo(n[0],n[1]),i=2;i<r;i+=6)this.globalData.canvasContext.bezierCurveTo(n[i],n[i+1],n[i+2],n[i+3],n[i+4],n[i+5]);this.globalData.canvasContext.closePath(),c.ctxFill()}if(this.stroke){for(s&&s.sw?f!==s.sw&&(f=s.sw,c.ctxLineWidth(s.sw)):f!==this.values.sWidth&&(f=this.values.sWidth,c.ctxLineWidth(this.values.sWidth)),s&&s.sc?m!==s.sc&&(m=s.sc,c.ctxStrokeStyle(s.sc)):m!==this.values.stroke&&(m=this.values.stroke,c.ctxStrokeStyle(this.values.stroke)),e=(a=this.textSpans[d].elem).length,this.globalData.canvasContext.beginPath(),t=0;t<e;t+=1)for(r=(n=a[t]).length,this.globalData.canvasContext.moveTo(n[0],n[1]),i=2;i<r;i+=6)this.globalData.canvasContext.bezierCurveTo(n[i],n[i+1],n[i+2],n[i+3],n[i+4],n[i+5]);this.globalData.canvasContext.closePath(),c.ctxStroke()}s&&this.globalData.renderer.restore()}},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVImageElement),CVImageElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVImageElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVImageElement.prototype.createContent=function(){var t,e,i,r,s,a,n,o,h;!this.img.width||this.assetData.w===this.img.width&&this.assetData.h===this.img.height||((t=createTag("canvas")).width=this.assetData.w,t.height=this.assetData.h,e=t.getContext("2d"),i=this.img.width,r=this.img.height,a=this.assetData.w/this.assetData.h,h=this.assetData.pr||this.globalData.renderConfig.imagePreserveAspectRatio,a<(s=i/r)&&"xMidYMid slice"===h||s<a&&"xMidYMid slice"!==h?n=(o=r)*a:o=(n=i)/a,e.drawImage(this.img,(i-n)/2,(r-o)/2,n,o,0,0,this.assetData.w,this.assetData.h),this.img=t)},CVImageElement.prototype.renderInnerContent=function(){this.canvasContext.drawImage(this.img,0,0)},CVImageElement.prototype.destroy=function(){this.img=null},extendPrototype([BaseElement,TransformElement,CVBaseElement,HierarchyElement,FrameElement,RenderableElement],CVSolidElement),CVSolidElement.prototype.initElement=SVGShapeElement.prototype.initElement,CVSolidElement.prototype.prepareFrame=IImageElement.prototype.prepareFrame,CVSolidElement.prototype.renderInnerContent=function(){this.globalData.renderer.ctxFillStyle(this.data.sc),this.globalData.renderer.ctxFillRect(0,0,this.data.sw,this.data.sh)},extendPrototype([BaseRenderer],CanvasRendererBase),CanvasRendererBase.prototype.createShape=function(t){return new CVShapeElement(t,this.globalData,this)},CanvasRendererBase.prototype.createText=function(t){return new CVTextElement(t,this.globalData,this)},CanvasRendererBase.prototype.createImage=function(t){return new CVImageElement(t,this.globalData,this)},CanvasRendererBase.prototype.createSolid=function(t){return new CVSolidElement(t,this.globalData,this)},CanvasRendererBase.prototype.createNull=SVGRenderer.prototype.createNull,CanvasRendererBase.prototype.ctxTransform=function(t){1===t[0]&&0===t[1]&&0===t[4]&&1===t[5]&&0===t[12]&&0===t[13]||this.canvasContext.transform(t[0],t[1],t[4],t[5],t[12],t[13])},CanvasRendererBase.prototype.ctxOpacity=function(t){this.canvasContext.globalAlpha*=t<0?0:t},CanvasRendererBase.prototype.ctxFillStyle=function(t){this.canvasContext.fillStyle=t},CanvasRendererBase.prototype.ctxStrokeStyle=function(t){this.canvasContext.strokeStyle=t},CanvasRendererBase.prototype.ctxLineWidth=function(t){this.canvasContext.lineWidth=t},CanvasRendererBase.prototype.ctxLineCap=function(t){this.canvasContext.lineCap=t},CanvasRendererBase.prototype.ctxLineJoin=function(t){this.canvasContext.lineJoin=t},CanvasRendererBase.prototype.ctxMiterLimit=function(t){this.canvasContext.miterLimit=t},CanvasRendererBase.prototype.ctxFill=function(t){this.canvasContext.fill(t)},CanvasRendererBase.prototype.ctxFillRect=function(t,e,i,r){this.canvasContext.fillRect(t,e,i,r)},CanvasRendererBase.prototype.ctxStroke=function(){this.canvasContext.stroke()},CanvasRendererBase.prototype.reset=function(){this.renderConfig.clearCanvas?this.contextData.reset():this.canvasContext.restore()},CanvasRendererBase.prototype.save=function(){this.canvasContext.save()},CanvasRendererBase.prototype.restore=function(t){this.renderConfig.clearCanvas?(t&&(this.globalData.blendMode="source-over"),this.contextData.restore(t)):this.canvasContext.restore()},CanvasRendererBase.prototype.configAnimation=function(t){var e,i;this.animationItem.wrapper?(this.animationItem.container=createTag("canvas"),(e=this.animationItem.container.style).width="100%",e.height="100%",e.transformOrigin=i="0px 0px 0px",e.mozTransformOrigin=i,e.webkitTransformOrigin=i,e["-webkit-transform"]=i,e.contentVisibility=this.renderConfig.contentVisibility,this.animationItem.wrapper.appendChild(this.animationItem.container),this.canvasContext=this.animationItem.container.getContext("2d"),this.renderConfig.className&&this.animationItem.container.setAttribute("class",this.renderConfig.className),this.renderConfig.id&&this.animationItem.container.setAttribute("id",this.renderConfig.id)):this.canvasContext=this.renderConfig.context,this.contextData.setContext(this.canvasContext),this.data=t,this.layers=t.layers,this.transformCanvas={w:t.w,h:t.h,sx:0,sy:0,tx:0,ty:0},this.setupGlobalData(t,document.body),this.globalData.canvasContext=this.canvasContext,(this.globalData.renderer=this).globalData.isDashed=!1,this.globalData.progressiveLoad=this.renderConfig.progressiveLoad,this.globalData.transformCanvas=this.transformCanvas,this.elements=createSizedArray(t.layers.length),this.updateContainerSize()},CanvasRendererBase.prototype.updateContainerSize=function(t,e){var i,r,s,a,n;this.reset(),t?(r=e,this.canvasContext.canvas.width=i=t,this.canvasContext.canvas.height=r):(r=this.animationItem.wrapper&&this.animationItem.container?(i=this.animationItem.wrapper.offsetWidth,this.animationItem.wrapper.offsetHeight):(i=this.canvasContext.canvas.width,this.canvasContext.canvas.height),this.canvasContext.canvas.width=i*this.renderConfig.dpr,this.canvasContext.canvas.height=r*this.renderConfig.dpr),-1!==this.renderConfig.preserveAspectRatio.indexOf("meet")||-1!==this.renderConfig.preserveAspectRatio.indexOf("slice")?(t=(e=this.renderConfig.preserveAspectRatio.split(" "))[1]||"meet",s=(e=e[0]||"xMidYMid").substr(0,4),e=e.substr(4),(a=i/r)<(n=this.transformCanvas.w/this.transformCanvas.h)&&"meet"===t||n<a&&"slice"===t?(this.transformCanvas.sx=i/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=i/(this.transformCanvas.w/this.renderConfig.dpr)):(this.transformCanvas.sx=r/(this.transformCanvas.h/this.renderConfig.dpr),this.transformCanvas.sy=r/(this.transformCanvas.h/this.renderConfig.dpr)),this.transformCanvas.tx="xMid"===s&&(n<a&&"meet"===t||a<n&&"slice"===t)?(i-this.transformCanvas.w*(r/this.transformCanvas.h))/2*this.renderConfig.dpr:"xMax"===s&&(n<a&&"meet"===t||a<n&&"slice"===t)?(i-this.transformCanvas.w*(r/this.transformCanvas.h))*this.renderConfig.dpr:0,this.transformCanvas.ty="YMid"===e&&(a<n&&"meet"===t||n<a&&"slice"===t)?(r-this.transformCanvas.h*(i/this.transformCanvas.w))/2*this.renderConfig.dpr:"YMax"===e&&(a<n&&"meet"===t||n<a&&"slice"===t)?(r-this.transformCanvas.h*(i/this.transformCanvas.w))*this.renderConfig.dpr:0):("none"===this.renderConfig.preserveAspectRatio?(this.transformCanvas.sx=i/(this.transformCanvas.w/this.renderConfig.dpr),this.transformCanvas.sy=r/(this.transformCanvas.h/this.renderConfig.dpr)):(this.transformCanvas.sx=this.renderConfig.dpr,this.transformCanvas.sy=this.renderConfig.dpr),this.transformCanvas.tx=0,this.transformCanvas.ty=0),this.transformCanvas.props=[this.transformCanvas.sx,0,0,0,0,this.transformCanvas.sy,0,0,0,0,1,0,this.transformCanvas.tx,this.transformCanvas.ty,0,1],this.ctxTransform(this.transformCanvas.props),this.canvasContext.beginPath(),this.canvasContext.rect(0,0,this.transformCanvas.w,this.transformCanvas.h),this.canvasContext.closePath(),this.canvasContext.clip(),this.renderFrame(this.renderedFrame,!0)},CanvasRendererBase.prototype.destroy=function(){this.renderConfig.clearCanvas&&this.animationItem.wrapper&&(this.animationItem.wrapper.innerText="");for(var t=(this.layers?this.layers.length:0)-1;0<=t;--t)this.elements[t]&&this.elements[t].destroy&&this.elements[t].destroy();this.elements.length=0,this.globalData.canvasContext=null,this.animationItem.container=null,this.destroyed=!0},CanvasRendererBase.prototype.renderFrame=function(t,e){if((this.renderedFrame!==t||!0!==this.renderConfig.clearCanvas||e)&&!this.destroyed&&-1!==t){this.renderedFrame=t,this.globalData.frameNum=t-this.animationItem._isFirstFrame,this.globalData.frameId+=1,this.globalData._mdf=!this.renderConfig.clearCanvas||e,this.globalData.projectInterface.currentFrame=t;var i,e=this.layers.length;for(this.completeLayers||this.checkLayers(t),i=e-1;0<=i;--i)(this.completeLayers||this.elements[i])&&this.elements[i].prepareFrame(t-this.layers[i].st);if(this.globalData._mdf){for(!0===this.renderConfig.clearCanvas?this.canvasContext.clearRect(0,0,this.transformCanvas.w,this.transformCanvas.h):this.save(),i=e-1;0<=i;--i)(this.completeLayers||this.elements[i])&&this.elements[i].renderFrame();!0!==this.renderConfig.clearCanvas&&this.restore()}}},CanvasRendererBase.prototype.buildItem=function(t){var e,i=this.elements;i[t]||99===this.layers[t].ty||(e=this.createItem(this.layers[t],this,this.globalData),(i[t]=e).initExpressions())},CanvasRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;)this.pendingElements.pop().checkParenting()},CanvasRendererBase.prototype.hide=function(){this.animationItem.container.style.display="none"},CanvasRendererBase.prototype.show=function(){this.animationItem.container.style.display="block"},CVContextData.prototype.duplicate=function(){for(var t=2*this._length,e=0,e=this._length;e<t;e+=1)this.stack[e]=new CanvasContext;this._length=t},CVContextData.prototype.reset=function(){this.cArrPos=0,this.cTr.reset(),this.stack[this.cArrPos].opacity=1},CVContextData.prototype.restore=function(t){--this.cArrPos;for(var e,i=this.stack[this.cArrPos],r=i.transform,s=this.cTr.props,a=0;a<16;a+=1)s[a]=r[a];t&&(this.nativeContext.restore(),e=this.stack[this.cArrPos+1],this.appliedFillStyle=e.fillStyle,this.appliedStrokeStyle=e.strokeStyle,this.appliedLineWidth=e.lineWidth,this.appliedLineCap=e.lineCap,this.appliedLineJoin=e.lineJoin,this.appliedMiterLimit=e.miterLimit),this.nativeContext.setTransform(r[0],r[1],r[4],r[5],r[12],r[13]),(t||-1!==i.opacity&&this.currentOpacity!==i.opacity)&&(this.nativeContext.globalAlpha=i.opacity,this.currentOpacity=i.opacity),this.currentFillStyle=i.fillStyle,this.currentStrokeStyle=i.strokeStyle,this.currentLineWidth=i.lineWidth,this.currentLineCap=i.lineCap,this.currentLineJoin=i.lineJoin,this.currentMiterLimit=i.miterLimit},CVContextData.prototype.save=function(t){t&&this.nativeContext.save();for(var e=this.cTr.props,i=(this._length<=this.cArrPos&&this.duplicate(),this.stack[this.cArrPos]),r=0;r<16;r+=1)i.transform[r]=e[r];this.cArrPos+=1;t=this.stack[this.cArrPos];t.opacity=i.opacity,t.fillStyle=i.fillStyle,t.strokeStyle=i.strokeStyle,t.lineWidth=i.lineWidth,t.lineCap=i.lineCap,t.lineJoin=i.lineJoin,t.miterLimit=i.miterLimit},CVContextData.prototype.setOpacity=function(t){this.stack[this.cArrPos].opacity=t},CVContextData.prototype.setContext=function(t){this.nativeContext=t},CVContextData.prototype.fillStyle=function(t){this.stack[this.cArrPos].fillStyle!==t&&(this.currentFillStyle=t,this.stack[this.cArrPos].fillStyle=t)},CVContextData.prototype.strokeStyle=function(t){this.stack[this.cArrPos].strokeStyle!==t&&(this.currentStrokeStyle=t,this.stack[this.cArrPos].strokeStyle=t)},CVContextData.prototype.lineWidth=function(t){this.stack[this.cArrPos].lineWidth!==t&&(this.currentLineWidth=t,this.stack[this.cArrPos].lineWidth=t)},CVContextData.prototype.lineCap=function(t){this.stack[this.cArrPos].lineCap!==t&&(this.currentLineCap=t,this.stack[this.cArrPos].lineCap=t)},CVContextData.prototype.lineJoin=function(t){this.stack[this.cArrPos].lineJoin!==t&&(this.currentLineJoin=t,this.stack[this.cArrPos].lineJoin=t)},CVContextData.prototype.miterLimit=function(t){this.stack[this.cArrPos].miterLimit!==t&&(this.currentMiterLimit=t,this.stack[this.cArrPos].miterLimit=t)},CVContextData.prototype.transform=function(t){this.transformMat.cloneFromProps(t);t=this.cTr,this.transformMat.multiply(t),t.cloneFromProps(this.transformMat.props),t=t.props;this.nativeContext.setTransform(t[0],t[1],t[4],t[5],t[12],t[13])},CVContextData.prototype.opacity=function(t){var e=this.stack[this.cArrPos].opacity;this.stack[this.cArrPos].opacity!==(e*=t<0?0:t)&&(this.currentOpacity!==t&&(this.nativeContext.globalAlpha=t,this.currentOpacity=t),this.stack[this.cArrPos].opacity=e)},CVContextData.prototype.fill=function(t){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fill(t)},CVContextData.prototype.fillRect=function(t,e,i,r){this.appliedFillStyle!==this.currentFillStyle&&(this.appliedFillStyle=this.currentFillStyle,this.nativeContext.fillStyle=this.appliedFillStyle),this.nativeContext.fillRect(t,e,i,r)},CVContextData.prototype.stroke=function(){this.appliedStrokeStyle!==this.currentStrokeStyle&&(this.appliedStrokeStyle=this.currentStrokeStyle,this.nativeContext.strokeStyle=this.appliedStrokeStyle),this.appliedLineWidth!==this.currentLineWidth&&(this.appliedLineWidth=this.currentLineWidth,this.nativeContext.lineWidth=this.appliedLineWidth),this.appliedLineCap!==this.currentLineCap&&(this.appliedLineCap=this.currentLineCap,this.nativeContext.lineCap=this.appliedLineCap),this.appliedLineJoin!==this.currentLineJoin&&(this.appliedLineJoin=this.currentLineJoin,this.nativeContext.lineJoin=this.appliedLineJoin),this.appliedMiterLimit!==this.currentMiterLimit&&(this.appliedMiterLimit=this.currentMiterLimit,this.nativeContext.miterLimit=this.appliedMiterLimit),this.nativeContext.stroke()},extendPrototype([CanvasRendererBase,ICompElement,CVBaseElement],CVCompElement),CVCompElement.prototype.renderInnerContent=function(){var t=this.canvasContext;t.beginPath(),t.moveTo(0,0),t.lineTo(this.data.w,0),t.lineTo(this.data.w,this.data.h),t.lineTo(0,this.data.h),t.lineTo(0,0),t.clip();for(var e=this.layers.length-1;0<=e;--e)(this.completeLayers||this.elements[e])&&this.elements[e].renderFrame()},CVCompElement.prototype.destroy=function(){for(var t=this.layers.length-1;0<=t;--t)this.elements[t]&&this.elements[t].destroy();this.layers=null,this.elements=null},CVCompElement.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},extendPrototype([CanvasRendererBase],CanvasRenderer),CanvasRenderer.prototype.createComp=function(t){return new CVCompElement(t,this.globalData,this)},HBaseElement.prototype={checkBlendMode:function(){},initRendererElement:function(){this.baseElement=createTag(this.data.tg||"div"),this.data.hasMask?(this.svgElement=createNS("svg"),this.layerElement=createNS("g"),this.maskedElement=this.layerElement,this.svgElement.appendChild(this.layerElement),this.baseElement.appendChild(this.svgElement)):this.layerElement=this.baseElement,styleDiv(this.baseElement)},createContainerElements:function(){this.renderableEffectsManager=new CVEffects(this),this.transformedElement=this.baseElement,this.maskedElement=this.layerElement,this.data.ln&&this.layerElement.setAttribute("id",this.data.ln),this.data.cl&&this.layerElement.setAttribute("class",this.data.cl),0!==this.data.bm&&this.setBlendMode()},renderElement:function(){var t,e=this.transformedElement?this.transformedElement.style:{};this.finalTransform._matMdf&&(t=this.finalTransform.mat.toCSS(),e.transform=t,e.webkitTransform=t),this.finalTransform._opMdf&&(e.opacity=this.finalTransform.mProp.o.v)},renderFrame:function(){this.data.hd||this.hidden||(this.renderTransform(),this.renderRenderable(),this.renderElement(),this.renderInnerContent(),this._isFirstFrame&&(this._isFirstFrame=!1))},destroy:function(){this.layerElement=null,this.transformedElement=null,this.matteElement&&(this.matteElement=null),this.maskManager&&(this.maskManager.destroy(),this.maskManager=null)},createRenderableComponents:function(){this.maskManager=new MaskElement(this.data,this,this.globalData)},addEffects:function(){},setMatte:function(){}},HBaseElement.prototype.getBaseElement=SVGBaseElement.prototype.getBaseElement,HBaseElement.prototype.destroyBaseElement=HBaseElement.prototype.destroy,HBaseElement.prototype.buildElementParenting=BaseRenderer.prototype.buildElementParenting,extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement],HSolidElement),HSolidElement.prototype.createContent=function(){var t;this.data.hasMask?((t=createNS("rect")).setAttribute("width",this.data.sw),t.setAttribute("height",this.data.sh),t.setAttribute("fill",this.data.sc),this.svgElement.setAttribute("width",this.data.sw),this.svgElement.setAttribute("height",this.data.sh)):((t=createTag("div")).style.width=this.data.sw+"px",t.style.height=this.data.sh+"px",t.style.backgroundColor=this.data.sc),this.layerElement.appendChild(t)},extendPrototype([BaseElement,TransformElement,HSolidElement,SVGShapeElement,HBaseElement,HierarchyElement,FrameElement,RenderableElement],HShapeElement),HShapeElement.prototype._renderShapeFrame=HShapeElement.prototype.renderInnerContent,HShapeElement.prototype.createContent=function(){var t,e;this.baseElement.style.fontSize=0,this.data.hasMask?(this.layerElement.appendChild(this.shapesContainer),t=this.svgElement):(t=createNS("svg"),e=this.comp.data||this.globalData.compSize,t.setAttribute("width",e.w),t.setAttribute("height",e.h),t.appendChild(this.shapesContainer),this.layerElement.appendChild(t)),this.searchShapes(this.shapesData,this.itemsData,this.prevViewData,this.shapesContainer,0,[],!0),this.filterUniqueShapes(),this.shapeCont=t},HShapeElement.prototype.getTransformedPoint=function(t,e){for(var i=t.length,r=0;r<i;r+=1)e=t[r].mProps.v.applyToPointArray(e[0],e[1],0);return e},HShapeElement.prototype.calculateShapeBoundingBox=function(t,e){var i,r,s,a,n,o=t.sh.v,h=t.transformers,l=o._length;if(!(l<=1)){for(i=0;i<l-1;i+=1)r=this.getTransformedPoint(h,o.v[i]),s=this.getTransformedPoint(h,o.o[i]),a=this.getTransformedPoint(h,o.i[i+1]),n=this.getTransformedPoint(h,o.v[i+1]),this.checkBounds(r,s,a,n,e);o.c&&(r=this.getTransformedPoint(h,o.v[i]),s=this.getTransformedPoint(h,o.o[i]),a=this.getTransformedPoint(h,o.i[0]),n=this.getTransformedPoint(h,o.v[0]),this.checkBounds(r,s,a,n,e))}},HShapeElement.prototype.checkBounds=function(t,e,i,r,s){this.getBoundsOfCurve(t,e,i,r);t=this.shapeBoundingBox;s.x=bmMin(t.left,s.x),s.xMax=bmMax(t.right,s.xMax),s.y=bmMin(t.top,s.y),s.yMax=bmMax(t.bottom,s.yMax)},HShapeElement.prototype.shapeBoundingBox={left:0,right:0,top:0,bottom:0},HShapeElement.prototype.tempBoundingBox={x:0,xMax:0,y:0,yMax:0,width:0,height:0},HShapeElement.prototype.getBoundsOfCurve=function(t,e,i,r){for(var s,a,n,o,h=[[t[0],r[0]],[t[1],r[1]]],l=0;l<2;++l)a=6*t[l]-12*e[l]+6*i[l],s=-3*t[l]+9*e[l]-9*i[l]+3*r[l],o=3*e[l]-3*t[l],a|=0,o|=0,0==(s|=0)&&0==a||(0==s?0<(n=-o/a)&&n<1&&h[l].push(this.calculateF(n,t,e,i,r,l)):0<=(n=a*a-4*o*s)&&(0<(o=(-a+bmSqrt(n))/(2*s))&&o<1&&h[l].push(this.calculateF(o,t,e,i,r,l)),0<(o=(-a-bmSqrt(n))/(2*s)))&&o<1&&h[l].push(this.calculateF(o,t,e,i,r,l)));this.shapeBoundingBox.left=bmMin.apply(null,h[0]),this.shapeBoundingBox.top=bmMin.apply(null,h[1]),this.shapeBoundingBox.right=bmMax.apply(null,h[0]),this.shapeBoundingBox.bottom=bmMax.apply(null,h[1])},HShapeElement.prototype.calculateF=function(t,e,i,r,s,a){return bmPow(1-t,3)*e[a]+3*bmPow(1-t,2)*t*i[a]+3*(1-t)*bmPow(t,2)*r[a]+bmPow(t,3)*s[a]},HShapeElement.prototype.calculateBoundingBox=function(t,e){for(var i=t.length,r=0;r<i;r+=1)t[r]&&t[r].sh?this.calculateShapeBoundingBox(t[r],e):t[r]&&t[r].it?this.calculateBoundingBox(t[r].it,e):t[r]&&t[r].style&&t[r].w&&this.expandStrokeBoundingBox(t[r].w,e)},HShapeElement.prototype.expandStrokeBoundingBox=function(t,e){var i=0;if(t.keyframes){for(var r=0;r<t.keyframes.length;r+=1){var s=t.keyframes[r].s;i<s&&(i=s)}i*=t.mult}else i=t.v*t.mult;e.x-=i,e.xMax+=i,e.y-=i,e.yMax+=i},HShapeElement.prototype.currentBoxContains=function(t){return this.currentBBox.x<=t.x&&this.currentBBox.y<=t.y&&this.currentBBox.width+this.currentBBox.x>=t.x+t.width&&this.currentBBox.height+this.currentBBox.y>=t.y+t.height},HShapeElement.prototype.renderInnerContent=function(){var t,e;this._renderShapeFrame(),this.hidden||!this._isFirstFrame&&!this._mdf||((e=this.tempBoundingBox).x=t=999999,e.xMax=-t,e.y=t,e.yMax=-t,this.calculateBoundingBox(this.itemsData,e),e.width=e.xMax<e.x?0:e.xMax-e.x,e.height=e.yMax<e.y?0:e.yMax-e.y,!this.currentBoxContains(e)&&(t=!1,this.currentBBox.w!==e.width&&(this.currentBBox.w=e.width,this.shapeCont.setAttribute("width",e.width),t=!0),this.currentBBox.h!==e.height&&(this.currentBBox.h=e.height,this.shapeCont.setAttribute("height",e.height),t=!0),t||this.currentBBox.x!==e.x||this.currentBBox.y!==e.y)&&(this.currentBBox.w=e.width,this.currentBBox.h=e.height,this.currentBBox.x=e.x,this.currentBBox.y=e.y,this.shapeCont.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h),t=this.shapeCont.style,e="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)",t.transform=e,t.webkitTransform=e))},extendPrototype([BaseElement,TransformElement,HBaseElement,HierarchyElement,FrameElement,RenderableDOMElement,ITextElement],HTextElement),HTextElement.prototype.createContent=function(){var t;this.isMasked=this.checkMasks(),this.isMasked?(this.renderType="svg",this.compW=this.comp.data.w,this.compH=this.comp.data.h,this.svgElement.setAttribute("width",this.compW),this.svgElement.setAttribute("height",this.compH),t=createNS("g"),this.maskedElement.appendChild(t),this.innerElem=t):(this.renderType="html",this.innerElem=this.layerElement),this.checkParenting()},HTextElement.prototype.buildNewText=function(){for(var t,e,i,r,s,a,n,o=this.textProperty.currentData,h=(this.renderedLetters=createSizedArray(o.l?o.l.length:0),this.innerElem.style),l=o.fc?this.buildColor(o.fc):"rgba(0,0,0,0)",p=(h.fill=l,h.color=l,o.sc&&(h.stroke=this.buildColor(o.sc),h.strokeWidth=o.sw+"px"),this.globalData.fontManager.getFontByName(o.f)),m=(this.globalData.fontManager.chars||(h.fontSize=o.finalSize+"px",h.lineHeight=o.finalSize+"px",p.fClass?this.innerElem.className=p.fClass:(h.fontFamily=p.fFamily,l=o.fWeight,t=o.fStyle,h.fontStyle=t,h.fontWeight=l)),o.l),f=m.length,c=this.mHelper,d=0,u=0;u<f;u+=1)this.globalData.fontManager.chars?(this.textPaths[d]?e=this.textPaths[d]:((e=createNS("path")).setAttribute("stroke-linecap",lineCapEnum[1]),e.setAttribute("stroke-linejoin",lineJoinEnum[2]),e.setAttribute("stroke-miterlimit","4")),this.isMasked||(this.textSpans[d]?r=(i=this.textSpans[d]).children[0]:((i=createTag("div")).style.lineHeight=0,(r=createNS("svg")).appendChild(e),styleDiv(i)))):this.isMasked?e=this.textPaths[d]||createNS("text"):this.textSpans[d]?(i=this.textSpans[d],e=this.textPaths[d]):(styleDiv(i=createTag("span")),styleDiv(e=createTag("span")),i.appendChild(e)),this.globalData.fontManager.chars?(a=(a=this.globalData.fontManager.getCharData(o.finalText[u],p.fStyle,this.globalData.fontManager.getFontByName(o.f).fFamily))?a.data:null,c.reset(),a&&a.shapes&&a.shapes.length&&(s=a.shapes[0].it,c.scale(o.finalSize/100,o.finalSize/100),s=this.createPathShape(c,s),e.setAttribute("d",s)),this.isMasked?this.innerElem.appendChild(e):(this.innerElem.appendChild(i),a&&a.shapes?(document.body.appendChild(r),s=r.getBBox(),r.setAttribute("width",s.width+2),r.setAttribute("height",s.height+2),r.setAttribute("viewBox",s.x-1+" "+(s.y-1)+" "+(s.width+2)+" "+(s.height+2)),a=r.style,n="translate("+(s.x-1)+"px,"+(s.y-1)+"px)",a.transform=n,a.webkitTransform=n,m[u].yOffset=s.y-1):(r.setAttribute("width",1),r.setAttribute("height",1)),i.appendChild(r))):(e.textContent=m[u].val,e.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),this.isMasked?this.innerElem.appendChild(e):(this.innerElem.appendChild(i),a=e.style,n="translate3d(0,"+-o.finalSize/1.2+"px,0)",a.transform=n,a.webkitTransform=n)),this.isMasked?this.textSpans[d]=e:this.textSpans[d]=i,this.textSpans[d].style.display="block",this.textPaths[d]=e,d+=1;for(;d<this.textSpans.length;)this.textSpans[d].style.display="none",d+=1},HTextElement.prototype.renderInnerContent=function(){var t;if(this.validateText(),this.data.singleShape){if(!this._isFirstFrame&&!this.lettersChangedFlag)return;this.isMasked&&this.finalTransform._matMdf&&(this.svgElement.setAttribute("viewBox",-this.finalTransform.mProp.p.v[0]+" "+-this.finalTransform.mProp.p.v[1]+" "+this.compW+" "+this.compH),t=this.svgElement.style,s="translate("+-this.finalTransform.mProp.p.v[0]+"px,"+-this.finalTransform.mProp.p.v[1]+"px)",t.transform=s,t.webkitTransform=s)}if(this.textAnimator.getMeasures(this.textProperty.currentData,this.lettersChangedFlag),this.lettersChangedFlag||this.textAnimator.lettersChangedFlag){for(var e,i,r,s,a=0,n=this.textAnimator.renderedLetters,o=this.textProperty.currentData.l,h=o.length,l=0;l<h;l+=1)o[l].n?a+=1:(i=this.textSpans[l],r=this.textPaths[l],e=n[a],a+=1,e._mdf.m&&(this.isMasked?i.setAttribute("transform",e.m):(i.style.webkitTransform=e.m,i.style.transform=e.m)),i.style.opacity=e.o,e.sw&&e._mdf.sw&&r.setAttribute("stroke-width",e.sw),e.sc&&e._mdf.sc&&r.setAttribute("stroke",e.sc),e.fc&&e._mdf.fc&&(r.setAttribute("fill",e.fc),r.style.color=e.fc));this.innerElem.getBBox&&!this.hidden&&(this._isFirstFrame||this._mdf)&&(s=this.innerElem.getBBox(),this.currentBBox.w!==s.width&&(this.currentBBox.w=s.width,this.svgElement.setAttribute("width",s.width)),this.currentBBox.h!==s.height&&(this.currentBBox.h=s.height,this.svgElement.setAttribute("height",s.height)),this.currentBBox.w===s.width+2&&this.currentBBox.h===s.height+2&&this.currentBBox.x===s.x-1&&this.currentBBox.y===s.y-1||(this.currentBBox.w=s.width+2,this.currentBBox.h=s.height+2,this.currentBBox.x=s.x-1,this.currentBBox.y=s.y-1,this.svgElement.setAttribute("viewBox",this.currentBBox.x+" "+this.currentBBox.y+" "+this.currentBBox.w+" "+this.currentBBox.h),t=this.svgElement.style,s="translate("+this.currentBBox.x+"px,"+this.currentBBox.y+"px)",t.transform=s,t.webkitTransform=s))}},extendPrototype([BaseElement,FrameElement,HierarchyElement],HCameraElement),HCameraElement.prototype.setup=function(){for(var t,e,i,r,s,a=this.comp.threeDElements.length,n=0;n<a;n+=1)"3d"===(s=this.comp.threeDElements[n]).type&&(t=s.perspectiveElem.style,s=s.container.style,e=this.pe.v+"px",i="0px 0px 0px",r="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)",t.perspective=e,t.webkitPerspective=e,s.transformOrigin=i,s.mozTransformOrigin=i,s.webkitTransformOrigin=i,t.transform=r,t.webkitTransform=r)},HCameraElement.prototype.createElements=function(){},HCameraElement.prototype.hide=function(){},HCameraElement.prototype.renderFrame=function(){var t=this._isFirstFrame;if(this.hierarchy)for(h=this.hierarchy.length,l=0;l<h;l+=1)t=this.hierarchy[l].finalTransform.mProp._mdf||t;if(t||this.pe._mdf||this.p&&this.p._mdf||this.px&&(this.px._mdf||this.py._mdf||this.pz._mdf)||this.rx._mdf||this.ry._mdf||this.rz._mdf||this.or._mdf||this.a&&this.a._mdf){if(this.mat.reset(),this.hierarchy)for(l=h=this.hierarchy.length-1;0<=l;--l){var e=this.hierarchy[l].finalTransform.mProp;this.mat.translate(-e.p.v[0],-e.p.v[1],e.p.v[2]),this.mat.rotateX(-e.or.v[0]).rotateY(-e.or.v[1]).rotateZ(e.or.v[2]),this.mat.rotateX(-e.rx.v).rotateY(-e.ry.v).rotateZ(e.rz.v),this.mat.scale(1/e.s.v[0],1/e.s.v[1],1/e.s.v[2]),this.mat.translate(e.a.v[0],e.a.v[1],e.a.v[2])}this.p?this.mat.translate(-this.p.v[0],-this.p.v[1],this.p.v[2]):this.mat.translate(-this.px.v,-this.py.v,this.pz.v),this.a&&(r=this.p?[this.p.v[0]-this.a.v[0],this.p.v[1]-this.a.v[1],this.p.v[2]-this.a.v[2]]:[this.px.v-this.a.v[0],this.py.v-this.a.v[1],this.pz.v-this.a.v[2]],i=Math.sqrt(Math.pow(r[0],2)+Math.pow(r[1],2)+Math.pow(r[2],2)),r=[r[0]/i,r[1]/i,r[2]/i],i=Math.sqrt(r[2]*r[2]+r[0]*r[0]),i=Math.atan2(r[1],i),r=Math.atan2(r[0],-r[2]),this.mat.rotateY(r).rotateX(-i)),this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v),this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]),this.mat.translate(this.globalData.compSize.w/2,this.globalData.compSize.h/2,0),this.mat.translate(0,0,this.pe.v);var i,r,s=!this._prevMat.equals(this.mat);if((s||this.pe._mdf)&&this.comp.threeDElements){for(var a,n,o,h=this.comp.threeDElements.length,l=0;l<h;l+=1)"3d"===(o=this.comp.threeDElements[l]).type&&(s&&(a=this.mat.toCSS(),(n=o.container.style).transform=a,n.webkitTransform=a),this.pe._mdf)&&((n=o.perspectiveElem.style).perspective=this.pe.v+"px",n.webkitPerspective=this.pe.v+"px");this.mat.clone(this._prevMat)}}this._isFirstFrame=!1},HCameraElement.prototype.prepareFrame=function(t){this.prepareProperties(t,!0)},HCameraElement.prototype.destroy=function(){},HCameraElement.prototype.getBaseElement=function(){return null},extendPrototype([BaseElement,TransformElement,HBaseElement,HSolidElement,HierarchyElement,FrameElement,RenderableElement],HImageElement),HImageElement.prototype.createContent=function(){var t=this.globalData.getAssetsPath(this.assetData),e=new Image;this.data.hasMask?(this.imageElem=createNS("image"),this.imageElem.setAttribute("width",this.assetData.w+"px"),this.imageElem.setAttribute("height",this.assetData.h+"px"),this.imageElem.setAttributeNS("http://www.w3.org/1999/xlink","href",t),this.layerElement.appendChild(this.imageElem),this.baseElement.setAttribute("width",this.assetData.w),this.baseElement.setAttribute("height",this.assetData.h)):this.layerElement.appendChild(e),e.crossOrigin="anonymous",e.src=t,this.data.ln&&this.baseElement.setAttribute("id",this.data.ln)},extendPrototype([BaseRenderer],HybridRendererBase),HybridRendererBase.prototype.buildItem=SVGRenderer.prototype.buildItem,HybridRendererBase.prototype.checkPendingElements=function(){for(;this.pendingElements.length;)this.pendingElements.pop().checkParenting()},HybridRendererBase.prototype.appendElementInPos=function(t,e){t=t.getBaseElement();if(t){var i=this.layers[e];if(i.ddd&&this.supports3d)this.addTo3dContainer(t,e);else if(this.threeDElements)this.addTo3dContainer(t,e);else{for(var r,s,a=0;a<e;)this.elements[a]&&!0!==this.elements[a]&&this.elements[a].getBaseElement&&(s=this.elements[a],r=(this.layers[a].ddd?this.getThreeDContainerByPos(a):s.getBaseElement())||r),a+=1;r?i.ddd&&this.supports3d||this.layerElement.insertBefore(t,r):i.ddd&&this.supports3d||this.layerElement.appendChild(t)}}},HybridRendererBase.prototype.createShape=function(t){return new(this.supports3d?HShapeElement:SVGShapeElement)(t,this.globalData,this)},HybridRendererBase.prototype.createText=function(t){return new(this.supports3d?HTextElement:SVGTextLottieElement)(t,this.globalData,this)},HybridRendererBase.prototype.createCamera=function(t){return this.camera=new HCameraElement(t,this.globalData,this),this.camera},HybridRendererBase.prototype.createImage=function(t){return new(this.supports3d?HImageElement:IImageElement)(t,this.globalData,this)},HybridRendererBase.prototype.createSolid=function(t){return new(this.supports3d?HSolidElement:ISolidElement)(t,this.globalData,this)},HybridRendererBase.prototype.createNull=SVGRenderer.prototype.createNull,HybridRendererBase.prototype.getThreeDContainerByPos=function(t){for(var e=0,i=this.threeDElements.length;e<i;){if(this.threeDElements[e].startPos<=t&&this.threeDElements[e].endPos>=t)return this.threeDElements[e].perspectiveElem;e+=1}return null},HybridRendererBase.prototype.createThreeDContainer=function(t,e){var i,r=createTag("div"),s=(styleDiv(r),createTag("div")),a=(styleDiv(s),"3d"===e&&((a=r.style).width=this.globalData.compSize.w+"px",a.height=this.globalData.compSize.h+"px",a.webkitTransformOrigin=i="50% 50%",a.mozTransformOrigin=i,a.transformOrigin=i,(a=s.style).transform=i="matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)",a.webkitTransform=i),r.appendChild(s),{container:s,perspectiveElem:r,startPos:t,endPos:t,type:e});return this.threeDElements.push(a),a},HybridRendererBase.prototype.build3dContainers=function(){for(var t,e=this.layers.length,i="",r=0;r<e;r+=1)this.layers[r].ddd&&3!==this.layers[r].ty?(t="3d"!==i?this.createThreeDContainer(r,i="3d"):t).endPos=Math.max(t.endPos,r):(t="2d"!==i?this.createThreeDContainer(r,i="2d"):t).endPos=Math.max(t.endPos,r);for(r=(e=this.threeDElements.length)-1;0<=r;--r)this.resizerElem.appendChild(this.threeDElements[r].perspectiveElem)},HybridRendererBase.prototype.addTo3dContainer=function(t,e){for(var i=0,r=this.threeDElements.length;i<r;){if(e<=this.threeDElements[i].endPos){for(var s,a=this.threeDElements[i].startPos;a<e;)this.elements[a]&&this.elements[a].getBaseElement&&(s=this.elements[a].getBaseElement()),a+=1;s?this.threeDElements[i].container.insertBefore(t,s):this.threeDElements[i].container.appendChild(t);break}i+=1}},HybridRendererBase.prototype.configAnimation=function(t){var e=createTag("div"),i=this.animationItem.wrapper,r=e.style,i=(r.width=t.w+"px",r.height=t.h+"px",styleDiv(this.resizerElem=e),r.transformStyle="flat",r.mozTransformStyle="flat",r.webkitTransformStyle="flat",this.renderConfig.className&&e.setAttribute("class",this.renderConfig.className),i.appendChild(e),r.overflow="hidden",createNS("svg")),e=(i.setAttribute("width","1"),i.setAttribute("height","1"),styleDiv(i),this.resizerElem.appendChild(i),createNS("defs"));i.appendChild(e),this.data=t,this.setupGlobalData(t,i),this.globalData.defs=e,this.layers=t.layers,this.layerElement=this.resizerElem,this.build3dContainers(),this.updateContainerSize()},HybridRendererBase.prototype.destroy=function(){this.animationItem.wrapper&&(this.animationItem.wrapper.innerText=""),this.animationItem.container=null,this.globalData.defs=null;for(var t=this.layers?this.layers.length:0,e=0;e<t;e+=1)this.elements[e]&&this.elements[e].destroy&&this.elements[e].destroy();this.elements.length=0,this.destroyed=!0,this.animationItem=null},HybridRendererBase.prototype.updateContainerSize=function(){var t,e,i,r=this.animationItem.wrapper.offsetWidth,s=this.animationItem.wrapper.offsetHeight,r=r/s<this.globalData.compSize.w/this.globalData.compSize.h?(t=r/this.globalData.compSize.w,e=r/this.globalData.compSize.w,i=0,(s-this.globalData.compSize.h*(r/this.globalData.compSize.w))/2):(t=s/this.globalData.compSize.h,e=s/this.globalData.compSize.h,i=(r-this.globalData.compSize.w*(s/this.globalData.compSize.h))/2,0),s=this.resizerElem.style;s.webkitTransform="matrix3d("+t+",0,0,0,0,"+e+",0,0,0,0,1,0,"+i+","+r+",0,1)",s.transform=s.webkitTransform},HybridRendererBase.prototype.renderFrame=SVGRenderer.prototype.renderFrame,HybridRendererBase.prototype.hide=function(){this.resizerElem.style.display="none"},HybridRendererBase.prototype.show=function(){this.resizerElem.style.display="block"},HybridRendererBase.prototype.initItems=function(){if(this.buildAllItems(),this.camera)this.camera.setup();else for(var t=this.globalData.compSize.w,e=this.globalData.compSize.h,i=this.threeDElements.length,r=0;r<i;r+=1){var s=this.threeDElements[r].perspectiveElem.style;s.webkitPerspective=Math.sqrt(Math.pow(t,2)+Math.pow(e,2))+"px",s.perspective=s.webkitPerspective}},HybridRendererBase.prototype.searchExtraCompositions=function(t){for(var e,i=t.length,r=createTag("div"),s=0;s<i;s+=1)t[s].xt&&((e=this.createComp(t[s],r,this.globalData.comp,null)).initExpressions(),this.globalData.projectInterface.registerComposition(e))},extendPrototype([HybridRendererBase,ICompElement,HBaseElement],HCompElement),HCompElement.prototype._createBaseContainerElements=HCompElement.prototype.createContainerElements,HCompElement.prototype.createContainerElements=function(){this._createBaseContainerElements(),this.data.hasMask?(this.svgElement.setAttribute("width",this.data.w),this.svgElement.setAttribute("height",this.data.h),this.transformedElement=this.baseElement):this.transformedElement=this.layerElement},HCompElement.prototype.addTo3dContainer=function(t,e){for(var i,r=0;r<e;)this.elements[r]&&this.elements[r].getBaseElement&&(i=this.elements[r].getBaseElement()),r+=1;i?this.layerElement.insertBefore(t,i):this.layerElement.appendChild(t)},HCompElement.prototype.createComp=function(t){return new(this.supports3d?HCompElement:SVGCompElement)(t,this.globalData,this)},extendPrototype([HybridRendererBase],HybridRenderer),HybridRenderer.prototype.createComp=function(t){return new(this.supports3d?HCompElement:SVGCompElement)(t,this.globalData,this)};var CompExpressionInterface=function(r){function t(t){for(var e=0,i=r.layers.length;e<i;){if(r.layers[e].nm===t||r.layers[e].ind===t)return r.elements[e].layerInterface;e+=1}return null}return Object.defineProperty(t,"_name",{value:r.data.nm}),(t.layer=t).pixelAspect=1,t.height=r.data.h||r.globalData.compSize.h,t.width=r.data.w||r.globalData.compSize.w,t.pixelAspect=1,t.frameDuration=1/r.globalData.frameRate,t.displayStartTime=0,t.numLayers=r.layers.length,t};function _typeof$2(t){return(_typeof$2="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function seedRandom(n,o){var h,l=this,p=256,m=6,f="random",c=o.pow(p,m),d=o.pow(2,52),u=2*d,y=p-1;function g(t){var e,i=t.length,n=this,r=0,s=n.i=n.j=0,a=n.S=[];for(i||(t=[i++]);r<p;)a[r]=r++;for(r=0;r<p;r++)a[r]=a[s=y&s+t[r%i]+(e=a[r])],a[s]=e;n.g=function(t){for(var e,i=0,r=n.i,s=n.j,a=n.S;t--;)e=a[r=y&r+1],i=i*p+a[y&(a[r]=a[s=y&s+e])+(a[s]=e)];return n.i=r,n.j=s,i}}function v(t,e){return e.i=t.i,e.j=t.j,e.S=t.S.slice(),e}function b(t,e){for(var i,r=t+"",s=0;s<r.length;)e[y&s]=y&(i^=19*e[y&s])+r.charCodeAt(s++);return x(e)}function x(t){return String.fromCharCode.apply(0,t)}o["seed"+f]=function(t,e,i){function r(){for(var t=a.g(m),e=c,i=0;t<d;)t=(t+i)*p,e*=p,i=a.g(1);for(;u<=t;)t/=2,e/=2,i>>>=1;return(t+i)/e}var s=[],t=b(function t(e,i){var r,s=[],a=_typeof$2(e);if(i&&"object"==a)for(r in e)try{s.push(t(e[r],i-1))}catch(t){}return s.length?s:"string"==a?e:e+"\0"}((e=!0===e?{entropy:!0}:e||{}).entropy?[t,x(n)]:null===t?(()=>{try{return h?x(h.randomBytes(p)):(e=new Uint8Array(p),(l.crypto||l.msCrypto).getRandomValues(e),x(e))}catch(t){var e=l.navigator,e=e&&e.plugins;return[+new Date,l,e,l.screen,x(n)]}})():t,3),s),a=new g(s);return r.int32=function(){return 0|a.g(4)},r.quick=function(){return a.g(4)/4294967296},r.double=r,b(x(a.S),n),(e.pass||i||function(t,e,i,r){return r&&(r.S&&v(r,a),t.state=function(){return v(a,{})}),i?(o[f]=t,e):t})(r,t,"global"in e?e.global:this==o,e.state)},b(o.random(),n)}function initialize$2(t){seedRandom([],t)}var propTypes={SHAPE:"shape"};function _typeof$1(t){return(_typeof$1="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var ExpressionManager=function(){var ob={},Math=BMMath,window=null,document=null,XMLHttpRequest=null,fetch=null,frames=null,_lottieGlobal={};function resetFrame(){_lottieGlobal={}}function $bm_isInstanceOfArray(t){return t.constructor===Array||t.constructor===Float32Array}function isNumerable(t,e){return"number"===t||e instanceof Number||"boolean"===t||"string"===t}function $bm_neg(t){var e=_typeof$1(t);if("number"===e||t instanceof Number||"boolean"===e)return-t;if($bm_isInstanceOfArray(t)){for(var i=t.length,r=[],s=0;s<i;s+=1)r[s]=-t[s];return r}return t.propType?t.v:-t}initialize$2(BMMath);var easeInBez=BezierFactory.getBezierEasing(.333,0,.833,.833,"easeIn").get,easeOutBez=BezierFactory.getBezierEasing(.167,.167,.667,1,"easeOut").get,easeInOutBez=BezierFactory.getBezierEasing(.33,0,.667,1,"easeInOut").get;function sum(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e)||"string"===i||"string"===r)return t+e;if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]+=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t+e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]+e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}var add=sum;function sub(t,e){var i=_typeof$1(t),r=_typeof$1(e);if(isNumerable(i,t)&&isNumerable(r,e))return(t="string"===i?parseInt(t,10):t)-(e="string"===r?parseInt(e,10):e);if($bm_isInstanceOfArray(t)&&isNumerable(r,e))return(t=t.slice(0))[0]-=e,t;if(isNumerable(i,t)&&$bm_isInstanceOfArray(e))return(e=e.slice(0))[0]=t-e[0],e;if($bm_isInstanceOfArray(t)&&$bm_isInstanceOfArray(e)){for(var s=0,a=t.length,n=e.length,o=[];s<a||s<n;)("number"==typeof t[s]||t[s]instanceof Number)&&("number"==typeof e[s]||e[s]instanceof Number)?o[s]=t[s]-e[s]:o[s]=void 0===e[s]?t[s]:t[s]||e[s],s+=1;return o}return 0}function mul(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t*e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]*e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t*e[r];return i}return 0}function div(t,e){var i,r,s,a=_typeof$1(t),n=_typeof$1(e);if(isNumerable(a,t)&&isNumerable(n,e))return t/e;if($bm_isInstanceOfArray(t)&&isNumerable(n,e)){for(s=t.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t[r]/e;return i}if(isNumerable(a,t)&&$bm_isInstanceOfArray(e)){for(s=e.length,i=createTypedArray("float32",s),r=0;r<s;r+=1)i[r]=t/e[r];return i}return 0}function mod(t,e){return(t="string"==typeof t?parseInt(t,10):t)%(e="string"==typeof e?parseInt(e,10):e)}var $bm_sum=sum,$bm_sub=sub,$bm_mul=mul,$bm_div=div,$bm_mod=mod;function clamp(t,e,i){var r;return i<e&&(r=i,i=e,e=r),Math.min(Math.max(t,e),i)}function radiansToDegrees(t){return t/degToRads}var radians_to_degrees=radiansToDegrees;function degreesToRadians(t){return t*degToRads}var degrees_to_radians=radiansToDegrees,helperLengthArray=[0,0,0,0,0,0];function length(t,e){if("number"==typeof t||t instanceof Number)return Math.abs(t-(e=e||0));for(var i=Math.min(t.length,(e=e||helperLengthArray).length),r=0,s=0;s<i;s+=1)r+=Math.pow(e[s]-t[s],2);return Math.sqrt(r)}function normalize(t){return div(t,length(t))}function rgbToHsl(t){var e,i=t[0],r=t[1],s=t[2],a=Math.max(i,r,s),n=Math.min(i,r,s),o=(a+n)/2;if(a===n)l=e=0;else{var h=a-n,l=.5<o?h/(2-a-n):h/(a+n);switch(a){case i:e=(r-s)/h+(r<s?6:0);break;case r:e=(s-i)/h+2;break;case s:e=(i-r)/h+4}e/=6}return[e,l,o,t[3]]}function hue2rgb(t,e,i){return i<0&&(i+=1),1<i&&--i,i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t}function hslToRgb(t){var e,i,r,s=t[0],a=t[1],n=t[2];return 0===a?i=r=e=n:(e=hue2rgb(a=2*n-(n=n<.5?n*(1+a):n+a-n*a),n,s+1/3),i=hue2rgb(a,n,s),r=hue2rgb(a,n,s-1/3)),[e,i,r,t[3]]}function linear(t,e,i,r,s){var a;if(void 0!==r&&void 0!==s||(r=e,s=i,e=0,i=1),i<e&&(a=i,i=e,e=a),t<=e)return r;if(i<=t)return s;var n=i===e?0:(t-e)/(i-e);if(!r.length)return r+(s-r)*n;for(var o=r.length,h=createTypedArray("float32",o),l=0;l<o;l+=1)h[l]=r[l]+(s[l]-r[l])*n;return h}function random(t,e){if(void 0===e&&(void 0===t?(t=0,e=1):(e=t,t=void 0)),e.length){for(var i=e.length,r=(t=t||createTypedArray("float32",i),createTypedArray("float32",i)),s=BMMath.random(),a=0;a<i;a+=1)r[a]=t[a]+s*(e[a]-t[a]);return r}return(t=void 0===t?0:t)+BMMath.random()*(e-t)}function createPath(t,e,i,r){for(var s,a,n=t.length,o=shapePool.newElement(),h=(o.setPathData(!!r,n),[0,0]),l=0;l<n;l+=1)s=e&&e[l]?e[l]:h,a=i&&i[l]?i[l]:h,o.setTripleAt(t[l][0],t[l][1],a[0]+t[l][0],a[1]+t[l][1],s[0]+t[l][0],s[1]+t[l][1],l,!0);return o}function initiateExpression(elem,data,property){function noOp(t){return t}if(!elem.globalData.renderConfig.runExpressions)return noOp;var val=data.x,needsVelocity=/velocity(?![\w\d])/.test(val),_needsRandom=-1!==val.indexOf("random"),elemType=elem.data.ty,transform,$bm_transform,content,effect,thisProperty=property,inPoint=(thisProperty._name=elem.data.nm,thisProperty.valueAtTime=thisProperty.getValueAtTime,Object.defineProperty(thisProperty,"value",{get:function(){return thisProperty.v}}),elem.comp.frameDuration=1/elem.comp.globalData.frameRate,elem.comp.displayStartTime=0,elem.data.ip/elem.comp.globalData.frameRate),outPoint=elem.data.op/elem.comp.globalData.frameRate,width=elem.data.sw||0,height=elem.data.sh||0,name=elem.data.nm,loopIn,loop_in,loopOut,loop_out,smooth,toWorld,fromWorld,fromComp,toComp,fromCompToSurface,position,rotation,anchorPoint,scale,thisLayer,thisComp,mask,valueAtTime,velocityAtTime,scoped_bm_rt,expression_function=eval("[function _expression_function(){"+val+";scoped_bm_rt=$bm_rt}]")[0],numKeys=property.kf?data.k.length:0,active=!this.data||!0!==this.data.hd,wiggle=function(t,e){for(var i=this.pv.length||1,r=createTypedArray("float32",i),s=Math.floor(5*time),a=0,n=0;a<s;){for(n=0;n<i;n+=1)r[n]+=-e+2*e*BMMath.random();a+=1}var o=5*time,h=o-Math.floor(o),l=createTypedArray("float32",i);if(1<i){for(n=0;n<i;n+=1)l[n]=this.pv[n]+r[n]+(-e+2*e*BMMath.random())*h;return l}return this.pv+r[0]+(-e+2*e*BMMath.random())*h}.bind(this);function loopInDuration(t,e){return loopIn(t,e,!0)}function loopOutDuration(t,e){return loopOut(t,e,!0)}thisProperty.loopIn&&(loopIn=thisProperty.loopIn.bind(thisProperty),loop_in=loopIn),thisProperty.loopOut&&(loopOut=thisProperty.loopOut.bind(thisProperty),loop_out=loopOut),thisProperty.smooth&&(smooth=thisProperty.smooth.bind(thisProperty)),this.getValueAtTime&&(valueAtTime=this.getValueAtTime.bind(this)),this.getVelocityAtTime&&(velocityAtTime=this.getVelocityAtTime.bind(this));var comp=elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface),time,velocity,value,text,textIndex,textTotal,selectorValue;function lookAt(t,e){e=[e[0]-t[0],e[1]-t[1],e[2]-t[2]],t=Math.atan2(e[0],Math.sqrt(e[1]*e[1]+e[2]*e[2]))/degToRads;return[-Math.atan2(e[1],e[2])/degToRads,t,0]}function easeOut(t,e,i,r,s){return applyEase(easeOutBez,t,e,i,r,s)}function easeIn(t,e,i,r,s){return applyEase(easeInBez,t,e,i,r,s)}function ease(t,e,i,r,s){return applyEase(easeInOutBez,t,e,i,r,s)}function applyEase(t,e,i,r,s,a){void 0===s?(s=i,a=r):e=(e-i)/(r-i),1<e?e=1:e<0&&(e=0);var n=t(e);if($bm_isInstanceOfArray(s)){for(var o=s.length,h=createTypedArray("float32",o),l=0;l<o;l+=1)h[l]=(a[l]-s[l])*n+s[l];return h}return(a-s)*n+s}function nearestKey(t){var e,i,r,s=data.k.length;if(data.k.length&&"number"!=typeof data.k[0])if(i=-1,(t*=elem.comp.globalData.frameRate)<data.k[0].t)i=1,r=data.k[0].t;else{for(e=0;e<s-1;e+=1){if(t===data.k[e].t){i=e+1,r=data.k[e].t;break}if(t>data.k[e].t&&t<data.k[e+1].t){r=(t-data.k[e].t>data.k[e+1].t-t?(i=e+2,data.k[e+1]):(i=e+1,data.k[e])).t;break}}-1===i&&(i=e+1,r=data.k[e].t)}else r=i=0;var a={};return a.index=i,a.time=r/elem.comp.globalData.frameRate,a}function key(t){if(!data.k.length||"number"==typeof data.k[0])throw new Error("The property has no keyframe at index "+t);for(var e={time:data.k[--t].t/elem.comp.globalData.frameRate,value:[]},i=Object.prototype.hasOwnProperty.call(data.k[t],"s")?data.k[t].s:data.k[t-1].e,r=i.length,s=0;s<r;s+=1)e[s]=i[s],e.value[s]=i[s];return e}function framesToTime(t,e){return t/(e=e||elem.comp.globalData.frameRate)}function timeToFrames(t,e){return(t=t||0===t?t:time)*(e=e||elem.comp.globalData.frameRate)}function seedRandom(t){BMMath.seedrandom(randSeed+t)}function sourceRectAtTime(){return elem.sourceRectAtTime()}function substring(t,e){return"string"==typeof value?void 0===e?value.substring(t):value.substring(t,e):""}function substr(t,e){return"string"==typeof value?void 0===e?value.substr(t):value.substr(t,e):""}function posterizeTime(t){time=0===t?0:Math.floor(time*t)/t,value=valueAtTime(time)}var index=elem.data.ind,hasParent=!(!elem.hierarchy||!elem.hierarchy.length),parent,randSeed=Math.floor(1e6*Math.random()),globalData=elem.globalData;function executeExpression(t){return value=t,this.frameExpressionId===elem.globalData.frameId&&"textSelector"!==this.propType?value:("textSelector"===this.propType&&(textIndex=this.textIndex,textTotal=this.textTotal,selectorValue=this.selectorValue),thisLayer||(text=elem.layerInterface.text,thisLayer=elem.layerInterface,thisComp=elem.comp.compInterface,toWorld=thisLayer.toWorld.bind(thisLayer),fromWorld=thisLayer.fromWorld.bind(thisLayer),fromComp=thisLayer.fromComp.bind(thisLayer),toComp=thisLayer.toComp.bind(thisLayer),mask=thisLayer.mask?thisLayer.mask.bind(thisLayer):null,fromCompToSurface=fromComp),!transform&&(transform=elem.layerInterface("ADBE Transform Group"),$bm_transform=transform)&&(anchorPoint=transform.anchorPoint),4===elemType&&(content=content||thisLayer("ADBE Root Vectors Group")),effect=effect||thisLayer(4),(hasParent=!(!elem.hierarchy||!elem.hierarchy.length))&&!parent&&(parent=elem.hierarchy[0].layerInterface),time=this.comp.renderedFrame/this.comp.globalData.frameRate,_needsRandom&&seedRandom(randSeed+time),needsVelocity&&(velocity=velocityAtTime(time)),expression_function(),this.frameExpressionId=elem.globalData.frameId,scoped_bm_rt=scoped_bm_rt.propType===propTypes.SHAPE?scoped_bm_rt.v:scoped_bm_rt)}return executeExpression.__preventDeadCodeRemoval=[$bm_transform,anchorPoint,time,velocity,inPoint,outPoint,width,height,name,loop_in,loop_out,smooth,toComp,fromCompToSurface,toWorld,fromWorld,mask,position,rotation,scale,thisComp,numKeys,active,wiggle,loopInDuration,loopOutDuration,comp,lookAt,easeOut,easeIn,ease,nearestKey,key,text,textIndex,textTotal,selectorValue,framesToTime,timeToFrames,sourceRectAtTime,substring,substr,posterizeTime,index,globalData],executeExpression}return ob.initiateExpression=initiateExpression,ob.__preventDeadCodeRemoval=[window,document,XMLHttpRequest,fetch,frames,$bm_neg,add,$bm_sum,$bm_sub,$bm_mul,$bm_div,$bm_mod,clamp,radians_to_degrees,degreesToRadians,degrees_to_radians,normalize,rgbToHsl,hslToRgb,linear,random,createPath,_lottieGlobal],ob.resetFrame=resetFrame,ob}(),Expressions=(()=>{var t={};return t.initExpressions=function(t){var i=0,r=[];t.renderer.compInterface=CompExpressionInterface(t.renderer),t.renderer.globalData.projectInterface.registerComposition(t.renderer),t.renderer.globalData.pushExpression=function(){i+=1},t.renderer.globalData.popExpression=function(){if(0===--i){var t,e=r.length;for(t=0;t<e;t+=1)r[t].release();r.length=0}},t.renderer.globalData.registerExpressionProperty=function(t){-1===r.indexOf(t)&&r.push(t)}},t.resetFrame=ExpressionManager.resetFrame,t})(),MaskManagerInterface=(()=>{function t(t,e){this._mask=t,this._data=e}return Object.defineProperty(t.prototype,"maskPath",{get:function(){return this._mask.prop.k&&this._mask.prop.getValue(),this._mask.prop}}),Object.defineProperty(t.prototype,"maskOpacity",{get:function(){return this._mask.op.k&&this._mask.op.getValue(),100*this._mask.op.v}}),function(e){for(var i=createSizedArray(e.viewData.length),r=e.viewData.length,s=0;s<r;s+=1)i[s]=new t(e.viewData[s],e.masksProperties[s]);return function(t){for(s=0;s<r;){if(e.masksProperties[s].nm===t)return i[s];s+=1}return null}}})(),ExpressionPropertyInterface=(()=>{var p={pv:0,v:0,mult:1},m={pv:[0,0,0],v:[0,0,0],mult:1};function f(r,s,a){Object.defineProperty(r,"velocity",{get:function(){return s.getVelocityAtTime(s.comp.currentFrame)}}),r.numKeys=s.keyframes?s.keyframes.length:0,r.key=function(t){var e,i;return r.numKeys?(e="",e="s"in s.keyframes[t-1]?s.keyframes[t-1].s:"e"in s.keyframes[t-2]?s.keyframes[t-2].e:s.keyframes[t-2].s,(i="unidimensional"===a?new Number(e):Object.assign({},e)).time=s.keyframes[t-1].t/s.elem.comp.globalData.frameRate,i.value="unidimensional"===a?e[0]:e,i):0},r.valueAtTime=s.getValueAtTime,r.speedAtTime=s.getSpeedAtTime,r.velocityAtTime=s.getVelocityAtTime,r.propertyGroup=s.propertyGroup}function c(){return p}return function(t){var e,i,r,s,a,n,o,h,l;return t?"unidimensional"===t.propType?(i=1/(e=(e=t)&&"pv"in e?e:p).mult,r=e.pv*i,(s=new Number(r)).value=r,f(s,e,"unidimensional"),function(){return e.k&&e.getValue(),r=e.v*i,s.value!==r&&((s=new Number(r)).value=r,s[0]=r,f(s,e,"unidimensional")),s}):(n=1/(a=(a=t)&&"pv"in a?a:m).mult,o=a.data&&a.data.l||a.pv.length,h=createTypedArray("float32",o),l=createTypedArray("float32",o),h.value=l,f(h,a,"multidimensional"),function(){a.k&&a.getValue();for(var t=0;t<o;t+=1)l[t]=a.v[t]*n,h[t]=l[t];return h}):c}})(),TransformExpressionInterface=function(t){function e(t){switch(t){case"scale":case"Scale":case"ADBE Scale":case 6:return e.scale;case"rotation":case"Rotation":case"ADBE Rotation":case"ADBE Rotate Z":case 10:return e.rotation;case"ADBE Rotate X":return e.xRotation;case"ADBE Rotate Y":return e.yRotation;case"position":case"Position":case"ADBE Position":case 2:return e.position;case"ADBE Position_0":return e.xPosition;case"ADBE Position_1":return e.yPosition;case"ADBE Position_2":return e.zPosition;case"anchorPoint":case"AnchorPoint":case"Anchor Point":case"ADBE AnchorPoint":case 1:return e.anchorPoint;case"opacity":case"Opacity":case 11:return e.opacity;default:return null}}var i,r,s,a;return Object.defineProperty(e,"rotation",{get:ExpressionPropertyInterface(t.r||t.rz)}),Object.defineProperty(e,"zRotation",{get:ExpressionPropertyInterface(t.rz||t.r)}),Object.defineProperty(e,"xRotation",{get:ExpressionPropertyInterface(t.rx)}),Object.defineProperty(e,"yRotation",{get:ExpressionPropertyInterface(t.ry)}),Object.defineProperty(e,"scale",{get:ExpressionPropertyInterface(t.s)}),t.p?a=ExpressionPropertyInterface(t.p):(i=ExpressionPropertyInterface(t.px),r=ExpressionPropertyInterface(t.py),t.pz&&(s=ExpressionPropertyInterface(t.pz))),Object.defineProperty(e,"position",{get:function(){return t.p?a():[i(),r(),s?s():0]}}),Object.defineProperty(e,"xPosition",{get:ExpressionPropertyInterface(t.px)}),Object.defineProperty(e,"yPosition",{get:ExpressionPropertyInterface(t.py)}),Object.defineProperty(e,"zPosition",{get:ExpressionPropertyInterface(t.pz)}),Object.defineProperty(e,"anchorPoint",{get:ExpressionPropertyInterface(t.a)}),Object.defineProperty(e,"opacity",{get:ExpressionPropertyInterface(t.o)}),Object.defineProperty(e,"skew",{get:ExpressionPropertyInterface(t.sk)}),Object.defineProperty(e,"skewAxis",{get:ExpressionPropertyInterface(t.sa)}),Object.defineProperty(e,"orientation",{get:ExpressionPropertyInterface(t.or)}),e},LayerExpressionInterface=(()=>{function s(t){var e=new Matrix;return void 0!==t?this._elem.finalTransform.mProp.getValueAtTime(t).clone(e):this._elem.finalTransform.mProp.applyToMatrix(e),e}function a(t,e){e=this.getMatrix(e);return e.props[12]=0,e.props[13]=0,e.props[14]=0,this.applyPoint(e,t)}function n(t,e){e=this.getMatrix(e);return this.applyPoint(e,t)}function o(t,e){e=this.getMatrix(e);return e.props[12]=0,e.props[13]=0,e.props[14]=0,this.invertPoint(e,t)}function h(t,e){e=this.getMatrix(e);return this.invertPoint(e,t)}function l(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length)for(var i=this._elem.hierarchy.length,r=0;r<i;r+=1)this._elem.hierarchy[r].finalTransform.mProp.applyToMatrix(t);return t.applyToPointArray(e[0],e[1],e[2]||0)}function p(t,e){if(this._elem.hierarchy&&this._elem.hierarchy.length)for(var i=this._elem.hierarchy.length,r=0;r<i;r+=1)this._elem.hierarchy[r].finalTransform.mProp.applyToMatrix(t);return t.inversePoint(e)}function m(t){var e=new Matrix;if(e.reset(),this._elem.finalTransform.mProp.applyToMatrix(e),this._elem.hierarchy&&this._elem.hierarchy.length)for(var i=this._elem.hierarchy.length,r=0;r<i;r+=1)this._elem.hierarchy[r].finalTransform.mProp.applyToMatrix(e);return e.inversePoint(t)}function f(){return[1,1,1,1]}return function(e){function i(t){switch(t){case"ADBE Root Vectors Group":case"Contents":case 2:return i.shapeInterface;case 1:case 6:case"Transform":case"transform":case"ADBE Transform Group":return r;case 4:case"ADBE Effect Parade":case"effects":case"Effects":return i.effect;case"ADBE Text Properties":return i.textInterface;default:return null}}i.getMatrix=s,i.invertPoint=p,i.applyPoint=l,i.toWorld=n,i.toWorldVec=a,i.fromWorld=h,i.fromWorldVec=o,i.toComp=n,i.fromComp=m,i.sampleImage=f,i.sourceRectAtTime=e.sourceRectAtTime.bind(e);var r,t=getDescriptor(r=TransformExpressionInterface((i._elem=e).finalTransform.mProp),"anchorPoint");return Object.defineProperties(i,{hasParent:{get:function(){return e.hierarchy.length}},parent:{get:function(){return e.hierarchy[0].layerInterface}},rotation:getDescriptor(r,"rotation"),scale:getDescriptor(r,"scale"),position:getDescriptor(r,"position"),opacity:getDescriptor(r,"opacity"),anchorPoint:t,anchor_point:t,transform:{get:function(){return r}},active:{get:function(){return e.isInRange}}}),i.startTime=e.data.st,i.index=e.data.ind,i.source=e.data.refId,i.height=0===e.data.ty?e.data.h:100,i.width=0===e.data.ty?e.data.w:100,i.inPoint=e.data.ip/e.comp.globalData.frameRate,i.outPoint=e.data.op/e.comp.globalData.frameRate,i._name=e.data.nm,i.registerMaskInterface=function(t){i.mask=new MaskManagerInterface(t,e)},i.registerEffectsInterface=function(t){i.effect=t},i}})(),propertyGroupFactory=function(e,i){return function(t){return(t=void 0===t?1:t)<=0?e:i(t-1)}},PropertyInterface=function(t,e){var i={_name:t};return function(t){return(t=void 0===t?1:t)<=0?i:e(t-1)}},EffectsExpressionInterface=(()=>{function p(t,e,i,r){var s=ExpressionPropertyInterface(t.p);return t.p.setGroupProperty&&t.p.setGroupProperty(PropertyInterface("",r)),function(){return 10===e?i.comp.compInterface(t.p.v):s()}}return{createEffectsInterface:function(t,e){if(t.effectsManager){var i,r=[],s=t.data.ef,a=t.effectsManager.effectElements.length;for(i=0;i<a;i+=1)r.push(function t(s,e,i,r){function a(t){for(var e=s.ef,i=0,r=e.length;i<r;){if(t===e[i].nm||t===e[i].mn||t===e[i].ix)return 5===e[i].ty?o[i]:o[i]();i+=1}throw new Error}var n=propertyGroupFactory(a,i);var o=[];var h;var l=s.ef.length;for(h=0;h<l;h+=1)5===s.ef[h].ty?o.push(t(s.ef[h],e.effectElements[h],e.effectElements[h].propertyGroup,r)):o.push(p(e.effectElements[h],s.ef[h].ty,r,n));"ADBE Color Control"===s.mn&&Object.defineProperty(a,"color",{get:function(){return o[0]()}});Object.defineProperties(a,{numProperties:{get:function(){return s.np}},_name:{value:s.nm},propertyGroup:{value:n}});a.enabled=0!==s.en;a.active=a.enabled;return a}(s[i],t.effectsManager.effectElements[i],e,t));var n=t.data.ef||[],o=function(t){for(i=0,a=n.length;i<a;){if(t===n[i].nm||t===n[i].mn||t===n[i].ix)return r[i];i+=1}return null};return Object.defineProperty(o,"numProperties",{get:function(){return n.length}}),o}return null}}})(),ShapePathInterface=function(t,e,i){var r=e.sh;function s(t){return"Shape"===t||"shape"===t||"Path"===t||"path"===t||"ADBE Vector Shape"===t||2===t?s.path:null}e=propertyGroupFactory(s,i);return r.setGroupProperty(PropertyInterface("Path",e)),Object.defineProperties(s,{path:{get:function(){return r.k&&r.getValue(),r}},shape:{get:function(){return r.k&&r.getValue(),r}},_name:{value:t.nm},ix:{value:t.ix},propertyIndex:{value:t.ix},mn:{value:t.mn},propertyGroup:{value:i}}),s},ShapeExpressionInterface=(()=>{function n(t,e,i){for(var r=[],s=t?t.length:0,a=0;a<s;a+=1)"gr"===t[a].ty?r.push(((t,e,i)=>{function r(t){switch(t){case"ADBE Vectors Group":case"Contents":case 2:return r.content;default:return r.transform}}return r.propertyGroup=propertyGroupFactory(r,i),i=((t,e,i)=>{function r(t){for(var e=0,i=s.length;e<i;){if(s[e]._name===t||s[e].mn===t||s[e].propertyIndex===t||s[e].ix===t||s[e].ind===t)return s[e];e+=1}return"number"==typeof t?s[t-1]:null}r.propertyGroup=propertyGroupFactory(r,i),s=n(t.it,e.it,r.propertyGroup),r.numProperties=s.length;var s,i=o(t.it[t.it.length-1],e.it[e.it.length-1],r.propertyGroup);return r.transform=i,r.propertyIndex=t.cix,r._name=t.nm,r})(t,e,r.propertyGroup),e=o(t.it[t.it.length-1],e.it[e.it.length-1],r.propertyGroup),r.content=i,r.transform=e,Object.defineProperty(r,"_name",{get:function(){return t.nm}}),r.numProperties=t.np,r.propertyIndex=t.ix,r.nm=t.nm,r.mn=t.mn,r})(t[a],e[a],i)):"fl"===t[a].ty?r.push(((t,e,i)=>{function r(t){return"Color"===t||"color"===t?r.color:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r})(t[a],e[a],i)):"st"===t[a].ty?r.push(((t,e,i)=>{var r,i=propertyGroupFactory(h,i),s=propertyGroupFactory(void 0,i),a=t.d?t.d.length:0,n={};for(r=0;r<a;r+=1){{o=void 0;var o=r;Object.defineProperty(n,t.d[o].nm,{get:ExpressionPropertyInterface(e.d.dataProps[o].p)})}e.d.dataProps[r].p.setGroupProperty(s)}function h(t){return"Color"===t||"color"===t?h.color:"Opacity"===t||"opacity"===t?h.opacity:"Stroke Width"===t||"stroke width"===t?h.strokeWidth:null}return Object.defineProperties(h,{color:{get:ExpressionPropertyInterface(e.c)},opacity:{get:ExpressionPropertyInterface(e.o)},strokeWidth:{get:ExpressionPropertyInterface(e.w)},dash:{get:function(){return n}},_name:{value:t.nm},mn:{value:t.mn}}),e.c.setGroupProperty(PropertyInterface("Color",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),e.w.setGroupProperty(PropertyInterface("Stroke Width",i)),h})(t[a],e[a],i)):"tm"===t[a].ty?r.push(((e,t,i)=>{function r(t){return t===e.e.ix||"End"===t||"end"===t?r.end:t===e.s.ix?r.start:t===e.o.ix?r.offset:null}var s=propertyGroupFactory(r,i);return r.propertyIndex=e.ix,t.s.setGroupProperty(PropertyInterface("Start",s)),t.e.setGroupProperty(PropertyInterface("End",s)),t.o.setGroupProperty(PropertyInterface("Offset",s)),r.propertyIndex=e.ix,r.propertyGroup=i,Object.defineProperties(r,{start:{get:ExpressionPropertyInterface(t.s)},end:{get:ExpressionPropertyInterface(t.e)},offset:{get:ExpressionPropertyInterface(t.o)},_name:{value:e.nm}}),r.mn=e.mn,r})(t[a],e[a],i)):"tr"!==t[a].ty&&("el"===t[a].ty?r.push(((e,t,i)=>{function r(t){return e.p.ix===t?r.position:e.s.ix===t?r.size:null}return i=propertyGroupFactory(r,i),r.propertyIndex=e.ix,(t="tm"===t.sh.ty?t.sh.prop:t.sh).s.setGroupProperty(PropertyInterface("Size",i)),t.p.setGroupProperty(PropertyInterface("Position",i)),Object.defineProperties(r,{size:{get:ExpressionPropertyInterface(t.s)},position:{get:ExpressionPropertyInterface(t.p)},_name:{value:e.nm}}),r.mn=e.mn,r})(t[a],e[a],i)):"sr"===t[a].ty?r.push(((e,t,i)=>{function r(t){return e.p.ix===t?r.position:e.r.ix===t?r.rotation:e.pt.ix===t?r.points:e.or.ix===t||"ADBE Vector Star Outer Radius"===t?r.outerRadius:e.os.ix===t?r.outerRoundness:!e.ir||e.ir.ix!==t&&"ADBE Vector Star Inner Radius"!==t?e.is&&e.is.ix===t?r.innerRoundness:null:r.innerRadius}return i=propertyGroupFactory(r,i),t="tm"===t.sh.ty?t.sh.prop:t.sh,r.propertyIndex=e.ix,t.or.setGroupProperty(PropertyInterface("Outer Radius",i)),t.os.setGroupProperty(PropertyInterface("Outer Roundness",i)),t.pt.setGroupProperty(PropertyInterface("Points",i)),t.p.setGroupProperty(PropertyInterface("Position",i)),t.r.setGroupProperty(PropertyInterface("Rotation",i)),e.ir&&(t.ir.setGroupProperty(PropertyInterface("Inner Radius",i)),t.is.setGroupProperty(PropertyInterface("Inner Roundness",i))),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(t.p)},rotation:{get:ExpressionPropertyInterface(t.r)},points:{get:ExpressionPropertyInterface(t.pt)},outerRadius:{get:ExpressionPropertyInterface(t.or)},outerRoundness:{get:ExpressionPropertyInterface(t.os)},innerRadius:{get:ExpressionPropertyInterface(t.ir)},innerRoundness:{get:ExpressionPropertyInterface(t.is)},_name:{value:e.nm}}),r.mn=e.mn,r})(t[a],e[a],i)):"sh"===t[a].ty?r.push(ShapePathInterface(t[a],e[a],i)):"rc"===t[a].ty?r.push(((e,t,i)=>{function r(t){return e.p.ix===t?r.position:e.r.ix===t?r.roundness:e.s.ix===t||"Size"===t||"ADBE Vector Rect Size"===t?r.size:null}return i=propertyGroupFactory(r,i),t="tm"===t.sh.ty?t.sh.prop:t.sh,r.propertyIndex=e.ix,t.p.setGroupProperty(PropertyInterface("Position",i)),t.s.setGroupProperty(PropertyInterface("Size",i)),t.r.setGroupProperty(PropertyInterface("Rotation",i)),Object.defineProperties(r,{position:{get:ExpressionPropertyInterface(t.p)},roundness:{get:ExpressionPropertyInterface(t.r)},size:{get:ExpressionPropertyInterface(t.s)},_name:{value:e.nm}}),r.mn=e.mn,r})(t[a],e[a],i)):"rd"===t[a].ty?r.push(((e,t,i)=>{function r(t){return e.r.ix===t||"Round Corners 1"===t?r.radius:null}return i=propertyGroupFactory(r,i),r.propertyIndex=e.ix,t.rd.setGroupProperty(PropertyInterface("Radius",i)),Object.defineProperties(r,{radius:{get:ExpressionPropertyInterface(t.rd)},_name:{value:e.nm}}),r.mn=e.mn,r})(t[a],e[a],i)):"rp"===t[a].ty?r.push(((e,t,i)=>{function r(t){return e.c.ix===t||"Copies"===t?r.copies:e.o.ix===t||"Offset"===t?r.offset:null}return i=propertyGroupFactory(r,i),r.propertyIndex=e.ix,t.c.setGroupProperty(PropertyInterface("Copies",i)),t.o.setGroupProperty(PropertyInterface("Offset",i)),Object.defineProperties(r,{copies:{get:ExpressionPropertyInterface(t.c)},offset:{get:ExpressionPropertyInterface(t.o)},_name:{value:e.nm}}),r.mn=e.mn,r})(t[a],e[a],i)):"gf"===t[a].ty?r.push(((t,e,i)=>{function r(t){return"Start Point"===t||"start point"===t?r.startPoint:"End Point"===t||"end point"===t?r.endPoint:"Opacity"===t||"opacity"===t?r.opacity:null}return Object.defineProperties(r,{startPoint:{get:ExpressionPropertyInterface(e.s)},endPoint:{get:ExpressionPropertyInterface(e.e)},opacity:{get:ExpressionPropertyInterface(e.o)},type:{get:function(){return"a"}},_name:{value:t.nm},mn:{value:t.mn}}),e.s.setGroupProperty(PropertyInterface("Start Point",i)),e.e.setGroupProperty(PropertyInterface("End Point",i)),e.o.setGroupProperty(PropertyInterface("Opacity",i)),r})(t[a],e[a],i)):r.push((t[a],e[a],function(){return null})));return r}function o(e,t,i){function r(t){return e.a.ix===t||"Anchor Point"===t?r.anchorPoint:e.o.ix===t||"Opacity"===t?r.opacity:e.p.ix===t||"Position"===t?r.position:e.r.ix===t||"Rotation"===t||"ADBE Vector Rotation"===t?r.rotation:e.s.ix===t||"Scale"===t?r.scale:e.sk&&e.sk.ix===t||"Skew"===t?r.skew:e.sa&&e.sa.ix===t||"Skew Axis"===t?r.skewAxis:null}var s=propertyGroupFactory(r,i);return t.transform.mProps.o.setGroupProperty(PropertyInterface("Opacity",s)),t.transform.mProps.p.setGroupProperty(PropertyInterface("Position",s)),t.transform.mProps.a.setGroupProperty(PropertyInterface("Anchor Point",s)),t.transform.mProps.s.setGroupProperty(PropertyInterface("Scale",s)),t.transform.mProps.r.setGroupProperty(PropertyInterface("Rotation",s)),t.transform.mProps.sk&&(t.transform.mProps.sk.setGroupProperty(PropertyInterface("Skew",s)),t.transform.mProps.sa.setGroupProperty(PropertyInterface("Skew Angle",s))),t.transform.op.setGroupProperty(PropertyInterface("Opacity",s)),Object.defineProperties(r,{opacity:{get:ExpressionPropertyInterface(t.transform.mProps.o)},position:{get:ExpressionPropertyInterface(t.transform.mProps.p)},anchorPoint:{get:ExpressionPropertyInterface(t.transform.mProps.a)},scale:{get:ExpressionPropertyInterface(t.transform.mProps.s)},rotation:{get:ExpressionPropertyInterface(t.transform.mProps.r)},skew:{get:ExpressionPropertyInterface(t.transform.mProps.sk)},skewAxis:{get:ExpressionPropertyInterface(t.transform.mProps.sa)},_name:{value:e.nm}}),r.ty="tr",r.mn=e.mn,r.propertyGroup=i,r}return function(t,e,r){var s;function i(t){if("number"==typeof t)return 0===(t=void 0===t?1:t)?r:s[t-1];for(var e=0,i=s.length;e<i;){if(s[e]._name===t)return s[e];e+=1}return null}return i.propertyGroup=propertyGroupFactory(i,function(){return r}),s=n(t,e,i.propertyGroup),i.numProperties=s.length,i._name="Contents",i}})(),TextExpressionInterface=function(e){var i;function r(t){return"ADBE Text Document"!==t?null:r.sourceText}return Object.defineProperty(r,"sourceText",{get:function(){e.textProperty.getValue();var t=e.textProperty.currentData.t;return i&&t===i.value||((i=new String(t)).value=t||new String(t),Object.defineProperty(i,"style",{get:function(){return{fillColor:e.textProperty.currentData.fc}}})),i}}),r};function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var FootageInterface=(()=>{var r=function(t){var i="",r=t.getFootageData();function s(t){var e;return r[t]?"object"===_typeof(r=r[i=t])?s:r:-1!==(e=t.indexOf(i))?(t=parseInt(t.substr(e+i.length),10),"object"===_typeof(r=r[t])?s:r):""}return function(){return i="",r=t.getFootageData(),s}};return function(t){function e(t){return"Data"===t?e.dataInterface:null}function i(t){return"Outline"===t?i.outlineInterface():null}return e._name="Data",e.dataInterface=(t=t,i._name="Outline",i.outlineInterface=r(t),i),e}})(),interfaces={layer:LayerExpressionInterface,effects:EffectsExpressionInterface,comp:CompExpressionInterface,shape:ShapeExpressionInterface,text:TextExpressionInterface,footage:FootageInterface};function getInterface(t){return interfaces[t]||null}var expressionHelpers={searchExpressions:function(t,e,i){e.x&&(i.k=!0,i.x=!0,i.initiateExpression=ExpressionManager.initiateExpression,i.effectsSequence.push(i.initiateExpression(t,e,i).bind(i)))},getSpeedAtTime:function(t){var e=this.getValueAtTime(t),i=this.getValueAtTime(t+-.01),r=0;if(e.length){for(var s=0;s<e.length;s+=1)r+=Math.pow(i[s]-e[s],2);r=100*Math.sqrt(r)}else r=0;return r},getVelocityAtTime:function(t){if(void 0!==this.vel)return this.vel;var e=this.getValueAtTime(t),i=this.getValueAtTime(t+-.001);if(e.length)for(var r=createTypedArray("float32",e.length),s=0;s<e.length;s+=1)r[s]=(i[s]-e[s])/-.001;else r=(i-e)/-.001;return r},getValueAtTime:function(t){return(t=(t*=this.elem.globalData.frameRate)-this.offsetTime)!==this._cachingAtTime.lastFrame&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastFrame<t?this._cachingAtTime.lastIndex:0,this._cachingAtTime.value=this.interpolateValue(t,this._cachingAtTime),this._cachingAtTime.lastFrame=t),this._cachingAtTime.value},getStaticValueAtTime:function(){return this.pv},setGroupProperty:function(t){this.propertyGroup=t}};function addPropertyDecorator(){function n(t,e,i){if(!this.k||!this.keyframes)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[l.length-1].t;if(h<=p)return this.pv;if(i?s=p-(r=e?Math.abs(p-this.elem.comp.globalData.frameRate*e):Math.max(0,p-this.elem.data.ip)):((!e||e>l.length-1)&&(e=l.length-1),r=p-(s=l[l.length-1-e].t)),"pingpong"===t){if(Math.floor((h-s)/r)%2!=0)return this.getValueAtTime((r-(h-s)%r+s)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var m=this.getValueAtTime(s/this.comp.globalData.frameRate,0),f=this.getValueAtTime(p/this.comp.globalData.frameRate,0),c=this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0),d=Math.floor((h-s)/r);if(this.pv.length){for(n=(o=new Array(m.length)).length,a=0;a<n;a+=1)o[a]=(f[a]-m[a])*d+c[a];return o}return(f-m)*d+c}if("continue"===t){var u=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p-.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*((h-p)/this.comp.globalData.frameRate)/5e-4;return o}return u+(h-p)/.001*(u-y)}}return this.getValueAtTime(((h-s)%r+s)/this.comp.globalData.frameRate,0)}function o(t,e,i){if(!this.k)return this.pv;t=t?t.toLowerCase():"";var r,s,a,n,o,h=this.comp.renderedFrame,l=this.keyframes,p=l[0].t;if(p<=h)return this.pv;if(i?s=p+(r=e?Math.abs(this.elem.comp.globalData.frameRate*e):Math.max(0,this.elem.data.op-p)):r=(s=l[e=!e||e>l.length-1?l.length-1:e].t)-p,"pingpong"===t){if(Math.floor((p-h)/r)%2==0)return this.getValueAtTime(((p-h)%r+p)/this.comp.globalData.frameRate,0)}else{if("offset"===t){var m=this.getValueAtTime(p/this.comp.globalData.frameRate,0),f=this.getValueAtTime(s/this.comp.globalData.frameRate,0),c=this.getValueAtTime((r-(p-h)%r+p)/this.comp.globalData.frameRate,0),d=Math.floor((p-h)/r)+1;if(this.pv.length){for(n=(o=new Array(m.length)).length,a=0;a<n;a+=1)o[a]=c[a]-(f[a]-m[a])*d;return o}return c-(f-m)*d}if("continue"===t){var u=this.getValueAtTime(p/this.comp.globalData.frameRate,0),y=this.getValueAtTime((p+.001)/this.comp.globalData.frameRate,0);if(this.pv.length){for(n=(o=new Array(u.length)).length,a=0;a<n;a+=1)o[a]=u[a]+(u[a]-y[a])*(p-h)/.001;return o}return u+(u-y)*(p-h)/.001}}return this.getValueAtTime((r-((p-h)%r+p))/this.comp.globalData.frameRate,0)}function h(t,e){if(!this.k)return this.pv;if(t=.5*(t||.4),(e=Math.floor(e||5))<=1)return this.pv;for(var i,r=this.comp.renderedFrame/this.comp.globalData.frameRate,s=r-t,a=1<e?(r+t-s)/(e-1):1,n=0,o=0,h=this.pv.length?createTypedArray("float32",this.pv.length):0;n<e;){if(i=this.getValueAtTime(s+n*a),this.pv.length)for(o=0;o<this.pv.length;o+=1)h[o]+=i[o];else h+=i;n+=1}if(this.pv.length)for(o=0;o<this.pv.length;o+=1)h[o]/=e;else h/=e;return h}var r=TransformPropertyFactory.getTransformProperty,l=(TransformPropertyFactory.getTransformProperty=function(t,e,i){t=r(t,e,i);return t.dynamicProperties.length?t.getValueAtTime=function(t){this._transformCachingAtTime||(this._transformCachingAtTime={v:new Matrix});var e,i,r,s,a=this._transformCachingAtTime.v;return a.cloneFromProps(this.pre.props),this.appliedTransformations<1&&(i=this.a.getValueAtTime(t),a.translate(-i[0]*this.a.mult,-i[1]*this.a.mult,i[2]*this.a.mult)),this.appliedTransformations<2&&(i=this.s.getValueAtTime(t),a.scale(i[0]*this.s.mult,i[1]*this.s.mult,i[2]*this.s.mult)),this.sk&&this.appliedTransformations<3&&(i=this.sk.getValueAtTime(t),e=this.sa.getValueAtTime(t),a.skewFromAxis(-i*this.sk.mult,e*this.sa.mult)),this.r&&this.appliedTransformations<4?(i=this.r.getValueAtTime(t),a.rotate(-i*this.r.mult)):!this.r&&this.appliedTransformations<4&&(e=this.rz.getValueAtTime(t),i=this.ry.getValueAtTime(t),r=this.rx.getValueAtTime(t),s=this.or.getValueAtTime(t),a.rotateZ(-e*this.rz.mult).rotateY(i*this.ry.mult).rotateX(r*this.rx.mult).rotateZ(-s[2]*this.or.mult).rotateY(s[1]*this.or.mult).rotateX(s[0]*this.or.mult)),this.data.p&&this.data.p.s?(e=this.px.getValueAtTime(t),i=this.py.getValueAtTime(t),this.data.p.z?(r=this.pz.getValueAtTime(t),a.translate(e*this.px.mult,i*this.py.mult,-r*this.pz.mult)):a.translate(e*this.px.mult,i*this.py.mult,0)):(s=this.p.getValueAtTime(t),a.translate(s[0]*this.p.mult,s[1]*this.p.mult,-s[2]*this.p.mult)),a}.bind(t):t.getValueAtTime=function(){return this.v.clone(new Matrix)}.bind(t),t.setGroupProperty=expressionHelpers.setGroupProperty,t},PropertyFactory.getProp);PropertyFactory.getProp=function(t,e,i,r,s){var r=l(t,e,i,r,s),a=(r.kf?r.getValueAtTime=expressionHelpers.getValueAtTime.bind(r):r.getValueAtTime=expressionHelpers.getStaticValueAtTime.bind(r),r.setGroupProperty=expressionHelpers.setGroupProperty,r.loopOut=n,r.loopIn=o,r.smooth=h,r.getVelocityAtTime=expressionHelpers.getVelocityAtTime.bind(r),r.getSpeedAtTime=expressionHelpers.getSpeedAtTime.bind(r),r.numKeys=1===e.a?e.k.length:0,r.propertyIndex=e.ix,0);return 0!==i&&(a=createTypedArray("float32",(1===e.a?e.k[0].s:e.k).length)),r._cachingAtTime={lastFrame:initialDefaultFrame,lastIndex:0,value:a},expressionHelpers.searchExpressions(t,e,r),r.k&&s.addDynamicProperty(r),r};var t=ShapePropertyFactory.getConstructorFunction(),e=ShapePropertyFactory.getKeyframedConstructorFunction();function i(){}i.prototype={vertices:function(t,e){this.k&&this.getValue();for(var i=this.v,r=(i=void 0!==e?this.getValueAtTime(e,0):i)._length,s=i[t],a=i.v,n=createSizedArray(r),o=0;o<r;o+=1)n[o]="i"===t||"o"===t?[s[o][0]-a[o][0],s[o][1]-a[o][1]]:[s[o][0],s[o][1]];return n},points:function(t){return this.vertices("v",t)},inTangents:function(t){return this.vertices("i",t)},outTangents:function(t){return this.vertices("o",t)},isClosed:function(){return this.v.c},pointOnPath:function(t,e){for(var i=this.v,e=(void 0!==e&&(i=this.getValueAtTime(e,0)),this._segmentsLength||(this._segmentsLength=bez.getSegmentsLength(i)),this._segmentsLength),r=e.lengths,s=e.totalLength*t,a=0,n=r.length,o=0;a<n;){if(o+r[a].addedLength>s){var h=a,l=i.c&&a===n-1?0:a+1,p=(s-o)/r[a].addedLength,m=bez.getPointInSegment(i.v[h],i.v[l],i.o[h],i.i[l],p,r[a]);break}o+=r[a].addedLength,a+=1}return m=m||(i.c?[i.v[0][0],i.v[0][1]]:[i.v[i._length-1][0],i.v[i._length-1][1]])},vectorOnPath:function(t,e,i){1==t?t=this.v.c:0==t&&(t=.999);var r=this.pointOnPath(t,e),t=this.pointOnPath(t+.001,e),e=t[0]-r[0],t=t[1]-r[1],r=Math.sqrt(Math.pow(e,2)+Math.pow(t,2));return 0===r?[0,0]:"tangent"===i?[e/r,t/r]:[-t/r,e/r]},tangentOnPath:function(t,e){return this.vectorOnPath(t,e,"tangent")},normalOnPath:function(t,e){return this.vectorOnPath(t,e,"normal")},setGroupProperty:expressionHelpers.setGroupProperty,getValueAtTime:expressionHelpers.getStaticValueAtTime},extendPrototype([i],t),extendPrototype([i],e),e.prototype.getValueAtTime=function(t){return this._cachingAtTime||(this._cachingAtTime={shapeValue:shapePool.clone(this.pv),lastIndex:0,lastTime:initialDefaultFrame}),(t=(t*=this.elem.globalData.frameRate)-this.offsetTime)!==this._cachingAtTime.lastTime&&(this._cachingAtTime.lastIndex=this._cachingAtTime.lastTime<t?this._caching.lastIndex:0,this._cachingAtTime.lastTime=t,this.interpolateShape(t,this._cachingAtTime.shapeValue,this._cachingAtTime)),this._cachingAtTime.shapeValue},e.prototype.initiateExpression=ExpressionManager.initiateExpression;var a=ShapePropertyFactory.getShapeProp;ShapePropertyFactory.getShapeProp=function(t,e,i,r,s){r=a(t,e,i,r,s);return r.propertyIndex=e.ix,r.lock=!1,3===i?expressionHelpers.searchExpressions(t,e.pt,r):4===i&&expressionHelpers.searchExpressions(t,e.ks,r),r.k&&t.addDynamicProperty(r),r}}function initialize$1(){addPropertyDecorator()}function addDecorator(){TextProperty.prototype.getExpressionValue=function(t,e){var i,e=this.calculateExpression(e);return t.t!==e?(this.copyData(i={},t),i.t=e.toString(),i.__complete=!1,i):t},TextProperty.prototype.searchProperty=function(){var t=this.searchKeyframes(),e=this.searchExpressions();return this.kf=t||e,this.kf},TextProperty.prototype.searchExpressions=function(){return this.data.d.x?(this.calculateExpression=ExpressionManager.initiateExpression.bind(this)(this.elem,this.data.d,this),this.addEffect(this.getExpressionValue.bind(this)),!0):null}}function initialize(){addDecorator()}function SVGComposableEffect(){}SVGComposableEffect.prototype={createMergeNode:function(t,e){var i,r,s=createNS("feMerge");for(s.setAttribute("result",t),r=0;r<e.length;r+=1)(i=createNS("feMergeNode")).setAttribute("in",e[r]),s.appendChild(i),s.appendChild(i);return s}};var linearFilterValue="0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0";function SVGTintFilter(t,e,i,r,s){this.filterManager=e;e=createNS("feColorMatrix"),e.setAttribute("type","matrix"),e.setAttribute("color-interpolation-filters","linearRGB"),e.setAttribute("values",linearFilterValue+" 1 0"),(this.linearFilter=e).setAttribute("result",r+"_tint_1"),t.appendChild(e),(e=createNS("feColorMatrix")).setAttribute("type","matrix"),e.setAttribute("color-interpolation-filters","sRGB"),e.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),e.setAttribute("result",r+"_tint_2"),t.appendChild(e),this.matrixFilter=e,e=this.createMergeNode(r,[s,r+"_tint_1",r+"_tint_2"]);t.appendChild(e)}function SVGFillFilter(t,e,i,r){this.filterManager=e;e=createNS("feColorMatrix");e.setAttribute("type","matrix"),e.setAttribute("color-interpolation-filters","sRGB"),e.setAttribute("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"),e.setAttribute("result",r),t.appendChild(e),this.matrixFilter=e}function SVGStrokeEffect(t,e,i){this.initialized=!1,this.filterManager=e,this.elem=i,this.paths=[]}function SVGTritoneFilter(t,e,i,r){this.filterManager=e;e=createNS("feColorMatrix"),e.setAttribute("type","matrix"),e.setAttribute("color-interpolation-filters","linearRGB"),e.setAttribute("values","0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0"),t.appendChild(e),e=createNS("feComponentTransfer"),e.setAttribute("color-interpolation-filters","sRGB"),e.setAttribute("result",r),this.matrixFilter=e,r=createNS("feFuncR"),r.setAttribute("type","table"),e.appendChild(r),this.feFuncR=r,r=createNS("feFuncG"),r.setAttribute("type","table"),e.appendChild(r),this.feFuncG=r,r=createNS("feFuncB");r.setAttribute("type","table"),e.appendChild(r),this.feFuncB=r,t.appendChild(e)}function SVGProLevelsFilter(t,e,i,r){this.filterManager=e;var e=this.filterManager.effectElements,s=createNS("feComponentTransfer");(e[10].p.k||0!==e[10].p.v||e[11].p.k||1!==e[11].p.v||e[12].p.k||1!==e[12].p.v||e[13].p.k||0!==e[13].p.v||e[14].p.k||1!==e[14].p.v)&&(this.feFuncR=this.createFeFunc("feFuncR",s)),(e[17].p.k||0!==e[17].p.v||e[18].p.k||1!==e[18].p.v||e[19].p.k||1!==e[19].p.v||e[20].p.k||0!==e[20].p.v||e[21].p.k||1!==e[21].p.v)&&(this.feFuncG=this.createFeFunc("feFuncG",s)),(e[24].p.k||0!==e[24].p.v||e[25].p.k||1!==e[25].p.v||e[26].p.k||1!==e[26].p.v||e[27].p.k||0!==e[27].p.v||e[28].p.k||1!==e[28].p.v)&&(this.feFuncB=this.createFeFunc("feFuncB",s)),(e[31].p.k||0!==e[31].p.v||e[32].p.k||1!==e[32].p.v||e[33].p.k||1!==e[33].p.v||e[34].p.k||0!==e[34].p.v||e[35].p.k||1!==e[35].p.v)&&(this.feFuncA=this.createFeFunc("feFuncA",s)),(this.feFuncR||this.feFuncG||this.feFuncB||this.feFuncA)&&(s.setAttribute("color-interpolation-filters","sRGB"),t.appendChild(s)),(e[3].p.k||0!==e[3].p.v||e[4].p.k||1!==e[4].p.v||e[5].p.k||1!==e[5].p.v||e[6].p.k||0!==e[6].p.v||e[7].p.k||1!==e[7].p.v)&&((s=createNS("feComponentTransfer")).setAttribute("color-interpolation-filters","sRGB"),s.setAttribute("result",r),t.appendChild(s),this.feFuncRComposed=this.createFeFunc("feFuncR",s),this.feFuncGComposed=this.createFeFunc("feFuncG",s),this.feFuncBComposed=this.createFeFunc("feFuncB",s))}function SVGDropShadowEffect(t,e,i,r,s){var a=e.container.globalData.renderConfig.filterSize,n=e.data.fs||a,n=(t.setAttribute("x",n.x||a.x),t.setAttribute("y",n.y||a.y),t.setAttribute("width",n.width||a.width),t.setAttribute("height",n.height||a.height),this.filterManager=e,createNS("feGaussianBlur")),a=(n.setAttribute("in","SourceAlpha"),n.setAttribute("result",r+"_drop_shadow_1"),n.setAttribute("stdDeviation","0"),this.feGaussianBlur=n,t.appendChild(n),createNS("feOffset")),e=(a.setAttribute("dx","25"),a.setAttribute("dy","0"),a.setAttribute("in",r+"_drop_shadow_1"),a.setAttribute("result",r+"_drop_shadow_2"),this.feOffset=a,t.appendChild(a),createNS("feFlood")),n=(e.setAttribute("flood-color","#00ff00"),e.setAttribute("flood-opacity","1"),e.setAttribute("result",r+"_drop_shadow_3"),this.feFlood=e,t.appendChild(e),createNS("feComposite")),a=(n.setAttribute("in",r+"_drop_shadow_3"),n.setAttribute("in2",r+"_drop_shadow_2"),n.setAttribute("operator","in"),n.setAttribute("result",r+"_drop_shadow_4"),t.appendChild(n),this.createMergeNode(r,[r+"_drop_shadow_4",s]));t.appendChild(a)}extendPrototype([SVGComposableEffect],SVGTintFilter),SVGTintFilter.prototype.renderFrame=function(t){var e,i;(t||this.filterManager._mdf)&&(t=this.filterManager.effectElements[0].p.v,e=this.filterManager.effectElements[1].p.v,i=this.filterManager.effectElements[2].p.v/100,this.linearFilter.setAttribute("values",linearFilterValue+" "+i+" 0"),this.matrixFilter.setAttribute("values",e[0]-t[0]+" 0 0 0 "+t[0]+" "+(e[1]-t[1])+" 0 0 0 "+t[1]+" "+(e[2]-t[2])+" 0 0 0 "+t[2]+" 0 0 0 1 0"))},SVGFillFilter.prototype.renderFrame=function(t){var e;(t||this.filterManager._mdf)&&(t=this.filterManager.effectElements[2].p.v,e=this.filterManager.effectElements[6].p.v,this.matrixFilter.setAttribute("values","0 0 0 0 "+t[0]+" 0 0 0 0 "+t[1]+" 0 0 0 0 "+t[2]+" 0 0 0 "+e+" 0"))},SVGStrokeEffect.prototype.initialize=function(){var t,e,i,r,s=this.elem.layerElement.children||this.elem.layerElement.childNodes;for(1===this.filterManager.effectElements[1].p.v?(r=this.elem.maskManager.masksProperties.length,i=0):r=(i=this.filterManager.effectElements[0].p.v-1)+1,(e=createNS("g")).setAttribute("fill","none"),e.setAttribute("stroke-linecap","round"),e.setAttribute("stroke-dashoffset",1);i<r;i+=1)t=createNS("path"),e.appendChild(t),this.paths.push({p:t,m:i});if(3===this.filterManager.effectElements[10].p.v){var a=createNS("mask"),n=createElementID(),o=(a.setAttribute("id",n),a.setAttribute("mask-type","alpha"),a.appendChild(e),this.elem.globalData.defs.appendChild(a),createNS("g"));for(o.setAttribute("mask","url("+getLocationHref()+"#"+n+")");s[0];)o.appendChild(s[0]);this.elem.layerElement.appendChild(o),this.masker=a,e.setAttribute("stroke","#fff")}else if(1===this.filterManager.effectElements[10].p.v||2===this.filterManager.effectElements[10].p.v){if(2===this.filterManager.effectElements[10].p.v)for(s=this.elem.layerElement.children||this.elem.layerElement.childNodes;s.length;)this.elem.layerElement.removeChild(s[0]);this.elem.layerElement.appendChild(e),this.elem.layerElement.removeAttribute("mask"),e.setAttribute("stroke","#fff")}this.initialized=!0,this.pathMasker=e},SVGStrokeEffect.prototype.renderFrame=function(t){this.initialized||this.initialize();for(var e,i,r=this.paths.length,s=0;s<r;s+=1)if(-1!==this.paths[s].m&&(a=this.elem.maskManager.viewData[this.paths[s].m],e=this.paths[s].p,(t||this.filterManager._mdf||a.prop._mdf)&&e.setAttribute("d",a.lastPath),t||this.filterManager.effectElements[9].p._mdf||this.filterManager.effectElements[4].p._mdf||this.filterManager.effectElements[7].p._mdf||this.filterManager.effectElements[8].p._mdf||a.prop._mdf)){if(0!==this.filterManager.effectElements[7].p.v||100!==this.filterManager.effectElements[8].p.v){for(var a=.01*Math.min(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),n=.01*Math.max(this.filterManager.effectElements[7].p.v,this.filterManager.effectElements[8].p.v),o=e.getTotalLength(),h="0 0 0 "+o*a+" ",l=1+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01,p=Math.floor(o*(n-a)/l),m=0;m<p;m+=1)h+="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01+" ";h+="0 "+10*o+" 0 0"}else h="1 "+2*this.filterManager.effectElements[4].p.v*this.filterManager.effectElements[9].p.v*.01;e.setAttribute("stroke-dasharray",h)}(t||this.filterManager.effectElements[4].p._mdf)&&this.pathMasker.setAttribute("stroke-width",2*this.filterManager.effectElements[4].p.v),(t||this.filterManager.effectElements[6].p._mdf)&&this.pathMasker.setAttribute("opacity",this.filterManager.effectElements[6].p.v),1!==this.filterManager.effectElements[10].p.v&&2!==this.filterManager.effectElements[10].p.v||(t||this.filterManager.effectElements[3].p._mdf)&&(i=this.filterManager.effectElements[3].p.v,this.pathMasker.setAttribute("stroke","rgb("+bmFloor(255*i[0])+","+bmFloor(255*i[1])+","+bmFloor(255*i[2])+")"))},SVGTritoneFilter.prototype.renderFrame=function(t){var e,i,r,s;(t||this.filterManager._mdf)&&(t=this.filterManager.effectElements[0].p.v,e=this.filterManager.effectElements[1].p.v,i=(s=this.filterManager.effectElements[2].p.v)[0]+" "+e[0]+" "+t[0],r=s[1]+" "+e[1]+" "+t[1],s=s[2]+" "+e[2]+" "+t[2],this.feFuncR.setAttribute("tableValues",i),this.feFuncG.setAttribute("tableValues",r),this.feFuncB.setAttribute("tableValues",s))},SVGProLevelsFilter.prototype.createFeFunc=function(t,e){t=createNS(t);return t.setAttribute("type","table"),e.appendChild(t),t},SVGProLevelsFilter.prototype.getTableValue=function(t,e,i,r,s){for(var a,n=0,o=Math.min(t,e),h=Math.max(t,e),l=Array.call(null,{length:256}),p=0,m=s-r,f=e-t;n<=256;)a=(a=n/256)<=o?f<0?s:r:h<=a?f<0?r:s:r+m*Math.pow((a-t)/f,1/i),l[p]=a,p+=1,n+=256/255;return l.join(" ")},SVGProLevelsFilter.prototype.renderFrame=function(t){var e,i;(t||this.filterManager._mdf)&&(i=this.filterManager.effectElements,this.feFuncRComposed&&(t||i[3].p._mdf||i[4].p._mdf||i[5].p._mdf||i[6].p._mdf||i[7].p._mdf)&&(e=this.getTableValue(i[3].p.v,i[4].p.v,i[5].p.v,i[6].p.v,i[7].p.v),this.feFuncRComposed.setAttribute("tableValues",e),this.feFuncGComposed.setAttribute("tableValues",e),this.feFuncBComposed.setAttribute("tableValues",e)),this.feFuncR&&(t||i[10].p._mdf||i[11].p._mdf||i[12].p._mdf||i[13].p._mdf||i[14].p._mdf)&&(e=this.getTableValue(i[10].p.v,i[11].p.v,i[12].p.v,i[13].p.v,i[14].p.v),this.feFuncR.setAttribute("tableValues",e)),this.feFuncG&&(t||i[17].p._mdf||i[18].p._mdf||i[19].p._mdf||i[20].p._mdf||i[21].p._mdf)&&(e=this.getTableValue(i[17].p.v,i[18].p.v,i[19].p.v,i[20].p.v,i[21].p.v),this.feFuncG.setAttribute("tableValues",e)),this.feFuncB&&(t||i[24].p._mdf||i[25].p._mdf||i[26].p._mdf||i[27].p._mdf||i[28].p._mdf)&&(e=this.getTableValue(i[24].p.v,i[25].p.v,i[26].p.v,i[27].p.v,i[28].p.v),this.feFuncB.setAttribute("tableValues",e)),this.feFuncA)&&(t||i[31].p._mdf||i[32].p._mdf||i[33].p._mdf||i[34].p._mdf||i[35].p._mdf)&&(e=this.getTableValue(i[31].p.v,i[32].p.v,i[33].p.v,i[34].p.v,i[35].p.v),this.feFuncA.setAttribute("tableValues",e))},extendPrototype([SVGComposableEffect],SVGDropShadowEffect),SVGDropShadowEffect.prototype.renderFrame=function(t){var e,i;(t||this.filterManager._mdf)&&((t||this.filterManager.effectElements[4].p._mdf)&&this.feGaussianBlur.setAttribute("stdDeviation",this.filterManager.effectElements[4].p.v/4),(t||this.filterManager.effectElements[0].p._mdf)&&(i=this.filterManager.effectElements[0].p.v,this.feFlood.setAttribute("flood-color",rgbToHex(Math.round(255*i[0]),Math.round(255*i[1]),Math.round(255*i[2])))),(t||this.filterManager.effectElements[1].p._mdf)&&this.feFlood.setAttribute("flood-opacity",this.filterManager.effectElements[1].p.v/255),t||this.filterManager.effectElements[2].p._mdf||this.filterManager.effectElements[3].p._mdf)&&(i=this.filterManager.effectElements[3].p.v,t=(this.filterManager.effectElements[2].p.v-90)*degToRads,e=i*Math.cos(t),i=i*Math.sin(t),this.feOffset.setAttribute("dx",e),this.feOffset.setAttribute("dy",i))};var _svgMatteSymbols=[];function SVGMatte3Effect(t,e,i){this.initialized=!1,this.filterManager=e,this.filterElem=t,(this.elem=i).matteElement=createNS("g"),i.matteElement.appendChild(i.layerElement),i.matteElement.appendChild(i.transformedElement),i.baseElement=i.matteElement}function SVGGaussianBlurEffect(t,e,i,r){t.setAttribute("x","-100%"),t.setAttribute("y","-100%"),t.setAttribute("width","300%"),t.setAttribute("height","300%"),this.filterManager=e;e=createNS("feGaussianBlur");e.setAttribute("result",r),t.appendChild(e),this.feGaussianBlur=e}function TransformEffect(){}function SVGTransformEffect(t,e){this.init(e)}function CVTransformEffect(t){this.init(t)}return SVGMatte3Effect.prototype.findSymbol=function(t){for(var e=0,i=_svgMatteSymbols.length;e<i;){if(_svgMatteSymbols[e]===t)return _svgMatteSymbols[e];e+=1}return null},SVGMatte3Effect.prototype.replaceInParent=function(t,e){var i=t.layerElement.parentNode;if(i){for(var r,s=i.children,a=0,n=s.length;a<n&&s[a]!==t.layerElement;)a+=1;a<=n-2&&(r=s[a+1]);var o=createNS("use");o.setAttribute("href","#"+e),r?i.insertBefore(o,r):i.appendChild(o)}},SVGMatte3Effect.prototype.setElementAsMask=function(t,e){var i,r,s,a;this.findSymbol(e)||(i=createElementID(),(r=createNS("mask")).setAttribute("id",e.layerId),r.setAttribute("mask-type","alpha"),_svgMatteSymbols.push(e),(a=t.globalData.defs).appendChild(r),(s=createNS("symbol")).setAttribute("id",i),this.replaceInParent(e,i),s.appendChild(e.layerElement),a.appendChild(s),(a=createNS("use")).setAttribute("href","#"+i),r.appendChild(a),e.data.hd=!1,e.show()),t.setMatte(e.layerId)},SVGMatte3Effect.prototype.initialize=function(){for(var t=this.filterManager.effectElements[0].p.v,e=this.elem.comp.elements,i=0,r=e.length;i<r;)e[i]&&e[i].data.ind===t&&this.setElementAsMask(this.elem,e[i]),i+=1;this.initialized=!0},SVGMatte3Effect.prototype.renderFrame=function(){this.initialized||this.initialize()},SVGGaussianBlurEffect.prototype.renderFrame=function(t){var e;(t||this.filterManager._mdf)&&(t=.3*this.filterManager.effectElements[0].p.v,e=this.filterManager.effectElements[1].p.v,this.feGaussianBlur.setAttribute("stdDeviation",(3==e?0:t)+" "+(2==e?0:t)),e=1==this.filterManager.effectElements[2].p.v?"wrap":"duplicate",this.feGaussianBlur.setAttribute("edgeMode",e))},TransformEffect.prototype.init=function(t){this.effectsManager=t,this.type=effectTypes.TRANSFORM_EFFECT,this.matrix=new Matrix,this.opacity=-1,this._mdf=!1,this._opMdf=!1},TransformEffect.prototype.renderFrame=function(t){var e,i,r,s,a,n,o;this._opMdf=!1,this._mdf=!1,(t||this.effectsManager._mdf)&&(e=(t=this.effectsManager.effectElements)[0].p.v,i=t[1].p.v,s=1===t[2].p.v,r=t[3].p.v,s=s?r:t[4].p.v,a=t[5].p.v,n=t[6].p.v,o=t[7].p.v,this.matrix.reset(),this.matrix.translate(-e[0],-e[1],e[2]),this.matrix.scale(.01*s,.01*r,1),this.matrix.rotate(-o*degToRads),this.matrix.skewFromAxis(-a*degToRads,(n+90)*degToRads),this.matrix.translate(i[0],i[1],0),this._mdf=!0,this.opacity!==t[8].p.v)&&(this.opacity=t[8].p.v,this._opMdf=!0)},extendPrototype([TransformEffect],SVGTransformEffect),extendPrototype([TransformEffect],CVTransformEffect),registerRenderer("canvas",CanvasRenderer),registerRenderer("html",HybridRenderer),registerRenderer("svg",SVGRenderer),ShapeModifiers.registerModifier("tm",TrimModifier),ShapeModifiers.registerModifier("pb",PuckerAndBloatModifier),ShapeModifiers.registerModifier("rp",RepeaterModifier),ShapeModifiers.registerModifier("rd",RoundCornersModifier),ShapeModifiers.registerModifier("zz",ZigZagModifier),ShapeModifiers.registerModifier("op",OffsetPathModifier),setExpressionsPlugin(Expressions),setExpressionInterfaces(getInterface),initialize$1(),initialize(),registerEffect$1(20,SVGTintFilter,!0),registerEffect$1(21,SVGFillFilter,!0),registerEffect$1(22,SVGStrokeEffect,!1),registerEffect$1(23,SVGTritoneFilter,!0),registerEffect$1(24,SVGProLevelsFilter,!0),registerEffect$1(25,SVGDropShadowEffect,!0),registerEffect$1(28,SVGMatte3Effect,!1),registerEffect$1(29,SVGGaussianBlurEffect,!0),registerEffect$1(35,SVGTransformEffect,!1),registerEffect(35,CVTransformEffect),lottie}),{loadAnimation:loadAnimation}}({});onmessage=function(t){var t=t.data,e=t.type,i=t.payload;"load"===e?lottieInternal.loadAnimation(i):"pause"===e?animations[i.id]&&animations[i.id].animation.pause():"play"===e?animations[i.id]&&animations[i.id].animation.play():"stop"===e?animations[i.id]&&animations[i.id].animation.stop():"setSpeed"===e?animations[i.id]&&animations[i.id].animation.setSpeed(i.value):"setDirection"===e?animations[i.id]&&animations[i.id].animation.setDirection(i.value):"setLoop"===e?animations[i.id]&&animations[i.id].animation.setLoop(i.value):"goToAndPlay"===e?animations[i.id]&&animations[i.id].animation.goToAndPlay(i.value,i.isFrame):"goToAndStop"===e?animations[i.id]&&animations[i.id].animation.goToAndStop(i.value,i.isFrame):"setSubframe"===e?animations[i.id]&&animations[i.id].animation.setSubframe(i.value):"addEventListener"===e?animations[i.id]&&(animations[i.id].events[i.callbackId]={callback:t=function(){self.postMessage({type:"event",payload:{id:i.id,callbackId:i.callbackId,argument:arguments[0]}})}},animations[i.id].animation.addEventListener(i.eventName,t)):"removeEventListener"===e?animations[i.id]&&(t=animations[i.id].events[i.callbackId],animations[i.id].animation.removeEventListener(i.eventName,t)):"destroy"===e?animations[i.id]&&(animations[i.id].animation.destroy(),animations[i.id]=null):"resize"===e?animations[i.id]&&animations[i.id].animation.resize(i.width,i.height):"playSegments"===e?animations[i.id]&&animations[i.id].animation.playSegments(i.arr,i.forceFlag):"resetSegments"===e?animations[i.id]&&animations[i.id].animation.resetSegments(i.forceFlag):"updateDocumentData"===e&&animations[i.id].animation.updateDocumentData(i.path,i.documentData,i.index)}}function createWorker(t){t=new Blob(["("+t.toString()+"())"],{type:"text/javascript"}),t=URL.createObjectURL(t);return new Worker(t)}var lottie=(()=>{var h=createWorker(workerContent),i=0,s=0,P={},a={rendererSettings:{}};function E(t,e,i,r){var s,a,n="div"===t.type?document.createElement("div"):document.createElementNS(t.namespace,t.type);for(s in t.textContent&&(n.textContent=t.textContent),t.attributes)Object.prototype.hasOwnProperty.call(t.attributes,s)&&("href"===s?n.setAttributeNS("http://www.w3.org/1999/xlink",s,t.attributes[s]):n.setAttribute(s,t.attributes[s]),"id"===s)&&(i[t.attributes[s]]=n);for(a in t.style)Object.prototype.hasOwnProperty.call(t.style,a)&&(n.style[a]=t.style[a]);t.children.forEach(function(t){E(t,n,i)}),r?e.insertBefore(n,r):e.appendChild(n)}var e={DOMLoaded:function(t){var e=P[t.id];e._loaded=!0,e.pendingCallbacks.forEach(function(t){e.animInstance.addEventListener(t.eventName,t.callback),"DOMLoaded"===t.eventName&&t.callback()}),e.animInstance.totalFrames=t.totalFrames,e.animInstance.frameRate=t.frameRate,e.animInstance.firstFrame=t.firstFrame,e.animInstance.playDirection=t.playDirection,e.animInstance.currentFrame=t.isSubframeEnabled?t.currentRawFrame:~~t.currentRawFrame,t.timeCompleted!==t.totalFrames&&t.currentFrame>t.timeCompleted&&(e.animInstance.currentFrame=t.timeCompleted)},SVGloaded:function(t){var e=P[t.id],i=e.container;E(t.tree,i,e.elements)},SVGupdated:function(t){var e=t.elements,i=P[t.id];if(i){for(var r=i.elements,s=0;s<e.length;s+=1){for(var a,n=r[(a=e[s]).id],o=(m=f=l=p=h=o=void 0,a.elements),h=r,l=0;l<o.length;l+=1){var p,m,f=h[(p=o[l])[1]];f&&(p[2]&&(m=h[p[2]]),E(p[0],f,h,m),o.splice(l,1),--l)}y=c=u=d=void 0;for(var c,d=n,u=a.styles,y=0;y<u.length;y+=1)d.style[(c=u[y])[0]]=c[1];x=g=b=v=void 0;for(var g,v=n,b=a.attributes,x=0;x<b.length;x+=1)v.setAttribute((g=b[x])[0],g[1]);n=n,(a=a.textContent)&&(n.textContent=a)}i.animInstance.currentFrame=t.currentTime}},CanvasUpdated:function(t){P[t.id].instructionsHandler(t.instructions)},event:function(t){var e=P[t.id];e&&(e=e.callbacks)[t.callbackId]&&e[t.callbackId].callback(t.argument)},playing:function(t){(t=P[t.id])&&(t.animInstance.isPaused=!1)},paused:function(t){(t=P[t.id])&&(t.animInstance.isPaused=!0)}};return h.onmessage=function(t){e[t.data.type]&&e[t.data.type](t.data.payload)},{loadAnimation:function(t){var r,n="lottie_animationId_"+(i+=1),o={elements:{},callbacks:{},pendingCallbacks:[],status:"init"},e={id:n,isPaused:!0,pause:function(){h.postMessage({type:"pause",payload:{id:n}})},play:function(){h.postMessage({type:"play",payload:{id:n}})},stop:function(){h.postMessage({type:"stop",payload:{id:n}})},setSpeed:function(t){h.postMessage({type:"setSpeed",payload:{id:n,value:t}})},setDirection:function(t){h.postMessage({type:"setDirection",payload:{id:n,value:t}})},setLoop:function(t){h.postMessage({type:"setLoop",payload:{id:n,value:t}})},goToAndStop:function(t,e){h.postMessage({type:"goToAndStop",payload:{id:n,value:t,isFrame:e}})},goToAndPlay:function(t,e){h.postMessage({type:"goToAndPlay",payload:{id:n,value:t,isFrame:e}})},playSegments:function(t,e){h.postMessage({type:"playSegments",payload:{id:n,arr:t,forceFlag:e}})},setSubframe:function(t){h.postMessage({type:"setSubframe",payload:{id:n,value:t}})},addEventListener:function(t,e){var i;o._loaded?(i="callback_"+(s+=1),o.callbacks[i]={eventName:t,callback:e},h.postMessage({type:"addEventListener",payload:{id:n,callbackId:i,eventName:t}})):o.pendingCallbacks.push({eventName:t,callback:e})},removeEventListener:function(e,i){Object.keys(o.callbacks).forEach(function(t){o.callbacks[t].eventName!==e||o.callbacks[t].callback!==i&&i||(delete o.callbacks[t],h.postMessage({type:"removeEventListener",payload:{id:n,callbackId:t,eventName:e}}))})},destroy:function(){"init"===o.status?o.status="destroyable":(o.status="destroyed",P[n]=null,o.container&&(o.container.innerHTML=""),h.postMessage({type:"destroy",payload:{id:n}}))},resize:function(t,e){var i=window.devicePixelRatio||1;h.postMessage({type:"resize",payload:{id:n,width:t||(o.container?o.container.offsetWidth*i:0),height:e||(o.container?o.container.offsetHeight*i:0)}})},updateDocumentData:function(t,e,i){h.postMessage({type:"updateDocumentData",payload:{id:n,path:t,documentData:e,index:i}})}};return o.animInstance=e,r=t,new Promise(function(e,t){var i=Object.assign({},a,r);i.animType&&!i.renderer&&(i.renderer=i.animType),i.wrapper&&(i.container||(i.container=i.wrapper),delete i.wrapper),i.animationData?e(i):i.path?fetch(i.path).then(function(t){return t.json()}).then(function(t){i.animationData=t,delete i.path,e(i)}):t()}).then(function(t){var e,i,r,s,a;"destroyable"===o.status?o.animInstance.destroy():(o.status="loaded",e=[],t.container&&(o.container=t.container,delete t.container),"canvas"===t.renderer&&((i=t.rendererSettings.canvas)||(r=window.devicePixelRatio||1,i=document.createElement("canvas"),o.container.appendChild(i),i.width=(o.container?o.container.offsetWidth:t.animationData.w)*r,i.height=(o.container?o.container.offsetHeight:t.animationData.h)*r,i.style.width="100%",i.style.height="100%"),r=i,"undefined"==typeof OffscreenCanvas?(o.canvas=i,o.instructionsHandler=(s=i.getContext("2d"),a={beginPath:s.beginPath,closePath:s.closePath,rect:s.rect,clip:s.clip,clearRect:s.clearRect,setTransform:s.setTransform,moveTo:s.moveTo,bezierCurveTo:s.bezierCurveTo,lineTo:s.lineTo,fill:s.fill,save:s.save,restore:s.restore},function(t){for(var e=0;e<t.length;e+=1){var i=t[e],r=a[i.t];r?r.apply(s,i.a):s[i.t]=i.a}})):(i instanceof OffscreenCanvas||(r=i.transferControlToOffscreen(),t.rendererSettings.canvas=r),e.push(r))),P[n]=o,h.postMessage({type:"load",payload:{params:t,id:n}},e))}),e}}})();
 return lottie;
 }));
\ No newline at end of file
diff --git a/package.json b/package.json
index 2473640..0549103 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "lottie-web",
-  "version": "5.12.2",
+  "version": "5.13.0",
   "description": "After Effects plugin for exporting animations to SVG + JavaScript or canvas + JavaScript",
   "main": "./build/player/lottie.js",
   "repository": {
